From 17060bc5e373ca7d41348c1cb1b1522bdd4b0af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Renison?= <85908989+IvanRenison@users.noreply.github.com> Date: Sat, 13 Jun 2026 01:31:30 +0000 Subject: [PATCH 0001/1300] feat(Combinatorics/SimpleGraph/Maps): add theorems about composition (#37624) --- Mathlib/Combinatorics/SimpleGraph/Maps.lean | 35 ++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index a4d9325a549275..3fbde0b4f959eb 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -45,7 +45,7 @@ open Function namespace SimpleGraph -variable {V W X : Type*} (G : SimpleGraph V) (G' : SimpleGraph W) {u v : V} +variable {V W X Y : Type*} (G : SimpleGraph V) (G' : SimpleGraph W) {u v : V} /-! ## Map and comap -/ @@ -420,7 +420,7 @@ theorem le_comap (f : H →g G) : H ≤ G.comap f := theorem nonempty_hom_iff_exists_le_comap : Nonempty (H →g G) ↔ ∃ f, H ≤ G.comap f := ⟨fun ⟨f⟩ ↦ ⟨f, f.le_comap⟩, fun ⟨f, h⟩ ↦ ⟨f, (h ·)⟩⟩ -variable {G'' : SimpleGraph X} +variable {G'' : SimpleGraph X} {G''' : SimpleGraph Y} /-- Composition of graph homomorphisms. -/ abbrev comp (f' : G' →g G'') (f : G →g G') : G →g G'' := @@ -430,6 +430,15 @@ abbrev comp (f' : G' →g G'') (f : G →g G') : G →g G'' := theorem coe_comp (f' : G' →g G'') (f : G →g G') : ⇑(f'.comp f) = f' ∘ f := rfl +theorem comp_assoc (f : G'' →g G''') (g : G' →g G'') (h : G →g G') : + f.comp (g.comp h) = (f.comp g).comp h := rfl + +@[simp] +theorem comp_id (f : G →g G') : f.comp .id = f := rfl + +@[simp] +theorem id_comp (f : G →g G') : .comp .id f = f := rfl + @[simp] theorem comp_comap_ofLE (f : H →g G) : .comp (.comap f G) (.ofLE f.le_comap) = f := rfl @@ -533,7 +542,7 @@ protected def completeGraph {α β : Type*} (f : α ↪ β) : completeGraph α @[simp] lemma coe_completeGraph {α β : Type*} (f : α ↪ β) : ⇑(Embedding.completeGraph f) = f := rfl -variable {G'' : SimpleGraph X} +variable {G'' : SimpleGraph X} {G''' : SimpleGraph Y} /-- Composition of graph embeddings. -/ abbrev comp (f' : G' ↪g G'') (f : G ↪g G') : G ↪g G'' := @@ -543,6 +552,15 @@ abbrev comp (f' : G' ↪g G'') (f : G ↪g G') : G ↪g G'' := theorem coe_comp (f' : G' ↪g G'') (f : G ↪g G') : ⇑(f'.comp f) = f' ∘ f := rfl +theorem comp_assoc (f : G'' ↪g G''') (g : G' ↪g G'') (h : G ↪g G') : + f.comp (g.comp h) = (f.comp g).comp h := rfl + +@[simp] +theorem comp_refl (f : G ↪g G') : f.comp .refl = f := rfl + +@[simp] +theorem refl_comp (f : G ↪g G') : .comp .refl f = f := rfl + /-- Graph embeddings from `G` to `H` are the same thing as graph embeddings from `Gᶜ` to `Hᶜ`. -/ def complEquiv : G ↪g H ≃ Gᶜ ↪g Hᶜ where toFun f := ⟨f.toEmbedding, by simp⟩ @@ -713,7 +731,7 @@ theorem toEmbedding_completeGraph {α β : Type*} (f : α ≃ β) : (Iso.completeGraph f).toEmbedding = Embedding.completeGraph f.toEmbedding := rfl -variable {G'' : SimpleGraph X} +variable {G'' : SimpleGraph X} {G''' : SimpleGraph Y} /-- Composition of graph isomorphisms. -/ abbrev comp (f' : G' ≃g G'') (f : G ≃g G') : G ≃g G'' := @@ -723,6 +741,15 @@ abbrev comp (f' : G' ≃g G'') (f : G ≃g G') : G ≃g G'' := theorem coe_comp (f' : G' ≃g G'') (f : G ≃g G') : ⇑(f'.comp f) = f' ∘ f := rfl +theorem comp_assoc (f : G'' ≃g G''') (g : G' ≃g G'') (h : G ≃g G') : + f.comp (g.comp h) = (f.comp g).comp h := rfl + +@[simp] +theorem comp_refl (f : G ≃g G') : f.comp .refl = f := rfl + +@[simp] +theorem refl_comp (f : G ≃g G') : .comp .refl f = f := rfl + section induce variable {s : Set V} {t : Set W} {r : Set X} From 1680840431e25235216ab3384877c76f073e24a6 Mon Sep 17 00:00:00 2001 From: Bingyu Xia <71547343+BryceT233@users.noreply.github.com> Date: Sat, 13 Jun 2026 09:53:21 +0000 Subject: [PATCH 0002/1300] feat(RingTheory/Extension): `h1CotangentEquivCotangent` (#39520) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given `Algebra R S` and an extension `P : Extension R S`, this PR adds `extendScalars` (viewing `P` as an extension of `S` over `P.Ring`), `defaultHom` (the canonical extension homomorphism from the universal extension `R[S] → S` to `P`) and some related linear equivalences on cotangent spaces or the first homology of the naive cotangent complexes. We show the commutativity of the following diagram: 交换图latex Co-authored-by: @chrisflav --- Mathlib.lean | 1 + .../RingTheory/Extension/Cotangent/Basic.lean | 11 ++ .../RingTheory/Extension/ExtendScalars.lean | 167 ++++++++++++++++++ Mathlib/RingTheory/Extension/Generators.lean | 13 ++ Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 5 + 5 files changed, 197 insertions(+) create mode 100644 Mathlib/RingTheory/Extension/ExtendScalars.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2ac87fdbac13e4..09b8c19e674791 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6491,6 +6491,7 @@ public import Mathlib.RingTheory.Extension.Cotangent.Basic public import Mathlib.RingTheory.Extension.Cotangent.Basis public import Mathlib.RingTheory.Extension.Cotangent.Free public import Mathlib.RingTheory.Extension.Cotangent.LocalizationAway +public import Mathlib.RingTheory.Extension.ExtendScalars public import Mathlib.RingTheory.Extension.Generators public import Mathlib.RingTheory.Extension.Presentation.Basic public import Mathlib.RingTheory.Extension.Presentation.Core diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean index e389a24689ec0e..0f6e4172bbc0d5 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean @@ -68,6 +68,12 @@ def cotangentComplex : P.Cotangent →ₗ[S] P.CotangentSpace := lemma cotangentComplex_mk (x) : P.cotangentComplex (.mk x) = 1 ⊗ₜ .D _ _ x := rfl +lemma Cotangent.mk_C_mem_ker_cotangentComplex {σ : Type*} (G : Generators R S σ) + {r : R} (hr : C r ∈ G.ker) : + Extension.Cotangent.mk ⟨C r, hr⟩ ∈ G.toExtension.cotangentComplex.ker := by + have : D R G.toExtension.Ring (C r) = 0 := Derivation.map_algebraMap .. + simp [this] + section baseChange variable {A : Type*} [CommRing A] [Algebra S A] [Algebra P.Ring A] [IsScalarTower P.Ring S A] @@ -435,6 +441,11 @@ def H1Cotangent.equiv {P₁ P₂ : Extension R S} (f₁ : P₁.Hom P₂) (f₂ : rw [← Extension.H1Cotangent.map_id, eq_comm, map_eq _ (f₁.comp f₂), Extension.H1Cotangent.map_comp]; rfl +omit [IsScalarTower R S S'] in +lemma Cotangent.map_comp_h1Cotangentι (f : P.Hom P') : + Cotangent.map f ∘ₗ P.h1Cotangentι = + P'.h1Cotangentι.restrictScalars S ∘ₗ H1Cotangent.map f := rfl + end Extension namespace Generators diff --git a/Mathlib/RingTheory/Extension/ExtendScalars.lean b/Mathlib/RingTheory/Extension/ExtendScalars.lean new file mode 100644 index 00000000000000..0037ec8ed4ea75 --- /dev/null +++ b/Mathlib/RingTheory/Extension/ExtendScalars.lean @@ -0,0 +1,167 @@ +/- +Copyright (c) 2024 Bingyu Xia. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Bingyu Xia +-/ +module + +public import Mathlib.RingTheory.Kaehler.JacobiZariski + +/-! +# Extension of Scalars for Algebra Extensions + +This file provides APIs for extending the base ring of an algebra extension `P : Extension R S` +to its own extension ring `P.Ring`. We introduce canonical maps and isomorphisms between +the cotangent spaces and the first homology of naive cotangent complex associated with +`P.extendScalars` and `P`. We provide commutativity results of these maps and ismorphisms +(See https://github.com/leanprover-community/mathlib4/pull/39520 for an image of the full diagram). +In particular, we show the boundary map of the Jacobi-Zariski sequence of `R → P.Ring → S` +coincides with `P.cotangentComplex` via a canonical isomorphism `P.h1CotangentEquivCotangent`. + +## Main definitions and results + +- `extendScalars`: Views `P : Extension R S` as `Extension P.Ring S`. +- `toExtendScalars`: The canonical homomorphism from `P` to `P.extendScalars` induced by + the identity map on the underlying extension rings. +- `cotangentExtendScalarsEquiv` : The linear equivalence between the cotangent spaces of + `P.extensScalars` and `P` induced by the identity map. +- `h1CotangentExtendScalarsEquiv`: `P.extensScalars` can be used to compute the first homology of + the naive cotangent complex of `S` over `P.Ring`. +- `h1CotangentEquivOfSurjective`: If `R → P.Ring` is surjective, this is the linear isomorphism + induced by `P.h1Cotangentι`. +- `h1CotangentEquivCotangent`: This is the linear equivalence between `H1Cotangent P.Ring S` and + `P.Cotangent` defined by the composition of `h1CotangentExtendScalarsEquiv.symm`, + `h1CotangentEquivOfSurjective` and `cotangentExtendScalarsEquiv`. +- `cotangentComplex_comp_h1CotangentEquivCotangent`, + `h1CotangentEquivCotangent_comp_map`: commutativity results. + +-/ + +@[expose] public section + +open KaehlerDifferential + +namespace Algebra.Extension + +universe w v u + +variable {R : Type u} {S : Type v} [CommRing R] [CommRing S] [Algebra R S] + +/-- Given an extension `P` of `S` over `R`, `P.extendScalars` is the same extension +but viewed as an extension of `S` over `P.Ring`. -/ +@[simps] +def extendScalars {R : Type u} {S : Type v} [CommRing R] [CommRing S] [Algebra R S] + (P : Extension.{w} R S) : Extension P.Ring S where + Ring := P.Ring + σ := P.σ + algebraMap_σ := P.algebraMap_σ + +set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in +/-- The canonical homomorphism from `P` to `P.extendScalars` induced by the identity map +on the underlying extension rings. -/ +@[simps!] +noncomputable +def toExtendScalars {R : Type u} {S : Type v} [CommRing R] [CommRing S] [Algebra R S] + (P : Extension.{w} R S) : P.Hom P.extendScalars := + .ofAlgHom (IsScalarTower.toAlgHom R P.Ring P.extendScalars.Ring) + (by dsimp; ext; simp) + +/-- `Extension.extendScalars` does not change the cotangent space of an extension. -/ +noncomputable +def cotangentExtendScalarsEquiv {R : Type u} {S : Type v} [CommRing R] [CommRing S] + [Algebra R S] (P : Extension.{w} R S) : + P.extendScalars.Cotangent ≃ₗ[S] P.Cotangent := + LinearEquiv.refl _ _ + +@[simp] +lemma cotangentExtendScalarsEquiv_symm_toLinearMap (P : Extension.{w} R S) : + P.cotangentExtendScalarsEquiv.symm.toLinearMap = Cotangent.map P.toExtendScalars := by + ext x + obtain ⟨x, rfl⟩ := Cotangent.mk_surjective x + rfl + +set_option backward.isDefEq.respectTransparency false in +theorem H1Cotangent.map_toExtendScalars_injective (P : Extension.{w} R S) : + Function.Injective (H1Cotangent.map P.toExtendScalars) := by + rw [← LinearMap.ker_eq_bot, H1Cotangent.map, LinearMap.ker_restrict, + ← cotangentExtendScalarsEquiv_symm_toLinearMap, LinearEquiv.ker, + Submodule.comap_bot, Submodule.ker_subtype] + +/-- The first homology of the naive cotangent complex of `P.extendScalars` is +linearly equivalent to that of `S` over `P.Ring`. -/ +@[simps! toLinearMap] +noncomputable +def h1CotangentExtendScalarsEquiv {R : Type u} {S : Type v} [CommRing R] [CommRing S] + [Algebra R S] (P : Extension.{w} R S) : + P.extendScalars.H1Cotangent ≃ₗ[S] H1Cotangent P.Ring S := + Extension.H1Cotangent.equiv + (.ofAlgHom (Algebra.ofId _ _) (by ext)) P.extendScalars.defaultHom + +@[simp] +lemma h1CotangentExtendScalarsEquiv_symm_toLinearMap (P : Extension.{w} R S) : + P.h1CotangentExtendScalarsEquiv.symm = H1Cotangent.map P.extendScalars.defaultHom := rfl + +/-- Given an extension `P` of `S` over `R` such that `algebraMap R P.Ring` is surjective, +this is the equivalence induced by `P.h1Cotangentι`. -/ +@[simps! toLinearMap] +noncomputable +def h1CotangentEquivOfSurjective {R : Type u} {S : Type v} [CommRing R] [CommRing S] + [Algebra R S] (P : Extension.{w} R S) (h : Function.Surjective (algebraMap R P.Ring)) : + P.H1Cotangent ≃ₗ[S] P.Cotangent where + __ := P.h1Cotangentι + invFun x := ⟨x, by + have : Subsingleton Ω[P.Ring⁄R] := subsingleton_of_surjective R P.Ring h + exact Subsingleton.elim _ _⟩ + +/-- Given an extension `P : Extension R S`, this is the linear equivalence between +the first homology of the naive cotangent complex of `S` over `P.Ring` and +the cotangent space of `P`. -/ +noncomputable +def h1CotangentEquivCotangent {R : Type u} {S : Type v} [CommRing R] [CommRing S] + [Algebra R S] (P : Extension.{w} R S) : + H1Cotangent P.Ring S ≃ₗ[S] P.Cotangent := + P.h1CotangentExtendScalarsEquiv.symm ≪≫ₗ + P.extendScalars.h1CotangentEquivOfSurjective Function.surjective_id ≪≫ₗ + P.cotangentExtendScalarsEquiv + +theorem cotangentComplex_comp_h1CotangentEquivCotangent (P : Extension.{w} R S) : + P.cotangentComplex.comp P.h1CotangentEquivCotangent.toLinearMap = + H1Cotangent.δ R P.Ring S := by + rw [h1CotangentEquivCotangent, LinearEquiv.coe_trans, LinearEquiv.coe_trans, + h1CotangentEquivOfSurjective_toLinearMap, ← LinearMap.comp_assoc, ← LinearMap.comp_assoc, + LinearEquiv.comp_toLinearMap_symm_eq, LinearMap.comp_assoc, + h1CotangentExtendScalarsEquiv_toLinearMap] + ext ⟨x, _⟩ + obtain ⟨⟨x : P.Ring, x_in : x ∈ P.ker⟩, rfl⟩ := Cotangent.mk_surjective x + trans 1 ⊗ₜ[P.Ring] D R P.Ring x; · exact cotangentComplex_mk P ⟨x, x_in⟩ + let u : (Generators.self P.Ring S).toExtension.ker := + ⟨algebraMap P.Ring (Generators.self P.Ring S).toExtension.Ring x, by + rwa [← Ideal.mem_comap, RingHom.comap_ker, ← IsScalarTower.algebraMap_eq]⟩ + rw [← Generators.H1Cotangent.δ_C _ _ u.prop] + congr + +theorem h1CotangentEquivCotangent_comp_map (P : Extension.{w} R S) : + P.h1CotangentEquivCotangent.toLinearMap.comp (Algebra.H1Cotangent.map R P.Ring S S) = + h1Cotangentι.comp (H1Cotangent.map P.defaultHom) := by + rw [h1CotangentEquivCotangent, LinearEquiv.coe_trans, LinearEquiv.coe_trans, + h1CotangentExtendScalarsEquiv_symm_toLinearMap, h1CotangentEquivOfSurjective_toLinearMap, + LinearMap.comp_assoc, LinearMap.comp_assoc, Algebra.H1Cotangent.map, + ← (H1Cotangent.map P.extendScalars.defaultHom).restrictScalars_self, ← H1Cotangent.map_comp, + eq_comm, ← LinearEquiv.toLinearMap_symm_comp_eq, cotangentExtendScalarsEquiv_symm_toLinearMap, + ← LinearMap.comp_assoc, Cotangent.map_comp_h1Cotangentι, LinearMap.restrictScalars_self, + LinearMap.comp_assoc, ← (H1Cotangent.map P.toExtendScalars).restrictScalars_self, + ← H1Cotangent.map_comp, H1Cotangent.map_eq] + +theorem H1Cotangent.map_defaultHom_surjective (P : Extension.{w} R S) : + Function.Surjective (H1Cotangent.map P.defaultHom) := by + rw [← LinearMap.range_eq_top, + ← (Submodule.map_injective_of_injective h1Cotangentι_injective).eq_iff, + ← LinearMap.range_comp, ← P.h1CotangentEquivCotangent_comp_map, LinearMap.range_comp, + ← (Algebra.H1Cotangent.exact_map_δ R P.Ring S).linearMap_ker_eq, Submodule.map_top, + ← exact_hCotangentι_cotangentComplex.linearMap_ker_eq, Submodule.map_equiv_eq_comap_symm, + LinearMap.ker, LinearMap.ker, ← Submodule.comap_comp] + congr + rw [LinearEquiv.comp_toLinearMap_symm_eq, P.cotangentComplex_comp_h1CotangentEquivCotangent] + +end Algebra.Extension diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index a165eabc2a2ff7..1e3ede9f668cb7 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -798,3 +798,16 @@ lemma toAlgHom_ofComp_localizationAway (g : S) [IsLocalization.Away g T] : end Hom end Algebra.Generators + +namespace Algebra.Extension + +set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in +/-- The canonical homomorphism of extensions from the universal extension `R[S] → S` +(given by `Generators.self R S`) to any extension `P` defined via the designated section `P.σ`. -/ +@[simps!] +noncomputable +def defaultHom (P : Extension.{w} R S) : (Generators.self R S).toExtension.Hom P := + .ofAlgHom (MvPolynomial.aeval P.σ) (by dsimp; ext; simp) + +end Algebra.Extension diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index 0175dfdec63ab4..1220b5ccd0bf32 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -400,6 +400,11 @@ lemma δ_eq_δAux (x : Q.ker) (hx) : ((Q.comp P).toExtension.cotangentComplex y) rw [CotangentSpace.fst_compEquiv, Extension.CotangentSpace.map_cotangentComplex, hy, hx] +lemma δ_C {r : S} (hr : C r ∈ Q.ker) : + δ Q P ⟨Extension.Cotangent.mk ⟨C r, hr⟩, Extension.Cotangent.mk_C_mem_ker_cotangentComplex ..⟩ + = 1 ⊗ₜ[S] D R S r := by + rw [δ_eq_δAux, δAux_C] + lemma δ_eq_δ : δ Q P = δ Q P' := by ext ⟨x, hx⟩ obtain ⟨x, rfl⟩ := Extension.Cotangent.mk_surjective x From 9d9fa2436c5971d37e55b6aa8171817dce7bac3c Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Sat, 13 Jun 2026 10:48:58 +0000 Subject: [PATCH 0003/1300] feat: connections between order, `realPart` and `imaginaryPart` in star ordered rings (#40565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mainly, this provides the characterization: `a ≤ b ↔ ℜ a ≤ ℜ b ∧ ℑ a = ℑ b`, but also several related lemmas of convenience. --- Mathlib/LinearAlgebra/Complex/Module.lean | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Mathlib/LinearAlgebra/Complex/Module.lean b/Mathlib/LinearAlgebra/Complex/Module.lean index 30edae0cc3b9f8..7db6282b5b709a 100644 --- a/Mathlib/LinearAlgebra/Complex/Module.lean +++ b/Mathlib/LinearAlgebra/Complex/Module.lean @@ -7,11 +7,13 @@ module public import Mathlib.Algebra.Algebra.RestrictScalars public import Mathlib.Algebra.CharP.Invertible +public import Mathlib.Algebra.Order.Star.Basic public import Mathlib.Algebra.Star.Unitary public import Mathlib.Data.Complex.Basic public import Mathlib.Data.Real.Star public import Mathlib.LinearAlgebra.Matrix.ToLin import Mathlib.Algebra.Module.Torsion.Field +import Mathlib.Algebra.Order.Monoid.Submonoid /-! # Complex number as a vector space over `ℝ` @@ -595,6 +597,42 @@ lemma star_mul_self_eq_realPart_sq_add_imaginaryPart_sq (x : A) [hx : IsStarNorm end NonUnitalNonAssocRing +section StarOrderedRing + +variable [NonUnitalRing A] [StarRing A] [PartialOrder A] + [StarOrderedRing A] [Module ℂ A] [StarModule ℂ A] + +lemma nonneg_iff_realPart_imaginaryPart {a : A} : + 0 ≤ a ↔ 0 ≤ ℜ a ∧ ℑ a = 0 := by + refine ⟨fun h ↦ ⟨?_, h.isSelfAdjoint.imaginaryPart⟩, fun h ↦ ?_⟩ + · simpa +singlePass [← h.isSelfAdjoint.coe_realPart] using! h + · rw [← realPart_add_I_smul_imaginaryPart a, h.2] + simpa using! h.1 + +lemma nonpos_iff_realPart_imaginaryPart {a : A} : + a ≤ 0 ↔ ℜ a ≤ 0 ∧ ℑ a = 0 := by + simpa using nonneg_iff_realPart_imaginaryPart (a := -a) + +lemma realPart_nonneg_of_nonneg {a : A} (ha : 0 ≤ a) : 0 ≤ ℜ a := + nonneg_iff_realPart_imaginaryPart.mp ha |>.1 + +lemma realPart_nonpos_of_nonpos {a : A} (ha : a ≤ 0) : ℜ a ≤ 0 := + nonpos_iff_realPart_imaginaryPart.mp ha |>.1 + +lemma le_iff_realPart_imaginaryPart {a b : A} : + a ≤ b ↔ ℜ a ≤ ℜ b ∧ ℑ a = ℑ b := by + simpa [sub_eq_zero, eq_comm (a := ℑ a)] using nonneg_iff_realPart_imaginaryPart (a := b - a) + +lemma imaginaryPart_eq_of_le {a b : A} (hab : a ≤ b) : + ℑ a = ℑ b := + le_iff_realPart_imaginaryPart.mp hab |>.2 + +lemma realPart_mono {a b : A} (hab : a ≤ b) : + ℜ a ≤ ℜ b := + le_iff_realPart_imaginaryPart.mp hab |>.1 + +end StarOrderedRing + @[simp] lemma realPart_one [Ring A] [StarRing A] [Module ℂ A] [StarModule ℂ A] : ℜ (1 : A) = 1 := by From 36ac4e29ee787119d0ee5e1abba9a560ce7e65d9 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Sat, 13 Jun 2026 12:29:28 +0000 Subject: [PATCH 0004/1300] chore(CategoryTheory/Filtered): generalise criteria for filteredness of `CostructuredArrow` (#40559) From Proetale and subsequently cleaned up by Claude Fable 5. --- Mathlib/CategoryTheory/Filtered/Final.lean | 37 ++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/Mathlib/CategoryTheory/Filtered/Final.lean b/Mathlib/CategoryTheory/Filtered/Final.lean index bebaba5487036e..edd610db14229d 100644 --- a/Mathlib/CategoryTheory/Filtered/Final.lean +++ b/Mathlib/CategoryTheory/Filtered/Final.lean @@ -60,12 +60,12 @@ theorem Functor.initial_of_isCofiltered_costructuredArrow [∀ d, IsCofiltered (CostructuredArrow F d)] : Initial F where out _ := IsCofiltered.isConnected _ -theorem isFiltered_structuredArrow_of_isFiltered_of_exists [IsFilteredOrEmpty C] - (h₁ : ∀ d, ∃ c, Nonempty (d ⟶ F.obj c)) (h₂ : ∀ {d : D} {c : C} (s s' : d ⟶ F.obj c), - ∃ (c' : C) (t : c ⟶ c'), s ≫ F.map t = s' ≫ F.map t) (d : D) : +theorem isFiltered_structuredArrow_of_isFiltered_of_exists [IsFilteredOrEmpty C] (d : D) + (h₁ : ∃ c, Nonempty (d ⟶ F.obj c)) (h₂ : ∀ {c : C} (s s' : d ⟶ F.obj c), + ∃ (c' : C) (t : c ⟶ c'), s ≫ F.map t = s' ≫ F.map t) : IsFiltered (StructuredArrow d F) := by have : Nonempty (StructuredArrow d F) := by - obtain ⟨c, ⟨f⟩⟩ := h₁ d + obtain ⟨c, ⟨f⟩⟩ := h₁ exact ⟨.mk f⟩ suffices IsFilteredOrEmpty (StructuredArrow d F) from IsFiltered.mk refine ⟨fun f g => ?_, fun f g η μ => ?_⟩ @@ -78,18 +78,17 @@ theorem isFiltered_structuredArrow_of_isFiltered_of_exists [IsFilteredOrEmpty C] StructuredArrow.homMk (IsFiltered.coeqHom η.right μ.right) (by simp), ?_⟩ simpa using IsFiltered.coeq_condition _ _ -theorem isCofiltered_costructuredArrow_of_isCofiltered_of_exists [IsCofilteredOrEmpty C] - (h₁ : ∀ d, ∃ c, Nonempty (F.obj c ⟶ d)) (h₂ : ∀ {d : D} {c : C} (s s' : F.obj c ⟶ d), - ∃ (c' : C) (t : c' ⟶ c), F.map t ≫ s = F.map t ≫ s') (d : D) : +theorem isCofiltered_costructuredArrow_of_isCofiltered_of_exists [IsCofilteredOrEmpty C] (d : D) + (h₁ : ∃ c, Nonempty (F.obj c ⟶ d)) (h₂ : ∀ {c : C} (s s' : F.obj c ⟶ d), + ∃ (c' : C) (t : c' ⟶ c), F.map t ≫ s = F.map t ≫ s') : IsCofiltered (CostructuredArrow F d) := by suffices IsFiltered (CostructuredArrow F d)ᵒᵖ from isCofiltered_of_isFiltered_op _ suffices IsFiltered (StructuredArrow (op d) F.op) from IsFiltered.of_equivalence (costructuredArrowOpEquivalence _ _).symm apply isFiltered_structuredArrow_of_isFiltered_of_exists - · intro d - obtain ⟨c, ⟨t⟩⟩ := h₁ d.unop + · obtain ⟨c, ⟨t⟩⟩ := h₁ exact ⟨op c, ⟨Quiver.Hom.op t⟩⟩ - · intro d c s s' + · intro c s s' obtain ⟨c', t, ht⟩ := h₂ s.unop s'.unop exact ⟨op c', Quiver.Hom.op t, Quiver.Hom.unop_inj ht⟩ @@ -99,7 +98,7 @@ theorem Functor.final_of_exists_of_isFiltered [IsFilteredOrEmpty C] (h₁ : ∀ d, ∃ c, Nonempty (d ⟶ F.obj c)) (h₂ : ∀ {d : D} {c : C} (s s' : d ⟶ F.obj c), ∃ (c' : C) (t : c ⟶ c'), s ≫ F.map t = s' ≫ F.map t) : Functor.Final F := by suffices ∀ d, IsFiltered (StructuredArrow d F) from final_of_isFiltered_structuredArrow F - exact isFiltered_structuredArrow_of_isFiltered_of_exists F h₁ h₂ + exact fun d => isFiltered_structuredArrow_of_isFiltered_of_exists F d (h₁ d) h₂ /-- The inclusion of a terminal object is final. -/ theorem Functor.final_const_of_isTerminal [IsFiltered C] {X : D} (hX : IsTerminal X) : @@ -119,7 +118,7 @@ theorem Functor.initial_of_exists_of_isCofiltered [IsCofilteredOrEmpty C] ∃ (c' : C) (t : c' ⟶ c), F.map t ≫ s = F.map t ≫ s') : Functor.Initial F := by suffices ∀ d, IsCofiltered (CostructuredArrow F d) from initial_of_isCofiltered_costructuredArrow F - exact isCofiltered_costructuredArrow_of_isCofiltered_of_exists F h₁ h₂ + exact fun d => isCofiltered_costructuredArrow_of_isCofiltered_of_exists F d (h₁ d) h₂ /-- The inclusion of an initial object is initial. -/ theorem Functor.initial_const_of_isInitial [IsCofiltered C] {X : D} (hX : IsInitial X) : @@ -196,16 +195,14 @@ theorem Functor.initial_of_exists_of_isCofiltered_of_fullyFaithful [IsCofiltered /-- Any under category on a filtered or empty category is filtered. (Note that under categories are always cofiltered since they have an initial object.) -/ instance IsFiltered.under [IsFilteredOrEmpty C] (c : C) : IsFiltered (Under c) := - isFiltered_structuredArrow_of_isFiltered_of_exists _ - (fun c' => ⟨c', ⟨𝟙 _⟩⟩) - (fun s s' => IsFilteredOrEmpty.cocone_maps s s') c + isFiltered_structuredArrow_of_isFiltered_of_exists _ c ⟨c, ⟨𝟙 _⟩⟩ + (fun s s' => IsFilteredOrEmpty.cocone_maps s s') /-- Any over category on a cofiltered or empty category is cofiltered. (Note that over categories are always filtered since they have a terminal object.) -/ instance IsCofiltered.over [IsCofilteredOrEmpty C] (c : C) : IsCofiltered (Over c) := - isCofiltered_costructuredArrow_of_isCofiltered_of_exists _ - (fun c' => ⟨c', ⟨𝟙 _⟩⟩) - (fun s s' => IsCofilteredOrEmpty.cone_maps s s') c + isCofiltered_costructuredArrow_of_isCofiltered_of_exists _ c ⟨c, ⟨𝟙 _⟩⟩ + (fun s s' => IsCofilteredOrEmpty.cone_maps s s') set_option backward.defeqAttrib.useBackward true in /-- The forgetful functor of the under category on any filtered or empty category is final. -/ @@ -296,7 +293,7 @@ theorem Functor.final_iff_isFiltered_structuredArrow [IsFilteredOrEmpty C] : Final F ↔ ∀ d, IsFiltered (StructuredArrow d F) := by refine ⟨?_, fun h => final_of_isFiltered_structuredArrow F⟩ rw [final_iff_of_isFiltered] - exact fun h => isFiltered_structuredArrow_of_isFiltered_of_exists F h.1 h.2 + exact fun h d => isFiltered_structuredArrow_of_isFiltered_of_exists F d (h.1 d) h.2 /-- If `C` is cofiltered, then `F : C ⥤ D` is initial if and only if `CostructuredArrow F d` is cofiltered for all `d : D`. -/ @@ -304,7 +301,7 @@ theorem Functor.initial_iff_isCofiltered_costructuredArrow [IsCofilteredOrEmpty Initial F ↔ ∀ d, IsCofiltered (CostructuredArrow F d) := by refine ⟨?_, fun h => initial_of_isCofiltered_costructuredArrow F⟩ rw [initial_iff_of_isCofiltered] - exact fun h => isCofiltered_costructuredArrow_of_isCofiltered_of_exists F h.1 h.2 + exact fun h d => isCofiltered_costructuredArrow_of_isCofiltered_of_exists F d (h.1 d) h.2 /-- If `C` is filtered, then the structured arrow category on the diagonal functor `C ⥤ C × C` is filtered as well. -/ From 6ca5e2d4f1ab325db1fe867e2da3144302f79904 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Sat, 13 Jun 2026 12:57:04 +0000 Subject: [PATCH 0005/1300] =?UTF-8?q?feat:=20the=20canonical=20approximate?= =?UTF-8?q?=20unit=20in=20a=20C=E2=8B=86-algebra=20is=20not=20`=E2=8A=A5`?= =?UTF-8?q?=20(#40566)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We also add a convenience lemma. This is almost trivial from the definition, but it's useful to have the `closedBall` version. --- Mathlib/Analysis/CStarAlgebra/ApproximateUnit.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Analysis/CStarAlgebra/ApproximateUnit.lean b/Mathlib/Analysis/CStarAlgebra/ApproximateUnit.lean index ab32228a31290d..0e759020348256 100644 --- a/Mathlib/Analysis/CStarAlgebra/ApproximateUnit.lean +++ b/Mathlib/Analysis/CStarAlgebra/ApproximateUnit.lean @@ -158,6 +158,11 @@ lemma eventually_star_eq {l : Filter A} (hl : l.IsIncreasingApproximateUnit) : ∀ᶠ x in l, star x = x := hl.eventually_isSelfAdjoint.mp <| .of_forall fun _ ↦ IsSelfAdjoint.star_eq +omit [StarOrderedRing A] in +lemma closedBall_mem {l : Filter A} (hl : l.IsIncreasingApproximateUnit) : + Metric.closedBall 0 1 ∈ l := by + simpa [Metric.closedBall] using! hl.eventually_norm + lemma pure_one (A : Type*) [CStarAlgebra A] [PartialOrder A] [StarOrderedRing A] : (pure 1 : Filter A).IsIncreasingApproximateUnit where toIsApproximateUnit := .pure_one A @@ -326,6 +331,8 @@ lemma increasingApproximateUnit : neBot := hasBasis_approximateUnit A |>.neBot_iff.mpr fun hx ↦ ⟨_, ⟨le_rfl, by simpa using hx.2.le⟩⟩ +instance : (approximateUnit A).NeBot := (increasingApproximateUnit A).neBot + end CStarAlgebra end ApproximateUnit From bf69091c35a4c18a1294f4fba3528046966fd3b0 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sat, 13 Jun 2026 13:42:07 +0000 Subject: [PATCH 0006/1300] =?UTF-8?q?feat(Order/ConditionallyCompleteLatti?= =?UTF-8?q?ce/Finset):=20`sSup=20s=20=E2=89=A0=20=E2=8A=A4`=20in=20a=20`Co?= =?UTF-8?q?mpleteLinearOrder`=20for=20a=20finite=20set=20without=20`?= =?UTF-8?q?=E2=8A=A4`=20(#38356)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and more generally, `sSup s ≠ a` for a finite set `s` without `a`, when `a ≠ ⊥`. Also adds the equivalent `sInf`/`iSup`/`iInf` lemmas. --- .../ConditionallyCompleteLattice/Finset.lean | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index c6f70a19799255..386e4e5f5ff243 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -179,6 +179,42 @@ end ListMultiset end ConditionallyCompleteLinearOrder +section CompleteLinearOrder + +variable {α : Type*} [CompleteLinearOrder α] {ι : Sort*} + +theorem sSup_ne_of_notMem {s : Set α} (hfin : s.Finite) {a : α} (hne : a ≠ ⊥) (hmem : a ∉ s) : + sSup s ≠ a := by + rcases s.eq_empty_or_nonempty with rfl | hnonempty + · simp [eq_comm, hne] + exact (hmem <| · ▸ hnonempty.csSup_mem hfin) + +theorem sInf_ne_of_notMem {s : Set α} (hfin : s.Finite) {a : α} (hne : a ≠ ⊤) (hmem : a ∉ s) : + sInf s ≠ a := + sSup_ne_of_notMem (α := αᵒᵈ) hfin hne hmem + +theorem sSup_ne_top [Nontrivial α] {s : Set α} (hfin : s.Finite) (htop : ⊤ ∉ s) : sSup s ≠ ⊤ := + sSup_ne_of_notMem hfin top_ne_bot htop + +theorem sInf_ne_bot [Nontrivial α] {s : Set α} (hfin : s.Finite) (hbot : ⊥ ∉ s) : sInf s ≠ ⊥ := + sSup_ne_top (α := αᵒᵈ) hfin hbot + +theorem iSup_ne_of_notMem [Finite ι] {f : ι → α} {a : α} (hne : a ≠ ⊥) (h : ∀ x, f x ≠ a) : + iSup f ≠ a := + sSup_ne_of_notMem (Set.finite_range f) hne <| by grind + +theorem iInf_ne_of_notMem [Finite ι] {f : ι → α} {a : α} (hne : a ≠ ⊤) (h : ∀ x, f x ≠ a) : + iInf f ≠ a := + iSup_ne_of_notMem (α := αᵒᵈ) hne h + +theorem iSup_ne_top [Finite ι] [Nontrivial α] {f : ι → α} (h : ∀ x, f x ≠ ⊤) : iSup f ≠ ⊤ := + iSup_ne_of_notMem top_ne_bot h + +theorem iInf_ne_bot [Finite ι] [Nontrivial α] {f : ι → α} (h : ∀ x, f x ≠ ⊥) : iInf f ≠ ⊥ := + iSup_ne_top (α := αᵒᵈ) h + +end CompleteLinearOrder + /-! ### Relation between `sSup` / `sInf` and `Finset.sup'` / `Finset.inf'` From e0cf79c4769ba1be20bb3e188bc59130676dda9d Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Sat, 13 Jun 2026 14:25:02 +0000 Subject: [PATCH 0007/1300] feat: use `alias_in` attribute for CW complexes (#38785) Using the `alias_in` attribute for classical CW complexes to get rid of the `export` sections. --- .../Topology/CWComplex/Classical/Basic.lean | 127 ++++++++++++------ .../Topology/CWComplex/Classical/Finite.lean | 18 +-- .../CWComplex/Classical/Subcomplex.lean | 16 +-- 3 files changed, 103 insertions(+), 58 deletions(-) diff --git a/Mathlib/Topology/CWComplex/Classical/Basic.lean b/Mathlib/Topology/CWComplex/Classical/Basic.lean index 9ddc89d00f237c..97b4720eaba62a 100644 --- a/Mathlib/Topology/CWComplex/Classical/Basic.lean +++ b/Mathlib/Topology/CWComplex/Classical/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.Normed.Module.RCLike.Real public import Mathlib.Data.ENat.Basic public import Mathlib.Logic.Equiv.PartialEquiv +public import Mathlib.Util.AliasIn /-! # CW complexes @@ -62,6 +63,19 @@ together. cells `cell C` of an absolute CW complex `C`, this actually refers to `RelCWComplex.cell C` through this instance. Again, we want typeclass inference to first consider absolute CW structures. +* The namespaces `CWComplex` and `RelCWComplex` generally should not be opened at the same time + as they contain many declarations with identical names. Still, we want working with absolute + CW complexes to be as convenient as possible. Thus every declaration about relative CW complexes + that doesn't have a modified version for absolute CW complexes should receive an alias in the + `CWComplex` namespace. It is recommended to use the `alias_in` attribute for this here. See + below for a restriction on when we want to create aliases. +* For types and definitions relevant to CW complexes like `cell`, `openCell`, `closedCell`, + `cellFrontier`, `skeletonLT` and similar, we want there to exist only one actually used version, + namely the version in the `RelCWComplex` namespace (and thus no seperate definition in the + `CWComplex` namespace.) This is to avoid unnecessary duplication of lemmas. To achieve this, + definitions from the `RelCWComplex` namespace should be added to the `CWComplex` namespace with + `export` intead of `alias_in`/`alias`. These will then apply to the absolute CW complex through + the instance `CWComplex.instRelCWComplex`. * For statements, the auxiliary construction `skeletonLT` is preferred over `skeleton` as it makes the base case of inductions easier. The statement about `skeleton` should then be derived from the one about `skeletonLT`. @@ -199,7 +213,7 @@ def RelCWComplex.cellFrontier [RelCWComplex C D] (n : ℕ) (i : cell C n) : Set namespace CWComplex -export RelCWComplex (cell map source_eq continuousOn continuousOn_symm mapsTo isClosedBase openCell +export RelCWComplex (cell map source_eq continuousOn continuousOn_symm isClosedBase openCell closedCell cellFrontier) end CWComplex @@ -210,14 +224,17 @@ lemma CWComplex.mapsTo [CWComplex C] (n : ℕ) (i : cell C n) : ∃ I : Π m, Fi simp_rw [empty_union] at this exact this +@[alias_in CWComplex] lemma RelCWComplex.pairwiseDisjoint [RelCWComplex C D] : (univ : Set (Σ n, cell C n)).PairwiseDisjoint (fun ni ↦ openCell ni.1 ni.2) := RelCWComplex.pairwiseDisjoint' +@[alias_in CWComplex] lemma RelCWComplex.disjointBase [RelCWComplex C D] (n : ℕ) (i : cell C n) : Disjoint (openCell n i) D := RelCWComplex.disjointBase' n i +@[alias_in CWComplex] lemma RelCWComplex.disjoint_openCell_of_ne [RelCWComplex C D] {n m : ℕ} {i : cell C n} {j : cell C m} (ne : (⟨n, i⟩ : Σ n, cell C n) ≠ ⟨m, j⟩) : Disjoint (openCell n i) (openCell m j) := @@ -246,23 +263,28 @@ lemma CWComplex.union [CWComplex C] : ⋃ (n : ℕ) (j : cell C n), closedCell n rw [empty_union] at this exact this +@[alias_in CWComplex] lemma RelCWComplex.openCell_subset_closedCell [RelCWComplex C D] (n : ℕ) (i : cell C n) : openCell n i ⊆ closedCell n i := image_mono Metric.ball_subset_closedBall +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_subset_closedCell [RelCWComplex C D] (n : ℕ) (i : cell C n) : cellFrontier n i ⊆ closedCell n i := image_mono Metric.sphere_subset_closedBall +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_union_openCell_eq_closedCell [RelCWComplex C D] (n : ℕ) (i : cell C n) : cellFrontier n i ∪ openCell n i = closedCell n i := by rw [cellFrontier, openCell, closedCell, ← image_union] congrm map n i '' ?_ exact sphere_union_ball +@[alias_in CWComplex] lemma RelCWComplex.map_zero_mem_openCell [RelCWComplex C D] (n : ℕ) (i : cell C n) : map n i 0 ∈ openCell n i := by apply mem_image_of_mem simp only [mem_ball, dist_self, zero_lt_one] +@[alias_in CWComplex] lemma RelCWComplex.map_zero_mem_closedCell [RelCWComplex C D] (n : ℕ) (i : cell C n) : map n i 0 ∈ closedCell n i := openCell_subset_closedCell _ _ (map_zero_mem_openCell _ _) @@ -298,21 +320,26 @@ lemma CWComplex.eq_of_eq_union_iUnion [CWComplex C] (I J : Π n, Set (cell C n)) apply RelCWComplex.eq_of_eq_union_iUnion simp_rw [empty_union, hIJ] +@[alias_in CWComplex] lemma RelCWComplex.isCompact_closedCell [RelCWComplex C D] {n : ℕ} {i : cell C n} : IsCompact (closedCell n i) := (isCompact_closedBall _ _).image_of_continuousOn (continuousOn n i) +@[alias_in CWComplex] lemma RelCWComplex.isClosed_closedCell [RelCWComplex C D] [T2Space X] {n : ℕ} {i : cell C n} : IsClosed (closedCell n i) := isCompact_closedCell.isClosed +@[alias_in CWComplex] lemma RelCWComplex.isCompact_cellFrontier [RelCWComplex C D] {n : ℕ} {i : cell C n} : IsCompact (cellFrontier n i) := (isCompact_sphere _ _).image_of_continuousOn ((continuousOn n i).mono sphere_subset_closedBall) +@[alias_in CWComplex] lemma RelCWComplex.isClosed_cellFrontier [RelCWComplex C D] [T2Space X] {n : ℕ} {i : cell C n} : IsClosed (cellFrontier n i) := isCompact_cellFrontier.isClosed +@[alias_in CWComplex] lemma RelCWComplex.closure_openCell_eq_closedCell [RelCWComplex C D] [T2Space X] {n : ℕ} {j : cell C n} : closure (openCell n j) = closedCell n j := by apply subset_antisymm (isClosed_closedCell.closure_subset_iff.2 (openCell_subset_closedCell n j)) @@ -332,31 +359,38 @@ lemma CWComplex.closed (C : Set X) [CWComplex C] [T2Space X] (A : Set X) (asubc have := RelCWComplex.closed C A asubc simp_all +@[alias_in CWComplex] lemma RelCWComplex.closedCell_subset_complex [RelCWComplex C D] (n : ℕ) (j : cell C n) : closedCell n j ⊆ C := by simp_rw [← union] exact subset_union_of_subset_right (subset_iUnion₂ _ _) _ +@[alias_in CWComplex] lemma RelCWComplex.openCell_subset_complex [RelCWComplex C D] (n : ℕ) (j : cell C n) : openCell n j ⊆ C := (openCell_subset_closedCell _ _).trans (closedCell_subset_complex _ _) +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_subset_complex [RelCWComplex C D] (n : ℕ) (j : cell C n) : cellFrontier n j ⊆ C := (cellFrontier_subset_closedCell n j).trans (closedCell_subset_complex n j) +@[alias_in CWComplex] lemma RelCWComplex.closedCell_zero_eq_singleton [RelCWComplex C D] {j : cell C 0} : closedCell 0 j = {map 0 j ![]} := by simp [closedCell, Matrix.empty_eq] +@[alias_in CWComplex] lemma RelCWComplex.openCell_zero_eq_singleton [RelCWComplex C D] {j : cell C 0} : openCell 0 j = {map 0 j ![]} := by simp [openCell, Matrix.empty_eq] +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_zero_eq_empty [RelCWComplex C D] {j : cell C 0} : cellFrontier 0 j = ∅ := by simp [cellFrontier, sphere_eq_empty_of_subsingleton] +@[alias_in CWComplex] lemma RelCWComplex.nonempty_cellFrontier [CWComplex C] {n : ℕ} (hn : n ≠ 0) (j : cell C n) : (cellFrontier n j).Nonempty := by letI : NeZero n := ⟨hn⟩ @@ -365,6 +399,7 @@ lemma RelCWComplex.nonempty_cellFrontier [CWComplex C] {n : ℕ} (hn : n ≠ 0) use Pi.single 0 1, by simp [Pi.norm_single] /-- If two 0-cells have the same characteristic image point, they are equal. -/ +@[alias_in CWComplex] lemma RelCWComplex.injective_map_zero (C : Set X) [RelCWComplex C D] : Injective ((map 0 · ![]) : cell C 0 → X) := by rintro x z h @@ -372,23 +407,26 @@ lemma RelCWComplex.injective_map_zero (C : Set X) [RelCWComplex C D] : exact not_disjoint_iff.mpr ⟨map 0 x ![], by simp [openCell_zero_eq_singleton, h]⟩ <| disjoint_openCell_of_ne (by grind : (⟨0, x⟩ : Σ n, cell C n) ≠ ⟨0, z⟩) -@[simp] +@[simp, alias_in CWComplex] lemma RelCWComplex.map_zero_eq_self_iff (C : Set X) [RelCWComplex C D] {x z : cell C 0} : map 0 x ![] = map 0 z ![] ↔ x = z := ⟨fun h ↦ injective_map_zero C h, fun h ↦ h ▸ rfl⟩ +@[alias_in CWComplex] lemma RelCWComplex.closedCell_zero_injective (C : Set X) [RelCWComplex C D] : Injective (closedCell 0 : cell C 0 → _) := by intro x y h rw [closedCell_zero_eq_singleton, closedCell_zero_eq_singleton, singleton_eq_singleton_iff] at h exact injective_map_zero C h +@[alias_in CWComplex] lemma RelCWComplex.openCell_zero_injective (C : Set X) [RelCWComplex C D] : Injective (openCell 0 : cell C 0 → _) := by intro x y h rw [openCell_zero_eq_singleton, openCell_zero_eq_singleton, singleton_eq_singleton_iff] at h exact injective_map_zero C h +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_one_eq [RelCWComplex C D] (e : cell C 1) : cellFrontier 1 e = map 1 e '' {-1, 1} := by rw [cellFrontier] @@ -411,10 +449,12 @@ lemma CWComplex.exists_cellFrontier_one_eq [CWComplex C] (e : cell C 1) : simp [RelCWComplex.cellFrontier_one_eq, image_pair, RelCWComplex.closedCell_zero_eq_singleton, hun1, hv1, pair_comm] +@[alias_in CWComplex] lemma RelCWComplex.base_subset_complex [RelCWComplex C D] : D ⊆ C := by simp_rw [← union] exact subset_union_left +@[alias_in CWComplex] lemma RelCWComplex.isClosed [T2Space X] [RelCWComplex C D] : IsClosed C := by rw [closed C C (by rfl)] constructor @@ -467,6 +507,7 @@ lemma CWComplex.iUnion_openCell_eq_complex [CWComplex C] : simpa using RelCWComplex.union_iUnion_openCell_eq_complex (C := C) /-- The contrapositive of `disjoint_openCell_of_ne`. -/ +@[alias_in CWComplex] lemma RelCWComplex.eq_of_not_disjoint_openCell [RelCWComplex C D] {n : ℕ} {j : cell C n} {m : ℕ} {i : cell C m} (h : ¬ Disjoint (openCell n j) (openCell m i)) : (⟨n, j⟩ : (Σ n, cell C n)) = ⟨m, i⟩ := by @@ -629,13 +670,17 @@ instance : PartialOrder (Subcomplex C) := .ofSetLike (Subcomplex C) X initialize_simps_projections Subcomplex (carrier → coe, as_prefix coe) +@[alias_in CWComplex.Subcomplex] lemma mem_carrier {E : Subcomplex C} {x : X} : x ∈ E.carrier ↔ x ∈ (E : Set X) := Iff.rfl +@[alias_in CWComplex.Subcomplex] lemma coe_eq_carrier {E : Subcomplex C} : (E : Set X) = E.carrier := rfl -@[ext] lemma ext {E F : Subcomplex C} (h : ∀ x, x ∈ E ↔ x ∈ F) : E = F := +@[ext, alias_in CWComplex.Subcomplex] +lemma ext {E F : Subcomplex C} (h : ∀ x, x ∈ E ↔ x ∈ F) : E = F := SetLike.ext h +@[alias_in CWComplex.Subcomplex] lemma eq_iff (E F : Subcomplex C) : E = F ↔ (E : Set X) = F := SetLike.coe_injective.eq_iff.symm @@ -648,10 +693,12 @@ protected def copy (E : Subcomplex C) (F : Set X) (hF : F = E) (J : (n : ℕ) closed' := hF.symm ▸ E.closed' union' := hF.symm ▸ hJ ▸ E.union' } -@[simp] lemma coe_copy (E : Subcomplex C) (F : Set X) (hF : F = E) (J : (n : ℕ) → Set (cell C n)) +@[simp, alias_in CWComplex.Subcomplex] +lemma coe_copy (E : Subcomplex C) (F : Set X) (hF : F = E) (J : (n : ℕ) → Set (cell C n)) (hJ : J = E.I) : (E.copy F hF J hJ : Set X) = F := rfl +@[alias_in CWComplex.Subcomplex] lemma copy_eq (E : Subcomplex C) (F : Set X) (hF : F = E) (J : (n : ℕ) → Set (cell C n)) (hJ : J = E.I) : E.copy F hF J hJ = E := SetLike.coe_injective hF @@ -661,6 +708,7 @@ lemma union (E : Subcomplex C) : rw [E.union'] rfl +@[alias_in CWComplex.Subcomplex] lemma closed (E : Subcomplex C) : IsClosed (E : Set X) := E.closed' end Subcomplex @@ -669,13 +717,9 @@ end RelCWComplex namespace CWComplex -export RelCWComplex (Subcomplex) +export RelCWComplex (Subcomplex Subcomplex.I Subcomplex.copy) -namespace Subcomplex - -export RelCWComplex.Subcomplex (I closed union mem_carrier coe_eq_carrier ext copy coe_copy copy_eq) - -end CWComplex.Subcomplex +end CWComplex lemma CWComplex.Subcomplex.union {C : Set X} [CWComplex C] {E : Subcomplex C} : ⋃ (n : ℕ) (j : E.I n), openCell (C := C) n j = E := by @@ -749,22 +793,18 @@ def CWComplex.Subcomplex.mk'' [T2Space X] (C : Set X) [h : CWComplex C] (E : Set rw [empty_union] exact union +@[alias_in CWComplex.Subcomplex] lemma RelCWComplex.Subcomplex.subset_complex {C D : Set X} [RelCWComplex C D] (E : Subcomplex C) : ↑E ⊆ C := by simp_rw [← union, ← RelCWComplex.union_iUnion_openCell_eq_complex] exact union_subset_union_right _ (iUnion_mono fun _ ↦ iUnion_mono' fun j ↦ ⟨j, subset_rfl⟩) +@[alias_in CWComplex.Subcomplex] lemma RelCWComplex.Subcomplex.base_subset {C D : Set X} [RelCWComplex C D] (E : Subcomplex C) : D ⊆ E := by simp_rw [← union] exact subset_union_left -namespace CWComplex.Subcomplex - -export RelCWComplex.Subcomplex (subset_complex base_subset) - -end CWComplex.Subcomplex - end Subcomplex section skeleton @@ -778,7 +818,7 @@ This allows the base case of induction to be about the base instead of being abo the base and some points. The standard `skeleton` is defined in terms of `skeletonLT`. `skeletonLT` is preferred in statements. You should then derive the statement about `skeleton`. -/ -@[simps! -isSimp, irreducible] +@[simps! (attr := alias_in CWComplex) -isSimp, irreducible] def skeletonLT (C : Set X) {D : Set X} [RelCWComplex C D] (n : ℕ∞) : Subcomplex C := Subcomplex.mk' _ (D ∪ ⋃ (m : ℕ) (_ : m < n) (j : cell C m), closedCell m j) (fun l ↦ {x : cell C l | l < n}) @@ -803,7 +843,7 @@ end RelCWComplex namespace CWComplex -export RelCWComplex (skeletonLT coe_skeletonLT skeletonLT_I skeleton) +export RelCWComplex (skeletonLT skeleton) end CWComplex @@ -813,11 +853,14 @@ lemma RelCWComplex.skeletonLT_zero_eq_base [RelCWComplex C D] : skeletonLT C 0 = lemma CWComplex.skeletonLT_zero_eq_empty [CWComplex C] : (skeletonLT C 0 : Set X) = ∅ := RelCWComplex.skeletonLT_zero_eq_base -@[simp] lemma RelCWComplex.skeletonLT_top [RelCWComplex C D] : skeletonLT C ⊤ = C := by +@[simp, alias_in CWComplex] lemma RelCWComplex.skeletonLT_top [RelCWComplex C D] : + skeletonLT C ⊤ = C := by simp [coe_skeletonLT, union] -@[simp] lemma RelCWComplex.skeleton_top [RelCWComplex C D] : skeleton C ⊤ = C := skeletonLT_top +@[simp, alias_in CWComplex] lemma RelCWComplex.skeleton_top [RelCWComplex C D] : skeleton C ⊤ = C := + skeletonLT_top +@[alias_in CWComplex] lemma RelCWComplex.skeletonLT_mono [RelCWComplex C D] {n m : ℕ∞} (h : m ≤ n) : (skeletonLT C m : Set X) ⊆ skeletonLT C n := by simp_rw [coe_skeletonLT] @@ -827,16 +870,20 @@ lemma RelCWComplex.skeletonLT_mono [RelCWComplex C D] {n m : ℕ∞} (h : m ≤ obtain ⟨l, lltm, xmeml⟩ := xmem exact ⟨l, lt_of_lt_of_le lltm h, xmeml⟩ +@[alias_in CWComplex] lemma RelCWComplex.skeletonLT_monotone [RelCWComplex C D] : Monotone (skeletonLT C) := fun _ _ h ↦ skeletonLT_mono h +@[alias_in CWComplex] lemma RelCWComplex.skeleton_mono [RelCWComplex C D] {n m : ℕ∞} (h : m ≤ n) : (skeleton C m : Set X) ⊆ skeleton C n := skeletonLT_mono (by gcongr) +@[alias_in CWComplex] lemma RelCWComplex.skeleton_monotone [RelCWComplex C D] : Monotone (skeleton C) := fun _ _ h ↦ skeleton_mono h +@[alias_in CWComplex] lemma RelCWComplex.closedCell_subset_skeletonLT [RelCWComplex C D] (n : ℕ) (j : cell C n) : closedCell n j ⊆ skeletonLT C (n + 1) := by intro x xmem @@ -845,18 +892,22 @@ lemma RelCWComplex.closedCell_subset_skeletonLT [RelCWComplex C D] (n : ℕ) (j simp_rw [mem_iUnion, exists_prop] refine ⟨n, (by norm_cast; exact lt_add_one n), ⟨j,xmem⟩⟩ +@[alias_in CWComplex] lemma RelCWComplex.closedCell_subset_skeleton [RelCWComplex C D] (n : ℕ) (j : cell C n) : closedCell n j ⊆ skeleton C n := closedCell_subset_skeletonLT n j +@[alias_in CWComplex] lemma RelCWComplex.openCell_subset_skeletonLT [RelCWComplex C D] (n : ℕ) (j : cell C n) : openCell n j ⊆ skeletonLT C (n + 1) := (openCell_subset_closedCell _ _).trans (closedCell_subset_skeletonLT _ _) +@[alias_in CWComplex] lemma RelCWComplex.openCell_subset_skeleton [RelCWComplex C D] (n : ℕ) (j : cell C n) : openCell n j ⊆ skeleton C n := (openCell_subset_closedCell _ _).trans (closedCell_subset_skeleton _ _) +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_subset_skeletonLT [RelCWComplex C D] (n : ℕ) (j : cell C n) : cellFrontier n j ⊆ skeletonLT C n := by obtain ⟨I, hI⟩ := cellFrontier_subset_base_union_finite_closedCell n j @@ -868,18 +919,22 @@ lemma RelCWComplex.cellFrontier_subset_skeletonLT [RelCWComplex C D] (n : ℕ) ( obtain ⟨i, iltn, j, _, xmem⟩ := xmem exact ⟨i, by norm_cast, j, xmem⟩ +@[alias_in CWComplex] lemma RelCWComplex.cellFrontier_subset_skeleton [RelCWComplex C D] (n : ℕ) (j : cell C (n + 1)) : cellFrontier (n + 1) j ⊆ skeleton C n := cellFrontier_subset_skeletonLT _ _ +@[alias_in CWComplex] lemma RelCWComplex.iUnion_cellFrontier_subset_skeletonLT [RelCWComplex C D] (l : ℕ) : ⋃ (j : cell C l), cellFrontier l j ⊆ skeletonLT C l := iUnion_subset (fun _ ↦ cellFrontier_subset_skeletonLT _ _) +@[alias_in CWComplex] lemma RelCWComplex.iUnion_cellFrontier_subset_skeleton [RelCWComplex C D] (l : ℕ) : ⋃ (j : cell C l), cellFrontier l j ⊆ skeleton C l := (iUnion_cellFrontier_subset_skeletonLT l).trans (skeletonLT_mono le_self_add) +@[alias_in CWComplex] lemma RelCWComplex.skeletonLT_union_iUnion_closedCell_eq_skeletonLT_succ [RelCWComplex C D] (n : ℕ) : (skeletonLT C n : Set X) ∪ ⋃ (j : cell C n), closedCell n j = skeletonLT C (n + 1) := by @@ -888,6 +943,7 @@ lemma RelCWComplex.skeletonLT_union_iUnion_closedCell_eq_skeletonLT_succ [RelCWC norm_cast exact (biUnion_lt_succ _ _).symm +@[alias_in CWComplex] lemma RelCWComplex.skeleton_union_iUnion_closedCell_eq_skeleton_succ [RelCWComplex C D] (n : ℕ) : (skeleton C n : Set X) ∪ ⋃ (j : cell C (n + 1)), closedCell (n + 1) j = skeleton C (n + 1) := skeletonLT_union_iUnion_closedCell_eq_skeletonLT_succ _ @@ -909,6 +965,7 @@ lemma CWComplex.iUnion_openCell_eq_skeleton [CWComplex C] (n : ℕ∞) : ⋃ (m : ℕ) (_ : m < n + 1) (j : cell C m), openCell m j = skeleton C n := iUnion_openCell_eq_skeletonLT _ +@[alias_in CWComplex] lemma RelCWComplex.iUnion_skeletonLT_eq_complex [RelCWComplex C D] : ⋃ (n : ℕ), skeletonLT C n = C := by apply subset_antisymm (iUnion_subset_iff.2 fun _ ↦ (skeletonLT C _).subset_complex) @@ -916,6 +973,7 @@ lemma RelCWComplex.iUnion_skeletonLT_eq_complex [RelCWComplex C D] : exact ⟨subset_iUnion_of_subset 0 (skeletonLT C 0).base_subset, fun n i ↦ subset_iUnion_of_subset _ (openCell_subset_skeletonLT n i)⟩ +@[alias_in CWComplex] lemma RelCWComplex.iUnion_skeleton_eq_complex [RelCWComplex C D] : ⋃ (n : ℕ), skeleton C n = C := by apply subset_antisymm (iUnion_subset_iff.2 fun _ ↦ (skeleton C _).subset_complex) @@ -940,11 +998,15 @@ lemma RelCWComplex.mem_skeleton_iff [RelCWComplex C D] {n : ℕ∞} {x : X} : · simp · rw [← Nat.cast_one, ← Nat.cast_add, Nat.cast_lt, Nat.cast_le, Order.lt_add_one_iff] -lemma CWComplex.exists_mem_openCell_of_mem_skeleton [CWComplex C] {n : ℕ∞} {x : X} : +lemma CWComplex.mem_skeleton_iff [CWComplex C] {n : ℕ∞} {x : X} : x ∈ skeleton C n ↔ ∃ (m : ℕ) (_ : m ≤ n) (j : cell C m), x ∈ openCell m j := by rw [RelCWComplex.mem_skeleton_iff, mem_empty_iff_false, false_or] +@[deprecated (since := "2026-04-30")] alias CWComplex.exists_mem_openCell_of_mem_skeleton := + CWComplex.mem_skeleton_iff + /-- A skeleton and an open cell of a higher dimension are disjoint. -/ +@[alias_in CWComplex] lemma RelCWComplex.disjoint_skeletonLT_openCell [RelCWComplex C D] {n : ℕ∞} {m : ℕ} {j : cell C m} (hnm : n ≤ m) : Disjoint (skeletonLT C n : Set X) (openCell m j) := by -- This is a consequence of `iUnion_openCell_eq_skeletonLT` and `disjoint_openCell_of_ne` @@ -957,12 +1019,14 @@ lemma RelCWComplex.disjoint_skeletonLT_openCell [RelCWComplex C D] {n : ℕ∞} exact (lt_self_iff_false m).mp (ENat.coe_lt_coe.1 (hln.trans_le hnm)) /-- A skeleton and an open cell of a higher dimension are disjoint. -/ +@[alias_in CWComplex] lemma RelCWComplex.disjoint_skeleton_openCell [RelCWComplex C D] {n : ℕ∞} {m : ℕ} {j : cell C m} (nlem : n < m) : Disjoint (skeleton C n : Set X) (openCell m j) := disjoint_skeletonLT_openCell (Order.add_one_le_of_lt nlem) /-- A skeleton intersected with a closed cell of a higher dimension is the skeleton intersected with the boundary of the cell. -/ +@[alias_in CWComplex] lemma RelCWComplex.skeletonLT_inter_closedCell_eq_skeletonLT_inter_cellFrontier [RelCWComplex C D] {n : ℕ∞} {m : ℕ} {j : cell C m} (hnm : n ≤ m) : (skeletonLT C n : Set X) ∩ closedCell m j = (skeletonLT C n : Set X) ∩ cellFrontier m j := by @@ -973,6 +1037,7 @@ lemma RelCWComplex.skeletonLT_inter_closedCell_eq_skeletonLT_inter_cellFrontier exact empty_subset _ /-- Version of `skeletonLT_inter_closedCell_eq_skeletonLT_inter_cellFrontier` using `skeleton`. -/ +@[alias_in CWComplex] lemma RelCWComplex.skeleton_inter_closedCell_eq_skeleton_inter_cellFrontier [RelCWComplex C D] {n : ℕ∞} {m : ℕ} {j : cell C m} (hnm : n < m) : (skeleton C n : Set X) ∩ closedCell m j = (skeleton C n : Set X) ∩ cellFrontier m j := @@ -996,24 +1061,4 @@ lemma RelCWComplex.disjoint_interior_base_iUnion_closedCell [T2Space X] [RelCWCo simp_rw [disjoint_iff_inter_eq_empty, inter_iUnion, disjoint_interior_base_closedCell.inter_eq, iUnion_empty] -namespace CWComplex - -export RelCWComplex (pairwiseDisjoint disjoint_openCell_of_ne openCell_subset_closedCell - cellFrontier_subset_closedCell cellFrontier_union_openCell_eq_closedCell map_zero_mem_openCell - map_zero_mem_closedCell isCompact_closedCell isClosed_closedCell isCompact_cellFrontier - isClosed_cellFrontier closure_openCell_eq_closedCell skeletonLT_top skeleton_top skeletonLT_mono - skeleton_mono skeletonLT_monotone skeleton_monotone closedCell_subset_skeletonLT - closedCell_subset_skeleton closedCell_subset_complex openCell_subset_skeletonLT - openCell_subset_skeleton - openCell_subset_complex cellFrontier_subset_skeletonLT cellFrontier_subset_skeleton - cellFrontier_subset_complex iUnion_cellFrontier_subset_skeletonLT - iUnion_cellFrontier_subset_skeleton closedCell_zero_eq_singleton openCell_zero_eq_singleton - cellFrontier_zero_eq_empty isClosed skeletonLT_union_iUnion_closedCell_eq_skeletonLT_succ - skeleton_union_iUnion_closedCell_eq_skeleton_succ iUnion_skeletonLT_eq_complex - iUnion_skeleton_eq_complex eq_of_not_disjoint_openCell disjoint_skeletonLT_openCell - disjoint_skeleton_openCell skeletonLT_inter_closedCell_eq_skeletonLT_inter_cellFrontier - skeleton_inter_closedCell_eq_skeleton_inter_cellFrontier) - -end CWComplex - end Topology diff --git a/Mathlib/Topology/CWComplex/Classical/Finite.lean b/Mathlib/Topology/CWComplex/Classical/Finite.lean index f28ba68f9b5798..993561d306d25e 100644 --- a/Mathlib/Topology/CWComplex/Classical/Finite.lean +++ b/Mathlib/Topology/CWComplex/Classical/Finite.lean @@ -42,18 +42,24 @@ class RelCWComplex.FiniteDimensional.{u} {X : Type u} [TopologicalSpace X] (C : /-- For some natural number `n`, the type `cell C m` is empty for all `m ≥ n`. -/ eventually_isEmpty_cell : ∀ᶠ n in Filter.atTop, IsEmpty (cell C n) +alias CWComplex.FiniteDimensional.eventually_isEmpty_cell := + RelCWComplex.FiniteDimensional.eventually_isEmpty_cell + /-- A CW complex is of finite type if `cell C n` is finite for every `n`. -/ class RelCWComplex.FiniteType.{u} {X : Type u} [TopologicalSpace X] (C : Set X) {D : Set X} [RelCWComplex C D] : Prop where /-- `cell C n` is finite for every `n`. -/ finite_cell (n : ℕ) : Finite (cell C n) +alias CWComplex.FiniteType.finite_cell := RelCWComplex.FiniteType.finite_cell + /-- A CW complex is finite if it is finite dimensional and of finite type. -/ class RelCWComplex.Finite {X : Type*} [TopologicalSpace X] (C : Set X) {D : Set X} [RelCWComplex C D] extends FiniteDimensional C, FiniteType C variable {X : Type*} [TopologicalSpace X] (C : Set X) {D : Set X} [RelCWComplex C D] +@[alias_in CWComplex] lemma RelCWComplex.finite_of_finiteDimensional_finiteType [FiniteDimensional C] [FiniteType C] : Finite C where eventually_isEmpty_cell := FiniteDimensional.eventually_isEmpty_cell @@ -61,8 +67,7 @@ lemma RelCWComplex.finite_of_finiteDimensional_finiteType [FiniteDimensional C] namespace CWComplex -export RelCWComplex (FiniteDimensional FiniteType Finite FiniteDimensional.eventually_isEmpty_cell - FiniteType.finite_cell finite_of_finiteDimensional_finiteType) +export RelCWComplex (FiniteDimensional FiniteType Finite) end CWComplex @@ -306,6 +311,7 @@ variable {X : Type*} [TopologicalSpace X] {C D : Set X} [RelCWComplex C D] /-- If the collection of all cells (of any dimension) of a relative CW complex `C` is finite, then `C` is finite as a CW complex. -/ +@[alias_in CWComplex] lemma RelCWComplex.finite_of_finite_cells (finite : _root_.Finite (Σ n, cell C n)) : Finite C where eventually_isEmpty_cell := by simp only [Filter.eventually_atTop] @@ -329,6 +335,7 @@ lemma RelCWComplex.finite_of_finite_cells (finite : _root_.Finite (Σ n, cell C /-- If `C` is finite as a CW complex then the collection of all cells (of any dimension) is finite. -/ +@[alias_in CWComplex] lemma RelCWComplex.finite_cells_of_finite [finite : Finite C] : _root_.Finite (Σ n, cell C n) := by -- We show that there is a bijection between `Σ n, cell C n` and -- `Σ (m : {m : ℕ // m < n}), cell C m`. @@ -348,13 +355,8 @@ lemma RelCWComplex.finite_cells_of_finite [finite : Finite C] : _root_.Finite ( exact Finite.instSigma /-- A CW complex is finite iff the total number of its cells is finite. -/ +@[alias_in CWComplex] lemma RelCWComplex.finite_iff_finite_cells : Finite C ↔ _root_.Finite (Σ n, cell C n) := ⟨fun h ↦ finite_cells_of_finite (finite := h), finite_of_finite_cells⟩ -namespace CWComplex - -export RelCWComplex (finite_of_finite_cells finite_cells_of_finite finite_iff_finite_cells) - -end CWComplex - end Topology diff --git a/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean b/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean index 438323f8296faf..3c8c3994156c1d 100644 --- a/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean +++ b/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean @@ -32,6 +32,7 @@ namespace Topology variable {X : Type*} [t : TopologicalSpace X] {C D : Set X} +@[alias_in CWComplex.Subcomplex] lemma RelCWComplex.Subcomplex.closedCell_subset_of_mem [T2Space X] [RelCWComplex C D] (E : Subcomplex C) {n : ℕ} {i : cell C n} (hi : i ∈ E.I n) : closedCell n i ⊆ E := by @@ -40,11 +41,13 @@ lemma RelCWComplex.Subcomplex.closedCell_subset_of_mem [T2Space X] [RelCWComplex exact subset_iUnion_of_subset n (subset_iUnion (fun (j : ↑(E.I n)) ↦ openCell (C := C) n j) ⟨i, hi⟩) +@[alias_in CWComplex.Subcomplex] lemma RelCWComplex.Subcomplex.openCell_subset_of_mem [T2Space X] [RelCWComplex C D] (E : Subcomplex C) {n : ℕ} {i : cell C n} (hi : i ∈ E.I n) : openCell n i ⊆ E := (openCell_subset_closedCell n i).trans (closedCell_subset_of_mem E hi) +@[alias_in CWComplex.Subcomplex] lemma RelCWComplex.Subcomplex.cellFrontier_subset_of_mem [T2Space X] [RelCWComplex C D] (E : Subcomplex C) {n : ℕ} {i : cell C n} (hi : i ∈ E.I n) : cellFrontier n i ⊆ E := @@ -66,6 +69,7 @@ lemma CWComplex.Subcomplex.union_closedCell [T2Space X] [CWComplex C] (E : Subco ⋃ (n : ℕ) (j : E.I n), closedCell (C := C) n j = E := (empty_union _).symm.trans (RelCWComplex.Subcomplex.union_closedCell E) +@[alias_in CWComplex.Subcomplex] lemma RelCWComplex.Subcomplex.disjoint_openCell_subcomplex_of_not_mem [RelCWComplex C D] (E : Subcomplex C) {n : ℕ} {i : cell C n} (h : i ∉ E.I n) : Disjoint (openCell n i) E := by simp_rw [← union, disjoint_union_right, disjoint_iUnion_right] @@ -142,12 +146,14 @@ lemma RelCWComplex.Subcomplex.cellFrontier_eq [T2Space X] [RelCWComplex C D] (E (n : ℕ) (i : E.I n) : cellFrontier (C := E) n i = cellFrontier n (i : cell C n) := by rfl +@[alias_in CWComplex.Subcomplex] instance RelCWComplex.Subcomplex.finiteType_subcomplex_of_finiteType [T2Space X] [RelCWComplex C D] [FiniteType C] (E : Subcomplex C) : FiniteType (E : Set X) where finite_cell n := let _ := FiniteType.finite_cell (C := C) (D := D) n Subtype.finite +@[alias_in CWComplex.Subcomplex] instance RelCWComplex.Subcomplex.finiteDimensional_subcomplex_of_finiteDimensional [T2Space X] [RelCWComplex C D] [FiniteDimensional C] (E : Subcomplex C) : FiniteDimensional (E : Set X) where @@ -156,17 +162,9 @@ instance RelCWComplex.Subcomplex.finiteDimensional_subcomplex_of_finiteDimension simp [isEmpty_subtype] /-- A subcomplex of a finite CW complex is again finite. -/ +@[alias_in CWComplex.Subcomplex] instance RelCWComplex.Subcomplex.finite_subcomplex_of_finite [T2Space X] [RelCWComplex C D] [Finite C] (E : Subcomplex C) : Finite (E : Set X) := finite_of_finiteDimensional_finiteType _ -namespace CWComplex.Subcomplex - -export RelCWComplex.Subcomplex (closedCell_subset_of_mem openCell_subset_of_mem - cellFrontier_subset_of_mem disjoint_openCell_subcomplex_of_not_mem subset_complex - finiteType_subcomplex_of_finiteType finiteDimensional_subcomplex_of_finiteDimensional - finite_subcomplex_of_finite) - -end CWComplex.Subcomplex - end Topology From c3c39061306554f18e141a8008b30778118c3285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= <4094732+RemyDegenne@users.noreply.github.com> Date: Sat, 13 Jun 2026 14:25:04 +0000 Subject: [PATCH 0008/1300] feat(Probability/Decision): Bayes estimators (#39810) This PR adds the concept of a Bayes estimator for an estimation problem: an estimator that attains the Bayes risk. We can get such estimators by taking an argmin of an integral involving a posterior kernel, when a measurable version of that argmin exists. Co-authored-by: Lorenzo Luccioli @LorenzoLuccioli Co-authored-by: Remy Degenne --- Mathlib.lean | 1 + .../Probability/Decision/BayesEstimator.lean | 168 ++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 Mathlib/Probability/Decision/BayesEstimator.lean diff --git a/Mathlib.lean b/Mathlib.lean index 09b8c19e674791..2ba33f02117f1e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6202,6 +6202,7 @@ public import Mathlib.Probability.Combinatorics.BinomialRandomGraph.Defs public import Mathlib.Probability.CondVar public import Mathlib.Probability.ConditionalExpectation public import Mathlib.Probability.ConditionalProbability +public import Mathlib.Probability.Decision.BayesEstimator public import Mathlib.Probability.Decision.Risk.Basic public import Mathlib.Probability.Decision.Risk.Countable public import Mathlib.Probability.Decision.Risk.Defs diff --git a/Mathlib/Probability/Decision/BayesEstimator.lean b/Mathlib/Probability/Decision/BayesEstimator.lean new file mode 100644 index 00000000000000..7f3991f3a74edc --- /dev/null +++ b/Mathlib/Probability/Decision/BayesEstimator.lean @@ -0,0 +1,168 @@ +/- +Copyright (c) 2025 Rémy Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rémy Degenne, Lorenzo Luccioli +-/ +module + +public import Mathlib.Probability.Decision.Risk.Defs +public import Mathlib.Probability.Kernel.Posterior + +import Mathlib.Probability.Decision.Risk.Basic + +/-! +# Bayes estimator + +Let `Θ` be a parameter space, `𝓧` a data space, `𝓨` a prediction space, `P : Kernel Θ 𝓧` a +data generating kernel, `π` a prior on the parameter space, and `ℓ : Θ → 𝓨 → ℝ≥0∞` a loss function. + +An estimator (a `Kernel 𝓧 𝓨`) is said to be a Bayes estimator if it attains the Bayes risk for +the estimation problem. +It can be written as a measurable function `x ↦ argmin_y P†π(x)[θ ↦ ℓ θ y]` +for `(P ∘ₘ π)`-almost every `x`, where `P†π` is the posterior kernel, whenever we can select +the argmin in a measurable way. + +## Main definitions + +* `IsBayesEstimator`: an estimator is a Bayes estimator if it attains the Bayes risk for the prior. +* `IsArgminEstimator`: a measurable function `f : 𝓧 → 𝓨` is an argmin estimator + if for `(P ∘ₘ π)`-almost every `x` the value `f x` belongs to `argmin_y P†π(x)[θ ↦ ℓ θ y]`. +* `HasArgminEstimator`: the estimation problem admits an argmin estimator. + That is, we can choose the argmin of the posterior expected loss in a measurable way. + +## Main statements + +* `lintegral_iInf_posterior_le_bayesRisk`: the Bayes risk with respect to a prior is bounded + from below by the integral over the data (with distribution `P ∘ₘ π`) of the infimum over the + possible predictions `y` of the posterior loss `∫⁻ θ, ℓ θ y ∂((P†π) x)`: + `∫⁻ x, ⨅ y : 𝓨, ∫⁻ θ, ℓ θ y ∂((P†π) x) ∂(P ∘ₘ π) ≤ bayesRisk ℓ P π` +* `IsArgminEstimator.isBayesEstimator`: an argmin Bayes estimator is a Bayes estimator. + That is, it minimizes the Bayesian risk. +* `bayesRisk_eq_of_hasArgminEstimator`: if the estimation problem admits an argmin estimator, + then the Bayesian risk attains the risk lower bound `∫⁻ x, ⨅ y, ∫⁻ θ, ℓ θ y ∂(P†π) x ∂(P ∘ₘ π)`. + +## TODO + +Once Mathlib has measurable selection theorems, we will be able to prove `HasArgminEstimator` under +general conditions on the measurable spaces `𝓧` and/or `𝓨`. + +-/ + +@[expose] public section + +open MeasureTheory +open scoped ENNReal NNReal + +namespace ProbabilityTheory + +variable {Θ 𝓧 𝓨 : Type*} {mΘ : MeasurableSpace Θ} {m𝓧 : MeasurableSpace 𝓧} {m𝓨 : MeasurableSpace 𝓨} + {ℓ : Θ → 𝓨 → ℝ≥0∞} {P : Kernel Θ 𝓧} {κ : Kernel 𝓧 𝓨} {π : Measure Θ} + +section Posterior + +variable [StandardBorelSpace Θ] [Nonempty Θ] + +/-- The average risk of an estimator `κ` with respect to a prior `π` can be expressed as +an integral in the following way: `R_π(κ) = ((P†π × κ) ∘ P ∘ π)[(θ, y) ↦ ℓ θ y]`. -/ +lemma avgRisk_eq_lintegral_posterior_prod + (hl : Measurable (Function.uncurry ℓ)) (P : Kernel Θ 𝓧) [IsFiniteKernel P] + (κ : Kernel 𝓧 𝓨) [IsSFiniteKernel κ] (π : Measure Θ) [IsFiniteMeasure π] : + avgRisk ℓ P κ π = ∫⁻ θy, ℓ θy.1 θy.2 ∂(((P†π) ×ₖ κ) ∘ₘ (P ∘ₘ π)) := by + rw [avgRisk, ← Measure.lintegral_compProd (f := fun θy ↦ ℓ θy.1 θy.2) (by fun_prop)] + congr + calc π ⊗ₘ (κ ∘ₖ P) = (Kernel.id ∥ₖ κ) ∘ₘ (π ⊗ₘ P) := Measure.parallelComp_comp_compProd.symm + _ = (Kernel.id ∥ₖ κ) ∘ₘ ((P†π) ×ₖ Kernel.id) ∘ₘ P ∘ₘ π := by rw [posterior_prod_id_comp] + _ = ((P†π) ×ₖ κ) ∘ₘ P ∘ₘ π := by + rw [Measure.comp_assoc, Kernel.parallelComp_comp_prod, Kernel.id_comp, Kernel.comp_id] + +lemma avgRisk_eq_lintegral_lintegral_lintegral + (hl : Measurable (Function.uncurry ℓ)) (P : Kernel Θ 𝓧) [IsFiniteKernel P] + (κ : Kernel 𝓧 𝓨) [IsSFiniteKernel κ] (π : Measure Θ) [IsFiniteMeasure π] : + avgRisk ℓ P κ π = ∫⁻ x, ∫⁻ y, ∫⁻ θ, ℓ θ y ∂(P†π) x ∂κ x ∂(P ∘ₘ π) := by + rw [avgRisk_eq_lintegral_posterior_prod hl, Measure.lintegral_bind (by fun_prop) (by fun_prop)] + congr with x + rw [Kernel.prod_apply, lintegral_prod_symm' _ (by fun_prop)] + +lemma lintegral_iInf_posterior_le_avgRisk + (hl : Measurable (Function.uncurry ℓ)) (P : Kernel Θ 𝓧) [IsFiniteKernel P] + (κ : Kernel 𝓧 𝓨) [IsMarkovKernel κ] (π : Measure Θ) [IsFiniteMeasure π] : + ∫⁻ x, ⨅ y : 𝓨, ∫⁻ θ, ℓ θ y ∂((P†π) x) ∂(P ∘ₘ π) ≤ avgRisk ℓ P κ π := by + rw [avgRisk_eq_lintegral_lintegral_lintegral hl] + gcongr with x + exact iInf_le_lintegral _ + +lemma lintegral_iInf_posterior_le_bayesRisk + (hl : Measurable (Function.uncurry ℓ)) (P : Kernel Θ 𝓧) [IsFiniteKernel P] + (π : Measure Θ) [IsFiniteMeasure π] : + ∫⁻ x, ⨅ y : 𝓨, ∫⁻ θ, ℓ θ y ∂((P†π) x) ∂(P ∘ₘ π) ≤ bayesRisk ℓ P π := + le_iInf₂ fun κ _ ↦ lintegral_iInf_posterior_le_avgRisk hl P κ π + +end Posterior + +/-- An estimator is a Bayes estimator for a prior `π` if it attains the Bayes risk for `π`. -/ +def IsBayesEstimator (ℓ : Θ → 𝓨 → ℝ≥0∞) (P : Kernel Θ 𝓧) (κ : Kernel 𝓧 𝓨) (π : Measure Θ) : Prop := + avgRisk ℓ P κ π = bayesRisk ℓ P π + +variable [StandardBorelSpace Θ] [Nonempty Θ] {f : 𝓧 → 𝓨} [IsFiniteKernel P] [IsFiniteMeasure π] + +/-- We say that a measurable function `f : 𝓧 → 𝓨` is an argmin estimator +with respect to the prior `π` if for `(P ∘ₘ π)`-almost every `x` it is of +the form `x ↦ argmin_y P†π(x)[θ ↦ ℓ θ y]`. -/ +structure IsArgminEstimator {𝓨 : Type*} [MeasurableSpace 𝓨] + (ℓ : Θ → 𝓨 → ℝ≥0∞) (P : Kernel Θ 𝓧) [IsFiniteKernel P] + (π : Measure Θ) [IsFiniteMeasure π] (f : 𝓧 → 𝓨) : Prop where + measurable : Measurable f + property : ∀ᵐ x ∂(P ∘ₘ π), ∫⁻ θ, ℓ θ (f x) ∂(P†π) x = ⨅ y, ∫⁻ θ, ℓ θ y ∂(P†π) x + +/-- Given an argmin estimator `f`, we can define a deterministic kernel. -/ +protected noncomputable +abbrev IsArgminEstimator.kernel (h : IsArgminEstimator ℓ P π f) : Kernel 𝓧 𝓨 := + Kernel.deterministic f h.measurable + +/-- The risk of an argmin estimator is the risk lower bound +`∫⁻ x, ⨅ z, ∫⁻ θ, ℓ θ z ∂(P†π) x ∂(P ∘ₘ π)`. -/ +lemma IsArgminEstimator.avgRisk_eq_lintegral_iInf (hf : IsArgminEstimator ℓ P π f) + (hl : Measurable (Function.uncurry ℓ)) : + avgRisk ℓ P hf.kernel π = ∫⁻ x, ⨅ y, ∫⁻ θ, ℓ θ y ∂(P†π) x ∂(P ∘ₘ π) := by + rw [avgRisk_eq_lintegral_lintegral_lintegral hl] + refine lintegral_congr_ae ?_ + filter_upwards [hf.property] with x hx + rwa [Kernel.lintegral_deterministic' _ (by fun_prop)] + +/-- An argmin estimator is a Bayes estimator: that is, it minimizes the Bayesian risk. -/ +lemma IsArgminEstimator.isBayesEstimator (hf : IsArgminEstimator ℓ P π f) + (hl : Measurable (Function.uncurry ℓ)) : + IsBayesEstimator ℓ P hf.kernel π := by + refine le_antisymm ?_ (bayesRisk_le_avgRisk _ _ _ _) + rw [hf.avgRisk_eq_lintegral_iInf hl] + exact lintegral_iInf_posterior_le_bayesRisk hl _ _ + +/-- The estimation problem admits an argmin estimator with respect to the prior `π`. +That is, we can choose the argmin of the posterior expected loss in a measurable way. -/ +structure HasArgminEstimator {𝓨 : Type*} [MeasurableSpace 𝓨] + (ℓ : Θ → 𝓨 → ℝ≥0∞) (P : Kernel Θ 𝓧) [IsFiniteKernel P] (π : Measure Θ) [IsFiniteMeasure π] : + Prop where + exists_isArgminEstimator : ∃ f : 𝓧 → 𝓨, IsArgminEstimator ℓ P π f + +namespace HasArgminEstimator + +/-- An estimator for an estimation problem that for `(P ∘ₘ π)`-almost every `x` is of +the form `x ↦ argmin_y P†π(x)[θ ↦ ℓ θ y]`. -/ +noncomputable +def argminEstimator (h : HasArgminEstimator ℓ P π) : 𝓧 → 𝓨 := + h.exists_isArgminEstimator.choose + +lemma isArgminEstimator_argminEstimator (h : HasArgminEstimator ℓ P π) : + IsArgminEstimator ℓ P π h.argminEstimator := + h.exists_isArgminEstimator.choose_spec + +/-- If the estimation problem admits an argmin estimator, then the Bayesian risk +attains the risk lower bound `∫⁻ x, ⨅ y, ∫⁻ θ, ℓ θ y ∂((P†π) x) ∂(P ∘ₘ π)`. -/ +lemma bayesRisk_eq (hl : Measurable (Function.uncurry ℓ)) (h : HasArgminEstimator ℓ P π) : + bayesRisk ℓ P π = ∫⁻ x, ⨅ y, ∫⁻ θ, ℓ θ y ∂((P†π) x) ∂(P ∘ₘ π) := by + rw [← h.isArgminEstimator_argminEstimator.isBayesEstimator hl, + h.isArgminEstimator_argminEstimator.avgRisk_eq_lintegral_iInf hl] + +end HasArgminEstimator + +end ProbabilityTheory From b55fea0a288e55a0ccc12c183d203073951e5861 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Sat, 13 Jun 2026 14:25:06 +0000 Subject: [PATCH 0009/1300] feat: variants of lemmas in CondJensen with a.e. inequalities for the trimmed measure (#39819) This PR was automatically created from PR #35349 by @RemyDegenne via a [review comment](https://github.com/leanprover-community/mathlib4/pull/35349#discussion_r3298163528) by @RemyDegenne. Co-authored-by: RemyDegenne <4094732+RemyDegenne@users.noreply.github.com> --- .../ConditionalExpectation/CondJensen.lean | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean index 2fe493d15670d3..7d25c166b20b66 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean @@ -181,6 +181,15 @@ theorem ConvexOn.map_condExp_le (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] filter_upwards [h1, h2, h3] with a ha hb hc simpa [← ha, ← hb] +theorem ConvexOn.map_condExp_le_trim {mE : MeasurableSpace E} [BorelSpace E] + (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] + (hφ_cvx : ConvexOn ℝ s φ) (hφ_cont : LowerSemicontinuousOn φ s) + (hφ_meas : StronglyMeasurable φ) (hf : ∀ᵐ a ∂μ, f a ∈ s) + (hs : IsClosed s) (hf_int : Integrable f μ) (hφ_int : Integrable (φ ∘ f) μ) : + φ ∘ μ[f | m] ≤ᵐ[μ.trim hm] μ[φ ∘ f | m] := by + rw [StronglyMeasurable.ae_le_trim_iff hm (by fun_prop) (by fun_prop)] + exact hφ_cvx.map_condExp_le hm hφ_cont hf hs hf_int hφ_int + theorem ConcaveOn.condExp_map_le (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] (hφ_cvx : ConcaveOn ℝ s φ) (hφ_cont : UpperSemicontinuousOn φ s) (hf : ∀ᵐ a ∂μ, f a ∈ s) (hs : IsClosed s) (hf_int : Integrable f μ) (hφ_int : Integrable (φ ∘ f) μ) : @@ -189,6 +198,15 @@ theorem ConcaveOn.condExp_map_le (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] condExp_neg (φ ∘ f) m] with a h ha simp_all [Pi.neg_comp] +theorem ConcaveOn.condExp_map_le_trim {mE : MeasurableSpace E} [BorelSpace E] + (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] + (hφ_cvx : ConcaveOn ℝ s φ) (hφ_cont : UpperSemicontinuousOn φ s) + (hφ_meas : StronglyMeasurable φ) (hf : ∀ᵐ a ∂μ, f a ∈ s) + (hs : IsClosed s) (hf_int : Integrable f μ) (hφ_int : Integrable (φ ∘ f) μ) : + μ[φ ∘ f | m] ≤ᵐ[μ.trim hm] φ ∘ μ[f | m] := by + rw [StronglyMeasurable.ae_le_trim_iff hm (by fun_prop) (by fun_prop)] + exact hφ_cvx.condExp_map_le hm hφ_cont hf hs hf_int hφ_int + /-- **Conditional Jensen's inequality**: in a Banach space `E` with a measure `μ` that is σ-finite on a sub-σ-algebra `m`, if `φ : E → ℝ` is convex and lower-semicontinuous, then for any `f : α → E` such that `f` and `φ ∘ f` are integrable, we have `φ (𝔼[f | m]) ≤ᵐ[μ] 𝔼[φ ∘ f | m]`. -/ @@ -199,6 +217,14 @@ theorem ConvexOn.map_condExp_le_univ (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] ConvexOn.map_condExp_le hm hφ_cvx (lowerSemicontinuousOn_univ_iff.2 hφ_cont) (by simp) isClosed_univ hf_int hφ_int +theorem ConvexOn.map_condExp_le_trim_univ {mE : MeasurableSpace E} [BorelSpace E] + (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] + (hφ_cvx : ConvexOn ℝ univ φ) (hφ_cont : LowerSemicontinuous φ) + (hφ_meas : StronglyMeasurable φ) (hf_int : Integrable f μ) (hφ_int : Integrable (φ ∘ f) μ) : + φ ∘ μ[f | m] ≤ᵐ[μ.trim hm] μ[φ ∘ f | m] := by + rw [StronglyMeasurable.ae_le_trim_iff hm (by fun_prop) (by fun_prop)] + exact hφ_cvx.map_condExp_le_univ hm hφ_cont hf_int hφ_int + theorem ConcaveOn.condExp_map_le_univ (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] (hφ_cvx : ConcaveOn ℝ univ φ) (hφ_cont : UpperSemicontinuous φ) (hf_int : Integrable f μ) (hφ_int : Integrable (φ ∘ f) μ) : @@ -207,6 +233,14 @@ theorem ConcaveOn.condExp_map_le_univ (hm : m ≤ mα) [SigmaFinite (μ.trim hm) condExp_neg (φ ∘ f) m] with a h ha simp_all [Pi.neg_comp] +theorem ConcaveOn.condExp_map_le_trim_univ {mE : MeasurableSpace E} [BorelSpace E] + (hm : m ≤ mα) [SigmaFinite (μ.trim hm)] + (hφ_cvx : ConcaveOn ℝ univ φ) (hφ_cont : UpperSemicontinuous φ) + (hφ_meas : StronglyMeasurable φ) (hf_int : Integrable f μ) (hφ_int : Integrable (φ ∘ f) μ) : + μ[φ ∘ f | m] ≤ᵐ[μ.trim hm] φ ∘ μ[f | m] := by + rw [StronglyMeasurable.ae_le_trim_iff hm (by fun_prop) (by fun_prop)] + exact hφ_cvx.condExp_map_le_univ hm hφ_cont hf_int hφ_int + /-- In a Banach space `E` with a measure `μ`, then for any `f : α → E`, we have `‖𝔼[f | m]‖ ≤ᵐ[μ] 𝔼[‖f‖ | m]`. -/ theorem norm_condExp_le : (‖μ[f | m] ·‖) ≤ᵐ[μ] μ[(‖f ·‖) | m] := by From 06b9dc81c6231b5b67ef260d241f1821e3a7b1ed Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sat, 13 Jun 2026 14:25:07 +0000 Subject: [PATCH 0010/1300] chore: replace `(by rfl)` with `rfl` (#40371) Replaces `(by rfl)` with `rfl` whenever possible. Co-authored-by: Batixx --- Archive/Imo/Imo1982Q1.lean | 2 +- Counterexamples/CharPZeroNeCharZero.lean | 2 +- Mathlib/Algebra/DirectSum/Internal.lean | 2 +- Mathlib/Algebra/Order/CauSeq/Completion.lean | 4 ++-- Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean | 2 +- Mathlib/CategoryTheory/Category/PartialFun.lean | 2 +- Mathlib/CategoryTheory/Sites/Sheaf.lean | 2 +- Mathlib/Data/Vector/Basic.lean | 2 +- Mathlib/Dynamics/Flow.lean | 2 +- Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean | 2 +- Mathlib/GroupTheory/FreeGroup/Basic.lean | 2 +- Mathlib/GroupTheory/MonoidLocalization/Basic.lean | 2 +- Mathlib/NumberTheory/BernoulliPolynomials.lean | 2 +- Mathlib/Order/Filter/Germ/Basic.lean | 2 +- Mathlib/RepresentationTheory/Intertwining.lean | 2 +- Mathlib/RingTheory/AdicCompletion/Completeness.lean | 6 +++--- Mathlib/RingTheory/Adjoin/Singleton.lean | 2 +- Mathlib/RingTheory/Algebraic/Basic.lean | 2 +- 18 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Archive/Imo/Imo1982Q1.lean b/Archive/Imo/Imo1982Q1.lean index ef97cd79289882..544af84ecc0474 100644 --- a/Archive/Imo/Imo1982Q1.lean +++ b/Archive/Imo/Imo1982Q1.lean @@ -93,7 +93,7 @@ lemma part_1 : 660 ≤ f (1980) := by lemma part_2 : f 1980 ≤ 660 := by have h : 5 * f 1980 + 33 * f 3 ≤ 5 * 660 + 33 := by calc (5 : ℕ+) * f 1980 + (33 : ℕ+) * f 3 ≤ f (5 * 1980 + 33 * 3) := by apply hf.superlinear - _ = f 9999 := by rfl + _ = f 9999 := rfl _ = 5 * 660 + 33 := by rw [hf.f_9999] rw [hf.f₃, mul_one] at h -- from 5 * f 1980 + 33 ≤ 5 * 660 + 33 we show f 1980 ≤ 660 diff --git a/Counterexamples/CharPZeroNeCharZero.lean b/Counterexamples/CharPZeroNeCharZero.lean index 39e01fe8e56397..fcb0eb5e258ee4 100644 --- a/Counterexamples/CharPZeroNeCharZero.lean +++ b/Counterexamples/CharPZeroNeCharZero.lean @@ -24,7 +24,7 @@ namespace Counterexample @[simp] theorem add_one_eq_one (x : WithZero Unit) : x + 1 = 1 := - WithZero.cases_on x (by rfl) fun h => by rfl + WithZero.cases_on x rfl fun h => by rfl theorem withZero_unit_charP_zero : CharP (WithZero Unit) 0 := ⟨fun x => by cases x <;> simp⟩ diff --git a/Mathlib/Algebra/DirectSum/Internal.lean b/Mathlib/Algebra/DirectSum/Internal.lean index 4aeb4fab711013..b0f553a0a9d362 100644 --- a/Mathlib/Algebra/DirectSum/Internal.lean +++ b/Mathlib/Algebra/DirectSum/Internal.lean @@ -320,7 +320,7 @@ theorem Submodule.iSup_eq_toSubmodule_range [AddMonoid ι] [CommSemiring S] [Sem theorem DirectSum.coeAlgHom_of [AddMonoid ι] [CommSemiring S] [Semiring R] [Algebra S R] (A : ι → Submodule S R) [SetLike.GradedMonoid A] (i : ι) (x : A i) : DirectSum.coeAlgHom A (DirectSum.of (fun i => A i) i x) = x := - DirectSum.toSemiring_of _ (by rfl) (fun _ _ => (by rfl)) _ _ + DirectSum.toSemiring_of _ rfl (fun _ _ => rfl) _ _ end DirectSum diff --git a/Mathlib/Algebra/Order/CauSeq/Completion.lean b/Mathlib/Algebra/Order/CauSeq/Completion.lean index b48635495389f0..9d8794438abc3f 100644 --- a/Mathlib/Algebra/Order/CauSeq/Completion.lean +++ b/Mathlib/Algebra/Order/CauSeq/Completion.lean @@ -142,7 +142,7 @@ theorem ofRat_injective : Function.Injective (ofRat : β → Cauchy abv) := fun simpa [ofRat, mk_eq, ← const_sub, const_limZero, sub_eq_zero] using h instance Cauchy.ring : Ring (Cauchy abv) := fast_instance% - Function.Surjective.ring mk Quotient.mk'_surjective (by rfl) (by rfl) + Function.Surjective.ring mk Quotient.mk'_surjective rfl rfl (fun _ _ => (mk_add _ _).symm) (fun _ _ => (mk_mul _ _).symm) (fun _ => (mk_neg _).symm) (fun _ _ => (mk_sub _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_pow _ _).symm) (fun _ => rfl) fun _ => rfl @@ -170,7 +170,7 @@ variable {α : Type*} [Field α] [LinearOrder α] [IsStrictOrderedRing α] variable {β : Type*} [CommRing β] {abv : β → α} [IsAbsoluteValue abv] instance Cauchy.commRing : CommRing (Cauchy abv) := fast_instance% - Function.Surjective.commRing mk Quotient.mk'_surjective (by rfl) (by rfl) + Function.Surjective.commRing mk Quotient.mk'_surjective rfl rfl (fun _ _ => (mk_add _ _).symm) (fun _ _ => (mk_mul _ _).symm) (fun _ => (mk_neg _).symm) (fun _ _ => (mk_sub _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_pow _ _).symm) (fun _ => rfl) fun _ => rfl diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean index 9fe6d6e66a330f..40edeb5bc6a42d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean @@ -242,7 +242,7 @@ theorem GammaSeq_add_one_left (s : ℂ) {n : ℕ} (hn : n ≠ 0) : ← mul_assoc, mul_comm _ (Finset.prod _ _)] congr 3 · rw [cpow_add _ _ (Nat.cast_ne_zero.mpr hn), cpow_one, mul_comm] - · refine Finset.prod_congr (by rfl) fun x _ => ?_ + · refine Finset.prod_congr rfl fun x _ => ?_ push_cast; ring · abel diff --git a/Mathlib/CategoryTheory/Category/PartialFun.lean b/Mathlib/CategoryTheory/Category/PartialFun.lean index b6a34630701d81..d544ff514b4e8e 100644 --- a/Mathlib/CategoryTheory/Category/PartialFun.lean +++ b/Mathlib/CategoryTheory/Category/PartialFun.lean @@ -146,7 +146,7 @@ noncomputable def partialFunEquivPointed : PartialFun.{u} ≌ Pointed where exact hw.symm counitIso := NatIso.ofComponents - (fun X ↦ Pointed.Iso.mk (by classical exact Equiv.optionSubtypeNe X.point) (by rfl)) + (fun X ↦ Pointed.Iso.mk (by classical exact Equiv.optionSubtypeNe X.point) rfl) fun {X Y} f ↦ Pointed.Hom.ext <| funext fun a ↦ by obtain _ | ⟨a, ha⟩ := a · exact f.map_point.symm diff --git a/Mathlib/CategoryTheory/Sites/Sheaf.lean b/Mathlib/CategoryTheory/Sites/Sheaf.lean index 0483c6977df99f..1ee14826e07ea4 100644 --- a/Mathlib/CategoryTheory/Sites/Sheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Sheaf.lean @@ -103,7 +103,7 @@ def conesEquivSieveCompatibleFamily : toFun π := ⟨fun _ f h => π.app (op ⟨Over.mk f, h⟩), fun X Y f g hf => by let φ : S.arrows.categoryMk (g ≫ f) (S.downward_closed hf g) ⟶ - S.arrows.categoryMk f hf := ObjectProperty.homMk (Over.homMk _ (by rfl)) + S.arrows.categoryMk f hf := ObjectProperty.homMk (Over.homMk _ rfl) simpa using! π.naturality φ.op⟩ invFun x := { app := fun f => x.1 f.unop.1.hom f.unop.2 diff --git a/Mathlib/Data/Vector/Basic.lean b/Mathlib/Data/Vector/Basic.lean index 7ceba21415a26f..a056a01b21f9fc 100644 --- a/Mathlib/Data/Vector/Basic.lean +++ b/Mathlib/Data/Vector/Basic.lean @@ -522,7 +522,7 @@ def casesOn₃ {motive : ∀ {n}, Vector α n → Vector β n → Vector γ n /-- Cast a vector to an array. -/ def toArray : Vector α n → Array α - | ⟨xs, _⟩ => cast (by rfl) xs.toArray + | ⟨xs, _⟩ => xs.toArray section InsertIdx diff --git a/Mathlib/Dynamics/Flow.lean b/Mathlib/Dynamics/Flow.lean index 6c6fe71cb8f661..bad8543dece3ee 100644 --- a/Mathlib/Dynamics/Flow.lean +++ b/Mathlib/Dynamics/Flow.lean @@ -247,7 +247,7 @@ theorem IsFactorOf.trans (h₁ : IsFactorOf ϕ ψ) (h₂ : IsFactorOf ψ χ) : I h₁.elim fun π hπ => h₂.elim fun ρ hρ => ⟨π ∘ ρ, hρ.comp χ ψ ϕ hπ⟩ /-- Every flow is a factor of itself. -/ -theorem IsFactorOf.self : IsFactorOf ϕ ϕ := ⟨id, (isSemiconjugacy_id_iff_eq ϕ ϕ).mpr (by rfl)⟩ +theorem IsFactorOf.self : IsFactorOf ϕ ϕ := ⟨id, (isSemiconjugacy_id_iff_eq ϕ ϕ).mpr rfl⟩ end Flow diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean index 12e8258353a615..3f596fe43485df 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean @@ -601,7 +601,7 @@ instance : Algebra A⟮b⟯ A⟮(algebraMap B C) b⟯ := RingHom.toAlgebra (RingHom.adjoinAlgebraMap _) instance : IsScalarTower A⟮b⟯ A⟮(algebraMap B C) b⟯ C := - IsScalarTower.of_algebraMap_eq' (by rfl) + IsScalarTower.of_algebraMap_eq' rfl end AdjoinSimple diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 8a1e4753bdb254..3a4a00e0b12b57 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -931,7 +931,7 @@ def freeGroupUnitEquivInt : FreeGroup Unit ≃ ℤ where rintro ⟨L⟩ simp only [quot_mk_eq_mk, map.mk, sum_mk, List.map_map] exact List.recOn L - (by rfl) + rfl (fun ⟨⟨⟩, b⟩ tl ih => by cases b <;> simp [zpow_add, ih] <;> rfl) right_inv x := diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index b8440d8c517a69..6b2cb8e36d0c07 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -235,7 +235,7 @@ then `f` is defined on the whole `AddLocalization S`. -/] def rec {p : Localization S → Sort u} (f : ∀ (a : M) (b : S), p (mk a b)) (H : ∀ {a c : M} {b d : S} (h : r S (a, b) (c, d)), (Eq.ndrec (f a b) (mk_eq_mk_iff.mpr h) : p (mk c d)) = f c d) (x) : p x := - Quot.rec (fun y ↦ Eq.ndrec (f y.1 y.2) (by rfl)) + Quot.rec (fun y ↦ f y.1 y.2) (fun y z h ↦ by cases y; cases z; exact H (r_iff_oreEqv_r.mpr h)) x /-- Copy of `Quotient.recOnSubsingleton₂` for `Localization` -/ diff --git a/Mathlib/NumberTheory/BernoulliPolynomials.lean b/Mathlib/NumberTheory/BernoulliPolynomials.lean index 6adffaddb78dfa..51e293fd0ad465 100644 --- a/Mathlib/NumberTheory/BernoulliPolynomials.lean +++ b/Mathlib/NumberTheory/BernoulliPolynomials.lean @@ -111,7 +111,7 @@ theorem derivative_bernoulli_add_one (k : ℕ) : rw [range_add_one, sum_insert notMem_range_self, tsub_self, cast_zero, mul_zero, map_zero, zero_add, mul_sum] -- the rest of the sum is termwise equal: - refine sum_congr (by rfl) fun m _ => ?_ + refine sum_congr rfl fun m _ => ?_ conv_rhs => rw [← Nat.cast_one, ← Nat.cast_add, ← C_eq_natCast, C_mul_monomial, mul_comm] rw [mul_assoc, mul_assoc, ← Nat.cast_mul, ← Nat.cast_mul] congr 3 diff --git a/Mathlib/Order/Filter/Germ/Basic.lean b/Mathlib/Order/Filter/Germ/Basic.lean index 7390a26c100c7e..dd0aa8723d3e62 100644 --- a/Mathlib/Order/Filter/Germ/Basic.lean +++ b/Mathlib/Order/Filter/Germ/Basic.lean @@ -406,7 +406,7 @@ theorem const_pow [Pow G M] (a : G) (n : M) : (↑(a ^ n) : Germ l G) = (↑a : -- TODO: https://github.com/leanprover-community/mathlib4/pull/7432 @[to_additive] instance instMonoid [Monoid M] : Monoid (Germ l M) := - { Function.Surjective.monoid ofFun Quot.mk_surjective (by rfl) + { Function.Surjective.monoid ofFun Quot.mk_surjective rfl (fun _ _ => by rfl) fun _ _ => by rfl with toSemigroup := instSemigroup toOne := instOne diff --git a/Mathlib/RepresentationTheory/Intertwining.lean b/Mathlib/RepresentationTheory/Intertwining.lean index a4931239af1b82..ebcc0244e85ec0 100644 --- a/Mathlib/RepresentationTheory/Intertwining.lean +++ b/Mathlib/RepresentationTheory/Intertwining.lean @@ -498,7 +498,7 @@ noncomputable def equivAlgEnd : IntertwiningMap ρ ρ ≃ₐ[A] Module.End A[G] ρ.asModule := AlgEquiv.ofLinearEquiv (equivLinearMapAsModule ρ ρ) - (by rfl) + rfl (by intro f g; rfl) theorem isIntertwiningMap_of_mem_center (g : G) (hg : g ∈ Submonoid.center G) : diff --git a/Mathlib/RingTheory/AdicCompletion/Completeness.lean b/Mathlib/RingTheory/AdicCompletion/Completeness.lean index ef7db25d3cb756..5f8b5b456c3b61 100644 --- a/Mathlib/RingTheory/AdicCompletion/Completeness.lean +++ b/Mathlib/RingTheory/AdicCompletion/Completeness.lean @@ -102,8 +102,8 @@ def ofValEqZero {n : ℕ} {x : AdicCompletion I M} (hxn : x.val n = 0) : val i := ofValEqZeroAux I (Eq.refl (i + n)) hxn property {i j} h := by obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le h - rw [← (powSMulQuotInclusion_injective I (by rfl) ⊤).eq_iff, ofValEqZeroAux_prop, - ← LinearMap.comp_apply, ← factorPow_comp_powSMulQuotInclusion I (by rfl) + rw [← (powSMulQuotInclusion_injective I rfl ⊤).eq_iff, ofValEqZeroAux_prop, + ← LinearMap.comp_apply, ← factorPow_comp_powSMulQuotInclusion I rfl (show i + k + n = k + (i + n) by ring), LinearMap.comp_apply, ofValEqZeroAux_prop] exact x.prop (by lia) @@ -112,7 +112,7 @@ theorem ofPowSMul_ofValEqZero {n : ℕ} {x : AdicCompletion I M} (hxn : x.val n ofPowSMul I M n (ofValEqZero I hxn) = x := by ext i; by_cases! h : n ≤ i · obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le' h - rw [ofPowSMul_val_apply _ (by rfl), ofValEqZero, ofValEqZeroAux_prop] + rw [ofPowSMul_val_apply _ rfl, ofValEqZero, ofValEqZeroAux_prop] rw [ofPowSMul_val_apply_eq_zero _ h.le, ← x.prop h.le, hxn, _root_.map_zero] theorem restrictScalars_range_ofPowSMul_eq_ker_eval {n : ℕ} : diff --git a/Mathlib/RingTheory/Adjoin/Singleton.lean b/Mathlib/RingTheory/Adjoin/Singleton.lean index 1bde86bb66cd0c..2b26c1ddf9c972 100644 --- a/Mathlib/RingTheory/Adjoin/Singleton.lean +++ b/Mathlib/RingTheory/Adjoin/Singleton.lean @@ -55,7 +55,7 @@ instance : Algebra A[b] A[(algebraMap B C) b] := RingHom.toAlgebra (RingHom.adjoinAlgebraMap b) instance : IsScalarTower A[b] A[(algebraMap B C) b] C := - IsScalarTower.of_algebraMap_eq' (by rfl) + IsScalarTower.of_algebraMap_eq' rfl /-- If the `algebraMap` injective then we have a Ring isomorphism between A[b] and A[↑b]. -/ noncomputable def RingHom.adjoinAlgebraMapEquiv [FaithfulSMul B C] : diff --git a/Mathlib/RingTheory/Algebraic/Basic.lean b/Mathlib/RingTheory/Algebraic/Basic.lean index d1fefdb9b42f5a..e4771691dbe162 100644 --- a/Mathlib/RingTheory/Algebraic/Basic.lean +++ b/Mathlib/RingTheory/Algebraic/Basic.lean @@ -343,7 +343,7 @@ theorem isAlgebraic_of_isAlgebraic_bot {x : S} (halg : IsAlgebraic (⊥ : Subalg theorem isAlgebraic_bot_iff (h : Function.Injective (algebraMap R S)) {x : S} : IsAlgebraic (⊥ : Subalgebra R S) x ↔ IsAlgebraic R x := isAlgebraic_ringHom_iff_of_comp_eq (Algebra.botEquivOfInjective h).symm (RingHom.id S) - Function.injective_id (by rfl) + Function.injective_id rfl variable (R S) in theorem algebra_isAlgebraic_of_algebra_isAlgebraic_bot_left From f1ceb733fa418759932c458de4f14076f8d15efe Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Sat, 13 Jun 2026 14:25:09 +0000 Subject: [PATCH 0011/1300] feat: clean up `PositiveLinearMap` and add API (#40492) Among other things, this removes the coercion from the morphism class into the morphism type, and renames the underlying convenience constructor to `PositiveLinearMap.ofClass`. --- .../Order/Module/PositiveLinearMap.lean | 46 ++++++++++++++----- .../CStarAlgebra/PositiveLinearMap.lean | 2 +- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean b/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean index b5141ae70a6e97..e32de62a976895 100644 --- a/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean +++ b/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean @@ -38,7 +38,7 @@ add_decl_doc PositiveLinearMap.toOrderHom /-- Notation for a `PositiveLinearMap`. -/ notation:25 E " →ₚ[" R:25 "] " F:0 => PositiveLinearMap R E F -namespace PositiveLinearMapClass +section PositiveLinearMapClass variable {F R E₁ E₂ : Type*} [Semiring R] [AddCommMonoid E₁] [PartialOrder E₁] [AddCommMonoid E₂] [PartialOrder E₂] @@ -46,16 +46,15 @@ variable {F R E₁ E₂ : Type*} [Semiring R] [OrderHomClass F E₁ E₂] /-- Reinterpret an element of a type of positive linear maps as a positive linear map. -/ -def toPositiveLinearMap (f : F) : E₁ →ₚ[R] E₂ := +def PositiveLinearMap.ofClass (f : F) : E₁ →ₚ[R] E₂ := { (f : E₁ →ₗ[R] E₂), (f : E₁ →o E₂) with } -/-- Reinterpret an element of a type of positive linear maps as a positive linear map. -/ -instance instCoeToLinearMap : CoeHead F (E₁ →ₚ[R] E₂) where - coe f := toPositiveLinearMap f +@[deprecated (since := "2026-06-10")] +alias PositiveLinearMapClass.toPositiveLinearMap := PositiveLinearMap.ofClass -/-- An additive group homomorphism that maps nonnegative elements to nonnegative elements -is an order homomorphism. -/ -lemma _root_.OrderHomClass.of_addMonoidHom {F' E₁' E₂' : Type*} [FunLike F' E₁' E₂'] [AddGroup E₁'] +/-- A type of additive group homomorphisms that map nonnegative elements to nonnegative elements +is also a type of order homomorphisms. -/ +lemma OrderHomClass.of_addMonoidHom {F' E₁' E₂' : Type*} [FunLike F' E₁' E₂'] [AddGroup E₁'] [LE E₁'] [AddRightMono E₁'] [AddGroup E₂'] [LE E₂'] [AddRightMono E₂'] [AddMonoidHomClass F' E₁' E₂'] (h : ∀ f : F', ∀ x, 0 ≤ x → 0 ≤ f x) : OrderHomClass F' E₁' E₂' where @@ -67,9 +66,11 @@ namespace PositiveLinearMap section general -variable {R E₁ E₂ : Type*} [Semiring R] - [AddCommMonoid E₁] [PartialOrder E₁] [AddCommMonoid E₂] [PartialOrder E₂] - [Module R E₁] [Module R E₂] +variable {R E₁ E₂ E₃ : Type*} [Semiring R] + [AddCommMonoid E₁] [PartialOrder E₁] + [AddCommMonoid E₂] [PartialOrder E₂] + [AddCommMonoid E₃] [PartialOrder E₃] + [Module R E₁] [Module R E₂] [Module R E₃] instance : FunLike (E₁ →ₚ[R] E₂) E₁ E₂ where coe f := f.toFun @@ -80,10 +81,33 @@ instance : FunLike (E₁ →ₚ[R] E₂) E₁ E₂ where apply DFunLike.coe_injective exact h +initialize_simps_projections PositiveLinearMap (toFun → apply, as_prefix toLinearMap) + @[ext] lemma ext {f g : E₁ →ₚ[R] E₂} (h : ∀ x, f x = g x) : f = g := DFunLike.ext f g h +variable (R E₁) in +/-- The identity as a positive linear map. -/ +@[simps! apply toLinearMap] protected def id : E₁ →ₚ[R] E₁ where + __ := LinearMap.id + __ := OrderHom.id + +@[simp] lemma toOrderHom_id : (PositiveLinearMap.id R E₁).toOrderHom = .id := rfl + +/-- The composition of positive linear maps is again a positive linear map. -/ +@[simps! apply toLinearMap] +def comp (g : E₂ →ₚ[R] E₃) (f : E₁ →ₚ[R] E₂) : E₁ →ₚ[R] E₃ where + toLinearMap := g.toLinearMap.comp f.toLinearMap + monotone' := g.monotone'.comp f.monotone' + +@[simp] lemma toOrderHom_comp (g : E₂ →ₚ[R] E₃) (f : E₁ →ₚ[R] E₂) : + (g.comp f).toOrderHom = g.toOrderHom.comp f.toOrderHom := + rfl + +@[simp] lemma comp_id (f : E₁ →ₚ[R] E₂) : f.comp (.id R E₁) = f := rfl +@[simp] lemma id_comp (f : E₁ →ₚ[R] E₂) : (PositiveLinearMap.id R E₂).comp f = f := rfl + instance : LinearMapClass (E₁ →ₚ[R] E₂) R E₁ E₂ where map_add f := map_add f.toLinearMap map_smulₛₗ f := f.toLinearMap.map_smul' diff --git a/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean b/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean index dc4dabe59f7fbd..a5d0adb3aab838 100644 --- a/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean +++ b/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean @@ -130,7 +130,7 @@ instance {F : Type*} [FunLike F A₁ A₂] [LinearMapClass F ℂ A₁ A₂] [Ord ContinuousLinearMapClass F ℂ A₁ A₂ where map_continuous f := by have hbound : ∃ C : ℝ, ∀ a, ‖f a‖ ≤ C * ‖a‖ := by - obtain ⟨C, h⟩ := exists_norm_apply_le (f : A₁ →ₚ[ℂ] A₂) + obtain ⟨C, h⟩ := exists_norm_apply_le (.ofClass f) exact ⟨C, h⟩ exact (LinearMap.mkContinuousOfExistsBound (f : A₁ →ₗ[ℂ] A₂) hbound).continuous From dab4b77c11870a1b54bd22fa185abdbf74bada85 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Sat, 13 Jun 2026 14:25:11 +0000 Subject: [PATCH 0012/1300] feat: selfadjointness for comparable elements in a star ordered ring (#40513) --- Mathlib/Algebra/Order/Star/Basic.lean | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index 5e2ab31abba409..99fa9e39b070f5 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -171,7 +171,7 @@ section NonUnitalSemiring variable [NonUnitalSemiring R] [PartialOrder R] [StarRing R] [StarOrderedRing R] -lemma IsSelfAdjoint.mono {x y : R} (h : x ≤ y) (hx : IsSelfAdjoint x) : IsSelfAdjoint y := by +lemma IsSelfAdjoint.of_ge {x y : R} (h : x ≤ y) (hx : IsSelfAdjoint x) : IsSelfAdjoint y := by rw [StarOrderedRing.le_iff] at h obtain ⟨d, hd, rfl⟩ := h rw [IsSelfAdjoint, star_add, hx.star_eq] @@ -180,9 +180,11 @@ lemma IsSelfAdjoint.mono {x y : R} (h : x ≤ y) (hx : IsSelfAdjoint x) : IsSelf rintro - ⟨s, rfl⟩ simp +@[deprecated (since := "2026-06-12")] alias IsSelfAdjoint.mono := IsSelfAdjoint.of_ge + @[aesop 10% apply, grind ←] lemma IsSelfAdjoint.of_nonneg {x : R} (hx : 0 ≤ x) : IsSelfAdjoint x := - .mono hx <| .zero R + .of_ge hx <| .zero R /-- An alias of `IsSelfAdjoint.of_nonneg` for use with dot notation. -/ alias LE.le.isSelfAdjoint := IsSelfAdjoint.of_nonneg @@ -204,6 +206,7 @@ protected theorem IsSelfAdjoint.mul_self_nonneg {a : R} (ha : IsSelfAdjoint a) : simpa [ha.star_eq] using star_mul_self_nonneg a /-- A star projection is non-negative in a star-ordered ring. -/ +@[grind →, aesop safe forward (rule_sets := [CStarAlgebra])] theorem IsStarProjection.nonneg {p : R} (hp : IsStarProjection p) : 0 ≤ p := hp.isIdempotentElem ▸ hp.isSelfAdjoint.mul_self_nonneg @@ -316,6 +319,19 @@ theorem mul_star_self_pos [Nontrivial R] {x : R} (hx : IsRegular x) : 0 < x * st end NonUnitalSemiring +section NonUnitalRing + +variable [NonUnitalRing R] [PartialOrder R] [StarRing R] [StarOrderedRing R] + +lemma IsSelfAdjoint.iff_of_le {a b : R} (hab : a ≤ b) : + IsSelfAdjoint a ↔ IsSelfAdjoint b := by + replace hab := (sub_nonneg.mpr hab).isSelfAdjoint + aesop (add simp IsSelfAdjoint) + +alias ⟨_, IsSelfAdjoint.of_le⟩ := IsSelfAdjoint.iff_of_le + +end NonUnitalRing + section Semiring variable [Semiring R] [PartialOrder R] [StarRing R] [StarOrderedRing R] From 9e7b1c1166169f7aa90a08054ce9b97948d44083 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Sat, 13 Jun 2026 17:40:35 +0000 Subject: [PATCH 0013/1300] feat(Analysis/Complex/Exponential): add new bounds on exponential (#39690) We add new upper bounds on Real.exp in terms of 2x/(2+x), and use these to move some bounds on log higher in mathlib. We also add a lemma for the common bound (1+1/n)^n <= e, though this is a special-case of `one_sub_div_pow_le_exp_neg` (immediately before), but is added for convenience and discoverability, as this is a "well-known" bound. --- Mathlib/Analysis/Complex/Exponential.lean | 25 +++++++++++++++++++ .../Analysis/Complex/ExponentialBounds.lean | 2 +- .../Analysis/SpecialFunctions/Log/Basic.lean | 10 ++++++++ .../Analysis/SpecialFunctions/Log/Deriv.lean | 10 -------- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index d2ba768f73a164..4fbc28c76c4d3e 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -11,6 +11,8 @@ public import Mathlib.Algebra.Order.CauSeq.BigOperators public import Mathlib.Algebra.Order.Star.Basic public import Mathlib.Data.Complex.BigOperators public import Mathlib.Data.Nat.Choose.Sum +public import Mathlib.Tactic.NormNum.BigOperators +public import Mathlib.Tactic.NormNum.NatFactorial /-! # Exponential Function @@ -648,12 +650,35 @@ theorem one_sub_div_pow_le_exp_neg {n : ℕ} {t : ℝ} (ht' : t ≤ n) : (1 - t · exact one_sub_le_exp_neg _ _ = rexp (-t) := by rw [← Real.exp_nat_mul, mul_neg, mul_comm, div_mul_cancel₀]; positivity +lemma one_add_inv_pow_le_exp {n : ℕ} : (1 + (n : ℝ)⁻¹) ^ n ≤ exp 1 := by + convert one_sub_div_pow_le_exp_neg (n := n) (t := -1) (by grind) using 1 + · field + · simp + lemma le_inv_mul_exp (x : ℝ) {c : ℝ} (hc : 0 < c) : x ≤ c⁻¹ * exp (c * x) := by rw [le_inv_mul_iff₀ hc] calc c * x _ ≤ c * x + 1 := le_add_of_nonneg_right zero_le_one _ ≤ _ := Real.add_one_le_exp (c * x) +lemma exp_lt_two_add_div_two_sub {x : ℝ} (hx : 0 < x) (hx' : x < 2) : + exp x < (2 + x) / (2 - x) := by calc + _ = exp (x / 2) ^ 2 := by grind [Real.exp_nat_mul (x / 2) 2] + _ ≤ _ := by + grw [Real.exp_bound' (x := x / 2) (by grind) (by grind) (n := 3) (by simp)] + apply Real.exp_nonneg + _ < (2 + x) / (2 - x) := by + rw [lt_div_iff₀ (by linarith), ← sub_pos] + simp only [Finset.sum_range_succ] + ring_nf + positivity + +lemma exp_le_two_add_div_two_sub {x : ℝ} (hx : 0 ≤ x) (hx' : x < 2) : + exp x ≤ (2 + x) / (2 - x) := by + obtain rfl | hx₀ := hx.eq_or_lt + · simp + · exact (exp_lt_two_add_div_two_sub hx₀ hx').le + theorem prod_one_add_le_exp_sum {ι : Type*} (s : Finset ι) {f : ι → ℝ} (hf : ∀ i, 0 ≤ f i) : ∏ i ∈ s, (1 + f i) ≤ exp (∑ i ∈ s, f i) := (Finset.prod_le_prod (fun i _ ↦ add_nonneg zero_le_one (hf i)) diff --git a/Mathlib/Analysis/Complex/ExponentialBounds.lean b/Mathlib/Analysis/Complex/ExponentialBounds.lean index 56d1b556a6c820..190f489b95125a 100644 --- a/Mathlib/Analysis/Complex/ExponentialBounds.lean +++ b/Mathlib/Analysis/Complex/ExponentialBounds.lean @@ -77,7 +77,7 @@ theorem log_two_near_10 : |log 2 - 287209 / 414355| ≤ 1 / 10 ^ 10 := by norm_num1 at z rw [one_div (2 : ℝ), log_inv, ← sub_eq_add_neg, _root_.abs_sub_comm] at z apply le_trans (_root_.abs_sub_le _ _ _) (add_le_add z _) - norm_num [sum_range_succ] + norm_num theorem log_two_gt_d9 : 0.6931471803 < log 2 := lt_of_lt_of_le (by norm_num1) (sub_le_comm.1 (abs_sub_le_iff.1 log_two_near_10).2) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index 04ddb94fdc1d91..ab6a43aa827bb2 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -336,6 +336,16 @@ theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| rw [← abs_of_nonneg aux, neg_mul, abs_neg] at this exact this +lemma le_log_one_add_of_nonneg {x : ℝ} (hx : 0 ≤ x) : 2 * x / (x + 2) ≤ log (1 + x) := by + rw [le_log_iff_exp_le (by grind)] + convert exp_le_two_add_div_two_sub (x := 2 * x / (x + 2)) (by positivity) _ using 1 + all_goals field_simp; grind + +lemma lt_log_one_add_of_pos {x : ℝ} (hx : 0 < x) : 2 * x / (x + 2) < log (1 + x) := by + rw [lt_log_iff_exp_lt (by grind)] + convert exp_lt_two_add_div_two_sub (x := 2 * x / (x + 2)) (by positivity) _ using 1 + all_goals field_simp; grind + /-- The real logarithm function tends to `+∞` at `+∞`. -/ theorem tendsto_log_atTop : Tendsto log atTop atTop := tendsto_comp_exp_atTop.1 <| by simpa only [log_exp] using! tendsto_id diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean index a8ca2fea64a7fa..99ebf667e962ce 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean @@ -423,14 +423,4 @@ theorem hasSum_log_one_add {a : ℝ} (h : 0 ≤ a) : · convert! hasSum_log_one_add_inv (inv_pos.mpr (lt_of_le_of_ne h ha0.symm)) using 4 all_goals simp [field, add_comm] -lemma le_log_one_add_of_nonneg {x : ℝ} (hx : 0 ≤ x) : 2 * x / (x + 2) ≤ log (1 + x) := by - convert! le_hasSum (hasSum_log_one_add hx) 0 (by intros; positivity) using 1 - simp [field] - -lemma lt_log_one_add_of_pos {x : ℝ} (hx : 0 < x) : 2 * x / (x + 2) < log (1 + x) := by - convert! - lt_hasSum (hasSum_log_one_add hx.le) 0 (by intros; positivity) 1 (by positivity) - (by positivity) using 1 - simp [field] - end Real From 57249a69cc0b63f6eb5d0d3f1b06c34f16a22e52 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 19:59:05 -0700 Subject: [PATCH 0014/1300] Add to_dual tags for conditionally complete lattice lemmas --- .../ConditionallyCompleteLattice/Basic.lean | 17 +- .../ConditionallyCompleteLattice/Indexed.lean | 229 ++++-------------- 2 files changed, 58 insertions(+), 188 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index 31ad01f242423e..9237a25656763b 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -68,7 +68,7 @@ theorem WithTop.sInf_eq [InfSet α] {s : Set (WithTop α)} (hs : ¬s ⊆ {⊤}) sInf s = ↑(sInf ((↑) ⁻¹' s) : α) := if_neg <| by simp [hs, h's] -@[simp] +@[to_dual (attr := simp)] theorem WithTop.sInf_empty [InfSet α] : sInf (∅ : Set (WithTop α)) = ⊤ := if_pos <| by simp @@ -105,10 +105,6 @@ theorem WithTop.coe_sSup' [SupSet α] {s : Set α} (hs : BddAbove s) : · exact Option.some_injective _ · rintro ⟨x, _, ⟨⟩⟩ -@[simp] -theorem WithBot.sSup_empty [SupSet α] : sSup (∅ : Set (WithBot α)) = ⊥ := - WithTop.sInf_empty (α := αᵒᵈ) - @[to_dual] theorem WithTop.sSup_empty (α : Type*) [CompleteLattice α] : (sSup ∅ : WithTop α) = ⊥ := by rw [sSup_eq (by simp) (OrderTop.bddAbove _), Set.preimage_empty, _root_.sSup_empty, coe_bot] @@ -264,19 +260,16 @@ theorem notMem_of_csSup_lt {x : α} {s : Set α} (h : sSup s < x) (hs : BddAbove /-- Introduction rule to prove that `b` is the supremum of `s`: it suffices to check that `b` is larger than all elements of `s`, and that this is not the case of any `wb`. +See `sInf_eq_of_forall_ge_of_forall_gt_exists_lt` for a version in complete lattices. -/] theorem csSup_eq_of_forall_le_of_forall_lt_exists_gt (hs : s.Nonempty) (H : ∀ a ∈ s, a ≤ b) (H' : ∀ w, w < b → ∃ a ∈ s, w < a) : sSup s = b := (eq_of_le_of_not_lt (csSup_le hs H)) fun hb => let ⟨_, ha, ha'⟩ := H' _ hb lt_irrefl _ <| ha'.trans_le <| le_csSup ⟨b, H⟩ ha -/-- Introduction rule to prove that `b` is the infimum of `s`: it suffices to check that `b` -is smaller than all elements of `s`, and that this is not the case of any `w>b`. -See `sInf_eq_of_forall_ge_of_forall_gt_exists_lt` for a version in complete lattices. -/ -theorem csInf_eq_of_forall_ge_of_forall_gt_exists_lt : - s.Nonempty → (∀ a ∈ s, b ≤ a) → (∀ w, b < w → ∃ a ∈ s, a < w) → sInf s = b := - csSup_eq_of_forall_le_of_forall_lt_exists_gt (α := αᵒᵈ) - /-- `b < sSup s` when there is an element `a` in `s` with `b < a`, when `s` is bounded above. This is essentially an iff, except that the assumptions for the two implications are slightly different (one needs boundedness above for one direction, nonemptiness and linear diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean index 65502dab75bcbf..558f50fc38df58 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean @@ -33,30 +33,21 @@ Extension of `iSup` and `iInf` from a preorder `α` to `WithTop α` and `WithBot variable [Preorder α] -@[simp] +@[to_dual (attr := simp)] theorem WithTop.iInf_empty [IsEmpty ι] [InfSet α] (f : ι → WithTop α) : - ⨅ i, f i = ⊤ := by rw [iInf, range_eq_empty, WithTop.sInf_empty] + ⨅ i, f i = ⊤ := by + rw [iInf_of_isEmpty, WithTop.sInf_empty] -@[norm_cast] +@[to_dual (attr := norm_cast)] theorem WithTop.coe_iInf [Nonempty ι] [InfSet α] {f : ι → α} (hf : BddBelow (range f)) : ↑(⨅ i, f i) = (⨅ i, f i : WithTop α) := by rw [iInf, iInf, WithTop.coe_sInf' (range_nonempty f) hf, ← range_comp, Function.comp_def] -@[norm_cast] +@[to_dual (attr := norm_cast)] theorem WithTop.coe_iSup [SupSet α] (f : ι → α) (h : BddAbove (Set.range f)) : ↑(⨆ i, f i) = (⨆ i, f i : WithTop α) := by rw [iSup, iSup, WithTop.coe_sSup' h, ← range_comp, Function.comp_def] -@[simp] -theorem WithBot.ciSup_empty [IsEmpty ι] [SupSet α] (f : ι → WithBot α) : - ⨆ i, f i = ⊥ := - WithTop.iInf_empty (α := αᵒᵈ) _ - -@[norm_cast] -theorem WithBot.coe_iSup [Nonempty ι] [SupSet α] {f : ι → α} (hf : BddAbove (range f)) : - ↑(⨆ i, f i) = (⨆ i, f i : WithBot α) := - WithTop.coe_iInf (α := αᵒᵈ) hf - theorem WithBot.coe_biSup {ι : Type*} {s : Set ι} (hs : s.Nonempty) {α : Type*} [CompleteLattice α] (f : ι → α) : ⨆ i ∈ s, f i = ⨆ i ∈ s, (f i : WithBot α) := by @@ -69,11 +60,6 @@ theorem WithBot.coe_biSup {ι : Type*} {s : Set ι} (hs : s.Nonempty) · simpa only [iSup_pos h] using by apply le_biSup _ h · simpa only [iSup_neg h] using le_trans (by simp) (le_biSup _ hj) -@[norm_cast] -theorem WithBot.coe_iInf [InfSet α] (f : ι → α) (h : BddBelow (Set.range f)) : - ↑(⨅ i, f i) = (⨅ i, f i : WithBot α) := - WithTop.coe_iSup (α := αᵒᵈ) _ h - theorem WithBot.coe_biInf {ι : Type*} {s : Set ι} {α : Type*} [CompleteLattice α] (f : ι → α) : ⨅ i ∈ s, f i = ⨅ i ∈ s, (f i : WithBot α) := by refine le_antisymm (by simpa using fun _ ↦ biInf_le _) <| @@ -88,65 +74,56 @@ section ConditionallyCompleteLattice variable [ConditionallyCompleteLattice α] {a b : α} +@[to_dual] theorem isLUB_ciSup [Nonempty ι] {f : ι → α} (H : BddAbove (range f)) : IsLUB (range f) (⨆ i, f i) := isLUB_csSup (range_nonempty f) H +@[to_dual] theorem isLUB_ciSup_set {f : β → α} {s : Set β} (H : BddAbove (f '' s)) (Hne : s.Nonempty) : IsLUB (f '' s) (⨆ i : s, f i) := by rw [← sSup_image'] exact isLUB_csSup (Hne.image _) H -theorem isGLB_ciInf [Nonempty ι] {f : ι → α} (H : BddBelow (range f)) : - IsGLB (range f) (⨅ i, f i) := - isGLB_csInf (range_nonempty f) H - -theorem isGLB_ciInf_set {f : β → α} {s : Set β} (H : BddBelow (f '' s)) (Hne : s.Nonempty) : - IsGLB (f '' s) (⨅ i : s, f i) := - isLUB_ciSup_set (α := αᵒᵈ) H Hne - +@[to_dual le_ciInf_iff] theorem ciSup_le_iff [Nonempty ι] {f : ι → α} {a : α} (hf : BddAbove (range f)) : iSup f ≤ a ↔ ∀ i, f i ≤ a := (isLUB_le_iff <| isLUB_ciSup hf).trans forall_mem_range -theorem le_ciInf_iff [Nonempty ι] {f : ι → α} {a : α} (hf : BddBelow (range f)) : - a ≤ iInf f ↔ ∀ i, a ≤ f i := - (le_isGLB_iff <| isGLB_ciInf hf).trans forall_mem_range - +@[to_dual le_ciInf_set_iff] theorem ciSup_set_le_iff {ι : Type*} {s : Set ι} {f : ι → α} {a : α} (hs : s.Nonempty) (hf : BddAbove (f '' s)) : ⨆ i : s, f i ≤ a ↔ ∀ i ∈ s, f i ≤ a := (isLUB_le_iff <| isLUB_ciSup_set hf hs).trans forall_mem_image -theorem le_ciInf_set_iff {ι : Type*} {s : Set ι} {f : ι → α} {a : α} (hs : s.Nonempty) - (hf : BddBelow (f '' s)) : (a ≤ ⨅ i : s, f i) ↔ ∀ i ∈ s, a ≤ f i := - (le_isGLB_iff <| isGLB_ciInf_set hf hs).trans forall_mem_image - +@[to_dual] theorem IsLUB.ciSup_eq [Nonempty ι] {f : ι → α} (H : IsLUB (range f) a) : ⨆ i, f i = a := H.csSup_eq (range_nonempty f) +@[to_dual] theorem IsLUB.ciSup_set_eq {s : Set β} {f : β → α} (H : IsLUB (f '' s) a) (Hne : s.Nonempty) : ⨆ i : s, f i = a := IsLUB.csSup_eq (image_eq_range f s ▸ H) (image_eq_range f s ▸ Hne.image f) -theorem IsGLB.ciInf_eq [Nonempty ι] {f : ι → α} (H : IsGLB (range f) a) : ⨅ i, f i = a := - H.csInf_eq (range_nonempty f) - -theorem IsGLB.ciInf_set_eq {s : Set β} {f : β → α} (H : IsGLB (f '' s) a) (Hne : s.Nonempty) : - ⨅ i : s, f i = a := - IsGLB.csInf_eq (image_eq_range f s ▸ H) (image_eq_range f s ▸ Hne.image f) - -/-- The indexed supremum of a function is bounded above by a uniform bound -/ +/-- The indexed supremum of a function is bounded above by a uniform bound. -/ +@[to_dual le_ciInf /-- The indexed minimum of a function is bounded below by a uniform lower +bound. -/] theorem ciSup_le [Nonempty ι] {f : ι → α} {c : α} (H : ∀ x, f x ≤ c) : iSup f ≤ c := csSup_le (range_nonempty f) (by rwa [forall_mem_range]) /-- The indexed supremum of a function is bounded below by the value taken at one point -/ +@[to_dual ciInf_le /-- The indexed infimum of a function is bounded above by the value taken +at one point. -/] theorem le_ciSup {f : ι → α} (H : BddAbove (range f)) (c : ι) : f c ≤ iSup f := le_csSup H (mem_range_self _) +@[to_dual ciInf_le_of_le] theorem le_ciSup_of_le {f : ι → α} (H : BddAbove (range f)) (c : ι) (h : a ≤ f c) : a ≤ iSup f := le_trans h (le_ciSup H c) /-- If the set of all `f i j` is bounded above, then so is the set of the supremums of every row -/ +@[to_dual + /-- If the set of all `f i j` is bounded below, then so is the set of the infimums + of every row -/] theorem BddAbove.range_iSup_of_iUnion_range {κ : ι → Sort*} {f : ∀ i, κ i → α} (H : BddAbove <| ⋃ i, range (f i)) : BddAbove <| range fun i ↦ ⨆ j, f i j := by have ⟨a, h⟩ := H @@ -155,19 +132,23 @@ theorem BddAbove.range_iSup_of_iUnion_range {κ : ι → Sort*} {f : ∀ i, κ i · exact iSup_of_empty' (f i) ▸ le_sup_right exact ciSup_le fun j ↦ le_sup_of_le_left <| h ⟨_, ⟨i, rfl⟩, ⟨j, rfl⟩⟩ +@[to_dual ciInf₂_le] theorem le_ciSup₂ {κ : ι → Sort*} {f : ∀ i, κ i → α} (H : BddAbove <| ⋃ i, range (f i)) (i : ι) (j : κ i) : f i j ≤ ⨆ (i) (j), f i j := le_ciSup_of_le H.range_iSup_of_iUnion_range i <| le_ciSup (H.mono <| subset_iUnion (range <| f ·) i) j /-- The indexed suprema of two functions are comparable if the functions are pointwise comparable -/ -@[gcongr low] +@[to_dual (attr := gcongr low) +/-- The indexed infimum of two functions are comparable if the functions are pointwise +comparable -/] theorem ciSup_mono {f g : ι → α} (B : BddAbove (range g)) (H : ∀ x, f x ≤ g x) : iSup f ≤ iSup g := by cases isEmpty_or_nonempty ι · rw [iSup_of_empty', iSup_of_empty'] · exact ciSup_le fun x => le_ciSup_of_le B x (H x) +@[to_dual] theorem ciSup_sup_eq {f g : ι → α} (Hf : BddAbove <| range f) (Hg : BddAbove <| range g) : ⨆ x, f x ⊔ g x = (⨆ x, f x) ⊔ (⨆ x, g x) := by cases isEmpty_or_nonempty ι @@ -176,60 +157,21 @@ theorem ciSup_sup_eq {f g : ι → α} (Hf : BddAbove <| range f) (Hg : BddAbove have := bbdAbove_range_sup Hf Hg exact sup_le (ciSup_mono this fun _ ↦ le_sup_left) (ciSup_mono this fun _ ↦ le_sup_right) +@[to_dual ciInf_set_le] theorem le_ciSup_set {f : β → α} {s : Set β} (H : BddAbove (f '' s)) {c : β} (hc : c ∈ s) : f c ≤ ⨆ i : s, f i := (le_csSup H <| mem_image_of_mem f hc).trans_eq sSup_image' -/-- The indexed infimum of two functions are comparable if the functions are pointwise comparable -/ -@[gcongr low] -theorem ciInf_mono {f g : ι → α} (B : BddBelow (range f)) (H : ∀ x, f x ≤ g x) : iInf f ≤ iInf g := - ciSup_mono (α := αᵒᵈ) B H - -theorem ciInf_inf_eq {f g : ι → α} (Hf : BddBelow <| range f) (Hg : BddBelow <| range g) : - ⨅ x, f x ⊓ g x = (⨅ x, f x) ⊓ (⨅ x, g x) := - ciSup_sup_eq (α := αᵒᵈ) Hf Hg - -/-- The indexed minimum of a function is bounded below by a uniform lower bound -/ -theorem le_ciInf [Nonempty ι] {f : ι → α} {c : α} (H : ∀ x, c ≤ f x) : c ≤ iInf f := - ciSup_le (α := αᵒᵈ) H - -/-- The indexed infimum of a function is bounded above by the value taken at one point -/ -theorem ciInf_le {f : ι → α} (H : BddBelow (range f)) (c : ι) : iInf f ≤ f c := - le_ciSup (α := αᵒᵈ) H c - -theorem ciInf_le_of_le {f : ι → α} (H : BddBelow (range f)) (c : ι) (h : f c ≤ a) : iInf f ≤ a := - le_ciSup_of_le (α := αᵒᵈ) H c h - +@[to_dual] theorem ciSup_mono_of_forall_exists {ι'} [Nonempty ι] {f : ι → α} {g : ι' → α} (hg : BddAbove <| range g) (h : ∀ i, ∃ i', f i ≤ g i') : ⨆ i, f i ≤ ⨆ i', g i' := ciSup_le fun i ↦ h i |>.elim <| le_ciSup_of_le hg -theorem ciInf_mono_of_forall_exists {ι'} [Nonempty ι'] {f : ι → α} {g : ι' → α} - (hf : BddBelow <| range f) (h : ∀ i', ∃ i, f i ≤ g i') : ⨅ i, f i ≤ ⨅ i', g i' := - ciSup_mono_of_forall_exists (α := αᵒᵈ) hf h - -/-- If the set of all `f i j` is bounded below, then so is the set of the infimums of every row -/ -theorem BddBelow.range_iInf_of_iUnion_range {κ : ι → Sort*} {f : ∀ i, κ i → α} - (H : BddBelow <| ⋃ i, range (f i)) : BddBelow <| range fun i ↦ ⨅ j, f i j := by - have ⟨a, h⟩ := H - refine ⟨a ⊓ (sInf ∅), fun x ⟨i, hx⟩ ↦ hx ▸ ?_⟩ - cases isEmpty_or_nonempty <| κ i - · exact iInf_of_isEmpty (f i) ▸ inf_le_right - exact le_ciInf fun j ↦ inf_le_of_left_le <| h ⟨_, ⟨i, rfl⟩, ⟨j, rfl⟩⟩ - -theorem ciInf₂_le {κ : ι → Sort*} {f : ∀ i, κ i → α} (H : BddBelow <| ⋃ i, range (f i)) (i : ι) - (j : κ i) : ⨅ (i) (j), f i j ≤ f i j := - ciInf_le_of_le H.range_iInf_of_iUnion_range i <| - ciInf_le (H.mono <| subset_iUnion (range <| f ·) i) j - -theorem ciInf_set_le {f : β → α} {s : Set β} (H : BddBelow (f '' s)) {c : β} (hc : c ∈ s) : - ⨅ i : s, f i ≤ f c := - le_ciSup_set (α := αᵒᵈ) H hc - lemma ciInf_le_ciSup [Nonempty ι] {f : ι → α} (hf : BddBelow (range f)) (hf' : BddAbove (range f)) : ⨅ i, f i ≤ ⨆ i, f i := (ciInf_le hf (Classical.arbitrary _)).trans <| le_ciSup hf' (Classical.arbitrary _) +@[to_dual] lemma ciSup_prod {f : β × γ → α} (hf : BddAbove (Set.range f)) : ⨆ p, f p = ⨆ b, ⨆ c, f (b, c) := by rcases isEmpty_or_nonempty β @@ -251,34 +193,25 @@ lemma ciSup_prod {f : β × γ → α} (hf : BddAbove (Set.range f)) : conv_rhs => enter [b]; rw [ciSup_le_iff (h₂ b)] simp [Prod.forall] -lemma ciInf_prod {f : β × γ → α} (hf : BddBelow (Set.range f)) : - ⨅ p, f p = ⨅ b, ⨅ c, f (b, c) := - ciSup_prod (α := αᵒᵈ) hf - /-- Introduction rule to prove that `b` is the supremum of `f`: it suffices to check that `b` is larger than `f i` for all `i`, and that this is not the case of any `wb`. +See `iInf_eq_of_forall_ge_of_forall_gt_exists_lt` for a version in complete lattices. -/] theorem ciSup_eq_of_forall_le_of_forall_lt_exists_gt [Nonempty ι] {f : ι → α} (h₁ : ∀ i, f i ≤ b) (h₂ : ∀ w, w < b → ∃ i, w < f i) : ⨆ i : ι, f i = b := csSup_eq_of_forall_le_of_forall_lt_exists_gt (range_nonempty f) (forall_mem_range.mpr h₁) fun w hw => exists_range_iff.mpr <| h₂ w hw -/-- Introduction rule to prove that `b` is the infimum of `f`: it suffices to check that `b` -is smaller than `f i` for all `i`, and that this is not the case of any `w>b`. -See `iInf_eq_of_forall_ge_of_forall_gt_exists_lt` for a version in complete lattices. -/ -theorem ciInf_eq_of_forall_ge_of_forall_gt_exists_lt [Nonempty ι] {f : ι → α} (h₁ : ∀ i, b ≤ f i) - (h₂ : ∀ w, b < w → ∃ i, f i < w) : ⨅ i : ι, f i = b := - ciSup_eq_of_forall_le_of_forall_lt_exists_gt (α := αᵒᵈ) h₁ h₂ - +@[to_dual] lemma Set.Iic_ciInf [Nonempty ι] {f : ι → α} (hf : BddBelow (range f)) : Iic (⨅ i, f i) = ⋂ i, Iic (f i) := by ext simpa using le_ciInf_iff hf -lemma Set.Ici_ciSup [Nonempty ι] {f : ι → α} (hf : BddAbove (range f)) : - Ici (⨆ i, f i) = ⋂ i, Ici (f i) := - Iic_ciInf (α := αᵒᵈ) hf - +@[to_dual] theorem ciSup_subtype {p : ι → Prop} {f : Subtype p → α} (hf : BddAbove (Set.range f)) (hf' : sSup ∅ ≤ iSup f) : iSup f = ⨆ (i) (h : p i), f ⟨i, h⟩ := by @@ -300,11 +233,7 @@ theorem ciSup_subtype {p : ι → Prop} {f : Subtype p → α} · exact le_ciSup hf ?_ · exact hf' -theorem ciInf_subtype {p : ι → Prop} {f : Subtype p → α} - (hf : BddBelow (Set.range f)) (hf' : iInf f ≤ sInf ∅) : - iInf f = ⨅ (i) (h : p i), f ⟨i, h⟩ := - ciSup_subtype (α := αᵒᵈ) hf hf' - +@[to_dual] theorem cbiSup_eq_ciSup_subtype {p : ι → Prop} {f : ∀ i, p i → α} (hf : BddAbove (Set.range (fun i : Subtype p ↦ f i i.prop))) (hf' : sSup ∅ ≤ ⨆ (i : Subtype p), f i i.prop) : @@ -313,14 +242,9 @@ theorem cbiSup_eq_ciSup_subtype {p : ι → Prop} {f : ∀ i, p i → α} @[deprecated (since := "2026-04-04")] alias ciSup_subtype' := cbiSup_eq_ciSup_subtype -theorem cbiInf_eq_ciInf_subtype {p : ι → Prop} {f : ∀ i, p i → α} - (hf : BddBelow (Set.range (fun i : Subtype p ↦ f i i.prop))) - (hf' : ⨅ (i : Subtype p), f i i.prop ≤ sInf ∅) : - ⨅ (i) (h), f i h = ⨅ x : Subtype p, f x x.property := - (ciInf_subtype (f := fun x => f x.val x.property) hf hf').symm - @[deprecated (since := "2026-04-04")] alias ciInf_subtype' := cbiInf_eq_ciInf_subtype +@[to_dual] theorem ciSup_subtype_fun {ι} {s : Set ι} {f : ι → α} (hf : BddAbove (Set.range fun i : s ↦ f i)) (hf' : sSup ∅ ≤ ⨆ i : s, f i) : ⨆ i : s, f i = ⨆ (t : ι) (_ : t ∈ s), f t := @@ -328,33 +252,21 @@ theorem ciSup_subtype_fun {ι} {s : Set ι} {f : ι → α} @[deprecated (since := "2026-04-04")] alias ciSup_subtype'' := ciSup_subtype_fun -theorem ciInf_subtype_fun {ι} {s : Set ι} {f : ι → α} - (hf : BddBelow (Set.range fun i : s ↦ f i)) (hf' : ⨅ i : s, f i ≤ sInf ∅) : - ⨅ i : s, f i = ⨅ (t : ι) (_ : t ∈ s), f t := - ciInf_subtype hf hf' - @[deprecated (since := "2026-04-04")] alias ciInf_subtype'' := ciInf_subtype_fun +@[to_dual] theorem csSup_image {s : Set β} {f : β → α} (hf : BddAbove (Set.range fun i : s ↦ f i)) (hf' : sSup ∅ ≤ ⨆ i : s, f i) : sSup (f '' s) = ⨆ a ∈ s, f a := by rw [← ciSup_subtype_fun hf hf', iSup, Set.image_eq_range] -theorem csInf_image {s : Set β} {f : β → α} - (hf : BddBelow (Set.range fun i : s ↦ f i)) (hf' : ⨅ i : s, f i ≤ sInf ∅) : - sInf (f '' s) = ⨅ a ∈ s, f a := - csSup_image (α := αᵒᵈ) hf hf' - +@[to_dual] theorem cbiSup_id {s : Set α} (hs : BddAbove s) (h : sSup ∅ ≤ sSup s) : ⨆ i ∈ s, i = sSup s := by rw [← csSup_image (Subtype.range_coe ▸ hs), Set.image_id'] · convert! h rw [← sSup_range, Subtype.range_coe] -theorem cbiInf_id {s : Set α} (hs : BddBelow s) (h : sInf s ≤ sInf ∅) : ⨅ i ∈ s, i = sInf s := by - rw [← csInf_image (Subtype.range_coe ▸ hs), Set.image_id'] - · convert! h - rw [← sInf_range, Subtype.range_coe] - +@[to_dual] lemma ciSup_image {ι ι' : Type*} {s : Set ι} {f : ι → ι'} {g : ι' → α} (hf : BddAbove (Set.range fun i : s ↦ g (f i))) (hg' : sSup ∅ ≤ ⨆ i : s, g (f i)) : ⨆ i ∈ (f '' s), g i = ⨆ x ∈ s, g (f x) := by @@ -375,13 +287,9 @@ lemma ciSup_image {ι ι' : Type*} {s : Set ι} {f : ι → ι'} {g : ι' → α simpa [bddAbove_def] using hf rw [← csSup_image hg hf', ← csSup_image hf hg', ← Set.image_comp, comp_def] -lemma ciInf_image {ι ι' : Type*} {s : Set ι} {f : ι → ι'} {g : ι' → α} - (hf : BddBelow (Set.range fun i : s ↦ g (f i))) (hg' : ⨅ i : s, g (f i) ≤ sInf ∅) : - ⨅ i ∈ (f '' s), g i = ⨅ x ∈ s, g (f x) := - ciSup_image (α := αᵒᵈ) hf hg' - /-- Note that equality need not hold: consider `ι := Bool, p := (·), α := ℤ, f := fun _ ↦ -1`, then the LHS is `-1` but the RHS is `-1 ⊔ sSup ∅ = -1 ⊔ 0 = 0`. -/ +@[to_dual] theorem ciSup_exists_le {p : ι → Prop} {f : Exists p → α} : ⨆ ih, f ih ≤ ⨆ (i) (h), f ⟨i, h⟩ := by by_cases! h : Exists p · have : Nonempty <| Exists p := ⟨h⟩ @@ -391,15 +299,10 @@ theorem ciSup_exists_le {p : ι → Prop} {f : Exists p → α} : ⨆ ih, f ih · cases isEmpty_or_nonempty ι <;> simp [h, iSup_of_empty', ciSup_const] -theorem le_ciInf_exists {p : ι → Prop} {f : Exists p → α} : ⨅ (i) (h), f ⟨i, h⟩ ≤ ⨅ ih, f ih := - ciSup_exists_le (α := αᵒᵈ) - +@[to_dual] theorem ciSup_and {p q : Prop} {f : p ∧ q → α} : ⨆ ih, f ih = ⨆ (h₁) (h₂), f ⟨h₁, h₂⟩ := by by_cases hp : p <;> by_cases hq : q <;> simp [hp, hq, iSup_of_empty'] -theorem ciInf_and {p q : Prop} {f : p ∧ q → α} : ⨅ ih, f ih = ⨅ (h₁) (h₂), f ⟨h₁, h₂⟩ := - ciSup_and (α := αᵒᵈ) - end ConditionallyCompleteLattice section ConditionallyCompleteLinearOrder @@ -421,16 +324,14 @@ theorem ciInf_inf_le {f g : ι → α} : (⨅ x, f x) ⊓ (⨅ x, g x) ≤ ⨅ x /-- Indexed version of `exists_lt_of_lt_csSup`. When `b < iSup f`, there is an element `i` such that `b < f i`. -/ +@[to_dual +/-- Indexed version of `exists_lt_of_csInf_lt`. +When `iInf f < a`, there is an element `i` such that `f i < a`. +-/] theorem exists_lt_of_lt_ciSup [Nonempty ι] {f : ι → α} (h : b < iSup f) : ∃ i, b < f i := let ⟨_, ⟨i, rfl⟩, h⟩ := exists_lt_of_lt_csSup (range_nonempty f) h ⟨i, h⟩ -/-- Indexed version of `exists_lt_of_csInf_lt`. -When `iInf f < a`, there is an element `i` such that `f i < a`. --/ -theorem exists_lt_of_ciInf_lt [Nonempty ι] {f : ι → α} (h : iInf f < a) : ∃ i, f i < a := - exists_lt_of_lt_ciSup (α := αᵒᵈ) h - theorem lt_ciSup_iff [Nonempty ι] {f : ι → α} (hb : BddAbove (range f)) : a < iSup f ↔ ∃ i, a < f i := by simpa only [mem_range, exists_exists_eq_and] using! lt_csSup_iff hb (range_nonempty _) @@ -566,38 +467,26 @@ namespace GaloisConnection variable [ConditionallyCompleteLattice α] [ConditionallyCompleteLattice β] [Nonempty ι] {l : α → β} {u : β → α} +@[to_dual u_csInf] theorem l_csSup (gc : GaloisConnection l u) {s : Set α} (hne : s.Nonempty) (hbdd : BddAbove s) : l (sSup s) = ⨆ x : s, l x := Eq.symm <| IsLUB.ciSup_set_eq (gc.isLUB_l_image <| isLUB_csSup hne hbdd) hne +@[to_dual u_csInf'] theorem l_csSup' (gc : GaloisConnection l u) {s : Set α} (hne : s.Nonempty) (hbdd : BddAbove s) : l (sSup s) = sSup (l '' s) := by rw [gc.l_csSup hne hbdd, sSup_image'] +@[to_dual u_ciInf] theorem l_ciSup (gc : GaloisConnection l u) {f : ι → α} (hf : BddAbove (range f)) : l (⨆ i, f i) = ⨆ i, l (f i) := by rw [iSup, gc.l_csSup (range_nonempty _) hf, iSup_range'] +@[to_dual u_ciInf_set] theorem l_ciSup_set (gc : GaloisConnection l u) {s : Set γ} {f : γ → α} (hf : BddAbove (f '' s)) (hne : s.Nonempty) : l (⨆ i : s, f i) = ⨆ i : s, l (f i) := by haveI := hne.to_subtype rw [image_eq_range] at hf exact gc.l_ciSup hf -theorem u_csInf (gc : GaloisConnection l u) {s : Set β} (hne : s.Nonempty) (hbdd : BddBelow s) : - u (sInf s) = ⨅ x : s, u x := - gc.dual.l_csSup hne hbdd - -theorem u_csInf' (gc : GaloisConnection l u) {s : Set β} (hne : s.Nonempty) (hbdd : BddBelow s) : - u (sInf s) = sInf (u '' s) := - gc.dual.l_csSup' hne hbdd - -theorem u_ciInf (gc : GaloisConnection l u) {f : ι → β} (hf : BddBelow (range f)) : - u (⨅ i, f i) = ⨅ i, u (f i) := - gc.dual.l_ciSup hf - -theorem u_ciInf_set (gc : GaloisConnection l u) {s : Set γ} {f : γ → β} (hf : BddBelow (f '' s)) - (hne : s.Nonempty) : u (⨅ i : s, f i) = ⨅ i : s, u (f i) := - gc.dual.l_ciSup_set hf hne - end GaloisConnection namespace OrderIso @@ -605,38 +494,26 @@ namespace OrderIso section ConditionallyCompleteLattice variable [ConditionallyCompleteLattice α] [ConditionallyCompleteLattice β] [Nonempty ι] +@[to_dual] theorem map_csSup (e : α ≃o β) {s : Set α} (hne : s.Nonempty) (hbdd : BddAbove s) : e (sSup s) = ⨆ x : s, e x := e.to_galoisConnection.l_csSup hne hbdd +@[to_dual] theorem map_csSup' (e : α ≃o β) {s : Set α} (hne : s.Nonempty) (hbdd : BddAbove s) : e (sSup s) = sSup (e '' s) := e.to_galoisConnection.l_csSup' hne hbdd +@[to_dual] theorem map_ciSup (e : α ≃o β) {f : ι → α} (hf : BddAbove (range f)) : e (⨆ i, f i) = ⨆ i, e (f i) := e.to_galoisConnection.l_ciSup hf +@[to_dual] theorem map_ciSup_set (e : α ≃o β) {s : Set γ} {f : γ → α} (hf : BddAbove (f '' s)) (hne : s.Nonempty) : e (⨆ i : s, f i) = ⨆ i : s, e (f i) := e.to_galoisConnection.l_ciSup_set hf hne -theorem map_csInf (e : α ≃o β) {s : Set α} (hne : s.Nonempty) (hbdd : BddBelow s) : - e (sInf s) = ⨅ x : s, e x := - e.dual.map_csSup hne hbdd - -theorem map_csInf' (e : α ≃o β) {s : Set α} (hne : s.Nonempty) (hbdd : BddBelow s) : - e (sInf s) = sInf (e '' s) := - e.dual.map_csSup' hne hbdd - -theorem map_ciInf (e : α ≃o β) {f : ι → α} (hf : BddBelow (range f)) : - e (⨅ i, f i) = ⨅ i, e (f i) := - e.dual.map_ciSup hf - -theorem map_ciInf_set (e : α ≃o β) {s : Set γ} {f : γ → α} (hf : BddBelow (f '' s)) - (hne : s.Nonempty) : e (⨅ i : s, f i) = ⨅ i : s, e (f i) := - e.dual.map_ciSup_set hf hne - end ConditionallyCompleteLattice section ConditionallyCompleteLinearOrderBot From 48e6e57aac375c42afb73d83e0007a4440dbd1d8 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 11:36:48 -0700 Subject: [PATCH 0015/1300] Add finset supremum convergence lemmas --- .../Topology/Order/MonotoneConvergence.lean | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 525b8006cece8f..2ce07750fb97c4 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -5,6 +5,7 @@ Authors: Heather Macbeth, Yury Kudryashov -/ module +public import Mathlib.Order.CompleteLattice.Finset public import Mathlib.Topology.Order.Basic /-! @@ -164,6 +165,35 @@ end iInf end +section FinsetSup + +variable {ι α : Type*} [TopologicalSpace α] + +theorem tendsto_finset_sup_iSup [CompleteLattice α] [SupConvergenceClass α] (a : ι → α) : + Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by + have hmono : Monotone (fun F : Finset ι => F.sup a) := + fun F G hFG => Finset.sup_mono hFG + simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup hmono + +theorem tendsto_finset_sup_ciSup [ConditionallyCompleteLattice α] [OrderBot α] + [SupConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddAbove (Set.range a)) : + Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by + have hmono : Monotone (fun F : Finset ι => F.sup a) := + fun F G hFG => Finset.sup_mono hFG + have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by + refine ⟨⨆ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.sup_le fun i _ => le_ciSup ha i + have hsup : (⨆ F : Finset ι, F.sup a) = ⨆ i, a i := by + refine le_antisymm ?_ ?_ + · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i + · exact ciSup_le fun i => + (Finset.le_sup (s := ({i} : Finset ι)) (f := a) (by simp)).trans + (le_ciSup hbdd ({i} : Finset ι)) + simpa [hsup] using tendsto_atTop_ciSup hmono hbdd + +end FinsetSup + instance Prod.supConvergenceClass [Preorder α] [Preorder β] [TopologicalSpace α] [TopologicalSpace β] [SupConvergenceClass α] [SupConvergenceClass β] : SupConvergenceClass (α × β) := by From 87213eeb1cd68058e298f6fb7797dedcb415d69a Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 13:19:48 -0700 Subject: [PATCH 0016/1300] Add finset infimum convergence lemmas --- .../Topology/Order/MonotoneConvergence.lean | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 2ce07750fb97c4..9ff4b140a8158d 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -165,7 +165,7 @@ end iInf end -section FinsetSup +section FinsetSupInf variable {ι α : Type*} [TopologicalSpace α] @@ -192,7 +192,30 @@ theorem tendsto_finset_sup_ciSup [ConditionallyCompleteLattice α] [OrderBot α] (le_ciSup hbdd ({i} : Finset ι)) simpa [hsup] using tendsto_atTop_ciSup hmono hbdd -end FinsetSup +theorem tendsto_finset_inf_iInf [CompleteLattice α] [InfConvergenceClass α] (a : ι → α) : + Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by + have hanti : Antitone (fun F : Finset ι => F.inf a) := + fun F G hFG => Finset.inf_mono hFG + simpa [Finset.inf_eq_iInf, ← iInf_eq_iInf_finset a] using tendsto_atTop_iInf hanti + +theorem tendsto_finset_inf_ciInf [ConditionallyCompleteLattice α] [OrderTop α] + [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (Set.range a)) : + Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by + have hanti : Antitone (fun F : Finset ι => F.inf a) := + fun F G hFG => Finset.inf_mono hFG + have hbdd : BddBelow (Set.range fun F : Finset ι => F.inf a) := by + refine ⟨⨅ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.le_inf fun i _ => ciInf_le ha i + have hinf : (⨅ F : Finset ι, F.inf a) = ⨅ i, a i := by + refine le_antisymm ?_ ?_ + · exact le_ciInf fun i => + (ciInf_le hbdd ({i} : Finset ι)).trans + (Finset.inf_le (s := ({i} : Finset ι)) (f := a) (by simp)) + · exact le_ciInf fun F => Finset.le_inf fun i _ => ciInf_le ha i + simpa [hinf] using tendsto_atTop_ciInf hanti hbdd + +end FinsetSupInf instance Prod.supConvergenceClass [Preorder α] [Preorder β] [TopologicalSpace α] [TopologicalSpace β] From d3d402c26130abdf5d079a2a41b02c2cd3637056 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 14:08:18 -0700 Subject: [PATCH 0017/1300] Rework finset convergence lemmas via ciSup --- .../Topology/Order/MonotoneConvergence.lean | 79 +++++++++++-------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 9ff4b140a8158d..205cb16c796ca6 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -5,7 +5,6 @@ Authors: Heather Macbeth, Yury Kudryashov -/ module -public import Mathlib.Order.CompleteLattice.Finset public import Mathlib.Topology.Order.Basic /-! @@ -167,53 +166,71 @@ end section FinsetSupInf -variable {ι α : Type*} [TopologicalSpace α] +variable {ι α : Type*} -theorem tendsto_finset_sup_iSup [CompleteLattice α] [SupConvergenceClass α] (a : ι → α) : - Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - have hmono : Monotone (fun F : Finset ι => F.sup a) := - fun F G hFG => Finset.sup_mono hFG - simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup hmono +theorem ciSup_eq_ciSup_finset [ConditionallyCompleteLattice α] [OrderBot α] [Nonempty ι] + (a : ι → α) (ha : BddAbove (Set.range a)) : + ⨆ i, a i = ⨆ F : Finset ι, F.sup a := by + have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by + refine ⟨⨆ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.sup_le fun i _ => le_ciSup ha i + refine le_antisymm ?_ ?_ + · exact ciSup_le fun i => + (Finset.le_sup (s := ({i} : Finset ι)) (f := a) (by simp)).trans + (le_ciSup hbdd ({i} : Finset ι)) + · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i + +theorem ciInf_eq_ciInf_finset [ConditionallyCompleteLattice α] [OrderTop α] [Nonempty ι] + (a : ι → α) (ha : BddBelow (Set.range a)) : + ⨅ i, a i = ⨅ F : Finset ι, F.inf a := by + have hbdd : BddBelow (Set.range fun F : Finset ι => F.inf a) := by + refine ⟨⨅ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.le_inf fun i _ => ciInf_le ha i + refine le_antisymm ?_ ?_ + · exact le_ciInf fun F => Finset.le_inf fun i _ => ciInf_le ha i + · exact le_ciInf fun i => + (ciInf_le hbdd ({i} : Finset ι)).trans + (Finset.inf_le (s := ({i} : Finset ι)) (f := a) (by simp)) + +variable [TopologicalSpace α] theorem tendsto_finset_sup_ciSup [ConditionallyCompleteLattice α] [OrderBot α] [SupConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddAbove (Set.range a)) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - have hmono : Monotone (fun F : Finset ι => F.sup a) := - fun F G hFG => Finset.sup_mono hFG + have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by refine ⟨⨆ i, a i, ?_⟩ rintro _ ⟨F, rfl⟩ exact Finset.sup_le fun i _ => le_ciSup ha i - have hsup : (⨆ F : Finset ι, F.sup a) = ⨆ i, a i := by - refine le_antisymm ?_ ?_ - · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i - · exact ciSup_le fun i => - (Finset.le_sup (s := ({i} : Finset ι)) (f := a) (by simp)).trans - (le_ciSup hbdd ({i} : Finset ι)) - simpa [hsup] using tendsto_atTop_ciSup hmono hbdd - -theorem tendsto_finset_inf_iInf [CompleteLattice α] [InfConvergenceClass α] (a : ι → α) : - Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by - have hanti : Antitone (fun F : Finset ι => F.inf a) := - fun F G hFG => Finset.inf_mono hFG - simpa [Finset.inf_eq_iInf, ← iInf_eq_iInf_finset a] using tendsto_atTop_iInf hanti + simpa [ciSup_eq_ciSup_finset a ha] using tendsto_atTop_ciSup hmono hbdd theorem tendsto_finset_inf_ciInf [ConditionallyCompleteLattice α] [OrderTop α] [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (Set.range a)) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by - have hanti : Antitone (fun F : Finset ι => F.inf a) := - fun F G hFG => Finset.inf_mono hFG + have hanti : Antitone (fun F : Finset ι => F.inf a) := fun F G hFG => Finset.inf_mono hFG have hbdd : BddBelow (Set.range fun F : Finset ι => F.inf a) := by refine ⟨⨅ i, a i, ?_⟩ rintro _ ⟨F, rfl⟩ exact Finset.le_inf fun i _ => ciInf_le ha i - have hinf : (⨅ F : Finset ι, F.inf a) = ⨅ i, a i := by - refine le_antisymm ?_ ?_ - · exact le_ciInf fun i => - (ciInf_le hbdd ({i} : Finset ι)).trans - (Finset.inf_le (s := ({i} : Finset ι)) (f := a) (by simp)) - · exact le_ciInf fun F => Finset.le_inf fun i _ => ciInf_le ha i - simpa [hinf] using tendsto_atTop_ciInf hanti hbdd + simpa [ciInf_eq_ciInf_finset a ha] using tendsto_atTop_ciInf hanti hbdd + +theorem tendsto_finset_sup_iSup [CompleteLattice α] [SupConvergenceClass α] (a : ι → α) : + Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by + cases isEmpty_or_nonempty ι + · haveI := ‹IsEmpty ι› + simpa [iSup_of_empty] using + (tendsto_const_nhds : Tendsto (fun _ : Finset ι => (⊥ : α)) atTop (𝓝 ⊥)) + · exact tendsto_finset_sup_ciSup a (OrderTop.bddAbove _) + +theorem tendsto_finset_inf_iInf [CompleteLattice α] [InfConvergenceClass α] (a : ι → α) : + Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by + cases isEmpty_or_nonempty ι + · haveI := ‹IsEmpty ι› + simpa [iInf_of_empty] using + (tendsto_const_nhds : Tendsto (fun _ : Finset ι => (⊤ : α)) atTop (𝓝 ⊤)) + · exact tendsto_finset_inf_ciInf a (OrderBot.bddBelow _) end FinsetSupInf From b5e47b3543f7244d6f63b0c0f7d5e75f9c2e8f76 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 14:40:03 -0700 Subject: [PATCH 0018/1300] Use order dual for finset infimum lemmas --- .../Topology/Order/MonotoneConvergence.lean | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 205cb16c796ca6..f31ea28c1053d7 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -184,15 +184,8 @@ theorem ciSup_eq_ciSup_finset [ConditionallyCompleteLattice α] [OrderBot α] [N theorem ciInf_eq_ciInf_finset [ConditionallyCompleteLattice α] [OrderTop α] [Nonempty ι] (a : ι → α) (ha : BddBelow (Set.range a)) : ⨅ i, a i = ⨅ F : Finset ι, F.inf a := by - have hbdd : BddBelow (Set.range fun F : Finset ι => F.inf a) := by - refine ⟨⨅ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.le_inf fun i _ => ciInf_le ha i - refine le_antisymm ?_ ?_ - · exact le_ciInf fun F => Finset.le_inf fun i _ => ciInf_le ha i - · exact le_ciInf fun i => - (ciInf_le hbdd ({i} : Finset ι)).trans - (Finset.inf_le (s := ({i} : Finset ι)) (f := a) (by simp)) + rw [← OrderDual.toDual_inj] + simpa using ciSup_eq_ciSup_finset (α := αᵒᵈ) (OrderDual.toDual ∘ a) ha variable [TopologicalSpace α] @@ -209,27 +202,18 @@ theorem tendsto_finset_sup_ciSup [ConditionallyCompleteLattice α] [OrderBot α] theorem tendsto_finset_inf_ciInf [ConditionallyCompleteLattice α] [OrderTop α] [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (Set.range a)) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by - have hanti : Antitone (fun F : Finset ι => F.inf a) := fun F G hFG => Finset.inf_mono hFG - have hbdd : BddBelow (Set.range fun F : Finset ι => F.inf a) := by - refine ⟨⨅ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.le_inf fun i _ => ciInf_le ha i - simpa [ciInf_eq_ciInf_finset a ha] using tendsto_atTop_ciInf hanti hbdd + convert! tendsto_finset_sup_ciSup (α := αᵒᵈ) (OrderDual.toDual ∘ a) ha using 1 theorem tendsto_finset_sup_iSup [CompleteLattice α] [SupConvergenceClass α] (a : ι → α) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by cases isEmpty_or_nonempty ι - · haveI := ‹IsEmpty ι› - simpa [iSup_of_empty] using - (tendsto_const_nhds : Tendsto (fun _ : Finset ι => (⊥ : α)) atTop (𝓝 ⊥)) + · simp_all [iSup_of_empty, tendsto_const_nhds] · exact tendsto_finset_sup_ciSup a (OrderTop.bddAbove _) theorem tendsto_finset_inf_iInf [CompleteLattice α] [InfConvergenceClass α] (a : ι → α) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by cases isEmpty_or_nonempty ι - · haveI := ‹IsEmpty ι› - simpa [iInf_of_empty] using - (tendsto_const_nhds : Tendsto (fun _ : Finset ι => (⊤ : α)) atTop (𝓝 ⊤)) + · simp_all [iInf_of_empty, tendsto_const_nhds] · exact tendsto_finset_inf_ciInf a (OrderBot.bddBelow _) end FinsetSupInf From fd840e603783c4a1b999647b1ffb21828a4c9d4f Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 20:03:17 -0700 Subject: [PATCH 0019/1300] Use to_dual for finset supremum identity --- .../ConditionallyCompleteLattice/Finset.lean | 20 ++++++++++ .../Topology/Order/MonotoneConvergence.lean | 39 +++++-------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index c6f70a19799255..a3e806afade5b3 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -179,6 +179,26 @@ end ListMultiset end ConditionallyCompleteLinearOrder +section ConditionallyCompleteLattice + +variable [ConditionallyCompleteLattice α] + +/-- Supremum of `a i`, `i : ι`, is equal to the supremum over finite suprema of `a`. -/ +@[to_dual +/-- Infimum of `a i`, `i : ι`, is equal to the infimum over finite infima of `a`. -/] +theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} + (ha : BddAbove (range a)) : + ⨆ i, a i = ⨆ F : Finset ι, F.sup a := by + have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by + refine ⟨⨆ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.sup_le fun i _ => le_ciSup ha i + refine le_antisymm ?_ ?_ + · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup hbdd ({i} : Finset ι)) + · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i + +end ConditionallyCompleteLattice + /-! ### Relation between `sSup` / `sInf` and `Finset.sup'` / `Finset.inf'` diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index f31ea28c1053d7..29b617cf3fac2f 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -168,53 +168,32 @@ section FinsetSupInf variable {ι α : Type*} -theorem ciSup_eq_ciSup_finset [ConditionallyCompleteLattice α] [OrderBot α] [Nonempty ι] - (a : ι → α) (ha : BddAbove (Set.range a)) : - ⨆ i, a i = ⨆ F : Finset ι, F.sup a := by - have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by - refine ⟨⨆ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.sup_le fun i _ => le_ciSup ha i - refine le_antisymm ?_ ?_ - · exact ciSup_le fun i => - (Finset.le_sup (s := ({i} : Finset ι)) (f := a) (by simp)).trans - (le_ciSup hbdd ({i} : Finset ι)) - · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i - -theorem ciInf_eq_ciInf_finset [ConditionallyCompleteLattice α] [OrderTop α] [Nonempty ι] - (a : ι → α) (ha : BddBelow (Set.range a)) : - ⨅ i, a i = ⨅ F : Finset ι, F.inf a := by - rw [← OrderDual.toDual_inj] - simpa using ciSup_eq_ciSup_finset (α := αᵒᵈ) (OrderDual.toDual ∘ a) ha - variable [TopologicalSpace α] theorem tendsto_finset_sup_ciSup [ConditionallyCompleteLattice α] [OrderBot α] - [SupConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddAbove (Set.range a)) : + [SupConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by refine ⟨⨆ i, a i, ?_⟩ rintro _ ⟨F, rfl⟩ exact Finset.sup_le fun i _ => le_ciSup ha i - simpa [ciSup_eq_ciSup_finset a ha] using tendsto_atTop_ciSup hmono hbdd + simpa [ciSup_eq_ciSup_finset ha] using tendsto_atTop_ciSup hmono hbdd theorem tendsto_finset_inf_ciInf [ConditionallyCompleteLattice α] [OrderTop α] - [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (Set.range a)) : - Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by - convert! tendsto_finset_sup_ciSup (α := αᵒᵈ) (OrderDual.toDual ∘ a) ha using 1 + [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (range a)) : + Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := + tendsto_finset_sup_ciSup (α := αᵒᵈ) ha theorem tendsto_finset_sup_iSup [CompleteLattice α] [SupConvergenceClass α] (a : ι → α) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - cases isEmpty_or_nonempty ι - · simp_all [iSup_of_empty, tendsto_const_nhds] - · exact tendsto_finset_sup_ciSup a (OrderTop.bddAbove _) + have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG + simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup hmono theorem tendsto_finset_inf_iInf [CompleteLattice α] [InfConvergenceClass α] (a : ι → α) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by - cases isEmpty_or_nonempty ι - · simp_all [iInf_of_empty, tendsto_const_nhds] - · exact tendsto_finset_inf_ciInf a (OrderBot.bddBelow _) + have hanti : Antitone (fun F : Finset ι => F.inf a) := fun F G hFG => Finset.inf_mono hFG + simpa [Finset.inf_eq_iInf, ← iInf_eq_iInf_finset a] using tendsto_atTop_iInf hanti end FinsetSupInf From 4e6adfdf75c263af0e8d78cfec95c9e64750de6d Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 21:30:00 -0700 Subject: [PATCH 0020/1300] update MC --- .../Topology/Order/MonotoneConvergence.lean | 73 ++++++++++--------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 29b617cf3fac2f..a2e0766531a8ab 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -111,6 +111,8 @@ end IsGLB section CiSup +section ConditionallyCompletePartialOrder + variable [ConditionallyCompletePartialOrderSup α] [SupConvergenceClass α] {f : ι → α} theorem tendsto_atTop_ciSup (h_mono : Monotone f) (hbdd : BddAbove <| range f) : @@ -124,10 +126,28 @@ theorem tendsto_atTop_ciSup (h_mono : Monotone f) (hbdd : BddAbove <| range f) : theorem tendsto_atBot_ciSup (h_anti : Antitone f) (hbdd : BddAbove <| range f) : Tendsto f atBot (𝓝 (⨆ i, f i)) := by convert! tendsto_atTop_ciSup h_anti.dual hbdd.dual using 1 +end ConditionallyCompletePartialOrder + +section ConditionallyCompleteLattice + +theorem tendsto_finset_sup_ciSup {ι} [ConditionallyCompleteLattice α] [OrderBot α] + [SupConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : + Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by + have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG + have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by + refine ⟨⨆ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.sup_le fun i _ => le_ciSup ha i + simpa [ciSup_eq_ciSup_finset ha] using tendsto_atTop_ciSup hmono hbdd + +end ConditionallyCompleteLattice + end CiSup section CiInf +section ConditionallyCompletePartialOrder + variable [ConditionallyCompletePartialOrderInf α] [InfConvergenceClass α] {f : ι → α} theorem tendsto_atBot_ciInf (h_mono : Monotone f) (hbdd : BddBelow <| range f) : @@ -136,6 +156,17 @@ theorem tendsto_atBot_ciInf (h_mono : Monotone f) (hbdd : BddBelow <| range f) : theorem tendsto_atTop_ciInf (h_anti : Antitone f) (hbdd : BddBelow <| range f) : Tendsto f atTop (𝓝 (⨅ i, f i)) := by convert! tendsto_atBot_ciSup h_anti.dual hbdd.dual using 1 +end ConditionallyCompletePartialOrder + +section ConditionallyCompleteLattice + +theorem tendsto_finset_inf_ciInf {ι} [ConditionallyCompleteLattice α] [OrderTop α] + [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (range a)) : + Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := + tendsto_finset_sup_ciSup (α := αᵒᵈ) ha + +end ConditionallyCompleteLattice + end CiInf section iSup @@ -145,6 +176,11 @@ variable [CompleteLattice α] [SupConvergenceClass α] {f : ι → α} theorem tendsto_atTop_iSup (h_mono : Monotone f) : Tendsto f atTop (𝓝 (⨆ i, f i)) := tendsto_atTop_ciSup h_mono (OrderTop.bddAbove _) +theorem tendsto_finset_sup_iSup {ι} (a : ι → α) : + Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by + have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG + simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup hmono + theorem tendsto_atBot_iSup (h_anti : Antitone f) : Tendsto f atBot (𝓝 (⨆ i, f i)) := tendsto_atBot_ciSup h_anti (OrderTop.bddAbove _) @@ -157,6 +193,10 @@ variable [CompleteLattice α] [InfConvergenceClass α] {f : ι → α} theorem tendsto_atBot_iInf (h_mono : Monotone f) : Tendsto f atBot (𝓝 (⨅ i, f i)) := tendsto_atBot_ciInf h_mono (OrderBot.bddBelow _) +theorem tendsto_finset_inf_iInf {ι} (a : ι → α) : + Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := + tendsto_finset_sup_iSup (α := αᵒᵈ) a + theorem tendsto_atTop_iInf (h_anti : Antitone f) : Tendsto f atTop (𝓝 (⨅ i, f i)) := tendsto_atTop_ciInf h_anti (OrderBot.bddBelow _) @@ -164,39 +204,6 @@ end iInf end -section FinsetSupInf - -variable {ι α : Type*} - -variable [TopologicalSpace α] - -theorem tendsto_finset_sup_ciSup [ConditionallyCompleteLattice α] [OrderBot α] - [SupConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : - Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG - have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by - refine ⟨⨆ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.sup_le fun i _ => le_ciSup ha i - simpa [ciSup_eq_ciSup_finset ha] using tendsto_atTop_ciSup hmono hbdd - -theorem tendsto_finset_inf_ciInf [ConditionallyCompleteLattice α] [OrderTop α] - [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (range a)) : - Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := - tendsto_finset_sup_ciSup (α := αᵒᵈ) ha - -theorem tendsto_finset_sup_iSup [CompleteLattice α] [SupConvergenceClass α] (a : ι → α) : - Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG - simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup hmono - -theorem tendsto_finset_inf_iInf [CompleteLattice α] [InfConvergenceClass α] (a : ι → α) : - Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := by - have hanti : Antitone (fun F : Finset ι => F.inf a) := fun F G hFG => Finset.inf_mono hFG - simpa [Finset.inf_eq_iInf, ← iInf_eq_iInf_finset a] using tendsto_atTop_iInf hanti - -end FinsetSupInf - instance Prod.supConvergenceClass [Preorder α] [Preorder β] [TopologicalSpace α] [TopologicalSpace β] [SupConvergenceClass α] [SupConvergenceClass β] : SupConvergenceClass (α × β) := by From 8fa96c90eb6224406164e1882e032b3eb38457ec Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Sat, 13 Jun 2026 21:32:09 -0700 Subject: [PATCH 0021/1300] trivial --- Mathlib/Order/ConditionallyCompleteLattice/Finset.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 25fe2ab2403330..2836b4ae6b05aa 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -198,6 +198,7 @@ theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i end ConditionallyCompleteLattice + section CompleteLinearOrder variable {α : Type*} [CompleteLinearOrder α] {ι : Sort*} From 63d139d1c3ec90874fdcc14e7b0a261324cca0c1 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 21:33:45 -0700 Subject: [PATCH 0022/1300] move section --- .../ConditionallyCompleteLattice/Finset.lean | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 2836b4ae6b05aa..525824db98d3d9 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -21,6 +21,26 @@ open Set variable {ι α β γ : Type*} +section ConditionallyCompleteLattice + +variable [ConditionallyCompleteLattice α] + +/-- Supremum of `a i`, `i : ι`, is equal to the supremum over finite suprema of `a`. -/ +@[to_dual +/-- Infimum of `a i`, `i : ι`, is equal to the infimum over finite infima of `a`. -/] +theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} + (ha : BddAbove (range a)) : + ⨆ i, a i = ⨆ F : Finset ι, F.sup a := by + have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by + refine ⟨⨆ i, a i, ?_⟩ + rintro _ ⟨F, rfl⟩ + exact Finset.sup_le fun i _ => le_ciSup ha i + refine le_antisymm ?_ ?_ + · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup hbdd ({i} : Finset ι)) + · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i + +end ConditionallyCompleteLattice + section ConditionallyCompleteLinearOrder variable [ConditionallyCompleteLinearOrder α] {s t : Set α} {a b : α} @@ -179,26 +199,6 @@ end ListMultiset end ConditionallyCompleteLinearOrder -section ConditionallyCompleteLattice - -variable [ConditionallyCompleteLattice α] - -/-- Supremum of `a i`, `i : ι`, is equal to the supremum over finite suprema of `a`. -/ -@[to_dual -/-- Infimum of `a i`, `i : ι`, is equal to the infimum over finite infima of `a`. -/] -theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} - (ha : BddAbove (range a)) : - ⨆ i, a i = ⨆ F : Finset ι, F.sup a := by - have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by - refine ⟨⨆ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.sup_le fun i _ => le_ciSup ha i - refine le_antisymm ?_ ?_ - · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup hbdd ({i} : Finset ι)) - · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i - -end ConditionallyCompleteLattice - section CompleteLinearOrder variable {α : Type*} [CompleteLinearOrder α] {ι : Sort*} From bf6f8bccc9ace85e38711a2cc0a10021b27c71dd Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 21:34:11 -0700 Subject: [PATCH 0023/1300] trivial --- Mathlib/Order/ConditionallyCompleteLattice/Finset.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 525824db98d3d9..7d6f6da9bbd401 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -36,7 +36,7 @@ theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} rintro _ ⟨F, rfl⟩ exact Finset.sup_le fun i _ => le_ciSup ha i refine le_antisymm ?_ ?_ - · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup hbdd ({i} : Finset ι)) + · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup hbdd {i}) · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i end ConditionallyCompleteLattice From 0c9776382e5c018ed12647a6c0704296457c3fc5 Mon Sep 17 00:00:00 2001 From: dannyply <8302246+dannyply@users.noreply.github.com> Date: Sun, 14 Jun 2026 04:43:55 +0000 Subject: [PATCH 0024/1300] feat(Topology/Algebra/PontryaginDual): prove compact monoids have discrete duals (#38669) Proves that the Pontryagin dual of a compact monoid is discrete. As a consequence, it also adds the corresponding finite-type instances for compact discrete monoids. This upstreams a result first added downstream in [`YaelDillies/APAP`](https://github.com/YaelDillies/APAP), where this fact was needed to close a `sorry`. The proof separates the trivial character from all the others using the right half of the circle and adds a few reusable `Circle` helper lemmas near the existing related API. The original APAP proof was AI-assisted and then reviewed/rewritten during downstream review. For this PR, I used Codex to help adapt the APAP proof to mathlib and to refactor the supporting lemmas. --- .../SpecialFunctions/Complex/Circle.lean | 88 ++++++++++++++++++- Mathlib/Topology/Algebra/PontryaginDual.lean | 61 +++++++++---- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 12 +++ 3 files changed, 141 insertions(+), 20 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean index b525d1a43dd6a6..33a581fdc10383 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean @@ -34,6 +34,10 @@ theorem injective_arg : Injective fun z : Circle => arg z := fun z w h => theorem arg_eq_arg {z w : Circle} : arg z = arg w ↔ z = w := injective_arg.eq_iff +@[simp] +theorem arg_eq_zero {z : Circle} : arg z = 0 ↔ z = 1 := by + simpa using arg_eq_arg (w := 1) + theorem arg_exp {x : ℝ} (h₁ : -π < x) (h₂ : x ≤ π) : arg (exp x) = x := by rw [coe_exp, exp_mul_I, arg_cos_add_sin_mul_I ⟨h₁, h₂⟩] @@ -112,6 +116,54 @@ lemma exp_injOn_Ico {a b : ℝ} (h : b - a ≤ 2 * π) : InjOn exp (Ico a b) := lemma exp_injOn_Ioc {a b : ℝ} (h : b - a ≤ 2 * π) : InjOn exp (Ioc a b) := exp_injOn_of_forall_sub_mem_Ioo <| fun x ⟨hx1, hx2⟩ y ⟨hy1, hy2⟩ ↦ by constructor <;> linarith +/-- The image under `Circle.exp` of the interval of angles `(-r, r)`. -/ +def centeredArc (r : ℝ) : Set Circle := + exp '' {x | |x| < r} + +theorem bijOn_exp_Ioo_centeredArc {r : ℝ} (hr : r ≤ π) : + BijOn Circle.exp (Ioo (-r) r) (centeredArc r) := by + simp_rw [centeredArc, abs_lt, Set.Ioo_def] + refine exp_injOn_Ico ?_ |>.mono Ioo_subset_Ico_self |>.bijOn_image + grind + +theorem centeredArc_mono {r s : ℝ} (h : r ≤ s) : centeredArc r ⊆ centeredArc s := by + rintro _ ⟨x, hx, rfl⟩ + exact ⟨x, hx.trans_le h, rfl⟩ + +theorem mem_centeredArc {r : ℝ} (hr : r ≤ π) {z : Circle} : + z ∈ centeredArc r ↔ |arg z| < r := by + refine ⟨?_, fun hz ↦ ⟨arg z, hz, exp_arg z⟩⟩ + rintro ⟨t, ht, rfl⟩ + have htπ : |t| < π := ht.trans_le hr + rwa [arg_exp (neg_lt_of_abs_lt htπ) (lt_of_abs_lt htπ).le] + +theorem centeredArc_eq_empty {r : ℝ} (hr : r ≤ 0) : centeredArc r = ∅ := by + contrapose! hr + obtain ⟨-, x, hx, rfl⟩ := hr + exact (abs_nonneg x).trans_lt hx + +@[simp] +theorem centeredArc_zero : centeredArc 0 = ∅ := + centeredArc_eq_empty le_rfl + +theorem mem_centeredArc_div {z : Circle} {s : ℝ} {n : ℕ} (hs : s ≤ π) + (h1 : z ∈ centeredArc (π / n)) (h2 : z ^ n ∈ centeredArc s) : + z ∈ centeredArc (s / n) := by + have hs0 : 0 < s := by + contrapose! h2 + simp [centeredArc_eq_empty h2] + have hn0 : n ≠ 0 := by + contrapose! h1 + simp [h1] + have hn : 1 ≤ (n : ℝ) := by simpa [Nat.one_le_iff_ne_zero] + rw [mem_centeredArc ((div_le_self hs0.le hn).trans hs), + lt_div_iff₀' (one_pos.trans_le hn)] + rw [mem_centeredArc (div_le_self pi_nonneg hn)] at h1 + rwa [mem_centeredArc hs, coe_pow, ← arg_coe_angle_toReal_eq_arg, arg_pow_coe_angle, + (Angle.nsmul_toReal_eq_mul hn0).mpr (mem_Ioc_of_Ioo ?_), abs_mul, Nat.abs_cast, + arg_coe_angle_toReal_eq_arg] at h2 + rwa [neg_div, mem_Ioo, ← abs_lt, arg_coe_angle_toReal_eq_arg] + lemma exp_surjective : Surjective exp := fun z => ⟨z.val.arg, exp_arg z⟩ instance : PathConnectedSpace Circle := exp_surjective.pathConnectedSpace exp.continuous @@ -403,7 +455,41 @@ theorem Circle.isCoveringMap_exp : IsCoveringMap exp := isAddQuotientCoveringMap lemma isLocalHomeomorph_circleExp : IsLocalHomeomorph Circle.exp := Circle.isCoveringMap_exp.isLocalHomeomorph -/-- TODO: this generalizes to a large class of groups, but requires an open mapping theorem for +/-- The centered arcs `centeredArc (π / 2 ^ (n + 1))` form a neighborhood basis at `1`. +This basis is useful because multiplying two sufficiently small arcs stays inside an earlier arc. -/ +theorem Circle.hasBasis_centeredArc_div_two_pow : + (nhds (1 : Circle)).HasBasis (fun _ ↦ True) (fun n ↦ centeredArc (π / 2 ^ (n + 1))) := by + rw [← Circle.exp_zero, ← isLocalHomeomorph_circleExp.map_nhds_eq 0] + simp_rw [centeredArc, abs_lt, Set.Ioo_def, ← Real.ball_zero_eq_Ioo] + apply Filter.HasBasis.map + refine nhds_basis_uniformity <| Metric.mk_uniformity_basis_of_tendsto (l := Filter.atTop) + (fun _ _ ↦ by positivity) (by simp) ?_ + simp_rw [div_eq_mul_inv, pow_succ, mul_inv_rev, ← mul_assoc] + rw [← mul_zero (π * 2⁻¹)] + exact tendsto_inv_atTop_zero.comp (tendsto_pow_atTop_atTop_of_one_lt (by norm_num)) + |>.const_mul _ + +theorem Circle.isOpen_centeredArc (r : ℝ) : IsOpen (centeredArc r) := by + have hset : {x : ℝ | |x| < r} = Ioo (-r) r := by + ext x + simp [abs_lt] + simpa [centeredArc, hset] using + isLocalHomeomorph_circleExp.isOpenMap (Ioo (-r) r) isOpen_Ioo + +/-- If all positive powers of a point on the circle lie in the right half centered arc, +then the point is `1`. -/ +theorem Circle.eq_one_of_forall_pow_mem_centeredArc_pi_div_two {z : Circle} + (hz : ∀ n > 0, z ^ n ∈ centeredArc (π / 2)) : z = 1 := by + have hz1 : z ∈ centeredArc (π / 2) := by simpa using hz 1 + have h (n : ℕ) : z ∈ centeredArc (π / 2 ^ (n + 1)) := by + induction n with + | zero => simpa using hz1 + | succ n ih => + simpa [div_div, ← pow_succ'] using mem_centeredArc_div + (div_le_self pi_nonneg one_le_two) (by simpa) (hz (2 ^ (n + 1)) (by positivity)) + simpa [h] using Set.ext_iff.mp hasBasis_centeredArc_div_two_pow.ker z + +/- TODO: this generalizes to a large class of groups, but requires an open mapping theorem for topological groups to show the `n`th power map is open (see https://www.mathematik.tu-darmstadt.de/media/mathematik/forschung/preprint/preprints/2480.pdf and https://www.math.uwaterloo.ca/~cgodsil/pdfs/topology/topgr.pdf), and discreteness of the kernel (see https://gemini.google.com/share/6e9ab4abcb95). -/ diff --git a/Mathlib/Topology/Algebra/PontryaginDual.lean b/Mathlib/Topology/Algebra/PontryaginDual.lean index 15a396ef4737e5..769f32e134617a 100644 --- a/Mathlib/Topology/Algebra/PontryaginDual.lean +++ b/Mathlib/Topology/Algebra/PontryaginDual.lean @@ -25,6 +25,7 @@ isomorphic to its double dual. @[expose] public section open scoped Pointwise +open Real variable (A B C G H : Type*) [Monoid A] [Monoid B] [Monoid C] [CommGroup G] [Group H] [TopologicalSpace A] [TopologicalSpace B] [TopologicalSpace C] @@ -38,13 +39,10 @@ def PontryaginDual := deriving TopologicalSpace instance [LocallyCompactSpace H] : LocallyCompactSpace (PontryaginDual H) := by - let Vn : ℕ → Set Circle := - fun n ↦ Circle.exp '' { x | |x| < Real.pi / 2 ^ (n + 1)} - have hVn : ∀ n x, x ∈ Vn n ↔ |Complex.arg x| < Real.pi / 2 ^ (n + 1) := by - refine fun n x ↦ ⟨?_, fun hx ↦ ⟨Complex.arg x, hx, Circle.exp_arg x⟩⟩ - rintro ⟨t, ht : |t| < _, rfl⟩ - have ht' := ht.trans_le (div_le_self Real.pi_nonneg (one_le_pow₀ one_le_two)) - rwa [Circle.arg_exp (neg_lt_of_abs_lt ht') (lt_of_abs_lt ht').le] + let Vn : ℕ → Set Circle := fun n ↦ Circle.centeredArc (π / 2 ^ (n + 1)) + have hVn : ∀ n x, x ∈ Vn n ↔ |Complex.arg x| < π / 2 ^ (n + 1) := + fun n x ↦ Circle.mem_centeredArc (z := x) + (div_le_self pi_nonneg (one_le_pow₀ one_le_two)) refine ContinuousMonoidHom.locallyCompactSpace_of_hasBasis Vn ?_ ?_ · intro n x h1 h2 rw [hVn] at h1 h2 ⊢ @@ -55,15 +53,7 @@ instance [LocallyCompactSpace H] : LocallyCompactSpace (PontryaginDual H) := by refine h1.trans_le ?_ gcongr exact le_self_pow₀ one_le_two n.succ_ne_zero - · rw [← Circle.exp_zero, ← isLocalHomeomorph_circleExp.map_nhds_eq 0] - refine ((nhds_basis_zero_abs_lt ℝ).to_hasBasis - (fun x hx ↦ ⟨Nat.ceil (Real.pi / x), trivial, fun t ht ↦ ?_⟩) - fun k _ ↦ ⟨Real.pi / 2 ^ (k + 1), by positivity, le_rfl⟩).map Circle.exp - rw [Set.mem_setOf_eq] at ht ⊢ - refine lt_of_lt_of_le ht ?_ - rw [div_le_iff₀' (pow_pos two_pos _), ← div_le_iff₀ hx] - refine (Nat.le_ceil (Real.pi / x)).trans ?_ - exact_mod_cast (Nat.le_succ _).trans Nat.lt_two_pow_self.le + · simpa [Vn] using Circle.hasBasis_centeredArc_div_two_pow variable {A B C G} @@ -83,9 +73,42 @@ deriving instance [DiscreteTopology A] → CompactSpace _ for PontryaginDual A +@[ext] +theorem ext {ψ φ : PontryaginDual A} (h : ∀ a, ψ a = φ a) : ψ = φ := + DFunLike.ext _ _ h + +@[simp] +theorem one_apply (a : A) : (1 : PontryaginDual A) a = 1 := + rfl + /-- A discrete monoid has compact Pontryagin dual. -/ add_decl_doc instLocallyCompactSpacePontryaginDual +/-- A compact monoid has discrete Pontryagin dual. -/ +instance [CompactSpace A] : DiscreteTopology (PontryaginDual A) := by + let V : Set (PontryaginDual A) := {ψ | Set.MapsTo ψ Set.univ (Circle.centeredArc (π / 2))} + have hVopen : IsOpen V := by + dsimp only [V] + exact isOpen_induced (ContinuousMap.isOpen_setOf_mapsTo isCompact_univ + (Circle.isOpen_centeredArc (π / 2))) + have hVeq : V = ({1} : Set (PontryaginDual A)) := by + ext ψ + rw [Set.mem_singleton_iff] + refine ⟨fun hψ ↦ ?_, ?_⟩ + · ext1 a + refine Circle.eq_one_of_forall_pow_mem_centeredArc_pi_div_two fun n hn ↦ ?_ + simpa using hψ (Set.mem_univ (a ^ n)) + · rintro rfl _ _ + rw [Circle.mem_centeredArc (by linarith [pi_pos])] + simp [pi_pos] + exact discreteTopology_of_isOpen_singleton_one (by simpa [hVeq] using hVopen) + +instance [DiscreteTopology A] [CompactSpace A] : Finite (PontryaginDual A) := + finite_of_compact_of_discrete + +noncomputable instance [DiscreteTopology A] [CompactSpace A] : Fintype (PontryaginDual A) := + .ofFinite _ + /-- `PontryaginDual` is a contravariant functor. -/ def map (f : A →ₜ* B) : (PontryaginDual B) →ₜ* (PontryaginDual A) := @@ -98,16 +121,16 @@ theorem map_apply (f : A →ₜ* B) (x : PontryaginDual B) (y : A) : @[simp] theorem map_one : map (1 : A →ₜ* B) = 1 := - ext fun x => ext (fun _y => OneHomClass.map_one x) + ContinuousMonoidHom.ext fun x => PontryaginDual.ext fun _y => OneHomClass.map_one x @[simp] theorem map_comp (g : B →ₜ* C) (f : A →ₜ* B) : map (comp g f) = ContinuousMonoidHom.comp (map f) (map g) := - ext fun _x => ext fun _y => rfl + ContinuousMonoidHom.ext fun _x => PontryaginDual.ext fun _y => rfl @[simp] nonrec theorem map_mul (f g : A →ₜ* G) : map (f * g) = map f * map g := - ext fun x => ext fun y => map_mul x (f y) (g y) + ContinuousMonoidHom.ext fun x => PontryaginDual.ext fun y => map_mul x (f y) (g y) variable (A B C G) diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index e2d4122228196e..e3694f57974cec 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -1214,6 +1214,18 @@ namespace Metric variable {x y z : α} {ε ε₁ ε₂ : ℝ} {s : Set α} +/-- If `f` is a positive radius tending to zero, then the sets of pairs with distance less than +`f i` form a basis of the uniformity. -/ +lemma mk_uniformity_basis_of_tendsto {β : Type*} {p : β → Prop} {f : β → ℝ} + {l : Filter β} [l.NeBot] (hf₀ : ∀ i, p i → 0 < f i) (hf₁ : ∀ᶠ i in l, p i) + (hf : Tendsto f l (𝓝 0)) : + (𝓤 α).HasBasis p fun i ↦ {x | dist x.1 x.2 < f i} := by + apply Metric.mk_uniformity_basis hf₀ + rw [nhds_basis_closedBall.tendsto_right_iff] at hf + refine fun ε hε ↦ hf₁.and (hf ε hε) |>.exists.imp fun i ↦ and_imp.mpr fun hp hi ↦ ?_ + exact ⟨hp, by + simpa [Metric.mem_closedBall, Real.dist_eq, abs_of_nonneg (hf₀ i hp).le] using hi⟩ + theorem ball_subset_interior_closedBall : ball x ε ⊆ interior (closedBall x ε) := interior_maximal ball_subset_closedBall isOpen_ball From 76021236640b1d116a5d6007245ef520601e502a Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Sat, 13 Jun 2026 21:58:22 -0700 Subject: [PATCH 0025/1300] Fix generated ciInf theorem name --- Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean index 558f50fc38df58..217a256864676b 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean @@ -324,7 +324,7 @@ theorem ciInf_inf_le {f g : ι → α} : (⨅ x, f x) ⊓ (⨅ x, g x) ≤ ⨅ x /-- Indexed version of `exists_lt_of_lt_csSup`. When `b < iSup f`, there is an element `i` such that `b < f i`. -/ -@[to_dual +@[to_dual exists_lt_of_ciInf_lt /-- Indexed version of `exists_lt_of_csInf_lt`. When `iInf f < a`, there is an element `i` such that `f i < a`. -/] From e59d9d4058be0d9de5d54a30cd775901580a01e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sun, 14 Jun 2026 07:12:20 +0000 Subject: [PATCH 0026/1300] feat(Algebra/BigOperators/Expect): expectation of an indicator (#40388) and replace the generic variable `M` with `K` in the `Semifield` section From MeanFourier --- Mathlib/Algebra/BigOperators/Expect.lean | 26 +++++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Expect.lean b/Mathlib/Algebra/BigOperators/Expect.lean index 155aae5dc8a9af..1c0505e075c2ad 100644 --- a/Mathlib/Algebra/BigOperators/Expect.lean +++ b/Mathlib/Algebra/BigOperators/Expect.lean @@ -14,6 +14,8 @@ public import Mathlib.Data.Finset.Density public import Mathlib.Data.Fintype.BigOperators public import Mathlib.Algebra.Group.Pointwise.Finset.Basic +import Mathlib.Algebra.BigOperators.Group.Finset.Indicator + /-! # Average over a finset @@ -51,7 +53,7 @@ open Finset Function open Fintype (card) open scoped Pointwise -variable {ι κ M N : Type*} +variable {ι κ K M N : Type*} local notation a " /ℚ " q => (q : ℚ≥0)⁻¹ • a @@ -350,26 +352,30 @@ lemma expect_pow (s : Finset ι) (f : ι → M) (n : ℕ) : end CommSemiring section Semifield -variable [Semifield M] [CharZero M] +variable [Semifield K] [CharZero K] + +@[simp] lemma expect_indicator_one [Fintype ι] (s : Finset ι) : + 𝔼 i : ι, (Set.indicator s 1 i : K) = s.dens := by + classical simp [expect, sum_indicator_eq_sum_inter, dens, div_eq_inv_mul, NNRat.smul_def] -lemma expect_boole_mul [Fintype ι] [Nonempty ι] [DecidableEq ι] (f : ι → M) (i : ι) : - 𝔼 j, ite (i = j) (Fintype.card ι : M) 0 * f j = f i := by +lemma expect_boole_mul [Fintype ι] [Nonempty ι] [DecidableEq ι] (f : ι → K) (i : ι) : + 𝔼 j, ite (i = j) (Fintype.card ι : K) 0 * f j = f i := by simp_rw [expect_univ, ite_mul, zero_mul, sum_ite_eq, if_pos (mem_univ _)] - rw [← @NNRat.cast_natCast M, ← NNRat.smul_def, inv_smul_smul₀] + rw [← @NNRat.cast_natCast K, ← NNRat.smul_def, inv_smul_smul₀] simp [Fintype.card_ne_zero] -lemma expect_boole_mul' [Fintype ι] [Nonempty ι] [DecidableEq ι] (f : ι → M) (i : ι) : - 𝔼 j, ite (j = i) (Fintype.card ι : M) 0 * f j = f i := by +lemma expect_boole_mul' [Fintype ι] [Nonempty ι] [DecidableEq ι] (f : ι → K) (i : ι) : + 𝔼 j, ite (j = i) (Fintype.card ι : K) 0 * f j = f i := by simp_rw [@eq_comm _ _ i, expect_boole_mul] -lemma expect_eq_sum_div_card (s : Finset ι) (f : ι → M) : +lemma expect_eq_sum_div_card (s : Finset ι) (f : ι → K) : 𝔼 i ∈ s, f i = (∑ i ∈ s, f i) / #s := by rw [expect, NNRat.smul_def, div_eq_inv_mul, NNRat.cast_inv, NNRat.cast_natCast] -lemma _root_.Fintype.expect_eq_sum_div_card [Fintype ι] (f : ι → M) : +lemma _root_.Fintype.expect_eq_sum_div_card [Fintype ι] (f : ι → K) : 𝔼 i, f i = (∑ i, f i) / Fintype.card ι := Finset.expect_eq_sum_div_card _ _ -lemma expect_div (s : Finset ι) (f : ι → M) (a : M) : (𝔼 i ∈ s, f i) / a = 𝔼 i ∈ s, f i / a := by +lemma expect_div (s : Finset ι) (f : ι → K) (a : K) : (𝔼 i ∈ s, f i) / a = 𝔼 i ∈ s, f i / a := by simp_rw [div_eq_mul_inv, expect_mul] end Semifield From e80d076d5230771e8dd8e3d1907fb1af9ffd3a85 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sun, 14 Jun 2026 08:29:24 +0000 Subject: [PATCH 0027/1300] chore: update Mathlib dependencies 2026-06-14 (#40589) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index a46005d646bbed..eafa08243a29de 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "5dd219c775e402f818b42cd3997b5cf21017babf", + "rev": "c43d7789ff29244c1f6f7c8480342a2d2d6c0d30", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 4fcc8d62a41f9bb65a78d97d3a8d9017ad165602 Mon Sep 17 00:00:00 2001 From: Laurance <60111599+LLaurance@users.noreply.github.com> Date: Sun, 14 Jun 2026 08:55:00 +0000 Subject: [PATCH 0028/1300] chore: replace refine with intro (#40581) Replace `refine` with `intro` where the purpose is to solely `intro` variables. --- Mathlib/Analysis/Convex/Quasiconvex.lean | 2 +- Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean | 2 +- Mathlib/Data/DFinsupp/Interval.lean | 2 +- Mathlib/Data/Nat/Totient.lean | 2 +- Mathlib/Data/Set/Subsingleton.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/Independent.lean | 2 +- Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean | 2 +- Mathlib/MeasureTheory/Measure/Restrict.lean | 2 +- Mathlib/ModelTheory/Satisfiability.lean | 2 +- Mathlib/NumberTheory/LegendreSymbol/AddCharacter.lean | 2 +- Mathlib/RingTheory/Algebraic/StronglyTranscendental.lean | 4 ++-- Mathlib/RingTheory/Polynomial/Basic.lean | 4 ++-- Mathlib/Topology/MetricSpace/HolderNorm.lean | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Mathlib/Analysis/Convex/Quasiconvex.lean b/Mathlib/Analysis/Convex/Quasiconvex.lean index 88136225ccbd97..2f6e3f05c870da 100644 --- a/Mathlib/Analysis/Convex/Quasiconvex.lean +++ b/Mathlib/Analysis/Convex/Quasiconvex.lean @@ -221,7 +221,7 @@ theorem quasilinearOn_iff_mem_uIcc : QuasilinearOn 𝕜 s f ↔ Convex 𝕜 s theorem QuasiconvexOn.convex_lt (hf : QuasiconvexOn 𝕜 s f) (r : β) : Convex 𝕜 ({ x ∈ s | f x < r }) := by - refine fun x hx y hy a b ha hb hab => ?_ + intro x hx y hy a b ha hb hab have h := hf _ ⟨hx.1, le_max_left _ _⟩ ⟨hy.1, le_max_right _ _⟩ ha hb hab exact ⟨h.1, h.2.trans_lt <| max_lt hx.2 hy.2⟩ diff --git a/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean b/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean index e1c3ba1fce316f..9ae4abb0b79848 100644 --- a/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean @@ -100,7 +100,7 @@ theorem isSheaf_toGrothendieck_iff (P : Cᵒᵖ ⥤ Type*) : (∀ {X Y : C} {f : Y ⟶ X} (R : Presieve X), R ∈ J X → Presieve.IsSheafFor P ((Sieve.generate R).pullback f).arrows) := by constructor - · refine fun H _ _ _ _ hR => ?_ + · intro H _ _ _ _ hR apply H.isSheafFor rw [Sieve.generate_sieve] exact J.toGrothendieck.pullback_stable _ (Saturate.of _ _ hR) diff --git a/Mathlib/Data/DFinsupp/Interval.lean b/Mathlib/Data/DFinsupp/Interval.lean index fb5a449a44609f..4559962fd6af73 100644 --- a/Mathlib/Data/DFinsupp/Interval.lean +++ b/Mathlib/Data/DFinsupp/Interval.lean @@ -114,7 +114,7 @@ theorem mem_rangeIcc_apply_iff : a ∈ f.rangeIcc g i ↔ f i ≤ a ∧ a ≤ g theorem support_rangeIcc_subset [DecidableEq ι] [∀ i, DecidableEq (α i)] : (f.rangeIcc g).support ⊆ f.support ∪ g.support := by - refine fun x hx => ?_ + intro x hx by_contra h refine notMem_support_iff.2 ?_ hx rw [rangeIcc_apply, notMem_support_iff.1 (notMem_mono subset_union_left h), diff --git a/Mathlib/Data/Nat/Totient.lean b/Mathlib/Data/Nat/Totient.lean index b49ccd4787777e..9f59ec38d113ca 100644 --- a/Mathlib/Data/Nat/Totient.lean +++ b/Mathlib/Data/Nat/Totient.lean @@ -152,7 +152,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) : rw [gcd_mul_left, ha2, mul_one] · simp [hd0.ne'] · simp only [mem_filter, mem_range, exists_prop, and_imp] - refine fun b hb1 hb2 => ?_ + intro b hb1 hb2 have : d ∣ b := by rw [← hb2] apply gcd_dvd_right diff --git a/Mathlib/Data/Set/Subsingleton.lean b/Mathlib/Data/Set/Subsingleton.lean index b66554094adb13..948c01f09b8c53 100644 --- a/Mathlib/Data/Set/Subsingleton.lean +++ b/Mathlib/Data/Set/Subsingleton.lean @@ -121,7 +121,7 @@ theorem eq_empty_or_singleton_of_unique [Unique α] (s : Set α) : @[simp, norm_cast] theorem subsingleton_coe (s : Set α) : Subsingleton s ↔ s.Subsingleton := by constructor - · refine fun h => fun a ha b hb => ?_ + · intro h a ha b hb exact SetCoe.ext_iff.2 (@Subsingleton.elim s h ⟨a, ha⟩ ⟨b, hb⟩) · exact fun h => Subsingleton.intro fun a b => SetCoe.ext (h a.property b.property) diff --git a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean index e751e95544cebe..77f39139c1b99f 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean @@ -115,7 +115,7 @@ theorem affineIndependent_iff_linearIndependent_vsub (p : ι → P) (i1 : ι) : set g2 : { x // x ≠ i1 } → V := fun x => g x • (p x -ᵥ p i1) have hf2g2 : ∀ x : { x // x ≠ i1 }, f2 x = g2 x := by simp only [g2, hf2def] - refine fun x => ?_ + intro x rw [hfg] rw [Finset.weightedVSub_eq_weightedVSubOfPoint_of_sum_eq_zero s2 f p hf (p i1), Finset.weightedVSubOfPoint_insert, Finset.weightedVSubOfPoint_apply, diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean index 51f80547faaf2a..b07967f77a8080 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean @@ -347,7 +347,7 @@ a linear retraction `g` that also preserves the quadratic forms, then `CliffordA is a retraction of `CliffordAlgebra.map f`. -/ lemma leftInverse_map_of_leftInverse {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (f : Q₁ →qᵢ Q₂) (g : Q₂ →qᵢ Q₁) (h : LeftInverse g f) : LeftInverse (map g) (map f) := by - refine fun x => ?_ + intro x replace h : g.comp f = QuadraticMap.Isometry.id Q₁ := DFunLike.ext _ _ h rw [← AlgHom.comp_apply, map_comp_map, h, map_id, AlgHom.coe_id, id_eq] diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index a70d88a3a69a1b..7d145ac05dc563 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -128,7 +128,7 @@ theorem _root_.IsCountablySpanning.null_of_forall_restrict_null {C : Set (Set α (hC : IsCountablySpanning C) (hm : C ⊆ MeasurableSet) (ht : ∀ t ∈ C, μ.restrict t s = 0) : μ s = 0 := by rw [← forall_measure_inter_isCountablySpanning_eq_zero hC] - refine fun t htc => ?_ + intro t htc simpa [← μ.restrict_apply' (hm htc)] using ht t htc theorem restrict_apply₀' (hs : NullMeasurableSet s μ) : μ.restrict s t = μ (t ∩ s) := by diff --git a/Mathlib/ModelTheory/Satisfiability.lean b/Mathlib/ModelTheory/Satisfiability.lean index f0ff75d836b059..ff95887b9bc350 100644 --- a/Mathlib/ModelTheory/Satisfiability.lean +++ b/Mathlib/ModelTheory/Satisfiability.lean @@ -136,7 +136,7 @@ theorem isSatisfiable_union_distinctConstantsTheory_of_card_le (T : L.Theory) (s have : M ⊨ (L.lhomWithConstants α).onTheory T ∪ L.distinctConstantsTheory s := by refine ((LHom.onTheory_model _ _).2 inferInstance).union ?_ rw [model_distinctConstantsTheory] - refine fun a as b bs ab => ?_ + intro a as b bs ab rw [← Subtype.coe_mk a as, ← Subtype.coe_mk b bs, ← Subtype.ext_iff] exact h.some.injective diff --git a/Mathlib/NumberTheory/LegendreSymbol/AddCharacter.lean b/Mathlib/NumberTheory/LegendreSymbol/AddCharacter.lean index 851328dcaa1ba0..9c8589c4e800b9 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/AddCharacter.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/AddCharacter.lean @@ -173,7 +173,7 @@ theorem IsPrimitive.zmod_char_eq_one_iff (n : ℕ) [NeZero n] then it is primitive. -/ theorem zmod_char_primitive_of_eq_one_only_at_zero (n : ℕ) (ψ : AddChar (ZMod n) C) (hψ : ∀ a, ψ a = 1 → a = 0) : IsPrimitive ψ := by - refine fun a ha hf => ?_ + intro a ha hf have h : mulShift ψ a 1 = (1 : AddChar (ZMod n) C) (1 : ZMod n) := congr_fun (congr_arg (↑) hf) 1 rw [mulShift_apply, mul_one] at h; norm_cast at h diff --git a/Mathlib/RingTheory/Algebraic/StronglyTranscendental.lean b/Mathlib/RingTheory/Algebraic/StronglyTranscendental.lean index 14f6763901e8c3..a185e2c338883e 100644 --- a/Mathlib/RingTheory/Algebraic/StronglyTranscendental.lean +++ b/Mathlib/RingTheory/Algebraic/StronglyTranscendental.lean @@ -51,7 +51,7 @@ lemma isStronglyTranscendental_iff_of_field {K : Type*} [Field K] [Algebra R K] lemma IsStronglyTranscendental.of_map {x : S} {f : S →ₐ[R] T} (hf : Function.Injective f) (h : IsStronglyTranscendental R (f x)) : IsStronglyTranscendental R x := by - refine fun u p hp ↦ ?_ + intro u p hp have := h (f u) p (by rw [aeval_algHom_apply, ← map_mul, hp, map_zero]) rwa [← f.comp_algebraMap, ← map_map, ← f.coe_toRingHom, ← map_C, ← Polynomial.map_mul, ← coe_mapRingHom, map_eq_zero_iff] at this @@ -61,7 +61,7 @@ lemma IsStronglyTranscendental.of_isLocalization [Algebra S T] (M : Submonoid S) [IsLocalization M T] [IsScalarTower R S T] {x : S} (h : IsStronglyTranscendental R x) : IsStronglyTranscendental R (algebraMap S T x) := by - refine fun u p hp ↦ ?_ + intro u p hp obtain ⟨u, s, rfl⟩ := IsLocalization.exists_mk'_eq M u obtain ⟨a, haM, e⟩ : ∃ a ∈ M, a * ((aeval x) p * u) = 0 := by simpa [aeval_algebraMap_apply, ← Algebra.smul_def, IsLocalization.smul_mk', diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index 8bc610e192f05e..c186c48bb63ee7 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -424,7 +424,7 @@ theorem mem_map_C_iff {I : Ideal R} {f : R[X]} : · simp [h] · simp · exact fun f g _ _ hf hg n => by simp [I.add_mem (hf n) (hg n)] - · refine fun f g _ hg n => ?_ + · intro f g _ hg n rw [smul_eq_mul, coeff_mul] exact I.sum_mem fun c _ => I.mul_mem_left (f.coeff c.fst) (hg c.snd) · intro hf @@ -1009,7 +1009,7 @@ theorem mem_map_C_iff {I : Ideal R} {f : MvPolynomial σ R} : · simp [Ne.symm h] · simp · exact fun f g _ _ hf hg n => by simp [I.add_mem (hf n) (hg n)] - · refine fun f g _ hg n => ?_ + · intro f g _ hg n rw [smul_eq_mul, coeff_mul] exact I.sum_mem fun c _ => I.mul_mem_left (f.coeff c.fst) (hg c.snd) · intro hf diff --git a/Mathlib/Topology/MetricSpace/HolderNorm.lean b/Mathlib/Topology/MetricSpace/HolderNorm.lean index 38814b0dc9fda0..966b5a9b538ed3 100644 --- a/Mathlib/Topology/MetricSpace/HolderNorm.lean +++ b/Mathlib/Topology/MetricSpace/HolderNorm.lean @@ -202,7 +202,7 @@ variable [MetricSpace X] [EMetricSpace Y] lemma eHolderNorm_eq_zero {r : ℝ≥0} {f : X → Y} : eHolderNorm r f = 0 ↔ ∀ x₁ x₂, f x₁ = f x₂ := by constructor - · refine fun h x₁ x₂ => ?_ + · intro h x₁ x₂ by_cases hx : x₁ = x₂ · rw [hx] · rw [eHolderNorm, ← ENNReal.bot_eq_zero, iInf₂_eq_bot] at h From 6923f2f17585e9f2ef76e10ad91efe1b9cb8500d Mon Sep 17 00:00:00 2001 From: Albert Smith <10266947+ChiCubed@users.noreply.github.com> Date: Sun, 14 Jun 2026 09:14:23 +0000 Subject: [PATCH 0029/1300] feat(NumberTheory/Padics/PadicVal): remove redundant hypotheses + add `padicValRat.zpow` (#40558) We remove redundant hypotheses q != 0 on pow / inv theorems (which can now be simp), and add the missing theorem `padicValRat.zpow` --- .../NumberTheory/Padics/PadicVal/Basic.lean | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean index 18333fad51b625..80b6ae2ff73f00 100644 --- a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean +++ b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean @@ -237,19 +237,28 @@ protected theorem mul {q r : ℚ} (hq : q ≠ 0) (hr : r ≠ 0) : · simp [finite_int_prime_iff] · simp [finite_int_prime_iff, hq, hr] -/-- A rewrite lemma for `padicValRat p (q^k)` with condition `q ≠ 0`. -/ -protected theorem pow {q : ℚ} (hq : q ≠ 0) {k : ℕ} : +/-- A rewrite lemma for `padicValRat p (q^k)`. -/ +@[simp] +protected theorem pow (q : ℚ) {k : ℕ} : padicValRat p (q ^ k) = k * padicValRat p q := by + obtain rfl | hq := eq_or_ne q 0 + · cases k <;> simp induction k <;> simp [*, padicValRat.mul hq (pow_ne_zero _ hq), _root_.pow_succ', add_mul, add_comm] -/-- A rewrite lemma for `padicValRat p (q⁻¹)` with condition `q ≠ 0`. -/ +/-- A rewrite lemma for `padicValRat p (q⁻¹)`. -/ +@[simp] protected theorem inv (q : ℚ) : padicValRat p q⁻¹ = -padicValRat p q := by by_cases hq : q = 0 · simp [hq] · rw [eq_neg_iff_add_eq_zero, ← padicValRat.mul (inv_ne_zero hq) hq, inv_mul_cancel₀ hq, padicValRat.one] +@[simp] +protected theorem zpow (q : ℚ) {k : ℤ} : + padicValRat p (q ^ k) = k * padicValRat p q := by + induction k using Int.negInduction <;> simp + /-- A rewrite lemma for `padicValRat p (q / r)` with conditions `q ≠ 0`, `r ≠ 0`. -/ protected theorem div {q r : ℚ} (hq : q ≠ 0) (hr : r ≠ 0) : padicValRat p (q / r) = padicValRat p q - padicValRat p r := by @@ -329,10 +338,8 @@ lemma lt_add_of_lt {q r₁ r₂ : ℚ} (hqr : r₁ + r₂ ≠ 0) padicValRat p q < padicValRat p (r₁ + r₂) := lt_of_lt_of_le (lt_min hval₁ hval₂) (padicValRat.min_le_padicValRat_add hqr) -@[simp] lemma self_pow_inv (r : ℕ) : padicValRat p ((p : ℚ) ^ r)⁻¹ = -r := by - rw [padicValRat.inv, neg_inj, padicValRat.pow (Nat.cast_ne_zero.mpr hp.elim.ne_zero), - padicValRat.self hp.elim.one_lt, mul_one] + rw [padicValRat.inv, neg_inj, padicValRat.pow p, padicValRat.self hp.elim.one_lt, mul_one] /-- A finite sum of rationals with positive `p`-adic valuation has positive `p`-adic valuation (if the sum is non-zero). -/ @@ -388,12 +395,12 @@ protected theorem div (dvd : p ∣ b) : padicValNat p (b / p) = padicValNat p b rw [padicValNat.div_of_dvd dvd, padicValNat_self] /-- A version of `padicValRat.pow` for `padicValNat`. -/ -protected theorem pow (n : ℕ) (ha : a ≠ 0) : padicValNat p (a ^ n) = n * padicValNat p a := by - simpa only [← @Nat.cast_inj ℤ, push_cast] using padicValRat.pow (Nat.cast_ne_zero.mpr ha) - @[simp] +protected theorem pow (a n : ℕ) : padicValNat p (a ^ n) = n * padicValNat p a := by + simpa only [← @Nat.cast_inj ℤ, push_cast] using padicValRat.pow a + protected theorem prime_pow (n : ℕ) : padicValNat p (p ^ n) = n := by - rw [padicValNat.pow _ (@Fact.out p.Prime).ne_zero, padicValNat_self, mul_one] + rw [padicValNat.pow p, padicValNat_self, mul_one] protected theorem div_pow (dvd : p ^ a ∣ b) : padicValNat p (b / p ^ a) = padicValNat p b - a := by rw [padicValNat.div_of_dvd dvd, padicValNat.prime_pow] @@ -444,7 +451,7 @@ theorem padicValNat_primes {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime] (ne theorem padicValNat_prime_prime_pow {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime] (n : ℕ) (ne : p ≠ q) : padicValNat p (q ^ n) = 0 := by - rw [padicValNat.pow _ <| Nat.Prime.ne_zero hq.elim, padicValNat_primes ne, mul_zero] + rw [padicValNat.pow _, padicValNat_primes ne, mul_zero] theorem padicValNat_mul_pow_left {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime] (n m : ℕ) (ne : p ≠ q) : padicValNat p (p ^ n * q ^ m) = n := by From 271d273e99cbdbeae1cfce4cee1a0eaa1736bbcd Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:00:39 +0000 Subject: [PATCH 0030/1300] feat(Combinatorics/SimpleGraph/Basic): more `neighborSet` and `IsIsolated` lemmas (#38747) --- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 65 +++++++++++++++++++ Mathlib/Combinatorics/SimpleGraph/Finite.lean | 17 ++--- Mathlib/Combinatorics/SimpleGraph/Maps.lean | 5 -- .../SimpleGraph/StronglyRegular.lean | 2 +- 4 files changed, 72 insertions(+), 17 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 78c9d1e7668b4c..8ca659a86b0a21 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -749,6 +749,18 @@ theorem mem_neighborSet (v w : V) : w ∈ G.neighborSet v ↔ G.Adj v w := lemma notMem_neighborSet_self : a ∉ G.neighborSet a := by simp +variable {G} in +theorem nonempty_neighborSet : (G.neighborSet v).Nonempty ↔ ∃ u, G.Adj v u := + .rfl + +variable (v) in +theorem neighborSet_subset_compl : G.neighborSet v ⊆ {v}ᶜ := by + simp + +variable (v) in +theorem neighborSet_ne_univ : G.neighborSet v ≠ .univ := + Set.ne_univ_iff_exists_notMem _ |>.mpr ⟨v, G.notMem_neighborSet_self⟩ + @[simp] theorem mem_incidenceSet (v w : V) : s(v, w) ∈ G.incidenceSet v ↔ G.Adj v w := by simp [incidenceSet] @@ -792,6 +804,23 @@ theorem neighborSet_compl (G : SimpleGraph V) (v : V) : ext w simp [and_comm, eq_comm] +variable {G} in +@[gcongr] +theorem neighborSet_mono {G' : SimpleGraph V} (hle : G ≤ G') (v : V) : + G.neighborSet v ⊆ G'.neighborSet v := + fun _ hadj ↦ hle hadj + +@[simp] +theorem neighborSet_top : neighborSet ⊤ v = {v}ᶜ := by + grind [mem_neighborSet, top_adj] + +theorem neighborSet_bot : neighborSet ⊥ v = ∅ := by + grind [mem_neighborSet, bot_adj] + +variable {G} in +theorem Adj.nontrivial (hadj : G.Adj u v) : Nontrivial V := + ⟨u, v, hadj.ne⟩ + /-- The set of common neighbors between two vertices `v` and `w` in a graph `G` is the intersection of the neighbor sets of `v` and `w`. -/ def commonNeighbors (v w : V) : Set V := @@ -829,6 +858,10 @@ theorem commonNeighbors_top_eq {v w : V} : ext u simp [commonNeighbors, eq_comm, not_or] +@[simp] +theorem commonNeighbors_bot_eq : commonNeighbors ⊥ u v = ∅ := by + simp [commonNeighbors, neighborSet_bot] + section Incidence variable [DecidableEq V] @@ -916,4 +949,36 @@ attribute [simp] IsIsolated.neighborSet_eq_empty lemma mem_support_iff_not_isIsolated : v ∈ G.support ↔ ¬ G.IsIsolated v := by simp [mem_support, IsIsolated] +@[simp] +theorem notMem_support_iff_isIsolated : v ∉ G.support ↔ G.IsIsolated v := by + simp [mem_support_iff_not_isIsolated] + +variable {G} in +theorem exists_adj_iff_not_isIsolated : (∃ u, G.Adj v u) ↔ ¬G.IsIsolated v := by + simp [IsIsolated] + +@[simp] +theorem IsIsolated.of_subsingleton [Subsingleton V] (G : SimpleGraph V) (v : V) : + G.IsIsolated v := + fun _ hadj ↦ not_nontrivial V hadj.nontrivial + +variable {G} in +theorem nontrivial_of_not_isIsolated (h : ¬G.IsIsolated v) : Nontrivial V := + exists_adj_iff_not_isIsolated.mpr h |>.elim fun _ ↦ Adj.nontrivial + +variable {G} in +theorem Adj.not_isIsolated_left (h : G.Adj u v) : ¬G.IsIsolated u := + exists_adj_iff_not_isIsolated.mp ⟨_, h⟩ + +variable {G} in +theorem Adj.not_isIsolated_right (h : G.Adj u v) : ¬G.IsIsolated v := + h.symm.not_isIsolated_left + +@[simp] +theorem isIsolated_bot : IsIsolated ⊥ v := + neighborSet_eq_empty _ |>.mp neighborSet_bot + +theorem eq_bot_iff_isIsolated : G = ⊥ ↔ ∀ v, G.IsIsolated v := by + simp [eq_bot_iff_forall_not_adj, ← neighborSet_eq_empty, Set.eq_empty_iff_forall_notMem] + end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index 82242f1778d3ad..c5f2e356c5f83c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -233,22 +233,19 @@ theorem degree_pos_iff_mem_support : 0 < G.degree v ↔ v ∈ G.support := by theorem degree_eq_zero_iff_notMem_support : G.degree v = 0 ↔ v ∉ G.support := by rw [← G.degree_pos_iff_mem_support v, Nat.pos_iff_ne_zero, not_ne_iff] -@[simp] theorem degree_eq_zero_of_subsingleton {G : SimpleGraph V} (v : V) [Fintype (G.neighborSet v)] [Subsingleton V] : G.degree v = 0 := by - have := G.degree_pos_iff_exists_adj v - simp_all [subsingleton_iff_forall_eq v] + simp + +theorem nontrivial_of_degree_ne_zero {G : SimpleGraph V} {v : V} [Fintype (G.neighborSet v)] + (h : G.degree v ≠ 0) : Nontrivial V := + nontrivial_of_not_isIsolated <| G.degree_eq_zero v |>.not.mp h theorem degree_eq_one_iff_existsUnique_adj {G : SimpleGraph V} {v : V} [Fintype (G.neighborSet v)] : G.degree v = 1 ↔ ∃! w : V, G.Adj v w := by rw [degree, Finset.card_eq_one, Finset.singleton_iff_unique_mem] simp only [mem_neighborFinset] -theorem nontrivial_of_degree_ne_zero {G : SimpleGraph V} {v : V} [Fintype (G.neighborSet v)] - (h : G.degree v ≠ 0) : Nontrivial V := by - by_contra! - simp_all [degree_eq_zero_of_subsingleton] - theorem degree_compl [Fintype (Gᶜ.neighborSet v)] [Fintype V] : Gᶜ.degree v = Fintype.card V - 1 - G.degree v := by classical @@ -364,10 +361,8 @@ theorem complete_graph_degree [DecidableEq V] (v : V) : simp_rw [degree, neighborFinset_eq_filter, top_adj, filter_ne] rw [card_erase_of_mem (mem_univ v), card_univ] -@[simp] theorem bot_degree (v : V) : (⊥ : SimpleGraph V).degree v = 0 := by - simp_rw [degree, neighborFinset_eq_filter, bot_adj, filter_false] - exact Finset.card_empty + simp theorem IsRegularOfDegree.top [DecidableEq V] : (⊤ : SimpleGraph V).IsRegularOfDegree (Fintype.card V - 1) := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index 3fbde0b4f959eb..e2aec80aab3607 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -387,11 +387,6 @@ theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective repeat rw [Subtype.mk_eq_mk] apply Sym2.map.injective hinj -@[gcongr] -theorem _root_.SimpleGraph.neighborSet_mono (hle : G₁ ≤ G₂) (v : V) : - G₁.neighborSet v ⊆ G₂.neighborSet v := - subset_preimage_neighborSet v <| .ofLE hle - /-- Every graph homomorphism from a complete graph is injective. -/ theorem injective_of_top_hom (f : (⊤ : SimpleGraph V) →g G') : Function.Injective f := by intro v w h diff --git a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean index b65a73bf3cc8ee..bda19262960e8e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean +++ b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -64,7 +64,7 @@ theorem bot_strongly_regular : (⊥ : SimpleGraph V).IsSRGWith (Fintype.card V) of_not_adj v w _ := by simp only [card_eq_zero, Fintype.card_ofFinset, forall_true_left, not_false_iff, bot_adj] ext - simp [mem_commonNeighbors] + simp theorem IsSRGWith.ediam_eq_two [Nontrivial V] (h : G.IsSRGWith n k ℓ μ) (ht : G ≠ ⊤) (hm : μ ≠ 0) : G.ediam = 2 := by From fdfd7c5f4fbcd7a9e7102f59428c36ca6aed7e87 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:14:40 +0000 Subject: [PATCH 0031/1300] =?UTF-8?q?chore:=20replace=20:=3D=20=E2=86=90?= =?UTF-8?q?=20by=20=E2=86=90=20when=20possible=20(#40594)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minimize the diff on the upcoming mathlib bump, with the new do elaborator. --- Cache/Requests.lean | 4 ++-- Mathlib/Algebra/Order/BigOperators/Expect.lean | 2 +- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 2 +- Mathlib/Tactic/Algebra/Basic.lean | 2 +- Mathlib/Tactic/ComputeDegree.lean | 12 ++++++------ Mathlib/Tactic/DeprecateTo.lean | 2 +- Mathlib/Tactic/FieldSimp.lean | 4 ++-- Mathlib/Tactic/LinearCombination.lean | 2 +- Mathlib/Tactic/Linter/TextBased.lean | 4 ++-- Mathlib/Tactic/Module.lean | 2 +- Mathlib/Tactic/NormNum/Irrational.lean | 4 ++-- Mathlib/Tactic/NormNum/Pow.lean | 2 +- Mathlib/Tactic/Simps/Basic.lean | 2 +- Mathlib/Util/DischargerAsTactic.lean | 2 +- Mathlib/Util/GetAllModules.lean | 4 ++-- MathlibTest/ClickSuggestions/TestImpl.lean | 2 +- scripts/create_deprecated_modules.lean | 2 +- 17 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cache/Requests.lean b/Cache/Requests.lean index 8c9e156e4fe2f0..cca1dc42314b1c 100644 --- a/Cache/Requests.lean +++ b/Cache/Requests.lean @@ -669,7 +669,7 @@ def getFiles -- Skip when forceDownload is set, since downloadFiles will re-download (and pipeline-decompress) -- all files including already-cached ones, which would race with this background task. let bgDecomp ← if decompress && !forceDownload then - if let some plan := ← IO.prepareDecompConfig hashMap forceUnpack then + if let some plan ← IO.prepareDecompConfig hashMap forceUnpack then if plan.alreadyDecompressed > 0 then IO.println s!"Decompressing {plan.needsDecomp} already-cached file(s) \ ({plan.alreadyDecompressed} already decompressed)" @@ -702,7 +702,7 @@ def getFiles let mut failed : Nat := 0 for h : i in [0:repos.length] do - failed := ← downloadFiles repos[i] hashMap forceDownload parallel + failed ← downloadFiles repos[i] hashMap forceDownload parallel (warnOnMissing := i = repos.length - 1) (decompress := decompress) (forceUnpack := forceUnpack) isMathlibRoot mathlibDepPath diff --git a/Mathlib/Algebra/Order/BigOperators/Expect.lean b/Mathlib/Algebra/Order/BigOperators/Expect.lean index 440665a2a5d223..8f77dc667d84d0 100644 --- a/Mathlib/Algebra/Order/BigOperators/Expect.lean +++ b/Mathlib/Algebra/Order/BigOperators/Expect.lean @@ -226,7 +226,7 @@ meta def evalFinsetExpect : PositivityExt where eval {u α} zα pα e := do let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque have body : Q($α) := .betaRev f #[i] let rbody ← core zα pα body - let p_pos : Option Q(0 < $e) := ← (do + let p_pos : Option Q(0 < $e) ← (do let .positive pbody := rbody | pure none -- Fail if the body is not provably positive let some ps ← proveFinsetNonempty s | pure none let .some pα' ← trySynthInstanceQ q(IsOrderedCancelAddMonoid $α) | pure none diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 004b5bfaf977e8..9836ea7f5a2ede 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -133,7 +133,7 @@ meta def EuclideanSpace.delabVecNotation : Delab := let p : Term ← withNaryArg 0 <| delab -- to be conservative, only allow subscripts which are numerals guard <| p matches `($_:num) - let `(![$elems,*]) := ← withNaryArg 2 delab | failure + let `(![$elems,*]) ← withNaryArg 2 delab | failure `(!$p[$elems,*]) end Notation diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index 37d55dfd2eb81c..1af2eff93f1afd 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -128,7 +128,7 @@ def evalCast (cR : Algebra.Cache q($sR)) (cA : Algebra.Cache q($sA)): into casts. -/ def pushCast (e : Expr) : MetaM Simp.Result := do -- collect the available `push_cast` lemmas - let mut thms : SimpTheorems := ← NormCast.pushCastExt.getTheorems + let mut thms : SimpTheorems ← NormCast.pushCastExt.getTheorems let simps : Array Name := #[``eq_natCast, ``eq_intCast, ``eq_ratCast] for thm in simps do let ⟨levelParams, _, proof⟩ ← abstractMVars (mkConst thm) diff --git a/Mathlib/Tactic/ComputeDegree.lean b/Mathlib/Tactic/ComputeDegree.lean index d00e44bfc8e562..aad91fcb2100ef 100644 --- a/Mathlib/Tactic/ComputeDegree.lean +++ b/Mathlib/Tactic/ComputeDegree.lean @@ -379,11 +379,11 @@ It returns the list of `MVarId`s, beginning with the ones that initially involve metavariables followed by the rest. -/ def tryRfl (mvs : List MVarId) : MetaM (List MVarId) := do - let (yesMV, noMV) := ← mvs.partitionM fun mv => + let (yesMV, noMV) ← mvs.partitionM fun mv => return hasExprMVar (← instantiateMVars (← mv.getDecl).type) - let tried_rfl := ← noMV.mapM fun g => g.applyConst ``rfl <|> return [g] - let assignable := ← yesMV.mapM fun g => do - let tgt := ← instantiateMVars (← g.getDecl).type + let tried_rfl ← noMV.mapM fun g => g.applyConst ``rfl <|> return [g] + let assignable ← yesMV.mapM fun g => do + let tgt ← instantiateMVars (← g.getDecl).type match tgt.eq? with | some (_, lhs, rhs) => if (isMVar rhs && (! hasExprMVar lhs)) || @@ -407,9 +407,9 @@ lemma and returns two lists: the left-over goals of all the applications, follow concatenation of the previous `static` list, followed by the newly discovered goals outside of the scope of `compute_degree`. -/ def splitApply (mvs static : List MVarId) : MetaM ((List MVarId) × (List MVarId)) := do - let (can_progress, curr_static) := ← mvs.partitionM fun mv => do + let (can_progress, curr_static) ← mvs.partitionM fun mv => do return dispatchLemma (twoHeadsArgs (← mv.getType'')) != ``id - let progress := ← can_progress.mapM fun mv => do + let progress ← can_progress.mapM fun mv => do let lem := dispatchLemma <| twoHeadsArgs (← mv.getType'') mv.applyConst <| lem return (progress.flatten, static ++ curr_static) diff --git a/Mathlib/Tactic/DeprecateTo.lean b/Mathlib/Tactic/DeprecateTo.lean index 975dbb7fcf67a9..6c4805d681021e 100644 --- a/Mathlib/Tactic/DeprecateTo.lean +++ b/Mathlib/Tactic/DeprecateTo.lean @@ -129,7 +129,7 @@ elab tk:"deprecate" "to" id:ident* dat:(ppSpace str ppSpace)? ppLine cmd:command for i in id.toList.drop news.size do logErrorAt i "" warn := warn.push s!"Unused names: {id.toList.drop news.size}" let (oldId, newCmd) := renameTheorem id[0]! cmd - let oldNames := ← resolveGlobalName (oldId.raw.getArg 0).getId.eraseMacroScopes + let oldNames ← resolveGlobalName (oldId.raw.getArg 0).getId.eraseMacroScopes let fil := news.filter fun n => n.toString.endsWith oldNames[0]!.1.toString if fil.size != 1 && oldId != default then logError m!"Expected to find one declaration called {oldNames[0]!.1}, found {fil.size}" diff --git a/Mathlib/Tactic/FieldSimp.lean b/Mathlib/Tactic/FieldSimp.lean index a7bea5f1a206ce..4848295ba6a635 100644 --- a/Mathlib/Tactic/FieldSimp.lean +++ b/Mathlib/Tactic/FieldSimp.lean @@ -433,7 +433,7 @@ partial def normalize (disch : ∀ {u : Level} (type : Q(Sort u)), MetaM Q($type let ⟨y₂, ⟨g₂, pf₂_sgn⟩, l₂, pf₂⟩ ← normalize disch iM x₂ -- build the new list and proof have pf := qNF.mkMulProof iM l₁ l₂ - let ⟨G, pf_y⟩ := ← Sign.mul iM y₁ y₂ g₁ g₂ + let ⟨G, pf_y⟩ ← Sign.mul iM y₁ y₂ g₁ g₂ pure ⟨q($y₁ * $y₂), ⟨G, q(Eq.trans (congr_arg₂ HMul.hMul $pf₁_sgn $pf₂_sgn) $pf_y)⟩, qNF.mul l₁ l₂, q(NF.mul_eq_eval $pf₁ $pf₂ $pf)⟩ /- normalize a division: `x₁ / x₂` -/ @@ -442,7 +442,7 @@ partial def normalize (disch : ∀ {u : Level} (type : Q(Sort u)), MetaM Q($type let ⟨y₂, ⟨g₂, pf₂_sgn⟩, l₂, pf₂⟩ ← normalize disch iM x₂ -- build the new list and proof let pf := qNF.mkDivProof iM l₁ l₂ - let ⟨G, pf_y⟩ := ← Sign.div iM y₁ y₂ g₁ g₂ + let ⟨G, pf_y⟩ ← Sign.div iM y₁ y₂ g₁ g₂ pure ⟨q($y₁ / $y₂), ⟨G, q(Eq.trans (congr_arg₂ HDiv.hDiv $pf₁_sgn $pf₂_sgn) $pf_y)⟩, qNF.div l₁ l₂, q(NF.div_eq_eval $pf₁ $pf₂ $pf)⟩ /- normalize an inversion: `y⁻¹` -/ diff --git a/Mathlib/Tactic/LinearCombination.lean b/Mathlib/Tactic/LinearCombination.lean index d3a1453f64453c..f6d218b9c8661e 100644 --- a/Mathlib/Tactic/LinearCombination.lean +++ b/Mathlib/Tactic/LinearCombination.lean @@ -171,7 +171,7 @@ def elabLinearCombination (tk : Syntax) Prod.mk eq <$> `(Eq.refl 0) | .proof hypRel p => pure (hypRel, p) -- look up the lemma for the central `refine` in `linear_combination` - let (reduceLem, newGoalRel) : Name × Ineq := ← do + let (reduceLem, newGoalRel) : Name × Ineq ← do match Ineq.relImpRelData hypRel goalRel with | none => throwError "cannot prove an equality from inequality hypotheses" | some n => pure n diff --git a/Mathlib/Tactic/Linter/TextBased.lean b/Mathlib/Tactic/Linter/TextBased.lean index f22c1d62769539..e88d6761db1ec3 100644 --- a/Mathlib/Tactic/Linter/TextBased.lean +++ b/Mathlib/Tactic/Linter/TextBased.lean @@ -526,10 +526,10 @@ def lintModules (opts : LinterOptions) (nolints : Array String) (moduleNames : A -- Convert the module name to a file name, then lint that file. let path := mkFilePath (module.components.map toString)|>.addExtension "lean" - let (errors, changed) := ← lintFile opts path styleExceptions + let (errors, changed) ← lintFile opts path styleExceptions if let some c := changed then if fix then - let _ := ← IO.FS.writeFile path ("\n".intercalate c.toList) + let _ ← IO.FS.writeFile path ("\n".intercalate c.toList) if errors.size > 0 then allUnexpectedErrors := allUnexpectedErrors.append errors numberErrorFiles := numberErrorFiles + 1 diff --git a/Mathlib/Tactic/Module.lean b/Mathlib/Tactic/Module.lean index ea19a03a9a39ae..dd5d1b1bc065b4 100644 --- a/Mathlib/Tactic/Module.lean +++ b/Mathlib/Tactic/Module.lean @@ -571,7 +571,7 @@ most commonly occurring `algebraMap`s (those out of `ℕ`, `ℤ` and `ℚ`) into (`ℕ`, `ℤ` and `ℚ` casts) and then try to disperse the casts using the various `push_cast` lemmas. -/ def postprocess (mvarId : MVarId) : MetaM MVarId := do -- collect the available `push_cast` lemmas - let mut thms : SimpTheorems := ← NormCast.pushCastExt.getTheorems + let mut thms : SimpTheorems ← NormCast.pushCastExt.getTheorems -- augment this list with the `algebraMapThms` lemmas, which handle `algebraMap` operations for thm in algebraMapThms do let ⟨levelParams, _, proof⟩ ← abstractMVars (mkConst thm) diff --git a/Mathlib/Tactic/NormNum/Irrational.lean b/Mathlib/Tactic/NormNum/Irrational.lean index 13cb6cc4ebdfad..8528c4739b4e17 100644 --- a/Mathlib/Tactic/NormNum/Irrational.lean +++ b/Mathlib/Tactic/NormNum/Irrational.lean @@ -248,8 +248,8 @@ def findNotPowerCertificateCore (m n : ℕ) : Option ℕ := Id.run do /-- Finds `NotPowerCertificate` showing that `m` is not `n`-power. -/ def findNotPowerCertificate (m n : Q(ℕ)) : MetaM (NotPowerCertificate m n) := do - let .isNat (_ : Q(AddMonoidWithOne ℕ)) m _ := ← derive m | failure - let .isNat (_ : Q(AddMonoidWithOne ℕ)) n _ := ← derive n | failure + let .isNat (_ : Q(AddMonoidWithOne ℕ)) m _ ← derive m | failure + let .isNat (_ : Q(AddMonoidWithOne ℕ)) n _ ← derive n | failure let mVal := m.natLit! let nVal := n.natLit! let some k := findNotPowerCertificateCore mVal nVal | failure diff --git a/Mathlib/Tactic/NormNum/Pow.lean b/Mathlib/Tactic/NormNum/Pow.lean index 2151187c30aec5..a05e9b46eee0ea 100644 --- a/Mathlib/Tactic/NormNum/Pow.lean +++ b/Mathlib/Tactic/NormNum/Pow.lean @@ -137,7 +137,7 @@ partial def evalIntPow (za : ℤ) (a : Q(ℤ)) (b : Q(ℕ)) : have : $a =Q .negOfNat $a' := ⟨⟩ let b' := b.natLit! have b₀ : Q(ℕ) := mkRawNatLit (b' >>> 1) - let ⟨c₀, p⟩ := ← evalNatPow a' b₀ + let ⟨c₀, p⟩ ← evalNatPow a' b₀ let c' := c₀.natLit! if b' &&& 1 == 0 then have c : Q(ℕ) := mkRawNatLit (c' * c') diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index e9917bf5a80fcb..91bd1091d93821 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -756,7 +756,7 @@ def findAutomaticProjections (str : Name) (projs : Array ParsedProjectionData) : MetaM.run' <| TermElabM.run' (s := {levelNames := strDecl.levelParams}) <| forallTelescope strDecl.type fun args _ ↦ do let projs ← projs.mapM fun proj => do - if let some (projExpr, projName) := ← findAutomaticProjectionsAux str proj args then + if let some (projExpr, projName) ← findAutomaticProjectionsAux str proj args then unless ← isDefEq projExpr proj.expr?.get! do throwError "The projection {proj.newName} is not definitionally equal to an application \ of {projName}:{indentExpr proj.expr?.get!}\nvs{indentExpr projExpr}" diff --git a/Mathlib/Util/DischargerAsTactic.lean b/Mathlib/Util/DischargerAsTactic.lean index 131473e5c45d2a..a6be9961ee49d7 100644 --- a/Mathlib/Util/DischargerAsTactic.lean +++ b/Mathlib/Util/DischargerAsTactic.lean @@ -25,7 +25,7 @@ so that it can be passed as an argument to `simp (discharger := foo)`. This is inverse to `mkDischargeWrapper`. -/ def wrapSimpDischarger (dis : Simp.Discharge) : TacticM Unit := do let eS : Lean.Meta.Simp.State := {} - let eC : Lean.Meta.Simp.Context := ← Simp.mkContext {} + let eC : Lean.Meta.Simp.Context ← Simp.mkContext {} let eM : Lean.Meta.Simp.Methods := {} let (some a, _) ← liftM <| StateRefT'.run (ReaderT.run (ReaderT.run (dis <| ← getMainTarget) eM.toMethodsRef) eC) eS | failure diff --git a/Mathlib/Util/GetAllModules.lean b/Mathlib/Util/GetAllModules.lean index da4f4e51be49b0..5da0463be9851c 100644 --- a/Mathlib/Util/GetAllModules.lean +++ b/Mathlib/Util/GetAllModules.lean @@ -53,6 +53,6 @@ i.e. names of the form `Mathlib/Algebra/Algebra/Basic.lean`. In addition, these names are sorted in a platform-independent order. -/ def getAllModulesSorted (git : Bool) (ml : String) : IO (Array String) := do let files ← getAllFiles git ml - let names := ← files.mapM fun f => do - return (← moduleNameOfFileName f none).toString + let names ← files.mapM fun f => do + return (← moduleNameOfFileName f none).toString return names.qsort (· < ·) diff --git a/MathlibTest/ClickSuggestions/TestImpl.lean b/MathlibTest/ClickSuggestions/TestImpl.lean index 244a3cfee64c49..67db395e1ee068 100644 --- a/MathlibTest/ClickSuggestions/TestImpl.lean +++ b/MathlibTest/ClickSuggestions/TestImpl.lean @@ -67,7 +67,7 @@ elab "click_test" onGoal?:(num)? hyp?:(ident)? pos?:(str)? "=>" expecteds:str+ : | .ok pos => return pos | .error s => throwError "{s}" let expecteds := expecteds.map (·.getString) - let loc : GoalLocation := ← match hyp?, pos? with + let loc : GoalLocation ← match hyp?, pos? with | some h, some pos => pure <| .hypType h pos | none , some pos => pure <| .target pos | some h, none => pure <| .hyp h diff --git a/scripts/create_deprecated_modules.lean b/scripts/create_deprecated_modules.lean index 2bcfc4ece90828..31705550029ad0 100644 --- a/scripts/create_deprecated_modules.lean +++ b/scripts/create_deprecated_modules.lean @@ -233,7 +233,7 @@ def deprecateFilePath (fname : String) (rename comment : Option String) : -- Retrieve the final version of the file, before it was deleted. let file ← runCmd s!"git show {modifiedHash}:{fname}" -- Generate a module deprecation for the file `fname`. - let fileHeader := ← match rename with + let fileHeader ← match rename with | some rename => do let modName := mkModName rename pure s!"import {modName}" From a76f26fe763efc700df79ccc628133be56dc378d Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Sun, 14 Jun 2026 20:07:23 +0000 Subject: [PATCH 0032/1300] doc: add wikidata attributes (#40440) This PR adds a batch of 25 `@[wikidata]` attributes. Follows the same template as #40004. Claude helped generate the list of crossrefs (by scanning Wikidata + Mathlib) and then wrote each of the `@[wikidata]` tags. Comments were generated by [Johan's script](https://github.com/jcommelin/mathlib-crossref-report) (Thanks Snir Broshi for telling me about this!) I manually verified all of the cross refs for mathematical correctness, and made sure they're attached to the appropriate declaration. --- Mathlib/Algebra/Group/Defs.lean | 2 +- Mathlib/Algebra/Polynomial/Basic.lean | 1 + Mathlib/Algebra/Ring/Defs.lean | 1 + Mathlib/Analysis/Complex/Exponential.lean | 2 +- Mathlib/Analysis/Distribution/Distribution.lean | 1 + Mathlib/Analysis/Fourier/LpSpace.lean | 1 + Mathlib/Analysis/SpecialFunctions/Log/Basic.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean | 1 + Mathlib/Computability/Partrec.lean | 1 + Mathlib/Data/Int/ModEq.lean | 1 + Mathlib/Data/Nat/Factorial/Basic.lean | 2 ++ Mathlib/Data/Nat/Prime/Defs.lean | 2 +- Mathlib/Geometry/Euclidean/Angle/Unoriented/Basic.lean | 1 + Mathlib/Geometry/Manifold/IsManifold/Basic.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean | 1 + Mathlib/NumberTheory/NumberField/Basic.lean | 2 +- Mathlib/Order/RelClasses.lean | 2 ++ Mathlib/Probability/Moments/Variance.lean | 1 + Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean | 1 + Mathlib/SetTheory/Cardinal/Defs.lean | 3 ++- Mathlib/SetTheory/Ordinal/Basic.lean | 2 +- Mathlib/Topology/Connected/Basic.lean | 1 + Mathlib/Topology/Defs/Filter.lean | 1 + Mathlib/Topology/Homotopy/Basic.lean | 1 + Mathlib/Topology/MetricSpace/Defs.lean | 1 + 25 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index d7e8c24a4763d8..8da0e62370f626 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -1276,7 +1276,7 @@ class AddCommGroup (G : Type u) extends AddGroup G, AddCommMonoid G /-- A commutative group is a group with commutative `(*)`. -/ -- There is intentionally no `IsMulCommutative` for `CommGroup` instance for performance reasons. -@[to_additive] +@[to_additive (attr := wikidata Q181296)] class CommGroup (G : Type u) extends Group G, CommMonoid G section CommGroup diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index c6cc31c85d43e6..bedc15cd7f6966 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -68,6 +68,7 @@ denoted as `R[X]` within the `Polynomial` namespace. Polynomials should be seen as (semi-)rings with the additional constructor `X`. The embedding from `R` is called `C`. -/ +@[wikidata Q43260] structure Polynomial (R : Type*) [Semiring R] where ofFinsupp :: /-- The coefficients `ℕ →₀ R` of a polynomial in `R[X]`. -/ toFinsupp : AddMonoidAlgebra R ℕ diff --git a/Mathlib/Algebra/Ring/Defs.lean b/Mathlib/Algebra/Ring/Defs.lean index 0ff309f0832c35..5bcb9b4e73ec77 100644 --- a/Mathlib/Algebra/Ring/Defs.lean +++ b/Mathlib/Algebra/Ring/Defs.lean @@ -411,6 +411,7 @@ instance (priority := 100) NonUnitalCommRing.toNonUnitalCommSemiring [s : NonUni { s with } /-- A commutative ring is a ring with commutative multiplication. -/ +@[wikidata Q858656] class CommRing (α : Type u) extends Ring α, CommMonoid α instance (priority := 100) CommRing.toNonAssocCommRing [CommRing α] : NonAssocCommRing α where diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index 4fbc28c76c4d3e..58e394719d257c 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -76,7 +76,7 @@ open Complex noncomputable section /-- The real exponential function, defined as the real part of the complex exponential -/ -@[pp_nodot] +@[pp_nodot, wikidata Q168698] nonrec def exp (x : ℝ) : ℝ := (exp x).re diff --git a/Mathlib/Analysis/Distribution/Distribution.lean b/Mathlib/Analysis/Distribution/Distribution.lean index edc44da2dcf9ff..a9731fcfaa4774 100644 --- a/Mathlib/Analysis/Distribution/Distribution.lean +++ b/Mathlib/Analysis/Distribution/Distribution.lean @@ -192,6 +192,7 @@ end mapCLM section DiracDelta /-- The Dirac delta distribution. This is zero if `x` does not belong to `Ω`. -/ +@[wikidata Q209675] noncomputable def delta (x : E) : 𝓓'^{n}(Ω, ℝ) where toFun f := f x map_add' _ _ := rfl diff --git a/Mathlib/Analysis/Fourier/LpSpace.lean b/Mathlib/Analysis/Fourier/LpSpace.lean index 702a38dd177a69..5475d647eb65ba 100644 --- a/Mathlib/Analysis/Fourier/LpSpace.lean +++ b/Mathlib/Analysis/Fourier/LpSpace.lean @@ -46,6 +46,7 @@ namespace MeasureTheory.Lp variable (E F) in /-- The Fourier transform on `L2` as a linear isometry equivalence. -/ +@[wikidata Q6520159] def fourierTransformₗᵢ : (Lp (α := E) F 2) ≃ₗᵢ[ℂ] (Lp (α := E) F 2) := (fourierEquiv ℂ 𝓢(E, F)).extendOfIsometry (toLpCLM ℂ (E := E) F 2 volume) (toLpCLM ℂ (E := E) F 2 volume) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index ab6a43aa827bb2..f64147755f1c5c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -40,7 +40,7 @@ variable {x y : ℝ} to `log |x|` for `x < 0`, and to `0` for `0`. We use this unconventional extension to `(-∞, 0]` as it gives the formula `log (x * y) = log x + log y` for all nonzero `x` and `y`, and the derivative of `log` is `1/x` away from `0`. -/ -@[pp_nodot] +@[pp_nodot, wikidata Q11197] noncomputable def log (x : ℝ) : ℝ := if hx : x = 0 then 0 else expOrderIso.symm ⟨|x|, abs_pos.2 hx⟩ diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean index fe5091bdf1e323..f673be94a073fd 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean @@ -123,6 +123,7 @@ from which one can derive all its properties. For explicit bounds on π, see `Mathlib/Analysis/Real/Pi/Bounds.lean`. Denoted `π`, once the `Real` namespace is opened. -/ +@[wikidata Q167] protected noncomputable def pi : ℝ := 2 * Classical.choose exists_cos_eq_zero diff --git a/Mathlib/Computability/Partrec.lean b/Mathlib/Computability/Partrec.lean index 43697b6b771a02..f73cb614714702 100644 --- a/Mathlib/Computability/Partrec.lean +++ b/Mathlib/Computability/Partrec.lean @@ -236,6 +236,7 @@ def Partrec₂ {α β σ} [Primcodable α] [Primcodable β] [Primcodable σ] (f /-- Computable functions `α → σ` between `Primcodable` types: a function is computable if and only if it is partially recursive (as a partial function) -/ +@[wikidata Q1148456] def Computable {α σ} [Primcodable α] [Primcodable σ] (f : α → σ) := Partrec (f : α →. σ) diff --git a/Mathlib/Data/Int/ModEq.lean b/Mathlib/Data/Int/ModEq.lean index 5a8cb427cd8b0b..2af03e37ca02ab 100644 --- a/Mathlib/Data/Int/ModEq.lean +++ b/Mathlib/Data/Int/ModEq.lean @@ -26,6 +26,7 @@ modeq, congruence, mod, MOD, modulo, integers /-- `a ≡ b [ZMOD n]` when `a % n = b % n`. -/ +@[wikidata Q3773677] def Int.ModEq (n a b : ℤ) := a % n = b % n diff --git a/Mathlib/Data/Nat/Factorial/Basic.lean b/Mathlib/Data/Nat/Factorial/Basic.lean index aebc402568578f..4a434c8b88ebfa 100644 --- a/Mathlib/Data/Nat/Factorial/Basic.lean +++ b/Mathlib/Data/Nat/Factorial/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.Nat.Basic public import Mathlib.Tactic.Common +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.Monotonicity.Attr /-! @@ -31,6 +32,7 @@ see `Fintype.card_perm`. namespace Nat /-- `Nat.factorial n` is the factorial of `n`. -/ +@[wikidata Q120976] def factorial : ℕ → ℕ | 0 => 1 | succ n => succ n * factorial n diff --git a/Mathlib/Data/Nat/Prime/Defs.lean b/Mathlib/Data/Nat/Prime/Defs.lean index 4c6a3aa35c4fb2..852308e4137880 100644 --- a/Mathlib/Data/Nat/Prime/Defs.lean +++ b/Mathlib/Data/Nat/Prime/Defs.lean @@ -38,7 +38,7 @@ variable {n : ℕ} /-- `Nat.Prime p` means that `p` is a prime number, that is, a natural number at least 2 whose only divisors are `p` and `1`. The theorem `Nat.prime_def` witnesses this description of a prime number. -/ -@[pp_nodot] +@[pp_nodot, wikidata Q49008] def Prime (p : ℕ) := Irreducible p diff --git a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Basic.lean b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Basic.lean index aef62d15dfab1d..a63db76cb04807 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Basic.lean @@ -37,6 +37,7 @@ variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V] {x y : V} /-- The undirected angle between two vectors. If either vector is 0, this is π/2. See `Orientation.oangle` for the corresponding oriented angle definition. -/ +@[wikidata Q11352] def angle (x y : V) : ℝ := Real.arccos (⟪x, y⟫ / (‖x‖ * ‖y‖)) diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index b3a41ea3b8d56c..79619e7d1384c9 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -1037,7 +1037,7 @@ set_option linter.unusedVariables false in The definition of `TangentSpace` is not reducible so that type class inference does not pick wrong instances. -/ -@[nolint unusedArguments] +@[nolint unusedArguments, wikidata Q909601] def TangentSpace {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type u} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean index bb576bab423ae3..87b6da663393c1 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean @@ -56,6 +56,7 @@ def detRowAlternating : (n → R) [⋀^n]→ₗ[R] R := MultilinearMap.alternatization ((MultilinearMap.mkPiAlgebra R n R).compLinearMap LinearMap.proj) /-- The determinant of a matrix given by the Leibniz formula. -/ +@[wikidata Q178546] def det (M : Matrix n n R) : R := detRowAlternating M diff --git a/Mathlib/NumberTheory/NumberField/Basic.lean b/Mathlib/NumberTheory/NumberField/Basic.lean index 14a4d13f5d746f..c9e3ddec84ca4b 100644 --- a/Mathlib/NumberTheory/NumberField/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Basic.lean @@ -38,7 +38,7 @@ number field, ring of integers /-- A number field is a field which has characteristic zero and is finite dimensional over ℚ. -/ -@[stacks 09GA] +@[stacks 09GA, wikidata Q616608] class NumberField (K : Type*) [Field K] : Prop where [to_charZero : CharZero K] [to_finiteDimensional : FiniteDimensional ℚ K] diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index d91f6c50cd389b..63bc0a93b2ab8d 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -7,6 +7,7 @@ module public import Mathlib.Logic.IsEmpty.Basic public import Mathlib.Order.OrderDual +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.MkIffOfInductiveProp /-! @@ -266,6 +267,7 @@ theorem wellFoundedGT_dual_iff (α : Type*) [LT α] : WellFoundedGT αᵒᵈ ↔ ⟨fun h => ⟨h.wf⟩, fun h => ⟨h.wf⟩⟩ /-- A well order is a well-founded linear order. -/ +@[wikidata Q659746] class IsWellOrder (α : Type u) (r : α → α → Prop) : Prop extends IsWellFounded α r, Std.Trichotomous r diff --git a/Mathlib/Probability/Moments/Variance.lean b/Mathlib/Probability/Moments/Variance.lean index 790187496a04c3..c5b09a75a54bd2 100644 --- a/Mathlib/Probability/Moments/Variance.lean +++ b/Mathlib/Probability/Moments/Variance.lean @@ -60,6 +60,7 @@ def evariance : ℝ≥0∞ := ∫⁻ ω, ‖X ω - μ[X]‖ₑ ^ 2 ∂μ variable (X μ) in /-- The `ℝ`-valued variance of a real-valued random variable defined by applying `ENNReal.toReal` to `evariance`. -/ +@[wikidata Q175199] def variance : ℝ := (evariance X μ).toReal /-- The `ℝ≥0∞`-valued variance of the real-valued random variable `X` according to the measure `μ`. diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean index 7daf0c1328c12e..945495351dc27f 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean @@ -31,6 +31,7 @@ variable [Preorder α] variable (α) in /-- The cofinality of a preorder is the smallest cardinality of a cofinal subset. -/ +@[wikidata Q1283623] def cof : Cardinal := ⨅ s : {s : Set α // IsCofinal s}, #s diff --git a/Mathlib/SetTheory/Cardinal/Defs.lean b/Mathlib/SetTheory/Cardinal/Defs.lean index a169cf2dc00fa0..7889e0f375c920 100644 --- a/Mathlib/SetTheory/Cardinal/Defs.lean +++ b/Mathlib/SetTheory/Cardinal/Defs.lean @@ -6,6 +6,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Floris van Doorn module public import Mathlib.Data.ULift +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.PPWithUniv public import Mathlib.Util.Delaborators @@ -76,7 +77,7 @@ instance Cardinal.isEquivalent : Setoid (Type u) where /-- `Cardinal.{u}` is the type of cardinal numbers in `Type u`, defined as the quotient of `Type u` by existence of an equivalence (a bijection with explicit inverse). -/ -@[pp_with_univ] +@[pp_with_univ, wikidata Q163875] def Cardinal : Type (u + 1) := Quotient Cardinal.isEquivalent diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 1f3663a02c95f3..d5641068269f63 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -101,7 +101,7 @@ instance Ordinal.isEquivalent : Setoid WellOrder where ⟨fun _ => ⟨RelIso.refl _⟩, fun ⟨e⟩ => ⟨e.symm⟩, fun ⟨e₁⟩ ⟨e₂⟩ => ⟨e₁.trans e₂⟩⟩ /-- `Ordinal.{u}` is the type of well orders in `Type u`, up to order isomorphism. -/ -@[pp_with_univ] +@[pp_with_univ, wikidata Q191780] def Ordinal : Type (u + 1) := Quotient Ordinal.isEquivalent diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index c8b1080eac1bca..6d2c298d792167 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -649,6 +649,7 @@ class PreconnectedSpace (α : Type u) [TopologicalSpace α] : Prop where export PreconnectedSpace (isPreconnected_univ) /-- A connected space is a nonempty one where there is no non-trivial open partition. -/ +@[wikidata Q1491995] class ConnectedSpace (α : Type u) [TopologicalSpace α] : Prop extends PreconnectedSpace α where /-- A connected space is nonempty. -/ toNonempty : Nonempty α diff --git a/Mathlib/Topology/Defs/Filter.lean b/Mathlib/Topology/Defs/Filter.lean index 7b96de027f3295..9dadbcb88ff98e 100644 --- a/Mathlib/Topology/Defs/Filter.lean +++ b/Mathlib/Topology/Defs/Filter.lean @@ -279,6 +279,7 @@ def IsCompact (s : Set X) := variable (X) in /-- Type class for compact spaces. Separation is sometimes included in the definition, especially in the French literature, but we do not include it here. -/ +@[wikidata Q381892] class CompactSpace : Prop where /-- In a compact space, `Set.univ` is a compact set. -/ isCompact_univ : IsCompact (Set.univ : Set X) diff --git a/Mathlib/Topology/Homotopy/Basic.lean b/Mathlib/Topology/Homotopy/Basic.lean index 80f21dab4daeed..fdebd05ecd645e 100644 --- a/Mathlib/Topology/Homotopy/Basic.lean +++ b/Mathlib/Topology/Homotopy/Basic.lean @@ -73,6 +73,7 @@ When possible, instead of parametrizing results over `(f : ContinuousMap.Homotop you should parametrize over `{F : Type*} [HomotopyLike F f₀ f₁] (f : F)`. When you extend this structure, make sure to extend `ContinuousMap.HomotopyLike`. -/ +@[wikidata Q746083] structure Homotopy (f₀ f₁ : C(X, Y)) extends C(I × X, Y) where /-- value of the homotopy at 0 -/ map_zero_left : ∀ x, toFun (0, x) = f₀ x diff --git a/Mathlib/Topology/MetricSpace/Defs.lean b/Mathlib/Topology/MetricSpace/Defs.lean index ab9838b78440c5..e580baef4437d1 100644 --- a/Mathlib/Topology/MetricSpace/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Defs.lean @@ -66,6 +66,7 @@ This e.g. ensures that we do not get a diamond when doing `[MetricSpace α] [MetricSpace β] : TopologicalSpace (α × β)`: The product metric and product topology agree, but not definitionally so. See Note [forgetful inheritance]. -/ +@[wikidata Q180953] class MetricSpace (α : Type u) : Type u extends PseudoMetricSpace α where eq_of_dist_eq_zero : ∀ {x y : α}, dist x y = 0 → x = y From 26a595e71188b7f8cfc013bd4cf0d5b3d7469993 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Sun, 14 Jun 2026 20:07:25 +0000 Subject: [PATCH 0033/1300] doc(SimpleGraph): fix incorrect theorem/instance names (#40596) Taken from this [Zulip thread.](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.22Main.20declarations.22.20which.20do.20not.20exist/with/602887714) --- Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Subgraph.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Tutte.lean | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean b/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean index fc01f89848f26f..5e901085b73c54 100644 --- a/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean +++ b/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean @@ -24,7 +24,7 @@ case. * `SimpleGraph.deleteIncidenceSet G v` is the simple graph `G` with the incidence set of `v` removed from the edge set. -* `SimpleGraph.deleteFar G p r` is the predicate that a graph is `r`-*delete-far* from a property +* `SimpleGraph.DeleteFar G p r` is the predicate that a graph is `r`-*delete-far* from a property `p`, that is, at least `r` edges must be deleted to satisfy `p`. -/ diff --git a/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean b/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean index 736609b3af813f..ee5bd217f3925c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean +++ b/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean @@ -19,7 +19,7 @@ This module defines the Laplacian matrix of a graph, and proves some of its elem * `SimpleGraph.degMatrix`: The degree matrix of a simple graph * `SimpleGraph.lapMatrix`: The Laplacian matrix of a simple graph, defined as the difference between the degree matrix and the adjacency matrix. -* `isPosSemidef_lapMatrix`: The Laplacian matrix is positive semidefinite. +* `posSemidef_lapMatrix`: The Laplacian matrix is positive semidefinite. * `card_connectedComponent_eq_finrank_ker_toLin'_lapMatrix`: The number of connected components in a graph is the dimension of the nullspace of its Laplacian matrix. diff --git a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean index 34b7f8f96a0cc0..bc9ccfecd07846 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean @@ -28,7 +28,7 @@ sub-relation of the adjacency relation of the simple graph. * `Subgraph.IsSpanning` for whether a subgraph is a spanning subgraph and `Subgraph.IsInduced` for whether a subgraph is an induced subgraph. -* Instances for `Lattice (Subgraph G)` and `BoundedOrder (Subgraph G)`. +* Instances for `DistribLattice G.Subgraph` and `BoundedOrder (Subgraph G)`. * `SimpleGraph.toSubgraph`: If a `SimpleGraph` is a subgraph of another, then you can turn it into a member of the larger graph's `SimpleGraph.Subgraph` type. diff --git a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean index 8e8cad783bda75..e905473f5226e5 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean @@ -16,7 +16,7 @@ public import Mathlib.Data.Fintype.Card ## Main definitions -* `SimpleGraph.TutteViolator G u` is a set of vertices `u` such that the amount of +* `SimpleGraph.IsTutteViolator G u` is a set of vertices `u` such that the amount of odd components left after deleting `u` from `G` is larger than the number of vertices in `u`. This certifies non-existence of a perfect matching. From 439c664b0475c29168b177bc60839c7549e5d894 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:50:38 +0000 Subject: [PATCH 0034/1300] chore(Counterexamples/DirectSumIsInternal): fix defLemma error (#40592) As could be seen from running #lint in that file. The new `defProp` linter in Lean core also flagged this. --- Counterexamples/DirectSumIsInternal.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Counterexamples/DirectSumIsInternal.lean b/Counterexamples/DirectSumIsInternal.lean index c0f2aff71c4e92..c46125e7464b48 100644 --- a/Counterexamples/DirectSumIsInternal.lean +++ b/Counterexamples/DirectSumIsInternal.lean @@ -19,7 +19,6 @@ This file demonstrates why `DirectSum.isInternal_submodule_of_iSupIndep_of_iSup_ take `Ring R` and not `Semiring R`. -/ - namespace Counterexample theorem UnitsInt.one_ne_neg_one : (1 : ℤˣ) ≠ -1 := by decide @@ -57,9 +56,8 @@ theorem withSign.isCompl : IsCompl ℤ≥0 ℤ≤0 := by · exact Submodule.mem_sup_left (mem_withSign_one.mpr hp) · exact Submodule.mem_sup_right (mem_withSign_neg_one.mpr hn) -def withSign.independent : iSupIndep withSign := by - apply - (iSupIndep_pair UnitsInt.one_ne_neg_one _).mpr withSign.isCompl.disjoint +lemma withSign.independent : iSupIndep withSign := by + apply (iSupIndep_pair UnitsInt.one_ne_neg_one _).mpr withSign.isCompl.disjoint intro i fin_cases i <;> simp From 261b5e314a7e71cff47a151b610fa834b3e6a7ae Mon Sep 17 00:00:00 2001 From: "mathlib-nolints[bot]" <258989889+mathlib-nolints[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 01:30:21 +0000 Subject: [PATCH 0035/1300] chore: remove unnecessary set_option lines (#40609) I removed 24 unnecessary `set_option` line(s) across 9 file(s). --- Mathlib/Analysis/CStarAlgebra/Matrix.lean | 1 - Mathlib/Analysis/LocallyConvex/WeakDual.lean | 4 ---- Mathlib/Analysis/Normed/Order/Lattice.lean | 1 - Mathlib/LinearAlgebra/RootSystem/Irreducible.lean | 2 -- Mathlib/RepresentationTheory/Irreducible.lean | 6 ------ Mathlib/RepresentationTheory/Rep/Iso.lean | 3 --- Mathlib/RepresentationTheory/Semisimple.lean | 1 - Mathlib/RingTheory/Extension/Cotangent/Basis.lean | 1 - Mathlib/Topology/UniformSpace/Dini.lean | 5 ----- 9 files changed, 24 deletions(-) diff --git a/Mathlib/Analysis/CStarAlgebra/Matrix.lean b/Mathlib/Analysis/CStarAlgebra/Matrix.lean index 2dae014aca2719..c304aa4b11eae3 100644 --- a/Mathlib/Analysis/CStarAlgebra/Matrix.lean +++ b/Mathlib/Analysis/CStarAlgebra/Matrix.lean @@ -151,7 +151,6 @@ def l2OpNormedRingAux : NormedRing (Matrix n n 𝕜) := open Bornology Filter open scoped Topology Uniformity -set_option backward.isDefEq.respectTransparency false in /-- The metric on `Matrix m n 𝕜` arising from the operator norm given by the identification with (continuous) linear maps of `EuclideanSpace`. -/ @[instance_reducible] diff --git a/Mathlib/Analysis/LocallyConvex/WeakDual.lean b/Mathlib/Analysis/LocallyConvex/WeakDual.lean index d88c1193fa6504..92f685b76fa21a 100644 --- a/Mathlib/Analysis/LocallyConvex/WeakDual.lean +++ b/Mathlib/Analysis/LocallyConvex/WeakDual.lean @@ -179,7 +179,6 @@ theorem mem_span_iff_bound {f : ι → E →ₗ[𝕜] 𝕜} (φ : E →ₗ[𝕜] variable [AddCommGroup F] [Module 𝕜 F] (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) -set_option backward.isDefEq.respectTransparency false in /-- The Weak Representation Theorem: Every continuous functional on `E` endowed with the `σ(E, F; B)`-topology is of the form `x ↦ B(x, y)` for some `y : F`. -/ theorem dualEmbedding_surjective : Function.Surjective (WeakBilin.eval B) := fun f ↦ by @@ -212,14 +211,12 @@ section Topology variable [NormedField 𝕜] [AddCommGroup E] [Module 𝕜 E] [AddCommGroup F] [Module 𝕜 F] -set_option backward.isDefEq.respectTransparency false in theorem LinearMap.weakBilin_withSeminorms (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) : WithSeminorms (LinearMap.toSeminormFamily B : F → Seminorm 𝕜 (WeakBilin B)) := let e : F ≃ (Σ _ : F, Fin 1) := .symm <| .sigmaUnique _ _ withSeminorms_induced (withSeminorms_pi (fun _ ↦ norm_withSeminorms 𝕜 𝕜)) (LinearMap.ltoFun 𝕜 F 𝕜 𝕜 ∘ₗ B : (WeakBilin B) →ₗ[𝕜] (F → 𝕜)) |>.congr_equiv e -set_option backward.isDefEq.respectTransparency false in theorem LinearMap.hasBasis_weakBilin (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) : (𝓝 (0 : WeakBilin B)).HasBasis (· ∈ B.toSeminormFamily.basisSets) _root_.id := LinearMap.weakBilin_withSeminorms B |>.hasBasis @@ -231,7 +228,6 @@ section LocallyConvex variable [NormedField 𝕜] [AddCommGroup E] [Module 𝕜 E] [AddCommGroup F] [Module 𝕜 F] variable [NormedSpace ℝ 𝕜] [Module ℝ E] [IsScalarTower ℝ 𝕜 E] -set_option backward.isDefEq.respectTransparency false in instance WeakBilin.locallyConvexSpace {B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜} : LocallyConvexSpace ℝ (WeakBilin B) := B.weakBilin_withSeminorms.toLocallyConvexSpace diff --git a/Mathlib/Analysis/Normed/Order/Lattice.lean b/Mathlib/Analysis/Normed/Order/Lattice.lean index 898f8fc84305e4..dc4bd9ccc0a8b4 100644 --- a/Mathlib/Analysis/Normed/Order/Lattice.lean +++ b/Mathlib/Analysis/Normed/Order/Lattice.lean @@ -137,7 +137,6 @@ instance (priority := 100) HasSolidNorm.continuousInf : ContinuousInf α := by ((continuous_snd.tendsto q).sub <| tendsto_const_nhds).norm simp -set_option backward.isDefEq.respectTransparency false in -- see Note [lower instance priority] instance (priority := 100) HasSolidNorm.continuousSup {α : Type*} [NormedAddCommGroup α] [Lattice α] [HasSolidNorm α] [IsOrderedAddMonoid α] : ContinuousSup α := diff --git a/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean b/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean index d108d2127bac23..db9d53ee6aad0c 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean @@ -122,7 +122,6 @@ lemma invtRootSubmodule.eq_span_root {K : Type*} [Field K] [NeZero (2 : K)] · exact LinearMap.mem_ker.mp (invtRootSubmodule.le_ker_coroot' q hk htQ) exact P.eq_zero_iff_forall_coroot'_eq_zero.mpr h_ker -set_option backward.isDefEq.respectTransparency false in lemma isSimpleModule_weylGroupRootRep_iff [Nontrivial M] : IsSimpleModule R[P.weylGroup] P.weylGroupRootRep.asModule ↔ ∀ (q : Submodule R M), (∀ i, q ∈ invtSubmodule (P.reflection i)) → q ≠ ⊥ → q = ⊤ := by @@ -160,7 +159,6 @@ instance [P.IsIrreducible] : P.flip.IsIrreducible where eq_top_of_invtSubmodule_reflection := IsIrreducible.eq_top_of_invtSubmodule_coreflection (P := P) eq_top_of_invtSubmodule_coreflection := IsIrreducible.eq_top_of_invtSubmodule_reflection (P := P) -set_option backward.isDefEq.respectTransparency false in lemma isSimpleModule_weylGroupRootRep [P.IsIrreducible] : IsSimpleModule R[P.weylGroup] P.weylGroupRootRep.asModule := have := IsIrreducible.nontrivial P diff --git a/Mathlib/RepresentationTheory/Irreducible.lean b/Mathlib/RepresentationTheory/Irreducible.lean index ceaf936a5ef501..85891bec9b62f0 100644 --- a/Mathlib/RepresentationTheory/Irreducible.lean +++ b/Mathlib/RepresentationTheory/Irreducible.lean @@ -30,7 +30,6 @@ subrepresentations. -/ abbrev IsIrreducible := IsSimpleOrder (Subrepresentation ρ) -set_option backward.isDefEq.respectTransparency false in theorem irreducible_iff_isSimpleModule_asModule : IsIrreducible ρ ↔ IsSimpleModule k[G] ρ.asModule := by rw [isSimpleModule_iff] @@ -49,18 +48,15 @@ namespace IsIrreducible variable {ρ σ} (f : IntertwiningMap ρ σ) [IsIrreducible ρ] -set_option backward.isDefEq.respectTransparency false in instance : IsSimpleModule k[G] ρ.asModule := (irreducible_iff_isSimpleModule_asModule ρ).mp inferInstance open Function IntertwiningMap -set_option backward.isDefEq.respectTransparency false in theorem injective_or_eq_zero : Injective f ∨ f = 0 := by rw [← LinearEquiv.map_eq_zero_iff (equivLinearMapAsModule ρ σ)] exact LinearMap.injective_or_eq_zero (equivLinearMapAsModule ρ σ f) -set_option backward.isDefEq.respectTransparency false in theorem bijective_or_eq_zero [IsIrreducible σ] : Bijective f ∨ f = 0 := by rw [← LinearEquiv.map_eq_zero_iff (equivLinearMapAsModule ρ σ)] exact LinearMap.bijective_or_eq_zero (equivLinearMapAsModule ρ σ f) @@ -70,7 +66,6 @@ instance [IsIrreducible σ] [IsEmpty (Equiv ρ σ)] : Subsingleton (Intertwining fun h ↦ isEmpty_iff.mp inferInstance <| (f - g).ofBijective h⟩ variable [FiniteDimensional k V] [IsAlgClosed k] -set_option backward.isDefEq.respectTransparency false in variable (f : IntertwiningMap ρ ρ) in theorem algebraMap_intertwiningMap_bijective_of_isAlgClosed : Bijective (algebraMap k (IntertwiningMap ρ ρ)) := by @@ -85,7 +80,6 @@ variable (ρ) in exact CommSemiring.finrank_self k open scoped IsMulCommutative in -set_option backward.isDefEq.respectTransparency false in include ρ in variable (ρ) in theorem finrank_eq_one_of_isMulCommutative [IsMulCommutative G] : Module.finrank k V = 1 := by diff --git a/Mathlib/RepresentationTheory/Rep/Iso.lean b/Mathlib/RepresentationTheory/Rep/Iso.lean index 8699f639dfaab0..e9c9a47ceff40a 100644 --- a/Mathlib/RepresentationTheory/Rep/Iso.lean +++ b/Mathlib/RepresentationTheory/Rep/Iso.lean @@ -83,7 +83,6 @@ theorem to_Module_monoidAlgebra_map_aux {k G : Type*} [CommRing k] [Monoid G] (V · intro r g w simp only [map_smul, w, LinearMap.smul_apply] -set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `toModuleMonoidAlgebra`. -/ def toModuleMonoidAlgebraMap {V W : Rep.{w} k G} (f : V ⟶ W) : ModuleCat.of k[G] V.ρ.asModule ⟶ ModuleCat.of k[G] W.ρ.asModule := @@ -92,7 +91,6 @@ def toModuleMonoidAlgebraMap {V W : Rep.{w} k G} (f : V ⟶ W) : map_smul' := fun r x => to_Module_monoidAlgebra_map_aux V.V W.V V.ρ W.ρ f.hom.toLinearMap f.hom.2 r x } -set_option backward.isDefEq.respectTransparency false in /-- Functorially convert a representation of `G` into a module over `k[G]`. -/ def toModuleMonoidAlgebra : Rep.{w} k G ⥤ ModuleCat k[G] where obj V := ModuleCat.of _ V.ρ.asModule @@ -196,7 +194,6 @@ variable {k G : Type u} [CommRing k] [Monoid G] in instance : CategoryTheory.EnoughProjectives (Rep.{max w u} k G) := equivalenceModuleMonoidAlgebra.enoughProjectives_iff.2 ModuleCat.enoughProjectives.{max w u} -set_option backward.isDefEq.respectTransparency false in instance free_projective {α : Type (max w u)} : Projective (free k G α) := equivalenceModuleMonoidAlgebra.toAdjunction.projective_of_map_projective _ <| diff --git a/Mathlib/RepresentationTheory/Semisimple.lean b/Mathlib/RepresentationTheory/Semisimple.lean index 9ed66a1397f387..b21260eca4f9b7 100644 --- a/Mathlib/RepresentationTheory/Semisimple.lean +++ b/Mathlib/RepresentationTheory/Semisimple.lean @@ -34,7 +34,6 @@ variable [Monoid G] [Field k] [AddCommGroup V] [Module k V] abbrev IsSemisimpleRepresentation := ComplementedLattice (Subrepresentation ρ) -set_option backward.isDefEq.respectTransparency false in theorem isSemisimpleRepresentation_iff_isSemisimpleModule_asModule : IsSemisimpleRepresentation ρ ↔ IsSemisimpleModule k[G] ρ.asModule := by rw [isSemisimpleModule_iff] diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index df9d59125b1c4b..0d6ac75f554800 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -150,7 +150,6 @@ lemma tensorCotangentHom_tmul (x : D.presLeft.toExtension.ker) : def tensorCotangentInv : P.toExtension.Cotangent →ₗ[S] S ⊗[D.T] D.presLeft.toExtension.Cotangent := b.constr S fun i : σ ↦ 1 ⊗ₜ Extension.Cotangent.mk (D.kerGen i) -set_option backward.isDefEq.respectTransparency false in @[simp] lemma tensorCotangentInv_apply (i : σ) : D.tensorCotangentInv (b i) = 1 ⊗ₜ Extension.Cotangent.mk (D.kerGen i) := diff --git a/Mathlib/Topology/UniformSpace/Dini.lean b/Mathlib/Topology/UniformSpace/Dini.lean index 34c07a3509d4fb..e5daead8c0747d 100644 --- a/Mathlib/Topology/UniformSpace/Dini.lean +++ b/Mathlib/Topology/UniformSpace/Dini.lean @@ -103,7 +103,6 @@ end Monotone namespace Antitone -set_option backward.isDefEq.respectTransparency false in /-- **Dini's theorem**: if `F n` is a monotone decreasing collection of continuous functions on a converging pointwise to a continuous function `f`, then `F n` converges locally uniformly to `f`. -/ lemma tendstoLocallyUniformly_of_forall_tendsto @@ -112,7 +111,6 @@ lemma tendstoLocallyUniformly_of_forall_tendsto TendstoLocallyUniformly F f atTop := Monotone.tendstoLocallyUniformly_of_forall_tendsto (G := Gᵒᵈ) hF_cont hF_anti hf h_tendsto -set_option backward.isDefEq.respectTransparency false in /-- **Dini's theorem**: if `F n` is a monotone decreasing collection of continuous functions on a set `s` converging pointwise to a continuous function `f`, then `F n` converges locally uniformly to `f`. -/ @@ -122,7 +120,6 @@ lemma tendstoLocallyUniformlyOn_of_forall_tendsto {s : Set α} TendstoLocallyUniformlyOn F f atTop s := Monotone.tendstoLocallyUniformlyOn_of_forall_tendsto (G := Gᵒᵈ) hF_cont hF_anti hf h_tendsto -set_option backward.isDefEq.respectTransparency false in /-- **Dini's theorem**: if `F n` is a monotone decreasing collection of continuous functions on a compact space converging pointwise to a continuous function `f`, then `F n` converges uniformly to `f`. -/ @@ -131,7 +128,6 @@ lemma tendstoUniformly_of_forall_tendsto [CompactSpace α] (hF_cont : ∀ i, Con TendstoUniformly F f atTop := Monotone.tendstoUniformly_of_forall_tendsto (G := Gᵒᵈ) hF_cont hF_anti hf h_tendsto -set_option backward.isDefEq.respectTransparency false in /-- **Dini's theorem**: if `F n` is a monotone decreasing collection of continuous functions on a compact set `s` converging pointwise to a continuous `f`, then `F n` converges uniformly to `f`. -/ lemma tendstoUniformlyOn_of_forall_tendsto {s : Set α} (hs : IsCompact s) @@ -157,7 +153,6 @@ lemma tendsto_of_monotone_of_pointwise (hF_mono : Monotone F) tendsto_of_tendstoLocallyUniformly <| hF_mono.tendstoLocallyUniformly_of_forall_tendsto (F · |>.continuous) f.continuous h_tendsto -set_option backward.isDefEq.respectTransparency false in /-- **Dini's theorem**: if `F n` is a monotone decreasing collection of continuous functions converging pointwise to a continuous function `f`, then `F n` converges to `f` in the compact-open topology. -/ From e47b3cbac62dfb6ddb095cd4a2863ab3843d0238 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Mon, 15 Jun 2026 08:19:09 +0000 Subject: [PATCH 0036/1300] ci: update SpliceBot action (#40494) This bump should allow `splice-bot maintainer merge? ` to work even on PRs that haven't merged `master` yet. (The core logic for that was moved into the `workflow_run` half of the action, which reads from `master` rather than the PR branch.) --- .github/workflows/splice_bot.yaml | 2 +- .github/workflows/splice_bot_wf_run.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/splice_bot.yaml b/.github/workflows/splice_bot.yaml index e46bce162219e8..19e1915aa0c8fe 100644 --- a/.github/workflows/splice_bot.yaml +++ b/.github/workflows/splice_bot.yaml @@ -9,7 +9,7 @@ permissions: {} jobs: call-splice-bot: if: ${{ contains(github.event.comment.body, 'splice-bot') }} - uses: leanprover-community/SpliceBot/.github/workflows/splice.yaml@61d21ff3cb6fde3c49b81a3016a8718e59e52f60 # master + uses: leanprover-community/SpliceBot/.github/workflows/splice.yaml@d86d20efffbd18f839199fdd5ec126570f7eceda # master with: # Optional override; omit to use the reusable workflow's default "master" base_ref: master diff --git a/.github/workflows/splice_bot_wf_run.yaml b/.github/workflows/splice_bot_wf_run.yaml index d8b98abdb20c0d..b5777a10cfdd8c 100644 --- a/.github/workflows/splice_bot_wf_run.yaml +++ b/.github/workflows/splice_bot_wf_run.yaml @@ -45,7 +45,7 @@ jobs: owner: leanprover-community - name: Run splice bot action - uses: leanprover-community/SpliceBot/.github/actions/splice-wf-run@61d21ff3cb6fde3c49b81a3016a8718e59e52f60 + uses: leanprover-community/SpliceBot/.github/actions/splice-wf-run@d86d20efffbd18f839199fdd5ec126570f7eceda with: source_workflow: ${{ github.event.workflow_run.name }} push_to_fork: leanprover-community/mathlib4_copy From 43f7f5c74481a10840e1f071e82345be3c03b8cf Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:36:28 +0000 Subject: [PATCH 0037/1300] chore: fix non-reducible diamond in AEval (#40429) The following fails before the PR: ```example : ((Module.AEval.instAddCommGroup a).toAdd : Add (Module.AEval R M a)) = (Module.AEval.instAddCommMonoid a).toAddCommSemigroup.toAddCommMagma.toAdd := by with_reducible_and_instances rfl ``` It works after the PR, modulo the instance renaming. Co-authored-by: sgouezel --- Mathlib/Algebra/Polynomial/Module/AEval.lean | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Module/AEval.lean b/Mathlib/Algebra/Polynomial/Module/AEval.lean index ed21373297fda9..b6eb75e695dd37 100644 --- a/Mathlib/Algebra/Polynomial/Module/AEval.lean +++ b/Mathlib/Algebra/Polynomial/Module/AEval.lean @@ -39,6 +39,7 @@ and the action of `f` is `f • (of R M a m) = of R M a ((aeval a f) • m)`. @[nolint unusedArguments] def AEval (R M : Type*) {A : Type*} [CommSemiring R] [Semiring A] [Algebra R A] [AddCommMonoid M] [Module A M] [Module R M] [IsScalarTower R A M] (_ : A) := M + deriving AddCommMonoid, Module R instance AEval.instAddCommGroup {R A M} [CommSemiring R] [Semiring A] (a : A) [Algebra R A] [AddCommGroup M] [Module A M] [Module R M] [IsScalarTower R A M] : @@ -49,12 +50,8 @@ variable {R A M} [CommSemiring R] [Semiring A] (a : A) [Algebra R A] [AddCommMon namespace AEval -instance instAddCommMonoid : AddCommMonoid <| AEval R M a := inferInstanceAs (AddCommMonoid M) - -instance instModuleOrig : Module R <| AEval R M a := inferInstanceAs (Module R M) - instance instFiniteOrig [Module.Finite R M] : Module.Finite R <| AEval R M a := - ‹Module.Finite R M› + inferInstanceAs <| Module.Finite R M noncomputable instance instModulePolynomial : Module R[X] <| AEval R M a := compHom M (aeval a).toRingHom From b5ae1ef3ff123cfd169c2289640cb67f69f30bed Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:53:12 +0000 Subject: [PATCH 0038/1300] chore: remove non-reducible diamond in splitting field (#40420) Currently, `f.SplittingField` has two `K`-algebra structures. The PR fixes this. Co-authored-by: sgouezel --- Mathlib/FieldTheory/SplittingField/Construction.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/FieldTheory/SplittingField/Construction.lean b/Mathlib/FieldTheory/SplittingField/Construction.lean index 9123fb3c2664bb..bdeff93804b3a7 100644 --- a/Mathlib/FieldTheory/SplittingField/Construction.lean +++ b/Mathlib/FieldTheory/SplittingField/Construction.lean @@ -214,7 +214,7 @@ end SplittingFieldAux def SplittingField (f : K[X]) := MvPolynomial (SplittingFieldAux f.natDegree f) K ⧸ RingHom.ker (MvPolynomial.aeval (R := K) id).toRingHom -deriving Inhabited, CommRing, Algebra K +deriving Inhabited, CommRing namespace SplittingField @@ -226,6 +226,8 @@ deriving instance SMul S for SplittingField f variable {R : Type*} [CommSemiring R] [Algebra R K] in deriving instance Algebra R, IsScalarTower R K for SplittingField f +instance : Algebra K f.SplittingField := inferInstance + /-- The algebra equivalence with `SplittingFieldAux`, which we will use to construct the field structure. -/ def algEquivSplittingFieldAux (f : K[X]) : SplittingField f ≃ₐ[K] SplittingFieldAux f.natDegree f := From d706b80d5719f25955af00cd0d33e2bfc3b2287f Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:53:14 +0000 Subject: [PATCH 0039/1300] chore: fix non-reducible diamond in tensor product norms (#40452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following fails before the PR, succeeds after it: ``` example : (PiTensorProduct.instSeminormedAddCommGroup.toNorm : Norm (PiTensorProduct 𝕜 fun i => E i)) = PiTensorProduct.instNorm := by with_reducible_and_instances rfl ``` Co-authored-by: sgouezel --- .../Normed/Module/PiTensorProduct/InjectiveSeminorm.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean index 7669b31e356f1a..50460c1ef4893c 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean @@ -213,10 +213,10 @@ theorem injectiveSeminorm_tprod_le (m : Π (i : ι), E i) : le_trans (injectiveSeminorm_le_projectiveSeminorm _) (projectiveSeminorm_tprod_le m) -- Use `projectiveSeminorm` to turn the `PiTensorProduct` into a seminormed space. --- The definition `injectiveSeminorm` is subject to deprecication in a follow-up PR. See: +-- The definition `injectiveSeminorm` is subject to deprecation in a follow-up PR. See: -- https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/injectiveSeminorm/with/568798633 noncomputable instance : SeminormedAddCommGroup (⨂[𝕜] i, E i) := - AddGroupSeminorm.toSeminormedAddCommGroup projectiveSeminorm.toAddGroupSeminorm + fast_instance% AddGroupSeminorm.toSeminormedAddCommGroup projectiveSeminorm.toAddGroupSeminorm noncomputable instance : NormedSpace 𝕜 (⨂[𝕜] i, E i) := ⟨projectiveSeminorm_smul_le⟩ From 9a62f87bb95793abaaf4d1cb48d2c3ca27a17780 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 11:02:22 +0000 Subject: [PATCH 0040/1300] chore: update Mathlib dependencies 2026-06-15 (#40623) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index eafa08243a29de..289958f5764546 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "c43d7789ff29244c1f6f7c8480342a2d2d6c0d30", + "rev": "c6f7103faab35720af56784a9553733832f17349", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From ed00c7a87269a76c1eddb6e12fbed24d2fa0e3e9 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 15 Jun 2026 11:19:50 +0000 Subject: [PATCH 0041/1300] feat(Combinatorics/SimpleGraph/Copy): `Is(Ind)Contained` `completeGraph` lemmas (#38549) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `G ⊑ completeGraph W ↔ Nonempty (V ↪ W)` - `completeGraph V ⊴ completeGraph W ↔ Nonempty (V ↪ W)` - `G ⊴ completeGraph W → G = ⊤` --- Mathlib/Combinatorics/SimpleGraph/Copy.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Copy.lean b/Mathlib/Combinatorics/SimpleGraph/Copy.lean index 7ec6f8e34559ab..3bc1aeb011955b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Copy.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Copy.lean @@ -462,6 +462,15 @@ theorem isIndContained_iff_exists_iso_induce : G ⊴ H ↔ ∃ s, Nonempty (G (⊤ : SimpleGraph V) ⊴ H ↔ (⊤ : SimpleGraph V) ⊑ H := ⟨IsIndContained.isContained, fun ⟨f⟩ ↦ ⟨f.topEmbedding⟩⟩ +theorem isContained_top_iff {G : SimpleGraph V} : G ⊑ completeGraph W ↔ Nonempty (V ↪ W) := + ⟨(⟨·.some.toEmbedding⟩), (.trans (.of_le le_top) ⟨Embedding.completeGraph ·.some |>.toCopy⟩)⟩ + +theorem top_isIndContained_top_iff : completeGraph V ⊴ completeGraph W ↔ Nonempty (V ↪ W) := + ⟨(⟨·.some.toEmbedding⟩), (⟨.completeGraph ·.some⟩)⟩ + +theorem eq_top_of_isIndContained_top (h : G ⊴ completeGraph W) : G = ⊤ := + h.some.comap_eq ▸ comap_top h.some.injective + @[simp] lemma compl_isIndContained_compl : Gᶜ ⊴ Hᶜ ↔ G ⊴ H := Embedding.complEquiv.symm.nonempty_congr From dd9f867f729dd85e5fe94ed84ca323acb2e57132 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 15 Jun 2026 11:33:55 +0000 Subject: [PATCH 0042/1300] feat: custom elaborators for TangentSpace and tangentMap(Within) (#36155) And use these to golf the differential geometry files a bit further. --- .../Geometry/Manifold/ContMDiffMFDeriv.lean | 18 +-- .../Geometry/Manifold/GroupLieAlgebra.lean | 8 +- .../Manifold/IntegralCurve/Basic.lean | 9 +- .../Manifold/MFDeriv/NormedSpace.lean | 14 +- .../Manifold/MFDeriv/SpecificFunctions.lean | 121 +++++++++--------- .../Geometry/Manifold/MFDeriv/Tangent.lean | 6 +- Mathlib/Geometry/Manifold/Notation.lean | 26 ++++ .../Geometry/Manifold/Riemannian/Basic.lean | 24 ++-- .../Manifold/Riemannian/PathELength.lean | 10 +- .../Topology/FiberBundle/Constructions.lean | 2 +- .../DifferentialGeometry/Notation/Basic.lean | 29 ++++- 11 files changed, 161 insertions(+), 106 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index e6ab158996ea6c..fe370981f4d96c 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -274,18 +274,18 @@ variable [Is : IsManifold I 1 M] [I's : IsManifold I' 1 M'] is `C^m` when `m+1 ≤ n`. -/ theorem ContMDiffOn.contMDiffOn_tangentMapWithin (hf : CMDiff[s] n f) (hmn : m + 1 ≤ n) (hs : UniqueMDiffOn I s) : - CMDiff[(π E (TangentSpace I) ⁻¹' s)] m (tangentMapWithin I I' f s) := by + CMDiff[(π E (TangentSpace I) ⁻¹' s)] m (tangentMap[s] f) := by intro x₀ hx₀ let s' : Set (TangentBundle I M) := (π E (TangentSpace I) ⁻¹' s) let b₁ : TangentBundle I M → M := fun p ↦ p.1 - let v : Π (y : TangentBundle I M), TangentSpace I (b₁ y) := fun y ↦ y.2 + let v : Π (y : TangentBundle I M), TangentSpace% (b₁ y) := fun y ↦ y.2 have hv : ContMDiffWithinAt I.tangent I.tangent m (fun y ↦ (v y : TangentBundle I M)) s' x₀ := contMDiffWithinAt_id let b₂ : TangentBundle I M → M' := f ∘ b₁ have hb₂ : CMDiffAt[s'] m b₂ x₀ := ((hf (b₁ x₀) hx₀).of_le (le_self_add.trans hmn)).comp _ (contMDiffWithinAt_proj (TangentSpace I)) (fun x h ↦ h) - let ϕ : Π (y : TangentBundle I M), TangentSpace I (b₁ y) →L[𝕜] TangentSpace I' (b₂ y) := + let ϕ : Π (y : TangentBundle I M), TangentSpace% (b₁ y) →L[𝕜] TangentSpace% (b₂ y) := fun y ↦ mfderiv[s] f (b₁ y) have hϕ : CMDiffAt[s'] m (fun y ↦ ContinuousLinearMap.inCoordinates E (TangentSpace I (M := M)) E' (TangentSpace I' (M := M')) (b₁ x₀) (b₁ y) (b₂ x₀) (b₂ y) (ϕ y)) x₀ := by @@ -299,21 +299,21 @@ theorem ContMDiffOn.contMDiffOn_tangentMapWithin derivative is continuous there. -/ theorem ContMDiffOn.continuousOn_tangentMapWithin (hf : CMDiff[s] n f) (hmn : 1 ≤ n) (hs : UniqueMDiffOn I s) : - ContinuousOn (tangentMapWithin I I' f s) (π E (TangentSpace I) ⁻¹' s) := by - have : CMDiff[π E (TangentSpace I) ⁻¹' s] 0 (tangentMapWithin I I' f s) := + ContinuousOn (tangentMap[s] f) (π E (TangentSpace I) ⁻¹' s) := by + have : CMDiff[π E (TangentSpace I) ⁻¹' s] 0 (tangentMap[s] f) := hf.contMDiffOn_tangentMapWithin hmn hs exact this.continuousOn /-- If a function is `C^n`, then its bundled derivative is `C^m` when `m+1 ≤ n`. -/ theorem ContMDiff.contMDiff_tangentMap (hf : CMDiff n f) (hmn : m + 1 ≤ n) : - CMDiff m (tangentMap I I' f) := by + CMDiff m (tangentMap% f) := by rw [← contMDiffOn_univ] at hf ⊢ convert! hf.contMDiffOn_tangentMapWithin hmn uniqueMDiffOn_univ rw [tangentMapWithin_univ] /-- If a function is `C^n`, with `1 ≤ n`, then its bundled derivative is continuous. -/ theorem ContMDiff.continuous_tangentMap (hf : CMDiff n f) (hmn : 1 ≤ n) : - Continuous (tangentMap I I' f) := by + Continuous (tangentMap% f) := by rw [← contMDiffOn_univ] at hf rw [← continuousOn_univ] convert! hf.continuousOn_tangentMapWithin hmn uniqueMDiffOn_univ @@ -342,7 +342,7 @@ may seem. TODO define splittings of vector bundles; state this result invariantly. -/ theorem tangentMap_tangentBundle_pure [Is : IsManifold I 1 M] (p : TangentBundle I M) : - tangentMap I I.tangent (zeroSection E (TangentSpace I)) p = ⟨⟨p.proj, 0⟩, ⟨p.2, 0⟩⟩ := by + tangentMap% (zeroSection (B := M) E (TangentSpace I)) p = ⟨⟨p.proj, 0⟩, ⟨p.2, 0⟩⟩ := by rcases p with ⟨x, v⟩ have N : I.symm ⁻¹' (chartAt H x).target ∈ 𝓝 (I ((chartAt H x) x)) := by apply IsOpen.mem_nhds @@ -404,7 +404,7 @@ bundles. -/ lemma equivTangentBundleProd_eq_tangentMap_prod_tangentMap : equivTangentBundleProd I M I' M' = fun (p : TangentBundle (I.prod I') (M × M')) ↦ - (tangentMap (I.prod I') I Prod.fst p, tangentMap (I.prod I') I' Prod.snd p) := by + (tangentMap% (@Prod.fst M M') p, tangentMap% (@Prod.snd M M') p) := by simp only [tangentMap_prodFst, tangentMap_prodSnd]; rfl variable [IsManifold I 1 M] [IsManifold I' 1 M'] diff --git a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean index 010d41d7d763a8..0a011da1035f3d 100644 --- a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean +++ b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean @@ -53,13 +53,13 @@ variable (I G) in `GroupLieAlgebra` instead of `LieAlgebra` as the latter is taken as a generic class. -/ @[to_additive /-- The Lie algebra of an additive Lie group, i.e., its tangent space at zero. We use the word `AddGroupLieAlgebra` instead of `LieAlgebra` as the latter is taken as a generic class. -/] -abbrev GroupLieAlgebra : Type _ := TangentSpace I (1 : G) +abbrev GroupLieAlgebra : Type _ := TangentSpace% (1 : G) /-- The invariant vector field associated to a vector `v` in the Lie algebra. At a point `g`, it is given by the image of `v` under left-multiplication by `g`. -/ @[to_additive /-- The invariant vector field associated to a vector `v` in the Lie algebra. At a point `g`, it is given by the image of `v` under left-addition by `g`. -/] -noncomputable def mulInvariantVectorField (v : GroupLieAlgebra I G) (g : G) : TangentSpace I g := +noncomputable def mulInvariantVectorField (v : GroupLieAlgebra I G) (g : G) : TangentSpace% g := mfderiv% (g * ·) (1 : G) v set_option backward.isDefEq.respectTransparency false in @@ -134,7 +134,7 @@ lemma mpullback_mulInvariantVectorField (g : G) (v : GroupLieAlgebra I G) : set_option backward.isDefEq.respectTransparency false in @[to_additive] -lemma mulInvariantVectorField_eq_mpullback (g : G) (V : Π (g : G), TangentSpace I g) : +lemma mulInvariantVectorField_eq_mpullback (g : G) (V : Π (g : G), TangentSpace% g) : mulInvariantVectorField (V 1) g = mpullback I I (g⁻¹ * ·) V g := by have A : 1 = g⁻¹ * g := by simp simp only [mulInvariantVectorField, mpullback, inverse_mfderiv_mul_left] @@ -171,7 +171,7 @@ theorem contMDiff_mulInvariantVectorField (v : GroupLieAlgebra I G) : (equivTangentBundleProd I G I G).symm have S₂ : CMDiff (minSmoothness 𝕜 2) F₂ := contMDiff_equivTangentBundleProd_symm let F₃ : TangentBundle (I.prod I) (G × G) → TangentBundle I G := - tangentMap (I.prod I) I (fun (p : G × G) ↦ p.1 * p.2) + tangentMap% (fun (p : G × G) ↦ p.1 * p.2) have S₃ : CMDiff (minSmoothness 𝕜 2) F₃ := by apply ContMDiff.contMDiff_tangentMap _ (m := minSmoothness 𝕜 2) le_rfl rw [A] diff --git a/Mathlib/Geometry/Manifold/IntegralCurve/Basic.lean b/Mathlib/Geometry/Manifold/IntegralCurve/Basic.lean index 39836315da45e3..be0efc65d54a50 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve/Basic.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve/Basic.lean @@ -6,6 +6,7 @@ Authors: Winston Yin module public import Mathlib.Geometry.Manifold.MFDeriv.Tangent +public import Mathlib.Geometry.Manifold.Notation /-! # Integral curves of vector fields on a manifold @@ -62,21 +63,21 @@ variable /-- If `γ : ℝ → M` is $C^1$ on `s : Set ℝ` and `v` is a vector field on `M`, `IsMIntegralCurveOn γ v s` means `γ t` is tangent to `v (γ t)` for all `t ∈ s`. The value of `γ` outside of `s` is irrelevant and considered junk. -/ -def IsMIntegralCurveOn (γ : ℝ → M) (v : (x : M) → TangentSpace I x) (s : Set ℝ) : Prop := +def IsMIntegralCurveOn (γ : ℝ → M) (v : (x : M) → TangentSpace% x) (s : Set ℝ) : Prop := ∀ t ∈ s, HasMFDerivAt[s] γ t ((1 : ℝ →L[ℝ] ℝ).smulRight <| v (γ t)) /-- If `v` is a vector field on `M` and `t₀ : ℝ`, `IsMIntegralCurveAt γ v t₀` means `γ : ℝ → M` is a local integral curve of `v` in a neighbourhood containing `t₀`. The value of `γ` outside of this interval is irrelevant and considered junk. -/ -def IsMIntegralCurveAt (γ : ℝ → M) (v : (x : M) → TangentSpace I x) (t₀ : ℝ) : Prop := +def IsMIntegralCurveAt (γ : ℝ → M) (v : (x : M) → TangentSpace% x) (t₀ : ℝ) : Prop := ∀ᶠ t in 𝓝 t₀, HasMFDerivAt% γ t ((1 : ℝ →L[ℝ] ℝ).smulRight <| v (γ t)) /-- If `v : M → TM` is a vector field on `M`, `IsMIntegralCurve γ v` means `γ : ℝ → M` is a global integral curve of `v`. That is, `γ t` is tangent to `v (γ t)` for all `t : ℝ`. -/ -def IsMIntegralCurve (γ : ℝ → M) (v : (x : M) → TangentSpace I x) : Prop := +def IsMIntegralCurve (γ : ℝ → M) (v : (x : M) → TangentSpace% x) : Prop := ∀ t : ℝ, HasMFDerivAt% γ t ((1 : ℝ →L[ℝ] ℝ).smulRight (v (γ t))) -variable {γ γ' : ℝ → M} {v : (x : M) → TangentSpace I x} {s s' : Set ℝ} {t₀ : ℝ} +variable {γ γ' : ℝ → M} {v : (x : M) → TangentSpace% x} {s s' : Set ℝ} {t₀ : ℝ} lemma IsMIntegralCurve.isMIntegralCurveOn (h : IsMIntegralCurve γ v) (s : Set ℝ) : IsMIntegralCurveOn γ v s := fun t _ ↦ (h t).hasMFDerivWithinAt diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 45c0236b5d06fe..0cc8f598e3708b 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -276,15 +276,15 @@ This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, w canonical identification. (It would also be possible to phrase the formula without this equiv, instead using casting and definitional abuse.) -/ private lemma HasMFDerivAt.smul - {f' : TangentSpace I x →L[𝕜] 𝕜} + {f' : TangentSpace% x →L[𝕜] 𝕜} (hs : HasMFDerivAt% f x ((fromTangentSpace (f x)).symm.toContinuousLinearMap ∘L f')) - {g' : TangentSpace I x →L[𝕜] V} + {g' : TangentSpace% x →L[𝕜] V} (hg : HasMFDerivAt% g x ((fromTangentSpace (g x)).symm.toContinuousLinearMap ∘L g')) : -- canonically identify `g'` with a linear map into the tangent space at `(f • g) x` - letI g'_ : TangentSpace I x →L[𝕜] TangentSpace 𝓘(𝕜, V) ((f • g) x) := + letI g'_ : TangentSpace% x →L[𝕜] TangentSpace 𝓘(𝕜, V) ((f • g) x) := (fromTangentSpace _).symm.toContinuousLinearMap ∘L g' -- canonically identify `g x` with a linear map into a tangent space at `(f • g) x` - letI gx : 𝕜 →L[𝕜] TangentSpace 𝓘(𝕜, V) ((f • g) x) := + letI gx : 𝕜 →L[𝕜] TangentSpace% ((f • g) x) := toSpanSingleton 𝕜 ((fromTangentSpace _).symm (g x)) -- now the main statement typechecks HasMFDerivAt% (f • g) x (f x • g'_ + gx ∘L f') := by @@ -382,7 +382,7 @@ typecheck we need a phrasing involving the canonical identification `NormedSpace between the vector space `V` and the tangent space to this vector space at any point. This is because two different tangent spaces (at `(f • g) x` and `g x`) appear in the equation. -/ private lemma fromTangentSpace_mfderiv_smul_apply (hf : MDiffAt f x) (hg : MDiffAt g x) - (v : TangentSpace I x) : + (v : TangentSpace% x) : fromTangentSpace _ (mfderiv% (f • g) x v) = f x • fromTangentSpace _ (mfderiv% g x v) + fromTangentSpace _ (mfderiv% f x v) • g x := by simpa using congr($(fromTangentSpace_mfderiv_smul hf hg) v) @@ -400,7 +400,7 @@ because two different tangent spaces (at `(f • g) x` and `g x`) appear in the This is a defeq variant of the main lemma `fromTangentSpace_mfderiv_smul_apply`, in which we work in the tangent space at `f x • g x` (the simp-normal form) rather than at `(f • g) x`. -/ private lemma fromTangentSpace_mfderiv_smul_apply' (hf : MDiffAt f x) (hg : MDiffAt g x) - (v : TangentSpace I x) : + (v : TangentSpace% x) : fromTangentSpace (f x • g x) (mfderiv% (f • g) x v) = f x • fromTangentSpace _ (mfderiv% g x v) + fromTangentSpace _ (mfderiv% f x v) • g x := fromTangentSpace_mfderiv_smul_apply hf hg v @@ -428,7 +428,7 @@ Future: this could be generalised to functions into additive torsors over abelia -/ @[expose] noncomputable def mvfderiv (g : M → F) : - Π x : M, TangentSpace I x →L[𝕜] F := + Π x : M, TangentSpace% x →L[𝕜] F := fun x ↦ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv% g x) @[deprecated (since := "2026-05-17")] alias extDerivFun := mvfderiv diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 28254093a16323..60b917645a0878 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -7,7 +7,7 @@ module public import Mathlib.Analysis.Calculus.FDeriv.Mul public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.Notation /-! # Differentiability of specific functions @@ -126,7 +126,7 @@ section id /-! #### Identity -/ theorem hasMFDerivAt_id (x : M) : - HasMFDerivAt% (@id M) x (ContinuousLinearMap.id 𝕜 (TangentSpace I x)) := by + HasMFDerivAt% (@id M) x (ContinuousLinearMap.id 𝕜 (TangentSpace% x)) := by refine ⟨continuousAt_id, ?_⟩ have : ∀ᶠ y in 𝓝[range I] (extChartAt I x) x, (extChartAt I x ∘ (extChartAt I x).symm) y = y := by apply Filter.mem_of_superset (extChartAt_target_mem_nhdsWithin x) @@ -135,7 +135,7 @@ theorem hasMFDerivAt_id (x : M) : simp only [mfld_simps] theorem hasMFDerivWithinAt_id (s : Set M) (x : M) : - HasMFDerivAt[s] (@id M) x (ContinuousLinearMap.id 𝕜 (TangentSpace I x)) := + HasMFDerivAt[s] (@id M) x (ContinuousLinearMap.id 𝕜 (TangentSpace% x)) := (hasMFDerivAt_id x).hasMFDerivWithinAt theorem mdifferentiableAt_id : MDiffAt (@id M) x := @@ -150,20 +150,20 @@ theorem mdifferentiableOn_id : MDiff[s] (@id M) := mdifferentiable_id.mdifferentiableOn @[simp, mfld_simps] -theorem mfderiv_id : mfderiv% (@id M) x = ContinuousLinearMap.id 𝕜 (TangentSpace I x) := +theorem mfderiv_id : mfderiv% (@id M) x = ContinuousLinearMap.id 𝕜 (TangentSpace% x) := (hasMFDerivAt_id x).mfderiv theorem mfderivWithin_id (hxs : UniqueMDiffWithinAt I s x) : - mfderiv[s] (@id M) x = ContinuousLinearMap.id 𝕜 (TangentSpace I x) := by + mfderiv[s] (@id M) x = ContinuousLinearMap.id 𝕜 (TangentSpace% x) := by rw [MDifferentiable.mfderivWithin mdifferentiableAt_id hxs] exact mfderiv_id set_option backward.isDefEq.respectTransparency false in @[simp, mfld_simps] -theorem tangentMap_id : tangentMap I I (id : M → M) = id := by ext1 ⟨x, v⟩; simp [tangentMap] +theorem tangentMap_id : tangentMap% (@id M) = id := by ext1 ⟨x, v⟩; simp [tangentMap] theorem tangentMapWithin_id {p : TangentBundle I M} (hs : UniqueMDiffWithinAt I s p.proj) : - tangentMapWithin I I (id : M → M) s p = p := by + tangentMap[s] (id : M → M) p = p := by simp only [tangentMapWithin, id] rw [mfderivWithin_id] · rcases p with ⟨⟩; rfl @@ -180,11 +180,11 @@ variable {c : M'} set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivAt_const (c : M') (x : M) : - HasMFDerivAt% (fun _ : M ↦ c) x (0 : TangentSpace I x →L[𝕜] TangentSpace I' c) := + HasMFDerivAt% (fun _ : M ↦ c) x (0 : TangentSpace% x →L[𝕜] TangentSpace% c) := ⟨by fun_prop, by simp [Function.comp_def, hasFDerivWithinAt_const]⟩ theorem hasMFDerivWithinAt_const (c : M') (s : Set M) (x : M) : - HasMFDerivAt[s] (fun _ : M ↦ c) x (0 : TangentSpace I x →L[𝕜] TangentSpace I' c) := + HasMFDerivAt[s] (fun _ : M ↦ c) x (0 : TangentSpace% x →L[𝕜] TangentSpace% c) := (hasMFDerivAt_const c x).hasMFDerivWithinAt theorem mdifferentiableAt_const : MDiffAt (fun _ : M ↦ c) x := @@ -200,11 +200,11 @@ theorem mdifferentiableOn_const : MDiff[s] (fun _ : M ↦ c) := @[simp, mfld_simps] theorem mfderiv_const : - mfderiv% (fun _ : M ↦ c) x = (0 : TangentSpace I x →L[𝕜] TangentSpace I' c) := + mfderiv% (fun _ : M ↦ c) x = (0 : TangentSpace% x →L[𝕜] TangentSpace% c) := (hasMFDerivAt_const c x).mfderiv theorem mfderivWithin_const : - mfderiv[s] (fun _ : M ↦ c) x = (0 : TangentSpace I x →L[𝕜] TangentSpace I' c) := + mfderiv[s] (fun _ : M ↦ c) x = (0 : TangentSpace% x →L[𝕜] TangentSpace% c) := (hasMFDerivWithinAt_const _ _ _).mfderivWithin_eq_zero end Const @@ -221,8 +221,8 @@ theorem MDifferentiableWithinAt.prodMk {f : M → M'} {g : M → M''} /-- If `f` and `g` have derivatives `df` and `dg` within `s` at `x`, respectively, then `x ↦ (f x, g x)` has derivative `df.prod dg` within `s`. -/ theorem HasMFDerivWithinAt.prodMk {f : M → M'} {g : M → M''} - {df : TangentSpace I x →L[𝕜] TangentSpace I' (f x)} (hf : HasMFDerivAt[s] f x df) - {dg : TangentSpace I x →L[𝕜] TangentSpace I'' (g x)} (hg : HasMFDerivAt[s] g x dg) : + {df : TangentSpace% x →L[𝕜] TangentSpace% (f x)} (hf : HasMFDerivAt[s] f x df) + {dg : TangentSpace% x →L[𝕜] TangentSpace% (g x)} (hg : HasMFDerivAt[s] g x dg) : HasMFDerivAt[s] (fun y ↦ (f y, g y)) x (df.prod dg) := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ @@ -244,8 +244,8 @@ theorem MDifferentiableAt.prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt f /-- If `f` and `g` have derivatives `df` and `dg` at `x`, respectively, then `x ↦ (f x, g x)` has derivative `df.prod dg`. -/ theorem HasMFDerivAt.prodMk {f : M → M'} {g : M → M''} - {df : TangentSpace I x →L[𝕜] TangentSpace I' (f x)} (hf : HasMFDerivAt% f x df) - {dg : TangentSpace I x →L[𝕜] TangentSpace I'' (g x)} (hg : HasMFDerivAt% g x dg) : + {df : TangentSpace% x →L[𝕜] TangentSpace% (f x)} (hf : HasMFDerivAt% f x df) + {dg : TangentSpace% x →L[𝕜] TangentSpace% (g x)} (hg : HasMFDerivAt% g x dg) : HasMFDerivAt% (fun y ↦ (f y, g y)) x (df.prod dg) := ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ @@ -276,7 +276,7 @@ fun x ↦ (hf x).prodMk_space (hg x) theorem hasMFDerivAt_fst (x : M × M') : HasMFDerivAt% (@Prod.fst M M') x - (ContinuousLinearMap.fst 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2)) := by + (ContinuousLinearMap.fst 𝕜 (TangentSpace% x.1) (TangentSpace% x.2)) := by refine ⟨continuous_fst.continuousAt, ?_⟩ have : ∀ᶠ y in 𝓝[range (I.prod I')] extChartAt (I.prod I') x x, @@ -294,7 +294,7 @@ theorem hasMFDerivAt_fst (x : M × M') : theorem hasMFDerivWithinAt_fst (s : Set (M × M')) (x : M × M') : HasMFDerivAt[s] (@Prod.fst M M') x - (ContinuousLinearMap.fst 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2)) := + (ContinuousLinearMap.fst 𝕜 (TangentSpace% x.1) (TangentSpace% x.2)) := (hasMFDerivAt_fst x).hasMFDerivWithinAt theorem mdifferentiableAt_fst {x : M × M'} : MDiffAt (@Prod.fst M M') x := @@ -312,23 +312,23 @@ theorem mdifferentiableOn_fst {s : Set (M × M')} : MDiff[s] (@Prod.fst M M') := @[simp, mfld_simps] theorem mfderiv_fst {x : M × M'} : mfderiv% (@Prod.fst M M') x = - ContinuousLinearMap.fst 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2) := + ContinuousLinearMap.fst 𝕜 (TangentSpace% x.1) (TangentSpace% x.2) := (hasMFDerivAt_fst x).mfderiv theorem mfderivWithin_fst {s : Set (M × M')} {x : M × M'} (hxs : UniqueMDiffWithinAt (I.prod I') s x) : mfderiv[s] (@Prod.fst M M') x = - ContinuousLinearMap.fst 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2) := by + ContinuousLinearMap.fst 𝕜 (TangentSpace% x.1) (TangentSpace% x.2) := by rw [MDifferentiable.mfderivWithin mdifferentiableAt_fst hxs]; exact mfderiv_fst @[simp, mfld_simps] theorem tangentMap_prodFst {p : TangentBundle (I.prod I') (M × M')} : - tangentMap (I.prod I') I Prod.fst p = ⟨p.proj.1, p.2.1⟩ := by + tangentMap% (@Prod.fst M M') p = ⟨p.proj.1, p.2.1⟩ := by simp [tangentMap]; rfl theorem tangentMapWithin_prodFst {s : Set (M × M')} {p : TangentBundle (I.prod I') (M × M')} (hs : UniqueMDiffWithinAt (I.prod I') s p.proj) : - tangentMapWithin (I.prod I') I Prod.fst s p = ⟨p.proj.1, p.2.1⟩ := by + tangentMap[s] (@Prod.fst M M') p = ⟨p.proj.1, p.2.1⟩ := by simp only [tangentMapWithin] rw [mfderivWithin_fst] · rcases p with ⟨⟩; rfl @@ -336,7 +336,7 @@ theorem tangentMapWithin_prodFst {s : Set (M × M')} {p : TangentBundle (I.prod theorem hasMFDerivAt_snd (x : M × M') : HasMFDerivAt% (@Prod.snd M M') x - (ContinuousLinearMap.snd 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2)) := by + (ContinuousLinearMap.snd 𝕜 (TangentSpace% x.1) (TangentSpace% x.2)) := by refine ⟨continuous_snd.continuousAt, ?_⟩ have : ∀ᶠ y in 𝓝[range (I.prod I')] extChartAt (I.prod I') x x, @@ -354,7 +354,7 @@ theorem hasMFDerivAt_snd (x : M × M') : theorem hasMFDerivWithinAt_snd (s : Set (M × M')) (x : M × M') : HasMFDerivAt[s] (@Prod.snd M M') x - (ContinuousLinearMap.snd 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2)) := + (ContinuousLinearMap.snd 𝕜 (TangentSpace% x.1) (TangentSpace% x.2)) := (hasMFDerivAt_snd x).hasMFDerivWithinAt theorem mdifferentiableAt_snd {x : M × M'} : MDiffAt (@Prod.snd M M') x := @@ -371,13 +371,13 @@ theorem mdifferentiableOn_snd {s : Set (M × M')} : MDiff[s] (@Prod.snd M M') := @[simp, mfld_simps] theorem mfderiv_snd {x : M × M'} : mfderiv% (@Prod.snd M M') x = - ContinuousLinearMap.snd 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2) := + ContinuousLinearMap.snd 𝕜 (TangentSpace% x.1) (TangentSpace% x.2) := (hasMFDerivAt_snd x).mfderiv theorem mfderivWithin_snd {s : Set (M × M')} {x : M × M'} (hxs : UniqueMDiffWithinAt (I.prod I') s x) : mfderiv[s] (@Prod.snd M M') x = - ContinuousLinearMap.snd 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2) := by + ContinuousLinearMap.snd 𝕜 (TangentSpace% x.1) (TangentSpace% x.2) := by rw [MDifferentiable.mfderivWithin mdifferentiableAt_snd hxs]; exact mfderiv_snd theorem MDifferentiableWithinAt.fst {f : N → M × M'} {s : Set N} {x : N} @@ -481,9 +481,9 @@ theorem MDifferentiable.prodMap (hf : MDiff f) (hg : MDiff g) : MDiff (Prod.map set_option backward.isDefEq.respectTransparency false in lemma HasMFDerivWithinAt.prodMap {s : Set <| M × M'} {p : M × M'} {f : M → N} {g : M' → N'} - {df : TangentSpace I p.1 →L[𝕜] TangentSpace J (f p.1)} + {df : TangentSpace% p.1 →L[𝕜] TangentSpace% (f p.1)} (hf : HasMFDerivAt[Prod.fst '' s] f p.1 df) - {dg : TangentSpace I' p.2 →L[𝕜] TangentSpace J' (g p.2)} + {dg : TangentSpace% p.2 →L[𝕜] TangentSpace% (g p.2)} (hg : HasMFDerivAt[Prod.snd '' s] g p.2 dg) : HasMFDerivAt[s] (Prod.map f g) p (df.prodMap dg) := by refine ⟨hf.1.prodMap hg.1 |>.mono (by grind), ?_⟩ @@ -501,8 +501,8 @@ lemma HasMFDerivWithinAt.prodMap {s : Set <| M × M'} {p : M × M'} {f : M → N set_option backward.isDefEq.respectTransparency false in lemma HasMFDerivAt.prodMap {p : M × M'} {f : M → N} {g : M' → N'} - {df : TangentSpace I p.1 →L[𝕜] TangentSpace J (f p.1)} (hf : HasMFDerivAt% f p.1 df) - {dg : TangentSpace I' p.2 →L[𝕜] TangentSpace J' (g p.2)} (hg : HasMFDerivAt% g p.2 dg) : + {df : TangentSpace% p.1 →L[𝕜] TangentSpace% (f p.1)} (hf : HasMFDerivAt% f p.1 df) + {dg : TangentSpace% p.2 →L[𝕜] TangentSpace% (g p.2)} (hg : HasMFDerivAt% g p.2 dg) : HasMFDerivAt% (Prod.map f g) p ((mfderiv% f p.1).prodMap (mfderiv% g p.2)) := by simp_rw [← hasMFDerivWithinAt_univ, ← mfderivWithin_univ, ← univ_prod_univ] @@ -535,12 +535,12 @@ end prodMap @[simp, mfld_simps] theorem tangentMap_prodSnd {p : TangentBundle (I.prod I') (M × M')} : - tangentMap (I.prod I') I' Prod.snd p = ⟨p.proj.2, p.2.2⟩ := by + tangentMap% (@Prod.snd M M') p = ⟨p.proj.2, p.2.2⟩ := by simp [tangentMap]; rfl theorem tangentMapWithin_prodSnd {s : Set (M × M')} {p : TangentBundle (I.prod I') (M × M')} (hs : UniqueMDiffWithinAt (I.prod I') s p.proj) : - tangentMapWithin (I.prod I') I' Prod.snd s p = ⟨p.proj.2, p.2.2⟩ := by + tangentMap[s] (@Prod.snd M M') p = ⟨p.proj.2, p.2.2⟩ := by simp only [tangentMapWithin] rw [mfderivWithin_snd hs] rcases p with ⟨⟩; rfl @@ -551,24 +551,25 @@ alias MDifferentiableAt.mfderiv_prod := mfderiv_prodMk set_option backward.isDefEq.respectTransparency false in theorem mfderiv_prod_left {x₀ : M} {y₀ : M'} : mfderiv% (fun (x : M) ↦ (x, y₀)) x₀ = - ContinuousLinearMap.inl 𝕜 (TangentSpace I x₀) (TangentSpace I' y₀) := by + ContinuousLinearMap.inl 𝕜 (TangentSpace% x₀) (TangentSpace% y₀) := by refine (mdifferentiableAt_id.mfderiv_prod mdifferentiableAt_const).trans ?_ rw [mfderiv_id, mfderiv_const, ContinuousLinearMap.inl] +-- TODO: better error when the type of x is left open theorem tangentMap_prod_left {p : TangentBundle I M} {y₀ : M'} : - tangentMap I (I.prod I') (fun x ↦ (x, y₀)) p = ⟨(p.1, y₀), (p.2, 0)⟩ := by + tangentMap% (fun (x : M) ↦ (x, y₀)) p = ⟨(p.1, y₀), (p.2, 0)⟩ := by simp only [tangentMap, mfderiv_prod_left, TotalSpace.mk_inj] rfl set_option backward.isDefEq.respectTransparency false in theorem mfderiv_prod_right {x₀ : M} {y₀ : M'} : mfderiv% (fun (y : M') ↦ (x₀, y)) y₀ = - ContinuousLinearMap.inr 𝕜 (TangentSpace I x₀) (TangentSpace I' y₀) := by + ContinuousLinearMap.inr 𝕜 (TangentSpace% x₀) (TangentSpace% y₀) := by refine (mdifferentiableAt_const.mfderiv_prod mdifferentiableAt_id).trans ?_ rw [mfderiv_id, mfderiv_const, ContinuousLinearMap.inr] theorem tangentMap_prod_right {p : TangentBundle I' M'} {x₀ : M} : - tangentMap I' (I.prod I') (fun y ↦ (x₀, y)) p = ⟨(x₀, p.1), (0, p.2)⟩ := by + tangentMap% (fun (y : M') ↦ (x₀, y)) p = ⟨(x₀, p.1), (0, p.2)⟩ := by simp only [tangentMap, mfderiv_prod_right, TotalSpace.mk_inj] rfl @@ -596,9 +597,9 @@ theorem mfderiv_prod_eq_add {f : M × M' → M''} {p : M × M'} theorem mfderiv_prod_eq_add_comp {f : M × M' → M''} {p : M × M'} (hf : MDiffAt f p) : mfderiv% f p = (mfderiv% (fun z : M ↦ f (z, p.2)) p.1) ∘L (id (ContinuousLinearMap.fst 𝕜 E E') : - (TangentSpace (I.prod I') p) →L[𝕜] (TangentSpace I p.1)) + + (TangentSpace% p) →L[𝕜] (TangentSpace% p.1)) + (mfderiv% (fun z : M' ↦ f (p.1, z)) p.2) ∘L (id (ContinuousLinearMap.snd 𝕜 E E') : - (TangentSpace (I.prod I') p) →L[𝕜] (TangentSpace I' p.2)) := by + (TangentSpace% p) →L[𝕜] (TangentSpace% p.2)) := by rw [mfderiv_prod_eq_add hf] congr · have : (fun z : M × M' ↦ f (z.1, p.2)) = (fun z : M ↦ f (z, p.2)) ∘ Prod.fst := rfl @@ -617,7 +618,7 @@ theorem mfderiv_prod_eq_add_comp {f : M × M' → M''} {p : M × M'} (hf : MDiff /-- The total derivative of a function in two variables is the sum of the partial derivatives. Note that to state this (without casts) we need to be able to see through the definition of `TangentSpace`. Version in terms of the one-variable derivatives. -/ -theorem mfderiv_prod_eq_add_apply {f : M × M' → M''} {p : M × M'} {v : TangentSpace (I.prod I') p} +theorem mfderiv_prod_eq_add_apply {f : M × M' → M''} {p : M × M'} {v : TangentSpace% p} (hf : MDiffAt f p) : mfderiv% f p v = mfderiv% (fun z : M ↦ f (z, p.2)) p.1 v.1 + mfderiv% (fun z : M' ↦ f (p.1, z)) p.2 v.2 := by @@ -662,7 +663,7 @@ lemma writtenInExtChartAt_sumSwap_eventuallyEq_id : exact (chartAt H x).open_target.mem_nhds (by simp) theorem hasMFDerivAt_sumSwap : - HasMFDerivAt% (@Sum.swap M M') p (ContinuousLinearMap.id 𝕜 (TangentSpace I p)) := by + HasMFDerivAt% (@Sum.swap M M') p (ContinuousLinearMap.id 𝕜 (TangentSpace% p)) := by refine ⟨by fun_prop, ?_⟩ apply (hasFDerivWithinAt_id _ (range I)).congr_of_eventuallyEq · exact writtenInExtChartAt_sumSwap_eventuallyEq_id @@ -671,12 +672,12 @@ theorem hasMFDerivAt_sumSwap : @[simp] theorem mfderivWithin_sumSwap {s : Set (M ⊕ M')} (hs : UniqueMDiffWithinAt I s p) : - mfderiv[s] (@Sum.swap M M') p = ContinuousLinearMap.id 𝕜 (TangentSpace I p) := + mfderiv[s] (@Sum.swap M M') p = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := hasMFDerivAt_sumSwap.hasMFDerivWithinAt.mfderivWithin hs @[simp] theorem mfderiv_sumSwap : - mfderiv% (@Sum.swap M M') p = ContinuousLinearMap.id 𝕜 (TangentSpace I p) := by + mfderiv% (@Sum.swap M M') p = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := by simpa [mfderivWithin_univ] using (mfderivWithin_sumSwap (uniqueMDiffWithinAt_univ I)) variable {f : M → N} (g : M' → N') {q : M} {q' : M'} @@ -706,7 +707,7 @@ lemma writtenInExtChartAt_sumInr_eventuallyEq_id : (chartAt H q').right_inv (by simpa [Set.mem_preimage, I.left_inv] using hyT)] theorem hasMFDerivWithinAt_inl : - HasMFDerivAt[s] (@Sum.inl M M') q (ContinuousLinearMap.id 𝕜 (TangentSpace I q)) := by + HasMFDerivAt[s] (@Sum.inl M M') q (ContinuousLinearMap.id 𝕜 (TangentSpace% q)) := by refine ⟨by fun_prop, ?_⟩ have : (writtenInExtChartAt I I q (@Sum.inl M M')) =ᶠ[𝓝[(extChartAt I q).symm ⁻¹' s ∩ Set.range I] (extChartAt I q q)] id := @@ -715,11 +716,11 @@ theorem hasMFDerivWithinAt_inl : (by simp [writtenInExtChartAt, extChartAt]) theorem hasMFDerivAt_inl : - HasMFDerivAt% (@Sum.inl M M') q (ContinuousLinearMap.id 𝕜 (TangentSpace I p)) := by + HasMFDerivAt% (@Sum.inl M M') q (ContinuousLinearMap.id 𝕜 (TangentSpace% p)) := by simpa [HasMFDerivAt, hasMFDerivWithinAt_univ] using! hasMFDerivWithinAt_inl (s := Set.univ) theorem hasMFDerivWithinAt_inr {t : Set M'} : - HasMFDerivAt[t] (@Sum.inr M M') q' (ContinuousLinearMap.id 𝕜 (TangentSpace I q')) := by + HasMFDerivAt[t] (@Sum.inr M M') q' (ContinuousLinearMap.id 𝕜 (TangentSpace% q')) := by refine ⟨by fun_prop, ?_⟩ have : (writtenInExtChartAt I I q' (@Sum.inr M M')) =ᶠ[𝓝[(extChartAt I q').symm ⁻¹' t ∩ Set.range I] (extChartAt I q' q')] id := @@ -728,23 +729,23 @@ theorem hasMFDerivWithinAt_inr {t : Set M'} : (by simp [writtenInExtChartAt, extChartAt]) theorem hasMFDerivAt_inr : - HasMFDerivAt% (@Sum.inr M M') q' (ContinuousLinearMap.id 𝕜 (TangentSpace I p)) := by + HasMFDerivAt% (@Sum.inr M M') q' (ContinuousLinearMap.id 𝕜 (TangentSpace% p)) := by simpa [HasMFDerivAt, hasMFDerivWithinAt_univ] using! hasMFDerivWithinAt_inr (t := Set.univ) theorem mfderivWithin_sumInl (hU : UniqueMDiffWithinAt I s q) : - mfderiv[s] (@Sum.inl M M') q = ContinuousLinearMap.id 𝕜 (TangentSpace I p) := + mfderiv[s] (@Sum.inl M M') q = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := hasMFDerivWithinAt_inl.mfderivWithin hU theorem mfderiv_sumInl : - mfderiv% (@Sum.inl M M') q = ContinuousLinearMap.id 𝕜 (TangentSpace I p) := by + mfderiv% (@Sum.inl M M') q = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := by simpa [mfderivWithin_univ] using (mfderivWithin_sumInl (uniqueMDiffWithinAt_univ I)) theorem mfderivWithin_sumInr {t : Set M'} (hU : UniqueMDiffWithinAt I t q') : - mfderiv[t] (@Sum.inr M M') q' = ContinuousLinearMap.id 𝕜 (TangentSpace I q') := + mfderiv[t] (@Sum.inr M M') q' = ContinuousLinearMap.id 𝕜 (TangentSpace% q') := hasMFDerivWithinAt_inr.mfderivWithin hU theorem mfderiv_sumInr : - mfderiv% (@Sum.inr M M') q' = ContinuousLinearMap.id 𝕜 (TangentSpace I q') := by + mfderiv% (@Sum.inr M M') q' = ContinuousLinearMap.id 𝕜 (TangentSpace% q') := by simpa [mfderivWithin_univ] using (mfderivWithin_sumInr (uniqueMDiffWithinAt_univ I)) end disjointUnion @@ -760,7 +761,7 @@ canonical, but in this case (the tangent space of a vector space) it is canonica section Group -variable {z : M} {f g : M → E'} {f' g' : TangentSpace I z →L[𝕜] E'} +variable {z : M} {f g : M → E'} {f' g' : TangentSpace% z →L[𝕜] E'} theorem HasMFDerivWithinAt.add {s : Set M} (hf : HasMFDerivAt[s] f z f') (hg : HasMFDerivAt[s] g z g') : @@ -788,18 +789,18 @@ theorem MDifferentiable.add (hf : MDiff f) (hg : MDiff g) : MDiff (f + g) := -- Deprecate all these lemmas in favour of a version using `mvfderiv(Within)` -- Porting note: forcing types using `by exact` theorem mfderiv_add (hf : MDiffAt f z) (hg : MDiffAt g z) : - (mfderiv% (f + g) z : TangentSpace I z →L[𝕜] E') = + (mfderiv% (f + g) z : TangentSpace% z →L[𝕜] E') = (by exact mfderiv% f z) + (by exact mfderiv% g z) := (hf.hasMFDerivAt.add hg.hasMFDerivAt).mfderiv theorem mfderivWithin_add (hf : MDiffAt[s] f z) (hg : MDiffAt[s] g z) (hs : UniqueMDiffWithinAt I s z) : - (mfderiv[s] (f + g) z : TangentSpace I z →L[𝕜] E') = + (mfderiv[s] (f + g) z : TangentSpace% z →L[𝕜] E') = (by exact mfderiv[s] f z) + (by exact mfderiv[s] g z) := (hf.hasMFDerivWithinAt.add hg.hasMFDerivWithinAt).mfderivWithin hs section sum -variable {ι : Type} {t : Finset ι} {f : ι → M → E'} {f' : ι → TangentSpace I z →L[𝕜] E'} +variable {ι : Type} {t : Finset ι} {f : ι → M → E'} {f' : ι → TangentSpace% z →L[𝕜] E'} lemma HasMFDerivWithinAt.sum (hf : ∀ i ∈ t, HasMFDerivAt[s] (f i) z (f' i)) : HasMFDerivAt[s] (∑ i ∈ t, f i) z (∑ i ∈ t, f' i) := by @@ -914,12 +915,12 @@ theorem MDifferentiable.sub (hf : MDiff f) (hg : MDiff g) : MDiff (f - g) := theorem mfderivWithin_sub (hf : MDiffAt[s] f z) (hg : MDiffAt[s] g z) (hs : UniqueMDiffWithinAt I s z) : - (mfderiv[s] (f - g) z : TangentSpace I z →L[𝕜] E') = + (mfderiv[s] (f - g) z : TangentSpace% z →L[𝕜] E') = (by exact mfderiv[s] f z) - (by exact mfderiv[s] g z) := (hf.hasMFDerivWithinAt.sub hg.hasMFDerivWithinAt).mfderivWithin hs theorem mfderiv_sub (hf : MDiffAt f z) (hg : MDiffAt g z) : - (mfderiv% (f - g) z : TangentSpace I z →L[𝕜] E') = + (mfderiv% (f - g) z : TangentSpace% z →L[𝕜] E') = (by exact mfderiv% f z) - (by exact mfderiv% g z) := (hf.hasMFDerivAt.sub hg.hasMFDerivAt).mfderiv @@ -929,7 +930,7 @@ section AlgebraOverRing open scoped RightActions variable {z : M} {F' : Type*} [NormedRing F'] [NormedAlgebra 𝕜 F'] {p q : M → F'} - {p' q' : TangentSpace I z →L[𝕜] F'} + {p' q' : TangentSpace% z →L[𝕜] F'} theorem HasMFDerivWithinAt.mul' (hp : HasMFDerivWithinAt I 𝓘(𝕜, F') p s z p') (hq : HasMFDerivWithinAt I 𝓘(𝕜, F') q s z q') : @@ -979,7 +980,7 @@ end AlgebraOverRing section AlgebraOverCommRing variable {z : M} {F' : Type*} [NormedCommRing F'] [NormedAlgebra 𝕜 F'] {p q : M → F'} - {p' q' : TangentSpace I z →L[𝕜] F'} + {p' q' : TangentSpace% z →L[𝕜] F'} set_option backward.isDefEq.respectTransparency false in theorem HasMFDerivWithinAt.mul (hp : HasMFDerivWithinAt I 𝓘(𝕜, F') p s z p') @@ -993,7 +994,7 @@ theorem HasMFDerivAt.mul (hp : HasMFDerivAt I 𝓘(𝕜, F') p z p') hasMFDerivWithinAt_univ.mp <| hp.hasMFDerivWithinAt.mul hq.hasMFDerivWithinAt section prod -variable {ι : Type} {t : Finset ι} {f : ι → M → F'} {f' : ι → TangentSpace I z →L[𝕜] F'} +variable {ι : Type} {t : Finset ι} {f : ι → M → F'} {f' : ι → TangentSpace% z →L[𝕜] F'} set_option backward.isDefEq.respectTransparency false in lemma HasMFDerivWithinAt.prod [DecidableEq ι] @@ -1046,7 +1047,7 @@ section DivisionRing open scoped RightActions variable {z : M} {F' : Type*} [NormedDivisionRing F'] [NormedAlgebra 𝕜 F'] {p q : M → F'} - {p' q' : TangentSpace I z →L[𝕜] F'} + {p' q' : TangentSpace% z →L[𝕜] F'} lemma HasMFDerivWithinAt.inv' (hp : HasMFDerivWithinAt I 𝓘(𝕜, F') p s z p') (hp_ne : p z ≠ 0) : HasMFDerivWithinAt I 𝓘(𝕜, F') (p⁻¹) s z (-((p z)⁻¹ •> p' <• (p z)⁻¹) : E →L[𝕜] F') := @@ -1097,7 +1098,7 @@ end DivisionRing section Field variable {z : M} {F' : Type*} [NormedField F'] [NormedAlgebra 𝕜 F'] {p q : M → F'} - {p' q' : TangentSpace I z →L[𝕜] F'} + {p' q' : TangentSpace% z →L[𝕜] F'} lemma HasMFDerivWithinAt.inv (hp : HasMFDerivWithinAt I 𝓘(𝕜, F') p s z p') (hp_ne : p z ≠ 0) : HasMFDerivWithinAt I 𝓘(𝕜, F') (p⁻¹) s z (-(p z ^ 2)⁻¹ • p' : E →L[𝕜] F') := by diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean index bbde671e83da07..ea2f7fa9b139b9 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean @@ -35,7 +35,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] /-- The derivative of the chart at a base point is the chart of the tangent bundle, composed with the identification between the tangent bundle of the model space and the product space. -/ theorem tangentMap_chart {p q : TangentBundle I M} (h : q.1 ∈ (chartAt H p.1).source) : - tangentMap I I (chartAt H p.1) q = + tangentMap% (chartAt H p.1) q = (TotalSpace.toProd _ _).symm ((chartAt (ModelProd H E) p : TangentBundle I M → ModelProd H E) q) := by dsimp [tangentMap] @@ -48,7 +48,7 @@ tangent bundle, composed with the identification between the tangent bundle of t the product space. -/ theorem tangentMap_chart_symm {p : TangentBundle I M} {q : TangentBundle I H} (h : q.1 ∈ (chartAt H p.1).target) : - tangentMap I I (chartAt H p.1).symm q = + tangentMap% (chartAt H p.1).symm q = (chartAt (ModelProd H E) p).symm (TotalSpace.toProd H E q) := by dsimp only [tangentMap] rw [MDifferentiableAt.mfderiv (mdifferentiableAt_atlas_symm (chart_mem_atlas _ _) h)] @@ -74,7 +74,7 @@ postcomposing it with derivatives of extended charts. Concrete version of `inTangentCoordinates_eq`. -/ lemma inTangentCoordinates_eq_mfderiv_comp {N : Type*} {f : N → M} {g : N → M'} - {ϕ : Π x : N, TangentSpace I (f x) →L[𝕜] TangentSpace I' (g x)} {x₀ : N} {x : N} + {ϕ : Π x : N, TangentSpace% (f x) →L[𝕜] TangentSpace% (g x)} {x₀ : N} {x : N} (hx : f x ∈ (chartAt H (f x₀)).source) (hy : g x ∈ (chartAt H' (g x₀)).source) : inTangentCoordinates I I' f g ϕ x₀ x = (mfderiv% (extChartAt I' (g x₀)) (g x)) ∘L (ϕ x) ∘L diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index cc7ede9c610b4d..24e6737558c2c5 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -37,6 +37,9 @@ including inference of the model with corners. | `mfderiv% f x` | `mfderiv I J f x` | | `HasMFDerivAt[s] f x f'` | `HasMFDerivWithinAt I J f s x f'` | | `HasMFDerivAt% f x f'` | `HasMFDerivAt I J f x f'` | +| `TangentSpace% x` | `TangentSpace I x` | +| `tangentMap[s] f` | `tangentMapWithin I J f s` | +| `tangentMap% f` | `tangentMap I J f` | In each of these cases, the models with corners are inferred from the domain and codomain of `f`. The search for models with corners uses the local context and is (almost) only based on expression @@ -941,6 +944,29 @@ scoped elab:max "HasMFDerivAt%" ppSpace let (srcI, tgtI) ← findModels ef none mkAppM ``HasMFDerivAt #[srcI, tgtI, ef, ex, ef'] +/-- `TangentSpace% x` elaborates to `TangentSpace I x`, +trying to determine `I` from the local context. -/ +scoped elab:max "TangentSpace%" ppSpace x:term:arg : term => do + let ex ← Term.elabTerm x none + let extype ← instantiateMVars <| ← inferType ex + let src ← findModel extype + mkAppM ``TangentSpace #[src, ex] + +/-- `tangentMap[s] f` elaborates to `tangentMapWithin I J f s`, +trying to determine `I` and `J` from the local context. -/ +scoped elab:max "tangentMap[" s:term "]" ppSpace f:term:arg : term => do + let es ← Term.elabTerm s none + let ef ← ensureIsFunction <|← Term.elabTerm f none + let (srcI, tgtI) ← findModels ef none + mkAppM ``tangentMapWithin #[srcI, tgtI, ef, es] + +/-- `tangentMap% f` elaborates to `tangentMap I J f`, +trying to determine `I` and `J` from the local context. -/ +scoped elab:max "tangentMap%" ppSpace f:term:arg : term => do + let ef ← ensureIsFunction <|← Term.elabTerm f none + let (srcI, tgtI) ← findModels ef none + mkAppM ``tangentMap #[srcI, tgtI, ef] + end Manifold section trace diff --git a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean index aac89e42f29fcd..7ddda591cfd451 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean @@ -66,7 +66,7 @@ variable section variable [PseudoEMetricSpace M] [ChartedSpace H M] - [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + [RiemannianBundle (fun (x : M) ↦ TangentSpace% x)] variable (I M) in /-- Consider a manifold in which the tangent spaces are already endowed with an inner product, and @@ -101,7 +101,7 @@ variable (F) in /-- The standard Riemannian metric on a vector space with an inner product, given by this inner product on each tangent space. -/ noncomputable def riemannianMetricVectorSpace : - ContMDiffRiemannianMetric 𝓘(ℝ, F) ω F (fun (x : F) ↦ TangentSpace 𝓘(ℝ, F) x) where + ContMDiffRiemannianMetric 𝓘(ℝ, F) ω F (fun (x : F) ↦ TangentSpace% x) where inner x := (innerSL ℝ (E := F) : F →L[ℝ] F →L[ℝ] ℝ) symm x v w := real_inner_comm _ _ pos x v hv := real_inner_self_pos.2 hv @@ -123,19 +123,19 @@ noncomputable def riemannianMetricVectorSpace : ext v w simp [hom_trivializationAt_apply, ContinuousLinearMap.inCoordinates, TangentSpace] -noncomputable instance : RiemannianBundle (fun (x : F) ↦ TangentSpace 𝓘(ℝ, F) x) := +noncomputable instance : RiemannianBundle (fun (x : F) ↦ TangentSpace% x) := ⟨(riemannianMetricVectorSpace F).toRiemannianMetric⟩ set_option backward.isDefEq.respectTransparency false in -lemma norm_tangentSpace_vectorSpace {x : F} {v : TangentSpace 𝓘(ℝ, F) x} : +lemma norm_tangentSpace_vectorSpace {x : F} {v : TangentSpace% x} : ‖v‖ = ‖letI V : F := v; V‖ := by rw [norm_eq_sqrt_real_inner, norm_eq_sqrt_real_inner] -lemma nnnorm_tangentSpace_vectorSpace {x : F} {v : TangentSpace 𝓘(ℝ, F) x} : +lemma nnnorm_tangentSpace_vectorSpace {x : F} {v : TangentSpace% x} : ‖v‖₊ = ‖letI V : F := v; V‖₊ := by simp [nnnorm, norm_tangentSpace_vectorSpace] -lemma enorm_tangentSpace_vectorSpace {x : F} {v : TangentSpace 𝓘(ℝ, F) x} : +lemma enorm_tangentSpace_vectorSpace {x : F} {v : TangentSpace% x} : ‖v‖ₑ = ‖letI V : F := v; V‖ₑ := by simp [enorm, nnnorm_tangentSpace_vectorSpace] @@ -210,8 +210,8 @@ the image of the neighborhood in the extended chart. open Manifold Metric open scoped NNReal -variable [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] - [IsManifold I 1 M] [IsContinuousRiemannianBundle E (fun (x : M) ↦ TangentSpace I x)] +variable [RiemannianBundle (fun (x : M) ↦ TangentSpace% x)] + [IsManifold I 1 M] [IsContinuousRiemannianBundle E (fun (x : M) ↦ TangentSpace% x)] /-- Register on the tangent space to a normed vector space the same `NormedAddCommGroup` structure as in the vector space. @@ -220,7 +220,7 @@ Should not be a global instance, as it does not coincide definitionally with the structure for inner product spaces, but can be activated locally. -/ @[instance_reducible] def normedAddCommGroupTangentSpaceVectorSpace (x : E) : - NormedAddCommGroup (TangentSpace 𝓘(ℝ, E) x) := + NormedAddCommGroup (TangentSpace% x) := inferInstanceAs (NormedAddCommGroup E) attribute [local instance] normedAddCommGroupTangentSpaceVectorSpace @@ -231,7 +231,7 @@ as in the vector space. Should not be a global instance, as it does not coincide definitionally with the Riemannian structure for inner product spaces, but can be activated locally. -/ @[instance_reducible] -def normedSpaceTangentSpaceVectorSpace (x : E) : NormedSpace ℝ (TangentSpace 𝓘(ℝ, E) x) := +def normedSpaceTangentSpaceVectorSpace (x : E) : NormedSpace ℝ (TangentSpace% x) := inferInstanceAs (NormedSpace ℝ E) attribute [local instance] normedSpaceTangentSpaceVectorSpace @@ -241,7 +241,7 @@ variable (I) set_option backward.isDefEq.respectTransparency false in lemma eventually_norm_mfderiv_extChartAt_lt (x : M) : ∃ C > 0, ∀ᶠ y in 𝓝 x, ‖mfderiv% (extChartAt I x) y‖ < C := by - rcases eventually_norm_trivializationAt_lt E (fun (x : M) ↦ TangentSpace I x) x + rcases eventually_norm_trivializationAt_lt E (fun (x : M) ↦ TangentSpace% x) x with ⟨C, C_pos, hC⟩ refine ⟨C, C_pos, ?_⟩ have hx : (chartAt H x).source ∈ 𝓝 x := chart_source_mem_nhds H x @@ -262,7 +262,7 @@ lemma eventually_enorm_mfderiv_extChartAt_lt (x : M) : set_option backward.isDefEq.respectTransparency false in lemma eventually_norm_mfderivWithin_symm_extChartAt_comp_lt (x : M) : ∃ C > 0, ∀ᶠ y in 𝓝 x, ‖mfderiv[range I] (extChartAt I x).symm (extChartAt I x y)‖ < C := by - rcases eventually_norm_symmL_trivializationAt_lt E (fun (x : M) ↦ TangentSpace I x) x + rcases eventually_norm_symmL_trivializationAt_lt E (fun (x : M) ↦ TangentSpace% x) x with ⟨C, C_pos, hC⟩ refine ⟨C, C_pos, ?_⟩ have hx : (chartAt H x).source ∈ 𝓝 x := chart_source_mem_nhds H x diff --git a/Mathlib/Geometry/Manifold/Riemannian/PathELength.lean b/Mathlib/Geometry/Manifold/Riemannian/PathELength.lean index bc1507a2f8fa13..f41e39caaafe9b 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/PathELength.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/PathELength.lean @@ -50,7 +50,7 @@ variable namespace Manifold -variable [∀ (x : M), ENorm (TangentSpace I x)] {a b c a' b' : ℝ} {γ γ' : ℝ → M} +variable [∀ (x : M), ENorm (TangentSpace% x)] {a b c a' b' : ℝ} {γ γ' : ℝ → M} variable (I) in /-- The length on `Icc a b` of a path into a manifold, where the path is defined on the whole real @@ -131,7 +131,7 @@ lemma lintegral_norm_mfderiv_Icc_eq_pathELength_projIcc {a b : ℝ} open MeasureTheory -variable [∀ (x : M), ENormSMulClass ℝ (TangentSpace I x)] +variable [∀ (x : M), ENormSMulClass ℝ (TangentSpace% x)] set_option backward.isDefEq.respectTransparency false in /-- The length of a path in a manifold is invariant under a monotone reparametrization. -/ @@ -158,7 +158,7 @@ lemma pathELength_comp_of_monotoneOn {f : ℝ → ℝ} (h : a ≤ b) (hf : Monot exact uniqueDiffOn_Icc h _ ht rw [this] simp only [Function.comp_apply, ContinuousLinearMap.comp_apply] - have : mfderiv[Icc a b] f t 1 = derivWithin f (Icc a b) t • (1 : TangentSpace 𝓘(ℝ) (f t)) := by + have : mfderiv[Icc a b] f t 1 = derivWithin f (Icc a b) t • (1 : TangentSpace% (f t)) := by simp only [mfderivWithin_eq_fderivWithin, ← fderivWithin_derivWithin, smul_eq_mul, mul_one] rfl rw [this] @@ -191,7 +191,7 @@ lemma pathELength_comp_of_antitoneOn {f : ℝ → ℝ} (h : a ≤ b) (hf : Antit rw [this] simp only [Function.comp_apply, ContinuousLinearMap.comp_apply] have : mfderiv[Icc a b] f t 1 - = derivWithin f (Icc a b) t • (1 : TangentSpace 𝓘(ℝ) (f t)) := by + = derivWithin f (Icc a b) t • (1 : TangentSpace% (f t)) := by simp only [mfderivWithin_eq_fderivWithin, ← fderivWithin_derivWithin, smul_eq_mul, mul_one] rfl rw [this] @@ -242,7 +242,7 @@ lemma riemannianEDist_le_pathELength {γ : ℝ → M} (hγ : CMDiff[Icc a b] 1 · simpa [η, ContinuousAffineMap.coe_lineMap_eq] using hγ.mdifferentiableOn one_ne_zero · apply (AffineMap.lineMap_mono hab).monotoneOn -omit [∀ (x : M), ENormSMulClass ℝ (TangentSpace I x)] in +omit [∀ (x : M), ENormSMulClass ℝ (TangentSpace% x)] in /-- If some `r` is strictly larger than the Riemannian edistance between two points, there exists a path between these two points of length `< r`. Here, we get such a path on `[0, 1]`. For a more precise version giving locally constant paths around the endpoints, see diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index d3dca3611b0892..0e44b40be93d8c 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -308,7 +308,7 @@ variable [∀ _b, Zero (E _b)] {K : Type U} [FunLike K B' B] [ContinuousMapClass noncomputable def Bundle.Trivialization.pullback (e : Trivialization F (π F E)) (f : K) : Trivialization F (π F ((f : B' → B) *ᵖ E)) where toFun z := (z.proj, (e (Pullback.lift f z)).2) - invFun y := @TotalSpace.mk _ F (f *ᵖ E) y.1 (e.symm (f y.1) y.2) + invFun y := TotalSpace.mk' F y.1 (e.symm (f y.1) y.2) source := Pullback.lift f ⁻¹' e.source baseSet := f ⁻¹' e.baseSet target := (f ⁻¹' e.baseSet) ×ˢ univ diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 2976d90b7c9fc8..862e96f248d2da 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -931,7 +931,7 @@ info: ContMDiffWithinAt (modelWithCornersSelf 𝕜 E) (modelWithCornersSelf 𝕜 end smoothness --- Inferring the type of `x` for all ContMDiff/MDifferentiable{Within}At elaborators. +/-! Inferring the type of `x` for all ContMDiff/MDifferentiable{Within}At elaborators. -/ section variable {EM' : Type*} [NormedAddCommGroup EM'] @@ -970,6 +970,33 @@ open ContDiff in -- for the ∞ notation end +/-! Tests for the elaborators for `tangentMap(Within)` and `TangentSpace` -/ +section + +variable {f : M → M} {s : Set M} {x : M} {X : TangentSpace% x} + +/-- info: TangentSpace I x : Type u_2 -/ +#guard_msgs in +#check TangentSpace% x + +/-- info: tangentMap I I f : TangentBundle I M → TangentBundle I M -/ +#guard_msgs in +#check tangentMap% f + +/-- info: tangentMapWithin I I f s : TangentBundle I M → TangentBundle I M -/ +#guard_msgs in +#check tangentMap[s] f + +/-- info: tangentMap I I f { proj := x, snd := X } : TangentBundle I M -/ +#guard_msgs in +#check tangentMap% f X + +/-- info: tangentMapWithin I I f s { proj := x, snd := X } : TangentBundle I M -/ +#guard_msgs in +#check tangentMap[s] f X + +end + /-! Products of models with corners: TODO, add lots of further tests -/ section From 0be66d77ba290828a5260d883ace636f56bce89a Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:27:20 +0000 Subject: [PATCH 0043/1300] feat: add a few basic checks for PR descriptions (#40181) Not exhaustive, but hopefully this is already useful. --- .github/workflows/build_template.yml | 17 ++++- .github/workflows/check_pr_titles.yaml | 3 +- Mathlib/Tactic/Linter/ValidatePRTitle.lean | 48 +++++++++++++ MathlibTest/ValidatePRTitle.lean | 83 +++++++++++++++++++++- scripts/check_title_labels.lean | 15 ++-- 5 files changed, 159 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 6eea0109569af5..333c646aa06c86 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -804,7 +804,22 @@ jobs: run: | lake env lean scripts/create_deprecated_modules.lean lake env lean scripts/autolabel.lean - lake exe check_title_labels --labels "t-algebra" "feat: dummy PR for testing" + lake exe check_title_labels --labels "t-algebra" "feat: dummy PR for testing" "dummy PR body" > title_output.txt + if grep -qE "Missing positional argument " "title_output.txt"; then + echo "" + echo "==============================================================================" + echo "ERROR: Your branch predates the current 'check title' configuration." + echo "Please merge 'master' into your PR branch and push again." + echo "" + echo "You can do this with:" + echo " git fetch upstream" + echo " git merge upstream/master" + echo " git push" + echo "==============================================================================" + echo "" + exit 1 + fi + cat title_output.txt - name: build everything # make sure everything is available for test/import_all.lean diff --git a/.github/workflows/check_pr_titles.yaml b/.github/workflows/check_pr_titles.yaml index edbe9058ecd2a8..491b023c9b522f 100644 --- a/.github/workflows/check_pr_titles.yaml +++ b/.github/workflows/check_pr_titles.yaml @@ -34,6 +34,7 @@ jobs: if: github.event.pull_request.draft == false && github.event.pull_request.base.ref == 'master' env: TITLE: ${{ github.event.pull_request.title }} + BODY: ${{ github.event.pull_request.body }} PR_LABELS: ${{ toJson(github.event.pull_request.labels) }} run: | set -o pipefail @@ -53,7 +54,7 @@ jobs: set +e # Capture output and exit code - output=$(lake exe check_title_labels --labels "$label_names" "$TITLE" 2>&1) + output=$(lake exe check_title_labels --labels "$label_names" "$TITLE" "$BODY" 2>&1) exit_code=$? set -e diff --git a/Mathlib/Tactic/Linter/ValidatePRTitle.lean b/Mathlib/Tactic/Linter/ValidatePRTitle.lean index feb10809e868a7..09e4f1e5f87a19 100644 --- a/Mathlib/Tactic/Linter/ValidatePRTitle.lean +++ b/Mathlib/Tactic/Linter/ValidatePRTitle.lean @@ -11,10 +11,13 @@ import Mathlib.Tactic.Linter.TextBased.UnicodeLinter /-! # Checker for well-formed title and labels + This script checks if a PR title matches [mathlib's commit conventions](https://leanprover-community.github.io/contribute/commit.html). Not all checks from the commit conventions are implemented: for instance, no effort is made to verify whether the title or body are written in present imperative tense. + +It also verifies if the PR description matches some basic sanity checks for good descriptions. -/ open Std.Internal.Parsec String @@ -136,3 +139,48 @@ public def validateTitle (title : String) : Array String := Id.run do errors := errors.push s!"error: the PR contains {badChars.length} Unicode characters \ which are not allowed: {err}" return errors + +/-- Check if `description` matches some basic checks for good PR descriptions +(a subset of the ones at , +plus a few basic sanity checks). + +`isLabelledEasy` denotes whether a PR is labelled as easy: if so, an empty description is allowed. + +Return all error messages for violations found. +-/ +public def validatePRBody (description : String) (isLabelledEasy : Bool) : Array String := Id.run do + if description.trimAscii.isEmpty && !isLabelledEasy then + return #["error: the PR description is empty"] + + -- Find all lines in the PR description before a "fold". bors truncates the squash + -- commit message at the first line starting with "---" (its `cut_body_after = "\n---"`), + -- so that is exactly what we treat as a fold here. + let before := description.lines.toList.takeWhile (fun l ↦ !l.startsWith "---") + -- If `after` is non-empty, there is a fold. + let after := description.lines.toList.drop before.length + let mut errors := #[] + if let some l := before.getLast? then + if !after.isEmpty && l != "" then + errors := errors.push + "error: there should be a blank line between the PR description and the fold" + if before.any (· == "## Summary") then + errors := errors.push "error: do not include a 'summary' header in the PR body" + if before.any (· == "## Testing plan") then + errors := errors.push "error: usually, a section 'Testing plan' is superfluous \ + (particularly if it only mentions checks done in CI anyway)\n\ + If you have done particular testing, please mention this --- but no need for the header." + -- Should this error on any headings in the PR description? + + -- Just whitespace, or a period before the fold also count as empty descriptions. + let beforeContainsText := before.any (·.any (·.isAlpha)) + if !beforeContainsText then + -- We drop the leading "---" line. + let afterContainsText := after.drop 1 |>.any (·.any (·.isAlpha)) + if afterContainsText then + errors := errors.push + "warning: your PR description is non-empty, but everything is after the '---' line\n\ + note: the final PR commit message only uses what is above that line" + else + errors := errors.push "error: the PR description is empty" + + return errors diff --git a/MathlibTest/ValidatePRTitle.lean b/MathlibTest/ValidatePRTitle.lean index aacda293a7e90d..66a9d8e9c03356 100644 --- a/MathlibTest/ValidatePRTitle.lean +++ b/MathlibTest/ValidatePRTitle.lean @@ -1,6 +1,8 @@ import Mathlib.Tactic.Linter.ValidatePRTitle --- Tests for the PR title validation logic. +/-! Tests for the PR title validation logic. -/ +section title + open Lean in /-- `#check_title title` takes as input the `String` `title`, expected to be a mathlib PR title. @@ -186,3 +188,82 @@ info: Message: 'error: the PR title contains multiple consecutive spaces; please -/ #guard_msgs in #check_title "feat(Mathlib/Algebra.lean): title." + +end title + +-- Tests for the PR description validation logic. +section description + +open Lean in +/-- +`#check_description desc` takes as input the `String` `desc`, expected to be a mathlib PR body. +It logs details of what the linter would report if the description is "malformed". +-/ +elab "#check_description " desc:str : command => do + let title := desc.getString + for err in validatePRBody title false do + logInfo m!"Message: '{err}'" + +/-- info: Message: 'error: the PR description is empty' -/ +#guard_msgs in +#check_description "" + +/-- info: Message: 'error: the PR description is empty' -/ +#guard_msgs in +#check_description " " -- whitespace only PR bodies should also get linted + +-- This description is virtually empty: just whitespace. +/-- info: Message: 'error: the PR description is empty' -/ +#guard_msgs in +#check_description "\n\n---" + +/-- info: Message: 'error: the PR description is empty' -/ +#guard_msgs in +#check_description ".\n\n---" + +/-- info: Message: 'error: there should be a blank line between the PR description and the fold' -/ +#guard_msgs in +#check_description "A word\n----\n" + +/-- info: Message: 'error: there should be a blank line between the PR description and the fold' -/ +#guard_msgs in +#check_description "A word\n----\nSome content\nAnother fold\n" + +-- Regression test against confusing errors with just a fold. +/-- info: Message: 'error: the PR description is empty' -/ +#guard_msgs in +#check_description "---" + +/-- +info: Message: 'warning: your PR description is non-empty, but everything is after the '---' line +note: the final PR commit message only uses what is above that line' +-/ +#guard_msgs in +#check_description "----\nA helpful description after the fold\n" + +/-- info: Message: 'error: do not include a 'summary' header in the PR body' -/ +#guard_msgs in +#check_description "## Summary\nSome other content\n" + +/-- +info: Message: 'error: usually, a section 'Testing plan' is superfluous (particularly if it only mentions checks done in CI anyway) +If you have done particular testing, please mention this --- but no need for the header.' +-/ +#guard_msgs in +#check_description "Some actual PR body containing useful content.\n## Testing plan\nLake build passes\n" + +/-- +info: Message: 'error: do not include a 'summary' header in the PR body' +--- +info: Message: 'error: usually, a section 'Testing plan' is superfluous (particularly if it only mentions checks done in CI anyway) +If you have done particular testing, please mention this --- but no need for the header.' +-/ +#guard_msgs in +#check_description "Some actual PR body containing useful content.\n## Testing plan\n## Summary\nLake build passes\n" + +-- Tests for false positives around a bug in recognising the "fold". +#guard_msgs in #check_description "First paragraph.\n\nSecond paragraph.\n" + +#guard_msgs in #check_description "My description.\n\n---\n\nMeta info after the fold.\n" + +end description diff --git a/scripts/check_title_labels.lean b/scripts/check_title_labels.lean index 0f3504dd51aa1f..fd82ded1e9de7c 100644 --- a/scripts/check_title_labels.lean +++ b/scripts/check_title_labels.lean @@ -21,10 +21,10 @@ open Cli in The exit code is the number of violations found. -/ def checkTitleLabelsCLI (args : Parsed) : IO UInt32 := do let title := (args.positionalArg! "title").value + let body := (args.positionalArg! "body").value let labels : List String := match args.flag? "labels" with | some f => (f.as! String).splitOn "\n" | none => [] - IO.println s!"labels are {labels}" -- We do not validate titles of WIP PRs. if labels.contains "WIP" then return 0 @@ -34,6 +34,11 @@ def checkTitleLabelsCLI (args : Parsed) : IO UInt32 := do numberErrors := UInt32.ofNat titleErrors.size for err in titleErrors do IO.println err + -- Enforce some properties of the PR description. + let descriptionErrors : Array String := validatePRBody body (labels.contains "easy") + numberErrors := numberErrors + UInt32.ofNat descriptionErrors.size + for err in descriptionErrors do + IO.println err return min numberErrors 125 open Cli in @@ -45,16 +50,18 @@ def checkTitleLabels : Cmd := `[Cli| If this PR is a feature PR, also verify that it has a topic label, and that there are no contradictory labels. - If the inpupt title does not pass validation, output a list of errors." + If the input title does not pass validation, output a list of errors." FLAGS: "labels" : String; "newline-separated list of label names of this PR\ - These are optional; we merely use a WIP label to skip any checks of the PR title" + These are optional; we use a WIP label to skip all checks, and an `easy` label \ + to skip some PR description checks" ARGS: title : String; "this PR's title" + body : String; "this PR's body" ] -/-- The entrypoint to the `lake exe check-title-labels` command. -/ +/-- The entrypoint to the `lake exe check_title_labels` command. -/ def main (args : List String) : IO UInt32 := checkTitleLabels.validate args From 2025c51063750c45d6cf959608bd46a2c596cb2e Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:40:28 +0000 Subject: [PATCH 0044/1300] feat: missing instances for RingCon (#40563) This adds all the missing commutative instances, as well as instances for when only the additive or multiplicative structure is lawful. --- Mathlib/RingTheory/Congruence/Defs.lean | 79 +++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/Mathlib/RingTheory/Congruence/Defs.lean b/Mathlib/RingTheory/Congruence/Defs.lean index 60ca0cc2e57c46..c4521330d750d4 100644 --- a/Mathlib/RingTheory/Congruence/Defs.lean +++ b/Mathlib/RingTheory/Congruence/Defs.lean @@ -339,19 +339,84 @@ The operations above on the quotient by `c : RingCon R` preserve the algebraic s section Algebraic +section Add + +instance [AddZeroClass R] [Mul R] (c : RingCon R) : AddZeroClass c.Quotient := + inferInstanceAs <| AddZeroClass c.toAddCon.Quotient + +instance [AddSemigroup R] [Mul R] (c : RingCon R) : AddSemigroup c.Quotient := + inferInstanceAs <| AddSemigroup c.toAddCon.Quotient + +instance [AddCommMagma R] [Mul R] (c : RingCon R) : AddCommMagma c.Quotient := + inferInstanceAs <| AddCommMagma c.toAddCon.Quotient + +instance [AddCommSemigroup R] [Mul R] (c : RingCon R) : AddCommSemigroup c.Quotient := + inferInstanceAs <| AddCommSemigroup c.toAddCon.Quotient + +instance [AddMonoid R] [Mul R] (c : RingCon R) : AddMonoid c.Quotient := + inferInstanceAs <| AddMonoid c.toAddCon.Quotient + +instance [AddCommMonoid R] [Mul R] (c : RingCon R) : AddCommMonoid c.Quotient := + inferInstanceAs <| AddCommMonoid c.toAddCon.Quotient + +instance [AddGroup R] [Mul R] (c : RingCon R) : AddGroup c.Quotient := + inferInstanceAs <| AddGroup c.toAddCon.Quotient + +instance [AddCommGroup R] [Mul R] (c : RingCon R) : AddCommGroup c.Quotient := + inferInstanceAs <| AddCommGroup c.toAddCon.Quotient + +end Add + +section Mul + +instance [Add R] [MulOneClass R] (c : RingCon R) : MulOneClass c.Quotient := + inferInstanceAs <| MulOneClass c.toCon.Quotient + +instance [Add R] [Semigroup R] (c : RingCon R) : Semigroup c.Quotient := + inferInstanceAs <| Semigroup c.toCon.Quotient + +instance [Add R] [CommMagma R] (c : RingCon R) : CommMagma c.Quotient := + inferInstanceAs <| CommMagma c.toCon.Quotient + +instance [Add R] [CommSemigroup R] (c : RingCon R) : CommSemigroup c.Quotient := + inferInstanceAs <| CommSemigroup c.toCon.Quotient + +instance [Add R] [Monoid R] (c : RingCon R) : Monoid c.Quotient := + inferInstanceAs <| Monoid c.toCon.Quotient + +instance [Add R] [CommMonoid R] (c : RingCon R) : CommMonoid c.Quotient := + inferInstanceAs <| CommMonoid c.toCon.Quotient + +end Mul + instance [NonUnitalNonAssocSemiring R] (c : RingCon R) : NonUnitalNonAssocSemiring c.Quotient := fast_instance% Function.Surjective.nonUnitalNonAssocSemiring _ Quotient.mk''_surjective rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl +instance [NonUnitalNonAssocCommSemiring R] (c : RingCon R) : + NonUnitalNonAssocCommSemiring c.Quotient := fast_instance% + Function.Surjective.nonUnitalNonAssocCommSemiring _ Quotient.mk''_surjective rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + instance [NonAssocSemiring R] (c : RingCon R) : NonAssocSemiring c.Quotient := fast_instance% Function.Surjective.nonAssocSemiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl +instance [NonAssocCommSemiring R] (c : RingCon R) : + NonAssocCommSemiring c.Quotient := fast_instance% + Function.Surjective.nonAssocCommSemiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + instance [NonUnitalSemiring R] (c : RingCon R) : NonUnitalSemiring c.Quotient := fast_instance% Function.Surjective.nonUnitalSemiring _ Quotient.mk''_surjective rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl +instance [NonUnitalCommSemiring R] (c : RingCon R) : + NonUnitalCommSemiring c.Quotient := fast_instance% + Function.Surjective.nonUnitalCommSemiring _ Quotient.mk''_surjective rfl (fun _ _ => rfl) + (fun _ _ => rfl) fun _ _ => rfl + instance [Semiring R] (c : RingCon R) : Semiring c.Quotient := fast_instance% Function.Surjective.semiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl @@ -365,15 +430,29 @@ instance [NonUnitalNonAssocRing R] (c : RingCon R) : Function.Surjective.nonUnitalNonAssocRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl +instance [NonUnitalNonAssocCommRing R] (c : RingCon R) : + NonUnitalNonAssocCommRing c.Quotient := fast_instance% + Function.Surjective.nonUnitalNonAssocCommRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + instance [NonAssocRing R] (c : RingCon R) : NonAssocRing c.Quotient := fast_instance% Function.Surjective.nonAssocRing _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) fun _ => rfl +instance [NonAssocCommRing R] (c : RingCon R) : NonAssocCommRing c.Quotient := fast_instance% + Function.Surjective.nonAssocCommRing _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ => rfl) fun _ => rfl + instance [NonUnitalRing R] (c : RingCon R) : NonUnitalRing c.Quotient := fast_instance% Function.Surjective.nonUnitalRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl +instance [NonUnitalCommRing R] (c : RingCon R) : NonUnitalCommRing c.Quotient := fast_instance% + Function.Surjective.nonUnitalCommRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + instance [Ring R] (c : RingCon R) : Ring c.Quotient := fast_instance% Function.Surjective.ring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) From ddd592eb364828f0a506648596c38bbf580a3165 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Mon, 15 Jun 2026 13:16:03 +0000 Subject: [PATCH 0045/1300] feat(RingTheory/Invariant/Basic): generalize `Ideal.Quotient.normal` to `IsFractionRing` (#40247) This PR generalizes `Ideal.Quotient.normal` to `IsFractionRing` (currently it only holds for quotients of maximal ideals). I have left both versions since that is the pattern of the file (to have both an `IsFractionRing` version and an `Ideal.Quotient` version). Co-authored-by: tb65536 --- .../IntegralClosure/IntegralRestrict.lean | 12 +-- Mathlib/RingTheory/Invariant/Basic.lean | 89 ++++++++++++++----- Mathlib/RingTheory/Localization/Integral.lean | 2 +- 3 files changed, 73 insertions(+), 30 deletions(-) diff --git a/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean b/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean index 4632e56e931129..a5c4644937b610 100644 --- a/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean +++ b/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean @@ -220,7 +220,7 @@ instance (priority := 900) [IsDomain A] [IsDomain B] [IsIntegrallyClosed B] IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := - isAlgebraic_of_isFractionRing (R := A) (S := B) .. + isAlgebraic_of_isFractionRing A B .. haveI : IsLocalization (Algebra.algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ @@ -262,7 +262,7 @@ def Algebra.intTrace : B →ₗ[A] A := IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := - isAlgebraic_of_isFractionRing (R := A) (S := B) .. + isAlgebraic_of_isFractionRing A B .. haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ @@ -276,7 +276,7 @@ lemma Algebra.algebraMap_intTrace (x : B) : IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := - isAlgebraic_of_isFractionRing (R := A) (S := B) .. + isAlgebraic_of_isFractionRing A B .. haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ @@ -296,7 +296,7 @@ lemma Algebra.algebraMap_intTrace_fractionRing (x : B) : IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := - isAlgebraic_of_isFractionRing (R := A) (S := B) .. + isAlgebraic_of_isFractionRing A B .. haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ @@ -310,7 +310,7 @@ lemma Algebra.intTrace_eq_trace [Module.Free A B] : Algebra.intTrace A B = Algeb IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := - isAlgebraic_of_isFractionRing (R := A) (S := B) .. + isAlgebraic_of_isFractionRing A B .. haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ apply IsFractionRing.injective A (FractionRing A) @@ -334,7 +334,7 @@ lemma Algebra.intTrace_eq_of_isLocalization IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := - isAlgebraic_of_isFractionRing (R := A) (S := B) .. + isAlgebraic_of_isFractionRing A B .. have : IsLocalization (algebraMapSubmonoid B A⁰) L := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ let f : Aₘ →+* K := IsLocalization.map _ (T := A⁰) (RingHom.id A) hM diff --git a/Mathlib/RingTheory/Invariant/Basic.lean b/Mathlib/RingTheory/Invariant/Basic.lean index dfe951fc2a6b42..83972a5c02b355 100644 --- a/Mathlib/RingTheory/Invariant/Basic.lean +++ b/Mathlib/RingTheory/Invariant/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.RingTheory.Invariant.Defs public import Mathlib.RingTheory.IntegralClosure.IntegralRestrict +public import Mathlib.RingTheory.LocalRing.ResidueField.Ideal /-! # Invariant Extensions of Rings @@ -146,6 +147,9 @@ theorem charpoly_eq_prod_smul (b : B) : charpoly G b = ∏ g : G, g • (X - C b theorem monic_charpoly (b : B) : (charpoly G b).Monic := monic_prod_of_monic _ _ (fun _ _ ↦ monic_X_sub_C _) +theorem splits_charpoly (b : B) : (charpoly G b).Splits := + .prod fun g _ ↦ .X_sub_C (g • b) + theorem eval_charpoly (b : B) : (charpoly G b).eval b = 0 := by rw [charpoly_eq, eval_prod] apply Finset.prod_eq_zero (Finset.mem_univ (1 : G)) @@ -511,41 +515,80 @@ lemma Ideal.Quotient.exists_algEquiv_fixedPoint_quotient_under refine .trans ?_ (σ.apply_symm_apply _) rw [← h₂, ← e, h₁] +namespace Ideal.IsFractionRing + +variable [P.IsPrime] [Q.IsPrime] (K L : Type*) [Field K] [Field L] [Algebra K L] + [Algebra (A ⧸ P) K] [IsFractionRing (A ⧸ P) K] [Algebra (B ⧸ Q) L] [IsFractionRing (B ⧸ Q) L] + [Algebra (A ⧸ P) L] [IsScalarTower (A ⧸ P) (B ⧸ Q) L] [IsScalarTower (A ⧸ P) K L] + +open Polynomial in +include P Q G in +lemma normal : Normal K L := by + have := Algebra.IsInvariant.isIntegral A B G + have := isAlgebraic_of_isFractionRing (A ⧸ P) (B ⧸ Q) K L + constructor + intro x + obtain ⟨x, y, hy, rfl⟩ := IsFractionRing.div_surjective (B ⧸ Q) x + obtain ⟨b, a, ha, h⟩ := (Algebra.IsAlgebraic.isAlgebraic (R := A ⧸ P) y).exists_smul_eq_mul x hy + obtain ⟨a, rfl⟩ := Quotient.mk_surjective a + obtain ⟨b, rfl⟩ := Quotient.mk_surjective b + simp_rw [← Quotient.algebraMap_eq] at * + cases nonempty_fintype G + obtain ⟨p, hp, -, h_monic⟩ := lifts_and_natDegree_eq_and_monic + (Algebra.IsInvariant.charpoly_mem_lifts A B G b) (MulSemiringAction.monic_charpoly ..) + have h_eval : p.aeval b = 0 := by + rw [← eval_map_algebraMap, hp, MulSemiringAction.eval_charpoly] + let q := p.comp (C a * X) + let d := (algebraMap (B ⧸ Q) L) x / (algebraMap (B ⧸ Q) L) y + have comm₁ : (algebraMap K L).comp (algebraMap (A ⧸ P) K) = + (algebraMap (B ⧸ Q) L).comp (algebraMap (A ⧸ P) (B ⧸ Q)) := by + simp_rw [← IsScalarTower.algebraMap_eq] + have comm₂ : (algebraMap (A ⧸ P) (B ⧸ Q)).comp (algebraMap A (A ⧸ P)) = + (algebraMap B (B ⧸ Q)).comp (algebraMap A B) := by + simp_rw [← IsScalarTower.algebraMap_eq] + replace h_eval : ((q.map (algebraMap A (A ⧸ P))).map (algebraMap (A ⧸ P) K)).aeval d = 0 := by + simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X, aeval_comp, aeval_mul, aeval_C, aeval_X, + ← RingHom.comp_apply, ← RingHom.comp_assoc, comm₁, RingHom.comp_apply, d, mul_div, ← map_mul] + rw [← Algebra.smul_def, h, map_mul, mul_div_cancel_left₀ _ (by simpa using hy), + aeval_map_algebraMap, aeval_algebraMap_apply, aeval_map_algebraMap, aeval_algebraMap_apply, + h_eval, map_zero, map_zero] + replace h_splits : (p.map (algebraMap A B)).Splits := by + rw [hp] + exact MulSemiringAction.splits_charpoly G b + refine .of_dvd ?_ ?_ (map_dvd (algebraMap K L) (minpoly.dvd K d h_eval)) + · simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X] + refine .comp_of_degree_le_one ?_ (degree_C_mul_X_le _) + rw [Polynomial.map_map, Polynomial.map_map, comm₁, RingHom.comp_assoc, comm₂, + ← RingHom.comp_assoc, ← Polynomial.map_map] + apply h_splits.map + · simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X, Polynomial.map_map] + exact mt (comp_C_mul_X_eq_zero_iff (by simpa)).mp (map_monic_ne_zero h_monic) + +include P Q in +lemma finite_of_isInvariant [SMulCommClass G A B] [Algebra.IsSeparable K L] : + Module.Finite K L := by + have : IsGalois K L := { __ := normal G P Q K L } + have := Finite.of_surjective _ (IsFractionRing.stabilizerHom_surjective G P Q K L) + apply IsGalois.finiteDimensional_of_finite + +end Ideal.IsFractionRing + attribute [local instance] Ideal.Quotient.field in include G in /-- For any domain `k` containing `B ⧸ Q`, any endomorphism of `k` can be restricted to an endomorphism of `B ⧸ Q`. -/ lemma Ideal.Quotient.normal [P.IsMaximal] [Q.IsMaximal] : - Normal (A ⧸ P) (B ⧸ Q) := by - cases subsingleton_or_nontrivial B - · cases ‹Q.IsMaximal›.ne_top (Subsingleton.elim _ _) - have := Algebra.IsInvariant.isIntegral A B G - constructor - intro x - obtain ⟨x, rfl⟩ := Ideal.Quotient.mk_surjective x - cases nonempty_fintype G - obtain ⟨p, hp, h₁, h₂⟩ := Polynomial.lifts_and_degree_eq_and_monic - (Algebra.IsInvariant.charpoly_mem_lifts A B G x) (MulSemiringAction.monic_charpoly _ _) - have H : Polynomial.aeval x p = 0 := by - rw [Polynomial.aeval_def, ← Polynomial.eval_map, hp, MulSemiringAction.eval_charpoly] - have := minpoly.dvd _ (algebraMap _ (B ⧸ Q) x) (p := p.map (algebraMap _ (A ⧸ P))) - (by rw [Polynomial.aeval_map_algebraMap, Polynomial.aeval_algebraMap_apply, H, map_zero]) - refine Polynomial.Splits.of_dvd ?_ ?_ ((Polynomial.map_dvd_map' _).mpr this) - · rw [Polynomial.map_map, ← IsScalarTower.algebraMap_eq, IsScalarTower.algebraMap_eq A B, - ← Polynomial.map_map, hp, MulSemiringAction.charpoly_eq, Polynomial.map_prod] - exact Polynomial.Splits.prod (fun _ _ ↦ (Polynomial.Splits.X_sub_C _).map _) - · exact ((h₂.map _).map _).ne_zero + Normal (A ⧸ P) (B ⧸ Q) := + IsFractionRing.normal G P Q (A ⧸ P) (B ⧸ Q) attribute [local instance] Ideal.Quotient.field in include G in /-- If the extension `B/Q` over `A/P` is separable, then it is finite dimensional. -/ lemma Ideal.Quotient.finite_of_isInvariant [P.IsMaximal] [Q.IsMaximal] [SMulCommClass G A B] [Algebra.IsSeparable (A ⧸ P) (B ⧸ Q)] : - Module.Finite (A ⧸ P) (B ⧸ Q) := by - have : IsGalois (A ⧸ P) (B ⧸ Q) := { __ := Ideal.Quotient.normal (A := A) G P Q } - have := Finite.of_surjective _ (Ideal.Quotient.stabilizerHom_surjective G P Q) - exact IsGalois.finiteDimensional_of_finite _ _ + Module.Finite (A ⧸ P) (B ⧸ Q) := + IsFractionRing.finite_of_isInvariant G P Q (A ⧸ P) (B ⧸ Q) end normal diff --git a/Mathlib/RingTheory/Localization/Integral.lean b/Mathlib/RingTheory/Localization/Integral.lean index 8ad6870f80e83f..8d608d1116c9c8 100644 --- a/Mathlib/RingTheory/Localization/Integral.lean +++ b/Mathlib/RingTheory/Localization/Integral.lean @@ -551,7 +551,7 @@ theorem ideal_span_singleton_map_subset {L : Type*} [IsDomain R] [IsDomain S] [F end IsFractionRing open nonZeroDivisors in -lemma isAlgebraic_of_isFractionRing {R S} (K L) [CommRing R] [CommRing S] [Field K] [CommRing L] +lemma isAlgebraic_of_isFractionRing (R S K L) [CommRing R] [CommRing S] [Field K] [CommRing L] [Algebra R S] [Algebra R K] [Algebra R L] [Algebra S L] [Algebra K L] [IsScalarTower R S L] [IsScalarTower R K L] [IsFractionRing S L] [Algebra.IsIntegral R S] : Algebra.IsAlgebraic K L := by From 24ef8a8c893173686f1ce65b5961175cd6f6413d Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 15 Jun 2026 13:35:23 +0000 Subject: [PATCH 0046/1300] fix: revert #40181 (#40630) This revert #40181: right now, any PR with empty description breaks the "check PR title" workflow. Let's revert the change while we investigate. --- .github/workflows/build_template.yml | 17 +---- .github/workflows/check_pr_titles.yaml | 3 +- Mathlib/Tactic/Linter/ValidatePRTitle.lean | 48 ------------- MathlibTest/ValidatePRTitle.lean | 83 +--------------------- scripts/check_title_labels.lean | 15 ++-- 5 files changed, 7 insertions(+), 159 deletions(-) diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 333c646aa06c86..6eea0109569af5 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -804,22 +804,7 @@ jobs: run: | lake env lean scripts/create_deprecated_modules.lean lake env lean scripts/autolabel.lean - lake exe check_title_labels --labels "t-algebra" "feat: dummy PR for testing" "dummy PR body" > title_output.txt - if grep -qE "Missing positional argument " "title_output.txt"; then - echo "" - echo "==============================================================================" - echo "ERROR: Your branch predates the current 'check title' configuration." - echo "Please merge 'master' into your PR branch and push again." - echo "" - echo "You can do this with:" - echo " git fetch upstream" - echo " git merge upstream/master" - echo " git push" - echo "==============================================================================" - echo "" - exit 1 - fi - cat title_output.txt + lake exe check_title_labels --labels "t-algebra" "feat: dummy PR for testing" - name: build everything # make sure everything is available for test/import_all.lean diff --git a/.github/workflows/check_pr_titles.yaml b/.github/workflows/check_pr_titles.yaml index 491b023c9b522f..edbe9058ecd2a8 100644 --- a/.github/workflows/check_pr_titles.yaml +++ b/.github/workflows/check_pr_titles.yaml @@ -34,7 +34,6 @@ jobs: if: github.event.pull_request.draft == false && github.event.pull_request.base.ref == 'master' env: TITLE: ${{ github.event.pull_request.title }} - BODY: ${{ github.event.pull_request.body }} PR_LABELS: ${{ toJson(github.event.pull_request.labels) }} run: | set -o pipefail @@ -54,7 +53,7 @@ jobs: set +e # Capture output and exit code - output=$(lake exe check_title_labels --labels "$label_names" "$TITLE" "$BODY" 2>&1) + output=$(lake exe check_title_labels --labels "$label_names" "$TITLE" 2>&1) exit_code=$? set -e diff --git a/Mathlib/Tactic/Linter/ValidatePRTitle.lean b/Mathlib/Tactic/Linter/ValidatePRTitle.lean index 09e4f1e5f87a19..feb10809e868a7 100644 --- a/Mathlib/Tactic/Linter/ValidatePRTitle.lean +++ b/Mathlib/Tactic/Linter/ValidatePRTitle.lean @@ -11,13 +11,10 @@ import Mathlib.Tactic.Linter.TextBased.UnicodeLinter /-! # Checker for well-formed title and labels - This script checks if a PR title matches [mathlib's commit conventions](https://leanprover-community.github.io/contribute/commit.html). Not all checks from the commit conventions are implemented: for instance, no effort is made to verify whether the title or body are written in present imperative tense. - -It also verifies if the PR description matches some basic sanity checks for good descriptions. -/ open Std.Internal.Parsec String @@ -139,48 +136,3 @@ public def validateTitle (title : String) : Array String := Id.run do errors := errors.push s!"error: the PR contains {badChars.length} Unicode characters \ which are not allowed: {err}" return errors - -/-- Check if `description` matches some basic checks for good PR descriptions -(a subset of the ones at , -plus a few basic sanity checks). - -`isLabelledEasy` denotes whether a PR is labelled as easy: if so, an empty description is allowed. - -Return all error messages for violations found. --/ -public def validatePRBody (description : String) (isLabelledEasy : Bool) : Array String := Id.run do - if description.trimAscii.isEmpty && !isLabelledEasy then - return #["error: the PR description is empty"] - - -- Find all lines in the PR description before a "fold". bors truncates the squash - -- commit message at the first line starting with "---" (its `cut_body_after = "\n---"`), - -- so that is exactly what we treat as a fold here. - let before := description.lines.toList.takeWhile (fun l ↦ !l.startsWith "---") - -- If `after` is non-empty, there is a fold. - let after := description.lines.toList.drop before.length - let mut errors := #[] - if let some l := before.getLast? then - if !after.isEmpty && l != "" then - errors := errors.push - "error: there should be a blank line between the PR description and the fold" - if before.any (· == "## Summary") then - errors := errors.push "error: do not include a 'summary' header in the PR body" - if before.any (· == "## Testing plan") then - errors := errors.push "error: usually, a section 'Testing plan' is superfluous \ - (particularly if it only mentions checks done in CI anyway)\n\ - If you have done particular testing, please mention this --- but no need for the header." - -- Should this error on any headings in the PR description? - - -- Just whitespace, or a period before the fold also count as empty descriptions. - let beforeContainsText := before.any (·.any (·.isAlpha)) - if !beforeContainsText then - -- We drop the leading "---" line. - let afterContainsText := after.drop 1 |>.any (·.any (·.isAlpha)) - if afterContainsText then - errors := errors.push - "warning: your PR description is non-empty, but everything is after the '---' line\n\ - note: the final PR commit message only uses what is above that line" - else - errors := errors.push "error: the PR description is empty" - - return errors diff --git a/MathlibTest/ValidatePRTitle.lean b/MathlibTest/ValidatePRTitle.lean index 66a9d8e9c03356..aacda293a7e90d 100644 --- a/MathlibTest/ValidatePRTitle.lean +++ b/MathlibTest/ValidatePRTitle.lean @@ -1,8 +1,6 @@ import Mathlib.Tactic.Linter.ValidatePRTitle -/-! Tests for the PR title validation logic. -/ -section title - +-- Tests for the PR title validation logic. open Lean in /-- `#check_title title` takes as input the `String` `title`, expected to be a mathlib PR title. @@ -188,82 +186,3 @@ info: Message: 'error: the PR title contains multiple consecutive spaces; please -/ #guard_msgs in #check_title "feat(Mathlib/Algebra.lean): title." - -end title - --- Tests for the PR description validation logic. -section description - -open Lean in -/-- -`#check_description desc` takes as input the `String` `desc`, expected to be a mathlib PR body. -It logs details of what the linter would report if the description is "malformed". --/ -elab "#check_description " desc:str : command => do - let title := desc.getString - for err in validatePRBody title false do - logInfo m!"Message: '{err}'" - -/-- info: Message: 'error: the PR description is empty' -/ -#guard_msgs in -#check_description "" - -/-- info: Message: 'error: the PR description is empty' -/ -#guard_msgs in -#check_description " " -- whitespace only PR bodies should also get linted - --- This description is virtually empty: just whitespace. -/-- info: Message: 'error: the PR description is empty' -/ -#guard_msgs in -#check_description "\n\n---" - -/-- info: Message: 'error: the PR description is empty' -/ -#guard_msgs in -#check_description ".\n\n---" - -/-- info: Message: 'error: there should be a blank line between the PR description and the fold' -/ -#guard_msgs in -#check_description "A word\n----\n" - -/-- info: Message: 'error: there should be a blank line between the PR description and the fold' -/ -#guard_msgs in -#check_description "A word\n----\nSome content\nAnother fold\n" - --- Regression test against confusing errors with just a fold. -/-- info: Message: 'error: the PR description is empty' -/ -#guard_msgs in -#check_description "---" - -/-- -info: Message: 'warning: your PR description is non-empty, but everything is after the '---' line -note: the final PR commit message only uses what is above that line' --/ -#guard_msgs in -#check_description "----\nA helpful description after the fold\n" - -/-- info: Message: 'error: do not include a 'summary' header in the PR body' -/ -#guard_msgs in -#check_description "## Summary\nSome other content\n" - -/-- -info: Message: 'error: usually, a section 'Testing plan' is superfluous (particularly if it only mentions checks done in CI anyway) -If you have done particular testing, please mention this --- but no need for the header.' --/ -#guard_msgs in -#check_description "Some actual PR body containing useful content.\n## Testing plan\nLake build passes\n" - -/-- -info: Message: 'error: do not include a 'summary' header in the PR body' ---- -info: Message: 'error: usually, a section 'Testing plan' is superfluous (particularly if it only mentions checks done in CI anyway) -If you have done particular testing, please mention this --- but no need for the header.' --/ -#guard_msgs in -#check_description "Some actual PR body containing useful content.\n## Testing plan\n## Summary\nLake build passes\n" - --- Tests for false positives around a bug in recognising the "fold". -#guard_msgs in #check_description "First paragraph.\n\nSecond paragraph.\n" - -#guard_msgs in #check_description "My description.\n\n---\n\nMeta info after the fold.\n" - -end description diff --git a/scripts/check_title_labels.lean b/scripts/check_title_labels.lean index fd82ded1e9de7c..0f3504dd51aa1f 100644 --- a/scripts/check_title_labels.lean +++ b/scripts/check_title_labels.lean @@ -21,10 +21,10 @@ open Cli in The exit code is the number of violations found. -/ def checkTitleLabelsCLI (args : Parsed) : IO UInt32 := do let title := (args.positionalArg! "title").value - let body := (args.positionalArg! "body").value let labels : List String := match args.flag? "labels" with | some f => (f.as! String).splitOn "\n" | none => [] + IO.println s!"labels are {labels}" -- We do not validate titles of WIP PRs. if labels.contains "WIP" then return 0 @@ -34,11 +34,6 @@ def checkTitleLabelsCLI (args : Parsed) : IO UInt32 := do numberErrors := UInt32.ofNat titleErrors.size for err in titleErrors do IO.println err - -- Enforce some properties of the PR description. - let descriptionErrors : Array String := validatePRBody body (labels.contains "easy") - numberErrors := numberErrors + UInt32.ofNat descriptionErrors.size - for err in descriptionErrors do - IO.println err return min numberErrors 125 open Cli in @@ -50,18 +45,16 @@ def checkTitleLabels : Cmd := `[Cli| If this PR is a feature PR, also verify that it has a topic label, and that there are no contradictory labels. - If the input title does not pass validation, output a list of errors." + If the inpupt title does not pass validation, output a list of errors." FLAGS: "labels" : String; "newline-separated list of label names of this PR\ - These are optional; we use a WIP label to skip all checks, and an `easy` label \ - to skip some PR description checks" + These are optional; we merely use a WIP label to skip any checks of the PR title" ARGS: title : String; "this PR's title" - body : String; "this PR's body" ] -/-- The entrypoint to the `lake exe check_title_labels` command. -/ +/-- The entrypoint to the `lake exe check-title-labels` command. -/ def main (args : List String) : IO UInt32 := checkTitleLabels.validate args From fabf563a7c95a166b8d7b6efca11c8b4dc9d911f Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Mon, 15 Jun 2026 14:22:22 +0000 Subject: [PATCH 0047/1300] chore: bump toolchain to v4.31.0 (#40633) Upgrade the toolchain to v4.31.0 as part of the release process of Lean. Co-authored-by: Joscha --- lake-manifest.json | 16 ++++++++-------- lean-toolchain | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 289958f5764546..1db86ab034fd85 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "744117af710b1c0400cd297c9ce91f8d0ad3a347", + "rev": "63045536fe95024e6c18fc7b48e03f506701c5bc", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "99c763c8a96d3d44fb4994e96eaa51ca4568449d", + "rev": "5c7542ed018c78194f1e2b903eaf6a792b74c03d", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b2da7698bdf22804095ea5b5007f23c09398f687", + "rev": "24b0d9dc081c5423f8eec7e866c441e5184f29d9", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "7897ea6e5cfc6522d355083bdfa798377ab35e11", + "rev": "e3cb2f741431ce31bf73549fb52316a57368b06f", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "94346b7b49c36ae871639d1434232f057c193d60", + "rev": "f46324995fca5f0483b742e4eb4daec7f4ee50d2", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "c6f7103faab35720af56784a9553733832f17349", + "rev": "fa08db58b30eb033edcdab331bba000827f9f785", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "baf3e62fbb3502305076ca077e004aea78157c63", + "rev": "92564e5770e4d09f2d86dfbf8ada1e9c715b384c", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.31.0-rc2", + "inputRev": "v4.31.0", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lean-toolchain b/lean-toolchain index e6a8c3c1fa203a..18640c8b066b18 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.31.0-rc2 +leanprover/lean4:v4.31.0 From c0477ad6b77161888036499c30cfaaeb0b50d46f Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:33:48 +0000 Subject: [PATCH 0048/1300] perf: don't import `Lean.Meta` or `Lean.Elab.Tactic` (#40625) This PR gets rid of the broad imports of `Lean.Meta`/`Lean.Elab.Tactic`, and adds them to the broad imports linter to avoid future violations. As a result, imports in some other files had to be updated. --- Mathlib/Algebra/GradedMonoid.lean | 1 - Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean | 1 - Mathlib/Tactic/Algebra/Basic.lean | 3 +-- Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean | 3 +-- Mathlib/Tactic/Linter/Header.lean | 2 +- Mathlib/Tactic/Module.lean | 2 +- Mathlib/Util/DelabNonCanonical.lean | 1 - MathlibTest/Tactic/Grind/Lint.lean | 3 +++ 8 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/GradedMonoid.lean b/Mathlib/Algebra/GradedMonoid.lean index 9cd3249feff46e..e979eb59e8d2e8 100644 --- a/Mathlib/Algebra/GradedMonoid.lean +++ b/Mathlib/Algebra/GradedMonoid.lean @@ -11,7 +11,6 @@ public import Mathlib.Algebra.Group.Submonoid.Defs public import Mathlib.Data.List.FinRange public import Mathlib.Data.SetLike.Basic public import Mathlib.Data.Sigma.Basic -public import Lean.Elab.Tactic public import Mathlib.Algebra.BigOperators.Group.Finset.Basic /-! diff --git a/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean b/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean index d4b44397882ed4..6baef24ebebd58 100644 --- a/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean +++ b/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean @@ -9,7 +9,6 @@ public import Mathlib.Lean.Meta.RefinedDiscrTree.Basic public import Lean.Meta.DiscrTree public import Lean.Meta.LazyDiscrTree import all Lean.Meta.DiscrTree -public import Lean.Meta /-! # Encoding an `Expr` as a sequence of `Key`s diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index 1af2eff93f1afd..d71ca00b7cd5db 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -5,8 +5,7 @@ Authors: Arend Mellendijk -/ module -public import Mathlib.Algebra.Algebra.Basic -public import Mathlib.Algebra.Algebra.Defs +public meta import Lean.Meta.Tactic.NormCast public import Mathlib.Tactic.Algebra.Lemmas public import Mathlib.Tactic.Ring.RingNF diff --git a/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean b/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean index 3464db91905817..4a88eaaeda8c8f 100644 --- a/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean +++ b/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean @@ -5,9 +5,8 @@ Authors: Robert Y. Lewis -/ module +public meta import Std.Data.HashMap.AdditionalOperations public meta import Batteries.Lean.HashMap -public meta import Mathlib.Tactic.Linarith.Datatypes -public import Batteries.Lean.HashMap public import Mathlib.Tactic.Linarith.Datatypes /-! diff --git a/Mathlib/Tactic/Linter/Header.lean b/Mathlib/Tactic/Linter/Header.lean index 24a13be0b14023..73ecfad1d38d45 100644 --- a/Mathlib/Tactic/Linter/Header.lean +++ b/Mathlib/Tactic/Linter/Header.lean @@ -306,7 +306,7 @@ namespace Style.header def broadImportsCheck (imports : Array Syntax) (mainModule : Name) : CommandElabM Unit := do for i in imports do match i.getId with - | `Mathlib.Tactic | `Lean | `Lean.Elab | `Std => + | `Mathlib.Tactic | `Lean | `Lean.Meta | `Lean.Elab | `Lean.Elab.Tactic | `Std => Linter.logLint linter.style.header i s!"Files in mathlib cannot import the whole `{i.getId}` folder. \ Doing so would cause imports to be unnecessarily slow." diff --git a/Mathlib/Tactic/Module.lean b/Mathlib/Tactic/Module.lean index dd5d1b1bc065b4..b894df41611c37 100644 --- a/Mathlib/Tactic/Module.lean +++ b/Mathlib/Tactic/Module.lean @@ -5,11 +5,11 @@ Authors: Heather Macbeth -/ module +public meta import Lean.Meta.Tactic.NormCast public import Mathlib.Algebra.Algebra.Tower public import Mathlib.Algebra.BigOperators.GroupWithZero.Action public import Mathlib.Tactic.Ring public import Mathlib.Util.AtomM -public meta import Mathlib.Algebra.Algebra.Defs /-! # A tactic for normalization over modules diff --git a/Mathlib/Util/DelabNonCanonical.lean b/Mathlib/Util/DelabNonCanonical.lean index 1c3e8e88cc7120..9430e9fedeee05 100644 --- a/Mathlib/Util/DelabNonCanonical.lean +++ b/Mathlib/Util/DelabNonCanonical.lean @@ -6,7 +6,6 @@ Authors: Robert Maxton module public import Mathlib.Init -public meta import Lean.Meta public meta import Lean.PrettyPrinter.Delaborator.Builtins /-! Delab checking canonicity. diff --git a/MathlibTest/Tactic/Grind/Lint.lean b/MathlibTest/Tactic/Grind/Lint.lean index d0d30e6dd9b87b..628f45a63eebbc 100644 --- a/MathlibTest/Tactic/Grind/Lint.lean +++ b/MathlibTest/Tactic/Grind/Lint.lean @@ -1,4 +1,7 @@ +module + import Mathlib +import Lean.Elab.Tactic.Grind.LintExceptions -- These each instantiate 24 further lemmas (pretty much the same ones), but they seem reasonable. -- We'll make an exception for this one, From 6a37ffc6da38a4c46eb1a09e77301fe19881a70b Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 15 Jun 2026 18:17:50 +0000 Subject: [PATCH 0049/1300] chore: fix non-reducible diamond in `ConjAct` (#40427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following fails before the PR, suceeds after it ``` example : (ConjAct.instGroupWithZero.toDivInvMonoid : DivInvMonoid (ConjAct G₀)) = ConjAct.instDivInvMonoid := by with_reducible_and_instances rfl ``` Co-authored-by: sgouezel --- Mathlib/Algebra/GroupWithZero/Action/ConjAct.lean | 2 +- Mathlib/GroupTheory/GroupAction/ConjAct.lean | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/Action/ConjAct.lean b/Mathlib/Algebra/GroupWithZero/Action/ConjAct.lean index 56471c6a4e888c..93f00b66517270 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/ConjAct.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/ConjAct.lean @@ -21,7 +21,7 @@ variable {α G₀ : Type*} namespace ConjAct variable [GroupWithZero G₀] -instance : GroupWithZero (ConjAct G₀) := ‹GroupWithZero G₀› +instance : GroupWithZero (ConjAct G₀) := inferInstanceAs <| GroupWithZero G₀ @[simp] lemma ofConjAct_zero : ofConjAct 0 = (0 : G₀) := rfl @[simp] lemma toConjAct_zero : toConjAct (0 : G₀) = 0 := rfl diff --git a/Mathlib/GroupTheory/GroupAction/ConjAct.lean b/Mathlib/GroupTheory/GroupAction/ConjAct.lean index f6243e6eabcb82..e63abfbcc6fb5f 100644 --- a/Mathlib/GroupTheory/GroupAction/ConjAct.lean +++ b/Mathlib/GroupTheory/GroupAction/ConjAct.lean @@ -49,11 +49,11 @@ open MulAction Subgroup variable {M G} -instance [Group G] : Group (ConjAct G) := ‹Group G› +instance [DivInvMonoid G] : DivInvMonoid (ConjAct G) := inferInstanceAs <| DivInvMonoid G -instance [DivInvMonoid G] : DivInvMonoid (ConjAct G) := ‹DivInvMonoid G› +instance [Group G] : Group (ConjAct G) := inferInstanceAs <| Group G -instance [Fintype G] : Fintype (ConjAct G) := ‹Fintype G› +instance [Fintype G] : Fintype (ConjAct G) := inferInstanceAs <| Fintype G @[simp] theorem card [Fintype G] : Fintype.card (ConjAct G) = Fintype.card G := @@ -255,7 +255,7 @@ theorem _root_.MulAut.conjNormal_apply {H : Subgroup G} [H.Normal] (g : G) (h : @[simp] theorem _root_.MulAut.conjNormal_symm_apply {H : Subgroup G} [H.Normal] (g : G) (h : H) : ↑((MulAut.conjNormal g).symm h) = g⁻¹ * h * g := by - change _ * _⁻¹⁻¹ = _ + change _ * g⁻¹⁻¹ = _ rw [inv_inv] rfl From 3cd5cf90f02bfb11b3b39fde2aab54574b171dea Mon Sep 17 00:00:00 2001 From: Robert Hawkins Date: Mon, 15 Jun 2026 19:03:16 +0000 Subject: [PATCH 0050/1300] feat(RingTheory): quotients of coalgebra/bialgebra/Hopf algebras (#39790) Co-authored-by: Eric Wieser --- Mathlib.lean | 3 + Mathlib/RingTheory/Bialgebra/Quotient.lean | 82 +++++++++++++ Mathlib/RingTheory/Coalgebra/Quotient.lean | 92 ++++++++++++++ Mathlib/RingTheory/HopfAlgebra/Quotient.lean | 119 +++++++++++++++++++ 4 files changed, 296 insertions(+) create mode 100644 Mathlib/RingTheory/Bialgebra/Quotient.lean create mode 100644 Mathlib/RingTheory/Coalgebra/Quotient.lean create mode 100644 Mathlib/RingTheory/HopfAlgebra/Quotient.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2ba33f02117f1e..cbf1ae94070768 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6419,6 +6419,7 @@ public import Mathlib.RingTheory.Bialgebra.Equiv public import Mathlib.RingTheory.Bialgebra.GroupLike public import Mathlib.RingTheory.Bialgebra.Hom public import Mathlib.RingTheory.Bialgebra.MonoidAlgebra +public import Mathlib.RingTheory.Bialgebra.Quotient public import Mathlib.RingTheory.Bialgebra.SymmetricAlgebra public import Mathlib.RingTheory.Bialgebra.TensorProduct public import Mathlib.RingTheory.Binomial @@ -6434,6 +6435,7 @@ public import Mathlib.RingTheory.Coalgebra.GroupLike public import Mathlib.RingTheory.Coalgebra.Hom public import Mathlib.RingTheory.Coalgebra.MonoidAlgebra public import Mathlib.RingTheory.Coalgebra.MulOpposite +public import Mathlib.RingTheory.Coalgebra.Quotient public import Mathlib.RingTheory.Coalgebra.TensorProduct public import Mathlib.RingTheory.Complex public import Mathlib.RingTheory.Conductor @@ -6576,6 +6578,7 @@ public import Mathlib.RingTheory.HopfAlgebra.Basic public import Mathlib.RingTheory.HopfAlgebra.Convolution public import Mathlib.RingTheory.HopfAlgebra.GroupLike public import Mathlib.RingTheory.HopfAlgebra.MonoidAlgebra +public import Mathlib.RingTheory.HopfAlgebra.Quotient public import Mathlib.RingTheory.HopfAlgebra.TensorProduct public import Mathlib.RingTheory.HopkinsLevitzki public import Mathlib.RingTheory.Ideal.AssociatedPrime.Basic diff --git a/Mathlib/RingTheory/Bialgebra/Quotient.lean b/Mathlib/RingTheory/Bialgebra/Quotient.lean new file mode 100644 index 00000000000000..29b1c29309ef53 --- /dev/null +++ b/Mathlib/RingTheory/Bialgebra/Quotient.lean @@ -0,0 +1,82 @@ +/- +Copyright (c) 2026 Robert Hawkins. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Robert Hawkins +-/ +module + +public import Mathlib.RingTheory.Bialgebra.Hom +public import Mathlib.RingTheory.Coalgebra.Quotient +public import Mathlib.RingTheory.Ideal.Quotient.Operations +public import Mathlib.RingTheory.TensorProduct.Maps + +/-! +# Bialgebra structure on quotients + +If `I` is a two-sided ideal of an `R`-bialgebra `A` whose underlying `R`-submodule is a +coideal, then the quotient `A ⧸ I` inherits a bialgebra structure. + +## Main definitions + +* `Bialgebra.Quotient.counitAlgHom` : the counit on `A ⧸ I`, as an `R`-algebra homomorphism. +* `Bialgebra.Quotient.comulAlgHom` : comultiplication on `A ⧸ I` as an `R`-algebra homomorphism. +* `Bialgebra.Quotient.mkBialgHom` : `Ideal.Quotient.mkₐ` as a bialgebra homomorphism. + +## Main results + +* `Bialgebra R (A ⧸ I)` instance when `[I.IsTwoSided]` and `[(I.restrictScalars R).IsCoideal]`. +-/ + +@[expose] public section + +open Bialgebra Coalgebra LinearMap TensorProduct + +variable {R A : Type*} [CommRing R] [Ring A] [Bialgebra R A] +variable (I : Ideal A) [I.IsTwoSided] [(I.restrictScalars R).IsCoideal] + +namespace Bialgebra.Quotient + +/-- The counit on `A ⧸ I`, as an `R`-algebra homomorphism. -/ +def counitAlgHom : (A ⧸ I) →ₐ[R] R := + Ideal.Quotient.liftₐ I (Bialgebra.counitAlgHom R A) + (Submodule.IsCoideal.counit_eq_zero (I := I.restrictScalars R)) + +/-- The comultiplication on `A ⧸ I`, as an `R`-algebra homomorphism. -/ +def comulAlgHom : (A ⧸ I) →ₐ[R] (A ⧸ I) ⊗[R] (A ⧸ I) := + Ideal.Quotient.liftₐ I + ((Algebra.TensorProduct.map (Ideal.Quotient.mkₐ R I) (Ideal.Quotient.mkₐ R I)).comp + (Bialgebra.comulAlgHom R A)) + (Submodule.IsCoideal.map_mkQ_comul_eq_zero (I := I.restrictScalars R)) + +lemma counit_comp_mkₐ : + (counitAlgHom I).toLinearMap ∘ₗ (Ideal.Quotient.mkₐ R I).toLinearMap = counit := rfl + +lemma comul_comp_mkₐ : + (comulAlgHom (R := R) I).toLinearMap ∘ₗ (Ideal.Quotient.mkₐ R I).toLinearMap = + map (Ideal.Quotient.mkₐ R I).toLinearMap (Ideal.Quotient.mkₐ R I).toLinearMap ∘ₗ comul := rfl + +/-- The bialgebra structure on `A ⧸ I` when `I` is a biideal. -/ +instance : Bialgebra R (A ⧸ I) := by + refine .ofAlgHom (comulAlgHom I) (counitAlgHom I) ?_ ?_ ?_ <;> + refine Ideal.Quotient.algHom_ext R (AlgHom.toLinearMap_injective ?_) <;> + simp only [coassoc_simps, AlgHom.comp_toLinearMap, Algebra.TensorProduct.toLinearMap_map, + comul_comp_mkₐ, counit_comp_mkₐ] + · simp [coassoc_simps] + · rw [CoassocSimps.map_counit_comp_comul_left]; rfl + · rw [CoassocSimps.map_counit_comp_comul_right]; rfl + +@[simp] lemma counit_mk (a : A) : + counit (R := R) (Ideal.Quotient.mk I a) = counit a := rfl + +@[simp] lemma comul_mk (a : A) : + comul (R := R) (Ideal.Quotient.mk I a) = + map (Ideal.Quotient.mkₐ R I).toLinearMap (Ideal.Quotient.mkₐ R I).toLinearMap (comul a) := + rfl + +/-- `Ideal.Quotient.mkₐ` as a bialgebra homomorphism. -/ +def mkBialgHom : A →ₐc[R] A ⧸ I := .ofAlgHom (Ideal.Quotient.mkₐ R I) rfl rfl + +@[simp] lemma mkBialgHom_apply (a : A) : + mkBialgHom (R := R) I a = Ideal.Quotient.mk I a := rfl + +end Bialgebra.Quotient diff --git a/Mathlib/RingTheory/Coalgebra/Quotient.lean b/Mathlib/RingTheory/Coalgebra/Quotient.lean new file mode 100644 index 00000000000000..87f053509589db --- /dev/null +++ b/Mathlib/RingTheory/Coalgebra/Quotient.lean @@ -0,0 +1,92 @@ +/- +Copyright (c) 2026 Robert Hawkins. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Robert Hawkins +-/ +module + +public import Mathlib.LinearAlgebra.Quotient.Basic +public import Mathlib.LinearAlgebra.TensorProduct.RightExactness +public import Mathlib.RingTheory.Coalgebra.CoassocSimps +public import Mathlib.RingTheory.Coalgebra.Hom + +/-! +# Coalgebra structure on the quotient by a coideal + +## Main definitions + +* `Submodule.IsCoideal I` : the submodule `I : Submodule R C` is a coideal. +* `Coalgebra.Quotient.mkQCoalgHom` : `Submodule.mkQ` as a coalgebra homomorphism. + +## Main results + +* `Coalgebra` instance on `C ⧸ I` when `[I.IsCoideal]`. +-/ + +public section + +open Coalgebra LinearMap TensorProduct + +variable {R C : Type*} [CommRing R] [AddCommGroup C] [Module R C] + +section CoalgebraStruct + +variable [CoalgebraStruct R C] + +/-- An `R`-submodule `I` of an `R`-coalgebra `C` is a *coideal* if the counit vanishes on +`I` and the comultiplication descends through the module quotient `C ⧸ I`. -/ +@[mk_iff] +class Submodule.IsCoideal (I : Submodule R C) : Prop where + counit_eq_zero : ∀ ⦃x : C⦄, x ∈ I → counit (R := R) x = 0 + map_mkQ_comul_eq_zero : ∀ ⦃x : C⦄, x ∈ I → TensorProduct.map I.mkQ I.mkQ (comul x) = 0 + +/-- A submodule is a coideal iff the counit vanishes on it and its comultiplication image lies +in `I ⊗ C + C ⊗ I`, the textbook form of the coideal condition. -/ +lemma Submodule.isCoideal_iff_comul_mem (I : Submodule R C) : + I.IsCoideal ↔ (∀ x ∈ I, counit (R := R) x = 0) ∧ + ∀ x ∈ I, comul x ∈ + LinearMap.range (lTensor C I.subtype) ⊔ LinearMap.range (rTensor C I.subtype) := by + simp_rw [isCoideal_iff, ← LinearMap.mem_ker, + TensorProduct.map_ker (LinearMap.exact_subtype_mkQ I) I.mkQ_surjective + (LinearMap.exact_subtype_mkQ I) I.mkQ_surjective] + +end CoalgebraStruct + +namespace Coalgebra.Quotient + +section CoalgebraStruct + +variable [CoalgebraStruct R C] (I : Submodule R C) [I.IsCoideal] + +instance : CoalgebraStruct R (C ⧸ I) where + comul := I.liftQ (map I.mkQ I.mkQ ∘ₗ comul) Submodule.IsCoideal.map_mkQ_comul_eq_zero + counit := I.liftQ counit Submodule.IsCoideal.counit_eq_zero + +lemma comul_comp_mkQ : comul ∘ₗ I.mkQ = map I.mkQ I.mkQ ∘ₗ (comul : C →ₗ[R] _) := rfl + +lemma counit_comp_mkQ : counit ∘ₗ I.mkQ = (counit : C →ₗ[R] R) := rfl + +@[simp] +lemma counit_mk (x : C) : counit (R := R) (Submodule.Quotient.mk (p := I) x) = counit x := rfl + +@[simp] +lemma comul_mk (x : C) : + comul (R := R) (Submodule.Quotient.mk (p := I) x) = map I.mkQ I.mkQ (comul x) := rfl + +/-- `Submodule.mkQ` as a coalgebra homomorphism. -/ +@[expose] def mkQCoalgHom : C →ₗc[R] C ⧸ I := ⟨I.mkQ, rfl, rfl⟩ + +@[simp] lemma mkQCoalgHom_apply (x : C) : + mkQCoalgHom (R := R) I x = Submodule.Quotient.mk x := rfl + +end CoalgebraStruct + +variable [Coalgebra R C] (I : Submodule R C) [I.IsCoideal] + +instance : Coalgebra R (C ⧸ I) := by + constructor <;> ext : 1 <;> + simp only [coassoc_simps, comul_comp_mkQ, counit_comp_mkQ] + · rw [CoassocSimps.map_counit_comp_comul_left]; rfl + · rw [CoassocSimps.map_counit_comp_comul_right]; rfl + +end Coalgebra.Quotient diff --git a/Mathlib/RingTheory/HopfAlgebra/Quotient.lean b/Mathlib/RingTheory/HopfAlgebra/Quotient.lean new file mode 100644 index 00000000000000..4e04f0e785894a --- /dev/null +++ b/Mathlib/RingTheory/HopfAlgebra/Quotient.lean @@ -0,0 +1,119 @@ +/- +Copyright (c) 2026 Robert Hawkins. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Robert Hawkins +-/ +module + +public import Mathlib.RingTheory.Bialgebra.Quotient +public import Mathlib.RingTheory.HopfAlgebra.Convolution + +/-! +# Hopf algebra structure on quotients by Hopf ideals + +A *Hopf ideal* of an `R`-Hopf algebra `A` is a biideal stable under the antipode. The quotient +by a Hopf ideal inherits a Hopf algebra structure. + +## Main definitions + +* `Ideal.IsHopfIdeal R I` : `I` is a coideal (as an `R`-submodule) stable under the antipode. + +## Main results + +* `HopfAlgebra.ofSurjective` : the Hopf algebra axioms transfer along a surjective bialgebra + homomorphism intertwining the antipodes. +* `HopfAlgebra R (A ⧸ I)` instance when `[I.IsTwoSided]` and `[I.IsHopfIdeal R]`. +-/ + +public section + +open Bialgebra Bialgebra.Quotient Coalgebra HopfAlgebra Ideal.Quotient LinearMap + TensorProduct WithConv + +namespace HopfAlgebra + +section ofSurjective + +variable {R A B : Type*} [CommSemiring R] [Semiring A] [Semiring B] + [HopfAlgebra R A] [HopfAlgebraStruct R B] + +/-- Post-composition by an algebra homomorphism preserves the convolution unit. -/ +lemma _root_.LinearMap.algHom_comp_convOne (g : A →ₐ[R] B) : + g.toLinearMap ∘ₗ (1 : WithConv (A →ₗ[R] A)).ofConv = (1 : WithConv (A →ₗ[R] B)).ofConv := by + ext a; simp + +/-- Pre-composition by a coalgebra homomorphism preserves the convolution unit. -/ +lemma _root_.LinearMap.convOne_comp_coalgHom (g : A →ₗc[R] B) : + (1 : WithConv (B →ₗ[R] B)).ofConv ∘ₗ g.toLinearMap = (1 : WithConv (A →ₗ[R] B)).ofConv := by + ext a; simp + +/-- Transfer the Hopf algebra axioms along a surjective bialgebra homomorphism intertwining +the antipodes. -/ +noncomputable abbrev ofSurjective (f : A →ₐc[R] B) (hf : Function.Surjective f) + (hS : antipode R ∘ₗ f.toLinearMap = f.toLinearMap ∘ₗ antipode R) : HopfAlgebra R B := by + refine .ofConvInverse (antipode R) (ofConv_injective ?_) (ofConv_injective ?_) <;> + rw [← LinearMap.cancel_right (show Function.Surjective f.toLinearMap from hf)] + · calc (toConv (antipode R) * toConv .id : WithConv (B →ₗ[R] B)).ofConv ∘ₗ + f.toCoalgHom.toLinearMap + = (toConv (f.toLinearMap ∘ₗ antipode R) * toConv f.toLinearMap).ofConv := by + rw [convMul_comp_coalgHom_distrib, hS]; rfl + _ = (AlgHomClass.toAlgHom f).toLinearMap ∘ₗ + (toConv (antipode R) * toConv .id : WithConv (A →ₗ[R] A)).ofConv := by + rw [algHom_comp_convMul_distrib]; rfl + _ = (1 : WithConv (B →ₗ[R] B)).ofConv ∘ₗ f.toLinearMap := by + rw [antipode_mul_id, algHom_comp_convOne, ← convOne_comp_coalgHom f.toCoalgHom] + · calc (toConv .id * toConv (antipode R) : WithConv (B →ₗ[R] B)).ofConv ∘ₗ + f.toCoalgHom.toLinearMap + = (toConv f.toLinearMap * toConv (f.toLinearMap ∘ₗ antipode R)).ofConv := by + rw [convMul_comp_coalgHom_distrib, hS]; rfl + _ = (AlgHomClass.toAlgHom f).toLinearMap ∘ₗ + (toConv .id * toConv (antipode R) : WithConv (A →ₗ[R] A)).ofConv := by + rw [algHom_comp_convMul_distrib]; rfl + _ = (1 : WithConv (B →ₗ[R] B)).ofConv ∘ₗ f.toLinearMap := by + rw [id_mul_antipode, algHom_comp_convOne, ← convOne_comp_coalgHom f.toCoalgHom] + +end ofSurjective + +end HopfAlgebra + +variable {R A : Type*} [CommRing R] [Ring A] + +section HopfAlgebraStruct + +variable [HopfAlgebraStruct R A] + +variable (R) in +/-- An ideal whose underlying `R`-submodule is a coideal and which is stable under the +antipode (`S(I) ⊆ I`). Together with `I.IsTwoSided`, this makes `I` a *Hopf ideal*. -/ +@[mk_iff] +class Ideal.IsHopfIdeal (I : Ideal A) : Prop extends (I.restrictScalars R).IsCoideal where + antipode_mem : ∀ ⦃x : A⦄, x ∈ I → antipode R x ∈ I + +end HopfAlgebraStruct + +namespace HopfAlgebra.Quotient + +section HopfAlgebraStruct + +variable [HopfAlgebraStruct R A] (I : Ideal A) [I.IsTwoSided] [I.IsHopfIdeal R] + +instance : HopfAlgebraStruct R (A ⧸ I) where + antipode := Submodule.mapQ (I.restrictScalars R) (I.restrictScalars R) + (antipode R) (Ideal.IsHopfIdeal.antipode_mem (R := R)) + +@[simp] +lemma antipode_mk (a : A) : + antipode R (Ideal.Quotient.mk I a) = Ideal.Quotient.mk I (antipode R a) := rfl + +lemma antipode_comp_mkₐ : + antipode R ∘ₗ (Ideal.Quotient.mkₐ R I).toLinearMap = + (Ideal.Quotient.mkₐ R I).toLinearMap ∘ₗ antipode R := by ext; simp + +end HopfAlgebraStruct + +variable [HopfAlgebra R A] (I : Ideal A) [I.IsTwoSided] [I.IsHopfIdeal R] + +noncomputable instance : HopfAlgebra R (A ⧸ I) := + .ofSurjective (mkBialgHom I) mk_surjective (antipode_comp_mkₐ I) + +end HopfAlgebra.Quotient From 05bdd16f046e16d10f628857261c596d68dc2c51 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Mon, 15 Jun 2026 19:17:28 +0000 Subject: [PATCH 0051/1300] feat(cache): restructure cache tool server-side storage layout (#40035) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR significantly restructures the cache back-end storage layout to address some security issues and as a side benefit improve auditing, garbage collection, provenance. 1) Instead of setting the cache-universe boundary to the repository, we scope it to particular commit SHAs. This means a review of the changes in a PR does give you confidence in pulling from the cache at that commit. 2) Split the cache universes from master, forks, and nightly-testing at the infrastructure level, using different azure containers. This has other benefits in management, like better auditing, the possibility of targeted garbage collection, etc. See `SECURITY.md` for the motivation and explanation of the trust model implemented here. Also added cache tool tests, and changed a bunch of the messages output to users to surface security concerns more clearly. Extra details: ### Trust model - Five containers — `master`, `forks`, `nightly-testing`, `pr-toolchain-tests`, and `legacy` (the original bare `mathlib4` bucket) — each mapped to a dedicated Azure container. Every trust level has its own writer identity. Azure RBAC on the OIDC token is the enforced write boundary, not the workflow logic. - Reads use a per-repo, trust-ordered chain (most-trusted first, stop at first hit - URL layout is fixed per container, not per repo: `master` is flat (`/f/{hash}`), multi-writer containers namespace by repo (`/f/{repo}/{hash}`), `legacy` preserves its historical mixed layout for older clients. ### Per-commit scoping & discovery - Fork uploads are scoped to their commit SHA (`/f/{repo}/{sha}/{hash}`), so a closed/hidden PR's artifacts can't be served to a later honest PR on the same fork. A marker blob (`/m/{repo}/{sha}`) is written after a successful upload. - New `cache query [REF]`: walks history to the merge-base with master and HEAD- probes markers to report the most recent cached commit (or a boolean probe for a single ref). `cache get --scope=` then reads that commit's namespace. - `cache get --unsafe` folds that discovery into the download itself: it walks history for the most recent cached fork commit and reads it as a scope automatically, instead of you copying a SHA into `--scope`. `--unsafe-window=N` widens this to the `N` most recent (default `1`). It always prints the security notice, since it trusts whoever built those commits. - `cache get` prints a security notice whenever a read leaves the repo's default trust boundary (a scope, a widened `--cache-from`, or a `--repo` that diverges from the git remote), plus a hint pointing uncached fork HEADs at `cache query`. ### CLI / env surface - New flags: `--cache-from=LIST`, `--container=NAME`, `--scope=REF`, `--unsafe`, `--unsafe-window=N`; new command `cache query`. - New env: `MATHLIB_CACHE_FROM`, `MATHLIB_CACHE_REPO_SCOPE`. `MATHLIB_CACHE_GET_URL` / `_PUT_URL` retained as single-URL escape hatches; `MATHLIB_CACHE_USE_CLOUDFLARE` removed. ### CI wiring - New composite action `cache-trust-dispatch` is the single source mapping `(repo, branch) → (write container, read chain, per-commit scope)`; `build.yml`, `bors.yml`, and `build_template.yml` consult it. Trust policy lives in YAML, not in the Lean tool. - During migration, master CI dual-writes to `legacy` so older cache clients keep working; forks/nightly never write to `legacy`. ### Code organization & testing - Backend split into focused modules: `Cache.Infra` (container model), `Cache.Cli` (option parsing), `Cache.Marker`, `Cache.Query`, `Cache.Warning`; `Cache.Init` folded away. - New standalone `lake exe cache-test` (`Cache.Test`) unit-tests the pure logic — container model, URL construction, per-repo read chains, flag parsing, and the warning conditions — without building Mathlib. --- .../actions/cache-trust-dispatch/action.yml | 157 +++ .github/actions/get-tools/action.yml | 26 + .github/workflows/bors.yml | 47 +- .github/workflows/build.yml | 40 +- .github/workflows/build_template.yml | 165 ++- .github/workflows/cache_test.yml | 43 + Cache/Cli.lean | 49 + Cache/Infra.lean | 151 +++ Cache/Init.lean | 16 - Cache/Main.lean | 183 ++- Cache/Marker.lean | 64 ++ Cache/Query.lean | 229 ++++ Cache/README.md | 216 ++-- Cache/Requests.lean | 609 +++++++--- Cache/SECURITY.md | 152 +++ Cache/Test.lean | 1007 +++++++++++++++++ Cache/Warning.lean | 228 ++++ lakefile.lean | 6 + 18 files changed, 3030 insertions(+), 358 deletions(-) create mode 100644 .github/actions/cache-trust-dispatch/action.yml create mode 100644 .github/workflows/cache_test.yml create mode 100644 Cache/Cli.lean create mode 100644 Cache/Infra.lean delete mode 100644 Cache/Init.lean create mode 100644 Cache/Marker.lean create mode 100644 Cache/Query.lean create mode 100644 Cache/SECURITY.md create mode 100644 Cache/Test.lean create mode 100644 Cache/Warning.lean diff --git a/.github/actions/cache-trust-dispatch/action.yml b/.github/actions/cache-trust-dispatch/action.yml new file mode 100644 index 00000000000000..7e3811a969d2d9 --- /dev/null +++ b/.github/actions/cache-trust-dispatch/action.yml @@ -0,0 +1,157 @@ +# Single source of truth mapping (repo, branch) → (upload container, +# read fallback chain) for Mathlib's multi-container cache. +# +# Called by build, upload_cache, and post_steps in build_template.yml so +# trust classification is decided in exactly one place. Lean-side cache +# logic stays branch-agnostic; this composite is the seam where CI-only +# trust policy lives. + +name: Cache trust dispatch +description: Compute the cache container target and read fallback for this job. + +inputs: + repo: + description: GitHub repo full name (`owner/name`). + required: true + branch: + description: Branch name (`github.head_ref || github.ref_name`). + required: true + head-sha: + description: | + Head commit SHA for the ref being built. Used as the per-commit cache + namespace (`MATHLIB_CACHE_REPO_SCOPE`) for fork-trust uploads, so a + closed/hidden PR's poisoned artifacts cannot be served to a later + honest PR from the same fork. + required: true + +# Outputs are mirrored to $GITHUB_ENV inside the step, which is what +# downstream `cache get` / `cache put-staged` calls actually read. We +# also expose them as action outputs for callers that need them in +# `with:` blocks (e.g. constructing further `if:` conditions). +outputs: + primary: + description: Container name for uploads (master, forks, nightly-testing, pr-toolchain-tests). + value: ${{ steps.dispatch.outputs.primary }} + read-chain: + description: | + Comma-separated read fallback chain for `MATHLIB_CACHE_FROM`. Empty + when the job should use the cache tool's repo-level default. + value: ${{ steps.dispatch.outputs.read-chain }} + repo-scope: + description: | + Per-commit namespace suffix for `MATHLIB_CACHE_REPO_SCOPE`. Set to + the head SHA when uploading to fork-trust containers; empty for + master / nightly / pr-toolchain-tests uploads where scoping isn't + applied. + value: ${{ steps.dispatch.outputs.repo-scope }} + +runs: + using: composite + steps: + - name: Compute trust dispatch + id: dispatch + shell: bash + run: | + REPO="${{ inputs.repo }}" + BRANCH="${{ inputs.branch }}" + HEAD_SHA="${{ inputs.head-sha }}" + PRIMARY="" + READ_CHAIN="" + REPO_SCOPE="" + + # Security note: this dispatch is NOT the trust boundary for writes. + # The real enforcement is the OIDC bearer token minted in upload_cache: + # the token is scoped to a specific container, so a malicious actor + # rewriting this case to `--container=master` from a fork build would + # be 403'd by Azure regardless. The dispatch exists so the workflow + # does the right thing in the honest case; defence in depth is RBAC. + + case "$REPO" in + "leanprover-community/mathlib4") + case "$BRANCH" in + "master"|"staging") + # Master / staging are the only writers that feed `master` + # (`staging` is bors's merge candidate, which fast-forwards to + # `master`). Read `master` only, not the default [master, + # legacy]: files the read chain serves are skipped at stage + # time, so keeping `legacy` would leave legacy-only files out of + # `master` for good. Reading `master` alone turns them into + # misses that get rebuilt and uploaded, so `master` fills itself + # into a standalone cache. (Only PRIMARY=master does this; other + # runs write to `forks` and keep the wider chain.) + PRIMARY="master" + READ_CHAIN="master" + ;; + *) + # `bors trying`, `ci-dev/*`, maintainer dev branches on the + # canonical repo: trust level is fork-equivalent (the OIDC + # token's RBAC scopes them to `forks`). Reads must widen + # past the default [master, legacy] so the post-build + # verification finds the just-uploaded fork-trust artifacts. + PRIMARY="forks" + READ_CHAIN="master,forks,legacy" + ;; + esac + ;; + "leanprover-community/mathlib4-nightly-testing") + case "$BRANCH" in + "nightly-testing"|"nightly-testing-green"|"staging"|bump/*) + # Trusted nightly refs use the default [nightly-testing, legacy]. + # It excludes `pr-toolchain-tests` so an upload from a + # `lean-pr-testing-*` branch never reaches a trusted-nightly + # consumer. + PRIMARY="nightly-testing" + ;; + *) + # `lean-pr-testing-*`, `batteries-pr-testing-*`, etc.: + # least-trusted (can build with arbitrary toolchains). Widen + # reads to recover this branch's own previously-uploaded + # artifacts; trusted-nightly stays preferred where hash + # spaces happen to align. + PRIMARY="pr-toolchain-tests" + READ_CHAIN="pr-toolchain-tests,nightly-testing,legacy" + ;; + esac + ;; + *) + # Foreign fork. The cache tool's default chain for a fork repo + # is [master, forks, legacy] (master-first): master supplies the + # bulk of unchanged upstream deps, forks supplies PR-specific + # files. No widening needed, so MATHLIB_CACHE_FROM stays unset. + PRIMARY="forks" + ;; + esac + + # Per-commit cache namespace, only for fork-trust uploads. Closes the + # within-fork temporal replay attack: each commit's CI run gets its + # own /f/{repo}/{sha}/... namespace, so artifacts from a closed/ + # hidden PR cannot be served to a later honest build on the same + # fork. Master / nightly / pr-toolchain-tests uploads stay un-scoped: + # master has a single writer (no replay risk), and the per-toolchain + # hash partitioning isolates nightly and toolchain-test classes via + # their root-hash inputs. + if [ "$PRIMARY" = "forks" ]; then + REPO_SCOPE="$HEAD_SHA" + fi + + echo "primary=$PRIMARY" >> "$GITHUB_OUTPUT" + echo "read-chain=$READ_CHAIN" >> "$GITHUB_OUTPUT" + echo "repo-scope=$REPO_SCOPE" >> "$GITHUB_OUTPUT" + echo "MATHLIB_CACHE_PRIMARY=$PRIMARY" >> "$GITHUB_ENV" + if [ -n "$READ_CHAIN" ]; then + echo "MATHLIB_CACHE_FROM=$READ_CHAIN" >> "$GITHUB_ENV" + fi + if [ -n "$REPO_SCOPE" ]; then + echo "MATHLIB_CACHE_REPO_SCOPE=$REPO_SCOPE" >> "$GITHUB_ENV" + fi + # Visible in CI logs so a glance at any cache-touching step shows + # what trust class the job is operating under. + SCOPE_NOTE="" + if [ -n "$REPO_SCOPE" ]; then + SCOPE_NOTE=", MATHLIB_CACHE_REPO_SCOPE=$REPO_SCOPE" + fi + if [ -n "$READ_CHAIN" ]; then + echo "cache-trust-dispatch: REPO=$REPO BRANCH=$BRANCH → container=$PRIMARY, MATHLIB_CACHE_FROM=$READ_CHAIN$SCOPE_NOTE" + else + echo "cache-trust-dispatch: REPO=$REPO BRANCH=$BRANCH → container=$PRIMARY, MATHLIB_CACHE_FROM=$SCOPE_NOTE" + fi diff --git a/.github/actions/get-tools/action.yml b/.github/actions/get-tools/action.yml index 87831ca5b600e4..6e195f21ea308e 100644 --- a/.github/actions/get-tools/action.yml +++ b/.github/actions/get-tools/action.yml @@ -36,6 +36,15 @@ inputs: description: Destination directory for the tools. required: false default: tools-branch + source_dir: + description: > + Optional path to a local checkout under test. When set and the artifact + fast path is in play, the action compares this checkout's tool sources + against the artifact's `master` baseline; if they differ it skips the + prebuilt artifact and builds from source, so a branch that changes the + tool is tested with its own tool. Empty disables the comparison. + required: false + default: '' runs: using: composite steps: @@ -56,6 +65,23 @@ runs: --workflow "${{ inputs.artifact_workflow }}" \ --branch master --status success --event push \ --limit 1 --json databaseId --jq '.[0].databaseId // empty' 2>/dev/null || true) + + # If a local checkout under test is provided and its tool sources differ + # from the artifact's master baseline, the prebuilt tool would mask the + # change — drop it and build from source. Local git only; no API call. + # These are the source paths that determine the bundled tools (the + # `cache` binary and the build-helper scripts in publish_tools.yml); they + # live here so callers don't have to duplicate the list. + if [[ -n "$run_id" && -n "${{ inputs.source_dir }}" ]]; then + git -C "${{ inputs.source_dir }}" fetch --no-tags --depth=1 \ + "https://github.com/${{ inputs.artifact_repo }}.git" master || true + # Fail safe toward building: a failed fetch/diff leaves $? non-zero. + if ! git -C "${{ inputs.source_dir }}" diff --quiet FETCH_HEAD -- \ + Cache scripts/lake-build-with-retry.sh scripts/lake-build-wrapper.py; then + echo "Tool sources in '${{ inputs.source_dir }}' differ from master; building from source." + run_id="" + fi + fi fi echo "Resolved publisher run_id: '${run_id}'" echo "run_id=${run_id}" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/bors.yml b/.github/workflows/bors.yml index d1618133a6bec6..b6fc3e849b538c 100644 --- a/.github/workflows/bors.yml +++ b/.github/workflows/bors.yml @@ -27,13 +27,46 @@ jobs: with: concurrency_group: ${{ github.workflow }}-${{ github.ref }}-${{ github.run_id }} pr_branch_ref: ${{ github.sha }} - # Use the MASTER cache key only when merging into mathlib4 (staging branch); - # 'bors try' runs (trying branch) and nightly-testing use NON_MASTER - cache_application_id: ${{ github.ref_name == 'staging' && github.repository == 'leanprover-community/mathlib4' && vars.CACHE_MASTER_WRITER_AZURE_APP_ID || vars.CACHE_NON_MASTER_WRITER_AZURE_APP_ID }} - # Track the cache_application_id choice above; the environment fixes the OIDC subject the Azure app trusts. - # nightly-testing is intentionally left without an environment ('') so it keeps its existing ref-based trust. - # TODO: give mathlib4-nightly-testing its own cache-upload environment + federated credential. - cache_environment: ${{ github.repository == 'leanprover-community/mathlib4' && (github.ref_name == 'staging' && 'cache-upload-master' || 'cache-upload-forks') || '' }} + # Trust-level dispatch for the cache writer app (bors runs on + # `staging` = real merge candidate; `trying` = experimental). + # Each case is spelled out so the trust mapping is unambiguous: + # - mathlib4/staging → MASTER writer + # - mathlib4/trying → NON_MASTER (FORKS) writer + # (explicitly NOT master-trust) + # - mathlib4-nightly-testing/staging → NIGHTLY_TESTING writer + # - mathlib4-nightly-testing/trying → PR_TOOLCHAIN_TESTS writer + # (least-trust on the nightly repo) + # - any other ref on either repo → NON_MASTER (FORKS) writer + cache_application_id: >- + ${{ + (github.repository == 'leanprover-community/mathlib4' + && github.ref_name == 'staging') + && vars.CACHE_MASTER_WRITER_AZURE_APP_ID + || (github.repository == 'leanprover-community/mathlib4' + && github.ref_name == 'trying') + && vars.CACHE_NON_MASTER_WRITER_AZURE_APP_ID + || (github.repository == 'leanprover-community/mathlib4-nightly-testing' + && github.ref_name == 'staging') + && vars.CACHE_NIGHTLY_TESTING_WRITER_AZURE_APP_ID + || (github.repository == 'leanprover-community/mathlib4-nightly-testing' + && github.ref_name == 'trying') + && vars.CACHE_PR_TOOLCHAIN_TESTS_WRITER_AZURE_APP_ID + || vars.CACHE_NON_MASTER_WRITER_AZURE_APP_ID + }} + # OIDC environment binding for the upload_cache job. MUST track the cache_application_id + # mapping above so the minted token's `:environment:` subject matches the writer app's + # federated credential. mathlib4-nightly-testing intentionally uses branch/ref-scoped + # trust instead of an environment: each nightly writer app is RBAC-isolated to its own + # container, so branch scoping is sufficient there. + cache_environment: >- + ${{ + (github.repository == 'leanprover-community/mathlib4' + && github.ref_name == 'staging') + && 'cache-upload-master' + || (github.repository == 'leanprover-community/mathlib4') + && 'cache-upload-forks' + || '' + }} # bors runs should build the tools from their commit-under-test: after all, we are trying to # test 'what would happen if this was merged', so we need to use the 'would-be-post-merge' tools tools_branch_ref: ${{ github.sha }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab369c741f2c67..120bd6ae6ba196 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,11 +36,39 @@ jobs: with: concurrency_group: ${{ github.workflow }}-${{ github.ref }}-${{ (github.event_name == 'push' && github.ref == 'refs/heads/master' && github.run_id) || '' }} pr_branch_ref: ${{ github.sha }} - # Use the MASTER cache key only on mathlib4/master; nightly-testing and other branches use NON_MASTER - cache_application_id: ${{ github.repository == 'leanprover-community/mathlib4' && github.ref == 'refs/heads/master' && vars.CACHE_MASTER_WRITER_AZURE_APP_ID || vars.CACHE_NON_MASTER_WRITER_AZURE_APP_ID }} - # Track the cache_application_id choice above; the environment fixes the OIDC subject the Azure app trusts. - # nightly-testing is intentionally left without an environment ('') so it keeps its existing ref-based trust. - # TODO: give mathlib4-nightly-testing its own cache-upload environment + federated credential. - cache_environment: ${{ github.repository == 'leanprover-community/mathlib4' && (github.ref == 'refs/heads/master' && 'cache-upload-master' || 'cache-upload-forks') || '' }} + # Trust-level dispatch for the cache writer app: + # - mathlib4/master → MASTER writer + # - mathlib4-nightly-testing/(nightly-testing | nightly-testing-green | bump/*) + # → NIGHTLY_TESTING writer + # - mathlib4-nightly-testing/(anything else) → PR_TOOLCHAIN_TESTS writer + # - everything else (dev branches on mathlib4, etc.) → NON_MASTER (forks) writer + cache_application_id: >- + ${{ + (github.repository == 'leanprover-community/mathlib4' + && github.ref_name == 'master') + && vars.CACHE_MASTER_WRITER_AZURE_APP_ID + || (github.repository == 'leanprover-community/mathlib4-nightly-testing' + && (github.ref_name == 'nightly-testing' + || github.ref_name == 'nightly-testing-green' + || startsWith(github.ref_name, 'bump/'))) + && vars.CACHE_NIGHTLY_TESTING_WRITER_AZURE_APP_ID + || (github.repository == 'leanprover-community/mathlib4-nightly-testing') + && vars.CACHE_PR_TOOLCHAIN_TESTS_WRITER_AZURE_APP_ID + || vars.CACHE_NON_MASTER_WRITER_AZURE_APP_ID + }} + # OIDC environment binding for the upload_cache job. MUST track the cache_application_id + # mapping above so the minted token's `:environment:` subject matches the writer app's + # federated credential. mathlib4-nightly-testing intentionally uses branch/ref-scoped + # trust instead of an environment: each nightly writer app is RBAC-isolated to its own + # container, so branch scoping is sufficient there. + cache_environment: >- + ${{ + (github.repository == 'leanprover-community/mathlib4' + && github.ref_name == 'master') + && 'cache-upload-master' + || (github.repository == 'leanprover-community/mathlib4') + && 'cache-upload-forks' + || '' + }} runs_on: pr secrets: inherit diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 6eea0109569af5..5b0676dd6245e7 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -115,6 +115,19 @@ jobs: with: ref: ${{ inputs.mathlib_ci_ref }} + # Compute the trust-classified container target and read fallback + # for this job. Sets MATHLIB_CACHE_FROM / MATHLIB_CACHE_PRIMARY in + # env so every subsequent `cache get` in this job inherits them + # without per-call flag plumbing. Loaded from master via the sparse + # `workflow-actions/` checkout above, not from the PR branch — this + # keeps the trust policy out of fork-controllable file paths. + - name: Compute cache trust dispatch + uses: ./workflow-actions/.github/actions/cache-trust-dispatch + with: + repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + branch: ${{ github.head_ref || github.ref_name }} + head-sha: ${{ github.event.pull_request.head.sha || github.sha }} + # Checkout the PR branch into a subdirectory - name: Checkout PR branch uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -126,6 +139,45 @@ jobs: # Don't leave the GITHUB_TOKEN in pr-branch/.git/config, where that code could read it. persist-credentials: false + # TEMPORARY (cache storage-layout migration, PR #40035): remove once + # active branches have merged the new cache tool. + # CI writes the new container layout via the master-built cache binary, + # but a PR branch that predates the migration ships the old cache tool locally, + # so `lake exe cache get` on the contributor's machine reads the old layout and misses + # its own branch's freshly-built artifacts. + # Hard-fail here (same style as the `lake lint` predates-config gate below in 'lint mathlib') + # and tell the author to merge master, which swaps in the new binary. + # The marker is `Cache/Infra.lean`, a module that only exists post-migration (it replaced `Cache/Init.lean`). + # + # TODO: Remove this check eventually. Note that there is no 'correctness' issue if we don't check this: + # it's just that locally, the user will not get the artifacts this run has produced (also meaning the upload is 'waste'). + - name: check cache tool is post-migration + # Canonical repo only. This nudge targets human fork-PR / dev-branch + # contributors who run `lake exe cache get` locally. The nightly-testing + # repo's branches (nightly-testing, bump/*, lean-pr-testing-*) are + # machine-managed and don't merge master the same way, so "merge master + # and push" is the wrong remedy there; never fail their CI on it. + if: github.repository == 'leanprover-community/mathlib4' + shell: bash + run: | + if [ ! -f pr-branch/Cache/Infra.lean ]; then + echo "::error title=Outdated cache tool::Your branch predates the cache storage-layout migration; merge master so 'lake exe cache get' can read your branch's artifacts." + echo "" + echo "==============================================================================" + echo "ERROR: Your branch predates the cache storage-layout migration (PR #40035)." + echo "Its 'lake exe cache' tool uses outdated infrastructure, so it will miss the" + echo "artifacts CI builds for your branch and rebuild them locally instead." + echo "Please merge 'master' into your PR branch and push again." + echo "" + echo "You can do this with:" + echo " git fetch upstream" + echo " git merge upstream/master" + echo " git push" + echo "==============================================================================" + echo "" + exit 1 + fi + - name: Prepare DownstreamTest directory shell: bash run: | @@ -198,20 +250,28 @@ jobs: echo "LEAN_SRC_PATH=$LEAN_SRC_PATH" >> "$GITHUB_ENV" # Populate `tools-branch/` with the trusted CI tooling (the `cache` binary and - # the `lake-build-*` helper scripts invoked by path below). On the common path - # this downloads the prebuilt `tools-bin` artifact published from `master` by - # `publish_tools.yml`; otherwise (bors/ci_dev overrides, nightly-testing, or any - # download failure) it falls back to checking out and building from source. + # the `lake-build-*` helper scripts invoked by path below). # - # Recall that on the `leanprover-community/mathlib4-nightly-testing` repository, - # we don't maintain a `master` branch at all. For PRs and pushes to this - # repository, we build tools from `nightly-testing-green` instead, so that even - # when `nightly-testing` is broken, we can still build tools from a known good state. + # - Fast path: download the prebuilt `tools-bin` artifact published from + # `master` by `publish_tools.yml` — only on canonical mathlib4, and only + # when the branch under test doesn't change the cache tool. `get-tools` + # makes that comparison itself against `source_dir` (the already-checked- + # out `pr-branch`), so the tool-source path list lives in the action, not + # duplicated here. + # - Source build: from `tools_source_ref`, pointed at the branch *under + # test* (`pr_branch_ref`) — bors `staging`/`trying`, in-repo dev branches, + # and the nightly-testing repo (which has no `master` branch) — so the + # built tool matches the tree. Fork PRs keep `master` and skip the + # comparison (empty `source_dir`): they run master's `build_template` via + # `pull_request_target`, never this one, and their untrusted tool must + # never be built/run with cache credentials (bors exercises tool changes + # in-repo instead). - name: Get CI tools uses: ./workflow-actions/.github/actions/get-tools with: use_artifact: ${{ inputs.tools_branch_ref == '' && github.repository == 'leanprover-community/mathlib4' }} - tools_source_ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.repository == 'leanprover-community/mathlib4-nightly-testing' && 'nightly-testing-green' || 'master') }} + tools_source_ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} + source_dir: ${{ github.event.pull_request.head.repo.fork != true && 'pr-branch' || '' }} github_token: ${{ github.token }} - name: download dependencies @@ -627,12 +687,29 @@ jobs: # See discussion at https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Some.20files.20not.20found.20in.20the.20cache/near/407183836 if: ${{ always() && needs.build.outputs.cache-staging-has-files == 'true' }} steps: + # Build the write-side cache tool (and load the trust-dispatch action below) + # from the branch under test, so a PR's `--container`-aware tool is what + # writes the cache. This job only runs in trusted in-repo contexts (bors, + # dev branches, the nightly-testing repo) — fork PRs run master's + # `build_template` via `pull_request_target`, never this one — so + # `pr_branch_ref` is always a trusted ref here. Fork PRs keep `master`. - name: Checkout tools branch uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: - ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.repository == 'leanprover-community/mathlib4-nightly-testing' && 'nightly-testing-green' || 'master') }} + ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} fetch-depth: 1 + # Same trust dispatch as in the `build` and `post_steps` jobs. Loaded from + # the tools-branch checkout above (the branch under test, a trusted in-repo + # ref in the contexts where this job runs), which is what the OIDC token's + # container scoping is keyed to. + - name: Compute cache trust dispatch + uses: ./.github/actions/cache-trust-dispatch + with: + repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + branch: ${{ github.head_ref || github.ref_name }} + head-sha: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 with: @@ -658,40 +735,36 @@ jobs: path: cache-staging - name: Azure CLI OIDC login and mint storage bearer token - id: mint_cache_bearer - continue-on-error: true uses: leanprover-community/mathlib-ci/.github/actions/azure-create-cache-token@17db5ff55a65df98d55cbddcc67938f70d10dab2 with: azure-client-id: ${{ inputs.cache_application_id }} azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} - - name: Fallback to SAS token if bearer mint fails (for ease of migration) - if: ${{ steps.mint_cache_bearer.outcome != 'success' }} + - name: Upload staged cache to Azure shell: bash env: - MATHLIB_CACHE_SAS_RAW: ${{ secrets.MATHLIB_CACHE_SAS }} + REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }} run: | - if [ -z "$MATHLIB_CACHE_SAS_RAW" ]; then - echo "Azure bearer mint failed and secrets.MATHLIB_CACHE_SAS is not set" - exit 1 + # $MATHLIB_CACHE_PRIMARY is set by the `Compute cache trust dispatch` + # step above, from the shared composite action that owns the (repo, + # branch) → container mapping for both this job and the read-side + # jobs (build, post_steps). + # Dual-write to the legacy `mathlib4` container first, then the + # primary. Only master CI dual-writes: older cache tools read only + # `legacy`, so it must stay fresh for them, while forks and nightly + # never write `legacy` (keeping low-trust artifacts out of what those + # readers trust). Writing `legacy` first keeps it a superset of + # `master` for as long as we dual-write: with `set -e`, a failed + # legacy write aborts the step before `master` gets artifacts that + # `legacy` lacks. (`put-staged` exits non-zero on real upload + # failures; already-present 409/412 blobs are not failures.) + if [ "$MATHLIB_CACHE_PRIMARY" = "master" ]; then + echo "Dual-writing to legacy container first (keeps legacy a superset of master)..." + lake env "$CACHE_BIN" put-staged --container=legacy --staging-dir="cache-staging" --repo="$REPO" fi - MATHLIB_CACHE_SAS="${MATHLIB_CACHE_SAS_RAW%"${MATHLIB_CACHE_SAS_RAW##*[![:space:]]}"}" - if [ -z "$MATHLIB_CACHE_SAS" ]; then - echo "Azure bearer mint failed and secrets.MATHLIB_CACHE_SAS is empty after trimming" - exit 1 - fi - - echo "::add-mask::$MATHLIB_CACHE_SAS" - echo "MATHLIB_CACHE_AZURE_BEARER_TOKEN=" >> "$GITHUB_ENV" - echo "MATHLIB_CACHE_SAS=$MATHLIB_CACHE_SAS" >> "$GITHUB_ENV" - echo "Using SAS fallback because bearer mint step failed." - - - name: Upload staged cache to Azure - shell: bash - run: | - echo "Uploading cache to Azure..." - MATHLIB_CACHE_USE_CLOUDFLARE=0 lake env "$CACHE_BIN" put-staged --staging-dir="cache-staging" --repo=${{ github.event.pull_request.head.repo.full_name || github.repository }} + echo "Uploading cache to Azure (container: $MATHLIB_CACHE_PRIMARY)..." + lake env "$CACHE_BIN" put-staged --container="$MATHLIB_CACHE_PRIMARY" --staging-dir="cache-staging" --repo="$REPO" post_steps: name: Post-Build Step @@ -710,6 +783,30 @@ jobs: # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false + # Sparse-checkout master's `.github/actions/` so the trust dispatch + # below loads from a trust-rooted source, not from PR-branch-controlled + # content. Mirrors the `Checkout local actions` step in the `build` job. + - name: Checkout local actions + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + ref: ${{ github.workflow_sha }} + fetch-depth: 1 + sparse-checkout: .github/actions + path: workflow-actions + + # Sets MATHLIB_CACHE_FROM in env so the `cache get` calls below pick + # up the trust-class-appropriate read fallback automatically. Replaces + # the previous test-only `--cache-from=master,forks` hardcode that + # lived in this file — that policy is now in the shared composite + # action so build, upload_cache, and post_steps all consult the same + # source of truth. + - name: Compute cache trust dispatch + uses: ./workflow-actions/.github/actions/cache-trust-dispatch + with: + repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + branch: ${{ github.head_ref || github.ref_name }} + head-sha: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 with: diff --git a/.github/workflows/cache_test.yml b/.github/workflows/cache_test.yml new file mode 100644 index 00000000000000..ecf1b87a9cf864 --- /dev/null +++ b/.github/workflows/cache_test.yml @@ -0,0 +1,43 @@ +# Runs the cache tool's unit tests (`lake exe cache-test`) on PRs that touch +# the cache code. The suite is deliberately network-free (see the module +# docstring in `Cache/Test.lean`), so the job only needs the toolchain and the +# package dependencies' sources — not a Mathlib build — and finishes in a few +# minutes on a hosted runner. +name: cache tests + +on: + pull_request: + paths: + - 'Cache/**' + # The `cache-test` target and the toolchain it compiles under live here; + # a bump can break the tool's compilation even with `Cache/` untouched. + - 'lakefile.lean' + - 'lean-toolchain' + +concurrency: + group: cache-test-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + cache-test: + if: github.repository == 'leanprover-community/mathlib4' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: install elan + run: | + set -o pipefail + curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh + chmod +x elan-init.sh + ./elan-init.sh -y --default-toolchain none + echo "$HOME/.elan/bin" >> "${GITHUB_PATH}" + + - name: build cache-test + run: lake build cache-test + + - name: run cache tests + run: .lake/build/bin/cache-test diff --git a/Cache/Cli.lean b/Cache/Cli.lean new file mode 100644 index 00000000000000..e59a239e0122d4 --- /dev/null +++ b/Cache/Cli.lean @@ -0,0 +1,49 @@ +/- +Copyright (c) 2026 Marcelo Lynch. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Marcelo Lynch +-/ + +/-! +# Cache CLI option parsing + +Pure helpers for the cache binary's option parsing. They live here rather than +in `Cache.Main` so the test binary can import them directly — `Cache.Main`'s +top-level `main` would otherwise collide with the test entrypoint. + +The cache binary partitions its arguments into named options (`--name=value`), +boolean flags (`--name`), and positional arguments before dispatch. These +helpers implement that partitioning and the validation of known option names. +-/ + +namespace Cache.Cli + +/-- The named options supported by the CLI. -/ +def knownNamedOpts : List String := + ["repo", "staging-dir", "cache-from", "container", "scope", "unsafe-window"] + +/-- The flag options supported by the CLI. -/ +def knownFlagOpts : List String := ["help", "unsafe"] + +/-- Parses an optional `--foo=bar` option. Returns the value for the +last-mentioned occurrence (so a later `--foo=` overrides an earlier one). -/ +def parseNamedOpt (opt : String) (args : List String) : IO (Option String) := do + let pref := s!"--{opt}=" + if let some a := args.findRev? (fun a => a.startsWith pref) then + let val := a.drop pref.length + return some val.toString + return none + +/-- Parses a boolean `--foo` flag. True iff the bare token `--foo` appears +anywhere in `args`. -/ +def parseFlagOpt (opt : String) (args : List String) : Bool := + args.elem s!"--{opt}" + +/-- Check whether `opt` (e.g. `"--repo=foo"` or `"--help"`) is a recognized +option. Used to error out on unknown `--`-prefixed tokens so typos like +`--scoop=` don't get silently ignored. -/ +def isKnownOpt (opt : String) : Bool := + knownNamedOpts.any (opt.startsWith s!"--{·}=") || + knownFlagOpts.any (opt == s!"--{·}") + +end Cache.Cli diff --git a/Cache/Infra.lean b/Cache/Infra.lean new file mode 100644 index 00000000000000..3b133b2d1e3bd7 --- /dev/null +++ b/Cache/Infra.lean @@ -0,0 +1,151 @@ +/- +Copyright (c) 2026 Marcelo Lynch. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Marcelo Lynch, Arthur Paulino +-/ + +/-! +# Cache backend infrastructure + +The multi-container model — trust-classified Azure containers and the per-repo +lookup chain — together with the GitHub repo names the cache tool dispatches on. + +This lives apart from `Cache.Requests` so the container model and trust ordering +stand on their own, independent of the HTTP/curl machinery that consumes them. +-/ + +namespace Cache.Requests + +open System (FilePath) + +/-- The full name of the main Mathlib GitHub repository. -/ +def MATHLIBREPO := "leanprover-community/mathlib4" + +/-- The full name of the Mathlib nightly-testing GitHub repository. -/ +def NIGHTLY_TESTING_REPO := "leanprover-community/mathlib4-nightly-testing" + +/-- +Trust-classified Azure storage containers for the Mathlib cache. + +Each variant maps to one Azure Blob Storage container on the `lakecache` storage +account. A CI job at a given trust level may write only to its corresponding +container, and `cache get` always tries the most trusted container first. +-/ +inductive Container where + /-- Most-trusted container (`mathlib4-master`); only master CI writes here. -/ + | master + /-- Container for PR builds on forks of mathlib4. -/ + | forks + /-- Container for the `nightly-testing` branch and related refs. -/ + | nightlyTesting + /-- Container for toolchain-PR test runs. -/ + | prToolchainTests + /-- The bare `mathlib4` container that older cache clients read from. Only + master CI writes here (mirroring its `mathlib4-master` upload), so those + clients keep finding master-built artifacts; forks and nightly-testing stay + out to keep low-trust writes from reaching readers that predate the split. -/ + | legacy + deriving DecidableEq, Repr, BEq, Inhabited + +namespace Container + +/-- Canonical short name for a container, used in CLI flags and URLs. -/ +def name : Container → String + | .master => "master" + | .forks => "forks" + | .nightlyTesting => "nightly-testing" + | .prToolchainTests => "pr-toolchain-tests" + | .legacy => "legacy" + +/-- All known containers, listed in their canonical declaration order. -/ +def all : List Container := + [.master, .forks, .nightlyTesting, .prToolchainTests, .legacy] + +/-- Parse a short name back into a `Container`. Matching is case-insensitive. -/ +def parse? (s : String) : Option Container := + match s.toLower with + | "master" => some .master + | "forks" => some .forks + | "nightly-testing" => some .nightlyTesting + | "pr-toolchain-tests" => some .prToolchainTests + | "legacy" => some .legacy + | _ => none + +/-- +Azure storage container name on the `lakecache` storage account. + +Trust-level containers follow the `mathlib4-{name}` convention; `legacy` is the +bare `mathlib4` container. +-/ +def azureContainerName : Container → String + | .legacy => "mathlib4" + | c => s!"mathlib4-{c.name}" + +/-- Public Azure Blob Storage base URL for a container. -/ +def azureURL (c : Container) : String := + s!"https://lakecache.blob.core.windows.net/{c.azureContainerName}" + +/-- +Whether file lookups in this container use the flat `/f/` layout, or +namespace under `/f//`. + +The layout is fixed per container, not per repo, because one container holds +artifacts from several writers whose `repo` need not match the container's +trust level, and a stable per-container layout is what keeps readers and +writers in sync. + +- `master` is flat: RBAC admits only master CI, whose writes all carry + `repo == MATHLIBREPO`, so a single hash never collides. +- `legacy` keys the layout on the writer: `MATHLIBREPO` writes are flat (where + older `mathlib4` readers look for them), fork writes are repo-namespaced. +- `forks`, `nightly-testing`, and `pr-toolchain-tests` always namespace by + repo. They collect artifacts from many writers — different forks, different + toolchain refs, and canonical-repo builds whose trust is fork-equivalent + (`ci-dev/*`, `bors trying`) — so identical hashes from different writers must + stay on distinct paths. +-/ +def flatPath (c : Container) (repo : String) : Bool := + match c with + | .master => true + | .legacy => repo == MATHLIBREPO + | _ => false + +end Container + +/-- +Comma-separated list parser for `--cache-from=a,b,c`. + +Returns `none` if any element is unrecognized. +-/ +def parseCacheFromList (s : String) : Option (List Container) := do + let parts := s.splitOn "," + parts.mapM (fun p => Container.parse? p.trimAscii.toString) + +/-- +Trust-ordered containers to try when downloading for a given GitHub repo, most +trusted first. Each repo reads from its own trust-level container, with `legacy` +appended so older clients' artifacts stay reachable. + +Fork chains lead with `master`. The layout is fixed per container +(`Container.flatPath`), so the `master` container is read flat at `/f/{hash}` +whatever the `repo` is, and a fork build finds the master-built deps that make +up the bulk of its files there; the fork's own container then supplies the +PR-specific files at `/f/{repo}/...`. + +Nightly-testing chains omit `master`: that repo builds under a non-release +toolchain, so its root hash differs and a master probe never matches. +-/ +def defaultContainersForRepo (repo : String) : List Container := + if repo == MATHLIBREPO then + [.master, .legacy] + else if repo == NIGHTLY_TESTING_REPO then + -- Trusted-nightly consumers (`nightly-testing`, `nightly-testing-green`, + -- `bump/*`) read only `nightly-testing` + `legacy`; `pr-toolchain-tests` is + -- excluded so low-trust toolchain-PR uploads can't reach them. Toolchain-PR + -- branches opt into reading their own uploads with `--cache-from=...` (or, + -- in CI, via the `MATHLIB_CACHE_FROM` env var). + [.nightlyTesting, .legacy] + else + -- Forks and everything else: `master` for shared upstream deps, the fork's + -- own container for PR-specific files, then `legacy`. + [.master, .forks, .legacy] diff --git a/Cache/Init.lean b/Cache/Init.lean deleted file mode 100644 index 7ceceb43495b13..00000000000000 --- a/Cache/Init.lean +++ /dev/null @@ -1,16 +0,0 @@ -/- -Copyright (c) 2023 Arthur Paulino. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Arthur Paulino --/ - -namespace Cache.Requests - -open System (FilePath) - --- Cloudflare cache may be flaky: https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/The.20cache.20doesn't.20work/near/411058849 --- This is defined in a separate file because it is used in the definition of `URL` and `UPLOAD_URL` --- and Lean does not allow one `initialize` to use another `initialize` defined in the same file -initialize useCloudflareCache : Bool ← do - let cache ← IO.getEnv "MATHLIB_CACHE_USE_CLOUDFLARE" - return cache == some "1" || cache == some "true" diff --git a/Cache/Main.lean b/Cache/Main.lean index 4949ad7677f0ca..dcce94de04f8fd 100644 --- a/Cache/Main.lean +++ b/Cache/Main.lean @@ -1,10 +1,14 @@ /- Copyright (c) 2023 Arthur Paulino. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Arthur Paulino, Jon Eugster +Authors: Arthur Paulino, Jon Eugster, Marcelo Lynch -/ +import Cache.Cli import Cache.Requests +import Cache.Marker +import Cache.Query +import Cache.Warning def help : String := "Mathlib4 caching CLI Usage: cache [OPTIONS] [COMMAND] @@ -21,6 +25,8 @@ Commands: clean Delete non-linked files clean! Delete everything on the local cache lookup [ARGS] Show information about cache files for the given Lean files + query [REF] Without REF: find most recent cached commit on this branch. + With REF (e.g. HEAD, a SHA): boolean probe; exit 0 if cached, 1 if not. # Privilege required put Run 'pack' then upload linked files missing on the server @@ -39,6 +45,30 @@ Commands: Options: --repo=OWNER/REPO Override the repository to fetch/push cache from --staging-dir= Required for 'stage', 'stage!', 'unstage' and 'put-staged': staging directory. + --cache-from=LIST Comma-separated, trust-ordered list of containers to read from + (e.g. `--cache-from=master,forks`). Overrides the per-repo default. + Known containers: master, forks, nightly-testing, + pr-toolchain-tests, legacy. + --scope=REF Read the fork SHA-scoped namespace at the given commit ref + (any git ref `git rev-parse` accepts: HEAD, branch, tag, SHA) + instead of the default, the checked-out HEAD. Use the SHA + reported by `cache query`. Wins over the + MATHLIB_CACHE_REPO_SCOPE env var. Reading another commit's + scope means trusting the artifacts produced at that commit; + `cache get` prints a security notice when the scope differs + from HEAD. + --unsafe (get only) Instead of pinning one --scope, automatically walk + this branch's history and try the most recent cached fork + commits as scopes, in order, until the cache is satisfied. + Trusts the artifacts of every commit it tries. Mutually + exclusive with --scope; always prints a security notice. + --unsafe-window=N Number of cached fork commits --unsafe will try (default + 1). Implies --unsafe. + --container=NAME Target container for upload commands (put/put!/put-unpacked/ + put-staged/commit/commit!). Known containers: master, forks, + nightly-testing, pr-toolchain-tests, legacy. Pass this + explicitly; with neither it nor MATHLIB_CACHE_PUT_URL set, + the upload falls back to `legacy` and warns. * Linked files refer to local cache files with corresponding Lean sources * Commands ending with '!' should be used manually, when hot-fixes are needed @@ -63,9 +93,11 @@ Valid arguments are: # Environment variables * MATHLIB_CACHE_DIR Local cache directory (default: ~/.cache/mathlib) -* MATHLIB_CACHE_USE_CLOUDFLARE Set to '1' to use Cloudflare instead of Azure -* MATHLIB_CACHE_GET_URL Override the download URL -* MATHLIB_CACHE_PUT_URL Override the upload URL +* MATHLIB_CACHE_GET_URL Download from this single URL, bypassing the containers +* MATHLIB_CACHE_PUT_URL Upload to this single URL, bypassing the containers +* MATHLIB_CACHE_FROM Comma-separated container list for reads, same shape as + --cache-from. Used by CI to widen reads per job; + --cache-from takes precedence when both are set. See Cache/README.md for more details. " @@ -78,30 +110,7 @@ def curlArgs : List String := def leanTarArgs : List String := ["get", "get!", "put", "put!", "put-unpacked", "pack", "pack!", "unpack", "lookup", "stage", "stage!"] -/-- The named options supported by the CLI. -/ -def knownNamedOpts : List String := ["repo", "staging-dir"] - -/-- The flag options supported by the CLI. -/ -def knownFlagOpts : List String := ["help"] - -/-- Parses an optional `--foo=bar` option. -/ -def parseNamedOpt (opt : String) (args : List String) : IO (Option String) := do - let pref := s!"--{opt}=" - if let some a := args.findRev? (fun a => a.startsWith pref) then - let val := a.drop pref.length - return some val.toString - return none - -/-- Parses a boolean `--foo` flag. -/ -def parseFlagOpt (opt : String) (args : List String) : Bool := - args.elem s!"--{opt}" - -/-- Check whether `opt` (e.g. `"--repo=foo"` or `"--help"`) is a recognized option. -/ -def isKnownOpt (opt : String) : Bool := - knownNamedOpts.any (opt.startsWith s!"--{·}=") || - knownFlagOpts.any (opt == s!"--{·}") - -open Cache IO Hashing Requests System in +open Cache Cli IO Hashing Requests System in def main (args : List String) : IO Unit := do if args.isEmpty || parseFlagOpt "help" args then println help @@ -120,6 +129,79 @@ def main (args : List String) : IO Unit := do let repo? ← parseNamedOpt "repo" options let stagingDir? ← parseNamedOpt "staging-dir" options + let cacheFromStr? ← parseNamedOpt "cache-from" options + let containerStr? ← parseNamedOpt "container" options + let scopeStr? ← parseNamedOpt "scope" options + let unsafeFlag := parseFlagOpt "unsafe" options + let unsafeWindowStr? ← parseNamedOpt "unsafe-window" options + + -- Resolve `--unsafe` / `--unsafe-window=N` into an optional SHA window. + -- `some n` means unsafe mode is on with window `n`; `none` means off. Passing + -- `--unsafe-window` implies `--unsafe`. + let unsafeWindow? : Option Nat ← match unsafeWindowStr? with + | some s => match s.toNat? with + | some n => + if n == 0 then + IO.eprintln "--unsafe-window must be a positive integer" + Process.exit 1 + pure (some n) + | none => + IO.eprintln s!"--unsafe-window must be a positive integer (got '{s}')" + Process.exit 1 + | none => pure (if unsafeFlag then some defaultUnsafeSHAWindow else none) + + -- `--unsafe` and `--scope` are mutually exclusive: `--unsafe` walks several + -- commit scopes automatically, `--scope` pins exactly one. + if unsafeWindow?.isSome && scopeStr?.isSome then + IO.eprintln "--unsafe and --scope are mutually exclusive: --unsafe walks several commit \ + scopes automatically, while --scope pins exactly one." + Process.exit 1 + + -- Apply `--scope=` to the process-wide override read by `getRepoScope`. + -- Accepts any git ref `git rev-parse` resolves (HEAD, branch, tag, SHA); + -- falls through to the literal value if `git rev-parse` is unavailable + -- (e.g. invoked outside a git checkout with a bare SHA). + if let some s := scopeStr? then + let resolved ← try resolveGitRef s catch _ => pure s + scopeOverride.set (some resolved) + + -- Apply `--cache-from` to the process-wide override read by `effectiveGetURLs`. + if let some s := cacheFromStr? then + match parseCacheFromList s with + | none => + IO.eprintln s!"Unknown container name in --cache-from={s}.\n\ + Known containers: {", ".intercalate (Container.all.map Container.name)}." + Process.exit 1 + | some cs => cacheFromOverride.set (some cs) + + -- Parse `--container=NAME`. Validation is unconditional; the upload commands + -- enforce that the flag is set (via `effectiveUploadURL`). + let container? ← match containerStr? with + | none => pure none + | some s => match Container.parse? s with + | some c => pure (some c) + | none => + IO.eprintln s!"Unknown container name in --container={s}.\n\ + Known containers: {", ".intercalate (Container.all.map Container.name)}." + Process.exit 1 + + -- Early dispatch for `query`: avoids running `parseArgs` (which would try to + -- interpret a git ref like `HEAD` as a Lean module) and skips the expensive + -- hash-memo build below — the query only needs git + a single HTTP probe. + match args with + | ["query"] => + let repo ← resolveQueryRepo repo? + cacheQuery repo (cap := 50) + return + | ["query", ref] => + let repo ← resolveQueryRepo repo? + let sha ← resolveGitRef ref + cacheQuerySingle repo sha + return + | "query" :: _ => + IO.eprintln "Usage: cache query [REF]" + Process.exit 1 + | _ => pure () let mut roots : Std.HashMap Lean.Name FilePath ← parseArgs args if roots.isEmpty then do @@ -135,12 +217,38 @@ def main (args : List String) : IO Unit := do let goodCurl ← pure !curlArgs.contains (args.headD "") <||> validateCurl let get (args : List String) (force := false) (decompress := true) := do let hashMap ← if args.isEmpty then pure hashMap else hashMemo.filterByRootModules roots.keys - getFiles repo? hashMap force force goodCurl decompress + -- Resolve the repo once (single git-remote probe) and thread it through the + -- read path, the non-default-scope warning, and the HEAD hint below. + let cliOverride? ← cacheFromOverride.get + let (detectedRepo?, resolvedRepo) ← resolveRepo repo? (← read).mathlibDepPath + -- Warn before reading if the scope is non-default (`--unsafe` always is). + warnIfNonDefaultScope repo? detectedRepo? cliOverride? resolvedRepo unsafeWindow? + -- In `--unsafe` mode, walk history for recent cached fork commits to try as + -- scopes; otherwise point an uncached fork HEAD at the per-commit workflow. + let unsafeScopes ← match unsafeWindow? with + | some window => + let scopes ← discoverUnsafeScopes resolvedRepo window + if scopes.isEmpty then + IO.eprintln s!"--unsafe: no cached fork commits found in range for {resolvedRepo}; \ + reading the default cache only." + else + IO.eprintln s!"--unsafe: trying {scopes.length} cached fork commit scope(s) for \ + {resolvedRepo} (most recent first):" + for s in scopes do IO.eprintln s!" {s}" + pure scopes + | none => + informIfHeadNotBuilt resolvedRepo + pure [] + getFiles resolvedRepo hashMap force force goodCurl decompress (unsafeScopes := unsafeScopes) let pack (overwrite verbose unpackedOnly := false) := do packCache hashMap overwrite verbose unpackedOnly (← getGitCommitHash) let put (overwrite unpackedOnly := false) := do let repo := repo?.getD MATHLIBREPO - putFiles repo (← pack overwrite (verbose := true) unpackedOnly) overwrite (← getUploadAuth) + let auth ← getUploadAuth + putFiles repo container? (← pack overwrite (verbose := true) unpackedOnly) overwrite auth + if let some sha ← getRepoScope then + if let some c := container? then + uploadMarker c repo sha auth let stage outDir (unpackedOnly := true) := do stageFiles outDir (← pack (verbose := true) (unpackedOnly := unpackedOnly)) let unstage (overwrite := false) := do @@ -151,8 +259,15 @@ def main (args : List String) : IO Unit := do if !(←stagingDir.isDir) then IO.println "--staging-dir must be a directory" return else let fileSet ← getFilesWithExtension stagingDir "ltar" - putFilesAbsolute repo fileSet (tempConfigFilePath := stagingDir / "curl.config") - (overwrite := false) (← getUploadAuth) + let auth ← getUploadAuth + putFilesAbsolute repo container? fileSet (tempConfigFilePath := stagingDir / "curl.config") + (overwrite := false) auth + -- After artifacts upload, write the per-SHA marker if the upload is + -- SHA-scoped. The marker lets `cache query` discover cached commits + -- with a cheap HEAD probe. + if let some sha ← getRepoScope then + if let some c := container? then + uploadMarker c repo sha auth match args with | "get" :: args => get args @@ -179,10 +294,10 @@ def main (args : List String) : IO Unit := do putStaged stagingDir?.get! | ["commit"] => if !(← isGitStatusClean) then IO.println "Please commit your changes first" return else - commit hashMap false (← getUploadAuth) + commit container? hashMap false (← getUploadAuth) | ["commit!"] => if !(← isGitStatusClean) then IO.println "Please commit your changes first" return else - commit hashMap true (← getUploadAuth) + commit container? hashMap true (← getUploadAuth) | ["collect"] => IO.println "TODO" | "lookup" :: _ => lookup hashMap roots.keys | [] => println help -- unreachable: options are already partitioned out diff --git a/Cache/Marker.lean b/Cache/Marker.lean new file mode 100644 index 00000000000000..56a3e9d43def93 --- /dev/null +++ b/Cache/Marker.lean @@ -0,0 +1,64 @@ +/- +Copyright (c) 2026 Marcelo Lynch. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Marcelo Lynch +-/ + +import Cache.Requests + +/-! +# Per-SHA cache markers + +A marker is a tiny blob at `/m/{repo}/{sha}` whose existence signals that the +full `.ltar` upload for a commit completed. `put-staged` writes it as the last +upload step, and `cache query` probes it to discover cached commits with a +cheap HEAD request instead of a blob listing. +-/ + +namespace Cache.Requests + +open System (FilePath) + +/-- +URL for the per-SHA marker blob: `{container}/m/{repo}/{sha}`. + +The marker is uploaded by `put-staged` as the last step when an upload is +SHA-scoped (`MATHLIB_CACHE_REPO_SCOPE` set). Its presence at this URL +indicates that the full `.ltar` upload completed for this commit, and lets +`cache query` discover cached commits with a cheap HEAD probe rather than +a blob-listing call. +-/ +def markerURL (container : Container) (repo sha : String) : String := + s!"{container.azureURL}/m/{repo}/{sha}" + +/-- +Upload a tiny marker blob to `/m/{repo}/{sha}` in the given container. The +blob content is the SHA itself, as a debugging aid; existence is the +signal. + +Called from `put` and `put-staged` after the `.ltar` artifact uploads +complete. If this PUT fails the artifacts are already uploaded — the only +loss is that `cache query` will not find this commit — so failures here +are logged but not fatal. +-/ +def uploadMarker (container : Container) (repo sha : String) (auth : UploadAuth) : + IO Unit := do + let url := markerURL container repo sha + let path := IO.CACHEDIR / s!"marker-{sha}" + IO.FS.createDirAll IO.CACHEDIR + IO.FS.writeFile path s!"{sha}\n" + let azureDateHeader ← getAzureDateHeader + try + match auth with + | .azureSas token => + let params := #["-X", "PUT", "-H", "x-ms-blob-type: BlockBlob"] + discard <| IO.runCurl <| params ++ #["-T", path.toString, s!"{url}?{token}"] + | .azureBearer token => + let params := #["-X", "PUT", "-H", "x-ms-blob-type: BlockBlob", "-H", + azureBearerApiVersionHeader, "-H", azureDateHeader, "--oauth2-bearer", token] + discard <| IO.runCurl <| params ++ #["-T", path.toString, url] + catch e => + IO.eprintln s!"warning: marker upload to {url} failed: {e}" + IO.FS.removeFile path + +end Cache.Requests diff --git a/Cache/Query.lean b/Cache/Query.lean new file mode 100644 index 00000000000000..147f1d16723b4e --- /dev/null +++ b/Cache/Query.lean @@ -0,0 +1,229 @@ +/- +Copyright (c) 2026 Marcelo Lynch. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Marcelo Lynch +-/ + +import Cache.Marker + +/-! +# The `cache query` subcommand + +Discovers the most recent commit on the current branch that has a cached CI +build, by walking git history back to the merge base with `master` and probing +each commit's per-SHA marker. Diagnostic only: it prints a SHA for the user to +pass to `cache get --scope=`, and never reads or writes artifacts itself. +-/ + +namespace Cache.Requests + +open System (FilePath) + +/-- +Walk git log backwards from HEAD, starting from `startRef`, stopping at +`stopRef` or after `cap` commits (whichever comes first). + +Returns the list of commit SHAs in reverse chronological order (most recent first). +-/ +def gitLogWalk (startRef stopRef : String) (cap : Nat) (cwd : FilePath := ".") : + IO (List String) := do + -- Construct git log command: walk from startRef to stopRef (if provided) using first-parent. + -- First-parent follows the main branch across merges, which is the intended behavior. + let args := if stopRef.isEmpty then + #["log", startRef, "--first-parent", "--pretty=format:%H", s!"--max-count={cap}"] + else + #["log", s!"{startRef}...{stopRef}", "--first-parent", "--pretty=format:%H", s!"--max-count={cap}"] + let out ← IO.Process.output {cmd := "git", args := args, cwd := cwd} + unless out.exitCode == 0 do + throw <| IO.userError + s!"git log failed (exit code {out.exitCode}):\n{out.stderr.trimAscii}" + let shas := out.stdout.trimAscii.toString.splitOn "\n" |>.filter (· ≠ "") + pure shas + +/-- +Determine the merge base between `HEAD` and a target ref (typically `master`). +Falls back to a cap-only walk if the ref is not reachable. +-/ +def gitMergeBase (targetRef : String) (cwd : FilePath := ".") : IO (Option String) := do + let out ← IO.Process.output + {cmd := "git", args := #["merge-base", "HEAD", targetRef], cwd := cwd} + if out.exitCode == 0 then + pure (some out.stdout.trimAscii.toString) + else + -- merge-base failed (target ref not reachable); return none to signal cap-only walk + pure none + +/-- +Return `true` if `HEAD` is an ancestor of (or equal to) the local `master` +branch — i.e. the current commit is already part of master's history and has no +fork-specific divergence. + +Uses `git merge-base --is-ancestor HEAD master`, which exits 0 when HEAD is an +ancestor of master and 1 when it is not. Any other outcome (e.g. `master` not +present locally, or git unavailable) is treated as "not an ancestor", so callers +degrade to their default behavior rather than throwing — matching the never-throw +posture of the rest of the read path. +-/ +def headIsAncestorOfMaster (cwd : FilePath := ".") : IO Bool := do + try + let out ← IO.Process.output + {cmd := "git", args := #["merge-base", "--is-ancestor", "HEAD", "master"], cwd := cwd} + pure (out.exitCode == 0) + catch _ => + pure false + +/-- +Probe a single container for the per-SHA marker blob. + +Issues an anonymous HEAD against `{container}/m/{repo}/{sha}` and returns +`true` iff the response is 200. The marker is uploaded by `put-staged` +after a successful upload, so its existence is a reliable "this commit +was fully cached" signal. + +Cheaper than blob-listing: deterministic URL, headers-only response, +billed as a Read op. +-/ +def probeContainerForSHA (container : Container) (repo sha : String) : + IO Bool := do + let url := markerURL container repo sha + let out ← IO.Process.output + {cmd := (← IO.getCurl), + args := #["-s", "-o", "/dev/null", "-w", "%{http_code}", "-I", url], + cwd := "."} + if out.exitCode != 0 then + -- Network error; assume no cache at this SHA + pure false + else + pure (out.stdout.trimAscii.toString == "200") + +/-- Default number of marked fork commits `cache get --unsafe` will try as SHA +scopes: 1, namely just the latest cached SHA. Overridden by +`--unsafe-window=N`. -/ +def defaultUnsafeSHAWindow : Nat := 1 + +/-- +Walk a list of SHAs (most recent first) and collect up to `limit` of them whose +per-SHA marker exists in the `forks` container. Stops early once `limit` are +found, so at most `limit` probes succeed (and at most `shas.length` are made). + +`forks` is the only SHA-scoped container; master/nightly-testing/pr-toolchain-tests +are not scoped, so probing them here would be meaningless. +-/ +def findRecentSHAsWithCache (shas : List String) (repo : String) (limit : Nat) : + IO (List String) := do + let container := Container.forks + let mut found : Array String := #[] + for sha in shas do + if found.size ≥ limit then break + if ← probeContainerForSHA container repo sha then + found := found.push sha + pure found.toList + +/-- +Given a list of SHAs, find the most recent one that has cached entries in the +forks container under the SHA-scoped namespace. Returns the first SHA the probe +accepts, or none if none are found. +-/ +def findMostRecentSHAWithCache (shas : List String) (repo : String) : + IO (Option String) := + return (← findRecentSHAsWithCache shas repo 1).head? + +/-- +Resolve a git ref (HEAD, branch name, tag, short SHA, full SHA) to a full +commit SHA via `git rev-parse`. Errors propagate if the ref is unknown. +-/ +def resolveGitRef (ref : String) (cwd : FilePath := ".") : IO String := do + let out ← IO.Process.output {cmd := "git", args := #["rev-parse", ref], cwd := cwd} + unless out.exitCode == 0 do + throw <| IO.userError + s!"git rev-parse {ref} failed (exit code {out.exitCode}):\n{out.stderr.trimAscii}" + pure out.stdout.trimAscii.toString + +/-- +Resolve the repo to use for a `cache query` invocation. + +Precedence: the explicit `--repo=` flag (if passed) > the cwd's git remote +> `MATHLIBREPO`. Defaulting to the git remote is intentional for `query` — +the typical user is asking "what's cached for *my* commits", not for +canonical mathlib's commits. +-/ +def resolveQueryRepo (repoExplicit? : Option String) : IO String := do + match repoExplicit? with + | some r => pure r + | none => + match ← getRemoteRepo "." with + | some info => pure info.repo + | none => pure MATHLIBREPO + +/-- +Boolean probe for a single commit: prints `cached` or `not cached` and exits +with status 0 / 1 respectively. Intended for scripting. + +Probes the `forks` container's per-SHA marker, the only SHA-scoped container. +-/ +def cacheQuerySingle (repo sha : String) : IO Unit := do + let cached ← probeContainerForSHA Container.forks repo sha + if cached then + IO.println s!"cached: {sha}" + else + IO.println s!"not cached: {sha}" + (← IO.getStdout).flush + IO.Process.exit 1 + +/-- +Implement the `cache query` subcommand. + +Walks git log backwards from HEAD, stopping at the merge base with `master` +(or a hard cap if the merge base is not reachable), and probes each commit's +SHA-scoped namespace to find the most recent commit that has cache entries. + +This is a diagnostic-only command: it prints the SHA to stdout but does not +auto-apply it. The user manually passes the result to `cache get` if desired. +-/ +def cacheQuery (repo : String) (cap : Nat := 50) (cwd : FilePath := ".") : IO Unit := do + -- Determine merge base with master. If not reachable, use cap-only walk. + let mergeBase? ← gitMergeBase "master" cwd + let stopRef := mergeBase?.getD "" + + -- Walk git log backwards from HEAD. + let shas ← gitLogWalk "HEAD" stopRef cap cwd + if shas.isEmpty then + IO.println "No commits found to walk (repository history is empty)" + return + + -- Probe each SHA in order (most recent first). + let found? ← findMostRecentSHAWithCache shas repo + match found? with + | some sha => + IO.println s!"Most recent cached commit on this branch for fork {repo}: {sha}" + IO.println s!"" + IO.println s!"To use this cache, run:" + IO.println s!" lake exe cache get --scope={sha}" + IO.println s!"" + IO.println s!"Note: this means trusting the artifacts built at that commit;" + IO.println s!"`cache get` will print a security notice when --scope is set." + | none => + IO.println s!"No cached CI build found for fork {repo} within the last {cap} commits on this branch." + IO.println s!"This usually means CI hasn't built any of these commits yet." + +/-- +Discover the SHA scopes `cache get --unsafe` should try, most recent first. + +Walks git history from HEAD back to the merge base with `master` (or a hard +`cap` if the merge base is not reachable) and returns up to `window` commit SHAs +whose per-SHA marker exists in the `forks` container — i.e. the most recent +`window` commits on this branch that CI has fully cached for this fork. + +Unlike `cacheQuery`, this is consumed automatically by `cache get` rather than +printed for the user, and it returns several SHAs instead of one. An empty +result means no cached commit was found in range; the caller falls back to a +normal (unscoped) read. +-/ +def discoverUnsafeScopes (repo : String) (window : Nat := defaultUnsafeSHAWindow) + (cap : Nat := 50) (cwd : FilePath := ".") : IO (List String) := do + let mergeBase? ← gitMergeBase "master" cwd + let stopRef := mergeBase?.getD "" + let shas ← gitLogWalk "HEAD" stopRef cap cwd + findRecentSHAsWithCache shas repo window + +end Cache.Requests diff --git a/Cache/README.md b/Cache/README.md index 2c25714653f41c..d027fb238a44c1 100644 --- a/Cache/README.md +++ b/Cache/README.md @@ -4,6 +4,9 @@ This directory contains the implementation of Mathlib's build cache system (`lak > **Note**: A new `lake cache` command is currently being designed and implemented in Lake itself. This will eventually replace the Mathlib-specific `lake exe cache` and work for all repositories. Until then, this cache system remains the primary way to get pre-built artifacts for Mathlib. +> **Trust model & security**: see [`SECURITY.md`](./SECURITY.md) for the +> trust model behind the multi-container split. + ## Quick Start ```bash @@ -34,6 +37,7 @@ lake exe cache get Mathlib.Algebra.Group.Basic | `clean` | Delete non-linked files | | `clean!` | Delete everything on the local cache | | `lookup [ARGS]` | Show information about cache files for the given Lean files | +| `query` | Find the most recent commit with cached entries on the current branch | ### Privilege Required (CI/Maintainers) @@ -61,37 +65,47 @@ When arguments are provided, only the specified files and their transitive impor | Option | Description | |---------------------|--------------------------------------------------------------------------------------------| | `--repo=OWNER/REPO` | Override the repository to fetch cache from (e.g., `--repo=leanprover-community/mathlib4`) | +| `--cache-from=LIST` | For `get`/`get!`/`get-`/`lookup`: trust-ordered, comma-separated list of containers to read from. Overrides the per-repo default (see [Trust-ordered containers](#trust-ordered-containers)). | +| `--scope=REF` | For `get`/`get!`/`get-`: read from the SHA-scoped namespace for the given git ref (anything `git rev-parse` accepts: `HEAD`, branch, tag, SHA). Use the SHA reported by `cache query`. Triggers the non-default-scope security notice. | +| `--unsafe` | For `get`/`get!`/`get-`: instead of pinning one `--scope`, automatically walk this branch's history and read the `forks` container at the most recent cached fork commit (newest first if `--unsafe-window` allows more than one), until the cache is satisfied (see [Unsafe automatic scope walk](#unsafe-automatic-scope-walk)). Mutually exclusive with `--scope`; always triggers the security notice. | +| `--unsafe-window=N` | Number of cached fork commits `--unsafe` will try (default `1`). Implies `--unsafe`. | +| `--container=NAME` | For `put`/`put!`/`put-unpacked`/`put-staged`/`commit`/`commit!`: target container for upload. | -## Environment Variables +Container names (known to both flags): `master`, `forks`, `nightly-testing`, `pr-toolchain-tests`, `legacy`. -### Cache Location +## Trust-ordered containers -| Variable | Description | Default | -|---------------------|------------------------------------|-------------------------------------------------| -| `MATHLIB_CACHE_DIR` | Directory for cached `.ltar` files | `$XDG_CACHE_HOME/mathlib` or `~/.cache/mathlib` | +The cache is split across multiple Azure Blob Storage containers on the +`lakecache` storage account. Container names accepted by `--container=NAME` +and `--cache-from=LIST`: `master`, `forks`, `nightly-testing`, +`pr-toolchain-tests`, `legacy`. -### Cache Backend Selection +`cache get` resolves a file by trying a default chain of containers in +order, depending on the repo: -| Variable | Description | Default | -|--------------------------------|----------------------------------------------------------|-------------| -| `MATHLIB_CACHE_USE_CLOUDFLARE` | Set to `1` or `true` to use Cloudflare R2 instead of Azure | Azure cache | +| GitHub repo | Container order tried | +|-------------------------------------------------|-----------------------------| +| `leanprover-community/mathlib4` | `master`, `legacy` | +| `leanprover-community/mathlib4-nightly-testing` | `nightly-testing`, `legacy` | +| any fork (PRs) | `master`, `forks`, `legacy` | -### Custom Cache URLs +Override the read chain with `--cache-from=LIST`: -These allow overriding the cache endpoints, useful for mirrors or custom deployments: +```bash +# Read only from the master container +lake exe cache get --cache-from=master -| Variable | Description | Default | -|-------------------------|---------------------------------|-------------------------------------------------------------------| -| `MATHLIB_CACHE_GET_URL` | URL for downloading cache files | Azure or Cloudflare URL based on `MATHLIB_CACHE_USE_CLOUDFLARE` | -| `MATHLIB_CACHE_PUT_URL` | URL for uploading cache files | Azure or Cloudflare URL based on `MATHLIB_CACHE_USE_CLOUDFLARE` | +# Read master first, then forks +lake exe cache get --cache-from=master,forks +``` -### Authentication (for uploads) +Uploads target a single container via `--container=NAME`. -| Variable | Description | -|--------------------------|------------------------------------------------| -| `MATHLIB_CACHE_AZURE_BEARER_TOKEN` | Azure bearer token (preferred for Azure backend) | -| `MATHLIB_CACHE_SAS` | Azure SAS token fallback (for Azure backend) | -| `MATHLIB_CACHE_S3_TOKEN` | S3 credentials (when using Cloudflare backend) | +## Environment Variables + +| Variable | Description | Default | +|---------------------|------------------------------------|-------------------------------------------------| +| `MATHLIB_CACHE_DIR` | Directory for cached `.ltar` files | `$XDG_CACHE_HOME/mathlib` or `~/.cache/mathlib` | ## How It Works @@ -140,92 +154,134 @@ The cache covers these packages: - `Archive` - `Counterexamples` -## Default Cache Backends +## Finding Cached Commits with `query` -### Azure Blob Storage (Default) +For branches with per-commit SHA scoping (e.g., fork PRs), you can use +`lake exe cache query` to discover which recent commits on your branch have +cached entries. This is useful when your current branch has diverged from +upstream and you want to avoid waiting for CI to build everything. -- **Download URL**: `https://lakecache.blob.core.windows.net/mathlib4` -- Used by default for downloads and uploads - -### Cloudflare R2 +```bash +# Find the most recent cached commit on the current branch +lake exe cache query + +# Example output: +# Most recent cached commit on branch: 5a3c7e9a2f8c1d6b4e0f9a2c3d4e5f6a7b8c9d0e +# Repository: leanprover-community/mathlib4 +# Container: forks +# +# To use this cache, run: +# lake exe cache get --scope=5a3c7e9a2f8c1d6b4e0f9a2c3d4e5f6a7b8c9d0e +``` -- **Download URL**: `https://mathlib4.lean-cache.cloud` -- **Upload URL**: `https://a09a7664adc082e00f294ac190827820.r2.cloudflarestorage.com/mathlib4` -- Enable with `MATHLIB_CACHE_USE_CLOUDFLARE=1` +The `query` command walks your git log backwards from `HEAD`, stopping at the +merge base with `master` or a hard cap of 50 commits (whichever comes first), +and probes each commit for a completed SHA-scoped upload in the `forks` +container. That signal is written by `put-staged` only after a successful +upload, so its presence is a reliable "this commit was cached" signal. `query` +prints the SHA to stdout (and does not auto-apply it) — you manually copy the +result into your `cache get` command if desired. -## Setting Up Your Own Cache Endpoint +### Boolean probe on a single commit -You can host your own cache mirror or private cache using any S3-compatible storage or HTTP server. +`lake exe cache query ` checks a specific commit and exits with 0 (cached) +or 1 (not cached). The ref can be `HEAD`, a branch name, a tag, or a SHA — anything +`git rev-parse` accepts. -### Requirements +```bash +# Is the current checkout's HEAD cached? +lake exe cache query HEAD && echo "yes" || echo "no" -Your endpoint must support: +# Is a specific SHA cached? +lake exe cache query 5a3c7e9a2f8c1d6b4e0f9a2c3d4e5f6a7b8c9d0e +# prints "cached: 5a3c7e9a..." (exit 0) or "not cached: 5a3c7e9a..." (exit 1) +``` -1. **GET requests** for downloading files at: - - `/f/{repo}/{hash}.ltar` - for fork caches - - `/f/{hash}.ltar` - for main mathlib cache (Azure only) - - `/c/{commit_hash}` - for commit manifests +By default `query` (both modes) targets the cwd's git remote — pass `--repo=` +to override. -2. **PUT requests** for uploading (if you need upload capability) +### Unsafe automatic scope walk -### Using a Custom Endpoint +`cache get --unsafe` folds the `query` discovery into the download itself: rather +than asking you to copy one SHA into `--scope=`, it walks your branch history +(`HEAD` back to the merge base with `master`) for commits that have a cached fork +build and reads the `forks` container at their scope. By +default it uses just the single most recent such commit; `--unsafe-window=N` +widens this to the `N` most recent, tried newest first with files fetched in one +round dropped from the next. ```bash -# Download from a custom mirror -export MATHLIB_CACHE_GET_URL="https://my-mirror.example.com/mathlib4" -lake exe cache get - -# Upload to a custom endpoint -export MATHLIB_CACHE_PUT_URL="https://my-upload.example.com/mathlib4" -export MATHLIB_CACHE_AZURE_BEARER_TOKEN="your-bearer-token" # preferred for Azure -# export MATHLIB_CACHE_SAS="your-sas-token" # Azure fallback -# export MATHLIB_CACHE_S3_TOKEN="ACCESS_KEY:SECRET_KEY" # for S3/Cloudflare -lake exe cache put +lake exe cache get --unsafe # use the most recent cached fork commit +lake exe cache get --unsafe-window=10 # try the 10 most recent (implies --unsafe) ``` -### Example: S3-Compatible Storage +The trust-ordered container chain is unchanged: `master` is still tried first and +serves the bulk of every fork's files by hash; only the `forks` round is expanded +into one round per discovered SHA. If no cached fork commit is found in range, +`--unsafe` falls back to a plain unscoped read. -For S3-compatible storage (MinIO, Cloudflare R2, AWS S3, etc.): +`--unsafe` trusts the artifacts of *every* commit it tries, so it always prints +the [non-default-scope security notice](#security-warning-non-default-scope). It +is mutually exclusive with `--scope=` (which pins exactly one commit). -1. Create a bucket (e.g., `mathlib-cache`) -2. Configure public read access for downloads (or use signed URLs) -3. Set up authentication for uploads -4. Set the environment variables: +### Heads-up note from `cache get` -```bash -export MATHLIB_CACHE_GET_URL="https://your-bucket.s3.region.amazonaws.com/mathlib-cache" -export MATHLIB_CACHE_PUT_URL="https://your-bucket.s3.region.amazonaws.com/mathlib-cache" -export MATHLIB_CACHE_USE_CLOUDFLARE=1 # Use S3-style auth -export MATHLIB_CACHE_S3_TOKEN="ACCESS_KEY:SECRET_KEY" -``` +When you run `cache get` on a fork-trust repo and HEAD has not been built and +cached at fork-trust level, the tool prints a stderr note pointing you at +`cache query` (and warning that picking a different commit means trusting its +artifacts). Costs one HTTP HEAD per `cache get` invocation; only fires when the +resolved repo's default chain includes `forks` and no `--scope=` / `--cache-from` +override is supplied. -### Example: Simple HTTP Mirror +## Security Warning: Non-Default Scope -For a read-only mirror using nginx or any static file server: +When you read cache artifacts at a non-default scope, the cache tool prints a +security warning to stderr. This happens when: -1. Periodically sync files from the official cache -2. Serve them at a public URL -3. Point users to your mirror: +1. **`--unsafe` is passed** — you are letting the tool walk history and trust the + artifacts of whichever recent fork commit(s) it finds cached. +2. **`--scope=` is passed** — you are reading from a specific commit's + namespace instead of the repo's default trust chain. +3. **`--cache-from` widens the read chain** — you are explicitly telling the tool + to trust containers beyond the repo default. +4. **`--repo` overrides the detected git remote** — you are reading cache for a + different repository than your cwd's git remote. + +Example warning: -```bash -export MATHLIB_CACHE_GET_URL="https://mathlib-mirror.myorg.com" -lake exe cache get +``` +================================================================= +SECURITY: reading cache at a non-default scope +================================================================= +You are reading cache artifacts at a scope outside the default trust +boundary for this repo. The cache cannot verify the contents of these +artifacts; you are choosing to trust whoever uploaded them. + +Repository: leanprover-community/mathlib4 +Reason: --scope=5a3c7e9a2f8c1d6b4e0f9a2c3d4e5f6a7b8c9d0e (explicit per-commit scope) +================================================================= ``` -### URL Structure +This warning is always printed — it cannot be suppressed with `--quiet`. The +warning is purely informational; it does not prompt for confirmation (so it +doesn't interfere with CI). -The cache uses this URL pattern: +## Tests +The cache tool's pure logic (container URL construction, per-repo allowlist, +CLI parsing) is covered by a standalone test exe: + +```bash +lake exe cache-test ``` -{BASE_URL}/f/{repo}/{filename}.ltar # Fork/branch caches -{BASE_URL}/f/{filename}.ltar # Main mathlib cache (Azure) -{BASE_URL}/c/{commit_hash} # Commit manifests -``` -Where: -- `{repo}` is like `leanprover-community/mathlib4` or `username/mathlib4` -- `{filename}` is a hash like `1234567890abcdef` -- `{commit_hash}` is a git commit SHA +The exe builds only `Cache.*` and its direct deps — it does not require +Mathlib or `MathlibTest`. Exits 0 on success, non-zero on failure. + +> A Lake package has a single `testDriver`, which the enclosing `mathlib` +> package already binds to `MathlibTest`. If the cache tool ever moves to +> its own Lake project, the `cache-test` exe can be promoted to that +> project's `testDriver` so `lake test` invokes it directly. ## Dependencies diff --git a/Cache/Requests.lean b/Cache/Requests.lean index cca1dc42314b1c..2b766e6fd7ba47 100644 --- a/Cache/Requests.lean +++ b/Cache/Requests.lean @@ -1,28 +1,23 @@ /- Copyright (c) 2023 Arthur Paulino. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Arthur Paulino +Authors: Arthur Paulino, Marcelo Lynch -/ -import Batteries.Data.String.Matcher import Cache.Hashing -import Cache.Init +import Cache.Infra import Lake.Load.Manifest namespace Cache.Requests open System (FilePath) -/-- The full name of the main Mathlib GitHub repository. -/ -def MATHLIBREPO := "leanprover-community/mathlib4" - /-- -Structure to hold repository information with priority ordering +Resolved repository identity for cache lookups. -/ structure RepoInfo where repo : String - useFirst : Bool - deriving Repr + deriving Repr, BEq /-- Helper function to extract repository name from a git remote URL @@ -147,11 +142,10 @@ def isDetachedAtNightlyTesting (mathlibDepPath : FilePath) : IO Bool := do return false /-- -Attempts to determine the GitHub repository of a version of Mathlib from its Git remote. -If the current commit coincides with a PR ref, it will determine the source fork -of that PR rather than just using the origin remote. +Inner implementation: may throw if git is unavailable or the directory has no +git checkout. Callers should use `getRemoteRepo` instead. -/ -def getRemoteRepo (mathlibDepPath : FilePath) : IO (Option RepoInfo) := do +private def getRemoteRepoImpl (mathlibDepPath : FilePath) : IO (Option RepoInfo) := do -- Since currently we need to push a PR to `leanprover-community/mathlib` build a user cache, -- we check if we are a special branch or a branch with PR. This leaves out non-PRed fork @@ -179,9 +173,8 @@ def getRemoteRepo (mathlibDepPath : FilePath) : IO (Option RepoInfo) := do if shouldUseNightlyTesting then let repo := "leanprover-community/mathlib4-nightly-testing" - let cacheService := if useCloudflareCache then "Cloudflare" else "Azure" - IO.println s!"Using cache ({cacheService}) from nightly-testing remote: {repo}" - return some {repo := repo, useFirst := true} + IO.println s!"Using cache from nightly-testing remote: {repo}" + return some {repo := repo} -- Only search for PR refs if we're not on a regular branch like master, bump/*, or nightly-testing* -- let isSpecialBranch := branchName == "master" || branchName.startsWith "bump/" || @@ -241,63 +234,164 @@ def getRemoteRepo (mathlibDepPath : FilePath) : IO (Option RepoInfo) := do let repo? ← getRepoFromRemote mathlibDepPath remoteName s!"Ensure Git is installed and the '{remoteName}' remote points to its GitHub repository." - let cacheService := if useCloudflareCache then "Cloudflare" else "Azure" match repo? with | some repo => - IO.println s!"Using cache ({cacheService}) from {remoteName}: {repo?}" - return some {repo := repo, useFirst := false} + IO.println s!"Using cache from {remoteName}: {repo?}" + return some {repo := repo} | none => - IO.println s!"Using cache ({cacheService}) from {MATHLIBREPO}." + IO.println s!"Using cache from {MATHLIBREPO}." return none -/-- Public URL for mathlib cache -/ -initialize URL : String ← do - let url? ← IO.getEnv "MATHLIB_CACHE_GET_URL" - let defaultUrl := - if useCloudflareCache then - "https://mathlib4.lean-cache.cloud" - else - "https://lakecache.blob.core.windows.net/mathlib4" - return url?.getD defaultUrl +/-- +Attempts to determine the GitHub repository of a version of Mathlib from its Git remote. +If the current commit coincides with a PR ref, it will determine the source fork +of that PR rather than just using the origin remote. + +Returns `none` if git is unavailable, the path is not inside a git checkout, or +the remote cannot be resolved. This is the expected outcome when `cache get` is +invoked on a dependency that was fetched as an archive rather than a git clone; +callers fall back to `MATHLIBREPO` and the master container. +-/ +def getRemoteRepo (mathlibDepPath : FilePath) : IO (Option RepoInfo) := do + try + return (← getRemoteRepoImpl mathlibDepPath) + catch _ => + return none + +/-- +Resolve the GitHub repo for cache reads from a single `getRemoteRepo` probe. + +Returns `(detectedRepo?, resolvedRepo)`: +* `detectedRepo?` is what the git remote reports (`none` if it can't be + determined); the warning path compares it against an explicit `--repo=` to + tell whether the user is overriding the checkout's repo. +* `resolvedRepo` applies the override precedence `--repo=` > git remote > + `MATHLIBREPO`, and is what the read path uses. + +`getRemoteRepo` shells out to git and prints branch/remote diagnostics; +resolving here lets the read path, the warning, and the HEAD hint share a +single probe keyed on `mathlibDepPath`. +-/ +def resolveRepo (repo? : Option String) (mathlibDepPath : FilePath) : + IO (Option String × String) := do + let detected? := (← getRemoteRepo mathlibDepPath).map (·.repo) + return (detected?, repo?.getD (detected?.getD MATHLIBREPO)) + +/-- +Process-wide override for the container fallback list, set by the `--cache-from` +CLI flag. When `none`, downloads use `defaultContainersForRepo`; when `some cs`, +all repos use `cs` instead. +-/ +initialize cacheFromOverride : IO.Ref (Option (List Container)) ← IO.mkRef none + +/-- +Compute the trust-ordered list of container base URLs to try when downloading +files for a given GitHub repo. + +Precedence (most specific wins): +1. `MATHLIB_CACHE_GET_URL` env var: a single anonymous URL that bypasses the + container logic entirely. +2. `--cache-from` CLI override (via `cacheFromOverride`). +3. `MATHLIB_CACHE_FROM` env var (same comma-separated shape as `--cache-from`): + how CI widens the lookup chain to match its write target without touching + each `cache get` call. The (repo, branch) → chain mapping lives in CI config, + not here. +4. `defaultContainersForRepo repo`: the repo-level fallback when nothing + overrides it. +-/ +def effectiveGetURLs (repo : String) : IO (List (Option Container × String)) := do + if let some url ← IO.getEnv "MATHLIB_CACHE_GET_URL" then + return [(none, url)] + if let some cliOverride ← cacheFromOverride.get then + return cliOverride.map fun c => (some c, c.azureURL) + let envOverride? ← do + match (← IO.getEnv "MATHLIB_CACHE_FROM") with + | none => pure none + | some s => + match parseCacheFromList s with + | some cs => pure (some cs) + | none => + IO.eprintln s!"Warning: ignoring MATHLIB_CACHE_FROM={s} \ + (unrecognized container name). Known containers: \ + {", ".intercalate (Container.all.map Container.name)}." + pure none + let containers := envOverride?.getD (defaultContainersForRepo repo) + return containers.map fun c => (some c, c.azureURL) /-- Authentication method used for cache upload operations. -/ inductive UploadAuth where - | cloudflareS3 (token : String) | azureSas (token : String) | azureBearer (token : String) /-- Retrieves upload credentials from the environment. -/ def getUploadAuth : IO UploadAuth := do - if useCloudflareCache then - let envVar := "MATHLIB_CACHE_S3_TOKEN" - let some token ← IO.getEnv envVar - | throw <| IO.userError s!"environment variable {envVar} must be set to upload caches" - return .cloudflareS3 token - else - if let some token ← IO.getEnv "MATHLIB_CACHE_AZURE_BEARER_TOKEN" then - let token := token.trimAscii.copy - if !token.isEmpty then - return .azureBearer token - if let some token ← IO.getEnv "MATHLIB_CACHE_SAS" then - let token := token.trimAscii.copy - if !token.isEmpty then - return .azureSas token - throw <| IO.userError - "environment variable MATHLIB_CACHE_AZURE_BEARER_TOKEN or MATHLIB_CACHE_SAS must be set to upload caches" + if let some token ← IO.getEnv "MATHLIB_CACHE_AZURE_BEARER_TOKEN" then + let token := token.trimAscii.copy + if !token.isEmpty then + return .azureBearer token + if let some token ← IO.getEnv "MATHLIB_CACHE_SAS" then + let token := token.trimAscii.copy + if !token.isEmpty then + return .azureSas token + throw <| IO.userError + "environment variable MATHLIB_CACHE_AZURE_BEARER_TOKEN or MATHLIB_CACHE_SAS must be set to upload caches" /-- -Given a file name like `"1234.tar.gz"`, makes the URL to that file on the server. +Construct the URL for the cache file `fileName` in repo `repo`, against the +container reachable at `containerURL`. + +The `f/` prefix marks files (commits use `c/`). Whether the rest of the path is +flat (`/f/`) or repo-namespaced (`/f//`) follows the +container (see `Container.flatPath`), not the repo: the same hash under +`repo = MATHLIBREPO` lands flat in `master` and prefixed in `forks`. -The `f/` prefix means that it's a common file for caching. +`container` is `none` for the user-supplied `MATHLIB_CACHE_GET_URL` / +`MATHLIB_CACHE_PUT_URL` URLs, where no container policy applies; the path then +follows the repo directly — flat for `MATHLIBREPO`, prefixed otherwise. +-/ +def mkFileURL (container : Option Container) (repo containerURL fileName : String) + (repoScope : Option String := none) : String := + let flat := match container with + | some c => c.flatPath repo + | none => repo == MATHLIBREPO + let pre := if flat then "" + else match repoScope with + | some s => s!"{repo}/{s}/" + | none => s!"{repo}/" + s!"{containerURL}/f/{pre}{fileName}" + +/-- +Process-wide override for the per-SHA scope, set by the `--scope=` CLI flag. +When set, it wins over `MATHLIB_CACHE_REPO_SCOPE`. -/ -def mkFileURL (repo URL fileName : String) : String := - let pre := if !useCloudflareCache && repo == MATHLIBREPO then "" else s!"{repo}/" - s!"{URL}/f/{pre}{fileName}" +initialize scopeOverride : IO.Ref (Option String) ← IO.mkRef none + +/-- +Resolved repo-scope SHA. Precedence: `--scope=` flag > `MATHLIB_CACHE_REPO_SCOPE` +env var > `none`. Both sources mean "the user has explicitly opted into a +SHA-scoped read"; the non-default-scope warning fires for either. +-/ +def getRepoScope : IO (Option String) := do + if let some s ← scopeOverride.get then + return some s + let s? ← IO.getEnv "MATHLIB_CACHE_REPO_SCOPE" + match s? with + | some s => + let trimmed := s.trimAscii.toString + pure (if trimmed.isEmpty then none else some trimmed) + | none => pure none + +def getGitCommitHash : IO String := + return (← IO.runCmd "git" #["rev-parse", "HEAD"]).trimAsciiEnd.copy section Get -/-- Formats the config file for `curl`, containing the list of files to be downloaded -/ -def mkGetConfigContent (repo : String) (hashMap : IO.ModuleHashMap) : IO String := do +/-- Formats the config file for `curl`, containing the list of files to be downloaded +from a single container's base URL. `scope?` is the per-round SHA scope (see +`mkFileURL`); it is the resolved `getRepoScope` for a normal read and an +individual walked SHA for an `--unsafe` forks round. -/ +def mkGetConfigContent (container : Option Container) (repo containerURL : String) + (hashMap : IO.ModuleHashMap) (scope? : Option String) : IO String := do hashMap.toArray.foldlM (init := "") fun acc ⟨_, hash⟩ => do let fileName := hash.asLTar -- Below we use `String.quote`, which is intended for quoting for use in Lean code @@ -313,13 +407,16 @@ def mkGetConfigContent (repo : String) (hashMap : IO.ModuleHashMap) : IO String -- Note we append a '.part' to the filenames here, -- which `downloadFiles` then removes when the download is successful. - pure <| acc ++ s!"url = {mkFileURL repo URL fileName}\n\ + pure <| acc ++ s!"url = {mkFileURL container repo containerURL fileName scope?}\n\ -o {(IO.CACHEDIR / (fileName ++ ".part")).toString.quote}\n" -/-- Calls `curl` to download a single file from the server to `CACHEDIR` (`.cache`) -/ -def downloadFile (repo : String) (hash : UInt64) : IO Bool := do +/-- Calls `curl` to download a single file from a specific container to `CACHEDIR` +(`.cache`). Returns `true` on success, `false` on any error including 404. +`scope?` is the per-round SHA scope (see `mkGetConfigContent`). -/ +def downloadFile (container : Option Container) (repo containerURL : String) + (hash : UInt64) (scope? : Option String) : IO Bool := do let fileName := hash.asLTar - let url := mkFileURL repo URL fileName + let url := mkFileURL container repo containerURL fileName scope? let path := IO.CACHEDIR / fileName let partFileName := fileName ++ ".part" let partPath := IO.CACHEDIR / partFileName @@ -397,9 +494,36 @@ def dispatchDecompBatch (pending : Array (FilePath × Lean.Name)) (config : Deco let task ← IO.asTask (decompressBatch pending config.force config.isMathlibRoot config.mathlibDepPath) return some task +/-- +Whether an HTTP status returned for a single-file read should be treated as a +cache miss (fall through to the next container in the chain) rather than a +transfer failure worth reporting. + +`404` is always a miss. A `403` is a miss only when `treatForbiddenAsMiss` is +set, which callers do for the `legacy` container: when its public read access is +revoked ahead of retirement it answers reads with `403`, and old clients whose +chain still lists `legacy` should fall through quietly instead of printing a +per-file transfer failure. Any other status is a real failure. +-/ +def isCacheMissStatus (httpCode : Nat) (treatForbiddenAsMiss : Bool) : Bool := + httpCode == 404 || (httpCode == 403 && treatForbiddenAsMiss) + +/-- +Whether an HTTP status is the one Azure returns for a blob that already exists, +which a non-overwrite `put` (`If-None-Match: *`) hits when it declines to +overwrite. Azure reports it as 409 (the `BlobAlreadyExists` error, what it +returns in practice) or 412 (the conditional-header spec's code for an unmet +`If-None-Match`), so we accept both. Whether that's benign is the caller's call: +the upload path skips it, reads don't. +-/ +def isAlreadyPresentStatus (httpCode : Nat) : Bool := + httpCode == 409 || httpCode == 412 + def monitorCurl (args : Array String) (size : Nat) (caption : String) (speedVar : String) (removeOnError := false) - (decompConfig : Option DecompConfig := none) : IO TransferState := do + (decompConfig : Option DecompConfig := none) + (treatForbiddenAsMiss : Bool := false) + (treatExistsAsSkip : Bool := false) : IO TransferState := do let useAnsi := (← IO.getEnv "TERM").isSome let mkStatus (s : TransferState) : String := Id.run do let speedStr := @@ -463,26 +587,35 @@ def monitorCurl (args : Array String) (size : Nat) currentTask ← dispatchDecompBatch pending config pending := #[] success := success + 1 - | .ok 404 => pure () + -- A cache miss (404, or 403 from a retiring `legacy`) just falls through + -- to the next container; a blob already on the server (409/412 from a + -- non-overwrite put) is expected, not a failure; anything else fails. | code? => - failed := failed + 1 - let mkFailureMsg code? fn? msg? : String := Id.run do - let mut msg := "Transfer failed" + let alreadyPresent := match code? with + | .ok c => isAlreadyPresentStatus c + | .error _ => false + let isMiss := match code? with + | .ok c => isCacheMissStatus c treatForbiddenAsMiss + | .error _ => false + unless isMiss || (treatExistsAsSkip && alreadyPresent) do + failed := failed + 1 + let mkFailureMsg code? fn? msg? : String := Id.run do + let mut msg := "Transfer failed" + if let .ok fn := fn? then + msg := s!"{fn}: {msg}" + if let .ok code := code? then + msg := s!"{msg} (error code: {code})" + if let .ok errMsg := msg? then + msg := s!"{msg}: {errMsg}" + return msg + let msg? := result.getObjValAs? String "errormsg" + let fn? := result.getObjValAs? String "filename_effective" + IO.println (mkFailureMsg code? fn? msg?) if let .ok fn := fn? then - msg := s!"{fn}: {msg}" - if let .ok code := code? then - msg := s!"{msg} (error code: {code})" - if let .ok errMsg := msg? then - msg := s!"{msg}: {errMsg}" - return msg - let msg? := result.getObjValAs? String "errormsg" - let fn? := result.getObjValAs? String "filename_effective" - IO.println (mkFailureMsg code? fn? msg?) - if let .ok fn := fn? then - if removeOnError then - -- `curl --remove-on-error` can already do this, but only from 7.83 onwards - if (← System.FilePath.pathExists fn) then - IO.FS.removeFile fn + if removeOnError then + -- `curl --remove-on-error` can already do this, but only from 7.83 onwards + if (← System.FilePath.pathExists fn) then + IO.FS.removeFile fn done := done + 1 let now ← IO.monoMsNow if now - last ≥ 100 then -- max 10/s update rate @@ -498,55 +631,162 @@ def monitorCurl (args : Array String) (size : Nat) IO.eprintln (mkStatus s) return s +/-- Run one container's download pass for the given hash map. Returns the +`TransferState` produced by `monitorCurl` (or a synthesized empty state in +serial mode). Side effect: any files successfully fetched are written to +`CACHEDIR` with their final names. -/ +private def downloadFilesFromContainer + (container : Option Container) (repo containerURL : String) + (hashMap : IO.ModuleHashMap) + (parallel : Bool) (decompConfig : Option DecompConfig) + (scope? : Option String) : + IO (Nat × TransferState) := do + let size := hashMap.size + if parallel then + IO.FS.writeFile IO.CURLCFG (← mkGetConfigContent container repo containerURL hashMap scope?) + let args := #["--request", "GET", "--parallel", + -- commented as this creates a big slowdown on curl 8.13.0: "--fail", + "--silent", + "--retry", "5", -- there seem to be some intermittent failures + "--write-out", "%{json}\n", "--config", IO.CURLCFG.toString] + -- `legacy` answers reads with 403 once its public access is revoked ahead + -- of retirement; treat that as a miss so the chain stays quiet for clients + -- whose chain still lists it. + let treatForbiddenAsMiss := container == some Container.legacy + let s ← monitorCurl args size "Downloaded" "speed_download" (removeOnError := true) + decompConfig (treatForbiddenAsMiss := treatForbiddenAsMiss) + IO.FS.removeFile IO.CURLCFG + return (s.failed, s) + else + let r ← hashMap.foldM (init := []) fun acc _ hash => do + pure <| (← IO.asTask do downloadFile container repo containerURL hash scope?) :: acc + let failed := r.foldl (init := 0) fun f t => if let .ok true := t.get then f else f + 1 + let emptyState : TransferState := ⟨0, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ + return (failed, emptyState) + +/-- Expand the trust-ordered container list into the concrete download rounds to +run, each carrying the SHA scope to read at. A round is +`(container?, url, scope?)`. + +Without `--unsafe` (`unsafeScopes` empty) every round uses the single resolved +`scope?`: one round per container, all at the same scope. When no explicit +scope is given, `headScope?` (the checked-out HEAD, resolved by the caller) +applies to the `forks` round only: fork uploads live under the per-commit +namespace, so this is what lets a plain `cache get` retrieve what CI built for +exactly the commit the reader has checked out. The other containers' layouts +are not SHA-scoped, so `headScope?` must not leak into their rounds. + +With `--unsafe` (`unsafeScopes` non-empty) the `forks` container — the only +SHA-scoped container, whose markers the walk probed — is expanded into one round +per discovered SHA, most recent first. Every other container reads unscoped +(`master` is flat and serves the bulk of files by hash; `legacy` has no walked +markers), so the base `scope?` is intentionally dropped here. -/ +def expandDownloadRounds (containerURLs : List (Option Container × String)) + (scope? : Option String) (unsafeScopes : List String) + (headScope? : Option String := none) : + List (Option Container × String × Option String) := + if unsafeScopes.isEmpty then + containerURLs.map fun (c, url) => + if c == some Container.forks then (c, url, scope? <|> headScope?) + else (c, url, scope?) + else + containerURLs.flatMap fun (c, url) => + if c == some Container.forks then + unsafeScopes.map fun sha => (c, url, some sha) + else + [(c, url, none)] + /-- Call `curl` to download files from the server to `CACHEDIR` (`.cache`). Return the number of files which failed to download. -If `decompress` is true, decompresses files as they're downloaded (pipelined). -/ +If `decompress` is true, decompresses files as they're downloaded (pipelined). + +For each repo, the tool tries the trust-ordered container list returned by +`effectiveGetURLs`. After each container round, files that were successfully +fetched are filtered out so the next container only retries genuine misses. + +`unsafeScopes` is the list of SHA scopes discovered by `cache get --unsafe` +(empty for a normal read); see `expandDownloadRounds`. -/ def downloadFiles (repo : String) (hashMap : IO.ModuleHashMap) (forceDownload : Bool) (parallel : Bool) (warnOnMissing : Bool) (decompress : Bool := false) (forceUnpack : Bool := false) - (isMathlibRoot : Bool := false) (mathlibDepPath : FilePath := ".") : IO Nat := do + (isMathlibRoot : Bool := false) (mathlibDepPath : FilePath := ".") + (unsafeScopes : List String := []) : IO Nat := do let hashMap ← if forceDownload then pure hashMap else hashMap.filterExists false if hashMap.isEmpty then IO.println "No files to download"; return 0 - let size := hashMap.size IO.FS.createDirAll IO.CACHEDIR - IO.println s!"Attempting to download {size} file(s) from {repo} cache" - -- Set up decompression config if enabled + let containerURLs ← effectiveGetURLs repo + if containerURLs.isEmpty then + IO.eprintln "No container URLs configured for download" + return hashMap.size + + -- Set up decompression config if enabled. We keep one config across all + -- container rounds so pipelined decompression continues across them. let decompConfig ← if decompress then - -- Build hash → module name mapping let hashToMod : Std.HashMap UInt64 Lean.Name := hashMap.fold (init := ∅) fun acc mod hash => acc.insert hash mod pure (some { hashToMod, force := forceUnpack, isMathlibRoot, mathlibDepPath : DecompConfig }) else pure none - let (downloadFailed, finalState) ← if parallel then - IO.FS.writeFile IO.CURLCFG (← mkGetConfigContent repo hashMap) - let args := #["--request", "GET", "--parallel", - -- commented as this creates a big slowdown on curl 8.13.0: "--fail", - "--silent", - "--retry", "5", -- there seem to be some intermittent failures - "--write-out", "%{json}\n", "--config", IO.CURLCFG.toString] - let s ← monitorCurl args size "Downloaded" "speed_download" (removeOnError := true) decompConfig - IO.FS.removeFile IO.CURLCFG - if warnOnMissing && s.success + s.failed < s.done then - IO.eprintln "Warning: some files were not found in the cache." - IO.eprintln "This usually means that your local checkout of mathlib4 has diverged from upstream." - IO.eprintln "" - IO.eprintln " * If you push your commits to a PR to the mathlib4 repository" - IO.eprintln " (use a draft PR if it is not ready for review)," - IO.eprintln " then CI will build the oleans and they will be available later." - IO.eprintln " * If you have already opened a PR, this may mean" - IO.eprintln " the CI build has failed part-way through building." - pure (s.failed, s) - else - let r ← hashMap.foldM (init := []) fun acc _ hash => do - pure <| (← IO.asTask do downloadFile repo hash) :: acc - let failed := r.foldl (init := 0) fun f t => if let .ok true := t.get then f else f + 1 - -- Non-parallel mode doesn't support pipelined decompression - let emptyState : TransferState := ⟨0, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ - pure (failed, emptyState) + -- Walk container URLs in trust order. After each round, drop files that + -- succeeded so the next round only retries genuine misses. With `--unsafe` + -- the `forks` container is expanded into one round per discovered SHA scope. + let scope? ← getRepoScope + -- With no explicit scope, the forks round defaults to HEAD: `cache get` on a + -- checked-out commit retrieves what CI built for exactly that commit, fork + -- included. This adds no trust over an unscoped forks read — the namespace + -- can only hold artifacts built from the commit the reader already has. + let headScope? ← if scope?.isNone && unsafeScopes.isEmpty then + try pure (some (← getGitCommitHash)) catch _ => pure none + else pure none + let rounds := expandDownloadRounds containerURLs scope? unsafeScopes headScope? + let unsafeMode := !unsafeScopes.isEmpty + let mut remaining := hashMap + let mut finalState : TransferState := ⟨0, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ + let mut downloadFailed := 0 + -- For the `--unsafe` summary: how many files each scoped (forks) round supplied, + -- attributed by the drop in `remaining` across that round. + let mut scopeServed : Array (String × Nat) := #[] + for (container?, url, roundScope?) in rounds do + if remaining.isEmpty then break + let scopeNote := match roundScope? with | some s => s!" (scope {s})" | none => "" + IO.println s!"Attempting to download {remaining.size} file(s) from {repo} cache at {url}{scopeNote}" + let before := remaining.size + let (failed, s) ← downloadFilesFromContainer container? repo url remaining parallel decompConfig roundScope? + -- Carry forward the decompression-related state across container rounds. + -- Counter fields (success/failed/done) reflect only the last round; we + -- aggregate `downloadFailed` separately below. + finalState := s + downloadFailed := failed + remaining ← remaining.filterExists false + if unsafeMode then + if let some sha := roundScope? then + scopeServed := scopeServed.push (sha, before - remaining.size) + + -- `--unsafe`: report which fork commits actually contributed files, so the + -- user knows whose artifacts they ended up trusting. + if unsafeMode then + if scopeServed.isEmpty then + IO.eprintln "--unsafe: no fork scopes were needed; \ + all files were served by higher-trust containers." + else + IO.eprintln s!"--unsafe: cache served from {scopeServed.size} fork commit scope(s):" + for (sha, n) in scopeServed do + IO.eprintln s!" {sha} → {n} file(s)" + if remaining.size > 0 then + IO.eprintln s!" {remaining.size} file(s) still missing after all scopes." + + if warnOnMissing && downloadFailed > 0 && parallel then + IO.eprintln "Warning: some files were not found in the cache." + IO.eprintln "This usually means that your local checkout of mathlib4 has diverged from upstream." + IO.eprintln "" + IO.eprintln " * If you push your commits to a PR to the mathlib4 repository" + IO.eprintln " (use a draft PR if it is not ready for review)," + IO.eprintln " then CI will build the oleans and they will be available later." + IO.eprintln " * If you have already opened a PR, this may mean" + IO.eprintln " the CI build has failed part-way through building." -- Finalize decompression: wait for current task and process any remaining files if let some config := decompConfig then @@ -652,10 +892,17 @@ def checkForManifestMismatch : IO.CacheM Unit := do precedence, then run `lake update`." IO.Process.exit 1 -/-- Downloads missing files, and unpacks files. -/ +/-- Downloads missing files, and unpacks files. + +`repo` is the already-resolved GitHub repo (see `resolveRepo`); its +trust-ordered container list from `defaultContainersForRepo` is the single +source of truth for what gets tried — there's no separate outer-loop +iteration. Master's cache reaches fork builds via `master` being in the fork +chain (the highest-trust source, holding the bulk of any fork's deps). -/ def getFiles - (repo? : Option String) (hashMap : IO.ModuleHashMap) + (repo : String) (hashMap : IO.ModuleHashMap) (forceDownload forceUnpack parallel decompress : Bool) + (unsafeScopes : List String := []) : IO.CacheM Unit := do let isMathlibRoot ← IO.isMathlibRoot unless isMathlibRoot do @@ -680,38 +927,13 @@ def getFiles else pure none else pure none - if let some repo := repo? then - let failed ← downloadFiles repo hashMap forceDownload parallel (warnOnMissing := true) - (decompress := decompress) (forceUnpack := forceUnpack) - isMathlibRoot mathlibDepPath - if failed > 0 then IO.Process.exit 1 - else - let repoInfo? ← getRemoteRepo (← read).mathlibDepPath - - -- Build list of repositories to download from in order - let repos : List String := - if let some repoInfo := repoInfo? then - if repoInfo.repo == MATHLIBREPO then - [MATHLIBREPO] - else if repoInfo.useFirst then - [repoInfo.repo, MATHLIBREPO] - else - [MATHLIBREPO, repoInfo.repo] - else - [MATHLIBREPO] - - let mut failed : Nat := 0 - for h : i in [0:repos.length] do - failed ← downloadFiles repos[i] hashMap forceDownload parallel - (warnOnMissing := i = repos.length - 1) - (decompress := decompress) (forceUnpack := forceUnpack) - isMathlibRoot mathlibDepPath - if failed > 10 then - IO.println s!"Too many downloads failed; stopping the downloading" - IO.Process.exit 1 - if failed > 0 then - IO.println s!"Downloading {failed} files failed" - IO.Process.exit 1 + let failed ← downloadFiles repo hashMap forceDownload parallel + (warnOnMissing := true) + (decompress := decompress) (forceUnpack := forceUnpack) + isMathlibRoot mathlibDepPath (unsafeScopes := unsafeScopes) + if failed > 0 then + IO.println s!"Downloading {failed} files failed" + IO.Process.exit 1 -- Wait for decompression of already-cached files to complete if let some (task, size) := bgDecomp then @@ -740,15 +962,31 @@ end Get section Put -/-- Cloudflare cache S3 URL -/ -initialize UPLOAD_URL : String ← do - let url? ← IO.getEnv "MATHLIB_CACHE_PUT_URL" - let defaultUrl := - if useCloudflareCache then - "https://a09a7664adc082e00f294ac190827820.r2.cloudflarestorage.com/mathlib4" - else - "https://lakecache.blob.core.windows.net/mathlib4" - return url?.getD defaultUrl +/-- +Resolve the upload base URL. + +Precedence: +1. `MATHLIB_CACHE_PUT_URL` env var, if set. +2. The Azure URL for the explicitly chosen `container`. +3. With neither set, fall back to `Container.legacy` (the bare `mathlib4` + container) and warn. RBAC still scopes each identity to its own container, + so the fallback cannot reach a trust-level container it isn't entitled to; + the warning steers workflows toward passing `--container=NAME`. +-/ +def effectiveUploadURL (container : Option Container) : + IO (Option Container × String) := do + if let some url ← IO.getEnv "MATHLIB_CACHE_PUT_URL" then + -- A user-supplied URL carries no container policy, so signal `none` and let + -- `mkFileURL` choose the path from the repo alone. + return (none, url) + match container with + | none => + IO.eprintln <| + "Warning: cache upload without --container=NAME; defaulting to the\n" ++ + " `legacy` (bare `mathlib4`) container. Pass --container=NAME\n" ++ + " explicitly to choose a trust-level container." + return (some Container.legacy, Container.legacy.azureURL) + | some c => return (some c, c.azureURL) def azureBearerApiVersionHeader : String := "x-ms-version: 2026-02-06" @@ -759,31 +997,37 @@ def getAzureDateHeader : IO String := do throw <| IO.userError s!"failed to produce x-ms-date header (exit code {out.exitCode})" return s!"x-ms-date: {out.stdout.trimAscii.copy}" -/-- Formats the config file for `curl`, containing the list of files to be uploaded -/ -def mkPutConfigContent (repo : String) (files : Array FilePath) (auth : UploadAuth) : IO String := do +/-- Formats the config file for `curl`, containing the list of files to be uploaded. +The destination base URL is the explicit `uploadURL` argument. `container` is +threaded through to `mkFileURL` so the per-container URL-shape policy applies; +it is `none` only when `MATHLIB_CACHE_PUT_URL` is overriding the endpoint. -/ +def mkPutConfigContent (container : Option Container) (repo uploadURL : String) + (files : Array FilePath) (auth : UploadAuth) : IO String := do + let scope? ← getRepoScope let token := match auth with | .azureSas token => s!"?{token}" | _ => "" let l ← files.toList.mapM fun file : FilePath => do - pure s!"-T {file.toString}\nurl = {mkFileURL repo UPLOAD_URL file.fileName.get!}{token}" + pure s!"-T {file.toString}\nurl = {mkFileURL container repo uploadURL file.fileName.get! scope?}{token}" return "\n".intercalate l -/-- Calls `curl` to send a set of files to the server -/ +/-- Calls `curl` to send a set of files to the server. The destination container +is selected by `container`; pass `none` to require `MATHLIB_CACHE_PUT_URL` to +be set instead (otherwise this errors). -/ def putFilesAbsolute - (repo : String) (files : Array FilePath) (tempConfigFilePath : FilePath) + (repo : String) (container : Option Container) + (files : Array FilePath) (tempConfigFilePath : FilePath) (overwrite : Bool) (auth : UploadAuth) : IO Unit := do -- TODO: reimplement using HEAD requests? - let _ := overwrite let size := files.size if size > 0 then - IO.FS.writeFile tempConfigFilePath (← mkPutConfigContent repo files auth) - IO.println s!"Attempting to upload {size} file(s) to {repo} cache" + let (urlContainer?, uploadURL) ← effectiveUploadURL container + IO.FS.writeFile tempConfigFilePath + (← mkPutConfigContent urlContainer? repo uploadURL files auth) + let target := container.map Container.name |>.getD "(env override)" + IO.println s!"Attempting to upload {size} file(s) to {repo} cache (container: {target})" let azureDateHeader ← getAzureDateHeader let args := match auth with - | .cloudflareS3 token => - -- TODO: reimplement using HEAD requests? - let _ := overwrite - #["--aws-sigv4", "aws:amz:auto:s3", "--user", token] | .azureSas _ => if overwrite then #["-H", "x-ms-blob-type: BlockBlob"] @@ -801,17 +1045,24 @@ def putFilesAbsolute "-X", "PUT", "--parallel", "--retry", "5", -- there seem to be some intermittent failures "--write-out", "%{json}\n", "--config", tempConfigFilePath.toString] - discard <| monitorCurl args size "Uploaded" "speed_upload" (removeOnError := false) (decompConfig := none) + let s ← monitorCurl args size "Uploaded" "speed_upload" (removeOnError := false) + (decompConfig := none) (treatExistsAsSkip := !overwrite) IO.FS.removeFile tempConfigFilePath + -- Surface genuine upload failures. Already-present blobs (409/412 on a + -- non-overwrite put) are excused in `monitorCurl`, so this won't trip on a + -- re-upload of files the server already has. + if s.failed > 0 then + IO.eprintln s!"Uploading {s.failed} file(s) failed" + IO.Process.exit 1 else IO.println "No files to upload" -/-- Calls `curl` to send a set of cached files to the server -/ +/-- Calls `curl` to send a set of cached files to the server. -/ def putFiles - (repo : String) (fileNames : Array String) + (repo : String) (container : Option Container) (fileNames : Array String) (overwrite : Bool) (auth : UploadAuth) : IO Unit := do -- TODO: reimplement using HEAD requests? let files : Array FilePath := fileNames.map (fun (f : String) => (IO.CACHEDIR / f)) - putFilesAbsolute repo files IO.CURLCFG overwrite auth + putFilesAbsolute repo container files IO.CURLCFG overwrite auth end Put section Stage @@ -861,31 +1112,28 @@ section Commit def isGitStatusClean : IO Bool := return (← IO.runCmd "git" #["status", "--porcelain"]).isEmpty -def getGitCommitHash : IO String := - return (← IO.runCmd "git" #["rev-parse", "HEAD"]).trimAsciiEnd.copy - /-- Sends a commit file to the server, containing the hashes of the respective committed files. The file name is the current Git hash and the `c/` prefix means that it's a commit file. +The destination container follows the same rules as `putFiles`. -/ -def commit (hashMap : IO.ModuleHashMap) (overwrite : Bool) (auth : UploadAuth) : IO Unit := do +def commit (container : Option Container) (hashMap : IO.ModuleHashMap) (overwrite : Bool) + (auth : UploadAuth) : IO Unit := do let hash ← getGitCommitHash let path := IO.CACHEDIR / hash IO.FS.createDirAll IO.CACHEDIR IO.FS.writeFile path <| ("\n".intercalate <| hashMap.hashes.toList.map toString) ++ "\n" let azureDateHeader ← getAzureDateHeader + -- Commit files are never namespaced by repo (they always live at `/c/`), + -- so we only need the URL from `effectiveUploadURL`, not the URL-shape container. + let (_, uploadURL) ← effectiveUploadURL container match auth with - | .cloudflareS3 token => - -- TODO: reimplement using HEAD requests? - let _ := overwrite - discard <| IO.runCurl #["-T", path.toString, - "--aws-sigv4", "aws:amz:auto:s3", "--user", token, s!"{UPLOAD_URL}/c/{hash}"] | .azureSas token => let params := if overwrite then #["-X", "PUT", "-H", "x-ms-blob-type: BlockBlob"] else #["-X", "PUT", "-H", "x-ms-blob-type: BlockBlob", "-H", "If-None-Match: *"] - discard <| IO.runCurl <| params ++ #["-T", path.toString, s!"{URL}/c/{hash}?{token}"] + discard <| IO.runCurl <| params ++ #["-T", path.toString, s!"{uploadURL}/c/{hash}?{token}"] | .azureBearer token => let params := if overwrite then #["-X", "PUT", "-H", "x-ms-blob-type: BlockBlob", "-H", azureBearerApiVersionHeader, @@ -893,7 +1141,7 @@ def commit (hashMap : IO.ModuleHashMap) (overwrite : Bool) (auth : UploadAuth) : "--oauth2-bearer", token] else #["-X", "PUT", "-H", "x-ms-blob-type: BlockBlob", "-H", "If-None-Match: *", "-H", azureBearerApiVersionHeader, "-H", azureDateHeader, "--oauth2-bearer", token] - discard <| IO.runCurl <| params ++ #["-T", path.toString, s!"{URL}/c/{hash}"] + discard <| IO.runCurl <| params ++ #["-T", path.toString, s!"{uploadURL}/c/{hash}"] IO.FS.removeFile path end Commit @@ -922,10 +1170,9 @@ Retrieves metadata about hosted files: their names and the timestamps of last mo Example: `["f/39476538726384726.tar.gz", "Sat, 24 Dec 2022 17:33:01 GMT"]` -/ def getFilesInfo (q : QueryType) : IO <| List (String × String) := do - if useCloudflareCache then - throw <| .userError "FIXME: getFilesInfo is not adapted to Cloudflare cache yet" IO.println s!"Downloading info list of {q.desc}" - let ret ← IO.runCurl #["-X", "GET", s!"{URL}?comp=list&restype=container{q.prefix}"] + let ret ← IO.runCurl + #["-X", "GET", s!"{Container.master.azureURL}?comp=list&restype=container{q.prefix}"] match ret.splitOn "" with | [] => formatError | [_] => return [] diff --git a/Cache/SECURITY.md b/Cache/SECURITY.md new file mode 100644 index 00000000000000..0c93d31772981e --- /dev/null +++ b/Cache/SECURITY.md @@ -0,0 +1,152 @@ +# Cache trust model & security notes + +## Background + +The mathlib build cache holds CI-built artifacts shared across every +contributor's local checkout. A PR can run arbitrary code during its CI build +(Lean executes user code at elaboration time), so it can write any bytes into +the artifacts that are then packed and uploaded. The infrastructure cannot +validate artifact content; verifying integrity would mean re-running the build, +defeating the point of caching. + +The cache thus cannot prevent a malicious build from producing a poisoned +artifact; it prevents delivery of that artifact to a higher-trust consumer. +Artifacts produced at trust level T are only readable by consumers at level T +or below. + +## Trust hierarchy and containers + +The model spans four storage containers, each written by a distinct class of +CI job and assigned a trust level: + +| Container | Who may write | Trust | +|-----------------------|--------------------------------------------------------|--------| +| `master` | mathlib4 `master`/`staging` | high | +| `forks` | mathlib4 PR builds, non-master branches, `bors try` | medium | +| `nightly-testing` | nightly-testing's trusted branches | medium | +| `pr-toolchain-tests` | nightly-testing's experimental toolchain branches | low | + +Each writer identity is granted write access to exactly one container, enforced +by the storage backend. An upload aimed at any other container is rejected, +regardless of what the cache binary requests. + +On the read side, each repo has a default lookup chain — the ordered list of +containers a consumer reads from: + +| Consumer | Default lookup chain | +|-------------------------|----------------------| +| mathlib4 | `master` | +| nightly-testing | `nightly-testing` | +| forks (PRs) | `master`, `forks` | + +The nightly default excludes the low-trust container, so a poisoned upload from +an experimental toolchain branch cannot reach a trusted nightly consumer. +Branches that legitimately need to read their own prior low-trust uploads opt +into a wider chain explicitly. + +## Four enforcement layers + +The first two enforce the trust boundary; the last two provide correctness +guarantees and additional containment. + +### 1. Token-scoped uploads (server-side) + +Before uploading, the workflow obtains a short-lived token for the writer +identity tied to its container. The identity provider issues the token only +when the workflow's identity — stamped by GitHub from the repo, event type, and +ref — matches a pre-registered credential. The token's scope is fixed when it +is issued and cannot be widened afterward. + +This is the boundary's anchor: a compromised cache binary, a tampered workflow, +or a malicious PR that captures and replays the token still cannot upload +outside the one container the token grants. + +### 2. Isolation of the cache binary + +The cache binary is built from a trusted branch, never from the PR's checkout, +so the PR's toolchain never reaches the compiler that produces it. The binary +runs in two separate jobs — one that fetches and packs artifacts, and one that +uploads them — and each builds its own copy from the trusted source. The PR's +own build writes only its artifacts, which the trusted binary later packs. + +The two jobs also run on different runner pools, and the upload token is minted +only in the upload job, so it never reaches the build host; a compromised build +host cannot extract it. + +### 3. Read-only source tree during the build + +The PR build, where untrusted code runs, executes inside a sandbox that makes +the source tree read-only. This keeps the inputs to the cache key honest while +they are being hashed: without it, a malicious build could rewrite a hash input +(such as the toolchain) between hashing and packing, aligning its keys with a +target branch's and bypassing the partitioning below. + +### 4. Hash partitioning + +Cache keys derive from the source content, its imports, and the build's +toolchain and configuration. Branches with different toolchains therefore live +in disjoint key spaces, so even within one container their artifacts cannot +collide unless an attacker aligns all of those inputs — which Layer 3 prevents. + +This layer is not sufficient alone: it relies on Layer 2 for an honest binary +computing the keys, Layer 3 to keep the inputs honest, and Layer 1 to bound the +damage if partitioning ever fails. + +## How CI routes each job + +A routing policy decides, for each CI job, which container it writes to and +which lookup chain it reads from. The policy is loaded from the trusted branch, +not from the PR, so a PR cannot route itself to a higher-trust container. + +This routing applies only in CI. User machines fall back to the strict per-repo +default and must opt into a wider lookup chain explicitly. + +## Per-commit namespace for fork uploads + +Within the fork container, uploads are further namespaced by the PR's head +commit. This closes a replay window: artifacts from a closed, hidden, or +force-pushed-away PR live under a different commit, so a later honest PR from +the same fork cannot read them. Uploads to the other containers are not +commit-scoped — each receives uploads from a single trust level, so the +container boundary alone isolates them. + +By default a `cache get` reads the fork namespace at the checked-out HEAD: it +can only serve artifacts built from the commit the reader already has, so it +adds no trust over the fork container itself and prints no notice. (CI pins +the same namespace explicitly via `MATHLIB_CACHE_REPO_SCOPE`, set to the build +SHA.) A reader opts into a *different* commit's namespace with +`cache get --scope=SHA`, or lets `cache get --unsafe` discover the most recent +cached fork commits automatically (`--unsafe-window=N` reads the `N` most +recent, default `1`). Either way the reader is choosing to trust whoever +produced those fork artifacts — the per-commit namespace bounds *replay*, not +the trust decision itself — so both forms print the non-default-scope security +notice before reading. Neither runs in CI; CI routing (above) is loaded from +the trusted branch. + +## Explicitly out of scope + +The trust model does not attempt to defend against: + +- **Compromised upstream Lean releases** — a malicious toolchain on the trusted + branch builds the cache binary itself. +- **Compromised storage tenant** — admin-level compromise defeats the access + grants. +- **Sandbox escape via kernel vulnerability** — invalidates Layer 3. +- **Maintainer trust on the trusted branches** — write access to a branch the + cache binary is built from can land a bad tool, workflow, or toolchain. +- **Compromised CI platform credentials** — forged identity tokens break the + upload boundary. +- **Validation of artifact byte-identity** — the cache key identifies inputs, + not bytes; containment is trust-bounded delivery, not fetch-time detection. + +## Code pointers + +| Concern | File(s) | +|------------------------------------------------|------------------------------------------------------------------| +| Container model, URL shape, per-repo defaults | [`Cache/Infra.lean`](Infra.lean) | +| Read-fallback resolution, upload URL, dispatch | [`Cache/Requests.lean`](Requests.lean) (`effectiveGetURLs`, `effectiveUploadURL`) | +| Trust property tests | [`Cache/Test.lean`](Test.lean) | +| User-facing CLI surface, env vars | [`Cache/Main.lean`](Main.lean), [`Cache/README.md`](README.md) | +| OIDC mint + per-job dispatch | [`.github/workflows/build_template.yml`](../.github/workflows/build_template.yml) (`upload_cache` job) | +| (repo, branch) → trust class policy table | [`.github/actions/cache-trust-dispatch/action.yml`](../.github/actions/cache-trust-dispatch/action.yml) | +| Caller `cache_application_id` ternaries | [`.github/workflows/build.yml`](../.github/workflows/build.yml), [`bors.yml`](../.github/workflows/bors.yml), [`build_fork.yml`](../.github/workflows/build_fork.yml), [`ci_dev.yml`](../.github/workflows/ci_dev.yml) | diff --git a/Cache/Test.lean b/Cache/Test.lean new file mode 100644 index 00000000000000..15bf2c1b701839 --- /dev/null +++ b/Cache/Test.lean @@ -0,0 +1,1007 @@ +/- +Copyright (c) 2026 Marcelo Lynch. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Marcelo Lynch +-/ + +import Cache.Cli +import Cache.Requests +import Cache.Marker +import Cache.Query +import Cache.Warning +import Cache.Lean + +/-! +# Unit tests for the cache CLI + +These tests cover the pure logic of the cache system, including: +- Container model (trust levels, URL shapes, Azure integration) +- Trust-ordered fallback chains per repo +- URL construction (`mkFileURL`) with support for per-SHA scoping +- CLI flag parsing (`--cache-from`, `--scope`, `--unsafe`, `--repo`, etc.) +- `--unsafe` download-round expansion (`expandDownloadRounds`) and the + non-default-scope security warning it triggers +- Utility functions (URL extraction, filename hashing, etc.) + +Anything that touches `curl` or the network is left to CI, which exercises the +`cache get`/`put` paths end-to-end on real containers. + +## Invariants these tests defend + +1. Trust boundary per container: each container has a dedicated writer (OIDC + + Azure RBAC) and reads follow a per-repo trust-ordered list, so a PR cannot + upload to a higher-trust container. +2. Per-SHA namespace for fork uploads: fork uploads land at `/f/{repo}/{sha}/{hash}`, + so one commit's artifacts never serve another commit on the same fork. +3. Flat layout for single-writer containers: `master` reads and writes flat at + `/f/{hash}`, the path older tools also use. +4. Prefixed layout for multi-writer containers: `forks`, `nightly-testing`, and + `pr-toolchain-tests` namespace by repo so uploads from different sources don't + collide. +5. `legacy` stays readable with its mixed layout (flat for the canonical repo, + prefixed for forks) so older clients keep working. + +## Running the tests + +Run with `lake exe cache-test`. Exits 0 on success, non-zero on failure. + +The tests stand alone (no dependency on `MathlibTest`). A Lake package has a +single `testDriver`, and the enclosing `mathlib` package binds that to +`MathlibTest` (see `lakefile.lean`); if the cache tool moves to its own Lake +project, the `cache-test` `lean_exe` here can become that project's `testDriver`. +-/ + +namespace Cache.Test + +open Cache.Requests + +/-- Counter for failed assertions. -/ +initialize failures : IO.Ref Nat ← IO.mkRef 0 + +/-- A single named assertion. On failure, prints details and bumps the counter. -/ +def assert (name : String) (cond : Bool) : IO Unit := do + if cond then + IO.println s!" ok: {name}" + else + IO.eprintln s!" FAIL: {name}" + failures.modify (· + 1) + +/-- Assert two strings are equal; show both on failure. -/ +def assertEq (name expected actual : String) : IO Unit := do + if expected == actual then + IO.println s!" ok: {name}" + else + IO.eprintln s!" FAIL: {name}\n expected: {expected}\n actual: {actual}" + failures.modify (· + 1) + +/-- Run `action` with both stdout and stderr redirected to /dev/null. Restores +both on completion, including on exception. Apply this to every production code +call in tests so diagnostic prints never mix with test output, regardless of +whether the production code currently produces any. -/ +private def withSuppressedOutput (action : IO α) : IO α := do + let savedOut ← IO.getStdout + let savedErr ← IO.getStderr + let sink ← IO.FS.Handle.mk "/dev/null" IO.FS.Mode.append + let sinkStream := IO.FS.Stream.ofHandle sink + -- `IO.setStdout`/`IO.setStderr` return the previous stream; we already saved it, + -- so discard the return value here. + discard <| IO.setStdout sinkStream + discard <| IO.setStderr sinkStream + try + let r ← action + discard <| IO.setStdout savedOut + discard <| IO.setStderr savedErr + return r + catch e => + discard <| IO.setStdout savedOut + discard <| IO.setStderr savedErr + throw e + +section ContainerModel + +/-- The short name is the string used on the CLI (`--container=NAME`) and to +derive the Azure container name. These names are part of the public CLI +contract, so they are pinned here: a rename must be a deliberate edit to this +test, not an accident. -/ +def test_Container_name : IO Unit := do + IO.println "Container.name:" + assertEq "master" "master" Container.master.name + assertEq "forks" "forks" Container.forks.name + assertEq "nightly-testing" "nightly-testing" Container.nightlyTesting.name + assertEq "pr-toolchain-tests" "pr-toolchain-tests" Container.prToolchainTests.name + assertEq "legacy" "legacy" Container.legacy.name + +/-- Parser is the inverse of `Container.name` on valid inputs, and rejects everything else. -/ +def test_Container_parse : IO Unit := do + IO.println "Container.parse?:" + -- Every canonical name round-trips back to its enum case. + assert "master parses" (Container.parse? "master" == some .master) + assert "forks parses" (Container.parse? "forks" == some .forks) + assert "nightly-testing parses" (Container.parse? "nightly-testing" == some .nightlyTesting) + assert "pr-toolchain-tests parses" + (Container.parse? "pr-toolchain-tests" == some .prToolchainTests) + assert "legacy parses" (Container.parse? "legacy" == some .legacy) + -- Matching is case-insensitive, so `--container=Master` canonicalizes too. + assert "case-insensitive" (Container.parse? "Master" == some .master) + -- An unknown name returns `none` so `--container=bogus` errors out rather than + -- defaulting to some container the user didn't ask for. + assert "unknown rejected" (Container.parse? "bogus" == none) + assert "empty rejected" (Container.parse? "" == none) + +/-- The Azure URL each container resolves to: `mathlib4-{name}` for the +trust-level containers, bare `mathlib4` for `legacy`. These URLs go into every +request, and changing one means re-coordinating the Azure side with every +consumer, so they are pinned here. -/ +def test_Container_azureURL : IO Unit := do + IO.println "Container.azureURL:" + assertEq "master URL" + "https://lakecache.blob.core.windows.net/mathlib4-master" + Container.master.azureURL + assertEq "forks URL" + "https://lakecache.blob.core.windows.net/mathlib4-forks" + Container.forks.azureURL + assertEq "nightly-testing URL" + "https://lakecache.blob.core.windows.net/mathlib4-nightly-testing" + Container.nightlyTesting.azureURL + assertEq "pr-toolchain-tests URL" + "https://lakecache.blob.core.windows.net/mathlib4-pr-toolchain-tests" + Container.prToolchainTests.azureURL + -- `legacy` is the bare `mathlib4` container, with no `-legacy` suffix. + assertEq "legacy URL" + "https://lakecache.blob.core.windows.net/mathlib4" + Container.legacy.azureURL + +/-- Whether a container lays files out flat (`/f/`) or namespaces them by +repo (`/f//`). The layout is fixed per container so that all of a +container's writers stay on non-colliding paths: +- `master` is flat for every repo (one writer, no collisions possible). +- `forks`, `nightly-testing`, and `pr-toolchain-tests` are prefixed for every + repo, including the canonical one, so fork-trust uploads from the canonical + repo coexist with fork uploads. +- `legacy` is flat for the canonical repo and prefixed otherwise. +-/ +def test_Container_flatPath : IO Unit := do + IO.println "Container.flatPath:" + assert "master is flat for the canonical repo" + (Container.master.flatPath MATHLIBREPO == true) + assert "master is flat for a fork repo too" + (Container.master.flatPath "alice/mathlib4" == true) + assert "legacy is flat for the canonical repo" + (Container.legacy.flatPath MATHLIBREPO == true) + assert "legacy is prefixed for a fork repo" + (Container.legacy.flatPath "alice/mathlib4" == false) + assert "forks is prefixed for the canonical repo" + (Container.forks.flatPath MATHLIBREPO == false) + assert "forks is prefixed for a fork repo" + (Container.forks.flatPath "alice/mathlib4" == false) + assert "nightly-testing is prefixed for the nightly-testing repo" + (Container.nightlyTesting.flatPath NIGHTLY_TESTING_REPO == false) + assert "nightly-testing is prefixed for the canonical repo" + (Container.nightlyTesting.flatPath MATHLIBREPO == false) + assert "pr-toolchain-tests is prefixed for the nightly-testing repo" + (Container.prToolchainTests.flatPath NIGHTLY_TESTING_REPO == false) + +end ContainerModel + +section PerRepoAllowlist + +/-- Trust-ordered read chain per GitHub repo: the tool tries containers in this +order and stops at the first hit, so both membership and ordering are part of +the trust boundary. Key points the tests pin: +- The nightly-testing chain excludes `pr-toolchain-tests`, so trusted-nightly + consumers never fall back to low-trust toolchain-PR uploads (those branches + opt into the wider chain via `MATHLIB_CACHE_FROM` in CI). +- The fork chain leads with `master` (shared upstream deps), then `forks` + (PR-specific files); `master` is absent from the nightly chain because that + repo's toolchain gives it a different root hash. +- Every chain ends with `legacy`, so older clients' artifacts stay reachable. +-/ +def test_defaultContainersForRepo : IO Unit := do + IO.println "defaultContainersForRepo:" + assert "canonical repo → [master, legacy]" + (defaultContainersForRepo MATHLIBREPO == [.master, .legacy]) + assert "nightly-testing repo → [nightly-testing, legacy], no pr-toolchain-tests" + (defaultContainersForRepo NIGHTLY_TESTING_REPO == [.nightlyTesting, .legacy]) + assert "fork repo → [master, forks, legacy]" + (defaultContainersForRepo "alice/mathlib4" == [.master, .forks, .legacy]) + assert "unknown repo falls back to the fork chain" + (defaultContainersForRepo "some/other-repo" == [.master, .forks, .legacy]) + -- Every chain ends with `legacy`; dropping it would quietly shrink hit rates. + assert "fork chain ends with legacy" + ((defaultContainersForRepo "alice/mathlib4").getLast? == some .legacy) + assert "canonical chain ends with legacy" + ((defaultContainersForRepo MATHLIBREPO).getLast? == some .legacy) + assert "nightly-testing chain ends with legacy" + ((defaultContainersForRepo NIGHTLY_TESTING_REPO).getLast? == some .legacy) + +end PerRepoAllowlist + +section MkFileURL + +/-- URL construction for a cache file. The path shape follows the container +(`Container.flatPath`), not the repo, so the same repo lands flat in `master` +and prefixed in `forks`. A `none` container is the user-supplied-URL case +(`MATHLIB_CACHE_GET_URL` / `_PUT_URL`), where the shape follows the repo alone. + +A per-SHA scope (`MATHLIB_CACHE_REPO_SCOPE`) inserts `{sha}` between repo and +hash on prefixed paths only — `/f/{repo}/{sha}/{hash}` — keeping each commit's +fork uploads in their own namespace. Flat paths ignore the scope. +-/ +def test_mkFileURL : IO Unit := do + IO.println "mkFileURL:" + assertEq "master is flat for the canonical repo" + "https://lakecache.blob.core.windows.net/mathlib4-master/f/abc.ltar" + (mkFileURL (some .master) MATHLIBREPO Container.master.azureURL "abc.ltar") + assertEq "master is flat for a fork repo too" + "https://lakecache.blob.core.windows.net/mathlib4-master/f/abc.ltar" + (mkFileURL (some .master) "alice/mathlib4" Container.master.azureURL "abc.ltar") + -- `forks` prefixes by repo even for the canonical repo, so its fork-trust + -- uploads don't collide with fork uploads in the same container. + assertEq "forks prefixes by repo for the canonical repo" + "https://lakecache.blob.core.windows.net/mathlib4-forks/f/leanprover-community/mathlib4/abc.ltar" + (mkFileURL (some .forks) MATHLIBREPO Container.forks.azureURL "abc.ltar") + assertEq "forks prefixes by repo for a fork repo" + "https://lakecache.blob.core.windows.net/mathlib4-forks/f/alice/mathlib4/abc.ltar" + (mkFileURL (some .forks) "alice/mathlib4" Container.forks.azureURL "abc.ltar") + assertEq "nightly-testing prefixes by repo" + "https://lakecache.blob.core.windows.net/mathlib4-nightly-testing/f/leanprover-community/mathlib4-nightly-testing/abc.ltar" + (mkFileURL (some .nightlyTesting) NIGHTLY_TESTING_REPO + Container.nightlyTesting.azureURL "abc.ltar") + assertEq "pr-toolchain-tests prefixes by repo" + "https://lakecache.blob.core.windows.net/mathlib4-pr-toolchain-tests/f/leanprover-community/mathlib4-nightly-testing/abc.ltar" + (mkFileURL (some .prToolchainTests) NIGHTLY_TESTING_REPO + Container.prToolchainTests.azureURL "abc.ltar") + assertEq "legacy is flat for the canonical repo" + "https://lakecache.blob.core.windows.net/mathlib4/f/abc.ltar" + (mkFileURL (some .legacy) MATHLIBREPO Container.legacy.azureURL "abc.ltar") + assertEq "legacy prefixes by repo for a fork repo" + "https://lakecache.blob.core.windows.net/mathlib4/f/alice/mathlib4/abc.ltar" + (mkFileURL (some .legacy) "alice/mathlib4" Container.legacy.azureURL "abc.ltar") + -- No container (user-supplied URL): the shape follows the repo — flat for the + -- canonical repo, prefixed otherwise. + assertEq "user URL is flat for the canonical repo" + "https://custom.example/cache/f/abc.ltar" + (mkFileURL none MATHLIBREPO "https://custom.example/cache" "abc.ltar") + assertEq "user URL prefixes by repo for a fork repo" + "https://custom.example/cache/f/alice/mathlib4/abc.ltar" + (mkFileURL none "alice/mathlib4" "https://custom.example/cache" "abc.ltar") + -- A scope adds a `{sha}` path segment on prefixed paths. + assertEq "scope adds a SHA segment on a fork path" + "https://lakecache.blob.core.windows.net/mathlib4-forks/f/alice/mathlib4/abc123def/H.ltar" + (mkFileURL (some .forks) "alice/mathlib4" Container.forks.azureURL "H.ltar" (some "abc123def")) + assertEq "scope adds a SHA segment on the canonical repo's forks path" + "https://lakecache.blob.core.windows.net/mathlib4-forks/f/leanprover-community/mathlib4/abc123def/H.ltar" + (mkFileURL (some .forks) MATHLIBREPO Container.forks.azureURL "H.ltar" (some "abc123def")) + -- A scope is ignored on flat paths. + assertEq "scope is ignored on a flat master path" + "https://lakecache.blob.core.windows.net/mathlib4-master/f/abc.ltar" + (mkFileURL (some .master) MATHLIBREPO Container.master.azureURL "abc.ltar" (some "abc123def")) + assertEq "scope is ignored on a flat legacy path" + "https://lakecache.blob.core.windows.net/mathlib4/f/abc.ltar" + (mkFileURL (some .legacy) MATHLIBREPO Container.legacy.azureURL "abc.ltar" (some "abc123def")) + +end MkFileURL + +section ParseCacheFromList + +/-- Parser for `--cache-from=a,b,c`. List order is the trust order tried at +download time, so it is preserved exactly. The parser is strict: one bad name +or empty input fails the whole list rather than degrading to a default, so a +typo surfaces instead of silently changing where the cache is read. -/ +def test_parseCacheFromList : IO Unit := do + IO.println "parseCacheFromList:" + assert "single container" + (parseCacheFromList "master" == some [.master]) + assert "two containers" + (parseCacheFromList "master,forks" == some [.master, .forks]) + assert "all five containers" + (parseCacheFromList "master,forks,nightly-testing,pr-toolchain-tests,legacy" == + some [.master, .forks, .nightlyTesting, .prToolchainTests, .legacy]) + assert "master,legacy" + (parseCacheFromList "master,legacy" == some [.master, .legacy]) + -- Order is preserved, not normalized: `forks,master` reverses the priority. + assert "preserves the given order" + (parseCacheFromList "forks,master" == some [.forks, .master]) + -- Whitespace around commas is tolerated, so the flag survives shell expansion. + assert "whitespace around names is tolerated" + (parseCacheFromList " master , forks " == some [.master, .forks]) + assert "one unknown name rejects the whole list" + (parseCacheFromList "master,bogus" == none) + assert "empty input is rejected" + (parseCacheFromList "" == none) + +end ParseCacheFromList + +section ExtractRepoFromUrl + +/-- Parses `owner/name` from a git remote URL. The result selects the per-repo +read chain, so misreading a fork as the canonical repo would read the wrong +chain; these cases cover every URL shape git emits via `git remote get-url` or a +direct remote (e.g. `gh pr checkout`). Unparseable input returns `none`, and the +caller falls back to `MATHLIBREPO`. -/ +def test_extractRepoFromUrl : IO Unit := do + IO.println "extractRepoFromUrl:" + assert "ssh URL with .git suffix" + (extractRepoFromUrl "git@github.com:alice/mathlib4.git" == some "alice/mathlib4") + assert "ssh URL without .git suffix" + (extractRepoFromUrl "git@github.com:alice/mathlib4" == some "alice/mathlib4") + assert "https URL with .git suffix" + (extractRepoFromUrl "https://github.com/alice/mathlib4.git" == some "alice/mathlib4") + assert "https URL without .git suffix" + (extractRepoFromUrl "https://github.com/alice/mathlib4" == some "alice/mathlib4") + -- A hyphenated owner is part of the repo identity and must survive intact. + assert "hyphenated owner is preserved" + (extractRepoFromUrl "https://github.com/leanprover-community/mathlib4.git" == some "leanprover-community/mathlib4") + assert "empty input returns none" + (extractRepoFromUrl "" == none) + assert "a token with no slash or colon returns none" + (extractRepoFromUrl "norepo" == none) + +end ExtractRepoFromUrl + +section ExtractPRNumber + +/-- Extracts a PR number from a git ref. The contract is "second-to-last +segment must be `pr`, last must be a Nat". -/ +def test_extractPRNumber : IO Unit := do + IO.println "extractPRNumber:" + -- The shape git produces for fetched PR refs. + assert "standard PR ref format" + (extractPRNumber "refs/remotes/upstream/pr/1234" == some 1234) + -- Branch refs are not PR refs; must not match. + assert "master branch returns none" + (extractPRNumber "refs/heads/master" == none) + -- Minimal `pr/N` is also accepted — the parser only inspects the trailing two segments. + assert "simple pr number" + (extractPRNumber "pr/42" == some 42) + -- The tail must be a valid Nat; non-numeric tails are rejected (no partial parsing). + assert "non-numeric tail returns none" + (extractPRNumber "refs/remotes/upstream/pr/foo" == none) + -- `0` is a valid Nat; pin down that it isn't special-cased. + assert "zero PR number" + (extractPRNumber "refs/remotes/upstream/pr/0" == some 0) + -- A numeric tail without the `pr/` parent must not be mistaken for a PR ref. + assert "missing pr segment returns none" + (extractPRNumber "refs/remotes/upstream/42" == none) + +end ExtractPRNumber + +section HashFromFileName + +/-- Recovers the UInt64 cache hash from a cached file's path, the inverse of +`UInt64.asLTar`. The subtle case is `.ltar.part` — the suffix curl writes during +a download — where `.part` must be stripped before `.ltar`. A regression here +corrupts cache lookups, so both suffixes and a non-hex stem are covered. -/ +def test_hashFromFileName : IO Unit := do + IO.println "hashFromFileName:" + assert "plain .ltar file" + (hashFromFileName "abc123def.ltar" == String.parseHexToUInt64? "000000abc123def") + assert "in-flight .ltar.part file strips both suffixes" + (hashFromFileName "abc123def.ltar.part" == String.parseHexToUInt64? "000000abc123def") + assert "full 16-digit hex stem" + (hashFromFileName "deadbeef00112233.ltar" == String.parseHexToUInt64? "deadbeef00112233") + -- A non-hex stem returns none rather than a garbage hash. + assert "non-hex stem returns none" + (hashFromFileName "nothexa.ltar" == none) + -- Directory components are ignored; only the basename's stem is parsed. + assert "leading path is ignored" + (hashFromFileName "/path/to/abc123def.ltar" == String.parseHexToUInt64? "000000abc123def") + +end HashFromFileName + +section IsRemoteURL + +/-- Discriminator: is this string a remote URL (vs a local filesystem path)? +Used to decide whether to short-circuit `git remote get-url` lookups. -/ +def test_isRemoteURL : IO Unit := do + IO.println "isRemoteURL:" + -- The three protocols accepted by the cache tool. + assert "https URL is remote" + (isRemoteURL "https://github.com/alice/mathlib4.git" == true) + assert "http URL is remote" + (isRemoteURL "http://github.com/alice/mathlib4" == true) + assert "ssh URL is remote" + (isRemoteURL "git@github.com:alice/mathlib4.git" == true) + -- Absolute and relative local paths must be classified as not-remote so they + -- get routed through `git remote get-url`. + assert "local path is not remote" + (isRemoteURL "/local/path/to/repo" == false) + assert "relative path is not remote" + (isRemoteURL "./local/repo" == false) + -- Defensive — empty input shouldn't accidentally match the predicate. + assert "empty string is not remote" + (isRemoteURL "" == false) + +end IsRemoteURL + +section UInt64Formatting + +/-- Filename derived from a cache hash: exactly 16 lowercase hex digits plus +`.ltar`. The fixed width makes the hash ↔ filename mapping unique and +invertible — without it, `0x1` and `0x01` would share a stem and collide. -/ +def test_UInt64_asLTar : IO Unit := do + IO.println "UInt64.asLTar:" + assertEq "small value is left-padded to 16 digits" + "0000000000000001.ltar" + (1 : UInt64).asLTar + assertEq "mid-width value is left-padded" + "0000000000abc123.ltar" + (0xabc123 : UInt64).asLTar + assertEq "full-width value is not truncated" + "deadbeef00112233.ltar" + (0xdeadbeef00112233 : UInt64).asLTar + assertEq "zero is padded, not emptied" + "0000000000000000.ltar" + (0 : UInt64).asLTar + -- Max value is 16 lowercase `f`s; the parser elsewhere is case-sensitive. + assertEq "max value is lowercase hex" + "ffffffffffffffff.ltar" + (0xffffffffffffffff : UInt64).asLTar + +end UInt64Formatting + +section RoundTrip + +/-- `asLTar` then `hashFromFileName` must return the original hash — the property +that lets the filename serve as the cache key. A padding or truncation bug would +read a file back as a different hash, causing misses or collisions. -/ +def test_hash_roundtrip : IO Unit := do + IO.println "hash roundtrip (asLTar then hashFromFileName):" + let h1 : UInt64 := 0xdeadbeef00112233 + assert "full-width hash round-trips" + (hashFromFileName h1.asLTar == some h1) + -- A short hash exercises both pad-on-write and trim-on-read. + let h2 : UInt64 := 0xabc123 + assert "padded hash round-trips" + (hashFromFileName h2.asLTar == some h2) + +end RoundTrip + +section Marker + +/-- URL shape for the per-SHA marker blob written by `put-staged`. Probed by +`cache query` with a HEAD request. The marker lives at `/m/{repo}/{sha}` in +the chosen container; its presence is a 200 HEAD response that signals "all +artifacts for this commit were uploaded". This shape enables cheap per-commit +discovery via HEAD (no blob-listing). -/ +def test_markerURL : IO Unit := do + IO.println "markerURL:" + assertEq "forks marker URL" + "https://lakecache.blob.core.windows.net/mathlib4-forks/m/alice/mathlib4/abc123" + (markerURL .forks "alice/mathlib4" "abc123") + -- The marker lives under `/m/`, its own namespace, and is keyed by repo. + assertEq "marker is under /m/, keyed by repo" + "https://lakecache.blob.core.windows.net/mathlib4-forks/m/leanprover-community/mathlib4/deadbeef" + (markerURL .forks MATHLIBREPO "deadbeef") + assertEq "marker URL respects the container base" + "https://lakecache.blob.core.windows.net/mathlib4/m/someorg/mathlib4/sha9999" + (markerURL .legacy "someorg/mathlib4" "sha9999") + +end Marker + +section ScopeResolution + +/-- `getRepoScope` answers "is the user reading from a SHA-scoped namespace?". +It reads the `--scope=` flag (the `scopeOverride` ref) first, then the +`MATHLIB_CACHE_REPO_SCOPE` env var, so an explicit flag is never overridden by +an inherited env var. The flag value is returned as given. The env-var branch +needs process state, so it is exercised by the CI integration tests rather than +here. -/ +def test_getRepoScope : IO Unit := do + IO.println "getRepoScope:" + -- Guard the IORef so a leak doesn't pollute subsequent tests. + let saved ← scopeOverride.get + try + scopeOverride.set none + assert "no scope set returns none" ((← withSuppressedOutput getRepoScope) == none) + + scopeOverride.set (some "abc123") + assert "the flag value is returned" ((← withSuppressedOutput getRepoScope) == some "abc123") + + -- The flag value is returned as-is, without trimming or normalization. + scopeOverride.set (some "deadbeef") + assert "the flag value is returned verbatim" + ((← withSuppressedOutput getRepoScope) == some "deadbeef") + + scopeOverride.set none + assert "clearing the flag returns none" ((← withSuppressedOutput getRepoScope) == none) + finally + scopeOverride.set saved + +end ScopeResolution + +section NonDefaultScope + +/-- `shouldWarnNonDefaultScope` decides whether `cache get` prints the +non-default-scope security warning. It warns when any of three inputs takes the +reader off the repo's default trust boundary: + +1. a scope is set (`--scope=` or `MATHLIB_CACHE_REPO_SCOPE`) and differs from + the checked-out HEAD; +2. `--cache-from=LIST` differs from the repo's default chain (passing the + default explicitly is not widening); +3. `--repo=` is given and differs from the detected git remote. + +The behavior the tests pin most carefully: a plain `cache get` with no flags +never warns, even on a fork checkout whose remote isn't the canonical repo. +`detectedRepo?` is passed in (resolved once by `resolveRepo`), so the cases are +deterministic without needing a real checkout. -/ +def test_shouldWarnNonDefaultScope : IO Unit := do + IO.println "shouldWarnNonDefaultScope:" + -- Sandbox the IORef for the duration of this test. + let saved ← scopeOverride.get + try + scopeOverride.set none + + assert "plain get with no flags does not warn" + (!(← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO))) + + scopeOverride.set (some "abc123") + assert "a set scope warns" + (← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO)) + scopeOverride.set none + + -- A scope equal to HEAD is trust-equivalent to no scope (CI's normal mode). + -- Skipped when HEAD can't be resolved (not in a git checkout). + let head? ← try some <$> withSuppressedOutput getGitCommitHash catch _ => pure none + if let some head := head? then + scopeOverride.set (some head) + assert "a scope equal to HEAD does not warn" + (!(← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO))) + scopeOverride.set none + + -- --cache-from equal to the repo's default chain is not widening. + let mathlibDefault := defaultContainersForRepo MATHLIBREPO + assert "--cache-from equal to the default does not warn" + (!(← withSuppressedOutput + (shouldWarnNonDefaultScope none none (some mathlibDefault) MATHLIBREPO))) + + assert "--cache-from widening the chain warns" + (← withSuppressedOutput + (shouldWarnNonDefaultScope none none (some [.master, .forks, .legacy]) MATHLIBREPO)) + + -- A fork checkout (remote ≠ resolved repo) stays silent without an explicit --repo. + assert "a fork checkout without --repo does not warn" + (!(← withSuppressedOutput + (shouldWarnNonDefaultScope none (some "alice/mathlib4") none "alice/mathlib4"))) + + assert "--repo differing from the remote warns" + (← withSuppressedOutput + (shouldWarnNonDefaultScope (some "bob/mathlib4") (some "alice/mathlib4") none "bob/mathlib4")) + + assert "--repo matching the remote does not warn" + (!(← withSuppressedOutput + (shouldWarnNonDefaultScope (some "alice/mathlib4") (some "alice/mathlib4") none + "alice/mathlib4"))) + + -- With no detectable remote there is nothing to compare --repo against. + assert "--repo with no detectable remote does not warn" + (!(← withSuppressedOutput + (shouldWarnNonDefaultScope (some "bob/mathlib4") none none "bob/mathlib4"))) + + -- `--unsafe` (any window) always warns; it walks several untrusted scopes. + assert "--unsafe warns regardless of other inputs" + (← withSuppressedOutput + (shouldWarnNonDefaultScope none none none MATHLIBREPO (unsafeWindow? := some 5))) + assert "no --unsafe (none window) does not warn on its own" + (!(← withSuppressedOutput + (shouldWarnNonDefaultScope none none none MATHLIBREPO (unsafeWindow? := none)))) + finally + scopeOverride.set saved + +/-- `getNonDefaultScopeReason` produces the `Reason:` line in the warning, naming +the specific input that triggered it so the user can match it to their command +line. When several inputs apply at once it reports the most specific first — +scope, then `--cache-from`, then `--repo` — and that order is pinned here. -/ +def test_getNonDefaultScopeReason : IO Unit := do + IO.println "getNonDefaultScopeReason:" + let saved ← scopeOverride.get + try + scopeOverride.set none + + -- A placeholder rather than a crash if nothing matches. + let reason ← withSuppressedOutput (getNonDefaultScopeReason none none none MATHLIBREPO) + assert "no trigger yields a placeholder reason" (reason == "unknown reason") + + scopeOverride.set (some "abc123") + let reason ← withSuppressedOutput (getNonDefaultScopeReason none none none MATHLIBREPO) + assert "scope reason names the flag and SHA" + (reason == "--scope=abc123 (explicit per-commit scope)") + + -- Scope outranks cache-from when both apply. + let reason ← withSuppressedOutput (getNonDefaultScopeReason none none (some [.forks]) MATHLIBREPO) + assert "scope is reported ahead of cache-from" + (reason == "--scope=abc123 (explicit per-commit scope)") + scopeOverride.set none + + -- A HEAD scope is exempt from condition 1, so a simultaneous cache-from + -- trigger is reported instead of the scope. + let head? ← try some <$> withSuppressedOutput getGitCommitHash catch _ => pure none + if let some head := head? then + scopeOverride.set (some head) + let reason ← + withSuppressedOutput (getNonDefaultScopeReason none none (some [.forks, .legacy]) MATHLIBREPO) + assert "a HEAD scope yields the cache-from reason" + (reason == "--cache-from=forks, legacy (explicit container override)") + scopeOverride.set none + + let reason ← + withSuppressedOutput (getNonDefaultScopeReason none none (some [.forks, .legacy]) MATHLIBREPO) + assert "cache-from reason names the container list" + (reason == "--cache-from=forks, legacy (explicit container override)") + + let reason ← withSuppressedOutput + (getNonDefaultScopeReason (some "bob/mathlib4") (some "alice/mathlib4") none "bob/mathlib4") + assert "repo reason names the override and the detected remote" + (reason == "--repo=bob/mathlib4 (overrides detected git remote: alice/mathlib4)") + + -- --cache-from equal to the default is not a trigger, so no reason applies. + let reason ← + withSuppressedOutput (getNonDefaultScopeReason none none (some [.master, .legacy]) MATHLIBREPO) + assert "cache-from equal to the default yields the placeholder" + (reason == "unknown reason") + + -- `--unsafe` outranks every other trigger and names its window. + scopeOverride.set (some "abc123") + let reason ← withSuppressedOutput + (getNonDefaultScopeReason (some "bob/mathlib4") (some "alice/mathlib4") (some [.forks]) + "bob/mathlib4" (unsafeWindow? := some 7)) + assert "unsafe reason names the window and outranks scope/cache-from/repo" + (reason == "--unsafe (automatic walk over up to 7 fork commit(s); trusting whoever built them)") + scopeOverride.set none + finally + scopeOverride.set saved + +/-- `findMostRecentSHAWithCache` returns the first candidate SHA whose per-SHA +marker exists in the `forks` container, used by `cache query` to find the most +recent cached build on the branch. The non-empty cases hit the network (a marker +HEAD probe per SHA) and aren't unit-tested; here we pin that an empty list +returns `none` with no probe. -/ +def test_findMostRecentSHAWithCache : IO Unit := do + IO.println "findMostRecentSHAWithCache:" + let result ← withSuppressedOutput (findMostRecentSHAWithCache [] MATHLIBREPO) + assert "empty SHA list returns none without probing" (result == none) + +/-- `findRecentSHAsWithCache` collects up to `limit` marked SHAs. The non-empty +cases hit the network (a marker HEAD probe per SHA); here we pin that an empty +candidate list returns `[]` for any limit, with no probe. -/ +def test_findRecentSHAsWithCache : IO Unit := do + IO.println "findRecentSHAsWithCache:" + let result ← withSuppressedOutput (findRecentSHAsWithCache [] MATHLIBREPO 5) + assert "empty SHA list returns [] without probing" (result == []) + let result ← withSuppressedOutput (findRecentSHAsWithCache [] MATHLIBREPO 0) + assert "limit 0 returns [] without probing" (result == []) + +end NonDefaultScope + +section GitFallback + +/-- `getRemoteRepo` and `resolveRepo` must never throw, regardless of git's +availability or the state of the target path. This matters for `cache get` +invoked inside a Lake dependency update, where the Mathlib dependency may be a +plain archive without a `.git` directory. + +Two distinct failure modes are tested: + +* **Nonexistent path** — `IO.Process.output` throws before git even starts + (the OS rejects the invalid cwd). The `try...catch` in `getRemoteRepo` must + catch the exception and return `none`. + +* **Non-git directory** — git runs successfully but the path is not a repo, so + every git command exits non-zero. The existing exit-code checks already handle + this path; the test pins that `none` is returned here too. + +In both cases `resolveRepo` must fall back to `MATHLIBREPO`, giving the +master-only container chain (no `forks`) — exactly what a dependency build +should read from. -/ +def test_getRemoteRepo_gitFallback : IO Unit := do + IO.println "getRemoteRepo git fallback:" + -- Case 1: nonexistent cwd causes IO.Process.output to throw. + -- The try...catch in getRemoteRepo must intercept it and return none. + let fakePath := "/tmp/surely-nonexistent-mathlib-cache-test-xyz-9999999" + let r1 ← withSuppressedOutput (getRemoteRepo fakePath) + assert "getRemoteRepo returns none when git throws (nonexistent cwd)" (r1 == none) + + -- Case 2: existing directory that is not a git repo (git returns exit 128). + -- This exercises the exit-code fallback path that predates the try...catch. + let r2 ← withSuppressedOutput (getRemoteRepo "/tmp") + assert "getRemoteRepo returns none in a non-git directory" (r2 == none) + + -- resolveRepo propagates the fallback correctly: + -- detected? = none, resolved = MATHLIBREPO → master-only chain. + let (detected?, resolved) ← withSuppressedOutput (resolveRepo none fakePath) + assert "resolveRepo detected? is none on git failure" (detected? == none) + assert "resolveRepo falls back to MATHLIBREPO on git failure" (resolved == MATHLIBREPO) + assert "fallback chain includes master" + ((defaultContainersForRepo resolved).contains .master) + assert "fallback chain excludes forks (no fork container for dependency builds)" + (!(defaultContainersForRepo resolved).contains .forks) + +/-- `headIsAncestorOfMaster` gates the uncached-fork-HEAD note: when HEAD is +already part of master's history, `master` (first in the fork lookup chain) +serves every file by hash, so the note would be a false positive and is +suppressed. + +Like `getRemoteRepo`, this helper must never throw — it runs on the read path, +including inside dependency builds where the checkout may not be a git repo (or +may lack a local `master`). Both failure modes degrade to `false` (= "not an +ancestor", so the caller keeps its default behavior): + +* **Nonexistent path** — `IO.Process.output` throws before git starts; the + `try...catch` must intercept it. +* **Non-git directory** — git runs but exits non-zero; the `exitCode == 0` + check returns `false`. + +The positive topology cases (HEAD on master ⇒ `true`; diverged branch ⇒ `false`) +exercise real git history and are covered by the CI integration tests, matching +how the other git-walking helpers are tested. -/ +def test_headIsAncestorOfMaster_gitFallback : IO Unit := do + IO.println "headIsAncestorOfMaster git fallback:" + let fakePath := "/tmp/surely-nonexistent-mathlib-cache-test-xyz-9999999" + let r1 ← withSuppressedOutput (headIsAncestorOfMaster fakePath) + assert "headIsAncestorOfMaster returns false when git throws (nonexistent cwd)" + (r1 == false) + let r2 ← withSuppressedOutput (headIsAncestorOfMaster "/tmp") + assert "headIsAncestorOfMaster returns false in a non-git directory" (r2 == false) + +end GitFallback + +section CliOptions + +open Cache.Cli + +/-- `isKnownOpt` is the gatekeeper that decides whether a `--`-prefixed token +in the command line is a recognized option or a typo. Unknown options error +out with a help message rather than being silently ignored — important so a +typo like `--scoop=abc` doesn't silently disable the scope flag. + +The recognition rule: +- A named option matches if `--{name}=` is a prefix of the token. +- A flag matches if the token is exactly `--{name}` (no `=`). + +These tests pin the contract so a future refactor can't accidentally accept +unknown options or reject known ones. -/ +def test_isKnownOpt : IO Unit := do + IO.println "isKnownOpt:" + -- Every named option is recognized when used with `=value` form. + assert "--repo=foo is known" (isKnownOpt "--repo=foo") + assert "--cache-from=master is known" (isKnownOpt "--cache-from=master") + assert "--scope=HEAD is known" (isKnownOpt "--scope=HEAD") + assert "--container=master is known" (isKnownOpt "--container=master") + assert "--staging-dir=/tmp is known" (isKnownOpt "--staging-dir=/tmp") + assert "--unsafe-window=5 is known" (isKnownOpt "--unsafe-window=5") + + -- Empty value passes recognition (parseNamedOpt returns the empty string + -- for these — callers decide whether to treat that as an error). + assert "--scope= (empty value) is known" (isKnownOpt "--scope=") + + -- Flags use the bare `--name` form, no `=`. + assert "--help (no =) is known" (isKnownOpt "--help") + assert "--unsafe (no =) is known" (isKnownOpt "--unsafe") + + -- `--unsafe` is a flag, not a named option: the `=value` form is a user error. + assert "--unsafe=5 is NOT known (flags don't take values)" + (!isKnownOpt "--unsafe=5") + + -- A typo on a known option name should fail recognition, not be silently + -- accepted. This is the regression-guard: if `--scoop=` were accepted, the + -- user's `--scope=` would be silently dropped and reads would fall back to + -- the default chain with no warning. + assert "--scoop=foo (typo on scope) is NOT known" (!isKnownOpt "--scoop=foo") + assert "--bogus=foo (unknown name) is NOT known" (!isKnownOpt "--bogus=foo") + + -- A named option without `=` must NOT be accepted as a flag — `--scope` + -- (no value) is a user error, distinct from the `--help` flag form. + assert "--scope (no =) is NOT known (named opts require value)" + (!isKnownOpt "--scope") + + -- Symmetric: a flag with `=` must NOT be accepted as a named opt. + assert "--help=foo is NOT known (flags don't take values)" + (!isKnownOpt "--help=foo") + + -- A bare positional doesn't even look like an option. The cache binary + -- splits args by `startsWith "--"` before consulting `isKnownOpt`, so this + -- case should never reach us, but we pin it anyway for safety. + assert "bare positional 'scope' is NOT known" (!isKnownOpt "scope") + +/-- `parseNamedOpt` extracts the value of a `--name=value` option from a +list of args. The rules tests pin: + +- Missing option → `none`. +- Single occurrence → the value after `=`. +- Empty value (`--scope=`) → `some ""` (caller decides what to do). +- Multiple occurrences → the *last* one wins (`findRev?`). This mirrors + conventional shell semantics where `--scope=a --scope=b` resolves to `b`. +- Non-matching args are ignored, even if they look similar (e.g., + `--scope-other=` is a different option name). +-/ +def test_parseNamedOpt : IO Unit := do + IO.println "parseNamedOpt:" + -- Empty arg list. + let v ← parseNamedOpt "scope" [] + assert "empty args → none" (v == none) + + -- Args without the target option. + let v ← parseNamedOpt "scope" ["--repo=foo", "get"] + assert "no matching option → none" (v == none) + + -- Single occurrence. + let v ← parseNamedOpt "scope" ["--scope=abc123"] + assert "single occurrence → some value" (v == some "abc123") + + -- `--scope=` is recognized with the empty string as its value, distinct from + -- "not passed" (none). + let v ← parseNamedOpt "scope" ["--scope="] + assert "empty value → some \"\"" (v == some "") + + -- Multiple occurrences: last wins, matching shell precedence. + let v ← parseNamedOpt "scope" ["--scope=first", "--scope=second"] + assert "duplicate option → last value wins" (v == some "second") + + -- Surrounding positionals and other options don't interfere. + let v ← parseNamedOpt "scope" ["get", "--repo=foo", "--scope=mid", "Mathlib/Init.lean"] + assert "found among other args" (v == some "mid") + + -- A longer lookalike name must not match. + let v ← parseNamedOpt "scope" ["--scope-other=foo"] + assert "--scope-other does not match --scope" (v == none) + +/-- `parseFlagOpt` checks whether a bare `--name` flag is present in args. +Used for `--help` today. The contract is strict equality — `--help` matches, +`--help=true` and `--help-me` do not. -/ +def test_parseFlagOpt : IO Unit := do + IO.println "parseFlagOpt:" + -- Empty args. + assert "empty args → false" (!parseFlagOpt "help" []) + + -- Bare `--help` present. + assert "--help present → true" (parseFlagOpt "help" ["--help"]) + + -- `--help=` with a value is NOT a bare flag. (`isKnownOpt` would also + -- reject it; this is the parser-level guarantee.) + assert "--help=true is NOT a bare flag" (!parseFlagOpt "help" ["--help=true"]) + + -- Flag absent among other args. + assert "no flag among args → false" + (!parseFlagOpt "help" ["get", "--repo=foo"]) + + -- Lookalike: `--help-me` isn't the `--help` flag. + assert "lookalike prefix doesn't match" (!parseFlagOpt "help" ["--help-me"]) + +end CliOptions + +section CacheMissStatus + +/-- `isCacheMissStatus` decides whether a read's HTTP status is a benign miss +(fall through to the next container) or a real transfer failure. `404` is always +a miss; `403` is a miss only for a container flagged `treatForbiddenAsMiss` +(currently `legacy`, whose reads start returning `403` once public access is +revoked ahead of retirement). This guards old clients — whose chain still lists +`legacy` — against per-file failures when the container is brought down. -/ +def test_isCacheMissStatus : IO Unit := do + IO.println "isCacheMissStatus:" + -- 404 is a miss regardless of the flag. + assert "404 is a miss (flag off)" (isCacheMissStatus 404 false) + assert "404 is a miss (flag on)" (isCacheMissStatus 404 true) + -- 403 is a miss only when the flag is set (i.e. for `legacy`). + assert "403 is a failure when flag off" (!isCacheMissStatus 403 false) + assert "403 is a miss when flag on" (isCacheMissStatus 403 true) + -- Success and server errors are never misses; they must surface. + assert "200 is not a miss" (!isCacheMissStatus 200 true) + assert "500 is not a miss" (!isCacheMissStatus 500 true) + assert "403-as-miss is scoped to 403" (!isCacheMissStatus 401 true) + +end CacheMissStatus + +section AlreadyPresentStatus + +/-- A non-overwrite `put` (`If-None-Match: *`) gets a 409 or 412 back for a blob +that already exists; both mean "present", not a failure. -/ +def test_isAlreadyPresentStatus : IO Unit := do + IO.println "isAlreadyPresentStatus:" + -- 409/412 are the codes Azure returns for a blob that already exists. + assert "409 is already-present" (isAlreadyPresentStatus 409) + assert "412 is already-present" (isAlreadyPresentStatus 412) + -- Successes, misses, and server errors are not. + assert "201 is not already-present" (!isAlreadyPresentStatus 201) + assert "404 is not already-present" (!isAlreadyPresentStatus 404) + assert "500 is not already-present" (!isAlreadyPresentStatus 500) + +end AlreadyPresentStatus + +section UnsafeRounds + +/-- `expandDownloadRounds` turns the trust-ordered container list into the +concrete download rounds to run, each tagged with the SHA scope to read at. + +Without `--unsafe` (empty `unsafeScopes`) every round carries the single resolved +base scope; with no base scope, `headScope?` applies to the `forks` round only, +so a plain `cache get` reads the fork namespace of the checked-out commit while +the other containers' non-SHA-scoped layouts stay untouched. With `--unsafe` the +`forks` container — the only SHA-scoped container — fans out into one round per +discovered SHA (most recent first), while every other container reads unscoped +and the base scope is dropped. -/ +def test_expandDownloadRounds : IO Unit := do + IO.println "expandDownloadRounds:" + let chain : List (Option Container × String) := + [(some .master, "U_m"), (some .forks, "U_f"), (some .legacy, "U_l")] + + -- No unsafe scopes: one round per container, each carrying the base scope. + assert "no unsafe scopes, no base scope → scope none on every round" + (expandDownloadRounds chain none [] == + [(some .master, "U_m", none), (some .forks, "U_f", none), (some .legacy, "U_l", none)]) + assert "no unsafe scopes, base scope → base scope on every round" + (expandDownloadRounds chain (some "S") [] == + [(some .master, "U_m", some "S"), (some .forks, "U_f", some "S"), + (some .legacy, "U_l", some "S")]) + + -- With no base scope the forks round defaults to the HEAD scope; the other + -- containers' layouts are not SHA-scoped, so it must not leak into them. + assert "no base scope, head scope → forks at head, others unscoped" + (expandDownloadRounds chain none [] (some "H") == + [(some .master, "U_m", none), (some .forks, "U_f", some "H"), + (some .legacy, "U_l", none)]) + assert "explicit base scope wins over head scope" + (expandDownloadRounds chain (some "S") [] (some "H") == + [(some .master, "U_m", some "S"), (some .forks, "U_f", some "S"), + (some .legacy, "U_l", some "S")]) + assert "unsafe mode ignores head scope" + (expandDownloadRounds chain none ["a"] (some "H") == + [(some .master, "U_m", none), (some .forks, "U_f", some "a"), + (some .legacy, "U_l", none)]) + + -- Unsafe scopes: only forks fans out, in order; others unscoped, base dropped. + assert "unsafe scopes fan out forks (in order), others unscoped" + (expandDownloadRounds chain (some "ignored") ["a", "b"] == + [(some .master, "U_m", none), + (some .forks, "U_f", some "a"), (some .forks, "U_f", some "b"), + (some .legacy, "U_l", none)]) + + -- A chain without forks admits no SHA-scoped reads, so it is left unchanged. + assert "no forks container → unsafe scopes have no effect" + (expandDownloadRounds [(some .master, "U_m"), (some .legacy, "U_l")] none ["a", "b"] == + [(some .master, "U_m", none), (some .legacy, "U_l", none)]) + +end UnsafeRounds + +def runAll : IO Unit := do + test_Container_name + test_Container_parse + test_Container_azureURL + test_Container_flatPath + test_defaultContainersForRepo + test_mkFileURL + test_parseCacheFromList + test_extractRepoFromUrl + test_extractPRNumber + test_hashFromFileName + test_isRemoteURL + test_UInt64_asLTar + test_hash_roundtrip + test_markerURL + test_getRepoScope + test_shouldWarnNonDefaultScope + test_getNonDefaultScopeReason + test_findMostRecentSHAWithCache + test_findRecentSHAsWithCache + test_getRemoteRepo_gitFallback + test_headIsAncestorOfMaster_gitFallback + test_isKnownOpt + test_parseNamedOpt + test_parseFlagOpt + test_isCacheMissStatus + test_isAlreadyPresentStatus + test_expandDownloadRounds + +end Cache.Test + +open Cache.Test in +def main : IO UInt32 := do + runAll + let n ← failures.get + if n == 0 then + IO.println "\nAll cache tests passed." + return 0 + else + IO.eprintln s!"\n{n} cache test(s) failed." + return 1 diff --git a/Cache/Warning.lean b/Cache/Warning.lean new file mode 100644 index 00000000000000..2aba0a12428b87 --- /dev/null +++ b/Cache/Warning.lean @@ -0,0 +1,228 @@ +/- +Copyright (c) 2026 Marcelo Lynch. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Marcelo Lynch +-/ + +import Cache.Query + +/-! +# Read-time advisories + +Two stderr-only notices `cache get` prints before reading: + +* a security warning when the read is taken off the repo's default trust + boundary (a scope, a widened `--cache-from`, or a `--repo` that diverges + from the git remote), and +* a hint pointing an uncached fork HEAD at `cache query` and the SHA-scoped + workflow. +-/ + +namespace Cache.Requests + +/-- +`true` iff the resolved scope (see `getRepoScope`) equals the checked-out HEAD. + +A HEAD scope only serves artifacts built from the commit already checked out, +and it is what an unscoped `cache get` reads anyway — the forks round defaults +to the HEAD namespace (see `expandDownloadRounds`). So an explicit HEAD scope +(e.g. CI's `MATHLIB_CACHE_REPO_SCOPE`, set to the build SHA on every fork +build) just pins the default behavior and warrants no warning. + +`false` when no scope is set or HEAD cannot be determined. +-/ +def scopeIsHead : IO Bool := do + let some scope ← getRepoScope | return false + let head ← try getGitCommitHash catch _ => return false + return head == scope + +/-- +Condition to determine if a non-default scope warning should be printed. + +Returns `true` if any of these hold: +0. `--unsafe` was passed (`unsafeWindow?` is `some _`): the read walks several + fork commits and trusts whoever built each of them +1. `MATHLIB_CACHE_REPO_SCOPE` is set in the environment (any non-empty value) + and differs from the checked-out HEAD (see `scopeIsHead`) +2. `--cache-from` was passed and widens the lookup chain beyond `defaultContainersForRepo` for the resolved repo +3. `--repo` was passed and does not match the git remote (`detectedRepo?`) + +`detectedRepo?` is the repo reported by the git remote (from `resolveRepo`, +probed once per command); it is `none` if it could not be determined. + +Otherwise returns `false` (default lookup chain, no warning needed). +-/ +def shouldWarnNonDefaultScope (repoExplicit? detectedRepo? : Option String) + (cliCacheFromOverride? : Option (List Container)) (resolvedRepo : String) + (unsafeWindow? : Option Nat := none) : + IO Bool := do + -- Condition 0: `--unsafe` (with its SHA window) — the most permissive read. + if unsafeWindow?.isSome then return true + + -- Condition 1: `--scope=` flag or `MATHLIB_CACHE_REPO_SCOPE` env var supplied. + -- A HEAD scope is exempt: trust-equivalent to no scope (see `scopeIsHead`). + if (← getRepoScope).isSome then + unless (← scopeIsHead) do return true + + -- Condition 2: --cache-from CLI override widens the lookup chain + match cliCacheFromOverride? with + | some cliOverride => + let defaultContainers := defaultContainersForRepo resolvedRepo + unless cliOverride == defaultContainers do + return true + | none => pure () + + -- Condition 3: --repo was explicitly passed AND does not match the git remote. + -- Only fires when the user explicitly overrode --repo; defaulting to MATHLIBREPO + -- from a fork checkout is normal and does not warn. + match repoExplicit?, detectedRepo? with + | some explicitRepo, some detected => + unless explicitRepo == detected do + return true + -- No --repo override, or the remote couldn't be determined: don't warn. + | _, _ => pure () + + return false + +/-- +Print a prominent security warning to stderr when reading at a non-default scope. + +The warning includes: +- A clear statement that the user is trusting artifacts at a non-default scope +- The scope details (container, repo, SHA as applicable) +- Why the warning is being issued (which condition triggered it) +-/ +def printNonDefaultScopeWarning (repo : String) (triggerReason : String) : IO Unit := do + let lines : List String := [ + "=================================================================", + "SECURITY: reading cache at a non-default scope", + "=================================================================", + "You are reading cache artifacts at a scope outside the default trust", + "boundary for this repo. The cache cannot verify the contents of these", + "artifacts; you are choosing to trust whoever uploaded them.", + "", + s!"Repository: {repo}", + s!"Reason: {triggerReason}", + "=================================================================", + ] + for line in lines do + IO.eprintln line + +/-- +Determine the reason why a non-default scope warning is being issued. + +Returns a human-readable string describing which condition triggered the warning. +-/ +def getNonDefaultScopeReason (repoExplicit? detectedRepo? : Option String) + (cliCacheFromOverride? : Option (List Container)) (resolvedRepo : String) + (unsafeWindow? : Option Nat := none) : + IO String := do + -- Check conditions in order; return the first that matches. + + -- Condition 0: `--unsafe` walks up to `window` fork commits, trusting each. + if let some window := unsafeWindow? then + return s!"--unsafe (automatic walk over up to {window} fork commit(s); \ + trusting whoever built them)" + + -- Condition 1: `--scope=` flag (preferred form) or `MATHLIB_CACHE_REPO_SCOPE` + -- env var (CI form). Reported with the source that set it. A HEAD scope is + -- exempt, mirroring `shouldWarnNonDefaultScope`. + unless (← scopeIsHead) do + if let some s ← scopeOverride.get then + return s!"--scope={s} (explicit per-commit scope)" + let scope? ← IO.getEnv "MATHLIB_CACHE_REPO_SCOPE" + if let some scope := scope? then + let trimmed := scope.trimAscii + if !trimmed.isEmpty then + return s!"MATHLIB_CACHE_REPO_SCOPE={trimmed} (explicit per-commit scope)" + + -- Condition 2: --cache-from override + if let some cliOverride := cliCacheFromOverride? then + let defaultContainers := defaultContainersForRepo resolvedRepo + if cliOverride != defaultContainers then + let overrideStr := ", ".intercalate (cliOverride.map Container.name) + return s!"--cache-from={overrideStr} (explicit container override)" + + -- Condition 3: --repo was explicitly passed AND doesn't match the git remote + match repoExplicit?, detectedRepo? with + | some explicitRepo, some detected => + if explicitRepo != detected then + return s!"--repo={explicitRepo} (overrides detected git remote: {detected})" + | _, _ => pure () + + return "unknown reason" + +/-- +Print the non-default-scope warning if any of the three conditions hold. + +Called before a read (`cache get`). The warning is informational only — it +never prompts, so it stays safe to run in CI. +-/ +def warnIfNonDefaultScope (repoExplicit? detectedRepo? : Option String) + (cliCacheFromOverride? : Option (List Container)) (resolvedRepo : String) + (unsafeWindow? : Option Nat := none) : + IO Unit := do + if (← shouldWarnNonDefaultScope repoExplicit? detectedRepo? cliCacheFromOverride? resolvedRepo + unsafeWindow?) + then + let reason ← getNonDefaultScopeReason repoExplicit? detectedRepo? cliCacheFromOverride? + resolvedRepo unsafeWindow? + printNonDefaultScopeWarning resolvedRepo reason + +/-- +If the user is on a commit that hasn't been cached for this fork (no marker +present at `forks/m/{repo}/{HEAD-sha}`), print an informational note +explaining the new SHA-scoped behavior and pointing at `cache query`. + +Fires only on naive `cache get` invocations: +- no `--scope=` / `MATHLIB_CACHE_REPO_SCOPE` set (else the user has already + picked a scope and the non-default-scope warning is doing the talking) +- no `--cache-from` override (else they've already taken explicit + responsibility for the lookup chain) +- the resolved repo's default lookup chain reads from `forks` (otherwise SHA + scoping is not relevant) +- HEAD is not already an ancestor of `master`. From a personal-fork checkout + sitting on `master` (or an undiverged branch), the fork's SHA-scoped marker is + structurally absent, but `master` is first in the fork lookup chain and serves + every file by hash — there is nothing fork-specific to build, so the note would + be a pure false positive. + +One HEAD probe per invocation; the message is stderr-only so it doesn't +mix with `cache get`'s stdout output. + +`repo` is the already-resolved repo (see `resolveRepo`). +-/ +def informIfHeadNotBuilt (repo : String) : IO Unit := do + if (← getRepoScope).isSome then return + if (← cacheFromOverride.get).isSome then return + unless (defaultContainersForRepo repo).contains Container.forks do return + -- HEAD already on (an ancestor of) master: master CI builds these commits and + -- the master container (first in the fork lookup chain) serves their artifacts + -- by hash, so there is nothing fork-specific to build. The forks marker is + -- structurally absent here, which would otherwise trigger a misleading note. + if (← headIsAncestorOfMaster) then return + let sha ← try getGitCommitHash catch _ => return + let hasMarker ← probeContainerForSHA Container.forks repo sha + if hasMarker then return + let lines : List String := [ + "", + s!"NOTE: no cache found for HEAD ({sha}) on fork {repo}.", + "This commit hasn't been built by CI for this fork yet. You'll still", + "get cache hits for files that match mathlib's master cache; only", + "files unique to this PR will need to be rebuilt.", + "", + "To use a prior CI run from this fork, find a cached commit:", + " lake exe cache query", + "", + "then re-run with:", + " lake exe cache get --scope=", + "", + "Important: using another commit's scope means trusting the artifacts", + "produced at that commit. `cache get` will print a security notice", + "when you do.", + "", + ] + for line in lines do + IO.eprintln line + +end Cache.Requests diff --git a/lakefile.lean b/lakefile.lean index 573d0222a7a789..46071184a166ee 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -101,6 +101,12 @@ lean_exe autolabel where lean_exe cache where root := `Cache.Main +/-- `lake exe cache-test` runs the cache tool's unit tests (container URL +construction, per-repo trust-ordered allowlist, `--cache-from` parsing). +Runnable standalone — does not require building Mathlib or `MathlibTest`. -/ +lean_exe «cache-test» where + root := `Cache.Test + /-- `lake exe check-yaml` verifies that all declarations referred to in `docs/*.yaml` files exist. -/ lean_exe «check-yaml» where srcDir := "scripts" From 50b70b95b5f7070567a7de4bc2079b25776783b2 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:23:47 +0000 Subject: [PATCH 0052/1300] chore(CI): fix merge conflict resolution for nightly-testing (#40257) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolving merge conflicts in favor of `nightly-testing` when merging `master` may be convenient for nightly maintainers, but it can lead to changes made on `master` accidentally being dropped again later in the bump PR. For an example case, see #40189 (see [#PR reviews > #39443 `nonempty_preimage_iff` @ 💬](https://leanprover.zulipchat.com/#narrow/channel/144837-PR-reviews/topic/.2339443.20.60nonempty_preimage_iff.60/near/599885755) for an explanation of what happened). Resolving conflicts in favor of `master` means that `nightly-testing` will rather break than silently undoing changes made on `master`. Co-authored-by: Joscha --- .github/workflows/nightly_merge_master.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/nightly_merge_master.yml b/.github/workflows/nightly_merge_master.yml index 097518d25dcf5a..e371f9e9b4cd10 100644 --- a/.github/workflows/nightly_merge_master.yml +++ b/.github/workflows/nightly_merge_master.yml @@ -1,4 +1,4 @@ -# This job merges every commit to `master` into `nightly-testing`, resolving merge conflicts in favor of `nightly-testing`. +# This job merges every commit to `master` into `nightly-testing`, resolving merge conflicts in favor of `master`. name: Merge master to nightly @@ -49,15 +49,17 @@ jobs: git config user.name "mathlib-nightly-testing[bot]" git config user.email "mathlib-nightly-testing[bot]@users.noreply.github.com" - - name: Merge master to nightly favoring nightly changes + - name: Merge master to nightly favoring master changes run: | cd nightly-testing git remote add upstream https://github.com/leanprover-community/mathlib4.git git fetch upstream master - # Merge master into nightly-testing, resolving conflicts in favor of nightly-testing + # Merge master into nightly-testing, resolving conflicts in favor of master. + # In the past, we've silently dropped changes made on master because + # conflicts were resolved in favor of nightly-testing, which is bad. # If the merge goes badly, we proceed anyway via '|| true'. # CI will report failures on the 'nightly-testing' branch direct to Zulip. - git merge upstream/master --strategy-option ours --no-commit --allow-unrelated-histories || true + git merge upstream/master --strategy-option theirs --no-commit --allow-unrelated-histories || true # We aggressively run `lake update`, to avoid having to do this by hand. # When Batteries changes break Mathlib, this will likely show up on nightly-testing first. lake update -v From 94fba23a1390006d2c960739fec79a580e947d85 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Tue, 16 Jun 2026 01:11:54 +0000 Subject: [PATCH 0053/1300] feat(MeasureTheory): use `Is*Apply` for `VectorMeasure` (#40450) Add `FunLike` and `IsApply` instances for `VectorMeasure`, also add a `coe_mk` `simp` lemma. --- .../MeasureTheory/VectorMeasure/Basic.lean | 137 ++++++++++-------- .../VectorMeasure/BoundedVariation.lean | 3 +- .../VectorMeasure/Decomposition/Hahn.lean | 6 +- .../VectorMeasure/Decomposition/Jordan.lean | 23 ++- .../VectorMeasure/Decomposition/Lebesgue.lean | 10 +- .../Decomposition/RadonNikodym.lean | 2 +- .../MeasureTheory/VectorMeasure/Integral.lean | 12 +- .../VectorMeasure/Variation/Basic.lean | 12 +- .../VectorMeasure/WithDensity.lean | 8 +- 9 files changed, 109 insertions(+), 104 deletions(-) diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index 89109bd96cf520..3f8ee9b91f4a05 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -82,10 +82,13 @@ section variable {M : Type*} [AddCommMonoid M] [TopologicalSpace M] -attribute [coe] VectorMeasure.measureOf' +instance : FunLike (VectorMeasure α M) (Set α) M where + coe := VectorMeasure.measureOf' + coe_injective v w h := by + cases v; cases w; congr -instance instCoeFun : CoeFun (VectorMeasure α M) fun _ => Set α → M := - ⟨VectorMeasure.measureOf'⟩ +@[simp] +theorem coe_mk (v : Set α → M) (h₁) (h₂) (h₃) : (mk v h₁ h₂ h₃ : VectorMeasure α M) = v := rfl initialize_simps_projections VectorMeasure (measureOf' → apply) @@ -101,19 +104,15 @@ theorem m_iUnion (v : VectorMeasure α M) {f : ℕ → Set α} (hf₁ : ∀ i, M (hf₂ : Pairwise (Disjoint on f)) : HasSum (fun i => v (f i)) (v (⋃ i, f i)) := v.m_iUnion' hf₁ hf₂ -theorem coe_injective : @Function.Injective (VectorMeasure α M) (Set α → M) (⇑) := fun v w h => by - cases v - cases w - congr +@[deprecated (since := "2026-06-10")] alias coe_injective := DFunLike.coe_injective -theorem ext_iff' (v w : VectorMeasure α M) : v = w ↔ ∀ i : Set α, v i = w i := by - rw [← coe_injective.eq_iff, funext_iff] +@[deprecated (since := "2026-06-10")] alias ext_iff' := DFunLike.ext_iff theorem ext_iff (v w : VectorMeasure α M) : v = w ↔ ∀ i : Set α, MeasurableSet i → v i = w i := by constructor · rintro rfl _ _ rfl - · rw [ext_iff'] + · rw [DFunLike.ext_iff] intro h i by_cases hi : MeasurableSet i · exact h i hi @@ -271,10 +270,12 @@ def smul (r : R) (v : VectorMeasure α M) : VectorMeasure α M where instance instSMul : SMul R (VectorMeasure α M) := ⟨smul⟩ -@[simp] -theorem coe_smul (r : R) (v : VectorMeasure α M) : ⇑(r • v) = r • ⇑v := rfl +instance : IsSMulApply R (VectorMeasure α M) (Set α) M where + smul_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] alias coe_smul := FunLike.coe_smul -theorem smul_apply (r : R) (v : VectorMeasure α M) (i : Set α) : (r • v) i = r • v i := rfl +@[deprecated (since := "2026-06-10")] protected alias smul_apply := smul_apply end SMul @@ -285,6 +286,9 @@ variable {M : Type*} [AddCommMonoid M] [TopologicalSpace M] instance instZero : Zero (VectorMeasure α M) := ⟨⟨0, rfl, fun _ _ => rfl, fun _ _ _ => hasSum_zero⟩⟩ +instance : IsZeroApply (VectorMeasure α M) (Set α) M where + zero_apply _ := rfl + instance instInhabited : Inhabited (VectorMeasure α M) := ⟨0⟩ @@ -299,10 +303,9 @@ instance [IsEmpty α] : Subsingleton (VectorMeasure α M) := theorem eq_zero_of_isEmpty [IsEmpty α] (μ : VectorMeasure α M) : μ = 0 := Subsingleton.elim μ 0 -@[simp] -theorem coe_zero : ⇑(0 : VectorMeasure α M) = 0 := rfl +@[deprecated (since := "2026-06-10")] alias coe_zero := FunLike.coe_zero -theorem zero_apply (i : Set α) : (0 : VectorMeasure α M) i = 0 := rfl +@[deprecated (since := "2026-06-10")] protected alias zero_apply := zero_apply variable [ContinuousAdd M] @@ -316,24 +319,21 @@ def add (v w : VectorMeasure α M) : VectorMeasure α M where instance instAdd : Add (VectorMeasure α M) := ⟨add⟩ -@[simp] -theorem coe_add (v w : VectorMeasure α M) : ⇑(v + w) = v + w := rfl +instance : IsAddApply (VectorMeasure α M) (Set α) M where + add_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] alias coe_add := FunLike.coe_add -theorem add_apply (v w : VectorMeasure α M) (i : Set α) : (v + w) i = v i + w i := rfl +@[deprecated (since := "2026-06-10")] protected alias add_apply := add_apply instance instAddCommMonoid : AddCommMonoid (VectorMeasure α M) := - Function.Injective.addCommMonoid _ coe_injective coe_zero coe_add fun _ _ => coe_smul _ _ + fast_instance% FunLike.addCommMonoid -/-- `(⇑)` is an `AddMonoidHom`. -/ -@[simps] -def coeFnAddMonoidHom : VectorMeasure α M →+ Set α → M where - toFun := (⇑) - map_zero' := coe_zero - map_add' := coe_add +@[deprecated (since := "2026-06-10")] alias coeFnAddMonoidHom := FunLike.coeAddMonoidHom -@[simp] -theorem coe_finsetSum {ι} (I : Finset ι) (v : ι → VectorMeasure α M) : - ⇑(∑ i ∈ I, v i) = ∑ i ∈ I, ⇑(v i) := map_sum coeFnAddMonoidHom v I +@[deprecated (since := "2026-06-10")] alias coeFnAddMonoidHom_apply := FunLike.coeAddMonoidHom_apply + +@[deprecated (since := "2026-06-10")] alias coe_finsetSum := FunLike.coe_sum end AddCommMonoid @@ -351,10 +351,12 @@ def neg (v : VectorMeasure α M) : VectorMeasure α M where instance instNeg : Neg (VectorMeasure α M) := ⟨neg⟩ -@[simp] -theorem coe_neg (v : VectorMeasure α M) : ⇑(-v) = -v := rfl +instance : IsNegApply (VectorMeasure α M) (Set α) M where + neg_apply _ _ := rfl -theorem neg_apply (v : VectorMeasure α M) (i : Set α) : (-v) i = -v i := rfl +@[deprecated (since := "2026-06-10")] alias coe_neg := FunLike.coe_neg + +@[deprecated (since := "2026-06-10")] protected alias neg_apply := neg_apply /-- The difference of two vector measure is a vector measure. -/ def sub (v w : VectorMeasure α M) : VectorMeasure α M where @@ -366,14 +368,14 @@ def sub (v w : VectorMeasure α M) : VectorMeasure α M where instance instSub : Sub (VectorMeasure α M) := ⟨sub⟩ -@[simp] -theorem coe_sub (v w : VectorMeasure α M) : ⇑(v - w) = v - w := rfl +instance : IsSubApply (VectorMeasure α M) (Set α) M where + sub_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] alias coe_sub := FunLike.coe_sub -theorem sub_apply (v w : VectorMeasure α M) (i : Set α) : (v - w) i = v i - w i := rfl +@[deprecated (since := "2026-06-10")] protected alias sub_apply := sub_apply -instance instAddCommGroup : AddCommGroup (VectorMeasure α M) := - Function.Injective.addCommGroup _ coe_injective coe_zero coe_add coe_neg coe_sub - (fun _ _ => coe_smul _ _) fun _ _ => coe_smul _ _ +instance instAddCommGroup : AddCommGroup (VectorMeasure α M) := fast_instance% FunLike.addCommGroup end AddCommGroup @@ -383,7 +385,7 @@ variable {M : Type*} [AddCommMonoid M] [TopologicalSpace M] variable {R : Type*} [Semiring R] [DistribMulAction R M] [ContinuousConstSMul R M] instance instDistribMulAction [ContinuousAdd M] : DistribMulAction R (VectorMeasure α M) := - Function.Injective.distribMulAction coeFnAddMonoidHom coe_injective coe_smul + fast_instance% FunLike.distribMulAction end DistribMulAction @@ -393,7 +395,7 @@ variable {M : Type*} [AddCommMonoid M] [TopologicalSpace M] variable {R : Type*} [Semiring R] [Module R M] [ContinuousConstSMul R M] instance instModule [ContinuousAdd M] : Module R (VectorMeasure α M) := - Function.Injective.module R coeFnAddMonoidHom coe_injective coe_smul + fast_instance% FunLike.module end Module @@ -423,8 +425,8 @@ def dirac (x : β) (v : M) : VectorMeasure β M where have : Disjoint (f i) (f j) := f_disj hi grind -@[simp] lemma dirac_apply_of_mem (hs : MeasurableSet s) (hx : x ∈ s) : dirac x v s = v := by - simp [dirac, hs, hx] +@[simp] lemma dirac_apply_of_mem (hs : MeasurableSet s) (hx : x ∈ s) : dirac x v s = v := + if_pos (And.intro hs hx) @[simp] lemma dirac_apply_of_notMem (hx : x ∉ s) : dirac x v s = 0 := by simp [dirac, hx] @@ -439,11 +441,10 @@ end VectorMeasure namespace Measure -open Classical in +open scoped Classical in /-- A finite measure coerced into a real function is a signed measure. -/ -@[simps] def toSignedMeasure (μ : Measure α) [hμ : IsFiniteMeasure μ] : SignedMeasure α where - measureOf' := fun s : Set α => if MeasurableSet s then μ.real s else 0 + measureOf' s := if MeasurableSet s then μ.real s else 0 empty' := by simp not_measurable' _ hi := if_neg hi m_iUnion' f hf₁ hf₂ := by @@ -451,6 +452,11 @@ def toSignedMeasure (μ : Measure α) [hμ : IsFiniteMeasure μ] : SignedMeasure rw [ENNReal.tsum_toReal_eq] exacts [(summable_measure_toReal hf₁ hf₂).hasSum, fun _ ↦ measure_ne_top _ _] +open scoped Classical in +@[simp] +theorem toSignedMeasure_apply (μ : Measure α) [hμ : IsFiniteMeasure μ] (i : Set α) : + μ.toSignedMeasure i = if MeasurableSet i then μ.real i else 0 := rfl + theorem toSignedMeasure_apply_measurable {μ : Measure α} [IsFiniteMeasure μ] {i : Set α} (hi : MeasurableSet i) : μ.toSignedMeasure i = μ.real i := if_pos hi @@ -472,30 +478,29 @@ theorem toSignedMeasure_eq_toSignedMeasure_iff {μ ν : Measure α} [IsFiniteMea @[simp] theorem toSignedMeasure_zero : (0 : Measure α).toSignedMeasure = 0 := by - ext i - simp + ext i hi + simp [hi] @[simp] theorem toSignedMeasure_add (μ ν : Measure α) [IsFiniteMeasure μ] [IsFiniteMeasure ν] : (μ + ν).toSignedMeasure = μ.toSignedMeasure + ν.toSignedMeasure := by ext i hi rw [toSignedMeasure_apply_measurable hi, measureReal_add_apply, - VectorMeasure.add_apply, toSignedMeasure_apply_measurable hi, + _root_.add_apply, toSignedMeasure_apply_measurable hi, toSignedMeasure_apply_measurable hi] @[simp] theorem toSignedMeasure_smul (μ : Measure α) [IsFiniteMeasure μ] (r : ℝ≥0) : (r • μ).toSignedMeasure = r • μ.toSignedMeasure := by ext i hi - rw [toSignedMeasure_apply_measurable hi, VectorMeasure.smul_apply, + rw [toSignedMeasure_apply_measurable hi, _root_.smul_apply, toSignedMeasure_apply_measurable hi, measureReal_nnreal_smul_apply] rfl -open Classical in +open scoped Classical in /-- A measure is a vector measure over `ℝ≥0∞`. -/ -@[simps] def toENNRealVectorMeasure (μ : Measure α) : VectorMeasure α ℝ≥0∞ where - measureOf' := fun i : Set α => if MeasurableSet i then μ i else 0 + measureOf' i := if MeasurableSet i then μ i else 0 empty' := by simp not_measurable' _ hi := if_neg hi m_iUnion' _ hf₁ hf₂ := by @@ -503,6 +508,11 @@ def toENNRealVectorMeasure (μ : Measure α) : VectorMeasure α ℝ≥0∞ where MeasureTheory.measure_iUnion hf₂ hf₁] exact tsum_congr fun n => if_pos (hf₁ n) +open scoped Classical in +@[simp] +theorem toENNRealVectorMeasure_apply (μ : Measure α) (i : Set α) : + μ.toENNRealVectorMeasure i = if MeasurableSet i then μ i else 0 := rfl + theorem toENNRealVectorMeasure_apply_measurable {μ : Measure α} {i : Set α} (hi : MeasurableSet i) : μ.toENNRealVectorMeasure i = μ i := if_pos hi @@ -516,13 +526,13 @@ theorem toENNRealVectorMeasure_zero : (0 : Measure α).toENNRealVectorMeasure = theorem toENNRealVectorMeasure_add (μ ν : Measure α) : (μ + ν).toENNRealVectorMeasure = μ.toENNRealVectorMeasure + ν.toENNRealVectorMeasure := by refine MeasureTheory.VectorMeasure.ext fun i hi => ?_ - rw [toENNRealVectorMeasure_apply_measurable hi, add_apply, VectorMeasure.add_apply, + rw [toENNRealVectorMeasure_apply_measurable hi, add_apply, _root_.add_apply, toENNRealVectorMeasure_apply_measurable hi, toENNRealVectorMeasure_apply_measurable hi] theorem toSignedMeasure_sub_apply {μ ν : Measure α} [IsFiniteMeasure μ] [IsFiniteMeasure ν] {i : Set α} (hi : MeasurableSet i) : (μ.toSignedMeasure - ν.toSignedMeasure) i = μ.real i - ν.real i := by - rw [VectorMeasure.sub_apply, toSignedMeasure_apply_measurable hi, + rw [_root_.sub_apply, toSignedMeasure_apply_measurable hi, Measure.toSignedMeasure_apply_measurable hi] end Measure @@ -812,7 +822,7 @@ variable {v : VectorMeasure α M} {i s t : Set α} theorem restrict_add_restrict_compl (hi : MeasurableSet i) : v.restrict i + v.restrict iᶜ = v := by ext A hA - rw [add_apply, restrict_apply _ hi hA, restrict_apply _ hi.compl hA, + rw [_root_.add_apply, restrict_apply _ hi hA, restrict_apply _ hi.compl hA, ← of_union _ (hA.inter hi) (hA.inter hi.compl)] · simp · exact disjoint_compl_right.inter_right' A |>.inter_left' A @@ -820,7 +830,7 @@ theorem restrict_add_restrict_compl (hi : MeasurableSet i) : theorem restrict_inter_add_sdiff (hs : MeasurableSet s) (ht : MeasurableSet t) : v.restrict (s ∩ t) + v.restrict (s \ t) = v.restrict s := by ext u hu - simp only [add_apply, restrict_apply, hs, hu, hs.inter ht, hs.diff ht] + simp only [_root_.add_apply, restrict_apply, hs, hu, hs.inter ht, hs.diff ht] rw [← of_union (by grind) (hu.inter (hs.inter ht)) (hu.inter (hs.diff ht))] congr grind @@ -1100,7 +1110,7 @@ variable {M : Type*} [TopologicalSpace M] [AddCommMonoid M] [PartialOrder M] [AddLeftMono M] [ContinuousAdd M] instance instAddLeftMono : AddLeftMono (VectorMeasure α M) := - ⟨fun _ _ _ h i hi => by dsimp; grw [h i hi]⟩ + ⟨fun _ _ _ h i hi => by simp only [_root_.add_apply]; grw [h i hi]⟩ end @@ -1159,7 +1169,7 @@ theorem neg_right {N : Type*} [AddCommGroup N] [TopologicalSpace N] [IsTopologic theorem add [ContinuousAdd M] {v₁ v₂ : VectorMeasure α M} {w : VectorMeasure α N} (hv₁ : v₁ ≪ᵥ w) (hv₂ : v₂ ≪ᵥ w) : v₁ + v₂ ≪ᵥ w := by intro s hs - rw [add_apply, hv₁ hs, hv₂ hs, zero_add] + rw [_root_.add_apply, hv₁ hs, hv₂ hs, zero_add] theorem sub {M : Type*} [AddCommGroup M] [TopologicalSpace M] [IsTopologicalAddGroup M] {v₁ v₂ : VectorMeasure α M} {w : VectorMeasure α N} (hv₁ : v₁ ≪ᵥ w) (hv₂ : v₂ ≪ᵥ w) : @@ -1170,7 +1180,7 @@ theorem sub {M : Type*} [AddCommGroup M] [TopologicalSpace M] [IsTopologicalAddG theorem smul {R : Type*} [Semiring R] [DistribMulAction R M] [ContinuousConstSMul R M] {r : R} {v : VectorMeasure α M} {w : VectorMeasure α N} (h : v ≪ᵥ w) : r • v ≪ᵥ w := by intro s hs - rw [smul_apply, h hs, smul_zero] + rw [_root_.smul_apply, h hs, smul_zero] theorem map [MeasureSpace β] (h : v ≪ᵥ w) (f : α → β) : v.map f ≪ᵥ w.map f := by by_cases hf : Measurable f @@ -1233,7 +1243,7 @@ theorem add_left [T2Space N] [ContinuousAdd M] (h₁ : v₁ ⟂ᵥ w) (h₂ : v obtain ⟨u, hmu, hu₁, hu₂⟩ := h₁ obtain ⟨v, hmv, hv₁, hv₂⟩ := h₂ refine mk (u ∩ v) (hmu.inter hmv) (fun t ht _ => ?_) fun t ht hmt => ?_ - · rw [add_apply, hu₁ _ (Set.subset_inter_iff.1 ht).1, hv₁ _ (Set.subset_inter_iff.1 ht).2, + · rw [_root_.add_apply, hu₁ _ (Set.subset_inter_iff.1 ht).1, hv₁ _ (Set.subset_inter_iff.1 ht).2, zero_add] · rw [Set.compl_inter] at ht rw [(_ : t = uᶜ ∩ t ∪ vᶜ \ uᶜ ∩ t), @@ -1254,7 +1264,7 @@ theorem add_right [T2Space M] [ContinuousAdd N] (h₁ : v ⟂ᵥ w₁) (h₂ : v theorem smul_right {R : Type*} [Semiring R] [DistribMulAction R N] [ContinuousConstSMul R N] (r : R) (h : v ⟂ᵥ w) : v ⟂ᵥ r • w := let ⟨s, hmeas, hs₁, hs₂⟩ := h - ⟨s, hmeas, hs₁, fun t ht => by simp only [coe_smul, Pi.smul_apply, hs₂ t ht, smul_zero]⟩ + ⟨s, hmeas, hs₁, fun t ht => by simp only [_root_.smul_apply, hs₂ t ht, smul_zero]⟩ theorem smul_left {R : Type*} [Semiring R] [DistribMulAction R M] [ContinuousConstSMul R M] (r : R) (h : v ⟂ᵥ w) : r • v ⟂ᵥ w := @@ -1427,8 +1437,7 @@ variable (μ ν : Measure α) [IsFiniteMeasure μ] [IsFiniteMeasure ν] (s : Set theorem zero_le_toSignedMeasure : 0 ≤ μ.toSignedMeasure := by rw [← le_restrict_univ_iff_le] refine restrict_le_restrict_of_subset_le _ _ fun j hj₁ _ => ?_ - simp only [VectorMeasure.coe_zero, Pi.zero_apply, Measure.toSignedMeasure_apply_measurable hj₁, - measureReal_nonneg] + simp [hj₁] theorem toSignedMeasure_toMeasureOfZeroLE : μ.toSignedMeasure.toMeasureOfZeroLE Set.univ MeasurableSet.univ @@ -1442,7 +1451,7 @@ theorem toSignedMeasure_toMeasureOfZeroLE : theorem toSignedMeasure_restrict_eq_restrict_toSignedMeasure (hs : MeasurableSet s) : μ.toSignedMeasure.restrict s = (μ.restrict s).toSignedMeasure := by ext A hA - simp [VectorMeasure.restrict_apply, toSignedMeasure_apply, hA, hs] + simp [VectorMeasure.restrict_apply, hA, hs] theorem toSignedMeasure_le_toSignedMeasure_iff : μ.toSignedMeasure ≤ ν.toSignedMeasure ↔ μ ≤ ν := by diff --git a/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean b/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean index 6cfb1d2441bbdf..c053ad9ee7f9c9 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean @@ -139,8 +139,7 @@ lemma vectorMeasure_singleton (hf : BoundedVariationOn f univ) : have A : hf.exists_vectorMeasure_le_measureAux.choose {a} = 0 := by rw [← botSet_eq_singleton_of_isBot ha] exact hf.exists_vectorMeasure_le_measureAux.choose_spec.2.1 - simp only [vectorMeasure, h, ↓reduceDIte, VectorMeasure.coe_add, Pi.add_apply, A, - zero_add] + simp only [vectorMeasure, h, ↓reduceDIte, add_apply, A, zero_add] rw [VectorMeasure.dirac_apply_of_mem (MeasurableSet.singleton a)] · simpa only [heqa, sub_right_inj] using (leftLim_eq_of_isBot ha).symm · simp [heqa] diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean index cac5d70445e547..79ff56ab497813 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean @@ -423,8 +423,7 @@ theorem of_symmDiff_compl_positive_negative {s : SignedMeasure α} {i j : Set α le_antisymm (hi'.2 (hi.compl.inter hj) Set.inter_subset_left) (hj'.1 (hi.compl.inter hj) Set.inter_subset_right), le_antisymm (hj'.2 (hj.compl.inter hi) Set.inter_subset_left) - (hi'.1 (hj.compl.inter hi) Set.inter_subset_right), - VectorMeasure.zero_apply, VectorMeasure.zero_apply, zero_add] + (hi'.1 (hj.compl.inter hi) Set.inter_subset_right), zero_apply, zero_apply, zero_add] · exact Set.disjoint_of_subset_left Set.inter_subset_left (Set.disjoint_of_subset_right Set.inter_subset_right @@ -436,8 +435,7 @@ theorem of_symmDiff_compl_positive_negative {s : SignedMeasure α} {i j : Set α le_antisymm (hi'.2 (hj.inter hi.compl) Set.inter_subset_right) (hj'.1 (hj.inter hi.compl) Set.inter_subset_left), le_antisymm (hj'.2 (hi.inter hj.compl) Set.inter_subset_right) - (hi'.1 (hi.inter hj.compl) Set.inter_subset_left), - VectorMeasure.zero_apply, VectorMeasure.zero_apply, zero_add] + (hi'.1 (hi.inter hj.compl) Set.inter_subset_left), zero_apply, zero_apply, zero_add] · exact Set.disjoint_of_subset_left Set.inter_subset_left (Set.disjoint_of_subset_right Set.inter_subset_right diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean index 262cf40971bb08..417bfddffebd7e 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean @@ -152,16 +152,16 @@ def toSignedMeasure : SignedMeasure α := theorem toSignedMeasure_zero : (0 : JordanDecomposition α).toSignedMeasure = 0 := by ext1 i hi rw [toSignedMeasure, toSignedMeasure_sub_apply hi, zero_posPart, zero_negPart, sub_self, - VectorMeasure.coe_zero, Pi.zero_apply] + FunLike.coe_zero, Pi.zero_apply] theorem toSignedMeasure_neg : (-j).toSignedMeasure = -j.toSignedMeasure := by ext1 i hi - rw [VectorMeasure.neg_apply, toSignedMeasure, toSignedMeasure, toSignedMeasure_sub_apply hi, + rw [neg_apply, toSignedMeasure, toSignedMeasure, toSignedMeasure_sub_apply hi, toSignedMeasure_sub_apply hi, neg_sub, neg_posPart, neg_negPart] theorem toSignedMeasure_smul (r : ℝ≥0) : (r • j).toSignedMeasure = r • j.toSignedMeasure := by ext1 i hi - rw [VectorMeasure.smul_apply, toSignedMeasure, toSignedMeasure, + rw [_root_.smul_apply, toSignedMeasure, toSignedMeasure, toSignedMeasure_sub_apply hi, toSignedMeasure_sub_apply hi, smul_sub, smul_posPart, smul_negPart, measureReal_nnreal_smul_apply, measureReal_nnreal_smul_apply] rfl @@ -177,7 +177,7 @@ theorem exists_compl_positive_negative : · refine restrict_le_restrict_of_subset_le _ _ fun A hA hA₁ => ?_ rw [toSignedMeasure, toSignedMeasure_sub_apply hA, measureReal_def, show j.posPart A = 0 from nonpos_iff_eq_zero.1 (hS₂ ▸ measure_mono hA₁), ENNReal.toReal_zero, - zero_sub, neg_le, VectorMeasure.zero_apply, neg_zero] + zero_sub, neg_le, zero_apply, neg_zero] exact ENNReal.toReal_nonneg · refine restrict_le_restrict_of_subset_le _ _ fun A hA hA₁ => ?_ rw [toSignedMeasure, toSignedMeasure_sub_apply hA, measureReal_def (μ := j.negPart), @@ -261,7 +261,7 @@ theorem subset_negative_null_set (hu : MeasurableSet u) (hv : MeasurableSet v) s v = 0 := by rw [← s.neg_le_neg_iff _ hu, neg_zero] at hsu have := subset_positive_null_set hu hv hw hsu - simp only [Pi.neg_apply, neg_eq_zero, coe_neg] at this + simp only [neg_apply, neg_eq_zero] at this exact this hw₁ hw₂ hwt open scoped symmDiff @@ -277,7 +277,7 @@ theorem of_sdiff_eq_zero_of_symmDiff_eq_zero_positive (hu : MeasurableSet u) (hv rw [Set.symmDiff_def, of_union (v := s) (Set.disjoint_of_subset_left sdiff_subset disjoint_sdiff_self_right) (hu.diff hv) (hv.diff hu)] at hs - rw [VectorMeasure.zero_apply] at a b + rw [zero_apply] at a b constructor · linarith · linarith @@ -294,7 +294,7 @@ theorem of_sdiff_eq_zero_of_symmDiff_eq_zero_negative (hu : MeasurableSet u) (hv rw [← s.neg_le_neg_iff _ hu, neg_zero] at hsu rw [← s.neg_le_neg_iff _ hv, neg_zero] at hsv have := of_sdiff_eq_zero_of_symmDiff_eq_zero_positive hu hv hsu hsv - simp only [Pi.neg_apply, neg_eq_zero, coe_neg] at this + simp only [neg_apply, neg_eq_zero] at this exact this hs @[deprecated (since := "2026-06-03")] @@ -322,7 +322,7 @@ theorem of_inter_eq_of_symmDiff_eq_zero_negative (hu : MeasurableSet u) (hv : Me rw [← s.neg_le_neg_iff _ hu, neg_zero] at hsu rw [← s.neg_le_neg_iff _ hv, neg_zero] at hsv have := of_inter_eq_of_symmDiff_eq_zero_positive hu hv hw hsu hsv - simp only [Pi.neg_apply, neg_inj, neg_eq_zero, coe_neg] at this + simp only [neg_apply, neg_inj, neg_eq_zero] at this exact this hs end @@ -469,11 +469,10 @@ theorem totalVariation_neg (s : SignedMeasure α) : (-s).totalVariation = s.tota theorem null_of_totalVariation_zero (s : SignedMeasure α) {i : Set α} (hs : s.totalVariation i = 0) : s i = 0 := by rw [totalVariation, Measure.coe_add, Pi.add_apply, add_eq_zero] at hs - rw [← toSignedMeasure_toJordanDecomposition s, toSignedMeasure, VectorMeasure.coe_sub, - Pi.sub_apply, Measure.toSignedMeasure_apply, Measure.toSignedMeasure_apply] by_cases hi : MeasurableSet i - · simp [hs.1, hs.2, measureReal_def] - · simp [if_neg hi] + · rw [← toSignedMeasure_toJordanDecomposition s, toSignedMeasure] + simp [hi, measureReal_def, hs.1, hs.2] + · simp [hi] theorem absolutelyContinuous_ennreal_iff (s : SignedMeasure α) (μ : VectorMeasure α ℝ≥0∞) : s ≪ᵥ μ ↔ s.totalVariation ≪ μ.ennrealToMeasure := by diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean index e86f35d52639ce..11c223168aeaf3 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean @@ -234,15 +234,15 @@ theorem toJordanDecomposition_eq_of_eq_add_withDensity {f : α → ℝ} (hf : Me refine toJordanDecomposition_eq ?_ simp_rw [JordanDecomposition.toSignedMeasure, hadd] ext i hi - rw [VectorMeasure.sub_apply, toSignedMeasure_apply_measurable hi, + rw [_root_.sub_apply, toSignedMeasure_apply_measurable hi, toSignedMeasure_apply_measurable hi, measureReal_add_apply, measureReal_add_apply, add_sub_add_comm, ← toSignedMeasure_apply_measurable hi, - ← toSignedMeasure_apply_measurable hi, ← VectorMeasure.sub_apply, + ← toSignedMeasure_apply_measurable hi, ← _root_.sub_apply, ← JordanDecomposition.toSignedMeasure, toSignedMeasure_toJordanDecomposition, - VectorMeasure.add_apply, ← toSignedMeasure_apply_measurable hi, + _root_.add_apply, ← toSignedMeasure_apply_measurable hi, ← toSignedMeasure_apply_measurable hi, withDensityᵥ_eq_withDensity_pos_part_sub_withDensity_neg_part hfi, - VectorMeasure.sub_apply] + _root_.sub_apply] private theorem haveLebesgueDecomposition_mk' (μ : Measure α) {f : α → ℝ} (hf : Measurable f) (hfi : Integrable f μ) (htμ : t ⟂ᵥ μ.toENNRealVectorMeasure) (hadd : s = t + μ.withDensityᵥ f) : @@ -441,7 +441,7 @@ theorem singularPart_add_withDensity_rnDeriv_eq [c.HaveLebesgueDecomposition μ] c.singularPart μ + μ.withDensityᵥ (c.rnDeriv μ) = c := by conv_rhs => rw [← c.toComplexMeasure_to_signedMeasure] ext i hi : 1 - rw [VectorMeasure.add_apply, SignedMeasure.toComplexMeasure_apply] + rw [add_apply, SignedMeasure.toComplexMeasure_apply] apply Complex.ext · rw [Complex.add_re, withDensityᵥ_apply (c.integrable_rnDeriv μ) hi, ← RCLike.re_eq_complex_re, ← integral_re (c.integrable_rnDeriv μ).integrableOn, RCLike.re_eq_complex_re, diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/RadonNikodym.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/RadonNikodym.lean index e000659ce34903..e61eedeb921bc4 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/RadonNikodym.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/RadonNikodym.lean @@ -34,7 +34,7 @@ theorem withDensityᵥ_rnDeriv_eq (s : SignedMeasure α) (μ : Measure α) [Sigm rw [withDensityᵥ_apply (integrable_rnDeriv _ _) hi, rnDeriv_def, integral_sub, setIntegral_toReal_rnDeriv h.1 i, setIntegral_toReal_rnDeriv h.2 i] · conv_rhs => rw [← s.toSignedMeasure_toJordanDecomposition] - rw [JordanDecomposition.toSignedMeasure, VectorMeasure.sub_apply, + rw [JordanDecomposition.toSignedMeasure, _root_.sub_apply, toSignedMeasure_apply_measurable hi, toSignedMeasure_apply_measurable hi, measureReal_def, measureReal_def] all_goals diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index 227c9783e8f9a8..9c96314769d4c9 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -479,7 +479,7 @@ lemma Integrable.restrict (hf : μ.Integrable f B) {s : Set X} : @[simp] theorem integral_zero_vectorMeasure : - ∫ᵛ x, f x ∂[B; (0 : VectorMeasure X F)] = 0 := by simp [integral] + ∫ᵛ x, f x ∂[B; (0 : VectorMeasure X F)] = 0 := by simp [integral, FunLike.coe_zero] lemma integral_of_isEmpty [IsEmpty X] : ∫ᵛ x, f x ∂[B; μ] = 0 := by simp [eq_zero_of_isEmpty] @@ -493,7 +493,7 @@ theorem integral_smul_vectorMeasure (f : X → E) (c : ℝ) : simp [transpose, mapRange_smul, variation_smul] simp only [this, mul_one] have : DominatedFinMeasAdditive (μ.transpose B).variation ((c • μ).transpose B) ‖c‖ := by - simp only [transpose_smul, coe_smul, Real.norm_eq_abs] + simp only [transpose_smul, FunLike.coe_smul, Real.norm_eq_abs] simpa using! (dominatedFinMeasAdditive_cbmApplyMeasure μ B).smul c rw! [← setToFun_congr_smul_measure' _ this, transpose_smul] rfl @@ -522,7 +522,7 @@ theorem integral_finsetSum_vectorMeasure {μ : ι → VectorMeasure X F} @[integral_simps] theorem integral_neg_vectorMeasure : ∫ᵛ x, f x ∂[B; -μ] = -∫ᵛ x, f x ∂[B; μ] := by - simp [integral, ← setToFun_neg'] + simp [integral, ← setToFun_neg', FunLike.coe_neg] theorem integral_sub_vectorMeasure (hμ : μ.Integrable f B) (hν : ν.Integrable f B) : ∫ᵛ x, f x ∂[B; μ - ν] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x, f x ∂[B; ν] := by @@ -568,7 +568,7 @@ variable (f μ) in @[simp] theorem integral_zero_cbm : ∫ᵛ x, f x ∂[(0 : E →L[ℝ] F →L[ℝ] G); μ] = 0 := by - simp [integral] + simp [integral, FunLike.coe_zero] theorem integral_add_cbm (hB : μ.Integrable f B) (hC : μ.Integrable f C) : ∫ᵛ x, f x ∂[B + C; μ] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, f x ∂[C; μ] := @@ -589,7 +589,7 @@ theorem integral_finsetSum_cbm {B : ι → E →L[ℝ] F →L[ℝ] G} @[integral_simps] theorem integral_neg_cbm : ∫ᵛ x, f x ∂[-B; μ] = -∫ᵛ x, f x ∂[B; μ] := by - simp [integral, ← setToFun_neg'] + simp [integral, ← setToFun_neg', FunLike.coe_neg] theorem integral_sub_cbm (hB : μ.Integrable f B) (hC : μ.Integrable f C) : ∫ᵛ x, f x ∂[B - C; μ] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x, f x ∂[C; μ] := by @@ -646,7 +646,7 @@ theorem exists_ne_zero_of_integral_ne_zero simp only [variation_transpose_lsmul_flip, variation_toSignedMeasure] apply setToFun_congr_left' _ _ (fun s hs h's ↦ ?_) simp only [transpose, ContinuousLinearMap.flip_flip, mapRange_apply, - Measure.toSignedMeasure_apply, hs, ↓reduceIte, LinearMap.toAddMonoidHom_coe, + Measure.toSignedMeasure_apply_measurable hs, LinearMap.toAddMonoidHom_coe, ContinuousLinearMap.coe_coe, weightedSMul] rfl diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean index 90022637bbd5a5..2c0ba7a93d9b1e 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean @@ -110,7 +110,7 @@ lemma exists_variation_le_add (μ : VectorMeasure X V) {s : Set X} (hs : Measura theorem enorm_measure_le_variation (μ : VectorMeasure X V) (E : Set X) : ‖μ E‖ₑ ≤ variation μ E := by by_cases hE : MeasurableSet E - swap; · simp [μ.not_measurable' hE] + swap; · simp [hE] by_cases hE' : (⟨E, hE⟩ : Subtype MeasurableSet) = ⊥ · simp_all simp only [variation_apply, preVariation, ennrealToMeasure_apply hE, ennrealPreVariation_apply] @@ -120,7 +120,7 @@ theorem enorm_measure_le_variation (μ : VectorMeasure X V) (E : Set X) : @[simp] lemma variation_zero : (0 : VectorMeasure X V).variation = 0 := by - simp only [variation, coe_zero, Pi.zero_apply, enorm_zero] + simp only [variation, zero_apply, enorm_zero] exact preVariation_zero lemma absolutelyContinuous (μ : VectorMeasure X V) : μ ≪ᵥ μ.ennrealVariation := by @@ -128,7 +128,7 @@ lemma absolutelyContinuous (μ : VectorMeasure X V) : μ ≪ᵥ μ.ennrealVariat by_cases hsm : MeasurableSet s · suffices ‖μ s‖ₑ ≤ 0 by simp_all grw [enorm_measure_le_variation, ← ennrealVariation_apply _ hsm, hs] - · exact μ.not_measurable' hsm + · exact μ.not_measurable hsm lemma variation_apply_le_of_forall_enorm_le {m : Measure X} (hs : MeasurableSet s) (h : ∀ E, MeasurableSet E → E ⊆ s → ‖μ E‖ₑ ≤ m E) : @@ -273,7 +273,7 @@ lemma variation_sub_le : (μ - ν).variation ≤ μ.variation + ν.variation := private lemma variation_smul_le {𝕜 : Type*} [NormedField 𝕜] [NormedSpace 𝕜 V] {c : 𝕜} : (c • μ).variation ≤ ‖c‖₊ • μ.variation := by apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) - simp only [coe_smul, Pi.smul_apply, enorm_smul, Measure.smul_apply, Measure.nnreal_smul_coe_apply] + simp only [smul_apply, enorm_smul, Measure.smul_apply, Measure.nnreal_smul_coe_apply] grw [enorm_measure_le_variation, enorm_eq_nnnorm] lemma variation_smul {𝕜 : Type*} [NormedField 𝕜] [NormedSpace 𝕜 V] {c : 𝕜} : @@ -310,10 +310,10 @@ instance {x : X} {v : V} : IsFiniteMeasure (VectorMeasure.dirac x v).variation : μ.toSignedMeasure.variation = μ := by apply le_antisymm · apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) - simp [Measure.toSignedMeasure_apply, hs, Measure.real, Real.enorm_eq_ofReal] + simp [hs, Measure.real, Real.enorm_eq_ofReal] · apply Measure.le_iff.2 (fun s hs ↦ ?_) apply le_trans ?_ (enorm_measure_le_variation _ _) - simp [Measure.toSignedMeasure_apply, hs, Measure.real, Real.enorm_eq_ofReal] + simp [hs, Measure.real, Real.enorm_eq_ofReal] end NormedAddCommGroup diff --git a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean index 595c05309b37e4..a6fa2b886b0531 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean @@ -70,7 +70,7 @@ theorem withDensityᵥ_zero : μ.withDensityᵥ (0 : α → E) = 0 := by theorem withDensityᵥ_neg : μ.withDensityᵥ (-f) = -μ.withDensityᵥ f := by by_cases hf : Integrable f μ · ext1 i hi - rw [VectorMeasure.neg_apply, withDensityᵥ_apply hf hi, ← integral_neg, + rw [_root_.neg_apply, withDensityᵥ_apply hf hi, ← integral_neg, withDensityᵥ_apply hf.neg hi] simp only [Pi.neg_apply] · rw [withDensityᵥ, withDensityᵥ, dif_neg hf, dif_neg, neg_zero] @@ -83,7 +83,7 @@ theorem withDensityᵥ_neg' : (μ.withDensityᵥ fun x => -f x) = -μ.withDensit theorem withDensityᵥ_add (hf : Integrable f μ) (hg : Integrable g μ) : μ.withDensityᵥ (f + g) = μ.withDensityᵥ f + μ.withDensityᵥ g := by ext1 i hi - rw [withDensityᵥ_apply (hf.add hg) hi, VectorMeasure.add_apply, withDensityᵥ_apply hf hi, + rw [withDensityᵥ_apply (hf.add hg) hi, _root_.add_apply, withDensityᵥ_apply hf hi, withDensityᵥ_apply hg hi] simp_rw [Pi.add_apply] rw [integral_add] @@ -108,7 +108,7 @@ theorem withDensityᵥ_smul {𝕜 : Type*} [NontriviallyNormedField 𝕜] [Norme [SMulCommClass ℝ 𝕜 E] (f : α → E) (r : 𝕜) : μ.withDensityᵥ (r • f) = r • μ.withDensityᵥ f := by by_cases hf : Integrable f μ · ext1 i hi - rw [withDensityᵥ_apply (hf.smul r) hi, VectorMeasure.smul_apply, withDensityᵥ_apply hf hi, ← + rw [withDensityᵥ_apply (hf.smul r) hi, _root_.smul_apply, withDensityᵥ_apply hf hi, ← integral_smul r f] simp only [Pi.smul_apply] · by_cases hr : r = 0 @@ -195,7 +195,7 @@ theorem withDensityᵥ_eq_withDensity_pos_part_sub_withDensity_neg_part {f : α ext i hi rw [withDensityᵥ_apply hfi hi, integral_eq_lintegral_pos_part_sub_lintegral_neg_part hfi.integrableOn, - VectorMeasure.sub_apply, toSignedMeasure_apply_measurable hi, + _root_.sub_apply, toSignedMeasure_apply_measurable hi, toSignedMeasure_apply_measurable hi, measureReal_def, measureReal_def, withDensity_apply _ hi, withDensity_apply _ hi] From 71a914d3d98f2e1720b90f38818c0b5687272e9a Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Tue, 16 Jun 2026 07:15:39 +0000 Subject: [PATCH 0054/1300] feat(LinearAlgebra/Matrix/GeneralLinear/Projective): add iso between psl and pgl when algebraically closed (#40605) This PR is split and generalised from [FLT#1020](https://github.com/ImperialCollegeLondon/FLT/pull/1020) --- .../Matrix/GeneralLinearGroup/Defs.lean | 8 ++ .../Matrix/GeneralLinearGroup/Projective.lean | 102 +++++++++++++++++- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean index 6f87c1ce89d19a..5572c3144c2f05 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean @@ -88,6 +88,14 @@ theorem det_scalar (u : Rˣ) : det (scalar n u) = u ^ Fintype.card n := by ext simp +lemma det_surjective [Nonempty n] : Function.Surjective (det : GL n R → Rˣ) := fun r ↦ by + obtain ⟨i⟩ := ‹Nonempty n› + refine ⟨⟨diagonal fun j ↦ if j = i then r else 1, diagonal fun j ↦ if j = i then r⁻¹.1 else 1, + ?_, ?_⟩, by simp [det]⟩ + <;> simp only [diagonal_mul_diagonal, mul_ite, ite_mul, Units.mul_inv, one_mul, mul_one, + diagonal_eq_one] + <;> funext j <;> split_ifs <;> simp + /-- The groups `GL n R` (notation for `Matrix.GeneralLinearGroup n R`) and `LinearMap.GeneralLinearGroup R (n → R)` are multiplicatively equivalent -/ def toLin : GL n R ≃* LinearMap.GeneralLinearGroup R (n → R) := diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean index 5127ad2bb5304d..e71b01a2ac3414 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean @@ -5,9 +5,10 @@ Authors: Yury G. Kudryashov -/ module -public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Defs public import Mathlib.Data.Sign.Basic -import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Basic +public import Mathlib.FieldTheory.IsAlgClosed.Basic +public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Basic +public import Mathlib.LinearAlgebra.Matrix.ProjectiveSpecialLinearGroup /-! # Projective general linear group @@ -40,11 +41,19 @@ namespace ProjGenLinGroup variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] /-- The natural projection from `GL n R` to `PGL n R`. -/ -def mk : GL n R →* PGL(n, R) := QuotientGroup.mk' _ +def mk : GL n R →* PGL(n, R) := QuotientGroup.mk' (Subgroup.center (GL n R)) theorem mk_surjective : Function.Surjective (mk : GL n R → PGL(n, R)) := Quotient.mk_surjective +lemma mk_eq_mk_iff' {g₁ g₂ : GL n R} : + mk g₁ = mk g₂ ↔ ∃ z ∈ Subgroup.center (GL n R), g₁ * z = g₂ := + QuotientGroup.mk'_eq_mk' (Subgroup.center (GL n R)) + +lemma mk_eq_mk_iff {g₁ g₂ : GL n R} : + mk g₁ = mk g₂ ↔ ∃ u : Rˣ, g₁ * .scalar n u = g₂ := by + simp [mk_eq_mk_iff', Matrix.GeneralLinearGroup.center_eq_range_scalar] + @[simp] theorem ker_mk : mk.ker = Subgroup.center (GL n R) := QuotientGroup.ker_mk' _ @@ -62,6 +71,93 @@ theorem induction_on {motive : PGL(n, R) → Prop} (g : PGL(n, R)) (mk : ∀ g : GL n R, motive (ProjGenLinGroup.mk g)) : motive g := Quotient.inductionOn g mk +section isoPSL + +open Matrix.SpecialLinearGroup + +/-- The natural inclusion map from `PSL(n, R)` to `PGL(n, R)` induced by the inclusion + map from `SL(n, R)` to `GL(n, R)`. -/ +@[expose] +def _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL : + ProjectiveSpecialLinearGroup n R →* PGL(n, R) := + QuotientGroup.lift _ (mk.comp toGL) fun x hx ↦ by + simp only [mem_center_iff, scalar_apply, MonoidHom.mem_ker, MonoidHom.coe_comp, + Function.comp_apply, mk_eq_one, GeneralLinearGroup.mem_center_iff_val_mem_range_scalar, + coe_GL_coe_matrix, Set.mem_range] at hx ⊢ + exact ⟨hx.choose, hx.choose_spec.2⟩ + +@[simp] +lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_mk (g : SpecialLinearGroup n R) : + ProjectiveSpecialLinearGroup.toPGL g = mk (toGL g) := rfl + +lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_injective : + Function.Injective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun x y h ↦ by + induction x using QuotientGroup.induction_on with | H x => + induction y using QuotientGroup.induction_on with | H y => + simp only [ProjectiveSpecialLinearGroup.toPGL_mk, mk_eq_mk_iff] at h + rw [← QuotientGroup.mk'_apply, ← QuotientGroup.mk'_apply] + simp only [QuotientGroup.mk'_eq_mk', mem_center_iff] + obtain ⟨u, hu'⟩ := h + have hu : u.1 ^ Fintype.card n = 1 := by + simpa [Units.ext_iff] using congr(Matrix.GeneralLinearGroup.det $hu') + set z : SpecialLinearGroup n R := ⟨scalar n u.1, by simpa using hu⟩ with hz_eq + have hz : (GeneralLinearGroup.scalar n) u = toGL z := by ext; simp [hz_eq] + refine ⟨z, ⟨u.1, hu, by simp [hz_eq]⟩, ?_⟩ + rwa [hz, ← map_mul, toGL_inj] at hu' + +lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_of_roots + (hR : ∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r) : + Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun g ↦ by + induction g using Matrix.ProjGenLinGroup.induction_on with | mk g => + obtain ⟨r, hr⟩ : ∃ r : Rˣ, r ^ Fintype.card n * g.det = 1 := by + obtain ⟨r, hr⟩ := hR g.det⁻¹ + exact ⟨r, by simpa [mul_eq_one_iff_eq_inv] using hr⟩ + simp only [Units.ext_iff, Units.val_mul, Units.val_pow_eq_pow_val, + GeneralLinearGroup.val_det_apply, ← Matrix.det_smul g.1 r.1, Units.val_one] at hr + use QuotientGroup.mk ⟨r.1 • g.1, hr⟩ + simp only [ProjectiveSpecialLinearGroup.toPGL_mk, mk_eq_mk_iff] + refine ⟨r⁻¹, Units.ext ?_⟩ + simp only [Units.val_mul, coe_GL_coe_matrix,GeneralLinearGroup.val_scalar_apply] + simp [← Matrix.mul_smul, ← Matrix.diagonal_smul, Pi.smul_def, smul_eq_mul] + +lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_iff [Nonempty n] : + Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) ↔ + ∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r := by + refine ⟨fun h r ↦ ?_, ProjectiveSpecialLinearGroup.toPGL_surj_of_roots⟩ + obtain ⟨A, hA⟩ := GeneralLinearGroup.det_surjective (n := n) r + obtain ⟨X, hX⟩ := h (.mk A) + induction X using QuotientGroup.induction_on with | H X => + obtain ⟨u, hu⟩ : ∃ u, toGL X * (GeneralLinearGroup.scalar n) u = A := by + simpa [mk_eq_mk_iff] using hX + exact ⟨u, by simpa [hA] using congr(Matrix.GeneralLinearGroup.det $hu)⟩ + +open Polynomial in +/-- An isomorphism between `PGL(n, F)` and `PSL(n, F)` in the case of an algebraically closed field + induced from the natural inclusion map. -/ +noncomputable def isoPSLOfAlgClosedOfNonempty [Nonempty n] {F : Type*} [Field F] [IsAlgClosed F] : + PGL(n, F) ≃* ProjectiveSpecialLinearGroup n F := + MulEquiv.symm (MulEquiv.ofBijective Matrix.ProjectiveSpecialLinearGroup.toPGL + ⟨Matrix.ProjectiveSpecialLinearGroup.toPGL_injective, + Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_of_roots fun r => by + obtain ⟨x, hx⟩ := IsAlgClosed.exists_root (X ^ Fintype.card n - C r.1 : F[X]) (by + simp [Polynomial.degree_X_pow_sub_C Fintype.card_pos]) + have hx' : x ≠ 0 := by aesop + exact ⟨⟨x, x⁻¹, mul_inv_cancel₀ hx', inv_mul_cancel₀ hx'⟩, by + simpa [Units.ext_iff, sub_eq_zero] using hx⟩⟩) + +/-- An isomorphism between `PGL(n, F)` and `PSL(n, F)` in the case of an algebraically closed field + induced from the natural inclusion map where when `n` is empty it gives a junk isomorphism. -/ +noncomputable def isoPSLOfAlgClosed {F : Type*} [Field F] [IsAlgClosed F] : + PGL(n, F) ≃* ProjectiveSpecialLinearGroup n F := + open scoped Classical in + if h : Nonempty n then isoPSLOfAlgClosedOfNonempty else + have : IsEmpty n := by simpa using h + have : Subsingleton (PGL(n, F)) := mk_surjective.subsingleton + MulEquiv.symm (MulEquiv.ofBijective Matrix.ProjectiveSpecialLinearGroup.toPGL + ⟨Matrix.ProjectiveSpecialLinearGroup.toPGL_injective, Function.surjective_to_subsingleton _⟩) + +end isoPSL + variable {M : Type*} [Monoid M] /-- Lift a monoid homomorphism `f : GL n R →* M` that vanishes on all scalar matrices From cbeca4d743ba17b79fd585e31f4cd035b555da98 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Tue, 16 Jun 2026 07:39:23 +0000 Subject: [PATCH 0055/1300] doc: adjust references to ring quotients (#40640) The previous references weren't linked. Linking to `RingCon` rather than `RingQuot` is arguably the better choice, since the former references the latter but not vice versa. In the longer term I'd like to drop `RingQuot` entirely. --- Mathlib/RingTheory/Ideal/Quotient/Basic.lean | 2 +- Mathlib/RingTheory/Ideal/Quotient/Defs.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean index 6d3fa90bb8b0d5..ab3b8fc6869fd3 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean @@ -18,7 +18,7 @@ public import Mathlib.Tactic.FinCases This file defines ideal quotients as a special case of submodule quotients and proves some basic results about these quotients. -See `Algebra.RingQuot` for quotients of semirings. +See `RingCon.Quotient` for quotients of (possibly non-commutative) semirings. ## Main definitions diff --git a/Mathlib/RingTheory/Ideal/Quotient/Defs.lean b/Mathlib/RingTheory/Ideal/Quotient/Defs.lean index 8a05330c3e763b..352e9b336639a9 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Defs.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Defs.lean @@ -15,7 +15,7 @@ public import Mathlib.RingTheory.Ideal.Defs This file defines ideal quotients as a special case of submodule quotients and proves some basic results about these quotients. -See `Algebra.RingQuot` for quotients of non-commutative rings. +See `RingCon.Quotient` for quotients of (possibly non-commutative) semirings. ## Main definitions From c1f268b3370e727834bc31ca014d3c212eb91b42 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 08:48:36 +0000 Subject: [PATCH 0056/1300] chore: update Mathlib dependencies 2026-06-16 (#40659) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 1db86ab034fd85..aff8d1dac87c1c 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "fa08db58b30eb033edcdab331bba000827f9f785", + "rev": "fc38104235ab6cf8a448a74405aa258804ef4e36", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 45042665a65650329c9d2db223405af67c227d77 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:46:34 +0000 Subject: [PATCH 0057/1300] feat(Data/Sym/Sym2): `fromRel` equivalence with `Sigma` over a `Quotient` (#34909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a non-dependent recursor on members of a `fromRel` set, and the following `Equiv`s: - The `fromRel` set of a symmetric relation `r` is equivalent to summing that set restricted to fibers of `f`. - For a relation homomorphism `r →r r'` where `r` is symmetric, the `fromRel` set of `r` is equivalent to summing that set restricted to equivalence classes of `r'` using a `Subtype`. --- .../Combinatorics/SimpleGraph/Bipartite.lean | 6 +-- Mathlib/Data/Sym/Sym2.lean | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean b/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean index 04a8ab8e959625..db6aebddef53e0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean @@ -487,13 +487,13 @@ theorem encard_edgeSet_completeBipartiteGraph : def IsBipartiteWith.edgeSetEmbeddingCompleteBipartiteGraph [DecidableRel (· ∈ · : V → Set V → _)] (hG : G.IsBipartiteWith s t) : G.edgeSet ↪ (completeBipartiteGraph s t).edgeSet where toFun := fun ⟨e, he⟩ ↦ - e.hrec (fun u v h ↦ hG.mem_of_adj h |>.by_cases + e.fromRelNdrec he (sym := G.symm) (fun u v h ↦ hG.mem_of_adj h |>.by_cases (fun h ↦ ⟨s(.inl ⟨u, h.left⟩, .inr ⟨v, h.right⟩), .inl ⟨rfl, rfl⟩⟩) (fun h ↦ ⟨s(.inl ⟨v, h.right⟩, .inr ⟨u, h.left⟩), .inl ⟨rfl, rfl⟩⟩) - ) (fun _ _ ↦ Function.hfunext (by grind) <| by grind [Or.by_cases, hG.disjoint]) he + ) <| by grind [Or.by_cases, hG.disjoint] inj' := by rintro ⟨⟨⟩⟩ ⟨⟨⟩⟩ - change (if _ : _ then _ else _) = (if _ : _ then _ else _) → _ + change (dite ..) = (dite ..) → _ grind end completeBipartiteGraph diff --git a/Mathlib/Data/Sym/Sym2.lean b/Mathlib/Data/Sym/Sym2.lean index 77435725873bc5..a70c5c2b5cff24 100644 --- a/Mathlib/Data/Sym/Sym2.lean +++ b/Mathlib/Data/Sym/Sym2.lean @@ -606,6 +606,11 @@ theorem fromRel_mono_iff (sym₁ : Std.Symm r₁) (sym₂ : Std.Symm r₂) : @[gcongr] alias ⟨_, fromRel_mono⟩ := fromRel_mono_iff +theorem mem_fromRel_comap {r : β → β → Prop} (sym : Std.Symm r) (f : α → β) (z : Sym2 α) : + z ∈ fromRel (sym.comap f) ↔ z.map f ∈ fromRel sym := by + cases z + simp + theorem fromRel_bot : fromRel (α := α) (r := ⊥) inferInstance = ∅ := Set.eq_empty_of_forall_notMem <| Sym2.ind <| by simp @@ -672,6 +677,52 @@ lemma fromRel_relationMap {r : α → α → Prop} (hr : Std.Symm r) (f : α → forall_exists_index, and_imp] exact fun c d hcd hc hd ↦ ⟨d, c, symm hcd, hd, hc⟩ +/-- Non-dependent recursor on members of a `fromRel` set -/ +def fromRelNdrec {motive : Sort*} {sym : Std.Symm r} (z : Sym2 α) (hz : z ∈ fromRel sym) + (f : (a b : α) → r a b → motive) (h : ∀ (a b : α) (h : r a b), f a b h = f b a (symm h)) : + motive := + z.hrec f (fun _ _ ↦ Function.hfunext (sym.iff .. |>.eq) fun _ _ _ ↦ heq_of_eq <| h ..) hz + +@[simp] +theorem fromRelNdrec_mk {motive : Sort*} {sym : Std.Symm r} {a b : α} (hz : r a b) + (f : (a b : α) → r a b → motive) (h : ∀ (a b : α) (h : r a b), f a b h = f b a (symm h)) : + fromRelNdrec (sym := sym) s(a, b) hz f h = f a b hz := + rfl + +/-- The `fromRel` set of a symmetric relation `r` is equivalent to summing that set restricted to +fibers of a function `f`, given that `f` agrees on elements related by `r`. -/ +@[simps] +def _root_.Equiv.sigmaFiberFromRel (sym : Std.Symm r) {f : α → β} (hf : r ≤ Setoid.ker f) : + fromRel sym ≃ Σ b : β, fromRel (α := { a // f a = b }) <| sym.comap (↑) where + toFun z := z.val.fromRelNdrec z.prop + (fun a₁ a₂ h ↦ ⟨f a₁, s(⟨a₁, rfl⟩, ⟨a₂, hf a₁ a₂ h |>.symm⟩), h⟩) + fun a₁ a₂ h ↦ by + rw! [hf a₁ a₂ h, eq_swap] + rfl + invFun z := ⟨z.snd.val.map (↑), mem_fromRel_comap sym .. |>.mp z.snd.prop⟩ + left_inv z := by + rcases z with ⟨⟨a₁, a₂⟩, h⟩ + rfl + right_inv z := by + rcases z with ⟨b, ⟨⟨a₁, rfl⟩, ⟨a₂, ha₂⟩⟩, h⟩ + rfl + +/-- For a relation homomorphism `r →r r'` where `r` is symmetric, the `fromRel` set of `r` is +equivalent to summing that set restricted to equivalence classes of `r'` using a `Subtype`, +`Quot` version -/ +@[simps!] +def _root_.Equiv.sigmaQuotFromRel (sym : Std.Symm r) {r' : β → β → Prop} (f : r →r r') : + fromRel sym ≃ Σ q : Quot r', fromRel (α := { x // .mk r' (f x) = q }) <| sym.comap (↑) := + .sigmaFiberFromRel sym fun _ _ h ↦ Quot.sound <| f.map_rel h + +/-- For a relation homomorphism `r →r r'` where `r` is symmetric, the `fromRel` set of `r` is +equivalent to summing that set restricted to equivalence classes of `r'` using a `Subtype`, +`Quotient` version -/ +@[simps!] +def _root_.Equiv.sigmaQuotientFromRel (sym : Std.Symm r) {r' : Setoid β} (f : r →r r') : + fromRel sym ≃ Σ q : Quotient r', fromRel (α := { x // ⟦f x⟧ = q }) <| sym.comap (↑) := + .sigmaFiberFromRel sym fun _ _ h ↦ Quotient.sound <| f.map_rel h + /-- The inverse to `Sym2.fromRel`. Given a set on `Sym2 α`, give a symmetric relation on `α` (see `Sym2.toRel_symm`). -/ def ToRel (s : Set (Sym2 α)) (x y : α) : Prop := From f469a458bcdb9e2d5d58594871deb33644477e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 16 Jun 2026 09:46:37 +0000 Subject: [PATCH 0058/1300] chore(Algebra): use `Even.pow_of_ne_zero` (#40456) Also use `Even.pow_of_ne_zero` wherever possible. From APAP --- Mathlib/NumberTheory/Fermat.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index 088c6444ea0f2f..c5b50d9a5d15ab 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -51,7 +51,7 @@ lemma two_lt_fermatNumber (n : ℕ) : 2 < fermatNumber n := three_le_fermatNumbe lemma fermatNumber_ne_one (n : ℕ) : fermatNumber n ≠ 1 := by have := three_le_fermatNumber n; lia theorem odd_fermatNumber (n : ℕ) : Odd (fermatNumber n) := - (even_pow.mpr ⟨even_two, (pow_pos two_pos n).ne'⟩).add_one + (even_two.pow_of_ne_zero (pow_pos two_pos n).ne').add_one theorem prod_fermatNumber (n : ℕ) : ∏ k ∈ range n, fermatNumber k = fermatNumber n - 2 := by induction n with | zero => rfl | succ n hn => @@ -175,7 +175,7 @@ lemma fermat_primeFactors_one_lt (n p : ℕ) (hn : 1 < n) (hp : p.Prime) ∃ k, p = k * 2 ^ (n + 2) + 1 := by have : Fact p.Prime := Fact.mk hp have hp2 : p ≠ 2 := by - exact ((even_pow.mpr ⟨even_two, pow_ne_zero n two_ne_zero⟩).add_one).ne_two_of_dvd_nat hpdvd + exact (even_two.pow_of_ne_zero <| pow_ne_zero n two_ne_zero).add_one.ne_two_of_dvd_nat hpdvd have hp8 : p % 8 = 1 := by obtain ⟨k, rfl⟩ := pow_pow_add_primeFactors_one_lt hp hp2 hpdvd obtain ⟨n, rfl⟩ := Nat.exists_eq_add_of_le' hn From d292472f13fc10eb063e6efd93601f976a387055 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 16 Jun 2026 09:46:39 +0000 Subject: [PATCH 0059/1300] feat: expand API for `StarAlgEquiv` (#40517) This PR adds API for `StarAlgEquiv`. It provides: + `StarAlgEquiv.toNonUnitalStarAlgHom` + `StarAlgEquiv.toStarAlgHom` + `StarAlgEquiv.arrowCongr'` (non-unital morphisms) + `StarAlgEquiv.arrowCongr` (unital morphisms) + `StarAlgEquiv.ofNonUnitalStarAlgHom` (non-unital morphisms) + `StarAlgEquiv.ofStarAlgHom` (unital morphisms); this was pre-existing, but used morphism classes instead of actual morphisms. This PR fixes that. It also generalizes the type class hypothesis in `StarAlgEquiv.restrictScalars` so that it applies to non-unital algebras. In addition, `StarAlgEquiv.refl` is protected and its type arguments made explicit. --- Mathlib/Algebra/Star/StarAlgHom.lean | 210 ++++++++++++++++-- Mathlib/Algebra/Star/Subalgebra.lean | 40 +++- .../Analysis/InnerProductSpace/Adjoint.lean | 2 +- 3 files changed, 223 insertions(+), 29 deletions(-) diff --git a/Mathlib/Algebra/Star/StarAlgHom.lean b/Mathlib/Algebra/Star/StarAlgHom.lean index 4d83cb05d2e607..badc8dfcf88451 100644 --- a/Mathlib/Algebra/Star/StarAlgHom.lean +++ b/Mathlib/Algebra/Star/StarAlgHom.lean @@ -723,17 +723,18 @@ theorem toRingEquiv_eq_coe (e : A ≃⋆ₐ[R] B) : e.toRingEquiv = e := theorem ext {f g : A ≃⋆ₐ[R] B} (h : ∀ a, f a = g a) : f = g := DFunLike.ext f g h +variable (R A) in /-- The identity map is a star algebra isomorphism. -/ @[refl] -def refl : A ≃⋆ₐ[R] A := +protected def refl : A ≃⋆ₐ[R] A := { StarRingEquiv.refl (A := A) with map_smul' := fun _ _ => rfl } instance : Inhabited (A ≃⋆ₐ[R] A) := - ⟨refl⟩ + ⟨.refl R A⟩ @[simp] -theorem coe_refl : ⇑(refl : A ≃⋆ₐ[R] A) = id := +theorem coe_refl : ⇑(StarAlgEquiv.refl R A) = id := rfl /-- The inverse of a star algebra isomorphism is a star algebra isomorphism. -/ @@ -775,7 +776,7 @@ theorem symm_mk (e : A ≃⋆+* B) (h₁) : dsimp% rfl @[simp] -theorem refl_symm : (StarAlgEquiv.refl : A ≃⋆ₐ[R] A).symm = StarAlgEquiv.refl := +theorem refl_symm : (StarAlgEquiv.refl R A).symm = .refl R A := rfl @[simp] @@ -845,7 +846,7 @@ theorem toAlgEquiv_injective : Function.Injective (toAlgEquiv (R := R) (A := A) fun _ _ h => ext <| AlgEquiv.congr_fun h @[simp] -theorem toAlgEquiv_refl : (refl : A ≃⋆ₐ[R] A).toAlgEquiv = AlgEquiv.refl := rfl +theorem toAlgEquiv_refl : (StarAlgEquiv.refl R A).toAlgEquiv = AlgEquiv.refl := rfl /-- Upgrade an algebra equivalence to a ⋆-algebra equivalence given that it preserves the `star` operation. -/ @@ -876,6 +877,190 @@ end AlgEquiv end Basic +section NonUnitalArrowCongr + +variable {R A₁ A₂ A₃ A₁' A₂' A₃' : Type*} [Monoid R] + [NonUnitalNonAssocSemiring A₁] [DistribMulAction R A₁] [Star A₁] + [NonUnitalNonAssocSemiring A₂] [DistribMulAction R A₂] [Star A₂] + [NonUnitalNonAssocSemiring A₃] [DistribMulAction R A₃] [Star A₃] + [NonUnitalNonAssocSemiring A₁'] [DistribMulAction R A₁'] [Star A₁'] + [NonUnitalNonAssocSemiring A₂'] [DistribMulAction R A₂'] [Star A₂'] + [NonUnitalNonAssocSemiring A₃'] [DistribMulAction R A₃'] [Star A₃'] + (e : A₁ ≃⋆ₐ[R] A₂) + +/-- Reintrepret a star algebra equivalence as a non-unital star algebra homomorphism. -/ +@[simps] +def toNonUnitalStarAlgHom : A₁ →⋆ₙₐ[R] A₂ := + { e with + toFun := e + map_zero' := map_zero e } + +@[simp] +lemma toNonUnitalStarAlgHom_refl : (StarAlgEquiv.refl R A₁).toNonUnitalStarAlgHom = .id R A₁ := + rfl + +@[simp] +lemma toNonUnitalStarAlgHom_comp (e₁ : A₁ ≃⋆ₐ[R] A₂) (e₂ : A₂ ≃⋆ₐ[R] A₃) : + e₂.toNonUnitalStarAlgHom.comp e₁.toNonUnitalStarAlgHom = + (e₁.trans e₂).toNonUnitalStarAlgHom := rfl + +/-- If `A₁` is equivalent to `A₁'` and `A₂` is equivalent to `A₂'` as star algebras, then the type +of maps `A₁ →⋆ₙₐ[R] A₂` is equivalent to the type of maps `A₁' →⋆ₙₐ[R] A₂'`. + +For unital star algebra homomorphisms, see `StarAlgEquiv.arrowCongr`. -/ +@[simps apply] +def arrowCongr' (e₁ : A₁ ≃⋆ₐ[R] A₁') (e₂ : A₂ ≃⋆ₐ[R] A₂') : + (A₁ →⋆ₙₐ[R] A₂) ≃ (A₁' →⋆ₙₐ[R] A₂') where + toFun f := (e₂.toNonUnitalStarAlgHom.comp f).comp e₁.symm.toNonUnitalStarAlgHom + invFun f := (e₂.symm.toNonUnitalStarAlgHom.comp f).comp e₁.toNonUnitalStarAlgHom + left_inv f := by ext; simp + right_inv f := by ext; simp + +theorem arrowCongr'_comp (e₁ : A₁ ≃⋆ₐ[R] A₁') (e₂ : A₂ ≃⋆ₐ[R] A₂') + (e₃ : A₃ ≃⋆ₐ[R] A₃') (f : A₁ →⋆ₙₐ[R] A₂) (g : A₂ →⋆ₙₐ[R] A₃) : + arrowCongr' e₁ e₃ (g.comp f) = (arrowCongr' e₂ e₃ g).comp (arrowCongr' e₁ e₂ f) := by + ext + simp + +@[simp] +theorem arrowCongr'_refl : arrowCongr' (.refl _ _) (.refl _ _) = Equiv.refl (A₁ →⋆ₙₐ[R] A₂) := + rfl + +@[simp] +theorem arrowCongr'_trans (e₁ : A₁ ≃⋆ₐ[R] A₂) (e₁' : A₁' ≃⋆ₐ[R] A₂') + (e₂ : A₂ ≃⋆ₐ[R] A₃) (e₂' : A₂' ≃⋆ₐ[R] A₃') : + arrowCongr' (e₁.trans e₂) (e₁'.trans e₂') = (arrowCongr' e₁ e₁').trans (arrowCongr' e₂ e₂') := + rfl + +@[simp] +theorem symm_arrowCongr' (e₁ : A₁ ≃⋆ₐ[R] A₁') (e₂ : A₂ ≃⋆ₐ[R] A₂') : + (arrowCongr' e₁ e₂).symm = arrowCongr' e₁.symm e₂.symm := + rfl + +/-- Construct a star algebra equivalence from a pair of non-unital star algebra homomorphisms. -/ +@[simps] +def ofNonUnitalStarAlgHom (f : A₁ →⋆ₙₐ[R] A₂) (g : A₂ →⋆ₙₐ[R] A₁) (h₁ : g.comp f = .id R A₁) + (h₂ : f.comp g = .id R A₂) : A₁ ≃⋆ₐ[R] A₂ := + { f with + toFun := f + invFun := g + left_inv x := congr($h₁ x) + right_inv x := congr($h₂ x) } + +@[simp] +lemma toNonUnitalStarAlgHom_ofNonUnitalStarAlgHom (f : A₁ →⋆ₙₐ[R] A₂) (g : A₂ →⋆ₙₐ[R] A₁) + (h₁ : g.comp f = .id R A₁) (h₂ : f.comp g = .id R A₂) : + (ofNonUnitalStarAlgHom f g h₁ h₂).toNonUnitalStarAlgHom = f := + rfl + +lemma symm_ofNonUnitalStarAlgHom (f : A₁ →⋆ₙₐ[R] A₂) (g : A₂ →⋆ₙₐ[R] A₁) + (h₁ : g.comp f = .id R A₁) (h₂ : f.comp g = .id R A₂) : + (ofNonUnitalStarAlgHom f g h₁ h₂).symm = ofNonUnitalStarAlgHom g f h₂ h₁ := + rfl + +@[simp] +lemma toNonUnitalStarAlgHom_symm_ofNonUnitalStarAlgHom (f : A₁ →⋆ₙₐ[R] A₂) (g : A₂ →⋆ₙₐ[R] A₁) + (h₁ : g.comp f = .id R A₁) (h₂ : f.comp g = .id R A₂) : + (ofNonUnitalStarAlgHom f g h₁ h₂).symm.toNonUnitalStarAlgHom = g := + rfl + +end NonUnitalArrowCongr + +section Unital + +variable {R A₁ A₂ A₃ A₁' A₂' A₃' : Type*} + [CommSemiring R] [Semiring A₁] [Semiring A₂] [Semiring A₃] + [Semiring A₁'] [Semiring A₂'] [Semiring A₃'] + [Algebra R A₁] [Algebra R A₂] [Algebra R A₃] + [Algebra R A₁'] [Algebra R A₂'] [Algebra R A₃'] + [Star A₁] [Star A₂] [Star A₃] + [Star A₁'] [Star A₂'] [Star A₃'] + (e : A₁ ≃⋆ₐ[R] A₂) + +/-- Reintrepret a star algebra equivalence as a star algebra homomorphism. -/ +@[simps] +def toStarAlgHom : A₁ →⋆ₐ[R] A₂ := + { e with + toFun := e + __ := e.toAlgEquiv.toAlgHom } + +@[simp] +lemma toNonUnitalStarAlgHom_toStarAlgHom (e : A₁ ≃⋆ₐ[R] A₂) : + e.toStarAlgHom.toNonUnitalStarAlgHom = e.toNonUnitalStarAlgHom := + rfl + +@[simp] +lemma toStarAlgHom_refl : (StarAlgEquiv.refl R A₁).toStarAlgHom = .id R A₁ := + rfl + +@[simp] +lemma toStarAlgHom_comp (e₁ : A₁ ≃⋆ₐ[R] A₂) (e₂ : A₂ ≃⋆ₐ[R] A₃) : + e₂.toStarAlgHom.comp e₁.toStarAlgHom = (e₁.trans e₂).toStarAlgHom := rfl + +/-- If `A₁` is equivalent to `A₁'` and `A₂` is equivalent to `A₂'` as star algebras, then the type +of maps `A₁ →⋆ₐ[R] A₂` is equivalent to the type of maps `A₁' →⋆ₐ[R] A₂'`. + +For non-unital star algebra homomorphisms, see `StarAlgEquiv.arrowCongr'`. -/ +@[simps apply] +def arrowCongr (e₁ : A₁ ≃⋆ₐ[R] A₁') (e₂ : A₂ ≃⋆ₐ[R] A₂') : (A₁ →⋆ₐ[R] A₂) ≃ (A₁' →⋆ₐ[R] A₂') where + toFun f := (e₂.toStarAlgHom.comp f).comp e₁.symm.toStarAlgHom + invFun f := (e₂.symm.toStarAlgHom.comp f).comp e₁.toStarAlgHom + left_inv f := by ext; simp + right_inv f := by ext; simp + +theorem arrowCongr_comp (e₁ : A₁ ≃⋆ₐ[R] A₁') (e₂ : A₂ ≃⋆ₐ[R] A₂') + (e₃ : A₃ ≃⋆ₐ[R] A₃') (f : A₁ →⋆ₐ[R] A₂) (g : A₂ →⋆ₐ[R] A₃) : + arrowCongr e₁ e₃ (g.comp f) = (arrowCongr e₂ e₃ g).comp (arrowCongr e₁ e₂ f) := by + ext + simp + +@[simp] +theorem arrowCongr_refl : arrowCongr (.refl _ _) (.refl _ _) = Equiv.refl (A₁ →⋆ₐ[R] A₂) := + rfl + +@[simp] +theorem arrowCongr_trans (e₁ : A₁ ≃⋆ₐ[R] A₂) (e₁' : A₁' ≃⋆ₐ[R] A₂') + (e₂ : A₂ ≃⋆ₐ[R] A₃) (e₂' : A₂' ≃⋆ₐ[R] A₃') : + arrowCongr (e₁.trans e₂) (e₁'.trans e₂') = (arrowCongr e₁ e₁').trans (arrowCongr e₂ e₂') := + rfl + +@[simp] +theorem symm_arrowCongr (e₁ : A₁ ≃⋆ₐ[R] A₁') (e₂ : A₂ ≃⋆ₐ[R] A₂') : + (arrowCongr e₁ e₂).symm = arrowCongr e₁.symm e₂.symm := + rfl + +/-- Construct a star algebra equivalence from a pair of star algebra homomorphisms. -/ +@[simps] +def ofStarAlgHom {R A B : Type*} [CommSemiring R] + [Semiring A] [Algebra R A] [Star A] [Semiring B] [Algebra R B] [Star B] + (f : A →⋆ₐ[R] B) (g : B →⋆ₐ[R] A) (h₁ : g.comp f = .id R A) (h₂ : f.comp g = .id R B) : + A ≃⋆ₐ[R] B := + { f with + toFun := f + invFun := g + left_inv x := congr($h₁ x) + right_inv x := congr($h₂ x) + map_smul' := map_smul f } + +@[simp] +lemma toStarAlgHom_ofStarAlgHom (f : A₁ →⋆ₐ[R] A₂) (g : A₂ →⋆ₐ[R] A₁) + (h₁ : g.comp f = .id R A₁) (h₂ : f.comp g = .id R A₂) : + (ofStarAlgHom f g h₁ h₂).toStarAlgHom = f := + rfl + +lemma symm_ofStarAlgHom (f : A₁ →⋆ₐ[R] A₂) (g : A₂ →⋆ₐ[R] A₁) + (h₁ : g.comp f = .id R A₁) (h₂ : f.comp g = .id R A₂) : + (ofStarAlgHom f g h₁ h₂).symm = ofStarAlgHom g f h₂ h₁ := + rfl + +@[simp] +lemma toStarAlgHom_symm_ofStarAlgHom (f : A₁ →⋆ₐ[R] A₂) (g : A₂ →⋆ₐ[R] A₁) + (h₁ : g.comp f = .id R A₁) (h₂ : f.comp g = .id R A₂) : + (ofStarAlgHom f g h₁ h₂).symm.toStarAlgHom = g := + rfl + +end Unital + section Bijective variable {F G R A B : Type*} [Monoid R] @@ -884,19 +1069,6 @@ variable [NonUnitalNonAssocSemiring B] [DistribMulAction R B] [Star B] variable [FunLike F A B] [NonUnitalAlgHomClass F R A B] [StarHomClass F A B] variable [FunLike G B A] [NonUnitalAlgHomClass G R B A] [StarHomClass G B A] -/-- If a (unital or non-unital) star algebra morphism has an inverse, it is an isomorphism of -star algebras. -/ -@[simps] -def ofStarAlgHom (f : F) (g : G) (h₁ : ∀ x, g (f x) = x) (h₂ : ∀ x, f (g x) = x) : A ≃⋆ₐ[R] B where - toFun := f - invFun := g - left_inv := h₁ - right_inv := h₂ - map_add' := map_add f - map_mul' := map_mul f - map_smul' := map_smul f - map_star' := map_star f - /-- Promote a bijective star algebra homomorphism to a star algebra equivalence. -/ noncomputable def ofBijective (f : F) (hf : Function.Bijective f) : A ≃⋆ₐ[R] B := { @@ -922,7 +1094,7 @@ variable {S R : Type*} [Mul R] [Add R] [Star R] [SMul S R] @[simps -isSimp one mul] instance aut : Group (R ≃⋆ₐ[S] R) where - one := refl + one := .refl _ _ mul a b := b.trans a one_mul _ := rfl mul_one _ := rfl diff --git a/Mathlib/Algebra/Star/Subalgebra.lean b/Mathlib/Algebra/Star/Subalgebra.lean index 4ca55c7aca647f..993ecdcd7aaba0 100644 --- a/Mathlib/Algebra/Star/Subalgebra.lean +++ b/Mathlib/Algebra/Star/Subalgebra.lean @@ -869,6 +869,32 @@ end StarAlgHom section RestrictScalars +section Equiv + +variable (R : Type*) {S A B : Type*} [CommSemiring R] [CommSemiring S] + [NonUnitalNonAssocSemiring A] [NonUnitalNonAssocSemiring B] [MulAction R S] [Module S A] + [Module S B] [Module R A] [Module R B] [IsScalarTower R S A] [IsScalarTower R S B] + [Star A] [Star B] + +/-- Restrict the scalar ring of a star algebra equivalence. -/ +@[simps] +def StarAlgEquiv.restrictScalars (f : A ≃⋆ₐ[S] B) : A ≃⋆ₐ[R] B := + { (f : A →ₗ[S] B).restrictScalars R, f with + toFun := f } + +theorem StarAlgEquiv.restrictScalars_injective : + Function.Injective (StarAlgEquiv.restrictScalars R : (A ≃⋆ₐ[S] B) → A ≃⋆ₐ[R] B) := + fun _ _ h => ext (DFunLike.congr_fun h ·) + +@[simp] +theorem StarAlgEquiv.toNonUnitalStarAlgHom_restrictScalars (e : A ≃⋆ₐ[S] B) : + (e.restrictScalars R).toNonUnitalStarAlgHom = e.toNonUnitalStarAlgHom.restrictScalars R := + rfl + +end Equiv + +section Unital + variable (R : Type*) {S A B : Type*} [CommSemiring R] [CommSemiring S] [Semiring A] [Semiring B] [Algebra R S] [Algebra S A] [Algebra S B] [Algebra R A] [Algebra R B] [IsScalarTower R S A] [IsScalarTower R S B] [Star A] [Star B] @@ -883,16 +909,12 @@ theorem StarAlgHom.restrictScalars_injective : fun f g h => StarAlgHom.ext fun x => show f.restrictScalars R x = g.restrictScalars R x from DFunLike.congr_fun h x -@[simps] -def StarAlgEquiv.restrictScalars (f : A ≃⋆ₐ[S] B) : A ≃⋆ₐ[R] B := - { (f : A →⋆ₐ[S] B).restrictScalars R, f with - toFun := f - map_smul' := map_smul ((f : A →⋆ₐ[S] B).restrictScalars R) } +@[simp] +theorem StarAlgEquiv.toStarAlgHom_restrictScalars (e : A ≃⋆ₐ[S] B) : + (e.restrictScalars R).toStarAlgHom = e.toStarAlgHom.restrictScalars R := + rfl -theorem StarAlgEquiv.restrictScalars_injective : - Function.Injective (StarAlgEquiv.restrictScalars R : (A ≃⋆ₐ[S] B) → A ≃⋆ₐ[R] B) := - fun f g h => StarAlgEquiv.ext fun x => - show f.restrictScalars R x = g.restrictScalars R x from DFunLike.congr_fun h x +end Unital end RestrictScalars diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index 2f9e018b3e211f..61d64cedb022f6 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -894,7 +894,7 @@ lemma conjStarAlgEquiv_apply (e : H ≃ₗᵢ[𝕜] K) (x : H →L[𝕜] H) : @[simp] lemma symm_conjStarAlgEquiv (e : H ≃ₗᵢ[𝕜] K) : e.conjStarAlgEquiv.symm = e.symm.conjStarAlgEquiv := rfl -@[simp] theorem conjStarAlgEquiv_refl : conjStarAlgEquiv (.refl 𝕜 H) = .refl := rfl +@[simp] theorem conjStarAlgEquiv_refl : conjStarAlgEquiv (.refl 𝕜 H) = .refl _ _ := rfl theorem conjStarAlgEquiv_trans {G : Type*} [NormedAddCommGroup G] [InnerProductSpace 𝕜 G] [CompleteSpace G] (e : H ≃ₗᵢ[𝕜] K) (f : K ≃ₗᵢ[𝕜] G) : From 95eb1704eebcd56eafb16e5c01969bba5f2597cf Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:46:42 +0000 Subject: [PATCH 0060/1300] feat(CategoryTheory/Sites): morphism property induced by precoverage (#40529) We define the weakest morphism property satisfied by all morphisms in covering families of a given precoverage. This provides a left-adjoint to the existing `Precoverage.morphismProperty`. This is useful when talking about morphism properties local on the source. --- .../Sites/MorphismProperty.lean | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Sites/MorphismProperty.lean b/Mathlib/CategoryTheory/Sites/MorphismProperty.lean index 270662f5f73331..7d6f1c72ace666 100644 --- a/Mathlib/CategoryTheory/Sites/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/Sites/MorphismProperty.lean @@ -46,6 +46,11 @@ lemma ofArrows_mem_precoverage {X : C} {ι : Type*} {Y : ι → C} {f : ∀ i, Y .ofArrows Y f ∈ precoverage P X ↔ ∀ i, P (f i) := ⟨fun h i ↦ h ⟨i⟩, fun h _ g ⟨i⟩ ↦ h i⟩ +@[simp, grind =] +lemma singleton_mem_precoverage {X Y : C} (f : X ⟶ Y) : + .singleton f ∈ precoverage P Y ↔ P f := by + simp [← Presieve.ofArrows_pUnit.{_, _, 0}] + instance [P.ContainsIdentities] [P.RespectsIso] : P.precoverage.HasIsos where mem_coverings_of_isIso f _ _ _ := fun ⟨⟩ ↦ P.of_isIso f @@ -145,4 +150,56 @@ end end HasPullbacks -end CategoryTheory.MorphismProperty +end MorphismProperty + +/-- The weakest morphism property satisfied by all morphisms in covering families. -/ +def Precoverage.morphismProperty (K : Precoverage C) : MorphismProperty C := + fun _ Y f ↦ ∃ R ∈ K Y, R f + +@[simp] +lemma MorphismProperty.morphismProperty_precoverage (P : MorphismProperty C) : + P.precoverage.morphismProperty = P := by + ext X Y f + exact ⟨fun ⟨R, hR, hf⟩ ↦ hR hf, fun hf ↦ ⟨.singleton f, by simpa⟩⟩ + +namespace Precoverage + +variable {K L : Precoverage C} {P : MorphismProperty C} + +lemma morphismProperty_le_iff_le_precoverage : + K.morphismProperty ≤ P ↔ K ≤ P.precoverage := + ⟨fun hle _ R hR _ _ hf ↦ hle _ ⟨R, hR, hf⟩, fun hle _ _ _ ⟨_, hR, hf⟩ ↦ hle _ hR hf⟩ + +lemma galoisConnection_morphismProperty_precoverage : + GaloisConnection (Precoverage.morphismProperty (C := C)) MorphismProperty.precoverage := + @Precoverage.morphismProperty_le_iff_le_precoverage _ _ + +lemma monotone_morphismProperty : Monotone (Precoverage.morphismProperty (C := C)) := + Precoverage.galoisConnection_morphismProperty_precoverage.monotone_l + +lemma le_precoverage_morphismProperty : K ≤ K.morphismProperty.precoverage := + galoisConnection_morphismProperty_precoverage.le_u_l _ + +@[simp] +lemma morphismProperty_bot : (⊥ : Precoverage C).morphismProperty = ⊥ := + Precoverage.galoisConnection_morphismProperty_precoverage.l_bot + +@[simp] +lemma morphismProperty_sup : (K ⊔ L).morphismProperty = K.morphismProperty ⊔ L.morphismProperty := + Precoverage.galoisConnection_morphismProperty_precoverage.l_sup + +instance [K.HasIsos] : K.morphismProperty.ContainsIdentities where + id_mem X := ⟨.singleton (𝟙 X), K.mem_coverings_of_isIso _, by simp⟩ + +@[simp, grind .] +lemma ZeroHypercover.morphismProperty {X : C} {E : ZeroHypercover.{w} K X} (i : E.I₀) : + K.morphismProperty (E.f i) := + ⟨_, E.mem₀, ⟨i⟩⟩ + +end Precoverage + +@[simp] +lemma MorphismProperty.precoverage_top : (⊤ : MorphismProperty C).precoverage = ⊤ := + Precoverage.galoisConnection_morphismProperty_precoverage.u_top + +end CategoryTheory From a35aeb07d4cd240c7f9bfe98606c27fcf6ad28a5 Mon Sep 17 00:00:00 2001 From: Kamille Bidan <25210160030@m.fudan.edu.cn> Date: Tue, 16 Jun 2026 10:21:33 +0000 Subject: [PATCH 0061/1300] feat(Topology/DerivedSet): add relative derived set lemmas (#37374) Add `relDerivedSet`, `relDerivedSet_subset`, and `IsClosed.relDerivedSet_eq`. Co-authored-by: NoneMore --- Mathlib/Topology/DerivedSet.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/Topology/DerivedSet.lean b/Mathlib/Topology/DerivedSet.lean index aa560743e11750..e63908ffb209c4 100644 --- a/Mathlib/Topology/DerivedSet.lean +++ b/Mathlib/Topology/DerivedSet.lean @@ -46,6 +46,16 @@ lemma derivedSet_union (A B : Set X) : derivedSet (A ∪ B) = derivedSet A ∪ d lemma derivedSet_mono (A B : Set X) (h : A ⊆ B) : derivedSet A ⊆ derivedSet B := fun _ hx ↦ hx.mono <| le_principal_iff.mpr <| mem_principal.mpr h +/-- The relative derived set operator viewed as a monotone self-map of `Set X`. -/ +def relDerivedSet : Set X →o Set X where + toFun s := derivedSet s ∩ s + monotone' s t h := Set.inter_subset_inter (derivedSet_mono s t h) h + +@[simp] lemma relDerivedSet_apply (A : Set X) : relDerivedSet A = derivedSet A ∩ A := rfl + +lemma relDerivedSet_subset {A : Set X} : relDerivedSet A ⊆ A := + Set.inter_subset_right + theorem Continuous.image_derivedSet {β : Type*} [TopologicalSpace β] {A : Set X} {f : X → β} (hf1 : Continuous f) (hf2 : Function.Injective f) : f '' derivedSet A ⊆ derivedSet (f '' A) := by @@ -68,6 +78,10 @@ lemma isClosed_iff_derivedSet_subset (A : Set X) : IsClosed A ↔ derivedSet A rw [this, ← accPt_principal_iff_clusterPt] at ha exact nh (h ha) +lemma IsClosed.relDerivedSet_eq {A : Set X} (hA : IsClosed A) : + relDerivedSet A = derivedSet A := by + simpa using (isClosed_iff_derivedSet_subset A).mp hA + lemma closure_eq_self_union_derivedSet (A : Set X) : closure A = A ∪ derivedSet A := by ext simp [closure_eq_cluster_pts, clusterPt_principal] @@ -95,6 +109,9 @@ lemma isClosed_derivedSet [T1Space X] (A : Set X) : IsClosed (derivedSet A) := b lemma preperfect_iff_subset_derivedSet {U : Set X} : Preperfect U ↔ U ⊆ derivedSet U := Iff.rfl +lemma preperfect_iff_eq_relDerivedSet {U : Set X} : Preperfect U ↔ U = relDerivedSet U := by + simp [preperfect_iff_subset_derivedSet] + lemma perfect_iff_eq_derivedSet {U : Set X} : Perfect U ↔ U = derivedSet U := by rw [perfect_def, isClosed_iff_derivedSet_subset, preperfect_iff_subset_derivedSet, ← subset_antisymm_iff, eq_comm] From 3eb2bc7febbb9767d38bb83758c4aee453264c83 Mon Sep 17 00:00:00 2001 From: Suzuka Yu <109365723+Yu-Misaka@users.noreply.github.com> Date: Tue, 16 Jun 2026 10:35:36 +0000 Subject: [PATCH 0062/1300] feat: a Cartan matrix of a reduced crystallographic root system cannot have eigenvalue 4 (#39491) This proves the TODO that a Cartan matrix of a reduced crystallographic root system cannot have eigenvalue 4. Co-authored-by: Oliver Nash --- .../LinearAlgebra/RootSystem/CartanMatrix.lean | 17 +++++++++++++++++ .../RootSystem/GeckConstruction/Basis.lean | 3 --- .../RootSystem/GeckConstruction/Semisimple.lean | 7 +++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean b/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean index 29897030287b16..8b913425fb324e 100644 --- a/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean +++ b/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean @@ -8,8 +8,10 @@ module public import Mathlib.Algebra.CharZero.Infinite public import Mathlib.Algebra.Module.Submodule.Union public import Mathlib.Data.Int.Star +public import Mathlib.LinearAlgebra.Determinant public import Mathlib.LinearAlgebra.Matrix.BilinearForm public import Mathlib.LinearAlgebra.Matrix.PosDef +public import Mathlib.LinearAlgebra.Matrix.ZMatrix public import Mathlib.LinearAlgebra.RootSystem.Base public import Mathlib.LinearAlgebra.RootSystem.Finite.Lemmas public import Mathlib.LinearAlgebra.RootSystem.Finite.Nondegenerate @@ -208,6 +210,21 @@ lemma exists_cartanMatrix_diagaonal_mul_posDef [DecidableEq ι] [P.IsRootSystem] rw [← PosDef.transpose_iff] at hd' aesop +open LinearMap Module.End in +lemma det_four_sub_cartanMatrix_ne_zero [DecidableEq ι] [P.IsRootSystem] : + (4 - b.cartanMatrix).det ≠ 0 := by + suffices ¬ HasEigenvalue b.cartanMatrix.toLin' 4 by + have aux : (4 - b.cartanMatrix).toLin' = - (b.cartanMatrix.toLin' - (4 : ℤ) • 1) := by ext; simp + rwa [ne_eq, ← det_toLin', det_eq_zero_iff_ker_ne_bot, aux, ker_neg, ← eigenspace_def, + ← hasEigenvalue_iff] + obtain ⟨d, hd, hdS⟩ := b.exists_cartanMatrix_diagaonal_mul_posDef + have aux (i j : b.support) : b.cartanMatrix i j ≤ if i = j then 2 else 0 := by + rcases eq_or_ne i j with rfl | hij + · simp + · simpa [hij] using cartanMatrix_le_zero_of_ne b i j hij + have := b.cartanMatrix.lt_two_mul_of_mul_diagonal_posDef_of_for_le_of_hasEigen d hdS hd 2 4 aux + aesop + /-- A characterisation of the connectedness of the Dynkin diagram for irreducible root pairings. -/ lemma induction_on_cartanMatrix [P.IsReduced] [P.IsIrreducible] (p : b.support → Prop) {i j : b.support} (hi : p i) diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean index d863aa78d52771..aefcf38fd038cd 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean @@ -91,9 +91,6 @@ def basis : instance : (cartanSubalgebra' b).IsCartanSubalgebra := inferInstanceAs (basis b).cartan.IsCartanSubalgebra --- TODO drop this after: https://github.com/leanprover-community/mathlib4/issues/28713 -variable [Fact ((4 - b.cartanMatrix).det ≠ 0)] - open LieAlgebra.IsKilling in /-- Up to equivalence, `LieAlgebra.IsKilling.rootSystem` is left inverse to `RootPairing.GeckConstruction.lieAlgebra`. -/ diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean index 9bef0c271679aa..80afc55a86c57b 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean @@ -352,9 +352,7 @@ lemma coe_genWeightSpace_zero_eq_span_range_u : rintro ⟨⟨x, -⟩, hx⟩ exact ⟨1, funext fun j ↦ by simpa using apply_sum_inl_eq_zero_of_mem_span_h i j hx⟩ --- TODO Turn this `Fact` into a lemma: it is always true and may be proved via Perron-Frobenius --- See https://leanprover.zulipchat.com/#narrow/channel/116395-maths/topic/Eigenvalues.20of.20Cartan.20matrices/near/516844801 -variable [Fact ((4 - b.cartanMatrix).det ≠ 0)] [P.IsReduced] [P.IsIrreducible] +variable [P.IsReduced] [P.IsIrreducible] /-- Lemma 4.2 from [Geck](Geck2017). -/ instance instIsIrreducible [Nonempty ι] : @@ -369,7 +367,8 @@ instance instIsIrreducible [Nonempty ι] : obtain ⟨c, hc⟩ : ∃ c : b.support → K, ∑ i, c i • u i = x := (mem_span_range_iff_exists_fun K).mp <| hU hx suffices c = 0 by simp [this, ← hc] - have hCM : (4 - b.cartanMatrix).det ≠ 0 := Fact.out + have hCM : (4 - b.cartanMatrix).det ≠ 0 := + RootPairing.Base.det_four_sub_cartanMatrix_ne_zero b contrapose! hCM suffices ((Int.castRingHom K).mapMatrix (4 - b.cartanMatrix)).det = 0 by simpa only [← RingHom.map_det, eq_intCast, Int.cast_eq_zero] using this From 28c4b7f064ee955494c783d17322da87a4cb5b9f Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 16 Jun 2026 11:54:43 +0000 Subject: [PATCH 0063/1300] feat(Combinatorics/SimpleGraph/Operations): a graph is the supremum of edge graphs (#39561) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `G = ⨆ e ∈ G.edgeSet, fromEdgeSet {e}` - `G = sSup { edge u v | (u : V) (v : V) (_ : G.Adj u v) }` and `edgeSet` & `fromEdgeSet` preserve sup & inf. --- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 42 +++++++++++++++++++ .../Combinatorics/SimpleGraph/Operations.lean | 9 ++++ 2 files changed, 51 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 8ca659a86b0a21..6d2f1c5de950af 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -526,6 +526,27 @@ theorem edgeSet_inf : (G₁ ⊓ G₂).edgeSet = G₁.edgeSet ∩ G₂.edgeSet := ext ⟨x, y⟩ rfl +theorem edgeSet_sSup {s : Set (SimpleGraph V)} : (sSup s).edgeSet = ⋃₀ (edgeSet '' s) := by + ext ⟨x, y⟩ + simp + +theorem edgeSet_sInf {s : Set (SimpleGraph V)} (h : s.Nonempty) : + (sInf s).edgeSet = ⋂₀ (edgeSet '' s) := by + ext ⟨x, y⟩ + have ⟨G, hG⟩ := h + simpa using (· G hG |>.ne) + +theorem edgeSet_iSup {ι : Sort*} {f : ι → SimpleGraph V} : + (⨆ i, f i).edgeSet = ⋃ i, (f i).edgeSet := by + ext ⟨x, y⟩ + simp + +theorem edgeSet_iInf {ι : Sort*} [Nonempty ι] {f : ι → SimpleGraph V} : + (⨅ i, f i).edgeSet = ⋂ i, (f i).edgeSet := by + ext ⟨x, y⟩ + have ⟨i⟩ := ‹Nonempty ι› + simpa using (· i |>.ne) + @[simp] theorem edgeSet_sdiff : (G₁ \ G₂).edgeSet = G₁.edgeSet \ G₂.edgeSet := by ext ⟨x, y⟩ @@ -670,6 +691,27 @@ theorem fromEdgeSet_union (s t : Set (Sym2 V)) : ext v w simp [Set.mem_union, or_and_right] +theorem fromEdgeSet_sUnion {s : Set (Set (Sym2 V))} : + fromEdgeSet (⋃₀ s) = sSup (fromEdgeSet '' s) := by + ext u v + simp + grind + +theorem fromEdgeSet_iUnion {ι : Sort*} {f : ι → Set (Sym2 V)} : + fromEdgeSet (⋃ i, f i) = ⨆ i, fromEdgeSet (f i) := by + ext u v + simp + +theorem fromEdgeSet_sInter {s : Set (Set (Sym2 V))} : + fromEdgeSet (⋂₀ s) = sInf (fromEdgeSet '' s) := by + ext u v + simp_all + +theorem fromEdgeSet_iInter {ι : Sort*} {f : ι → Set (Sym2 V)} : + fromEdgeSet (⋂ i, f i) = ⨅ i, fromEdgeSet (f i) := by + ext u v + simp_all + @[simp] theorem fromEdgeSet_sdiff (s t : Set (Sym2 V)) : fromEdgeSet (s \ t) = fromEdgeSet s \ fromEdgeSet t := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Operations.lean b/Mathlib/Combinatorics/SimpleGraph/Operations.lean index d8fa90b4dfa818..43932a8732e0b1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Operations.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Operations.lean @@ -195,6 +195,15 @@ lemma disjoint_edge {u v : V} : Disjoint G (edge u v) ↔ ¬G.Adj u v := by lemma sdiff_edge {u v : V} (h : ¬G.Adj u v) : G \ edge u v = G := by simp [disjoint_edge, h] +theorem biSup_fromEdgeSet_singleton_eq : ⨆ e ∈ G.edgeSet, fromEdgeSet {e} = G := by + simp_rw [← edgeSet_inj, ← iSup_subtype'', edgeSet_iSup, edgeSet_fromEdgeSet, ← Set.iUnion_sdiff, + Set.iUnion_coe_set, Set.biUnion_of_singleton] + exact Set.disjoint_left.mpr G.edgeSet_subset_compl_diagSet |>.sdiff_eq_left + +theorem sSup_edge_eq : sSup { edge u v | (u : V) (v : V) (_ : G.Adj u v) } = G := by + refine .trans ?_ G.biSup_fromEdgeSet_singleton_eq + simp_rw [edge, ← iSup_subtype'', iSup, Set.range, Subtype.exists, Sym2.exists, mem_edgeSet] + theorem Subgraph.spanningCoe_sup_edge_le {H : Subgraph (G ⊔ edge s t)} (h : ¬ H.Adj s t) : H.spanningCoe ≤ G := by intro v w hvw From 2c3e688dffed1b1e5ca4749b9e4732fbf2ac0879 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:08:55 +0000 Subject: [PATCH 0064/1300] feat(CategoryTheory/Comma/Basic): use `to_dual` more (#40355) This PR continues tagging things about `Comma` with `to_dual`. This PR also expands the `to_dual_name_hint` syntax so that you can give multiple name hints with a single command, instead of having to repeat the command. This PR adds `CategoryTheory.Comma.map_obj_hom'`, the dual of `CategoryTheory.Comma.map_obj_hom`. --- Mathlib/CategoryTheory/Comma/Basic.lean | 198 +++++++++-------------- Mathlib/Order/Interval/Set/Disjoint.lean | 3 +- Mathlib/Tactic/Translate/ToDual.lean | 11 +- MathlibTest/Attribute/ToDual.lean | 3 +- 4 files changed, 81 insertions(+), 134 deletions(-) diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index eb82d3564b36c4..84918905be1fe7 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -100,6 +100,8 @@ structure CommaMorphism (X Y : Comma L R) where attribute [to_dual existing right] CommaMorphism.left +to_dual_name_hint Left Right, Fst Snd, L R, L₁ R₁, L₂ R₂, A B, F₁ F₂ + @[to_dual existing w] theorem CommaMorphism.w' {X Y : Comma R L} (self : CommaMorphism Y X) : Y.hom ≫ L.map self.right = R.map self.left ≫ X.hom := @@ -141,11 +143,11 @@ variable {X Y Z : Comma L R} {f : X ⟶ Y} {g : Y ⟶ Z} lemma hom_ext (f g : X ⟶ Y) (h₁ : f.left = g.left) (h₂ : f.right = g.right) : f = g := CommaMorphism.ext h₁ h₂ -@[to_dual (attr := simp) id_right] +@[to_dual (attr := simp)] theorem id_left : (𝟙 X : CommaMorphism X X).left = 𝟙 X.left := rfl -@[to_dual (attr := simp) comp_right] +@[to_dual (attr := simp)] theorem comp_left : (f ≫ g).left = f.left ≫ g.left := rfl @@ -154,23 +156,21 @@ end variable (L) (R) /-- The functor sending an object `X` in the comma category to `X.left`. -/ -@[simps] +@[to_dual (reorder := L R) (attr := simps) +/-- The functor sending an object `X` in the comma category to `X.right`. -/] def fst : Comma L R ⥤ A where obj X := X.left map f := f.left -/-- The functor sending an object `X` in the comma category to `X.right`. -/ -@[simps] -def snd : Comma L R ⥤ B where - obj X := X.right - map f := f.right +set_option linter.existingAttributeWarning false in +attribute [to_dual existing] fst_map set_option backward.defeqAttrib.useBackward true in /-- We can interpret the commutative square constituting a morphism in the comma category as a natural transformation between the functors `fst ⋙ L` and `snd ⋙ R` from the comma category to `T`, where the components are given by the morphism that constitutes an object of the comma category. -/ -@[simps] +@[simps, to_dual self] def natTrans : fst L R ⋙ L ⟶ snd L R ⋙ R where app X := X.hom @[simp] @@ -189,28 +189,19 @@ section variable {L R} {X Y : Comma L R} (e : X ⟶ Y) +@[to_dual] instance [IsIso e] : IsIso e.left := (Comma.fst L R).map_isIso e -instance [IsIso e] : IsIso e.right := - (Comma.snd L R).map_isIso e - -@[simp, push ←] +@[to_dual (attr := simp, push ←)] lemma inv_left [IsIso e] : (inv e).left = inv e.left := by apply IsIso.eq_inv_of_hom_inv_id rw [← Comma.comp_left, IsIso.hom_inv_id, id_left] -@[simp, push ←] -lemma inv_right [IsIso e] : (inv e).right = inv e.right := by - apply IsIso.eq_inv_of_hom_inv_id - rw [← Comma.comp_right, IsIso.hom_inv_id, id_right] - +@[to_dual inv_left_hom_right] lemma left_hom_inv_right [IsIso e] : L.map (e.left) ≫ Y.hom ≫ R.map (inv e.right) = X.hom := by simp -lemma inv_left_hom_right [IsIso e] : L.map (inv e.left) ≫ X.hom ≫ R.map e.right = Y.hom := by - simp - end section @@ -218,17 +209,14 @@ section variable {L₁ L₂ L₃ : A ⥤ T} {R₁ R₂ R₃ : B ⥤ T} /-- Extract the isomorphism between the left objects from an isomorphism in the comma category. -/ -@[simps!] +@[to_dual (attr := simps!) +/-- Extract the isomorphism between the right objects from an isomorphism in the comma category. -/] def leftIso {X Y : Comma L₁ R₁} (α : X ≅ Y) : X.left ≅ Y.left := (fst L₁ R₁).mapIso α -/-- Extract the isomorphism between the right objects from an isomorphism in the comma category. -/ -@[simps!] -def rightIso {X Y : Comma L₁ R₁} (α : X ≅ Y) : X.right ≅ Y.right := (snd L₁ R₁).mapIso α - /-- Construct an isomorphism in the comma category given isomorphisms of the objects whose forward directions give a commutative square. -/ -@[simps] +@[to_dual none, simps (attr := to_dual none)] def isoMk {X Y : Comma L₁ R₁} (l : X.left ≅ Y.left) (r : X.right ≅ Y.right) (h : L₁.map l.hom ≫ Y.hom = X.hom ≫ R₁.map r.hom := by cat_disch) : X ≅ Y where hom := @@ -253,7 +241,7 @@ variable {L' : A' ⥤ T'} {R' : B' ⥤ T'} set_option backward.isDefEq.respectTransparency false in /-- The functor `Comma L R ⥤ Comma L' R'` induced by three functors `F₁`, `F₂`, `F` and two natural transformations `F₁ ⋙ L' ⟶ L ⋙ F` and `R ⋙ F ⟶ F₂ ⋙ R'`. -/ -@[simps] +@[simps, to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β)] def map : Comma L R ⥤ Comma L' R' where obj X := { left := F₁.obj X.left @@ -269,6 +257,15 @@ def map : Comma L R ⥤ Comma L' R' where dsimp rw [← F.map_comp_assoc, ← F.map_comp_assoc, φ.w] } +set_option linter.existingAttributeWarning false in +attribute [to_dual existing] map_obj_left + +set_option backward.isDefEq.respectTransparency false in +@[to_dual existing (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β) map_obj_hom] +theorem map_obj_hom' (X : Comma L R) : + ((map α β).obj X).hom = (α.app X.left ≫ F.map X.hom) ≫ β.app X.right := by simp + +@[to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, 22 23)] instance faithful_map [F₁.Faithful] [F₂.Faithful] : (map α β).Faithful where map_injective {X Y} f g h := by ext @@ -276,6 +273,7 @@ instance faithful_map [F₁.Faithful] [F₂.Faithful] : (map α β).Faithful whe · exact F₂.map_injective (congr_arg CommaMorphism.right h) set_option backward.isDefEq.respectTransparency false in +@[to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, 23 24, 25 26)] instance full_map [F.Faithful] [F₁.Full] [F₂.Full] [IsIso α] [IsIso β] : (map α β).Full where map_surjective {X Y} φ := ⟨{left := F₁.preimage φ.left @@ -292,6 +290,7 @@ instance full_map [F.Faithful] [F₁.Full] [F₂.Full] [IsIso α] [IsIso β] : ( by cat_disch⟩ set_option backward.defeqAttrib.useBackward true in +@[to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, 22 23, 25 26)] instance essSurj_map [F₁.EssSurj] [F₂.EssSurj] [F.Full] [IsIso α] [IsIso β] : (map α β).EssSurj where mem_essImage X := @@ -305,38 +304,32 @@ instance essSurj_map [F₁.EssSurj] [F₂.EssSurj] [F.Full] [IsIso α] [IsIso β IsIso.inv_hom_id, comp_id, IsIso.hom_inv_id_assoc] rw [← R'.map_comp, Iso.inv_hom_id, R'.map_id, comp_id])⟩⟩ +@[to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, 22 23, 26 27)] noncomputable instance isEquivalenceMap [F₁.IsEquivalence] [F₂.IsEquivalence] [F.Faithful] [F.Full] [IsIso α] [IsIso β] : (map α β).IsEquivalence where /-- The equality between `map α β ⋙ fst L' R'` and `fst L R ⋙ F₁`, where `α : F₁ ⋙ L' ⟶ L ⋙ F`. -/ -@[simp] +@[to_dual (attr := simp) (reorder := α β) +/-- The equality between `map α β ⋙ snd L' R'` and `snd L R ⋙ F₂`, +where `β : R ⋙ F ⟶ F₂ ⋙ R'`. -/] theorem map_fst : map α β ⋙ fst L' R' = fst L R ⋙ F₁ := rfl /-- The isomorphism between `map α β ⋙ fst L' R'` and `fst L R ⋙ F₁`, where `α : F₁ ⋙ L' ⟶ L ⋙ F`. -/ -@[simps!] -def mapFst : map α β ⋙ fst L' R' ≅ fst L R ⋙ F₁ := - NatIso.ofComponents (fun _ => Iso.refl _) (by simp) - -/-- The equality between `map α β ⋙ snd L' R'` and `snd L R ⋙ F₂`, -where `β : R ⋙ F ⟶ F₂ ⋙ R'`. -/ -@[simp] -theorem map_snd : map α β ⋙ snd L' R' = snd L R ⋙ F₂ := - rfl - +@[to_dual (attr := simps!) (reorder := α β) /-- The isomorphism between `map α β ⋙ snd L' R'` and `snd L R ⋙ F₂`, -where `β : R ⋙ F ⟶ F₂ ⋙ R'`. -/ -@[simps!] -def mapSnd : map α β ⋙ snd L' R' ≅ snd L R ⋙ F₂ := +where `β : R ⋙ F ⟶ F₂ ⋙ R'`. -/] +def mapFst : map α β ⋙ fst L' R' ≅ fst L R ⋙ F₁ := NatIso.ofComponents (fun _ => Iso.refl _) (by simp) end /-- A natural transformation `L₁ ⟶ L₂` induces a functor `Comma L₂ R ⥤ Comma L₁ R`. -/ -@[simps] +@[to_dual (attr := simps) +/-- A natural transformation `R₁ ⟶ R₂` induces a functor `Comma L R₁ ⥤ Comma L R₂`. -/] def mapLeft (l : L₁ ⟶ L₂) : Comma L₂ R ⥤ Comma L₁ R where obj X := { left := X.left @@ -346,10 +339,17 @@ def mapLeft (l : L₁ ⟶ L₂) : Comma L₂ R ⥤ Comma L₁ R where { left := f.left right := f.right } +set_option linter.existingAttributeWarning false +set_option linter.translateGenerateName false +attribute [to_dual existing mapRight_map_right] mapLeft_map_left +attribute [to_dual existing mapRight_map_left] mapLeft_map_right + set_option backward.defeqAttrib.useBackward true in /-- The functor `Comma L R ⥤ Comma L R` induced by the identity natural transformation on `L` is naturally isomorphic to the identity functor. -/ -@[simps!] +@[to_dual (attr := simps!) +/-- The functor `Comma L R ⥤ Comma L R` induced by the identity natural transformation on `R` is +naturally isomorphic to the identity functor. -/] def mapLeftId : mapLeft R (𝟙 L) ≅ 𝟭 _ := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) @@ -357,70 +357,34 @@ set_option backward.defeqAttrib.useBackward true in /-- The functor `Comma L₁ R ⥤ Comma L₃ R` induced by the composition of two natural transformations `l : L₁ ⟶ L₂` and `l' : L₂ ⟶ L₃` is naturally isomorphic to the composition of the two functors induced by these natural transformations. -/ -@[simps!] +@[to_dual (attr := simps!) +/-- The functor `Comma L R₁ ⥤ Comma L R₃` induced by the composition of the natural transformations +`r : R₁ ⟶ R₂` and `r' : R₂ ⟶ R₃` is naturally isomorphic to the composition of the functors +induced by these natural transformations. -/] def mapLeftComp (l : L₁ ⟶ L₂) (l' : L₂ ⟶ L₃) : mapLeft R (l ≫ l') ≅ mapLeft R l' ⋙ mapLeft R l := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) /-- Two equal natural transformations `L₁ ⟶ L₂` yield naturally isomorphic functors `Comma L₁ R ⥤ Comma L₂ R`. -/ -@[simps!] +@[to_dual (attr := simps!) +/-- Two equal natural transformations `R₁ ⟶ R₂` yield naturally isomorphic functors +`Comma L R₁ ⥤ Comma L R₂`. -/] def mapLeftEq (l l' : L₁ ⟶ L₂) (h : l = l') : mapLeft R l ≅ mapLeft R l' := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) set_option backward.defeqAttrib.useBackward true in /-- A natural isomorphism `L₁ ≅ L₂` induces an equivalence of categories `Comma L₁ R ≌ Comma L₂ R`. -/ -@[simps!] +@[to_dual (attr := simps!) +/-- A natural isomorphism `R₁ ≅ R₂` induces an equivalence of categories +`Comma L R₁ ≌ Comma L R₂`. -/] def mapLeftIso (i : L₁ ≅ L₂) : Comma L₁ R ≌ Comma L₂ R where functor := mapLeft _ i.inv inverse := mapLeft _ i.hom unitIso := (mapLeftId _ _).symm ≪≫ mapLeftEq _ _ _ i.hom_inv_id.symm ≪≫ mapLeftComp _ _ _ counitIso := (mapLeftComp _ _ _).symm ≪≫ mapLeftEq _ _ _ i.inv_hom_id ≪≫ mapLeftId _ _ -/-- A natural transformation `R₁ ⟶ R₂` induces a functor `Comma L R₁ ⥤ Comma L R₂`. -/ -@[simps] -def mapRight (r : R₁ ⟶ R₂) : Comma L R₁ ⥤ Comma L R₂ where - obj X := - { left := X.left - right := X.right - hom := X.hom ≫ r.app X.right } - map f := - { left := f.left - right := f.right } - -set_option backward.defeqAttrib.useBackward true in -/-- The functor `Comma L R ⥤ Comma L R` induced by the identity natural transformation on `R` is -naturally isomorphic to the identity functor. -/ -@[simps!] -def mapRightId : mapRight L (𝟙 R) ≅ 𝟭 _ := - NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) - -set_option backward.defeqAttrib.useBackward true in -/-- The functor `Comma L R₁ ⥤ Comma L R₃` induced by the composition of the natural transformations -`r : R₁ ⟶ R₂` and `r' : R₂ ⟶ R₃` is naturally isomorphic to the composition of the functors -induced by these natural transformations. -/ -@[simps!] -def mapRightComp (r : R₁ ⟶ R₂) (r' : R₂ ⟶ R₃) : - mapRight L (r ≫ r') ≅ mapRight L r ⋙ mapRight L r' := - NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) - -/-- Two equal natural transformations `R₁ ⟶ R₂` yield naturally isomorphic functors -`Comma L R₁ ⥤ Comma L R₂`. -/ -@[simps!] -def mapRightEq (r r' : R₁ ⟶ R₂) (h : r = r') : mapRight L r ≅ mapRight L r' := - NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) - -set_option backward.defeqAttrib.useBackward true in -/-- A natural isomorphism `R₁ ≅ R₂` induces an equivalence of categories -`Comma L R₁ ≌ Comma L R₂`. -/ -@[simps!] -def mapRightIso (i : R₁ ≅ R₂) : Comma L R₁ ≌ Comma L R₂ where - functor := mapRight _ i.hom - inverse := mapRight _ i.inv - unitIso := (mapRightId _ _).symm ≪≫ mapRightEq _ _ _ i.hom_inv_id.symm ≪≫ mapRightComp _ _ _ - counitIso := (mapRightComp _ _ _).symm ≪≫ mapRightEq _ _ _ i.inv_hom_id ≪≫ mapRightId _ _ - end section @@ -428,7 +392,7 @@ section variable {C : Type u₄} [Category.{v₄} C] /-- The functor `(F ⋙ L, R) ⥤ (L, R)` -/ -@[simps] +@[to_dual (attr := simps) (reorder := F L R) /-- The functor `(L, F ⋙ R) ⥤ (L, R)` -/] def preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : Comma (F ⋙ L) R ⥤ Comma L R where obj X := { left := F.obj X.left @@ -442,58 +406,33 @@ def preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : Comma (F ⋙ L) R ⥤ Co set_option backward.defeqAttrib.useBackward true in /-- `Comma.preLeft` is a particular case of `Comma.map`, but with better definitional properties. -/ +@[to_dual (reorder := F L R) +/-- `Comma.preRight` is a particular case of `Comma.map`, +but with better definitional properties. -/] def preLeftIso (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : preLeft F L R ≅ map (F ⋙ L).rightUnitor.inv (R.rightUnitor.hom ≫ R.leftUnitor.inv) := - NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) + NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _) (by simp -implicitDefEqProofs)) +@[to_dual] instance (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) [F.Faithful] : (preLeft F L R).Faithful := Functor.Faithful.of_iso (preLeftIso F L R).symm +@[to_dual] instance (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) [F.Full] : (preLeft F L R).Full := Functor.Full.of_iso (preLeftIso F L R).symm +@[to_dual] instance (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) [F.EssSurj] : (preLeft F L R).EssSurj := Functor.essSurj_of_iso (preLeftIso F L R).symm /-- If `F` is an equivalence, then so is `preLeft F L R`. -/ +@[to_dual /-- If `F` is an equivalence, then so is `preRight L F R`. -/] instance isEquivalence_preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) [F.IsEquivalence] : (preLeft F L R).IsEquivalence where -set_option backward.isDefEq.respectTransparency false in -/-- The functor `(L, F ⋙ R) ⥤ (L, R)` -/ -@[simps] -def preRight (L : A ⥤ T) (F : C ⥤ B) (R : B ⥤ T) : Comma L (F ⋙ R) ⥤ Comma L R where - obj X := - { left := X.left - right := F.obj X.right - hom := X.hom } - map f := - { left := f.left - right := F.map f.right } - -set_option backward.defeqAttrib.useBackward true in -/-- `Comma.preRight` is a particular case of `Comma.map`, -but with better definitional properties. -/ -def preRightIso (L : A ⥤ T) (F : C ⥤ B) (R : B ⥤ T) : - preRight L F R ≅ map (L.leftUnitor.hom ≫ L.rightUnitor.inv) (F ⋙ R).rightUnitor.hom := - NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) - -instance (L : A ⥤ T) (F : C ⥤ B) (R : B ⥤ T) [F.Faithful] : (preRight L F R).Faithful := - Functor.Faithful.of_iso (preRightIso L F R).symm - -instance (L : A ⥤ T) (F : C ⥤ B) (R : B ⥤ T) [F.Full] : (preRight L F R).Full := - Functor.Full.of_iso (preRightIso L F R).symm - -instance (L : A ⥤ T) (F : C ⥤ B) (R : B ⥤ T) [F.EssSurj] : (preRight L F R).EssSurj := - Functor.essSurj_of_iso (preRightIso L F R).symm - -/-- If `F` is an equivalence, then so is `preRight L F R`. -/ -instance isEquivalence_preRight (L : A ⥤ T) (F : C ⥤ B) (R : B ⥤ T) [F.IsEquivalence] : - (preRight L F R).IsEquivalence where - set_option backward.isDefEq.respectTransparency false in /-- The functor `(L, R) ⥤ (L ⋙ F, R ⋙ F)` -/ -@[simps] +@[to_dual self, simps] def post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : Comma L R ⥤ Comma (L ⋙ F) (R ⋙ F) where obj X := { left := X.left @@ -504,22 +443,31 @@ def post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : Comma L R ⥤ Comma (L ⋙ right := f.right w := by simp only [Functor.comp_map, ← F.map_comp, f.w] } +set_option linter.existingAttributeWarning false in +attribute [to_dual existing] post_obj_left +attribute [to_dual self] post_obj_hom + set_option backward.defeqAttrib.useBackward true in /-- `Comma.post` is a particular case of `Comma.map`, but with better definitional properties. -/ +@[to_dual self] def postIso (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : post L R F ≅ map (F₁ := 𝟭 _) (F₂ := 𝟭 _) (L ⋙ F).leftUnitor.hom (R ⋙ F).leftUnitor.inv := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +@[to_dual self] instance (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : (post L R F).Faithful := Functor.Faithful.of_iso (postIso L R F).symm +@[to_dual self] instance (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) [F.Faithful] : (post L R F).Full := Functor.Full.of_iso (postIso L R F).symm +@[to_dual self] instance (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) [F.Full] : (post L R F).EssSurj := Functor.essSurj_of_iso (postIso L R F).symm /-- If `F` is an equivalence, then so is `post L R F`. -/ +@[to_dual self] instance isEquivalence_post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) [F.IsEquivalence] : (post L R F).IsEquivalence where diff --git a/Mathlib/Order/Interval/Set/Disjoint.lean b/Mathlib/Order/Interval/Set/Disjoint.lean index aff5f999922bcc..f42c0a674c0c52 100644 --- a/Mathlib/Order/Interval/Set/Disjoint.lean +++ b/Mathlib/Order/Interval/Set/Disjoint.lean @@ -36,8 +36,7 @@ section Preorder variable [Preorder α] {a b c : α} -to_dual_name_hint Disjoint Disjoint -to_dual_name_hint Left Right +to_dual_name_hint Disjoint Disjoint, Left Right @[to_dual (attr := simp)] theorem Iic_disjoint_Ioi (h : a ≤ b) : Disjoint (Iic a) (Ioi b) := diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index b46222f703695c..da8dcb078ff371 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -295,10 +295,11 @@ initialize registerBuiltinAttribute { applicationTime := .afterCompilation } -/-- `to_dual_name_hint src tgt` lets `to_dual` translate between the name segments `src` and `tgt` -for the rest of the file current. `src` and `tgt` should both be capitalized. -/ -elab "to_dual_name_hint" src:ident tgt:ident : command => do - guessNameExt.addTranslation src tgt - guessNameExt.addTranslation tgt src +/-- `to_dual_name_hint src₁ tgt₁, ..., srcₙ tgtₙ` lets `to_dual` translate between the name segments +`srcᵢ` and `tgtᵢ` for the rest of the file current. The name segments should be capitalized. -/ +elab "to_dual_name_hint" hints:(ident ident),* : command => do + for ⟨hint⟩ in hints.getElems do + guessNameExt.addTranslation ⟨hint[0]⟩ ⟨hint[1]⟩ + guessNameExt.addTranslation ⟨hint[1]⟩ ⟨hint[0]⟩ end Mathlib.Tactic.ToDual diff --git a/MathlibTest/Attribute/ToDual.lean b/MathlibTest/Attribute/ToDual.lean index 8113c3ac6fe7fc..890c9c996640e3 100644 --- a/MathlibTest/Attribute/ToDual.lean +++ b/MathlibTest/Attribute/ToDual.lean @@ -431,8 +431,7 @@ to_dual_name_hint LeftMono FooBar #guard_msgs in #eval return GuessName.guessName (data.guessNameExt.getState (← getEnv)) "leftMono" -to_dual_name_hint Left Right -to_dual_name_hint Epi Mono +to_dual_name_hint Left Right, Epi Mono /-- info: "right_epi" -/ #guard_msgs in From bf81df9aa4ee509ba0247f7d0aa9fe24d3f45d7a Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 16 Jun 2026 13:03:38 +0000 Subject: [PATCH 0065/1300] feat: an explicit criterion for membership in the maximal atlas of a `C^n` manifold (#40632) Add an explicit characterisation, that an `OpenPartialHomeomorph` phi lies in the maximal atlas of a C^n manifold if both phi and phi.symm are C^n on their source. This can be useful to prove that certain explicit maps are in the maximal atlas, so prove some maps are immersions. Motivating examples are #29077 (for the inclusion of a closed interval [a, b] into the real numbers) and for a manual proof that diffeomorphisms are immersions. Along the way, rename `contMDiff_model` and its inverse cousin `contMDiffOn_model_symm` to match the naming convention, and golf their proofs. --- .../Geometry/Manifold/ContMDiff/Atlas.lean | 43 +++++++++++++------ .../Geometry/Manifold/PartitionOfUnity.lean | 2 +- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean index f52989501c5754..78a63c9fcaf56b 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean @@ -45,19 +45,20 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section Atlas -theorem contMDiff_model : ContMDiff I 𝓘(𝕜, E) n I := by +variable (I) in +theorem ModelWithCorners.contMDiff : ContMDiff I 𝓘(𝕜, E) n I := by intro x refine contMDiffAt_iff.mpr ⟨I.continuousAt, ?_⟩ - simp only [mfld_simps] - refine contDiffWithinAt_id.congr_of_eventuallyEq ?_ ?_ - · exact Filter.eventuallyEq_of_mem self_mem_nhdsWithin fun x₂ => I.right_inv - simp_rw [Function.comp_apply, I.left_inv, Function.id_def] + simpa using contDiffWithinAt_id.congr (fun y hy ↦ by simp [hy]) (by simp) +@[deprecated (since := "2026-06-16")] alias contMDiff_model := ModelWithCorners.contMDiff -theorem contMDiffOn_model_symm : ContMDiffOn 𝓘(𝕜, E) I n I.symm (range I) := by - rw [contMDiffOn_iff] - refine ⟨I.continuousOn_symm, fun x y => ?_⟩ - simp only [mfld_simps] - exact contDiffOn_id.congr fun x' => I.right_inv +variable (I) in +theorem ModelWithCorners.contMDiffOn_symm : ContMDiffOn 𝓘(𝕜, E) I n I.symm (range I) := by + intro x hx + apply contMDiffWithinAt_iff.mpr ⟨by fun_prop, ?_⟩ + simpa using contDiffWithinAt_id.congr (fun y hy ↦ by simp [hy]) (by simp [hx]) +@[deprecated (since := "2026-06-16")] +alias contMDiffOn_model_symm := ModelWithCorners.contMDiffOn_symm /-- An atlas member is `C^n` for any `n`. -/ theorem contMDiffOn_of_mem_maximalAtlas (h : e ∈ maximalAtlas I n M) : @@ -89,7 +90,7 @@ theorem contMDiffOn_chart_symm [IsManifold I n M] : theorem contMDiffAt_extend {x : M} (he : e ∈ maximalAtlas I n M) (hx : x ∈ e.source) : ContMDiffAt I 𝓘(𝕜, E) n (e.extend I) x := - (contMDiff_model _).comp x <| contMDiffAt_of_mem_maximalAtlas he hx + (I.contMDiff _).comp x <| contMDiffAt_of_mem_maximalAtlas he hx theorem contMDiffOn_extend (he : e ∈ maximalAtlas I n M) : ContMDiffOn I 𝓘(𝕜, E) n (e.extend I) e.source := @@ -112,7 +113,7 @@ theorem contMDiffOn_extChartAt [IsManifold I n M] : theorem contMDiffOn_extend_symm (he : e ∈ maximalAtlas I n M) : ContMDiffOn 𝓘(𝕜, E) I n (e.extend I).symm (I '' e.target) := by refine (contMDiffOn_symm_of_mem_maximalAtlas he).comp - (contMDiffOn_model_symm.mono <| image_subset_range _ _) ?_ + (I.contMDiffOn_symm.mono <| image_subset_range _ _) ?_ simp_rw [image_subset_iff, PartialEquiv.restr_coe_symm, I.toPartialEquiv_coe_symm, preimage_preimage, I.left_inv, preimage_id']; rfl @@ -155,6 +156,24 @@ theorem contMDiffOn_of_mem_contDiffGroupoid {e' : OpenPartialHomeomorph H H} (h : e' ∈ contDiffGroupoid n I) : ContMDiffOn I I n e' e'.source := (contDiffWithinAt_localInvariantProp n).liftPropOn_of_mem_groupoid contDiffWithinAtProp_id h +lemma OpenPartialHomeomorph.mem_maximalAtlas_of_contMDiffOn (φ : OpenPartialHomeomorph H H) + (hφ : ContMDiffOn I I n φ φ.source) (hφ' : ContMDiffOn I I n φ.symm φ.target) : + φ ∈ maximalAtlas I n H := by + simp only [mfld_simps, IsManifold.mem_maximalAtlas_iff, StructureGroupoid.maximalAtlas, forall_eq, + contDiffGroupoid, mem_groupoid_of_pregroupoid, contDiffPregroupoid, + ← contMDiffOn_iff_contDiffOn] + refine ⟨⟨?_, ?_⟩, ?_, ?_⟩ + all_goals apply I.contMDiff.comp_contMDiffOn + · exact hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) + · exact hφ.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) + · exact hφ.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) + · exact hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) + +lemma IsManifold.mem_maximalAtlas_iff_contMDiffOn (φ : OpenPartialHomeomorph H H) : + φ ∈ maximalAtlas I n H ↔ ContMDiffOn I I n φ φ.source ∧ ContMDiffOn I I n φ.symm φ.target := + ⟨fun h ↦ ⟨contMDiffOn_of_mem_maximalAtlas h, contMDiffOn_symm_of_mem_maximalAtlas h⟩, + fun ⟨hφ, hφ'⟩ ↦ φ.mem_maximalAtlas_of_contMDiffOn hφ hφ'⟩ + end Atlas /-! ### (local) structomorphisms are `C^n` -/ diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index 2fa99c7ca2695d..db07e504d28b3d 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -736,7 +736,7 @@ lemma IsOpen.exists_contMDiff_support_eq_aux {s : Set H} (hs : IsOpen s) : refine ⟨f ∘ I, ?_, ?_, ?_⟩ · rw [support_comp_eq_preimage, f_supp, ← preimage_comp] simp only [ModelWithCorners.symm_comp_self, preimage_id_eq, id_eq] - · exact f_diff.comp_contMDiff contMDiff_model + · exact f_diff.comp_contMDiff I.contMDiff · exact Subset.trans (range_comp_subset_range _ _) f_range @[deprecated (since := "2025-12-17")] From d18bb636bbd4f3f19fa9a70b7f11e3bf4b501e97 Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Tue, 16 Jun 2026 13:17:59 +0000 Subject: [PATCH 0066/1300] chore: make `_root_.toContinuousMap` reducible (#40477) If a structure extends `ContinuousMap` and also carries an instance of `ContinuousMapClass` then it will have two `toContinuousMap` functions available to it. Without this change, at non-reducible transparency Lean is unable to see that these two are defeq (assuming we have written a sane API and they are!). The motivating example is the `Path` structure where the lack of this reducibility was responsible for some `backward.isDefEq.respectTransparency false` in #33108. --- .../CStarAlgebra/ContinuousFunctionalCalculus/Basic.lean | 2 +- .../CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean | 2 +- .../CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean | 2 +- .../CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean | 4 ++-- Mathlib/Analysis/RCLike/BoundedContinuous.lean | 2 +- Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean | 2 +- Mathlib/Topology/ContinuousMap/Defs.lean | 2 +- Mathlib/Topology/ContinuousMap/Ideals.lean | 2 +- Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean | 4 ++-- Mathlib/Topology/Homotopy/HomotopyGroup.lean | 2 +- Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Basic.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Basic.lean index 88bf4a6749cf38..bdce04f278e2d3 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Basic.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Basic.lean @@ -212,7 +212,7 @@ instance IsStarNormal.instNonUnitalIsometricContinuousFunctionalCalculus : rw [← norm_inr (𝕜 := ℂ), ← inrNonUnitalStarAlgHom_apply, ← NonUnitalStarAlgHom.comp_apply, inr_comp_cfcₙHom_eq_cfcₙAux a, cfcₙAux] simp only [NonUnitalStarAlgHom.comp_assoc, NonUnitalStarAlgHom.comp_apply, - toContinuousMapHom_apply, NonUnitalStarAlgHom.coe_coe] + NonUnitalStarAlgHom.coe_coe] rw [norm_cfcHom (a : Unitization ℂ A), StarAlgEquiv.norm_map] rfl diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean index 3143700d96afb5..d720af78d8eec5 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean @@ -387,7 +387,7 @@ protected theorem isometric_cfc (f : C(S, R)) (halg : Isometry (algebraMap R S)) · simpa [halg.dist_eq] using! ContinuousMap.dist_apply_le_dist _ · let x' : σₙ S a := Subtype.map (algebraMap R S) (fun _ ↦ quasispectrum.algebraMap_mem S) x apply le_of_eq_of_le ?_ <| ContinuousMap.dist_apply_le_dist x' - simp only [ContinuousMap.coe_coe, ContinuousMapZero.comp_apply, ContinuousMapZero.coe_mk, + simp only [ContinuousMapZero.comp_apply, ContinuousMapZero.coe_mk, ContinuousMap.coe_mk, StarAlgHom.ofId_apply, halg.dist_eq, x'] congr! 2 all_goals ext; exact haf.left_inv _ |>.symm diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index ff14e3c5dd92ea..be142dd60e974d 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -873,7 +873,7 @@ lemma cfcₙ_eq_cfc [ContinuousFunctionalCalculus R A p] [ContinuousMapZero.Uniq by_cases ha : p a · have hf' := hf.mono <| spectrum_subset_quasispectrum R a rw [cfc_apply f a ha hf', cfcₙ_apply f a hf, cfcₙHom_eq_cfcₙHom_of_cfcHom, cfcₙHom_of_cfcHom] - dsimp only [NonUnitalStarAlgHom.comp_apply, toContinuousMapHom_apply, + dsimp only [NonUnitalStarAlgHom.comp_apply, NonUnitalStarAlgHom.coe_coe, compStarAlgHom'_apply] congr · simp [cfc_apply_of_not_predicate a ha, cfcₙ_apply_of_not_predicate (R := R) a ha] diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean index 99805af4c52965..035cce82a04c39 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean @@ -262,14 +262,14 @@ lemma toNNReal_mul_add_neg_mul_add_mul_neg_eq (f g : C(X, ℝ)₀) : ((f * g).toNNReal + (-f).toNNReal * g.toNNReal + f.toNNReal * (-g).toNNReal) = ((-(f * g)).toNNReal + f.toNNReal * g.toNNReal + (-f).toNNReal * (-g).toNNReal) := by apply toContinuousMap_injective - simpa only [← toContinuousMapHom_apply, map_add, map_mul, map_neg, toContinuousMapHom_toNNReal] + simpa only [map_add, map_mul, map_neg, toContinuousMapHom_toNNReal] using! (f : C(X, ℝ)).toNNReal_mul_add_neg_mul_add_mul_neg_eq g lemma toNNReal_add_add_neg_add_neg_eq (f g : C(X, ℝ)₀) : ((f + g).toNNReal + (-f).toNNReal + (-g).toNNReal) = ((-(f + g)).toNNReal + f.toNNReal + g.toNNReal) := by apply toContinuousMap_injective - simpa only [← toContinuousMapHom_apply, map_add, map_mul, map_neg, toContinuousMapHom_toNNReal] + simpa only [map_add, map_mul, map_neg, toContinuousMapHom_toNNReal] using! (f : C(X, ℝ)).toNNReal_add_add_neg_add_neg_eq g end ContinuousMapZero diff --git a/Mathlib/Analysis/RCLike/BoundedContinuous.lean b/Mathlib/Analysis/RCLike/BoundedContinuous.lean index 4570eefe1e7e14..1dc8f44d0cbef7 100644 --- a/Mathlib/Analysis/RCLike/BoundedContinuous.lean +++ b/Mathlib/Analysis/RCLike/BoundedContinuous.lean @@ -32,7 +32,7 @@ theorem restrict_toContinuousMap_eq_toContinuousMapStar_restrict (ofRealAm.compLeftContinuous ℝ continuous_ofReal) := by ext g simp only [Subalgebra.mem_map, Subalgebra.mem_comap, Subalgebra.mem_restrictScalars, - StarSubalgebra.mem_toSubalgebra, toContinuousMapₐ_apply, StarSubalgebra.mem_map] + StarSubalgebra.mem_toSubalgebra, StarSubalgebra.mem_map] constructor · intro ⟨x, hxA, hxg⟩ use (@ofRealAm 𝕜 _).compLeftContinuousBounded ℝ lipschitzWith_ofReal x, hxA diff --git a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean index 9225e1d9bdca95..69d07a5fe3f10b 100644 --- a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean +++ b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean @@ -329,7 +329,7 @@ def toContinuousMapHom [StarRing R] [ContinuousStar R] : C(X, R)₀ →⋆ₙₐ map_mul' _ _ := rfl map_star' _ := rfl -lemma coe_toContinuousMapHom [StarRing R] [ContinuousStar R] : +@[simp] lemma coe_toContinuousMapHom [StarRing R] [ContinuousStar R] : ⇑(toContinuousMapHom (X := X) (R := R)) = (↑) := rfl diff --git a/Mathlib/Topology/ContinuousMap/Defs.lean b/Mathlib/Topology/ContinuousMap/Defs.lean index e8d9692c28c740..f3a961ad2e07de 100644 --- a/Mathlib/Topology/ContinuousMap/Defs.lean +++ b/Mathlib/Topology/ContinuousMap/Defs.lean @@ -61,7 +61,7 @@ variable {F X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] [FunLike F X variable [ContinuousMapClass F X Y] /-- Coerce a bundled morphism with a `ContinuousMapClass` instance to a `ContinuousMap`. -/ -@[coe] def toContinuousMap (f : F) : C(X, Y) := ⟨f, map_continuous f⟩ +@[coe, reducible] def toContinuousMap (f : F) : C(X, Y) := ⟨f, map_continuous f⟩ instance : CoeTC F C(X, Y) := ⟨toContinuousMap⟩ diff --git a/Mathlib/Topology/ContinuousMap/Ideals.lean b/Mathlib/Topology/ContinuousMap/Ideals.lean index 3cb9dec9560162..b13c306a8ecc46 100644 --- a/Mathlib/Topology/ContinuousMap/Ideals.lean +++ b/Mathlib/Topology/ContinuousMap/Ideals.lean @@ -268,7 +268,7 @@ theorem idealOfSet_ofIdeal_eq_closure (I : Ideal C(X, 𝕜)) : pow_pos (norm_pos_iff.mpr hx.1) 2⟩⟩ convert! I.mul_mem_left (star g) hI ext - simp only [comp_apply, ContinuousMap.coe_coe, coe_mk, algebraMapCLM_apply, map_pow, + simp only [comp_apply, coe_mk, algebraMapCLM_apply, map_pow, mul_apply, star_apply, star_def] simp only [RCLike.conj_mul] rfl diff --git a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean index d3a0f9317126f0..2b8c165c02034c 100644 --- a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean @@ -632,10 +632,10 @@ lemma ContinuousMapZero.adjoin_id_dense (s : Set 𝕜) [Fact (0 ∈ s)] ← isClosedEmbedding_toContinuousMap.injective.preimage_image (closure _), ← isClosedEmbedding_toContinuousMap.closure_image_eq, ← coe_toContinuousMapHom, ← NonUnitalStarSubalgebra.coe_map, NonUnitalStarAlgHom.map_adjoin_singleton, - toContinuousMapHom_apply, toContinuousMap_id, + coe_toContinuousMapHom, toContinuousMap_id, ← ContinuousMap.ker_evalStarAlgHom_eq_closure_adjoin_id s h0'] apply Set.eq_univ_of_forall fun f ↦ ?_ - simp only [Set.mem_preimage, toContinuousMapHom_apply, SetLike.mem_coe, RingHom.mem_ker, + simp only [Set.mem_preimage, SetLike.mem_coe, RingHom.mem_ker, ContinuousMap.evalStarAlgHom_apply, ContinuousMap.coe_coe] exact map_zero f diff --git a/Mathlib/Topology/Homotopy/HomotopyGroup.lean b/Mathlib/Topology/Homotopy/HomotopyGroup.lean index 9f469ee3cf1744..3c720fbf834efe 100644 --- a/Mathlib/Topology/Homotopy/HomotopyGroup.lean +++ b/Mathlib/Topology/Homotopy/HomotopyGroup.lean @@ -285,7 +285,7 @@ def fromLoop (i : N) (p : Ω (Ω^ { j // j ≠ i } X x) const) : Ω^ N X x := (Cube.splitAt i), by rintro y ⟨j, Hj⟩ - simp only [ContinuousMap.comp_apply, ContinuousMap.coe_coe, + simp only [ContinuousMap.comp_apply, funSplitAt_apply, ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair] obtain rfl | Hne := eq_or_ne j i diff --git a/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean b/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean index bdf2b1c36414d2..5e833eaa0a3ae7 100644 --- a/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean +++ b/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean @@ -43,14 +43,14 @@ set_option backward.isDefEq.respectTransparency false in @[simp] lemma toSSetObj₁Equiv_apply_zero (s : toSSet.obj X _⦋1⦌) : X.toSSetObj₁Equiv s 0 = toSSetObj₀Equiv ((toSSet.obj X).δ 1 s) := by - simp [toSSetObj₀Equiv, toSSetObj₁Equiv, + simp [toSSetObj₀Equiv, toSSetObj₁Equiv, -ContinuousMap.coe_mk, Subsingleton.elim (default : stdSimplex ℝ (Fin 1)) (stdSimplex.vertex 0)] set_option backward.isDefEq.respectTransparency false in @[simp] lemma toSSetObj₁Equiv_apply_one (s : toSSet.obj X _⦋1⦌) : X.toSSetObj₁Equiv s 1 = toSSetObj₀Equiv ((toSSet.obj X).δ 0 s) := by - simp [toSSetObj₀Equiv, toSSetObj₁Equiv, + simp [toSSetObj₀Equiv, toSSetObj₁Equiv, -ContinuousMap.coe_mk, Subsingleton.elim (default : stdSimplex ℝ (Fin 1)) (stdSimplex.vertex 0)] @[simp] From 3eb2cbf91c0e2ce5fddf184f5d5b0457a210585e Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Tue, 16 Jun 2026 13:55:01 +0000 Subject: [PATCH 0067/1300] feat: define the closed unit disc in the complex numbers (#40511) The API is a minimally-edited copy-paste of that which already exists for `Complex.UnitDisc`. Upstreaming this from https://alexkontorovich.github.io/CoveringSpacesProject/web/ where it is called `Complex.disk`. Co-authored-by: AlexKontorovich <58564076+AlexKontorovich@users.noreply.github.com> --- Mathlib/Analysis/Complex/UnitDisc/Basic.lean | 271 +++++++++++++++++-- Mathlib/Analysis/Normed/Field/UnitBall.lean | 4 + 2 files changed, 246 insertions(+), 29 deletions(-) diff --git a/Mathlib/Analysis/Complex/UnitDisc/Basic.lean b/Mathlib/Analysis/Complex/UnitDisc/Basic.lean index 94f936987ebc4f..e6ce3a7c5e48fb 100644 --- a/Mathlib/Analysis/Complex/UnitDisc/Basic.lean +++ b/Mathlib/Analysis/Complex/UnitDisc/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Complex.Circle public import Mathlib.Analysis.Normed.Module.Ball.Action +public import Mathlib.Algebra.Group.NatPowAssoc public import Mathlib.Algebra.Group.PNatPowAssoc /-! @@ -29,7 +30,13 @@ namespace Complex def UnitDisc : Type := Subsemigroup.unitBall ℂ deriving TopologicalSpace +/-- The complex closed unit disc, denoted as `𝕔𝔻` within the Complex namespace -/ +def UnitClosedDisc : Type := + Submonoid.unitClosedBall ℂ deriving TopologicalSpace + @[inherit_doc] scoped[Complex.UnitDisc] notation "𝔻" => Complex.UnitDisc +@[inherit_doc] scoped[Complex.UnitDisc] notation "𝕔𝔻" => Complex.UnitClosedDisc + open UnitDisc namespace UnitDisc @@ -171,35 +178,6 @@ theorem coe_circle_smul (z : Circle) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) : @[deprecated (since := "2026-01-06")] alias coe_smul_circle := coe_circle_smul -instance instMulActionClosedBall : MulAction (closedBall (0 : ℂ) 1) 𝔻 := - inferInstanceAs <| MulAction (closedBall _ _) (ball _ _) - -instance instIsScalarTower_closedBall_closedBall : - IsScalarTower (closedBall (0 : ℂ) 1) (closedBall (0 : ℂ) 1) 𝔻 := - inferInstanceAs <| IsScalarTower (closedBall _ _) (closedBall _ _) (ball _ _) - -instance instIsScalarTower_closedBall : IsScalarTower (closedBall (0 : ℂ) 1) 𝔻 𝔻 := - inferInstanceAs <| IsScalarTower (closedBall _ _) (ball _ _) (ball _ _) - -instance instSMulCommClass_closedBall_left : SMulCommClass (closedBall (0 : ℂ) 1) 𝔻 𝔻 := - ⟨fun _ _ _ => Subtype.ext <| mul_left_comm _ _ _⟩ - -instance instSMulCommClass_closedBall_right : SMulCommClass 𝔻 (closedBall (0 : ℂ) 1) 𝔻 := - SMulCommClass.symm _ _ _ - -instance instSMulCommClass_circle_closedBall : SMulCommClass Circle (closedBall (0 : ℂ) 1) 𝔻 := - inferInstanceAs <| SMulCommClass (sphere _ _) (closedBall _ _) (ball _ _) - -instance instSMulCommClass_closedBall_circle : SMulCommClass (closedBall (0 : ℂ) 1) Circle 𝔻 := - SMulCommClass.symm _ _ _ - -@[simp, norm_cast] -theorem coe_closedBall_smul (z : closedBall (0 : ℂ) 1) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) := - rfl - -@[deprecated (since := "2026-01-06")] -alias coe_smul_closedBall := coe_closedBall_smul - instance : Pow UnitDisc ℕ+ where pow z n := ⟨z ^ (n : ℕ), by simp [pow_lt_one_iff_of_nonneg, z.norm_lt_one]⟩ @@ -302,4 +280,239 @@ theorem conj_mul (z w : 𝔻) : star (z * w) = star z * star w := end UnitDisc +namespace UnitClosedDisc + +/-- Coercion to `ℂ`. -/ +@[coe] protected def coe : 𝕔𝔻 → ℂ := Subtype.val + +instance : MonoidWithZero 𝕔𝔻 := inferInstanceAs <| MonoidWithZero (closedBall _ _) + +instance : IsCancelMulZero 𝕔𝔻 := + inferInstanceAs <| IsCancelMulZero (closedBall _ _) + +instance : HasDistribNeg 𝕔𝔻 := + inferInstanceAs <| HasDistribNeg (closedBall _ _) + +instance : Coe 𝕔𝔻 ℂ := ⟨UnitClosedDisc.coe⟩ + +@[ext] +theorem coe_injective : Injective ((↑) : 𝕔𝔻 → ℂ) := + Subtype.coe_injective + +@[simp, norm_cast] +theorem coe_inj {z w : 𝕔𝔻} : (z : ℂ) = w ↔ z = w := Subtype.val_inj + +@[fun_prop] +theorem isEmbedding_coe : Topology.IsEmbedding ((↑) : 𝕔𝔻 → ℂ) := .subtypeVal + +@[fun_prop] +theorem continuous_coe : Continuous ((↑) : 𝕔𝔻 → ℂ) := isEmbedding_coe.continuous + +theorem norm_le_one (z : 𝕔𝔻) : ‖(z : ℂ)‖ ≤ 1 := + mem_closedBall_zero_iff.1 z.2 + +theorem sq_norm_lt_one (z : 𝕔𝔻) : ‖(z : ℂ)‖ ^ 2 ≤ 1 := by + rw [sq_le_one_iff_abs_le_one, abs_norm] + exact z.norm_le_one + +theorem normSq_lt_one (z : 𝕔𝔻) : normSq z ≤ 1 := by + rw [← Complex.norm_mul_self_eq_normSq, ← sq] + exact z.sq_norm_lt_one + +@[simp, norm_cast] +theorem coe_mul (z w : 𝕔𝔻) : ↑(z * w) = (z * w : ℂ) := + rfl + +@[simp, norm_cast] +theorem coe_neg (z : 𝕔𝔻) : ↑(-z) = (-z : ℂ) := rfl + +/-- A constructor that assumes `‖z‖ < 1` instead of `dist z 0 < 1` and returns an element +of `𝕔𝔻` instead of `↥Metric.ball (0 : ℂ) 1`. -/ +def mk (z : ℂ) (hz : ‖z‖ ≤ 1) : 𝕔𝔻 := + ⟨z, mem_closedBall_zero_iff.2 hz⟩ + +instance : CanLift ℂ 𝕔𝔻 (↑) (‖·‖ ≤ 1) where + prf z hz := ⟨mk z hz, rfl⟩ + +/-- A cases eliminator that makes `cases z` use `UnitClosedDisc.mk` instead of `Subtype.mk`. -/ +@[elab_as_elim, cases_eliminator] +protected def casesOn {motive : 𝕔𝔻 → Sort*} (mk : ∀ z hz, motive (.mk z hz)) (z : 𝕔𝔻) : + motive z := + mk z z.norm_le_one + +@[simp] +theorem casesOn_mk {motive : 𝕔𝔻 → Sort*} (mk' : ∀ z hz, motive (.mk z hz)) {z : ℂ} (hz : ‖z‖ ≤ 1) : + (mk z hz).casesOn mk' = mk' z hz := + rfl + +@[simp] +theorem coe_mk (z : ℂ) (hz : ‖z‖ ≤ 1) : (mk z hz : ℂ) = z := + rfl + +@[simp] +theorem mk_coe (z : 𝕔𝔻) (hz : ‖(z : ℂ)‖ ≤ 1 := z.norm_le_one) : mk z hz = z := + Subtype.eta _ _ + +@[simp] +theorem mk_inj {z w : ℂ} (hz : ‖z‖ ≤ 1) (hw : ‖w‖ ≤ 1) : mk z hz = mk w hw ↔ z = w := + Subtype.mk_eq_mk + +protected theorem «forall» {p : 𝕔𝔻 → Prop} : (∀ z, p z) ↔ ∀ z hz, p (mk z hz) := + ⟨fun h z hz ↦ h (mk z hz), fun h z ↦ h z z.norm_le_one⟩ + +protected theorem «exists» {p : 𝕔𝔻 → Prop} : (∃ z, p z) ↔ ∃ z hz, p (mk z hz) := + ⟨fun ⟨z, hz⟩ ↦ ⟨z, z.norm_le_one, hz⟩, fun ⟨z, hz, h⟩ ↦ ⟨mk z hz, h⟩⟩ + +@[simp] +theorem mk_neg (z : ℂ) (hz : ‖-z‖ ≤ 1) : mk (-z) hz = -mk z (norm_neg z ▸ hz) := + rfl + +@[simp] +theorem coe_zero : ((0 : 𝕔𝔻) : ℂ) = 0 := + rfl + +@[simp] +theorem coe_eq_zero {z : 𝕔𝔻} : (z : ℂ) = 0 ↔ z = 0 := + coe_injective.eq_iff' coe_zero + +@[simp] theorem mk_zero : mk 0 (by simp) = 0 := rfl + +@[simp] theorem mk_eq_zero {z : ℂ} (hz : ‖z‖ ≤ 1) : mk z hz = 0 ↔ z = 0 := by simp [← coe_inj] + +@[simp] +theorem coe_one : ((1 : 𝕔𝔻) : ℂ) = 1 := + rfl + +@[simp] +theorem coe_eq_one {z : 𝕔𝔻} : (z : ℂ) = 1 ↔ z = 1 := + coe_injective.eq_iff' coe_one + +@[simp] theorem mk_one : mk 1 (by simp) = 1 := rfl + +@[simp] theorem mk_eq_one {z : ℂ} (hz : ‖z‖ ≤ 1) : mk z hz = 1 ↔ z = 1 := by simp [← coe_inj] + +instance : Inhabited 𝕔𝔻 := + ⟨0⟩ + +instance : MulAction Circle 𝕔𝔻 := + inferInstanceAs <| MulAction (sphere _ _) (closedBall _ _) + +instance : IsScalarTower Circle Circle 𝕔𝔻 := + inferInstanceAs <| IsScalarTower (sphere _ _) (sphere _ _) (closedBall _ _) + +instance : IsScalarTower Circle 𝕔𝔻 𝕔𝔻 := + isScalarTower_sphere_closedBall_closedBall + +instance : SMulCommClass Circle 𝕔𝔻 𝕔𝔻 := + instSMulCommClass_sphere_closedBall_closedBall + +instance : SMulCommClass 𝕔𝔻 Circle 𝕔𝔻 := + SMulCommClass.symm _ _ _ + +instance instMulActionClosedBall : MulAction 𝕔𝔻 𝔻 := + inferInstanceAs <| MulAction (closedBall _ _) (ball _ _) + +instance instIsScalarTower_closedBall_closedBall : + IsScalarTower 𝕔𝔻 𝕔𝔻 𝔻 := + inferInstanceAs <| IsScalarTower (closedBall _ _) (closedBall _ _) (ball _ _) + +instance instIsScalarTower_closedBall : IsScalarTower 𝕔𝔻 𝔻 𝔻 := + inferInstanceAs <| IsScalarTower (closedBall _ _) (ball _ _) (ball _ _) + +instance instSMulCommClass_closedBall_left : SMulCommClass 𝕔𝔻 𝔻 𝔻 := + ⟨fun _ _ _ => Subtype.ext <| mul_left_comm _ _ _⟩ + +instance instSMulCommClass_closedBall_right : SMulCommClass 𝔻 𝕔𝔻 𝔻 := + SMulCommClass.symm _ _ _ + +instance instSMulCommClass_circle_closedBall : SMulCommClass Circle 𝕔𝔻 𝔻 := + inferInstanceAs <| SMulCommClass (sphere _ _) (closedBall _ _) (ball _ _) + +instance instSMulCommClass_closedBall_circle : SMulCommClass 𝕔𝔻 Circle 𝔻 := + SMulCommClass.symm _ _ _ + +@[simp, norm_cast] +theorem coe_closedBall_smul (z : 𝕔𝔻) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) := + rfl + +@[deprecated (since := "2026-01-06")] +alias coe_smul_closedBall := coe_closedBall_smul + +@[simp, norm_cast] +theorem coe_circle_smul (z : Circle) (w : 𝕔𝔻) : ↑(z • w) = (z * w : ℂ) := + rfl + +instance : SMulCommClass 𝕔𝔻 Circle 𝕔𝔻 := + SMulCommClass.symm _ _ _ + +instance : Pow 𝕔𝔻 ℕ where + pow z n := ⟨z ^ n, by simp [pow_le_one₀ (norm_nonneg _) z.norm_le_one]⟩ + +@[simp, norm_cast] +theorem coe_pow (z : 𝕔𝔻) (n : ℕ) : ((z ^ n : 𝕔𝔻) : ℂ) = z ^ (n : ℕ) := rfl + +@[fun_prop] +theorem continuous_pow (n : ℕ) : Continuous (· ^ n : 𝕔𝔻 → 𝕔𝔻) := by + simp only [isEmbedding_coe.continuous_iff, Function.comp_def, coe_pow] + fun_prop + +instance : NatPowAssoc 𝕔𝔻 where + npow_add m n z := mod_cast pow_add (z : ℂ) m n + npow_one z := by simp [← coe_inj] + npow_zero z := by simp [← coe_inj] + +/-- Real part of a point of the unit disc. -/ +def re (z : 𝕔𝔻) : ℝ := + Complex.re z + +/-- Imaginary part of a point of the unit disc. -/ +def im (z : 𝕔𝔻) : ℝ := + Complex.im z + +@[simp, norm_cast] +theorem re_coe (z : 𝕔𝔻) : (z : ℂ).re = z.re := + rfl + +@[simp, norm_cast] +theorem im_coe (z : 𝕔𝔻) : (z : ℂ).im = z.im := + rfl + +@[simp] +theorem re_neg (z : 𝕔𝔻) : (-z).re = -z.re := + rfl + +@[simp] +theorem im_neg (z : 𝕔𝔻) : (-z).im = -z.im := + rfl + +@[simp] theorem re_zero : re 0 = 0 := rfl +@[simp] theorem im_zero : im 0 = 0 := rfl + +/-- Conjugate point of the unit disc. -/ +instance : Star 𝕔𝔻 where + star z := mk (conj z) <| (norm_conj z).symm ▸ z.norm_le_one + +@[simp] theorem coe_star (z : 𝕔𝔻) : (↑(star z) : ℂ) = conj ↑z := rfl + +@[simp] +protected theorem star_eq_zero {z : 𝕔𝔻} : star z = 0 ↔ z = 0 := by + simp [← coe_eq_zero] + +@[simp] +protected theorem star_zero : star (0 : 𝕔𝔻) = 0 := by simp + +instance : InvolutiveStar 𝕔𝔻 where + star_involutive z := by ext; simp + +@[simp] protected theorem star_neg (z : 𝕔𝔻) : star (-z) = -(star z) := rfl + +@[simp] protected theorem re_star (z : 𝕔𝔻) : (star z).re = z.re := rfl + +@[simp] protected theorem im_star (z : 𝕔𝔻) : (star z).im = -z.im := rfl + +instance : StarMul 𝕔𝔻 where + star_mul z w := coe_injective <| by simp [mul_comm] + +end UnitClosedDisc + end Complex diff --git a/Mathlib/Analysis/Normed/Field/UnitBall.lean b/Mathlib/Analysis/Normed/Field/UnitBall.lean index 99252ea7420fb0..16d2e409f1cf80 100644 --- a/Mathlib/Analysis/Normed/Field/UnitBall.lean +++ b/Mathlib/Analysis/Normed/Field/UnitBall.lean @@ -141,6 +141,10 @@ def Submonoid.unitClosedBall (𝕜 : Type*) [SeminormedRing 𝕜] [NormOneClass carrier := closedBall 0 1 one_mem' := mem_closedBall_zero_iff.2 norm_one.le } +@[simp] lemma Submonoid.mem_unitClosedBall (𝕜 : Type*) [SeminormedRing 𝕜] [NormOneClass 𝕜] {x : 𝕜} : + x ∈ Submonoid.unitClosedBall 𝕜 ↔ ‖x‖ ≤ 1 := by + simp [Submonoid.unitClosedBall] + instance Metric.unitClosedBall.instMonoid [SeminormedRing 𝕜] [NormOneClass 𝕜] : Monoid (closedBall (0 : 𝕜) 1) := inferInstanceAs <| Monoid (Submonoid.unitClosedBall 𝕜) From b1013c671ddf090973ec6cf555d9941c21a979bf Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:06:19 +0000 Subject: [PATCH 0068/1300] feat: tag map_mono and comap_mono with gcongr (#40560) --- Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean | 1 + Mathlib/Algebra/Algebra/Subalgebra/Basic.lean | 1 + Mathlib/Algebra/Group/Subgroup/Map.lean | 2 +- Mathlib/Algebra/Star/NonUnitalSubalgebra.lean | 1 + Mathlib/Algebra/Star/Subalgebra.lean | 1 + Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean | 1 + Mathlib/Combinatorics/SimpleGraph/Maps.lean | 2 ++ Mathlib/Data/Multiset/MapFold.lean | 2 ++ Mathlib/FieldTheory/IntermediateField/Basic.lean | 1 + Mathlib/GroupTheory/FiniteIndexNormalSubgroup.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean | 1 + Mathlib/MeasureTheory/MeasurableSpace/Basic.lean | 2 ++ Mathlib/RingTheory/Congruence/Basic.lean | 1 + Mathlib/RingTheory/Ideal/Maps.lean | 2 ++ Mathlib/Topology/Sets/Opens.lean | 1 + 15 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index 6ba167e51d4ba3..49483234759347 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean @@ -344,6 +344,7 @@ def map (f : F) (S : NonUnitalSubalgebra R A) : NonUnitalSubalgebra R B := rcases hb with ⟨a, ha, rfl⟩ exact map_smulₛₗ f r a ▸ Set.mem_image_of_mem f (S.smul_mem' r ha) } +@[gcongr] theorem map_mono {S₁ S₂ : NonUnitalSubalgebra R A} {f : F} : S₁ ≤ S₂ → (map f S₁ : NonUnitalSubalgebra R B) ≤ map f S₂ := Set.image_mono diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean index f78f5e49160742..a34f06fcba9763 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean @@ -417,6 +417,7 @@ def map (f : A →ₐ[R] B) (S : Subalgebra R A) : Subalgebra R B := { S.toSubsemiring.map (f : A →+* B) with algebraMap_mem' := fun r => f.commutes r ▸ Set.mem_image_of_mem _ (S.algebraMap_mem r) } +@[gcongr] theorem map_mono {S₁ S₂ : Subalgebra R A} {f : A →ₐ[R] B} : S₁ ≤ S₂ → S₁.map f ≤ S₂.map f := Set.image_mono diff --git a/Mathlib/Algebra/Group/Subgroup/Map.lean b/Mathlib/Algebra/Group/Subgroup/Map.lean index 2d8825b6258ce9..d05286dc6eca13 100644 --- a/Mathlib/Algebra/Group/Subgroup/Map.lean +++ b/Mathlib/Algebra/Group/Subgroup/Map.lean @@ -82,7 +82,7 @@ theorem coe_comap (K : Subgroup N) (f : G →* N) : (K.comap f : Set G) = f ⁻ theorem mem_comap {K : Subgroup N} {f : G →* N} {x : G} : x ∈ K.comap f ↔ f x ∈ K := Iff.rfl -@[to_additive] +@[to_additive (attr := gcongr)] theorem comap_mono {f : G →* N} {K K' : Subgroup N} : K ≤ K' → comap f K ≤ comap f K' := preimage_mono diff --git a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean index 00eb073f8ede15..4ff88552ac4834 100644 --- a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean @@ -343,6 +343,7 @@ def map (f : F) (S : NonUnitalStarSubalgebra R A) : NonUnitalStarSubalgebra R B toNonUnitalSubalgebra := S.toNonUnitalSubalgebra.map (f : A →ₙₐ[R] B) star_mem' := by rintro _ ⟨a, ha, rfl⟩; exact ⟨star a, star_mem (s := S) ha, map_star f a⟩ +@[gcongr] theorem map_mono {S₁ S₂ : NonUnitalStarSubalgebra R A} {f : F} : S₁ ≤ S₂ → (map f S₁ : NonUnitalStarSubalgebra R B) ≤ map f S₂ := Set.image_mono diff --git a/Mathlib/Algebra/Star/Subalgebra.lean b/Mathlib/Algebra/Star/Subalgebra.lean index 993ecdcd7aaba0..d729e0d61d2a4f 100644 --- a/Mathlib/Algebra/Star/Subalgebra.lean +++ b/Mathlib/Algebra/Star/Subalgebra.lean @@ -273,6 +273,7 @@ theorem map_le_iff_le_comap {S : StarSubalgebra R A} {f : A →⋆ₐ[R] B} {U : theorem gc_map_comap (f : A →⋆ₐ[R] B) : GaloisConnection (map f) (comap f) := fun _S _U => map_le_iff_le_comap +@[gcongr] theorem comap_mono {S₁ S₂ : StarSubalgebra R B} {f : A →⋆ₐ[R] B} : S₁ ≤ S₂ → S₁.comap f ≤ S₂.comap f := Set.preimage_mono diff --git a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean index f9d148751510b9..d27f71fc9cc941 100644 --- a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean @@ -387,6 +387,7 @@ def comap (S : Subgroupoid D) : Subgroupoid C where simp only [mem_setOf, Functor.map_comp] apply S.mul <;> assumption +@[gcongr] theorem comap_mono (S T : Subgroupoid D) : S ≤ T → comap φ S ≤ comap φ T := fun ST _ => @ST ⟨_, _, _⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index e2aec80aab3607..07a8cc9ab92df0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -101,6 +101,7 @@ theorem map_adj_apply' {f : V → W} (hadj : G.Adj u v) (hne : f u ≠ f v) : (G.map f).Adj (f u) (f v) := ⟨hne, u, v, hadj, rfl, rfl⟩ +@[gcongr] theorem map_monotone (f : V → W) : Monotone (SimpleGraph.map f) := by rintro G G' h z1 z2 ⟨huv, u, v, ha, rfl, rfl⟩ exact ⟨huv, _, _, h ha, rfl, rfl⟩ @@ -151,6 +152,7 @@ lemma comap_symm (G : SimpleGraph V) (e : V ≃ W) : lemma map_symm (G : SimpleGraph W) (e : V ≃ W) : G.map e.symm.toEmbedding = G.comap e.toEmbedding := by rw [← comap_symm, e.symm_symm] +@[gcongr] theorem comap_monotone (f : V ↪ W) : Monotone (SimpleGraph.comap f) := fun _ _ h _ _ ha ↦ h ha diff --git a/Mathlib/Data/Multiset/MapFold.lean b/Mathlib/Data/Multiset/MapFold.lean index f343e6abbee27c..78ddf10a56632d 100644 --- a/Mathlib/Data/Multiset/MapFold.lean +++ b/Mathlib/Data/Multiset/MapFold.lean @@ -183,8 +183,10 @@ theorem map_lt_map {f : α → β} {s t : Multiset α} (h : s < t) : s.map f < t rw [← s.card_map f, ← t.card_map f] exact card_le_card H +@[gcongr] theorem map_mono (f : α → β) : Monotone (map f) := fun _ _ => map_le_map +@[gcongr] theorem map_strictMono (f : α → β) : StrictMono (map f) := fun _ _ => map_lt_map @[simp, gcongr] diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index 6867c9c2e5e58a..ca54cf81abab2a 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -495,6 +495,7 @@ theorem map_map {K L₁ L₂ L₃ : Type*} [Field K] [Field L₁] [Algebra K L (E.map f).map g = E.map (g.comp f) := SetLike.coe_injective <| Set.image_image _ _ _ +@[gcongr] theorem map_mono (f : L →ₐ[K] L') {S T : IntermediateField K L} (h : S ≤ T) : S.map f ≤ T.map f := SetLike.coe_mono (Set.image_mono h) diff --git a/Mathlib/GroupTheory/FiniteIndexNormalSubgroup.lean b/Mathlib/GroupTheory/FiniteIndexNormalSubgroup.lean index 1330053ba514bd..1376102a527800 100644 --- a/Mathlib/GroupTheory/FiniteIndexNormalSubgroup.lean +++ b/Mathlib/GroupTheory/FiniteIndexNormalSubgroup.lean @@ -138,7 +138,7 @@ theorem toSubgroup_comap (f : G →* H) (K : FiniteIndexNormalSubgroup H) : ((comap f K : FiniteIndexNormalSubgroup G) : Subgroup G) = (K : Subgroup H).comap f := rfl -@[to_additive] +@[to_additive (attr := gcongr)] theorem comap_mono (f : G →* H) {K L : FiniteIndexNormalSubgroup H} (h : K ≤ L) : comap f K ≤ comap f L := fun _ hx ↦ h hx diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index 3ee18f671c5e45..b4f59a92546e88 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -736,6 +736,7 @@ theorem coe_comap (f : P₁ →ᵃ[k] P₂) (s : AffineSubspace k P₂) : (s.com theorem mem_comap {f : P₁ →ᵃ[k] P₂} {x : P₁} {s : AffineSubspace k P₂} : x ∈ s.comap f ↔ f x ∈ s := Iff.rfl +@[gcongr] theorem comap_mono {f : P₁ →ᵃ[k] P₂} {s t : AffineSubspace k P₂} : s ≤ t → s.comap f ≤ t.comap f := preimage_mono diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean index dd4131f6d51f18..f092dbf255e704 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean @@ -113,11 +113,13 @@ theorem gc_comap_map (f : α → β) : theorem map_mono (h : m₁ ≤ m₂) : m₁.map f ≤ m₂.map f := (gc_comap_map f).monotone_u h +@[gcongr] theorem monotone_map : Monotone (MeasurableSpace.map f) := fun _ _ => map_mono theorem comap_mono (h : m₁ ≤ m₂) : m₁.comap g ≤ m₂.comap g := (gc_comap_map g).monotone_l h +@[gcongr] theorem monotone_comap : Monotone (MeasurableSpace.comap g) := fun _ _ h => comap_mono h @[simp] diff --git a/Mathlib/RingTheory/Congruence/Basic.lean b/Mathlib/RingTheory/Congruence/Basic.lean index 10c01c3f5100f1..ed6041e7d612d6 100644 --- a/Mathlib/RingTheory/Congruence/Basic.lean +++ b/Mathlib/RingTheory/Congruence/Basic.lean @@ -142,6 +142,7 @@ instance : LE (RingCon R) where /-- Definition of `≤` for congruence relations. -/ theorem le_def : c ≤ d ↔ ∀ {x y}, c x y → d x y := .rfl +@[gcongr] theorem comap_mono {R' : Type*} [Add R'] [Mul R'] {F : Type*} [FunLike F R R'] [AddHomClass F R R'] [MulHomClass F R R'] {J J' : RingCon R'} {f : F} (h : J ≤ J') : diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 8b2013443e57fb..523c5a0fdc457d 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -62,6 +62,7 @@ lemma map_coe [RingHomClass F R S] (I : Ideal R) : I.map (f : R →+* S) = I.map variable {f} +@[gcongr] theorem map_mono (h : I ≤ J) : map f I ≤ map f J := span_mono <| Set.image_mono h @@ -78,6 +79,7 @@ theorem map_le_iff_le_comap [RingHomClass F R S] : map f I ≤ K ↔ I ≤ comap theorem mem_comap [RingHomClass F R S] {x} : x ∈ comap f K ↔ f x ∈ K := Iff.rfl +@[gcongr] theorem comap_mono [RingHomClass F R S] (h : K ≤ L) : comap f K ≤ comap f L := Set.preimage_mono fun _ hx => h hx diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index f15b486678b9f6..13e02d1439fc4c 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -411,6 +411,7 @@ def comap (f : C(α, β)) : FrameHom (Opens β) (Opens α) where theorem comap_id : comap (ContinuousMap.id α) = FrameHom.id _ := FrameHom.ext fun _ => ext rfl +@[gcongr] theorem comap_mono (f : C(α, β)) {s t : Opens β} (h : s ≤ t) : comap f s ≤ comap f t := OrderHomClass.mono (comap f) h From c53555075e0c49c3963699412f35799e7e6a43bd Mon Sep 17 00:00:00 2001 From: Yifan Bai <110049727+TTony2019@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:57:08 +0000 Subject: [PATCH 0069/1300] feat: Add `AffineEquiv.image_intrinsicInterior` (#38275) ## Summary This PR generalizes the existing lemma `AffineIsometry.image_intrinsicInterior` to the setting of affine equivalences, yielding the corresponding result `AffineEquiv.image_intrinsicInterior`. Since affine equivalences are more general than affine isometries, the proof requires an additional finite-dimensionality assumption. The key extra input is that in finite-dimensional spaces, an affine equivalence induces a homeomorphism via `AffineEquiv.toHomeomorphOfFiniteDimensional`, so the assumptions are adjusted accordingly. Apart from these extra assumptions, the argument is essentially the same as for `AffineIsometry.image_intrinsicInterior`. ## Collaboration This PR was developed together with @imathwy. Co-authored-by: imathwy <148067791+imathwy@users.noreply.github.com> Co-authored-by: PrinChern <148067791+imathwy@users.noreply.github.com> --- Mathlib/Analysis/Convex/Intrinsic.lean | 183 ++++++++++++++---- .../Normed/Module/FiniteDimension.lean | 32 ++- .../LinearAlgebra/AffineSpace/Restrict.lean | 20 ++ Mathlib/Topology/Algebra/AffineSubspace.lean | 51 ++++- Mathlib/Topology/Homeomorph/Defs.lean | 38 ++++ Mathlib/Topology/Homeomorph/Lemmas.lean | 11 -- 6 files changed, 282 insertions(+), 53 deletions(-) diff --git a/Mathlib/Analysis/Convex/Intrinsic.lean b/Mathlib/Analysis/Convex/Intrinsic.lean index 9f0d2177026522..9479339d6c71c4 100644 --- a/Mathlib/Analysis/Convex/Intrinsic.lean +++ b/Mathlib/Analysis/Convex/Intrinsic.lean @@ -29,8 +29,8 @@ same as the topological closure. ## Results The main results are: -* `AffineIsometry.image_intrinsicInterior`/`AffineIsometry.image_intrinsicFrontier`/ - `AffineIsometry.image_intrinsicClosure`: Intrinsic interiors/frontiers/closures commute with +* `AffineIsometry.intrinsicInterior_image`/`AffineIsometry.intrinsicFrontier_image`/ + `AffineIsometry.intrinsicClosure_image`: Intrinsic interiors/frontiers/closures commute with taking the image under an affine isometry. * `Set.Nonempty.intrinsicInterior`: The intrinsic interior of a nonempty convex set is nonempty. @@ -217,8 +217,99 @@ theorem intrinsicClosure_eq_closure_inter_affineSpan (s : Set P) : rw [Subtype.range_coe] apply subset_affineSpan +section ImageOfHomeomorphAffineSpan + +variable [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace Q] [AddTorsor W Q] + {f : P → Q} {s : Set P} + +/-- If `f` agrees with a homeomorphism between the affine spans of `s` and `f '' s`, then pulling +`f '' s` back to the affine span of `s` recovers `s` itself. -/ +private theorem preimage_image_eq_of_homeomorph_affineSpan + (e : affineSpan 𝕜 s → affineSpan 𝕜 (f '' s)) (he_homeo : IsHomeomorph e) + (he : ∀ x, (e x : Q) = f x) : + (f ∘ (↑)) ⁻¹' (f '' s) = ((↑) ⁻¹' s : Set <| affineSpan 𝕜 s) := by + ext x + refine ⟨fun ⟨_, hy, hfy⟩ ↦ ?_ , fun hx ↦ ⟨_, hx, rfl⟩⟩ + change (x : P) ∈ s + rwa [exists_eq_subtype_mk_iff.mp ⟨subset_affineSpan 𝕜 s hy, he_homeo.injective <| Subtype.ext <| + by simpa [he] using hfy.symm⟩] + +variable (e : [Nonempty s] → affineSpan 𝕜 s → affineSpan 𝕜 (f '' s)) + (he_homeo : [Nonempty s] → IsHomeomorph e) (he : [Nonempty s] → ∀ x, e x = f x) + +include e he_homeo he + +/-- Naturality of intrinsic interior under a map whose induced map on affine spans is a +homeomorphism. It is introduced here to share the proof of the affine equivalence and affine +isometry versions below. -/ +private theorem intrinsicInterior_image_of_homeomorph_affineSpan : + intrinsicInterior 𝕜 (f '' s) = f '' intrinsicInterior 𝕜 s := by + rcases s.eq_empty_or_nonempty with rfl | hs + · simp + · haveI : Nonempty s := hs.to_subtype + rw [intrinsicInterior, ← image_interior_preimage_comp e he_homeo, + (funext he : (↑) ∘ e = f ∘ (↑)), + preimage_image_eq_of_homeomorph_affineSpan e he_homeo he, image_comp]; rfl + +/-- Naturality of intrinsic frontier under a map whose induced map on affine spans is a +homeomorphism. It is introduced here to share the proof of the affine equivalence and affine +isometry versions below. -/ +private theorem intrinsicFrontier_image_of_homeomorph_affineSpan : + intrinsicFrontier 𝕜 (f '' s) = f '' intrinsicFrontier 𝕜 s := by + rcases s.eq_empty_or_nonempty with rfl | hs + · simp + · haveI : Nonempty s := hs.to_subtype + rw [intrinsicFrontier, ← image_frontier_preimage_comp e he_homeo, + (funext he : (↑) ∘ e = f ∘ (↑)), + preimage_image_eq_of_homeomorph_affineSpan e he_homeo he, image_comp]; rfl + +/-- Naturality of intrinsic closure under a map whose induced map on affine spans is a +homeomorphism. It is introduced here to share the proof of the affine equivalence and affine +isometry versions below. -/ +private theorem intrinsicClosure_image_of_homeomorph_affineSpan : + intrinsicClosure 𝕜 (f '' s) = f '' intrinsicClosure 𝕜 s := by + rcases s.eq_empty_or_nonempty with rfl | hs + · simp + · haveI : Nonempty s := hs.to_subtype + rw [intrinsicClosure, ← image_closure_preimage_comp e he_homeo, + (funext he : (↑) ∘ e = f ∘ (↑)), + preimage_image_eq_of_homeomorph_affineSpan e he_homeo he, image_comp]; rfl + +end ImageOfHomeomorphAffineSpan + end AddTorsor +namespace ContinuousAffineEquiv + +variable [Ring 𝕜] [AddCommGroup V] [AddCommGroup W] [Module 𝕜 V] [Module 𝕜 W] + [TopologicalSpace P] [TopologicalSpace Q] [AddTorsor V P] [AddTorsor W Q] + +@[simp] +theorem intrinsicInterior_image (φ : P ≃ᴬ[𝕜] Q) (s : Set P) : + intrinsicInterior 𝕜 (φ '' s) = φ '' intrinsicInterior 𝕜 s := + let e : [Nonempty s] → (affineSpan 𝕜 s) ≃ᴬ[𝕜] (affineSpan 𝕜 (φ '' s)) := fun [_] => + (φ.affineSubspaceMap (affineSpan 𝕜 s)).trans <| ofEq (map_span φ.toAffineMap s) + intrinsicInterior_image_of_homeomorph_affineSpan + (fun [_] => e.toHomeomorph) (fun [_] => e.toHomeomorph.isHomeomorph) (fun [_] _ => rfl) + +@[simp] +theorem intrinsicFrontier_image (φ : P ≃ᴬ[𝕜] Q) (s : Set P) : + intrinsicFrontier 𝕜 (φ '' s) = φ '' intrinsicFrontier 𝕜 s := + let e : [Nonempty s] → (affineSpan 𝕜 s) ≃ᴬ[𝕜] (affineSpan 𝕜 (φ '' s)) := fun [_] => + (φ.affineSubspaceMap (affineSpan 𝕜 s)).trans <| ofEq (map_span φ.toAffineMap s) + intrinsicFrontier_image_of_homeomorph_affineSpan + (fun [_] => e.toHomeomorph) (fun [_] => e.toHomeomorph.isHomeomorph) (fun [_] _ => rfl) + +@[simp] +theorem intrinsicClosure_image (φ : P ≃ᴬ[𝕜] Q) (s : Set P) : + intrinsicClosure 𝕜 (φ '' s) = φ '' intrinsicClosure 𝕜 s := + let e : [Nonempty s] → (affineSpan 𝕜 s) ≃ᴬ[𝕜] (affineSpan 𝕜 (φ '' s)) := fun [_] => + (φ.affineSubspaceMap (affineSpan 𝕜 s)).trans <| ofEq (map_span φ.toAffineMap s) + intrinsicClosure_image_of_homeomorph_affineSpan + (fun [_] => e.toHomeomorph) (fun [_] => e.toHomeomorph.isHomeomorph) (fun [_] _ => rfl) + +end ContinuousAffineEquiv + namespace AffineIsometry variable [NormedField 𝕜] [SeminormedAddCommGroup V] [SeminormedAddCommGroup W] [NormedSpace 𝕜 V] @@ -226,46 +317,68 @@ variable [NormedField 𝕜] [SeminormedAddCommGroup V] [SeminormedAddCommGroup W [NormedAddTorsor W Q] @[simp] -theorem image_intrinsicInterior (φ : P →ᵃⁱ[𝕜] Q) (s : Set P) : - intrinsicInterior 𝕜 (φ '' s) = φ '' intrinsicInterior 𝕜 s := by - obtain rfl | hs := s.eq_empty_or_nonempty - · simp only [intrinsicInterior_empty, image_empty] - haveI : Nonempty s := hs.to_subtype - let f := ((affineSpan 𝕜 s).isometryEquivMap φ).toHomeomorph - have : φ.toAffineMap ∘ (↑) ∘ f.symm = (↑) := funext isometryEquivMap.apply_symm_apply - rw [intrinsicInterior, intrinsicInterior, ← φ.coe_toAffineMap, ← map_span φ.toAffineMap s, ← this, - ← Function.comp_assoc, image_comp, image_comp, f.symm.image_interior, f.image_symm, - ← preimage_comp, Function.comp_assoc, f.symm_comp_self, AffineIsometry.coe_toAffineMap, - Function.comp_id, preimage_comp, φ.injective.preimage_image] +theorem intrinsicInterior_image (φ : P →ᵃⁱ[𝕜] Q) (s : Set P) : + intrinsicInterior 𝕜 (φ '' s) = φ '' intrinsicInterior 𝕜 s := + let e : [Nonempty s] → (affineSpan 𝕜 s) ≃ᴬ[𝕜] (affineSpan 𝕜 (φ '' s)) := fun [_] => + ((affineSpan 𝕜 s).isometryEquivMap φ).toContinuousAffineEquiv.trans <| ofEq <| + (map_span φ.toAffineMap s).trans <| congrArg _ <| congrArg (· '' s) φ.coe_toAffineMap + intrinsicInterior_image_of_homeomorph_affineSpan + (fun [_] => e.toHomeomorph) (fun [_] => e.toHomeomorph.isHomeomorph) (fun [_] _ => rfl) @[simp] -theorem image_intrinsicFrontier (φ : P →ᵃⁱ[𝕜] Q) (s : Set P) : - intrinsicFrontier 𝕜 (φ '' s) = φ '' intrinsicFrontier 𝕜 s := by - obtain rfl | hs := s.eq_empty_or_nonempty - · simp - haveI : Nonempty s := hs.to_subtype - let f := ((affineSpan 𝕜 s).isometryEquivMap φ).toHomeomorph - have : φ.toAffineMap ∘ (↑) ∘ f.symm = (↑) := funext isometryEquivMap.apply_symm_apply - rw [intrinsicFrontier, intrinsicFrontier, ← φ.coe_toAffineMap, ← map_span φ.toAffineMap s, ← this, - ← Function.comp_assoc, image_comp, image_comp, f.symm.image_frontier, f.image_symm, - ← preimage_comp, Function.comp_assoc, f.symm_comp_self, AffineIsometry.coe_toAffineMap, - Function.comp_id, preimage_comp, φ.injective.preimage_image] +theorem intrinsicFrontier_image (φ : P →ᵃⁱ[𝕜] Q) (s : Set P) : + intrinsicFrontier 𝕜 (φ '' s) = φ '' intrinsicFrontier 𝕜 s := + let e : [Nonempty s] → (affineSpan 𝕜 s) ≃ᴬ[𝕜] (affineSpan 𝕜 (φ '' s)) := fun [_] => + ((affineSpan 𝕜 s).isometryEquivMap φ).toContinuousAffineEquiv.trans <| ofEq <| + (map_span φ.toAffineMap s).trans <| congrArg _ <| congrArg (· '' s) φ.coe_toAffineMap + intrinsicFrontier_image_of_homeomorph_affineSpan + (fun [_] => e.toHomeomorph) (fun [_] => e.toHomeomorph.isHomeomorph) (fun [_] _ => rfl) @[simp] -theorem image_intrinsicClosure (φ : P →ᵃⁱ[𝕜] Q) (s : Set P) : - intrinsicClosure 𝕜 (φ '' s) = φ '' intrinsicClosure 𝕜 s := by - obtain rfl | hs := s.eq_empty_or_nonempty - · simp - haveI : Nonempty s := hs.to_subtype - let f := ((affineSpan 𝕜 s).isometryEquivMap φ).toHomeomorph - have : φ.toAffineMap ∘ (↑) ∘ f.symm = (↑) := funext isometryEquivMap.apply_symm_apply - rw [intrinsicClosure, intrinsicClosure, ← φ.coe_toAffineMap, ← map_span φ.toAffineMap s, ← this, - ← Function.comp_assoc, image_comp, image_comp, f.symm.image_closure, f.image_symm, - ← preimage_comp, Function.comp_assoc, f.symm_comp_self, AffineIsometry.coe_toAffineMap, - Function.comp_id, preimage_comp, φ.injective.preimage_image] +theorem intrinsicClosure_image (φ : P →ᵃⁱ[𝕜] Q) (s : Set P) : + intrinsicClosure 𝕜 (φ '' s) = φ '' intrinsicClosure 𝕜 s := + let e : [Nonempty s] → (affineSpan 𝕜 s) ≃ᴬ[𝕜] (affineSpan 𝕜 (φ '' s)) := fun [_] => + ((affineSpan 𝕜 s).isometryEquivMap φ).toContinuousAffineEquiv.trans <| ofEq <| + (map_span φ.toAffineMap s).trans <| congrArg _ <| congrArg (· '' s) φ.coe_toAffineMap + intrinsicClosure_image_of_homeomorph_affineSpan + (fun [_] => e.toHomeomorph) (fun [_] => e.toHomeomorph.isHomeomorph) (fun [_] _ => rfl) + +@[deprecated intrinsicInterior_image (since := "2026-05-08")] +alias image_intrinsicInterior := intrinsicInterior_image + +@[deprecated intrinsicFrontier_image (since := "2026-05-08")] +alias image_intrinsicFrontier := intrinsicFrontier_image + +@[deprecated intrinsicClosure_image (since := "2026-05-08")] +alias image_intrinsicClosure := intrinsicClosure_image end AffineIsometry +namespace AffineEquiv + +variable [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + [NormedAddCommGroup V] [NormedSpace 𝕜 V] [FiniteDimensional 𝕜 V] + [NormedAddCommGroup W] [NormedSpace 𝕜 W] + [MetricSpace P] [NormedAddTorsor V P] + [MetricSpace Q] [NormedAddTorsor W Q] + +@[simp] +theorem intrinsicInterior_image (φ : P ≃ᵃ[𝕜] Q) (s : Set P) : + intrinsicInterior 𝕜 (φ '' s) = φ '' intrinsicInterior 𝕜 s := + φ.toContinuousAffineEquiv.intrinsicInterior_image s + +@[simp] +theorem intrinsicFrontier_image (φ : P ≃ᵃ[𝕜] Q) (s : Set P) : + intrinsicFrontier 𝕜 (φ '' s) = φ '' intrinsicFrontier 𝕜 s := + φ.toContinuousAffineEquiv.intrinsicFrontier_image s + +@[simp] +theorem intrinsicClosure_image (φ : P ≃ᵃ[𝕜] Q) (s : Set P) : + intrinsicClosure 𝕜 (φ '' s) = φ '' intrinsicClosure 𝕜 s := + φ.toContinuousAffineEquiv.intrinsicClosure_image s + +end AffineEquiv + section NormedAddTorsor variable (𝕜) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormedAddCommGroup V] [NormedSpace 𝕜 V] diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index a4d06ac9733d96..efa1834193c4dc 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -131,13 +131,30 @@ theorem AffineMap.continuous_of_finiteDimensional (f : PE →ᵃ[𝕜] PF) : Con theorem AffineEquiv.continuous_of_finiteDimensional (f : PE ≃ᵃ[𝕜] PF) : Continuous f := f.toAffineMap.continuous_of_finiteDimensional +/-- Reinterpret an affine equivalence as a continuous affine equivalence in finite dimension. -/ +def AffineEquiv.toContinuousAffineEquiv : (PE ≃ᵃ[𝕜] PF) ≃ (PE ≃ᴬ[𝕜] PF) where + toFun f := + haveI := f.linear.finiteDimensional + ⟨f, f.continuous_of_finiteDimensional, f.symm.continuous_of_finiteDimensional⟩ + invFun f := f.toAffineEquiv + left_inv _ := rfl + right_inv _ := ContinuousAffineEquiv.toAffineEquiv_injective rfl + +@[simp] +theorem AffineEquiv.coe_toContinuousAffineEquiv (f : PE ≃ᵃ[𝕜] PF) : + ⇑(toContinuousAffineEquiv f) = f := rfl + +@[simp] +theorem AffineEquiv.toAffineEquiv_toContinuousAffineEquiv (f : PE ≃ᵃ[𝕜] PF) : + (toContinuousAffineEquiv f).toAffineEquiv = f := rfl + +@[simp] +theorem AffineEquiv.toContinuousAffineEquiv_symm_apply (f : PE ≃ᴬ[𝕜] PF) : + toContinuousAffineEquiv.symm f = f.toAffineEquiv := rfl + /-- Reinterpret an affine equivalence as a homeomorphism. -/ -def AffineEquiv.toHomeomorphOfFiniteDimensional (f : PE ≃ᵃ[𝕜] PF) : PE ≃ₜ PF where - toEquiv := f.toEquiv - continuous_toFun := f.continuous_of_finiteDimensional - continuous_invFun := - haveI : FiniteDimensional 𝕜 F := f.linear.finiteDimensional - f.symm.continuous_of_finiteDimensional +def AffineEquiv.toHomeomorphOfFiniteDimensional (f : PE ≃ᵃ[𝕜] PF) : PE ≃ₜ PF := + (toContinuousAffineEquiv f).toHomeomorph @[simp] theorem AffineEquiv.coe_toHomeomorphOfFiniteDimensional (f : PE ≃ᵃ[𝕜] PF) : @@ -149,6 +166,9 @@ theorem AffineEquiv.coe_toHomeomorphOfFiniteDimensional_symm (f : PE ≃ᵃ[𝕜 ⇑f.toHomeomorphOfFiniteDimensional.symm = f.symm := rfl +attribute [deprecated AffineEquiv.toContinuousAffineEquiv (since := "2026-05-11")] + AffineEquiv.toHomeomorphOfFiniteDimensional + /-- An affine map from a finite-dimensional space is automatically Lipschitz. -/ theorem AffineMap.lipschitzWith_of_finiteDimensional (f : PE →ᵃ[𝕜] PF) : ∃ K : ℝ≥0, LipschitzWith K f := by diff --git a/Mathlib/LinearAlgebra/AffineSpace/Restrict.lean b/Mathlib/LinearAlgebra/AffineSpace/Restrict.lean index 95f5a7340452e5..4a16f9c79064a2 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Restrict.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Restrict.lean @@ -81,3 +81,23 @@ theorem AffineMap.restrict.surjective (φ : P₁ →ᵃ[k] P₂) {E : AffineSubs theorem AffineMap.restrict.bijective {E : AffineSubspace k P₁} [Nonempty E] {φ : P₁ →ᵃ[k] P₂} (hφ : Function.Injective φ) : Function.Bijective (φ.restrict (le_refl (E.map φ))) := ⟨AffineMap.restrict.injective hφ _, AffineMap.restrict.surjective _ rfl⟩ + +namespace AffineEquiv + +/-- An affine equivalence restricts to an affine equivalence between an affine subspace and its +image. -/ +noncomputable def affineSubspaceMap (e : P₁ ≃ᵃ[k] P₂) (s : AffineSubspace k P₁) + [Nonempty s] : s ≃ᵃ[k] s.map e.toAffineMap := + .ofBijective (AffineMap.restrict.bijective e.injective) + +@[simp] +theorem affineSubspaceMap_apply (e : P₁ ≃ᵃ[k] P₂) (s : AffineSubspace k P₁) + [Nonempty s] (x : s) : e.affineSubspaceMap s x = e x := + rfl + +@[simp] +theorem affineSubspaceMap_apply_symm_apply (e : P₁ ≃ᵃ[k] P₂) (s : AffineSubspace k P₁) + [Nonempty s] (x : s.map e.toAffineMap) : e ((e.affineSubspaceMap s).symm x) = x := + congrArg Subtype.val <| (e.affineSubspaceMap s).apply_symm_apply x + +end AffineEquiv diff --git a/Mathlib/Topology/Algebra/AffineSubspace.lean b/Mathlib/Topology/Algebra/AffineSubspace.lean index 0896280ff814f5..dc38b016cd6fdb 100644 --- a/Mathlib/Topology/Algebra/AffineSubspace.lean +++ b/Mathlib/Topology/Algebra/AffineSubspace.lean @@ -6,8 +6,9 @@ Authors: Joseph Myers module public import Mathlib.LinearAlgebra.AffineSpace.AffineSubspace.Basic +public import Mathlib.LinearAlgebra.AffineSpace.Restrict public import Mathlib.Topology.Algebra.ContinuousAffineMap -public import Mathlib.Topology.Algebra.Group.Torsor +public import Mathlib.Topology.Algebra.ContinuousAffineEquiv /-! # Topology of affine subspaces. @@ -41,6 +42,54 @@ def subtypeA (s : AffineSubspace R P) [Nonempty s] : s →ᴬ[R] P where s.subtypeA.toAffineMap = s.subtype := rfl +/-- `AffineEquiv.ofEq` as a continuous affine equivalence. -/ +noncomputable def ofEq {s t : AffineSubspace R P} [Nonempty s] [Nonempty t] + (h : s = t) : s ≃ᴬ[R] t where + toAffineEquiv := .ofEq s t h + continuous_toFun := by subst h; exact continuous_id + continuous_invFun := by subst h; exact continuous_id + +@[simp] +theorem coe_ofEq_apply {s t : AffineSubspace R P} [Nonempty s] [Nonempty t] + (h : s = t) (x : s) : (ofEq h x : P) = x := AffineEquiv.coe_ofEq_apply s t h x + +end AffineSubspace + +namespace ContinuousAffineEquiv + +variable {R V P W Q : Type*} [Ring R] [AddCommGroup V] [Module R V] [TopologicalSpace P] + [AddTorsor V P] [AddCommGroup W] [Module R W] [TopologicalSpace Q] [AddTorsor W Q] + +/-- A continuous affine equivalence restricts to a continuous affine equivalence between an affine +subspace and its image. + +This is the continuous affine version of `AffineEquiv.affineSubspaceMap`. -/ +noncomputable def affineSubspaceMap (e : P ≃ᴬ[R] Q) (s : AffineSubspace R P) [Nonempty s] : + s ≃ᴬ[R] s.map e.toAffineMap := + { e.toAffineEquiv.affineSubspaceMap s with + continuous_toFun := by simpa [Topology.IsEmbedding.subtypeVal.continuous_iff] using! + (e.continuous.comp continuous_subtype_val).congr fun _ => rfl + continuous_invFun := by simpa [Topology.IsEmbedding.subtypeVal.continuous_iff] using! + (e.continuous_invFun.comp continuous_subtype_val).congr fun x ↦ + (e.apply_eq_iff_eq_symm_apply.mp + (AffineEquiv.affineSubspaceMap_apply_symm_apply e.toAffineEquiv s x)).symm } + +@[simp] +theorem affineSubspaceMap_apply (e : P ≃ᴬ[R] Q) (s : AffineSubspace R P) [Nonempty s] + (x : s) : e.affineSubspaceMap s x = e x := rfl + +@[simp] +theorem affineSubspaceMap_apply_symm_apply (e : P ≃ᴬ[R] Q) (s : AffineSubspace R P) + [Nonempty s] (x : s.map e.toAffineMap) : e ((e.affineSubspaceMap s).symm x) = x := + AffineEquiv.affineSubspaceMap_apply_symm_apply e.toAffineEquiv s x + +end ContinuousAffineEquiv + +namespace AffineSubspace + +variable {R V P : Type*} [Ring R] [AddCommGroup V] [Module R V] [TopologicalSpace P] + [AddTorsor V P] + variable [TopologicalSpace V] [IsTopologicalAddTorsor P] instance {s : AffineSubspace R P} [Nonempty s] : IsTopologicalAddTorsor s where diff --git a/Mathlib/Topology/Homeomorph/Defs.lean b/Mathlib/Topology/Homeomorph/Defs.lean index 102f58751b96a6..79ccff73ceae30 100644 --- a/Mathlib/Topology/Homeomorph/Defs.lean +++ b/Mathlib/Topology/Homeomorph/Defs.lean @@ -499,14 +499,52 @@ protected theorem Homeomorph.isHomeomorph (h : X ≃ₜ Y) : IsHomeomorph h := namespace IsHomeomorph +/-- Bundled homeomorphism constructed from a map that is a homeomorphism. -/ +@[simps! toEquiv apply symm_apply] +noncomputable def homeomorph (f : X → Y) (hf : IsHomeomorph f) : X ≃ₜ Y where + continuous_toFun := hf.1 + continuous_invFun := + Equiv.ofBijective f hf.bijective |>.continuous_symm_iff.2 hf.isOpenMap + toEquiv := Equiv.ofBijective f hf.bijective + protected lemma injective (hf : IsHomeomorph f) : Function.Injective f := hf.bijective.injective protected lemma surjective (hf : IsHomeomorph f) : Function.Surjective f := hf.bijective.surjective protected lemma id : IsHomeomorph (@id X) := ⟨continuous_id, .id, Function.bijective_id⟩ +theorem image_interior (hf : IsHomeomorph f) (s : Set X) : + f '' interior s = interior (f '' s) := hf.homeomorph.image_interior s + +theorem image_closure (hf : IsHomeomorph f) (s : Set X) : + f '' closure s = closure (f '' s) := hf.homeomorph.image_closure s + +theorem image_frontier (hf : IsHomeomorph f) (s : Set X) : + f '' frontier s = frontier (f '' s) := hf.homeomorph.image_frontier s + lemma comp {g : Y → Z} (hg : IsHomeomorph g) (hf : IsHomeomorph f) : IsHomeomorph (g ∘ f) := ⟨hg.1.comp hf.1, hg.2.comp hf.2, hg.3.comp hf.3⟩ end IsHomeomorph end IsHomeomorph + +variable {X Y Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] in +/-- Precomposing by a homeomorphism does not change the image of the interior of a preimage. -/ +theorem image_interior_preimage_comp (e : X → Y) (he : IsHomeomorph e) (f : Y → Z) (s : Set Z) : + (f ∘ e) '' interior ((f ∘ e) ⁻¹' s) = f '' interior (f ⁻¹' s) := by + simp only [Set.preimage_comp, Set.image_comp, he.image_interior, + Set.image_preimage_eq _ he.surjective] + +variable {X Y Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] in +/-- Precomposing by a homeomorphism does not change the image of the frontier of a preimage. -/ +theorem image_frontier_preimage_comp (e : X → Y) (he : IsHomeomorph e) (f : Y → Z) (s : Set Z) : + (f ∘ e) '' frontier ((f ∘ e) ⁻¹' s) = f '' frontier (f ⁻¹' s) := by + simp only [Set.preimage_comp, Set.image_comp, he.image_frontier, + Set.image_preimage_eq _ he.surjective] + +variable {X Y Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] in +/-- Precomposing by a homeomorphism does not change the image of the closure of a preimage. -/ +theorem image_closure_preimage_comp (e : X → Y) (he : IsHomeomorph e) (f : Y → Z) (s : Set Z) : + (f ∘ e) '' closure ((f ∘ e) ⁻¹' s) = f '' closure (f ⁻¹' s) := by + simp only [Set.preimage_comp, Set.image_comp, he.image_closure, + Set.image_preimage_eq _ he.surjective] diff --git a/Mathlib/Topology/Homeomorph/Lemmas.lean b/Mathlib/Topology/Homeomorph/Lemmas.lean index 4ac8614c83e476..9fc328a54765e0 100644 --- a/Mathlib/Topology/Homeomorph/Lemmas.lean +++ b/Mathlib/Topology/Homeomorph/Lemmas.lean @@ -484,17 +484,6 @@ namespace IsHomeomorph variable (hf : IsHomeomorph f) include hf -variable (f) in -/-- Bundled homeomorphism constructed from a map that is a homeomorphism. -/ -@[simps! toEquiv apply symm_apply] -noncomputable def homeomorph : X ≃ₜ Y where - continuous_toFun := hf.1 - continuous_invFun := by - rw [← continuousOn_univ, ← hf.bijective.2.range_eq] - exact hf.isOpenMap.continuousOn_range_of_leftInverse - (Equiv.ofBijective f hf.bijective).left_inv - toEquiv := Equiv.ofBijective f hf.bijective - protected lemma isClosedMap : IsClosedMap f := (hf.homeomorph f).isClosedMap lemma isInducing : IsInducing f := (hf.homeomorph f).isInducing lemma isQuotientMap : IsQuotientMap f := (hf.homeomorph f).isQuotientMap From 6891e4fdd8ba77c691b4a89ebe3715622cd30d4c Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:57:11 +0000 Subject: [PATCH 0070/1300] chore: move Data.Set.{Accumulate,Dissipate} to Order.Set{Accumulate,Dissipate} (#40003) Both files have only order-theoretic imports, and their contents are arguably also order-theoretic. --- Mathlib.lean | 4 ++-- Mathlib/MeasureTheory/PiSystem.lean | 2 +- Mathlib/MeasureTheory/SetSemiring.lean | 2 +- .../{Data/Set/Accumulate.lean => Order/SetAccumulate.lean} | 0 Mathlib/{Data/Set/Dissipate.lean => Order/SetDissipate.lean} | 2 +- Mathlib/Topology/Compactness/Compact.lean | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename Mathlib/{Data/Set/Accumulate.lean => Order/SetAccumulate.lean} (100%) rename Mathlib/{Data/Set/Dissipate.lean => Order/SetDissipate.lean} (98%) diff --git a/Mathlib.lean b/Mathlib.lean index cbf1ae94070768..e6c0e093bd8d15 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4312,7 +4312,6 @@ public import Mathlib.Data.Seq.Basic public import Mathlib.Data.Seq.Computation public import Mathlib.Data.Seq.Defs public import Mathlib.Data.Seq.Parallel -public import Mathlib.Data.Set.Accumulate public import Mathlib.Data.Set.Basic public import Mathlib.Data.Set.BoolIndicator public import Mathlib.Data.Set.BooleanAlgebra @@ -4323,7 +4322,6 @@ public import Mathlib.Data.Set.Constructions public import Mathlib.Data.Set.Countable public import Mathlib.Data.Set.Defs public import Mathlib.Data.Set.Disjoint -public import Mathlib.Data.Set.Dissipate public import Mathlib.Data.Set.Enumerate public import Mathlib.Data.Set.Equitable public import Mathlib.Data.Set.Finite.Basic @@ -6152,6 +6150,8 @@ public import Mathlib.Order.ScottContinuity.Complete public import Mathlib.Order.ScottContinuity.Prod public import Mathlib.Order.SemiconjSup public import Mathlib.Order.Set +public import Mathlib.Order.SetAccumulate +public import Mathlib.Order.SetDissipate public import Mathlib.Order.SetIsMax public import Mathlib.Order.SetNotation public import Mathlib.Order.Shrink diff --git a/Mathlib/MeasureTheory/PiSystem.lean b/Mathlib/MeasureTheory/PiSystem.lean index 323e653bf0d44c..06bfac122aa2f9 100644 --- a/Mathlib/MeasureTheory/PiSystem.lean +++ b/Mathlib/MeasureTheory/PiSystem.lean @@ -5,10 +5,10 @@ Authors: Johannes Hölzl, Martin Zinkevich, Rémy Degenne -/ module -public import Mathlib.Data.Set.Dissipate public import Mathlib.Logic.Encodable.Lattice public import Mathlib.MeasureTheory.MeasurableSpace.Defs public import Mathlib.Order.Disjointed +public import Mathlib.Order.SetDissipate /-! # Induction principles for measurable sets, related to π-systems and λ-systems. diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 04be1bbd849335..55d406b20306b8 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -5,11 +5,11 @@ Authors: Rémy Degenne, Peter Pfaffelhuber -/ module -public import Mathlib.Data.Set.Accumulate public import Mathlib.Data.Set.Pairwise.Lattice public import Mathlib.MeasureTheory.PiSystem public import Mathlib.Order.Lattice.Nat public import Mathlib.Order.Partition.Finpartition +public import Mathlib.Order.SetAccumulate public import Mathlib.Order.SupClosed /-! # Semirings and rings of sets diff --git a/Mathlib/Data/Set/Accumulate.lean b/Mathlib/Order/SetAccumulate.lean similarity index 100% rename from Mathlib/Data/Set/Accumulate.lean rename to Mathlib/Order/SetAccumulate.lean diff --git a/Mathlib/Data/Set/Dissipate.lean b/Mathlib/Order/SetDissipate.lean similarity index 98% rename from Mathlib/Data/Set/Dissipate.lean rename to Mathlib/Order/SetDissipate.lean index f0d281c104912e..e163c53144fcf5 100644 --- a/Mathlib/Data/Set/Dissipate.lean +++ b/Mathlib/Order/SetDissipate.lean @@ -6,7 +6,7 @@ Authors: Peter Pfaffelhuber module -public import Mathlib.Data.Set.Accumulate +public import Mathlib.Order.SetAccumulate /-! # Dissipate diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index fb6b6d7acff7d6..4df746261b2037 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -6,7 +6,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Yury Kudryashov module public import Mathlib.Order.Filter.Tendsto -public import Mathlib.Data.Set.Accumulate +public import Mathlib.Order.SetAccumulate public import Mathlib.Topology.Bornology.Basic public import Mathlib.Topology.ContinuousOn public import Mathlib.Topology.Ultrafilter From 483ba09b2edd4d422fa9e502f1c6df6b382483e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 16 Jun 2026 16:57:14 +0000 Subject: [PATCH 0071/1300] chore: deprecate `Rat.coe_int_inj` (#40670) --- Mathlib/Algebra/Module/ZLattice/Basic.lean | 2 +- Mathlib/Data/Rat/Defs.lean | 5 +---- Mathlib/Data/Rat/Lemmas.lean | 2 +- Mathlib/NumberTheory/DiophantineApproximation/Basic.lean | 2 +- Mathlib/NumberTheory/PythagoreanTriples.lean | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index ae95cf8def950d..a7546316ed9cbe 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -594,7 +594,7 @@ theorem ZLattice.rank [hs : IsZLattice K L] : finrank ℤ L = finrank K E := by obtain ⟨n, -, m, -, h_ne, h_eq⟩ := Set.Infinite.exists_ne_map_eq_of_mapsTo Set.infinite_univ h_mapsto h_finite have h_nz : (-n + m : ℚ) ≠ 0 := by - rwa [Ne, add_eq_zero_iff_eq_neg.not, neg_inj, Rat.coe_int_inj, ← Ne] + rwa [Ne, add_eq_zero_iff_eq_neg.not, neg_inj, Rat.intCast_inj, ← Ne] apply (smul_mem_iff _ h_nz).mp refine span_subset_span ℤ ℚ _ ?_ rwa [add_smul, neg_smul, SetLike.mem_coe, ← fract_eq_fract, Int.cast_smul_eq_zsmul ℚ, diff --git a/Mathlib/Data/Rat/Defs.lean b/Mathlib/Data/Rat/Defs.lean index ac76129b7fcc11..1b3f964e3a1f79 100644 --- a/Mathlib/Data/Rat/Defs.lean +++ b/Mathlib/Data/Rat/Defs.lean @@ -263,10 +263,7 @@ theorem den_eq_one_iff (r : ℚ) : r.den = 1 ↔ ↑r.num = r := instance canLift : CanLift ℚ ℤ (↑) fun q => q.den = 1 := ⟨fun q hq => ⟨q.num, coe_int_num_of_den_eq_one hq⟩⟩ --- Will be subsumed by `Int.coe_inj` after we have defined --- `LinearOrderedField ℚ` (which implies characteristic zero). -theorem coe_int_inj (m n : ℤ) : (m : ℚ) = n ↔ m = n := - ⟨congr_arg num, congr_arg _⟩ +@[deprecated (since := "2026-06-06")] alias coe_int_inj := intCast_inj end Casts diff --git a/Mathlib/Data/Rat/Lemmas.lean b/Mathlib/Data/Rat/Lemmas.lean index 5e7016ec9f7af6..fe43e95dfecb29 100644 --- a/Mathlib/Data/Rat/Lemmas.lean +++ b/Mathlib/Data/Rat/Lemmas.lean @@ -262,7 +262,7 @@ theorem intCast_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by by_cases hn : n = 0 · subst hn simp - · have : (n : ℚ) ≠ 0 := by rwa [← coe_int_inj] at hn + · have : (n : ℚ) ≠ 0 := by rwa [← intCast_inj] at hn simp only [Int.ediv_self hn, Int.cast_one, div_self this] @[norm_cast] diff --git a/Mathlib/NumberTheory/DiophantineApproximation/Basic.lean b/Mathlib/NumberTheory/DiophantineApproximation/Basic.lean index c71bef7bddf592..704a720427df65 100644 --- a/Mathlib/NumberTheory/DiophantineApproximation/Basic.lean +++ b/Mathlib/NumberTheory/DiophantineApproximation/Basic.lean @@ -501,7 +501,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) : obtain ⟨_, h₁, h₂⟩ := h rcases le_or_gt (u : ℝ) ξ with ht | ht · use 0 - rw [convergent_zero, Rat.coe_int_inj, eq_comm, floor_eq_iff] + rw [convergent_zero, Rat.intCast_inj, eq_comm, floor_eq_iff] convert! And.intro ht (sub_lt_iff_lt_add'.mp (abs_lt.mp h₂).2) <;> norm_num · replace h₁ := lt_sub_iff_add_lt'.mp (h₁ rfl) have hξ₁ : ⌊ξ⌋ = u - 1 := by diff --git a/Mathlib/NumberTheory/PythagoreanTriples.lean b/Mathlib/NumberTheory/PythagoreanTriples.lean index 062bb6e1941f47..4a3ccc22d77dc2 100644 --- a/Mathlib/NumberTheory/PythagoreanTriples.lean +++ b/Mathlib/NumberTheory/PythagoreanTriples.lean @@ -413,7 +413,7 @@ theorem isPrimitiveClassified_aux (hc : x.gcd y = 1) (hzpos : 0 < z) {m n : ℤ} apply And.intro _ (And.intro co pp) right refine ⟨?_, h2.left⟩ - rw [← Rat.coe_int_inj _ _, ← div_left_inj' ((mt (Rat.coe_int_inj z 0).mp) hz), hv2, h2.right] + rw [← Rat.intCast_inj, ← div_left_inj' (mt Rat.intCast_inj.mp hz), hv2, h2.right] norm_cast theorem isPrimitiveClassified_of_coprime_of_odd_of_pos (hc : Int.gcd x y = 1) (hyo : y % 2 = 1) From 3d21c42b6e1f377f299956fed4d8351bdbc52deb Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 16 Jun 2026 17:40:55 +0000 Subject: [PATCH 0072/1300] refactor(Analysis): golf `Mathlib/Analysis/Normed/Unbundled/FiniteExtension` (#39899) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - refactors `Normed/Unbundled/FiniteExtension` by proving `Basis.norm_smul` via `Finset.mul₀_sup'` Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- .../Normed/Unbundled/FiniteExtension.lean | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean index 1236db2da757f6..028dffb4ec2f00 100644 --- a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean +++ b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean @@ -153,21 +153,10 @@ theorem norm_mul_le_const_mul_norm {i : ι} (hBi : B i = (1 : L)) theorem norm_smul {ι : Type*} [Fintype ι] [Nonempty ι] {B : Basis ι K L} {i : ι} (hBi : B i = (1 : L)) (k : K) (y : L) : B.norm ((algebraMap K L) k * y) = B.norm ((algebraMap K L) k) * B.norm y := by - by_cases hk : k = 0 - · rw [hk, map_zero, zero_mul, B.norm_zero, zero_mul] - · rw [norm_extends hBi] - obtain ⟨i, _, hi⟩ := exists_mem_eq_sup' univ_nonempty (fun i ↦ ‖B.repr y i‖) - obtain ⟨j, _, hj⟩ := exists_mem_eq_sup' univ_nonempty - (fun i ↦ ‖B.repr ((algebraMap K L) k * y) i‖) - have hij : ‖B.repr y i‖ = ‖B.repr y j‖ := by - rw [← hi] - apply le_antisymm _ (norm_repr_le_norm B j) - have hj' := Finset.le_sup' (fun i ↦ ‖B.repr ((algebraMap K L) k * y) i‖) (mem_univ i) - simp only [repr_smul', norm_mul, ← hi] at hj hj' - exact (mul_le_mul_iff_right₀ (lt_of_le_of_ne (norm_nonneg _) - (Ne.symm (norm_ne_zero_iff.mpr hk)))).mp (hj ▸ hj') - simp only [norm, hj] - rw [repr_smul', norm_mul, hi, hij] + rw [norm_extends hBi, Basis.norm, Basis.norm, + Finset.mul₀_sup' (norm_nonneg _) (fun j : ι ↦ ‖B.repr y j‖) univ univ_nonempty] + congr with j + rw [repr_smul', norm_mul] end Module.Basis From 8e7aadcd06bec331b15f9c7b0b7c2fc01e37a884 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 16 Jun 2026 17:40:58 +0000 Subject: [PATCH 0073/1300] refactor(Analysis): golf `Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral` (#39900) - refactors `Gaussian/GaussianIntegral` by proving `integral_gaussian_complex_Ioi` using `integral_comp_neg_Ioi` Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- .../Gaussian/GaussianIntegral.lean | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean index df5ccca8e69926..d5530157c7cded 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean @@ -292,27 +292,16 @@ theorem integral_gaussian_complex {b : ℂ} (hb : 0 < re b) : -- The Gaussian integral on the half-line, `∫ x in Ioi 0, exp (-b * x^2)`, for complex `b`. theorem integral_gaussian_complex_Ioi {b : ℂ} (hb : 0 < re b) : ∫ x : ℝ in Ioi 0, cexp (-b * (x : ℂ) ^ 2) = (π / b) ^ (1 / 2 : ℂ) / 2 := by + let f : ℝ → ℂ := fun x => cexp (-b * (x : ℂ) ^ 2) have full_integral := integral_gaussian_complex hb - have : MeasurableSet (Ioi (0 : ℝ)) := measurableSet_Ioi - rw [← integral_add_compl this (integrable_cexp_neg_mul_sq hb), compl_Ioi] at full_integral - suffices ∫ x : ℝ in Iic 0, cexp (-b * (x : ℂ) ^ 2) = ∫ x : ℝ in Ioi 0, cexp (-b * (x : ℂ) ^ 2) by - rw [this, ← mul_two] at full_integral - rwa [eq_div_iff]; exact two_ne_zero - have : ∀ c : ℝ, ∫ x in (0 : ℝ)..c, cexp (-b * (x : ℂ) ^ 2) = - ∫ x in -c..0, cexp (-b * (x : ℂ) ^ 2) := by - intro c - have := intervalIntegral.integral_comp_sub_left (a := 0) (b := c) - (fun x => cexp (-b * (x : ℂ) ^ 2)) 0 - simpa [zero_sub, neg_sq, neg_zero] using this - have t1 := - intervalIntegral_tendsto_integral_Ioi 0 (integrable_cexp_neg_mul_sq hb).integrableOn tendsto_id - have t2 : - Tendsto (fun c : ℝ => ∫ x : ℝ in (0 : ℝ)..c, cexp (-b * (x : ℂ) ^ 2)) atTop - (𝓝 (∫ x : ℝ in Iic 0, cexp (-b * (x : ℂ) ^ 2))) := by - simp_rw [this] - refine intervalIntegral_tendsto_integral_Iic _ ?_ tendsto_neg_atTop_atBot - apply (integrable_cexp_neg_mul_sq hb).integrableOn - exact tendsto_nhds_unique t2 t1 + have h_eq := calc + ∫ x : ℝ in Iic 0, f x = ∫ x : ℝ in Ioi 0, f (-x) := by + simpa [f] using (integral_comp_neg_Ioi 0 f).symm + _ = ∫ x : ℝ in Ioi 0, f x := + setIntegral_congr_fun measurableSet_Ioi fun _ _ ↦ (by simp [f]) + rw [← integral_add_compl (s := Ioi 0) (by simp) (integrable_cexp_neg_mul_sq hb), compl_Ioi, h_eq, + ← mul_two] at full_integral + exact (eq_div_iff two_ne_zero).2 (by simpa using full_integral) -- The Gaussian integral on the half-line, `∫ x in Ioi 0, exp (-b * x^2)`, for real `b`. theorem integral_gaussian_Ioi (b : ℝ) : From ce43383a24924c84cbc2223c3649080a15e6aa84 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 16 Jun 2026 17:41:03 +0000 Subject: [PATCH 0074/1300] refactor(Analysis): golf `Mathlib/Analysis/Analytic/Order` (#40067) - refactors `AnalyticOnNhd.preimage_zero_mem_codiscreteWithin` to use `eqOn_zero_or_eventually_ne_zero_of_preconnected` directly Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Analysis/Analytic/Order.lean | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Order.lean b/Mathlib/Analysis/Analytic/Order.lean index 018825449dd978..5f8cb7ed88f349 100644 --- a/Mathlib/Analysis/Analytic/Order.lean +++ b/Mathlib/Analysis/Analytic/Order.lean @@ -664,14 +664,9 @@ codiscrete sets. theorem preimage_zero_mem_codiscreteWithin {x : 𝕜} (h₁f : AnalyticOnNhd 𝕜 f U) (h₂f : f x ≠ 0) (hx : x ∈ U) (hU : IsConnected U) : f ⁻¹' {0}ᶜ ∈ codiscreteWithin U := by - filter_upwards [h₁f.codiscreteWithin_setOf_analyticOrderAt_eq_zero_or_top, - self_mem_codiscreteWithin U] with a ha h₂a - rw [← (h₁f x hx).analyticOrderAt_eq_zero] at h₂f - have {u : U} : analyticOrderAt f u ≠ ⊤ := by - apply (h₁f.exists_analyticOrderAt_ne_top_iff_forall hU).1 - use ⟨x, hx⟩ - simp_all - simp_all [(h₁f a h₂a).analyticOrderAt_eq_zero] + rcases h₁f.eqOn_zero_or_eventually_ne_zero_of_preconnected hU.isPreconnected with hzero | hne + · exact (h₂f (hzero hx)).elim + · exact hne /-- If an analytic function `f` is not constantly zero on `𝕜`, then its set of zeros is codiscrete. From 6071266be2fa9ec5032c9dfc574bb560f53db509 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 16 Jun 2026 17:41:05 +0000 Subject: [PATCH 0075/1300] refactor(Analysis): golf `Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction` (#40069) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - refactors `σ_mul` by simplifying the determinant sign split with `mul_pos_iff` - rewrites `denom_cocycle'` as a direct consequence of `denom_cocycle` Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- .../Analysis/Complex/UpperHalfPlane/MoebiusAction.lean | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean index 6b66a5771136f2..91ed0eb715979c 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean @@ -156,13 +156,7 @@ def smulAux (g : GL (Fin 2) ℝ) (z : ℍ) : ℍ := lemma denom_cocycle' (g h : GL (Fin 2) ℝ) (z : ℍ) : denom (g * h) z = σ h (denom g (smulAux h z)) * denom h z := by - simp only [smulAux, smulAux', coe_mk, map_div₀, σ_num, σ_denom, σ_sq] - change _ = (_ * (_ / _) + _) * _ - field_simp [denom_ne_zero h z] - simp only [denom, Units.val_mul, mul_apply, Fin.sum_univ_succ, Finset.univ_unique, - Fin.default_eq_zero, Finset.sum_singleton, Fin.succ_zero_eq_one, Complex.ofReal_add, - Complex.ofReal_mul, num] - ring + simpa [smulAux, smulAux', denom, σ_sq] using denom_cocycle g h z.im_ne_zero theorem mul_smul' (g h : GL (Fin 2) ℝ) (z : ℍ) : smulAux (g * h) z = smulAux g (smulAux h z) := by From 9b785f98836c80b97bd069719ab54aa29c197200 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:41:08 +0000 Subject: [PATCH 0076/1300] chore: clean up `Mathlib.Init` imports after #32419 (#40674) Now that #32419 is merged, we can remove this import from Mathlib.Init. --- Mathlib/Init.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/Init.lean b/Mathlib/Init.lean index 5c6e0b48acc622..81b05422e07d29 100644 --- a/Mathlib/Init.lean +++ b/Mathlib/Init.lean @@ -28,10 +28,6 @@ public import Mathlib.Tactic.Linter.Style public import Mathlib.Tactic.Linter.Whitespace public import Mathlib.Tactic.TacticAnalysis.Declarations public import Mathlib.Tactic.TypeStar --- This is a redundant import, but it is needed so that --- the linter doesn't complain about `ParseCommand` not importing `Header`. --- This can be removed after https://github.com/leanprover-community/mathlib4/pull/32419 -public import Mathlib.Util.ParseCommand -- This import makes the `#help` command available globally. public import Batteries.Tactic.HelpCmd -- This import makes the `proof_wanted` command available globally. From 545bd043025d40d8f925d89d3f4ba7a8976530ee Mon Sep 17 00:00:00 2001 From: Dennj Date: Tue, 16 Jun 2026 18:37:30 +0000 Subject: [PATCH 0077/1300] feat(LinearAlgebra/Matrix): add Hadamard matrices (#38582) Define Hadamard matrices (over any star ring) and add basic API, including the fact that a Hadamard matrix with integer entries must have rank 1 or 2 or divisible by 4. Co-authored-by: Eric Wieser Co-authored-by: Oliver Nash --- Mathlib.lean | 1 + Mathlib/Algebra/Regular/Basic.lean | 10 + .../LinearAlgebra/Matrix/ConjTranspose.lean | 4 + .../LinearAlgebra/Matrix/HadamardMatrix.lean | 261 ++++++++++++++++++ docs/references.bib | 11 + 5 files changed, 287 insertions(+) create mode 100644 Mathlib/LinearAlgebra/Matrix/HadamardMatrix.lean diff --git a/Mathlib.lean b/Mathlib.lean index e6c0e093bd8d15..8a4fbc6a4795c7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5085,6 +5085,7 @@ public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.MvPolynomial public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Projective public import Mathlib.LinearAlgebra.Matrix.Gershgorin public import Mathlib.LinearAlgebra.Matrix.Hadamard +public import Mathlib.LinearAlgebra.Matrix.HadamardMatrix public import Mathlib.LinearAlgebra.Matrix.Hermitian public import Mathlib.LinearAlgebra.Matrix.Ideal public import Mathlib.LinearAlgebra.Matrix.Integer diff --git a/Mathlib/Algebra/Regular/Basic.lean b/Mathlib/Algebra/Regular/Basic.lean index 14d95772970905..8f567ab997558f 100644 --- a/Mathlib/Algebra/Regular/Basic.lean +++ b/Mathlib/Algebra/Regular/Basic.lean @@ -155,6 +155,16 @@ theorem isRegular_mul_iff : IsRegular (a * b) ↔ IsRegular a ∧ IsRegular b := refine Iff.trans ?_ isRegular_mul_and_mul_iff exact ⟨fun ab => ⟨ab, by rwa [mul_comm]⟩, fun rab => rab.1⟩ +/-- If a product is regular, so is its left factor. -/ +@[to_additive /-- If a sum is add-regular, so is its left summand. -/] +theorem IsRegular.of_mul_left (h : IsRegular (a * b)) : IsRegular a := + (isRegular_mul_iff.mp h).1 + +/-- If a product is regular, so is its right factor. -/ +@[to_additive /-- If a sum is add-regular, so is its right summand. -/] +theorem IsRegular.of_mul_right (h : IsRegular (a * b)) : IsRegular b := + (isRegular_mul_iff.mp h).2 + end CommSemigroup section Monoid diff --git a/Mathlib/LinearAlgebra/Matrix/ConjTranspose.lean b/Mathlib/LinearAlgebra/Matrix/ConjTranspose.lean index 6acd1c31f97c1d..ff316045d3c17e 100644 --- a/Mathlib/LinearAlgebra/Matrix/ConjTranspose.lean +++ b/Mathlib/LinearAlgebra/Matrix/ConjTranspose.lean @@ -151,6 +151,10 @@ theorem transpose_conjTranspose [Star α] (M : Matrix m n α) : Mᵀᴴ = M.map star := rfl +theorem conjTranspose_transpose_eq_transpose_conjTranspose [Star α] (M : Matrix m n α) : + Mᵀᴴ = Mᴴᵀ := + rfl + theorem conjTranspose_injective [InvolutiveStar α] : Function.Injective (conjTranspose : Matrix m n α → Matrix n m α) := (map_injective star_injective).comp transpose_injective diff --git a/Mathlib/LinearAlgebra/Matrix/HadamardMatrix.lean b/Mathlib/LinearAlgebra/Matrix/HadamardMatrix.lean new file mode 100644 index 00000000000000..4ace07110c3435 --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/HadamardMatrix.lean @@ -0,0 +1,261 @@ +/- +Copyright (c) 2026 Dennj Osele. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Dennj Osele +-/ +module + +public import Mathlib.LinearAlgebra.Matrix.Kronecker +public import Mathlib.LinearAlgebra.Matrix.Adjugate +public import Mathlib.Data.Matrix.Basic +public import Mathlib.Algebra.Star.Unitary + +/-! +# Hadamard matrices + +This file defines `Matrix.IsHadamard`, a unified notion that specializes to the classical real +Hadamard matrices over `ℝ`/`ℤ` (where `star` is trivial and entries are `±1`) and to the complex +Hadamard matrices over `ℂ` (where entries have unit norm). Basic results: conjugate-transpose +closure, the order identity `n = s * star s` from constant row or column sums, the Sylvester +(Kronecker) construction, and the divisibility obstruction `4 ∣ n`. + +## References + +* [W. de Launey and D. L. Flannery, *Algebraic Design Theory*][deLauneyFlannery2011] +-/ + +@[expose] public section + + +variable {m n R : Type*} + +namespace Matrix + +open scoped Kronecker + +variable [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n] + +section Semiring +variable [Semiring R] [StarRing R] + +/-- A square matrix over a `*`-semiring whose entries are unitary and whose rows and columns are +orthogonal with respect to the conjugate transpose: +`A * Aᴴ = n • 1` and `Aᴴ * A = n • 1`. + +Over a commutative ring in which the order is regular, the one-sided condition from +[Definition 2.3.1][deLauneyFlannery2011] implies this predicate by +`IsHadamard.of_mul_conjTranspose`; over a ring with trivial star (e.g. `ℝ`, `ℤ`), the entry +condition becomes `A i j = 1 ∨ A i j = -1`. Over `ℂ`, the entry condition becomes `‖A i j‖ = 1`, +generalizing the fourth-root complex Hadamard matrices of +[Definition 2.7.1][deLauneyFlannery2011]. -/ +@[mk_iff] structure IsHadamard (A : Matrix n n R) : Prop where + apply_mem (i j : n) : A i j ∈ unitary R + mul_conjTranspose : A * Aᴴ = (Fintype.card n : R) • (1 : Matrix n n R) + conjTranspose_mul : Aᴴ * A = (Fintype.card n : R) • (1 : Matrix n n R) + +variable {A : Matrix n n R} + +theorem IsHadamard.isStarNormal (hA : A.IsHadamard) : IsStarNormal A where + star_comm_self := by + rw [commute_iff_eq, star_eq_conjTranspose, hA.conjTranspose_mul, hA.mul_conjTranspose] + +/-- The conjugate transpose of a Hadamard matrix is Hadamard. -/ +theorem IsHadamard.conjTranspose (hA : A.IsHadamard) : Aᴴ.IsHadamard := by + exact ⟨fun i j => Unitary.star_mem (hA.apply_mem j i), + by simpa using hA.conjTranspose_mul, + by simpa using hA.mul_conjTranspose⟩ + +@[simp] +theorem isHadamard_conjTranspose_iff : Aᴴ.IsHadamard ↔ A.IsHadamard := + ⟨fun hA => by simpa using hA.conjTranspose, (·.conjTranspose)⟩ + +/-- Permuting the rows and columns of a Hadamard matrix gives a Hadamard matrix. -/ +theorem IsHadamard.reindex (e₁ e₂ : n ≃ m) (hA : A.IsHadamard) : + (reindex e₁ e₂ A).IsHadamard := by + refine ⟨fun i j => hA.apply_mem _ _, ?_, ?_⟩ <;> + simp [reindex_apply, submatrix_mul_equiv, hA.mul_conjTranspose, hA.conjTranspose_mul, + Fintype.card_congr e₁, submatrix_smul, Pi.smul_apply] + +@[simp] +theorem isHadamard_submatrix_equiv_iff (e₁ e₂ : m ≃ n) : + (A.submatrix e₁ e₂).IsHadamard ↔ A.IsHadamard := + ⟨fun h => by simpa using h.reindex e₁ e₂, + fun h => by simpa [reindex_apply] using h.reindex e₁.symm e₂.symm⟩ + +/-- The Kronecker product of two Hadamard matrices is Hadamard. -/ +theorem IsHadamard.kronecker {A : Matrix m m R} {B : Matrix n n R} + (hA : A.IsHadamard) (hB : B.IsHadamard) : (A ⊗ₖ B).IsHadamard := by + refine ⟨fun _ _ ↦ mul_mem (hA.apply_mem _ _) (hB.apply_mem _ _), ?_, ?_⟩ <;> ext ⟨i, i'⟩ ⟨j, j'⟩ + · calc + _ = ∑ x₁, ∑ x₂, A i x₁ * (B i' x₂ * Bᴴ x₂ j') * Aᴴ x₁ j := by + simp [conjTranspose_kronecker', mul_apply, mul_assoc, ← Finset.sum_product'] + _ = if i' = j' then ∑ x, A i x * (Fintype.card n • Aᴴ) x j else 0 := by + simp [← Finset.sum_mul, ← Finset.mul_sum, ← mul_apply, hB.mul_conjTranspose, + one_apply, mul_assoc _ (Fintype.card n : R), -conjTranspose_apply] + _ = _ := by + simp only [← mul_apply, mul_smul_comm, hA.mul_conjTranspose] + simp [one_apply, ← Nat.cast_mul, mul_comm, ← ite_and, and_comm] + · calc + _ = ∑ x₁, ∑ x₂, Bᴴ i' x₂ * (Aᴴ i x₁ * A x₁ j) * B x₂ j' := by + simp [conjTranspose_kronecker', mul_apply, mul_assoc, ← Finset.sum_product'] + _ = if i = j then ∑ x, Bᴴ i' x * (Fintype.card m • B) x j' else 0 := by + rw [Finset.sum_comm] + simp [← Finset.sum_mul, ← Finset.mul_sum, ← mul_apply, hA.conjTranspose_mul, + one_apply, mul_assoc _ (Fintype.card m : R), -conjTranspose_apply] + _ = _ := by + simp only [← mul_apply, mul_smul_comm, hB.conjTranspose_mul] + simp [one_apply, ← Nat.cast_mul, ← ite_and] + +/-- A Hadamard matrix with constant column sum `s` has order `s * star s`, provided the order +is regular in `R`. + +The row-sum form is `IsHadamard.card_eq_star_mul_of_const_row_sum`; over a ring with trivial +star the conclusion becomes `(Fintype.card n : R) = s ^ 2`, a slightly stronger form of +[Theorem 2.3.7][deLauneyFlannery2011]: only a constant sum hypothesis on one side is needed +under the two-sided orthogonality condition. -/ +theorem IsHadamard.card_eq_mul_star_of_const_col_sum {s : R} + (hA : A.IsHadamard) (hcard : IsRegular (Fintype.card n : R)) + (hcol : ∀ j, ∑ i, A i j = s) : (Fintype.card n : R) = s * star s := by + have hvcol : (1 : n → R) ᵥ* A = s • 1 := by + ext j + simpa [Matrix.vecMul, dotProduct] using hcol j + have hconjcol : Aᴴ *ᵥ (1 : n → R) = star s • 1 := by + ext i + simp [Matrix.mulVec, dotProduct, ← star_sum, hcol i] + have hleft : (1 : n → R) ᵥ* (A * Aᴴ) ⬝ᵥ 1 = (Fintype.card n : R) ^ 2 := by + rw [hA.mul_conjTranspose, Nat.cast_smul_eq_nsmul, vecMul_smul, smul_dotProduct] + simp [dotProduct, pow_two] + have hright : (1 : n → R) ᵥ* (A * Aᴴ) ⬝ᵥ 1 = (Fintype.card n : R) * (s * star s) := by + rw [← vecMul_vecMul, ← dotProduct_mulVec, hvcol, hconjcol] + simp [dotProduct] + exact hcard.left <| show (Fintype.card n : R) * (Fintype.card n : R) = + (Fintype.card n : R) * (s * star s) by + simpa [pow_two] using hleft.symm.trans hright + +/-- A Hadamard matrix with constant row sum `s` has order `star s * s`, provided the order +is regular in `R`. This generalizes [Theorem 2.3.7][deLauneyFlannery2011]. -/ +theorem IsHadamard.card_eq_star_mul_of_const_row_sum {s : R} + (hA : A.IsHadamard) (hcard : IsRegular (Fintype.card n : R)) + (hrow : ∀ i, ∑ j, A i j = s) : (Fintype.card n : R) = star s * s := by + have hcol : ∀ j, ∑ i, Aᴴ i j = star s := fun j => by + simp [conjTranspose_apply, ← star_sum, hrow j] + simpa using hA.conjTranspose.card_eq_mul_star_of_const_col_sum hcard hcol + +end Semiring + +section CommSemiring +variable [CommSemiring R] [StarRing R] {A : Matrix n n R} + +/-- The transpose of a Hadamard matrix is Hadamard. + +Unlike `IsHadamard.conjTranspose` this requires commutativity: over a noncommutative ring the +transpose of a Hadamard matrix need not be Hadamard. -/ +theorem IsHadamard.transpose (hA : A.IsHadamard) : Aᵀ.IsHadamard where + apply_mem i j := hA.apply_mem j i + mul_conjTranspose := by + rw [conjTranspose_transpose_eq_transpose_conjTranspose, ← transpose_mul, hA.conjTranspose_mul, + transpose_smul, transpose_one] + conjTranspose_mul := by + rw [conjTranspose_transpose_eq_transpose_conjTranspose, ← transpose_mul, hA.mul_conjTranspose, + transpose_smul, transpose_one] + +@[simp] +theorem isHadamard_transpose_iff : Aᵀ.IsHadamard ↔ A.IsHadamard := + ⟨fun hA => by simpa using hA.transpose, (·.transpose)⟩ + +end CommSemiring + +section Ring +variable [Ring R] [StarRing R] {A : Matrix n n R} + +/-- Negating a Hadamard matrix gives a Hadamard matrix. -/ +theorem IsHadamard.neg (hA : A.IsHadamard) : (-A).IsHadamard := by + simpa [isHadamard_iff, Unitary.mem_iff] using hA + +/-- A matrix is Hadamard iff its negation is. -/ +@[simp] +theorem IsHadamard.neg_iff : (-A).IsHadamard ↔ A.IsHadamard := + ⟨fun hA => by simpa using hA.neg, (·.neg)⟩ + +end Ring + +section CommRing +variable [CommRing R] [StarRing R] {A : Matrix n n R} + +/-- The Hadamard determinant identity: `det A * star (det A) = (card n)^(card n)`. -/ +theorem IsHadamard.det_mul_star_det (hA : A.IsHadamard) : + A.det * star A.det = (Fintype.card n : R) ^ Fintype.card n := by + have := congr_arg det hA.mul_conjTranspose + rwa [det_mul, det_conjTranspose, det_smul, det_one, mul_one] at this + +/-- The Hadamard determinant identity: `star (det A) * det A = (card n)^(card n)`. -/ +theorem IsHadamard.star_det_mul_det (hA : A.IsHadamard) : + star A.det * A.det = (Fintype.card n : R) ^ Fintype.card n := by + rw [mul_comm, hA.det_mul_star_det] + +/-- A Hadamard matrix over a reduced commutative ring has nonzero determinant, provided the order +is nonzero in `R`. -/ +theorem IsHadamard.det_ne_zero [IsReduced R] (hA : A.IsHadamard) + (hcard : (Fintype.card n : R) ≠ 0) : A.det ≠ 0 := fun h => + pow_ne_zero _ hcard <| by rw [← hA.det_mul_star_det, h, star_zero, zero_mul] + +/-- The determinant of a Hadamard matrix is regular, provided the order is regular in `R`. -/ +theorem IsHadamard.isRegular_det (hA : A.IsHadamard) + (hcard : IsRegular (Fintype.card n : R)) : IsRegular A.det := by + have : IsRegular (A.det * star A.det) := by + rw [hA.det_mul_star_det] + exact hcard.pow _ + exact this.of_mul_left + +/-- Build a Hadamard matrix from the one-sided row-orthogonality condition, provided the order is +regular in `R`. + +This is the matrix form of [Theorem 2.3.6][deLauneyFlannery2011]. -/ +theorem IsHadamard.of_mul_conjTranspose + (hentry : ∀ i j, A i j ∈ unitary R) + (hmul : A * Aᴴ = (Fintype.card n : R) • (1 : Matrix n n R)) + (hcard : IsRegular (Fintype.card n : R)) : A.IsHadamard := by + refine ⟨hentry, hmul, ?_⟩ + have hdet : IsRegular (A.det * star A.det) := by + have := congr_arg det hmul + rw [det_mul, det_conjTranspose, det_smul, det_one, mul_one] at this + rw [this] + exact hcard.pow _ + have hreg : IsLeftRegular A := + (isRegular_of_isLeftRegular_det hdet.of_mul_left.left).left + exact hreg <| show A * (Aᴴ * A) = A * ((Fintype.card n : R) • 1) by + rw [← mul_assoc, hmul, smul_mul_assoc, one_mul, mul_smul_comm, mul_one] + +theorem isHadamard_iff_mul_conjTranspose + (hcard : IsRegular (Fintype.card n : R)) : + A.IsHadamard ↔ + (∀ i j, A i j ∈ unitary R) ∧ + A * Aᴴ = (Fintype.card n : R) • (1 : Matrix n n R) := + ⟨fun hA => ⟨hA.apply_mem, hA.mul_conjTranspose⟩, + fun hA => IsHadamard.of_mul_conjTranspose hA.1 hA.2 hcard⟩ + +end CommRing + +/-- An integer Hadamard matrix of order greater than two has order divisible by four. + +This is the standard divisibility obstruction in [Section 2.3][deLauneyFlannery2011]. -/ +theorem IsHadamard.four_dvd_card {A : Matrix n n ℤ} + (hA : A.IsHadamard) (hcard : 2 < Fintype.card n) : 4 ∣ Fintype.card n := by + have hpm : ∀ i j, A i j = 1 ∨ A i j = -1 := fun i j => + Unitary.mem_iff_eq_one_or_eq_neg_one.mp (hA.apply_mem i j) + obtain ⟨r, s, t, hrs, hrt, hst⟩ := Fintype.two_lt_card_iff.mp hcard + have horth ⦃i k : n⦄ (hik : i ≠ k) : ∑ j, A i j * A k j = 0 := by + simpa [Matrix.mul_apply, hik] using congr_fun (congr_fun hA.mul_conjTranspose i) k + have hexpand : ∀ j, (1 + A s j * A r j) * (1 + A t j * A r j) = + 1 + A s j * A r j + A t j * A r j + A s j * A t j := fun j => by + obtain hr | hr := hpm r j <;> simp [hr] <;> ring + have hdvd : ∀ j, (4 : ℤ) ∣ (1 + A s j * A r j) * (1 + A t j * A r j) := fun j => by + obtain hs | hs := hpm s j <;> obtain hr | hr := hpm r j <;> + obtain ht | ht := hpm t j <;> simp [hs, hr, ht] + have hsum : ∑ j, (1 + A s j * A r j) * (1 + A t j * A r j) = (Fintype.card n : ℤ) := by + simp_rw [hexpand] + simp [Finset.sum_add_distrib, horth hrs.symm, horth hrt.symm, horth hst] + rw [← Int.ofNat_dvd, ← hsum] + exact Finset.dvd_sum fun j _ => hdvd j + +end Matrix diff --git a/docs/references.bib b/docs/references.bib index 96ac2dcb039f3c..064ad6e45eed78 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -1580,6 +1580,17 @@ @Article{ day1972 url = {https://doi.org/10.1016/0022-4049(72)90021-7} } +@Book{ deLauneyFlannery2011, + author = {de Launey, Warwick and Flannery, Dane L.}, + title = {Algebraic Design Theory}, + series = {Mathematical Surveys and Monographs}, + volume = {175}, + publisher = {American Mathematical Society}, + year = {2011}, + doi = {10.1090/surv/175}, + url = {https://doi.org/10.1090/surv/175} +} + @InProceedings{ deligne_formulaire, author = {Deligne, P.}, title = {Courbes elliptiques: formulaire d'apr\`es {J}. {T}ate}, From db127794c79fdeb86f6b0cf6ff2c804026fbaff1 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:37:42 +0000 Subject: [PATCH 0078/1300] feat(NumberTheory): costa-pereira inequalities (#40569) Co-authored-by: Terence Tao Co-authored-by: Oliver Nash --- Mathlib/NumberTheory/Chebyshev.lean | 182 +++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 15 deletions(-) diff --git a/Mathlib/NumberTheory/Chebyshev.lean b/Mathlib/NumberTheory/Chebyshev.lean index 7bba721b9fdd3e..85cab1e97e9ab0 100644 --- a/Mathlib/NumberTheory/Chebyshev.lean +++ b/Mathlib/NumberTheory/Chebyshev.lean @@ -36,8 +36,12 @@ These give logarithmically weighted sums of primes and prime powers. - `Chebyshev.theta_eq_log_primorial` shows that `θ x` is the log of the product of primes up to x - `Chebyshev.theta_le_log4_mul_x` gives Chebyshev's upper bound on `θ` - `Chebyshev.theta_ge` gives Chebyshev's lower bound on `θ`. -- `Chebyshev.psi_eq_log_lcmUpto` shows that `ψ n` is the log of the lcm of `{1,...,n}` -- `Chebyshev.psi_eq_sum_theta` and `Chebyshev.psi_eq_theta_add_sum_theta` relate `psi` to `theta`. +- `Chebyshev.psi_eq_log_lcmUpto` shows that `ψ n` is the log of the lcm of `{1,...,n}`. +- `Chebyshev.psi_eq_sum_theta` and `Chebyshev.psi_eq_theta_add_sum_theta` relate `ψ` to `θ`. +- `Chebyshev.psi_sub_theta_le_mul_sqrt` gives an upper bound on `ψ - θ`. +- `Chebyshev.psi_sub_theta_le_psi_add_psi_add_psi` and + `Chebyshev.psi_sub_theta_ge_psi_add_psi_add_psi` establish the Costa-Pereira inequalities + for `ψ - θ`. - `Chebyshev.psi_le_const_mul_self` gives Chebyshev's upper bound on `ψ`. - `Chebyshev.psi_ge` gives Chebyshev's lower bound on `ψ`. - `Chebyshev.primeCounting_eq_theta_div_log_add_integral` relates the prime counting function to `θ` @@ -113,6 +117,18 @@ theorem psi_eq_zero_of_lt_two {x : ℝ} (hx : x < 2) : ψ x = 0 := by norm_cast at this linarith +@[simp] +theorem psi_eq_zero_iff {x : ℝ} : ψ x = 0 ↔ x < 2 := by + refine ⟨fun h₀ ↦ ?_, psi_eq_zero_of_lt_two⟩ + by_contra! contra + replace contra : 2 ∈ Ioc 0 ⌊x⌋₊ := by rw [mem_Ioc, le_floor_iff (by grind)]; grind + have : Λ 2 ≤ ψ x := single_le_sum (fun n _ ↦ vonMangoldt_nonneg (n := n)) contra + have := vonMangoldt_pos_iff.mpr prime_two.isPrimePow + linarith + +theorem psi_eq_zero_of_le_one {x : ℝ} (hx : x ≤ 1) : ψ x = 0 := + psi_eq_zero_of_lt_two (by linarith) + @[simp] theorem psi_zero : ψ 0 = 0 := psi_eq_zero_of_lt_two zero_lt_two @@ -127,6 +143,19 @@ theorem theta_eq_zero_of_lt_two {x : ℝ} (hx : x < 2) : θ x = 0 := by norm_cast at ⊢ this linarith +@[simp] +theorem theta_eq_zero_iff {x : ℝ} : θ x = 0 ↔ x < 2 := by + refine ⟨fun h₀ ↦ ?_, theta_eq_zero_of_lt_two⟩ + by_contra! contra + replace contra : 2 ∈ Ioc 0 ⌊x⌋₊ := by rw [mem_Ioc, le_floor_iff (by grind)]; grind + have h₁ : log (↑(2 : ℕ) : ℝ) ≤ θ x := + single_le_sum (fun p hp ↦ log_nonneg (by aesop)) (by aesop (add simp prime_two)) + have := Real.log_pos one_lt_two + grind + +theorem theta_eq_zero_of_le_one {x : ℝ} (hx : x ≤ 1) : θ x = 0 := + theta_eq_zero_of_lt_two (by linarith) + @[simp] theorem theta_zero : θ 0 = 0 := theta_eq_zero_of_lt_two zero_lt_two @@ -305,10 +334,11 @@ are close. -/ /-- A sum over prime powers may be written as a double sum over exponents and then primes. -/ -theorem sum_PrimePow_eq_sum_sum {R : Type*} [AddCommMonoid R] (f : ℕ → R) {x : ℝ} (hx : 0 ≤ x) : +theorem sum_PrimePow_eq_sum_sum' {R : Type*} [AddCommMonoid R] (f : ℕ → R) {x : ℝ} (hx : 0 ≤ x) + {N : ℕ} (hN : ⌊log x / log 2⌋₊ ≤ N) : ∑ n ∈ Ioc 0 ⌊x⌋₊ with IsPrimePow n, f n - = ∑ k ∈ Icc 1 ⌊log x / log 2⌋₊, ∑ p ∈ Ioc 0 ⌊x ^ ((1 : ℝ) / k)⌋₊ with p.Prime, f (p ^ k) := by - trans ∑ ⟨k, p⟩ ∈ Icc 1 ⌊log x / log 2⌋₊ ×ˢ (Ioc 0 ⌊x⌋₊).filter Nat.Prime + = ∑ k ∈ Icc 1 N, ∑ p ∈ Ioc 0 ⌊x ^ ((1 : ℝ) / k)⌋₊ with p.Prime, f (p ^ k) := by + trans ∑ ⟨k, p⟩ ∈ Icc 1 N ×ˢ (Ioc 0 ⌊x⌋₊).filter Nat.Prime with p ≤ ⌊x ^ (k : ℝ)⁻¹⌋₊, f (p ^ k) · refine (sum_bij (i := fun ⟨k, p⟩ _ ↦ p ^ k) ?_ ?_ ?_ ?_).symm · simp +contextual [hx, rpow_nonneg, le_floor_iff, ← pos_iff_ne_zero, Prime.isPrimePow, @@ -321,7 +351,7 @@ theorem sum_PrimePow_eq_sum_sum {R : Type*} [AddCommMonoid R] (f : ℕ → R) {x mem_product, mem_Icc, succ_le_iff, exists_prop, Prod.exists, exists_and_left, and_imp] rintro b _ hbx ⟨p, k, hp, hk₀, rfl⟩ rw [cast_pow] at hbx - refine ⟨k, hk₀, le_floor ?_, p, hp.nat_prime.pos, ?_, hp.nat_prime, ?_, rfl⟩ + refine ⟨k, hk₀, (le_floor ?_).trans hN, p, hp.nat_prime.pos, ?_, hp.nat_prime, ?_, rfl⟩ · rw [le_div_iff₀ (log_pos (by norm_num)), ← Real.log_pow] gcongr apply (LE.le.trans ?_ hbx) @@ -343,21 +373,35 @@ theorem sum_PrimePow_eq_sum_sum {R : Type*} [AddCommMonoid R] (f : ℕ → R) {x contrapose! this apply rpow_lt_one hx this (by bound) -theorem psi_eq_sum_theta {x : ℝ} (hx : 0 ≤ x) : - ψ x = ∑ n ∈ Icc 1 ⌊log x / log 2⌋₊, θ (x ^ ((1 : ℝ) / n)) := by - simp_rw [psi, vonMangoldt_apply, ← sum_filter, sum_PrimePow_eq_sum_sum _ hx] +theorem sum_PrimePow_eq_sum_sum {R : Type*} [AddCommMonoid R] (f : ℕ → R) {x : ℝ} (hx : 0 ≤ x) : + ∑ n ∈ Ioc 0 ⌊x⌋₊ with IsPrimePow n, f n + = ∑ k ∈ Icc 1 ⌊log x / log 2⌋₊, ∑ p ∈ Ioc 0 ⌊x ^ ((1 : ℝ) / k)⌋₊ with p.Prime, f (p ^ k) := + sum_PrimePow_eq_sum_sum' f hx (le_refl _) + +theorem psi_eq_sum_theta' {x : ℝ} (hx : 0 ≤ x) {N : ℕ} (hN : ⌊log x / log 2⌋₊ ≤ N) : + ψ x = ∑ n ∈ Icc 1 N, θ (x ^ ((1 : ℝ) / n)) := by + simp_rw [psi, vonMangoldt_apply, ← sum_filter, sum_PrimePow_eq_sum_sum' _ hx hN] apply sum_congr rfl fun _ hk ↦ sum_congr rfl fun _ _ ↦ ?_ rw [Prime.pow_minFac _ (by linarith [mem_Icc.mp hk])] simp_all -theorem psi_eq_theta_add_sum_theta {x : ℝ} (hx : 2 ≤ x) : - ψ x = θ x + ∑ n ∈ Icc 2 ⌊log x / log 2⌋₊, θ (x ^ ((1 : ℝ) / n)) := by - rw [psi_eq_sum_theta (by linarith), ← add_sum_Ioc_eq_sum_Icc] +theorem psi_eq_sum_theta {x : ℝ} (hx : 0 ≤ x) : + ψ x = ∑ n ∈ Icc 1 ⌊log x / log 2⌋₊, θ (x ^ ((1 : ℝ) / n)) := + psi_eq_sum_theta' hx (le_refl _) + +theorem psi_eq_theta_add_sum_theta' {x : ℝ} (hx : 2 ≤ x) {N : ℕ} (hN : ⌊log x / log 2⌋₊ ≤ N) : + ψ x = θ x + ∑ n ∈ Icc 2 N, θ (x ^ ((1 : ℝ) / n)) := by + rw [psi_eq_sum_theta' (by linarith) hN, ← add_sum_Ioc_eq_sum_Icc] · congr simp - · rw [le_floor_iff' one_ne_zero, le_div_iff₀ (by positivity), cast_one, one_mul] + · apply le_trans _ hN + rw [le_floor_iff' one_ne_zero, le_div_iff₀ (by positivity), cast_one, one_mul] gcongr +theorem psi_eq_theta_add_sum_theta {x : ℝ} (hx : 2 ≤ x) : + ψ x = θ x + ∑ n ∈ Icc 2 ⌊log x / log 2⌋₊, θ (x ^ ((1 : ℝ) / n)) := + psi_eq_theta_add_sum_theta' hx (le_refl _) + theorem theta_le_psi (x : ℝ) : θ x ≤ ψ x := by by_cases! h : x < 2 · rw [theta_eq_zero_of_lt_two h, psi_eq_zero_of_lt_two h] @@ -365,8 +409,8 @@ theorem theta_le_psi (x : ℝ) : θ x ≤ ψ x := by simp only [le_add_iff_nonneg_right] exact sum_nonneg fun _ _ ↦ theta_nonneg _ ---Note that a more careful argument could remove the log x in the following with a worse constant. -/-- `|ψ x - θ x| ≤ c √ x log x` with an explicit constant c. -/ +/-- `|ψ x - θ x| ≤ c √ x log x` with an explicit constant c. To remove the log, see +`psi_sub_theta_le_mul_sqrt`. -/ theorem abs_psi_sub_theta_le_sqrt_mul_log {x : ℝ} (hx : 1 ≤ x) : |ψ x - θ x| ≤ 2 * x.sqrt * x.log := by by_cases! hx : x < 2 @@ -462,6 +506,114 @@ theorem theta_ge' {x : ℝ} (hx : 1 ≤ x) : grw [psi_ge' (by linarith)] linarith [psi_sub_theta_le hx] +section CostaPereira + +/-! ## The Costa-Pereira inequalities + +The Costa-Pereira inequalities give explicit upper and lower bounds on the difference +`ψ x - θ x`, namely that they lie between `ψ x^(1/2) + ψ x^(1/3) + ψ x^(1/7)` and +`ψ x^(1/2) + ψ x^(1/3) + ψ x^(1/5)`. These are useful for applications in explicit +analytic number theory. -/ + +variable (x : ℝ) (n : ℕ) + +private noncomputable def b := θ (x ^ (n : ℝ)⁻¹) + +private noncomputable def c := b x (6 * n - 1) - b x (6 * n) + b x (6 * n + 1) + +private theorem b_antitone (hx : 0 ≤ x) : AntitoneOn (b x) (.Ici 1) := by + intro n hn m hm hnm; unfold b + simp only [Set.mem_Ici] at hn hm + rcases le_or_gt x 1 with h | h + · repeat rw [theta_eq_zero_of_le_one (rpow_le_one hx h (by positivity))] + apply theta_mono (monotone_rpow_of_base_ge_one h.le _) + field_simp + norm_num [hnm] + +private theorem psi_pow_eq_sum_b (hx : 0 ≤ x) : ∃ M, ∀ N ≥ M, + ψ (x ^ (n : ℝ)⁻¹) = ∑ k ∈ Icc 1 N, b x (n * k) := by + have : 0 ≤ x ^ ((n : ℝ)⁻¹) := by positivity + use ⌊log (x ^ (n : ℝ)⁻¹) / log 2⌋₊ + intro N hN + simp_rw [psi_eq_sum_theta' this hN, one_div, b, cast_mul, mul_inv_rev, mul_comm, + ← rpow_mul (by positivity)] + +private theorem sum_b_eq_b_add_sum_add_sum_add_sum (N : ℕ) : + ∑ n ∈ Icc 1 (1 + 6 * N), b x n = + b x 1 + + ∑ n ∈ Icc 1 (3 * N), b x (2 * n) + + ∑ n ∈ Icc 1 (2 * N), b x (3 * n) + + ∑ n ∈ Icc 1 N, c x n := by + induction N with + | zero => simp + | succ N ih => + rw [show 1 + 6 * (N + 1) = (1 + 6 * N) + 1 + 1 + 1 + 1 + 1 + 1 by ring, + show 3 * (N + 1) = 3 * N + 1 + 1 + 1 by ring, + show 2 * (N + 1) = 2 * N + 1 + 1 by ring] + simp only [le_add_iff_nonneg_left, _root_.zero_le, sum_Icc_succ_top, ih, c] + rw [show 6 * (N + 1) - 1 = 6 * N + 5 by lia] + ring_nf + +private theorem psi_sub_theta_bounds {x : ℝ} (hx : 0 ≤ x) : + ψ x - θ x ≤ ψ (x ^ (2 : ℝ)⁻¹) + ψ (x ^ (3 : ℝ)⁻¹) + ψ (x ^ (5 : ℝ)⁻¹) ∧ + ψ (x ^ (2 : ℝ)⁻¹) + ψ (x ^ (3 : ℝ)⁻¹) + ψ (x ^ (7 : ℝ)⁻¹) ≤ ψ x - θ x := by + obtain ⟨N₁, h1⟩ := psi_pow_eq_sum_b x 1 hx + obtain ⟨N₂, h2⟩ := psi_pow_eq_sum_b x 2 hx + obtain ⟨N₃, h3⟩ := psi_pow_eq_sum_b x 3 hx + obtain ⟨N₅, h5⟩ := psi_pow_eq_sum_b x 5 hx + obtain ⟨N₇, h7⟩ := psi_pow_eq_sum_b x 7 hx + let N := N₁ + N₂ + N₃ + N₅ + N₇ + specialize h1 (1 + 6 * N) (by lia) + specialize h2 (3 * N) (by lia) + specialize h3 (2 * N) (by lia) + specialize h5 N (by lia) + specialize h7 N (by lia) + have : ∑ n ∈ Icc 1 N, c x n ≤ ∑ n ∈ Icc 1 N, b x (5 * n) := by + apply sum_le_sum + intro n hn + unfold c + linarith [(b_antitone x hx (by grind) (by grind) (by lia) : b x (6 * n + 1) ≤ b x (6 * n)), + (b_antitone x hx (by grind) (by grind) (by lia) : b x (6 * n - 1) ≤ b x (5 * n))] + have : ∑ n ∈ Icc 1 N, b x (7 * n) ≤ ∑ n ∈ Icc 1 N, c x n := by + apply sum_le_sum; intro n hn; simp only [mem_Icc, c] at hn ⊢ + linarith [(b_antitone x hx (by grind) (by grind) (by lia) : b x (6 * n) ≤ b x (6 * n - 1)), + (b_antitone x hx (by grind) (by grind) (by lia) : b x (7 * n) ≤ b x (6 * n + 1))] + have : b x 1 = θ x := by simp [b] + simp only [cast_one, one_mul, sum_b_eq_b_add_sum_add_sum_add_sum, inv_one, rpow_one] at h1 + grind + +theorem psi_sub_theta_le_psi_add_psi_add_psi (x : ℝ) : + ψ x - θ x ≤ ψ (x ^ (2 : ℝ)⁻¹) + ψ (x ^ (3 : ℝ)⁻¹) + ψ (x ^ (5 : ℝ)⁻¹) := by + rcases le_total x 0 with hx | hx + · grind [theta_eq_zero_iff, psi_eq_zero_iff, psi_nonneg] + · exact (psi_sub_theta_bounds hx).1 + +theorem psi_sub_theta_ge_psi_add_psi_add_psi {x : ℝ} (hx : 0 ≤ x) : + ψ (x ^ (2 : ℝ)⁻¹) + ψ (x ^ (3 : ℝ)⁻¹) + ψ (x ^ (7 : ℝ)⁻¹) ≤ ψ x - θ x := + (psi_sub_theta_bounds hx).2 + +/-- `ψ x = θ x + O( √x )`. -/ +theorem psi_sub_theta_le_mul_sqrt : ∃ C, ∀ x, ψ x - θ x ≤ C * x.sqrt := by + use (log 4 + 4) * 3 + intro x + rcases le_total x 1 with h | h + · rw [theta_eq_zero_of_le_one h, psi_eq_zero_of_le_one h, sub_self]; positivity + have (n : ℕ) (hn : 2 ≤ n) : ψ (x ^ (1 / (n : ℝ))) ≤ (log 4 + 4) * x.sqrt := by + grw [psi_le_const_mul_self (by positivity), sqrt_eq_rpow x]; gcongr; norm_cast + linarith [psi_sub_theta_le_psi_add_psi_add_psi x, this 2 (le_refl _), this 3 (by norm_num), + this 5 (by norm_num)] + +open Asymptotics Filter in +theorem isBigO_psi_sub_theta_sqrt : IsBigO atTop (ψ - θ) sqrt := by + simp_rw [isBigO_iff, Pi.sub_apply, norm_eq_abs, eventually_atTop] + obtain ⟨C, hC⟩ := psi_sub_theta_le_mul_sqrt + refine ⟨C, 0, fun x _ ↦ ?_⟩ + have := theta_le_psi x + rw [abs_of_nonneg (by positivity), abs_of_nonneg (by positivity)] + exact hC x + +end CostaPereira + section PrimeCounting /-! ## Relation to prime counting From 56d32c2bd1a2ad4911817bafc345c72e9159ad8a Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 16 Jun 2026 19:20:43 +0000 Subject: [PATCH 0079/1300] chore: golf proofs which use autogenerated lemmas (#40657) This removes all exceptions of the linter except in CategoryTheory/Functor/Category.lean (which I do not understand) Co-authored-by: Batixx --- .../Calculus/FormalMultilinearSeries.lean | 9 ++------- Mathlib/Data/List/Sigma.lean | 19 +++++++++---------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean index 487a58b2cdcfc9..c868edf4a29c29 100644 --- a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean +++ b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean @@ -388,17 +388,12 @@ theorem constFormalMultilinearSeries_apply_of_nonzero [NontriviallyNormedField {n : ℕ} (hn : n ≠ 0) : constFormalMultilinearSeries 𝕜 E c n = 0 := Nat.casesOn n (fun hn => (hn rfl).elim) (fun _ _ => rfl) hn -set_option linter.auxLemma false in @[simp] lemma constFormalMultilinearSeries_zero [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedSpace 𝕜 E] [NormedSpace 𝕜 F] : constFormalMultilinearSeries 𝕜 E (0 : F) = 0 := by - ext n x - simp only [FormalMultilinearSeries.zero_apply, ContinuousMultilinearMap.zero_apply, - constFormalMultilinearSeries] - induction n - · simp only [ContinuousMultilinearMap.uncurry0_apply] - · simp only [constFormalMultilinearSeries.match_1.eq_2, ContinuousMultilinearMap.zero_apply] + ext n + induction n <;> simp @[simp] lemma compContinuousLinearMap_zero [NontriviallyNormedField 𝕜] diff --git a/Mathlib/Data/List/Sigma.lean b/Mathlib/Data/List/Sigma.lean index f66a6b2837f6ce..b7dc804c2cc447 100644 --- a/Mathlib/Data/List/Sigma.lean +++ b/Mathlib/Data/List/Sigma.lean @@ -547,10 +547,8 @@ theorem kerase_comm (a₁ a₂) (l : List (Sigma β)) : else by simp [ha₂, mt mem_keys_of_mem_keys_kerase ha₂] else by simp [ha₁, mt mem_keys_of_mem_keys_kerase ha₁] -set_option linter.auxLemma false in theorem sizeOf_kerase [SizeOf (Sigma β)] (x : α) (xs : List (Sigma β)) : SizeOf.sizeOf (List.kerase x xs) ≤ SizeOf.sizeOf xs := by - simp only [SizeOf.sizeOf, _sizeOf_1] induction xs with | nil => simp | cons y ys => by_cases x = y.1 <;> simp [*] @@ -618,7 +616,6 @@ theorem dedupKeys_cons {x : Sigma β} (l : List (Sigma β)) : dedupKeys (x :: l) = kinsert x.1 x.2 (dedupKeys l) := rfl - theorem nodupKeys_dedupKeys (l : List (Sigma β)) : NodupKeys (dedupKeys l) := by dsimp [dedupKeys] generalize hl : nil = l' @@ -647,17 +644,19 @@ theorem dlookup_dedupKeys (a : α) (l : List (Sigma β)) : dlookup a (dedupKeys · rw [dedupKeys_cons, dlookup_kinsert_ne h, l_ih, dlookup_cons_ne] exact h -set_option linter.auxLemma false in +theorem sizeOf_cons_le_sizeOf_cons {α : Type*} [SizeOf α] {l r : List α} (a : α) + (h : SizeOf.sizeOf l ≤ SizeOf.sizeOf r) : + SizeOf.sizeOf (a :: l) ≤ SizeOf.sizeOf (a :: r) := by + rw [cons.sizeOf_spec, cons.sizeOf_spec] + exact Nat.add_le_add_iff_left.mpr h + theorem sizeOf_dedupKeys [SizeOf (Sigma β)] (xs : List (Sigma β)) : SizeOf.sizeOf (dedupKeys xs) ≤ SizeOf.sizeOf xs := by - simp only [SizeOf.sizeOf, _sizeOf_1] induction xs with | nil => simp [dedupKeys] - | cons x xs => - simp only [dedupKeys_cons, kinsert_def, Nat.add_le_add_iff_left, Sigma.eta] - trans - · apply sizeOf_kerase - · assumption + | cons x xs h => + simp only [dedupKeys_cons, kinsert_def, Sigma.eta] + exact sizeOf_cons_le_sizeOf_cons x (le_trans (sizeOf_kerase x.fst xs.dedupKeys) h) /-! ### `kunion` -/ From da24afce9320416675a1169dd0c73919ceca018e Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:10:10 +0000 Subject: [PATCH 0080/1300] chore: avoid `meta`-importing math files (#40671) It should never be neccessary to meta import a maths file, so this PR removes some such imports. In some cases this was caused by a `public meta section` at the top of a tactic file, even though there are some definitions in the file that should not be meta (because they are used as part of the generated proofs). --- Mathlib/Data/Rat/Floor.lean | 1 - .../RingTheory/Coalgebra/TensorProduct.lean | 3 +-- Mathlib/Tactic/CancelDenoms/Core.lean | 1 - .../CategoryTheory/BicategoryCoherence.lean | 11 +++++------ Mathlib/Tactic/CategoryTheory/Coherence.lean | 19 ++++++++----------- Mathlib/Tactic/CongrExclamation.lean | 2 +- Mathlib/Tactic/IntervalCases.lean | 1 - Mathlib/Tactic/ModCases.lean | 11 +++++------ Mathlib/Tactic/NormNum/LegendreSymbol.lean | 7 ++++--- Mathlib/Tactic/Positivity/Basic.lean | 1 - Mathlib/Tactic/Ring/Basic.lean | 4 +--- Mathlib/Tactic/Ring/Common.lean | 3 --- Mathlib/Tactic/Sat/FromLRAT.lean | 1 - Mathlib/Tactic/Simproc/Divisors.lean | 2 +- Mathlib/Tactic/Simproc/Factors.lean | 1 - 15 files changed, 26 insertions(+), 42 deletions(-) diff --git a/Mathlib/Data/Rat/Floor.lean b/Mathlib/Data/Rat/Floor.lean index 8fd070adc7bc46..613f5decc4b6b5 100644 --- a/Mathlib/Data/Rat/Floor.lean +++ b/Mathlib/Data/Rat/Floor.lean @@ -9,7 +9,6 @@ public import Mathlib.Algebra.Order.Round public import Mathlib.Data.Rat.Cast.Order public import Mathlib.Tactic.FieldSimp public import Mathlib.Tactic.Ring -meta import Mathlib.Algebra.Order.Floor.Defs public meta import Mathlib.Algebra.Order.Round /-! diff --git a/Mathlib/RingTheory/Coalgebra/TensorProduct.lean b/Mathlib/RingTheory/Coalgebra/TensorProduct.lean index 3048b5ec4dd08a..0b22dc3521a3b9 100644 --- a/Mathlib/RingTheory/Coalgebra/TensorProduct.lean +++ b/Mathlib/RingTheory/Coalgebra/TensorProduct.lean @@ -8,8 +8,7 @@ module public import Mathlib.LinearAlgebra.TensorProduct.Tower public import Mathlib.RingTheory.Coalgebra.Equiv -meta import Mathlib.RingTheory.Coalgebra.CoassocSimps - +import Mathlib.RingTheory.Coalgebra.CoassocSimps import Mathlib.Algebra.Algebra.Bilinear /-! diff --git a/Mathlib/Tactic/CancelDenoms/Core.lean b/Mathlib/Tactic/CancelDenoms/Core.lean index af4068c577306c..2751270e0cc562 100644 --- a/Mathlib/Tactic/CancelDenoms/Core.lean +++ b/Mathlib/Tactic/CancelDenoms/Core.lean @@ -6,7 +6,6 @@ Authors: Robert Y. Lewis module public meta import Mathlib.Data.Tree.Basic -public meta import Mathlib.Logic.Basic public import Mathlib.Algebra.Field.Basic public meta import Mathlib.Algebra.Group.Nat.Defs public import Mathlib.Algebra.Order.Ring.Defs diff --git a/Mathlib/Tactic/CategoryTheory/BicategoryCoherence.lean b/Mathlib/Tactic/CategoryTheory/BicategoryCoherence.lean index 3e110d1fdc6191..47d34a4493ae79 100644 --- a/Mathlib/Tactic/CategoryTheory/BicategoryCoherence.lean +++ b/Mathlib/Tactic/CategoryTheory/BicategoryCoherence.lean @@ -5,7 +5,6 @@ Authors: Yuma Mizuno -/ module -public meta import Mathlib.CategoryTheory.Bicategory.Free public import Mathlib.CategoryTheory.Bicategory.Free public import Mathlib.Tactic.CategoryTheory.BicategoricalComp @@ -22,7 +21,7 @@ tactic is given in `Mathlib/Tactic/CategoryTheory/Coherence.lean` at the same ti tactic for monoidal categories. -/ -public meta section +public section noncomputable section @@ -93,11 +92,11 @@ instance liftHom₂WhiskerRight {f g : a ⟶ b} (η : f ⟶ g) [LiftHom f] [Lift open Lean Elab Tactic Meta /-- Helper function for throwing exceptions. -/ -def exception {α : Type} (g : MVarId) (msg : MessageData) : MetaM α := +meta def exception {α : Type} (g : MVarId) (msg : MessageData) : MetaM α := throwTacticEx `bicategorical_coherence g msg /-- Helper function for throwing exceptions with respect to the main goal. -/ -def exception' (msg : MessageData) : TacticM Unit := do +meta def exception' (msg : MessageData) : TacticM Unit := do try liftMetaTactic (exception (msg := msg)) catch _ => @@ -108,13 +107,13 @@ set_option quotPrecheck false in /-- Auxiliary definition for `bicategorical_coherence`. -/ -- We could construct this expression directly without using `elabTerm`, -- but it would require preparing many implicit arguments by hand. -def mkLiftMap₂LiftExpr (e : Expr) : TermElabM Expr := do +meta def mkLiftMap₂LiftExpr (e : Expr) : TermElabM Expr := do Term.elabTerm (← ``((FreeBicategory.lift (Prefunctor.id _)).map₂ (LiftHom₂.lift $(← Term.exprToSyntax e)))) none /-- Coherence tactic for bicategories. -/ -def bicategoryCoherence (g : MVarId) : TermElabM Unit := g.withContext do +meta def bicategoryCoherence (g : MVarId) : TermElabM Unit := g.withContext do withOptions (fun opts => synthInstance.maxSize.set opts (max 256 (synthInstance.maxSize.get opts))) do let thms := [``BicategoricalCoherence.iso, ``Iso.trans, ``Iso.symm, ``Iso.refl, diff --git a/Mathlib/Tactic/CategoryTheory/Coherence.lean b/Mathlib/Tactic/CategoryTheory/Coherence.lean index 1154d770d6d945..549bbcd6437fb5 100644 --- a/Mathlib/Tactic/CategoryTheory/Coherence.lean +++ b/Mathlib/Tactic/CategoryTheory/Coherence.lean @@ -5,10 +5,7 @@ Authors: Kim Morrison, Yuma Mizuno, Oleksandr Manzyuk -/ module -public meta import Mathlib.Lean.Meta public import Mathlib.CategoryTheory.Monoidal.Free.Basic -public meta import Mathlib.CategoryTheory.Monoidal.Free.Basic -public import Mathlib.Lean.Meta public import Mathlib.Tactic.CategoryTheory.BicategoryCoherence public import Mathlib.Tactic.CategoryTheory.MonoidalComp @@ -27,7 +24,7 @@ are equal. -/ -public meta section +public section universe v u @@ -112,11 +109,11 @@ end lifting open Lean Meta Elab Tactic /-- Helper function for throwing exceptions. -/ -def exception {α : Type} (g : MVarId) (msg : MessageData) : MetaM α := +meta def exception {α : Type} (g : MVarId) (msg : MessageData) : MetaM α := throwTacticEx `monoidal_coherence g msg /-- Helper function for throwing exceptions with respect to the main goal. -/ -def exception' (msg : MessageData) : TacticM Unit := do +meta def exception' (msg : MessageData) : TacticM Unit := do try liftMetaTactic (exception (msg := msg)) catch _ => @@ -126,13 +123,13 @@ def exception' (msg : MessageData) : TacticM Unit := do /-- Auxiliary definition for `monoidal_coherence`. -/ -- We could construct this expression directly without using `elabTerm`, -- but it would require preparing many implicit arguments by hand. -def mkProjectMapExpr (e : Expr) : TermElabM Expr := do +meta def mkProjectMapExpr (e : Expr) : TermElabM Expr := do Term.elabTerm (← ``(FreeMonoidalCategory.projectMap _root_.id _ _ (LiftHom.lift $(← Term.exprToSyntax e)))) none /-- Coherence tactic for monoidal categories. -/ -def monoidalCoherence (g : MVarId) : TermElabM Unit := g.withContext do +meta def monoidalCoherence (g : MVarId) : TermElabM Unit := g.withContext do withOptions (fun opts => synthInstance.maxSize.set opts (max 512 (synthInstance.maxSize.get opts))) do let thms := [``MonoidalCoherence.iso, ``Iso.trans, ``Iso.symm, ``Iso.refl, @@ -157,7 +154,7 @@ open Mathlib.Tactic.BicategoryCoherence /-- If set to `false`, the warning on the use of the deprecated coherence tactic is disabled. -/ -register_option warn.refl_coherence : Bool := { +meta register_option warn.refl_coherence : Bool := { defValue := true descr := "warn when the deprecated coherence tactic is used" } @@ -233,7 +230,7 @@ lemma insert_id_rhs {C : Type*} [Category* C] {X Y : C} (f g : X ⟶ Y) (w : f = simpa using w /-- If either the lhs or rhs is not a composition, compose it on the right with an identity. -/ -def insertTrailingIds (g : MVarId) : MetaM MVarId := do +meta def insertTrailingIds (g : MVarId) : MetaM MVarId := do let some (_, lhs, rhs) := (← withReducible g.getType').eq? | exception g "Not an equality." let mut g := g if !(lhs.isAppOf ``CategoryStruct.comp) then @@ -248,7 +245,7 @@ def insertTrailingIds (g : MVarId) : MetaM MVarId := do -- Porting note: this is an ugly port, using too many `evalTactic`s. -- We can refactor later into either a `macro` (but the flow control is awkward) -- or a `MetaM` tactic. -def coherenceLoop (maxSteps := 37) : TacticM Unit := +meta def coherenceLoop (maxSteps := 37) : TacticM Unit := match maxSteps with | 0 => exception' "`coherence` tactic reached iteration limit" | maxSteps' + 1 => do diff --git a/Mathlib/Tactic/CongrExclamation.lean b/Mathlib/Tactic/CongrExclamation.lean index 07e5e0acd858cc..dbad9c4977c1c8 100644 --- a/Mathlib/Tactic/CongrExclamation.lean +++ b/Mathlib/Tactic/CongrExclamation.lean @@ -10,7 +10,7 @@ public meta import Lean.Elab.Tactic.RCases public meta import Lean.Meta.Tactic.Assumption public meta import Lean.Meta.Tactic.Rfl public meta import Mathlib.Lean.Meta.CongrTheorems -public meta import Mathlib.Logic.Basic +public import Mathlib.Logic.Basic public import Mathlib.Lean.Meta.CongrTheorems /-! diff --git a/Mathlib/Tactic/IntervalCases.lean b/Mathlib/Tactic/IntervalCases.lean index 2ac7324c92f3fa..322522024cf1b9 100644 --- a/Mathlib/Tactic/IntervalCases.lean +++ b/Mathlib/Tactic/IntervalCases.lean @@ -5,7 +5,6 @@ Authors: Kim Morrison, Mario Carneiro -/ module -public meta import Mathlib.Control.Basic public import Mathlib.Data.Finset.Attr public import Mathlib.Tactic.NormNum diff --git a/Mathlib/Tactic/ModCases.lean b/Mathlib/Tactic/ModCases.lean index d57edea9e6a4d2..ce38de6ac045da 100644 --- a/Mathlib/Tactic/ModCases.lean +++ b/Mathlib/Tactic/ModCases.lean @@ -5,7 +5,6 @@ Authors: Mario Carneiro, Heather Macbeth -/ module -public meta import Mathlib.Data.Int.ModEq public import Mathlib.Data.Int.ModEq public import Mathlib.Tactic.HaveI @@ -15,7 +14,7 @@ The `mod_cases` tactic does case disjunction on `e % n`, where `e : ℤ` or `e : to yield `n` new subgoals corresponding to the possible values of `e` modulo `n`. -/ -public meta section +public section namespace Mathlib.Tactic.ModCases open Lean Meta Elab Tactic Term Qq @@ -66,7 +65,7 @@ and the `a ≡ b (mod n) → p` case becomes a subgoal. Proves an expression of the form `OnModCases n a b p` where `n` and `b` are raw nat literals and `b ≤ n`. Returns the list of subgoals `?gi : a ≡ i [ZMOD n] → p`. -/ -partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℤ)) (b : Q(ℕ)) (p : Q(Sort u)) : +meta partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℤ)) (b : Q(ℕ)) (p : Q(Sort u)) : MetaM (Q(OnModCases $n $a $b $p) × List MVarId) := do if n.natLit! ≤ b.natLit! then haveI' : $b =Q $n := ⟨⟩ @@ -82,7 +81,7 @@ partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℤ)) (b : Q(ℕ)) ( /-- Int case of `mod_cases h : e % n`. -/ -def modCases (h : TSyntax `Lean.binderIdent) (e : Q(ℤ)) (n : ℕ) : TacticM Unit := do +meta def modCases (h : TSyntax `Lean.binderIdent) (e : Q(ℤ)) (n : ℕ) : TacticM Unit := do let ⟨u, p, g⟩ ← inferTypeQ (.mvar (← getMainGoal)) have lit : Q(ℕ) := mkRawNatLit n have p₁ : Nat.ble 1 $lit =Q true := ⟨⟩ @@ -142,7 +141,7 @@ and the `a ≡ b (mod n) → p` case becomes a subgoal. Proves an expression of the form `OnModCases n a b p` where `n` and `b` are raw nat literals and `b ≤ n`. Returns the list of subgoals `?gi : a ≡ i [MOD n] → p`. -/ -partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℕ)) (b : Q(ℕ)) (p : Q(Sort u)) : +meta partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℕ)) (b : Q(ℕ)) (p : Q(Sort u)) : MetaM (Q(OnModCases $n $a $b $p) × List MVarId) := do if n.natLit! ≤ b.natLit! then have : $b =Q $n := ⟨⟩ @@ -157,7 +156,7 @@ partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℕ)) (b : Q(ℕ)) ( /-- Nat case of `mod_cases h : e % n`. -/ -def modCases (h : TSyntax `Lean.binderIdent) (e : Q(ℕ)) (n : ℕ) : TacticM Unit := do +meta def modCases (h : TSyntax `Lean.binderIdent) (e : Q(ℕ)) (n : ℕ) : TacticM Unit := do let ⟨u, p, g⟩ ← inferTypeQ (.mvar (← getMainGoal)) have lit : Q(ℕ) := mkRawNatLit n let p₁ : Q(Nat.ble 1 $lit = true) := (q(Eq.refl true) : Expr) diff --git a/Mathlib/Tactic/NormNum/LegendreSymbol.lean b/Mathlib/Tactic/NormNum/LegendreSymbol.lean index 21642667152ab3..25a5be8211c825 100644 --- a/Mathlib/Tactic/NormNum/LegendreSymbol.lean +++ b/Mathlib/Tactic/NormNum/LegendreSymbol.lean @@ -5,7 +5,6 @@ Authors: Michael Stoll -/ module -public meta import Mathlib.NumberTheory.LegendreSymbol.JacobiSymbol public import Mathlib.NumberTheory.LegendreSymbol.JacobiSymbol /-! @@ -47,7 +46,7 @@ where we encode the residue classes mod 2, mod 4, or mod 8 by using hypotheses l are the ones occurring in the use of QR above. -/ -public meta section +public section section Lemmas @@ -193,6 +192,8 @@ end Mathlib.Meta.NormNum end Lemmas +meta section + section Evaluation /-! @@ -208,7 +209,7 @@ namespace Mathlib.Meta.NormNum open Lean Elab Tactic Qq -- TODO: redefined here for reduction; should this be special-handled in quote4? -private meta def mkRawIntLit' (n : ℤ) : Q(ℤ) := +private def mkRawIntLit' (n : ℤ) : Q(ℤ) := let lit : Q(ℕ) := .lit <| .natVal n.natAbs if 0 ≤ n then q(.ofNat $lit) else q(.negOfNat $lit) diff --git a/Mathlib/Tactic/Positivity/Basic.lean b/Mathlib/Tactic/Positivity/Basic.lean index f9498cc1a2c586..8edffeca629e60 100644 --- a/Mathlib/Tactic/Positivity/Basic.lean +++ b/Mathlib/Tactic/Positivity/Basic.lean @@ -11,7 +11,6 @@ public import Mathlib.Data.Nat.Factorial.Basic -- shake: keep (Qq dependency) public import Mathlib.Data.Int.CharZero -- shake: keep (Qq dependency) public import Mathlib.Data.PNat.Defs -- shake: keep (Qq dependency) public import Mathlib.Algebra.Order.Ring.Basic -- shake: keep (Qq dependency) -public meta import Mathlib.Algebra.Notation.Defs public import Mathlib.Algebra.Order.Hom.Basic public import Mathlib.Data.NNRat.Defs public import Mathlib.Tactic.Positivity.Core diff --git a/Mathlib/Tactic/Ring/Basic.lean b/Mathlib/Tactic/Ring/Basic.lean index 2cb699521c625b..6875ffafe604ec 100644 --- a/Mathlib/Tactic/Ring/Basic.lean +++ b/Mathlib/Tactic/Ring/Basic.lean @@ -5,10 +5,8 @@ Authors: Mario Carneiro, Aurélien Saue, Anne Baanen -/ module -public import Mathlib.Tactic.NormNum.Inv -public import Mathlib.Tactic.NormNum.Pow public import Mathlib.Tactic.Ring.Common -meta import Mathlib.Tactic.Ring.Common +public meta import Mathlib.Algebra.Order.Ring.Unbundled.Rat -- for the `Ord Rat` instance /-! # `ring` tactic diff --git a/Mathlib/Tactic/Ring/Common.lean b/Mathlib/Tactic/Ring/Common.lean index b883ee79abcf09..bba23ff5496407 100644 --- a/Mathlib/Tactic/Ring/Common.lean +++ b/Mathlib/Tactic/Ring/Common.lean @@ -7,9 +7,6 @@ module public import Mathlib.Tactic.NormNum.Inv public import Mathlib.Tactic.NormNum.Pow -public meta import Mathlib.Tactic.NormNum.Result - -meta import Mathlib.Algebra.Order.Ring.Unbundled.Rat /-! # `ring`-like tactics diff --git a/Mathlib/Tactic/Sat/FromLRAT.lean b/Mathlib/Tactic/Sat/FromLRAT.lean index 3dfdd07a2f8184..919fa47cf47e13 100644 --- a/Mathlib/Tactic/Sat/FromLRAT.lean +++ b/Mathlib/Tactic/Sat/FromLRAT.lean @@ -6,7 +6,6 @@ Authors: Mario Carneiro module public import Mathlib.Algebra.Group.Nat.Defs -public meta import Mathlib.Algebra.Notation.Defs public import Mathlib.Tactic.Push /-! diff --git a/Mathlib/Tactic/Simproc/Divisors.lean b/Mathlib/Tactic/Simproc/Divisors.lean index f534203d18aea2..5259b06d9c77a9 100644 --- a/Mathlib/Tactic/Simproc/Divisors.lean +++ b/Mathlib/Tactic/Simproc/Divisors.lean @@ -5,7 +5,7 @@ Authors: Paul Lezeau, Bhavik Mehta -/ module -public meta import Mathlib.NumberTheory.Divisors -- TODO: check if `meta` is still needed after https://github.com/leanprover/lean4/pull/13043 +public meta import Mathlib.NumberTheory.Divisors public meta import Mathlib.Tactic.ToAdditive public meta import Mathlib.Util.Qq diff --git a/Mathlib/Tactic/Simproc/Factors.lean b/Mathlib/Tactic/Simproc/Factors.lean index 600e85a32d9cd8..c0a6e985dacc2c 100644 --- a/Mathlib/Tactic/Simproc/Factors.lean +++ b/Mathlib/Tactic/Simproc/Factors.lean @@ -6,7 +6,6 @@ Authors: Mario Carneiro, Eric Wieser module import all Mathlib.Tactic.NormNum.Prime -- for accessing `evalMinFac.core` -public meta import Mathlib.Algebra.BigOperators.Group.List.Defs public import Mathlib.Data.Nat.Factors public import Mathlib.Tactic.NormNum.Prime From 699ca544fb64ebd90bba96837f79f88080fdea55 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:58:40 +0000 Subject: [PATCH 0081/1300] feat: big operator lemmas for congruence quotients (#40564) This adds `coe` lemmas for `Con`, `AddCon`, and `RingCon`, for all the big operators for which we already had the relation lemmas. --- .../GroupTheory/Congruence/BigOperators.lean | 44 +++++++++++- .../RingTheory/Congruence/BigOperators.lean | 71 +++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/Mathlib/GroupTheory/Congruence/BigOperators.lean b/Mathlib/GroupTheory/Congruence/BigOperators.lean index 994b3f3536c1fa..25e62abbf084bd 100644 --- a/Mathlib/GroupTheory/Congruence/BigOperators.lean +++ b/Mathlib/GroupTheory/Congruence/BigOperators.lean @@ -10,9 +10,7 @@ public import Mathlib.Algebra.BigOperators.Group.List.Lemmas public import Mathlib.Algebra.BigOperators.Group.Finset.Defs public import Mathlib.Algebra.BigOperators.Finsupp.Basic public import Mathlib.Data.DFinsupp.BigOperators -public import Mathlib.GroupTheory.Congruence.Defs - -import Mathlib.GroupTheory.Congruence.Basic +public import Mathlib.GroupTheory.Congruence.Basic /-! # Interactions between `∑, ∏` and `(Add)Con` @@ -35,6 +33,12 @@ protected theorem list_prod {ι M : Type*} [MulOneClass M] (c : Con M) {l : List rw [List.map_cons, List.map_cons, List.prod_cons, List.prod_cons] exact c.mul (h _ <| .head _) <| ih fun k hk ↦ h _ (.tail _ hk) +@[to_additive (attr := simp, norm_cast)] +protected theorem coe_listProd {ι M : Type*} [MulOneClass M] (c : Con M) + (l : List ι) (f : ι → M) : + (↑(l.map f).prod : c.Quotient) = (l.map fun i => (f i : c.Quotient)).prod := by + induction l with simp [*] + /-- Multiplicative congruence relations preserve product indexed by a multiset. -/ @[to_additive /-- Additive congruence relations preserve sum indexed by a multiset. -/] protected theorem multiset_prod {ι M : Type*} [CommMonoid M] (c : Con M) {s : Multiset ι} @@ -42,6 +46,12 @@ protected theorem multiset_prod {ι M : Type*} [CommMonoid M] (c : Con M) {s : M c (s.map f).prod (s.map g).prod := by rcases s; simpa using c.list_prod h +@[to_additive (attr := simp, norm_cast)] +protected theorem coe_multisetProd {ι M : Type*} [CommMonoid M] (c : Con M) + (s : Multiset ι) (f : ι → M) : + (↑(s.map f).prod : c.Quotient) = (s.map fun i => (f i : c.Quotient)).prod := by + simpa using map_multiset_prod c.mk' (s.map f) + /-- Multiplicative congruence relations preserve finite product. -/ @[to_additive /-- Additive congruence relations preserve finite sum. -/] protected theorem finsetProd {ι M : Type*} [CommMonoid M] (c : Con M) (s : Finset ι) @@ -49,6 +59,12 @@ protected theorem finsetProd {ι M : Type*} [CommMonoid M] (c : Con M) (s : Fins c (s.prod f) (s.prod g) := c.multiset_prod h +@[to_additive (attr := simp, norm_cast)] +protected theorem coe_finsetProd {ι M : Type*} [CommMonoid M] (c : Con M) (s : Finset ι) + (f : ι → M) : + (↑(s.prod f) : c.Quotient) = s.prod fun i => (f i : c.Quotient) := + map_prod c.mk' f s + @[to_additive] protected theorem finsuppProd {ι : Type*} {β : Type*} {M : Type*} [CommMonoid M] [Zero β] @@ -63,6 +79,12 @@ protected theorem finsuppProd {ι : Type*} {β : Type*} {M : Type*} (fun _ _ => Quotient.sound <| H _) (fun _ _ => Quotient.sound <| hf _) (fun _ _ => Quotient.sound <| hf' _) +@[to_additive (attr := simp, norm_cast)] +protected theorem coe_finsuppProd {ι : Type*} {β : Type*} {M : Type*} + [CommMonoid M] [Zero β] (c : Con M) (h : ι → β → M) (f : ι →₀ β) : + (↑(f.prod h) : c.Quotient) = f.prod fun i b => (h i b : c.Quotient) := + map_finsuppProd c.mk' f h + @[to_additive] protected theorem dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} [DecidableEq ι] [CommMonoid M] [∀ i, Zero (β i)] [∀ i (y : β i), Decidable (y ≠ 0)] @@ -77,6 +99,13 @@ protected theorem dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} (fun _ _ => Quotient.sound <| H _) (fun _ _ => Quotient.sound <| hf _) (fun _ _ => Quotient.sound <| hf' _) +@[to_additive (attr := simp, norm_cast)] +protected theorem coe_dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} + [DecidableEq ι] [CommMonoid M] [∀ i, Zero (β i)] [∀ i (y : β i), Decidable (y ≠ 0)] + (c : Con M) (h : (i : ι) → β i → M) (f : Π₀ i, β i) : + (↑(f.prod h) : c.Quotient) = f.prod fun i b => (h i b : c.Quotient) := + map_dfinsuppProd c.mk' f h + protected theorem _root_.AddCon.dfinsuppSumAddHom {ι : Type*} {β : ι → Type*} {M : Type*} [DecidableEq ι] [AddCommMonoid M] [∀ i, AddCommMonoid (β i)] (c : AddCon M) (h : (i : ι) → β i →+ M) (h' : (i : ι) → β i →+ M) {f g : Π₀ i, β i} @@ -87,6 +116,15 @@ protected theorem _root_.AddCon.dfinsuppSumAddHom {ι : Type*} {β : ι → Type exact c.dfinsuppSum _ _ (bot_le (a := c) <| map_zero <| h ·) (bot_le (a := c) <| map_zero <| h' ·) H +@[simp, norm_cast] +protected theorem _root_.AddCon.coe_dfinsuppSumAddHom {ι : Type*} {β : ι → Type*} {M : Type*} + [DecidableEq ι] [AddCommMonoid M] [∀ i, AddCommMonoid (β i)] + (c : AddCon M) (h : (i : ι) → β i →+ M) (f : Π₀ i, β i) : + (↑(f.sumAddHom h) : c.Quotient) = f.sumAddHom fun i => (AddCon.mk' c).comp (h i) := by + classical + simp_rw [← AddCon.coe_mk', DFinsupp.sumAddHom_apply, map_dfinsuppSum] + rfl + @[deprecated (since := "2026-04-08")] protected alias _root_.AddCon.finset_sum := AddCon.finsetSum diff --git a/Mathlib/RingTheory/Congruence/BigOperators.lean b/Mathlib/RingTheory/Congruence/BigOperators.lean index d883c7a8dd68a5..9d89edccf68e41 100644 --- a/Mathlib/RingTheory/Congruence/BigOperators.lean +++ b/Mathlib/RingTheory/Congruence/BigOperators.lean @@ -11,6 +11,8 @@ public import Mathlib.RingTheory.Congruence.Defs /-! # Interactions between `∑, ∏` and `RingCon` +TODO: some of the typeclass assumptions in this file can be weakened if more instances are added +for `RingCon.Quotient`. -/ public section @@ -23,36 +25,72 @@ protected lemma listProd {ι S : Type*} [Add S] [Monoid S] t (l.map f).prod (l.map g).prod := t.toCon.list_prod h +@[simp, norm_cast] +protected lemma coe_listProd {ι S : Type*} [Add S] [Monoid S] (t : RingCon S) + (l : List ι) (f : ι → S) : + (↑(l.map f).prod : t.Quotient) = (l.map fun i => (f i : t.Quotient)).prod := + t.toCon.coe_listProd l f + /-- Congruence relation of a ring preserves finite sum indexed by a list. -/ protected lemma listSum {ι S : Type*} [AddMonoid S] [Mul S] (t : RingCon S) (l : List ι) {f g : ι → S} (h : ∀ i ∈ l, t (f i) (g i)) : t (l.map f).sum (l.map g).sum := t.toAddCon.list_sum h +@[simp, norm_cast] +protected lemma coe_listSum {ι S : Type*} [AddMonoid S] [Mul S] (t : RingCon S) + (l : List ι) (f : ι → S) : + (↑(l.map f).sum : t.Quotient) = (l.map fun i => (f i : t.Quotient)).sum := + t.toAddCon.coe_listSum l f + /-- Congruence relation of a ring preserves finite product indexed by a multiset. -/ protected lemma multisetProd {ι S : Type*} [Add S] [CommMonoid S] (t : RingCon S) (s : Multiset ι) {f g : ι → S} (h : ∀ i ∈ s, t (f i) (g i)) : t (s.map f).prod (s.map g).prod := t.toCon.multiset_prod h +@[simp, norm_cast] +protected lemma coe_multisetProd {ι S : Type*} [Add S] [CommMonoid S] (t : RingCon S) + (s : Multiset ι) (f : ι → S) : + (↑(s.map f).prod : t.Quotient) = (s.map fun i => (f i : t.Quotient)).prod := + t.toCon.coe_multisetProd s f + /-- Congruence relation of a ring preserves finite sum indexed by a multiset. -/ protected lemma multisetSum {ι S : Type*} [AddCommMonoid S] [Mul S] (t : RingCon S) (s : Multiset ι) {f g : ι → S} (h : ∀ i ∈ s, t (f i) (g i)) : t (s.map f).sum (s.map g).sum := t.toAddCon.multiset_sum h +@[simp, norm_cast] +protected lemma coe_multisetSum {ι S : Type*} [AddCommMonoid S] [Mul S] (t : RingCon S) + (s : Multiset ι) (f : ι → S) : + (↑(s.map f).sum : t.Quotient) = (s.map fun i => (f i : t.Quotient)).sum := + t.toAddCon.coe_multisetSum s f + /-- Congruence relation of a ring preserves finite product. -/ protected lemma finsetProd {ι S : Type*} [Add S] [CommMonoid S] (t : RingCon S) (s : Finset ι) {f g : ι → S} (h : ∀ i ∈ s, t (f i) (g i)) : t (s.prod f) (s.prod g) := t.toCon.finsetProd s h +@[simp, norm_cast] +protected lemma coe_finsetProd {ι S : Type*} [Add S] [CommMonoid S] (t : RingCon S) (s : Finset ι) + (f : ι → S) : + (↑(s.prod f) : t.Quotient) = s.prod fun i => (f i : t.Quotient) := + t.toCon.coe_finsetProd s f + /-- Congruence relation of a ring preserves finite sum. -/ protected lemma finsetSum {ι S : Type*} [AddCommMonoid S] [Mul S] (t : RingCon S) (s : Finset ι) {f g : ι → S} (h : ∀ i ∈ s, t (f i) (g i)) : t (s.sum f) (s.sum g) := t.toAddCon.finsetSum s h +@[simp, norm_cast] +protected lemma coe_finsetSum {ι S : Type*} [AddCommMonoid S] [Mul S] (t : RingCon S) (s : Finset ι) + (f : ι → S) : + (↑(s.sum f) : t.Quotient) = s.sum fun i => (f i : t.Quotient) := + t.toAddCon.coe_finsetSum s f + protected lemma finsuppProd {ι : Type*} {β : Type*} {M : Type*} [Add M] [CommMonoid M] [Zero β] (c : RingCon M) (h : ι → β → M) (h' : ι → β → M) @@ -61,6 +99,12 @@ protected lemma finsuppProd {ι : Type*} {β : Type*} {M : Type*} c (f.prod h) (g.prod h') := c.toCon.finsuppProd h h' hf hf' H +@[simp, norm_cast] +protected lemma coe_finsuppProd {ι : Type*} {β : Type*} {M : Type*} + [Add M] [CommMonoid M] [Zero β] (c : RingCon M) (h : ι → β → M) (f : ι →₀ β) : + (↑(f.prod h) : c.Quotient) = f.prod fun i b => (h i b : c.Quotient) := + c.toCon.coe_finsuppProd h f + protected lemma finsuppSum {ι : Type*} {β : Type*} {M : Type*} [AddCommMonoid M] [Mul M] [Zero β] (c : RingCon M) (h : ι → β → M) (h' : ι → β → M) @@ -69,6 +113,12 @@ protected lemma finsuppSum {ι : Type*} {β : Type*} {M : Type*} c (f.sum h) (g.sum h') := c.toAddCon.finsuppSum h h' hf hf' H +@[simp, norm_cast] +protected lemma coe_finsuppSum {ι : Type*} {β : Type*} {M : Type*} + [AddCommMonoid M] [Mul M] [Zero β] (c : RingCon M) (h : ι → β → M) (f : ι →₀ β) : + (↑(f.sum h) : c.Quotient) = f.sum fun i b => (h i b : c.Quotient) := + c.toAddCon.coe_finsuppSum h f + protected lemma dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} [DecidableEq ι] [Add M] [CommMonoid M] [∀ i, Zero (β i)] [∀ i (y : β i), Decidable (y ≠ 0)] (c : RingCon M) (h : (i : ι) → β i → M) (h' : (i : ι) → β i → M) @@ -77,6 +127,13 @@ protected lemma dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} c (f.prod h) (g.prod h') := c.toCon.dfinsuppProd h h' hf hf' H +@[simp, norm_cast] +protected lemma coe_dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} + [DecidableEq ι] [Add M] [CommMonoid M] [∀ i, Zero (β i)] [∀ i (y : β i), Decidable (y ≠ 0)] + (c : RingCon M) (h : (i : ι) → β i → M) (f : Π₀ i, β i) : + (↑(f.prod h) : c.Quotient) = f.prod fun i b => (h i b : c.Quotient) := + c.toCon.coe_dfinsuppProd h f + protected lemma dfinsuppSum {ι : Type*} {β : ι → Type*} {M : Type*} [DecidableEq ι] [AddCommMonoid M] [Mul M] [∀ i, Zero (β i)] [∀ i (y : β i), Decidable (y ≠ 0)] (c : RingCon M) (h : (i : ι) → β i → M) (h' : (i : ι) → β i → M) @@ -85,6 +142,13 @@ protected lemma dfinsuppSum {ι : Type*} {β : ι → Type*} {M : Type*} c (f.sum h) (g.sum h') := c.toAddCon.dfinsuppSum h h' hf hf' H +@[simp, norm_cast] +protected lemma coe_dfinsuppSum {ι : Type*} {β : ι → Type*} {M : Type*} + [DecidableEq ι] [AddCommMonoid M] [Mul M] [∀ i, Zero (β i)] [∀ i (y : β i), Decidable (y ≠ 0)] + (c : RingCon M) (h : (i : ι) → β i → M) (f : Π₀ i, β i) : + (↑(f.sum h) : c.Quotient) = f.sum fun i b => (h i b : c.Quotient) := + c.toAddCon.coe_dfinsuppSum h f + protected lemma dfinsuppSumAddHom {ι : Type*} {β : ι → Type*} {M : Type*} [DecidableEq ι] [AddCommMonoid M] [Mul M] [∀ i, AddCommMonoid (β i)] (c : RingCon M) (h : (i : ι) → β i →+ M) (h' : (i : ι) → β i →+ M) {f g : Π₀ i, β i} @@ -92,4 +156,11 @@ protected lemma dfinsuppSumAddHom {ι : Type*} {β : ι → Type*} {M : Type*} c (f.sumAddHom h) (g.sumAddHom h') := c.toAddCon.dfinsuppSumAddHom h h' H +@[simp, norm_cast] +protected lemma coe_dfinsuppSumAddHom {ι : Type*} {β : ι → Type*} {M : Type*} + [DecidableEq ι] [AddCommMonoid M] [Mul M] [∀ i, AddCommMonoid (β i)] + (c : RingCon M) (h : (i : ι) → β i →+ M) (f : Π₀ i, β i) : + (↑(f.sumAddHom h) : c.Quotient) = f.sumAddHom fun i => c.toAddCon.mk'.comp (h i) := + c.toAddCon.coe_dfinsuppSumAddHom h f + end RingCon From b90fc6c341f128f1c27ab34cb06bbeb243cdd1dd Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 16 Jun 2026 23:11:54 +0000 Subject: [PATCH 0082/1300] refactor(Analysis): golf `Mathlib/Analysis/Complex/Isometry` (#40070) - simplifies `LinearIsometry.im_apply_eq_im` by deriving real-part equality from the squared distance identity Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Analysis/Complex/Isometry.lean | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Mathlib/Analysis/Complex/Isometry.lean b/Mathlib/Analysis/Complex/Isometry.lean index 9be1f7b76ccabc..8deafc5101dd26 100644 --- a/Mathlib/Analysis/Complex/Isometry.lean +++ b/Mathlib/Analysis/Complex/Isometry.lean @@ -101,17 +101,9 @@ theorem LinearIsometry.im_apply_eq_im_or_neg_of_re_apply_eq_re {f : ℂ →ₗ theorem LinearIsometry.im_apply_eq_im {f : ℂ →ₗᵢ[ℝ] ℂ} (h : f 1 = 1) (z : ℂ) : z + conj z = f z + conj (f z) := by - have : ‖f z - 1‖ = ‖z - 1‖ := by rw [← f.norm_map (z - 1), f.map_sub, h] - apply_fun fun x => x ^ 2 at this - simp only [← normSq_eq_norm_sq] at this - rw [← ofReal_inj, ← mul_conj, ← mul_conj] at this - rw [map_sub, map_sub] at this - simp only [sub_mul, mul_sub, one_mul] at this - rw [mul_conj, normSq_eq_norm_sq, LinearIsometry.norm_map] at this - rw [mul_conj, normSq_eq_norm_sq] at this - simp only [sub_sub, sub_right_inj, mul_one, ofReal_pow, map_one] at this - simp only [add_sub, sub_left_inj] at this - rw [add_comm, ← this, add_comm] + have hsq : ‖f z - 1‖ ^ 2 = ‖z - 1‖ ^ 2 := by simpa [h] using f.norm_map (z - 1) + simp_rw [← normSq_eq_norm_sq, Complex.normSq_sub] at hsq + simpa [normSq_eq_norm_sq, Complex.add_conj, LinearIsometry.norm_map] using hsq.symm theorem LinearIsometry.re_apply_eq_re {f : ℂ →ₗᵢ[ℝ] ℂ} (h : f 1 = 1) (z : ℂ) : (f z).re = z.re := by apply LinearIsometry.re_apply_eq_re_of_add_conj_eq From 939a3b823e06d0fbd1cb47e9cd2618120357093d Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 16 Jun 2026 23:11:56 +0000 Subject: [PATCH 0083/1300] feat(Analysis/MeanInequalities): equality condition for Young's inequality (#40485) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `a * b = a ^ p / p + b ^ q / q ↔ a ^ p = b ^ q` with `Real`/`NNReal`/`ENNReal` versions that match the existing `≤` theorems. --- Mathlib/Analysis/MeanInequalities.lean | 38 +++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/MeanInequalities.lean b/Mathlib/Analysis/MeanInequalities.lean index c1131e6d0685eb..ac11e444efd9db 100644 --- a/Mathlib/Analysis/MeanInequalities.lean +++ b/Mathlib/Analysis/MeanInequalities.lean @@ -499,7 +499,7 @@ namespace Real /-- **Young's inequality**, a version for nonnegative real numbers. -/ theorem young_inequality_of_nonneg {a b p q : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hpq : p.HolderConjugate q) : a * b ≤ a ^ p / p + b ^ q / q := by - simpa [← rpow_mul, ha, hb, hpq.ne_zero, hpq.symm.ne_zero, _root_.div_eq_inv_mul] using + simpa [← rpow_mul, ha, hb, hpq.ne_zero, hpq.symm.ne_zero, div_eq_inv_mul] using geom_mean_le_arith_mean2_weighted hpq.inv_nonneg hpq.symm.inv_nonneg (rpow_nonneg ha p) (rpow_nonneg hb q) hpq.inv_add_inv_eq_one @@ -512,6 +512,13 @@ theorem young_inequality (a b : ℝ) {p q : ℝ} (hpq : p.HolderConjugate q) : _ ≤ |a| ^ p / p + |b| ^ q / q := Real.young_inequality_of_nonneg (abs_nonneg a) (abs_nonneg b) hpq +/-- **Young's inequality** equality condition for nonnegative real numbers. -/ +theorem young_inequality_eq_iff_of_nonneg {a b p q : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) + (hpq : p.HolderConjugate q) : a * b = a ^ p / p + b ^ q / q ↔ a ^ p = b ^ q := by + simpa [← rpow_mul, ha, hb, hpq.ne_zero, hpq.symm.ne_zero, div_eq_inv_mul] using + geom_mean_eq_arith_mean2_weighted_iff_of_nonneg hpq.inv_nonneg hpq.symm.inv_nonneg + (rpow_nonneg ha p) (rpow_nonneg hb q) hpq.inv_add_inv_eq_one + end Real namespace NNReal @@ -524,8 +531,18 @@ theorem young_inequality (a b : ℝ≥0) {p q : ℝ≥0} (hpq : p.HolderConjugat /-- **Young's inequality**, `ℝ≥0` version with real conjugate exponents. -/ theorem young_inequality_real (a b : ℝ≥0) {p q : ℝ} (hpq : p.HolderConjugate q) : - a * b ≤ a ^ p / Real.toNNReal p + b ^ q / Real.toNNReal q := by - simpa [Real.coe_toNNReal, hpq.nonneg, hpq.symm.nonneg] using young_inequality a b hpq.toNNReal + a * b ≤ a ^ p / p.toNNReal + b ^ q / q.toNNReal := by + simpa [hpq.nonneg, hpq.symm.nonneg] using young_inequality a b hpq.toNNReal + +/-- **Young's inequality** equality condition, `ℝ≥0` version. -/ +theorem young_inequality_eq_iff (a b : ℝ≥0) {p q : ℝ≥0} (hpq : p.HolderConjugate q) : + a * b = a ^ (p : ℝ) / p + b ^ (q : ℝ) / q ↔ a ^ (p : ℝ) = b ^ (q : ℝ) := + mod_cast Real.young_inequality_eq_iff_of_nonneg a.coe_nonneg b.coe_nonneg hpq.coe + +/-- **Young's inequality** equality condition, `ℝ≥0` version with real conjugate exponents. -/ +theorem young_inequality_real_eq_iff (a b : ℝ≥0) {p q : ℝ} (hpq : p.HolderConjugate q) : + a * b = a ^ p / p.toNNReal + b ^ q / q.toNNReal ↔ a ^ p = b ^ q := by + simpa [hpq.nonneg, hpq.symm.nonneg] using young_inequality_eq_iff a b hpq.toNNReal end NNReal @@ -538,13 +555,26 @@ theorem young_inequality (a b : ℝ≥0∞) {p q : ℝ} (hpq : p.HolderConjugate · refine le_trans le_top (le_of_eq ?_) repeat rw [div_eq_mul_inv] rcases h with h | h <;> rw [h] <;> simp [hpq.pos, hpq.symm.pos] - -- if a ≠ ⊤ and b ≠ ⊤, use the nnreal version: nnreal.young_inequality_real + -- if `a ≠ ⊤` and `b ≠ ⊤`, use the `NNReal` version: `NNReal.young_inequality_real` rw [← coe_toNNReal h.left, ← coe_toNNReal h.right, ← coe_mul, ← coe_rpow_of_nonneg _ hpq.nonneg, ← coe_rpow_of_nonneg _ hpq.symm.nonneg, ENNReal.ofReal, ENNReal.ofReal, ← @coe_div (Real.toNNReal p) _ (by simp [hpq.pos]), ← @coe_div (Real.toNNReal q) _ (by simp [hpq.symm.pos]), ← coe_add, coe_le_coe] exact NNReal.young_inequality_real a.toNNReal b.toNNReal hpq +/-- **Young's inequality** equality condition, `ℝ≥0∞` version with real conjugate exponents. -/ +theorem young_inequality_eq_iff (a b : ℝ≥0∞) {p q : ℝ} (hpq : p.HolderConjugate q) : + a * b = a ^ p / .ofReal p + b ^ q / .ofReal q ↔ + (a = ⊤ ∧ b ≠ 0) ∨ (a ≠ 0 ∧ b = ⊤) ∨ a ^ p = b ^ q := by + by_cases! h0 : a = 0 ∨ b = 0 + · rcases h0 with rfl | rfl <;> simp [hpq.pos, hpq.symm.pos, eq_comm] + by_cases! h : a = ⊤ ∨ b = ⊤ + · rcases h with rfl | rfl <;> simp [hpq.pos, hpq.symm.pos, h0, div_eq_mul_inv] + rw [← coe_toNNReal h.left, ← coe_toNNReal h.right, ← coe_mul, ← coe_rpow_of_nonneg _ hpq.nonneg, + ← coe_rpow_of_nonneg _ hpq.symm.nonneg, ← ofNNReal_toNNReal, ← ofNNReal_toNNReal, + ← coe_div (by simp [hpq.pos]), ← coe_div (by simp [hpq.symm.pos]), ← coe_add, coe_inj, coe_inj] + simp [young_inequality_real_eq_iff a.toNNReal b.toNNReal hpq] + end ENNReal end Young From 9c1fa80c5dc73a897bdd30caa2ab99c8d3298362 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Tue, 16 Jun 2026 23:11:58 +0000 Subject: [PATCH 0084/1300] feat: some API for relating self-adjoint and skew-adjoints (#40684) --- Mathlib/Analysis/RCLike/Basic.lean | 15 +++++++ Mathlib/LinearAlgebra/Complex/Module.lean | 51 ++++++++++------------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 77997bae54b4e6..1970d7eb45f5ad 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -763,8 +763,23 @@ theorem isCauSeq_norm {f : ℕ → K} (hf : IsCauSeq norm f) : IsCauSeq abs (nor let ⟨i, hi⟩ := hf ε ε0 ⟨i, fun j hj => lt_of_le_of_lt (abs_norm_sub_norm_le _ _) (hi j hj)⟩ +lemma I_mem_skewAdjoint : I ∈ skewAdjoint K := by simp [skewAdjoint.mem_iff] + end RCLike +section +variable {A : Type*} [AddCommGroup A] [StarAddMonoid A] [Module K A] [StarModule K A] {a : A} + +open RCLike + +lemma IsSelfAdjoint.I_smul_mem_skewAdjoint (h : IsSelfAdjoint a) : + (I : K) • a ∈ skewAdjoint A := h.smul_mem_skewAdjoint I_mem_skewAdjoint + +lemma IsSelfAdjoint.I_smul_of_mem_skewAdjoint (h : a ∈ skewAdjoint A) : + IsSelfAdjoint ((I : K) • a) := isSelfAdjoint_smul_of_mem_skewAdjoint I_mem_skewAdjoint h + +end + section Instances noncomputable instance Real.instRCLike : RCLike ℝ where diff --git a/Mathlib/LinearAlgebra/Complex/Module.lean b/Mathlib/LinearAlgebra/Complex/Module.lean index 7db6282b5b709a..6b9d1cdd32c577 100644 --- a/Mathlib/LinearAlgebra/Complex/Module.lean +++ b/Mathlib/LinearAlgebra/Complex/Module.lean @@ -362,26 +362,26 @@ section AddCommGroup variable [AddCommGroup A] [Module ℂ A] [StarAddMonoid A] [StarModule ℂ A] +lemma Complex.I_mem_skewAdjoint : I ∈ skewAdjoint ℂ := by simp [skewAdjoint.mem_iff] + +@[simp] lemma Complex.I_smul_mem_skewAdjoint_iff_isSelfAdjoint {a : A} : + I • a ∈ skewAdjoint A ↔ IsSelfAdjoint a := by + simp [skewAdjoint.mem_iff, IsSelfAdjoint, smul_right_inj] + +@[simp] lemma Complex.isSelfAdjoint_I_smul_iff_mem_skewAdjoint {a : A} : + IsSelfAdjoint (I • a) ↔ a ∈ skewAdjoint A := by + simp [← I_smul_mem_skewAdjoint_iff_isSelfAdjoint, smul_smul] + /-- Create a `selfAdjoint` element from a `skewAdjoint` element by multiplying by the scalar `-Complex.I`. -/ @[simps] def skewAdjoint.negISMul : skewAdjoint A →ₗ[ℝ] selfAdjoint A where - toFun a := - ⟨-I • ↑a, by - simp only [neg_smul, neg_mem_iff, selfAdjoint.mem_iff, star_smul, star_def, conj_I, - star_val_eq, smul_neg, neg_neg]⟩ - map_add' a b := by - ext - simp only [AddSubgroup.coe_add, smul_add, AddMemClass.mk_add_mk] - map_smul' a b := by - ext - simp only [neg_smul, skewAdjoint.val_smul, RingHom.id_apply, - selfAdjoint.val_smul, smul_neg, neg_inj] - rw [smul_comm] + toFun a := ⟨-I • ↑a, by simp [selfAdjoint.mem_iff]⟩ + map_add' a b := by simp + map_smul' a b := by ext; simp [smul_comm I] theorem skewAdjoint.I_smul_neg_I (a : skewAdjoint A) : I • (skewAdjoint.negISMul a : A) = a := by - simp only [smul_smul, skewAdjoint.negISMul_apply_coe, neg_smul, smul_neg, I_mul_I, one_smul, - neg_neg] + simp [smul_smul] /-- The real part `ℜ a` of an element `a` of a star module over `ℂ`, as a linear map. This is just `selfAdjointPart ℝ`, but we provide it as a separate definition in order to link it with lemmas @@ -405,20 +405,15 @@ scoped[ComplexStarModule] notation "ℑ" => imaginaryPart open ComplexStarModule theorem realPart_apply_coe (a : A) : (ℜ a : A) = (2 : ℝ)⁻¹ • (a + star a) := by - unfold realPart - simp only [selfAdjointPart_apply_coe, invOf_eq_inv] + simp [realPart] theorem imaginaryPart_apply_coe (a : A) : (ℑ a : A) = -I • (2 : ℝ)⁻¹ • (a - star a) := by - unfold imaginaryPart - simp only [LinearMap.coe_comp, Function.comp_apply, skewAdjoint.negISMul_apply_coe, - skewAdjointPart_apply_coe, invOf_eq_inv, neg_smul] + simp [imaginaryPart] /-- The standard decomposition of `ℜ a + Complex.I • ℑ a = a` of an element of a star module over `ℂ` into a linear combination of self adjoint elements. -/ theorem realPart_add_I_smul_imaginaryPart (a : A) : (ℜ a : A) + I • (ℑ a : A) = a := by - simpa only [smul_smul, realPart_apply_coe, imaginaryPart_apply_coe, neg_smul, I_mul_I, one_smul, - neg_sub, add_add_sub_cancel, smul_sub, smul_add, neg_sub_neg, invOf_eq_inv] using - invOf_two_smul_add_invOf_two_smul ℝ a + simp [realPart, imaginaryPart, smul_smul, ← smul_add, inv_smul_eq_iff₀, two_smul] @[simp] theorem realPart_I_smul (a : A) : ℜ (I • a) = -ℑ a := by @@ -460,8 +455,7 @@ lemma realPart_comp_subtype_selfAdjoint : lemma imaginaryPart_comp_subtype_selfAdjoint : imaginaryPart.comp (selfAdjoint.submodule ℝ A).subtype = 0 := by - rw [imaginaryPart, LinearMap.comp_assoc, skewAdjointPart_comp_subtype_selfAdjoint, - LinearMap.comp_zero] + ext; simp [imaginaryPart] @[simp] lemma selfAdjoint.realPart_coe {x : selfAdjoint A} : ℜ (x : A) = x := @@ -542,12 +536,9 @@ lemma realPart_ofReal (r : ℝ) : (ℜ (r : ℂ) : ℂ) = r := by lemma imaginaryPart_ofReal (r : ℝ) : ℑ (r : ℂ) = 0 := by ext1; simp [imaginaryPart_apply_coe, conj_ofReal] -set_option linter.style.whitespace false in -- manual alignment is not recognised -lemma Complex.coe_realPart (z : ℂ) : (ℜ z : ℂ) = z.re := calc - (ℜ z : ℂ) = (↑(ℜ (↑z.re + ↑z.im * I))) := by congrm (ℜ $((re_add_im z).symm)) - _ = z.re := by - rw [map_add, AddSubmonoid.coe_add, mul_comm, ← smul_eq_mul, realPart_I_smul] - simp +lemma Complex.coe_realPart (z : ℂ) : (ℜ z : ℂ) = z.re := by + conv_lhs => rw [← re_add_im z] + simp [-re_add_im, realPart_I_smul, mul_comm _ I, ← smul_eq_mul] section NonUnitalNonAssocRing From 55b749ddf32c6604e7b310d6eb8467691d2d3cf7 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Tue, 16 Jun 2026 23:12:00 +0000 Subject: [PATCH 0085/1300] chore(Analysis/Normed/Lp/PiLp): remove some `backward.defeqAttrib.useBackward` (#40685) --- Mathlib/Analysis/Normed/Lp/PiLp.lean | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 558b4a00548e99..5bc4fbdc2b7368 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -947,7 +947,6 @@ variable {ι : Type*} {κ : ι → Type*} (p : ℝ≥0∞) [Fact (1 ≤ p)] [Fintype ι] [∀ i, Fintype (κ i)] (α : ∀ i, κ i → Type*) [∀ i k, SeminormedAddCommGroup (α i k)] [∀ i k, Module 𝕜 (α i k)] -set_option backward.defeqAttrib.useBackward true in variable (𝕜) in /-- `LinearEquiv.piCurry` for `PiLp`, as an isometry. -/ def _root_.LinearIsometryEquiv.piLpCurry : @@ -958,16 +957,11 @@ def _root_.LinearIsometryEquiv.piLpCurry : ≪≫ₗ (LinearEquiv.piCongrRight fun _ => (WithLp.linearEquiv _ _ _).symm) ≪≫ₗ (WithLp.linearEquiv _ _ _).symm norm_map' := (WithLp.linearEquiv p 𝕜 _).symm.surjective.forall.2 fun x => by - simp_rw [← coe_nnnorm, NNReal.coe_inj] - dsimp only [WithLp.linearEquiv_symm_apply] + simp_rw [← coe_nnnorm, NNReal.coe_inj, WithLp.linearEquiv_symm_apply] obtain rfl | hp := eq_or_ne p ⊤ - · simp_rw [← PiLp.nnnorm_ofLp, Pi.nnnorm_def, ← PiLp.nnnorm_ofLp, Pi.nnnorm_def] - dsimp [Sigma.curry] - rw [← Finset.univ_sigma_univ, Finset.sup_sigma] + · simp [Pi.nnnorm_def, ← Finset.univ_sigma_univ, Finset.sup_sigma, Sigma.curry] · have : 0 < p.toReal := (toReal_pos_iff_ne_top _).mpr hp - simp_rw [PiLp.nnnorm_eq_sum hp] - dsimp [Sigma.curry] - simp_rw [one_div, NNReal.rpow_inv_rpow this.ne', ← Finset.univ_sigma_univ, Finset.sum_sigma] + simp [nnnorm_eq_sum hp, this.ne', ← Finset.univ_sigma_univ, Finset.sum_sigma, Sigma.curry] @[simp] theorem _root_.LinearIsometryEquiv.piLpCurry_apply (f : PiLp p (fun i : Sigma κ => α i.1 i.2)) : @@ -1149,12 +1143,12 @@ lemma coe_continuousLinearEquiv : lemma coe_symm_continuousLinearEquiv : ⇑(PiLp.continuousLinearEquiv p 𝕜 β).symm = toLp p := rfl -set_option backward.defeqAttrib.useBackward true in variable {𝕜} in /-- The projection on the `i`-th coordinate of `PiLp p β`, as a continuous linear map. -/ @[simps!] def proj (i : ι) : PiLp p β →L[𝕜] β i where __ := projₗ p β i + cont := (by fun_prop : Continuous fun a : PiLp p β ↦ a.ofLp i) end From e4fb9733350d1bb80cbb478b68bc854ac3981f4c Mon Sep 17 00:00:00 2001 From: Vasilii Nesterov <118051017+vasnesterov@users.noreply.github.com> Date: Tue, 16 Jun 2026 23:34:15 +0000 Subject: [PATCH 0086/1300] feat(Tactic/ComputeAsymptotics/Multiseries): define `Trimmed` (#40017) Define `Trimmed` predicate and prove basic lemmas about it. --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + .../ComputeAsymptotics/Multiseries/Defs.lean | 19 ++- .../Multiseries/Trimming.lean | 140 ++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Tactic/ComputeAsymptotics/Multiseries/Trimming.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8a4fbc6a4795c7..c91c39aba616da 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7200,6 +7200,7 @@ public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Monomial.Basic public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Monomial.Predicates +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Trimming public import Mathlib.Tactic.ComputeDegree public import Mathlib.Tactic.CongrExclamation public import Mathlib.Tactic.CongrM diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 38a86214f5cb93..f7fe1f5c1e9e22 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -74,6 +74,7 @@ public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Monomial.Basic public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Monomial.Predicates +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Trimming public import Mathlib.Tactic.ComputeDegree public import Mathlib.Tactic.CongrExclamation public import Mathlib.Tactic.CongrM diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean index 4680297763ea00..2264a94ec0a599 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean @@ -42,7 +42,7 @@ in the basis `[b₂, ..., bₙ]` (`basis_tl`). namespace Tactic.ComputeAsymptotics -open Filter Stream' +open Filter Stream' Topology /-- List of functions used to construct monomials in multiseries. -/ abbrev Basis := List (ℝ → ℝ) @@ -706,6 +706,23 @@ theorem replaceFun {ms : MultiseriesExpansion (basis_hd :: basis_tl)} {f : ℝ h_tl, ?_⟩ grw [mk_toFun, h_eq] +/-- If `f` can be approximated by multiseries with negative leading exponent, then +it tends to zero. -/ +theorem neg_leadingExp_tendsto_zero {basis_hd : ℝ → ℝ} {basis_tl : Basis} + {ms : MultiseriesExpansion (basis_hd :: basis_tl)} + (h_neg : ms.leadingExp < 0) (h_approx : ms.Approximates) : + Tendsto ms.toFun atTop (𝓝 0) := by + cases ms + · exact Tendsto.congr' h_approx.elim_nil.symm tendsto_const_nhds + · obtain ⟨h_coef, h_maj, h_tl⟩ := h_approx.elim_cons + simp only [leadingExp_def, mk_seq, Multiseries.leadingExp_cons, WithBot.coe_lt_zero] at h_neg + exact Majorized.tendsto_zero_of_neg h_neg h_maj + +theorem nil_tendsto_zero {basis_hd : ℝ → ℝ} {basis_tl : Basis} {f : ℝ → ℝ} + (h : MultiseriesExpansion.Approximates (basis := basis_hd :: basis_tl) (mk .nil f)) : + Tendsto f atTop (𝓝 0) := + neg_leadingExp_tendsto_zero (by simp) h + end Approximates instance (basis_hd : ℝ → ℝ) (basis_tl : Basis) : diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Trimming.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Trimming.lean new file mode 100644 index 00000000000000..15e00292ae25ca --- /dev/null +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Trimming.lean @@ -0,0 +1,140 @@ +/- +Copyright (c) 2026 Vasilii Nesterov. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Vasilii Nesterov +-/ +module + +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs + +/-! +# Trimming of multiseries + +A multiseries is *trimmed* when its leading coefficient (the head of its expansion) is itself +trimmed and non-zero. For a trimmed multiseries, the leading monomial captures the main +asymptotic behavior of the approximated function. + +## Main definitions + +* `IsZero`: a multiseries represents the zero function — it is either the real number `0` + (for the empty basis) or has an empty underlying sequence (`.nil`). +* `Trimmed` and `Multiseries.Trimmed`: a multiseries is trimmed in the sense above. The former + is defined inductively for `MultiseriesExpansion`, and the latter for `Multiseries` is + derived from it. + +We also prove structural lemmas relating these predicates to `seq` and to the `cons`/`nil` +constructors. + +-/ + +@[expose] public section + +namespace Tactic.ComputeAsymptotics + +namespace MultiseriesExpansion + +open Filter Topology Stream' + +/-- A multiseries is zero if it is the real constant `0` or has an empty sequence. -/ +inductive IsZero : {basis : Basis} → MultiseriesExpansion basis → Prop +| const {c : MultiseriesExpansion []} (hc : c.toReal = 0) : IsZero c +| nil {basis_hd} {basis_tl} (f) : @IsZero (basis_hd :: basis_tl) (mk .nil f) + +namespace IsZero + +@[simp] +theorem const_iff {c : MultiseriesExpansion []} : IsZero c ↔ c.toReal = 0 := by + constructor <;> grind [IsZero] + +@[simp] +theorem iff_seq_eq_nil {basis_hd basis_tl} {ms : MultiseriesExpansion (basis_hd :: basis_tl)} : + IsZero ms ↔ ms.seq = .nil where + mp h := by cases h; rw [mk_seq] + mpr h := by + convert IsZero.nil ms.toFun + simp [h] + +theorem approximates_zero {basis : Basis} {ms : MultiseriesExpansion basis} + (h_zero : IsZero ms) (h_approx : ms.Approximates) : + ms.toFun =ᶠ[atTop] 0 := by + cases h_zero with + | const hc => simp [hc, Pi.zero_def] + | nil => simpa using h_approx + +theorem not_cons {basis_hd} {basis_tl} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} + {tl : Multiseries basis_hd basis_tl} {f : ℝ → ℝ} : + ¬ @IsZero (basis_hd :: basis_tl) (mk (.cons exp coef tl) f) := by + simp + +end IsZero + +/-- We call a multiseries `Trimmed` if it is either a constant, `.nil`, or `cons (exp, coef) tl` +where `coef` is trimmed and is not zero. Intuitively, when a multiseries is trimmed, its leading +monomial gives the main asymptotic behavior of the approximated function. -/ +inductive Trimmed : {basis : Basis} → MultiseriesExpansion basis → Prop +| const {c : ℝ} : @Trimmed [] c +| nil {basis_hd} {basis_tl} {f} : @Trimmed (basis_hd :: basis_tl) (mk .nil f) +| cons {basis_hd} {basis_tl} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} + {tl : Multiseries basis_hd basis_tl} {f : ℝ → ℝ} (h_trimmed : coef.Trimmed) + (h_ne_zero : ¬ IsZero coef) : + @Trimmed (basis_hd :: basis_tl) (mk (.cons exp coef tl) f) + +/-- We call a `Multiseries` `Trimmed` if it is either `.nil` or `cons (exp, coef) tl` where `coef` +is trimmed and is not zero. -/ +def Multiseries.Trimmed {basis_hd : ℝ → ℝ} {basis_tl : Basis} + (ms : Multiseries basis_hd basis_tl) : Prop := + (mk ms 0).Trimmed + +theorem trimmed_iff_seq_trimmed {basis_hd : ℝ → ℝ} {basis_tl : Basis} + (ms : MultiseriesExpansion (basis_hd :: basis_tl)) : + ms.Trimmed ↔ ms.seq.Trimmed where + mp h := by + cases h <;> constructor <;> grind + mpr h := by + generalize hs : ms.seq = s at h + cases h with + | nil => + convert Trimmed.nil (f := ms.toFun) + simp [hs] + | @cons _ _ exp coef tl _ h_trimmed h_ne_zero => + convert Trimmed.cons h_trimmed h_ne_zero (exp := exp) (tl := tl) (f := ms.toFun) + simp only [ms_eq_mk_iff, hs, and_true] + +namespace Multiseries.Trimmed + +@[simp] +theorem nil {basis_hd} {basis_tl} : + @Multiseries.Trimmed basis_hd basis_tl .nil := by + constructor + +theorem cons {basis_hd} {basis_tl} {exp : ℝ} + {coef : MultiseriesExpansion basis_tl} {tl : Multiseries basis_hd basis_tl} + (h_coef : coef.Trimmed) (h_ne_zero : ¬ IsZero coef) : + Multiseries.Trimmed (cons exp coef tl) := + MultiseriesExpansion.Trimmed.cons h_coef h_ne_zero + +/-- If `cons (exp, coef) tl` is trimmed, then `coef` is trimmed and is not zero. -/ +theorem elim_cons {basis_hd} {basis_tl} {exp : ℝ} + {coef : MultiseriesExpansion basis_tl} {tl : Multiseries basis_hd basis_tl} + (h : Multiseries.Trimmed (.cons exp coef tl)) : + coef.Trimmed ∧ ¬ IsZero coef := by + generalize h_ms : Multiseries.cons exp coef tl = ms at h + cases h with + | nil => simp at h_ms + | cons h_trimmed h_ne_zero => + simp at h_ms + grind + +end Multiseries.Trimmed + +/-- If `cons (exp, coef) tl` is trimmed, then `coef` is trimmed and is not zero. -/ +theorem elim_cons {basis_hd} {basis_tl} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} + {tl : Multiseries basis_hd basis_tl} {f : ℝ → ℝ} + (h : Trimmed (mk (.cons exp coef tl) f)) : + coef.Trimmed ∧ ¬ IsZero coef := by + simp only [trimmed_iff_seq_trimmed, mk_seq] at h + exact h.elim_cons + +end MultiseriesExpansion + +end Tactic.ComputeAsymptotics From 727fecc30e2196620e58b7cafed9e154826a76f7 Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Tue, 16 Jun 2026 23:48:01 +0000 Subject: [PATCH 0087/1300] doc(RingTheory/DedekindDomain/LinearDisjoint): fix typos in the module docstring (#40218) Fix typos in the namespace in the module docstring. --- Mathlib/RingTheory/DedekindDomain/LinearDisjoint.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/DedekindDomain/LinearDisjoint.lean b/Mathlib/RingTheory/DedekindDomain/LinearDisjoint.lean index d504e598dc6aab..70e4e672eda398 100644 --- a/Mathlib/RingTheory/DedekindDomain/LinearDisjoint.lean +++ b/Mathlib/RingTheory/DedekindDomain/LinearDisjoint.lean @@ -18,8 +18,8 @@ and `Frac R` denotes the fraction field of a domain `R`. ## Main results and definitions -* `FractionalIdeal.differentIdeal_eq_map_differentIdeal`: `𝓓(B/R₁) = 𝓓(R₂/A)` -* `FractionalIdeal.differentIdeal_eq_differentIdeal_mul_differentIdeal_of_isCoprime`: +* `IsDedekindDomain.differentIdeal_eq_map_differentIdeal`: `𝓓(B/R₁) = 𝓓(R₂/A)` +* `IsDedekindDomain.differentIdeal_eq_differentIdeal_mul_differentIdeal_of_isCoprime`: `𝓓(B/A) = 𝓓(R₁/A) * 𝓓(R₂/A)`. * `Module.Basis.ofIsCoprimeDifferentIdeal`: Construct a `R₁`-basis of `B` by lifting an `A`-basis of `R₂`. From e5591f1062d09a4220a7f6ecc3b1456c29ffb894 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:02:22 +0000 Subject: [PATCH 0088/1300] chore(MeasureTheory/Integral/Lebesgue): remove an `erw` (#40407) Extracted from #40348 Co-authored-by: Batixx --- Mathlib/MeasureTheory/Integral/Lebesgue/Countable.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Countable.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Countable.lean index d0833a711607b1..2d3d72d8434f76 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Countable.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Countable.lean @@ -238,7 +238,8 @@ theorem exists_pos_lintegral_lt_of_sigmaFinite (μ : Measure α) [SigmaFinite μ have hN_meas : Measurable N := measurableSet_spanningSetsIndex μ have hNs : ∀ n, N ⁻¹' {n} = s n := preimage_spanningSetsIndex_singleton μ refine ⟨δ ∘ N, fun x => δpos _, measurable_from_nat.comp hN_meas, ?_⟩ - erw [lintegral_comp measurable_from_nat.coe_nnreal_ennreal hN_meas] + simp_rw [Function.comp_apply, ← Function.comp_apply (f := (fun n ↦ (↑(δ n) : ℝ≥0∞))), + lintegral_comp measurable_from_nat.coe_nnreal_ennreal hN_meas] simpa [N, hNs, lintegral_countable', measurableSet_spanningSetsIndex, mul_comm] using δsum omit [MeasurableSpace α] From af5794b60dceddf115f1bc6869cf1669e291d0ec Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:02:24 +0000 Subject: [PATCH 0089/1300] chore: use more `inferInstanceAs` to define instances on type synonyms (#40457) Otherwise, the instance functions are not declared on the right space. Co-authored-by: sgouezel --- Mathlib/Topology/Defs/Basic.lean | 1 + Mathlib/Topology/EMetricSpace/Weak.lean | 37 +++++++++++-------- .../Topology/VectorBundle/Constructions.lean | 6 ++- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Mathlib/Topology/Defs/Basic.lean b/Mathlib/Topology/Defs/Basic.lean index 75f02a3e86df4b..c2976b51382d49 100644 --- a/Mathlib/Topology/Defs/Basic.lean +++ b/Mathlib/Topology/Defs/Basic.lean @@ -68,6 +68,7 @@ universe u v open Set /-- A topology on `X`. -/ +@[to_dual_dont_translate] class TopologicalSpace (X : Type u) where /-- A predicate saying that a set is an open set. Use `IsOpen` in the root namespace instead. -/ protected IsOpen : Set X → Prop diff --git a/Mathlib/Topology/EMetricSpace/Weak.lean b/Mathlib/Topology/EMetricSpace/Weak.lean index 8b7d8de1b5a318..add0cc36ac9133 100644 --- a/Mathlib/Topology/EMetricSpace/Weak.lean +++ b/Mathlib/Topology/EMetricSpace/Weak.lean @@ -197,22 +197,25 @@ instance [EDist α] : EDist (WithTop α) where | (x : α), ⊤ => ∞ | (x : α), (y : α) => edist x y -/-- If `α` has a topology induced by a linear order in is a weak pseudo extended metric space, -so if `WithTop α` -/ +/-- If `α` has a topology induced by a linear order and is a weak pseudo extended metric space, +so is `WithTop α` -/ @[to_dual] instance instWeakPseudoEMetricSpaceWithTop [m : WeakPseudoEMetricSpace α] : WeakPseudoEMetricSpace (WithTop α) := - let : TopologicalSpace (Option α) := TopologicalSpace.instWithTopOfOrderTopology - Option.WeakPseudoEMetricSpace.OfIsOpenEmbedding (inst := instEDistWithTop) rfl + letI : TopologicalSpace (Option α) := TopologicalSpace.instWithTopOfOrderTopology + letI : WeakPseudoEMetricSpace (Option α) := + Option.WeakPseudoEMetricSpace.OfIsOpenEmbedding (inst := instEDistWithTop) rfl WithTop.isOpenEmbedding_some + inferInstanceAs <| WeakPseudoEMetricSpace (Option α) -/-- If `α` has a topology induced by a linear order in is a weak extended metric space, -so if `WithTop α` -/ +/-- If `α` has a topology induced by a linear order and is a weak extended metric space, +so is `WithTop α` -/ @[to_dual] instance instWeakEMetricSpaceWithTop [m : WeakEMetricSpace α] : WeakEMetricSpace (WithTop α) := let : TopologicalSpace (Option α) := TopologicalSpace.instWithTopOfOrderTopology - Option.WeakEMetricSpace.OfIsOpenEmbedding (inst := instEDistWithTop) rfl - WithTop.isOpenEmbedding_some + let : WeakEMetricSpace (Option α) := Option.WeakEMetricSpace.OfIsOpenEmbedding + (inst := instEDistWithTop) rfl WithTop.isOpenEmbedding_some + inferInstanceAs <| WeakEMetricSpace (Option α) open scoped OnePoint in instance [EDist α] : EDist (OnePoint α) where @@ -227,30 +230,32 @@ extended metric space. -/ instance instWeakPseudoEMetricSpaceOnePoint [m : WeakPseudoEMetricSpace α] : WeakPseudoEMetricSpace (OnePoint α) := let : TopologicalSpace (Option α) := OnePoint.instTopologicalSpace - Option.WeakPseudoEMetricSpace.OfIsOpenEmbedding (inst := instEDistOnePoint) rfl - OnePoint.isOpenEmbedding_coe + let : WeakPseudoEMetricSpace (Option α) := Option.WeakPseudoEMetricSpace.OfIsOpenEmbedding + (inst := instEDistOnePoint) rfl OnePoint.isOpenEmbedding_coe + inferInstanceAs <| WeakPseudoEMetricSpace (Option α) /-- The one point compactification of a weak extended metric space is again a weak extended metric space. -/ instance instWeakEMetricSpaceOnePoint [m : WeakEMetricSpace α] : WeakEMetricSpace (OnePoint α) := let : TopologicalSpace (Option α) := OnePoint.instTopologicalSpace - Option.WeakEMetricSpace.OfIsOpenEmbedding (inst := instEDistOnePoint) rfl - OnePoint.isOpenEmbedding_coe + let : WeakEMetricSpace (Option α) := Option.WeakEMetricSpace.OfIsOpenEmbedding + (inst := instEDistOnePoint) rfl OnePoint.isOpenEmbedding_coe + inferInstanceAs <| WeakEMetricSpace (Option α) /-- `ℝ≥0∞` is a weak extended metric space with its usual distance function. -/ noncomputable instance instWeakEMetricSpaceENNReal : WeakEMetricSpace ℝ≥0∞ := - instWeakEMetricSpaceWithTop + inferInstanceAs <| WeakEMetricSpace (WithTop ℝ≥0) /-- `EReal` is a weak extended metric space with its usual distance function. -/ noncomputable instance instWeakEMetricSpaceEReal : WeakEMetricSpace EReal := - instWeakEMetricSpaceWithBot + inferInstanceAs <| WeakEMetricSpace (WithBot (WithTop ℝ)) /-- `ℕ∞` is a weak extended metric space with its usual distance function. -/ noncomputable instance instWeakEMetricSpaceENat : WeakEMetricSpace ℕ∞ := - instWeakEMetricSpaceWithTop + inferInstanceAs <| WeakEMetricSpace (WithTop ℕ) -theorem ENNReal.edist_eq_top_iff (a b : ℝ≥0∞) : edist a b = ⊤ ↔ a ≠ b ∧ (a = ⊤ ∨ b = ⊤) := by +theorem ENNReal.edist_eq_top_iff (a b : ℝ≥0∞) : edist a b = ∞ ↔ a ≠ b ∧ (a = ∞ ∨ b = ∞) := by cases a <;> cases b <;> simp only [ne_eq, not_true_eq_false, or_self, and_true, iff_false, top_ne_coe, not_false_eq_true, coe_ne_top, or_false, and_self, or_true, and_self, iff_true, coe_inj, and_false, iff_false] diff --git a/Mathlib/Topology/VectorBundle/Constructions.lean b/Mathlib/Topology/VectorBundle/Constructions.lean index ab64b02686f619..1ea7d3026627dc 100644 --- a/Mathlib/Topology/VectorBundle/Constructions.lean +++ b/Mathlib/Topology/VectorBundle/Constructions.lean @@ -180,10 +180,12 @@ section variable (R 𝕜 : Type*) {B : Type*} (F : Type*) (E : B → Type*) {B' : Type*} (f : B' → B) -instance [i : ∀ x : B, AddCommMonoid (E x)] (x : B') : AddCommMonoid ((f *ᵖ E) x) := i _ +instance [i : ∀ x : B, AddCommMonoid (E x)] (x : B') : AddCommMonoid ((f *ᵖ E) x) := + inferInstanceAs <| AddCommMonoid (E (f x)) instance [Semiring R] [∀ x : B, AddCommMonoid (E x)] [i : ∀ x, Module R (E x)] (x : B') : - Module R ((f *ᵖ E) x) := i _ + Module R ((f *ᵖ E) x) := + inferInstanceAs <| Module R (E (f x)) variable {E F} [TopologicalSpace B'] [TopologicalSpace (TotalSpace F E)] [NontriviallyNormedField 𝕜] [NormedAddCommGroup F] [NormedSpace 𝕜 F] [TopologicalSpace B] [∀ x, AddCommMonoid (E x)] From 4dbd0e30c53c18da017fbc60ce7609a22fdefb41 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:02:26 +0000 Subject: [PATCH 0090/1300] feat(Analysis): use `IsApply` for `TestFunction` (#40608) --- .../Analysis/Distribution/TestFunction.lean | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Mathlib/Analysis/Distribution/TestFunction.lean b/Mathlib/Analysis/Distribution/TestFunction.lean index 3134a5962eb12a..8ccaddbd709770 100644 --- a/Mathlib/Analysis/Distribution/TestFunction.lean +++ b/Mathlib/Analysis/Distribution/TestFunction.lean @@ -171,55 +171,68 @@ theorem coe_mk {f : E → F} {contDiff : ContDiff ℝ n f} {hasCompactSupport : section AddCommGroup -@[simps -fullyApplied] instance : Zero 𝓓^{n}(Ω, F) where zero := ⟨0, contDiff_zero_fun, .zero, by simp only [tsupport_zero, empty_subset]⟩ -@[simps -fullyApplied] +instance : IsZeroApply 𝓓^{n}(Ω, F) E F where + zero_apply _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_zero := FunLike.coe_zero + instance : Add 𝓓^{n}(Ω, F) where add f g := ⟨f + g, f.contDiff.add g.contDiff, f.hasCompactSupport.add g.hasCompactSupport, tsupport_add f g |>.trans <| union_subset f.tsupport_subset g.tsupport_subset⟩ -@[simps -fullyApplied] +instance : IsAddApply 𝓓^{n}(Ω, F) E F where + add_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_add := FunLike.coe_add + instance : Neg 𝓓^{n}(Ω, F) where neg f := ⟨-f, f.contDiff.neg, f.hasCompactSupport.neg, tsupport_neg f ▸ f.tsupport_subset⟩ -@[simps -fullyApplied] +instance : IsNegApply 𝓓^{n}(Ω, F) E F where + neg_apply _ _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_neg := FunLike.coe_neg + instance : Sub 𝓓^{n}(Ω, F) where sub f g := ⟨f - g, f.contDiff.sub g.contDiff, f.hasCompactSupport.sub g.hasCompactSupport, tsupport_sub f g |>.trans <| union_subset f.tsupport_subset g.tsupport_subset⟩ -@[simps -fullyApplied] +instance : IsSubApply 𝓓^{n}(Ω, F) E F where + sub_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_sub := FunLike.coe_sub + instance {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : SMul R 𝓓^{n}(Ω, F) where smul c f := ⟨c • f, f.contDiff.const_smul c, f.hasCompactSupport.smul_left, tsupport_smul_subset_right _ _ |>.trans f.tsupport_subset⟩ -instance : AddCommGroup 𝓓^{n}(Ω, F) := fast_instance% - DFunLike.coe_injective.addCommGroup _ rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) +instance {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : + IsSMulApply R 𝓓^{n}(Ω, F) E F where + smul_apply _ _ _ := rfl -variable (Ω F n) in -/-- Coercion as an additive homomorphism. -/ -@[simps -fullyApplied] -def coeFnAddMonoidHom : 𝓓^{n}(Ω, F) →+ E → F where - toFun f := f - map_zero' := coe_zero - map_add' _ _ := rfl +@[deprecated (since := "2026-06-15")] alias coe_smul := FunLike.coe_smul + +instance : AddCommGroup 𝓓^{n}(Ω, F) := fast_instance% FunLike.addCommGroup + +@[deprecated (since := "2026-06-15")] alias coeFnAddMonoidHom := FunLike.coeAddMonoidHom + +@[deprecated (since := "2026-06-15")] alias coeFnAddMonoidHom_apply := FunLike.coeAddMonoidHom_apply end AddCommGroup section Module instance {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : - Module R 𝓓^{n}(Ω, F) := fast_instance% - DFunLike.coe_injective.module R (coeFnAddMonoidHom Ω F n) fun _ _ ↦ rfl + Module R 𝓓^{n}(Ω, F) := fast_instance% FunLike.module instance {R S} [Semiring R] [Semiring S] [Module R F] [Module S F] [SMulCommClass ℝ R F] [SMulCommClass ℝ S F] [ContinuousConstSMul R F] [ContinuousConstSMul S F] [SMul R S] [IsScalarTower R S F] : - IsScalarTower R S 𝓓^{n}(Ω, F) where - smul_assoc _ _ _ := by ext; simp + IsScalarTower R S 𝓓^{n}(Ω, F) := FunLike.isScalarTower end Module From c7b36bfb52039c09c9e29ab8612f378ba637537e Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Wed, 17 Jun 2026 00:34:42 +0000 Subject: [PATCH 0091/1300] chore(Topology/Instances/Complex): remove an erw (#40321) - rewrites the real subfield branch to use `ofRealHom.rangeRestrictField`, allowing the `hr` rewrite to be handled by `rw` Extracted from #40147 --- Mathlib/Topology/Instances/Complex.lean | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Mathlib/Topology/Instances/Complex.lean b/Mathlib/Topology/Instances/Complex.lean index cab97bbcf862d4..f476d7ae6403fc 100644 --- a/Mathlib/Topology/Instances/Complex.lean +++ b/Mathlib/Topology/Instances/Complex.lean @@ -69,23 +69,17 @@ theorem Complex.uniformContinuous_ringHom_eq_id_or_conj (K : Subfield ℂ) {ψ : let j := RingEquiv.subfieldCongr h -- ψ₁ is the continuous ring hom `ℝ →+* ℂ` constructed from `j : closure (K) ≃+* ℝ` -- and `extψ : closure (K) →+* ℂ` - let ψ₁ := RingHom.comp extψ (RingHom.comp j.symm.toRingHom ofRealHom.rangeRestrict) + let ψ₁ := RingHom.comp extψ (RingHom.comp j.symm.toRingHom ofRealHom.rangeRestrictField) -- Porting note: was `by continuity!` and was used inline have hψ₁ : Continuous ψ₁ := by simpa only [RingHom.coe_comp] using! hψ.comp ((continuous_algebraMap ℝ ℂ).subtype_mk _) ext1 x - rsuffices ⟨r, hr⟩ : ∃ r : ℝ, ofRealHom.rangeRestrict r = j (ι x) - · have := - RingHom.congr_fun (ringHom_eq_ofReal_of_continuous hψ₁) r - rw [RingHom.comp_apply, RingHom.comp_apply] at this - -- In `this`, the `DFunLike.coe` thinks it is applying a `(ℝ →+* ↥ofRealHom.fieldRange)`, - -- while in `hr`, we have a `(ℝ →+* ↥ofRealHom.range)`. - -- We could add a `@[simp]` lemma fixing this, but it breaks later steps of the proof. - erw [hr] at this - rw [RingEquiv.toRingHom_eq_coe] at this + rsuffices ⟨r, hr⟩ : ∃ r : ℝ, ofRealHom.rangeRestrictField r = j (ι x) + · have := RingHom.congr_fun (ringHom_eq_ofReal_of_continuous hψ₁) r + rw [RingHom.comp_apply, RingHom.comp_apply, hr, RingEquiv.toRingHom_eq_coe] at this convert! this using 1 · exact (IsDenseInducing.extend_eq di hc.continuous _).symm - · rw [← ofRealHom.coe_rangeRestrict, hr] + · rw [← ofRealHom.coe_rangeRestrictField, hr] rfl obtain ⟨r, hr⟩ := SetLike.coe_mem (j (ι x)) exact ⟨r, Subtype.ext hr⟩ From 749ea6a384276750699b6b7a8f50727132f4dc4c Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:34:45 +0000 Subject: [PATCH 0092/1300] feat(LinearAlgebra): use `Is*Apply` for `MultilinearMap` (#40466) --- Mathlib/FieldTheory/Fixed.lean | 2 +- Mathlib/FieldTheory/JacobsonNoether.lean | 2 +- .../LinearAlgebra/Alternating/DomCoprod.lean | 12 ++-- Mathlib/LinearAlgebra/Multilinear/Basic.lean | 72 +++++++++---------- .../RootSystem/CartanMatrix.lean | 2 +- .../LinearAlgebra/TensorPower/Pairing.lean | 9 +-- .../RingTheory/MatrixPolynomialAlgebra.lean | 9 +-- Mathlib/RingTheory/PicardGroup.lean | 2 +- 8 files changed, 53 insertions(+), 57 deletions(-) diff --git a/Mathlib/FieldTheory/Fixed.lean b/Mathlib/FieldTheory/Fixed.lean index bf68c06f4bfe70..aac5f0fa40dcf1 100644 --- a/Mathlib/FieldTheory/Fixed.lean +++ b/Mathlib/FieldTheory/Fixed.lean @@ -156,7 +156,7 @@ theorem linearIndependent_smul_of_linearIndependent {s : Finset F} : refine (sum_attach s fun i ↦ (g • l i - l i) • MulAction.toFun G F i).trans ?_ ext g' conv_lhs => - rw [sum_apply] + rw [Finset.sum_apply] congr · skip · ext diff --git a/Mathlib/FieldTheory/JacobsonNoether.lean b/Mathlib/FieldTheory/JacobsonNoether.lean index 09527bb125b7de..a6f82c4e7180e1 100644 --- a/Mathlib/FieldTheory/JacobsonNoether.lean +++ b/Mathlib/FieldTheory/JacobsonNoether.lean @@ -97,7 +97,7 @@ lemma exist_pow_eq_zero_of_le (p : ℕ) [hchar : ExpChar D p] have inter : (ad k D a)^[p ^ m] = 0 := by ext x rw [ad_eq_lmul_left_sub_lmul_right, ← Module.End.pow_apply, Pi.sub_apply, - sub_pow_expChar_pow_of_commute p m (commute_mulLeft_right a a), sub_apply, + sub_pow_expChar_pow_of_commute p m (commute_mulLeft_right a a), LinearMap.sub_apply, pow_mulLeft, mulLeft_apply, pow_mulRight, mulRight_apply, Pi.zero_apply, Subring.mem_center_iff.1 hm.2 x] exact sub_eq_zero_of_eq rfl diff --git a/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean b/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean index 5976c2a5dbd070..fb33822f9b1960 100644 --- a/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean +++ b/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean @@ -56,7 +56,7 @@ def domCoprod.summand (a : Mᵢ [⋀^ιa]→ₗ[R'] N₁) (b : Mᵢ [⋀^ιb]→ obtain ⟨⟨sl, sr⟩, h⟩ := H ext v simp only [MultilinearMap.domDomCongr_apply, MultilinearMap.domCoprod_apply, - coe_multilinearMap, MultilinearMap.smul_apply] + coe_multilinearMap, _root_.smul_apply] replace h := inv_mul_eq_iff_eq_mul.mp h.symm have : Equiv.Perm.sign (σ₁ * Perm.sumCongrHom _ _ (sl, sr)) = Equiv.Perm.sign σ₁ * (Equiv.Perm.sign sl * Equiv.Perm.sign sr) := by simp @@ -83,7 +83,7 @@ theorem domCoprod.summand_add_swap_smul_eq_zero (a : Mᵢ [⋀^ιa]→ₗ[R'] N domCoprod.summand] rw [smul_eq_mul, Perm.sign_mul, Perm.sign_swap hij] simp only [one_mul, neg_mul, Function.comp_apply, Units.neg_smul, Perm.coe_mul, - MultilinearMap.smul_apply, MultilinearMap.neg_apply, MultilinearMap.domDomCongr_apply, + _root_.smul_apply, _root_.neg_apply, MultilinearMap.domDomCongr_apply, MultilinearMap.domCoprod_apply] convert! add_neg_cancel (G := N₁ ⊗[R'] N₂) _ using 6 <;> · ext k @@ -96,7 +96,7 @@ theorem domCoprod.summand_eq_zero_of_smul_invariant (a : Mᵢ [⋀^ιa]→ₗ[R' {i j : ιa ⊕ ιb} (hv : v i = v j) (hij : i ≠ j) : swap i j • σ = σ → domCoprod.summand a b σ v = 0 := by induction σ using Quotient.inductionOn' with | _ σ - dsimp only [Quotient.liftOn'_mk'', Quotient.map'_mk'', MultilinearMap.smul_apply, + dsimp only [Quotient.liftOn'_mk'', Quotient.map'_mk'', _root_.smul_apply, MultilinearMap.domDomCongr_apply, MultilinearMap.domCoprod_apply, domCoprod.summand] intro hσ obtain ⟨⟨sl, sr⟩, hσ⟩ := QuotientGroup.leftRel_apply.mp (Quotient.exact' hσ) @@ -139,7 +139,7 @@ def domCoprod (a : Mᵢ [⋀^ιa]→ₗ[R'] N₁) (b : Mᵢ [⋀^ιb]→ₗ[R'] { ∑ σ : Perm.ModSumCongr ιa ιb, domCoprod.summand a b σ with toFun := fun v => (⇑(∑ σ : Perm.ModSumCongr ιa ιb, domCoprod.summand a b σ)) v map_eq_zero_of_eq' := fun v i j hv hij => by - rw [MultilinearMap.sum_apply] + rw [_root_.sum_apply] exact Finset.sum_involution (fun σ _ => Equiv.swap i j • σ) (fun σ _ => domCoprod.summand_add_swap_smul_eq_zero a b σ hv hij) @@ -163,11 +163,11 @@ def domCoprod' : fun c m n => ?_ <;> · ext simp only [domCoprod_apply, add_apply, smul_apply, ← Finset.sum_add_distrib, - Finset.smul_sum, MultilinearMap.sum_apply, domCoprod.summand] + Finset.smul_sum, _root_.sum_apply, domCoprod.summand] congr ext σ induction σ using Quotient.inductionOn' - simp only [Quotient.liftOn'_mk'', coe_add, coe_smul, MultilinearMap.smul_apply, + simp only [Quotient.liftOn'_mk'', coe_add, coe_smul, _root_.smul_apply, ← MultilinearMap.domCoprod'_apply] simp only [TensorProduct.add_tmul, ← TensorProduct.smul_tmul', TensorProduct.tmul_add, TensorProduct.tmul_smul, map_add, map_smul] diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index 81ed0952bd1bc5..890dda5223e163 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -6,9 +6,12 @@ Authors: Sébastien Gouëzel module public import Mathlib.Algebra.BigOperators.Group.Finset.Powerset +public import Mathlib.Algebra.BigOperators.Pi public import Mathlib.Data.Finset.Sort public import Mathlib.Data.Fintype.BigOperators public import Mathlib.Data.Fintype.Powerset +public import Mathlib.Data.FunLike.Group +public import Mathlib.Data.FunLike.Module public import Mathlib.LinearAlgebra.Pi public import Mathlib.Logic.Equiv.Fintype public import Mathlib.Tactic.Abel @@ -183,19 +186,21 @@ instance : Add (MultilinearMap R M₁ M₂) := ⟨fun x => f x + f' x, fun m i x y => by simp [add_left_comm, add_assoc], fun m i c x => by simp [smul_add]⟩⟩ -@[simp] -theorem add_apply (m : ∀ i, M₁ i) : (f + f') m = f m + f' m := - rfl +instance : IsAddApply (MultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + add_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias add_apply := add_apply instance : Zero (MultilinearMap R M₁ M₂) := ⟨⟨fun _ => 0, fun _ _ _ _ => by simp, fun _ _ c _ => by simp⟩⟩ +instance : IsZeroApply (MultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + zero_apply _ := rfl + instance : Inhabited (MultilinearMap R M₁ M₂) := ⟨0⟩ -@[simp] -theorem zero_apply (m : ∀ i, M₁ i) : (0 : MultilinearMap R M₁ M₂) m = 0 := - rfl +@[deprecated (since := "2026-06-10")] protected alias zero_apply := zero_apply section SMul @@ -206,32 +211,28 @@ instance : SMul S (MultilinearMap R M₁ M₂) := ⟨fun m => c • f m, fun m i x y => by simp [smul_add], fun l i x d => by simp [← smul_comm x c (_ : M₂)]⟩⟩ -@[simp] -theorem smul_apply (f : MultilinearMap R M₁ M₂) (c : S) (m : ∀ i, M₁ i) : (c • f) m = c • f m := - rfl +instance : IsSMulApply S (MultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + smul_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias smul_apply := smul_apply -theorem coe_smul (c : S) (f : MultilinearMap R M₁ M₂) : ⇑(c • f) = c • (⇑f) := rfl +@[deprecated (since := "2026-06-10")] alias coe_smul := FunLike.coe_smul end SMul -- The `AddMonoid` instance exists to help speedup unification -instance : AddMonoid (MultilinearMap R M₁ M₂) := fast_instance% - coe_injective.addMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl +instance : AddMonoid (MultilinearMap R M₁ M₂) := fast_instance% FunLike.addMonoid instance addCommMonoid : AddCommMonoid (MultilinearMap R M₁ M₂) := fast_instance% - coe_injective.addCommMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + FunLike.addCommMonoid -/-- Coercion of a multilinear map to a function as an additive monoid homomorphism. -/ -@[simps] def coeAddMonoidHom : MultilinearMap R M₁ M₂ →+ (((i : ι) → M₁ i) → M₂) where - toFun := DFunLike.coe; map_zero' := rfl; map_add' _ _ := rfl +@[deprecated (since := "2026-06-10")] alias coeAddMonoidHom := FunLike.coeAddMonoidHom -@[simp] -theorem coe_sum {α : Type*} (f : α → MultilinearMap R M₁ M₂) (s : Finset α) : - ⇑(∑ a ∈ s, f a) = ∑ a ∈ s, ⇑(f a) := - map_sum coeAddMonoidHom f s +@[deprecated (since := "2026-06-10")] alias coeAddMonoidHom_apply := FunLike.coeAddMonoidHom_apply + +@[deprecated (since := "2026-06-10")] alias coe_sum := FunLike.coe_sum -theorem sum_apply {α : Type*} (f : α → MultilinearMap R M₁ M₂) (m : ∀ i, M₁ i) {s : Finset α} : - (∑ a ∈ s, f a) m = ∑ a ∈ s, f a m := by simp +@[deprecated (since := "2026-06-10")] protected alias sum_apply := _root_.sum_apply /-- If `f` is a multilinear map, then `f.toLinearMap m i` is the linear map obtained by fixing all coordinates but `i` equal to those of `m`, and varying the `i`-th coordinate. -/ @@ -885,8 +886,7 @@ variable [Semiring R] [(i : ι) → AddCommMonoid (M₁ i)] [(i : ι) → Module [AddCommMonoid M₂] [Module R M₂] instance [Monoid S] [DistribMulAction S M₂] [SMulCommClass R S M₂] : - DistribMulAction S (MultilinearMap R M₁ M₂) := fast_instance% - coe_injective.distribMulAction coeAddMonoidHom fun _ _ ↦ rfl + DistribMulAction S (MultilinearMap R M₁ M₂) := fast_instance% FunLike.distribMulAction section Module @@ -895,10 +895,10 @@ variable [Semiring S] [Module S M₂] [SMulCommClass R S M₂] /-- The space of multilinear maps over an algebra over `R` is a module over `R`, for the pointwise addition and scalar multiplication. -/ instance : Module S (MultilinearMap R M₁ M₂) := fast_instance% - coe_injective.module _ coeAddMonoidHom fun _ _ ↦ rfl + FunLike.module instance [Module.IsTorsionFree S M₂] : Module.IsTorsionFree S (MultilinearMap R M₁ M₂) := - coe_injective.moduleIsTorsionFree _ coe_smul + coe_injective.moduleIsTorsionFree _ FunLike.coe_smul variable [AddCommMonoid M₃] [Module S M₃] [Module R M₃] [SMulCommClass R S M₃] @@ -1273,7 +1273,7 @@ theorem mkPiRing_eq_iff [Fintype ι] {z₁ z₂ : M₂} : · simp [h] theorem mkPiRing_zero [Fintype ι] : MultilinearMap.mkPiRing R ι (0 : M₂) = 0 := by - ext; rw [mkPiRing_apply, smul_zero, MultilinearMap.zero_apply] + ext; rw [mkPiRing_apply, smul_zero, zero_apply] theorem mkPiRing_eq_zero_iff [Fintype ι] (z : M₂) : MultilinearMap.mkPiRing R ι z = 0 ↔ z = 0 := by rw [← mkPiRing_zero, mkPiRing_eq_iff] @@ -1288,9 +1288,10 @@ variable [Semiring R] [∀ i, AddCommMonoid (M₁ i)] [AddCommGroup M₂] [∀ i instance : Neg (MultilinearMap R M₁ M₂) := ⟨fun f => ⟨fun m => -f m, fun m i x y => by simp [add_comm], fun m i c x => by simp⟩⟩ -@[simp] -theorem neg_apply (m : ∀ i, M₁ i) : (-f) m = -f m := - rfl +instance : IsNegApply (MultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + neg_apply _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias neg_apply := neg_apply instance : Sub (MultilinearMap R M₁ M₂) := ⟨fun f g => @@ -1299,13 +1300,12 @@ instance : Sub (MultilinearMap R M₁ M₂) := abel, fun m i c x => by simp only [MultilinearMap.map_update_smul, smul_sub]⟩⟩ -@[simp] -theorem sub_apply (m : ∀ i, M₁ i) : (f - g) m = f m - g m := - rfl +instance : IsSubApply (MultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + sub_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias sub_apply := sub_apply -instance : AddCommGroup (MultilinearMap R M₁ M₂) := fast_instance% - coe_injective.addCommGroup _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) +instance : AddCommGroup (MultilinearMap R M₁ M₂) := fast_instance% FunLike.addCommGroup end RangeAddCommGroup diff --git a/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean b/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean index 8b913425fb324e..f3782786f24566 100644 --- a/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean +++ b/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean @@ -184,7 +184,7 @@ lemma cartanMatrix_mul_diagonal_eq [Fintype ι] [DecidableEq ι] [P.IsRootSystem (2 : ℤ) • (P.posRootForm ℤ).posForm.toMatrix b.toWeightBasisInt := by ext i j apply algebraMap_injective ℤ R - simp only [mul_diagonal, map_mul, algebraMap_rootFormIn, posRootForm_eq, smul_apply, + simp only [mul_diagonal, map_mul, algebraMap_rootFormIn, posRootForm_eq, Matrix.smul_apply, LinearMap.BilinForm.toMatrix_apply, Int.zsmul_eq_mul] simpa [← algebraMap_pairingIn P ℤ i j] using congr_fun₂ (cartanMatrixIn_mul_diagonal_eq ℤ P.toInvariantForm b) i j diff --git a/Mathlib/LinearAlgebra/TensorPower/Pairing.lean b/Mathlib/LinearAlgebra/TensorPower/Pairing.lean index 18816895d34cee..891b9cc7a678ba 100644 --- a/Mathlib/LinearAlgebra/TensorPower/Pairing.lean +++ b/Mathlib/LinearAlgebra/TensorPower/Pairing.lean @@ -43,15 +43,10 @@ noncomputable def multilinearMapToDual : (MultilinearMap.compLinearMap (MultilinearMap.mkPiRing R (Fin n) 1) f) map_update_add' := fun f i φ₁ φ₂ ↦ by ext v - dsimp - simp only [lift.tprod, MultilinearMap.compLinearMap_apply, this, - LinearMap.add_apply, MultilinearMap.map_update_add] + simp [this] map_update_smul' := fun f i a φ ↦ by ext v - dsimp - simp only [lift.tprod, MultilinearMap.compLinearMap_apply, this, - LinearMap.smul_apply, MultilinearMap.map_update_smul] - dsimp } + simp [this, Finset.prod_update_of_mem, Semigroup.mul_assoc] } variable {R M n} in @[simp] diff --git a/Mathlib/RingTheory/MatrixPolynomialAlgebra.lean b/Mathlib/RingTheory/MatrixPolynomialAlgebra.lean index 23c09d35b90c41..49eab5fdaf1b32 100644 --- a/Mathlib/RingTheory/MatrixPolynomialAlgebra.lean +++ b/Mathlib/RingTheory/MatrixPolynomialAlgebra.lean @@ -87,7 +87,7 @@ theorem matPolyEquiv_coeff_apply_aux_2 (i j : n) (p : R[X]) (k : ℕ) : refine Polynomial.induction_on' p ?_ ?_ · intro p q hp hq ext - simp [hp, hq, coeff_add, add_apply, single_add] + simp [hp, hq, coeff_add, Matrix.add_apply, single_add] · intro k x simp only [matPolyEquiv_coeff_apply_aux_1, coeff_monomial] split_ifs <;> @@ -118,8 +118,9 @@ theorem matPolyEquiv_symm_apply_coeff (p : (Matrix n n R)[X]) (i j : n) (k : ℕ theorem matPolyEquiv_smul_one (p : R[X]) : matPolyEquiv (p • (1 : Matrix n n R[X])) = p.map (algebraMap R (Matrix n n R)) := by ext m i j - simp only [matPolyEquiv_coeff_apply, smul_apply, one_apply, smul_eq_mul, mul_ite, mul_one, - mul_zero, coeff_map, algebraMap_matrix_apply, Algebra.algebraMap_self, RingHom.id_apply] + simp only [matPolyEquiv_coeff_apply, Matrix.smul_apply, Matrix.one_apply, smul_eq_mul, mul_ite, + mul_one, mul_zero, coeff_map, algebraMap_matrix_apply, Algebra.algebraMap_self, + RingHom.id_apply] split_ifs <;> simp @[simp] @@ -153,7 +154,7 @@ theorem support_subset_support_matPolyEquiv (m : Matrix n n R[X]) (i j : n) : contrapose simp only [notMem_support_iff] intro hk - rw [← matPolyEquiv_coeff_apply, hk, zero_apply] + rw [← matPolyEquiv_coeff_apply, hk, Matrix.zero_apply] theorem eval_det {R : Type*} [CommRing R] (M : Matrix n n R[X]) (r : R) : Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det := by diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 41ce2bf1b54d93..fa191bb3509d09 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -648,7 +648,7 @@ private theorem projective_units_and_mul'_comp_lTensor_bijective (I : (Submodule exact LinearEquiv.ofInjective_symm_apply .. let g : (S → R) →ₗ[R] I := .lsum _ _ ℕ fun i ↦ .toSpanSingleton _ _ ⟨b i, hT' <| hb i⟩ have hgf : g ∘ₗ f = .id := LinearMap.ext fun x ↦ Subtype.ext <| by - simp only [g, lsum_apply, comp_apply, sum_apply, toSpanSingleton_apply, proj_apply] + simp only [g, lsum_apply, comp_apply, LinearMap.sum_apply, toSpanSingleton_apply, proj_apply] simp_rw [coe_sum, coe_smul, Algebra.smul_def, hf, mul_assoc, ← Finset.mul_sum, Algebra.smul_mul_assoc, eq, (Finset.sum_coe_sort ..).trans hr.2, mul_one, id_apply] set m := mul' R A ∘ₗ I.1.subtype.lTensor A From 800238935b9c4b495da5771a0dac0db5549b26ab Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:34:47 +0000 Subject: [PATCH 0093/1300] feat(Analysis): use `IsApply` for `ContDiffMapSupportedIn` (#40607) --- .../Distribution/ContDiffMapSupportedIn.lean | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean b/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean index d46a03d077e0d9..d3a90374eea707 100644 --- a/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean +++ b/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean @@ -195,63 +195,70 @@ theorem coe_toBoundedContinuousFunction (f : 𝓓^{n}_{K}(E, F)) : section AddCommGroup -@[simps -fullyApplied] instance : Zero 𝓓^{n}_{K}(E, F) where zero := .mk 0 contDiff_zero_fun fun _ _ ↦ rfl -@[simps -fullyApplied] +instance : IsZeroApply 𝓓^{n}_{K}(E, F) E F where + zero_apply _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_zero := FunLike.coe_zero + instance : Add 𝓓^{n}_{K}(E, F) where add f g := .mk (f + g) (f.contDiff.add g.contDiff) <| by rw [← add_zero 0] exact f.zero_on_compl.comp_left₂ g.zero_on_compl -@[simps -fullyApplied] +instance : IsAddApply 𝓓^{n}_{K}(E, F) E F where + add_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_add := FunLike.coe_add + instance : Neg 𝓓^{n}_{K}(E, F) where neg f := .mk (-f) (f.contDiff.neg) <| by rw [← neg_zero] exact f.zero_on_compl.comp_left -@[simps -fullyApplied] +instance : IsNegApply 𝓓^{n}_{K}(E, F) E F where + neg_apply _ _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_neg := FunLike.coe_neg + instance instSub : Sub 𝓓^{n}_{K}(E, F) where sub f g := .mk (f - g) (f.contDiff.sub g.contDiff) <| by rw [← sub_zero 0] exact f.zero_on_compl.comp_left₂ g.zero_on_compl -@[simps -fullyApplied] +instance : IsSubApply 𝓓^{n}_{K}(E, F) E F where + sub_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-15")] alias coe_sub := FunLike.coe_sub + instance instSMul {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : SMul R 𝓓^{n}_{K}(E, F) where smul c f := .mk (c • (f : E → F)) (f.contDiff.const_smul c) <| by rw [← smul_zero c] exact f.zero_on_compl.comp_left -instance : AddCommGroup 𝓓^{n}_{K}(E, F) := fast_instance% - DFunLike.coe_injective.addCommGroup _ rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ _ ↦ rfl) fun _ _ ↦ rfl +instance {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : + IsSMulApply R 𝓓^{n}_{K}(E, F) E F where + smul_apply _ _ _ := rfl -variable (E F K n) +@[deprecated (since := "2026-06-15")] alias coe_smul := FunLike.coe_smul -/-- Coercion as an additive homomorphism. -/ -def coeHom : 𝓓^{n}_{K}(E, F) →+ E → F where - toFun f := f - map_zero' := coe_zero - map_add' _ _ := rfl +instance : AddCommGroup 𝓓^{n}_{K}(E, F) := fast_instance% FunLike.addCommGroup -variable {E F} +@[deprecated (since := "2026-06-15")] alias coeHom := FunLike.coeAddMonoidHom -theorem coe_coeHom : (coeHom E F n K : 𝓓^{n}_{K}(E, F) → E → F) = DFunLike.coe := - rfl +@[deprecated (since := "2026-06-15")] alias coe_coeHom := FunLike.coe_coeAddMonoidHom -theorem coeHom_injective : Function.Injective (coeHom E F n K) := by - rw [coe_coeHom] - exact DFunLike.coe_injective +@[deprecated (since := "2026-06-15")] alias coeHom_injective := FunLike.coeAddMonoidHom_injective end AddCommGroup section Module instance {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : - Module R 𝓓^{n}_{K}(E, F) := fast_instance% - (coeHom_injective n K).module R (coeHom E F n K) fun _ _ ↦ rfl + Module R 𝓓^{n}_{K}(E, F) := fast_instance% FunLike.module end Module @@ -384,13 +391,14 @@ noncomputable def fderivLM : · have hk' : 0 < (n : ℕ∞ω) := mod_cast (add_pos_of_right zero_lt_one k).trans_le hk ext simp [fderiv_add (f.contDiff.differentiable hk'.ne').differentiableAt - (g.contDiff.differentiable hk'.ne').differentiableAt] + (g.contDiff.differentiable hk'.ne').differentiableAt, FunLike.coe_add] · simp map_smul' c f := by split_ifs with hk · have hk' : 0 < (n : ℕ∞ω) := mod_cast (add_pos_of_right zero_lt_one k).trans_le hk ext - simp [fderiv_const_smul (f.contDiff.differentiable hk'.ne').differentiableAt] + simp [fderiv_const_smul (f.contDiff.differentiable hk'.ne').differentiableAt, + FunLike.coe_smul] · simp @[simp] @@ -440,13 +448,13 @@ noncomputable def iteratedFDerivLM (i : ℕ) : split_ifs with hi · have hi' : (i : ℕ∞ω) ≤ n := mod_cast (le_of_add_le_right hi) ext - simp [iteratedFDeriv_add (f.contDiff.of_le hi') (g.contDiff.of_le hi')] + simp [iteratedFDeriv_add (f.contDiff.of_le hi') (g.contDiff.of_le hi'), FunLike.coe_add] · simp map_smul' c f := by split_ifs with hi · have hi' : (i : ℕ∞ω) ≤ n := mod_cast (le_of_add_le_right hi) ext - simp [iteratedFDeriv_const_smul_apply (f.contDiff.of_le hi').contDiffAt] + simp [iteratedFDeriv_const_smul_apply (f.contDiff.of_le hi').contDiffAt, FunLike.coe_smul] · simp @[simp] @@ -919,12 +927,12 @@ noncomputable def integralAgainstBilinLM (B : F₁ →L[𝕜] F₂ →L[𝕜] F if IntegrableOn φ K μ then ∫ x, B (f x) (φ x) ∂μ else 0 map_add' f g := by split_ifs with hφ - · simp_rw [coe_add, Pi.add_apply, map_add, add_apply, + · simp_rw [add_apply, map_add, add_apply, integral_add (f.integrable_bilin B hφ) (g.integrable_bilin B hφ)] · simp map_smul' c f := by split_ifs with hφ - · simp_rw [coe_smul, Pi.smul_apply, map_smul, smul_apply, integral_smul c, RingHom.id_apply] + · simp_rw [smul_apply, map_smul, smul_apply, integral_smul c, RingHom.id_apply] · simp @[simp] From c5752439da3c6b206cce0b7f8798a02609bc3614 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 17 Jun 2026 02:55:50 +0000 Subject: [PATCH 0094/1300] chore(MeasureTheory/Measure/NullMeasurable): remove some defEq abuse (#40647) Co-authored-by: Batixx --- .../MeasureTheory/Measure/NullMeasurable.lean | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean index a837c37899a151..3f645566c47cc3 100644 --- a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean @@ -97,6 +97,10 @@ def NullMeasurableSet [MeasurableSpace α] (s : Set α) theorem _root_.MeasurableSet.nullMeasurableSet (h : MeasurableSet s) : NullMeasurableSet s μ := h.eventuallyMeasurableSet +theorem _root_.MeasureTheory.nullMeasurableSet_iff_eventuallyMeasurableSet (s : Set α) : + NullMeasurableSet s μ ↔ EventuallyMeasurableSet m0 (ae μ) s := + Iff.rfl + theorem nullMeasurableSet_empty : NullMeasurableSet ∅ μ := MeasurableSet.empty @@ -122,9 +126,9 @@ theorem compl_iff : NullMeasurableSet sᶜ μ ↔ NullMeasurableSet s μ := theorem of_subsingleton [Subsingleton α] : NullMeasurableSet s μ := Subsingleton.measurableSet -set_option backward.isDefEq.respectTransparency false in -protected theorem congr (hs : NullMeasurableSet s μ) (h : s =ᵐ[μ] t) : NullMeasurableSet t μ := - EventuallyMeasurableSet.congr hs h.symm +protected theorem congr (hs : NullMeasurableSet s μ) (h : s =ᵐ[μ] t) : NullMeasurableSet t μ := by + rw [nullMeasurableSet_iff_eventuallyMeasurableSet] + exact EventuallyMeasurableSet.congr hs h.symm @[measurability] protected theorem iUnion {ι : Sort*} [Countable ι] {s : ι → Set α} @@ -379,7 +383,7 @@ end section NullMeasurable -variable [MeasurableSpace α] [MeasurableSpace β] [MeasurableSpace γ] {f : α → β} {μ : Measure α} +variable [m : MeasurableSpace α] [MeasurableSpace β] [MeasurableSpace γ] {f : α → β} {μ : Measure α} /-- A function `f : α → β` is null measurable if the preimage of a measurable set is a null measurable set. @@ -389,6 +393,9 @@ the σ-algebra on the codomain is countably generated, but stronger in general. def NullMeasurable (f : α → β) (μ : Measure α := by volume_tac) : Prop := ∀ ⦃s : Set β⦄, MeasurableSet s → NullMeasurableSet (f ⁻¹' s) μ +theorem _root_.MeasureTheory.nullMeasurable_iff_eventuallyMeasurable (f : α → β) : + NullMeasurable f μ ↔ EventuallyMeasurable m (ae μ) f := by rfl + protected theorem _root_.Measurable.nullMeasurable (h : Measurable f) : NullMeasurable f μ := h.eventuallyMeasurable @@ -396,15 +403,15 @@ protected theorem NullMeasurable.measurable' (h : NullMeasurable f μ) : @Measurable (NullMeasurableSpace α μ) β _ _ f := h -set_option backward.isDefEq.respectTransparency false in theorem Measurable.comp_nullMeasurable {g : β → γ} (hg : Measurable g) (hf : NullMeasurable f μ) : - NullMeasurable (g ∘ f) μ := - hg.comp_eventuallyMeasurable hf + NullMeasurable (g ∘ f) μ := by + rw [nullMeasurable_iff_eventuallyMeasurable] + exact hg.comp_eventuallyMeasurable hf -set_option backward.isDefEq.respectTransparency false in theorem NullMeasurable.congr {g : α → β} (hf : NullMeasurable f μ) (hg : f =ᵐ[μ] g) : - NullMeasurable g μ := - EventuallyMeasurable.congr hf hg.symm + NullMeasurable g μ := by + rw [nullMeasurable_iff_eventuallyMeasurable] + exact EventuallyMeasurable.congr hf hg.symm end NullMeasurable From 6a6c957ae0220fbd3e6313d9116a2cbd46bab879 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 17 Jun 2026 04:02:27 +0000 Subject: [PATCH 0095/1300] feat: integral presentation of the proximity function of value distribution theory (#38500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If `f : ℂ → ℂ` is meromorphic, establish a presentation of the proximity function `proximity f ⊤` as iterated circle averages. This statement can be used to compare the proximity- and logarithmic counting functions, and is one of the key ingredients in the proof of Cartan's classic formula for the characteristic function. This is the first section of a multi-part PR, establishing Cartan's formula. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 1 + .../Proximity/IntegralPresentation.lean | 201 ++++++++++++++++++ Mathlib/Analysis/Meromorphic/Basic.lean | 2 +- .../MeasureTheory/Integral/Bochner/Basic.lean | 14 ++ Mathlib/MeasureTheory/Integral/Prod.lean | 9 + 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Analysis/Complex/ValueDistribution/Proximity/IntegralPresentation.lean diff --git a/Mathlib.lean b/Mathlib.lean index c91c39aba616da..5be51fc0034ca1 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1912,6 +1912,7 @@ public import Mathlib.Analysis.Complex.ValueDistribution.FirstMainTheorem public import Mathlib.Analysis.Complex.ValueDistribution.LogCounting.Asymptotic public import Mathlib.Analysis.Complex.ValueDistribution.LogCounting.Basic public import Mathlib.Analysis.Complex.ValueDistribution.Proximity.Basic +public import Mathlib.Analysis.Complex.ValueDistribution.Proximity.IntegralPresentation public import Mathlib.Analysis.ConstantSpeed public import Mathlib.Analysis.Convex.AmpleSet public import Mathlib.Analysis.Convex.Approximation diff --git a/Mathlib/Analysis/Complex/ValueDistribution/Proximity/IntegralPresentation.lean b/Mathlib/Analysis/Complex/ValueDistribution/Proximity/IntegralPresentation.lean new file mode 100644 index 00000000000000..4652faec23121d --- /dev/null +++ b/Mathlib/Analysis/Complex/ValueDistribution/Proximity/IntegralPresentation.lean @@ -0,0 +1,201 @@ +/- +Copyright (c) 2026 Stefan Kebekus. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Matteo Cipollina, Stefan Kebekus +-/ + +module + +public import Mathlib.Analysis.Complex.ValueDistribution.Proximity.Basic +public import Mathlib.Analysis.SpecialFunctions.Integrals.PosLogEqCircleAverage + +/-! +# Integral Presentation of the Proximity Function + +If `f : ℂ → ℂ` is meromorphic, this file establishes a presentation of the proximity function +`proximity f ⊤` as iterated circle averages. This statement can be used to compare the proximity- +and logarithmic counting functions, and is one of the key ingredients in the proof of Cartan's +classic formula for the characteristic function. + +See Section VI.2 of [Lang, *Introduction to Complex Hyperbolic Spaces*][MR886677] for a detailed +discussion. +-/ + +public section + +open Filter MeasureTheory Real Set + +namespace ValueDistribution + +variable {f : ℂ → ℂ} {R : ℝ} + +namespace Cartan + +/-! +### Integrability of the Cartan Kernel + +The proof of the integral presentation of the proximity function relies on an extended computation, +applying Fubini's theorem to the Cartan kernel of integration. This section defines the kernel and +establishes its integrability, as a function of two variables. +-/ + +/-- +Given `f : ℂ → ℂ` and `R : ℝ`, define the Cartan kernel of integration as the function +`α β ↦ log ‖f (circleMap 0 R β) - circleMap 0 1 α‖`. +-/ +noncomputable def cartanKernel (f : ℂ → ℂ) (R : ℝ) (α β : ℝ) : ℝ := + log ‖f (circleMap 0 R β) - circleMap 0 1 α‖ + +/-- +For every function `f : ℂ → ℂ`, the Cartan kernel of integration `cartanKernel f R α β` is +integrable as a function in `α`. +-/ +lemma integrableOn_cartanKernel_left (f : ℂ → ℂ) (R : ℝ) (β : ℝ) : + IntegrableOn (cartanKernel f R · β) (Ioc 0 (2 * π)) := by + apply (intervalIntegrable_iff_integrableOn_Ioc_of_le two_pi_pos.le).1 + simpa [cartanKernel, norm_sub_rev, CircleIntegrable] using circleIntegrable_log_norm_sub_const 1 + +/-- +If `f : ℂ → ℂ` is measurable, then the Cartan kernel of integration is measurable as a function in +the two variables `α` and `β`. +-/ +@[fun_prop] +theorem measurable_cartanKernel (hf : Measurable f) : + Measurable (fun p : ℝ × ℝ ↦ cartanKernel f R p.1 p.2) := by + unfold cartanKernel; fun_prop + +/- Formula for the `L¹` norm of an angular slice of the Cartan kernel. -/ +private lemma integral_norm_cartanKernel_eq (f : ℂ → ℂ) (R β : ℝ) : + ∫ α in Ioc 0 (2 * π), ‖cartanKernel f R α β‖ = + 2 * (∫ α, (cartanKernel f R α β)⁺ ∂(volume.restrict (Ioc 0 (2 * π)))) - + (2 * π) * log⁺ ‖f (circleMap 0 R β)‖ := by + let μ : Measure ℝ := volume.restrict (Ioc 0 (2 * π)) + calc ∫ α, ‖cartanKernel f R α β‖ ∂μ + _ = 2 * (∫ α, (cartanKernel f R α β)⁺ ∂μ) - ∫ α, cartanKernel f R α β ∂μ := + integral_abs_eq_two_mul_integral_posPart_sub_integral (integrableOn_cartanKernel_left f R β) + _ = 2 * (∫ α, (cartanKernel f R α β)⁺ ∂μ) - 2 * π * log⁺ ‖f (circleMap 0 R β)‖ := by + congr + set z := f (circleMap 0 R β) + suffices h_avg : circleAverage (log ‖z - ·‖) 0 1 = log⁺ ‖z‖ by + convert congr(2 * π * $h_avg) + simp [circleAverage_def, field, cartanKernel, intervalIntegral.integral_of_le two_pi_pos.le] + simp [norm_sub_rev] + +/- +If `f : ℂ → ℂ` is meromorphic,, then the `L¹` norms of the angular slices of the Cartan kernel form +an integrable family. +-/ +lemma integrable_integral_norm_cartanKernel (h : Meromorphic f) : + Integrable (∫ α, ‖cartanKernel f R α ·‖ ∂(volume.restrict (Ioc 0 (2 * π)))) + (volume.restrict (Ioc 0 (2 * π))) := by + let μ : Measure ℝ := volume.restrict (Ioc 0 (2 * π)) + have h_meas_K : Measurable (fun a : ℝ × ℝ ↦ (cartanKernel f R a.1 a.2)⁺) := by fun_prop + have h_int_posLog : Integrable (fun β ↦ log⁺ ‖f (circleMap 0 R β)‖) μ := by + have : CircleIntegrable (log⁺ ‖f ·‖) 0 R := h.meromorphicOn.circleIntegrable_posLog_norm + rwa [CircleIntegrable, intervalIntegrable_iff_integrableOn_Ioc_of_le two_pi_pos.le] at this + have h_int_Bound : Integrable (fun β ↦ log⁺ ‖f (circleMap 0 R β)‖ + log 2) μ := + h_int_posLog.add (integrable_const _) + have h_int_Term1 : Integrable (fun β ↦ ∫ α, (cartanKernel f R α β)⁺ ∂μ) μ := by + apply Integrable.mono (h_int_Bound.const_mul (2 * π)) + h_meas_K.stronglyMeasurable.integral_prod_left'.aestronglyMeasurable + filter_upwards with β + have h_int_nonneg : 0 ≤ ∫ α, (cartanKernel f R α β)⁺ ∂μ := by positivity + have h_bound_nonneg : 0 ≤ (2 * π) * (log⁺ ‖f (circleMap 0 R β)‖ + log 2) := by + positivity [posLog_nonneg (x := ‖f (circleMap 0 R β)‖)] + rw [norm_of_nonneg h_int_nonneg, norm_of_nonneg h_bound_nonneg] + have : ∫ α, (cartanKernel f R α β)⁺ ∂(volume.restrict (Ioc 0 (2 * π))) ≤ + ∫ _, log⁺ ‖f (circleMap 0 R β)‖ + log 2 ∂(volume.restrict (Ioc 0 (2 * π))) := by + refine integral_mono_of_nonneg (.of_forall (by simp [posPart])) (integrable_const _) + (.of_forall ?_) + intro α + calc (cartanKernel f R α β)⁺ + _ = log⁺ ‖f (circleMap 0 R β) + (-circleMap 0 1 α)‖ := by + simp [cartanKernel, posLog_def, posPart, max_comm, sub_eq_add_neg] + _ ≤ log⁺ ‖f (circleMap 0 R β)‖ + log⁺ ‖-circleMap 0 1 α‖ + log 2 := + posLog_norm_add_le (f (circleMap 0 R β)) (-circleMap 0 1 α) + _ = log⁺ ‖f (circleMap 0 R β)‖ + log 2 := by + simp [norm_circleMap_zero, add_comm] + rwa [integral_const, smul_eq_mul, mul_comm, measureReal_restrict_apply_univ, + mul_comm, volume_real_Ioc_of_le two_pi_pos.le, sub_zero] at this + exact Integrable.congr ((h_int_Term1.const_mul 2).sub (h_int_posLog.const_mul (2 * π))) + (Eventually.of_forall fun β ↦ (integral_norm_cartanKernel_eq f R β).symm) + +/-- +If `f : ℂ → ℂ` is meromorphic, then the Cartan kernel of integration is integrable as a function in +the two variables `α` and `β`. +-/ +theorem integrableOn_cartanKernel (h : Meromorphic f) : + IntegrableOn (fun p ↦ cartanKernel f R p.1 p.2) (uIoc 0 (2 * π) ×ˢ uIoc 0 (2 * π)) := by + rw [IntegrableOn, Measure.volume_eq_prod, ← Measure.prod_restrict] + have := h.measurable + simpa [uIoc_of_le two_pi_pos.le] using (integrable_prod_iff' (by fun_prop)).2 + ⟨Eventually.of_forall (integrableOn_cartanKernel_left f R), + integrable_integral_norm_cartanKernel h⟩ + +/-- +Corollary of `integrableOn_cartanKernel`: If `f : ℂ → ℂ` is meromorphic, then the function +`β ↦ ∫ α in 0..2 * π, Cartan.cartanKernel f R α β` is integrable. +-/ +lemma integrableOn_intervalIntegral_cartanKernel_left (h : Meromorphic f) : + IntegrableOn (∫ α in 0..2 * π, Cartan.cartanKernel f R α ·) (Ioc 0 (2 * π)) := by + have h_int := Cartan.integrableOn_cartanKernel (R := R) h + rw [uIoc_of_le two_pi_pos.le, IntegrableOn, Measure.volume_eq_prod, ← Measure.prod_restrict] + at h_int + simpa [IntegrableOn, intervalIntegral.integral_of_le two_pi_pos.le, Cartan.cartanKernel] + using h_int.integral_prod_right + +/-- +Corollary of `integrableOn_cartanKernel`: If `f : ℂ → ℂ` is meromorphic, then the function +`α ↦ ∫ β in 0..2 * π, Cartan.cartanKernel f R α β` is integrable. +-/ +lemma integrableOn_intervalIntegral_cartanKernel_right (h : Meromorphic f) : + IntegrableOn (∫ β in 0..2 * π, Cartan.cartanKernel f R · β) (Ioc 0 (2 * π)) := by + have h_int := Cartan.integrableOn_cartanKernel (R := R) h + rw [uIoc_of_le two_pi_pos.le, IntegrableOn, Measure.volume_eq_prod, ← Measure.prod_restrict] + at h_int + simpa [IntegrableOn, intervalIntegral.integral_of_le two_pi_pos.le, Cartan.cartanKernel] + using h_int.integral_prod_left + +end Cartan + +/-- +Presentation of the proximity function as iterated circle averages. +-/ +theorem circleAverage_circleAverage_eq_proximity_top (h : Meromorphic f) : + (fun R ↦ circleAverage (fun a ↦ circleAverage (log ‖f · - a‖) 0 R) 0 1) = proximity f ⊤ := by + ext R + let F : ℝ → ℝ → ℝ := Cartan.cartanKernel f R + calc circleAverage (fun a ↦ circleAverage (log ‖f · - a‖) 0 R) 0 1 + _ = (2 * π)⁻¹ * (2 * π)⁻¹ * ∫ α in 0..2 * π, ∫ β in 0..2 * π, F α β := by + simp [circleAverage, F, Cartan.cartanKernel, mul_assoc] + _ = (2 * π)⁻¹ * (2 * π)⁻¹ * ∫ β in 0..2 * π, ∫ α in 0..2 * π, F α β := by + rw [MeasureTheory.intervalIntegral_intervalIntegral_swap] + exact Cartan.integrableOn_cartanKernel h + _ = (2 * π)⁻¹ * ∫ β in 0..2 * π, ((2 * π)⁻¹ * ∫ α in 0..2 * π, F α β) := by + simp [mul_comm, mul_left_comm, mul_assoc] + _ = (2 * π)⁻¹ * ∫ β in 0..2 * π, log⁺ ‖f (circleMap 0 R β)‖ := by + congr 1 + apply intervalIntegral.integral_congr + intro β hβ + calc (2 * π)⁻¹ * ∫ α in 0..2 * π, F α β + _ = circleAverage (log ‖f (circleMap 0 R β) - ·‖) 0 1 := by + simp [F, circleAverage, Cartan.cartanKernel] + _ = log⁺ ‖f (circleMap 0 R β)‖ := by + simp [norm_sub_rev] + _ = circleAverage (log⁺ ‖f ·‖) 0 R := by + simp [circleAverage, intervalIntegral.integral_of_le two_pi_pos.le] + +/-- +Complementary statement to `proximity_top_eq_circleAverage_circleAverage`, providing circle +integrability of the integrand. +-/ +theorem circleIntegrable_circleAverage_log_norm_sub (h : Meromorphic f) : + CircleIntegrable (fun a ↦ circleAverage (log ‖f · - a‖) 0 R) 0 1 := by + by_cases hR : R = 0 + · simp [hR, circleAverage_zero, norm_sub_rev, circleIntegrable_log_norm_sub_const] + rw [CircleIntegrable, intervalIntegrable_iff_integrableOn_Ioc_of_le two_pi_pos.le] + apply IntegrableOn.congr_fun + ((Cartan.integrableOn_intervalIntegral_cartanKernel_right (R := R) h).const_mul (2 * π)⁻¹) + (fun _ _ ↦ by simp [circleAverage, Cartan.cartanKernel]) measurableSet_Ioc + +end ValueDistribution diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 3b6f6547e631b9..1d4d2a28f600dd 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -759,7 +759,7 @@ theorem countable_compl_analyticAt [SecondCountableTopology 𝕜] [CompleteSpace /-- Meromorphic functions are measurable. -/ -theorem measurable [MeasurableSpace 𝕜] [SecondCountableTopology 𝕜] [BorelSpace 𝕜] +@[fun_prop] theorem measurable [MeasurableSpace 𝕜] [SecondCountableTopology 𝕜] [BorelSpace 𝕜] [MeasurableSpace E] [CompleteSpace E] [BorelSpace E] (h : Meromorphic f) : Measurable f := by set s := {z : 𝕜 | AnalyticAt 𝕜 f z} diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index 9a0109eccba0c6..e726c0325904e3 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -566,6 +566,20 @@ theorem integral_eq_integral_pos_part_sub_integral_neg_part {f : α → ℝ} (hf · simp · exact hf.neg.real_toNNReal +theorem integral_abs_eq_two_mul_integral_posPart_sub_integral {f : α → ℝ} (hf : Integrable f μ) : + ∫ x, |f x| ∂μ = 2 * ∫ x, (f x)⁺ ∂μ - ∫ x, f x ∂μ := by + simp only [PosPart.posPart] + have h_eq : ∀ x, |f x| = 2 * max (f x) 0 - f x := by grind + rw [integral_congr_ae (Eventually.of_forall h_eq), integral_sub (by fun_prop) hf, + integral_const_mul] + +theorem integral_abs_eq_two_mul_integral_negPart_add_integral {f : α → ℝ} (hf : Integrable f μ) : + ∫ x, |f x| ∂μ = 2 * ∫ x, (f x)⁻ ∂μ + ∫ x, f x ∂μ := by + simp only [NegPart.negPart] + have h_eq : ∀ x, |f x| = 2 * max (-f x) 0 + f x := by grind + rw [integral_congr_ae (Eventually.of_forall h_eq), integral_add (by fun_prop) hf, + integral_const_mul] + end Basic section Order diff --git a/Mathlib/MeasureTheory/Integral/Prod.lean b/Mathlib/MeasureTheory/Integral/Prod.lean index de59485ec6289f..6dd14fda021671 100644 --- a/Mathlib/MeasureTheory/Integral/Prod.lean +++ b/Mathlib/MeasureTheory/Integral/Prod.lean @@ -544,6 +544,15 @@ lemma intervalIntegral_integral_swap {a b : ℝ} {f : ℝ → α → E} simp only [hab, Set.uIoc_of_ge] at h_int rw [integral_integral_swap h_int, integral_neg] +/-- Change the order of integration for interval integrals. -/ +lemma intervalIntegral_intervalIntegral_swap {F : ℝ → ℝ → E} {a b c d : ℝ} + (h : IntegrableOn F.uncurry (uIoc a b ×ˢ uIoc c d)) : + ∫ x in a..b, ∫ y in c..d, F x y = ∫ y in c..d, ∫ x in a..b, F x y := by + rw [intervalIntegral.intervalIntegral_eq_integral_uIoc, ← intervalIntegral_integral_swap, + ← intervalIntegral.integral_smul] + · simp_rw [intervalIntegral.intervalIntegral_eq_integral_uIoc] + · rwa [← integrable_swap_iff, Measure.prod_restrict, ← Measure.volume_eq_prod, ← IntegrableOn] + /-- **Fubini's Theorem** for set integrals. -/ theorem setIntegral_prod (f : α × β → E) {s : Set α} {t : Set β} (hf : IntegrableOn f (s ×ˢ t) (μ.prod ν)) : From 5d1abc4cd8c71e2a463fb58d0e406decab077bdd Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 04:19:44 +0000 Subject: [PATCH 0096/1300] chore(LinearAlgebra/Matrix/Hermitian): `star A = A` from Hermitian `A` shortcut (#40686) Co-authored-by: ScottWe <4276716+ScottWe@users.noreply.github.com> Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/LinearAlgebra/Matrix/Hermitian.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/LinearAlgebra/Matrix/Hermitian.lean b/Mathlib/LinearAlgebra/Matrix/Hermitian.lean index bfc5286afe2018..f47d0fc51adc7c 100644 --- a/Mathlib/LinearAlgebra/Matrix/Hermitian.lean +++ b/Mathlib/LinearAlgebra/Matrix/Hermitian.lean @@ -54,6 +54,8 @@ theorem isHermitian_iff_isSelfAdjoint {A : Matrix n n α} : protected alias ⟨IsHermitian.isSelfAdjoint, _root_.IsSelfAdjoint.isHermitian⟩ := isHermitian_iff_isSelfAdjoint +theorem IsHermitian.star_eq (hA : A.IsHermitian) : star A = A := hA.isSelfAdjoint.star_eq + theorem IsHermitian.ext {A : Matrix n n α} : (∀ i j, star (A j i) = A i j) → A.IsHermitian := by intro h; ext i j; exact h i j From 4971f8ebe8c184103f1c267f371377194e460249 Mon Sep 17 00:00:00 2001 From: Adam Kiezun Date: Wed, 17 Jun 2026 06:03:31 +0000 Subject: [PATCH 0097/1300] feat(NumberTheory): add almost prime numbers (#39903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `Nat.IsAlmostPrime k n` for natural numbers with exactly `k` prime factors counted with multiplicity, plus `Nat.IsAtMostAlmostPrime` and `Nat.IsSemiprime`. The definitions reuse the existing arithmetic function `Ω`, and the initial API proves the basic zero/one cases, prime examples, and closure under multiplication. --- Mathlib.lean | 1 + Mathlib/NumberTheory/AlmostPrime.lean | 90 +++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 Mathlib/NumberTheory/AlmostPrime.lean diff --git a/Mathlib.lean b/Mathlib.lean index 5be51fc0034ca1..610df212f17b02 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5650,6 +5650,7 @@ public import Mathlib.ModelTheory.Types public import Mathlib.ModelTheory.Ultraproducts public import Mathlib.NumberTheory.ADEInequality public import Mathlib.NumberTheory.AbelSummation +public import Mathlib.NumberTheory.AlmostPrime public import Mathlib.NumberTheory.ArithmeticFunction.Carmichael public import Mathlib.NumberTheory.ArithmeticFunction.Defs public import Mathlib.NumberTheory.ArithmeticFunction.LFunction diff --git a/Mathlib/NumberTheory/AlmostPrime.lean b/Mathlib/NumberTheory/AlmostPrime.lean new file mode 100644 index 00000000000000..0d6e654eed48fb --- /dev/null +++ b/Mathlib/NumberTheory/AlmostPrime.lean @@ -0,0 +1,90 @@ +/- +Copyright (c) 2026 Adam Kiezun. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Adam Kiezun +-/ +module + +public import Mathlib.NumberTheory.ArithmeticFunction.Misc + +/-! +# Almost prime numbers + +This file defines `Nat.IsAlmostPrime k n`, the predicate that `n` has exactly `k` +prime factors counted with multiplicity. We also define `Nat.IsAtMostAlmostPrime`, +the corresponding predicate with at most `k` prime factors, and `Nat.IsSemiprime`, +the special case of `2`-almost-prime numbers. + +Both definitions use the arithmetic function `ArithmeticFunction.cardFactors`, written `Ω`. + +The terminology follows the standard definition of an +[almost prime](https://en.wikipedia.org/wiki/Almost_prime). + +## Main statements + +* `Nat.IsAlmostPrime.mul`: the product of a `k`-almost-prime number and an + `l`-almost-prime number is `(k + l)`-almost-prime. +* `Nat.IsAtMostAlmostPrime.mul`: the analogous statement for at most `k` prime factors. + +-/ + +@[expose] public section + +open scoped ArithmeticFunction.Omega + +namespace Nat + +/-- `IsAlmostPrime k n` means that `n` is `k`-almost prime: it has exactly `k` +prime factors, counted with multiplicity. The side condition excludes `0`, so `1` is +`0`-almost prime. -/ +def IsAlmostPrime (k n : ℕ) : Prop := + n ≠ 0 ∧ Ω n = k + +/-- `IsAtMostAlmostPrime k n` means that `n` has at most `k` prime factors, +counted with multiplicity. -/ +def IsAtMostAlmostPrime (k n : ℕ) : Prop := + n ≠ 0 ∧ Ω n ≤ k + +/-- A semiprime is a `2`-almost-prime number. -/ +abbrev IsSemiprime (n : ℕ) : Prop := + IsAlmostPrime 2 n + +variable {k l m n p q : ℕ} + +@[simp] +theorem isAlmostPrime_zero_iff : IsAlmostPrime 0 n ↔ n = 1 := by + rw [IsAlmostPrime, ArithmeticFunction.cardFactors_eq_zero_iff_eq_zero_or_one] + exact ⟨fun h ↦ h.2.resolve_left h.1, fun h ↦ by simp [h]⟩ + +@[simp] +theorem isAlmostPrime_one_iff : IsAlmostPrime 1 n ↔ n.Prime := by + constructor + · exact fun h ↦ ArithmeticFunction.cardFactors_eq_one_iff_prime.mp h.2 + · exact fun h ↦ ⟨h.ne_zero, ArithmeticFunction.cardFactors_eq_one_iff_prime.mpr h⟩ + +theorem Prime.isAlmostPrime_one (hp : p.Prime) : IsAlmostPrime 1 p := by + simpa using isAlmostPrime_one_iff.mpr hp + +theorem IsAlmostPrime.mul (hm : IsAlmostPrime k m) (hn : IsAlmostPrime l n) : + IsAlmostPrime (k + l) (m * n) := by + refine ⟨mul_ne_zero hm.1 hn.1, ?_⟩ + rw [ArithmeticFunction.cardFactors_mul hm.1 hn.1, hm.2, hn.2] + +theorem IsAtMostAlmostPrime.mul (hm : IsAtMostAlmostPrime k m) (hn : IsAtMostAlmostPrime l n) : + IsAtMostAlmostPrime (k + l) (m * n) := by + refine ⟨mul_ne_zero hm.1 hn.1, ?_⟩ + rw [ArithmeticFunction.cardFactors_mul hm.1 hn.1] + exact add_le_add hm.2 hn.2 + +theorem IsAlmostPrime.isAtMost (hn : IsAlmostPrime k n) (hkl : k ≤ l) : + IsAtMostAlmostPrime l n := + ⟨hn.1, hn.2 ▸ hkl⟩ + +theorem Prime.mul_isAlmostPrime_two (hp : p.Prime) (hq : q.Prime) : + IsAlmostPrime 2 (p * q) := by + simpa using hp.isAlmostPrime_one.mul hq.isAlmostPrime_one + +theorem Prime.sq_isAlmostPrime_two (hp : p.Prime) : IsAlmostPrime 2 (p ^ 2) := by + simpa [pow_two] using hp.mul_isAlmostPrime_two hp + +end Nat From 8390fffb841318b28e4305ae51a91febbba3f4b5 Mon Sep 17 00:00:00 2001 From: "M. Winter" <112132359+martinwintermath@users.noreply.github.com> Date: Wed, 17 Jun 2026 06:16:39 +0000 Subject: [PATCH 0098/1300] chore(LinearAlgebra/SesquilinearForm): deprecate `IsOrtho` and associated lemmas (#37381) Next steps in cleaning up bilinearity and orthogonality: - deprecate `IsOrtho` and accompanying trivial lemmas (this also allows to shorten the proofs in `orthogonalBilin`). - deprecate `ortho_smul_right` and `ortho_smul_left` since now provable from simp. - remove uses of deprecated definitions. - replace `IsOrtho` in undergrad.yaml by `iIsOrtho`. See discussion at [#mathlib4 > Reorganizing bilinearity and orthogonality?](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Reorganizing.20bilinearity.20and.20orthogonality.3F/with/582426197) Due to too agressive simplification I had to remove simp from - `QuadraticMap.associated_apply` - `QuadraticMap.isOrtho_polarBilin` Co-authored-by: Martin Winter Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Algebra/Lie/InvariantForm.lean | 6 +- Mathlib/Algebra/Lie/TraceForm.lean | 2 +- Mathlib/Algebra/Lie/Weights/Killing.lean | 2 +- .../BilinearForm/Orthogonal.lean | 59 +++++++----- .../LinearAlgebra/QuadraticForm/Basic.lean | 26 +++--- .../QuadraticForm/IsometryEquiv.lean | 2 +- .../LinearAlgebra/QuadraticForm/Radical.lean | 2 +- .../QuadraticForm/TensorProduct.lean | 6 +- .../TensorProduct/Isometries.lean | 5 +- .../RootSystem/Finite/Nondegenerate.lean | 4 +- .../LinearAlgebra/SesquilinearForm/Basic.lean | 90 ++++++++++--------- docs/undergrad.yaml | 2 +- 12 files changed, 112 insertions(+), 94 deletions(-) diff --git a/Mathlib/Algebra/Lie/InvariantForm.lean b/Mathlib/Algebra/Lie/InvariantForm.lean index ac4082707e8fba..18f81272293a12 100644 --- a/Mathlib/Algebra/Lie/InvariantForm.lean +++ b/Mathlib/Algebra/Lie/InvariantForm.lean @@ -74,7 +74,7 @@ def orthogonal (hΦ_inv : Φ.lieInvariant L) (N : LieSubmodule R L M) : LieSubmo __ := Φ.orthogonal N lie_mem {x y} := by suffices (∀ n ∈ N, Φ n y = 0) → ∀ n ∈ N, Φ n ⁅x, y⁆ = 0 by - simpa only [LinearMap.BilinForm.isOrtho_def, -- and some default simp lemmas + simpa only [ AddSubsemigroup.mem_carrier, AddSubmonoid.mem_toSubsemigroup, Submodule.mem_toAddSubmonoid, LinearMap.BilinForm.mem_orthogonal_iff, LieSubmodule.mem_toSubmodule] intro H a ha @@ -89,7 +89,7 @@ lemma orthogonal_toSubmodule (N : LieSubmodule R L M) : lemma mem_orthogonal (N : LieSubmodule R L M) (y : M) : y ∈ orthogonal Φ hΦ_inv N ↔ ∀ x ∈ N, Φ x y = 0 := by - simp [orthogonal, LinearMap.BilinForm.isOrtho_def, LinearMap.BilinForm.mem_orthogonal_iff] + simp [orthogonal, LinearMap.BilinForm.mem_orthogonal_iff] variable [LieAlgebra R L] @@ -202,7 +202,7 @@ theorem isSemisimple_of_nondegenerate : IsSemisimple K L := by intro J hJ hJI rw [← lie_eq_self_of_isAtom_of_nonabelian J hJ (hL J hJ), lieIdeal_oper_eq_span, lieSpan_le] rintro _ ⟨x, y, rfl⟩ - simp only [orthogonal_carrier, LinearMap.IsOrtho, Set.mem_setOf_eq] + simp only [orthogonal_carrier, Set.mem_setOf_eq] intro z hz rw [← neg_eq_zero, ← hΦ_inv] suffices ⁅(x : L), z⁆ = 0 by simp only [this, map_zero, LinearMap.zero_apply] diff --git a/Mathlib/Algebra/Lie/TraceForm.lean b/Mathlib/Algebra/Lie/TraceForm.lean index 1dad3c51e75468..b8117c7d26e145 100644 --- a/Mathlib/Algebra/Lie/TraceForm.lean +++ b/Mathlib/Algebra/Lie/TraceForm.lean @@ -404,7 +404,7 @@ noncomputable def killingCompl : LieIdeal R L := lemma coe_killingCompl_top : killingCompl R L ⊤ = LinearMap.ker (killingForm R L) := by ext x - simp [LinearMap.ext_iff, LinearMap.BilinForm.IsOrtho, LieModule.traceForm_comm R L L x] + simp [LinearMap.ext_iff, LieModule.traceForm_comm R L L x] lemma restrict_killingForm : (killingForm R L).restrict I = LieModule.traceForm R I L := diff --git a/Mathlib/Algebra/Lie/Weights/Killing.lean b/Mathlib/Algebra/Lie/Weights/Killing.lean index 6072fbc6715590..0fcc327d084cda 100644 --- a/Mathlib/Algebra/Lie/Weights/Killing.lean +++ b/Mathlib/Algebra/Lie/Weights/Killing.lean @@ -524,7 +524,7 @@ lemma traceForm_eq_zero_of_mem_ker_of_mem_span_coroot {α : Weight K H L} {x y : refine le_antisymm (fun x hx ↦ ?_) (fun x hx y hy ↦ ?_) · simp only [LinearMap.BilinForm.mem_orthogonal_iff] at hx specialize hx (coroot α) (Submodule.mem_span_singleton_self _) - simp only [LinearMap.BilinForm.isOrtho_def, traceForm_coroot, smul_eq_mul, nsmul_eq_mul, + simp only [traceForm_coroot, smul_eq_mul, nsmul_eq_mul, Nat.cast_ofNat, mul_eq_zero, OfNat.ofNat_ne_zero, inv_eq_zero, false_or] at hx simpa using hx.resolve_left (root_apply_cartanEquivDual_symm_ne_zero hα) · have := traceForm_eq_zero_of_mem_ker_of_mem_span_coroot hx hy diff --git a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean index cf6c510b7622db..6400c41c3c9ff0 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean @@ -50,32 +50,47 @@ namespace BilinForm /-- The proposition that two elements of a bilinear form space are orthogonal. For orthogonality of an indexed set of elements, use `BilinForm.iIsOrtho`. -/ +@[deprecated "Use `B x y = 0`." (since := "2026-03-30")] def IsOrtho (B : BilinForm R M) (x y : M) : Prop := B x y = 0 +set_option linter.deprecated false in +@[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_def {B : BilinForm R M} {x y : M} : B.IsOrtho x y ↔ B x y = 0 := Iff.rfl +set_option linter.deprecated false in +@[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_left (x : M) : IsOrtho B (0 : M) x := LinearMap.isOrtho_zero_left B x +set_option linter.deprecated false in +@[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_right (x : M) : IsOrtho B x (0 : M) := zero_right x -theorem ne_zero_of_not_isOrtho_self {B : BilinForm K V} (x : V) (hx₁ : ¬B.IsOrtho x x) : x ≠ 0 := - fun hx₂ => hx₁ (hx₂.symm ▸ isOrtho_zero_left _) +theorem ne_zero_of_not_isOrtho_self {B : BilinForm K V} (x : V) (hx₁ : B x x ≠ 0) : x ≠ 0 := by + by_contra; simp [this] at hx₁ -theorem IsRefl.ortho_comm (H : B.IsRefl) {x y : M} : IsOrtho B x y ↔ IsOrtho B y x := +theorem IsRefl.eq_iff (H : B.IsRefl) {x y : M} : B x y = 0 ↔ B y x = 0 := ⟨eq_zero H, eq_zero H⟩ -theorem IsAlt.ortho_comm (H : B₁.IsAlt) {x y : M₁} : IsOrtho B₁ x y ↔ IsOrtho B₁ y x := - LinearMap.IsAlt.ortho_comm H +@[deprecated (since := "2026-03-31")] +alias IsRefl.ortho_comm := IsRefl.eq_iff -theorem IsSymm.ortho_comm (H : B.IsSymm) {x y : M} : IsOrtho B x y ↔ IsOrtho B y x := - LinearMap.IsSymm.ortho_comm (isSymm_iff.1 H) +theorem IsAlt.eq_iff (H : B₁.IsAlt) {x y : M₁} : B₁ x y = 0 ↔ B₁ y x = 0 := + LinearMap.IsAlt.eq_iff H + +@[deprecated (since := "2026-03-31")] +alias IsAlt.ortho_comm := IsAlt.eq_iff + +theorem IsSymm.eq_iff (H : B.IsSymm) {x y : M} : B x y = 0 ↔ B y x = 0 := + LinearMap.IsSymm.eq_iff (isSymm_iff.1 H) + +@[deprecated (since := "2026-03-31")] +alias IsSymm.ortho_comm := IsSymm.eq_iff /-- A set of vectors `v` is orthogonal with respect to some bilinear form `B` if and only -if for all `i ≠ j`, `B (v i) (v j) = 0`. For orthogonality between two elements, use -`BilinForm.IsOrtho` -/ +if for all `i ≠ j`, `B (v i) (v j) = 0`. -/ def iIsOrtho {n : Type w} (B : BilinForm R M) (v : n → M) : Prop := B.IsOrthoᵢ v @@ -88,7 +103,8 @@ section variable {R₄ M₄ : Type*} [CommRing R₄] [IsDomain R₄] variable [AddCommGroup M₄] [Module R₄ M₄] {G : BilinForm R₄ M₄} -@[simp] +set_option linter.deprecated false in +@[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_smul_left {x y : M₄} {a : R₄} (ha : a ≠ 0) : IsOrtho G (a • x) y ↔ IsOrtho G x y := by dsimp only [IsOrtho] @@ -96,7 +112,8 @@ theorem isOrtho_smul_left {x y : M₄} {a : R₄} (ha : a ≠ 0) : simp only [LinearMap.smul_apply, smul_eq_mul, mul_eq_zero, or_iff_right_iff_imp] exact fun a ↦ (ha a).elim -@[simp] +set_option linter.deprecated false in +@[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_smul_right {x y : M₄} {a : R₄} (ha : a ≠ 0) : IsOrtho G x (a • y) ↔ IsOrtho G x y := by dsimp only [IsOrtho] @@ -107,7 +124,7 @@ theorem isOrtho_smul_right {x y : M₄} {a : R₄} (ha : a ≠ 0) : /-- A set of orthogonal vectors `v` with respect to some bilinear form `B` is linearly independent if for all `i`, `B (v i) (v i) ≠ 0`. -/ theorem linearIndependent_of_iIsOrtho {n : Type w} {B : BilinForm K V} {v : n → V} - (hv₁ : B.iIsOrtho v) (hv₂ : ∀ i, ¬B.IsOrtho (v i) (v i)) : LinearIndependent K v := by + (hv₁ : B.iIsOrtho v) (hv₂ : ∀ i, B (v i) (v i) ≠ 0) : LinearIndependent K v := by classical rw [linearIndependent_iff'] intro s w hs i hi @@ -136,10 +153,10 @@ variable {N L : Submodule R M} @[simp] theorem mem_orthogonal_iff {N : Submodule R M} {m : M} : - m ∈ B.orthogonal N ↔ ∀ n ∈ N, IsOrtho B n m := + m ∈ B.orthogonal N ↔ ∀ n ∈ N, B n m = 0 := Iff.rfl -@[simp] lemma orthogonal_bot : B.orthogonal ⊥ = ⊤ := by ext; simp [IsOrtho] +@[simp] lemma orthogonal_bot : B.orthogonal ⊥ = ⊤ := by ext; simp theorem orthogonal_le (h : N ≤ L) : B.orthogonal L ≤ B.orthogonal N := fun _ hn l hl => hn l (h hl) @@ -148,14 +165,14 @@ theorem le_orthogonal_orthogonal (b : B.IsRefl) : N ≤ B.orthogonal (B.orthogon lemma orthogonal_top_eq_ker (hB : B.IsRefl) : B.orthogonal ⊤ = LinearMap.ker B := by - ext; simp [LinearMap.BilinForm.IsOrtho, LinearMap.ext_iff, hB.eq_iff] + ext; simp [LinearMap.ext_iff, hB.eq_iff] lemma orthogonal_top_eq_bot (hB : B.Nondegenerate) : B.orthogonal ⊤ = ⊥ := (Submodule.eq_bot_iff _).mpr fun x hx ↦ hB.2 x (by simpa using! hx) -- ↓ This lemma only applies in fields as we require `a * b = 0 → a = 0 ∨ b = 0` -theorem span_singleton_inf_orthogonal_eq_bot {B : BilinForm K V} {x : V} (hx : ¬B.IsOrtho x x) : +theorem span_singleton_inf_orthogonal_eq_bot {B : BilinForm K V} {x : V} (hx : B x x ≠ 0) : K ∙ x ⊓ B.orthogonal (K ∙ x) = ⊥ := LinearMap.span_singleton_inf_orthogonal_eq_bot B _ hx @@ -164,13 +181,13 @@ theorem orthogonal_span_singleton_eq_toLin_ker {B : BilinForm K V} (x : V) : B.orthogonal (K ∙ x) = LinearMap.ker (LinearMap.BilinForm.toLinHomAux₁ B x) := LinearMap.orthogonal_span_singleton_eq_to_lin_ker .. -theorem span_singleton_sup_orthogonal_eq_top {B : BilinForm K V} {x : V} (hx : ¬B.IsOrtho x x) : +theorem span_singleton_sup_orthogonal_eq_top {B : BilinForm K V} {x : V} (hx : B x x ≠ 0) : K ∙ x ⊔ B.orthogonal (K ∙ x) = ⊤ := LinearMap.span_singleton_sup_orthogonal_eq_top hx /-- Given a bilinear form `B` and some `x` such that `B x x ≠ 0`, the span of the singleton of `x` is complement to its orthogonal complement. -/ -theorem isCompl_span_singleton_orthogonal {B : BilinForm K V} {x : V} (hx : ¬B.IsOrtho x x) : +theorem isCompl_span_singleton_orthogonal {B : BilinForm K V} {x : V} (hx : B x x ≠ 0) : IsCompl (K ∙ x) (B.orthogonal <| K ∙ x) := LinearMap.isCompl_span_singleton_orthogonal hx @@ -189,14 +206,14 @@ theorem nondegenerate_restrict_of_disjoint_orthogonal (B : BilinForm R₁ M₁) elements. -/ theorem iIsOrtho.not_isOrtho_basis_self_of_nondegenerate {n : Type w} [Nontrivial R] {B : BilinForm R M} {v : Basis n R M} (h : B.iIsOrtho v) (hB : B.Nondegenerate) (i : n) : - ¬B.IsOrtho (v i) (v i) := + B (v i) (v i) ≠ 0 := h.not_isOrtho_basis_self_of_separatingLeft hB.1 i /-- Given an orthogonal basis with respect to a bilinear form, the bilinear form is nondegenerate iff the basis has no elements which are self-orthogonal. -/ theorem iIsOrtho.nondegenerate_iff_not_isOrtho_basis_self {n : Type w} [IsDomain R] (B : BilinForm R M) (v : Basis n R M) (hO : B.iIsOrtho v) : - B.Nondegenerate ↔ ∀ i, ¬B.IsOrtho (v i) (v i) := + B.Nondegenerate ↔ ∀ i, B (v i) (v i) ≠ 0 := ⟨hO.not_isOrtho_basis_self_of_nondegenerate, hO.nondegenerate_of_not_isOrtho_basis_self _⟩ section @@ -351,7 +368,7 @@ on the whole space. -/ /-- The restriction of a reflexive, non-degenerate bilinear form on the orthogonal complement of the span of a singleton is also non-degenerate. -/ theorem restrict_nondegenerate_orthogonal_spanSingleton (B : BilinForm K V) (b₁ : B.Nondegenerate) - (b₂ : B.IsRefl) {x : V} (hx : ¬B.IsOrtho x x) : + (b₂ : B.IsRefl) {x : V} (hx : B x x ≠ 0) : Nondegenerate <| B.restrict <| B.orthogonal (K ∙ x) := by have (n : V) : n ∈ K ∙ x ⊔ B.orthogonal (K ∙ x) := (span_singleton_sup_orthogonal_eq_top hx).symm ▸ Submodule.mem_top diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index ecb33bc815b2ae..7a28de8535feb4 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -901,16 +901,14 @@ def associatedHom : QuadraticMap R M N →ₗ[S] (BilinMap R M N) where variable (Q : QuadraticMap R M N) -@[simp] theorem associated_apply (x y : M) : - associatedHom S Q x y = ⅟(2 : Module.End R N) • (Q (x + y) - Q x - Q y) := - rfl + associatedHom S Q x y = ⅟(2 : Module.End R N) • (Q (x + y) - Q x - Q y) := rfl set_option backward.defeqAttrib.useBackward true in /-- Twice the associated bilinear map of `Q` is the same as the polar of `Q`. -/ @[simp] theorem two_nsmul_associated : 2 • associatedHom S Q = Q.polarBilin := by ext - dsimp + dsimp [associated_apply] rw [← LinearMap.smul_apply, nsmul_eq_mul, Nat.cast_ofNat, mul_invOf_self', Module.End.one_apply, polar] @@ -1065,9 +1063,9 @@ alias ⟨IsOrtho.symm, _⟩ := isOrtho_comm theorem _root_.LinearMap.BilinForm.toQuadraticMap_isOrtho [IsCancelAdd R] [NoZeroDivisors R] [CharZero R] {B : BilinMap R M R} {x y : M} (h : B.IsSymm) : - B.toQuadraticMap.IsOrtho x y ↔ B.IsOrtho x y := by + B.toQuadraticMap.IsOrtho x y ↔ B x y = 0 := by letI : AddCancelMonoid R := { ‹IsCancelAdd R›, (inferInstance : AddCommMonoid R) with } - simp_rw [isOrtho_def, LinearMap.isOrtho_def, B.toQuadraticMap_apply, map_add, + simp_rw [isOrtho_def, B.toQuadraticMap_apply, map_add, LinearMap.add_apply, add_comm _ (B y y), add_add_add_comm _ _ (B y y), add_comm (B y y)] rw [add_eq_left (a := B x x + B y y), ← h.eq, RingHom.id_apply, add_self_eq_zero] @@ -1077,18 +1075,16 @@ section CommRing variable [CommRing R] [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N] {Q : QuadraticMap R M N} -@[simp] -theorem isOrtho_polarBilin {x y : M} : Q.polarBilin.IsOrtho x y ↔ IsOrtho Q x y := by - simp_rw [isOrtho_def, LinearMap.isOrtho_def, polarBilin_apply_apply, polar, sub_sub, sub_eq_zero] +theorem isOrtho_polarBilin {x y : M} : Q.polarBilin x y = 0 ↔ IsOrtho Q x y := by + simp_rw [isOrtho_def, polarBilin_apply_apply, polar, sub_sub, sub_eq_zero] theorem IsOrtho.polar_eq_zero {x y : M} (h : IsOrtho Q x y) : polar Q x y = 0 := isOrtho_polarBilin.mpr h @[simp] theorem associated_isOrtho [Invertible (2 : R)] {x y : M} : - Q.associated.IsOrtho x y ↔ Q.IsOrtho x y := by - simp_rw [isOrtho_def, LinearMap.isOrtho_def, associated_apply, invOf_smul_eq_iff, - smul_zero, sub_sub, sub_eq_zero] + Q.associated x y = 0 ↔ Q.IsOrtho x y := by + simp_rw [isOrtho_def, associated_apply, invOf_smul_eq_iff, smul_zero, sub_sub, sub_eq_zero] end CommRing @@ -1366,7 +1362,7 @@ variable [CommRing R] [AddCommGroup M] [Module R M] on a module `M` over a ring `R` with invertible `2`, i.e. there exists some `x : M` such that `B x x ≠ 0`. -/ theorem exists_bilinForm_self_ne_zero [htwo : Invertible (2 : R)] {B : BilinForm R M} - (hB₁ : B ≠ 0) (hB₂ : B.IsSymm) : ∃ x, ¬B.IsOrtho x x := by + (hB₁ : B ≠ 0) (hB₂ : B.IsSymm) : ∃ x, B x x ≠ 0 := by lift B to QuadraticForm R M using hB₂ with Q obtain ⟨x, hx⟩ := QuadraticMap.exists_quadraticMap_ne_zero hB₁ exact ⟨x, fun h => hx (Q.associated_eq_self_apply ℕ x ▸ h)⟩ @@ -1410,7 +1406,7 @@ theorem exists_orthogonal_basis [hK : Invertible (2 : K)] {B : LinearMap.BilinFo intro y refine ⟨-B x y / B x x, fun z hz => ?_⟩ obtain ⟨c, rfl⟩ := Submodule.mem_span_singleton.1 hz - rw [IsOrtho, map_smul, smul_apply, map_add, map_smul, smul_eq_mul, smul_eq_mul, + rw [map_smul, smul_apply, map_add, map_smul, smul_eq_mul, smul_eq_mul, div_mul_cancel₀ _ hx, add_neg_cancel, mul_zero]) refine ⟨b, ?_⟩ rw [Basis.coe_mkFinCons] @@ -1418,7 +1414,7 @@ theorem exists_orthogonal_basis [hK : Invertible (2 : K)] {B : LinearMap.BilinFo refine Fin.cases ?_ (fun i => ?_) i <;> refine Fin.cases ?_ (fun j => ?_) j <;> intro hij <;> simp only [Function.onFun, Fin.cons_zero, Fin.cons_succ, Function.comp_apply] · exact (hij rfl).elim - · rw [IsOrtho, ← hB₂.eq] + · rw [← hB₂.eq] exact (v' j).prop _ (Submodule.mem_span_singleton_self x) · exact (v' i).prop _ (Submodule.mem_span_singleton_self x) · exact hv₁ (ne_of_apply_ne _ hij) diff --git a/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean b/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean index 34157f8ca08d6e..bda0fcc2cee93b 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean @@ -171,7 +171,7 @@ theorem equivalent_weightedSumSquares_units_of_nondegenerate' (Q : QuadraticForm ∃ w : Fin (Module.finrank K V) → Kˣ, Equivalent Q (weightedSumSquares K w) := by obtain ⟨v, hv₁⟩ := exists_orthogonal_basis (associated_isSymm K Q) have hv₂ := hv₁.not_isOrtho_basis_self_of_separatingLeft hQ - simp_rw [LinearMap.IsOrtho, associated_eq_self_apply] at hv₂ + simp_rw [associated_eq_self_apply] at hv₂ exact ⟨fun i => Units.mk0 _ (hv₂ i), ⟨Q.isometryEquivWeightedSumSquares v hv₁⟩⟩ variable {ι S R : Type*} diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Radical.lean b/Mathlib/LinearAlgebra/QuadraticForm/Radical.lean index df01c340bda52d..62ebdc80a84f20 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Radical.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Radical.lean @@ -138,7 +138,7 @@ the radical of a quadratic map is the kernel of its associated bilinear map. -/ lemma radical_eq_ker_associated : Q.radical = (QuadraticMap.associated Q).ker := by rw [radical_eq_ker_polarBilin] ext m - simp [LinearMap.ext_iff, QuadraticMap.polar, -smul_eq_mul, invOf_smul_eq_iff] + simp [associated_apply, LinearMap.ext_iff, QuadraticMap.polar, invOf_smul_eq_iff] /-- If `2` is invertible in the coefficient ring, diff --git a/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean b/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean index c562808d6c6af6..f2e5f4e238dccb 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean @@ -110,8 +110,10 @@ protected abbrev tmul (Q₁ : QuadraticForm A M₁) (Q₂ : QuadraticForm R M₂ theorem associated_tmul [Invertible (2 : A)] (Q₁ : QuadraticForm A M₁) (Q₂ : QuadraticForm R M₂) : (Q₁.tmul Q₂).associated = BilinForm.tmul Q₁.associated Q₂.associated := by rw [BilinForm.tmul, BilinForm.tensorDistrib, LinearMap.comp_apply, ← BilinMap.tmul, - ← QuadraticMap.associated_tmul Q₁ Q₂] - aesop + ← QuadraticMap.associated_tmul Q₁ Q₂, LinearEquiv.coe_coe, LinearEquiv.congrRight₂_apply] + ext : 6 + simp [associated_apply] + rfl set_option backward.isDefEq.respectTransparency false in theorem polarBilin_tmul [Invertible (2 : A)] (Q₁ : QuadraticForm A M₁) (Q₂ : QuadraticForm R M₂) : diff --git a/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct/Isometries.lean b/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct/Isometries.lean index 7f057783b837c2..1bd58fe2a8f641 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct/Isometries.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct/Isometries.lean @@ -47,7 +47,7 @@ theorem tmul_comp_tensorMap have h₃ : Q₃ = Q₄.comp g.toLinearMap := QuadraticMap.ext fun x => (g.map_app x).symm refine (QuadraticMap.associated_rightInverse R).injective ?_ ext m₁ m₃ m₁' m₃' - simp [-associated_apply, h₁, h₃, associated_tmul] + simp [h₁, h₃, associated_tmul] @[simp] theorem tmul_tensorMap_apply @@ -156,8 +156,7 @@ theorem comp_tensorRId_eq (Q₁ : QuadraticForm R M₁) : Q₁.comp (TensorProduct.rid R M₁) = Q₁.tmul (sq (R := R)) := by refine (QuadraticMap.associated_rightInverse R).injective ?_ ext m₁ m₁' - simp only [associated_tmul, QuadraticMap.associated_comp] - simp [-associated_apply, one_mul] + simp [associated_tmul, QuadraticMap.associated_comp, one_mul] @[simp] theorem tmul_tensorRId_apply diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean index 72d1c45be90d40..20eda0b8dfc45e 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean @@ -328,11 +328,11 @@ lemma orthogonal_rootSpan_eq : rw [← LinearMap.BilinForm.orthogonal_top_eq_ker P.rootForm_symmetric.isRefl] refine le_antisymm ?_ (by intro; simp_all) rintro x hx y - - simp only [LinearMap.BilinForm.mem_orthogonal_iff, LinearMap.BilinForm.IsOrtho] at hx ⊢ + simp only [LinearMap.BilinForm.mem_orthogonal_iff] at hx ⊢ obtain ⟨u, hu, v, hv, rfl⟩ : ∃ᵉ (u ∈ P.rootSpan R) (v ∈ LinearMap.ker P.RootForm), u + v = y := by rw [← Submodule.mem_sup, P.isCompl_rootSpan_ker_rootForm.sup_eq_top]; exact Submodule.mem_top simp only [LinearMap.mem_ker] at hv - simp [LinearMap.IsOrtho, hx _ hu, hv] + simp [hx _ hu, hv] @[simp] lemma orthogonal_corootSpan_eq : diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean index b46d360514ce54..bd8ccfce7388c1 100644 --- a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean @@ -25,9 +25,8 @@ basic lemmas about construction and elementary calculations are found there. ## Main declarations -* `IsOrtho`: states that two vectors are orthogonal with respect to a sesquilinear map * `IsSymm`, `IsAlt`: states that a sesquilinear form is symmetric and alternating, respectively -* `orthogonalBilin` provides the orthogonal complement with respect to a sesquilinear form +* `orthogonalBilin` provides the orthogonal complement with respect to a sesquilinear map ## References @@ -57,28 +56,36 @@ variable [CommSemiring R] [CommSemiring R₁] [AddCommMonoid M₁] [Module R₁ {I₁ : R₁ →+* R} {I₂ : R₂ →+* R} {I₁' : R₁ →+* R} /-- The proposition that two elements of a sesquilinear map space are orthogonal -/ +@[deprecated "Use `B x y = 0`" (since := "2026-03-30")] def IsOrtho (B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M) (x : M₁) (y : M₂) : Prop := B x y = 0 +set_option linter.deprecated false in +@[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_def {B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M} {x y} : B.IsOrtho x y ↔ B x y = 0 := Iff.rfl +set_option linter.deprecated false in +@[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_left (B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M) (x) : IsOrtho B (0 : M₁) x := by dsimp only [IsOrtho] rw [map_zero B, zero_apply] +set_option linter.deprecated false in +@[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_right (B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M) (x) : IsOrtho B x (0 : M₂) := map_zero (B x) +set_option linter.deprecated false in +@[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_flip {B : M₁ →ₛₗ[I₁] M₁ →ₛₗ[I₁'] M} {x y} : B.IsOrtho x y ↔ B.flip.IsOrtho y x := by simp_rw [isOrtho_def, flip_apply] open scoped Function in -- required for scoped `on` notation /-- A set of vectors `v` is orthogonal with respect to some bilinear map `B` if and only -if for all `i ≠ j`, `B (v i) (v j) = 0`. For orthogonality between two elements, use -`BilinForm.isOrtho` -/ +if for all `i ≠ j`, `B (v i) (v j) = 0`. -/ def IsOrthoᵢ (B : M₁ →ₛₗ[I₁] M₁ →ₛₗ[I₁'] M) (v : n → M₁) : Prop := - Pairwise (B.IsOrtho on v) + Pairwise ((fun n m => B n m = 0) on v) theorem isOrthoᵢ_def {B : M₁ →ₛₗ[I₁] M₁ →ₛₗ[I₁'] M} {v : n → M₁} : B.IsOrthoᵢ v ↔ ∀ i j : n, i ≠ j → B (v i) (v j) = 0 := @@ -97,7 +104,8 @@ variable [Field K] [AddCommGroup V] [Module K V] [Field K₁] [AddCommGroup V₁ [Field K₂] [AddCommGroup V₂] [Module K₂ V₂] {I₁ : K₁ →+* K} {I₂ : K₂ →+* K} {I₁' : K₁ →+* K} {J₁ : K →+* K} {J₂ : K →+* K} --- todo: this also holds for [CommRing R] [IsDomain R] when J₁ is invertible +set_option linter.deprecated false in +@[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem ortho_smul_left {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} {a : K₁} (ha : a ≠ 0) : IsOrtho B x y ↔ IsOrtho B (a • x) y := by dsimp only [IsOrtho] @@ -109,7 +117,8 @@ theorem ortho_smul_left {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} trivial · exact H --- todo: this also holds for [CommRing R] [IsDomain R] when J₂ is invertible +set_option linter.deprecated false in +@[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem ortho_smul_right {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} {a : K₂} {ha : a ≠ 0} : IsOrtho B x y ↔ IsOrtho B x (a • y) := by simp_all [IsOrtho] @@ -117,7 +126,7 @@ theorem ortho_smul_right {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} /-- A set of orthogonal vectors `v` with respect to some sesquilinear map `B` is linearly independent if for all `i`, `B (v i) (v i) ≠ 0`. -/ theorem linearIndependent_of_isOrthoᵢ {B : V₁ →ₛₗ[I₁] V₁ →ₛₗ[I₁'] V} {v : n → V₁} - (hv₁ : B.IsOrthoᵢ v) (hv₂ : ∀ i, ¬B.IsOrtho (v i) (v i)) : LinearIndependent K₁ v := by + (hv₁ : B.IsOrthoᵢ v) (hv₂ : ∀ i, B (v i) (v i) ≠ 0) : LinearIndependent K₁ v := by classical rw [linearIndependent_iff'] intro s w hs i hi @@ -134,7 +143,6 @@ end Field /-! ### Reflexive bilinear maps -/ - section Reflexive variable [CommSemiring R] [AddCommMonoid M] [Module R M] [CommSemiring R₁] [AddCommMonoid M₁] @@ -154,8 +162,8 @@ theorem eq_zero : ∀ {x y}, B x y = 0 → B y x = 0 := fun {x y} ↦ H x y theorem eq_iff {x y} : B x y = 0 ↔ B y x = 0 := ⟨H x y, H y x⟩ -theorem ortho_comm {x y} : IsOrtho B x y ↔ IsOrtho B y x := - ⟨eq_zero H, eq_zero H⟩ +@[deprecated (since := "2026-03-30")] +alias ortho_comm := eq_iff theorem domRestrict (p : Submodule R₁ M₁) : (B.domRestrict₁₂ p p).IsRefl := fun _ _ ↦ by @@ -184,7 +192,6 @@ end Reflexive /-! ### Symmetric bilinear forms -/ - section Symmetric variable [CommSemiring R] [AddCommMonoid M] [Module R M] {I : R →+* R} {B : M →ₛₗ[I] M →ₗ[R] R} @@ -202,8 +209,10 @@ theorem isRefl (H : B.IsSymm) : B.IsRefl := fun x y H1 ↦ by rw [← H.eq] simp [H1] -theorem ortho_comm (H : B.IsSymm) {x y} : IsOrtho B x y ↔ IsOrtho B y x := - H.isRefl.ortho_comm +theorem eq_iff (H : B.IsSymm) {x y} : B x y = 0 ↔ B y x = 0 := H.isRefl.eq_iff + +@[deprecated (since := "2026-03-30")] +alias ortho_comm := eq_iff theorem domRestrict (H : B.IsSymm) (p : Submodule R M) : (B.domRestrict₁₂ p p).IsSymm where eq _ _ := by @@ -273,7 +282,6 @@ end PositiveSemidefinite /-! ### Alternating bilinear maps -/ - section Alternating section CommSemiring @@ -317,8 +325,10 @@ theorem isRefl (H : B.IsAlt) : B.IsRefl := by intro x y h rw [← neg H, h, neg_zero] -theorem ortho_comm (H : B.IsAlt) {x y} : IsOrtho B x y ↔ IsOrtho B y x := - H.isRefl.ortho_comm +theorem eq_iff (H : B.IsAlt) {x y} : B x y = 0 ↔ B y x = 0 := H.isRefl.eq_iff + +@[deprecated (since := "2026-03-30")] +alias ortho_comm := eq_iff end IsAlt @@ -371,16 +381,13 @@ chirality; in addition to this "left" orthogonal complement one could define a " complement for which, for all `y` in `N`, `B y x = 0`. This variant definition is not currently provided in mathlib. -/ def orthogonalBilin (N : Submodule R₁ M₁) : Submodule R₂ M₂ where - carrier := { m | ∀ n ∈ N, B.IsOrtho n m } - zero_mem' x _ := B.isOrtho_zero_right x - add_mem' hx hy n hn := by - rw [LinearMap.IsOrtho, map_add, show B n _ = 0 from hx n hn, show B n _ = 0 from hy n hn, - zero_add] - smul_mem' c x hx n hn := by - rw [LinearMap.IsOrtho, map_smulₛₗ, show B n x = 0 from hx n hn, smul_zero] + carrier := { m | ∀ n ∈ N, B n m = 0 } + zero_mem' x _ := map_zero _ + add_mem' {u v} hu hv x hx := by simp [hu _ hx, hv _ hx] + smul_mem' c y hy x hx := by simp [hy _ hx] @[simp] -theorem mem_orthogonalBilin_iff {m : M₂} : m ∈ N.orthogonalBilin B ↔ ∀ n ∈ N, B.IsOrtho n m := +theorem mem_orthogonalBilin_iff {m : M₂} : m ∈ N.orthogonalBilin B ↔ ∀ n ∈ N, B n m = 0:= Iff.rfl theorem orthogonalBilin_le (h : N ≤ L) : L.orthogonalBilin B ≤ N.orthogonalBilin B := @@ -408,14 +415,14 @@ variable [Field K] [AddCommGroup V] [Module K V] [Field K₁] [AddCommGroup V₁ -- ↓ This lemma only applies in fields as we require `a * b = 0 → a = 0 ∨ b = 0` theorem span_singleton_inf_orthogonal_eq_bot (B : V₁ →ₛₗ[J₁] V₁ →ₛₗ[J₁'] V₂) (x : V₁) - (hx : ¬B.IsOrtho x x) : (K₁ ∙ x) ⊓ (K₁ ∙ x).orthogonalBilin B = ⊥ := by + (hx : B x x ≠ 0) : (K₁ ∙ x) ⊓ (K₁ ∙ x).orthogonalBilin B = ⊥ := by rw [← Finset.coe_singleton] refine eq_bot_iff.2 fun y h ↦ ?_ obtain ⟨μ, -, rfl⟩ := Submodule.mem_span_finset.1 h.1 replace h := h.2 x (by simp [Submodule.mem_span] : x ∈ Submodule.span K₁ ({x} : Finset V₁)) rw [Finset.sum_singleton] at h ⊢ suffices hμzero : μ x = 0 by rw [hμzero, zero_smul, Submodule.mem_bot] - rw [isOrtho_def, map_smulₛₗ] at h + rw [map_smulₛₗ] at h exact Or.elim (smul_eq_zero.mp h) (fun y ↦ by simpa using y) (fun hfalse ↦ False.elim <| hx hfalse) @@ -428,11 +435,11 @@ theorem orthogonal_span_singleton_eq_to_lin_ker {B : V →ₗ[K] V →ₛₗ[J] constructor · exact fun h ↦ h x ⟨1, one_smul _ _⟩ · rintro h _ ⟨z, rfl⟩ - rw [isOrtho_def, map_smulₛₗ₂, smul_eq_zero] + rw [map_smulₛₗ₂, smul_eq_zero] exact Or.intro_right _ h -- todo: Generalize this to sesquilinear maps -theorem span_singleton_sup_orthogonal_eq_top {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : ¬B.IsOrtho x x) : +theorem span_singleton_sup_orthogonal_eq_top {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : B x x ≠ 0) : (K ∙ x) ⊔ (K ∙ x).orthogonalBilin B = ⊤ := by rw [orthogonal_span_singleton_eq_to_lin_ker] exact (B x).span_singleton_sup_ker_eq_top hx @@ -440,7 +447,7 @@ theorem span_singleton_sup_orthogonal_eq_top {B : V →ₗ[K] V →ₗ[K] K} {x -- todo: Generalize this to sesquilinear maps /-- Given a bilinear form `B` and some `x` such that `B x x ≠ 0`, the span of the singleton of `x` is complement to its orthogonal complement. -/ -theorem isCompl_span_singleton_orthogonal {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : ¬B.IsOrtho x x) : +theorem isCompl_span_singleton_orthogonal {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : B x x ≠ 0) : IsCompl (K ∙ x) ((K ∙ x).orthogonalBilin B) := { disjoint := disjoint_iff.2 <| span_singleton_inf_orthogonal_eq_bot B x hx codisjoint := codisjoint_iff.2 <| span_singleton_sup_orthogonal_eq_top hx } @@ -449,7 +456,6 @@ end Orthogonal /-! ### Adjoint pairs -/ - section AdjointPair section AddCommMonoid @@ -558,7 +564,6 @@ end AdjointPair /-! ### Self-adjoint pairs -/ - section SelfadjointPair section AddCommMonoid @@ -657,7 +662,6 @@ end SelfadjointPair /-! ### Nondegenerate bilinear maps -/ - section Nondegenerate section CommSemiring @@ -837,8 +841,7 @@ theorem nondegenerate_restrict_of_disjoint_orthogonal {B : M →ₗ[R] M →ₗ[ refine hW.le_bot ⟨hx, fun y hy ↦ ?_⟩ specialize b₁ ⟨y, hy⟩ simp_rw [domRestrict₁₂_apply] at b₁ - rw [hB.ortho_comm] - exact b₁ + exact hB.eq_zero b₁ end CommRing @@ -851,7 +854,7 @@ variable {R M M₁ : Type*} [CommSemiring R] [AddCommMonoid M] [AddCommMonoid M elements. -/ theorem IsOrthoᵢ.not_isOrtho_basis_self_of_separatingLeft [Nontrivial R] {v : Basis n R M} (h : B.IsOrthoᵢ v) (hB : B.SeparatingLeft) - (i : n) : ¬B.IsOrtho (v i) (v i) := by + (i : n) : B (v i) (v i) ≠ 0 := by intro ho refine v.ne_zero i (hB (v i) fun m ↦ ?_) obtain ⟨vi, rfl⟩ := v.repr.symm.surjective m @@ -868,9 +871,8 @@ theorem IsOrthoᵢ.not_isOrtho_basis_self_of_separatingLeft [Nontrivial R] elements. -/ theorem IsOrthoᵢ.not_isOrtho_basis_self_of_separatingRight [Nontrivial R] {v : Basis n R M} (h : B.IsOrthoᵢ v) (hB : B.SeparatingRight) - (i : n) : ¬B.IsOrtho (v i) (v i) := by + (i : n) : B (v i) (v i) ≠ 0 := by rw [isOrthoᵢ_flip] at h - rw [isOrtho_flip] exact h.not_isOrtho_basis_self_of_separatingLeft (flip_separatingLeft.mpr hB) i variable [IsDomain R] [IsTorsionFree R M₁] @@ -878,7 +880,7 @@ variable [IsDomain R] [IsTorsionFree R M₁] /-- Given an orthogonal basis with respect to a bilinear map, the bilinear map is left-separating if the basis has no elements which are self-orthogonal. -/ theorem IsOrthoᵢ.separatingLeft_of_not_isOrtho_basis_self {B : M →ₗ[R] M →ₗ[R] M₁} (v : Basis n R M) - (hO : B.IsOrthoᵢ v) (h : ∀ i, ¬B.IsOrtho (v i) (v i)) : B.SeparatingLeft := by + (hO : B.IsOrthoᵢ v) (h : ∀ i, B (v i) (v i) ≠ 0) : B.SeparatingLeft := by intro m hB obtain ⟨vi, rfl⟩ := v.repr.symm.surjective m rw [LinearEquiv.map_eq_zero_iff] @@ -888,7 +890,10 @@ theorem IsOrthoᵢ.separatingLeft_of_not_isOrtho_basis_self {B : M →ₗ[R] M simp_rw [Basis.repr_symm_apply, Finsupp.linearCombination_apply, Finsupp.sum, map_sum₂, map_smulₛₗ₂] at hB rw [Finset.sum_eq_single i] at hB - · exact (smul_eq_zero.mp hB).elim _root_.id (h i).elim + · cases smul_eq_zero.mp hB + · assumption + · specialize h i + contradiction · intro j _hj hij replace hij : B (v j) (v i) = 0 := hO hij rw [hij, RingHom.id_apply, smul_zero] @@ -899,17 +904,16 @@ theorem IsOrthoᵢ.separatingLeft_of_not_isOrtho_basis_self {B : M →ₗ[R] M /-- Given an orthogonal basis with respect to a bilinear map, the bilinear map is right-separating if the basis has no elements which are self-orthogonal. -/ lemma IsOrthoᵢ.separatingRight_iff_not_isOrtho_basis_self {B : M →ₗ[R] M →ₗ[R] M₁} (v : Basis n R M) - (hO : B.IsOrthoᵢ v) (h : ∀ i, ¬B.IsOrtho (v i) (v i)) : B.SeparatingRight := by + (hO : B.IsOrthoᵢ v) (h : ∀ i, B (v i) (v i) ≠ 0) : B.SeparatingRight := by rw [isOrthoᵢ_flip] at hO rw [← flip_separatingLeft] refine IsOrthoᵢ.separatingLeft_of_not_isOrtho_basis_self v hO fun i ↦ ?_ - rw [isOrtho_flip] exact h i /-- Given an orthogonal basis with respect to a bilinear map, the bilinear map is nondegenerate if the basis has no elements which are self-orthogonal. -/ theorem IsOrthoᵢ.nondegenerate_of_not_isOrtho_basis_self {B : M →ₗ[R] M →ₗ[R] M₁} (v : Basis n R M) - (hO : B.IsOrthoᵢ v) (h : ∀ i, ¬B.IsOrtho (v i) (v i)) : B.Nondegenerate := + (hO : B.IsOrthoᵢ v) (h : ∀ i, B (v i) (v i) ≠ 0) : B.Nondegenerate := ⟨IsOrthoᵢ.separatingLeft_of_not_isOrtho_basis_self v hO h, IsOrthoᵢ.separatingRight_iff_not_isOrtho_basis_self v hO h⟩ diff --git a/docs/undergrad.yaml b/docs/undergrad.yaml index 5daf196a4b20b8..710b7695d179c4 100644 --- a/docs/undergrad.yaml +++ b/docs/undergrad.yaml @@ -204,7 +204,7 @@ Bilinear and Quadratic Forms Over a Vector Space: quadratic form: 'QuadraticForm' polar form of a quadratic: 'QuadraticMap.polar' Orthogonality: - orthogonal elements: 'LinearMap.BilinForm.IsOrtho' + orthogonal elements: 'LinearMap.BilinForm.iIsOrtho' adjoint endomorphism: 'LinearMap.BilinForm.leftAdjointOfNondegenerate' Sylvester's law of inertia (existence): 'QuadraticForm.equivalent_one_zero_neg_one_weighted_sum_squared' Sylvester's law of inertia (uniqueness): 'QuadraticForm.sigPos_of_equiv_weightedSumSquares' From 691477963dcf9f47ef6dda6419e864200b5f3ffd Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Wed, 17 Jun 2026 06:16:41 +0000 Subject: [PATCH 0099/1300] chore(AlgebraicGeometry/AffineTransitionLimit): deduce that `Hom(-, X)` preserves certain cofiltered limits (#40546) We deduce this from the unbundled statement. Usually the unbundled formulation is more useful, but sometimes we need the categorical spelling to apply general API. We also add some API for descending a finite affine open cover. From Proetale. --- .../AffineTransitionLimit.lean | 108 ++++++++++++++++-- 1 file changed, 96 insertions(+), 12 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index 4f7291ff066e06..c12b8899b8151a 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -11,6 +11,7 @@ public import Mathlib.AlgebraicGeometry.Morphisms.Separated public import Mathlib.AlgebraicGeometry.Morphisms.FinitePresentation public import Mathlib.AlgebraicGeometry.QuasiAffine public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Connected +public import Mathlib.CategoryTheory.Limits.Types.ColimitTypeFiltered public import Mathlib.CategoryTheory.Monad.Limits /-! @@ -24,7 +25,7 @@ following EGA IV 8 and https://stacks.math.columbia.edu/tag/01YT. @[expose] public section -universe uI u +universe w uI u open CategoryTheory Limits @@ -1070,6 +1071,30 @@ lemma exists_isAffineOpen_preimage_eq obtain ⟨j, hj⟩ := Scheme.exists_isAffine_of_isLimit _ _ (isLimitOpensCone D c hc i U) exact ⟨_, _, hj, by simp [← Scheme.Hom.comp_preimage]⟩ +set_option backward.isDefEq.respectTransparency false in +open TopologicalSpace in +include hc in +lemma Scheme.exists_isOpenCover_and_isAffine_of_finite [IsCofiltered I] + [∀ {i j} (f : i ⟶ j), IsAffineHom (D.map f)] [∀ (i : I), CompactSpace (D.obj i)] + [∀ (i : I), QuasiSeparatedSpace (D.obj i)] + {J : Type*} [Finite J] (U : J → c.pt.Opens) (hU : IsOpenCover U) + (hU' : ∀ i, IsAffineOpen (U i)) : + ∃ (i : I) (V : J → (D.obj i).Opens), + IsOpenCover V ∧ ∀ j, IsAffineOpen (V j) ∧ U j = c.π.app i ⁻¹ᵁ (V j) := by + classical + choose j V hV hVU using fun k ↦ exists_isAffineOpen_preimage_eq D c hc (U k) (hU' k) + cases nonempty_fintype J + obtain ⟨i, fi⟩ := IsCofiltered.inf_objs_exists (Finset.univ.image j) + replace fi : ∀ k, i ⟶ j k := fun k ↦ (fi (by simp)).some + obtain ⟨k, fkj, e⟩ := exists_map_eq_top D c hc (⨆ (k), D.map (fi k) ⁻¹ᵁ V k) (by + simp_rw [Hom.preimage_iSup, ← Hom.comp_preimage, c.w, hVU] + exact hU) + refine ⟨k, fun x ↦ D.map (fkj ≫ fi x) ⁻¹ᵁ V _, ?_, fun k ↦ ⟨(hV k).preimage _, ?_⟩⟩ + · refine top_le_iff.mp (e.symm.trans_le ?_) + simp_rw [Hom.preimage_iSup, ← Hom.comp_preimage, ← D.map_comp] + simp + · rw [← hVU, ← Hom.comp_preimage, c.w] + set_option backward.isDefEq.respectTransparency false in open TopologicalSpace in include hc in @@ -1084,19 +1109,48 @@ lemma Scheme.exists_isOpenCover_and_isAffine [IsCofiltered I] IsOpenCover V ∧ ∀ j, IsAffineOpen (V j) ∧ U j = c.π.app i ⁻¹ᵁ (V j) := by classical have := compactSpace_of_isLimit D c hc - choose j V hV hVU using fun k ↦ exists_isAffineOpen_preimage_eq D c hc (U k) (hU' k) obtain ⟨s, hs⟩ := isCompact_univ.elim_finite_subcover _ (fun i ↦ (U i).isOpen) hU.iSup_set_eq_univ.ge - obtain ⟨i, fi⟩ := IsCofiltered.inf_objs_exists (s.image j) - replace fi : ∀ k ∈ s, i ⟶ j k := fun k hk ↦ (fi (Finset.mem_image_of_mem _ hk)).some - obtain ⟨k, fkj, e⟩ := exists_map_eq_top D c hc (⨆ (k) (hk : k ∈ s), D.map (fi k hk) ⁻¹ᵁ V k) (by - simp_rw [Hom.preimage_iSup, ← Hom.comp_preimage, c.w, hVU] - exact top_le_iff.mp fun x _ ↦ by simpa using hs (Set.mem_univ x)) - refine ⟨k, s, fun x ↦ D.map (fkj ≫ fi x.1 x.2) ⁻¹ᵁ V _, ?_, fun k ↦ ⟨(hV k).preimage _, ?_⟩⟩ - · refine top_le_iff.mp (e.symm.trans_le ?_) - simp_rw [Hom.preimage_iSup, ← Hom.comp_preimage, iSup_subtype, ← D.map_comp] - simp - · rw [← hVU, ← Hom.comp_preimage, c.w] + have hU : IsOpenCover fun j : s ↦ U ↑j := by + simpa only [IsOpenCover, eq_top_iff, ← SetLike.coe_subset_coe, Opens.coe_top, Opens.iSup_mk, + Opens.carrier_eq_coe, Opens.coe_mk, Set.iUnion_subtype] + obtain ⟨i, V, hV, heq⟩ := Scheme.exists_isOpenCover_and_isAffine_of_finite _ _ hc _ hU (hU' ·) + use i, s, V, hV + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +include hc in +/-- Variant of `Scheme.exists_isOpenCover_and_isAffine_of_finite` in terms of `Scheme.OpenCover`. -/ +lemma Scheme.OpenCover.exists_of_isCofiltered_of_finite [IsCofiltered I] + [∀ {i j} (f : i ⟶ j), IsAffineHom (D.map f)] [∀ (i : I), CompactSpace (D.obj i)] + [∀ (i : I), QuasiSeparatedSpace (D.obj i)] + (𝒰 : OpenCover.{w} c.pt) [∀ i, IsAffine (𝒰.X i)] [Finite 𝒰.I₀] : + ∃ (i : I) (R : 𝒰.I₀ → CommRingCat.{u}) (f : ∀ (a : 𝒰.I₀), Spec (R a) ⟶ (D.obj i)) + (_ : Presieve.ofArrows _ f ∈ zariskiPrecoverage _) (g : ∀ (j : 𝒰.I₀), 𝒰.X j ⟶ Spec (R j)), + ∀ (j : 𝒰.I₀), IsPullback (g j) (𝒰.f j) (f j) (c.π.app i) := by + obtain ⟨i, V, hV, hV'⟩ := Scheme.exists_isOpenCover_and_isAffine_of_finite _ _ hc _ + 𝒰.isOpenCover_opensRange fun k ↦ isAffineOpen_opensRange (𝒰.f k) + have hV'' (k) := dsimp% congr($((hV' k).right).carrier) + refine ⟨i, fun k ↦ Γ(_, V k), fun k ↦ (hV' k).left.isoSpec.inv ≫ (V k).ι, ?_, ?_, ?_⟩ + · simp only [IsAffineOpen.isoSpec_inv_ι, ofArrows_mem_precoverage_iff, + IsAffineOpen.range_fromSpec, SetLike.mem_coe] + exact ⟨fun x ↦ hV.exists_mem x, inferInstance⟩ + · intro k + exact IsOpenImmersion.lift (V k).ι (𝒰.f _ ≫ c.π.app i) (by simp [hV'', Set.range_comp]) ≫ + (hV' k).left.isoSpec.hom + · intro k + dsimp + refine ⟨⟨?_⟩, ⟨PullbackCone.IsLimit.mk _ ?_ ?_ ?_ ?_⟩⟩ + · simp [← IsAffineOpen.isoSpec_inv_ι] + · intro s + refine IsOpenImmersion.lift (𝒰.f k) s.snd ?_ + simp only [hV'', Set.range_subset_iff, Set.mem_preimage, SetLike.mem_coe] + intro y + rw [← Scheme.Hom.comp_apply, ← s.condition] + simp [← IsAffineOpen.isoSpec_inv_ι] + · simp [← cancel_mono (hV' _).left.isoSpec.inv, ← cancel_mono (V k).ι, PullbackCone.condition] + · simp + · simp [← cancel_mono (𝒰.f k)] end IsAffine @@ -1283,6 +1337,36 @@ lemma Scheme.exists_π_app_comp_eq_of_locallyOfFinitePresentation · refine 𝒲.hom_ext _ _ fun j ↦ ?_ simp [F, Cover.ι_glueMorphisms_assoc, hak]; rfl +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- `Hom_S(-, X)` sends a cofiltered limit of qcqs `S`-schemes with affine transition maps +to a filtered colimit if `X` is locally of finite presentation over `X`. -/ +instance Scheme.preservesColimit_yoneda (D : I ⥤ Over S) [IsCofiltered I] + [∀ {i j} (f : i ⟶ j), IsAffineHom (D.map f).left] + [∀ (i : I), CompactSpace (D.obj i).left] [∀ (i : I), QuasiSeparatedSpace (D.obj i).left] + (X : Over S) [LocallyOfFinitePresentation X.hom] : + PreservesColimit D.op (yoneda.obj X) where + preserves {c hc} := by + rw [Limits.Types.isColimit_iff_coconeTypesIsColimit] + have (i : I) : CompactSpace ((D ⋙ Over.forget S).obj i) := by dsimp; infer_instance + have (i : I) : QuasiSeparatedSpace ((D ⋙ Over.forget S).obj i) := by dsimp; infer_instance + have {i j : I} (f : i ⟶ j) : IsAffineHom ((D ⋙ Over.forget S).map f) := by + dsimp; infer_instance + refine ⟨⟨?_, ?_⟩⟩ + · rw [Functor.CoconeTypes.descColimitType_injective_iff_of_isFiltered'] + intro k g₁ g₂ hg + obtain ⟨k, hik, heq⟩ := Scheme.exists_hom_comp_eq_comp_of_locallyOfFiniteType + (D ⋙ Over.forget _) (.mk (fun _ ↦ (D.obj _).hom)) X.hom _ (isLimitOfPreserves _ hc.unop) + g₁.left g₂.left (Over.w g₁).symm (Over.w g₂).symm congr($(hg).left) + use .op k, hik.op + cat_disch + · intro g + obtain ⟨k, u, h, h'⟩ := Scheme.exists_π_app_comp_eq_of_locallyOfFinitePresentation + (D ⋙ Over.forget _) (.mk (fun _ ↦ (D.obj _).hom)) X.hom _ (isLimitOfPreserves _ hc.unop) + g.left (by ext; simp) + use Functor.ιColimitType _ (.op k) (Over.homMk u) + cat_disch + end LocallyOfFinitePresentation end AlgebraicGeometry From 598d514da0055c5d4d63a6d268dbdb61574f42ee Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Wed, 17 Jun 2026 07:42:24 +0000 Subject: [PATCH 0100/1300] chore: refactor the vector measure integral by changing the reference measure (#40603) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given a bilinear form `B` on `E x F` to `G`, a function `f` with values in `E` and a vector measure `v` with values in `F`, the integral wrt the vector measure is defined when the function is integrable wrt the measure `(v.transpose B).variation`, which is the minimal condition for the integral to make sense. I have played a lot recently with integrals for vector measures, and I have realized that assuming this minimal condition creates a lot of complications, for essentially no gain. In this PR, I require the stronger condition that the function is integrable wrt `v.variation`. So, the integrability condition does not depend on `B` any more. This makes for smoother statements and smoother proofs (especially in the forthcoming Fubini theorem). In all standard applications, `B` is an isometry, so `(v.transpose B).variation = v.variation`, and the theory is unchanged. Note that the new approach does not lose any generality: in the unlikely event one wants to integrate a function which is only integrable wrt `(v.transpose B).variation` for some exotic `B`, then one can integrate with the vector measure `v.transpose B` (which takes values in `E -> G`) and the bilinear form which is the function application, i.e., `E -> (E -> G) -> G`. Zulip discussion at [#mathlib4 > Refactoring vector measure integral @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Refactoring.20vector.20measure.20integral/near/603283077). Everyone seems to agree the refactor is a good idea. Co-authored-by: sgouezel --- Mathlib/Data/NNReal/Defs.lean | 2 + .../MeasureTheory/VectorMeasure/Integral.lean | 393 ++++++++++-------- .../VectorMeasure/Variation/Basic.lean | 3 +- 3 files changed, 216 insertions(+), 182 deletions(-) diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index 612791983d60ef..41e15f10ecf1e6 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -127,6 +127,8 @@ noncomputable instance : LinearOrderedCommGroupWithZero ℝ≥0 where example {p q : ℝ≥0} (h1p : 0 < p) (h2p : p ≤ q) : q⁻¹ ≤ p⁻¹ := by with_reducible_and_instances exact inv_anti₀ h1p h2p +@[simp] lemma mk_coe (a : ℝ≥0) (ha : 0 ≤ (a : ℝ)) : NNReal.mk (a : ℝ) ha = a := rfl + -- Simp lemma to put back `n.val` into the normal form given by the coercion. @[simp] theorem val_eq_coe (n : ℝ≥0) : n.val = n := diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index 9c96314769d4c9..bc0a720f0b4a69 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -58,7 +58,7 @@ We often consider integrable functions with respect to the total variation of `μ.transpose B` = `μ.mapRange B.flip.toAddMonoidHom B.flip.continuous`, which is the reference measure for the pairing integral. -When `f` is not integrable with respect to `(μ.transpose B).variation`, the value of +When `f` is not integrable with respect to `μ.variation`, the value of `μ.integral B f` is set to `0`. This is an analogous convention to the Bochner integral. However, there are cases where a natural definition of the integral as an unconditional sum exists, but `f` is not integrable in this sense: Let `μ` be the `L∞(ℕ)`-valued measure on `ℕ` defined by extending @@ -73,10 +73,11 @@ public section open Set MeasureTheory VectorMeasure ContinuousLinearMap Filter Topology open scoped ENNReal NNReal -variable {ι X Y E F G : Type*} {mX : MeasurableSpace X} [MeasurableSpace Y] +variable {ι X Y E F G H : Type*} {mX : MeasurableSpace X} [MeasurableSpace Y] [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedAddCommGroup G] [NormedSpace ℝ G] + [NormedAddCommGroup H] [NormedSpace ℝ H] namespace MeasureTheory @@ -112,17 +113,25 @@ theorem cbmApplyMeasure_union (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ ext x simp [of_union hdisj hs ht] -theorem dominatedFinMeasAdditive_cbmApplyMeasure (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : - DominatedFinMeasAdditive (μ.transpose B).variation (μ.transpose B) 1 := by - refine ⟨fun s t hs ht _ _ hdisj ↦ cbmApplyMeasure_union μ B hs ht hdisj, fun s hs hsf ↦ ?_⟩ - simpa using! norm_measure_le_variation hsf.ne - theorem norm_cbmApplyMeasure_le (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) (s : Set X) : ‖cbmApplyMeasure μ B s‖ ≤ ‖B‖ * ‖μ s‖ := by rw [opNorm_le_iff (by positivity)] intro x grw [cbmApplyMeasure_apply, le_opNorm₂, mul_right_comm] +theorem dominatedFinMeasAdditive_cbmApplyMeasure (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : + DominatedFinMeasAdditive μ.variation (μ.transpose B) ‖B‖ := by + refine ⟨fun s t hs ht _ _ hdisj ↦ cbmApplyMeasure_union μ B hs ht hdisj, fun s hs hsf ↦ ?_⟩ + apply (norm_cbmApplyMeasure_le _ _ _).trans + gcongr + exact norm_measure_le_variation hsf.ne + +theorem dominatedFinMeasAdditive_transpose_cbmApplyMeasure + (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : + DominatedFinMeasAdditive (μ.transpose B).variation (μ.transpose B) 1 := by + refine ⟨fun s t hs ht _ _ hdisj ↦ cbmApplyMeasure_union μ B hs ht hdisj, fun s hs hsf ↦ ?_⟩ + simpa using! norm_measure_le_variation hsf.ne + end cbmApplyMeasure namespace VectorMeasure @@ -221,15 +230,15 @@ function with respect to a signed measure. -/ /-- `f : X → E` is said to be integrable with respect to `μ` and `B` if it is integrable with respect to `(μ.transpose B).variation`. -/ -protected abbrev Integrable (μ : VectorMeasure X F) (f : X → E) (B : E →L[ℝ] F →L[ℝ] G) : Prop := - MeasureTheory.Integrable f (μ.transpose B).variation +protected abbrev Integrable (μ : VectorMeasure X F) (f : X → E) : Prop := + MeasureTheory.Integrable f μ.variation /-- `f : X → E` is said to be integrable with respect to `μ` and `B` on `s` if it is integrable with respect to the vector measure `μ.restrict s`. When `s` is measurable, this is equivalent to integrability with respect to `(μ.transpose B).variation.restrict s`. -/ protected abbrev IntegrableOn - (μ : VectorMeasure X F) (f : X → E) (B : E →L[ℝ] F →L[ℝ] G) (s : Set X) : Prop := - (μ.restrict s).Integrable f B + (μ : VectorMeasure X F) (f : X → E) (s : Set X) : Prop := + (μ.restrict s).Integrable f open Classical in /-- The `G`-valued integral of `E`-valued function and the `F`-valued vector measure `μ` with linear @@ -242,7 +251,7 @@ When `μ` is a signed measure, to get the integral in `G` of a `G`-valued functi `B = (ContinousLinearMap.lsmul ℝ ℝ).flip`. Notation `∫ᵛ x, f x ∂<•μ`. -/ noncomputable def integral (μ : VectorMeasure X F) (f : X → E) (B : E →L[ℝ] F →L[ℝ] G) : G := - setToFun (μ.transpose B).variation (μ.transpose B) + setToFun μ.variation (μ.transpose B) (dominatedFinMeasAdditive_cbmApplyMeasure μ B) f @[inherit_doc integral] @@ -274,9 +283,14 @@ notation3 "∫ᵛ "(...)" in "s", "r:60:(scoped f => f)" ∂<•"μ:70 => variable {μ ν B} -lemma integral_eq_setToFun : ∫ᵛ x, f x ∂[B; μ] = setToFun (μ.transpose B).variation (μ.transpose B) +lemma integral_eq_setToFun : ∫ᵛ x, f x ∂[B; μ] = setToFun μ.variation (μ.transpose B) (dominatedFinMeasAdditive_cbmApplyMeasure μ B) f := by rfl +lemma integral_eq_setToFun_transpose (hf : μ.Integrable f) : + ∫ᵛ x, f x ∂[B; μ] = setToFun (μ.transpose B).variation (μ.transpose B) + (dominatedFinMeasAdditive_transpose_cbmApplyMeasure μ B) f := + setToFun_congr_measure_of_integrable _ (by simp) (variation_transpose_le _ _) _ _ _ hf + theorem integral_of_not_completeSpace (hG : ¬CompleteSpace G) : ∫ᵛ x, f x ∂[B; μ] = 0 := by simp [integral, setToFun, hG] @@ -343,7 +357,7 @@ theorem transpose_sub_cbm (μ : VectorMeasure X F) (B C : E →L[ℝ] F →L[ℝ section Function -theorem integral_undef (h : ¬ μ.Integrable f B) : +theorem integral_undef (h : ¬ μ.Integrable f) : ∫ᵛ x, f x ∂[B; μ] = 0 := by simp [integral, setToFun_undef _ h] @@ -351,48 +365,54 @@ theorem integral_undef (h : ¬ μ.Integrable f B) : theorem integral_zero : ∫ᵛ _, 0 ∂[B; μ] = 0 := setToFun_zero _ -theorem integral_congr_ae (h : f =ᵐ[(μ.transpose B).variation] g) : +theorem integral_congr_ae (h : f =ᵐ[μ.variation] g) : ∫ᵛ x, f x ∂[B; μ] = ∫ᵛ x, g x ∂[B; μ] := setToFun_congr_ae _ h -theorem integral_eq_zero_of_ae (hf : f =ᵐ[(μ.transpose B).variation] 0) : +theorem integral_eq_zero_of_ae (hf : f =ᵐ[μ.variation] 0) : ∫ᵛ x, f x ∂[B; μ] = 0 := by simp [integral_congr_ae hf] -@[to_fun] lemma Integrable.add (hf : μ.Integrable f B) (hg : μ.Integrable g B) : - μ.Integrable (f + g) B := +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +@[to_fun] lemma Integrable.add (hf : μ.Integrable f) (hg : μ.Integrable g) : + μ.Integrable (f + g) := MeasureTheory.Integrable.add hf hg -@[to_fun] lemma Integrable.neg (hf : μ.Integrable f B) : - μ.Integrable (-f) B := +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +@[to_fun] lemma Integrable.neg (hf : μ.Integrable f) : + μ.Integrable (-f) := MeasureTheory.Integrable.neg hf -@[to_fun] lemma Integrable.sub (hf : μ.Integrable f B) (hg : μ.Integrable g B) : - μ.Integrable (f - g) B := +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +@[to_fun] lemma Integrable.sub (hf : μ.Integrable f) (hg : μ.Integrable g) : + μ.Integrable (f - g) := MeasureTheory.Integrable.sub hf hg +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in @[to_fun] lemma Integrable.smul {𝕜 : Type*} [NormedAddCommGroup 𝕜] [SMulZeroClass 𝕜 E] - [IsBoundedSMul 𝕜 E] (c : 𝕜) (hf : μ.Integrable f B) : - μ.Integrable (c • f) B := + [IsBoundedSMul 𝕜 E] (c : 𝕜) (hf : μ.Integrable f) : + μ.Integrable (c • f) := MeasureTheory.Integrable.smul c hf +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in theorem Integrable.finsetSum {ι : Type*} (s : Finset ι) {f : ι → X → E} - (hf : ∀ i ∈ s, μ.Integrable (f i) B) : μ.Integrable (∑ i ∈ s, f i) B := + (hf : ∀ i ∈ s, μ.Integrable (f i)) : μ.Integrable (∑ i ∈ s, f i) := integrable_finsetSum' s hf +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in theorem Integrable.fun_finsetSum {ι : Type*} (s : Finset ι) {f : ι → X → E} - (hf : ∀ i ∈ s, μ.Integrable (f i) B) : μ.Integrable (fun x ↦ ∑ i ∈ s, f i x) B := + (hf : ∀ i ∈ s, μ.Integrable (f i)) : μ.Integrable (fun x ↦ ∑ i ∈ s, f i x) := integrable_finsetSum s hf -theorem integral_fun_add (hf : μ.Integrable f B) (hg : μ.Integrable g B) : +theorem integral_fun_add (hf : μ.Integrable f) (hg : μ.Integrable g) : ∫ᵛ x, f x + g x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, g x ∂[B; μ] := setToFun_add _ hf hg -theorem integral_add (hf : μ.Integrable f B) (hg : μ.Integrable g B) : +theorem integral_add (hf : μ.Integrable f) (hg : μ.Integrable g) : ∫ᵛ x, (f + g) x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, g x ∂[B; μ] := integral_fun_add hf hg theorem integral_finsetSum (s : Finset ι) {f : ι → X → E} - (hf : ∀ i ∈ s, μ.Integrable (f i) B) : + (hf : ∀ i ∈ s, μ.Integrable (f i)) : ∫ᵛ x, ∑ i ∈ s, f i x ∂[B; μ] = ∑ i ∈ s, ∫ᵛ x, f i x ∂[B; μ] := setToFun_finsetSum _ s hf @@ -407,11 +427,11 @@ variable (f μ B) in theorem integral_neg : ∫ᵛ x, (-f) x ∂[B; μ] = -∫ᵛ x, f x ∂[B; μ] := integral_fun_neg μ B f -theorem integral_fun_sub (hf : μ.Integrable f B) (hg : μ.Integrable g B) : +theorem integral_fun_sub (hf : μ.Integrable f) (hg : μ.Integrable g) : ∫ᵛ x, f x - g x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x, g x ∂[B; μ] := setToFun_sub _ hf hg -theorem integral_sub (hf : μ.Integrable f B) (hg : μ.Integrable g B) : +theorem integral_sub (hf : μ.Integrable f) (hg : μ.Integrable g) : ∫ᵛ x, (f - g) x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x, g x ∂[B; μ] := integral_fun_sub hf hg variable (f μ B) in @@ -426,7 +446,7 @@ theorem integral_smul (c : ℝ) : ∫ᵛ x, (c • f) x ∂[B; μ] = c • ∫ᵛ x, f x ∂[B; μ] := integral_fun_smul μ B c f @[simp] -theorem integral_const [CompleteSpace G] [IsFiniteMeasure (μ.transpose B).variation] (c : E) : +theorem integral_const [CompleteSpace G] [IsFiniteMeasure μ.variation] (c : E) : ∫ᵛ _ : X, c ∂[B; μ] = B c (μ univ) := setToFun_const _ _ @@ -434,34 +454,40 @@ end Function section VectorMeasure +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in /- `simpNF` complains that this lemma can be proved by `simp`, because the `simp`-generated lemma unfolds the abbrev `VectorMeasure.Integrable`. TODO: fix `simp`. See lean4#13958. -/ @[nolint simpNF, simp] -lemma Integrable.zero_vectorMeasure : (0 : VectorMeasure X F).Integrable f B := by +lemma Integrable.zero_vectorMeasure : (0 : VectorMeasure X F).Integrable f := by simp [VectorMeasure.Integrable] -lemma Integrable.add_vectorMeasure (hμ : μ.Integrable f B) (hν : ν.Integrable f B) : - (μ + ν).Integrable f B := by +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +lemma Integrable.add_vectorMeasure (hμ : μ.Integrable f) (hν : ν.Integrable f) : + (μ + ν).Integrable f := by apply Integrable.mono_measure (integrable_add_measure.2 ⟨hμ, hν⟩) - grw [transpose_add, variation_add_le] + grw [variation_add_le] -lemma Integrable.neg_vectorMeasure (hμ : μ.Integrable f B) : - (-μ).Integrable f B := +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +lemma Integrable.neg_vectorMeasure (hμ : μ.Integrable f) : + (-μ).Integrable f := Integrable.mono_measure hμ (by simp) -lemma Integrable.sub_vectorMeasure (hμ : μ.Integrable f B) (hν : ν.Integrable f B) : - (μ - ν).Integrable f B := by +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +lemma Integrable.sub_vectorMeasure (hμ : μ.Integrable f) (hν : ν.Integrable f) : + (μ - ν).Integrable f := by convert hμ.add_vectorMeasure hν.neg_vectorMeasure using 1 exact sub_eq_add_neg μ ν -lemma Integrable.smul_vectorMeasure (hμ : μ.Integrable f B) (c : ℝ) : - (c • μ).Integrable f B := by +omit [NormedSpace ℝ E] in +lemma Integrable.smul_vectorMeasure (hμ : μ.Integrable f) (c : ℝ) : + (c • μ).Integrable f := by apply Integrable.mono_measure (Integrable.smul_measure_nnreal hμ (c := ‖c‖₊)) - simp [transpose_smul, variation_smul] + simp [variation_smul] +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in lemma Integrable.finsetSum_vectorMeasure {ι : Type*} {μ : ι → VectorMeasure X F} {s : Finset ι} - (h : ∀ i ∈ s, (μ i).Integrable f B) : - (∑ i ∈ s, μ i).Integrable f B := by + (h : ∀ i ∈ s, (μ i).Integrable f) : + (∑ i ∈ s, μ i).Integrable f := by classical induction s using Finset.induction_on with | empty => simp @@ -470,8 +496,9 @@ lemma Integrable.finsetSum_vectorMeasure {ι : Type*} {μ : ι → VectorMeasure Finset.sum_insert] at h ⊢ exact h.1.add_vectorMeasure (ih h.2) -lemma Integrable.restrict (hf : μ.Integrable f B) {s : Set X} : - (μ.restrict s).Integrable f B := by +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in +lemma Integrable.restrict (hf : μ.Integrable f) {s : Set X} : + (μ.restrict s).Integrable f := by by_cases hs : MeasurableSet s · simpa [VectorMeasure.Integrable, transpose_restrict, variation_restrict hs] using MeasureTheory.Integrable.restrict hf @@ -489,12 +516,12 @@ theorem integral_smul_vectorMeasure (f : X → E) (c : ℝ) : by_cases hG : CompleteSpace G; swap · simp [integral, setToFun, hG] simp_rw [integral, ← setToFun_smul_left] - have : ((c • μ).transpose B).variation = ‖c‖₊ • (μ.transpose B).variation := by - simp [transpose, mapRange_smul, variation_smul] - simp only [this, mul_one] - have : DominatedFinMeasAdditive (μ.transpose B).variation ((c • μ).transpose B) ‖c‖ := by - simp only [transpose_smul, FunLike.coe_smul, Real.norm_eq_abs] - simpa using! (dominatedFinMeasAdditive_cbmApplyMeasure μ B).smul c + have : (c • μ).variation = ‖c‖₊ • μ.variation := by + simp [variation_smul] + simp only [this] + have : DominatedFinMeasAdditive μ.variation ((c • μ).transpose B) (‖c‖ * ‖B‖) := by + simp only [transpose_smul, FunLike.coe_smul] + exact (dominatedFinMeasAdditive_cbmApplyMeasure μ B).smul c rw! [← setToFun_congr_smul_measure' _ this, transpose_smul] rfl @@ -503,13 +530,13 @@ theorem integral_smul_nnreal_vectorMeasure (f : X → E) (c : ℝ≥0) : ∫ᵛ x, f x ∂[B; c • μ] = c • ∫ᵛ x, f x ∂[B; μ] := integral_smul_vectorMeasure f (c : ℝ) -theorem integral_add_vectorMeasure (hμ : μ.Integrable f B) (hν : ν.Integrable f B) : +theorem integral_add_vectorMeasure (hμ : μ.Integrable f) (hν : ν.Integrable f) : ∫ᵛ x, f x ∂[B; μ + ν] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, f x ∂[B; ν] := - setToFun_add_left'' (by simp [transpose]) hμ hν (by grw [transpose_add, variation_add_le]) - zero_le_one zero_le_one zero_le_one + setToFun_add_left'' (by simp [transpose]) hμ hν (by grw [variation_add_le]) + (norm_nonneg _) (norm_nonneg _) (norm_nonneg _) theorem integral_finsetSum_vectorMeasure {μ : ι → VectorMeasure X F} - {s : Finset ι} (hf : ∀ i ∈ s, (μ i).Integrable f B) : + {s : Finset ι} (hf : ∀ i ∈ s, (μ i).Integrable f) : ∫ᵛ x, f x ∂[B; ∑ i ∈ s, μ i] = ∑ i ∈ s, ∫ᵛ x, f x ∂[B; μ i] := by classical induction s using Finset.induction_on with @@ -524,7 +551,7 @@ theorem integral_neg_vectorMeasure : ∫ᵛ x, f x ∂[B; -μ] = -∫ᵛ x, f x ∂[B; μ] := by simp [integral, ← setToFun_neg', FunLike.coe_neg] -theorem integral_sub_vectorMeasure (hμ : μ.Integrable f B) (hν : ν.Integrable f B) : +theorem integral_sub_vectorMeasure (hμ : μ.Integrable f) (hν : ν.Integrable f) : ∫ᵛ x, f x ∂[B; μ - ν] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x, f x ∂[B; ν] := by rw [sub_eq_add_neg, integral_add_vectorMeasure hμ hν.neg_vectorMeasure, integral_neg_vectorMeasure, ← sub_eq_add_neg] @@ -533,76 +560,46 @@ end VectorMeasure section cbm -/- `simpNF` complains that this lemma can be proved by `simp`, because the `simp`-generated lemma -unfolds the abbrev `VectorMeasure.Integrable`. TODO: fix `simp`. See lean4#13958. -/ -@[nolint simpNF, simp] -lemma Integrable.zero_cbm : μ.Integrable f (0 : E →L[ℝ] F →L[ℝ] G) := by - simp [VectorMeasure.Integrable] - -lemma Integrable.add_cbm (hB : μ.Integrable f B) (hC : μ.Integrable f C) : - μ.Integrable f (B + C) := by - apply Integrable.mono_measure (integrable_add_measure.2 ⟨hB, hC⟩) - grw [transpose_add_cbm, variation_add_le] - -lemma Integrable.neg_cbm (hB : μ.Integrable f B) : - μ.Integrable f (-B) := by - apply Integrable.mono_measure hB - simp - -lemma Integrable.sub_cbm (hB : μ.Integrable f B) (hC : μ.Integrable f C) : - μ.Integrable f (B - C) := by - convert hB.add_cbm hC.neg_cbm using 1 - exact sub_eq_add_neg B C - -lemma Integrable.finsetSum_cbm {ι : Type*} {B : ι → E →L[ℝ] F →L[ℝ] G} {s : Finset ι} - (h : ∀ i ∈ s, μ.Integrable f (B i)) : μ.Integrable f (∑ i ∈ s, B i) := by - classical - induction s using Finset.induction_on with - | empty => simp - | insert a s ha ih => - simp only [Finset.mem_insert, forall_eq_or_imp, ha, not_false_eq_true, - Finset.sum_insert] at h ⊢ - exact h.1.add_cbm (ih h.2) - variable (f μ) in @[simp] theorem integral_zero_cbm : ∫ᵛ x, f x ∂[(0 : E →L[ℝ] F →L[ℝ] G); μ] = 0 := by simp [integral, FunLike.coe_zero] -theorem integral_add_cbm (hB : μ.Integrable f B) (hC : μ.Integrable f C) : - ∫ᵛ x, f x ∂[B + C; μ] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, f x ∂[C; μ] := - setToFun_add_left'' (by simp [transpose]) hB hC (by simp [variation_add_le]) - zero_le_one zero_le_one zero_le_one +theorem integral_add_cbm (hB : μ.Integrable f) : + ∫ᵛ x, f x ∂[B + C; μ] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, f x ∂[C; μ] := by + refine setToFun_add_left'' (by simp [transpose]) hB hB ?_ + (norm_nonneg _) (norm_nonneg _) (norm_nonneg _) + nth_rw 1 [← add_zero μ.variation] + gcongr + exact Measure.zero_le μ.variation theorem integral_finsetSum_cbm {B : ι → E →L[ℝ] F →L[ℝ] G} - {s : Finset ι} (hf : ∀ i ∈ s, μ.Integrable f (B i)) : + {s : Finset ι} (hf : μ.Integrable f) : ∫ᵛ x, f x ∂[∑ i ∈ s, B i; μ] = ∑ i ∈ s, ∫ᵛ x, f x ∂[B i; μ] := by classical induction s using Finset.induction_on with | empty => simp | insert a s ha ih => - simp only [Finset.mem_insert, forall_eq_or_imp, ha, not_false_eq_true, - Finset.sum_insert] at hf ⊢ - rw [integral_add_cbm hf.1 (Integrable.finsetSum_cbm hf.2), ih hf.2] + simp only [ha, not_false_eq_true, Finset.sum_insert] + rw [integral_add_cbm hf, ih] @[integral_simps] theorem integral_neg_cbm : ∫ᵛ x, f x ∂[-B; μ] = -∫ᵛ x, f x ∂[B; μ] := by simp [integral, ← setToFun_neg', FunLike.coe_neg] -theorem integral_sub_cbm (hB : μ.Integrable f B) (hC : μ.Integrable f C) : +theorem integral_sub_cbm (hB : μ.Integrable f) : ∫ᵛ x, f x ∂[B - C; μ] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x, f x ∂[C; μ] := by rw [sub_eq_add_neg, integral_add_cbm hB, integral_neg_cbm, ← sub_eq_add_neg] - simpa [VectorMeasure.Integrable] using hC end cbm -theorem Integrable.of_integral_ne_zero (h : ∫ᵛ a, f a ∂[B; μ] ≠ 0) : μ.Integrable f B := +theorem Integrable.of_integral_ne_zero (h : ∫ᵛ a, f a ∂[B; μ] ≠ 0) : μ.Integrable f := Not.imp_symm integral_undef h theorem integral_non_aestronglyMeasurable {f : X → E} - (h : ¬AEStronglyMeasurable f (μ.transpose B).variation) : + (h : ¬AEStronglyMeasurable f μ.variation) : ∫ᵛ a, f a ∂[B; μ] = 0 := integral_undef <| not_and_of_not_left _ h @@ -610,28 +607,56 @@ lemma integral_indicator₂ {β : Type*} (f : β → X → E) (s : Set β) (b : ∫ᵛ y, s.indicator (f · y) b ∂[B; μ] = s.indicator (fun x ↦ ∫ᵛ y, f x y ∂[B; μ]) b := by by_cases hb : b ∈ s <;> simp [hb] +@[fun_prop] +theorem continuous_integral : Continuous fun f : X →₁[μ.variation] E => ∫ᵛ a, f a ∂[B; μ] := by + simp only [integral_eq_setToFun] + exact continuous_setToFun _ + theorem norm_integral_le_lintegral_norm : - ‖∫ᵛ a, f a ∂[B; μ]‖ ≤ ENNReal.toReal (∫⁻ a, ENNReal.ofReal ‖f a‖ ∂(μ.transpose B).variation) := + ‖∫ᵛ a, f a ∂[B; μ]‖ ≤ ‖B‖ * ENNReal.toReal (∫⁻ a, ENNReal.ofReal ‖f a‖ ∂μ.variation) := (norm_setToFun_le_toReal _ (by simp)).trans (by simp) -theorem enorm_integral_le_lintegral_enorm : - ‖∫ᵛ a, f a ∂[B; μ]‖ₑ ≤ ∫⁻ a, ‖f a‖ₑ ∂(μ.transpose B).variation := - (enorm_setToFun_le _ (by simp)).trans (by simp) +theorem norm_integral_le_integral_norm : + ‖∫ᵛ a, f a ∂[B; μ]‖ ≤ ‖B‖ * ∫ a, ‖f a‖ ∂μ.variation := by + have le_ae : ∀ᵐ a ∂μ.variation, 0 ≤ ‖f a‖ := + Eventually.of_forall fun a => norm_nonneg _ + by_cases h : AEStronglyMeasurable f μ.variation + · calc ‖∫ᵛ a, f a ∂[B; μ]‖ + _ ≤ ‖B‖ * ENNReal.toReal (∫⁻ a, ENNReal.ofReal ‖f a‖ ∂μ.variation) := + norm_integral_le_lintegral_norm + _ = ‖B‖ * ∫ a, ‖f a‖ ∂μ.variation := by + rw [integral_eq_lintegral_of_nonneg_ae le_ae <| h.norm] + · rw [integral_non_aestronglyMeasurable h, norm_zero] + positivity -theorem dist_integral_le_lintegral_edist (hf : μ.Integrable f B) (hg : μ.Integrable g B) : +theorem enorm_integral_le_lintegral_enorm : + ‖∫ᵛ a, f a ∂[B; μ]‖ₑ ≤ ‖B‖ₑ * ∫⁻ a, ‖f a‖ₑ ∂μ.variation := by + apply (enorm_setToFun_le _ (by simp)).trans + gcongr + simp [← coe_nnnorm] + +theorem enorm_integral_le_lintegral_enorm_transpose : + ‖∫ᵛ a, f a ∂[B; μ]‖ₑ ≤ ∫⁻ a, ‖f a‖ₑ ∂(μ.transpose B).variation := by + by_cases hf : μ.Integrable f + · rw [integral_eq_setToFun_transpose hf] + apply (enorm_setToFun_le _ (by simp)).trans (by simp) + · simp [integral_undef hf] + +theorem dist_integral_le_lintegral_edist (hf : μ.Integrable f) (hg : μ.Integrable g) : dist (∫ᵛ a, f a ∂[B; μ]) (∫ᵛ a, g a ∂[B; μ]) ≤ - (∫⁻ a, edist (f a) (g a) ∂(μ.transpose B).variation).toReal := by + ‖B‖ * (∫⁻ a, edist (f a) (g a) ∂μ.variation).toReal := by grw [dist_eq_norm, ← integral_sub hf hg, norm_integral_le_lintegral_norm] simp [edist_eq_enorm_sub] -theorem edist_integral_le_lintegral_edist (hf : μ.Integrable f B) (hg : μ.Integrable g B) : +theorem edist_integral_le_lintegral_edist (hf : μ.Integrable f) (hg : μ.Integrable g) : edist (∫ᵛ a, f a ∂[B; μ]) (∫ᵛ a, g a ∂[B; μ]) ≤ - ∫⁻ a, edist (f a) (g a) ∂(μ.transpose B).variation := by + ‖B‖ₑ * ∫⁻ a, edist (f a) (g a) ∂μ.variation := by rw [edist_dist] - exact ENNReal.ofReal_le_of_le_toReal (dist_integral_le_lintegral_edist hf hg) + apply ENNReal.ofReal_le_of_le_toReal + grw [dist_integral_le_lintegral_edist hf hg, ENNReal.toReal_mul, toReal_enorm] theorem frequently_ae_ne_zero_of_integral_ne_zero - (h : ∫ᵛ a, f a ∂[B; μ] ≠ 0) : ∃ᶠ a in ae (μ.transpose B).variation, f a ≠ 0 := + (h : ∫ᵛ a, f a ∂[B; μ] ≠ 0) : ∃ᶠ a in ae μ.variation, f a ≠ 0 := fun h' ↦ h (integral_eq_zero_of_ae (h'.mono fun _ ↦ not_not.mp)) theorem exists_ne_zero_of_integral_ne_zero @@ -643,7 +668,7 @@ theorem exists_ne_zero_of_integral_ne_zero rcases subsingleton_or_nontrivial G with h'G | h'G · apply Subsingleton.elim rw [integral_eq_setToFun, MeasureTheory.integral_eq_setToFun] - simp only [variation_transpose_lsmul_flip, variation_toSignedMeasure] + simp only [Measure.variation_toSignedMeasure] apply setToFun_congr_left' _ _ (fun s hs h's ↦ ?_) simp only [transpose, ContinuousLinearMap.flip_flip, mapRange_apply, Measure.toSignedMeasure_apply_measurable hs, LinearMap.toAddMonoidHom_coe, @@ -662,7 +687,7 @@ theorem integral_dirac' [MeasurableSpace X] [CompleteSpace G] {a : X} {v : F} calc ∫ᵛ x, f x ∂[B; VectorMeasure.dirac a v] = ∫ᵛ _, f a ∂[B; VectorMeasure.dirac a v] := by apply integral_congr_ae - simp only [transpose_dirac, variation_dirac] + simp only [variation_dirac] exact Measure.ae_smul_measure (ae_eq_dirac' hfm.measurable) _ _ = B (f a) v := by simp @@ -677,7 +702,7 @@ theorem integral_dirac [MeasurableSpace X] [MeasurableSingletonClass X] [Complet calc ∫ᵛ x, f x ∂[B; VectorMeasure.dirac a v] = ∫ᵛ _, f a ∂[B; VectorMeasure.dirac a v] := by apply integral_congr_ae - simp only [transpose_dirac, variation_dirac] + simp only [variation_dirac] exact Measure.ae_smul_measure (ae_eq_dirac f) _ _ = B (f a) v := by simp @@ -689,17 +714,17 @@ theorem integral_unique [Unique X] [CompleteSpace G] : /-- If `F i → f` in `L1`, then `∫ᵛ x, F i x ∂[B; μ] → ∫ᵛ x, f x ∂[B; μ]`. -/ theorem tendsto_integral_of_L1 {ι} (f : X → E) - (hfi : AEStronglyMeasurable f (μ.transpose B).variation) {F : ι → X → E} - {l : Filter ι} (hFi : ∀ᶠ i in l, μ.Integrable (F i) B) - (hF : Tendsto (fun i ↦ ∫⁻ x, ‖F i x - f x‖ₑ ∂(μ.transpose B).variation) l (𝓝 0)) : + (hfi : AEStronglyMeasurable f μ.variation) {F : ι → X → E} + {l : Filter ι} (hFi : ∀ᶠ i in l, μ.Integrable (F i)) + (hF : Tendsto (fun i ↦ ∫⁻ x, ‖F i x - f x‖ₑ ∂μ.variation) l (𝓝 0)) : Tendsto (fun i ↦ ∫ᵛ x, F i x ∂[B; μ]) l (𝓝 <| ∫ᵛ x, f x ∂[B; μ]) := tendsto_setToFun_of_L1 _ f hfi hFi hF /-- If `F i → f` in `L1`, then `∫ᵛ x, F i x ∂[B; μ] → ∫ᵛ x, f x ∂[B; μ]`. -/ lemma tendsto_integral_of_L1' {ι} (f : X → E) - (hfi : AEStronglyMeasurable f (μ.transpose B).variation) {F : ι → X → E} - {l : Filter ι} (hFi : ∀ᶠ i in l, μ.Integrable (F i) B) - (hF : Tendsto (fun i ↦ eLpNorm (F i - f) 1 (μ.transpose B).variation) l (𝓝 0)) : + (hfi : AEStronglyMeasurable f μ.variation) {F : ι → X → E} + {l : Filter ι} (hFi : ∀ᶠ i in l, μ.Integrable (F i)) + (hF : Tendsto (fun i ↦ eLpNorm (F i - f) 1 μ.variation) l (𝓝 0)) : Tendsto (fun i ↦ ∫ᵛ x, F i x ∂[B; μ]) l (𝓝 (∫ᵛ x, f x ∂[B; μ])) := by refine tendsto_integral_of_L1 f hfi hFi ?_ simp_rw [eLpNorm_one_eq_lintegral_enorm, Pi.sub_apply] at hF @@ -708,67 +733,72 @@ lemma tendsto_integral_of_L1' {ι} (f : X → E) variable {Y : Type*} [TopologicalSpace Y] [FirstCountableTopology Y] theorem continuousWithinAt_of_dominated {F : Y → X → E} {x₀ : Y} {bound : X → ℝ} {s : Set Y} - (hF_meas : ∀ᶠ x in 𝓝[s] x₀, AEStronglyMeasurable (F x) (μ.transpose B).variation) - (h_bound : ∀ᶠ x in 𝓝[s] x₀, ∀ᵐ a ∂(μ.transpose B).variation, ‖F x a‖ ≤ bound a) - (bound_integrable : Integrable bound (μ.transpose B).variation) - (h_cont : ∀ᵐ a ∂(μ.transpose B).variation, ContinuousWithinAt (fun x ↦ F x a) s x₀) : + (hF_meas : ∀ᶠ x in 𝓝[s] x₀, AEStronglyMeasurable (F x) μ.variation) + (h_bound : ∀ᶠ x in 𝓝[s] x₀, ∀ᵐ a ∂μ.variation, ‖F x a‖ ≤ bound a) + (bound_integrable : Integrable bound μ.variation) + (h_cont : ∀ᵐ a ∂μ.variation, ContinuousWithinAt (fun x ↦ F x a) s x₀) : ContinuousWithinAt (fun x ↦ ∫ᵛ a, F x a ∂[B; μ]) s x₀ := continuousWithinAt_setToFun_of_dominated _ hF_meas h_bound bound_integrable h_cont theorem continuousAt_of_dominated {F : Y → X → E} {x₀ : Y} {bound : X → ℝ} - (hF_meas : ∀ᶠ x in 𝓝 x₀, AEStronglyMeasurable (F x) (μ.transpose B).variation) - (h_bound : ∀ᶠ x in 𝓝 x₀, ∀ᵐ a ∂(μ.transpose B).variation, ‖F x a‖ ≤ bound a) - (bound_integrable : Integrable bound (μ.transpose B).variation) - (h_cont : ∀ᵐ a ∂(μ.transpose B).variation, ContinuousAt (fun x ↦ F x a) x₀) : + (hF_meas : ∀ᶠ x in 𝓝 x₀, AEStronglyMeasurable (F x) μ.variation) + (h_bound : ∀ᶠ x in 𝓝 x₀, ∀ᵐ a ∂μ.variation, ‖F x a‖ ≤ bound a) + (bound_integrable : Integrable bound μ.variation) + (h_cont : ∀ᵐ a ∂μ.variation, ContinuousAt (fun x ↦ F x a) x₀) : ContinuousAt (fun x ↦ ∫ᵛ a, F x a ∂[B; μ]) x₀ := continuousAt_setToFun_of_dominated _ hF_meas h_bound bound_integrable h_cont theorem continuousOn_of_dominated {F : Y → X → E} {bound : X → ℝ} {s : Set Y} - (hF_meas : ∀ x ∈ s, AEStronglyMeasurable (F x) (μ.transpose B).variation) - (h_bound : ∀ x ∈ s, ∀ᵐ a ∂(μ.transpose B).variation, ‖F x a‖ ≤ bound a) - (bound_integrable : Integrable bound (μ.transpose B).variation) - (h_cont : ∀ᵐ a ∂(μ.transpose B).variation, ContinuousOn (fun x ↦ F x a) s) : + (hF_meas : ∀ x ∈ s, AEStronglyMeasurable (F x) μ.variation) + (h_bound : ∀ x ∈ s, ∀ᵐ a ∂μ.variation, ‖F x a‖ ≤ bound a) + (bound_integrable : Integrable bound μ.variation) + (h_cont : ∀ᵐ a ∂μ.variation, ContinuousOn (fun x ↦ F x a) s) : ContinuousOn (fun x ↦ ∫ᵛ a, F x a ∂[B; μ]) s := continuousOn_setToFun_of_dominated _ hF_meas h_bound bound_integrable h_cont theorem continuous_of_dominated {F : Y → X → E} {bound : X → ℝ} - (hF_meas : ∀ x, AEStronglyMeasurable (F x) (μ.transpose B).variation) - (h_bound : ∀ x, ∀ᵐ a ∂(μ.transpose B).variation, ‖F x a‖ ≤ bound a) - (bound_integrable : Integrable bound (μ.transpose B).variation) - (h_cont : ∀ᵐ a ∂(μ.transpose B).variation, Continuous fun x ↦ F x a) : + (hF_meas : ∀ x, AEStronglyMeasurable (F x) μ.variation) + (h_bound : ∀ x, ∀ᵐ a ∂μ.variation, ‖F x a‖ ≤ bound a) + (bound_integrable : Integrable bound μ.variation) + (h_cont : ∀ᵐ a ∂μ.variation, Continuous fun x ↦ F x a) : Continuous fun x ↦ ∫ᵛ a, F x a ∂[B; μ] := continuous_setToFun_of_dominated _ hF_meas h_bound bound_integrable h_cont -theorem norm_integral_le_of_norm_le_const [IsFiniteMeasure (μ.transpose B).variation] - {C : ℝ} (h : ∀ᵐ x ∂(μ.transpose B).variation, ‖f x‖ ≤ C) : - ‖∫ᵛ x, f x ∂[B; μ]‖ ≤ C * (μ.transpose B).variation.real univ := calc +theorem norm_integral_le_of_norm_le_const [IsFiniteMeasure μ.variation] + {C : ℝ} (h : ∀ᵐ x ∂μ.variation, ‖f x‖ ≤ C) : + ‖∫ᵛ x, f x ∂[B; μ]‖ ≤ C * ‖B‖ * μ.variation.real univ := calc ‖∫ᵛ x, f x ∂[B; μ]‖ - _ ≤ (∫⁻ a, ENNReal.ofReal ‖f a‖ ∂(μ.transpose B).variation).toReal := + _ ≤ ‖B‖ * (∫⁻ a, ENNReal.ofReal ‖f a‖ ∂μ.variation).toReal := norm_integral_le_lintegral_norm - _ ≤ (∫⁻ a, ENNReal.ofReal C ∂(μ.transpose B).variation).toReal := by + _ ≤ ‖B‖ * (∫⁻ a, ENNReal.ofReal C ∂μ.variation).toReal := by + gcongr 1 apply ENNReal.toReal_mono · simp only [lintegral_const, ne_eq] finiteness · apply lintegral_mono_ae filter_upwards [h] with x hx using ENNReal.ofReal_mono hx - _ = C * (μ.transpose B).variation.real univ := by - by_cases hμ : (μ.transpose B).variation = 0 + _ = ‖B‖ * (C * μ.variation.real univ) := by + by_cases hμ : μ.variation = 0 · simp [hμ] - have : (ae (μ.transpose B).variation).NeBot := ae_neBot.mpr hμ + have : (ae μ.variation).NeBot := ae_neBot.mpr hμ have hC : 0 ≤ C := by obtain ⟨x, hx⟩ := h.exists exact (norm_nonneg _).trans hx simp [ENNReal.toReal_ofReal hC, Measure.real] + _ = C * ‖B‖ * μ.variation.real univ := by ring theorem enorm_integral_le_of_enorm_le_const - {C : ℝ≥0∞} (h : ∀ᵐ x ∂(μ.transpose B).variation, ‖f x‖ₑ ≤ C) : - ‖∫ᵛ x, f x ∂[B; μ]‖ₑ ≤ C * (μ.transpose B).variation univ := - enorm_integral_le_lintegral_enorm.trans ((lintegral_mono_ae h).trans (by simp)) + {C : ℝ≥0∞} (h : ∀ᵐ x ∂μ.variation, ‖f x‖ₑ ≤ C) : + ‖∫ᵛ x, f x ∂[B; μ]‖ₑ ≤ C * ‖B‖ₑ * μ.variation univ := by + apply enorm_integral_le_lintegral_enorm.trans + rw [mul_comm C, mul_assoc] + gcongr + exact (lintegral_mono_ae h).trans (by simp) theorem nndist_integral_add_vectorMeasure_le_lintegral - (h₁ : μ.Integrable f B) (h₂ : ν.Integrable f B) : + (h₁ : μ.Integrable f) (h₂ : ν.Integrable f) : (nndist (∫ᵛ x, f x ∂[B; μ]) (∫ᵛ x, f x ∂[B; (μ + ν)]) : ℝ≥0∞) ≤ - ∫⁻ x, ‖f x‖ₑ ∂(ν.transpose B).variation := by + ‖B‖ₑ * ∫⁻ x, ‖f x‖ₑ ∂ν.variation := by rw [integral_add_vectorMeasure h₁ h₂, nndist_comm, nndist_eq_nnnorm, add_sub_cancel_left] exact enorm_integral_le_lintegral_enorm @@ -778,21 +808,22 @@ lemma variation_transpose_map_le : ((μ.map φ).transpose B).variation ≤ Measure.map φ (μ.transpose B).variation := by grw [transpose_map, variation_map_le] +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in theorem Integrable.map {β : Type*} [MeasurableSpace β] {φ : X → β} - {f : β → E} (hfm : AEStronglyMeasurable f ((μ.transpose B).variation.map φ)) - (h : μ.Integrable (f ∘ φ) B) : (μ.map φ).Integrable f B := by + {f : β → E} (hfm : AEStronglyMeasurable f (μ.variation.map φ)) + (h : μ.Integrable (f ∘ φ)) : (μ.map φ).Integrable f := by by_cases hφ : Measurable φ; swap · simp [VectorMeasure.map, hφ] simp_rw [VectorMeasure.Integrable] at h ⊢ apply ((integrable_map_measure hfm hφ.aemeasurable).2 h).mono_measure - apply variation_transpose_map_le + apply variation_map_le theorem integral_map {β : Type*} [MeasurableSpace β] {φ : X → β} (hφ : Measurable φ) {f : β → E} - (hfm : AEStronglyMeasurable f ((μ.transpose B).variation.map φ)) - (hfi' : μ.Integrable (f ∘ φ) B) : + (hfm : AEStronglyMeasurable f (μ.variation.map φ)) + (hfi' : μ.Integrable (f ∘ φ)) : ∫ᵛ y, f y ∂[B; μ.map φ] = ∫ᵛ x, f (φ x) ∂[B; μ] := by - apply setToFun_of_le_map _ _ hfi' hfm hφ variation_transpose_map_le + apply setToFun_of_le_map _ _ hfi' hfm hφ variation_map_le intro s x hs simp [hs, VectorMeasure.map, transpose, hφ] @@ -800,24 +831,24 @@ theorem _root_.MeasurableEmbedding.variation_transpose_map (hφ : MeasurableEmbe ((μ.map φ).transpose B).variation = (μ.transpose B).variation.map φ := by rw [transpose_map, hφ.variation_map] +omit [NormedSpace ℝ E] [NormedSpace ℝ F] in theorem _root_.MeasurableEmbedding.integrable_map_vectorMeasure (hφ : MeasurableEmbedding φ) {f : β → E} : - (μ.map φ).Integrable f B ↔ μ.Integrable (f ∘ φ) B := by - simp_rw [VectorMeasure.Integrable, - ← hφ.integrable_map_iff (g := f) (μ := (μ.transpose B).variation), hφ.variation_transpose_map] + (μ.map φ).Integrable f ↔ μ.Integrable (f ∘ φ) := by + simp_rw [VectorMeasure.Integrable, ← hφ.integrable_map_iff, hφ.variation_map] theorem _root_.MeasurableEmbedding.integral_map_vectorMeasure (hφ : MeasurableEmbedding φ) {f : β → E} : ∫ᵛ y, f y ∂[B; μ.map φ] = ∫ᵛ x, f (φ x) ∂[B; μ] := by - by_cases hfm : AEStronglyMeasurable f ((μ.transpose B).variation.map φ) - · by_cases h'fm : μ.Integrable (f ∘ φ) B + by_cases hfm : AEStronglyMeasurable f (μ.variation.map φ) + · by_cases h'fm : μ.Integrable (f ∘ φ) · apply integral_map hφ.measurable hfm h'fm · rw [integral_undef, integral_undef] · exact h'fm · rwa [hφ.integrable_map_vectorMeasure] · rw [integral_non_aestronglyMeasurable, integral_non_aestronglyMeasurable] · rwa [hφ.aestronglyMeasurable_map_iff] at hfm - · rwa [hφ.variation_transpose_map] + · rwa [hφ.variation_map] theorem _root_.Topology.IsClosedEmbedding.integral_map_vectorMeasure [TopologicalSpace X] [BorelSpace X] @@ -832,40 +863,40 @@ theorem integral_map_equiv {β} [MeasurableSpace β] (e : X ≃ᵐ β) (f : β /-- **Lebesgue dominated convergence theorem** provides sufficient conditions under which almost everywhere convergence of a sequence of functions implies the convergence of their integrals. We could weaken the condition `bound_integrable` to require - `HasFiniteIntegral bound (μ.transpose B).variation` instead (i.e. not requiring that `bound` is + `HasFiniteIntegral bound μ.variation` instead (i.e. not requiring that `bound` is measurable), but in all applications proving integrability is easier. -/ theorem tendsto_integral_of_dominated_convergence {F : ℕ → X → E} {f : X → E} (bound : X → ℝ) - (F_measurable : ∀ n, AEStronglyMeasurable (F n) (μ.transpose B).variation) - (bound_integrable : Integrable bound (μ.transpose B).variation) - (h_bound : ∀ n, ∀ᵐ a ∂(μ.transpose B).variation, ‖F n a‖ ≤ bound a) - (h_lim : ∀ᵐ a ∂(μ.transpose B).variation, Tendsto (fun n ↦ F n a) atTop (𝓝 (f a))) : + (F_measurable : ∀ n, AEStronglyMeasurable (F n) μ.variation) + (bound_integrable : Integrable bound μ.variation) + (h_bound : ∀ n, ∀ᵐ a ∂μ.variation, ‖F n a‖ ≤ bound a) + (h_lim : ∀ᵐ a ∂μ.variation, Tendsto (fun n ↦ F n a) atTop (𝓝 (f a))) : Tendsto (fun n ↦ ∫ᵛ a, F n a ∂[B; μ]) atTop (𝓝 <| ∫ᵛ a, f a ∂[B; μ]) := tendsto_setToFun_of_dominated_convergence _ bound F_measurable bound_integrable h_bound h_lim /-- Lebesgue dominated convergence theorem for filters with a countable basis -/ theorem tendsto_integral_filter_of_dominated_convergence {l : Filter ι} [l.IsCountablyGenerated] {F : ι → X → E} {f : X → E} (bound : X → ℝ) - (hF_meas : ∀ᶠ n in l, AEStronglyMeasurable (F n) (μ.transpose B).variation) - (h_bound : ∀ᶠ n in l, ∀ᵐ a ∂(μ.transpose B).variation, ‖F n a‖ ≤ bound a) - (bound_integrable : Integrable bound (μ.transpose B).variation) - (h_lim : ∀ᵐ a ∂(μ.transpose B).variation, Tendsto (fun n ↦ F n a) l (𝓝 (f a))) : + (hF_meas : ∀ᶠ n in l, AEStronglyMeasurable (F n) μ.variation) + (h_bound : ∀ᶠ n in l, ∀ᵐ a ∂μ.variation, ‖F n a‖ ≤ bound a) + (bound_integrable : Integrable bound μ.variation) + (h_lim : ∀ᵐ a ∂μ.variation, Tendsto (fun n ↦ F n a) l (𝓝 (f a))) : Tendsto (fun n ↦ ∫ᵛ a, F n a ∂[B; μ]) l (𝓝 <| ∫ᵛ a, f a ∂[B; μ]) := tendsto_setToFun_filter_of_dominated_convergence _ bound hF_meas h_bound bound_integrable h_lim /-- Lebesgue dominated convergence theorem for series. -/ theorem hasSum_integral_of_dominated_convergence [Countable ι] {F : ι → X → E} {f : X → E} - (bound : ι → X → ℝ) (hF_meas : ∀ n, AEStronglyMeasurable (F n) (μ.transpose B).variation) - (h_bound : ∀ n, ∀ᵐ a ∂(μ.transpose B).variation, ‖F n a‖ ≤ bound n a) - (bound_summable : ∀ᵐ a ∂(μ.transpose B).variation, Summable fun n ↦ bound n a) - (bound_integrable : Integrable (fun a ↦ ∑' n, bound n a) (μ.transpose B).variation) - (h_lim : ∀ᵐ a ∂(μ.transpose B).variation, HasSum (fun n ↦ F n a) (f a)) : + (bound : ι → X → ℝ) (hF_meas : ∀ n, AEStronglyMeasurable (F n) μ.variation) + (h_bound : ∀ n, ∀ᵐ a ∂μ.variation, ‖F n a‖ ≤ bound n a) + (bound_summable : ∀ᵐ a ∂μ.variation, Summable fun n ↦ bound n a) + (bound_integrable : Integrable (fun a ↦ ∑' n, bound n a) μ.variation) + (h_lim : ∀ᵐ a ∂μ.variation, HasSum (fun n ↦ F n a) (f a)) : HasSum (fun n ↦ ∫ᵛ a, F n a ∂[B; μ]) (∫ᵛ a, f a ∂[B; μ]) := hasSum_setToFun_of_dominated_convergence _ bound hF_meas h_bound bound_summable bound_integrable h_lim theorem integral_tsum [CompleteSpace E] [Countable ι] - {f : ι → X → E} (hf : ∀ i, AEStronglyMeasurable (f i) (μ.transpose B).variation) - (hf' : ∑' i, ∫⁻ a : X, ‖f i a‖ₑ ∂(μ.transpose B).variation ≠ ∞) : + {f : ι → X → E} (hf : ∀ i, AEStronglyMeasurable (f i) μ.variation) + (hf' : ∑' i, ∫⁻ a : X, ‖f i a‖ₑ ∂μ.variation ≠ ∞) : ∫ᵛ a, ∑' i, f i a ∂[B; μ] = ∑' i, ∫ᵛ a, f i a ∂[B; μ] := setToFun_tsum _ hf hf' @@ -874,10 +905,10 @@ theorem integral_tsum [CompleteSpace E] [Countable ι] function `f`, then the integrals of `F n` with respect to a vector measure `μ` with finite variation converge to the integral of `f`. -/ theorem tendsto_integral_filter_of_norm_le_const {l : Filter ι} [l.IsCountablyGenerated] - {F : ι → X → E} [IsFiniteMeasure (μ.transpose B).variation] {f : X → E} - (h_meas : ∀ᶠ n in l, AEStronglyMeasurable (F n) (μ.transpose B).variation) - (h_bound : ∃ C, ∀ᶠ n in l, ∀ᵐ a ∂(μ.transpose B).variation, ‖F n a‖ ≤ C) - (h_lim : ∀ᵐ a ∂(μ.transpose B).variation, Tendsto (fun n ↦ F n a) l (𝓝 (f a))) : + {F : ι → X → E} [IsFiniteMeasure μ.variation] {f : X → E} + (h_meas : ∀ᶠ n in l, AEStronglyMeasurable (F n) μ.variation) + (h_bound : ∃ C, ∀ᶠ n in l, ∀ᵐ a ∂μ.variation, ‖F n a‖ ≤ C) + (h_lim : ∀ᵐ a ∂μ.variation, Tendsto (fun n ↦ F n a) l (𝓝 (f a))) : Tendsto (fun n ↦ ∫ᵛ a, F n a ∂[B; μ]) l (𝓝 (∫ᵛ a, f a ∂[B; μ])) := tendsto_setToFun_filter_of_norm_le_const _ h_meas h_bound h_lim diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean index 2c0ba7a93d9b1e..de8e791a846bee 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean @@ -306,7 +306,8 @@ instance {x : X} {v : V} : IsFiniteMeasure (VectorMeasure.dirac x v).variation : simp only [variation_dirac, enorm_eq_nnnorm, Measure.coe_nnreal_smul] infer_instance -@[simp] lemma variation_toSignedMeasure {μ : Measure X} [IsFiniteMeasure μ] : +@[simp] lemma _root_.MeasureTheory.Measure.variation_toSignedMeasure + {μ : Measure X} [IsFiniteMeasure μ] : μ.toSignedMeasure.variation = μ := by apply le_antisymm · apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) From 7da7c276aa3f0d0dbcea1e2fb9adcff0dba08651 Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Wed, 17 Jun 2026 08:21:18 +0000 Subject: [PATCH 0101/1300] chore(Algebra): module deprecations for moved `AddTorsor` files (#39134) --- Mathlib.lean | 4 ++++ Mathlib/Algebra/AddTorsor/Basic.lean | 5 +++++ Mathlib/Algebra/AddTorsor/Defs.lean | 5 +++++ Mathlib/Topology/Algebra/Group/AddTorsor.lean | 5 +++++ Mathlib/Topology/Algebra/ProperAction/AddTorsor.lean | 5 +++++ 5 files changed, 24 insertions(+) create mode 100644 Mathlib/Algebra/AddTorsor/Basic.lean create mode 100644 Mathlib/Algebra/AddTorsor/Defs.lean create mode 100644 Mathlib/Topology/Algebra/Group/AddTorsor.lean create mode 100644 Mathlib/Topology/Algebra/ProperAction/AddTorsor.lean diff --git a/Mathlib.lean b/Mathlib.lean index 610df212f17b02..8be7995c7dde01 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4,6 +4,8 @@ public import Std public import Batteries public import Mathlib.Algebra.AddConstMap.Basic public import Mathlib.Algebra.AddConstMap.Equiv +public import Mathlib.Algebra.AddTorsor.Basic +public import Mathlib.Algebra.AddTorsor.Defs public import Mathlib.Algebra.AffineMonoid.Basic public import Mathlib.Algebra.AffineMonoid.Embedding public import Mathlib.Algebra.AffineMonoid.Irreducible @@ -7499,6 +7501,7 @@ public import Mathlib.Topology.Algebra.ContinuousMonoidHom public import Mathlib.Topology.Algebra.Equicontinuity public import Mathlib.Topology.Algebra.Field public import Mathlib.Topology.Algebra.FilterBasis +public import Mathlib.Topology.Algebra.Group.AddTorsor public import Mathlib.Topology.Algebra.Group.Basic public import Mathlib.Topology.Algebra.Group.ClosedSubgroup public import Mathlib.Topology.Algebra.Group.Compact @@ -7613,6 +7616,7 @@ public import Mathlib.Topology.Algebra.Order.Support public import Mathlib.Topology.Algebra.Order.UpperLower public import Mathlib.Topology.Algebra.Polynomial public import Mathlib.Topology.Algebra.PontryaginDual +public import Mathlib.Topology.Algebra.ProperAction.AddTorsor public import Mathlib.Topology.Algebra.ProperAction.Basic public import Mathlib.Topology.Algebra.ProperAction.CompactlyGenerated public import Mathlib.Topology.Algebra.ProperAction.ProperlyDiscontinuous diff --git a/Mathlib/Algebra/AddTorsor/Basic.lean b/Mathlib/Algebra/AddTorsor/Basic.lean new file mode 100644 index 00000000000000..b1f613e225f0ca --- /dev/null +++ b/Mathlib/Algebra/AddTorsor/Basic.lean @@ -0,0 +1,5 @@ +module -- shake: keep-all + +public import Mathlib.Algebra.Torsor.Basic + +deprecated_module (since := "2026-06-12") diff --git a/Mathlib/Algebra/AddTorsor/Defs.lean b/Mathlib/Algebra/AddTorsor/Defs.lean new file mode 100644 index 00000000000000..52df5cca935bbe --- /dev/null +++ b/Mathlib/Algebra/AddTorsor/Defs.lean @@ -0,0 +1,5 @@ +module -- shake: keep-all + +public import Mathlib.Algebra.Torsor.Defs + +deprecated_module (since := "2026-06-12") diff --git a/Mathlib/Topology/Algebra/Group/AddTorsor.lean b/Mathlib/Topology/Algebra/Group/AddTorsor.lean new file mode 100644 index 00000000000000..6b42000ee362d3 --- /dev/null +++ b/Mathlib/Topology/Algebra/Group/AddTorsor.lean @@ -0,0 +1,5 @@ +module -- shake: keep-all + +public import Mathlib.Topology.Algebra.Group.Torsor + +deprecated_module (since := "2026-06-12") diff --git a/Mathlib/Topology/Algebra/ProperAction/AddTorsor.lean b/Mathlib/Topology/Algebra/ProperAction/AddTorsor.lean new file mode 100644 index 00000000000000..2ce65c6dba91ef --- /dev/null +++ b/Mathlib/Topology/Algebra/ProperAction/AddTorsor.lean @@ -0,0 +1,5 @@ +module -- shake: keep-all + +public import Mathlib.Topology.Algebra.ProperAction.Torsor + +deprecated_module (since := "2026-06-12") From 2fb84f40125bfc66936eff5dea70c236315f17b2 Mon Sep 17 00:00:00 2001 From: ooovi <79147175+ooovi@users.noreply.github.com> Date: Wed, 17 Jun 2026 08:53:23 +0000 Subject: [PATCH 0102/1300] feat(Geometry/Convex/Cone/Pointed): faces of pointed cones (#39185) - Define PointedCone.IsFaceOf, for a pointed cone being a face of another pointed cone. - Prove some basic properties, that faces are extreme sets of their cone, and how they behave under intersection, map and product operations. Co-authored-by: Martin Winter Co-authored-by: ovi --- Mathlib.lean | 1 + Mathlib/Geometry/Convex/Cone/Face/Basic.lean | 287 +++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 Mathlib/Geometry/Convex/Cone/Face/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8be7995c7dde01..3231bbedb8ef7a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4549,6 +4549,7 @@ public import Mathlib.FieldTheory.Tower public import Mathlib.Geometry.Convex.Cone.Basic public import Mathlib.Geometry.Convex.Cone.Dual public import Mathlib.Geometry.Convex.Cone.DualFinite +public import Mathlib.Geometry.Convex.Cone.Face.Basic public import Mathlib.Geometry.Convex.Cone.Pointed public import Mathlib.Geometry.Convex.Cone.Simplicial public import Mathlib.Geometry.Convex.Cone.TensorProduct diff --git a/Mathlib/Geometry/Convex/Cone/Face/Basic.lean b/Mathlib/Geometry/Convex/Cone/Face/Basic.lean new file mode 100644 index 00000000000000..777c71f0d0b5a7 --- /dev/null +++ b/Mathlib/Geometry/Convex/Cone/Face/Basic.lean @@ -0,0 +1,287 @@ +/- +Copyright (c) 2025 Olivia Röhrig. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Olivia Röhrig +-/ +module + +public import Mathlib.Analysis.Convex.Extreme +public import Mathlib.Geometry.Convex.Cone.Pointed + +/-! +# Faces of pointed cones + +This file defines what it means for a pointed cone to be a face of another pointed cone and +establishes basic properties of this relation. +A subcone `F` of a cone `C` is a face if any two points in `C` that have a positive combination +in `F` are also in `F`. + +## Main declarations + +* `IsFaceOf F C`: States that the pointed cone `F` is a face of the pointed cone `C`. + +## Implementation notes + +* We do not use `IsExtreme` as a definition because this is an affine notion and does not allow the + flexibility necessary to deal wth cones over general rings. E.g. the cone of positive integers has + no proper subset that are extreme. We prove that every face is an extreme set of its cone. +* Most results proven over a division ring hold more generally over an Archimedean ring. In + particular, `iff_mem_of_add_mem_left` holds whenever for every `x ∈ R` there is a `y ∈ R` with + `1 ≤ x * y`. + +-/ + +open Submodule + +public section + +namespace PointedCone + +variable {R M N : Type*} + +section Semiring + +variable [Semiring R] [PartialOrder R] [IsOrderedRing R] +variable [AddCommGroup M] [Module R M] + +/-- A sub-cone `F` of a pointed cone `C` is a face of `C` if any two points of `C` with a strictly +positive combination in `F` are also in `F`. -/ +@[mk_iff] +structure IsFaceOf (F C : PointedCone R M) : Prop where + le : F ≤ C + mem_of_smul_add_mem {x y : M} {a : R} : + x ∈ C → y ∈ C → 0 < a → a • x + y ∈ F → x ∈ F + +variable {C C₁ C₂ F F₁ F₂ : PointedCone R M} + +namespace IsFaceOf + +theorem mem_of_smul_add_smul_mem_left {x y : M} {a b : R} (hF : F.IsFaceOf C) (hx : x ∈ C) + (hy : y ∈ C) (ha : 0 < a) (hb : 0 < b) (h : a • x + b • y ∈ F) : x ∈ F := + hF.2 hx (smul_mem _ hb.le hy) ha h + +theorem mem_of_smul_add_smul_mem_right {x y : M} {a b : R} (hF : F.IsFaceOf C) (hx : x ∈ C) + (hy : y ∈ C) (ha : 0 < a) (hb : 0 < b) (h : a • x + b • y ∈ F) : y ∈ F := + by apply hF.2 hy (smul_mem _ ha.le hx) hb; rwa [add_comm] + +/-- A pointed cone `C` is a face of itself. -/ +@[refl, simp] +protected theorem refl (C : PointedCone R M) : C.IsFaceOf C := ⟨fun _ a ↦ a, fun hx _ _ _ ↦ hx⟩ + +protected theorem rfl {C : PointedCone R M} : C.IsFaceOf C := .refl _ + +/-- A face of a cone is a face of another if and only if they are contained in each other. -/ +theorem isFaceOf_iff_le (h₁ : F₁.IsFaceOf C) (h₂ : F₂.IsFaceOf C) : + F₁.IsFaceOf F₂ ↔ F₁ ≤ F₂ := + ⟨IsFaceOf.le, fun h ↦ ⟨h, fun hx hy ha hxy ↦ h₁.2 (h₂.le hx) (h₂.le hy) ha hxy⟩⟩ + +/-- A face of a cone is an extreme subset of the cone. -/ +theorem isExtreme (h : F.IsFaceOf C) : IsExtreme R (C : Set M) F := by + refine ⟨h.1, ?_⟩ + rintro _ xc _ yc _ zf ⟨_, _, a0, b0, -, rfl⟩ + exact h.mem_of_smul_add_smul_mem_left xc yc a0 b0 zf + +/-- The intersection of two faces of two cones is a face of the intersection of the cones. -/ +protected theorem inf (h₁ : F₁.IsFaceOf C₁) (h₂ : F₂.IsFaceOf C₂) : + (F₁ ⊓ F₂).IsFaceOf (C₁ ⊓ C₂) := by + use le_inf_iff.mpr ⟨Set.inter_subset_left.trans h₁.le, Set.inter_subset_right.trans h₂.le⟩ + simp only [mem_inf, and_imp] + refine fun xc₁ xc₂ yc₁ yc₂ a0 hz₁ hz₂ ↦ ⟨?_, ?_⟩ + · exact h₁.mem_of_smul_add_mem xc₁ yc₁ a0 hz₁ + · exact h₂.mem_of_smul_add_mem xc₂ yc₂ a0 hz₂ + +/-- The intersection of two faces of a cone is a face of the cone. -/ +theorem inf_left (h₁ : F₁.IsFaceOf C) (h₂ : F₂.IsFaceOf C) : (F₁ ⊓ F₂).IsFaceOf C := + inf_idem C ▸ IsFaceOf.inf h₁ h₂ + +/-- If a cone is a face of two cones simultaneously, then it's also a face of their intersection. -/ +theorem inf_right (h₁ : F.IsFaceOf C₁) (h₂ : F.IsFaceOf C₂) : F.IsFaceOf (C₁ ⊓ C₂) := + inf_idem F ▸ IsFaceOf.inf h₁ h₂ + +protected theorem sInf (F : Set (PointedCone R M)) (h : ∀ f ∈ F, f.IsFaceOf C) : + (C ⊓ sInf F).IsFaceOf C where + le _ sm := sm.1 + mem_of_smul_add_mem := by + simp only [mem_inf, mem_sInf, and_imp] + intro _ _ a xc yc a0 _ h' + simpa [xc] using fun F Fs ↦ (h F Fs).mem_of_smul_add_mem xc yc a0 (h' F Fs) + +theorem mem_of_add_mem_left (hF : F.IsFaceOf C) {x y : M} + (hx : x ∈ C) (hy : y ∈ C) (hxy : x + y ∈ F) : x ∈ F := by + nontriviality R using Module.subsingleton R M + simpa [hxy] using hF.mem_of_smul_add_mem hx hy zero_lt_one + +theorem mem_of_add_mem_right (hF : F.IsFaceOf C) {x y : M} + (hx : x ∈ C) (hy : y ∈ C) (hxy : x + y ∈ F) : y ∈ F := by + rw [add_comm x y] at hxy; exact mem_of_add_mem_left hF hy hx hxy + +theorem add_mem_iff_mem (hF : F.IsFaceOf C) {x y : M} (hx : x ∈ C) (hy : y ∈ C) : + x + y ∈ F ↔ x ∈ F ∧ y ∈ F := by + refine ⟨?_, fun ⟨hx, hy⟩ ↦ F.add_mem hx hy⟩ + exact fun h ↦ ⟨mem_of_add_mem_left hF hx hy h, mem_of_add_mem_right hF hx hy h⟩ + +/-- If the sum of points of a cone is in a face, then all the points are in the face. -/ +theorem mem_of_sum_mem {ι : Type*} [Fintype ι] {f : ι → M} (hF : F.IsFaceOf C) + (hsC : ∀ i : ι, f i ∈ C) (hs : ∑ i : ι, f i ∈ F) (i : ι) : f i ∈ F := by classical + apply hF.mem_of_add_mem_left (hsC i) (sum_mem (fun j (_ : j ∈ Finset.univ.erase i) ↦ hsC j)) + simp [hs] + +theorem sum_mem_iff_mem {ι : Type*} [Fintype ι] {f : ι → M} (hF : F.IsFaceOf C) + (hsC : ∀ i, f i ∈ C) : ∑ i, f i ∈ F ↔ ∀ i, f i ∈ F := + ⟨mem_of_sum_mem hF hsC, fun a ↦ Submodule.sum_mem F fun c _ ↦ a c⟩ + +/-- If the positive combination of points of a cone is in a face, then all the points are +in the face. -/ +theorem mem_of_sum_smul_mem {ι : Type*} [Fintype ι] {f : ι → M} {c : ι → R} + (hF : F.IsFaceOf C) (hsC : ∀ i : ι, f i ∈ C) (hc : ∀ i, 0 ≤ c i) (hs : ∑ i : ι, c i • f i ∈ F) + (i : ι) (hci : 0 < c i) : f i ∈ F := by classical + rw [Finset.sum_eq_add_sum_sdiff_singleton i] at hs + · refine hF.mem_of_smul_add_mem (hsC i) ?_ hci hs + exact C.sum_mem fun i _ ↦ C.smul_mem (hc i) (hsC i) + · simp + +/-- The face of a face of a cone is also a face of the cone. -/ +@[trans] +protected theorem trans (h₁ : F₂.IsFaceOf F₁) (h₂ : F₁.IsFaceOf C) : F₂.IsFaceOf C := by + refine ⟨h₁.1.trans h₂.1, fun hx hy ha hxy ↦ h₁.2 (h₂.2 hx hy ha (h₁.le hxy)) ?_ ha hxy⟩ + exact h₂.mem_of_add_mem_right (smul_mem _ ha.le hx) hy (h₁.le hxy) + +section Map + +variable [AddCommGroup N] [Module R N] + +/-- The image of a face of a cone under an injective linear map is a face of the +image of the cone. -/ +protected theorem map (f : M →ₗ[R] N) (hf : Function.Injective f) (hF : F.IsFaceOf C) : + (F.map f).IsFaceOf (C.map f) where + le := map_mono hF.le + mem_of_smul_add_mem := by + rintro _ _ a ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩ ha ⟨z, hz₁, hz₂⟩ + dsimp at hz₂ + rw [← map_smul, ← map_add] at hz₂ + exact ⟨x, hF.mem_of_smul_add_mem hx hy ha (hf hz₂ ▸ hz₁), rfl⟩ + +/-- The image of a face of a cone under an equivalence is a face of the image of the cone. -/ +theorem map_equiv (e : M ≃ₗ[R] N) (hF : F.IsFaceOf C) : + (F.map (e : M →ₗ[R] N)).IsFaceOf (C.map e) := hF.map _ e.injective + +theorem of_map_injective {f : M →ₗ[R] N} (hf : Function.Injective f) + (hc : (map f F).IsFaceOf (map f C)) : F.IsFaceOf C := by + obtain ⟨sub, hF⟩ := hc + refine ⟨fun x xf ↦ ?_, fun hx hy ha h ↦ ?_⟩ + · obtain ⟨y, yC, hy⟩ := mem_map.mp <| sub (mem_map_of_mem xf) + rwa [hf hy] at yC + · simp only [mem_map, forall_exists_index, and_imp] at hF + obtain ⟨_, ⟨hx', hhx'⟩⟩ := hF _ hx rfl _ hy rfl ha _ h (by simp) + convert hx' + exact hf hhx'.symm + +/-- The comap of a face of a cone under a linear map is a face of the comap of the cone. -/ +protected theorem comap (f : N →ₗ[R] M) (hF : F.IsFaceOf C) : (F.comap f).IsFaceOf (C.comap f) := by + refine ⟨comap_mono hF.le, ?_⟩ + simp only [mem_comap, map_add, map_smul] + exact hF.mem_of_smul_add_mem + +theorem of_comap_surjective {f : N →ₗ[R] M} (hf : Function.Surjective f) + (hc : (F.comap f).IsFaceOf (C.comap f)) : F.IsFaceOf C := by + refine ⟨fun x xF ↦ ?_, fun {x y _} xC yC a0 h ↦ ?_⟩ + · rw [← (hf x).choose_spec] at xF ⊢ + exact mem_comap.mp (hc.1 xF) + · rw [← (hf x).choose_spec] at h ⊢ xC + rw [← (hf y).choose_spec] at h yC + exact hc.2 xC yC a0 (by simpa) + +end Map + +end IsFaceOf + +/-- The image of a cone `F` under an injective linear map is a face of the +image of another cone `C` if and only if `F` is a face of `C`. -/ +theorem isFaceOf_map_iff [AddCommGroup N] [Module R N] {f : M →ₗ[R] N} (hf : Function.Injective f) : + (F.map f).IsFaceOf (C.map f) ↔ F.IsFaceOf C := + ⟨IsFaceOf.of_map_injective hf, IsFaceOf.map _ hf⟩ + +/-- The comap of a cone `F` under a surjective linear map is a face of the +comap of another cone `F` if and only if `F` is a face of `C`. -/ +theorem isFaceOf_comap_iff [AddCommGroup N] [Module R N] {f : N →ₗ[R] M} + (hf : Function.Surjective f) : (F.comap f).IsFaceOf (C.comap f) ↔ F.IsFaceOf C := + ⟨IsFaceOf.of_comap_surjective hf, IsFaceOf.comap _⟩ + +end Semiring + +section DivisionRing + +variable [DivisionRing R] [LinearOrder R] [IsOrderedRing R] +variable [AddCommGroup M] [Module R M] +variable {C F F₁ F₂ : PointedCone R M} + +namespace IsFaceOf + +theorem of_mem_of_add_mem_left (h₁ : F ≤ C) (h₂ : ∀ {x y : M}, x ∈ C → y ∈ C → x + y ∈ F → x ∈ F) : + F.IsFaceOf C := by + refine ⟨h₁, fun hx hy ha haxy ↦ ?_⟩ + simpa [← smul_assoc, inv_mul_cancel₀ (ne_of_gt ha)] using smul_mem _ + (inv_nonneg.mpr (le_of_lt ha)) <| h₂ (smul_mem _ (le_of_lt ha) hx) hy haxy + +/-- The lineality space of a cone is a face. -/ +lemma lineal (C : PointedCone R M) : IsFaceOf C.lineal C := by + apply of_mem_of_add_mem_left (lineal_le C) + intro _ _ xc yc xyf + simp [neg_add_rev, xc, true_and] at xyf ⊢ + simpa [neg_add_cancel_comm] using add_mem xyf.2 yc + +/-- The lineality space of a cone lies in every face. -/ +lemma lineal_le (hF : F.IsFaceOf C) : C.lineal ≤ F := + fun _ hx ↦ hF.mem_of_add_mem_left hx.1 hx.2 (by simp) + +/-- The lineality space of a face of a cone agrees with the lineality space of the cone. -/ +lemma lineal_congr (hF : F.IsFaceOf C) : F.lineal = C.lineal := by + ext + refine ⟨fun ⟨hx, hx'⟩ ↦ ⟨hF.le hx, hF.le hx'⟩, fun ⟨hx, hx'⟩ ↦ ⟨?_, ?_⟩⟩ + · exact hF.mem_of_add_mem_left hx hx' (by simp) + · exact hF.mem_of_add_mem_left hx' hx (by simp) + +section Prod + +variable [AddCommGroup N] [Module R N] + +/-- The product of two faces of two cones is a face of the product of the cones. -/ +protected theorem prod {C₁ F₁ : PointedCone R M} {C₂ F₂ : PointedCone R N} + (hF₁ : F₁.IsFaceOf C₁) (hF₂ : F₂.IsFaceOf C₂) : IsFaceOf (F₁.prod F₂) (C₁.prod C₂) := by + refine ⟨fun x hx ↦ by simpa [mem_prod] using ⟨hF₁.le hx.1, hF₂.le hx.2⟩, ?_⟩ + simp only [mem_prod, Prod.fst_add, Prod.smul_fst, Prod.snd_add, + Prod.smul_snd, and_imp, Prod.forall] + intro _ _ _ _ _ xc₁ xc₂ yc₁ yc₂ a0 hab₁ hab₂ + exact ⟨hF₁.mem_of_smul_add_mem xc₁ yc₁ a0 hab₁, hF₂.mem_of_smul_add_mem xc₂ yc₂ a0 hab₂⟩ + +/-- The projection of a face of a product cone onto the first component is a face of the +projection of the product cone onto the first component. -/ +protected theorem fst {C₁ : PointedCone R M} {C₂ : PointedCone R N} + {F : PointedCone R (M × N)} + (hF : F.IsFaceOf (C₁.prod C₂)) : (F.map (.fst R M N)).IsFaceOf C₁ := by + constructor + · intro x hx + simp only [mem_map, LinearMap.fst_apply, Prod.exists, exists_and_right, exists_eq_right] at hx + exact (Set.mem_prod.mp <| hF.le hx.choose_spec).1 + · simp only [mem_map, LinearMap.fst_apply, Prod.exists, exists_and_right, exists_eq_right, + forall_exists_index] + intro x y a hx hy ha z h + refine ⟨0, hF.mem_of_smul_add_mem (x := (x, 0)) (y := (y, z)) ?_ ?_ ha (by simpa)⟩ + · exact mem_prod.mp ⟨hx, zero_mem C₂⟩ + · exact mem_prod.mp ⟨hy, (hF.le h).2⟩ + +/-- The projection of a face of a product cone onto the second component is a face of the +projection of the product cone onto the second component. -/ +protected theorem snd {C₁ : PointedCone R M} {C₂ : PointedCone R N} {F : PointedCone R (M × N)} + (hF : F.IsFaceOf (C₁.prod C₂)) : (F.map (.snd R M N)).IsFaceOf C₂ := by + have := hF.map _ (LinearEquiv.prodComm R M N).injective + convert IsFaceOf.fst (by simpa [PointedCone.map, Submodule.map]) + ext; simp + +end Prod + +end IsFaceOf + +end DivisionRing + +end PointedCone From 69892ec2946cc9efacff8bff6dc3700fec6a527a Mon Sep 17 00:00:00 2001 From: William Coram Date: Wed, 17 Jun 2026 10:37:35 +0000 Subject: [PATCH 0103/1300] feat: lemmas towards showing gaussNorm on MvPowerSeries is an absolute value (#38049) We prove lemmas: ``gaussNorm_mul_le`` and ``gaussNorm_le_mul`` which will allow us to show it is an absolute value on Mv restricted power series. Co-authored-by: WilliamCoram --- .../Algebra/Order/Ring/IsNonarchimedean.lean | 103 +++++++++------- .../Normed/Unbundled/FiniteExtension.lean | 4 +- .../Normed/Unbundled/SpectralNorm.lean | 3 +- .../RingTheory/MvPowerSeries/GaussNorm.lean | 112 +++++++++++++++++- Mathlib/RingTheory/Polynomial/GaussNorm.lean | 2 +- 5 files changed, 173 insertions(+), 51 deletions(-) diff --git a/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean b/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean index 7cc52beee21e32..92d41588b31803 100644 --- a/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean +++ b/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean @@ -19,6 +19,9 @@ nonarchimedean functions. public section +/- TODO: Remove the Funlike hypothesis on these statements and turn them all into the form + {f : α → R} + properties on f. -/ + namespace IsNonarchimedean variable {R : Type*} [Semiring R] [LinearOrder R] {a b : R} {m n : ℕ} @@ -112,6 +115,37 @@ theorem add_eq_max_of_ne {F α : Type*} [AddGroup α] [FunLike F α R] · rw [add_eq_left_of_lt hna h_lt] exact (max_eq_left_of_lt h_lt).symm +/- TODO: Remove the funlike conditions on the lemmas required for add_max_of_ne, this will allow us + to remove the CommGroup part in the below which is unnecessary. -/ + +lemma add_eq_max_of_ne' {α S : Type*} [Semiring S] [LinearOrder S] [AddCommGroup α] + (f : α → S) (fna : IsNonarchimedean f) (Neg : ∀ a, f a = f (-a)) {a b : α} + (hne : f a ≠ f b) : f (a + b) = max (f a) (f b) := by + wlog hab : f a > f b generalizing a b with H + · simpa [add_comm, max_comm] using (H hne.symm ((not_lt.mp hab).lt_of_ne hne)) + apply le_antisymm (fna a b) + rcases le_max_iff.mp (fna (a + b) (-b)) with h | h + · simpa [max_eq_left (le_of_lt hab)] using h + · exact absurd h (not_le.mpr (by simpa [Neg b] using hab)) + +omit [Semiring R] in +open Finset in +/-- Ultrametric inequality with `Finset.sum`. -/ +lemma apply_sum_le_sup {α β : Type*} [AddCommMonoid α] {f : α → R} + (nonarch : IsNonarchimedean f) {s : Finset β} (hnonempty : s.Nonempty) {l : β → α} : + f (∑ i ∈ s, l i) ≤ s.sup' hnonempty fun i => f (l i) := by + induction hnonempty using Nonempty.cons_induction with + | singleton i => simp + | cons i s _ hs hind => + simp only [sum_cons, le_sup'_iff, mem_cons, exists_eq_or_imp] + rw [← le_sup'_iff hs] + rcases le_max_iff.mp <| nonarch (l i) (∑ i ∈ s, l i) with h₁ | h₂ + · exact .inl h₁ + · exact .inr <| le_trans h₂ hind + +@[deprecated (since := "2026-04-27")] +alias apply_sum_le_sup_of_isNonarchimedean := apply_sum_le_sup + omit [Semiring R] in /-- Given a nonarchimedean function `α → R`, a function `g : β → α` and a nonempty multiset `s : Multiset β`, we can always find `b : β` belonging to `s` such that @@ -133,11 +167,10 @@ theorem multiset_image_add_of_nonempty {α β : Type*} [AddCommMonoid α] [Nonem omit [Semiring R] in /-- Given a nonarchimedean function `α → R`, a function `g : β → α` and a nonempty finset `t : Finset β`, we can always find `b : β` belonging to `t` such that `f (t.sum g) ≤ f (g b)` . -/ -theorem finset_image_add_of_nonempty {α β : Type*} [AddCommMonoid α] [Nonempty β] {f : α → R} +theorem finset_image_add_of_nonempty {α β : Type*} [AddCommMonoid α] {f : α → R} (hna : IsNonarchimedean f) (g : β → α) {t : Finset β} (ht : t.Nonempty) : ∃ b ∈ t, f (t.sum g) ≤ f (g b) := by - apply multiset_image_add_of_nonempty hna - simp_all [Finset.nonempty_iff_ne_empty] + simpa [Finset.le_sup'_iff] using IsNonarchimedean.apply_sum_le_sup hna ht /-- Given a nonnegative nonarchimedean function `α → R` such that `f 0 = 0`, a function `g : β → α` and a multiset `s : Multiset β`, we can always find `b : β`, belonging to `s` if `s` is nonempty, @@ -155,13 +188,13 @@ theorem multiset_image_add {F α β : Type*} [AddCommMonoid α] [FunLike F α R] /-- Given a nonnegative nonarchimedean function `α → R` such that `f 0 = 0`, a function `g : β → α` and a finset `t : Finset β`, we can always find `b : β`, belonging to `t` if `t` is nonempty, such that `f (t.sum g) ≤ f (g b)` . -/ -theorem finset_image_add {F α β : Type*} [AddCommMonoid α] [FunLike F α R] - [ZeroHomClass F α R] [NonnegHomClass F α R] [Nonempty β] {f : F} (hna : IsNonarchimedean f) - (g : β → α) (t : Finset β) : - ∃ b : β, (t.Nonempty → b ∈ t) ∧ f (t.sum g) ≤ f (g b) := by - have h1 : t.Nonempty ↔ t.val ≠ 0 := by simp [Finset.nonempty_iff_ne_empty] - rw [h1] - exact multiset_image_add hna g t.val +lemma finset_image_add {α β : Type*} [AddCommMonoid α] [Nonempty β] {f : α → R} (f_zero : f 0 = 0) + (f_nonneg : ∀ x, 0 ≤ f x) (hna : IsNonarchimedean f) (g : β → α) (t : Finset β) : + ∃ i, (t.Nonempty → i ∈ t) ∧ f (t.sum g) ≤ f (g i) := by + rcases t.eq_empty_or_nonempty with rfl | ht + · simp [f_zero, f_nonneg] + · exact (fun ⟨i, h, h'⟩ => ⟨i, fun _ ↦ h, h'⟩) <| + IsNonarchimedean.finset_image_add_of_nonempty hna g ht open Multiset in theorem multiset_powerset_image_add [IsStrictOrderedRing R] @@ -186,42 +219,22 @@ theorem finset_powerset_image_add [IsStrictOrderedRing R] f ((powersetCard (s.card - m) s).sum fun t : Finset β ↦ t.prod fun i : β ↦ -b i) ≤ f (u.val.prod fun i : β ↦ -b i) := by set g := fun t : Finset β ↦ t.prod fun i : β ↦ - b i - obtain ⟨b, hb_in, hb⟩ := hf_na.finset_image_add g (powersetCard (s.card - m) s) + obtain ⟨b, hb_in, hb⟩ := hf_na.finset_image_add (by grind) (apply_nonneg f) + g (powersetCard (s.card - m) s) exact ⟨⟨b, hb_in (powersetCard_nonempty.mpr (Nat.sub_le s.card m))⟩, hb⟩ -omit [Semiring R] in -open Finset in -/-- Ultrametric inequality with `Finset.sum`. -/ -lemma apply_sum_le_sup {α β : Type*} [AddCommMonoid α] {f : α → R} - (nonarch : IsNonarchimedean f) {s : Finset β} (hnonempty : s.Nonempty) {l : β → α} : - f (∑ i ∈ s, l i) ≤ s.sup' hnonempty fun i => f (l i) := by - induction hnonempty using Nonempty.cons_induction with - | singleton i => simp - | cons i s _ hs hind => - simp only [sum_cons, le_sup'_iff, mem_cons, exists_eq_or_imp] - rw [← le_sup'_iff hs] - rcases le_max_iff.mp <| nonarch (l i) (∑ i ∈ s, l i) with h₁ | h₂ - · exact .inl h₁ - · exact .inr <| le_trans h₂ hind - -@[deprecated (since := "2026-04-27")] -alias apply_sum_le_sup_of_isNonarchimedean := apply_sum_le_sup - -open Finset in -lemma apply_sum_eq_of_lt {α β F : Type*} [AddCommGroup α] [FunLike F α R] - [AddGroupSeminormClass F α R] {f : F} (nonarch : IsNonarchimedean f) {s : Finset β} {l : β → α} - {k : β} (hk : k ∈ s) (hmax : ∀ j ∈ s, j ≠ k → f (l j) < f (l k)) : - f (∑ i ∈ s, l i) = f (l k) := by - have : s.Nonempty := by use k - induction this using Nonempty.cons_induction generalizing k with - | singleton a => simp_all - | cons a s _ hs _ => - by_cases ha : k = a - · rw [sum_cons, ha] - apply add_eq_left_of_lt nonarch - grw [apply_sum_le_sup nonarch hs] - grind [sup'_lt_iff] - · grind [add_eq_right_of_lt nonarch] +lemma apply_sum_eq_of_lt {α β : Type*} [AddCommGroup α] {f : α → R} (fna : IsNonarchimedean f) + (f_neg : ∀ a, f a = f (-a)) {s : Finset β} {l : β → α} {k : β} (hk : k ∈ s) + (hmax : ∀ j ∈ s, j ≠ k → f (l j) < f (l k)) : f (∑ i ∈ s, l i) = f (l k) := by + by_cases hcard : s.card = 1 + · grind [Finset.card_eq_one.mp hcard] + · classical + rw [← Finset.add_sum_erase _ _ hk] + have hNonempty : (s.erase k).Nonempty := + Finset.Nontrivial.erase_nonempty (Finset.one_lt_card_iff_nontrivial.mp (by grind)) + have hrest_le := IsNonarchimedean.apply_sum_le_sup fna hNonempty (l := l) + simp only [Finset.le_sup'_iff, Finset.mem_erase, ne_eq] at hrest_le + rw [add_eq_max_of_ne' f fna f_neg (by grind), max_eq_left (le_of_lt (by grind))] /-- If `f` is a nonarchimedean additive group seminorm on a commutative ring `α`, `n : ℕ`, and `a b : α`, then we can find `m : ℕ` such that `m ≤ n` and @@ -229,7 +242,7 @@ lemma apply_sum_eq_of_lt {α β F : Type*} [AddCommGroup α] [FunLike F α R] theorem add_pow_le {F α : Type*} [CommRing α] [FunLike F α R] [ZeroHomClass F α R] [NonnegHomClass F α R] [SubmultiplicativeHomClass F α R] {f : F} (hna : IsNonarchimedean f) (n : ℕ) (a b : α) : ∃ m < n + 1, f ((a + b) ^ n) ≤ f (a ^ m) * f (b ^ (n - m)) := by - obtain ⟨m, hm_lt, hM⟩ := finset_image_add hna + obtain ⟨m, hm_lt, hM⟩ := finset_image_add (by aesop) (by aesop) hna (fun m => a ^ m * b ^ (n - m) * ↑(n.choose m)) (Finset.range (n + 1)) simp only [Finset.nonempty_range_iff, ne_eq, Nat.succ_ne_zero, not_false_iff, Finset.mem_range, forall_true_left] at hm_lt diff --git a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean index 028dffb4ec2f00..f887dd057b06cd 100644 --- a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean +++ b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean @@ -120,7 +120,7 @@ theorem norm_mul_le_const_mul_norm {i : ι} (hBi : B i = (1 : L)) obtain ⟨k, -, (hk : ‖∑ i : ι, (B.repr x i • ∑ i_1 : ι, B.repr y i_1 • B.repr (B i * B i_1)) ixy‖ ≤ ‖(B.repr x k • ∑ j : ι, B.repr y j • B.repr (B k * B j)) ixy‖)⟩ := - IsNonarchimedean.finset_image_add hna' + IsNonarchimedean.finset_image_add (map_zero _) (apply_nonneg _) hna' (fun i ↦ (B.repr x i • ∑ i_1 : ι, B.repr y i_1 • B.repr (B i * B i_1)) ixy) (univ : Finset ι) simp only [Finsupp.coe_smul, Finsupp.coe_finsetSum, Pi.smul_apply, Finset.sum_apply, @@ -130,7 +130,7 @@ theorem norm_mul_le_const_mul_norm {i : ι} (hBi : B i = (1 : L)) obtain ⟨k', hk'⟩ : ∃ (k' : ι), ‖∑ j : ι, B.repr y j • B.repr (B k * B j) ixy‖ ≤ ‖B.repr y k' • B.repr (B k * B k') ixy‖ := by - obtain ⟨k, hk0, hk⟩ := IsNonarchimedean.finset_image_add hna' + obtain ⟨k, hk0, hk⟩ := IsNonarchimedean.finset_image_add (map_zero _) (apply_nonneg _) hna' (fun i ↦ B.repr y i • B.repr (B k * B i) ixy) (univ : Finset ι) exact ⟨k, hk⟩ apply le_trans (mul_le_mul_of_nonneg_left hk' (norm_nonneg _)) diff --git a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean index ac24e149280c5f..e8e8c4ef5c0ea9 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean @@ -271,7 +271,8 @@ theorem norm_root_le_spectralValue {f : AlgebraNorm K L} (hf_pm : IsPowMul f) set g := fun i : ℕ ↦ p.coeff i • x ^ i obtain ⟨m, hm_in, hm⟩ : ∃ (m : ℕ) (_ : 0 < p.natDegree → m < p.natDegree), f ((Finset.range p.natDegree).sum g) ≤ f (g m) := by - obtain ⟨m, hm, h⟩ := IsNonarchimedean.finset_image_add hf_na g (Finset.range p.natDegree) + obtain ⟨m, hm, h⟩ := IsNonarchimedean.finset_image_add (map_zero _) (apply_nonneg _) hf_na g + (Finset.range p.natDegree) rw [Finset.nonempty_range_iff, ← zero_lt_iff, Finset.mem_range] at hm exact ⟨m, hm, h⟩ exact lt_of_le_of_lt hm (hn' m (hm_in h_deg)) diff --git a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean index 8dcad1cf5683a4..db2ea3a8a78c2e 100644 --- a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean +++ b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean @@ -8,6 +8,8 @@ module public import Mathlib.Analysis.Normed.Ring.Basic public import Mathlib.RingTheory.MvPowerSeries.Basic +public import Mathlib.Algebra.Order.Ring.IsNonarchimedean + /-! # Gauss norm for multivariate power series @@ -37,7 +39,11 @@ the set of all values of `v (coeff t f) * ∏ i : t.support, c i` for all `t : namespace MvPowerSeries -variable {R σ : Type*} [Semiring R] (v : R → ℝ) (c : σ → ℝ) (f : MvPowerSeries σ R) +variable {R σ : Type*} (v : R → ℝ) (c : σ → ℝ) (f : MvPowerSeries σ R) + +section Semiring + +variable [Semiring R] /-- Given a multivariate power series `f` in, a function `v : R → ℝ` and a tuple `c` of real numbers, the Gauss norm is defined as the supremum of the set of all values of @@ -81,7 +87,7 @@ lemma gaussNorm_eq_zero_iff (vZero : v 0 = 0) (vNonneg : ∀ a, v a ≥ 0) _ ≤ _ := le_gaussNorm v c f hbd n lemma gaussNorm_add_le_max (f g : MvPowerSeries σ R) (hc : 0 ≤ c) - (vNonneg : ∀ a, v a ≥ 0) (hv : ∀ x y, v (x + y) ≤ max (v x) (v y)) + (vNonneg : ∀ a, v a ≥ 0) (hv : IsNonarchimedean v) (hbfd : HasGaussNorm v c f) (hbgd : HasGaussNorm v c g) : gaussNorm v c (f + g) ≤ max (gaussNorm v c f) (gaussNorm v c g) := by have H (t : σ →₀ ℕ) : 0 ≤ ∏ i ∈ t.support, c i ^ t i := @@ -120,4 +126,106 @@ lemma gaussNorm_add_le_max (f g : MvPowerSeries σ R) (hc : 0 ≤ c) left exact gaussNorm_nonneg v c f vNonneg +private lemma c_prod_nonneg (hc : 0 ≤ c) (t : σ →₀ ℕ) : 0 ≤ t.prod (c · ^ ·) := + Finset.prod_nonneg (fun i _ ↦ pow_nonneg (hc i) (t i)) + +lemma gaussNorm_mul_le (f g : MvPowerSeries σ R) (hc : 0 ≤ c) (vNonneg : ∀ a, v a ≥ 0) + (vMul : ∀ a b, v (a * b) ≤ v a * v b) (vna : IsNonarchimedean v) + (vZero : v 0 = 0) (hbfd : HasGaussNorm v c f) (hbgd : HasGaussNorm v c g) : + gaussNorm v c (f * g) ≤ gaussNorm v c f * gaussNorm v c g := by + classical + refine Real.iSup_le ?_ ?_ + · intro t + obtain ⟨k, hk, hsum⟩ := IsNonarchimedean.finset_image_add vZero vNonneg vna + (fun a ↦ coeff a.1 f * coeff a.2 g) (Finset.antidiagonal t) + have hk' : k.1 + k.2 = t := by + simpa [Finset.mem_antidiagonal] using hk (Finset.nonempty_def.mpr ⟨(t, 0), by simp⟩) + have hprod : t.prod (c · ^ ·) = k.1.prod (c · ^ ·) * k.2.prod (c · ^ ·) := by + simp [← hk', Finsupp.prod_add_index' (h := (c · ^ ·)) (by grind) (by grind)] + rw [hprod] + refine (mul_le_mul hsum (by rfl) (mul_nonneg (c_prod_nonneg c hc k.1) (c_prod_nonneg c hc k.2)) + (vNonneg _)).trans ?_ + have : v ((coeff k.1) f * (coeff k.2) g) * (k.1.prod (c · ^ ·) * k.2.prod (c · ^ ·)) ≤ + (v (coeff k.1 f) * k.1.prod (c · ^ ·)) * (v (coeff k.2 g) * k.2.prod (c · ^ ·)) := by + calc + _ ≤ v (coeff k.1 f) * v (coeff k.2 g) * (k.1.prod (c · ^ ·) * k.2.prod (c · ^ ·)) := + mul_le_mul (vMul _ _) (by rfl) (mul_nonneg (c_prod_nonneg c hc k.1) + (c_prod_nonneg c hc k.2)) (mul_nonneg (vNonneg _) (vNonneg _)) + _ = _ := by ring + exact this.trans (mul_le_mul (le_gaussNorm v c f hbfd k.1) (le_gaussNorm v c g hbgd k.2) + (mul_nonneg (vNonneg _) (c_prod_nonneg c hc k.2)) (gaussNorm_nonneg v c f vNonneg)) + · exact mul_nonneg (gaussNorm_nonneg v c f vNonneg) (gaussNorm_nonneg v c g vNonneg) + +end Semiring + +variable [Ring R] + +/-- Predicate for when the gaussNorm is achieved by an index. -/ +abbrev AchievesGaussNorm (i : σ →₀ ℕ) : Prop := + v (coeff i f) * i.prod (c · ^ ·) = gaussNorm v c f + +section absoluteValue + +variable {α S : Type*} [LinearOrder S] [AddCommGroup α] (f : α → S) + +lemma ultrametric_strict (na : IsNonarchimedean f) + (Neg : ∀ a, f a = f (-a)) {a b : α} (hne : f a ≠ f b) : f (a + b) = max (f a) (f b) := by + wlog hab : f a > f b generalizing a b with H + · simpa [add_comm, max_comm] using (H hne.symm ((not_lt.mp hab).lt_of_ne hne)) + apply le_antisymm (na a b) + rcases le_max_iff.mp (na (a + b) (-b)) with h | h + · simpa [max_eq_left (le_of_lt hab)] using h + · exact absurd h (not_le.mpr (by simpa [Neg b] using hab)) + +variable [Semiring S] + +lemma Finset.Nonempty.map_sum_le_sup'_map + {α S : Type*} [Semiring S] [LinearOrder S] [AddCommMonoid α] (g : α → S) + {ι : Type*} {s : Finset ι} (hs : s.Nonempty) (f : ι → α) + (na : ∀ a b, g (a + b) ≤ max (g a) (g b)) : + g (∑ i ∈ s, f i) ≤ s.sup' hs fun x ↦ g (f x) := by + simp only [Finset.le_sup'_iff] + induction hs using Finset.Nonempty.cons_induction with + | singleton j => simp only [Finset.mem_singleton, Finset.sum_singleton, exists_eq_left, le_refl] + | cons j s hj _ IH => + simp only [Finset.sum_cons, Finset.mem_cons, exists_eq_or_imp] + refine (le_total (g (∑ i ∈ s, f i)) (g (f j))).imp ?_ ?_ <;> intro h + · exact (na _ _).trans (max_eq_left h).le + · exact ⟨_, IH.choose_spec.left, (na _ _).trans <| + ((max_eq_right h).le.trans IH.choose_spec.right)⟩ + +variable [DecidableEq σ] (f g : MvPowerSeries σ R) + +lemma antidiagonal_dominant (i j : σ →₀ ℕ) (vna : IsNonarchimedean v) + (vMulEq : ∀ a b, v (a * b) = v a * v b) (vNeg : ∀ a, v a = v (-a)) + (hdom : ∀ p ∈ Finset.antidiagonal (i + j), p ≠ (i, j) → + v (coeff p.1 f * coeff p.2 g) < v (coeff i f) * v (coeff j g)) : + v (coeff (i + j) (f * g)) = v (coeff i f * coeff j g) := by + rw [← vMulEq] at hdom + rw [coeff_mul, IsNonarchimedean.apply_sum_eq_of_lt vna (by grind) (k := (i, j)) + (s := Finset.antidiagonal (i + j)) (Finset.mem_antidiagonal.mpr rfl) hdom] + +lemma gaussNorm_le_mul (vMulEq : ∀ a b, v (a * b) = v a * v b) + (vna : IsNonarchimedean v) (vNeg : ∀ a, v a = v (-a)) + (hbfg : HasGaussNorm v c (f * g)) + (hdom : ∃ i j, AchievesGaussNorm v c f i ∧ AchievesGaussNorm v c g j ∧ + ∀ p ∈ Finset.antidiagonal (i + j), p ≠ (i, j) → + v (coeff p.1 f * coeff p.2 g) < v (coeff i f) * v (coeff j g)) : + gaussNorm v c f * gaussNorm v c g ≤ gaussNorm v c (f * g) := by + obtain ⟨i₀, j₀, hi₀, hj₀, hdom'⟩ := hdom + unfold AchievesGaussNorm at hi₀ hj₀ + calc + _ = (v (coeff i₀ f) * i₀.prod (c · ^ ·)) * (v (coeff j₀ g) * j₀.prod (c · ^ ·)) := by + rw [← hi₀, ← hj₀] + _ = v (coeff i₀ f) * v (coeff j₀ g) * ((i₀ + j₀).prod (c · ^ ·)) := by + have hprod : (i₀ + j₀).prod (c · ^ ·) = i₀.prod (c · ^ ·) * j₀.prod (c · ^ ·) := by + simp [Finsupp.prod_add_index', pow_add] + rw [hprod]; ring + _ = v (coeff i₀ f * coeff j₀ g) * (i₀ + j₀).prod (c · ^ ·) := by rw [vMulEq] + _ = v (coeff (i₀ + j₀) (f * g)) * (i₀ + j₀).prod (c · ^ ·) := by + rw [antidiagonal_dominant v f g i₀ j₀ vna vMulEq vNeg hdom'] + _ ≤ gaussNorm v c (f * g) := le_gaussNorm v c (f * g) hbfg (i₀ + j₀) + +end absoluteValue + end MvPowerSeries diff --git a/Mathlib/RingTheory/Polynomial/GaussNorm.lean b/Mathlib/RingTheory/Polynomial/GaussNorm.lean index 858acd5a73cb03..04250ee856e304 100644 --- a/Mathlib/RingTheory/Polynomial/GaussNorm.lean +++ b/Mathlib/RingTheory/Polynomial/GaussNorm.lean @@ -235,7 +235,7 @@ private theorem mul_gaussNorm_le_gaussNorm_mul (p q : R[X]) : apply le_of_eq_of_le _ <| (p * q).le_gaussNorm v hc0 (i + j) -- gaussNorm v c p * gaussNorm v c q is actually equal to v ((p * q).coeff (i + j)) * c ^ (i + j) rw [hi_p, hj_q, coeff_mul, Nat.sum_antidiagonal_eq_sum_range_succ_mk, - IsNonarchimedean.apply_sum_eq_of_lt hna (k := i) (by simp)] + IsNonarchimedean.apply_sum_eq_of_lt hna (k := i) (by simp) (by simp)] /- IsNonarchimedean.apply_sum_eq_of_lt makes the goal almost trivial so we are left to prove the hmax hypothesis -/ · grind From ce224279646af25dc80c231f5257bcfd6e70af45 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Wed, 17 Jun 2026 11:02:51 +0000 Subject: [PATCH 0104/1300] feat: add `Algebra.norm_zpow` (#40238) We generalize `Algebra.norm_inv` from fields to division rings and we add `Algebra.norm_zpow`. From flt-regular. --- Mathlib/RingTheory/Norm/Basic.lean | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/Norm/Basic.lean b/Mathlib/RingTheory/Norm/Basic.lean index 6859260ed69c9f..57096d1816ef5f 100644 --- a/Mathlib/RingTheory/Norm/Basic.lean +++ b/Mathlib/RingTheory/Norm/Basic.lean @@ -127,12 +127,21 @@ theorem norm_ne_zero_iff_of_basis [IsDomain R] [IsDomain S] (b : Basis ι R S) { Algebra.norm R x ≠ 0 ↔ x ≠ 0 := not_iff_not.mpr (norm_eq_zero_iff_of_basis b) -theorem norm_inv [Module.Finite K L] (x : L) : Algebra.norm K x⁻¹ = (Algebra.norm K x)⁻¹ := by +end EqZeroIff + +section DivisionRing + +variable {L : Type*} [DivisionRing L] [Algebra K L] [Module.Finite K L] + +theorem norm_inv (x : L) : Algebra.norm K x⁻¹ = (Algebra.norm K x)⁻¹ := by by_cases hx : x = 0 · simp [hx] exact mul_left_injective₀ (norm_ne_zero_iff.mpr hx) (by simp [hx, ← map_mul]) -end EqZeroIff +theorem norm_zpow (x : L) (n : ℤ) : Algebra.norm K (x ^ n) = Algebra.norm K x ^ n := + map_zpow' _ norm_inv _ _ + +end DivisionRing open IntermediateField From 2d792c9bea7859d32dd125ee02ad72fa54a7a237 Mon Sep 17 00:00:00 2001 From: Kamille Bidan <25210160030@m.fudan.edu.cn> Date: Wed, 17 Jun 2026 11:18:00 +0000 Subject: [PATCH 0105/1300] feat(ModelTheory): add `exClosure` definition for first-order formulas (#36667) Prepare for moving realizations between elementarily equivalent structures. Co-authored-by: NoneMore --- Mathlib/ModelTheory/Semantics.lean | 39 ++++++++++++++++++++++++++++++ Mathlib/ModelTheory/Syntax.lean | 6 +++++ 2 files changed, 45 insertions(+) diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index 7fe1a9e0d5939a..dfcdfdc43b2eed 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -933,6 +933,45 @@ theorem realize_iExsUnique [Finite γ] {φ : L.Formula (α ⊕ γ)} {v : α → end BoundedFormula +namespace Formula + +@[simp] +theorem realize_exClosure [DecidableEq α] (φ : L.Formula α) : + φ.exClosure.Realize M ↔ + ∃ v : φ.freeVarFinset → M, Formula.Realize (φ.restrictFreeVar id) v := by + simp [Sentence.Realize, Formula.exClosure, Formula.realize_iExs] + +theorem realize_exClosure_of_realize_equivSentence [DecidableEq α] [L[[α]].Structure M] + [(L.lhomWithConstants α).IsExpansionOn M] {φ : L.Formula α} + (h : (Formula.equivSentence φ).Realize M) : φ.exClosure.Realize M := by + rw [Formula.realize_exClosure] + exists fun a => (L.con (a : α) : M) + simpa [Formula.Realize, BoundedFormula.realize_restrictFreeVar] using h + +theorem exists_realize_equivSentence_iff_realize_exClosure + [DecidableEq α] [Nonempty M] {φ : L.Formula α} : + (∃ v : α → M, + letI := (constantsOn.structure v); + (Formula.equivSentence φ).Realize M) ↔ (φ.exClosure.Realize M) := by + constructor + · rintro ⟨v, hv⟩ + exact (Formula.realize_exClosure φ).mpr ⟨fun a => v a, + (BoundedFormula.realize_restrictFreeVar (φ := φ) (f := id) (v := fun a => v a) (v' := v) + (fun _ => rfl)).2 + (by simpa [Formula.Realize] + using (realize_equivSentence_symm M (Formula.equivSentence φ) v).2 hv)⟩ + · intro h + classical + obtain ⟨v, hv⟩ := (Formula.realize_exClosure φ).1 h + let v' := fun a => if hmem : a ∈ φ.freeVarFinset + then v ⟨a, hmem⟩ else Classical.choice inferInstance + exists v' + refine (Formula.realize_equivSentence_symm M (Formula.equivSentence φ) v').mp ?_ + simpa [Equiv.symm_apply_apply, Formula.Realize] using + (BoundedFormula.realize_restrictFreeVar v' (by grind)).1 hv + +end Formula + namespace StrongHomClass variable {F : Type*} [EquivLike F M N] [StrongHomClass L F M N] (g : F) diff --git a/Mathlib/ModelTheory/Syntax.lean b/Mathlib/ModelTheory/Syntax.lean index 1b7dfa56d6698b..3a24b6664bcf24 100644 --- a/Mathlib/ModelTheory/Syntax.lean +++ b/Mathlib/ModelTheory/Syntax.lean @@ -784,6 +784,12 @@ noncomputable def iExsUnique [Finite β] (φ : L.Formula (α ⊕ β)) : L.Formul ((φ.relabel (fun a => Sum.elim (.inl ∘ .inl) .inr a)).imp <| .iInf fun g => Term.equal (var (.inr g)) (var (.inl (.inr g)))) +variable [DecidableEq α] in +/-- `exClosure φ` is the sentence asserting that there exist values for all free variables of `φ` +such that `φ` holds. -/ +noncomputable def exClosure (φ : L.Formula α) : L.Sentence := + iExs φ.freeVarFinset (Formula.relabel Sum.inr (φ.restrictFreeVar id)) + /-- The biimplication between formulas, as a formula. -/ protected nonrec abbrev iff (φ ψ : L.Formula α) : L.Formula α := φ.iff ψ From 31beafde0b4e8eab3184a0e18e4da4a8ca06eda0 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:33:09 +0000 Subject: [PATCH 0106/1300] chore: fix non-reducible diamonds around scalar multiplication in `RingCon` (#40704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following fails before the PR, succeeds after it. ``` example {R : Type*} [Ring R] (c : RingCon R) : (RingCon.hasZSMul c : SMul ℤ c.Quotient) = RingCon.instSMulQuotient c := by with_reducible_and_instances rfl -- fails ``` Co-authored-by: sgouezel --- Mathlib/RingTheory/Congruence/Basic.lean | 2 +- Mathlib/RingTheory/Congruence/Defs.lean | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Mathlib/RingTheory/Congruence/Basic.lean b/Mathlib/RingTheory/Congruence/Basic.lean index ed6041e7d612d6..40ad52ee203bd3 100644 --- a/Mathlib/RingTheory/Congruence/Basic.lean +++ b/Mathlib/RingTheory/Congruence/Basic.lean @@ -52,7 +52,7 @@ variable [SMul α R] [IsScalarTower α R R] variable [SMul β R] [IsScalarTower β R R] variable (c : RingCon R) -instance : SMul α c.Quotient := inferInstanceAs (SMul α c.toCon.Quotient) +instance : SMul α c.Quotient := ⟨c.smulAux (Con.smul c.toCon)⟩ @[simp, norm_cast] theorem coe_smul (a : α) (x : R) : (↑(a • x) : c.Quotient) = a • (x : c.Quotient) := diff --git a/Mathlib/RingTheory/Congruence/Defs.lean b/Mathlib/RingTheory/Congruence/Defs.lean index c4521330d750d4..16f78f06af0245 100644 --- a/Mathlib/RingTheory/Congruence/Defs.lean +++ b/Mathlib/RingTheory/Congruence/Defs.lean @@ -252,6 +252,13 @@ theorem coe_one : (↑(1 : R) : c.Quotient) = 1 := end One +/-- A function used to define scalar actions on `RingCon.Quotient`. To make sure such actions coming +from different sources are reducibly defeq, they should all go through this function. -/ +def smulAux [Add R] [Mul R] {α : Type*} [SMul α R] + (c : RingCon R) (h : ∀ (a : α) (x y : R), c x y → c (a • x) (a • y)) + (a : α) (x : c.Quotient) : c.Quotient := + Quotient.map' (a • ·) (h a) x + section NegSubZSMul variable [AddGroup R] [Mul R] (c : RingCon R) @@ -268,7 +275,7 @@ instance : Sub c.Quotient := inferInstanceAs (Sub c.toAddCon.Quotient) theorem coe_sub (x y : R) : (↑(x - y) : c.Quotient) = x - y := rfl -instance hasZSMul : SMul ℤ c.Quotient := inferInstanceAs (SMul ℤ c.toAddCon.Quotient) +instance hasZSMul : SMul ℤ c.Quotient := ⟨c.smulAux (RingCon.zsmul c)⟩ @[simp, norm_cast] theorem coe_zsmul (z : ℤ) (x : R) : (↑(z • x) : c.Quotient) = z • (x : c.Quotient) := @@ -280,7 +287,7 @@ section NSMul variable [AddMonoid R] [Mul R] (c : RingCon R) -instance hasNSMul : SMul ℕ c.Quotient := inferInstanceAs (SMul ℕ c.toAddCon.Quotient) +instance hasNSMul : SMul ℕ c.Quotient := ⟨c.smulAux (RingCon.nsmul c)⟩ @[simp, norm_cast] theorem coe_nsmul (n : ℕ) (x : R) : (↑(n • x) : c.Quotient) = n • (x : c.Quotient) := @@ -353,14 +360,16 @@ instance [AddCommMagma R] [Mul R] (c : RingCon R) : AddCommMagma c.Quotient := instance [AddCommSemigroup R] [Mul R] (c : RingCon R) : AddCommSemigroup c.Quotient := inferInstanceAs <| AddCommSemigroup c.toAddCon.Quotient -instance [AddMonoid R] [Mul R] (c : RingCon R) : AddMonoid c.Quotient := - inferInstanceAs <| AddMonoid c.toAddCon.Quotient +instance [AddMonoid R] [Mul R] (c : RingCon R) : AddMonoid c.Quotient where + nsmul n x := n • x + __ : AddMonoid c.Quotient := inferInstanceAs <| AddMonoid c.toAddCon.Quotient instance [AddCommMonoid R] [Mul R] (c : RingCon R) : AddCommMonoid c.Quotient := inferInstanceAs <| AddCommMonoid c.toAddCon.Quotient -instance [AddGroup R] [Mul R] (c : RingCon R) : AddGroup c.Quotient := - inferInstanceAs <| AddGroup c.toAddCon.Quotient +instance [AddGroup R] [Mul R] (c : RingCon R) : AddGroup c.Quotient where + zsmul n x := n • x + __ : AddGroup c.Quotient := inferInstanceAs <| AddGroup c.toAddCon.Quotient instance [AddCommGroup R] [Mul R] (c : RingCon R) : AddCommGroup c.Quotient := inferInstanceAs <| AddCommGroup c.toAddCon.Quotient From 3203991ba3604bf3ac6d980d140afcbdcfbba8a9 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:33:22 +0000 Subject: [PATCH 0107/1300] chore: move generic SMul definition before AddMonoid or AddGroup instances to make sure they can use it (#40706) Co-authored-by: sgouezel --- Mathlib/Algebra/Quaternion.lean | 9 ++++++--- Mathlib/Algebra/TrivSqZeroExt/Basic.lean | 16 +++++++++------- .../Analysis/CStarAlgebra/CStarMatrix.lean | 16 +++++++++------- .../IsAlgClosed/AlgebraicClosure.lean | 7 ++++++- Mathlib/RingTheory/AdjoinRoot.lean | 19 ++++++++++++------- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/Mathlib/Algebra/Quaternion.lean b/Mathlib/Algebra/Quaternion.lean index b76bf93cde6f72..4c57a1cd268505 100644 --- a/Mathlib/Algebra/Quaternion.lean +++ b/Mathlib/Algebra/Quaternion.lean @@ -723,11 +723,14 @@ variable {S T R : Type*} [CommRing R] (r x y : R) (a b : ℍ[R]) instance : CoeTC R ℍ[R] := ⟨coe⟩ -instance instRing : Ring ℍ[R] := inferInstanceAs <| Ring ℍ[R,-1,0,-1] +instance [SMul S R] : SMul S ℍ[R] := inferInstanceAs <| SMul S ℍ[R,-1,0,-1] -instance : Inhabited ℍ[R] := inferInstanceAs <| Inhabited ℍ[R,-1,0,-1] +instance instRing : Ring ℍ[R] where + nsmul := letI := Quaternion.instSMul (S := ℕ) (R := R); (· • ·) + zsmul := letI := Quaternion.instSMul (S := ℤ) (R := R); (· • ·) + __ : Ring ℍ[R] := inferInstanceAs <| Ring ℍ[R,-1,0,-1] -instance [SMul S R] : SMul S ℍ[R] := inferInstanceAs <| SMul S ℍ[R,-1,0,-1] +instance : Inhabited ℍ[R] := inferInstanceAs <| Inhabited ℍ[R,-1,0,-1] instance [SMul S T] [SMul S R] [SMul T R] [IsScalarTower S T R] : IsScalarTower S T ℍ[R] := inferInstanceAs <| IsScalarTower S T ℍ[R,-1,0,-1] diff --git a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean index 7133a5c4559176..d9a220b6c71c85 100644 --- a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean +++ b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean @@ -197,11 +197,16 @@ instance addSemigroup [AddSemigroup R] [AddSemigroup M] : AddSemigroup (tsze R M instance addZeroClass [AddZeroClass R] [AddZeroClass M] : AddZeroClass (tsze R M) := inferInstanceAs <| AddZeroClass (R × M) -instance addMonoid [AddMonoid R] [AddMonoid M] : AddMonoid (tsze R M) := - inferInstanceAs <| AddMonoid (R × M) +instance smul [SMul S R] [SMul S M] : SMul S (tsze R M) := + inferInstanceAs <| SMul S (R × M) + +instance addMonoid [AddMonoid R] [AddMonoid M] : AddMonoid (tsze R M) where + nsmul := letI := smul (S := ℕ) (R := R) (M := M); (· • ·) + __ : AddMonoid (tsze R M) := inferInstanceAs <| AddMonoid (R × M) -instance addGroup [AddGroup R] [AddGroup M] : AddGroup (tsze R M) := - inferInstanceAs <| AddGroup (R × M) +instance addGroup [AddGroup R] [AddGroup M] : AddGroup (tsze R M) where + zsmul := letI := smul (S := ℤ) (R := R) (M := M); (· • ·) + __ : AddGroup (tsze R M) := inferInstanceAs <| AddGroup (R × M) instance addCommSemigroup [AddCommSemigroup R] [AddCommSemigroup M] : AddCommSemigroup (tsze R M) := inferInstanceAs <| AddCommSemigroup (R × M) @@ -212,9 +217,6 @@ instance addCommMonoid [AddCommMonoid R] [AddCommMonoid M] : AddCommMonoid (tsze instance addCommGroup [AddCommGroup R] [AddCommGroup M] : AddCommGroup (tsze R M) := inferInstanceAs <| AddCommGroup (R × M) -instance smul [SMul S R] [SMul S M] : SMul S (tsze R M) := - inferInstanceAs <| SMul S (R × M) - instance isScalarTower [SMul T R] [SMul T M] [SMul S R] [SMul S M] [SMul T S] [IsScalarTower T S R] [IsScalarTower T S M] : IsScalarTower T S (tsze R M) := inferInstanceAs <| IsScalarTower T S (R × M) diff --git a/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean b/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean index 7ed03d6b564b4e..3efc1706d31ec5 100644 --- a/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean +++ b/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean @@ -141,8 +141,12 @@ instance instZero [Zero A] : Zero (CStarMatrix m n A) := instance instAddZeroClass [AddZeroClass A] : AddZeroClass (CStarMatrix m n A) := inferInstanceAs <| AddZeroClass (Matrix m n A) -instance instAddMonoid [AddMonoid A] : AddMonoid (CStarMatrix m n A) := - inferInstanceAs <| AddMonoid (Matrix m n A) +instance instSMul [SMul R A] : SMul R (CStarMatrix m n A) := + inferInstanceAs <| SMul R (Matrix m n A) + +instance instAddMonoid [AddMonoid A] : AddMonoid (CStarMatrix m n A) where + nsmul := letI := instSMul (R := ℕ) (A := A) (m := m) (n := n); (· • · ) + __ : AddMonoid (CStarMatrix m n A) := inferInstanceAs <| AddMonoid (Matrix m n A) instance instAddCommMonoid [AddCommMonoid A] : AddCommMonoid (CStarMatrix m n A) := inferInstanceAs <| AddCommMonoid (Matrix m n A) @@ -153,8 +157,9 @@ instance instNeg [Neg A] : Neg (CStarMatrix m n A) := instance instSub [Sub A] : Sub (CStarMatrix m n A) := inferInstanceAs <| Sub (Matrix m n A) -instance instAddGroup [AddGroup A] : AddGroup (CStarMatrix m n A) := - inferInstanceAs <| AddGroup (Matrix m n A) +instance instAddGroup [AddGroup A] : AddGroup (CStarMatrix m n A) where + zsmul := letI := instSMul (R := ℤ) (A := A) (m := m) (n := n); (· • · ) + __ : AddGroup (CStarMatrix m n A) := inferInstanceAs <| AddGroup (Matrix m n A) instance instAddCommGroup [AddCommGroup A] : AddCommGroup (CStarMatrix m n A) := inferInstanceAs <| AddCommGroup (Matrix m n A) @@ -168,9 +173,6 @@ instance instSubsingleton [Subsingleton A] : Subsingleton (CStarMatrix m n A) := instance instNontrivial [Nonempty m] [Nonempty n] [Nontrivial A] : Nontrivial (CStarMatrix m n A) := inferInstanceAs <| Nontrivial (Matrix m n A) -instance instSMul [SMul R A] : SMul R (CStarMatrix m n A) := - inferInstanceAs <| SMul R (Matrix m n A) - instance instSMulCommClass [SMul R A] [SMul S A] [SMulCommClass R S A] : SMulCommClass R S (CStarMatrix m n A) := inferInstanceAs <| SMulCommClass R S (Matrix m n A) diff --git a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index addd091a272214..aa9c04459b4788 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -129,11 +129,16 @@ def AlgebraicClosure : Type u := namespace AlgebraicClosure -deriving instance CommRing, Inhabited for AlgebraicClosure +deriving instance Inhabited for AlgebraicClosure instance {S : Type*} [DistribSMul S k] [IsScalarTower S k k] : SMul S (AlgebraicClosure k) := inferInstanceAs <| SMul S (_ ⧸ _) +instance : CommRing (AlgebraicClosure k) where + nsmul := letI := AlgebraicClosure.instSMulOfIsScalarTower k (S := ℕ); (· • · ) + zsmul := letI := AlgebraicClosure.instSMulOfIsScalarTower k (S := ℤ); (· • · ) + __ : CommRing (AlgebraicClosure k) := inferInstanceAs <| CommRing (_ ⧸ _) + instance instAlgebra {R : Type*} [CommSemiring R] [Algebra R k] : Algebra R (AlgebraicClosure k) := inferInstanceAs <| Algebra R (_ ⧸ _) diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index 829bc3c3d9bc5b..46e60c23c827e6 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -68,7 +68,18 @@ section CommRing variable [CommRing R] (f g : R[X]) -deriving instance CommRing, Inhabited for AdjoinRoot +deriving instance Inhabited for AdjoinRoot + +instance instSMulAdjoinRoot [DistribSMul S R] [IsScalarTower S R R] : SMul S (AdjoinRoot f) := + inferInstanceAs <| SMul S (_ ⧸ _) + +instance : CommRing (AdjoinRoot f) where + nsmul := letI := instSMulAdjoinRoot (S := ℕ) (R := R); (· • ·) + zsmul := letI := instSMulAdjoinRoot (S := ℤ) (R := R); (· • ·) + __ : CommRing (AdjoinRoot f) := inferInstanceAs <| CommRing (_ ⧸ _) + +instance [DistribSMul S R] [IsScalarTower S R R] : DistribSMul S (AdjoinRoot f) := + inferInstanceAs <| DistribSMul S (_ ⧸ _) instance : DecidableEq (AdjoinRoot f) := Classical.decEq _ @@ -92,12 +103,6 @@ theorem induction_on {C : AdjoinRoot f → Prop} (x : AdjoinRoot f) (ih : ∀ p def of : R →+* AdjoinRoot f := (mk f).comp C -instance instSMulAdjoinRoot [DistribSMul S R] [IsScalarTower S R R] : SMul S (AdjoinRoot f) := - inferInstanceAs <| SMul S (_ ⧸ _) - -instance [DistribSMul S R] [IsScalarTower S R R] : DistribSMul S (AdjoinRoot f) := - inferInstanceAs <| DistribSMul S (_ ⧸ _) - @[simp] theorem smul_mk [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R[X]) : a • mk f x = mk f (a • x) := From 34c002db86b155aa62dd7da60462b70412fc46f9 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:07:13 +0000 Subject: [PATCH 0108/1300] feat: `isClosed_eqLocus` (#40712) This PR was automatically created from PR #39100 by @ADedecker via a [review comment](https://github.com/leanprover-community/mathlib4/pull/39100#discussion_r3428059834) by @ADedecker. Co-authored-by: ADedecker <48656793+ADedecker@users.noreply.github.com> --- .../Algebra/Module/ContinuousLinearMap/Basic.lean | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean index bbe7c8ee90e94e..f0f7d0b1425042 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean @@ -686,13 +686,22 @@ end ApplyAction theorem isClosed_ker [T1Space M₂] (f : M₁ →SL[σ₁₂] M₂) : IsClosed (f.ker : Set M₁) := - continuous_iff_isClosed.1 (map_continuous f) _ isClosed_singleton + isClosed_singleton.preimage f.continuous + +theorem isClosed_eqLocus [T2Space M₂] (f g : M₁ →SL[σ₁₂] M₂) : + IsClosed (f.eqLocus g : Set M₁) := + isClosed_eq f.continuous g.continuous theorem isComplete_ker {M' : Type*} [UniformSpace M'] [CompleteSpace M'] [AddCommMonoid M'] [Module R₁ M'] [T1Space M₂] (f : M' →SL[σ₁₂] M₂) : IsComplete (f.ker : Set M') := (isClosed_ker f).isComplete +theorem isComplete_eqLocus {M' : Type*} [UniformSpace M'] [CompleteSpace M'] [AddCommMonoid M'] + [Module R₁ M'] [T2Space M₂] (f g : M' →SL[σ₁₂] M₂) : + IsComplete (f.eqLocus g : Set M') := + (isClosed_eqLocus f g).isComplete + instance completeSpace_ker {M' : Type*} [UniformSpace M'] [CompleteSpace M'] [AddCommMonoid M'] [Module R₁ M'] [T1Space M₂] (f : M' →SL[σ₁₂] M₂) : CompleteSpace f.ker := @@ -701,7 +710,7 @@ instance completeSpace_ker {M' : Type*} [UniformSpace M'] [CompleteSpace M'] instance completeSpace_eqLocus {M' : Type*} [UniformSpace M'] [CompleteSpace M'] [AddCommMonoid M'] [Module R₁ M'] [T2Space M₂] (f g : M' →SL[σ₁₂] M₂) : CompleteSpace (f.toLinearMap.eqLocus g.toLinearMap) := - IsClosed.completeSpace_coe (hs := isClosed_eq (map_continuous f) (map_continuous g)) + (isComplete_eqLocus f g).completeSpace_coe section From c00d191d1f49ea170b3a61b8b0b298c2d7c1eea1 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:37:13 +0000 Subject: [PATCH 0109/1300] fix: add missing coercion lemma (#40698) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having the obvious lemma `⇑f.toNonUnitalRingHom = f`, we had some weirder lemmas to try and simplify larger terms containing `⇑f.toNonUnitalRingHom`. The unprimed name is already taken by `NonUnitalRingHomClass.toNonUnitalRingHom`; I believe the plan is to eliminate that in future, but that's out of scope for this PR. --- Mathlib/Algebra/Ring/Equiv.lean | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Ring/Equiv.lean b/Mathlib/Algebra/Ring/Equiv.lean index 88edfb047f529d..9297647839f674 100644 --- a/Mathlib/Algebra/Ring/Equiv.lean +++ b/Mathlib/Algebra/Ring/Equiv.lean @@ -701,6 +701,10 @@ theorem toNonUnitalRingHom_eq_coe (f : R ≃+* S) : f.toNonUnitalRingHom = ↑f theorem coe_toNonUnitalRingHom (f : R ≃+* S) : ⇑(f : R →ₙ+* S) = f := rfl +@[simp] +theorem coe_toNonUnitalRingHom' (f : R ≃+* S) : ⇑f.toNonUnitalRingHom = f := + rfl + theorem coe_nonUnitalRingHom_inj_iff {R S : Type*} [NonUnitalNonAssocSemiring R] [NonUnitalNonAssocSemiring S] (f g : R ≃+* S) : f = g ↔ (f : R →ₙ+* S) = g := ⟨fun h => by rw [h], fun h => ext <| NonUnitalRingHom.ext_iff.mp h⟩ @@ -710,12 +714,12 @@ theorem toNonUnitalRingHom_refl : (RingEquiv.refl R).toNonUnitalRingHom = NonUnitalRingHom.id R := rfl -@[simp] +@[deprecated apply_symm_apply (since := "2026-06-16")] theorem toNonUnitalRingHom_apply_symm_toNonUnitalRingHom_apply (e : R ≃+* S) : ∀ y : S, e.toNonUnitalRingHom (e.symm.toNonUnitalRingHom y) = y := e.toEquiv.apply_symm_apply -@[simp] +@[deprecated symm_apply_apply (since := "2026-06-16")] theorem symm_toNonUnitalRingHom_apply_toNonUnitalRingHom_apply (e : R ≃+* S) : ∀ x : R, e.symm.toNonUnitalRingHom (e.toNonUnitalRingHom x) = x := Equiv.symm_apply_apply e.toEquiv From ddd4c00ead8d964427c49289ee4be172a08ec4f5 Mon Sep 17 00:00:00 2001 From: Vasilii Nesterov <118051017+vasnesterov@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:20:38 +0000 Subject: [PATCH 0110/1300] feat(Tactic/ComputeAsymptotics/Multiseries): basic constructions (#40014) Introduce basic constructions for multiseries: `const`, `monomial`, `monomialRpow`. --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + .../ComputeAsymptotics/Multiseries/Basic.lean | 287 ++++++++++++++++++ .../ComputeAsymptotics/Multiseries/Basis.lean | 2 +- 4 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3231bbedb8ef7a..57d9493e5cebd8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7199,6 +7199,7 @@ public import Mathlib.Tactic.ClickSuggestions.Util public import Mathlib.Tactic.Coe public import Mathlib.Tactic.Common public import Mathlib.Tactic.ComputeAsymptotics.Lemmas +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basic public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index f7fe1f5c1e9e22..50686dca468d2e 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -68,6 +68,7 @@ public import Mathlib.Tactic.ClickSuggestions.Util public import Mathlib.Tactic.Coe public import Mathlib.Tactic.Common public import Mathlib.Tactic.ComputeAsymptotics.Lemmas +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basic public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean new file mode 100644 index 00000000000000..7ebab0b38796a1 --- /dev/null +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean @@ -0,0 +1,287 @@ +/- +Copyright (c) 2026 Vasilii Nesterov. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Vasilii Nesterov +-/ +module + +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis + +/-! +# Basic constructions for multiseries + +## Main definitions + +Let `[b₁, ..., bₙ]` be our basis. + +* `const c` represents a constant multiseries `c • b₁⁰ ... bₙ⁰`. + Then we define `zero` and `one` in terms of it. +* `monomial k` represents a monomial `bₖ`. +* `monomialRpow k r` represents a monomial `bₖʳ`. + +For each construction, we provide two definitions: one for `Multiseries` and one for +`MultiseriesExpansion`. We then prove structural `simp`-lemmas describing their relationships with +`MultiseriesExpansion.seq` and `MultiseriesExpansion.toFun`. Finally, we prove that all +constructions are `Sorted` and `Approximates` their attached functions. + +-/ + +@[expose] public section + +namespace Tactic.ComputeAsymptotics + +namespace MultiseriesExpansion + +open Filter Stream' Topology + +mutual + +/-- `Multiseries`-part of `MultiseriesExpansion.const`. -/ +def Multiseries.const (basis_hd : ℝ → ℝ) (basis_tl : Basis) (c : ℝ) : + Multiseries basis_hd basis_tl := + .cons 0 (const basis_tl c) .nil + +/-- Multiseries representing a constant. -/ +def const (basis : Basis) (c : ℝ) : MultiseriesExpansion basis := + match basis with + | [] => ofReal c + | List.cons basis_hd basis_tl => mk (Multiseries.const basis_hd basis_tl c) (fun _ ↦ c) + +end + +/-- Neutral element for addition. It is `0 : ℝ` for the empty basis and `[]` otherwise. -/ +def zero {basis : Basis} : MultiseriesExpansion basis := + match basis with + | [] => ofReal 0 + | List.cons _ _ => mk .nil (fun _ ↦ 0) + +/-- This instance is needed to create an instance for `AddCommMonoid (MultiseriesExpansion basis)`, +which is necessary for using the `abel` tactic in our proofs. -/ +instance {basis : Basis} : Zero (MultiseriesExpansion basis) where + zero := zero + +/-- This instance is needed to create an instance for `AddCommMonoid (MultiseriesExpansion basis)`, +which is necessary for using the `abel` tactic in our proofs. -/ +instance {basis_hd : ℝ → ℝ} {basis_tl : Basis} : Zero (Multiseries basis_hd basis_tl) where + zero := .nil + +/-- `Multiseries`-part of `MultiseriesExpansion.one`. -/ +def Multiseries.one {basis_hd : ℝ → ℝ} {basis_tl : Basis} : Multiseries basis_hd basis_tl := + Multiseries.const _ _ 1 + +/-- Neutral element for multiplication. -/ +def one {basis : Basis} : MultiseriesExpansion basis := + const basis 1 + +mutual + +/-- `Multiseries`-part of `MultiseriesExpansion.monomialRpow`. -/ +noncomputable def Multiseries.monomialRpow (basis_hd : ℝ → ℝ) (basis_tl : Basis) (n : ℕ) (r : ℝ) : + Multiseries basis_hd basis_tl := + match n with + | 0 => .cons r one .nil + | m + 1 => .cons 0 (monomialRpow _ m r) .nil + +/-- Multiseries representing `basis[n] ^ r`. -/ +noncomputable def monomialRpow (basis : Basis) (n : ℕ) (r : ℝ) : MultiseriesExpansion basis := + match basis with + | [] => default + | List.cons basis_hd basis_tl => + mk (Multiseries.monomialRpow _ _ n r) ((basis_hd :: basis_tl)[n]! ^ r) + +end + +/-- `Multiseries`-part of `MultiseriesExpansion.monomial`. -/ +noncomputable def Multiseries.monomial (basis_hd : ℝ → ℝ) (basis_tl : Basis) (n : ℕ) : + Multiseries basis_hd basis_tl := + Multiseries.monomialRpow _ _ n 1 + +/-- Multiseries representing `basis[n]`. -/ +noncomputable def monomial (basis : Basis) (n : ℕ) : MultiseriesExpansion basis := + monomialRpow _ n 1 + +theorem zero_def {basis_hd basis_tl} : + (0 : MultiseriesExpansion (basis_hd :: basis_tl)) = mk .nil (fun _ ↦ 0) := + rfl + +@[simp] +theorem Multiseries.zero_def {basis_hd : ℝ → ℝ} {basis_tl : Basis} : + (0 : Multiseries basis_hd basis_tl) = .nil := rfl + +theorem Multiseries.const_def {basis_hd basis_tl} (c : ℝ) : + Multiseries.const basis_hd basis_tl c = + Multiseries.cons 0 (MultiseriesExpansion.const basis_tl c) .nil := by + simp [Multiseries.const] + +@[simp] +theorem const_toFun' {basis : Basis} {c : ℝ} : (const basis c).toFun = fun _ ↦ c := by + match basis with + | [] => simp [const, ofReal, toReal] + | List.cons _ _ => simp [const] + +@[simp] +theorem const_seq {basis_hd basis_tl} {c : ℝ} : + (const (basis_hd :: basis_tl) c).seq = Multiseries.const basis_hd basis_tl c := by + simp [const, Multiseries.const] + +@[simp] +theorem zero_toFun {basis : Basis} : (@zero basis).toFun = 0 := by + match basis with + | [] => rfl + | List.cons _ _ => rfl + +theorem Multiseries.one_def {basis_hd basis_tl} : + @Multiseries.one basis_hd basis_tl = Multiseries.cons 0 MultiseriesExpansion.one .nil := by + simp [Multiseries.one, Multiseries.const_def, MultiseriesExpansion.one] + +@[simp] +theorem one_toFun {basis : Basis} : (@one basis).toFun = 1 := by + simp [one] + rfl + +@[simp] +theorem one_seq {basis_hd : ℝ → ℝ} {basis_tl : Basis} : + (@one (basis_hd :: basis_tl)).seq = Multiseries.one := by + simp [one, Multiseries.one, const] + +mutual + +theorem Multiseries.const_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} {c : ℝ} : + (Multiseries.const basis_hd basis_tl c).Sorted := by + simp only [Multiseries.const] + exact const_sorted.cons_nil + +/-- Constants are well-ordered. -/ +theorem const_sorted {basis : Basis} {c : ℝ} : + (const basis c).Sorted := by + cases basis with + | nil => constructor + | cons basis_hd basis_tl => + simpa only [const, sorted_iff_seq_sorted, mk_seq] using Multiseries.const_sorted + +end + +/-- Zero is well-ordered. -/ +theorem zero_sorted {basis : Basis} : (0 : MultiseriesExpansion basis).Sorted := by + cases basis with + | nil => constructor + | cons => apply Sorted.nil + +theorem Multiseries.one_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} : + (Multiseries.one : Multiseries basis_hd basis_tl).Sorted := + Multiseries.const_sorted + +/-- `one` is Sorted. -/ +theorem one_sorted {basis : Basis} : one.Sorted (basis := basis) := + const_sorted + +/-- The constant multiseries approximates the constant function. -/ +theorem const_approximates {c : ℝ} {basis : Basis} (h_basis : WellFormedBasis basis) : + (const basis c).Approximates := by + cases basis with + | nil => simp + | cons basis_hd basis_tl => + simp only [const, Multiseries.const] + apply (const_approximates h_basis.tail).cons _ (by simp) + exact Majorized.const <| h_basis.tendsto_atTop (by simp) + +/-- `zero` approximates the zero function. -/ +theorem zero_approximates {basis : Basis} : + (@zero basis).Approximates := by + cases basis with + | nil => simp [zero] + | cons => exact Approximates.nil (by rfl) + +/-- `one` approximates the unit function. -/ +theorem one_approximates {basis : Basis} (h_basis : WellFormedBasis basis) : + (@one basis).Approximates := + const_approximates h_basis + +@[simp] +theorem monomialRpow_toFun {basis : Basis} {n : Fin (List.length basis)} {r : ℝ} : + (monomialRpow basis n r).toFun = basis[n] ^ r := by + cases basis with + | nil => grind + | cons basis_hd basis_tl => cases n using Fin.cases <;> simp [monomialRpow] + +@[simp] +theorem monomialRpow_seq {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} {r : ℝ} : + (monomialRpow (basis_hd :: basis_tl) n r).seq = Multiseries.monomialRpow _ _ n r := by + simp [monomialRpow] + +mutual + +theorem Multiseries.monomialRpow_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} {r : ℝ} : + (@Multiseries.monomialRpow basis_hd basis_tl n r).Sorted := by + cases n with + | zero => + simp only [Multiseries.monomialRpow] + exact Sorted.cons_nil const_sorted + | succ m => + simp only [Multiseries.monomialRpow] + exact Sorted.cons_nil monomialRpow_sorted + +/-- `monomial` is well-ordered. -/ +theorem monomialRpow_sorted {basis : Basis} {n : ℕ} {r : ℝ} : + (monomialRpow basis n r).Sorted := by + cases basis with + | nil => constructor + | cons basis_hd basis_tl => + simpa only [sorted_iff_seq_sorted, monomialRpow_seq] using Multiseries.monomialRpow_sorted + +end + +/-- `monomialRpow` approximates the monomial function. -/ +theorem monomialRpow_approximates {basis : Basis} {n : Fin (List.length basis)} {r : ℝ} + (h_basis : WellFormedBasis basis) : + (monomialRpow basis n r).Approximates := by + cases basis with + | nil => simp + | cons basis_hd basis_tl => + simp only [List.length_cons, monomialRpow, Fin.is_lt, getElem!_pos] + cases n using Fin.cases with + | zero => + simp only [Fin.coe_ofNat_eq_mod, Nat.zero_mod, Multiseries.monomialRpow, + List.getElem_cons_zero] + apply (one_approximates h_basis.tail).cons _ (by simp) + exact Majorized.self <| h_basis.tendsto_atTop (by simp) + | succ m => + simp only [Fin.val_succ, Multiseries.monomialRpow, List.getElem_cons_succ] + apply (monomialRpow_approximates h_basis.tail).cons _ (by simp) + apply h_basis.tail_pow_majorized_head (by simp) + +@[simp] +theorem monomial_toFun {basis : Basis} {n : ℕ} (h : n < basis.length) : + (monomial basis n).toFun = basis[n] := by + let n' : Fin basis.length := ⟨n, h⟩ + conv_lhs => rw [show n = n'.val by simp [n']] + convert! monomialRpow_toFun + simp + grind + +theorem monomial_toFun' {basis : Basis} {n : Fin basis.length} : + (monomial basis n).toFun = basis[n] := by + simp + +@[simp] +theorem monomial_seq {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} : + (monomial (basis_hd :: basis_tl) n).seq = Multiseries.monomial _ _ n := + monomialRpow_seq + +theorem Multiseries.monomial_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} : + (@Multiseries.monomial basis_hd basis_tl n).Sorted := + Multiseries.monomialRpow_sorted + +/-- `monomial` is well-ordered. -/ +theorem monomial_sorted {basis : Basis} {n : ℕ} : (monomial basis n).Sorted := + monomialRpow_sorted + +/-- `monomial` approximates the monomial function. -/ +theorem monomial_approximates {basis : Basis} {n : Fin (List.length basis)} + (h_basis : WellFormedBasis basis) : (monomial basis n).Approximates := + monomialRpow_approximates h_basis + +end MultiseriesExpansion + +end Tactic.ComputeAsymptotics diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean index 771abcedd265ef..81f1baed725e6f 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Vasilii Nesterov -/ module -public import Mathlib.Analysis.Complex.Exponential + public import Mathlib.Analysis.Asymptotics.AsymptoticEquivalent public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs From 14f97d34085433072577aa03ce025ce8867016f4 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:20:48 +0000 Subject: [PATCH 0111/1300] chore(Matrix/GeneralLinearGroup/Projective): sort out namespace and golf the proof (#40666) --- Mathlib/GroupTheory/QuotientGroup/Defs.lean | 6 ++ .../Matrix/GeneralLinearGroup/Basic.lean | 25 ++++- .../Matrix/GeneralLinearGroup/Defs.lean | 17 +++- .../Matrix/GeneralLinearGroup/Projective.lean | 97 +++++++++++++------ .../Projectivization/Action.lean | 13 ++- 5 files changed, 121 insertions(+), 37 deletions(-) diff --git a/Mathlib/GroupTheory/QuotientGroup/Defs.lean b/Mathlib/GroupTheory/QuotientGroup/Defs.lean index 4d6ae589c68783..dcec9bc41d43c6 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Defs.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Defs.lean @@ -278,6 +278,12 @@ theorem ker_lift (φ : G →* M) (HN : N ≤ φ.ker) : rw [← congrArg MonoidHom.ker (lift_comp_mk' N φ HN), ← MonoidHom.comap_ker, Subgroup.map_comap_eq_self_of_surjective (mk'_surjective N)] +@[to_additive] +lemma injective_lift_iff (φ : G →* M) (HN : N ≤ φ.ker) : + Function.Injective (QuotientGroup.lift N φ HN) ↔ N = φ.ker := by + rw [← MonoidHom.ker_eq_bot_iff, QuotientGroup.ker_lift, Subgroup.map_eq_bot_iff] + grind [QuotientGroup.ker_mk'] + /-- A surjective group homomorphism `φ : G →* H` with `N = ker(φ)` descends (i.e. `lift`s) to a group isomorphism `G/N ≃* H`. -/ @[to_additive /-- A surjective `AddGroup` homomorphism `φ : G →+ H` with `N = ker(φ)` descends diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Basic.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Basic.lean index c8afa36c790e37..33cf339f419e47 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Basic.lean @@ -46,7 +46,7 @@ lemma mem_center_iff_val_mem_range_scalar {g : GL n R} : refine Matrix.mem_range_scalar_of_commute_transvectionStruct fun t ↦ ?_ simpa [Units.ext_iff] using! Subgroup.mem_center_iff.mp hg (.mk _ _ t.mul_inv t.inv_mul) · refine fun ⟨a, ha⟩ ↦ Subgroup.mem_center_iff.mpr fun h ↦ ?_ - simpa [Units.ext_iff, ← ha] using! (scalar_commute a (mul_comm a ·) h.val).symm + simp [-scalar_apply, Units.ext_iff, ← ha, Matrix.scalar_comm a (Commute.all _)] @[deprecated (since := "2026-02-08")] alias mem_center_iff_val_eq_scalar := mem_center_iff_val_mem_range_scalar @@ -74,8 +74,31 @@ lemma center_eq_range_scalar : @[deprecated (since := "2026-02-08")] alias center_eq_range_units := center_eq_range_scalar +lemma map_center_le {S : Type*} [CommRing S] (f : R →+* S) : + Subgroup.center (GL n R) ≤ (Subgroup.center (GL n S)).comap (map f) := fun u hu ↦ by + simp only [GeneralLinearGroup.center_eq_range_scalar, MonoidHom.mem_range, + Subgroup.mem_comap] at hu ⊢ + obtain ⟨r, rfl⟩ := hu + exact ⟨(Units.map f) r, GeneralLinearGroup.map_scalar _ _ |>.symm⟩ + end Center end GeneralLinearGroup +lemma SpecialLinearGroup.toGL_mem_center_iff {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] + (g : SpecialLinearGroup n R) : + toGL g ∈ Subgroup.center (GL n R) ↔ g ∈ Subgroup.center (SpecialLinearGroup n R) := by + if hn : IsEmpty n then simp [Subgroup.center_eq_top] else + replace hn : Nonempty n := by simpa using hn + obtain ⟨i⟩ := hn + simp only [GeneralLinearGroup.center_eq_range_scalar, MonoidHom.mem_range, + mem_center_iff, scalar_apply] + refine ⟨fun ⟨r, hr⟩ ↦ ⟨r, by simpa [Units.ext_iff] using congr(GeneralLinearGroup.det $hr), + by simpa [Units.ext_iff] using hr⟩, fun ⟨r, hr1, hr⟩ ↦ ⟨⟨r, g⁻¹.1 i i, ?_, ?_⟩, + by simp [Units.ext_iff, hr]⟩⟩ + · simpa [-mul_inv_cancel, ← hr, ← pow_succ', + Nat.sub_one_add_one Fintype.card_pos.ne.symm] using + Matrix.ext_iff.2 (Subtype.ext_iff.1 (mul_inv_cancel g)) i i + · simpa [-inv_mul_cancel, ← hr] using Matrix.ext_iff.2 (Subtype.ext_iff.1 (inv_mul_cancel g)) i i + end Matrix diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean index 5572c3144c2f05..966882903956a8 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean @@ -52,23 +52,25 @@ variable {n : Type u} [DecidableEq n] [Fintype n] {R : Type v} variable (n) in /-- Scalar matrix as an element of `GL n R`. -/ -@[simps!] def scalar [Semiring R] : Rˣ →* GL n R := Units.map (Matrix.scalar n).toMonoidHom -#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. -Assistance investigating this would be appreciated. -/ -attribute [nolint simpNF] _root_.Matrix.GeneralLinearGroup.val_inv_scalar_apply - section CoeFnInstance instance instCoeFun [Semiring R] : CoeFun (GL n R) fun _ => n → n → R where coe A := (A : Matrix n n R) +@[simp] +lemma coe_scalar [Semiring R] (u : Rˣ) : ↑(scalar n u) = Matrix.scalar n u.1 := rfl + end CoeFnInstance variable [CommRing R] +lemma scalar_commute (u : Rˣ) (A : GL n R) : scalar n u * A = A * scalar n u := by + ext : 1 + rw [Units.val_mul, Units.val_mul, coe_scalar, Matrix.scalar_comm _ (Commute.all _)] + /-- The determinant of a unit matrix is itself a unit. -/ @[simps] def det : GL n R →* Rˣ where @@ -220,6 +222,11 @@ lemma coe_map_inv_mul_map (g : GL n R) : g.val⁻¹.map f * g.val.map f = 1 := b rw [← Matrix.map_mul] simp only [isUnits_det_units, nonsing_inv_mul, map_zero, map_one, Matrix.map_one] +lemma map_scalar (u : Rˣ) : map f (scalar n u) = scalar n (Units.map f u) := by + ext + simp [Matrix.diagonal_apply] + split <;> simp + section kronecker variable {R m : Type*} [CommSemiring R] [Fintype m] [DecidableEq m] diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean index e71b01a2ac3414..d7cc42e2829ffb 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2026 Yury G. Kudryashov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Yury G. Kudryashov +Authors: Yury G. Kudryashov, Edison Xie -/ module @@ -17,11 +17,22 @@ In this file we define `Matrix.ProjGenLinGroup n R` as the quotient of `GL n R` We introduce notation `PGL(n, R)` for this group, which works if `n` is either a finite type or a natural number. If `n` is a number, then `PGL(n, R)` is interpreted as `PGL(Fin n, R)`. + +## Main definitions + +* `Matrix.SpecialLinearGroup.toPGL` is the natural map from `SL(n, R)` to `PGL(n, R)`. + +* `Matrix.ProjectiveSpecialLinearGroup.toPGL` is the natural + inclusion from `PSL(n, R)` to `PGL(n, R)`. + +* `Matrix.ProjectiveSpecialLinearGroup.isoPSLOfAlgClosed` is an isomorphism between + `PGL(n, F)` and `PSL(n, F)` in the case of an algebraically closed field. + -/ open scoped MatrixGroups -public section +@[expose] public section namespace Matrix @@ -61,6 +72,9 @@ theorem ker_mk : mk.ker = Subgroup.center (GL n R) := QuotientGroup.ker_mk' _ theorem mk_eq_one {g : GL n R} : mk g = 1 ↔ g ∈ Subgroup.center (GL n R) := by rw [← MonoidHom.mem_ker, ker_mk] +@[simp] +lemma mk_one : mk (1 : GL n R) = 1 := rfl + @[simp] theorem mk_scalar (u : Rˣ) : mk (.scalar n u) = 1 := by rw [← MonoidHom.mem_ker, ker_mk, GeneralLinearGroup.center_eq_range_scalar] @@ -71,41 +85,43 @@ theorem induction_on {motive : PGL(n, R) → Prop} (g : PGL(n, R)) (mk : ∀ g : GL n R, motive (ProjGenLinGroup.mk g)) : motive g := Quotient.inductionOn g mk +end ProjGenLinGroup + section isoPSL +variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] + +open Matrix.ProjGenLinGroup + +namespace SpecialLinearGroup + +/-- The natural map from `SL(n, R)` to `PGL(n, R)` by composing the maps from `SL` to `GL` and the + quotient map from `GL` to `PGL`. -/ +abbrev toPGL : SpecialLinearGroup n R →* PGL(n, R) := mk.comp toGL + +lemma toPGL_ker : toPGL.ker = Subgroup.center (SpecialLinearGroup n R) := by + ext; simp [toGL_mem_center_iff] + +end SpecialLinearGroup + +namespace ProjectiveSpecialLinearGroup + open Matrix.SpecialLinearGroup /-- The natural inclusion map from `PSL(n, R)` to `PGL(n, R)` induced by the inclusion map from `SL(n, R)` to `GL(n, R)`. -/ -@[expose] -def _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL : - ProjectiveSpecialLinearGroup n R →* PGL(n, R) := - QuotientGroup.lift _ (mk.comp toGL) fun x hx ↦ by - simp only [mem_center_iff, scalar_apply, MonoidHom.mem_ker, MonoidHom.coe_comp, - Function.comp_apply, mk_eq_one, GeneralLinearGroup.mem_center_iff_val_mem_range_scalar, - coe_GL_coe_matrix, Set.mem_range] at hx ⊢ - exact ⟨hx.choose, hx.choose_spec.2⟩ +def toPGL : ProjectiveSpecialLinearGroup n R →* PGL(n, R) := + QuotientGroup.lift _ SpecialLinearGroup.toPGL <| le_of_eq toPGL_ker.symm @[simp] -lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_mk (g : SpecialLinearGroup n R) : +lemma toPGL_mk (g : SpecialLinearGroup n R) : ProjectiveSpecialLinearGroup.toPGL g = mk (toGL g) := rfl -lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_injective : - Function.Injective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun x y h ↦ by - induction x using QuotientGroup.induction_on with | H x => - induction y using QuotientGroup.induction_on with | H y => - simp only [ProjectiveSpecialLinearGroup.toPGL_mk, mk_eq_mk_iff] at h - rw [← QuotientGroup.mk'_apply, ← QuotientGroup.mk'_apply] - simp only [QuotientGroup.mk'_eq_mk', mem_center_iff] - obtain ⟨u, hu'⟩ := h - have hu : u.1 ^ Fintype.card n = 1 := by - simpa [Units.ext_iff] using congr(Matrix.GeneralLinearGroup.det $hu') - set z : SpecialLinearGroup n R := ⟨scalar n u.1, by simpa using hu⟩ with hz_eq - have hz : (GeneralLinearGroup.scalar n) u = toGL z := by ext; simp [hz_eq] - refine ⟨z, ⟨u.1, hu, by simp [hz_eq]⟩, ?_⟩ - rwa [hz, ← map_mul, toGL_inj] at hu' - -lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_of_roots +lemma toPGL_injective : + Function.Injective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := + QuotientGroup.injective_lift_iff _ _ _ |>.2 toPGL_ker.symm + +lemma toPGL_surj_of_roots (hR : ∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r) : Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun g ↦ by induction g using Matrix.ProjGenLinGroup.induction_on with | mk g => @@ -117,10 +133,10 @@ lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_of_roots use QuotientGroup.mk ⟨r.1 • g.1, hr⟩ simp only [ProjectiveSpecialLinearGroup.toPGL_mk, mk_eq_mk_iff] refine ⟨r⁻¹, Units.ext ?_⟩ - simp only [Units.val_mul, coe_GL_coe_matrix,GeneralLinearGroup.val_scalar_apply] + simp only [Units.val_mul, coe_GL_coe_matrix, GeneralLinearGroup.coe_scalar] simp [← Matrix.mul_smul, ← Matrix.diagonal_smul, Pi.smul_def, smul_eq_mul] -lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_iff [Nonempty n] : +lemma toPGL_surj_iff [Nonempty n] : Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) ↔ ∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r := by refine ⟨fun h r ↦ ?_, ProjectiveSpecialLinearGroup.toPGL_surj_of_roots⟩ @@ -156,9 +172,13 @@ noncomputable def isoPSLOfAlgClosed {F : Type*} [Field F] [IsAlgClosed F] : MulEquiv.symm (MulEquiv.ofBijective Matrix.ProjectiveSpecialLinearGroup.toPGL ⟨Matrix.ProjectiveSpecialLinearGroup.toPGL_injective, Function.surjective_to_subsingleton _⟩) +end ProjectiveSpecialLinearGroup + end isoPSL -variable {M : Type*} [Monoid M] +namespace ProjGenLinGroup + +variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] {M : Type*} [Monoid M] /-- Lift a monoid homomorphism `f : GL n R →* M` that vanishes on all scalar matrices to a homomorphism from `PGL(n, R)`. -/ @@ -191,6 +211,23 @@ theorem mk_smul {α : Type*} [MulAction (GL n R) α] (h) (g : GL n R) (a : α) : mk g • a = g • a := by rfl +/-- The monoid hom between `PGL(n, R)` and `PGL(n, S)` induced by a + ring homomorphism `f : R →+* S`. -/ +def map {S : Type*} [CommRing S] (f : R →+* S) : PGL(n, R) →* PGL(n, S) := + QuotientGroup.map _ _ (GeneralLinearGroup.map (n := n) f) <| GeneralLinearGroup.map_center_le f + +@[simp] +lemma map_id : map (RingHom.id R) = MonoidHom.id (PGL(n, R)) := QuotientGroup.map_id _ + +@[simp] +lemma map_mk {S : Type*} [CommRing S] (f : R →+* S) (g : GL n R) : + map f (mk g) = mk (GeneralLinearGroup.map f g) := rfl + +lemma map_comp {S T : Type*} [CommRing S] [CommRing T] (f : R →+* S) (g : S →+* T) : + map (n := n) (g.comp f) = (map g).comp (map f) := by + ext g + induction g using Matrix.ProjGenLinGroup.induction_on with | mk g => simp + variable [Fact (Even (Fintype.card n))] [LinearOrder R] [IsStrictOrderedRing R] /-- In case of an even dimension, the sign of the determinant of `g : PGL(n, R)` is well-defined. -/ diff --git a/Mathlib/LinearAlgebra/Projectivization/Action.lean b/Mathlib/LinearAlgebra/Projectivization/Action.lean index 1cbfb0e7a71d0f..7ff05dfca850b4 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Action.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Action.lean @@ -11,7 +11,7 @@ public import Mathlib.LinearAlgebra.Projectivization.Basic public import Mathlib.LinearAlgebra.SpecialLinearGroup public import Mathlib.LinearAlgebra.Transvection.Basic public import Mathlib.LinearAlgebra.Matrix.IsDiag -public import Mathlib.LinearAlgebra.Matrix.ProjectiveSpecialLinearGroup +public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Projective public import Mathlib.LinearAlgebra.Center /-! @@ -240,6 +240,17 @@ instance : IsPreprimitive (Matrix.ProjectiveSpecialLinearGroup ι K) (ℙ K (ι {toFun := id, map_smul' := by intros; simp; rfl} (prePrimitive_SL (ι := ι) (K := K)) Function.surjective_id +open MatrixGroups Matrix.ProjGenLinGroup + +instance : MulAction PGL(ι, K) (ℙ K (ι → K)) := + mulActionOfGL fun u ↦ ind fun v hv ↦ by + simp only [smul_mk, mk_eq_mk_iff] + exact ⟨u, by simp [Units.smul_def]⟩ + +@[simp] +lemma PGL.mk_smul_mk (g : GL ι K) {v : ι → K} (hv : v ≠ 0) : + (.mk g : PGL(ι, K)) • mk K v hv = mk K (g • v) (smul_ne_zero_iff_ne g|>.2 hv) := rfl + end Field end Projectivization From 6ac35b674ab1680c90d29efb843a5ed238ca258f Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:20:58 +0000 Subject: [PATCH 0112/1300] chore: remove redudant `nolint simpNF` (#40680) Remove the attribute whenever its redundant. Some of this comes from #23201, not sure about why others work. Co-authored-by: Batixx --- Mathlib/Algebra/Group/Subgroup/Map.lean | 6 +----- Mathlib/Algebra/Group/Submonoid/Operations.lean | 6 +----- Mathlib/CategoryTheory/Localization/Construction.lean | 8 ++------ Mathlib/CategoryTheory/PathCategory/Basic.lean | 4 +--- Mathlib/CategoryTheory/WithTerminal/Basic.lean | 4 +--- Mathlib/Data/Multiset/MapFold.lean | 6 +----- Mathlib/Data/Option/Basic.lean | 6 +----- Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean | 4 ++-- Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean | 4 +--- Mathlib/ModelTheory/Order.lean | 2 +- Mathlib/Order/Filter/Map.lean | 6 +----- Mathlib/RingTheory/Extension/Generators.lean | 8 ++------ Mathlib/Topology/MetricSpace/Snowflaking.lean | 2 +- 13 files changed, 16 insertions(+), 50 deletions(-) diff --git a/Mathlib/Algebra/Group/Subgroup/Map.lean b/Mathlib/Algebra/Group/Subgroup/Map.lean index d05286dc6eca13..5946958e6bda6c 100644 --- a/Mathlib/Algebra/Group/Subgroup/Map.lean +++ b/Mathlib/Algebra/Group/Subgroup/Map.lean @@ -158,11 +158,7 @@ theorem mem_map_equiv {f : G ≃* N} {K : Subgroup G} {x : N} : x ∈ K.map f.toMonoidHom ↔ f.symm x ∈ K := Set.mem_image_equiv --- The simpNF linter says that the LHS can be simplified via `Subgroup.mem_map`. --- However this is a higher priority lemma. --- It seems the side condition `hf` is not applied by `simpNF`. --- https://github.com/leanprover/std4/issues/207 -@[to_additive (attr := simp 1100, nolint simpNF)] +@[to_additive (attr := simp 1100)] theorem mem_map_iff_mem {f : G →* N} (hf : Function.Injective f) {K : Subgroup G} {x : G} : f x ∈ K.map f ↔ x ∈ K := hf.mem_set_image diff --git a/Mathlib/Algebra/Group/Submonoid/Operations.lean b/Mathlib/Algebra/Group/Submonoid/Operations.lean index 621a9b3897d077..82fdff1c1df514 100644 --- a/Mathlib/Algebra/Group/Submonoid/Operations.lean +++ b/Mathlib/Algebra/Group/Submonoid/Operations.lean @@ -235,11 +235,7 @@ theorem apply_coe_mem_map (f : F) (S : Submonoid M) (x : S) : f x ∈ S.map f := theorem map_map (g : N →* P) (f : M →* N) : (S.map f).map g = S.map (g.comp f) := SetLike.coe_injective <| image_image _ _ _ --- The simpNF linter says that the LHS can be simplified via `Submonoid.mem_map`. --- However this is a higher priority lemma. --- It seems the side condition `hf` is not applied by `simpNF`. --- https://github.com/leanprover/std4/issues/207 -@[to_additive (attr := simp 1100, nolint simpNF)] +@[to_additive (attr := simp 1100)] theorem mem_map_iff_mem {f : F} (hf : Function.Injective f) {S : Submonoid M} {x : M} : f x ∈ S.map f ↔ x ∈ S := hf.mem_set_image diff --git a/Mathlib/CategoryTheory/Localization/Construction.lean b/Mathlib/CategoryTheory/Localization/Construction.lean index 15b685a2cd1179..25bf8f4eb82a31 100644 --- a/Mathlib/CategoryTheory/Localization/Construction.lean +++ b/Mathlib/CategoryTheory/Localization/Construction.lean @@ -70,20 +70,16 @@ the category `C` -/ def ιPaths (X : C) : Paths (LocQuiver W) := ⟨X⟩ -#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. -Assistance investigating this would be appreciated. -/ /-- The morphism in the path category associated to a morphism in the original category. -/ -@[simp, nolint simpNF] +@[simp] def ψ₁ {X Y : C} (f : X ⟶ Y) : ιPaths W X ⟶ ιPaths W Y := (Paths.of _).map (Sum.inl f) #adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. Assistance investigating this would be appreciated. -/ attribute [nolint simpNF] ψ₁.eq_1 -#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. -Assistance investigating this would be appreciated. -/ /-- The morphism in the path category corresponding to a formal inverse. -/ -@[simp, nolint simpNF] +@[simp] def ψ₂ {X Y : C} (w : X ⟶ Y) (hw : W w) : ιPaths W Y ⟶ ιPaths W X := (Paths.of _).map (Sum.inr ⟨w, hw⟩) diff --git a/Mathlib/CategoryTheory/PathCategory/Basic.lean b/Mathlib/CategoryTheory/PathCategory/Basic.lean index 7e012cc4e81fa5..ad3b72ce3b1c92 100644 --- a/Mathlib/CategoryTheory/PathCategory/Basic.lean +++ b/Mathlib/CategoryTheory/PathCategory/Basic.lean @@ -247,11 +247,9 @@ def pathComposition : Paths C ⥤ C where -- the `HomRel` for the kernel of any functor. -- Indeed, this should be part of an equivalence between congruence relations on a category `C` -- and full, essentially surjective functors out of `C`. -#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. -Assistance investigating this would be appreciated. -/ /-- The canonical relation on the path category of a category: two paths are related if they compose to the same morphism. -/ -@[simp, nolint simpNF] +@[simp] def pathsHomRel : HomRel (Paths C) := fun _ _ p q => (pathComposition C).map p = (pathComposition C).map q diff --git a/Mathlib/CategoryTheory/WithTerminal/Basic.lean b/Mathlib/CategoryTheory/WithTerminal/Basic.lean index dc00c176e29eb2..f53ba944c15c1d 100644 --- a/Mathlib/CategoryTheory/WithTerminal/Basic.lean +++ b/Mathlib/CategoryTheory/WithTerminal/Basic.lean @@ -83,10 +83,8 @@ def id : ∀ X : WithTerminal C, Hom X X | of _ => 𝟙 _ | star => PUnit.unit -#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. -Assistance investigating this would be appreciated. -/ /-- Composition of morphisms for `WithTerminal C`. -/ -@[simp, nolint simpNF] +@[simp] def comp : ∀ {X Y Z : WithTerminal C}, Hom X Y → Hom Y Z → Hom X Z | of _X, of _Y, of _Z => fun f g => f ≫ g | of _X, _, star => fun _f _g => PUnit.unit diff --git a/Mathlib/Data/Multiset/MapFold.lean b/Mathlib/Data/Multiset/MapFold.lean index 78ddf10a56632d..232137c36eb954 100644 --- a/Mathlib/Data/Multiset/MapFold.lean +++ b/Mathlib/Data/Multiset/MapFold.lean @@ -142,11 +142,7 @@ theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Mult refine ⟨a, mem_cons_self _ _, rfl, ?_⟩ rw [Multiset.erase_cons_head, h] --- The simpNF linter says that the LHS can be simplified via `Multiset.mem_map`. --- However this is a higher priority lemma. --- It seems the side condition `H` is not applied by `simpNF`. --- https://github.com/leanprover/std4/issues/207 -@[simp 1100, nolint simpNF] +@[simp 1100] theorem mem_map_of_injective {f : α → β} (H : Function.Injective f) {a : α} {s : Multiset α} : f a ∈ map f s ↔ a ∈ s := Quot.inductionOn s fun _l => List.mem_map_of_injective H diff --git a/Mathlib/Data/Option/Basic.lean b/Mathlib/Data/Option/Basic.lean index 79684a9bb2ad13..e66b8f9b8b3ef2 100644 --- a/Mathlib/Data/Option/Basic.lean +++ b/Mathlib/Data/Option/Basic.lean @@ -47,11 +47,7 @@ theorem coe_def : (fun a ↦ ↑a : α → Option α) = some := theorem mem_map {f : α → β} {y : β} {o : Option α} : y ∈ o.map f ↔ ∃ x ∈ o, f x = y := by simp --- The simpNF linter says that the LHS can be simplified via `Option.mem_def`. --- However this is a higher priority lemma. --- It seems the side condition `H` is not applied by `simpNF`. --- https://github.com/leanprover/std4/issues/207 -@[simp 1100, nolint simpNF] +@[simp 1100] theorem mem_map_of_injective {f : α → β} (H : Function.Injective f) {a : α} {o : Option α} : f a ∈ o.map f ↔ a ∈ o := by aesop diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean index 3a118004d1cb36..a1f6d27897f034 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean @@ -287,14 +287,14 @@ protected theorem finrank_bot : finrank F (⊥ : IntermediateField F E) = 1 := b @[simp] theorem rank_bot' : Module.rank (⊥ : IntermediateField F E) E = Module.rank F E := by rw [← rank_mul_rank F (⊥ : IntermediateField F E) E, IntermediateField.rank_bot, one_mul] -@[simp, nolint simpNF] -- `simpNF` hits a (deterministic) timeout at `typeclass` +@[simp] theorem finrank_bot' : finrank (⊥ : IntermediateField F E) E = finrank F E := congr(Cardinal.toNat $(rank_bot')) @[simp] protected theorem rank_top : Module.rank (⊤ : IntermediateField F E) E = 1 := Subalgebra.bot_eq_top_iff_rank_eq_one.mp <| top_le_iff.mp fun x _ ↦ ⟨⟨x, trivial⟩, rfl⟩ -@[simp, nolint simpNF] -- `simpNF` hits a (deterministic) timeout at `typeclass` +@[simp] protected theorem finrank_top : finrank (⊤ : IntermediateField F E) E = 1 := rank_eq_one_iff_finrank_eq_one.mp IntermediateField.rank_top diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean index 9d2e68a1004432..75e22d61ca3c93 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean @@ -346,13 +346,11 @@ theorem changeFormEquiv_symm : variable (Q) -#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here. -Assistance investigating this would be appreciated. -/ /-- The module isomorphism to the exterior algebra. Note that this holds more generally when `Q` is divisible by two, rather than only when `1` is divisible by two; but that would be more awkward to use. -/ -@[simp, nolint simpNF] +@[simp] def equivExterior [Invertible (2 : R)] : CliffordAlgebra Q ≃ₗ[R] ExteriorAlgebra R M := changeFormEquiv changeForm.associated_neg_proof diff --git a/Mathlib/ModelTheory/Order.lean b/Mathlib/ModelTheory/Order.lean index 0b85297e2ca919..fc01bc4c2f53c7 100644 --- a/Mathlib/ModelTheory/Order.lean +++ b/Mathlib/ModelTheory/Order.lean @@ -135,7 +135,7 @@ language. -/ @[simps] def orderLHom : Language.order →ᴸ L where onRelation | _, .le => leSymb -@[simp, nolint simpNF] +@[simp] theorem orderLHom_leSymb : (orderLHom L).onRelation leSymb = (leSymb : L.Relations 2) := rfl diff --git a/Mathlib/Order/Filter/Map.lean b/Mathlib/Order/Filter/Map.lean index 671beda2c6109e..bd63d6f641c8eb 100644 --- a/Mathlib/Order/Filter/Map.lean +++ b/Mathlib/Order/Filter/Map.lean @@ -60,11 +60,7 @@ theorem mem_map' : t ∈ map m f ↔ { x | m x ∈ t } ∈ f := theorem image_mem_map (hs : s ∈ f) : m '' s ∈ map m f := f.sets_of_superset hs <| subset_preimage_image m s --- The simpNF linter says that the LHS can be simplified via `Filter.mem_map`. --- However this is a higher priority lemma. --- It seems the side condition `hf` is not applied by `simpNF`. --- https://github.com/leanprover/std4/issues/207 -@[simp 1100, nolint simpNF] +@[simp 1100] theorem image_mem_map_iff (hf : Injective m) : m '' s ∈ map m f ↔ s ∈ f := ⟨fun h => by rwa [← preimage_image_eq s hf], image_mem_map⟩ diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index 1e3ede9f668cb7..8f0c380fec7e72 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -639,18 +639,14 @@ lemma ker_naive {σ : Type*} {I : Ideal (MvPolynomial σ R)} set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in --- FIXME: `simpNF` times out synthesizing --- `FaithfulSMul (Algebra.Generators.ofAlgHom f h).toExtension.Ring S`. -@[simp, nolint simpNF] +@[simp] lemma ker_ofAlgHom {I : Type*} (f : MvPolynomial I R →ₐ[R] S) (h : Function.Surjective ⇑f) : (ofAlgHom f h).ker = RingHom.ker f.toRingHom := by change RingHom.ker _ = _ congr exact MvPolynomial.ringHom_ext (by simp) (by simp [ofAlgHom]) --- FIXME: `simpNF` times out synthesizing --- `FaithfulSMul (P.ofAlgEquiv e).toExtension.Ring T`. -@[simp, nolint simpNF] +@[simp] lemma ker_ofAlgEquiv (P : Generators R S ι) {T : Type*} [CommRing T] [Algebra R T] (e : S ≃ₐ[R] T) : (P.ofAlgEquiv e).ker = P.ker := by rw [ker_eq_ker_aeval_val, ofAlgEquiv_val, Function.comp_def, ← AlgHom.coe_coe, diff --git a/Mathlib/Topology/MetricSpace/Snowflaking.lean b/Mathlib/Topology/MetricSpace/Snowflaking.lean index 11b2fb82b74c91..365ed2843654fb 100644 --- a/Mathlib/Topology/MetricSpace/Snowflaking.lean +++ b/Mathlib/Topology/MetricSpace/Snowflaking.lean @@ -84,7 +84,7 @@ theorem toSnowflaking.sizeOf_spec [SizeOf X] (x : X) : sizeOf (toSnowflaking x : Snowflaking X α hα₀ hα₁) = 1 + sizeOf x := rfl -attribute [nolint simpNF] mk.injEq mk.sizeOf_spec +attribute [nolint simpNF] mk.injEq /-- This definition makes `cases x` and `induction x` use `toSnowflaking` instead of `mk`. -/ @[elab_as_elim, cases_eliminator, induction_eliminator] From dcb1501721aa814cf2eae1e761398b076627b7b2 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Wed, 17 Jun 2026 14:21:01 +0000 Subject: [PATCH 0113/1300] chore: move `IsOpenQuotientMap.baireSpace` to `Baire.Lemmas` (#40713) This makes the import tree a bit cleaner, so that importing `OpenQuotient` is cheaper. --- Mathlib/Topology/Baire/Lemmas.lean | 12 +++++++++++- Mathlib/Topology/Homeomorph/Lemmas.lean | 1 + Mathlib/Topology/Maps/OpenQuotient.lean | 10 ---------- Mathlib/Topology/Order/IsLUB.lean | 1 + 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Mathlib/Topology/Baire/Lemmas.lean b/Mathlib/Topology/Baire/Lemmas.lean index 0f15e154154f65..7d9c592d303eeb 100644 --- a/Mathlib/Topology/Baire/Lemmas.lean +++ b/Mathlib/Topology/Baire/Lemmas.lean @@ -6,8 +6,9 @@ Authors: Sébastien Gouëzel module public import Mathlib.Data.Fintype.Powerset -public import Mathlib.Topology.GDelta.Basic public import Mathlib.Topology.Constructions +public import Mathlib.Topology.GDelta.Basic +public import Mathlib.Topology.Maps.OpenQuotient public import Mathlib.Tactic.CrossRefAttribute /-! @@ -111,6 +112,15 @@ theorem Topology.IsOpenEmbedding.baireSpace {Y : Type*} [TopologicalSpace Y] {p theorem IsOpen.baireSpace {s : Set X} (hO : IsOpen s) : BaireSpace s := hO.isOpenEmbedding_subtypeVal.baireSpace +/-- If `f` is an open quotient map and `X` is Baire, then `Y` is Baire. -/ +theorem IsOpenQuotientMap.baireSpace {Y : Type*} [TopologicalSpace Y] {f : X → Y} + (hf : IsOpenQuotientMap f) : BaireSpace Y := by + constructor + intro u hou hdu + have := dense_iInter_of_isOpen_nat (fun n => hf.continuous.isOpen_preimage (u n) (hou n)) + (fun n => (IsOpenQuotientMap.dense_preimage_iff hf).mpr (hdu n)) + simp_all [← preimage_iInter, IsOpenQuotientMap.dense_preimage_iff] + /-- Baire theorem: a countable intersection of dense open sets is dense. Formulated here with ⋂₀. -/ theorem dense_sInter_of_isOpen {S : Set (Set X)} (ho : ∀ s ∈ S, IsOpen s) (hS : S.Countable) (hd : ∀ s ∈ S, Dense s) : Dense (⋂₀ S) := by diff --git a/Mathlib/Topology/Homeomorph/Lemmas.lean b/Mathlib/Topology/Homeomorph/Lemmas.lean index 9fc328a54765e0..1dbcf2a6d5059b 100644 --- a/Mathlib/Topology/Homeomorph/Lemmas.lean +++ b/Mathlib/Topology/Homeomorph/Lemmas.lean @@ -9,6 +9,7 @@ public import Mathlib.Logic.Equiv.Fin.Basic public import Mathlib.Topology.Connected.LocallyConnected public import Mathlib.Topology.DenseEmbedding public import Mathlib.Topology.Connected.TotallyDisconnected +public import Mathlib.Topology.Baire.Lemmas /-! # Further properties of homeomorphisms diff --git a/Mathlib/Topology/Maps/OpenQuotient.lean b/Mathlib/Topology/Maps/OpenQuotient.lean index ccbd3c06193cac..be2ce3cb93e7f3 100644 --- a/Mathlib/Topology/Maps/OpenQuotient.lean +++ b/Mathlib/Topology/Maps/OpenQuotient.lean @@ -6,7 +6,6 @@ Authors: Yury Kudryashov module public import Mathlib.Topology.Maps.Basic -public import Mathlib.Topology.Baire.Lemmas /-! # Open quotient maps @@ -65,15 +64,6 @@ theorem dense_preimage_iff (h : IsOpenQuotientMap f) {s : Set Y} : Dense (f ⁻ ⟨fun hs ↦ h.surjective.denseRange.dense_of_mapsTo h.continuous hs (mapsTo_preimage _ _), fun hs ↦ hs.preimage h.isOpenMap⟩ -/-- If `f` is an open quotient map and `X` is Baire, then `Y` is Baire. -/ -theorem baireSpace {f : X → Y} [BaireSpace X] (hf : IsOpenQuotientMap f) : - BaireSpace Y := by - constructor - intro u hou hdu - have := dense_iInter_of_isOpen_nat (fun n => hf.continuous.isOpen_preimage (u n) (hou n)) - (fun n => (IsOpenQuotientMap.dense_preimage_iff hf).mpr (hdu n)) - simp_all [← preimage_iInter, IsOpenQuotientMap.dense_preimage_iff] - end IsOpenQuotientMap theorem Topology.IsInducing.isOpenQuotientMap_of_surjective (ind : IsInducing f) diff --git a/Mathlib/Topology/Order/IsLUB.lean b/Mathlib/Topology/Order/IsLUB.lean index 3780b512cae029..f36797e4ef2d73 100644 --- a/Mathlib/Topology/Order/IsLUB.lean +++ b/Mathlib/Topology/Order/IsLUB.lean @@ -5,6 +5,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Yury Kudryashov -/ module +public import Mathlib.Order.Filter.CountableInter public import Mathlib.Topology.Order.LeftRightNhds /-! From 51dc5fe5cec5c2ef41c1abbf9ca3735314598d4c Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:21:04 +0000 Subject: [PATCH 0114/1300] feat: isEmbedding_subtypeL (#40716) This PR was automatically created from PR #39100 by @ADedecker via a [review comment](https://github.com/leanprover-community/mathlib4/pull/39100#discussion_r3428436762) by @ADedecker. Co-authored-by: ADedecker <48656793+ADedecker@users.noreply.github.com> --- .../Algebra/Module/ContinuousLinearMap/Restrict.lean | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean index d441ec3c01472a..b143c030d2091a 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean @@ -58,6 +58,14 @@ alias coe_subtypeL' := coe_subtypeL theorem subtypeL_apply (p : Submodule R M) (x : p) : p.subtypeL x = x := by simp +theorem isEmbedding_subtype (p : Submodule R M) : Topology.IsEmbedding p.subtype := .subtypeVal +theorem isEmbedding_subtypeL (p : Submodule R M) : Topology.IsEmbedding p.subtypeL := .subtypeVal + +theorem isClosedEmbedding_subtype (p : Submodule R M) (hp : IsClosed (p : Set M)) : + Topology.IsClosedEmbedding p.subtype := .subtypeVal hp +theorem isClosedEmbedding_subtypeL (p : Submodule R M) (hp : IsClosed (p : Set M)) : + Topology.IsClosedEmbedding p.subtypeL := .subtypeVal hp + @[deprecated range_subtype (since := "2026-05-06")] theorem range_subtypeL (p : Submodule R M) : (p.subtypeL : p →ₗ[R] M).range = p := Submodule.range_subtype _ From 7d46b4c5ac5094a978500cec6f1de5a7550ba64e Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:21:12 +0000 Subject: [PATCH 0115/1300] chore: rename `{OpenPartialHomeomorph,PartialEquiv}.map_source''` (#40717) The new name avoids a double prime and also matches the naming convention. As suggested [here](https://github.com/leanprover-community/mathlib4/pull/39084#discussion_r3423172247). --- Mathlib/Geometry/Manifold/ChartedSpace.lean | 2 +- Mathlib/Logic/Equiv/PartialEquiv.lean | 4 +++- Mathlib/Topology/OpenPartialHomeomorph/Defs.lean | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index da6ab6a1bf0368..c5f1f48b6ac267 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -275,7 +275,7 @@ theorem ChartedSpace.locPathConnectedSpace [LocPathConnectedSpace H] : LocPathCo apply e.symm.image_mem_nhds (by simp [e]) exact pathComponentIn_mem_nhds <| e.image_mem_nhds (mem_chart_source _ _) ht · refine (isPathConnected_pathComponentIn <| mem_image_of_mem e (mem_of_mem_nhds ht)).image' ?_ - refine e.continuousOn_symm.mono <| subset_trans ?_ e.map_source'' + refine e.continuousOn_symm.mono <| subset_trans ?_ e.image_source_subset exact (pathComponentIn_mono <| image_mono inter_subset_right).trans pathComponentIn_subset · exact (image_mono pathComponentIn_subset).trans (PartialEquiv.symm_image_image_of_subset_source _ inter_subset_right).subset diff --git a/Mathlib/Logic/Equiv/PartialEquiv.lean b/Mathlib/Logic/Equiv/PartialEquiv.lean index 022bfe7a6c1a28..14605e6ca9458c 100644 --- a/Mathlib/Logic/Equiv/PartialEquiv.lean +++ b/Mathlib/Logic/Equiv/PartialEquiv.lean @@ -180,9 +180,11 @@ theorem map_source {x : α} (h : x ∈ e.source) : e x ∈ e.target := e.map_source' h /-- Variant of `e.map_source` and `map_source'`, stated for images of subsets of `source`. -/ -lemma map_source'' : e '' e.source ⊆ e.target := +lemma image_source_subset : e '' e.source ⊆ e.target := fun _ ⟨_, hx, hex⟩ ↦ mem_of_eq_of_mem (id hex.symm) (e.map_source' hx) +@[deprecated (since := "2026-06-17")] alias map_source'' := image_source_subset + @[simp, mfld_simps] theorem map_target {x : β} (h : x ∈ e.target) : e.symm x ∈ e.source := e.map_target' h diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean index 8b78eaffe96302..362cbe712da3c6 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean @@ -144,9 +144,11 @@ theorem map_source {x : X} (h : x ∈ e.source) : e x ∈ e.target := e.map_source' h /-- Variant of `map_source`, stated for images of subsets of `source`. -/ -lemma map_source'' : e '' e.source ⊆ e.target := +lemma image_source_subset : e '' e.source ⊆ e.target := fun _ ⟨_, hx, hex⟩ ↦ mem_of_eq_of_mem (id hex.symm) (e.map_source' hx) +@[deprecated (since := "2026-06-17")] alias map_source'' := image_source_subset + @[simp, mfld_simps] theorem map_target {x : Y} (h : x ∈ e.target) : e.symm x ∈ e.source := e.map_target' h From 64f7dc5fc88fdadd768edca49f0a0e2953496ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 17 Jun 2026 15:15:28 +0000 Subject: [PATCH 0116/1300] doc(Algebra/Order): update mentions of `OrderedSemiring` and friends (#37835) As of #20676, it was replaced by `IsOrderedRing`. Also deprecate `Rat.coe_int_inj` in favor of `Rat.intCast_inj` and action a TODO in `norm_num`'s code. Not all docs were straightforward to update. --- Counterexamples/HomogeneousPrimeNotPrime.lean | 2 +- .../OrderedCancelAddCommMonoidWithBounds.lean | 6 +- Mathlib/Algebra/Group/Subgroup/Order.lean | 3 +- Mathlib/Algebra/Group/ULift.lean | 2 +- Mathlib/Algebra/Order/AddTorsor.lean | 20 ++--- Mathlib/Algebra/Order/CompleteField.lean | 2 +- Mathlib/Algebra/Order/Floor/Defs.lean | 3 +- Mathlib/Algebra/Order/Floor/Ring.lean | 2 +- Mathlib/Algebra/Order/Floor/Semiring.lean | 2 +- Mathlib/Algebra/Order/Group/Cone.lean | 5 +- Mathlib/Algebra/Order/Group/Cyclic.lean | 2 +- Mathlib/Algebra/Order/GroupWithZero/Defs.lean | 26 +++--- Mathlib/Algebra/Order/Hom/Monoid.lean | 8 +- .../Algebra/Order/Interval/Set/Monoid.lean | 4 +- .../Algebra/Order/Monoid/Canonical/Defs.lean | 16 ++-- .../Algebra/Order/Monoid/Unbundled/Defs.lean | 41 +++++---- .../Order/Monoid/Unbundled/ExistsOfLE.lean | 8 +- Mathlib/Algebra/Order/Nonneg/Field.lean | 4 - Mathlib/Algebra/Order/Nonneg/Ring.lean | 4 - Mathlib/Algebra/Order/Positive/Ring.lean | 2 +- Mathlib/Algebra/Order/Ring/Basic.lean | 7 +- Mathlib/Algebra/Order/Ring/Cone.lean | 3 +- Mathlib/Algebra/Order/Ring/Defs.lean | 72 +++------------ .../Algebra/Order/Ring/Unbundled/Basic.lean | 89 +------------------ Mathlib/Algebra/Order/Star/Basic.lean | 4 +- Mathlib/Algebra/Order/Sub/Basic.lean | 2 +- Mathlib/Algebra/Order/Sub/WithTop.lean | 4 +- Mathlib/Algebra/Order/ToIntervalMod.lean | 5 +- Mathlib/Algebra/Order/WithTop/Untop0.lean | 12 --- Mathlib/Analysis/Complex/Order.lean | 4 +- Mathlib/Combinatorics/Pigeonhole.lean | 2 +- Mathlib/Data/Finsupp/Weight.lean | 4 +- Mathlib/Data/NNReal/Defs.lean | 2 +- Mathlib/Data/Nat/Cast/Order/Basic.lean | 14 +-- Mathlib/Data/Nat/Cast/Order/Ring.lean | 10 +-- .../Matrix/Irreducible/Defs.lean | 2 +- Mathlib/MeasureTheory/Function/LpOrder.lean | 2 +- .../Measure/Typeclasses/Finite.lean | 2 +- .../Order/Filter/AtTopBot/Archimedean.lean | 6 +- Mathlib/Order/Filter/Germ/OrderedMonoid.lean | 2 +- Mathlib/Order/Interval/Finset/Nat.lean | 2 +- Mathlib/Order/Interval/Set/Defs.lean | 2 +- Mathlib/Order/Interval/Set/OrdConnected.lean | 2 +- Mathlib/RingTheory/GradedAlgebra/Radical.lean | 2 +- .../RingTheory/HahnSeries/PowerSeries.lean | 5 +- Mathlib/RingTheory/HahnSeries/Valuation.lean | 3 +- .../MvPolynomial/WeightedHomogeneous.lean | 4 +- Mathlib/Tactic/NormNum/Ineq.lean | 18 +--- MathlibTest/positivity.lean | 3 +- docs/overview.yaml | 2 +- 50 files changed, 139 insertions(+), 314 deletions(-) diff --git a/Counterexamples/HomogeneousPrimeNotPrime.lean b/Counterexamples/HomogeneousPrimeNotPrime.lean index a52f267bd992ce..f6ad1b8b76c8ed 100644 --- a/Counterexamples/HomogeneousPrimeNotPrime.lean +++ b/Counterexamples/HomogeneousPrimeNotPrime.lean @@ -12,7 +12,7 @@ import Mathlib.RingTheory.GradedAlgebra.Homogeneous.Ideal # A homogeneous ideal that is homogeneously prime but not prime In `Ideal.IsHomogeneous.isPrime_of_homogeneous_mem_or_mem`, we assumed that the underlying grading -is indexed by a `LinearOrderedCancelAddCommMonoid` to prove that a homogeneous ideal is prime +is indexed by a linearly ordered cancellative monoid to prove that a homogeneous ideal is prime if and only if it is homogeneously prime. This file shows that even if this assumption isn't strictly necessary, the assumption of "being cancellative" is. We construct a counterexample where the underlying indexing set is a `LinearOrderedAddCommMonoid` but is not cancellative and the diff --git a/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean b/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean index 1eb0e49b8aa8ef..b5346725242b49 100644 --- a/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean +++ b/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean @@ -7,11 +7,11 @@ import Mathlib.Algebra.Order.Monoid.Defs import Mathlib.Order.BoundedOrder.Lattice /-! -# Do not combine OrderedCancelAddCommMonoid with BoundedOrder +# Do not combine `IsOrderedCancelAddMonoid` with `BoundedOrder` -This file shows that combining `OrderedCancelAddCommMonoid` with `BoundedOrder` is not a good idea, +This file shows that combining `IsOrderedCancelAddMonoid` with `BoundedOrder` is not a good idea, as such a structure must be trivial (`⊥ = x = ⊤` for all `x`). -The same applies to any superclasses, e.g. combining `StrictOrderedSemiring` with `CompleteLattice`. +The same applies to any superclasses, e.g. combining `IsStrictOrderedRing` with `CompleteLattice`. -/ example {α : Type*} [AddCommMonoid α] [PartialOrder α] [IsOrderedCancelAddMonoid α] diff --git a/Mathlib/Algebra/Group/Subgroup/Order.lean b/Mathlib/Algebra/Group/Subgroup/Order.lean index 0db35f85ce7d68..9b821ebe9b7d7a 100644 --- a/Mathlib/Algebra/Group/Subgroup/Order.lean +++ b/Mathlib/Algebra/Group/Subgroup/Order.lean @@ -77,7 +77,8 @@ namespace Subgroup variable {G : Type*} /-- A subgroup of an ordered group is an ordered group. -/ -@[to_additive /-- An `AddSubgroup` of an `AddOrderedCommGroup` is an `AddOrderedCommGroup`. -/] +@[to_additive +/-- An additive subgroup of an additive ordered group is an additive ordered group. -/] instance toIsOrderedMonoid [CommGroup G] [Preorder G] [IsOrderedMonoid G] (H : Subgroup G) : IsOrderedMonoid H := Function.Injective.isOrderedMonoid Subtype.val (fun _ _ => rfl) .rfl diff --git a/Mathlib/Algebra/Group/ULift.lean b/Mathlib/Algebra/Group/ULift.lean index ba97d0e915c396..375f8ee797273c 100644 --- a/Mathlib/Algebra/Group/ULift.lean +++ b/Mathlib/Algebra/Group/ULift.lean @@ -136,6 +136,6 @@ instance cancelCommMonoid [CancelCommMonoid α] : CancelCommMonoid (ULift α) := instance nontrivial [Nontrivial α] : Nontrivial (ULift α) := Equiv.ulift.symm.injective.nontrivial --- TODO we don't do `OrderedCancelCommMonoid` or `OrderedCommGroup` +-- TODO: We don't do `IsOrderedCancelMonoid`. -- We'd need to add instances for `ULift` in `Order.Basic`. end ULift diff --git a/Mathlib/Algebra/Order/AddTorsor.lean b/Mathlib/Algebra/Order/AddTorsor.lean index b52354f9409fbb..edd40c9ab230b6 100644 --- a/Mathlib/Algebra/Order/AddTorsor.lean +++ b/Mathlib/Algebra/Order/AddTorsor.lean @@ -32,16 +32,16 @@ an ordered field. * IsOrderedCancelVAdd : inequalities are preserved and reflected by translation. ## Instances -* OrderedCommMonoid.toIsOrderedSMul -* OrderedAddCommMonoid.toIsOrderedVAdd -* IsOrderedSMul.toCovariantClassLeft -* IsOrderedVAdd.toCovariantClassLeft -* IsOrderedCancelSMul.toCancelSMul -* IsOrderedCancelVAdd.toCancelVAdd -* OrderedCancelCommMonoid.toIsOrderedCancelSMul -* OrderedCancelAddCommMonoid.toIsOrderedCancelVAdd -* IsOrderedCancelSMul.toContravariantClassLeft -* IsOrderedCancelVAdd.toContravariantClassLeft +* `IsOrderedMonoid.toIsOrderedSMul` +* `IsOrderedAddMonoid.toIsOrderedVAdd` +* `IsOrderedSMul.toCovariantClassLeft` +* `IsOrderedVAdd.toCovariantClassLeft` +* `IsOrderedCancelSMul.toCancelSMul` +* `IsOrderedCancelVAdd.toCancelVAdd` +* `IsOrderedCancelMonoid.toIsOrderedCancelSMul` +* `IsOrderedCancelAddMonoid.toIsOrderedCancelVAdd` +* `IsOrderedCancelSMul.toContravariantClassLeft` +* `IsOrderedCancelVAdd.toContravariantClassLeft` ## TODO * (lex) prod instances diff --git a/Mathlib/Algebra/Order/CompleteField.lean b/Mathlib/Algebra/Order/CompleteField.lean index 368aabd6624c2a..e0515d95472fab 100644 --- a/Mathlib/Algebra/Order/CompleteField.lean +++ b/Mathlib/Algebra/Order/CompleteField.lean @@ -18,7 +18,7 @@ This is `ConditionallyCompleteLinearOrderedField.inducedOrderRingIso`. Moreover this isomorphism is unique. We show all conditionally complete linear ordered fields are -archimedean. We also construct the natural map from a `LinearOrderedField` to such a field. +archimedean. We also construct the natural map from a linearly ordered field to such a field. ## Main definitions diff --git a/Mathlib/Algebra/Order/Floor/Defs.lean b/Mathlib/Algebra/Order/Floor/Defs.lean index ea027109b35e54..64f301a1f3b181 100644 --- a/Mathlib/Algebra/Order/Floor/Defs.lean +++ b/Mathlib/Algebra/Order/Floor/Defs.lean @@ -39,8 +39,7 @@ for `nnnorm`. ## TODO -`LinearOrderedRing`/`LinearOrderedSemiring` can be relaxed to `OrderedRing`/`OrderedSemiring` in -many lemmas. +`LinearOrder` can be relaxed to `PartialOrder` in many lemmas. ## Tags diff --git a/Mathlib/Algebra/Order/Floor/Ring.lean b/Mathlib/Algebra/Order/Floor/Ring.lean index 43b7f578f2e0d8..79a3481beeae1e 100644 --- a/Mathlib/Algebra/Order/Floor/Ring.lean +++ b/Mathlib/Algebra/Order/Floor/Ring.lean @@ -20,7 +20,7 @@ fractional part operator. ## TODO -`LinearOrderedRing` can be relaxed to `OrderedRing` in many lemmas. +`LinearOrder` can be relaxed to `PartialOrder` in many lemmas. ## Tags diff --git a/Mathlib/Algebra/Order/Floor/Semiring.lean b/Mathlib/Algebra/Order/Floor/Semiring.lean index d024388b60f93d..8af0bf21b086d4 100644 --- a/Mathlib/Algebra/Order/Floor/Semiring.lean +++ b/Mathlib/Algebra/Order/Floor/Semiring.lean @@ -15,7 +15,7 @@ This file contains basic results on the natural-valued floor and ceiling functio ## TODO -`LinearOrderedSemiring` can be relaxed to `OrderedSemiring` in many lemmas. +`LinearOrder` can be relaxed to `PartialOrder` in many lemmas. ## Tags diff --git a/Mathlib/Algebra/Order/Group/Cone.lean b/Mathlib/Algebra/Order/Group/Cone.lean index 851666410a32bc..1156753e2f7abd 100644 --- a/Mathlib/Algebra/Order/Group/Cone.lean +++ b/Mathlib/Algebra/Order/Group/Cone.lean @@ -12,9 +12,8 @@ public import Mathlib.Algebra.Order.Monoid.Submonoid /-! # Construct ordered groups from groups with a specified positive cone. -In this file we provide the structure `GroupCone` and the predicate `IsMaxCone` -that encode axioms of `OrderedCommGroup` and `LinearOrderedCommGroup` -in terms of the subset of non-negative elements. +In this file we provide the structure `GroupCone` and the predicate `IsMaxCone` that encode +the axioms of ordered groups in terms of the subset of non-negative elements. We also provide constructors that convert between cones in groups and the corresponding ordered groups. diff --git a/Mathlib/Algebra/Order/Group/Cyclic.lean b/Mathlib/Algebra/Order/Group/Cyclic.lean index 5741ab7e3a05ab..e8141a76b1bc79 100644 --- a/Mathlib/Algebra/Order/Group/Cyclic.lean +++ b/Mathlib/Algebra/Order/Group/Cyclic.lean @@ -15,7 +15,7 @@ This file contains basic results about cyclic linearly ordered groups and cyclic linearly ordered groups. The definitions `LinearOrderedCommGroup.Subgroup.genLTOne` (*resp.* -`LinearOrderedCommGroup.genLTOone`) yields a generator of a non-trivial subgroup of a linearly +`LinearOrderedCommGroup.genLTOne`) yields a generator of a non-trivial subgroup of a linearly ordered commutative group with (*resp.* of a non-trivial linearly ordered commutative group) that is strictly less than `1`. The corresponding additive definitions are also provided. -/ diff --git a/Mathlib/Algebra/Order/GroupWithZero/Defs.lean b/Mathlib/Algebra/Order/GroupWithZero/Defs.lean index 0c6e6304051e23..40e8ee9d4c90cd 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Defs.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Defs.lean @@ -31,7 +31,7 @@ We then provide statements and instances about these typeclasses not requiring ` or higher on the underlying type – those that do can be found in `Mathlib/Algebra/Order/GroupWithZero/Unbundled/Basic.lean`. -Less granular typeclasses like `OrderedAddCommMonoid` and `LinearOrderedField` should be enough for +Less granular typeclasses like `IsOrderedAddMonoid` and `IsOrderedRing` should be enough for most purposes, and the system is set up so that they imply the correct granular typeclasses here. ## Implications @@ -53,10 +53,10 @@ The commonly used implications are: * `posMulReflectLT_iff_mulPosReflectLT` Furthermore, the bundled non-granular typeclasses imply the granular ones like so: -* `OrderedSemiring → PosMulMono` -* `OrderedSemiring → MulPosMono` -* `StrictOrderedSemiring → PosMulStrictMono` -* `StrictOrderedSemiring → MulPosStrictMono` +* `IsOrderedRing → PosMulMono` +* `IsOrderedRing → MulPosMono` +* `IsStrictOrderedRing → PosMulStrictMono` +* `IsStrictOrderedRing → MulPosStrictMono` All these are registered as instances, which means that in practice you should not worry about these implications. However, if you encounter a case where you think a statement is true but not covered @@ -95,7 +95,7 @@ variable [Mul α] [Zero α] [Preorder α] namely `a₁ ≤ a₂ → b * a₁ ≤ b * a₂` if `0 ≤ b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedSemiring`. -/ +`IsOrderedRing`. -/ @[mk_iff] class PosMulMono : Prop where /-- Do not use this. Use `_root_.mul_le_mul_of_nonneg_left` instead. -/ protected mul_le_mul_of_nonneg_left ⦃a : α⦄ (ha : 0 ≤ a) ⦃b c : α⦄ (hbc : b ≤ c) : a * b ≤ a * c @@ -104,7 +104,7 @@ You should usually not use this very granular typeclass directly, but rather a t namely `a₁ < a₂ → b * a₁ < b * a₂` if `0 < b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`StrictOrderedSemiring`. -/ +`IsStrictOrderedRing`. -/ @[mk_iff] class PosMulStrictMono : Prop where /-- Do not use this. Use `_root_.mul_lt_mul_of_pos_left` instead. -/ protected mul_lt_mul_of_pos_left ⦃a : α⦄ (ha : 0 < a) ⦃b c : α⦄ (hbc : b < c) : a * b < a * c @@ -113,21 +113,21 @@ You should usually not use this very granular typeclass directly, but rather a t the left, namely `b * a₁ < b * a₂ → a₁ < a₂` if `0 ≤ b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`LinearOrderedSemiring`. -/ +`IsStrictOrderedRing`. -/ @[mk_iff] class PosMulReflectLT : Prop extends ContravariantClass α≥0 α (fun x y => x * y) (· < ·) /-- Typeclass for reverse monotonicity of multiplication by positive elements on the left, namely `b * a₁ ≤ b * a₂ → a₁ ≤ a₂` if `0 < b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`LinearOrderedSemiring`. -/ +`IsStrictOrderedRing`. -/ @[mk_iff] class PosMulReflectLE : Prop extends ContravariantClass α>0 α (fun x y => x * y) (· ≤ ·) /-- Typeclass for monotonicity of multiplication by nonnegative elements on the right, namely `a₁ ≤ a₂ → a₁ * b ≤ a₂ * b` if `0 ≤ b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedSemiring`. -/ +`IsOrderedRing`. -/ @[mk_iff] class MulPosMono : Prop where /-- Do not use this. Use `_root_.mul_le_mul_of_nonneg_right` instead. -/ protected mul_le_mul_of_nonneg_right ⦃c : α⦄ (hc : 0 ≤ c) ⦃a b : α⦄ (hab : a ≤ b) : a * c ≤ b * c @@ -136,7 +136,7 @@ You should usually not use this very granular typeclass directly, but rather a t namely `a₁ < a₂ → a₁ * b < a₂ * b` if `0 < b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`StrictOrderedSemiring`. -/ +`IsStrictOrderedRing`. -/ @[mk_iff] class MulPosStrictMono : Prop where /-- Do not use this. Use `_root_.mul_lt_mul_of_pos_right` instead. -/ protected mul_lt_mul_of_pos_right ⦃c : α⦄ (hc : 0 < c) ⦃a b : α⦄ (hab : a < b) : a * c < b * c @@ -145,14 +145,14 @@ You should usually not use this very granular typeclass directly, but rather a t the right, namely `a₁ * b < a₂ * b → a₁ < a₂` if `0 ≤ b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`LinearOrderedSemiring`. -/ +`IsStrictOrderedRing`. -/ @[mk_iff] class MulPosReflectLT : Prop extends ContravariantClass α≥0 α (fun x y => y * x) (· < ·) /-- Typeclass for reverse monotonicity of multiplication by positive elements on the right, namely `a₁ * b ≤ a₂ * b → a₁ ≤ a₂` if `0 < b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`LinearOrderedSemiring`. -/ +`IsStrictOrderedRing`. -/ @[mk_iff] class MulPosReflectLE : Prop extends ContravariantClass α>0 α (fun x y => y * x) (· ≤ ·) end Abbreviations diff --git a/Mathlib/Algebra/Order/Hom/Monoid.lean b/Mathlib/Algebra/Order/Hom/Monoid.lean index 16e48a14aaba0f..e9156ad8f34a22 100644 --- a/Mathlib/Algebra/Order/Hom/Monoid.lean +++ b/Mathlib/Algebra/Order/Hom/Monoid.lean @@ -67,7 +67,7 @@ variable {F α β γ δ : Type*} section AddMonoid -/-- `α →+o β` is the type of monotone functions `α → β` that preserve the `OrderedAddCommMonoid` +/-- `α →+o β` is the type of monotone functions `α → β` that preserve the ordered additive monoid structure. `OrderAddMonoidHom` is also used for ordered group homomorphisms. @@ -83,7 +83,7 @@ structure OrderAddMonoidHom (α β : Type*) [Preorder α] [Preorder β] [AddZero /-- Infix notation for `OrderAddMonoidHom`. -/ infixr:25 " →+o " => OrderAddMonoidHom -/-- `α ≃+o β` is the type of monotone isomorphisms `α ≃ β` that preserve the `OrderedAddCommMonoid` +/-- `α ≃+o β` is the type of isomorphisms `α ≃ β` that preserve the ordered additive monoid structure. `OrderAddMonoidIso` is also used for ordered group isomorphisms. @@ -104,7 +104,7 @@ end AddMonoid section Monoid -/-- `α →*o β` is the type of functions `α → β` that preserve the `OrderedCommMonoid` structure. +/-- `α →*o β` is the type of functions `α → β` that preserve the ordered monoid structure. `OrderMonoidHom` is also used for ordered group homomorphisms. @@ -139,7 +139,7 @@ def OrderMonoidHomClass.toOrderMonoidHom [OrderHomClass F α β] [MonoidHomClass instance [OrderHomClass F α β] [MonoidHomClass F α β] : CoeTC F (α →*o β) := ⟨OrderMonoidHomClass.toOrderMonoidHom⟩ -/-- `α ≃*o β` is the type of isomorphisms `α ≃ β` that preserve the `OrderedCommMonoid` structure. +/-- `α ≃*o β` is the type of isomorphisms `α ≃ β` that preserve the ordered monoid structure. `OrderMonoidIso` is also used for ordered group isomorphisms. diff --git a/Mathlib/Algebra/Order/Interval/Set/Monoid.lean b/Mathlib/Algebra/Order/Interval/Set/Monoid.lean index 3e3f8e1a066673..d272521e25c660 100644 --- a/Mathlib/Algebra/Order/Interval/Set/Monoid.lean +++ b/Mathlib/Algebra/Order/Interval/Set/Monoid.lean @@ -16,8 +16,8 @@ public import Mathlib.Algebra.Order.Monoid.Unbundled.ExistsOfLE The lemmas in this file state that addition maps intervals bijectively. The typeclass `ExistsAddOfLE` is defined specifically to make them work when combined with -`OrderedCancelAddCommMonoid`; the lemmas below therefore apply to all -`OrderedAddCommGroup`, but also to `ℕ` and `ℝ≥0`, which are not groups. +`IsOrderedCancelAddMonoid`; the lemmas below therefore apply to all ordered groups, +but also to `ℕ` and `ℝ≥0`, which are not groups. -/ public section diff --git a/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean b/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean index cdc0baaf93f60f..c94ab7346b57cf 100644 --- a/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean +++ b/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean @@ -23,14 +23,14 @@ universe u variable {α : Type u} /-- An ordered additive monoid is `CanonicallyOrderedAdd` - if the ordering coincides with the subtractibility relation, - which is to say, `a ≤ b` iff there exists `c` with `b = a + c`. - This is satisfied by the natural numbers, for example, but not - the integers or other nontrivial `OrderedAddCommGroup`s. - - We have `a ≤ b + a` and `a ≤ a + b` as separate fields. In the commutative case the second field - is redundant, but in the noncommutative case (satisfied most relevantly by the ordinals), this - extra field allows us to prove more things without the extra commutativity assumption. -/ +if the ordering coincides with the subtractibility relation, +which is to say, `a ≤ b` iff there exists `c` with `b = a + c`. +This is satisfied by the natural numbers, for example, but not +the integers or other nontrivial ordered groups. + +We have `a ≤ b + a` and `a ≤ a + b` as separate fields. In the commutative case the second field +is redundant, but in the noncommutative case (satisfied most relevantly by the ordinals), this +extra field allows us to prove more things without the extra commutativity assumption. -/ class CanonicallyOrderedAdd (α : Type*) [Add α] [LE α] : Prop extends ExistsAddOfLE α where /-- For any `a` and `b`, `a ≤ a + b` -/ diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Defs.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Defs.lean index f20efe7851731b..0e4a1637743fee 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Defs.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Defs.lean @@ -29,9 +29,9 @@ Since `Co(ntra)variantClass` takes as input the operation (typically `(+)` or `( relation (typically `(≤)` or `(<)`), these are the only two typeclasses that I have used. The general approach is to formulate the lemma that you are interested in and prove it, with the -`Ordered[...]` typeclass of your liking. After that, you convert the single typeclass, -say `[OrderedCancelMonoid M]`, into three typeclasses, e.g. -`[CancelMonoid M] [PartialOrder M] [CovariantClass M M (Function.swap (*)) (≤)]` +`IsOrdered[...]` typeclass of your liking. After that, you convert the typeclass, +say `[IsOrderedCancelMonoid M]`, into whichever typeclasses, e.g. +`[CovariantClass M M (Function.swap (*)) (≤)]` and have a go at seeing if the proof still works! Note that it is possible to combine several `Co(ntra)variantClass` assumptions together. @@ -54,6 +54,9 @@ typeclass assumptions, since `Function.swap` is slightly better behaved than `fl However, sometimes as a **non-typeclass** assumption, we prefer `flip (*)` (or `flip (+)`), as it is easier to use. +## TODO + +This is unergonomic. Inline in `MulLeftMono` and friends. -/ @[expose] public section @@ -125,7 +128,7 @@ class ContravariantClass : Prop where namely `b₁ ≤ b₂ → a * b₁ ≤ a * b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCommMonoid`. -/ +`IsOrderedMonoid`. -/ abbrev MulLeftMono [Mul M] [LE M] : Prop := CovariantClass M M (· * ·) (· ≤ ·) @@ -133,7 +136,7 @@ abbrev MulLeftMono [Mul M] [LE M] : Prop := namely `a₁ ≤ a₂ → a₁ * b ≤ a₂ * b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCommMonoid`. -/ +`IsOrderedMonoid`. -/ abbrev MulRightMono [Mul M] [LE M] : Prop := CovariantClass M M (swap (· * ·)) (· ≤ ·) @@ -141,7 +144,7 @@ abbrev MulRightMono [Mul M] [LE M] : Prop := namely `b₁ ≤ b₂ → a + b₁ ≤ a + b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedAddCommMonoid`. -/ +`IsOrderedAddMonoid`. -/ abbrev AddLeftMono [Add M] [LE M] : Prop := CovariantClass M M (· + ·) (· ≤ ·) @@ -149,7 +152,7 @@ abbrev AddLeftMono [Add M] [LE M] : Prop := namely `a₁ ≤ a₂ → a₁ + b ≤ a₂ + b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedAddCommMonoid`. -/ +`IsOrderedAddMonoid`. -/ abbrev AddRightMono [Add M] [LE M] : Prop := CovariantClass M M (swap (· + ·)) (· ≤ ·) @@ -159,7 +162,7 @@ attribute [to_additive existing] MulLeftMono MulRightMono namely `b₁ < b₂ → a * b₁ < a * b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCommGroup`. -/ +`IsOrderedMonoid`. -/ abbrev MulLeftStrictMono [Mul M] [LT M] : Prop := CovariantClass M M (· * ·) (· < ·) @@ -167,7 +170,7 @@ abbrev MulLeftStrictMono [Mul M] [LT M] : Prop := namely `a₁ < a₂ → a₁ * b < a₂ * b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCommGroup`. -/ +`IsOrderedMonoid`. -/ abbrev MulRightStrictMono [Mul M] [LT M] : Prop := CovariantClass M M (swap (· * ·)) (· < ·) @@ -175,7 +178,7 @@ abbrev MulRightStrictMono [Mul M] [LT M] : Prop := namely `b₁ < b₂ → a + b₁ < a + b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedAddCommGroup`. -/ +`IsOrderedAddMonoid`. -/ abbrev AddLeftStrictMono [Add M] [LT M] : Prop := CovariantClass M M (· + ·) (· < ·) @@ -183,7 +186,7 @@ abbrev AddLeftStrictMono [Add M] [LT M] : Prop := namely `a₁ < a₂ → a₁ + b < a₂ + b`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedAddCommGroup`. -/ +`IsOrderedAddMonoid`. -/ abbrev AddRightStrictMono [Add M] [LT M] : Prop := CovariantClass M M (swap (· + ·)) (· < ·) @@ -193,7 +196,7 @@ attribute [to_additive existing] MulLeftStrictMono MulRightStrictMono namely `a * b₁ < a * b₂ → b₁ < b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCommGroup`. -/ +`IsOrderedMonoid`. -/ abbrev MulLeftReflectLT [Mul M] [LT M] : Prop := ContravariantClass M M (· * ·) (· < ·) @@ -201,7 +204,7 @@ abbrev MulLeftReflectLT [Mul M] [LT M] : Prop := namely `a₁ * b < a₂ * b → a₁ < a₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCommGroup`. -/ +`IsOrderedMonoid`. -/ abbrev MulRightReflectLT [Mul M] [LT M] : Prop := ContravariantClass M M (swap (· * ·)) (· < ·) @@ -209,7 +212,7 @@ abbrev MulRightReflectLT [Mul M] [LT M] : Prop := namely `a + b₁ < a + b₂ → b₁ < b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedAddCommGroup`. -/ +`IsOrderedAddMonoid`. -/ abbrev AddLeftReflectLT [Add M] [LT M] : Prop := ContravariantClass M M (· + ·) (· < ·) @@ -217,7 +220,7 @@ abbrev AddLeftReflectLT [Add M] [LT M] : Prop := namely `a₁ * b < a₂ * b → a₁ < a₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedAddCommGroup`. -/ +`IsOrderedAddMonoid`. -/ abbrev AddRightReflectLT [Add M] [LT M] : Prop := ContravariantClass M M (swap (· + ·)) (· < ·) @@ -227,7 +230,7 @@ attribute [to_additive existing] MulLeftReflectLT MulRightReflectLT namely `a * b₁ ≤ a * b₂ → b₁ ≤ b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCancelCommMonoid`. -/ +`IsOrderedCancelMonoid`. -/ class MulLeftReflectLE [Mul M] [LE M] : Prop where /-- Do not use this. Use `le_of_mul_le_mul_left'` instead. -/ protected le_of_mul_le_mul_left' {a b₁ b₂ : M} : a * b₁ ≤ a * b₂ → b₁ ≤ b₂ @@ -236,7 +239,7 @@ class MulLeftReflectLE [Mul M] [LE M] : Prop where namely `a₁ * b ≤ a₂ * b → a₁ ≤ a₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCancelCommMonoid`. -/ +`IsOrderedCancelMonoid`. -/ class MulRightReflectLE [Mul M] [LE M] : Prop where /-- Do not use this. Use `le_of_mul_le_mul_right'` instead. -/ protected le_of_mul_le_mul_right' {b a₁ a₂ : M} : a₁ * b ≤ a₂ * b → a₁ ≤ a₂ @@ -245,7 +248,7 @@ class MulRightReflectLE [Mul M] [LE M] : Prop where namely `a + b₁ ≤ a + b₂ → b₁ ≤ b₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCancelAddCommMonoid`. -/ +`IsOrderedCancelAddMonoid`. -/ class AddLeftReflectLE [Add M] [LE M] : Prop where /-- Do not use this. Use `le_of_add_le_add_left` instead. -/ protected le_of_add_le_add_left {a b₁ b₂ : M} : a + b₁ ≤ a + b₂ → b₁ ≤ b₂ @@ -254,7 +257,7 @@ class AddLeftReflectLE [Add M] [LE M] : Prop where namely `a₁ + b ≤ a₂ + b → a₁ ≤ a₂`. You should usually not use this very granular typeclass directly, but rather a typeclass like -`OrderedCancelAddCommMonoid`. -/ +`IsOrderedCancelAddMonoid`. -/ class AddRightReflectLE [Add M] [LE M] : Prop where /-- Do not use this. Use `le_of_add_le_add_right` instead. -/ protected le_of_add_le_add_right {b a₁ a₂ : M} : a₁ + b ≤ a₂ + b → a₁ ≤ a₂ diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean index 81459510a72dc9..506961d65399eb 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean @@ -22,16 +22,16 @@ public section universe u variable {α : Type u} -/-- An `OrderedAddCommMonoid` with one-sided 'subtraction' in the sense that +/-- An ordered additive monoid with one-sided 'subtraction' in the sense that if `a ≤ b`, then there is some `c` for which `a + c = b`. This is a weaker version -of the condition on canonical orderings defined by `CanonicallyOrderedAddCommMonoid`. -/ +of the condition on canonical orderings defined by `CanonicallyOrderedAdd`. -/ class ExistsAddOfLE (α : Type u) [Add α] [LE α] : Prop where /-- For `a ≤ b`, there is a `c` so `b = a + c`. -/ exists_add_of_le : ∀ {a b : α}, a ≤ b → ∃ c : α, b = a + c -/-- An `OrderedCommMonoid` with one-sided 'division' in the sense that +/-- An ordered monoid with one-sided 'division' in the sense that if `a ≤ b`, there is some `c` for which `a * c = b`. This is a weaker version -of the condition on canonical orderings defined by `CanonicallyOrderedCommMonoid`. -/ +of the condition on canonical orderings defined by `CanonicallyOrderedMul`. -/ @[to_additive] class ExistsMulOfLE (α : Type u) [Mul α] [LE α] : Prop where /-- For `a ≤ b`, `a` left divides `b` -/ diff --git a/Mathlib/Algebra/Order/Nonneg/Field.lean b/Mathlib/Algebra/Order/Nonneg/Field.lean index e78440221e8537..3e1f5c8136cdfb 100644 --- a/Mathlib/Algebra/Order/Nonneg/Field.lean +++ b/Mathlib/Algebra/Order/Nonneg/Field.lean @@ -18,10 +18,6 @@ This file defines instances and prove some properties about the nonnegative elem `{x : α // 0 ≤ x}` of an arbitrary type `α`. This is used to derive algebraic structures on `ℝ≥0` and `ℚ≥0` automatically. - -## Main declarations - -* `{x : α // 0 ≤ x}` is a `CanonicallyLinearOrderedSemifield` if `α` is a `LinearOrderedField`. -/ @[expose] public section diff --git a/Mathlib/Algebra/Order/Nonneg/Ring.lean b/Mathlib/Algebra/Order/Nonneg/Ring.lean index 3a34a803638f25..7bed53c24a457c 100644 --- a/Mathlib/Algebra/Order/Nonneg/Ring.lean +++ b/Mathlib/Algebra/Order/Nonneg/Ring.lean @@ -21,10 +21,6 @@ Currently we only state instances and states some `simp`/`norm_cast` lemmas. When `α` is `ℝ`, this will give us some properties about `ℝ≥0`. -## Main declarations - -* `{x : α // 0 ≤ x}` is a `CanonicallyLinearOrderedAddCommMonoid` if `α` is a `LinearOrderedRing`. - ## Implementation Notes Instead of `{x : α // 0 ≤ x}` we could also use `Set.Ici (0 : α)`, which is definitionally equal. diff --git a/Mathlib/Algebra/Order/Positive/Ring.lean b/Mathlib/Algebra/Order/Positive/Ring.lean index cf3eef98b85bcc..a445ed2d6e8bc0 100644 --- a/Mathlib/Algebra/Order/Positive/Ring.lean +++ b/Mathlib/Algebra/Order/Positive/Ring.lean @@ -12,7 +12,7 @@ public import Mathlib.Tactic.FastInstance /-! # Algebraic structures on the set of positive numbers -In this file we define various instances (`AddSemigroup`, `OrderedCommMonoid` etc) on the +In this file we define various instances (`AddSemigroup`, `IsOrderedMonoid` etc) on the type `{x : R // 0 < x}`. In each case we try to require the weakest possible typeclass assumptions on `R` but possibly, there is a room for improvements. -/ diff --git a/Mathlib/Algebra/Order/Ring/Basic.lean b/Mathlib/Algebra/Order/Ring/Basic.lean index e6787f71924f37..6bd5827d8ae773 100644 --- a/Mathlib/Algebra/Order/Ring/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Basic.lean @@ -96,11 +96,10 @@ def IsNonarchimedean {α : Type*} [Add α] (f : α → R) : Prop := ∀ a b : α /-! ### Lemmas for canonically linear ordered semirings or linear ordered rings -The slightly unusual typeclass assumptions `[LinearOrderedSemiring R] [ExistsAddOfLE R]` cover two +The slightly unusual typeclass assumptions `[IsStrictOrderedRing R] [ExistsAddOfLE R]` cover two more familiar settings: -* `[LinearOrderedRing R]`, e.g. `ℤ`, `ℚ` or `ℝ` -* `[CanonicallyLinearOrderedSemiring R]` (although we don't actually have this typeclass), e.g. `ℕ`, - `ℚ≥0` or `ℝ≥0` +* linearly ordered rings, e.g. `ℤ`, `ℚ` or `ℝ` +* canonically ordered semirings, e.g. `ℕ`, `ℚ≥0` or `ℝ≥0` -/ variable [ExistsAddOfLE R] diff --git a/Mathlib/Algebra/Order/Ring/Cone.lean b/Mathlib/Algebra/Order/Ring/Cone.lean index 6a25aeef9afe6f..087733faa3c575 100644 --- a/Mathlib/Algebra/Order/Ring/Cone.lean +++ b/Mathlib/Algebra/Order/Ring/Cone.lean @@ -11,8 +11,7 @@ public import Mathlib.Algebra.Ring.Subsemiring.Order /-! # Construct ordered rings from rings with a specified positive cone. -In this file we provide the structure `RingCone` -that encodes axioms of `OrderedRing` and `LinearOrderedRing` +In this file we provide the structure `RingCone` that encodes axioms of ordered rings in terms of the subset of non-negative elements. We also provide constructors that convert between diff --git a/Mathlib/Algebra/Order/Ring/Defs.lean b/Mathlib/Algebra/Order/Ring/Defs.lean index 45ff82dcc6f8ca..920929518e66b2 100644 --- a/Mathlib/Algebra/Order/Ring/Defs.lean +++ b/Mathlib/Algebra/Order/Ring/Defs.lean @@ -34,24 +34,10 @@ For short, ## Typeclasses -* `OrderedSemiring`: Semiring with a partial order such that `+` and `*` respect `≤`. -* `StrictOrderedSemiring`: Nontrivial semiring with a partial order such that `+` and `*` respects - `<`. -* `OrderedCommSemiring`: Commutative semiring with a partial order such that `+` and `*` respect - `≤`. -* `StrictOrderedCommSemiring`: Nontrivial commutative semiring with a partial order such that `+` - and `*` respect `<`. -* `OrderedRing`: Ring with a partial order such that `+` respects `≤` and `*` respects `<`. -* `OrderedCommRing`: Commutative ring with a partial order such that `+` respects `≤` and - `*` respects `<`. -* `LinearOrderedSemiring`: Nontrivial semiring with a linear order such that `+` respects `≤` and - `*` respects `<`. -* `LinearOrderedCommSemiring`: Nontrivial commutative semiring with a linear order such that `+` - respects `≤` and `*` respects `<`. -* `LinearOrderedRing`: Nontrivial ring with a linear order such that `+` respects `≤` and `*` - respects `<`. -* `LinearOrderedCommRing`: Nontrivial commutative ring with a linear order such that `+` respects - `≤` and `*` respects `<`. +* `IsOrderedRing`: Semiring with a partial order such that addition and multiplication by a + nonnegative number are both monotone. +* `IsStrictOrderedRing`: Nontrivial semiring with a partial order such that addition and + multiplication by a positive number are both strictly monotone. ## Hierarchy @@ -59,49 +45,13 @@ The hardest part of proving order lemmas might be to figure out the correct gene corresponding typeclass. Here's an attempt at demystifying it. For each typeclass, we list its immediate predecessors and what conditions are added to each of them. -* `OrderedSemiring` - - `OrderedAddCommMonoid` & multiplication & `*` respects `≤` - - `Semiring` & partial order structure & `+` respects `≤` & `*` respects `≤` -* `StrictOrderedSemiring` - - `OrderedCancelAddCommMonoid` & multiplication & `*` respects `<` & nontriviality - - `OrderedSemiring` & `+` respects `<` & `*` respects `<` & nontriviality -* `OrderedCommSemiring` - - `OrderedSemiring` & commutativity of multiplication - - `CommSemiring` & partial order structure & `+` respects `≤` & `*` respects `<` -* `StrictOrderedCommSemiring` - - `StrictOrderedSemiring` & commutativity of multiplication - - `OrderedCommSemiring` & `+` respects `<` & `*` respects `<` & nontriviality -* `OrderedRing` - - `OrderedSemiring` & additive inverses - - `OrderedAddCommGroup` & multiplication & `*` respects `<` - - `Ring` & partial order structure & `+` respects `≤` & `*` respects `<` -* `StrictOrderedRing` - - `StrictOrderedSemiring` & additive inverses - - `OrderedSemiring` & `+` respects `<` & `*` respects `<` & nontriviality -* `OrderedCommRing` - - `OrderedRing` & commutativity of multiplication - - `OrderedCommSemiring` & additive inverses - - `CommRing` & partial order structure & `+` respects `≤` & `*` respects `<` -* `StrictOrderedCommRing` - - `StrictOrderedCommSemiring` & additive inverses - - `StrictOrderedRing` & commutativity of multiplication - - `OrderedCommRing` & `+` respects `<` & `*` respects `<` & nontriviality -* `LinearOrderedSemiring` - - `StrictOrderedSemiring` & totality of the order - - `LinearOrderedAddCommMonoid` & multiplication & nontriviality & `*` respects `<` -* `LinearOrderedCommSemiring` - - `StrictOrderedCommSemiring` & totality of the order - - `LinearOrderedSemiring` & commutativity of multiplication -* `LinearOrderedRing` - - `StrictOrderedRing` & totality of the order - - `LinearOrderedSemiring` & additive inverses - - `LinearOrderedAddCommGroup` & multiplication & `*` respects `<` - - `Ring` & `IsDomain` & linear order structure -* `LinearOrderedCommRing` - - `StrictOrderedCommRing` & totality of the order - - `LinearOrderedRing` & commutativity of multiplication - - `LinearOrderedCommSemiring` & additive inverses - - `CommRing` & `IsDomain` & linear order structure +* `PartialOrder` + `Semiring` + `IsOrderedRing` + - `IsOrderedAddMonoid` & multiplication & `*` respects `≤` +* `PartialOrder` + `Semiring` + `IsStrictOrderedRing` + - `IsOrderedCancelAddMonoid` & multiplication & `*` respects `<` & nontriviality +* `LinearOrder` + `Ring` + `IsOrderedRing` + - `IsStrictOrderedRing` & totality of the order + - `IsDomain` & linear order structure -/ public section diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean index 5a8efc07831acf..3fa36da6ea7b5b 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean @@ -21,97 +21,14 @@ public import Mathlib.Tactic.Tauto This file develops the basics of ordered (semi)rings in an unbundled fashion for later use with the bundled classes from `Mathlib/Algebra/Order/Ring/Defs.lean`. -The set of typeclass variables here comprises -* an algebraic class (`Semiring`, `CommSemiring`, `Ring`, `CommRing`) -* an order class (`PartialOrder`, `LinearOrder`) -* assumptions on how both interact ((strict) monotonicity, canonicity) - -For short, -* "`+` respects `≤`" means "monotonicity of addition" -* "`+` respects `<`" means "strict monotonicity of addition" -* "`*` respects `≤`" means "monotonicity of multiplication by a nonnegative number". -* "`*` respects `<`" means "strict monotonicity of multiplication by a positive number". - -## Typeclasses found in `Algebra.Order.Ring.Defs` - -* `OrderedSemiring`: Semiring with a partial order such that `+` and `*` respect `≤`. -* `StrictOrderedSemiring`: Nontrivial semiring with a partial order such that `+` and `*` respects - `<`. -* `OrderedCommSemiring`: Commutative semiring with a partial order such that `+` and `*` respect - `≤`. -* `StrictOrderedCommSemiring`: Nontrivial commutative semiring with a partial order such that `+` - and `*` respect `<`. -* `OrderedRing`: Ring with a partial order such that `+` respects `≤` and `*` respects `<`. -* `OrderedCommRing`: Commutative ring with a partial order such that `+` respects `≤` and - `*` respects `<`. -* `LinearOrderedSemiring`: Nontrivial semiring with a linear order such that `+` respects `≤` and - `*` respects `<`. -* `LinearOrderedCommSemiring`: Nontrivial commutative semiring with a linear order such that `+` - respects `≤` and `*` respects `<`. -* `LinearOrderedRing`: Nontrivial ring with a linear order such that `+` respects `≤` and `*` - respects `<`. -* `LinearOrderedCommRing`: Nontrivial commutative ring with a linear order such that `+` respects - `≤` and `*` respects `<`. -* `CanonicallyOrderedCommSemiring`: Commutative semiring with a partial order such that `+` - respects `≤`, `*` respects `<`, and `a ≤ b ↔ ∃ c, b = a + c`. - -## Hierarchy - -The hardest part of proving order lemmas might be to figure out the correct generality and its -corresponding typeclass. Here's an attempt at demystifying it. For each typeclass, we list its -immediate predecessors and what conditions are added to each of them. - -* `OrderedSemiring` - - `OrderedAddCommMonoid` & multiplication & `*` respects `≤` - - `Semiring` & partial order structure & `+` respects `≤` & `*` respects `≤` -* `StrictOrderedSemiring` - - `OrderedCancelAddCommMonoid` & multiplication & `*` respects `<` & nontriviality - - `OrderedSemiring` & `+` respects `<` & `*` respects `<` & nontriviality -* `OrderedCommSemiring` - - `OrderedSemiring` & commutativity of multiplication - - `CommSemiring` & partial order structure & `+` respects `≤` & `*` respects `<` -* `StrictOrderedCommSemiring` - - `StrictOrderedSemiring` & commutativity of multiplication - - `OrderedCommSemiring` & `+` respects `<` & `*` respects `<` & nontriviality -* `OrderedRing` - - `OrderedSemiring` & additive inverses - - `OrderedAddCommGroup` & multiplication & `*` respects `<` - - `Ring` & partial order structure & `+` respects `≤` & `*` respects `<` -* `StrictOrderedRing` - - `StrictOrderedSemiring` & additive inverses - - `OrderedSemiring` & `+` respects `<` & `*` respects `<` & nontriviality -* `OrderedCommRing` - - `OrderedRing` & commutativity of multiplication - - `OrderedCommSemiring` & additive inverses - - `CommRing` & partial order structure & `+` respects `≤` & `*` respects `<` -* `StrictOrderedCommRing` - - `StrictOrderedCommSemiring` & additive inverses - - `StrictOrderedRing` & commutativity of multiplication - - `OrderedCommRing` & `+` respects `<` & `*` respects `<` & nontriviality -* `LinearOrderedSemiring` - - `StrictOrderedSemiring` & totality of the order - - `LinearOrderedAddCommMonoid` & multiplication & nontriviality & `*` respects `<` -* `LinearOrderedCommSemiring` - - `StrictOrderedCommSemiring` & totality of the order - - `LinearOrderedSemiring` & commutativity of multiplication -* `LinearOrderedRing` - - `StrictOrderedRing` & totality of the order - - `LinearOrderedSemiring` & additive inverses - - `LinearOrderedAddCommGroup` & multiplication & `*` respects `<` - - `Ring` & `IsDomain` & linear order structure -* `LinearOrderedCommRing` - - `StrictOrderedCommRing` & totality of the order - - `LinearOrderedRing` & commutativity of multiplication - - `LinearOrderedCommSemiring` & additive inverses - - `CommRing` & `IsDomain` & linear order structure - ## Generality Each section is labelled with a corresponding bundled ordered ring typeclass in mind. Mixins for relating the order structures and ring structures are added as needed. -TODO: the mixin assumptions can be relaxed in most cases +## TODO +The mixin assumptions can be relaxed in most cases. -/ public section @@ -581,7 +498,7 @@ theorem mul_nonneg_iff [ExistsAddOfLE R] [MulPosStrictMono R] [PosMulStrictMono ⟨nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg, fun h => h.elim (and_imp.2 mul_nonneg) (and_imp.2 mul_nonneg_of_nonpos_of_nonpos)⟩ -/-- Out of three elements of a `LinearOrderedRing`, two must have the same sign. -/ +/-- Out of three elements of a linearly ordered semiring, two must have the same sign. -/ theorem mul_nonneg_of_three [ExistsAddOfLE R] [MulPosStrictMono R] [PosMulStrictMono R] [AddLeftMono R] [AddLeftReflectLE R] (a b c : R) : 0 ≤ a * b ∨ 0 ≤ b * c ∨ 0 ≤ c * a := by diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index 99fa9e39b070f5..9aba3e1e74e5d3 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -29,8 +29,8 @@ rather the entire `≤` relation with `StarOrderedRing.le_iff`. However, notice `NonUnitalRing`, these are equivalent (see `StarOrderedRing.nonneg_iff` and `StarOrderedRing.of_nonneg_iff`). -It is important to note that while a `StarOrderedRing` is an `OrderedAddCommMonoid` it is often -*not* an `OrderedSemiring`. +It is important to note that while a `StarOrderedRing` often satisfies `IsOrderedAddMonoid`, +it usually does *not* satisfy `IsOrderedRing`. ## TODO diff --git a/Mathlib/Algebra/Order/Sub/Basic.lean b/Mathlib/Algebra/Order/Sub/Basic.lean index d518c3bd07dab7..9882f36b04bb39 100644 --- a/Mathlib/Algebra/Order/Sub/Basic.lean +++ b/Mathlib/Algebra/Order/Sub/Basic.lean @@ -191,7 +191,7 @@ theorem tsub_add_min : a - b + min a b = a := by rw [← tsub_min, @tsub_add_cancel_of_le] apply min_le_left --- `Odd.tsub` requires `CanonicallyLinearOrderedSemiring`, which we don't have +-- TODO: Should we introduce `Odd.tsub`? It will probably only be used by `ℕ`. lemma Even.tsub [AddLeftReflectLE α] {m n : α} (hm : Even m) (hn : Even n) : Even (m - n) := by obtain ⟨a, rfl⟩ := hm diff --git a/Mathlib/Algebra/Order/Sub/WithTop.lean b/Mathlib/Algebra/Order/Sub/WithTop.lean index 4139459a3b5b07..e2805019755413 100644 --- a/Mathlib/Algebra/Order/Sub/WithTop.lean +++ b/Mathlib/Algebra/Order/Sub/WithTop.lean @@ -17,8 +17,8 @@ the bottom element is zero. Note that there is another subtraction on objects of the form `WithTop α` in the file `Mathlib/Algebra/Order/AddGroupWithTop.lean`, setting `-⊤ = ⊤` as this corresponds to the -additivization of the usual convention `0⁻¹ = 0` and is relevant in valuation theory. Since this -other instance is only registered for `LinearOrderedAddCommGroup α` (which doesn't have a bottom +additivization of the usual convention `0⁻¹ = 0` and is relevant in valuation theory. Since that +other instance is only registered for `AddCommGroup α` (which doesn't have a bottom element, unless the group is trivial), this shouldn't create diamonds. -/ diff --git a/Mathlib/Algebra/Order/ToIntervalMod.lean b/Mathlib/Algebra/Order/ToIntervalMod.lean index 0ac987cb2d166d..637edc191bba29 100644 --- a/Mathlib/Algebra/Order/ToIntervalMod.lean +++ b/Mathlib/Algebra/Order/ToIntervalMod.lean @@ -16,9 +16,8 @@ import Mathlib.GroupTheory.QuotientGroup.ModEq /-! # Reducing to an interval modulo its length -This file defines operations that reduce a number (in an `Archimedean` -`LinearOrderedAddCommGroup`) to a number in a given interval, modulo the length of that -interval. +This file defines operations that reduce a number (in an archimedean linearly ordered abelian group) +to a number in a given interval, modulo the length of that interval. ## Main definitions diff --git a/Mathlib/Algebra/Order/WithTop/Untop0.lean b/Mathlib/Algebra/Order/WithTop/Untop0.lean index 5750f6c6b92df2..8310003823c8c4 100644 --- a/Mathlib/Algebra/Order/WithTop/Untop0.lean +++ b/Mathlib/Algebra/Order/WithTop/Untop0.lean @@ -86,18 +86,10 @@ lemma untop₀_neg [AddCommGroup α] : ∀ a : WithTop α, (-a).untop₀ = -a.un | ⊤ => by simp | (a : α) => rfl -/-! -## Simplifying Lemmas in cases where α is a MulZeroClass --/ - @[simp] lemma untop₀_mul [DecidableEq α] [MulZeroClass α] (a b : WithTop α) : (a * b).untop₀ = a.untop₀ * b.untop₀ := untopD_zero_mul a b -/-! -## Simplifying Lemmas in cases where α is an OrderedAddCommGroup --/ - section OrderedAddCommGroup variable [AddCommGroup α] [PartialOrder α] {a b : WithTop α} @@ -132,10 +124,6 @@ theorem untop₀_le_untop₀_iff (ha : a ≠ ⊤) (hb : b ≠ ⊤) : end OrderedAddCommGroup -/-! -## Simplifying Lemmas in cases where α is a LinearOrderedAddCommGroup --/ - section LinearOrderedAddCommGroup variable [AddCommGroup α] [LinearOrder α] {a b : WithTop α} diff --git a/Mathlib/Analysis/Complex/Order.lean b/Mathlib/Analysis/Complex/Order.lean index a9f974e34436db..179d46a06f6aba 100644 --- a/Mathlib/Analysis/Complex/Order.lean +++ b/Mathlib/Analysis/Complex/Order.lean @@ -13,9 +13,9 @@ public import Mathlib.Analysis.Complex.Norm This order is defined by `z ≤ w ↔ z.re ≤ w.re ∧ z.im = w.im`. This is a natural order on `ℂ` because, as is well-known, there does not exist an order on `ℂ` -making it into a `LinearOrderedField`. However, the order described above is the canonical order +making it into a linearly ordered field. However, the order described above is the canonical order stemming from the structure of `ℂ` as a ⋆-ring (i.e., it becomes a `StarOrderedRing`). Moreover, -with this order `ℂ` is a `StrictOrderedCommRing` and the coercion `(↑) : ℝ → ℂ` is an order +with this order `ℂ` satisfies `IsStrictOrderedRing` and the coercion `(↑) : ℝ → ℂ` is an order embedding. This file only provides `Complex.partialOrder` and lemmas about it. Further structural classes are diff --git a/Mathlib/Combinatorics/Pigeonhole.lean b/Mathlib/Combinatorics/Pigeonhole.lean index 35207f37b09821..f76c77f931577d 100644 --- a/Mathlib/Combinatorics/Pigeonhole.lean +++ b/Mathlib/Combinatorics/Pigeonhole.lean @@ -87,7 +87,7 @@ variations of this theorem. The principle is formalized in the following way, see `Finset.exists_lt_sum_fiber_of_maps_to_of_nsmul_lt_sum`: if `f : α → β` is a function which maps all elements of `s : Finset α` to `t : Finset β` and `#t • b < ∑ x ∈ s, w x`, where `w : α → M` is -a weight function taking values in a `LinearOrderedCancelAddCommMonoid`, then for +a weight function taking values in a linearly ordered cancellative monoid, then for some `y ∈ t`, the sum of the weights of all `x ∈ s` such that `f x = y` is greater than `b`. There are a few bits we can change in this theorem: diff --git a/Mathlib/Data/Finsupp/Weight.lean b/Mathlib/Data/Finsupp/Weight.lean index 19d680c975ef11..4c1fae64aabf15 100644 --- a/Mathlib/Data/Finsupp/Weight.lean +++ b/Mathlib/Data/Finsupp/Weight.lean @@ -31,9 +31,9 @@ as well as a function `w : σ → M`. (The important case is `R = ℕ`.) - `Finsupp.le_weight` says that `f s ≤ f.weight w` when `M = ℕ` - `Finsupp.le_weight_of_ne_zero` says that `w s ≤ f.weight w` - for `OrderedAddCommMonoid M`, when `f s ≠ 0` and all `w i` are nonnegative. + for `IsOrderedAddMonoid M`, when `f s ≠ 0` and all `w i` are nonnegative. -- `Finsupp.le_weight_of_ne_zero'` is the same statement for `CanonicallyOrderedAddCommMonoid M`. +- `Finsupp.le_weight_of_ne_zero'` is the same statement for `CanonicallyOrderedAdd M`. - `NonTorsionWeight`: all values `w s` are nontorsion in `M`. diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index 41e15f10ecf1e6..5bb1fff0c6d3d4 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -24,7 +24,7 @@ a.k.a. the interval `[0, ∞)`. We also define the following operations and stru complete linear ordered archimedean commutative semifield; we have no typeclass for this in `mathlib` yet, so we define the following instances instead: - - `LinearOrderedSemiring ℝ≥0`; + - `IsOrderedRing ℝ≥0`; - `OrderedCommSemiring ℝ≥0`; - `CanonicallyOrderedAdd ℝ≥0`; - `LinearOrderedCommGroupWithZero ℝ≥0`; diff --git a/Mathlib/Data/Nat/Cast/Order/Basic.lean b/Mathlib/Data/Nat/Cast/Order/Basic.lean index 575cb7470728b0..77c89f5e3e0ca5 100644 --- a/Mathlib/Data/Nat/Cast/Order/Basic.lean +++ b/Mathlib/Data/Nat/Cast/Order/Basic.lean @@ -23,12 +23,6 @@ assert_not_exists IsOrderedMonoid variable {α : Type*} namespace Nat - -section OrderedSemiring -/- Note: even though the section indicates `OrderedSemiring`, which is the common use case, -we use a generic collection of instances so that it applies in other settings (e.g., in a -`StarOrderedRing`, or the `selfAdjoint` or `StarOrderedRing.positive` parts thereof). -/ - variable [AddMonoidWithOne α] [PartialOrder α] variable [AddLeftMono α] [ZeroLEOneClass α] @@ -37,12 +31,12 @@ theorem mono_cast : Monotone (Nat.cast : ℕ → α) := monotone_nat_of_le_succ fun n ↦ by rw [Nat.cast_succ]; exact le_add_of_nonneg_right zero_le_one -/-- See also `Nat.cast_nonneg`, specialised for an `OrderedSemiring`. -/ +/-- See also `Nat.cast_nonneg`, specialised to `IsOrderedRing`. -/ @[simp low] theorem cast_nonneg' (n : ℕ) : 0 ≤ (n : α) := @Nat.cast_zero α _ ▸ mono_cast (Nat.zero_le n) -/-- See also `Nat.ofNat_nonneg`, specialised for an `OrderedSemiring`. -/ +/-- See also `Nat.ofNat_nonneg`, specialised to `IsOrderedRing`. -/ @[simp low] theorem ofNat_nonneg' (n : ℕ) [n.AtLeastTwo] : 0 ≤ (ofNat(n) : α) := cast_nonneg' n @@ -55,7 +49,7 @@ theorem cast_add_one_pos (n : ℕ) : 0 < (n : α) + 1 := by convert! (@mono_cast α _).imp (?_ : 1 ≤ n + 1) <;> simp -/-- See also `Nat.cast_pos`, specialised for an `OrderedSemiring`. -/ +/-- See also `Nat.cast_pos`, specialised to `IsOrderedRing`. -/ @[simp low] theorem cast_pos' {n : ℕ} : (0 : α) < n ↔ 0 < n := by cases n <;> simp [cast_add_one_pos] @@ -153,8 +147,6 @@ theorem ofNat_lt : (ofNat(m) : α) < (ofNat(n) : α) ↔ (OfNat.ofNat m : ℕ) < OfNat.ofNat n := cast_lt -end OrderedSemiring - end Nat instance [AddMonoidWithOne α] [CharZero α] : Nontrivial α where exists_pair_ne := diff --git a/Mathlib/Data/Nat/Cast/Order/Ring.lean b/Mathlib/Data/Nat/Cast/Order/Ring.lean index 9b99ac171001ed..dd5419a62a310e 100644 --- a/Mathlib/Data/Nat/Cast/Order/Ring.lean +++ b/Mathlib/Data/Nat/Cast/Order/Ring.lean @@ -21,11 +21,7 @@ variable {R α : Type*} namespace Nat -section OrderedSemiring -/- Note: even though the section indicates `OrderedSemiring`, which is the common use case, -we use a generic collection of instances so that it applies in other settings (e.g., in a -`StarOrderedRing`, or the `selfAdjoint` or `StarOrderedRing.positive` parts thereof). -/ - +section AddMonoidWithOne variable [AddMonoidWithOne α] [PartialOrder α] variable [AddLeftMono α] [ZeroLEOneClass α] @@ -59,7 +55,7 @@ variable [NeZero (1 : α)] theorem cast_pos {α} [Semiring α] [PartialOrder α] [IsOrderedRing α] [Nontrivial α] {n : ℕ} : (0 : α) < n ↔ 0 < n := cast_pos' -/-- See also `Nat.ofNat_pos`, specialised for an `OrderedSemiring`. -/ +/-- See also `Nat.ofNat_pos`, specialised to `IsOrderedRing`. -/ @[simp low] theorem ofNat_pos' {n : ℕ} [n.AtLeastTwo] : 0 < (ofNat(n) : α) := cast_pos'.mpr (NeZero.pos n) @@ -73,7 +69,7 @@ theorem ofNat_pos {α} [Semiring α] [PartialOrder α] [IsOrderedRing α] [Nontr end Nontrivial -end OrderedSemiring +end AddMonoidWithOne /-- A version of `Nat.cast_sub` that works for `ℝ≥0` and `ℚ≥0`. Note that this proof doesn't work for `ℕ∞` and `ℝ≥0∞`, so we use type-specific lemmas for these types. -/ diff --git a/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean index 550c4f6b503a3d..f98961391940e6 100644 --- a/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean @@ -46,7 +46,7 @@ matrix (like powers) into graph-theoretic properties of its quiver (like the exi ## Implementation notes -Throughout we work over a `LinearOrderedRing R`. Some results require stronger assumptions, +Throughout we work over a linearly ordered ring `R`. Some results require stronger assumptions, like `PosMulStrictMono R` or `Nontrivial R`. Some statements expand matrix powers and thus require `[DecidableEq n]` to reason about finite sums. diff --git a/Mathlib/MeasureTheory/Function/LpOrder.lean b/Mathlib/MeasureTheory/Function/LpOrder.lean index a56c96738bcebb..e28f57d227f38a 100644 --- a/Mathlib/MeasureTheory/Function/LpOrder.lean +++ b/Mathlib/MeasureTheory/Function/LpOrder.lean @@ -14,7 +14,7 @@ public import Mathlib.MeasureTheory.Function.LpSpace.Basic ## Results -- `Lp E p μ` is an `OrderedAddCommGroup` when `E` is a `NormedLatticeAddCommGroup`. +- `Lp E p μ` is an ordered group when `E` is a `NormedLatticeAddCommGroup`. ## TODO diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean index 1f4ea177ffb1d0..fdc5d2827d7b41 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean @@ -148,7 +148,7 @@ theorem measureUnivNNReal_pos [IsFiniteMeasure μ] (hμ : μ ≠ 0) : 0 < measur contrapose! hμ simpa [measureUnivNNReal_eq_zero, Nat.le_zero] using hμ -/-- `le_of_add_le_add_left` is normally applicable to `OrderedCancelAddCommMonoid`, +/-- `le_of_add_le_add_left` is normally applicable to ordered cancellative monoids, but it holds for measures with the additional assumption that μ is finite. -/ theorem Measure.le_of_add_le_add_left [IsFiniteMeasure μ] (A2 : μ + ν₁ ≤ μ + ν₂) : ν₁ ≤ ν₂ := fun S => ENNReal.le_of_add_le_add_left (MeasureTheory.measure_ne_top μ S) (A2 S) diff --git a/Mathlib/Order/Filter/AtTopBot/Archimedean.lean b/Mathlib/Order/Filter/AtTopBot/Archimedean.lean index de33d127a733bd..dcafa4e223f82d 100644 --- a/Mathlib/Order/Filter/AtTopBot/Archimedean.lean +++ b/Mathlib/Order/Filter/AtTopBot/Archimedean.lean @@ -214,20 +214,20 @@ section LinearOrderedRing variable [Ring R] [LinearOrder R] [IsStrictOrderedRing R] [Archimedean R] /-- See also `Filter.Tendsto.atTop_mul_const_of_neg` for a version of this lemma for -`LinearOrderedField`s which does not require the `Archimedean` assumption. -/ +linearly ordered fields which does not require the `Archimedean` assumption. -/ theorem Tendsto.atTop_mul_const_of_neg' (hr : r < 0) (hf : Tendsto f l atTop) : Tendsto (fun x => f x * r) l atBot := by simpa only [tendsto_neg_atTop_iff, mul_neg] using hf.atTop_mul_const' (neg_pos.mpr hr) /-- See also `Filter.Tendsto.atBot_mul_const` for a version of this lemma for -`LinearOrderedField`s which does not require the `Archimedean` assumption. -/ +linearly ordered fields which does not require the `Archimedean` assumption. -/ theorem Tendsto.atBot_mul_const' (hr : 0 < r) (hf : Tendsto f l atBot) : Tendsto (fun x => f x * r) l atBot := by simp only [← tendsto_neg_atTop_iff, ← neg_mul] at hf ⊢ exact hf.atTop_mul_const' hr /-- See also `Filter.Tendsto.atBot_mul_const_of_neg` for a version of this lemma for -`LinearOrderedField`s which does not require the `Archimedean` assumption. -/ +linearly ordered fields which does not require the `Archimedean` assumption. -/ theorem Tendsto.atBot_mul_const_of_neg' (hr : r < 0) (hf : Tendsto f l atBot) : Tendsto (fun x => f x * r) l atTop := by simpa only [mul_neg, tendsto_neg_atBot_iff] using hf.atBot_mul_const' (neg_pos.2 hr) diff --git a/Mathlib/Order/Filter/Germ/OrderedMonoid.lean b/Mathlib/Order/Filter/Germ/OrderedMonoid.lean index 3500fd9b30b493..e786c7d1fbe922 100644 --- a/Mathlib/Order/Filter/Germ/OrderedMonoid.lean +++ b/Mathlib/Order/Filter/Germ/OrderedMonoid.lean @@ -15,7 +15,7 @@ public import Mathlib.Order.Filter.Germ.Basic For each of the following structures we prove that if `β` has this structure, then so does `Germ l β`: -* `OrderedCancelCommMonoid` and `OrderedCancelAddCommMonoid`. +* `IsOrderedCancelMonoid` and `IsOrderedCancelAddMonoid`. ## Tags diff --git a/Mathlib/Order/Interval/Finset/Nat.lean b/Mathlib/Order/Interval/Finset/Nat.lean index 7852bd74f40333..700ddec86f1b7e 100644 --- a/Mathlib/Order/Interval/Finset/Nat.lean +++ b/Mathlib/Order/Interval/Finset/Nat.lean @@ -16,7 +16,7 @@ intervals as finsets and fintypes. ## TODO -Some lemmas can be generalized using `OrderedGroup`, `CanonicallyOrderedMul` or `SuccOrder` +Some lemmas can be generalized using `IsOrderedAddMonoid`, `CanonicallyOrderedAdd` or `SuccOrder` and subsequently be moved upstream to `Order.Interval.Finset`. -/ diff --git a/Mathlib/Order/Interval/Set/Defs.lean b/Mathlib/Order/Interval/Set/Defs.lean index 5e19c38fbed891..068a144114ac37 100644 --- a/Mathlib/Order/Interval/Set/Defs.lean +++ b/Mathlib/Order/Interval/Set/Defs.lean @@ -83,7 +83,7 @@ to_dual_insert_cast Icc := by simp only [and_comm] /-- We say that a set `s : Set α` is `OrdConnected` if for all `x y ∈ s` it includes the interval `[[x, y]]`. If `α` is a `DenselyOrdered` `ConditionallyCompleteLinearOrder` with the `OrderTopology`, then this condition is equivalent to `IsPreconnected s`. If `α` is a -`LinearOrderedField`, then this condition is also equivalent to `Convex α s`. -/ +linearly ordered field, then this condition is also equivalent to `Convex α s`. -/ class OrdConnected (s : Set α) : Prop where /-- `s : Set α` is `OrdConnected` if for all `x y ∈ s` it includes the interval `[[x, y]]`. -/ out' ⦃x : α⦄ (hx : x ∈ s) ⦃y : α⦄ (hy : y ∈ s) : Icc x y ⊆ s diff --git a/Mathlib/Order/Interval/Set/OrdConnected.lean b/Mathlib/Order/Interval/Set/OrdConnected.lean index 0bad6f3c644c35..47cae5ddfedfa6 100644 --- a/Mathlib/Order/Interval/Set/OrdConnected.lean +++ b/Mathlib/Order/Interval/Set/OrdConnected.lean @@ -15,7 +15,7 @@ public import Mathlib.Order.SetNotation We say that a set `s : Set α` is `OrdConnected` if for all `x y ∈ s` it includes the interval `[[x, y]]`. If `α` is a `DenselyOrdered` `ConditionallyCompleteLinearOrder` with the `OrderTopology`, then this condition is equivalent to `IsPreconnected s`. If `α` is a -`LinearOrderedField`, then this condition is also equivalent to `Convex α s`. +linearly ordered field, then this condition is also equivalent to `Convex α s`. In this file we prove that intersection of a family of `OrdConnected` sets is `OrdConnected` and that all standard intervals are `OrdConnected`. diff --git a/Mathlib/RingTheory/GradedAlgebra/Radical.lean b/Mathlib/RingTheory/GradedAlgebra/Radical.lean index bbdea52c8b271b..e83178cf7ff08f 100644 --- a/Mathlib/RingTheory/GradedAlgebra/Radical.lean +++ b/Mathlib/RingTheory/GradedAlgebra/Radical.lean @@ -26,7 +26,7 @@ This file contains a proof that the radical of any homogeneous ideal is a homoge ## Implementation details Throughout this file, the indexing type `ι` of grading is assumed to be a -`LinearOrderedCancelAddCommMonoid`. This might be stronger than necessary but cancelling +linearly ordered cancellative monoid. This might be stronger than necessary but cancelling property is strictly necessary; for a counterexample of how `Ideal.IsHomogeneous.isPrime_iff` fails for a non-cancellative set see `Counterexamples/HomogeneousPrimeNotPrime.lean`. diff --git a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean index 79dff1967dc088..0dec034a06063a 100644 --- a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean +++ b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean @@ -85,7 +85,7 @@ theorem coeff_toPowerSeries_symm {f : PowerSeries R} {n : ℕ} : variable (Γ R) [Semiring Γ] [PartialOrder Γ] [IsStrictOrderedRing Γ] -/-- Casts a power series as a Hahn series with coefficients from a `StrictOrderedSemiring`. -/ +/-- Casts a power series as a Hahn series with coefficients from a strictly ordered semiring. -/ def ofPowerSeries : PowerSeries R →+* R⟦Γ⟧ := (HahnSeries.embDomainRingHom (Nat.castAddMonoidHom Γ) Nat.strictMono_cast.injective fun _ _ => Nat.cast_le).comp @@ -206,8 +206,7 @@ def toPowerSeriesAlg : A⟦ℕ⟧ ≃ₐ[R] PowerSeries A := variable (Γ) [Semiring Γ] [PartialOrder Γ] [IsStrictOrderedRing Γ] -/-- Casting a power series as a Hahn series with coefficients from a `StrictOrderedSemiring` - is an algebra homomorphism. -/ +/-- Casting a power series as a Hahn series with coefficients from a strictly ordered semiring. -/ @[simps!] def ofPowerSeriesAlg : PowerSeries A →ₐ[R] A⟦Γ⟧ := (HahnSeries.embDomainAlgHom (Nat.castAddMonoidHom Γ) Nat.strictMono_cast.injective fun _ _ => diff --git a/Mathlib/RingTheory/HahnSeries/Valuation.lean b/Mathlib/RingTheory/HahnSeries/Valuation.lean index 046fc3adbab514..349014bca05cff 100644 --- a/Mathlib/RingTheory/HahnSeries/Valuation.lean +++ b/Mathlib/RingTheory/HahnSeries/Valuation.lean @@ -10,7 +10,8 @@ public import Mathlib.RingTheory.Valuation.Basic /-! # Valuations on Hahn Series rings -If `Γ` is a `LinearOrderedCancelAddCommMonoid` and `R` is a domain, then the domain `R⟦Γ⟧` + +If `Γ` is a linearly ordered cancellative monoid and `R` is a domain, then the domain `R⟦Γ⟧` admits an additive valuation given by `orderTop`. ## Main Definitions diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index d7342312ee467e..2be43ba2d95807 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -523,8 +523,8 @@ section OrderedAddCommMonoid variable [AddCommMonoid M] [PartialOrder M] {w : σ → M} (φ : MvPolynomial σ R) -/-- If `M` is a canonically `OrderedAddCommMonoid`, then the `weightedHomogeneousComponent` - of weighted degree `0` of a polynomial is its constant coefficient. -/ +/-- If `M` is canonically ordered, then the `weightedHomogeneousComponent` of weighted degree `0` +of a polynomial is its constant coefficient. -/ @[simp] theorem weightedHomogeneousComponent_zero [CanonicallyOrderedAdd M] [IsAddTorsionFree M] (hw : ∀ i : σ, w i ≠ 0) : diff --git a/Mathlib/Tactic/NormNum/Ineq.lean b/Mathlib/Tactic/NormNum/Ineq.lean index 74518ce20e9761..a70b42dde5a358 100644 --- a/Mathlib/Tactic/NormNum/Ineq.lean +++ b/Mathlib/Tactic/NormNum/Ineq.lean @@ -22,7 +22,7 @@ namespace Mathlib.Meta.NormNum variable {u : Level} -/-- Helper function to synthesize typed `Semiring α` `PartialOrder α` `IsOrderedSemiring α` +/-- Helper function to synthesize typed `Semiring α` `PartialOrder α` `IsOrderedRing α` expressions. -/ def inferOrderedSemiring (α : Q(Type u)) : MetaM <| (_ : Q(Semiring $α)) × (_ : Q(PartialOrder $α)) × Q(IsOrderedRing $α) := @@ -33,7 +33,7 @@ def inferOrderedSemiring (α : Q(Type u)) : MetaM <| return ⟨semiring, partialOrder, isOrderedRing⟩ go <|> throwError "not an ordered semiring" -/-- Helper function to synthesize typed `Ring α` `PartialOrder α` `IsOrderedSemiring α` +/-- Helper function to synthesize typed `Ring α` `PartialOrder α` `IsOrderedRing α` expressions. -/ def inferOrderedRing (α : Q(Type u)) : MetaM <| (_ : Q(Ring $α)) × (_ : Q(PartialOrder $α)) × Q(IsOrderedRing $α) := @@ -240,7 +240,7 @@ where else if let .some _i ← trySynthInstanceQ q(CharZero $α) then let r : Q(Nat.ble $na $nb = false) := (q(Eq.refl false) : Expr) return .isFalse q(isNat_le_false $pa $pb $r) - else -- Nats can appear in an `OrderedRing` without `CharZero`. + else -- Nats can appear in an ordered ring without `CharZero`. intArm attribute [local instance] monadLiftOptionMetaM in @@ -277,11 +277,6 @@ where let r : Q(decide ($nb ≤ $na) = true) := (q(Eq.refl true) : Expr) return .isFalse q(isInt_lt_false $pa $pb $r) let rec nnratArm : MetaM (Result e) := do - -- We need a division ring with an order, and `LinearOrderedField` is the closest mathlib has. - /- - NOTE: after the ordered algebra refactor, this is not true anymore, - so there may be a better typeclass - -/ let ⟨_, _, _⟩ ← inferLinearOrderedSemifield α assumeInstancesCommute haveI' : $e =Q ($a < $b) := ⟨⟩ @@ -294,11 +289,6 @@ where let r : Q(decide ($nb * $da ≤ $na * $db) = true) := (q(Eq.refl true) : Expr) return .isFalse q(isNNRat_lt_false $pa $pb $r) let rec ratArm : MetaM (Result e) := do - -- We need a division ring with an order, and `LinearOrderedField` is the closest mathlib has. - /- - NOTE: after the ordered algebra refactor, this is not true anymore, - so there may be a better typeclass - -/ let ⟨_, _, _i⟩ ← inferLinearOrderedField α assumeInstancesCommute haveI' : $e =Q ($a < $b) := ⟨⟩ @@ -327,7 +317,7 @@ where if let .some _i ← trySynthInstanceQ q(CharZero $α) then let r : Q(Nat.ble $nb $na = false) := (q(Eq.refl false) : Expr) return .isTrue q(isNat_lt_true $pa $pb $r) - else -- Nats can appear in an `OrderedRing` without `CharZero`. + else -- Nats can appear in an ordered ring without `CharZero`. intArm else let r : Q(Nat.ble $nb $na = true) := (q(Eq.refl true) : Expr) diff --git a/MathlibTest/positivity.lean b/MathlibTest/positivity.lean index 1a5b1a7a6c0f4e..9765bcb3dbfffe 100644 --- a/MathlibTest/positivity.lean +++ b/MathlibTest/positivity.lean @@ -545,7 +545,8 @@ example {r : ℝ} (hr : 0 < r) : (0 : EReal) < r := by positivity example {r : ℝ≥0∞} : (0 : EReal) ≤ r := by positivity example {r : ℝ≥0∞} (hr : 0 < r) : (0 : EReal) < r := by positivity --- example {α : Type*} [OrderedRing α] {n : ℤ} : 0 ≤ ((n ^ 2 : ℤ) : α) := by positivity +-- example {R : Type*} [Ring R] [PartialOrder R] [IsOrderedRing R] {n : ℤ} : +-- 0 ≤ ((n ^ 2 : ℤ) : R) := by positivity example {r : ℝ≥0} : 0 ≤ ((r : ℝ) : EReal) := by positivity example {r : ℝ≥0} : 0 < ((r + 1 : ℝ) : EReal) := by positivity diff --git a/docs/overview.yaml b/docs/overview.yaml index ec76c6c11f4918..7d40e124f37b23 100644 --- a/docs/overview.yaml +++ b/docs/overview.yaml @@ -69,7 +69,7 @@ General algebra: localization: 'Localization' local ring: 'IsLocalRing' Noetherian ring: 'IsNoetherianRing' - # ordered ring: 'OrderedRing' + ordered ring: 'IsOrderedRing' Ideals and quotients: ideal of a commutative ring: 'Ideal' From 4d472910901f530740174e155a67628929fb1e44 Mon Sep 17 00:00:00 2001 From: Brian Nugent Date: Wed, 17 Jun 2026 15:15:32 +0000 Subject: [PATCH 0117/1300] feat(CategoryTheory): Functors that preserve the terminal object are Final (#39994) Co-authored-by: Brian-Nugent --- Mathlib/CategoryTheory/Limits/Final.lean | 18 ++++++++++++++++++ .../Sites/CoproductSheafCondition.lean | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Limits/Final.lean b/Mathlib/CategoryTheory/Limits/Final.lean index f4864fa01f8bd7..40de447a51ef95 100644 --- a/Mathlib/CategoryTheory/Limits/Final.lean +++ b/Mathlib/CategoryTheory/Limits/Final.lean @@ -940,6 +940,24 @@ lemma initial_fromPUnit_of_isInitial (hc : Limits.IsInitial c) : (fromPUnit c).I ⟨fun i j ↦ CostructuredArrow.obj_ext _ _ (by cat_disch) (hc.hom_ext _ _)⟩ infer_instance +instance [HasTerminal C] {D : Type u₂} [Category.{v₂} D] (F : C ⥤ D) + [PreservesLimit (Functor.empty.{0} C) F] : F.Final := + have : (fromPUnit.{0} (⊤_ C)).Final := final_fromPUnit_of_isTerminal terminalIsTerminal + have : (fromPUnit.{0} (F.obj (⊤_ C))).Final := final_fromPUnit_of_isTerminal + (terminalIsTerminal.isTerminalObj F (⊤_ C)) + have : ((fromPUnit.{0} (⊤_ C)) ⋙ F).Final := final_of_natIso (F := fromPUnit.{0} (F.obj (⊤_ C))) + (Discrete.natIso (fun _ => Iso.refl _)) + final_of_final_comp (fromPUnit.{0} (⊤_ C)) F + +instance [HasInitial C] {D : Type u₂} [Category.{v₂} D] (F : C ⥤ D) + [PreservesColimit (Functor.empty.{0} C) F] : F.Initial := + have : (fromPUnit.{0} (⊥_ C)).Initial := initial_fromPUnit_of_isInitial initialIsInitial + have : (fromPUnit.{0} (F.obj (⊥_ C))).Initial := initial_fromPUnit_of_isInitial + (initialIsInitial.isInitialObj F (⊥_ C)) + have : ((fromPUnit.{0} (⊥_ C)) ⋙ F).Initial := initial_of_natIso + (F := fromPUnit.{0} (F.obj (⊥_ C))) (Discrete.natIso (fun _ => Iso.refl _)) + initial_of_initial_comp (fromPUnit.{0} (⊥_ C)) F + end section diff --git a/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean b/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean index 205ab6da6c2c30..9ebc9725d813d7 100644 --- a/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean +++ b/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean @@ -98,7 +98,8 @@ lemma Presieve.isSheafFor_sigmaDesc_iff {ι : Type*} {X : ι → C} (f : ∀ i, dsimp [E]; infer_instance have : PreservesLimit (Discrete.functor fun i ↦ op (E.toPreOneHypercover.Y' i)) F := by convert! Functor.Initial.preservesLimit_of_comp (Discrete.equivalence <| .sigmaPUnit _).inverse - assumption + · infer_instance + · assumption let equiv := (E.isLimitSigmaOfIsColimitEquiv hc hc' F).nonempty_congr rwa [isLimit_toPreOneHypercover_type_iff, isLimit_toPreOneHypercover_type_iff, presieve₀_sigmaOfIsColimit] at equiv From 5ac74759704aa69e70b00ea2a622efd06aba73df Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:15:35 +0000 Subject: [PATCH 0118/1300] chore(Analysis/SumIntegralComparisons): golf proofs (#40655) Golfed the existing code in `SumIntegralComparisons.lean`. I had also added some additional API lemmas, but this is now done in #40588 and I have removed the redundant additions to simplify the PR. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) Co-authored-by: Terence Tao --- Mathlib/Analysis/SumIntegralComparisons.lean | 292 ++++++------------- 1 file changed, 88 insertions(+), 204 deletions(-) diff --git a/Mathlib/Analysis/SumIntegralComparisons.lean b/Mathlib/Analysis/SumIntegralComparisons.lean index 8b7e0f244ba4bc..d333e36c258610 100644 --- a/Mathlib/Analysis/SumIntegralComparisons.lean +++ b/Mathlib/Analysis/SumIntegralComparisons.lean @@ -25,11 +25,11 @@ At the moment it contains several lemmas in this direction, for antitone or mono ## Main Results * `AntitoneOn.integral_le_sum`: The integral of an antitone function is at most the sum of its - values at integer steps aligning with the left-hand side of the interval + values at integer steps aligning with the left-hand side of the interval. * `AntitoneOn.sum_le_integral`: The sum of an antitone function along integer steps aligning with the right-hand side of the interval is at most the integral of the function along that interval * `MonotoneOn.integral_le_sum`: The integral of a monotone function is at most the sum of its - values at integer steps aligning with the right-hand side of the interval + values at integer steps aligning with the right-hand side of the interval. * `MonotoneOn.sum_le_integral`: The sum of a monotone function along integer steps aligning with the left-hand side of the interval is at most the integral of the function along that interval * `sum_mul_Ico_le_integral_of_monotone_antitone`: the sum of `f i * g i` on an interval is bounded @@ -44,248 +44,132 @@ analysis, comparison, asymptotics public section - -open Set MeasureTheory MeasureSpace +open Set MeasureTheory MeasureSpace intervalIntegral variable {x₀ : ℝ} {a b : ℕ} {f g : ℝ → ℝ} -lemma sum_Ico_le_integral_of_le - (hab : a ≤ b) (h : ∀ i ∈ Ico a b, ∀ x ∈ Ico (i : ℝ) (i + 1 : ℕ), f i ≤ g x) - (hg : IntegrableOn g (Set.Ico a b)) : - ∑ i ∈ Finset.Ico a b, f i ≤ ∫ x in a..b, g x := by - have A i (hi : i ∈ Finset.Ico a b) : IntervalIntegrable g volume i (i + 1 : ℕ) := by +lemma sum_Ico_le_integral_of_le (hab : a ≤ b) + (h : ∀ i ∈ Ico a b, ∀ x ∈ Ico (i : ℝ) ↑(i + 1), f i ≤ g x) + (hg : IntegrableOn g (Ico a b)) : ∑ i ∈ .Ico a b, f i ≤ ∫ x in a..b, g x := by + have A i (hi : i ∈ Finset.Ico a b) : IntervalIntegrable g volume i ↑(i + 1) := by rw [intervalIntegrable_iff_integrableOn_Ico_of_le (by simp)] - apply hg.mono _ le_rfl - rintro x ⟨hx, h'x⟩ - simp only [Finset.mem_Ico, mem_Ico] at hi ⊢ - exact ⟨le_trans (mod_cast hi.1) hx, h'x.trans_le (mod_cast hi.2)⟩ + simp only [Finset.mem_Ico, ← Nat.add_one_le_iff] at hi + rify at hi + exact hg.mono (by grind) le_rfl calc - ∑ i ∈ Finset.Ico a b, f i - _ = ∑ i ∈ Finset.Ico a b, (∫ x in (i : ℝ)..(i + 1 : ℕ), f i) := by simp - _ ≤ ∑ i ∈ Finset.Ico a b, (∫ x in (i : ℝ)..(i + 1 : ℕ), g x) := by + _ = ∑ i ∈ .Ico a b, (∫ x in (i : ℝ)..↑(i + 1), f i) := by simp + _ ≤ ∑ i ∈ .Ico a b, (∫ x in (i : ℝ)..↑(i + 1), g x) := by gcongr with i hi - apply intervalIntegral.integral_mono_on_of_le_Ioo (by simp) (by simp) (A _ hi) (fun x hx ↦ ?_) + apply integral_mono_on_of_le_Ioo (by simp) (by simp) (A _ hi) (fun x hx ↦ ?_) exact h _ (by simpa using hi) _ (Ioo_subset_Ico_self hx) - _ = ∫ x in a..b, g x := by - rw [intervalIntegral.sum_integral_adjacent_intervals_Ico (a := fun i ↦ i) hab] - intro i hi - exact A _ (by simpa using hi) + _ = _ := by rw [sum_integral_adjacent_intervals_Ico (a := (↑·)) hab]; grind + +lemma integral_le_sum_Ico_of_le (hab : a ≤ b) + (h : ∀ i ∈ Ico a b, ∀ x ∈ Ico (i : ℝ) ↑(i + 1), g x ≤ f i) + (hg : IntegrableOn g (Ico a b)) : ∫ x in a..b, g x ≤ ∑ i ∈ .Ico a b, f i := by + convert! neg_le_neg (sum_Ico_le_integral_of_le (f := -f) (g := -g) hab + (fun i hi x hx ↦ neg_le_neg (h i hi x hx)) hg.neg) <;> simp -lemma integral_le_sum_Ico_of_le - (hab : a ≤ b) (h : ∀ i ∈ Ico a b, ∀ x ∈ Ico (i : ℝ) (i + 1 : ℕ), g x ≤ f i) - (hg : IntegrableOn g (Set.Ico a b)) : - ∫ x in a..b, g x ≤ ∑ i ∈ Finset.Ico a b, f i := by - convert! - neg_le_neg - (sum_Ico_le_integral_of_le (f := -f) (g := -g) hab (fun i hi x hx ↦ neg_le_neg (h i hi x hx)) - hg.neg) <;> simp +private theorem AntitoneOn.intervalIntegrable_subset (hf : AntitoneOn f (Icc x₀ (x₀ + a))) + (k : ℕ) (hk : k + 1 ≤ a) : IntervalIntegrable f volume (x₀ + k) (x₀ + ↑(k + 1)) := by + refine (hf.mono ?_).intervalIntegrable + rw [uIcc_of_le (by simp)] + apply Icc_subset_Icc <;> simp [-Nat.cast_add, hk] theorem AntitoneOn.integral_le_sum (hf : AntitoneOn f (Icc x₀ (x₀ + a))) : - (∫ x in x₀..x₀ + a, f x) ≤ ∑ i ∈ Finset.range a, f (x₀ + i) := by - have hint : ∀ k : ℕ, k < a → IntervalIntegrable f volume (x₀ + k) (x₀ + (k + 1 : ℕ)) := by - intro k hk - refine (hf.mono ?_).intervalIntegrable - rw [uIcc_of_le] - · apply Icc_subset_Icc - · simp only [le_add_iff_nonneg_right, Nat.cast_nonneg] - · simp only [add_le_add_iff_left, Nat.cast_le, Nat.succ_le_of_lt hk] - · simp only [add_le_add_iff_left, Nat.cast_le, Nat.le_succ] - calc - ∫ x in x₀..x₀ + a, f x = ∑ i ∈ Finset.range a, ∫ x in x₀ + i..x₀ + (i + 1 : ℕ), f x := by - convert! (intervalIntegral.sum_integral_adjacent_intervals hint).symm - simp only [Nat.cast_zero, add_zero] - _ ≤ ∑ i ∈ Finset.range a, ∫ _ in x₀ + i..x₀ + (i + 1 : ℕ), f (x₀ + i) := by - gcongr with i hi - have ia : i < a := Finset.mem_range.1 hi - refine intervalIntegral.integral_mono_on (by simp) (hint _ ia) (by simp) fun x hx => ?_ - apply hf _ _ hx.1 - · simp only [ia.le, mem_Icc, le_add_iff_nonneg_right, Nat.cast_nonneg, add_le_add_iff_left, - Nat.cast_le, and_self_iff] - · refine mem_Icc.2 ⟨le_trans (by simp) hx.1, le_trans hx.2 ?_⟩ - simp only [add_le_add_iff_left, Nat.cast_le, Nat.succ_le_of_lt ia] - _ = ∑ i ∈ Finset.range a, f (x₀ + i) := by simp + ∫ x in x₀..x₀ + a, f x ≤ ∑ i ∈ .range a, f (x₀ + i) := calc + _ = ∑ i ∈ .range a, ∫ x in x₀ + i..x₀ + ↑(i + 1), f x := by + convert! (sum_integral_adjacent_intervals hf.intervalIntegrable_subset).symm + simp + _ ≤ ∑ i ∈ .range a, ∫ _ in x₀ + i..x₀ + ↑(i + 1), f (x₀ + i) := by + gcongr with i hi + rw [Finset.mem_range, ← Nat.add_one_le_iff] at hi + have := hf.intervalIntegrable_subset _ hi + rify at hi this ⊢ + refine integral_mono_on (by simp) this (by simp) fun _ _ ↦ by apply hf <;> grind + _ = _ := by simp theorem AntitoneOn.integral_le_sum_Ico (hab : a ≤ b) (hf : AntitoneOn f (Set.Icc a b)) : - (∫ x in a..b, f x) ≤ ∑ x ∈ Finset.Ico a b, f x := by - rw [(Nat.sub_add_cancel hab).symm, Nat.cast_add] - conv => - congr - congr - · skip - · skip - rw [add_comm] - · skip - · skip - congr - congr - rw [← zero_add a] + ∫ x in a..b, f x ≤ ∑ x ∈ .Ico a b, f x := by + suffices ∫ x in a..a + ↑(b - a), f x ≤ ∑ x ∈ .Ico (0 + a) (b - a + a), f x by simp_all rw [← Finset.sum_Ico_add, Nat.Ico_zero_eq_range] - conv => - rhs - congr - · skip - ext - rw [Nat.cast_add] - apply AntitoneOn.integral_le_sum - simp only [hf, hab, Nat.cast_sub, add_sub_cancel] + suffices ∫ x in a..a + ↑(b - a), f x ≤ ∑ x ∈ .range (b - a), f (a + x) by simp_all + exact AntitoneOn.integral_le_sum (by simp only [hf, hab, Nat.cast_sub, add_sub_cancel]) theorem AntitoneOn.sum_le_integral (hf : AntitoneOn f (Icc x₀ (x₀ + a))) : - (∑ i ∈ Finset.range a, f (x₀ + (i + 1 : ℕ))) ≤ ∫ x in x₀..x₀ + a, f x := by - have hint : ∀ k : ℕ, k < a → IntervalIntegrable f volume (x₀ + k) (x₀ + (k + 1 : ℕ)) := by - intro k hk - refine (hf.mono ?_).intervalIntegrable - rw [uIcc_of_le] - · apply Icc_subset_Icc - · simp only [le_add_iff_nonneg_right, Nat.cast_nonneg] - · simp only [add_le_add_iff_left, Nat.cast_le, Nat.succ_le_of_lt hk] - · simp only [add_le_add_iff_left, Nat.cast_le, Nat.le_succ] - calc - (∑ i ∈ Finset.range a, f (x₀ + (i + 1 : ℕ))) = - ∑ i ∈ Finset.range a, ∫ _ in x₀ + i..x₀ + (i + 1 : ℕ), f (x₀ + (i + 1 : ℕ)) := by simp - _ ≤ ∑ i ∈ Finset.range a, ∫ x in x₀ + i..x₀ + (i + 1 : ℕ), f x := by - apply Finset.sum_le_sum fun i hi => ?_ - have ia : i + 1 ≤ a := Finset.mem_range.1 hi - refine intervalIntegral.integral_mono_on (by simp) (by simp) (hint _ ia) fun x hx => ?_ - apply hf _ _ hx.2 - · refine mem_Icc.2 ⟨le_trans (le_add_of_nonneg_right (Nat.cast_nonneg _)) hx.1, - le_trans hx.2 ?_⟩ - simp only [Nat.cast_le, add_le_add_iff_left, ia] - · refine mem_Icc.2 ⟨le_add_of_nonneg_right (Nat.cast_nonneg _), ?_⟩ - simp only [add_le_add_iff_left, Nat.cast_le, ia] - _ = ∫ x in x₀..x₀ + a, f x := by - convert! intervalIntegral.sum_integral_adjacent_intervals hint - simp only [Nat.cast_zero, add_zero] - -theorem AntitoneOn.sum_le_integral_Ico (hab : a ≤ b) (hf : AntitoneOn f (Set.Icc a b)) : - (∑ i ∈ Finset.Ico a b, f (i + 1 : ℕ)) ≤ ∫ x in a..b, f x := by - rw [(Nat.sub_add_cancel hab).symm, Nat.cast_add] - conv => - congr - congr - congr - rw [← zero_add a] - · skip - · skip - · skip - rw [add_comm] - rw [← Finset.sum_Ico_add, Nat.Ico_zero_eq_range] - conv => - lhs - congr - congr - · skip - ext - rw [add_assoc, Nat.cast_add] - apply AntitoneOn.sum_le_integral - simp only [hf, hab, Nat.cast_sub, add_sub_cancel] + ∑ i ∈ .range a, f (x₀ + ↑(i + 1)) ≤ ∫ x in x₀..x₀ + a, f x := calc + _ = ∑ i ∈ .range a, ∫ _ in x₀ + i..x₀ + ↑(i + 1), f (x₀ + ↑(i + 1)) := by simp + _ ≤ ∑ i ∈ .range a, ∫ x in x₀ + i..x₀ + ↑(i + 1), f x := by + gcongr with i hi + rw [Finset.mem_range, ← Nat.add_one_le_iff] at hi + have := hf.intervalIntegrable_subset _ hi + rify at hi this ⊢ + exact integral_mono_on (by simp) (by simp) this fun _ _ ↦ by apply hf <;> grind + _ = _ := by + convert! sum_integral_adjacent_intervals hf.intervalIntegrable_subset + simp [-Nat.cast_add] + +theorem AntitoneOn.sum_le_integral_Ico (hab : a ≤ b) (hf : AntitoneOn f (Icc a b)) : + ∑ i ∈ .Ico a b, f ↑(i + 1) ≤ ∫ x in a..b, f x := by + suffices ∑ i ∈ .Ico (0 + a) (b - a + a), f ↑(i + 1) ≤ ∫ x in a..a + ↑(b - a), f x by simp_all + simp_rw [← Finset.sum_Ico_add, Nat.Ico_zero_eq_range, add_assoc] + suffices ∑ x ∈ .range (b - a), f (a + ↑(x + 1)) ≤ ∫ x in a..a + ↑(b - a), f x by simp_all + exact AntitoneOn.sum_le_integral (by simp [hf, hab]) theorem MonotoneOn.sum_le_integral (hf : MonotoneOn f (Icc x₀ (x₀ + a))) : - (∑ i ∈ Finset.range a, f (x₀ + i)) ≤ ∫ x in x₀..x₀ + a, f x := by + ∑ i ∈ .range a, f (x₀ + i) ≤ ∫ x in x₀..x₀ + a, f x := by rw [← neg_le_neg_iff, ← Finset.sum_neg_distrib, ← intervalIntegral.integral_neg] exact hf.neg.integral_le_sum theorem MonotoneOn.sum_le_integral_Ico (hab : a ≤ b) (hf : MonotoneOn f (Set.Icc a b)) : - ∑ x ∈ Finset.Ico a b, f x ≤ ∫ x in a..b, f x := by + ∑ x ∈ .Ico a b, f x ≤ ∫ x in a..b, f x := by rw [← neg_le_neg_iff, ← Finset.sum_neg_distrib, ← intervalIntegral.integral_neg] exact hf.neg.integral_le_sum_Ico hab theorem MonotoneOn.integral_le_sum (hf : MonotoneOn f (Icc x₀ (x₀ + a))) : - (∫ x in x₀..x₀ + a, f x) ≤ ∑ i ∈ Finset.range a, f (x₀ + (i + 1 : ℕ)) := by + ∫ x in x₀..x₀ + a, f x ≤ ∑ i ∈ .range a, f (x₀ + ↑(i + 1)) := by rw [← neg_le_neg_iff, ← Finset.sum_neg_distrib, ← intervalIntegral.integral_neg] exact hf.neg.sum_le_integral theorem MonotoneOn.integral_le_sum_Ico (hab : a ≤ b) (hf : MonotoneOn f (Set.Icc a b)) : - (∫ x in a..b, f x) ≤ ∑ i ∈ Finset.Ico a b, f (i + 1 : ℕ) := by + ∫ x in a..b, f x ≤ ∑ i ∈ .Ico a b, f ↑(i + 1) := by rw [← neg_le_neg_iff, ← Finset.sum_neg_distrib, ← intervalIntegral.integral_neg] exact hf.neg.sum_le_integral_Ico hab lemma sum_mul_Ico_le_integral_of_monotone_antitone (hab : a ≤ b) (hf : MonotoneOn f (Icc a b)) (hg : AntitoneOn g (Icc (a - 1) (b - 1))) (fpos : 0 ≤ f a) (gpos : 0 ≤ g (b - 1)) : - ∑ i ∈ Finset.Ico a b, f i * g i ≤ ∫ x in a..b, f x * g (x - 1) := by + ∑ i ∈ .Ico a b, f i * g i ≤ ∫ x in a..b, f x * g (x - 1) := by apply sum_Ico_le_integral_of_le (f := fun x ↦ f x * g x) hab · intro i hi x hx - simp only [Nat.cast_add, Nat.cast_one, mem_Ico] at hx hi - have I0 : (i : ℝ) ≤ b - 1 := by - simp only [le_sub_iff_add_le] - norm_cast - lia - have I1 : (i : ℝ) ∈ Icc (a - 1 : ℝ) (b - 1) := by - simp only [mem_Icc, tsub_le_iff_right] - exact ⟨by norm_cast; lia, I0⟩ - have I2 : x ∈ Icc (a : ℝ) b := by - refine ⟨le_trans (mod_cast hi.1) hx.1, hx.2.le.trans ?_⟩ - norm_cast - lia - apply mul_le_mul - · apply hf - · simp only [mem_Icc, Nat.cast_le] - exact ⟨hi.1, hi.2.le⟩ - · exact I2 - · exact hx.1 - · apply hg - · simp only [mem_Icc, tsub_le_iff_right, sub_add_cancel] - refine ⟨le_trans (mod_cast hi.1) hx.1, hx.2.le.trans ?_⟩ - norm_cast - lia - · exact I1 - · simpa [sub_le_iff_le_add] using hx.2.le - · apply gpos.trans - apply hg I1 (by simp [hab]) I0 - · apply fpos.trans - apply hf (by simp [hab]) I2 - exact le_trans (mod_cast hi.1) hx.1 - · apply Integrable.mono_measure _ (Measure.restrict_mono_set _ Ico_subset_Icc_self) - apply Integrable.mul_of_top_left - · exact hf.integrableOn_isCompact isCompact_Icc - · apply AntitoneOn.memLp_isCompact isCompact_Icc - intro x hx y hy hxy - apply hg - · simpa using hx - · simpa using hy - · simpa using hxy + simp only [Nat.cast_add, Nat.cast_one, mem_Ico, ← Nat.add_one_le_iff] at hx hi + rify at hi + gcongr + · grw [gpos]; apply hg <;> grind + · grw [fpos]; apply hf <;> grind + · apply hf <;> grind + · apply hg <;> grind + · apply Integrable.mono_measure _ (volume.restrict_mono_set Ico_subset_Icc_self) + apply (hf.integrableOn_isCompact isCompact_Icc).mul_of_top_left + apply AntitoneOn.memLp_isCompact isCompact_Icc + intro _ _ _ _ _ + apply hg <;> grind lemma integral_le_sum_mul_Ico_of_antitone_monotone (hab : a ≤ b) (hf : AntitoneOn f (Icc a b)) (hg : MonotoneOn g (Icc (a - 1) (b - 1))) (fpos : 0 ≤ f b) (gpos : 0 ≤ g (a - 1)) : - ∫ x in a..b, f x * g (x - 1) ≤ ∑ i ∈ Finset.Ico a b, f i * g i := by + ∫ x in a..b, f x * g (x - 1) ≤ ∑ i ∈ .Ico a b, f i * g i := by apply integral_le_sum_Ico_of_le (f := fun x ↦ f x * g x) hab · intro i hi x hx - simp only [Nat.cast_add, Nat.cast_one, mem_Ico] at hx hi - have I0 : (i : ℝ) ≤ b - 1 := by - simp only [le_sub_iff_add_le] - norm_cast - lia - have I1 : (i : ℝ) ∈ Icc (a - 1 : ℝ) (b - 1) := by - simp only [mem_Icc, tsub_le_iff_right] - exact ⟨by norm_cast; lia, I0⟩ - have I2 : x ∈ Icc (a : ℝ) b := by - refine ⟨le_trans (mod_cast hi.1) hx.1, hx.2.le.trans ?_⟩ - norm_cast - lia - apply mul_le_mul - · apply hf - · simp only [mem_Icc, Nat.cast_le] - exact ⟨hi.1, hi.2.le⟩ - · exact I2 - · exact hx.1 - · apply hg - · simp only [mem_Icc, tsub_le_iff_right, sub_add_cancel] - refine ⟨le_trans (mod_cast hi.1) hx.1, hx.2.le.trans ?_⟩ - norm_cast - lia - · exact I1 - · simpa [sub_le_iff_le_add] using hx.2.le - · apply gpos.trans - apply hg (by simp [hab]) (by simpa using I2) (by simpa using I2.1) - · apply fpos.trans - apply hf ⟨mod_cast hi.1, mod_cast hi.2.le⟩ (by simpa using hab) (mod_cast hi.2.le) - · apply Integrable.mono_measure _ (Measure.restrict_mono_set _ Ico_subset_Icc_self) - apply Integrable.mul_of_top_left - · exact hf.integrableOn_isCompact isCompact_Icc - · apply MonotoneOn.memLp_isCompact isCompact_Icc - intro x hx y hy hxy - apply hg - · simpa using hx - · simpa using hy - · simpa using hxy + simp only [Nat.cast_add, Nat.cast_one, mem_Ico, ← Nat.add_one_le_iff] at hx hi + rify at hi + gcongr + · grw [gpos]; apply hg <;> grind + · grw [fpos]; apply hf <;> grind + · apply hf <;> grind + · apply hg <;> grind + · apply Integrable.mono_measure _ (volume.restrict_mono_set Ico_subset_Icc_self) + apply (hf.integrableOn_isCompact isCompact_Icc).mul_of_top_left + apply MonotoneOn.memLp_isCompact isCompact_Icc + intro _ _ _ _ _ + apply hg <;> grind From 9d11f4f019262236efcde4231f455265d2021f05 Mon Sep 17 00:00:00 2001 From: Pan Lin <58059503+HugLycan@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:42:38 +0000 Subject: [PATCH 0119/1300] feat(Tactic/Positivity): make positivity work for types that are not partial orders (#35394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make positivity work for types that are not partial orders Most PositivityExt haven't been updated for non partial order cases yet. They will be updated in the later PR. `Strictness` now depends on `Option Q(PartialOrder $α)` instead of `Q(PartialOrder $α)`, and the constructors `Strictness.positive`/`Strictness.nonnegative` now have their `Q(PartialOrder $α)` typeclass arguments. Co-authored-by: Floris van Doorn --- .../Algebra/Order/AbsoluteValue/Basic.lean | 3 +- Mathlib/Algebra/Order/Algebra.lean | 6 +- .../Algebra/Order/BigOperators/Expect.lean | 3 +- .../Order/BigOperators/Ring/Finset.lean | 3 +- Mathlib/Algebra/Order/Field/Basic.lean | 39 +- Mathlib/Algebra/Order/Field/Power.lean | 14 +- Mathlib/Algebra/Order/Floor/Extended.lean | 6 +- Mathlib/Algebra/Order/Floor/Ring.lean | 15 +- Mathlib/Algebra/Order/Interval/Basic.lean | 6 +- Mathlib/Algebra/Order/Module/Field.lean | 3 +- Mathlib/Analysis/Complex/Exponential.lean | 3 +- Mathlib/Analysis/Complex/Order.lean | 13 +- Mathlib/Analysis/Complex/Trigonometric.lean | 3 +- .../Complex/UpperHalfPlane/Basic.lean | 6 +- Mathlib/Analysis/Normed/Group/Basic.lean | 6 +- Mathlib/Analysis/Real/Sqrt.lean | 10 +- .../Analysis/SpecialFunctions/Bernstein.lean | 3 +- .../SpecialFunctions/Gamma/Basic.lean | 5 +- .../Analysis/SpecialFunctions/Log/Basic.lean | 9 +- .../Analysis/SpecialFunctions/Pow/NNReal.lean | 28 +- .../Analysis/SpecialFunctions/Pow/Real.lean | 12 +- .../Trigonometric/Arctan.lean | 29 +- .../SpecialFunctions/Trigonometric/Basic.lean | 3 +- .../Trigonometric/DerivHyp.lean | 3 +- .../Combinatorics/Enumerative/DyckWord.lean | 5 +- .../SimpleGraph/Regularity/Bound.lean | 6 +- .../SimpleGraph/Triangle/Removal.lean | 5 +- Mathlib/Data/ENNReal/Basic.lean | 8 +- Mathlib/Data/ENNReal/Real.lean | 5 +- Mathlib/Data/EReal/Basic.lean | 20 +- Mathlib/Data/EReal/Inv.lean | 6 +- Mathlib/Data/EReal/Operations.lean | 6 +- Mathlib/Data/NNReal/Defs.lean | 15 +- .../Data/Nat/Factorial/DoubleFactorial.lean | 3 +- Mathlib/Data/Nat/Totient.lean | 5 +- Mathlib/Data/Rat/Cast/Order.lean | 12 +- Mathlib/Geometry/Euclidean/Altitude.lean | 3 +- .../MeasureTheory/Covering/Besicovitch.lean | 3 +- .../MeasureTheory/Integral/Bochner/Basic.lean | 3 +- Mathlib/MeasureTheory/Measure/Real.lean | 3 +- .../NumberTheory/ArithmeticFunction/Misc.lean | 5 +- .../NumberTheory/ArithmeticFunction/Zeta.lean | 5 +- Mathlib/NumberTheory/Height/Basic.lean | 12 +- Mathlib/NumberTheory/Height/NumberField.lean | 3 +- .../NumberTheory/Height/Projectivization.lean | 6 +- Mathlib/NumberTheory/LucasLehmer.lean | 5 +- Mathlib/NumberTheory/SelbergSieve.lean | 3 +- Mathlib/Tactic/Positivity/Basic.lean | 376 +++++++++++------- Mathlib/Tactic/Positivity/Core.lean | 162 +++++--- Mathlib/Tactic/Positivity/Finset.lean | 14 +- .../Topology/Algebra/InfiniteSum/Order.lean | 3 +- Mathlib/Topology/MetricSpace/Bounded.lean | 3 +- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 3 +- MathlibTest/positivity.lean | 27 ++ 54 files changed, 612 insertions(+), 354 deletions(-) diff --git a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean index 6e11dcc3275e68..2438aca9fe70bd 100644 --- a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean +++ b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean @@ -416,7 +416,8 @@ open Lean Meta Mathlib Meta Positivity Qq in For performance reasons, we only attempt to apply this when `abv` is a variable. If it is an explicit function, e.g. `|_|` or `‖_‖`, another extension should apply. -/ @[positivity _] -meta def Mathlib.Meta.Positivity.evalAbv : PositivityExt where eval {_ _α} _zα _pα e := do +meta def Mathlib.Meta.Positivity.evalAbv : PositivityExt where eval {_ _α} _zα pα? e := do + let some _ := pα? | pure .none let (.app f a) ← whnfR e | throwError "not abv ·" if !f.getAppFn.isFVar then throwError "abv: function is not a variable" diff --git a/Mathlib/Algebra/Order/Algebra.lean b/Mathlib/Algebra/Order/Algebra.lean index b2c00ad489a471..c5a1cbd199b481 100644 --- a/Mathlib/Algebra/Order/Algebra.lean +++ b/Mathlib/Algebra/Order/Algebra.lean @@ -95,11 +95,12 @@ open Lean Meta Qq Function /-- Extension for `algebraMap`. -/ @[positivity algebraMap _ _ _] -meta def evalAlgebraMap : PositivityExt where eval {u β} _zβ _pβ e := do +meta def evalAlgebraMap : PositivityExt where eval {u β} _zβ pβ? e := do let ~q(@algebraMap $α _ $instα $instβ $instαβ $a) := e | throwError "not `algebraMap`" - let pα ← synthInstanceQ q(PartialOrder $α) + let pα ← try? <| synthInstanceQ q(PartialOrder $α) match ← core q(inferInstance) pα a with | .positive pa => + let some _ := pβ? | pure .none let _instαSemiring ← synthInstanceQ q(Semiring $α) let _instαPartialOrder ← synthInstanceQ q(PartialOrder $α) try @@ -117,6 +118,7 @@ meta def evalAlgebraMap : PositivityExt where eval {u β} _zβ _pβ e := do assertInstancesCommute return .nonnegative q(algebraMap_nonneg $β <| le_of_lt $pa) | .nonnegative pa => + let some _ := pβ? | pure .none let _instαSemiring ← synthInstanceQ q(CommSemiring $α) let _instαPartialOrder ← synthInstanceQ q(PartialOrder $α) let _instβSemiring ← synthInstanceQ q(Semiring $β) diff --git a/Mathlib/Algebra/Order/BigOperators/Expect.lean b/Mathlib/Algebra/Order/BigOperators/Expect.lean index 8f77dc667d84d0..2f7e1bf8a89631 100644 --- a/Mathlib/Algebra/Order/BigOperators/Expect.lean +++ b/Mathlib/Algebra/Order/BigOperators/Expect.lean @@ -220,7 +220,8 @@ open scoped BigOperators attribute [local instance] monadLiftOptionMetaM in /-- Positivity extension for `Finset.expect`. -/ @[positivity Finset.expect _ _] -meta def evalFinsetExpect : PositivityExt where eval {u α} zα pα e := do +meta def evalFinsetExpect : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match e with | ~q(@Finset.expect $ι _ $instα $instmod $s $f) => let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque diff --git a/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean b/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean index b4ccd4aed08988..f4b2836ef9c166 100644 --- a/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean @@ -225,9 +225,10 @@ example (s : Finset ℕ) (f : ℕ → ℤ) (hf : ∀ n, 0 ≤ f n) : 0 ≤ s.pro because `compareHyp` can't look for assumptions behind binders. -/ @[positivity Finset.prod _ _] -meta def evalFinsetProd : PositivityExt where eval {u α} zα pα e := do +meta def evalFinsetProd : PositivityExt where eval {u α} zα pα? e := do match e with | ~q(@Finset.prod $ι _ $instα $s $f) => + let some pα := pα? | pure .none let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque have body : Q($α) := Expr.betaRev f #[i] let rbody ← core zα pα body diff --git a/Mathlib/Algebra/Order/Field/Basic.lean b/Mathlib/Algebra/Order/Field/Basic.lean index aadae9becada01..6db675d49c48a0 100644 --- a/Mathlib/Algebra/Order/Field/Basic.lean +++ b/Mathlib/Algebra/Order/Field/Basic.lean @@ -733,15 +733,23 @@ lemma zpow_zero_pos {α : Type*} [Semifield α] [PartialOrder α] [IsStrictOrder /-- The `positivity` extension which identifies expressions of the form `a / b`, such that `positivity` successfully recognises both `a` and `b`. -/ -@[positivity _ / _] meta def evalDiv : PositivityExt where eval {u α} zα pα e := do +@[positivity _ / _] meta def evalDiv : PositivityExt where eval {u α} zα pα? e := do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← withReducible (whnf e) | throwError "not /" let _e_eq : $e =Q $f $a $b := ⟨⟩ + trace[Tactic.positivity.zeroness] "evalDiv: {a} divided by {b}" + let _a ← synthInstanceQ q(Semifield $α) + let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HDiv.hDiv) + let some pα := pα? | + match ← core zα pα? a, ← core zα pα? b with + | .nonzero pa, .nonzero pb => + let _a ← synthInstanceQ q(GroupWithZero $α) + assumeInstancesCommute + pure (.nonzero q(div_ne_zero $pa $pb)) + | _, _ => pure .none let _a ← synthInstanceQ q(GroupWithZero $α) - let _a ← synthInstanceQ q(PartialOrder $α) let _a ← synthInstanceQ q(PosMulReflectLT $α) assumeInstancesCommute - let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HDiv.hDiv) let ra ← core zα pα a; let rb ← core zα pα b match ra, rb with | .positive pa, .positive pb => pure (.positive q(div_pos $pa $pb)) @@ -756,25 +764,38 @@ such that `positivity` successfully recognises both `a` and `b`. -/ /-- The `positivity` extension which identifies expressions of the form `a⁻¹`, such that `positivity` successfully recognises `a`. -/ @[positivity _⁻¹] -meta def evalInv : PositivityExt where eval {u α} zα pα e := do +meta def evalInv : PositivityExt where eval {u α} zα pα? e := do let .app (f : Q($α → $α)) (a : Q($α)) ← withReducible (whnf e) | throwError "not ⁻¹" let _e_eq : $e =Q $f $a := ⟨⟩ + let _a ← synthInstanceQ q(Semifield $α) + let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(Inv.inv) + let some _ := pα? | + match ← core zα pα? a with + | .nonzero pa => + let _a ← synthInstanceQ q(GroupWithZero $α) + assumeInstancesCommute + pure (.nonzero q(inv_ne_zero $pa)) + | _ => pure .none let _a ← synthInstanceQ q(GroupWithZero $α) let _a ← synthInstanceQ q(PartialOrder $α) let _a ← synthInstanceQ q(PosMulReflectLT $α) assumeInstancesCommute - let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(Inv.inv) - let ra ← core zα pα a + let ra ← core zα pα? a match ra with - | .positive pa => pure (.positive q(inv_pos_of_pos $pa)) - | .nonnegative pa => pure (.nonnegative q(inv_nonneg_of_nonneg $pa)) + | .positive pa => + assumeInstancesCommute + pure (.positive q(inv_pos_of_pos $pa)) + | .nonnegative pa => + assumeInstancesCommute + pure (.nonnegative q(inv_nonneg_of_nonneg $pa)) | .nonzero pa => pure (.nonzero q(inv_ne_zero $pa)) | .none => pure .none /-- The `positivity` extension which identifies expressions of the form `a ^ (0:ℤ)`. -/ @[positivity _ ^ (0 : ℤ), Pow.pow _ (0 : ℤ)] -meta def evalPowZeroInt : PositivityExt where eval {u α} _zα _pα e := do +meta def evalPowZeroInt : PositivityExt where eval {u α} _zα pα? e := do let .app (.app _ (a : Q($α))) _ ← withReducible (whnf e) | throwError "not ^" + let some _ := pα? | pure .none let _a ← synthInstanceQ q(Semifield $α) let _a ← synthInstanceQ q(LinearOrder $α) let _a ← synthInstanceQ q(IsStrictOrderedRing $α) diff --git a/Mathlib/Algebra/Order/Field/Power.lean b/Mathlib/Algebra/Order/Field/Power.lean index 8f888e8a9c5c2a..921d4a96f7f17f 100644 --- a/Mathlib/Algebra/Order/Field/Power.lean +++ b/Mathlib/Algebra/Order/Field/Power.lean @@ -123,8 +123,16 @@ open Lean Meta Qq /-- The `positivity` extension which identifies expressions of the form `a ^ (b : ℤ)`, such that `positivity` successfully recognises both `a` and `b`. -/ @[positivity _ ^ (_ : ℤ), Pow.pow _ (_ : ℤ)] -meta def evalZPow : PositivityExt where eval {u α} zα pα e := do +meta def evalZPow : PositivityExt where eval {u α} zα pα? e := do let .app (.app _ (a : Q($α))) (b : Q(ℤ)) ← withReducible (whnf e) | throwError "not ^" + let some pα := pα? | + match ← core zα pα? a with + | .nonzero pa => + let _a ← synthInstanceQ q(GroupWithZero $α) + assumeInstancesCommute + haveI' : $e =Q $a ^ $b := ⟨⟩ + pure (.nonzero q(zpow_ne_zero $b $pa)) + | _ => pure .none let result ← catchNone do let _a ← synthInstanceQ q(Field $α) let _a ← synthInstanceQ q(LinearOrder $α) @@ -151,11 +159,11 @@ meta def evalZPow : PositivityExt where eval {u α} zα pα e := do let ra ← core zα pα a let ofNonneg (pa : Q(0 ≤ $a)) (_oα : Q(Semifield $α)) (_oα : Q(LinearOrder $α)) (_oα : Q(IsStrictOrderedRing $α)) : - MetaM (Strictness zα pα e) := do + MetaM (Strictness zα e pα) := do haveI' : $e =Q $a ^ $b := ⟨⟩ assumeInstancesCommute pure (.nonnegative q(zpow_nonneg $pa $b)) - let ofNonzero (pa : Q($a ≠ 0)) (_oα : Q(GroupWithZero $α)) : MetaM (Strictness zα pα e) := do + let ofNonzero (pa : Q($a ≠ 0)) (_oα : Q(GroupWithZero $α)) : MetaM (Strictness zα e pα) := do haveI' : $e =Q $a ^ $b := ⟨⟩ let _a ← synthInstanceQ q(GroupWithZero $α) assumeInstancesCommute diff --git a/Mathlib/Algebra/Order/Floor/Extended.lean b/Mathlib/Algebra/Order/Floor/Extended.lean index e1f38ba80964d0..3708cc1a32b067 100644 --- a/Mathlib/Algebra/Order/Floor/Extended.lean +++ b/Mathlib/Algebra/Order/Floor/Extended.lean @@ -256,11 +256,11 @@ alias ⟨_, natCeil_pos⟩ := ENat.ceil_pos /-- Extension for the `positivity` tactic: `ENat.ceil` is positive if its input is. -/ @[positivity ⌈_⌉ₑ] -meta def evalENatCeil : PositivityExt where eval {u α} _zα _pα e := do +meta def evalENatCeil : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℕ∞), ~q(ENat.ceil $r) => - assertInstancesCommute - match ← core q(inferInstance) q(inferInstance) r with + let some _ := pα? | pure .none + match ← core q(inferInstance) (some q(inferInstance)) r with | .positive pr => assertInstancesCommute pure (.positive q(natCeil_pos $pr)) diff --git a/Mathlib/Algebra/Order/Floor/Ring.lean b/Mathlib/Algebra/Order/Floor/Ring.lean index 79a3481beeae1e..3537d313859ee3 100644 --- a/Mathlib/Algebra/Order/Floor/Ring.lean +++ b/Mathlib/Algebra/Order/Floor/Ring.lean @@ -50,10 +50,11 @@ theorem int_floor_nonneg_of_pos [Ring α] [LinearOrder α] [FloorRing α] {a : /-- Extension for the `positivity` tactic: `Int.floor` is nonnegative if its input is. -/ @[positivity ⌊_⌋] -meta def evalIntFloor : PositivityExt where eval {u α} _zα _pα e := do +meta def evalIntFloor : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℤ), ~q(@Int.floor $α' $ir $io $j $a) => - match ← core q(inferInstance) q(inferInstance) a with + let some _ := pα? | pure .none + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute pure (.nonnegative q(int_floor_nonneg_of_pos (α := $α') $pa)) @@ -69,13 +70,14 @@ theorem nat_ceil_pos [Semiring α] [LinearOrder α] [FloorSemiring α] {a : α} /-- Extension for the `positivity` tactic: `Nat.ceil` is positive if its input is. -/ @[positivity ⌈_⌉₊] -meta def evalNatCeil : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNatCeil : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℕ), ~q(@Nat.ceil $α' $ir $io $j $a) => + let some _ := pα? | pure .none let _i ← synthInstanceQ q(LinearOrder $α') let _i ← synthInstanceQ q(IsStrictOrderedRing $α') assertInstancesCommute - match ← core q(inferInstance) q(inferInstance) a with + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute pure (.positive q(nat_ceil_pos (α := $α') $pa)) @@ -87,10 +89,11 @@ theorem int_ceil_pos [Ring α] [LinearOrder α] [FloorRing α] {a : α} : 0 < a /-- Extension for the `positivity` tactic: `Int.ceil` is positive/nonnegative if its input is. -/ @[positivity ⌈_⌉] -meta def evalIntCeil : PositivityExt where eval {u α} _zα _pα e := do +meta def evalIntCeil : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℤ), ~q(@Int.ceil $α' $ir $io $j $a) => - match ← core q(inferInstance) q(inferInstance) a with + let some _ := pα? | pure .none + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute pure (.positive q(int_ceil_pos (α := $α') $pa)) diff --git a/Mathlib/Algebra/Order/Interval/Basic.lean b/Mathlib/Algebra/Order/Interval/Basic.lean index 714243ac6829cd..620b79a1c6fa82 100644 --- a/Mathlib/Algebra/Order/Interval/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Basic.lean @@ -660,9 +660,10 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/ @[positivity NonemptyInterval.length _] meta def evalNonemptyIntervalLength : PositivityExt where - eval {u α} _ _ e := do + eval {u α} _ pα? e := do let ~q(@NonemptyInterval.length _ $ig $ipo $a) := e | throwError "not NonemptyInterval.length" + let some _ := pα? | pure .none let _i ← synthInstanceQ q(IsOrderedAddMonoid $α) assertInstancesCommute return .nonnegative q(NonemptyInterval.length_nonneg $a) @@ -670,8 +671,9 @@ meta def evalNonemptyIntervalLength : PositivityExt where /-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/ @[positivity Interval.length _] meta def evalIntervalLength : PositivityExt where - eval {u α} _ _ e := do + eval {u α} _ pα? e := do let ~q(@Interval.length _ $ig $ipo $a) := e | throwError "not Interval.length" + let some _ := pα? | pure .none let _i ← synthInstanceQ q(IsOrderedAddMonoid $α) assumeInstancesCommute return .nonnegative q(Interval.length_nonneg $a) diff --git a/Mathlib/Algebra/Order/Module/Field.lean b/Mathlib/Algebra/Order/Module/Field.lean index 9e248fcace8a25..f1575550df9058 100644 --- a/Mathlib/Algebra/Order/Module/Field.lean +++ b/Mathlib/Algebra/Order/Module/Field.lean @@ -103,7 +103,8 @@ end Module.IsTorsionFree /-- Positivity extension for scalar multiplication. -/ @[positivity HSMul.hSMul _ _] -meta def evalSMul : PositivityExt where eval {_u α} zα pα (e : Q($α)) := do +meta def evalSMul : PositivityExt where eval {_u α} zα pα? (e : Q($α)) := do + let some pα := pα? | pure .none let .app (.app (.app (.app (.app (.app (.const ``HSMul.hSMul [u1, _, _]) (β : Q(Type u1))) _) _) _) (a : Q($β))) (b : Q($α)) ← whnfR e | throwError "failed to match hSMul" diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index 58e394719d257c..9a51b9898ee788 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -692,9 +692,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `Real.exp` is always positive. -/ @[positivity Real.exp _] -meta def evalExp : PositivityExt where eval {u α} _ _ e := do +meta def evalExp : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.exp $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(Real.exp_pos $a)) | _, _, _ => throwError "not Real.exp" diff --git a/Mathlib/Analysis/Complex/Order.lean b/Mathlib/Analysis/Complex/Order.lean index 179d46a06f6aba..03bf6ffb6cb7fa 100644 --- a/Mathlib/Analysis/Complex/Order.lean +++ b/Mathlib/Analysis/Complex/Order.lean @@ -142,19 +142,12 @@ alias ⟨_, ofReal_ne_zero_of_ne_zero⟩ := ofReal_ne_zero /-- Extension for the `positivity` tactic: `Complex.ofReal` is positive/nonnegative/nonzero if its input is. -/ @[positivity Complex.ofReal _, Complex.ofReal _] -meta def evalComplexOfReal : PositivityExt where eval {u α} _ _ e := do - -- TODO: Can we avoid duplicating the code? +meta def evalComplexOfReal : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℂ), ~q(Complex.ofReal $a) => + let some _ := pα? | pure .none assumeInstancesCommute - match ← core q(inferInstance) q(inferInstance) a with - | .positive pa => return .positive q(ofReal_pos $pa) - | .nonnegative pa => return .nonnegative q(ofReal_nonneg $pa) - | .nonzero pa => return .nonzero q(ofReal_ne_zero_of_ne_zero $pa) - | _ => return .none - | 0, ~q(ℂ), ~q(Complex.ofReal $a) => - assumeInstancesCommute - match ← core q(inferInstance) q(inferInstance) a with + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => return .positive q(ofReal_pos $pa) | .nonnegative pa => return .nonnegative q(ofReal_nonneg $pa) | .nonzero pa => return .nonzero q(ofReal_ne_zero_of_ne_zero $pa) diff --git a/Mathlib/Analysis/Complex/Trigonometric.lean b/Mathlib/Analysis/Complex/Trigonometric.lean index b00c1f90b5c481..44d62339fd1e11 100644 --- a/Mathlib/Analysis/Complex/Trigonometric.lean +++ b/Mathlib/Analysis/Complex/Trigonometric.lean @@ -940,9 +940,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `Real.cosh` is always positive. -/ @[positivity Real.cosh _] -meta def evalCosh : PositivityExt where eval {u α} _ _ e := do +meta def evalCosh : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.cosh $a) => + let some _ := pα? | pure .none assertInstancesCommute return .positive q(Real.cosh_pos $a) | _, _, _ => throwError "not Real.cosh" diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 512ba2046a568b..1ce4914b6dffdb 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -148,18 +148,20 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `UpperHalfPlane.im`. -/ @[positivity UpperHalfPlane.im _] -meta def evalUpperHalfPlaneIm : PositivityExt where eval {u α} _zα _pα e := do +meta def evalUpperHalfPlaneIm : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(UpperHalfPlane.im $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(@UpperHalfPlane.im_pos $a)) | _, _, _ => throwError "not UpperHalfPlane.im" /-- Extension for the `positivity` tactic: `UpperHalfPlane.coe`. -/ @[positivity UpperHalfPlane.coe _] -meta def evalUpperHalfPlaneCoe : PositivityExt where eval {u α} _zα _pα e := do +meta def evalUpperHalfPlaneCoe : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℂ), ~q(UpperHalfPlane.coe $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonzero q(@UpperHalfPlane.ne_zero $a)) | _, _, _ => throwError "not UpperHalfPlane.coe" diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index 941ebb349425b5..e9a4d77951abf4 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -1069,9 +1069,10 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: multiplicative norms are always nonnegative, and positive on non-one inputs. -/ @[positivity ‖_‖] -meta def evalMulNorm : PositivityExt where eval {u α} _ _ e := do +meta def evalMulNorm : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@Norm.norm $E $_n $a) => + let some _ := pα? | pure .none let _seminormedGroup_E ← synthInstanceQ q(SeminormedGroup $E) assertInstancesCommute -- Check whether we are in a normed group and whether the context contains a `a ≠ 1` assumption @@ -1091,9 +1092,10 @@ meta def evalMulNorm : PositivityExt where eval {u α} _ _ e := do /-- Extension for the `positivity` tactic: additive norms are always nonnegative, and positive on non-zero inputs. -/ @[positivity ‖_‖] -meta def evalAddNorm : PositivityExt where eval {u α} _ _ e := do +meta def evalAddNorm : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@Norm.norm $E $_n $a) => + let some _ := pα? | pure .none let _seminormedAddGroup_E ← synthInstanceQ q(SeminormedAddGroup $E) assertInstancesCommute -- Check whether we are in a normed group and whether the context contains a `a ≠ 0` assumption diff --git a/Mathlib/Analysis/Real/Sqrt.lean b/Mathlib/Analysis/Real/Sqrt.lean index 1d7361a4aaa405..bb2d0f3c36425a 100644 --- a/Mathlib/Analysis/Real/Sqrt.lean +++ b/Mathlib/Analysis/Real/Sqrt.lean @@ -312,11 +312,12 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: a square root of a strictly positive nonnegative real is positive. -/ @[positivity NNReal.sqrt _] -meta def evalNNRealSqrt : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNNRealSqrt : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(NNReal), ~q(NNReal.sqrt $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(NNReal.sqrt_pos_of_pos $pa)) | _ => failure -- this case is dealt with by generic nonnegativity of nnreals @@ -325,11 +326,12 @@ meta def evalNNRealSqrt : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for the `positivity` tactic: a square root is nonnegative, and is strictly positive if its input is. -/ @[positivity √_] -meta def evalSqrt : PositivityExt where eval {u α} _zα _pα e := do +meta def evalSqrt : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ), ~q(√$a) => - let ra ← catchNone <| core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← catchNone <| core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(Real.sqrt_pos_of_pos $pa)) | _ => pure (.nonnegative q(Real.sqrt_nonneg $a)) diff --git a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean index db4e9c639de726..2e650b4aa8f761 100644 --- a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean +++ b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean @@ -80,8 +80,9 @@ open Lean Meta Qq Function /-- Extension of the `positivity` tactic for Bernstein polynomials: they are always non-negative. -/ @[positivity DFunLike.coe (bernstein _ _) _] -meta def evalBernstein : PositivityExt where eval {_ _} _zα _pα e := do +meta def evalBernstein : PositivityExt where eval {_ _} _zα pα? e := do let .app (.app _coe (.app (.app _ n) ν)) x ← whnfR e | throwError "not bernstein polynomial" + let some _ := pα? | pure .none let p ← mkAppOptM ``bernstein_nonneg #[n, ν, x] pure (.nonnegative p) diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index d9657e4d690184..16c34c92f0cf0a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -472,10 +472,11 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) : open Lean.Meta Qq Mathlib.Meta.Positivity in /-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/ @[positivity Gamma (_ : ℝ)] -meta def _root_.Mathlib.Meta.Positivity.evalGamma : PositivityExt where eval {u α} _zα _pα e := do +meta def _root_.Mathlib.Meta.Positivity.evalGamma : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Gamma $a) => - match ← core q(inferInstance) q(inferInstance) a with + let some _ := pα? | pure .none + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute pure (.positive q(Gamma_pos_of_pos $pa)) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index f64147755f1c5c..a50cc14b759129 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -596,27 +596,30 @@ lemma log_nz_of_isRat_neg {n : ℤ} : (NormNum.IsRat e n d) → (decide (n / d < /-- Extension for the `positivity` tactic: `Real.log` of a natural number is always nonnegative. -/ @[positivity Real.log (Nat.cast _)] -meta def evalLogNatCast : PositivityExt where eval {u α} _zα _pα e := do +meta def evalLogNatCast : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.log (Nat.cast $a)) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(Real.log_natCast_nonneg $a)) | _, _, _ => throwError "not Real.log" /-- Extension for the `positivity` tactic: `Real.log` of an integer is always nonnegative. -/ @[positivity Real.log (Int.cast _)] -meta def evalLogIntCast : PositivityExt where eval {u α} _zα _pα e := do +meta def evalLogIntCast : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.log (Int.cast $a)) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(Real.log_intCast_nonneg $a)) | _, _, _ => throwError "not Real.log" /-- Extension for the `positivity` tactic: `Real.log` of a numeric literal. -/ @[positivity Real.log _] -meta def evalLogNatLit : PositivityExt where eval {u α} _ _ e := do +meta def evalLogNatLit : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.log $a) => + let some _ := pα? | pure .none match ← NormNum.derive a with | .isNat (_ : Q(AddMonoidWithOne ℝ)) lit p => assumeInstancesCommute diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean b/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean index c76491e3102c03..ccde81c19c3eca 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean @@ -1125,18 +1125,20 @@ open Lean Meta Qq the base is nonnegative and positive when the base is positive. This is the `NNReal` analogue of `evalRpow` for `Real`. -/ @[positivity (_ : ℝ≥0) ^ (_ : ℝ)] -meta def evalNNRealRpow : PositivityExt where eval {u α} _ _ e := do +meta def evalNNRealRpow : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ≥0), ~q($a ^ (0 : ℝ)) => assertInstancesCommute pure (.positive q(NNReal.rpow_zero_pos $a)) | 0, ~q(ℝ≥0), ~q($a ^ ($b : ℝ)) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => - pure (.positive q(NNReal.rpow_pos $pa)) - | _ => pure (.nonnegative q(zero_le (a := $e))) + pure (.positive q(NNReal.rpow_pos $pa)) + | _ => + pure (.nonnegative q(zero_le (a := $e))) | _, _, _ => throwError "not NNReal.rpow" private meta def isFiniteM? (x : Q(ℝ≥0∞)) : MetaM (Option Q($x ≠ (⊤ : ℝ≥0∞))) := do @@ -1153,24 +1155,26 @@ private meta def isFiniteM? (x : Q(ℝ≥0∞)) : MetaM (Option Q($x ≠ (⊤ : the base is nonnegative and positive when the base is positive. This is the `ENNReal` analogue of `evalRpow` for `Real`. -/ @[positivity (_ : ℝ≥0∞) ^ (_ : ℝ)] -meta def evalENNRealRpow : PositivityExt where eval {u α} _ _ e := do +meta def evalENNRealRpow : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ≥0∞), ~q($a ^ (0 : ℝ)) => assertInstancesCommute pure (.positive q(ENNReal.rpow_zero_pos $a)) | 0, ~q(ℝ≥0∞), ~q($a ^ ($b : ℝ)) => - let ra ← core q(inferInstance) q(inferInstance) a - let rb ← catchNone <| core q(inferInstance) q(inferInstance) b assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a + let rb ← catchNone <| core q(inferInstance) (some q(inferInstance)) b match ra, rb with | .positive pa, .positive pb => - pure (.positive q(ENNReal.rpow_pos_of_nonneg $pa <| le_of_lt $pb)) + pure (.positive q(ENNReal.rpow_pos_of_nonneg $pa <| le_of_lt $pb)) | .positive pa, .nonnegative pb => - pure (.positive q(ENNReal.rpow_pos_of_nonneg $pa $pb)) + pure (.positive q(ENNReal.rpow_pos_of_nonneg $pa $pb)) | .positive pa, _ => - let some ha ← isFiniteM? a | pure <| .nonnegative q(zero_le (a := $e)) - pure <| .positive q(ENNReal.rpow_pos $pa $ha) - | _, _ => pure <| .nonnegative q(zero_le (a := $e)) + let some ha ← isFiniteM? a | pure <| .nonnegative q(zero_le (a := $e)) + pure <| .positive q(ENNReal.rpow_pos $pa $ha) + | _, _ => + pure <| .nonnegative q(zero_le (a := $e)) | _, _, _ => throwError "not ENNReal.rpow" end Mathlib.Meta.Positivity diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean index 526196e702c259..b220c5e0e31fdb 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean @@ -375,7 +375,8 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: exponentiation by a real number is positive (namely 1) when the exponent is zero. The other cases are done in `evalRpow`. -/ @[positivity (_ : ℝ) ^ (0 : ℝ)] -meta def evalRpowZero : PositivityExt where eval {u α} _ _ e := do +meta def evalRpowZero : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ), ~q($a ^ (0 : ℝ)) => assertInstancesCommute @@ -385,16 +386,17 @@ meta def evalRpowZero : PositivityExt where eval {u α} _ _ e := do /-- Extension for the `positivity` tactic: exponentiation by a real number is nonnegative when the base is nonnegative and positive when the base is positive. -/ @[positivity (_ : ℝ) ^ (_ : ℝ)] -meta def evalRpow : PositivityExt where eval {u α} _zα _pα e := do +meta def evalRpow : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ), ~q($a ^ ($b : ℝ)) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => - pure (.positive q(Real.rpow_pos_of_pos $pa $b)) + pure (.positive q(Real.rpow_pos_of_pos $pa $b)) | .nonnegative pa => - pure (.nonnegative q(Real.rpow_nonneg $pa $b)) + pure (.nonnegative q(Real.rpow_nonneg $pa $b)) | _ => pure .none | _, _, _ => throwError "not Real.rpow" diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean index 1a81fa75ea4bca..db73145896a607 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean @@ -403,19 +403,25 @@ meta def evalRealArctan : PositivityExt where eval {u α} z p e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.arctan $a) => let ra ← core z p a - assumeInstancesCommute match ra with - | .positive pa => return .positive q(Real.arctan_pos.mpr $pa) - | .nonnegative na => return .nonnegative q(Real.arctan_nonneg.mpr $na) - | .nonzero na => return .nonzero q(mt Real.arctan_eq_zero_iff.mp $na) + | .positive pa => + assumeInstancesCommute + return .positive q(Real.arctan_pos.mpr $pa) + | .nonnegative na => + assumeInstancesCommute + return .nonnegative q(Real.arctan_nonneg.mpr $na) + | .nonzero na => + assumeInstancesCommute + return .nonzero q(mt Real.arctan_eq_zero_iff.mp $na) | .none => return .none | _ => throwError "not Real.arctan" /-- Extension for `Real.cos (Real.arctan _)`. -/ @[positivity Real.cos (Real.arctan _)] -meta def evalRealCosArctan : PositivityExt where eval {u α} _ _ e := do +meta def evalRealCosArctan : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.cos (Real.arctan $a)) => + let some _ := pα? | pure .none assumeInstancesCommute return .positive q(Real.cos_arctan_pos _) | _ => throwError "not Real.cos (Real.arctan _)" @@ -425,11 +431,16 @@ meta def evalRealCosArctan : PositivityExt where eval {u α} _ _ e := do meta def evalRealSinArctan : PositivityExt where eval {u α} z p e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.sin (Real.arctan $a)) => - assumeInstancesCommute match ← core z p a with - | .positive pa => return .positive q(Real.sin_arctan_pos.mpr $pa) - | .nonnegative na => return .nonnegative q(Real.sin_arctan_nonneg.mpr $na) - | .nonzero na => return .nonzero q(mt Real.sin_arctan_eq_zero.mp $na) + | .positive pa => + assumeInstancesCommute + return .positive q(Real.sin_arctan_pos.mpr $pa) + | .nonnegative na => + assumeInstancesCommute + return .nonnegative q(Real.sin_arctan_nonneg.mpr $na) + | .nonzero na => + assumeInstancesCommute + return .nonzero q(mt Real.sin_arctan_eq_zero.mp $na) | .none => return .none | _ => throwError "not Real.sin (Real.arctan _)" diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean index f673be94a073fd..6d712d0f1aa57e 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean @@ -177,9 +177,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `π` is always positive. -/ @[positivity Real.pi] -meta def evalRealPi : PositivityExt where eval {u α} _zα _pα e := do +meta def evalRealPi : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(Real.pi) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(Real.pi_pos)) | _, _, _ => throwError "not Real.pi" diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean index 1735eed0bfc822..d4ae1114b1700b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean @@ -798,7 +798,8 @@ alias ⟨_, sinh_ne_zero_of_ne_zero⟩ := Real.sinh_ne_zero /-- Extension for the `positivity` tactic: `Real.sinh` is positive/nonnegative/nonzero if its input is. -/ @[positivity Real.sinh _] -meta def evalSinh : PositivityExt where eval {u α} _ _ e := do +meta def evalSinh : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | pure .none let zα : Q(Zero ℝ) := q(inferInstance) let pα : Q(PartialOrder ℝ) := q(inferInstance) match u, α, e with diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index 972ca6dccd153a..0dfcee6466b377 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -557,11 +557,12 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `p.firstReturn` is positive if `p` is nonzero. -/ @[positivity DyckWord.firstReturn _] -meta def evalDyckWordFirstReturn : PositivityExt where eval {u α} _zα _pα e := do +meta def evalDyckWordFirstReturn : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℕ), ~q(DyckWord.firstReturn $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(DyckWord.firstReturn_pos ($pa).ne')) | .nonzero pa => pure (.positive q(DyckWord.firstReturn_pos $pa)) diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean index 4298225b631b62..10020841234a53 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean @@ -239,9 +239,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `SzemerediRegularity.initialBound` is always positive. -/ @[positivity SzemerediRegularity.initialBound _ _] -meta def evalInitialBound : PositivityExt where eval {u α} _ _ e := do +meta def evalInitialBound : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℕ), ~q(SzemerediRegularity.initialBound $ε $l) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(SzemerediRegularity.initialBound_pos $ε $l)) | _, _, _ => throwError "not initialBound" @@ -251,9 +252,10 @@ example (ε : ℝ) (l : ℕ) : 0 < SzemerediRegularity.initialBound ε l := by p /-- Extension for the `positivity` tactic: `SzemerediRegularity.bound` is always positive. -/ @[positivity SzemerediRegularity.bound _ _] -meta def evalBound : PositivityExt where eval {u α} _ _ e := do +meta def evalBound : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℕ), ~q(SzemerediRegularity.bound $ε $l) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(SzemerediRegularity.bound_pos $ε $l)) | _, _, _ => throwError "not bound" diff --git a/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean b/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean index bdf4f169a854ea..2e4f7bb17a6c94 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean @@ -176,10 +176,11 @@ if `ε` is. This exploits the positivity of the junk value of `triangleRemovalBound ε` for `ε ≥ 1`. -/ @[positivity triangleRemovalBound _] -meta def evalTriangleRemovalBound : PositivityExt where eval {u α} _zα _pα e := do +meta def evalTriangleRemovalBound : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(triangleRemovalBound $ε) => - let .positive hε ← core q(inferInstance) q(inferInstance) ε | failure + let some _ := pα? | pure .none + let .positive hε ← core q(inferInstance) (some q(inferInstance)) ε | failure assertInstancesCommute pure (.positive q(triangleRemovalBound_pos $hε)) | _, _, _ => throwError "failed to match on Int.ceil application" diff --git a/Mathlib/Data/ENNReal/Basic.lean b/Mathlib/Data/ENNReal/Basic.lean index 40b42ed7d30639..3b71f90289ab75 100644 --- a/Mathlib/Data/ENNReal/Basic.lean +++ b/Mathlib/Data/ENNReal/Basic.lean @@ -741,7 +741,8 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `ENNReal.toReal`. -/ @[positivity ENNReal.toReal _] -meta def evalENNRealtoReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalENNRealtoReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ), ~q(ENNReal.toReal $a) => assertInstancesCommute @@ -750,11 +751,12 @@ meta def evalENNRealtoReal : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for the `positivity` tactic: `ENNReal.ofNNReal`. -/ @[positivity ENNReal.ofNNReal _] -meta def evalENNRealOfNNReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalENNRealOfNNReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ≥0∞), ~q(ENNReal.ofNNReal $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure <| .positive q(ENNReal.coe_pos.mpr $pa) | _ => pure .none diff --git a/Mathlib/Data/ENNReal/Real.lean b/Mathlib/Data/ENNReal/Real.lean index 4c818edb0ab5b4..6da5409e3594ec 100644 --- a/Mathlib/Data/ENNReal/Real.lean +++ b/Mathlib/Data/ENNReal/Real.lean @@ -392,11 +392,12 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `ENNReal.ofReal`. -/ @[positivity ENNReal.ofReal _] -meta def evalENNRealOfReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalENNRealOfReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ≥0∞), ~q(ENNReal.ofReal $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(Iff.mpr (@ENNReal.ofReal_pos $a) $pa)) | _ => pure .none diff --git a/Mathlib/Data/EReal/Basic.lean b/Mathlib/Data/EReal/Basic.lean index ca18cc4fdf469e..9cbb2d70f53709 100644 --- a/Mathlib/Data/EReal/Basic.lean +++ b/Mathlib/Data/EReal/Basic.lean @@ -850,11 +850,12 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: cast from `ℝ` to `EReal`. -/ @[positivity Real.toEReal _] -meta def evalRealToEReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalRealToEReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(EReal), ~q(Real.toEReal $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(EReal.coe_pos.2 $pa)) | .nonnegative pa => pure (.nonnegative q(EReal.coe_nonneg.2 $pa)) @@ -864,11 +865,12 @@ meta def evalRealToEReal : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for the `positivity` tactic: cast from `ℝ≥0∞` to `EReal`. -/ @[positivity ENNReal.toEReal _] -meta def evalENNRealToEReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalENNRealToEReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(EReal), ~q(ENNReal.toEReal $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(EReal.coe_ennreal_pos.2 $pa)) | .nonzero pa => pure (.positive q(EReal.coe_ennreal_pos_iff_ne_zero.2 $pa)) @@ -881,11 +883,12 @@ We prove that `EReal.toReal x` is nonnegative whenever `x` is nonnegative. Since `EReal.toReal ⊤ = 0`, we cannot prove a stronger statement, at least without relying on a tactic like `finiteness`. -/ @[positivity EReal.toReal _] -meta def evalERealToReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalERealToReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(Real), ~q(EReal.toReal $a) => assertInstancesCommute - match (← core q(inferInstance) q(inferInstance) a).toNonneg with + match (← core q(inferInstance) (some q(inferInstance)) a).toNonneg with | .some pa => pure (.nonnegative q(EReal.toReal_nonneg $pa)) | _ => pure .none | _, _, _ => throwError "not EReal.toReal" @@ -897,11 +900,12 @@ and it is nonnegative otherwise. We cannot deduce any corollaries from `x ≠ 0`, since `EReal.toENNReal x = 0` for `x < 0`. -/ @[positivity EReal.toENNReal _] -meta def evalERealToENNReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalERealToENNReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ENNReal), ~q(EReal.toENNReal $a) => assertInstancesCommute - match ← core q(inferInstance) q(inferInstance) a with + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => pure (.positive q(EReal.toENNReal_pos_iff.2 $pa)) | _ => pure (.nonnegative q(zero_le (a := $e))) | _, _, _ => throwError "not EReal.toENNReal" diff --git a/Mathlib/Data/EReal/Inv.lean b/Mathlib/Data/EReal/Inv.lean index 26d1a3cc43c590..e61ad93ab0efa8 100644 --- a/Mathlib/Data/EReal/Inv.lean +++ b/Mathlib/Data/EReal/Inv.lean @@ -551,7 +551,8 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: inverse of an `EReal`. -/ @[positivity (_⁻¹ : EReal)] -meta def evalERealInv : PositivityExt where eval {u α} zα pα e := do +meta def evalERealInv : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match u, α, e with | 0, ~q(EReal), ~q($a⁻¹) => assertInstancesCommute @@ -562,7 +563,8 @@ meta def evalERealInv : PositivityExt where eval {u α} zα pα e := do /-- Extension for the `positivity` tactic: ratio of two `EReal`s. -/ @[positivity (_ / _ : EReal)] -meta def evalERealDiv : PositivityExt where eval {u α} zα pα e := do +meta def evalERealDiv : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match u, α, e with | 0, ~q(EReal), ~q($a / $b) => assertInstancesCommute diff --git a/Mathlib/Data/EReal/Operations.lean b/Mathlib/Data/EReal/Operations.lean index 1d3cea1bfb2454..075d47a6994978 100644 --- a/Mathlib/Data/EReal/Operations.lean +++ b/Mathlib/Data/EReal/Operations.lean @@ -821,7 +821,8 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: sum of two `EReal`s. -/ @[positivity (_ + _ : EReal)] -meta def evalERealAdd : PositivityExt where eval {u α} zα pα e := do +meta def evalERealAdd : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match u, α, e with | 0, ~q(EReal), ~q($a + $b) => assertInstancesCommute @@ -840,7 +841,8 @@ meta def evalERealAdd : PositivityExt where eval {u α} zα pα e := do /-- Extension for the `positivity` tactic: product of two `EReal`s. -/ @[positivity (_ * _ : EReal)] -meta def evalERealMul : PositivityExt where eval {u α} zα pα e := do +meta def evalERealMul : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match u, α, e with | 0, ~q(EReal), ~q($a * $b) => assertInstancesCommute diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index 5bb1fff0c6d3d4..d1a46797c16806 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -1006,11 +1006,12 @@ alias ⟨_, nnreal_coe_pos⟩ := coe_pos /-- Extension for the `positivity` tactic: cast from `ℝ≥0` to `ℝ`. -/ @[positivity NNReal.toReal _] -meta def evalNNRealtoReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNNRealtoReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ), ~q(NNReal.toReal $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(nnreal_coe_pos $pa)) | _ => pure (.nonnegative q(NNReal.coe_nonneg $a)) @@ -1018,11 +1019,12 @@ meta def evalNNRealtoReal : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for the `positivity` tactic: `Real.toNNReal` -/ @[positivity Real.toNNReal _] -meta def evalRealToNNReal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalRealToNNReal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ≥0), ~q(Real.toNNReal $a) => assertInstancesCommute - match (← core q(inferInstance) q(inferInstance) a) with + match (← core q(inferInstance) (some q(inferInstance)) a) with | .positive pa => pure (.positive q(toNNReal_pos.mpr $pa)) | _ => failure | _, _, _ => throwError "not Real.toNNReal" @@ -1031,11 +1033,12 @@ alias ⟨_, nnabs_pos_of_pos⟩ := Real.nnabs_pos /-- Extension for the `positivity` tactic: `Real.nnabs` -/ @[positivity Real.nnabs _] -meta def evalRealNNAbs : PositivityExt where eval {u α} _zα _pα e := do +meta def evalRealNNAbs : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℝ≥0), ~q(Real.nnabs $a) => assertInstancesCommute - match (← core q(inferInstance) q(inferInstance) a).toNonzero with + match (← core q(inferInstance) (some q(inferInstance)) a).toNonzero with | some pa => pure (.positive q(nnabs_pos_of_pos $pa)) | _ => failure | _, _, _ => throwError "not Real.nnabs" diff --git a/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean b/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean index 40d3bb7a8ca3f2..0d27087ca77713 100644 --- a/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean +++ b/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean @@ -87,7 +87,8 @@ open Lean Meta Qq /-- Extension for `Nat.doubleFactorial`. -/ @[positivity Nat.doubleFactorial _] -meta def evalDoubleFactorial : PositivityExt where eval {u α} _ _ e := do +meta def evalDoubleFactorial : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℕ), ~q(Nat.doubleFactorial $n) => assumeInstancesCommute diff --git a/Mathlib/Data/Nat/Totient.lean b/Mathlib/Data/Nat/Totient.lean index 9f59ec38d113ca..82b080ac815907 100644 --- a/Mathlib/Data/Nat/Totient.lean +++ b/Mathlib/Data/Nat/Totient.lean @@ -446,9 +446,10 @@ open Lean Meta Qq meta def evalNatTotient : PositivityExt where eval {u α} z p e := do match u, α, e with | 0, ~q(ℕ), ~q(Nat.totient $n) => - assumeInstancesCommute match ← core z p n with - | .positive pa => return .positive q(Nat.totient_pos.mpr $pa) + | .positive pa => + assumeInstancesCommute + return .positive q(Nat.totient_pos.mpr $pa) | _ => failure | _, _, _ => throwError "not Nat.totient" diff --git a/Mathlib/Data/Rat/Cast/Order.lean b/Mathlib/Data/Rat/Cast/Order.lean index 24a8ad895fa5f8..935ce8e22c6bcf 100644 --- a/Mathlib/Data/Rat/Cast/Order.lean +++ b/Mathlib/Data/Rat/Cast/Order.lean @@ -260,16 +260,18 @@ open Lean Meta Qq Function /-- Extension for Rat.cast. -/ @[positivity Rat.cast _] -meta def evalRatCast : PositivityExt where eval {u α} _zα _pα e := do +meta def evalRatCast : PositivityExt where eval {u α} _zα pα? e := do let ~q(@Rat.cast _ (_) ($a : ℚ)) := e | throwError "not Rat.cast" - match ← core q(inferInstance) q(inferInstance) a with + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => + let some _ := pα? | pure .none let _oα ← synthInstanceQ q(Field $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) assumeInstancesCommute return .positive q((Rat.cast_pos (K := $α)).mpr $pa) | .nonnegative pa => + let some _ := pα? | pure .none let _oα ← synthInstanceQ q(Field $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) @@ -284,16 +286,18 @@ meta def evalRatCast : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for NNRat.cast. -/ @[positivity NNRat.cast _] -meta def evalNNRatCast : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNNRatCast : PositivityExt where eval {u α} _zα pα? e := do let ~q(@NNRat.cast _ (_) ($a : ℚ≥0)) := e | throwError "not NNRat.cast" - match ← core q(inferInstance) q(inferInstance) a with + match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => + let some _ := pα? | pure .none let _oα ← synthInstanceQ q(Semifield $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) assumeInstancesCommute return .positive q((NNRat.cast_pos (K := $α)).mpr $pa) | _ => + let some _ := pα? | pure .none let _oα ← synthInstanceQ q(Semifield $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) diff --git a/Mathlib/Geometry/Euclidean/Altitude.lean b/Mathlib/Geometry/Euclidean/Altitude.lean index d35a424aec9492..1d100ab3c1c959 100644 --- a/Mathlib/Geometry/Euclidean/Altitude.lean +++ b/Mathlib/Geometry/Euclidean/Altitude.lean @@ -260,9 +260,10 @@ lemma height_pos {n : ℕ} [NeZero n] (s : Simplex ℝ P n) (i : Fin (n + 1)) : open Qq Mathlib.Meta.Positivity in /-- Extension for the `positivity` tactic: the height of a simplex is always positive. -/ @[positivity height _ _] -meta def evalHeight : PositivityExt where eval {u α} _ _ e := do +meta def evalHeight : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@height $V $P $i1 $i2 $i3 $i4 $n $hn $s $i) => + let some _ := pα? | pure .none assertInstancesCommute return .positive q(height_pos $s $i) | _, _, _ => throwError "not Simplex.height" diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index 314885dfedd883..c369663b90f5d7 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -138,9 +138,10 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `Besicovitch.SatelliteConfig.r`. -/ @[positivity Besicovitch.SatelliteConfig.r _ _] -meta def evalBesicovitchSatelliteConfigR : PositivityExt where eval {u α} _zα _pα e := do +meta def evalBesicovitchSatelliteConfigR : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@Besicovitch.SatelliteConfig.r $β $inst $N $τ $self $i) => + let some _ := pα? | pure .none assertInstancesCommute return .positive q(Besicovitch.SatelliteConfig.rpos $self $i) | _, _, _ => throwError "not Besicovitch.SatelliteConfig.r" diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index e726c0325904e3..577389d0ba23ef 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -1367,7 +1367,8 @@ attribute [local instance] monadLiftOptionMetaM in This extension only proves non-negativity, strict positivity is more delicate for integration and requires more assumptions. -/ @[positivity MeasureTheory.integral _ _] -meta def evalIntegral : PositivityExt where eval {u α} zα pα e := do +meta def evalIntegral : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match u, α, e with | 0, ~q(ℝ), ~q(@MeasureTheory.integral $i ℝ _ $inst2 _ _ $f) => let i : Q($i) ← mkFreshExprMVarQ q($i) .syntheticOpaque diff --git a/Mathlib/MeasureTheory/Measure/Real.lean b/Mathlib/MeasureTheory/Measure/Real.lean index ebde97eb7f5f44..0d15c02f097b66 100644 --- a/Mathlib/MeasureTheory/Measure/Real.lean +++ b/Mathlib/MeasureTheory/Measure/Real.lean @@ -493,8 +493,9 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: applications of `μ.real` are nonnegative. -/ @[positivity MeasureTheory.Measure.real _ _] -meta def evalMeasureReal : PositivityExt where eval {_ _} _zα _pα e := do +meta def evalMeasureReal : PositivityExt where eval {_ _} _zα pα? e := do let .app (.app _ a) b ← whnfR e | throwError "not measureReal" + let some _ := pα? | pure .none let p ← mkAppOptM ``MeasureTheory.measureReal_nonneg #[none, none, a, b] pure (.nonnegative p) diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean index 6b7c2d9b959adf..0978dd9917eae5 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean @@ -456,11 +456,12 @@ open Lean Meta Qq /-- Extension for `ArithmeticFunction.sigma`. -/ @[positivity ArithmeticFunction.sigma _ _] -meta def evalArithmeticFunctionSigma : PositivityExt where eval {u α} z p e := do +meta def evalArithmeticFunctionSigma : PositivityExt where eval {u α} z p? e := do + let some p := p? | throwError "no PartialOrder instance" match u, α, e with | 0, ~q(ℕ), ~q(ArithmeticFunction.sigma $k $n) => - let rn ← core z p n assumeInstancesCommute + let rn ← core z p n match rn with | .positive pn => return .positive q(Iff.mpr ArithmeticFunction.sigma_pos_iff $pn) | _ => return .nonnegative q(Nat.zero_le _) diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean index a7320c6d952dbd..f0595aca62f502 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean @@ -222,11 +222,12 @@ open Lean Meta Qq /-- Extension for `ArithmeticFunction.zeta`. -/ @[positivity ArithmeticFunction.zeta _] -meta def evalArithmeticFunctionZeta : PositivityExt where eval {u α} z p e := do +meta def evalArithmeticFunctionZeta : PositivityExt where eval {u α} z p? e := do + let some p := p? | throwError "no PartialOrder instance" match u, α, e with | 0, ~q(ℕ), ~q(ArithmeticFunction.zeta $n) => - let rn ← core z p n assumeInstancesCommute + let rn ← core z p n match rn with | .positive pn => return .positive q(Iff.mpr ArithmeticFunction.zeta_pos $pn) | _ => return .nonnegative q(Nat.zero_le _) diff --git a/Mathlib/NumberTheory/Height/Basic.lean b/Mathlib/NumberTheory/Height/Basic.lean index ccb65f86701f3c..7118e99a9d8893 100644 --- a/Mathlib/NumberTheory/Height/Basic.lean +++ b/Mathlib/NumberTheory/Height/Basic.lean @@ -189,18 +189,20 @@ open Lean.Meta Qq Height /-- Extension for the `positivity` tactic: `Height.mulHeight₁` is always positive. -/ @[positivity Height.mulHeight₁ _] -meta def evalMulHeight₁ : PositivityExt where eval {u α} _ _ e := do +meta def evalMulHeight₁ : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@mulHeight₁ $K $KF $KA $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(mulHeight₁_pos $a)) | _, _, _ => throwError "not Height.mulHeight₁" /-- Extension for the `positivity` tactic: `Height.logHeight₁` is always nonnegative. -/ @[positivity Height.logHeight₁ _] -meta def evalLogHeight₁ : PositivityExt where eval {u α} _ _ e := do +meta def evalLogHeight₁ : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@logHeight₁ $K $KF $KA $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(zero_le_logHeight₁ $a)) | _, _, _ => throwError "not Height.logHeight₁" @@ -508,9 +510,10 @@ open Lean.Meta Qq Height /-- Extension for the `positivity` tactic: `Height.mulHeight` is always positive. -/ @[positivity Height.mulHeight _] -meta def evalMulHeight : PositivityExt where eval {u α} _ _ e := do +meta def evalMulHeight : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@mulHeight $K $KF $KA $ι $a) => + let some _ := pα? | pure .none -- Check whether there is a `Finite` instance for `$ι` around. match ← trySynthInstanceQ q(Finite $ι) with | .some _instFinite => @@ -521,9 +524,10 @@ meta def evalMulHeight : PositivityExt where eval {u α} _ _ e := do /-- Extension for the `positivity` tactic: `Height.logHeight` is always nonnegative. -/ @[positivity Height.logHeight _] -meta def evalLogHeight : PositivityExt where eval {u α} _ _ e := do +meta def evalLogHeight : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@logHeight $K $KF $KA $ι $a) => + let some _ := pα? | pure .none -- Check whether there is a `Finite` instance for `$ι` around. match ← trySynthInstanceQ q(Finite $ι) with | .some _instFinite => diff --git a/Mathlib/NumberTheory/Height/NumberField.lean b/Mathlib/NumberTheory/Height/NumberField.lean index 74804fb2a94663..0e3471a25c812c 100644 --- a/Mathlib/NumberTheory/Height/NumberField.lean +++ b/Mathlib/NumberTheory/Height/NumberField.lean @@ -194,9 +194,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `Height.totalWeight` is positive for number fields. -/ @[positivity Height.totalWeight _] -meta def evalHeightTotalWeight : PositivityExt where eval {u α} _ _ e := do +meta def evalHeightTotalWeight : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℕ), ~q(@Height.totalWeight $K $KF $KA) => + let some _ := pα? | pure .none -- Check whether there is a `NumberField` instance for `$K` around. match ← trySynthInstanceQ q(NumberField $K) with | .some _inst => diff --git a/Mathlib/NumberTheory/Height/Projectivization.lean b/Mathlib/NumberTheory/Height/Projectivization.lean index 4251faa9ce7221..0caa26f4437275 100644 --- a/Mathlib/NumberTheory/Height/Projectivization.lean +++ b/Mathlib/NumberTheory/Height/Projectivization.lean @@ -83,18 +83,20 @@ open Lean.Meta Qq Projectivization /-- Extension for the `positivity` tactic: `Projectivization.mulHeight` is always positive. -/ @[positivity Projectivization.mulHeight _] -meta def evalProjMulHeight : PositivityExt where eval {u α} _ _ e := do +meta def evalProjMulHeight : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@mulHeight $K $KF $KA $ι $ιF $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(mulHeight_pos $a)) | _, _, _ => throwError "not Projectivization.mulHeight" /-- Extension for the `positivity` tactic: `Projectivization.logHeight` is always nonnegative. -/ @[positivity Projectivization.logHeight _] -meta def evalProjLogHeight : PositivityExt where eval {u α} _ _ e := do +meta def evalProjLogHeight : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@logHeight $K $KF $KA $ι $ιF $a) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(logHeight_nonneg $a)) | _, _, _ => throwError "not Projectivization.logHeight" diff --git a/Mathlib/NumberTheory/LucasLehmer.lean b/Mathlib/NumberTheory/LucasLehmer.lean index 68b1afc4de2cc0..cfac67c69e8e3b 100644 --- a/Mathlib/NumberTheory/LucasLehmer.lean +++ b/Mathlib/NumberTheory/LucasLehmer.lean @@ -78,11 +78,12 @@ alias ⟨_, mersenne_pos_of_pos⟩ := mersenne_pos /-- Extension for the `positivity` tactic: `mersenne`. -/ @[positivity mersenne _] -meta def evalMersenne : PositivityExt where eval {u α} _zα _pα e := do +meta def evalMersenne : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | pure .none match u, α, e with | 0, ~q(ℕ), ~q(mersenne $a) => - let ra ← core q(inferInstance) q(inferInstance) a assertInstancesCommute + let ra ← core q(inferInstance) (some q(inferInstance)) a match ra with | .positive pa => pure (.positive q(mersenne_pos_of_pos $pa)) | _ => pure (.nonnegative q(Nat.zero_le (mersenne $a))) diff --git a/Mathlib/NumberTheory/SelbergSieve.lean b/Mathlib/NumberTheory/SelbergSieve.lean index d066238a75fe9e..93cfa77d4eb6ff 100644 --- a/Mathlib/NumberTheory/SelbergSieve.lean +++ b/Mathlib/NumberTheory/SelbergSieve.lean @@ -89,9 +89,10 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `BoundingSieve.weights`. -/ @[positivity BoundingSieve.weights _ _] -meta def evalBoundingSieveWeights : PositivityExt where eval {u α} _zα _pα e := do +meta def evalBoundingSieveWeights : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@BoundingSieve.weights $s $n) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(BoundingSieve.weights_nonneg $s $n)) | _, _, _ => throwError "not BoundingSieve.weights" diff --git a/Mathlib/Tactic/Positivity/Basic.lean b/Mathlib/Tactic/Positivity/Basic.lean index 8edffeca629e60..4e078e63ad35fc 100644 --- a/Mathlib/Tactic/Positivity/Basic.lean +++ b/Mathlib/Tactic/Positivity/Basic.lean @@ -57,35 +57,20 @@ end ite /-- The `positivity` extension which identifies expressions of the form `ite p a b`, such that `positivity` successfully recognises both `a` and `b`. -/ -@[positivity ite _ _ _] def evalIte : PositivityExt where eval {u α} zα pα e := do +@[positivity ite _ _ _] def evalIte : PositivityExt where eval {u α} zα pα? e := do let .app (.app (.app (.app f (p : Q(Prop))) (_ : Q(Decidable $p))) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not ite" haveI' : $e =Q ite $p $a $b := ⟨⟩ - let ra ← core zα pα a; let rb ← core zα pα b + let ra ← core zα pα? a; let rb ← core zα pα? b guard <|← withDefault <| withNewMCtxDepth <| isDefEq f q(ite (α := $α)) match ra, rb with - | .positive pa, .positive pb => - pure (.positive q(ite_pos $p $pa $pb)) - | .positive pa, .nonnegative pb => - let _b ← synthInstanceQ q(Preorder $α) - assumeInstancesCommute - pure (.nonnegative q(ite_nonneg_of_pos_of_nonneg $p $pa $pb)) - | .nonnegative pa, .positive pb => - let _b ← synthInstanceQ q(Preorder $α) - assumeInstancesCommute - pure (.nonnegative q(ite_nonneg_of_nonneg_of_pos $p $pa $pb)) - | .nonnegative pa, .nonnegative pb => - pure (.nonnegative q(ite_nonneg $p $pa $pb)) - | .positive pa, .nonzero pb => - let _b ← synthInstanceQ q(Preorder $α) - assumeInstancesCommute - pure (.nonzero q(ite_ne_zero_of_pos_of_ne_zero $p $pa $pb)) - | .nonzero pa, .positive pb => - let _b ← synthInstanceQ q(Preorder $α) - assumeInstancesCommute - pure (.nonzero q(ite_ne_zero_of_ne_zero_of_pos $p $pa $pb)) - | .nonzero pa, .nonzero pb => - pure (.nonzero q(ite_ne_zero $p $pa $pb)) + | .positive pa, .positive pb => pure (.positive q(ite_pos $p $pa $pb)) + | .positive pa, .nonnegative pb => pure (.nonnegative q(ite_nonneg_of_pos_of_nonneg $p $pa $pb)) + | .nonnegative pa, .positive pb => pure (.nonnegative q(ite_nonneg_of_nonneg_of_pos $p $pa $pb)) + | .nonnegative pa, .nonnegative pb => pure (.nonnegative q(ite_nonneg $p $pa $pb)) + | .positive pa, .nonzero pb => pure (.nonzero q(ite_ne_zero_of_pos_of_ne_zero $p $pa $pb)) + | .nonzero pa, .positive pb => pure (.nonzero q(ite_ne_zero_of_ne_zero_of_pos $p $pa $pb)) + | .nonzero pa, .nonzero pb => pure (.nonzero q(ite_ne_zero $p $pa $pb)) | _, _ => pure .none section LinearOrder @@ -104,59 +89,80 @@ end LinearOrder /-- The `positivity` extension which identifies expressions of the form `min a b`, such that `positivity` successfully recognises both `a` and `b`. -/ -@[positivity min _ _] def evalMin : PositivityExt where eval {u α} zα pα e := do +@[positivity min _ _] def evalMin : PositivityExt where eval {u α} zα pα? e := do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not min" let _e_eq : $e =Q $f $a $b := ⟨⟩ let _a ← synthInstanceQ q(LinearOrder $α) - assumeInstancesCommute let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(min) - match ← core zα pα a, ← core zα pα b with - | .positive pa, .positive pb => pure (.positive q(lt_min $pa $pb)) - | .positive pa, .nonnegative pb => pure (.nonnegative q(le_min_of_lt_of_le $pa $pb)) - | .nonnegative pa, .positive pb => pure (.nonnegative q(le_min_of_le_of_lt $pa $pb)) - | .nonnegative pa, .nonnegative pb => pure (.nonnegative q(le_min $pa $pb)) - | .positive pa, .nonzero pb => pure (.nonzero q(min_ne_of_lt_of_ne $pa $pb)) - | .nonzero pa, .positive pb => pure (.nonzero q(min_ne_of_ne_of_lt $pa $pb)) - | .nonzero pa, .nonzero pb => pure (.nonzero q(min_ne $pa $pb)) + assumeInstancesCommute + match ← core zα pα? a, ← core zα pα? b with + | .positive (pα := pα') pa, .positive pb => + assumeInstancesCommute + pure (.positive q(lt_min $pa $pb)) + | .positive (pα := pα') pa, .nonnegative pb => + assumeInstancesCommute + pure (.nonnegative q(le_min_of_lt_of_le $pa $pb)) + | .nonnegative (pα := pα') pa, .positive pb => + assumeInstancesCommute + pure (.nonnegative q(le_min_of_le_of_lt $pa $pb)) + | .nonnegative pa (pα := pα'), .nonnegative pb => + assumeInstancesCommute + pure (.nonnegative q(le_min $pa $pb)) + | .positive pa, .nonzero pb => + assumeInstancesCommute + pure (.nonzero q(min_ne_of_lt_of_ne $pa $pb)) + | .nonzero pa, .positive pb => + assumeInstancesCommute + pure (.nonzero q(min_ne_of_ne_of_lt $pa $pb)) + | .nonzero pa, .nonzero pb => do + pure (.nonzero q(min_ne $pa $pb)) | _, _ => pure .none /-- Extension for the `max` operator. The `max` of two numbers is nonnegative if at least one is nonnegative, strictly positive if at least one is positive, and nonzero if both are nonzero. -/ -@[positivity max _ _] def evalMax : PositivityExt where eval {u α} zα pα e := do +@[positivity max _ _] def evalMax : PositivityExt where eval {u α} zα pα? e := do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not max" let _e_eq : $e =Q $f $a $b := ⟨⟩ let _a ← synthInstanceQ q(LinearOrder $α) - assumeInstancesCommute let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(max) - let result : Strictness zα pα e ← catchNone do - let ra ← core zα pα a + let result : Strictness zα e pα? ← catchNone do + let ra ← core zα pα? a match ra with - | .positive pa => pure (.positive q(lt_max_of_lt_left $pa)) - | .nonnegative pa => pure (.nonnegative q(le_max_of_le_left $pa)) + | .positive pa => + assumeInstancesCommute + pure (.positive q(lt_max_of_lt_left $pa)) + | .nonnegative pa => + assumeInstancesCommute + pure (.nonnegative q(le_max_of_le_left $pa)) -- If `a ≠ 0`, we might prove `max a b ≠ 0` if `b ≠ 0` but we don't want to evaluate -- `b` before having ruled out `0 < a`, for performance. So we do that in the second branch -- of the `orElse'`. | _ => pure .none orElse result do - let rb ← core zα pα b + let rb ← core zα pα? b match rb with - | .positive pb => pure (.positive q(lt_max_of_lt_right $pb)) - | .nonnegative pb => pure (.nonnegative q(le_max_of_le_right $pb)) + | .positive pb => + assumeInstancesCommute + pure (.positive q(lt_max_of_lt_right $pb)) + | .nonnegative pb => + assumeInstancesCommute + pure (.nonnegative q(le_max_of_le_right $pb)) | .nonzero pb => do - match ← core zα pα a with + match ← core zα pα? a with | .nonzero pa => pure (.nonzero q(max_ne $pa $pb)) | _ => pure .none | _ => pure .none /-- The `positivity` extension which identifies expressions of the form `a + b`, such that `positivity` successfully recognises both `a` and `b`. -/ -@[positivity _ + _] def evalAdd : PositivityExt where eval {u α} zα pα e := do +@[positivity _ + _] def evalAdd : PositivityExt where eval {u α} zα pα? e := do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not +" let _e_eq : $e =Q $f $a $b := ⟨⟩ let _a ← synthInstanceQ q(AddZeroClass $α) assumeInstancesCommute let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HAdd.hAdd) - let ra ← core zα pα a; let rb ← core zα pα b + let ra ← core zα pα? a; let rb ← core zα pα? b + let some _pα := pα? | pure .none match ra, rb with | .positive pa, .positive pb => let _a ← synthInstanceQ q(AddLeftMono $α) @@ -174,81 +180,106 @@ such that `positivity` successfully recognises both `a` and `b`. -/ /-- The `positivity` extension which identifies expressions of the form `a - b`, such that there is a local hypothesis `b < a`, `b ≤ a`, `a ≠ b` or `b ≠ a`. -/ -@[positivity _ - _] def evalSub : PositivityExt where eval {u α} _zα pα e := do +@[positivity _ - _] def evalSub : PositivityExt where eval {u α} _zα pα? e := do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not -" let _e_eq : $e =Q $f $a $b := ⟨⟩ let _a ← synthInstanceQ q(AddGroup $α) assumeInstancesCommute let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HSub.hSub) - let mut result := .none - for decl in ← getLCtx do - unless decl.isImplementationDetail do - have e' : Q(Prop) := decl.type - have p : Q($e') := .fvar decl.fvarId - result ← orElse result do - match e' with - | ~q(@LE.le.{u} $β $le $lo $hi) => - let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none - let .defEq _ ← isDefEqQ q($le) q(($pα).toLE) | return .none - let .defEq (_ : $a =Q $hi) ← isDefEqQ a hi | return .none - let .defEq (_ : $b =Q $lo) ← isDefEqQ b lo | return .none - let _ ← synthInstanceQ q(AddRightMono $α) - return .nonnegative q(sub_nonneg_of_le $p) - | ~q(@LT.lt.{u} $β $lt $lo $hi) => - let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none - let .defEq _ ← isDefEqQ q($lt) q(($pα).toLT) | return .none - let .defEq (_ : $a =Q $hi) ← isDefEqQ a hi | return .none - let .defEq (_ : $b =Q $lo) ← isDefEqQ b lo | return .none - let _i ← synthInstanceQ q(AddRightStrictMono $α) - assumeInstancesCommute - return .positive (q(sub_pos_of_lt $p):) - | ~q(@Ne.{u + 1} $β $lhs $rhs) => - let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none - if let .defEq (_ : $a =Q $lhs) ← isDefEqQ a lhs then - let .defEq (_ : $b =Q $rhs) ← isDefEqQ b rhs | return .none - return .nonzero (q(sub_ne_zero_of_ne $p):) - if let .defEq _ ← isDefEqQ a rhs then - let .defEq _ ← isDefEqQ b lhs | return .none - return .nonzero (q(sub_ne_zero_of_ne ($p).symm):) - return .none - | _ => return .none - return result + match pα? with + | some pα => + let mut result := .none + for decl in ← getLCtx do + unless decl.isImplementationDetail do + have e' : Q(Prop) := decl.type + have p : Q($e') := .fvar decl.fvarId + result ← orElse result do + match e' with + | ~q(@LE.le.{u} $β $le $lo $hi) => + let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none + let .defEq _ ← isDefEqQ q($le) q(($pα).toLE) | return .none + let .defEq (_ : $a =Q $hi) ← isDefEqQ a hi | return .none + let .defEq (_ : $b =Q $lo) ← isDefEqQ b lo | return .none + let _ ← synthInstanceQ q(AddRightMono $α) + return .nonnegative q(sub_nonneg_of_le $p) + | ~q(@LT.lt.{u} $β $lt $lo $hi) => + let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none + let .defEq _ ← isDefEqQ q($lt) q(($pα).toLT) | return .none + let .defEq (_ : $a =Q $hi) ← isDefEqQ a hi | return .none + let .defEq (_ : $b =Q $lo) ← isDefEqQ b lo | return .none + let _i ← synthInstanceQ q(AddRightStrictMono $α) + assumeInstancesCommute + return .positive (q(sub_pos_of_lt $p):) + | ~q(@Ne.{u + 1} $β $lhs $rhs) => + let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none + if let .defEq (_ : $a =Q $lhs) ← isDefEqQ a lhs then + let .defEq (_ : $b =Q $rhs) ← isDefEqQ b rhs | return .none + return .nonzero (q(sub_ne_zero_of_ne $p):) + if let .defEq _ ← isDefEqQ a rhs then + let .defEq _ ← isDefEqQ b lhs | return .none + return .nonzero (q(sub_ne_zero_of_ne ($p).symm):) + return .none + | _ => return .none + return result + | none => + let mut result := .none + for decl in ← getLCtx do + unless decl.isImplementationDetail do + have e' : Q(Prop) := decl.type + have p : Q($e') := .fvar decl.fvarId + result ← orElse result do + match e' with + | ~q(@Ne.{u + 1} $β $lhs $rhs) => + let .defEq (_ : $α =Q $β) ← isDefEqQ α β | return .none + if let .defEq (_ : $a =Q $lhs) ← isDefEqQ a lhs then + let .defEq (_ : $b =Q $rhs) ← isDefEqQ b rhs | return .none + return .nonzero (q(sub_ne_zero_of_ne $p):) + if let .defEq _ ← isDefEqQ a rhs then + let .defEq _ ← isDefEqQ b lhs | return .none + return .nonzero (q(sub_ne_zero_of_ne ($p).symm):) + return .none + | _ => return .none + return result /-- The `positivity` extension which identifies expressions of the form `a * b`, such that `positivity` successfully recognises both `a` and `b`. -/ -@[positivity _ * _] def evalMul : PositivityExt where eval {u α} zα pα e := do +@[positivity _ * _] def evalMul : PositivityExt where eval {u α} zα pα? e := do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not *" let _e_eq : $e =Q $f $a $b := ⟨⟩ let _a ← synthInstanceQ q(Mul $α) let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HMul.hMul) - let ra ← core zα pα a; let rb ← core zα pα b - let tryProveNonzero (pa? : Option Q($a ≠ 0)) (pb? : Option Q($b ≠ 0)) : - MetaM (Strictness zα pα e) := do + let ra ← core zα pα? a; let rb ← core zα pα? b + let tryProveNonzero (pα? : Option Q(PartialOrder $α)) + (pa? : Option Q($a ≠ 0)) (pb? : Option Q($b ≠ 0)) : MetaM (Strictness zα e pα?) := do let pa ← liftOption pa? let pb ← liftOption pb? let _a ← synthInstanceQ q(NoZeroDivisors $α) pure (.nonzero q(mul_ne_zero $pa $pb)) - let tryProveNonneg (pa? : Option Q(0 ≤ $a)) (pb? : Option Q(0 ≤ $b)) : - MetaM (Strictness zα pα e) := do + let tryProveNonneg (pα : Q(PartialOrder $α)) (pa? : Option Q(0 ≤ $a)) (pb? : Option Q(0 ≤ $b)) : + MetaM (Strictness zα e pα) := do let pa ← liftOption pa? let pb ← liftOption pb? let _a ← synthInstanceQ q(MulZeroClass $α) let _a ← synthInstanceQ q(PosMulMono $α) assumeInstancesCommute pure (.nonnegative q(mul_nonneg $pa $pb)) - let tryProvePositive (pa? : Option Q(0 < $a)) (pb? : Option Q(0 < $b)) : - MetaM (Strictness zα pα e) := do + let tryProvePositive (pα : Q(PartialOrder $α)) (pa? : Option Q(0 < $a)) (pb? : Option Q(0 < $b)) : + MetaM (Strictness zα e pα) := do let pa ← liftOption pa? let pb ← liftOption pb? let _a ← synthInstanceQ q(MulZeroClass $α) let _a ← synthInstanceQ q(PosMulStrictMono $α) assumeInstancesCommute pure (.positive q(mul_pos $pa $pb)) - let mut result := .none - result ← orElse result (tryProvePositive ra.toPositive rb.toPositive) - result ← orElse result (tryProveNonneg ra.toNonneg rb.toNonneg) - result ← orElse result (tryProveNonzero ra.toNonzero rb.toNonzero) - return result + match pα? with + | some pα => + let mut result : Strictness zα e (some pα) := .none + result ← orElse result (tryProvePositive pα ra.toPositive rb.toPositive) + result ← orElse result (tryProveNonneg pα ra.toNonneg rb.toNonneg) + result ← orElse result (tryProveNonzero pα ra.toNonzero rb.toNonzero) + return result + | none => + return ← catchNone <| tryProveNonzero .none ra.toNonzero rb.toNonzero lemma int_div_self_pos {a : ℤ} (ha : 0 < a) : 0 < a / a := by rw [Int.ediv_self ha.ne']; exact zero_lt_one @@ -264,15 +295,17 @@ lemma int_div_nonneg_of_pos_of_pos {a b : ℤ} (ha : 0 < a) (hb : 0 < b) : 0 ≤ /-- The `positivity` extension which identifies expressions of the form `a / b`, where `a` and `b` are integers. -/ -@[positivity (_ : ℤ) / (_ : ℤ)] def evalIntDiv : PositivityExt where eval {u α} _ _ e := do +@[positivity (_ : ℤ) / (_ : ℤ)] def evalIntDiv : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℤ" match u, α, e with | 0, ~q(ℤ), ~q($a / $b) => - let ra ← core q(inferInstance) q(inferInstance) a - let rb ← core q(inferInstance) q(inferInstance) b + let ra ← core q(inferInstance) (some q(inferInstance)) a + let rb ← core q(inferInstance) (some q(inferInstance)) b assertInstancesCommute match ra, rb with | .positive (pa : Q(0 < $a)), .positive (pb : Q(0 < $b)) => -- Only attempts to prove `0 < a / a`, otherwise falls back to `0 ≤ a / b` + let _ := q(int_div_self_pos $pa) match ← isDefEqQ a b with | .defEq _ => pure (.positive q(int_div_self_pos $pa)) | .notDefEq => pure (.nonnegative q(int_div_nonneg_of_pos_of_pos $pa $pb)) @@ -289,43 +322,55 @@ theorem pow_zero_pos [Semiring α] [PartialOrder α] [IsOrderedRing α] [Nontriv (a : α) : 0 < a ^ 0 := zero_lt_one.trans_le (pow_zero a).ge +theorem pow_zero_ne_zero [Semiring α] [Nontrivial α] (a : α) : a ^ 0 ≠ 0 := + pow_zero a ▸ one_ne_zero + /-- The `positivity` extension which identifies expressions of the form `a ^ (0 : ℕ)`. This extension is run in addition to the general `a ^ b` extension (they are overlapping). -/ @[positivity _ ^ (0 : ℕ)] -meta def evalPowZeroNat : PositivityExt where eval {u α} _zα _pα e := do +meta def evalPowZeroNat : PositivityExt where eval {u α} _zα pα? e := do let .app (.app _ (a : Q($α))) _ ← whnfR e | throwError "not ^" let _a ← synthInstanceQ q(Semiring $α) - let _a ← synthInstanceQ q(PartialOrder $α) + assumeInstancesCommute + haveI' : $e =Q $a ^ 0 := ⟨⟩ + let _a ← synthInstanceQ q(Nontrivial $α) + let some _pα := pα? | pure (.nonzero q(pow_zero_ne_zero $a)) let _a ← synthInstanceQ q(IsOrderedRing $α) - _ ← synthInstanceQ q(Nontrivial $α) - pure (.positive (q(pow_zero_pos $a) : Expr)) + pure (.positive q(pow_zero_pos $a)) /-- The `positivity` extension which identifies expressions of the form `a ^ (b : ℕ)`, such that `positivity` successfully recognises both `a` and `b`. -/ @[positivity _ ^ (_ : ℕ)] -meta def evalPow : PositivityExt where eval {u α} zα pα e := do +meta def evalPow : PositivityExt where eval {u α} zα pα? e := do let .app (.app _ (a : Q($α))) (b : Q(ℕ)) ← whnfR e | throwError "not ^" - let result ← catchNone do + let some pα := pα? | do + let _a ← synthInstanceQ q(MonoidWithZero $α) + let _a ← synthInstanceQ q(NoZeroDivisors $α) + assumeInstancesCommute + haveI' : $e =Q $a ^ $b := ⟨⟩ + let .nonzero nza ← core zα .none a | pure .none + pure (.nonzero q(pow_ne_zero $b $nza)) + let result : Strictness zα e pα ← catchNone do + let _a ← synthInstanceQ q(Ring $α) + let _a ← synthInstanceQ q(LinearOrder $α) + let _a ← synthInstanceQ q(IsStrictOrderedRing $α) + assumeInstancesCommute let .true := b.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ n where n is a literal" let some n := (b.getRevArg! 1).rawNatLit? | throwError "not a ^ n where n is a literal" guard (n % 2 = 0) have m : Q(ℕ) := mkRawNatLit (n / 2) haveI' : $b =Q 2 * $m := ⟨⟩ - let _a ← synthInstanceQ q(Ring $α) - let _a ← synthInstanceQ q(LinearOrder $α) - let _a ← synthInstanceQ q(IsStrictOrderedRing $α) - assumeInstancesCommute haveI' : $e =Q $a ^ $b := ⟨⟩ pure (.nonnegative q((even_two_mul $m).pow_nonneg $a)) orElse result do let ra ← core zα pα a let ofNonneg (pa : Q(0 ≤ $a)) (_rα : Q(Semiring $α)) (_oα : Q(IsOrderedRing $α)) : - MetaM (Strictness zα pα e) := do + MetaM (Strictness zα e (some pα)) := do haveI' : $e =Q $a ^ $b := ⟨⟩ assumeInstancesCommute pure (.nonnegative q(pow_nonneg $pa $b)) let ofNonzero (pa : Q($a ≠ 0)) (_rα : Q(Semiring $α)) (_oα : Q(IsOrderedRing $α)) : - MetaM (Strictness zα pα e) := do + MetaM (Strictness zα e (some pα)) := do haveI' : $e =Q $a ^ $b := ⟨⟩ assumeInstancesCommute let _a ← synthInstanceQ q(NoZeroDivisors $α) @@ -358,20 +403,21 @@ theorem abs_pos_of_ne_zero {α : Type*} [AddGroup α] [LinearOrder α] /-- The `positivity` extension which identifies expressions of the form `|a|`. -/ @[positivity |_|] -meta def evalAbs : PositivityExt where eval {_u} (α zα pα) (e : Q($α)) := do +meta def evalAbs : PositivityExt where eval {_u} (α zα pα?) (e : Q($α)) := do let ~q(@abs _ (_) (_) $a) := e | throwError "not |·|" + let some pα' := pα? | pure .none try - match ← core zα pα a with + match ← core zα (some pα') a with | .positive pa => let pa' ← mkAppM ``abs_pos_of_pos #[pa] - pure (.positive pa') + pure (.positive (pα := pα') pa') | .nonzero pa => let pa' ← mkAppM ``abs_pos_of_ne_zero #[pa] - pure (.positive pa') + pure (.positive (pα := pα') pa') | _ => throwError "goto catch" catch _ => do let pa' ← mkAppM ``abs_nonneg #[a] - pure (.nonnegative pa') + pure (.nonnegative (pα := pα') pa') theorem int_natAbs_pos {n : ℤ} (hn : 0 < n) : 0 < n.natAbs := Int.natAbs_pos.mpr hn.ne' @@ -381,18 +427,18 @@ Since the output type of `Int.natAbs` is `ℕ`, the nonnegative case is handled `positivity` tactic. -/ @[positivity Int.natAbs _] -meta def evalNatAbs : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNatAbs : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Int.natAbs $a) => let zα' : Q(Zero Int) := q(inferInstance) let pα' : Q(PartialOrder Int) := q(inferInstance) + assertInstancesCommute let ra ← core zα' pα' a match ra with | .positive pa => - assertInstancesCommute pure (.positive q(int_natAbs_pos $pa)) | .nonzero pa => - assertInstancesCommute pure (.positive q(Int.natAbs_pos.mpr $pa)) | .nonnegative _pa => pure .none @@ -403,11 +449,17 @@ meta def evalNatAbs : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for the `positivity` tactic: `Nat.cast` is always non-negative, and positive when its input is. -/ @[positivity Nat.cast _] -meta def evalNatCast : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNatCast : PositivityExt where eval {u α} _zα pα? e := do let ~q(@Nat.cast _ (_) ($a : ℕ)) := e | throwError "not Nat.cast" let zα' : Q(Zero Nat) := q(inferInstance) - let pα' : Q(PartialOrder Nat) := q(inferInstance) let (_i1 : Q(AddMonoidWithOne $α)) ← synthInstanceQ q(AddMonoidWithOne $α) + let some _pα := pα? | do + let (_cz : Q(CharZero $α)) ← synthInstanceQ q(CharZero $α) + assumeInstancesCommute + match ← core zα' .none a with + | .nonzero nza => pure (.nonzero q(Nat.cast_ne_zero.2 $nza)) + | _ => pure .none + let pα' : Q(PartialOrder Nat) := q(inferInstance) let (_i2 : Q(AddLeftMono $α)) ← synthInstanceQ q(AddLeftMono $α) let (_i3 : Q(ZeroLEOneClass $α)) ← synthInstanceQ q(ZeroLEOneClass $α) assumeInstancesCommute @@ -424,35 +476,36 @@ meta def evalNatCast : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for the `positivity` tactic: `Int.cast` is positive (resp. non-negative) if its input is. -/ @[positivity Int.cast _] -meta def evalIntCast : PositivityExt where eval {u α} _zα _pα e := do +meta def evalIntCast : PositivityExt where eval {u α} _zα pα? e := do let ~q(@Int.cast _ (_) ($a : ℤ)) := e | throwError "not Int.cast" let zα' : Q(Zero Int) := q(inferInstance) let pα' : Q(PartialOrder Int) := q(inferInstance) let ra ← core zα' pα' a - match ra with - | .positive pa => + match ra, pα? with + | .positive pa, some _ => let _rα ← synthInstanceQ q(Ring $α) let _oα ← synthInstanceQ q(IsOrderedRing $α) let _nt ← synthInstanceQ q(Nontrivial $α) assumeInstancesCommute pure (.positive q(Int.cast_pos.mpr $pa)) - | .nonnegative pa => + | .nonnegative pa, some _ => let _rα ← synthInstanceQ q(Ring $α) let _oα ← synthInstanceQ q(IsOrderedRing $α) let _nt ← synthInstanceQ q(Nontrivial $α) assumeInstancesCommute pure (.nonnegative q(Int.cast_nonneg $pa)) - | .nonzero pa => + | .nonzero pa, _ => let _oα ← synthInstanceQ q(AddGroupWithOne $α) let _nt ← synthInstanceQ q(CharZero $α) assumeInstancesCommute pure (.nonzero q(Int.cast_ne_zero.mpr $pa)) - | .none => + | _ , _ => pure .none /-- Extension for `Nat.succ`. -/ @[positivity Nat.succ _] -meta def evalNatSucc : PositivityExt where eval {u α} _zα _pα e := do +meta def evalNatSucc : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Nat.succ $a) => assertInstancesCommute @@ -461,7 +514,8 @@ meta def evalNatSucc : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for `PNat.val`. -/ @[positivity PNat.val _] -meta def evalPNatVal : PositivityExt where eval {u α} _zα _pα e := do +meta def evalPNatVal : PositivityExt where eval {u α} _zα pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(PNat.val $a) => assertInstancesCommute @@ -470,7 +524,8 @@ meta def evalPNatVal : PositivityExt where eval {u α} _zα _pα e := do /-- Extension for `Nat.factorial`. -/ @[positivity Nat.factorial _] -meta def evalFactorial : PositivityExt where eval {u α} _ _ e := do +meta def evalFactorial : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Nat.factorial $a) => assertInstancesCommute @@ -479,7 +534,8 @@ meta def evalFactorial : PositivityExt where eval {u α} _ _ e := do /-- Extension for `Nat.ascFactorial`. -/ @[positivity Nat.ascFactorial _ _] -meta def evalAscFactorial : PositivityExt where eval {u α} _ _ e := do +meta def evalAscFactorial : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Nat.ascFactorial ($n + 1) $k) => assertInstancesCommute @@ -496,10 +552,14 @@ meta def evalNatGCD : PositivityExt where eval {u α} z p e := do | 0, ~q(ℕ), ~q(Nat.gcd $a $b) => assertInstancesCommute match ← core z p a with - | .positive pa => return .positive q(Nat.gcd_pos_of_pos_left $b $pa) + | .positive pa => + assertInstancesCommute + return .positive q(Nat.gcd_pos_of_pos_left $b $pa) | _ => match ← core z p b with - | .positive pb => return .positive q(Nat.gcd_pos_of_pos_right $a $pb) + | .positive pb => + assertInstancesCommute + return .positive q(Nat.gcd_pos_of_pos_right $a $pb) | _ => failure | _, _, _ => throwError "not Nat.gcd" @@ -508,11 +568,12 @@ meta def evalNatGCD : PositivityExt where eval {u α} z p e := do meta def evalNatLCM : PositivityExt where eval {u α} z p e := do match u, α, e with | 0, ~q(ℕ), ~q(Nat.lcm $a $b) => - assertInstancesCommute match ← core z p a with | .positive pa => + assertInstancesCommute match ← core z p b with | .positive pb => + assertInstancesCommute return .positive q(Nat.lcm_pos $pa $pb) | _ => failure | _ => failure @@ -523,40 +584,43 @@ meta def evalNatLCM : PositivityExt where eval {u α} z p e := do meta def evalNatSqrt : PositivityExt where eval {u α} z p e := do match u, α, e with | 0, ~q(ℕ), ~q(Nat.sqrt $n) => - assumeInstancesCommute match ← core z p n with - | .positive pa => return .positive q(Nat.sqrt_pos.mpr $pa) + | .positive pa => + assumeInstancesCommute + return .positive q(Nat.sqrt_pos.mpr $pa) | _ => failure | _, _, _ => throwError "not Nat.sqrt" /-- Extension for `Int.gcd`. Uses positivity of the left term, if available, then tries the right term. -/ @[positivity Int.gcd _ _] -meta def evalIntGCD : PositivityExt where eval {u α} _ _ e := do +meta def evalIntGCD : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Int.gcd $a $b) => let z ← synthInstanceQ (q(Zero ℤ) : Q(Type)) let p ← synthInstanceQ (q(PartialOrder ℤ) : Q(Type)) assertInstancesCommute - match (← catchNone (core z p a)).toNonzero with + match (← catchNone (core z (some p) a)).toNonzero z with | some na => return .positive q(Int.gcd_pos_of_ne_zero_left $b $na) | none => - match (← core z p b).toNonzero with + match (← core z (some p) b).toNonzero z with | some nb => return .positive q(Int.gcd_pos_of_ne_zero_right $a $nb) | none => failure | _, _, _ => throwError "not Int.gcd" /-- Extension for `Int.lcm`. -/ @[positivity Int.lcm _ _] -meta def evalIntLCM : PositivityExt where eval {u α} _ _ e := do +meta def evalIntLCM : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Int.lcm $a $b) => let z ← synthInstanceQ (q(Zero ℤ) : Q(Type)) let p ← synthInstanceQ (q(PartialOrder ℤ) : Q(Type)) assertInstancesCommute - match (← core z p a).toNonzero with + match (← core z (some p) a).toNonzero z with | some na => - match (← core z p b).toNonzero with + match (← core z (some p) b).toNonzero z with | some nb => return .positive q(Int.lcm_pos $na $nb) | _ => failure | _ => failure @@ -571,21 +635,25 @@ alias ⟨_, NNRat.num_ne_zero_of_ne_zero⟩ := num_ne_zero /-- The `positivity` extension which identifies expressions of the form `NNRat.num q`, such that `positivity` successfully recognises `q`. -/ @[positivity NNRat.num _] -meta def evalNNRatNum : PositivityExt where eval {u α} _ _ e := do +meta def evalNNRatNum : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(NNRat.num $a) => let zα : Q(Zero ℚ≥0) := q(inferInstance) let pα : Q(PartialOrder ℚ≥0) := q(inferInstance) + trace[Tactic.positivity] "I'm evalNNRatNum: {e}" assumeInstancesCommute match ← core zα pα a with - | .positive pa => return .positive q(NNRat.num_pos_of_pos $pa) + | .positive pa => + return .positive q(NNRat.num_pos_of_pos $pa) | .nonzero pa => return .nonzero q(NNRat.num_ne_zero_of_ne_zero $pa) | _ => return .none | _, _, _ => throwError "not NNRat.num" /-- The `positivity` extension which identifies expressions of the form `Rat.den a`. -/ @[positivity NNRat.den _] -meta def evalNNRatDen : PositivityExt where eval {u α} _ _ e := do +meta def evalNNRatDen : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(NNRat.den $a) => assumeInstancesCommute @@ -609,22 +677,26 @@ alias ⟨_, num_ne_zero_of_ne_zero⟩ := num_ne_zero /-- The `positivity` extension which identifies expressions of the form `Rat.num a`, such that `positivity` successfully recognises `a`. -/ @[positivity Rat.num _] -meta def evalRatNum : PositivityExt where eval {u α} _ _ e := do +meta def evalRatNum : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℤ" match u, α, e with | 0, ~q(ℤ), ~q(Rat.num $a) => let zα : Q(Zero ℚ) := q(inferInstance) let pα : Q(PartialOrder ℚ) := q(inferInstance) assumeInstancesCommute match ← core zα pα a with - | .positive pa => pure <| .positive q(num_pos_of_pos $pa) - | .nonnegative pa => pure <| .nonnegative q(num_nonneg_of_nonneg $pa) + | .positive pa => + pure <| .positive q(num_pos_of_pos $pa) + | .nonnegative pa => + pure <| .nonnegative q(num_nonneg_of_nonneg $pa) | .nonzero pa => pure <| .nonzero q(num_ne_zero_of_ne_zero $pa) | .none => pure .none | _, _ => throwError "not Rat.num" /-- The `positivity` extension which identifies expressions of the form `Rat.den a`. -/ @[positivity Rat.den _] -meta def evalRatDen : PositivityExt where eval {u α} _ _ e := do +meta def evalRatDen : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | throwError "not PartialOrder ℕ" match u, α, e with | 0, ~q(ℕ), ~q(Rat.den $a) => assumeInstancesCommute @@ -633,7 +705,8 @@ meta def evalRatDen : PositivityExt where eval {u α} _ _ e := do /-- Extension for `posPart`. `a⁺` is always nonnegative, and positive if `a` is. -/ @[positivity _⁺] -meta def evalPosPart : PositivityExt where eval {u α} zα pα e := do +meta def evalPosPart : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match e with | ~q(@posPart _ $instαpospart $a) => let _instαlat ← synthInstanceQ q(Lattice $α) @@ -643,13 +716,15 @@ meta def evalPosPart : PositivityExt where eval {u α} zα pα e := do -- `.none`) here sometimes. See e.g. the first test for `posPart`. This is why we need -- `catchNone` match ← catchNone (core zα pα a) with - | .positive pf => return .positive q(posPart_pos $pf) + | .positive pf => + return .positive q(posPart_pos $pf) | _ => return .nonnegative q(posPart_nonneg $a) | _ => throwError "not `posPart`" /-- Extension for `negPart`. `a⁻` is always nonnegative. -/ @[positivity _⁻] -meta def evalNegPart : PositivityExt where eval {u α} _ _ e := do +meta def evalNegPart : PositivityExt where eval {u α} _ pα? e := do + let some _ := pα? | pure .none match e with | ~q(@negPart _ $instαnegpart $a) => let _instαlat ← synthInstanceQ q(Lattice $α) @@ -660,7 +735,8 @@ meta def evalNegPart : PositivityExt where eval {u α} _ _ e := do /-- Extension for the `positivity` tactic: nonnegative maps take nonnegative values. -/ @[positivity DFunLike.coe _ _] -meta def evalMap : PositivityExt where eval {_ β} _ _ e := do +meta def evalMap : PositivityExt where eval {_ β} _ pβ? e := do + let some _ := pβ? | pure .none let .app (.app _ f) a ← whnfR e | throwError "not ↑f · where f is of NonnegHomClass" let pa ← mkAppOptM ``apply_nonneg #[none, none, β, none, none, none, none, f, a] diff --git a/Mathlib/Tactic/Positivity/Core.lean b/Mathlib/Tactic/Positivity/Core.lean index f669b02420923e..45a3faaa15fde1 100644 --- a/Mathlib/Tactic/Positivity/Core.lean +++ b/Mathlib/Tactic/Positivity/Core.lean @@ -54,37 +54,36 @@ lemma ne_of_ne_of_eq' {α : Sort*} {a c b : α} (hab : (a : α) ≠ c) (hbc : a namespace Mathlib.Meta.Positivity -variable {u : Level} {α : Q(Type u)} (zα : Q(Zero $α)) (pα : Q(PartialOrder $α)) +variable {u : Level} {α : Q(Type u)} (zα : Q(Zero $α)) /-- The result of `positivity` running on an expression `e` of type `α`. -/ -inductive Strictness (e : Q($α)) where - | positive (pf : Q(0 < $e)) - | nonnegative (pf : Q(0 ≤ $e)) - | nonzero (pf : Q($e ≠ 0)) - | none - deriving Repr +inductive Strictness (e : Q($α)) : Option Q(PartialOrder $α) → Type where + | positive {pα : Q(PartialOrder $α)} (pf : Q(0 < $e)) : Strictness e pα + | nonnegative {pα : Q(PartialOrder $α)} (pf : Q(0 ≤ $e)) : Strictness e pα + | nonzero {pα?} (pf : Q($e ≠ 0)) : Strictness e pα? + | none {pα?} : Strictness e pα? /-- Gives a generic description of the `positivity` result. -/ -def Strictness.toString {e : Q($α)} : Strictness zα pα e → String +def Strictness.toString {e pα?} : Strictness zα e pα? → String | positive _ => "positive" | nonnegative _ => "nonnegative" | nonzero _ => "nonzero" | none => "none" /-- Extract a proof that `e` is positive, if possible, from `Strictness` information about `e`. -/ -def Strictness.toPositive {e} : Strictness zα pα e → Option Q(0 < $e) +def Strictness.toPositive {e pα} : Strictness zα e (some pα) → Option Q(0 < $e) | .positive pf => some pf | _ => .none /-- Extract a proof that `e` is nonnegative, if possible, from `Strictness` information about `e`. -/ -def Strictness.toNonneg {e} : Strictness zα pα e → Option Q(0 ≤ $e) +def Strictness.toNonneg {e pα} : Strictness zα e (some pα) → Option Q(0 ≤ $e) | .positive pf => some q(le_of_lt $pf) | .nonnegative pf => some pf | _ => .none /-- Extract a proof that `e` is nonzero, if possible, from `Strictness` information about `e`. -/ -def Strictness.toNonzero {e} : Strictness zα pα e → Option Q($e ≠ 0) +def Strictness.toNonzero {e pα?} : Strictness zα e pα? → Option Q($e ≠ 0) | .positive pf => some q(ne_of_gt $pf) | .nonzero pf => some pf | _ => .none @@ -92,8 +91,8 @@ def Strictness.toNonzero {e} : Strictness zα pα e → Option Q($e ≠ 0) /-- An extension for `positivity`. -/ structure PositivityExt where /-- Attempts to prove an expression `e : α` is `>0`, `≥0`, or `≠0`. -/ - eval {u : Level} {α : Q(Type u)} (zα : Q(Zero $α)) (pα : Q(PartialOrder $α)) (e : Q($α)) : - MetaM (Strictness zα pα e) + eval {u : Level} {α : Q(Type u)} (zα : Q(Zero $α)) (pα? : Option Q(PartialOrder $α)) (e : Q($α)) : + MetaM (Strictness zα e pα?) /-- Read a `positivity` extension from a declaration of the right type. -/ def mkPositivityExt (n : Name) : ImportM PositivityExt := do @@ -213,24 +212,25 @@ lemma nz_of_isRat {n : ℤ} {d : ℕ} [Ring A] [LinearOrder A] [IsStrictOrderedR rw [eq] exact ne_iff_lt_or_gt.2 (Or.inl neg) -variable {zα pα} in +variable {zα} in /-- Converts a `MetaM Strictness` which can fail into one that never fails and returns `.none` instead. -/ -def catchNone {e : Q($α)} (t : MetaM (Strictness zα pα e)) : MetaM (Strictness zα pα e) := +def catchNone {e pα?} (t : MetaM (Strictness zα e pα?)) : MetaM (Strictness zα e pα?) := try t catch e => trace[Tactic.positivity.failure] "{e.toMessageData}" pure .none -variable {zα pα} in +variable {zα} in /-- Converts a `MetaM Strictness` which can return `.none` into one which never returns `.none` but fails instead. -/ -def throwNone {e : Q($α)} (t : MetaM (Strictness zα pα e)) : MetaM (Strictness zα pα e) := do +def throwNone {e pα?} (t : MetaM (Strictness zα e pα?)) : MetaM (Strictness zα e pα?) := do match ← t with | .none => throwError "Strictness result was `{.ofConstName ``Strictness.none}`." | r => pure r /-- Attempts to prove a `Strictness` result when `e` evaluates to a literal number. -/ -def normNumPositivity (e : Q($α)) : MetaM (Strictness zα pα e) := catchNone do +def normNumPositivity (pα : Q(PartialOrder $α)) (e : Q($α)) + : MetaM (Strictness zα e (some pα)) := catchNone do match ← NormNum.derive e with | .isBool .. => failure | .isNat _ lit p => @@ -312,7 +312,7 @@ def normNumPositivity (e : Q($α)) : MetaM (Strictness zα pα e) := catchNone d pure (.nonnegative q(nonneg_of_isRat $p $w)) /-- Attempts to prove that `e ≥ 0` using `zero_le` in a `CanonicallyOrderedAdd` monoid. -/ -def positivityCanon (e : Q($α)) : MetaM (Strictness zα pα e) := do +def positivityCanon (pα : Q(PartialOrder $α)) (e : Q($α)) : MetaM (Strictness zα e (some pα)) := do let _add ← synthInstanceQ q(AddMonoid $α) let _le ← synthInstanceQ q(PartialOrder $α) let _i ← synthInstanceQ q(CanonicallyOrderedAdd $α) @@ -320,21 +320,24 @@ def positivityCanon (e : Q($α)) : MetaM (Strictness zα pα e) := do pure (.nonnegative q(zero_le (a := $e))) /-- A variation on `assumption` when the hypothesis is `lo ≤ e` where `lo` is a numeral. -/ -def compareHypLE (lo e : Q($α)) (p₂ : Q($lo ≤ $e)) : MetaM (Strictness zα pα e) := do +def compareHypLE (pα : Q(PartialOrder $α)) (lo e : Q($α)) (p₂ : Q($lo ≤ $e)) + : MetaM (Strictness zα e pα) := do match ← normNumPositivity zα pα lo with | .positive p₁ => pure (.positive q(lt_of_lt_of_le $p₁ $p₂)) | .nonnegative p₁ => pure (.nonnegative q(le_trans $p₁ $p₂)) | _ => pure .none /-- A variation on `assumption` when the hypothesis is `lo < e` where `lo` is a numeral. -/ -def compareHypLT (lo e : Q($α)) (p₂ : Q($lo < $e)) : MetaM (Strictness zα pα e) := do +def compareHypLT (pα : Q(PartialOrder $α)) (lo e : Q($α)) (p₂ : Q($lo < $e)) : + MetaM (Strictness zα e pα) := do match ← normNumPositivity zα pα lo with | .positive p₁ => pure (.positive q(lt_trans $p₁ $p₂)) | .nonnegative p₁ => pure (.positive q(lt_of_le_of_lt $p₁ $p₂)) | _ => pure .none /-- A variation on `assumption` when the hypothesis is `x = e` where `x` is a numeral. -/ -def compareHypEq (e x : Q($α)) (p₂ : Q($x = $e)) : MetaM (Strictness zα pα e) := do +def compareHypEq (pα : Q(PartialOrder $α)) (e x : Q($α)) (p₂ : Q($x = $e)) : + MetaM (Strictness zα e pα) := do match ← normNumPositivity zα pα x with | .positive p₁ => pure (.positive q(lt_of_lt_of_eq $p₁ $p₂)) | .nonnegative p₁ => pure (.nonnegative q(le_of_le_of_eq $p₁ $p₂)) @@ -346,7 +349,8 @@ initialize registerTraceClass `Tactic.positivity.failure /-- A variation on `assumption` which checks if the hypothesis `ldecl` is `a [ pure <| .nonnegative q(ge_of_eq $p) | _ => compareHypEq zα pα e rhs q(Eq.symm $p) - | ~q(@Ne.{u + 1} $α' $lhs $rhs) => + | ~q(@Ne.{u+1} $α' $lhs $rhs) => let .defEq (_ : $α =Q $α') ← isDefEqQ α α' | pure .none match lhs, rhs with | ~q(0), _ => @@ -390,13 +394,30 @@ def compareHyp (e : Q($α)) (ldecl : LocalDecl) : MetaM (Strictness zα pα e) : | _, _ => pure .none | _ => pure .none -variable {zα pα} in +/-- A variation on `assumption` when the hypothesis is `e ≠ 0` or `0 ≠ e`. -/ +def compareHypNonzero {pα?} (e : Q($α)) (ldecl : LocalDecl) : MetaM (Strictness zα e pα?) := do + have e' : Q(Prop) := ldecl.type + let p : Q($e') := .fvar ldecl.fvarId + match e' with + | ~q(@Ne.{u+1} $α' $lhs $rhs) => + let .defEq (_ : $α =Q $α') ← isDefEqQ α α' | pure .none + match lhs, rhs with + | ~q(0), _ => + let .defEq _ ← isDefEqQ e rhs | pure .none + pure <| .nonzero q(Ne.symm $p) + | _, ~q(0) => + let .defEq _ ← isDefEqQ e lhs | pure .none + pure <| .nonzero q($p) + | _, _ => pure .none + | _ => pure .none + +variable {zα} in /-- The main combinator which combines multiple `positivity` results. It assumes `t₁` has already been run for a result, and runs `t₂` and takes the best result. It will skip `t₂` if `t₁` is already a proof of `.positive`, and can also combine `.nonnegative` and `.nonzero` to produce a `.positive` result. -/ -def orElse {e : Q($α)} (t₁ : Strictness zα pα e) (t₂ : MetaM (Strictness zα pα e)) : - MetaM (Strictness zα pα e) := do +def orElse {pα?} {e : Q($α)} (t₁ : Strictness zα e pα?) (t₂ : MetaM (Strictness zα e pα?)) : + MetaM (Strictness zα e pα?) := do match t₁ with | .none => catchNone t₂ | p@(.positive _) => pure p @@ -412,24 +433,41 @@ def orElse {e : Q($α)} (t₁ : Strictness zα pα e) (t₂ : MetaM (Strictness | _ => pure (.nonzero p₁) /-- Run each registered `positivity` extension on an expression, returning a `NormNum.Result`. -/ -def core (e : Q($α)) : MetaM (Strictness zα pα e) := do +def core (pα? : Option Q(PartialOrder $α)) (e : Q($α)) : MetaM (Strictness zα e pα?) := do let mut result := .none trace[Tactic.positivity] "trying to prove positivity of {e}" for ext in ← (positivityExt.getState (← getEnv)).2.getMatch e do try - result ← orElse result <| ext.eval zα pα e + result ← orElse result <| ext.eval zα pα? e catch err => trace[Tactic.positivity] "{e} failed: {err.toMessageData}" - result ← orElse result <| normNumPositivity zα pα e - result ← orElse result <| positivityCanon zα pα e - if let .positive _ := result then + trace[Tactic.positivity] "current result from positivity extensions: {result.toString}" + match pα? with + | some pα => + trace[Tactic.positivity] "{α} has some {pα}" + result ← orElse result <| normNumPositivity zα pα e + trace[Tactic.positivity] "current result from normNum: {result.toString}" + result ← orElse result <| positivityCanon zα pα e + trace[Tactic.positivity] "current result from canonicity: {result.toString}" + if let .positive _ := result then + trace[Tactic.positivity] "{e} => {result.toString}" + return result + for ldecl in ← getLCtx do + if !ldecl.isImplementationDetail then + result ← orElse result <| compareHyp zα pα e ldecl + trace[Tactic.positivity] "{e} => {result.toString}" + throwNone (pure result) + | .none => + trace[Tactic.positivity] "{α} has no PartialOrder" + if let .nonzero _ := result then + trace[Tactic.positivity] "{e} => {result.toString}" + return result + for ldecl in ← getLCtx do + if !ldecl.isImplementationDetail then + result ← orElse result <| compareHypNonzero zα e ldecl trace[Tactic.positivity] "{e} => {result.toString}" - return result - for ldecl in ← getLCtx do - if !ldecl.isImplementationDetail then - result ← orElse result <| compareHyp zα pα e ldecl - trace[Tactic.positivity] "{e} => {result.toString}" - throwNone (pure result) + throwNone (pure result) + private inductive OrderRel : Type | le : OrderRel -- `0 ≤ a` @@ -446,8 +484,9 @@ inequality was established) together with the proof as an expression. -/ def bestResult (e : Expr) : MetaM (Bool × Expr) := do let ⟨u, α, _⟩ ← inferTypeQ' e let zα ← synthInstanceQ q(Zero $α) - let pα ← synthInstanceQ q(PartialOrder $α) - match ← try? (Meta.Positivity.core zα pα e) with + let pα? ← try? <| synthInstanceQ q(PartialOrder $α) + assumeInstancesCommute + match ← try? (Meta.Positivity.core zα pα? e) with | some (.positive pf) => pure (true, pf) | some (.nonnegative pf) => pure (false, pf) | _ => throwError "could not establish the nonnegativity of {e}" @@ -464,28 +503,33 @@ or fails. -/ def solve (t : Q(Prop)) : MetaM Expr := do let rest {u : Level} (α : Q(Type u)) z e (relDesired : OrderRel) : MetaM Expr := do let zα ← synthInstanceQ q(Zero $α) - assumeInstancesCommute let .true ← isDefEq z q(0 : $α) | throwError "not a positivity goal" - let pα ← synthInstanceQ q(PartialOrder $α) - assumeInstancesCommute - let r ← catchNone <| Meta.Positivity.core zα pα e + let pα? ← try? <| synthInstanceQ q(PartialOrder $α) + let r ← catchNone <| Meta.Positivity.core zα pα? e let throw (a b : String) : MetaM Expr := throwError "failed to prove {a}, but it would be possible to prove {b} if desired" - let p ← show MetaM Expr from match relDesired, r with - | .lt, .positive p - | .le, .nonnegative p - | .ne, .nonzero p => pure p - | .le, .positive p => pure q(le_of_lt $p) - | .ne, .positive p => pure q(ne_of_gt $p) - | .ne', .positive p => pure q(ne_of_lt $p) - | .ne', .nonzero p => pure q(Ne.symm $p) - | .lt, .nonnegative _ => throw "strict positivity" "nonnegativity" - | .lt, .nonzero _ => throw "strict positivity" "nonzeroness" - | .le, .nonzero _ => throw "nonnegativity" "nonzeroness" - | .ne, .nonnegative _ - | .ne', .nonnegative _ => throw "nonzeroness" "nonnegativity" - | _, .none => throwError "failed to prove positivity/nonnegativity/nonzeroness" - pure p + if let some _ := pα? then + match relDesired, r with + | .lt, .positive p + | .le, .nonnegative p + | .ne, .nonzero p => pure p + | .le, .positive p => pure q(le_of_lt $p) + | .ne, .positive p => pure q(ne_of_gt $p) + | .ne', .positive p => pure q(ne_of_lt $p) + | .ne', .nonzero p => pure q(Ne.symm $p) + | .lt, .nonnegative _ => throw "strict positivity" "nonnegativity" + | .lt, .nonzero _ => throw "strict positivity" "nonzeroness" + | .le, .nonzero _ => throw "nonnegativity" "nonzeroness" + | .ne, .nonnegative _ + | .ne', .nonnegative _ => throw "nonzeroness" "nonnegativity" + | _, .none => throwError "failed to prove positivity/nonnegativity/nonzeroness" + else + match relDesired, r with + | .ne, .nonzero p => pure p + | .ne', .nonzero p => pure q(Ne.symm $p) + | .lt, .nonzero _ => throw "strict positivity" "nonzeroness" + | .le, .nonzero _ => throw "nonnegativity" "nonzeroness" + | _, _ => throwError "failed to prove nonzeroness" match t with | ~q(@LE.le $α $_a $z $e) => rest α z e .le | ~q(@LT.lt $α $_a $z $e) => rest α z e .lt diff --git a/Mathlib/Tactic/Positivity/Finset.lean b/Mathlib/Tactic/Positivity/Finset.lean index 7e1d3c40ce0b72..50fb47d5c610e6 100644 --- a/Mathlib/Tactic/Positivity/Finset.lean +++ b/Mathlib/Tactic/Positivity/Finset.lean @@ -27,9 +27,10 @@ open Qq Lean Meta Finset It calls `Mathlib.Meta.proveFinsetNonempty` to attempt proving that the finset is nonempty. -/ @[positivity Finset.card _] -meta def evalFinsetCard : PositivityExt where eval {u α} _ _ e := do +meta def evalFinsetCard : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℕ), ~q(Finset.card $s) => + let some _ := pα? | pure .none let some ps ← proveFinsetNonempty s | return .none assertInstancesCommute return .positive q(Finset.Nonempty.card_pos $ps) @@ -37,9 +38,10 @@ meta def evalFinsetCard : PositivityExt where eval {u α} _ _ e := do /-- Extension for `Fintype.card`. `Fintype.card α` is positive if `α` is nonempty. -/ @[positivity Fintype.card _] -meta def evalFintypeCard : PositivityExt where eval {u α} _ _ e := do +meta def evalFintypeCard : PositivityExt where eval {u α} _ pα? e := do match u, α, e with | 0, ~q(ℕ), ~q(@Fintype.card $β $instβ) => + let some _ := pα? | pure .none let instβno ← synthInstanceQ q(Nonempty $β) assumeInstancesCommute return .positive q(@Fintype.card_pos $β $instβ $instβno) @@ -49,9 +51,10 @@ meta def evalFintypeCard : PositivityExt where eval {u α} _ _ e := do It calls `Mathlib.Meta.proveFinsetNonempty` to attempt proving that the finset is nonempty. -/ @[positivity Finset.dens _] -meta def evalFinsetDens : PositivityExt where eval {u 𝕜} _ _ e := do +meta def evalFinsetDens : PositivityExt where eval {u 𝕜} _ pα? e := do match u, 𝕜, e with | 0, ~q(ℚ≥0), ~q(@Finset.dens $α $instα $s) => + let some _ := pα? | pure .none let some ps ← proveFinsetNonempty s | return .none assumeInstancesCommute return .positive q(@Nonempty.dens_pos $α $instα $s $ps) @@ -68,12 +71,13 @@ example (s : Finset ℕ) (f : ℕ → ℤ) (hf : ∀ n, 0 ≤ f n) : 0 ≤ s.sum because `compareHyp` can't look for assumptions behind binders. -/ @[positivity Finset.sum _ _] -meta def evalFinsetSum : PositivityExt where eval {u α} zα pα e := do +meta def evalFinsetSum : PositivityExt where eval {u α} zα pα? e := do match e with | ~q(@Finset.sum $ι _ $instα $s $f) => let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque have body : Q($α) := .betaRev f #[i] - let rbody ← core zα pα body + let rbody ← core zα pα? body + let some pα := pα? | pure .none -- TODO: the case without PartialOrder let p_pos : Option Q(0 < $e) := ← (do let .positive pbody := rbody | pure none -- Fail if the body is not provably positive let some ps ← proveFinsetNonempty s | pure none diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean index dc8f2ac255a83e..ddd26a88733d28 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean @@ -371,7 +371,8 @@ attribute [local instance] monadLiftOptionMetaM in This extension only proves non-negativity, strict positivity is more delicate for infinite sums and requires more assumptions. -/ @[positivity tsum _] -meta def evalTsum : PositivityExt where eval {u α} zα pα e := do +meta def evalTsum : PositivityExt where eval {u α} zα pα? e := do + let some pα := pα? | pure .none match e with | ~q(@tsum _ $ι $instCommMonoid $instTopSpace $f $L) => lambdaBoundedTelescope f 1 fun args (body : Q($α)) => do diff --git a/Mathlib/Topology/MetricSpace/Bounded.lean b/Mathlib/Topology/MetricSpace/Bounded.lean index 1e1351befa0e17..50d0a217cdaf41 100644 --- a/Mathlib/Topology/MetricSpace/Bounded.lean +++ b/Mathlib/Topology/MetricSpace/Bounded.lean @@ -589,9 +589,10 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: the diameter of a set is always nonnegative. -/ @[positivity Metric.diam _] -meta def evalDiam : PositivityExt where eval {u α} _zα _pα e := do +meta def evalDiam : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@Metric.diam _ $inst $s) => + let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(Metric.diam_nonneg)) | _, _, _ => throwError "not ‖ · ‖" diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index e3694f57974cec..334e1ae713a618 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -257,9 +257,10 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: distances are nonnegative. -/ @[positivity Dist.dist _ _] -meta def evalDist : PositivityExt where eval {u α} _zα _pα e := do +meta def evalDist : PositivityExt where eval {u α} _zα pα? e := do match u, α, e with | 0, ~q(ℝ), ~q(@Dist.dist $β $inst $a $b) => + let some _ := pα? | pure .none let _inst ← synthInstanceQ q(PseudoMetricSpace $β) assertInstancesCommute pure (.nonnegative q(dist_nonneg)) diff --git a/MathlibTest/positivity.lean b/MathlibTest/positivity.lean index 9765bcb3dbfffe..a680ddf744befd 100644 --- a/MathlibTest/positivity.lean +++ b/MathlibTest/positivity.lean @@ -633,3 +633,30 @@ example [Semiring S] [PartialOrder S] [IsOrderedRing S] [Semiring R] (abv : R → S) [IsAbsoluteValue abv] (x : R) : 0 ≤ abv x := by positivity + +/- ## Nonzeroness -/ + +example {α : Type*} [Zero α] {a : α} (ha : a ≠ 0) : a ≠ 0 := by positivity +example {α : Type*} [Zero α] {a : α} (ha : a ≠ 0) : 0 ≠ a := by positivity +example {α : Type*} [Zero α] {a : α} (ha : 0 ≠ a) : a ≠ 0 := by positivity + +example {α : Type*} [Semifield α] {x : α} (hx : x ≠ 0) : x⁻¹ ≠ 0 := by positivity +example {α : Type*} [Semifield α] {x y : α} (hx : x ≠ 0) (hy : y ≠ 0) : x / y ≠ 0 := by positivity + +example {α : Type*} [MonoidWithZero α] [NoZeroDivisors α] {x : α} (hx : x ≠ 0) (n : ℕ) : + x ^ n ≠ 0 := by positivity + +example {α : Type*} [MonoidWithZero α] [NoZeroDivisors α] {x y : α} + (hx : x ≠ 0) (hy : y ≠ 0) : x * y ≠ 0 := by positivity + +example {α : Type*} [AddMonoidWithOne α] [CharZero α] {n : ℕ} (hn : n ≠ 0) : + (n : α) ≠ 0 := by positivity +example {α : Type*} [AddGroupWithOne α] [CharZero α] {z : ℤ} (hz : z ≠ 0) : + (z : α) ≠ 0 := by positivity +example {α : Type*} [DivisionRing α] [CharZero α] {q : ℚ} (hq : q ≠ 0) : + (q : α) ≠ 0 := by positivity + +example {α : Type*} [Semiring α] [Nontrivial α] (a : α) : a ^ 0 ≠ 0 := by positivity + +example {α : Type*} [AddGroup α] {a b : α} (ha : a ≠ b) : 0 ≠ b - a := by positivity +example {α : Type*} [AddGroup α] {a b : α} (ha : a ≠ b) : 0 ≠ a - b := by positivity From e1d1de3bbb575ceb968a895a3462d5a9ca4b22c9 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:42:42 +0000 Subject: [PATCH 0120/1300] feat(Convert): less aggressive congruence (#38071) This PR tries to make `convert` behave more predictably, disabling some of the aggressive congruence steps that `congr!` does. In particular, when the two sides have a different head constants, then we should not use congruence on these applications. Co-authored-by: Jon Eugster --- Mathlib/Analysis/Complex/Exponential.lean | 2 +- Mathlib/Data/Fin/Tuple/Basic.lean | 9 ++--- Mathlib/Data/List/Perm/Basic.lean | 3 +- Mathlib/Tactic/Convert.lean | 49 +++++------------------ MathlibTest/Tactic/Convert/Basic.lean | 12 +----- 5 files changed, 19 insertions(+), 56 deletions(-) diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index 9a51b9898ee788..798b4ef9df2d96 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -95,7 +95,7 @@ variable (x y : ℂ) theorem exp_zero : exp 0 = 1 := by rw [exp] refine lim_eq_of_equiv_const fun ε ε0 => ⟨1, fun j hj => ?_⟩ - convert! (config := .unfoldSameFun) ε0 -- ε0 : ε > 0 but goal is _ < ε + convert ε0.lt rcases j with - | j · exact absurd hj (not_le_of_gt zero_lt_one) · dsimp [exp'] diff --git a/Mathlib/Data/Fin/Tuple/Basic.lean b/Mathlib/Data/Fin/Tuple/Basic.lean index 8dda5f5800debb..cc05c5f49d6741 100644 --- a/Mathlib/Data/Fin/Tuple/Basic.lean +++ b/Mathlib/Data/Fin/Tuple/Basic.lean @@ -400,9 +400,8 @@ theorem append_castAdd_natAdd {f : Fin (m + n) → α} : /-- Splitting a dependent finite sequence v into an initial part and a final part, and then concatenating these components, produces an identical sequence. -/ -theorem addCases_castAdd_natAdd {γ : Fin (m + n) → Sort*} (v : ∀ i, γ i) : - addCases (fun i ↦ v (castAdd n i)) (fun j ↦ v (natAdd m j)) = v := by - ext i +theorem addCases_castAdd_natAdd {γ : Fin (m + n) → Sort*} (v : ∀ i, γ i) (i : Fin (m + n)) : + addCases (fun i ↦ v (castAdd n i)) (fun j ↦ v (natAdd m j)) i = v i := by cases i using addCases <;> simp theorem append_comp_sumElim {xs : Fin m → α} {ys : Fin n → α} : @@ -802,8 +801,8 @@ theorem forall_fin_add_pi {γ : Fin (m + n) → Sort*} {P : (∀ i, γ i) → Pr (∀ (vₘ : ∀ i, γ (castAdd n i)) (vₙ : ∀ j, γ (natAdd m j)), P (addCases vₘ vₙ)) where mp hv vm vn := hv (addCases vm vn) mpr h v := by - convert! h (fun i => v (castAdd n i)) (fun j => v (natAdd m j)) - exact (addCases_castAdd_natAdd v).symm + convert h (fun i => v (castAdd n i)) (fun j => v (natAdd m j)) + exact (addCases_castAdd_natAdd v _).symm lemma exists_iff_castSucc {P : Fin (n + 1) → Prop} : (∃ i, P i) ↔ P (last n) ∨ ∃ i : Fin n, P i.castSucc where diff --git a/Mathlib/Data/List/Perm/Basic.lean b/Mathlib/Data/List/Perm/Basic.lean index c1bc8b988698fa..d15c400a41f037 100644 --- a/Mathlib/Data/List/Perm/Basic.lean +++ b/Mathlib/Data/List/Perm/Basic.lean @@ -164,7 +164,8 @@ end Rel lemma count_eq_count_filter_add [DecidableEq α] (P : α → Prop) [DecidablePred P] (l : List α) (a : α) : count a l = count a (l.filter P) + count a (l.filter (¬ P ·)) := by - convert! countP_eq_countP_filter_add l _ P + unfold count + convert countP_eq_countP_filter_add l _ P simp only [decide_not] theorem Perm.foldl_eq {f : β → α → β} {l₁ l₂ : List α} [rcomm : RightCommutative f] (p : l₁ ~ l₂) : diff --git a/Mathlib/Tactic/Convert.lean b/Mathlib/Tactic/Convert.lean index c023a7dfb9e737..eb74ff924a4cec 100644 --- a/Mathlib/Tactic/Convert.lean +++ b/Mathlib/Tactic/Convert.lean @@ -24,7 +24,7 @@ e : Prime (2 * n + 1) ⊢ Prime (n + n + 1) ``` -the tactic `convert e using 2` will change the goal to +the tactic `convert e` will change the goal to ```lean ⊢ n + n = 2 * n @@ -32,14 +32,6 @@ the tactic `convert e using 2` will change the goal to In this example, the new goal can be solved using `ring`. -The `using 2` indicates it should iterate the congruence algorithm up to two times, -where `convert e` would use an unrestricted number of iterations and lead to two -impossible goals: `⊢ HAdd.hAdd = HMul.hMul` and `⊢ n = 2`. - -A variant configuration is `convert (config := .unfoldSameFun) e`, which only equates function -applications for the same function (while doing so at the higher `default` transparency). -This gives the same goal of `⊢ n + n = 2 * n` without needing `using 2`. - The `convert` tactic applies congruence lemmas eagerly before reducing, therefore it can fail in cases where `exact` succeeds: ```lean @@ -47,7 +39,7 @@ def p (n : ℕ) := True example (h : p 0) : p 1 := by exact h -- succeeds example (h : p 0) : p 1 := by convert h -- fails, with leftover goal `1 = 0` ``` -Limiting the depth of recursion can help with this. For example, `convert h using 1` will work +Limiting the depth of recursion can help with this. For example, `convert h using 0` will work in this case. The syntax `convert ← e` will reverse the direction of the new goals @@ -85,21 +77,12 @@ between `Convert.CheapConfig` and `Convert.ExpensiveConfig` based on other flags -/ structure Convert.CheapConfig extends Congr!.Config where postTransparency := .reducible + partialApp := false + sameFun := true /-- Internal elaborator for `Convert.CheapConfig`: use `Convert.elabConfig` instead. -/ declare_config_elab Convert.elabCheapConfig Convert.CheapConfig -/-- A configuration option that makes `convert` do the sorts of aggressive unfoldings that `congr` -does while also similarly preventing `convert` from considering partial applications or congruences -between different functions being applied. - -Note that `convert (config := .unfoldSameFun)` and `convert! (config := .unfoldSameFun)` -currently do the same thing since `.unfoldSameFun` runs at default transparency always. -This may change in the future, if `convert!` affects other options too. --/ -abbrev Convert.CheapConfig.unfoldSameFun : Convert.CheapConfig := - { Congr!.Config.unfoldSameFun with } - /-- Configuration for the `convert!` family of tactics. This is `Convert.CheapConfig` (used by `convert` without exclamation mark) with different, more aggressive, defaults. @@ -113,26 +96,14 @@ example the following call runs at `.instances` transparency. convert! (postTransparency := .instances) ``` -/ -structure Convert.ExpensiveConfig extends Convert.CheapConfig where +structure Convert.ExpensiveConfig extends Congr!.Config where -- TODO: also enable this in the future? -- preTransparency := .default -- transparency := .default - postTransparency := .default /-- Internal elaborator for `Convert.ExpensiveConfig`: use `Convert.elabConfig` instead. -/ declare_config_elab Convert.elabExpensiveConfig Convert.ExpensiveConfig -/-- A configuration option that makes `convert!` do the sorts of aggressive unfoldings that `congr` -does while also similarly preventing `convert!` from considering partial applications or congruences -between different functions being applied. - -Note that `convert (config := .unfoldSameFun)` and `convert! (config := .unfoldSameFun)` -currently do the same thing since `.unfoldSameFun` runs at default transparency always. -This may change in the future, if `convert!` affects other options too. --/ -abbrev Convert.ExpensiveConfig.unfoldSameFun : Convert.ExpensiveConfig := - { Congr!.Config.unfoldSameFun with } - /-- Configuration elaborator for the `convert`/`convert!` family of tactics. If `expensive` is true, we're elaborating for `convert!`, and will configure to run at default @@ -201,9 +172,10 @@ pattern-matched, like `rintro` would, using the `with` keyword. See also `convert_to t`, where `t` specifies the expected type, instead of a proof term of type `t`. In other words, `convert_to t` works like `convert (?_ : t)`. Both tactics use the same options. -* `convert! e` uses default transparency, rather than reducible, when solving side goals. +* `convert! e` uses default transparency, rather than reducible, when solving side goals, and + it tries to apply congruence even if the two expressions do not have the same head constant. * `convert ← e` creates equality goals in the opposite direction (with the goal type on the right). -* `convert e using n`, where `n` is a positive numeral, controls the depth with which congruence is +* `convert e using n`, where `n` is a numeral, controls the depth with which congruence is applied. For example, if the main goal is `⊢ Prime (n + n + 1)` and `e : Prime (2 * n + 1)`, then `convert e using 2` results in one goal, `⊢ n + n = 2 * n`, and `convert e using 3` (or more) results in two (impossible) goals `⊢ HAdd.hAdd = HMul.hMul` and `⊢ n = 2`. @@ -216,10 +188,9 @@ In other words, `convert_to t` works like `convert (?_ : t)`. Both tactics use t Examples: ```lean --- `convert using` controls the depth of congruence. example {n : ℕ} (e : Prime (2 * n + 1)) : Prime (n + n + 1) := by - convert e using 2 + convert e -- One goal: ⊢ n + n = 2 * n ring @@ -234,7 +205,7 @@ example (h : p 0) : p 1 := by -- `convert with` names introduced variables. example (p q : Nat → Prop) (h : ∀ ε > 0, p ε) : ∀ ε > 0, q ε := by - convert h using 2 with ε hε + convert h with ε hε -- Goal now looks like: -- hε : ε > 0 -- ⊢ q ε ↔ p ε diff --git a/MathlibTest/Tactic/Convert/Basic.lean b/MathlibTest/Tactic/Convert/Basic.lean index e49fab8836a4ad..6c41f450e271e8 100644 --- a/MathlibTest/Tactic/Convert/Basic.lean +++ b/MathlibTest/Tactic/Convert/Basic.lean @@ -61,7 +61,7 @@ end convert_to example (prime : Nat → Prop) (n : Nat) (h : prime (2 * n + 1)) : prime (n + n + 1) := by - convert h + convert! h · guard_target = (HAdd.hAdd : Nat → Nat → Nat) = HMul.hMul exact test_sorry · guard_target = n = 2 @@ -69,15 +69,7 @@ example (prime : Nat → Prop) (n : Nat) (h : prime (2 * n + 1)) : example (prime : Nat → Prop) (n : Nat) (h : prime (2 * n + 1)) : prime (n + n + 1) := by - convert (config := .unfoldSameFun) h - guard_target = n + n = 2 * n - exact test_sorry - --- `convert! (config := .unfoldSameFun)` does the same thing as `convert (config := .unfoldSameFun)` --- (at least for now) -example (prime : Nat → Prop) (n : Nat) (h : prime (2 * n + 1)) : - prime (n + n + 1) := by - convert! (config := .unfoldSameFun) h + convert h guard_target = n + n = 2 * n exact test_sorry From e24b844979be3369da7481a9ab864a3528f326ab Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:42:45 +0000 Subject: [PATCH 0121/1300] chore: add deprecations for `Data/Set/{Accumulate,Dissipate}` (#40676) Follow-up to #40003. --- Mathlib.lean | 2 ++ Mathlib/Data/Set/Accumulate.lean | 5 +++++ Mathlib/Data/Set/Dissipate.lean | 5 +++++ 3 files changed, 12 insertions(+) create mode 100644 Mathlib/Data/Set/Accumulate.lean create mode 100644 Mathlib/Data/Set/Dissipate.lean diff --git a/Mathlib.lean b/Mathlib.lean index 57d9493e5cebd8..28715711f082d3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4315,6 +4315,7 @@ public import Mathlib.Data.Seq.Basic public import Mathlib.Data.Seq.Computation public import Mathlib.Data.Seq.Defs public import Mathlib.Data.Seq.Parallel +public import Mathlib.Data.Set.Accumulate public import Mathlib.Data.Set.Basic public import Mathlib.Data.Set.BoolIndicator public import Mathlib.Data.Set.BooleanAlgebra @@ -4325,6 +4326,7 @@ public import Mathlib.Data.Set.Constructions public import Mathlib.Data.Set.Countable public import Mathlib.Data.Set.Defs public import Mathlib.Data.Set.Disjoint +public import Mathlib.Data.Set.Dissipate public import Mathlib.Data.Set.Enumerate public import Mathlib.Data.Set.Equitable public import Mathlib.Data.Set.Finite.Basic diff --git a/Mathlib/Data/Set/Accumulate.lean b/Mathlib/Data/Set/Accumulate.lean new file mode 100644 index 00000000000000..6645dd738d08eb --- /dev/null +++ b/Mathlib/Data/Set/Accumulate.lean @@ -0,0 +1,5 @@ +module -- shake: keep-all + +public import Mathlib.Order.SetAccumulate + +deprecated_module (since := "2026-06-10") diff --git a/Mathlib/Data/Set/Dissipate.lean b/Mathlib/Data/Set/Dissipate.lean new file mode 100644 index 00000000000000..672b1257912b06 --- /dev/null +++ b/Mathlib/Data/Set/Dissipate.lean @@ -0,0 +1,5 @@ +module -- shake: keep-all + +public import Mathlib.Order.SetDissipate + +deprecated_module (since := "2026-06-10") From 1ce228d453951997c60c821c7738e71fa0db0142 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 17 Jun 2026 16:39:00 +0000 Subject: [PATCH 0122/1300] feat: metric connections (#36299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This file defines what it means for a connection on a Riemannian vector bundle `(V, g)` to be *compatible* with the metric `g`. Namely, the differentiated metric tensor `∇ g` (defined by `(X, σ, τ) ↦ X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)`) should vanish on all differentiable vector fields `X` and differentiable sections `σ`, `τ`. From the path towards the Levi-Civita connection and Riemannian geometry. Co-authored-by: Heather Macbeth [25316162+hrmacbeth@users.noreply.github.com](mailto:25316162+hrmacbeth@users.noreply.github.com) Co-authored-by: Patrick Massot [patrickmassot@free.fr](mailto:patrickmassot@free.fr) Co-authored-by: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Co-authored-by: sgouezel Co-authored-by: Patrick Massot --- Mathlib.lean | 1 + .../CovariantDerivative/Metric.lean | 182 ++++++++++++++++++ .../VectorBundle/MDifferentiable.lean | 25 ++- 3 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean diff --git a/Mathlib.lean b/Mathlib.lean index 28715711f082d3..631fc974d6988a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4665,6 +4665,7 @@ public import Mathlib.Geometry.Manifold.Submersion public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.VectorBundle.ContMDiffSection public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.Hom diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean new file mode 100644 index 00000000000000..740d390849c3eb --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -0,0 +1,182 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace + +/-! # Metric connections + +This file defines connections on a Riemannian vector bundle which are compatible with the ambient +metric. A bundled connection `∇` on a Riemannian vector bundle `(V, g)` is compatible with the +metric `g` if and only if the differentiated metric tensor `∇ g` (defined by +`(X, σ, τ) ↦ 𝓛_X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)`) vanishes on all differentiable vector fields +`X` and differentiable sections `σ`, `τ`. + +## Main definitions and results + +* `CovariantDerivative.derivMetricTensor`: the tensor + `(X, σ, τ) ↦ 𝓛_X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)` defining when a connection `∇` on a + Riemannian vector bundle `(V, g)` is compatible with the metric `g`. +* `CovariantDerivative.derivMetricTensor_apply` and + `CovariantDerivative.derivMetricTensor_apply_eq_extend` give formulas for applying + the compatibility tensor at `x` to vector fields and sections which are differentiable at `x`, + resp. to extensions of tangent vectors and sections at `x` to differentiable vector fields and + sections near `x`. +* `CovariantDerivative.IsMetricCompatible`: predicate for a connection to be metric, namely that + `∇` is metric iff its `derivMetricTensor` vanishes + +## TODO + +* When Mathlib has a notion of parallel transport, prove the equivalence of + `CovariantDerivative.IsMetricCompatible` with the characterisation that parallel transport be an + isometry. + +* Given connections on bundles `V` and `W`, there is an induced connnection on the bundle + `Hom(V, W)`. When this induced connection has been defined in Mathlib, rephrase the definition of + `CovariantDerivative.derivMetricTensor`, to be simply the covariant derivative of the + metric tensor (considered as a section of `Hom(V, Hom(V, ℝ))`). + +-/ +open Bundle NormedSpace +open scoped Manifold ContDiff + +variable + -- Let `M` be a real manifold modeled on `(E, H)` + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + -- Let `V` be a bundle over `M` with standard fiber `F`. + {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, NormedAddCommGroup (V x)] [∀ x, InnerProductSpace ℝ (V x)] [FiberBundle F V] + +/-! # Compatible connections + +A connection on `V` is compatible with the metric on `V` iff `𝓛_X ⟨σ, τ⟩ = ⟨∇_X σ, τ⟩ + ⟨σ, ∇_X τ⟩` +holds for all sufficiently nice vector fields `X` on `M` and sections `σ`, `τ` of `V`. +The left hand side is the Lie derivative of the function `⟨σ, τ⟩` w.r.t. the vector field `X`: +its value at `x` is `df(X x)`, where `f := ⟨σ, τ⟩` (ie. `X` is seen a derivation on the algebra +of functions on the base manifold acting on the function `⟨σ, τ⟩`). +In our definition, we ask for this identity to hold at each `x : M`, whenever `X`, `σ` and `τ` are +differentiable at `x`. +-/ + +variable {σ σ' σ'' τ τ' τ'' : Π x : M, V x} + +local notation "⟪" σ ", " τ "⟫" => fun x ↦ inner ℝ (σ x) (τ x) + +namespace CovariantDerivative + +-- Let `cov` be a covariant derivative on `V`. +variable (cov : CovariantDerivative I F V) + +/-- Local notation for a covariant derivative on a vector bundle acting on a vector field and a +section. -/ +local syntax "∇" term:arg term : term +local macro_rules | `(∇ $X $σ) => `(fun (x : M) ↦ cov $σ x ($X x)) + +/-- The function defining the compatibility tensor for `∇` w.r.t. `g`: +prefer using `derivMetricTensor` instead -/ +noncomputable def derivMetricTensorAux (σ τ : Π x : M, V x) (x : M) : TangentSpace I x →L[ℝ] ℝ := + d% ⟪σ, τ⟫ x - innerSL ℝ (τ x) ∘L cov σ x - innerSL ℝ (σ x) ∘L cov τ x + +@[simp] +lemma derivMetricTensorAux_apply (σ τ : Π x : M, V x) {x : M} (X₀ : TangentSpace I x) : + derivMetricTensorAux I cov σ τ x X₀ = + d% ⟪σ, τ⟫ x X₀ - inner ℝ (cov σ x X₀) (τ x) - inner ℝ (σ x) (cov τ x X₀) := by + rw [real_inner_comm] + rfl + +-- From now on, assume `V` is a vector bundle endowed with a `C¹` Riemannian metric. +variable [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {x : M} + +theorem tensorial_derivMetricTensorAux₁ (τ : Π x, V x) (hτ : MDiffAt (T% τ) x) : + TensorialAt I F (derivMetricTensorAux I cov · τ x) x where + smul hf hσ := by + ext X₀ + simp [mvfderiv_fun_mul hf (hσ.inner_bundle hτ), + cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_left, inner_smul_left] + ring + add hσ hσ' := by + ext X₀ + simp [mvfderiv_fun_add (hσ.inner_bundle hτ) (hσ'.inner_bundle hτ), + cov.isCovariantDerivativeOn.add hσ hσ', inner_add_left] + abel + +theorem tensorial_derivMetricTensorAux₂ (σ : Π x, V x) (hσ : MDiffAt (T% σ) x) : + TensorialAt I F (derivMetricTensorAux I cov σ · x) x where + smul hf hτ := by + ext X₀ + simp [mvfderiv_fun_mul hf (hσ.inner_bundle hτ), + cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, inner_smul_right] + ring + add hτ hτ' := by + ext X₀ + simp [mvfderiv_fun_add (hσ.inner_bundle hτ) (hσ.inner_bundle hτ'), + cov.isCovariantDerivativeOn.add hτ hτ', inner_add_right] + abel + +variable {I} [ContMDiffVectorBundle 1 F V I] in +/-- The tensor `(X, σ, τ) ↦ X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)` defining when a connection +`∇` on a Riemannian bundle `(M, V)` is compatible with the metric `g`. -/ +public noncomputable def derivMetricTensor [FiniteDimensional ℝ F] (x : M) : + V x →L[ℝ] V x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := + TensorialAt.mkHom₂ (derivMetricTensorAux I cov · · x) _ + (tensorial_derivMetricTensorAux₁ I cov) (tensorial_derivMetricTensorAux₂ I cov) + +variable {X : Π x : M, TangentSpace I x} + +variable {I} [ContMDiffVectorBundle 1 F V I] in +public theorem derivMetricTensor_apply [FiniteDimensional ℝ F] (x : M) + (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + cov.derivMetricTensor x (σ x) (τ x) (X x) = + d% ⟪σ, τ⟫ x (X x) - ⟪∇ X σ, τ⟫ x - ⟪σ, ∇ X τ⟫ x := by + unfold derivMetricTensor + rw [TensorialAt.mkHom₂_apply _ _ hσ hτ, derivMetricTensorAux_apply] + +variable {I} [ContMDiffVectorBundle 1 F V I] in +public theorem derivMetricTensor_apply_eq_extend [FiniteDimensional ℝ F] + (X₀ : TangentSpace I x) (σ₀ τ₀ : V x) : + cov.derivMetricTensor x σ₀ τ₀ X₀ = + d% ⟪(FiberBundle.extend F σ₀), (FiberBundle.extend F τ₀)⟫ x X₀ + - inner ℝ (cov (FiberBundle.extend F σ₀) x X₀) τ₀ + - inner ℝ σ₀ (cov (FiberBundle.extend F τ₀) x X₀) := by + simp [derivMetricTensor, TensorialAt.mkHom₂_apply_eq_extend] + +variable {I} [ContMDiffVectorBundle 1 F V I] in +/-- Predicate saying that a connection `∇` on a Riemannian bundle `(V, g)` is compatible with the +ambient metric, i.e. for all differentiable vector fields `X` on `M` and sections `σ` and `τ` of +`V`, we have `X ⟨σ, τ⟩ = ⟨∇_X σ, τ⟩ + ⟨σ, ∇_X τ⟩`. -/ +public def IsMetricCompatible [FiniteDimensional ℝ F] : Prop := derivMetricTensor cov = 0 + +variable {I} [ContMDiffVectorBundle 1 F V I] + +variable {cov} in +public lemma IsMetricCompatible.mvfderiv_inner_eq [FiniteDimensional ℝ F] + (hcov : cov.IsMetricCompatible) {x : M} (X : Π x, TangentSpace I x) {σ τ : (x : M) → V x} + (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + d% ⟪σ, τ⟫ x (X x) = ⟪∇ X σ, τ⟫ x + ⟪σ, ∇ X τ⟫ x := by + have H := congr($hcov x (σ x) (τ x) (X x)) + simp [derivMetricTensor_apply _ _ hσ hτ] at H + linear_combination H + +variable [IsManifold I 1 M] + +public lemma isMetricCompatible_iff [FiniteDimensional ℝ F] : + cov.IsMetricCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {σ τ : (x : M) → V x}, + MDiffAt (T% X) x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + d% ⟪σ, τ⟫ x (X x) = ⟪∇ X σ, τ⟫ x + ⟪σ, ∇ X τ⟫ x := by + refine ⟨fun hcov x X σ τ hX ↦ hcov.mvfderiv_inner_eq X, fun h ↦ ?_⟩ + ext1 x + apply VectorBundle.injective_eval_mdifferentiableAt_sec I F; ext1 σ; ext1 hσ + apply VectorBundle.injective_eval_mdifferentiableAt_sec I F; ext1 τ; ext1 hτ + apply VectorBundle.injective_eval_mdifferentiableAt_sec I E (TangentSpace I); ext X hX + simp (disch := assumption) [derivMetricTensor_apply] + linear_combination h hX hσ hτ + +end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index ac9b4aab75ccf4..b47e572fc3d9b8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -17,9 +17,8 @@ import Mathlib.Geometry.Manifold.Notation public section -open Bundle Set OpenPartialHomeomorph ContinuousLinearMap Pretrivialization Filter - -open scoped Manifold Bundle Topology +open Bundle Set ContinuousLinearMap Pretrivialization Filter +open scoped Manifold Topology section @@ -717,5 +716,25 @@ lemma mdifferentiableAt_extend {x : M} (σ₀ : V x) : MDiffAt (T% (extend F σ₀)) x := (contMDiffAt_extend' (k := 1) I F σ₀).mdifferentiableAt one_ne_zero +variable (V) in +lemma _root_.VectorBundle.injective_eval_mdifferentiableAt_sec [∀ x, Module 𝕜 (V x)] + (W : Type*) [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace W] (x : M) : + Function.Injective + (fun A : V x →L[𝕜] W ↦ + fun (Z : Π x, V x) (_ : MDiffAt (T% Z) x) ↦ A (Z x)) := by + intro X X' h + ext σ₀ + simpa using congr($h (extend F σ₀) (mdifferentiableAt_extend ..)) + +variable (V) in +lemma _root_.VectorBundle.injective_eval_contMDiffAt_sec {n : WithTop ℕ∞} [∀ x, Module 𝕜 (V x)] + (W : Type*) [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace W] (x : M) : + Function.Injective + (fun A : V x →L[𝕜] W ↦ + fun (Z : Π x, V x) (_ : CMDiffAt n (T% Z) x) ↦ A (Z x)) := by + intro X X' h + ext σ₀ + simpa using congr($h (extend F σ₀) (contMDiffAt_extend' ..)) + end FiberBundle end extend From 2ebce3689ad34d0d826baf7191226aefba799996 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Wed, 17 Jun 2026 16:39:03 +0000 Subject: [PATCH 0123/1300] ci(cache): consolidate cache fetching into one action, warmed from master (#40678) Consolidates the build job's cache fetch into a single `get-cache` action. It used to be a 3-step sequence (a cold-cache probe, a landrun verify, then a parent-commit warmup plus the fetch); now one action runs a single HEAD-scoped `cache get`, optionally warmed from a free master snapshot. Two things come out of that: - HEAD-scoped fetch: dropping the parent-commit warmup (which checked out other SHAs and read their cache) means a run reads only its own scope plus the trusted master snapshot, matching the per-commit scope from #40035. - Warmed from master: master's `.ltar` set is otherwise re-read from the paid Azure cache on every cold runner. The master `push` build in `build.yml` now publishes it once as a free `cache-snapshot` artifact, pruned to that commit's set and reusing what is already on disk, so it adds no Azure read. The action seeds `~/.cache/mathlib` from the snapshot at the PR's merge-base (its unchanged files hash identically there), else the newest one at-or-before it, else the latest, before fetching, so the unchanged-from-master oleans come from GitHub rather than Azure. The snapshot download is trust-pinned to master push runs and fail-safe (any problem falls back to a plain Azure `cache get`), and fork-safe because `pull_request_target` runs the base branch's workflow and actions rather than the PR's. Each run logs a warm/cold count. `bors.yml` and `ci_dev.yml` gain read-only `actions: read`. Snapshot retention is 14 days, and `.ltar` are input-hash-keyed, so a stale base falls back gracefully. --- .github/actions/get-cache/action.yml | 95 ++++++++++++++++++++ .github/workflows/bors.yml | 1 + .github/workflows/build.yml | 2 + .github/workflows/build_fork.yml | 7 +- .github/workflows/build_template.yml | 126 ++++++++------------------- .github/workflows/ci_dev.yml | 1 + 6 files changed, 138 insertions(+), 94 deletions(-) create mode 100644 .github/actions/get-cache/action.yml diff --git a/.github/actions/get-cache/action.yml b/.github/actions/get-cache/action.yml new file mode 100644 index 00000000000000..ca5d3a1a2846f7 --- /dev/null +++ b/.github/actions/get-cache/action.yml @@ -0,0 +1,95 @@ +# Get this commit's oleans, in two phases: +# 1. Warm the cache from the `cache-snapshot` GitHub artifact (canonical repo only). +# 2. Fetch this commit's oleans from the remote cache with the trusted master-built binary. +# The fetch is HEAD-scoped (reads only this commit's own cache scope). The warm is fail-safe +# (any failure → just the remote fetch) and its source is hardcoded, so nothing can redirect +# the download off the trusted master pipeline. +name: Get cache +description: Get this commit's oleans into the local cache. +inputs: + working_directory: + description: The lake project to fetch the cache for (e.g. the checked-out PR branch). + required: true + cache_bin: + description: Path to the trusted `cache` binary, relative to `working_directory`. + required: true +runs: + using: composite + steps: + # 1. Warm cache from the GitHub artifact. Resolve which snapshot to use: the one built + # at this commit's merge-base with master (its unchanged files hash identically + # there), else the newest still-retained one at-or-before it, else the latest (a + # merge-base older than retention, or any failure, lands here). Canonical repo only. + - name: Resolve cache snapshot + id: resolve + if: ${{ github.repository == 'leanprover-community/mathlib4' }} + shell: bash + env: + GH_TOKEN: ${{ github.token }} + HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + run: | + set -uo pipefail + runs="repos/leanprover-community/mathlib4/actions/workflows/build.yml/runs?branch=master&event=push&status=success" + + # Each helper prints a matching successful master-push run-id, or empty. + run_at() { gh api "${runs}&head_sha=$1" --jq '.workflow_runs[0].id // empty' 2>/dev/null || true; } + latest_run() { gh api "${runs}&per_page=1" --jq '.workflow_runs[0].id // empty' 2>/dev/null || true; } + # newest run created at-or-before date $1, but not older than cutoff $2 + newest_before() { + gh api "${runs}&per_page=100" 2>/dev/null | jq -r --arg d "$1" --arg c "$2" \ + '[.workflow_runs[] | select(.created_at <= $d and ($c == "" or .created_at >= $c))][0].id // empty' \ + 2>/dev/null || true + } + + # This PR's merge-base with master (+ its commit date), and the cutoff below which + # snapshots have expired (retention ~14d). + mb_info=$(gh api "repos/leanprover-community/mathlib4/compare/master...${HEAD_SHA}" \ + --jq '.merge_base_commit | "\(.sha) \(.commit.committer.date)"' 2>/dev/null || true) + read -r mb mb_date <<< "${mb_info}" + cutoff=$(date -u -d '13 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true) + + # Prefer the merge-base's snapshot (while still retained), then the newest one + # before it, then the latest of all. + run_id="" + if [[ -n "${mb}" && ( -z "${cutoff}" || "${mb_date}" > "${cutoff}" ) ]]; then + run_id=$(run_at "${mb}") + [[ -z "${run_id}" ]] && run_id=$(newest_before "${mb_date}" "${cutoff}") + fi + [[ -z "${run_id}" ]] && run_id=$(latest_run) + + echo "Resolved cache-snapshot run_id: '${run_id}' (merge-base: ${mb:-unknown})" + echo "run_id=${run_id}" >> "$GITHUB_OUTPUT" + + - name: Warm cache from GitHub artifact + if: ${{ steps.resolve.outputs.run_id != '' }} + continue-on-error: true # fail-safe: fall back to the remote fetch (step 2) + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: cache-snapshot + path: /home/lean/.cache/mathlib + repository: leanprover-community/mathlib4 + run-id: ${{ steps.resolve.outputs.run_id }} + github-token: ${{ github.token }} + + # 2. Fetch this commit's oleans from the remote cache with the trusted `cache` binary + # (outside landrun). Runs on every repo; the warm above just gives the canonical + # repo a local head start. HEAD-scoped: reads only this commit's own cache scope. + - name: Fetch cache from remote + shell: bash + env: + WORKDIR: ${{ inputs.working_directory }} + CACHE_BIN: ${{ inputs.cache_bin }} + CACHE_REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + run: | + set -eo pipefail + cd "${WORKDIR}" + rm -rf .lake/build/lib/lean/Mathlib + log="${RUNNER_TEMP:-/tmp}/cache-get.log" + # --repo so fork PRs also read their own repo-namespaced cache (master is read flat, + # so this still gets the master bulk); for in-repo runs it resolves to the same repo. + "${CACHE_BIN}" --repo="${CACHE_REPO}" get 2>&1 | tee "${log}" + # Warmth = how much the snapshot covered HEAD: files already cached locally + # (just decompressed) vs downloaded from Azure. Parsed best-effort from the log. + warm=$(grep -oE 'Decompressing [0-9]+ already-cached' "${log}" | grep -oE '[0-9]+' | head -1 || true) + cold=$(grep -oE 'Attempting to download [0-9]+' "${log}" | grep -oE '[0-9]+' | head -1 || true) + echo "Cache warmth: ${warm:-0} already-cached (warm) / ${cold:-0} downloaded from Azure (cold)" diff --git a/.github/workflows/bors.yml b/.github/workflows/bors.yml index b6fc3e849b538c..a9eaf8fd68886f 100644 --- a/.github/workflows/bors.yml +++ b/.github/workflows/bors.yml @@ -16,6 +16,7 @@ concurrency: permissions: contents: read id-token: write + actions: read # download master artifacts (tools-bin, cache-snapshot) pull-requests: write # Only allow PR comments/labels # All other permissions are implicitly 'none' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 120bd6ae6ba196..db56bf6f261e22 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,5 +70,7 @@ jobs: && 'cache-upload-forks' || '' }} + # the single producer: the master `push` build + publish_cache: ${{ github.repository == 'leanprover-community/mathlib4' && github.event_name == 'push' && github.ref == 'refs/heads/master' }} runs_on: pr secrets: inherit diff --git a/.github/workflows/build_fork.yml b/.github/workflows/build_fork.yml index addc86f66e546c..36a435275dc222 100644 --- a/.github/workflows/build_fork.yml +++ b/.github/workflows/build_fork.yml @@ -9,10 +9,9 @@ on: - 'staging*.tmp' - 'nolints' paths-ignore: - # pull_request_target uses the workflow from the target branch: - # PR changes under this directory won't affect this run, so - # running it is just wasteful - - '.github/workflows/**' + # pull_request_target runs the workflow and its actions from the target branch, not + # the PR, so PR changes under these dirs can't affect the run — triggering is wasteful. + - '.github/**' concurrency: # label each workflow run; only the latest with each label will run diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 5b0676dd6245e7..511e19544781d5 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -33,6 +33,12 @@ on: # federated credential is scoped to; it must match the writer `cache_application_id`. type: string required: true + publish_cache: + # On a successful build, publish this run's `.ltar` set as `cache-snapshot`. + # Set by callers ONLY for the master-`push` build — the single producer. + type: boolean + required: false + default: false env: # Disable Lake's automatic fetching of cloud builds. @@ -51,7 +57,6 @@ jobs: archive-outcome: ${{ steps.archive.outcome }} counterexamples-outcome: ${{ steps.counterexamples.outcome }} cache-staging-has-files: ${{ steps.cache_staging_check.outputs.has_files }} - get-cache-outcome: ${{ steps.get.outcome }} lint-outcome: ${{ steps.lint.outcome }} mk_all-outcome: ${{ steps.mk_all.outcome }} noisy-outcome: ${{ steps.noisy.outcome }} @@ -313,95 +318,12 @@ jobs: echo "✅ All inputRevs in lake-manifest.json are valid" fi - - name: get cache (1/3 - setup and initial fetch) - id: get_cache_part1_setup - shell: bash # only runs `cache get` from `tools-branch`, so doesn't need to be inside landrun - run: | - cd pr-branch - echo "Removing old Mathlib build directories prior to cache fetch..." - rm -rf .lake/build/lib/lean/Mathlib - - # Fail quickly if the cache is completely cold, by checking for Mathlib.Init - echo "Attempting to fetch olean for Mathlib/Init.lean from cache..." - ../tools-branch/.lake/build/bin/cache get Mathlib/Init.lean - - - name: get cache (2/3 - test Mathlib.Init cache) - id: get_cache_part2_test - continue-on-error: true # Allow workflow to proceed to Part 3 to check outcome - # This step uses the job's default shell, which is landrun-wrapped bash - run: | - cd pr-branch - - echo "Attempting: lake build --no-build -v Mathlib.Init (this runs under landrun)" - lake build --no-build -v Mathlib.Init - - - name: get cache (3/3 - finalize cache operation) - id: get - shell: bash # only runs git and `cache get` from `tools-branch`, so doesn't need to be inside landrun - env: - BEFORE_SHA: ${{ github.event.before || '' }} - BASE_SHA: ${{ github.event.pull_request.base.sha || '' }} - CACHE_REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - run: | - cd pr-branch - if [[ "${{ steps.get_cache_part2_test.outcome }}" != "success" ]]; then - echo "WARNING: 'lake build --no-build -v Mathlib.Init' failed." - echo "No cache for 'Mathlib.Init' available or it could not be prepared." - exit 0 - fi - - ORIG_SHA="$(git rev-parse HEAD)" - PREV_SHA="" - PREV_SHA_SOURCE="" - - # When a ref is newly created, github.event.before can be all-zero. - if [[ "$BEFORE_SHA" =~ ^0{40}$ ]]; then - BEFORE_SHA="" - fi - - if [[ -n "$BEFORE_SHA" ]]; then - PREV_SHA="$BEFORE_SHA" - PREV_SHA_SOURCE="github.event.before" - elif [[ -n "$BASE_SHA" ]]; then - PREV_SHA="$BASE_SHA" - PREV_SHA_SOURCE="pull_request.base.sha" - else - PREV_SHA="$(git rev-parse --verify --quiet HEAD^ || true)" - if [[ -n "$PREV_SHA" ]]; then - PREV_SHA_SOURCE="HEAD^" - fi - fi - - if [[ -n "$PREV_SHA" ]]; then - # cf. https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Mathlib.20has.20moved.20to.20the.20new.20module.20system/near/563452000 - echo "Warming up cache using previous commit: $PREV_SHA (source: $PREV_SHA_SOURCE)" - if git cat-file -e "$PREV_SHA^{commit}" 2>/dev/null || git fetch --no-tags --depth=1 origin "$PREV_SHA"; then - # Skip warmup if the previous commit uses a different toolchain - PREV_TOOLCHAIN=$(git show "$PREV_SHA:lean-toolchain" 2>/dev/null || true) - if [[ "$PREV_TOOLCHAIN" != "$(cat lean-toolchain)" ]]; then - echo "Previous commit $PREV_SHA uses a different toolchain ($PREV_TOOLCHAIN); skipping warmup." - else - git checkout "$PREV_SHA" - ../tools-branch/.lake/build/bin/cache get - # Run again with --repo, to ensure we actually get the oleans. - ../tools-branch/.lake/build/bin/cache --repo="$CACHE_REPO" get - - echo "Switching back to branch head" - git checkout "$ORIG_SHA" - fi - else - echo "Could not fetch $PREV_SHA; skipping parent warmup cache fetch." - fi - else - echo "No previous commit candidate found; skipping parent warmup cache fetch." - fi - - echo "Fetching all remaining cache..." - - ../tools-branch/.lake/build/bin/cache get - - # Run again with --repo, to ensure we actually get the oleans. - ../tools-branch/.lake/build/bin/cache --repo="$CACHE_REPO" get + # Get this commit's oleans into the local cache — see the action for the steps. + - name: Get cache + uses: ./workflow-actions/.github/actions/get-cache + with: + working_directory: pr-branch + cache_bin: ../tools-branch/.lake/build/bin/cache - name: update {Mathlib, Tactic, Counterexamples, Archive}.lean id: mk_all @@ -522,6 +444,30 @@ jobs: name: cache-staging path: cache-staging/ + # Prune to this commit's `.ltar` set so the published snapshot is exactly master's + # current cache (the local dir also holds the previous snapshot it warmed from). + - name: prune local cache to this commit's set + if: ${{ inputs.publish_cache && steps.build.outcome == 'success' }} + continue-on-error: true # best-effort; never fail the build + shell: bash # runs the trusted tools-branch `cache` binary, so no landrun needed + run: | + cd pr-branch + ../tools-branch/.lake/build/bin/cache clean + + # Publish this run's pruned `.ltar` set as `cache-snapshot` for other runs to warm + # from. Already on disk (no Azure egress) and already zstd-compressed (skip + # recompression); retention covers how far back a PR's merge-base can be matched. + - name: upload cache snapshot warming artifact + if: ${{ inputs.publish_cache && steps.build.outcome == 'success' }} + continue-on-error: true # best-effort; never fail the build + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: cache-snapshot + path: /home/lean/.cache/mathlib/*.ltar + compression-level: 0 + retention-days: 14 + if-no-files-found: warn + - name: Check if building Archive or Counterexamples failed if: steps.archive.outcome == 'failure' || steps.counterexamples.outcome == 'failure' run: | diff --git a/.github/workflows/ci_dev.yml b/.github/workflows/ci_dev.yml index c2bd37019314c1..5b394f44cd2d88 100644 --- a/.github/workflows/ci_dev.yml +++ b/.github/workflows/ci_dev.yml @@ -28,6 +28,7 @@ on: permissions: contents: read id-token: write + actions: read # read-only: download master artifacts (tools-bin, cache-snapshot) # By default let's remove this permission (which is present in the other build pipelines) # from the CI experimentation runs to avoid unwitting side effects # pull-requests: write From 60d8e4f973821226de51b3688df20433325c7f58 Mon Sep 17 00:00:00 2001 From: Sabrina Jewson <58880148+SabrinaJewson@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:44:29 +0000 Subject: [PATCH 0124/1300] feat(Order): add conversions from `Std` order typeclasses to Mathlib ones (#37718) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `{Preorder, PartialOrder, LinearOrder}.ofStd` exist to facilitate convenient translation from `Std` order typeclasses to Mathlib ones. The design is modelled closely after [`Init.Data.Order.PackageFactories`](https://leanprover-community.github.io/mathlib4_docs/Init/Data/Order/PackageFactories.html) (`Std.PreorderPackage` is equivalent-ish to Mathlib’s `Preorder`, and same for partial and linear orders). The `OfStdArgs` types allow conveniently bundling a whole bunch of default arguments together in a way that allows one default argument set to `extends` another. Co-authored-by: SabrinaJewson --- Mathlib.lean | 1 + Mathlib/Order/Std.lean | 289 ++++++++++++++++++++++++++++++++++++ MathlibTest/OrderOfStd.lean | 101 +++++++++++++ 3 files changed, 391 insertions(+) create mode 100644 Mathlib/Order/Std.lean create mode 100644 MathlibTest/OrderOfStd.lean diff --git a/Mathlib.lean b/Mathlib.lean index 631fc974d6988a..a7c7d7b349bc80 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6164,6 +6164,7 @@ public import Mathlib.Order.SetDissipate public import Mathlib.Order.SetIsMax public import Mathlib.Order.SetNotation public import Mathlib.Order.Shrink +public import Mathlib.Order.Std public import Mathlib.Order.Sublattice public import Mathlib.Order.Sublocale public import Mathlib.Order.SuccPred.Archimedean diff --git a/Mathlib/Order/Std.lean b/Mathlib/Order/Std.lean new file mode 100644 index 00000000000000..cc4f6df8be5f5f --- /dev/null +++ b/Mathlib/Order/Std.lean @@ -0,0 +1,289 @@ +/- +Copyright (c) 2026 Sabrina Jewson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sabrina Jewson +-/ +module + +public import Mathlib.Order.Defs.LinearOrder + +/-! +# Converting Std order typeclasses into Mathlib ones + +This file provides factories for creating Mathlib order typeclasses (`PartialOrder`, `LinearOrder`) +from Std ones. + +When all instances are present, the factories may be used without arguments: + +```lean +instance : LinearOrder X := .ofStd X +``` + +Otherwise, it may be necessary to provide some instances manually: + +```lean +instance : LinearOrder X := .ofStd X + { lawfulOrderOrd := sorry } +``` + +When existing instances of typeclasses exist, they will be preferred; otherwise, they will be +generated automatically. + +## Implementation notes + +This module's job is to take a bunch of autoparams filled in with all the ways we could synthesize +order typeclasses from `Std` and bundle them into a Mathlib order typeclass. We also need +inheritance of sets of autoparams, because `PartialOrder.ofStd` takes all the autoparams of +`Preorder.ofStd` and then some. + +To achieve this, each set of autoparams becomes a structure called `OfStdArgs` (thereby allowing it +to extend existing `OfStdArgs` structures), and the synthesization scripts are in the default field +values of this type. For the user, a simple `{}` will synthesize all fields of the structure with +tactics, while individual fields that fail to synthesize may be specified using `{ field := … }`. + +The autoparam tactic scripts prioritize existing instances if they exist, to prevent diamonds, +and in such cases require extra `Prop` typeclasses to ensure everyone agrees on the order. +Otherwise, those agreement typeclasses can be synthesized with tactics automatically. + +Often, we write `let := someField` in the type of the structure fields, followed by `extract_lets` +in the tactic body. This is done to make sure that `someField` is an instance that can be found by +typeclass search in the tactic body: in the case where `someField` is generated by some means other +than typeclass inference, it does not exist as a local variable otherwise. +-/ + +public section + +/-- Arguments for `Preorder.ofStd`; see that function for details. -/ +structure Preorder.OfStdArgs (α : Type*) where + /-- The `LE` instance of the order. -/ + le : LE α := by + first + | infer_instance + | exact LE.ofOrd _ + | fail "failed to infer `LE` instance; \ + make sure you have an `LE` or `Ord` instance" + /-- The `LT` instance of the order. -/ + lt : + let := le + LT α := by + extract_lets + first + | infer_instance + | exact ⟨fun a b ↦ a ≤ b ∧ ¬b ≤ a⟩ + /-- `a < b` is equivalent to `a ≤ b ∧ ¬b ≤ a`. -/ + lawfulOrderLT : + let := le; let := lt + Std.LawfulOrderLT α := by + extract_lets + first + /- Try the case where `LT` is synthesized from `LE` first so the error message points to the + lack of an instance and not the lack of a definitional equality. -/ + | exact ⟨fun _ _ ↦ _root_.Iff.rfl⟩ + | infer_instance + /-- ≤ forms a preorder. -/ + isPreorder : + let := le + Std.IsPreorder α := by + extract_lets + first + | infer_instance + | exact _root_.Std.IsLinearPreorder.of_ord.toIsPreorder + | fail "failed to infer `Std.IsPreorder` instance; \ + make sure you have an `Std.IsPreorder` instance \ + or `Std.LawfulOrderOrd` and `Std.TransOrd` instances" + +/-- Create a `Preorder` from a type satisfying `Std.IsPreorder`. + +If an `LE` instance exists, either an `Std.IsPreorder` instance must exist, or there must be an +`Ord` instance together with `Std.LawfulOrderOrd` and `Std.TransOrd` instances. + +If no `LE` instance exists, it can be generated from `Ord` and `Std.TransOrd` instances. + +If an `LT` instance exists, an `Std.LawfulOrderLT` instance must exist also; otherwise, a suitable +`LT` instance will be generated. -/ +@[expose, implicit_reducible] +def Preorder.ofStd (α : Type*) (args : OfStdArgs α := by exact {}) : Preorder α where + toLE := args.le + toLT := args.lt + le_refl := args.isPreorder.le_refl + le_trans := args.isPreorder.le_trans + lt_iff_le_not_ge := args.lawfulOrderLT.lt_iff + +/-- Arguments for `PartialOrder.ofStd`; see that function for details. -/ +structure PartialOrder.OfStdArgs (α : Type*) extends toPreorderArgs : Preorder.OfStdArgs α where + /-- ≤ forms a partial order. -/ + isPartialOrder : + let := le + Std.IsPartialOrder α := by + extract_lets + first + | infer_instance + | exact _root_.Std.IsLinearOrder.of_ord.toIsPartialOrder + | fail "failed to infer `Std.IsPartialOrder` instance; \ + make sure you have an `Std.IsPartialOrder` instance \ + or `LawfulOrderOrd`, `LawfulEqOrd` and `TransOrd` instances" + +/-- Create a `PartialOrder` from a type satisfying `Std.IsPartialOrder`. + +If an `LE` instance exists, either an `Std.IsPartialOrder` instance must exist, or there must be an +`Ord` instance together with `Std.LawfulOrderOrd`, `Std.LawfulEqOrd`, and `Std.TransOrd` instances. + +If no `LE` instance exists, it can be generated from `Ord`, `Std.LawfulEqOrd`, and `Std.TransOrd` +instances. + +If an `LT` instance exists, an `Std.LawfulOrderLT` instance must exist also; otherwise, a suitable +`LT` instance will be generated. -/ +@[expose, implicit_reducible] +def PartialOrder.ofStd (α : Type*) (args : OfStdArgs α := by exact {}) : PartialOrder α where + toPreorder := .ofStd α args.toPreorderArgs + le_antisymm := args.isPartialOrder.le_antisymm + +/- Although Batteries provides that `compareOfLessAndEq` satisfies `LawfulLECmp`, there is +unfortunately no link between that and `LawfulOrderCmp` even though they are essentially the same +thing. -/ +theorem Std.LawfulOrderCmp.compareOfLessAndEq (α : Type*) + [LE α] [LT α] [LawfulOrderLT α] [IsLinearOrder α] [DecidableEq α] [DecidableLT α] : + LawfulOrderCmp (fun a b : α ↦ compareOfLessAndEq a b) := + let : Ord α := ⟨fun a b : α ↦ _root_.compareOfLessAndEq a b⟩ + { isLE_compare _ _ := + have : DecidableLE α := fun _ _ ↦ Classical.propDecidable _ + isLE_compareOfLessAndEq Std.le_antisymm Std.not_le (fun _ _ ↦ Std.le_total) + isGE_compare _ _ := + have : DecidableLE α := fun _ _ ↦ Classical.propDecidable _ + isGE_compareOfLessAndEq Std.le_antisymm Std.not_le (fun _ _ ↦ Std.le_total) } + +/-- Arguments for `LinearOrder.ofStd`; see that function for details. -/ +structure LinearOrder.OfStdArgs (α : Type*) extends + toPartialOrderArgs : PartialOrder.OfStdArgs α where + /-- ≤ forms a linear order. -/ + isLinearOrder : + let := le + Std.IsLinearOrder α := by + extract_lets + first + | infer_instance + | exact _root_.Std.IsLinearOrder.of_ord + | fail "failed to infer `Std.IsLinearOrder` instance; \ + make sure you have an `Std.IsLinearOrder` instance \ + or `LawfulOrderOrd`, `LawfulEqOrd` and `TransOrd` instances" + /-- ≤ is decidable. -/ + decidableLE : DecidableLE α := by + first + | infer_instance + | exact _root_.DecidableLE.ofOrd _ + | fail "failed to infer `DecidableLE` instance; \ + make sure you have a `DecidableLE` instance \ + or a `LawfulOrderOrd` instance" + /-- = is decidable. This can always be automatically derived from `decidableLE`. -/ + decidableEq : + let := toPartialOrderArgs; let := decidableLE + DecidableEq α := by + extract_lets _ toPartialOrderArgs + first + | infer_instance + | exact @_root_.decidableEqOfDecidableLE _ (.ofStd _ toPartialOrderArgs) _ + /-- < is decidable. This can always be automatically derived from `decidableLE`. -/ + decidableLT : + let := toPreorderArgs; let := decidableLE + DecidableLT α := by + extract_lets _ toPreorderArgs + first + | infer_instance + | exact @_root_.decidableLTOfDecidableLE _ (.ofStd _ toPreorderArgs) _ + /-- The `Min` instance of the order. This can always be automatically derived. -/ + min : + let := le; let := decidableLE + Min α := by + extract_lets + first + | infer_instance + | exact _root_.Min.leftLeaningOfLE _ + /-- The `Max` instance of the order. This can always be automatically derived. -/ + max : + let := le; let := decidableLE + Max α := by + extract_lets + first + | infer_instance + | exact _root_.Max.leftLeaningOfLE _ + /-- `min a b` is equivalent to `if a ≤ b then a else b`. -/ + lawfulOrderLeftLeaningMin : Std.LawfulOrderLeftLeaningMin α := by infer_instance + /-- `max a b` is equivalent to `if b ≤ a then a else b`. -/ + lawfulOrderLeftLeaningMax : Std.LawfulOrderLeftLeaningMax α := by infer_instance + /-- The `Ord` instance of the order. This can always be automatically derived. -/ + ord : + let := lt; let := decidableEq; let := decidableLT + Ord α := by + extract_lets + first + | infer_instance + | exact ⟨fun a b ↦ _root_.compareOfLessAndEq a b⟩ + /-- `Ord` is compatible with ≤. -/ + lawfulOrderOrd : + let := le; let := lt; let := lawfulOrderLT; let := isLinearOrder + let := decidableEq; let := decidableLT + Std.LawfulOrderOrd α := by + extract_lets + first + /- Try the case where `Ord` is synthesized from `compareOfLessAndEq` first so the error message + points to the lack of an instance and not the lack of a definitional equality. -/ + | exact _root_.Std.LawfulOrderCmp.compareOfLessAndEq _ + | infer_instance + +/-- Create a `LinearOrder` from a type satisfying `Std.IsLinearOrder`. + +If an `LE` instance exists, either an `Std.IsLinearOrder` instance must exist, or there must be an +`Ord` instance together with `Std.LawfulOrderOrd`, `Std.LawfulEqOrd`, and `Std.TransOrd` instances. + +If no `LE` instance exists, it can be generated from `Ord`, `Std.LawfulEqOrd`, and `Std.TransOrd` +instances. + +If an `LT` instance exists, an `Std.LawfulOrderLT` instance must exist also; otherwise, a suitable +`LT` instance will be generated. + +If a `DecidableLE` instance exists, it will be used. Otherwise, it can be generated from an `Ord` +instance. + +If `DecidableEq` and `DecidableLT` instances exist, they will be used. Otherwise, they will be +generated from the `DecidableLE` instance. + +If `Min` and `Max` instances exist, they will be used, in which case the user must provide +`Std.LawfulOrderLeftLeaningMin` or `Std.LawfulOrderLeftLeaningMax` respectively. Otherwise, they +will be generated. + +If an `Ord` instance exists, it will be used, in which case the user must provide an +`Std.LawfulOrderOrd` instance. Otherwise, it will be generated. -/ +@[expose, implicit_reducible] +def LinearOrder.ofStd (α : Type*) (args : OfStdArgs α := by exact {}) : LinearOrder α := + let := args.le + let := args.lt + have := args.lawfulOrderLT + have := args.isLinearOrder + let := args.decidableLE + have := args.lawfulOrderLeftLeaningMin + have := args.lawfulOrderLeftLeaningMax + { toPartialOrder := .ofStd _ args.toPartialOrderArgs + le_total := args.isLinearOrder.le_total + toDecidableLE := args.decidableLE + toDecidableEq := args.decidableEq + toDecidableLT := args.decidableLT + toMin := args.min + toMax := args.max + min_def _ _ := Std.min_eq_if + max_def a b := by + rw [Std.max_eq_if] + split + · split + · exact Std.le_antisymm ‹_› ‹_› + · rfl + case _ h => rw [if_pos (Std.le_of_lt (Std.not_le.mp h))] + toOrd := args.ord + compare_eq_compareOfLessAndEq a b := by + let := args.ord + have := args.lawfulOrderOrd + rw [compareOfLessAndEq] + split_ifs + case _ => rwa [Std.compare_eq_lt] + case _ => rwa [Std.compare_eq_iff_eq] + case _ h h' => + exact Std.compare_eq_gt.mpr <| Std.lt_of_le_of_ne (Std.not_lt.mp h) (Ne.symm h') } diff --git a/MathlibTest/OrderOfStd.lean b/MathlibTest/OrderOfStd.lean new file mode 100644 index 00000000000000..543d1185512d61 --- /dev/null +++ b/MathlibTest/OrderOfStd.lean @@ -0,0 +1,101 @@ +module +import Mathlib.Order.Std + +namespace PreorderFromLE + +def X := Nat deriving LE, Std.IsPreorder +instance h : Preorder X := .ofStd X {} +example : h.toLE = instLEX := rfl +example {a b : X} : h.lt a b ↔ instLEX.le a b ∧ ¬instLEX.le b a := Iff.rfl + +end PreorderFromLE + +namespace PreorderFromLELT + +def X := Nat deriving LE, LT, Std.LawfulOrderLT, Std.IsPreorder +attribute [irreducible] instLEX instLTX +instance h : Preorder X := .ofStd X {} +example : h.toLE = instLEX := rfl +example : h.toLT = instLTX := rfl + +end PreorderFromLELT + +namespace PreorderFromOrd + +def X := Nat deriving Ord, Std.TransOrd +instance h : Preorder X := .ofStd X {} +example {a b} : h.le a b ↔ (instOrdX.compare a b).isLE := Iff.rfl +example {a b} : h.lt a b ↔ (instOrdX.compare a b).isLE ∧ ¬(instOrdX.compare b a).isLE := Iff.rfl + +end PreorderFromOrd + +namespace PartialOrderFromLE + +def X := Nat deriving LE, Std.IsPartialOrder +instance h : PartialOrder X := .ofStd X {} +example : h.toLE = instLEX := rfl + +end PartialOrderFromLE + +namespace LinearOrderFromLE + +def X := Nat deriving LE, Std.IsLinearOrder, DecidableLE +instance h : LinearOrder X := .ofStd X {} +example : h.toLE = instLEX := rfl +example {a b} : h.toOrd.compare a b = compareOfLessAndEq a b := rfl + +end LinearOrderFromLE + +-- If `DecidableEq`, `DecidableLT`, `Min` and `Max` instances exist, they are preserved. +namespace DecidableMinMaxInstances + +def X := Nat +deriving + LE, LT, Std.LawfulOrderLT, Std.IsLinearOrder, + DecidableLE, DecidableEq, DecidableLT, + Min, Max, Std.LawfulOrderLeftLeaningMin, Std.LawfulOrderLeftLeaningMax +attribute [irreducible] instDecidableEqX instDecidableLTX instMinX instMaxX +instance h : LinearOrder X := .ofStd X {} +example : h.toDecidableEq = instDecidableEqX := rfl +example : h.toDecidableLT = instDecidableLTX := rfl +example : h.toMin = instMinX := rfl +example : h.toMax = instMaxX := rfl + +end DecidableMinMaxInstances + +-- Generate `LE` from `Ord` +namespace FromOrd + +def X := Nat deriving Ord, Std.TransOrd, Std.LawfulEqOrd +attribute [irreducible] instOrdX +instance h : LinearOrder X := .ofStd X +example : h.toOrd = instOrdX := rfl +example {a b} : h.le a b ↔ (instOrdX.compare a b).isLE := Iff.rfl +example {a b} : h.lt a b ↔ (instOrdX.compare a b).isLE ∧ ¬(instOrdX.compare b a).isLE := Iff.rfl +example : h.toMin = .leftLeaningOfLE X := rfl +example : h.toMax = .leftLeaningOfLE X := rfl + +end FromOrd + +-- Transfer the properties of `Ord` over to the properties of `LE` +namespace FromLEOrdViaOrd + +def X := Nat deriving LE, Ord, Std.TransOrd, Std.LawfulOrderOrd, Std.LawfulEqOrd +attribute [irreducible] instLEX instOrdX +instance h : LinearOrder X := .ofStd X +example : h.toLE = instLEX := rfl +example : h.toOrd = instOrdX := rfl + +end FromLEOrdViaOrd + +-- Transfer the properties of `LE` over to the properties of `Ord` +namespace FromLEOrdViaLE + +def X := Nat deriving LE, Std.IsLinearOrder, DecidableLE, Ord, Std.LawfulOrderOrd +attribute [irreducible] instLEX instDecidableLEX instOrdX +instance h : LinearOrder X := .ofStd X +example : h.toLE = instLEX := rfl +example : h.toDecidableLE = instDecidableLEX := rfl +example : h.toOrd = instOrdX := rfl + +end FromLEOrdViaLE From 83a621b2967b53d00417992c770f6ffc232771ba Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:44:31 +0000 Subject: [PATCH 0125/1300] feat: generalize `OpenPartialHomeomorph.Defs` file to `PartialHomeomorph` (#39084) Add `PartialHomeomorph`, which generalises `OpenPartialHomoemorph` by dropping the condition that the source and target be open. In other words, an `OpenPartialHomeomorph` is a `PartialHomeomorph` that additionally has open source and target. This generalisation should find uses for manifolds (extended charts are `PartialHomeomorph`s, but their target is not open for manifolds with boundary). For CW complexes, we will want a `ClosedPartialHomeomorph`: this allows re-using results as much as possible. This PR adds the basic definitions; future PRs will add additional material: #39071 indicates what the eventual result may be. Zulip discussion: [#mathlib4 > Generalizing `PartialHomeomorph`?](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Generalizing.20.60PartialHomeomorph.60.3F/with/536896273) --- Mathlib.lean | 1 + .../Geometry/Manifold/ContMDiffMFDeriv.lean | 4 +- .../Geometry/Manifold/IsManifold/Basic.lean | 2 +- .../Geometry/Manifold/LocalDiffeomorph.lean | 2 +- .../Manifold/LocalSourceTargetProperty.lean | 2 +- .../CanonicalEmbedding/NormLeOne.lean | 7 +- .../Topology/FiberBundle/Trivialization.lean | 4 +- .../Topology/OpenPartialHomeomorph/Basic.lean | 4 +- .../OpenPartialHomeomorph/Composition.lean | 9 +- .../OpenPartialHomeomorph/Constructions.lean | 6 +- .../Topology/OpenPartialHomeomorph/Defs.lean | 49 ++-- .../OpenPartialHomeomorph/IsImage.lean | 5 +- Mathlib/Topology/PartialHomeomorph/Defs.lean | 226 ++++++++++++++++++ 13 files changed, 277 insertions(+), 44 deletions(-) create mode 100644 Mathlib/Topology/PartialHomeomorph/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index a7c7d7b349bc80..d03479050e91f0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -8038,6 +8038,7 @@ public import Mathlib.Topology.Order.T5 public import Mathlib.Topology.Order.UpperLowerSetTopology public import Mathlib.Topology.Order.WithTop public import Mathlib.Topology.Partial +public import Mathlib.Topology.PartialHomeomorph.Defs public import Mathlib.Topology.PartitionOfUnity public import Mathlib.Topology.Path public import Mathlib.Topology.Perfect diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index fe370981f4d96c..d5747cf0dbe93d 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -455,7 +455,7 @@ lemma contMDiff_equivTangentBundleProd_symm : filter_upwards [chart_source_mem_nhds (ModelProd (ModelProd H E) (ModelProd H' E')) (a, b)] with p hp -- now we have to check that the original map coincides locally with `pM` read in target chart. - simp only [prodChartedSpace_chartAt, OpenPartialHomeomorph.prod_toPartialEquiv, + simp only [prodChartedSpace_chartAt, OpenPartialHomeomorph.prod_toPartialHomeomorph, PartialEquiv.prod_source, mem_prod, TangentBundle.mem_chart_source_iff] at hp let φ (x : E) := I ((chartAt H a.proj) ((chartAt H p.1.proj).symm (I.symm x))) have D0 : DifferentiableWithinAt 𝕜 φ (Set.range I) (I ((chartAt H p.1.proj) p.1.proj)) := by @@ -494,7 +494,7 @@ lemma contMDiff_equivTangentBundleProd_symm : filter_upwards [chart_source_mem_nhds (ModelProd (ModelProd H E) (ModelProd H' E')) (a, b)] with p hp -- now we have to check that the original map coincides locally with `pM'` read in target chart. - simp only [prodChartedSpace_chartAt, OpenPartialHomeomorph.prod_toPartialEquiv, + simp only [prodChartedSpace_chartAt, OpenPartialHomeomorph.prod_toPartialHomeomorph, PartialEquiv.prod_source, mem_prod, TangentBundle.mem_chart_source_iff] at hp let φ (x : E') := I' ((chartAt H' b.proj) ((chartAt H' p.2.proj).symm (I'.symm x))) have D0 : DifferentiableWithinAt 𝕜 φ (Set.range I') (I' ((chartAt H' p.2.proj) p.2.proj)) := by diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 79619e7d1384c9..11fbcf447b60bd 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -751,7 +751,7 @@ theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCor e.prod e' ∈ contDiffGroupoid n (I.prod I') := by obtain ⟨he, he_symm⟩ := he obtain ⟨he', he'_symm⟩ := he' - constructor <;> simp only [PartialEquiv.prod_source, OpenPartialHomeomorph.prod_toPartialEquiv, + constructor <;> simp only [OpenPartialHomeomorph.prod_toPartialHomeomorph, contDiffPregroupoid] · have h3 := ContDiffOn.prodMap he he' rw [← I.image_eq, ← I'.image_eq, prod_image_image_eq] at h3 diff --git a/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean b/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean index 6edbe4e85b53d5..db32ceb65a874e 100644 --- a/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean +++ b/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean @@ -105,7 +105,7 @@ namespace PartialDiffeomorph variable (Φ : PartialDiffeomorph I J M N n) /-- A partial diffeomorphism is also a local homeomorphism. -/ -@[expose, simps toPartialEquiv] +@[expose, simps toPartialHomeomorph_toPartialEquiv] def toOpenPartialHomeomorph : OpenPartialHomeomorph M N where toPartialEquiv := Φ.toPartialEquiv open_source := Φ.open_source diff --git a/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean b/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean index eba67d29639cd2..ab1e4a4b92d4d4 100644 --- a/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean +++ b/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean @@ -238,7 +238,7 @@ lemma prodMap [IsManifold I n M] [IsManifold I' n M'] [IsManifold J n N] [IsMani (domChart_mem_maximalAtlas hf) (domChart_mem_maximalAtlas hg) · apply IsManifold.mem_maximalAtlas_prod (codChart_mem_maximalAtlas hf) (codChart_mem_maximalAtlas hg) - · simp only [OpenPartialHomeomorph.prod_toPartialEquiv, PartialEquiv.prod_source, + · simp only [OpenPartialHomeomorph.prod_toPartialHomeomorph, PartialEquiv.prod_source, preimage_prod_map_prod] exact prod_mono hf.source_subset_preimage_source hg.source_subset_preimage_source · exact h hf.property hg.property diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean index f3b6b6f2488b12..7da4f53aa81781 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean @@ -248,12 +248,13 @@ variable (K) theorem expMap_source : expMap.source = (Set.univ : Set (realSpace K)) := by - simp_rw [expMap, OpenPartialHomeomorph.pi_toPartialEquiv, PartialEquiv.pi_source, expMap_single, - Set.pi_univ Set.univ] + simp_rw [expMap, OpenPartialHomeomorph.pi_toPartialHomeomorph, + PartialEquiv.pi_source, expMap_single, Set.pi_univ Set.univ] theorem expMap_target : expMap.target = Set.univ.pi fun (_ : InfinitePlace K) ↦ Set.Ioi 0 := by - simp_rw [expMap, OpenPartialHomeomorph.pi_toPartialEquiv, PartialEquiv.pi_target, expMap_single] + simp_rw [expMap, OpenPartialHomeomorph.pi_toPartialHomeomorph, + PartialEquiv.pi_target, expMap_single] theorem injective_expMap : Function.Injective (expMap : realSpace K → realSpace K) := diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index a3b14ce26719a8..38133c78000fab 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -412,8 +412,8 @@ initialize_simps_projections Trivialization (toFun → apply, invFun → symm_ap theorem toPretrivialization_injective : Function.Injective fun e : Trivialization F proj => e.toPretrivialization := fun e e' h => by ext1 - exacts [OpenPartialHomeomorph.toPartialEquiv_injective - (congr_arg Pretrivialization.toPartialEquiv h), congr_arg Pretrivialization.baseSet h] + exacts [OpenPartialHomeomorph.toPartialEquiv_injective congr(Pretrivialization.toPartialEquiv $h), + congr(Pretrivialization.baseSet $h)] @[simp, mfld_simps] theorem coe_coe : ⇑e.toOpenPartialHomeomorph = e := diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean index d7b7543fc806ee..bb87598e2874a5 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean @@ -122,7 +122,7 @@ theorem isOpen_image_iff_of_subset_source {s : Set X} (hs : s ⊆ e.source) : /-- A `PartialEquiv` with continuous open forward map and open source is a `OpenPartialHomeomorph`. -/ -@[simps toPartialEquiv] +@[simps toPartialHomeomorph] def ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) (ho : IsOpenMap (e.source.restrict e)) (hs : IsOpen e.source) : OpenPartialHomeomorph X Y where toPartialEquiv := e @@ -145,7 +145,7 @@ theorem coe_ofContinuousOpenRestrict_symm (e : PartialEquiv X Y) (hc : Continuou /-- A `PartialEquiv` with continuous open forward map and open source is a `OpenPartialHomeomorph`. -/ -@[simps! toPartialEquiv] +@[simps! toPartialHomeomorph] def ofContinuousOpen (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) (ho : IsOpenMap e) (hs : IsOpen e.source) : OpenPartialHomeomorph X Y := ofContinuousOpenRestrict e hc (ho.restrict hs) hs diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean b/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean index 943cdfd79060bf..b60b59954a009f 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean @@ -37,7 +37,7 @@ variable (e' : OpenPartialHomeomorph Y Z) /-- Composition of two open partial homeomorphisms when the target of the first and the source of the second coincide. -/ -@[simps! apply symm_apply toPartialEquiv, simps! -isSimp source target] +@[simps! apply symm_apply toPartialHomeomorph, simps! -isSimp source target] protected def trans' (h : e.target = e'.source) : OpenPartialHomeomorph X Z where toPartialEquiv := PartialEquiv.trans' e.toPartialEquiv e'.toPartialEquiv h open_source := e.open_source @@ -103,11 +103,11 @@ theorem trans_assoc (e'' : OpenPartialHomeomorph Z Z') : @[simp, mfld_simps] theorem trans_refl : e.trans (OpenPartialHomeomorph.refl Y) = e := - toPartialEquiv_injective e.1.trans_refl + toPartialHomeomorph_injective (PartialHomeomorph.toPartialEquiv_injective e.1.trans_refl) @[simp, mfld_simps] theorem refl_trans : (OpenPartialHomeomorph.refl X).trans e = e := - toPartialEquiv_injective e.1.refl_trans + toPartialHomeomorph_injective (PartialHomeomorph.toPartialEquiv_injective e.1.refl_trans) theorem trans_ofSet {s : Set Y} (hs : IsOpen s) : e.trans (ofSet s hs) = e.restr (e ⁻¹' s) := OpenPartialHomeomorph.ext _ _ (fun _ => rfl) (fun _ => rfl) <| by @@ -197,7 +197,8 @@ variable (e : X ≃ₜ Y) (e' : Y ≃ₜ Z) @[simp, mfld_simps] theorem trans_toOpenPartialHomeomorph : (e.trans e').toOpenPartialHomeomorph = e.toOpenPartialHomeomorph.trans e'.toOpenPartialHomeomorph := - OpenPartialHomeomorph.toPartialEquiv_injective <| Equiv.trans_toPartialEquiv _ _ + OpenPartialHomeomorph.toPartialHomeomorph_injective <| + PartialHomeomorph.toPartialEquiv_injective <| Equiv.trans_toPartialEquiv _ _ /-- Precompose an open partial homeomorphism with a homeomorphism. We modify the source and target to have better definitional behavior. -/ diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean index b1543e614aa23f..7da001d1a1cebe 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean @@ -76,7 +76,7 @@ section Prod /-- The product of two open partial homeomorphisms, as an open partial homeomorphism on the product space. -/ -@[simps! (attr := mfld_simps) -fullyApplied toPartialEquiv apply, +@[simps! (attr := mfld_simps) -fullyApplied toPartialHomeomorph apply, simps! -isSimp source target symm_apply] def prod (eX : OpenPartialHomeomorph X X') (eY : OpenPartialHomeomorph Y Y') : OpenPartialHomeomorph (X × Y) (X' × Y') where @@ -137,7 +137,7 @@ variable {ι : Type*} [Finite ι] {X Y : ι → Type*} [∀ i, TopologicalSpace [∀ i, TopologicalSpace (Y i)] (ei : ∀ i, OpenPartialHomeomorph (X i) (Y i)) /-- The product of a finite family of `OpenPartialHomeomorph`s. -/ -@[simps! toPartialEquiv apply symm_apply] +@[simps! toPartialHomeomorph apply symm_apply] def pi : OpenPartialHomeomorph (∀ i, X i) (∀ i, Y i) where toPartialEquiv := PartialEquiv.pi fun i => (ei i).toPartialEquiv open_source := isOpen_set_pi finite_univ fun i _ => (ei i).open_source @@ -164,7 +164,7 @@ To ensure the maps `toFun` and `invFun` are inverse of each other on the new `so the definition assumes that the sets `s` and `t` are related both by `e.is_image` and `e'.is_image`. To ensure that the new maps are continuous on `source`/`target`, it also assumes that `e.source` and `e'.source` meet `frontier s` on the same set and `e x = e' x` on this intersection. -/ -@[simps! -fullyApplied toPartialEquiv apply] +@[simps! -fullyApplied toPartialHomeomorph apply] def piecewise (e e' : OpenPartialHomeomorph X Y) (s : Set X) (t : Set Y) [∀ x, Decidable (x ∈ s)] [∀ y, Decidable (y ∈ t)] (H : e.IsImage s t) (H' : e'.IsImage s t) (Hs : e.source ∩ frontier s = e'.source ∩ frontier s) diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean index 362cbe712da3c6..a8f90bd94cf6df 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean @@ -5,8 +5,7 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.Logic.Equiv.PartialEquiv -public import Mathlib.Topology.ContinuousOn +public import Mathlib.Topology.PartialHomeomorph.Defs /-! # Partial homeomorphisms: definitions @@ -17,7 +16,7 @@ This file defines homeomorphisms between open subsets of topological spaces. An Additionally, we require that these sets are open, and that the functions are continuous on them. Equivalently, they are homeomorphisms there. -As in equivs, we register a coercion to functions, and we use `e x` and `e.symm x` throughout +As for `Equiv`s, we register a coercion to functions, and we use `e x` and `e.symm x` throughout instead of `e.toFun x` and `e.invFun x`. ## Main definitions @@ -52,11 +51,9 @@ variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} /-- Partial homeomorphisms, defined on open subsets of the space -/ structure OpenPartialHomeomorph (X : Type*) (Y : Type*) [TopologicalSpace X] - [TopologicalSpace Y] extends PartialEquiv X Y where + [TopologicalSpace Y] extends PartialHomeomorph X Y where open_source : IsOpen source open_target : IsOpen target - continuousOn_toFun : ContinuousOn toFun source - continuousOn_invFun : ContinuousOn invFun target namespace OpenPartialHomeomorph @@ -65,8 +62,7 @@ variable (e : OpenPartialHomeomorph X Y) /-! Basic properties; inverse (symm instance) -/ section Basic /-- Coercion of an open partial homeomorphisms to a function. We don't use `e.toFun` because it is -actually `e.toPartialEquiv.toFun`, so `simp` will apply lemmas about `toPartialEquiv`. -While we may want to switch to this behavior later, doing it mid-port will break a lot of proofs. -/ +actually `e.toPartialEquiv.toFun`, so `simp` will apply lemmas about `toPartialEquiv`. -/ @[coe] def toFun' : X → Y := e.toFun /-- Coercion of an `OpenPartialHomeomorph` to function. @@ -77,11 +73,9 @@ instance : CoeFun (OpenPartialHomeomorph X Y) fun _ => X → Y := /-- The inverse of an open partial homeomorphism -/ @[symm] protected def symm : OpenPartialHomeomorph Y X where - toPartialEquiv := e.toPartialEquiv.symm + toPartialHomeomorph := e.toPartialHomeomorph.symm open_source := e.open_target open_target := e.open_source - continuousOn_toFun := e.continuousOn_invFun - continuousOn_invFun := e.continuousOn_toFun /-- See Note [custom simps projection]. We need to specify this projection explicitly in this case, because it is a composition of multiple projections. -/ @@ -100,21 +94,25 @@ theorem continuousOn_symm : ContinuousOn e.symm e.target := @[simp, mfld_simps] theorem coe_mk (e : PartialEquiv X Y) (h₁ h₂ h₃ h₄) : - (OpenPartialHomeomorph.mk e h₁ h₂ h₃ h₄ : X → Y) = e := + (OpenPartialHomeomorph.mk (.mk e h₁ h₂) h₃ h₄ : X → Y) = e := rfl @[deprecated (since := "2026-05-20")] alias mk_coe := coe_mk @[simp, mfld_simps] theorem coe_mk_symm (e : PartialEquiv X Y) (h₁ h₂ h₃ h₄) : - ((OpenPartialHomeomorph.mk e h₁ h₂ h₃ h₄).symm : Y → X) = e.symm := + ((OpenPartialHomeomorph.mk (.mk e h₁ h₂) h₃ h₄).symm : Y → X) = e.symm := rfl @[deprecated (since := "2026-05-20")] alias mk_coe_symm := coe_mk_symm +theorem toPartialHomeomorph_injective : + Injective (toPartialHomeomorph : OpenPartialHomeomorph X Y → PartialHomeomorph X Y) + | ⟨_, _, _⟩, ⟨_, _, _⟩, rfl => rfl + theorem toPartialEquiv_injective : - Injective (toPartialEquiv : OpenPartialHomeomorph X Y → PartialEquiv X Y) - | ⟨_, _, _, _, _⟩, ⟨_, _, _, _, _⟩, rfl => rfl + Injective (fun f ↦ f.toPartialEquiv : OpenPartialHomeomorph X Y → PartialEquiv X Y) := + PartialHomeomorph.toPartialEquiv_injective.comp toPartialHomeomorph_injective /- Register a few simp lemmas to make sure that `simp` puts the application of a local homeomorphism in its normal form, i.e., in terms of its coercion to a function. -/ @@ -143,6 +141,14 @@ theorem coe_toPartialEquiv_symm : (e.toPartialEquiv.symm : Y → X) = e.symm := theorem map_source {x : X} (h : x ∈ e.source) : e x ∈ e.target := e.map_source' h +@[simp, mfld_simps] +theorem coe_toPartialHomeomorph : (e.toPartialHomeomorph : X → Y) = e := + rfl + +@[simp, mfld_simps] +theorem coe_toPartialHomeomorph_symm : (e.toPartialHomeomorph.symm : Y → X) = e.symm := + rfl + /-- Variant of `map_source`, stated for images of subsets of `source`. -/ lemma image_source_subset : e '' e.source ⊆ e.target := fun _ ⟨_, hx, hex⟩ ↦ mem_of_eq_of_mem (id hex.symm) (e.map_source' hx) @@ -192,15 +198,13 @@ end Basic /-- Interpret a `Homeomorph` as an `OpenPartialHomeomorph` by restricting it to an open set `s` in the domain and to `t` in the codomain. -/ -@[simps! -fullyApplied apply symm_apply toPartialEquiv, +@[simps! -fullyApplied apply symm_apply toPartialHomeomorph, simps! -isSimp source target] def _root_.Homeomorph.toOpenPartialHomeomorphOfImageEq (e : X ≃ₜ Y) (s : Set X) (hs : IsOpen s) (t : Set Y) (h : e '' s = t) : OpenPartialHomeomorph X Y where - toPartialEquiv := e.toPartialEquivOfImageEq s t h + toPartialHomeomorph := e.toPartialHomeomorphOfImageEq s t h open_source := hs open_target := by simpa [← h] - continuousOn_toFun := e.continuous.continuousOn - continuousOn_invFun := e.symm.continuous.continuousOn /-- A homeomorphism induces an open partial homeomorphism on the whole space -/ @[simps! (attr := mfld_simps) -fullyApplied] @@ -211,11 +215,9 @@ def _root_.Homeomorph.toOpenPartialHomeomorph (e : X ≃ₜ Y) : OpenPartialHome /-- Replace `toPartialEquiv` field to provide better definitional equalities. -/ def replacePartialEquiv (e : OpenPartialHomeomorph X Y) (e' : PartialEquiv X Y) (h : e.toPartialEquiv = e') : OpenPartialHomeomorph X Y where - toPartialEquiv := e' + toPartialHomeomorph := e.toPartialHomeomorph.replacePartialEquiv e' h open_source := h ▸ e.open_source open_target := h ▸ e.open_target - continuousOn_toFun := h ▸ e.continuousOn_toFun - continuousOn_invFun := h ▸ e.continuousOn_invFun @[deprecated (since := "2026-05-19")] alias replaceEquiv := replacePartialEquiv @@ -234,7 +236,8 @@ called `EqOnSource`. -/ @[ext] protected theorem ext (e' : OpenPartialHomeomorph X Y) (h : ∀ x, e x = e' x) (hinv : ∀ x, e.symm x = e'.symm x) (hs : e.source = e'.source) : e = e' := - toPartialEquiv_injective (PartialEquiv.ext h hinv hs) + toPartialHomeomorph_injective + (PartialHomeomorph.ext e.toPartialHomeomorph e'.toPartialHomeomorph h hinv hs) @[simp, mfld_simps] theorem symm_toPartialEquiv : e.symm.toPartialEquiv = e.toPartialEquiv.symm := diff --git a/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean b/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean index 4046c9bec712cd..fe21e40169ee0f 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean @@ -171,7 +171,7 @@ theorem isOpen_iff (h : e.IsImage s t) : IsOpen (e.source ∩ s) ↔ IsOpen (e.t h.preimage_eq' ▸ e.isOpen_inter_preimage hs⟩ /-- Restrict an `OpenPartialHomeomorph` to a pair of corresponding open sets. -/ -@[simps! -fullyApplied apply symm_apply toPartialEquiv] +@[simps! -fullyApplied apply symm_apply toPartialHomeomorph] def restr (h : e.IsImage s t) (hs : IsOpen (e.source ∩ s)) : OpenPartialHomeomorph X Y where toPartialEquiv := h.toPartialEquiv.restr open_source := hs @@ -315,7 +315,8 @@ theorem eqOnSource_iff (e e' : OpenPartialHomeomorph X Y) : /-- `EqOnSource` is an equivalence relation. -/ instance eqOnSourceSetoid : Setoid (OpenPartialHomeomorph X Y) := - { PartialEquiv.eqOnSourceSetoid.comap toPartialEquiv with r := EqOnSource } + { PartialEquiv.eqOnSourceSetoid.comap + (fun x ↦ (toPartialHomeomorph x).toPartialEquiv) with r := EqOnSource } theorem eqOnSource_refl : e ≈ e := Setoid.refl _ diff --git a/Mathlib/Topology/PartialHomeomorph/Defs.lean b/Mathlib/Topology/PartialHomeomorph/Defs.lean new file mode 100644 index 00000000000000..ab78f5be70780c --- /dev/null +++ b/Mathlib/Topology/PartialHomeomorph/Defs.lean @@ -0,0 +1,226 @@ +/- +Copyright (c) 2019 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.Logic.Equiv.PartialEquiv +public import Mathlib.Topology.ContinuousOn + +/-! +# Partial homeomorphisms: definitions + +This file defines homeomorphisms between subsets of topological spaces. An element `e` of +`PartialHomeomorph X Y` is an extension of `PartialEquiv X Y`, i.e., it is a pair of functions +`e.toFun` and `e.invFun`, inverse of each other on the sets `e.source` and `e.target`. +Additionally, we require that the functions are continuous on them. Equivalently, they are +homeomorphisms there. + +As for `Equiv`s, we register a coercion to functions, and we use `e x` and `e.symm x` throughout +instead of `e.toFun x` and `e.invFun x`. + +## Main definitions + +This file is intentionally kept small; many other constructions of, and lemmas about, +partial homeomorphisms can be found in other files under `Mathlib/Topology/PartialHomeomorph/`. + +* `Homeomorph.toPartialHomeomorph`: associating a partial homeomorphism to a + homeomorphism, with `source = target = Set.univ`; +* `PartialHomeomorph.symm`: the inverse of a partial homeomorphism + +## Implementation notes + +Most statements are copied from their `PartialEquiv` versions, although some care is required. + +For design notes, see `PartialEquiv.lean`. + +### Local coding conventions + +If a lemma deals with the intersection of a set with either source or target of a `PartialEquiv`, +then it should use `e.source ∩ s` or `e.target ∩ t`, not `s ∩ e.source` or `t ∩ e.target`. +-/ + +@[expose] public section + +open Function Set Filter Topology + +variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} + [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] + [TopologicalSpace Z] [TopologicalSpace Z'] + +/-- Partial homeomorphisms, defined on subsets of the space -/ +structure PartialHomeomorph (X : Type*) (Y : Type*) [TopologicalSpace X] + [TopologicalSpace Y] extends PartialEquiv X Y where + continuousOn_toFun : ContinuousOn toFun source + continuousOn_invFun : ContinuousOn invFun target + +namespace PartialHomeomorph + +variable (e : PartialHomeomorph X Y) + +/-! Basic properties; inverse (symm instance) -/ +section Basic +/-- Coercion of a partial homeomorphisms to a function. We don't use `e.toFun` because it is +actually `e.toPartialEquiv.toFun`, so `simp` will apply lemmas about `toPartialEquiv`. -/ +@[coe] def toFun' : X → Y := e.toFun + +/-- Coercion of a `PartialHomeomorph` to function. +Note that a `PartialHomeomorph` is not `DFunLike`. -/ +instance : CoeFun (PartialHomeomorph X Y) fun _ => X → Y := + ⟨fun e => e.toFun'⟩ + +/-- The inverse of a partial homeomorphism -/ +@[symm] +protected def symm : PartialHomeomorph Y X where + toPartialEquiv := e.toPartialEquiv.symm + continuousOn_toFun := e.continuousOn_invFun + continuousOn_invFun := e.continuousOn_toFun + +/-- See Note [custom simps projection]. We need to specify this projection explicitly in this case, + because it is a composition of multiple projections. -/ +def Simps.apply (e : PartialHomeomorph X Y) : X → Y := e + +/-- See Note [custom simps projection] -/ +def Simps.symm_apply (e : PartialHomeomorph X Y) : Y → X := e.symm + +initialize_simps_projections PartialHomeomorph (toFun → apply, invFun → symm_apply) + +protected theorem continuousOn : ContinuousOn e e.source := + e.continuousOn_toFun + +theorem continuousOn_symm : ContinuousOn e.symm e.target := + e.continuousOn_invFun + +@[simp] +theorem coe_mk (e : PartialEquiv X Y) (h₁ h₂) : (PartialHomeomorph.mk e h₁ h₂ : X → Y) = e := rfl + +@[simp] +theorem coe_mk_symm (e : PartialEquiv X Y) (h₁ h₂) : + ((PartialHomeomorph.mk e h₁ h₂).symm : Y → X) = e.symm := + rfl + +theorem toPartialEquiv_injective : + Injective (toPartialEquiv : PartialHomeomorph X Y → PartialEquiv X Y) + | ⟨_, _, _⟩, ⟨_, _, _⟩, rfl => rfl + +/- Register a few simp lemmas to make sure that `simp` puts the application of a local +homeomorphism in its normal form, i.e., in terms of its coercion to a function. -/ +@[simp] +theorem toFun_eq_coe (e : PartialHomeomorph X Y) : e.toFun = e := + rfl + +@[simp] +theorem invFun_eq_coe (e : PartialHomeomorph X Y) : e.invFun = e.symm := + rfl + +@[simp] +theorem coe_toPartialEquiv : (e.toPartialEquiv : X → Y) = e := + rfl + +@[simp] +theorem coe_toPartialEquiv_symm : (e.toPartialEquiv.symm : Y → X) = e.symm := + rfl + +@[simp] +theorem map_source {x : X} (h : x ∈ e.source) : e x ∈ e.target := + e.map_source' h + +/-- Variant of `map_source`, stated in terms of subsets. -/ +lemma image_source_subset : e '' e.source ⊆ e.target := + fun _ ⟨_, hx, hex⟩ ↦ mem_of_eq_of_mem (id hex.symm) (e.map_source' hx) + +@[simp] +theorem map_target {x : Y} (h : x ∈ e.target) : e.symm x ∈ e.source := + e.map_target' h + +@[simp] +theorem left_inv {x : X} (h : x ∈ e.source) : e.symm (e x) = x := + e.left_inv' h + +@[simp] +theorem right_inv {x : Y} (h : x ∈ e.target) : e (e.symm x) = x := + e.right_inv' h + +theorem eq_symm_apply {x : X} {y : Y} (hx : x ∈ e.source) (hy : y ∈ e.target) : + x = e.symm y ↔ e x = y := + e.toPartialEquiv.eq_symm_apply hx hy + +protected theorem mapsTo : MapsTo e e.source e.target := fun _ => e.map_source + +protected theorem mapsTo_symm : MapsTo e.symm e.target e.source := + e.symm.mapsTo + +protected theorem leftInvOn : LeftInvOn e.symm e e.source := fun _ => e.left_inv + +protected theorem rightInvOn : RightInvOn e.symm e e.target := fun _ => e.right_inv + +protected theorem invOn : InvOn e.symm e e.source e.target := + ⟨e.leftInvOn, e.rightInvOn⟩ + +protected theorem injOn : InjOn e e.source := + e.leftInvOn.injOn + +protected theorem bijOn : BijOn e e.source e.target := + e.invOn.bijOn e.mapsTo e.mapsTo_symm + +protected theorem surjOn : SurjOn e e.source e.target := + e.bijOn.surjOn + +end Basic + +/-- Interpret a `Homeomorph` as a `PartialHomeomorph` by restricting it +to a set `s` in the domain and to `t` in the codomain. -/ +@[simps! -fullyApplied apply symm_apply toPartialEquiv, + simps! -isSimp source target] +def _root_.Homeomorph.toPartialHomeomorphOfImageEq (e : X ≃ₜ Y) (s : Set X) + (t : Set Y) (h : e '' s = t) : PartialHomeomorph X Y where + toPartialEquiv := e.toPartialEquivOfImageEq s t h + continuousOn_toFun := e.continuous.continuousOn + continuousOn_invFun := e.symm.continuous.continuousOn + +/-- A homeomorphism induces a partial homeomorphism on the whole space -/ +@[simps! -fullyApplied] +def _root_.Homeomorph.toPartialHomeomorph (e : X ≃ₜ Y) : PartialHomeomorph X Y := + e.toPartialHomeomorphOfImageEq univ univ <| by rw [image_univ, e.surjective.range_eq] + +/-- Replace `toPartialEquiv` field to provide better definitional equalities. -/ +def replacePartialEquiv (e : PartialHomeomorph X Y) (e' : PartialEquiv X Y) + (h : e.toPartialEquiv = e') : PartialHomeomorph X Y where + toPartialEquiv := e' + continuousOn_toFun := h ▸ e.continuousOn_toFun + continuousOn_invFun := h ▸ e.continuousOn_invFun + +theorem replacePartialEquiv_eq_self (e' : PartialEquiv X Y) + (h : e.toPartialEquiv = e') : e.replacePartialEquiv e' h = e := by + cases e + subst e' + rfl + +/-- Two partial homeomorphisms are equal when they have equal `toFun`, `invFun` and `source`. +It is not sufficient to have equal `toFun` and `source`, as this only determines `invFun` on +the target. This would only be true for a weaker notion of equality, arguably the right one, +called `EqOnSource`. -/ +@[ext] +protected theorem ext (e' : PartialHomeomorph X Y) (h : ∀ x, e x = e' x) + (hinv : ∀ x, e.symm x = e'.symm x) (hs : e.source = e'.source) : e = e' := + toPartialEquiv_injective (PartialEquiv.ext h hinv hs) + +@[simp] +theorem symm_toPartialEquiv : e.symm.toPartialEquiv = e.toPartialEquiv.symm := + rfl + +-- The following lemmas are already simp via `PartialEquiv` +theorem symm_source : e.symm.source = e.target := + rfl + +theorem symm_target : e.symm.target = e.source := + rfl + +@[simp] theorem symm_symm : e.symm.symm = e := rfl + +theorem symm_bijective : Function.Bijective + (PartialHomeomorph.symm : PartialHomeomorph X Y → PartialHomeomorph Y X) := + Function.bijective_iff_has_inverse.mpr ⟨_, symm_symm, symm_symm⟩ + +end PartialHomeomorph From c7943cc789d6f1fcd90b124812b946f766a44abe Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Wed, 17 Jun 2026 19:45:24 +0000 Subject: [PATCH 0126/1300] chore: remove stray line break (#40719) --- Mathlib/GroupTheory/Congruence/Hom.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/GroupTheory/Congruence/Hom.lean b/Mathlib/GroupTheory/Congruence/Hom.lean index 0e04ceff448309..0d95b7350e7028 100644 --- a/Mathlib/GroupTheory/Congruence/Hom.lean +++ b/Mathlib/GroupTheory/Congruence/Hom.lean @@ -40,7 +40,6 @@ namespace Con section Mul variable {F} [Mul M] [Mul N] [Mul P] [FunLike F M N] [MulHomClass F M N] - /-- The natural homomorphism from a magma to its quotient by a congruence relation. -/ @[to_additive (attr := simps) /-- The natural homomorphism from an additive magma to its quotient by an additive congruence relation. -/] From 54d47da30ce1fec48772370361cdaea2587c1af0 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Wed, 17 Jun 2026 20:47:16 +0000 Subject: [PATCH 0127/1300] chore: always include comment when importing header linter explicitly (#40729) This PR makes sure we always includes the comment ``` -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. ``` whenever `Mathlib.Tactic.Linter.Header` is imported explicitly. Some files already had this comment, and this PR just makes sure all of them do. We also normalize whitespace in adjacent `shake` annotations while we're at it. We could check for this in lint-style, but it would be easier after #40347. --- Mathlib/Lean/Elab/InfoTree.lean | 2 +- Mathlib/Lean/Environment.lean | 2 +- Mathlib/Lean/Expr/Basic.lean | 2 +- Mathlib/Tactic/Linter/AuxLemma.lean | 2 ++ Mathlib/Tactic/Linter/DocString.lean | 2 ++ Mathlib/Tactic/Linter/EmptyLine.lean | 3 +++ Mathlib/Tactic/Linter/FlexibleLinter.lean | 2 ++ Mathlib/Tactic/Linter/TacticDocumentation.lean | 2 ++ Mathlib/Tactic/Linter/UnusedInstancesInType.lean | 2 +- Mathlib/Tactic/Linter/Whitespace.lean | 2 ++ Mathlib/Tactic/TypeStar.lean | 2 +- Mathlib/Util/ParseCommand.lean | 2 +- 12 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Mathlib/Lean/Elab/InfoTree.lean b/Mathlib/Lean/Elab/InfoTree.lean index 9755b678eea600..cca33050a3b0e2 100644 --- a/Mathlib/Lean/Elab/InfoTree.lean +++ b/Mathlib/Lean/Elab/InfoTree.lean @@ -11,7 +11,7 @@ public import Lean.Meta.TryThis public import Batteries.Tactic.Lint.Misc -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. -import Mathlib.Tactic.Linter.Header --shake: keep +import Mathlib.Tactic.Linter.Header -- shake: keep public import Batteries.Tactic.Lint.Basic import Lean.Elab.Term.TermElabM diff --git a/Mathlib/Lean/Environment.lean b/Mathlib/Lean/Environment.lean index aed6331c83adf0..5afff12cfbe458 100644 --- a/Mathlib/Lean/Environment.lean +++ b/Mathlib/Lean/Environment.lean @@ -8,7 +8,7 @@ module public import Lean.Environment -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. -import Mathlib.Tactic.Linter.Header --shake: keep +import Mathlib.Tactic.Linter.Header -- shake: keep /-! # Additional utilities for `Lean.Environment` diff --git a/Mathlib/Lean/Expr/Basic.lean b/Mathlib/Lean/Expr/Basic.lean index 91f9bd6a9666f3..0be1b3683d9f16 100644 --- a/Mathlib/Lean/Expr/Basic.lean +++ b/Mathlib/Lean/Expr/Basic.lean @@ -8,7 +8,7 @@ module -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. -import Mathlib.Tactic.Linter.Header --shake: keep +import Mathlib.Tactic.Linter.Header -- shake: keep public import Lean.Meta.AppBuilder public import Lean.Meta.Match.MatcherInfo public import Lean.Meta.Transform diff --git a/Mathlib/Tactic/Linter/AuxLemma.lean b/Mathlib/Tactic/Linter/AuxLemma.lean index a329619c0e265c..964759aa94aae7 100644 --- a/Mathlib/Tactic/Linter/AuxLemma.lean +++ b/Mathlib/Tactic/Linter/AuxLemma.lean @@ -6,6 +6,8 @@ Authors: Kim Morrison module public meta import Lean.Elab.Command +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. public meta import Mathlib.Tactic.Linter.Header -- shake: keep /-! diff --git a/Mathlib/Tactic/Linter/DocString.lean b/Mathlib/Tactic/Linter/DocString.lean index 37045c86f2197d..8b3182d24d9ca4 100644 --- a/Mathlib/Tactic/Linter/DocString.lean +++ b/Mathlib/Tactic/Linter/DocString.lean @@ -5,6 +5,8 @@ Authors: Michael Rothgang, Damiano Testa -/ module +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. public meta import Mathlib.Tactic.Linter.Header -- shake: keep public meta import Std.Data.Iterators.Combinators.Zip public import Lean.Parser.Command diff --git a/Mathlib/Tactic/Linter/EmptyLine.lean b/Mathlib/Tactic/Linter/EmptyLine.lean index d86bfce93400c4..2a927a380c2a54 100644 --- a/Mathlib/Tactic/Linter/EmptyLine.lean +++ b/Mathlib/Tactic/Linter/EmptyLine.lean @@ -5,6 +5,9 @@ Authors: Damiano Testa -/ module + +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. public meta import Mathlib.Tactic.Linter.Header -- shake: keep public import Lean.Parser.Command diff --git a/Mathlib/Tactic/Linter/FlexibleLinter.lean b/Mathlib/Tactic/Linter/FlexibleLinter.lean index 0246c939ff4119..b7de42cc5db889 100644 --- a/Mathlib/Tactic/Linter/FlexibleLinter.lean +++ b/Mathlib/Tactic/Linter/FlexibleLinter.lean @@ -9,6 +9,8 @@ public meta import Lean.Elab.Command public meta import Lean.Elab.Tactic.Simp public meta import Lean.Meta.Tactic.TryThis public meta import Lean.Server.InfoUtils +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. public meta import Mathlib.Tactic.Linter.Header -- shake: keep public import Lean.Parser.Term diff --git a/Mathlib/Tactic/Linter/TacticDocumentation.lean b/Mathlib/Tactic/Linter/TacticDocumentation.lean index 315f35673e7945..bd0874afb9d480 100644 --- a/Mathlib/Tactic/Linter/TacticDocumentation.lean +++ b/Mathlib/Tactic/Linter/TacticDocumentation.lean @@ -7,6 +7,8 @@ module public meta import Lean.Elab.Tactic.Doc public meta import Lean.Parser.Tactic.Doc +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. public import Mathlib.Tactic.Linter.Header -- shake: keep public import Batteries.Tactic.Lint.Basic public import Lean.Elab.Tactic.Doc diff --git a/Mathlib/Tactic/Linter/UnusedInstancesInType.lean b/Mathlib/Tactic/Linter/UnusedInstancesInType.lean index 72e03512cdafc3..4a6ec648aff168 100644 --- a/Mathlib/Tactic/Linter/UnusedInstancesInType.lean +++ b/Mathlib/Tactic/Linter/UnusedInstancesInType.lean @@ -11,7 +11,7 @@ public meta import Mathlib.Lean.Elab.InfoTree public meta import Lean.Linter.Basic -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. -public import Mathlib.Tactic.Linter.Header --shake: keep +public import Mathlib.Tactic.Linter.Header -- shake: keep public import Batteries.Tactic.Lint.Basic public import Batteries.Tactic.Lint.Misc diff --git a/Mathlib/Tactic/Linter/Whitespace.lean b/Mathlib/Tactic/Linter/Whitespace.lean index 054bff27fa7fb1..16a175642c7990 100644 --- a/Mathlib/Tactic/Linter/Whitespace.lean +++ b/Mathlib/Tactic/Linter/Whitespace.lean @@ -5,6 +5,8 @@ Authors: Damiano Testa -/ module +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. public import Mathlib.Tactic.Linter.Header -- shake: keep /-! diff --git a/Mathlib/Tactic/TypeStar.lean b/Mathlib/Tactic/TypeStar.lean index f80f6490f307ec..9ad0340489994d 100644 --- a/Mathlib/Tactic/TypeStar.lean +++ b/Mathlib/Tactic/TypeStar.lean @@ -7,7 +7,7 @@ module -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. -public import Mathlib.Tactic.Linter.Header --shake: keep +public import Mathlib.Tactic.Linter.Header -- shake: keep /-! # Support for `Sort*` and `Type*`. diff --git a/Mathlib/Util/ParseCommand.lean b/Mathlib/Util/ParseCommand.lean index ec932c087b98fc..3feb0438ac9028 100644 --- a/Mathlib/Util/ParseCommand.lean +++ b/Mathlib/Util/ParseCommand.lean @@ -8,7 +8,7 @@ module public meta import Lean.Elab.Command -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. -public meta import Mathlib.Tactic.Linter.Header --shake: keep +public meta import Mathlib.Tactic.Linter.Header -- shake: keep /-! # `#parse` -- a command to parse text and log outputs From dba82c485d7efa056a35e699878b3951dcdc0583 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Wed, 17 Jun 2026 21:42:41 +0000 Subject: [PATCH 0128/1300] ci(cache): fall back to latest cache-snapshot when the resolved run has none (#40734) The resolved master run can predate the `cache-snapshot` artifact (or have an expired one), making the warm step's `download-artifact` log a spurious "Artifact not found" error. Verify the artifact exists first; otherwise fall back to the latest master run that has one, and skip the warm if none does. --- .github/actions/get-cache/action.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/actions/get-cache/action.yml b/.github/actions/get-cache/action.yml index ca5d3a1a2846f7..00bfcdaf0550be 100644 --- a/.github/actions/get-cache/action.yml +++ b/.github/actions/get-cache/action.yml @@ -40,6 +40,13 @@ runs: '[.workflow_runs[] | select(.created_at <= $d and ($c == "" or .created_at >= $c))][0].id // empty' \ 2>/dev/null || true } + # True if run-id $1 actually carries a `cache-snapshot` artifact. Older runs + # predate the feature and artifacts expire, so a successful run is not enough. + # Filters server-side by name, but re-checks in jq in case `name` is ignored. + has_snapshot() { + [[ -n "$(gh api "repos/leanprover-community/mathlib4/actions/runs/$1/artifacts?name=cache-snapshot&per_page=100" \ + --jq '.artifacts[] | select(.name == "cache-snapshot") | .id' 2>/dev/null | head -1 || true)" ]] + } # This PR's merge-base with master (+ its commit date), and the cutoff below which # snapshots have expired (retention ~14d). @@ -57,6 +64,19 @@ runs: fi [[ -z "${run_id}" ]] && run_id=$(latest_run) + # The resolved run may carry no `cache-snapshot` artifact: an older merge-base + # predating the feature, or one whose artifact already expired (older-than-today + # runs often won't have one). Rather than let the download step hard-error on a + # missing artifact, confirm it's present; if not, fall back to the latest master + # run, and warm only if that one has it. + if [[ -n "${run_id}" ]] && ! has_snapshot "${run_id}"; then + echo "Run ${run_id} has no cache-snapshot artifact; falling back to latest master run." + run_id=$(latest_run) + if [[ -n "${run_id}" ]] && ! has_snapshot "${run_id}"; then + run_id="" + fi + fi + echo "Resolved cache-snapshot run_id: '${run_id}' (merge-base: ${mb:-unknown})" echo "run_id=${run_id}" >> "$GITHUB_OUTPUT" From 9a9483a92959bc92bd6a60176dd1fe597298c1f8 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 18 Jun 2026 02:43:13 +0000 Subject: [PATCH 0129/1300] =?UTF-8?q?feat(Combinatorics/SimpleGraph/Paths)?= =?UTF-8?q?:=20`p.IsPath=20=E2=86=92=20p.dropLast.IsPath`=20(#40667)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have this for `tail`/`take`/`drop`/`takeUntil`/`dropUntil`/`reverse`/`copy`/`concat` but not for `dropLast`. --- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 52bdf1c73ab472..a5813a65160535 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -358,6 +358,9 @@ lemma IsPath.tail {p : G.Walk u v} (hp : p.IsPath) : p.tail.IsPath := by | cons hadj p => simp_all [Walk.isPath_def] +theorem IsPath.dropLast (hp : p.IsPath) : p.dropLast.IsPath := + hp.take _ + /-- There exists a trail of maximal length in a non-empty graph on finite edges. -/ lemma exists_isTrail_forall_isTrail_length_le_length (G : SimpleGraph V) [N : Nonempty V] [Finite G.edgeSet] : From 014c1563dc2c952488b6acfd3fac97ee588f0c6d Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Thu, 18 Jun 2026 06:53:39 +0000 Subject: [PATCH 0130/1300] doc: add wikidata attributes (#40682) This PR adds a batch of 25 `@[wikidata]` attributes. Claude helped generate the list of crossrefs (by scanning Wikidata + Mathlib). Comments are generated by [crossref-report](https://github.com/jcommelin/mathlib-crossref-report) and Wikilean. See https://wikilean.jackmccarthy.org/review?pr=40682 for reviewer UI. --- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 3 ++- Mathlib/Data/Countable/Defs.lean | 3 ++- Mathlib/Geometry/Manifold/IsManifold/Basic.lean | 2 ++ Mathlib/GroupTheory/Solvable.lean | 3 ++- Mathlib/LinearAlgebra/Matrix/Defs.lean | 2 ++ Mathlib/MeasureTheory/MeasurableSpace/Defs.lean | 3 ++- Mathlib/NumberTheory/DirichletCharacter/Basic.lean | 2 ++ Mathlib/NumberTheory/LSeries/RiemannZeta.lean | 2 ++ Mathlib/NumberTheory/Padics/PadicNumbers.lean | 2 ++ Mathlib/NumberTheory/Real/Irrational.lean | 2 ++ Mathlib/Probability/CDF.lean | 2 ++ Mathlib/Probability/Distributions/Gaussian/Real.lean | 2 ++ Mathlib/Probability/Distributions/Poisson/Basic.lean | 2 ++ Mathlib/RingTheory/Coprime/Basic.lean | 2 ++ Mathlib/RingTheory/PowerSeries/Basic.lean | 2 ++ Mathlib/Topology/Defs/Basic.lean | 4 +++- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 2 ++ Mathlib/Topology/UniformSpace/UniformConvergence.lean | 2 ++ 18 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 6d2f1c5de950af..d1b86b494d8c74 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -11,6 +11,7 @@ public import Mathlib.Data.Rel public import Mathlib.Data.Set.Finite.Basic public import Mathlib.Data.Sym.Sym2 public import Mathlib.Order.CompleteBooleanAlgebra +public import Mathlib.Tactic.CrossRefAttribute /-! # Simple graphs @@ -88,7 +89,7 @@ The relation describes which pairs of vertices are adjacent. There is exactly one edge for every pair of adjacent vertices; see `SimpleGraph.edgeSet` for the corresponding edge set. -/ -@[ext, aesop safe constructors (rule_sets := [SimpleGraph])] +@[ext, aesop safe constructors (rule_sets := [SimpleGraph]), wikidata Q141488] structure SimpleGraph (V : Type u) where /-- The adjacency relation of a simple graph. -/ Adj : V → V → Prop diff --git a/Mathlib/Data/Countable/Defs.lean b/Mathlib/Data/Countable/Defs.lean index 2a85f6ab177fb3..e3b5df28b7d149 100644 --- a/Mathlib/Data/Countable/Defs.lean +++ b/Mathlib/Data/Countable/Defs.lean @@ -8,6 +8,7 @@ module public import Mathlib.Data.Finite.Defs public import Mathlib.Data.Bool.Basic public import Mathlib.Data.Subtype +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.MkIffOfInductiveProp /-! @@ -36,7 +37,7 @@ variable {α : Sort u} {β : Sort v} -/ /-- A type `α` is countable if there exists an injective map `α → ℕ`. -/ -@[mk_iff countable_iff_exists_injective] +@[mk_iff countable_iff_exists_injective, wikidata Q66707394] class Countable (α : Sort u) : Prop where /-- A type `α` is countable if there exists an injective map `α → ℕ`. -/ exists_injective_nat' : ∃ f : α → ℕ, Injective f diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 11fbcf447b60bd..5dc7b8202b1ab3 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.Normed.Module.Convex public import Mathlib.Analysis.RCLike.TangentCone public import Mathlib.Data.Bundle public import Mathlib.Geometry.Manifold.HasGroupoid +public import Mathlib.Tactic.CrossRefAttribute /-! # `C^n` manifolds (possibly with boundary or corners) @@ -1070,6 +1071,7 @@ variable (M) in -- is empty if the base manifold is empty /-- The tangent bundle to a manifold, as a Sigma type. Defined in terms of `Bundle.TotalSpace` to be able to put a suitable topology on it. -/ +@[wikidata Q746550] abbrev TangentBundle := Bundle.TotalSpace E (TangentSpace I : M → Type _) end TangentSpace diff --git a/Mathlib/GroupTheory/Solvable.lean b/Mathlib/GroupTheory/Solvable.lean index a72d318f20ef0e..9ec89956631467 100644 --- a/Mathlib/GroupTheory/Solvable.lean +++ b/Mathlib/GroupTheory/Solvable.lean @@ -10,6 +10,7 @@ public import Mathlib.GroupTheory.Abelianization.Defs public import Mathlib.GroupTheory.Perm.ViaEmbedding public import Mathlib.GroupTheory.Subgroup.Simple public import Mathlib.SetTheory.Cardinal.Order +public import Mathlib.Tactic.CrossRefAttribute /-! # Solvable Groups @@ -102,7 +103,7 @@ variable (G) /-- A group `G` is solvable if its derived series is eventually trivial. We use this definition because it's the most convenient one to work with. -/ -@[mk_iff isSolvable_def] +@[mk_iff isSolvable_def, wikidata Q759832] class IsSolvable : Prop where /-- A group `G` is solvable if its derived series is eventually trivial. -/ solvable : ∃ n : ℕ, derivedSeries G n = ⊥ diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index 4654757566793a..73ad6a744b33d9 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Module.Pi public import Mathlib.Logic.Nontrivial.Basic +public import Mathlib.Tactic.CrossRefAttribute /-! # Matrices @@ -50,6 +51,7 @@ universe u u' v w /-- `Matrix m n R` is the type of matrices with entries in `R`, whose rows are indexed by `m` and whose columns are indexed by `n`. -/ +@[wikidata Q44337] def Matrix (m : Type u) (n : Type u') (α : Type v) : Type max u u' v := m → n → α diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index a7e126d997a52b..d7965599471eca 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.Set.Countable public import Mathlib.Order.ConditionallyCompleteLattice.Basic +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.FunProp.Attr public import Mathlib.Tactic.Measurability @@ -489,7 +490,7 @@ end MeasurableSpace /-- A function `f` between measurable spaces is measurable if the preimage of every measurable set is measurable. -/ -@[fun_prop] +@[fun_prop, wikidata Q516776] def Measurable [MeasurableSpace α] [MeasurableSpace β] (f : α → β) : Prop := ∀ ⦃t : Set β⦄, MeasurableSet t → MeasurableSet (f ⁻¹' t) diff --git a/Mathlib/NumberTheory/DirichletCharacter/Basic.lean b/Mathlib/NumberTheory/DirichletCharacter/Basic.lean index 39d32385a7820e..2e86d6e8cf4339 100644 --- a/Mathlib/NumberTheory/DirichletCharacter/Basic.lean +++ b/Mathlib/NumberTheory/DirichletCharacter/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Algebra.Group.EvenFunction public import Mathlib.Data.ZMod.Units public import Mathlib.NumberTheory.MulChar.Basic +public import Mathlib.Tactic.CrossRefAttribute /-! # Dirichlet Characters @@ -35,6 +36,7 @@ dirichlet character, multiplicative character -/ /-- The type of Dirichlet characters of level `n`. -/ +@[wikidata Q1063579] abbrev DirichletCharacter (R : Type*) [CommMonoidWithZero R] (n : ℕ) := MulChar (ZMod n) R open MulChar diff --git a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean index 276c7e7c8635c2..fdff2c94adcfd8 100644 --- a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean +++ b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean @@ -7,6 +7,7 @@ module public import Mathlib.NumberTheory.LSeries.HurwitzZeta public import Mathlib.Analysis.PSeriesComplex +public import Mathlib.Tactic.CrossRefAttribute /-! # Definition of the Riemann zeta function @@ -179,6 +180,7 @@ theorem riemannZeta_one_sub {s : ℂ} (hs : ∀ n : ℕ, s ≠ -n) (hs' : s ≠ /-- A formal statement of the **Riemann hypothesis** – constructing a term of this type is worth a million dollars. -/ +@[wikidata Q205966] def RiemannHypothesis : Prop := ∀ (s : ℂ) (_ : riemannZeta s = 0) (_ : ¬∃ n : ℕ, s = -2 * (n + 1)) (_ : s ≠ 1), s.re = 1 / 2 diff --git a/Mathlib/NumberTheory/Padics/PadicNumbers.lean b/Mathlib/NumberTheory/Padics/PadicNumbers.lean index 937a475b3d77ec..a01f31fae82778 100644 --- a/Mathlib/NumberTheory/Padics/PadicNumbers.lean +++ b/Mathlib/NumberTheory/Padics/PadicNumbers.lean @@ -8,6 +8,7 @@ module public import Mathlib.RingTheory.Valuation.Basic public import Mathlib.NumberTheory.Padics.PadicNorm public import Mathlib.Analysis.Normed.Field.Lemmas +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.Peel public import Mathlib.Topology.MetricSpace.Ultra.Basic @@ -526,6 +527,7 @@ end PadicSeq /-- The `p`-adic numbers `ℚ_[p]` are the Cauchy completion of `ℚ` with respect to the `p`-adic norm. -/ +@[wikidata Q311627] def Padic (p : ℕ) [Fact p.Prime] := CauSeq.Completion.Cauchy (padicNorm p) deriving Zero, One, Add, Neg, Sub, Mul, Div, AddCommGroup, Ring, CommRing, Field, Inhabited diff --git a/Mathlib/NumberTheory/Real/Irrational.lean b/Mathlib/NumberTheory/Real/Irrational.lean index 16b276aef33605..763756b8560f64 100644 --- a/Mathlib/NumberTheory/Real/Irrational.lean +++ b/Mathlib/NumberTheory/Real/Irrational.lean @@ -10,6 +10,7 @@ public import Mathlib.Data.Nat.Prime.Int public import Mathlib.Data.Rat.Sqrt public import Mathlib.Analysis.Real.Sqrt public import Mathlib.RingTheory.Algebraic.Basic +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.IntervalCases /-! @@ -32,6 +33,7 @@ but this only works if you `unseal Nat.sqrt.iter in` before the theorem where yo open Rat Real /-- A real number is irrational if it is not equal to any rational number. -/ +@[wikidata Q607728] def Irrational (x : ℝ) := x ∉ Set.range ((↑) : ℚ → ℝ) diff --git a/Mathlib/Probability/CDF.lean b/Mathlib/Probability/CDF.lean index c145e7ffde0855..52656abe68af9d 100644 --- a/Mathlib/Probability/CDF.lean +++ b/Mathlib/Probability/CDF.lean @@ -6,6 +6,7 @@ Authors: Rémy Degenne module public import Mathlib.Probability.Kernel.Disintegration.CondCDF +public import Mathlib.Tactic.CrossRefAttribute /-! # Cumulative distribution function of a real probability measure @@ -51,6 +52,7 @@ namespace ProbabilityTheory /-- Cumulative distribution function of a real measure. The definition currently makes sense only for probability measures. In that case, it satisfies `cdf μ x = μ.real (Iic x)` (see `ProbabilityTheory.cdf_eq_real`). -/ +@[wikidata Q386228] noncomputable def cdf (μ : Measure ℝ) : StieltjesFunction ℝ := condCDF ((dirac Unit.unit).prod μ) Unit.unit diff --git a/Mathlib/Probability/Distributions/Gaussian/Real.lean b/Mathlib/Probability/Distributions/Gaussian/Real.lean index 0f4143516c8f8e..9b7b05e1bbfa7b 100644 --- a/Mathlib/Probability/Distributions/Gaussian/Real.lean +++ b/Mathlib/Probability/Distributions/Gaussian/Real.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.SpecialFunctions.Gaussian.FourierTransform public import Mathlib.Probability.HasLaw public import Mathlib.Probability.Moments.MGFAnalytic +public import Mathlib.Tactic.CrossRefAttribute /-! # Gaussian distributions over ℝ @@ -216,6 +217,7 @@ end GaussianPDF section GaussianReal /-- A Gaussian distribution on `ℝ` with mean `μ` and variance `v`. -/ +@[wikidata Q133871] noncomputable def gaussianReal (μ : ℝ) (v : ℝ≥0) : Measure ℝ := if v = 0 then Measure.dirac μ else volume.withDensity (gaussianPDF μ v) diff --git a/Mathlib/Probability/Distributions/Poisson/Basic.lean b/Mathlib/Probability/Distributions/Poisson/Basic.lean index 71b10edb13dd25..9b92070095b9a6 100644 --- a/Mathlib/Probability/Distributions/Poisson/Basic.lean +++ b/Mathlib/Probability/Distributions/Poisson/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.MeasureTheory.Measure.CharacteristicFunction.Basic public import Mathlib.Probability.HasLaw public import Mathlib.Probability.ProbabilityMassFunction.Basic +public import Mathlib.Tactic.CrossRefAttribute import Mathlib.LinearAlgebra.Complex.FiniteDimensional @@ -35,6 +36,7 @@ open scoped NNReal Nat namespace ProbabilityTheory /-- The poisson measure with rate `r : ℝ≥0` as a measure over `ℕ`. -/ +@[wikidata Q205692] noncomputable def poissonMeasure (r : ℝ≥0) : Measure ℕ := Measure.sum (fun n ↦ ENNReal.ofReal (exp (-r) * r ^ n / (n)!) • (.dirac n)) diff --git a/Mathlib/RingTheory/Coprime/Basic.lean b/Mathlib/RingTheory/Coprime/Basic.lean index 4aed62561adf65..2b88d64f35a22c 100644 --- a/Mathlib/RingTheory/Coprime/Basic.lean +++ b/Mathlib/RingTheory/Coprime/Basic.lean @@ -11,6 +11,7 @@ public import Mathlib.Algebra.GroupWithZero.Associated public import Mathlib.Algebra.Ring.Divisibility.Basic public import Mathlib.Algebra.Ring.Hom.Defs public import Mathlib.Logic.Basic +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.Ring /-! @@ -40,6 +41,7 @@ variable {R : Type u} [CommSemiring R] (x y z w : R) /-- The proposition that `x` and `y` are coprime, defined to be the existence of `a` and `b` such that `a * x + b * y = 1`. Note that elements with no common divisors are not necessarily coprime, e.g., the multivariate polynomials `x₁` and `x₂` are not coprime. -/ +@[wikidata Q104752] def IsCoprime : Prop := ∃ a b, a * x + b * y = 1 diff --git a/Mathlib/RingTheory/PowerSeries/Basic.lean b/Mathlib/RingTheory/PowerSeries/Basic.lean index 3cd109ae347e5d..b9c69c2a9e360c 100644 --- a/Mathlib/RingTheory/PowerSeries/Basic.lean +++ b/Mathlib/RingTheory/PowerSeries/Basic.lean @@ -9,6 +9,7 @@ public import Mathlib.Algebra.CharP.Defs public import Mathlib.Algebra.Polynomial.AlgebraMap public import Mathlib.Algebra.Polynomial.Basic public import Mathlib.RingTheory.MvPowerSeries.Basic +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.MoveAdd public import Mathlib.Algebra.MvPolynomial.Equiv public import Mathlib.RingTheory.Ideal.Basic @@ -55,6 +56,7 @@ noncomputable section open Finset (antidiagonal mem_antidiagonal) /-- Formal power series over a coefficient type `R` -/ +@[wikidata Q1003025] abbrev PowerSeries (R : Type*) := MvPowerSeries Unit R diff --git a/Mathlib/Topology/Defs/Basic.lean b/Mathlib/Topology/Defs/Basic.lean index c2976b51382d49..25731ef39ec5b2 100644 --- a/Mathlib/Topology/Defs/Basic.lean +++ b/Mathlib/Topology/Defs/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.Order.SetNotation public import Mathlib.Tactic.Continuity +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.FunProp public import Mathlib.Tactic.MkIffOfInductiveProp public import Mathlib.Data.Nat.Notation @@ -90,6 +91,7 @@ section Defs variable [TopologicalSpace X] [TopologicalSpace Y] {s t : Set X} /-- `IsOpen s` means that `s` is open in the ambient topological space on `X` -/ +@[wikidata Q213363] def IsOpen : Set X → Prop := TopologicalSpace.IsOpen @[simp] theorem isOpen_univ : IsOpen (univ : Set X) := TopologicalSpace.isOpen_univ @@ -148,7 +150,7 @@ def DenseRange {α : Type*} (f : α → X) := Dense (range f) /-- A function between topological spaces is continuous if the preimage of every open set is open. Registered as a structure to make sure it is not unfolded by Lean. -/ -@[fun_prop] +@[fun_prop, wikidata Q170058] structure Continuous (f : X → Y) : Prop where /-- The preimage of an open set under a continuous function is an open set. Use `IsOpen.preimage` instead. -/ diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index 334e1ae713a618..aabb1cb2b5e4d6 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.ENNReal.Real public import Mathlib.Tactic.Bound.Attribute +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.Bornology.Basic public import Mathlib.Topology.EMetricSpace.Defs public import Mathlib.Topology.UniformSpace.Basic @@ -365,6 +366,7 @@ namespace Metric variable {x y z : α} {δ ε ε₁ ε₂ : ℝ} {s : Set α} /-- `ball x ε` is the set of all points `y` with `dist y x < ε` -/ +@[wikidata Q838611] def ball (x : α) (ε : ℝ) : Set α := { y | dist y x < ε } diff --git a/Mathlib/Topology/UniformSpace/UniformConvergence.lean b/Mathlib/Topology/UniformSpace/UniformConvergence.lean index 4cd72c2a9f15e8..283de8651863b5 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergence.lean @@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel -/ module +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.UniformSpace.Cauchy /-! @@ -110,6 +111,7 @@ theorem tendstoUniformlyOn_iff_tendsto : /-- A sequence of functions `Fₙ` converges uniformly to a limiting function `f` with respect to a filter `p` if, for any entourage of the diagonal `u`, one has `p`-eventually `(f x, Fₙ x) ∈ u` for all `x`. -/ +@[wikidata Q1411887] def TendstoUniformly (F : ι → α → β) (f : α → β) (p : Filter ι) := ∀ u ∈ 𝓤 β, ∀ᶠ n in p, ∀ x : α, (f x, F n x) ∈ u From b1bc198f96e5c034c0fe49b89efa03e4067f9644 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 18 Jun 2026 07:34:46 +0000 Subject: [PATCH 0131/1300] chore: remove `using` clause from `convert` (#40738) The new `convert` is less aggressive so in many cases, the `using` clause is not needed anymore. In this PR I manually removed some of these. There are many more left to remove, ideally using some automation. --- Archive/Imo/Imo1959Q2.lean | 2 +- Archive/Imo/Imo2024Q3.lean | 6 +++--- Archive/Imo/Imo2024Q6.lean | 4 ++-- Archive/MinimalSheffer.lean | 2 +- Archive/MiuLanguage/DecisionSuf.lean | 4 ++-- .../AscendingDescendingSequences.lean | 2 +- .../CliffordAlgebraNotInjective.lean | 2 +- Counterexamples/Phillips.lean | 2 +- .../ZeroDivisorsInAddMonoidAlgebras.lean | 2 +- .../Algebra/Spectrum/Quasispectrum.lean | 10 +++++----- Mathlib/Algebra/GCDMonoid/Basic.lean | 2 +- Mathlib/Algebra/Group/ForwardDiff.lean | 2 +- Mathlib/Algebra/Jordan/Basic.lean | 2 +- Mathlib/Algebra/Lie/Basic.lean | 2 +- Mathlib/Algebra/Lie/Weights/IsSimple.lean | 2 +- Mathlib/Algebra/Lie/Weights/RootSystem.lean | 2 +- Mathlib/Algebra/Module/Submodule/Union.lean | 2 +- .../Order/BigOperators/Group/Finset.lean | 2 +- Mathlib/Algebra/Order/CauSeq/Basic.lean | 4 ++-- Mathlib/Algebra/Order/Field/Basic.lean | 10 +++++----- Mathlib/Algebra/Order/Floor/Ring.lean | 4 ++-- .../Algebra/Order/Module/HahnEmbedding.lean | 2 +- Mathlib/Algebra/Order/Ring/Archimedean.lean | 2 +- .../Polynomial/Degree/IsMonicOfDegree.lean | 2 +- Mathlib/Algebra/Polynomial/EraseLead.lean | 2 +- Mathlib/Algebra/Polynomial/Laurent.lean | 2 +- Mathlib/Algebra/Polynomial/RuleOfSigns.lean | 2 +- Mathlib/Algebra/QuadraticDiscriminant.lean | 2 +- Mathlib/Algebra/Regular/SMul.lean | 2 +- Mathlib/Algebra/Ring/Divisibility/Basic.lean | 2 +- Mathlib/Algebra/Ring/Idempotent.lean | 2 +- Mathlib/Algebra/Ring/Subring/Basic.lean | 2 +- Mathlib/Algebra/TrivSqZeroExt/Basic.lean | 2 +- Mathlib/AlgebraicGeometry/AffineScheme.lean | 2 +- .../AffineTransitionLimit.lean | 2 +- .../IdealSheaf/Subscheme.lean | 4 ++-- Mathlib/AlgebraicGeometry/Limits.lean | 2 +- .../AlgebraicGeometry/Morphisms/Affine.lean | 6 +++--- .../Morphisms/QuasiCompact.lean | 2 +- .../Morphisms/QuasiFinite.lean | 2 +- .../AlgebraicGeometry/Morphisms/Separated.lean | 2 +- .../Morphisms/UnderlyingMap.lean | 2 +- .../ProjectiveSpectrum/Proper.lean | 8 ++++---- .../ProjectiveSpectrum/Scheme.lean | 12 ++++++------ Mathlib/Analysis/Analytic/Basic.lean | 18 +++++++++--------- Mathlib/Analysis/Analytic/Binomial.lean | 12 ++++++------ Mathlib/Analysis/Analytic/OfScalars.lean | 2 +- Mathlib/Analysis/Asymptotics/Lemmas.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Spectrum.lean | 2 +- .../Calculus/ContDiff/Convolution.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Inv.lean | 4 ++-- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 2 +- .../Analysis/Calculus/FDeriv/Symmetric.lean | 2 +- Mathlib/Analysis/Calculus/LogDeriv.lean | 2 +- Mathlib/Analysis/Calculus/Taylor.lean | 4 ++-- Mathlib/Analysis/Complex/CoveringMap.lean | 4 ++-- Mathlib/Analysis/Complex/Exponential.lean | 4 ++-- Mathlib/Analysis/Complex/HasPrimitives.lean | 4 ++-- Mathlib/Analysis/Complex/Poisson.lean | 2 +- Mathlib/Analysis/Complex/TaylorSeries.lean | 2 +- .../ValueDistribution/FirstMainTheorem.lean | 2 +- Mathlib/Analysis/ConstantSpeed.lean | 4 ++-- Mathlib/Analysis/Convex/Basic.lean | 2 +- Mathlib/Analysis/Convex/Deriv.lean | 4 ++-- Mathlib/Analysis/Convex/PathConnected.lean | 2 +- Mathlib/Analysis/Convex/Segment.lean | 4 ++-- Mathlib/Analysis/Distribution/Sobolev.lean | 2 +- .../Analysis/Distribution/TemperateGrowth.lean | 2 +- Mathlib/Analysis/Fourier/AddCircle.lean | 4 ++-- .../FunctionalSpaces/SobolevInequality.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Basic.lean | 2 +- .../Analysis/InnerProductSpace/LinearPMap.lean | 2 +- .../Analysis/InnerProductSpace/NormPow.lean | 2 +- Mathlib/Analysis/InnerProductSpace/OfNorm.lean | 6 +++--- .../Analysis/InnerProductSpace/Orthogonal.lean | 2 +- .../InnerProductSpace/Projection/Basic.lean | 2 +- .../Projection/Reflection.lean | 2 +- .../Projection/Submodule.lean | 4 ++-- Mathlib/Analysis/MeanInequalities.lean | 13 ++++++------- Mathlib/Analysis/MeanInequalitiesPow.lean | 2 +- Mathlib/Analysis/Meromorphic/Basic.lean | 8 ++++---- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 2 +- Mathlib/Analysis/Normed/Group/Basic.lean | 2 +- Mathlib/Analysis/SumOverResidueClass.lean | 2 +- 84 files changed, 142 insertions(+), 143 deletions(-) diff --git a/Archive/Imo/Imo1959Q2.lean b/Archive/Imo/Imo1959Q2.lean index 808f53a5984f23..2ac53efe02d11f 100644 --- a/Archive/Imo/Imo1959Q2.lean +++ b/Archive/Imo/Imo1959Q2.lean @@ -60,7 +60,7 @@ theorem sqrt_two_mul_sub_one_le_one : sqrt (2 * x - 1) ≤ 1 ↔ x ≤ 1 := by theorem isGood_iff_eq_sqrt_two (hx : x ∈ Icc (1 / 2) 1) : IsGood x A ↔ A = sqrt 2 := by have : sqrt (2 * x - 1) ≤ 1 := sqrt_two_mul_sub_one_le_one.2 hx.2 simp only [isGood_iff, hx.1, abs_sub_comm _ (1 : ℝ), abs_of_nonneg (sub_nonneg.2 this), and_true] - suffices 2 = A * sqrt 2 ↔ A = sqrt 2 by convert! this using 2; ring + suffices 2 = A * sqrt 2 ↔ A = sqrt 2 by convert this; ring rw [← div_eq_iff, div_sqrt, eq_comm] positivity diff --git a/Archive/Imo/Imo2024Q3.lean b/Archive/Imo/Imo2024Q3.lean index ea807ad1b99c00..2c51652ba0ffd4 100644 --- a/Archive/Imo/Imo2024Q3.lean +++ b/Archive/Imo/Imo2024Q3.lean @@ -938,7 +938,7 @@ lemma exists_a_apply_add_eq : ∃ b c, 0 < c ∧ ∀ n, b < n → have := hc.p_pos (N' a N + 2 * (b + 2)) rcases hc.even_p (by lia) (hs (b + 2)) with ⟨_, _⟩ lia - · convert! hc.apply_add_p_eq (by lia) (hs n) using 3 + · convert hc.apply_add_p_eq (by lia) (hs n) rcases hc.even_p (by lia) (hs n) with ⟨_, ht⟩ simp [ht, ← two_mul] @@ -949,8 +949,8 @@ theorem result {a : ℕ → ℕ} {N : ℕ} (h : Condition a N) : obtain ⟨b, c, hc, hbc⟩ := h.exists_a_apply_add_eq a N obtain ⟨t, _⟩ | ⟨t, _⟩ := Nat.even_or_odd (Condition.N' a N) · refine .inl ⟨c, Condition.N' a N / 2 + b + 1, hc, fun m hm ↦ ?_⟩ - convert! hbc (m - t) (by lia) using 1 <;> dsimp only <;> congr <;> lia + convert hbc (m - t) (by lia) <;> lia · refine .inr ⟨c, Condition.N' a N / 2 + b + 1, hc, fun m hm ↦ ?_⟩ - convert! hbc (m - t) (by lia) using 1 <;> dsimp only <;> congr 1 <;> lia + convert hbc (m - t) (by lia) using 2 <;> lia end Imo2024Q3 diff --git a/Archive/Imo/Imo2024Q6.lean b/Archive/Imo/Imo2024Q6.lean index 422898498003a3..84fc79eb2061d0 100644 --- a/Archive/Imo/Imo2024Q6.lean +++ b/Archive/Imo/Imo2024Q6.lean @@ -57,7 +57,7 @@ lemma Aquaesulian.injective : Function.Injective f := by lemma Aquaesulian.apply_zero : f 0 = 0 := by refine h.injective ?_ - convert! h.apply_apply_add 0 using 1 <;> simp + convert h.apply_apply_add 0 <;> simp @[simp] lemma Aquaesulian.apply_neg_apply_add (x : G) : f (-(f x)) + x = 0 := by @@ -80,7 +80,7 @@ lemma Aquaesulian.apply_neg_of_apply_eq {x₁ x₂ : G} (hx : f x₁ = x₂) : f lemma Aquaesulian.apply_neg_eq_neg_iff {x₁ x₂ : G} : f (-x₂) = -x₁ ↔ f x₁ = x₂ := by refine ⟨fun hn ↦ ?_, h.apply_neg_of_apply_eq⟩ - convert! h.apply_neg_of_apply_eq hn <;> rw [neg_neg] + convert h.apply_neg_of_apply_eq hn <;> rw [neg_neg] lemma Aquaesulian.pair_lemma {x u v : G} (huv : u ≠ v) (hx : f x = u ∨ f u = x) (hy : f x = v ∨ f v = x) : f x = v ∨ f x = u := by diff --git a/Archive/MinimalSheffer.lean b/Archive/MinimalSheffer.lean index 329aa377c84033..19f9bbef6f1d99 100644 --- a/Archive/MinimalSheffer.lean +++ b/Archive/MinimalSheffer.lean @@ -121,7 +121,7 @@ lemma sup_le (h₁ : a ≤ c) (h₂ : b ≤ c) : aᶜ | bᶜ ≤ c := by rw [h₂] have l1 := (abba (aᶜ | (b | c)) (b | c | c)).symm rw [comm _ (aᶜ | _), ← le_def] at l1 - convert! l1 using 1 + convert l1 have l2 := veroff (b | c) c a rw [comm _ a, ← h₁, comm, comm _ aᶜ] at l2 nth_rw 1 [l2, comm (b | c) c, comm b, veroff] diff --git a/Archive/MiuLanguage/DecisionSuf.lean b/Archive/MiuLanguage/DecisionSuf.lean index e4b1c5f4d9f5fd..5cc67b253b8bfc 100644 --- a/Archive/MiuLanguage/DecisionSuf.lean +++ b/Archive/MiuLanguage/DecisionSuf.lean @@ -194,7 +194,7 @@ theorem der_replicate_I_of_mod3 (c : ℕ) (h : c % 3 = 1 ∨ c % 3 = 2) : replicate ((2 ^ m - c) / 3) U ++ replicate ((2 ^ m - c) / 3 % 2) U) := by apply der_cons_replicate_I_replicate_U_append_of_der_cons_replicate_I_append c ((2 ^ m - c) / 3) h - convert! hw₂ using 4 + convert hw₂ -- now we must show `c + 3 * ((2 ^ m - c) / 3) = 2 ^ m` rw [Nat.mul_div_cancel'] · exact add_tsub_cancel_of_le hm.1 @@ -220,7 +220,7 @@ example (c : ℕ) (h : c % 3 = 1 ∨ c % 3 = 2) : Derivable (M :: replicate c I) replicate ((2 ^ m - c) / 3) U ++ replicate ((2 ^ m - c) / 3 % 2) U) := by apply der_cons_replicate_I_replicate_U_append_of_der_cons_replicate_I_append c ((2 ^ m - c) / 3) h - convert! hw₂ using 4 + convert hw₂ -- now we must show `c + 3 * ((2 ^ m - c) / 3) = 2 ^ m` rw [Nat.mul_div_cancel'] · exact add_tsub_cancel_of_le hm.1 diff --git a/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean b/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean index ec92034f0ad98c..b9480c2046155a 100644 --- a/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean +++ b/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean @@ -91,7 +91,7 @@ private lemma maxIncSequencesTo_lt {i j : α} (hij : i < j) (hfij : f i < f j) : exact (hti.2 hx).trans_lt hij refine ⟨insert j t, ?_, ?_, ?_⟩ next => - convert! hti.insert j using 1 + convert hti.insert j next => simp next => rw [max_eq_left hij.le] next => diff --git a/Counterexamples/CliffordAlgebraNotInjective.lean b/Counterexamples/CliffordAlgebraNotInjective.lean index 1d52202222ca50..f47f319b0e9f62 100644 --- a/Counterexamples/CliffordAlgebraNotInjective.lean +++ b/Counterexamples/CliffordAlgebraNotInjective.lean @@ -234,7 +234,7 @@ theorem quot_obv : α • x' - β • y' - γ • z' = 0 := by dsimp only [gen] simp_rw [← map_smul, ← map_sub, ← Submodule.Quotient.mk_smul _ (_ : K), ← Submodule.Quotient.mk_sub] - convert! LinearMap.map_zero _ using 2 + convert LinearMap.map_zero _ rw [Submodule.Quotient.mk_eq_zero] simp +decide [sub_zero] diff --git a/Counterexamples/Phillips.lean b/Counterexamples/Phillips.lean index 026e8594775262..1fc73e0eda9341 100644 --- a/Counterexamples/Phillips.lean +++ b/Counterexamples/Phillips.lean @@ -360,7 +360,7 @@ theorem discretePart_apply (f : BoundedAdditiveMeasure α) (s : Set α) : theorem continuousPart_apply_eq_zero_of_countable (f : BoundedAdditiveMeasure α) (s : Set α) (hs : s.Countable) : f.continuousPart s = 0 := by simp only [continuousPart, restrict_apply] - convert! f.apply_countable s hs using 2 + convert f.apply_countable s hs ext x simp [and_comm] diff --git a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean index 4a9c213dd49407..03e41b3f218856 100644 --- a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean +++ b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean @@ -97,7 +97,7 @@ theorem zero_divisors_of_torsion {R A} [Nontrivial R] [Ring R] [AddMonoid A] (a (nsmul_ne_zero_of_lt_addOrderOf one_ne_zero (Nat.succ_le_iff.mp o2)) simp only [a0, single_eq_of_ne', Ne, not_false_iff] · simpa only [single_eq_same] using zero_ne_one - · convert! Commute.geom_sum₂_mul (R := AddMonoidAlgebra R A) _ (addOrderOf a) using 3 + · convert Commute.geom_sum₂_mul (R := AddMonoidAlgebra R A) _ (addOrderOf a) · rw [single_zero_one, one_pow, mul_one] · rw [single_pow, one_pow, addOrderOf_nsmul_eq_zero, single_zero_one, one_pow, sub_self] · simp only [single_zero_one, Commute.one_right] diff --git a/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean b/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean index 352921912f0081..01711a7aa8dadb 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean @@ -156,13 +156,13 @@ def unitsFstOne_mulEquiv_quasiregular : unitsFstOne R A ≃* (PreQuasiregular A) { val := 1 + PreQuasiregular.equiv.symm x.val inv := 1 + PreQuasiregular.equiv.symm x⁻¹.val val_inv := by - convert! congr((1 + $(inv_add_add_mul_eq_zero x) : Unitization R A)) using 1 + convert congr((1 + $(inv_add_add_mul_eq_zero x) : Unitization R A)) · simp only [mul_one, PreQuasiregular.equiv_symm_apply, one_mul, mul_add, add_mul, inr_add, inr_mul] abel · simp only [inr_zero, add_zero] inv_val := by - convert! congr((1 + $(add_inv_add_mul_eq_zero x) : Unitization R A)) using 1 + convert congr((1 + $(add_inv_add_mul_eq_zero x) : Unitization R A)) · simp only [mul_one, PreQuasiregular.equiv_symm_apply, one_mul, mul_add, add_mul, inr_add, inr_mul] abel @@ -216,8 +216,8 @@ lemma IsQuasiregular.isUnit_one_add {R : Type*} [Semiring R] {x : R} (hx : IsQua IsUnit (1 + x) := by obtain ⟨y, hy₁, hy₂⟩ := isQuasiregular_iff.mp hx refine ⟨⟨1 + x, 1 + y, ?_, ?_⟩, rfl⟩ - · convert! congr(1 + $(hy₁)) using 1 <;> [noncomm_ring; simp] - · convert! congr(1 + $(hy₂)) using 1 <;> [noncomm_ring; simp] + · convert congr(1 + $(hy₁)) <;> [noncomm_ring; simp] + · convert congr(1 + $(hy₂)) <;> [noncomm_ring; simp] lemma isQuasiregular_iff_isUnit {R : Type*} [Ring R] {x : R} : IsQuasiregular x ↔ IsUnit (1 + x) := by @@ -229,7 +229,7 @@ lemma isQuasiregular_iff_isUnit {R : Type*} [Ring R] {x : R} : case' h.right => have := congr($(hx.val_inv_mul) - 1) all_goals rw [← sub_add_cancel (↑hx.unit⁻¹ : R) 1, sub_self] at this - convert! this using 1 + convert this noncomm_ring -- interestingly, this holds even in the semiring case. diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index 5c5fb38a783f39..2bafbe6eb818b4 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -624,7 +624,7 @@ theorem isUnit_gcd_of_eq_mul_gcd {α : Type*} [CommMonoidWithZero α] [GCDMonoid IsUnit (gcd x' y') := by rw [← associated_one_iff_isUnit] refine Associated.of_mul_left ?_ (Associated.refl <| gcd x y) h - convert! (gcd_mul_left' (gcd x y) x' y').symm using 1 + convert (gcd_mul_left' (gcd x y) x' y').symm rw [← ex, ← ey, mul_one] theorem extract_gcd {α : Type*} [CommMonoidWithZero α] [GCDMonoid α] (x y : α) : diff --git a/Mathlib/Algebra/Group/ForwardDiff.lean b/Mathlib/Algebra/Group/ForwardDiff.lean index 2c95d310a551fa..90a86ed78e6758 100644 --- a/Mathlib/Algebra/Group/ForwardDiff.lean +++ b/Mathlib/Algebra/Group/ForwardDiff.lean @@ -151,7 +151,7 @@ theorem fwdDiff_iter_eq_sum_shift (f : M → G) (n : ℕ) (y : M) : rw [← coe_fwdDiffₗ, this, ← Module.End.pow_apply] -- use binomial theorem `Commute.add_pow` to expand this have : Commute (shiftₗ M G h) (-1) := (Commute.one_right _).neg_right - convert! congr_fun (LinearMap.congr_fun (this.add_pow n) f) y using 3 + convert congr_fun (LinearMap.congr_fun (this.add_pow n) f) y · simp only [sub_eq_add_neg] · rw [LinearMap.sum_apply, sum_apply] congr 1 with k diff --git a/Mathlib/Algebra/Jordan/Basic.lean b/Mathlib/Algebra/Jordan/Basic.lean index 937a2df977f828..55dfe8ff8daaae 100644 --- a/Mathlib/Algebra/Jordan/Basic.lean +++ b/Mathlib/Algebra/Jordan/Basic.lean @@ -165,7 +165,7 @@ theorem two_nsmul_lie_lmul_lmul_add_eq_lie_lmul_lmul_add [IsCommJordan A] (a b : 2 • (⁅L a, L (a * b)⁆ + ⁅L b, L (b * a)⁆) = ⁅L (a * a), L b⁆ + ⁅L (b * b), L a⁆ := by suffices 2 • ⁅L a, L (a * b)⁆ + 2 • ⁅L b, L (b * a)⁆ + ⁅L b, L (a * a)⁆ + ⁅L a, L (b * b)⁆ = 0 by rwa [← sub_eq_zero, ← sub_sub, sub_eq_add_neg, sub_eq_add_neg, lie_skew, lie_skew, nsmul_add] - convert! (commute_lmul_lmul_sq (a + b)).lie_eq using 1 + convert (commute_lmul_lmul_sq (a + b)).lie_eq simp only [add_mul, mul_add, map_add, lie_add, add_lie, mul_comm b a, (commute_lmul_lmul_sq a).lie_eq, (commute_lmul_lmul_sq b).lie_eq, zero_add, add_zero, two_smul] abel diff --git a/Mathlib/Algebra/Lie/Basic.lean b/Mathlib/Algebra/Lie/Basic.lean index 71797fc47faf5f..e90318b3481721 100644 --- a/Mathlib/Algebra/Lie/Basic.lean +++ b/Mathlib/Algebra/Lie/Basic.lean @@ -121,7 +121,7 @@ lemma lie_swap_lie [Bracket L₂ L₁] [AddCommGroup M] [IsLieTower L₁ L₂ M] (x : L₁) (y : L₂) (m : M) : ⁅⁅x, y⁆, m⁆ = -⁅⁅y, x⁆, m⁆ := by have h1 := leibniz_lie x y m have h2 := leibniz_lie y x m - convert! congr($h1.symm - $h2) using 1 <;> simp only [add_sub_cancel_right, sub_add_cancel_right] + convert congr($h1.symm - $h2) <;> simp only [add_sub_cancel_right, sub_add_cancel_right] end IsLieTower diff --git a/Mathlib/Algebra/Lie/Weights/IsSimple.lean b/Mathlib/Algebra/Lie/Weights/IsSimple.lean index 46c7955c7d3236..fedb3e7ceb88fa 100644 --- a/Mathlib/Algebra/Lie/Weights/IsSimple.lean +++ b/Mathlib/Algebra/Lie/Weights/IsSimple.lean @@ -324,7 +324,7 @@ private theorem chi_not_in_q_aux (h_chi_not_in_q : ↑χ ∉ q) : rw [hi] at h_equiv exact h_chi_not_in_q (h_equiv.mpr (by rw [hj, Weight.toLinear_neg] - convert! q.smul_mem (-1) hαq using 1 + convert q.smul_mem (-1) hαq rw [neg_smul, one_smul])) obtain ⟨i, hi⟩ := exists_root_index χ (Weight.coe_toLinear_ne_zero_iff.mp w_chi) obtain ⟨j, hj⟩ := exists_root_index α hα₀ diff --git a/Mathlib/Algebra/Lie/Weights/RootSystem.lean b/Mathlib/Algebra/Lie/Weights/RootSystem.lean index b5674c3c1754bf..15e5b3055a9dff 100644 --- a/Mathlib/Algebra/Lie/Weights/RootSystem.lean +++ b/Mathlib/Algebra/Lie/Weights/RootSystem.lean @@ -274,7 +274,7 @@ lemma chainTopCoeff_zero_right [Nontrivial L] (hα : α.IsNonZero) : obtain ⟨k, hk⟩ : ∃ k : K, k • f = (toEnd K L L f ^ (chainTopCoeff α (0 : Weight K H L) + 1)) x := by have : (toEnd K L L f ^ (chainTopCoeff α (0 : Weight K H L) + 1)) x ∈ rootSpace H (-α) := by - convert! toEnd_pow_apply_mem hf hx (chainTopCoeff α (0 : Weight K H L) + 1) using 2 + convert toEnd_pow_apply_mem hf hx (chainTopCoeff α (0 : Weight K H L) + 1) rw [coe_chainTop', Weight.coe_zero, add_zero, succ_nsmul', add_assoc, smul_neg, neg_add_cancel, add_zero] simpa using! (finrank_eq_one_iff_of_nonzero' ⟨f, hf⟩ (by simpa using! isSl2.f_ne_zero)).mp diff --git a/Mathlib/Algebra/Module/Submodule/Union.lean b/Mathlib/Algebra/Module/Submodule/Union.lean index 1573543bc065ef..8a1c1deb6ef30c 100644 --- a/Mathlib/Algebra/Module/Submodule/Union.lean +++ b/Mathlib/Algebra/Module/Submodule/Union.lean @@ -79,7 +79,7 @@ lemma Submodule.iUnion_ssubset_of_forall_ne_top_of_card_lt (s : Finset ι) (p : obtain ⟨z₁, -, z₂, -, h⟩ := exists_ne_map_eq_of_encard_lt_of_maps_to (by simpa) hf' exact ⟨z₁, z₂, h⟩ replace ht : y ∈ p k := by - have : (t₁ - t₂) • y ∈ p k := by convert! sub_mem ht₁ ht₂ using 1; module + have : (t₁ - t₂) • y ∈ p k := by convert sub_mem ht₁ ht₂; module refine ((p k).smul_mem_iff ?_).mp this rwa [sub_ne_zero] replace ht : x ∈ p k := by convert sub_mem ht₁ ((p k).smul_mem t₁ ht); simp diff --git a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean index 1da58707e8c8cc..cf94a12bd7304e 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean @@ -677,7 +677,7 @@ alias finset_sum_eq_sup_iff_disjoint := finsetSum_eq_sup_iff_disjoint theorem sup_powerset_len [DecidableEq α] (x : Multiset α) : (Finset.sup (Finset.range (card x + 1)) fun k => x.powersetCard k) = x.powerset := by - convert! bind_powerset_len x using 1 + convert bind_powerset_len x rw [Multiset.bind, Multiset.join, ← Finset.range_val, ← Finset.sum_eq_multiset_sum] exact Eq.symm (finsetSum_eq_sup_iff_disjoint.mpr fun _ _ _ _ h => pairwise_disjoint_powersetCard x h) diff --git a/Mathlib/Algebra/Order/CauSeq/Basic.lean b/Mathlib/Algebra/Order/CauSeq/Basic.lean index 6d999ed68ba29d..c3f8165c29f6db 100644 --- a/Mathlib/Algebra/Order/CauSeq/Basic.lean +++ b/Mathlib/Algebra/Order/CauSeq/Basic.lean @@ -631,7 +631,7 @@ instance : LE (CauSeq α abs) := theorem lt_of_lt_of_eq {f g h : CauSeq α abs} (fg : f < g) (gh : g ≈ h) : f < h := show Pos (h - f) by - convert! pos_add_limZero fg (neg_limZero gh) using 1 + convert pos_add_limZero fg (neg_limZero gh) simp theorem lt_of_eq_of_lt {f g h : CauSeq α abs} (fg : f ≈ g) (gh : g < h) : f < h := by @@ -640,7 +640,7 @@ theorem lt_of_eq_of_lt {f g h : CauSeq α abs} (fg : f ≈ g) (gh : g < h) : f < theorem lt_trans {f g h : CauSeq α abs} (fg : f < g) (gh : g < h) : f < h := show Pos (h - f) by - convert! add_pos fg gh using 1 + convert add_pos fg gh simp theorem lt_irrefl {f : CauSeq α abs} : ¬f < f diff --git a/Mathlib/Algebra/Order/Field/Basic.lean b/Mathlib/Algebra/Order/Field/Basic.lean index 6db675d49c48a0..ca4d841b0657e8 100644 --- a/Mathlib/Algebra/Order/Field/Basic.lean +++ b/Mathlib/Algebra/Order/Field/Basic.lean @@ -217,10 +217,10 @@ theorem inv_strictAntiOn : StrictAntiOn (fun x : α => x⁻¹) (Set.Ioi 0) := fu (inv_lt_inv₀ hy hx).2 xy theorem inv_pow_le_inv_pow_of_le (a1 : 1 ≤ a) {m n : ℕ} (mn : m ≤ n) : (a ^ n)⁻¹ ≤ (a ^ m)⁻¹ := by - convert! one_div_pow_le_one_div_pow_of_le a1 mn using 1 <;> simp + convert one_div_pow_le_one_div_pow_of_le a1 mn <;> simp theorem inv_pow_lt_inv_pow_of_lt (a1 : 1 < a) {m n : ℕ} (mn : m < n) : (a ^ n)⁻¹ < (a ^ m)⁻¹ := by - convert! one_div_pow_lt_one_div_pow_of_lt a1 mn using 1 <;> simp + convert one_div_pow_lt_one_div_pow_of_lt a1 mn <;> simp theorem inv_pow_anti (a1 : 1 ≤ a) : Antitone fun n : ℕ => (a ^ n)⁻¹ := fun _ _ => inv_pow_le_inv_pow_of_le a1 @@ -236,11 +236,11 @@ theorem le_iff_forall_one_lt_le_mul₀ {α : Type*} · simp_rw [zero_mul] at h exact h 2 one_lt_two refine le_of_forall_gt_imp_ge_of_dense fun x hbx => ?_ - convert! h (x / b) ((one_lt_div hb).mpr hbx) + convert h (x / b) ((one_lt_div hb).mpr hbx) rw [mul_div_cancel₀ _ hb.ne'] theorem div_nat_le_self_of_nonnneg (ha : 0 ≤ a) (n : ℕ) : a / n ≤ a := - if h : n = 0 then by simpa [h] using ha + if h : n = 0 then by simpa [h] else div_le_self ha (n.one_le_cast_iff_ne_zero.mpr h) theorem div_nat_lt_self_of_pos_of_two_le (ha : 0 < a) {n : ℕ} (hn : 2 ≤ n) : a / n < a := @@ -538,7 +538,7 @@ theorem sub_one_div_inv_le_two (a2 : 2 ≤ a) : (1 - 1 / a)⁻¹ ≤ 2 := by -- move `1 / a` to the left and `2⁻¹` to the right. rw [le_sub_iff_add_le, add_comm, ← le_sub_iff_add_le] -- take inverses on both sides and use the assumption `2 ≤ a`. - convert! (one_div a).le.trans (inv_anti₀ zero_lt_two a2) using 1 + convert (one_div a).le.trans (inv_anti₀ zero_lt_two a2) -- show `1 - 1 / 2 = 1 / 2`. -- show `1 - 1 / 2 = 1 / 2`. diff --git a/Mathlib/Algebra/Order/Floor/Ring.lean b/Mathlib/Algebra/Order/Floor/Ring.lean index 3537d313859ee3..a7b86a5d802241 100644 --- a/Mathlib/Algebra/Order/Floor/Ring.lean +++ b/Mathlib/Algebra/Order/Floor/Ring.lean @@ -671,7 +671,7 @@ theorem ceil_sub_intCast (a : R) (z : ℤ) : ⌈a - z⌉ = ⌈a⌉ - z := @[simp] theorem ceil_sub_natCast (a : R) (n : ℕ) : ⌈a - n⌉ = ⌈a⌉ - n := by - convert! ceil_sub_intCast a n using 1 + convert ceil_sub_intCast a n simp @[simp] @@ -769,7 +769,7 @@ lemma ceil_div_ceil_inv_sub_one (ha : 1 ≤ a) : ⌈⌈(a - 1)⁻¹⌉ / a⌉ = refine le_antisymm (ceil_le.2 <| div_le_self (by positivity) ha.le) <| ?_ rw [le_ceil_iff, sub_lt_comm, div_eq_mul_inv, ← mul_one_sub, ← lt_div_iff₀ (sub_pos.2 <| inv_lt_one_of_one_lt₀ ha)] - convert! ceil_lt_add_one (R := k) _ using 1 + convert ceil_lt_add_one (R := k) _ field lemma ceil_lt_mul (hb : 1 < b) (hba : ⌈(b - 1)⁻¹⌉ / b < a) : ⌈a⌉ < b * a := by diff --git a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean index 8bbb9bd0db33c6..e9101fdda6f68b 100644 --- a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean +++ b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean @@ -545,7 +545,7 @@ theorem isWF_support_evalCoeff [IsOrderedAddMonoid R] [Archimedean R] (x : M) : have hmem' (n : ℕ) : seq n ∈ (ofLex (f.val y)).coeff.support := by specialize hmem n rw [Function.mem_support] at ⊢ hmem - convert! hmem using 1 + convert hmem refine (f.evalCoeff_eq ((ball_strictAnti K).antitone ?_ hy)).symm simpa using hanti.antitone (show 0 ≤ n by simp) obtain hwf := (ofLex (f.val y)).isWF_support diff --git a/Mathlib/Algebra/Order/Ring/Archimedean.lean b/Mathlib/Algebra/Order/Ring/Archimedean.lean index 6bc0565a98cf90..ad71ce19de201b 100644 --- a/Mathlib/Algebra/Order/Ring/Archimedean.lean +++ b/Mathlib/Algebra/Order/Ring/Archimedean.lean @@ -62,7 +62,7 @@ private theorem mk_mul_le_of_le {x₁ y₁ x₂ y₂ : R} (hx : mk x₁ ≤ mk x obtain ⟨m, hm⟩ := hx obtain ⟨n, hn⟩ := hy use m * n - convert! mul_le_mul hm hn (abs_nonneg _) (nsmul_nonneg (abs_nonneg _) _) using 1 <;> + convert mul_le_mul hm hn (abs_nonneg _) (nsmul_nonneg (abs_nonneg _) _) <;> simp_rw [ArchimedeanOrder.val_of, abs_mul] ring diff --git a/Mathlib/Algebra/Polynomial/Degree/IsMonicOfDegree.lean b/Mathlib/Algebra/Polynomial/Degree/IsMonicOfDegree.lean index 0acdfb7850f3fb..9ab22b4f95c7cc 100644 --- a/Mathlib/Algebra/Polynomial/Degree/IsMonicOfDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/IsMonicOfDegree.lean @@ -267,7 +267,7 @@ lemma IsMonicOfDegree.of_dvd_add {a b r : R[X]} {m n : ℕ} (hmn : n ≤ m) (ha lemma IsMonicOfDegree.of_dvd_sub {a b r : R[X]} {m n : ℕ} (hmn : n ≤ m) (ha : IsMonicOfDegree a m) (hb : IsMonicOfDegree b n) (hr : r.natDegree < m) (h : b ∣ a - r) : ∃ q : R[X], IsMonicOfDegree q (m - n) ∧ a = q * b + r := by - convert! ha.of_dvd_add hmn hb ?_ h using 4 with q + convert ha.of_dvd_add hmn hb ?_ h with q · rw [sub_neg_eq_add] · rwa [natDegree_neg] diff --git a/Mathlib/Algebra/Polynomial/EraseLead.lean b/Mathlib/Algebra/Polynomial/EraseLead.lean index ce8b63e2e27be0..54af338b94faea 100644 --- a/Mathlib/Algebra/Polynomial/EraseLead.lean +++ b/Mathlib/Algebra/Polynomial/EraseLead.lean @@ -327,7 +327,7 @@ theorem induction_with_natDegree_le (motive : R[X] → Prop) (N : ℕ) (zero : m | succ c hc => rw [← eraseLead_add_C_mul_X_pow f] cases c - · convert! C_mul_pow f.natDegree f.leadingCoeff ?_ df using 1 + · convert C_mul_pow f.natDegree f.leadingCoeff ?_ df · convert! zero_add (C (leadingCoeff f) * X ^ f.natDegree) rw [← card_support_eq_zero, card_support_eraseLead' hf] · rw [leadingCoeff_ne_zero, Ne, ← card_support_eq_zero, hf] diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index e3b674a50ed46d..c0c049fb4ab09e 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -375,7 +375,7 @@ theorem reduce_to_polynomial_of_mul_T (f : R[T;T⁻¹]) {Q : R[T;T⁻¹] → Pro induction f using LaurentPolynomial.induction_on_mul_T with | _ f n induction n with | zero => simpa only [Nat.cast_zero, neg_zero, T_zero, mul_one] using Qf _ - | succ n hn => convert! QT _ _; simpa using hn + | succ n hn => convert QT _ _; simpa section Support diff --git a/Mathlib/Algebra/Polynomial/RuleOfSigns.lean b/Mathlib/Algebra/Polynomial/RuleOfSigns.lean index 6a3f307dd88e4d..7cddfd744d4758 100644 --- a/Mathlib/Algebra/Polynomial/RuleOfSigns.lean +++ b/Mathlib/Algebra/Polynomial/RuleOfSigns.lean @@ -209,7 +209,7 @@ lemma signVariations_eraseLead_mul_X_sub_C (hη : 0 < η) (hP₀ : 0 < leadingCo lemma succ_signVariations_X_sub_C_mul_monomial {d c} (hc : c ≠ 0) (hη : 0 < η) : (monomial d c).signVariations + 1 ≤ ((X - C η) * monomial d c).signVariations := by have h₁ : nextCoeff ((X - C η) * monomial d c) = -(η * c) := by - convert! coeff_mul_monomial (X - C η) d 0 c using 1 + convert coeff_mul_monomial (X - C η) d 0 c · simp [hc, nextCoeff, natDegree_mul (X_sub_C_ne_zero η)] · simp have h₂ : eraseLead ((X - C η) * monomial d c) ≠ 0 := by diff --git a/Mathlib/Algebra/QuadraticDiscriminant.lean b/Mathlib/Algebra/QuadraticDiscriminant.lean index d468d87f32ef32..3b663b49b48ba3 100644 --- a/Mathlib/Algebra/QuadraticDiscriminant.lean +++ b/Mathlib/Algebra/QuadraticDiscriminant.lean @@ -139,7 +139,7 @@ theorem discrim_le_zero (h : ∀ x : K, 0 ≤ a * (x * x) + b * x + c) : discrim linarith -- if a > 0 · have ha' : 0 ≤ 4 * a := mul_nonneg zero_le_four ha.le - convert! neg_nonpos.2 (mul_nonneg ha' (h (-b / (2 * a)))) using 1 + convert neg_nonpos.2 (mul_nonneg ha' (h (-b / (2 * a)))) field lemma discrim_le_zero_of_nonpos (h : ∀ x : K, a * (x * x) + b * x + c ≤ 0) : discrim a b c ≤ 0 := diff --git a/Mathlib/Algebra/Regular/SMul.lean b/Mathlib/Algebra/Regular/SMul.lean index 3d343ced450708..4ba3c9dbceed3a 100644 --- a/Mathlib/Algebra/Regular/SMul.lean +++ b/Mathlib/Algebra/Regular/SMul.lean @@ -224,7 +224,7 @@ variable {G : Type*} [Group G] of the inverse given by groups, since there is no `LeftCancelSMul` typeclass. -/ theorem isSMulRegular_of_group [MulAction G R] (g : G) : IsSMulRegular R g := by intro x y h - convert! congr_arg (g⁻¹ • ·) h using 1 <;> simp [← smul_assoc] + convert congr_arg (g⁻¹ • ·) h <;> simp [← smul_assoc] end Group diff --git a/Mathlib/Algebra/Ring/Divisibility/Basic.lean b/Mathlib/Algebra/Ring/Divisibility/Basic.lean index 1dbced56baea73..05bb2b130d1cc7 100644 --- a/Mathlib/Algebra/Ring/Divisibility/Basic.lean +++ b/Mathlib/Algebra/Ring/Divisibility/Basic.lean @@ -182,7 +182,7 @@ variable [NonUnitalCommRing α] theorem dvd_mul_sub_mul {k a b x y : α} (hab : k ∣ a - b) (hxy : k ∣ x - y) : k ∣ a * x - b * y := by - convert! dvd_add (hxy.mul_left a) (hab.mul_right y) using 1 + convert dvd_add (hxy.mul_left a) (hab.mul_right y) rw [mul_sub_left_distrib, mul_sub_right_distrib] simp only [sub_eq_add_neg, add_assoc, neg_add_cancel_left] diff --git a/Mathlib/Algebra/Ring/Idempotent.lean b/Mathlib/Algebra/Ring/Idempotent.lean index 5e11e9f0f17344..05999cf2e63959 100644 --- a/Mathlib/Algebra/Ring/Idempotent.lean +++ b/Mathlib/Algebra/Ring/Idempotent.lean @@ -143,7 +143,7 @@ theorem sub_iff [NonUnitalRing R] [IsAddTorsionFree R] {p q : R} simp_rw [sub_mul, add_mul, mul_assoc, hq.eq, add_sub_cancel_left, ← mul_assoc] at h2 exact h2.symm.trans h1 rw [hpq.eq, and_self, ← nsmul_right_inj (by simp : 2 ≠ 0), ← zero_add (2 • p)] - convert! congrArg (· + 2 • p) h using 1 + convert congrArg (· + 2 • p) h simp [sub_mul, mul_sub, hp.eq, hpq.eq, two_nsmul, sub_add, sub_sub] end IsIdempotentElem diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index fa665fc64c8c3a..381b16158620ac 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -1166,5 +1166,5 @@ end Subring theorem AddSubgroup.int_mul_mem {G : AddSubgroup R} (k : ℤ) {g : R} (h : g ∈ G) : (k : R) * g ∈ G := by - convert! AddSubgroup.zsmul_mem G h k using 1 + convert AddSubgroup.zsmul_mem G h k rw [zsmul_eq_mul] diff --git a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean index d9a220b6c71c85..d1559a84faf99a 100644 --- a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean +++ b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean @@ -790,7 +790,7 @@ protected theorem inv_one : (1 : tsze R M)⁻¹ = (1 : tsze R M) := by rw [← inl_one, TrivSqZeroExt.inv_inl, inv_one] protected theorem inv_mul_cancel {x : tsze R M} (hx : fst x ≠ 0) : x⁻¹ * x = 1 := by - convert! mul_left_eq_one _ _ (_root_.inv_mul_cancel₀ hx) using 2 + convert mul_left_eq_one _ _ (_root_.inv_mul_cancel₀ hx) ext <;> simp variable [SMulCommClass R Rᵐᵒᵖ M] diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 5c6067430c560d..06bc6b0c1d65fa 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -807,7 +807,7 @@ theorem isLocalization_stalk' (y : PrimeSpectrum Γ(X, U)) (hy : hU.fromSpec y (S := X.presheaf.stalk (hU.fromSpec y)) _ y.asIdeal.primeCompl _ (TopCat.Presheaf.algebra_section_stalk X.presheaf ⟨hU.fromSpec y, hy⟩) _ _ (asIso <| hU.fromSpec.stalkMap y).commRingCatIsoToRingEquiv).mpr - convert! StructureSheaf.IsLocalization.to_stalk Γ(X, U) y using 1 + convert StructureSheaf.IsLocalization.to_stalk Γ(X, U) y delta IsLocalization.AtPrime StructureSheaf.stalkAlgebra congr! simp [RingHom.algebraMap_toAlgebra, ← CommRingCat.hom_comp, IsAffineOpen.fromSpec_app_self] diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index c12b8899b8151a..105ba3a560eaad 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -749,7 +749,7 @@ lemma exists_appTop_map_eq_zero_of_isLimit [∀ {i j} (f : i ⟶ j), IsAffineHom have (j : Over i) : IsAffine ((opensDiagram D i U).obj j) := hU.preimage (D.map _) obtain ⟨j, f, hj⟩ := exists_appTop_map_eq_zero_of_isAffine_of_isLimit _ _ (isLimitOpensCone D c hc i U) (.mk (𝟙 i)) (((opensDiagramι D i U).app _).appTop s) (by - convert! congr((c.pt.presheaf.map (homOfLE le_top).op).hom $hs) using 1 + convert congr((c.pt.presheaf.map (homOfLE le_top).op).hom $hs) · simp [Scheme.Hom.app_eq_appLE, Scheme.Hom.resLE_appLE, ← ConcreteCategory.comp_apply]; rfl · simp) refine ⟨U, hU, hxU, j.left, j.hom, ?_⟩ diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean index ef44e2202e0812..d767fc855ecdee 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean @@ -174,7 +174,7 @@ lemma ideal_le_ker_glueDataObjι (U V : X.affineOpens) : simp only [Scheme.Hom.comp_app, Scheme.Opens.ι_app, Scheme.homOfLE_app, ← Functor.map_comp_assoc, Scheme.Hom.app_eq _ H, Scheme.Opens.toScheme_presheaf_map, ← Functor.map_comp, Category.assoc] simp only [CommRingCat.hom_comp, RingHom.comp_apply] - convert! RingHom.map_zero _ using 2 + convert RingHom.map_zero _ rw [← RingHom.mem_ker, ker_glueDataObjι_appTop, ← Ideal.mem_comap, Ideal.comap_comap, ← CommRingCat.hom_comp] simp only [homOfLE_leOfHom, Scheme.Hom.comp_base, @@ -703,7 +703,7 @@ def Hom.toImage : X ⟶ f.image := @[reassoc (attr := simp)] lemma Hom.toImage_imageι : f.toImage ≫ f.imageι = f := by - convert! f.toImageAux_spec using 2 + convert f.toImageAux_spec exact Scheme.Hom.copyBase_eq _ _ _ instance [QuasiCompact f] : IsDominant f.toImage where diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index 7d557c41b1f71f..a832ac5e0c047b 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -664,7 +664,7 @@ private lemma IsAffineOpen.iSup_of_disjoint_aux [Finite ι] {U : ι → X.Opens} (hU : ∀ i, IsAffineOpen (U i)) (hU' : Pairwise (Disjoint on U)) : IsAffineOpen (iSup U) := by have := isOpenImmersion_sigmaDesc _ (fun i ↦ (U i).ι) - (fun i j e ↦ by convert! hU' e using 0; simp [← Opens.coe_disjoint]) + (fun i j e ↦ by convert hU' e; simp [← Opens.coe_disjoint]) convert! isAffineOpen_opensRange (Sigma.desc fun i ↦ (U i).ι) · ext simp [(sigmaMk _).symm.exists_congr_left, ← Scheme.Hom.comp_apply, Scheme.Opens.exists_toScheme] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean index fad81099650161..e2615dd23bd633 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean @@ -253,14 +253,14 @@ lemma isAffineHom_of_isInducing exact ⟨⟨U', hU'⟩ ⊓ U, inf_le_right, Opens.ext (by simpa [e] using hVU)⟩ obtain ⟨r, hrU', hxr⟩ := hU.exists_basicOpen_le ⟨f x, hxV⟩ hxU refine ⟨_, hxr, hU.basicOpen r, ?_⟩ - convert! hV.basicOpen (f.app _ (Y.presheaf.map (homOfLE hU'U).op r)) using 1 + convert hV.basicOpen (f.app _ (Y.presheaf.map (homOfLE hU'U).op r)) simp only [Scheme.preimage_basicOpen, ← CommRingCat.comp_apply, f.naturality] simpa using ((Opens.map f.base).map (homOfLE hrU')).le · obtain ⟨_, ⟨U, hU, rfl⟩, hyU, hU'⟩ := Y.isBasis_affineOpens.exists_subset_of_mem_open hy hf₂.isOpen_compl rw [Set.subset_compl_iff_disjoint_right, ← Set.preimage_eq_empty_iff] at hU' refine ⟨U, hyU, hU, ?_⟩ - convert! isAffineOpen_bot _ + convert isAffineOpen_bot _ exact Opens.ext hU' lemma IsAffineOpen.isCompact_pullback_inf {X Y Z : Scheme.{u}} {f : X ⟶ Z} {g : Y ⟶ Z} @@ -303,7 +303,7 @@ theorem diagonal_isAffine_iff_forall_isAffineOpen_inf [IsAffine Y] (f : X ⟶ Y) exact .of_isIso this.isoPullback.hom · introv H h₁ h₂ have : IsAffineOpen (pullback.fst f₁ f₂ ≫ f₁).opensRange := by - convert! H _ _ (isAffineOpen_opensRange f₁) (isAffineOpen_opensRange f₂) using 1 + convert! H _ _ (isAffineOpen_opensRange f₁) (isAffineOpen_opensRange f₂) exact Opens.ext (IsOpenImmersion.range_pullback_to_base_of_left _ _) change IsAffine _ at this exact .of_isIso (pullback.fst f₁ f₂ ≫ f₁).isoOpensRange.hom diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean index 8d498a091cc989..26d5fefa8013e3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean @@ -84,7 +84,7 @@ theorem isCompact_and_isOpen_iff_finite_and_eq_biUnion_affineOpens {U : Set X} : theorem isCompact_iff_finite_and_eq_biUnion_affineOpens {U : X.Opens} : IsCompact (X := X) U ↔ ∃ s : Set X.affineOpens, s.Finite ∧ U = ⨆ i ∈ s, (i : X.Opens) := by - convert! isCompact_and_isOpen_iff_finite_and_eq_biUnion_affineOpens (U := U.1) using 4 with s + convert isCompact_and_isOpen_iff_finite_and_eq_biUnion_affineOpens (U := U.1) with s · simp [U.isOpen] · convert! SetLike.coe_injective.eq_iff.symm; simp diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean index fbe4adfc521fb3..2e85b370116bd2 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean @@ -232,7 +232,7 @@ nonrec lemma LocallyQuasiFinite.of_fiberToSpecResidueField let g : (X.affineCover.f i ≫ f).fiber x ⟶ f.fiber x := pullback.map _ _ _ _ (X.affineCover.f i) (𝟙 _) (𝟙 _) (by simp) (by simp) have : IsClosedImmersion g := .of_isPreimmersion _ (isClosed_discrete _) - convert! (inferInstance : LocallyQuasiFinite <| g ≫ f.fiberToSpecResidueField _) using 1 + convert (inferInstance : LocallyQuasiFinite <| g ≫ f.fiberToSpecResidueField _) simp [g, Hom.fiberToSpecResidueField] obtain ⟨S, rfl⟩ := hX obtain ⟨φ, rfl⟩ := Spec.map_surjective f diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean index 062845c2c55847..853b0ae33aa695 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean @@ -133,7 +133,7 @@ instance [IsSeparated g] : rw [← MorphismProperty.cancel_left_of_respectsIso @IsClosedImmersion (pullback.fst f (𝟙 Y))] rw [← MorphismProperty.cancel_right_of_respectsIso @IsClosedImmersion _ (pullback.congrHom rfl (Category.id_comp g)).inv] - convert! (inferInstance : IsClosedImmersion (pullback.mapDesc f (𝟙 _) g)) using 1 + convert (inferInstance : IsClosedImmersion (pullback.mapDesc f (𝟙 _) g)) ext : 1 <;> simp [pullback.condition] end IsSeparated diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean index e71b9335da7474..f505798c3260fe 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean @@ -258,7 +258,7 @@ lemma IsDominant.of_comp_of_isOpenImmersion IsDominant f := by rw [isDominant_iff, DenseRange] at H ⊢ simp only [Scheme.Hom.comp_base, TopCat.coe_comp, Set.range_comp] at H - convert! H.preimage g.isOpenEmbedding.isOpenMap using 1 + convert H.preimage g.isOpenEmbedding.isOpenMap rw [Set.preimage_image_eq _ g.isOpenEmbedding.injective] lemma Opens.isDominant_ι {U : X.Opens} (hU : Dense (X := X) U) : IsDominant U.ι := diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean index 7bbc9d9c03b233..10c2bdfa34cc70 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean @@ -53,17 +53,17 @@ lemma lift_awayMapₐ_awayMapₐ_surjective {d e : ℕ} {f : A} (hf : f ∈ 𝒜 let x0 : NumDenSameDeg 𝒜 (.powers f) := { deg := j * (d * (e + 1)) num := ⟨a * g ^ (j * (d - 1)), by - convert! SetLike.mul_mem_graded ha (SetLike.pow_mem_graded _ hg) using 2 + convert SetLike.mul_mem_graded ha (SetLike.pow_mem_graded _ hg) rw [this] cases d · contradiction · simp; ring⟩ - den := ⟨f ^ (j * (e + 1)), by convert! SetLike.pow_mem_graded _ hf using 2; ring⟩ + den := ⟨f ^ (j * (e + 1)), by convert SetLike.pow_mem_graded _ hf; ring⟩ den_mem := ⟨_,rfl⟩ } let y0 : NumDenSameDeg 𝒜 (.powers g) := { deg := j * (d * e) - num := ⟨f ^ (j * e), by convert! SetLike.pow_mem_graded _ hf using 2; ring⟩ - den := ⟨g ^ (j * d), by convert! SetLike.pow_mem_graded _ hg using 2; ring⟩ + num := ⟨f ^ (j * e), by convert SetLike.pow_mem_graded _ hf; ring⟩ + den := ⟨g ^ (j * d), by convert SetLike.pow_mem_graded _ hg; ring⟩ den_mem := ⟨_,rfl⟩ } use mk x0 ⊗ₜ mk y0 ext diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index 0df625c2b1eb3b..b56912df297135 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -383,10 +383,10 @@ variable (hm : 0 < m) (q : Spec.T A⁰_ f) include hm theorem carrier.zero_mem : (0 : A) ∈ carrier f_deg q := fun i => by - convert! Submodule.zero_mem q.1 using 1 + convert Submodule.zero_mem q.1 rw [HomogeneousLocalization.ext_iff_val, HomogeneousLocalization.val_mk, HomogeneousLocalization.val_zero]; simp_rw [map_zero, zero_pow hm.ne'] - convert! Localization.mk_zero (S := Submonoid.powers f) _ using 1 + exact Localization.mk_zero (S := Submonoid.powers f) _ theorem carrier.smul_mem (c x : A) (hx : x ∈ carrier f_deg q) : c • x ∈ carrier f_deg q := by revert c @@ -442,7 +442,7 @@ theorem carrier.denom_notMem : f ∉ carrier.asIdeal f_deg hm q := fun rid => q.isPrime.ne_top <| (Ideal.eq_top_iff_one _).mpr (by - convert! rid m + convert rid m rw [HomogeneousLocalization.ext_iff_val, HomogeneousLocalization.val_one, HomogeneousLocalization.val_mk] dsimp @@ -460,7 +460,7 @@ theorem carrier.asIdeal.prime : (carrier.asIdeal f_deg hm q).IsPrime := (carrier.asIdeal.ne_top f_deg hm q) fun {x y} ⟨nx, hnx⟩ ⟨ny, hny⟩ hxy => show (∀ _, _ ∈ _) ∨ ∀ _, _ ∈ _ by rw [← and_forall_ne nx, and_iff_left, ← and_forall_ne ny, and_iff_left] - · apply q.2.mem_or_mem; convert! hxy (nx + ny) using 1 + · apply q.2.mem_or_mem; convert! hxy (nx + ny) dsimp simp_rw [decompose_of_mem_same 𝒜 hnx, decompose_of_mem_same 𝒜 hny, decompose_of_mem_same 𝒜 (SetLike.GradedMonoid.toGradedMul.mul_mem hnx hny), @@ -469,7 +469,7 @@ theorem carrier.asIdeal.prime : (carrier.asIdeal f_deg hm q).IsPrime := HomogeneousLocalization.val_mul, Localization.mk_mul] simp only [Submonoid.mk_mul_mk, mk_eq_monoidOf_mk'] all_goals - intro n hn; convert! q.1.zero_mem using 1 + intro n hn; convert q.1.zero_mem rw [HomogeneousLocalization.ext_iff_val, HomogeneousLocalization.val_mk, HomogeneousLocalization.val_zero]; simp_rw [proj_apply] convert! mk_zero (S := Submonoid.powers f) _ @@ -742,7 +742,7 @@ lemma isLocalization_atPrime (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 ⟨f ^ i, SetLike.pow_mem_graded _ f_deg⟩, ⟨_, rfl⟩⟩, (mk_mem_toSpec_base_apply _ _ _).not.mpr <| x.1.1.toIdeal.primeCompl.pow_mem hb' m⟩⟩, val_injective _ ?_⟩ - · convert! SetLike.mul_mem_graded a.2 (SetLike.pow_mem_graded (m - 1) hb) using 2 + · convert SetLike.mul_mem_graded a.2 (SetLike.pow_mem_graded (m - 1) hb) rw [← succ_nsmul', tsub_add_cancel_of_le (by lia), mul_comm, smul_eq_mul] · simp only [RingHom.algebraMap_toAlgebra, map_mk, GradedRingHom.id_apply, val_mul, val_mk, mk_eq_mk', ← IsLocalization.mk'_mul, Submonoid.mk_mul_mk, IsLocalization.mk'_eq_iff_eq] diff --git a/Mathlib/Analysis/Analytic/Basic.lean b/Mathlib/Analysis/Analytic/Basic.lean index 56f14154b5d5fd..0c93cffbd50709 100644 --- a/Mathlib/Analysis/Analytic/Basic.lean +++ b/Mathlib/Analysis/Analytic/Basic.lean @@ -157,7 +157,7 @@ theorem HasFPowerSeriesOnBall.comp_sub (hf : HasFPowerSeriesOnBall f p x r) (y : { r_le := hf.r_le r_pos := hf.r_pos hasSum := fun {z} hz => by - convert! hf.hasSum hz using 2 + convert hf.hasSum hz abel } theorem HasFPowerSeriesWithinOnBall.comp_sub (hf : HasFPowerSeriesWithinOnBall f p s x r) (y : E) : @@ -169,7 +169,7 @@ theorem HasFPowerSeriesWithinOnBall.comp_sub (hf : HasFPowerSeriesWithinOnBall f simp only [add_singleton, image_add_right, mem_insert_iff, add_eq_left, mem_preimage] at hz1 ⊢ abel_nf at hz1 assumption - convert! hf.hasSum this hz2 using 2 + convert hf.hasSum this hz2 abel theorem HasFPowerSeriesAt.comp_sub (hf : HasFPowerSeriesAt f p x) (y : E) : @@ -192,7 +192,7 @@ theorem AnalyticOnNhd.comp_sub (hf : AnalyticOnNhd 𝕜 f s) (y : E) : intro x hx simp only [add_singleton, image_add_right, mem_preimage] at hx rw [show x = (x - y) + y by abel] - apply (hf (x - y) (by convert! hx using 1; abel)).comp_sub + apply (hf (x - y) (by convert hx; abel)).comp_sub theorem AnalyticWithinAt.comp_sub (hf : AnalyticWithinAt 𝕜 f s x) (y : E) : AnalyticWithinAt 𝕜 (fun z ↦ f (z - y)) (s + {y}) (x + y) := by @@ -204,7 +204,7 @@ theorem AnalyticOn.comp_sub (hf : AnalyticOn 𝕜 f s) (y : E) : intro x hx simp only [add_singleton, image_add_right, mem_preimage] at hx rw [show x = (x - y) + y by abel] - apply (hf (x - y) (by convert! hx using 1; abel)).comp_sub + apply (hf (x - y) (by convert hx; abel)).comp_sub theorem HasFPowerSeriesWithinOnBall.hasSum_sub (hf : HasFPowerSeriesWithinOnBall f p s x r) {y : E} (hy : y ∈ (insert x s) ∩ Metric.eball x r) : @@ -243,7 +243,7 @@ lemma HasFPowerSeriesWithinOnBall.congr {f g : E → F} {p : FormalMultilinearSe HasFPowerSeriesWithinOnBall g p s x r := by refine ⟨h.r_le, h.r_pos, ?_⟩ intro y hy h'y - convert! h.hasSum hy h'y using 1 + convert h.hasSum hy h'y simp only [mem_insert_iff, add_eq_left] at hy rcases hy with rfl | hy · simpa using h'' @@ -258,7 +258,7 @@ lemma HasFPowerSeriesWithinOnBall.congr' {f g : E → F} {p : FormalMultilinearS (h' : EqOn g f (insert x s ∩ Metric.eball x r)) : HasFPowerSeriesWithinOnBall g p s x r := by refine ⟨h.r_le, h.r_pos, fun {y} hy h'y ↦ ?_⟩ - convert! h.hasSum hy h'y using 1 + convert h.hasSum hy h'y exact h' ⟨hy, by simpa [edist_eq_enorm_sub] using h'y⟩ lemma HasFPowerSeriesWithinAt.congr {f g : E → F} {p : FormalMultilinearSeries 𝕜 E F} {s : Set E} @@ -279,7 +279,7 @@ theorem HasFPowerSeriesOnBall.congr (hf : HasFPowerSeriesOnBall f p x r) { r_le := hf.r_le r_pos := hf.r_pos hasSum := fun {y} hy => by - convert! hf.hasSum hy using 1 + convert hf.hasSum hy apply hg.symm simpa [edist_eq_enorm_sub] using hy } @@ -798,9 +798,9 @@ theorem HasFPowerSeriesWithinOnBall.isBigO_image_sub_image_sub_deriv_principal exact Metric.eball_subset_eball hr.le hy' set A : ℕ → F := fun n => (p n fun _ => y.1 - x) - p n fun _ => y.2 - x have hA : HasSum (fun n => A (n + 2)) (f y.1 - f y.2 - p 1 fun _ => y.1 - y.2) := by - convert! + convert (hasSum_nat_add_iff' 2).2 - ((hf.hasSum_sub ⟨ys.1, hy.1⟩).sub (hf.hasSum_sub ⟨ys.2, hy.2⟩)) using 1 + ((hf.hasSum_sub ⟨ys.1, hy.1⟩).sub (hf.hasSum_sub ⟨ys.2, hy.2⟩)) rw [Finset.sum_range_succ, Finset.sum_range_one, hf.coeff_zero, hf.coeff_zero, sub_self, zero_add, ← Subsingleton.pi_single_eq (0 : Fin 1) (y.1 - x), Pi.single, ← Subsingleton.pi_single_eq (0 : Fin 1) (y.2 - x), Pi.single, ← (p 1).map_update_sub, diff --git a/Mathlib/Analysis/Analytic/Binomial.lean b/Mathlib/Analysis/Analytic/Binomial.lean index f155a1e5126456..e86e83ba680519 100644 --- a/Mathlib/Analysis/Analytic/Binomial.lean +++ b/Mathlib/Analysis/Analytic/Binomial.lean @@ -171,7 +171,7 @@ theorem one_div_one_sub_cpow_hasFPowerSeriesOnBall_zero (a : ℂ) : theorem one_div_one_sub_pow_hasFPowerSeriesOnBall_zero (a : ℕ) : HasFPowerSeriesOnBall (fun x ↦ 1 / (1 - x) ^ (a + 1)) (.ofScalars ℂ (𝕜 := ℂ) fun n ↦ ↑(Nat.choose (a + n) a)) 0 1 := by - convert! one_div_one_sub_cpow_hasFPowerSeriesOnBall_zero (a + 1) using 3 with z n + convert one_div_one_sub_cpow_hasFPowerSeriesOnBall_zero (a + 1) with z n · norm_cast · rw [eq_comm, add_right_comm, add_sub_cancel_right, ← Nat.cast_add, Ring.choose_natCast, Nat.choose_symm_add] @@ -184,7 +184,7 @@ theorem one_div_sub_pow_hasFPowerSeriesOnBall_zero (a : ℕ) {z : ℂ} (hz : z have := this.compContinuousLinearMap have H : 1 / ‖(z⁻¹ • 1 : ℂ →L[ℂ] ℂ)‖ₑ = ‖z‖ₑ := by simp [enorm_smul, enorm_inv, hz] simp only [one_div, FunLike.coe_smul, H, Function.comp_def] at this - convert! (this.const_smul (c := (z ^ (a + 1))⁻¹)).congr ?_ using 2 + convert (this.const_smul (c := (z ^ (a + 1))⁻¹)).congr ?_ · ext n simp only [FormalMultilinearSeries.smul_apply, ContinuousMultilinearMap.smul_apply, FormalMultilinearSeries.compContinuousLinearMap_apply] @@ -213,9 +213,9 @@ theorem one_div_one_sub_sq_hasFPowerSeriesOnBall_zero : theorem hasFPowerSeriesOnBall_ofScalars_mul_add_zero (a b : ℂ) : HasFPowerSeriesOnBall (fun x ↦ (b - a) / (1 - x) + a / (1 - x) ^ 2) (.ofScalars ℂ fun n ↦ a * n + b) 0 1 := by - convert! + convert (one_div_one_sub_hasFPowerSeriesOnBall_zero.const_smul (c := b - a)).add - (one_div_one_sub_sq_hasFPowerSeriesOnBall_zero.const_smul (c := a)) using 2 + (one_div_one_sub_sq_hasFPowerSeriesOnBall_zero.const_smul (c := a)) · simp [div_eq_mul_inv] · ext; simp; ring @@ -262,7 +262,7 @@ theorem one_div_one_sub_rpow_hasFPowerSeriesOnBall_zero (a : ℝ) : (.ofScalars ℝ fun n ↦ Ring.choose (a + n - 1) n) 0 1 := by have := (Complex.one_div_one_sub_cpow_hasFPowerSeriesOnBall_zero a).restrictScalars (𝕜 := ℝ) rw [← Complex.ofRealCLM.map_zero] at this - convert! (Complex.reCLM.comp_hasFPowerSeriesOnBall this.compContinuousLinearMap).congr ?_ using 1 + convert (Complex.reCLM.comp_hasFPowerSeriesOnBall this.compContinuousLinearMap).congr ?_ · ext n simp only [ContinuousLinearMap.compFormalMultilinearSeries_apply, ContinuousLinearMap.compContinuousMultilinearMap_coe, Function.comp_apply, @@ -281,7 +281,7 @@ theorem one_div_sub_pow_hasFPowerSeriesOnBall_zero (a : ℕ) {r : ℝ} (hr : r have := (Complex.one_div_sub_pow_hasFPowerSeriesOnBall_zero a (z := r) (by simpa)).restrictScalars (𝕜 := ℝ) rw [← Complex.ofRealCLM.map_zero] at this - convert! (Complex.reCLM.comp_hasFPowerSeriesOnBall this.compContinuousLinearMap) using 2 + convert (Complex.reCLM.comp_hasFPowerSeriesOnBall this.compContinuousLinearMap) · simp [-Complex.inv_re, ← Complex.ofReal_pow, ← Complex.ofReal_inv, ← Complex.ofReal_sub] · ext n simp only [ContinuousLinearMap.compFormalMultilinearSeries_apply, diff --git a/Mathlib/Analysis/Analytic/OfScalars.lean b/Mathlib/Analysis/Analytic/OfScalars.lean index 47d7b0d043060d..eb4d78c2e000e8 100644 --- a/Mathlib/Analysis/Analytic/OfScalars.lean +++ b/Mathlib/Analysis/Analytic/OfScalars.lean @@ -240,7 +240,7 @@ theorem ofScalars_radius_eq_of_tendsto [NormOneClass E] {r : NNReal} (hr : r ≠ suffices Tendsto (fun n ↦ ‖c n.succ‖ / ‖c n‖) atTop (𝓝 r⁻¹) by convert! ofScalars_radius_eq_inv_of_tendsto E c (inv_ne_zero hr) this simp - convert! hc.inv₀ (NNReal.coe_ne_zero.mpr hr) using 1 + convert hc.inv₀ (NNReal.coe_ne_zero.mpr hr) simp /-- The ratio test stating that if `‖c n.succ‖ / ‖c n‖` tends to zero, the radius is unbounded. diff --git a/Mathlib/Analysis/Asymptotics/Lemmas.lean b/Mathlib/Analysis/Asymptotics/Lemmas.lean index b9597d4931a31a..fed7b0cf783739 100644 --- a/Mathlib/Analysis/Asymptotics/Lemmas.lean +++ b/Mathlib/Analysis/Asymptotics/Lemmas.lean @@ -443,7 +443,7 @@ theorem IsLittleO.of_tendsto_div_atTop (h : Tendsto (fun x ↦ g x / f x) l atTo theorem IsLittleO.of_tendsto_div_atBot (h : Tendsto (fun x ↦ g x / f x) l atBot) : f =o[l] g := by refine IsLittleO.of_neg_left (IsLittleO.of_tendsto_div_atTop ?_) rw [← tendsto_neg_atBot_iff] - convert! h using 2 + convert h simp [div_neg_eq_neg_div] end div_tendsto_infty diff --git a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean index df886834d172f9..d821cfa99d5166 100644 --- a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean +++ b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean @@ -211,7 +211,7 @@ lemma IsSelfAdjoint.isConnected_spectrum_compl {a : A} (ha : IsSelfAdjoint a) : suffices IsConnected (((σ ℂ a)ᶜ ∩ {z | 0 ≤ z.im}) ∪ (σ ℂ a)ᶜ ∩ {z | z.im ≤ 0}) by rw [← Set.inter_union_distrib_left, ← Set.setOf_or] at this rw [← Set.inter_univ (σ ℂ a)ᶜ] - convert! this using 2 + convert this exact Eq.symm <| Set.eq_univ_of_forall (fun z ↦ le_total 0 z.im) refine IsConnected.union ?nonempty ?upper ?lower case nonempty => diff --git a/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean b/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean index cb9f5ef728ebfc..36568b8076f591 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean @@ -115,7 +115,7 @@ variable [IsAddLeftInvariant μ] [SFinite μ] theorem _root_.HasCompactSupport.hasDerivAt_convolution_right (hf : LocallyIntegrable f₀ μ) (hcg : HasCompactSupport g₀) (hg : ContDiff 𝕜 1 g₀) (x₀ : 𝕜) : HasDerivAt (f₀ ⋆[L, μ] g₀) ((f₀ ⋆[L, μ] deriv g₀) x₀) x₀ := by - convert! (hcg.hasFDerivAt_convolution_right L hf hg x₀).hasDerivAt using 1 + convert (hcg.hasFDerivAt_convolution_right L hf hg x₀).hasDerivAt rw [convolution_precompR_apply L hf (hcg.fderiv 𝕜) (hg.continuous_fderiv one_ne_zero)] rfl diff --git a/Mathlib/Analysis/Calculus/Deriv/Inv.lean b/Mathlib/Analysis/Calculus/Deriv/Inv.lean index d2ef70ed083d9a..5222e9c6990361 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Inv.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Inv.lean @@ -143,7 +143,7 @@ variable {𝕜' : Type*} [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 theorem HasDerivWithinAt.fun_div (hc : HasDerivWithinAt c c' s x) (hd : HasDerivWithinAt d d' s x) (hx : d x ≠ 0) : HasDerivWithinAt (fun y => c y / d y) ((c' * d x - c x * d') / d x ^ 2) s x := by - convert! hc.fun_mul ((hasDerivAt_inv hx).comp_hasDerivWithinAt x hd) using 1 + convert hc.fun_mul ((hasDerivAt_inv hx).comp_hasDerivWithinAt x hd) · simp only [div_eq_mul_inv, (· ∘ ·)] · simp [field] ring @@ -155,7 +155,7 @@ theorem HasDerivWithinAt.div (hc : HasDerivWithinAt c c' s x) (hd : HasDerivWith theorem HasStrictDerivAt.fun_div (hc : HasStrictDerivAt c c' x) (hd : HasStrictDerivAt d d' x) (hx : d x ≠ 0) : HasStrictDerivAt (fun y => c y / d y) ((c' * d x - c x * d') / d x ^ 2) x := by - convert! hc.fun_mul ((hasStrictDerivAt_inv hx).comp x hd) using 1 + convert hc.fun_mul ((hasStrictDerivAt_inv hx).comp x hd) · simp only [div_eq_mul_inv, (· ∘ ·)] · simp [field] ring diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index 4f3d64e754953d..e474eb729abbb5 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -42,7 +42,7 @@ theorem hasStrictDerivAt_zpow (m : ℤ) (x : 𝕜) (h : x ≠ 0 ∨ 0 ≤ m) : have : ∀ m : ℤ, 0 < m → HasStrictDerivAt (· ^ m) ((m : 𝕜) * x ^ (m - 1)) x := fun m hm ↦ by lift m to ℕ using hm.le simp only [zpow_natCast, Int.cast_natCast] - convert! hasStrictDerivAt_pow m x using 2 + convert hasStrictDerivAt_pow m x rw [← Int.ofNat_one, ← Int.ofNat_sub, zpow_natCast] norm_cast at hm rcases lt_trichotomy m 0 with (hm | hm | hm) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean index 581c3531bff0ca..f6490c818ee8c8 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean @@ -273,7 +273,7 @@ theorem Convex.taylor_approx_two_segment {v w : E} (hv : x + v ∈ interior s) · apply_rules [HasDerivAt.hasDerivWithinAt, HasDerivAt.smul_const, hasDerivAt_mul_const] · suffices H : HasDerivWithinAt (fun u => ((u * h) ^ 2 / 2) • f'' w w) ((((2 : ℕ) : ℝ) * (t * h) ^ (2 - 1) * (1 * h) / 2) • f'' w w) (Icc 0 1) t by - convert! H using 2 + convert H ring apply_rules [HasDerivAt.hasDerivWithinAt, HasDerivAt.smul_const, hasDerivAt_id', HasDerivAt.pow, HasDerivAt.mul_const] diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index 90db509ede78e6..c836382083c822 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -150,6 +150,6 @@ theorem AnalyticAt.tendsto_mul_logDeriv_simple_zero [CompleteSpace 𝕜] (𝓝[≠] x) (𝓝 1) := by have h_slope := hasDerivAt_iff_tendsto_slope.mp hf.differentiableAt.hasDerivAt rw [← div_self hf'] - convert! hf.deriv.continuousAt.tendsto.mono_left nhdsWithin_le_nhds |>.div h_slope hf' using 2 + convert hf.deriv.continuousAt.tendsto.mono_left nhdsWithin_le_nhds |>.div h_slope hf' simp [logDeriv, slope, hfx] field diff --git a/Mathlib/Analysis/Calculus/Taylor.lean b/Mathlib/Analysis/Calculus/Taylor.lean index 586b700edafde2..0a6d490a2fc651 100644 --- a/Mathlib/Analysis/Calculus/Taylor.lean +++ b/Mathlib/Analysis/Calculus/Taylor.lean @@ -152,7 +152,7 @@ theorem hasDerivWithinAt_taylor_coeff_within {f : ℝ → E} {x y : ℝ} {k : ((k ! : ℝ)⁻¹ * (x - y) ^ k) • iteratedDerivWithin (k + 1) f s y) t y := by replace hf : HasDerivWithinAt (iteratedDerivWithin (k + 1) f s) (iteratedDerivWithin (k + 2) f s y) t y := by - convert! (hf.mono_of_mem_nhdsWithin hs).hasDerivWithinAt using 1 + convert (hf.mono_of_mem_nhdsWithin hs).hasDerivWithinAt rw [iteratedDerivWithin_succ] exact (derivWithin_of_mem_nhdsWithin hs ht hf).symm have : HasDerivWithinAt (fun t => ((k + 1 : ℝ) * k !)⁻¹ * (x - t) ^ (k + 1)) @@ -284,7 +284,7 @@ theorem Real.taylor_tendsto {f : ℝ → ℝ} {x₀ : ℝ} {n : ℕ} {s : Set (hs : Convex ℝ s) (hx₀s : x₀ ∈ s) (hf : ContDiffOn ℝ n f s) : Filter.Tendsto (fun x ↦ (f x - taylorWithinEval f n s x₀ x) / (x - x₀) ^ n) (𝓝[s] x₀) (𝓝 0) := by - convert! _root_.taylor_tendsto hs hx₀s hf using 2 with x + convert _root_.taylor_tendsto hs hx₀s hf with x simp [div_eq_inv_mul] diff --git a/Mathlib/Analysis/Complex/CoveringMap.lean b/Mathlib/Analysis/Complex/CoveringMap.lean index 478849a45717a8..95872f8372379f 100644 --- a/Mathlib/Analysis/Complex/CoveringMap.lean +++ b/Mathlib/Analysis/Complex/CoveringMap.lean @@ -88,7 +88,7 @@ theorem isCoveringMapOn_zpow (n : ℤ) (hn : (n : 𝕜) ≠ 0) : IsCoveringMapOn (fun x : 𝕜 ↦ x ^ n) {0}ᶜ := by have (x : 𝕜) : x ^ n = 0 ↔ x = 0 := zpow_eq_zero_iff (by aesop) refine .of_isCoveringMap_restrictPreimage _ (by simp) ?_ ?_ - · convert! isClosed_singleton (x := (0 : 𝕜)).isOpen_compl using 1 + · convert isClosed_singleton (x := (0 : 𝕜)).isOpen_compl ext; simp [this] · convert! (isCoveringMap_zpow n hn).comp_homeomorph (.setCongr _) using 1 ext; simpa using! (this _).not @@ -121,7 +121,7 @@ theorem isQuotientCoveringMap_zpow (n : ℤ) (hn : (n : 𝕜) ≠ 0) obtain ⟨n, rfl | rfl⟩ := n.eq_nat_or_neg · exact isQuotientCoveringMap_npow n (by aesop) (by simpa using surj) rw [show (zpowGroupHom (α := 𝕜ˣ) (-n)).ker = (powMonoidHom n).ker by ext; simp] - convert! (isQuotientCoveringMap_npow n (by aesop) _).homeomorph_comp (.inv 𝕜ˣ) using 1 + convert (isQuotientCoveringMap_npow n (by aesop) _).homeomorph_comp (.inv 𝕜ˣ) · ext; simp convert! inv_involutive.surjective.comp surj; simp diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index 798b4ef9df2d96..5d95d2378a9389 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -477,7 +477,7 @@ lemma norm_exp_sub_sum_le_exp_norm_sub_sum (x : ℂ) (n : ℕ) : exact Real.sum_le_exp_of_nonneg (norm_nonneg _) _ lemma norm_exp_le_exp_norm (x : ℂ) : ‖exp x‖ ≤ Real.exp ‖x‖ := by - convert! norm_exp_sub_sum_le_exp_norm_sub_sum x 0 using 1 <;> simp + convert norm_exp_sub_sum_le_exp_norm_sub_sum x 0 <;> simp lemma norm_exp_sub_sum_le_norm_mul_exp (x : ℂ) (n : ℕ) : ‖exp x - ∑ m ∈ range n, x ^ m / m.factorial‖ ≤ ‖x‖ ^ n * Real.exp ‖x‖ := by @@ -515,7 +515,7 @@ open Complex Finset nonrec theorem exp_bound {x : ℝ} (hx : |x| ≤ 1) {n : ℕ} (hn : 0 < n) : |exp x - ∑ m ∈ range n, x ^ m / m.factorial| ≤ |x| ^ n * (n.succ / (n.factorial * n)) := by have hxc : ‖(x : ℂ)‖ ≤ 1 := mod_cast hx - convert! exp_bound hxc hn using 2 <;> + convert exp_bound hxc hn <;> norm_cast theorem exp_bound' {x : ℝ} (h1 : 0 ≤ x) (h2 : x ≤ 1) {n : ℕ} (hn : 0 < n) : diff --git a/Mathlib/Analysis/Complex/HasPrimitives.lean b/Mathlib/Analysis/Complex/HasPrimitives.lean index ce8389f6b12e97..fbb3957cd971b3 100644 --- a/Mathlib/Analysis/Complex/HasPrimitives.lean +++ b/Mathlib/Analysis/Complex/HasPrimitives.lean @@ -70,12 +70,12 @@ private lemma mem_closedBall_aux (z_in_ball : z ∈ closedBall c r) (y_in_I : y private lemma mem_ball_of_map_re_aux {a₁ a₂ b : ℝ} (ha₁ : a₁ + b * I ∈ ball c r) (ha₂ : a₂ + b * I ∈ ball c r) : (fun (x : ℝ) ↦ x + b * I) '' [[a₁, a₂]] ⊆ ball c r := by - convert! Convex.rectangle_subset (convex_ball c r) ha₁ ha₂ ?_ ?_ using 1 <;> + convert Convex.rectangle_subset (convex_ball c r) ha₁ ha₂ ?_ ?_ <;> simp [horizontalSegment_eq a₁ a₂ b, ha₁, ha₂, Rectangle] private lemma mem_ball_of_map_im_aux₁ {a b₁ b₂ : ℝ} (hb₁ : a + b₁ * I ∈ ball c r) (hb₂ : a + b₂ * I ∈ ball c r) : (fun (y : ℝ) ↦ a + y * I) '' [[b₁, b₂]] ⊆ ball c r := by - convert! Convex.rectangle_subset (convex_ball c r) hb₁ hb₂ ?_ ?_ using 1 <;> + convert Convex.rectangle_subset (convex_ball c r) hb₁ hb₂ ?_ ?_ <;> simp [verticalSegment_eq a b₁ b₂, hb₁, hb₂, Rectangle] private lemma mem_ball_of_map_im_aux₂ {w : ℂ} (hw : w ∈ ball z (r - dist z c)) : diff --git a/Mathlib/Analysis/Complex/Poisson.lean b/Mathlib/Analysis/Complex/Poisson.lean index 4a0d2429ef660a..b154d58cc976bf 100644 --- a/Mathlib/Analysis/Complex/Poisson.lean +++ b/Mathlib/Analysis/Complex/Poisson.lean @@ -85,7 +85,7 @@ private lemma re_herglotzRieszKernel_le_aux (φ θ r R : ℝ) (h₁ : 0 < r) (h have h_subst : (R ^ 2 - r ^ 2) / (R ^ 2 + r ^ 2 - 2 * R * r * Real.cos (θ - φ)) ≤ (R + r) / (R - r) := by rw [div_le_div_iff₀] <;> nlinarith [mul_pos h₁ (sub_pos.mpr h₂)] - convert! h_subst using 1 + convert h_subst rw [← div_eq_mul_inv, poissonKernel_eq_re_herglotzRieszKernel_aux] suffices (R * R * normSq (cexp (θ * I)) + r * r * normSq (cexp (φ * I)) - 2 * (R * Real.cos θ * (r * Real.cos φ) + R * Real.sin θ * (r * Real.sin φ))) = diff --git a/Mathlib/Analysis/Complex/TaylorSeries.lean b/Mathlib/Analysis/Complex/TaylorSeries.lean index ab6844609a75e1..139c1c86c83be1 100644 --- a/Mathlib/Analysis/Complex/TaylorSeries.lean +++ b/Mathlib/Analysis/Complex/TaylorSeries.lean @@ -54,7 +54,7 @@ lemma hasSum_taylorSeries_on_ball : have H := (hf.mono <| Metric.closedBall_subset_ball hr').hasFPowerSeriesOnBall hr'₀ |>.hasSum_iteratedFDeriv hz' simp only [add_sub_cancel] at H - convert! H using 4 with n + convert H with n simpa only [iteratedDeriv_eq_iteratedFDeriv, smul_eq_mul, mul_one, Finset.prod_const, Finset.card_fin] using ((iteratedFDeriv ℂ n f c).map_smul_univ (fun _ ↦ z - c) (fun _ ↦ 1)).symm diff --git a/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean b/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean index a08119f5e7bbc6..a4a7141a25b97c 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean @@ -147,7 +147,7 @@ theorem abs_characteristic_sub_characteristic_shift_le {r : ℝ} (h : Meromorphi using (posLog_norm_add_le (f θ - a₀) a₀) · simp only [abs_of_nonpos (le_of_not_ge h), neg_sub, tsub_le_iff_right, add_comm (log⁺ ‖a₀‖ + log 2), ← add_assoc] - convert! posLog_norm_add_le (-f θ) (a₀) using 2 + convert! posLog_norm_add_le (-f θ) a₀ using 2 · rw [← norm_neg] abel_nf · simp diff --git a/Mathlib/Analysis/ConstantSpeed.lean b/Mathlib/Analysis/ConstantSpeed.lean index b01b287321c026..2af9ce0d7bf53b 100644 --- a/Mathlib/Analysis/ConstantSpeed.lean +++ b/Mathlib/Analysis/ConstantSpeed.lean @@ -200,7 +200,7 @@ monotonically maps `s` onto `t`, then `φ` is just a translation (on `s`). theorem unique_unit_speed {φ : ℝ → ℝ} (φm : MonotoneOn φ s) (hfφ : HasUnitSpeedOn (f ∘ φ) s) (hf : HasUnitSpeedOn f (φ '' s)) ⦃x : ℝ⦄ (xs : x ∈ s) : EqOn φ (fun y => y - x + φ x) s := by dsimp only [HasUnitSpeedOn] at hf hfφ - convert! HasConstantSpeedOnWith.ratio one_ne_zero φm hfφ hf xs using 3 + convert HasConstantSpeedOnWith.ratio one_ne_zero φm hfφ hf xs simp /-- If both `f` and `f ∘ φ` have unit speed (on `Icc 0 t` and `Icc 0 s` respectively) @@ -211,7 +211,7 @@ theorem unique_unit_speed_on_Icc_zero {s t : ℝ} (hs : 0 ≤ s) (ht : 0 ≤ t) (hfφ : HasUnitSpeedOn (f ∘ φ) (Icc 0 s)) (hf : HasUnitSpeedOn f (Icc 0 t)) : EqOn φ id (Icc 0 s) := by rw [← φst] at hf - convert! unique_unit_speed φm hfφ hf ⟨le_rfl, hs⟩ using 1 + convert unique_unit_speed φm hfφ hf ⟨le_rfl, hs⟩ have : φ 0 = 0 := by have hm : 0 ∈ φ '' Icc 0 s := by simp only [φst, ht, mem_Icc, le_refl, and_self] obtain ⟨x, xs, hx⟩ := hm diff --git a/Mathlib/Analysis/Convex/Basic.lean b/Mathlib/Analysis/Convex/Basic.lean index 9c17d20218a071..14ef4e4268b6b4 100644 --- a/Mathlib/Analysis/Convex/Basic.lean +++ b/Mathlib/Analysis/Convex/Basic.lean @@ -643,7 +643,7 @@ lemma convex_of_nonneg_surjective_algebraMap [FaithfulSMul R A] {s : Set M} intro u hu v hv a b ha hb hab obtain ⟨c, hc1, hc2⟩ := halg ha obtain ⟨d, hd1, hd2⟩ := halg hb - convert! hs hu hv hc1 hd1 _ using 2 + convert hs hu hv hc1 hd1 _ · rw [← hc2, algebraMap_smul] · rw [← hd2, algebraMap_smul] rw [← hc2, ← hd2, ← algebraMap.coe_add] at hab diff --git a/Mathlib/Analysis/Convex/Deriv.lean b/Mathlib/Analysis/Convex/Deriv.lean index bcfcdc3f7a0c35..0e4fae608c2e01 100644 --- a/Mathlib/Analysis/Convex/Deriv.lean +++ b/Mathlib/Analysis/Convex/Deriv.lean @@ -238,7 +238,7 @@ lemma convexOn_of_hasDerivWithinAt2_nonneg {D : Set ℝ} (hD : Convex ℝ D) {f · rw [differentiableOn_congr this] exact fun x hx ↦ (hf'' _ hx).differentiableWithinAt · rintro x hx - convert! hf''₀ _ hx using 1 + convert hf''₀ _ hx dsimp rw [deriv_eqOn isOpen_interior (fun y hy ↦ ?_) hx] exact (hf'' _ hy).congr this <| by rw [this hy] @@ -254,7 +254,7 @@ lemma concaveOn_of_hasDerivWithinAt2_nonpos {D : Set ℝ} (hD : Convex ℝ D) {f · rw [differentiableOn_congr this] exact fun x hx ↦ (hf'' _ hx).differentiableWithinAt · rintro x hx - convert! hf''₀ _ hx using 1 + convert hf''₀ _ hx dsimp rw [deriv_eqOn isOpen_interior (fun y hy ↦ ?_) hx] exact (hf'' _ hy).congr this <| by rw [this hy] diff --git a/Mathlib/Analysis/Convex/PathConnected.lean b/Mathlib/Analysis/Convex/PathConnected.lean index 2daa2c26a7bec5..d42bac5955b2e9 100644 --- a/Mathlib/Analysis/Convex/PathConnected.lean +++ b/Mathlib/Analysis/Convex/PathConnected.lean @@ -109,7 +109,7 @@ protected theorem IsTopologicalAddGroup.pathConnectedSpace : PathConnectedSpace is path connected in `p` then the complement of `q` is path connected in `E`. -/ theorem isPathConnected_compl_of_isPathConnected_compl_zero {p q : Submodule ℝ E} (hpq : IsCompl p q) (hpc : IsPathConnected ({0}ᶜ : Set p)) : IsPathConnected (qᶜ : Set E) := by - convert! (hpc.image continuous_subtype_val).add q.isPathConnected using 1 + convert (hpc.image continuous_subtype_val).add q.isPathConnected trans Submodule.prodEquivOfIsCompl p q hpq '' ({0}ᶜ ×ˢ univ) · rw [prod_univ, LinearEquiv.image_eq_preimage_symm] ext diff --git a/Mathlib/Analysis/Convex/Segment.lean b/Mathlib/Analysis/Convex/Segment.lean index 47dd1c0d348ad6..59bbbd65c0192f 100644 --- a/Mathlib/Analysis/Convex/Segment.lean +++ b/Mathlib/Analysis/Convex/Segment.lean @@ -218,12 +218,12 @@ theorem openSegment_eq_image' (x y : E) : theorem segment_eq_image_lineMap (x y : E) : [x -[𝕜] y] = AffineMap.lineMap x y '' Icc (0 : 𝕜) 1 := by - convert! segment_eq_image 𝕜 x y using 2 + convert segment_eq_image 𝕜 x y exact AffineMap.lineMap_apply_module _ _ _ theorem openSegment_eq_image_lineMap (x y : E) : openSegment 𝕜 x y = AffineMap.lineMap x y '' Ioo (0 : 𝕜) 1 := by - convert! openSegment_eq_image 𝕜 x y using 2 + convert openSegment_eq_image 𝕜 x y exact AffineMap.lineMap_apply_module _ _ _ theorem lineMap_mem_openSegment (a b : E) {t : 𝕜} (ht : t ∈ Ioo 0 1) : diff --git a/Mathlib/Analysis/Distribution/Sobolev.lean b/Mathlib/Analysis/Distribution/Sobolev.lean index f92508dc030efc..3a49f003320e3a 100644 --- a/Mathlib/Analysis/Distribution/Sobolev.lean +++ b/Mathlib/Analysis/Distribution/Sobolev.lean @@ -252,7 +252,7 @@ theorem MemSobolev.fourier_memL1 {s : ℝ} (hs : Module.finrank ℝ E < 2 * s) { norm_cast simp_rw [ofReal_norm] at h simp_rw [← enorm_pow] - convert! h using 4 + convert h rw [← Real.rpow_mul_natCast (by positivity)] simp apply ((integrable_rpow_neg_one_add_norm_sq hs).congr _).lintegral_lt_top diff --git a/Mathlib/Analysis/Distribution/TemperateGrowth.lean b/Mathlib/Analysis/Distribution/TemperateGrowth.lean index 94f84510e344d4..0232517372254d 100644 --- a/Mathlib/Analysis/Distribution/TemperateGrowth.lean +++ b/Mathlib/Analysis/Distribution/TemperateGrowth.lean @@ -208,7 +208,7 @@ theorem HasTemperateGrowth.add (hf : f.HasTemperateGrowth) (hg : g.HasTemperateG @[to_fun (attr := fun_prop)] theorem HasTemperateGrowth.sub (hf : f.HasTemperateGrowth) (hg : g.HasTemperateGrowth) : (f - g).HasTemperateGrowth := by - convert! hf.add hg.neg using 1 + convert hf.add hg.neg grind @[fun_prop] diff --git a/Mathlib/Analysis/Fourier/AddCircle.lean b/Mathlib/Analysis/Fourier/AddCircle.lean index 7ce45abcc6e465..36d822059852c1 100644 --- a/Mathlib/Analysis/Fourier/AddCircle.lean +++ b/Mathlib/Analysis/Fourier/AddCircle.lean @@ -192,7 +192,7 @@ theorem fourier_add_half_inv_index {n : ℤ} (hn : n ≠ 0) (hT : 0 < T) (x : Ad Metric.unitSphere.coe_mul] have : (@toCircle T (n • (T / 2 / n) : ℝ) : ℂ) = -1 := by rw [zsmul_eq_mul, toCircle, Function.Periodic.lift_coe, Circle.coe_exp] - convert! Complex.exp_pi_mul_I using 3 + convert Complex.exp_pi_mul_I field_simp rw [this]; simp @@ -461,7 +461,7 @@ theorem hasSum_sq_fourierCoeffOn haveI := Fact.mk (by linarith : 0 < b - a) rw [← add_sub_cancel a b] at hL2 have h := hL2.memLp_liftIoc.haarAddCircle - convert! hasSum_sq_fourierCoeff h.toLp using 1 + convert hasSum_sq_fourierCoeff h.toLp · simp [fourierCoeff_congr_ae h.coeFn_toLp, fourierCoeff_liftIoc_eq] · nth_rw 2 [← add_sub_cancel a b] rw [← AddCircle.integral_liftIoc_eq_intervalIntegral, ← Function.comp_def (f := (‖·‖ ^ 2))] diff --git a/Mathlib/Analysis/FunctionalSpaces/SobolevInequality.lean b/Mathlib/Analysis/FunctionalSpaces/SobolevInequality.lean index 5412b5761d2357..e01a773a122aec 100644 --- a/Mathlib/Analysis/FunctionalSpaces/SobolevInequality.lean +++ b/Mathlib/Analysis/FunctionalSpaces/SobolevInequality.lean @@ -284,7 +284,7 @@ theorem lintegral_prod_lintegral_pow_le [Fintype ι] [∀ i, SigmaFinite (μ i)] have h3 : (#ι - 1 : ℝ) * ((1 : ℝ) / (#ι - 1 : ℝ)) ≤ 1 := by field_simp; rfl have h4 : p = 1 + 1 / (↑#ι - 1) := by simp [field]; rw [mul_comm, hp.sub_one_mul_conj] rw [h4] - convert! lintegral_mul_prod_lintegral_pow_le μ h2 h3 hf using 2 + convert lintegral_mul_prod_lintegral_pow_le μ h2 h3 hf field_simp simp diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index e89df93fb1c72a..6171f8318e2fb8 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -818,7 +818,7 @@ theorem real_inner_div_norm_mul_norm_eq_neg_one_iff (x y : F) : the equality case for Cauchy-Schwarz. -/ theorem inner_eq_one_iff_of_norm_eq_one {x y : E} (hx : ‖x‖ = 1) (hy : ‖y‖ = 1) : ⟪x, y⟫ = 1 ↔ x = y := by - convert! inner_eq_norm_mul_iff (𝕜 := 𝕜) (E := E) using 2 <;> simp [hx, hy] + convert inner_eq_norm_mul_iff (𝕜 := 𝕜) (E := E) <;> simp [hx, hy] /-- If the inner product of two unit vectors is `-1`, then the two vectors are negations of each other. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean index 9cf3e7608ebd4c..da112f39df47a6 100644 --- a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean +++ b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean @@ -166,7 +166,7 @@ theorem mem_adjoint_domain_of_exists (y : F) (h : ∃ w : E, ∀ x : T.domain, obtain ⟨w, hw⟩ := h rw [T.mem_adjoint_domain_iff] have : Continuous ((innerSL 𝕜 w).comp T.domain.subtypeL) := by fun_prop - convert! this using 1 + convert this exact funext fun x => (hw x).symm theorem adjoint_apply_of_not_dense (hT : ¬Dense (T.domain : Set E)) (y : T†.domain) : T† y = 0 := by diff --git a/Mathlib/Analysis/InnerProductSpace/NormPow.lean b/Mathlib/Analysis/InnerProductSpace/NormPow.lean index 31e04699fc7e43..ac271a6994117a 100644 --- a/Mathlib/Analysis/InnerProductSpace/NormPow.lean +++ b/Mathlib/Analysis/InnerProductSpace/NormPow.lean @@ -58,7 +58,7 @@ theorem differentiable_norm_rpow {p : ℝ} (hp : 1 < p) : theorem hasDerivAt_norm_rpow (x : ℝ) {p : ℝ} (hp : 1 < p) : HasDerivAt (fun x : ℝ ↦ ‖x‖ ^ p) (p * ‖x‖ ^ (p - 2) * x) x := by - convert! hasFDerivAt_norm_rpow x hp |>.hasDerivAt using 1; simp + convert hasFDerivAt_norm_rpow x hp |>.hasDerivAt; simp theorem hasDerivAt_abs_rpow (x : ℝ) {p : ℝ} (hp : 1 < p) : HasDerivAt (fun x : ℝ ↦ |x| ^ p) (p * |x| ^ (p - 2) * x) x := by diff --git a/Mathlib/Analysis/InnerProductSpace/OfNorm.lean b/Mathlib/Analysis/InnerProductSpace/OfNorm.lean index 49ffd3cc9cd697..aca1a98baa557c 100644 --- a/Mathlib/Analysis/InnerProductSpace/OfNorm.lean +++ b/Mathlib/Analysis/InnerProductSpace/OfNorm.lean @@ -118,7 +118,7 @@ theorem inner_.norm_sq (x : E) : ‖x‖ ^ 2 = re (inner_ 𝕜 x x) := by simp only [inner_, normSq_apply, ofNat_re, ofNat_im, map_sub, map_add, ofReal_re, ofReal_im, mul_re, inv_re, mul_im, I_re, inv_im] have h₁ : ‖x - x‖ = 0 := by simp - have h₂ : ‖x + x‖ = 2 • ‖x‖ := by convert! norm_nsmul 𝕜 2 x using 2; module + have h₂ : ‖x + x‖ = 2 • ‖x‖ := by convert norm_nsmul 𝕜 2 x; module rw [h₁, h₂] ring @@ -132,10 +132,10 @@ theorem inner_.conj_symm (x y : E) : conj (inner_ 𝕜 y x) = inner_ 𝕜 x y := have hI' := I_mul_I_of_nonzero hI have I_smul (v : E) : ‖(I : 𝕜) • v‖ = ‖v‖ := by rw [norm_smul, norm_I_of_ne_zero hI, one_mul] have h₁ : ‖(I : 𝕜) • y - x‖ = ‖(I : 𝕜) • x + y‖ := by - convert! I_smul ((I : 𝕜) • x + y) using 2 + convert I_smul ((I : 𝕜) • x + y) linear_combination (norm := module) -hI' • x have h₂ : ‖(I : 𝕜) • y + x‖ = ‖(I : 𝕜) • x - y‖ := by - convert! (I_smul ((I : 𝕜) • y + x)).symm using 2 + convert (I_smul ((I : 𝕜) • y + x)).symm linear_combination (norm := module) -hI' • y rw [h₁, h₂] ring diff --git a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean index 9025cd0391da01..82411d48abf41a 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean @@ -372,7 +372,7 @@ theorem IsOrtho.map_iff (f : E ≃ₗᵢ[𝕜] F) {U V : Submodule 𝕜 E} : @[simp] theorem IsOrtho.comap_iff (f : E ≃ₗᵢ[𝕜] F) {U V : Submodule 𝕜 F} : U.comap (f : E →ₗ[𝕜] F) ⟂ V.comap (f : E →ₗ[𝕜] F) ↔ U ⟂ V := by - convert! IsOrtho.map_iff f.symm using 2 <;> + convert IsOrtho.map_iff f.symm <;> exact Submodule.comap_equiv_eq_map_symm (f : E ≃ₗ[𝕜] F) _ end Submodule diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean index deaa7bed797ae5..95e52bd3f93f08 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean @@ -456,7 +456,7 @@ theorem IsOrtho.starProjection_comp_starProjection {U V : Submodule 𝕜 E} theorem orthogonalProjectionOnto_comp_subtypeL_eq_zero_iff {U V : Submodule 𝕜 E} [U.HasOrthogonalProjection] : U.orthogonalProjectionOnto ∘L V.subtypeL = 0 ↔ U ⟂ V := by refine ⟨fun h u hu v hv ↦ ?_, Submodule.IsOrtho.orthogonalProjectionOnto_comp_subtypeL⟩ - convert! starProjection_inner_eq_zero v u hu using 2 + convert starProjection_inner_eq_zero v u hu have : U.orthogonalProjectionOnto v = 0 := DFunLike.congr_fun h (⟨_, hv⟩ : V) rw [starProjection_apply, this, Submodule.coe_zero, sub_zero] diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean index 28d00c7bd12d5f..84a98a95f9bd85 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean @@ -51,7 +51,7 @@ def reflection : E ≃ₗᵢ[𝕜] E := let w : K := K.orthogonalProjectionOnto x let v := x - w have : ⟪v, w⟫ = 0 := starProjection_inner_eq_zero x w w.2 - convert! norm_sub_eq_norm_add this using 2 + convert norm_sub_eq_norm_add this · dsimp [reflectionLinearEquiv, v, w] abel · simp only [v, add_sub_cancel] } diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean index 8331a9fb57497c..f3ddc25cb6926e 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean @@ -47,7 +47,7 @@ theorem sup_orthogonal_inf_of_hasOrthogonalProjection {K₁ K₂ : Submodule variable {K} in /-- If `K` admits an orthogonal projection, then `K` and `Kᗮ` span the whole space. -/ theorem sup_orthogonal_of_hasOrthogonalProjection [K.HasOrthogonalProjection] : K ⊔ Kᗮ = ⊤ := by - convert! Submodule.sup_orthogonal_inf_of_hasOrthogonalProjection (le_top : K ≤ ⊤) using 2 + convert Submodule.sup_orthogonal_inf_of_hasOrthogonalProjection (le_top : K ≤ ⊤) simp /-- If `K` admits an orthogonal projection, then the orthogonal complement of its orthogonal @@ -87,7 +87,7 @@ of all elements equal to zero. Then `Kᗮ = ⊥`, `Kᗮᗮ = ⊤`. -/ theorem orthogonal_orthogonal_eq_closure [CompleteSpace E] : Kᗮᗮ = K.topologicalClosure := by refine le_antisymm ?_ ?_ - · convert! Submodule.orthogonal_orthogonal_monotone K.le_topologicalClosure using 1 + · convert Submodule.orthogonal_orthogonal_monotone K.le_topologicalClosure rw [K.topologicalClosure.orthogonal_orthogonal] · exact K.topologicalClosure_minimal K.le_orthogonal_orthogonal Kᗮ.isClosed_orthogonal diff --git a/Mathlib/Analysis/MeanInequalities.lean b/Mathlib/Analysis/MeanInequalities.lean index ac11e444efd9db..b6aba130f375d6 100644 --- a/Mathlib/Analysis/MeanInequalities.lean +++ b/Mathlib/Analysis/MeanInequalities.lean @@ -153,7 +153,7 @@ theorem geom_mean_le_arith_mean_weighted (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 theorem geom_mean_le_arith_mean {ι : Type*} (s : Finset ι) (w : ι → ℝ) (z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i) (hw' : 0 < ∑ i ∈ s, w i) (hz : ∀ i ∈ s, 0 ≤ z i) : (∏ i ∈ s, z i ^ w i) ^ (∑ i ∈ s, w i)⁻¹ ≤ (∑ i ∈ s, w i * z i) / (∑ i ∈ s, w i) := by - convert! geom_mean_le_arith_mean_weighted s (fun i => (w i) / ∑ i ∈ s, w i) z ?_ ?_ hz using 2 + convert geom_mean_le_arith_mean_weighted s (fun i => (w i) / ∑ i ∈ s, w i) z ?_ ?_ hz · rw [← finsetProd_rpow _ _ (fun i hi => rpow_nonneg (hz _ hi) _) _] refine Finset.prod_congr rfl (fun _ ih => ?_) rw [div_eq_mul_inv, rpow_mul (hz _ ih)] @@ -649,9 +649,9 @@ product of their `L^p` and `L^q` norms when `p`, `q`, and `r` form a `Real.Holde theorem Lr_le_Lp_mul_Lq (f g : ι → ℝ≥0) {p q r : ℝ} (hpqr : p.HolderTriple q r) : (∑ i ∈ s, (f i * g i) ^ r) ^ (1 / r) ≤ (∑ i ∈ s, f i ^ p) ^ (1 / p) * (∑ i ∈ s, g i ^ q) ^ (1 / q) := by - convert! + convert rpow_le_rpow_iff (inv_eq_one_div r ▸ inv_pos.mpr hpqr.pos' : 0 < 1 / r) |>.mpr <| - Lr_rpow_le_Lp_mul_Lq s f g hpqr using 1 + Lr_rpow_le_Lp_mul_Lq s f g hpqr have hr := hpqr.pos'.ne' simp only [← rpow_mul, mul_rpow] field_simp @@ -924,10 +924,9 @@ by (the `r`-power of) the product of their `L^p` and `L^q` norms, when `p`, `q`, theorem Lr_rpow_le_Lp_mul_Lq_of_nonneg {ι : Type*} (s : Finset ι) {f g : ι → ℝ} {p q r : ℝ} (hpqr : p.HolderTriple q r) (hf : ∀ i ∈ s, 0 ≤ f i) (hg : ∀ i ∈ s, 0 ≤ g i) : ∑ i ∈ s, (f i * g i) ^ r ≤ (∑ i ∈ s, f i ^ p) ^ (r / p) * (∑ i ∈ s, g i ^ q) ^ (r / q) := by - convert! Lr_rpow_le_Lp_mul_Lq s f g hpqr using 3 with i hi + convert Lr_rpow_le_Lp_mul_Lq s f g hpqr with i hi · rw [abs_of_nonneg (mul_nonneg (hf i hi) (hg i hi))] all_goals - congr! with i hi exact Eq.symm (abs_of_nonneg (by grind)) /-- **Weighted Hölder inequality**. -/ @@ -1000,10 +999,10 @@ theorem Lr_le_Lp_mul_Lq_tsum_of_nonneg (hpqr : p.HolderTriple q r) (hf : ∀ i, have hf' : 0 ≤ ∑' i, f i ^ p := tsum_nonneg fun i ↦ rpow_nonneg (hf i) p have hg' : 0 ≤ ∑' i, g i ^ q := tsum_nonneg fun i ↦ rpow_nonneg (hg i) q have hr := hpqr.pos' - convert! + convert rpow_le_rpow_iff (tsum_nonneg fun i ↦ by positivity [hf i, hg i]) (by positivity) (inv_eq_one_div r ▸ inv_pos.mpr hr) |>.mpr <| - Lr_rpow_le_Lp_mul_Lq_tsum_of_nonneg hpqr hf hg hf_sum hg_sum using 1 + Lr_rpow_le_Lp_mul_Lq_tsum_of_nonneg hpqr hf hg hf_sum hg_sum rw [mul_rpow (rpow_nonneg hf' _) (rpow_nonneg hg' _), ← Real.rpow_mul hg', ← Real.rpow_mul hf'] field_simp diff --git a/Mathlib/Analysis/MeanInequalitiesPow.lean b/Mathlib/Analysis/MeanInequalitiesPow.lean index 9fba152359c694..d157730b07294d 100644 --- a/Mathlib/Analysis/MeanInequalitiesPow.lean +++ b/Mathlib/Analysis/MeanInequalitiesPow.lean @@ -366,7 +366,7 @@ theorem rpow_add_le_mul_rpow_add_rpow'' (z₁ z₂ : ℝ≥0∞) {p : ℝ≥0∞ LpAddConst p * (z₁ ^ p.toReal⁻¹ + z₂ ^ p.toReal⁻¹) := by by_cases p_zero : p = 0 · simp [p_zero, LpAddConst_zero] - convert! rpow_add_le_mul_rpow_add_rpow' z₁ z₂ (p := p.toReal⁻¹) (by positivity) using 1 + convert rpow_add_le_mul_rpow_add_rpow' z₁ z₂ (p := p.toReal⁻¹) (by positivity) rw [← ENNReal.toReal_inv, ENNReal.ofReal_toReal (by simpa), inv_inv] end ENNReal diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 1d4d2a28f600dd..76db272de7420a 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -90,7 +90,7 @@ lemma smul {f : 𝕜 → 𝕜} {g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : M rcases hf with ⟨m, hf⟩ rcases hg with ⟨n, hg⟩ refine ⟨m + n, ?_⟩ - convert! hf.smul hg using 2 with z + convert hf.smul hg with z simp module @@ -100,7 +100,7 @@ lemma mul {f g : 𝕜 → 𝕜'} (hf : MeromorphicAt f x) (hg : MeromorphicAt g rcases hf with ⟨m, hf⟩ rcases hg with ⟨n, hg⟩ refine ⟨m + n, ?_⟩ - convert! hf.mul hg using 2 with z + convert hf.mul hg with z simp module @@ -164,7 +164,7 @@ theorem finsum (hF : ∀ i, MeromorphicAt (F i) x) : @[to_fun (attr := fun_prop)] lemma neg {f : 𝕜 → E} (hf : MeromorphicAt f x) : MeromorphicAt (-f) x := by - convert! (MeromorphicAt.const (-1 : 𝕜) x).smul hf using 1 + convert (MeromorphicAt.const (-1 : 𝕜) x).smul hf ext1 z simp only [Pi.neg_apply, Pi.smul_apply', neg_smul, one_smul] @@ -176,7 +176,7 @@ lemma neg_iff {f : 𝕜 → E} : @[to_fun (attr := fun_prop)] lemma sub {f g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : MeromorphicAt (f - g) x := by - convert! hf.add hg.neg using 1 + convert hf.add hg.neg ext1 z simp_rw [Pi.sub_apply, Pi.add_apply, Pi.neg_apply, sub_eq_add_neg] diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index dc1eb5d87b7a76..eb2a4e773f4a14 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -254,7 +254,7 @@ theorem spectralRadius_le_pow_nnnorm_pow_one_div (a : A) (n : ℕ) : ENNReal.coe_mul] using coe_mono (Real.toNNReal_mono (norm_le_norm_mul_of_mem pow_mem)) -- take (n + 1)ᵗʰ roots and clean up the left-hand side have hn : 0 < ((n + 1 : ℕ) : ℝ) := mod_cast Nat.succ_pos' - convert! monotone_rpow_of_nonneg (one_div_pos.mpr hn).le nnnorm_pow_le using 1 + convert monotone_rpow_of_nonneg (one_div_pos.mpr hn).le nnnorm_pow_le all_goals dsimp · rw [one_div, pow_rpow_inv_natCast] positivity diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index e9a4d77951abf4..0409bfc27bfc7b 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -364,7 +364,7 @@ alias NormedAddCommGroup.nhds_zero_basis_norm_lt := NormedAddGroup.nhds_zero_bas @[to_additive] theorem NormedGroup.uniformity_basis_dist : (𝓤 E).HasBasis (fun ε : ℝ => 0 < ε) fun ε => { p : E × E | ‖p.fst⁻¹ * p.snd‖ < ε } := by - convert! Metric.uniformity_basis_dist (α := E) using 1 + convert Metric.uniformity_basis_dist (α := E) simp [dist_eq_norm_inv_mul] open Finset diff --git a/Mathlib/Analysis/SumOverResidueClass.lean b/Mathlib/Analysis/SumOverResidueClass.lean index b29da2f5d98ff7..bdc7e0dec25275 100644 --- a/Mathlib/Analysis/SumOverResidueClass.lean +++ b/Mathlib/Analysis/SumOverResidueClass.lean @@ -44,7 +44,7 @@ lemma summable_indicator_mod_iff_summable {R : Type*} [AddCommGroup R] [Topologi intro n hn contrapose! hn exact (Nat.range_mul_add m k).symm ▸ mem_of_indicator_ne_zero hn - convert! (Function.Injective.summable_iff hg hg').symm using 3 + convert (Function.Injective.summable_iff hg hg').symm simp only [Function.comp_apply, mem_setOf_eq, Nat.cast_add, Nat.cast_mul, CharP.cast_eq_zero, zero_mul, zero_add, le_add_iff_nonneg_left, zero_le, and_self, indicator_of_mem, g] From 7ab1c47ce634c21b7321b7ee660f0645f75bca9b Mon Sep 17 00:00:00 2001 From: Laurance <60111599+LLaurance@users.noreply.github.com> Date: Thu, 18 Jun 2026 08:17:39 +0000 Subject: [PATCH 0132/1300] chore(Probability): remove TODO on characteristic functions (#40595) mathlib4 now has Fourier transforms and the characteristic function is defined at [`MeasureTheory.charFun`](https://leanprover-community.github.io/mathlib4_docs/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.html#MeasureTheory.charFun). --- Mathlib/Probability/Density.lean | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Mathlib/Probability/Density.lean b/Mathlib/Probability/Density.lean index d836da178c64e9..3b8db490b50342 100644 --- a/Mathlib/Probability/Density.lean +++ b/Mathlib/Probability/Density.lean @@ -43,12 +43,6 @@ random variables with this distribution. * `MeasureTheory.pdf.IsUniform.integral_eq` : If `X` follows the uniform distribution with its pdf having support `s`, then `X` has expectation `(λ s)⁻¹ * ∫ x in s, x dx` where `λ` is the Lebesgue measure. - -## TODO - -Ultimately, we would also like to define characteristic functions to describe distributions as -it exists for all random variables. However, to define this, we will need Fourier transforms -which we currently do not have. -/ @[expose] public section From 7c0bf438871951abe1800ee614568a9bd8c5dd59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 18 Jun 2026 10:07:08 +0000 Subject: [PATCH 0133/1300] feat(LinearAlgebra): generators of pi tensor products (#26464) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this PR, we show that the `R`-module `⨂[R] i, M i` is finitely generated if the index type is finite and all `M i` are finitely generated. This follows from a more precise result about generators of `⨂[R] i, M i`. Co-authored-by: Eric Wieser --- Mathlib.lean | 5 +- .../PiTensorProduct/ProjectiveSeminorm.lean | 2 +- Mathlib/Data/Set/Card.lean | 9 ++ Mathlib/Data/SubtypeNeLift.lean | 45 ++++++ .../Basic.lean} | 0 .../PiTensorProduct/DFinsupp.lean | 2 +- .../PiTensorProduct/DirectSum.lean | 2 +- .../LinearAlgebra/PiTensorProduct/Finite.lean | 30 ++++ .../PiTensorProduct/Generators.lean | 153 ++++++++++++++++++ Mathlib/LinearAlgebra/TensorPower/Basic.lean | 2 +- .../LinearAlgebra/TensorPower/Symmetric.lean | 2 +- Mathlib/Logic/Equiv/Option.lean | 4 + Mathlib/RingTheory/PiTensorProduct.lean | 2 +- 13 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 Mathlib/Data/SubtypeNeLift.lean rename Mathlib/LinearAlgebra/{PiTensorProduct.lean => PiTensorProduct/Basic.lean} (100%) create mode 100644 Mathlib/LinearAlgebra/PiTensorProduct/Finite.lean create mode 100644 Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean diff --git a/Mathlib.lean b/Mathlib.lean index d03479050e91f0..3093c4df4064be 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4387,6 +4387,7 @@ public import Mathlib.Data.String.Basic public import Mathlib.Data.String.Defs public import Mathlib.Data.String.Lemmas public import Mathlib.Data.Subtype +public import Mathlib.Data.SubtypeNeLift public import Mathlib.Data.Sum.Basic public import Mathlib.Data.Sum.Interval public import Mathlib.Data.Sum.Lattice @@ -5146,12 +5147,14 @@ public import Mathlib.LinearAlgebra.PID public import Mathlib.LinearAlgebra.PerfectPairing.Basic public import Mathlib.LinearAlgebra.PerfectPairing.Restrict public import Mathlib.LinearAlgebra.Pi -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.LinearAlgebra.PiTensorProduct.Basis public import Mathlib.LinearAlgebra.PiTensorProduct.DFinsupp public import Mathlib.LinearAlgebra.PiTensorProduct.DirectSum public import Mathlib.LinearAlgebra.PiTensorProduct.Dual +public import Mathlib.LinearAlgebra.PiTensorProduct.Finite public import Mathlib.LinearAlgebra.PiTensorProduct.Finsupp +public import Mathlib.LinearAlgebra.PiTensorProduct.Generators public import Mathlib.LinearAlgebra.Prod public import Mathlib.LinearAlgebra.Projection public import Mathlib.LinearAlgebra.Projectivization.Action diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean index b2319ec8628f80..4a419478bd0338 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean @@ -6,7 +6,7 @@ Authors: Sophie Morel module public import Mathlib.Analysis.Normed.Module.Multilinear.Basic -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic /-! # Projective seminorm on the tensor of a finite family of normed spaces. diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index 4ed3717591a453..5e66b76ade76d6 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -1162,10 +1162,19 @@ theorem ncard_add_ncard_compl (s : Set α) (hs : s.Finite := by toFinite_tac) (hsc : sᶜ.Finite := by toFinite_tac) : s.ncard + sᶜ.ncard = Nat.card α := by rw [← ncard_univ, ← ncard_union_eq (@disjoint_compl_right _ _ s) hs hsc, union_compl_self] +theorem ncard_compl_add_ncard (s : Set α) (hs : s.Finite := by toFinite_tac) + (hsc : sᶜ.Finite := by toFinite_tac) : sᶜ.ncard + s.ncard = Nat.card α := by + rw [add_comm, ncard_add_ncard_compl s hs hsc] + theorem ncard_compl (s : Set α) (hs : s.Finite := by toFinite_tac) (hsc : sᶜ.Finite := by toFinite_tac) : sᶜ.ncard = Nat.card α - s.ncard := by rw [← ncard_add_ncard_compl s hs hsc, Nat.add_sub_cancel_left] +theorem ncard_compl_of_ncard_eq_add [Finite α] (s : Set α) {n : ℕ} + (h : Nat.card α = n + s.ncard) : + sᶜ.ncard = n := by + rwa [← ncard_compl_add_ncard s, Nat.add_right_cancel_iff] at h + theorem eq_univ_iff_ncard [Finite α] (s : Set α) : s = univ ↔ ncard s = Nat.card α := by rw [← compl_empty_iff, ← ncard_eq_zero, ← ncard_add_ncard_compl s, left_eq_add] diff --git a/Mathlib/Data/SubtypeNeLift.lean b/Mathlib/Data/SubtypeNeLift.lean new file mode 100644 index 00000000000000..681cef12384c1b --- /dev/null +++ b/Mathlib/Data/SubtypeNeLift.lean @@ -0,0 +1,45 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Logic.Equiv.Option + +/-! +# Extending a function from the complement of a singleton + +In this file, we define `Function.subtypeNeLift` which allows to +extend a (dependent) function defined on the complement of a singleton. + +-/ + +@[expose] public section + +namespace Function + +variable {ι : Type*} [DecidableEq ι] {M : ι → Type*} (i₀ : ι) + (f : ∀ (j : { i // i ≠ i₀ }), M j) (x : M i₀) + +/-- Given `i₀ : ι` and `x : M i₀`, this is the (dependent) map `(i : ι) → M i` +whose value at `i₀` is `x` and which extends a given map on the complement of `{i₀}`. -/ +def subtypeNeLift (i : ι) : M i := + if h : i = i₀ then by rw [h]; exact x else f ⟨i, h⟩ + +@[simp] +lemma subtypeNeLift_self : subtypeNeLift i₀ f x i₀ = x := dif_pos rfl + +lemma subtypeNeLift_of_neq (i : ι) (h : i ≠ i₀) : + subtypeNeLift i₀ f x i = f ⟨i, h⟩ := dif_neg h + +@[simp] +lemma subtypeNeLift_restriction (φ : ∀ i, M i) (i₀ : ι) : + subtypeNeLift i₀ (fun i ↦ φ i) (φ i₀) = φ := by + ext i + by_cases h : i = i₀ + · subst h + simp + · rw [subtypeNeLift_of_neq _ _ _ _ h] + +end Function diff --git a/Mathlib/LinearAlgebra/PiTensorProduct.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean similarity index 100% rename from Mathlib/LinearAlgebra/PiTensorProduct.lean rename to Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean b/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean index e568c71cdfac29..88c01be9919241 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean @@ -5,7 +5,7 @@ Authors: Sophie Morel, Eric Wieser -/ module -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.LinearAlgebra.DFinsupp public import Mathlib.LinearAlgebra.Multilinear.DFinsupp diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/DirectSum.lean b/Mathlib/LinearAlgebra/PiTensorProduct/DirectSum.lean index 7741c57f651ac2..6b41366b14043c 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/DirectSum.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/DirectSum.lean @@ -5,7 +5,7 @@ Authors: Sophie Morel, Eric Wieser -/ module -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.LinearAlgebra.PiTensorProduct.DFinsupp public import Mathlib.Algebra.DirectSum.Module diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Finite.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Finite.lean new file mode 100644 index 00000000000000..ede782165307c3 --- /dev/null +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Finite.lean @@ -0,0 +1,30 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.RingTheory.Finiteness.Basic +public import Mathlib.LinearAlgebra.PiTensorProduct.Generators + +/-! +# A multiple tensor product of finitely generated modules is finitely generated + +-/ + +public section + +open TensorProduct + +namespace PiTensorProduct + +instance finite {R : Type*} [CommRing R] {ι : Type*} [Finite ι] + {M : ι → Type*} [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] + [∀ i, Module.Finite R (M i)] : + Module.Finite R (⨂[R] i, M i) := by + choose n γ hg using fun i => Module.Finite.exists_fin (R := R) (M := M i) + rw [Module.finite_def, ← submodule_span_eq_top hg] + exact Submodule.fg_span (Set.finite_range _) + +end PiTensorProduct diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean new file mode 100644 index 00000000000000..fb60ceae5a3b65 --- /dev/null +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean @@ -0,0 +1,153 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Data.SubtypeNeLift +public import Mathlib.Data.Set.Card +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic +public import Mathlib.LinearAlgebra.Quotient.Basic +public import Mathlib.LinearAlgebra.TensorProduct.Map +public import Mathlib.SetTheory.Cardinal.Finite + +/-! +# Generators of multiple tensor products + +Given a finite family of `R`-modules `M i`, if we have, for each `i`, +a family of generators of the module `M i`, then the tensor products +of these elements generate `⨂[R] i, M i`. + +In `LinearAlgebra.PiTensorProduct.Finite`, we deduce that if the modules `M i` +are finitely generated, then so is `⨂[R] i, M i`. + +-/ + +@[expose] public section + +open TensorProduct + +namespace PiTensorProduct + +variable (R : Type*) + +section equivPiTensorComplSingletonTensor + +variable {ι : Type*} [DecidableEq ι] (M : ι → Type*) + [CommSemiring R] [∀ i, AddCommMonoid (M i)] [∀ i, Module R (M i)] + +/-- The linear equivalence between `⨂[R] i, M i` and the tensor product of +the pi tensor product indexed by the complement of `{i₀}` and `M i₀`. -/ +noncomputable def equivPiTensorComplSingletonTensor (i₀ : ι) : + (⨂[R] i, M i) ≃ₗ[R] ((⨂[R] (i : ({i₀}ᶜ : Set ι)), M i) ⊗[R] M i₀) := + (reindex R (s := M) (Equiv.subtypeNeSumPUnit.{0} i₀).symm).trans + ((tmulEquivDep R (fun i ↦ M (Equiv.subtypeNeSumPUnit i₀ i))).symm.trans + (LinearEquiv.lTensor _ (subsingletonEquiv Unit.unit))) + +variable (i₀ : ι) + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma equivPiTensorComplSingletonTensor_tprod (i₀ : ι) (m : ∀ i, M i) : + equivPiTensorComplSingletonTensor R M i₀ (⨂ₜ[R] i, m i) = + (⨂ₜ[R] (j : ((Set.singleton i₀)ᶜ : Set ι)), m j) ⊗ₜ m i₀:= by + dsimp [equivPiTensorComplSingletonTensor] + have : (reindex R M (Equiv.subtypeNeSumPUnit.{0} i₀).symm) (⨂ₜ[R] (i : ι), m i) = + ⨂ₜ[R] j, m ((Equiv.subtypeNeSumPUnit.{0} i₀) j) := by + simp_rw [reindex_tprod (R := R) (s := M), Equiv.symm_symm] + rw [dsimp% this, dsimp% tmulEquivDep_symm_apply R + (fun i ↦ M ((Equiv.subtypeNeSumPUnit.{0} i₀) i))] + exact (LinearEquiv.lTensor_tmul _ _ _ _).trans (by congr; simp) + +@[simp] +lemma equivPiTensorComplSingletonTensor_symm_tmul (i₀ : ι) + (m : ∀ (i : ((Set.singleton i₀)ᶜ : Set ι)), M i) (x : M i₀) : + (equivPiTensorComplSingletonTensor R M i₀).symm + ((⨂ₜ[R] (j : ((Set.singleton i₀)ᶜ : Set ι)), m j) ⊗ₜ x) = + (⨂ₜ[R] i, Function.subtypeNeLift i₀ m x i) := by + apply (equivPiTensorComplSingletonTensor R M i₀).injective + simp only [LinearEquiv.apply_symm_apply, equivPiTensorComplSingletonTensor_tprod, + Function.subtypeNeLift_self] + congr + ext ⟨i, hi⟩ + rw [Function.subtypeNeLift_of_neq _ _ _ _ hi] + rfl + +end equivPiTensorComplSingletonTensor + +variable {R} {ι : Type*} [Finite ι] {M : ι → Type*} {N : Type*} {γ : ι → Type*} + +section AddCommMonoid + +variable [CommSemiring R] [∀ i, AddCommMonoid (M i)] [∀ i, Module R (M i)] + [AddCommMonoid N] [Module R N] {g : ⦃i : ι⦄ → (j : γ i) → M i} + +lemma ext_of_span_eq_top + (hg : ∀ i, Submodule.span R (Set.range (@g i)) = ⊤) + {φ φ' : (⨂[R] i, M i) →ₗ[R] N} + (h : ∀ (j : (i : ι) → γ i), + φ (tprod _ (fun i ↦ g (j i))) = φ' (tprod _ (fun i ↦ g (j i)))) : + φ = φ' := by + obtain ⟨n, hι⟩ : ∃ (n : ℕ), Nat.card ι = n := ⟨_, rfl⟩ + induction n generalizing ι with + | zero => + ext x + have : IsEmpty ι := (Nat.card_eq_zero.1 hι).resolve_right <| Finite.not_infinite ‹_› + obtain rfl : x = fun i ↦ @g i (isEmptyElim i) := Subsingleton.elim _ _ + apply h + | succ n hn => + classical + have : Nonempty ι := ((Nat.card_pos_iff (α := ι)).1 (by omega)).1 + have i₀ : ι := Classical.arbitrary _ + let e := (equivPiTensorComplSingletonTensor R M i₀).trans (TensorProduct.comm _ _ _) + obtain ⟨ψ, rfl⟩ : ∃ ψ, φ = LinearMap.comp ψ e.toLinearMap := + ⟨φ.comp e.symm.toLinearMap, by ext; simp⟩ + obtain ⟨ψ', rfl⟩ : ∃ ψ', φ' = LinearMap.comp ψ' e.toLinearMap := + ⟨φ'.comp e.symm.toLinearMap, by ext; simp⟩ + dsimp [e] at h + congr 1 + apply (TensorProduct.lift.equiv _ _ _ _).symm.injective + rw [Submodule.linearMap_eq_iff_of_span_eq_top _ _ (hg i₀)] + rintro ⟨_, ⟨g₀, rfl⟩⟩ + apply hn (g := fun i (j : γ i.1) ↦ by exact g j) + · intro + exact hg _ + · intro j + have : (g g₀ ⊗ₜ[R] (tprod R) fun i ↦ g (j i)) = + TensorProduct.comm R _ _ ((equivPiTensorComplSingletonTensor R M i₀) + (⨂ₜ[R] (i : ι), g (Function.subtypeNeLift i₀ j g₀ i))) := by + simp only [equivPiTensorComplSingletonTensor_tprod, Function.subtypeNeLift_self] + congr + ext ⟨x, hx⟩ + congr + rw [Function.subtypeNeLift_of_neq _ _ _ _ (by assumption)] + rfl + simpa only [lift.equiv_symm_apply, this] using h (Function.subtypeNeLift i₀ j g₀) + · exact Set.ncard_compl_of_ncard_eq_add _ (by simpa) + +lemma _root_.MultilinearMap.ext_of_span_eq_top + (hg : ∀ i, Submodule.span R (Set.range (@g i)) = ⊤) + {φ φ' : MultilinearMap R M N} + (h : ∀ (j : (i : ι) → γ i), φ (fun i ↦ g (j i)) = φ' (fun i ↦ g (j i))) : + φ = φ' := by + suffices lift φ = lift φ' by + ext m + simpa using DFunLike.congr_fun this (tprod _ m) + exact PiTensorProduct.ext_of_span_eq_top hg (fun j ↦ by simpa using h j) + +end AddCommMonoid + +variable [CommRing R] [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] + [AddCommMonoid N] [Module R N] {g : ⦃i : ι⦄ → (j : γ i) → M i} + +lemma submodule_span_eq_top + (hg : ∀ i, Submodule.span R (Set.range (@g i)) = ⊤) : + Submodule.span R (Set.range (fun j : ((i : ι) → γ i) ↦ + ⨂ₜ[R] (i : ι), g (j i))) = ⊤ := by + rw [← (Submodule.span R _).ker_mkQ, LinearMap.ker_eq_top] + refine ext_of_span_eq_top hg (fun j ↦ ?_) + simp only [Submodule.mkQ_apply, LinearMap.zero_apply, Submodule.Quotient.mk_eq_zero] + exact Submodule.subset_span ⟨j, rfl⟩ + +end PiTensorProduct diff --git a/Mathlib/LinearAlgebra/TensorPower/Basic.lean b/Mathlib/LinearAlgebra/TensorPower/Basic.lean index 99590b87b2047a..8c920d358a1af7 100644 --- a/Mathlib/LinearAlgebra/TensorPower/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorPower/Basic.lean @@ -5,7 +5,7 @@ Authors: Eric Wieser -/ module -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.Logic.Equiv.Fin.Basic public import Mathlib.Algebra.DirectSum.Algebra diff --git a/Mathlib/LinearAlgebra/TensorPower/Symmetric.lean b/Mathlib/LinearAlgebra/TensorPower/Symmetric.lean index 3549e86257a213..7eed6268cd9194 100644 --- a/Mathlib/LinearAlgebra/TensorPower/Symmetric.lean +++ b/Mathlib/LinearAlgebra/TensorPower/Symmetric.lean @@ -5,7 +5,7 @@ Authors: Kenny Lau -/ module -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.Tactic.SuppressCompilation /-! diff --git a/Mathlib/Logic/Equiv/Option.lean b/Mathlib/Logic/Equiv/Option.lean index 895f3324f211fb..6419012cdb2fb3 100644 --- a/Mathlib/Logic/Equiv/Option.lean +++ b/Mathlib/Logic/Equiv/Option.lean @@ -289,4 +289,8 @@ def optionIsSomeEquiv (α) : { x : Option α // x.isSome } ≃ α where left_inv _ := Subtype.ext <| Option.some_get _ right_inv _ := Option.get_some _ _ +/-- The bijection `{ i // i ≠ i₀ } ⊕ PUnit ≃ α` for any `i₀ : α`. -/ +abbrev subtypeNeSumPUnit (i₀ : α) : { i // i ≠ i₀ } ⊕ PUnit.{u + 1} ≃ α := + (Equiv.optionEquivSumPUnit.{u} _).symm.trans (Equiv.optionSubtypeNe i₀) + end Equiv diff --git a/Mathlib/RingTheory/PiTensorProduct.lean b/Mathlib/RingTheory/PiTensorProduct.lean index 2543913444a0a1..df1663a1d5ae85 100644 --- a/Mathlib/RingTheory/PiTensorProduct.lean +++ b/Mathlib/RingTheory/PiTensorProduct.lean @@ -5,7 +5,7 @@ Authors: Jujian Zhang -/ module -public import Mathlib.LinearAlgebra.PiTensorProduct +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.Algebra.Algebra.Bilinear public import Mathlib.Algebra.Algebra.Equiv public import Mathlib.Data.Finset.NoncommProd From 17367c7945865a81a93b76faf79de9721f062545 Mon Sep 17 00:00:00 2001 From: David Gross Date: Thu, 18 Jun 2026 10:58:11 +0000 Subject: [PATCH 0134/1300] refactor(PiTensorProduct/{InjectiveNorm, ProjectiveNorm}): deprecate `injectiveSeminorm` (#35569) This PR: * Deprecates `PiTensorProduct.injectiveSeminorm` and supporting lemmas. * Moves the theory of `liftEquiv` from InjectiveSeminorm.lean to ProjectiveSeminorm.lean. No changes are introduced beyond adding deprecation notices, adapting docstrings, and moving material between files. The PR leaves InjectiveSeminorm.lean almost empty. A new implementation of `injectiveSeminorm`, one which reflects the common mathematical definition, is to be done. This is the third in a series of three PRs with the goal to [deprecate `PiTensorProuduct.injectiveSeminorm`](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/injectiveSeminorm/with/568798633). --- .../PiTensorProduct/InjectiveSeminorm.lean | 258 ++---------------- .../PiTensorProduct/ProjectiveSeminorm.lean | 210 +++++++++++++- 2 files changed, 227 insertions(+), 241 deletions(-) diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean index 50460c1ef4893c..4a18420fc5ec71 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean @@ -11,79 +11,36 @@ import Mathlib.LinearAlgebra.Isomorphisms /-! # Injective seminorm on the tensor of a finite family of normed spaces. -Let `𝕜` be a nontrivially normed field and `E` be a family of normed `𝕜`-vector spaces `Eᵢ`, -indexed by a finite type `ι`. We define a seminorm on `⨂[𝕜] i, Eᵢ`, which we call the -"injective seminorm". It is chosen to satisfy the following property: for every -normed `𝕜`-vector space `F`, the linear equivalence -`MultilinearMap 𝕜 E F ≃ₗ[𝕜] (⨂[𝕜] i, Eᵢ) →ₗ[𝕜] F` -expressing the universal property of the tensor product induces an isometric linear equivalence -`ContinuousMultilinearMap 𝕜 E F ≃ₗᵢ[𝕜] (⨂[𝕜] i, Eᵢ) →L[𝕜] F`. +The purpose of this file is to develop the theory of the injective tensor norm. -The idea is the following: Every normed `𝕜`-vector space `F` defines a linear map -from `⨂[𝕜] i, Eᵢ` to `ContinuousMultilinearMap 𝕜 E F →ₗ[𝕜] F`, which sends `x` to the map -`f ↦ f.lift x`. Thanks to `PiTensorProduct.norm_eval_le_projectiveSeminorm`, this map lands in -`ContinuousMultilinearMap 𝕜 E F →L[𝕜] F`. As this last space has a natural operator (semi)norm, -we get an induced seminorm on `⨂[𝕜] i, Eᵢ`, which, by -`PiTensorProduct.norm_eval_le_projectiveSeminorm`, is bounded above by the projective seminorm -`PiTensorProduct.projectiveSeminorm`. We then take the `sup` of these seminorms as `F` varies; -as this family of seminorms is bounded, its `sup` has good properties. +A first formalization turned out not to capture the common mathematical definition and is +now deprecated. See -In fact, we cannot take the `sup` over all normed spaces `F` because of set-theoretical issues, -so we only take spaces `F` in the same universe as `⨂[𝕜] i, Eᵢ`. We prove in -`norm_eval_le_injectiveSeminorm` that this gives the same result, because every multilinear map -from `E = Πᵢ Eᵢ` to `F` factors though a normed vector space in the same universe as -`⨂[𝕜] i, Eᵢ`. - -We then prove the universal property and the functoriality of `⨂[𝕜] i, Eᵢ` as a normed vector -space. +https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/injectiveSeminorm/with/568798633 ## Main definitions * `PiTensorProduct.toDualContinuousMultilinearMap`: The `𝕜`-linear map from `⨂[𝕜] i, Eᵢ` to `ContinuousMultilinearMap 𝕜 E F →L[𝕜] F` sending `x` to the map `f ↦ f x`. -* `PiTensorProduct.injectiveSeminorm`: The injective seminorm on `⨂[𝕜] i, Eᵢ`. -* `PiTensorProduct.liftEquiv`: The bijection between `ContinuousMultilinearMap 𝕜 E F` - and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F`, as a continuous linear equivalence. -* `PiTensorProduct.liftIsometry`: The bijection between `ContinuousMultilinearMap 𝕜 E F` - and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F`, as an isometric linear equivalence. -* `PiTensorProduct.tprodL`: The canonical continuous multilinear map from `E = Πᵢ Eᵢ` - to `⨂[𝕜] i, Eᵢ`. -* `PiTensorProduct.mapL`: The continuous linear map from `⨂[𝕜] i, Eᵢ` to `⨂[𝕜] i, E'ᵢ` - induced by a family of continuous linear maps `Eᵢ →L[𝕜] E'ᵢ`. -* `PiTensorProduct.mapLMultilinear`: The continuous multilinear map from - `Πᵢ (Eᵢ →L[𝕜] E'ᵢ)` to `(⨂[𝕜] i, Eᵢ) →L[𝕜] (⨂[𝕜] i, E'ᵢ)` sending a family - `f` to `PiTensorProduct.mapL f`. - -## Main results - -* `PiTensorProduct.norm_eval_le_injectiveSeminorm`: The main property of the injective seminorm - on `⨂[𝕜] i, Eᵢ`: for every `x` in `⨂[𝕜] i, Eᵢ` and every continuous multilinear map `f` from - `E = Πᵢ Eᵢ` to a normed space `F`, we have `‖f.lift x‖ ≤ ‖f‖ * injectiveSeminorm x `. -* `PiTensorProduct.mapL_opNorm`: If `f` is a family of continuous linear maps - `fᵢ : Eᵢ →L[𝕜] Fᵢ`, then `‖PiTensorProduct.mapL f‖ ≤ ∏ i, ‖fᵢ‖`. -* `PiTensorProduct.mapLMultilinear_opNorm` : If `F` is a normed vector space, then - `‖mapLMultilinear 𝕜 E F‖ ≤ 1`. ## TODO -* If all `Eᵢ` are separated and satisfy `SeparatingDual`, then the seminorm on - `⨂[𝕜] i, Eᵢ` is a norm. This uses the construction of a basis of the `PiTensorProduct`, hence - depends on PR https://github.com/leanprover-community/mathlib4/pull/11156. - It should probably go in a separate file. - -* Adapt the remaining functoriality constructions/properties from `PiTensorProduct`. +* Reimplement `injectiveSeminorm`. -/ @[expose] public section -universe uι u𝕜 uE uF +-- These explicit universe variables are required by `injectiveSeminorm`, which +-- has been marked as deprecated on 2026-06-10. TBD: delete the variables after the +-- deprecated material has been removed or re-implemented. +universe uι u𝕜 uE variable {ι : Type uι} [Fintype ι] variable {𝕜 : Type u𝕜} [NontriviallyNormedField 𝕜] variable {E : ι → Type uE} [∀ i, SeminormedAddCommGroup (E i)] [∀ i, NormedSpace 𝕜 (E i)] -variable {F : Type uF} [SeminormedAddCommGroup F] [NormedSpace 𝕜 F] +variable {F : Type*} [SeminormedAddCommGroup F] [NormedSpace 𝕜 F] open scoped TensorProduct @@ -116,11 +73,15 @@ theorem toDualContinuousMultilinearMap_le_projectiveSeminorm (x : ⨂[𝕜] i, E normed vector spaces `F`. In fact, we only take in the same universe as `⨂[𝕜] i, Eᵢ`, and then prove in `PiTensorProduct.norm_eval_le_injectiveSeminorm` that this gives the same result. -/ +@[deprecated + "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" + (since := "2026-06-10")] noncomputable irreducible_def injectiveSeminorm : Seminorm 𝕜 (⨂[𝕜] i, E i) := sSup {p | ∃ (G : Type (max uι u𝕜 uE)) (_ : SeminormedAddCommGroup G) (_ : NormedSpace 𝕜 G), p = Seminorm.comp (normSeminorm 𝕜 (ContinuousMultilinearMap 𝕜 E G →L[𝕜] G)) (toDualContinuousMultilinearMap G (𝕜 := 𝕜) (E := E))} +@[deprecated "no replacement" (since := "2026-06-10")] lemma dualSeminorms_bounded : BddAbove {p | ∃ (G : Type (max uι u𝕜 uE)) (_ : SeminormedAddCommGroup G) (_ : NormedSpace 𝕜 G), p = Seminorm.comp (normSeminorm 𝕜 (ContinuousMultilinearMap 𝕜 E G →L[𝕜] G)) @@ -130,6 +91,9 @@ lemma dualSeminorms_bounded : BddAbove {p | ∃ (G : Type (max uι u𝕜 uE)) intro p G _ _ hp x simpa [hp] using toDualContinuousMultilinearMap_le_projectiveSeminorm _ +@[deprecated + "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" + (since := "2026-06-10")] theorem injectiveSeminorm_apply (x : ⨂[𝕜] i, E i) : injectiveSeminorm x = ⨆ p : {p | ∃ (G : Type (max uι u𝕜 uE)) (_ : SeminormedAddCommGroup G) (_ : NormedSpace 𝕜 G), p = Seminorm.comp (normSeminorm 𝕜 @@ -138,6 +102,10 @@ theorem injectiveSeminorm_apply (x : ⨂[𝕜] i, E i) : simpa only [injectiveSeminorm, Set.coe_setOf, Set.mem_setOf_eq] using Seminorm.sSup_apply dualSeminorms_bounded +attribute [-instance] instSeminormedAddCommGroup in +@[deprecated + "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" + (since := "2026-06-10")] theorem norm_eval_le_injectiveSeminorm (f : ContinuousMultilinearMap 𝕜 E F) (x : ⨂[𝕜] i, E i) : ‖lift f.toMultilinearMap x‖ ≤ ‖f‖ * injectiveSeminorm x := by /- If `F` were in `Type (max uι u𝕜 uE)` (which is the type of `⨂[𝕜] i, E i`), then the @@ -191,6 +159,9 @@ theorem norm_eval_le_injectiveSeminorm (f : ContinuousMultilinearMap 𝕜 E F) ( rw [mul_comm] exact ContinuousLinearMap.le_opNorm _ _ +@[deprecated + "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" + (since := "2026-06-10")] theorem injectiveSeminorm_le_projectiveSeminorm : injectiveSeminorm (𝕜 := 𝕜) (E := E) ≤ projectiveSeminorm := by rw [injectiveSeminorm] @@ -208,188 +179,13 @@ theorem injectiveSeminorm_le_projectiveSeminorm : rw [h]; intro x; simp only [Seminorm.comp_apply, coe_normSeminorm] exact toDualContinuousMultilinearMap_le_projectiveSeminorm _ +@[deprecated + "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" + (since := "2026-06-10")] theorem injectiveSeminorm_tprod_le (m : Π (i : ι), E i) : injectiveSeminorm (⨂ₜ[𝕜] i, m i) ≤ ∏ i, ‖m i‖ := le_trans (injectiveSeminorm_le_projectiveSeminorm _) (projectiveSeminorm_tprod_le m) --- Use `projectiveSeminorm` to turn the `PiTensorProduct` into a seminormed space. --- The definition `injectiveSeminorm` is subject to deprecation in a follow-up PR. See: --- https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/injectiveSeminorm/with/568798633 -noncomputable instance : SeminormedAddCommGroup (⨂[𝕜] i, E i) := - fast_instance% AddGroupSeminorm.toSeminormedAddCommGroup projectiveSeminorm.toAddGroupSeminorm - -noncomputable instance : NormedSpace 𝕜 (⨂[𝕜] i, E i) := ⟨projectiveSeminorm_smul_le⟩ - -variable (𝕜 E F) - -/-- The linear equivalence between `ContinuousMultilinearMap 𝕜 E F` and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F` -induced by `PiTensorProduct.lift`, for every normed space `F`. --/ -@[simps] -noncomputable def liftEquiv : ContinuousMultilinearMap 𝕜 E F ≃ₗ[𝕜] (⨂[𝕜] i, E i) →L[𝕜] F where - toFun f := LinearMap.mkContinuous (lift f.toMultilinearMap) ‖f‖ fun x ↦ - norm_eval_le_projectiveSeminorm f x - map_add' f g := by ext; simp - map_smul' a f := by ext; simp - invFun l := MultilinearMap.mkContinuous (lift.symm l.toLinearMap) ‖l‖ fun x ↦ - ContinuousLinearMap.le_opNorm_of_le _ (projectiveSeminorm_tprod_le x) - left_inv f := by ext; simp - right_inv l := by - rw [← ContinuousLinearMap.coe_inj] - ext; simp - -/-- For a normed space `F`, we have constructed in `PiTensorProduct.liftEquiv` the canonical -linear equivalence between `ContinuousMultilinearMap 𝕜 E F` and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F` -(induced by `PiTensorProduct.lift`). Here we give the upgrade of this equivalence to -an isometric linear equivalence; in particular, it is a continuous linear equivalence. -/ -noncomputable def liftIsometry : ContinuousMultilinearMap 𝕜 E F ≃ₗᵢ[𝕜] (⨂[𝕜] i, E i) →L[𝕜] F := - LinearIsometryEquiv.ofBounds (liftEquiv 𝕜 E F) - (fun f ↦ LinearMap.mkContinuous_norm_le _ (norm_nonneg f) (norm_eval_le_projectiveSeminorm f)) - (fun f ↦ by - rw [liftEquiv_symm_apply] - exact MultilinearMap.mkContinuous_norm_le _ (norm_nonneg f) _) - -variable {𝕜 E F} - --- API missing for `LinearIsometryEquiv.ofBounds`? -@[simp] -theorem liftIsometry_apply_apply (f : ContinuousMultilinearMap 𝕜 E F) (x : ⨂[𝕜] i, E i) : - liftIsometry 𝕜 E F f x = lift f.toMultilinearMap x := by - simp [LinearIsometryEquiv.ofBounds, liftIsometry] - -variable (𝕜) in -/-- The canonical continuous multilinear map from `E = Πᵢ Eᵢ` to `⨂[𝕜] i, Eᵢ`. -/ -@[simps! toFun] -noncomputable def tprodL : ContinuousMultilinearMap 𝕜 E (⨂[𝕜] i, E i) := - (liftIsometry 𝕜 E _).symm (ContinuousLinearMap.id 𝕜 _) - -@[simp] -theorem tprodL_coe : (tprodL 𝕜).toMultilinearMap = tprod 𝕜 (s := E) := by - ext; simp - -@[simp] -theorem liftIsometry_symm_apply (l : (⨂[𝕜] i, E i) →L[𝕜] F) : - (liftIsometry 𝕜 E F).symm l = l.compContinuousMultilinearMap (tprodL 𝕜) := by - rfl - -@[simp] -theorem liftIsometry_tprodL : - liftIsometry 𝕜 E _ (tprodL 𝕜) = ContinuousLinearMap.id 𝕜 (⨂[𝕜] i, E i) := by - ext; simp - end seminorm -section map - -variable {E' E'' : ι → Type*} -variable [∀ i, SeminormedAddCommGroup (E' i)] [∀ i, NormedSpace 𝕜 (E' i)] -variable [∀ i, SeminormedAddCommGroup (E'' i)] [∀ i, NormedSpace 𝕜 (E'' i)] -variable (g : Π i, E' i →L[𝕜] E'' i) (f : Π i, E i →L[𝕜] E' i) - -/-- Let `Eᵢ` and `E'ᵢ` be two families of normed `𝕜`-vector spaces. -Let `f` be a family of continuous `𝕜`-linear maps between `Eᵢ` and `E'ᵢ`, i.e. -`f : Πᵢ Eᵢ →L[𝕜] E'ᵢ`, then there is an induced continuous linear map -`⨂ᵢ Eᵢ → ⨂ᵢ E'ᵢ` by `⨂ aᵢ ↦ ⨂ fᵢ aᵢ`. -/ -noncomputable def mapL : (⨂[𝕜] i, E i) →L[𝕜] ⨂[𝕜] i, E' i := - liftIsometry 𝕜 E _ <| (tprodL 𝕜).compContinuousLinearMap f - -@[simp] -theorem mapL_coe : (mapL f).toLinearMap = map (fun i ↦ (f i).toLinearMap) := by - ext; simp [mapL] - -@[simp] -theorem mapL_apply (x : ⨂[𝕜] i, E i) : mapL f x = map (fun i ↦ (f i).toLinearMap) x := by - rfl - -/-- Given submodules `pᵢ ⊆ Eᵢ`, this is the natural map: `⨂[𝕜] i, pᵢ → ⨂[𝕜] i, Eᵢ`. -This is the continuous version of `PiTensorProduct.mapIncl`. -/ -@[simp] -noncomputable def mapLIncl (p : Π i, Submodule 𝕜 (E i)) : (⨂[𝕜] i, p i) →L[𝕜] ⨂[𝕜] i, E i := - mapL fun (i : ι) ↦ (p i).subtypeL - -theorem mapL_comp : mapL (fun (i : ι) ↦ g i ∘L f i) = mapL g ∘L mapL f := by - apply ContinuousLinearMap.coe_injective - ext; simp - -theorem liftIsometry_comp_mapL (h : ContinuousMultilinearMap 𝕜 E' F) : - liftIsometry 𝕜 E' F h ∘L mapL f = liftIsometry 𝕜 E F (h.compContinuousLinearMap f) := by - apply ContinuousLinearMap.coe_injective - ext; simp - -@[simp] -theorem mapL_id : mapL (fun i ↦ ContinuousLinearMap.id 𝕜 (E i)) = ContinuousLinearMap.id _ _ := by - apply ContinuousLinearMap.coe_injective - ext; simp - -@[simp] -theorem mapL_one : mapL (fun (i : ι) ↦ (1 : E i →L[𝕜] E i)) = 1 := - mapL_id - -theorem mapL_mul (f₁ f₂ : Π i, E i →L[𝕜] E i) : - mapL (fun i ↦ f₁ i * f₂ i) = mapL f₁ * mapL f₂ := - mapL_comp f₁ f₂ - -/-- Upgrading `PiTensorProduct.mapL` to a `MonoidHom` when `E = E'`. -/ -@[simps] -noncomputable def mapLMonoidHom : (Π i, E i →L[𝕜] E i) →* ((⨂[𝕜] i, E i) →L[𝕜] ⨂[𝕜] i, E i) where - toFun := mapL - map_one' := mapL_one - map_mul' := mapL_mul - -@[simp] -protected theorem mapL_pow (f : Π i, E i →L[𝕜] E i) (n : ℕ) : - mapL (f ^ n) = mapL f ^ n := MonoidHom.map_pow mapLMonoidHom f n - --- We redeclare `ι` here, and later dependent arguments, --- to avoid the `[Fintype ι]` assumption present throughout the rest of the file. -open Function in -private theorem mapL_add_smul_aux {ι : Type uι} - {E : ι → Type uE} [(i : ι) → SeminormedAddCommGroup (E i)] [(i : ι) → NormedSpace 𝕜 (E i)] - {E' : ι → Type u_1} [(i : ι) → SeminormedAddCommGroup (E' i)] [(i : ι) → NormedSpace 𝕜 (E' i)] - (f : (i : ι) → E i →L[𝕜] E' i) [DecidableEq ι] (i : ι) (u : E i →L[𝕜] E' i) : - (fun j ↦ (update f i u j).toLinearMap) = - update (fun j ↦ (f j).toLinearMap) i u.toLinearMap := by - grind - -open Function in -protected theorem mapL_add [DecidableEq ι] (i : ι) (u v : E i →L[𝕜] E' i) : - mapL (update f i (u + v)) = mapL (update f i u) + mapL (update f i v) := by - ext - simp [mapL_add_smul_aux, PiTensorProduct.map_update_add] - -open Function in -protected theorem mapL_smul [DecidableEq ι] (i : ι) (c : 𝕜) (u : E i →L[𝕜] E' i) : - mapL (update f i (c • u)) = c • mapL (update f i u) := by - ext - simp [mapL_add_smul_aux, PiTensorProduct.map_update_smul] - -theorem mapL_opNorm : ‖mapL f‖ ≤ ∏ i, ‖f i‖ := by - refine (ContinuousLinearMap.opNorm_le_iff (by positivity)).mpr fun x ↦ ?_ - apply le_trans (norm_eval_le_projectiveSeminorm ..) (mul_le_mul_of_nonneg_right _ (norm_nonneg x)) - refine (ContinuousMultilinearMap.opNorm_le_iff (by positivity)).mpr fun m ↦ ?_ - apply le_trans (projectiveSeminorm_tprod_le fun i ↦ f i (m i)) - rw [← Finset.prod_mul_distrib] - gcongr - exact ContinuousLinearMap.le_opNorm _ _ - -variable (𝕜 E E') - -/-- The tensor of a family of linear maps from `Eᵢ` to `E'ᵢ`, as a continuous multilinear map of -the family. -/ -@[simps! toFun_apply] -noncomputable def mapLMultilinear : ContinuousMultilinearMap 𝕜 (fun (i : ι) ↦ E i →L[𝕜] E' i) - ((⨂[𝕜] i, E i) →L[𝕜] ⨂[𝕜] i, E' i) := - MultilinearMap.mkContinuous - { toFun := mapL - map_update_smul' := fun _ _ _ _ ↦ PiTensorProduct.mapL_smul _ _ _ _ - map_update_add' := fun _ _ _ _ ↦ PiTensorProduct.mapL_add _ _ _ _ } - 1 (fun f ↦ by rw [one_mul]; exact mapL_opNorm f) - -variable {𝕜 E E'} - -theorem mapLMultilinear_opNorm : ‖mapLMultilinear 𝕜 E E'‖ ≤ 1 := - MultilinearMap.mkContinuous_norm_le _ zero_le_one _ - -end map - end PiTensorProduct diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean index 4a419478bd0338..432bc808ff1f78 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2024 Sophie Morel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Sophie Morel +Authors: Sophie Morel, David Gross, Davood Haji Taghi Tehrani -/ module @@ -23,27 +23,41 @@ for every `m` in `Π i, Eᵢ` is bounded above by the projective seminorm. ## Main definitions * `PiTensorProduct.projectiveSeminorm`: The projective seminorm on `⨂[𝕜] i, Eᵢ`. +* `PiTensorProduct.liftEquiv`: The bijection between `ContinuousMultilinearMap 𝕜 E F` + and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F`, as a continuous linear equivalence. +* `PiTensorProduct.liftIsometry`: The bijection between `ContinuousMultilinearMap 𝕜 E F` + and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F`, as an isometric linear equivalence. +* `PiTensorProduct.tprodL`: The canonical continuous multilinear map from `E = Πᵢ Eᵢ` + to `⨂[𝕜] i, Eᵢ`. +* `PiTensorProduct.mapL`: The continuous linear map from `⨂[𝕜] i, Eᵢ` to `⨂[𝕜] i, E'ᵢ` + induced by a family of continuous linear maps `Eᵢ →L[𝕜] E'ᵢ`. +* `PiTensorProduct.mapLMultilinear`: The continuous multilinear map from + `Πᵢ (Eᵢ →L[𝕜] E'ᵢ)` to `(⨂[𝕜] i, Eᵢ) →L[𝕜] (⨂[𝕜] i, E'ᵢ)` sending a family + `f` to `PiTensorProduct.mapL f`. ## Main results * `PiTensorProduct.norm_eval_le_projectiveSeminorm`: If `f` is a continuous multilinear map on `E = Π i, Eᵢ` and `x` is in `⨂[𝕜] i, Eᵢ`, then `‖f.lift x‖ ≤ projectiveSeminorm x * ‖f‖`. +* `PiTensorProduct.mapL_opNorm`: If `f` is a family of continuous linear maps + `fᵢ : Eᵢ →L[𝕜] Fᵢ`, then `‖PiTensorProduct.mapL f‖ ≤ ∏ i, ‖fᵢ‖`. +* `PiTensorProduct.opNorm_mapLMultilinear_le` : If `F` is a normed vecteor space, then + `‖mapLMultilinear 𝕜 E F‖ ≤ 1`. ## TODO * If the base field is `ℝ` or `ℂ` (or more generally if the injection of `Eᵢ` into its bidual is an isometry for every `i`), then we have `projectiveSeminorm ⨂ₜ[𝕜] i, mᵢ = Π i, ‖mᵢ‖`. - -* The functoriality. +* If all `Eᵢ` are separated and satisfy `SeparatingDual`, then the seminorm on + `⨂[𝕜] i, Eᵢ` is a norm. +* Adapt the remaining functoriality constructions/properties from `PiTensorProduct`. -/ @[expose] public section -universe uι u𝕜 uE uF - -variable {ι : Type uι} [Fintype ι] -variable {𝕜 : Type u𝕜} -variable {E : ι → Type uE} [∀ i, SeminormedAddCommGroup (E i)] +variable {ι : Type*} [Fintype ι] +variable {𝕜 : Type*} +variable {E : ι → Type*} [∀ i, SeminormedAddCommGroup (E i)] open scoped TensorProduct @@ -86,7 +100,7 @@ noncomputable instance : Norm (⨂[𝕜] i, E i) := theorem norm_def (x : ⨂[𝕜] i, E i) : ‖x‖ = iInf (fun (p : lifts x) ↦ projectiveSeminormAux p.val) := rfl -@[deprecated (since := "2026-03-13")] alias projectiveSeminormFun := norm +@[deprecated (since := "2026-06-10")] alias projectiveSeminormFun := norm theorem projectiveSeminorm_zero : ‖(0 : ⨂[𝕜] i, E i)‖ = 0 := le_antisymm (ciInf_le (bddBelow_projectiveSemiNormAux _) ⟨0, lifts_zero⟩) @@ -108,7 +122,12 @@ of `∑ j, Π i, ‖mⱼ i‖`. -/ noncomputable def projectiveSeminorm : Seminorm 𝕜 (⨂[𝕜] i, E i) := .ofSMulLE _ projectiveSeminorm_zero projectiveSeminorm_add_le projectiveSeminorm_smul_le -@[deprecated norm_def (since := "2026-03-06")] +noncomputable instance : SeminormedAddCommGroup (⨂[𝕜] i, E i) := + fast_instance% AddGroupSeminorm.toSeminormedAddCommGroup projectiveSeminorm.toAddGroupSeminorm + +noncomputable instance : NormedSpace 𝕜 (⨂[𝕜] i, E i) := ⟨projectiveSeminorm_smul_le⟩ + +@[deprecated norm_def (since := "2026-06-10")] theorem projectiveSeminorm_apply (x : ⨂[𝕜] i, E i) : projectiveSeminorm x = iInf (fun (p : lifts x) ↦ projectiveSeminormAux p.1) := rfl @@ -136,6 +155,177 @@ theorem norm_eval_le_projectiveSeminorm {G : Type*} [SeminormedAddCommGroup G] simpa [norm_smul, ← mul_assoc, mul_comm ‖f‖ _] using fun a m _ ↦ mul_le_mul_of_nonneg_left (f.le_opNorm _) (norm_nonneg _) +variable {F : Type*} [SeminormedAddCommGroup F] [NormedSpace 𝕜 F] + +variable (𝕜 E F) + +/-- The linear equivalence between `ContinuousMultilinearMap 𝕜 E F` and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F` +induced by `PiTensorProduct.lift`, for every normed space `F`. +-/ +@[simps] +noncomputable def liftEquiv : ContinuousMultilinearMap 𝕜 E F ≃ₗ[𝕜] (⨂[𝕜] i, E i) →L[𝕜] F where + toFun f := LinearMap.mkContinuous (lift f.toMultilinearMap) ‖f‖ fun x ↦ + norm_eval_le_projectiveSeminorm f x + map_add' f g := by ext; simp + map_smul' a f := by ext; simp + invFun l := MultilinearMap.mkContinuous (lift.symm l.toLinearMap) ‖l‖ fun x ↦ + ContinuousLinearMap.le_opNorm_of_le _ (projectiveSeminorm_tprod_le x) + left_inv f := by ext; simp + right_inv l := by + rw [← ContinuousLinearMap.coe_inj] + ext; simp + +/-- For a normed space `F`, we have constructed in `PiTensorProduct.liftEquiv` the canonical +linear equivalence between `ContinuousMultilinearMap 𝕜 E F` and `(⨂[𝕜] i, Eᵢ) →L[𝕜] F` +(induced by `PiTensorProduct.lift`). Here we give the upgrade of this equivalence to +an isometric linear equivalence; in particular, it is a continuous linear equivalence. -/ +noncomputable def liftIsometry : ContinuousMultilinearMap 𝕜 E F ≃ₗᵢ[𝕜] (⨂[𝕜] i, E i) →L[𝕜] F := + LinearIsometryEquiv.ofBounds (liftEquiv 𝕜 E F) + (fun f ↦ LinearMap.mkContinuous_norm_le _ (norm_nonneg f) (norm_eval_le_projectiveSeminorm f)) + (fun f ↦ by + rw [liftEquiv_symm_apply] + exact MultilinearMap.mkContinuous_norm_le _ (norm_nonneg f) _) + +variable {𝕜 E F} + +@[simp] +theorem liftIsometry_apply_apply (f : ContinuousMultilinearMap 𝕜 E F) (x : ⨂[𝕜] i, E i) : + liftIsometry 𝕜 E F f x = lift f.toMultilinearMap x := by + simp [LinearIsometryEquiv.ofBounds, liftIsometry] + +variable (𝕜) in +/-- The canonical continuous multilinear map from `E = Πᵢ Eᵢ` to `⨂[𝕜] i, Eᵢ`. -/ +@[simps! toFun] +noncomputable def tprodL : ContinuousMultilinearMap 𝕜 E (⨂[𝕜] i, E i) := + (liftIsometry 𝕜 E _).symm (ContinuousLinearMap.id 𝕜 _) + +@[simp] +theorem tprodL_coe : (tprodL 𝕜).toMultilinearMap = tprod 𝕜 (s := E) := by + ext; simp + +@[simp] +theorem liftIsometry_symm_apply (l : (⨂[𝕜] i, E i) →L[𝕜] F) : + (liftIsometry 𝕜 E F).symm l = l.compContinuousMultilinearMap (tprodL 𝕜) := by + rfl + +@[simp] +theorem liftIsometry_tprodL : + liftIsometry 𝕜 E _ (tprodL 𝕜) = ContinuousLinearMap.id 𝕜 (⨂[𝕜] i, E i) := by + ext; simp + +section map + +variable {E' E'' : ι → Type*} +variable [∀ i, SeminormedAddCommGroup (E' i)] [∀ i, NormedSpace 𝕜 (E' i)] +variable [∀ i, SeminormedAddCommGroup (E'' i)] [∀ i, NormedSpace 𝕜 (E'' i)] +variable (g : Π i, E' i →L[𝕜] E'' i) (f : Π i, E i →L[𝕜] E' i) + +/-- Let `Eᵢ` and `E'ᵢ` be two families of normed `𝕜`-vector spaces. +Let `f` be a family of continuous `𝕜`-linear maps between `Eᵢ` and `E'ᵢ`, i.e. +`f : Πᵢ Eᵢ →L[𝕜] E'ᵢ`, then there is an induced continuous linear map +`⨂ᵢ Eᵢ → ⨂ᵢ E'ᵢ` by `⨂ aᵢ ↦ ⨂ fᵢ aᵢ`. -/ +noncomputable def mapL : (⨂[𝕜] i, E i) →L[𝕜] ⨂[𝕜] i, E' i := + liftIsometry 𝕜 E _ <| (tprodL 𝕜).compContinuousLinearMap f + +@[simp] +theorem mapL_coe : (mapL f).toLinearMap = map (fun i ↦ (f i).toLinearMap) := by + ext; simp [mapL] + +@[simp] +theorem mapL_apply (x : ⨂[𝕜] i, E i) : mapL f x = map (fun i ↦ (f i).toLinearMap) x := by + rfl + +/-- Given submodules `pᵢ ⊆ Eᵢ`, this is the natural map: `⨂[𝕜] i, pᵢ → ⨂[𝕜] i, Eᵢ`. +This is the continuous version of `PiTensorProduct.mapIncl`. -/ +@[simp] +noncomputable def mapLIncl (p : Π i, Submodule 𝕜 (E i)) : (⨂[𝕜] i, p i) →L[𝕜] ⨂[𝕜] i, E i := + mapL fun (i : ι) ↦ (p i).subtypeL + +theorem mapL_comp : mapL (fun (i : ι) ↦ g i ∘L f i) = mapL g ∘L mapL f := by + apply ContinuousLinearMap.coe_injective + ext; simp + +theorem liftIsometry_comp_mapL (h : ContinuousMultilinearMap 𝕜 E' F) : + liftIsometry 𝕜 E' F h ∘L mapL f = liftIsometry 𝕜 E F (h.compContinuousLinearMap f) := by + apply ContinuousLinearMap.coe_injective + ext; simp + +@[simp] +theorem mapL_id : mapL (fun i ↦ ContinuousLinearMap.id 𝕜 (E i)) = ContinuousLinearMap.id _ _ := by + apply ContinuousLinearMap.coe_injective + ext; simp + +@[simp] +theorem mapL_one : mapL (fun (i : ι) ↦ (1 : E i →L[𝕜] E i)) = 1 := + mapL_id + +theorem mapL_mul (f₁ f₂ : Π i, E i →L[𝕜] E i) : + mapL (fun i ↦ f₁ i * f₂ i) = mapL f₁ * mapL f₂ := + mapL_comp f₁ f₂ + +/-- Upgrading `PiTensorProduct.mapL` to a `MonoidHom` when `E = E'`. -/ +@[simps] +noncomputable def mapLMonoidHom : (Π i, E i →L[𝕜] E i) →* ((⨂[𝕜] i, E i) →L[𝕜] ⨂[𝕜] i, E i) where + toFun := mapL + map_one' := mapL_one + map_mul' := mapL_mul + +@[simp] +protected theorem mapL_pow (f : Π i, E i →L[𝕜] E i) (n : ℕ) : + mapL (f ^ n) = mapL f ^ n := MonoidHom.map_pow mapLMonoidHom f n + +-- We redeclare `ι` here, and later dependent arguments, +-- to avoid the `[Fintype ι]` assumption present throughout the rest of the file. +open Function in +private theorem mapL_add_smul_aux {ι : Type*} + {E : ι → Type*} [∀ i, SeminormedAddCommGroup (E i)] [∀ i, NormedSpace 𝕜 (E i)] + {E' : ι → Type*} [∀ i, SeminormedAddCommGroup (E' i)] [∀ i, NormedSpace 𝕜 (E' i)] + (f : (i : ι) → E i →L[𝕜] E' i) [DecidableEq ι] (i : ι) (u : E i →L[𝕜] E' i) : + (fun j ↦ (update f i u j).toLinearMap) = + update (fun j ↦ (f j).toLinearMap) i u.toLinearMap := by + grind + +open Function in +protected theorem mapL_add [DecidableEq ι] (i : ι) (u v : E i →L[𝕜] E' i) : + mapL (update f i (u + v)) = mapL (update f i u) + mapL (update f i v) := by + ext + simp [mapL_add_smul_aux, PiTensorProduct.map_update_add] + +open Function in +protected theorem mapL_smul [DecidableEq ι] (i : ι) (c : 𝕜) (u : E i →L[𝕜] E' i) : + mapL (update f i (c • u)) = c • mapL (update f i u) := by + ext + simp [mapL_add_smul_aux, PiTensorProduct.map_update_smul] + +theorem opNorm_mapL : ‖mapL f‖ ≤ ∏ i, ‖f i‖ := by + refine (ContinuousLinearMap.opNorm_le_iff (by positivity)).mpr fun x ↦ ?_ + apply le_trans (norm_eval_le_projectiveSeminorm ..) (mul_le_mul_of_nonneg_right _ (norm_nonneg x)) + refine (ContinuousMultilinearMap.opNorm_le_iff (by positivity)).mpr fun m ↦ ?_ + apply le_trans (projectiveSeminorm_tprod_le fun i ↦ f i (m i)) + rw [← Finset.prod_mul_distrib] + gcongr + exact ContinuousLinearMap.le_opNorm _ _ + +variable (𝕜 E E') + +/-- The tensor of a family of linear maps from `Eᵢ` to `E'ᵢ`, as a continuous multilinear map of +the family. -/ +@[simps! toFun_apply] +noncomputable def mapLMultilinear : ContinuousMultilinearMap 𝕜 (fun (i : ι) ↦ E i →L[𝕜] E' i) + ((⨂[𝕜] i, E i) →L[𝕜] ⨂[𝕜] i, E' i) := + MultilinearMap.mkContinuous + { toFun := mapL + map_update_smul' := fun _ _ _ _ ↦ PiTensorProduct.mapL_smul _ _ _ _ + map_update_add' := fun _ _ _ _ ↦ PiTensorProduct.mapL_add _ _ _ _ } + 1 (fun f ↦ by rw [one_mul]; exact opNorm_mapL f) + +variable {𝕜 E E'} + +theorem opNorm_mapLMultilinear_le : ‖mapLMultilinear 𝕜 E E'‖ ≤ 1 := + MultilinearMap.mkContinuous_norm_le _ zero_le_one _ + +end map + end NontriviallyNormedField end PiTensorProduct From cb934192a12300b675308b0469207f53b3f8e4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 18 Jun 2026 10:58:13 +0000 Subject: [PATCH 0135/1300] =?UTF-8?q?feat(CategoryTheory):=20the=20=CE=BA-?= =?UTF-8?q?accessible=20category=20of=20=CE=BA-directed=20posets=20(#39655?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given a regular cardinal `κ : Cardinal.{u}`, we show that the category `CardinalFilteredPoset κ` of `κ`-directed partially ordered types (with order embeddings as morphisms) is a `κ`-accessible category. --- .../Presentable/CardinalDirectedPoset.lean | 191 +++++++++++++++++- 1 file changed, 189 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean index 287c35be55071b..8217cf1f7859a6 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean @@ -14,8 +14,13 @@ public import Mathlib.Order.Category.PartOrdEmb Given a regular cardinal `κ : Cardinal.{u}`, we define the category `CardinalFilteredPoset κ` of `κ`-directed partially ordered -types (with order embeddings as morphisms). We shall show that it is -a `κ`-accessible category (TODO @joelriou). +types (with order embeddings as morphisms), and we show that it is +a `κ`-accessible category. + +If `κ ≤ κ'` where `κ'` is also a regular cardinal, we characterize +the `κ'`-presentable objects of `CardinalFilteredPoset κ` as +the objects `J` such that the underlying type `J.obj` has +cardinality `< κ'`. ## References * [Adámek, J. and Rosický, J., *Locally presentable and accessible categories*][Adamek_Rosicky_1994] @@ -105,6 +110,13 @@ abbrev of (J : PartOrdEmb.{u}) [IsCardinalFiltered J κ] : CardinalFilteredPoset obj := J property := inferInstance +lemma Hom.injective {J₁ J₂ : CardinalFilteredPoset κ} (f : J₁ ⟶ J₂) : + Function.Injective f := f.hom.injective + +lemma Hom.le_iff_le {J₁ J₂ : CardinalFilteredPoset κ} (f : J₁ ⟶ J₂) (x₁ x₂ : J₁.obj) : + f x₁ ≤ f x₂ ↔ x₁ ≤ x₂ := + f.hom.hom.le_iff_le + instance (J : CardinalFilteredPoset κ) : IsCardinalFiltered J.obj κ := J.property instance (J : CardinalFilteredPoset κ) : IsFiltered J.obj := @@ -170,6 +182,77 @@ noncomputable def isColimitCoconeOfPredicateSet end +variable (κ) in +/-- The property of posets in `CardinalFilteredPoset κ` that are +of cardinality `< κ` and have terminal object. -/ +def hasCardinalLTWithTerminal : ObjectProperty (CardinalFilteredPoset κ) := + fun J ↦ HasCardinalLT J.obj κ ∧ HasTerminal J.obj + +instance : ObjectProperty.EssentiallySmall.{u} (hasCardinalLTWithTerminal κ) where + exists_small_le' := by + obtain ⟨X, hX⟩ : ∃ (X : Type u), Cardinal.mk X = κ := ⟨κ.ord.ToType, by simp⟩ + let α : Type u := Σ (S : Set X) (_ : PartialOrder S), + ULift.{u} (PLift (IsCardinalFiltered S κ)) + let (a : α) : PartialOrder a.1 := a.2.1 + let ι (a : α) : CardinalFilteredPoset κ := + { obj := .of a.1 + property := a.2.2.down.down } + refine ⟨.ofObj ι, inferInstance, fun J ⟨hJ, _⟩ ↦ ?_⟩ + obtain ⟨f⟩ : Cardinal.mk J.obj ≤ Cardinal.mk X := by + simpa [hX] using ((hasCardinalLT_iff_cardinal_mk_lt _ _).1 hJ).le + let e := Equiv.ofInjective _ f.injective + letI : PartialOrder (Set.range f) := PartialOrder.lift _ e.symm.injective + let e' : Set.range f ≃o J.obj := { toEquiv := e.symm, map_rel_iff' := by rfl } + exact ⟨_, ⟨⟨Set.range f, inferInstance, + ⟨⟨IsCardinalFiltered.of_equivalence κ e'.symm.equivalence⟩⟩⟩⟩, + ⟨CardinalFilteredPoset.ι.preimageIso (PartOrdEmb.Iso.mk (by exact e'.symm))⟩⟩ + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma isCardinalPresentable_of_hasCardinalLT_of_le (J : CardinalFilteredPoset κ) + {κ' : Cardinal.{u}} [Fact κ'.IsRegular] (hJ : HasCardinalLT J.obj κ') (h : κ ≤ κ') : + IsCardinalPresentable J κ' where + preservesColimitOfShape A _ _ := ⟨fun {F} ↦ ⟨fun {c} hc ↦ ⟨by + · have := isFiltered_of_isCardinalFiltered A κ' + have := IsCardinalFiltered.of_le A h + replace hc := isColimitOfPreserves (forget _) hc + refine Types.FilteredColimit.isColimitOf' _ _ (fun f ↦ ?_) (fun j f g h ↦ ?_) + · dsimp at f + choose j g hg using fun (x : J.obj) ↦ Types.jointly_surjective_of_isColimit hc (f x) + let m := IsCardinalFiltered.max j hJ + let φ (x : J.obj) : (F.obj m).obj := F.map (IsCardinalFiltered.toMax j hJ x) (g x) + have hφ (x : J.obj) : f x = c.ι.app _ (φ x) := by + dsimp [φ] + rw [← hg, ← ConcreteCategory.comp_apply, c.w] + rfl + refine ⟨m, + ObjectProperty.homMk (PartOrdEmb.ofHom + { toFun := φ + inj' x y h := Hom.injective f (by simpa [hφ]) + map_rel_iff' {x y} := ?_ }), ?_⟩ + · simp [← Hom.le_iff_le f, hφ] + · dsimp + ext x + trans c.ι.app (j x) (g x) + · exact (hg x).symm + · exact (ConcreteCategory.congr_hom (c.w (IsCardinalFiltered.toMax j hJ x)).symm (g x)) + · choose k a hk using fun (x : J.obj) ↦ + (Types.FilteredColimit.isColimit_eq_iff' hc _ _).1 (ConcreteCategory.congr_hom h x) + dsimp at f g h k a hk ⊢ + obtain ⟨l, b, c, hl⟩ : ∃ (l : A) (c : j ⟶ l) (b : ∀ x, k x ⟶ l), + ∀ x, a x ≫ b x = c := by + let φ (x : J.obj) : j ⟶ IsCardinalFiltered.max k hJ := + a x ≫ IsCardinalFiltered.toMax k hJ x + exact ⟨IsCardinalFiltered.coeq φ hJ, + IsCardinalFiltered.toCoeq φ hJ, + fun x ↦ IsCardinalFiltered.toMax k hJ x ≫ IsCardinalFiltered.coeqHom φ hJ, + fun x ↦ by simpa [φ] using IsCardinalFiltered.coeq_condition φ hJ x⟩ + refine ⟨l, b, ?_⟩ + ext x + simpa only [← hl x, Functor.map_comp, ObjectProperty.FullSubcategory.comp_hom, + PartOrdEmb.hom_comp, RelEmbedding.coe_trans, Function.comp_apply] + using! congr_arg _ (hk x)⟩⟩⟩ + section variable (J : CardinalFilteredPoset κ) @@ -240,8 +323,112 @@ noncomputable def isColimitCoconeWithTop : IsColimit (coconeWithTop J κ') := | some a => exact ⟨_, propSetWithTop_pair _ a, by aesop⟩ | none => exact ⟨_, propSetWithTop_pair _ (Classical.arbitrary _), by aesop⟩) +variable {κ'} in +protected lemma isCardinalPresentable_iff (h : κ ≤ κ') : + IsCardinalPresentable J κ' ↔ HasCardinalLT J.obj κ' := by + refine ⟨fun _ ↦ ?_, fun hJ ↦ isCardinalPresentable_of_hasCardinalLT_of_le _ hJ h⟩ + obtain ⟨X, f, hf⟩ := + IsCardinalPresentable.exists_hom_of_isColimit κ' (isColimitCoconeWithTop J κ') + (ObjectProperty.homMk (PartOrdEmb.ofHom WithTop.coeOrderHom)) + replace hf : OrderEmbedding.subtype X.1 ∘ f = WithTop.coeOrderHom := by + ext x + exact ConcreteCategory.congr_hom hf x + refine X.2.1.of_injective f (Function.Injective.of_comp + (f := OrderEmbedding.subtype X.1) ?_) + dsimp at hf ⊢ + rw [hf] + exact WithTop.coe_injective + end +protected lemma isCardinalPresentable_iff' (J : CardinalFilteredPoset κ) : + IsCardinalPresentable J κ ↔ HasCardinalLT J.obj κ := + CardinalFilteredPoset.isCardinalPresentable_iff _ (le_refl _) + +section + +variable (J : CardinalFilteredPoset κ) + +/-- Given `J : CardinalFilteredPoset κ`, this is the predicate +on `Set J.obj` that is satisfied by subsets that are of +cardinality `< κ` and have a terminal object. -/ +def PropSet (S : Set J.obj) : Prop := + HasCardinalLT S κ ∧ HasTerminal S + +instance (S : Subtype J.PropSet) : HasTerminal S := S.prop.2 + +instance (S : Subtype J.PropSet) : IsCardinalFiltered S κ := + isCardinalFiltered_of_hasTerminal _ _ + +variable {J} in +lemma propSet_singleton (j : J.obj) : J.PropSet {j} := + ⟨hasCardinalLT_of_finite _ _ (Cardinal.IsRegular.aleph0_le Fact.out), by + let : OrderTop ({j} : Set J.obj) := { top := ⟨j, rfl⟩, le_top := by simp } + exact isTerminalTop.hasTerminal⟩ + +instance : IsCardinalFiltered (Subtype J.PropSet) κ := + isCardinalFiltered_preorder _ _ (fun K α hK ↦ by + rw [← hasCardinalLT_iff_cardinal_mk_lt] at hK + let t (k : K) : (α k).val := ⊤_ _ + let m := IsCardinalFiltered.max (fun k ↦ (t k).val) hK + let S : Set J.obj := (⋃ (k : K), α k) ∪ {m} + let : OrderTop S := + { top := ⟨m, by simp [S]⟩ + le_top := by + rintro ⟨s, hs⟩ + simp only [Set.union_singleton, Set.mem_insert_iff, Set.mem_iUnion, S] at hs + obtain rfl | ⟨k, hs⟩ := hs + · simp + · simp only [Subtype.mk_le_mk] + exact leOfHom ((by exact terminal.from (C := (α k).val) ⟨_, hs⟩) ≫ + IsCardinalFiltered.toMax _ hK k) } + refine ⟨⟨S, ?_, isTerminalTop.hasTerminal⟩, fun k ↦ ?_⟩ + · have hκ : Cardinal.aleph0 ≤ κ := Cardinal.IsRegular.aleph0_le Fact.out + exact hasCardinalLT_union hκ (hasCardinalLT_iUnion _ hK (fun k ↦ (α k).2.1)) + (hasCardinalLT_of_finite _ _ hκ) + · simp only [← Subtype.coe_le_coe, Set.le_eq_subset] + exact subset_trans (Set.subset_iUnion_of_subset k (subset_refl _)) Set.subset_union_left ) + +instance : IsFiltered (Subtype J.PropSet) := isFiltered_of_isCardinalFiltered _ κ + +instance : IsDirectedOrder (Subtype J.PropSet) := + IsFiltered.isDirectedOrder _ + +instance : Nonempty (Subtype J.PropSet) := + IsFiltered.nonempty + +/-- For any object `J : CardinalFilteredPoset κ`, this is a colimit +cocone exhibiting `J` as the colimit of its subsets +that are of cardinality `< κ` and have a terminal object. -/ +abbrev cocone : Cocone (functorOfPredicateSet J.PropSet) := + coconeOfPredicateSet J.PropSet + +/-- Any object `J : CardinalFilteredPoset κ` is a colimit +of its subsets that are of cardinality `< κ` and have a terminal object. -/ +noncomputable def isColimitCocone (J : CardinalFilteredPoset κ) : + IsColimit (cocone J) := + isColimitCoconeOfPredicateSet _ (fun a ↦ ⟨_, propSet_singleton a, by simp⟩) + +end + +variable (κ) in +lemma isCardinalFilteredGenerator_hasCardinalLTWithTerminal : + (hasCardinalLTWithTerminal κ).IsCardinalFilteredGenerator κ where + le_isCardinalPresentable := by + rintro J ⟨_, _⟩ + rwa [isCardinalPresentable_iff, J.isCardinalPresentable_iff'] + exists_colimitsOfShape J := + ⟨_, inferInstance, inferInstance, ⟨{ + diag := _ + ι := _ + isColimit := isColimitCocone J + prop_diag_obj j := j.prop }⟩⟩ + +instance : IsCardinalAccessibleCategory (CardinalFilteredPoset κ) κ where + exists_generator := + ⟨hasCardinalLTWithTerminal κ, inferInstance, + isCardinalFilteredGenerator_hasCardinalLTWithTerminal κ⟩ + end CardinalFilteredPoset end CategoryTheory From ec6e08b4dfb414460f0ee7b4ce9678e7e04fb584 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Thu, 18 Jun 2026 10:58:15 +0000 Subject: [PATCH 0136/1300] feat(FieldTheory/IntermediateField): add eq_iff_finrank_eq_of_le(') (#40300) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the iff-strengthenings of `IntermediateField.eq_of_le_of_finrank_eq` and `eq_of_le_of_finrank_eq'`: - `eq_iff_finrank_eq_of_le`: for `F ≤ E` with `[E : K]` finite, `F = E ↔ finrank K F = finrank K E`. - `eq_iff_finrank_eq_of_le'`: for `F ≤ E` with `[L : F]` finite, `F = E ↔ finrank F L = finrank E L`. :robot: This PR was extracted from the [SKW project](https://github.com/xroblot/SKW) by Claude. --- Mathlib/FieldTheory/IntermediateField/Algebraic.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean index a6f80e8bd9464c..0898d2e4d45ed6 100644 --- a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean @@ -75,6 +75,12 @@ theorem eq_of_le_of_finrank_eq [FiniteDimensional K E] (h_le : F ≤ E) (h_finrank : finrank K F = finrank K E) : F = E := eq_of_le_of_finrank_le h_le h_finrank.ge +/-- If `F ≤ E` are two intermediate fields of `L / K` such that `[E : K]` is finite, +then `F = E` iff `[F : K] = [E : K]`. -/ +theorem eq_iff_finrank_eq_of_le [FiniteDimensional K E] (h_le : F ≤ E) : + F = E ↔ finrank K F = finrank K E := + ⟨fun h ↦ by rw [h], eq_of_le_of_finrank_eq h_le⟩ + -- If `F ≤ E` are two intermediate fields of a finite extension `L / K` such that -- `[L : F] ≤ [L : E]`, then `F = E`. Marked as private since it's a direct corollary of -- `eq_of_le_of_finrank_le'` (the `FiniteDimensional K L` implies `FiniteDimensional F L` @@ -101,6 +107,12 @@ theorem eq_of_le_of_finrank_eq' [FiniteDimensional F L] (h_le : F ≤ E) (h_finrank : finrank F L = finrank E L) : F = E := eq_of_le_of_finrank_le' h_le h_finrank.le +/-- If `F ≤ E` are two intermediate fields of `L / K` such that `[L : F]` is finite, +then `F = E` iff `[L : F] = [L : E]`. -/ +theorem eq_iff_finrank_eq_of_le' [FiniteDimensional F L] (h_le : F ≤ E) : + F = E ↔ finrank F L = finrank E L := + ⟨fun h ↦ by rw [h], eq_of_le_of_finrank_eq' h_le⟩ + lemma finrank_lt_of_gt [FiniteDimensional F L] (H : F < E) : Module.finrank E L < Module.finrank F L := by letI := (IntermediateField.inclusion H.le).toAlgebra From 028b72cdeb34a8dcf80f29ba01136ce9dc86ec15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:17:00 +0000 Subject: [PATCH 0137/1300] =?UTF-8?q?feat(AlgebraicGeometry):=20points=20o?= =?UTF-8?q?f=20the=20small=20=C3=A9tale=20site=20(#35136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main definition in this PR is `Scheme.pointSmallEtale`. Given a morphism `Spec (.of Ω) ⟶ S` where `Ω` is a separably closed field, we define the corresponding point of the small étale site of `S`. We show that these points form a conservative family. (This PR also removes the definition `Scheme.geometricFiber` which was not correct.) Co-authored-by: Christian Merten --- Mathlib.lean | 1 + Mathlib/AlgebraicGeometry/Fiber.lean | 5 + .../AlgebraicGeometry/Morphisms/Etale.lean | 50 +++++- Mathlib/AlgebraicGeometry/Sites/Etale.lean | 31 ++++ .../AlgebraicGeometry/Sites/EtalePoint.lean | 164 ++++++++++++++++++ Mathlib/CategoryTheory/Elements.lean | 21 +++ Mathlib/CategoryTheory/EssentialImage.lean | 12 +- .../CategoryTheory/Limits/FinallySmall.lean | 11 ++ .../Limits/MorphismProperty.lean | 5 +- .../MorphismProperty/Comma.lean | 2 +- .../MorphismProperty/CommaSites.lean | 2 + .../CategoryTheory/ObjectProperty/Small.lean | 5 + 12 files changed, 302 insertions(+), 7 deletions(-) create mode 100644 Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3093c4df4064be..73d920207c69ad 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1458,6 +1458,7 @@ public import Mathlib.AlgebraicGeometry.Sites.BigZariski public import Mathlib.AlgebraicGeometry.Sites.ConstantSheaf public import Mathlib.AlgebraicGeometry.Sites.ElladicCohomology public import Mathlib.AlgebraicGeometry.Sites.Etale +public import Mathlib.AlgebraicGeometry.Sites.EtalePoint public import Mathlib.AlgebraicGeometry.Sites.Fpqc public import Mathlib.AlgebraicGeometry.Sites.MorphismProperty public import Mathlib.AlgebraicGeometry.Sites.Pretopology diff --git a/Mathlib/AlgebraicGeometry/Fiber.lean b/Mathlib/AlgebraicGeometry/Fiber.lean index bb0a2929f09ea1..186ddc1e9f5700 100644 --- a/Mathlib/AlgebraicGeometry/Fiber.lean +++ b/Mathlib/AlgebraicGeometry/Fiber.lean @@ -47,6 +47,11 @@ def Scheme.Hom.fiberToSpecResidueField (f : X ⟶ Y) (y : Y) : f.fiber y ⟶ Spec (Y.residueField y) := pullback.snd _ _ +@[reassoc] +lemma Scheme.Hom.fiber_fac (f : X ⟶ Y) (y : Y) : + f.fiberι y ≫ f = f.fiberToSpecResidueField y ≫ Y.fromSpecResidueField y := + pullback.condition + /-- The fiber of `f` at `y` is naturally a `κ(y)`-scheme. -/ @[reducible] def Scheme.Hom.fiberOverSpecResidueField (f : X ⟶ Y) (y : Y) : (f.fiber y).Over (Spec (Y.residueField y)) where diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean b/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean index 52bc757775e5a9..0b4f6f16974b8b 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean @@ -149,21 +149,65 @@ namespace Scheme /-- The category `Etale X` is the category of schemes étale over `X`. -/ protected def Etale (X : Scheme.{u}) : Type _ := MorphismProperty.Over @Etale ⊤ X -deriving Category, HasPullbacks +deriving Category, HasPullbacks, HasFiniteLimits variable (X : Scheme.{u}) -instance (Y : X.Etale) : Etale Y.hom := Y.prop +set_option backward.defeqAttrib.useBackward true in +instance (Y : X.Etale) : dsimp% Etale Y.hom := Y.prop + +instance {X : Scheme.{u}} {Z Y : X.Etale} (f : Z ⟶ Y) : Etale f.left := by + have : Etale (f.left ≫ Y.hom) := by rw [CategoryTheory.Over.w]; infer_instance + exact Etale.of_comp f.left Y.hom /-- The forgetful functor from schemes étale over `X` to schemes over `X`. -/ def Etale.forget : X.Etale ⥤ Over X := MorphismProperty.Over.forget @Etale ⊤ X -deriving Functor.Full, Functor.Faithful /-- The forgetful functor from schemes étale over `X` to schemes over `X` is fully faithful. -/ def Etale.forgetFullyFaithful : (Etale.forget X).FullyFaithful := MorphismProperty.Comma.forgetFullyFaithful _ _ _ +-- Note: using `deriving Functor.Full/Faithful` in the declaration of `Etale.forget` +-- would "succeed", but it seems it would fail to create the next two instances +instance : (Etale.forget X).Full := + (Etale.forgetFullyFaithful X).full + +instance : (Etale.forget X).Faithful := + (Etale.forgetFullyFaithful X).faithful + +variable {X} in +/-- Constructor for objects in the étale site of a scheme `X`: it takes +an étale morphism `f : Y ⟶ X` as an input. -/ +abbrev Etale.mk {Y : Scheme.{u}} (f : Y ⟶ X) [Etale f] : X.Etale := + MorphismProperty.Over.mk _ f inferInstance + +variable {X} in +@[simp] +lemma Etale.forget_mk {Y : Scheme.{u}} (f : Y ⟶ X) [Etale f] : + (Etale.forget X).obj (.mk f) = Over.mk f := rfl + +@[simp] +lemma Etale.forget_obj_left (Y : X.Etale) : + ((Etale.forget X).obj Y).left = Y.left := rfl + +@[simp] +lemma Etale.forget_obj_hom (Y : X.Etale) : + ((Etale.forget X).obj Y).hom = Y.hom := rfl + +instance (Y : X.Etale) : Etale (Y.left ↘ X) := Y.prop + +/-- Induction principle for the objects of the small étale site of a scheme. -/ +@[elab_as_elim, cases_eliminator, induction_eliminator] +def Etale.rec {motive : X.Etale → Sort*} + (mk : ∀ (Y : Scheme.{u}) (f : Y ⟶ X) (_ : Etale f), motive (Etale.mk f)) + (T : X.Etale) : + motive T := + mk _ _ T.prop + +instance : PreservesFiniteLimits (Etale.forget X) := + inferInstanceAs (PreservesFiniteLimits (MorphismProperty.Over.forget _ ⊤ X)) + end Scheme end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Sites/Etale.lean b/Mathlib/AlgebraicGeometry/Sites/Etale.lean index b54e73a748fcdd..6bcfcdeea6eb76 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Etale.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Etale.lean @@ -54,6 +54,37 @@ def smallEtaleTopology (X : Scheme.{u}) : GrothendieckTopology X.Etale := def smallEtalePretopology (X : Scheme.{u}) : Pretopology X.Etale := X.smallPretopology (Q := @Etale) (P := @Etale) +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma ofArrows_mem_smallEtaleTopology_iff + {X : Scheme.{u}} {W : X.Etale} {ι : Type*} + {Z : ι → X.Etale} (f : ∀ i, Z i ⟶ W) : + Sieve.ofArrows _ f ∈ smallEtaleTopology _ _ ↔ + ⋃ i, Set.range (f i).left = .univ := by + refine ⟨fun hf ↦ ?_, fun hf ↦ (mem_smallGrothendieckTopology _ _).2 ?_⟩ + · obtain ⟨U, _, _, hU⟩ := (mem_smallGrothendieckTopology _ _).1 hf + ext y + simp only [Set.mem_iUnion, Set.mem_range, Set.mem_univ, iff_true] + obtain ⟨i, ⟨u, rfl⟩⟩ := ((ofArrows_mem_precoverage_iff _).1 U.mem₀).1 y + obtain ⟨_, b, _, ⟨j⟩, fac⟩ := hU _ _ ⟨i⟩ + replace fac : b.left ≫ (f j).left = U.f i := + (Etale.forget _ ⋙ CategoryTheory.Over.forget _).congr_map fac + exact ⟨j, b.left u, by simp [← fac]⟩ + · have (w : W.left) : ∃ (i : ι), w ∈ Set.range (f i).left := by + have := Set.mem_univ w + simpa [← hf] + choose i z hz using this + let V : Cover (precoverage @Etale) W.left := + Cover.mkOfCovers W.left (fun w ↦ (Z (i w)).left) + (fun w ↦ (f (i w)).left) (fun w ↦ ⟨_, _, hz w⟩) inferInstance + letI : Cover.Over X V := + { over w := ⟨(Z (i w)).hom⟩ + isOver_map w := by cat_disch } + have (w : W.left) : Etale (V.X w ↘ X) := (Z (i w)).prop + refine ⟨V, inferInstance, inferInstance, ?_⟩ + rintro _ _ ⟨w⟩ + refine ⟨_, 𝟙 _, _, ⟨i w⟩, by cat_disch⟩ + instance {S : Scheme.{u}} (𝒰 : S.Cover (precoverage @Etale)) (i : 𝒰.I₀) : Etale (𝒰.f i) := 𝒰.map_prop i diff --git a/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean b/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean new file mode 100644 index 00000000000000..46192dcbf7394a --- /dev/null +++ b/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean @@ -0,0 +1,164 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten, Joël Riou +-/ +module + +public import Mathlib.AlgebraicGeometry.Fiber +public import Mathlib.AlgebraicGeometry.Sites.AffineEtale +public import Mathlib.CategoryTheory.Functor.TypeValuedFlat +public import Mathlib.CategoryTheory.Limits.Elements +public import Mathlib.CategoryTheory.Sites.Point.Conservative + +public import Mathlib.FieldTheory.SeparableClosure + +/-! + +# Points of the étale site + +In this file, we show that a morphism `Spec (.of Ω) ⟶ S` where `Ω` is +a separably closed field defines a point on the small étale site of `S`. +We show that these points form a conservative family. + +-/ + +@[expose] public section + +universe u + +open CategoryTheory Opposite + +namespace AlgebraicGeometry.Scheme + +variable {S : Scheme.{u}} {Ω : Type u} [Field Ω] [IsSepClosed Ω] + (s : Spec (.of Ω) ⟶ S) + +lemma exists_fac_of_etale_of_isSepClosed {X S : Scheme.{u}} (f : X ⟶ S) [Etale f] + {Ω : Type u} [Field Ω] [IsSepClosed Ω] (s : Spec (.of Ω) ⟶ S) + (x : X) (hx : f x = s default) : + ∃ (l : Spec (.of Ω) ⟶ X), l ≫ f = s ∧ l default = x := by + obtain ⟨⟨s, a⟩, rfl⟩ := (SpecToEquivOfField Ω S).symm.surjective s + obtain rfl : f x = s := by simp [hx, SpecToEquivOfField] + let m := (f.residueFieldMap x).hom + dsimp at m + algebraize [m, a.hom] + let b : X.residueField x →ₐ[S.residueField (f x)] Ω := + IsSepClosed.lift + have : f.residueFieldMap x ≫ CommRingCat.ofHom b.toRingHom = a := by + ext1; exact b.comp_algebraMap + refine ⟨Spec.map (CommRingCat.ofHom b.toRingHom) ≫ X.fromSpecResidueField x, ?_, ?_⟩ + · simp [SpecToEquivOfField, ← this] + rfl + · dsimp + apply fromSpecResidueField_apply + +instance : IsCofiltered (Etale.forget S ⋙ coyoneda.obj (op (Over.mk s))).Elements := + Functor.isCofiltered_elements _ + +set_option backward.defeqAttrib.useBackward true in +/-- A morphism `s : Spec (.of Ω) ⟶ S` where `Ω` is a separably closed field +defines a point for the small étale site of `S`. -/ +@[simps] +noncomputable def pointSmallEtale : (smallEtaleTopology S).Point where + fiber := Etale.forget S ⋙ coyoneda.obj (op (Over.mk s)) + initiallySmall := + initiallySmall_of_essentiallySmall_weakly_initial_objectProperty + (Functor.Elements.precomp (AffineEtale.Spec S) + (Etale.forget S ⋙ coyoneda.obj (op (Over.mk s)))).essImage (by + rintro ⟨X, x⟩ + cases X with | _ Y f + obtain ⟨y, hy, rfl⟩ := Over.homMk_surjective x + dsimp at y hy + obtain ⟨R, j, _, y', rfl⟩ : ∃ (R : CommRingCat) (j : Spec (.of R) ⟶ Y) + (_ : IsOpenImmersion j) (y' : _ ⟶ _), y' ≫ j = y := by + obtain ⟨R, j, _, hj, _⟩ := exists_affine_mem_range_and_range_subset + (x := y.base default) (U := ⊤) (by simp) + refine ⟨R, j, inferInstance, _, IsOpenImmersion.lift_fac j y ?_⟩ + rintro _ ⟨a, rfl⟩ + rwa [Subsingleton.elim a default] + exact ⟨_, + ⟨Functor.elementsMk _ (AffineEtale.mk (j ≫ f)) (Over.homMk y'), ⟨Iso.refl _⟩⟩, + ⟨⟨MorphismProperty.Over.homMk j rfl (by simp), by cat_disch⟩⟩⟩) + jointly_surjective {X} R hR φ := by + cases X with | _ X f + obtain ⟨φ : Spec (.of Ω) ⟶ X, rfl : φ ≫ f = s, rfl⟩ := Over.homMk_surjective φ + obtain ⟨𝒰, h, _, le⟩ := (mem_smallGrothendieckTopology _ _).1 hR + obtain ⟨i, y, hy⟩ := 𝒰.exists_eq (φ default) + obtain ⟨l, hl₁, hl₂⟩ := exists_fac_of_etale_of_isSepClosed (𝒰.f i) φ _ hy + have : 𝒰.f i ≫ f = 𝒰.X i ↘ S := HomIsOver.comp_over (f := 𝒰.f i) (S := S) + exact ⟨(𝒰.X i).asOverProp S inferInstance, + MorphismProperty.Over.homMk (𝒰.f i), le _ _ ⟨i⟩, Over.homMk l, by cat_disch⟩ + +variable {s₀ : S} (hs₀ : s default = s₀) + +/-- Given a morphism `s : Spec (.of Ω) ⟶ S` with image `s₀ : S` where `Ω` is a +separably closed field, this is the canonical map +`(pointSmallEtale s).fiber.obj X ⟶ X.hom ⁻¹' {s₀}` for `X : S.Etale`. -/ +@[simps] +noncomputable def pointSmallEtaleFiberObjToPreimage {X : S.Etale} + (t : (pointSmallEtale s).fiber.obj X) : + X.hom ⁻¹' {s₀} := + ⟨t.left (default : Spec (.of Ω)), by + have := (Over.w t).symm + cat_disch⟩ + +set_option backward.isDefEq.respectTransparency false in +instance {Y X : Scheme.{u}} (f : Y ⟶ X) [Etale f] (x : X) : + Etale (f.fiberToSpecResidueField x) := by + dsimp [Hom.fiberToSpecResidueField] + infer_instance + +set_option backward.isDefEq.respectTransparency false in +lemma pointSmallEtaleFiberObjToPreimage_surjective (X : S.Etale) : + Function.Surjective (pointSmallEtaleFiberObjToPreimage s hs₀ (X := X)) := by + intro y + obtain ⟨y, rfl⟩ := (X.hom.fiberHomeo s₀).surjective y + obtain ⟨⟨t, a⟩, rfl⟩ := (Scheme.SpecToEquivOfField Ω _).symm.surjective s + obtain rfl : t = s₀ := by simp [SpecToEquivOfField, ← hs₀] + obtain ⟨l, hl, rfl⟩ := exists_fac_of_etale_of_isSepClosed + (X.hom.fiberToSpecResidueField _) (Spec.map a) y (by subsingleton) + refine ⟨Over.homMk (l ≫ X.hom.fiberι t) ?_, rfl⟩ + simp [X.hom.fiber_fac, reassoc_of% hl] + rfl + +set_option backward.isDefEq.respectTransparency false in +lemma isConservative_pointSmallEtale + {ι : Type*} {S : Scheme.{u}} + {Ω : ι → Type u} [∀ i, Field (Ω i)] [∀ i, IsSepClosed (Ω i)] + (s : ∀ i, Spec (.of (Ω i)) ⟶ S) + (hs : ⋃ i, Set.range (s i) = .univ) : + (ObjectProperty.ofObj (fun i ↦ pointSmallEtale (s i))).IsConservativeFamilyOfPoints := + .mk' (fun X R hR ↦ by + obtain ⟨α, T, f, rfl⟩ := R.exists_eq_ofArrows + rw [ofArrows_mem_smallEtaleTopology_iff] + ext x + simp only [Set.mem_iUnion, Set.mem_range, Set.mem_univ, iff_true] + obtain ⟨i, hi⟩ : ∃ i, s i default = X.hom x := by + have := Set.mem_univ (X.hom x) + simp only [← hs, Functor.id_obj, Set.mem_iUnion, Set.mem_range] at this + obtain ⟨i, y, hy⟩ := this + obtain rfl := Subsingleton.elim y default + exact ⟨i, hy⟩ + obtain ⟨x', hx'⟩ := pointSmallEtaleFiberObjToPreimage_surjective (s i) hi X ⟨x, by simp⟩ + rw [Subtype.ext_iff] at hx' + simp only [Functor.id_obj, pointSmallEtaleFiberObjToPreimage_coe, Etale.forget_obj_left] at hx' + subst hx' + obtain ⟨W, g, ⟨Z, p, _, ⟨a⟩, rfl⟩, y, rfl⟩ := hR ⟨_, ⟨i⟩⟩ x' + exact ⟨a, (pointSmallEtaleFiberObjToPreimage (s i) hi (y ≫ p.hom)).1, rfl⟩) + +lemma isConservativeFamilyOfPoints_pointSmallEtale' (S : Scheme.{u}) : + (ObjectProperty.ofObj (fun (s : S) ↦ pointSmallEtale + ((SpecToEquivOfField (SeparableClosure (S.residueField s)) _).2 + ⟨s, CommRingCat.ofHom + (algebraMap (S.residueField s) _)⟩))).IsConservativeFamilyOfPoints := + isConservative_pointSmallEtale _ (by + ext s + simp only [Equiv.invFun_as_coe, Set.mem_iUnion, Set.mem_range, Set.mem_univ, iff_true] + exact ⟨s, default, by simp [SpecToEquivOfField]⟩) + +instance : GrothendieckTopology.HasEnoughPoints.{u} (smallEtaleTopology S) where + exists_objectProperty := + ⟨_, inferInstance, isConservativeFamilyOfPoints_pointSmallEtale' S⟩ + +end AlgebraicGeometry.Scheme diff --git a/Mathlib/CategoryTheory/Elements.lean b/Mathlib/CategoryTheory/Elements.lean index d8f926c0b5c135..2548dd3b2a4c39 100644 --- a/Mathlib/CategoryTheory/Elements.lean +++ b/Mathlib/CategoryTheory/Elements.lean @@ -7,6 +7,7 @@ module public import Mathlib.CategoryTheory.Comma.StructuredArrow.Basic public import Mathlib.CategoryTheory.EssentiallySmall +public import Mathlib.CategoryTheory.ObjectProperty.Small /-! # The category of elements @@ -354,6 +355,26 @@ def Elements.initial (A : C) : (yoneda.obj A).Elements := def Elements.isInitial (A : C) : Limits.IsInitial (Elements.initial A) := isInitialOfRepresentableBy (.yoneda A) +/-- The functor `(F ⋙ G).Elements ⥤ G.Elements`. -/ +@[simps] +def Elements.precomp {D : Type*} [Category D] (F : C ⥤ D) (G : D ⥤ Type w) : + (F ⋙ G).Elements ⥤ G.Elements where + obj x := G.elementsMk (F.obj x.fst) x.snd + map f := ⟨F.map f.1, f.2⟩ + +instance Elements.essentiallySmall {C : Type u} [Category.{v} C] + (F : C ⥤ Type w) [EssentiallySmall.{w} C] : + EssentiallySmall.{w} F.Elements := by + rw [essentiallySmall_iff_objectPropertyEssentiallySmall_top] + obtain ⟨P, _, hP⟩ := ObjectProperty.EssentiallySmall.exists_small_le' (⊤ : ObjectProperty C) + refine ⟨fun x ↦ P x.1, ?_, fun y _ ↦ ?_⟩ + · exact small_of_surjective.{w} (α := Σ (Z : Subtype P), F.obj Z.1) + (f := fun x ↦ ⟨F.elementsMk _ x.2, x.1.2⟩) + (fun ⟨x, hx⟩ ↦ ⟨⟨⟨x.1, hx⟩, x.2⟩, rfl⟩) + · obtain ⟨Z, hZ, ⟨e⟩⟩ := hP y.fst (by simp) + exact ⟨F.elementsMk Z (F.map e.hom y.snd), hZ, + ⟨CategoryOfElements.isoMk _ _ e rfl⟩⟩ + end Functor end CategoryTheory diff --git a/Mathlib/CategoryTheory/EssentialImage.lean b/Mathlib/CategoryTheory/EssentialImage.lean index 2a5f68abd05fcd..03c782c1703628 100644 --- a/Mathlib/CategoryTheory/EssentialImage.lean +++ b/Mathlib/CategoryTheory/EssentialImage.lean @@ -5,10 +5,9 @@ Authors: Bhavik Mehta -/ module -public import Mathlib.CategoryTheory.NatIso public import Mathlib.CategoryTheory.ObjectProperty.ClosedUnderIsomorphisms public import Mathlib.CategoryTheory.ObjectProperty.FullSubcategory -public import Mathlib.Data.Set.Operations +public import Mathlib.Order.BooleanAlgebra.Defs /-! # Essential image of a functor @@ -223,4 +222,13 @@ lemma faithful_of_comp_essSurj (F : D ⥤ E) (L : C ⥤ D) [EssSurj L] end Functor +lemma ObjectProperty.map_top (F : C ⥤ D) : + (⊤ : ObjectProperty C).map F = F.essImage := by + ext Y + refine ⟨?_, ?_⟩ + · rintro ⟨X, _, ⟨e⟩⟩ + exact ⟨X, ⟨e⟩⟩ + · rintro ⟨X, ⟨e⟩⟩ + exact ⟨X, by simp, ⟨e⟩⟩ + end CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/FinallySmall.lean b/Mathlib/CategoryTheory/Limits/FinallySmall.lean index cc3b7f4bcf28d8..e551669d855b26 100644 --- a/Mathlib/CategoryTheory/Limits/FinallySmall.lean +++ b/Mathlib/CategoryTheory/Limits/FinallySmall.lean @@ -212,6 +212,17 @@ theorem initiallySmall_of_small_weakly_initial_set [IsCofilteredOrEmpty J] (s : obtain ⟨j, hj₁, hj₂⟩ := hs i exact ⟨⟨j, hj₁⟩, hj₂⟩ +variable {J} in +theorem initiallySmall_of_essentiallySmall_weakly_initial_objectProperty + [IsCofilteredOrEmpty J] (P : ObjectProperty J) [ObjectProperty.EssentiallySmall.{v} P] + (hP : ∀ i, ∃ j, P j ∧ Nonempty (j ⟶ i)) : InitiallySmall.{v} J := by + obtain ⟨Q, H, hQ⟩ := ObjectProperty.EssentiallySmall.exists_small_le'.{v} P + have : Small.{v} (show Set _ from Q) := by assumption + refine initiallySmall_of_small_weakly_initial_set Q (fun i ↦ ?_) + obtain ⟨j, hj, ⟨f⟩⟩ := hP i + obtain ⟨k, hk, ⟨e⟩⟩ := hQ _ hj + exact ⟨k, hk, ⟨e.inv ≫ f⟩⟩ + theorem initiallySmall_iff_exists_small_weakly_initial_set [IsCofilteredOrEmpty J] : InitiallySmall.{v} J ↔ ∃ (s : Set J) (_ : Small.{v} s), ∀ i, ∃ j ∈ s, Nonempty (j ⟶ i) := by refine ⟨fun _ => InitiallySmall.exists_small_weakly_initial_set _, fun h => ?_⟩ diff --git a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean index 2f52b596250381..469c6f3a5e85bd 100644 --- a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean @@ -296,9 +296,12 @@ instance (priority := 900) hasPullbacks [HasPullbacks T] [P.IsStableUnderComposi [P.IsStableUnderBaseChange] [P.HasOfPostcompProperty P] : HasPullbacks (P.Over ⊤ X) := CostructuredArrow.hasPullbacks _ _ -variable [HasPullbacks T] [P.IsStableUnderComposition] [P.ContainsIdentities] +variable [HasPullbacks T] [P.IsMultiplicative] [P.IsStableUnderBaseChange] [P.HasOfPostcompProperty P] +instance hasFiniteLimits : HasFiniteLimits (P.Over ⊤ X) := + hasFiniteLimits_of_hasTerminal_and_pullbacks + noncomputable instance : CreatesFiniteLimits (Over.forget P ⊤ X) := createsFiniteLimitsOfCreatesTerminalAndPullbacks _ diff --git a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean index f5c14845afd010..8a0d834d4922e1 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean @@ -790,7 +790,7 @@ lemma CostructuredArrow.Hom.ext {A B : P.CostructuredArrow Q F X} {f g : A ⟶ B ext <;> simp [h] variable {P Q F X} in -/-- Construct an morphism in `P.CostructuredArrow Q F X` by giving the isomorphism +/-- Construct an isomorphism in `P.CostructuredArrow Q F X` by giving the isomorphism on the underlying objects of `C`. -/ @[simps] def CostructuredArrow.isoMk {A B : P.CostructuredArrow Q F X} (f : A.left ≅ B.left) (hf : Q f.hom) diff --git a/Mathlib/CategoryTheory/MorphismProperty/CommaSites.lean b/Mathlib/CategoryTheory/MorphismProperty/CommaSites.lean index aa594de4c9e6b3..6a5196bfc86997 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/CommaSites.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/CommaSites.lean @@ -93,6 +93,8 @@ lemma coverPreserving_comap_forget (H : K ≤ P.precoverage) : variable [HasFiniteWidePullbacks C] [P.HasOfPostcompProperty P] [P.IsStableUnderBaseChange] [P.ContainsIdentities] +attribute [local instance] hasFiniteLimits_of_hasTerminal_and_pullbacks + preservesFiniteLimits_of_preservesTerminal_and_pullbacks in lemma isContinuous_comap_forget (H : K ≤ P.precoverage) : (Over.forget P ⊤ S).IsContinuous (Precoverage.comap (Over.forget P ⊤ S ⋙ CategoryTheory.Over.forget S) K).toGrothendieck diff --git a/Mathlib/CategoryTheory/ObjectProperty/Small.lean b/Mathlib/CategoryTheory/ObjectProperty/Small.lean index 5404a7f6c78704..b78a4eb6bc8e70 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Small.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Small.lean @@ -218,6 +218,11 @@ instance (P : ObjectProperty C) [ObjectProperty.EssentiallySmall.{w} P] obtain ⟨Q, _, h₁, h₂⟩ := EssentiallySmall.exists_small_le P exact ⟨Q.strictMap F, inferInstance, (map_monotone h₂ F).trans (by simp)⟩ +instance [EssentiallySmall.{w} C] (F : C ⥤ D) : + ObjectProperty.EssentiallySmall.{w} F.essImage := by + rw [← ObjectProperty.map_top] + infer_instance + instance (P : ObjectProperty C) [LocallySmall.{w} C] [ObjectProperty.EssentiallySmall.{w} P] : EssentiallySmall.{w} P.FullSubcategory := by obtain ⟨Q, _, h₁, h₂⟩ := EssentiallySmall.exists_small_le P From 08af479bddcb3abff52bf57d88b2be1db9c0bcb0 Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Thu, 18 Jun 2026 11:44:43 +0000 Subject: [PATCH 0138/1300] feat(RingTheory): let `B` be a faithfully flat `A`-algebra, then `A` is a local ring if `B` is (#39611) Let `B` be a faithfully flat `A`-algebra, then `A` is a local ring if `B` is. --- Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean b/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean index b043b91f8e57c3..d304770bc068e5 100644 --- a/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean +++ b/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean @@ -154,3 +154,16 @@ lemma PrimeSpectrum.comap_surjective_of_faithfullyFlat : @[deprecated (since := "2025-12-10")] alias PrimeSpectrum.specComap_surjective_of_faithfullyFlat := PrimeSpectrum.comap_surjective_of_faithfullyFlat + +section IsLocalRing + +variable (A B) + +instance Module.FaithfullyFlat.isLocalHom : IsLocalHom (algebraMap A B) := + IsLocalHom.of_comap_surjective (algebraMap A B) PrimeSpectrum.comap_surjective_of_faithfullyFlat + +/-- Let `B` be a faithfully flat `A`-algebra, then `A` is a local ring if `B` is. -/ +theorem Module.FaithfullyFlat.isLocalRing [IsLocalRing B] : IsLocalRing A := + (algebraMap A B).domain_isLocalRing + +end IsLocalRing From 63b065c2a061e7286444690d8c427f79cd6d5b6d Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:44:45 +0000 Subject: [PATCH 0139/1300] feat(NumberTheory/RamificationInertia/Galois): ramification inertia refactor (#40126) This is a first pass at refactoring `NumberTheory/RamificationInertia/Galois` to use the new definitions `ramificationIdx'` and `inertiaDeg'`. I tried to keep changes to downstream files minimal to keep this PR on the smaller side. More will be done in future PRs. Co-authored-by: tb65536 --- .../NumberTheory/NumberField/ClassNumber.lean | 19 +- .../NumberField/Cyclotomic/Galois.lean | 5 +- .../NumberField/Cyclotomic/Ideal.lean | 55 +++--- .../NumberField/ExistsRamified.lean | 8 +- .../RamificationInertia/Galois.lean | 179 ++++++++---------- .../RamificationInertia/HilbertTheory.lean | 27 +-- Mathlib/RingTheory/Ideal/GoingUp.lean | 6 +- Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 8 +- 8 files changed, 149 insertions(+), 158 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/ClassNumber.lean b/Mathlib/NumberTheory/NumberField/ClassNumber.lean index b95c4f81116f64..488c642d93a9bf 100644 --- a/Mathlib/NumberTheory/NumberField/ClassNumber.lean +++ b/Mathlib/NumberTheory/NumberField/ClassNumber.lean @@ -143,7 +143,7 @@ The way this theorem should be used is to first compute `⌊(M K)⌋₊` and the to deal with the finite number of primes `p` in the interval. -/ theorem isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_Icc (h : ∀ p ∈ Finset.Icc 1 ⌊(M K)⌋₊, p.Prime → ∀ (P : Ideal (𝓞 K)), - P ∈ primesOver (span {(p : ℤ)}) (𝓞 K) → p ^ ((span ({↑p} : Set ℤ)).inertiaDeg P) ≤ ⌊(M K)⌋₊ → + P ∈ primesOver (span {(p : ℤ)}) (𝓞 K) → p ^ P.inertiaDeg' ℤ ≤ ⌊(M K)⌋₊ → Submodule.IsPrincipal P) : IsPrincipalIdealRing (𝓞 K) := by refine isPrincipalIdealRing_of_isPrincipal_of_norm_le_of_isPrime <| fun ⟨P, HP⟩ hP hPN ↦ ?_ @@ -157,16 +157,19 @@ theorem isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_I simpa [h, span_singleton_neg p, ← submodule_span_eq, ← hp] using over_under P have hspan : span {↑p.natAbs} = span {p} := by rcases abs_choice p with h | h <;> simp [h] - have hple : p.natAbs ^ (span {(p.natAbs : ℤ)}).inertiaDeg P ≤ ⌊(M K)⌋₊ := by + have hple : p.natAbs ^ P.inertiaDeg' ℤ ≤ ⌊(M K)⌋₊ := by refine le_floor ?_ - simpa only [hspan, ← cast_pow, ← absNorm_eq_pow_inertiaDeg P (hpprime (hP.under _))] using hPN + have : P.IsMaximal := hP.isMaximal (by simpa using HP.2) + have : (span {p}).IsMaximal := (hpprime (.under ℤ P)).isMaximal_span_singleton + simpa only [hspan, ← cast_pow, absNorm_eq_pow_inertiaDeg P (hpprime (hP.under _)), + inertiaDeg_eq_inertiaDeg'] using hPN have hpabsprime := Int.prime_iff_natAbs_prime.mp (hpprime (hP.under _)) refine h _ ?_ hpabsprime _ ⟨hP, ?_⟩ hple - · suffices 0 < (span {(p.natAbs : ℤ)}).inertiaDeg P by + · suffices 0 < P.inertiaDeg' ℤ by exact Finset.mem_Icc.mpr ⟨hpabsprime.one_le, le_trans (le_pow this) hple⟩ have := (isPrime_of_prime (prime_span_singleton_iff.mpr <| hpprime (hP.under _))).isMaximal <| by simp [((hpprime (hP.under _))).ne_zero] - exact hspan ▸ inertiaDeg_pos .. + exact inertiaDeg'_pos .. · exact hspan ▸ hlies /-- Let `K` be a number field such that `K/ℚ` is Galois and let `M K` be the Minkowski bound of `K`. @@ -181,7 +184,7 @@ to deal with the finite number of primes `p` in the interval. -/ theorem isPrincipalIdealRing_of_isPrincipal_of_lt_or_isPrincipal_of_mem_primesOver_of_mem_Icc [IsGalois ℚ K] (h : ∀ p ∈ Finset.Icc 1 ⌊(M K)⌋₊, p.Prime → ∃ P ∈ primesOver (span {(p : ℤ)}) (𝓞 K), - ⌊(M K)⌋₊ < p ^ ((span ({↑p} : Set ℤ)).inertiaDeg P) ∨ + ⌊(M K)⌋₊ < p ^ P.inertiaDeg' ℤ ∨ Submodule.IsPrincipal P) : IsPrincipalIdealRing (𝓞 K) := by refine isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_Icc @@ -189,9 +192,9 @@ theorem isPrincipalIdealRing_of_isPrincipal_of_lt_or_isPrincipal_of_mem_primesOv obtain ⟨Q, ⟨hQ1, hQ2⟩, H⟩ := h p hpmem hp have := (isPrime_of_prime (prime_span_singleton_iff.mpr (prime_iff_prime_int.mp hp))).isMaximal (by simp [hp.ne_zero]) - by_cases h : ⌊(M K)⌋₊ < p ^ ((span ({↑p} : Set ℤ)).inertiaDeg P) + by_cases h : ⌊(M K)⌋₊ < p ^ P.inertiaDeg' ℤ · linarith - rw [inertiaDeg_eq_of_isGaloisGroup _ Q P (K ≃ₐ[ℚ] K)] at H + rw [inertiaDeg_eq_of_isGaloisGroup (span {↑p}) Q P (K ≃ₐ[ℚ] K)] at H obtain ⟨σ, rfl⟩ := exists_smul_eq_of_isGaloisGroup (span ({↑p} : Set ℤ)) Q P (K ≃ₐ[ℚ] K) exact (H.resolve_left h).map_ringHom (MulSemiringAction.toRingHom (K ≃ₐ[ℚ] K) (𝓞 K) σ) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean index 61777a3e550dca..a83cce9bee0610 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean @@ -146,10 +146,9 @@ theorem galEquivZMod_stabilizer : rw [Fintype.card_eq_nat_card, Fintype.card_eq_nat_card, SetLike.coe_sort_coe, Nat.card_zpowers, MulEquiv.mapSubgroup_apply, Subgroup.coe_map] change _ ≤ Nat.card ((galEquivZMod n K).toEquiv '' _) - rw [Nat.card_image_equiv, SetLike.coe_sort_coe, Ideal.card_stabilizer_eq (span {(p : ℤ)}) - (by simp [hp.out.ne_zero]), inertiaDegIn_eq_of_not_dvd p K hn, + rw [Nat.card_image_equiv, SetLike.coe_sort_coe, Ideal.card_stabilizer_eq (span {(p : ℤ)}), ramificationIdxIn_eq_of_not_dvd p K hn, one_mul, ← orderOf_injective _ Units.coeHom_injective, - Units.coeHom_apply, ZMod.coe_unitOfCoprime] + Units.coeHom_apply, ZMod.coe_unitOfCoprime, inertiaDegIn_eq_of_not_dvd p K hn] end stabilizer diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 6a23ec72c2d291..e8061a821c8f55 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -89,8 +89,9 @@ instance liesOver_span_zeta_sub_one : (span {hζ.toInteger - 1}).LiesOver 𝒑 : rw [span_singleton_le_iff_mem, mem_comap, algebraMap_int_eq, map_natCast] exact p_mem_span_zeta_sub_one p k hζ -theorem inertiaDeg_span_zeta_sub_one : inertiaDeg 𝒑 (span {hζ.toInteger - 1}) = 1 := by - have := liesOver_span_zeta_sub_one p k hζ +theorem inertiaDeg_span_zeta_sub_one : inertiaDeg' (span {hζ.toInteger - 1}) ℤ = 1 := by + have : IsMaximal (span {hζ.toInteger - 1}) := .of_liesOver_isMaximal _ 𝒑 + rw [← inertiaDeg_eq_inertiaDeg' 𝒑] rw [← Nat.pow_right_inj hp.out.one_lt, pow_one, ← absNorm_eq_pow_inertiaDeg' _ hp.out, absNorm_span_zeta_sub_one] @@ -114,12 +115,14 @@ theorem map_eq_span_zeta_sub_one_pow : ← Nat.card_eq_fintype_card, IsGalois.card_aut_eq_finrank] theorem ramificationIdx_span_zeta_sub_one : - ramificationIdx 𝒑 (span {hζ.toInteger - 1}) = p ^ k * (p - 1) := by + ramificationIdx' (span {hζ.toInteger - 1}) ℤ = p ^ k * (p - 1) := by have h := isPrime_span_zeta_sub_one p k hζ - rw [← Nat.totient_prime_pow_succ hp.out, ← finrank _ K, + have hp0 : 𝒑 ≠ ⊥ := by simpa using hp.out.ne_zero + rw [← ramificationIdx_eq_ramificationIdx' 𝒑 _ hp0, + ← Nat.totient_prime_pow_succ hp.out, ← finrank _ K, IsDedekindDomain.ramificationIdx_eq_multiplicity _ h, map_eq_span_zeta_sub_one_pow p k hζ, multiplicity_pow_self (span_zeta_sub_one_ne_bot p k hζ) (isUnit_iff.not.mpr h.ne_top)] - exact map_ne_bot_of_ne_bot <| by simpa using hp.out.ne_zero + exact map_ne_bot_of_ne_bot hp0 variable (K) @@ -127,8 +130,7 @@ include hK in theorem ncard_primesOver_of_prime_pow : (primesOver 𝒑 (𝓞 K)).ncard = 1 := by have : IsGalois ℚ K := isGalois {p ^ (k + 1)} ℚ K - have : 𝒑 ≠ ⊥ := by simpa using hp.out.ne_zero - have h_main := ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn this (𝓞 K) Gal(K/ℚ) + have h_main := ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 K) Gal(K/ℚ) have hζ := hK.zeta_spec have := liesOver_span_zeta_sub_one p k hζ rwa [ramificationIdxIn_eq_ramificationIdx 𝒑 (span {hζ.toInteger - 1}) Gal(K/ℚ), @@ -148,12 +150,12 @@ theorem eq_span_zeta_sub_one_of_liesOver (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime include hK in theorem inertiaDeg_eq_of_prime_pow (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - inertiaDeg 𝒑 P = 1 := by + inertiaDeg' P ℤ = 1 := by rw [eq_span_zeta_sub_one_of_liesOver p k K hK.zeta_spec P, inertiaDeg_span_zeta_sub_one] include hK in theorem ramificationIdx_eq_of_prime_pow (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - ramificationIdx 𝒑 P = p ^ k * (p - 1) := by + ramificationIdx' P ℤ = p ^ k * (p - 1) := by rw [eq_span_zeta_sub_one_of_liesOver p k K hK.zeta_spec P, ramificationIdx_span_zeta_sub_one] include hK in @@ -180,12 +182,12 @@ instance isPrime_span_zeta_sub_one' : IsPrime (span {hζ.toInteger - 1}) := by rw [← pow_one p] at hK hζ exact isPrime_span_zeta_sub_one p 0 hζ -theorem inertiaDeg_span_zeta_sub_one' : inertiaDeg 𝒑 (span {hζ.toInteger - 1}) = 1 := by +theorem inertiaDeg_span_zeta_sub_one' : inertiaDeg' (span {hζ.toInteger - 1}) ℤ = 1 := by rw [← pow_one p] at hK hζ exact inertiaDeg_span_zeta_sub_one p 0 hζ theorem ramificationIdx_span_zeta_sub_one' : - ramificationIdx 𝒑 (span {hζ.toInteger - 1}) = p - 1 := by + ramificationIdx' (span {hζ.toInteger - 1}) ℤ = p - 1 := by rw [← pow_one p] at hK hζ rw [ramificationIdx_span_zeta_sub_one p 0 hζ, pow_zero, one_mul] @@ -204,12 +206,12 @@ theorem eq_span_zeta_sub_one_of_liesOver' (P : Ideal (𝓞 K)) [hP₁ : P.IsPrim include hK in theorem inertiaDeg_eq_of_prime (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - inertiaDeg 𝒑 P = 1 := by + inertiaDeg' P ℤ = 1 := by rw [eq_span_zeta_sub_one_of_liesOver' p K hK.zeta_spec P, inertiaDeg_span_zeta_sub_one'] include hK in theorem ramificationIdx_eq_of_prime (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - ramificationIdx 𝒑 P = p - 1 := by + ramificationIdx' P ℤ = p - 1 := by rw [eq_span_zeta_sub_one_of_liesOver' p K hK.zeta_spec P, ramificationIdx_span_zeta_sub_one'] include hK in @@ -236,7 +238,7 @@ open NumberField.Ideal Polynomial variable {m} [NeZero m] [hK : IsCyclotomicExtension {m} ℚ K] theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : - inertiaDeg 𝒑 P = orderOf (p : ZMod m) := by + inertiaDeg' P ℤ = orderOf (p : ZMod m) := by replace hm : p.Coprime m := hp.out.coprime_iff_not_dvd.mpr hm let ζ := (zeta_spec m ℚ K).toInteger have h₁ : ¬ p ∣ exponent ζ := by @@ -247,6 +249,8 @@ theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : simp only [Subtype.coe_eta, Equiv.symm_apply_apply] at h₃ rw [Multiset.mem_toFinset, Polynomial.mem_normalizedFactors_iff (map_monic_ne_zero (minpoly.monic ζ.isIntegral))] at h₂ + have : P.IsMaximal := .of_liesOver_isMaximal P 𝒑 + rw [← inertiaDeg_eq_inertiaDeg' 𝒑] rw [h₃, natDegree_of_dvd_cyclotomic_of_irreducible (by simp) hm (f := 1) _ h₂.1] · simpa using (orderOf_injective _ Units.coeHom_injective (ZMod.unitOfCoprime p hm)).symm · refine dvd_trans h₂.2.2 ?_ @@ -258,7 +262,7 @@ theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : alias inertiaDeg_of_not_dvd := inertiaDeg_eq_of_not_dvd theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : - ramificationIdx 𝒑 P = 1 := by + ramificationIdx' P ℤ = 1 := by let ζ := (zeta_spec m ℚ K).toInteger have h₁ : ¬ p ∣ exponent ζ := by rw [exponent_eq_one_iff.mpr <| adjoin_singleton_eq_top (zeta_spec m ℚ K)] @@ -268,7 +272,7 @@ theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : simp only [Subtype.coe_eta, Equiv.symm_apply_apply] at h₃ rw [Multiset.mem_toFinset, Polynomial.mem_normalizedFactors_iff (map_monic_ne_zero (minpoly.monic ζ.isIntegral))] at h₂ - rw [h₃] + rw [← ramificationIdx_eq_ramificationIdx' 𝒑 P (by simpa using hp.out.ne_zero), h₃] refine multiplicity_eq_of_emultiplicity_eq_some (le_antisymm ?_ ?_) · apply emultiplicity_le_one_of_separable · exact isUnit_iff_degree_eq_zero.not.mpr (Irreducible.degree_pos h₂.1).ne' @@ -309,7 +313,6 @@ private theorem inertiaDegIn_ramificationIdxIn_aux (hn : n = p ^ (k + 1) * m) (h have : IsAbelianGalois ℚ K := IsCyclotomicExtension.isAbelianGalois {n} ℚ K have : NeZero m := ⟨fun h ↦ by simp [h] at hm⟩ have : NeZero n := ⟨hn ▸ NeZero.ne (p ^ (k + 1) * m)⟩ - have hp' : 𝒑 ≠ ⊥ := by simpa using hp.out.ne_zero let ζ := zeta n ℚ K have hζ := zeta_spec n ℚ K -- We construct `ℚ⟮ζₘ⟯ ⊆ ℚ⟮ζₙ⟯` @@ -332,7 +335,7 @@ private theorem inertiaDegIn_ramificationIdxIn_aux (hn : n = p ^ (k + 1) * m) (h Pₘ.inertiaDegIn (𝓞 K) * (Pₘ.primesOver (𝓞 K)).ncard = 1 by replace this := Nat.eq_one_of_mul_eq_one_right this rw [← inertiaDegIn_mul_inertiaDegIn 𝒑 Pₘ Gal(Fₘ/ℚ) _ Gal(K/ℚ) Gal(K/Fₘ), - ← ramificationIdxIn_mul_ramificationIdxIn' Pₚ Gal(Fₚ/ℚ) _ Gal(K/ℚ) Gal(K/Fₚ), + ← ramificationIdxIn_mul_ramificationIdxIn Pₚ Gal(Fₚ/ℚ) _ Gal(K/ℚ) Gal(K/Fₚ), Nat.eq_one_of_mul_eq_one_left this, Nat.eq_one_of_mul_eq_one_right this, mul_one, mul_one, inertiaDegIn_eq_of_not_dvd p _ hm, ramificationIdxIn_eq_of_prime_pow p k Fₚ] exact ⟨rfl, rfl⟩ @@ -341,18 +344,18 @@ private theorem inertiaDegIn_ramificationIdxIn_aux (hn : n = p ^ (k + 1) * m) (h exact Nat.Coprime.pow_left (k + 1) (by rwa [hp.out.coprime_iff_not_dvd]) rwa [← IsGalois.card_aut_eq_finrank, ← IsGalois.card_aut_eq_finrank, ← IsGalois.card_aut_eq_finrank, - ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp' (𝓞 Fₘ) Gal(Fₘ/ℚ), - ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp' (𝓞 Fₚ) Gal(Fₚ/ℚ), - ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp' (𝓞 K) Gal(K/ℚ), - ← ncard_primesOver_mul_ncard_primesOver Pₘ Gal(Fₘ/ℚ) (𝓞 K) Gal(K/ℚ) Gal(K/Fₘ) hp', + ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 Fₘ) Gal(Fₘ/ℚ), + ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 Fₚ) Gal(Fₚ/ℚ), + ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 K) Gal(K/ℚ), + ← ncard_primesOver_mul_ncard_primesOver Pₘ Gal(Fₘ/ℚ) (𝓞 K) Gal(K/ℚ) Gal(K/Fₘ), ramificationIdxIn_eq_of_not_dvd p Fₘ hm, inertiaDegIn_eq_of_prime_pow p k Fₚ, ncard_primesOver_of_prime_pow p k Fₚ, one_mul, one_mul, mul_one, mul_assoc, mul_assoc, mul_right_inj' (IsDedekindDomain.primesOver_ncard_ne_zero 𝒑 _), ← mul_assoc, ← mul_rotate (𝒑.inertiaDegIn (𝓞 K)), ← inertiaDegIn_mul_inertiaDegIn 𝒑 Pₘ Gal(Fₘ/ℚ) (𝓞 K) Gal(K/ℚ) Gal(K/Fₘ), mul_assoc, mul_assoc, mul_right_inj' (inertiaDegIn_ne_zero Gal(Fₘ/ℚ)), ← mul_rotate', - ← ramificationIdxIn_mul_ramificationIdxIn' (p := 𝒑) Pₚ Gal(Fₚ/ℚ) (𝓞 K) Gal(K/ℚ) Gal(K/Fₚ), - eq_comm, mul_assoc, mul_eq_left₀ (ramificationIdxIn_ne_zero Gal(Fₚ/ℚ) hp'), ← mul_assoc] + ← ramificationIdxIn_mul_ramificationIdxIn (p := 𝒑) Pₚ Gal(Fₚ/ℚ) (𝓞 K) Gal(K/ℚ) Gal(K/Fₚ), + eq_comm, mul_assoc, mul_eq_left₀ (ramificationIdxIn_ne_zero Gal(Fₚ/ℚ)), ← mul_assoc] at h_main /-- @@ -372,12 +375,12 @@ theorem ramificationIdxIn_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : (inertiaDegIn_ramificationIdxIn_aux n K hn hm).2 theorem inertiaDeg_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : - inertiaDeg 𝒑 P = orderOf (p : ZMod m) := by + inertiaDeg' P ℤ = orderOf (p : ZMod m) := by have : IsGalois ℚ K := isGalois {n} ℚ K rw [← inertiaDegIn_eq_inertiaDeg 𝒑 P Gal(K/ℚ), inertiaDegIn_eq n K hn hm] theorem ramificationIdx_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : - ramificationIdx 𝒑 P = p ^ k * (p - 1) := by + ramificationIdx' P ℤ = p ^ k * (p - 1) := by have : IsGalois ℚ K := isGalois {n} ℚ K rw [← ramificationIdxIn_eq_ramificationIdx 𝒑 P Gal(K/ℚ), ramificationIdxIn_eq n K hn hm] diff --git a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean index 1856156665d1d5..f1c8f469117601 100644 --- a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean +++ b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean @@ -8,6 +8,7 @@ module public import Mathlib.NumberTheory.NumberField.Discriminant.Basic public import Mathlib.NumberTheory.NumberField.Discriminant.Different public import Mathlib.NumberTheory.RamificationInertia.Galois +public import Mathlib.RingTheory.Ideal.Quotient.HasFiniteQuotients public import Mathlib.RingTheory.Unramified.Dedekind /-! @@ -83,7 +84,6 @@ lemma NumberField.exists_not_isUnramifiedAt_int_of_isGalois [IsGalois ℚ K] (map_dvd (algebraMap _ _) p.associated_natAbs.symm.dvd) (by simpa using hQ) have : .span {p} = Ideal.under ℤ Q := ((Ideal.liesOver_span_iff Ideal.IsPrime.ne_top' this).mpr hQ).1 - rwa [Algebra.isUnramifiedAt_iff_of_isDedekindDomain (by aesop), - ← Ideal.ramificationIdxIn_eq_ramificationIdx _ _ Gal(K/ℚ), ← this, ← hp, - Ideal.ramificationIdxIn_eq_ramificationIdx _ P Gal(K/ℚ), - ← Algebra.isUnramifiedAt_iff_of_isDedekindDomain (Ideal.IsMaximal.ne_bot_of_isIntegral_int _)] + rwa [← Ideal.ramificationIdx'_eq_one_iff, + ← Ideal.ramificationIdxIn_eq_ramificationIdx (Q.under ℤ) _ Gal(K/ℚ), ← this, ← hp, + Ideal.ramificationIdxIn_eq_ramificationIdx _ P Gal(K/ℚ), Ideal.ramificationIdx'_eq_one_iff] diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index cfeb2838861a4d..b0f32f53494438 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -5,8 +5,7 @@ Authors: Yongle Hu, Jiedong Jiang -/ module -public import Mathlib.FieldTheory.Galois.IsGaloisGroup -public import Mathlib.NumberTheory.RamificationInertia.Basic +public import Mathlib.RingTheory.RamificationInertia.Basic /-! # Ramification theory in Galois extensions of Dedekind domains @@ -58,7 +57,7 @@ open scoped Classical in maximal ideal `p` of `A` are the same, which we define as `Ideal.ramificationIdxIn`. -/ noncomputable def ramificationIdxIn {A : Type*} [CommRing A] (p : Ideal A) (B : Type*) [CommRing B] [Algebra A B] : ℕ := - if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then p.ramificationIdx h.choose + if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then h.choose.ramificationIdx' A else 0 open scoped Classical in @@ -67,7 +66,7 @@ open scoped Classical in maximal ideal `p` of `A` are the same, which we define as `Ideal.inertiaDegIn`. -/ noncomputable def inertiaDegIn {A : Type*} [CommRing A] (p : Ideal A) (B : Type*) [CommRing B] [Algebra A B] : ℕ := - if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then p.inertiaDeg h.choose else 0 + if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then h.choose.inertiaDeg' A else 0 section MulAction @@ -135,92 +134,78 @@ instance isPretransitive_of_isGaloisGroup : MulAction.IsPretransitive G (primesO rcases exists_smul_eq_of_isGaloisGroup p P Q G with ⟨σ, hs⟩ exact ⟨σ, Subtype.val_inj.mp hs⟩ -include G in +include p G in /-- All the `Ideal.ramificationIdx` over a fixed maximal ideal are the same. -/ theorem ramificationIdx_eq_of_isGaloisGroup : - ramificationIdx p P = ramificationIdx p Q := by + P.ramificationIdx' A = Q.ramificationIdx' A := by rcases exists_smul_eq_of_isGaloisGroup p P Q G with ⟨σ, rfl⟩ - exact (ramificationIdx_map_eq p P (MulSemiringAction.toAlgEquiv A B σ)).symm + rw [ramificationIdx'_smul] -include G in +include p G in /-- All the `Ideal.inertiaDeg` over a fixed maximal ideal are the same. -/ theorem inertiaDeg_eq_of_isGaloisGroup : - inertiaDeg p P = inertiaDeg p Q := by + P.inertiaDeg' A = Q.inertiaDeg' A := by rcases exists_smul_eq_of_isGaloisGroup p P Q G with ⟨σ, rfl⟩ - exact (inertiaDeg_map_eq p P (MulSemiringAction.toAlgEquiv A B σ)).symm + rw [inertiaDeg'_smul] -include G in +include p G in /-- The `ramificationIdxIn` is equal to any ramification index over the same ideal. -/ theorem ramificationIdxIn_eq_ramificationIdx : - ramificationIdxIn p B = ramificationIdx p P := by + ramificationIdxIn p B = P.ramificationIdx' A := by have h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p := ⟨P, hPp, hp⟩ obtain ⟨_, _⟩ := h.choose_spec rw [ramificationIdxIn, dif_pos h] exact ramificationIdx_eq_of_isGaloisGroup p h.choose P G include G in -theorem ramificationIdxIn_ne_zero [IsDedekindDomain B] {p : Ideal A} [p.IsPrime] (hp : p ≠ ⊥) - [IsDomain A] [IsTorsionFree A B] : p.ramificationIdxIn B ≠ 0 := by - have : Algebra.IsIntegral A B := IsGaloisGroup.isInvariant.isIntegral A B G +theorem ramificationIdxIn_ne_zero [Module.Finite A B] [FaithfulSMul A B] {p : Ideal A} [p.IsPrime] : + p.ramificationIdxIn B ≠ 0 := by obtain ⟨P⟩ := (inferInstance : Nonempty (primesOver p B)) rw [ramificationIdxIn_eq_ramificationIdx p P G] - exact IsDedekindDomain.ramificationIdx_ne_zero_of_liesOver P.1 hp + exact (P.1.ramificationIdx'_pos A).ne' include G in /-- The `inertiaDegIn` is equal to any ramification index over the same ideal. -/ theorem inertiaDegIn_eq_inertiaDeg : - inertiaDegIn p B = inertiaDeg p P := by + inertiaDegIn p B = P.inertiaDeg' A := by have h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p := ⟨P, hPp, hp⟩ obtain ⟨_, _⟩ := h.choose_spec rw [inertiaDegIn, dif_pos h] exact inertiaDeg_eq_of_isGaloisGroup p h.choose P G include G in -theorem inertiaDegIn_ne_zero {p : Ideal A} [p.IsMaximal] [IsDomain A] [IsTorsionFree A B] - [Module.Finite A B] [Nontrivial B] : +theorem inertiaDegIn_ne_zero [Module.Finite A B] [FaithfulSMul A B] {p : Ideal A} [p.IsPrime] : inertiaDegIn p B ≠ 0 := by obtain ⟨P⟩ := (inferInstance : Nonempty (primesOver p B)) rw [inertiaDegIn_eq_inertiaDeg p P G] - exact inertiaDeg_ne_zero _ _ + exact (P.1.inertiaDeg'_pos A).ne' section tower -variable (C : Type*) [CommRing C] [IsDomain C] [Algebra A C] [Algebra B C] [Module.Finite B C] - [IsDomain B] [IsTorsionFree B C] [IsScalarTower A B C] +variable (C : Type*) [CommRing C] [Algebra A C] [Algebra B C] + [Nonempty (P.primesOver C)] [IsScalarTower A B C] (GAC : Type*) [Group GAC] [Finite GAC] [MulSemiringAction GAC C] [IsGaloisGroup GAC A C] (GBC : Type*) [Group GBC] [Finite GBC] [MulSemiringAction GBC C] [IsGaloisGroup GBC B C] include G GAC GBC in -theorem inertiaDegIn_mul_inertiaDegIn [p.IsMaximal] [P.IsMaximal] : +theorem inertiaDegIn_mul_inertiaDegIn : p.inertiaDegIn B * P.inertiaDegIn C = p.inertiaDegIn C := by - obtain ⟨⟨Q, _, _⟩⟩ := P.nonempty_primesOver (S := C) + obtain ⟨⟨Q, _, _⟩⟩ := (inferInstance : Nonempty (primesOver P C)) have : Q.LiesOver p := LiesOver.trans Q P p rw [inertiaDegIn_eq_inertiaDeg p P G, inertiaDegIn_eq_inertiaDeg p Q GAC, - inertiaDegIn_eq_inertiaDeg P Q GBC, inertiaDeg_algebra_tower p P Q] - -set_option linter.overlappingInstances false + inertiaDegIn_eq_inertiaDeg P Q GBC, ← inertiaDeg'_tower P Q] variable {p} in include G GAC GBC in -theorem ramificationIdxIn_mul_ramificationIdxIn [IsDedekindDomain B] [IsDedekindDomain C] - (hp : map (algebraMap A C) p ≠ ⊥) (hP : map (algebraMap B C) P ≠ ⊥) : +theorem ramificationIdxIn_mul_ramificationIdxIn [Flat B C] : p.ramificationIdxIn B * P.ramificationIdxIn C = p.ramificationIdxIn C := by - obtain ⟨⟨Q, _, hQ⟩⟩ := P.nonempty_primesOver (S := C) + obtain ⟨⟨Q, _, hQ⟩⟩ := (inferInstance : Nonempty (primesOver P C)) have : Q.LiesOver p := LiesOver.trans Q P p rw [ramificationIdxIn_eq_ramificationIdx p P G, ramificationIdxIn_eq_ramificationIdx p Q GAC, - ramificationIdxIn_eq_ramificationIdx P Q GBC, ramificationIdx_algebra_tower hP hp] - exact over_def Q P ▸ map_comap_le + ramificationIdxIn_eq_ramificationIdx P Q GBC, ← ramificationIdx'_tower P Q] -variable {p} in -omit hp in -include G GAC GBC in -theorem ramificationIdxIn_mul_ramificationIdxIn' [IsDomain A] [IsTorsionFree A B] - [IsDedekindDomain B] [IsDedekindDomain C] [P.LiesOver p] : - p.ramificationIdxIn B * P.ramificationIdxIn C = p.ramificationIdxIn C := by - obtain ⟨⟨Q, _, hQ⟩⟩ := P.nonempty_primesOver (S := C) - have : Q.LiesOver p := LiesOver.trans Q P p - rw [ramificationIdxIn_eq_ramificationIdx p P G, ramificationIdxIn_eq_ramificationIdx p Q GAC, - ramificationIdxIn_eq_ramificationIdx P Q GBC, ramificationIdx_algebra_tower' p P Q] +@[deprecated (since := "2026-06-18")] alias ramificationIdxIn_mul_ramificationIdxIn' := + ramificationIdxIn_mul_ramificationIdxIn end tower @@ -228,59 +213,52 @@ end RamificationInertia section fundamental_identity -variable {A : Type*} [CommRing A] [IsDedekindDomain A] {p : Ideal A} (hpb : p ≠ ⊥) [p.IsMaximal] - (B : Type*) [CommRing B] [IsDedekindDomain B] [Algebra A B] [Module.Finite A B] - [IsTorsionFree A B] +variable {A : Type*} [CommRing A] [IsDomain A] (p : Ideal A) [p.IsPrime] + (B : Type*) [CommRing B] [IsDomain B] [Algebra A B] [Module.Finite A B] [Flat A B] (G : Type*) [Group G] [Finite G] [MulSemiringAction G B] [IsGaloisGroup G A B] -include hpb in /-- The form of the **fundamental identity** in the case of Galois extension. -/ theorem ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn : (primesOver p B).ncard * (ramificationIdxIn p B * inertiaDegIn p B) = Nat.card G := by - let K := FractionRing A - let L := FractionRing B - let := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) - rw [← smul_eq_mul, ← IsDedekindDomain.coe_primesOverFinset hpb B, Set.ncard_coe_finset, - ← Finset.sum_const] - rw [(IsGaloisGroup.toFractionRing G A B).card_eq_finrank, ← sum_ramification_inertia B K L hpb] + have : Fintype (primesOver p B) := (QuasiFinite.finite_primesOver p).fintype + rw [← smul_eq_mul, ← Set.fintypeCard_eq_ncard, ← Finset.card_univ, ← Finset.sum_const, + ← sum_ramification_inertia_eq_card p B] apply Finset.sum_congr rfl intro P hp - rw [← Finset.mem_coe, IsDedekindDomain.coe_primesOverFinset hpb B] at hp - obtain ⟨_, _⟩ := hp rw [ramificationIdxIn_eq_ramificationIdx p P G, inertiaDegIn_eq_inertiaDeg p P G] end fundamental_identity section tower -variable {A B : Type*} [CommRing A] [IsDedekindDomain A] [CommRing B] [IsDedekindDomain B] - [Algebra A B] [IsTorsionFree A B] {p : Ideal A} (P : Ideal B) [p.IsMaximal] - [P.IsMaximal] [P.LiesOver p] (G : Type*) [Group G] [Finite G] [MulSemiringAction G B] - [IsGaloisGroup G A B] (C : Type*) [CommRing C] [IsDedekindDomain C] [Algebra A C] [Algebra B C] - [Module.Finite A B] [Module.Finite A C] [Module.Finite B C] [IsTorsionFree A C] - [IsTorsionFree B C] [IsScalarTower A B C] +variable {A B : Type*} [CommRing A] [IsDomain A] [CommRing B] [IsDomain B] + [Algebra A B] [Flat A B] {p : Ideal A} (P : Ideal B) [p.IsPrime] + [P.IsPrime] [P.LiesOver p] (G : Type*) [Group G] [Finite G] [MulSemiringAction G B] + [IsGaloisGroup G A B] (C : Type*) [CommRing C] [IsDomain C] [Algebra A C] + [Algebra B C] [Module.Finite A B] [Module.Finite A C] [Module.Finite B C] [Flat A C] + [Flat B C] [IsScalarTower A B C] (GAC : Type*) [Group GAC] [Finite GAC] [MulSemiringAction GAC C] [IsGaloisGroup GAC A C] (GBC : Type*) [Group GBC] [Finite GBC] [MulSemiringAction GBC C] [IsGaloisGroup GBC B C] +-- todo: use transitivity to prove this under much weaker assumptions include G GAC GBC in -theorem ncard_primesOver_mul_ncard_primesOver (hp : p ≠ ⊥) : +theorem ncard_primesOver_mul_ncard_primesOver : (p.primesOver B).ncard * (P.primesOver C).ncard = (p.primesOver C).ncard := by - have hP : P ≠ ⊥ := ne_bot_of_liesOver_of_ne_bot hp P let := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) let := IsFractionRing.mulSemiringAction GAC A C (FractionRing A) (FractionRing C) let := IsFractionRing.mulSemiringAction GBC B C (FractionRing B) (FractionRing C) have : p.ramificationIdxIn C * p.inertiaDegIn C ≠ 0 := - mul_ne_zero (ramificationIdxIn_ne_zero GAC hp) (inertiaDegIn_ne_zero GAC) - rw [← Nat.mul_left_inj this, ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp C GAC] + mul_ne_zero (ramificationIdxIn_ne_zero GAC) (inertiaDegIn_ne_zero GAC) + rw [← Nat.mul_left_inj this, ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p C GAC] calc _ = ((p.primesOver B).ncard * (p.ramificationIdxIn B * p.inertiaDegIn B)) * ((P.primesOver C).ncard * (P.ramificationIdxIn C * P.inertiaDegIn C)) := by rw [← inertiaDegIn_mul_inertiaDegIn p P G C GAC GBC, - ← ramificationIdxIn_mul_ramificationIdxIn' P G C GAC GBC] + ← ramificationIdxIn_mul_ramificationIdxIn P G C GAC GBC] ring _ = Nat.card GAC := by - rw [ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp B G, - ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hP C GBC, + rw [ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p B G, + ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn P C GBC, (IsGaloisGroup.toFractionRing G A B).card_eq_finrank, (IsGaloisGroup.toFractionRing GAC A C).card_eq_finrank, (IsGaloisGroup.toFractionRing GBC B C).card_eq_finrank, Module.finrank_mul_finrank] @@ -297,52 +275,57 @@ open scoped Pointwise open Algebra attribute [local instance] Ideal.Quotient.field in -theorem card_stabilizer_eq_card_inertia_mul_finrank (p : Ideal R) [p.IsMaximal] - (P : Ideal S) [P.LiesOver p] [P.IsMaximal] [Algebra.IsSeparable (R ⧸ p) (S ⧸ P)] : - Nat.card (MulAction.stabilizer G P) = Nat.card (inertia G P) * - Module.finrank (R ⧸ p) (S ⧸ P) := by - have : IsGalois (R ⧸ p) (S ⧸ P) := { __ := Ideal.Quotient.normal (A := R) G p P } - have := Ideal.Quotient.finite_of_isInvariant G p P +theorem card_stabilizer_eq_card_inertia_mul_finrank (p : Ideal R) [p.IsPrime] + (P : Ideal S) [P.LiesOver p] [P.IsPrime] [PerfectField p.ResidueField] : + Nat.card (MulAction.stabilizer G P) = Nat.card (inertia G P) * P.inertiaDeg' R := by + let := Localization.AtPrime.algebraOfLiesOver p P + let : Algebra (R ⧸ p) p.ResidueField := inferInstance + let : Algebra (S ⧸ P) P.ResidueField := inferInstance + have heq : (algebraMap (S ⧸ P) P.ResidueField).comp (algebraMap (R ⧸ p) (S ⧸ P)) = + (algebraMap p.ResidueField P.ResidueField).comp (algebraMap (R ⧸ p) p.ResidueField) := by + ext + simp [← IsScalarTower.algebraMap_apply] + let := ((algebraMap (S ⧸ P) P.ResidueField).comp (algebraMap (R ⧸ p) (S ⧸ P))).toAlgebra + have : IsScalarTower (R ⧸ p) (S ⧸ P) P.ResidueField := .of_algebraMap_eq' rfl + have : IsScalarTower (R ⧸ p) p.ResidueField P.ResidueField := .of_algebraMap_eq' heq + have : IsGalois p.ResidueField P.ResidueField := + { __ := Ideal.IsFractionRing.normal G p P p.ResidueField P.ResidueField } + have : Module.Finite p.ResidueField P.ResidueField := + Ideal.IsFractionRing.finite_of_isInvariant G p P p.ResidueField P.ResidueField have : Subgroup.index _ = _ := Nat.card_congr - (Quotient.stabilizerQuotientInertiaEquiv G p P).toEquiv - rw [← IsGalois.card_aut_eq_finrank, ← this, + (IsFractionRing.stabilizerQuotientInertiaEquiv G p P p.ResidueField P.ResidueField).toEquiv + rw [inertiaDeg'_eq p P, ← IsGalois.card_aut_eq_finrank p.ResidueField P.ResidueField, ← this, ← ((inertia G P).subgroupOf (MulAction.stabilizer G P)).card_mul_index, Nat.card_congr (Subgroup.subgroupOfEquivOfLe (inertia_le_stabilizer (M := G) P)).toEquiv, AddSubgroup.subgroupOf_inertia] -lemma ncard_primesOver_mul_card_inertia_mul_finrank (p : Ideal R) [p.IsMaximal] - (P : Ideal S) [P.LiesOver p] [P.IsMaximal] [Algebra.IsSeparable (R ⧸ p) (S ⧸ P)] : - (p.primesOver S).ncard * Nat.card (P.inertia G) * - Module.finrank (R ⧸ p) (S ⧸ P) = Nat.card G := by - rw [mul_assoc, ← card_stabilizer_eq_card_inertia_mul_finrank, +lemma ncard_primesOver_mul_card_inertia_mul_finrank (p : Ideal R) [p.IsPrime] + (P : Ideal S) [P.LiesOver p] [P.IsPrime] [PerfectField p.ResidueField] : + (p.primesOver S).ncard * Nat.card (P.inertia G) * P.inertiaDeg' R = Nat.card G := by + rw [mul_assoc, ← card_stabilizer_eq_card_inertia_mul_finrank p P, ← IsInvariant.orbit_eq_primesOver R S G p P] simpa using Nat.card_congr (MulAction.orbitProdStabilizerEquivGroup G P) /-- The cardinality of the inertia group is equal to the ramification index. -/ -lemma card_inertia_eq_ramificationIdxIn - [IsDedekindDomain R] [IsDedekindDomain S] [Module.Finite R S] - [IsTorsionFree R S] - (p : Ideal R) (hp : p ≠ ⊥) - (P : Ideal S) [P.LiesOver p] [P.IsMaximal] [Algebra.IsSeparable (R ⧸ p) (S ⧸ P)] : +lemma card_inertia_eq_ramificationIdxIn [IsDomain R] [IsDomain S] [Module.Finite R S] [Flat R S] + (p : Ideal R) (P : Ideal S) [P.LiesOver p] [p.IsPrime] [P.IsPrime] + [PerfectField p.ResidueField] : Nat.card (P.inertia G) = Ideal.ramificationIdxIn p S := by - have := (show p.IsPrime from P.over_def p ▸ inferInstance).isMaximal hp have H := ncard_primesOver_mul_card_inertia_mul_finrank (G := G) p P - refine mul_right_injective₀ (IsDedekindDomain.primesOver_ncard_ne_zero p S) ?_ - refine mul_left_injective₀ (b := Module.finrank (R ⧸ p) (S ⧸ P)) ?_ ?_ - · intro e; simp [e, eq_comm, Nat.card_eq_zero, ‹Finite G›.not_infinite] at H - dsimp only - rw [H, mul_assoc, ← inertiaDeg_algebraMap, ← inertiaDegIn_eq_inertiaDeg p P G, - ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp S G] + rw [← inertiaDegIn_eq_inertiaDeg p P G] at H + have h1 : (p.primesOver S).ncard ≠ 0 := by grind [Nat.card_pos] + have h2 : p.inertiaDegIn S ≠ 0 := by grind [Nat.card_pos] + rwa [← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p S G, + mul_assoc, mul_right_inj' h1, mul_left_inj' h2] at H /-- The cardinality of the decomposition group is equal to the ramification index times the inertia degree. -/ -lemma card_stabilizer_eq [IsDedekindDomain R] [IsDedekindDomain S] [Module.Finite R S] - [IsTorsionFree R S] (p : Ideal R) (hp : p ≠ ⊥) (P : Ideal S) [P.LiesOver p] [P.IsMaximal] - [Algebra.IsSeparable (R ⧸ p) (S ⧸ P)] : +lemma card_stabilizer_eq [IsDomain R] [IsDomain S] [Module.Finite R S] [Flat R S] + (p : Ideal R) (P : Ideal S) [P.LiesOver p] [p.IsPrime] [P.IsPrime] + [PerfectField p.ResidueField] : Nat.card (MulAction.stabilizer G P) = p.ramificationIdxIn S * p.inertiaDegIn S := by - have := (show p.IsPrime from P.over_def p ▸ inferInstance).isMaximal hp - rw [card_stabilizer_eq_card_inertia_mul_finrank p P, card_inertia_eq_ramificationIdxIn p hp, - inertiaDegIn_eq_inertiaDeg p P G, inertiaDeg_algebraMap] + rw [card_stabilizer_eq_card_inertia_mul_finrank p P, card_inertia_eq_ramificationIdxIn p, + inertiaDegIn_eq_inertiaDeg p P G] end inertia diff --git a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean index ab55582a4b8ab5..d5378c4a94dcc3 100644 --- a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean +++ b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean @@ -181,7 +181,7 @@ theorem IsDecompositionField.rank_left (hp : p ≠ ⊥) : Module.finrank D L = p.ramificationIdxIn B * p.inertiaDegIn B := by have : p.IsMaximal := over_def P p ▸ Ideal.IsMaximal.under A P have : Finite (A ⧸ p) := Ring.HasFiniteQuotients.finiteQuotient hp - rw [← IsGaloisGroup.card_eq_finrank (stabilizer Gal(L/K) P) D L, card_stabilizer_eq p hp] + rw [← IsGaloisGroup.card_eq_finrank (stabilizer Gal(L/K) P) D L, card_stabilizer_eq p] /-- The degree `[D : K]` of the decomposition field `D` over `K` equals the number of prime ideals @@ -195,7 +195,7 @@ theorem IsDecompositionField.rank_right [IsGalois K L] [Algebra K D] [IsScalarTo refine mul_left_injective₀ (b := Module.finrank D L) Module.finrank_pos.ne' ?_ dsimp only rw [Module.finrank_mul_finrank, rank_left A K L P D hp, - ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp B Gal(L/K), + ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p B Gal(L/K), IsGaloisGroup.card_eq_finrank Gal(L/K) K L] variable (E : Type*) [Field E] [Algebra E L] [IsInertiaField K L P E] @@ -207,8 +207,7 @@ theorem IsInertiaField.rank_left (hp : p ≠ ⊥) : Module.finrank E L = p.ramificationIdxIn B := by have : p.IsMaximal := over_def P p ▸ Ideal.IsMaximal.under A P have : Finite (A ⧸ p) := Ring.HasFiniteQuotients.finiteQuotient hp - rw [← IsGaloisGroup.card_eq_finrank (inertia Gal(L/K) P) E L, - card_inertia_eq_ramificationIdxIn p hp] + rw [← IsGaloisGroup.card_eq_finrank (inertia Gal(L/K) P) E L, card_inertia_eq_ramificationIdxIn p] /-- The degree `[E : K]` of the inertia field `E` over `K` equals the product of the number of @@ -221,7 +220,7 @@ theorem IsInertiaField.rank_right [IsGalois K L] [Algebra K E] [IsScalarTower K refine mul_left_injective₀ (b := Module.finrank E L) Module.finrank_pos.ne' ?_ dsimp only rw [Module.finrank_mul_finrank, rank_left A K L P E hp, mul_assoc, mul_comm (p.inertiaDegIn B), - ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp B Gal(L/K), + ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p B Gal(L/K), IsGaloisGroup.card_eq_finrank Gal(L/K) K L] /-- @@ -291,15 +290,18 @@ private lemma ramificationIdxIn_eq_and_inertiaDegIn_eq (hp : p ≠ ⊥) : ramificationIdxIn 𝓟D B = p.ramificationIdxIn B ∧ inertiaDegIn 𝓟D B = p.inertiaDegIn B := by obtain ⟨_, _, _, _, _, h𝓟⟩ := instances A K L P D 𝓞D 𝓟D hp refine eq_and_eq_of_pos_of_le_of_mul_le_mul ?_ ?_ ?_ ?_ ?_ - · exact Nat.pos_of_ne_zero <| ramificationIdxIn_ne_zero (stabilizer Gal(L/K) P) h𝓟 + · exact Nat.pos_of_ne_zero <| ramificationIdxIn_ne_zero (stabilizer Gal(L/K) P) · exact Nat.pos_of_ne_zero <| inertiaDegIn_ne_zero (stabilizer Gal(L/K) P) · rw [ramificationIdxIn_eq_ramificationIdx p P Gal(L/K), ramificationIdxIn_eq_ramificationIdx _ P (stabilizer Gal(L/K) P)] + rw [← ramificationIdx_eq_ramificationIdx' p _ hp, + ← ramificationIdx_eq_ramificationIdx' 𝓟D _ h𝓟] exact IsDedekindDomain.ramificationIdx_le_ramificationIdx _ _ _ hp · rw [inertiaDegIn_eq_inertiaDeg p P Gal(L/K), inertiaDegIn_eq_inertiaDeg _ P (stabilizer Gal(L/K) P)] + rw [← inertiaDeg_eq_inertiaDeg' p, ← inertiaDeg_eq_inertiaDeg' 𝓟D] exact inertiaDeg_le_inertiaDeg p 𝓟D P - · have := ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn h𝓟 B (stabilizer Gal(L/K) P) + · have := ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝓟D B (stabilizer Gal(L/K) P) rw [primesOver_eq_singleton K L P D 𝓞D, Set.ncard_singleton, one_mul] at this rw [this, IsGaloisGroup.card_eq_finrank (stabilizer Gal(L/K) P) D L, IsDecompositionField.rank_left A K L P D hp] @@ -328,13 +330,12 @@ Let `D` be the decomposition field of `P` in `L/K`. Let `𝓟D` be a prime ideal then `𝓟D` is unramified over `K`. -/ theorem ramificationIdx_eq (hp : p ≠ ⊥) : - ramificationIdx p 𝓟D = 1 := by + 𝓟D.ramificationIdx' A = 1 := by obtain ⟨_, _, _, _, _, h𝓟⟩ := instances A K L P D 𝓞D 𝓟D hp - have := ramificationIdx_algebra_tower (map_ne_bot_of_ne_bot h𝓟) (map_ne_bot_of_ne_bot hp) - (map_le_iff_le_comap.mpr ((liesOver_iff P 𝓟D).mp inferInstance).le) + have := ramificationIdx'_tower (R := A) 𝓟D P rwa [← ramificationIdxIn_eq_ramificationIdx 𝓟D P (stabilizer Gal(L/K) P), ramificationIdxIn_eq A K L P D 𝓞D 𝓟D hp, ramificationIdxIn_eq_ramificationIdx p P Gal(L/K), - right_eq_mul₀ <| IsDedekindDomain.ramificationIdx_ne_zero_of_liesOver P hp] at this + right_eq_mul₀ <| (ramificationIdx'_pos P A).ne'] at this include K L D P in /-- @@ -342,9 +343,9 @@ Let `D` be the decomposition field of `P` in `L/K`. Let `𝓟D` be a prime ideal then the inertia degree of `𝓟D` over `K` is equal to `1`. -/ theorem inertiaDeg_eq (hp : p ≠ ⊥) : - inertiaDeg p 𝓟D = 1 := by + 𝓟D.inertiaDeg' A = 1 := by obtain ⟨_, _, _, _, _, _⟩ := instances A K L P D 𝓞D 𝓟D hp - have := inertiaDeg_algebra_tower p 𝓟D P + have := inertiaDeg'_tower (R := A) 𝓟D P rwa [← inertiaDegIn_eq_inertiaDeg p P Gal(L/K), ← inertiaDegIn_eq A K L P D 𝓞D 𝓟D hp, ← inertiaDegIn_eq_inertiaDeg 𝓟D P (stabilizer Gal(L/K) P), right_eq_mul₀ <| inertiaDegIn_ne_zero (stabilizer Gal(L/K) P)] at this diff --git a/Mathlib/RingTheory/Ideal/GoingUp.lean b/Mathlib/RingTheory/Ideal/GoingUp.lean index 17e2381d93e229..3c9b3441e4d7fe 100644 --- a/Mathlib/RingTheory/Ideal/GoingUp.lean +++ b/Mathlib/RingTheory/Ideal/GoingUp.lean @@ -333,10 +333,10 @@ theorem exists_ideal_over_prime_of_isIntegral [Algebra.IsIntegral R S] (P : Idea obtain ⟨Q, hQ, hQ', hQ''⟩ := exists_ideal_over_prime_of_isIntegral_of_isPrime P P' hP'' exact ⟨Q, hP.trans hQ, hQ', hQ''⟩ -instance nonempty_primesOver [IsDomain R] [Nontrivial S] [Algebra.IsIntegral R S] - [Module.IsTorsionFree R S] (P : Ideal R) [P.IsPrime] : +instance nonempty_primesOver [Algebra.IsIntegral R S] [FaithfulSMul R S] (P : Ideal R) [P.IsPrime] : Nonempty (primesOver P S) := by - obtain ⟨Q, _, hQ₁, hQ₂⟩ := exists_ideal_over_prime_of_isIntegral P (⊥ : Ideal S) (by simp) + obtain ⟨Q, _, hQ₁, hQ₂⟩ := exists_ideal_over_prime_of_isIntegral P (⊥ : Ideal S) + (by simp [← RingHom.ker_eq_comap_bot]) exact ⟨Q, ⟨hQ₁, (liesOver_iff _ _).mpr hQ₂.symm⟩⟩ /-- `comap (algebraMap R S)` is a surjection from the max spec of `S` to max spec of `R`. diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index 74b68815f1914c..86337c0e1acc2c 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -399,6 +399,7 @@ be Galois. -/ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] [IsGalois (FractionRing R) (FractionRing S)] : relNorm R P = p ^ p.inertiaDeg P := by + have : P.IsMaximal := IsMaximal.of_liesOver_isMaximal P p let G := Gal(FractionRing S/FractionRing R) let := IsIntegralClosure.MulSemiringAction R (FractionRing R) (FractionRing S) S have := IsGaloisGroup.of_isFractionRing G R S (FractionRing R) (FractionRing S) @@ -417,6 +418,7 @@ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] rw [Set.mem_toFinset] at hQ have : Q.IsPrime := hQ.1 have : Q.LiesOver p := hQ.2 + rw [ramificationIdx_eq_ramificationIdx' p Q hp] rw [← ramificationIdxIn_eq_ramificationIdx p Q G] obtain ⟨σ, rfl⟩ := Ideal.exists_smul_eq_of_isGaloisGroup p P Q G rw [relNorm_smul, hs, ← pow_mul, mul_comm] @@ -424,12 +426,12 @@ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] map_algebraMap_eq_finsetProd_pow hp).symm.trans <| relNorm_algebraMap S p simp +contextual only [map_prod, map_pow, h₀, Finset.prod_const, ← pow_mul] at h rwa [← IsGaloisGroup.card_eq_finrank G (FractionRing R) (FractionRing S), - ← Ideal.ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn hp S G, mul_comm, + ← Ideal.ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p S G, mul_comm, ← Set.ncard_eq_toFinset_card', ((IsLeftCancelMulZero.mul_left_cancel_of_ne_zero hp).pow_injective _).eq_iff, mul_right_inj' (IsDedekindDomain.primesOver_ncard_ne_zero p S), - mul_right_inj' (ramificationIdxIn_ne_zero G hp), - inertiaDegIn_eq_inertiaDeg p P G] at h + mul_right_inj' (ramificationIdxIn_ne_zero G), + inertiaDegIn_eq_inertiaDeg p P G, ← inertiaDeg_eq_inertiaDeg' p P] at h rw [one_eq_top] exact IsMaximal.ne_top inferInstance From c5517cc67b022ecda5b14c46d2953a39361155f9 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:44:48 +0000 Subject: [PATCH 0140/1300] chore: replace some `convert!` with `convert` (#40731) Replace some uses of `convert!` by `convert`. In particular, the field `AffineSubspace.smul_vsub_vadd_mem` didn't have the right type, so I've fixed this in this PR. Note: many such replacements should be done automatically with a direct replacement. This should be done automatically in another PR. --- Mathlib/Data/Fintype/List.lean | 12 +++----- Mathlib/GroupTheory/Coset/Basic.lean | 4 +-- .../AffineSpace/AffineSubspace/Basic.lean | 4 +-- .../AffineSpace/AffineSubspace/Defs.lean | 29 ++++++++++--------- .../UniqueFactorizationDomain/Basic.lean | 5 +--- .../NormalizedFactors.lean | 3 +- 6 files changed, 25 insertions(+), 32 deletions(-) diff --git a/Mathlib/Data/Fintype/List.lean b/Mathlib/Data/Fintype/List.lean index d81ea4001438e3..536953e26212ba 100644 --- a/Mathlib/Data/Fintype/List.lean +++ b/Mathlib/Data/Fintype/List.lean @@ -66,18 +66,14 @@ instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } := b constructor · simp only [Finset.coe_toList] rfl - · convert! Finset.nodup_toList (Finset.univ.powerset : Finset (Finset α)) - ext l - unfold Nodup - refine Pairwise.iff ?_ - intro m n + · -- Unfold `List.Nodup` in the type of the proof term to make it match with the goal. + convert dsimp% [List.Nodup] Finset.nodup_toList (Finset.univ.powerset : Finset (Finset α)) + with m n simp only [_root_.Disjoint] rw [← m.coe_toList, ← n.coe_toList, Multiset.lists_coe, Multiset.lists_coe] have := Multiset.coe_disjoint m.toList.permutations n.toList.permutations rw [_root_.Disjoint] at this - rw [this] - simp only [ne_eq] - rw [List.disjoint_iff_ne] + rw [this, List.disjoint_iff_ne] constructor · intro h by_contra hc diff --git a/Mathlib/GroupTheory/Coset/Basic.lean b/Mathlib/GroupTheory/Coset/Basic.lean index fdf30d965ac8ec..896ebb56a467bd 100644 --- a/Mathlib/GroupTheory/Coset/Basic.lean +++ b/Mathlib/GroupTheory/Coset/Basic.lean @@ -285,8 +285,8 @@ theorem strictMono_comap_prod_image : refine fun t₁ t₂ h ↦ ⟨⟨Subgroup.comap_mono h.1, Set.image_mono h.1⟩, mt (fun ⟨le1, le2⟩ a ha ↦ ?_) h.2⟩ obtain ⟨a', h', eq⟩ := le2 ⟨_, ha, rfl⟩ - convert! ← t₁.mul_mem h' (@le1 ⟨_, QuotientGroup.eq.1 eq⟩ <| t₂.mul_mem (t₂.inv_mem <| h.1 h') ha) - apply mul_inv_cancel_left + convert t₁.mul_mem h' (@le1 ⟨_, QuotientGroup.eq.1 eq⟩ <| t₂.mul_mem (t₂.inv_mem <| h.1 h') ha) + simp variable {s} {a b : α} diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index b4f59a92546e88..5874d92b08e4bd 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -530,7 +530,7 @@ namespace AffineSubspace /-- The image of an affine subspace under an affine map as an affine subspace. -/ def map (s : AffineSubspace k P₁) : AffineSubspace k P₂ where carrier := f '' s - smul_vsub_vadd_mem := by + smul_vsub_vadd_mem' := by rintro t - - - ⟨p₁, h₁, rfl⟩ ⟨p₂, h₂, rfl⟩ ⟨p₃, h₃, rfl⟩ use t • (p₁ -ᵥ p₂) +ᵥ p₃ suffices t • (p₁ -ᵥ p₂) +ᵥ p₃ ∈ s by @@ -723,7 +723,7 @@ namespace AffineSubspace /-- The preimage of an affine subspace under an affine map as an affine subspace. -/ def comap (f : P₁ →ᵃ[k] P₂) (s : AffineSubspace k P₂) : AffineSubspace k P₁ where carrier := f ⁻¹' s - smul_vsub_vadd_mem t p₁ p₂ p₃ (hp₁ : f p₁ ∈ s) (hp₂ : f p₂ ∈ s) (hp₃ : f p₃ ∈ s) := + smul_vsub_vadd_mem' t p₁ p₂ p₃ (hp₁ : f p₁ ∈ s) (hp₂ : f p₂ ∈ s) (hp₃ : f p₃ ∈ s) := show f _ ∈ s by rw [AffineMap.map_vadd, map_smul, AffineMap.linearMap_vsub] apply s.smul_vsub_vadd_mem _ hp₁ hp₂ hp₃ diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean index fdb3d07ecd305c..485c4d8a1dc3fc 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean @@ -150,14 +150,12 @@ structure AffineSubspace (k : Type*) {V : Type*} (P : Type*) [Ring k] [AddCommGr [Module k V] [AffineSpace V P] where /-- The affine subspace seen as a subset. -/ carrier : Set P - smul_vsub_vadd_mem : - ∀ (c : k) {p₁ p₂ p₃ : P}, - p₁ ∈ carrier → p₂ ∈ carrier → p₃ ∈ carrier → c • (p₁ -ᵥ p₂ : V) +ᵥ p₃ ∈ carrier + protected smul_vsub_vadd_mem' (c : k) {p₁ p₂ p₃ : P} : + p₁ ∈ carrier → p₂ ∈ carrier → p₃ ∈ carrier → c • (p₁ -ᵥ p₂ : V) +ᵥ p₃ ∈ carrier namespace AffineSubspace -variable (k : Type*) {V : Type*} (P : Type*) [Ring k] [AddCommGroup V] [Module k V] - [AffineSpace V P] +variable {k V P : Type*} [Ring k] [AddCommGroup V] [Module k V] [AffineSpace V P] instance : SetLike (AffineSubspace k P) P where coe := carrier @@ -167,12 +165,14 @@ instance : PartialOrder (AffineSubspace k P) := .ofSetLike (AffineSubspace k P) @[simp] lemma carrier_eq_coe (s : AffineSubspace k P) : s.carrier = s := rfl +lemma smul_vsub_vadd_mem (s : AffineSubspace k P) (c : k) {p₁ p₂ p₃ : P} : + p₁ ∈ s → p₂ ∈ s → p₃ ∈ s → c • (p₁ -ᵥ p₂ : V) +ᵥ p₃ ∈ s := + s.smul_vsub_vadd_mem' c + /-- A point is in an affine subspace coerced to a set if and only if it is in that affine subspace. -/ theorem mem_coe (p : P) (s : AffineSubspace k P) : p ∈ (s : Set P) ↔ p ∈ s := by simp -variable {k P} - /-- Two affine subspaces are equal if they have the same points. -/ theorem coe_injective : Function.Injective ((↑) : AffineSubspace k P → Set P) := SetLike.coe_injective @@ -193,7 +193,7 @@ variable {k V : Type*} [Ring k] [AddCommGroup V] [Module k V] /-- Reinterprets `p : Submodule k V` as an `AffineSubspace k V`. -/ @[coe] def toAffineSubspace (p : Submodule k V) : AffineSubspace k V where carrier := p - smul_vsub_vadd_mem _ _ _ _ h₁ h₂ h₃ := p.add_mem (p.smul_mem _ (p.sub_mem h₁ h₂)) h₃ + smul_vsub_vadd_mem' _ _ _ _ h₁ h₂ h₃ := p.add_mem (p.smul_mem _ (p.sub_mem h₁ h₂)) h₃ instance : Coe (Submodule k V) (AffineSubspace k V) := ⟨toAffineSubspace⟩ @@ -252,7 +252,8 @@ def directionOfNonempty {s : AffineSubspace k P} (h : (s : Set P).Nonempty) : Su rintro _ _ ⟨p₁, hp₁, p₂, hp₂, rfl⟩ ⟨p₃, hp₃, p₄, hp₄, rfl⟩ rw [← vadd_vsub_assoc] refine vsub_mem_vsub ?_ hp₄ - convert! s.smul_vsub_vadd_mem 1 hp₁ hp₂ hp₃ + rw [mem_coe] + convert s.smul_vsub_vadd_mem 1 hp₁ hp₂ hp₃ rw [one_smul] smul_mem' := by rintro c _ ⟨p₁, hp₁, p₂, hp₂, rfl⟩ @@ -287,7 +288,7 @@ theorem vadd_mem_of_mem_direction {s : AffineSubspace k P} {v : V} (hv : v ∈ s rw [mem_direction_iff_eq_vsub ⟨p, hp⟩] at hv rcases hv with ⟨p₁, hp₁, p₂, hp₂, hv⟩ rw [hv] - convert! s.smul_vsub_vadd_mem 1 hp₁ hp₂ hp + convert s.smul_vsub_vadd_mem 1 hp₁ hp₂ hp rw [one_smul] /-- Subtracting two points in the subspace produces a vector in the direction. -/ @@ -386,7 +387,7 @@ theorem eq_iff_direction_eq_of_mem {s₁ s₂ : AffineSubspace k P} {p : P} (h /-- Construct an affine subspace from a point and a direction. -/ def mk' (p : P) (direction : Submodule k V) : AffineSubspace k P where carrier := { q | q -ᵥ p ∈ direction } - smul_vsub_vadd_mem c p₁ p₂ p₃ hp₁ hp₂ hp₃ := by + smul_vsub_vadd_mem' c p₁ p₂ p₃ hp₁ hp₂ hp₃ := by simpa [vadd_vsub_assoc] using direction.add_mem (direction.smul_mem c (direction.sub_mem hp₁ hp₂)) hp₃ @@ -463,7 +464,7 @@ variable (k : Type*) {V : Type*} {P : Type*} [Ring k] [AddCommGroup V] [Module k (Actually defined here in terms of spans in modules.) -/ def affineSpan (s : Set P) : AffineSubspace k P where carrier := spanPoints k s - smul_vsub_vadd_mem c _ _ _ hp₁ hp₂ hp₃ := + smul_vsub_vadd_mem' c _ _ _ hp₁ hp₂ hp₃ := vadd_mem_spanPoints_of_mem_spanPoints_of_mem_vectorSpan k hp₃ ((vectorSpan k s).smul_mem c (vsub_mem_vectorSpan_of_mem_spanPoints_of_mem_spanPoints k hp₁ hp₂)) @@ -542,11 +543,11 @@ instance : CompleteLattice (AffineSubspace k P) where inf_le_right := fun _ _ => Set.inter_subset_right top := { carrier := Set.univ - smul_vsub_vadd_mem := fun _ _ _ _ _ _ _ => Set.mem_univ _ } + smul_vsub_vadd_mem' _ _ _ _ _ _ _ := Set.mem_univ _ } le_top := fun _ _ _ => Set.mem_univ _ bot := { carrier := ∅ - smul_vsub_vadd_mem := fun _ _ _ _ => False.elim } + smul_vsub_vadd_mem' _ _ _ _ := False.elim } bot_le := fun _ _ => False.elim sSup := fun s => affineSpan k (⋃ s' ∈ s, (s' : Set P)) sInf := fun s => diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index a1ad2b43565bc1..7b93b28eee7e7d 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -57,10 +57,7 @@ end WfDvdMonoid theorem WfDvdMonoid.of_wellFoundedLT_associates [CommMonoidWithZero α] [IsCancelMulZero α] (h : WellFoundedLT (Associates α)) : WfDvdMonoid α := WfDvdMonoid.of_wfDvdMonoid_associates - ⟨by - convert! h.wf - ext - exact Associates.dvdNotUnit_iff_lt⟩ + ⟨by convert h.wf; exact Associates.dvdNotUnit_iff_lt⟩ theorem WfDvdMonoid.iff_wellFounded_associates [CommMonoidWithZero α] [IsCancelMulZero α] : WfDvdMonoid α ↔ WellFoundedLT (Associates α) := diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean index d02f959aebbcb2..3db98f8f11a8b3 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean @@ -41,8 +41,7 @@ if `M` has a trivial group of units. -/ theorem factors_eq_normalizedFactors {M : Type*} [CommMonoidWithZero M] [UniqueFactorizationMonoid M] [Subsingleton Mˣ] (x : M) : factors x = normalizedFactors x := by unfold normalizedFactors - convert! (Multiset.map_id (factors x)).symm - ext p + convert (Multiset.map_id (factors x)).symm with p exact normalize_eq p theorem prod_normalizedFactors {a : α} (ane0 : a ≠ 0) : From cf36f3ffdb98eee75df18f733538eb51cbdfea3e Mon Sep 17 00:00:00 2001 From: Yan Yablonovskiy <186670707+YanYablonovskiy@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:44:50 +0000 Subject: [PATCH 0141/1300] feat(StrongMeasurability): `fun_prop` for `integral_kernel` (#40751) See [this](https://github.com/YaelDillies/gibbs-measure/pull/26#discussion_r3434489840) discussion. Co-authored-by: YanYablonovskiy --- Mathlib/Probability/Kernel/MeasurableIntegral.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Probability/Kernel/MeasurableIntegral.lean b/Mathlib/Probability/Kernel/MeasurableIntegral.lean index 8e8545a71131ec..0adc5b18d2add3 100644 --- a/Mathlib/Probability/Kernel/MeasurableIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableIntegral.lean @@ -51,6 +51,7 @@ namespace MeasureTheory variable [NormedSpace ℝ E] omit [IsSFiniteKernel κ] in +@[fun_prop] theorem StronglyMeasurable.integral_kernel ⦃f : β → E⦄ (hf : StronglyMeasurable f) : StronglyMeasurable fun x ↦ ∫ y, f y ∂κ x := by classical From 80379404120370388cda81cb32434da332cfceb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:22:21 +0000 Subject: [PATCH 0142/1300] refactor(Topology): redefine Delta-generated spaces (#38431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delta-generated spaces are made particular cases of `X`-generated spaces, where `X` is the family of spaces `Fin n → ℝ`. --- Mathlib/Topology/Category/DeltaGenerated.lean | 94 +++----- .../Compactness/DeltaGeneratedSpace.lean | 224 +++++++----------- Mathlib/Topology/Convenient/Category.lean | 26 +- Mathlib/Topology/Convenient/GeneratedBy.lean | 11 + 4 files changed, 144 insertions(+), 211 deletions(-) diff --git a/Mathlib/Topology/Category/DeltaGenerated.lean b/Mathlib/Topology/Category/DeltaGenerated.lean index 836bf8399aa1de..77fb4f8368300f 100644 --- a/Mathlib/Topology/Category/DeltaGenerated.lean +++ b/Mathlib/Topology/Category/DeltaGenerated.lean @@ -1,25 +1,30 @@ /- Copyright (c) 2024 Ben Eltschig. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Ben Eltschig +Authors: Ben Eltschig, Joël Riou -/ module public import Mathlib.CategoryTheory.Monad.Limits public import Mathlib.Topology.Category.TopCat.Limits.Basic public import Mathlib.Topology.Compactness.DeltaGeneratedSpace +public import Mathlib.Topology.Convenient.Category /-! # Delta-generated topological spaces -The category of delta-generated spaces. +This file defines the category `DeltaGenerated` of delta-generated spaces. +This is a particular case of the construction in the file +`Mathlib/Topology/Convenient/Category.Lean`: this is the category of +`X`-generated spaces where `X` is the family of spaces `Fin n → ℝ` +for all `n : ℕ`. -See https://ncatlab.org/nlab/show/Delta-generated+topological+space. +## TODO +* `DeltaGenerated` is Cartesian closed (@joelriou). -Adapted from `Mathlib/Topology/Category/CompactlyGenerated.lean`. +## References +* https://ncatlab.org/nlab/show/Delta-generated+topological+space -## TODO -* `DeltaGenerated` is Cartesian closed. -/ @[expose] public section @@ -28,77 +33,32 @@ universe u open CategoryTheory -/-- The type of delta-generated topological spaces. -/ -structure DeltaGenerated where - /-- the underlying topological space -/ - toTop : TopCat.{u} - /-- The underlying topological space is delta-generated. -/ - deltaGenerated : DeltaGeneratedSpace toTop := by infer_instance - -namespace DeltaGenerated +/-- The category of delta-generated topological spaces. -/ +abbrev DeltaGenerated := GeneratedByTopCat.{u} (fun n ↦ Fin n → ℝ) -instance : CoeSort DeltaGenerated Type* := - ⟨fun X ↦ X.toTop⟩ - -attribute [instance] deltaGenerated - -instance : LargeCategory.{u} DeltaGenerated.{u} := - inferInstanceAs <| Category (InducedCategory _ toTop) +/-- The faithful (but not full) functor taking each topological space to its delta-generated + coreflection. -/ +abbrev TopCat.toDeltaGenerated : TopCat.{u} ⥤ DeltaGenerated.{u} := + TopCat.toGeneratedByTopCat -instance : ConcreteCategory.{u} DeltaGenerated.{u} (C(·, ·)) := - inferInstanceAs <| ConcreteCategory (InducedCategory _ toTop) _ +namespace DeltaGenerated /-- Constructor for objects of the category `DeltaGenerated` -/ -abbrev of (X : Type u) [TopologicalSpace X] [DeltaGeneratedSpace X] : DeltaGenerated.{u} where - toTop := TopCat.of X - deltaGenerated := ‹_› +abbrev of (X : Type u) [TopologicalSpace X] [DeltaGeneratedSpace X] : DeltaGenerated.{u} := + GeneratedByTopCat.of X /-- The forgetful functor `DeltaGenerated ⥤ TopCat` -/ -@[simps!] -def deltaGeneratedToTop : DeltaGenerated.{u} ⥤ TopCat.{u} := - inducedFunctor _ +abbrev deltaGeneratedToTop : DeltaGenerated.{u} ⥤ TopCat.{u} := + GeneratedByTopCat.toTopCat /-- `deltaGeneratedToTop` is fully faithful. -/ -def fullyFaithfulDeltaGeneratedToTop : deltaGeneratedToTop.{u}.FullyFaithful := - fullyFaithfulInducedFunctor _ - -instance : deltaGeneratedToTop.{u}.Full := fullyFaithfulDeltaGeneratedToTop.full - -instance : deltaGeneratedToTop.{u}.Faithful := fullyFaithfulDeltaGeneratedToTop.faithful - -/-- The faithful (but not full) functor taking each topological space to its delta-generated - coreflection. -/ -@[simps!] -def topToDeltaGenerated : TopCat.{u} ⥤ DeltaGenerated.{u} where - obj X := of (DeltaGeneratedSpace.of X) - map {_ Y} f := ConcreteCategory.ofHom ⟨f, (continuous_to_deltaGenerated (Y := Y)).mpr <| - continuous_le_dom deltaGenerated_le f.hom.continuous⟩ +abbrev fullyFaithfulDeltaGeneratedToTop : deltaGeneratedToTop.{u}.FullyFaithful := + GeneratedByTopCat.fullyFaithfulToTopCat _ -instance : topToDeltaGenerated.{u}.Faithful := - ⟨fun h ↦ by ext x; exact CategoryTheory.congr_fun h x⟩ +@[deprecated (since := "2026-04-23")] alias topToDeltaGenerated := TopCat.toDeltaGenerated /-- The adjunction between the forgetful functor `DeltaGenerated ⥤ TopCat` and its coreflector. -/ -def coreflectorAdjunction : deltaGeneratedToTop ⊣ topToDeltaGenerated := - Adjunction.mkOfUnitCounit { - unit := { - app X := ConcreteCategory.ofHom - ⟨id, continuous_iff_coinduced_le.mpr (eq_deltaGenerated (X := X)).le⟩ } - counit := { - app X := ConcreteCategory.ofHom - ⟨DeltaGeneratedSpace.counit, DeltaGeneratedSpace.continuous_counit⟩ } } - -/-- The category of delta-generated spaces is coreflective in the category of topological spaces. -/ -instance deltaGeneratedToTop.coreflective : Coreflective deltaGeneratedToTop where - R := topToDeltaGenerated - adj := coreflectorAdjunction - -noncomputable instance deltaGeneratedToTop.createsColimits : CreatesColimits deltaGeneratedToTop := - comonadicCreatesColimits deltaGeneratedToTop - -instance hasLimits : Limits.HasLimits DeltaGenerated := - hasLimits_of_coreflective deltaGeneratedToTop - -instance hasColimits : Limits.HasColimits DeltaGenerated := - hasColimits_of_hasColimits_createsColimits deltaGeneratedToTop +abbrev coreflectorAdjunction : deltaGeneratedToTop ⊣ TopCat.toDeltaGenerated := + GeneratedByTopCat.adj end DeltaGenerated diff --git a/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean b/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean index 808a0556b7a8ce..d06465c472ce81 100644 --- a/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean +++ b/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean @@ -1,10 +1,11 @@ /- Copyright (c) 2024 Ben Eltschig. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Ben Eltschig +Authors: Ben Eltschig, Joël Riou -/ module +public import Mathlib.Topology.Convenient.GeneratedBy public import Mathlib.Analysis.LocallyConvex.WithSeminorms /-! @@ -17,7 +18,11 @@ locally path-connected, sequential and in particular compactly generated. See https://ncatlab.org/nlab/show/Delta-generated+topological+space. -Adapted from `Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean`. +The notions defined in this file (see also the file +`Mathlib/Topology/Category/DeltaGenerated.lean` for the category `DeltaGenerated`) +are a particular case of the notion of `X`-generated topological spaces where +`X` is a family of topological spaces (see the file +`Mathlib/Topology/Convenient/GeneratedBy.lean`.) ## TODO * All locally path-connected first-countable spaces are delta-generated - in particular, all normed @@ -28,158 +33,95 @@ Adapted from `Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean`. @[expose] public section -variable {X Y : Type*} [tX : TopologicalSpace X] [tY : TopologicalSpace Y] - open TopologicalSpace Topology +/-- A topological space is Delta-generated if its topology is generated +by the continuous maps from topological spaces of the form `Fin n → ℝ`. -/ +abbrev DeltaGeneratedSpace (Y : Type*) [TopologicalSpace Y] : Prop := + IsGeneratedBy (fun n ↦ Fin n → ℝ) Y + +namespace DeltaGeneratedSpace + +variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] + +/-- Type synonym to be equipped with the delta-generated topology. -/ +abbrev of : Type _ := WithGeneratedByTopology (fun n ↦ Fin n → ℝ) Y + +/-- Delta-generated spaces are locally path-connected. -/ +instance [DeltaGeneratedSpace X] : + LocPathConnectedSpace X := by + rw [← IsGeneratedBy.generatedBy_eq (X := fun n ↦ Fin n → ℝ) (Y := X), + generatedBy_eq_coinduced] + exact LocPathConnectedSpace.coinduced _ + +/-- Delta-generated spaces are sequential. -/ +instance [DeltaGeneratedSpace X] : SequentialSpace X := by + rw [← IsGeneratedBy.generatedBy_eq (X := fun n ↦ Fin n → ℝ) (Y := X)] + exact SequentialSpace.iSup (fun n ↦ SequentialSpace.iSup + (fun f ↦ SequentialSpace.coinduced _)) + +end DeltaGeneratedSpace + /-- The topology coinduced by all maps from ℝⁿ into a space. -/ -@[implicit_reducible] +@[implicit_reducible, deprecated "Use TopologicalSpace.generatedBy" (since := "2026-04-23")] def TopologicalSpace.deltaGenerated (X : Type*) [TopologicalSpace X] : TopologicalSpace X := ⨆ f : (n : ℕ) × C(((Fin n) → ℝ), X), coinduced f.2 inferInstance -/-- The delta-generated topology is also coinduced by a single map out of a sigma type. -/ -lemma deltaGenerated_eq_coinduced : deltaGenerated X = coinduced - (fun x : (f : (n : ℕ) × C(Fin n → ℝ, X)) × (Fin f.1 → ℝ) ↦ x.1.2 x.2) inferInstance := by - rw [deltaGenerated, instTopologicalSpaceSigma, coinduced_iSup]; rfl - -/-- The delta-generated topology is at least as fine as the original one. -/ -lemma deltaGenerated_le : deltaGenerated X ≤ tX := - iSup_le_iff.mpr fun f ↦ f.2.continuous.coinduced_le - -/-- A set is open in `deltaGenerated X` iff all its preimages under continuous functions ℝⁿ → X are - open. -/ -lemma isOpen_deltaGenerated_iff {u : Set X} : - IsOpen[deltaGenerated X] u ↔ ∀ n (p : C(Fin n → ℝ, X)), IsOpen (p ⁻¹' u) := by - simp_rw +instances [deltaGenerated, isOpen_iSup_iff, isOpen_coinduced, Sigma.forall] - -/-- A map from ℝⁿ to X is continuous iff it is continuous regarding the - delta-generated topology on X. Outside of this file, use the more general - `continuous_to_deltaGenerated` instead. -/ -private lemma continuous_euclidean_to_deltaGenerated {n : ℕ} {f : (Fin n → ℝ) → X} : - Continuous[_, deltaGenerated X] f ↔ Continuous f := by - simp_rw [continuous_iff_coinduced_le] - refine ⟨fun h ↦ h.trans deltaGenerated_le, fun h ↦ ?_⟩ - simp_rw [deltaGenerated] - exact le_iSup_of_le (i := ⟨n, f, continuous_iff_coinduced_le.mpr h⟩) le_rfl - -/-- `deltaGenerated` is idempotent as a function `TopologicalSpace X → TopologicalSpace X`. -/ -lemma deltaGenerated_deltaGenerated_eq : - @deltaGenerated X (deltaGenerated X) = deltaGenerated X := by - ext u; simp_rw [isOpen_deltaGenerated_iff]; refine forall_congr' fun n ↦ ?_ - -- somewhat awkward because `ContinuousMap` doesn't play well with multiple topologies. - refine ⟨fun h p ↦ h <| @ContinuousMap.mk _ _ _ (_) p ?_, fun h p ↦ h ⟨p, ?_⟩⟩ - · exact continuous_euclidean_to_deltaGenerated.mpr p.2 - · exact continuous_euclidean_to_deltaGenerated.mp <| @ContinuousMap.continuous_toFun _ _ _ (_) p - -/-- A space is delta-generated if its topology is equal to the delta-generated topology, i.e. - coinduced by all continuous maps ℝⁿ → X. Since the delta-generated topology is always finer - than the original one, it suffices to show that it is also coarser. -/ -class DeltaGeneratedSpace (X : Type*) [t : TopologicalSpace X] : Prop where - le_deltaGenerated : t ≤ deltaGenerated X - -lemma eq_deltaGenerated [DeltaGeneratedSpace X] : tX = deltaGenerated X := - eq_of_le_of_ge DeltaGeneratedSpace.le_deltaGenerated deltaGenerated_le - -/-- A subset of a delta-generated space is open iff its preimage is open for every - continuous map from ℝⁿ to X. -/ -lemma DeltaGeneratedSpace.isOpen_iff [DeltaGeneratedSpace X] {u : Set X} : - IsOpen u ↔ ∀ (n : ℕ) (p : ContinuousMap ((Fin n) → ℝ) X), IsOpen (p ⁻¹' u) := by - nth_rewrite 1 [eq_deltaGenerated (X := X)]; exact isOpen_deltaGenerated_iff - -/-- A map out of a delta-generated space is continuous iff it preserves continuity of maps - from ℝⁿ into X. -/ -lemma DeltaGeneratedSpace.continuous_iff [DeltaGeneratedSpace X] {f : X → Y} : - Continuous f ↔ ∀ (n : ℕ) (p : C(((Fin n) → ℝ), X)), Continuous (f ∘ p) := by - simp_rw [continuous_iff_coinduced_le] - nth_rewrite 1 [eq_deltaGenerated (X := X), deltaGenerated] - simp [coinduced_compose, Sigma.forall] - -/-- A map out of a delta-generated space is continuous iff it is continuous with respect - to the delta-generated topology on the codomain. -/ -lemma continuous_to_deltaGenerated [DeltaGeneratedSpace X] {f : X → Y} : - Continuous[_, deltaGenerated Y] f ↔ Continuous f := by - simp_rw [DeltaGeneratedSpace.continuous_iff, continuous_euclidean_to_deltaGenerated] - -/-- The delta-generated topology on `X` does in fact turn `X` into a delta-generated space. -/ -lemma deltaGeneratedSpace_deltaGenerated {X : Type*} {t : TopologicalSpace X} : - @DeltaGeneratedSpace X (@deltaGenerated X t) := by - let _ := @deltaGenerated X t; constructor; rw [@deltaGenerated_deltaGenerated_eq X t] - -lemma deltaGenerated_mono {X : Type*} {t₁ t₂ : TopologicalSpace X} (h : t₁ ≤ t₂) : - @deltaGenerated X t₁ ≤ @deltaGenerated X t₂ := by - rw [← continuous_id_iff_le, @continuous_to_deltaGenerated _ _ - (@deltaGenerated X t₁) t₂ deltaGeneratedSpace_deltaGenerated id] - exact continuous_id_iff_le.2 <| (@deltaGenerated_le X t₁).trans h +@[deprecated (since := "2026-04-23")] +alias deltaGenerated_eq_coinduced := generatedBy_eq_coinduced -namespace DeltaGeneratedSpace +@[deprecated (since := "2026-04-23")] alias deltaGenerated_le := generatedBy_le -/-- Type synonym to be equipped with the delta-generated topology. -/ -def of (X : Type*) := X +@[deprecated (since := "2026-04-23")] +alias isOpen_deltaGenerated_iff := WithGeneratedByTopology.isOpen_iff -instance : TopologicalSpace (of X) := deltaGenerated X +@[deprecated (since := "2026-04-23")] +alias deltaGenerated_deltaGenerated_eq := generatedBy_generatedBy -instance : DeltaGeneratedSpace (of X) := - deltaGeneratedSpace_deltaGenerated +@[deprecated (since := "2026-04-23")] +alias eq_deltaGenerated := IsGeneratedBy.generatedBy_eq -/-- The natural map from `DeltaGeneratedSpace.of X` to `X`. -/ -def counit : (of X) → X := id +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.isOpen_iff := IsGeneratedBy.isOpen_iff -lemma continuous_counit : Continuous (counit : _ → X) := by - rw [continuous_iff_coinduced_le]; exact deltaGenerated_le +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.continuous_iff := IsGeneratedBy.continuous_iff -/-- Delta-generated spaces are locally path-connected. -/ -instance [DeltaGeneratedSpace X] : LocPathConnectedSpace X := by - rw [eq_deltaGenerated (X := X), deltaGenerated_eq_coinduced] - exact LocPathConnectedSpace.coinduced _ +@[deprecated (since := "2026-04-23")] +alias continuous_to_deltaGenerated := WithGeneratedByTopology.continuous_equiv -/-- Delta-generated spaces are sequential. -/ -instance [DeltaGeneratedSpace X] : SequentialSpace X := by - rw [eq_deltaGenerated (X := X)] - exact SequentialSpace.iSup fun p ↦ SequentialSpace.coinduced p.2 +@[deprecated (since := "2026-04-23")] +alias deltaGeneratedSpace_deltaGenerated := IsGeneratedBy.instWithGeneratedByTopology -end DeltaGeneratedSpace +@[deprecated (since := "2026-04-23")] +alias deltaGenerated_mono := generatedBy_mono + +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.counit := WithGeneratedByTopology.equiv + +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.continuous_counit := WithGeneratedByTopology.continuous_equiv + +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.coinduced := IsGeneratedBy.coinduced + +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.iSup := IsGeneratedBy.iSup + +@[deprecated (since := "2026-04-23")] +alias DeltaGeneratedSpace.sup := IsGeneratedBy.sup + +@[deprecated (since := "2026-04-23")] +alias Topology.IsQuotientMap.deltaGeneratedSpace := Topology.IsQuotientMap.isGeneratedBy + +@[deprecated (since := "2026-04-23")] +alias Quot.deltaGeneratedSpace := Quot.isGeneratedBy + +@[deprecated (since := "2026-04-23")] +alias Quotient.deltaGeneratedSpace := Quotient.isGeneratedBy + +@[deprecated (since := "2026-04-23")] +alias Sum.deltaGeneratedSpace := Sum.isGeneratedBy -omit tY in -/-- Any topology coinduced by a delta-generated topology is delta-generated. -/ -lemma DeltaGeneratedSpace.coinduced [DeltaGeneratedSpace X] (f : X → Y) : - @DeltaGeneratedSpace Y (tX.coinduced f) := - let _ := tX.coinduced f - ⟨(continuous_to_deltaGenerated.2 continuous_coinduced_rng).coinduced_le⟩ - -/-- Suprema of delta-generated topologies are delta-generated. -/ -protected lemma DeltaGeneratedSpace.iSup {X : Type*} {ι : Sort*} {t : ι → TopologicalSpace X} - (h : ∀ i, @DeltaGeneratedSpace X (t i)) : @DeltaGeneratedSpace X (⨆ i, t i) := - let _ := ⨆ i, t i - ⟨iSup_le_iff.2 fun i ↦ (h i).le_deltaGenerated.trans <| deltaGenerated_mono <| le_iSup t i⟩ - -/-- Suprema of delta-generated topologies are delta-generated. -/ -protected lemma DeltaGeneratedSpace.sup {X : Type*} {t₁ t₂ : TopologicalSpace X} - (h₁ : @DeltaGeneratedSpace X t₁) (h₂ : @DeltaGeneratedSpace X t₂) : - @DeltaGeneratedSpace X (t₁ ⊔ t₂) := by - rw [sup_eq_iSup] - exact .iSup <| Bool.forall_bool.2 ⟨h₂, h₁⟩ - -/-- Quotients of delta-generated spaces are delta-generated. -/ -lemma Topology.IsQuotientMap.deltaGeneratedSpace [DeltaGeneratedSpace X] - {f : X → Y} (h : IsQuotientMap f) : DeltaGeneratedSpace Y := - h.isCoinducing.eq_coinduced ▸ DeltaGeneratedSpace.coinduced f - -/-- Quotients of delta-generated spaces are delta-generated. -/ -instance Quot.deltaGeneratedSpace [DeltaGeneratedSpace X] {r : X → X → Prop} : - DeltaGeneratedSpace (Quot r) := - isQuotientMap_quot_mk.deltaGeneratedSpace - -/-- Quotients of delta-generated spaces are delta-generated. -/ -instance Quotient.deltaGeneratedSpace [DeltaGeneratedSpace X] {s : Setoid X} : - DeltaGeneratedSpace (Quotient s) := - isQuotientMap_quotient_mk'.deltaGeneratedSpace - -/-- Disjoint unions of delta-generated spaces are delta-generated. -/ -instance Sum.deltaGeneratedSpace [DeltaGeneratedSpace X] [DeltaGeneratedSpace Y] : - DeltaGeneratedSpace (X ⊕ Y) := - DeltaGeneratedSpace.sup (.coinduced Sum.inl) (.coinduced Sum.inr) - -/-- Disjoint unions of delta-generated spaces are delta-generated. -/ -instance Sigma.deltaGeneratedSpace {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] - [∀ i, DeltaGeneratedSpace (X i)] : DeltaGeneratedSpace (Σ i, X i) := - .iSup fun _ ↦ .coinduced _ +@[deprecated (since := "2026-04-23")] +alias Sigma.deltaGeneratedSpace := Sigma.isGeneratedBy diff --git a/Mathlib/Topology/Convenient/Category.lean b/Mathlib/Topology/Convenient/Category.lean index e071b214b5b54f..fdde8314b14324 100644 --- a/Mathlib/Topology/Convenient/Category.lean +++ b/Mathlib/Topology/Convenient/Category.lean @@ -5,8 +5,8 @@ Authors: Joël Riou -/ module -public import Mathlib.CategoryTheory.Adjunction.FullyFaithful -public import Mathlib.Topology.Category.TopCat.Basic +public import Mathlib.CategoryTheory.Monad.Limits +public import Mathlib.Topology.Category.TopCat.Limits.Basic public import Mathlib.Topology.Convenient.ContinuousMapGeneratedBy /-! @@ -37,7 +37,7 @@ structure on `GeneratedByTopCat X` under suitable assumptions (TODO @joelriou). universe v t u -open CategoryTheory Topology +open CategoryTheory Topology Limits variable {ι : Type t} (X : ι → Type u) [∀ i, TopologicalSpace (X i)] @@ -203,6 +203,9 @@ instance : (toTopCat.{v} X).IsLeftAdjoint := adj.isLeftAdjoint instance : (TopCat.toContinuousGeneratedByCat.{v} X).IsRightAdjoint := adj.isRightAdjoint +instance : (TopCat.toContinuousGeneratedByCat.{v} X).Faithful where + map_injective h := by ext x; exact ConcreteCategory.congr_hom h x + instance : IsIso (adj.{v} (X := X)).unit := inferInstanceAs (IsIso adjUnitIso.hom) /-- The functor `GeneratedByTopCat X ⥤ ContinuousGeneratedByCat X` which is @@ -307,4 +310,21 @@ instance (Z : TopCat.{v}) : inferInstanceAs (IsIso ((TopCat.toContinuousGeneratedByCat X).map (ContinuousGeneratedByCat.adj.counit.app Z))) +instance : (TopCat.toGeneratedByTopCat.{v} (X := X)).Faithful where + map_injective h := by ext x; exact ConcreteCategory.congr_hom h x + +/-- The category of `X`-generated spaces is coreflective in the category of topological spaces. -/ +instance : Coreflective (toTopCat.{v} (X := X)) where + R := TopCat.toGeneratedByTopCat + adj := adj + +noncomputable instance : CreatesColimits (toTopCat.{v} (X := X)) := + comonadicCreatesColimits _ + +instance : HasLimits (GeneratedByTopCat X) := + hasLimits_of_coreflective toTopCat + +instance : HasColimits (GeneratedByTopCat X) := + hasColimits_of_hasColimits_createsColimits toTopCat + end GeneratedByTopCat diff --git a/Mathlib/Topology/Convenient/GeneratedBy.lean b/Mathlib/Topology/Convenient/GeneratedBy.lean index 3dd6e77999c945..b7523666776849 100644 --- a/Mathlib/Topology/Convenient/GeneratedBy.lean +++ b/Mathlib/Topology/Convenient/GeneratedBy.lean @@ -51,6 +51,13 @@ by all continuous maps `X i → Y`. -/ def generatedBy : TopologicalSpace Y := ⨆ (i : ι) (f : C(X i, Y)), coinduced f inferInstance +/-- The `X`-generated topology is also coinduced by a single map out of a sigma type. -/ +lemma generatedBy_eq_coinduced : + generatedBy X (Y := Y) = + coinduced (fun (x : (f : (i : ι) × C(X i, Y)) × X f.1) ↦ x.1.2 x.2) inferInstance := by + rw [generatedBy, instTopologicalSpaceSigma, coinduced_iSup, iSup_sigma] + rfl + end TopologicalSpace variable {X} @@ -265,3 +272,7 @@ instance Sum.isGeneratedBy [IsGeneratedBy X Y] [IsGeneratedBy X Z] : instance Sigma.isGeneratedBy {κ : Type*} {Y : κ → Type*} [∀ k, TopologicalSpace (Y k)] [∀ k, IsGeneratedBy X (Y k)] : IsGeneratedBy X (Σ k, Y k) := .iSup fun _ ↦ .coinduced _ + +lemma TopologicalSpace.generatedBy_generatedBy (Y : Type*) [TopologicalSpace Y] : + generatedBy X (tY := generatedBy X) = generatedBy X (Y := Y):= + IsGeneratedBy.generatedBy_eq (X := X) (Y := WithGeneratedByTopology X Y) From 5c73b0cd146b6b4bf4d7f5fe1ed7e721d19d8cde Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:22:24 +0000 Subject: [PATCH 0143/1300] feat: `Sum.inl` and `Sum.inr` are smooth embeddings (#40507) This provides an alternative proof of their smoothness. A future PR will use this to golf the existing proofs. Inspired by in-person discussions with Christian Merten and Edward van de Meent. --- Mathlib/Geometry/Manifold/Immersion.lean | 29 +++++++++++++++++++ .../Geometry/Manifold/SmoothEmbedding.lean | 12 ++++++++ 2 files changed, 41 insertions(+) diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index 7ab117455ac9af..852f775a9a4acd 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -54,6 +54,8 @@ This shortens the overall argument, as the definition of submersions has the sam * `IsImmersion.id`: the identity map is an immersion * `IsImmersion.of_opens`: the inclusion of an open subset `s → M` of a smooth manifold is a smooth immersion +* `IsImmersionOfComplement.sumInl` and `IsImmersionOfComplement.sumInr`: given `C^n` manifolds + `M` and `N`, `Sum.inl : M → M ⊕ N` and `Sum.inr : N → M ⊕ N` are `C^n` immersions * `IsImmersionAt.contMDiffAt`: if f is an immersion at `x`, it is `C^n` at `x`. * `IsImmersion.contMDiff`: if f is a `C^n` immersion, it is automatically `C^n` in the sense of `ContMDiff`. @@ -615,6 +617,7 @@ In other words, `f` is an immersion at each `x ∈ M`. This definition has a fixed parameter `F`, which is a choice of complement of `E` in `E'`: being an immersion at `x` includes a choice of linear isomorphism between `E × F` and `E'`. -/ +@[expose] def IsImmersionOfComplement (f : M → N) : Prop := ∀ x, IsImmersionAtOfComplement F I J n f x variable (I J n) in @@ -696,6 +699,32 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) : IsImmersionOfComplement PUnit I I n (Subtype.val : s → M) := fun y ↦ IsImmersionAtOfComplement.of_opens s y +/-- Given `C^n` manifolds `M` and `N` over the same model `I`, +`Sum.inl : M → M ⊕ N` is a `C^n` immersion with complement `Unit` -/ +lemma sumInl {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] [IsManifold I n M] + [IsManifold I n M'] : IsImmersionOfComplement Unit I I n (@Sum.inl M M') := by + intro x + apply IsImmersionAtOfComplement.mk_of_continuousAt (equiv := (.prodUnique 𝕜 E _)) + (by fun_prop) _ _ (mem_chart_source H x) (mem_chart_source H (Sum.inl x)) + (IsManifold.chart_mem_maximalAtlas x) (IsManifold.chart_mem_maximalAtlas (Sum.inl x)) + intro y hy + have : I ((chartAt H x) ((chartAt H x).symm (I.symm y))) = y := by + rw [(chartAt H x).right_inv (by simp_all), I.right_inv (by simp_all)] + simpa + +/-- Given `C^n` manifolds `M` and `N` over the same model `I`, +`Sum.inr : N → M ⊕ N` is a `C^n` immersion with complement `Unit` -/ +lemma sumInr {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] [IsManifold I n M] + [IsManifold I n M'] : IsImmersionOfComplement Unit I I n (@Sum.inr M M') := by + intro x + apply IsImmersionAtOfComplement.mk_of_continuousAt (equiv := (.prodUnique 𝕜 E _)) + (by fun_prop) _ _ (mem_chart_source H x) (mem_chart_source H (Sum.inr x)) + (IsManifold.chart_mem_maximalAtlas x) (IsManifold.chart_mem_maximalAtlas (Sum.inr x)) + intro y hy + have : I ((chartAt H x) ((chartAt H x).symm (I.symm y))) = y := by + rw [(chartAt H x).right_inv (by simp_all), I.right_inv (by simp_all)] + simpa + @[deprecated (since := "2025-12-16")] alias ofOpen := of_opens /-- A `C^n` immersion is `C^n`. -/ diff --git a/Mathlib/Geometry/Manifold/SmoothEmbedding.lean b/Mathlib/Geometry/Manifold/SmoothEmbedding.lean index da93f47ed144a8..14656f059daa50 100644 --- a/Mathlib/Geometry/Manifold/SmoothEmbedding.lean +++ b/Mathlib/Geometry/Manifold/SmoothEmbedding.lean @@ -22,6 +22,8 @@ This will be useful to define embedded submanifolds. * `IsSmoothEmbedding.id`: the identity map is a smooth embedding * `IsSmoothEmbedding.of_opens`: the inclusion of an open subset `s → M` of a smooth manifold is a smooth embedding +* `IsSmoothEmbedding.sumInl` and `IsSmoothEmbedding.sumInr`: given `C^n` manifolds `M` and `N`, + `Sum.inl : M → M ⊕ N` and `Sum.inr : N → M ⊕ N` are `C^n` embeddings * `IsSmoothEmbedding.contMDiff`: if `f` is a `C^n` embedding, it is automatically `C^n` in the sense of `ContMDiff`. @@ -92,6 +94,16 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) : rw [isSmoothEmbedding_iff] exact ⟨IsImmersion.of_opens s, IsEmbedding.subtypeVal⟩ +/-- Given `C^n` manifolds `M` and `N`, `Sum.inl : M → M ⊕ N` is a `C^n` embedding. -/ +lemma sumInl {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] + [IsManifold I n M] [IsManifold I n M'] : IsSmoothEmbedding I I n (@Sum.inl M M') := + ⟨IsImmersionOfComplement.sumInl.isImmersion, Topology.IsEmbedding.inl⟩ + +/-- Given `C^n` manifolds `M` and `N`, `Sum.inr : N → M ⊕ N` is a `C^n` embedding. -/ +lemma sumInr {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] + [IsManifold I n M] [IsManifold I n M'] : IsSmoothEmbedding I I n (@Sum.inr M M') := + ⟨IsImmersionOfComplement.sumInr.isImmersion, Topology.IsEmbedding.inr⟩ + /-- A smooth embedding is automatically smooth. -/ lemma contMDiff (hf : IsSmoothEmbedding I J n f) : ContMDiff I J n f := From 4176265817544b3530eca07e02a704b0316f2ab8 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:22:27 +0000 Subject: [PATCH 0144/1300] chore(Algebra/Module/ZLattice/Summable): automated extraction from #39646 (#40752) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Author: Yaël Dillies Co-authored-by: YaelDillies <14090593+YaelDillies@users.noreply.github.com> --- Mathlib/Algebra/Module/ZLattice/Summable.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Module/ZLattice/Summable.lean b/Mathlib/Algebra/Module/ZLattice/Summable.lean index 3e39537c3564fd..243715f9a2b4f2 100644 --- a/Mathlib/Algebra/Module/ZLattice/Summable.lean +++ b/Mathlib/Algebra/Module/ZLattice/Summable.lean @@ -147,9 +147,7 @@ lemma sum_piFinset_Icc_rpow_le {ι : Type*} [Fintype ι] [DecidableEq ι] rw [← Real.rpow_natCast, ← Real.rpow_add (by positivity), Nat.cast_sub hd] norm_cast _ ≤ 2 * d * 3 ^ (d - 1) * ε ^ r * ∑ k ∈ range (n + 1), (k : ℝ) ^ (d - 1 + r) := by - gcongr - rw [Finset.sum_range_succ', le_add_iff_nonneg_right] - positivity + grw [Finset.sum_range_succ', Nat.cast_zero, ← Real.rpow_nonneg le_rfl, add_zero] _ ≤ 2 * d * 3 ^ (d - 1) * ε ^ r * ∑' k : ℕ, (k : ℝ) ^ (d - 1 + r) := by gcongr refine Summable.sum_le_tsum _ (fun _ _ ↦ by positivity) (Real.summable_nat_rpow.mpr ?_) From 6b7272bed994cfedecc3ced84af38dc922cab594 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:56:57 +0000 Subject: [PATCH 0145/1300] =?UTF-8?q?perf:=20add=20a=20shortcut=20instance?= =?UTF-8?q?=20for=20`=E2=84=A4=E1=B5=90=E2=81=B0`=20(#40750)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/abbrev.20causes.20unfolding/with/604081047 --- Mathlib/Algebra/Order/GroupWithZero/Canonical.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index c7ac6009323965..94095610485d23 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -520,6 +520,9 @@ instance instLinearOrderedCommMonoidWithZero [CommMonoid α] [LinearOrder α] instance instLinearOrderedCommGroupWithZero [CommGroup α] [LinearOrder α] [IsOrderedMonoid α] : LinearOrderedCommGroupWithZero (WithZero α) where +-- Add a shortcut instance for the common case, to speed up unification. +instance : LinearOrderedCommGroupWithZero ℤᵐ⁰ := inferInstance + /-! ### Exponential and logarithm -/ variable {G : Type*} [Preorder G] {a b : G} From c980ea08a8b62ae08897917a968d99906e8be719 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 18 Jun 2026 13:40:23 +0000 Subject: [PATCH 0146/1300] feat(Combinatorics/SimpleGraph/Sum): `edgeSet` equivalence (#36099) --- Mathlib/Combinatorics/SimpleGraph/Sum.lean | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Sum.lean b/Mathlib/Combinatorics/SimpleGraph/Sum.lean index d31abcd13e4d58..349388d30ddf97 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Sum.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Sum.lean @@ -45,6 +45,12 @@ protected def sum (G : SimpleGraph V) (H : SimpleGraph W) : SimpleGraph (V ⊕ W @[inherit_doc] infixl:60 " ⊕g " => SimpleGraph.sum +theorem sum_adj_inl : (G ⊕g H).Adj (.inl v) (.inl v') ↔ G.Adj v v' := by + simp + +theorem sum_adj_inr : (G ⊕g H).Adj (.inr w) (.inr w') ↔ H.Adj w w' := by + simp + /-- The disjoint sum is commutative up to isomorphism. `Iso.sumComm` as a graph isomorphism. -/ @[simps!] def Iso.sumComm : G ⊕g H ≃g H ⊕g G := ⟨Equiv.sumComm V W, by @@ -126,6 +132,23 @@ lemma Iso.sumAssoc_comp_sumCongr (f : G ≃g G') (g : H ≃g H') (h : I ≃g I') comp sumAssoc (sumCongr (sumCongr f g) h) = comp (sumCongr f (sumCongr g h)) sumAssoc := by ext ((v | w) | u) <;> simp +/-- The edges of the disjoint sum of `G` and `H` are in bijection with +the disjoint sum of the edges of `G` and the edges of `H` -/ +def edgeSetSumEquiv : (G ⊕g H).edgeSet ≃ G.edgeSet ⊕ H.edgeSet where + toFun := + fun ⟨e, he⟩ ↦ e.fromRelNdrec (sym := symm _) he (fun + | Sum.inl u, Sum.inl v, h => .inl ⟨s(u, v), h⟩ + | Sum.inr u, Sum.inr v, h => .inr ⟨s(u, v), h⟩ + | Sum.inl u, Sum.inr v, h => by contradiction + | Sum.inr u, Sum.inl v, h => by contradiction + ) (by grind) + invFun + | Sum.inl ⟨e, he⟩ => + e.fromRelNdrec (sym := G.symm) he (fun u v h ↦ ⟨s(.inl u, .inl v), h⟩) <| by simp + | Sum.inr ⟨e, he⟩ => + e.fromRelNdrec (sym := H.symm) he (fun u v h ↦ ⟨s(.inr u, .inr v), h⟩) <| by simp + left_inv := by rintro ⟨⟨u | u, v | v⟩, h⟩ <;> first | contradiction | rfl + right_inv := by rintro (⟨⟨u, v⟩, h⟩ | ⟨⟨u, v⟩, h⟩) <;> rfl lemma not_adj_sum_inl_inr (v w) : ¬(G ⊕g H).Adj (.inl v) (.inr w) := by simp From 1f813eaf7a039c9f8d49d6dd727cdecdef970f25 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Thu, 18 Jun 2026 13:40:25 +0000 Subject: [PATCH 0147/1300] refactor(Analysis): golf `Mathlib/Analysis/Normed/Operator/ContinuousLinearMap` (#39896) - refactors `Normed/Operator/ContinuousLinearMap` by reusing `mkContinuous` in bounded linear continuity proofs and shortening `homothety_inverse` Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- .../Normed/Operator/ContinuousLinearMap.lean | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean b/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean index 5eaecf831a2ed2..7cbae9947bc753 100644 --- a/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean +++ b/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean @@ -75,11 +75,7 @@ theorem continuous_of_linear_of_boundₛₗ {f : E → F} (h_add : ∀ x y, f (x theorem continuous_of_linear_of_bound {f : E → G} (h_add : ∀ x y, f (x + y) = f x + f y) (h_smul : ∀ (c : 𝕜) (x), f (c • x) = c • f x) {C : ℝ} (h_bound : ∀ x, ‖f x‖ ≤ C * ‖x‖) : Continuous f := - let φ : E →ₗ[𝕜] G := - { toFun := f - map_add' := h_add - map_smul' := h_smul } - AddMonoidHomClass.continuous_of_bound φ C h_bound + continuous_of_linear_of_boundₛₗ (σ := RingHom.id 𝕜) h_add h_smul h_bound @[simp, norm_cast] theorem LinearMap.mkContinuous_coe (C : ℝ) (h : ∀ x, ‖f x‖ ≤ C * ‖x‖) : @@ -186,11 +182,7 @@ variable {σ₂₁ : 𝕜₂ →+* 𝕜} [RingHomInvPair σ σ₂₁] [RingHomIn theorem ContinuousLinearEquiv.homothety_inverse (a : ℝ) (ha : 0 < a) (f : E ≃ₛₗ[σ] F) : (∀ x : E, ‖f x‖ = a * ‖x‖) → ∀ y : F, ‖f.symm y‖ = a⁻¹ * ‖y‖ := by intro hf y - calc - ‖f.symm y‖ = a⁻¹ * (a * ‖f.symm y‖) := by - rw [← mul_assoc, inv_mul_cancel₀ (ne_of_lt ha).symm, one_mul] - _ = a⁻¹ * ‖f (f.symm y)‖ := by rw [hf] - _ = a⁻¹ * ‖y‖ := by simp + simpa [eq_inv_mul_iff_mul_eq₀ (ne_of_gt ha)] using (hf (f.symm y)).symm /-- A linear equivalence which is a homothety is a continuous linear equivalence. -/ noncomputable def ContinuousLinearEquiv.ofHomothety (f : E ≃ₛₗ[σ] F) (a : ℝ) (ha : 0 < a) From b446f18f2b42f7089c28a174015062fd92476367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20G=C3=B3mez=20Zaragoza?= <51706873+javgomzar@users.noreply.github.com> Date: Thu, 18 Jun 2026 13:40:28 +0000 Subject: [PATCH 0148/1300] chore: typo in submersion docstring (#40756) Typo in the definition of C^n submersions. Co-authored-by: Javier Gomez Zaragoza --- Mathlib/Geometry/Manifold/Submersion.lean | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Submersion.lean b/Mathlib/Geometry/Manifold/Submersion.lean index 46a6531defd097..af48f831ada3a6 100644 --- a/Mathlib/Geometry/Manifold/Submersion.lean +++ b/Mathlib/Geometry/Manifold/Submersion.lean @@ -330,8 +330,8 @@ lemma _root_.isOpen_isSubmersionAtOfComplement : exact IsOpen.liftSourceTargetPropertyAt set_option backward.isDefEq.respectTransparency false in -/-- If `f: M → N` and `g: M' × N'` are submersions at `x` and `x'`, respectively, -then `f × g: M × N → M' × N'` is a submersion at `(x, x')`. -/ +/-- If `f: M → N` and `g: M' → N'` are submersions at `x` and `x'`, respectively, +then `f × g: M × M' → N × N'` is a submersion at `(x, x')`. -/ theorem prodMap {f : M → N} {g : M' → N'} {x' : M'} [IsManifold I n M] [IsManifold I' n M'] [IsManifold J n N] [IsManifold J' n N'] (hf : IsSubmersionAtOfComplement F I J n f x) @@ -483,8 +483,8 @@ lemma _root_.isOpen_isSubmersionAt : fun y hy ↦ hy.isSubmersionAt, isOpen_isSubmersionAtOfComplement, by simp [hx.isSubmersionAtOfComplement_complement]⟩ -/-- If `f: M → N` and `g: M' × N'` are submersions at `x` and `x'`, respectively, -then `f × g: M × N → M' × N'` is a submersion at `(x, x')`. -/ +/-- If `f: M → N` and `g: M' → N'` are submersions at `x` and `x'`, respectively, +then `f × g: M × M' → N × N'` is a submersion at `(x, x')`. -/ theorem prodMap {f : M → N} {g : M' → N'} {x' : M'} [IsManifold I n M] [IsManifold I' n M'] [IsManifold J n N] [IsManifold J' n N'] (hf : IsSubmersionAt I J n f x) (hg : IsSubmersionAt I' J' n g x') : @@ -539,8 +539,8 @@ lemma congr_F (e : F ≃L[𝕜] F') : IsSubmersionOfComplement F I J n f ↔ IsSubmersionOfComplement F' I J n f := ⟨fun h ↦ trans_F (e := e) h, fun h ↦ trans_F (e := e.symm) h⟩ -/-- If `f: M → N` and `g: M' × N'` are submersions at `x` and `x'` (w.r.t. `F` and `F'`), -respectively, then `f × g: M × N → M' × N'` is a submersion at `(x, x')` w.r.t. `F × F'`. -/ +/-- If `f: M → N` and `g: M' → N'` are submersions at `x` and `x'` (w.r.t. `F` and `F'`), +respectively, then `f × g: M × M' → N × N'` is a submersion at `(x, x')` w.r.t. `F × F'`. -/ theorem prodMap {f : M → N} {g : M' → N'} [IsManifold I n M] [IsManifold I' n M'] [IsManifold J n N] [IsManifold J' n N'] (h : IsSubmersionOfComplement F I J n f) (h' : IsSubmersionOfComplement F' I' J' n g) : @@ -602,8 +602,8 @@ lemma isSubmersionAt (h : IsSubmersion I J n f) (x : M) : IsSubmersionAt I J n f use h.complement, by infer_instance, by infer_instance exact h.isSubmersionOfComplement_complement x -/-- If `f: M → N` and `g: M' × N'` are submersions at `x` and `x'`, respectively, -then `f × g: M × N → M' × N'` is a submersion at `(x, x')`. -/ +/-- If `f: M → N` and `g: M' → N'` are submersions at `x` and `x'`, respectively, +then `f × g: M × M' → N × N'` is a submersion at `(x, x')`. -/ theorem prodMap {f : M → N} {g : M' → N'} [IsManifold I n M] [IsManifold I' n M'] [IsManifold J n N] [IsManifold J' n N'] (hf : IsSubmersion I J n f) (hg : IsSubmersion I' J' n g) : From 86c0c038136c86682e63a575e4326d521963aa2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20G=C3=B3mez=20Zaragoza?= <51706873+javgomzar@users.noreply.github.com> Date: Thu, 18 Jun 2026 14:48:01 +0000 Subject: [PATCH 0149/1300] feat(FinitelyPresentedGroup): comap of finitely generated normal subgroup (#40726) @tb65536 suggested this addition for the FinitelyPresentedGroup project in [#40200](https://github.com/leanprover-community/mathlib4/pull/40200). [#38114](https://github.com/leanprover-community/mathlib4/pull/38114) will also be simplified using this theorem. Co-authored-by: Javier Gomez Zaragoza --- Mathlib/Algebra/Group/Subgroup/Basic.lean | 13 ++++++++++ .../GroupTheory/FinitelyPresentedGroup.lean | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 0123582c1c283b..8d12154ce3c9d3 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -528,6 +528,13 @@ theorem conj_mem_conjugatesOfSet {x c : G} : rcases mem_conjugatesOfSet_iff.1 H with ⟨a, h₁, h₂⟩ exact mem_conjugatesOfSet_iff.2 ⟨a, h₁, h₂.trans (isConj_iff.2 ⟨c, rfl⟩)⟩ +/-- The set of conjugates of the union of two sets is the union of the conjugates -/ +@[to_additive /-- The set of additive conjugates of the union of two sets is the union +of the additive conjugates. -/] +theorem conjugatesOfSet_union {G : Type*} [Group G] (s t : Set G) : + conjugatesOfSet (s ∪ t) = conjugatesOfSet s ∪ conjugatesOfSet t := by + simp_rw [conjugatesOfSet, Set.biUnion_union] + end Group namespace Subgroup @@ -620,6 +627,12 @@ theorem normalClosure_closure_eq_normalClosure {s : Set G} : lemma normalClosure_empty : normalClosure (∅ : Set G) = (⊥ : Subgroup G) := by rw [← normalClosure_closure_eq_normalClosure, closure_empty, normalClosure_eq_self] +/-- The normal closure of the union of sets is the join of the normal closures of each set. -/ +@[to_additive] +theorem normalClosure_union {G : Type*} [Group G] (s t : Set G) : + normalClosure (s ∪ t) = normalClosure s ⊔ normalClosure t := by + simp_rw [normalClosure, Group.conjugatesOfSet_union, closure_union] + /-- The normal core of a subgroup `H` is the largest normal subgroup of `G` contained in `H`, as shown by `Subgroup.normalCore_eq_iSup`. -/ @[to_additive /-- The normal core of an additive subgroup `H` is the largest normal additive diff --git a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean index 244c014130652c..81cbeaebab1630 100644 --- a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean +++ b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean @@ -51,6 +51,23 @@ protected theorem map {N : Subgroup G} (hN : N.IsNormalClosureFG) refine ⟨f '' S, hSfinite.image _, ?_⟩ rw [← hSclosure, Subgroup.map_normalClosure _ _ hf] +open Function Set Subgroup in +/-- The preimage of a finitely generated normal subgroup by a surjective homomorphism with +a finitely generated kernel is finitely generated. -/ +@[to_additive /-- The preimage of a finitely generated normal subgroup by a surjective additive +homomorphism with a finitely generated kernel is finitely generated. -/] +protected theorem comap {N : Subgroup H} (hN : N.IsNormalClosureFG) + {f : G →* H} (hf : Surjective f) (hf' : f.ker.IsNormalClosureFG) : + (N.comap f).IsNormalClosureFG := by + obtain ⟨S, hS_fin, hS⟩ := hN + obtain ⟨T, hT_fin, hT⟩ := hf' + have : ∃ S', S'.Finite ∧ f '' S' = S := + ⟨surjInv hf '' S, hS_fin.image _, by rw [← image_comp, comp_surjInv, image_id]⟩ + clear hS_fin + obtain ⟨S, hS_fin, rfl⟩ := this + refine ⟨S ∪ T, hS_fin.union hT_fin, ?_⟩ + rw [← hS, ← map_normalClosure S f hf, comap_map_eq, ← hT, normalClosure_union] + /-- The trivial group is the normal closure of a finite set of relations. -/ @[to_additive /-- The trivial additive group is the normal closure of a finite set of relations. -/] protected theorem bot : (⊥ : Subgroup G).IsNormalClosureFG := @@ -81,6 +98,14 @@ theorem equiv (iso : G ≃* H) (h : IsFinitelyPresented G) : IsFinitelyPresented refine ⟨n, (iso : G →* H).comp φ, iso.surjective.comp hφsurj, ?_⟩ rwa [φ.ker_mulEquiv_comp iso] +theorem of_surjective [hG : IsFinitelyPresented G] (f : G →* H) + (hf_surj : Function.Surjective f) (hf_ker : f.ker.IsNormalClosureFG) : + IsFinitelyPresented H := by + obtain ⟨n, φ, hφ_surj, hφ_ker⟩ := hG.out + refine ⟨n, f.comp φ, hf_surj.comp hφ_surj, ?_⟩ + rw [← MonoidHom.comap_ker] + exact hf_ker.comap hφ_surj hφ_ker + /-- A free group with a finite number of generators is finitely presented. -/ @[to_additive /-- A free additive group with a finite number of generators is finitely presented. -/ ] From fbf0644640719705c7dbfbf3fa9df21844858fd6 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 18 Jun 2026 15:54:37 +0000 Subject: [PATCH 0150/1300] ci: self-heal nightly-testing-green after a history rewrite (#40586) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR makes the `nightly-testing-green` update in `nightly_detect_failure.yml` recover from a history rewrite instead of freezing. The branch is advanced with a plain fast-forward push, which is rejected once `nightly-testing` history diverges from its tip (for example a toolchain reset to an rc). #38847 dropped the original `git push --force` and deferred recovery to a daily force-push job that does not exist, so the branch stuck on `v4.31.0-rc1` for weeks until it was force-pushed by hand. Fast-forward when possible, and otherwise force-push to recover, but only when the tested commit is strictly newer than the current tip by committer date, so an out-of-order CI completion can never roll the branch backwards. `nightly-testing-daily` keeps its fast-forward-or-skip behavior, and the stale comment referencing the nonexistent force-push job is corrected. 🤖 Prepared with Claude Code --- .github/workflows/nightly_detect_failure.yml | 38 +++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/workflows/nightly_detect_failure.yml b/.github/workflows/nightly_detect_failure.yml index caad2ec4c0811d..8a2010877288a3 100644 --- a/.github/workflows/nightly_detect_failure.yml +++ b/.github/workflows/nightly_detect_failure.yml @@ -133,11 +133,27 @@ jobs: - name: Update the nightly-testing-green branch continue-on-error: true run: | - # The `nightly-testing-green` branch keeps a record of the successfully built commits on `nightly-testing`. - # This is allowed to fail, because it might happen that an earlier commit finishes CI later, - # we don't want to force push and revert the history. - # In case `nightly-testing` does have its history rewritten, we do a force push once a day. - git push origin HEAD:nightly-testing-green + # `nightly-testing-green` records the latest successfully built `nightly-testing` commit; + # live.lean-lang.org and the prebuilt CI tools read from it. Normally a fast-forward, but + # if `nightly-testing`'s history is rewritten (e.g. a toolchain reset to an rc) the branch + # diverges and a plain push is rejected forever, freezing it. Recover by force-pushing, but + # only when the tested commit is strictly newer than the current tip (by committer date), so + # an out-of-order CI completion (older commit finishing after a newer one) can't roll back. + if git push origin HEAD:nightly-testing-green; then + exit 0 + fi + git fetch origin nightly-testing-green + tip="$(git rev-parse FETCH_HEAD)" + head_ct="$(git show -s --format=%ct HEAD)" + tip_ct="$(git show -s --format=%ct "$tip")" + if git merge-base --is-ancestor HEAD "$tip"; then + echo "nightly-testing-green is ahead of the tested commit; leaving it alone." + elif (( head_ct > tip_ct )); then + echo "nightly-testing-green diverged; force-pushing to the newer tested commit." + git push --force-with-lease=refs/heads/nightly-testing-green:"$tip" origin HEAD:nightly-testing-green + else + echo "nightly-testing-green is newer than the tested commit; leaving it alone." + fi - name: Create a nightly-testing-YYYY-MM-DD tag id: tag run: | @@ -162,14 +178,12 @@ jobs: exit 1 fi fi - # Fast-forward `nightly-testing-daily` and `nightly-testing-green` to the tested SHA. - # Since we now pin to the SHA whose CI succeeded (which may be older than the current - # tip of `nightly-testing` if a CI run for an older commit finishes after a newer one), - # we must NOT force-push here, or we'd roll the tracking branches backwards. - # If the push isn't a fast-forward, leave the branch alone; the daily force-push - # job handles the rare case where `nightly-testing` history has been rewritten. + # Fast-forward `nightly-testing-daily` to the tested SHA. We pin to the SHA whose CI + # succeeded, which may be older than the current `nightly-testing` tip if an older + # commit's CI finishes after a newer one's, so don't force-push here or we'd roll the + # branch backwards. (`nightly-testing-green` is advanced, with recovery from a history + # rewrite, by the `Update the nightly-testing-green branch` step above.) git push origin HEAD:nightly-testing-daily || echo "Skipping nightly-testing-daily update: not a fast-forward." - git push origin HEAD:nightly-testing-green || echo "Skipping nightly-testing-green update: not a fast-forward." hash="$(git rev-parse "nightly-testing-${version}")" curl -X POST "https://speed.lean-lang.org/mathlib4/api/queue/commit/e7b27246-a3e6-496a-b552-ff4b45c7236e/$hash" -u "admin:${{ secrets.SPEED }}" fi From 9808d392b10a1a0d349a63b635ef5cbe13c5d2a4 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:07:25 +0000 Subject: [PATCH 0151/1300] feat(Algebra/Homology): add `Exact.isZero_of_both_isZero` (#40758) Add `CategoryTheory.ShortComplex.Exact.isZero_of_both_isZero`, a variant of `ShortComplex.Exact.isZero_of_both_zeros` would be useful in long exact sequence. --- Mathlib/Algebra/Homology/ShortComplex/Exact.lean | 6 ++++++ Mathlib/CategoryTheory/ObjectProperty/Extensions.lean | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index f02dbe63a3ce37..fee0ba6b919258 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -261,6 +261,12 @@ lemma Exact.isZero_of_both_zeros (ex : S.Exact) (hf : S.f = 0) (hg : S.g = 0) : IsZero S.X₂ := (ShortComplex.HomologyData.ofZeros S hf hg).exact_iff.1 ex +/-- In an exact short complex, if the two outer objects are zero objects, then so is the +middle object. -/ +lemma Exact.isZero_of_both_isZero (ex : S.Exact) (hX₁ : IsZero S.X₁) (hX₃ : IsZero S.X₃) : + IsZero S.X₂ := + ex.isZero_of_both_zeros (hX₁.eq_zero_of_src _) (hX₃.eq_zero_of_tgt _) + end section Preadditive diff --git a/Mathlib/CategoryTheory/ObjectProperty/Extensions.lean b/Mathlib/CategoryTheory/ObjectProperty/Extensions.lean index 7bdf56218c1788..a006f41f609248 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Extensions.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Extensions.lean @@ -52,7 +52,7 @@ instance : (⊤ : ObjectProperty C).IsClosedUnderExtensions where instance : IsClosedUnderExtensions (IsZero (C := C)) where prop_X₂_of_shortExact hS h₁ h₃ := - hS.exact.isZero_of_both_zeros (h₁.eq_of_src _ _) (h₃.eq_of_tgt _ _) + hS.exact.isZero_of_both_isZero h₁ h₃ instance [P.IsClosedUnderExtensions] (F : D ⥤ C) [HasZeroMorphisms D] [F.PreservesZeroMorphisms] From c4b0d8e362fe47e8b2356c9e34b121990cfa21d2 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky <5342086+pechersky@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:25:49 +0000 Subject: [PATCH 0152/1300] feat(Algebra/Group/WithOne): `lift_symm_injective_of_injective` (#40691) `WithOne.lift.symm` preserves injectivity (it is functorial) --- Mathlib/Algebra/Group/WithOne/Basic.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Algebra/Group/WithOne/Basic.lean b/Mathlib/Algebra/Group/WithOne/Basic.lean index c3ce8cae26ec97..165315cf6d0ddc 100644 --- a/Mathlib/Algebra/Group/WithOne/Basic.lean +++ b/Mathlib/Algebra/Group/WithOne/Basic.lean @@ -76,6 +76,11 @@ theorem lift_unique (f : WithOne α →* β) : f = lift (f.toMulHom.comp coeMulH @[to_additive (attr := simp)] theorem lift_symm_apply (f : WithOne α →* β) (x : α) : lift.symm f x = f x := rfl +@[to_additive] +lemma lift_symm_injective_of_injective {f : WithOne α →* β} (hf : Function.Injective f) : + Function.Injective (lift.symm f) := + fun _ _ ↦ by simp [hf.eq_iff] + end lift section Map From 9aac62798eba680875a3baaead1b3d96db7a1c86 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Thu, 18 Jun 2026 17:15:56 +0000 Subject: [PATCH 0153/1300] fix(cache): correct the marker probe on Windows, add Windows test (#40767) On Windows, `cache query` and the "HEAD not built by CI" note always report no cache, even though the commit is cached and `cache get` downloads it. `probeContainerForSHA` discards curl's output to `/dev/null`, which isn't a valid path on Windows, so curl exits non-zero and the probe reads every marker as absent. The fix is to use a platform null device (`NUL` on Windows) in the probe. Also adds a `windows-latest` leg to the cache-test workflow to catch such regressions. Follow-up to #40035 --- .github/workflows/cache_test.yml | 49 +++++++++++++++++++++++--------- Cache/IO.lean | 4 +++ Cache/Query.lean | 4 ++- Cache/Test.lean | 10 +++---- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/.github/workflows/cache_test.yml b/.github/workflows/cache_test.yml index ecf1b87a9cf864..3348e82783dbce 100644 --- a/.github/workflows/cache_test.yml +++ b/.github/workflows/cache_test.yml @@ -1,8 +1,9 @@ -# Runs the cache tool's unit tests (`lake exe cache-test`) on PRs that touch -# the cache code. The suite is deliberately network-free (see the module -# docstring in `Cache/Test.lean`), so the job only needs the toolchain and the -# package dependencies' sources — not a Mathlib build — and finishes in a few -# minutes on a hosted runner. +# Runs the cache tool's unit tests (`lake exe cache-test`) on Linux and Windows +# for PRs that touch the cache code. The suite is deliberately network-free (see +# the module docstring in `Cache/Test.lean`), so the job only needs the toolchain +# and the package dependencies' sources — not a Mathlib build — and finishes in a +# few minutes on a hosted runner. The Windows job guards the tool's cross-platform +# behavior, such as the null device the marker probe and tests discard output to. name: cache tests on: @@ -13,6 +14,8 @@ on: # a bump can break the tool's compilation even with `Cache/` untouched. - 'lakefile.lean' - 'lean-toolchain' + # Re-run when the workflow itself changes. + - '.github/workflows/cache_test.yml' concurrency: group: cache-test-${{ github.ref }} @@ -24,20 +27,38 @@ permissions: jobs: cache-test: if: github.repository == 'leanprover-community/mathlib4' - runs-on: ubuntu-latest + strategy: + # Report both platforms even if one fails, so a Windows-only break is + # never hidden by a Linux failure (or vice versa). + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + # `leanprover/lean-action` installs elan from a bash step and adds it to the + # path in that shell's form, so the `lake` steps below must also run under + # bash (available on Windows runners as Git Bash) to find it. + defaults: + run: + shell: bash steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - - name: install elan - run: | - set -o pipefail - curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh - chmod +x elan-init.sh - ./elan-init.sh -y --default-toolchain none - echo "$HOME/.elan/bin" >> "${GITHUB_PATH}" + # Install elan and the toolchain cross-platform. Build/test/lint, the + # Mathlib cache, and the GitHub cache are all disabled, so this is a + # toolchain-only setup; the `lake` steps below then build and run just the + # `cache-test` target. (The GitHub cache cannot be written from fork PRs + # and buys little for this small build, so it stays off.) + - uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 + with: + auto-config: "false" + build: "false" + test: "false" + lint: "false" + use-mathlib-cache: "false" + use-github-cache: "false" - name: build cache-test run: lake build cache-test - name: run cache tests - run: .lake/build/bin/cache-test + run: lake exe cache-test diff --git a/Cache/IO.lean b/Cache/IO.lean index f5e6eac9485adf..c83b5752d383e2 100644 --- a/Cache/IO.lean +++ b/Cache/IO.lean @@ -82,6 +82,10 @@ def CURLBIN := def EXE := if System.Platform.isWindows then ".exe" else "" +/-- The platform's null device, for discarding a command's output: `NUL` on +Windows, `/dev/null` elsewhere. -/ +def nullDevice : String := if System.Platform.isWindows then "NUL" else "/dev/null" + def LAKEPACKAGESDIR : FilePath := ".lake" / "packages" diff --git a/Cache/Query.lean b/Cache/Query.lean index 147f1d16723b4e..8dd967501722be 100644 --- a/Cache/Query.lean +++ b/Cache/Query.lean @@ -86,9 +86,11 @@ billed as a Read op. def probeContainerForSHA (container : Container) (repo sha : String) : IO Bool := do let url := markerURL container repo sha + -- Discard the response body to the platform null device (`NUL` on Windows), + -- so curl reports a write error only on a genuine failure, not on every probe. let out ← IO.Process.output {cmd := (← IO.getCurl), - args := #["-s", "-o", "/dev/null", "-w", "%{http_code}", "-I", url], + args := #["-s", "-o", IO.nullDevice, "-w", "%{http_code}", "-I", url], cwd := "."} if out.exitCode != 0 then -- Network error; assume no cache at this SHA diff --git a/Cache/Test.lean b/Cache/Test.lean index 15bf2c1b701839..b620ffeefc079d 100644 --- a/Cache/Test.lean +++ b/Cache/Test.lean @@ -74,14 +74,14 @@ def assertEq (name expected actual : String) : IO Unit := do IO.eprintln s!" FAIL: {name}\n expected: {expected}\n actual: {actual}" failures.modify (· + 1) -/-- Run `action` with both stdout and stderr redirected to /dev/null. Restores -both on completion, including on exception. Apply this to every production code -call in tests so diagnostic prints never mix with test output, regardless of -whether the production code currently produces any. -/ +/-- Run `action` with both stdout and stderr redirected to the platform null +device. Restores both on completion, including on exception. Apply this to every +production code call in tests so diagnostic prints never mix with test output, +regardless of whether the production code currently produces any. -/ private def withSuppressedOutput (action : IO α) : IO α := do let savedOut ← IO.getStdout let savedErr ← IO.getStderr - let sink ← IO.FS.Handle.mk "/dev/null" IO.FS.Mode.append + let sink ← IO.FS.Handle.mk Cache.IO.nullDevice IO.FS.Mode.append let sinkStream := IO.FS.Stream.ofHandle sink -- `IO.setStdout`/`IO.setStderr` return the previous stream; we already saved it, -- so discard the return value here. From a912e82324c89ceb9b7f5741a2b481273264762b Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Thu, 18 Jun 2026 17:32:24 +0000 Subject: [PATCH 0154/1300] fix(cache): lowercase fork repo in cache blob paths (#40766) Azure Blob Storage paths are case-sensitive, but GitHub owner/repo names are not. CI uploads a fork's cache under its "canonical" (according to GitHub) repo name, while `cache get`/`query` derive the repo from a local git remote URL (often lowercased). Lowercase the repo path segment in `mkFileURL` and `markerURL` so uploads and downloads always meet at one key. Follow-up to #40035. --- Cache/Infra.lean | 11 +++++++++++ Cache/Marker.lean | 6 ++++-- Cache/Requests.lean | 4 ++++ Cache/Test.lean | 10 ++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Cache/Infra.lean b/Cache/Infra.lean index 3b133b2d1e3bd7..4bf54177c86d0f 100644 --- a/Cache/Infra.lean +++ b/Cache/Infra.lean @@ -24,6 +24,17 @@ def MATHLIBREPO := "leanprover-community/mathlib4" /-- The full name of the Mathlib nightly-testing GitHub repository. -/ def NIGHTLY_TESTING_REPO := "leanprover-community/mathlib4-nightly-testing" +/-- +Canonical form of a GitHub `owner/repo` name for use as a cache blob path +segment. + +GitHub treats owner and repository names case-insensitively, while Azure Blob +Storage paths are case-sensitive. Lowercasing yields one shared key whatever +capitalization a remote URL or the GitHub Actions context supplies, so a fork's +uploads and downloads always meet at the same path. +-/ +def normalizeRepo (repo : String) : String := repo.toLower + /-- Trust-classified Azure storage containers for the Mathlib cache. diff --git a/Cache/Marker.lean b/Cache/Marker.lean index 56a3e9d43def93..69f830eb0633b3 100644 --- a/Cache/Marker.lean +++ b/Cache/Marker.lean @@ -20,7 +20,9 @@ namespace Cache.Requests open System (FilePath) /-- -URL for the per-SHA marker blob: `{container}/m/{repo}/{sha}`. +URL for the per-SHA marker blob: `{container}/m/{repo}/{sha}`, where `repo` is +lowercased via `normalizeRepo` so the path is case-insensitive in the GitHub +owner/repo name. The marker is uploaded by `put-staged` as the last step when an upload is SHA-scoped (`MATHLIB_CACHE_REPO_SCOPE` set). Its presence at this URL @@ -29,7 +31,7 @@ indicates that the full `.ltar` upload completed for this commit, and lets a blob-listing call. -/ def markerURL (container : Container) (repo sha : String) : String := - s!"{container.azureURL}/m/{repo}/{sha}" + s!"{container.azureURL}/m/{normalizeRepo repo}/{sha}" /-- Upload a tiny marker blob to `/m/{repo}/{sha}` in the given container. The diff --git a/Cache/Requests.lean b/Cache/Requests.lean index 2b766e6fd7ba47..ddd52c5000ef8d 100644 --- a/Cache/Requests.lean +++ b/Cache/Requests.lean @@ -348,9 +348,13 @@ container (see `Container.flatPath`), not the repo: the same hash under `container` is `none` for the user-supplied `MATHLIB_CACHE_GET_URL` / `MATHLIB_CACHE_PUT_URL` URLs, where no container policy applies; the path then follows the repo directly — flat for `MATHLIBREPO`, prefixed otherwise. + +`repo` is lowercased via `normalizeRepo` so the repo-namespaced path is +case-insensitive in the GitHub owner/repo name. -/ def mkFileURL (container : Option Container) (repo containerURL fileName : String) (repoScope : Option String := none) : String := + let repo := normalizeRepo repo let flat := match container with | some c => c.flatPath repo | none => repo == MATHLIBREPO diff --git a/Cache/Test.lean b/Cache/Test.lean index b620ffeefc079d..93cb93991ec46a 100644 --- a/Cache/Test.lean +++ b/Cache/Test.lean @@ -279,6 +279,11 @@ def test_mkFileURL : IO Unit := do assertEq "scope is ignored on a flat legacy path" "https://lakecache.blob.core.windows.net/mathlib4/f/abc.ltar" (mkFileURL (some .legacy) MATHLIBREPO Container.legacy.azureURL "abc.ltar" (some "abc123def")) + -- The repo segment is lowercased, so a mixed-case GitHub owner resolves to the + -- same path whether it reaches the cache from CI or a local remote URL. + assertEq "fork repo is lowercased in the path" + "https://lakecache.blob.core.windows.net/mathlib4-forks/f/alice/mathlib4/abc.ltar" + (mkFileURL (some .forks) "Alice/Mathlib4" Container.forks.azureURL "abc.ltar") end MkFileURL @@ -476,6 +481,11 @@ def test_markerURL : IO Unit := do assertEq "marker URL respects the container base" "https://lakecache.blob.core.windows.net/mathlib4/m/someorg/mathlib4/sha9999" (markerURL .legacy "someorg/mathlib4" "sha9999") + -- The repo segment is lowercased, so an upload and a probe for the same fork + -- meet at one path regardless of how the owner name was capitalized. + assertEq "marker repo is lowercased in the path" + "https://lakecache.blob.core.windows.net/mathlib4-forks/m/alice/mathlib4/abc123" + (markerURL .forks "Alice/Mathlib4" "abc123") end Marker From bd5ddedec83813f0dab190d95173d44bcdee5258 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Thu, 18 Jun 2026 17:53:10 +0000 Subject: [PATCH 0155/1300] fix(cache): cross-repo PRs from the nightly-testing fork (#40770) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A PR opened from the `mathlib4-nightly-testing` fork into mathlib4 (e.g. #40732, a `bump/*` toolchain bump) is a cross-repo PR, built by `build_fork.yml` with fork-trust credentials — so its cache can only live in the `forks` container. Two things broke: - **Upload (CI):** the trust dispatch keyed the container on the head repo, so it targeted `nightly-testing` and Azure RBAC returned 403. Classify any build whose repo differs from `$GITHUB_REPOSITORY` (the credential context) as a fork → `forks`. - **Read (tool):** `defaultContainersForRepo` for the nightly-testing repo was `[nightly-testing, legacy]`, omitting `forks` — so neither the contributor's local `lake exe cache get` nor CI could find the upload. Add `forks` to the chain. It's no wider a trust grant than `nightly-testing` itself: `forks` reads are HEAD-scoped and namespaced under `/f/{repo}/…`, so only artifacts built for the exact checked-out commit by a push-access writer are served. `pr-toolchain-tests` stays excluded (unscoped, arbitrary-toolchain). Native master/nightly/pr-toolchain and ordinary fork PRs are unchanged. Follow-up to #40035. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- .github/actions/cache-trust-dispatch/action.yml | 13 +++++++++++++ Cache/Infra.lean | 9 +++------ Cache/Test.lean | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.github/actions/cache-trust-dispatch/action.yml b/.github/actions/cache-trust-dispatch/action.yml index 7e3811a969d2d9..3cb8f2f785ced0 100644 --- a/.github/actions/cache-trust-dispatch/action.yml +++ b/.github/actions/cache-trust-dispatch/action.yml @@ -66,6 +66,18 @@ runs: # be 403'd by Azure regardless. The dispatch exists so the workflow # does the right thing in the honest case; defence in depth is RBAC. + # Privileged containers (master, nightly-testing, pr-toolchain-tests) are + # writable only by a repo's own native CI, whose OIDC token is RBAC-scoped + # to match. A cross-repo pull request is built by build_fork.yml with + # fork-trust credentials whatever repo the PR head lives on (e.g. a `bump/*` + # branch on the mathlib4-nightly-testing fork), so it can only write + # `forks`. `GITHUB_REPOSITORY` is the repo the workflow runs as (the base + # repo for `pull_request_target`), i.e. the one whose credentials this job + # holds; when it differs from `$REPO`, the build is a fork and targets + # `forks` regardless of the head repo's own trust class. + if [ "$REPO" != "$GITHUB_REPOSITORY" ]; then + PRIMARY="forks" + else case "$REPO" in "leanprover-community/mathlib4") case "$BRANCH" in @@ -121,6 +133,7 @@ runs: PRIMARY="forks" ;; esac + fi # Per-commit cache namespace, only for fork-trust uploads. Closes the # within-fork temporal replay attack: each commit's CI run gets its diff --git a/Cache/Infra.lean b/Cache/Infra.lean index 4bf54177c86d0f..47b88f739ea583 100644 --- a/Cache/Infra.lean +++ b/Cache/Infra.lean @@ -150,12 +150,9 @@ def defaultContainersForRepo (repo : String) : List Container := if repo == MATHLIBREPO then [.master, .legacy] else if repo == NIGHTLY_TESTING_REPO then - -- Trusted-nightly consumers (`nightly-testing`, `nightly-testing-green`, - -- `bump/*`) read only `nightly-testing` + `legacy`; `pr-toolchain-tests` is - -- excluded so low-trust toolchain-PR uploads can't reach them. Toolchain-PR - -- branches opt into reading their own uploads with `--cache-from=...` (or, - -- in CI, via the `MATHLIB_CACHE_FROM` env var). - [.nightlyTesting, .legacy] + -- `forks` is needed for PRs opened from this repo into mathlib4: their CI + -- uploads land in `forks`. `pr-toolchain-tests` is excluded. + [.nightlyTesting, .forks, .legacy] else -- Forks and everything else: `master` for shared upstream deps, the fork's -- own container for PR-specific files, then `legacy`. diff --git a/Cache/Test.lean b/Cache/Test.lean index 93cb93991ec46a..e9aa2298bdefd9 100644 --- a/Cache/Test.lean +++ b/Cache/Test.lean @@ -200,8 +200,8 @@ def test_defaultContainersForRepo : IO Unit := do IO.println "defaultContainersForRepo:" assert "canonical repo → [master, legacy]" (defaultContainersForRepo MATHLIBREPO == [.master, .legacy]) - assert "nightly-testing repo → [nightly-testing, legacy], no pr-toolchain-tests" - (defaultContainersForRepo NIGHTLY_TESTING_REPO == [.nightlyTesting, .legacy]) + assert "nightly-testing repo → [nightly-testing, forks, legacy], no pr-toolchain-tests" + (defaultContainersForRepo NIGHTLY_TESTING_REPO == [.nightlyTesting, .forks, .legacy]) assert "fork repo → [master, forks, legacy]" (defaultContainersForRepo "alice/mathlib4" == [.master, .forks, .legacy]) assert "unknown repo falls back to the fork chain" From 113f7cc9a477501aba4decac2a6f60103a660308 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Thu, 18 Jun 2026 19:42:16 +0000 Subject: [PATCH 0156/1300] refactor(FieldTheory/*): swap imports of `IsSepClosed` and `SeparableClosure` (#40777) This PR swaps the imports order between `IsSepClosed.lean` and `SeparableClosure.lean`. This allows basic facts like adjoining separable elements gives a separable extension to be used to golf a proof in `Galois/Basic.lean`. These basic facts basically require knowing the existence of the separable closure, but right now `SeparableClosure.lean` imports `IsSepClosed.lean` which imports `Galois/Basic.lean`. This PR is a slight modification of #40339. Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/Basic.lean | 38 +++------------- Mathlib/FieldTheory/Galois/GaloisClosure.lean | 3 +- Mathlib/FieldTheory/IsSepClosed.lean | 41 +++++++++++++++++ .../FieldTheory/PurelyInseparable/Basic.lean | 2 +- Mathlib/FieldTheory/Separable.lean | 7 +++ Mathlib/FieldTheory/SeparableClosure.lean | 45 +++++-------------- Mathlib/FieldTheory/SeparableDegree.lean | 7 +++ 7 files changed, 74 insertions(+), 69 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 878605b075d283..9a8f0a6a0aed22 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.FieldTheory.Fixed public import Mathlib.FieldTheory.Normal.Closure public import Mathlib.FieldTheory.PrimitiveElement +public import Mathlib.FieldTheory.SeparableClosure public import Mathlib.GroupTheory.GroupAction.FixingSubgroup /-! @@ -502,6 +503,8 @@ theorem of_card_aut_eq_finrank [FiniteDimensional F E] variable {F} {E} variable {p : F[X]} +@[deprecated "No replacement; this was an auxiliary lemma used to prove \ +`Algebra.isSeparable_of_separable_splitting_field`." (since := "2026-06-12")] theorem of_separable_splitting_field_aux [hFE : FiniteDimensional F E] [sp : p.IsSplittingField F E] (hp : p.Separable) (K : Type*) [Field K] [Algebra F K] [Algebra K E] [IsScalarTower F K E] {x : E} (hx : x ∈ p.aroots E) : @@ -532,37 +535,10 @@ theorem of_separable_splitting_field_aux [hFE : FiniteDimensional F E] [sp : p.I · apply sp.splits.of_dvd (Polynomial.map_ne_zero h1) rwa [← f.comp_algebraMap, ← p.map_map, RingHom.algebraMap_toAlgebra, Polynomial.map_dvd_map'] -theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separable) : - IsGalois F E := by - haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p - letI := Classical.decEq E - let s := p.rootSet E - have adjoin_root : IntermediateField.adjoin F s = ⊤ := by - apply IntermediateField.toSubalgebra_injective - rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet] - apply IntermediateField.algebra_adjoin_le_adjoin - let P : IntermediateField F E → Prop := fun K => Nat.card (K →ₐ[F] E) = finrank F K - suffices P (IntermediateField.adjoin F s) by - rw [adjoin_root] at this - apply of_card_aut_eq_finrank - rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)] - exact Nat.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans - (IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl)) - apply IntermediateField.induction_on_adjoin_finset _ P - · have key := IntermediateField.card_algHom_adjoin_integral F (K := E) - (show IsIntegral F (0 : E) from isIntegral_zero) - rw [IsSeparable, minpoly.zero, Polynomial.natDegree_X] at key - specialize key Polynomial.separable_X (Polynomial.Splits.X.map (algebraMap F E)) - rw [← @Subalgebra.finrank_bot F E _ _ _, ← IntermediateField.bot_toSubalgebra] at key - refine Eq.trans ?_ key - apply Nat.card_congr - rw [IntermediateField.adjoin_zero] - intro K x hx hK - simp only [P] at * - rw [of_separable_splitting_field_aux hp K (Multiset.mem_toFinset.mp hx), hK, finrank_mul_finrank] - symm - refine LinearEquiv.finrank_eq ?_ - rfl +theorem of_separable_splitting_field [p.IsSplittingField F E] (hp : p.Separable) : + IsGalois F E := + { to_isSeparable := Algebra.isSeparable_of_separable_splitting_field F E hp, + to_normal := Normal.of_isSplittingField p } /-- Equivalent characterizations of a Galois extension of finite degree. -/ theorem tfae [FiniteDimensional F E] : List.TFAE [ diff --git a/Mathlib/FieldTheory/Galois/GaloisClosure.lean b/Mathlib/FieldTheory/Galois/GaloisClosure.lean index b08c80a7d8ed8a..dfc8954599d3c3 100644 --- a/Mathlib/FieldTheory/Galois/GaloisClosure.lean +++ b/Mathlib/FieldTheory/Galois/GaloisClosure.lean @@ -5,8 +5,7 @@ Authors: Nailin Guan, Yuyang Zhao -/ module -public import Mathlib.FieldTheory.Normal.Closure -public import Mathlib.FieldTheory.SeparableClosure +public import Mathlib.FieldTheory.Galois.Basic /-! diff --git a/Mathlib/FieldTheory/IsSepClosed.lean b/Mathlib/FieldTheory/IsSepClosed.lean index 823bf62ad7f452..fd98ad49f7d954 100644 --- a/Mathlib/FieldTheory/IsSepClosed.lean +++ b/Mathlib/FieldTheory/IsSepClosed.lean @@ -6,6 +6,7 @@ Authors: Jz Pan module public import Mathlib.FieldTheory.Galois.Basic +public import Mathlib.FieldTheory.SeparableClosure /-! # Separably Closed Field @@ -311,3 +312,43 @@ noncomputable def equiv : L ≃ₐ[K] M := (IsSepClosed.lift : L →ₐ[K] M) (IsSepClosed.lift : M →ₐ[K] L)).1 end IsSepClosure + +section separableClosure + +variable (F E : Type*) [Field F] [Field E] [Algebra F E] + +/-- If `E` is normal over `F`, then the separable closure of `F` in `E` is Galois (i.e. +normal and separable) over `F`. -/ +@[stacks 0EXK] +instance separableClosure.isGalois [Normal F E] : IsGalois F (separableClosure F E) where + to_isSeparable := separableClosure.isSeparable F E + to_normal := by + rw [← separableClosure.normalClosure_eq_self] + exact normalClosure.normal F _ E + +/-- If `E / F` is a field extension and `E` is separably closed, then the separable closure +of `F` in `E` is equal to `F` if and only if `F` is separably closed. -/ +theorem IsSepClosed.separableClosure_eq_bot_iff [IsSepClosed E] : + separableClosure F E = ⊥ ↔ IsSepClosed F := by + refine ⟨fun h ↦ IsSepClosed.of_exists_root _ fun p _ hirr hsep ↦ ?_, + fun _ ↦ IntermediateField.eq_bot_of_isSepClosed_of_isSeparable _⟩ + obtain ⟨x, hx⟩ := IsSepClosed.exists_aeval_eq_zero E p (degree_pos_of_irreducible hirr).ne' hsep + obtain ⟨x, rfl⟩ := h ▸ mem_separableClosure_iff.2 (hsep.of_dvd <| minpoly.dvd _ x hx) + exact ⟨x, by simpa [Algebra.ofId_apply] using hx⟩ + +/-- If `E` is separably closed, then the separable closure of `F` in `E` is an absolute +separable closure of `F`. -/ +instance separableClosure.isSepClosure [IsSepClosed E] : IsSepClosure F (separableClosure F E) := + ⟨(IsSepClosed.separableClosure_eq_bot_iff _ E).mp (separableClosure.separableClosure_eq_bot F E), + isSeparable F E⟩ + +/-- The absolute separable closure is defined to be the relative separable closure inside the +algebraic closure. It is indeed a separable closure (`IsSepClosure`) by +`separableClosure.isSepClosure`, and it is Galois (`IsGalois`) by `separableClosure.isGalois` +or `IsSepClosure.isGalois`, and every separable extension embeds into it (`IsSepClosed.lift`). -/ +abbrev SeparableClosure : Type _ := separableClosure F (AlgebraicClosure F) + +instance SeparableClosure.isSepClosed : IsSepClosed (SeparableClosure F) := + (inferInstance : IsSepClosure F (SeparableClosure F)).sep_closed + +end separableClosure diff --git a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean index 6baa4cd00f365a..e737a97e815e7d 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean @@ -6,7 +6,7 @@ Authors: Jz Pan module public import Mathlib.Algebra.CharP.IntermediateField -public import Mathlib.FieldTheory.SeparableClosure +public import Mathlib.FieldTheory.IsSepClosed /-! diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 3d7f1ab88bce21..6fe3e6458fa074 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -755,6 +755,13 @@ lemma Algebra.IsSeparable.of_equiv_equiv [Algebra.IsSeparable A₁ B₁] : Algeb ⟨fun x ↦ (e₂.apply_symm_apply x) ▸ _root_.IsSeparable.of_equiv_equiv e₁ e₂ he (Algebra.IsSeparable.isSeparable _ _)⟩ +lemma Algebra.IsSeparable.iff_of_equiv_equiv : + Algebra.IsSeparable A₁ B₁ ↔ Algebra.IsSeparable A₂ B₂ := + ⟨fun _ ↦ Algebra.IsSeparable.of_equiv_equiv e₁ e₂ he, + fun _ ↦ Algebra.IsSeparable.of_equiv_equiv e₁.symm e₂.symm (by + ext x + simpa [RingEquiv.eq_symm_apply] using (RingHom.ext_iff.mp he (e₁.symm x)).symm)⟩ + end AlgEquiv section CardAlgHom diff --git a/Mathlib/FieldTheory/SeparableClosure.lean b/Mathlib/FieldTheory/SeparableClosure.lean index b6aafbad0637f8..cad4b2aad6bfbb 100644 --- a/Mathlib/FieldTheory/SeparableClosure.lean +++ b/Mathlib/FieldTheory/SeparableClosure.lean @@ -6,7 +6,6 @@ Authors: Jz Pan module public import Mathlib.FieldTheory.SeparableDegree -public import Mathlib.FieldTheory.IsSepClosed public import Mathlib.RingTheory.AlgebraicIndependent.AlgebraicClosure /-! @@ -64,6 +63,8 @@ separable degree, degree, separable closure @[expose] public section +assert_not_exists IsGalois + open Module Polynomial IntermediateField Field noncomputable section @@ -180,46 +181,20 @@ theorem separableClosure.normalClosure_eq_self : (AlgEquiv.Algebra.isSeparable (AlgEquiv.ofInjectiveField i)) le_separableClosure F E _) (le_normalClosure _) -/-- If `E` is normal over `F`, then the separable closure of `F` in `E` is Galois (i.e. -normal and separable) over `F`. -/ -@[stacks 0EXK] -instance separableClosure.isGalois [Normal F E] : IsGalois F (separableClosure F E) where - to_isSeparable := separableClosure.isSeparable F E - to_normal := by - rw [← separableClosure.normalClosure_eq_self] - exact normalClosure.normal F _ E - -/-- If `E / F` is a field extension and `E` is separably closed, then the separable closure -of `F` in `E` is equal to `F` if and only if `F` is separably closed. -/ -theorem IsSepClosed.separableClosure_eq_bot_iff [IsSepClosed E] : - separableClosure F E = ⊥ ↔ IsSepClosed F := by - refine ⟨fun h ↦ IsSepClosed.of_exists_root _ fun p _ hirr hsep ↦ ?_, - fun _ ↦ IntermediateField.eq_bot_of_isSepClosed_of_isSeparable _⟩ - obtain ⟨x, hx⟩ := IsSepClosed.exists_aeval_eq_zero E p (degree_pos_of_irreducible hirr).ne' hsep - obtain ⟨x, rfl⟩ := h ▸ mem_separableClosure_iff.2 (hsep.of_dvd <| minpoly.dvd _ x hx) - exact ⟨x, by simpa [Algebra.ofId_apply] using hx⟩ - -/-- If `E` is separably closed, then the separable closure of `F` in `E` is an absolute -separable closure of `F`. -/ -instance separableClosure.isSepClosure [IsSepClosed E] : IsSepClosure F (separableClosure F E) := - ⟨(IsSepClosed.separableClosure_eq_bot_iff _ E).mp (separableClosure.separableClosure_eq_bot F E), - isSeparable F E⟩ - -/-- The absolute separable closure is defined to be the relative separable closure inside the -algebraic closure. It is indeed a separable closure (`IsSepClosure`) by -`separableClosure.isSepClosure`, and it is Galois (`IsGalois`) by `separableClosure.isGalois` -or `IsSepClosure.isGalois`, and every separable extension embeds into it (`IsSepClosed.lift`). -/ -abbrev SeparableClosure : Type _ := separableClosure F (AlgebraicClosure F) - -instance SeparableClosure.isSepClosed : IsSepClosed (SeparableClosure F) := - (inferInstance : IsSepClosure F (SeparableClosure F)).sep_closed - /-- `F(S) / F` is a separable extension if and only if all elements of `S` are separable elements. -/ theorem IntermediateField.isSeparable_adjoin_iff_isSeparable {S : Set E} : Algebra.IsSeparable F (adjoin F S) ↔ ∀ x ∈ S, IsSeparable F x := (le_separableClosure_iff F E _).symm.trans adjoin_le_iff +/-- If `p` is a separable polynomial with splitting field `E` over `F`, then `E / F` is a +separable extension. -/ +theorem Algebra.isSeparable_of_separable_splitting_field {p : F[X]} + [sp : p.IsSplittingField F E] (hp : p.Separable) : Algebra.IsSeparable F E := by + rw [← isSeparable_top, ← (isSplittingField_iff_intermediateField.mp sp).2, + isSeparable_adjoin_iff_isSeparable] + exact fun x hx ↦ hp.of_dvd (minpoly.dvd F x (aeval_eq_zero_of_mem_rootSet hx)) + /-- The separable closure of `F` in `E` is equal to `E` if and only if `E / F` is separable. -/ theorem separableClosure.eq_top_iff : separableClosure F E = ⊤ ↔ Algebra.IsSeparable F E := diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index 5b90913ccb2b6f..8f092165f30c70 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -196,6 +196,13 @@ theorem finSepDegree_top : finSepDegree F (⊤ : IntermediateField E K) = finSep end Tower +theorem isSeparable_bot : Algebra.IsSeparable F (⊥ : IntermediateField F E) := + AlgEquiv.Algebra.isSeparable (IntermediateField.botEquiv F E).symm + +theorem isSeparable_top : + Algebra.IsSeparable F (⊤ : IntermediateField F E) ↔ Algebra.IsSeparable F E := + Algebra.IsSeparable.iff_of_equiv_equiv (RingEquiv.refl F) topEquiv.toRingEquiv (by ext; simp) + end IntermediateField namespace Field From bbed4187a91bb274a4359b92d49b59e32be9c95b Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Thu, 18 Jun 2026 21:17:05 +0000 Subject: [PATCH 0157/1300] =?UTF-8?q?feat:=20continuous=20linear=20equival?= =?UTF-8?q?ence=20between=20continuous=20`=E2=84=9D`-=20and=20`?= =?UTF-8?q?=F0=9D=95=9C`-linear=20functionals=20(in=20either=20the=20stron?= =?UTF-8?q?g=20or=20weak-=E2=8B=86=20topologies)=20(#34728)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This realizes the map `StrongDual.extendRCLikeₗ`, after pre- and post-composing so that it is an equivalence between the weak duals, as a *continuous* linear equivalence. In addition, when the space is a topological vector space, we realize `StrongDual.extendRCLikeₗ` as a *continuous* linear equivalence between the strong duals. --- .../Analysis/Normed/Module/RCLike/Extend.lean | 34 +++++++- Mathlib/Analysis/Normed/Module/WeakDual.lean | 83 +++++++++++++++++++ Mathlib/Analysis/RCLike/Extend.lean | 3 - .../Algebra/Module/Spaces/WeakDual.lean | 19 +++++ 4 files changed, 135 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Normed/Module/RCLike/Extend.lean b/Mathlib/Analysis/Normed/Module/RCLike/Extend.lean index d85858c2bda0b0..b5269e984b5373 100644 --- a/Mathlib/Analysis/Normed/Module/RCLike/Extend.lean +++ b/Mathlib/Analysis/Normed/Module/RCLike/Extend.lean @@ -5,7 +5,7 @@ Authors: Ruben Van de Velde -/ module -public import Mathlib.Analysis.Normed.Operator.Basic +public import Mathlib.Analysis.Normed.Operator.Mul public import Mathlib.Analysis.RCLike.Extend /-! @@ -38,6 +38,28 @@ theorem Module.Dual.norm_extendRCLike_le_seminorm [AddCommGroup E] [Module 𝕜 namespace StrongDual +/-- The extension `StrongDual.extendRCLike` as a continuous linear equivalence between +the strong duals when scalar multiplication (by `𝕜`) is jointly continuous. -/ +@[expose, simps! -isSimp apply symm_apply] +noncomputable def extendRCLikeL {𝕜 F : Type*} [RCLike 𝕜] [TopologicalSpace F] + [AddCommGroup F] [Module 𝕜 F] [ContinuousSMul 𝕜 F] [Module ℝ F] [IsScalarTower ℝ 𝕜 F] : + StrongDual ℝ F ≃L[ℝ] StrongDual 𝕜 F where + toLinearEquiv := extendRCLikeₗ + continuous_toFun := by + rw [(ContinuousLinearMap.isEmbedding_restrictScalars ℝ).continuous_iff] + let smulI : F →L[ℝ] F := (I : 𝕜) • ContinuousLinearMap.id 𝕜 F |>.restrictScalars ℝ + let mulI : 𝕜 →L[ℝ] 𝕜 := ContinuousLinearMap.mul ℝ 𝕜 (I : 𝕜) + exact ofRealCLM.postcomp F - mulI.postcomp F ∘L smulI.precomp 𝕜 ∘L ofRealCLM.postcomp F + |>.continuous + continuous_invFun := reCLM.postcomp F |>.continuous.comp <| + (ContinuousLinearMap.isEmbedding_restrictScalars ℝ).continuous + +@[simp] +lemma toLinearEquiv_extendRCLikeL {𝕜 F : Type*} [RCLike 𝕜] [TopologicalSpace F] + [AddCommGroup F] [Module 𝕜 F] [ContinuousSMul 𝕜 F] [Module ℝ F] [IsScalarTower ℝ 𝕜 F] : + (extendRCLikeL (𝕜 := 𝕜) (F := F)).toLinearEquiv = extendRCLikeₗ := + rfl + /-- If a continuous real-linear functional is bounded by a `𝕜`-seminorm, then its `𝕜`-linear extension is bounded by the same seminorm. -/ theorem norm_extendRCLike_le_seminorm [AddCommGroup E] [Module 𝕜 E] [Module ℝ E] @@ -70,6 +92,16 @@ noncomputable def extendRCLikeₗᵢ : StrongDual ℝ F ≃ₗᵢ[ℝ] StrongDua toLinearEquiv := StrongDual.extendRCLikeₗ norm_map' := norm_extendRCLike +@[simp] +lemma toLinearEquiv_extendRCLikeₗᵢ : + (extendRCLikeₗᵢ (𝕜 := 𝕜) (F := F)).toLinearEquiv = extendRCLikeₗ := + rfl + +@[simp] +lemma toContinuousLinearEquiv_extendRCLikeₗᵢ : + (extendRCLikeₗᵢ (F := F) (𝕜 := 𝕜)).toContinuousLinearEquiv = extendRCLikeL := + rfl + end StrongDual namespace ContinuousLinearMap diff --git a/Mathlib/Analysis/Normed/Module/WeakDual.lean b/Mathlib/Analysis/Normed/Module/WeakDual.lean index 857a24373b9937..99aeca6008b7bf 100644 --- a/Mathlib/Analysis/Normed/Module/WeakDual.lean +++ b/Mathlib/Analysis/Normed/Module/WeakDual.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Normed.Module.Dual public import Mathlib.Analysis.Normed.Operator.Completeness +public import Mathlib.Analysis.Normed.Operator.Mul public import Mathlib.Topology.Algebra.Module.Spaces.WeakDual public import Mathlib.Topology.MetricSpace.PiNat public import Mathlib.Analysis.Normed.Operator.BanachSteinhaus @@ -370,3 +371,85 @@ theorem isSeqCompact_closedBall (x' : StrongDual 𝕜 E) (r : ℝ) : isSeqCompact_of_isBounded_of_isClosed 𝕜 _ (isBounded_closedBall x' r) (isClosed_closedBall x' r) end WeakDual + +section RCLike + +open RCLike +open scoped NNReal Topology + +namespace WeakDual + +-- we shadow the variables for this section because they don't fit with the rest of the file. +variable {α 𝕜 E F : Type*} [TopologicalSpace α] [RCLike 𝕜] + [AddCommGroup E] [Module 𝕜 E] [AddCommGroup F] [Module 𝕜 F] + +/-- A map into `WeakBilin (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜)` over `𝕜` (with `RCLike 𝕜`) is +continuous if the real parts of all the evaluation maps `a ↦ B (g a) y` are +continuous for each `y : F`. -/ +theorem _root_.WeakBilin.continuous_of_continuous_eval_re (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) + {g : α → WeakBilin B} (h : ∀ y, Continuous fun a ↦ re (B (g a) y)) : + Continuous g := by + refine WeakBilin.continuous_of_continuous_eval _ fun x ↦ ?_ + suffices Continuous fun a ↦ (re (B (g a) x) : 𝕜) - re (B (g a) ((I : 𝕜) • x)) * I by simpa + fun_prop + +variable [TopologicalSpace F] + +/-- A map into `WeakDual 𝕜 F` over `𝕜` (with `RCLike 𝕜`) is continuous if the real parts of all +the evaluation maps `a ↦ g a y` are continuous for each `y : F`. -/ +theorem continuous_of_continuous_eval_re {g : α → WeakDual 𝕜 F} + (h : ∀ x, Continuous fun a ↦ re (g a x)) : + Continuous g := + WeakBilin.continuous_of_continuous_eval_re _ h + +variable [ContinuousConstSMul 𝕜 F] [Module ℝ F] [IsScalarTower ℝ 𝕜 F] + +open StrongDual + +/-- The extension `StrongDual.extendRCLike` as a continuous linear equivalence between +the weak duals. -/ +@[simps! -isSimp apply symm_apply] +noncomputable def extendRCLikeL : WeakDual ℝ F ≃L[ℝ] WeakDual 𝕜 F where + toLinearEquiv := toStrongDual ≪≫ₗ extendRCLikeₗ ≪≫ₗ toWeakDual.restrictScalars ℝ + continuous_toFun := continuous_of_continuous_eval_re fun x ↦ by + simpa [extendRCLikeₗ_apply] using eval_continuous x + continuous_invFun := + continuous_of_continuous_eval fun x ↦ RCLike.continuous_re.comp (eval_continuous x) + +@[simp] +lemma toLinearEquiv_extendRCLikeL : + (extendRCLikeL (𝕜 := 𝕜) (F := F)).toLinearEquiv = + toStrongDual ≪≫ₗ extendRCLikeₗ ≪≫ₗ toWeakDual.restrictScalars ℝ := by + rfl + +lemma extendRCLikeL_apply_apply (f : WeakDual ℝ F) (x : F) : + extendRCLikeL (𝕜 := 𝕜) f x = f x - (I : 𝕜) • f ((I : 𝕜) • x) := by + rfl + +lemma extendRCLikeL_symm_apply_apply (f : WeakDual 𝕜 F) (x : F) : + extendRCLikeL.symm f x = re (f x) := + rfl + +@[simp] +lemma re_extendRCLikeL_apply_apply (f : WeakDual ℝ F) (x : F) : + re (extendRCLikeL (𝕜 := 𝕜) f x) = f x := by + simp [extendRCLikeL_apply_apply] + +@[simp] +lemma im_extendRCLikeL_apply_apply (f : WeakDual ℝ F) (x : F) : + im (extendRCLikeL (𝕜 := 𝕜) f x) = - f ((I : 𝕜) • x) := by + simp [extendRCLikeL_apply, extendRCLikeₗ_apply] + +@[simp high] +lemma toStrongDual_extendRCLikeL_apply (f : WeakDual ℝ F) : + (extendRCLikeL (𝕜 := 𝕜) f).toStrongDual = extendRCLikeₗ f := + rfl + +@[simp high] +lemma _root_.StrongDual.toWeakDual_extendRCLikeₗ_apply (f : StrongDual ℝ F) : + (extendRCLikeₗ f).toWeakDual = extendRCLikeL (𝕜 := 𝕜) f.toWeakDual := + rfl + +end WeakDual + +end RCLike diff --git a/Mathlib/Analysis/RCLike/Extend.lean b/Mathlib/Analysis/RCLike/Extend.lean index 9bfd56a416bf36..f1edf68502006f 100644 --- a/Mathlib/Analysis/RCLike/Extend.lean +++ b/Mathlib/Analysis/RCLike/Extend.lean @@ -103,9 +103,6 @@ variable [Module ℝ F] [IsScalarTower ℝ 𝕜 F] /-- Extend `fr : StrongDual ℝ F` to `StrongDual 𝕜 F`. -It would be possible to use `LinearMap.mkContinuous` here, but we would need to know that the -continuity of `fr` implies it has bounded norm and we want to avoid that dependency here. - Norm properties of this extension can be found in `Mathlib/Analysis/Normed/Module/RCLike/Extend.lean`. -/ noncomputable def extendRCLike (fr : StrongDual ℝ F) : StrongDual 𝕜 F where diff --git a/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean b/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean index fc6dcabebd8be6..e7ac7aa3da5de1 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean @@ -137,6 +137,25 @@ equivalence `StrongDual.toWeakDual` in the other direction. -/ def toStrongDual : WeakDual 𝕜 E ≃ₗ[𝕜] StrongDual 𝕜 E := StrongDual.toWeakDual.symm +@[simp] +theorem symm_toStrongDual : + (toStrongDual (𝕜 := 𝕜) (E := E)).symm = StrongDual.toWeakDual := + rfl + +@[simp] +theorem _root_.StrongDual.symm_toWeakDual : + (StrongDual.toWeakDual (𝕜 := 𝕜) (E := E)).symm = toStrongDual := + rfl + +@[simp] +theorem _root_.StrongDual.toStrongDual_toWeakDual (x : StrongDual 𝕜 E) : + x.toWeakDual.toStrongDual = x := + rfl + +@[simp] +theorem toWeakDual_toStrongDual (x : WeakDual 𝕜 E) : x.toStrongDual.toWeakDual = x := + rfl + @[simp] theorem toStrongDual_apply (x : WeakDual 𝕜 E) (y : E) : (toStrongDual x) y = x y := rfl From e69d3a0c829dab0ba9ff0a5270ae932e9c8492a6 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Thu, 18 Jun 2026 22:01:28 +0000 Subject: [PATCH 0158/1300] ci: make lake cache shadow shells uniform (#40744) Sets one workflow-level default shell (`bash -euo pipefail {0}`) so every `run` step shares the same strict mode, instead of relying on the implicit per-step `shell: bash`. `upload`/`consume`/`report` inherit it; `build_and_stage` keeps its landrun sandbox as its job default, and its setup steps spell out the same flags to opt out of the sandbox. This also fixes some observed issues related to not passing pipefail in places. --- .github/workflows/lake_cache_shadow.yml | 37 +++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index ceb83aa283ec17..b0b0491fe7f769 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -62,6 +62,10 @@ concurrency: group: lake-cache-shadow-${{ inputs.mathlib_ref || 'master' }} cancel-in-progress: false +defaults: + run: + shell: bash -euo pipefail {0} + env: # Scope prefix for all puts and gets in this workflow. Namespaces the # workflow's artifacts within the cache bucket. @@ -87,7 +91,7 @@ jobs: shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI --env LAKE_CACHE_DIR --env LAKE_NO_CACHE --env STAGE_TARGETS --env SHADOW_SCOPE -- bash -euxo pipefail {0} steps: - name: job info - shell: bash + shell: bash -euo pipefail {0} run: echo "::notice::Lake cache shadow on ref ${{ inputs.mathlib_ref || 'master' }} run ${{ github.run_id }}" - name: Setup jq @@ -108,7 +112,7 @@ jobs: - name: Resolve sha & toolchain id: resolve - shell: bash + shell: bash -euo pipefail {0} run: | cd pr-branch SHA="$(git rev-parse HEAD)" @@ -117,23 +121,22 @@ jobs: echo "toolchain=$TC" >> "$GITHUB_OUTPUT" - name: Create empty directories (landrun prerequisites) - shell: bash + shell: bash -euo pipefail {0} run: | mkdir -p pr-branch/.lake/ mkdir -p .cache/mathlib/ mkdir -p _work - name: install elan - shell: bash + shell: bash -euo pipefail {0} run: | - set -o pipefail curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh chmod +x elan-init.sh ./elan-init.sh -y --default-toolchain none echo "$HOME/.elan/bin" >> "${GITHUB_PATH}" - name: set toolchain directory - shell: bash + shell: bash -euo pipefail {0} run: | cd pr-branch LAKE_PATH=$(elan which lake) @@ -141,7 +144,7 @@ jobs: echo "TOOLCHAIN_DIR=$TOOLCHAIN_DIR" >> "$GITHUB_ENV" - name: set LEAN_SRC_PATH - shell: bash + shell: bash -euo pipefail {0} run: | cd pr-branch LEAN_SRC_PATH=".:$TOOLCHAIN_DIR/src/lean/lake" @@ -154,7 +157,7 @@ jobs: echo "LEAN_SRC_PATH=$LEAN_SRC_PATH" >> "$GITHUB_ENV" - name: build tools-branch tools - shell: bash + shell: bash -euo pipefail {0} run: | cd tools-branch lake build cache @@ -166,13 +169,13 @@ jobs: lake env - name: Hydrate .lake/build via legacy cache - shell: bash + shell: bash -euo pipefail {0} run: | cd pr-branch ../tools-branch/.lake/build/bin/cache get - name: Patch lakefile to enable Lake's artifact cache - shell: bash + shell: bash -euo pipefail {0} run: | cd pr-branch if grep -q 'enableArtifactCache' lakefile.lean; then @@ -228,7 +231,7 @@ jobs: # write to it. Same pattern as build_template.yml uses for the legacy # cache-staging dir. - name: Create staging directory - shell: bash + shell: bash -euo pipefail {0} run: mkdir -p lake-cache-staging - name: Stage cache for upload @@ -245,7 +248,7 @@ jobs: # free-tier / lifecycle budget. Logs the size first, so a trip still tells # us how big the build got. - name: Guard upload size (bail if staging > 1 GB) - shell: bash + shell: bash -euo pipefail {0} run: | MAX=$((1 * 1000 * 1000 * 1000)) # 1 GB — ~2.5x the measured ~389 MB full build (runaway guard) BYTES=$(du -sb lake-cache-staging | cut -f1) @@ -284,9 +287,7 @@ jobs: fetch-depth: 1 - name: install elan + matching lake - shell: bash run: | - set -o pipefail curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh chmod +x elan-init.sh ./elan-init.sh -y --default-toolchain none @@ -336,7 +337,8 @@ jobs: base="${AUTH%/artifacts}/analysis" sha="${{ needs.build_and_stage.outputs.sha }}" sig=(--aws-sigv4 aws:amz:auto:s3 --user "$LAKE_CACHE_KEY") - grep -oE 'uploaded artifact [0-9a-f]+' /tmp/put.log | awk '{print $3}' | sort -u > /tmp/today.txt + # grep exits 1 on no match (handled by the total==0 branch); tolerate it under pipefail. + grep -oE 'uploaded artifact [0-9a-f]+' /tmp/put.log | awk '{print $3}' | sort -u > /tmp/today.txt || true total=$(wc -l < /tmp/today.txt) if [ "$total" -eq 0 ]; then echo "::warning::no uploaded artifacts parsed from put.log — skipping carryover (manifest/pointer left unchanged)" @@ -418,7 +420,6 @@ jobs: - name: install elan run: | - set -o pipefail curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh chmod +x elan-init.sh ./elan-init.sh -y --default-toolchain none @@ -458,7 +459,8 @@ jobs: # Artifacts fetched here = the root-package outputs served from cache # (a non-verbose build replays them silently). Hand the count to the # provenance step. - FETCHED=$(find ~/.elan/toolchains -name '*.ltar' 2>/dev/null | wc -l) + # `|| true`: an informational count must not trip pipefail if find fails. + FETCHED=$(find ~/.elan/toolchains -name '*.ltar' 2>/dev/null | wc -l || true) echo "ltar count after get: $FETCHED" echo "FETCHED_ARTIFACTS=$FETCHED" >> "$GITHUB_ENV" @@ -514,7 +516,6 @@ jobs: steps: - name: Compose Zulip message id: compose - shell: bash env: BUILD: ${{ needs.build_and_stage.result }} UPLOAD: ${{ needs.upload.result }} From e81046e832ef8aac1d13bc7510be8d27d6568e5c Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Thu, 18 Jun 2026 22:50:24 +0000 Subject: [PATCH 0159/1300] chore(NumberTheory/ArithmeticFunction/LFunction): add backticks to fix docgen (#40783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds backticks to the module docstring of `NumberTheory/ArithmeticFunction/LFunction.lean` to fix the docgen output. The current output is pretty poor: ``` T=q⁻ˢ s ∈ ℂ [polynomials in T] ----> [polynomials in q⁻ˢ] ----> [analytic function in s] | | | | (reciprocal) | (reciprocal) | (reciprocal) v T=q⁻ˢ V s ∈ ℂ V [power series in T] ----> [power series in q⁻ˢ] ----> [analytic function in s] (the Euler factor) | | | | (product) | (product) | (product) v T=q⁻ˢ V s ∈ ℂ V [multivariate power series] ----> [Dirichlet series] ----> [L-function in s] (the Euler product) ``` Co-authored-by: tb65536 --- Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean index 15a06a3780598d..bc9919c9511070 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean @@ -32,7 +32,7 @@ We take the following route from polynomials to L-functions: For example, the Riemann zeta function `ζ(s)` corresponds to taking `1 - T` at each prime `p`. For context, here is a diagram of the possible routes from polynomials to L-functions: - +``` T=q⁻ˢ s ∈ ℂ [polynomials in T] ----> [polynomials in q⁻ˢ] ----> [analytic function in s] | | | @@ -43,6 +43,7 @@ For context, here is a diagram of the possible routes from polynomials to L-func | (product) | (product) | (product) v T=q⁻ˢ V s ∈ ℂ V [multivariate power series] ----> [Dirichlet series] ----> [L-function in s] (the Euler product) +``` -/ @[expose] public section From 360da6fa66c1273b76b6b2d8c5666fd5ac2e3b56 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Thu, 18 Jun 2026 23:59:56 +0000 Subject: [PATCH 0160/1300] chore: bump toolchain to v4.32.0-rc1 (#40732) Co-authored-by: mathlib-nightly-testing[bot] Co-authored-by: Kim Morrison Co-authored-by: mathlib4-bot Co-authored-by: Joscha Co-authored-by: Rob23oba Co-authored-by: leanprover-community-mathlib4-bot Co-authored-by: Julia Markus Himmel <2065352+TwoFX@users.noreply.github.com> Co-authored-by: Sebastian Ullrich --- Counterexamples/DirectSumIsInternal.lean | 6 +- Mathlib/Algebra/Category/Grp/Basic.lean | 7 +- .../Algebra/Module/Presentation/Basic.lean | 2 + .../Algebra/Order/AbsoluteValue/Basic.lean | 4 +- Mathlib/Algebra/Order/Algebra.lean | 11 +- .../Algebra/Order/BigOperators/Expect.lean | 10 +- .../Order/BigOperators/Ring/Finset.lean | 14 +- Mathlib/Algebra/Order/Field/Basic.lean | 64 ++--- Mathlib/Algebra/Order/Field/Power.lean | 110 ++++----- Mathlib/Algebra/Order/Floor/Extended.lean | 4 +- Mathlib/Algebra/Order/Floor/Ring.lean | 12 +- Mathlib/Algebra/Order/Interval/Basic.lean | 8 +- Mathlib/Algebra/Order/Module/Field.lean | 4 +- Mathlib/Analysis/Complex/Exponential.lean | 4 +- Mathlib/Analysis/Complex/Order.lean | 4 +- Mathlib/Analysis/Complex/Trigonometric.lean | 4 +- .../Complex/UpperHalfPlane/Basic.lean | 8 +- Mathlib/Analysis/Normed/Group/Basic.lean | 24 +- Mathlib/Analysis/Real/Sqrt.lean | 8 +- .../Analysis/SpecialFunctions/Bernstein.lean | 4 +- .../SpecialFunctions/Gamma/Basic.lean | 4 +- .../Analysis/SpecialFunctions/Log/Basic.lean | 12 +- .../Analysis/SpecialFunctions/Pow/NNReal.lean | 8 +- .../Analysis/SpecialFunctions/Pow/Real.lean | 8 +- .../Trigonometric/Arctan.lean | 10 +- .../SpecialFunctions/Trigonometric/Basic.lean | 4 +- .../Trigonometric/DerivHyp.lean | 4 +- Mathlib/CategoryTheory/Bicategory/Basic.lean | 1 + Mathlib/CategoryTheory/Category/Cat.lean | 1 + Mathlib/CategoryTheory/Category/Preorder.lean | 1 + Mathlib/CategoryTheory/Category/Quiv.lean | 1 + Mathlib/CategoryTheory/Category/ReflQuiv.lean | 1 + .../FiberedCategory/BasedCategory.lean | 1 + .../FiberedCategory/HasFibers.lean | 1 + .../CategoryTheory/Groupoid/Grpd/Basic.lean | 1 + Mathlib/CategoryTheory/Limits/Chosen/End.lean | 2 + Mathlib/CategoryTheory/Limits/Creates.lean | 2 + .../Limits/Shapes/Multiequalizer.lean | 2 + .../Monoidal/OfHasFiniteProducts.lean | 2 + .../MorphismProperty/Local.lean | 16 +- .../Combinatorics/Enumerative/DyckWord.lean | 4 +- Mathlib/Combinatorics/Hindman.lean | 4 + .../SimpleGraph/Regularity/Bound.lean | 8 +- .../SimpleGraph/Triangle/Removal.lean | 4 +- Mathlib/Computability/Partrec.lean | 1 + Mathlib/Data/ENNReal/Basic.lean | 8 +- Mathlib/Data/ENNReal/Real.lean | 4 +- Mathlib/Data/EReal/Basic.lean | 16 +- Mathlib/Data/EReal/Inv.lean | 8 +- Mathlib/Data/EReal/Operations.lean | 8 +- Mathlib/Data/Fin/Tuple/Reflection.lean | 12 +- Mathlib/Data/NNReal/Defs.lean | 12 +- .../Data/Nat/Factorial/DoubleFactorial.lean | 4 +- Mathlib/Data/Nat/Find.lean | 1 + Mathlib/Data/Nat/Sqrt.lean | 106 +-------- Mathlib/Data/Nat/Totient.lean | 3 +- Mathlib/Data/PFunctor/Univariate/Basic.lean | 1 + Mathlib/Data/Rat/Cast/Order.lean | 29 ++- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 1 + Mathlib/Geometry/Euclidean/Altitude.lean | 4 +- Mathlib/Geometry/RingedSpace/Basic.lean | 1 + Mathlib/Init.lean | 2 +- Mathlib/Lean/MessageData/ForExprs.lean | 1 + .../Lean/Meta/RefinedDiscrTree/Encode.lean | 4 +- .../MeasureTheory/Covering/Besicovitch.lean | 4 +- .../MeasureTheory/Integral/Bochner/Basic.lean | 4 +- Mathlib/MeasureTheory/Measure/Real.lean | 4 +- Mathlib/ModelTheory/Basic.lean | 1 + .../NumberTheory/ArithmeticFunction/Misc.lean | 4 +- .../NumberTheory/ArithmeticFunction/Zeta.lean | 4 +- Mathlib/NumberTheory/Height/Basic.lean | 16 +- Mathlib/NumberTheory/Height/NumberField.lean | 4 +- .../NumberTheory/Height/Projectivization.lean | 8 +- Mathlib/NumberTheory/LucasLehmer.lean | 4 +- Mathlib/NumberTheory/Padics/Hensel.lean | 1 + Mathlib/NumberTheory/SelbergSieve.lean | 4 +- Mathlib/SetTheory/Ordinal/Univ.lean | 2 + Mathlib/SetTheory/ZFC/PSet.lean | 1 + Mathlib/Tactic/Algebra/Basic.lean | 77 +++--- Mathlib/Tactic/CrossRefAttribute.lean | 10 +- Mathlib/Tactic/DefEqAbuse.lean | 38 +-- Mathlib/Tactic/DeprecateTo.lean | 9 +- Mathlib/Tactic/DeriveEncodable.lean | 2 +- Mathlib/Tactic/FieldSimp.lean | 26 +- Mathlib/Tactic/FieldSimp/Lemmas.lean | 14 +- .../Oracle/SimplexAlgorithm/Gauss.lean | 4 +- Mathlib/Tactic/LinearCombinationPrime.lean | 2 +- Mathlib/Tactic/Linter/HaveLetLinter.lean | 4 +- Mathlib/Tactic/Linter/Style.lean | 6 +- Mathlib/Tactic/Linter/Whitespace.lean | 6 +- Mathlib/Tactic/NormNum/Core.lean | 2 +- Mathlib/Tactic/NormNum/Irrational.lean | 104 ++++---- Mathlib/Tactic/Positivity/Basic.lean | 222 +++++++++--------- Mathlib/Tactic/Positivity/Core.lean | 47 ++-- Mathlib/Tactic/Positivity/Finset.lean | 26 +- Mathlib/Tactic/ReduceModChar.lean | 3 +- Mathlib/Tactic/Ring/Basic.lean | 17 +- Mathlib/Tactic/Ring/Common.lean | 82 +++---- Mathlib/Tactic/Ring/Compare.lean | 8 +- Mathlib/Tactic/Simproc/ExistsAndEq.lean | 20 +- .../Tactic/TacticAnalysis/Declarations.lean | 4 +- Mathlib/Tactic/Translate/Core.lean | 2 +- Mathlib/Tactic/Translate/Reorder.lean | 2 +- Mathlib/Tactic/Variable.lean | 4 +- .../Topology/Algebra/InfiniteSum/Order.lean | 4 +- .../Category/CompHausLike/Limits.lean | 1 + Mathlib/Topology/ContinuousMap/Algebra.lean | 1 + Mathlib/Topology/MetricSpace/Bounded.lean | 4 +- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 4 +- Mathlib/Util/CountHeartbeats.lean | 2 +- Mathlib/Util/GetAllModules.lean | 2 +- Mathlib/Util/WhatsNew.lean | 2 +- MathlibTest/Attribute/ToAdditive/Basic.lean | 3 + MathlibTest/Attribute/ToDual.lean | 3 + MathlibTest/CategoryTheory/CategoryStar.lean | 2 + MathlibTest/Linter/DocPrime.lean | 1 + MathlibTest/MinImports.lean | 2 + MathlibTest/Simps.lean | 1 + MathlibTest/Subsingleton.lean | 1 + MathlibTest/Tactic/Says/Basic.lean | 2 + MathlibTest/UnusedTactic.lean | 1 + MathlibTest/globalAttributeIn.lean | 1 + MathlibTest/symm.lean | 2 + lake-manifest.json | 16 +- lean-toolchain | 2 +- scripts/create_deprecated_modules.lean | 2 +- scripts/lint-style.lean | 2 +- scripts/mk_all.lean | 2 +- 128 files changed, 756 insertions(+), 749 deletions(-) diff --git a/Counterexamples/DirectSumIsInternal.lean b/Counterexamples/DirectSumIsInternal.lean index c46125e7464b48..b2f95cb70a44d2 100644 --- a/Counterexamples/DirectSumIsInternal.lean +++ b/Counterexamples/DirectSumIsInternal.lean @@ -56,8 +56,10 @@ theorem withSign.isCompl : IsCompl ℤ≥0 ℤ≤0 := by · exact Submodule.mem_sup_left (mem_withSign_one.mpr hp) · exact Submodule.mem_sup_right (mem_withSign_neg_one.mpr hn) -lemma withSign.independent : iSupIndep withSign := by - apply (iSupIndep_pair UnitsInt.one_ne_neg_one _).mpr withSign.isCompl.disjoint +set_option linter.defProp false in +def withSign.independent : iSupIndep withSign := by + apply + (iSupIndep_pair UnitsInt.one_ne_neg_one _).mpr withSign.isCompl.disjoint intro i fin_cases i <;> simp diff --git a/Mathlib/Algebra/Category/Grp/Basic.lean b/Mathlib/Algebra/Category/Grp/Basic.lean index 3f1342fbd31449..bd4be06cb2de90 100644 --- a/Mathlib/Algebra/Category/Grp/Basic.lean +++ b/Mathlib/Algebra/Category/Grp/Basic.lean @@ -600,19 +600,24 @@ instance CommGrpCat.forget_reflects_isos : (forget CommGrpCat.{u}).ReflectsIsomo -- note: in the following definitions, there is a problem with `@[to_additive]` -- as the `Category` instance is not found on the additive variant -- this variant is then renamed with an `Aux` suffix - +set_option linter.checkUnivs false in /-- An alias for `GrpCat.{max u v}`, to deal around unification issues. -/ @[to_additive (attr := nolint checkUnivs) GrpMaxAux /-- An alias for `AddGrpCat.{max u v}`, to deal around unification issues. -/] abbrev GrpMax.{u1, u2} := GrpCat.{max u1 u2} + +set_option linter.checkUnivs false in /-- An alias for `AddGrpCat.{max u v}`, to deal around unification issues. -/ @[nolint checkUnivs] abbrev AddGrpMax.{u1, u2} := AddGrpCat.{max u1 u2} +set_option linter.checkUnivs false in /-- An alias for `CommGrpCat.{max u v}`, to deal around unification issues. -/ @[to_additive (attr := nolint checkUnivs) AddCommGrpMaxAux /-- An alias for `AddCommGrpCat.{max u v}`, to deal around unification issues. -/] abbrev CommGrpMax.{u1, u2} := CommGrpCat.{max u1 u2} + +set_option linter.checkUnivs false in /-- An alias for `AddCommGrpCat.{max u v}`, to deal around unification issues. -/ @[nolint checkUnivs] abbrev AddCommGrpMax.{u1, u2} := AddCommGrpCat.{max u1 u2} diff --git a/Mathlib/Algebra/Module/Presentation/Basic.lean b/Mathlib/Algebra/Module/Presentation/Basic.lean index c66b20bdc5641d..47775e86dd5dff 100644 --- a/Mathlib/Algebra/Module/Presentation/Basic.lean +++ b/Mathlib/Algebra/Module/Presentation/Basic.lean @@ -48,6 +48,7 @@ namespace Module variable (A : Type u) [Ring A] +set_option linter.checkUnivs false in /-- Given a ring `A`, this structure involves a family of elements (indexed by a type `R`) in a free module `G →₀ A`. This allows to define an `A`-module by generators and relations, see `Relations.Quotient`. -/ @@ -488,6 +489,7 @@ end Relations variable (M : Type v) [AddCommGroup M] [Module A M] +set_option linter.checkUnivs false in /-- Given an `A`-module `M`, a term in this type is a presentation by `M` by generators and relations. -/ @[nolint checkUnivs] diff --git a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean index 2438aca9fe70bd..7caaf3ed13c86c 100644 --- a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean +++ b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean @@ -416,8 +416,8 @@ open Lean Meta Mathlib Meta Positivity Qq in For performance reasons, we only attempt to apply this when `abv` is a variable. If it is an explicit function, e.g. `|_|` or `‖_‖`, another extension should apply. -/ @[positivity _] -meta def Mathlib.Meta.Positivity.evalAbv : PositivityExt where eval {_ _α} _zα pα? e := do - let some _ := pα? | pure .none +meta def Mathlib.Meta.Positivity.evalAbv : PositivityExt where eval {_ _α} _zα pα? e := + match pα? with | none => pure .none | some _ => do let (.app f a) ← whnfR e | throwError "not abv ·" if !f.getAppFn.isFVar then throwError "abv: function is not a variable" diff --git a/Mathlib/Algebra/Order/Algebra.lean b/Mathlib/Algebra/Order/Algebra.lean index c5a1cbd199b481..36fe510b349ab7 100644 --- a/Mathlib/Algebra/Order/Algebra.lean +++ b/Mathlib/Algebra/Order/Algebra.lean @@ -95,14 +95,13 @@ open Lean Meta Qq Function /-- Extension for `algebraMap`. -/ @[positivity algebraMap _ _ _] -meta def evalAlgebraMap : PositivityExt where eval {u β} _zβ pβ? e := do +meta def evalAlgebraMap : PositivityExt where eval {u β} _zβ pβ? e := + match pβ? with | none => pure .none | some _ => do let ~q(@algebraMap $α _ $instα $instβ $instαβ $a) := e | throwError "not `algebraMap`" - let pα ← try? <| synthInstanceQ q(PartialOrder $α) - match ← core q(inferInstance) pα a with + let some pα ← try? <| synthInstanceQ q(PartialOrder $α) | pure .none + match ← core q(inferInstance) (some pα) a with | .positive pa => - let some _ := pβ? | pure .none let _instαSemiring ← synthInstanceQ q(Semiring $α) - let _instαPartialOrder ← synthInstanceQ q(PartialOrder $α) try let _instβSemiring ← synthInstanceQ q(Semiring $β) let _instβPartialOrder ← synthInstanceQ q(PartialOrder $β) @@ -118,9 +117,7 @@ meta def evalAlgebraMap : PositivityExt where eval {u β} _zβ pβ? e := do assertInstancesCommute return .nonnegative q(algebraMap_nonneg $β <| le_of_lt $pa) | .nonnegative pa => - let some _ := pβ? | pure .none let _instαSemiring ← synthInstanceQ q(CommSemiring $α) - let _instαPartialOrder ← synthInstanceQ q(PartialOrder $α) let _instβSemiring ← synthInstanceQ q(Semiring $β) let _instβPartialOrder ← synthInstanceQ q(PartialOrder $β) let _instβIsOrderedRing ← synthInstanceQ q(IsOrderedRing $β) diff --git a/Mathlib/Algebra/Order/BigOperators/Expect.lean b/Mathlib/Algebra/Order/BigOperators/Expect.lean index 2f7e1bf8a89631..5b72ba801fa25a 100644 --- a/Mathlib/Algebra/Order/BigOperators/Expect.lean +++ b/Mathlib/Algebra/Order/BigOperators/Expect.lean @@ -220,22 +220,22 @@ open scoped BigOperators attribute [local instance] monadLiftOptionMetaM in /-- Positivity extension for `Finset.expect`. -/ @[positivity Finset.expect _ _] -meta def evalFinsetExpect : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalFinsetExpect : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match e with | ~q(@Finset.expect $ι _ $instα $instmod $s $f) => let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque have body : Q($α) := .betaRev f #[i] let rbody ← core zα pα body - let p_pos : Option Q(0 < $e) ← (do + let p_pos : Option Q(0 < $e) ← do let .positive pbody := rbody | pure none -- Fail if the body is not provably positive let some ps ← proveFinsetNonempty s | pure none let .some pα' ← trySynthInstanceQ q(IsOrderedCancelAddMonoid $α) | pure none let .some instαordsmul ← trySynthInstanceQ q(PosSMulStrictMono ℚ≥0 $α) | pure none assumeInstancesCommute let pr : Q(∀ i, 0 < $f i) ← mkLambdaFVars #[i] pbody - return some - q(@expect_pos $ι $α $instα $pα $pα' $instmod $instαordsmul $s $f (fun i _ ↦ $pr i) $ps)) + pure <| some + q(@expect_pos $ι $α $instα $pα $pα' $instmod $instαordsmul $s $f (fun i _ ↦ $pr i) $ps) -- Try to show that the sum is positive if let some p_pos := p_pos then return .positive p_pos diff --git a/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean b/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean index f4b2836ef9c166..0d96d6a018402a 100644 --- a/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/Ring/Finset.lean @@ -225,16 +225,16 @@ example (s : Finset ℕ) (f : ℕ → ℤ) (hf : ∀ n, 0 ≤ f n) : 0 ≤ s.pro because `compareHyp` can't look for assumptions behind binders. -/ @[positivity Finset.prod _ _] -meta def evalFinsetProd : PositivityExt where eval {u α} zα pα? e := do +meta def evalFinsetProd : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match e with | ~q(@Finset.prod $ι _ $instα $s $f) => - let some pα := pα? | pure .none let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque have body : Q($α) := Expr.betaRev f #[i] let rbody ← core zα pα body let _instαmon ← synthInstanceQ q(CommMonoidWithZero $α) -- Try to show that the product is positive - let p_pos : Option Q(0 < $e) := ← do + let p_pos : Option Q(0 < $e) ← do let .positive pbody := rbody | pure none -- Fail if the body is not provably positive -- TODO(https://github.com/leanprover-community/quote4/issues/38): -- We must name the following, else `assertInstancesCommute` loops. @@ -243,19 +243,19 @@ meta def evalFinsetProd : PositivityExt where eval {u α} zα pα? e := do let .some _instαnontriv ← trySynthInstanceQ q(Nontrivial $α) | pure none assertInstancesCommute let pr : Q(∀ i, 0 < $f i) ← mkLambdaFVars #[i] pbody (binderInfoForMVars := .default) - return some q(prod_pos fun i _ ↦ $pr i) + pure <| some q(prod_pos fun i _ ↦ $pr i) if let some p_pos := p_pos then return .positive p_pos -- Try to show that the product is nonnegative - let p_nonneg : Option Q(0 ≤ $e) := ← do + let p_nonneg : Option Q(0 ≤ $e) ← do let some pbody := rbody.toNonneg - | return none -- Fail if the body is not provably nonnegative + | pure none -- Fail if the body is not provably nonnegative let pr : Q(∀ i, 0 ≤ $f i) ← mkLambdaFVars #[i] pbody (binderInfoForMVars := .default) -- TODO(https://github.com/leanprover-community/quote4/issues/38): -- We must name the following, else `assertInstancesCommute` loops. let .some _instαzeroone ← trySynthInstanceQ q(ZeroLEOneClass $α) | pure none let .some _instαposmul ← trySynthInstanceQ q(PosMulMono $α) | pure none assertInstancesCommute - return some q(prod_nonneg fun i _ ↦ $pr i) + pure <| some q(prod_nonneg fun i _ ↦ $pr i) if let some p_nonneg := p_nonneg then return .nonnegative p_nonneg -- Fall back to showing that the product is nonzero let pbody ← rbody.toNonzero diff --git a/Mathlib/Algebra/Order/Field/Basic.lean b/Mathlib/Algebra/Order/Field/Basic.lean index ca4d841b0657e8..f50b2c06f3020b 100644 --- a/Mathlib/Algebra/Order/Field/Basic.lean +++ b/Mathlib/Algebra/Order/Field/Basic.lean @@ -740,26 +740,28 @@ such that `positivity` successfully recognises both `a` and `b`. -/ trace[Tactic.positivity.zeroness] "evalDiv: {a} divided by {b}" let _a ← synthInstanceQ q(Semifield $α) let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HDiv.hDiv) - let some pα := pα? | + match (dependent := true) pα? with + | none => match ← core zα pα? a, ← core zα pα? b with | .nonzero pa, .nonzero pb => let _a ← synthInstanceQ q(GroupWithZero $α) assumeInstancesCommute pure (.nonzero q(div_ne_zero $pa $pb)) | _, _ => pure .none - let _a ← synthInstanceQ q(GroupWithZero $α) - let _a ← synthInstanceQ q(PosMulReflectLT $α) - assumeInstancesCommute - let ra ← core zα pα a; let rb ← core zα pα b - match ra, rb with - | .positive pa, .positive pb => pure (.positive q(div_pos $pa $pb)) - | .positive pa, .nonnegative pb => pure (.nonnegative q(div_nonneg_of_pos_of_nonneg $pa $pb)) - | .nonnegative pa, .positive pb => pure (.nonnegative q(div_nonneg_of_nonneg_of_pos $pa $pb)) - | .nonnegative pa, .nonnegative pb => pure (.nonnegative q(div_nonneg $pa $pb)) - | .positive pa, .nonzero pb => pure (.nonzero q(div_ne_zero_of_pos_of_ne_zero $pa $pb)) - | .nonzero pa, .positive pb => pure (.nonzero q(div_ne_zero_of_ne_zero_of_pos $pa $pb)) - | .nonzero pa, .nonzero pb => pure (.nonzero q(div_ne_zero $pa $pb)) - | _, _ => pure .none + | some pα => + let _a ← synthInstanceQ q(GroupWithZero $α) + let _a ← synthInstanceQ q(PosMulReflectLT $α) + assumeInstancesCommute + let ra ← core zα pα a; let rb ← core zα pα b + match ra, rb with + | .positive pa, .positive pb => pure (.positive q(div_pos $pa $pb)) + | .positive pa, .nonnegative pb => pure (.nonnegative q(div_nonneg_of_pos_of_nonneg $pa $pb)) + | .nonnegative pa, .positive pb => pure (.nonnegative q(div_nonneg_of_nonneg_of_pos $pa $pb)) + | .nonnegative pa, .nonnegative pb => pure (.nonnegative q(div_nonneg $pa $pb)) + | .positive pa, .nonzero pb => pure (.nonzero q(div_ne_zero_of_pos_of_ne_zero $pa $pb)) + | .nonzero pa, .positive pb => pure (.nonzero q(div_ne_zero_of_ne_zero_of_pos $pa $pb)) + | .nonzero pa, .nonzero pb => pure (.nonzero q(div_ne_zero $pa $pb)) + | _, _ => pure .none /-- The `positivity` extension which identifies expressions of the form `a⁻¹`, such that `positivity` successfully recognises `a`. -/ @@ -769,33 +771,35 @@ meta def evalInv : PositivityExt where eval {u α} zα pα? e := do let _e_eq : $e =Q $f $a := ⟨⟩ let _a ← synthInstanceQ q(Semifield $α) let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(Inv.inv) - let some _ := pα? | + match (dependent := true) pα? with + | none => match ← core zα pα? a with | .nonzero pa => let _a ← synthInstanceQ q(GroupWithZero $α) assumeInstancesCommute pure (.nonzero q(inv_ne_zero $pa)) | _ => pure .none - let _a ← synthInstanceQ q(GroupWithZero $α) - let _a ← synthInstanceQ q(PartialOrder $α) - let _a ← synthInstanceQ q(PosMulReflectLT $α) - assumeInstancesCommute - let ra ← core zα pα? a - match ra with - | .positive pa => + | some pα => + let _a ← synthInstanceQ q(GroupWithZero $α) + let _a ← synthInstanceQ q(PartialOrder $α) + let _a ← synthInstanceQ q(PosMulReflectLT $α) assumeInstancesCommute - pure (.positive q(inv_pos_of_pos $pa)) - | .nonnegative pa => - assumeInstancesCommute - pure (.nonnegative q(inv_nonneg_of_nonneg $pa)) - | .nonzero pa => pure (.nonzero q(inv_ne_zero $pa)) - | .none => pure .none + let ra ← core zα (some pα) a + match ra with + | .positive pa => + assumeInstancesCommute + pure (.positive q(inv_pos_of_pos $pa)) + | .nonnegative pa => + assumeInstancesCommute + pure (.nonnegative q(inv_nonneg_of_nonneg $pa)) + | .nonzero pa => pure (.nonzero q(inv_ne_zero $pa)) + | .none => pure .none /-- The `positivity` extension which identifies expressions of the form `a ^ (0:ℤ)`. -/ @[positivity _ ^ (0 : ℤ), Pow.pow _ (0 : ℤ)] -meta def evalPowZeroInt : PositivityExt where eval {u α} _zα pα? e := do +meta def evalPowZeroInt : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do let .app (.app _ (a : Q($α))) _ ← withReducible (whnf e) | throwError "not ^" - let some _ := pα? | pure .none let _a ← synthInstanceQ q(Semifield $α) let _a ← synthInstanceQ q(LinearOrder $α) let _a ← synthInstanceQ q(IsStrictOrderedRing $α) diff --git a/Mathlib/Algebra/Order/Field/Power.lean b/Mathlib/Algebra/Order/Field/Power.lean index 921d4a96f7f17f..99b8427345bff4 100644 --- a/Mathlib/Algebra/Order/Field/Power.lean +++ b/Mathlib/Algebra/Order/Field/Power.lean @@ -125,7 +125,8 @@ such that `positivity` successfully recognises both `a` and `b`. -/ @[positivity _ ^ (_ : ℤ), Pow.pow _ (_ : ℤ)] meta def evalZPow : PositivityExt where eval {u α} zα pα? e := do let .app (.app _ (a : Q($α))) (b : Q(ℤ)) ← withReducible (whnf e) | throwError "not ^" - let some pα := pα? | + match (dependent := true) pα? with + | none => match ← core zα pα? a with | .nonzero pa => let _a ← synthInstanceQ q(GroupWithZero $α) @@ -133,61 +134,62 @@ meta def evalZPow : PositivityExt where eval {u α} zα pα? e := do haveI' : $e =Q $a ^ $b := ⟨⟩ pure (.nonzero q(zpow_ne_zero $b $pa)) | _ => pure .none - let result ← catchNone do - let _a ← synthInstanceQ q(Field $α) - let _a ← synthInstanceQ q(LinearOrder $α) - let _a ← synthInstanceQ q(IsStrictOrderedRing $α) - assumeInstancesCommute - match ← whnfR b with - | .app (.app (.app (.const `OfNat.ofNat _) _) (.lit (Literal.natVal n))) _ => - guard (n % 2 = 0) - have m : Q(ℕ) := mkRawNatLit (n / 2) - haveI' : $b =Q $m + $m := ⟨⟩ - haveI' : $e =Q $a ^ $b := ⟨⟩ - pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a)) - | .app (.app (.app (.const `Neg.neg _) _) _) b' => - let b' ← whnfR b' - let .true := b'.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ -n where n is a literal" - let some n := (b'.getRevArg! 1).rawNatLit? | throwError "not a ^ -n where n is a literal" - guard (n % 2 = 0) - have m : Q(ℕ) := mkRawNatLit (n / 2) - haveI' : $b =Q (-$m) + (-$m) := ⟨⟩ - haveI' : $e =Q $a ^ $b := ⟨⟩ - pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a)) - | _ => throwError "not a ^ n where n is a literal or a negated literal" - orElse result do - let ra ← core zα pα a - let ofNonneg (pa : Q(0 ≤ $a)) - (_oα : Q(Semifield $α)) (_oα : Q(LinearOrder $α)) (_oα : Q(IsStrictOrderedRing $α)) : - MetaM (Strictness zα e pα) := do - haveI' : $e =Q $a ^ $b := ⟨⟩ - assumeInstancesCommute - pure (.nonnegative q(zpow_nonneg $pa $b)) - let ofNonzero (pa : Q($a ≠ 0)) (_oα : Q(GroupWithZero $α)) : MetaM (Strictness zα e pα) := do - haveI' : $e =Q $a ^ $b := ⟨⟩ - let _a ← synthInstanceQ q(GroupWithZero $α) + | some pα => + let result ← catchNone do + let _a ← synthInstanceQ q(Field $α) + let _a ← synthInstanceQ q(LinearOrder $α) + let _a ← synthInstanceQ q(IsStrictOrderedRing $α) assumeInstancesCommute - pure (.nonzero q(zpow_ne_zero $b $pa)) - match ra with - | .positive pa => - try - let _a ← synthInstanceQ q(Semifield $α) - let _a ← synthInstanceQ q(LinearOrder $α) - let _a ← synthInstanceQ q(IsStrictOrderedRing $α) + match ← whnfR b with + | .app (.app (.app (.const `OfNat.ofNat _) _) (.lit (Literal.natVal n))) _ => + guard (n % 2 = 0) + have m : Q(ℕ) := mkRawNatLit (n / 2) + haveI' : $b =Q $m + $m := ⟨⟩ + haveI' : $e =Q $a ^ $b := ⟨⟩ + pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a)) + | .app (.app (.app (.const `Neg.neg _) _) _) b' => + let b' ← whnfR b' + let .true := b'.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ -n where n is a literal" + let some n := (b'.getRevArg! 1).rawNatLit? | throwError "not a ^ -n where n is a literal" + guard (n % 2 = 0) + have m : Q(ℕ) := mkRawNatLit (n / 2) + haveI' : $b =Q (-$m) + (-$m) := ⟨⟩ + haveI' : $e =Q $a ^ $b := ⟨⟩ + pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a)) + | _ => throwError "not a ^ n where n is a literal or a negated literal" + orElse result do + let ra ← core zα pα a + let ofNonneg (pa : Q(0 ≤ $a)) + (_oα : Q(Semifield $α)) (_oα : Q(LinearOrder $α)) (_oα : Q(IsStrictOrderedRing $α)) : + MetaM (Strictness zα e pα) := do + haveI' : $e =Q $a ^ $b := ⟨⟩ assumeInstancesCommute + pure (.nonnegative q(zpow_nonneg $pa $b)) + let ofNonzero (pa : Q($a ≠ 0)) (_oα : Q(GroupWithZero $α)) : MetaM (Strictness zα e pα) := do haveI' : $e =Q $a ^ $b := ⟨⟩ - pure (.positive q(zpow_pos $pa $b)) - catch e : Exception => - trace[Tactic.positivity.failure] "{e.toMessageData}" - let sα ← synthInstanceQ q(Semifield $α) - let oα ← synthInstanceQ q(LinearOrder $α) - let iα ← synthInstanceQ q(IsStrictOrderedRing $α) - orElse (← catchNone (ofNonneg q(le_of_lt $pa) sα oα iα)) - (ofNonzero q(ne_of_gt $pa) q(inferInstance)) - | .nonnegative pa => - ofNonneg pa (← synthInstanceQ (_ : Q(Type u))) - (← synthInstanceQ (_ : Q(Type u))) (← synthInstanceQ (_ : Q(Prop))) - | .nonzero pa => ofNonzero pa (← synthInstanceQ (_ : Q(Type u))) - | .none => pure .none + let _a ← synthInstanceQ q(GroupWithZero $α) + assumeInstancesCommute + pure (.nonzero q(zpow_ne_zero $b $pa)) + match ra with + | .positive pa => + try + let _a ← synthInstanceQ q(Semifield $α) + let _a ← synthInstanceQ q(LinearOrder $α) + let _a ← synthInstanceQ q(IsStrictOrderedRing $α) + assumeInstancesCommute + haveI' : $e =Q $a ^ $b := ⟨⟩ + pure (.positive q(zpow_pos $pa $b)) + catch e : Exception => + trace[Tactic.positivity.failure] "{e.toMessageData}" + let sα ← synthInstanceQ q(Semifield $α) + let oα ← synthInstanceQ q(LinearOrder $α) + let iα ← synthInstanceQ q(IsStrictOrderedRing $α) + orElse (← catchNone (ofNonneg q(le_of_lt $pa) sα oα iα)) + (ofNonzero q(ne_of_gt $pa) q(inferInstance)) + | .nonnegative pa => + ofNonneg pa (← synthInstanceQ (_ : Q(Type u))) + (← synthInstanceQ (_ : Q(Type u))) (← synthInstanceQ (_ : Q(Prop))) + | .nonzero pa => ofNonzero pa (← synthInstanceQ (_ : Q(Type u))) + | .none => pure .none end Mathlib.Meta.Positivity diff --git a/Mathlib/Algebra/Order/Floor/Extended.lean b/Mathlib/Algebra/Order/Floor/Extended.lean index 3708cc1a32b067..3b73682846a96d 100644 --- a/Mathlib/Algebra/Order/Floor/Extended.lean +++ b/Mathlib/Algebra/Order/Floor/Extended.lean @@ -256,10 +256,10 @@ alias ⟨_, natCeil_pos⟩ := ENat.ceil_pos /-- Extension for the `positivity` tactic: `ENat.ceil` is positive if its input is. -/ @[positivity ⌈_⌉ₑ] -meta def evalENatCeil : PositivityExt where eval {u α} _zα pα? e := do +meta def evalENatCeil : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ∞), ~q(ENat.ceil $r) => - let some _ := pα? | pure .none match ← core q(inferInstance) (some q(inferInstance)) r with | .positive pr => assertInstancesCommute diff --git a/Mathlib/Algebra/Order/Floor/Ring.lean b/Mathlib/Algebra/Order/Floor/Ring.lean index a7b86a5d802241..8aeced5d83d30d 100644 --- a/Mathlib/Algebra/Order/Floor/Ring.lean +++ b/Mathlib/Algebra/Order/Floor/Ring.lean @@ -50,10 +50,10 @@ theorem int_floor_nonneg_of_pos [Ring α] [LinearOrder α] [FloorRing α] {a : /-- Extension for the `positivity` tactic: `Int.floor` is nonnegative if its input is. -/ @[positivity ⌊_⌋] -meta def evalIntFloor : PositivityExt where eval {u α} _zα pα? e := do +meta def evalIntFloor : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℤ), ~q(@Int.floor $α' $ir $io $j $a) => - let some _ := pα? | pure .none match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute @@ -70,10 +70,10 @@ theorem nat_ceil_pos [Semiring α] [LinearOrder α] [FloorSemiring α] {a : α} /-- Extension for the `positivity` tactic: `Nat.ceil` is positive if its input is. -/ @[positivity ⌈_⌉₊] -meta def evalNatCeil : PositivityExt where eval {u α} _zα pα? e := do +meta def evalNatCeil : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(@Nat.ceil $α' $ir $io $j $a) => - let some _ := pα? | pure .none let _i ← synthInstanceQ q(LinearOrder $α') let _i ← synthInstanceQ q(IsStrictOrderedRing $α') assertInstancesCommute @@ -89,10 +89,10 @@ theorem int_ceil_pos [Ring α] [LinearOrder α] [FloorRing α] {a : α} : 0 < a /-- Extension for the `positivity` tactic: `Int.ceil` is positive/nonnegative if its input is. -/ @[positivity ⌈_⌉] -meta def evalIntCeil : PositivityExt where eval {u α} _zα pα? e := do +meta def evalIntCeil : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℤ), ~q(@Int.ceil $α' $ir $io $j $a) => - let some _ := pα? | pure .none match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute diff --git a/Mathlib/Algebra/Order/Interval/Basic.lean b/Mathlib/Algebra/Order/Interval/Basic.lean index 620b79a1c6fa82..b833e2ff856d15 100644 --- a/Mathlib/Algebra/Order/Interval/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Basic.lean @@ -660,10 +660,10 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/ @[positivity NonemptyInterval.length _] meta def evalNonemptyIntervalLength : PositivityExt where - eval {u α} _ pα? e := do + eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do let ~q(@NonemptyInterval.length _ $ig $ipo $a) := e | throwError "not NonemptyInterval.length" - let some _ := pα? | pure .none let _i ← synthInstanceQ q(IsOrderedAddMonoid $α) assertInstancesCommute return .nonnegative q(NonemptyInterval.length_nonneg $a) @@ -671,9 +671,9 @@ meta def evalNonemptyIntervalLength : PositivityExt where /-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/ @[positivity Interval.length _] meta def evalIntervalLength : PositivityExt where - eval {u α} _ pα? e := do + eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do let ~q(@Interval.length _ $ig $ipo $a) := e | throwError "not Interval.length" - let some _ := pα? | pure .none let _i ← synthInstanceQ q(IsOrderedAddMonoid $α) assumeInstancesCommute return .nonnegative q(Interval.length_nonneg $a) diff --git a/Mathlib/Algebra/Order/Module/Field.lean b/Mathlib/Algebra/Order/Module/Field.lean index f1575550df9058..e09bbc4544fd08 100644 --- a/Mathlib/Algebra/Order/Module/Field.lean +++ b/Mathlib/Algebra/Order/Module/Field.lean @@ -103,8 +103,8 @@ end Module.IsTorsionFree /-- Positivity extension for scalar multiplication. -/ @[positivity HSMul.hSMul _ _] -meta def evalSMul : PositivityExt where eval {_u α} zα pα? (e : Q($α)) := do - let some pα := pα? | pure .none +meta def evalSMul : PositivityExt where eval {_u α} zα pα? (e : Q($α)) := + match pα? with | none => pure .none | some pα => do let .app (.app (.app (.app (.app (.app (.const ``HSMul.hSMul [u1, _, _]) (β : Q(Type u1))) _) _) _) (a : Q($β))) (b : Q($α)) ← whnfR e | throwError "failed to match hSMul" diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index 5d95d2378a9389..1bf61e0671053f 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -692,10 +692,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `Real.exp` is always positive. -/ @[positivity Real.exp _] -meta def evalExp : PositivityExt where eval {u α} _ pα? e := do +meta def evalExp : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.exp $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(Real.exp_pos $a)) | _, _, _ => throwError "not Real.exp" diff --git a/Mathlib/Analysis/Complex/Order.lean b/Mathlib/Analysis/Complex/Order.lean index 03bf6ffb6cb7fa..43dc270e625bde 100644 --- a/Mathlib/Analysis/Complex/Order.lean +++ b/Mathlib/Analysis/Complex/Order.lean @@ -142,10 +142,10 @@ alias ⟨_, ofReal_ne_zero_of_ne_zero⟩ := ofReal_ne_zero /-- Extension for the `positivity` tactic: `Complex.ofReal` is positive/nonnegative/nonzero if its input is. -/ @[positivity Complex.ofReal _, Complex.ofReal _] -meta def evalComplexOfReal : PositivityExt where eval {u α} _ pα? e := do +meta def evalComplexOfReal : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℂ), ~q(Complex.ofReal $a) => - let some _ := pα? | pure .none assumeInstancesCommute match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => return .positive q(ofReal_pos $pa) diff --git a/Mathlib/Analysis/Complex/Trigonometric.lean b/Mathlib/Analysis/Complex/Trigonometric.lean index 44d62339fd1e11..554e4153002295 100644 --- a/Mathlib/Analysis/Complex/Trigonometric.lean +++ b/Mathlib/Analysis/Complex/Trigonometric.lean @@ -940,10 +940,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `Real.cosh` is always positive. -/ @[positivity Real.cosh _] -meta def evalCosh : PositivityExt where eval {u α} _ pα? e := do +meta def evalCosh : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.cosh $a) => - let some _ := pα? | pure .none assertInstancesCommute return .positive q(Real.cosh_pos $a) | _, _, _ => throwError "not Real.cosh" diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 1ce4914b6dffdb..6786ec87928768 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -148,20 +148,20 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `UpperHalfPlane.im`. -/ @[positivity UpperHalfPlane.im _] -meta def evalUpperHalfPlaneIm : PositivityExt where eval {u α} _zα pα? e := do +meta def evalUpperHalfPlaneIm : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(UpperHalfPlane.im $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(@UpperHalfPlane.im_pos $a)) | _, _, _ => throwError "not UpperHalfPlane.im" /-- Extension for the `positivity` tactic: `UpperHalfPlane.coe`. -/ @[positivity UpperHalfPlane.coe _] -meta def evalUpperHalfPlaneCoe : PositivityExt where eval {u α} _zα pα? e := do +meta def evalUpperHalfPlaneCoe : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℂ), ~q(UpperHalfPlane.coe $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonzero q(@UpperHalfPlane.ne_zero $a)) | _, _, _ => throwError "not UpperHalfPlane.coe" diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index 0409bfc27bfc7b..f0789e63185df6 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -1069,17 +1069,17 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: multiplicative norms are always nonnegative, and positive on non-one inputs. -/ @[positivity ‖_‖] -meta def evalMulNorm : PositivityExt where eval {u α} _ pα? e := do +meta def evalMulNorm : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@Norm.norm $E $_n $a) => - let some _ := pα? | pure .none let _seminormedGroup_E ← synthInstanceQ q(SeminormedGroup $E) assertInstancesCommute -- Check whether we are in a normed group and whether the context contains a `a ≠ 1` assumption - let o : Option (Q(NormedGroup $E) × Q($a ≠ 1)) := ← do - let .some normedGroup_E ← trySynthInstanceQ q(NormedGroup $E) | return none - let some pa ← findLocalDeclWithTypeQ? q($a ≠ 1) | return none - return some (normedGroup_E, pa) + let o : Option (Q(NormedGroup $E) × Q($a ≠ 1)) ← do + let .some normedGroup_E ← trySynthInstanceQ q(NormedGroup $E) | pure none + let some pa ← findLocalDeclWithTypeQ? q($a ≠ 1) | pure none + pure <| some (normedGroup_E, pa) match o with -- If so, return a proof of `0 < ‖a‖` | some (_normedGroup_E, pa) => @@ -1092,17 +1092,17 @@ meta def evalMulNorm : PositivityExt where eval {u α} _ pα? e := do /-- Extension for the `positivity` tactic: additive norms are always nonnegative, and positive on non-zero inputs. -/ @[positivity ‖_‖] -meta def evalAddNorm : PositivityExt where eval {u α} _ pα? e := do +meta def evalAddNorm : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@Norm.norm $E $_n $a) => - let some _ := pα? | pure .none let _seminormedAddGroup_E ← synthInstanceQ q(SeminormedAddGroup $E) assertInstancesCommute -- Check whether we are in a normed group and whether the context contains a `a ≠ 0` assumption - let o : Option (Q(NormedAddGroup $E) × Q($a ≠ 0)) := ← do - let .some normedAddGroup_E ← trySynthInstanceQ q(NormedAddGroup $E) | return none - let some pa ← findLocalDeclWithTypeQ? q($a ≠ 0) | return none - return some (normedAddGroup_E, pa) + let o : Option (Q(NormedAddGroup $E) × Q($a ≠ 0)) ← do + let .some normedAddGroup_E ← trySynthInstanceQ q(NormedAddGroup $E) | pure none + let some pa ← findLocalDeclWithTypeQ? q($a ≠ 0) | pure none + pure <| some (normedAddGroup_E, pa) match o with -- If so, return a proof of `0 < ‖a‖` | some (_normedAddGroup_E, pa) => diff --git a/Mathlib/Analysis/Real/Sqrt.lean b/Mathlib/Analysis/Real/Sqrt.lean index bb2d0f3c36425a..3b8cd015df8f07 100644 --- a/Mathlib/Analysis/Real/Sqrt.lean +++ b/Mathlib/Analysis/Real/Sqrt.lean @@ -312,8 +312,8 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: a square root of a strictly positive nonnegative real is positive. -/ @[positivity NNReal.sqrt _] -meta def evalNNRealSqrt : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalNNRealSqrt : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(NNReal), ~q(NNReal.sqrt $a) => assertInstancesCommute @@ -326,8 +326,8 @@ meta def evalNNRealSqrt : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for the `positivity` tactic: a square root is nonnegative, and is strictly positive if its input is. -/ @[positivity √_] -meta def evalSqrt : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalSqrt : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(√$a) => assertInstancesCommute diff --git a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean index 2e650b4aa8f761..ca7fffbc5653b5 100644 --- a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean +++ b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean @@ -80,9 +80,9 @@ open Lean Meta Qq Function /-- Extension of the `positivity` tactic for Bernstein polynomials: they are always non-negative. -/ @[positivity DFunLike.coe (bernstein _ _) _] -meta def evalBernstein : PositivityExt where eval {_ _} _zα pα? e := do +meta def evalBernstein : PositivityExt where eval {_ _} _zα pα? e := + match pα? with | none => pure .none | some _ => do let .app (.app _coe (.app (.app _ n) ν)) x ← whnfR e | throwError "not bernstein polynomial" - let some _ := pα? | pure .none let p ← mkAppOptM ``bernstein_nonneg #[n, ν, x] pure (.nonnegative p) diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index 16c34c92f0cf0a..a57539a4f3e2de 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -472,10 +472,10 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) : open Lean.Meta Qq Mathlib.Meta.Positivity in /-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/ @[positivity Gamma (_ : ℝ)] -meta def _root_.Mathlib.Meta.Positivity.evalGamma : PositivityExt where eval {u α} _zα pα? e := do +meta def _root_.Mathlib.Meta.Positivity.evalGamma : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Gamma $a) => - let some _ := pα? | pure .none match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => assertInstancesCommute diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index a50cc14b759129..cc7333c231aa1b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -596,30 +596,30 @@ lemma log_nz_of_isRat_neg {n : ℤ} : (NormNum.IsRat e n d) → (decide (n / d < /-- Extension for the `positivity` tactic: `Real.log` of a natural number is always nonnegative. -/ @[positivity Real.log (Nat.cast _)] -meta def evalLogNatCast : PositivityExt where eval {u α} _zα pα? e := do +meta def evalLogNatCast : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.log (Nat.cast $a)) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(Real.log_natCast_nonneg $a)) | _, _, _ => throwError "not Real.log" /-- Extension for the `positivity` tactic: `Real.log` of an integer is always nonnegative. -/ @[positivity Real.log (Int.cast _)] -meta def evalLogIntCast : PositivityExt where eval {u α} _zα pα? e := do +meta def evalLogIntCast : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.log (Int.cast $a)) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(Real.log_intCast_nonneg $a)) | _, _, _ => throwError "not Real.log" /-- Extension for the `positivity` tactic: `Real.log` of a numeric literal. -/ @[positivity Real.log _] -meta def evalLogNatLit : PositivityExt where eval {u α} _ pα? e := do +meta def evalLogNatLit : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.log $a) => - let some _ := pα? | pure .none match ← NormNum.derive a with | .isNat (_ : Q(AddMonoidWithOne ℝ)) lit p => assumeInstancesCommute diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean b/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean index ccde81c19c3eca..6e98036e4a5139 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean @@ -1125,8 +1125,8 @@ open Lean Meta Qq the base is nonnegative and positive when the base is positive. This is the `NNReal` analogue of `evalRpow` for `Real`. -/ @[positivity (_ : ℝ≥0) ^ (_ : ℝ)] -meta def evalNNRealRpow : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | pure .none +meta def evalNNRealRpow : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ≥0), ~q($a ^ (0 : ℝ)) => assertInstancesCommute @@ -1155,8 +1155,8 @@ private meta def isFiniteM? (x : Q(ℝ≥0∞)) : MetaM (Option Q($x ≠ (⊤ : the base is nonnegative and positive when the base is positive. This is the `ENNReal` analogue of `evalRpow` for `Real`. -/ @[positivity (_ : ℝ≥0∞) ^ (_ : ℝ)] -meta def evalENNRealRpow : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | pure .none +meta def evalENNRealRpow : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ≥0∞), ~q($a ^ (0 : ℝ)) => assertInstancesCommute diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean index b220c5e0e31fdb..4fa7722f332deb 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean @@ -375,8 +375,8 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: exponentiation by a real number is positive (namely 1) when the exponent is zero. The other cases are done in `evalRpow`. -/ @[positivity (_ : ℝ) ^ (0 : ℝ)] -meta def evalRpowZero : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | pure .none +meta def evalRpowZero : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q($a ^ (0 : ℝ)) => assertInstancesCommute @@ -386,8 +386,8 @@ meta def evalRpowZero : PositivityExt where eval {u α} _ pα? e := do /-- Extension for the `positivity` tactic: exponentiation by a real number is nonnegative when the base is nonnegative and positive when the base is positive. -/ @[positivity (_ : ℝ) ^ (_ : ℝ)] -meta def evalRpow : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalRpow : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q($a ^ ($b : ℝ)) => assertInstancesCommute diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean index db73145896a607..a4f209c1ff56de 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean @@ -399,7 +399,8 @@ open Lean Meta Qq /-- Extension for `Real.arctan`. -/ @[positivity Real.arctan _] -meta def evalRealArctan : PositivityExt where eval {u α} z p e := do +meta def evalRealArctan : PositivityExt where eval {u α} z p e := + match p with | none => pure .none | some p => do match u, α, e with | 0, ~q(ℝ), ~q(Real.arctan $a) => let ra ← core z p a @@ -418,17 +419,18 @@ meta def evalRealArctan : PositivityExt where eval {u α} z p e := do /-- Extension for `Real.cos (Real.arctan _)`. -/ @[positivity Real.cos (Real.arctan _)] -meta def evalRealCosArctan : PositivityExt where eval {u α} _ pα? e := do +meta def evalRealCosArctan : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.cos (Real.arctan $a)) => - let some _ := pα? | pure .none assumeInstancesCommute return .positive q(Real.cos_arctan_pos _) | _ => throwError "not Real.cos (Real.arctan _)" /-- Extension for `Real.sin (Real.arctan _)`. -/ @[positivity Real.sin (Real.arctan _)] -meta def evalRealSinArctan : PositivityExt where eval {u α} z p e := do +meta def evalRealSinArctan : PositivityExt where eval {u α} z p e := + match p with | none => pure .none | some p => do match u, α, e with | 0, ~q(ℝ), ~q(Real.sin (Real.arctan $a)) => match ← core z p a with diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean index 6d712d0f1aa57e..86ee5817a80fec 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean @@ -177,10 +177,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `π` is always positive. -/ @[positivity Real.pi] -meta def evalRealPi : PositivityExt where eval {u α} _zα pα? e := do +meta def evalRealPi : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(Real.pi) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(Real.pi_pos)) | _, _, _ => throwError "not Real.pi" diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean index d4ae1114b1700b..7568fe3549d181 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean @@ -798,8 +798,8 @@ alias ⟨_, sinh_ne_zero_of_ne_zero⟩ := Real.sinh_ne_zero /-- Extension for the `positivity` tactic: `Real.sinh` is positive/nonnegative/nonzero if its input is. -/ @[positivity Real.sinh _] -meta def evalSinh : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | pure .none +meta def evalSinh : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do let zα : Q(Zero ℝ) := q(inferInstance) let pα : Q(PartialOrder ℝ) := q(inferInstance) match u, α, e with diff --git a/Mathlib/CategoryTheory/Bicategory/Basic.lean b/Mathlib/CategoryTheory/Bicategory/Basic.lean index 130bb40e313fbe..a715b9ac6890cd 100644 --- a/Mathlib/CategoryTheory/Bicategory/Basic.lean +++ b/Mathlib/CategoryTheory/Bicategory/Basic.lean @@ -48,6 +48,7 @@ universe w v u open Category Iso -- intended to be used with explicit universe parameters +set_option linter.checkUnivs false in /-- In a bicategory, we can compose the 1-morphisms `f : a ⟶ b` and `g : b ⟶ c` to obtain a 1-morphism `f ≫ g : a ⟶ c`. This composition does not need to be strictly associative, but there is a specified associator, `α_ f g h : (f ≫ g) ≫ h ≅ f ≫ (g ≫ h)`. diff --git a/Mathlib/CategoryTheory/Category/Cat.lean b/Mathlib/CategoryTheory/Category/Cat.lean index f1335563886635..b179e05ca015f0 100644 --- a/Mathlib/CategoryTheory/Category/Cat.lean +++ b/Mathlib/CategoryTheory/Category/Cat.lean @@ -31,6 +31,7 @@ namespace CategoryTheory open Bicategory Functor -- intended to be used with explicit universe parameters +set_option linter.checkUnivs false in /-- Category of categories. -/ @[nolint checkUnivs] def Cat := diff --git a/Mathlib/CategoryTheory/Category/Preorder.lean b/Mathlib/CategoryTheory/Category/Preorder.lean index 6a0802ed2d49da..8e91d464d4b631 100644 --- a/Mathlib/CategoryTheory/Category/Preorder.lean +++ b/Mathlib/CategoryTheory/Category/Preorder.lean @@ -80,6 +80,7 @@ theorem homOfLE_comp {x y z : X} (h : x ≤ y) (k : y ≤ z) : theorem leOfHom {x y : X} (h : x ⟶ y) : x ≤ y := h.down.down +set_option linter.defProp false in @[nolint defLemma, inherit_doc leOfHom] abbrev _root_.Quiver.Hom.le := @leOfHom diff --git a/Mathlib/CategoryTheory/Category/Quiv.lean b/Mathlib/CategoryTheory/Category/Quiv.lean index 473229f413a7c4..60b2bf23c8709f 100644 --- a/Mathlib/CategoryTheory/Category/Quiv.lean +++ b/Mathlib/CategoryTheory/Category/Quiv.lean @@ -22,6 +22,7 @@ universe v u v₁ v₂ v₃ u₁ u₂ u₃ w namespace CategoryTheory -- intended to be used with explicit universe parameters +set_option linter.checkUnivs false in /-- Category of quivers. -/ @[nolint checkUnivs] def Quiv := diff --git a/Mathlib/CategoryTheory/Category/ReflQuiv.lean b/Mathlib/CategoryTheory/Category/ReflQuiv.lean index 9dd8b7a23195f1..f1dc344cb96886 100644 --- a/Mathlib/CategoryTheory/Category/ReflQuiv.lean +++ b/Mathlib/CategoryTheory/Category/ReflQuiv.lean @@ -21,6 +21,7 @@ The category `ReflQuiv` of (bundled) reflexive quivers, and the free/forgetful a namespace CategoryTheory universe v u v₁ v₂ u₁ u₂ +set_option linter.checkUnivs false in /-- Category of refl quivers. -/ @[nolint checkUnivs] def ReflQuiv := diff --git a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean index ed5734b16d5cd4..02f09d2a413c2a 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean @@ -36,6 +36,7 @@ open Functor Category NatTrans IsHomLift variable {𝒮 : Type u₁} [Category.{v₁} 𝒮] +set_option linter.checkUnivs false in /-- A based category over `𝒮` is a category `𝒳` together with a functor `p : 𝒳 ⥤ 𝒮`. -/ @[nolint checkUnivs] structure BasedCategory (𝒮 : Type u₁) [Category.{v₁} 𝒮] where diff --git a/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean b/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean index 7907d6276d3caa..7dc53e2dabba98 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean @@ -58,6 +58,7 @@ open CategoryTheory Functor Category IsCartesian IsHomLift Fiber variable {𝒮 : Type u₁} {𝒳 : Type u₂} [Category.{v₁} 𝒮] [Category.{v₂} 𝒳] +set_option linter.checkUnivs false in /-- HasFibers is an extrinsic notion of fibers on a functor `p : 𝒳 ⥤ 𝒮`. It is given by a collection of categories `Fib S` for every `S : 𝒮` (the fiber categories), each equipped with a functors `ι : Fib S ⥤ 𝒳` which map constantly to `S` on the base such that the induced functor diff --git a/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean b/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean index 9674e4558b323d..9860d8bd1379b6 100644 --- a/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean +++ b/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean @@ -33,6 +33,7 @@ universe v u namespace CategoryTheory -- intended to be used with explicit universe parameters +set_option linter.checkUnivs false in /-- Category of groupoids -/ @[nolint checkUnivs] def Grpd := diff --git a/Mathlib/CategoryTheory/Limits/Chosen/End.lean b/Mathlib/CategoryTheory/Limits/Chosen/End.lean index 29a4f819429c10..8bacfbd3374248 100644 --- a/Mathlib/CategoryTheory/Limits/Chosen/End.lean +++ b/Mathlib/CategoryTheory/Limits/Chosen/End.lean @@ -30,6 +30,7 @@ class ChosenCoendsOfShape (J : Type*) [Category* J] (C : Type*) [Category* C] wh /-- The chosen cowedge is colimiting. -/ isCoend (F : Jᵒᵖ ⥤ J ⥤ C) : IsColimit (cowedge F) +set_option linter.checkUnivs false in /-- The data of chosen coends in `C`. -/ @[nolint checkUnivs, pp_with_univ] abbrev ChosenCoends (C : Type*) [Category* C] := @@ -104,6 +105,7 @@ class ChosenEndsOfShape (J : Type*) [Category* J] (C : Type*) [Category* C] wher /-- The chosen wedge is limiting. -/ isEnd (F : Jᵒᵖ ⥤ J ⥤ C) : IsLimit (wedge F) +set_option linter.checkUnivs false in /-- The data of chosen ends in `C`. -/ @[nolint checkUnivs, pp_with_univ] abbrev ChosenEnds (C : Type*) [Category* C] := diff --git a/Mathlib/CategoryTheory/Limits/Creates.lean b/Mathlib/CategoryTheory/Limits/Creates.lean index 6e50771af6bbee..0608f6fb77867b 100644 --- a/Mathlib/CategoryTheory/Limits/Creates.lean +++ b/Mathlib/CategoryTheory/Limits/Creates.lean @@ -81,6 +81,7 @@ class CreatesLimitsOfShape (J : Type w) [Category.{w'} J] (F : C ⥤ D) where CreatesLimit : ∀ {K : J ⥤ C}, CreatesLimit K F := by infer_instance -- This should be used with explicit universe variables. +set_option linter.checkUnivs false in /-- `F` creates limits if it creates limits of shape `J` for any `J`. -/ -- After https://github.com/leanprover/lean4/pull/12286 and -- https://github.com/leanprover/lean4/pull/12423, the shape universes in @@ -114,6 +115,7 @@ class CreatesColimitsOfShape (J : Type w) [Category.{w'} J] (F : C ⥤ D) where CreatesColimit : ∀ {K : J ⥤ C}, CreatesColimit K F := by infer_instance -- This should be used with explicit universe variables. +set_option linter.checkUnivs false in /-- `F` creates colimits if it creates colimits of shape `J` for any small `J`. -/ @[univ_out_params, nolint checkUnivs, pp_with_univ] class CreatesColimitsOfSize (F : C ⥤ D) where diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index aaef3ca24fd17d..7a154e987b310e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -35,6 +35,7 @@ namespace CategoryTheory.Limits universe t w w' v u +set_option linter.checkUnivs false in /-- The shape of a multiequalizer diagram. It involves two types `L` and `R`, and two maps `R → L`. -/ @[nolint checkUnivs] @@ -58,6 +59,7 @@ def MulticospanShape.prod (ι : Type w) : MulticospanShape where fst := _root_.Prod.fst snd := _root_.Prod.snd +set_option linter.checkUnivs false in /-- The shape of a multicoequalizer diagram. It involves two types `L` and `R`, and two maps `L → R`. -/ @[nolint checkUnivs] diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index e3b93682c62958..db187334c5de14 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -181,6 +181,7 @@ variable [PreservesLimit (Functor.empty.{0} C) F] [PreservesLimitsOfShape (Discrete WalkingPair) F] set_option backward.defeqAttrib.useBackward true in +set_option linter.deprecated false in @[deprecated inferInstance (since := "2025-10-19")] instance : have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal @@ -190,6 +191,7 @@ instance : IsIso (η F) := by dsimp [η_eq]; apply instIsIsoTerminalComparison set_option backward.defeqAttrib.useBackward true in +set_option linter.deprecated false in @[deprecated inferInstance (since := "2025-10-19")] instance (X Y : C) : have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal diff --git a/Mathlib/CategoryTheory/MorphismProperty/Local.lean b/Mathlib/CategoryTheory/MorphismProperty/Local.lean index ba30a655b47b9a..60a80b23c863ab 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Local.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Local.lean @@ -135,7 +135,13 @@ instance inf (P Q : MorphismProperty C) [IsLocalAtTarget P K] [IsLocalAtTarget Q end IsLocalAtTarget -alias of_zeroHypercover_target := IsLocalAtTarget.of_zeroHypercover +set_option backward.defeqAttrib.useBackward true in +lemma of_zeroHypercover_target {P : MorphismProperty C} {K : Precoverage C} [K.HasPullbacks] + [P.IsLocalAtTarget K] {X Y : C} {f : X ⟶ Y} (𝒰 : Precoverage.ZeroHypercover.{w} K Y) + [Precoverage.ZeroHypercover.Small.{v} 𝒰] (h : ∀ i, P (pullback.snd f (𝒰.f i))) : + P f := by + rw [IsLocalAtTarget.iff_of_zeroHypercover (P := P) 𝒰.restrictIndexOfSmall] + simp [h] alias iff_of_zeroHypercover_target := IsLocalAtTarget.iff_of_zeroHypercover @@ -211,7 +217,13 @@ instance inf (P Q : MorphismProperty C) [IsLocalAtSource P K] [IsLocalAtSource Q end IsLocalAtSource -alias of_zeroHypercover_source := IsLocalAtSource.of_zeroHypercover +set_option backward.defeqAttrib.useBackward true in +lemma of_zeroHypercover_source {P : MorphismProperty C} {K : Precoverage C} + [P.IsLocalAtSource K] {X Y : C} {f : X ⟶ Y} (𝒰 : Precoverage.ZeroHypercover.{w} K X) + [Precoverage.ZeroHypercover.Small.{v} 𝒰] (h : ∀ i, P (𝒰.f i ≫ f)) : + P f := by + rw [IsLocalAtSource.iff_of_zeroHypercover (P := P) 𝒰.restrictIndexOfSmall] + simp [h] alias iff_of_zeroHypercover_source := IsLocalAtSource.iff_of_zeroHypercover diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index 0dfcee6466b377..b4462eda3c50f6 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -557,8 +557,8 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `p.firstReturn` is positive if `p` is nonzero. -/ @[positivity DyckWord.firstReturn _] -meta def evalDyckWordFirstReturn : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalDyckWordFirstReturn : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(DyckWord.firstReturn $a) => assertInstancesCommute diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index 66f54aeee73816..8e12c26ea959be 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -104,14 +104,18 @@ section Aliases we provide match patterns that preserve the defeq correctly in their type. -/ variable {M} [Semigroup M] (a : Stream' M) (m : M) (h : FP a.tail m) + +set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.head'`. -/ @[to_additive (attr := match_pattern, nolint defLemma) /-- Constructor for `FS`. This is the preferred spelling over `FS.head'`. -/] abbrev FP.head : a.head ∈ FP a := FP.head' a +set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.tail'`. -/ @[to_additive (attr := match_pattern, nolint defLemma) /-- Constructor for `FS`. This is the preferred spelling over `FS.tail'`. -/] abbrev FP.tail : m ∈ FP a := FP.tail' a m h +set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.cons'`. -/ @[to_additive (attr := match_pattern, nolint defLemma) /-- Constructor for `FS`. This is the preferred spelling over `FS.cons'`. -/] diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean index 10020841234a53..308abad39b08c1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean @@ -239,10 +239,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `SzemerediRegularity.initialBound` is always positive. -/ @[positivity SzemerediRegularity.initialBound _ _] -meta def evalInitialBound : PositivityExt where eval {u α} _ pα? e := do +meta def evalInitialBound : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(SzemerediRegularity.initialBound $ε $l) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(SzemerediRegularity.initialBound_pos $ε $l)) | _, _, _ => throwError "not initialBound" @@ -252,10 +252,10 @@ example (ε : ℝ) (l : ℕ) : 0 < SzemerediRegularity.initialBound ε l := by p /-- Extension for the `positivity` tactic: `SzemerediRegularity.bound` is always positive. -/ @[positivity SzemerediRegularity.bound _ _] -meta def evalBound : PositivityExt where eval {u α} _ pα? e := do +meta def evalBound : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(SzemerediRegularity.bound $ε $l) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(SzemerediRegularity.bound_pos $ε $l)) | _, _, _ => throwError "not bound" diff --git a/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean b/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean index 2e4f7bb17a6c94..3377d40e399d70 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Triangle/Removal.lean @@ -176,10 +176,10 @@ if `ε` is. This exploits the positivity of the junk value of `triangleRemovalBound ε` for `ε ≥ 1`. -/ @[positivity triangleRemovalBound _] -meta def evalTriangleRemovalBound : PositivityExt where eval {u α} _zα pα? e := do +meta def evalTriangleRemovalBound : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(triangleRemovalBound $ε) => - let some _ := pα? | pure .none let .positive hε ← core q(inferInstance) (some q(inferInstance)) ε | failure assertInstancesCommute pure (.positive q(triangleRemovalBound_pos $hε)) diff --git a/Mathlib/Computability/Partrec.lean b/Mathlib/Computability/Partrec.lean index f73cb614714702..0e6f71a84e1bc8 100644 --- a/Mathlib/Computability/Partrec.lean +++ b/Mathlib/Computability/Partrec.lean @@ -46,6 +46,7 @@ set_option backward.privateInPublic true in private def lbp (m n : ℕ) : Prop := m = n + 1 ∧ ∀ k ≤ n, false ∈ p k +set_option linter.defProp false in set_option backward.privateInPublic true in private def wf_lbp (H : ∃ n, true ∈ p n ∧ ∀ k < n, (p k).Dom) : WellFounded (lbp p) := ⟨by diff --git a/Mathlib/Data/ENNReal/Basic.lean b/Mathlib/Data/ENNReal/Basic.lean index 3b71f90289ab75..8679db698faccf 100644 --- a/Mathlib/Data/ENNReal/Basic.lean +++ b/Mathlib/Data/ENNReal/Basic.lean @@ -741,8 +741,8 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `ENNReal.toReal`. -/ @[positivity ENNReal.toReal _] -meta def evalENNRealtoReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalENNRealtoReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(ENNReal.toReal $a) => assertInstancesCommute @@ -751,8 +751,8 @@ meta def evalENNRealtoReal : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for the `positivity` tactic: `ENNReal.ofNNReal`. -/ @[positivity ENNReal.ofNNReal _] -meta def evalENNRealOfNNReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalENNRealOfNNReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ≥0∞), ~q(ENNReal.ofNNReal $a) => assertInstancesCommute diff --git a/Mathlib/Data/ENNReal/Real.lean b/Mathlib/Data/ENNReal/Real.lean index 6da5409e3594ec..2aeca7a1b8dabf 100644 --- a/Mathlib/Data/ENNReal/Real.lean +++ b/Mathlib/Data/ENNReal/Real.lean @@ -392,8 +392,8 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `ENNReal.ofReal`. -/ @[positivity ENNReal.ofReal _] -meta def evalENNRealOfReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalENNRealOfReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ≥0∞), ~q(ENNReal.ofReal $a) => assertInstancesCommute diff --git a/Mathlib/Data/EReal/Basic.lean b/Mathlib/Data/EReal/Basic.lean index 9cbb2d70f53709..2e8a1d014a1c2c 100644 --- a/Mathlib/Data/EReal/Basic.lean +++ b/Mathlib/Data/EReal/Basic.lean @@ -850,8 +850,8 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: cast from `ℝ` to `EReal`. -/ @[positivity Real.toEReal _] -meta def evalRealToEReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalRealToEReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(EReal), ~q(Real.toEReal $a) => assertInstancesCommute @@ -865,8 +865,8 @@ meta def evalRealToEReal : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for the `positivity` tactic: cast from `ℝ≥0∞` to `EReal`. -/ @[positivity ENNReal.toEReal _] -meta def evalENNRealToEReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalENNRealToEReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(EReal), ~q(ENNReal.toEReal $a) => assertInstancesCommute @@ -883,8 +883,8 @@ We prove that `EReal.toReal x` is nonnegative whenever `x` is nonnegative. Since `EReal.toReal ⊤ = 0`, we cannot prove a stronger statement, at least without relying on a tactic like `finiteness`. -/ @[positivity EReal.toReal _] -meta def evalERealToReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalERealToReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(Real), ~q(EReal.toReal $a) => assertInstancesCommute @@ -900,8 +900,8 @@ and it is nonnegative otherwise. We cannot deduce any corollaries from `x ≠ 0`, since `EReal.toENNReal x = 0` for `x < 0`. -/ @[positivity EReal.toENNReal _] -meta def evalERealToENNReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalERealToENNReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ENNReal), ~q(EReal.toENNReal $a) => assertInstancesCommute diff --git a/Mathlib/Data/EReal/Inv.lean b/Mathlib/Data/EReal/Inv.lean index e61ad93ab0efa8..20f2c4bbc6a20c 100644 --- a/Mathlib/Data/EReal/Inv.lean +++ b/Mathlib/Data/EReal/Inv.lean @@ -551,8 +551,8 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: inverse of an `EReal`. -/ @[positivity (_⁻¹ : EReal)] -meta def evalERealInv : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalERealInv : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match u, α, e with | 0, ~q(EReal), ~q($a⁻¹) => assertInstancesCommute @@ -563,8 +563,8 @@ meta def evalERealInv : PositivityExt where eval {u α} zα pα? e := do /-- Extension for the `positivity` tactic: ratio of two `EReal`s. -/ @[positivity (_ / _ : EReal)] -meta def evalERealDiv : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalERealDiv : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match u, α, e with | 0, ~q(EReal), ~q($a / $b) => assertInstancesCommute diff --git a/Mathlib/Data/EReal/Operations.lean b/Mathlib/Data/EReal/Operations.lean index 075d47a6994978..53bf367a596b7d 100644 --- a/Mathlib/Data/EReal/Operations.lean +++ b/Mathlib/Data/EReal/Operations.lean @@ -821,8 +821,8 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: sum of two `EReal`s. -/ @[positivity (_ + _ : EReal)] -meta def evalERealAdd : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalERealAdd : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match u, α, e with | 0, ~q(EReal), ~q($a + $b) => assertInstancesCommute @@ -841,8 +841,8 @@ meta def evalERealAdd : PositivityExt where eval {u α} zα pα? e := do /-- Extension for the `positivity` tactic: product of two `EReal`s. -/ @[positivity (_ * _ : EReal)] -meta def evalERealMul : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalERealMul : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match u, α, e with | 0, ~q(EReal), ~q($a * $b) => assertInstancesCommute diff --git a/Mathlib/Data/Fin/Tuple/Reflection.lean b/Mathlib/Data/Fin/Tuple/Reflection.lean index 0b5d508e05e0b9..e577f7abd086a9 100644 --- a/Mathlib/Data/Fin/Tuple/Reflection.lean +++ b/Mathlib/Data/Fin/Tuple/Reflection.lean @@ -175,10 +175,10 @@ open Lean Meta Qq that shows it is equal to `∏ i, f i`. -/ meta def mkProdEqQ {u : Level} {α : Q(Type u)} (inst : Q(CommMonoid $α)) (n : ℕ) (f : Q(Fin $n → $α)) : - MetaM <| (val : Q($α)) × Q(∏ i, $f i = $val) := do + MetaM <| (val : Q($α)) × Q(∏ i, $f i = $val) := match n with - | 0 => return ⟨q((1 : $α)), q(Fin.prod_univ_zero $f)⟩ - | m + 1 => + | 0 => do return ⟨q((1 : $α)), q(Fin.prod_univ_zero $f)⟩ + | m + 1 => do let nezero : Q(NeZero ($m + 1)) := q(⟨Nat.succ_ne_zero _⟩) let val ← makeRHS (m + 1) f nezero (m + 1) let _ : $val =Q FinVec.prod $f := ⟨⟩ @@ -198,10 +198,10 @@ where that shows it is equal to `∑ i, f i`. -/ meta def mkSumEqQ {u : Level} {α : Q(Type u)} (inst : Q(AddCommMonoid $α)) (n : ℕ) (f : Q(Fin $n → $α)) : - MetaM <| (val : Q($α)) × Q(∑ i, $f i = $val) := do + MetaM <| (val : Q($α)) × Q(∑ i, $f i = $val) := match n with | 0 => return ⟨q((0 : $α)), q(Fin.sum_univ_zero $f)⟩ - | m + 1 => + | m + 1 => do let nezero : Q(NeZero ($m + 1)) := q(⟨Nat.succ_ne_zero _⟩) let val ← makeRHS (m + 1) f nezero (m + 1) let _ : $val =Q FinVec.sum $f := ⟨⟩ @@ -228,7 +228,7 @@ open Qq Lean FinVec simproc_decl prod_univ_ofNat (∏ _ : Fin _, _) := .ofQ fun u _ e => do match u, e with | .succ _, ~q(@Finset.prod (Fin $n) _ $inst (@Finset.univ _ $instF) $f) => do - match (generalizing := false) n.nat? with + match n.nat? with | none => return .continue | some nVal => diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index d1a46797c16806..1e2243a3c8284b 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -1006,8 +1006,8 @@ alias ⟨_, nnreal_coe_pos⟩ := coe_pos /-- Extension for the `positivity` tactic: cast from `ℝ≥0` to `ℝ`. -/ @[positivity NNReal.toReal _] -meta def evalNNRealtoReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalNNRealtoReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(NNReal.toReal $a) => assertInstancesCommute @@ -1019,8 +1019,8 @@ meta def evalNNRealtoReal : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for the `positivity` tactic: `Real.toNNReal` -/ @[positivity Real.toNNReal _] -meta def evalRealToNNReal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalRealToNNReal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ≥0), ~q(Real.toNNReal $a) => assertInstancesCommute @@ -1033,8 +1033,8 @@ alias ⟨_, nnabs_pos_of_pos⟩ := Real.nnabs_pos /-- Extension for the `positivity` tactic: `Real.nnabs` -/ @[positivity Real.nnabs _] -meta def evalRealNNAbs : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalRealNNAbs : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ≥0), ~q(Real.nnabs $a) => assertInstancesCommute diff --git a/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean b/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean index 0d27087ca77713..7bb9f92d299545 100644 --- a/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean +++ b/Mathlib/Data/Nat/Factorial/DoubleFactorial.lean @@ -87,8 +87,8 @@ open Lean Meta Qq /-- Extension for `Nat.doubleFactorial`. -/ @[positivity Nat.doubleFactorial _] -meta def evalDoubleFactorial : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | pure .none +meta def evalDoubleFactorial : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.doubleFactorial $n) => assumeInstancesCommute diff --git a/Mathlib/Data/Nat/Find.lean b/Mathlib/Data/Nat/Find.lean index 250e74085224df..1a61e465b21bd9 100644 --- a/Mathlib/Data/Nat/Find.lean +++ b/Mathlib/Data/Nat/Find.lean @@ -29,6 +29,7 @@ private def lbp (m n : ℕ) : Prop := variable [DecidablePred p] (H : ∃ n, p n) +set_option linter.defProp false in set_option backward.privateInPublic true in private def wf_lbp : WellFounded (@lbp p) := ⟨let ⟨n, pn⟩ := H diff --git a/Mathlib/Data/Nat/Sqrt.lean b/Mathlib/Data/Nat/Sqrt.lean index a2f2013abde8af..6e0e55b225761c 100644 --- a/Mathlib/Data/Nat/Sqrt.lean +++ b/Mathlib/Data/Nat/Sqrt.lean @@ -6,7 +6,6 @@ Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro module public import Mathlib.Data.Nat.Basic -public import Batteries.Data.Nat.Basic /-! # Properties of the natural number square root function. @@ -28,92 +27,8 @@ See [Wikipedia, *Methods of computing square roots*] (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)). -/ -private lemma iter_fp_bound (n k : ℕ) : - let iter_next (n guess : ℕ) := (guess + n / guess) / 2; - sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by - intro iter_next - unfold sqrt.iter - if h : (k + n / k) / 2 < k then - simpa [if_pos h] using iter_fp_bound _ _ - else - grind - -private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b)) - | 0, _ => by rw [Nat.mul_zero, Nat.zero_mul]; exact zero_le _ - | _, 0 => by rw [Nat.mul_zero]; exact zero_le _ - | a + 1, b + 1 => by - simpa only [Nat.mul_add, Nat.add_mul, show (4 : ℕ) = 1 + 1 + 1 + 1 from rfl, Nat.one_mul, - Nat.mul_one, Nat.add_assoc, Nat.add_left_comm, Nat.add_le_add_iff_left] - using Nat.add_le_add_right (@AM_GM a b) 4 - --- These two lemmas seem like they belong to `Batteries.Data.Nat.Basic`. - -lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by - unfold sqrt.iter - let next := (guess + n / guess) / 2 - if h : next < guess then - simpa only [next, dif_pos h] using sqrt.iter_sq_le n next - else - apply Nat.mul_le_of_le_div - grind - -lemma sqrt.lt_iter_succ_sq (n guess : ℕ) (hn : n < (guess + 1) * (guess + 1)) : - n < (sqrt.iter n guess + 1) * (sqrt.iter n guess + 1) := by - unfold sqrt.iter - -- m was `next` - let m := (guess + n / guess) / 2 - dsimp - split_ifs with h - · suffices n < (m + 1) * (m + 1) by - simpa only [dif_pos h] using sqrt.lt_iter_succ_sq n m this - refine Nat.lt_of_mul_lt_mul_left ?_ (a := 4 * (guess * guess)) - apply Nat.lt_of_le_of_lt AM_GM - rw [show (4 : ℕ) = 2 * 2 from rfl] - rw [Nat.mul_mul_mul_comm 2, Nat.mul_mul_mul_comm (2 * guess)] - refine Nat.mul_self_lt_mul_self (?_ : _ < _ * ((_ / 2) + 1)) - rw [← add_div_right _ (by decide), Nat.mul_comm 2, Nat.mul_assoc, - show guess + n / guess + 2 = (guess + n / guess + 1) + 1 from rfl] - have aux_lemma {a : ℕ} : a ≤ 2 * ((a + 1) / 2) := by lia - refine lt_of_lt_of_le ?_ (Nat.mul_le_mul_left _ aux_lemma) - rw [Nat.add_assoc, Nat.mul_add] - exact Nat.add_lt_add_left (lt_mul_div_succ _ (lt_of_le_of_lt (Nat.zero_le m) h)) _ - · exact hn - -private def IsSqrt (n q : ℕ) : Prop := - q * q ≤ n ∧ n < (q + 1) * (q + 1) - -/- -Sketch of proof: -Up to rounding, in terms of the definition of `sqrt.iter`, - -* By AM-GM inequality, `next² ≥ n` giving one of the bounds. -* When we terminated, we have `guess ≥ next` from which we deduce the other bound `n ≥ next²`. - -To turn this into a lean proof we need to manipulate, use properties of natural number division etc. --/ -private lemma sqrt_isSqrt (n : ℕ) : IsSqrt n (sqrt n) := by - match n with - | 0 => simp [IsSqrt, sqrt] - | 1 => simp [IsSqrt, sqrt] - | n + 2 => - have h : ¬ (n + 2) ≤ 1 := by simp - simp only [IsSqrt, sqrt, h, ite_false] - refine ⟨sqrt.iter_sq_le _ _, sqrt.lt_iter_succ_sq _ _ ?_⟩ - simp only [Nat.mul_add, Nat.add_mul, Nat.one_mul, Nat.mul_one, ← Nat.add_assoc] - rw [Nat.lt_add_one_iff, Nat.add_assoc, ← Nat.mul_two] - refine le_trans (Nat.le_of_eq (div_add_mod' (n + 2) 2).symm) ?_ - rw [show (n + 2) / 2 * 2 + (n + 2) % 2 = n + 2 by grind] - simp only [shiftLeft_eq, Nat.one_mul] - refine Nat.le_of_lt (Nat.le_trans lt_log2_self (le_add_right_of_le ?_)) - rw [← Nat.pow_add] - grind - -lemma sqrt_le (n : ℕ) : sqrt n * sqrt n ≤ n := (sqrt_isSqrt n).left - lemma sqrt_le' (n : ℕ) : sqrt n ^ 2 ≤ n := by simpa [Nat.pow_two] using sqrt_le n -lemma lt_succ_sqrt (n : ℕ) : n < succ (sqrt n) * succ (sqrt n) := (sqrt_isSqrt n).right - lemma lt_succ_sqrt' (n : ℕ) : n < succ (sqrt n) ^ 2 := by simpa [Nat.pow_two] using lt_succ_sqrt n lemma sqrt_le_add (n : ℕ) : n ≤ sqrt n * sqrt n + sqrt n + sqrt n := by @@ -134,15 +49,8 @@ lemma sqrt_le_self (n : ℕ) : sqrt n ≤ n := le_trans (le_mul_self _) (sqrt_le @[gcongr] lemma sqrt_le_sqrt (h : m ≤ n) : sqrt m ≤ sqrt n := le_sqrt.2 (le_trans (sqrt_le _) h) -@[simp, grind =] lemma sqrt_zero : sqrt 0 = 0 := rfl - -@[simp, grind =] lemma sqrt_one : sqrt 1 = 1 := rfl - -lemma sqrt_eq_zero : sqrt n = 0 ↔ n = 0 := - ⟨fun h ↦ have := @sqrt_lt n 1; by grind, by grind⟩ - lemma eq_sqrt : a = sqrt n ↔ a * a ≤ n ∧ n < (a + 1) * (a + 1) := - ⟨fun e ↦ e.symm ▸ sqrt_isSqrt n, + ⟨fun e ↦ e.symm ▸ ⟨sqrt_le n, lt_succ_sqrt n⟩, fun ⟨h₁, h₂⟩ ↦ le_antisymm (le_sqrt.2 h₁) (le_of_lt_succ <| sqrt_lt.2 h₂)⟩ lemma eq_sqrt' : a = sqrt n ↔ a ^ 2 ≤ n ∧ n < (a + 1) ^ 2 := by @@ -178,8 +86,18 @@ lemma sqrt_succ_le_succ_sqrt (n : ℕ) : sqrt n.succ ≤ n.sqrt.succ := @[simp] lemma log2_two : (2 : ℕ).log2 = 1 := by simp [log2_def] +@[simp, grind =] lemma sqrt_zero : sqrt 0 = 0 := + eq_comm.1 (by simp [eq_sqrt]) + +@[simp, grind =] lemma sqrt_one : sqrt 1 = 1 := + eq_comm.1 (by simp [eq_sqrt]) + +lemma sqrt_eq_zero : sqrt n = 0 ↔ n = 0 := + ⟨fun h ↦ have := @sqrt_lt n 1; by grind, by grind⟩ + @[simp] -lemma sqrt_two : sqrt 2 = 1 := by simp [sqrt, sqrt.iter] +lemma sqrt_two : sqrt 2 = 1 := + eq_comm.1 (by simp [eq_sqrt]) lemma add_one_sqrt_le_of_ne_zero {n : ℕ} (hn : n ≠ 0) : (n + 1).sqrt ≤ n := le_induction (by simp) (fun n _ ih ↦ le_trans n.succ.sqrt_succ_le_succ_sqrt (succ_le_succ ih)) n diff --git a/Mathlib/Data/Nat/Totient.lean b/Mathlib/Data/Nat/Totient.lean index 82b080ac815907..c31f22ad920296 100644 --- a/Mathlib/Data/Nat/Totient.lean +++ b/Mathlib/Data/Nat/Totient.lean @@ -443,7 +443,8 @@ open Lean Meta Qq /-- Extension for `Nat.totient`. -/ @[positivity Nat.totient _] -meta def evalNatTotient : PositivityExt where eval {u α} z p e := do +meta def evalNatTotient : PositivityExt where eval {u α} z p e := + match p with | none => pure .none | some p => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.totient $n) => match ← core z p n with diff --git a/Mathlib/Data/PFunctor/Univariate/Basic.lean b/Mathlib/Data/PFunctor/Univariate/Basic.lean index 536ed9683b7150..69a65f27239bf0 100644 --- a/Mathlib/Data/PFunctor/Univariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Univariate/Basic.lean @@ -18,6 +18,7 @@ This file defines polynomial functors and the W-type construction as a polynomia universe u v uA uB uA₁ uB₁ uA₂ uB₂ v₁ v₂ v₃ +set_option linter.checkUnivs false in /-- A polynomial functor `P` is given by a type `A` and a family `B` of types over `A`. `P` maps any type `α` to a new type `P α`, which is defined as the sigma type `Σ x, P.B x → α`. diff --git a/Mathlib/Data/Rat/Cast/Order.lean b/Mathlib/Data/Rat/Cast/Order.lean index 935ce8e22c6bcf..8fecc133d64446 100644 --- a/Mathlib/Data/Rat/Cast/Order.lean +++ b/Mathlib/Data/Rat/Cast/Order.lean @@ -263,15 +263,21 @@ open Lean Meta Qq Function meta def evalRatCast : PositivityExt where eval {u α} _zα pα? e := do let ~q(@Rat.cast _ (_) ($a : ℚ)) := e | throwError "not Rat.cast" match ← core q(inferInstance) (some q(inferInstance)) a with - | .positive pa => - let some _ := pα? | pure .none - let _oα ← synthInstanceQ q(Field $α) - let _oα ← synthInstanceQ q(LinearOrder $α) - let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) - assumeInstancesCommute - return .positive q((Rat.cast_pos (K := $α)).mpr $pa) - | .nonnegative pa => - let some _ := pα? | pure .none + | .positive pa => id <| + match pα? with + | none => do + let _oα ← synthInstanceQ q(DivisionRing $α) + let _cα ← synthInstanceQ q(CharZero $α) + assumeInstancesCommute + return .nonzero q((Rat.cast_ne_zero (α := $α)).mpr ($pa).ne') + | some _ => do + let _oα ← synthInstanceQ q(Field $α) + let _oα ← synthInstanceQ q(LinearOrder $α) + let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) + assumeInstancesCommute + return .positive q((Rat.cast_pos (K := $α)).mpr $pa) + | .nonnegative pa => id <| + match pα? with | none => pure .none | some _ => do let _oα ← synthInstanceQ q(Field $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) @@ -286,18 +292,17 @@ meta def evalRatCast : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for NNRat.cast. -/ @[positivity NNRat.cast _] -meta def evalNNRatCast : PositivityExt where eval {u α} _zα pα? e := do +meta def evalNNRatCast : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do let ~q(@NNRat.cast _ (_) ($a : ℚ≥0)) := e | throwError "not NNRat.cast" match ← core q(inferInstance) (some q(inferInstance)) a with | .positive pa => - let some _ := pα? | pure .none let _oα ← synthInstanceQ q(Semifield $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) assumeInstancesCommute return .positive q((NNRat.cast_pos (K := $α)).mpr $pa) | _ => - let some _ := pα? | pure .none let _oα ← synthInstanceQ q(Semifield $α) let _oα ← synthInstanceQ q(LinearOrder $α) let _oα ← synthInstanceQ q(IsStrictOrderedRing $α) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index dc2cecbf723157..f76a7cbae7f149 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -667,6 +667,7 @@ theorem isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDis ⟨fun g q b ↦ Quotient.inductionOn' q fun h ↦ by simp [mul_smul, mulSemiringActionQuotient_smul_def]⟩ +set_option linter.defProp false in /-- If `G` acts on `C` commuting with `A`, then the action of `G ⧸ N` on `B` commutes with `A`. -/ @[implicit_reducible] def smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCommClass G A C] diff --git a/Mathlib/Geometry/Euclidean/Altitude.lean b/Mathlib/Geometry/Euclidean/Altitude.lean index 1d100ab3c1c959..cf2c704ce1e916 100644 --- a/Mathlib/Geometry/Euclidean/Altitude.lean +++ b/Mathlib/Geometry/Euclidean/Altitude.lean @@ -260,10 +260,10 @@ lemma height_pos {n : ℕ} [NeZero n] (s : Simplex ℝ P n) (i : Fin (n + 1)) : open Qq Mathlib.Meta.Positivity in /-- Extension for the `positivity` tactic: the height of a simplex is always positive. -/ @[positivity height _ _] -meta def evalHeight : PositivityExt where eval {u α} _ pα? e := do +meta def evalHeight : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@height $V $P $i1 $i2 $i3 $i4 $n $hn $s $i) => - let some _ := pα? | pure .none assertInstancesCommute return .positive q(height_pos $s $i) | _, _, _ => throwError "not Simplex.height" diff --git a/Mathlib/Geometry/RingedSpace/Basic.lean b/Mathlib/Geometry/RingedSpace/Basic.lean index ce4c5879fe072e..4a615fbba24138 100644 --- a/Mathlib/Geometry/RingedSpace/Basic.lean +++ b/Mathlib/Geometry/RingedSpace/Basic.lean @@ -38,6 +38,7 @@ open TopCat.Presheaf namespace AlgebraicGeometry +set_option linter.checkUnivs false in /-- The type of Ringed spaces, as an abbreviation for `SheafedSpace CommRingCat`. -/ @[nolint checkUnivs] -- The universes appear together in the type, but separately in the value. abbrev RingedSpace : Type max (u + 1) (v + 1) := diff --git a/Mathlib/Init.lean b/Mathlib/Init.lean index 81b05422e07d29..e49829ccc5766f 100644 --- a/Mathlib/Init.lean +++ b/Mathlib/Init.lean @@ -132,7 +132,7 @@ run_cmd liftTermElabM do let DefinedInScripts : Array Name := #[`linter.checkInitImports, `linter.allScriptsDocumented] let env ← getEnv - let ls := linterSetsExt.getEntries env + let ls := (linterSetsExt.getState env).localEntries let some (_, mlLinters) := ls.find? (·.1 == ``linter.mathlibStandardSet) | throwError m!"'linter.mathlibStandardSet' is not defined." let some (_, nrLinters) := ls.find? (·.1 == ``linter.nightlyRegressionSet) | diff --git a/Mathlib/Lean/MessageData/ForExprs.lean b/Mathlib/Lean/MessageData/ForExprs.lean index a67e574dbe10fc..93d155149f7d7a 100644 --- a/Mathlib/Lean/MessageData/ForExprs.lean +++ b/Mathlib/Lean/MessageData/ForExprs.lean @@ -68,6 +68,7 @@ where | .ofFormatWithInfos fwi => do let some ppCtx := ctx?.map (mkPPContext nctx) | return .yield s goFmt ppCtx fwi.infos s fwi.fmt + | .ofOriginatingSyntax _ m => go nctx ctx? s m /-- Iterate over the tags of a `Format` using `f`. -/ goFmt (ppCtx : PPContext) (infos) (s : σ) : Format → m (ForInStep σ) | .tag n fmt => do diff --git a/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean b/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean index 6baef24ebebd58..4650ebd053cd21 100644 --- a/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean +++ b/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean @@ -134,8 +134,8 @@ private def etaPossibilities (e : Expr) (lambdas : List FVarId) (root : Bool) if isStarWithArg (.fvar fvarId) a && !f.getAppFn.isMVar then etaPossibilities f lambdas root entry else - return [] - | _, _ => return []) + pure [] + | _, _ => pure []) where /-- Check whether the expression is represented by `Key.star` and has `arg` as an argument. -/ isStarWithArg (arg : Expr) : Expr → Bool diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index c369663b90f5d7..f91ca532768c13 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -138,10 +138,10 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `Besicovitch.SatelliteConfig.r`. -/ @[positivity Besicovitch.SatelliteConfig.r _ _] -meta def evalBesicovitchSatelliteConfigR : PositivityExt where eval {u α} _zα pα? e := do +meta def evalBesicovitchSatelliteConfigR : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@Besicovitch.SatelliteConfig.r $β $inst $N $τ $self $i) => - let some _ := pα? | pure .none assertInstancesCommute return .positive q(Besicovitch.SatelliteConfig.rpos $self $i) | _, _, _ => throwError "not Besicovitch.SatelliteConfig.r" diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index 577389d0ba23ef..87f7e189d926d1 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -1367,8 +1367,8 @@ attribute [local instance] monadLiftOptionMetaM in This extension only proves non-negativity, strict positivity is more delicate for integration and requires more assumptions. -/ @[positivity MeasureTheory.integral _ _] -meta def evalIntegral : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalIntegral : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match u, α, e with | 0, ~q(ℝ), ~q(@MeasureTheory.integral $i ℝ _ $inst2 _ _ $f) => let i : Q($i) ← mkFreshExprMVarQ q($i) .syntheticOpaque diff --git a/Mathlib/MeasureTheory/Measure/Real.lean b/Mathlib/MeasureTheory/Measure/Real.lean index 0d15c02f097b66..ec1f88b8aa8fe4 100644 --- a/Mathlib/MeasureTheory/Measure/Real.lean +++ b/Mathlib/MeasureTheory/Measure/Real.lean @@ -493,9 +493,9 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: applications of `μ.real` are nonnegative. -/ @[positivity MeasureTheory.Measure.real _ _] -meta def evalMeasureReal : PositivityExt where eval {_ _} _zα pα? e := do +meta def evalMeasureReal : PositivityExt where eval {_ _} _zα pα? e := + match pα? with | none => pure .none | some _ => do let .app (.app _ a) b ← whnfR e | throwError "not measureReal" - let some _ := pα? | pure .none let p ← mkAppOptM ``MeasureTheory.measureReal_nonneg #[none, none, a, b] pure (.nonnegative p) diff --git a/Mathlib/ModelTheory/Basic.lean b/Mathlib/ModelTheory/Basic.lean index 461a3c31318c83..bab71eb42a7dd3 100644 --- a/Mathlib/ModelTheory/Basic.lean +++ b/Mathlib/ModelTheory/Basic.lean @@ -52,6 +52,7 @@ namespace FirstOrder -- intended to be used with explicit universe parameters +set_option linter.checkUnivs false in /-- A first-order language consists of a type of functions of every natural-number arity and a type of relations of every natural-number arity. -/ @[nolint checkUnivs] diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean index 0978dd9917eae5..11f9445eac20a4 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean @@ -456,8 +456,8 @@ open Lean Meta Qq /-- Extension for `ArithmeticFunction.sigma`. -/ @[positivity ArithmeticFunction.sigma _ _] -meta def evalArithmeticFunctionSigma : PositivityExt where eval {u α} z p? e := do - let some p := p? | throwError "no PartialOrder instance" +meta def evalArithmeticFunctionSigma : PositivityExt where eval {u α} z p? e := + match p? with | none => throwError "no PartialOrder instance" | some p => do match u, α, e with | 0, ~q(ℕ), ~q(ArithmeticFunction.sigma $k $n) => assumeInstancesCommute diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean index f0595aca62f502..3c7e3486d06ac2 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean @@ -222,8 +222,8 @@ open Lean Meta Qq /-- Extension for `ArithmeticFunction.zeta`. -/ @[positivity ArithmeticFunction.zeta _] -meta def evalArithmeticFunctionZeta : PositivityExt where eval {u α} z p? e := do - let some p := p? | throwError "no PartialOrder instance" +meta def evalArithmeticFunctionZeta : PositivityExt where eval {u α} z p? e := + match p? with | none => throwError "no PartialOrder instance" | some p => do match u, α, e with | 0, ~q(ℕ), ~q(ArithmeticFunction.zeta $n) => assumeInstancesCommute diff --git a/Mathlib/NumberTheory/Height/Basic.lean b/Mathlib/NumberTheory/Height/Basic.lean index 7118e99a9d8893..e5bdeb555ef6a8 100644 --- a/Mathlib/NumberTheory/Height/Basic.lean +++ b/Mathlib/NumberTheory/Height/Basic.lean @@ -189,20 +189,20 @@ open Lean.Meta Qq Height /-- Extension for the `positivity` tactic: `Height.mulHeight₁` is always positive. -/ @[positivity Height.mulHeight₁ _] -meta def evalMulHeight₁ : PositivityExt where eval {u α} _ pα? e := do +meta def evalMulHeight₁ : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@mulHeight₁ $K $KF $KA $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(mulHeight₁_pos $a)) | _, _, _ => throwError "not Height.mulHeight₁" /-- Extension for the `positivity` tactic: `Height.logHeight₁` is always nonnegative. -/ @[positivity Height.logHeight₁ _] -meta def evalLogHeight₁ : PositivityExt where eval {u α} _ pα? e := do +meta def evalLogHeight₁ : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@logHeight₁ $K $KF $KA $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(zero_le_logHeight₁ $a)) | _, _, _ => throwError "not Height.logHeight₁" @@ -510,10 +510,10 @@ open Lean.Meta Qq Height /-- Extension for the `positivity` tactic: `Height.mulHeight` is always positive. -/ @[positivity Height.mulHeight _] -meta def evalMulHeight : PositivityExt where eval {u α} _ pα? e := do +meta def evalMulHeight : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@mulHeight $K $KF $KA $ι $a) => - let some _ := pα? | pure .none -- Check whether there is a `Finite` instance for `$ι` around. match ← trySynthInstanceQ q(Finite $ι) with | .some _instFinite => @@ -524,10 +524,10 @@ meta def evalMulHeight : PositivityExt where eval {u α} _ pα? e := do /-- Extension for the `positivity` tactic: `Height.logHeight` is always nonnegative. -/ @[positivity Height.logHeight _] -meta def evalLogHeight : PositivityExt where eval {u α} _ pα? e := do +meta def evalLogHeight : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@logHeight $K $KF $KA $ι $a) => - let some _ := pα? | pure .none -- Check whether there is a `Finite` instance for `$ι` around. match ← trySynthInstanceQ q(Finite $ι) with | .some _instFinite => diff --git a/Mathlib/NumberTheory/Height/NumberField.lean b/Mathlib/NumberTheory/Height/NumberField.lean index 0e3471a25c812c..3c154daa059b4d 100644 --- a/Mathlib/NumberTheory/Height/NumberField.lean +++ b/Mathlib/NumberTheory/Height/NumberField.lean @@ -194,10 +194,10 @@ open Lean.Meta Qq /-- Extension for the `positivity` tactic: `Height.totalWeight` is positive for number fields. -/ @[positivity Height.totalWeight _] -meta def evalHeightTotalWeight : PositivityExt where eval {u α} _ pα? e := do +meta def evalHeightTotalWeight : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(@Height.totalWeight $K $KF $KA) => - let some _ := pα? | pure .none -- Check whether there is a `NumberField` instance for `$K` around. match ← trySynthInstanceQ q(NumberField $K) with | .some _inst => diff --git a/Mathlib/NumberTheory/Height/Projectivization.lean b/Mathlib/NumberTheory/Height/Projectivization.lean index 0caa26f4437275..6d7c19f22bc3e6 100644 --- a/Mathlib/NumberTheory/Height/Projectivization.lean +++ b/Mathlib/NumberTheory/Height/Projectivization.lean @@ -83,20 +83,20 @@ open Lean.Meta Qq Projectivization /-- Extension for the `positivity` tactic: `Projectivization.mulHeight` is always positive. -/ @[positivity Projectivization.mulHeight _] -meta def evalProjMulHeight : PositivityExt where eval {u α} _ pα? e := do +meta def evalProjMulHeight : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@mulHeight $K $KF $KA $ι $ιF $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.positive q(mulHeight_pos $a)) | _, _, _ => throwError "not Projectivization.mulHeight" /-- Extension for the `positivity` tactic: `Projectivization.logHeight` is always nonnegative. -/ @[positivity Projectivization.logHeight _] -meta def evalProjLogHeight : PositivityExt where eval {u α} _ pα? e := do +meta def evalProjLogHeight : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@logHeight $K $KF $KA $ι $ιF $a) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(logHeight_nonneg $a)) | _, _, _ => throwError "not Projectivization.logHeight" diff --git a/Mathlib/NumberTheory/LucasLehmer.lean b/Mathlib/NumberTheory/LucasLehmer.lean index cfac67c69e8e3b..137d17b82b52ba 100644 --- a/Mathlib/NumberTheory/LucasLehmer.lean +++ b/Mathlib/NumberTheory/LucasLehmer.lean @@ -78,8 +78,8 @@ alias ⟨_, mersenne_pos_of_pos⟩ := mersenne_pos /-- Extension for the `positivity` tactic: `mersenne`. -/ @[positivity mersenne _] -meta def evalMersenne : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | pure .none +meta def evalMersenne : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(mersenne $a) => assertInstancesCommute diff --git a/Mathlib/NumberTheory/Padics/Hensel.lean b/Mathlib/NumberTheory/Padics/Hensel.lean index 98571de58969ce..9031f81aa319ec 100644 --- a/Mathlib/NumberTheory/Padics/Hensel.lean +++ b/Mathlib/NumberTheory/Padics/Hensel.lean @@ -227,6 +227,7 @@ private def calc_eval_z' {z z' z1 : ℤ_[p]} (hz' : z' = z - z1) {n} (hz : ih n _ = -F.aeval z := by simp only [mul_div_cancel₀ _ hdzne', Subtype.coe_eta] exact ⟨q, by simpa [sub_eq_add_neg, neg_mul_eq_mul_neg, this, hz'] using hq⟩ +set_option linter.defProp false in private def calc_eval_z'_norm {z z' z1 : ℤ_[p]} {n} (hz : ih n z) {q} (heq : F.aeval z' = q * z1 ^ 2) (h1 : ‖(↑(F.aeval z) : ℚ_[p]) / ↑(F.derivative.aeval z)‖ ≤ 1) (hzeq : z1 = ⟨_, h1⟩) : diff --git a/Mathlib/NumberTheory/SelbergSieve.lean b/Mathlib/NumberTheory/SelbergSieve.lean index 93cfa77d4eb6ff..316cf8e7ddb7c0 100644 --- a/Mathlib/NumberTheory/SelbergSieve.lean +++ b/Mathlib/NumberTheory/SelbergSieve.lean @@ -89,10 +89,10 @@ open Lean Meta Qq /-- Extension for the `positivity` tactic: `BoundingSieve.weights`. -/ @[positivity BoundingSieve.weights _ _] -meta def evalBoundingSieveWeights : PositivityExt where eval {u α} _zα pα? e := do +meta def evalBoundingSieveWeights : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@BoundingSieve.weights $s $n) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(BoundingSieve.weights_nonneg $s $n)) | _, _, _ => throwError "not BoundingSieve.weights" diff --git a/Mathlib/SetTheory/Ordinal/Univ.lean b/Mathlib/SetTheory/Ordinal/Univ.lean index d7aac64cfe94d2..7abc9881f863c0 100644 --- a/Mathlib/SetTheory/Ordinal/Univ.lean +++ b/Mathlib/SetTheory/Ordinal/Univ.lean @@ -28,6 +28,7 @@ This makes the basic API easier to set up. See `Cardinal.mk_cardinal` for a proo universe u v w +set_option linter.checkUnivs false in open Ordinal in -- intended to be used with explicit universe parameters /-- The ordinal `univ.{u, v}` is the order type of `Ordinal.{u}` or `Cardinal.{u}`, as an element of @@ -36,6 +37,7 @@ open Ordinal in def Ordinal.univ : Ordinal.{max (u + 1) v} := lift.{v, u + 1} (typeLT Ordinal) +set_option linter.checkUnivs false in open Cardinal in -- intended to be used with explicit universe parameters /-- The cardinal `univ.{u, v}` is the cardinality of `Ordinal.{u}` or `Cardinal.{u}`, as an element diff --git a/Mathlib/SetTheory/ZFC/PSet.lean b/Mathlib/SetTheory/ZFC/PSet.lean index 70115837262919..ca273f551fb0fe 100644 --- a/Mathlib/SetTheory/ZFC/PSet.lean +++ b/Mathlib/SetTheory/ZFC/PSet.lean @@ -441,6 +441,7 @@ protected def Lift : PSet.{u} → PSet.{max u v} | ⟨α, A⟩ => ⟨ULift.{v, u} α, fun ⟨x⟩ => PSet.Lift (A x)⟩ -- intended to be used with explicit universe parameters +set_option linter.checkUnivs false in /-- Embedding of one universe in another -/ @[nolint checkUnivs] def embed : PSet.{max (u + 1) v} := diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index d71ca00b7cd5db..cda5ca25b7cf19 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -164,24 +164,24 @@ namespace RingCompute /-- Evaluate the sum of two normalized expressions in `R` using `ring`. -/ def add (cR : Common.Cache sR) {a b : Q($A)} (za : BaseType sAlg a) (zb : BaseType sAlg b) : - MetaM (Common.Result (BaseType sAlg) q($a + $b) × Option Q(IsNat ($a + $b) 0)) := do - let ⟨r, vr⟩ := za - let ⟨s, vs⟩ := zb - let ⟨t, vt, pt⟩ ← Common.evalAdd (Ring.ringCompute cR) rcℕ vr vs - match vt with - | .zero => - have : $t =Q 0 := ⟨⟩ - return ⟨⟨_, .mk _ vt, q(add_algebraMap $pt)⟩, some q(add_algebraMap_isNat_zero $pt)⟩ - | vt => - return ⟨⟨_, .mk _ vt, q(add_algebraMap $pt)⟩, none⟩ + MetaM (Common.Result (BaseType sAlg) q($a + $b) × Option Q(IsNat ($a + $b) 0)) := + match za, zb with + | .mk r vr, .mk s vs => do + let ⟨t, vt, pt⟩ ← Common.evalAdd (Ring.ringCompute cR) rcℕ vr vs + match (dependent := true) vt with + | .zero => + have : $t =Q 0 := ⟨⟩ + return ⟨⟨_, .mk _ vt, q(add_algebraMap $pt)⟩, some q(add_algebraMap_isNat_zero $pt)⟩ + | vt => + return ⟨⟨_, .mk _ vt, q(add_algebraMap $pt)⟩, none⟩ /-- Evaluate the product of two normalized expressions in `R` using `ring`. -/ def mul (cR : Common.Cache sR) {a b : Q($A)} (za : BaseType sAlg a) (zb : BaseType sAlg b) : - MetaM (Common.Result (BaseType sAlg) q($a * $b)) := do - let ⟨r, vr⟩ := za - let ⟨s, vs⟩ := zb - let ⟨t, vt, pt⟩ ← Common.evalMul (Ring.ringCompute cR) rcℕ vr vs - return ⟨_, .mk _ vt, q(by simp [← $pt, map_mul])⟩ + MetaM (Common.Result (BaseType sAlg) q($a * $b)) := + match za, zb with + | .mk r vr, .mk s vs => do + let ⟨t, vt, pt⟩ ← Common.evalMul (Ring.ringCompute cR) rcℕ vr vs + return ⟨_, .mk _ vt, q(by simp [← $pt, map_mul])⟩ /-- Take an expression `r'` in a ring `R'` such that `R` is an `R'`-algebra and cast `r'` to `R` using `algebraMap R' R`, so that the scalar multiplication action on `A` is preserved. -/ @@ -194,7 +194,7 @@ def cast (cR : Algebra.Cache sR) (u' : Level) (R' : Q(Type u')) let ⟨r, pf_smul⟩ ← evalSMulCast q($sAlg) q($_smul) r' let ⟨_r'', vr, pr⟩ ← Common.eval rcℕ (Ring.ringCompute cR.toCache) cR.toCache q($r) - match vr with + match (dependent := true) vr with | .zero .. => assumeInstancesCommute return ⟨_, .zero, q(cast_zero_smul_eq_zero_mul $pr $pf_smul)⟩ @@ -205,37 +205,40 @@ def cast (cR : Algebra.Cache sR) (u' : Level) (R' : Q(Type u')) /-- Evaluate the product of two normalized expressions in `R` using `ring`. -/ def neg (cR : Algebra.Cache sR) {a : Q($A)} (_rA : Q(CommRing $A)) (za : BaseType sAlg a) : - MetaM (Common.Result (BaseType sAlg) q(-$a)) := do - let ⟨r, vr⟩ := za - match cR.rα with - | some rR => - let ⟨_, vt, pt⟩ ← Common.evalNeg (Ring.ringCompute cR.toCache) q($rR) vr - assumeInstancesCommute - return ⟨_, .mk _ vt, q(neg_algebraMap $pt)⟩ - | none => failure + MetaM (Common.Result (BaseType sAlg) q(-$a)) := + match za with + | .mk r vr => do + match cR.rα with + | some rR => + let ⟨_, vt, pt⟩ ← Common.evalNeg (Ring.ringCompute cR.toCache) q($rR) vr + assumeInstancesCommute + return ⟨_, .mk _ vt, q(neg_algebraMap $pt)⟩ + | none => failure /-- Raise a normalized expression in `R` to the power of a normalized natural number expression using `ring`. -/ def pow (cR : Common.Cache sR) {a : Q($A)} {b : Q(ℕ)} (za : BaseType sAlg a) (vb : Common.ExProdNat q($b)) : - OptionT MetaM (Common.Result (BaseType sAlg) q($a ^ $b)) := do - let ⟨r, vr⟩ := za - let ⟨_, vs, ps⟩ ← Common.evalPow₁ (Ring.ringCompute cR) rcℕ vr vb - return ⟨_, ⟨_, vs⟩, q(pow_algebraMap $ps)⟩ + OptionT MetaM (Common.Result (BaseType sAlg) q($a ^ $b)) := + match za with + | .mk r vr => do + let ⟨_, vs, ps⟩ ← Common.evalPow₁ (Ring.ringCompute cR) rcℕ vr vb + return ⟨_, ⟨_, vs⟩, q(pow_algebraMap $ps)⟩ /-- Evaluate the inverse of two normalized expressions in `R` using `ring`. -/ /- We include the CharZero argument to match the type signature of the ringCompute entry. -/ @[nolint unusedArguments] def inv (cR : Algebra.Cache sR) {a : Q($A)} (_ : Option Q(CharZero $A)) (fA : Q(Semifield $A)) - (za : BaseType sAlg a) : AtomM (Option (Common.Result (BaseType sAlg) q($a⁻¹))) := do - match cR.dsα with - | some fR => - let ⟨r, vr⟩ := za - let ⟨_, vs, ps⟩ ← Common.ExSum.evalInv (Ring.ringCompute cR.toCache) rcℕ q($fR) cR.czα vr - assumeInstancesCommute - return some ⟨_, ⟨_, vs⟩, q(inv_algebraMap $ps)⟩ - | none => - return none + (za : BaseType sAlg a) : AtomM (Option (Common.Result (BaseType sAlg) q($a⁻¹))) := + match za with + | .mk r vr => do + match cR.dsα with + | some fR => + let ⟨_, vs, ps⟩ ← Common.ExSum.evalInv (Ring.ringCompute cR.toCache) rcℕ q($fR) cR.czα vr + assumeInstancesCommute + return some ⟨_, ⟨_, vs⟩, q(inv_algebraMap $ps)⟩ + | none => + return none /-- Evaluate constants in `A` using `norm_num`. -/ def derive (cR : Algebra.Cache sR) (cA : Algebra.Cache sA) (x : Q($A)) : diff --git a/Mathlib/Tactic/CrossRefAttribute.lean b/Mathlib/Tactic/CrossRefAttribute.lean index 8b8881d079c5ef..d99fb0748397f9 100644 --- a/Mathlib/Tactic/CrossRefAttribute.lean +++ b/Mathlib/Tactic/CrossRefAttribute.lean @@ -224,9 +224,9 @@ initialize Lean.registerBuiltinAttribute { name := `stacksTag descr := "Apply a Stacks or Kerodon project tag to a theorem." add := fun decl stx _attrKind => do - let (db, tag, comment) := ← match stx with - | `(attr| stacks $tag $[$comment]?) => return (Database.stacks, tag, comment) - | `(attr| kerodon $tag $[$comment]?) => return (Database.kerodon, tag, comment) + let (db, tag, comment) ← match stx with + | `(attr| stacks $tag $[$comment]?) => pure (Database.stacks, tag, comment) + | `(attr| kerodon $tag $[$comment]?) => pure (Database.kerodon, tag, comment) | _ => throwUnsupportedSyntax addCrossRefDoc db decl (← tag.getStacksTag) ((comment.map (·.getString)).getD "") -- docstrings are immutable once an asynchronous elaboration task has been started @@ -247,8 +247,8 @@ initialize Lean.registerBuiltinAttribute { name := `wikidataTag descr := "Apply a Wikidata identifier to a declaration." add := fun decl stx _attrKind => do - let (id, comment) := ← match stx with - | `(attr| wikidata $id $[$comment]?) => return (id, comment) + let (id, comment) ← match stx with + | `(attr| wikidata $id $[$comment]?) => pure (id, comment) | _ => throwUnsupportedSyntax addCrossRefDoc .wikidata decl (← id.getWikidataId) ((comment.map (·.getString)).getD "") -- docstrings are immutable once an asynchronous elaboration task has been started diff --git a/Mathlib/Tactic/DefEqAbuse.lean b/Mathlib/Tactic/DefEqAbuse.lean index e5f0546c1573f8..bb376b1bccf820 100644 --- a/Mathlib/Tactic/DefEqAbuse.lean +++ b/Mathlib/Tactic/DefEqAbuse.lean @@ -113,7 +113,8 @@ where return result | .ascend a? => return a?.getD empty | .compose a b => return combine (← go a) (← go b) - | .nest _ m | .group m | .tagged _ m | .withContext _ m | .withNamingContext _ m => go m + | .nest _ m | .group m | .tagged _ m | .withContext _ m | .withNamingContext _ m + | .ofOriginatingSyntax _ m => go m | .ofLazy _ _ | .ofWidget _ _ | .ofGoal _ | .ofFormatWithInfos _ => return empty /-- Convenience wrapper which accumulates the results of `visitM` across `arr`, attempting to @@ -143,6 +144,7 @@ partial def withPPOptions (msg : MessageData) (modify : Options → Options) : M | .nest n m => .nest n (withPPOptions m modify) | .group m => .group (withPPOptions m modify) | .tagged t m => .tagged t (withPPOptions m modify) + | .ofOriginatingSyntax stx m => .ofOriginatingSyntax stx (withPPOptions m modify) | .withNamingContext nc m => .withNamingContext nc (withPPOptions m modify) | .trace td header children => .trace td (withPPOptions header modify) (children.map (withPPOptions · modify)) @@ -164,19 +166,6 @@ namespace Mathlib.Tactic.DefEqAbuse unless (`Meta.isDefEq).isPrefixOf td.cls do return .descend f td header children -/-- Strip the leading status emoji that `withTraceNodeBefore` prepends to trace headers. -`withTraceNodeBefore` stores `m!"{result.toEmoji} {content}"` as the header; this strips the -emoji prefix using the structured `TraceData.result?` to know exactly what was prepended. -Needed because the same isDefEq check has different emoji prefixes across trace runs -(✅️ when it succeeds, ❌️ when it fails), but we need to compare the content. -See https://github.com/leanprover/lean4/pull/13070 for the upstream fix. -/ -private def stripHeaderEmoji (s : String) (result? : Option Lean.TraceResult) : String := - match result? with - | some result => - let emojiPrefix := s!"{result.toEmoji} " - if s.startsWith emojiPrefix then (s.drop emojiPrefix.length).toString else s - | none => s - /-- Find the deepest failing `Meta.isDefEq` trace nodes (leaf failures). Skips `onFailure` retry nodes and ignores ✅️ branches (recovered failures aren't root causes). -/ partial def findLeafFailures (msg : MessageData) : BaseIO (Array MessageData) := @@ -188,13 +177,13 @@ partial def findLeafFailures (msg : MessageData) : BaseIO (Array MessageData) := return .ascend <| if childFailures.isEmpty then #[header] else childFailures /-- Collect rendered check strings from `Meta.isDefEq` trace nodes matching a status predicate. -Returns a `HashSet` of emoji-stripped header strings. -/ +Returns a `HashSet` of header strings. -/ partial def collectIsDefEqChecks (pred : Lean.TraceResult → Bool) (msg : MessageData) : BaseIO (Std.HashSet String) := msg.visitTraceNodesM <| onlyOnDefEqNodes fun td header children => do if let some status := td.result? then if pred status then - let headerStr := stripHeaderEmoji (← header.toString) td.result? + let headerStr ← header.toString return .descend (butFirst := some {headerStr}) return .descend @@ -210,7 +199,7 @@ partial def findTransitionFailures (permSuccesses : Std.HashSet String) if permSuccesses.isEmpty then findLeafFailures msg else msg.visitTraceNodesM <| onlyOnDefEqNodes fun td header children => do unless td.result? matches some .failure do return .descend - let headerStr := stripHeaderEmoji (← header.toString) td.result? + let headerStr ← header.toString if permSuccesses.contains headerStr && !permFailures.contains headerStr then -- Transition point: fails strict, succeeds permissive, doesn't also fail permissive. -- Look for deeper transition points among children. @@ -303,17 +292,13 @@ def analyzeTraces (strictMsgs permMsgs : Array MessageData) (includeSynth : Bool return (uniqueFailures, dedupedResults) /-- Check whether a rendered isDefEq check string has syntactically identical LHS and RHS -(e.g. `"❌️ ⊤ =?= ⊤"` or `"Quiver C =?= Quiver C"`). +(e.g. `"⊤ =?= ⊤"` or `"Quiver C =?= Quiver C"`). Comparison is whitespace-insensitive to handle cases where LHS and RHS are semantically identical but rendered with different line breaks or spacing. TODO: once https://github.com/leanprover/lean4/pull/12698 is available, refactor to use `TraceData.result?` and compare the LHS/RHS `Expr`s structurally instead of string-matching. -/ def isIdenticalSidesStr (raw : String) : Bool := - if let [lhsRaw, rhs] := raw.splitOn " =?= " then - -- Strip the leading status emoji/word (first whitespace-delimited token). - let lhs := match lhsRaw.splitOn " " with - | _ :: rest => " ".intercalate rest - | _ => lhsRaw + if let [lhs, rhs] := raw.splitOn " =?= " then -- Compare up to whitespace so that line-break differences don't cause false negatives. let tokenize (s : String) : List String := (s.split Char.isWhitespace).toList.map (·.toString) |>.filter (· ≠ "") @@ -346,13 +331,14 @@ def disambiguateFailures (failures : Array MessageData) : BaseIO (Array MessageD def reportDefEqAbuse {m : Type → Type} [Monad m] [MonadLog m] [AddMessageContext m] [MonadOptions m] (kind : String) (uniqueFailures : Array MessageData) (synthResults : Array (MessageData × Array MessageData)) : m Unit := do + let failureEmoji := Lean.TraceResult.failure.toEmoji if !synthResults.isEmpty then -- Structured report: group by instance application let mut entries : Array MessageData := #[] for (app, failures) in synthResults do let failureList := joinSep - (failures.toList.map fun f => m!" {f}") "\n" - entries := entries.push m!" {app}\n{failureList}" + (failures.toList.map fun f => m!" {failureEmoji} {f}") "\n" + entries := entries.push m!" {failureEmoji} {app}\n{failureList}" let report := joinSep entries.toList "\n" logWarning m!"#defeq_abuse: {kind} fails with \ @@ -365,7 +351,7 @@ def reportDefEqAbuse {m : Type → Type} [Monad m] [MonadLog m] [AddMessageConte Could not identify specific failing isDefEq checks from traces." else let failureList := joinSep - (uniqueFailures.toList.map fun f => m!" {f}") "\n" + (uniqueFailures.toList.map fun f => m!" {failureEmoji} {f}") "\n" logWarning m!"#defeq_abuse: {kind} fails with \ `backward.isDefEq.respectTransparency true` but succeeds with `false`.\n\ diff --git a/Mathlib/Tactic/DeprecateTo.lean b/Mathlib/Tactic/DeprecateTo.lean index 6c4805d681021e..96a3d1352a2db9 100644 --- a/Mathlib/Tactic/DeprecateTo.lean +++ b/Mathlib/Tactic/DeprecateTo.lean @@ -47,11 +47,10 @@ open Lean Elab Term Command /-- Produce the syntax for the command `@[deprecated (since := "YYYY-MM-DD")] alias n := id`. -/ def mkDeprecationStx (id : TSyntax `ident) (n : Name) (dat : Option String := none) : CommandElabM (TSyntax `command) := do - let dat := ← - match dat with - | none => do - return s!"{(← Std.Time.ZonedDateTime.now).toPlainDate}" - | some s => return s + let dat ← match dat with + | none => do + pure s!"{← Std.Time.PlainDate.now}" + | some s => pure s let nd := mkNode `str #[mkAtom ("\"" ++ dat.trimAsciiEnd ++ "\"")] `(command| @[deprecated (since := $nd)] alias $(mkIdent n) := $id) diff --git a/Mathlib/Tactic/DeriveEncodable.lean b/Mathlib/Tactic/DeriveEncodable.lean index 52f418e78bf039..7ac67b035ee4e9 100644 --- a/Mathlib/Tactic/DeriveEncodable.lean +++ b/Mathlib/Tactic/DeriveEncodable.lean @@ -126,7 +126,7 @@ private def S_equiv : S ≃ ℕ where · rwa [Nat.one_le_iff_ne_zero] · exact nat_unpair_lt_2 h · obtain _ | n' := n - · exact False.elim (h rfl) + · exact False.elim (h (by simp)) · have := Nat.unpair_lt (by lia : 1 ≤ n' + 1) lia diff --git a/Mathlib/Tactic/FieldSimp.lean b/Mathlib/Tactic/FieldSimp.lean index 4848295ba6a635..70cc8bae5385bb 100644 --- a/Mathlib/Tactic/FieldSimp.lean +++ b/Mathlib/Tactic/FieldSimp.lean @@ -62,7 +62,7 @@ def onExponent (l : qNF M) (f : ℤ → ℤ) : qNF M := /-- Build a transparent expression for the product of powers represented by `l : qNF M`. -/ def evalPrettyMonomial (iM : Q(GroupWithZero $M)) (r : ℤ) (x : Q($M)) : - MetaM (Σ e : Q($M), Q(zpow' $x $r = $e)) := do + MetaM (Σ e : Q($M), Q(zpow' $x $r = $e)) := match r with | 0 => /- If an exponent is zero then we must not have been able to prove that x is nonzero. -/ return ⟨q($x / $x), q(zpow'_zero_eq_div ..)⟩ @@ -111,10 +111,10 @@ def removeZeros of) the negative powers. -/ def split (iM : Q(CommGroupWithZero $M)) (l : qNF M) : MetaM (Σ l_n l_d : qNF M, Q(NF.eval $(l.toNF) - = NF.eval $(l_n.toNF) / NF.eval $(l_d.toNF))) := do + = NF.eval $(l_n.toNF) / NF.eval $(l_d.toNF))) := match l with | [] => return ⟨[], [], q(Eq.symm (div_one (1:$M)))⟩ - | ((r, x), i) :: t => + | ((r, x), i) :: t => do let ⟨t_n, t_d, pf⟩ ← split iM t if r > 0 then return ⟨((r, x), i) :: t_n, t_d, (q(NF.cons_eq_div_of_eq_div $r $x $pf):)⟩ @@ -125,13 +125,13 @@ def split (iM : Q(CommGroupWithZero $M)) (l : qNF M) : return ⟨t_n, ((r', x), i) :: t_d, (q(NF.cons_eq_div_of_eq_div' $r' $x $pf):)⟩ private def evalPrettyAux (iM : Q(CommGroupWithZero $M)) (l : qNF M) : - MetaM (Σ e : Q($M), Q(NF.eval $(l.toNF) = $e)) := do + MetaM (Σ e : Q($M), Q(NF.eval $(l.toNF) = $e)) := match l with | [] => return ⟨q(1), q(rfl)⟩ - | [((r, x), _)] => + | [((r, x), _)] => do let ⟨e, pf⟩ ← evalPrettyMonomial q(inferInstance) r x return ⟨e, q(by rw [NF.eval_cons]; exact Eq.trans (one_mul _) $pf)⟩ - | ((r, x), k) :: t => + | ((r, x), k) :: t => do let ⟨e, pf_e⟩ ← evalPrettyMonomial q(inferInstance) r x let ⟨t', pf⟩ ← evalPrettyAux iM t have pf'' : Q(NF.eval $(qNF.toNF (((r, x), k) :: t)) = (NF.eval $(qNF.toNF t)) * zpow' $x $r) := @@ -144,7 +144,7 @@ def evalPretty (iM : Q(CommGroupWithZero $M)) (l : qNF M) : let ⟨l_n, l_d, pf⟩ ← split iM l let ⟨num, pf_n⟩ ← evalPrettyAux q(inferInstance) l_n let ⟨den, pf_d⟩ ← evalPrettyAux q(inferInstance) l_d - match l_d with + match (dependent := true) l_d with | [] => return ⟨num, q(eq_div_of_eq_one_of_subst $pf $pf_n)⟩ | _ => let pf_n : Q(NF.eval $(l_n.toNF) = $num) := pf_n @@ -281,14 +281,14 @@ def mkDenomConditionProofSucc {iM : Q(CommGroupWithZero $M)} (disch : ∀ {u : Level} (type : Q(Sort u)), MetaM Q($type)) {cond : DenomCondition (M := M) q(inferInstance)} {L : qNF M} (hL : cond.proof L) (e : Q($M)) (r : ℤ) (i : ℕ) : - MetaM (Q($e ≠ 0) × cond.proof (((r, e), i) :: L)) := do + MetaM (Q($e ≠ 0) × cond.proof (((r, e), i) :: L)) := match cond with | .none => return (← disch q($e ≠ 0), Unit.unit) - | .nonzero => + | .nonzero => do let pf ← disch q($e ≠ 0) let pf₀ : Q(NF.eval $(qNF.toNF L) ≠ 0) := hL return (pf, q(NF.cons_ne_zero $r $pf $pf₀)) - | .positive _ _ _ _ => + | .positive _ _ _ _ => do let pf ← disch q(0 < $e) let pf₀ : Q(0 < NF.eval $(qNF.toNF L)) := hL let pf' := q(NF.cons_pos $r (x := $e) $pf $pf₀) @@ -301,14 +301,14 @@ def mkDenomConditionProofSucc' {iM : Q(CommGroupWithZero $M)} (disch : ∀ {u : Level} (type : Q(Sort u)), MetaM Q($type)) {cond : DenomCondition (M := M) q(inferInstance)} {L : qNF M} (hL : cond.proof L) (e : Q($M)) (r : ℤ) (i : ℕ) : - MetaM (cond.proof (((r, e), i) :: L)) := do + MetaM (cond.proof (((r, e), i) :: L)) := match cond with | .none => return Unit.unit - | .nonzero => + | .nonzero => do let pf ← disch q($e ≠ 0) let pf₀ : Q(NF.eval $(qNF.toNF L) ≠ 0) := hL return q(NF.cons_ne_zero $r $pf $pf₀) - | .positive _ _ _ _ => + | .positive _ _ _ _ => do let pf ← disch q(0 < $e) let pf₀ : Q(0 < NF.eval $(qNF.toNF L)) := hL return q(NF.cons_pos $r (x := $e) $pf $pf₀) diff --git a/Mathlib/Tactic/FieldSimp/Lemmas.lean b/Mathlib/Tactic/FieldSimp/Lemmas.lean index 9b5669aa6f68cb..177257c99d0d68 100644 --- a/Mathlib/Tactic/FieldSimp/Lemmas.lean +++ b/Mathlib/Tactic/FieldSimp/Lemmas.lean @@ -398,7 +398,7 @@ def Sign.expr : Sign M → Q($M) → Q($M) the product with `c` of (± `y`) (here taking the specified sign) is ± `c * y`. -/ def Sign.mulRight (iM : Q(CommGroupWithZero $M)) (c y : Q($M)) (g : Sign M) : MetaM Q($(g.expr q($c * $y)) = $c * $(g.expr y)) := do - match g with + match (dependent := true) g with | .plus => pure q(rfl) | .minus _ => assumeInstancesCommute @@ -409,7 +409,7 @@ the product of (± `y₁`) and (± `y₂`) (here taking the specified signs) is proof and the computed sign. -/ def Sign.mul (iM : Q(CommGroupWithZero $M)) (y₁ y₂ : Q($M)) (g₁ g₂ : Sign M) : MetaM (Σ (G : Sign M), Q($(g₁.expr y₁) * $(g₂.expr y₂) = $(G.expr q($y₁ * $y₂)))) := do - match g₁, g₂ with + match (dependent := true) g₁, g₂ with | .plus, .plus => pure ⟨.plus, q(rfl)⟩ | .plus, .minus i => assumeInstancesCommute @@ -425,7 +425,7 @@ def Sign.mul (iM : Q(CommGroupWithZero $M)) (y₁ y₂ : Q($M)) (g₁ g₂ : Sig the inverse of (± `y`) (here taking the specified sign) is ± `y⁻¹`. -/ def Sign.inv (iM : Q(CommGroupWithZero $M)) (y : Q($M)) (g : Sign M) : MetaM (Q($(g.expr y)⁻¹ = $(g.expr q($y⁻¹)))) := do - match g with + match (dependent := true) g with | .plus => pure q(rfl) | .minus _ => assumeInstancesCommute @@ -436,7 +436,7 @@ the quotient of (± `y₁`) and (± `y₂`) (here taking the specified signs) is proof and the computed sign. -/ def Sign.div (iM : Q(CommGroupWithZero $M)) (y₁ y₂ : Q($M)) (g₁ g₂ : Sign M) : MetaM (Σ (G : Sign M), Q($(g₁.expr y₁) / $(g₂.expr y₂) = $(G.expr q($y₁ / $y₂)))) := do - match g₁, g₂ with + match (dependent := true) g₁, g₂ with | .plus, .plus => pure ⟨.plus, q(rfl)⟩ | .plus, .minus i => assumeInstancesCommute @@ -452,7 +452,7 @@ def Sign.div (iM : Q(CommGroupWithZero $M)) (y₁ y₂ : Q($M)) (g₁ g₂ : Sig the negation of (± `y`) (here taking the specified sign) is ∓ `y`. -/ def Sign.neg (iM : Q(Field $M)) (y : Q($M)) (g : Sign M) : MetaM (Σ (G : Sign M), Q(-$(g.expr y) = $(G.expr y))) := do - match g with + match (dependent := true) g with | .plus => pure ⟨.minus iM, q(rfl)⟩ | .minus _ => assumeInstancesCommute @@ -463,7 +463,7 @@ the exponentiation to power `s : ℕ` of (± `y`) (here taking the specified sig return this proof and the computed sign. -/ def Sign.pow (iM : Q(CommGroupWithZero $M)) (y : Q($M)) (g : Sign M) (s : ℕ) : MetaM (Σ (G : Sign M), Q($(g.expr y) ^ $s = $(G.expr q($y ^ $s)))) := do - match g with + match (dependent := true) g with | .plus => pure ⟨.plus, q(rfl)⟩ | .minus i => assumeInstancesCommute @@ -479,7 +479,7 @@ the exponentiation to power `s : ℤ` of (± `y`) (here taking the specified sig return this proof and the computed sign. -/ def Sign.zpow (iM : Q(CommGroupWithZero $M)) (y : Q($M)) (g : Sign M) (s : ℤ) : MetaM (Σ (G : Sign M), Q($(g.expr y) ^ $s = $(G.expr q($y ^ $s)))) := do - match g with + match (dependent := true) g with | .plus => pure ⟨.plus, q(rfl)⟩ | .minus i => assumeInstancesCommute diff --git a/Mathlib/Tactic/Linarith/Oracle/SimplexAlgorithm/Gauss.lean b/Mathlib/Tactic/Linarith/Oracle/SimplexAlgorithm/Gauss.lean index d89a10b0fce4e1..190798ae8eab1c 100644 --- a/Mathlib/Tactic/Linarith/Oracle/SimplexAlgorithm/Gauss.lean +++ b/Mathlib/Tactic/Linarith/Oracle/SimplexAlgorithm/Gauss.lean @@ -65,13 +65,13 @@ def getTableauImp : GaussM n m matType <| Tableau matType := do for i in [col:m] do free := free.push i - let ansMatrix : matType basic.size free.size := ← do + let ansMatrix : matType basic.size free.size ← do let vals := getValues (← get) |>.filterMap fun (i, j, v) => if j == basic[i]! then none else some (i, free.findIdx? (· == j) |>.get!, -v) - return ofValues vals + pure <| ofValues vals return ⟨basic, free, ansMatrix⟩ diff --git a/Mathlib/Tactic/LinearCombinationPrime.lean b/Mathlib/Tactic/LinearCombinationPrime.lean index 6b71f8dab9737e..530e066e78ee2e 100644 --- a/Mathlib/Tactic/LinearCombinationPrime.lean +++ b/Mathlib/Tactic/LinearCombinationPrime.lean @@ -94,7 +94,7 @@ partial def expandLinearCombo (ty : Expr) (stx : Syntax.Term) : TermElabM Expand match ← expandLinearCombo ty e with | .const c => .const <$> `(-$c) | .proof p => .proof <$> ``(neg_pf $p) - | `(← $e) => do + | `(← $e:term) => do match ← expandLinearCombo ty e with | .const c => return .const c | .proof p => .proof <$> ``(Eq.symm $p) diff --git a/Mathlib/Tactic/Linter/HaveLetLinter.lean b/Mathlib/Tactic/Linter/HaveLetLinter.lean index a0322f4601c61d..65a3dfcc4bffbe 100644 --- a/Mathlib/Tactic/Linter/HaveLetLinter.lean +++ b/Mathlib/Tactic/Linter/HaveLetLinter.lean @@ -88,7 +88,7 @@ def toFormat_propTypes (ctx : ContextInfo) (lc : LocalContext) (es : Array (Expr also a `Format`ted version of the corresponding Type. -/ public partial def nonPropHaves : InfoTree → CommandElabM (Array (Syntax × Format)) := - InfoTree.foldInfoM (init := #[]) fun ctx info args => return args ++ (← do + InfoTree.foldInfoM (init := #[]) fun ctx info args => return args ++ (← (do let .ofTacticInfo i := info | return #[] let stx := i.stx let .original .. := stx.getHeadInfo | return #[] @@ -109,7 +109,7 @@ def nonPropHaves : InfoTree → CommandElabM (Array (Syntax × Format)) := -- Now, we get the `MetaM` state up and running to find the types of each entry of `newDecls`. -- For each entry which is a `Type`, we print a warning on `have`. let fmts ← toFormat_propTypes ctx lc (newDecls.map (fun e ↦ (e.type, e.userName))).toArray - return fmts.map fun (fmt, na) ↦ (stx, f!"{na} : {fmt}")) + return fmts.map fun (fmt, na) ↦ (stx, f!"{na} : {fmt}"))) /-- The main implementation of the `have` vs `let` linter. -/ def haveLetLinter : Linter where run := withSetOptionIn fun _stx => do diff --git a/Mathlib/Tactic/Linter/Style.lean b/Mathlib/Tactic/Linter/Style.lean index 5b17726d37d547..d949f89d541593 100644 --- a/Mathlib/Tactic/Linter/Style.lean +++ b/Mathlib/Tactic/Linter/Style.lean @@ -458,14 +458,14 @@ def longLineLinter : Linter where run := withSetOptionIn fun stx ↦ do return if stx.isOfKind ``Lean.Parser.Module.header then return -- if the linter reached the end of the file, then we scan the `import` syntax instead - let stx := ← do + let stx ← do if stx.isOfKind ``Lean.Parser.Command.eoi then let fileMap ← getFileMap -- `impMods` is the syntax for the modules imported in the current file let (impMods, _) ← Parser.parseHeader { inputString := fileMap.source, fileName := ← getFileName, fileMap := fileMap } - return impMods.raw - else return stx + pure impMods.raw + else pure stx let sstr := stx.getSubstring? let fm ← getFileMap let maxLineLength := linter.style.longLine.maxLineLength.get (← getOptions) diff --git a/Mathlib/Tactic/Linter/Whitespace.lean b/Mathlib/Tactic/Linter/Whitespace.lean index 16a175642c7990..2c6a496e390461 100644 --- a/Mathlib/Tactic/Linter/Whitespace.lean +++ b/Mathlib/Tactic/Linter/Whitespace.lean @@ -335,14 +335,14 @@ def whitespaceLinter : Linter where run := withSetOptionIn fun stx ↦ do return let some upTo := CommandStart.endPos stx | return - let fmt : Option Format := ← + let fmt : Option Format ← try - liftCoreM <| PrettyPrinter.ppCategory `command stx + liftCoreM <| some <$> PrettyPrinter.ppCategory `command stx catch _ => Linter.logLintIf linter.style.whitespace.verbose (stx.getHead?.getD stx) m!"The `whitespace` linter had some parsing issues: \ feel free to silence it and report this error!" - return none + pure none if let some fmt := fmt then let st := fmt.pretty let origSubstring := stx.getSubstring?.getD default diff --git a/Mathlib/Tactic/NormNum/Core.lean b/Mathlib/Tactic/NormNum/Core.lean index be79b82e34957e..07d76133491ac1 100644 --- a/Mathlib/Tactic/NormNum/Core.lean +++ b/Mathlib/Tactic/NormNum/Core.lean @@ -151,7 +151,7 @@ and returning the truth or falsity of `p' : Prop` from an equivalence `p ↔ p'` def deriveBoolOfIff (p p' : Q(Prop)) (hp : Q($p ↔ $p')) : MetaM ((b : Bool) × BoolResult p' b) := do let ⟨b, pb⟩ ← deriveBool p - match b with + match (dependent := true) b with | true => return ⟨true, q(Iff.mp $hp $pb)⟩ | false => return ⟨false, q((Iff.not $hp).mp $pb)⟩ diff --git a/Mathlib/Tactic/NormNum/Irrational.lean b/Mathlib/Tactic/NormNum/Irrational.lean index 8528c4739b4e17..e062206ec53c36 100644 --- a/Mathlib/Tactic/NormNum/Irrational.lean +++ b/Mathlib/Tactic/NormNum/Irrational.lean @@ -260,64 +260,64 @@ def findNotPowerCertificate (m n : Q(ℕ)) : MetaM (NotPowerCertificate m n) := /-- `norm_num` extension that proves `Irrational x ^ y` for rational `y`. `x` may be natural or rational. -/ @[norm_num Irrational (_ ^ (_ : ℝ))] -def evalIrrationalRpow : NormNumExt where eval {u α} e := do - let 0 := u | failure - let ~q(Prop) := α | failure - let ~q(Irrational (($x : ℝ) ^ ($y : ℝ))) := e | failure - let .isNNRat sℝ _ y_num y_den y_isNNRat ← derive y | failure - let ⟨gy, hy_coprime⟩ := proveNatGCD y_num y_den - if gy.natLit! != 1 then failure - let _ : $gy =Q 1 := ⟨⟩ - match ← derive x with - | .isNat sℝ ex x_isNat => - let cert ← findNotPowerCertificate q($ex) y_den - assumeInstancesCommute - return .isTrue q(irrational_rpow_nat_rat $x_isNat $y_isNNRat $hy_coprime - $cert.pf_left $cert.pf_right) - | .isNNRat sℝ _ x_num x_den x_isNNRat => - let ⟨gx, hx_coprime⟩ := proveNatGCD x_num x_den - if gx.natLit! != 1 then failure - let _ : $gx =Q 1 := ⟨⟩ - let hx_isNNRat' : Q(IsNNRat $x $x_num $x_den) := x_isNNRat - let hy_isNNRat' : Q(IsNNRat $y $y_num $y_den) := y_isNNRat - try - let numCert ← findNotPowerCertificate q($x_num) y_den +def evalIrrationalRpow : NormNumExt where eval {u α} e := + match u, α, e with + | 0, ~q(Prop), ~q(Irrational (($x : ℝ) ^ ($y : ℝ))) => do + let .isNNRat sℝ _ y_num y_den y_isNNRat ← derive y | failure + let ⟨gy, hy_coprime⟩ := proveNatGCD y_num y_den + if gy.natLit! != 1 then failure + let _ : $gy =Q 1 := ⟨⟩ + match ← derive x with + | .isNat sℝ ex x_isNat => + let cert ← findNotPowerCertificate q($ex) y_den assumeInstancesCommute - return Result.isTrue q(irrational_rpow_rat_rat_of_num $hx_isNNRat' $hy_isNNRat' - $hx_coprime $hy_coprime $numCert.pf_left $numCert.pf_right) - catch _ => - let denCert ← findNotPowerCertificate q($x_den) y_den - assumeInstancesCommute - return Result.isTrue q(irrational_rpow_rat_rat_of_den $hx_isNNRat' $hy_isNNRat' - $hx_coprime $hy_coprime $denCert.pf_left $denCert.pf_right) - | _ => failure + return .isTrue q(irrational_rpow_nat_rat $x_isNat $y_isNNRat $hy_coprime + $cert.pf_left $cert.pf_right) + | .isNNRat sℝ _ x_num x_den x_isNNRat => + let ⟨gx, hx_coprime⟩ := proveNatGCD x_num x_den + if gx.natLit! != 1 then failure + let _ : $gx =Q 1 := ⟨⟩ + let hx_isNNRat' : Q(IsNNRat $x $x_num $x_den) := x_isNNRat + let hy_isNNRat' : Q(IsNNRat $y $y_num $y_den) := y_isNNRat + try + let numCert ← findNotPowerCertificate q($x_num) y_den + assumeInstancesCommute + return Result.isTrue q(irrational_rpow_rat_rat_of_num $hx_isNNRat' $hy_isNNRat' + $hx_coprime $hy_coprime $numCert.pf_left $numCert.pf_right) + catch _ => + let denCert ← findNotPowerCertificate q($x_den) y_den + assumeInstancesCommute + return Result.isTrue q(irrational_rpow_rat_rat_of_den $hx_isNNRat' $hy_isNNRat' + $hx_coprime $hy_coprime $denCert.pf_left $denCert.pf_right) + | _ => failure + | _, _, _ => failure /-- `norm_num` extension that proves `Irrational √x` for rational `x`. -/ @[norm_num Irrational (Real.sqrt _)] def evalIrrationalSqrt : NormNumExt where eval {u α} e := do - let 0 := u | failure - let ~q(Prop) := α | failure - let ~q(Irrational (√$x)) := e | failure - match ← derive x with - | .isNat sℝ ex pf => - let cert ← findNotPowerCertificate ex q(nat_lit 2) - assumeInstancesCommute - return .isTrue q(irrational_sqrt_nat $pf $cert.pf_left $cert.pf_right) - | .isNNRat sℝ eq en ed pf => - let ⟨g, pf_coprime⟩ := proveNatGCD en ed - if g.natLit! != 1 then failure - let _ : $g =Q 1 := ⟨⟩ - try - let numCert ← findNotPowerCertificate en q(nat_lit 2) - assumeInstancesCommute - return Result.isTrue - q(irrational_sqrt_rat_of_num $pf $pf_coprime $numCert.pf_left $numCert.pf_right) - catch _ => - let denCert ← findNotPowerCertificate ed q(nat_lit 2) + match u, α, e with + | 0, ~q(Prop), ~q(Irrational (√$x)) => do + match ← derive x with + | .isNat sℝ ex pf => + let cert ← findNotPowerCertificate ex q(nat_lit 2) assumeInstancesCommute - return Result.isTrue - q(irrational_sqrt_rat_of_den $pf $pf_coprime $denCert.pf_left $denCert.pf_right) - | _ => failure + return .isTrue q(irrational_sqrt_nat $pf $cert.pf_left $cert.pf_right) + | .isNNRat sℝ eq en ed pf => + let ⟨g, pf_coprime⟩ := proveNatGCD en ed + if g.natLit! != 1 then failure + let _ : $g =Q 1 := ⟨⟩ + try + let numCert ← findNotPowerCertificate en q(nat_lit 2) + assumeInstancesCommute + return Result.isTrue + q(irrational_sqrt_rat_of_num $pf $pf_coprime $numCert.pf_left $numCert.pf_right) + catch _ => + let denCert ← findNotPowerCertificate ed q(nat_lit 2) + assumeInstancesCommute + return Result.isTrue + q(irrational_sqrt_rat_of_den $pf $pf_coprime $denCert.pf_left $denCert.pf_right) + | _ => failure + | _, _, _ => failure end NormNum diff --git a/Mathlib/Tactic/Positivity/Basic.lean b/Mathlib/Tactic/Positivity/Basic.lean index 4e078e63ad35fc..0efd17c7fde774 100644 --- a/Mathlib/Tactic/Positivity/Basic.lean +++ b/Mathlib/Tactic/Positivity/Basic.lean @@ -63,6 +63,7 @@ such that `positivity` successfully recognises both `a` and `b`. -/ haveI' : $e =Q ite $p $a $b := ⟨⟩ let ra ← core zα pα? a; let rb ← core zα pα? b guard <|← withDefault <| withNewMCtxDepth <| isDefEq f q(ite (α := $α)) + id <| match ra, rb with | .positive pa, .positive pb => pure (.positive q(ite_pos $p $pa $pb)) | .positive pa, .nonnegative pb => pure (.nonnegative q(ite_nonneg_of_pos_of_nonneg $p $pa $pb)) @@ -95,7 +96,7 @@ such that `positivity` successfully recognises both `a` and `b`. -/ let _a ← synthInstanceQ q(LinearOrder $α) let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(min) assumeInstancesCommute - match ← core zα pα? a, ← core zα pα? b with + match (dependent := true) ← core zα pα? a, ← core zα pα? b with | .positive (pα := pα') pa, .positive pb => assumeInstancesCommute pure (.positive q(lt_min $pa $pb)) @@ -127,7 +128,7 @@ is nonnegative, strictly positive if at least one is positive, and nonzero if bo let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(max) let result : Strictness zα e pα? ← catchNone do let ra ← core zα pα? a - match ra with + match (dependent := true) ra with | .positive pa => assumeInstancesCommute pure (.positive q(lt_max_of_lt_left $pa)) @@ -140,7 +141,7 @@ is nonnegative, strictly positive if at least one is positive, and nonzero if bo | _ => pure .none orElse result do let rb ← core zα pα? b - match rb with + match (dependent := true) rb with | .positive pb => assumeInstancesCommute pure (.positive q(lt_max_of_lt_right $pb)) @@ -155,14 +156,14 @@ is nonnegative, strictly positive if at least one is positive, and nonzero if bo /-- The `positivity` extension which identifies expressions of the form `a + b`, such that `positivity` successfully recognises both `a` and `b`. -/ -@[positivity _ + _] def evalAdd : PositivityExt where eval {u α} zα pα? e := do +@[positivity _ + _] def evalAdd : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do let .app (.app (f : Q($α → $α → $α)) (a : Q($α))) (b : Q($α)) ← whnfR e | throwError "not +" let _e_eq : $e =Q $f $a $b := ⟨⟩ let _a ← synthInstanceQ q(AddZeroClass $α) assumeInstancesCommute let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HAdd.hAdd) - let ra ← core zα pα? a; let rb ← core zα pα? b - let some _pα := pα? | pure .none + let ra ← core zα pα a; let rb ← core zα pα b match ra, rb with | .positive pa, .positive pb => let _a ← synthInstanceQ q(AddLeftMono $α) @@ -186,8 +187,9 @@ such that there is a local hypothesis `b < a`, `b ≤ a`, `a ≠ b` or `b ≠ a` let _a ← synthInstanceQ q(AddGroup $α) assumeInstancesCommute let ⟨_f_eq⟩ ← withDefault <| withNewMCtxDepth <| assertDefEqQ q($f) q(HSub.hSub) + id <| match pα? with - | some pα => + | some pα => do let mut result := .none for decl in ← getLCtx do unless decl.isImplementationDetail do @@ -221,7 +223,7 @@ such that there is a local hypothesis `b < a`, `b ≤ a`, `a ≠ b` or `b ≠ a` return .none | _ => return .none return result - | none => + | none => do let mut result := .none for decl in ← getLCtx do unless decl.isImplementationDetail do @@ -271,8 +273,9 @@ such that `positivity` successfully recognises both `a` and `b`. -/ let _a ← synthInstanceQ q(PosMulStrictMono $α) assumeInstancesCommute pure (.positive q(mul_pos $pa $pb)) + id <| match pα? with - | some pα => + | some pα => do let mut result : Strictness zα e (some pα) := .none result ← orElse result (tryProvePositive pα ra.toPositive rb.toPositive) result ← orElse result (tryProveNonneg pα ra.toNonneg rb.toNonneg) @@ -295,8 +298,8 @@ lemma int_div_nonneg_of_pos_of_pos {a b : ℤ} (ha : 0 < a) (hb : 0 < b) : 0 ≤ /-- The `positivity` extension which identifies expressions of the form `a / b`, where `a` and `b` are integers. -/ -@[positivity (_ : ℤ) / (_ : ℤ)] def evalIntDiv : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℤ" +@[positivity (_ : ℤ) / (_ : ℤ)] def evalIntDiv : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℤ), ~q($a / $b) => let ra ← core q(inferInstance) (some q(inferInstance)) a @@ -334,78 +337,82 @@ meta def evalPowZeroNat : PositivityExt where eval {u α} _zα pα? e := do assumeInstancesCommute haveI' : $e =Q $a ^ 0 := ⟨⟩ let _a ← synthInstanceQ q(Nontrivial $α) - let some _pα := pα? | pure (.nonzero q(pow_zero_ne_zero $a)) - let _a ← synthInstanceQ q(IsOrderedRing $α) - pure (.positive q(pow_zero_pos $a)) + match (dependent := true) pα? with + | some _pα => + let _a ← synthInstanceQ q(IsOrderedRing $α) + pure (.positive q(pow_zero_pos $a)) + | none => pure (.nonzero q(pow_zero_ne_zero $a)) /-- The `positivity` extension which identifies expressions of the form `a ^ (b : ℕ)`, such that `positivity` successfully recognises both `a` and `b`. -/ @[positivity _ ^ (_ : ℕ)] meta def evalPow : PositivityExt where eval {u α} zα pα? e := do let .app (.app _ (a : Q($α))) (b : Q(ℕ)) ← whnfR e | throwError "not ^" - let some pα := pα? | do + match (dependent := true) pα? with + | none => let _a ← synthInstanceQ q(MonoidWithZero $α) let _a ← synthInstanceQ q(NoZeroDivisors $α) assumeInstancesCommute haveI' : $e =Q $a ^ $b := ⟨⟩ let .nonzero nza ← core zα .none a | pure .none pure (.nonzero q(pow_ne_zero $b $nza)) - let result : Strictness zα e pα ← catchNone do - let _a ← synthInstanceQ q(Ring $α) - let _a ← synthInstanceQ q(LinearOrder $α) - let _a ← synthInstanceQ q(IsStrictOrderedRing $α) - assumeInstancesCommute - let .true := b.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ n where n is a literal" - let some n := (b.getRevArg! 1).rawNatLit? | throwError "not a ^ n where n is a literal" - guard (n % 2 = 0) - have m : Q(ℕ) := mkRawNatLit (n / 2) - haveI' : $b =Q 2 * $m := ⟨⟩ - haveI' : $e =Q $a ^ $b := ⟨⟩ - pure (.nonnegative q((even_two_mul $m).pow_nonneg $a)) - orElse result do - let ra ← core zα pα a - let ofNonneg (pa : Q(0 ≤ $a)) (_rα : Q(Semiring $α)) (_oα : Q(IsOrderedRing $α)) : - MetaM (Strictness zα e (some pα)) := do - haveI' : $e =Q $a ^ $b := ⟨⟩ + | some pα => + let result : Strictness zα e pα ← catchNone do + let _a ← synthInstanceQ q(Ring $α) + let _a ← synthInstanceQ q(LinearOrder $α) + let _a ← synthInstanceQ q(IsStrictOrderedRing $α) assumeInstancesCommute - pure (.nonnegative q(pow_nonneg $pa $b)) - let ofNonzero (pa : Q($a ≠ 0)) (_rα : Q(Semiring $α)) (_oα : Q(IsOrderedRing $α)) : - MetaM (Strictness zα e (some pα)) := do + let .true := b.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ n where n is a literal" + let some n := (b.getRevArg! 1).rawNatLit? | throwError "not a ^ n where n is a literal" + guard (n % 2 = 0) + have m : Q(ℕ) := mkRawNatLit (n / 2) + haveI' : $b =Q 2 * $m := ⟨⟩ haveI' : $e =Q $a ^ $b := ⟨⟩ - assumeInstancesCommute - let _a ← synthInstanceQ q(NoZeroDivisors $α) - pure (.nonzero q(pow_ne_zero $b $pa)) - match ra with - | .positive pa => - try - let _a ← synthInstanceQ q(Semiring $α) - let _a ← synthInstanceQ q(IsStrictOrderedRing $α) + pure (.nonnegative q((even_two_mul $m).pow_nonneg $a)) + orElse result do + let ra ← core zα pα a + let ofNonneg (pa : Q(0 ≤ $a)) (_rα : Q(Semiring $α)) (_oα : Q(IsOrderedRing $α)) : + MetaM (Strictness zα e (some pα)) := do + haveI' : $e =Q $a ^ $b := ⟨⟩ assumeInstancesCommute + pure (.nonnegative q(pow_nonneg $pa $b)) + let ofNonzero (pa : Q($a ≠ 0)) (_rα : Q(Semiring $α)) (_oα : Q(IsOrderedRing $α)) : + MetaM (Strictness zα e (some pα)) := do haveI' : $e =Q $a ^ $b := ⟨⟩ - pure (.positive q(pow_pos $pa $b)) - catch e : Exception => - trace[Tactic.positivity.failure] "{e.toMessageData}" - let rα ← synthInstanceQ q(Semiring $α) - let oα ← synthInstanceQ q(IsOrderedRing $α) - orElse (← catchNone (ofNonneg q(le_of_lt $pa) rα oα)) (ofNonzero q(ne_of_gt $pa) rα oα) - | .nonnegative pa => - let sα ← synthInstanceQ q(Semiring $α) - let oα ← synthInstanceQ q(IsOrderedRing $α) - ofNonneg q($pa) q($sα) q($oα) - | .nonzero pa => - let sα ← synthInstanceQ q(Semiring $α) - let oα ← synthInstanceQ q(IsOrderedRing $α) - ofNonzero q($pa) q($sα) q($oα) - | .none => pure .none + assumeInstancesCommute + let _a ← synthInstanceQ q(NoZeroDivisors $α) + pure (.nonzero q(pow_ne_zero $b $pa)) + match ra with + | .positive pa => + try + let _a ← synthInstanceQ q(Semiring $α) + let _a ← synthInstanceQ q(IsStrictOrderedRing $α) + assumeInstancesCommute + haveI' : $e =Q $a ^ $b := ⟨⟩ + pure (.positive q(pow_pos $pa $b)) + catch e : Exception => + trace[Tactic.positivity.failure] "{e.toMessageData}" + let rα ← synthInstanceQ q(Semiring $α) + let oα ← synthInstanceQ q(IsOrderedRing $α) + orElse (← catchNone (ofNonneg q(le_of_lt $pa) rα oα)) (ofNonzero q(ne_of_gt $pa) rα oα) + | .nonnegative pa => + let sα ← synthInstanceQ q(Semiring $α) + let oα ← synthInstanceQ q(IsOrderedRing $α) + ofNonneg q($pa) q($sα) q($oα) + | .nonzero pa => + let sα ← synthInstanceQ q(Semiring $α) + let oα ← synthInstanceQ q(IsOrderedRing $α) + ofNonzero q($pa) q($sα) q($oα) + | .none => pure .none theorem abs_pos_of_ne_zero {α : Type*} [AddGroup α] [LinearOrder α] [AddLeftMono α] {a : α} : a ≠ 0 → 0 < |a| := abs_pos.mpr /-- The `positivity` extension which identifies expressions of the form `|a|`. -/ @[positivity |_|] -meta def evalAbs : PositivityExt where eval {_u} (α zα pα?) (e : Q($α)) := do +meta def evalAbs : PositivityExt where eval {_u} (α zα pα?) (e : Q($α)) := + match pα? with | none => pure .none | some pα' => do let ~q(@abs _ (_) (_) $a) := e | throwError "not |·|" - let some pα' := pα? | pure .none try match ← core zα (some pα') a with | .positive pa => @@ -427,8 +434,8 @@ Since the output type of `Int.natAbs` is `ℕ`, the nonnegative case is handled `positivity` tactic. -/ @[positivity Int.natAbs _] -meta def evalNatAbs : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalNatAbs : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Int.natAbs $a) => let zα' : Q(Zero Int) := q(inferInstance) @@ -453,25 +460,27 @@ meta def evalNatCast : PositivityExt where eval {u α} _zα pα? e := do let ~q(@Nat.cast _ (_) ($a : ℕ)) := e | throwError "not Nat.cast" let zα' : Q(Zero Nat) := q(inferInstance) let (_i1 : Q(AddMonoidWithOne $α)) ← synthInstanceQ q(AddMonoidWithOne $α) - let some _pα := pα? | do + match (dependent := true) pα? with + | none => let (_cz : Q(CharZero $α)) ← synthInstanceQ q(CharZero $α) assumeInstancesCommute match ← core zα' .none a with | .nonzero nza => pure (.nonzero q(Nat.cast_ne_zero.2 $nza)) | _ => pure .none - let pα' : Q(PartialOrder Nat) := q(inferInstance) - let (_i2 : Q(AddLeftMono $α)) ← synthInstanceQ q(AddLeftMono $α) - let (_i3 : Q(ZeroLEOneClass $α)) ← synthInstanceQ q(ZeroLEOneClass $α) - assumeInstancesCommute - match ← core zα' pα' a with - | .positive pa => - try - let _nz ← synthInstanceQ q(NeZero (1 : $α)) - pure (.positive q(Nat.cast_pos'.2 $pa)) - catch _ => + | some _pα => + let pα' : Q(PartialOrder Nat) := q(inferInstance) + let (_i2 : Q(AddLeftMono $α)) ← synthInstanceQ q(AddLeftMono $α) + let (_i3 : Q(ZeroLEOneClass $α)) ← synthInstanceQ q(ZeroLEOneClass $α) + assumeInstancesCommute + match ← core zα' pα' a with + | .positive pa => + try + let _nz ← synthInstanceQ q(NeZero (1 : $α)) + pure (.positive q(Nat.cast_pos'.2 $pa)) + catch _ => + pure (.nonnegative q(Nat.cast_nonneg' _)) + | _ => pure (.nonnegative q(Nat.cast_nonneg' _)) - | _ => - pure (.nonnegative q(Nat.cast_nonneg' _)) /-- Extension for the `positivity` tactic: `Int.cast` is positive (resp. non-negative) if its input is. -/ @@ -481,7 +490,7 @@ meta def evalIntCast : PositivityExt where eval {u α} _zα pα? e := do let zα' : Q(Zero Int) := q(inferInstance) let pα' : Q(PartialOrder Int) := q(inferInstance) let ra ← core zα' pα' a - match ra, pα? with + match (dependent := true) ra, pα? with | .positive pa, some _ => let _rα ← synthInstanceQ q(Ring $α) let _oα ← synthInstanceQ q(IsOrderedRing $α) @@ -504,8 +513,8 @@ meta def evalIntCast : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for `Nat.succ`. -/ @[positivity Nat.succ _] -meta def evalNatSucc : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalNatSucc : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.succ $a) => assertInstancesCommute @@ -514,8 +523,8 @@ meta def evalNatSucc : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for `PNat.val`. -/ @[positivity PNat.val _] -meta def evalPNatVal : PositivityExt where eval {u α} _zα pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalPNatVal : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(PNat.val $a) => assertInstancesCommute @@ -524,8 +533,8 @@ meta def evalPNatVal : PositivityExt where eval {u α} _zα pα? e := do /-- Extension for `Nat.factorial`. -/ @[positivity Nat.factorial _] -meta def evalFactorial : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalFactorial : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.factorial $a) => assertInstancesCommute @@ -534,8 +543,8 @@ meta def evalFactorial : PositivityExt where eval {u α} _ pα? e := do /-- Extension for `Nat.ascFactorial`. -/ @[positivity Nat.ascFactorial _ _] -meta def evalAscFactorial : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalAscFactorial : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.ascFactorial ($n + 1) $k) => assertInstancesCommute @@ -547,7 +556,8 @@ Uses positivity of the left term, if available, then tries the right term. The implementation relies on the fact that `Positivity.core` on `ℕ` never returns `nonzero`. -/ @[positivity Nat.gcd _ _] -meta def evalNatGCD : PositivityExt where eval {u α} z p e := do +meta def evalNatGCD : PositivityExt where eval {u α} z p e := + match p with | none => throwError "not PartialOrder ℕ" | some p => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.gcd $a $b) => assertInstancesCommute @@ -565,7 +575,8 @@ meta def evalNatGCD : PositivityExt where eval {u α} z p e := do /-- Extension for `Nat.lcm`. -/ @[positivity Nat.lcm _ _] -meta def evalNatLCM : PositivityExt where eval {u α} z p e := do +meta def evalNatLCM : PositivityExt where eval {u α} z p e := + match p with | none => throwError "not PartialOrder ℕ" | some p => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.lcm $a $b) => match ← core z p a with @@ -581,7 +592,8 @@ meta def evalNatLCM : PositivityExt where eval {u α} z p e := do /-- Extension for `Nat.sqrt`. -/ @[positivity Nat.sqrt _] -meta def evalNatSqrt : PositivityExt where eval {u α} z p e := do +meta def evalNatSqrt : PositivityExt where eval {u α} z p e := + match p with | none => throwError "not PartialOrder ℕ" | some p => do match u, α, e with | 0, ~q(ℕ), ~q(Nat.sqrt $n) => match ← core z p n with @@ -594,8 +606,8 @@ meta def evalNatSqrt : PositivityExt where eval {u α} z p e := do /-- Extension for `Int.gcd`. Uses positivity of the left term, if available, then tries the right term. -/ @[positivity Int.gcd _ _] -meta def evalIntGCD : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalIntGCD : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Int.gcd $a $b) => let z ← synthInstanceQ (q(Zero ℤ) : Q(Type)) @@ -611,8 +623,8 @@ meta def evalIntGCD : PositivityExt where eval {u α} _ pα? e := do /-- Extension for `Int.lcm`. -/ @[positivity Int.lcm _ _] -meta def evalIntLCM : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalIntLCM : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Int.lcm $a $b) => let z ← synthInstanceQ (q(Zero ℤ) : Q(Type)) @@ -635,8 +647,8 @@ alias ⟨_, NNRat.num_ne_zero_of_ne_zero⟩ := num_ne_zero /-- The `positivity` extension which identifies expressions of the form `NNRat.num q`, such that `positivity` successfully recognises `q`. -/ @[positivity NNRat.num _] -meta def evalNNRatNum : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalNNRatNum : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(NNRat.num $a) => let zα : Q(Zero ℚ≥0) := q(inferInstance) @@ -652,8 +664,8 @@ meta def evalNNRatNum : PositivityExt where eval {u α} _ pα? e := do /-- The `positivity` extension which identifies expressions of the form `Rat.den a`. -/ @[positivity NNRat.den _] -meta def evalNNRatDen : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalNNRatDen : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(NNRat.den $a) => assumeInstancesCommute @@ -677,8 +689,8 @@ alias ⟨_, num_ne_zero_of_ne_zero⟩ := num_ne_zero /-- The `positivity` extension which identifies expressions of the form `Rat.num a`, such that `positivity` successfully recognises `a`. -/ @[positivity Rat.num _] -meta def evalRatNum : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℤ" +meta def evalRatNum : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℤ" | some _ => do match u, α, e with | 0, ~q(ℤ), ~q(Rat.num $a) => let zα : Q(Zero ℚ) := q(inferInstance) @@ -695,8 +707,8 @@ meta def evalRatNum : PositivityExt where eval {u α} _ pα? e := do /-- The `positivity` extension which identifies expressions of the form `Rat.den a`. -/ @[positivity Rat.den _] -meta def evalRatDen : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | throwError "not PartialOrder ℕ" +meta def evalRatDen : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Rat.den $a) => assumeInstancesCommute @@ -705,8 +717,8 @@ meta def evalRatDen : PositivityExt where eval {u α} _ pα? e := do /-- Extension for `posPart`. `a⁺` is always nonnegative, and positive if `a` is. -/ @[positivity _⁺] -meta def evalPosPart : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalPosPart : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match e with | ~q(@posPart _ $instαpospart $a) => let _instαlat ← synthInstanceQ q(Lattice $α) @@ -723,8 +735,8 @@ meta def evalPosPart : PositivityExt where eval {u α} zα pα? e := do /-- Extension for `negPart`. `a⁻` is always nonnegative. -/ @[positivity _⁻] -meta def evalNegPart : PositivityExt where eval {u α} _ pα? e := do - let some _ := pα? | pure .none +meta def evalNegPart : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match e with | ~q(@negPart _ $instαnegpart $a) => let _instαlat ← synthInstanceQ q(Lattice $α) @@ -735,8 +747,8 @@ meta def evalNegPart : PositivityExt where eval {u α} _ pα? e := do /-- Extension for the `positivity` tactic: nonnegative maps take nonnegative values. -/ @[positivity DFunLike.coe _ _] -meta def evalMap : PositivityExt where eval {_ β} _ pβ? e := do - let some _ := pβ? | pure .none +meta def evalMap : PositivityExt where eval {_ β} _ pβ? e := + match pβ? with | none => pure .none | some _ => do let .app (.app _ f) a ← whnfR e | throwError "not ↑f · where f is of NonnegHomClass" let pa ← mkAppOptM ``apply_nonneg #[none, none, β, none, none, none, none, f, a] diff --git a/Mathlib/Tactic/Positivity/Core.lean b/Mathlib/Tactic/Positivity/Core.lean index 45a3faaa15fde1..b69cd0624625f5 100644 --- a/Mathlib/Tactic/Positivity/Core.lean +++ b/Mathlib/Tactic/Positivity/Core.lean @@ -417,17 +417,17 @@ It assumes `t₁` has already been run for a result, and runs `t₂` and takes t It will skip `t₂` if `t₁` is already a proof of `.positive`, and can also combine `.nonnegative` and `.nonzero` to produce a `.positive` result. -/ def orElse {pα?} {e : Q($α)} (t₁ : Strictness zα e pα?) (t₂ : MetaM (Strictness zα e pα?)) : - MetaM (Strictness zα e pα?) := do + MetaM (Strictness zα e pα?) := match t₁ with | .none => catchNone t₂ | p@(.positive _) => pure p - | .nonnegative p₁ => + | .nonnegative p₁ => do match ← catchNone t₂ with | p@(.positive _) => pure p | .nonzero p₂ => pure (.positive q(lt_of_le_of_ne' $p₁ $p₂)) | _ => pure (.nonnegative p₁) - | .nonzero p₁ => - match ← catchNone t₂ with + | .nonzero p₁ => do + match (dependent := true) ← catchNone t₂ with | p@(.positive _) => pure p | .nonnegative p₂ => pure (.positive q(lt_of_le_of_ne' $p₂ $p₁)) | _ => pure (.nonzero p₁) @@ -442,22 +442,22 @@ def core (pα? : Option Q(PartialOrder $α)) (e : Q($α)) : MetaM (Strictness z catch err => trace[Tactic.positivity] "{e} failed: {err.toMessageData}" trace[Tactic.positivity] "current result from positivity extensions: {result.toString}" - match pα? with - | some pα => + match h : pα?, result with + | some pα, res => trace[Tactic.positivity] "{α} has some {pα}" - result ← orElse result <| normNumPositivity zα pα e - trace[Tactic.positivity] "current result from normNum: {result.toString}" - result ← orElse result <| positivityCanon zα pα e - trace[Tactic.positivity] "current result from canonicity: {result.toString}" - if let .positive _ := result then - trace[Tactic.positivity] "{e} => {result.toString}" - return result + let mut res ← orElse res <| normNumPositivity zα pα e + trace[Tactic.positivity] "current result from normNum: {res.toString}" + res ← orElse res <| positivityCanon zα pα e + trace[Tactic.positivity] "current result from canonicity: {res.toString}" + if let .positive _ := res then + trace[Tactic.positivity] "{e} => {res.toString}" + return h ▸ res for ldecl in ← getLCtx do if !ldecl.isImplementationDetail then - result ← orElse result <| compareHyp zα pα e ldecl - trace[Tactic.positivity] "{e} => {result.toString}" - throwNone (pure result) - | .none => + res ← orElse res <| compareHyp zα pα e ldecl + trace[Tactic.positivity] "{e} => {res.toString}" + throwNone (pure (h ▸ res)) + | .none, _ => trace[Tactic.positivity] "{α} has no PartialOrder" if let .nonzero _ := result then trace[Tactic.positivity] "{e} => {result.toString}" @@ -486,10 +486,10 @@ def bestResult (e : Expr) : MetaM (Bool × Expr) := do let zα ← synthInstanceQ q(Zero $α) let pα? ← try? <| synthInstanceQ q(PartialOrder $α) assumeInstancesCommute - match ← try? (Meta.Positivity.core zα pα? e) with - | some (.positive pf) => pure (true, pf) - | some (.nonnegative pf) => pure (false, pf) - | _ => throwError "could not establish the nonnegativity of {e}" + match pα?, ← try? (Meta.Positivity.core zα pα? e) with + | _, some (.positive pf) => pure (true, pf) + | _, some (.nonnegative pf) => pure (false, pf) + | _, _ => throwError "could not establish the nonnegativity of {e}" /-- Given an expression `e`, use the core method of the `positivity` tactic to prove it nonnegative. -/ @@ -508,7 +508,8 @@ def solve (t : Q(Prop)) : MetaM Expr := do let r ← catchNone <| Meta.Positivity.core zα pα? e let throw (a b : String) : MetaM Expr := throwError "failed to prove {a}, but it would be possible to prove {b} if desired" - if let some _ := pα? then + match (dependent := true) pα? with + | some _ => match relDesired, r with | .lt, .positive p | .le, .nonnegative p @@ -523,7 +524,7 @@ def solve (t : Q(Prop)) : MetaM Expr := do | .ne, .nonnegative _ | .ne', .nonnegative _ => throw "nonzeroness" "nonnegativity" | _, .none => throwError "failed to prove positivity/nonnegativity/nonzeroness" - else + | none => match relDesired, r with | .ne, .nonzero p => pure p | .ne', .nonzero p => pure q(Ne.symm $p) diff --git a/Mathlib/Tactic/Positivity/Finset.lean b/Mathlib/Tactic/Positivity/Finset.lean index 50fb47d5c610e6..139070a33db6d9 100644 --- a/Mathlib/Tactic/Positivity/Finset.lean +++ b/Mathlib/Tactic/Positivity/Finset.lean @@ -27,10 +27,10 @@ open Qq Lean Meta Finset It calls `Mathlib.Meta.proveFinsetNonempty` to attempt proving that the finset is nonempty. -/ @[positivity Finset.card _] -meta def evalFinsetCard : PositivityExt where eval {u α} _ pα? e := do +meta def evalFinsetCard : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(Finset.card $s) => - let some _ := pα? | pure .none let some ps ← proveFinsetNonempty s | return .none assertInstancesCommute return .positive q(Finset.Nonempty.card_pos $ps) @@ -38,10 +38,10 @@ meta def evalFinsetCard : PositivityExt where eval {u α} _ pα? e := do /-- Extension for `Fintype.card`. `Fintype.card α` is positive if `α` is nonempty. -/ @[positivity Fintype.card _] -meta def evalFintypeCard : PositivityExt where eval {u α} _ pα? e := do +meta def evalFintypeCard : PositivityExt where eval {u α} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℕ), ~q(@Fintype.card $β $instβ) => - let some _ := pα? | pure .none let instβno ← synthInstanceQ q(Nonempty $β) assumeInstancesCommute return .positive q(@Fintype.card_pos $β $instβ $instβno) @@ -51,10 +51,10 @@ meta def evalFintypeCard : PositivityExt where eval {u α} _ pα? e := do It calls `Mathlib.Meta.proveFinsetNonempty` to attempt proving that the finset is nonempty. -/ @[positivity Finset.dens _] -meta def evalFinsetDens : PositivityExt where eval {u 𝕜} _ pα? e := do +meta def evalFinsetDens : PositivityExt where eval {u 𝕜} _ pα? e := + match pα? with | none => pure .none | some _ => do match u, 𝕜, e with | 0, ~q(ℚ≥0), ~q(@Finset.dens $α $instα $s) => - let some _ := pα? | pure .none let some ps ← proveFinsetNonempty s | return .none assumeInstancesCommute return .positive q(@Nonempty.dens_pos $α $instα $s $ps) @@ -71,21 +71,23 @@ example (s : Finset ℕ) (f : ℕ → ℤ) (hf : ∀ n, 0 ≤ f n) : 0 ≤ s.sum because `compareHyp` can't look for assumptions behind binders. -/ @[positivity Finset.sum _ _] -meta def evalFinsetSum : PositivityExt where eval {u α} zα pα? e := do +meta def evalFinsetSum : PositivityExt where eval {u α} zα pα? e := + match pα? with + | none => pure .none -- TODO: the case without PartialOrder + | some pα => do match e with | ~q(@Finset.sum $ι _ $instα $s $f) => let i : Q($ι) ← mkFreshExprMVarQ q($ι) .syntheticOpaque have body : Q($α) := .betaRev f #[i] - let rbody ← core zα pα? body - let some pα := pα? | pure .none -- TODO: the case without PartialOrder - let p_pos : Option Q(0 < $e) := ← (do + let rbody ← core zα pα body + let p_pos : Option Q(0 < $e) ← do let .positive pbody := rbody | pure none -- Fail if the body is not provably positive let some ps ← proveFinsetNonempty s | pure none let .some pα' ← trySynthInstanceQ q(IsOrderedCancelAddMonoid $α) | pure none assertInstancesCommute let pr : Q(∀ i, 0 < $f i) ← mkLambdaFVars #[i] pbody - return some q(@sum_pos $ι $α $instα (@PartialOrder.toPreorder _ $pα) $pα' $f $s _ - (fun i _ ↦ $pr i) $ps)) + pure <| some q(@sum_pos $ι $α $instα (@PartialOrder.toPreorder _ $pα) $pα' $f $s _ + (fun i _ ↦ $pr i) $ps) -- Try to show that the sum is positive if let some p_pos := p_pos then return .positive p_pos diff --git a/Mathlib/Tactic/ReduceModChar.lean b/Mathlib/Tactic/ReduceModChar.lean index 11702f4f5e7b11..115eed60892f84 100644 --- a/Mathlib/Tactic/ReduceModChar.lean +++ b/Mathlib/Tactic/ReduceModChar.lean @@ -258,9 +258,10 @@ partial def derive (expensive := false) (e : Expr) : MetaM Simp.Result := do (simpTheorems := #[← ext.getTheorems]) let discharge := Mathlib.Meta.NormNum.discharge let r : Simp.Result := {expr := e} - let pre := Simp.preDefault #[] >> fun e => + let matchAndNorm : Simproc := fun e => try return (Simp.Step.done (← matchAndNorm (expensive := expensive) e)) catch _ => pure .continue + let pre := Simp.preDefault #[] >> matchAndNorm let post := Simp.postDefault #[] let r ← r.mkEqTrans (← Simp.main r.expr ctx (methods := { pre, post, discharge? := discharge })).1 diff --git a/Mathlib/Tactic/Ring/Basic.lean b/Mathlib/Tactic/Ring/Basic.lean index 6875ffafe604ec..ea4a8ac1fb1c2c 100644 --- a/Mathlib/Tactic/Ring/Basic.lean +++ b/Mathlib/Tactic/Ring/Basic.lean @@ -231,7 +231,7 @@ partial def ExProd.evalNatCast {a : Q(ℕ)} (va : ExProd sβ a) : AtomM (Result -/ partial def ExSum.evalNatCast {a : Q(ℕ)} (va : ExSum sβ a) : AtomM (Result (ExSum sα) q($a)) := do assumeInstancesCommute - match va with + match (dependent := true) va with | .zero => pure ⟨_, .zero, q(natCast_zero (R := $α))⟩ | .add va₁ va₂ => do let ⟨_, vb₁, pb₁⟩ ← ExProd.evalNatCast va₁ @@ -378,14 +378,13 @@ partial def add {u : Lean.Level} {α : Q(Type u)} (sα : Q(CommSemiring $α)) {a b : Q($α)} (za : RatCoeff a) (zb : RatCoeff b) : MetaM (Result RatCoeff q($a + $b) × Option Q(IsNat ($a + $b) 0)) := do let res ← za.toResult.add zb.toResult - let isZero : MetaM (Option Q(IsNat ($a + $b) 0)) ← match res with - | Result.isNat inst lit pf => do - if lit.natLit! == 0 then - have : $lit =Q 0 := ⟨⟩ - pure <| some q($pf) - else - pure none - | _ => pure none + let isZero ← match res with + | Result.isNat _inst lit pf => + if lit.natLit! == 0 then + pure <| some (pf : Q(IsNat ($a + $b) 0)) + else + pure none + | _ => pure none let r ← RatCoeff.ofResult res return ⟨r, isZero⟩ diff --git a/Mathlib/Tactic/Ring/Common.lean b/Mathlib/Tactic/Ring/Common.lean index bba23ff5496407..868611fdfd5cc9 100644 --- a/Mathlib/Tactic/Ring/Common.lean +++ b/Mathlib/Tactic/Ring/Common.lean @@ -525,7 +525,7 @@ and `xy + -xy = 0` is a `.zero` overlap. def evalAddOverlap {a b : Q($α)} (va : ExProd bt sα a) (vb : ExProd bt sα b) : OptionT MetaM (Overlap bt sα q($a + $b)) := do Lean.Core.checkSystem decl_name%.toString - match va, vb with + match (dependent := true) va, vb with | .const za, .const zb => do let ⟨⟨_, zc, pf⟩, isZero⟩ ← rc.add za zb match isZero with @@ -568,12 +568,12 @@ theorem add_pf_add_gt (b₁ : R) (_ : a + b₂ = c) : a + (b₁ + b₂) = b₁ + * `(a₁ + a₂) + (b₁ + b₂) = b₁ + ((a₁ + a₂) + b₂)` (if not `a₁.lt b₁`) -/ partial def evalAdd {a b : Q($α)} (va : ExSum bt sα a) (vb : ExSum bt sα b) : - MetaM <| Result (ExSum bt sα) q($a + $b) := do - Lean.Core.checkSystem decl_name%.toString + MetaM <| Result (ExSum bt sα) q($a + $b) := + Lean.Core.checkSystem decl_name%.toString *> match va, vb with - | .zero, vb => return ⟨b, vb, q(add_pf_zero_add $b)⟩ - | va, .zero => return ⟨a, va, q(add_pf_add_zero $a)⟩ - | .add (a := a₁) (b := _a₂) va₁ va₂, .add (a := b₁) (b := _b₂) vb₁ vb₂ => + | .zero, vb => do return ⟨b, vb, q(add_pf_zero_add $b)⟩ + | va, .zero => do return ⟨a, va, q(add_pf_add_zero $a)⟩ + | .add (a := a₁) (b := _a₂) va₁ va₂, .add (a := b₁) (b := _b₂) vb₁ vb₂ => do have va := .add va₁ va₂; have vb := .add vb₁ vb₂ -- FIXME: why does `va@(...)` fail? match ← (evalAddOverlap rc rcℕ va₁ vb₁).run with | some (.nonzero ⟨_, vc₁, pc₁⟩) => @@ -619,20 +619,20 @@ theorem mul_pp_pf_overlap {ea eb e : ℕ} (x : R) (_ : ea + eb = e) (_ : a₂ * * `(a₁ * a₂) * (b₁ * b₂) = b₁ * ((a₁ * a₂) * b₂)` (if not `a₁.lt b₁`) -/ partial def evalMulProd {a b : Q($α)} (va : ExProd bt sα a) (vb : ExProd bt sα b) : - MetaM <| Result (ExProd bt sα) q($a * $b) := do - Lean.Core.checkSystem decl_name%.toString + MetaM <| Result (ExProd bt sα) q($a * $b) := + Lean.Core.checkSystem decl_name%.toString *> match va, vb with - | .const za, .const zb => + | .const za, .const zb => do let ⟨_, zc, pf⟩ ← rc.mul za zb assumeInstancesCommute return ⟨_, .const zc, q($pf)⟩ - | .mul (x := a₁) (e := a₂) va₁ va₂ va₃, vb@(.const _) => + | .mul (x := a₁) (e := a₂) va₁ va₂ va₃, vb@(.const _) => do let ⟨_, vc, pc⟩ ← evalMulProd va₃ vb return ⟨_, .mul va₁ va₂ vc, q(mul_pf_left $a₁ $a₂ $pc)⟩ - | va@(.const _), .mul (x := b₁) (e := b₂) vb₁ vb₂ vb₃ => + | va@(.const _), .mul (x := b₁) (e := b₂) vb₁ vb₂ vb₃ => do let ⟨_, vc, pc⟩ ← evalMulProd va vb₃ return ⟨_, .mul vb₁ vb₂ vc, q(mul_pf_right $b₁ $b₂ $pc)⟩ - | .mul (x := xa) (e := ea) vxa vea va₂, .mul (x := xb) (e := eb) vxb veb vb₂ => + | .mul (x := xa) (e := ea) vxa vea va₂, .mul (x := xb) (e := eb) vxb veb vb₂ => do have va := .mul vxa vea va₂; have vb := .mul vxb veb vb₂ -- FIXME: why does `va@(...)` fail? let ⟨ea', vea'⟩ := vea.toExProd let ⟨eb', veb'⟩ := veb.toExProd @@ -664,10 +664,10 @@ theorem mul_add {d : R} (_ : (a : R) * b₁ = c₁) (_ : a * b₂ = c₂) (_ : c * `a * (b₁ + b₂) = (a * b₁) + (a * b₂)` -/ def evalMul₁ {a b : Q($α)} (va : ExProd bt sα a) (vb : ExSum bt sα b) : - MetaM <| Result (ExSum bt sα) q($a * $b) := do + MetaM <| Result (ExSum bt sα) q($a * $b) := match vb with - | .zero => return ⟨_, .zero, q(mul_zero $a)⟩ - | .add vb₁ vb₂ => + | .zero => do return ⟨_, .zero, q(mul_zero $a)⟩ + | .add vb₁ vb₂ => do let ⟨_, vc₁, pc₁⟩ ← evalMulProd rc rcℕ va vb₁ let ⟨_, vc₂, pc₂⟩ ← evalMul₁ va vb₂ let ⟨_, vd, pd⟩ ← evalAdd rc rcℕ vc₁.toSum vc₂ @@ -684,10 +684,10 @@ theorem add_mul {d : R} (_ : (a₁ : R) * b = c₁) (_ : a₂ * b = c₂) (_ : c * `(a₁ + a₂) * b = (a₁ * b) + (a₂ * b)` -/ def evalMul {a b : Q($α)} (va : ExSum bt sα a) (vb : ExSum bt sα b) : - MetaM <| Result (ExSum bt sα) q($a * $b) := do + MetaM <| Result (ExSum bt sα) q($a * $b) := match va with - | .zero => return ⟨_, .zero, q(zero_mul $b)⟩ - | .add va₁ va₂ => + | .zero => do return ⟨_, .zero, q(zero_mul $b)⟩ + | .add va₁ va₂ => do let ⟨_, vc₁, pc₁⟩ ← evalMul₁ rc rcℕ va₁ vb let ⟨_, vc₂, pc₂⟩ ← evalMul va₂ vb let ⟨_, vd, pd⟩ ← evalAdd rc rcℕ vc₁ vc₂ @@ -707,13 +707,13 @@ theorem neg_mul {R} [CommRing R] (a₁ : R) (a₂) {a₃ b : R} * `-(a₁ * a₂) = a₁ * -a₂` -/ def evalNegProd {a : Q($α)} (rα : Q(CommRing $α)) (va : ExProd bt sα a) : - MetaM <| Result (ExProd bt sα) q(-$a) := do - Lean.Core.checkSystem decl_name%.toString + MetaM <| Result (ExProd bt sα) q(-$a) := + Lean.Core.checkSystem decl_name%.toString *> match va with - | .const za => + | .const za => do let ⟨b, zb, pb⟩ ← rc.neg q($rα) za return ⟨b, .const zb, q($pb)⟩ - | .mul (x := a₁) (e := a₂) va₁ va₂ va₃ => + | .mul (x := a₁) (e := a₂) va₁ va₂ va₃ => do let ⟨_, vb, pb⟩ ← evalNegProd rα va₃ assumeInstancesCommute return ⟨_, .mul va₁ va₂ vb, q(neg_mul $a₁ $a₂ $pb)⟩ @@ -730,11 +730,13 @@ theorem neg_add {R} [CommRing R] {a₁ a₂ b₁ b₂ : R} * `-(a₁ + a₂) = -a₁ + -a₂` -/ def evalNeg {a : Q($α)} (rα : Q(CommRing $α)) (va : ExSum bt sα a) : - MetaM <| Result (ExSum bt sα) q(-$a) := do - assumeInstancesCommute + MetaM <| Result (ExSum bt sα) q(-$a) := match va with - | .zero => return ⟨_, .zero, q(neg_zero (R := $α))⟩ - | .add va₁ va₂ => + | .zero => do + assumeInstancesCommute + return ⟨_, .zero, q(neg_zero (R := $α))⟩ + | .add va₁ va₂ => do + assumeInstancesCommute let ⟨_, vb₁, pb₁⟩ ← evalNegProd rc rα va₁ let ⟨_, vb₂, pb₂⟩ ← evalNeg rα va₂ return ⟨_, .add vb₁ vb₂, q(neg_add $pb₁ $pb₂)⟩ @@ -913,9 +915,9 @@ In all other cases we use `evalPowProdAtom`. def evalPowProd {a : Q($α)} {b : Q(ℕ)} (va : ExProd bt sα a) (vb : ExProdNat b) : MetaM <| Result (ExProd bt sα) q($a ^ $b) := do Lean.Core.checkSystem decl_name%.toString - let res : OptionT MetaM (Result (ExProd bt sα) q($a ^ $b)) := do + let res : OptionT MetaM (Result (ExProd bt sα) q($a ^ $b)) := match va with - | va@(.const za) => + | va@(.const za) => do match rc.isOne za with | .some pf => return ⟨_, va, q(one_pow $b $pf)⟩ @@ -923,7 +925,7 @@ def evalPowProd {a : Q($α)} {b : Q(ℕ)} (va : ExProd bt sα a) (vb : ExProdNat -- NOTE: rc.pow may fail, e.g. for `ring` when `vb` is not a constant. let ⟨_, zc, pc⟩ ← rc.pow za vb return ⟨_, .const zc, q($pc)⟩ - | .mul vxa₁ (e := ea₁) vea₁ va₂ => + | .mul vxa₁ (e := ea₁) vea₁ va₂ => do let ⟨ea₁', vea₁'⟩ := vea₁.toExProd let ⟨b', vb'⟩ := vb.toExProd let ⟨c₁, vc₁, pc₁⟩ ← evalMulProd rcℕ rcℕ vea₁' vb' @@ -1002,15 +1004,15 @@ Otherwise `a ^ b` is just encoded as `a ^ b * 1 + 0` using `evalPowAtom`. -/ partial def evalPow₁ {a : Q($α)} {b : Q(ℕ)} (va : ExSum bt sα a) (vb : ExProdNat b) : MetaM <| Result (ExSum bt sα) q($a ^ $b) := do - let notPowOne : MetaM <| Result (ExSum bt sα) q($a ^ $b) := do + let notPowOne : MetaM <| Result (ExSum bt sα) q($a ^ $b) := match va with - | .zero => match vb.evalPos with + | .zero => do match vb.evalPos with | some p => return ⟨_, .zero, q(zero_pow (R := $α) $p)⟩ | none => return evalPowAtom rc (.sum .zero) vb - | ExSum.add va .zero => -- TODO: using `.add` here takes a while to compile? + | ExSum.add va .zero => do -- TODO: using `.add` here takes a while to compile? let ⟨_, vc, pc⟩ ← evalPowProd rc rcℕ va vb return ⟨_, vc.toSum, q(single_pow $pc)⟩ - | va => + | va => do -- FIXME: condition used to be k.coeff > 1. Should go back to something like this. let ⟨k, _, vc, pc⟩ := extractCoeff rcℕ vb if k.natLit! > 1 then @@ -1020,7 +1022,7 @@ partial def evalPow₁ {a : Q($α)} {b : Q(ℕ)} (va : ExSum bt sα a) (vb : ExP else return evalPowAtom rc (.sum va) vb match vb with - | .const zb => + | .const zb => do match rcℕ.isOne zb with | .some pf => assumeInstancesCommute @@ -1042,13 +1044,13 @@ theorem pow_add {b₁ b₂ : ℕ} {d : R} * `a ^ (b₁ + b₂) = a ^ b₁ * a ^ b₂` -/ def evalPow {a : Q($α)} {b : Q(ℕ)} (va : ExSum bt sα a) (vb : ExSumNat b) : - MetaM <| Result (ExSum bt sα) q($a ^ $b) := do + MetaM <| Result (ExSum bt sα) q($a ^ $b) := match vb with - | .zero => + | .zero => do let ⟨_, one, pf⟩ := rc.one assumeInstancesCommute return ⟨_, (ExProd.const (one)).toSum, q(pow_zero $a $pf)⟩ - | .add vb₁ vb₂ => + | .add vb₁ vb₂ => do let ⟨_, vc₁, pc₁⟩ ← evalPow₁ rc rcℕ va vb₁ let ⟨_, vc₂, pc₂⟩ ← evalPow va vb₂ let ⟨_, vd, pd⟩ ← evalMul rc rcℕ vc₁ vc₂ @@ -1130,10 +1132,10 @@ def evalInvAtom (a : Q($α)) : AtomM (Result (ExBase bt sα) q($a⁻¹)) := do * `(a ^ b * c)⁻¹ = a⁻¹ ^ b * c⁻¹` -/ def ExProd.evalInv {a : Q($α)} (czα : Option Q(CharZero $α)) (va : ExProd bt sα a) : - AtomM (Result (ExProd bt sα) q($a⁻¹)) := do - Lean.Core.checkSystem decl_name%.toString + AtomM (Result (ExProd bt sα) q($a⁻¹)) := + Lean.Core.checkSystem decl_name%.toString *> match va with - | .const c => + | .const c => do match ← rc.inv czα q($dsα) c with | some ⟨_, vd, pd⟩ => pure ⟨_, .const vd, q($pd)⟩ | none => diff --git a/Mathlib/Tactic/Ring/Compare.lean b/Mathlib/Tactic/Ring/Compare.lean index 08c15416b30deb..7d3f9da5a05e6a 100644 --- a/Mathlib/Tactic/Ring/Compare.lean +++ b/Mathlib/Tactic/Ring/Compare.lean @@ -134,8 +134,8 @@ def evalLE {v : Level} {α : Q(Type v)} let ⟨_, pz⟩ ← NormNum.mkOfNat α q(addMonoidWithOneOfCommSemiring $α) q(nat_lit 0) let rz : NormNum.Result q((0:$α)) := NormNum.Result.isNat q(addMonoidWithOneOfCommSemiring $α) q(nat_lit 0) - (q(NormNum.isNat_ofNat $α $pz):) - match va, vb with + (q(NormNum.isNat_ofNat $α $pz):) + match (dependent := true) va, vb with /- `0 ≤ 0` -/ | .zero, .zero => pure <| .ok (q(le_refl (0:$α)):) /- For numerals `ca` and `cb`, `ca + x ≤ cb + x` if `ca ≤ cb` -/ @@ -173,8 +173,8 @@ def evalLT {v : Level} {α : Q(Type v)} let ⟨_, pz⟩ ← NormNum.mkOfNat α q(addMonoidWithOneOfCommSemiring $α) q(nat_lit 0) let rz : NormNum.Result q((0:$α)) := NormNum.Result.isNat q(addMonoidWithOneOfCommSemiring $α) q(nat_lit 0) - (q(NormNum.isNat_ofNat $α $pz):) - match va, vb with + (q(NormNum.isNat_ofNat $α $pz):) + match (dependent := true) va, vb with /- `0 < 0` -/ | .zero, .zero => return .error tooSmall /- For numerals `ca` and `cb`, `ca + x < cb + x` if `ca < cb` -/ diff --git a/Mathlib/Tactic/Simproc/ExistsAndEq.lean b/Mathlib/Tactic/Simproc/ExistsAndEq.lean index bd82a4b79ea7c0..0684540ca62d4d 100644 --- a/Mathlib/Tactic/Simproc/ExistsAndEq.lean +++ b/Mathlib/Tactic/Simproc/ExistsAndEq.lean @@ -127,7 +127,7 @@ where assertUnreachable "findEq: some side of equality must be `a`, and the other must not depend on `a`" | ~q($L ∧ $R) => - match (generalizing := false) path with + match path with | [] => assertUnreachable "findEq: P is conjunction but path is empty" | .left :: tl => let (fvars, lctx, P', a') ← go a q($L) tl @@ -212,17 +212,17 @@ where MetaM Q($goal) := do match goal with | ~q(@Exists $β $pb) => - match (generalizing := false) exs with + match exs with | [] => assertUnreachable "mkAfterToBefore: goal is `Exists` but `exs` is empty" | ⟨v, γ, c⟩ :: exsTail => let _ : u_1 =QL v := ⟨⟩ let _ : $γ =Q $β := ⟨⟩ - let pf1 : Q($pb $c) := ← go h exsTail path + let pf1 : Q($pb $c) ← go h exsTail path return q(Exists.intro $c $pf1) | ~q(And $L $R) => let ~q($L' ∧ $R') := P | assertUnreachable "mkAfterToBefore: goal is `And` but `P` is not `And`" - match (generalizing := false) path with + match path with | [] => assertUnreachable "mkAfterToBefore: goal is `And` but `exs` is empty" | .left :: tl => let _ : $R =Q $R' := ⟨⟩ @@ -250,7 +250,7 @@ partial def withExistsElimAlongPathImp {u : Level} {α : Q(Sort u)} MetaM Q($goal) := do match P with | ~q(@Exists $β $pb) => - match (generalizing := false) exs with + match exs with | [] => assertUnreachable "withExistsElimAlongPathImp: `P` is `Exists` but `exs` is empty" | ⟨v, γ, b⟩ :: exsTail => let _ : u_1 =QL v := ⟨⟩ @@ -261,7 +261,7 @@ partial def withExistsElimAlongPathImp {u : Level} {α : Q(Sort u)} let pf2 : Q(∀ b, $pb b → $goal) ← mkLambdaFVars #[b, hb] pf1 return q(Exists.elim $h $pf2) | ~q(And $L' $R') => - match (generalizing := false) path with + match path with | [] => assertUnreachable "withExistsElimAlongPathImp: `P` is `And` but `path` is empty" | .left :: tl => withExistsElimAlongPathImp q(And.left $h) exs tl hs act @@ -372,21 +372,21 @@ where MetaM Q($goal) := do match P with | ~q(@Exists $β $pb) => - match (generalizing := false) exs with + match exs with | [] => assertUnreachable "mkBeforeToAfter: `P` is `Exists` but `exs` is empty" | ⟨v, γ, b⟩ :: exsTail => let _ : u_1 =QL v := ⟨⟩ let _ : $γ =Q $β := ⟨⟩ - match (generalizing := false) hs with + match hs with | [] => assertUnreachable "mkBeforeToAfter: `P` is `Exists` but `hs` is empty" | ⟨H, hb⟩ :: hsTail => let _ : $H =Q $pb $b := ⟨⟩ - let pf : Q($goal) := ← go hb exsTail hsTail path h_eq + let pf : Q($goal) ← go hb exsTail hsTail path h_eq return pf | ~q(And $L $R) => let ~q($L' ∧ $R') := goal | assertUnreachable "mkBeforeToAfter: `P` is `And` but `goal` is not `And`" - match (generalizing := false) path with + match path with | [] => assertUnreachable "mkBeforeToAfter: `P` is `And` but `path` is empty" | .left :: tl => let pa : Q($α → Prop) ← mkLambdaFVars #[a] R diff --git a/Mathlib/Tactic/TacticAnalysis/Declarations.lean b/Mathlib/Tactic/TacticAnalysis/Declarations.lean index b4dc95d07bb6da..16e41e534055f6 100644 --- a/Mathlib/Tactic/TacticAnalysis/Declarations.lean +++ b/Mathlib/Tactic/TacticAnalysis/Declarations.lean @@ -412,9 +412,9 @@ def Mathlib.TacticAnalysis.tryAtEachStepCore -- Extract just the tactic name, ignoring trailing comments/whitespace -- Use try/catch because ppTactic can fail on certain syntax (e.g., `congr($h x)`) let oldTacticPP := (← try - return ((← liftCoreM <| PrettyPrinter.ppTactic ⟨i.tacI.stx⟩).pretty.splitOn "\n")[0]!.trimAscii + pure (((← liftCoreM <| PrettyPrinter.ppTactic ⟨i.tacI.stx⟩).pretty.splitOn "\n")[0]!.trimAscii) catch _ => - return i.tacI.stx.reprint.getD "???") + pure (i.tacI.stx.reprint.getD "???")) let newTacticPP ← label.getDM (try return ((← liftCoreM <| PrettyPrinter.ppTactic tac).pretty.splitOn "\n")[0]!.trimAscii.copy catch _ => diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 7e2d6eb4249e9e..39e16b28bd0583 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -1084,7 +1084,7 @@ def elabTranslationAttr (declName : Name) (stx : Syntax) : CoreM Config := do | `(bracketedOption| (reorder := $reorder)) => if reorder?.isSome then throwErrorAt opt "cannot specify `reorder` multiple times" - reorder? ← elabReorder reorder argNames xs (.ofConstName declName) + reorder? ← some <$> elabReorder reorder argNames xs (.ofConstName declName) | `(bracketedOption| (relevant_arg := $n)) => if relevantArg?.isSome then throwErrorAt opt "cannot specify `relevant_arg` multiple times" diff --git a/Mathlib/Tactic/Translate/Reorder.lean b/Mathlib/Tactic/Translate/Reorder.lean index c2c614edeb632f..bf27e65901608e 100644 --- a/Mathlib/Tactic/Translate/Reorder.lean +++ b/Mathlib/Tactic/Translate/Reorder.lean @@ -242,7 +242,7 @@ private def decomposePerm {n} (map : Vector (Option (Fin n)) n) : Permutation := map := map.set! j none if j' = i then break j := j' - cycle := ⟨cycle.1 ++ [↑j], by grind⟩ + cycle := ⟨cycle.1 ++ [j.val], by grind⟩ perm := cycle :: perm return perm diff --git a/Mathlib/Tactic/Variable.lean b/Mathlib/Tactic/Variable.lean index cf6d13901ce531..0988a05e6a9210 100644 --- a/Mathlib/Tactic/Variable.lean +++ b/Mathlib/Tactic/Variable.lean @@ -191,7 +191,7 @@ partial def completeBinders' (maxSteps : Nat) (gas : Nat) trace[«variable?»] m!"elaborated binder types array = {types}" Term.synthesizeSyntheticMVarsNoPostponing -- checkpoint for withAutoBoundImplicit Term.withoutAutoBoundImplicit do - let (binders, toOmit) := ← do + let (binders, toOmit) ← (do match binder with | `(bracketedBinderF|[$[$ident? :]? $ty]) => -- Check if it's an alias @@ -213,7 +213,7 @@ partial def completeBinders' (maxSteps : Nat) (gas : Nat) return (binders, toOmit.push true) else return (binders, toOmit.push false) - | _ => return (binders, toOmit.push false) + | _ => return (binders, toOmit.push false)) completeBinders' maxSteps gas checkRedundant binders toOmit (i + 1) else if h : gas = 0 ∧ i < binders.size then diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean index ddd26a88733d28..97017871e4fcc6 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean @@ -371,8 +371,8 @@ attribute [local instance] monadLiftOptionMetaM in This extension only proves non-negativity, strict positivity is more delicate for infinite sums and requires more assumptions. -/ @[positivity tsum _] -meta def evalTsum : PositivityExt where eval {u α} zα pα? e := do - let some pα := pα? | pure .none +meta def evalTsum : PositivityExt where eval {u α} zα pα? e := + match pα? with | none => pure .none | some pα => do match e with | ~q(@tsum _ $ι $instCommMonoid $instTopSpace $f $L) => lambdaBoundedTelescope f 1 fun args (body : Q($α)) => do diff --git a/Mathlib/Topology/Category/CompHausLike/Limits.lean b/Mathlib/Topology/Category/CompHausLike/Limits.lean index 48241d88790508..a608a17cabb86d 100644 --- a/Mathlib/Topology/Category/CompHausLike/Limits.lean +++ b/Mathlib/Topology/Category/CompHausLike/Limits.lean @@ -120,6 +120,7 @@ lemma finiteCoproduct.ι_desc_apply {B : CompHausLike P} {π : (a : α) → X a instance : HasCoproduct X where exists_colimit := ⟨finiteCoproduct.cofan X, finiteCoproduct.isColimit X⟩ +set_option linter.checkUnivs false in variable (P) in /-- A typeclass describing the property that forming all finite disjoint unions is stable under the diff --git a/Mathlib/Topology/ContinuousMap/Algebra.lean b/Mathlib/Topology/ContinuousMap/Algebra.lean index 5d39eabc7e3970..ecac820768283a 100644 --- a/Mathlib/Topology/ContinuousMap/Algebra.lean +++ b/Mathlib/Topology/ContinuousMap/Algebra.lean @@ -492,6 +492,7 @@ end ContinuousMap end RingStructure +set_option linter.deprecated false in attribute [local ext] Subtype.eq section ModuleStructure diff --git a/Mathlib/Topology/MetricSpace/Bounded.lean b/Mathlib/Topology/MetricSpace/Bounded.lean index 50d0a217cdaf41..bd4e06e4f1504f 100644 --- a/Mathlib/Topology/MetricSpace/Bounded.lean +++ b/Mathlib/Topology/MetricSpace/Bounded.lean @@ -589,10 +589,10 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: the diameter of a set is always nonnegative. -/ @[positivity Metric.diam _] -meta def evalDiam : PositivityExt where eval {u α} _zα pα? e := do +meta def evalDiam : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@Metric.diam _ $inst $s) => - let some _ := pα? | pure .none assertInstancesCommute pure (.nonnegative q(Metric.diam_nonneg)) | _, _, _ => throwError "not ‖ · ‖" diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index aabb1cb2b5e4d6..0de76b0b857754 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -258,10 +258,10 @@ open Lean Meta Qq Function /-- Extension for the `positivity` tactic: distances are nonnegative. -/ @[positivity Dist.dist _ _] -meta def evalDist : PositivityExt where eval {u α} _zα pα? e := do +meta def evalDist : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do match u, α, e with | 0, ~q(ℝ), ~q(@Dist.dist $β $inst $a $b) => - let some _ := pα? | pure .none let _inst ← synthInstanceQ q(PseudoMetricSpace $β) assertInstancesCommute pure (.nonnegative q(dist_nonneg)) diff --git a/Mathlib/Util/CountHeartbeats.lean b/Mathlib/Util/CountHeartbeats.lean index 4180ad42d159ef..72c4fe8b668c19 100644 --- a/Mathlib/Util/CountHeartbeats.lean +++ b/Mathlib/Util/CountHeartbeats.lean @@ -153,7 +153,7 @@ elab "#count_heartbeats " approx:(&"approximately ")? "in" ppLine cmd:command : let m : TSyntax `num := quote max' Command.liftCoreM <| MetaM.run' do Lean.Meta.Tactic.TryThis.addSuggestion (← getRef) - (← set_option hygiene false in `(command| set_option maxHeartbeats $m in $cmd)) + (← (set_option hygiene false in `(command| set_option maxHeartbeats $m in $cmd))) set_option linter.style.maxHeartbeats false in /-- diff --git a/Mathlib/Util/GetAllModules.lean b/Mathlib/Util/GetAllModules.lean index 5da0463be9851c..09461a0d52f3ab 100644 --- a/Mathlib/Util/GetAllModules.lean +++ b/Mathlib/Util/GetAllModules.lean @@ -54,5 +54,5 @@ In addition, these names are sorted in a platform-independent order. -/ def getAllModulesSorted (git : Bool) (ml : String) : IO (Array String) := do let files ← getAllFiles git ml let names ← files.mapM fun f => do - return (← moduleNameOfFileName f none).toString + return (← moduleNameOfFileName f none).toString return names.qsort (· < ·) diff --git a/Mathlib/Util/WhatsNew.lean b/Mathlib/Util/WhatsNew.lean index a14267afd8b85e..b833d1f05b79f0 100644 --- a/Mathlib/Util/WhatsNew.lean +++ b/Mathlib/Util/WhatsNew.lean @@ -108,7 +108,7 @@ def whatsNew (old new : Environment) : CoreM MessageData := do diffs := diffs.push (← printIdCore c i) for ext in ← persistentEnvExtensionsRef.get do - if let some diff := ← diffExtension old new ext then + if let some diff ← diffExtension old new ext then diffs := diffs.push diff if diffs.isEmpty then return "no new constants" diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index 9496d27dc41f71..f4e097c49bfab5 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -142,6 +142,7 @@ def foo4 {α : Type u} : Type v → Type (max u v) := @my_has_pow α @[to_additive bar4_test] lemma foo4_test {α β : Type u} : @foo4 α β = @my_has_pow α β := rfl +set_option linter.defProp false in @[to_additive bar5] def foo5 {α} [my_has_pow α ℕ] [my_has_pow ℕ ℤ] : True := True.intro @@ -304,6 +305,7 @@ attribute [to_additive add_some_def] some_def run_cmd do liftCoreM <| successIfFail (getConstInfo `Test.add_some_def.in_namespace) +set_option linter.defProp false in set_option linter.unusedVariables false in def foo_mul {I J K : Type} (n : ℕ) {f : I → Type} (L : Type) [∀ i, One (f i)] [Add I] [Mul L] : true := by trivial @@ -911,6 +913,7 @@ def monoidAlgebraFoo₂ {k G : Type} [Inhabited k] : MonoidAlgebra k G × Nat := (⟨fun _ ↦ default⟩, 2) -- Proofs in types aren't abstracted: +set_option linter.defProp false in @[to_additive] def abstractMul : Function.const _ True (id Nat.zero_lt_one) := trivial diff --git a/MathlibTest/Attribute/ToDual.lean b/MathlibTest/Attribute/ToDual.lean index 890c9c996640e3..7a3676cc8633b0 100644 --- a/MathlibTest/Attribute/ToDual.lean +++ b/MathlibTest/Attribute/ToDual.lean @@ -71,6 +71,7 @@ attribute [to_dual existing] Semilattice.toSemilatticeSup -- when reordering arguments in arguments that are being reordered, -- there is a convenient syntax to specify this at the same time: +set_option linter.defProp false in @[to_dual self (reorder := h₁ h₂ (a b))] def SemilatticeSup.foo {α} [Semilattice α] (h₁ : ∀ a b : α, a ⊔ b ≤ b) (h₂ : ∀ a b : α, a ≤ b ⊓ a) (my_sorry : ∀ {p : Prop}, p) : False := @@ -310,6 +311,7 @@ info: theorem Cov.Ioc_def : ∀ {α : Type} [inst : PartialOrder α] {a b x : α /-! Test that translated autoparams are marked with `meta`. -/ +set_option linter.defProp false in @[to_dual] def Top.autoParamTest {a b : α} (h : a ≤ b := by grind) : a ≤ b := h @@ -362,6 +364,7 @@ private theorem WithBotPrivate.coe_le_top : WithTop.coe a ≤ .top := .le_top (W run_meta guard <| (← getEnv).contains ``WithTopPrivate.coe_le_bot +set_option linter.defProp false in set_option linter.unusedVariables false in @[to_dual (rename := x → y, Pbot ↔ Ptop) renameTest'] def renameTest [Top α] [Bot α] (x : α) {P : α → Prop} (Ptop : P ⊤) (Pbot : P ⊥) : True := trivial diff --git a/MathlibTest/CategoryTheory/CategoryStar.lean b/MathlibTest/CategoryTheory/CategoryStar.lean index c5f5ccbf709e1d..5e0f143a13f2d0 100644 --- a/MathlibTest/CategoryTheory/CategoryStar.lean +++ b/MathlibTest/CategoryTheory/CategoryStar.lean @@ -66,7 +66,9 @@ universe u₁ u₂ variable (E : Sort (imax (u₁ + 1) (u₂ + 1))) [Category* E] variable (F : Sort (max (u₁ + 1) (u₂ + 1))) [Category* F] +set_option linter.checkUnivs false in def barE := E ⥤ E +set_option linter.checkUnivs false in def barF := F ⥤ F /-- diff --git a/MathlibTest/Linter/DocPrime.lean b/MathlibTest/Linter/DocPrime.lean index bc217c8686bc65..7f3139c7d0e153 100644 --- a/MathlibTest/Linter/DocPrime.lean +++ b/MathlibTest/Linter/DocPrime.lean @@ -88,6 +88,7 @@ Declarations whose name ends with a `'` are expected to contain an explanation f Note: This linter can be disabled with `set_option linter.docPrime false` -/ #guard_msgs in +set_option linter.defProp false in def def_no_doc' : True := .intro -- Anonymous declarations in a primed namespace should not get flagged by the linter. diff --git a/MathlibTest/MinImports.lean b/MathlibTest/MinImports.lean index e9b070f1862af7..5d1ce54b16f228 100644 --- a/MathlibTest/MinImports.lean +++ b/MathlibTest/MinImports.lean @@ -86,6 +86,7 @@ lemma hi (n : ℕ) : n = n := by extract_goal; rfl section Variables +set_option linter.defProp false in /-- info: public import Mathlib.Data.Nat.Notation -/ #guard_msgs in #min_imports in @@ -98,6 +99,7 @@ variable {K : Type*} [Field K] namespace Namespace +set_option linter.defProp false in -- The dependency on `Semiring` is only found in the `variable` declaration. -- We find it by looking up the declaration by name and checking the term, -- which used to get confused if running in a namespace. diff --git a/MathlibTest/Simps.lean b/MathlibTest/Simps.lean index b315b0cb6598ad..e37261b0427cc4 100644 --- a/MathlibTest/Simps.lean +++ b/MathlibTest/Simps.lean @@ -977,6 +977,7 @@ instance has_PropClass (n : ℕ) : PropClass n := ⟨trivial⟩ structure NeedsPropClass (n : ℕ) [PropClass n] where (t : True) +set_option linter.defProp false in @[simps] def test_PropClass : NeedsPropClass 1 := { t := trivial } diff --git a/MathlibTest/Subsingleton.lean b/MathlibTest/Subsingleton.lean index f139fe25b410b0..eca165c5f4f5ac 100644 --- a/MathlibTest/Subsingleton.lean +++ b/MathlibTest/Subsingleton.lean @@ -141,6 +141,7 @@ example {α : Type} [BEq α] (f : ∀ {β : Type} [BEq β], Subsingleton β) (x The same, but now there's a universe level metavariable. -/ set_option warn.classDefReducibility false in +set_option linter.defProp false in def fdef : ∀ {β : Type _} [BEq β], Subsingleton β := test_sorry example {α : Type} [BEq α] (x y : α) : x = y := by diff --git a/MathlibTest/Tactic/Says/Basic.lean b/MathlibTest/Tactic/Says/Basic.lean index e21eac40686df1..1ab8f8f01ae9b7 100644 --- a/MathlibTest/Tactic/Says/Basic.lean +++ b/MathlibTest/Tactic/Says/Basic.lean @@ -97,8 +97,10 @@ example : True := by -- Check that verification works even with multi-line suggestions, as produced by aesop def P : Prop := True def Q : Prop := True +set_option linter.defProp false in @[simp] def very_long_lemma_name_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa : Q → P := fun _ => trivial +set_option linter.defProp false in @[simp] def very_long_lemma_name_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb : Q := trivial /-- diff --git a/MathlibTest/UnusedTactic.lean b/MathlibTest/UnusedTactic.lean index 812ffe92e2c33b..2991ffbb29eaca 100644 --- a/MathlibTest/UnusedTactic.lean +++ b/MathlibTest/UnusedTactic.lean @@ -20,6 +20,7 @@ example : 1 = 1 := by change 1 = 1 rfl +set_option linter.defProp false in def why2 : True → True := (by refine ·) example : True := by diff --git a/MathlibTest/globalAttributeIn.lean b/MathlibTest/globalAttributeIn.lean index 1c124f2b4d4ed0..ce50c8fece0e58 100644 --- a/MathlibTest/globalAttributeIn.lean +++ b/MathlibTest/globalAttributeIn.lean @@ -13,6 +13,7 @@ import Mathlib.Tactic.Linter.GlobalAttributeIn class Dummy where field : True +set_option linter.defProp false in @[reducible] def dummyInst : Dummy := ⟨True.intro⟩ /-- diff --git a/MathlibTest/symm.lean b/MathlibTest/symm.lean index 4ae3ef96355bc3..6e660b12b59b5b 100644 --- a/MathlibTest/symm.lean +++ b/MathlibTest/symm.lean @@ -3,6 +3,7 @@ import Mathlib.Logic.Equiv.Basic set_option autoImplicit true -- testing that the attribute is recognized +set_option linter.defProp false in @[symm] def eq_symm {α : Type} (a b : α) : a = b → b = a := Eq.symm example (a b : Nat) : a = b → b = a := by intros; symm; assumption @@ -11,6 +12,7 @@ example (a b : Nat) : a = b → True → b = a := by intro h _; symm at h; assum def sameParity : Nat → Nat → Prop | n, m => n % 2 = m % 2 +set_option linter.defProp false in @[symm] def sameParity_symm (n m : Nat) : sameParity n m → sameParity m n := Eq.symm example (a b : Nat) : sameParity a b → sameParity b a := by intros; symm; assumption diff --git a/lake-manifest.json b/lake-manifest.json index aff8d1dac87c1c..993ff072b9c621 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "63045536fe95024e6c18fc7b48e03f506701c5bc", + "rev": "f3f26cc72646205ca167117487c008ee1dafe816", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "5c7542ed018c78194f1e2b903eaf6a792b74c03d", + "rev": "41f407a8e85b0fdc00910633a8f14754139b63f4", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "24b0d9dc081c5423f8eec7e866c441e5184f29d9", + "rev": "e6518a674e62de322b8f79eebeda7bcae2a36bc3", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e3cb2f741431ce31bf73549fb52316a57368b06f", + "rev": "b5b9e2bb45ce91e4bc44eaa738c3a8910404ab82", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f46324995fca5f0483b742e4eb4daec7f4ee50d2", + "rev": "7a62bd13860cd39ac98da16ffc8c24d601353f69", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "fc38104235ab6cf8a448a74405aa258804ef4e36", + "rev": "954dbc9873f3b4534dc9896604593406d0383520", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "92564e5770e4d09f2d86dfbf8ada1e9c715b384c", + "rev": "406ebb8c8e2f7e852a1b47764b42494022ce652c", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.31.0", + "inputRev": "v4.32.0-rc1", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lean-toolchain b/lean-toolchain index 18640c8b066b18..2694eb767c1d5d 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.31.0 +leanprover/lean4:v4.32.0-rc1 diff --git a/scripts/create_deprecated_modules.lean b/scripts/create_deprecated_modules.lean index 31705550029ad0..92138e86c56e5d 100644 --- a/scripts/create_deprecated_modules.lean +++ b/scripts/create_deprecated_modules.lean @@ -85,7 +85,7 @@ def mkDeprecationWithDate (date : String) def mkDeprecation (customMessage : Option String := some "Auto-generated deprecation") : CommandElabM Format := do -- Get the current date in UTC: we don't want this to depend on the user computer's time zone. - let date := s!"{(← Std.Time.DateTime.now (tz := .UTC)).toPlainDate}" + let date := s!"{(Std.Time.DateTime.ofTimestamp (← Std.Time.Timestamp.now) .UTC).toPlainDate}" mkDeprecationWithDate date customMessage /-- diff --git a/scripts/lint-style.lean b/scripts/lint-style.lean index 727dcd1c7dd608..693913299410b9 100644 --- a/scripts/lint-style.lean +++ b/scripts/lint-style.lean @@ -54,7 +54,7 @@ instance : ToExpr LinterSets := inferInstanceAs <| ToExpr (NameMap _) /-- Return the linter sets defined at this point of elaborating the current file. -/ elab "linter_sets%" : term => do - return toExpr <| linterSetsExt.getState (← getEnv) + return toExpr <| (linterSetsExt.getState (← getEnv)).merged end LinterSetsElab diff --git a/scripts/mk_all.lean b/scripts/mk_all.lean index 4e3e0125670610..cbd76c092b401e 100644 --- a/scripts/mk_all.lean +++ b/scripts/mk_all.lean @@ -52,7 +52,7 @@ def mkAllCLI (args : Parsed) : IO UInt32 := do -- If the package is `mathlib`, then it removes the libraries `Cache` and `MathlibTest` and it -- adds `Mathlib/Tactic`. let libs := ← match args.flag? "lib" with - | some lib => return #[lib.as! String] + | some lib => pure #[lib.as! String] | none => getLeanLibs let mut updates := 0 for d in libs.reverse do -- reverse to create `Mathlib/Tactic.lean` before `Mathlib.lean` From 331ad87c32e76aca427277165a0855bd2bbc925d Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Fri, 19 Jun 2026 00:58:00 +0000 Subject: [PATCH 0161/1300] feat(Analysis): Taylor's theorem with the integral remainder (#31176) Prove Taylor's theorem with the integral remainder in higher dimensions. --- Mathlib.lean | 1 + .../Calculus/ContDiff/FTaylorSeries.lean | 9 ++ Mathlib/Analysis/Calculus/TaylorIntegral.lean | 139 ++++++++++++++++++ docs/100.yaml | 1 + docs/undergrad.yaml | 2 +- 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Analysis/Calculus/TaylorIntegral.lean diff --git a/Mathlib.lean b/Mathlib.lean index 73d920207c69ad..066f7d79c13745 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1843,6 +1843,7 @@ public import Mathlib.Analysis.Calculus.TangentCone.ProperSpace public import Mathlib.Analysis.Calculus.TangentCone.Real public import Mathlib.Analysis.Calculus.TangentCone.Seq public import Mathlib.Analysis.Calculus.Taylor +public import Mathlib.Analysis.Calculus.TaylorIntegral public import Mathlib.Analysis.Calculus.UniformLimitsDeriv public import Mathlib.Analysis.Calculus.VectorField public import Mathlib.Analysis.Complex.AbelLimit diff --git a/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean b/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean index 53ded4d8e91d6e..084664a10b855d 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Calculus.FDeriv.Add public import Mathlib.Analysis.Calculus.FDeriv.Equiv +public import Mathlib.Analysis.Calculus.FDeriv.CompCLM public import Mathlib.Analysis.Calculus.FormalMultilinearSeries public import Mathlib.Data.ENat.Lattice @@ -829,6 +830,14 @@ theorem iteratedFDeriv_succ_apply_left {n : ℕ} (m : Fin (n + 1) → E) : (fderiv 𝕜 (iteratedFDeriv 𝕜 n f) x : E → E [×n]→L[𝕜] F) (m 0) (tail m) := rfl +/-- The iterated derivative is given by the derivative of the `n-1` iterated derivative. -/ +theorem DifferentiableAt.iteratedFDeriv_succ_apply_left' {n : ℕ} {m : Fin (n + 1) → E} + (hf : DifferentiableAt 𝕜 (iteratedFDeriv 𝕜 n f) x) : + iteratedFDeriv 𝕜 (n + 1) f x m = + fderiv 𝕜 (fun y ↦ iteratedFDeriv 𝕜 n f y (Fin.tail m)) x (m 0) := by + convert iteratedFDeriv_succ_apply_left m + simp [fderiv_continuousMultilinear_apply_const hf] + /-- Writing explicitly the `n+1`-th derivative as the composition of a currying linear equiv, and the derivative of the `n`-th derivative. -/ theorem iteratedFDeriv_succ_eq_comp_left {n : ℕ} : diff --git a/Mathlib/Analysis/Calculus/TaylorIntegral.lean b/Mathlib/Analysis/Calculus/TaylorIntegral.lean new file mode 100644 index 00000000000000..cfec073db45c76 --- /dev/null +++ b/Mathlib/Analysis/Calculus/TaylorIntegral.lean @@ -0,0 +1,139 @@ +/- +Copyright (c) 2025 Moritz Doll. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Moritz Doll +-/ +module + +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.IntegrationByParts +public import Mathlib.Analysis.Calculus.ContDiff.Basic +public import Mathlib.Analysis.Calculus.Deriv.Pow +public import Mathlib.Analysis.Calculus.IteratedDeriv.Defs + +/-! +# Taylor's formula with an integral remainder in higher dimensions + +In this file we prove Taylor's formula with the remainder term in integral form. + +* `map_add_eq_sum_add_integral_iteratedFDeriv`: version for higher dimensions with `iteratedFDeriv` + +TODO: add a version that assumes `ContDiffOn f (closedBall x (‖y‖))` + +-/ + +@[expose] public section + +open Nat + +variable {𝕜 E F : Type*} +variable [NormedAddCommGroup E] [NormedAddCommGroup F] + +section NontriviallyNormedField + +variable [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 E] [NormedSpace 𝕜 F] + +variable {f : E → F} {x y : E} {t : 𝕜} {n : ℕ} + +theorem DifferentiableAt.deriv_comp_add_smul (hf : DifferentiableAt 𝕜 f (x + t • y)) : + deriv (fun (s : 𝕜) ↦ f (x + s • y)) t = fderiv 𝕜 f (x + t • y) y := by + have hg : Differentiable 𝕜 (fun (s : 𝕜) ↦ (x + s • y)) := by fun_prop + convert fderiv_comp_deriv t hf hg.differentiableAt + · simp + · simpa using (deriv_smul_const (x := t) differentiableAt_id y).symm + +theorem ContDiffAt.deriv_fderiv_add_smul (hf : ContDiffAt 𝕜 (n + 1) f (x + t • y)) : + deriv (fun (s : 𝕜) ↦ iteratedFDeriv 𝕜 n f (x + s • y) (fun _ ↦ y)) t = + iteratedFDeriv 𝕜 (n + 1) f (x + t • y) (fun _ ↦ y) := by + have hf' : DifferentiableAt 𝕜 (iteratedFDeriv 𝕜 n f) (x + t • y) := by + apply hf.differentiableAt_iteratedFDeriv + norm_cast + exact lt_add_one n + convert (hf'.continuousMultilinear_apply_const _).deriv_comp_add_smul + exact hf'.iteratedFDeriv_succ_apply_left' + +end NontriviallyNormedField + +variable [NormedSpace ℝ E] [NormedSpace ℝ F] + +variable {f : E → F} {x y : E} {n : ℕ} + +variable [CompleteSpace F] + +/-- *Taylor's theorem with remainder in integral form*. If `f` is `n + 1` times continuously +differentiable, then `f (x + y)` is given by +`∑ k in 0..n, D^k f(x; y,..,y) / k! + 1/n! ∫ t in 0..1, (1 - t) ^ n • D^{n+1}f (x + t • y; y,..,y)`, +where `D^k f` denotes the iterated derivative of `f`. + +In the case that `n = 1`, this is a reformulation of the fundamental theorem of calculus, namely +`f (x + y) = f x + ∫ t in 0..1, D f(x + t • y; y)`. -/ +theorem map_add_eq_sum_add_integral_iteratedFDeriv (hf : ∀ (t : ℝ) (_ht : t ∈ Set.Icc 0 1), + ContDiffAt ℝ (n + 1) f (x + t • y)) : + f (x + y) = ∑ k ∈ Finset.range (n + 1), (k ! : ℝ)⁻¹ • (iteratedFDeriv ℝ k f x (fun _ ↦ y)) + + (n ! : ℝ)⁻¹ • ∫ t in 0..1, (1 - t)^n • iteratedFDeriv ℝ (n + 1) f (x + t • y) (fun _ ↦ y) := by + simp_rw [← Set.uIcc_of_le zero_le_one] at hf + induction n with + | zero => + -- The base case follows from the fundamental theorem of calculus + have h_eq : Set.EqOn (fun t ↦ (fderiv ℝ f (x + t • y)) y) (deriv fun (s : ℝ) ↦ f (x + s • y)) + (Set.uIcc 0 1) := by + intro t ht + rw [DifferentiableAt.deriv_comp_add_smul] + exact (hf t ht).differentiableAt (by simp) + simp only [zero_add, Finset.range_one, Finset.sum_singleton, factorial_zero, cast_one, inv_one, + iteratedFDeriv_zero_apply, one_smul, pow_zero, reduceAdd, iteratedFDeriv_one_apply] + rw [← sub_eq_iff_eq_add', Eq.comm, intervalIntegral.integral_congr h_eq] + have hf' : ∀ (t : ℝ) (ht : t ∈ Set.uIcc 0 1), DifferentiableAt ℝ (fun s ↦ f (x + s • y)) t := + fun t ht ↦ ((hf t ht).differentiableAt (by simp)).comp t (by fun_prop) + have hint : IntervalIntegrable (deriv (fun s ↦ f (x + s • y))) MeasureTheory.volume 0 1 := by + have h₁ : ContinuousOn (fderiv ℝ f) ((fun t ↦ x + t • y) '' Set.uIcc (0 : ℝ) 1) := by + intro z ⟨t, ht, hz⟩ + rw [← hz] + exact (((hf t ht).fderiv_right (le_refl _)).continuousAt (n := 0)).continuousWithinAt + have h₂ : ContinuousOn (fun x_1 ↦ fderiv ℝ f (x + x_1 • y)) (Set.uIcc (0 : ℝ) 1) := by + apply h₁.comp (t := (fun t ↦ x + t • y) '' (Set.uIcc (0 : ℝ) 1)) (by fun_prop) + intro t ht + use t + apply (ContinuousOn.congr _ h_eq.symm).intervalIntegrable + fun_prop + simpa using intervalIntegral.integral_deriv_eq_sub hf' hint + | succ n ih => + -- We use the inductive hypothesis to cancel all lower order terms + specialize ih (fun t ht ↦ (hf t ht).of_le (by simp)) + rw [Finset.sum_range_succ, add_assoc] + convert ih using 2 + -- We define the functions u and v that we will integrate by parts + set u := fun (k : ℕ) (t : ℝ) ↦ (k ! : ℝ)⁻¹ * (1 - t) ^ k + have hu : ∀ (t : ℝ), HasDerivAt (u (n + 1)) (-u n t) t := by + intro t + unfold u + have : (-((n ! : ℝ)⁻¹ * (1 - t) ^ n)) = + ((n + 1) ! : ℝ)⁻¹ * ((n + 1) * (1 - t) ^ n * (-1)) := by + field_simp + congr 1 + rw [Nat.factorial_succ] + grind + rw [this] + apply HasDerivAt.const_mul + convert ((hasDerivAt_id t).const_sub 1).pow (n + 1) + all_goals norm_cast + have hu' : Continuous (u n) := by fun_prop + set v := fun (k : ℕ) (t : ℝ) ↦ iteratedFDeriv ℝ k f (x + t • y) (fun _ ↦ y) + have hv : ∀ (t : ℝ) (ht : t ∈ Set.uIcc 0 1), HasDerivAt (v (n + 1)) (v (n + 1 + 1) t) t := by + intro t ht + unfold v + rw [← (hf t ht).deriv_fderiv_add_smul] + have h_diff : DifferentiableAt ℝ (iteratedFDeriv ℝ (n + 1) f) (x + t • y) := by + apply (hf t ht).differentiableAt_iteratedFDeriv + norm_cast + grind + refine DifferentiableAt.hasDerivAt ?_ + fun_prop + have hv' : ContinuousOn (v (n + 1 + 1)) (Set.uIcc 0 1) := by + intro t ht + have h_cont : ContinuousAt (iteratedFDeriv ℝ (n + 1 + 1) f) (x + t • y) := + ((hf t ht).iteratedFDeriv_right (i := n + 1 + 1) (m := 0) (by simp)).continuousAt + exact (h_cont.comp (x := t) (by fun_prop)).continuousWithinAt.eval_const _ + -- Now we apply integration by parts and simplify + simpa [← eq_neg_add_iff_add_eq, ← intervalIntegral.integral_smul, smul_smul, u, v] using + intervalIntegral.integral_smul_deriv_eq_deriv_smul (fun t _ ↦ hu t) hv + (hu'.neg.intervalIntegrable _ _) hv'.intervalIntegrable diff --git a/docs/100.yaml b/docs/100.yaml index 84f6227e311369..17a09b6ceb64c1 100644 --- a/docs/100.yaml +++ b/docs/100.yaml @@ -146,6 +146,7 @@ decls : - taylor_mean_remainder_lagrange - taylor_mean_remainder_cauchy + - map_add_eq_sum_add_integral_iteratedFDeriv authors: Moritz Doll 36: title : Brouwer Fixed Point Theorem diff --git a/docs/undergrad.yaml b/docs/undergrad.yaml index 710b7695d179c4..9c97063d8ff3cb 100644 --- a/docs/undergrad.yaml +++ b/docs/undergrad.yaml @@ -466,7 +466,7 @@ Multivariable calculus: $k$-th order partial derivatives: '' partial derivatives commute: 'second_derivative_symmetric' Taylor's theorem with little-o remainder: '' - Taylor's theorem with integral form for remainder: '' + Taylor's theorem with integral form for remainder: 'map_add_eq_sum_add_integral_iteratedFDeriv' local extrema: 'IsLocalMin.fderiv_eq_zero' convexity of functions on an open convex subset of $\R^n$: 'ConvexOn' diffeomorphisms: 'Structomorph' From bbd0fbe5754c524969fd92429f849ae1f975a253 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 02:52:21 +0000 Subject: [PATCH 0162/1300] chore: update Mathlib dependencies 2026-06-19 (#40790) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 993ff072b9c621..83a478e0413ecb 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "954dbc9873f3b4534dc9896604593406d0383520", + "rev": "125807f43a86b5d58892b7ea6972eec0d6c164d2", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 39ca77e919f8582647530b35b8677c26fe679d1d Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Fri, 19 Jun 2026 03:50:53 +0000 Subject: [PATCH 0163/1300] doc(RingTheory): fix local ring doc comment (#39765) The predicate for local rings was updated to the current definition on non-commutative semirings back in mathlib3, but the outdated comment stating that local rings are commutative rings with a unique maximal ideal has not been updated since. --- Mathlib/RingTheory/LocalRing/Defs.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/RingTheory/LocalRing/Defs.lean b/Mathlib/RingTheory/LocalRing/Defs.lean index 211784be77b0d3..9538400b1f4589 100644 --- a/Mathlib/RingTheory/LocalRing/Defs.lean +++ b/Mathlib/RingTheory/LocalRing/Defs.lean @@ -12,14 +12,14 @@ public import Mathlib.Algebra.Ring.Defs # Local rings -Define local rings as commutative rings having a unique maximal ideal. +Define the notion of a local ring for non-commutative semirings. In the commutative case, +this is shown to be equivalent to the familiar definition that there exists a unique +maximal ideal in `IsLocalRing.of_unique_max_ideal` and `IsLocalRing.maximal_ideal_unique`. ## Main definitions * `IsLocalRing`: A predicate on semirings, stating that for any pair of elements that - adds up to `1`, one of them is a unit. In the commutative case this is shown to be equivalent - to the condition that there exists a unique maximal ideal, see - `IsLocalRing.of_unique_max_ideal` and `IsLocalRing.maximal_ideal_unique`. + adds up to `1`, one of them is a unit. -/ From 99e7e2c20b9c709ca1a32de2942db9cae7810a90 Mon Sep 17 00:00:00 2001 From: Jiedong Jiang <107380768+jjdishere@users.noreply.github.com> Date: Fri, 19 Jun 2026 05:50:18 +0000 Subject: [PATCH 0164/1300] chore(RingTheory/ValuativeRel): fix deprecation message of `ValueGroupWithZero.embed` (#40794) `embed` should be `orderMonoidIso`. --- Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 09454d77510d4b..26f6b4663daee7 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -1333,7 +1333,7 @@ lemma leftInverse_embedding_orderMonoidIso : Function.LeftInverse embedding embedding_orderMonoidIso_valuation_eq /-- The isomorphism between `ValueGroupWithZero R` and `ValueGroup₀ (valuation R)`. -/ -@[deprecated "use ValueGroupWithZero.embed (valuation R) instead" (since := "2026-03-17")] +@[deprecated "use ValueGroupWithZero.orderMonoidIso instead" (since := "2026-03-17")] def valueGroupWithZero_equiv_valueGroup₀ := orderMonoidIso (valuation R) end ValueGroupWithZero From e88fd8b40bb0b42b10ad5875c5b5e8b70fa79bd3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 19 Jun 2026 06:21:24 +0000 Subject: [PATCH 0165/1300] chore: remove two superfluous `IsManifold` hypotheses (#40786) --- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index 8d9f95219ccf58..a963ba00712ffb 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -324,7 +324,7 @@ theorem contMDiffAt_iff_source : section IsManifold theorem contMDiffWithinAt_iff_source_of_mem_maximalAtlas - [IsManifold I n M] (he : e ∈ maximalAtlas I n M) (hx : x ∈ e.source) : + (he : e ∈ maximalAtlas I n M) (hx : x ∈ e.source) : ContMDiffWithinAt I I' n f s x ↔ ContMDiffWithinAt 𝓘(𝕜, E) I' n (f ∘ (e.extend I).symm) ((e.extend I).symm ⁻¹' s ∩ range I) (e.extend I x) := by @@ -505,8 +505,7 @@ theorem contMDiffOn_iff [IsManifold I n M] [IsManifold I' n M'] : mfld_set_tac /-- zero-smoothness on a set is equivalent to continuity on this set. -/ -theorem contMDiffOn_zero_iff : - ContMDiffOn I I' 0 f s ↔ ContinuousOn f s := by +theorem contMDiffOn_zero_iff : ContMDiffOn I I' 0 f s ↔ ContinuousOn f s := by rw [contMDiffOn_iff] refine ⟨fun h ↦ h.1, fun h ↦ ⟨h, ?_⟩⟩ intro x y @@ -713,7 +712,7 @@ protected theorem ContMDiffOn.contMDiffAt (h : ContMDiffOn I I' n f s) (hx : s ContMDiffAt I I' n f x := (h x (mem_of_mem_nhds hx)).contMDiffAt hx -theorem contMDiffOn_iff_source_of_mem_maximalAtlas [IsManifold I n M] +theorem contMDiffOn_iff_source_of_mem_maximalAtlas (he : e ∈ maximalAtlas I n M) (hs : s ⊆ e.source) : ContMDiffOn I I' n f s ↔ ContMDiffOn 𝓘(𝕜, E) I' n (f ∘ (e.extend I).symm) (e.extend I '' s) := by From 8b94556e352c04a3d23faa327a71e911cde53774 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Fri, 19 Jun 2026 07:45:10 +0000 Subject: [PATCH 0166/1300] chore(Analysis/TemperedDistribution): add coercion and fix existing one (#40094) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a missing coercion from Schwartz functions to `Lp` functions and changes the current coercion from `Lp` functions to tempered distributions from `CoeDep` to `CoeHead`. The second coercion can only appear at the head of a coercion chain, because `𝓢'(E, F)` can't infer the value of `p` or `μ`. --- Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean | 4 ++++ Mathlib/Analysis/Distribution/TemperedDistribution.lean | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean index bbd069ea784a13..8216465d129539 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean @@ -1312,6 +1312,10 @@ theorem memLp (f : 𝓢(E, F)) (p : ℝ≥0∞) (μ : Measure E := by volume_tac def toLp (f : 𝓢(E, F)) (p : ℝ≥0∞) (μ : Measure E := by volume_tac) [hμ : μ.HasTemperateGrowth] : Lp F p μ := (f.memLp p μ).toLp +instance instCoeToLp {p : ℝ≥0∞} {μ : Measure E} [hμ : μ.HasTemperateGrowth] : + Coe 𝓢(E, F) (Lp F p μ) where + coe := (SchwartzMap.toLp · p μ) + theorem coeFn_toLp (f : 𝓢(E, F)) (p : ℝ≥0∞) (μ : Measure E := by volume_tac) [hμ : μ.HasTemperateGrowth] : f.toLp p μ =ᵐ[μ] f := (f.memLp p μ).coeFn_toLp diff --git a/Mathlib/Analysis/Distribution/TemperedDistribution.lean b/Mathlib/Analysis/Distribution/TemperedDistribution.lean index 5be14c0e45ed36..871955ee5ae633 100644 --- a/Mathlib/Analysis/Distribution/TemperedDistribution.lean +++ b/Mathlib/Analysis/Distribution/TemperedDistribution.lean @@ -175,13 +175,14 @@ theorem toTemperedDistribution_apply {p : ℝ≥0∞} [hp : Fact (1 ≤ p)] (f : filter_upwards [g.coeFn_toLp (1 - p⁻¹)⁻¹ μ] with x hg rw [hg] -instance instCoeDep {p : ℝ≥0∞} [hp : Fact (1 ≤ p)] (f : Lp F p μ) : - CoeDep (Lp F p μ) f 𝓢'(E, F) where - coe := toTemperedDistribution f +/-- This coercion has to be a `CoeHead`, because `𝓢'(E, F)` can't infer the value of `p` or `μ`. -/ +instance instCoeToTemperedDistribution {p : ℝ≥0∞} [hp : Fact (1 ≤ p)] : + CoeHead (Lp F p μ) 𝓢'(E, F) where + coe := toTemperedDistribution @[simp] theorem toTemperedDistribution_toLp_eq [SecondCountableTopology E] {p : ℝ≥0∞} [hp : Fact (1 ≤ p)] - (f : 𝓢(E, F)) : ((f.toLp p μ) : 𝓢'(E, F)) = f.toTemperedDistributionCLM E F μ := by + (f : 𝓢(E, F)) : ((f : Lp F p μ) : 𝓢'(E, F)) = f.toTemperedDistributionCLM E F μ := by ext g simp only [Lp.toTemperedDistribution_apply, toTemperedDistributionCLM_apply_apply] apply integral_congr_ae From e41065ae98bda505946885a844b968856a096054 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Fri, 19 Jun 2026 08:44:23 +0000 Subject: [PATCH 0167/1300] chore: rename `TwoSidedIdeal.mk` (#40776) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since this is an implemention detail and doesn't match the docstring, let's give it a more explicit name. If we in future refactor `mk'` to be the real constructor (to generalize to semirings, for instance), then we can keep this new `ofRingCon` name for the conversion function. Zulip: [#mathlib4 > Two sided ideals and Ring congruences @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Two.20sided.20ideals.20and.20Ring.20congruences/near/604588344) --- Mathlib/LinearAlgebra/Matrix/Ideal.lean | 2 +- Mathlib/RingTheory/TwoSidedIdeal/Basic.lean | 18 +++++++++++++++--- Mathlib/RingTheory/TwoSidedIdeal/Kernel.lean | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Ideal.lean b/Mathlib/LinearAlgebra/Matrix/Ideal.lean index c3bc08418c5df5..1ed4a0c51d8756 100644 --- a/Mathlib/LinearAlgebra/Matrix/Ideal.lean +++ b/Mathlib/LinearAlgebra/Matrix/Ideal.lean @@ -261,7 +261,7 @@ theorem matrix_monotone : Monotone (matrix (R := R) n) := theorem matrix_strictMono_of_nonempty [h : Nonempty n] : StrictMono (matrix (R := R) n) := matrix_monotone n |>.strictMono_of_injective <| - .comp (fun _ _ => mk.inj) <| (RingCon.matrix_injective n).comp ringCon_injective + .comp (fun _ _ => ofRingCon.inj) <| (RingCon.matrix_injective n).comp ringCon_injective @[simp] theorem matrix_bot : (⊥ : TwoSidedIdeal R).matrix n = ⊥ := diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean index 543ded7a05f1ee..d9de6ad31362b3 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean @@ -36,7 +36,9 @@ A two-sided ideal of a ring `R` is a subset of `R` that contains `0` and is clos negation, and absorbs multiplication on both sides. -/ structure TwoSidedIdeal (R : Type*) [NonUnitalNonAssocRing R] where - /-- every two-sided-ideal is induced by a congruence relation on the ring. -/ + /-- In a ring, every two-sided ideal is induced by a ring congruence relation. -/ + ofRingCon :: + /-- The congruence relation induced by this ideal. -/ ringCon : RingCon R end definitions @@ -69,9 +71,19 @@ instance : PartialOrder (TwoSidedIdeal R) := .ofSetLike (TwoSidedIdeal R) R lemma mem_iff (x : R) : x ∈ I ↔ I.ringCon x 0 := Iff.rfl @[simp] -lemma mem_mk {x : R} {c : RingCon R} : x ∈ mk c ↔ c x 0 := Iff.rfl +lemma mem_ofRingCon {x : R} {c : RingCon R} : x ∈ ofRingCon c ↔ c x 0 := Iff.rfl @[simp, norm_cast] +lemma coe_ofRingCon {c : RingCon R} : (ofRingCon c : Set R) = {x | c x 0} := rfl + +/-- A deprecated alias for `ofRingCon`. -/ +@[deprecated mk (since := "2026-06-18")] +abbrev mk (c : RingCon R) : TwoSidedIdeal R := ofRingCon c + +@[deprecated mem_ofRingCon (since := "2026-06-18")] +lemma mem_mk {x : R} {c : RingCon R} : x ∈ mk c ↔ c x 0 := Iff.rfl + +@[deprecated coe_ofRingCon (since := "2026-06-18")] lemma coe_mk {c : RingCon R} : (mk c : Set R) = {x | c x 0} := rfl lemma rel_iff (x y : R) : I.ringCon x y ↔ x - y ∈ I := by @@ -95,7 +107,7 @@ lemma le_iff {I J : TwoSidedIdeal R} : I ≤ J ↔ (I : Set R) ⊆ (J : Set R) : @[simps apply symm_apply] def orderIsoRingCon : TwoSidedIdeal R ≃o RingCon R where toFun := TwoSidedIdeal.ringCon - invFun := .mk + invFun := ofRingCon map_rel_iff' {I J} := Iff.symm <| le_iff.trans ⟨fun h x y r => by rw [rel_iff] at r ⊢; exact h r, fun h x hx => by rw [SetLike.mem_coe, mem_iff] at hx ⊢; exact h hx⟩ diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Kernel.lean b/Mathlib/RingTheory/TwoSidedIdeal/Kernel.lean index ad1b1e4d90c2ef..bc366c492530f2 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Kernel.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Kernel.lean @@ -31,7 +31,8 @@ variable (f : F) The kernel of a ring homomorphism, as a two-sided ideal. -/ def ker : TwoSidedIdeal R := - .mk + .ofRingCon + -- TODO: use `RingCon.ker` { r := fun x y ↦ f x = f y iseqv := by constructor <;> aesop mul' := by intro; simp_all From 65e1648ab2084b2481bcb1ddce09c7d070a4d1d7 Mon Sep 17 00:00:00 2001 From: Bingyu Xia <71547343+BryceT233@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:20:31 +0000 Subject: [PATCH 0168/1300] feat(Algebra/Category/Ring): `IsLocalRing` for limits (#37008) This PR introduces theorems establishing that limits in `CommRingCat` (specifically pullbacks and equalizers) preserve local homomorphisms and `IsLocalRing` properties under suitable conditions. --- Mathlib.lean | 1 + .../Algebra/Category/Ring/Constructions.lean | 133 ++++++++++----- Mathlib/RingTheory/LocalRing/Pullback.lean | 153 ++++++++++++++++++ .../RingTheory/LocalRing/RingHom/Basic.lean | 13 +- 4 files changed, 254 insertions(+), 46 deletions(-) create mode 100644 Mathlib/RingTheory/LocalRing/Pullback.lean diff --git a/Mathlib.lean b/Mathlib.lean index 066f7d79c13745..347da5096894ef 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6713,6 +6713,7 @@ public import Mathlib.RingTheory.LocalRing.MaximalIdeal.Defs public import Mathlib.RingTheory.LocalRing.MaximalIdeal.Square public import Mathlib.RingTheory.LocalRing.Module public import Mathlib.RingTheory.LocalRing.NonLocalRing +public import Mathlib.RingTheory.LocalRing.Pullback public import Mathlib.RingTheory.LocalRing.Quotient public import Mathlib.RingTheory.LocalRing.ResidueField.Basic public import Mathlib.RingTheory.LocalRing.ResidueField.Defs diff --git a/Mathlib/Algebra/Category/Ring/Constructions.lean b/Mathlib/Algebra/Category/Ring/Constructions.lean index cf49ecd37cfa4a..ff793325838353 100644 --- a/Mathlib/Algebra/Category/Ring/Constructions.lean +++ b/Mathlib/Algebra/Category/Ring/Constructions.lean @@ -5,13 +5,17 @@ Authors: Andrew Yang -/ module -public import Mathlib.Algebra.Category.Ring.Colimits +public import Mathlib.Algebra.Category.Ring.Adjunctions public import Mathlib.Algebra.Category.Ring.Instances public import Mathlib.Algebra.Category.Ring.Limits public import Mathlib.CategoryTheory.Limits.Shapes.StrictInitial public import Mathlib.RingTheory.Localization.BaseChange public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.IsPullback.Basic +import Mathlib.RingTheory.FreeCommRing +import Mathlib.Algebra.Ring.Subring.Units +import Mathlib.CategoryTheory.Adjunction.Limits + /-! # Constructions of (co)limits in `CommRingCat` @@ -335,6 +339,53 @@ noncomputable def _root_.RingEquiv.piEquivPi (R : ι → Type u) [∀ i, CommRin end Pi +namespace Limits + +variable {J : Type u'} [SmallCategory J] (F : J ⥤ CommRingCat.{u}) {c : Cone F} + +set_option backward.isDefEq.respectTransparency false in +theorem isUnit_iff_forall_isUnit (hc : IsLimit c) (r : c.pt) : IsUnit r ↔ + ∀ (j : J), IsUnit (c.π.app j r) := by + refine ⟨fun h _ ↦ h.map _, fun h ↦ ?_⟩ + simp only [isUnit_iff_exists_inv] at h ⊢ + choose inv h_inv using h + have map_inv {j k : J} (f : j ⟶ k) : F.map f (inv j) = inv k := by + have h := congr(F.map f $(h_inv j)) + have : F.map f (c.π.app j r) = c.π.app k r := + DFunLike.congr_fun (congr(Hom.hom $(c.w f))) r + rw [map_mul, map_one, this] at h + rw [← mul_one (F.map f (inv j)), ← h_inv k, ← mul_assoc] + nth_rw 2 [mul_comm]; rw [h, one_mul] + let inv_r : Cone F := .mk (CommRingCat.of (FreeCommRing PUnit)) { + app j := ConcreteCategory.ofHom (FreeCommRing.lift (fun _ ↦ inv j)) + naturality j k f := by + ext1; change FreeCommRing.lift (fun _ => inv k) = _ + ext; simp [map_inv f] } + use hc.lift inv_r (FreeCommRing.of PUnit.unit) + refine Concrete.isLimit_ext _ hc _ _ fun j ↦ ?_ + rw [RingHom.map_mul, RingHom.map_one]; convert h_inv j + change (hc.lift inv_r ≫ c.π.app j) (FreeCommRing.of PUnit.unit) = inv j + rw [IsLimit.fac]; exact FreeCommRing.lift_of .. + +-- The assumption `hj` can be generalized to a zigzag-like assumption of finite steps. +theorem π_isLocalHom (hc : IsLimit c) (j : J) (hj : ∀ (x : c.pt), IsUnit (c.π.app j x) → + ∀ (i : J), ∃ (k : J) (f : i ⟶ k) (g : j ⟶ k), IsLocalHom (F.map f).hom ∧ + F.map f (c.π.app i x) = F.map g (c.π.app j x)) : + IsLocalHom (c.π.app j).hom := by + refine ⟨fun (x : c.pt) hx ↦ (?_ : IsUnit x)⟩ + rw [isUnit_iff_forall_isUnit F hc]; intro i + obtain ⟨k, f, g, lh, eq⟩ := hj x hx i + exact lh.map_nonunit _ (eq ▸ hx.map _) + +theorem isLocalRing (hc : IsLimit c) (j : J) [IsLocalRing (F.obj j)] + (hj : ∀ (x : c.pt), IsUnit (c.π.app j x) → ∀ (i : J), ∃ (k : J) (f : i ⟶ k) (g : j ⟶ k), + IsLocalHom (F.map f).hom ∧ F.map f (c.π.app i x) = F.map g (c.π.app j x)) : + IsLocalRing c.pt := by + have := π_isLocalHom F hc j hj + apply RingHom.domain_isLocalRing (c.π.app j).hom + +end Limits + section Equalizer variable {A B : CommRingCat.{u}} (f g : A ⟶ B) @@ -357,55 +408,44 @@ def equalizerForkIsLimit : IsLimit (equalizerFork f g) := by ext x exact Subtype.ext <| RingHom.congr_fun (congrArg Hom.hom hm) x -instance : IsLocalHom (equalizerFork f g).ι.hom := by - constructor - rintro ⟨a, h₁ : _ = _⟩ (⟨⟨x, y, h₃, h₄⟩, rfl : x = _⟩ : IsUnit a) - have : y ∈ RingHom.eqLocus f.hom g.hom := by - apply (f.hom.isUnit_map ⟨⟨x, y, h₃, h₄⟩, rfl⟩ : IsUnit (f x)).mul_left_inj.mp - conv_rhs => rw [h₁] - rw [← f.hom.map_mul, ← g.hom.map_mul, h₄, f.hom.map_one, g.hom.map_one] - rw [isUnit_iff_exists_inv] - exact ⟨⟨y, this⟩, Subtype.ext h₃⟩ - -@[instance] -theorem equalizer_ι_isLocalHom (F : WalkingParallelPair ⥤ CommRingCat.{u}) : - IsLocalHom (limit.π F WalkingParallelPair.zero).hom := by - have := limMap_π (diagramIsoParallelPair F).hom WalkingParallelPair.zero - rw [← IsIso.comp_inv_eq] at this - rw [← this] - rw [← limit.isoLimitCone_hom_π - ⟨_, - equalizerForkIsLimit (F.map WalkingParallelPairHom.left) - (F.map WalkingParallelPairHom.right)⟩ - WalkingParallelPair.zero] - change IsLocalHom ((lim.map _ ≫ _ ≫ (equalizerFork _ _).ι) ≫ _).hom - infer_instance +instance : IsLocalHom (equalizerFork f g).ι.hom := + inferInstanceAs <| IsLocalHom (f.hom.eqLocus g.hom).subtype -open CategoryTheory.Limits.WalkingParallelPair Opposite +open WalkingParallelPair WalkingParallelPairHom Opposite -open CategoryTheory.Limits.WalkingParallelPairHom +instance equalizer_ι_isLocalHom (F : WalkingParallelPair ⥤ CommRingCat.{u}) : + IsLocalHom (limit.π F WalkingParallelPair.zero).hom := by + refine Limits.π_isLocalHom _ (limit.isLimit _) zero fun x hx i ↦ ?_ + rcases i with _ | _ + · exact ⟨zero, 𝟙 _, 𝟙 _, inferInstance, by simp⟩ + · refine ⟨one, 𝟙 _, left, inferInstance, ?_⟩ + simp only [CategoryTheory.Functor.map_id, hom_id, limit.cone_x, limit.cone_π, RingHom.id_apply] + exact (limit.w_apply F left x).symm + +theorem equalizer_limit_isLocalRing (F : WalkingParallelPair ⥤ CommRingCat.{u}) + [IsLocalRing (F.obj zero)] : IsLocalRing ↑(limit F) := + RingHom.domain_isLocalRing (limit.π F WalkingParallelPair.zero).hom -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance equalizer_ι_isLocalHom' (F : WalkingParallelPairᵒᵖ ⥤ CommRingCat.{u}) : - IsLocalHom (limit.π F (Opposite.op WalkingParallelPair.one)).hom := by - have := limit.isoLimitCone_inv_π - ⟨_, IsLimit.whiskerEquivalence (limit.isLimit F) walkingParallelPairOpEquiv⟩ - WalkingParallelPair.zero - dsimp at this - rw [← this] - -- note: this was not needed before https://github.com/leanprover-community/mathlib4/pull/19757 - have : IsLocalHom (limit.π (walkingParallelPairOp ⋙ F) zero).hom := by infer_instance - infer_instance + IsLocalHom (limit.π F (op one)).hom := by + refine Limits.π_isLocalHom _ (limit.isLimit _) (op one) fun x hx i ↦ ?_ + rcases i with _ | _ + · refine ⟨op zero, 𝟙 _, op left, inferInstance, ?_⟩ + simp only [CategoryTheory.Functor.map_id, hom_id, limit.cone_x, limit.cone_π, + RingHom.id_apply] + exact (limit.w_apply F (op left) x).symm + · exact ⟨op one, 𝟙 _, 𝟙 _, inferInstance, by simp⟩ end Equalizer section Pullback +variable {A B C : CommRingCat.{u}} + /-- In the category of `CommRingCat`, the pullback of `f : A ⟶ C` and `g : B ⟶ C` is the `eqLocus` of the two maps `A × B ⟶ C`. This is the constructed pullback cone. -/ -def pullbackCone {A B C : CommRingCat.{u}} (f : A ⟶ C) (g : B ⟶ C) : PullbackCone f g := +def pullbackCone (f : A ⟶ C) (g : B ⟶ C) : PullbackCone f g := PullbackCone.mk (CommRingCat.ofHom <| (RingHom.fst A B).comp @@ -418,7 +458,7 @@ def pullbackCone {A B C : CommRingCat.{u}} (f : A ⟶ C) (g : B ⟶ C) : Pullbac simpa [CommRingCat.ofHom] using e) /-- The constructed pullback cone is indeed the limit. -/ -def pullbackConeIsLimit {A B C : CommRingCat.{u}} (f : A ⟶ C) (g : B ⟶ C) : +def pullbackConeIsLimit (f : A ⟶ C) (g : B ⟶ C) : IsLimit (pullbackCone f g) := by fapply PullbackCone.IsLimit.mk · intro s @@ -439,6 +479,21 @@ def pullbackConeIsLimit {A B C : CommRingCat.{u}} (f : A ⟶ C) (g : B ⟶ C) : rw [← eq1, ← eq2] rfl +open WalkingCospan + +instance pullbackFst_isLocalHom (f : A ⟶ C) (g : B ⟶ C) [IsLocalHom g.hom] : + IsLocalHom (pullback.fst f g).hom := by + refine Limits.π_isLocalHom _ (limit.isLimit _) left fun x hx i ↦ ?_ + rcases i with _ | _ | _ + · exact ⟨one, 𝟙 _, Hom.inl, inferInstance, by simp; rfl⟩ + · exact ⟨left, 𝟙 _, 𝟙 _, inferInstance, by simp⟩ + · refine ⟨one, Hom.inr, Hom.inl, ‹_›, ?_⟩ + exact DFunLike.congr_fun (congr(Hom.hom $(pullback.condition (f := f) (g := g)))) x |>.symm + +theorem pullback_isLocalRing (f : A ⟶ C) (g : B ⟶ C) [IsLocalHom g.hom] [IsLocalRing A] : + IsLocalRing ↑(pullback f g) := + RingHom.domain_isLocalRing (pullback.fst f g).hom + end Pullback end CommRingCat diff --git a/Mathlib/RingTheory/LocalRing/Pullback.lean b/Mathlib/RingTheory/LocalRing/Pullback.lean new file mode 100644 index 00000000000000..544f6634a4a90c --- /dev/null +++ b/Mathlib/RingTheory/LocalRing/Pullback.lean @@ -0,0 +1,153 @@ +/- +Copyright (c) 2026 Bingyu Xia. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Bingyu Xia +-/ + +module + +public import Mathlib.Algebra.Torsor.Defs +public import Mathlib.RingTheory.LocalRing.MaximalIdeal.Basic + +import Mathlib.Algebra.Ring.Subring.Units +import Mathlib.RingTheory.LocalRing.RingHom.Basic + +/-! +# Local Ring Properties of Equalizers and Pullbacks + +In this file we provide basic lemmas for the equalizers the pullbacks and of ring homomorphisms +and algebra homomorphisms. We show that they preserve the property of being a local ring under +suitable conditions. + +## Main definitions + +* `RingHom.pullback`: The pullback of two ring homomorphisms `f : R →+* T` and `g : S →+* T`, + defined as the subring of `R × S` consisting of pairs `(r, s)` such that `f r = g s`. + +* `RingHom.pullbackFst`, `RingHom.pullbackSnd`: The canonical projection maps from the + pullback to `R` and `S`. + +## Main results + +* `RingHom.isLocalRing_eqLocus`: The equalizer of two ring homomorphisms from a local + ring is again a local ring. + +* `RingHom.isLocalRing_pullback`: The pullback of `f : R →+* T` and `g : S →+* T` is a + local ring, provided that `R` is a local ring and `g` is a local homomorphism. + +-/ + +@[expose] public section + +namespace RingHom + +variable {R S T : Type*} [Ring R] [Ring S] [Semiring T] + +theorem isLocalRing_eqLocus [IsLocalRing R] (f g : R →+* T) : IsLocalRing (f.eqLocus g) := + (f.eqLocus g).subtype.domain_isLocalRing + +/-- The subring of pairs `(r, s) : R × S` such that `f r = g s`, i.e., + the pullback of `f : R →+* T` and `g : S →+* T` as a subring of `R × S`. -/ +abbrev pullback (f : R →+* T) (g : S →+* T) : Subring (R × S) := + (f.comp (RingHom.fst R S)).eqLocus <| g.comp (RingHom.snd R S) + +/-- The first projection from the pullback of `f : R →+* T` and `g : S →+* T` to `R`. -/ +abbrev pullbackFst (f : R →+* T) (g : S →+* T) : f.pullback g →+* R := + (RingHom.fst R S).comp (RingHom.pullback f g).subtype + +/-- The second projection from the pullback of `f : R →+* T` and `g : S →+* T` to `S`. -/ +abbrev pullbackSnd (f : R →+* T) (g : S →+* T) : f.pullback g →+* S := + (RingHom.snd R S).comp (f.pullback g).subtype + +theorem pullback_comm_sq (f : R →+* T) (g : S →+* T) : + f.comp (f.pullbackFst g) = g.comp (f.pullbackSnd g) := + ext fun x ↦ x.prop + +theorem isUnit_pullback_mk_iff (f : R →+* T) (g : S →+* T) {a : R × S} (a_in : a ∈ f.pullback g) : + IsUnit (⟨a, a_in⟩ : f.pullback g) ↔ IsUnit a.1 ∧ IsUnit a.2 := by + rw [isUnit_eqLocus_mk_iff, Prod.isUnit_iff] + +instance isLocalHom_pullbackFst (f : R →+* T) (g : S →+* T) [IsLocalHom g] : + IsLocalHom (f.pullbackFst g) where + map_nonunit := fun ⟨⟨_, _⟩, h_in⟩ ha ↦ + (isUnit_pullback_mk_iff f g h_in).mpr ⟨ha, isUnit_of_map_unit g _ (h_in ▸ ha.map f)⟩ + +instance isLocalHom_pullbackSnd (f : R →+* T) (g : S →+* T) [IsLocalHom f] : + IsLocalHom (f.pullbackSnd g) where + map_nonunit := fun ⟨⟨_, _⟩, h_in⟩ ha ↦ + (isUnit_pullback_mk_iff f g h_in).mpr ⟨isUnit_of_map_unit f _ (h_in.symm ▸ ha.map g), ha⟩ + +theorem surjective_pullbackFst_of_surjective (f : R →+* T) (g : S →+* T) + (h : Function.Surjective g) : Function.Surjective (f.pullbackFst g) := + fun r ↦ by simpa [eq_comm] using h (f r) + +theorem surjective_pullbackSnd_of_surjective (f : R →+* T) (g : S →+* T) + (h : Function.Surjective f) : Function.Surjective (f.pullbackSnd g) := + fun s ↦ by simpa [eq_comm] using h (g s) + +theorem map_pullbackSnd_ker_pullbackFst_eq (f : R →+* T) (g : S →+* T) : + Ideal.map (f.pullbackSnd g) (RingHom.ker (f.pullbackFst g)) = RingHom.ker g := by + apply le_antisymm + · rw [Ideal.map_le_iff_le_comap] + rintro ⟨⟨_, _⟩, h⟩ + simp at h ⊢; grind + · intro s hs + exact Ideal.mem_map_of_mem (f.pullbackSnd g) (x := ⟨(0, s), by simpa using hs.symm⟩) + (I := RingHom.ker (f.pullbackFst g)) (by simp) + +theorem isLocalRing_pullback [IsLocalRing R] (f : R →+* T) (g : S →+* T) [IsLocalHom g] : + IsLocalRing (f.pullback g) := (f.pullbackFst g).domain_isLocalRing + +end RingHom + +namespace AlgHom + +variable {R A B C : Type*} [CommSemiring R] + +section Semiring + +variable [Semiring A] [Algebra R A] [Semiring B] [Algebra R B] [Semiring C] [Algebra R C] + +/-- The subalgebra of pairs `(a, b) : A × B` such that `f a = g b`, i.e., + the pullback of f and g as a subalgebra of A × B. -/ +abbrev pullback (f : A →ₐ[R] C) (g : B →ₐ[R] C) : Subalgebra R (A × B) := equalizer + (f.comp (fst R A B)) (g.comp (snd R A B)) + +/-- The first projection from the pullback of `f` and `g` to `A`. -/ +abbrev pullbackFst (f : A →ₐ[R] C) (g : B →ₐ[R] C) : pullback f g →ₐ[R] A := + (fst R A B).comp (pullback f g).val + +/-- The second projection from the pullback of `f` and `g` to `B`. -/ +abbrev pullbackSnd (f : A →ₐ[R] C) (g : B →ₐ[R] C) : pullback f g →ₐ[R] B := + (snd R A B).comp (pullback f g).val + +theorem pullback_comm_sq (f : A →ₐ[R] C) (g : B →ₐ[R] C) : + f.comp (pullbackFst f g) = g.comp (pullbackSnd f g) := + AlgHom.ext fun x ↦ x.prop + +end Semiring + +section Ring + +variable [Ring A] [Algebra R A] [Ring B] [Algebra R B] [Semiring C] [Algebra R C] + +theorem isUnit_pullback_mk_iff (f : A →ₐ[R] C) (g : B →ₐ[R] C) {a : A × B} + (a_in : a ∈ f.pullback g) : IsUnit (⟨a, a_in⟩ : f.pullback g) ↔ + IsUnit a.1 ∧ IsUnit a.2 := + RingHom.isUnit_pullback_mk_iff (f : A →+* C) (g : B →+* C) a_in + +theorem surjective_pullbackFst_of_surjective (f : A →ₐ[R] C) (g : B →ₐ[R] C) + (h : Function.Surjective g) : Function.Surjective (pullbackFst f g) := + RingHom.surjective_pullbackFst_of_surjective (f : A →+* C) (g : B →+* C) h + +theorem surjective_pullbackSnd_of_surjective (f : A →ₐ[R] C) (g : B →ₐ[R] C) + (h : Function.Surjective f) : Function.Surjective (pullbackSnd f g) := + RingHom.surjective_pullbackSnd_of_surjective (f : A →+* C) (g : B →+* C) h + +theorem isLocalRing_pullback [IsLocalRing A] (f : A →ₐ[R] C) (g : B →ₐ[R] C) + [IsLocalHom g] : IsLocalRing (f.pullback g) := + RingHom.isLocalRing_pullback (f : A →+* C) (g : B →+* C) + +end Ring + +end AlgHom diff --git a/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean b/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean index 1ab85fd57885fd..deeaae7fdb0531 100644 --- a/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean @@ -45,13 +45,12 @@ theorem isLocalHom_of_comp (f : R →+* S) (g : S →+* T) [IsLocalHom (g.comp f ⟨fun _ ha => (isUnit_map_iff (g.comp f) _).mp (g.isUnit_map ha)⟩ /-- If `f : R →+* S` is a local ring hom, then `R` is a local ring if `S` is. -/ -theorem RingHom.domain_isLocalRing {R S : Type*} [Semiring R] [CommSemiring S] [IsLocalRing S] - (f : R →+* S) [IsLocalHom f] : IsLocalRing R := by - haveI : Nontrivial R := f.domain_nontrivial - apply IsLocalRing.of_nonunits_add - intro a b - simp_rw [← map_mem_nonunits_iff f, f.map_add] - exact IsLocalRing.nonunits_add +theorem RingHom.domain_isLocalRing [IsLocalRing S] (f : R →+* S) [IsLocalHom f] : + IsLocalRing R where + toNontrivial := f.domain_nontrivial + isUnit_or_isUnit_of_add_one {a b} h := Or.imp + (isUnit_of_map_unit f a) (isUnit_of_map_unit f b) + (IsLocalRing.isUnit_or_isUnit_of_add_one (by rw [← map_add, h, map_one])) end From 189bef07b6d8ba64b925c62349afaa70be7b14b3 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:20:33 +0000 Subject: [PATCH 0169/1300] feat: more lemmas about `{Setoid,Con,AddCon,RingCon}.comap` (#40697) --- Mathlib/Data/Setoid/Basic.lean | 60 +++++++++++++++++++++-- Mathlib/GroupTheory/Congruence/Basic.lean | 55 +++++++-------------- Mathlib/GroupTheory/Congruence/Defs.lean | 17 +++++++ Mathlib/RingTheory/Congruence/Basic.lean | 36 ++++++++++++-- Mathlib/RingTheory/Congruence/Defs.lean | 20 ++++++++ 5 files changed, 145 insertions(+), 43 deletions(-) diff --git a/Mathlib/Data/Setoid/Basic.lean b/Mathlib/Data/Setoid/Basic.lean index 0547b8285f1049..29e735ede15619 100644 --- a/Mathlib/Data/Setoid/Basic.lean +++ b/Mathlib/Data/Setoid/Basic.lean @@ -38,7 +38,7 @@ attribute [refl, simp] Setoid.refl attribute [symm] Setoid.symm attribute [trans] Setoid.trans -variable {α : Type*} {β : Type*} +variable {α β γ : Type*} namespace Setoid @@ -55,6 +55,8 @@ instance : LE (Setoid α) := theorem le_def {r s : Setoid α} : r ≤ s ↔ ∀ {x y}, r x y → s x y := Iff.rfl +theorem le_iff_rel_le {r₁ r₂ : Setoid α} : r₁ ≤ r₂ ↔ ⇑r₁ ≤ ⇑r₂ := Iff.rfl + @[refl] theorem refl' (r : Setoid α) (x) : r x x := r.iseqv.refl x @@ -189,11 +191,11 @@ instance completeLattice : CompleteLattice (Setoid α) := bot := ⟨(· = ·), ⟨fun _ => rfl, fun h => h.symm, fun h1 h2 => h1.trans h2⟩⟩ bot_le := fun r x _ h => h ▸ r.2.1 x } -@[simp] +@[simp, grind =] theorem top_def : ⇑(⊤ : Setoid α) = ⊤ := rfl -@[simp] +@[simp, grind =] theorem bot_def : ⇑(⊥ : Setoid α) = (· = ·) := rfl @@ -207,6 +209,9 @@ theorem eq_top_iff {s : Setoid α} : s = (⊤ : Setoid α) ↔ ∀ x y : α, s x rw [_root_.eq_top_iff, Setoid.le_def, Setoid.top_def] simp only [Pi.top_apply, Prop.top_eq_true, forall_true_left] +@[simp] +theorem ker_eq_bot_iff {f : α → β} : ker f = ⊥ ↔ f.Injective := le_bot_iff.symm + lemma sInf_equiv {S : Set (Setoid α)} {x y : α} : letI := sInf S x ≈ y ↔ ∀ s ∈ S, s x y := Iff.rfl @@ -401,6 +406,21 @@ related to the elements of `f⁻¹(y)` by `r`.' -/ def map (r : Setoid α) (f : α → β) : Setoid β := Relation.EqvGen.setoid (Relation.Map r f f) +theorem coe_map_of_ker_le (r : Setoid α) (f : α → β) (hf : ker f ≤ r) : + ⇑(map r f) = Relation.Map r f f ⊔ (· = ·) := by + refine le_antisymm ?_ (sup_le Relation.EqvGen.rel (by rintro _ _ rfl; exact .refl _)) + rintro _ _ hxy + induction hxy with + | rel _ _ hab => exact .inl hab + | refl _ => exact .inr rfl + | symm _ _ _ ih => exact ih.imp (Std.Symm.symm _ _) (Std.Symm.symm _ _) + | trans _ _ _ _ _ ih1 ih2 => + rcases ih1 with ih1 | rfl + · rcases ih2 with ih2 | rfl + · exact .inl <| r.iseqv.isTrans.map hf |>.trans _ _ _ ih1 ih2 + · exact .inl ih1 + · exact ih2 + /-- Given a surjective function f whose kernel is contained in an equivalence relation r, the equivalence relation on f's codomain defined by x ≈ y ↔ the elements of f⁻¹(x) are related to the elements of f⁻¹(y) by r. -/ @@ -420,6 +440,9 @@ See note [reducible non-instances]. -/ abbrev comap (f : α → β) (r : Setoid β) : Setoid α := ⟨r on f, r.iseqv.comap _⟩ +theorem comap_rel_eq (f : α → β) (r : Setoid β) : ⇑(comap f r) = (⇑r on f) := + rfl + theorem comap_rel (f : α → β) (r : Setoid β) (x y : α) : comap f r x y ↔ r (f x) (f y) := Iff.rfl @@ -428,6 +451,37 @@ induced on `α` by `f` equals the kernel of `r`'s quotient map composed with `f` theorem comap_eq {f : α → β} {r : Setoid β} : comap f r = ker (@Quotient.mk'' _ r ∘ f) := ext fun x y => show _ ↔ ⟦_⟧ = ⟦_⟧ by rw [Quotient.eq]; rfl +@[simp] +theorem comap_id (c : Setoid α) : c.comap id = c := rfl + +@[simp] +theorem comap_comp (c : Setoid γ) (g : β → γ) (f : α → β) : c.comap (g ∘ f) = (c.comap g).comap f := + rfl + +theorem comap_injective (f : α → β) (hf : Function.Surjective f) : + Function.Injective (comap f) := + fun _ _ h => ext <| hf.forall₂.2 <| Setoid.ext_iff.1 h + +theorem le_comap_map {r : Setoid α} {f : α → β} : r ≤ comap f (r.map f) := + fun _ _ h => Relation.EqvGen.rel _ _ ⟨_, _, h, rfl, rfl⟩ + +theorem comap_map_of_ker_le (f : α → β) (r : Setoid α) (hf : ker f ≤ r) : + comap f (r.map f) = r := by + apply le_antisymm _ le_comap_map + rw [le_iff_rel_le, comap_rel_eq, coe_map_of_ker_le _ _ hf] + rintro x y (⟨a, b, h, ha, hb⟩ | h) + · replace ha := hf ha + replace hb := hf hb + exact trans (symm ha) (trans h hb) + · exact hf h + +theorem comap_map_eq (f : α → β) (r : Setoid α) (hf : f.Injective) : comap f (r.map f) = r := + comap_map_of_ker_le f r <| ker_eq_bot_iff.2 hf ▸ bot_le + +theorem comap_surjective (f : α → β) (hf : Function.Injective f) : + Function.Surjective (Setoid.comap f) := + fun r => ⟨_, comap_map_eq f r hf⟩ + /-- The second isomorphism theorem for sets. -/ noncomputable def comapQuotientEquiv (f : α → β) (r : Setoid β) : Quotient (comap f r) ≃ Set.range (@Quotient.mk'' _ r ∘ f) := diff --git a/Mathlib/GroupTheory/Congruence/Basic.lean b/Mathlib/GroupTheory/Congruence/Basic.lean index 407821655bdedd..3700a2bd93fbdf 100644 --- a/Mathlib/GroupTheory/Congruence/Basic.lean +++ b/Mathlib/GroupTheory/Congruence/Basic.lean @@ -75,48 +75,29 @@ protected def congr {c d : Con M} (h : c = d) : c.Quotient ≃* d.Quotient := theorem congr_mk {c d : Con M} (h : c = d) (a : M) : Con.congr h (a : c.Quotient) = (a : d.Quotient) := rfl -@[to_additive] -theorem le_comap_conGen {M N : Type*} [Mul M] [Mul N] (f : M → N) - (H : ∀ (x y : M), f (x * y) = f x * f y) (rel : N → N → Prop) : - conGen (fun x y ↦ rel (f x) (f y)) ≤ Con.comap f H (conGen rel) := by - intro x y h - simp only [Con.comap_rel] - exact .rec (fun x y h ↦ .of (f x) (f y) h) (fun x ↦ .refl (f x)) - (fun _ h ↦ .symm h) (fun _ _ h1 h2 ↦ h1.trans h2) (fun {w x y z} _ _ h1 h2 ↦ - (congrArg (fun a ↦ conGen rel a (f (x * z))) (H w y)).mpr - (((congrArg (fun a ↦ conGen rel (f w * f y) a) (H x z))).mpr - (.mul h1 h2))) h - @[to_additive] theorem comap_conGen_equiv {M N : Type*} [Mul M] [Mul N] (f : MulEquiv M N) (rel : N → N → Prop) : Con.comap f (map_mul f) (conGen rel) = conGen (fun x y ↦ rel (f x) (f y)) := by - apply le_antisymm _ (le_comap_conGen f (map_mul f) rel) + apply le_antisymm _ (le_comap_conGen rel f (map_mul f)) intro a b h simp only [Con.comap_rel] at h - have H : ∀ n1 n2, (conGen rel) n1 n2 → ∀ a b, f a = n1 → f b = n2 → - (conGen fun x y ↦ rel (f x) (f y)) a b := by - intro n1 n2 h - induction h with - | of x y h => - intro _ _ fa fb - apply ConGen.Rel.of - rwa [fa, fb] - | refl x => - intro _ _ fc fd - rw [f.injective (fc.trans fd.symm)] - exact ConGen.Rel.refl _ - | symm _ h => exact fun a b fs fb ↦ ConGen.Rel.symm (h b a fb fs) - | trans _ _ ih ih1 => - exact fun a b fa fb ↦ Exists.casesOn (f.surjective _) fun c' hc' ↦ - ConGen.Rel.trans (ih a c' fa hc') (ih1 c' b hc' fb) - | mul _ _ ih ih1 => - rename_i w x y z _ _ - intro a b fa fb - rw [← f.eq_symm_apply, map_mul] at fa fb - rw [fa, fb] - exact ConGen.Rel.mul (ih (f.symm w) (f.symm x) (by simp) (by simp)) - (ih1 (f.symm y) (f.symm z) (by simp) (by simp)) - exact H (f a) (f b) h a b (refl _) (refl _) + unfold Function.onFun + generalize fa : f a = n1 at h + generalize fb : f b = n2 at h + induction h generalizing a b with + | of x y h => + apply ConGen.Rel.of + rwa [fa, fb] + | refl x => + rw [f.injective (fa.trans fb.symm)] + exact ConGen.Rel.refl _ + | symm _ h => exact ConGen.Rel.symm (h fb fa) + | trans _ _ ih ih1 => + exact Exists.casesOn (f.surjective _) fun c' hc' ↦ ConGen.Rel.trans (ih fa hc') (ih1 hc' fb) + | @mul w x y z _ _ ih ih1 => + rw [← f.eq_symm_apply, map_mul] at fa fb + rw [fa, fb] + exact ConGen.Rel.mul (ih (by simp) (by simp)) (ih1 (by simp) (by simp)) @[to_additive] theorem comap_conGen_of_bijective {M N : Type*} [Mul M] [Mul N] (f : M → N) diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index b47a3672e90a92..499a5e8086a810 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -517,6 +517,23 @@ theorem comap_rel {f : M → N} (H : ∀ x y, f (x * y) = f x * f y) {c : Con N} comap f H c x y ↔ c (f x) (f y) := Iff.rfl +@[to_additive (attr := simp)] +theorem comap_id (c : Con M) : c.comap id (by intros; rfl) = c := rfl + +@[to_additive (attr := simp)] +theorem comap_comp (c : Con P) (g : N → P) (f : M → N) (hg) (hf) : + c.comap (g ∘ f) (by grind) = (c.comap g hg).comap f hf := rfl + +@[to_additive] +theorem le_comap_conGen (r : N → N → Prop) (f : M → N) (hf) : + conGen (r.onFun f) ≤ (conGen r).comap f hf := + conGen_le.2 fun _ _ h => ConGen.Rel.of _ _ h + +@[to_additive] +theorem comap_injective (f : M → N) (hf : Function.Surjective f) (hf') : + Function.Injective (comap f hf') := + .of_comp (f := toSetoid) <| (Setoid.comap_injective f hf).comp toSetoid_injective + end section diff --git a/Mathlib/RingTheory/Congruence/Basic.lean b/Mathlib/RingTheory/Congruence/Basic.lean index 40ad52ee203bd3..43628cefaaa913 100644 --- a/Mathlib/RingTheory/Congruence/Basic.lean +++ b/Mathlib/RingTheory/Congruence/Basic.lean @@ -32,7 +32,7 @@ Most of the time you likely want to use the `Ideal.Quotient` API that is built o @[expose] public section -variable {α β R : Type*} +variable {α β R R' : Type*} namespace RingCon @@ -132,7 +132,7 @@ The API in this section is copied from `Mathlib/GroupTheory/Congruence/Defs.lean section Lattice -variable [Add R] [Mul R] {c d : RingCon R} +variable [Add R] [Mul R] [Add R'] [Mul R'] {c d : RingCon R} /-- For congruence relations `c, d` on a type `M` with multiplication and addition, `c ≤ d` iff `∀ x y ∈ M`, `x` is related to `y` by `d` if `x` is related to `y` by `c`. -/ @@ -143,7 +143,7 @@ instance : LE (RingCon R) where theorem le_def : c ≤ d ↔ ∀ {x y}, c x y → d x y := .rfl @[gcongr] -theorem comap_mono {R' : Type*} [Add R'] [Mul R'] +theorem comap_mono {F : Type*} [FunLike F R R'] [AddHomClass F R R'] [MulHomClass F R R'] {J J' : RingCon R'} {f : F} (h : J ≤ J') : J.comap f ≤ J'.comap f := @@ -326,6 +326,36 @@ theorem sSup_eq_ringConGen (S : Set (RingCon R)) : congr! with x y simp +open scoped Function + +theorem le_comap_ringConGen {F} [FunLike F R' R] [MulHomClass F R' R] [AddHomClass F R' R] + (r : R → R → Prop) (f : F) : + ringConGen (r on f) ≤ (ringConGen r).comap f := + ringConGen_le.2 fun _ _ h => RingConGen.Rel.of _ _ h + +theorem comap_injective {F} [FunLike F R' R] [MulHomClass F R' R] [AddHomClass F R' R] + (f : F) (hf : Function.Surjective f) : + Function.Injective (comap · f) := + .of_comp (f := toCon) <| (Con.comap_injective f hf <| map_mul f).comp toCon_injective + +theorem comap_ringConGen_ringEquiv {R R'} [NonAssocSemiring R] [NonAssocSemiring R'] + (r : R' → R' → Prop) (f : R ≃+* R') : + (ringConGen r).comap f = ringConGen (r on f) := by + refine le_antisymm ?_ (le_comap_ringConGen _ _) + trans (ringConGen (r on ⇑f) |>.comap f.symm.toNonUnitalRingHom).comap f.toNonUnitalRingHom + · apply comap_mono + grw [← le_comap_ringConGen] + gcongr + simp [Function.onFun, RingEquiv.coe_toNonUnitalRingHom'] + · rw [← comap_nonUnitalRingHomComp] + simp + +-- This one probably needs the RingCon version of `Setoid.comap_surjective` +proof_wanted comap_ringConGen_equiv + {F} [FunLike F R' R] [MulHomClass F R' R] [AddHomClass F R' R] [EquivLike F R' R] + (r : R → R → Prop) (f : F) : + (ringConGen r).comap f = ringConGen (r on f) + end Lattice end RingCon diff --git a/Mathlib/RingTheory/Congruence/Defs.lean b/Mathlib/RingTheory/Congruence/Defs.lean index 16f78f06af0245..1ef19c1e92172e 100644 --- a/Mathlib/RingTheory/Congruence/Defs.lean +++ b/Mathlib/RingTheory/Congruence/Defs.lean @@ -159,6 +159,26 @@ def comap (J : RingCon R') (f : F) : theorem comap_rel {J : RingCon R'} {f : F} {x y : R} : J.comap f x y ↔ J (f x) (f y) := Iff.rfl +@[simp] +theorem comap_nonUnitalRingHomId {R} [NonUnitalNonAssocSemiring R] (J : RingCon R) : + J.comap (NonUnitalRingHom.id _) = J := rfl + +@[simp] +theorem comap_nonUnitalRingHomComp {R R' R''} + [NonUnitalNonAssocSemiring R] [NonUnitalNonAssocSemiring R'] [NonUnitalNonAssocSemiring R''] + (J : RingCon R) (g : R' →ₙ+* R) (f : R'' →ₙ+* R') : + J.comap (g.comp f) = (J.comap g).comap f := rfl + +@[simp] +theorem comap_ringHomId {R} [NonAssocSemiring R] (J : RingCon R) : + J.comap (RingHom.id _) = J := rfl + +@[simp] +theorem comap_ringHomComp {R R' R''} + [NonAssocSemiring R] [NonAssocSemiring R'] [NonAssocSemiring R''] + (J : RingCon R) (g : R' →+* R) (f : R'' →+* R') : + J.comap (g.comp f) = (J.comap g).comap f := rfl + end Basic section Quotient From 7f9226b30ad3ed0a756b7acaaea3dd191d1e4089 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:05:48 +0000 Subject: [PATCH 0170/1300] feat: set integral for vector measures (#40330) The API is completely copied from the one for the Bochner integral. I have kept and adapted to vector measures all the lemmas that made sense in this context. To keep the PR at a manageable size, it corresponds only to the first half of the file `SetIntegral`. Second half coming in a second PR once this one is merged. Co-authored-by: sgouezel --- Mathlib.lean | 1 + .../VectorMeasure/SetIntegral.lean | 280 ++++++++++++++++++ 2 files changed, 281 insertions(+) create mode 100644 Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean diff --git a/Mathlib.lean b/Mathlib.lean index 347da5096894ef..4e0d5a61092878 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5622,6 +5622,7 @@ public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.JordanSub public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.Lebesgue public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.RadonNikodym public import Mathlib.MeasureTheory.VectorMeasure.Integral +public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic public import Mathlib.MeasureTheory.VectorMeasure.Variation.Defs public import Mathlib.MeasureTheory.VectorMeasure.WithDensity diff --git a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean new file mode 100644 index 00000000000000..9bf93cfca754e6 --- /dev/null +++ b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean @@ -0,0 +1,280 @@ +/- +Copyright (c) 2026 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.MeasureTheory.VectorMeasure.Integral + +/-! +# Set integral + +In this file we prove properties of `∫ᵛ x in s, f x ∂[B; μ]`. Recall that this notation +is defined as `∫ᵛ x, f x ∂[B; μ.restrict s]`. + +The API in this file is modelled on the API for the Bochner integral. +-/ + +@[expose] public section + +assert_not_exists InnerProductSpace + +open Filter Function MeasureTheory RCLike Set TopologicalSpace Topology ContinuousLinearMap +open scoped ENNReal NNReal Finset + +variable {ι X E F G H : Type*} {mX : MeasurableSpace X} + [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedAddCommGroup G] [NormedAddCommGroup H] + {μ ν : VectorMeasure X F} {f g : X → E} {s t : Set X} + +namespace MeasureTheory.VectorMeasure + +theorem IntegrableOn.mono (hs : MeasurableSet s) (hts : t ⊆ s) (h : μ.IntegrableOn f s) : + μ.IntegrableOn f t := by + by_cases ht : MeasurableSet t; swap + · simp [VectorMeasure.IntegrableOn, restrict_not_measurable _ ht] + apply Integrable.mono_measure h + simp [variation_restrict, hs, ht, Measure.restrict_mono hts le_rfl] + +theorem IntegrableOn.union (hs : MeasurableSet s) (ht : MeasurableSet t) + (hf : μ.IntegrableOn f s) (h'f : μ.IntegrableOn f t) : + μ.IntegrableOn f (s ∪ t) := by + apply Integrable.mono_measure (hf.add_measure h'f) + grw [variation_restrict_le, Measure.restrict_union_le] + simp [variation_restrict, hs, ht] + +/- `simpNF` complains that this lemma can be proved by `simp`, because the `simp`-generated lemma +unfolds the abbrev `VectorMeasure.Integrable`. TODO: fix `simp`. See lean4#13958. -/ +@[simp, nolint simpNF] theorem IntegrableOn.empty : μ.IntegrableOn f ∅ := by + simp [VectorMeasure.IntegrableOn] + +theorem IntegrableOn.biUnion_finite + {s : Set ι} (hs : s.Finite) {t : ι → Set X} (ht : ∀ i ∈ s, MeasurableSet (t i)) + (h't : ∀ i ∈ s, μ.IntegrableOn f (t i)) : + μ.IntegrableOn f (⋃ i ∈ s, t i) := by + induction s, hs using Set.Finite.induction_on with + | empty => simp + | insert _ h's hf => + simp only [mem_insert_iff, forall_eq_or_imp, iUnion_iUnion_eq_or_left] at ht h't ⊢ + exact IntegrableOn.union ht.1 (h's.measurableSet_biUnion ht.2) h't.1 (hf ht.2 h't.2) + +theorem IntegrableOn.biUnion_finset {s : Finset ι} {t : ι → Set X} + (ht : ∀ i ∈ s, MeasurableSet (t i)) (h't : ∀ i ∈ s, μ.IntegrableOn f (t i)) : + μ.IntegrableOn f (⋃ i ∈ s, t i) := + IntegrableOn.biUnion_finite s.finite_toSet ht h't + +theorem IntegrableOn.iUnion_finite [Finite ι] {t : ι → Set X} + (ht : ∀ i, MeasurableSet (t i)) (h't : ∀ i, μ.IntegrableOn f (t i)) : + μ.IntegrableOn f (⋃ i, t i) := by + cases nonempty_fintype ι + simpa using IntegrableOn.biUnion_finset (f := f) (μ := μ) (s := Finset.univ) (t := t) + (fun i hi ↦ ht i) (fun i hi ↦ h't i) + +@[simp] theorem integrableOn_univ : μ.IntegrableOn f univ ↔ μ.Integrable f := by + simp [VectorMeasure.IntegrableOn] + +theorem Integrable.integrableOn (h : μ.Integrable f) : μ.IntegrableOn f s := by + rw [← integrableOn_univ] at h + exact h.mono MeasurableSet.univ (subset_univ _) + +theorem integrable_indicator_iff (hs : MeasurableSet s) : + μ.Integrable (indicator s f) ↔ μ.IntegrableOn f s := by + simp [VectorMeasure.Integrable, VectorMeasure.IntegrableOn, MeasureTheory.IntegrableOn, + MeasureTheory.integrable_indicator_iff hs, variation_restrict hs] + +theorem IntegrableOn.integrable_indicator (h : μ.IntegrableOn f s) (hs : MeasurableSet s) : + μ.Integrable (indicator s f) := + (integrable_indicator_iff hs).2 h + +variable [NormedSpace ℝ E] [NormedSpace ℝ F] [NormedSpace ℝ G] [NormedSpace ℝ H] + {B : E →L[ℝ] F →L[ℝ] G} + +theorem setIntegral_eq_zero_of_not_measurableSet (hs : ¬MeasurableSet s) : + ∫ᵛ x in s, f x ∂[B; μ] = 0 := by + simp [restrict_not_measurable _ hs] + +theorem setIntegral_congr_ae (h : ∀ᵐ x ∂μ.variation, x ∈ s → f x = g x) : + ∫ᵛ x in s, f x ∂[B; μ] = ∫ᵛ x in s, g x ∂[B; μ] := by + by_cases hs : MeasurableSet s; swap + · simp [setIntegral_eq_zero_of_not_measurableSet hs] + apply integral_congr_ae + rw [variation_restrict hs] + exact (ae_restrict_iff' hs).2 h + +theorem setIntegral_congr_fun (h : EqOn f g s) : + ∫ᵛ x in s, f x ∂[B; μ] = ∫ᵛ x in s, g x ∂[B; μ] := + setIntegral_congr_ae <| Eventually.of_forall h + +theorem setIntegral_union (hst : Disjoint s t) (hs : MeasurableSet s) (ht : MeasurableSet t) + (hfs : μ.IntegrableOn f s) (hft : μ.IntegrableOn f t) : + ∫ᵛ x in s ∪ t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] + ∫ᵛ x in t, f x ∂[B; μ] := by + rw [← integral_add_vectorMeasure hfs hft, μ.restrict_union hst hs ht] + +theorem setIntegral_sdiff (hs : MeasurableSet s) (ht : MeasurableSet t) + (hfs : μ.IntegrableOn f s) (hts : t ⊆ s) : + ∫ᵛ x in s \ t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] - ∫ᵛ x in t, f x ∂[B; μ] := by + rw [eq_sub_iff_add_eq, ← setIntegral_union (by grind) (hs.diff ht) ht (hfs.mono hs sdiff_subset) + (hfs.mono hs hts), sdiff_union_of_subset hts] + +theorem setIntegral_inter_add_sdiff (hs : MeasurableSet s) (ht : MeasurableSet t) + (hfs : μ.IntegrableOn f s) : + ∫ᵛ x in s ∩ t, f x ∂[B; μ] + ∫ᵛ x in s \ t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by + rw [← μ.restrict_inter_add_sdiff hs ht, + integral_add_vectorMeasure (hfs.mono hs inter_subset_left) (hfs.mono hs sdiff_subset)] + +theorem setIntegral_biUnion_finset {ι : Type*} (t : Finset ι) {s : ι → Set X} + (hs : ∀ i ∈ t, MeasurableSet (s i)) (h's : Set.Pairwise (↑t) (Disjoint on s)) + (hf : ∀ i ∈ t, μ.IntegrableOn f (s i)) : + ∫ᵛ x in ⋃ i ∈ t, s i, f x ∂[B; μ] = ∑ i ∈ t, ∫ᵛ x in s i, f x ∂[B; μ] := by + classical + induction t using Finset.induction_on with + | empty => simp + | insert _ _ hat IH => + simp only [Finset.coe_insert, Finset.forall_mem_insert, Set.pairwise_insert, + Finset.set_biUnion_insert] at hs hf h's ⊢ + rw [setIntegral_union] + · rw [Finset.sum_insert hat, IH hs.2 h's.1 hf.2] + · simp only [disjoint_iUnion_right] + exact fun i hi => (h's.2 i hi (ne_of_mem_of_not_mem hi hat).symm).1 + · exact hs.1 + · exact Finset.measurableSet_biUnion _ hs.2 + · exact hf.1 + · apply IntegrableOn.biUnion_finset hs.2 hf.2 + +theorem setIntegral_iUnion_fintype {ι : Type*} [Fintype ι] {s : ι → Set X} + (hs : ∀ i, MeasurableSet (s i)) (h's : Pairwise (Disjoint on s)) + (hf : ∀ i, μ.IntegrableOn f (s i)) : + ∫ᵛ x in ⋃ i, s i, f x ∂[B; μ] = ∑ i, ∫ᵛ x in s i, f x ∂[B; μ] := by + convert setIntegral_biUnion_finset Finset.univ (fun i _ => hs i) _ fun i _ => hf i + · simp + · simp [pairwise_univ, h's] + +theorem setIntegral_empty : ∫ᵛ x in ∅, f x ∂[B; μ] = 0 := by simp + +theorem setIntegral_univ : ∫ᵛ x in univ, f x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] := by simp + +theorem setIntegral_add_compl (hs : MeasurableSet s) (hfi : μ.Integrable f) : + ∫ᵛ x in s, f x ∂[B; μ] + ∫ᵛ x in sᶜ, f x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] := by + rw [← setIntegral_union disjoint_compl_right + hs hs.compl hfi.integrableOn hfi.integrableOn, union_compl_self, setIntegral_univ] + +theorem setIntegral_compl (hs : MeasurableSet s) (hfi : μ.Integrable f) : + ∫ᵛ x in sᶜ, f x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] - ∫ᵛ x in s, f x ∂[B; μ] := by + rw [← setIntegral_add_compl (μ := μ) hs hfi, add_sub_cancel_left] + +/-- For a function `f` and a measurable set `s`, the integral of `indicator s f` +over the whole space is equal to `∫ᵛ x in s, f x ∂[B; μ]` +defined as `∫ᵛ x, f x ∂[B; μ.restrict s]`. -/ +theorem integral_indicator (hs : MeasurableSet s) : + ∫ᵛ x, indicator s f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by + by_cases hfi : μ.IntegrableOn f s; swap + · rw [integral_undef hfi, integral_undef] + rw [integrable_indicator_iff hs] + simpa [transpose_restrict, variation_restrict hs] using hfi + calc + ∫ᵛ x, indicator s f x ∂[B; μ] + _ = ∫ᵛ x in s, indicator s f x ∂[B; μ] + ∫ᵛ x in sᶜ, indicator s f x ∂[B; μ] := + (setIntegral_add_compl hs (hfi.integrable_indicator hs)).symm + _ = ∫ᵛ x in s, f x ∂[B; μ] + ∫ᵛ x in sᶜ, 0 ∂[B; μ] := by + apply congr_arg₂ (· + ·) (integral_congr_ae ?_) (integral_congr_ae ?_) + · rw [variation_restrict hs] + exact indicator_ae_eq_restrict hs + · rw [variation_restrict hs.compl] + exact indicator_ae_eq_restrict_compl hs + _ = ∫ᵛ x in s, f x ∂[B; μ] := by simp + +theorem setIntegral_indicator (hs : MeasurableSet s) (ht : MeasurableSet t) : + ∫ᵛ x in s, t.indicator f x ∂[B; μ] = ∫ᵛ x in s ∩ t, f x ∂[B; μ] := by + rw [integral_indicator ht, μ.restrict_restrict ht hs, Set.inter_comm] + +theorem setIntegral_congr_set + (hs : MeasurableSet s) (ht : MeasurableSet t) (hst : s =ᵐ[μ.variation] t) : + ∫ᵛ x in s, f x ∂[B; μ] = ∫ᵛ x in t, f x ∂[B; μ] := by + rw [← integral_indicator hs, ← integral_indicator ht] + apply integral_congr_ae + filter_upwards [hst] with x hx + replace hx : x ∈ s ↔ x ∈ t := by simpa using! hx + simp [indicator] + grind + +theorem integral_piecewise [DecidablePred (· ∈ s)] + (hs : MeasurableSet s) (hf : μ.IntegrableOn f s) (hg : μ.IntegrableOn g sᶜ) : + ∫ᵛ x, s.piecewise f g x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] + ∫ᵛ x in sᶜ, g x ∂[B; μ] := by + rw [← Set.indicator_add_compl_eq_piecewise, + integral_add (hf.integrable_indicator hs) (hg.integrable_indicator hs.compl), + integral_indicator hs, integral_indicator hs.compl] + +theorem setIntegral_eq_zero_of_ae_eq_zero + (ht_eq : ∀ᵐ x ∂μ.variation, x ∈ t → f x = 0) : + ∫ᵛ x in t, f x ∂[B; μ] = 0 := by + by_cases ht : MeasurableSet t; swap + · simp [setIntegral_eq_zero_of_not_measurableSet ht] + by_cases hf : AEStronglyMeasurable f (μ.restrict t).variation; swap + · rw [integral_undef] + contrapose hf + exact hf.1 + simp only [variation_restrict ht] at hf + have : ∫ᵛ x in t, hf.mk f x ∂[B; μ] = 0 := by + refine integral_eq_zero_of_ae ?_ + simp only [variation_restrict ht] + apply (ae_restrict_iff' ht).2 + filter_upwards [ae_imp_of_ae_restrict hf.ae_eq_mk, ht_eq] with x hx h'x h''x + rw [← hx h''x] + exact h'x h''x + rw [← this] + apply integral_congr_ae + simp only [variation_restrict ht] + exact hf.ae_eq_mk + +theorem setIntegral_eq_zero_of_forall_eq_zero (ht_eq : ∀ x ∈ t, f x = 0) : + ∫ᵛ x in t, f x ∂[B; μ] = 0 := + setIntegral_eq_zero_of_ae_eq_zero (Eventually.of_forall ht_eq) + +theorem frequently_ae_ne_zero_of_setIntegral_ne_zero (hU : ∫ᵛ x in t, f x ∂[B; μ] ≠ 0) : + ∃ᶠ x in ae (μ.variation.restrict t), f x ≠ 0 := by + have ht : MeasurableSet t := by + contrapose! hU + simp [setIntegral_eq_zero_of_not_measurableSet hU] + rw [← variation_restrict ht] + exact frequently_ae_ne_zero_of_integral_ne_zero hU + +theorem exists_ne_zero_of_setIntegral_ne_zero (hU : ∫ᵛ x in t, f x ∂[B; μ] ≠ 0) : + ∃ x, x ∈ t ∧ f x ≠ 0 := by + contrapose! hU; exact setIntegral_eq_zero_of_forall_eq_zero hU + +theorem setIntegral_of_variation_apply_eq_zero (f : X → E) {s : Set X} + (hs : μ.variation s = 0) : + ∫ᵛ x in s, f x ∂[B; μ] = 0 := by + by_cases h's : MeasurableSet s; swap + · simp [restrict_not_measurable μ h's] + have : (μ.restrict s).variation = 0 := by + rw [variation_restrict h's] + apply Measure.restrict_eq_zero.2 hs + have : μ.restrict s = 0 := variation_eq_zero.1 this + simpa [integral_eq_setToFun, this] using! setToFun_zero_left + +theorem setIntegral_dirac' {mX : MeasurableSpace X} [CompleteSpace G] {a : X} {v : F} + (hf : StronglyMeasurable f) {s : Set X} (hs : MeasurableSet s) [Decidable (a ∈ s)] : + ∫ᵛ x in s, f x ∂[B; VectorMeasure.dirac a v] = if a ∈ s then B (f a) v else 0 := by + rw [restrict_dirac hs] + split_ifs + · exact integral_dirac' hf + · exact integral_zero_vectorMeasure + +theorem setIntegral_dirac [MeasurableSpace X] [MeasurableSingletonClass X] [CompleteSpace G] + {a : X} {v : F} {s : Set X} (hs : MeasurableSet s) [Decidable (a ∈ s)] : + ∫ᵛ x in s, f x ∂[B; VectorMeasure.dirac a v] = if a ∈ s then B (f a) v else 0 := by + rw [restrict_dirac hs] + split_ifs + · exact integral_dirac + · exact integral_zero_vectorMeasure + +theorem integral_singleton' [CompleteSpace G] {a : X} (hf : StronglyMeasurable f) : + ∫ᵛ a in {a}, f a ∂[B; μ] = B (f a) (μ {a}) := by + simp only [restrict_singleton, integral_dirac' hf] + +theorem integral_singleton [MeasurableSingletonClass X] {a : X} [CompleteSpace G] : + ∫ᵛ a in {a}, f a ∂[B; μ] = B (f a) (μ {a}) := by + simp only [restrict_singleton, integral_dirac] + +end MeasureTheory.VectorMeasure From 4db60865e6954700dc3c471830212740525f36a8 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:05:50 +0000 Subject: [PATCH 0171/1300] chore: move strong measurability proof to `setToFun` (#40602) The goal is to be able to use the very same lemma for the vector measure integral, in a forthcoming PR. Co-authored-by: sgouezel --- .../Integral/FinMeasAdditive.lean | 12 ++++ Mathlib/MeasureTheory/Integral/Prod.lean | 66 +++---------------- Mathlib/MeasureTheory/Integral/SetToL1.lean | 66 +++++++++++++++++++ 3 files changed, 87 insertions(+), 57 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean b/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean index d6a80a4a9e1495..1a9b39c030e3d8 100644 --- a/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean +++ b/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean @@ -322,6 +322,18 @@ theorem setToSimpleFunc_eq_sum_filter [DecidablePred fun x ↦ x ≠ (0 : F)] rw [hx0] exact map_zero _ +/-- The `setToSimpleFunc` is equal to a sum over any set that includes `f.range` (except `0`). -/ +theorem setToSimpleFunc_eq_sum_of_subset [DecidablePred fun x : F => x ≠ 0] + (T : Set α → F →L[ℝ] F') (hT : T ∅ = 0) {f : α →ₛ F} {s : Finset F} + (hs : {x ∈ f.range | x ≠ 0} ⊆ s) : + setToSimpleFunc T f = ∑ x ∈ s, T (f ⁻¹' {x}) x := by + rw [setToSimpleFunc_eq_sum_filter, Finset.sum_subset hs] + rintro x - hx; rw [Finset.mem_filter, not_and_or, Ne, Classical.not_not] at hx + rcases hx.symm with (rfl | hx) + · simp + rw [SimpleFunc.mem_range] at hx + rw [preimage_eq_empty] <;> simp [Set.disjoint_singleton_left, hx, hT] + theorem map_setToSimpleFunc (T : Set α → F →L[ℝ] F') (h_add : FinMeasAdditive μ T) {f : α →ₛ G} (hf : Integrable f μ) {g : G → F} (hg : g 0 = 0) : (f.map g).setToSimpleFunc T = ∑ x ∈ f.range, T (f ⁻¹' {x}) (g x) := by diff --git a/Mathlib/MeasureTheory/Integral/Prod.lean b/Mathlib/MeasureTheory/Integral/Prod.lean index 6dd14fda021671..da0f8ba97080c1 100644 --- a/Mathlib/MeasureTheory/Integral/Prod.lean +++ b/Mathlib/MeasureTheory/Integral/Prod.lean @@ -37,7 +37,6 @@ product measure, Fubini's theorem, Fubini-Tonelli theorem public section - noncomputable section open scoped Topology ENNReal MeasureTheory @@ -60,12 +59,6 @@ functions. We show that if `f` is a binary measurable function, then the functio along one of the variables (using either the Lebesgue or Bochner integral) is measurable. -/ - -theorem measurableSet_integrable [SFinite ν] ⦃f : α → β → E⦄ - (hf : StronglyMeasurable (uncurry f)) : MeasurableSet {x | Integrable (f x) ν} := by - simp_rw [Integrable, hf.of_uncurry_left.aestronglyMeasurable, true_and] - exact measurableSet_lt (Measurable.lintegral_prod_right hf.enorm) measurable_const - section variable [NormedSpace ℝ E] @@ -75,49 +68,10 @@ variable [NormedSpace ℝ E] This version has `f` in curried form. -/ theorem MeasureTheory.StronglyMeasurable.integral_prod_right [SFinite ν] ⦃f : α → β → E⦄ (hf : StronglyMeasurable (uncurry f)) : StronglyMeasurable fun x => ∫ y, f x y ∂ν := by - classical - by_cases hE : CompleteSpace E; swap; · simp [integral, hE, stronglyMeasurable_const] - borelize E - haveI : SeparableSpace (range (uncurry f) ∪ {0} : Set E) := - hf.separableSpace_range_union_singleton - let s : ℕ → SimpleFunc (α × β) E := - SimpleFunc.approxOn _ hf.measurable (range (uncurry f) ∪ {0}) 0 (by simp) - let s' : ℕ → α → SimpleFunc β E := fun n x => (s n).comp (Prod.mk x) measurable_prodMk_left - let f' : ℕ → α → E := fun n => {x | Integrable (f x) ν}.indicator fun x => (s' n x).integral ν - have hf' : ∀ n, StronglyMeasurable (f' n) := by - intro n; refine StronglyMeasurable.indicator ?_ (measurableSet_integrable hf) - have : ∀ x, ((s' n x).range.filter fun x => x ≠ 0) ⊆ (s n).range := by - intro x; refine Finset.Subset.trans (Finset.filter_subset _ _) ?_; intro y - simp_rw [SimpleFunc.mem_range]; rintro ⟨z, rfl⟩; exact ⟨(x, z), rfl⟩ - simp only [SimpleFunc.integral_eq_sum_of_subset (this _)] - refine Finset.stronglyMeasurable_fun_sum _ fun x _ => ?_ - refine (Measurable.ennreal_toReal ?_).stronglyMeasurable.smul_const _ - simp only [s', SimpleFunc.coe_comp, preimage_comp] - apply measurable_measure_prodMk_left - exact (s n).measurableSet_fiber x - have h2f' : Tendsto f' atTop (𝓝 fun x : α => ∫ y : β, f x y ∂ν) := by - rw [tendsto_pi_nhds]; intro x - by_cases hfx : Integrable (f x) ν - · have (n : _) : Integrable (s' n x) ν := by - apply (hfx.norm.add hfx.norm).mono' (s' n x).aestronglyMeasurable - filter_upwards with y - simp_rw [s', SimpleFunc.coe_comp]; exact SimpleFunc.norm_approxOn_zero_le _ _ (x, y) n - simp only [f', hfx, SimpleFunc.integral_eq_integral _ (this _), indicator_of_mem, - mem_setOf_eq] - refine - tendsto_integral_of_dominated_convergence (fun y => ‖f x y‖ + ‖f x y‖) - (fun n => (s' n x).aestronglyMeasurable) (hfx.norm.add hfx.norm) ?_ ?_ - · refine fun n => Eventually.of_forall fun y => - SimpleFunc.norm_approxOn_zero_le ?_ ?_ (x, y) n - · exact hf.measurable - · simp - · refine Eventually.of_forall fun y => SimpleFunc.tendsto_approxOn ?_ ?_ ?_ - · exact hf.measurable.of_uncurry_left - · simp - apply subset_closure - simp [-uncurry_apply_pair] - · simp [f', hfx, integral_undef] - exact stronglyMeasurable_of_tendsto _ hf' h2f' + simp only [integral_eq_setToFun] + apply StronglyMeasurable.setToFun_prod_right _ (fun s hs ↦ ?_) hf + refine (Measurable.ennreal_toReal ?_).stronglyMeasurable.smul_const _ + exact measurable_measure_prodMk_left hs /-- The Bochner integral is measurable. This shows that the integrand of (the right-hand-side of) Fubini's theorem is measurable. -/ @@ -380,13 +334,11 @@ end variable [NormedSpace ℝ E] theorem Integrable.integral_prod_left ⦃f : α × β → E⦄ (hf : Integrable f (μ.prod ν)) : - Integrable (fun x => ∫ y, f (x, y) ∂ν) μ := - Integrable.mono hf.integral_norm_prod_left hf.aestronglyMeasurable.integral_prod_right' <| - Eventually.of_forall fun x => - (norm_integral_le_integral_norm _).trans_eq <| - (norm_of_nonneg <| - integral_nonneg_of_ae <| - Eventually.of_forall fun y => (norm_nonneg (f (x, y)) :)).symm + Integrable (fun x => ∫ y, f (x, y) ∂ν) μ := by + apply Integrable.mono hf.integral_norm_prod_left hf.aestronglyMeasurable.integral_prod_right' + filter_upwards with x + grw [norm_integral_le_integral_norm] + exact le_abs_self _ theorem Integrable.integral_prod_right [SFinite μ] ⦃f : α × β → E⦄ (hf : Integrable f (μ.prod ν)) : Integrable (fun y => ∫ x, f (x, y) ∂μ) ν := diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index 1af06506765fed..bd8c0a097c415a 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -844,6 +844,12 @@ theorem setToFun_simpleFunc [CompleteSpace F] (hT : DominatedFinMeasAdditive μ apply (SimpleFunc.setToSimpleFunc_congr T (fun s ↦ hT.eq_zero_of_measure_zero) hT.1 hf _).symm grw [A, Lp.simpleFunc.toSimpleFunc_eq_toFun] +theorem setToFun_simpleFunc_eq_setToSimpleFunc [CompleteSpace F] + (hT : DominatedFinMeasAdditive μ T C) (f : SimpleFunc α E) (hf : Integrable f μ) : + setToFun μ T hT f = f.setToSimpleFunc T := by + rw [setToFun_simpleFunc hT f hf] + rfl + section Order variable {G' G'' : Type*} @@ -1384,6 +1390,66 @@ theorem tendsto_setToFun_filter_of_norm_le_const (hT : DominatedFinMeasAdditive exact tendsto_setToFun_filter_of_dominated_convergence hT C h_meas h_boundc (integrable_const c) h_lim +omit [NormedSpace ℝ E] in +theorem _root_.measurableSet_integrable {β : Type*} {mβ : MeasurableSpace β} [SFinite μ] + ⦃f : β → α → E⦄ (hf : StronglyMeasurable (Function.uncurry f)) : + MeasurableSet {x | Integrable (f x) μ} := by + simp_rw [Integrable, hf.of_uncurry_left.aestronglyMeasurable, true_and] + exact measurableSet_lt (Measurable.lintegral_prod_right hf.enorm) measurable_const + +/-- The `setToFun` operation is measurable. This shows that the integrand of (the right-hand-side +of) Fubini's theorem is measurable. This version has `f` in curried form. -/ +theorem StronglyMeasurable.setToFun_prod_right {β : Type*} {mβ : MeasurableSpace β} [SFinite μ] + (hT : DominatedFinMeasAdditive μ T C) + (h'T : ∀ (s : Set (β × α)), MeasurableSet s → StronglyMeasurable fun x => T (Prod.mk x ⁻¹' s)) + ⦃f : β → α → E⦄ (hf : StronglyMeasurable (Function.uncurry f)) : + StronglyMeasurable fun x => setToFun μ T hT (f x) := by + classical + by_cases hF : CompleteSpace F; swap; + · simp [setToFun, hF, stronglyMeasurable_const] + borelize E + haveI : SeparableSpace (range (Function.uncurry f) ∪ {0} : Set E) := + hf.separableSpace_range_union_singleton + let s : ℕ → SimpleFunc (β × α) E := + SimpleFunc.approxOn _ hf.measurable (range (Function.uncurry f) ∪ {0}) 0 (by simp) + let s' : ℕ → β → SimpleFunc α E := fun n x => (s n).comp (Prod.mk x) measurable_prodMk_left + let f' : ℕ → β → F := fun n => + {x | Integrable (f x) μ}.indicator fun x => (s' n x).setToSimpleFunc T + have hf' n : StronglyMeasurable (f' n) := by + refine StronglyMeasurable.indicator ?_ (measurableSet_integrable hf) + have : ∀ x, ((s' n x).range.filter fun x => x ≠ 0) ⊆ (s n).range := by + intro x; refine Finset.Subset.trans (Finset.filter_subset _ _) ?_; intro y + simp_rw [SimpleFunc.mem_range]; rintro ⟨z, rfl⟩; exact ⟨(x, z), rfl⟩ + simp_rw [SimpleFunc.setToSimpleFunc_eq_sum_of_subset T hT.1.map_empty_eq_zero (this _)] + refine Finset.stronglyMeasurable_fun_sum _ fun x _ => ?_ + simp only [s', SimpleFunc.coe_comp, preimage_comp] + apply StronglyMeasurable.apply_continuousLinearMap + apply h'T + exact (s n).measurableSet_fiber x + have h2f' : Tendsto f' atTop (𝓝 fun x : β => setToFun μ T hT (f x)) := by + apply tendsto_pi_nhds.2 fun x ↦ ?_ + by_cases hfx : Integrable (f x) μ + · have (n : _) : Integrable (s' n x) μ := by + apply (hfx.norm.add hfx.norm).mono' (s' n x).aestronglyMeasurable + filter_upwards with y + simp_rw [s', SimpleFunc.coe_comp]; exact SimpleFunc.norm_approxOn_zero_le _ _ (x, y) n + simp only [mem_setOf_eq, hfx, indicator_of_mem, this, + ← setToFun_simpleFunc_eq_setToSimpleFunc hT, f'] + refine + tendsto_setToFun_of_dominated_convergence hT (fun y => ‖f x y‖ + ‖f x y‖) + (fun n => (s' n x).aestronglyMeasurable) (hfx.norm.add hfx.norm) ?_ ?_ + · refine fun n => Eventually.of_forall fun y => + SimpleFunc.norm_approxOn_zero_le ?_ ?_ (x, y) n + · exact hf.measurable + · simp + · refine Eventually.of_forall fun y => SimpleFunc.tendsto_approxOn ?_ ?_ ?_ + · exact hf.measurable.of_uncurry_left + · simp + apply subset_closure + simp [-Function.uncurry_apply_pair] + · simp [f', hfx, setToFun_undef] + exact stronglyMeasurable_of_tendsto _ hf' h2f' + variable {X : Type*} [TopologicalSpace X] [FirstCountableTopology X] theorem continuousWithinAt_setToFun_of_dominated (hT : DominatedFinMeasAdditive μ T C) From 9aa409007908aecdb6a12049b8d664360ebaa9f7 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:24:01 +0000 Subject: [PATCH 0172/1300] feat: criterion for being smooth in terms of a maximal atlas element in the target (#40795) We already had this version in the source, but not in the target Co-authored-by: sgouezel --- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index a963ba00712ffb..4520d963cfe915 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -349,20 +349,24 @@ theorem contMDiffAt_iff_source_of_mem_source ContMDiffWithinAt 𝓘(𝕜, E) I' n (f ∘ (extChartAt I x).symm) (range I) (extChartAt I x x') := by simp_rw [ContMDiffAt, contMDiffWithinAt_iff_source_of_mem_source hx', preimage_univ, univ_inter] +theorem contMDiffWithinAt_iff_target_of_mem_maximalAtlas + (he' : e' ∈ maximalAtlas I' n M') (hx : f x ∈ e'.source) : + ContMDiffWithinAt I I' n f s x ↔ + ContinuousWithinAt f s x ∧ ContMDiffWithinAt I 𝓘(𝕜, E') n ((e'.extend I') ∘ f) s x := by + simp_rw [ContMDiffWithinAt, + (contDiffWithinAt_localInvariantProp n).liftPropWithinAt_indep_chart_target he' hx] + apply and_congr_right (fun h ↦ ?_) + have A : ContinuousWithinAt ((e'.extend I') ∘ f) s x := + (e'.continuousAt_extend hx).comp_continuousWithinAt h + have A' : ContinuousWithinAt (e' ∘ f) s x := (e'.continuousAt hx).comp_continuousWithinAt h + simp_rw [StructureGroupoid.liftPropWithinAt_self_target, A, A'] + simp [ContDiffWithinAtProp, comp_assoc] + theorem contMDiffWithinAt_iff_target_of_mem_source [IsManifold I' n M'] {x : M} {y : M'} (hy : f x ∈ (chartAt H' y).source) : ContMDiffWithinAt I I' n f s x ↔ - ContinuousWithinAt f s x ∧ ContMDiffWithinAt I 𝓘(𝕜, E') n (extChartAt I' y ∘ f) s x := by - simp_rw [ContMDiffWithinAt] - rw [(contDiffWithinAt_localInvariantProp n).liftPropWithinAt_indep_chart_target - (chart_mem_maximalAtlas y) hy, - and_congr_right] - intro hf - simp_rw [StructureGroupoid.liftPropWithinAt_self_target] - simp_rw [((chartAt H' y).continuousAt hy).comp_continuousWithinAt hf] - rw [← extChartAt_source (I := I')] at hy - simp_rw [(continuousAt_extChartAt' hy).comp_continuousWithinAt hf] - rfl + ContinuousWithinAt f s x ∧ ContMDiffWithinAt I 𝓘(𝕜, E') n (extChartAt I' y ∘ f) s x := + contMDiffWithinAt_iff_target_of_mem_maximalAtlas (chart_mem_maximalAtlas _) hy theorem contMDiffAt_iff_target_of_mem_source [IsManifold I' n M'] {x : M} {y : M'} (hy : f x ∈ (chartAt H' y).source) : @@ -380,7 +384,7 @@ theorem contMDiffWithinAt_iff_of_mem_maximalAtlas {x : M} (he : e ∈ maximalAtl (contDiffWithinAt_localInvariantProp n).liftPropWithinAt_indep_chart he hx he' hy /-- An alternative formulation of `contMDiffWithinAt_iff_of_mem_maximalAtlas` -if the set if `s` lies in `e.source`. -/ +if the set `s` lies in `e.source`. -/ theorem contMDiffWithinAt_iff_image {x : M} (he : e ∈ maximalAtlas I n M) (he' : e' ∈ maximalAtlas I' n M') (hs : s ⊆ e.source) (hx : x ∈ e.source) (hy : f x ∈ e'.source) : From 9fbe5e0065da0f234feecd62195593c91fc2ff89 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:56:51 +0000 Subject: [PATCH 0173/1300] feat: the semivariation of a vector measure (#40384) We define the semivariation of a vector measure (i.e., the supremum of the variation of its push-forwards by linear forms), and establish basic properties. We deduce that a vector measure is always bounded. Co-authored-by: sgouezel --- Mathlib.lean | 1 + Mathlib/Analysis/Normed/Group/Continuity.lean | 11 ++ .../VectorMeasure/Variation/Basic.lean | 86 ++++++++ .../Variation/Semivariation.lean | 187 ++++++++++++++++++ Mathlib/Topology/UniformSpace/Dini.lean | 2 +- docs/references.bib | 15 ++ 6 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4e0d5a61092878..68d485cacf48e4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5625,6 +5625,7 @@ public import Mathlib.MeasureTheory.VectorMeasure.Integral public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic public import Mathlib.MeasureTheory.VectorMeasure.Variation.Defs +public import Mathlib.MeasureTheory.VectorMeasure.Variation.Semivariation public import Mathlib.MeasureTheory.VectorMeasure.WithDensity public import Mathlib.ModelTheory.Algebra.Field.Basic public import Mathlib.ModelTheory.Algebra.Field.CharP diff --git a/Mathlib/Analysis/Normed/Group/Continuity.lean b/Mathlib/Analysis/Normed/Group/Continuity.lean index 609c44b07dde86..bce9c2ecb79818 100644 --- a/Mathlib/Analysis/Normed/Group/Continuity.lean +++ b/Mathlib/Analysis/Normed/Group/Continuity.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Normed.Group.Basic public import Mathlib.Topology.Algebra.Ring.Real +public import Mathlib.Topology.Instances.ENNReal.Lemmas public import Mathlib.Topology.Metrizable.Uniformity public import Mathlib.Topology.Sequences @@ -68,6 +69,16 @@ theorem tendsto_one_iff_norm_tendsto_zero {f : α → E} {a : Filter α} : Tendsto f a (𝓝 1) ↔ Tendsto (‖f ·‖) a (𝓝 0) := tendsto_iff_norm_inv_mul_tendsto_zero.trans <| by simp +@[to_additive] +theorem tendsto_iff_enorm_inv_mul_tendsto_zero {f : α → E} {a : Filter α} {b : E} : + Tendsto f a (𝓝 b) ↔ Tendsto (fun e => ‖(f e)⁻¹ * b‖ₑ) a (𝓝 0) := by + simp only [← edist_eq_enorm_inv_mul, ← tendsto_iff_edist_tendsto_0] + +@[to_additive] +theorem tendsto_one_iff_enorm_tendsto_zero {f : α → E} {a : Filter α} : + Tendsto f a (𝓝 1) ↔ Tendsto (‖f ·‖ₑ) a (𝓝 0) := + tendsto_iff_enorm_inv_mul_tendsto_zero.trans <| by simp + @[to_additive (attr := simp 1100)] theorem comap_norm_nhds_one : comap norm (𝓝 0) = 𝓝 (1 : E) := by simpa only [dist_one_right] using nhds_comap_dist (1 : E) diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean index de8e791a846bee..27c729bf7e976e 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean @@ -75,6 +75,31 @@ lemma le_variation (μ : VectorMeasure X V) {s : Set X} (hs : MeasurableSet s) { simp only [sup_set_eq_biUnion, id_eq] exact hs.diff <| .biUnion (Finset.countable_toSet _) (by simp) +/-- Measure version of `preVariation.exists_Finpartition_sum_gt`. -/ +lemma exists_lt_sum_of_lt_variation (μ : VectorMeasure X V) {s : Set X} (hs : MeasurableSet s) + {a : ℝ≥0∞} (ha : a < μ.variation s) : + ∃ (P : Finset (Set X)), (∀ t ∈ P, t ⊆ s) ∧ ((P : Set (Set X)).PairwiseDisjoint id) ∧ + (∀ t ∈ P, MeasurableSet t) ∧ a < ∑ p ∈ P, ‖μ p‖ₑ := by + simp only [variation_apply, preVariation, ennrealToMeasure_apply hs, ennrealPreVariation_apply] + at ha ⊢ + obtain ⟨P, hP⟩ : ∃ P : Finpartition (⟨s, hs⟩ : Subtype MeasurableSet), + a < ∑ p ∈ P.parts, (fun x ↦ ‖μ x‖ₑ) p := + preVariation.exists_Finpartition_sum_gt (‖μ ·‖ₑ) _ ha + refine ⟨P.parts.map (Function.Embedding.subtype _), ?_, ?_, ?_, ?_⟩ + · simp only [mem_map, Function.Embedding.subtype_apply, Subtype.exists, exists_and_right, + exists_eq_right, forall_exists_index] + intro t ht h't + exact P.le h't + · intro i hi j hj hij + simp only [coe_map, Function.Embedding.subtype_apply, Set.mem_image, SetLike.mem_coe, + Subtype.exists, exists_and_right, exists_eq_right] at hi hj + rcases hi with ⟨h'i, i_mem⟩ + rcases hj with ⟨h'j, j_mem⟩ + exact (disjoint_subtype_iff (fun _ _ hs ht ↦ hs.inter ht) _).1 + (P.disjoint i_mem j_mem (by simpa using hij)) + · simp +contextual + · rwa [Finset.sum_map] + /-- Measure version of `preVariation.exists_Finpartition_sum_ge'`. -/ lemma exists_variation_le_add' (μ : VectorMeasure X V) {s : Set X} (hs : MeasurableSet s) {ε : ℝ≥0∞} (hε : 0 < ε) (hμ : μ.variation s ≠ ∞) : @@ -316,6 +341,67 @@ instance {x : X} {v : V} : IsFiniteMeasure (VectorMeasure.dirac x v).variation : apply le_trans ?_ (enorm_measure_le_variation _ _) simp [hs, Measure.real, Real.enorm_eq_ofReal] +/-- For a signed measure, the variation is realized by the norm of the measure of a single set, up +to a factor of `2` and an arbitrarily small error. -/ +lemma _root_.MeasureTheory.SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation + (μ : SignedMeasure X) {s : Set X} (hs : MeasurableSet s) + {a : ℝ≥0∞} (ha : a < μ.variation s) : + ∃ t ⊆ s, MeasurableSet t ∧ a < 2 * ‖μ t‖ₑ := by + /- One may almost realize the variation through a partition into finitely many sets. + As their measures are real numbers, we can group together those of positive measure, and + also those of negative measure. This gives two measurable sets. Among these two, the one with the + largest measure in absolute value satisfies the result. -/ + obtain ⟨P, Ps, P_disj, P_meas, hP⟩ : ∃ (P : Finset (Set X)), (∀ t ∈ P, t ⊆ s) ∧ + ((P : Set (Set X)).PairwiseDisjoint id) ∧ + (∀ t ∈ P, MeasurableSet t) ∧ a < ∑ p ∈ P, ‖μ p‖ₑ := exists_lt_sum_of_lt_variation _ hs ha + have I : (∑ p ∈ P.filter (fun p ↦ 0 ≤ μ p), ‖μ p‖ₑ) = + ‖μ (⋃ p ∈ P.filter (fun p ↦ 0 ≤ μ p), p)‖ₑ := by + simp only [Real.norm_eq_abs, enorm_eq_nnnorm, + ← ENNReal.ofNNReal_finsetSum, ENNReal.coe_inj, ← NNReal.coe_inj, + NNReal.coe_sum, coe_nnnorm, Real.norm_eq_abs] + have A : ∑ x ∈ P with 0 ≤ μ x, |μ x| = μ (⋃ x ∈ P.filter (fun x ↦ 0 ≤ μ x), x) := calc + _ = ∑ x ∈ P with 0 ≤ μ x, μ x := by + apply Finset.sum_congr rfl (fun p hp ↦ ?_) + simp only [Finset.mem_filter] at hp + simp [hp] + _ = μ (⋃ x ∈ P.filter (fun x ↦ 0 ≤ μ x), x) := by + rw [of_biUnion_finset] + · apply P_disj.subset (by grind) + · grind + rw [A, abs_of_nonneg] + rw [← A] + exact Finset.sum_nonneg (fun p hp ↦ by positivity) + have J : (∑ p ∈ P.filter (fun p ↦ ¬ 0 ≤ μ p), ‖μ p‖ₑ) = + ‖μ (⋃ p ∈ P.filter (fun p ↦ ¬ 0 ≤ μ p), p)‖ₑ := by + simp only [not_le, enorm_eq_nnnorm, ← ENNReal.ofNNReal_finsetSum, + ENNReal.coe_inj, ← NNReal.coe_inj, NNReal.coe_sum, coe_nnnorm, Real.norm_eq_abs] + have A : ∑ x ∈ P with μ x < 0, |μ x| = - μ (⋃ x ∈ P.filter (fun x ↦ μ x < 0), x) := calc + ∑ x ∈ P with μ x < 0, |μ x| + _ = ∑ x ∈ P with μ x < 0, -μ x := by + refine Finset.sum_congr rfl (fun p hp ↦ ?_) + simp only [Finset.mem_filter] at hp + simp [hp.2.le] + _ = -μ (⋃ x ∈ P.filter (fun x ↦ μ x < 0), x) := by + rw [of_biUnion_finset] + · simp + · apply P_disj.subset (by grind) + · grind + rw [A, abs_of_nonpos] + rw [← neg_nonneg, ← A] + exact Finset.sum_nonneg (fun p hp ↦ by positivity) + simp_rw [two_mul] + rw [← Finset.sum_filter_add_sum_filter_not _ (fun p ↦ 0 ≤ μ p), I, J] at hP + rcases le_total (‖μ (⋃ p ∈ P.filter (fun p ↦ ¬ 0 ≤ μ p), p)‖ₑ) + (‖μ (⋃ p ∈ P.filter (fun p ↦ 0 ≤ μ p), p)‖ₑ) with h | h + · refine ⟨⋃ p ∈ P.filter (fun p ↦ 0 ≤ μ p), p, ?_, ?_, ?_⟩ + · simp; grind + · exact Finset.measurableSet_biUnion _ (by grind) + · exact hP.trans_le (by gcongr) + · refine ⟨⋃ p ∈ P.filter (fun p ↦ ¬ 0 ≤ μ p), p, ?_, ?_, ?_⟩ + · simp; grind + · exact Finset.measurableSet_biUnion _ (by grind) + · exact hP.trans_le (by gcongr) + end NormedAddCommGroup end MeasureTheory.VectorMeasure diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean new file mode 100644 index 00000000000000..06c83d0549c4b9 --- /dev/null +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean @@ -0,0 +1,187 @@ +/- +Copyright (c) 2026 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic + +import Mathlib.Analysis.Normed.Module.HahnBanach +import Mathlib.Analysis.Normed.Operator.NormedSpace + +/-! +# The semivariation of a vector measure + +The semivariation of a vector measure is the supremum of the variations of its push-forwards +to `ℝ` through all linear forms of norm at most `1`. The interest of this notion is that, in the +reals, any set has nonnegative or nonpositive measure, so that the variation is realized by +a subset (up to a factor of at most `2`). This property is inherited by the semivariation in +general: one has the inequalities +``` +‖μ s‖ₑ ≤ μ.semivariation s ≤ 2 sup_{t ⊆ s} ‖μ t‖ₑ +``` + +The notion of semivariation can in particular be used to show that any vector measure is bounded: +there exists `C < ∞` such that `‖μ s‖ ≤ C` for all `s`. + +## Main results + +* `μ.semivariation`: the semivariation of the vector measure `μ`. +* `exists_subset_lt_enorm_apply_of_lt_semivariation`: given `s`, there exists `t ⊆ s` such that + `μ.semivariation s ≤ 2 ‖μ t‖ₑ` up to an arbitrarily small error. +* `μ.bound`: the semivariation of `univ`, in `ℝ≥0`. It is finite by definition. +* `enorm_apply_le_bound`: the inequality `‖μ s‖ₑ ≤ μ.bound`, uniformly in `s`. + +## References + +* [J. Diestel and J.J. Uhl, Vector Measures][DiestelUhl1977] + +-/ + +public section + +open scoped ENNReal Function Topology NNReal +open Set Filter + +namespace MeasureTheory.VectorMeasure + +variable {X E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {mX : MeasurableSpace X} + {μ : VectorMeasure X E} {s t : Set X} + +/-- The semivariation of a vector measure, defined as the supremum of the variations +of the images of the vector measures under continuous linear forms of norm at most `1`. -/ +noncomputable def semivariation (μ : VectorMeasure X E) (s : Set X) : ℝ≥0∞ := + ⨆ ℓ ∈ {ℓ : StrongDual ℝ E | ‖ℓ‖ₑ ≤ 1}, (μ.mapRange (ℓ : E →+ ℝ) ℓ.continuous).variation s + +lemma semivariation_union_le : + μ.semivariation (s ∪ t) ≤ μ.semivariation s + μ.semivariation t := by + simp only [semivariation, iSup_le_iff] + intro ℓ hℓ + apply (measure_union_le _ _).trans + gcongr <;> apply le_biSup _ hℓ + +lemma semivariation_mono (hst : s ⊆ t) : μ.semivariation s ≤ μ.semivariation t := by + simp only [semivariation, iSup_le_iff] + intro ℓ hℓ + apply (measure_mono hst).trans + apply le_biSup _ hℓ + +lemma semivariation_le_variation : μ.semivariation s ≤ μ.variation s := by + simp only [semivariation, iSup_le_iff] + intro ℓ hℓ + suffices (μ.mapRange (ℓ : E →+ ℝ) ℓ.continuous).variation ≤ μ.variation from this s + apply variation_le_of_forall_enorm_le (fun t ht ↦ ?_) + simp only [mapRange_apply, AddMonoidHom.coe_coe] + apply le_trans ?_ (enorm_measure_le_variation _ _) + exact (ContinuousLinearMap.le_opNorm_enorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) + +lemma enorm_apply_le_semivariation : ‖μ s‖ₑ ≤ μ.semivariation s := by + by_cases hs : MeasurableSet s; swap + · simp [not_measurable, hs] + obtain ⟨ℓ, ℓ_norm, hℓ⟩ : ∃ ℓ : StrongDual ℝ E, ‖ℓ‖ ≤ 1 ∧ ℓ (μ s) = ‖μ s‖ := + exists_dual_vector'' _ _ + have h'ℓ : ℓ ∈ {ℓ : StrongDual ℝ E | ‖ℓ‖ₑ ≤ 1} := by + simp [enorm_eq_nnnorm, ← NNReal.coe_le_one, ℓ_norm] + calc ‖μ s‖ₑ + _ = ‖(μ.mapRange (ℓ : E →+ ℝ) ℓ.continuous) s‖ₑ := by simp [← ofReal_norm, hℓ] + _ ≤ (μ.mapRange (ℓ : E →+ ℝ) ℓ.continuous).variation s := enorm_measure_le_variation _ _ + _ ≤ μ.semivariation s := by apply le_biSup _ h'ℓ + +lemma enorm_apply_le_semivariation_of_subset (hst : s ⊆ t) : + ‖μ s‖ₑ ≤ μ.semivariation t := + enorm_apply_le_semivariation.trans (semivariation_mono hst) + +lemma exists_subset_lt_enorm_apply_of_lt_semivariation (hs : MeasurableSet s) + {a : ℝ≥0∞} (ha : a < μ.semivariation s) : + ∃ t ⊆ s, MeasurableSet t ∧ a < 2 * ‖μ t‖ₑ := by + obtain ⟨ℓ, hℓ, h'ℓ⟩ : ∃ ℓ ∈ {ℓ : StrongDual ℝ E | ‖ℓ‖ₑ ≤ 1}, + a < (μ.mapRange (ℓ : E →+ ℝ) ℓ.continuous).variation s := lt_biSup_iff.1 ha + obtain ⟨t, ts, t_meas, ht⟩ : + ∃ t ⊆ s, MeasurableSet t ∧ a < 2 * ‖μ.mapRange (ℓ : E →+ ℝ) ℓ.continuous t‖ₑ := + SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation _ hs h'ℓ + refine ⟨t, ts, t_meas, ht.trans_le ?_⟩ + gcongr + exact (ContinuousLinearMap.le_opNorm_enorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) + +private lemma exists_one_le_enorm_apply_of_semivariation_eq_top + (hs : MeasurableSet s) (h's : μ.semivariation s = ∞) : + ∃ t, MeasurableSet t ∧ t ⊆ s ∧ μ.semivariation t = ∞ ∧ 1 ≤ ‖μ (s \ t)‖ₑ := by + obtain ⟨t, ts, t_meas, ht⟩ : ∃ t ⊆ s, MeasurableSet t ∧ 2 * ‖μ s‖ₑ + 2 < 2 * ‖μ t‖ₑ := by + apply exists_subset_lt_enorm_apply_of_lt_semivariation hs + rw [h's] + finiteness + have h't : 1 + ‖μ s‖ₑ ≤ ‖μ t‖ₑ := by + apply (ENNReal.mul_le_mul_iff_right (a := 2) (by simp) (by simp)).1 + rw [mul_add, add_comm, mul_one] + exact ht.le + have I : ∞ ≤ μ.semivariation t + μ.semivariation (s \ t) := by + rw [← h's] + apply le_trans (semivariation_mono (by simp)) semivariation_union_le + simp only [top_le_iff, ENNReal.add_eq_top] at I + rcases I with hI | hI + · refine ⟨t, t_meas, ts, hI, ?_⟩ + have : 1 + ‖μ s‖ₑ ≤ ‖μ (s \ t)‖ₑ + ‖μ s‖ₑ := by + apply h't.trans + have : μ t = μ s - μ (s \ t) := by rw [← of_add_of_sdiff t_meas hs ts]; abel + rw [this, add_comm] + exact enorm_sub_le + rwa [ENNReal.add_le_add_iff_right (by simp)] at this + · refine ⟨s \ t, hs.diff t_meas, sdiff_subset, hI, ?_⟩ + simp only [_root_.sdiff_sdiff_right_self, le_eq_subset, ts, inf_of_le_right] + exact le_trans (by simp) h't + +private lemma semivariation_univ_lt_top : μ.semivariation univ < ∞ := by + apply Ne.lt_top (fun h ↦ ?_) + have A (s : Set X) (hs : MeasurableSet s) (h's : μ.semivariation s = ∞) : + ∃ t, MeasurableSet t ∧ t ⊆ s ∧ μ.semivariation t = ∞ ∧ 1 ≤ ‖μ (s \ t)‖ₑ := + exists_one_le_enorm_apply_of_semivariation_eq_top hs h's + choose! t t_meas t_subs t_var ht using A + let s n := t^[n] univ + have hs n : MeasurableSet (s n) ∧ μ.semivariation (s n) = ∞ := by + induction n with + | zero => simp [s, h] + | succ n ih => + simp only [Function.iterate_succ', Function.comp_apply, s] + exact ⟨t_meas _ ih.1 ih.2, t_var _ ih.1 ih.2⟩ + let u n := s n \ s (n + 1) + have hu n : 1 ≤ ‖μ (u n)‖ₑ := by + simp only [Function.iterate_succ', Function.comp_apply, u, s] + exact ht _ (hs n).1 (hs n).2 + have s_anti : Antitone s := by + apply antitone_nat_of_succ_le (fun n ↦ ?_) + simp only [Function.iterate_succ', Function.comp_apply, s] + apply t_subs _ (hs n).1 (hs n).2 + have u_disj : Pairwise (Disjoint on u) := by + apply (pairwise_disjoint_on _).2 (fun m n hmn ↦ ?_) + have : Disjoint (u m) (s (m + 1)) := by simp [u, disjoint_sdiff_left] + apply this.mono_right + simp only [sdiff_le_iff, sup_eq_union, le_eq_subset, u] + exact Subset.trans (s_anti (by grind)) subset_union_right + have : HasSum (fun i => μ (u i)) (μ (⋃ i, u i)) := + hasSum_of_disjoint_iUnion (fun n ↦ (hs n).1.diff (hs (n + 1)).1) u_disj + have : Tendsto (fun x ↦ ‖μ (u x)‖ₑ) atTop (𝓝 0) := + tendsto_zero_iff_enorm_tendsto_zero.1 this.summable.tendsto_atTop_zero + obtain ⟨n, hn⟩ : ∃ n, ‖μ (u n)‖ₑ < 1 := ((tendsto_order.1 this).2 _ zero_lt_one).exists + order [hu n] + +variable (μ) in +/-- A constant bounding the norm of `μ s` for any set `s`. -/ +protected noncomputable def bound : ℝ≥0 := (μ.semivariation univ).toNNReal + +lemma semivariation_apply_le_bound : μ.semivariation s ≤ μ.bound := by + apply (semivariation_mono (subset_univ _)).trans_eq + simp only [VectorMeasure.bound] + rw [ENNReal.coe_toNNReal semivariation_univ_lt_top.ne] + +lemma enorm_apply_le_bound : ‖μ s‖ₑ ≤ μ.bound := + (enorm_apply_le_semivariation).trans semivariation_apply_le_bound + +lemma nnnorm_apply_le_bound : ‖μ s‖₊ ≤ μ.bound := by + rw [← ENNReal.coe_le_coe, ← enorm_eq_nnnorm] + exact enorm_apply_le_bound + +lemma norm_apply_le_bound : ‖μ s‖ ≤ μ.bound := by + simpa [← coe_nnnorm] using nnnorm_apply_le_bound + +end MeasureTheory.VectorMeasure diff --git a/Mathlib/Topology/UniformSpace/Dini.lean b/Mathlib/Topology/UniformSpace/Dini.lean index e5daead8c0747d..cd6fd6672de1b0 100644 --- a/Mathlib/Topology/UniformSpace/Dini.lean +++ b/Mathlib/Topology/UniformSpace/Dini.lean @@ -56,7 +56,7 @@ lemma tendstoLocallyUniformly_of_forall_tendsto refine (atTop : Filter ι).eq_or_neBot.elim (fun h ↦ ?eq_bot) (fun _ ↦ ?_) case eq_bot => simp [h, tendstoLocallyUniformly_iff_forall_tendsto] have F_le_f (x : α) (n : ι) : F n x ≤ f x := by - refine ge_of_tendsto (h_tendsto x) ?_ + refine _root_.ge_of_tendsto (h_tendsto x) ?_ filter_upwards [Ici_mem_atTop n] with m hnm exact hF_mono hnm x simp_rw [Metric.tendstoLocallyUniformly_iff, dist_eq_norm'] diff --git a/docs/references.bib b/docs/references.bib index 064ad6e45eed78..dc0ca63035b90c 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -1670,6 +1670,21 @@ @Book{ diamondshurman2005 zbl = {1062.11022} } +@Book{ DiestelUhl1977, + author = {Diestel, J. and Uhl, J. J. jun.}, + title = {Vector measures}, + fseries = {Mathematical Surveys}, + series = {Math. Surv.}, + issn = {0076-5376}, + volume = {15}, + year = {1977}, + publisher = {American Mathematical Society (AMS), Providence, RI}, + language = {English}, + keywords = {46G10,28B05,28A15,28A20,46-02,46B10,46B99,46E15,46E30,46G05,47A65,47B06,47B10,47B99}, + zbmath = {3576139}, + zbl = {0369.46039} +} + @Article{ dieudonne1953, author = {Dieudonn\'{e}, Jean}, title = {On semi-simple {L}ie algebras}, From a446e171c086e2f6c2f40fc811445b7acc4bd88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Renison?= <85908989+IvanRenison@users.noreply.github.com> Date: Fri, 19 Jun 2026 11:22:46 +0000 Subject: [PATCH 0174/1300] feat(Data/Fin): add several lemmas about subtraction of `Fin.{castLT, castAdd, castSucc, castPred}` (#35610) --- Mathlib/Data/Fin/Basic.lean | 15 ++++++++++++ Mathlib/Data/Fin/SuccPred.lean | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index e5e643bffb4319..344ac23ae0b0e3 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -84,6 +84,21 @@ lemma ne_zero_of_lt {a b : Fin (n + 1)} (hab : a < b) : b ≠ 0 := lemma ne_last_of_lt {a b : Fin (n + 1)} (hab : a < b) : a ≠ last n := Fin.ne_of_lt <| Fin.lt_of_lt_of_le hab b.le_last +lemma ne_last_of_ne_last_of_le {a b : Fin (n + 1)} (hb : b ≠ last n) (hab : a ≤ b) : + a ≠ last n := by + intro rfl + exact Nat.not_lt_of_le hab (lt_last_iff_ne_last.mpr hb) + +lemma val_sub_lt_of_lt_of_le {a b : Fin n} (ha : a.val < m) (hab : b ≤ a) : + (a - b).val < m := by + rw [Fin.sub_val_of_le hab] + exact sub_lt_of_lt ha + +lemma sub_ne_last_of_ne_last_of_le {a b : Fin (n + 1)} (ha : a ≠ last n) (hab : b ≤ a) : + a - b ≠ last n := by + rw [← lt_last_iff_ne_last, lt_def] + exact val_sub_lt_of_lt_of_le (val_lt_last ha) hab + /-- Equivalence between `Fin n` and `{ i // i < n }`. -/ @[simps apply symm_apply] def equivSubtype : Fin n ≃ { i // i < n } where diff --git a/Mathlib/Data/Fin/SuccPred.lean b/Mathlib/Data/Fin/SuccPred.lean index e3672dc3d438d9..99d0eb5599a338 100644 --- a/Mathlib/Data/Fin/SuccPred.lean +++ b/Mathlib/Data/Fin/SuccPred.lean @@ -264,6 +264,13 @@ theorem succ_castAdd (i : Fin n) : succ (castAdd m i) = theorem succ_natAdd (i : Fin m) : succ (natAdd n i) = natAdd n (succ i) := rfl +theorem sub_castAdd_eq_castAdd_sub_of_le {n : ℕ} {a b : Fin n} (h : b ≤ a) : + a.castAdd m - b.castAdd m = (a - b).castAdd m := by + grind [Fin.sub_val_of_le] + +theorem sub_castSucc_eq_castSucc_sub_of_le {n : ℕ} {a b : Fin n} (h : b ≤ a) : + a.castSucc - b.castSucc = (a - b).castSucc := sub_castAdd_eq_castAdd_sub_of_le h + end Succ section Pred @@ -457,6 +464,42 @@ theorem pred_lt_castPred {a : Fin (n + 1)} (h₁ : a ≠ 0) (h₂ : a ≠ last n pred a h₁ < castPred a h₂ := by rw [pred_lt_castPred_iff, le_def] +theorem val_sub_castLT_of_le {a b : Fin m} (ha : a.val < n) (h : b ≤ a) : + (a.castLT ha - b.castLT (lt_of_le_of_lt h ha)).val = (a - b).val := by + have : b.castLT (lt_of_le_of_lt h ha) ≤ a.castLT ha := by simpa [← val_fin_le] using h + simp [sub_val_of_le, h, this] + +theorem sub_castLT_eq_castLT_sub_of_le {a b : Fin m} (ha : a.val < n) (h : b ≤ a) : + a.castLT ha - b.castLT (lt_of_le_of_lt h ha) = + (a - b).castLT (val_sub_lt_of_lt_of_le ha h) := by + rw [Fin.ext_iff] + exact val_sub_castLT_of_le ha h + +theorem val_sub_castLT_of_lt {a b : Fin m} (hb : b < n) (h : a < b) : + (a.castLT (lt_trans h hb) - b.castLT hb).val = (a - b).val + n - m := by + simp only [val_sub, val_castLT] + repeat rw [Nat.mod_eq_of_lt (by omega)] + have h' : a.val < b.val := h + omega + +theorem val_sub_castPred_of_le {a b : Fin (n + 1)} (ha : a ≠ last n) + (h : b ≤ a) : + (a.castPred ha - b.castPred (ne_last_of_ne_last_of_le ha h)).val = (a - b).val := + val_sub_castLT_of_le (lt_last_iff_ne_last.mpr ha) h + +theorem sub_castPred_eq_castPred_sub_of_le {a b : Fin (n + 1)} (ha : a ≠ last n) + (h : b ≤ a) : + a.castPred ha - b.castPred (ne_last_of_ne_last_of_le ha h) = + (a - b).castPred (sub_ne_last_of_ne_last_of_le ha h) := + sub_castLT_eq_castLT_sub_of_le (lt_last_iff_ne_last.mpr ha) h + +theorem val_sub_castPred_of_ge {a b : Fin (n + 1)} (hb : b ≠ last n) + (h : a ≤ b) : + (a.castPred (ne_last_of_ne_last_of_le hb h) - b.castPred hb).val = (a - b).val - 1 := by + obtain (rfl | h') := Fin.eq_or_lt_of_le h + · simp [val_sub, Nat.sub_add_cancel a.is_le] + grind [castPred, val_sub_castLT_of_lt] + end CastPred section SuccAbove From f68433175a06e4ff891d592dd601564ce0fe7124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= <4094732+RemyDegenne@users.noreply.github.com> Date: Fri, 19 Jun 2026 11:22:48 +0000 Subject: [PATCH 0175/1300] feat(Probability): add `HasCondDistrib` (#40291) This PR adds a predicate that states that a random variable has a given conditional distribution given an other random variable. From Lean Machine Learning. Co-authored by: Paulo Rauber Co-authored-by: Remy Degenne --- Mathlib.lean | 1 + Mathlib/Probability/HasCondDistrib.lean | 124 ++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 Mathlib/Probability/HasCondDistrib.lean diff --git a/Mathlib.lean b/Mathlib.lean index 68d485cacf48e4..b04a0f888973c9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6249,6 +6249,7 @@ public import Mathlib.Probability.Distributions.Poisson.PoissonLimitThm public import Mathlib.Probability.Distributions.SetBernoulli public import Mathlib.Probability.Distributions.TwoValued public import Mathlib.Probability.Distributions.Uniform +public import Mathlib.Probability.HasCondDistrib public import Mathlib.Probability.HasLaw public import Mathlib.Probability.HasLawExists public import Mathlib.Probability.IdentDistrib diff --git a/Mathlib/Probability/HasCondDistrib.lean b/Mathlib/Probability/HasCondDistrib.lean new file mode 100644 index 00000000000000..b70e76eb7ace7b --- /dev/null +++ b/Mathlib/Probability/HasCondDistrib.lean @@ -0,0 +1,124 @@ +/- +Copyright (c) 2026 Rémy Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rémy Degenne, Paulo Rauber +-/ + +module + +public import Mathlib.Probability.HasLaw + +import Mathlib.Probability.Kernel.Composition.Lemmas + +/-! +# A predicate for having a specified conditional distribution + +We introduce a predicate `HasCondDistrib Y X κ P` stating that the conditional distribution of `Y` +given `X` under the measure `P` is equal to the kernel `κ`. +The statement uses `HasLaw` to express that the law of the pair `(X, Y)` under `P` is equal to +`(P.map X) ⊗ₘ κ`, the product of the law of `X` under `P` and the kernel `κ`. +The use of `HasLaw` also implies that `Y` and `X` are a.e. measurable. + +## Main definitions + +* `HasCondDistrib Y X κ P` : predicate stating that the conditional distribution of `Y` given `X` + under the measure `P` is equal to the kernel `κ`. + +-/ + +@[expose] public section + +open MeasureTheory + +namespace ProbabilityTheory + +variable {Ω 𝓧 𝓨 𝓩 : Type*} {mΩ : MeasurableSpace Ω} + {m𝓧 : MeasurableSpace 𝓧} {m𝓨 : MeasurableSpace 𝓨} {m𝓩 : MeasurableSpace 𝓩} + {P : Measure Ω} {X : Ω → 𝓧} {Y : Ω → 𝓨} {κ : Kernel 𝓧 𝓨} + +/-- Predicate stating that the conditional distribution of `Y` given `X` under the measure `P` +is equal to the kernel `κ`. -/ +def HasCondDistrib (Y : Ω → 𝓨) (X : Ω → 𝓧) (κ : Kernel 𝓧 𝓨) (P : Measure Ω) : Prop := + HasLaw (fun ω ↦ (X ω, Y ω)) ((P.map X) ⊗ₘ κ) P + +@[fun_prop] +lemma HasCondDistrib.aemeasurable_fst (h : HasCondDistrib Y X κ P) : + AEMeasurable X P := h.aemeasurable.fst + +@[fun_prop] +lemma HasCondDistrib.aemeasurable_snd (h : HasCondDistrib Y X κ P) : + AEMeasurable Y P := h.aemeasurable.snd + +lemma HasLaw.prodMk_of_hasCondDistrib {Q : Measure 𝓧} [IsSFiniteKernel κ] + (h1 : HasLaw X Q P) (h2 : HasCondDistrib Y X κ P) : + HasLaw (fun ω ↦ (X ω, Y ω)) (Q ⊗ₘ κ) P := by rwa [← h1.map_eq] + +lemma HasCondDistrib.hasLaw_of_const [IsProbabilityMeasure P] {Q : Measure 𝓨} [SFinite Q] + (h : HasCondDistrib Y X (Kernel.const 𝓧 Q) P) : + HasLaw Y Q P where + map_eq := by + have h_snd : (P.map (fun ω ↦ (X ω, Y ω))).snd = Q := by + rw [h.map_eq, Measure.snd_compProd] + simp [Measure.map_apply_of_aemeasurable h.aemeasurable_fst] + rwa [Measure.snd_map_prodMk₀ h.aemeasurable_fst] at h_snd + +variable [SFinite P] [IsSFiniteKernel κ] + +lemma HasCondDistrib.comp_left (h : HasCondDistrib Y X κ P) {f : 𝓨 → 𝓩} (hf : Measurable f) : + HasCondDistrib (f ∘ Y) X (κ.map f) P where + map_eq := calc + P.map (fun ω ↦ (X ω, f (Y ω))) + _ = (P.map (fun ω ↦ (X ω, Y ω))).map (Prod.map id f) := by + rw [AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] + congr + _ = (P.map X ⊗ₘ κ).map (Prod.map id f) := by rw [h.map_eq] + _ = P.map X ⊗ₘ κ.map f := by rw [Measure.compProd_map hf] + +lemma HasCondDistrib.fst {Y : Ω → 𝓨 × 𝓩} {κ : Kernel 𝓧 (𝓨 × 𝓩)} [IsSFiniteKernel κ] + (h : HasCondDistrib Y X κ P) : + HasCondDistrib (fun ω ↦ (Y ω).1) X κ.fst P := by + rw [Kernel.fst_eq] + exact h.comp_left measurable_fst + +lemma HasCondDistrib.snd {Y : Ω → 𝓨 × 𝓩} {κ : Kernel 𝓧 (𝓨 × 𝓩)} [IsSFiniteKernel κ] + (h : HasCondDistrib Y X κ P) : + HasCondDistrib (fun ω ↦ (Y ω).2) X κ.snd P := by + rw [Kernel.snd_eq] + exact h.comp_left measurable_snd + +lemma HasCondDistrib.comp_right {f : 𝓩 → 𝓧} + {hf : Measurable f} {Z : Ω → 𝓩} (h : HasCondDistrib Y Z (κ.comap f hf) P) : + HasCondDistrib Y (f ∘ Z) κ P where + map_eq := calc + P.map (fun a ↦ ((f ∘ Z) a, Y a)) + _ = (P.map (fun a ↦ (Z a, Y a))).map (Prod.map f id) := by + rw [AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] + rfl + _ = (P.map Z ⊗ₘ κ.comap f hf).map (Prod.map f id) := by rw [h.map_eq] + _ = (P.map Z).map f ⊗ₘ κ := by + ext s hs + rw [Measure.map_apply (by fun_prop) hs, Measure.compProd_apply (by measurability), + Measure.compProd_apply hs, lintegral_map (Kernel.measurable_kernel_prodMk_left hs) hf] + rfl + _ = P.map (f ∘ Z) ⊗ₘ κ := by + rw [AEMeasurable.map_map_of_aemeasurable hf.aemeasurable (by fun_prop)] + +lemma HasCondDistrib.measurableEquiv_comp_right (h : HasCondDistrib Y X κ P) (f : 𝓧 ≃ᵐ 𝓩) : + HasCondDistrib Y (f ∘ X) (κ.comap f.symm f.symm.measurable) P := by + apply HasCondDistrib.comp_right (hf := f.measurable) + simpa [← Kernel.comap_comp_right] + +lemma HasCondDistrib.of_compProd {Z : Ω → 𝓩} {η : Kernel (𝓧 × 𝓨) 𝓩} [IsMarkovKernel η] + (h : HasCondDistrib (fun a ↦ (Y a, Z a)) X (κ ⊗ₖ η) P) : + HasCondDistrib Z (fun a ↦ (X a, Y a)) η P := by + have hZ : AEMeasurable Z P := h.aemeasurable_snd.snd + have hY : AEMeasurable Y P := h.aemeasurable_snd.fst + refine ⟨by fun_prop, ?_⟩ + calc P.map (fun a ↦ ((X a, Y a), Z a)) + _ = (P.map X ⊗ₘ (κ ⊗ₖ η)).map MeasurableEquiv.prodAssoc.symm := by + rw [← h.map_eq, AEMeasurable.map_map_of_aemeasurable (by fun_prop) (by fun_prop)] + rfl + _ = P.map X ⊗ₘ κ ⊗ₘ η := Measure.compProd_assoc + _ = P.map (fun a ↦ (X a, Y a)) ⊗ₘ η := by simp [h.fst.map_eq] + +end ProbabilityTheory From 07f4b8dcd071cb3a38a57d99a505ec56667c6be4 Mon Sep 17 00:00:00 2001 From: Dennj Date: Fri, 19 Jun 2026 11:22:50 +0000 Subject: [PATCH 0176/1300] refactor(Analysis/Fourier/Convolution): drop continuity hypotheses from the convolution theorems (#40583) drop continuity hypotheses from the convolution theorems --- Mathlib/Analysis/Fourier/Convolution.lean | 75 ++++++------------- .../Analysis/Fourier/FourierTransform.lean | 2 +- 2 files changed, 23 insertions(+), 54 deletions(-) diff --git a/Mathlib/Analysis/Fourier/Convolution.lean b/Mathlib/Analysis/Fourier/Convolution.lean index b072ac2c74f100..72357bbda4f4af 100644 --- a/Mathlib/Analysis/Fourier/Convolution.lean +++ b/Mathlib/Analysis/Fourier/Convolution.lean @@ -41,26 +41,11 @@ variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] [InnerProductSpace ℝ E] [FiniteDimensional ℝ E] [MeasurableSpace E] [BorelSpace E] [NormedSpace 𝕜 F₁] [NormedSpace 𝕜 F₂] [NormedSpace 𝕜 F₃] -/-- The norm of the integrant of the convolution is integrable if the functions are integrable -and continuous. -/ +/-- The norm of the integrand of the convolution is integrable if the functions are integrable. -/ theorem integrable_prod_sub (B : F₁ →L[𝕜] F₂ →L[𝕜] F₃) {f₁ : E → F₁} {f₂ : E → F₂} - (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (hf₁' : Continuous f₁) (hf₂' : Continuous f₂) : + (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) : Integrable (fun (p : E × E) ↦ ‖B‖ * (‖f₁ (p.1 - p.2)‖ * ‖f₂ p.2‖)) (volume.prod volume) := by - apply Integrable.const_mul - rw [integrable_prod_iff' (by fun_prop)] - constructor - · filter_upwards with x - exact (hf₁.comp_sub_right x).norm.mul_const _ - have : Integrable (fun x ↦ ((∫ y, ‖f₁ y‖) * ‖f₂ x‖)) := by - apply hf₂.norm.bdd_mul (by fun_prop) (c := ‖(∫ y, ‖f₁ y‖)‖) - filter_upwards with; rfl - convert! this using 1 - ext x - simp_rw [norm_mul, norm_norm] - rw [integral_mul_const] - congr 1 - convert! integral_sub_right_eq_self _ x (μ := volume) - rfl + simpa [mul_comm] using (hf₂.norm.convolution_integrand (.mul ℝ ℝ) hf₁.norm).const_mul ‖B‖ open FourierTransform @@ -68,8 +53,7 @@ variable [NormedSpace ℂ F₃] /-- Calculate the Fourier transform of the convolution as a symmetric integral. -/ theorem fourier_bilin_convolution_eq_integral (B : F₁ →L[𝕜] F₂ →L[𝕜] F₃) {f₁ : E → F₁} {f₂ : E → F₂} - (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (hf₁' : Continuous f₁) (hf₂' : Continuous f₂) - (ξ : E) : + (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (ξ : E) : 𝓕 (f₁ ⋆[B] f₂) ξ = ∫ y, ∫ x, 𝐞 (-inner ℝ (y + x) ξ) • B (f₁ x) (f₂ y) := calc _ = 𝓕 (f₂ ⋆[B.flip] f₁) ξ := by rw [convolution_flip] @@ -80,11 +64,11 @@ theorem fourier_bilin_convolution_eq_integral (B : F₁ →L[𝕜] F₂ →L[ simp_rw [Circle.smul_def, integral_smul] _ = ∫ y, ∫ x, 𝐞 (-inner ℝ x ξ) • B (f₁ (x - y)) (f₂ y) := by refine integral_integral_swap ?_ - apply (integrable_prod_sub B hf₁ hf₂ hf₁' hf₂').mono (by measurability) - filter_upwards with ⟨y, x⟩ - have : ‖(B (f₁ (y - x))) (f₂ x)‖ ≤ ‖B‖ * (‖f₁ (y - x)‖ * ‖f₂ x‖) := by - grw [B.le_opNorm₂ (f₁ (y - x)) (f₂ x), mul_assoc] - simpa + have hB := hf₂.convolution_integrand B.flip hf₁ + refine hB.mono ?_ ?_ + · exact continuous_fourierChar.comp (by fun_prop) |>.aestronglyMeasurable.smul + hB.aestronglyMeasurable + · filter_upwards with ⟨x, y⟩ using by simp _ = ∫ y, ∫ x, 𝐞 (-inner ℝ (y + x) ξ) • B (f₁ x) (f₂ y) := by congr ext y @@ -101,31 +85,18 @@ open ContinuousLinearMap /-- The Fourier transform of the convolution is given by the bilinear map applied to the Fourier transform of the individual functions. -/ theorem fourier_bilin_convolution_eq (B : F₁ →L[ℂ] F₂ →L[ℂ] F₃) {f₁ : E → F₁} {f₂ : E → F₂} - (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (hf₁' : Continuous f₁) (hf₂' : Continuous f₂) - (ξ : E) : + (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (ξ : E) : 𝓕 (f₁ ⋆[B] f₂) ξ = B (𝓕 f₁ ξ) (𝓕 f₂ ξ) := calc _ = ∫ y, ∫ x, 𝐞 (-inner ℝ (y + x) ξ) • B (f₁ x) (f₂ y) := - fourier_bilin_convolution_eq_integral B hf₁ hf₂ hf₁' hf₂' _ + fourier_bilin_convolution_eq_integral B hf₁ hf₂ _ _ = ∫ y, ∫ x, 𝐞 (-inner ℝ y ξ) • 𝐞 (-inner ℝ x ξ) • B (f₁ x) (f₂ y) := by - congr - ext y - congr - ext x - rw [smul_smul, ← AddChar.map_add_eq_mul, inner_add_left] - congr - grind + simp_rw [inner_add_left, neg_add, AddChar.map_add_eq_mul, smul_smul] _ = ∫ y, (∫ x, B (𝐞 (-inner ℝ x ξ) • f₁ x)) (𝐞 (-inner ℝ y ξ) • f₂ y) := by - congr - ext y - simp_rw [Circle.smul_def, map_smul, MeasureTheory.integral_smul] - congr - rw [integral_apply ?_ (f₂ y)] - · simp - have : MeasureTheory.Integrable (fun x ↦ ‖B‖ * ‖f₁ x‖) MeasureTheory.volume := - hf₁.norm.const_mul _ - apply this.mono (by fun_prop) - filter_upwards with x - simpa [← Circle.smul_def] using le_opNorm B (f₁ x) + congr with y + have : Integrable (fun x ↦ (𝐞 (-inner ℝ x ξ) : ℂ) • B (f₁ x)) volume := by + simpa [Circle.smul_def] using + (Real.fourierIntegral_convergent_iff ξ).2 (B.integrable_comp hf₁) + simp [Circle.smul_def, MeasureTheory.integral_smul, integral_apply this (f₂ y)] _ = B (∫ x, 𝐞 (-inner ℝ x ξ) • f₁ x) (∫ y, 𝐞 (-inner ℝ y ξ) • f₂ y) := by rw [← integral_comp_comm _ (by simpa using hf₂), ← integral_comp_comm _ (by simpa using hf₁)] @@ -134,10 +105,9 @@ of the individual functions. Version for scalar multiplication. -/ theorem fourier_smul_convolution_eq {f₁ : E → ℂ} {f₂ : E → F₁} - (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (hf₁' : Continuous f₁) (hf₂' : Continuous f₂) - (ξ : E) : + (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (ξ : E) : 𝓕 (f₁ ⋆[lsmul ℂ ℂ] f₂) ξ = (𝓕 f₁ ξ) • (𝓕 f₂ ξ) := - fourier_bilin_convolution_eq (lsmul ℂ ℂ) hf₁ hf₂ hf₁' hf₂' ξ + fourier_bilin_convolution_eq (lsmul ℂ ℂ) hf₁ hf₂ ξ variable [NormedRing R] [NormedSpace ℂ R] [IsScalarTower ℂ R R] [SMulCommClass ℂ R R] [CompleteSpace R] @@ -147,10 +117,9 @@ of the individual functions. Version for multiplication. -/ theorem fourier_mul_convolution_eq {f₁ : E → R} {f₂ : E → R} - (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (hf₁' : Continuous f₁) (hf₂' : Continuous f₂) - (ξ : E) : + (hf₁ : Integrable f₁) (hf₂ : Integrable f₂) (ξ : E) : 𝓕 (f₁ ⋆[mul ℂ R] f₂) ξ = (𝓕 f₁ ξ) * (𝓕 f₂ ξ) := - fourier_bilin_convolution_eq (mul ℂ R) hf₁ hf₂ hf₁' hf₂' ξ + fourier_bilin_convolution_eq (mul ℂ R) hf₁ hf₂ ξ end Real @@ -198,7 +167,7 @@ open MeasureTheory theorem fourier_convolution_apply (B : F₁ →L[ℂ] F₂ →L[ℂ] F₃) (f : 𝓢(E, F₁)) (g : 𝓢(E, F₂)) (x : E) : 𝓕 (convolution B f g) x = 𝓕 (f ⋆[B] g) x := by simp [fourier_convolution, fourier_coe, - Real.fourier_bilin_convolution_eq B f.integrable g.integrable f.continuous g.continuous] + Real.fourier_bilin_convolution_eq B f.integrable g.integrable] /-- The convolution on Schwartz functions is equal to the convolution on functions. -/ theorem convolution_apply (B : F₁ →L[ℂ] F₂ →L[ℂ] F₃) (f : 𝓢(E, F₁)) (g : 𝓢(E, F₂)) (x : E) : diff --git a/Mathlib/Analysis/Fourier/FourierTransform.lean b/Mathlib/Analysis/Fourier/FourierTransform.lean index 7023f5af93e170..6e4d3c70e1a79f 100644 --- a/Mathlib/Analysis/Fourier/FourierTransform.lean +++ b/Mathlib/Analysis/Fourier/FourierTransform.lean @@ -177,7 +177,7 @@ section Fubini variable [TopologicalSpace 𝕜] [IsTopologicalRing 𝕜] [TopologicalSpace V] [BorelSpace V] [TopologicalSpace W] [MeasurableSpace W] [BorelSpace W] {e : AddChar 𝕜 𝕊} {μ : Measure V} {L : V →ₗ[𝕜] W →ₗ[𝕜] 𝕜} - {ν : Measure W} [SigmaFinite μ] [SigmaFinite ν] [SecondCountableTopology V] + {ν : Measure W} [SigmaFinite μ] [SigmaFinite ν] [SecondCountableTopologyEither W V] variable {σ : ℂ →+* ℂ} [RingHomIsometric σ] From 6d8c75573d90d8801f36d35f97b5165fe912fbfd Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Fri, 19 Jun 2026 12:19:41 +0000 Subject: [PATCH 0177/1300] =?UTF-8?q?feat(Topology):=20`=CF=80=E2=82=81(E?= =?UTF-8?q?=E2=A7=B8G)=20=E2=89=83*=20G`=20for=20`E`=20simply=20connected?= =?UTF-8?q?=20(#33108)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Oliver Nash Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- .../FundamentalGroupoid/FundamentalGroup.lean | 16 +- .../FundamentalGroupoid/SimplyConnected.lean | 2 +- Mathlib/Topology/Homotopy/Lifting.lean | 237 ++++++++++++++++-- 3 files changed, 221 insertions(+), 34 deletions(-) diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean index b65e9b431853f1..a4dd9abc9cce9c 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean @@ -32,17 +32,19 @@ variable (X) /-- The fundamental group is the automorphism group (vertex group) of the basepoint in the fundamental groupoid. -/ -def FundamentalGroup (x : X) := +abbrev FundamentalGroup (x : X) := End (FundamentalGroupoid.mk x) -instance (x : X) : Group (FundamentalGroup X x) := inferInstanceAs (Group (End _)) - -instance (x : X) : Inhabited (FundamentalGroup X x) := inferInstanceAs (Inhabited (End _)) - variable {X} namespace FundamentalGroup +variable {x : X} {p q : FundamentalGroup X x} + +theorem one_def : (1 : FundamentalGroup X x) = .refl x := rfl +theorem mul_def : p * q = q.trans p := rfl +theorem inv_def : p⁻¹ = p.symm := rfl + /-- Get an isomorphism between the fundamental groups at two points given a path -/ def fundamentalGroupMulEquivOfPath (p : Path x₀ x₁) : FundamentalGroup X x₀ ≃* FundamentalGroup X x₁ := @@ -84,8 +86,8 @@ variable (f : C(X, Y)) {x : X} {y : Y} (h : f x = y) def mapOfEq : FundamentalGroup X x →* FundamentalGroup Y y := (eqToIso <| congr_arg FundamentalGroupoid.mk h).conj.toMonoidHom.comp (map f x) -theorem mapOfEq_apply (p : Path x x) : - mapOfEq f h (fromPath <| .mk p) = fromPath (.mk <| (p.map f.continuous).cast h.symm h.symm) := +theorem mapOfEq_apply (p : FundamentalGroup X x) : + mapOfEq f h p = (Path.Homotopic.Quotient.map p f).cast h.symm h.symm := FundamentalGroupoid.conj_eqToHom .. end FundamentalGroup diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean index c22d642451c080..568422865c68c9 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean @@ -67,7 +67,7 @@ instance (x y : X) : Subsingleton (Path.Homotopic.Quotient x y) := rw [simply_connected_iff_unique_homotopic] at *; tauto)) instance (x : X) : Subsingleton (FundamentalGroup X x) := - show Subsingleton (Path.Homotopic.Quotient x x) from inferInstance + inferInstanceAs <| Subsingleton (Path.Homotopic.Quotient x x) instance (priority := 100) : PathConnectedSpace X := let unique_homotopic := (simply_connected_iff_unique_homotopic X).mp inferInstance diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index 1178bed0e81c2b..a98ee8d80d3032 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -8,7 +8,7 @@ module public import Mathlib.AlgebraicTopology.FundamentalGroupoid.FundamentalGroup public import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected public import Mathlib.Topology.Connected.LocPathConnected -public import Mathlib.Topology.Covering.Basic +public import Mathlib.Topology.Covering.Quotient public import Mathlib.Topology.Homotopy.Path public import Mathlib.Topology.UnitInterval @@ -26,9 +26,11 @@ public import Mathlib.Topology.UnitInterval arbitrary point). -/ +noncomputable section + @[expose] public section -open Topology unitInterval +open Function Topology unitInterval variable {E X A : Type*} [TopologicalSpace E] [TopologicalSpace X] [TopologicalSpace A] {p : E → X} @@ -101,7 +103,7 @@ theorem exists_lift_nhds {f : C(I × A, X)} {g : I × A → E} (g_lifts : p ∘ rw [if_pos this] -- here we use that {tₙ} × Nₙ₊₁ is mapped to the domain of `q e` apply (q e).injOn (by rwa [← ta.eta, ht]) ((q e).map_target this) - rw [(q e).right_inv this, ← hpq e]; exact congr_fun g'_lifts ta + rw [(q e).right_inv this, ← hpq e]; exact congr($g'_lifts ta) · rw [closure_le_eq continuous_fst continuous_const] at ht exact ⟨⟨hta.1.1, ht⟩, hta.2.2.1⟩ · simp_rw [not_le]; exact (ContinuousOn.congr ((q e).continuousOn_invFun.comp f.2.continuousOn @@ -109,14 +111,14 @@ theorem exists_lift_nhds {f : C(I × A, X)} {g : I × A → E} (g_lifts : p ∘ fun _ h ↦ if_pos <| huv ⟨hu ⟨h.2, h.1.1.2⟩, h.1.2.1⟩).mono (Set.inter_subset_inter_right _ <| closure_lt_subset_le continuous_const continuous_fst) · ext ta; rw [Function.comp_apply]; split_ifs with _ hv - · exact congr_fun g'_lifts ta + · exact congr($g'_lifts ta) · rw [hpq e, (q e).right_inv hv] - · exact congr_fun g_lifts ta + · exact congr($g_lifts ta) · rw [← g'_0]; exact if_pos bot_le · dsimp only; split_ifs with htn hf · exact g'_a t0 htn · apply (q e).injOn ((q e).map_target hf) (h_sub ⟨le_of_not_ge htn, htn1⟩) - rw [(q e).right_inv hf, ← hpq e]; exact (congr_fun g_lifts _).symm + rw [(q e).right_inv hf, ← hpq e]; exact congr($g_lifts _).symm · rfl variable (sep : IsSeparatedMap p) @@ -254,7 +256,7 @@ theorem exists_path_lifts : ∃ Γ : C(I, E), p ∘ Γ = γ ∧ Γ 0 = e := by · dsimp only; rwa [if_pos (t_0 ▸ t_mono n.zero_le)] /-- The lift of a path to a covering space given a lift of the left endpoint. -/ -noncomputable def liftPath : C(I, E) := (cov.exists_path_lifts γ e γ_0).choose +def liftPath : C(I, E) := (cov.exists_path_lifts γ e γ_0).choose lemma liftPath_lifts : p ∘ cov.liftPath γ e γ_0 = γ := (cov.exists_path_lifts γ e γ_0).choose_spec.1 lemma liftPath_zero : cov.liftPath γ e γ_0 0 = e := (cov.exists_path_lifts γ e γ_0).choose_spec.2 @@ -277,13 +279,13 @@ lemma liftPath_const {x : X} (hpe : x = p e) : cov.liftPath (.const I x) e hpe = lemma liftPath_trans {x y z : X} {e : E} (hpe : x = p e) (γ : Path x y) (γ' : Path y z) : letI Γ := cov.liftPath γ e (γ.source.trans hpe) cov.liftPath (γ.trans γ') e (by simpa) = (⟨Γ, liftPath_zero .., rfl⟩ : Path e (Γ 1)).trans - ⟨cov.liftPath γ' (Γ 1) (by simpa using (congr_fun (cov.liftPath_lifts γ ..) 1).symm), + ⟨cov.liftPath γ' (Γ 1) (by simpa using congr($(cov.liftPath_lifts γ ..) 1).symm), liftPath_zero .., rfl⟩ := by refine .symm <| (cov.eq_liftPath_iff' _).mpr ⟨funext fun _ ↦ ?_, by simp⟩ simp only [ContinuousMap.coe_coe, Function.comp_apply, Path.trans_apply]; split_ifs · exact congr_fun (cov.liftPath_lifts γ e (γ.source.trans hpe)) _ · refine congr_fun (cov.liftPath_lifts γ' _ ?_) _ - simpa using (congr_fun (cov.liftPath_lifts γ ..) 1).symm + simpa using congr($(cov.liftPath_lifts γ ..) 1).symm end path_lifting @@ -294,7 +296,7 @@ variable (H : C(I × A, X)) (f : C(A, E)) (H_0 : ∀ a, H (0, a) = p (f a)) the homotopy lifting property for covering maps. In other words, a covering map is a Hurewicz fibration. Proposition 1.30 of [hatcher02]. -/ -@[simps] noncomputable def liftHomotopy : C(I × A, E) where +@[simps] def liftHomotopy : C(I × A, E) where toFun ta := cov.liftPath (H.comp <| (ContinuousMap.id I).prodMk <| .const I ta.2) (f ta.2) (H_0 ta.2) ta.1 continuous_toFun := cov.isLocalHomeomorph.continuous_lift cov.isSeparatedMap H @@ -326,7 +328,7 @@ variable {f₀ f₁ : C(A, X)} {S : Set A} (F : f₀.HomotopyRel f₁ S) open ContinuousMap in /-- The lift to a covering space of a homotopy between two continuous maps relative to a set given compatible lifts of the continuous maps. -/ -noncomputable def liftHomotopyRel [PreconnectedSpace A] +def liftHomotopyRel [PreconnectedSpace A] {f₀' f₁' : C(A, E)} (he : ∃ a ∈ S, f₀' a = f₁' a) (h₀ : p ∘ f₀' = f₀) (h₁ : p ∘ f₁' = f₁) : f₀'.HomotopyRel f₁' S := have F_0 : ∀ a, F (0, a) = p (f₀' a) := fun a ↦ (F.apply_zero a).trans (congr_fun h₀ a).symm @@ -339,10 +341,10 @@ noncomputable def liftHomotopyRel [PreconnectedSpace A] map_zero_left := cov.liftHomotopy_zero F f₀' F_0 map_one_left := by obtain ⟨a, ha, he⟩ := he - simp_rw [toFun_eq_coe, ← curry_apply] + simp_rw [toFun_eq_coe, ← ContinuousMap.curry_apply] refine congr_fun (cov.eq_of_comp_eq (ContinuousMap.continuous _) f₁'.continuous ?_ a <| (rel 1 a ha).trans he) - ext a; rw [h₁, Function.comp_apply, curry_apply] + ext a; rw [h₁, Function.comp_apply, ContinuousMap.curry_apply] exact (congr_fun (cov.liftHomotopy_lifts F f₀' _) (1, a)).trans (F.apply_one a) prop' := rel } @@ -354,44 +356,90 @@ theorem homotopicRel_iff_comp [PreconnectedSpace A] {f₀ f₁ : C(A, E)} {S : S (ContinuousMap.comp ⟨p, cov.continuous⟩ f₀).HomotopicRel (.comp ⟨p, cov.continuous⟩ f₁) S := ⟨fun ⟨F⟩ ↦ ⟨F.compContinuousMap _⟩, fun ⟨F⟩ ↦ ⟨cov.liftHomotopyRel F he rfl rfl⟩⟩ +theorem homotopicRel_liftPath {γ₀ γ₁ : C(I, X)} + (h : γ₀.HomotopicRel γ₁ {0,1}) (e : E) (h₀ : γ₀ 0 = p e) (h₁ : γ₁ 0 = p e) : + (cov.liftPath γ₀ e h₀).HomotopicRel (cov.liftPath γ₁ e h₁) {0,1} := + h.map fun H ↦ cov.liftHomotopyRel (f₀' := cov.liftPath γ₀ e h₀) (f₁' := cov.liftPath γ₁ e h₁) H + ⟨0, .inl rfl, by simp_rw [liftPath_zero]⟩ (liftPath_lifts ..) (liftPath_lifts ..) + /-- Lifting two paths that are homotopic relative to `{0,1}` starting from the same point also ends up in the same point. -/ theorem liftPath_apply_one_eq_of_homotopicRel {γ₀ γ₁ : C(I, X)} (h : γ₀.HomotopicRel γ₁ {0,1}) (e : E) (h₀ : γ₀ 0 = p e) (h₁ : γ₁ 0 = p e) : cov.liftPath γ₀ e h₀ 1 = cov.liftPath γ₁ e h₁ 1 := by - obtain ⟨H⟩ := h - have := cov.liftHomotopyRel (f₀' := cov.liftPath γ₀ e h₀) (f₁' := cov.liftPath γ₁ e h₁) H - ⟨0, .inl rfl, by simp_rw [liftPath_zero]⟩ (liftPath_lifts ..) (liftPath_lifts ..) + have := (cov.homotopicRel_liftPath h e h₀ h₁).some rw [← this.eq_fst 0 (.inr rfl), ← this.eq_snd 0 (.inr rfl)] /-- The monodromy of a covering map `p : E → X`, which sends a lift of the starting point of a path in `X` to the endpoint of the lifted path in `E`. It only depends on the homotopy class of the path. -/ -noncomputable def monodromy {x y : X} (γ : Path.Homotopic.Quotient x y) : +def monodromy {x y : X} (γ : Path.Homotopic.Quotient x y) : p ⁻¹' {x} → p ⁻¹' {y} := fun e ↦ γ.lift (fun γ : Path x y ↦ ⟨cov.liftPath γ e (γ.source.trans e.2.symm) 1, - (congr_fun (cov.liftPath_lifts ..) 1).trans γ.target⟩) + congr($(cov.liftPath_lifts ..) 1).trans γ.target⟩) fun _ _ h ↦ Subtype.ext (cov.liftPath_apply_one_eq_of_homotopicRel h ..) +/-- Lift a homotopy class of paths to a covering space. -/ +def liftPathQuotient {x y : X} (γ : Path.Homotopic.Quotient x y) (e : p ⁻¹' {x}) : + Path.Homotopic.Quotient e.1 (cov.monodromy γ e) := + have he (γ : Path x y) : γ 0 = p (e : E) := by aesop + let g (γ : Path x y) : Path.Homotopic.Quotient (e : E) (cov.liftPath γ (e : E) (he γ) 1) := + .mk ⟨cov.liftPath γ (e : E) (he γ), cov.liftPath_zero .., rfl⟩ + let _i : Setoid (Path x y) := Path.Homotopic.setoid x y + have hg (γ γ' : Path x y) (hγ : γ ≈ γ') : g γ ≍ g γ' := by + refine .trans (heq_of_eq ?_) (Path.Homotopic.Quotient.cast_heq rfl + (cov.liftPath_apply_one_eq_of_homotopicRel hγ _ (he γ) _)) + rw [← Path.Homotopic.Quotient.mk_cast, Path.Homotopic.Quotient.eq] + exact cov.homotopicRel_liftPath hγ _ (by aesop) (by aesop) + γ.hrecOn g hg + +theorem map_liftPathQuotient {x y : X} (γ : Path.Homotopic.Quotient x y) (e : p ⁻¹' {x}) : + (cov.liftPathQuotient γ e).map ⟨p, cov.continuous⟩ = γ.cast e.2 (cov.monodromy γ e).2 := by + obtain ⟨γ⟩ := γ + refine congr_arg Path.Homotopic.Quotient.mk ?_ + ext1 + exact cov.liftPath_lifts _ _ (γ.source.trans e.2.symm) + theorem monodromy_map {x y : E} (γ : Path.Homotopic.Quotient x y) : cov.monodromy (γ.map ⟨p, cov.continuous⟩) ⟨x, rfl⟩ = ⟨y, rfl⟩ := Subtype.ext <| by obtain ⟨γ⟩ := γ - exact (DFunLike.congr_fun ((cov.eq_liftPath_iff' _).mpr ⟨rfl, γ.source⟩).symm 1).trans γ.target + exact congr($((cov.eq_liftPath_iff' _).mpr ⟨rfl, γ.source⟩) 1).symm.trans γ.target + +theorem monodromy_eq_of_map_eq {x y : X} {γ : Path.Homotopic.Quotient x y} + {ex : p ⁻¹' {x}} {ey : p ⁻¹' {y}} (Γ : Path.Homotopic.Quotient ex.1 ey) + (eq : Γ.map ⟨p, cov.continuous⟩ = γ.cast ex.2 ey.2) : + cov.monodromy γ ex = ey := by + convert ← cov.monodromy_map Γ + exacts [ey.2, ex.2, ey.2, by rw [eq]; exact γ.cast_heq .., ey.2] theorem monodromy_refl {x : X} : cov.monodromy (.refl x) = id := - funext fun e ↦ Subtype.ext <| DFunLike.congr_fun (cov.liftPath_const e.2.symm) 1 + funext fun e ↦ Subtype.ext congr($(cov.liftPath_const e.2.symm) 1) theorem monodromy_trans_apply {x y z : X} (γ : Path.Homotopic.Quotient x y) (γ' : Path.Homotopic.Quotient y z) (e) : cov.monodromy (γ.trans γ') e = cov.monodromy γ' (cov.monodromy γ e) := by obtain ⟨γ⟩ := γ; obtain ⟨γ'⟩ := γ' - exact Subtype.ext ((DFunLike.congr_fun (cov.liftPath_trans e.2.symm ..) 1).trans (Path.target _)) + exact Subtype.ext (congr($(cov.liftPath_trans e.2.symm ..) 1).trans (Path.target _)) + +/-- The monodromy action of the fundamental group at `x` on the fiber over `x`. -/ +@[reducible] def fundamentalGroupMulAction (x : X) : + MulAction (FundamentalGroup X x) (p ⁻¹' {x}) := + { smul := cov.monodromy (x := x) (y := x) + mul_smul _ _ _ := cov.monodromy_trans_apply .. + one_smul := congr_fun cov.monodromy_refl } + +/-- The monodromy action of the fundamental group at `x` on the fiber over `x`. -/ +def monodromyPerm (x : X) : FundamentalGroup X x →* Equiv.Perm (p ⁻¹' {x}) := + letI := cov.fundamentalGroupMulAction x + MulAction.toPermHom _ _ + +@[simp] theorem coe_monodromyPerm {x γ} : cov.monodromyPerm x γ = cov.monodromy γ := rfl open CategoryTheory /-- Monodromy of a covering map as a functor. Definition 2.1 in https://ncatlab.org/nlab/show/monodromy. -/ -@[simps] noncomputable def monodromyFunctor : FundamentalGroupoid X ⥤ Type _ where +@[simps] def monodromyFunctor : FundamentalGroupoid X ⥤ Type _ where obj x := p ⁻¹' {x.as} map f := ↾(cov.monodromy f) map_id _ := by ext x : 3; simpa using! congr_fun cov.monodromy_refl x @@ -404,7 +452,7 @@ theorem monodromy_bijective {x y : X} (γ : Path.Homotopic.Quotient x y) : /-- A covering map induces an injection on all Hom-sets of the fundamental groupoid, in particular on the fundamental group. The first part of Proposition 1.31 of [hatcher02]. -/ lemma injective_path_homotopic_map (e₀ e₁ : E) : - Function.Injective fun γ : Path.Homotopic.Quotient e₀ e₁ ↦ γ.map ⟨p, cov.continuous⟩ := by + Injective fun γ : Path.Homotopic.Quotient e₀ e₁ ↦ γ.map ⟨p, cov.continuous⟩ := by refine Quotient.ind₂ fun γ₀ γ₁ ↦ ?_ dsimp only simp only [Path.Homotopic.Quotient.mk''_eq_mk] @@ -459,10 +507,9 @@ theorem existsUnique_continuousMap_lifts_of_range_le conv_rhs => rw [← eq.2 ⟨.reflTransSymm _⟩, mk_refl, monodromy_refl] rw [Path.map_symm, ← Path.map_trans] set pγγ' : Path a₀ a₀ := pγ.trans pγ'.symm - have ⟨pΓΓ', eq⟩ := le ⟨fromPath (.mk pγγ'), rfl⟩ - obtain ⟨pΓΓ', rfl⟩ := mk_surjective pΓΓ' + obtain ⟨⟨pΓΓ'⟩, eq⟩ := le ⟨fromPath (.mk pγγ'), rfl⟩ rw [mapOfEq_apply, map_apply, ← mk_map] at eq - exact eq ▸ Subtype.ext (congr_arg (·.1) (cov.monodromy_map (.mk pΓΓ'))) + exact eq ▸ Subtype.ext congr($(cov.monodromy_map <| .mk _)) end homotopy_lifting @@ -496,3 +543,141 @@ theorem IsCoveringMapOn.existsUnique_continuousMap_lifts [SimplyConnectedSpace A ⟨Subtype.ext hF'₁, ?_⟩ · ext; simp [← hF'₂] · ext; simp [← hF_unique] + +namespace IsQuotientCoveringMap + +variable {G : Type*} [Group G] [MulAction G E] (hp : IsQuotientCoveringMap p G) {g : G} + +/-- The monodromy action of a quotient covering map commutes with the group action. -/ +theorem monodromy_toPermFiber {x y : X} {γ : Path.Homotopic.Quotient x y} {e : p ⁻¹' {x}} : + letI monodromy := hp.isCoveringMap.monodromy + monodromy γ (hp.toPermFiber x g e) = hp.toPermFiber y g (monodromy γ e) := + let Γ := hp.isCoveringMap.liftPathQuotient γ e + let g' : C(E, E) := ⟨_, hp.toContinuousConstSMul.continuous_const_smul g⟩ + let p' : C(E, X) := ⟨p, hp.continuous⟩ + have hgp : p'.comp g' = p' := by ext; simp [g', p', hp.map_smul] + hp.isCoveringMap.monodromy_eq_of_map_eq (Γ.map g') <| show (Γ.map g').map p' = _ by + rw [← Path.Homotopic.Quotient.map_comp] + convert hp.isCoveringMap.map_liftPathQuotient γ e using 2 + · simp [g', p', hp.map_smul] + · simp [g', p', hp.map_smul] + · grind + · grind + +theorem commute_monodromyPerm_toPermFiber {x : X} {γ : FundamentalGroup X x} : + Commute (hp.isCoveringMap.monodromyPerm x γ) (hp.toPermFiber x g) := by + ext; exact congr($hp.monodromy_toPermFiber) + +theorem monodromy_ext_iff {x y : X} {γ γ' : Path.Homotopic.Quotient x y} (e : p ⁻¹' {x}) : + letI monodromy := hp.isCoveringMap.monodromy + monodromy γ e = monodromy γ' e ↔ monodromy γ = monodromy γ' where + mp eq := by + ext e' + obtain ⟨g, rfl⟩ := hp.exists_toPermFiber_eq e e' + simp_rw [monodromy_toPermFiber, eq] + mpr := (congr_fun · _) + +alias ⟨monodromy_ext, _⟩ := monodromy_ext_iff + +variable {x : X} (e : p ⁻¹' {x}) {γ : FundamentalGroup X x} + +theorem monodromy_eq_id_iff : + hp.isCoveringMap.monodromy γ = id ↔ hp.isCoveringMap.monodromy γ e = e where + mp := (congr_fun · _) + mpr eq := (hp.monodromy_ext e (eq.trans congr($hp.isCoveringMap.monodromy_refl e).symm)).trans + hp.isCoveringMap.monodromy_refl + +theorem ker_monodromyPerm : + (hp.isCoveringMap.monodromyPerm x).ker = + (FundamentalGroup.mapOfEq ⟨p, hp.continuous⟩ e.2).range := by + ext γ; constructor <;> intro h + · refine ⟨(hp.isCoveringMap.liftPathQuotient γ e).cast rfl congr($h.symm e), ?_⟩ + rw [FundamentalGroup.mapOfEq_apply, + Path.Homotopic.Quotient.map_cast, IsCoveringMap.map_liftPathQuotient] + aesop + · obtain ⟨γ, rfl⟩ := h + refine DFunLike.ext' <| + (hp.monodromy_eq_id_iff e).mpr <| hp.isCoveringMap.monodromy_eq_of_map_eq γ ?_ + aesop (add simp FundamentalGroup.mapOfEq_apply) + +theorem monodromyPerm_injective [SimplyConnectedSpace E] : + Injective (hp.isCoveringMap.monodromyPerm x) := by + let e : p⁻¹' {x} := ⟨(hp.surjective x).choose, (hp.surjective x).choose_spec⟩ + rw [← MonoidHom.ker_eq_bot_iff, hp.ker_monodromyPerm e] + set f : FundamentalGroup E (e : E) →* FundamentalGroup X x := + FundamentalGroup.mapOfEq ⟨p, hp.continuous⟩ e.2 + have : Subsingleton f.range := (Set.subsingleton_coe _).mpr f.subsingleton_coe_range + exact Subgroup.eq_bot_of_subsingleton _ + +open MulOpposite in +/-- Choosing an arbitrary basepoint `e ∈ f ⁻¹' {x}` induces a bijection `f ⁻¹' {x} ≃ G`, and the +`G`-action on `f ⁻¹' {x}` corresponds to left multiplication. The monodromy action commutes +with the `G`-action, so each monodromy must corresponds must correspond to a right multiplication. +-/ +def fundamentalGroupToMulOpposite : FundamentalGroup X x →* Gᵐᵒᵖ where + toFun γ := op <| hp.fiberEquivGroup e (hp.isCoveringMap.monodromy γ e) + map_one' := by rw [FundamentalGroup.one_def, IsCoveringMap.monodromy_refl]; simp + map_mul' γ γ' := by + rw [FundamentalGroup.mul_def, IsCoveringMap.monodromy_trans_apply, ← op_mul, op_inj] + apply hp.isCancelSMul.right_cancel _ _ e.1 + simp_rw [mul_smul, fiberEquivGroup_smul_self, ← hp.toPermFiber_apply_apply_coe] + congr + refine .trans ?_ hp.monodromy_toPermFiber + congr + exact Subtype.ext (fiberEquivGroup_smul_self ..).symm + +variable {e} in +theorem fundamentalGroupToMulOpposite_apply_eq_Iff {g : Gᵐᵒᵖ} : + hp.fundamentalGroupToMulOpposite e γ = g ↔ g.unop • e.1 = hp.isCoveringMap.monodromy γ e := by + rw [fundamentalGroupToMulOpposite, ← MulOpposite.unop_injective.eq_iff, iff_comm, eq_comm, + ← hp.fiberEquivGroup_smul_self e] + have := hp.isCancelSMul.right_cancel' + aesop + +variable {e} in +theorem unop_fundamentalGroupToMulOpposite_smul : + (hp.fundamentalGroupToMulOpposite e γ).unop • e.1 = hp.isCoveringMap.monodromy γ e := by + simp [fundamentalGroupToMulOpposite, fiberEquivGroup_smul_self] + +variable {e} in +theorem fundamentalGroupToMulOpposite_eq_one_iff : + hp.fundamentalGroupToMulOpposite e γ = 1 ↔ hp.isCoveringMap.monodromy γ e = e where + mp h := Subtype.ext <| by rw [← hp.unop_fundamentalGroupToMulOpposite_smul, h]; apply one_smul + mpr h := MulOpposite.unop_injective <| hp.isCancelSMul.right_cancel _ _ e.1 <| by + simp [fundamentalGroupToMulOpposite, h] + +theorem ker_fundamentalGroupToMulOpposite : + (hp.fundamentalGroupToMulOpposite e).ker = (hp.isCoveringMap.monodromyPerm x).ker := by + ext; simp [fundamentalGroupToMulOpposite_eq_one_iff, DFunLike.ext'_iff, ← hp.monodromy_eq_id_iff] + +theorem fundamentalGroupToMulOpposite_surjective [PathConnectedSpace E] : + Surjective (hp.fundamentalGroupToMulOpposite e) := by + intro g + set e' : p⁻¹' {x} := ⟨MulOpposite.unop g • (e : E), by + have := hp.map_smul (e := e) (MulOpposite.unop g); aesop⟩ with he' + set Γ : Path (e : E) (e' : E) := + { toFun := PathConnectedSpace.somePath (e : E) (e' : E) + continuous_toFun := by fun_prop + source' := by simp + target' := by simp } + set γ : Path x x := (Γ.map hp.continuous).cast + (by simpa using e.property.symm) (by simpa using e'.property.symm) + use .fromPath ⟦γ⟧ + rw [fundamentalGroupToMulOpposite_apply_eq_Iff] + change (e' : E) = _ + rw [← hp.isCoveringMap.monodromy_eq_of_map_eq (γ := ⟦γ⟧) (Γ := ⟦Γ⟧) rfl] + +lemma fundamentalGroupToMulOpposite_injective [SimplyConnectedSpace E] : + Injective (hp.fundamentalGroupToMulOpposite e) := by + rw [← MonoidHom.ker_eq_bot_iff, ker_fundamentalGroupToMulOpposite, MonoidHom.ker_eq_bot_iff] + exact hp.monodromyPerm_injective + +/-- The fundamental group of the base of simply-connected covering map is contravariantly +equivalent to the group of the covering map. -/ +def fundamentalGroupEquiv [SimplyConnectedSpace E] : + FundamentalGroup X x ≃* Gᵐᵒᵖ := + MulEquiv.ofBijective (hp.fundamentalGroupToMulOpposite e) + ⟨hp.fundamentalGroupToMulOpposite_injective e, + hp.fundamentalGroupToMulOpposite_surjective e⟩ + +end IsQuotientCoveringMap From 7c309b0e29db78e07335916aa82148910b5689eb Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:19:43 +0000 Subject: [PATCH 0178/1300] feat(Projectivization/PSL/Stabilizer): Add stabilizer lemmas (#39999) --- Mathlib.lean | 1 + Mathlib/LinearAlgebra/Matrix/Action.lean | 3 + .../Projectivization/PSL/Stabilizer.lean | 142 ++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean diff --git a/Mathlib.lean b/Mathlib.lean index b04a0f888973c9..f2a1f9bc7ef3f4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5165,6 +5165,7 @@ public import Mathlib.LinearAlgebra.Projectivization.Cardinality public import Mathlib.LinearAlgebra.Projectivization.Collinear public import Mathlib.LinearAlgebra.Projectivization.Constructions public import Mathlib.LinearAlgebra.Projectivization.Independence +public import Mathlib.LinearAlgebra.Projectivization.PSL.Stabilizer public import Mathlib.LinearAlgebra.Projectivization.Subspace public import Mathlib.LinearAlgebra.QuadraticForm.AlgClosed public import Mathlib.LinearAlgebra.QuadraticForm.Basic diff --git a/Mathlib/LinearAlgebra/Matrix/Action.lean b/Mathlib/LinearAlgebra/Matrix/Action.lean index 0a432ad73fef8e..bf7e4f980e4f63 100644 --- a/Mathlib/LinearAlgebra/Matrix/Action.lean +++ b/Mathlib/LinearAlgebra/Matrix/Action.lean @@ -47,6 +47,9 @@ instance [DistribSMul S R] [SMulCommClass S R R] : SMulCommClass S (Matrix n n R instance [DistribSMul S R] [IsScalarTower S R R] : IsScalarTower S (Matrix n n R) (n → R) where smul_assoc := smul_mulVec +lemma ext_iff_smul {A B : Matrix n n R} : + A = B ↔ ∀ v : n → R, A • v = B • v := Matrix.ext_iff_mulVec + end mulVec /-! ## `*ᵥ` as a right-module -/ diff --git a/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean b/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean new file mode 100644 index 00000000000000..2201a9a390797c --- /dev/null +++ b/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean @@ -0,0 +1,142 @@ +/- +Copyright (c) 2026 Yunzhou Xie. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Edison Xie +-/ + +module + +public import Mathlib.LinearAlgebra.Projectivization.Action + +/-! +# Stabilizer of a line in PSL(n, F) +This file contains key constructions to prove that `PSL(n, F)` is simple via +showing it has an Iwasawa structure. + +## Main definitions + +* `Matrix.SpecialLinearGroup.lineStab` : the unipotent radical attached to a subspace `L ⊆ ι → F` + defined as the subgroup of `SL ι F` consisting of matrices `A` such that `A - 1` + sends every vector into `L`. + +* `PSL.iwasawaT` : the candidate family of subgroups for the Iwasawa structure on + `PSL ι F` acting on the projective space `ℙ F (ι → F)` from `Matrix.SpecialLinearGroup.lineStab`. + +-/ + +@[expose] public section + +variable {F : Type*} [Field F] {ι : Type*} [DecidableEq ι] [Fintype ι] + +/-- The "unipotent radical" attached to a subspace `L ⊆ ι → F`: the subgroup of +`SL ι F` consisting of matrices `A` such that `A - 1` sends every vector into `L`. +When `L` is one-dimensional this is an abelian subgroup of the stabilizer of `L` in `SL`. -/ +def Matrix.SpecialLinearGroup.lineStab (L : Submodule F (ι → F)) : + Subgroup (SpecialLinearGroup ι F) where + carrier := {A | ∀ w : ι → F, A • w - w ∈ L} + one_mem' := by simp + mul_mem' {A B} hA hB := fun w ↦ by + simp only [Set.mem_setOf_eq, mul_smul] at hA hB ⊢ + rw [show A • B • w - w = ((A • (B • w) - A • w) - (B • w - w)) + + (B • w - w) + (A • w - w) by abel, ← smul_sub] + exact add_mem (add_mem (hA _) (hB w)) (hA w) + inv_mem' {A} hA := fun w ↦ by + convert neg_mem (hA (A⁻¹ • w)) using 1 + rw [← mul_smul, mul_inv_cancel, one_smul, neg_sub] + +@[simp] +lemma Matrix.SpecialLinearGroup.mem_lineStab_iff (A : SpecialLinearGroup ι F) + (L : Submodule F (ι → F)) : A ∈ lineStab L ↔ ∀ w : ι → F, A • w - w ∈ L := + Iff.rfl + +open scoped LinearAlgebra.Projectivization + +/-- The candidate family of subgroups for the Iwasawa structure on +`PSL ι F` acting on the projective space `ℙ F (ι → F)`: the unipotent radical +attached to the line through `p`. -/ +noncomputable abbrev PSL.iwasawaT (p : ℙ F (ι → F)) : + Subgroup (Matrix.ProjectiveSpecialLinearGroup ι F) := + Subgroup.map (QuotientGroup.mk' _) + (Matrix.SpecialLinearGroup.lineStab p.submodule) + +open scoped Pointwise + +lemma PSL.smul_submodule (g : Matrix.SpecialLinearGroup ι F) (p : ℙ F (ι → F)) : + (g • p).submodule = g • p.submodule:= by + induction p using Projectivization.ind with | _ v hv => ?_ + simp [Submodule.ext_iff, Submodule.pointwise_smul_def, Submodule.mem_span_singleton, smul_comm] + +/-- Equivariance of `lineStab` under conjugation by elements of `SL`. -/ +lemma Matrix.SpecialLinearGroup.lineStab_smul + (g : Matrix.SpecialLinearGroup ι F) (L : Submodule F (ι → F)) : + Matrix.SpecialLinearGroup.lineStab (g • L) = + MulAut.conj g • Matrix.SpecialLinearGroup.lineStab L := by + ext A + rw [Subgroup.mem_pointwise_smul_iff_inv_smul_mem] + simp only [mem_lineStab_iff, Submodule.mem_smul_pointwise_iff_exists, MulAut.smul_def, + MulAut.inv_apply, MulAut.conj_symm_apply] + refine ⟨fun hA w ↦ ?_, fun hA w ↦ ⟨g⁻¹ • (A • w - w), ?_, by simp⟩⟩ + · obtain ⟨v, hv, hvw⟩ := hA (g • w) + simp_all [eq_comm (a := g • v), sub_eq_iff_eq_add, mul_smul] + · simpa [mul_smul, smul_sub] using hA (g⁻¹ • w) + +/-- The SL-level equivariance pushed through the quotient: the image in `PSL` of +the conjugate `MulAut.conj g_SL • H` equals `MulAut.conj (mk g_SL) • (image of H)`. -/ +lemma PSL.iwasawaT_map_conj (g : Matrix.SpecialLinearGroup ι F) + (H : Subgroup (Matrix.SpecialLinearGroup ι F)) : + Subgroup.map (QuotientGroup.mk' (Subgroup.center (Matrix.SpecialLinearGroup ι F))) + (MulAut.conj g • H) = + MulAut.conj (QuotientGroup.mk g : Matrix.ProjectiveSpecialLinearGroup ι F) • + Subgroup.map (QuotientGroup.mk' (Subgroup.center (Matrix.SpecialLinearGroup ι F))) H := by + ext x + simp only [Subgroup.mem_map, Subgroup.mem_pointwise_smul_iff_inv_smul_mem, + MulAut.smul_def, MulAut.inv_apply, MulAut.conj_symm_apply, QuotientGroup.mk'_apply] + exact ⟨fun ⟨a, ha, ha'⟩ ↦ ⟨g⁻¹ * a * g, ha, by simp [ha']⟩, + fun ⟨a, ha, hx⟩ ↦ ⟨g * a * g⁻¹, by simp [mul_assoc, ha], by simp [hx, mul_assoc]⟩⟩ + +private lemma LinearMap.exists_restrict_span_singleton_eq_smul_id + {R V : Type*} [CommSemiring R] [AddCommMonoid V] [Module R V] + {v : V} {A : V →ₗ[R] V} (hAv : A v ∈ Submodule.span R {v}) : + ∃ c : R, A v = c • v ∧ ∃ hcomap : Submodule.span R {v} ≤ (Submodule.span R {v}).comap A, + A.restrict hcomap = (c • LinearMap.id : Submodule.span R {v} →ₗ[R] _) := by + obtain ⟨c, hc⟩ := Submodule.mem_span_singleton.1 hAv + refine ⟨c, hc.symm, fun w hw ↦ ?_, LinearMap.ext fun ⟨w, hw⟩ ↦ ?_⟩ + <;> obtain ⟨a, rfl⟩ := Submodule.mem_span_singleton.1 hw + · simpa [Submodule.mem_comap, map_smul] using Submodule.smul_mem _ _ hAv + · simp [Subtype.ext_iff, ← hc, smul_comm a c v] + +lemma Matrix.SpecialLinearGroup.lineStab_fix_of_span + (v : ι → F) (hv : v ≠ 0) + (A : Matrix.SpecialLinearGroup ι F) + (hA : A ∈ lineStab (Submodule.span F {v})) : + A • v = v := by + set L : Submodule F (ι → F) := Submodule.span F {v} + obtain ⟨c, hcv, hcomap, hres⟩ := + LinearMap.exists_restrict_span_singleton_eq_smul_id (A := A.toLin'.toLinearMap) + (by simpa using! add_mem (hA v) (Submodule.mem_span_singleton_self v)) + have hQ : L.mapQ L A.toLin'.toLinearMap hcomap = LinearMap.id := LinearMap.ext fun x ↦ by + induction x using Submodule.Quotient.induction_on with + | _ w => simpa [Submodule.Quotient.eq] using! hA w + have hdet := A.toLin'.toLinearMap.det_eq_det_mul_det L hcomap + rw [show LinearMap.det A.toLin'.toLinearMap = 1 by simp [toLin'_to_linearMap], + hres, hQ, LinearMap.det_smul, finrank_span_singleton hv, pow_one, + LinearMap.det_id, LinearMap.det_id, mul_one, mul_one] at hdet + exact hcv.trans (hdet ▸ one_smul F v) + +/-- The subgroup `lineStab (span F {v})` is commutative when `v ≠ 0`. -/ +lemma Matrix.SpecialLinearGroup.lineStab_isMulCommutative_of_span' + (v : ι → F) (hv : v ≠ 0) (A B : SpecialLinearGroup ι F) + (hA : A ∈ SpecialLinearGroup.lineStab (Submodule.span F {v})) + (hB : B ∈ SpecialLinearGroup.lineStab (Submodule.span F {v})) : + A * B = B * A := by + refine Subtype.ext <| ext_iff_smul.2 fun w ↦ ?_ + obtain ⟨α, hα⟩ := Submodule.mem_span_singleton.mp (hA w) + obtain ⟨β, hβ⟩ := Submodule.mem_span_singleton.mp (hB w) + simp only [coe_mul, mul_smul, ← Matrix.SpecialLinearGroup.smul_def] + rw [← sub_add_cancel (A • w) w, ← hα, ← sub_add_cancel (B • w) w, + ← hβ, smul_add, smul_add, ← sub_left_inj (a := w), ← add_sub, ← hα, ← add_sub, ← hβ, + smul_comm, lineStab_fix_of_span v hv A hA, smul_comm, lineStab_fix_of_span v hv B hB, add_comm] + +lemma Matrix.SpecialLinearGroup.lineStab_isMulCommutative_of_span + (v : ι → F) (hv : v ≠ 0) : IsMulCommutative (lineStab (Submodule.span F {v})) := + ⟨⟨fun ⟨A, hA⟩ ⟨B, hB⟩ ↦ by simpa using lineStab_isMulCommutative_of_span' v hv A B hA hB⟩⟩ From 9158e203ca676281c73e395d6d295ad2552a3599 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:19:45 +0000 Subject: [PATCH 0179/1300] chore(Order/Northcott): use `TendstoCofinite` in `Northcott.lean` (#40778) This PR switches `comp_of_finite_fibers` to use the existing typeclass `Filter.TendstoCofinite`. Co-authored-by: tb65536 --- Mathlib/Order/Northcott.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Order/Northcott.lean b/Mathlib/Order/Northcott.lean index db31e98d3efd98..15eb5362b13d27 100644 --- a/Mathlib/Order/Northcott.lean +++ b/Mathlib/Order/Northcott.lean @@ -5,7 +5,7 @@ Authors: Thomas Browning -/ module -public import Mathlib.Order.Filter.Cofinite +public import Mathlib.Order.Filter.TendstoCofinite /-! # Northcott Functions @@ -62,10 +62,11 @@ lemma comp_of_bddAbove [Preorder β] [LE γ] [Northcott h] (H : ∀ c, BddAbove exact (finite_le (h := h) b).subset <| by grind /-- A composition `h' ∘ h` is Northcott when `h'` is Northcott and the fibers of `h` are finite. -/ -lemma comp_of_finite_fibers [LE γ] [Northcott h'] (H : ∀ b, (h ⁻¹' {b}).Finite) : +lemma comp_of_finite_fibers [LE γ] [Northcott h'] [Filter.TendstoCofinite h] : Northcott (h' ∘ h) where finite_le c := by - refine Set.Finite.of_finite_fibers h ?_ fun x _ ↦ (H x).inter_of_right _ + refine Set.Finite.of_finite_fibers h ?_ fun x _ ↦ + (Filter.TendstoCofinite.finite_preimage_singleton h x).inter_of_right _ exact (finite_le (h := h') c).subset <| by grind end Northcott From 555b02bc956f8a17a8dc95eb1131efda57d8b837 Mon Sep 17 00:00:00 2001 From: Mac Malone <9020483+tydeu@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:19:49 +0000 Subject: [PATCH 0180/1300] chore: prerequisite options for the Lake cache (#40784) This PR sets Lake options that are prerequisites for using the Lake cache (i.e., `lake cache`) but are also compatible with the current setup. It does not enable the local Lake artifact cache by default (e.g., `enableArtifactCache := true`), because the local cache is largely redundant with `lake exe cache get`. --- .github/workflows/lake_cache_shadow.yml | 16 ++++++---------- lake-manifest.json | 2 +- lakefile.lean | 6 ++++++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index b0b0491fe7f769..50ce19d3b21d59 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -186,12 +186,10 @@ jobs: from pathlib import Path p = Path("lakefile.lean") src = p.read_text() - marker = ' testDriver := "MathlibTest"' + marker = ' restoreAllArtifacts := true' inject = ( - ' testDriver := "MathlibTest"\n' - ' fixedToolchain := true\n' - ' enableArtifactCache := true\n' - ' restoreAllArtifacts := true' + ' restoreAllArtifacts := true\n' + ' enableArtifactCache := true' ) if marker not in src: raise SystemExit("lakefile.lean shape changed; update the shadow patch in lake_cache_shadow.yml") @@ -438,12 +436,10 @@ jobs: from pathlib import Path p = Path("lakefile.lean") src = p.read_text() - marker = ' testDriver := "MathlibTest"' + marker = ' restoreAllArtifacts := true' inject = ( - ' testDriver := "MathlibTest"\n' - ' fixedToolchain := true\n' - ' enableArtifactCache := true\n' - ' restoreAllArtifacts := true' + ' restoreAllArtifacts := true\n' + ' enableArtifactCache := true' ) if marker not in src: raise SystemExit("lakefile.lean shape changed") diff --git a/lake-manifest.json b/lake-manifest.json index 83a478e0413ecb..44a71cb13c5519 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -83,4 +83,4 @@ "configFile": "lakefile.toml"}], "name": "mathlib", "lakeDir": ".lake", - "fixedToolchain": false} + "fixedToolchain": true} diff --git a/lakefile.lean b/lakefile.lean index 46071184a166ee..a4808f93fdd2c0 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -50,6 +50,12 @@ package mathlib where testDriver := "MathlibTest" lintDriver := "batteries/runLinter" lintDriverArgs := #["Mathlib"] + -- A version of Mathlib only supports the toolchain it is built with. + fixedToolchain := true + -- Mathlib oleans are built on Linux CI and used across platforms. + platformIndependent := true + -- Mathlib currently expects artifacts to be in the build directory. + restoreAllArtifacts := true -- These are additional settings which do not affect the lake hash, -- so they can be enabled in CI and disabled locally or vice versa. -- Warning: Do not put any options here that actually change the olean files, From 63c85da758e583e0be796f43c133ae7529486a40 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Fri, 19 Jun 2026 13:16:42 +0000 Subject: [PATCH 0181/1300] chore: rename Pi.algHom to AlgHom.pi (#40044) --- Mathlib/Algebra/Algebra/Pi.lean | 43 +++++++++++++++---- Mathlib/Algebra/Polynomial/AlgebraMap.lean | 6 +-- Mathlib/AlgebraicGeometry/Morphisms/Flat.lean | 2 +- Mathlib/RingTheory/RingHom/QuasiFinite.lean | 2 +- Mathlib/RingTheory/Smooth/Pi.lean | 4 +- .../Spectrum/Maximal/Localization.lean | 2 +- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Pi.lean b/Mathlib/Algebra/Algebra/Pi.lean index 28037ee3dd8ca1..cf9e8606cde360 100644 --- a/Mathlib/Algebra/Algebra/Pi.lean +++ b/Mathlib/Algebra/Algebra/Pi.lean @@ -48,15 +48,41 @@ theorem algebraMap_def (a : R) : algebraMap R (Π i, A i) a = fun i ↦ algebraM theorem algebraMap_apply (a : R) (i : ι) : algebraMap R (Π i, A i) a i = algebraMap R (A i) a := rfl -variable {ι} (R) +variable {ι} -/-- A family of algebra homomorphisms `g i : B →ₐ[R] A i` defines a ring homomorphism -`Pi.algHom g : B →ₐ[R] Π i, A i` given by `Pi.algHom g x i = g i x`. -/ +variable {A} in +/-- A family of algebra homomorphisms `g i : B →ₐ[R] A i` defines an algebra homomorphism +`AlgHom.pi g : B →ₐ[R] Π i, A i` given by `AlgHom.pi g x i = g i x`. -/ @[simps!] -def algHom {B : Type*} [Semiring B] [Algebra R B] (g : ∀ i, B →ₐ[R] A i) : B →ₐ[R] Π i, A i where +def _root_.AlgHom.pi {B : Type*} [Semiring B] [Algebra R B] (g : Π i, B →ₐ[R] A i) : + B →ₐ[R] Π i, A i where __ := RingHom.pi fun i ↦ (g i).toRingHom commutes' r := by ext; simp +variable {A} in +/-- `AlgHom.pi` commutes with composition. -/ +theorem _root_.AlgHom.pi_comp {B C : Type*} [Semiring B] [Algebra R B] [Semiring C] [Algebra R C] + (g : ∀ i, C →ₐ[R] A i) (h : B →ₐ[R] C) : + (AlgHom.pi g).comp h = AlgHom.pi (fun i ↦ (g i).comp h) := rfl + +variable (R) + +/-- Use `AlgHom.pi` instead. -/ +@[deprecated AlgHom.pi (since := "2026-05-30")] +abbrev algHom {B : Type*} [Semiring B] [Algebra R B] (g : Π i, B →ₐ[R] A i) : B →ₐ[R] Π i, A i := + .pi g + +/-- Use `AlgHom.pi_apply` instead. -/ +@[deprecated AlgHom.pi_apply (since := "2026-05-30")] +theorem algHom_apply {B : Type*} [Semiring B] [Algebra R B] + (g : Π i, B →ₐ[R] A i) (x : B) (i : ι) : Pi.algHom R A g x i = g i x := + AlgHom.pi_apply g x i + +@[deprecated AlgHom.pi_comp (since := "2026-05-30")] +theorem algHom_comp {B C : Type*} [Semiring B] [Algebra R B] [Semiring C] [Algebra R C] + (g : ∀ i, C →ₐ[R] A i) (h : B →ₐ[R] C) : + (algHom R A g).comp h = algHom R A (fun i ↦ (g i).comp h) := rfl + /-- `Function.eval` as an `AlgHom`. The name matches `Pi.evalRingHom`, `Pi.evalMonoidHom`, etc. -/ @[simps] @@ -68,12 +94,11 @@ def evalAlgHom (i : ι) : (Π i, A i) →ₐ[R] A i := lemma coe_evalAlgHom (i : ι) : evalAlgHom R A i = evalRingHom A i := rfl @[simp] -theorem algHom_evalAlgHom : algHom R A (evalAlgHom R A) = AlgHom.id R (Π i, A i) := rfl +theorem _root_.AlgHom.pi_evalAlgHom : AlgHom.pi (evalAlgHom R A) = AlgHom.id R (Π i, A i) := + rfl -/-- `Pi.algHom` commutes with composition. -/ -theorem algHom_comp {B C : Type*} [Semiring B] [Algebra R B] [Semiring C] [Algebra R C] - (g : ∀ i, C →ₐ[R] A i) (h : B →ₐ[R] C) : - (algHom R A g).comp h = algHom R A (fun i ↦ (g i).comp h) := rfl +@[deprecated (since := "2026-06-03")] +alias algHom_evalAlgHom := _root_.AlgHom.pi_evalAlgHom variable (S : ι → Type*) [∀ i, CommSemiring (S i)] diff --git a/Mathlib/Algebra/Polynomial/AlgebraMap.lean b/Mathlib/Algebra/Polynomial/AlgebraMap.lean index 04d27fae9bcaaf..72b9002779afbb 100644 --- a/Mathlib/Algebra/Polynomial/AlgebraMap.lean +++ b/Mathlib/Algebra/Polynomial/AlgebraMap.lean @@ -456,12 +456,12 @@ variable (x : Π i, A i) (p : R[X]) /-- Polynomial evaluation on an indexed tuple is the indexed product of the evaluations on the components. Generalizes `Polynomial.aeval_prod` to indexed products. -/ -theorem aeval_pi (x : Π i, A i) : aeval (R := R) x = Pi.algHom R A (fun i ↦ aeval (x i)) := +theorem aeval_pi (x : Π i, A i) : aeval (R := R) x = AlgHom.pi (fun i ↦ aeval (x i)) := (funext fun i ↦ aeval_algHom (Pi.evalAlgHom R A i) x) ▸ - (Pi.algHom_comp R A (Pi.evalAlgHom R A) (aeval x)) + (AlgHom.pi_comp (Pi.evalAlgHom R A) (aeval x)) theorem aeval_pi_apply₂ (j : I) : p.aeval x j = p.aeval (x j) := - aeval_pi (R := R) x ▸ Pi.algHom_apply R A (fun i ↦ aeval (x i)) p j + aeval_pi (R := R) x ▸ AlgHom.pi_apply (fun i ↦ aeval (x i)) p j /-- Polynomial evaluation on an indexed tuple is the indexed tuple of the evaluations on the components. diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean index b8e5ffa0b1bd1b..095c53dd0d0a98 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean @@ -270,7 +270,7 @@ lemma mono_pushoutSection_of_iSup_eq {ι : Type*} [Finite ι] (VX : ι → X.Ope let ψY : Γ(Y, UY) →+* Π i, Γ(Y, g ⁻¹ᵁ VX i ⊓ iY ⁻¹ᵁ UT) := RingHom.pi fun i ↦ (Y.presheaf.map (homOfLE (by subst hUY hVU; gcongr; exact le_iSup _ _)).op).hom -- The map `Γ(X, U) ⟶ ∏ᵢ Γ(X, Vᵢ)` - let ψ : Γ(X, UX) →ₐ[Γ(S, US)] Π i, Γ(X, VX i) := Pi.algHom _ _ fun i ↦ + let ψ : Γ(X, UX) →ₐ[Γ(S, US)] Π i, Γ(X, VX i) := AlgHom.pi fun i ↦ ⟨(X.presheaf.map (homOfLE (hVU ▸ le_iSup VX i)).op).hom, fun r ↦ by dsimp [RingHom.algebraMap_toAlgebra] simp only [← CommRingCat.comp_apply, Scheme.Hom.appLE_map]⟩ diff --git a/Mathlib/RingTheory/RingHom/QuasiFinite.lean b/Mathlib/RingTheory/RingHom/QuasiFinite.lean index da49a14fd38f9d..0d711883d8668b 100644 --- a/Mathlib/RingTheory/RingHom/QuasiFinite.lean +++ b/Mathlib/RingTheory/RingHom/QuasiFinite.lean @@ -81,7 +81,7 @@ lemma QuasiFinite.ofLocalizationSpanTarget : OfLocalizationSpanTarget QuasiFinit let φ (r : s) : P.Fiber S →ₐ[P.ResidueField] P.Fiber (Localization.Away r.1) := Algebra.TensorProduct.map (.id _ _) (IsScalarTower.toAlgHom _ _ _) let f : P.Fiber S →ₐ[P.ResidueField] Π r : s, (P.Fiber (Localization.Away r.1)) := - Pi.algHom _ _ φ + AlgHom.pi φ have : IsNoetherian P.ResidueField (Π r : s, (P.Fiber (Localization.Away r.1))) := isNoetherian_of_isNoetherianRing_of_finite .. suffices Function.Injective f from .of_injective f.toLinearMap this diff --git a/Mathlib/RingTheory/Smooth/Pi.lean b/Mathlib/RingTheory/Smooth/Pi.lean index 117f16bd59492d..f4799e26092736 100644 --- a/Mathlib/RingTheory/Smooth/Pi.lean +++ b/Mathlib/RingTheory/Smooth/Pi.lean @@ -62,7 +62,7 @@ theorem pi_iff [Finite I] : fun _ ↦ Ideal.Quotient.mk_surjective _ replace he' : ∀ i, Ideal.Quotient.mk J (e i) = g (Pi.single i 1) := congr_fun he' let iso : B ≃ₐ[R] ∀ i, B ⧸ Ideal.span {1 - e i} := - { __ := Pi.algHom _ _ fun i ↦ Ideal.Quotient.mkₐ R _ + { __ := AlgHom.pi fun i ↦ Ideal.Quotient.mkₐ R _ __ := Equiv.ofBijective _ he.bijective_pi } let J' := fun i ↦ J.map (Ideal.Quotient.mk (Ideal.span {1 - e i})) let ι : ∀ i, (B ⧸ J →ₐ[R] (B ⧸ _) ⧸ J' i) := fun i ↦ Ideal.quotientMapₐ _ @@ -87,7 +87,7 @@ theorem pi_iff [Finite I] : (by rw [← Ideal.map_pow, hJ, Ideal.map_bot]) g' exact ⟨a, AlgHom.congr_fun ha⟩ choose a ha using this - use iso.symm.toAlgHom.comp (Pi.algHom _ _ fun i ↦ (a i).comp (Pi.evalAlgHom R A i)) + use iso.symm.toAlgHom.comp (AlgHom.pi fun i ↦ (a i).comp (Pi.evalAlgHom R A i)) ext x; rw [← AlgHom.toLinearMap_apply, ← AlgHom.toLinearMap_apply]; congr 1 ext i x simp only [AlgHom.comp_toLinearMap, AlgEquiv.toAlgHom_toLinearMap, diff --git a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean index 9bd2c7935bdd97..70e090dc94f605 100644 --- a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean +++ b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean @@ -174,7 +174,7 @@ theorem toPiLocalization_injective : Function.Injective (toPiLocalization R) := /-- The projection from the product of localizations at primes to the product of localizations at maximal ideals. -/ def piLocalizationToMaximal : PiLocalization R →ₐ[R] MaximalSpectrum.PiLocalization R := - Pi.algHom _ _ fun I ↦ Pi.evalAlgHom _ _ I.toPrimeSpectrum + AlgHom.pi fun I ↦ Pi.evalAlgHom _ _ I.toPrimeSpectrum open scoped Classical in theorem piLocalizationToMaximal_surjective : Function.Surjective (piLocalizationToMaximal R) := From 01469fac233f7969277e6f6c5e53f4d1bd018e75 Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:16:45 +0000 Subject: [PATCH 0182/1300] feat(Geometry/Manifold/Notation): add (d)elaborators for `UniqueMDiffOn` and `UniqueMDiffWithinAt` (#40748) This PR adds elaborators and delaborators for `UniqueMDiffOn` and `UniqueMDiffWithinAt`. The elaborators currently don't work for finding a model with corners on `TotalSpace`s since they don't provide `baseInfo`. This should hopefully be fixed by #40047. --- .../Geometry/Manifold/ContMDiffMFDeriv.lean | 13 ++-- Mathlib/Geometry/Manifold/Diffeomorph.lean | 6 +- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 4 +- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 77 ++++++++++--------- Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean | 6 +- .../Manifold/MFDeriv/NormedSpace.lean | 12 +-- .../Manifold/MFDeriv/SpecificFunctions.lean | 32 ++++---- .../Manifold/MFDeriv/UniqueDifferential.lean | 40 +++++----- Mathlib/Geometry/Manifold/Notation.lean | 39 ++++++++++ .../Manifold/VectorField/LieBracket.lean | 38 ++++----- .../Manifold/VectorField/Pullback.lean | 34 ++++---- .../DifferentialGeometry/Notation/Basic.lean | 65 ++++++++++++++++ .../Notation/Delaborators.lean | 16 ++++ 13 files changed, 251 insertions(+), 131 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index d5747cf0dbe93d..fae86ea50365d1 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -69,7 +69,7 @@ protected theorem ContMDiffWithinAt.mfderivWithin {x₀ : N} {f : N → M → M' {t : Set N} {u : Set M} (hf : CMDiffAt[t ×ˢ u] n (Function.uncurry f) (x₀, g x₀)) (hg : CMDiffAt[t] m g x₀) (hx₀ : x₀ ∈ t) - (hu : MapsTo g t u) (hmn : m + 1 ≤ n) (h'u : UniqueMDiffOn I u) : + (hu : MapsTo g t u) (hmn : m + 1 ≤ n) (h'u : UniqueMDiff[u]) : CMDiffAt[t] m (inTangentCoordinates I I' g (fun x ↦ f x (g x)) (fun x ↦ mfderiv[u] (f x) (g x)) x₀) x₀ := by -- first localize the result to a smaller set, to make sure everything happens in chart domains @@ -148,8 +148,7 @@ protected theorem ContMDiffWithinAt.mfderivWithin {x₀ : N} {f : N → M → M' apply nhdsWithin_mono _ ht't filter_upwards [h2f, h4f, h2g, self_mem_nhdsWithin] with x hx h'x h2 hxt have h1 : g x ∈ u := hu hxt - have h3 : UniqueMDiffWithinAt 𝓘(𝕜, E) - ((extChartAt I (g x₀)).target ∩ (extChartAt I (g x₀)).symm ⁻¹' u) + have h3 : UniqueMDiffAt[(extChartAt I (g x₀)).target ∩ (extChartAt I (g x₀)).symm ⁻¹' u] ((extChartAt I (g x₀)) (g x)) := by apply UniqueDiffWithinAt.uniqueMDiffWithinAt apply UniqueMDiffOn.uniqueDiffOn_target_inter h'u @@ -191,7 +190,7 @@ This is a special case of `ContMDiffWithinAt.mfderivWithin` where `f` does not c parameters and `g = id`. -/ theorem ContMDiffWithinAt.mfderivWithin_const {x₀ : M} {f : M → M'} - (hf : CMDiffAt[s] n f x₀) (hmn : m + 1 ≤ n) (hx : x₀ ∈ s) (hs : UniqueMDiffOn I s) : + (hf : CMDiffAt[s] n f x₀) (hmn : m + 1 ≤ n) (hx : x₀ ∈ s) (hs : UniqueMDiff[s]) : CMDiffAt[s] m (inTangentCoordinates I I' id f (mfderiv[s] f) x₀) x₀ := by have : CMDiffAt[s ×ˢ s] n (fun x : M × M ↦ f x.2) (x₀, x₀) := hf.comp (x₀, x₀) contMDiffWithinAt_snd mapsTo_snd_prod @@ -210,7 +209,7 @@ theorem ContMDiffWithinAt.mfderivWithin_apply {x₀ : N'} (hf : CMDiffAt[t ×ˢ u] n (Function.uncurry f) (g₁ x₀, g (g₁ x₀))) (hg : CMDiffAt[t] m g (g₁ x₀)) (hg₁ : CMDiffAt[v] m g₁ x₀) (hg₂ : CMDiffAt[v] m g₂ x₀) (hmn : m + 1 ≤ n) (h'g₁ : MapsTo g₁ v t) - (hg₁x₀ : g₁ x₀ ∈ t) (h'g : MapsTo g t u) (hu : UniqueMDiffOn I u) : + (hg₁x₀ : g₁ x₀ ∈ t) (h'g : MapsTo g t u) (hu : UniqueMDiff[u]) : CMDiffAt[v] m (fun x ↦ (inTangentCoordinates I I' g (fun x ↦ f x (g x)) (fun x ↦ mfderiv[u] (f x) (g x)) (g₁ x₀) (g₁ x)) (g₂ x)) x₀ := ((hf.mfderivWithin hg hg₁x₀ h'g hmn hu).comp_of_eq hg₁ h'g₁ rfl).clm_apply hg₂ @@ -273,7 +272,7 @@ variable [Is : IsManifold I 1 M] [I's : IsManifold I' 1 M'] /-- If a function is `C^n` on a domain with unique derivatives, then its bundled derivative is `C^m` when `m+1 ≤ n`. -/ theorem ContMDiffOn.contMDiffOn_tangentMapWithin - (hf : CMDiff[s] n f) (hmn : m + 1 ≤ n) (hs : UniqueMDiffOn I s) : + (hf : CMDiff[s] n f) (hmn : m + 1 ≤ n) (hs : UniqueMDiff[s]) : CMDiff[(π E (TangentSpace I) ⁻¹' s)] m (tangentMap[s] f) := by intro x₀ hx₀ let s' : Set (TangentBundle I M) := (π E (TangentSpace I) ⁻¹' s) @@ -298,7 +297,7 @@ theorem ContMDiffOn.contMDiffOn_tangentMapWithin /-- If a function is `C^n` on a domain with unique derivatives, with `1 ≤ n`, then its bundled derivative is continuous there. -/ theorem ContMDiffOn.continuousOn_tangentMapWithin (hf : CMDiff[s] n f) (hmn : 1 ≤ n) - (hs : UniqueMDiffOn I s) : + (hs : UniqueMDiff[s]) : ContinuousOn (tangentMap[s] f) (π E (TangentSpace I) ⁻¹' s) := by have : CMDiff[π E (TangentSpace I) ⁻¹' s] 0 (tangentMap[s] f) := hf.contMDiffOn_tangentMapWithin hmn hs diff --git a/Mathlib/Geometry/Manifold/Diffeomorph.lean b/Mathlib/Geometry/Manifold/Diffeomorph.lean index 0e6e6e8fc38027..f99ed00f458dd2 100644 --- a/Mathlib/Geometry/Manifold/Diffeomorph.lean +++ b/Mathlib/Geometry/Manifold/Diffeomorph.lean @@ -338,19 +338,19 @@ theorem toOpenPartialHomeomorph_mdifferentiable (h : M ≃ₘ^n⟮I, J⟯ N) (hn ⟨h.mdifferentiableOn _ hn, h.symm.mdifferentiableOn _ hn⟩ theorem uniqueMDiffOn_image_aux (h : M ≃ₘ^n⟮I, J⟯ N) (hn : n ≠ 0) {s : Set M} - (hs : UniqueMDiffOn I s) : UniqueMDiffOn J (h '' s) := by + (hs : UniqueMDiff[s]) : UniqueMDiff[h '' s] := by convert! hs.uniqueMDiffOn_preimage (h.toOpenPartialHomeomorph_mdifferentiable hn) simp [h.image_eq_preimage_symm] @[simp] theorem uniqueMDiffOn_image (h : M ≃ₘ^n⟮I, J⟯ N) (hn : n ≠ 0) {s : Set M} : - UniqueMDiffOn J (h '' s) ↔ UniqueMDiffOn I s := + UniqueMDiff[h '' s] ↔ UniqueMDiff[s] := ⟨fun hs => h.symm_image_image s ▸ h.symm.uniqueMDiffOn_image_aux hn hs, h.uniqueMDiffOn_image_aux hn⟩ @[simp] theorem uniqueMDiffOn_preimage (h : M ≃ₘ^n⟮I, J⟯ N) (hn : n ≠ 0) {s : Set N} : - UniqueMDiffOn I (h ⁻¹' s) ↔ UniqueMDiffOn J s := + UniqueMDiff[h ⁻¹' s] ↔ UniqueMDiff[s] := h.symm_image_eq_preimage s ▸ h.symm.uniqueMDiffOn_image hn @[simp] diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index 70a61d9b9c7dba..2b06e0a39ea983 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -269,7 +269,7 @@ lemma mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm {x : M} {y : E} (hy : y ∈ (extChartAt I x).target) : (mfderiv% (extChartAt I x) ((extChartAt I x).symm y)) ∘L (mfderiv[range I] (extChartAt I x).symm y) = ContinuousLinearMap.id _ _ := by - have U : UniqueMDiffWithinAt 𝓘(𝕜, E) (range ↑I) y := by + have U : UniqueMDiffAt[range I] y := by apply I.uniqueMDiffOn exact extChartAt_target_subset_range x hy have h'y : (extChartAt I x).symm y ∈ (extChartAt I x).source := (extChartAt I x).map_target hy @@ -306,7 +306,7 @@ lemma mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt have h'y : (extChartAt I x).symm y ∈ (extChartAt I x).source := (extChartAt I x).map_target hy have h''y : (extChartAt I x).symm y ∈ (chartAt H x).source := by rwa [← extChartAt_source (I := I)] - have U' : UniqueMDiffWithinAt I (extChartAt I x).source ((extChartAt I x).symm y) := + have U' : UniqueMDiffAt[(extChartAt I x).source] ((extChartAt I x).symm y) := (isOpen_extChartAt_source x).uniqueMDiffWithinAt h'y have : mfderiv% (extChartAt I x) ((extChartAt I x).symm y) = mfderiv[(extChartAt I x).source] (extChartAt I x) ((extChartAt I x).symm y) := by diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index b6b72c2c4f437f..c1c0e5ecbf1239 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.Calculus.TangentCone.Prod public import Mathlib.Geometry.Manifold.MFDeriv.Defs public import Mathlib.Geometry.Manifold.ContMDiff.Defs +import Mathlib.Geometry.Manifold.Notation /-! # Basic properties of the manifold Fréchet derivative @@ -49,7 +50,7 @@ variable {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] {f f₁ : M → M'} {x : M} {s t : Set M} {g : M' → M''} {u : Set M'} -theorem uniqueMDiffWithinAt_univ : UniqueMDiffWithinAt I univ x := by +theorem uniqueMDiffWithinAt_univ : UniqueMDiffAt[(univ : Set M)] x := by unfold UniqueMDiffWithinAt simp only [preimage_univ, univ_inter] exact I.uniqueDiffOn _ (mem_range_self _) @@ -57,57 +58,57 @@ theorem uniqueMDiffWithinAt_univ : UniqueMDiffWithinAt I univ x := by variable {I} theorem uniqueMDiffWithinAt_iff_inter_range {s : Set M} {x : M} : - UniqueMDiffWithinAt I s x ↔ + UniqueMDiffAt[s] x ↔ UniqueDiffWithinAt 𝕜 ((extChartAt I x).symm ⁻¹' s ∩ range I) ((extChartAt I x) x) := Iff.rfl theorem uniqueMDiffWithinAt_iff {s : Set M} {x : M} : - UniqueMDiffWithinAt I s x ↔ + UniqueMDiffAt[s] x ↔ UniqueDiffWithinAt 𝕜 ((extChartAt I x).symm ⁻¹' s ∩ (extChartAt I x).target) ((extChartAt I x) x) := by apply uniqueDiffWithinAt_congr rw [nhdsWithin_inter, nhdsWithin_inter, nhdsWithin_extChartAt_target_eq] -nonrec theorem UniqueMDiffWithinAt.mono_nhds {s t : Set M} {x : M} (hs : UniqueMDiffWithinAt I s x) - (ht : 𝓝[s] x ≤ 𝓝[t] x) : UniqueMDiffWithinAt I t x := +nonrec theorem UniqueMDiffWithinAt.mono_nhds {s t : Set M} {x : M} (hs : UniqueMDiffAt[s] x) + (ht : 𝓝[s] x ≤ 𝓝[t] x) : UniqueMDiffAt[t] x := hs.mono_nhds <| by simpa only [← map_extChartAt_nhdsWithin] using Filter.map_mono ht theorem UniqueMDiffWithinAt.mono_of_mem_nhdsWithin {s t : Set M} {x : M} - (hs : UniqueMDiffWithinAt I s x) (ht : t ∈ 𝓝[s] x) : UniqueMDiffWithinAt I t x := + (hs : UniqueMDiffAt[s] x) (ht : t ∈ 𝓝[s] x) : UniqueMDiffAt[t] x := hs.mono_nhds (nhdsWithin_le_iff.2 ht) -theorem UniqueMDiffWithinAt.mono (h : UniqueMDiffWithinAt I s x) (st : s ⊆ t) : - UniqueMDiffWithinAt I t x := +theorem UniqueMDiffWithinAt.mono (h : UniqueMDiffAt[s] x) (st : s ⊆ t) : + UniqueMDiffAt[t] x := UniqueDiffWithinAt.mono h <| inter_subset_inter (preimage_mono st) (Subset.refl _) -theorem UniqueMDiffWithinAt.inter' (hs : UniqueMDiffWithinAt I s x) (ht : t ∈ 𝓝[s] x) : - UniqueMDiffWithinAt I (s ∩ t) x := +theorem UniqueMDiffWithinAt.inter' (hs : UniqueMDiffAt[s] x) (ht : t ∈ 𝓝[s] x) : + UniqueMDiffAt[s ∩ t] x := hs.mono_of_mem_nhdsWithin (Filter.inter_mem self_mem_nhdsWithin ht) -theorem UniqueMDiffWithinAt.inter (hs : UniqueMDiffWithinAt I s x) (ht : t ∈ 𝓝 x) : - UniqueMDiffWithinAt I (s ∩ t) x := +theorem UniqueMDiffWithinAt.inter (hs : UniqueMDiffAt[s] x) (ht : t ∈ 𝓝 x) : + UniqueMDiffAt[s ∩ t] x := hs.inter' (nhdsWithin_le_nhds ht) -theorem IsOpen.uniqueMDiffWithinAt (hs : IsOpen s) (xs : x ∈ s) : UniqueMDiffWithinAt I s x := +theorem IsOpen.uniqueMDiffWithinAt (hs : IsOpen s) (xs : x ∈ s) : UniqueMDiffAt[s] x := (uniqueMDiffWithinAt_univ I).mono_of_mem_nhdsWithin <| nhdsWithin_le_nhds <| hs.mem_nhds xs -theorem UniqueMDiffOn.inter (hs : UniqueMDiffOn I s) (ht : IsOpen t) : UniqueMDiffOn I (s ∩ t) := +theorem UniqueMDiffOn.inter (hs : UniqueMDiff[s]) (ht : IsOpen t) : UniqueMDiff[s ∩ t] := fun _x hx => UniqueMDiffWithinAt.inter (hs _ hx.1) (ht.mem_nhds hx.2) -theorem IsOpen.uniqueMDiffOn (hs : IsOpen s) : UniqueMDiffOn I s := +theorem IsOpen.uniqueMDiffOn (hs : IsOpen s) : UniqueMDiff[s] := fun _x hx => hs.uniqueMDiffWithinAt hx -theorem uniqueMDiffOn_univ : UniqueMDiffOn I (univ : Set M) := +theorem uniqueMDiffOn_univ : UniqueMDiff[(univ : Set M)] := isOpen_univ.uniqueMDiffOn -nonrec theorem UniqueMDiffWithinAt.prod {x : M} {y : M'} {s t} (hs : UniqueMDiffWithinAt I s x) - (ht : UniqueMDiffWithinAt I' t y) : UniqueMDiffWithinAt (I.prod I') (s ×ˢ t) (x, y) := by +nonrec theorem UniqueMDiffWithinAt.prod {x : M} {y : M'} {s : Set M} {t : Set M'} + (hs : UniqueMDiffAt[s] x) (ht : UniqueMDiffAt[t] y) : UniqueMDiffAt[s ×ˢ t] (x, y) := by refine (hs.prod ht).mono ?_ rw [ModelWithCorners.range_prod, ← prod_inter_prod] rfl -theorem UniqueMDiffOn.prod {s : Set M} {t : Set M'} (hs : UniqueMDiffOn I s) - (ht : UniqueMDiffOn I' t) : UniqueMDiffOn (I.prod I') (s ×ˢ t) := fun x h ↦ +theorem UniqueMDiffOn.prod {s : Set M} {t : Set M'} (hs : UniqueMDiff[s]) + (ht : UniqueMDiff[t]) : UniqueMDiff[s ×ˢ t] := fun x h ↦ (hs x.1 h.1).prod (ht x.2 h.2) theorem MDifferentiableWithinAt.mono (hst : s ⊆ t) (h : MDifferentiableWithinAt I I' f t x) : @@ -517,12 +518,12 @@ variable {f' f₀' f₁' : TangentSpace I x →L[𝕜] TangentSpace I' (f x)} set_option backward.isDefEq.respectTransparency false in /-- `UniqueMDiffWithinAt` achieves its goal: it implies the uniqueness of the derivative. -/ -protected nonrec theorem UniqueMDiffWithinAt.eq (U : UniqueMDiffWithinAt I s x) +protected nonrec theorem UniqueMDiffWithinAt.eq (U : UniqueMDiffAt[s] x) (h : HasMFDerivWithinAt I I' f s x f') (h₁ : HasMFDerivWithinAt I I' f s x f₁') : f' = f₁' := by -- `by apply` because the instances can be found in the term but not in the goal. apply U.eq h.2 h₁.2 -protected theorem UniqueMDiffOn.eq (U : UniqueMDiffOn I s) (hx : x ∈ s) +protected theorem UniqueMDiffOn.eq (U : UniqueMDiff[s]) (hx : x ∈ s) (h : HasMFDerivWithinAt I I' f s x f') (h₁ : HasMFDerivWithinAt I I' f s x f₁') : f' = f₁' := UniqueMDiffWithinAt.eq (U _ hx) h h₁ @@ -685,7 +686,7 @@ protected theorem HasMFDerivAt.mfderiv (h : HasMFDerivAt I I' f x f') : mfderiv (hasMFDerivAt_unique h h.mdifferentiableAt.hasMFDerivAt).symm protected theorem HasMFDerivWithinAt.mfderivWithin (h : HasMFDerivWithinAt I I' f s x f') - (hxs : UniqueMDiffWithinAt I s x) : mfderivWithin I I' f s x = f' := by + (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I' f s x = f' := by ext rw [hxs.eq h h.mdifferentiableWithinAt.hasMFDerivWithinAt] @@ -698,11 +699,11 @@ theorem HasMFDerivWithinAt.mfderivWithin_eq_zero (h : HasMFDerivWithinAt I I' f exact h.2 theorem MDifferentiable.mfderivWithin (h : MDifferentiableAt I I' f x) - (hxs : UniqueMDiffWithinAt I s x) : mfderivWithin I I' f s x = mfderiv I I' f x := by + (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I' f s x = mfderiv I I' f x := by apply HasMFDerivWithinAt.mfderivWithin _ hxs exact h.hasMFDerivAt.hasMFDerivWithinAt -theorem mfderivWithin_subset (st : s ⊆ t) (hs : UniqueMDiffWithinAt I s x) +theorem mfderivWithin_subset (st : s ⊆ t) (hs : UniqueMDiffAt[s] x) (h : MDifferentiableWithinAt I I' f t x) : mfderivWithin I I' f s x = mfderivWithin I I' f t x := ((MDifferentiableWithinAt.hasMFDerivWithinAt h).mono st).mfderivWithin hs @@ -755,7 +756,7 @@ theorem hasMFDerivWithinAt_sdiff_singleton (y : M) : @[deprecated (since := "2026-06-03")] alias hasMFDerivWithinAt_diff_singleton := hasMFDerivWithinAt_sdiff_singleton -theorem mfderivWithin_eq_mfderiv (hs : UniqueMDiffWithinAt I s x) (h : MDifferentiableAt I I' f x) : +theorem mfderivWithin_eq_mfderiv (hs : UniqueMDiffAt[s] x) (h : MDifferentiableAt I I' f x) : mfderivWithin I I' f s x = mfderiv I I' f x := by rw [← mfderivWithin_univ] exact mfderivWithin_subset (subset_univ _) hs h.mdifferentiableWithinAt @@ -839,7 +840,7 @@ theorem HasMFDerivAt.continuousAt (h : HasMFDerivAt I I' f x f') : ContinuousAt h.1 theorem tangentMapWithin_subset {p : TangentBundle I M} (st : s ⊆ t) - (hs : UniqueMDiffWithinAt I s p.1) (h : MDifferentiableWithinAt I I' f t p.1) : + (hs : UniqueMDiffAt[s] p.1) (h : MDifferentiableWithinAt I I' f t p.1) : tangentMapWithin I I' f s p = tangentMapWithin I I' f t p := by simp only [tangentMapWithin, mfld_simps] rw [mfderivWithin_subset st hs h] @@ -848,7 +849,7 @@ theorem tangentMapWithin_univ : tangentMapWithin I I' f univ = tangentMap I I' f ext p : 1 simp only [tangentMapWithin, tangentMap, mfld_simps] -theorem tangentMapWithin_eq_tangentMap {p : TangentBundle I M} (hs : UniqueMDiffWithinAt I s p.1) +theorem tangentMapWithin_eq_tangentMap {p : TangentBundle I M} (hs : UniqueMDiffAt[s] p.1) (h : MDifferentiableAt I I' f p.1) : tangentMapWithin I I' f s p = tangentMap I I' f p := by rw [← mdifferentiableWithinAt_univ] at h rw [← tangentMapWithin_univ] @@ -1054,17 +1055,17 @@ theorem MDifferentiableAt.congr_of_eventuallyEq (h : MDifferentiableAt I I' f x) (h.hasMFDerivAt.congr_of_eventuallyEq hL).mdifferentiableAt theorem MDifferentiableWithinAt.mfderivWithin_congr_mono (h : MDifferentiableWithinAt I I' f s x) - (hs : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (hxt : UniqueMDiffWithinAt I t x) (h₁ : t ⊆ s) : + (hs : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (hxt : UniqueMDiffAt[t] x) (h₁ : t ⊆ s) : mfderivWithin I I' f₁ t x = mfderivWithin I I' f s x := (HasMFDerivWithinAt.congr_mono h.hasMFDerivWithinAt hs hx h₁).mfderivWithin hxt theorem MDifferentiableWithinAt.mfderivWithin_mono (h : MDifferentiableWithinAt I I' f s x) - (hxt : UniqueMDiffWithinAt I t x) (h₁ : t ⊆ s) : + (hxt : UniqueMDiffAt[t] x) (h₁ : t ⊆ s) : mfderivWithin I I' f t x = mfderivWithin I I' f s x := h.mfderivWithin_congr_mono (fun _ _ ↦ rfl) rfl hxt h₁ theorem MDifferentiableWithinAt.mfderivWithin_mono_of_mem_nhdsWithin - (h : MDifferentiableWithinAt I I' f s x) (hxt : UniqueMDiffWithinAt I t x) (h₁ : s ∈ 𝓝[t] x) : + (h : MDifferentiableWithinAt I I' f s x) (hxt : UniqueMDiffAt[t] x) (h₁ : s ∈ 𝓝[t] x) : mfderivWithin I I' f t x = mfderivWithin I I' f s x := (HasMFDerivWithinAt.mono_of_mem_nhdsWithin h.hasMFDerivWithinAt h₁).mfderivWithin hxt @@ -1207,14 +1208,14 @@ theorem MDifferentiableAt.comp_mdifferentiableWithinAt_of_eq {y : M'} subst hy; exact hg.comp_mdifferentiableWithinAt _ hf theorem mfderivWithin_comp (hg : MDifferentiableWithinAt I' I'' g u (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffWithinAt I s x) : + (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I'' (g ∘ f) s x = (mfderivWithin I' I'' g u (f x)).comp (mfderivWithin I I' f s x) := by apply HasMFDerivWithinAt.mfderivWithin _ hxs exact HasMFDerivWithinAt.comp x hg.hasMFDerivWithinAt hf.hasMFDerivWithinAt h theorem mfderivWithin_comp_of_eq {x : M} {y : M'} (hg : MDifferentiableWithinAt I' I'' g u y) - (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffWithinAt I s x) + (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : mfderivWithin I I'' (g ∘ f) s x = (mfderivWithin I' I'' g u y).comp (mfderivWithin I I' f s x) := by @@ -1223,7 +1224,7 @@ theorem mfderivWithin_comp_of_eq {x : M} {y : M'} (hg : MDifferentiableWithinAt theorem mfderivWithin_comp_of_preimage_mem_nhdsWithin (hg : MDifferentiableWithinAt I' I'' g u (f x)) (hf : MDifferentiableWithinAt I I' f s x) (h : f ⁻¹' u ∈ 𝓝[s] x) - (hxs : UniqueMDiffWithinAt I s x) : + (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I'' (g ∘ f) s x = (mfderivWithin I' I'' g u (f x)).comp (mfderivWithin I I' f s x) := by have A : s ∩ f ⁻¹' u ∈ 𝓝[s] x := Filter.inter_mem self_mem_nhdsWithin h @@ -1238,20 +1239,20 @@ theorem mfderivWithin_comp_of_preimage_mem_nhdsWithin theorem mfderivWithin_comp_of_preimage_mem_nhdsWithin_of_eq {y : M'} (hg : MDifferentiableWithinAt I' I'' g u y) (hf : MDifferentiableWithinAt I I' f s x) (h : f ⁻¹' u ∈ 𝓝[s] x) - (hxs : UniqueMDiffWithinAt I s x) (hy : f x = y) : + (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : mfderivWithin I I'' (g ∘ f) s x = (mfderivWithin I' I'' g u y).comp (mfderivWithin I I' f s x) := by subst hy; exact mfderivWithin_comp_of_preimage_mem_nhdsWithin _ hg hf h hxs theorem mfderiv_comp_mfderivWithin (hg : MDifferentiableAt I' I'' g (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (hxs : UniqueMDiffWithinAt I s x) : + (hf : MDifferentiableWithinAt I I' f s x) (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I'' (g ∘ f) s x = (mfderiv I' I'' g (f x)).comp (mfderivWithin I I' f s x) := by rw [← mfderivWithin_univ] exact mfderivWithin_comp _ hg.mdifferentiableWithinAt hf (by simp) hxs theorem mfderiv_comp_mfderivWithin_of_eq {x : M} {y : M'} (hg : MDifferentiableAt I' I'' g y) - (hf : MDifferentiableWithinAt I I' f s x) (hxs : UniqueMDiffWithinAt I s x) (hy : f x = y) : + (hf : MDifferentiableWithinAt I I' f s x) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : mfderivWithin I I'' (g ∘ f) s x = (mfderiv I' I'' g y).comp (mfderivWithin I I' f s x) := by subst hy; exact mfderiv_comp_mfderivWithin x hg hf hxs @@ -1291,7 +1292,7 @@ theorem MDifferentiable.comp (hg : MDifferentiable I' I'' g) (hf : MDifferentiab theorem tangentMapWithin_comp_at (p : TangentBundle I M) (hg : MDifferentiableWithinAt I' I'' g u (f p.1)) (hf : MDifferentiableWithinAt I I' f s p.1) - (h : s ⊆ f ⁻¹' u) (hps : UniqueMDiffWithinAt I s p.1) : + (h : s ⊆ f ⁻¹' u) (hps : UniqueMDiffAt[s] p.1) : tangentMapWithin I I'' (g ∘ f) s p = tangentMapWithin I' I'' g u (tangentMapWithin I I' f s p) := by simp only [tangentMapWithin, mfld_simps] diff --git a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean index 453ec2e412a4a7..ad87a847c3abef 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean @@ -29,19 +29,19 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCom section MFDerivFDeriv theorem uniqueMDiffWithinAt_iff_uniqueDiffWithinAt : - UniqueMDiffWithinAt 𝓘(𝕜, E) s x ↔ UniqueDiffWithinAt 𝕜 s x := by + UniqueMDiffAt[s] x ↔ UniqueDiffWithinAt 𝕜 s x := by simp only [UniqueMDiffWithinAt, mfld_simps] alias ⟨UniqueMDiffWithinAt.uniqueDiffWithinAt, UniqueDiffWithinAt.uniqueMDiffWithinAt⟩ := uniqueMDiffWithinAt_iff_uniqueDiffWithinAt -theorem uniqueMDiffOn_iff_uniqueDiffOn : UniqueMDiffOn 𝓘(𝕜, E) s ↔ UniqueDiffOn 𝕜 s := by +theorem uniqueMDiffOn_iff_uniqueDiffOn : UniqueMDiff[s] ↔ UniqueDiffOn 𝕜 s := by simp [UniqueMDiffOn, UniqueDiffOn, uniqueMDiffWithinAt_iff_uniqueDiffWithinAt] alias ⟨UniqueMDiffOn.uniqueDiffOn, UniqueDiffOn.uniqueMDiffOn⟩ := uniqueMDiffOn_iff_uniqueDiffOn theorem ModelWithCorners.uniqueMDiffOn {H : Type*} [TopologicalSpace H] - (I : ModelWithCorners 𝕜 E H) : UniqueMDiffOn 𝓘(𝕜, E) (Set.range I) := + (I : ModelWithCorners 𝕜 E H) : UniqueMDiff[Set.range I] := I.uniqueDiffOn.uniqueMDiffOn @[simp, mfld_simps] diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 0cc8f598e3708b..1329b9ab42ef3b 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -486,27 +486,27 @@ lemma mvfderivWithin_const (c : F) {x : M} : d[s] (fun _ : M ↦ c) x = 0 := by @[simp, to_fun mvfderivWithin_fun_add] lemma mvfderivWithin_add {g g' : M → F} {x : M} - (hg : MDiffAt[s] g x) (hg' : MDiffAt[s] g' x) (hs : UniqueMDiffWithinAt I s x) : + (hg : MDiffAt[s] g x) (hg' : MDiffAt[s] g' x) (hs : UniqueMDiffAt[s] x) : d[s](g + g') x = d[s]g x + d[s]g' x := by simp [mvfderivWithin, mfderivWithin_add hg hg' hs] rfl @[simp, to_fun mvfderivWithin_fun_sub] lemma mvfderivWithin_sub {g g' : M → F} {x : M} - (hg : MDiffAt[s] g x) (hg' : MDiffAt[s] g' x) (hs : UniqueMDiffWithinAt I s x) : + (hg : MDiffAt[s] g x) (hg' : MDiffAt[s] g' x) (hs : UniqueMDiffAt[s] x) : d[s](g - g') x = d[s]g x - d[s]g' x := by simp [mvfderivWithin, mfderivWithin_sub hg hg' hs] rfl @[simp, to_fun mvfderivWithin_fun_neg] -lemma mvfderivWithin_neg {g : M → F} {x : M} (hs : UniqueMDiffWithinAt I s x) : +lemma mvfderivWithin_neg {g : M → F} {x : M} (hs : UniqueMDiffAt[s] x) : d[s](-g) x = -d[s]g x := by simp [mvfderivWithin, mfderivWithin_neg hs] rfl @[simp, to_fun mvfderivWithin_fun_smul] lemma mvfderivWithin_smul {a : M → 𝕜} (ha : MDiffAt[s] a x) {g : M → F} (hg : MDiffAt[s] g x) - (hs : UniqueMDiffWithinAt I s x) : + (hs : UniqueMDiffAt[s] x) : d[s](a • g) x = a x • d[s] g x + (d[s] a x).smulRight (g x) := by refine HasMFDerivWithinAt.mfderivWithin ⟨ha.1.smul hg.1, ?_⟩ hs @@ -516,14 +516,14 @@ lemma mvfderivWithin_smul {a : M → 𝕜} (ha : MDiffAt[s] a x) {g : M → F} ( @[simp, to_fun mvfderivWithin_fun_mul] lemma mvfderivWithin_mul {f g : M → 𝕜} {x : M} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) - (hs : UniqueMDiffWithinAt I s x) : + (hs : UniqueMDiffAt[s] x) : d[s](f * g) x = f x • d[s]g x + (g x) • (d[s]f x) := by convert! mvfderivWithin_smul hf hg hs ext v simp [mul_comm] @[simp] -lemma mvfderivWithin_zero {s : Set M} (hs : UniqueMDiffWithinAt I s x) : +lemma mvfderivWithin_zero {s : Set M} (hs : UniqueMDiffAt[s] x) : d[s] (0 : M → F) x = 0 := by have : d[s] (0 : M → F) x + d[s] (0 : M → F) x = d[s] (0 : M → F) x := by rw [← mvfderivWithin_add (by exact mdifferentiableWithinAt_const) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 60b917645a0878..1ab6f3612e7c95 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -83,7 +83,7 @@ protected theorem mdifferentiable : MDiff f := theorem mfderiv_eq : mfderiv% f x = f := f.hasMFDerivAt.mfderiv -theorem mfderivWithin_eq (hs : UniqueMDiffWithinAt 𝓘(𝕜, E) s x) : mfderiv[s] f x = f := +theorem mfderivWithin_eq (hs : UniqueMDiffAt[s] x) : mfderiv[s] f x = f := f.hasMFDerivWithinAt.mfderivWithin hs end ContinuousLinearMap @@ -113,7 +113,7 @@ protected theorem mdifferentiable : MDiff f := theorem mfderiv_eq : mfderiv% f x = (f : E →L[𝕜] E') := f.hasMFDerivAt.mfderiv -theorem mfderivWithin_eq (hs : UniqueMDiffWithinAt 𝓘(𝕜, E) s x) : +theorem mfderivWithin_eq (hs : UniqueMDiffAt[s] x) : mfderiv[s] f x = (f : E →L[𝕜] E') := f.hasMFDerivWithinAt.mfderivWithin hs @@ -153,7 +153,7 @@ theorem mdifferentiableOn_id : MDiff[s] (@id M) := theorem mfderiv_id : mfderiv% (@id M) x = ContinuousLinearMap.id 𝕜 (TangentSpace% x) := (hasMFDerivAt_id x).mfderiv -theorem mfderivWithin_id (hxs : UniqueMDiffWithinAt I s x) : +theorem mfderivWithin_id (hxs : UniqueMDiffAt[s] x) : mfderiv[s] (@id M) x = ContinuousLinearMap.id 𝕜 (TangentSpace% x) := by rw [MDifferentiable.mfderivWithin mdifferentiableAt_id hxs] exact mfderiv_id @@ -162,7 +162,7 @@ set_option backward.isDefEq.respectTransparency false in @[simp, mfld_simps] theorem tangentMap_id : tangentMap% (@id M) = id := by ext1 ⟨x, v⟩; simp [tangentMap] -theorem tangentMapWithin_id {p : TangentBundle I M} (hs : UniqueMDiffWithinAt I s p.proj) : +theorem tangentMapWithin_id {p : TangentBundle I M} (hs : UniqueMDiffAt[s] p.proj) : tangentMap[s] (id : M → M) p = p := by simp only [tangentMapWithin, id] rw [mfderivWithin_id] @@ -227,7 +227,7 @@ theorem HasMFDerivWithinAt.prodMk {f : M → M'} {g : M → M''} ⟨hf.1.prodMk hg.1, hf.2.prodMk hg.2⟩ lemma mfderivWithin_prodMk {f : M → M'} {g : M → M''} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) - (hs : UniqueMDiffWithinAt I s x) : + (hs : UniqueMDiffAt[s] x) : mfderiv[s] (fun x ↦ (f x, g x)) x = (mfderiv[s] f x).prod (mfderiv[s] g x) := (hf.hasMFDerivWithinAt.prodMk hg.hasMFDerivWithinAt).mfderivWithin hs @@ -316,7 +316,7 @@ theorem mfderiv_fst {x : M × M'} : (hasMFDerivAt_fst x).mfderiv theorem mfderivWithin_fst {s : Set (M × M')} {x : M × M'} - (hxs : UniqueMDiffWithinAt (I.prod I') s x) : + (hxs : UniqueMDiffAt[s] x) : mfderiv[s] (@Prod.fst M M') x = ContinuousLinearMap.fst 𝕜 (TangentSpace% x.1) (TangentSpace% x.2) := by rw [MDifferentiable.mfderivWithin mdifferentiableAt_fst hxs]; exact mfderiv_fst @@ -327,7 +327,7 @@ theorem tangentMap_prodFst {p : TangentBundle (I.prod I') (M × M')} : simp [tangentMap]; rfl theorem tangentMapWithin_prodFst {s : Set (M × M')} {p : TangentBundle (I.prod I') (M × M')} - (hs : UniqueMDiffWithinAt (I.prod I') s p.proj) : + (hs : UniqueMDiffAt[s] p.proj) : tangentMap[s] (@Prod.fst M M') p = ⟨p.proj.1, p.2.1⟩ := by simp only [tangentMapWithin] rw [mfderivWithin_fst] @@ -375,7 +375,7 @@ theorem mfderiv_snd {x : M × M'} : (hasMFDerivAt_snd x).mfderiv theorem mfderivWithin_snd {s : Set (M × M')} {x : M × M'} - (hxs : UniqueMDiffWithinAt (I.prod I') s x) : + (hxs : UniqueMDiffAt[s] x) : mfderiv[s] (@Prod.snd M M') x = ContinuousLinearMap.snd 𝕜 (TangentSpace% x.1) (TangentSpace% x.2) := by rw [MDifferentiable.mfderivWithin mdifferentiableAt_snd hxs]; exact mfderiv_snd @@ -516,7 +516,7 @@ lemma HasMFDerivAt.prodMap {p : M × M'} {f : M → N} {g : M' → N'} -- could be a strict superset of `s`. lemma mfderivWithin_prodMap {p : M × M'} {t : Set M'} {f : M → N} {g : M' → N'} (hf : MDiffAt[s] f p.1) (hg : MDiffAt[t] g p.2) - (hs : UniqueMDiffWithinAt I s p.1) (ht : UniqueMDiffWithinAt I' t p.2) : + (hs : UniqueMDiffAt[s] p.1) (ht : UniqueMDiffAt[t] p.2) : mfderiv[s ×ˢ t] (Prod.map f g) p = (mfderiv[s] f p.1).prodMap (mfderiv[t] g p.2) := by have hf' : HasMFDerivAt[Prod.fst '' s ×ˢ t] f p.1 (mfderiv[s] f p.1) := hf.hasMFDerivWithinAt.mono (by grind) @@ -539,7 +539,7 @@ theorem tangentMap_prodSnd {p : TangentBundle (I.prod I') (M × M')} : simp [tangentMap]; rfl theorem tangentMapWithin_prodSnd {s : Set (M × M')} {p : TangentBundle (I.prod I') (M × M')} - (hs : UniqueMDiffWithinAt (I.prod I') s p.proj) : + (hs : UniqueMDiffAt[s] p.proj) : tangentMap[s] (@Prod.snd M M') p = ⟨p.proj.2, p.2.2⟩ := by simp only [tangentMapWithin] rw [mfderivWithin_snd hs] @@ -671,7 +671,7 @@ theorem hasMFDerivAt_sumSwap : cases p <;> simp @[simp] -theorem mfderivWithin_sumSwap {s : Set (M ⊕ M')} (hs : UniqueMDiffWithinAt I s p) : +theorem mfderivWithin_sumSwap {s : Set (M ⊕ M')} (hs : UniqueMDiffAt[s] p) : mfderiv[s] (@Sum.swap M M') p = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := hasMFDerivAt_sumSwap.hasMFDerivWithinAt.mfderivWithin hs @@ -732,7 +732,7 @@ theorem hasMFDerivAt_inr : HasMFDerivAt% (@Sum.inr M M') q' (ContinuousLinearMap.id 𝕜 (TangentSpace% p)) := by simpa [HasMFDerivAt, hasMFDerivWithinAt_univ] using! hasMFDerivWithinAt_inr (t := Set.univ) -theorem mfderivWithin_sumInl (hU : UniqueMDiffWithinAt I s q) : +theorem mfderivWithin_sumInl (hU : UniqueMDiffAt[s] q) : mfderiv[s] (@Sum.inl M M') q = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := hasMFDerivWithinAt_inl.mfderivWithin hU @@ -740,7 +740,7 @@ theorem mfderiv_sumInl : mfderiv% (@Sum.inl M M') q = ContinuousLinearMap.id 𝕜 (TangentSpace% p) := by simpa [mfderivWithin_univ] using (mfderivWithin_sumInl (uniqueMDiffWithinAt_univ I)) -theorem mfderivWithin_sumInr {t : Set M'} (hU : UniqueMDiffWithinAt I t q') : +theorem mfderivWithin_sumInr {t : Set M'} (hU : UniqueMDiffAt[t] q') : mfderiv[t] (@Sum.inr M M') q' = ContinuousLinearMap.id 𝕜 (TangentSpace% q') := hasMFDerivWithinAt_inr.mfderivWithin hU @@ -794,7 +794,7 @@ theorem mfderiv_add (hf : MDiffAt f z) (hg : MDiffAt g z) : (hf.hasMFDerivAt.add hg.hasMFDerivAt).mfderiv theorem mfderivWithin_add (hf : MDiffAt[s] f z) (hg : MDiffAt[s] g z) - (hs : UniqueMDiffWithinAt I s z) : + (hs : UniqueMDiffAt[s] z) : (mfderiv[s] (f + g) z : TangentSpace% z →L[𝕜] E') = (by exact mfderiv[s] f z) + (by exact mfderiv[s] g z) := (hf.hasMFDerivWithinAt.add hg.hasMFDerivWithinAt).mfderivWithin hs @@ -881,7 +881,7 @@ theorem mdifferentiableAt_neg : MDiffAt (-f) z ↔ MDiffAt f z := theorem MDifferentiable.neg (hf : MDiff f) : MDiff (-f) := fun x ↦ (hf x).neg set_option backward.isDefEq.respectTransparency false in -theorem mfderivWithin_neg (hs : UniqueMDiffWithinAt I s x) : +theorem mfderivWithin_neg (hs : UniqueMDiffAt[s] x) : mfderiv[s] (-f) x = -mfderiv[s] f x := by simp_rw [mfderivWithin] by_cases hf : MDiffAt[s] f x @@ -914,7 +914,7 @@ theorem MDifferentiable.sub (hf : MDiff f) (hg : MDiff g) : MDiff (f - g) := fun x ↦ (hf x).sub (hg x) theorem mfderivWithin_sub (hf : MDiffAt[s] f z) (hg : MDiffAt[s] g z) - (hs : UniqueMDiffWithinAt I s z) : + (hs : UniqueMDiffAt[s] z) : (mfderiv[s] (f - g) z : TangentSpace% z →L[𝕜] E') = (by exact mfderiv[s] f z) - (by exact mfderiv[s] g z) := (hf.hasMFDerivWithinAt.sub hg.hasMFDerivWithinAt).mfderivWithin hs diff --git a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean index 87483b86150d63..3e0ad20b32c3a2 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean @@ -45,9 +45,9 @@ section /-- If `s` has the unique differential property at `x`, `f` is differentiable within `s` at `x` and its derivative has dense range, then `f '' s` has the unique differential property at `f x`. -/ -theorem UniqueMDiffWithinAt.image_denseRange (hs : UniqueMDiffWithinAt I s x) +theorem UniqueMDiffWithinAt.image_denseRange (hs : UniqueMDiffAt[s] x) {f : M → M'} {f' : E →L[𝕜] E'} (hf : HasMFDerivAt[s] f x f') - (hd : DenseRange f') : UniqueMDiffWithinAt I' (f '' s) (f x) := by + (hd : DenseRange f') : UniqueMDiffAt[f '' s] (f x) := by /- Rewrite in coordinates, apply `HasFDerivWithinAt.uniqueDiffWithinAt`. -/ have := hs.inter' <| hf.1 (extChartAt_source_mem_nhds (I := I') (f x)) refine (((hf.2.mono ?sub1).uniqueDiffWithinAt this hd).mono ?sub2).congr_pt ?pt @@ -60,22 +60,22 @@ theorem UniqueMDiffWithinAt.image_denseRange (hs : UniqueMDiffWithinAt I s x) /-- If `s` has the unique differential property, `f` is differentiable on `s` and its derivative at every point of `s` has dense range, then `f '' s` has the unique differential property. This version uses the `HasMFDerivWithinAt` predicate. -/ -theorem UniqueMDiffOn.image_denseRange' (hs : UniqueMDiffOn I s) {f : M → M'} +theorem UniqueMDiffOn.image_denseRange' (hs : UniqueMDiff[s]) {f : M → M'} {f' : M → E →L[𝕜] E'} (hf : ∀ x ∈ s, HasMFDerivAt[s] f x (f' x)) (hd : ∀ x ∈ s, DenseRange (f' x)) : - UniqueMDiffOn I' (f '' s) := + UniqueMDiff[f '' s] := forall_mem_image.2 fun x hx ↦ (hs x hx).image_denseRange (hf x hx) (hd x hx) /-- If `s` has the unique differential property, `f` is differentiable on `s` and its derivative at every point of `s` has dense range, then `f '' s` has the unique differential property. -/ -theorem UniqueMDiffOn.image_denseRange (hs : UniqueMDiffOn I s) {f : M → M'} +theorem UniqueMDiffOn.image_denseRange (hs : UniqueMDiff[s]) {f : M → M'} (hf : MDiff[s] f) (hd : ∀ x ∈ s, DenseRange (mfderiv[s] f x)) : - UniqueMDiffOn I' (f '' s) := + UniqueMDiff[f '' s] := hs.image_denseRange' (fun x hx ↦ (hf x hx).hasMFDerivWithinAt) hd protected theorem UniqueMDiffWithinAt.preimage_openPartialHomeomorph - (hs : UniqueMDiffWithinAt I s x) {e : OpenPartialHomeomorph M M'} (he : e.MDifferentiable I I') - (hx : x ∈ e.source) : UniqueMDiffWithinAt I' (e.target ∩ e.symm ⁻¹' s) (e x) := by + (hs : UniqueMDiffAt[s] x) {e : OpenPartialHomeomorph M M'} (he : e.MDifferentiable I I') + (hx : x ∈ e.source) : UniqueMDiffAt[e.target ∩ e.symm ⁻¹' s] (e x) := by rw [← e.image_source_inter_eq', inter_comm] exact (hs.inter (e.open_source.mem_nhds hx)).image_denseRange (he.mdifferentiableAt hx).hasMFDerivAt.hasMFDerivWithinAt @@ -83,16 +83,16 @@ protected theorem UniqueMDiffWithinAt.preimage_openPartialHomeomorph /-- If a set has the unique differential property, then its image under a local diffeomorphism also has the unique differential property. -/ -theorem UniqueMDiffOn.uniqueMDiffOn_preimage (hs : UniqueMDiffOn I s) +theorem UniqueMDiffOn.uniqueMDiffOn_preimage (hs : UniqueMDiff[s]) {e : OpenPartialHomeomorph M M'} (he : e.MDifferentiable I I') : - UniqueMDiffOn I' (e.target ∩ e.symm ⁻¹' s) := fun _x hx ↦ + UniqueMDiff[e.target ∩ e.symm ⁻¹' s] := fun _x hx ↦ e.right_inv hx.1 ▸ (hs _ hx.2).preimage_openPartialHomeomorph he (e.map_target hx.1) variable [IsManifold I 1 M] in /-- If a set in a manifold has the unique derivative property, then its pullback by any extended chart, in the vector space, also has the unique derivative property. -/ -theorem UniqueMDiffOn.uniqueMDiffOn_target_inter (hs : UniqueMDiffOn I s) (x : M) : - UniqueMDiffOn 𝓘(𝕜, E) ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) := by +theorem UniqueMDiffOn.uniqueMDiffOn_target_inter (hs : UniqueMDiff[s]) (x : M) : + UniqueMDiff[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] := by -- this is just a reformulation of `UniqueMDiffOn.uniqueMDiffOn_preimage`, using as `e` -- the local chart at `x`. rw [← PartialEquiv.image_source_inter_eq', inter_comm, extChartAt_source] @@ -103,12 +103,12 @@ theorem UniqueMDiffOn.uniqueMDiffOn_target_inter (hs : UniqueMDiffOn I s) (x : M variable [IsManifold I 1 M] in /-- If a set in a manifold has the unique derivative property, then its pullback by any extended chart, in the vector space, also has the unique derivative property. -/ -theorem UniqueMDiffOn.uniqueDiffOn_target_inter (hs : UniqueMDiffOn I s) (x : M) : +theorem UniqueMDiffOn.uniqueDiffOn_target_inter (hs : UniqueMDiff[s]) (x : M) : UniqueDiffOn 𝕜 ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) := (hs.uniqueMDiffOn_target_inter x).uniqueDiffOn variable [IsManifold I 1 M] in -theorem UniqueMDiffOn.uniqueDiffWithinAt_range_inter (hs : UniqueMDiffOn I s) (x : M) (y : E) +theorem UniqueMDiffOn.uniqueDiffWithinAt_range_inter (hs : UniqueMDiff[s]) (x : M) (y : E) (hy : y ∈ (extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) : UniqueDiffWithinAt 𝕜 (range I ∩ (extChartAt I x).symm ⁻¹' s) y := by apply (hs.uniqueDiffOn_target_inter x y hy).mono @@ -118,11 +118,11 @@ variable [IsManifold I 1 M] in /-- When considering functions between manifolds, this statement shows up often. It entails the unique differential of the pullback in extended charts of the set where the function can be read in the charts. -/ -theorem UniqueMDiffOn.uniqueDiffOn_inter_preimage (hs : UniqueMDiffOn I s) (x : M) (y : M'') +theorem UniqueMDiffOn.uniqueDiffOn_inter_preimage (hs : UniqueMDiff[s]) (x : M) (y : M'') {f : M → M''} (hf : ContinuousOn f s) : UniqueDiffOn 𝕜 ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' (s ∩ f ⁻¹' (extChartAt I' y).source)) := - haveI : UniqueMDiffOn I (s ∩ f ⁻¹' (extChartAt I' y).source) := by + haveI : UniqueMDiff[s ∩ f ⁻¹' (extChartAt I' y).source] := by intro z hz apply (hs z hz.1).inter' apply (hf z hz.1).preimage_mem_nhdsWithin @@ -138,7 +138,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {Z : M → Type set_option backward.isDefEq.respectTransparency false in private lemma UniqueMDiffWithinAt.bundle_preimage_aux {p : TotalSpace F Z} - (hs : UniqueMDiffWithinAt I s p.proj) (h's : s ⊆ (trivializationAt F Z p.proj).baseSet) : + (hs : UniqueMDiffAt[s] p.proj) (h's : s ⊆ (trivializationAt F Z p.proj).baseSet) : UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) p := by suffices ((extChartAt I p.proj).symm ⁻¹' s ∩ range I) ×ˢ univ ⊆ (extChartAt (I.prod 𝓘(𝕜, F)) p).symm ⁻¹' (TotalSpace.proj ⁻¹' s) ∩ range (I.prod 𝓘(𝕜, F)) by @@ -170,7 +170,7 @@ private lemma UniqueMDiffWithinAt.bundle_preimage_aux {p : TotalSpace F Z} /-- In a fiber bundle, the preimage under the projection of a set with unique differentials in the base has unique differentials in the bundle. -/ theorem UniqueMDiffWithinAt.bundle_preimage {p : TotalSpace F Z} - (hs : UniqueMDiffWithinAt I s p.proj) : + (hs : UniqueMDiffAt[s] p.proj) : UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) p := by suffices UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' (s ∩ (trivializationAt F Z p.proj).baseSet)) p from this.mono (by simp) @@ -182,13 +182,13 @@ variable (Z) /-- In a fiber bundle, the preimage under the projection of a set with unique differentials in the base has unique differentials in the bundle. Version with a point `⟨b, x⟩`. -/ -theorem UniqueMDiffWithinAt.bundle_preimage' {b : M} (hs : UniqueMDiffWithinAt I s b) +theorem UniqueMDiffWithinAt.bundle_preimage' {b : M} (hs : UniqueMDiffAt[s] b) (x : Z b) : UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) ⟨b, x⟩ := hs.bundle_preimage (p := ⟨b, x⟩) /-- In a fiber bundle, the preimage under the projection of a set with unique differentials in the base has unique differentials in the bundle. -/ -theorem UniqueMDiffOn.bundle_preimage (hs : UniqueMDiffOn I s) : +theorem UniqueMDiffOn.bundle_preimage (hs : UniqueMDiff[s]) : UniqueMDiffOn (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) := fun _p hp ↦ (hs _ hp).bundle_preimage diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 24e6737558c2c5..c742d0a4e9df21 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -40,6 +40,8 @@ including inference of the model with corners. | `TangentSpace% x` | `TangentSpace I x` | | `tangentMap[s] f` | `tangentMapWithin I J f s` | | `tangentMap% f` | `tangentMap I J f` | +| `UniqueMDiff[s]` | `UniqueMDiffOn I s` | +| `UniqueMDiffAt[s] x` | `UniqueMDiffWithinAt I s x` | In each of these cases, the models with corners are inferred from the domain and codomain of `f`. The search for models with corners uses the local context and is (almost) only based on expression @@ -967,6 +969,29 @@ scoped elab:max "tangentMap%" ppSpace f:term:arg : term => do let (srcI, tgtI) ← findModels ef none mkAppM ``tangentMap #[srcI, tgtI, ef] +/-- `UniqueMDiff[s]` elaborates to `UniqueMDiffOn I s`, +trying to determine `I` from the local context. -/ +scoped elab:max "UniqueMDiff[" s:term "]" : term => do + let es ← Term.elabTerm s none + let estype : Expr ← inferType es + match_expr estype with + | Set α => + let I ← findModel α + mkAppM ``UniqueMDiffOn #[I, es] + | _ => throwError "`{es}` has type `{estype}` which is not of the form `Set α` for some `α`." + +/-- `UniqueMDiffAt[s] x` elaborates to `UniqueMDiffWithinAt I s x` +trying to determine `I` from the local context. +The argument `x` can be omitted. -/ +scoped elab:max "UniqueMDiffAt[" s:term "]" : term => do + let es ← Term.elabTerm s none + let estype : Expr ← inferType es + match_expr estype with + | Set α => + let I ← findModel α + mkAppM ``UniqueMDiffWithinAt #[I, es] + | _ => throwError "`{es}` has type `{estype}` which is not of the form `Set α` for some `α`." + end Manifold section trace @@ -1126,6 +1151,20 @@ arguments that can use the `T%` elaborator. -/ let fs ← withNaryArg 20 <| delab `(MDiffAt[$ss] $fs) >>= annotateGoToSyntaxDef +/-- Delaborator for `UniqueMDiffOn` using the custom elaborator. -/ +@[app_delab UniqueMDiffOn] meta def delabUniqueMDiffOn : Delab := do + whenPPOption getPPNotation do + withOverApp 12 do + let ss ← withAppArg delab + `(UniqueMDiff[$ss]) >>= annotateGoToSyntaxDef + +/-- Delaborator for `UniqueMDiffWithinAt` using the custom elaborator. -/ +@[app_delab UniqueMDiffWithinAt] meta def delabUniqueMDiffWithinAt : Delab := do + whenPPOption getPPNotation do + withOverApp 12 do + let ss ← withAppArg delab + `(UniqueMDiffAt[$ss]) >>= annotateGoToSyntaxDef + -- TODO: add more delaborators (and tests) for -- ContMDiff, ContMDiffOn, ContMDiffAt, ContMDiffWithinAt, HasMFDerivAt, HasMFDerivWithinAt diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index d107d81b0c2720..40c611771099de 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -360,7 +360,7 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a -/ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDiffAt[s] f x) (hW : MDiffAt[s] (fun x ↦ (W x : TangentBundle I M)) x) - (hs : UniqueMDiffWithinAt I s x) : + (hs : UniqueMDiffAt[s] x) : mlieBracketWithin I V (f • W) s x = d[s] f x (V x) • (W x) + (f x) • mlieBracketWithin I V W s x := by simp only [mlieBracketWithin, mpullbackWithin_smul] @@ -401,7 +401,7 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a -/ lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDiffAt[s] f x) (hV : MDiffAt[s] (fun x ↦ (V x : TangentBundle I M)) x) - (hs : UniqueMDiffWithinAt I s x) : + (hs : UniqueMDiffAt[s] x) : mlieBracketWithin I (f • V) W s x = - d[s] f x (W x) • (V x) + (f x) • mlieBracketWithin I V W s x := by rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_smul_right hf hV (V := W) hs, @@ -420,7 +420,7 @@ lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDiffAt f x) exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I) lemma mlieBracketWithin_const_smul_left - (hV : MDiffAt[s] (T% V) x) (hs : UniqueMDiffWithinAt I s x) : + (hV : MDiffAt[s] (T% V) x) (hs : UniqueMDiffAt[s] x) : mlieBracketWithin I (c • V) W s x = c • mlieBracketWithin I V W s x := by simpa [mfderivWithin_const, mvfderivWithin] using! mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs @@ -431,7 +431,7 @@ lemma mlieBracket_const_smul_left (hV : MDiffAt (T% V) x) : exact mlieBracketWithin_const_smul_left hV (uniqueMDiffWithinAt_univ _) lemma mlieBracketWithin_const_smul_right - (hW : MDiffAt[s] (T% W) x) (hs : UniqueMDiffWithinAt I s x) : + (hW : MDiffAt[s] (T% W) x) (hs : UniqueMDiffAt[s] x) : mlieBracketWithin I V (c • W) s x = c • mlieBracketWithin I V W s x := by simpa [mfderivWithin_const, mvfderivWithin] using! mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs @@ -443,7 +443,7 @@ lemma mlieBracket_const_smul_right (hW : MDiffAt (T% W) x) : set_option backward.isDefEq.respectTransparency false in lemma mlieBracketWithin_add_left - (hV : MDiffAt[s] (T% V) x) (hV₁ : MDiffAt[s] (T% V₁) x) (hs : UniqueMDiffWithinAt I s x) : + (hV : MDiffAt[s] (T% V) x) (hV₁ : MDiffAt[s] (T% V₁) x) (hs : UniqueMDiffAt[s] x) : mlieBracketWithin I (V + V₁) W s x = mlieBracketWithin I V W s x + mlieBracketWithin I V₁ W s x := by simp only [mlieBracketWithin_apply] @@ -458,7 +458,7 @@ lemma mlieBracket_add_left (hV : MDiffAt (T% V) x) (hV₁ : MDiffAt (T% V₁) x) exact mlieBracketWithin_add_left hV hV₁ (uniqueMDiffWithinAt_univ _) lemma mlieBracketWithin_add_right - (hW : MDiffAt[s] (T% W) x) (hW₁ : MDiffAt[s] (T% W₁) x) (hs : UniqueMDiffWithinAt I s x) : + (hW : MDiffAt[s] (T% W) x) (hW₁ : MDiffAt[s] (T% W₁) x) (hs : UniqueMDiffAt[s] x) : mlieBracketWithin I V (W + W₁) s x = mlieBracketWithin I V W s x + mlieBracketWithin I V W₁ s x := by rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_add_left hW hW₁ hs, @@ -470,7 +470,7 @@ lemma mlieBracket_add_right (hW : MDiffAt (T% W) x) (hW₁ : MDiffAt (T% W₁) x simp only [← mlieBracketWithin_univ] at hW hW₁ ⊢ exact mlieBracketWithin_add_right hW hW₁ (uniqueMDiffWithinAt_univ _) -theorem mlieBracketWithin_of_mem_nhdsWithin (st : t ∈ 𝓝[s] x) (hs : UniqueMDiffWithinAt I s x) +theorem mlieBracketWithin_of_mem_nhdsWithin (st : t ∈ 𝓝[s] x) (hs : UniqueMDiffAt[s] x) (hV : MDiffAt[t] (T% V) x) (hW : MDiffAt[t] (T% W) x) : mlieBracketWithin I V W s x = mlieBracketWithin I V W t x := by simp only [mlieBracketWithin_apply] @@ -484,12 +484,12 @@ theorem mlieBracketWithin_of_mem_nhdsWithin (st : t ∈ 𝓝[s] x) (hs : UniqueM · exact hV.differentiableWithinAt_mpullbackWithin_vectorField · exact hW.differentiableWithinAt_mpullbackWithin_vectorField -theorem mlieBracketWithin_subset (st : s ⊆ t) (ht : UniqueMDiffWithinAt I s x) +theorem mlieBracketWithin_subset (st : s ⊆ t) (ht : UniqueMDiffAt[s] x) (hV : MDiffAt[t] (T% V) x) (hW : MDiffAt[t] (T% W) x) : mlieBracketWithin I V W s x = mlieBracketWithin I V W t x := mlieBracketWithin_of_mem_nhdsWithin (nhdsWithin_mono _ st self_mem_nhdsWithin) ht hV hW -theorem mlieBracketWithin_eq_mlieBracket (hs : UniqueMDiffWithinAt I s x) +theorem mlieBracketWithin_eq_mlieBracket (hs : UniqueMDiffAt[s] x) (hV : MDiffAt (T% V) x) (hW : MDiffAt (T% W) x) : mlieBracketWithin I V W s x = mlieBracket I V W x := by simp only [← mlieBracketWithin_univ, ← mdifferentiableWithinAt_univ] at hV hW ⊢ @@ -498,7 +498,7 @@ theorem mlieBracketWithin_eq_mlieBracket (hs : UniqueMDiffWithinAt I s x) theorem _root_.DifferentiableWithinAt.mlieBracketWithin_congr_mono (hV : MDiffAt[s] (T% V) x) (hVs : EqOn V₁ V t) (hVx : V₁ x = V x) (hW : MDiffAt[s] (T% W) x) (hWs : EqOn W₁ W t) (hWx : W₁ x = W x) - (hxt : UniqueMDiffWithinAt I t x) (h₁ : t ⊆ s) : + (hxt : UniqueMDiffAt[t] x) (h₁ : t ⊆ s) : mlieBracketWithin I V₁ W₁ t x = mlieBracketWithin I V W s x := by rw [mlieBracketWithin_congr hVs hVx hWs hWx] exact mlieBracketWithin_subset h₁ hxt hV hW @@ -516,7 +516,7 @@ in chart domains. -/ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) - (hu : UniqueMDiffOn I s) (hf : CMDiff[s] 2 f) (hx₀ : x₀ ∈ s) + (hu : UniqueMDiff[s]) (hf : CMDiff[s] 2 f) (hx₀ : x₀ ∈ s) (ht : t ⊆ (extChartAt I' (f x₀)).source) (hst : MapsTo f s t) (hsymm : IsSymmSndFDerivWithinAt 𝕜 ((extChartAt I' (f x₀)) ∘ f ∘ (extChartAt I x₀).symm) ((extChartAt I x₀).symm ⁻¹' s ∩ range I) (extChartAt I x₀ x₀)) : @@ -578,7 +578,7 @@ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] filter_upwards [self_mem_nhdsWithin, this] with y hy h'''y have h'y : f ((extChartAt I x₀).symm y) ∈ (extChartAt I' (f x₀)).source := ht (hst hy.1) have h''y : f ((extChartAt I x₀).symm y) ∈ (chartAt H' (f x₀)).source := by simpa using h'y - have huy : UniqueMDiffWithinAt 𝓘(𝕜, E) ((extChartAt I x₀).symm ⁻¹' s ∩ range I) y := by + have huy : UniqueMDiffAt[(extChartAt I x₀).symm ⁻¹' s ∩ range I] y := by apply UniqueDiffWithinAt.uniqueMDiffWithinAt rw [inter_comm] apply hu.uniqueDiffWithinAt_range_inter @@ -652,7 +652,7 @@ diffeomorphisms. -/ lemma mpullbackWithin_mlieBracketWithin_of_isSymmSndFDerivWithinAt {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) - (hu : UniqueMDiffOn I s) (hf : CMDiffAt[s] 2 f x₀) (hx₀ : x₀ ∈ s) + (hu : UniqueMDiff[s]) (hf : CMDiffAt[s] 2 f x₀) (hx₀ : x₀ ∈ s) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (hsymm : IsSymmSndFDerivWithinAt 𝕜 ((extChartAt I' (f x₀)) ∘ f ∘ (extChartAt I x₀).symm) ((extChartAt I x₀).symm ⁻¹' s ∩ range I) (extChartAt I x₀ x₀)) : @@ -741,7 +741,7 @@ becomes easier to check.) -/ lemma mpullbackWithin_mlieBracketWithin' {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s u : Set M} {t : Set M'} (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) - (hs : UniqueMDiffOn I s) (hu : UniqueMDiffOn I u) + (hs : UniqueMDiff[s]) (hu : UniqueMDiff[u]) (hf : CMDiffAt[u] n f x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (h'x₀ : x₀ ∈ closure (interior u)) (hsu : s ⊆ u) : mpullbackWithin I I' f (mlieBracketWithin I' V W t) s x₀ = @@ -777,7 +777,7 @@ lemma mpullbackWithin_mlieBracketWithin' lemma mpullbackWithin_mlieBracketWithin {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) - (hu : UniqueMDiffOn I s) (hf : CMDiffAt[s] n f x₀) (hx₀ : x₀ ∈ s) + (hu : UniqueMDiff[s]) (hf : CMDiffAt[s] n f x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (h'x₀ : x₀ ∈ closure (interior s)) : mpullbackWithin I I' f (mlieBracketWithin I' V W t) s x₀ = @@ -788,7 +788,7 @@ lemma mpullbackWithin_mlieBracketWithin lemma mpullback_mlieBracketWithin {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) - (hu : UniqueMDiffOn I s) (hf : CMDiffAt n f x₀) (hx₀ : x₀ ∈ s) + (hu : UniqueMDiff[s]) (hf : CMDiffAt n f x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) : mpullback I I' f (mlieBracketWithin I' V W t) x₀ = mlieBracketWithin I (mpullback I I' f V) (mpullback I I' f W) s x₀ := by @@ -830,7 +830,7 @@ protected lemma _root_.ContMDiffWithinAt.mlieBracketWithin_vectorField [IsManifold I (n + 1) M] {m : ℕ∞ω} {U V : Π (x : M), TangentSpace I x} {s : Set M} {x : M} (hU : CMDiffAt[s] n (T% U) x) (hV : CMDiffAt[s] n (T% V) x) - (hs : UniqueMDiffOn I s) (hx : x ∈ s) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : + (hs : UniqueMDiff[s]) (hx : x ∈ s) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : CMDiffAt[s] m (T% (mlieBracketWithin I U V s)) x := by /- The statement is not obvious, since at different points the Lie bracket is defined using different charts. However, since we know that the Lie bracket is invariant under diffeos, we can @@ -902,7 +902,7 @@ lemma _root_.ContMDiffAt.mlieBracket_vectorField {m n : ℕ∞} lemma _root_.ContMDiffOn.mlieBracketWithin_vectorField {m n : ℕ∞} [IsManifold I (n + 1) M] {U V : Π (x : M), TangentSpace I x} (hU : CMDiff[s] n (T% U)) (hV : CMDiff[s] n (T% V)) - (hs : UniqueMDiffOn I s) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : + (hs : UniqueMDiff[s]) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : CMDiff[s] m (T% (mlieBracketWithin I U V s)) := fun x hx ↦ (hU x hx).mlieBracketWithin_vectorField (hV x hx) hs hx hmn @@ -924,7 +924,7 @@ variable [IsManifold I (minSmoothness 𝕜 3) M] [CompleteSpace E] `[U, [V, W]] = [[U, V], W] + [V, [U, W]]` (also called Jacobi identity). -/ theorem leibniz_identity_mlieBracketWithin_apply {U V W : Π (x : M), TangentSpace I x} {s : Set M} {x : M} - (hs : UniqueMDiffOn I s) (h's : x ∈ closure (interior s)) (hx : x ∈ s) + (hs : UniqueMDiff[s]) (h's : x ∈ closure (interior s)) (hx : x ∈ s) (hU : CMDiffAt[s] (minSmoothness 𝕜 2) (T% U) x) (hV : CMDiffAt[s] (minSmoothness 𝕜 2) (T% V) x) (hW : CMDiffAt[s] (minSmoothness 𝕜 2) (T% W) x) : diff --git a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean index 3510738005c08e..7a44b80b89f725 100644 --- a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean +++ b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean @@ -154,7 +154,7 @@ lemma mpullbackWithin_neg : simp [mpullbackWithin_apply] set_option backward.isDefEq.respectTransparency false in -lemma mpullbackWithin_id {V : Π (x : M), TangentSpace I x} (h : UniqueMDiffWithinAt I s x) : +lemma mpullbackWithin_id {V : Π (x : M), TangentSpace I x} (h : UniqueMDiffAt[s] x) : mpullbackWithin I I id V s x = V x := by simp [mpullbackWithin_apply, mfderivWithin_id h] @@ -222,7 +222,7 @@ set_option backward.isDefEq.respectTransparency false in lemma mpullbackWithin_comp_of_left {g : M' → M''} {f : M → M'} {V : Π (x : M''), TangentSpace I'' x} {s : Set M} {t : Set M'} {x₀ : M} (hf : MDiffAt[s] f x₀) (h : Set.MapsTo f s t) - (hu : UniqueMDiffWithinAt I s x₀) (hg' : (mfderiv[t] g (f x₀)).IsInvertible) : + (hu : UniqueMDiffAt[s] x₀) (hg' : (mfderiv[t] g (f x₀)).IsInvertible) : mpullbackWithin I I'' (g ∘ f) V s x₀ = mpullbackWithin I I' f (mpullbackWithin I' I'' g V t) s x₀ := by simp only [mpullbackWithin] @@ -235,7 +235,7 @@ set_option backward.isDefEq.respectTransparency false in lemma mpullbackWithin_comp_of_right {g : M' → M''} {f : M → M'} {V : Π (x : M''), TangentSpace I'' x} {s : Set M} {t : Set M'} {x₀ : M} (hg : MDiffAt[t] g (f x₀)) (h : Set.MapsTo f s t) - (hu : UniqueMDiffWithinAt I s x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) : + (hu : UniqueMDiffAt[s] x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) : mpullbackWithin I I'' (g ∘ f) V s x₀ = mpullbackWithin I I' f (mpullbackWithin I' I'' g V t) s x₀ := by simp only [mpullbackWithin] @@ -260,7 +260,7 @@ variable [IsManifold I 2 M] [IsManifold I' 2 M'] [CompleteSpace E] differentiable. Version within a set at a point. -/ protected lemma _root_.MDifferentiableWithinAt.mpullbackWithin_vectorField_inter (hV : MDiffAt[t] (T% V) (f x₀)) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : 2 ≤ n) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : 2 ≤ n) : MDiffAt[s ∩ f ⁻¹' t] (T% (mpullbackWithin I I' f V s)) x₀ := by /- We want to apply the theorem `MDifferentiableWithinAt.clm_apply_of_inCoordinates`, stating that applying linear maps to vector fields gives a smooth result when the linear map and @@ -324,7 +324,7 @@ protected lemma _root_.MDifferentiableWithinAt.mpullbackWithin_vectorField_inter lemma _root_.MDifferentiableWithinAt.mpullbackWithin_vectorField_inter_of_eq (hV : MDiffAt[t] (T% V) y₀) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : 2 ≤ n) (h : y₀ = f x₀) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : 2 ≤ n) (h : y₀ = f x₀) : MDiffAt[s ∩ f ⁻¹' t] (T% (mpullbackWithin I I' f V s)) x₀ := by subst h exact hV.mpullbackWithin_vectorField_inter hf hf' hx₀ hs hmn @@ -334,7 +334,7 @@ differentiable. Version on a set. -/ protected lemma _root_.MDifferentiableOn.mpullbackWithin_vectorField_inter (hV : MDiff[t] (T% V)) (hf : CMDiff[s] n f) (hf' : ∀ x ∈ s ∩ f ⁻¹' t, (mfderiv[s] f x).IsInvertible) - (hs : UniqueMDiffOn I s) (hmn : 2 ≤ n) : + (hs : UniqueMDiff[s]) (hmn : 2 ≤ n) : MDiff[(s ∩ f ⁻¹' t)] (T% (mpullbackWithin I I' f V s)) := fun _ hx₀ ↦ MDifferentiableWithinAt.mpullbackWithin_vectorField_inter (hV _ hx₀.2) (hf _ hx₀.1) (hf' _ hx₀) hx₀.1 hs hmn @@ -395,7 +395,7 @@ Version within a set at a point. -/ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_inter (hV : CMDiffAt[t] m (T% V) (f x₀)) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) : CMDiffAt[s ∩ f ⁻¹' t] m (T% (mpullbackWithin I I' f V s)) x₀ := by /- We want to apply the theorem `ContMDiffWithinAt.clm_apply_of_inCoordinates`, stating that applying linear maps to vector fields gives a smooth result when the linear map and the @@ -454,7 +454,7 @@ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_inter lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_inter_of_eq (hV : CMDiffAt[t] m (T% V) y₀) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) (h : f x₀ = y₀) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (h : f x₀ = y₀) : CMDiffAt[s ∩ f ⁻¹' t] m (T% (mpullbackWithin I I' f V s)) x₀ := by subst h exact ContMDiffWithinAt.mpullbackWithin_vectorField_inter hV hf hf' hx₀ hs hmn @@ -465,7 +465,7 @@ Version within a set at a point. -/ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_of_mem (hV : CMDiffAt[t] m (T% V) (f x₀)) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) : CMDiffAt[s] m (T% (mpullbackWithin I I' f V s)) x₀ := by apply (ContMDiffWithinAt.mpullbackWithin_vectorField_inter hV hf hf' hx₀ hs hmn).mono_of_mem_nhdsWithin @@ -476,7 +476,7 @@ with `m + 1 ≤ n` is `C^m`. Version within a set at a point. -/ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_of_mem_of_eq (hV : CMDiffAt[t] m (T% V) y₀) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (hy₀ : f x₀ = y₀) : CMDiffAt[s] m (T% (mpullbackWithin I I' f V s)) x₀ := by subst hy₀ @@ -488,7 +488,7 @@ Version within a set at a point. -/ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField (hV : CMDiffAt[t] m (T% V) (f x₀)) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) (hst : MapsTo f s t) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (hst : MapsTo f s t) : CMDiffAt[s] m (T% (mpullbackWithin I I' f V s)) x₀ := ContMDiffWithinAt.mpullbackWithin_vectorField_of_mem hV hf hf' hx₀ hs hmn hst.preimage_mem_nhdsWithin @@ -498,7 +498,7 @@ with `m + 1 ≤ n` is `C^m`. Version within a set at a point. -/ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_of_eq (hV : CMDiffAt[t] m (T% V) y₀) (hf : CMDiffAt[s] n f x₀) (hf' : (mfderiv[s] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) (hst : MapsTo f s t) (h : f x₀ = y₀) : + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (hst : MapsTo f s t) (h : f x₀ = y₀) : CMDiffAt[s] m (T% (mpullbackWithin I I' f V s)) x₀ := by subst h exact ContMDiffWithinAt.mpullbackWithin_vectorField hV hf hf' hx₀ hs hmn hst @@ -509,7 +509,7 @@ Version within a set at a point, with a set used for the pullback possibly large protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField' {u : Set M} (hV : CMDiffAt[t] m (T% V) (f x₀)) (hf : CMDiffAt[u] n f x₀) (hf' : (mfderiv[u] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (hu : s ⊆ u) : CMDiffAt[s] m (T% (mpullbackWithin I I' f V u)) x₀ := by have hn : 1 ≤ n := le_trans (by simp) hmn @@ -530,7 +530,7 @@ with `m + 1 ≤ n` is `C^m`. Version within a set at a point, with a set used for the pullback possibly larger. -/ protected lemma _root_.ContMDiffWithinAt.mpullbackWithin_vectorField_of_eq' {u : Set M} (hV : CMDiffAt[t] m (T% V) y₀) (hf : CMDiffAt[u] n f x₀) (hf' : (mfderiv[u] f x₀).IsInvertible) - (hx₀ : x₀ ∈ s) (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) + (hx₀ : x₀ ∈ s) (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (hu : s ⊆ u) (hy₀ : f x₀ = y₀) : CMDiffAt[s] m (T% (mpullbackWithin I I' f V u)) x₀ := by subst hy₀ @@ -542,7 +542,7 @@ Version on a set. -/ protected lemma _root_.ContMDiffOn.mpullbackWithin_vectorField_inter (hV : CMDiff[t] m (T% V)) (hf : CMDiff[s] n f) (hf' : ∀ x ∈ s ∩ f ⁻¹' t, (mfderiv[s] f x).IsInvertible) - (hs : UniqueMDiffOn I s) (hmn : m + 1 ≤ n) : + (hs : UniqueMDiff[s]) (hmn : m + 1 ≤ n) : CMDiff[s ∩ f ⁻¹' t] m (T% (mpullbackWithin I I' f V s)) := fun _ hx₀ ↦ ContMDiffWithinAt.mpullbackWithin_vectorField_inter (hV _ hx₀.2) (hf _ hx₀.1) (hf' _ hx₀) hx₀.1 hs hmn @@ -616,7 +616,7 @@ protected lemma _root_.ContMDiff.mpullback_vectorField lemma contMDiffWithinAt_mpullbackWithin_extChartAt_symm {V : Π (x : M), TangentSpace I x} (hV : CMDiffAt[s] m (T% V) x) - (hs : UniqueMDiffOn I s) (hx : x ∈ s) (hmn : m + 1 ≤ n) : + (hs : UniqueMDiff[s]) (hx : x ∈ s) (hmn : m + 1 ≤ n) : CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] m (T% (mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I))) (extChartAt I x x) := ContMDiffWithinAt.mpullbackWithin_vectorField_of_eq' hV @@ -628,7 +628,7 @@ lemma contMDiffWithinAt_mpullbackWithin_extChartAt_symm lemma eventually_contMDiffWithinAt_mpullbackWithin_extChartAt_symm {V : Π (x : M), TangentSpace I x} (hV : CMDiffAt[s] m (T% V) x) - (hs : UniqueMDiffOn I s) (hx : x ∈ s) (hmn : m + 1 ≤ n) (hm : m ≠ ∞) : + (hs : UniqueMDiff[s]) (hx : x ∈ s) (hmn : m + 1 ≤ n) (hm : m ≠ ∞) : ∀ᶠ y in 𝓝[s] x, CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] m (T% (mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I))) (extChartAt I x y) := by have T := nhdsWithin_mono _ (subset_insert _ _) diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 862e96f248d2da..36f1634c00a05f 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -529,6 +529,71 @@ end end differentiability +/-! Tests for the elaborators for `UniqueMDiff{WithinAt,On}`. -/ +section UniqueMDiff + +variable {s : Set M} {m : M} + +/-- info: UniqueMDiffOn I s : Prop -/ +#guard_msgs in +#check UniqueMDiff[s] + +/-- info: UniqueMDiffOn (modelWithCornersSelf Real Real) (Set.Icc 0 1) : Prop -/ +#guard_msgs in +#check UniqueMDiff[(Set.Icc 0 1 : Set ℝ)] + +/-- error: `Real` has type `Type` which is not of the form `Set α` for some `α`. -/ +#guard_msgs in +#check UniqueMDiff[ℝ] + +/-- info: UniqueMDiffWithinAt I s : M → Prop -/ +#guard_msgs in +#check UniqueMDiffAt[s] + +/-- info: UniqueMDiffWithinAt I s m : Prop -/ +#guard_msgs in +#check UniqueMDiffAt[s] m + +/-- info: UniqueMDiffWithinAt I Set.univ m : Prop -/ +#guard_msgs in +#check UniqueMDiffAt[(Set.univ : Set M)] m + +-- In the future, the elaborators should take the type of `m` into account. +/-- +error: Could not find a model with corners for `?_`. + +Hint: the expected type contains metavariables, maybe you need to provide an implicit argument +-/ +#guard_msgs in +set_option pp.mvars.anonymous false in +#check UniqueMDiffAt[Set.univ] m + +variable {s : TopologicalSpace.Opens M} + +/-- info: UniqueMDiffOn I s.carrier : Prop -/ +#guard_msgs in +#check UniqueMDiff[s.carrier] + +/-- error: `s` has type `TopologicalSpace.Opens M` which is not of the form `Set α` for some `α`. -/ +#guard_msgs in +#check UniqueMDiff[s] + +/-- +error: Application type mismatch: The argument + s +has type + TopologicalSpace.Opens M +but is expected to have type + Set ?_ +in the application + UniqueMDiffOn I s +-/ +#guard_msgs in +set_option pp.mvars.anonymous false in +#check UniqueMDiffOn I s + +end UniqueMDiff + /-! Tests for the custom elaborators for `ContMDiff{WithinAt,At,On}` -/ section smoothness diff --git a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean index ce05e61ed64c58..f943715dd466e2 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean @@ -82,6 +82,22 @@ variable #guard_msgs in #check TotalSpace.mk (F := E) x (v x) +/-- info: UniqueMDiff[s] : Prop -/ +#guard_msgs in +#check UniqueMDiffOn I s + +/-- info: UniqueMDiffAt[s] : M → Prop -/ +#guard_msgs in +#check UniqueMDiffWithinAt I s + +/-- info: UniqueMDiffAt[s] x : Prop -/ +#guard_msgs in +#check UniqueMDiffWithinAt I s x + +/-- info: UniqueMDiffAt[s] : M → Prop -/ +#guard_msgs in +#check UniqueMDiffWithinAt (𝕜 := ℝ) I s + section ambiguity variable {g : E × E → M} in From 0c7d9c10847cd4a97cf50bd1a2f034acf5e9a9b0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:51:17 +0000 Subject: [PATCH 0183/1300] chore(Geometry/Manifold/ContMDiff/Defs): use `variable` more (#40798) The file uses `x' : M` and `y : M'` throughout: extract this into a variable to declutter statements. --- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index 4520d963cfe915..1a717ac3747ca5 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -69,8 +69,8 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] {I'' : ModelWithCorners 𝕜 E'' H''} {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] -- declare functions, sets, points and smoothness indices - {e : OpenPartialHomeomorph M H} - {e' : OpenPartialHomeomorph M' H'} {f f₁ : M → M'} {s s₁ t : Set M} {x : M} {m n : ℕ∞ω} + {e : OpenPartialHomeomorph M H} {e' : OpenPartialHomeomorph M' H'} + {f f₁ : M → M'} {s s₁ t : Set M} {x x' : M} {y : M'} {m n : ℕ∞ω} variable (I I') in /-- Property in the model space of a model with corners of being `C^n` within a set at a point, @@ -337,14 +337,14 @@ theorem contMDiffWithinAt_iff_source_of_mem_maximalAtlas rfl theorem contMDiffWithinAt_iff_source_of_mem_source - [IsManifold I n M] {x' : M} (hx' : x' ∈ (chartAt H x).source) : + [IsManifold I n M] (hx' : x' ∈ (chartAt H x).source) : ContMDiffWithinAt I I' n f s x' ↔ ContMDiffWithinAt 𝓘(𝕜, E) I' n (f ∘ (extChartAt I x).symm) ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x') := contMDiffWithinAt_iff_source_of_mem_maximalAtlas (chart_mem_maximalAtlas x) hx' theorem contMDiffAt_iff_source_of_mem_source - [IsManifold I n M] {x' : M} (hx' : x' ∈ (chartAt H x).source) : + [IsManifold I n M] (hx' : x' ∈ (chartAt H x).source) : ContMDiffAt I I' n f x' ↔ ContMDiffWithinAt 𝓘(𝕜, E) I' n (f ∘ (extChartAt I x).symm) (range I) (extChartAt I x x') := by simp_rw [ContMDiffAt, contMDiffWithinAt_iff_source_of_mem_source hx', preimage_univ, univ_inter] @@ -362,20 +362,20 @@ theorem contMDiffWithinAt_iff_target_of_mem_maximalAtlas simp_rw [StructureGroupoid.liftPropWithinAt_self_target, A, A'] simp [ContDiffWithinAtProp, comp_assoc] -theorem contMDiffWithinAt_iff_target_of_mem_source - [IsManifold I' n M'] {x : M} {y : M'} (hy : f x ∈ (chartAt H' y).source) : +theorem contMDiffWithinAt_iff_target_of_mem_source [IsManifold I' n M'] + (hy : f x ∈ (chartAt H' y).source) : ContMDiffWithinAt I I' n f s x ↔ ContinuousWithinAt f s x ∧ ContMDiffWithinAt I 𝓘(𝕜, E') n (extChartAt I' y ∘ f) s x := contMDiffWithinAt_iff_target_of_mem_maximalAtlas (chart_mem_maximalAtlas _) hy -theorem contMDiffAt_iff_target_of_mem_source - [IsManifold I' n M'] {x : M} {y : M'} (hy : f x ∈ (chartAt H' y).source) : +theorem contMDiffAt_iff_target_of_mem_source [IsManifold I' n M'] + (hy : f x ∈ (chartAt H' y).source) : ContMDiffAt I I' n f x ↔ ContinuousAt f x ∧ ContMDiffAt I 𝓘(𝕜, E') n (extChartAt I' y ∘ f) x := by rw [ContMDiffAt, contMDiffWithinAt_iff_target_of_mem_source hy, continuousWithinAt_univ, ContMDiffAt] -theorem contMDiffWithinAt_iff_of_mem_maximalAtlas {x : M} (he : e ∈ maximalAtlas I n M) +theorem contMDiffWithinAt_iff_of_mem_maximalAtlas (he : e ∈ maximalAtlas I n M) (he' : e' ∈ maximalAtlas I' n M') (hx : x ∈ e.source) (hy : f x ∈ e'.source) : ContMDiffWithinAt I I' n f s x ↔ ContinuousWithinAt f s x ∧ @@ -385,8 +385,8 @@ theorem contMDiffWithinAt_iff_of_mem_maximalAtlas {x : M} (he : e ∈ maximalAtl /-- An alternative formulation of `contMDiffWithinAt_iff_of_mem_maximalAtlas` if the set `s` lies in `e.source`. -/ -theorem contMDiffWithinAt_iff_image {x : M} (he : e ∈ maximalAtlas I n M) - (he' : e' ∈ maximalAtlas I' n M') +theorem contMDiffWithinAt_iff_image + (he : e ∈ maximalAtlas I n M) (he' : e' ∈ maximalAtlas I' n M') (hs : s ⊆ e.source) (hx : x ∈ e.source) (hy : f x ∈ e'.source) : ContMDiffWithinAt I I' n f s x ↔ ContinuousWithinAt f s x ∧ @@ -399,8 +399,7 @@ theorem contMDiffWithinAt_iff_image {x : M} (he : e ∈ maximalAtlas I n M) /-- One can reformulate being `C^n` within a set at a point as continuity within this set at this point, and being `C^n` in any chart containing that point. -/ theorem contMDiffWithinAt_iff_of_mem_source [IsManifold I n M] [IsManifold I' n M'] - {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) - (hy : f x' ∈ (chartAt H' y).source) : + (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : ContMDiffWithinAt I I' n f s x' ↔ ContinuousWithinAt f s x' ∧ ContDiffWithinAt 𝕜 n (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) @@ -409,8 +408,7 @@ theorem contMDiffWithinAt_iff_of_mem_source [IsManifold I n M] [IsManifold I' n (chart_mem_maximalAtlas y) hx hy theorem contMDiffWithinAt_iff_of_mem_source' [IsManifold I n M] [IsManifold I' n M'] - {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) - (hy : f x' ∈ (chartAt H' y).source) : + (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : ContMDiffWithinAt I I' n f s x' ↔ ContinuousWithinAt f s x' ∧ ContDiffWithinAt 𝕜 n (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) @@ -428,8 +426,7 @@ theorem contMDiffWithinAt_iff_of_mem_source' [IsManifold I n M] [IsManifold I' n exact hc (extChartAt_source_mem_nhds' hy) theorem contMDiffAt_iff_of_mem_source [IsManifold I n M] [IsManifold I' n M'] - {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) - (hy : f x' ∈ (chartAt H' y).source) : + (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : ContMDiffAt I I' n f x' ↔ ContinuousAt f x' ∧ ContDiffWithinAt 𝕜 n (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) (range I) @@ -458,7 +455,7 @@ these charts. Note: this lemma uses `extChartAt I x '' s` instead of `(extChartAt I x).symm ⁻¹' s` to ensure that this set lies in `(extChartAt I x).target`. -/ theorem contMDiffOn_iff_of_subset_source [IsManifold I n M] [IsManifold I' n M'] - {x : M} {y : M'} (hs : s ⊆ (chartAt H x).source) + (hs : s ⊆ (chartAt H x).source) (h2s : MapsTo f s (chartAt H' y).source) : ContMDiffOn I I' n f s ↔ ContinuousOn f s ∧ @@ -472,8 +469,7 @@ these charts. Note: this lemma uses `extChartAt I x '' s` instead of `(extChartAt I x).symm ⁻¹' s` to ensure that this set lies in `(extChartAt I x).target`. -/ theorem contMDiffOn_iff_of_subset_source' [IsManifold I n M] [IsManifold I' n M'] - {x : M} {y : M'} (hs : s ⊆ (extChartAt I x).source) - (h2s : MapsTo f s (extChartAt I' y).source) : + (hs : s ⊆ (extChartAt I x).source) (h2s : MapsTo f s (extChartAt I' y).source) : ContMDiffOn I I' n f s ↔ ContDiffOn 𝕜 n (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) (extChartAt I x '' s) := by rw [extChartAt_source] at hs h2s From 10212ec219a35b6f8603f9dd72751931be2a6167 Mon Sep 17 00:00:00 2001 From: Julia Markus Himmel <2065352+TwoFX@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:51:20 +0000 Subject: [PATCH 0184/1300] chore(CI): allow PR title to start with 'E2' (#40806) This PR relaxes the check at `ValidatePRTitle` to allow titles like `feat(ModularForm): E2 is bounded at ImInfty`. This came up in #40765. Zulip discussion (reviewers only): [#mathlib reviewers > Check PR title](https://leanprover.zulipchat.com/#narrow/channel/345428-mathlib-reviewers/topic/Check.20PR.20title/with/604860804) --- Mathlib/Tactic/Linter/ValidatePRTitle.lean | 8 +++++++- MathlibTest/ValidatePRTitle.lean | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Mathlib/Tactic/Linter/ValidatePRTitle.lean b/Mathlib/Tactic/Linter/ValidatePRTitle.lean index feb10809e868a7..29db84c14bc984 100644 --- a/Mathlib/Tactic/Linter/ValidatePRTitle.lean +++ b/Mathlib/Tactic/Linter/ValidatePRTitle.lean @@ -69,6 +69,12 @@ def prTitle : Parser (String × Option String × String) := do #guard_msgs in #eval Parser.run prTitle "chore: test" +/-- +Check if `word` looks like an abbreviation, like `JSON` or `E2` or `W3C`. +-/ +def isAbbreviation (word : String.Slice) : Bool := + word.all (fun c => c.isUpper || c.isDigit) && word.chars.length != 1 + open Mathlib.Linter.TextBased in /-- Check if `title` matches the mathlib conventions for PR titles @@ -115,7 +121,7 @@ public def validateTitle (title : String) : Array String := Id.run do -- Titles should be lower-cased (but we allow abbreviations). if subject.front.toLower != subject.front then let firstWord := subject.takeWhile (!·.isWhitespace) - if !(firstWord.all (·.isUpper)) then + if !isAbbreviation firstWord then errors := errors.push "error: the PR subject should be lowercased" if subject.endsWith "." then errors := errors.push "error: the PR title should not end with a full stop" diff --git a/MathlibTest/ValidatePRTitle.lean b/MathlibTest/ValidatePRTitle.lean index aacda293a7e90d..b9b01432b3dbbf 100644 --- a/MathlibTest/ValidatePRTitle.lean +++ b/MathlibTest/ValidatePRTitle.lean @@ -186,3 +186,23 @@ info: Message: 'error: the PR title contains multiple consecutive spaces; please -/ #guard_msgs in #check_title "feat(Mathlib/Algebra.lean): title." + +#guard_msgs in +#check_title "feat(ModularForm): E2 is bounded at ImInfty" + +#guard_msgs in +#check_title "feat(ModuleForm): 2E is bounded at ImInfty" + +#guard_msgs in +#check_title "feat(ModuleForm): 2e is less than 6" + +/-- info: Message: 'error: the PR subject should be lowercased' -/ +#guard_msgs in +#check_title "feat(ModuleForm): W3c" + +#guard_msgs in +#check_title "feat(ModuleForm): W3C" + +/-- info: Message: 'error: the PR subject should be lowercased' -/ +#guard_msgs in +#check_title "feat(ModuleForm): A new lemma" From 4084fffec05cf6a84e0097e3c3e4083b92e04fa4 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:33:10 +0000 Subject: [PATCH 0185/1300] feat(Representation/Continuous): show TopRep is a linear category (#40739) co-authored-by : @rmhi --- .../Continuous/Basic.lean | 142 +++++++++++++++++- .../Continuous/TopRep.lean | 50 ++++++ 2 files changed, 189 insertions(+), 3 deletions(-) diff --git a/Mathlib/RepresentationTheory/Continuous/Basic.lean b/Mathlib/RepresentationTheory/Continuous/Basic.lean index 506eb63ce991a7..fc6080606d36fd 100644 --- a/Mathlib/RepresentationTheory/Continuous/Basic.lean +++ b/Mathlib/RepresentationTheory/Continuous/Basic.lean @@ -66,6 +66,7 @@ namespace ContIntertwiningMap open ContRepresentation variable {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} + {π₃ : ContRepresentation R G U} /-- Any continuous intertwining map is an intertwining map. -/ abbrev toIntertwiningMap (f : π₁ →ⁱL π₂) : @@ -78,16 +79,25 @@ def id : π₁ →ⁱL π₁ where __ := ContinuousLinearMap.id R V isIntertwining' g := by simp +@[simp] +lemma toContinuousLinearMap_id : + (id : π₁ →ⁱL π₁).toContinuousLinearMap = ContinuousLinearMap.id R V := rfl + @[ext] lemma ext {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} {f g : π₁ →ⁱL π₂} (h : f.toContinuousLinearMap = g.toContinuousLinearMap) : f = g := by cases f; cases g; congr -lemma toIntertwiningMap_injective {π₁ : ContRepresentation R G V} +lemma toContinuousLinearMap_injective {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} : Function.Injective fun f : π₁ →ⁱL π₂ ↦ f.toContinuousLinearMap := fun _ _ ↦ ext +lemma toIntertwiningMap_injective {π₁ : ContRepresentation R G V} + {π₂ : ContRepresentation R G W} : + Function.Injective fun f : π₁ →ⁱL π₂ ↦ f.toIntertwiningMap := + fun _ _ _ ↦ by ext; simp_all + lemma toFun_injective {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} : Function.Injective fun f : π₁ →ⁱL π₂ ↦ f.toFun := fun f g h ↦ by ext x; exact congr_fun h x @@ -97,6 +107,11 @@ instance {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} : coe f := f.toFun coe_injective := toFun_injective +lemma id_apply (v : V) : (.id : π₁ →ⁱL π₁) v = v := rfl + +lemma toContinuousLinearMap_apply (f : π₁ →ⁱL π₂) (v : V) : + f.toContinuousLinearMap v = f v := rfl + lemma isIntertwining {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} (f : π₁ →ⁱL π₂) (g : G) (v : V) : f (π₁ g v) = π₂ g (f v) := f.toIntertwiningMap.isIntertwining _ _ g v @@ -114,6 +129,116 @@ def comp {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} __ := f.toContinuousLinearMap.comp g.toContinuousLinearMap isIntertwining' h := by rw [comp_assoc, g.2, ← comp_assoc, f.2, comp_assoc] +@[simp] +lemma toContinuousLinearMap_comp {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} + {π₃ : ContRepresentation R G U} (f : π₂ →ⁱL π₃) (g : π₁ →ⁱL π₂) : + (f.comp g).toContinuousLinearMap = f.toContinuousLinearMap.comp g.toContinuousLinearMap := rfl + +instance : Add (π₁ →ⁱL π₂) where + add f g := ⟨f.toContinuousLinearMap + g.toContinuousLinearMap, by simp [g.2, f.2]⟩ + +@[simp] +lemma toContinuousLinearMap_add (f g : π₁ →ⁱL π₂) : + (f + g).toContinuousLinearMap = f.toContinuousLinearMap + g.toContinuousLinearMap := rfl + +lemma add_apply (f g : π₁ →ⁱL π₂) (v : V) : (f + g) v = f v + g v := rfl + +lemma comp_add (f : π₂ →ⁱL π₃) (g h : π₁ →ⁱL π₂) : + f.comp (g + h) = f.comp g + f.comp h := by ext; simp + +lemma add_comp (f g : π₂ →ⁱL π₃) (h : π₁ →ⁱL π₂) : + (f + g).comp h = f.comp h + g.comp h := by ext; simp + +instance : One (π₁ →ⁱL π₁) where one := .id + +lemma one_def : (1 : π₁ →ⁱL π₁) = .id := rfl + +@[simp] +lemma toContinuousLinearMap_one : (1 : π₁ →ⁱL π₁).toContinuousLinearMap = 1 := rfl + +lemma one_apply (v : V) : (1 : π₁ →ⁱL π₁) v = v := rfl + +instance : Zero (π₁ →ⁱL π₂) where zero := ⟨0, by simp⟩ + +@[simp] +lemma toContinuousLinearMap_zero : (0 : π₁ →ⁱL π₂).toContinuousLinearMap = 0 := rfl + +lemma zero_apply (v : V) : (0 : π₁ →ⁱL π₂) v = 0 := rfl + +instance : AddZeroClass (π₁ →ⁱL π₂) := + fast_instance% toContinuousLinearMap_injective.addZeroClass _ + toContinuousLinearMap_zero toContinuousLinearMap_add + +instance : AddCommSemigroup (π₁ →ⁱL π₂) := + fast_instance% toContinuousLinearMap_injective.addCommSemigroup _ + toContinuousLinearMap_add + +instance : Neg (π₁ →ⁱL π₂) where + neg f := ⟨-f.toContinuousLinearMap, by simp [f.2]⟩ + +@[simp] +lemma toContinuousLinearMap_neg (f : π₁ →ⁱL π₂) : + (-f).toContinuousLinearMap = -f.toContinuousLinearMap := rfl + +lemma neg_apply (f : π₁ →ⁱL π₂) (v : V) : (-f) v = -f v := rfl + +instance : Sub (π₁ →ⁱL π₂) where + sub f g := ⟨f.toContinuousLinearMap - g.toContinuousLinearMap, by simp [g.2, f.2]⟩ + +@[simp] +lemma toContinuousLinearMap_sub (f g : π₁ →ⁱL π₂) : + (f - g).toContinuousLinearMap = f.toContinuousLinearMap - g.toContinuousLinearMap := rfl + +lemma sub_apply (f g : π₁ →ⁱL π₂) (v : V) : (f - g) v = f v - g v := rfl + +instance instSMul {S : Type*} [Monoid S] [DistribMulAction S W] [SMulCommClass R S W] + [ContinuousConstSMul S W] [LinearMap.CompatibleSMul W W S R] : + SMul S (π₁ →ⁱL π₂) where + smul s f := ⟨s • f.toContinuousLinearMap, fun g ↦ by + rw [ContinuousLinearMap.smul_comp, f.2, ContinuousLinearMap.comp_smul]⟩ + +section addcommgroup + +variable {S : Type*} [Monoid S] [DistribMulAction S W] [SMulCommClass R S W] + [ContinuousConstSMul S W] [LinearMap.CompatibleSMul W W S R] + +@[simp] +lemma toContinuousLinearMap_smul (s : S) (f : π₁ →ⁱL π₂) : + (s • f).toContinuousLinearMap = s • f.toContinuousLinearMap := rfl + +lemma smul_apply (s : S) (f : π₁ →ⁱL π₂) (v : V) : (s • f) v = s • f v := rfl + +lemma smul_comp {S : Type*} [Monoid S] [DistribMulAction S U] [SMulCommClass R S U] + [ContinuousConstSMul S U] [LinearMap.CompatibleSMul U U S R] + (s : S) (f : π₂ →ⁱL π₃) (g : π₁ →ⁱL π₂) : (s • f).comp g = s • (f.comp g) := by + ext; simp + +lemma comp_smul {S : Type*} [Monoid S] [DistribMulAction S U] [SMulCommClass R S U] + [ContinuousConstSMul S U] [LinearMap.CompatibleSMul U U S R] + [DistribMulAction S W] [SMulCommClass R S W] [ContinuousConstSMul S W] + [LinearMap.CompatibleSMul W W S R] [LinearMap.CompatibleSMul W U S R] + (s : S) (f : π₂ →ⁱL π₃) (g : π₁ →ⁱL π₂) : f.comp (s • g) = s • (f.comp g) := by + ext; simp + +instance : AddCommGroup (π₁ →ⁱL π₂) := + fast_instance% toContinuousLinearMap_injective.addCommGroup _ toContinuousLinearMap_zero + toContinuousLinearMap_add toContinuousLinearMap_neg toContinuousLinearMap_sub + (fun _ _ ↦ toContinuousLinearMap_smul _ _) (fun _ _ ↦ toContinuousLinearMap_smul _ _) + +instance : DistribMulAction S (π₁ →ⁱL π₂) where + one_smul _ := by ext; simp + mul_smul _ _ _ := by ext; simp [mul_smul] + smul_zero _ := by ext; simp + smul_add _ _ _ := by ext; simp [smul_add] + +instance instModule {S : Type*} [Ring S] [Module S W] [SMulCommClass R S W] + [ContinuousConstSMul S W] [LinearMap.CompatibleSMul W W S R] : + Module S (π₁ →ⁱL π₂) where + add_smul _ _ _ := by ext; simp [add_smul] + zero_smul _ := by ext; simp + +end addcommgroup + end ContIntertwiningMap namespace ContRepresentation @@ -279,6 +404,17 @@ lemma trivial_apply (g : G) (v : V) : trivial R G V g v = v := rfl def restrict {H : Type*} [Monoid H] (π : ContRepresentation R G V) (φ : H →* G) : ContRepresentation R H V := .comp π φ +/-- The submodule of `G`-invariant elements of a continuous representation. -/ +def invariants (π : ContRepresentation R G V) : Submodule R V where + carrier := {v | ∀ g, π g v = v} + zero_mem' := by simp + add_mem' _ _ := by simp_all + smul_mem' _ _ hv g := by simp [hv g] + +@[simp] +lemma mem_invariants {π : ContRepresentation R G V} (v : V) : + v ∈ π.invariants ↔ ∀ g, π g v = v := Iff.rfl + -- TODO : define `IsTopologicalMonoid` and then replace `Homeomorph.mulLeft g⁻¹` with the -- `ContinuousMap.mulRight g` to make `coind₁` work for monoids. variable {G H : Type*} [Group G] [TopologicalSpace G] [TopologicalSpace R] @@ -336,7 +472,7 @@ def coind₁ (π : ContRepresentation R G V) : /-- The functoriality of `coind₁`. -/ @[simps] -def coind₁_map (π₁ : ContRepresentation R G V) (π₂ : ContRepresentation R G W) (f : π₁ →ⁱL π₂) : +def coind₁Map (π₁ : ContRepresentation R G V) (π₂ : ContRepresentation R G W) (f : π₁ →ⁱL π₂) : coind₁ π₁ →ⁱL coind₁ π₂ where toFun := (f : ContinuousMap _ _).comp map_add' _ _ := by ext; simp @@ -346,7 +482,7 @@ def coind₁_map (π₁ : ContRepresentation R G V) (π₂ : ContRepresentation /-- The naturality of the transformation from `𝟭 ⟶ coind₁`. -/ @[simps] -def coind₁_ι (π : ContRepresentation R G V) : π →ⁱL coind₁ π where +def coind₁ι (π : ContRepresentation R G V) : π →ⁱL coind₁ π where toFun := .const G map_add' _ _ := rfl map_smul' _ _ := rfl diff --git a/Mathlib/RepresentationTheory/Continuous/TopRep.lean b/Mathlib/RepresentationTheory/Continuous/TopRep.lean index 1240e47542d0a2..c3fa7ff35657b2 100644 --- a/Mathlib/RepresentationTheory/Continuous/TopRep.lean +++ b/Mathlib/RepresentationTheory/Continuous/TopRep.lean @@ -128,6 +128,56 @@ variable {A B} in lemma hom_comm_apply (f : A ⟶ B) (g : G) (a : A) : f.hom (A.ρ g a) = B.ρ g (f.hom a) := by simpa using! congr($(f.hom.2 g) a) +instance : AddCommGroup (A ⟶ B) := ConcreteCategory.homEquiv.addCommGroup + +lemma hom_add (f g : A ⟶ B) : (f + g).hom = f.hom + g.hom := rfl + +lemma hom_sub (f g : A ⟶ B) : (f - g).hom = f.hom - g.hom := rfl + +lemma ofHom_add (f g : ρ →ⁱL σ) : ofHom (f + g) = ofHom f + ofHom g := rfl + +lemma ofHom_sub (f g : ρ →ⁱL σ) : ofHom (f - g) = ofHom f - ofHom g := rfl + +lemma comp_add' (f : A ⟶ B) (g h : B ⟶ C) : f ≫ (g + h) = f ≫ g + f ≫ h := by + ext : 1; simp [hom_add, ContIntertwiningMap.add_comp] + +lemma add_comp' (f g : A ⟶ B) (h : B ⟶ C) : (f + g) ≫ h = f ≫ h + g ≫ h := by + ext : 1; simp [hom_add, ContIntertwiningMap.comp_add] + +instance : Preadditive (TopRep k G) where + homGroup := inferInstance + add_comp := TopRep.add_comp' + comp_add := TopRep.comp_add' + +section Linear + +variable {k : Type u} {G : Type v} {X Y : Type w} [TopologicalSpace k] [CommRing k] + [IsTopologicalRing k] [Monoid G] [AddCommGroup X] [Module k X] [TopologicalSpace X] + [IsTopologicalAddGroup X] [ContinuousSMul k X] [AddCommGroup Y] [Module k Y] [TopologicalSpace Y] + [IsTopologicalAddGroup Y] [ContinuousSMul k Y] {ρ : ContRepresentation k G X} + {σ : ContRepresentation k G Y} {A B C : TopRep k G} + +instance : Module k (A ⟶ B) := ConcreteCategory.homEquiv.module k + +lemma hom_smul (r : k) (f : A ⟶ B) : (r • f).hom = r • f.hom := rfl + +lemma ofHom_smul (r : k) (f : ρ →ⁱL σ) : ofHom (r • f) = r • ofHom f := rfl + +variable (A B C) in +lemma smul_comp' (r : k) (f : A ⟶ B) (g : B ⟶ C) : (r • f) ≫ g = r • (f ≫ g) := by + ext; simp [hom_smul, ContIntertwiningMap.comp_smul] + +variable (A B C) in +lemma comp_smul' (f : A ⟶ B) (r : k) (g : B ⟶ C) : f ≫ (r • g) = r • (f ≫ g) := by + ext; simp [hom_smul, ContIntertwiningMap.smul_comp] + +instance : CategoryTheory.Linear k (TopRep k G) where + homModule := inferInstance + smul_comp := smul_comp' + comp_smul := comp_smul' + +end Linear + section equivAction /-- The functor sending a topological representation to the corresponding object in From e72c92ce6faaaa9e1c19532a0a7b3cefd18006c6 Mon Sep 17 00:00:00 2001 From: Jorge Luis Mayoral <178652443+j-mayoral@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:56:32 +0000 Subject: [PATCH 0186/1300] feat(FinitelyPresentedGroup): free product of finitely presented is finitely presented (#40332) Adds the instance for the Coproduct of FinitelyPresentedGroup: `[IsFinitelyPresented G] [IsFinitelyPresented H] : IsFinitelyPresented (Coprod G H)` Co-authored-by: j-mayoral --- .../GroupTheory/FinitelyPresentedGroup.lean | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean index 81cbeaebab1630..57f0f1f6729ce7 100644 --- a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean +++ b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean @@ -8,7 +8,12 @@ module public import Mathlib.Algebra.Group.Subgroup.Basic public import Mathlib.Data.Set.Finite.Basic +public import Mathlib.Data.Finite.Sum public import Mathlib.GroupTheory.FreeGroup.Basic +public import Mathlib.GroupTheory.Coprod.Basic +public import Mathlib.GroupTheory.PresentedGroup +public import Mathlib.GroupTheory.QuotientGroup.Basic +public import Mathlib.Logic.Equiv.Fin.Basic /-! # Finitely Presented Groups @@ -93,7 +98,7 @@ namespace Group.IsFinitelyPresented /-- Finitely presented groups are closed under isomorphism. -/ @[to_additive /-- Finitely presented additive groups are closed under additive isomorphism. -/ ] -theorem equiv (iso : G ≃* H) (h : IsFinitelyPresented G) : IsFinitelyPresented H := by +theorem equiv (iso : G ≃* H) [h : IsFinitelyPresented G] : IsFinitelyPresented H := by obtain ⟨n, φ, hφsurj, hNC⟩ := h refine ⟨n, (iso : G →* H).comp φ, iso.surjective.comp hφsurj, ?_⟩ rwa [φ.ker_mulEquiv_comp iso] @@ -106,6 +111,12 @@ theorem of_surjective [hG : IsFinitelyPresented G] (f : G →* H) rw [← MonoidHom.comap_ker] exact hf_ker.comap hφ_surj hφ_ker +open QuotientGroup in +theorem exists_mulEquiv_presentedGroup [hg : IsFinitelyPresented G] : + ∃ n : ℕ, ∃ s : Set (FreeGroup (Fin n)), Set.Finite s ∧ Nonempty (G ≃* PresentedGroup s) := by + obtain ⟨n, φ, hφ, s, hs, hsφ⟩ := hg + exact ⟨n, s, hs, ⟨(quotientKerEquivOfSurjective φ hφ).symm.trans (quotientMulEquivOfEq hsφ.symm)⟩⟩ + /-- A free group with a finite number of generators is finitely presented. -/ @[to_additive /-- A free additive group with a finite number of generators is finitely presented. -/ ] @@ -115,13 +126,24 @@ instance [Finite α] : IsFinitelyPresented (FreeGroup α) := by · rw [(FreeGroup.map f).ker_eq_bot (FreeGroup.map_injective hf_inj.injective)] exact .bot +instance [Finite α] (s : Set (FreeGroup α)) [Finite s] : + IsFinitelyPresented (PresentedGroup s) := + of_surjective (PresentedGroup.mk s) (PresentedGroup.mk_surjective s) + ⟨s, ‹_›, (QuotientGroup.ker_mk' (Subgroup.normalClosure s)).symm⟩ + /-- `Multiplicative ℤ` is finitely presented. -/ instance : IsFinitelyPresented (Multiplicative ℤ) := - equiv (FreeGroup.mulEquivIntOfUnique : FreeGroup Unit ≃* Multiplicative ℤ) inferInstance + equiv (FreeGroup.mulEquivIntOfUnique : FreeGroup Unit ≃* Multiplicative ℤ) /-- ℤ is finitely presented -/ instance : AddGroup.IsFinitelyPresented ℤ := - AddGroup.IsFinitelyPresented.equiv - (FreeAddGroup.addEquivIntOfUnique : FreeAddGroup Unit ≃+ ℤ) inferInstance + AddGroup.IsFinitelyPresented.equiv (FreeAddGroup.addEquivIntOfUnique : FreeAddGroup Unit ≃+ ℤ) + +/-- The free product of finitely presented groups is finitely presented -/ +instance [IsFinitelyPresented G] [IsFinitelyPresented H] : + IsFinitelyPresented (Monoid.Coprod G H) := by + obtain ⟨_, sG, ⟨_ : Finite sG, ⟨φG⟩⟩⟩ := exists_mulEquiv_presentedGroup (G := G) + obtain ⟨_, sH, ⟨_ : Finite sH, ⟨φH⟩⟩⟩ := exists_mulEquiv_presentedGroup (G := H) + exact equiv ((PresentedGroup.coprodPresentations sG sH).trans (MulEquiv.coprodCongr φG φH).symm) end Group.IsFinitelyPresented From c9ba3100f3ae30fffc9f6d2bbfe033dcd44ce577 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:34:35 +0000 Subject: [PATCH 0187/1300] chore(FieldTheory/Galois/IsGaloisGroup): generalize `IsGaloisGroup.of_ringEquiv` to surjective ring homs (#40805) `IsGaloisGroup.of_ringEquiv` only uses surjectivity, so I have added the generalization that only assumes surjectivity. Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index f76a7cbae7f149..cdb2d060676346 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -97,13 +97,13 @@ theorem IsGaloisGroup.of_algEquiv [hG : IsGaloisGroup G A B] (B' : Type*) [Semir simp [he, hx']) exact ⟨a, by rw [← e.commutes, ha, AlgEquiv.apply_symm_apply]⟩⟩ -theorem IsGaloisGroup.of_ringEquiv [hG : IsGaloisGroup G A B] [CommSemiring A'] [Algebra A' B] - (e : A ≃+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) : - IsGaloisGroup G A' B where +theorem IsGaloisGroup.of_ringHom_surjective [hG : IsGaloisGroup G A B] [CommSemiring A'] + [Algebra A' B] (e : A →+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) + (he' : Function.Surjective e) : IsGaloisGroup G A' B where faithful := hG.faithful commutes := ⟨by intro g a' b - obtain ⟨a, rfl⟩ : ∃ a, e a = a' := e.surjective a' + obtain ⟨a, rfl⟩ : ∃ a, e a = a' := he' a' rw [Algebra.smul_def, Algebra.smul_def, he, ← Algebra.smul_def, ← Algebra.smul_def] exact hG.commutes.smul_comm g a b⟩ isInvariant := ⟨by @@ -111,6 +111,11 @@ theorem IsGaloisGroup.of_ringEquiv [hG : IsGaloisGroup G A B] [CommSemiring A'] obtain ⟨a, ha⟩ := hG.isInvariant.isInvariant b h exact ⟨e a, by rw [he, ha]⟩⟩ +theorem IsGaloisGroup.of_ringEquiv [hG : IsGaloisGroup G A B] [CommSemiring A'] [Algebra A' B] + (e : A ≃+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) : + IsGaloisGroup G A' B := + .of_ringHom_surjective G A A' B e he e.surjective + attribute [instance low] IsGaloisGroup.commutes IsGaloisGroup.isInvariant variable {C : Type*} [CommSemiring C] [Algebra C B] From d846133bc96504cc64e86ff8010b310a38d09849 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:48:50 +0000 Subject: [PATCH 0188/1300] chore(Topology/Algebra/Category/ProfiniteGrp/*): to_additivize some declarations (#39973) This PR to_additivizes some declarations relating to profinite groups. There were a few trickier declarations that I left out of this PR for now. Co-authored-by: tb65536 --- .../Algebra/Category/ProfiniteGrp/Basic.lean | 5 ++++- .../Algebra/Category/ProfiniteGrp/Completion.lean | 12 ++++++++++++ .../Algebra/Category/ProfiniteGrp/Limits.lean | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean index 03526eb4ebbb72..4d7a993258824a 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean @@ -263,6 +263,8 @@ def ofContinuousMulEquiv {G : ProfiniteGrp.{u}} {H : Type v} [TopologicalSpace H /-- Build an isomorphism in the category `ProfiniteGrp` from a `ContinuousMulEquiv` between `ProfiniteGrp`s. -/ +@[to_additive /-- Build an isomorphism in the category `ProfiniteAddGrp` from +a `ContinuousAddEquiv` between `ProfiniteAddGrp`s. -/] def ContinuousMulEquiv.toProfiniteGrpIso {X Y : ProfiniteGrp} (e : X ≃ₜ* Y) : X ≅ Y where hom := ofHom e inv := ofHom e.symm @@ -279,7 +281,7 @@ instance : (forget₂ ProfiniteGrp Profinite).Faithful := { map_injective := fun {_ _} _ _ h => ConcreteCategory.hom_ext _ _ fun x ↦ CategoryTheory.congr_fun h x } - +@[to_additive] instance : (forget₂ ProfiniteGrp Profinite).ReflectsIsomorphisms where reflects {X Y} f _ := by let i := asIso ((forget₂ ProfiniteGrp Profinite).map f) @@ -288,6 +290,7 @@ instance : (forget₂ ProfiniteGrp Profinite).ReflectsIsomorphisms where map_mul' := map_mul f.hom } exact (ContinuousMulEquiv.toProfiniteGrpIso e).isIso_hom +@[to_additive] instance : (forget ProfiniteGrp.{u}).ReflectsIsomorphisms := CategoryTheory.reflectsIsomorphisms_comp (forget₂ ProfiniteGrp Profinite) (forget Profinite) diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean index b148f05cb044f6..d56ec3594c15ff 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean @@ -56,6 +56,7 @@ namespace ProfiniteCompletion variable (G : GrpCat.{u}) /-- The diagram of finite quotients indexed by finite-index normal subgroups of `G`. -/ +@[to_additive /-- The diagram of finite quotients indexed by finite-index normal subgroups. -/] def finiteGrpDiagram : FiniteIndexNormalSubgroup G ⥤ FiniteGrp.{u} where obj H := FiniteGrp.of <| G ⧸ H.toSubgroup map f := FiniteGrp.ofHom <| QuotientGroup.map _ _ (MonoidHom.id _) f.le @@ -63,16 +64,20 @@ def finiteGrpDiagram : FiniteIndexNormalSubgroup G ⥤ FiniteGrp.{u} where map_comp f g := by ext ⟨x⟩; rfl /-- The finite-quotient diagram viewed in `ProfiniteGrp`. -/ +@[to_additive /-- The finite-quotient diagram viewed in `ProfiniteAddGrp`. -/] def diagram : FiniteIndexNormalSubgroup G ⥤ ProfiniteGrp.{u} := finiteGrpDiagram _ ⋙ forget₂ _ _ /-- The profinite completion of `G` as a projective limit. -/ +@[to_additive /-- The profinite completion of `G` as a projective limit. -/] def completion : ProfiniteGrp.{u} := limit (diagram G) /-- The canonical map from `G` to its profinite completion, as a function. -/ +@[to_additive /-- The canonical map from `G` to its profinite completion, as a function. -/] def etaFn (x : G) : completion G := ⟨fun _ => QuotientGroup.mk x, fun _ _ _ => rfl⟩ /-- The canonical morphism from `G` to its profinite completion. -/ +@[to_additive /-- The canonical morphism from `G` to its profinite completion. -/] def eta : G ⟶ GrpCat.of (completion G) := GrpCat.ofHom { toFun := etaFn G map_one' := rfl @@ -80,6 +85,7 @@ def eta : G ⟶ GrpCat.of (completion G) := GrpCat.ofHom { } set_option backward.isDefEq.respectTransparency false in +@[to_additive] theorem mono_eta_iff_residuallyFinite : Mono (eta G) ↔ Group.ResiduallyFinite G := by rw [GrpCat.mono_iff_injective, injective_iff_map_eq_one, Group.residuallyFinite_iff_forall_finiteIndexNormalSubgroup] @@ -87,11 +93,13 @@ theorem mono_eta_iff_residuallyFinite : Mono (eta G) ↔ Group.ResiduallyFinite rw [Subtype.ext_iff, funext_iff] exact forall_congr' fun H ↦ QuotientGroup.eq_one_iff g +@[to_additive] theorem etaFn_injective_iff_residuallyFinite : Function.Injective (etaFn G) ↔ Group.ResiduallyFinite G := (GrpCat.mono_iff_injective (eta G)).symm.trans (mono_eta_iff_residuallyFinite G) set_option backward.isDefEq.respectTransparency false in +@[to_additive] lemma denseRange : DenseRange (etaFn G) := by apply dense_iff_inter_open.mpr rintro U ⟨s, hsO, hsv⟩ ⟨⟨spc, hspc⟩, uDefaultSpec⟩ @@ -119,14 +127,17 @@ variable {G} variable {P : ProfiniteGrp.{u}} /-- The preimage of an open normal subgroup under a morphism to a profinite group. -/ +@[to_additive /-- The preimage of an open normal subgroup under a morphism to a profinite group. -/] def preimage (f : G ⟶ GrpCat.of P) (H : OpenNormalSubgroup P) : FiniteIndexNormalSubgroup G := H.toFiniteIndexNormalSubgroup.comap f.hom +@[to_additive] lemma preimage_le {f : G ⟶ GrpCat.of P} {H K : OpenNormalSubgroup P} (h : H ≤ K) : preimage f H ≤ preimage f K := FiniteIndexNormalSubgroup.comap_mono _ h /-- The induced map on finite quotients coming from a morphism to `P`. -/ +@[to_additive /-- The induced map on finite quotients coming from a morphism to `P`. -/] def quotientMap (f : G ⟶ GrpCat.of P) (H : OpenNormalSubgroup P) : FiniteGrp.of (G ⧸ (preimage f H).toSubgroup) ⟶ FiniteGrp.of (P ⧸ H.toSubgroup) := FiniteGrp.ofHom <| QuotientGroup.map _ _ f.hom <| fun _ h => h @@ -163,6 +174,7 @@ lemma lift_eta (f : G ⟶ GrpCat.of P) : eta G ≫ (forget₂ _ _).map (lift f) simp only [Category.assoc, Iso.inv_hom_id] rfl +@[to_additive] lemma lift_unique (f g : completion G ⟶ P) (h : eta G ≫ (forget₂ _ _).map f = eta G ≫ (forget₂ _ _).map g) : f = g := by ext x diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean index 8c314bc61cabf3..e05a25f8247f72 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean @@ -43,6 +43,8 @@ namespace ProfiniteGrp /-- The functor from `OpenNormalSubgroup P` to `FiniteGrp` sending `U` to `P ⧸ U`, where `P : ProfiniteGrp`. -/ +@[to_additive /-- The functor from `OpenNormalAddSubgroup P` to `FiniteAddGrp` sending `U` to +`P ⧸ U`, where `P : ProfiniteAddGrp`. -/] def toFiniteQuotientFunctor (P : ProfiniteGrp) : OpenNormalSubgroup P ⥤ FiniteGrp where obj := fun H => FiniteGrp.of (P ⧸ H.toSubgroup) map := fun fHK => FiniteGrp.ofHom (QuotientGroup.map _ _ (.id _) (leOfHom fHK)) @@ -51,18 +53,22 @@ def toFiniteQuotientFunctor (P : ProfiniteGrp) : OpenNormalSubgroup P ⥤ Finite _ _ _ (.id _) (.id _) (leOfHom f) (leOfHom g)).symm /-- The diagram of finite quotients of `P` viewed in `ProfiniteGrp`. -/ -@[simps! obj map] +@[to_additive (attr := simps! obj map) +/-- The diagram of finite quotients of `P` viewed in `ProfiniteAddGrp`. -/] def diagram (P : ProfiniteGrp.{u}) : OpenNormalSubgroup P ⥤ ProfiniteGrp.{u} := toFiniteQuotientFunctor P ⋙ forget₂ FiniteGrp ProfiniteGrp /-- The `MonoidHom` from a profinite group `P` to the projective limit of its quotients by open normal subgroups ordered by inclusion -/ +@[to_additive /-- The `AddMonoidHom` from a profinite additive group `P` to the projective limit of +its quotients by open normal subgroups ordered by inclusion -/] def toLimitFun (P : ProfiniteGrp.{u}) : P →* limit (diagram P) where toFun p := ⟨fun _ => QuotientGroup.mk p, fun _ ↦ fun _ _ ↦ rfl⟩ map_one' := Subtype.val_inj.mp rfl map_mul' _ _ := Subtype.val_inj.mp rfl set_option backward.isDefEq.respectTransparency false in +@[to_additive] lemma toLimitFun_continuous (P : ProfiniteGrp.{u}) : Continuous (toLimitFun P) := by apply continuous_induced_rng.mpr (continuous_pi _) intro H @@ -81,6 +87,8 @@ lemma toLimitFun_continuous (P : ProfiniteGrp.{u}) : Continuous (toLimitFun P) : /-- The morphism in the category of `ProfiniteGrp` from a profinite group `P` to the projective limit of its quotients by open normal subgroups ordered by inclusion -/ +@[to_additive /-- The morphism in the category of `ProfiniteAddGrp` from a profinite additive group +`P` to the projective limit of its quotients by open normal subgroups ordered by inclusion -/] def toLimit (P : ProfiniteGrp.{u}) : P ⟶ limit (diagram P) := ofHom { toLimitFun P with continuous_toFun := toLimitFun_continuous P } @@ -115,6 +123,7 @@ theorem toLimit_surjective (P : ProfiniteGrp.{u}) : Function.Surjective (toLimit rw [← Set.range_eq_univ, ← closure_eq_iff_isClosed.mpr this, Dense.closure_eq (denseRange_toLimit P)] +@[to_additive] theorem toLimit_injective (P : ProfiniteGrp.{u}) : Function.Injective (toLimit P) := by change Function.Injective (toLimit P).hom.toMonoidHom rw [← MonoidHom.ker_eq_bot_iff, Subgroup.eq_bot_iff_forall] @@ -144,6 +153,7 @@ noncomputable def isoLimittoFiniteQuotientFunctor (P : ProfiniteGrp.{u}) : ContinuousMulEquiv.toProfiniteGrpIso (continuousMulEquivLimittoFiniteQuotientFunctor P) /-- The projection from `P` to the quotient by an open normal subgroup. -/ +@[to_additive /-- The projection from `P` to the quotient by an open normal subgroup. -/] def proj {P : ProfiniteGrp.{u}} (U : OpenNormalSubgroup P) : P ⟶ (diagram P).obj U := ProfiniteGrp.ofHom (Y := (diagram P).obj U) { toFun := QuotientGroup.mk @@ -154,7 +164,7 @@ def proj {P : ProfiniteGrp.{u}} (U : OpenNormalSubgroup P) : P ⟶ (diagram P).o } /-- The canonical cone over `diagram P` with point `P`. -/ -@[simps] +@[to_additive (attr := simps) /-- The canonical cone over `diagram P` with point `P`. -/] def cone (P : ProfiniteGrp.{u}) : Limits.Cone (diagram P) where pt := P π := { app := proj } From 1b82673ebcbcca37455a100743b2c2f56b61bda6 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:48:53 +0000 Subject: [PATCH 0189/1300] feat(RingTheory/Ideal/Over): add `Ideal.smul_under` (#40385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR proves `g • P.under A = (g • P).under A` in the `SMulDistribClass` setting. Co-authored-by: tb65536 --- Mathlib/RingTheory/Ideal/Over.lean | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/Ideal/Over.lean b/Mathlib/RingTheory/Ideal/Over.lean index 0965eb9bcd53a5..37a2399ed0d352 100644 --- a/Mathlib/RingTheory/Ideal/Over.lean +++ b/Mathlib/RingTheory/Ideal/Over.lean @@ -90,7 +90,7 @@ section Semiring variable (A : Type*) [CommSemiring A] {B C : Type*} [Semiring B] [Semiring C] [Algebra A B] [Algebra A C] (P : Ideal B) {Q : Ideal C} (p : Ideal A) - {G : Type*} [Group G] [MulSemiringAction G B] [SMulCommClass G A B] (g : G) + {G : Type*} [Group G] [MulSemiringAction G B] (g : G) /-- The ideal obtained by pulling back the ideal `P` from `B` to `A`. -/ abbrev under : Ideal A := Ideal.comap (algebraMap A B) P @@ -103,10 +103,19 @@ instance IsPrime.under [hP : P.IsPrime] : (P.under A).IsPrime := hP.comap (algebraMap A B) @[simp] -lemma under_smul : (g • P : Ideal B).under A = P.under A := by +lemma under_smul [SMulCommClass G A B] : (g • P : Ideal B).under A = P.under A := by ext a rw [mem_comap, mem_comap, mem_pointwise_smul_iff_inv_smul_mem, smul_algebraMap] +@[simp] +theorem smul_under [MulSemiringAction G A] [SMulDistribClass G A B] : + g • P.under A = (g • P).under A := by + conv_lhs => rw [pointwise_smul_eq_comap, ← comap_coe, under_def, comap_comap] + conv_rhs => rw [pointwise_smul_eq_comap, ← comap_coe, under_def, comap_comap] + congr + ext + simp [algebraMap.smul'] + variable (B) in theorem under_top : under A (⊤ : Ideal B) = ⊤ := comap_top @@ -154,7 +163,7 @@ theorem LiesOver.of_eq_map_equiv [P.LiesOver p] {E : Type*} [EquivLike E B C] exact of_eq_comap p (AlgEquivClass.toAlgEquiv σ : B ≃ₐ[A] C).symm h variable {p} in -instance LiesOver.smul [h : P.LiesOver p] : (g • P).LiesOver p := +instance LiesOver.smul [SMulCommClass G A B] [h : P.LiesOver p] : (g • P).LiesOver p := ⟨h.over.trans (under_smul A P g).symm⟩ variable (P) (Q) From 2e6e057c008759e50eda6b03746d6309d59d7b65 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:48:55 +0000 Subject: [PATCH 0190/1300] feat(RingTheory/Ideal/Pointwise): add `IsScalarTower` instance for pointwise action on ideals (#40386) This PR adds an `IsScalarTower` instance for pointwise action on ideals. Co-authored-by: tb65536 --- Mathlib/RingTheory/Ideal/Pointwise.lean | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/Ideal/Pointwise.lean b/Mathlib/RingTheory/Ideal/Pointwise.lean index 46e853d9691a61..cf3bbdbd200298 100644 --- a/Mathlib/RingTheory/Ideal/Pointwise.lean +++ b/Mathlib/RingTheory/Ideal/Pointwise.lean @@ -27,13 +27,13 @@ Where possible, try to keep them in sync. open Set -variable {M R : Type*} +variable {M N R : Type*} namespace Ideal section Monoid -variable [Monoid M] [Semiring R] [MulSemiringAction M R] +variable [Monoid M] [Monoid N] [Semiring R] [MulSemiringAction M R] [MulSemiringAction N R] /-- The action on an ideal corresponding to applying the action to every element. @@ -67,6 +67,13 @@ theorem pointwise_smul_def {a : M} (S : Ideal R) : a • S = S.map (MulSemiringAction.toRingHom _ _ a) := rfl +instance [SMul M N] [IsScalarTower M N R] : IsScalarTower M N (Ideal R) where + smul_assoc x y z := by + simp_rw [pointwise_smul_def, map_map] + congr + ext + simp + -- note: unlike with `Subring`, `pointwise_smul_toAddSubgroup` wouldn't be true theorem smul_mem_pointwise_smul (m : M) (r : R) (S : Ideal R) : r ∈ S → m • r ∈ m • S := From 4cf5258e7fcaee29f7b3abb025add73bdea63f41 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:48:57 +0000 Subject: [PATCH 0191/1300] feat(RingTheory/Ideal/Over): add instances for `LiesOver` in towers (#40437) This PR adds instances for `LiesOver` in towers. Co-authored-by: tb65536 --- Mathlib/RingTheory/Ideal/Over.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/RingTheory/Ideal/Over.lean b/Mathlib/RingTheory/Ideal/Over.lean index 37a2399ed0d352..cc305ab486e261 100644 --- a/Mathlib/RingTheory/Ideal/Over.lean +++ b/Mathlib/RingTheory/Ideal/Over.lean @@ -194,6 +194,12 @@ theorem LiesOver.trans [𝔓.LiesOver P] [P.LiesOver p] : 𝔓.LiesOver p where theorem LiesOver.tower_bot [hp : 𝔓.LiesOver p] [hP : 𝔓.LiesOver P] : P.LiesOver p where over := by rw [𝔓.over_def p, 𝔓.over_def P, under_under] +instance [𝔓.LiesOver P] : 𝔓.LiesOver (P.under A) := + .trans 𝔓 P (P.under A) + +instance [𝔓.LiesOver P] : P.LiesOver (𝔓.under A) := + .tower_bot 𝔓 P (𝔓.under A) + /-- Consider the following commutative diagram of ring maps ``` From c367137fa1e20d856c0d58e0efa86a62c87121fb Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:49:00 +0000 Subject: [PATCH 0192/1300] refactor(RingTheory/QuasiFinite/Basic): golf proof of `eq_of_le_of_under_eq` (#40772) This PR uses `Ideal.isPrime_map_of_isLocalizationAtPrime` and `Ideal.isPrime_map_of_isLocalizationAtPrime` to golf the proof of `eq_of_le_of_under_eq` slightly. Co-authored-by: tb65536 --- Mathlib/RingTheory/QuasiFinite/Basic.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/RingTheory/QuasiFinite/Basic.lean b/Mathlib/RingTheory/QuasiFinite/Basic.lean index cff1eb8679363a..08f45dedcf66ea 100644 --- a/Mathlib/RingTheory/QuasiFinite/Basic.lean +++ b/Mathlib/RingTheory/QuasiFinite/Basic.lean @@ -412,16 +412,15 @@ omit [Algebra S T] in lemma QuasiFiniteAt.eq_of_le_of_under_eq {P Q : Ideal S} [P.IsPrime] [Q.IsPrime] (h₁ : P ≤ Q) (h₂ : P.under R = Q.under R) [QuasiFiniteAt R Q] : P = Q := by - have : Disjoint (Q.primeCompl : Set S) P := by simpa [Set.disjoint_iff, Set.ext_iff, not_imp_comm] - have inst := IsLocalization.isPrime_of_isPrime_disjoint _ (Localization.AtPrime Q) P ‹_› this + have := Q.isPrime_map_of_isLocalizationAtPrime h₁ (S := Localization.AtPrime Q) have H := QuasiFinite.eq_of_le_of_under_eq (R := R) (Ideal.map (algebraMap S (Localization.AtPrime Q)) P) _ (IsLocalRing.le_maximalIdeal_of_isPrime _) (by convert! h₂ <;> rw [← Ideal.under_under (B := S)] - · rw [IsLocalization.under_map_of_isPrime_disjoint Q.primeCompl _ ‹P.IsPrime› this] + · rw [Q.under_map_of_isLocalizationAtPrime h₁] · rw [Localization.AtPrime.under_maximalIdeal]) rw [← Localization.AtPrime.under_maximalIdeal (I := Q), ← H, - IsLocalization.under_map_of_isPrime_disjoint Q.primeCompl _ ‹P.IsPrime› this] + Q.under_map_of_isLocalizationAtPrime h₁] instance (p : Ideal R) [p.IsPrime] (P : Ideal S) [P.IsPrime] [P.LiesOver p] [QuasiFiniteAt R P] [Algebra (Localization.AtPrime p) (Localization.AtPrime P)] From e1f7efcd7be2541b98efd51874fe6498299f6bab Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:49:02 +0000 Subject: [PATCH 0193/1300] feat(RingTheory/Ideal/Maps): coheight of ideal under surjective ring homomorphism (#40780) This PR proves that the coheight of an ideal is preserved when taking the preimage under a surjective ring homomorphism. Co-authored-by: tb65536 --- Mathlib/RingTheory/Ideal/Maps.lean | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 523c5a0fdc457d..62de906cb2c249 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -6,6 +6,7 @@ Authors: Kenny Lau module public import Mathlib.Data.DFinsupp.Module +public import Mathlib.Order.KrullDimension public import Mathlib.RingTheory.Ideal.Operations /-! @@ -392,6 +393,7 @@ theorem comap_le_comap_iff_of_surjective (hf : Function.Surjective f) (I J : Ide le_comap_of_map_le ((map_comap_of_surjective f hf I).le.trans h)⟩ /-- The map on ideals induced by a surjective map preserves inclusion. -/ +@[simps] def orderEmbeddingOfSurjective (hf : Function.Surjective f) : Ideal S ↪o Ideal R where toFun := comap f inj' _ _ eq := SetLike.ext' (Set.preimage_injective.mpr hf <| SetLike.ext'_iff.mp eq) @@ -588,6 +590,15 @@ theorem comap_map_of_surjective (hf : Function.Surjective f) (I : Ideal R) : add_sub_cancel s r⟩) (sup_le (map_le_iff_le_comap.1 le_rfl) (comap_mono bot_le)) +theorem coheight_comap_of_surjective (hf : Function.Surjective f) (I : Ideal S) : + Order.coheight (I.comap f) = Order.coheight I := by + let φ := orderEmbeddingOfSurjective f hf + refine (Order.coheight_eq_of_strictMono φ φ.strictMono (fun J K h ↦ ⟨K.map f, ?_, ?_⟩) I).symm + · rw [← J.map_comap_of_surjective f hf] + apply lt_of_le_not_ge (map_mono h.le) + simpa [map_le_iff_le_comap, φ] using h.not_ge + · exact (K.comap_map_of_surjective f hf).trans (sup_of_le_left ((comap_mono bot_le).trans h.le)) + /-- Correspondence theorem -/ def relIsoOfSurjective (hf : Function.Surjective f) : Ideal S ≃o { p : Ideal R // comap f ⊥ ≤ p } where From 2216b5b1ea909cc6bcd2c3b45516c1ece827135f Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:19:57 +0000 Subject: [PATCH 0194/1300] feat(NumberTheory/PrimeCounting): primesBelow/primesLE as filters of Ioo/Ioc (#40654) Added some minor variants of existing `primesBelow_eq_filter_Ico_one` type API to also handle `Ioo` and `Ioc` type intervals. This will be needed in a subsequent PR establishing Mertens' theorems. Co-authored-by: Terence Tao --- Mathlib/NumberTheory/PrimeCounting.lean | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Mathlib/NumberTheory/PrimeCounting.lean b/Mathlib/NumberTheory/PrimeCounting.lean index b88f94d8aa0873..094ba7830c3724 100644 --- a/Mathlib/NumberTheory/PrimeCounting.lean +++ b/Mathlib/NumberTheory/PrimeCounting.lean @@ -193,6 +193,14 @@ lemma primesLE_eq_filter_Icc_zero (n : ℕ) : primesLE n = filter Nat.Prime (Icc ext p simp [primesLE_eq_filter_range] +lemma primesBelow_eq_filter_Ioo_zero (n : ℕ) : primesBelow n = filter Nat.Prime (Ioo 0 n) := by + ext p + simp +contextual [primesBelow_eq_filter_range, Nat.Prime.pos] + +lemma primesLE_eq_filter_Ioc_zero (n : ℕ) : primesLE n = filter Nat.Prime (Ioc 0 n) := by + ext p + simp +contextual [primesLE_eq_filter_range, Nat.Prime.pos] + lemma primesBelow_eq_filter_Ico_one (n : ℕ) : primesBelow n = filter Nat.Prime (Ico 1 n) := by ext p simp +contextual [primesBelow_eq_filter_range, Nat.Prime.one_le] @@ -201,6 +209,14 @@ lemma primesLE_eq_filter_Icc_one (n : ℕ) : primesLE n = filter Nat.Prime (Icc ext p simp +contextual [primesLE_eq_filter_range, Nat.Prime.one_le] +lemma primesBelow_eq_filter_Ioo_one (n : ℕ) : primesBelow n = filter Nat.Prime (Ioo 1 n) := by + ext p + simp +contextual [primesBelow_eq_filter_range, Nat.Prime.one_lt] + +lemma primesLE_eq_filter_Ioc_one (n : ℕ) : primesLE n = filter Nat.Prime (Ioc 1 n) := by + ext p + simp +contextual [primesLE_eq_filter_range, Nat.Prime.one_lt] + lemma primesBelow_eq_filter_Ico_two (n : ℕ) : primesBelow n = filter Nat.Prime (Ico 2 n) := by ext p simp +contextual [primesBelow_eq_filter_range, Nat.Prime.two_le] From 413a92168ed3397410753fb2cd9373eb0d28824a Mon Sep 17 00:00:00 2001 From: Leonid Ryvkin <24719821+Ljon4ik4@users.noreply.github.com> Date: Fri, 19 Jun 2026 17:03:37 +0000 Subject: [PATCH 0195/1300] feat: Lie-Rinehart subalgebras introduced (#39850) This PR introduces subalgebras of Lie-Rinehart algebras. It defines the corresponding structures, introduces some basic api and shows that a Lie-Rinehart subalgebra is again a Lie-Rinehart algebra. Co-authored-by: Oliver Nash --- Mathlib.lean | 1 + Mathlib/Algebra/LieRinehartAlgebra/Defs.lean | 4 +- .../LieRinehartAlgebra/Subalgebra.lean | 232 ++++++++++++++++++ 3 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean diff --git a/Mathlib.lean b/Mathlib.lean index f2a1f9bc7ef3f4..b499769e07f489 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -764,6 +764,7 @@ public import Mathlib.Algebra.Lie.Weights.Killing public import Mathlib.Algebra.Lie.Weights.Linear public import Mathlib.Algebra.Lie.Weights.RootSystem public import Mathlib.Algebra.LieRinehartAlgebra.Defs +public import Mathlib.Algebra.LieRinehartAlgebra.Subalgebra public import Mathlib.Algebra.LinearRecurrence public import Mathlib.Algebra.ModEq public import Mathlib.Algebra.Module.Basic diff --git a/Mathlib/Algebra/LieRinehartAlgebra/Defs.lean b/Mathlib/Algebra/LieRinehartAlgebra/Defs.lean index e9150dd43eb190..063ea6e14fe236 100644 --- a/Mathlib/Algebra/LieRinehartAlgebra/Defs.lean +++ b/Mathlib/Algebra/LieRinehartAlgebra/Defs.lean @@ -45,8 +45,6 @@ class LieRinehartAlgebra (R A L : Type*) [CommRing A] [LieRing L] [CommRing R] [Algebra R A] [LieAlgebra R L] : Prop extends IsScalarTower R A L, LieModule R L A -namespace LieRinehartAlgebra - variable {R A₁ L₁ A₂ L₂ A₃ L₃ : Type*} [CommRing R] [CommRing A₁] [LieRing L₁] [Module A₁ L₁] [LieRingModule L₁ A₁] [CommRing A₂] [LieRing L₂] [Module A₂ L₂] [LieRingModule L₂ A₂] @@ -72,6 +70,8 @@ instance : LieRinehartRing A₁ (Derivation R A₁ A₁) where /-- The derivations of a commutative Algebra themselves form a LieRinehart-Algebra. -/ instance : LieRinehartAlgebra R A₁ (Derivation R A₁ A₁) where +namespace LieRinehartAlgebra + /-- A morphism of Lie-Rinehart algebras, from `(A₁, L₁)` to `(A₂, L₂)`, consists of a pair of maps `(σ, F)` where `σ : A₁ → A₂` is a morphism of algebras and `F` is a morphism of Lie algebras, which respect the module structures. diff --git a/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean b/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean new file mode 100644 index 00000000000000..56250b377b7ffd --- /dev/null +++ b/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean @@ -0,0 +1,232 @@ +/- +Copyright (c) 2026 Leonid Ryvkin. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Leonid Ryvkin +-/ + +module + +public import Mathlib.Algebra.LieRinehartAlgebra.Defs + +/-! +# Lie-Rinehart subalgebras + +This file defines Lie-Rinehart subalgebras of a Lie-Rinehart algebra and provides basic related +definitions and results. + +## Main definitions/ statements: + +* `LieRinehartSubalgebra` as an `A`-submodule of `L` stable under the Lie bracket. (This is also +applicable to Lie-Rinehart rings and more generally any `A`-module with a Lie ring structure). + +* A Lie-Rinehart subalgebra of a Lie-Rinehart ring is a Lie-Rinehart ring + +* A Lie-Rinehart subalgebra of a Lie-Rinehart algebra is a Lie-Rinehart algebra over the same ring. + +-/ + +public section + +open scoped LieRinehartAlgebra + +variable (A L : Type*) [CommRing A] [LieRing L] [Module A L] + +/-- A Lie-Rinehart subalgebra of a Lie-Rinehart algebra `(R A L)` is an `A`-submodule of `L`, which +is stable under the Lie bracket. (This can be defined independently of `R` and most +Lie-Rinehart algebra axioms). -/ +structure LieRinehartSubalgebra extends Submodule A L where + lie_mem' {a b} : a ∈ carrier → b ∈ carrier → ⁅a, b⁆ ∈ carrier + +instance : Zero (LieRinehartSubalgebra A L) := + ⟨⟨0, fun {x y hx _hy} ↦ by simp [(Submodule.mem_bot A).mp hx]⟩⟩ + +instance : Inhabited (LieRinehartSubalgebra A L) := + ⟨0⟩ + +namespace LieRinehartSubalgebra + +instance : SetLike (LieRinehartSubalgebra A L) L where + coe L' := L'.carrier + coe_injective L' L'' h := by + rcases L' + rcases L'' + congr + exact SetLike.coe_injective h + +instance : PartialOrder (LieRinehartSubalgebra A L) := .ofSetLike (LieRinehartSubalgebra A L) L + +instance : AddSubgroupClass (LieRinehartSubalgebra A L) L where + add_mem := Submodule.add_mem _ + zero_mem L' := L'.zero_mem' + neg_mem {L'} x hx := show -x ∈ L'.toSubmodule from neg_mem hx + +instance : SMulMemClass (LieRinehartSubalgebra A L) A L where + smul_mem {s} := SMulMemClass.smul_mem (s := s.toSubmodule) + +/-- A Lie-Rinehart subalgebra forms a Lie ring. -/ +instance lieRing (L' : LieRinehartSubalgebra A L) : LieRing L' where + bracket x y := ⟨⁅x.val, y.val⁆, L'.lie_mem' x.property y.property⟩ + lie_add x y z := by aesop + add_lie x y z := by aesop + lie_self x := by aesop + leibniz_lie x y z := by aesop + +variable {A L} +variable (L' : LieRinehartSubalgebra A L) + +protected theorem zero_mem : (0 : L) ∈ L' := + zero_mem L' + +protected theorem add_mem {x y : L} : x ∈ L' → y ∈ L' → (x + y : L) ∈ L' := + add_mem + +protected theorem sub_mem {x y : L} : x ∈ L' → y ∈ L' → (x - y : L) ∈ L' := + sub_mem + +protected theorem smul_mem (t : A) {x : L} (h : x ∈ L') : t • x ∈ L' := + SMulMemClass.smul_mem _ h + +theorem lie_mem {x y : L} (hx : x ∈ L') (hy : y ∈ L') : (⁅x, y⁆ : L) ∈ L' := + L'.lie_mem' hx hy + +theorem mem_carrier {x : L} : x ∈ L'.carrier ↔ x ∈ (L' : Set L) := + Iff.rfl + +theorem mem_mk_iff (S : Set L) (h₁ h₂ h₃ h₄) {x : L} : + x ∈ (⟨⟨⟨⟨S, h₁⟩, h₂⟩, h₃⟩, h₄⟩ : LieRinehartSubalgebra A L) ↔ x ∈ S := + Iff.rfl + +@[simp] +theorem mem_toSubmodule {x : L} : x ∈ L'.toSubmodule ↔ x ∈ L' := + Iff.rfl + +@[simp] +theorem mem_mk_iff' (p : Submodule A L) (h) {x : L} : + x ∈ (⟨p, h⟩ : LieRinehartSubalgebra A L) ↔ x ∈ p := + Iff.rfl + +theorem mem_coe {x : L} : x ∈ (L' : Set L) ↔ x ∈ L' := + Iff.rfl + +@[simp, norm_cast] +theorem coe_bracket (x y : L') : (↑⁅x, y⁆ : L) = ⁅(↑x : L), ↑y⁆ := + rfl + +theorem ext_iff (x y : L') : x = y ↔ (x : L) = y := Subtype.ext_iff + +theorem coe_zero_iff_zero (x : L') : (x : L) = 0 ↔ x = 0 := (ext_iff L' x 0).symm + +@[ext] +theorem ext (L₁' L₂' : LieRinehartSubalgebra A L) (h : ∀ x, x ∈ L₁' ↔ x ∈ L₂') : L₁' = L₂' := + SetLike.ext h + +theorem ext_iff' (L₁' L₂' : LieRinehartSubalgebra A L) : L₁' = L₂' ↔ ∀ x, x ∈ L₁' ↔ x ∈ L₂' := + SetLike.ext_iff + +@[simp] +theorem mk_coe (S : Set L) (h₁ h₂ h₃ h₄) : + ((⟨⟨⟨⟨S, h₁⟩, h₂⟩, h₃⟩, h₄⟩ : LieRinehartSubalgebra A L) : Set L) = S := + rfl + +theorem toSubmodule_mk (p : Submodule A L) (h) : + ({ p with lie_mem' := h } : LieRinehartSubalgebra A L).toSubmodule = p := rfl + +theorem coe_injective : Function.Injective ((↑) : LieRinehartSubalgebra A L → Set L) := + SetLike.coe_injective + +@[norm_cast] +theorem coe_set_eq (L₁' L₂' : LieRinehartSubalgebra A L) : (L₁' : Set L) = L₂' ↔ L₁' = L₂' := + SetLike.coe_set_eq + +theorem toSubmodule_injective : Function.Injective (toSubmodule (A := A) (L := L)) := by + intro L₁' L₂' h + rw [SetLike.ext'_iff] at h + rw [← coe_set_eq] + exact h + +theorem coe_toSubmodule : (L'.toSubmodule : Set L) = L' := + rfl + +section LieModule + +variable {M : Type*} [AddCommGroup M] [LieRingModule L M] + +instance : Bracket L' M where + bracket x m := ⁅(x : L), m⁆ + +@[simp] +theorem coe_bracket_of_module (x : L') (m : M) : ⁅x, m⁆ = ⁅(x : L), m⁆ := + rfl + +instance : IsLieTower L' L M where + leibniz_lie x y m := leibniz_lie x.val y m + +/-- Given a Lie-Rinehart algebra `L` containing a LieRinehart subalgebra `L' ⊆ L`, together with a +Lie ring module `M` of `L`, we may regard `M` as a Lie ring module of `L'` by restriction. -/ +instance lieRingModule : LieRingModule L' M where + add_lie x y m := add_lie (x : L) y m + lie_add x y m := lie_add (x : L) y m + leibniz_lie x y m := leibniz_lie x (y : L) m + +end LieModule + +variable [LieRingModule L A] [LieRinehartRing A L] + +/-- A Lie-Rinehart subalgebra of a Lie-Rinehart ring forms a new Lie-Rinehart ring. -/ +instance : LieRinehartRing A L' where + lie_smul_eq_mul' a b x := LieRinehartRing.lie_smul_eq_mul a b (x : L) + leibniz_mul_right' x a b := LieRinehartRing.leibniz_mul_right (x : L) a b + leibniz_smul_right' _ _ _ := by simp [ext_iff] + +variable (R : Type*) [CommRing R] [Algebra R A] [LieAlgebra R L] [LieRinehartAlgebra R A L] + +/-- A Lie-Rinehart subalgebra of a Lie-Rinehart algebra forms a Lie algebra. -/ +instance lieAlgebra : LieAlgebra R L' where + lie_smul := by aesop + +/-- Converts a Lie-Rinehart subalgebra to the corresponding Lie subalgebra. -/ +@[expose] def toLieSubalgebra : LieSubalgebra R L where + toSubmodule := L'.toSubmodule.restrictScalars R + lie_mem' := L'.lie_mem' + +theorem toLieSubalgebra_injective : Function.Injective (fun L' => + L'.toLieSubalgebra R : LieRinehartSubalgebra A L → LieSubalgebra R L) := fun L₁' L₂' h ↦ by + rw [SetLike.ext'_iff] at h + rw [← coe_set_eq] + exact h + +@[simp] +theorem toLieSubalgebra_inj (L₁' L₂' : LieRinehartSubalgebra A L) : + (L₁'.toLieSubalgebra R) = (L₂'.toLieSubalgebra R) ↔ L₁' = L₂' := + (toLieSubalgebra_injective R).eq_iff + +theorem coe_toLieSubalgebra : ((L'.toLieSubalgebra R) : Set L) = L' := rfl + +section LieModule + +variable {M : Type*} [AddCommGroup M] [LieRingModule L M] [Module R M] + +/-- Given a Lie-Rinehart algebra `L` containing a LieRinehart subalgebra `L' ⊆ L`, together with a + Lie module `M` of `L`, we may regard `M` as a Lie module of `L'` by restriction. -/ +instance lieModule [LieModule R L M] : LieModule R L' M where + smul_lie t x m := by + rw [coe_bracket_of_module, Submodule.coe_smul_of_tower, smul_lie, coe_bracket_of_module] + lie_smul t x m := by simp only [coe_bracket_of_module, lie_smul] + +end LieModule + +/-- A Lie-Rinehart subalgebra forms a new Lie-Rinehart algebra. -/ +instance : LieRinehartAlgebra R A L' where + +/-- The embedding of a Lie-Rinehart subalgebra into the ambient space as a morphism of +Lie-Rinehart algebras. -/ +@[expose] def incl : L' →ₗ⁅(AlgHom.id R A)⁆ L where + __ := L'.toSubmodule.subtype.restrictScalars R + map_lie' {x y} := coe_bracket L' x y + map_smul_apply' a x := L'.toSubmodule.subtype.map_smul a x + apply_lie' a x := AlgHom.id_apply ⁅x, a⁆ + +@[simp] +theorem coe_incl : ⇑(L'.incl R) = ((↑) : L' → L) := rfl + +end LieRinehartSubalgebra From 3685731497f316bb1b3ecbfa8282eca31494b20b Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:16:51 +0000 Subject: [PATCH 0196/1300] feat: add `contMDiffWithinAt_iff_of_mem_maximalAtlas'` (#40810) Add a version of `contMDiffWithinAt_iff_of_mem_maximalAtlas` specialized of to the source chart being the preferred chart at that point: this way, we can apply it without requiring an `IsManifold` instance to conclude the extended chart being in the maximal atlas. This allows avoiding an `IsManifold` hypothesis in #28865. --- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 66 ++++++++++++------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index 1a717ac3747ca5..e823fee3758e25 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -281,36 +281,37 @@ theorem contMDiffAt_iff_target {x : M} : ContinuousAt f x ∧ ContMDiffAt I 𝓘(𝕜, E') n (extChartAt I' (f x) ∘ f) x := by rw [ContMDiffAt, ContMDiffAt, contMDiffWithinAt_iff_target, continuousWithinAt_univ] +theorem continuousWithinAt_iff_source : + ContinuousWithinAt f s x ↔ + ContinuousWithinAt (f ∘ (extChartAt I x).symm) + ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · apply h.comp_of_eq + · exact (continuousAt_extChartAt_symm x).continuousWithinAt + · exact (mapsTo_preimage _ _).mono_left inter_subset_left + · exact extChartAt_to_inv x + · rw [← continuousWithinAt_inter (extChartAt_source_mem_nhds (I := I) x)] + have : ContinuousWithinAt ((f ∘ ↑(extChartAt I x).symm) ∘ ↑(extChartAt I x)) + (s ∩ (extChartAt I x).source) x := by + apply h.comp (continuousAt_extChartAt x).continuousWithinAt + intro y hy + have : (chartAt H x).symm ((chartAt H x) y) = y := + OpenPartialHomeomorph.left_inv _ (by simpa using hy.2) + simpa [this] using hy.1 + apply this.congr + · intro y hy + have : (chartAt H x).symm ((chartAt H x) y) = y := + OpenPartialHomeomorph.left_inv _ (by simpa using hy.2) + simp [this] + · simp + /-- One can reformulate being `Cⁿ` within a set at a point as being `Cⁿ` in the source space when composing with the extended chart. -/ theorem contMDiffWithinAt_iff_source : ContMDiffWithinAt I I' n f s x ↔ ContMDiffWithinAt 𝓘(𝕜, E) I' n (f ∘ (extChartAt I x).symm) ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by - simp_rw [ContMDiffWithinAt, liftPropWithinAt_iff'] - have : ContinuousWithinAt f s x - ↔ ContinuousWithinAt (f ∘ ↑(extChartAt I x).symm) (↑(extChartAt I x).symm ⁻¹' s ∩ range ↑I) - (extChartAt I x x) := by - refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ - · apply h.comp_of_eq - · exact (continuousAt_extChartAt_symm x).continuousWithinAt - · exact (mapsTo_preimage _ _).mono_left inter_subset_left - · exact extChartAt_to_inv x - · rw [← continuousWithinAt_inter (extChartAt_source_mem_nhds (I := I) x)] - have : ContinuousWithinAt ((f ∘ ↑(extChartAt I x).symm) ∘ ↑(extChartAt I x)) - (s ∩ (extChartAt I x).source) x := by - apply h.comp (continuousAt_extChartAt x).continuousWithinAt - intro y hy - have : (chartAt H x).symm ((chartAt H x) y) = y := - OpenPartialHomeomorph.left_inv _ (by simpa using hy.2) - simpa [this] using hy.1 - apply this.congr - · intro y hy - have : (chartAt H x).symm ((chartAt H x) y) = y := - OpenPartialHomeomorph.left_inv _ (by simpa using hy.2) - simp [this] - · simp - rw [← this] + simp_rw [ContMDiffWithinAt, liftPropWithinAt_iff', ← continuousWithinAt_iff_source] simp only [ContDiffWithinAtProp, mfld_simps, preimage_comp, comp_assoc] /-- One can reformulate being `Cⁿ` at a point as being `Cⁿ` in the source space when @@ -383,6 +384,23 @@ theorem contMDiffWithinAt_iff_of_mem_maximalAtlas (he : e ∈ maximalAtlas I n M ((e.extend I).symm ⁻¹' s ∩ range I) (e.extend I x) := (contDiffWithinAt_localInvariantProp n).liftPropWithinAt_indep_chart he hx he' hy +/-- An alternative version of `contMDiffWithinAt_iff_of_mem_maximalAtlas` which takes a +chart `e'` in the target in the maximal atlas, but uses the preferred chart on the domain. -/ +theorem contMDiffWithinAt_iff_of_mem_maximalAtlas' + (he' : e' ∈ maximalAtlas I' n M') (hy : f x ∈ e'.source) : + ContMDiffWithinAt I I' n f s x ↔ + ContinuousWithinAt f s x ∧ + ContDiffWithinAt 𝕜 n (e'.extend I' ∘ f ∘ (extChartAt I x).symm) + ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by + rw [contMDiffWithinAt_iff_source, + contMDiffWithinAt_iff_target_of_mem_maximalAtlas he' (by simpa)] + apply and_congr continuousWithinAt_iff_source.symm + -- TODO: this is `contMDiffWithinAt_iff_contDiffWithinAt` copied, + -- which is not put here for import reasons + simp +contextual only [ContMDiffWithinAt, liftPropWithinAt_iff', + ContDiffWithinAtProp, iff_def, mfld_simps] + exact ContDiffWithinAt.continuousWithinAt + /-- An alternative formulation of `contMDiffWithinAt_iff_of_mem_maximalAtlas` if the set `s` lies in `e.source`. -/ theorem contMDiffWithinAt_iff_image From 1220aa6023f69a3283decf8e204984a6075cd9bd Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Fri, 19 Jun 2026 19:19:23 +0000 Subject: [PATCH 0197/1300] refactor: make `{Con,AddCon,RingCon}.congr` match `Quotient.congr` (#40819) This adds an explicit equivalence argument, rather than defaulting it to `refl`. Also adds a missing `symm` lemma for each. --- Mathlib/GroupTheory/Congruence/Basic.lean | 30 ++++++++----- Mathlib/RingTheory/Congruence/Hom.lean | 55 ++++++++++++++--------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/Mathlib/GroupTheory/Congruence/Basic.lean b/Mathlib/GroupTheory/Congruence/Basic.lean index 3700a2bd93fbdf..ef9728e074efa5 100644 --- a/Mathlib/GroupTheory/Congruence/Basic.lean +++ b/Mathlib/GroupTheory/Congruence/Basic.lean @@ -63,17 +63,25 @@ def pi {ι : Type*} {f : ι → Type*} [∀ i, Mul (f i)] (C : ∀ i, Con (f i)) { @piSetoid _ _ fun i => (C i).toSetoid with mul' := fun h1 h2 i => (C i).mul (h1 i) (h2 i) } -/-- Makes an isomorphism of quotients by two congruence relations, given that the relations are -equal. -/ -@[to_additive /-- Makes an additive isomorphism of quotients by two additive congruence relations, -given that the relations are equal. -/] -protected def congr {c d : Con M} (h : c = d) : c.Quotient ≃* d.Quotient := - { Quotient.congr (Equiv.refl M) <| by apply Con.ext_iff.mp h with - map_mul' := fun x y => by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl } +/-- A multiplicative equivalence `e : α ≃* β` generates an equivalence between quotient spaces, +if it is compatible with the relations. -/ +@[to_additive +/-- An additive equivalence `e : α ≃+ β` generates an equivalence between quotient spaces, +if it is compatible with the relations. -/] +protected def congr {c : Con M} {d : Con N} (e : M ≃* N) (h : c = d.comap e (map_mul e)) : + c.Quotient ≃* d.Quotient where + __ := Quotient.congr e <| by apply Con.ext_iff.mp h + map_mul' := by rintro ⟨x⟩ ⟨y⟩; exact congrArg toQuotient (e.map_mul x y) @[to_additive (attr := simp)] -theorem congr_mk {c d : Con M} (h : c = d) (a : M) : - Con.congr h (a : c.Quotient) = (a : d.Quotient) := rfl +theorem congr_mk {c : Con M} {d : Con N} (e : M ≃* N) (h : c = d.comap e (map_mul e)) (a : M) : + Con.congr e h (a : c.Quotient) = (e a : d.Quotient) := rfl + +@[to_additive (attr := simp)] +theorem congr_symm {c : Con M} {d : Con N} (e : M ≃* N) (h : c = d.comap e (map_mul e)) : + (Con.congr e h).symm = + Con.congr e.symm (ext <| e.surjective.forall₂.2 <| by simp [h]) := + rfl @[to_additive] theorem comap_conGen_equiv {M N : Type*} [Mul M] [Mul N] (f : MulEquiv M N) (rel : N → N → Prop) : @@ -220,7 +228,7 @@ noncomputable def quotientKerEquivOfSurjective (f : M →* P) (hf : Surjective f AddCon N -/] noncomputable def comapQuotientEquivOfSurj (c : Con M) (f : N →* M) (hf : Function.Surjective f) : (Con.comap f f.map_mul c).Quotient ≃* c.Quotient := - (Con.congr Con.comap_eq).trans <| Con.quotientKerEquivOfSurjective (c.mk'.comp f) <| + (Con.congr (.refl _) Con.comap_eq).trans <| Con.quotientKerEquivOfSurjective (c.mk'.comp f) <| Con.mk'_surjective.comp hf @[to_additive (attr := simp)] @@ -244,7 +252,7 @@ lemma comapQuotientEquivOfSurj_symm_mk' (c : Con M) (f : N ≃* M) (x : N) : @[to_additive /-- The second isomorphism theorem for `AddMonoid`s. -/] noncomputable def comapQuotientEquiv (f : N →* M) : (comap f f.map_mul c).Quotient ≃* MonoidHom.mrange (c.mk'.comp f) := - (Con.congr comap_eq).trans <| quotientKerEquivRange <| c.mk'.comp f + (Con.congr (.refl _) comap_eq).trans <| quotientKerEquivRange <| c.mk'.comp f /-- The **third isomorphism theorem for monoids**. -/ @[to_additive /-- The third isomorphism theorem for `AddMonoid`s. -/] diff --git a/Mathlib/RingTheory/Congruence/Hom.lean b/Mathlib/RingTheory/Congruence/Hom.lean index 29f28b9dcabf2a..485dbe2a79ad80 100644 --- a/Mathlib/RingTheory/Congruence/Hom.lean +++ b/Mathlib/RingTheory/Congruence/Hom.lean @@ -80,16 +80,21 @@ theorem comap_eq {g : N →+* M} : c.comap g = ker (c.mk'.comp g) := by rw [ker_comp, ker_mk'_eq] -/-- Makes an isomorphism of quotients by two ring congruence -relations, given that the relations are equal. -/ -protected def congr (h : c = d) : - c.Quotient ≃+* d.Quotient := - { Quotient.congr (Equiv.refl M) <| by apply RingCon.ext_iff.mp h with - map_add' x y := by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl - map_mul' x y := by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl } - -@[simp] theorem congr_mk (h : c = d) (a : M) : - RingCon.congr h (a : c.Quotient) = (a : d.Quotient) := rfl +/-- An isomorphism of rings `e : M ≃+* N` generates an isomorphism between quotient spaces, +if it is compatible with the relations. -/ +protected def congr {c : RingCon M} {d : RingCon N} (e : M ≃+* N) (h : c = d.comap e) : + c.Quotient ≃+* d.Quotient where + __ := Quotient.congr e <| by apply RingCon.ext_iff.mp h + map_mul' := by rintro ⟨x⟩ ⟨y⟩; exact congrArg toQuotient (e.map_mul x y) + map_add' := by rintro ⟨x⟩ ⟨y⟩; exact congrArg toQuotient (e.map_add x y) + +@[simp] theorem congr_mk {c : RingCon M} {d : RingCon N} (e : M ≃+* N) (h : c = d.comap e) (a : M) : + RingCon.congr e h (a : c.Quotient) = (e a : d.Quotient) := rfl + +@[simp] theorem congr_symm {c : RingCon M} {d : RingCon N} (e : M ≃+* N) (h : c = d.comap e) : + (RingCon.congr e h).symm = + RingCon.congr e.symm (ext <| e.surjective.forall₂.2 <| by simp [h]) := + rfl /-- Given a function `f`, the smallest ring congruence relation containing the binary relation on `f`'s image defined by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to @@ -321,7 +326,7 @@ noncomputable def comapQuotientEquivOfSurj (c : RingCon M) (f : N →+* M) (hf : Function.Surjective f) {d : RingCon N} (hcd : d = c.comap f) : d.Quotient ≃+* c.Quotient := - (RingCon.congr (hcd.trans c.comap_eq)).trans + (RingCon.congr (.refl _) (hcd.trans c.comap_eq)).trans <| RingCon.quotientKerEquivOfSurjective (c.mk'.comp f) (c.mk'_surjective.comp hf) @@ -348,7 +353,7 @@ noncomputable def comapQuotientEquivOfSurj noncomputable def comapQuotientEquivRangeS (f : N →+* M) {d : RingCon N} (hcd : d = comap c f) : d.Quotient ≃+* RingHom.rangeS (c.mk'.comp f) := - (RingCon.congr (hcd.trans comap_eq)).trans <| quotientKerEquivRangeS <| c.mk'.comp f + (RingCon.congr (.refl _) (hcd.trans comap_eq)).trans <| quotientKerEquivRangeS <| c.mk'.comp f @[simp] theorem comapQuotientEquivRangeS_mk (f : N →+* M) {d : RingCon N} (hcd : d = comap c f) (x : N) : @@ -449,15 +454,21 @@ variable {R : Type*} [CommSemiring R] variable {c d : RingCon M} {f : M →ₐ[R] P} variable (R) in -/-- Makes an algebra isomorphism of quotients by two ring congruence -relations, given that the relations are equal. -/ -protected def congrₐ {c d : RingCon M} (h : c = d) : - c.Quotient ≃ₐ[R] d.Quotient := - { RingCon.congr h with - commutes' _ := rfl } - -theorem congrₐ_mk {c d : RingCon M} (h : c = d) (a : M) : - RingCon.congrₐ R h (a : c.Quotient) = (a : d.Quotient) := +/-- An isomorphism of algebras `e : M ≃ₐ[R] N` generates an isomorphism between quotient spaces, +if it is compatible with the relations. -/ +protected def congrₐ {c : RingCon M} {d : RingCon N} (e : M ≃ₐ[R] N) (h : c = d.comap e) : + c.Quotient ≃ₐ[R] d.Quotient where + __ := RingCon.congr e h + commutes' r := by simp [← coe_algebraMap] + +@[simp] +theorem congrₐ_mk {c : RingCon M} {d : RingCon N} (e : M ≃ₐ[R] N) (h : c = d.comap e) (a : M) : + RingCon.congrₐ R e h (a : c.Quotient) = (e a : d.Quotient) := + rfl + +@[simp] theorem congrₐ_symm {c : RingCon M} {d : RingCon N} (e : M ≃ₐ[R] N) (h : c = d.comap e) : + (RingCon.congrₐ R e h).symm = + RingCon.congrₐ R e.symm (ext <| e.surjective.forall₂.2 <| by simp [h]) := rfl theorem range_mkₐ : AlgHom.range (mkₐ R c) = ⊤ := @@ -570,7 +581,7 @@ theorem quotientKerEquivRangeₐ_comp_mkₐ (φ : M →ₐ[R] N) : /-- The **second isomorphism theorem for algebras**. -/ noncomputable def comapQuotientEquivRangeₐ (f : N →ₐ[R] M) {d : RingCon N} (h : d = comap c f) : d.Quotient ≃ₐ[R] AlgHom.range ((c.mkₐ _).comp f) := - (RingCon.congrₐ R (h.trans comap_eq)).trans <| quotientKerEquivRangeₐ ((c.mkₐ _).comp f) + (RingCon.congrₐ R .refl (h.trans comap_eq)).trans <| quotientKerEquivRangeₐ ((c.mkₐ _).comp f) theorem comapQuotientEquivRangeₐ_mk (f : N →ₐ[R] M) {d : RingCon N} (h : d = comap c f) (x : N) : c.comapQuotientEquivRangeₐ f h x = ⟨f x, AlgHom.mem_range_self _ x⟩ := From 5392b8aa32a2d5f6d24ab5c9e76ea4fd1c593538 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Fri, 19 Jun 2026 19:54:38 +0000 Subject: [PATCH 0198/1300] chore: move RingQuot results (#40823) This is prework for swapping `FreeProduct` to use `RingCon` instead of `RingQuot`; at which point this would allow the import to be removed from that file entirely. I renamed `R` to `S` in the move, to match the ambient variables in the destination. I haven't attempted to golf the proofs since my intent is to ultimately deprecate the entire destination file. --- Mathlib/Algebra/RingQuot.lean | 34 +++++++++++++++++- Mathlib/LinearAlgebra/FreeProduct/Basic.lean | 37 -------------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/Mathlib/Algebra/RingQuot.lean b/Mathlib/Algebra/RingQuot.lean index 6bb7fc25be788b..b5a17e7e40604c 100644 --- a/Mathlib/Algebra/RingQuot.lean +++ b/Mathlib/Algebra/RingQuot.lean @@ -5,7 +5,7 @@ Authors: Kim Morrison -/ module -public import Mathlib.Algebra.Algebra.Hom +public import Mathlib.Algebra.Algebra.Equiv public import Mathlib.RingTheory.Congruence.Basic public import Mathlib.RingTheory.Ideal.Quotient.Defs public import Mathlib.RingTheory.Ideal.Span @@ -546,6 +546,38 @@ theorem eq_liftAlgHom_comp_mkAlgHom {s : A → A → Prop} (f : RingQuot s → f = liftAlgHom S ⟨f.comp (mkAlgHom S s), fun _ _ h ↦ congr_arg f (mkAlgHom_rel S h)⟩ := liftAlgHom_unique S (f.comp (mkAlgHom S s)) (fun _ _ h ↦ congr_arg (⇑f) (mkAlgHom_rel S h)) f rfl +open scoped Function -- required for scoped `on` notation + +variable {S} + +/-- If two `S`-algebras are `S`-equivalent and their quotients by a relation `rel` are defined, +then their quotients are also `S`-equivalent. + +(Special case of the third isomorphism theorem.) -/ +def algEquivQuotAlgEquiv (f : A ≃ₐ[S] B) (rel : A → A → Prop) : + RingQuot rel ≃ₐ[S] RingQuot (rel on f.symm) := + AlgEquiv.ofAlgHom + (RingQuot.liftAlgHom S (s := rel) + ⟨AlgHom.comp (RingQuot.mkAlgHom S (rel on f.symm)) f, + fun x y h_rel ↦ by + apply RingQuot.mkAlgHom_rel + simpa [Function.onFun]⟩) + ((RingQuot.liftAlgHom S (s := rel on f.symm) + ⟨AlgHom.comp (RingQuot.mkAlgHom S rel) f.symm, + fun x y h ↦ by apply RingQuot.mkAlgHom_rel; simpa⟩)) + (by ext b; simp) (by ext a; simp) + +/-- If two (semi)rings are equivalent and their quotients by a relation `rel` are defined, +then their quotients are also equivalent. + +(Special case of `algEquivQuotAlgEquiv` when `S = ℕ`, which in turn is a special +case of the third isomorphism theorem.) -/ +def equivQuotEquiv (f : A ≃+* B) (rel : A → A → Prop) : + RingQuot rel ≃+* RingQuot (rel on f.symm) := + let f_alg : A ≃ₐ[ℕ] B := + AlgEquiv.ofRingEquiv (f := f) (fun n ↦ by simp) + algEquivQuotAlgEquiv f_alg rel |>.toRingEquiv + end Algebra end RingQuot diff --git a/Mathlib/LinearAlgebra/FreeProduct/Basic.lean b/Mathlib/LinearAlgebra/FreeProduct/Basic.lean index 48423cfb9ad65b..af6700f7588803 100644 --- a/Mathlib/LinearAlgebra/FreeProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/FreeProduct/Basic.lean @@ -65,43 +65,6 @@ theorem induction_lon {R : Type*} [Semiring R] {ι : Type*} [DecidableEq ι] end DirectSum -namespace RingQuot -universe uS uA uB - -open scoped Function -- required for scoped `on` notation - -/-- If two `R`-algebras are `R`-equivalent and their quotients by a relation `rel` are defined, -then their quotients are also `R`-equivalent. - -(Special case of the third isomorphism theorem.) -/ -def algEquivQuotAlgEquiv - {R : Type u} [CommSemiring R] {A B : Type v} [Semiring A] [Semiring B] - [Algebra R A] [Algebra R B] (f : A ≃ₐ[R] B) (rel : A → A → Prop) : - RingQuot rel ≃ₐ[R] RingQuot (rel on f.symm) := - AlgEquiv.ofAlgHom - (RingQuot.liftAlgHom R (s := rel) - ⟨AlgHom.comp (RingQuot.mkAlgHom R (rel on f.symm)) f, - fun x y h_rel ↦ by - apply RingQuot.mkAlgHom_rel - simpa [Function.onFun]⟩) - ((RingQuot.liftAlgHom R (s := rel on f.symm) - ⟨AlgHom.comp (RingQuot.mkAlgHom R rel) f.symm, - fun x y h ↦ by apply RingQuot.mkAlgHom_rel; simpa⟩)) - (by ext b; simp) (by ext a; simp) - -/-- If two (semi)rings are equivalent and their quotients by a relation `rel` are defined, -then their quotients are also equivalent. - -(Special case of `algEquiv_quot_algEquiv` when `R = ℕ`, which in turn is a special -case of the third isomorphism theorem.) -/ -def equivQuotEquiv {A B : Type v} [Semiring A] [Semiring B] (f : A ≃+* B) (rel : A → A → Prop) : - RingQuot rel ≃+* RingQuot (rel on f.symm) := - let f_alg : A ≃ₐ[ℕ] B := - AlgEquiv.ofRingEquiv (f := f) (fun n ↦ by simp) - algEquivQuotAlgEquiv f_alg rel |>.toRingEquiv - -end RingQuot - open TensorAlgebra DirectSum TensorPower variable {I : Type u} [DecidableEq I] {i : I} -- The type of the indexing set From 7ba890ea1765d6395f6236529f9e4e8cae006bb0 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Fri, 19 Jun 2026 20:08:12 +0000 Subject: [PATCH 0199/1300] feat: add `Homeomorph.chartedSpace` (#39107) Mathlib already has `IsLocalHomeomorph.chartedSpace`, which we can re-use. #40202 shows that this charted space is a `C^n` manifold whenever the initial manifold is one. --- Mathlib/Geometry/Manifold/ChartedSpace.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index c5f1f48b6ac267..59a70521d47941 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -591,6 +591,12 @@ def IsLocalHomeomorph.chartedSpace ChartedSpace H M' := hf.chartedSpaceOfRightInverse hf'.hasRightInverse.choose_spec +/-- Given a homeomorphism `f : M ≃ₜ M'`, endow `M'` with a `ChartedSpace` structure by pushing +forward the `ChartedSpace` structure from `M`. -/ +@[implicit_reducible] +def Homeomorph.chartedSpace (f : M ≃ₜ M') : ChartedSpace H M' := + f.isLocalHomeomorph.chartedSpace f.surjective + end IsLocalHomeomorph end Constructions From 005f0aa67b6922eb1a8f5209fd0e707aeb867945 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Fri, 19 Jun 2026 20:08:14 +0000 Subject: [PATCH 0200/1300] chore: remove an unused import (#40825) --- Mathlib/RingTheory/Congruence/Hom.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/RingTheory/Congruence/Hom.lean b/Mathlib/RingTheory/Congruence/Hom.lean index 485dbe2a79ad80..5e7a93606ddf80 100644 --- a/Mathlib/RingTheory/Congruence/Hom.lean +++ b/Mathlib/RingTheory/Congruence/Hom.lean @@ -12,7 +12,6 @@ public import Mathlib.Algebra.Group.Hom.Defs public import Mathlib.RingTheory.Congruence.Basic public import Mathlib.Algebra.Ring.Subsemiring.Basic public import Mathlib.Algebra.Ring.Subring.Basic -public import Mathlib.Algebra.RingQuot /-! # Congruence relations and ring homomorphisms From d3d49a109bea04e0f3b9bf33b43d2ad80ec33c09 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Sat, 20 Jun 2026 03:11:37 +0000 Subject: [PATCH 0201/1300] feat: conditions for commuting with a unitary element (#40516) --- Mathlib/Algebra/Group/Submonoid/Basic.lean | 4 ++++ Mathlib/Algebra/Star/Unitary.lean | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Mathlib/Algebra/Group/Submonoid/Basic.lean b/Mathlib/Algebra/Group/Submonoid/Basic.lean index 133c0073fadcfa..e080248b0791ed 100644 --- a/Mathlib/Algebra/Group/Submonoid/Basic.lean +++ b/Mathlib/Algebra/Group/Submonoid/Basic.lean @@ -361,6 +361,10 @@ theorem IsUnit.mem_submonoid_iff {M : Type*} [Monoid M] (a : M) : end IsUnit +@[simp] lemma Submonoid.commute_coe_coe {S M : Type*} [Mul M] [SetLike S M] + [MulMemClass S M] {s : S} {x y : s} : Commute (x : M) (y : M) ↔ Commute x y := by + simp [commute_iff_eq, Subtype.ext_iff] + namespace MonoidHom open Submonoid diff --git a/Mathlib/Algebra/Star/Unitary.lean b/Mathlib/Algebra/Star/Unitary.lean index c9164a65c0508e..3cf41580a98415 100644 --- a/Mathlib/Algebra/Star/Unitary.lean +++ b/Mathlib/Algebra/Star/Unitary.lean @@ -189,6 +189,23 @@ instance coe_isStarNormal (u : unitary R) : IsStarNormal (u : R) where lemma _root_.isStarNormal_of_mem_unitary {u : R} (hu : u ∈ unitary R) : IsStarNormal u := coe_isStarNormal ⟨u, hu⟩ +lemma commute_self_star (u : unitary R) : Commute u (star u) := by simp [commute_iff_eq] +lemma commute_star_self (u : unitary R) : Commute (star u) u := by simp [commute_iff_eq] + +lemma _root_.commute_unitary_star_self {u : R} (hu : u ∈ unitary R) : Commute (star u) u := + isStarNormal_of_mem_unitary hu |>.star_comm_self + +lemma _root_.commute_unitary_self_star {u : R} (hu : u ∈ unitary R) : Commute u (star u) := + commute_unitary_star_self hu |>.symm + +lemma _root_.commute_unitary_iff_star_left_conjugate {x u : R} (hu : u ∈ unitary R) : + Commute u x ↔ star u * x * u = x := by + simpa using! (Unitary.toUnits ⟨u, hu⟩).commute_iff_inv_mul_cancel + +lemma _root_.commute_unitary_iff_star_right_conjugate {x u : R} (hu : u ∈ unitary R) : + Commute u x ↔ u * x * star u = x := by + simpa using! (Unitary.toUnits ⟨u, hu⟩).commute_iff_mul_inv_cancel + end Monoid end Unitary From 6eb4a1ce07e071ac0f8365e6999a3135b45d8ae4 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Sat, 20 Jun 2026 03:53:49 +0000 Subject: [PATCH 0202/1300] =?UTF-8?q?feat:=20in=20a=20dense=20order,=20`?= =?UTF-8?q?=F0=9D=93=9D[<]=20a`=20has=20`fun=20x=20=E2=86=A6=20Ico=20x=20a?= =?UTF-8?q?`=20as=20a=20basis=20(#40523)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Topology/Order/LeftRightNhds.lean | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Mathlib/Topology/Order/LeftRightNhds.lean b/Mathlib/Topology/Order/LeftRightNhds.lean index 5925877c50128b..6d518605ac27d8 100644 --- a/Mathlib/Topology/Order/LeftRightNhds.lean +++ b/Mathlib/Topology/Order/LeftRightNhds.lean @@ -78,6 +78,18 @@ theorem nhdsGT_basis_of_exists_gt {a : α} (h : ∃ b, a < b) : (𝓝[>] a).HasB lemma nhdsGT_basis [NoMaxOrder α] (a : α) : (𝓝[>] a).HasBasis (a < ·) (Ioo a) := nhdsGT_basis_of_exists_gt <| exists_gt a +lemma nhdsGT_basis_Ioc_of_exists_gt [DenselyOrdered α] {a : α} (h : ∃ b, a < b) : + (𝓝[>] a).HasBasis (fun x ↦ a < x) (Ioc a) := + nhdsGT_basis_of_exists_gt h |>.to_hasBasis' + (fun _ hac ↦ + have ⟨b, hab, hbc⟩ := exists_between hac + ⟨b, hab, Ioc_subset_Ioo_right hbc⟩) + fun _ hac ↦ mem_of_superset ((nhdsGT_basis_of_exists_gt h).mem_of_mem hac) Ioo_subset_Ioc_self + +lemma nhdsGT_basis_Ioc [DenselyOrdered α] [NoMaxOrder α] (a : α) : + (𝓝[>] a).HasBasis (fun x ↦ a < x) (Ioc a) := + nhdsGT_basis_Ioc_of_exists_gt <| exists_gt a + theorem nhdsGT_eq_bot_iff {a : α} : 𝓝[>] a = ⊥ ↔ IsTop a ∨ ∃ b, a ⋖ b := by by_cases ha : IsTop a · simp [ha, ha.isMax.Ioi_eq] @@ -210,6 +222,18 @@ theorem nhdsLT_basis_of_exists_lt {a : α} (h : ∃ b, b < a) : (𝓝[<] a).HasB theorem nhdsLT_basis [NoMinOrder α] (a : α) : (𝓝[<] a).HasBasis (· < a) (Ioo · a) := nhdsLT_basis_of_exists_lt <| exists_lt a +lemma nhdsLT_basis_Ico_of_exists_lt [DenselyOrdered α] {a : α} (h : ∃ b, b < a) : + (𝓝[<] a).HasBasis (· < a) (Ico · a) := + nhdsLT_basis_of_exists_lt h |>.to_hasBasis' + (fun _ hac ↦ + have ⟨b, hab, hbc⟩ := exists_between hac + ⟨b, hbc, Ico_subset_Ioo_left hab⟩) + fun _ hac ↦ mem_of_superset ((nhdsLT_basis_of_exists_lt h).mem_of_mem hac) Ioo_subset_Ico_self + +lemma nhdsLT_basis_Ico [DenselyOrdered α] [NoMinOrder α] (a : α) : + (𝓝[<] a).HasBasis (· < a) (Ico · a) := + nhdsLT_basis_Ico_of_exists_lt <| exists_lt a + theorem nhdsLT_eq_bot_iff {a : α} : 𝓝[<] a = ⊥ ↔ IsBot a ∨ ∃ b, b ⋖ a := by convert! (config := { preTransparency := .default }) nhdsGT_eq_bot_iff (a := OrderDual.toDual a) using 4 From 887d94632e78e6e41701cf57c3e7206c6c2b1e5b Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sat, 20 Jun 2026 05:51:14 +0000 Subject: [PATCH 0203/1300] doc(1000-yaml): we don't have Cauchy's integral theorem (#40335) The [referenced declaration](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Analysis/Complex/CauchyIntegral.html#Complex.circleIntegral_div_sub_of_differentiable_on_off_countable) is [Cauchy's integral formula](https://en.wikipedia.org/wiki/Cauchy%27s_integral_formula), not [Cauchy's integral theorem](https://en.wikipedia.org/wiki/Cauchy%27s_integral_theorem). We do have [`DiffContOnCl.circleIntegral_eq_zero`](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Analysis/Complex/CauchyIntegral.html#DiffContOnCl.circleIntegral_eq_zero) for circle contours. --- docs/1000.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/1000.yaml b/docs/1000.yaml index 55f54757b9fe15..a500e287af5204 100644 --- a/docs/1000.yaml +++ b/docs/1000.yaml @@ -909,9 +909,8 @@ Q830513: Q834025: title: Cauchy integral theorem - decl: Complex.circleIntegral_div_sub_of_differentiable_on_off_countable - authors: Yury Kudryashov - date: 2021 + comment: We have `DiffContOnCl.circleIntegral_eq_zero` for circle contours + url: https://leanprover-community.github.io/mathlib4_docs/Mathlib/Analysis/Complex/CauchyIntegral.html#DiffContOnCl.circleIntegral_eq_zero Q834211: title: Wallace–Bolyai–Gerwien theorem From 8690e4fcb159b28ef4b3afd5c68404c9bc0a8992 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Sat, 20 Jun 2026 08:01:11 +0000 Subject: [PATCH 0204/1300] chore(RingTheory/Polynomial/Basic): squeeze terminal `simp`s (#40833) As recommended in the style guide. Extracted from #40793. --- Mathlib/RingTheory/Polynomial/Basic.lean | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index c186c48bb63ee7..efa4f23011e935 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -763,17 +763,8 @@ theorem prime_rename_iff (s : Set σ) {p : MvPolynomial s R} : (renameEquiv R <| (Equiv.sumComm (↥sᶜ) s).trans <| Equiv.Set.sumCompl s) have : (rename (↑)).toRingHom = eqv.toAlgHom.toRingHom.comp C := by apply ringHom_ext - · intro - simp only [eqv, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, rename_C, - AlgEquiv.toAlgHom_toRingHom, RingHom.coe_comp, AlgEquiv.coe_trans, - Function.comp_apply, MvPolynomial.sumAlgEquiv_symm_apply, iterToSum_C_C, - renameEquiv_apply, Equiv.coe_trans, Equiv.sumComm_apply] - · intro - simp only [eqv, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, rename_X, - AlgEquiv.toAlgHom_toRingHom, RingHom.coe_comp, AlgEquiv.coe_trans, - Function.comp_apply, MvPolynomial.sumAlgEquiv_symm_apply, iterToSum_C_X, - renameEquiv_apply, Equiv.coe_trans, Equiv.sumComm_apply, Sum.swap_inr, - Equiv.Set.sumCompl_apply_inl] + · simp [eqv] + · simp [eqv] apply_fun (· p) at this simp only [AlgHom.toRingHom_eq_coe, RingHom.coe_coe, AlgEquiv.toAlgHom_toRingHom, RingHom.coe_comp, Function.comp_apply] at this From fbfd7f57b6e24d35f345edee2d888a3e6b5f4cc4 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Sat, 20 Jun 2026 09:31:52 +0000 Subject: [PATCH 0205/1300] refactor(RingTheory/Localization/FractionRing): remove bottom ring and field from `IsFractionRing.mulSemiringAction` (#40804) This PR removes the bottom ring and field from `IsFractionRing.mulSemiringAction` since they are unnecessary. Co-authored-by: tb65536 --- Mathlib/Algebra/Ring/Action/Group.lean | 22 ++++++++++-- Mathlib/Algebra/Star/UnitaryStarAlgAut.lean | 2 +- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 35 +++++++----------- .../RamificationInertia/Galois.lean | 6 ++-- .../RingTheory/Localization/FractionRing.lean | 36 +++++++++++++++---- 5 files changed, 67 insertions(+), 34 deletions(-) diff --git a/Mathlib/Algebra/Ring/Action/Group.lean b/Mathlib/Algebra/Ring/Action/Group.lean index d5dce7f17fa431..91e4cd7961ba25 100644 --- a/Mathlib/Algebra/Ring/Action/Group.lean +++ b/Mathlib/Algebra/Ring/Action/Group.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.GroupWithZero.Action.Basic public import Mathlib.Algebra.Ring.Action.Basic +public import Mathlib.Algebra.Ring.Aut public import Mathlib.Algebra.Ring.Equiv /-! @@ -25,7 +26,24 @@ variable (R : Type*) [Semiring R] /-- Each element of the group defines a semiring isomorphism. -/ @[simps!] -def MulSemiringAction.toRingEquiv [MulSemiringAction G R] (x : G) : R ≃+* R := - { DistribMulAction.toAddEquiv R x, MulSemiringAction.toRingHom G R x with } +def MulSemiringAction.toRingEquiv [MulSemiringAction G R] : G →* (R ≃+* R) where + toFun x := { DistribMulAction.toAddEquiv R x, MulSemiringAction.toRingHom G R x with } + map_one' := by ext; simp + map_mul' x y := by ext; simp [mul_smul] + +@[deprecated (since := "2026-06-19")] alias MulSemiringAction.toRingEquiv_apply := +MulSemiringAction.toRingEquiv_apply_apply + +@[deprecated (since := "2026-06-19")] alias MulSemiringAction.toRingEquiv_symm_apply := +MulSemiringAction.toRingEquiv_apply_symm_apply + +instance : MulSemiringAction (R ≃+* R) R where + smul := (· ·) + mul_smul _ _ _ := rfl + one_smul _ := rfl + smul_zero := map_zero + smul_one := map_one + smul_add := map_add + smul_mul := map_mul end Semiring diff --git a/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean b/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean index 25d846324e92f6..6dfa47f00a244d 100644 --- a/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean +++ b/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean @@ -38,7 +38,7 @@ def conjStarAlgAut : unitary R →* (R ≃⋆ₐ[S] R) where dsimp [ConjAct.units_smul_def] simp [mul_assoc, ← Unitary.star_eq_inv] } map_one' := by ext; simp - map_mul' g h := by ext; simp [mul_smul] + map_mul' g h := by ext; simp @[simp] theorem conjStarAlgAut_apply (u : unitary R) (x : R) : conjStarAlgAut S R u x = u * x * (star u : R) := rfl diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index cdb2d060676346..ccc1a84e609c41 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -239,21 +239,17 @@ theorem IsGaloisGroup.iff_isFractionRing [Finite G] [IsIntegrallyClosed A] : @[deprecated (since := "2026-04-20")] alias FractionRing.mulSemiringAction_of_isGaloisGroup := IsFractionRing.mulSemiringAction -attribute [local instance] FractionRing.liftAlgebra in /-- If `G` is finite and `IsGaloisGroup G A B` with `A` and `B` domains, then `G` is also a Galois group for `FractionRing B / FractionRing A` for the action defined by `IsFractionRing.mulSemiringAction`. -/ -theorem IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [IsTorsionFree A B] [Finite G] - [IsGaloisGroup G A B] : - letI := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) +instance IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [IsTorsionFree A B] [Finite G] + [IsGaloisGroup G A B] [Algebra (FractionRing A) (FractionRing B)] + [IsScalarTower A (FractionRing A) (FractionRing B)] : + letI := IsFractionRing.mulSemiringAction G B (FractionRing B) IsGaloisGroup G (FractionRing A) (FractionRing B) := by - let := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) - have : SMulDistribClass G B (FractionRing B) := ⟨fun g b x ↦ by - rw [Algebra.smul_def', Algebra.smul_def', smul_mul'] - congr - exact IsFractionRing.fieldEquivOfAlgEquiv_algebraMap (FractionRing A) _ _ _ b⟩ + let := IsFractionRing.mulSemiringAction G B (FractionRing B) apply IsGaloisGroup.to_isFractionRing G A B _ _ open NumberField @@ -314,7 +310,7 @@ protected theorem finite (R B : Type*) [CommRing R] [CommRing B] [Algebra R B] [ [IsDomain B] [MulSemiringAction G B] [IsGaloisGroup G R B] : Finite G := by let A : Subring B := (algebraMap R B).range let := FractionRing.liftAlgebra A (FractionRing B) - let := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) + let := IsFractionRing.mulSemiringAction G B (FractionRing B) let : Algebra R A := (algebraMap R B).rangeRestrict.toAlgebra have : IsScalarTower R A B := IsScalarTower.of_algebraMap_eq' rfl have : Module.Finite A B := Module.Finite.of_restrictScalars_finite R A B @@ -331,9 +327,9 @@ theorem card_eq_finrank' (A B : Type*) [CommRing A] [CommRing B] [Algebra A B] [ Nat.card G = Module.finrank A B := by have := IsDomain.of_faithfulSMul A B let := FractionRing.liftAlgebra A (FractionRing B) - let := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) + let := IsFractionRing.mulSemiringAction G B (FractionRing B) have : Algebra.IsIntegral A B := IsGaloisGroup.isInvariant.isIntegral A B G - rw [(IsGaloisGroup.toFractionRing G A B).card_eq_finrank, + rw [IsGaloisGroup.card_eq_finrank G (FractionRing A) (FractionRing B), Algebra.IsAlgebraic.finrank_of_isFractionRing A (FractionRing A) B (FractionRing B)] /-- If `G` is a finite Galois group for `L/K`, then `G` is isomorphic to `Gal(L/K)`. -/ @@ -374,10 +370,8 @@ noncomputable def mulEquivCongr [Finite G] [Finite G'] (A B : Type*) [CommRing A haveI : IsDomain A := (FaithfulSMul.algebraMap_injective A B).isDomain letI K := FractionRing A letI L := FractionRing B - letI : MulSemiringAction G L := IsFractionRing.mulSemiringAction G A B K L - letI : MulSemiringAction G' L := IsFractionRing.mulSemiringAction G' A B K L - haveI : IsGaloisGroup G K L := IsGaloisGroup.toFractionRing G A B - haveI : IsGaloisGroup G' K L := IsGaloisGroup.toFractionRing G' A B + letI : MulSemiringAction G L := IsFractionRing.mulSemiringAction G B L + letI : MulSemiringAction G' L := IsFractionRing.mulSemiringAction G' B L mulEquivCongr' G G' K L attribute [local instance] FractionRing.liftAlgebra in @@ -389,10 +383,8 @@ theorem mulEquivCongr_apply_smul [Finite G] [Finite G'] (A B : Type*) [CommRing haveI : IsDomain A := (FaithfulSMul.algebraMap_injective A B).isDomain letI K := FractionRing A letI L := FractionRing B - letI : MulSemiringAction G L := IsFractionRing.mulSemiringAction G A B K L - letI : MulSemiringAction G' L := IsFractionRing.mulSemiringAction G' A B K L - haveI : IsGaloisGroup G K L := IsGaloisGroup.toFractionRing G A B - haveI : IsGaloisGroup G' K L := IsGaloisGroup.toFractionRing G' A B + letI : MulSemiringAction G L := IsFractionRing.mulSemiringAction G B L + letI : MulSemiringAction G' L := IsFractionRing.mulSemiringAction G' B L apply FaithfulSMul.algebraMap_injective B L rw [algebraMap.smul', algebraMap.smul'] exact mulEquivCongr'_apply_smul G G' K L g _ @@ -576,8 +568,7 @@ theorem fixingSubgroup_range_algebraMap [Finite G] (A B C : Type*) (H : Subgroup have : IsDomain A := (FaithfulSMul.algebraMap_injective A C).isDomain let K := FractionRing A let L := FractionRing C - let : MulSemiringAction G L := IsFractionRing.mulSemiringAction G A C K L - have : IsGaloisGroup G K L := IsGaloisGroup.toFractionRing G A C + let : MulSemiringAction G L := IsFractionRing.mulSemiringAction G C L have : IsGaloisGroup H (FractionRing B) L := IsGaloisGroup.toFractionRing H B C rw [← fixingSubgroup_range_algebraMap' G K L H (FractionRing B)] ext g diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index b0f32f53494438..06d4f5a5d2f7c0 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -244,9 +244,9 @@ variable {A B : Type*} [CommRing A] [IsDomain A] [CommRing B] [IsDomain B] include G GAC GBC in theorem ncard_primesOver_mul_ncard_primesOver : (p.primesOver B).ncard * (P.primesOver C).ncard = (p.primesOver C).ncard := by - let := IsFractionRing.mulSemiringAction G A B (FractionRing A) (FractionRing B) - let := IsFractionRing.mulSemiringAction GAC A C (FractionRing A) (FractionRing C) - let := IsFractionRing.mulSemiringAction GBC B C (FractionRing B) (FractionRing C) + let := IsFractionRing.mulSemiringAction G B (FractionRing B) + let := IsFractionRing.mulSemiringAction GAC C (FractionRing C) + let := IsFractionRing.mulSemiringAction GBC C (FractionRing C) have : p.ramificationIdxIn C * p.inertiaDegIn C ≠ 0 := mul_ne_zero (ramificationIdxIn_ne_zero GAC) (inertiaDegIn_ne_zero GAC) rw [← Nat.mul_left_inj this, ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p C GAC] diff --git a/Mathlib/RingTheory/Localization/FractionRing.lean b/Mathlib/RingTheory/Localization/FractionRing.lean index 00659e147c0d83..54d432f40eba71 100644 --- a/Mathlib/RingTheory/Localization/FractionRing.lean +++ b/Mathlib/RingTheory/Localization/FractionRing.lean @@ -437,6 +437,10 @@ lemma ringEquivOfRingEquiv_algebraMap (a : A) : ringEquivOfRingEquiv h (algebraMap A K a) = algebraMap B L (h a) := by simp +@[simp] +lemma ringEquivOfRingEquiv_refl : + ringEquivOfRingEquiv (.refl A) = .refl K := by ext; simp + @[simp] lemma ringEquivOfRingEquiv_symm : (ringEquivOfRingEquiv h : K ≃+* L).symm = ringEquivOfRingEquiv h.symm := rfl @@ -449,6 +453,26 @@ theorem ringEquivOfRingEquiv_comp {C : Type*} (M : Type*) [CommRing C] ext a simp [IsLocalization.map_map] +variable (A K) + +/-- A ring automorphism of a ring induces an ring automorphism of its fraction field. + +This is a bundled version of `ringEquivOfRingEquiv`. -/ +noncomputable def ringEquivOfRingEquivHom : (A ≃+* A) →* (K ≃+* K) where + toFun := ringEquivOfRingEquiv + map_one' := ringEquivOfRingEquiv_refl + map_mul' f g := ringEquivOfRingEquiv_comp K K K g f + +@[simp] +lemma ringEquivOfRingEquivHom_apply (f : A ≃+* A) : + ringEquivOfRingEquivHom A K f = ringEquivOfRingEquiv f := + rfl + +lemma ringEquivOfRingEquivHom_injective : Function.Injective (ringEquivOfRingEquivHom A K) := by + intro f g h + ext b + simpa using RingEquiv.ext_iff.mp h (algebraMap A K b) + end ringEquivOfRingEquiv section semilinearEquivOfRingEquiv @@ -624,21 +648,21 @@ variable (G A B K L : Type*) [Group G] [CommRing A] [CommRing B] [MulSemiringAct /-- Given a `MulSemiringAction G B`, extend the action of `G` on `B` to a `MulSemiringAction G L` on the fraction field `L` of `B`. -/ @[implicit_reducible] -noncomputable def mulSemiringAction [SMulCommClass G A B] : +noncomputable def mulSemiringAction : MulSemiringAction G L := MulSemiringAction.compHom L - ((fieldEquivOfAlgEquivHom K L).comp (MulSemiringAction.toAlgAut G A B)) + ((ringEquivOfRingEquivHom B L).comp (MulSemiringAction.toRingEquiv G B)) /-- The action of `G` on the fraction field `L` of `B` given by `IsFractionRing.mulSemiringAction` is compatible with the embedding `B ⊆ L`. -/ -instance smulDistribClass [SMulCommClass G A B] : - letI := mulSemiringAction G A B K L +instance smulDistribClass : + letI := mulSemiringAction G B L SMulDistribClass G B L := - let := mulSemiringAction G A B K L + let := mulSemiringAction G B L ⟨fun g b x ↦ by rw [Algebra.smul_def', Algebra.smul_def', smul_mul'] congr - apply fieldEquivOfAlgEquiv_algebraMap⟩ + apply ringEquivOfRingEquiv_algebraMap⟩ variable [MulSemiringAction G L] [SMulDistribClass G B L] From 843d7890de006fe2cb1d2974f5bafcf1b0e3fad8 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 13:53:39 +0000 Subject: [PATCH 0206/1300] chore(Algebra/Group/Subgroup/Basic): automated extraction from #38864 (#40842) This PR was automatically created from PR #38864 by @xroblot via a [review comment](https://github.com/leanprover-community/mathlib4/pull/38864#discussion_r3446463992) by @tb65536. Co-authored-by: xroblot <46200072+xroblot@users.noreply.github.com> --- Mathlib/Algebra/Group/Subgroup/Basic.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 8d12154ce3c9d3..c5a07c6d1114d7 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -939,6 +939,15 @@ theorem Normal.of_map_subtype {K : Subgroup G} {L : Subgroup K} (n : (Subgroup.map K.subtype L).Normal) : L.Normal := n.of_map_injective K.subtype_injective +theorem normal_comap_iff_of_surjective {f : G →* N} (hf : Function.Surjective f) {H : Subgroup N} : + (H.comap f).Normal ↔ H.Normal := by + rw [← normalizer_eq_top_iff, ← comap_normalizer_eq_of_surjective H hf, ← comap_top f, + (comap_injective hf).eq_iff, normalizer_eq_top_iff] + +theorem _root_.MulEquiv.normal_map_iff {f : G ≃* G'} {H : Subgroup G} : + (H.map (f : G →* G')).Normal ↔ H.Normal := by + rw [map_equiv_eq_comap_symm, normal_comap_iff_of_surjective f.symm.surjective] + section SubgroupNormal @[to_additive] From 2dfe37a6fa59521018b61dc988495a84dd47dd30 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:15:36 +0000 Subject: [PATCH 0207/1300] chore(FieldTheory/IntermediateField/Basic): automated extraction from #38864 (#40844) This PR was automatically created from PR #38864 by @xroblot via a [review comment](https://github.com/leanprover-community/mathlib4/pull/38864#discussion_r3446477153) by @tb65536. Co-authored-by: xroblot <46200072+xroblot@users.noreply.github.com> Co-authored-by: Thomas Browning --- .../FieldTheory/IntermediateField/Basic.lean | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index ca54cf81abab2a..3e4e49af1025a5 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -541,24 +541,26 @@ theorem coe_fieldRange : ↑f.fieldRange = Set.range f := theorem fieldRange_toSubfield : f.fieldRange.toSubfield = (f : L →+* L').fieldRange := rfl -variable {f} - +variable {f} in @[simp] theorem mem_fieldRange {y : L'} : y ∈ f.fieldRange ↔ ∃ x, f x = y := Iff.rfl -/-- An algebra homomorphism between fields restricts to an algebra equivalence onto its range. -/ +/-- The isomorphism from `L` to the field range of the `AlgHom` `f`, sending `x` to `f x`. -/ +@[simps! apply_coe] noncomputable def equivFieldRange : L ≃ₐ[K] f.fieldRange := - AlgEquiv.ofBijective - (f.codRestrict f.range fun x ↦ mem_fieldRange.mpr ⟨x, rfl⟩) - ⟨fun _ _ h ↦ f.injective (congr_arg Subtype.val h), - fun ⟨_, hy⟩ ↦ (mem_fieldRange.mp hy).imp fun _ hx => Subtype.ext hx⟩ + .ofBijective f.rangeRestrict ⟨f.rangeRestrict.injective, fun ⟨_, ⟨x, hx⟩⟩ ↦ ⟨x, Subtype.ext hx⟩⟩ -@[simp] -theorem equivFieldRange_apply (x : L) : f.equivFieldRange x = f x := rfl +@[deprecated (since := "2026-06-20")] alias equivFieldRange_apply := equivFieldRange_apply_coe end AlgHom +variable (K L L') in +@[simp] +theorem IsScalarTower.toAlgHom_fieldRange [Algebra L L'] [IsScalarTower K L L'] : + (IsScalarTower.toAlgHom K L L').fieldRange = Set.range (algebraMap L L') := by + ext; simp + namespace IntermediateField /-- The embedding from an intermediate field of `L / K` to `L`. -/ From 0bee4471e48fc38bb650f9547e743222d9c2b11d Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:40:22 +0000 Subject: [PATCH 0208/1300] refactor(FieldTheory/Galois/IsGaloisGroup): generalize `mulEquivAlgEquiv` to domains (#40822) This PR generalizes `mulEquivAlgEquiv` to domains. This allows us to remove `mulEquivCongr'` (a field version of `mulEquivCongr`). Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 80 +++++++------------ Mathlib/Logic/Function/Basic.lean | 4 + 2 files changed, 34 insertions(+), 50 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index ccc1a84e609c41..1495a47a590cae 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -307,7 +307,7 @@ theorem finiteDimensional [Finite G] [IsGaloisGroup G K L] : FiniteDimensional K FiniteDimensional.of_finrank_pos (card_eq_finrank G K L ▸ Nat.card_pos) protected theorem finite (R B : Type*) [CommRing R] [CommRing B] [Algebra R B] [Module.Finite R B] - [IsDomain B] [MulSemiringAction G B] [IsGaloisGroup G R B] : Finite G := by + [IsDomain B] [MulSemiringAction G B] [IsGaloisGroup G R B] : Finite G := by let A : Subring B := (algebraMap R B).range let := FractionRing.liftAlgebra A (FractionRing B) let := IsFractionRing.mulSemiringAction G B (FractionRing B) @@ -319,12 +319,16 @@ protected theorem finite (R B : Type*) [CommRing R] [CommRing B] [Algebra R B] [ rw [card_eq_finrank G (FractionRing A) (FractionRing B)] exact Module.finrank_pos.ne' +section IsDomain + +variable (A B : Type*) [CommRing A] [CommRing B] [IsDomain B] [Algebra A B] [FaithfulSMul A B] + [MulSemiringAction G B] [MulSemiringAction G' B] [IsGaloisGroup G A B] [IsGaloisGroup G' A B] + [Finite G] [Finite G'] + /-- The cardinality of a Galois group of `B/A` equals the rank of `B` as an `A`-module. -See `IsGaloisGroup.card_eq_finrank` a field-theoretic version that does not assume finiteness. -/ -theorem card_eq_finrank' (A B : Type*) [CommRing A] [CommRing B] [Algebra A B] [Finite G] - [IsDomain B] [FaithfulSMul A B] [MulSemiringAction G B] [IsGaloisGroup G A B] : - Nat.card G = Module.finrank A B := by +See `IsGaloisGroup.card_eq_finrank`, a field-theoretic version that does not assume finiteness. -/ +theorem card_eq_finrank' : Nat.card G = Module.finrank A B := by have := IsDomain.of_faithfulSMul A B let := FractionRing.liftAlgebra A (FractionRing B) let := IsFractionRing.mulSemiringAction G B (FractionRing B) @@ -332,70 +336,46 @@ theorem card_eq_finrank' (A B : Type*) [CommRing A] [CommRing B] [Algebra A B] [ rw [IsGaloisGroup.card_eq_finrank G (FractionRing A) (FractionRing B), Algebra.IsAlgebraic.finrank_of_isFractionRing A (FractionRing A) B (FractionRing B)] -/-- If `G` is a finite Galois group for `L/K`, then `G` is isomorphic to `Gal(L/K)`. -/ -@[simps!] noncomputable def mulEquivAlgEquiv [IsGaloisGroup G K L] [Finite G] : G ≃* Gal(L/K) := - MulEquiv.ofBijective (MulSemiringAction.toAlgAut G K L) (by +attribute [local instance] FractionRing.liftAlgebra in +/-- If `G` is a finite Galois group for `B/A`, then `G` is isomorphic to `Gal(B/A)`. -/ +@[simps!] noncomputable def mulEquivAlgEquiv : G ≃* Gal(B/A) := + MulEquiv.ofBijective (MulSemiringAction.toAlgAut G A B) (by + have := IsDomain.of_faithfulSMul A B + letI K := FractionRing A + letI L := FractionRing B + letI := IsFractionRing.mulSemiringAction G B L have := isGalois G K L have := finiteDimensional G K L + refine .of_comp_left ?_ (IsFractionRing.fieldEquivOfAlgEquivHom_injective A B K L) rw [Nat.bijective_iff_injective_and_card, card_eq_finrank G K L, IsGalois.card_aut_eq_finrank K L] exact ⟨fun _ _ ↦ (faithful K).eq_of_smul_eq_smul ∘ DFunLike.ext_iff.mp, rfl⟩) @[simp] -theorem map_mulEquivAlgEquiv_fixingSubgroup - [IsGaloisGroup G K L] [Finite G] (F : IntermediateField K L) : +theorem map_mulEquivAlgEquiv_fixingSubgroup [IsGaloisGroup G K L] (F : IntermediateField K L) : (fixingSubgroup G (F : Set L)).map (mulEquivAlgEquiv G K L) = F.fixingSubgroup := by ext g obtain ⟨g, rfl⟩ := (mulEquivAlgEquiv G K L).surjective g simp [mem_fixingSubgroup_iff] -/-- If `G` and `G'` are finite Galois groups for `L/K`, then `G` is isomorphic to `G'`. -See `mulEquivCongr` for a more general version. -/ -noncomputable def mulEquivCongr' [IsGaloisGroup G K L] [Finite G] - [IsGaloisGroup G' K L] [Finite G'] : G ≃* G' := - (mulEquivAlgEquiv G K L).trans (mulEquivAlgEquiv G' K L).symm +/-- If `G` and `G'` are finite Galois groups for `B/A`, then `G` is isomorphic to `G'`. -/ +noncomputable def mulEquivCongr : G ≃* G' := + (mulEquivAlgEquiv G A B).trans (mulEquivAlgEquiv G' A B).symm @[simp] -theorem mulEquivCongr'_apply_smul [IsGaloisGroup G K L] [Finite G] [IsGaloisGroup G' K L] - [Finite G'] (g : G) (x : L) : mulEquivCongr' G G' K L g • x = g • x := - AlgEquiv.ext_iff.mp ((mulEquivAlgEquiv G' K L).apply_symm_apply (mulEquivAlgEquiv G K L g)) x +theorem mulEquivCongr_apply_smul (g : G) (x : B) : mulEquivCongr G G' A B g • x = g • x := + AlgEquiv.ext_iff.mp ((mulEquivAlgEquiv G' A B).apply_symm_apply (mulEquivAlgEquiv G A B g)) x -attribute [local instance] FractionRing.liftAlgebra in -/-- If `G` and `G'` are finite Galois groups for `B/A` with `B` a domain, then `G` is -isomorphic to `G'`. -/ -noncomputable def mulEquivCongr [Finite G] [Finite G'] (A B : Type*) [CommRing A] - [CommRing B] [IsDomain B] [Algebra A B] [FaithfulSMul A B] [MulSemiringAction G B] - [MulSemiringAction G' B] [IsGaloisGroup G A B] [IsGaloisGroup G' A B] : - G ≃* G' := - haveI : IsDomain A := (FaithfulSMul.algebraMap_injective A B).isDomain - letI K := FractionRing A - letI L := FractionRing B - letI : MulSemiringAction G L := IsFractionRing.mulSemiringAction G B L - letI : MulSemiringAction G' L := IsFractionRing.mulSemiringAction G' B L - mulEquivCongr' G G' K L - -attribute [local instance] FractionRing.liftAlgebra in @[simp] -theorem mulEquivCongr_apply_smul [Finite G] [Finite G'] (A B : Type*) [CommRing A] - [CommRing B] [IsDomain B] [Algebra A B] [FaithfulSMul A B] [MulSemiringAction G B] - [MulSemiringAction G' B] [IsGaloisGroup G A B] [IsGaloisGroup G' A B] (g : G) (x : B) : - mulEquivCongr G G' A B g • x = g • x := by - haveI : IsDomain A := (FaithfulSMul.algebraMap_injective A B).isDomain - letI K := FractionRing A - letI L := FractionRing B - letI : MulSemiringAction G L := IsFractionRing.mulSemiringAction G B L - letI : MulSemiringAction G' L := IsFractionRing.mulSemiringAction G' B L - apply FaithfulSMul.algebraMap_injective B L - rw [algebraMap.smul', algebraMap.smul'] - exact mulEquivCongr'_apply_smul G G' K L g _ - -@[simp] -theorem mulEquivCongr_symm_apply_smul [Finite G] [Finite G'] (A B : Type*) [CommRing A] - [CommRing B] [IsDomain B] [Algebra A B] [FaithfulSMul A B] [MulSemiringAction G B] - [MulSemiringAction G' B] [IsGaloisGroup G A B] [IsGaloisGroup G' A B] (g : G') (x : B) : +theorem mulEquivCongr_symm_apply_smul (g : G') (x : B) : (mulEquivCongr G G' A B).symm g • x = g • x := by rw [← mulEquivCongr_apply_smul G G' A B, MulEquiv.apply_symm_apply] +@[deprecated (since := "2026-06-19")] alias mulEquivCongr' := mulEquivCongr +@[deprecated (since := "2026-06-19")] alias mulEquivCongr'_apply_smul := mulEquivCongr_apply_smul + +end IsDomain + variable (H H' : Subgroup G) (F F' : IntermediateField K L) instance (R S : Type*) [CommRing R] [CommRing S] [Algebra R S] diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index 6ab2a0cf0c7f63..d2d3f67f4f10da 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -352,6 +352,10 @@ theorem Bijective.of_comp_iff' {f : α → β} (hf : Bijective f) (g : γ → α Function.Bijective (f ∘ g) ↔ Function.Bijective g := and_congr (Injective.of_comp_iff hf.injective _) (Surjective.of_comp_iff' hf _) +theorem Bijective.of_comp_left {f : α → β} {g : γ → α} (hfg : Function.Bijective (f ∘ g)) + (hf : Function.Injective f) : Function.Bijective g := + ⟨hfg.1.of_comp, hfg.2.of_comp_left hf⟩ + /-- If `f : α → α → β` is surjective, then every endofunction on `β` has a fixed point. This is an instance of Lawvere's fixed-point theorem applied to the category of types and functions. It is the diagonal argument underlying `cantor_surjective` and From d5331d6fd7302656853f1c2cd8cbb994504e74d9 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Sat, 20 Jun 2026 17:37:45 +0000 Subject: [PATCH 0209/1300] chore(RingTheory/Spectrum/Prime/FreeLocus): unsqueeze terminal `simp`s (#40838) As recommended in the style guide. Extracted from #40793. --- Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean b/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean index 2ae9cab02f13e7..50ad1fe06dcaa0 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean @@ -68,11 +68,7 @@ lemma mem_freeLocus_of_isLocalization (p : PrimeSpectrum R) intro r x obtain ⟨r, s, rfl⟩ := IsLocalization.exists_mk'_eq p.asIdeal.primeCompl r apply ((Module.End.isUnit_iff _).mp (IsLocalizedModule.map_units f s)).1 - simp only [e, AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearEquiv.coe_coe, - algebraMap_end_apply, - AlgEquiv.toRingEquiv_toRingHom, RingHom.coe_coe, IsLocalization.algEquiv_apply, - IsLocalization.map_id_mk'] - simp only [← map_smul, ← smul_assoc, IsLocalization.smul_mk'_self, algebraMap_smul] + simp [e, ← map_smul, ← smul_assoc] attribute [local instance] RingHomInvPair.of_ringEquiv in lemma mem_freeLocus_iff_tensor (p : PrimeSpectrum R) From 55ad1c56adc88131d141e9f625f9a9b4b28ce941 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sat, 20 Jun 2026 17:52:00 +0000 Subject: [PATCH 0210/1300] feat: add Homeomorph.pointReflection (#40637) This is `Equiv.pointReflection` as a homeomorphism. The motivating use case is for a homeomorphism on the real line in #29077. While at it, also upgrade `AffineEquiv.pointReflection` to a `ContinuousAffineEquiv`. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../AffineSpace/AffineEquiv.lean | 3 ++- .../Algebra/ContinuousAffineEquiv.lean | 25 +++++++++++++++++++ Mathlib/Topology/Algebra/Group/Torsor.lean | 19 ++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean index 05e9a6328155cd..75f205c9b55110 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean @@ -509,7 +509,8 @@ variable {P₁} open Function -/-- Point reflection in `x` as a permutation. -/ +/-- The affine equivalence given by reflection about the point `x`. +This is `Equiv.pointReflection` as an `AffineEquiv`. -/ def pointReflection (x : P₁) : P₁ ≃ᵃ[k] P₁ := (constVSub k x).trans (vaddConst k x) diff --git a/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean b/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean index 46df6b9ac4ba7a..3605d581af24e8 100644 --- a/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean +++ b/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean @@ -309,6 +309,31 @@ end ReflSymmTrans section +variable (k) +variable [TopologicalSpace V₁] [IsTopologicalAddTorsor P₁] + +/-- The affine homeomorphism given by reflection about the point `x`. +This is `Equiv.pointReflection` as a `ContinuousAffineEquiv`. -/ +@[simps toAffineEquiv] +def pointReflection (x : P₁) : P₁ ≃ᴬ[k] P₁ where + toAffineEquiv := AffineEquiv.pointReflection k x + continuous_toFun := by dsimp [Equiv.pointReflection]; fun_prop + continuous_invFun := by + let : ContinuousNeg V₁ := + IsTopologicalAddTorsor.to_isTopologicalAddGroup (V := V₁) (P := P₁) |>.toContinuousNeg + dsimp [Equiv.pointReflection]; fun_prop + +theorem pointReflection_apply (x y : P₁) : pointReflection k x y = (x -ᵥ y) +ᵥ x := + rfl + +@[simp] +theorem pointReflection_symm (x : P₁) : (pointReflection k x).symm = pointReflection k x := + toAffineEquiv_injective <| AffineEquiv.pointReflection_symm k x + +end + +section + variable {E F : Type*} [AddCommGroup E] [Module k E] [TopologicalSpace E] [AddCommGroup F] [Module k F] [TopologicalSpace F] diff --git a/Mathlib/Topology/Algebra/Group/Torsor.lean b/Mathlib/Topology/Algebra/Group/Torsor.lean index cb5470f71e0f73..e06ff5bde26c9c 100644 --- a/Mathlib/Topology/Algebra/Group/Torsor.lean +++ b/Mathlib/Topology/Algebra/Group/Torsor.lean @@ -98,6 +98,25 @@ theorem IsTopologicalTorsor.to_isTopologicalGroup : IsTopologicalGroup V where def Homeomorph.smulConst (p : P) : V ≃ₜ P where __ := Equiv.smulConst p +/-- The map `p' ↦ p /ₛ p'` as a homeomorphism: `Equiv.constSDiv` as a homeomorphism -/ +@[to_additive (attr := simps!) +/-- The map `p' ↦ p -ᵥ p'` as a homeomorphism: `Equiv.constVSub` as a homeomorphism -/] +def Homeomorph.constSDiv (p : P) : P ≃ₜ V where + toEquiv := Equiv.constSDiv p + continuous_invFun := by + have := IsTopologicalTorsor.to_isTopologicalGroup V P + fun_prop + +/-- `Equiv.pointReflection` as a homeomorphism -/ +def Homeomorph.pointReflection {V P : Type*} [AddGroup V] [TopologicalSpace V] [AddTorsor V P] + [TopologicalSpace P] [IsTopologicalAddTorsor P] (p : P) : P ≃ₜ P := + (Homeomorph.constVSub p).trans (Homeomorph.vaddConst p) + +@[simp] +lemma Homeomorph.coe_pointReflection {V P : Type*} [AddGroup V] [TopologicalSpace V] [AddTorsor V P] + [TopologicalSpace P] [IsTopologicalAddTorsor P] (p : P) : + (Homeomorph.pointReflection p : P → P) = Equiv.pointReflection p := rfl + end Torsor section Group From 8d1ee6c7d56bcad90d248365305abcecf1cf5729 Mon Sep 17 00:00:00 2001 From: Lua Viana Reis <4229115+lua-vr@users.noreply.github.com> Date: Sat, 20 Jun 2026 17:52:02 +0000 Subject: [PATCH 0211/1300] chore(Integral/Layercake): fix LaTeX syntax in the module doc-string (#40839) The LaTeX formulas were not rendering correctly in the web docs due to missing escapes for the brackets. Besides that, I also added some standard spacing in the formulas for readability. --- Mathlib/MeasureTheory/Integral/Layercake.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/Layercake.lean b/Mathlib/MeasureTheory/Integral/Layercake.lean index 89d87338d77988..3a5b7c938a8f4f 100644 --- a/Mathlib/MeasureTheory/Integral/Layercake.lean +++ b/Mathlib/MeasureTheory/Integral/Layercake.lean @@ -27,7 +27,7 @@ The essence of the (mathematical) proof is Fubini's theorem. We also give the most common application of the layer cake formula - a representation of the integral of a nonnegative function f: -$$∫ f(ω) ∂μ(ω) = ∫ μ {ω | f(ω) ≥ t} dt$$ +$$∫ f(ω) \,∂μ(ω) = ∫ μ \{ω \mid f(ω) ≥ t\} \,dt$$ Variants of the formulas with measures of sets of the form `{ω | f(ω) > t}` instead of `{ω | f(ω) ≥ t}` are also included. @@ -41,12 +41,12 @@ Variants of the formulas with measures of sets of the form `{ω | f(ω) > t}` in * `MeasureTheory.lintegral_eq_lintegral_meas_le` and `MeasureTheory.lintegral_eq_lintegral_meas_lt`: The most common special cases of the layer cake formulas, stating that for a nonnegative - function f we have $∫ f(ω) ∂μ(ω) = ∫ μ {ω | f(ω) ≥ t} dt$ and - $∫ f(ω) ∂μ(ω) = ∫ μ {ω | f(ω) > t} dt$, respectively. + function f we have $∫ f(ω) \,∂μ(ω) = ∫ μ \{ω \mid f(ω) ≥ t\} \,dt$ and + $∫ f(ω) \,∂μ(ω) = ∫ μ \{ω \mid f(ω) > t\} \,dt$, respectively. * `Integrable.integral_eq_integral_meas_lt`: A Bochner integral version of the most common special case of the layer cake formulas, stating that for an integrable and a.e.-nonnegative function f we have - $∫ f(ω) ∂μ(ω) = ∫ μ {ω | f(ω) > t} dt$. + $∫ f(ω) \,∂μ(ω) = ∫ μ \{ω \mid f(ω) > t\} \,dt$. ## See also From 09b373db6e247a35cfa5e44578c09a20e7c97271 Mon Sep 17 00:00:00 2001 From: "mathlib-nolints[bot]" <258989889+mathlib-nolints[bot]@users.noreply.github.com> Date: Sun, 21 Jun 2026 00:48:00 +0000 Subject: [PATCH 0212/1300] chore(scripts): update nolints.json (#40856) I am happy to remove some nolints for you! --- scripts/nolints.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/nolints.json b/scripts/nolints.json index f46adf7bf9cee7..c2e26b90be252a 100644 --- a/scripts/nolints.json +++ b/scripts/nolints.json @@ -103,8 +103,6 @@ "CompactlySupportedContinuousMap.pullback_addMonoidHom"], ["defsWithUnderscore", "CompactlySupportedContinuousMap.pullback_monoidHom"], ["defsWithUnderscore", "ContDiffMapSupportedIn.of_support_subset"], - ["defsWithUnderscore", "ContRepresentation.coind₁_map"], - ["defsWithUnderscore", "ContRepresentation.coind₁_ι"], ["defsWithUnderscore", "ContinuousLinearMap.antilipschitzConstant_of_injective_of_isClosed_range"], ["defsWithUnderscore", @@ -638,7 +636,6 @@ ["docBlame", "RingQuot.toQuot"], ["docBlame", "Shrink.rec"], ["docBlame", "SlashAction.map"], - ["docBlame", "StarAlgEquiv.restrictScalars"], ["docBlame", "StarAlgHom.restrictScalars"], ["docBlame", "StateT.callCC"], ["docBlame", "StateT.mkLabel"], From f85645b51d74ad187fdc751c05070829540f3ee1 Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Sun, 21 Jun 2026 05:43:02 +0000 Subject: [PATCH 0213/1300] doc: add wikidata attributes (#40747) This PR adds a batch of 25 `@[wikidata]` attributes. Claude helped generate the list of crossrefs (by scanning Wikidata + Mathlib). Comments are generated by [crossref-report](https://github.com/jcommelin/mathlib-crossref-report) and Wikilean. See https://wikilean.jackmccarthy.org/review?pr=40747 for reviewer UI. --- Mathlib/Algebra/Module/Projective.lean | 1 + Mathlib/Algebra/Ring/Periodic.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Defs.lean | 1 + Mathlib/Analysis/InnerProductSpace/Laplacian.lean | 1 + Mathlib/Combinatorics/SimpleGraph/Basic.lean | 1 + .../AffineSpace/AffineSubspace/Basic.lean | 1 + Mathlib/Probability/CentralLimitTheorem.lean | 1 + Mathlib/Topology/UniformSpace/Defs.lean | 1 + WikifunctionsScratch_probe.lean | 10 ++++++++++ 9 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 WikifunctionsScratch_probe.lean diff --git a/Mathlib/Algebra/Module/Projective.lean b/Mathlib/Algebra/Module/Projective.lean index 5d944d77a74cbc..c6bd0bb04be016 100644 --- a/Mathlib/Algebra/Module/Projective.lean +++ b/Mathlib/Algebra/Module/Projective.lean @@ -67,6 +67,7 @@ from the free `R`-module on `P` to `P` splits. -/ /-- An R-module is projective if it is a direct summand of a free module, or equivalently if maps from the module lift along surjections. There are several other equivalent definitions. -/ +@[wikidata Q942423] class Module.Projective (R : Type*) [Semiring R] (P : Type*) [AddCommMonoid P] [Module R P] : Prop where out : ∃ s : P →ₗ[R] P →₀ R, Function.LeftInverse (Finsupp.linearCombination R id) s diff --git a/Mathlib/Algebra/Ring/Periodic.lean b/Mathlib/Algebra/Ring/Periodic.lean index 9b86104f1dc820..bb0a228b59f6d7 100644 --- a/Mathlib/Algebra/Ring/Periodic.lean +++ b/Mathlib/Algebra/Ring/Periodic.lean @@ -41,7 +41,7 @@ namespace Function /-- A function `f` is said to be `Periodic` with period `c` if for all `x`, `f (x + c) = f x`. -/ -@[simp] +@[simp, wikidata Q184743] def Periodic [Add α] (f : α → β) (c : α) : Prop := ∀ x : α, f (x + c) = f x diff --git a/Mathlib/Analysis/InnerProductSpace/Defs.lean b/Mathlib/Analysis/InnerProductSpace/Defs.lean index cc34ea1e8dda94..2bc916e9ff9f00 100644 --- a/Mathlib/Analysis/InnerProductSpace/Defs.lean +++ b/Mathlib/Analysis/InnerProductSpace/Defs.lean @@ -103,6 +103,7 @@ Note that `NormedSpace` does not assume that `‖x‖=0` implies `x=0` (it is ra To construct a seminorm from an inner product, see `PreInnerProductSpace.ofCore`. -/ +@[wikidata Q214159] class InnerProductSpace (𝕜 : Type*) (E : Type*) [RCLike 𝕜] [SeminormedAddCommGroup E] extends NormedSpace 𝕜 E, Inner 𝕜 E where /-- The inner product induces the norm. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/Laplacian.lean b/Mathlib/Analysis/InnerProductSpace/Laplacian.lean index b75c2c3ef2661b..2041f4bc929c6d 100644 --- a/Mathlib/Analysis/InnerProductSpace/Laplacian.lean +++ b/Mathlib/Analysis/InnerProductSpace/Laplacian.lean @@ -128,6 +128,7 @@ variable (f s) in Laplacian for functions on real inner product spaces, with respect to a set `s`. Use `open InnerProductSpace` to access the notation `Δ[s]` for `InnerProductSpace.LaplacianWithin`. -/ +@[wikidata Q203484] noncomputable def laplacianWithin : E → F := fun x ↦ tensorIteratedFDerivWithinTwo ℝ f s x (InnerProductSpace.canonicalCovariantTensor E) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index d1b86b494d8c74..e5a45faaf3d37a 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -316,6 +316,7 @@ instance completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra (SimpleGrap iInf_iSup_eq f := by ext; simp [Classical.skolem] /-- The complete graph on a type `V` is the simple graph with all pairs of distinct vertices. -/ +@[wikidata Q45715] abbrev completeGraph (V : Type u) : SimpleGraph V := ⊤ /-- The graph with no edges on a given vertex type `V`. -/ diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index 5874d92b08e4bd..bec793d3828b41 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -820,6 +820,7 @@ variable [AffineSpace V P] /-- Two affine subspaces are parallel if one is related to the other by adding the same vector to all points. -/ +@[wikidata Q53875] def Parallel (s₁ s₂ : AffineSubspace k P) : Prop := ∃ v : V, s₂ = s₁.map (constVAdd k P v) diff --git a/Mathlib/Probability/CentralLimitTheorem.lean b/Mathlib/Probability/CentralLimitTheorem.lean index 312e75db6e0570..1e1676806ae8f7 100644 --- a/Mathlib/Probability/CentralLimitTheorem.lean +++ b/Mathlib/Probability/CentralLimitTheorem.lean @@ -120,6 +120,7 @@ private theorem tendstoInDistribution_inv_sqrt_mul_var_mul_sum_sub independent, identically distributed with mean `μ` and variance `v`, and a random variable `Y : Ω' → ℝ` following `gaussianReal 0 v`, the sequence `n ↦ (√n)⁻¹ * (∑ k ∈ Finset.range n, X k ω - n * μ)` converges to `Y` in distribution. -/ +@[wikidata Q190391] theorem tendstoInDistribution_inv_sqrt_mul_sum_sub (hY : HasLaw Y (gaussianReal 0 Var[X 0; P].toNNReal) P') (hX : MemLp (X 0) 2 P) (hindep : iIndepFun X P) diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index f23cfccc9011c6..b2078d7073c3d9 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -189,6 +189,7 @@ theorem UniformSpace.Core.nhds_toTopologicalSpace {α : Type u} (u : Core α) (x A metric space has a natural uniformity, and a uniform space has a natural topology. A topological group also has a natural uniformity, even when it is not metrizable. -/ +@[wikidata Q652446] class UniformSpace (α : Type u) extends TopologicalSpace α where /-- The uniformity filter. -/ protected uniformity : Filter (α × α) diff --git a/WikifunctionsScratch_probe.lean b/WikifunctionsScratch_probe.lean new file mode 100644 index 00000000000000..13124263b5a9c6 --- /dev/null +++ b/WikifunctionsScratch_probe.lean @@ -0,0 +1,10 @@ +import Mathlib.Data.Nat.GCD.Basic +import Mathlib.Tactic +open Nat +#check @Nat.gcd_rec +#check @Nat.Coprime +#check @Nat.coprime_iff_gcd_eq_one +#check @Nat.gcd_zero_left +#check @Nat.gcd_zero_right +#check @Nat.gcd_comm +#print Nat.Coprime From e10f52c0007c0ae339eadb810170c739a99f4c58 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Sun, 21 Jun 2026 08:49:04 +0000 Subject: [PATCH 0214/1300] feat(NumberTheory/GaussSum): results on Gauss sums of trivial characters (#40730) Add the special values of the Gauss sum when one or both of the characters is trivial: * `gaussSum_one_one`: the Gauss sum of the two trivial characters equals the number of units of `R`; * `gaussSum_one_right`: the Gauss sum of a nontrivial multiplicative character and the trivial additive character vanishes; * `gaussSum_one_left`: the Gauss sum of the trivial multiplicative character and a nontrivial additive character, over a finite field, equals `-1`. :robot: This PR was extracted from the [SKW project](https://github.com/xroblot/SKW) by Claude. --- Mathlib/NumberTheory/GaussSum.lean | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Mathlib/NumberTheory/GaussSum.lean b/Mathlib/NumberTheory/GaussSum.lean index dec2c041cf88a3..9092406fa0325b 100644 --- a/Mathlib/NumberTheory/GaussSum.lean +++ b/Mathlib/NumberTheory/GaussSum.lean @@ -95,6 +95,49 @@ lemma star_gaussSum_eq (χ : MulChar R ℂ) (ψ : AddChar R ℂ) : end GaussSumDef +/-! +### Gauss sums of trivial characters +-/ + +section GaussSumTrivial + +variable {R R' : Type*} [CommRing R] [Fintype R] [CommRing R'] + +/-- The Gauss sum of the two trivial characters is the cardinality of the unit group of `R`. -/ +@[simp] +theorem gaussSum_one_one : gaussSum (1 : MulChar R R') (1 : AddChar R R') = Nat.card Rˣ := by + classical + simp [gaussSum, MulChar.sum_one_eq_card_units] + +/-- The Gauss sum of a nontrivial multiplicative character and the trivial additive character +vanishes. -/ +theorem gaussSum_one_right [IsDomain R'] {χ : MulChar R R'} (hχ : χ ≠ 1) : + gaussSum χ (1 : AddChar R R') = 0 := by + simpa [gaussSum] using MulChar.sum_eq_zero_of_ne_one hχ + +end GaussSumTrivial + +section GaussSumTrivialField + +variable {R R' : Type*} [Field R] [Fintype R] [CommRing R'] [IsDomain R'] + +/-- The Gauss sum of the trivial multiplicative character and a nontrivial additive character, +over a finite field, is `-1`. -/ +theorem gaussSum_one_left {ψ : AddChar R R'} (hψ : ψ ≠ 1) : + gaussSum (1 : MulChar R R') ψ = -1 := by + classical + simp only [gaussSum, ← add_eq_zero_iff_eq_neg] + calc ∑ a, (1 : MulChar R R') a * ψ a + 1 + _ = ∑ a ∈ {0}ᶜ, (1 : MulChar R R') a * ψ a + 1 := by + simp [← ({0} : Finset R).sum_compl_add_sum] + _ = ∑ a ∈ {0}ᶜ, ψ a + ψ 0 := by + congr! <;> aesop (add simp MulChar.one_apply) + _ = 0 := by + rw [← AddChar.sum_eq_zero_of_ne_one hψ, ← Finset.sum_compl_add_sum (s := {0})] + simp + +end GaussSumTrivialField + /-! ### The product of two Gauss sums -/ From 403c5d3f621d47843aed5a9c6f8a3ede7237bf1a Mon Sep 17 00:00:00 2001 From: "Filippo A. E. Nuccio" <65080144+faenuccio@users.noreply.github.com> Date: Sun, 21 Jun 2026 09:11:17 +0000 Subject: [PATCH 0215/1300] fix: remove extra file related to wikidata (#40859) Co-authored-by: faenuccio --- WikifunctionsScratch_probe.lean | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 WikifunctionsScratch_probe.lean diff --git a/WikifunctionsScratch_probe.lean b/WikifunctionsScratch_probe.lean deleted file mode 100644 index 13124263b5a9c6..00000000000000 --- a/WikifunctionsScratch_probe.lean +++ /dev/null @@ -1,10 +0,0 @@ -import Mathlib.Data.Nat.GCD.Basic -import Mathlib.Tactic -open Nat -#check @Nat.gcd_rec -#check @Nat.Coprime -#check @Nat.coprime_iff_gcd_eq_one -#check @Nat.gcd_zero_left -#check @Nat.gcd_zero_right -#check @Nat.gcd_comm -#print Nat.Coprime From e5836dbb05fccdfa24ab3396d46f1f49b1f816ed Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Sun, 21 Jun 2026 09:53:45 +0000 Subject: [PATCH 0216/1300] feat: add `fun_prop` attribute to `OpenPartialHomeomorph.continuousOn` and friends (#40462) --- Mathlib/Topology/OpenPartialHomeomorph/Defs.lean | 2 ++ Mathlib/Topology/PartialHomeomorph/Defs.lean | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean index a8f90bd94cf6df..c9563195b3dc36 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean @@ -86,9 +86,11 @@ def Simps.symm_apply (e : OpenPartialHomeomorph X Y) : Y → X := e.symm initialize_simps_projections OpenPartialHomeomorph (toFun → apply, invFun → symm_apply) +@[fun_prop] protected theorem continuousOn : ContinuousOn e e.source := e.continuousOn_toFun +@[fun_prop] theorem continuousOn_symm : ContinuousOn e.symm e.target := e.continuousOn_invFun diff --git a/Mathlib/Topology/PartialHomeomorph/Defs.lean b/Mathlib/Topology/PartialHomeomorph/Defs.lean index ab78f5be70780c..3cd827e68cc315 100644 --- a/Mathlib/Topology/PartialHomeomorph/Defs.lean +++ b/Mathlib/Topology/PartialHomeomorph/Defs.lean @@ -86,9 +86,11 @@ def Simps.symm_apply (e : PartialHomeomorph X Y) : Y → X := e.symm initialize_simps_projections PartialHomeomorph (toFun → apply, invFun → symm_apply) +@[fun_prop] protected theorem continuousOn : ContinuousOn e e.source := e.continuousOn_toFun +@[fun_prop] theorem continuousOn_symm : ContinuousOn e.symm e.target := e.continuousOn_invFun From 29af5245bafea7d69fdca69591450f60b916ed71 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sun, 21 Jun 2026 13:42:19 +0000 Subject: [PATCH 0217/1300] chore: adaptation for batteries#1864 and batteries#1866 (#40821) - With the `checkUniv` linter being removed, we delete all corresponding `nolint` entries. We move any comments to the corresponding `checkUniv` core linter suppression. - With the `simpVarHead` linter being removed, we delete all corresponding `nolint` entries. Co-authored-by: mathlib-nightly-testing[bot] --- Mathlib/Algebra/Category/FGModuleCat/Basic.lean | 6 ------ Mathlib/Algebra/Category/Grp/Basic.lean | 6 ++---- Mathlib/Algebra/Module/Presentation/Basic.lean | 2 -- Mathlib/CategoryTheory/Bicategory/Basic.lean | 1 - Mathlib/CategoryTheory/Category/Cat.lean | 1 - Mathlib/CategoryTheory/Category/Quiv.lean | 1 - Mathlib/CategoryTheory/Category/ReflQuiv.lean | 1 - .../FiberedCategory/BasedCategory.lean | 1 - .../CategoryTheory/FiberedCategory/HasFibers.lean | 1 - Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean | 1 - Mathlib/CategoryTheory/Limits/Chosen/End.lean | 4 ++-- Mathlib/CategoryTheory/Limits/Creates.lean | 4 ++-- Mathlib/CategoryTheory/Limits/Preserves/Basic.lean | 8 ++++---- .../CategoryTheory/Limits/Preserves/Filtered.lean | 8 ++++---- .../CategoryTheory/Limits/Shapes/Multiequalizer.lean | 4 ---- Mathlib/CategoryTheory/MorphismProperty/Comma.lean | 2 +- Mathlib/Data/PFunctor/Univariate/Basic.lean | 5 +++-- Mathlib/Geometry/RingedSpace/Basic.lean | 2 +- Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean | 2 +- Mathlib/ModelTheory/Basic.lean | 1 - Mathlib/RingTheory/Extension/Presentation/Basic.lean | 1 - .../Extension/Presentation/Submersive.lean | 2 -- Mathlib/SetTheory/Ordinal/Univ.lean | 4 ++-- Mathlib/SetTheory/ZFC/PSet.lean | 1 - Mathlib/Topology/Category/CompHausLike/Limits.lean | 12 +++++------- lake-manifest.json | 2 +- 26 files changed, 28 insertions(+), 55 deletions(-) diff --git a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean index bd7a124b616bc7..eefbde73cc87b9 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean @@ -99,12 +99,6 @@ abbrev of (V : Type v) [AddCommGroup V] [Module R V] [Module.Finite R V] : FGMod lemma of_carrier (V : Type v) [AddCommGroup V] [Module R V] [Module.Finite R V] : of R V = V := rfl -/- -The reduction done by `simpVarHead` is stronger than the one actually used by `simp`, -so we get a false positive here --/ -attribute [nolint simpVarHead] of_carrier - variable {R} in /-- Lift a linear map between finitely generated modules to `FGModuleCat R`. -/ abbrev ofHom {V W : Type v} [AddCommGroup V] [Module R V] [Module.Finite R V] diff --git a/Mathlib/Algebra/Category/Grp/Basic.lean b/Mathlib/Algebra/Category/Grp/Basic.lean index bd4be06cb2de90..58e59d68d21006 100644 --- a/Mathlib/Algebra/Category/Grp/Basic.lean +++ b/Mathlib/Algebra/Category/Grp/Basic.lean @@ -602,22 +602,20 @@ instance CommGrpCat.forget_reflects_isos : (forget CommGrpCat.{u}).ReflectsIsomo -- this variant is then renamed with an `Aux` suffix set_option linter.checkUnivs false in /-- An alias for `GrpCat.{max u v}`, to deal around unification issues. -/ -@[to_additive (attr := nolint checkUnivs) GrpMaxAux +@[to_additive GrpMaxAux /-- An alias for `AddGrpCat.{max u v}`, to deal around unification issues. -/] abbrev GrpMax.{u1, u2} := GrpCat.{max u1 u2} set_option linter.checkUnivs false in /-- An alias for `AddGrpCat.{max u v}`, to deal around unification issues. -/ -@[nolint checkUnivs] abbrev AddGrpMax.{u1, u2} := AddGrpCat.{max u1 u2} set_option linter.checkUnivs false in /-- An alias for `CommGrpCat.{max u v}`, to deal around unification issues. -/ -@[to_additive (attr := nolint checkUnivs) AddCommGrpMaxAux +@[to_additive AddCommGrpMaxAux /-- An alias for `AddCommGrpCat.{max u v}`, to deal around unification issues. -/] abbrev CommGrpMax.{u1, u2} := CommGrpCat.{max u1 u2} set_option linter.checkUnivs false in /-- An alias for `AddCommGrpCat.{max u v}`, to deal around unification issues. -/ -@[nolint checkUnivs] abbrev AddCommGrpMax.{u1, u2} := AddCommGrpCat.{max u1 u2} diff --git a/Mathlib/Algebra/Module/Presentation/Basic.lean b/Mathlib/Algebra/Module/Presentation/Basic.lean index 47775e86dd5dff..4f372e7e6ee899 100644 --- a/Mathlib/Algebra/Module/Presentation/Basic.lean +++ b/Mathlib/Algebra/Module/Presentation/Basic.lean @@ -52,7 +52,6 @@ set_option linter.checkUnivs false in /-- Given a ring `A`, this structure involves a family of elements (indexed by a type `R`) in a free module `G →₀ A`. This allows to define an `A`-module by generators and relations, see `Relations.Quotient`. -/ -@[nolint checkUnivs] structure Relations where /-- the index type for generators -/ G : Type w₀ @@ -492,7 +491,6 @@ variable (M : Type v) [AddCommGroup M] [Module A M] set_option linter.checkUnivs false in /-- Given an `A`-module `M`, a term in this type is a presentation by `M` by generators and relations. -/ -@[nolint checkUnivs] structure Presentation extends Relations.{w₀, w₁} A, toRelations.Solution M, toSolution.IsPresentation where diff --git a/Mathlib/CategoryTheory/Bicategory/Basic.lean b/Mathlib/CategoryTheory/Bicategory/Basic.lean index a715b9ac6890cd..99c3d8903325ad 100644 --- a/Mathlib/CategoryTheory/Bicategory/Basic.lean +++ b/Mathlib/CategoryTheory/Bicategory/Basic.lean @@ -58,7 +58,6 @@ These associators and unitors satisfy the pentagon and triangle equations. See https://ncatlab.org/nlab/show/bicategory. -/ -@[nolint checkUnivs] class Bicategory (B : Type u) extends CategoryStruct.{v} B where /-- The category structure on the collection of 1-morphisms -/ homCategory : ∀ a b : B, Category.{w} (a ⟶ b) := by infer_instance diff --git a/Mathlib/CategoryTheory/Category/Cat.lean b/Mathlib/CategoryTheory/Category/Cat.lean index b179e05ca015f0..d2b24eb2228105 100644 --- a/Mathlib/CategoryTheory/Category/Cat.lean +++ b/Mathlib/CategoryTheory/Category/Cat.lean @@ -33,7 +33,6 @@ open Bicategory Functor -- intended to be used with explicit universe parameters set_option linter.checkUnivs false in /-- Category of categories. -/ -@[nolint checkUnivs] def Cat := Bundled Category.{v, u} diff --git a/Mathlib/CategoryTheory/Category/Quiv.lean b/Mathlib/CategoryTheory/Category/Quiv.lean index 60b2bf23c8709f..0cdcf0680ed8c8 100644 --- a/Mathlib/CategoryTheory/Category/Quiv.lean +++ b/Mathlib/CategoryTheory/Category/Quiv.lean @@ -24,7 +24,6 @@ namespace CategoryTheory -- intended to be used with explicit universe parameters set_option linter.checkUnivs false in /-- Category of quivers. -/ -@[nolint checkUnivs] def Quiv := Bundled Quiver.{v, u} diff --git a/Mathlib/CategoryTheory/Category/ReflQuiv.lean b/Mathlib/CategoryTheory/Category/ReflQuiv.lean index f1dc344cb96886..649de3f73a0344 100644 --- a/Mathlib/CategoryTheory/Category/ReflQuiv.lean +++ b/Mathlib/CategoryTheory/Category/ReflQuiv.lean @@ -23,7 +23,6 @@ universe v u v₁ v₂ u₁ u₂ set_option linter.checkUnivs false in /-- Category of refl quivers. -/ -@[nolint checkUnivs] def ReflQuiv := Bundled ReflQuiver.{v, u} diff --git a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean index 02f09d2a413c2a..0f0df6df1fc83e 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean @@ -38,7 +38,6 @@ variable {𝒮 : Type u₁} [Category.{v₁} 𝒮] set_option linter.checkUnivs false in /-- A based category over `𝒮` is a category `𝒳` together with a functor `p : 𝒳 ⥤ 𝒮`. -/ -@[nolint checkUnivs] structure BasedCategory (𝒮 : Type u₁) [Category.{v₁} 𝒮] where /-- The type of objects in a `BasedCategory` -/ obj : Type u₂ diff --git a/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean b/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean index 7dc53e2dabba98..18d798ebab7cd3 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean @@ -63,7 +63,6 @@ set_option linter.checkUnivs false in collection of categories `Fib S` for every `S : 𝒮` (the fiber categories), each equipped with a functors `ι : Fib S ⥤ 𝒳` which map constantly to `S` on the base such that the induced functor `Fib S ⥤ Fiber p S` is an equivalence. -/ -@[nolint checkUnivs] class HasFibers (p : 𝒳 ⥤ 𝒮) where /-- The type of objects of the category `Fib S` for each `S`. -/ Fib (S : 𝒮) : Type u₃ diff --git a/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean b/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean index 9860d8bd1379b6..fcfc708418d719 100644 --- a/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean +++ b/Mathlib/CategoryTheory/Groupoid/Grpd/Basic.lean @@ -35,7 +35,6 @@ namespace CategoryTheory -- intended to be used with explicit universe parameters set_option linter.checkUnivs false in /-- Category of groupoids -/ -@[nolint checkUnivs] def Grpd := Bundled Groupoid.{v, u} diff --git a/Mathlib/CategoryTheory/Limits/Chosen/End.lean b/Mathlib/CategoryTheory/Limits/Chosen/End.lean index 8bacfbd3374248..6e01480689f9b9 100644 --- a/Mathlib/CategoryTheory/Limits/Chosen/End.lean +++ b/Mathlib/CategoryTheory/Limits/Chosen/End.lean @@ -32,7 +32,7 @@ class ChosenCoendsOfShape (J : Type*) [Category* J] (C : Type*) [Category* C] wh set_option linter.checkUnivs false in /-- The data of chosen coends in `C`. -/ -@[nolint checkUnivs, pp_with_univ] +@[pp_with_univ] abbrev ChosenCoends (C : Type*) [Category* C] := ∀ {J : Type u} [Category.{v} J], ChosenCoendsOfShape J C @@ -107,7 +107,7 @@ class ChosenEndsOfShape (J : Type*) [Category* J] (C : Type*) [Category* C] wher set_option linter.checkUnivs false in /-- The data of chosen ends in `C`. -/ -@[nolint checkUnivs, pp_with_univ] +@[pp_with_univ] abbrev ChosenEnds (C : Type*) [Category* C] := ∀ {J : Type u} [Category.{v} J], ChosenEndsOfShape J C diff --git a/Mathlib/CategoryTheory/Limits/Creates.lean b/Mathlib/CategoryTheory/Limits/Creates.lean index 0608f6fb77867b..553b495bb93180 100644 --- a/Mathlib/CategoryTheory/Limits/Creates.lean +++ b/Mathlib/CategoryTheory/Limits/Creates.lean @@ -87,7 +87,7 @@ set_option linter.checkUnivs false in -- https://github.com/leanprover/lean4/pull/12423, the shape universes in -- `CreatesLimitsOfSize` and `CreatesColimitsOfSize` would default to universe output parameters. -- See Note [universe output parameters and typeclass caching]. -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class CreatesLimitsOfSize (F : C ⥤ D) where CreatesLimitsOfShape : ∀ {J : Type w} [Category.{w'} J], CreatesLimitsOfShape J F := by infer_instance @@ -117,7 +117,7 @@ class CreatesColimitsOfShape (J : Type w) [Category.{w'} J] (F : C ⥤ D) where -- This should be used with explicit universe variables. set_option linter.checkUnivs false in /-- `F` creates colimits if it creates colimits of shape `J` for any small `J`. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class CreatesColimitsOfSize (F : C ⥤ D) where CreatesColimitsOfShape : ∀ {J : Type w} [Category.{w'} J], CreatesColimitsOfShape J F := by infer_instance diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean index 1967dc99751bd3..d9bbd2bac9030c 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean @@ -80,7 +80,7 @@ diagram `J ⥤ C` to limit cones, where `J : Type u` with `[Category.{v} J]`. -/ -- `PreservesLimitsOfSize`, `PreservesColimitsOfSize`, `ReflectsLimitsOfSize`, and -- `ReflectsColimitsOfSize` would default to universe output parameters. -- See Note [universe output parameters and typeclass caching]. -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class PreservesLimitsOfSize (F : C ⥤ D) : Prop where preservesLimitsOfShape : ∀ {J : Type w} [Category.{w'} J], PreservesLimitsOfShape J F := by infer_instance @@ -93,7 +93,7 @@ abbrev PreservesLimits (F : C ⥤ D) := -- This should be used with explicit universe variables. /-- `PreservesColimitsOfSize.{v u} F` means that `F` sends all colimit cocones over any diagram `J ⥤ C` to colimit cocones, where `J : Type u` with `[Category.{v} J]`. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class PreservesColimitsOfSize (F : C ⥤ D) : Prop where preservesColimitsOfShape : ∀ {J : Type w} [Category.{w'} J], PreservesColimitsOfShape J F := by infer_instance @@ -415,7 +415,7 @@ whenever the image of a cone over some `K : J ⥤ C` under `F` is a limit cone i the cone was already a limit cone in `C`. Note that we do not assume a priori that `D` actually has any limits. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class ReflectsLimitsOfSize (F : C ⥤ D) : Prop where reflectsLimitsOfShape : ∀ {J : Type w} [Category.{w'} J], ReflectsLimitsOfShape J F := by infer_instance @@ -434,7 +434,7 @@ whenever the image of a cocone over some `K : J ⥤ C` under `F` is a colimit co the cocone was already a colimit cocone in `C`. Note that we do not assume a priori that `D` actually has any colimits. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class ReflectsColimitsOfSize (F : C ⥤ D) : Prop where reflectsColimitsOfShape : ∀ {J : Type w} [Category.{w'} J], ReflectsColimitsOfShape J F := by infer_instance diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean index 693fdffbdb2041..ba98dbaaf5d1d6 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean @@ -48,7 +48,7 @@ filtered diagram `J ⥤ C` to colimit cocones, where `J : Type w` with `[Categor -- `PreservesFilteredColimitsOfSize`, `ReflectsFilteredColimitsOfSize`, -- `PreservesCofilteredLimitsOfSize`, and `ReflectsCofilteredLimitsOfSize` would default to -- universe output parameters. See Note [universe output parameters and typeclass caching]. -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class PreservesFilteredColimitsOfSize (F : C ⥤ D) : Prop where preserves_filtered_colimits : ∀ (J : Type w) [Category.{w'} J] [IsFiltered J], PreservesColimitsOfShape J F @@ -104,7 +104,7 @@ section Reflects -- This should be used with explicit universe variables. /-- `ReflectsFilteredColimitsOfSize.{w', w} F` means that whenever the image of a filtered cocone under `F` is a colimit cocone, the original cocone was already a colimit. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class ReflectsFilteredColimitsOfSize (F : C ⥤ D) : Prop where reflects_filtered_colimits : ∀ (J : Type w) [Category.{w'} J] [IsFiltered J], ReflectsColimitsOfShape J F @@ -164,7 +164,7 @@ section Preserves -- This should be used with explicit universe variables. /-- `PreservesCofilteredLimitsOfSize.{w', w} F` means that `F` sends all limit cones over any cofiltered diagram `J ⥤ C` to limit cones, where `J : Type w` with `[Category.{w'} J]`. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class PreservesCofilteredLimitsOfSize (F : C ⥤ D) : Prop where preserves_cofiltered_limits : ∀ (J : Type w) [Category.{w'} J] [IsCofiltered J], PreservesLimitsOfShape J F @@ -220,7 +220,7 @@ section Reflects -- This should be used with explicit universe variables. /-- `ReflectsCofilteredLimitsOfSize.{w', w} F` means that whenever the image of a cofiltered cone under `F` is a limit cone, the original cone was already a limit. -/ -@[univ_out_params, nolint checkUnivs, pp_with_univ] +@[univ_out_params, pp_with_univ] class ReflectsCofilteredLimitsOfSize (F : C ⥤ D) : Prop where reflects_cofiltered_limits : ∀ (J : Type w) [Category.{w'} J] [IsCofiltered J], ReflectsLimitsOfShape J F diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index 7a154e987b310e..aa78bf468b47b3 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -38,7 +38,6 @@ universe t w w' v u set_option linter.checkUnivs false in /-- The shape of a multiequalizer diagram. It involves two types `L` and `R`, and two maps `R → L`. -/ -@[nolint checkUnivs] structure MulticospanShape where /-- the left type -/ L : Type w @@ -62,7 +61,6 @@ def MulticospanShape.prod (ι : Type w) : MulticospanShape where set_option linter.checkUnivs false in /-- The shape of a multicoequalizer diagram. It involves two types `L` and `R`, and two maps `L → R`. -/ -@[nolint checkUnivs] structure MultispanShape where /-- the left type -/ L : Type w @@ -300,7 +298,6 @@ def arrowEquiv : end WalkingMultispan /-- This is a structure encapsulating the data necessary to define a `Multicospan`. -/ -@[nolint checkUnivs] structure MulticospanIndex (J : MulticospanShape.{w, w'}) (C : Type u) [Category.{v} C] where /-- Left map, from `J.L` to `C` -/ @@ -313,7 +310,6 @@ structure MulticospanIndex (J : MulticospanShape.{w, w'}) snd : ∀ b, left (J.snd b) ⟶ right b /-- This is a structure encapsulating the data necessary to define a `Multispan`. -/ -@[nolint checkUnivs] structure MultispanIndex (J : MultispanShape.{w, w'}) (C : Type u) [Category.{v} C] where /-- Left map, from `J.L` to `C` -/ diff --git a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean index 8a0d834d4922e1..b942cab0ba82c2 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean @@ -168,7 +168,7 @@ structure Hom (X Y : P.Comma L R Q W) extends CommaMorphism X.toComma Y.toComma abbrev Hom.hom {X Y : P.Comma L R Q W} (f : Comma.Hom X Y) : X.toComma ⟶ Y.toComma := f.toCommaMorphism -@[simp, nolint simpVarHead] +@[simp] lemma Hom.hom_mk {X Y : P.Comma L R Q W} (f : CommaMorphism X.toComma Y.toComma) (hf) (hg) : Comma.Hom.hom ⟨f, hf, hg⟩ = f := rfl diff --git a/Mathlib/Data/PFunctor/Univariate/Basic.lean b/Mathlib/Data/PFunctor/Univariate/Basic.lean index 69a65f27239bf0..a7c35efe92bc64 100644 --- a/Mathlib/Data/PFunctor/Univariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Univariate/Basic.lean @@ -18,6 +18,8 @@ This file defines polynomial functors and the W-type construction as a polynomia universe u v uA uB uA₁ uB₁ uA₂ uB₂ v₁ v₂ v₃ +-- Note: `set_option linter.checkUnivs` should not apply here, +-- we really do want two separate universe levels set_option linter.checkUnivs false in /-- A polynomial functor `P` is given by a type `A` and a family `B` of types over `A`. `P` maps any type `α` to a new type `P α`, which is defined as the sigma type `Σ x, P.B x → α`. @@ -26,8 +28,7 @@ An element of `P α` is a pair `⟨a, f⟩`, where `a` is an element of a type ` `f : B a → α`. Think of `a` as the shape of the object and `f` as an index to the relevant elements of `α`. -/ --- Note: `nolint checkUnivs` should not apply here, we really do want two separate universe levels -@[pp_with_univ, nolint checkUnivs] +@[pp_with_univ] structure PFunctor where /-- The head type -/ A : Type uA diff --git a/Mathlib/Geometry/RingedSpace/Basic.lean b/Mathlib/Geometry/RingedSpace/Basic.lean index 4a615fbba24138..9e998ab3534122 100644 --- a/Mathlib/Geometry/RingedSpace/Basic.lean +++ b/Mathlib/Geometry/RingedSpace/Basic.lean @@ -38,9 +38,9 @@ open TopCat.Presheaf namespace AlgebraicGeometry +-- The universes appear together in the type, but separately in the value. set_option linter.checkUnivs false in /-- The type of Ringed spaces, as an abbreviation for `SheafedSpace CommRingCat`. -/ -@[nolint checkUnivs] -- The universes appear together in the type, but separately in the value. abbrev RingedSpace : Type max (u + 1) (v + 1) := SheafedSpace.{v + 1, v, u} CommRingCat.{v} diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index be2bf1ffbab2ff..9cde91f2d687b5 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -84,7 +84,7 @@ structure Hom (X Y : LocallyRingedSpace.{u}) : Type _ abbrev Hom.toShHom {X Y : LocallyRingedSpace.{u}} (f : X.Hom Y) : X.toSheafedSpace ⟶ Y.toSheafedSpace := InducedCategory.homMk f.1 -@[simp, nolint simpVarHead] +@[simp] lemma Hom.toShHom_mk {X Y : LocallyRingedSpace.{u}} (f : X.toPresheafedSpace.Hom Y.toPresheafedSpace) (hf) : Hom.toShHom ⟨f, hf⟩ = InducedCategory.homMk f := rfl diff --git a/Mathlib/ModelTheory/Basic.lean b/Mathlib/ModelTheory/Basic.lean index bab71eb42a7dd3..c1a889021df466 100644 --- a/Mathlib/ModelTheory/Basic.lean +++ b/Mathlib/ModelTheory/Basic.lean @@ -55,7 +55,6 @@ namespace FirstOrder set_option linter.checkUnivs false in /-- A first-order language consists of a type of functions of every natural-number arity and a type of relations of every natural-number arity. -/ -@[nolint checkUnivs] structure Language where /-- For every arity, a `Type u` of functions of that arity -/ Functions : ℕ → Type u diff --git a/Mathlib/RingTheory/Extension/Presentation/Basic.lean b/Mathlib/RingTheory/Extension/Presentation/Basic.lean index 20b88f8700f9c0..b501c0723b700f 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Basic.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Basic.lean @@ -55,7 +55,6 @@ A presentation of an `R`-algebra `S` is a family of generators with `σ → MvPolynomial ι R`: The assignment of each relation to a polynomial in the generators. -/ -@[nolint checkUnivs] structure Algebra.Presentation extends Algebra.Generators R S ι where /-- The assignment of each relation to a polynomial in the generators. -/ relation : σ → toGenerators.Ring diff --git a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean index 08b03267550fd6..956fcb7d611e89 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean @@ -64,7 +64,6 @@ with relations equipped with an injective `map : relations → vars`. This map determines how the differential of `P` is constructed. See `PreSubmersivePresentation.differential` for details. -/ -@[nolint checkUnivs] structure PreSubmersivePresentation extends Algebra.Presentation R S ι σ where /-- A map from the relations type to the variables type. Used to compute the differential. -/ map : σ → ι @@ -495,7 +494,6 @@ variable [Finite σ] A `PreSubmersivePresentation` is submersive if its Jacobian is a unit in `S` and the presentation is finite. -/ -@[nolint checkUnivs] structure SubmersivePresentation extends PreSubmersivePresentation.{t, w} R S ι σ where jacobian_isUnit : IsUnit toPreSubmersivePresentation.jacobian diff --git a/Mathlib/SetTheory/Ordinal/Univ.lean b/Mathlib/SetTheory/Ordinal/Univ.lean index 7abc9881f863c0..5b302b22694094 100644 --- a/Mathlib/SetTheory/Ordinal/Univ.lean +++ b/Mathlib/SetTheory/Ordinal/Univ.lean @@ -33,7 +33,7 @@ open Ordinal in -- intended to be used with explicit universe parameters /-- The ordinal `univ.{u, v}` is the order type of `Ordinal.{u}` or `Cardinal.{u}`, as an element of `Ordinal.{v}` (when `u < v`). -/ -@[pp_with_univ, nolint checkUnivs] +@[pp_with_univ] def Ordinal.univ : Ordinal.{max (u + 1) v} := lift.{v, u + 1} (typeLT Ordinal) @@ -42,7 +42,7 @@ open Cardinal in -- intended to be used with explicit universe parameters /-- The cardinal `univ.{u, v}` is the cardinality of `Ordinal.{u}` or `Cardinal.{u}`, as an element of `Cardinal.{v}` (when `u < v`). -/ -@[pp_with_univ, nolint checkUnivs] +@[pp_with_univ] def Cardinal.univ : Cardinal.{max (u + 1) v} := lift.{v, u + 1} #Ordinal diff --git a/Mathlib/SetTheory/ZFC/PSet.lean b/Mathlib/SetTheory/ZFC/PSet.lean index ca273f551fb0fe..1e6516a0bbdc19 100644 --- a/Mathlib/SetTheory/ZFC/PSet.lean +++ b/Mathlib/SetTheory/ZFC/PSet.lean @@ -443,7 +443,6 @@ protected def Lift : PSet.{u} → PSet.{max u v} -- intended to be used with explicit universe parameters set_option linter.checkUnivs false in /-- Embedding of one universe in another -/ -@[nolint checkUnivs] def embed : PSet.{max (u + 1) v} := ⟨ULift.{v, u + 1} PSet, fun ⟨x⟩ => PSet.Lift.{u, max (u + 1) v} x⟩ diff --git a/Mathlib/Topology/Category/CompHausLike/Limits.lean b/Mathlib/Topology/Category/CompHausLike/Limits.lean index a608a17cabb86d..eedc1febd64392 100644 --- a/Mathlib/Topology/Category/CompHausLike/Limits.lean +++ b/Mathlib/Topology/Category/CompHausLike/Limits.lean @@ -120,6 +120,11 @@ lemma finiteCoproduct.ι_desc_apply {B : CompHausLike P} {π : (a : α) → X a instance : HasCoproduct X where exists_colimit := ⟨finiteCoproduct.cofan X, finiteCoproduct.isColimit X⟩ +/- +This linter complains that the universes `u` and `w` only occur together, but `w` appears by itself +in the indexing type of the coproduct. In almost all cases, `w` will be either `0` or `u`, but we +want to allow both possibilities. +-/ set_option linter.checkUnivs false in variable (P) in /-- @@ -129,13 +134,6 @@ property `P`. class HasExplicitFiniteCoproducts : Prop where hasProp {α : Type w} [Finite α] (X : α → CompHausLike.{max u w} P) : HasExplicitFiniteCoproduct X -/- -This linter complains that the universes `u` and `w` only occur together, but `w` appears by itself -in the indexing type of the coproduct. In almost all cases, `w` will be either `0` or `u`, but we -want to allow both possibilities. --/ -attribute [nolint checkUnivs] HasExplicitFiniteCoproducts - attribute [instance] HasExplicitFiniteCoproducts.hasProp instance [HasExplicitFiniteCoproducts.{w} P] (α : Type w) [Finite α] : diff --git a/lake-manifest.json b/lake-manifest.json index 44a71cb13c5519..4e97d39e9ad8eb 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "125807f43a86b5d58892b7ea6972eec0d6c164d2", + "rev": "e535e4feb0aa360e59e7adf4837b91ffbfb8c943", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 712103e03a61d29eafce1b530fa83ad6696ed9e9 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sun, 21 Jun 2026 17:29:57 +0000 Subject: [PATCH 0218/1300] chore: update Mathlib dependencies 2026-06-21 (#40849) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 4e97d39e9ad8eb..07ac27b85df079 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e535e4feb0aa360e59e7adf4837b91ffbfb8c943", + "rev": "7d1b02eb63b526dff04cb990cf05b06b38ccbd3f", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 617410cab1195bc6c05516bbf29b44d921845fe8 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Sun, 21 Jun 2026 18:23:57 +0000 Subject: [PATCH 0219/1300] chore(Algebra/simp): remove `@[simp]` tag in `AlgEquiv.coe_ringEquiv` since it can be proven by simp (#40834) And deprecate `AlgEquiv.coe_ringEquiv'` as a duplicate of `AlgEquiv.coe_ringEquiv`. --- Mathlib/Algebra/Algebra/Equiv.lean | 7 ++----- Mathlib/RingTheory/AdjoinRoot.lean | 2 +- scripts/nolints_prime_decls.txt | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index bfa2ba100c82b6..d3a116e40011be 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -160,12 +160,9 @@ theorem toRingEquiv_eq_coe : e.toRingEquiv = e := lemma toRingEquiv_toRingHom : ((e : A₁ ≃+* A₂) : A₁ →+* A₂) = e := rfl -@[simp] -theorem coe_ringEquiv : ((e : A₁ ≃+* A₂) : A₁ → A₂) = e := - rfl +theorem coe_ringEquiv : ((e : A₁ ≃+* A₂) : A₁ → A₂) = e := by simp -theorem coe_ringEquiv' : (e.toRingEquiv : A₁ → A₂) = e := - rfl +@[deprecated (since := "2026-06-21")] alias coe_ringEquiv' := coe_ringEquiv theorem coe_ringEquiv_injective : Function.Injective ((↑) : (A₁ ≃ₐ[R] A₂) → A₁ ≃+* A₂) := fun _ _ h => ext <| RingEquiv.congr_fun h diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index 46e60c23c827e6..42bca0ed2495bc 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -1014,7 +1014,7 @@ theorem quotientEquivQuotientMinpolyMap_apply_mk (pb : PowerBasis R S) (I : Idea (Ideal.span ({(minpoly R pb.gen).map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I)))) (g.map (Ideal.Quotient.mk I)) := by rw [PowerBasis.quotientEquivQuotientMinpolyMap, AlgEquiv.trans_apply, AlgEquiv.ofRingEquiv_apply, - quotientEquiv_mk, AlgEquiv.coe_ringEquiv', AdjoinRoot.equiv'_symm_apply, PowerBasis.lift_aeval, + quotientEquiv_mk, AlgEquiv.coe_ringEquiv, AdjoinRoot.equiv'_symm_apply, PowerBasis.lift_aeval, AdjoinRoot.aeval_eq, AdjoinRoot.quotEquivQuotMap_apply_mk] -- This lemma should have the simp tag but this causes a lint issue. diff --git a/scripts/nolints_prime_decls.txt b/scripts/nolints_prime_decls.txt index f5c9c276fd3d88..98c8ef29d15948 100644 --- a/scripts/nolints_prime_decls.txt +++ b/scripts/nolints_prime_decls.txt @@ -136,7 +136,6 @@ Algebra.TensorProduct.natCast_def' Algebra.toMatrix_lmul' AlgEquiv.apply_smulCommClass' AlgEquiv.coe_restrictScalars' -AlgEquiv.coe_ringEquiv' AlgEquiv.mk_coe' AlgHom.coe_mk' AlgHom.coe_restrictScalars' From 9c27dca6e4fa0831af9fae465fea2ad429876790 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sun, 21 Jun 2026 18:23:58 +0000 Subject: [PATCH 0220/1300] refactor(Topology): rename ```LocPathConnected``` (#40868) Rename ```LocPathConnected``` to ```LocallyPathConnected``` per discussion at https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Rename.20.60.60.60LocPathConnectedSpace.60.60.60.3F/with/582824006 Co-authored-by: Batixx --- Mathlib.lean | 2 +- .../CStarAlgebra/Unitary/Connected.lean | 5 +- Mathlib/Analysis/Complex/BranchLogRoot.lean | 6 +- .../Complex/UpperHalfPlane/Topology.lean | 2 +- Mathlib/Geometry/Manifold/ChartedSpace.lean | 8 +- Mathlib/Geometry/Manifold/Instances/Real.lean | 8 +- .../Algebra/Module/LocallyConvex.lean | 13 +- .../Compactness/DeltaGeneratedSpace.lean | 4 +- ...nnected.lean => LocallyPathConnected.lean} | 136 ++++++++++++------ .../Topology/Connected/PathComponentOne.lean | 6 +- Mathlib/Topology/Homotopy/Lifting.lean | 10 +- .../Homotopy/LocallyContractible.lean | 6 +- 12 files changed, 132 insertions(+), 74 deletions(-) rename Mathlib/Topology/Connected/{LocPathConnected.lean => LocallyPathConnected.lean} (69%) diff --git a/Mathlib.lean b/Mathlib.lean index b499769e07f489..92e3cf81853411 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7779,8 +7779,8 @@ public import Mathlib.Topology.Compactness.SigmaCompact public import Mathlib.Topology.Connected.Basic public import Mathlib.Topology.Connected.CardComponents public import Mathlib.Topology.Connected.Clopen -public import Mathlib.Topology.Connected.LocPathConnected public import Mathlib.Topology.Connected.LocallyConnected +public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Topology.Connected.PathComponentOne public import Mathlib.Topology.Connected.PathConnected public import Mathlib.Topology.Connected.Separation diff --git a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean index ab6c20e1b8b863..ac8d947d77b276 100644 --- a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean +++ b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean @@ -47,7 +47,8 @@ products of exponential unitaries. `expUnitary x` for a selfadjoint element `x`. + `Unitary.isPathConnected_ball`: any ball of radius `δ < 2` in the unitary group of a unital C⋆-algebra is path connected. -+ `Unitary.instLocPathConnectedSpace`: the unitary group of a C⋆-algebra is locally path connected. ++ `Unitary.instLocallyPathConnectedSpace`: the unitary group of a C⋆-algebra is + locally path connected. + `Unitary.mem_pathComponentOne_iff`: The path component of the identity in the unitary group of a C⋆-algebra is the set of unitaries that can be expressed as a product of exponentials of selfadjoint elements. @@ -326,7 +327,7 @@ lemma Unitary.isPathConnected_ball (u : unitary A) (δ : ℝ) (hδ₀ : 0 < δ) norm_expUnitary_smul_argSelfAdjoint_sub_one_le u t.2 (hu.trans hδ₂) |>.trans_lt hu /-- The unitary group in a C⋆-algebra is locally path connected. -/ -instance Unitary.instLocPathConnectedSpace : LocPathConnectedSpace (unitary A) := +instance Unitary.instLocallyPathConnectedSpace : LocallyPathConnectedSpace (unitary A) := .of_bases (fun _ ↦ nhds_basis_uniformity <| uniformity_basis_dist_lt zero_lt_two) <| by simpa using! isPathConnected_ball diff --git a/Mathlib/Analysis/Complex/BranchLogRoot.lean b/Mathlib/Analysis/Complex/BranchLogRoot.lean index 2a00d8bd917320..ffcf8ac4c78979 100644 --- a/Mathlib/Analysis/Complex/BranchLogRoot.lean +++ b/Mathlib/Analysis/Complex/BranchLogRoot.lean @@ -5,7 +5,7 @@ Authors: Yury Kudryashov -/ module -public import Mathlib.Topology.Connected.LocPathConnected +public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Analysis.Complex.Basic public import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected public import Mathlib.Analysis.Complex.Exponential @@ -27,7 +27,7 @@ open Set namespace Complex -variable {X : Type*} [TopologicalSpace X] [LocPathConnectedSpace X] {U : Set X} +variable {X : Type*} [TopologicalSpace X] [LocallyPathConnectedSpace X] {U : Set X} /-- If `g : X → ℂ` defined on a locally path connected space is continuous on an open simply connected set `U` and `0 ∉ g '' U`, @@ -39,7 +39,7 @@ theorem exists_continuousOn_eqOn_exp_comp (hUc : IsSimplyConnected U) (hUo : IsO ∃ f : X → ℂ, ContinuousOn f U ∧ EqOn (exp ∘ f) g U := by classical have := hUc.simplyConnectedSpace - have := hUo.locPathConnectedSpace + have := hUo.locallyPathConnectedSpace rcases hUc.nonempty with ⟨x₀, hx₀U⟩ have hx₀ : g x₀ ≠ 0 := ne_of_mem_of_not_mem (mem_image_of_mem g hx₀U) hU₀ lift x₀ to U using hx₀U diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean index 5962cb0757487a..fa7163e6fe288f 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean @@ -69,7 +69,7 @@ instance : ContractibleSpace ℍ := by rw [isEmbedding_coe.toHomeomorph.trans (.setCongr range_coe) |>.contractibleSpace_iff] exact (convex_halfSpace_im_gt 0).contractibleSpace ⟨I, one_pos.trans_eq I_im.symm⟩ -instance : LocPathConnectedSpace ℍ := isOpenEmbedding_coe.locPathConnectedSpace +instance : LocallyPathConnectedSpace ℍ := isOpenEmbedding_coe.locallyPathConnectedSpace instance : NoncompactSpace ℍ where noncompact_univ h := by diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 59a70521d47941..778649d7c467bc 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -6,7 +6,7 @@ Authors: Sébastien Gouëzel module public import Mathlib.Geometry.Manifold.StructureGroupoid -public import Mathlib.Topology.Connected.LocPathConnected +public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Topology.IsLocalHomeomorph public import Mathlib.Topology.OpenPartialHomeomorph.Constructions @@ -265,7 +265,8 @@ theorem ChartedSpace.locallyConnectedSpace [LocallyConnectedSpace H] : LocallyCo /-- If a topological space `M` admits an atlas with locally path-connected charts, then `M` itself is locally path-connected. -/ -theorem ChartedSpace.locPathConnectedSpace [LocPathConnectedSpace H] : LocPathConnectedSpace M := by +theorem ChartedSpace.locallyPathConnectedSpace [LocallyPathConnectedSpace H] : + LocallyPathConnectedSpace M := by refine ⟨fun x ↦ ⟨fun s ↦ ⟨fun hs ↦ ?_, fun ⟨u, hu⟩ ↦ Filter.mem_of_superset hu.1.1 hu.2⟩⟩⟩ let e := chartAt H x let t := s ∩ e.source @@ -280,6 +281,9 @@ theorem ChartedSpace.locPathConnectedSpace [LocPathConnectedSpace H] : LocPathCo · exact (image_mono pathComponentIn_subset).trans (PartialEquiv.symm_image_image_of_subset_source _ inter_subset_right).subset +@[deprecated (since := "2026-06-21")] +alias ChartedSpace.locPathConnectedSpace := ChartedSpace.locallyPathConnectedSpace + /-- If `M` is modelled on `H'` and `H'` is itself modelled on `H`, then we can consider `M` as being modelled on `H`. -/ @[implicit_reducible] diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 5e11d5245691c4..0ac71a8e87b7f7 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -108,11 +108,11 @@ instance EuclideanHalfSpace.pathConnectedSpace [NeZero n] : instance EuclideanQuadrant.pathConnectedSpace : PathConnectedSpace (EuclideanQuadrant n) := isPathConnected_iff_pathConnectedSpace.mp <| convex.isPathConnected ⟨0, by simp⟩ -instance [NeZero n] : LocPathConnectedSpace (EuclideanHalfSpace n) := - EuclideanHalfSpace.convex.locPathConnectedSpace +instance [NeZero n] : LocallyPathConnectedSpace (EuclideanHalfSpace n) := + EuclideanHalfSpace.convex.locallyPathConnectedSpace -instance : LocPathConnectedSpace (EuclideanQuadrant n) := - EuclideanQuadrant.convex.locPathConnectedSpace +instance : LocallyPathConnectedSpace (EuclideanQuadrant n) := + EuclideanQuadrant.convex.locallyPathConnectedSpace theorem range_euclideanHalfSpace (n : ℕ) [NeZero n] : range (Subtype.val : EuclideanHalfSpace n → _) = { y | 0 ≤ y 0 } := diff --git a/Mathlib/Topology/Algebra/Module/LocallyConvex.lean b/Mathlib/Topology/Algebra/Module/LocallyConvex.lean index a626fcaee69bcb..c252b2838872f4 100644 --- a/Mathlib/Topology/Algebra/Module/LocallyConvex.lean +++ b/Mathlib/Topology/Algebra/Module/LocallyConvex.lean @@ -6,7 +6,7 @@ Authors: Anatole Dedecker module public import Mathlib.Analysis.Convex.Topology -public import Mathlib.Topology.Connected.LocPathConnected +public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Analysis.Convex.PathConnected /-! @@ -100,14 +100,14 @@ theorem locallyConvexSpace_iff_exists_convex_subset_zero : (locallyConvexSpace_iff_zero 𝕜 E).trans hasBasis_self -- see Note [lower instance priority] -instance (priority := 100) LocallyConvexSpace.toLocPathConnectedSpace [Module ℝ E] - [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] : LocPathConnectedSpace E := +instance (priority := 100) LocallyConvexSpace.toLocallyPathConnectedSpace [Module ℝ E] + [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] : LocallyPathConnectedSpace E := .of_bases (fun x ↦ convex_basis (𝕜 := ℝ) x) fun _ _ hs ↦ hs.2.isPathConnected <| nonempty_of_mem <| mem_of_mem_nhds hs.1 /-- Convex subsets of locally convex spaces are locally path-connected. -/ -theorem Convex.locPathConnectedSpace [Module ℝ E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] - {S : Set E} (hS : Convex ℝ S) : LocPathConnectedSpace S := by +theorem Convex.locallyPathConnectedSpace [Module ℝ E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] + {S : Set E} (hS : Convex ℝ S) : LocallyPathConnectedSpace S := by refine ⟨fun x ↦ ⟨fun s ↦ ⟨fun hs ↦ ?_, fun ⟨t, ht⟩ ↦ mem_of_superset ht.1.1 ht.2⟩⟩⟩ let ⟨t, ht⟩ := (mem_nhds_subtype S x s).mp hs let ⟨t', ht'⟩ := (LocallyConvexSpace.convex_basis (𝕜 := ℝ) x.1).mem_iff.mp ht.1 @@ -116,6 +116,9 @@ theorem Convex.locPathConnectedSpace [Module ℝ E] [ContinuousSMul ℝ E] [Loca · refine Subtype.preimage_coe_self_inter _ _ ▸ IsPathConnected.preimage_coe ?_ inter_subset_left exact (hS.inter ht'.1.2).isPathConnected ⟨x, x.2, mem_of_mem_nhds ht'.1.1⟩ +@[deprecated (since := "2026-06-21")] +alias Convex.locPathConnectedSpace := Convex.locallyPathConnectedSpace + end Module section LinearOrderedField diff --git a/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean b/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean index d06465c472ce81..abcccc287c9198 100644 --- a/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean +++ b/Mathlib/Topology/Compactness/DeltaGeneratedSpace.lean @@ -49,10 +49,10 @@ abbrev of : Type _ := WithGeneratedByTopology (fun n ↦ Fin n → ℝ) Y /-- Delta-generated spaces are locally path-connected. -/ instance [DeltaGeneratedSpace X] : - LocPathConnectedSpace X := by + LocallyPathConnectedSpace X := by rw [← IsGeneratedBy.generatedBy_eq (X := fun n ↦ Fin n → ℝ) (Y := X), generatedBy_eq_coinduced] - exact LocPathConnectedSpace.coinduced _ + exact LocallyPathConnectedSpace.coinduced _ /-- Delta-generated spaces are sequential. -/ instance [DeltaGeneratedSpace X] : SequentialSpace X := by diff --git a/Mathlib/Topology/Connected/LocPathConnected.lean b/Mathlib/Topology/Connected/LocallyPathConnected.lean similarity index 69% rename from Mathlib/Topology/Connected/LocPathConnected.lean rename to Mathlib/Topology/Connected/LocallyPathConnected.lean index 4f43cadb842f43..d26494a7700b2a 100644 --- a/Mathlib/Topology/Connected/LocPathConnected.lean +++ b/Mathlib/Topology/Connected/LocallyPathConnected.lean @@ -11,7 +11,7 @@ public import Mathlib.Topology.AlexandrovDiscrete /-! # Locally path-connected spaces -This file defines `LocPathConnectedSpace X`, a predicate class asserting that `X` is locally +This file defines `LocallyPathConnectedSpace X`, a predicate class asserting that `X` is locally path-connected, in that each point has a basis of path-connected neighborhoods. ## Main results @@ -23,11 +23,11 @@ path-connected, in that each point has a basis of path-connected neighborhoods. * `pathConnectedSpace_iff_connectedSpace`: locally path-connected spaces are path-connected iff they are connected. * `instLocallyConnectedSpace`: locally path-connected spaces are also locally connected. -* `IsOpen.locPathConnectedSpace`: open subsets of locally path-connected spaces are +* `IsOpen.locallyPathConnectedSpace`: open subsets of locally path-connected spaces are locally path-connected. -* `LocPathConnectedSpace.coinduced` / `Quotient.locPathConnectedSpace`: quotients of locally +* `LocallyPathConnectedSpace.coinduced` / `Quotient.locallyPathConnectedSpace`: quotients of locally path-connected spaces are locally path-connected. -* `Sum.locPathConnectedSpace` / `Sigma.locPathConnectedSpace`: disjoint unions of locally +* `Sum.locallyPathConnectedSpace` / `Sigma.locallyPathConnectedSpace`: disjoint unions of locally path-connected spaces are locally path-connected. Abstractly, this also shows that locally path-connected spaces form a coreflective subcategory of @@ -35,7 +35,7 @@ the category of topological spaces, although we do not prove that in this form h ## Implementation notes -In the definition of `LocPathConnectedSpace X` we require neighbourhoods in the basis to be +In the definition of `LocallyPathConnectedSpace X` we require neighbourhoods in the basis to be path-connected, but not necessarily open; that they can also be required to be open is shown as a theorem in `isOpen_isPathConnected_basis`. -/ @@ -48,26 +48,34 @@ open Topology Filter unitInterval Set Function variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] {x y z : X} {ι : Type*} {F : Set X} -section LocPathConnectedSpace +section LocallyPathConnectedSpace /-- A topological space is locally path connected if, at every point, path connected neighborhoods form a neighborhood basis. -/ -class LocPathConnectedSpace (X : Type*) [TopologicalSpace X] : Prop where +class LocallyPathConnectedSpace (X : Type*) [TopologicalSpace X] : Prop where /-- Each neighborhood filter has a basis of path-connected neighborhoods. -/ path_connected_basis : ∀ x : X, (𝓝 x).HasBasis (fun s : Set X => s ∈ 𝓝 x ∧ IsPathConnected s) id -export LocPathConnectedSpace (path_connected_basis) +@[deprecated (since := "2026-06-21")] alias LocPathConnectedSpace := LocallyPathConnectedSpace +@[deprecated (since := "2026-06-21")] +alias LocPathConnectedSpace.path_connected_basis := + LocallyPathConnectedSpace.path_connected_basis -theorem LocPathConnectedSpace.of_bases {p : X → ι → Prop} {s : X → ι → Set X} +export LocallyPathConnectedSpace (path_connected_basis) + +theorem LocallyPathConnectedSpace.of_bases {p : X → ι → Prop} {s : X → ι → Set X} (h : ∀ x, (𝓝 x).HasBasis (p x) (s x)) (h' : ∀ x i, p x i → IsPathConnected (s x i)) : - LocPathConnectedSpace X where + LocallyPathConnectedSpace X where path_connected_basis x := by rw [hasBasis_self] intro t ht rcases (h x).mem_iff.mp ht with ⟨i, hpi, hi⟩ exact ⟨s x i, (h x).mem_of_mem hpi, h' x i hpi, hi⟩ -variable [LocPathConnectedSpace X] +@[deprecated (since := "2026-06-21")] +alias LocPathConnectedSpace.of_bases := LocallyPathConnectedSpace.of_bases + +variable [LocallyPathConnectedSpace X] protected theorem IsOpen.pathComponentIn (hF : IsOpen F) (x : X) : IsOpen (pathComponentIn F x) := by @@ -99,11 +107,14 @@ lemma pathComponentIn_mem_nhds (hF : F ∈ 𝓝 x) : pathComponentIn F x ∈ exact mem_nhds_iff.mpr ⟨pathComponentIn u x, pathComponentIn_mono huF, hu.pathComponentIn x, mem_pathComponentIn_self hxu⟩ -theorem PathConnectedSpace.of_locPathConnectedSpace [ConnectedSpace X] : PathConnectedSpace X := +theorem PathConnectedSpace.of_locallyPathConnectedSpace [ConnectedSpace X] : PathConnectedSpace X := ⟨inferInstance, by simp [← mem_pathComponent_iff, IsClopen.pathComponent _ |>.eq_univ]⟩ +@[deprecated (since := "2026-06-21")] +alias PathConnectedSpace.of_locPathConnectedSpace := PathConnectedSpace.of_locallyPathConnectedSpace + theorem pathConnectedSpace_iff_connectedSpace : PathConnectedSpace X ↔ ConnectedSpace X := - ⟨fun _ ↦ inferInstance, fun _ ↦ .of_locPathConnectedSpace⟩ + ⟨fun _ ↦ inferInstance, fun _ ↦ .of_locallyPathConnectedSpace⟩ theorem pathComponent_eq_connectedComponent (x : X) : pathComponent x = connectedComponent x := (pathComponent_subset_component x).antisymm <| @@ -149,21 +160,28 @@ theorem isOpen_isPathConnected_basis (x : X) : exact ⟨pathComponentIn u x, ⟨hu.pathComponentIn _, ⟨mem_pathComponentIn_self hxu, isPathConnected_pathComponentIn hxu⟩⟩, pathComponentIn_subset.trans hus⟩ -theorem Topology.IsOpenEmbedding.locPathConnectedSpace {e : Y → X} (he : IsOpenEmbedding e) : - LocPathConnectedSpace Y := +theorem Topology.IsOpenEmbedding.locallyPathConnectedSpace {e : Y → X} (he : IsOpenEmbedding e) : + LocallyPathConnectedSpace Y := have (y : Y) : (𝓝 y).HasBasis (fun s ↦ s ∈ 𝓝 (e y) ∧ IsPathConnected s ∧ s ⊆ range e) (e ⁻¹' ·) := he.basis_nhds <| pathConnected_subset_basis he.isOpen_range (mem_range_self _) .of_bases this fun x s ⟨_, hs, hse⟩ ↦ by rwa [he.isPathConnected_iff, image_preimage_eq_of_subset hse] -theorem IsOpen.locPathConnectedSpace {U : Set X} (h : IsOpen U) : LocPathConnectedSpace U := - h.isOpenEmbedding_subtypeVal.locPathConnectedSpace +@[deprecated (since := "2026-06-21")] +alias Topology.IsOpenEmbedding.locPathConnectedSpace := + Topology.IsOpenEmbedding.locallyPathConnectedSpace + +theorem IsOpen.locallyPathConnectedSpace {U : Set X} (h : IsOpen U) : LocallyPathConnectedSpace U := + h.isOpenEmbedding_subtypeVal.locallyPathConnectedSpace + +@[deprecated (since := "2026-06-21")] +alias IsOpen.locPathConnectedSpace := IsOpen.locallyPathConnectedSpace theorem IsOpen.isConnected_iff_isPathConnected {U : Set X} (U_op : IsOpen U) : IsConnected U ↔ IsPathConnected U := by rw [isConnected_iff_connectedSpace, isPathConnected_iff_pathConnectedSpace] - haveI := U_op.locPathConnectedSpace + haveI := U_op.locallyPathConnectedSpace exact pathConnectedSpace_iff_connectedSpace.symm /-- Locally path-connected spaces are locally connected. -/ @@ -174,30 +192,38 @@ instance : LocallyConnectedSpace X := by exact ⟨u, ⟨hu, hxu, hu'.isConnected⟩, hus⟩ /-- A space is locally path-connected iff all path components of open subsets are open. -/ -lemma locPathConnectedSpace_iff_isOpen_pathComponentIn {X : Type*} [TopologicalSpace X] : - LocPathConnectedSpace X ↔ ∀ (x : X) (u : Set X), IsOpen u → IsOpen (pathComponentIn u x) := +lemma locallyPathConnectedSpace_iff_isOpen_pathComponentIn {X : Type*} [TopologicalSpace X] : + LocallyPathConnectedSpace X ↔ ∀ (x : X) (u : Set X), IsOpen u → IsOpen (pathComponentIn u x) := ⟨fun _ _ _ hu ↦ hu.pathComponentIn _, fun h ↦ ⟨fun x ↦ ⟨fun s ↦ by refine ⟨fun hs ↦ ?_, fun ⟨_, ht⟩ ↦ Filter.mem_of_superset ht.1.1 ht.2⟩ let ⟨u, hu⟩ := mem_nhds_iff.mp hs exact ⟨pathComponentIn u x, ⟨(h x u hu.2.1).mem_nhds (mem_pathComponentIn_self hu.2.2), isPathConnected_pathComponentIn hu.2.2⟩, pathComponentIn_subset.trans hu.1⟩⟩⟩⟩ +@[deprecated (since := "2026-06-21")] +alias locPathConnectedSpace_iff_isOpen_pathComponentIn := + locallyPathConnectedSpace_iff_isOpen_pathComponentIn + /-- A space is locally path-connected iff all path components of open subsets are neighbourhoods. -/ -lemma locPathConnectedSpace_iff_pathComponentIn_mem_nhds {X : Type*} [TopologicalSpace X] : - LocPathConnectedSpace X ↔ +lemma locallyPathConnectedSpace_iff_pathComponentIn_mem_nhds {X : Type*} [TopologicalSpace X] : + LocallyPathConnectedSpace X ↔ ∀ x : X, ∀ u : Set X, IsOpen u → x ∈ u → pathComponentIn u x ∈ nhds x := by - rw [locPathConnectedSpace_iff_isOpen_pathComponentIn] + rw [locallyPathConnectedSpace_iff_isOpen_pathComponentIn] simp_rw [forall_comm (β := Set X), ← imp_forall_iff] refine forall_congr' fun u ↦ imp_congr_right fun _ ↦ ?_ exact ⟨fun h x hxu ↦ (h x).mem_nhds (mem_pathComponentIn_self hxu), fun h x ↦ isOpen_iff_mem_nhds.mpr fun y hy ↦ pathComponentIn_congr hy ▸ h y <| pathComponentIn_subset hy⟩ +@[deprecated (since := "2026-06-21")] +alias locPathConnectedSpace_iff_pathComponentIn_mem_nhds := + locallyPathConnectedSpace_iff_pathComponentIn_mem_nhds + /-- Any topology coinduced by a locally path-connected topology is locally path-connected. -/ -lemma LocPathConnectedSpace.coinduced {Y : Type*} (f : X → Y) : - @LocPathConnectedSpace Y (.coinduced f ‹_›) := by +lemma LocallyPathConnectedSpace.coinduced {Y : Type*} (f : X → Y) : + @LocallyPathConnectedSpace Y (.coinduced f ‹_›) := by let _ := TopologicalSpace.coinduced f ‹_›; have hf : Continuous f := continuous_coinduced_rng - refine locPathConnectedSpace_iff_isOpen_pathComponentIn.mpr fun y u hu ↦ + refine locallyPathConnectedSpace_iff_isOpen_pathComponentIn.mpr fun y u hu ↦ isOpen_coinduced.mpr <| isOpen_iff_mem_nhds.mpr fun x hx ↦ ?_ have hx' := preimage_mono pathComponentIn_subset hx refine mem_nhds_iff.mpr ⟨pathComponentIn (f ⁻¹' u) x, ?_, @@ -207,22 +233,37 @@ lemma LocPathConnectedSpace.coinduced {Y : Type*} (f : X → Y) : ⟨x, mem_pathComponentIn_self hx', rfl⟩ <| (image_mono pathComponentIn_subset).trans <| u.image_preimage_subset f +@[deprecated (since := "2026-06-21")] +alias LocPathConnectedSpace.coinduced := LocallyPathConnectedSpace.coinduced + /-- Quotients of locally path-connected spaces are locally path-connected. -/ -lemma Topology.IsQuotientMap.locPathConnectedSpace {f : X → Y} (h : IsQuotientMap f) : - LocPathConnectedSpace Y := - h.isCoinducing.eq_coinduced ▸ LocPathConnectedSpace.coinduced f +lemma Topology.IsQuotientMap.locallyPathConnectedSpace {f : X → Y} (h : IsQuotientMap f) : + LocallyPathConnectedSpace Y := + h.isCoinducing.eq_coinduced ▸ LocallyPathConnectedSpace.coinduced f + +@[deprecated (since := "2026-06-21")] +alias Topology.IsQuotientMap.locPathConnectedSpace := + Topology.IsQuotientMap.locallyPathConnectedSpace /-- Quotients of locally path-connected spaces are locally path-connected. -/ -instance Quot.locPathConnectedSpace {r : X → X → Prop} : LocPathConnectedSpace (Quot r) := - isQuotientMap_quot_mk.locPathConnectedSpace +instance Quot.locallyPathConnectedSpace {r : X → X → Prop} : LocallyPathConnectedSpace (Quot r) := + isQuotientMap_quot_mk.locallyPathConnectedSpace + +@[deprecated (since := "2026-06-21")] +alias Quot.locPathConnectedSpace := Quot.locallyPathConnectedSpace /-- Quotients of locally path-connected spaces are locally path-connected. -/ -instance Quotient.locPathConnectedSpace {s : Setoid X} : LocPathConnectedSpace (Quotient s) := - isQuotientMap_quotient_mk'.locPathConnectedSpace +instance Quotient.locallyPathConnectedSpace {s : Setoid X} : + LocallyPathConnectedSpace (Quotient s) := + isQuotientMap_quotient_mk'.locallyPathConnectedSpace + +@[deprecated (since := "2026-06-21")] +alias Quotient.locPathConnectedSpace := Quotient.locallyPathConnectedSpace /-- Disjoint unions of locally path-connected spaces are locally path-connected. -/ -instance Sum.locPathConnectedSpace [LocPathConnectedSpace Y] : LocPathConnectedSpace (X ⊕ Y) := by - rw [locPathConnectedSpace_iff_pathComponentIn_mem_nhds]; intro x u hu hxu; rw [mem_nhds_iff] +instance Sum.locallyPathConnectedSpace [LocallyPathConnectedSpace Y] : + LocallyPathConnectedSpace (X ⊕ Y) := by + rw [locallyPathConnectedSpace_iff_pathComponentIn_mem_nhds]; intro x u hu hxu; rw [mem_nhds_iff] obtain x | y := x · refine ⟨Sum.inl '' pathComponentIn (Sum.inl ⁻¹' u) x, ?_, ?_, ?_⟩ · apply IsPathConnected.subset_pathComponentIn @@ -239,11 +280,14 @@ instance Sum.locPathConnectedSpace [LocPathConnectedSpace Y] : LocPathConnectedS · exact isOpenMap_inr _ <| (hu.preimage continuous_inr).pathComponentIn _ · exact ⟨y, mem_pathComponentIn_self hxu, rfl⟩ +@[deprecated (since := "2026-06-21")] +alias Sum.locPathConnectedSpace := Sum.locallyPathConnectedSpace + /-- Disjoint unions of locally path-connected spaces are locally path-connected. -/ -instance Sigma.locPathConnectedSpace {X : ι → Type*} - [(i : ι) → TopologicalSpace (X i)] [(i : ι) → LocPathConnectedSpace (X i)] : - LocPathConnectedSpace ((i : ι) × X i) := by - rw [locPathConnectedSpace_iff_pathComponentIn_mem_nhds]; intro x u hu hxu; rw [mem_nhds_iff] +instance Sigma.locallyPathConnectedSpace {X : ι → Type*} + [(i : ι) → TopologicalSpace (X i)] [(i : ι) → LocallyPathConnectedSpace (X i)] : + LocallyPathConnectedSpace ((i : ι) × X i) := by + rw [locallyPathConnectedSpace_iff_pathComponentIn_mem_nhds]; intro x u hu hxu; rw [mem_nhds_iff] refine ⟨(Sigma.mk x.1) '' pathComponentIn ((Sigma.mk x.1) ⁻¹' u) x.2, ?_, ?_, ?_⟩ · apply IsPathConnected.subset_pathComponentIn · exact (isPathConnected_pathComponentIn (by exact hxu)).image continuous_sigmaMk @@ -252,9 +296,12 @@ instance Sigma.locPathConnectedSpace {X : ι → Type*} · exact isOpenMap_sigmaMk _ <| (hu.preimage continuous_sigmaMk).pathComponentIn _ · exact ⟨x.2, mem_pathComponentIn_self hxu, rfl⟩ -instance AlexandrovDiscrete.locPathConnectedSpace [AlexandrovDiscrete X] : - LocPathConnectedSpace X := by - apply LocPathConnectedSpace.of_bases nhds_basis_nhdsKer_singleton +@[deprecated (since := "2026-06-21")] +alias Sigma.locPathConnectedSpace := Sigma.locallyPathConnectedSpace + +instance AlexandrovDiscrete.locallyPathConnectedSpace [AlexandrovDiscrete X] : + LocallyPathConnectedSpace X := by + apply LocallyPathConnectedSpace.of_bases nhds_basis_nhdsKer_singleton simp only [forall_const, IsPathConnected, mem_nhdsKer_singleton] intro x exists x, specializes_rfl @@ -262,6 +309,9 @@ instance AlexandrovDiscrete.locPathConnectedSpace [AlexandrovDiscrete X] : symm apply hy.joinedIn <;> rewrite [mem_nhdsKer_singleton] <;> [assumption; rfl] +@[deprecated (since := "2026-06-21")] +alias AlexandrovDiscrete.locPathConnectedSpace := AlexandrovDiscrete.locallyPathConnectedSpace + /-- If a space is locally path-connected, the topology of its path components is discrete. -/ instance : DiscreteTopology <| ZerothHomotopy X := by refine discreteTopology_iff_isOpen_singleton.mpr fun c ↦ ?_ @@ -273,4 +323,4 @@ instance : DiscreteTopology <| ZerothHomotopy X := by instance [CompactSpace X] : Finite <| ZerothHomotopy X := finite_of_compact_of_discrete -end LocPathConnectedSpace +end LocallyPathConnectedSpace diff --git a/Mathlib/Topology/Connected/PathComponentOne.lean b/Mathlib/Topology/Connected/PathComponentOne.lean index c992c88d39b2aa..862803a9493bf8 100644 --- a/Mathlib/Topology/Connected/PathComponentOne.lean +++ b/Mathlib/Topology/Connected/PathComponentOne.lean @@ -6,7 +6,7 @@ Authors: Jireh Loreaux module public import Mathlib.Topology.Algebra.OpenSubgroup -public import Mathlib.Topology.Connected.LocPathConnected +public import Mathlib.Topology.Connected.LocallyPathConnected /-! # The path component of the identity in a locally path connected topological group @@ -27,7 +27,7 @@ as an open normal subgroup. It is, in fact, clopen. -/ /-- The path component of the identity in a locally path connected additive topological group, as an open normal additive subgroup. It is, in fact, clopen. -/] def OpenNormalSubgroup.pathComponentOne [Group G] - [IsTopologicalGroup G] [LocPathConnectedSpace G] : + [IsTopologicalGroup G] [LocallyPathConnectedSpace G] : OpenNormalSubgroup G where toSubgroup := .pathComponentOne G isOpen' := .pathComponent 1 @@ -36,7 +36,7 @@ def OpenNormalSubgroup.pathComponentOne [Group G] namespace OpenNormalSubgroup @[to_additive] -instance [Group G] [IsTopologicalGroup G] [LocPathConnectedSpace G] : +instance [Group G] [IsTopologicalGroup G] [LocallyPathConnectedSpace G] : IsClosed (OpenNormalSubgroup.pathComponentOne G : Set G) := .pathComponent 1 diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index a98ee8d80d3032..7c5fb225dd713b 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -7,7 +7,7 @@ module public import Mathlib.AlgebraicTopology.FundamentalGroupoid.FundamentalGroup public import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected -public import Mathlib.Topology.Connected.LocPathConnected +public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Topology.Covering.Quotient public import Mathlib.Topology.Homotopy.Path public import Mathlib.Topology.UnitInterval @@ -168,7 +168,7 @@ open PathConnectedSpace (somePath) in path `f ∘ γ` in `X` lifts to `E` with endpoint only dependent on the endpoint of `γ` and independent of the path chosen. In this theorem, we require that a specific point `a₀ : A` is lifted to a specific point `e₀ : E` over `a₀`. -/ -theorem existsUnique_continuousMap_lifts [PathConnectedSpace A] [LocPathConnectedSpace A] +theorem existsUnique_continuousMap_lifts [PathConnectedSpace A] [LocallyPathConnectedSpace A] (f : C(A, X)) (a₀ : A) (e₀ : E) (he : p e₀ = f a₀) (ex : ∀ γ : C(I, A), γ 0 = a₀ → ∃ Γ : C(I, E), Γ 0 = e₀ ∧ p ∘ Γ = f.comp γ) (uniq : ∀ γ γ' : C(I, A), ∀ Γ Γ' : C(I, E), γ 0 = a₀ → γ' 0 = a₀ → Γ 0 = e₀ → Γ' 0 = e₀ → @@ -466,7 +466,7 @@ alias injective_path_homotopic_mapFn := injective_path_homotopic_map /-- A continuous map `f` from a simply-connected, locally path-connected space `A` to another space `X` lifts uniquely through a covering map `p : E → X`, after specifying any lift `e₀ : E` of any point `a₀ : A`. -/ -theorem existsUnique_continuousMap_lifts [SimplyConnectedSpace A] [LocPathConnectedSpace A] +theorem existsUnique_continuousMap_lifts [SimplyConnectedSpace A] [LocallyPathConnectedSpace A] (f : C(A, X)) (a₀ : A) (e₀ : E) (he : p e₀ = f a₀) : ∃! F : C(A, E), F a₀ = e₀ ∧ p ∘ F = f := by refine cov.isLocalHomeomorph.existsUnique_continuousMap_lifts f a₀ e₀ he (fun γ γ_0 ↦ ?_) @@ -488,7 +488,7 @@ open FundamentalGroup Path.Homotopic.Quotient in if `f⁎ π₁(A, a₀) ⊆ p⁎ π₁(E, e₀)`. Proposition 1.33 of [hatcher02], known as the lifting criterion. -/ theorem existsUnique_continuousMap_lifts_of_range_le - [PathConnectedSpace A] [LocPathConnectedSpace A] + [PathConnectedSpace A] [LocallyPathConnectedSpace A] {f : C(A, X)} {a₀ : A} {e₀ : E} (he : p e₀ = f a₀) (le : (map f a₀).range ≤ (mapOfEq ⟨p, cov.continuous⟩ he).range) : ∃! F : C(A, E), F a₀ = e₀ ∧ p ∘ F = f := by @@ -525,7 +525,7 @@ Given a point `a₀` in the domain of `f` and a lift `e₀` of `f a₀` along `p there exists a unique lift `F` of `f` along `p` such that `F a₀ = e₀`. -/ theorem IsCoveringMapOn.existsUnique_continuousMap_lifts [SimplyConnectedSpace A] - [LocPathConnectedSpace A] {s : Set X} (cov : IsCoveringMapOn p s) (f : C(A, X)) {a₀ : A} + [LocallyPathConnectedSpace A] {s : Set X} (cov : IsCoveringMapOn p s) (f : C(A, X)) {a₀ : A} {e₀ : E} (he : p e₀ = f a₀) (hs : ∀ a, f a ∈ s) : ∃! F : C(A, E), F a₀ = e₀ ∧ p ∘ F = f := by obtain ⟨f, rfl⟩ : ∃ f' : C(A, s), f = .comp ⟨Subtype.val, by fun_prop⟩ f' := diff --git a/Mathlib/Topology/Homotopy/LocallyContractible.lean b/Mathlib/Topology/Homotopy/LocallyContractible.lean index 746ef1a8a3ea24..1f2349bda7e995 100644 --- a/Mathlib/Topology/Homotopy/LocallyContractible.lean +++ b/Mathlib/Topology/Homotopy/LocallyContractible.lean @@ -7,7 +7,7 @@ module public import Mathlib.Topology.Homotopy.Contractible public import Mathlib.Topology.Homotopy.Basic -public import Mathlib.Topology.Connected.LocPathConnected +public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Topology.Homeomorph.Lemmas /-! @@ -24,7 +24,7 @@ This file defines `LocallyContractibleSpace` and `StronglyLocallyContractibleSpa ## Main results * `StronglyLocallyContractibleSpace.locallyContractible`: SLC implies classical LC -* `instLocPathConnectedSpace`: strongly locally contractible spaces are locally path-connected +* `instLocallyPathConnectedSpace`: strongly locally contractible spaces are locally path-connected * `StronglyLocallyContractibleSpace.of_bases`: a helper to construct strongly locally contractible spaces from a neighborhood basis * `contractible_subset_basis`: basis of contractible neighborhoods contained in an open set @@ -122,7 +122,7 @@ theorem contractible_subset_basis {U : Set X} (h : IsOpen U) (hx : x ∈ U) : (contractible_basis x).hasBasis_self_subset (IsOpen.mem_nhds h hx) /-- Strongly locally contractible spaces are locally path-connected. -/ -instance (priority := 100) instLocPathConnectedSpace : LocPathConnectedSpace X where +instance (priority := 100) instLocallyPathConnectedSpace : LocallyPathConnectedSpace X where path_connected_basis x := by refine contractible_basis x |>.to_hasBasis' (fun s ⟨hs, hs'⟩ ↦ ⟨s, ⟨hs, ?_⟩, le_rfl⟩) (fun s hs ↦ hs.1) From 01a1a1f08b533c13dc48e1b5d2b9b05a2bf56c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hagb=20=28Junyu=20Guo=20=E9=83=AD=E4=BF=8A=E4=BD=99=29?= Date: Sun, 21 Jun 2026 19:15:34 +0000 Subject: [PATCH 0221/1300] chore(Order/Preorder/Finite): use `@[to_dual]` on lemmas about `{Min,Max}imal{For,}` (#39547) Proofs of other theorems (e.g. in #39427) with dual theorems dependent on these lemmas would benefit from their duality. --- Mathlib/Order/Preorder/Finite.lean | 36 +++++++++--------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/Mathlib/Order/Preorder/Finite.lean b/Mathlib/Order/Preorder/Finite.lean index 24e16fe9ffe9e6..c64ac316b4bd62 100644 --- a/Mathlib/Order/Preorder/Finite.lean +++ b/Mathlib/Order/Preorder/Finite.lean @@ -23,6 +23,7 @@ namespace Finset section IsTrans variable [LE α] [IsTrans α LE.le] {s : Finset α} {a : α} +@[to_dual] lemma exists_maximalFor (f : ι → α) (s : Finset ι) (hs : s.Nonempty) : ∃ i, MaximalFor (· ∈ s) f i := by induction hs using Finset.Nonempty.cons_induction with @@ -35,26 +36,21 @@ lemma exists_maximalFor (f : ι → α) (s : Finset ι) (hs : s.Nonempty) : exact fun k hk hik ↦ _root_.trans (hj.2 hk <| _root_.trans hji hik) hji · exact ⟨j, mem_cons_of_mem hj.1, by simpa [hji] using hj.2⟩ -lemma exists_minimalFor (f : ι → α) (s : Finset ι) (hs : s.Nonempty) : - ∃ i, MinimalFor (· ∈ s) f i := exists_maximalFor (α := αᵒᵈ) f s hs - +@[to_dual] lemma exists_maximal (hs : s.Nonempty) : ∃ i, Maximal (· ∈ s) i := s.exists_maximalFor id hs -lemma exists_minimal (hs : s.Nonempty) : ∃ i, Minimal (· ∈ s) i := s.exists_minimalFor id hs end IsTrans section Preorder variable [Preorder α] {s : Finset α} {a : α} +@[to_dual] lemma exists_le_maximal (s : Finset α) (ha : a ∈ s) : ∃ b, a ≤ b ∧ Maximal (· ∈ s) b := by classical obtain ⟨b, hb, hab, hbmin⟩ : ∃ b ∈ s, a ≤ b ∧ _ := by simpa [Maximal, and_assoc] using {x ∈ s | a ≤ x}.exists_maximal ⟨a, mem_filter.2 ⟨ha, le_rfl⟩⟩ exact ⟨b, hab, hb, fun c hc hbc ↦ hbmin hc (hab.trans hbc) hbc⟩ -lemma exists_le_minimal (s : Finset α) (ha : a ∈ s) : ∃ b ≤ a, Minimal (· ∈ s) b := - exists_le_maximal (α := αᵒᵈ) s ha - end Preorder end Finset @@ -62,42 +58,33 @@ namespace Set section IsTrans variable [LE α] [IsTrans α LE.le] {s : Set α} {a : α} +@[to_dual] lemma Finite.exists_maximalFor (f : ι → α) (s : Set ι) (h : s.Finite) (hs : s.Nonempty) : ∃ i, MaximalFor (· ∈ s) f i := by lift s to Finset ι using h; exact s.exists_maximalFor f hs -lemma Finite.exists_minimalFor (f : ι → α) (s : Set ι) (h : s.Finite) (hs : s.Nonempty) : - ∃ i, MinimalFor (· ∈ s) f i := Finite.exists_maximalFor (α := αᵒᵈ) f s h hs - +@[to_dual] lemma Finite.exists_maximal (h : s.Finite) (hs : s.Nonempty) : ∃ i, Maximal (· ∈ s) i := h.exists_maximalFor id _ hs -lemma Finite.exists_minimal (h : s.Finite) (hs : s.Nonempty) : ∃ i, Minimal (· ∈ s) i := - h.exists_minimalFor id _ hs - /-- A version of `Finite.exists_maximalFor` with the (weaker) hypothesis that the image of `s` is finite rather than `s` itself. -/ +@[to_dual /- A version of `Finite.exists_minimalFor` with the (weaker) hypothesis that the image of +`s` is finite rather than `s` itself.-/] lemma Finite.exists_maximalFor' (f : ι → α) (s : Set ι) (h : (f '' s).Finite) (hs : s.Nonempty) : ∃ i, MaximalFor (· ∈ s) f i := by obtain ⟨_, ⟨a, ha, rfl⟩, hmax⟩ := Finite.exists_maximalFor id (f '' s) h (hs.image f) exact ⟨a, ha, fun a' ha' hf ↦ hmax (mem_image_of_mem f ha') hf⟩ -/-- A version of `Finite.exists_minimalFor` with the (weaker) hypothesis that the image of `s` -is finite rather than `s` itself. -/ -lemma Finite.exists_minimalFor' (f : ι → α) (s : Set ι) (h : (f '' s).Finite) (hs : s.Nonempty) : - ∃ i, MinimalFor (· ∈ s) f i := h.exists_maximalFor' (α := αᵒᵈ) f s hs - end IsTrans section Preorder variable [Preorder α] {s : Set α} {a : α} +@[to_dual] lemma Finite.exists_le_maximal (hs : s.Finite) (ha : a ∈ s) : ∃ b, a ≤ b ∧ Maximal (· ∈ s) b := by lift s to Finset α using hs; exact s.exists_le_maximal ha -lemma Finite.exists_le_minimal (hs : s.Finite) (ha : a ∈ s) : ∃ b, b ≤ a ∧ Minimal (· ∈ s) b := by - lift s to Finset α using hs; exact s.exists_le_minimal ha - variable [Nonempty α] lemma infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite := by @@ -107,6 +94,7 @@ lemma infinite_of_forall_exists_gt (h : ∀ a, ∃ b ∈ s, a < b) : s.Infinite exact infinite_of_injective_forall_mem (strictMono_nat_of_lt_succ fun n => (h _).choose_spec.2).injective hf +@[to_dual existing infinite_of_forall_exists_gt] lemma infinite_of_forall_exists_lt (h : ∀ a, ∃ b ∈ s, b < a) : s.Infinite := infinite_of_forall_exists_gt (α := αᵒᵈ) h @@ -115,8 +103,8 @@ end Preorder section PartialOrder variable (α) [PartialOrder α] +@[to_dual] lemma finite_isTop : {a : α | IsTop a}.Finite := (subsingleton_isTop α).finite -lemma finite_isBot : {a : α | IsBot a}.Finite := (subsingleton_isBot α).finite end PartialOrder @@ -152,10 +140,8 @@ end Set section Preorder variable [Preorder α] [Finite α] {p : α → Prop} {a : α} +@[to_dual] lemma Finite.exists_le_maximal (h : p a) : ∃ b, a ≤ b ∧ Maximal p b := {x | p x}.toFinite.exists_le_maximal h -lemma Finite.exists_le_minimal (h : p a) : ∃ b ≤ a, Minimal p b := - {x | p x}.toFinite.exists_le_minimal h - end Preorder From 7516f8d0247fb957ef0918ef5a5f8b717e9d5eb1 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Sun, 21 Jun 2026 19:56:22 +0000 Subject: [PATCH 0222/1300] chore: fix duplicated lemma (#40870) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported on Zulip at [#mathlib4 > Redundant copy of `intervalIntegrable_const` @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Redundant.20copy.20of.20.60intervalIntegrable_const.60/near/605394633) Co-authored-by: sgouezel --- Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean | 3 --- Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean | 5 ++--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean index 0dc992510e3b42..e77c76e334d3e1 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean @@ -187,9 +187,6 @@ theorem integrableOn_Ioo_cpow_iff {s : ℂ} {t : ℝ} (ht : 0 < t) : theorem intervalIntegrable_id : IntervalIntegrable (fun x => x) μ a b := continuous_id.intervalIntegrable a b -theorem intervalIntegrable_const : IntervalIntegrable (fun _ => c) μ a b := - continuous_const.intervalIntegrable a b - theorem intervalIntegrable_one_div (h : ∀ x : ℝ, x ∈ [[a, b]] → f x ≠ 0) (hf : ContinuousOn f [[a, b]]) : IntervalIntegrable (fun x => 1 / f x) μ a b := (continuousOn_const.div hf h).intervalIntegrable diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean index 94ce88fa5001e0..f0b1203c751e17 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean @@ -171,10 +171,9 @@ theorem intervalIntegrable_const_iff {c : ε} (hc : ‖c‖ₑ ≠ ⊤ := by fin simp [intervalIntegrable_iff, integrableOn_const_iff hc] @[simp] -theorem intervalIntegrable_const [IsLocallyFiniteMeasure μ] - {c : E} (hc : ‖c‖ₑ ≠ ⊤ := by finiteness) : +theorem intervalIntegrable_const [IsLocallyFiniteMeasure μ] {c : E} : IntervalIntegrable (fun _ => c) μ a b := - intervalIntegrable_const_iff hc |>.2 <| Or.inr measure_Ioc_lt_top + intervalIntegrable_const_iff (by simp) |>.2 <| Or.inr measure_Ioc_lt_top protected theorem IntervalIntegrable.zero : IntervalIntegrable (0 : ℝ → E) μ a b := (intervalIntegrable_const_iff <| by finiteness).mpr <| .inl rfl From 7a1a9e0449fdf4adcb4e44e4be9552565228dc19 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:14:44 +0000 Subject: [PATCH 0223/1300] perf(Algebra/Algebra/Equiv): mark `coe_ringEquiv` with `defeq` again (#40873) This PR reverts the proof of `coe_ringEquiv` back to `:= rfl` after #40834, which apparently is necessary for performance reasons. --- Mathlib/Algebra/Algebra/Equiv.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index d3a116e40011be..5fad57bfc7b9b8 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -160,7 +160,7 @@ theorem toRingEquiv_eq_coe : e.toRingEquiv = e := lemma toRingEquiv_toRingHom : ((e : A₁ ≃+* A₂) : A₁ →+* A₂) = e := rfl -theorem coe_ringEquiv : ((e : A₁ ≃+* A₂) : A₁ → A₂) = e := by simp +theorem coe_ringEquiv : ((e : A₁ ≃+* A₂) : A₁ → A₂) = e := rfl @[deprecated (since := "2026-06-21")] alias coe_ringEquiv' := coe_ringEquiv From 8b068a6bd8a1c28826b167583a7379367052fa13 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:54:04 +0000 Subject: [PATCH 0224/1300] refactor(Order/Basic): move `Pi` & `Prop` orders to a new file (#40658) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the `LE` instances of `Pi` & `Prop` from `Order/Basic.lean` to a new `Order/Defs/Prop.lean`. This lets `Logic/Relation.lean` import them so that it can use `≤` between relations. --- Mathlib.lean | 1 + Mathlib/Order/Basic.lean | 18 +----------------- Mathlib/Order/Defs/Prop.lean | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 Mathlib/Order/Defs/Prop.lean diff --git a/Mathlib.lean b/Mathlib.lean index 92e3cf81853411..49a4130a24ce7c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5979,6 +5979,7 @@ public import Mathlib.Order.CountableSupClosed public import Mathlib.Order.Cover public import Mathlib.Order.Defs.LinearOrder public import Mathlib.Order.Defs.PartialOrder +public import Mathlib.Order.Defs.Prop public import Mathlib.Order.Defs.Unbundled public import Mathlib.Order.DirSupClosed public import Mathlib.Order.Directed diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index d03d6ac2f44b9d..24ba1c2d27cb80 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.Subtype public import Mathlib.Order.Defs.LinearOrder +public import Mathlib.Order.Defs.Prop public import Mathlib.Order.Notation public import Mathlib.Tactic.Spread public import Mathlib.Tactic.Convert @@ -549,15 +550,6 @@ instance Ne.instIsEquiv_compl : IsEquiv α (· ≠ ·)ᶜ := by /-! ### Order instances on the function space -/ - -instance Pi.hasLe [∀ i, LE (π i)] : - LE (∀ i, π i) where le x y := ∀ i, x i ≤ y i - -@[to_dual self] -theorem Pi.le_def [∀ i, LE (π i)] {x y : ∀ i, π i} : - x ≤ y ↔ ∀ i, x i ≤ y i := - Iff.rfl - instance Pi.preorder [∀ i, Preorder (π i)] : Preorder (∀ i, π i) where __ := (inferInstance : LE (∀ i, π i)) le_refl := fun a i ↦ le_refl (a i) @@ -1098,14 +1090,6 @@ end PUnit section «Prop» -/-- Propositions form a complete Boolean algebra, where the `≤` relation is given by implication. -/ -instance Prop.le : LE Prop := - ⟨(· → ·)⟩ - -@[simp] -theorem le_Prop_eq : ((· ≤ ·) : Prop → Prop → Prop) = (· → ·) := - rfl - theorem subrelation_iff_le {r s : α → α → Prop} : Subrelation r s ↔ r ≤ s := Iff.rfl diff --git a/Mathlib/Order/Defs/Prop.lean b/Mathlib/Order/Defs/Prop.lean new file mode 100644 index 00000000000000..2491ab8634ff70 --- /dev/null +++ b/Mathlib/Order/Defs/Prop.lean @@ -0,0 +1,32 @@ +/- +Copyright (c) 2016 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Yury Kudryashov +-/ +module + +import Mathlib.Tactic.ToDual + +/-! +# Order definitions for propositions + +This file defines orders on `Pi` and `Prop`. +-/ + +public section + +instance Pi.hasLe {ι : Type*} {π : ι → Type*} [∀ i, LE (π i)] : LE (∀ i, π i) where + le x y := ∀ i, x i ≤ y i + +@[to_dual self] +theorem Pi.le_def {ι : Type*} {π : ι → Type*} [∀ i, LE (π i)] {x y : ∀ i, π i} : + x ≤ y ↔ ∀ i, x i ≤ y i := + .rfl + +/-- Propositions form a complete Boolean algebra, where the `≤` relation is given by implication. -/ +instance Prop.le : LE Prop := + ⟨(· → ·)⟩ + +@[simp] +theorem le_Prop_eq : ((· ≤ ·) : Prop → Prop → Prop) = (· → ·) := + rfl From 2ddd05d857dc69b284736cba674786a219737907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Sun, 21 Jun 2026 22:46:15 +0000 Subject: [PATCH 0225/1300] =?UTF-8?q?feat:=20monotone=20function=20`Cardin?= =?UTF-8?q?al=20=E2=86=92=20=CE=B1`=20is=20eventually=20constant=20(#37344?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib.lean | 1 + Mathlib/Logic/Small/Basic.lean | 2 + Mathlib/Order/Preorder/Chain.lean | 17 +++++ .../SetTheory/Cardinal/EventuallyConst.lean | 74 +++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 Mathlib/SetTheory/Cardinal/EventuallyConst.lean diff --git a/Mathlib.lean b/Mathlib.lean index 49a4130a24ce7c..bd78be55936b6e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7106,6 +7106,7 @@ public import Mathlib.SetTheory.Cardinal.Defs public import Mathlib.SetTheory.Cardinal.Divisibility public import Mathlib.SetTheory.Cardinal.ENat public import Mathlib.SetTheory.Cardinal.Embedding +public import Mathlib.SetTheory.Cardinal.EventuallyConst public import Mathlib.SetTheory.Cardinal.Finite public import Mathlib.SetTheory.Cardinal.Finsupp public import Mathlib.SetTheory.Cardinal.Free diff --git a/Mathlib/Logic/Small/Basic.lean b/Mathlib/Logic/Small/Basic.lean index eb7769fbd3a1cc..2f947ce5c2af91 100644 --- a/Mathlib/Logic/Small/Basic.lean +++ b/Mathlib/Logic/Small/Basic.lean @@ -75,3 +75,5 @@ instance small_quot {α : Type u} [Small.{v} α] (r : α → α → Prop) : Smal instance small_quotient {α : Type u} [Small.{v} α] (s : Setoid α) : Small.{v} (Quotient s) := small_of_surjective Quotient.mk_surjective + +instance small_orderDual {α : Type*} [h : Small.{v} α] : Small.{v} αᵒᵈ := h diff --git a/Mathlib/Order/Preorder/Chain.lean b/Mathlib/Order/Preorder/Chain.lean index 62045ef0de9174..ef314eaee043c2 100644 --- a/Mathlib/Order/Preorder/Chain.lean +++ b/Mathlib/Order/Preorder/Chain.lean @@ -119,6 +119,14 @@ theorem Monotone.isChain_range [LinearOrder α] [Preorder β] {f : α → β} (h rw [← image_univ] exact hf.isChain_image (isChain_of_trichotomous _) +lemma Antitone.isChain_image [Preorder α] [Preorder β] {s : Set α} {f : α → β} + (hf : Antitone f) (hs : IsChain (· ≤ ·) s) : IsChain (· ≤ ·) (f '' s) := + hf.dual_left.isChain_image hs.symm + +theorem Antitone.isChain_range [LinearOrder α] [Preorder β] {f : α → β} (hf : Antitone f) : + IsChain (· ≤ ·) (range f) := + hf.dual_left.isChain_range + theorem IsChain.lt_of_le [PartialOrder α] {s : Set α} (h : IsChain (· ≤ ·) s) : IsChain (· < ·) s := fun _a ha _b hb hne ↦ (h ha hb hne).imp hne.lt_of_le hne.lt_of_le' @@ -222,6 +230,15 @@ theorem IsChain.exists3 (hchain : IsChain r s) [IsTrans α r] {a b c} (mem1 : a end Total +/-- A chain in a partial order is a linear order. -/ +@[implicit_reducible] +def IsChain.linearOrder [PartialOrder α] [DecidableLE α] {s : Set α} (hs : IsChain (· ≤ ·) s) : + LinearOrder s where + le_total := by + rintro ⟨a, ha⟩ ⟨b, hb⟩ + exact hs.total ha hb + toDecidableLE x y := inferInstanceAs (Decidable (x.1 ≤ y.1)) + lemma IsChain.le_of_not_gt [Preorder α] (hs : IsChain (· ≤ ·) s) {x y : α} (hx : x ∈ s) (hy : y ∈ s) (h : ¬ x < y) : y ≤ x := by cases hs.total hx hy with diff --git a/Mathlib/SetTheory/Cardinal/EventuallyConst.lean b/Mathlib/SetTheory/Cardinal/EventuallyConst.lean new file mode 100644 index 00000000000000..acdfa09f5982e9 --- /dev/null +++ b/Mathlib/SetTheory/Cardinal/EventuallyConst.lean @@ -0,0 +1,74 @@ +/- +Copyright (c) 2026 Violeta Hernández Palacios. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Violeta Hernández Palacios +-/ +module + +public import Mathlib.Order.Filter.EventuallyConst +public import Mathlib.SetTheory.Cardinal.Aleph + +/-! +# Eventually constant monotone functions + +This file proves variations of the following theorem: if `α` is a linear order and `β` is a partial +order with `#β < cof α`, then any monotone function `f : α → β` must be eventually constant. In +particular, this applies for functions from `Cardinal.{u}` or `Ordinal.{u}` into a `Small.{u}` type. +-/ + +public section + +universe u v + +variable {α : Type u} {β : Type v} [LinearOrder α] [PartialOrder β] + +open Cardinal Filter Order Set + +namespace Filter.EventuallyConst +variable {f : α → β} + +theorem of_not_isCofinal_rangeSplitting [Nonempty α] (hf : Monotone f) + (hf' : ¬ IsCofinal (range (rangeSplitting f))) : atTop.EventuallyConst f := by + rw [eventuallyConst_atTop] + obtain ⟨i, hi⟩ := not_isCofinal_iff.1 hf' + refine ⟨i, fun j hij ↦ (hf hij).antisymm' <| (hf (hi _ ⟨⟨f j, j, rfl⟩, rfl⟩).le).trans' ?_⟩ + rw [apply_rangeSplitting f] + +theorem of_monotone_of_lt_cof (hf : Monotone f) (hα : lift.{u} #β < lift.{v} (cof α)) : + atTop.EventuallyConst f := by + have : Nonempty α := by by_contra!; simp at hα + refine .of_not_isCofinal_rangeSplitting hf ?_ + contrapose! hα + classical let := hf.isChain_range.linearOrder + rw [← lift_cof_congr_of_strictMono (rangeSplitting_strictMono hf) hα, lift_le] + exact (cof_le_cardinalMk _).trans (mk_set_le _) + +theorem of_antitone_of_lt_cof (hf : Antitone f) (hα : lift.{u} #β < lift.{v} (cof α)) : + atTop.EventuallyConst f := + .of_monotone_of_lt_cof (β := βᵒᵈ) hf.dual_right hα + +end Filter.EventuallyConst + +namespace Cardinal +variable {f : Cardinal.{v} → β} [Small.{v} β] + +theorem eventuallyConst_of_monotone (hf : Monotone f) : atTop.EventuallyConst f := by + refine .of_monotone_of_lt_cof hf ?_ + simpa [← small_iff_lift_mk_lt_univ] + +theorem eventuallyConst_of_antitone (hf : Antitone f) : atTop.EventuallyConst f := + eventuallyConst_of_monotone (β := βᵒᵈ) hf + +end Cardinal + +namespace Ordinal +variable {f : Ordinal.{v} → β} [Small.{v} β] + +theorem eventuallyConst_of_monotone (hf : Monotone f) : atTop.EventuallyConst f := by + refine .of_monotone_of_lt_cof hf ?_ + simpa [← small_iff_lift_mk_lt_univ] + +theorem eventuallyConst_of_antitone (hf : Antitone f) : atTop.EventuallyConst f := + eventuallyConst_of_monotone (β := βᵒᵈ) hf + +end Ordinal From 914b89d98d8c61ccbfd8546e1617027bde93e6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Sun, 21 Jun 2026 22:46:17 +0000 Subject: [PATCH 0226/1300] feat: stationary sets (#39727) We define stationary sets as sets intersecting all club sets, and prove basic theorems about them. --- Mathlib/Order/Cofinal.lean | 5 + .../SetTheory/Cardinal/Cofinality/Club.lean | 171 +++++++++++++++--- 2 files changed, 154 insertions(+), 22 deletions(-) diff --git a/Mathlib/Order/Cofinal.lean b/Mathlib/Order/Cofinal.lean index ce94954545c4d6..0eddfbd7bccbca 100644 --- a/Mathlib/Order/Cofinal.lean +++ b/Mathlib/Order/Cofinal.lean @@ -52,6 +52,11 @@ theorem IsCofinal.mono {s t : Set α} (h : s ⊆ t) (hs : IsCofinal s) : IsCofin obtain ⟨b, hb, hb'⟩ := hs a exact ⟨b, h hb, hb'⟩ +theorem IsCofinal.nonempty [Nonempty α] {s : Set α} (h : IsCofinal s) : s.Nonempty := by + inhabit α + obtain ⟨x, hx, _⟩ := h default + exact ⟨x, hx⟩ + end LE section Preorder diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean index f772f2c6ae1fb6..852a93cbe709b4 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean @@ -10,11 +10,13 @@ public import Mathlib.Order.IsNormal public import Mathlib.SetTheory.Cardinal.Cofinality.Basic /-! -# Club sets +# Club sets and stationary sets -A subset of a well-ordered type `α` is called a club set when it is closed in the order topology and -cofinal. If `α` has no maximum, then an equivalent condition is that `α` is closed and unbounded; -hence the name. +A subset of a well-ordered type `α` is called a **club set** when it is closed in the order topology +and cofinal. If `α` has no maximum, then an equivalent condition is that `α` is closed and +unbounded; hence the name. + +A **stationary set** is a set which intersects all club sets. ## Implementation notes @@ -27,7 +29,9 @@ public section universe u v -open Cardinal Order +open Cardinal Order Set + +variable {α : Type v} {s t : Set α} {x : α} [LinearOrder α] /-- A club set is closed under suprema and cofinal. -/ structure IsClub {α : Type*} [LinearOrder α] (s : Set α) where @@ -40,8 +44,6 @@ structure IsClub {α : Type*} [LinearOrder α] (s : Set α) where namespace IsClub -variable {α : Type v} {s t : Set α} {x : α} [LinearOrder α] - @[simp] theorem of_isEmpty [IsEmpty α] {s : Set α} : IsClub s := ⟨.of_isEmpty, .of_isEmpty⟩ @@ -50,6 +52,12 @@ theorem of_isEmpty [IsEmpty α] {s : Set α} : IsClub s := protected theorem univ : IsClub (α := α) .univ := ⟨.univ, .univ⟩ +protected theorem nonempty [Nonempty α] (hs : IsClub s) : s.Nonempty := + hs.isCofinal.nonempty + +theorem _root_.isClub_empty_iff : IsClub (α := α) ∅ ↔ IsEmpty α := + ⟨fun h ↦ isCofinal_empty_iff.1 h.isCofinal, fun _ ↦ .of_isEmpty⟩ + protected theorem union (hs : IsClub s) (ht : IsClub t) : IsClub (s ∪ t) := ⟨hs.dirSupClosed.union ht.dirSupClosed, hs.isCofinal.mono Set.subset_union_left⟩ @@ -63,12 +71,12 @@ theorem csSup_mem {α} [ConditionallyCompleteLinearOrder α] {s t : Set α} theorem sInter_of_orderTop {s : Set (Set α)} [OrderTop α] (hs : ∀ x ∈ s, IsClub x) : IsClub (⋂₀ s) := by refine ⟨.sInter fun x hx ↦ (hs x hx).dirSupClosed, ?_⟩ - rw [isCofinal_iff_top_mem, Set.mem_sInter] + rw [isCofinal_iff_top_mem, mem_sInter] exact fun x hx ↦ (hs x hx).isCofinal.top_mem theorem iInter_of_orderTop {ι : Type*} {f : ι → Set α} [OrderTop α] (hs : ∀ i, IsClub (f i)) : IsClub (⋂ i, f i) := by - rw [← Set.sInter_range] + rw [← sInter_range] exact .sInter_of_orderTop (by simpa) theorem sInter_of_cof_le_one {s : Set (Set α)} (hα : cof α ≤ 1) (hs : ∀ x ∈ s, IsClub x) : @@ -80,11 +88,10 @@ theorem sInter_of_cof_le_one {s : Set (Set α)} (hα : cof α ≤ 1) (hs : ∀ x theorem iInter_of_cof_le_one {ι : Type*} {f : ι → Set α} (hα : cof α ≤ 1) (hs : ∀ i, IsClub (f i)) : IsClub (⋂ i, f i) := by - rw [← Set.sInter_range] + rw [← sInter_range] exact .sInter_of_cof_le_one hα (by simpa) section WellFoundedLT - variable [WellFoundedLT α] attribute [local instance] @@ -102,7 +109,7 @@ protected theorem sInter {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : #s refine .of_not_isCofinal fun hg ↦ (cof_le hg).not_gt (hα.trans_le' ?_) simpa using mk_range_le_lift (f := g) refine ⟨_, fun t ht ↦ ?_, le_csSup hg ⟨0, rfl⟩⟩ - apply (hs t ht).isLUB_mem (t := .range fun n ↦ f ⟨t, ht⟩ (g n)) _ (Set.range_nonempty _) + apply (hs t ht).isLUB_mem (t := .range fun n ↦ f ⟨t, ht⟩ (g n)) _ (range_nonempty _) · refine ⟨?_, fun b hb ↦ csSup_le' ?_⟩ <;> rintro _ ⟨n, rfl⟩ · apply (le_csSup (.of_not_isCofinal _) _).trans (le_csSup hg ⟨n + 1, rfl⟩) · exact fun hg' ↦ (cof_le hg').not_gt (mk_range_le.trans_lt hsα) @@ -113,19 +120,27 @@ protected theorem sInter {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : #s protected theorem iInter {ι : Type u} {f : ι → Set α} (hα : cof α ≠ ℵ₀) (hι : Cardinal.lift.{v} #ι < Cardinal.lift.{u} (cof α)) (hf : ∀ i, IsClub (f i)) : IsClub (⋂ i, f i) := by - rw [← Set.sInter_range] + rw [← sInter_range] refine IsClub.sInter hα ?_ (by simpa) rw [← Cardinal.lift_lt] exact mk_range_le_lift.trans_lt hι -protected theorem inter {s t : Set α} (hα : cof α ≠ ℵ₀) (hs : IsClub s) (ht : IsClub t) : - IsClub (s ∩ t) := by - rw [← Set.sInter_pair] - have H : ∀ x ∈ ({s, t} : Set _), IsClub x := by simpa [hs] - obtain hα | hα' := hα.lt_or_gt - · rw [cof_lt_aleph0_iff] at hα - exact .sInter_of_cof_le_one hα H - · exact .sInter hα (hα'.trans_le' <| by simp) H +theorem sInter_of_countable {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : s.Countable) + (hs : ∀ x ∈ s, IsClub x) : IsClub (⋂₀ s) := by + obtain hα | hα := hα.lt_or_gt + · apply IsClub.sInter_of_cof_le_one _ hs + rwa [← cof_lt_aleph0_iff] + · apply IsClub.sInter hα.ne' (hα.trans_le' _) hs + rwa [le_aleph0_iff_set_countable] + +theorem iInter_of_countable {ι : Sort*} {f : ι → Set α} [Countable ι] (hα : cof α ≠ ℵ₀) + (hf : ∀ i, IsClub (f i)) : IsClub (⋂ i, f i) := by + rw [← sInter_range] + apply IsClub.sInter_of_countable hα (countable_range f) + simpa + +protected theorem inter (hα : cof α ≠ ℵ₀) (hs : IsClub s) (ht : IsClub t) : IsClub (s ∩ t) := by + simpa [hs, ht] using IsClub.sInter_of_countable (s := {s, t}) hα theorem _root_.Order.IsNormal.isClub_range {f : α → α} (hf : IsNormal f) : IsClub (.range f) := ⟨hf.dirSupClosed_range, fun x ↦ ⟨_, ⟨x, rfl⟩, hf.strictMono.le_apply⟩⟩ @@ -134,7 +149,7 @@ theorem _root_.Order.IsNormal.isClub_fixedPoints {f : α → α} (hα : cof α IsClub f.fixedPoints := by cases isEmpty_or_nonempty α; · simp refine ⟨fun s hs hs₀ _ a ha ↦ (hf.map_isLUB ha hs₀).unique ?_, fun a ↦ ?_⟩ - · rwa [Set.image_congr hs, Set.image_id'] + · rwa [image_congr hs, image_id'] · cases topOrderOrNoTopOrder α with | inl => use ⊤; simpa using! hf.strictMono.id_le ⊤ | inr h => @@ -147,3 +162,115 @@ theorem _root_.Order.IsNormal.isClub_fixedPoints {f : α → α} (hα : cof α end WellFoundedLT end IsClub + +/-! ### Stationary sets -/ + +/-- A set is called stationary when it intersects all club sets. -/ +@[expose] +def IsStationary (s : Set α) : Prop := + ∀ ⦃t⦄, IsClub t → (s ∩ t).Nonempty + +theorem not_isStationary_iff : ¬ IsStationary s ↔ ∃ t, IsClub t ∧ Disjoint s t := by + simp [IsStationary, disjoint_iff, not_nonempty_iff_eq_empty] + +@[gcongr] +theorem IsStationary.mono (hs : IsStationary s) (h : s ⊆ t) : IsStationary t := + fun _u hu ↦ (hs hu).mono (inter_subset_inter_left _ h) + +theorem IsStationary.nonempty (hs : IsStationary s) : s.Nonempty := by + simpa using hs .univ + +theorem isStationary_univ_iff : IsStationary (.univ (α := α)) ↔ Nonempty α := by + simp [IsStationary, ← not_imp_not (b := IsClub _), not_nonempty_iff_eq_empty, + isClub_empty_iff] + +@[simp] +protected theorem IsStationary.univ [Nonempty α] : IsStationary (.univ (α := α)) := + isStationary_univ_iff.2 ‹_› + +@[simp] +theorem not_isStationary_empty : ¬ IsStationary (∅ : Set α) := by + intro h + simpa using h .univ + +@[simp] +theorem not_isStationary_of_isEmpty [IsEmpty α] : ¬ IsStationary s := + s.eq_empty_of_isEmpty ▸ not_isStationary_empty + +theorem IsStationary.of_not_isCofinal_compl (hs : ¬ IsCofinal sᶜ) : IsStationary s := by + intro t ht + obtain ⟨a, ha⟩ := not_isCofinal_iff.1 hs + obtain ⟨b, hb, hb'⟩ := ht.isCofinal a + refine ⟨b, ?_, hb⟩ + contrapose! ha + exact ⟨b, ha, hb'⟩ + +theorem isStationary_sUnion_iff_of_cof_le_one {s : Set (Set α)} (hα : cof α ≤ 1) : + IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x where + mp h := by + contrapose! h + simp_rw [not_isStationary_iff] at h ⊢ + choose f hf hxf using h + refine ⟨⋂ x : s, f _ x.2, ?_, ?_⟩ + · apply IsClub.iInter_of_cof_le_one hα + simpa + · rw [disjoint_sUnion_left] + exact fun x hx ↦ (hxf _ hx).mono_right (iInter_subset _ ⟨x, hx⟩) + mpr := fun ⟨x, hxs, hx⟩ ↦ hx.mono (subset_sUnion_of_mem hxs) + +theorem isStationary_iUnion_iff_of_cof_le_one {ι : Sort*} {f : ι → Set α} (hα : cof α ≤ 1) : + IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := by + rw [← sUnion_range, isStationary_sUnion_iff_of_cof_le_one hα] + simp + +theorem isStationary_sUnion_iff_of_orderTop [OrderTop α] {s : Set (Set α)} : + IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x := + isStationary_sUnion_iff_of_cof_le_one (by simp) + +theorem isStationary_iUnion_iff_of_orderTop [OrderTop α] {ι : Sort*} {f : ι → Set α} : + IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := + isStationary_iUnion_iff_of_cof_le_one (by simp) + +section WellFoundedLT +variable [WellFoundedLT α] + +theorem IsClub.isStationary [Nonempty α] (hα : cof α ≠ ℵ₀) (hs : IsClub s) : IsStationary s := + fun _ ht ↦ (hs.inter hα ht).nonempty + +theorem isStationary_sUnion_iff {s : Set (Set α)} (hα : cof α ≠ ℵ₀) (hsα : #s < cof α) : + IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x where + mp h := by + contrapose! h + simp_rw [not_isStationary_iff] at h ⊢ + choose f hf hxf using h + refine ⟨⋂ x : s, f _ x.2, ?_, ?_⟩ + · apply IsClub.iInter hα <;> simpa + · rw [disjoint_sUnion_left] + exact fun x hx ↦ (hxf _ hx).mono_right (iInter_subset _ ⟨x, hx⟩) + mpr := fun ⟨x, hxs, hx⟩ ↦ hx.mono (subset_sUnion_of_mem hxs) + +theorem isStationary_iUnion_iff {ι : Type u} {f : ι → Set α} (hα : cof α ≠ ℵ₀) + (hι : lift.{v} #ι < lift.{u} (cof α)) : IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := by + rw [← sUnion_range, isStationary_sUnion_iff hα] + · simp + · rw [← Cardinal.lift_lt] + exact mk_range_le_lift.trans_lt hι + +theorem isStationary_sUnion_iff_of_countable {s : Set (Set α)} (hα : cof α ≠ ℵ₀) + (hsα : s.Countable) : IsStationary (⋃₀ s) ↔ ∃ x ∈ s, IsStationary x := by + obtain hα | hα := hα.lt_or_gt + · apply isStationary_sUnion_iff_of_cof_le_one + rwa [← cof_lt_aleph0_iff] + · apply isStationary_sUnion_iff hα.ne' (hα.trans_le' _) + rwa [le_aleph0_iff_set_countable] + +theorem isStationary_iUnion_iff_of_countable {ι : Sort*} {f : ι → Set α} [Countable ι] + (hα : cof α ≠ ℵ₀) : IsStationary (⋃ i, f i) ↔ ∃ i, IsStationary (f i) := by + rw [← sUnion_range, isStationary_sUnion_iff_of_countable hα (countable_range f)] + simp + +theorem isStationary_union_iff (hα : cof α ≠ ℵ₀) : + IsStationary (s ∪ t) ↔ IsStationary s ∨ IsStationary t := by + simpa using isStationary_sUnion_iff_of_countable (s := {s, t}) hα + +end WellFoundedLT From f0e649cb15423f0afdb2a69a698d0330199518a9 Mon Sep 17 00:00:00 2001 From: "mathlib-nolints[bot]" <258989889+mathlib-nolints[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 01:32:46 +0000 Subject: [PATCH 0227/1300] chore: remove unnecessary set_option lines (#40881) I removed 12 unnecessary `set_option` line(s) across 3 file(s). --- Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean | 1 - Mathlib/LinearAlgebra/Semisimple.lean | 9 --------- .../FieldTheory/IsAlgClosed/AlgebraicClosure.lean | 2 -- 3 files changed, 12 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index 105ba3a560eaad..69443cf0fe5b99 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -1095,7 +1095,6 @@ lemma Scheme.exists_isOpenCover_and_isAffine_of_finite [IsCofiltered I] simp · rw [← hVU, ← Hom.comp_preimage, c.w] -set_option backward.isDefEq.respectTransparency false in open TopologicalSpace in include hc in /-- Suppose `{ Xᵢ }` is an inverse system of qcqs schemes with affine transition maps. diff --git a/Mathlib/LinearAlgebra/Semisimple.lean b/Mathlib/LinearAlgebra/Semisimple.lean index b1866db02932fd..6109d9ea4dda88 100644 --- a/Mathlib/LinearAlgebra/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Semisimple.lean @@ -55,7 +55,6 @@ section CommRing variable (f : End R M) -set_option backward.isDefEq.respectTransparency false in /-- A linear endomorphism of an `R`-module `M` is called *semisimple* if the induced `R[X]`-module structure on `M` is semisimple. This is equivalent to saying that every `f`-invariant `R`-submodule of `M` has an `f`-invariant complement: see `Module.End.isSemisimple_iff`. -/ @@ -68,7 +67,6 @@ def IsFinitelySemisimple : Prop := variable {f} -set_option backward.isDefEq.respectTransparency false in /-- A linear endomorphism is semisimple if every invariant submodule has in invariant complement. See also `Module.End.isSemisimple_iff`. -/ @@ -82,7 +80,6 @@ lemma isSemisimple_iff : f.IsSemisimple ↔ ∀ p ∈ invtSubmodule f, ∃ q ∈ invtSubmodule f, IsCompl p q := by simp [isSemisimple_iff'] -set_option backward.isDefEq.respectTransparency false in lemma isSemisimple_restrict_iff (p) (hp : p ∈ invtSubmodule f) : IsSemisimple (LinearMap.restrict f hp) ↔ ∀ q ∈ f.invtSubmodule, q ≤ p → ∃ r ≤ p, r ∈ f.invtSubmodule ∧ Disjoint q r ∧ q ⊔ r = p := by @@ -122,7 +119,6 @@ lemma isSemisimple_id [IsSemisimpleModule R M] : IsSemisimple (LinearMap.id : Mo @[simp] lemma isSemisimple_neg : (-f).IsSemisimple ↔ f.IsSemisimple := by simp [isSemisimple_iff, mem_invtSubmodule] -set_option backward.isDefEq.respectTransparency false in variable (f) in protected lemma _root_.LinearEquiv.isSemisimple_iff {M₂ : Type*} [AddCommGroup M₂] [Module R M₂] (g : End R M₂) (e : M ≃ₗ[R] M₂) (he : e ∘ₗ f = g ∘ₗ e) : @@ -132,7 +128,6 @@ protected lemma _root_.LinearEquiv.isSemisimple_iff {M₂ : Type*} [AddCommGroup simp_rw [IsSemisimple, isSemisimpleModule_iff, (Submodule.orderIsoMapComap e).complementedLattice_iff] -set_option backward.isDefEq.respectTransparency false in lemma eq_zero_of_isNilpotent_isSemisimple (hn : IsNilpotent f) (hs : f.IsSemisimple) : f = 0 := by have ⟨n, h0⟩ := hn rw [← aeval_X (R := R) f]; rw [← aeval_X_pow (R := R) f] at h0 @@ -170,7 +165,6 @@ lemma isSemisimple_sub_algebraMap_iff {μ : R} : refine fun p ↦ ⟨fun h x hx ↦ ?_, fun h x hx ↦ p.sub_mem (h hx) (p.smul_mem μ hx)⟩ simpa using p.add_mem (h hx) (p.smul_mem μ hx) -set_option backward.isDefEq.respectTransparency false in lemma IsSemisimple.restrict {p : Submodule R M} (hp : p ∈ f.invtSubmodule) (hf : f.IsSemisimple) : IsSemisimple (f.restrict hp) := by rw [IsSemisimple] at hf ⊢ @@ -224,7 +218,6 @@ lemma IsSemisimple_smul (t : K) (h : f.IsSemisimple) : wlog ht : t ≠ 0; · simp [not_not.mp ht] rwa [IsSemisimple_smul_iff ht] -set_option backward.isDefEq.respectTransparency false in theorem isSemisimple_of_squarefree_aeval_eq_zero {p : K[X]} (hp : Squarefree p) (hpf : aeval f p = 0) : f.IsSemisimple := by rw [← RingHom.mem_ker, ← AEval.annihilator_eq_ker_aeval (M := M), mem_annihilator, @@ -249,13 +242,11 @@ open Algebra variable (hf : f.IsSemisimple) include hf -set_option backward.isDefEq.respectTransparency false in /-- The minimal polynomial of a semisimple endomorphism is square free -/ theorem IsSemisimple.minpoly_squarefree : Squarefree (minpoly K f) := IsRadical.squarefree (minpoly.ne_zero <| IsIntegral.isIntegral _) <| by rw [isRadical_iff_span_singleton, span_minpoly_eq_annihilator]; exact hf.annihilator_isRadical -set_option backward.isDefEq.respectTransparency false in protected theorem IsSemisimple.aeval (p : K[X]) : (aeval f p).IsSemisimple := let R := K[X] ⧸ Ideal.span {minpoly K f} have : Module.Finite K R := diff --git a/MathlibTest/InstanceDiamonds/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/MathlibTest/InstanceDiamonds/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index c38a1903bf7bc7..f6ea1a241f847d 100644 --- a/MathlibTest/InstanceDiamonds/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/MathlibTest/InstanceDiamonds/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -3,12 +3,10 @@ import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure variable {k : Type*} [Field k] -set_option backward.isDefEq.respectTransparency false in example : (AddCommMonoid.toNatModule : Module ℕ (AlgebraicClosure k)) = @Algebra.toModule _ _ _ _ (AlgebraicClosure.instAlgebra k) := by with_reducible_and_instances rfl -set_option backward.isDefEq.respectTransparency false in example : (AddCommGroup.toIntModule _ : Module ℤ (AlgebraicClosure k)) = @Algebra.toModule _ _ _ _ (AlgebraicClosure.instAlgebra k) := by with_reducible_and_instances rfl From 69aaaa313f441d9ce4fe99f374f20820116a8c92 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 22 Jun 2026 03:41:57 +0000 Subject: [PATCH 0228/1300] chore: remove stray Subtype.eq_iff declaration (#40867) The theorem Subtype.eq_iff has been removed from core in v4.32.0-rc1 as it is a duplicate of Subtype.ext_iff. The `ext` tag here re-introduces a new public Subtype.eq_iff in Mathlib. We can remove this as theorems can just use Subtype.ext_iff from core. --- Mathlib/Topology/ContinuousMap/Algebra.lean | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mathlib/Topology/ContinuousMap/Algebra.lean b/Mathlib/Topology/ContinuousMap/Algebra.lean index ecac820768283a..926994ae9b3157 100644 --- a/Mathlib/Topology/ContinuousMap/Algebra.lean +++ b/Mathlib/Topology/ContinuousMap/Algebra.lean @@ -492,9 +492,6 @@ end ContinuousMap end RingStructure -set_option linter.deprecated false in -attribute [local ext] Subtype.eq - section ModuleStructure /-! From 8052a7142fd20f502171e269bd39a0987ddda93a Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Mon, 22 Jun 2026 05:44:19 +0000 Subject: [PATCH 0229/1300] chore(Dynamics): general clean-up (#40259) We do a bunch of clean-up: - move the type declarations to the top of the file - remove `[ContinuousAdd]` assumption from `Flow` - use sections to split between `AddMonoid` and `AddGroup` assumption (was done with opening and closing the namespace), also add new sections `AddZero` and `SubtractionCommMonoid` - move definitions and theorem into the correct section - add `@[simp]` lemmas for fully applied defs - use `fun_prop` - minor clean-up (whitespaces, unnecessary coercion arrows, etc) --- Mathlib/Dynamics/Flow.lean | 89 +++++++++++++++++++++----------- Mathlib/Dynamics/OmegaLimit.lean | 4 +- 2 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Mathlib/Dynamics/Flow.lean b/Mathlib/Dynamics/Flow.lean index bad8543dece3ee..87698e7d8c728b 100644 --- a/Mathlib/Dynamics/Flow.lean +++ b/Mathlib/Dynamics/Flow.lean @@ -34,13 +34,13 @@ flow onto an invariant subset, and the time-reversal of a flow by a group. open Set Function Filter +variable {τ α : Type*} + /-! ### Invariant sets -/ section Invariant -variable {τ : Type*} {α : Type*} - /-- A set `s ⊆ α` is invariant under `ϕ : τ → α → α` if `ϕ t s ⊆ s` for all `t` in `τ`. -/ def IsInvariant (ϕ : τ → α → α) (s : Set α) : Prop := ∀ t, MapsTo (ϕ t) s s @@ -76,21 +76,23 @@ end Invariant ### Flows -/ +variable (τ α) in /-- A flow on a topological space `α` by an additive topological monoid `τ` is a continuous monoid action of `τ` on `α`. -/ -structure Flow (τ : Type*) [TopologicalSpace τ] [AddMonoid τ] [ContinuousAdd τ] (α : Type*) - [TopologicalSpace α] where +structure Flow [TopologicalSpace τ] [TopologicalSpace α] [AddZero τ] where /-- The map `τ → α → α` underlying a flow of `τ` on `α`. -/ toFun : τ → α → α cont' : Continuous (uncurry toFun) map_add' : ∀ t₁ t₂ x, toFun (t₁ + t₂) x = toFun t₁ (toFun t₂ x) map_zero' : ∀ x, toFun 0 x = x - namespace Flow -variable {τ : Type*} [AddMonoid τ] [TopologicalSpace τ] [ContinuousAdd τ] - {α : Type*} [TopologicalSpace α] (ϕ : Flow τ α) +variable [TopologicalSpace τ] [TopologicalSpace α] + +section AddZero + +variable [AddZero τ] (ϕ : Flow τ α) instance : CoeFun (Flow τ α) fun _ => τ → α → α := ⟨Flow.toFun⟩ @@ -122,6 +124,10 @@ protected theorem continuous {β : Type*} [TopologicalSpace β] {t : β → τ} alias _root_.Continuous.flow := Flow.continuous +@[continuity, fun_prop] +theorem continuous_toFun (t : τ) : Continuous (ϕ.toFun t) := by + fun_prop + theorem map_add (t₁ t₂ : τ) (x : α) : ϕ (t₁ + t₂) x = ϕ t₁ (ϕ t₂ x) := ϕ.map_add' _ _ _ @[simp] @@ -132,13 +138,17 @@ theorem map_zero_apply (x : α) : ϕ 0 x = x := ϕ.map_zero' x /-- Iterations of a continuous function from a topological space `α` to itself defines a semiflow by `ℕ` on `α`. -/ def fromIter {g : α → α} (h : Continuous g) : Flow ℕ α where - toFun n x := g^[n] x - cont' := continuous_prod_of_discrete_left.mpr (Continuous.iterate h) + toFun n := g^[n] + cont' := continuous_prod_of_discrete_left.mpr h.iterate map_add' := iterate_add_apply _ map_zero' _x := rfl +@[simp] +theorem fromIter_apply {g : α → α} (h : Continuous g) (n : ℕ) (x : α) : + fromIter h n x = g^[n] x := rfl + /-- Restriction of a flow onto an invariant set. -/ -def restrict {s : Set α} (h : IsInvariant ϕ s) : Flow τ (↥s) where +def restrict {s : Set α} (h : IsInvariant ϕ s) : Flow τ s where toFun t := (h t).restrict _ _ _ cont' := Continuous.subtype_mk (by fun_prop) _ map_add' _ _ _ := Subtype.ext (map_add _ _ _ _) @@ -148,18 +158,23 @@ def restrict {s : Set α} (h : IsInvariant ϕ s) : Flow τ (↥s) where theorem coe_restrict_apply {s : Set α} (h : IsInvariant ϕ s) (t : τ) (x : s) : restrict ϕ h t x = ϕ t x := rfl -set_option linter.style.whitespace false in -- manual alignment is not recognised +end AddZero + +section AddMonoid + +variable [AddMonoid τ] (ϕ : Flow τ α) + /-- Convert a flow to an additive monoid action. -/ @[implicit_reducible] def toAddAction : AddAction τ α where - vadd := ϕ - add_vadd := ϕ.map_add' + vadd := ϕ + add_vadd := ϕ.map_add' zero_vadd := ϕ.map_zero' /-- Restrict a flow by `τ` to a flow by an additive submonoid of `τ`. -/ def restrictAddSubmonoid (S : AddSubmonoid τ) : Flow S α where toFun t x := ϕ t x - cont' := ϕ.continuous (continuous_subtype_val.comp continuous_fst) continuous_snd + cont' := by fun_prop map_add' t₁ t₂ x := ϕ.map_add' t₁ t₂ x map_zero' := ϕ.map_zero' @@ -249,12 +264,24 @@ theorem IsFactorOf.trans (h₁ : IsFactorOf ϕ ψ) (h₂ : IsFactorOf ψ χ) : I /-- Every flow is a factor of itself. -/ theorem IsFactorOf.self : IsFactorOf ϕ ϕ := ⟨id, (isSemiconjugacy_id_iff_eq ϕ ϕ).mpr rfl⟩ -end Flow +end AddMonoid -namespace Flow +section AddGroup -variable {τ : Type*} [AddCommGroup τ] [TopologicalSpace τ] [IsTopologicalAddGroup τ] - {α : Type*} [TopologicalSpace α] (ϕ : Flow τ α) +variable [AddGroup τ] (ϕ : Flow τ α) + +/-- The map `ϕ t` as a homeomorphism. -/ +def toHomeomorph (t : τ) : (α ≃ₜ α) where + toFun := ϕ t + invFun := ϕ (-t) + left_inv x := by simp [← map_add] + right_inv x := by simp [← map_add] + +@[simp] +theorem toHomeomorph_apply (t : τ) (x : α) : ϕ.toHomeomorph t x = ϕ t x := rfl + +@[simp] +theorem toHomeomorph_symm_apply (t : τ) (x : α) : (ϕ.toHomeomorph t).symm x = ϕ (-t) x := rfl theorem isInvariant_iff_image_eq (s : Set α) : IsInvariant ϕ s ↔ ∀ t, ϕ t '' s = s := (isInvariant_iff_image _ _).trans @@ -262,26 +289,26 @@ theorem isInvariant_iff_image_eq (s : Set α) : IsInvariant ϕ s ↔ ∀ t, ϕ t (fun h t => Subset.antisymm (h t) fun _ hx => ⟨_, h (-t) ⟨_, hx, rfl⟩, by simp [← map_add]⟩) fun h t => by rw [h t]) +theorem image_eq_preimage_symm (t : τ) (s : Set α) : ϕ t '' s = ϕ (-t) ⁻¹' s := + (ϕ.toHomeomorph t).toEquiv.image_eq_preimage_symm s + +end AddGroup + +section SubtractionCommMonoid + +variable [SubtractionCommMonoid τ] [ContinuousNeg τ] (ϕ : Flow τ α) + /-- The time-reversal of a flow `ϕ` by a (commutative, additive) group is defined `ϕ.reverse t x = ϕ (-t) x`. -/ def reverse : Flow τ α where toFun t := ϕ (-t) - cont' := ϕ.continuous continuous_fst.neg continuous_snd + cont' := by fun_prop map_add' _ _ _ := by rw [neg_add, map_add] map_zero' _ := by rw [neg_zero, map_zero_apply] -@[continuity, fun_prop] -theorem continuous_toFun (t : τ) : Continuous (ϕ.toFun t) := by - fun_prop - -/-- The map `ϕ t` as a homeomorphism. -/ -def toHomeomorph (t : τ) : (α ≃ₜ α) where - toFun := ϕ t - invFun := ϕ (-t) - left_inv x := by rw [← map_add, neg_add_cancel, map_zero_apply] - right_inv x := by rw [← map_add, add_neg_cancel, map_zero_apply] +@[simp] +theorem reverse_apply (t : τ) (x : α) : ϕ.reverse t x = ϕ (-t) x := rfl -theorem image_eq_preimage_symm (t : τ) (s : Set α) : ϕ t '' s = ϕ (-t) ⁻¹' s := - (ϕ.toHomeomorph t).toEquiv.image_eq_preimage_symm s +end SubtractionCommMonoid end Flow diff --git a/Mathlib/Dynamics/OmegaLimit.lean b/Mathlib/Dynamics/OmegaLimit.lean index 2054de1b5f9e50..870d7fcb88d7fb 100644 --- a/Mathlib/Dynamics/OmegaLimit.lean +++ b/Mathlib/Dynamics/OmegaLimit.lean @@ -306,7 +306,7 @@ end omegaLimit -/ namespace Flow -variable {τ : Type*} [TopologicalSpace τ] [AddMonoid τ] [ContinuousAdd τ] {α : Type*} +variable {τ : Type*} [TopologicalSpace τ] [AddMonoid τ] {α : Type*} [TopologicalSpace α] (f : Filter τ) (ϕ : Flow τ α) (s : Set α) open omegaLimit @@ -329,7 +329,7 @@ end Flow -/ namespace Flow -variable {τ : Type*} [TopologicalSpace τ] [AddCommGroup τ] [IsTopologicalAddGroup τ] {α : Type*} +variable {τ : Type*} [TopologicalSpace τ] [AddCommGroup τ] {α : Type*} [TopologicalSpace α] (f : Filter τ) (ϕ : Flow τ α) (s : Set α) open omegaLimit From bdf26e4015b22b2e2080ca93d810fc65b69d6f90 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Mon, 22 Jun 2026 06:02:41 +0000 Subject: [PATCH 0230/1300] feat(Topology/Algebra): use `Is*Apply` for `ContinuousMultilinearMap` (#40463) We replace manual `foo_apply` lemmas by using `IsFooApply` classes. For each `foo` in `zero`, `one`, `add`, `sub`, `neg`, smul` we do the following: - add an instance `IsFooApply` - deprecate `coe_foo` and `foo_apply` --- Mathlib/Analysis/Analytic/Binomial.lean | 2 +- Mathlib/Analysis/Analytic/CPolynomialDef.lean | 19 +++---- Mathlib/Analysis/Analytic/ChangeOrigin.lean | 2 +- Mathlib/Analysis/Analytic/Composition.lean | 21 ++++---- Mathlib/Analysis/Analytic/Inverse.lean | 3 +- Mathlib/Analysis/Analytic/IsolatedZeros.lean | 2 +- Mathlib/Analysis/Analytic/IteratedFDeriv.lean | 8 ++- .../Analysis/Calculus/AbsolutelyMonotone.lean | 3 +- .../Calculus/ContDiff/FaaDiBruno.lean | 1 - .../Calculus/ContDiff/Operations.lean | 6 +-- .../Analysis/Calculus/FDeriv/Analytic.lean | 13 ++--- .../Calculus/IteratedDeriv/Lemmas.lean | 7 +-- .../Fourier/FourierTransformDeriv.lean | 20 ++++---- .../Normed/Module/Multilinear/Basic.lean | 9 ++-- .../SpecialFunctions/Exponential.lean | 4 +- .../TaylorExpansion.lean | 4 +- .../Algebra/Module/Multilinear/Basic.lean | 51 +++++++++---------- 17 files changed, 79 insertions(+), 96 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Binomial.lean b/Mathlib/Analysis/Analytic/Binomial.lean index e86e83ba680519..d323470efb0c04 100644 --- a/Mathlib/Analysis/Analytic/Binomial.lean +++ b/Mathlib/Analysis/Analytic/Binomial.lean @@ -186,7 +186,7 @@ theorem one_div_sub_pow_hasFPowerSeriesOnBall_zero (a : ℕ) {z : ℂ} (hz : z simp only [one_div, FunLike.coe_smul, H, Function.comp_def] at this convert (this.const_smul (c := (z ^ (a + 1))⁻¹)).congr ?_ · ext n - simp only [FormalMultilinearSeries.smul_apply, ContinuousMultilinearMap.smul_apply, + simp only [FormalMultilinearSeries.smul_apply, smul_apply, FormalMultilinearSeries.compContinuousLinearMap_apply] simp [add_assoc, pow_add _ _ (a + 1), mul_assoc] · intro w hw diff --git a/Mathlib/Analysis/Analytic/CPolynomialDef.lean b/Mathlib/Analysis/Analytic/CPolynomialDef.lean index 59c66e2d8114ec..080fd7c388245b 100644 --- a/Mathlib/Analysis/Analytic/CPolynomialDef.lean +++ b/Mathlib/Analysis/Analytic/CPolynomialDef.lean @@ -215,7 +215,7 @@ theorem HasFiniteFPowerSeriesOnBall.eq_partialSum fun y hy m hm ↦ (hf.hasSum hy).unique (hasSum_sum_of_ne_finset_zero (f := fun m => p m (fun _ => y)) (s := Finset.range m) (fun N hN => by simp only [Finset.mem_range, not_lt] at hN - rw [hf.finite _ (le_trans hm hN), ContinuousMultilinearMap.zero_apply])) + rw [hf.finite _ (le_trans hm hN), zero_apply])) /-- Variant of the previous result with the variable expressed as `y` instead of `x + y`. -/ theorem HasFiniteFPowerSeriesOnBall.eq_partialSum' @@ -244,7 +244,7 @@ theorem HasFiniteFPowerSeriesOnBall.bound_zero_of_eq_zero (hf : ∀ y ∈ Metric · intro y hy rw [hf (x + y)] · convert! hasSum_zero - rw [hp, ContinuousMultilinearMap.zero_apply] + rw [hp, zero_apply] · rwa [Metric.mem_eball, edist_eq_enorm_sub, add_comm, add_sub_cancel_right, ← edist_zero_right, ← Metric.mem_eball] @@ -362,7 +362,7 @@ lemma changeOriginSeries_sum_eq_partialSum_of_finite (p : FormalMultilinearSerie intro m hm rw [Finset.mem_range, not_lt] at hm rw [p.changeOriginSeries_finite_of_finite hn k (by rw [add_comm]; exact Nat.le_add_of_sub_le hm), - ContinuousMultilinearMap.zero_apply] + _root_.zero_apply] /-- If `p` is a formal multilinear series such that `p m = 0` for `n ≤ m`, then `p.changeOrigin x k = 0` for `n ≤ k`. -/ @@ -373,8 +373,7 @@ lemma changeOrigin_finite_of_finite (p : FormalMultilinearSeries 𝕜 E F) {n : apply Finset.sum_eq_zero intro m hm rw [Finset.mem_range] at hm - rw [p.changeOriginSeries_finite_of_finite hn k (le_add_of_le_left hk), - ContinuousMultilinearMap.zero_apply] + rw [p.changeOriginSeries_finite_of_finite hn k (le_add_of_le_left hk), _root_.zero_apply] theorem hasFiniteFPowerSeriesOnBall_changeOrigin (p : FormalMultilinearSeries 𝕜 E F) {n : ℕ} (k : ℕ) (hn : ∀ (m : ℕ), n + k ≤ m → p m = 0) : @@ -395,20 +394,18 @@ theorem changeOrigin_eval_of_finite (p : FormalMultilinearSeries 𝕜 E F) {n : · refine fun s ↦ Not.imp_symm fun hs ↦ ?_ simp only [preimage_setOf_eq, changeOriginIndexEquiv_apply_fst, mem_setOf, not_lt] at hs dsimp only [f] - rw [changeOriginSeriesTerm_bound p hn _ _ _ hs, ContinuousMultilinearMap.zero_apply, - ContinuousMultilinearMap.zero_apply] + rw [changeOriginSeriesTerm_bound p hn _ _ _ hs, _root_.zero_apply, _root_.zero_apply] have hfkl k l : HasSum (f ⟨k, l, ·⟩) (changeOriginSeries p k l (fun _ ↦ x) fun _ ↦ y) := by - simp_rw [changeOriginSeries, ContinuousMultilinearMap.sum_apply]; apply hasSum_fintype + simp_rw [changeOriginSeries, sum_apply]; apply hasSum_fintype have hfk k : HasSum (f ⟨k, ·⟩) (changeOrigin p x k fun _ ↦ y) := by have (m) (hm : m ∉ Finset.range n) : changeOriginSeries p k m (fun _ ↦ x) = 0 := by rw [Finset.mem_range, not_lt] at hm - rw [changeOriginSeries_finite_of_finite _ hn _ (le_add_of_le_right hm), - ContinuousMultilinearMap.zero_apply] + rw [changeOriginSeries_finite_of_finite _ hn _ (le_add_of_le_right hm), _root_.zero_apply] rw [changeOrigin, FormalMultilinearSeries.sum, ContinuousMultilinearMap.tsum_eval (summable_of_ne_finset_zero this)] refine (summable_of_ne_finset_zero (s := Finset.range n) fun m hm ↦ ?_).hasSum.sigma_of_hasSum (hfkl k) (summable_of_hasFiniteSupport <| finsupp.preimage sigma_mk_injective.injOn) - rw [this m hm, ContinuousMultilinearMap.zero_apply] + rw [this m hm, _root_.zero_apply] have hf : HasSum f ((p.changeOrigin x).sum y) := ((p.changeOrigin x).hasSum_of_finite (fun _ ↦ changeOrigin_finite_of_finite p hn) _) |>.sigma_of_hasSum hfk (summable_of_hasFiniteSupport finsupp) diff --git a/Mathlib/Analysis/Analytic/ChangeOrigin.lean b/Mathlib/Analysis/Analytic/ChangeOrigin.lean index 40a765dab824cf..3dbdbdc6ca2e91 100644 --- a/Mathlib/Analysis/Analytic/ChangeOrigin.lean +++ b/Mathlib/Analysis/Analytic/ChangeOrigin.lean @@ -279,7 +279,7 @@ theorem changeOrigin_eval (h : (‖x‖₊ + ‖y‖₊ : ℝ≥0∞) < p.radius have := (p.hasFPowerSeriesOnBall_changeOrigin k h.pos).hasSum x_mem_ball rw [zero_add] at this refine HasSum.sigma_of_hasSum this (fun l => ?_) ?_ - · simp only [changeOriginSeries, ContinuousMultilinearMap.sum_apply] + · simp only [changeOriginSeries, sum_apply] apply hasSum_fintype · refine .of_nnnorm_bounded (p.changeOriginSeries_summable_aux₂ (mem_eball_zero_iff.1 x_mem_ball) k) diff --git a/Mathlib/Analysis/Analytic/Composition.lean b/Mathlib/Analysis/Analytic/Composition.lean index a1ec939506e5f5..a2d67c703fbb11 100644 --- a/Mathlib/Analysis/Analytic/Composition.lean +++ b/Mathlib/Analysis/Analytic/Composition.lean @@ -277,7 +277,7 @@ theorem removeZero_comp_of_pos (q : FormalMultilinearSeries 𝕜 F G) q.removeZero.comp p n = q.comp p n := by ext v simp only [FormalMultilinearSeries.comp, compAlongComposition, - ContinuousMultilinearMap.compAlongComposition_apply, ContinuousMultilinearMap.sum_apply] + ContinuousMultilinearMap.compAlongComposition_apply, sum_apply] refine Finset.sum_congr rfl fun c _hc => ?_ rw [removeZero_of_pos _ (c.length_pos_of_pos hn)] @@ -395,10 +395,10 @@ theorem comp_id (p : FormalMultilinearSeries 𝕜 E F) (x : E) : p.comp (id 𝕜 let j : Fin b.length := ⟨i.val, b.blocks_length ▸ i.prop⟩ have A : 1 < b.blocksFun j := by convert! lt_k ext v - rw [compAlongComposition_apply, ContinuousMultilinearMap.zero_apply] + rw [compAlongComposition_apply, _root_.zero_apply] apply ContinuousMultilinearMap.map_coord_zero _ j dsimp [applyComposition] - rw [id_apply_of_one_lt _ _ _ A, ContinuousMultilinearMap.zero_apply] + rw [id_apply_of_one_lt _ _ _ A, _root_.zero_apply] · simp @[simp] @@ -427,8 +427,8 @@ theorem id_comp (p : FormalMultilinearSeries 𝕜 E F) (v0 : Fin 0 → E) : have : 0 < b.length := Composition.length_pos_of_pos b n_pos lia ext v - rw [compAlongComposition_apply, id_apply_of_one_lt _ _ _ A, - ContinuousMultilinearMap.zero_apply, ContinuousMultilinearMap.zero_apply] + rw [compAlongComposition_apply, id_apply_of_one_lt _ _ _ A, _root_.zero_apply, + _root_.zero_apply] · simp /-- Variant of `id_comp` in which the zero coefficient is given by an equality hypothesis instead @@ -813,8 +813,7 @@ theorem HasFPowerSeriesWithinAt.comp {g : F → G} {f : E → F} {q : FormalMult have E : HasSum (fun n => (q.comp p) n fun _j => y) (g (f (x + y))) := by apply D.sigma intro n - simp only [compAlongComposition_apply, FormalMultilinearSeries.comp, - ContinuousMultilinearMap.sum_apply] + simp only [compAlongComposition_apply, FormalMultilinearSeries.comp, sum_apply] exact hasSum_fintype _ rw [Function.comp_apply] exact E @@ -910,7 +909,7 @@ theorem HasFiniteFPowerSeriesAt.comp {m n : ℕ} {g : F → G} {f : E → F} apply Finset.sum_eq_zero rintro c - ext v - simp only [compAlongComposition_apply, ContinuousMultilinearMap.zero_apply] + simp only [compAlongComposition_apply, _root_.zero_apply] rcases le_or_gt m c.length with hc | hc · simp [hg.finite _ hc] obtain ⟨j, hj⟩ : ∃ j, n ≤ c.blocksFun j := by @@ -1256,9 +1255,9 @@ theorem comp_assoc (r : FormalMultilinearSeries 𝕜 G H) (q : FormalMultilinear r c.1.length fun i : Fin c.1.length => q (c.2 i).length (applyComposition p (c.2 i) (v ∘ c.1.embedding i)) suffices ∑ c, f c = ∑ c, g c by - simpa +unfoldPartialApp only [FormalMultilinearSeries.comp, - ContinuousMultilinearMap.sum_apply, compAlongComposition_apply, Finset.sum_sigma', - applyComposition, ContinuousMultilinearMap.map_sum] + simpa +unfoldPartialApp only [FormalMultilinearSeries.comp, sum_apply, + compAlongComposition_apply, Finset.sum_sigma', applyComposition, + ContinuousMultilinearMap.map_sum] /- Now, we use `Composition.sigmaEquivSigmaPi n` to change variables in the second sum, and check that we get exactly the same sums. -/ rw [← (sigmaEquivSigmaPi n).sum_comp] diff --git a/Mathlib/Analysis/Analytic/Inverse.lean b/Mathlib/Analysis/Analytic/Inverse.lean index b9b860c5086d23..5a1ae3790ef0d7 100644 --- a/Mathlib/Analysis/Analytic/Inverse.lean +++ b/Mathlib/Analysis/Analytic/Inverse.lean @@ -133,8 +133,7 @@ theorem leftInv_comp (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (p.leftInv i x (n + 2) fun j : Fin (n + 2) => p 1 fun _ => v j) = -∑ c ∈ {c : Composition (n + 2) | c.length < n + 2}.toFinset, (p.leftInv i x c.length) (p.applyComposition c v) := by - simp only [leftInv, ContinuousMultilinearMap.neg_apply, neg_inj, - ContinuousMultilinearMap.sum_apply] + simp only [leftInv, _root_.neg_apply, neg_inj, _root_.sum_apply] convert! (sum_toFinset_eq_subtype (fun c : Composition (n + 2) => c.length < n + 2) (fun c : Composition (n + 2) => diff --git a/Mathlib/Analysis/Analytic/IsolatedZeros.lean b/Mathlib/Analysis/Analytic/IsolatedZeros.lean index 1fcc5670191e2d..9bad403947a195 100644 --- a/Mathlib/Analysis/Analytic/IsolatedZeros.lean +++ b/Mathlib/Analysis/Analytic/IsolatedZeros.lean @@ -103,7 +103,7 @@ theorem eq_pow_order_mul_iterate_dslope (hp : HasFPowerSeriesAt f p z₀) (z : f z = (z - z₀) ^ p.order • (swap dslope z₀)^[p.order] f z := by refine (pow_sub_smul_iterate_dslope_of_zero _ (fun k hk ↦ ?_) z).symm rw [← (has_fpower_series_iterate_dslope_fslope k hp).coeff_zero 1, ← coeff, coeff_iterate_fslope, - zero_add, coeff, p.apply_eq_zero_of_lt_order hk, ContinuousMultilinearMap.zero_apply] + zero_add, coeff, p.apply_eq_zero_of_lt_order hk, _root_.zero_apply] theorem locally_ne_zero (hp : HasFPowerSeriesAt f p z₀) (h : p ≠ 0) : ∀ᶠ z in 𝓝[≠] z₀, f z ≠ 0 := by rw [eventually_nhdsWithin_iff] diff --git a/Mathlib/Analysis/Analytic/IteratedFDeriv.lean b/Mathlib/Analysis/Analytic/IteratedFDeriv.lean index 2019cd650302ed..2d519981981421 100644 --- a/Mathlib/Analysis/Analytic/IteratedFDeriv.lean +++ b/Mathlib/Analysis/Analytic/IteratedFDeriv.lean @@ -99,8 +99,7 @@ lemma FormalMultilinearSeries.iteratedFDerivSeries_eq_zero {k n : ℕ} ContinuousLinearMap.compFormalMultilinearSeries_apply, ContinuousLinearMap.compContinuousMultilinearMap_coe, ContinuousLinearEquiv.coe_coe, LinearIsometryEquiv.coe_toContinuousLinearEquiv, Function.comp_apply, - continuousMultilinearCurryLeftEquiv_symm_apply, ContinuousMultilinearMap.zero_apply, - _root_.zero_apply, + continuousMultilinearCurryLeftEquiv_symm_apply, _root_.zero_apply, derivSeries_eq_zero _ (ih (p.congr_zero (Nat.succ_add_eq_add_succ _ _).symm h))] /-- If the `n`-th term in a power series is zero, then the `n`-th derivative of the corresponding @@ -111,8 +110,7 @@ lemma HasFPowerSeriesWithinOnBall.iteratedFDerivWithin_eq_zero iteratedFDerivWithin 𝕜 n f s x = 0 := by have : iteratedFDerivWithin 𝕜 n f s x = p.iteratedFDerivSeries n 0 (fun _ ↦ 0) := ((h.iteratedFDerivWithin h' n hu hx).coeff_zero _).symm - rw [this, p.iteratedFDerivSeries_eq_zero (p.congr_zero (Nat.zero_add n).symm hn), - ContinuousMultilinearMap.zero_apply] + rw [this, p.iteratedFDerivSeries_eq_zero (p.congr_zero (Nat.zero_add n).symm hn), zero_apply] lemma ContinuousMultilinearMap.iteratedFDeriv_comp_diagonal {n : ℕ} (f : E [×n]→L[𝕜] F) (x : E) (v : Fin n → E) : @@ -122,7 +120,7 @@ lemma ContinuousMultilinearMap.iteratedFDeriv_comp_diagonal change iteratedFDeriv 𝕜 n (f ∘ g) x v = _ rw [ContinuousLinearMap.iteratedFDeriv_comp_right _ f.contDiff _ le_rfl, f.iteratedFDeriv_eq] simp only [ContinuousMultilinearMap.iteratedFDeriv, - ContinuousMultilinearMap.compContinuousLinearMap_apply, ContinuousMultilinearMap.sum_apply, + ContinuousMultilinearMap.compContinuousLinearMap_apply, sum_apply, ContinuousMultilinearMap.iteratedFDerivComponent_apply, Set.mem_range, Pi.compRightL_apply] rw [← sum_comp (Equiv.embeddingEquivOfFinite (Fin n))] congr with σ diff --git a/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean b/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean index 79825130a34cf8..2bf4bd218d8658 100644 --- a/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean +++ b/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean @@ -103,8 +103,7 @@ theorem add (hf : AbsolutelyMonotoneOn f s) (hg : AbsolutelyMonotoneOn g s) : obtain ⟨p, hp, hp_nn⟩ := hf obtain ⟨q, hq, hq_nn⟩ := hg refine ⟨p + q, hp.add hq, fun n x hx => ?_⟩ - simp only [Pi.add_apply, FormalMultilinearSeries.add_apply, - ContinuousMultilinearMap.add_apply] + simp only [Pi.add_apply, FormalMultilinearSeries.add_apply, add_apply] exact add_nonneg (hp_nn n hx) (hq_nn n hx) /-- A nonnegative scalar multiple of an absolutely monotone function is absolutely monotone. -/ diff --git a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean index 6b24f9ee7aaf84..5ae2154bdc47b5 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean @@ -1100,7 +1100,6 @@ theorem HasFTaylorSeriesUpToOn.comp {n : WithTop ℕ∞} {g : F → G} {f : E convert! B ext v simp only [Nat.succ_eq_add_one, Fintype.sum_option, ContinuousMultilinearMap.curryLeft_apply, - ContinuousMultilinearMap.sum_apply, ContinuousMultilinearMap.add_apply, FormalMultilinearSeries.compAlongOrderedFinpartition_apply, sum_apply, add_apply] rw [Finset.sum_sigma'] exact Fintype.sum_equiv (OrderedFinpartition.extendEquiv m) _ _ (fun p ↦ rfl) diff --git a/Mathlib/Analysis/Calculus/ContDiff/Operations.lean b/Mathlib/Analysis/Calculus/ContDiff/Operations.lean index 7fb93ae9a9881d..6a19277621a564 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Operations.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Operations.lean @@ -284,8 +284,7 @@ theorem iteratedFDerivWithin_neg_apply {f : E → F} (hu : UniqueDiffOn 𝕜 s) _ = fderivWithin 𝕜 (-iteratedFDerivWithin 𝕜 i f s) s x (h 0) (Fin.tail h) := by rw [fderivWithin_congr' (@hi) hx, Pi.neg_def] _ = -(fderivWithin 𝕜 (iteratedFDerivWithin 𝕜 i f s) s) x (h 0) (Fin.tail h) := by - rw [fderivWithin_neg (hu x hx), neg_apply, - ContinuousMultilinearMap.neg_apply] + rw [fderivWithin_neg (hu x hx), neg_apply, neg_apply] _ = -(iteratedFDerivWithin 𝕜 (i + 1) f s) x h := by rw [iteratedFDerivWithin_succ_apply_left] @@ -690,8 +689,7 @@ theorem iteratedFDeriv_comp_const_smul (a : 𝕜) (hf : ContDiff 𝕜 i f) : ext v rw [iteratedFDeriv_succ_eq_comp_left, iteratedFDeriv_succ_eq_comp_left] simp only [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one, self_le_add_right, hf.of_le, hi, - comp_apply, continuousMultilinearCurryLeftEquiv_symm_apply, - ContinuousMultilinearMap.smul_apply] + comp_apply, continuousMultilinearCurryLeftEquiv_symm_apply, smul_apply] rw [fderiv_fun_const_smul, fderiv_comp_smul, smul_smul, ← pow_succ] · simp rw [← Function.comp_def (g := (a • ·))] diff --git a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean index 117d0433267872..e8a1130e401d16 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean @@ -334,7 +334,7 @@ theorem HasFPowerSeriesWithinOnBall.hasSum_derivSeries_of_hasFDerivWithinAt ContinuousLinearMap.compFormalMultilinearSeries_apply, FormalMultilinearSeries.changeOriginSeries, ContinuousLinearMap.compContinuousMultilinearMap_coe, ContinuousLinearEquiv.coe_coe, - LinearIsometryEquiv.coe_coe, Function.comp_apply, ContinuousMultilinearMap.sum_apply, map_sum] + LinearIsometryEquiv.coe_coe, Function.comp_apply, sum_apply, map_sum] rfl /-- If a function has a power series within a set on a ball, then so does its derivative. Version @@ -591,12 +591,13 @@ theorem changeOrigin_toFormalMultilinearSeries [DecidableEq ι] : cases isEmpty_or_nonempty ι · have (l : _) : 1 + l ≠ Fintype.card ι := by rw [add_comm, Fintype.card_eq_zero]; exact Nat.succ_ne_zero _ - simp_rw [Fintype.sum_empty, changeOriginSeries_support _ (this _), zero_apply _, tsum_zero]; rfl + simp_rw [Fintype.sum_empty, changeOriginSeries_support _ (this _), _root_.zero_apply _, + tsum_zero]; rfl rw [tsum_eq_single (Fintype.card ι - 1), changeOriginSeries]; swap · intro m hm rw [Ne, eq_tsub_iff_add_eq_of_le (by exact Fintype.card_pos), add_comm] at hm - rw [f.changeOriginSeries_support hm, zero_apply] - rw [sum_apply, ContinuousMultilinearMap.sum_apply, Fin.snoc_zero] + rw [f.changeOriginSeries_support hm, _root_.zero_apply] + rw [_root_.sum_apply, _root_.sum_apply, Fin.snoc_zero] simp_rw [changeOriginSeriesTerm_apply] refine (Fintype.sum_bijective (?_ ∘ Fintype.equivFinOfCardEq (Nat.add_sub_of_le Fintype.card_pos).symm) (.comp ?_ <| Equiv.bijective _) _ _ fun i ↦ ?_).symm @@ -795,8 +796,8 @@ theorem derivSeries_apply_diag (n : ℕ) (x : E) : derivSeries p n (fun _ ↦ x) x = (n + 1) • p (n + 1) fun _ ↦ x := by simp only [derivSeries, compFormalMultilinearSeries_apply, changeOriginSeries, compContinuousMultilinearMap_coe, ContinuousLinearEquiv.coe_coe, LinearIsometryEquiv.coe_coe, - Function.comp_apply, ContinuousMultilinearMap.sum_apply, map_sum, _root_.sum_apply, - continuousMultilinearCurryFin1_apply, Matrix.zero_empty] + Function.comp_apply, map_sum, _root_.sum_apply, continuousMultilinearCurryFin1_apply, + Matrix.zero_empty] convert! Finset.sum_const _ · rw [Fin.snoc_zero, changeOriginSeriesTerm_apply, Finset.piecewise_same, add_comm] · rw [← card, card_subtype, ← Finset.powerset_univ, ← Finset.powersetCard_eq_filter, diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean index 18b864f5d1edd5..aff008563104c5 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean @@ -75,8 +75,7 @@ theorem iteratedDerivWithin_add (hf : ContDiffWithinAt 𝕜 n f s x) (hg : ContDiffWithinAt 𝕜 n g s x) : iteratedDerivWithin n (f + g) s x = iteratedDerivWithin n f s x + iteratedDerivWithin n g s x := by - simp_rw [iteratedDerivWithin, iteratedFDerivWithin_add_apply hf hg h hx, - ContinuousMultilinearMap.add_apply] + simp_rw [iteratedDerivWithin, iteratedFDerivWithin_add_apply hf hg h hx, add_apply] include h hx in theorem iteratedDerivWithin_fun_add @@ -103,9 +102,7 @@ theorem iteratedDerivWithin_const_sub (hn : 0 < n) (c : F) : include h hx in theorem iteratedDerivWithin_const_smul (c : R) (hf : ContDiffWithinAt 𝕜 n f s x) : iteratedDerivWithin n (c • f) s x = c • iteratedDerivWithin n f s x := by - simp_rw [iteratedDerivWithin] - rw [iteratedFDerivWithin_const_smul_apply (a := c) hf h hx] - simp only [ContinuousMultilinearMap.smul_apply] + simp [iteratedDerivWithin, iteratedFDerivWithin_const_smul_apply hf h hx] include h hx in theorem iteratedDerivWithin_fun_const_smul (c : R) (hf : ContDiffWithinAt 𝕜 n f s x) : diff --git a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean index 69ce46ebc9901f..5cf7150a64f798 100644 --- a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean +++ b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean @@ -487,8 +487,7 @@ lemma hasFTaylorSeriesUpTo_fourierIntegral {N : ℕ∞ω} congr with v simp only [fourierPowSMulRight_apply, mul_comm, pow_succ, neg_mul, Fin.prod_univ_succ, Fin.cons_zero, Fin.cons_succ, neg_smul, fourierSMulRight_apply, - ContinuousMultilinearMap.neg_apply, ContinuousMultilinearMap.smul_apply, - smul_comm (M := ℝ) (N := ℂ) (α := E), smul_smul] + neg_apply, smul_apply, smul_comm (M := ℝ) (N := ℂ) (α := E), smul_smul] exact E ▸ hasFDerivAt_fourierIntegral L I₁ I₂ w · intro n hn apply fourierIntegral_continuous Real.continuous_fourierChar (by apply L.continuous₂) @@ -538,9 +537,9 @@ theorem fourierIntegral_iteratedFDeriv [FiniteDimensional ℝ V] induction n with | zero => ext w m - simp only [iteratedFDeriv_zero_apply, fourierPowSMulRight_apply, pow_zero, - Finset.univ_eq_empty, _root_.neg_apply, ContinuousLinearMap.flip_apply, - Finset.prod_empty, one_smul, fourierIntegral_continuousMultilinearMap_apply' ((h'f 0 bot_le))] + simp only [iteratedFDeriv_zero_apply, fourierPowSMulRight_apply, pow_zero, Finset.univ_eq_empty, + neg_apply, ContinuousLinearMap.flip_apply, Finset.prod_empty, one_smul, + fourierIntegral_continuousMultilinearMap_apply' ((h'f 0 bot_le))] | succ n ih => ext w m have J : Integrable (fderiv ℝ (iteratedFDeriv ℝ n f)) μ := by @@ -552,18 +551,17 @@ theorem fourierIntegral_iteratedFDeriv [FiniteDimensional ℝ V] (m 0) (Fin.tail m) = (-(2 * π * I)) ^ (n + 1) • (∏ x : Fin (n + 1), -L (m x) w) • ∫ v, 𝐞 (-L v w) • f v ∂μ by rw [fourierIntegral_continuousMultilinearMap_apply' (h'f _ hn)] - simp only [iteratedFDeriv_succ_apply_left, fourierPowSMulRight_apply, - _root_.neg_apply, ContinuousLinearMap.flip_apply] + simp only [iteratedFDeriv_succ_apply_left, fourierPowSMulRight_apply, neg_apply, + ContinuousLinearMap.flip_apply] rw [← fourierIntegral_continuousMultilinearMap_apply' ((J.apply_continuousLinearMap _)), ← fourierIntegral_continuousLinearMap_apply' J] exact H have h'n : n < N := (Nat.cast_lt.mpr n.lt_succ_self).trans_le hn rw [fourierIntegral_fderiv _ (h'f n h'n.le) (hf.differentiable_iteratedFDeriv (mod_cast h'n)) J] - simp only [ih h'n.le, fourierSMulRight_apply, _root_.neg_apply, - ContinuousLinearMap.flip_apply, neg_smul, smul_neg, neg_neg, - ContinuousMultilinearMap.smul_apply, fourierPowSMulRight_apply, - ← coe_smul (E := E), smul_smul] + simp only [ih h'n.le, fourierSMulRight_apply, neg_apply, ContinuousLinearMap.flip_apply, + neg_smul, smul_neg, neg_neg, smul_apply, fourierPowSMulRight_apply, ← coe_smul (E := E), + smul_smul] congr 1 simp only [ofReal_prod, ofReal_neg, pow_succ, mul_neg, Fin.prod_univ_succ, neg_mul, ofReal_mul, neg_neg, Fin.tail_def] diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean index 16db21c902d403..aba6bf12d57fad 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean @@ -932,16 +932,15 @@ def flipMultilinear (f : G →L[𝕜] ContinuousMultilinearMap 𝕜 E G') : MultilinearMap.mkContinuous { toFun := fun m => LinearMap.mkContinuous - { toFun := fun x => f x m - map_add' := fun x y => by simp only [map_add, ContinuousMultilinearMap.add_apply] - map_smul' := fun c x => by - simp only [ContinuousMultilinearMap.smul_apply, map_smul, RingHom.id_apply] } + { toFun := (f · m) + map_add' := by simp + map_smul' := by simp } (‖f‖ * ∏ i, ‖m i‖) fun x => by rw [mul_right_comm] exact (f x).le_of_opNorm_le (f.le_opNorm x) _ map_update_add' := fun m i x y => by ext1 - simp only [_root_.add_apply, ContinuousMultilinearMap.map_update_add, LinearMap.coe_mk, + simp only [add_apply, ContinuousMultilinearMap.map_update_add, LinearMap.coe_mk, LinearMap.mkContinuous_apply, AddHom.coe_mk] map_update_smul' := fun m i c x => by ext1 diff --git a/Mathlib/Analysis/SpecialFunctions/Exponential.lean b/Mathlib/Analysis/SpecialFunctions/Exponential.lean index d4285ca6039335..fa82b301845597 100644 --- a/Mathlib/Analysis/SpecialFunctions/Exponential.lean +++ b/Mathlib/Analysis/SpecialFunctions/Exponential.lean @@ -279,8 +279,8 @@ theorem hasFDerivAt_exp_smul_const_of_mem_ball (x : 𝔸) (t : 𝕊) have : Commute (t • x) (h • x) := ((Commute.refl x).smul_left t).smul_right h rw [add_smul t h, exp_add_of_commute_of_mem_ball this htx hh, zero_add, zero_smul, exp_zero, ContinuousLinearMap.smulRight_apply, one_apply_eq_self, - _root_.smul_apply, ContinuousLinearMap.smulRight_apply, - one_apply_eq_self, smul_eq_mul, mul_sub_left_distrib, mul_sub_left_distrib, mul_one] + smul_apply, ContinuousLinearMap.smulRight_apply, one_apply_eq_self, smul_eq_mul, + mul_sub_left_distrib, mul_sub_left_distrib, mul_one] theorem hasFDerivAt_exp_smul_const_of_mem_ball' (x : 𝔸) (t : 𝕊) (htx : t • x ∈ Metric.eball (0 : 𝔸) (expSeries 𝕂 𝔸).radius) : diff --git a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean index bfb217a1a6f464..2c5f7e64be0c71 100644 --- a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean +++ b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean @@ -80,8 +80,8 @@ theorem iteratedFDeriv_charFun {n : ℕ} {t : E} (hint : MemLp id n μ) (x : Fin exact contDiff_fourierIntegral _ hint' simp only [mul_inv_rev, neg_smul] rw [h, iteratedFDeriv_fourierIntegral _ hint' (by fun_prop) le_rfl] - simp only [ContinuousMultilinearMap.smul_apply, real_smul, ofReal_pow, ofReal_neg, ofReal_mul, - ofReal_inv, ofReal_ofNat, ofReal_prod] + simp only [smul_apply, real_smul, ofReal_pow, ofReal_neg, ofReal_mul, ofReal_inv, ofReal_ofNat, + ofReal_prod] rw [fourierIntegral_continuousMultilinearMap_apply Real.continuous_fourierChar] swap; · exact integrable_fourierPowSMulRight _ (by simpa using hint.integrable_norm_pow') (by fun_prop) diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean index 0f9c1b4807783e..e9e26963455cdd 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean @@ -126,9 +126,10 @@ instance : Zero (ContinuousMultilinearMap R M₁ M₂) := instance : Inhabited (ContinuousMultilinearMap R M₁ M₂) := ⟨0⟩ -@[simp] -theorem zero_apply (m : ∀ i, M₁ i) : (0 : ContinuousMultilinearMap R M₁ M₂) m = 0 := - rfl +instance : IsZeroApply (ContinuousMultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + zero_apply _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias zero_apply := zero_apply @[simp] theorem toMultilinearMap_zero : (0 : ContinuousMultilinearMap R M₁ M₂).toMultilinearMap = 0 := @@ -143,10 +144,10 @@ variable {R' R'' A : Type*} [Semiring A] [∀ i, Module A (M₁ i)] instance : SMul R' (ContinuousMultilinearMap A M₁ M₂) := ⟨fun c f => { c • f.toMultilinearMap with cont := f.cont.const_smul c }⟩ -@[simp] -theorem smul_apply (f : ContinuousMultilinearMap A M₁ M₂) (c : R') (m : ∀ i, M₁ i) : - (c • f) m = c • f m := - rfl +instance : IsSMulApply R' (ContinuousMultilinearMap A M₁ M₂) (∀ i, M₁ i) M₂ where + smul_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias smul_apply := smul_apply @[simp] theorem toMultilinearMap_smul (c : R') (f : ContinuousMultilinearMap A M₁ M₂) : @@ -154,15 +155,13 @@ theorem toMultilinearMap_smul (c : R') (f : ContinuousMultilinearMap A M₁ M₂ rfl instance [SMulCommClass R' R'' M₂] : SMulCommClass R' R'' (ContinuousMultilinearMap A M₁ M₂) := - ⟨fun _ _ _ => ext fun _ => smul_comm _ _ _⟩ + FunLike.smulCommClass instance [SMul R' R''] [IsScalarTower R' R'' M₂] : - IsScalarTower R' R'' (ContinuousMultilinearMap A M₁ M₂) := - ⟨fun _ _ _ => ext fun _ => smul_assoc _ _ _⟩ + IsScalarTower R' R'' (ContinuousMultilinearMap A M₁ M₂) := FunLike.isScalarTower instance [DistribSMul R'ᵐᵒᵖ M₂] [IsCentralScalar R' M₂] : - IsCentralScalar R' (ContinuousMultilinearMap A M₁ M₂) := - ⟨fun _ _ => ext fun _ => op_smul_eq_smul _ _⟩ + IsCentralScalar R' (ContinuousMultilinearMap A M₁ M₂) := FunLike.isCentralScalar end SMul @@ -183,9 +182,10 @@ variable [ContinuousAdd M₂] instance : Add (ContinuousMultilinearMap R M₁ M₂) := ⟨fun f f' => ⟨f.toMultilinearMap + f'.toMultilinearMap, f.cont.add f'.cont⟩⟩ -@[simp] -theorem add_apply (m : ∀ i, M₁ i) : (f + f') m = f m + f' m := - rfl +instance : IsAddApply (ContinuousMultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + add_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias add_apply := add_apply @[simp] theorem toMultilinearMap_add (f g : ContinuousMultilinearMap R M₁ M₂) : @@ -205,10 +205,7 @@ def applyAddHom (m : ∀ i, M₁ i) : ContinuousMultilinearMap R M₁ M₂ →+ map_zero' := rfl map_add' _ _ := rfl -@[simp] -theorem sum_apply {α : Type*} (f : α → ContinuousMultilinearMap R M₁ M₂) (m : ∀ i, M₁ i) - {s : Finset α} : (∑ a ∈ s, f a) m = ∑ a ∈ s, f a m := - map_sum (applyAddHom m) f s +@[deprecated (since := "2026-06-10")] protected alias sum_apply := sum_apply end ContinuousAdd @@ -482,16 +479,18 @@ variable [IsTopologicalAddGroup M₂] instance : Neg (ContinuousMultilinearMap R M₁ M₂) := ⟨fun f => { -f.toMultilinearMap with cont := f.cont.neg }⟩ -@[simp] -theorem neg_apply (m : ∀ i, M₁ i) : (-f) m = -f m := - rfl +instance : IsNegApply (ContinuousMultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + neg_apply _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias neg_apply := neg_apply instance : Sub (ContinuousMultilinearMap R M₁ M₂) := ⟨fun f g => { f.toMultilinearMap - g.toMultilinearMap with cont := f.cont.sub g.cont }⟩ -@[simp] -theorem sub_apply (m : ∀ i, M₁ i) : (f - f') m = f m - f' m := - rfl +instance : IsSubApply (ContinuousMultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where + sub_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-10")] protected alias sub_apply := sub_apply instance : AddCommGroup (ContinuousMultilinearMap R M₁ M₂) := fast_instance% toMultilinearMap_injective.addCommGroup _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) @@ -686,7 +685,7 @@ theorem mkPiRing_eq_iff {z₁ z₂ : M} : exact MultilinearMap.mkPiRing_eq_iff theorem mkPiRing_zero : ContinuousMultilinearMap.mkPiRing R ι (0 : M) = 0 := by - ext; rw [mkPiRing_apply, smul_zero, ContinuousMultilinearMap.zero_apply] + ext; rw [mkPiRing_apply, smul_zero, zero_apply] theorem mkPiRing_eq_zero_iff (z : M) : ContinuousMultilinearMap.mkPiRing R ι z = 0 ↔ z = 0 := by rw [← mkPiRing_zero, mkPiRing_eq_iff] From 413459545a370f9c5d0dd0151ee8f277224c23b3 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 22 Jun 2026 07:19:47 +0000 Subject: [PATCH 0231/1300] refactor(Topology): add deprecation module for ```LocPathConnected``` (#40869) Co-authored-by: Batixx --- Mathlib.lean | 1 + Mathlib/Topology/Connected/LocPathConnected.lean | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 Mathlib/Topology/Connected/LocPathConnected.lean diff --git a/Mathlib.lean b/Mathlib.lean index bd78be55936b6e..0b00953c68055d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7781,6 +7781,7 @@ public import Mathlib.Topology.Compactness.SigmaCompact public import Mathlib.Topology.Connected.Basic public import Mathlib.Topology.Connected.CardComponents public import Mathlib.Topology.Connected.Clopen +public import Mathlib.Topology.Connected.LocPathConnected public import Mathlib.Topology.Connected.LocallyConnected public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Topology.Connected.PathComponentOne diff --git a/Mathlib/Topology/Connected/LocPathConnected.lean b/Mathlib/Topology/Connected/LocPathConnected.lean new file mode 100644 index 00000000000000..cc71984b49b2fd --- /dev/null +++ b/Mathlib/Topology/Connected/LocPathConnected.lean @@ -0,0 +1,10 @@ +/- +Copyright (c) 2020 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Ben Eltschig +-/ +module -- shake: keep-all + +public import Mathlib.Topology.Connected.LocallyPathConnected + +deprecated_module (since := "2026-06-21") From 087fc91703c3ff630a37538ff7399a7c2972d008 Mon Sep 17 00:00:00 2001 From: Michael Stoll <99838730+MichaelStollBayreuth@users.noreply.github.com> Date: Mon, 22 Jun 2026 07:32:35 +0000 Subject: [PATCH 0232/1300] feat(AlgebraicGeometry/EllipticCurve/Affine/AddSubMap): sym2x + API (#40574) This continues the development toward the approximate parallelogram law on an elliptic curve. It introduces `WeierstrassCurve.Affine.Point.symx`, which represents the symmetric square of the `x`-coordinate map. The proof of the approximate parallelogram law is based on a commutative square relating `WeierstrassCurve.addSubMap` to `WeierstrassCurve.Affine.Point.symx`. --- .../EllipticCurve/Affine/AddSubMap.lean | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/AddSubMap.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/AddSubMap.lean index e827a3073c3ef7..a0d9e31f7c3413 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/AddSubMap.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/AddSubMap.lean @@ -5,8 +5,7 @@ Authors: Michael Stoll -/ module -public import Mathlib.AlgebraicGeometry.EllipticCurve.Weierstrass -public import Mathlib.LinearAlgebra.Matrix.Notation +public import Mathlib.AlgebraicGeometry.EllipticCurve.Affine.Point public import Mathlib.RingTheory.MvPolynomial.Homogeneous public import Mathlib.Tactic.Ring.NamePolyVars @@ -129,4 +128,58 @@ lemma addSubMap_ne_zero [IsReduced R] {x : Fin 3 → R} (hx : x ≠ 0) : end WeierstrassCurve +/-! +### The symmetric square of the x-coordinate map + +We define `Weierstrass.Affine.Point.sym2x`, which sends a pair `P`, `Q` of nonsingular points in +affine coordinates on a Weierstrass curve to a triple projectively equal to +`(x(P)*x(Q), x(P)+x(Q), 1)`, and provide some API. +-/ + +namespace WeierstrassCurve.Affine.Point + +variable {R : Type*} [CommRing R] {W' : Affine R} + +/-- This map sends a pair `P`, `Q` of nonsingular points in affine coordinates on `W` +to a triple projectively equivalent to `![x(P) * x(Q), x(P) + x(Q), 1]`. + +In more geometric terms, this is the map `Sym² W → Sym² ℙ¹ ≃ ℙ²` induced by `x : W → ℙ¹`. -/ +noncomputable def sym2x (P Q : W'.Point) : Fin 3 → R := + letI Px := P.xRep + letI Qx := Q.xRep + ![Px 0 * Qx 0, Px 0 * Qx 1 + Px 1 * Qx 0, Px 1 * Qx 1] + +@[simp] +lemma sym2x_zero_zero : (0 : W'.Point).sym2x 0 = ![1, 0, 0] := by + simp [sym2x] + +@[simp] +lemma sym2x_zero_some {x y : R} (h : W'.Nonsingular x y) : + (0 : W'.Point).sym2x (some x y h) = ![x, 1, 0] := by + simp [sym2x] + +@[simp] +lemma sym2x_some_zero {x y : R} (h : W'.Nonsingular x y) : + (some x y h).sym2x 0 = ![x, 1, 0] := by + simp [sym2x] + +@[simp] +lemma sym2x_some_some {x y x' y' : R} (h : W'.Nonsingular x y) (h' : W'.Nonsingular x' y') : + (some x y h).sym2x (some x' y' h') = ![x * x', x + x', 1] := by + simp [sym2x] + +lemma sym2x_ne_zero [Nontrivial R] (P Q : W'.Point) : P.sym2x Q ≠ 0 := by + cases P <;> cases Q <;> simp [sym2x, xRep] + +lemma sym2x_comm (P Q : W'.Point) : P.sym2x Q = Q.sym2x P := by + cases P <;> cases Q <;> simp [← zero_def, mul_comm, add_comm] + +lemma sym2x_neg_left (P Q : W'.Point) : (-P).sym2x Q = P.sym2x Q := by + simp [sym2x] + +lemma sym2x_neg_right (P Q : W'.Point) : P.sym2x (-Q) = P.sym2x Q := by + simp [sym2x] + +end WeierstrassCurve.Affine.Point + end From 95284251ca354e7a5d6d432f27c4b3a8c889cb1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Mon, 22 Jun 2026 07:32:37 +0000 Subject: [PATCH 0233/1300] feat(Topology/SmallInductiveDimension): fix small style issues (#40878) We make some arguments implicit, change `Type` to `Type*`, and fix some capitalization. --- Mathlib/Topology/SmallInductiveDimension.lean | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/SmallInductiveDimension.lean b/Mathlib/Topology/SmallInductiveDimension.lean index 45e6ca64d319d1..c31d8e015a7647 100644 --- a/Mathlib/Topology/SmallInductiveDimension.lean +++ b/Mathlib/Topology/SmallInductiveDimension.lean @@ -48,21 +48,25 @@ class inductive HasSmallInductiveDimensionLT.{u} : (h : ∀ U ∈ s, HasSmallInductiveDimensionLT ↑(frontier U) n) : HasSmallInductiveDimensionLT X (n + 1) -variable (X : Type) [TopologicalSpace X] +variable {X : Type*} [TopologicalSpace X] +variable (X) in /-- A topological space has dimension `≤ n` if it has dimension `< n + 1`. -/ abbrev HasSmallInductiveDimensionLE (n : ℕ) := HasSmallInductiveDimensionLT X (n + 1) +variable (X) in /-- The small inductive dimension of a topological space. -/ noncomputable def smallInductiveDimension : WithBot ℕ∞ := sInf {n : WithBot ℕ∞ | ∀ (i : ℕ), n < i → HasSmallInductiveDimensionLT X i} -lemma HasSmallInductiveDimensionLT_zero_iff : - HasSmallInductiveDimensionLT X 0 ↔ IsEmpty X := +lemma hasSmallInductiveDimensionLT_zero_iff : HasSmallInductiveDimensionLT X 0 ↔ IsEmpty X := ⟨fun h ↦ by cases h; assumption, fun _ ↦ .zero⟩ -lemma HasSmallInductiveDimensionLT_one_iff : +@[deprecated (since := "2026-06-21")] +alias HasSmallInductiveDimensionLT_zero_iff := hasSmallInductiveDimensionLT_zero_iff + +lemma hasSmallInductiveDimensionLT_one_iff : HasSmallInductiveDimensionLT X 1 ↔ IsTopologicalBasis { s : Set X | IsClopen s } := by constructor · intro (.succ _ s hs h) @@ -72,4 +76,7 @@ lemma HasSmallInductiveDimensionLT_one_iff : rwa [isEmpty_coe_sort, (hs.isOpen hU).frontier_eq, sdiff_eq_empty] at ‹_› · exact fun h ↦ .succ 0 _ h fun _ hU ↦ hU.frontier_eq ▸ .zero +@[deprecated (since := "2026-06-21")] +alias HasSmallInductiveDimensionLT_one_iff := hasSmallInductiveDimensionLT_one_iff + end From ba54f179f5b1ee123ef7bba7815ea5e4ea89fd07 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 22 Jun 2026 07:32:39 +0000 Subject: [PATCH 0234/1300] feat(Topology/MetricSpace): fix two non-terminal simps (#40882) Co-authored-by: Batixx --- Mathlib/Topology/MetricSpace/PiNat.lean | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index a074e24c734a3a..61b1c66783476d 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -933,21 +933,18 @@ lemma min_dist_le_dist_pi (x y : ∀ i, F i) (i : ι) : lemma dist_le_dist_pi_of_dist_lt (h : dist x y < 2⁻¹ ^ encode i) : dist (x i) (y i) ≤ dist x y := by simpa only [not_le.2 h, false_or] using min_le_iff.1 (min_dist_le_dist_pi x y i) --- TODO: fix two non-terminal simps below; second one uses a long lemma list -set_option linter.flexible false in /-- Given a countable family of metric spaces, one may put a distance on their product `Π i, E i`. It is highly non-canonical, though, and therefore not registered as a global instance. The distance we use here is `dist x y = ∑' i, min (1/2)^(encode i) (dist (x i) (y i))`. -/ @[instance_reducible] protected def pseudoMetricSpace : PseudoMetricSpace (∀ i, F i) := - PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist - (fun x y ↦ by simp [dist_eq_tsum]; positivity) fun x y ↦ by - rw [edist_eq_tsum, dist_eq_tsum, - ENNReal.ofReal_tsum_of_nonneg (fun _ ↦ by positivity) (dist_summable ..)] - simp [edist, ENNReal.inv_pow] - congr! with a - exact PseudoMetricSpace.edist_dist (x a) (y a) + PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist (fun x y ↦ by rw [dist_eq_tsum]; positivity) + fun x y ↦ by + rw [edist_eq_tsum, dist_eq_tsum, + ENNReal.ofReal_tsum_of_nonneg (fun _ ↦ by positivity) (dist_summable ..)] + congr! with a + simp [edist, ENNReal.inv_pow, PseudoMetricSpace.edist_dist (x a) (y a)] end PseudoMetricSpace From ed5d9e9233c1ea57f266569649134b163424ae9f Mon Sep 17 00:00:00 2001 From: Brian Nugent Date: Mon, 22 Jun 2026 07:51:29 +0000 Subject: [PATCH 0235/1300] feat(CategoryTheory/Order): Lattice Homs preserve limits and colimits (#39992) Provides instances for when [OrderHom.toFunctor](https://leanprover-community.github.io/mathlib4_docs/Mathlib/CategoryTheory/Category/Preorder.html#OrderHom.toFunctor) preserves limits and colimits. Co-authored-by: Brian-Nugent --- Mathlib.lean | 1 + .../Limits/Preserves/Lattice.lean | 104 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 Mathlib/CategoryTheory/Limits/Preserves/Lattice.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0b00953c68055d..80bad97308d364 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2871,6 +2871,7 @@ public import Mathlib.CategoryTheory.Limits.Preserves.Filtered public import Mathlib.CategoryTheory.Limits.Preserves.Finite public import Mathlib.CategoryTheory.Limits.Preserves.FunctorCategory public import Mathlib.CategoryTheory.Limits.Preserves.Grothendieck +public import Mathlib.CategoryTheory.Limits.Preserves.Lattice public import Mathlib.CategoryTheory.Limits.Preserves.Limits public import Mathlib.CategoryTheory.Limits.Preserves.Opposites public import Mathlib.CategoryTheory.Limits.Preserves.Over diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Lattice.lean b/Mathlib/CategoryTheory/Limits/Preserves/Lattice.lean new file mode 100644 index 00000000000000..627b4e7d2f6cab --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/Preserves/Lattice.lean @@ -0,0 +1,104 @@ +/- +Copyright (c) 2026 Brian Nugent. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Brian Nugent +-/ +module + +public import Mathlib.CategoryTheory.Limits.Lattice +public import Mathlib.CategoryTheory.Limits.Preserves.Finite +public import Mathlib.Order.ConditionallyCompleteLattice.Basic +public import Mathlib.Order.Hom.CompleteLattice + +/-! +# Lattice Homs that Preserve Limits and Colimits + +This file provides instances for when OrderHom.toFunctor preserves limits/colimits. +In particular, if `f` preserves finite infs/sups (i.e. is from a InfTopHomClass/SupBotHomClass) +then `(toOrderHom f).toFunctor` preserves finite limits/colimits. If `f` preserves +arbitrary infs/sups (i.e. is from a sInfHomClass/sSupHomClass) then `(toOrderHom f).toFunctor` +preserves all limits/colimits. + +-/ + +public section + +open OrderHomClass + +namespace CategoryTheory.Limits.CompleteLattice + +universe w w' u v + +variable {α : Type u} {β : Type v} {F : Type*} [FunLike F α β] (f : F) + +section + +variable [SemilatticeInf α] [OrderTop α] [SemilatticeInf β] [OrderTop β] [InfTopHomClass F α β] + +instance preservesLimit_finite_toFunctor {J : Type w} [SmallCategory J] + [FinCategory J] (K : J ⥤ α) : PreservesLimit K (toOrderHom f).toFunctor := + preservesLimit_of_preserves_limit_cone (finiteLimitCone K).isLimit <| + (finiteLimitCone _).isLimit.ofIsoLimit + (Cone.ext (eqToIso (show Finset.univ.inf _ = f _ by aesop)) (by subsingleton)) + +instance preservesLimitsOfShape_finite_toFunctor {J : Type w} [SmallCategory J] [FinCategory J] : + PreservesLimitsOfShape J (toOrderHom f).toFunctor where + +instance : PreservesFiniteLimits (toOrderHom f).toFunctor where + preservesFiniteLimits _ _ _ := inferInstance + +end + +section + +variable [SemilatticeSup α] [OrderBot α] [SemilatticeSup β] [OrderBot β] [SupBotHomClass F α β] + +instance preservesColimit_finite_toFunctor {J : Type w} [SmallCategory J] + [FinCategory J] (K : J ⥤ α) : PreservesColimit K (toOrderHom f).toFunctor := + preservesColimit_of_preserves_colimit_cocone (finiteColimitCocone K).isColimit <| + (finiteColimitCocone _).isColimit.ofIsoColimit + (Cocone.ext (eqToIso (show Finset.univ.sup _ = f _ by aesop)) (by subsingleton)) + +instance preservesColimitsOfShape_finite_toFunctor {J : Type w} [SmallCategory J] + [FinCategory J] : PreservesColimitsOfShape J (toOrderHom f).toFunctor where + +instance : PreservesFiniteColimits (toOrderHom f).toFunctor where + preservesFiniteColimits _ _ _ := inferInstance + +end + +section + +variable [CompleteLattice α] [CompleteLattice β] + +instance preservesLimit_toFunctor [sInfHomClass F α β] {J : Type w} [Category.{w'} J] + (K : J ⥤ α) : PreservesLimit K (toOrderHom f).toFunctor := + preservesLimit_of_preserves_limit_cone (limitCone K).isLimit <| + (limitCone _).isLimit.ofIsoLimit (Cone.ext (eqToIso (by aesop)) (by subsingleton)) + +instance preservesLimitsOfShape_toFunctor [sInfHomClass F α β] {J : Type w} [Category.{w'} J] : + PreservesLimitsOfShape J (toOrderHom f).toFunctor where + +instance preservesLimitsOfSize_toFunctor [sInfHomClass F α β] : + PreservesLimitsOfSize.{w', w} (toOrderHom f).toFunctor where + +instance preservesLimits_toFunctor [sInfHomClass F α β] : + PreservesLimits (toOrderHom f).toFunctor where + +instance preservesColimit_toFunctor [sSupHomClass F α β] {J : Type w} [Category.{w'} J] + (K : J ⥤ α) : PreservesColimit K (toOrderHom f).toFunctor := + preservesColimit_of_preserves_colimit_cocone (colimitCocone K).isColimit <| + (colimitCocone _).isColimit.ofIsoColimit (Cocone.ext (eqToIso (by aesop)) (by subsingleton)) + +instance preservesColimitsOfShape_toFunctor [sSupHomClass F α β] {J : Type w} [Category.{w'} J] : + PreservesColimitsOfShape J (toOrderHom f).toFunctor where + +instance preservesColimitsOfSize_toFunctor [sSupHomClass F α β] : + PreservesColimitsOfSize.{w', w} (toOrderHom f).toFunctor where + +instance preservesColimits_toFunctor [sSupHomClass F α β] : + PreservesColimits (toOrderHom f).toFunctor where + +end + +end CategoryTheory.Limits.CompleteLattice From 0489999bd41b243c63f843350f153950605f0206 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 22 Jun 2026 08:35:01 +0000 Subject: [PATCH 0236/1300] fix: correct differential geometry elaborators around the tangent bundle (#40051) The previous logic was simply wrong --- it was just masked in practice because the `fromBaseInfo` strategy is tried first. (Indeed, just changing the order makes both the build in `VectorBundle/Tangent` as well as a number of tests fail.) This bugfix is important as #40047 (another elaborators bug fix) will change things, so the tangent space strategy is tried first. --- Mathlib/Geometry/Manifold/Notation.lean | 4 +-- .../Notation/Advanced.lean | 29 ++++++------------- .../Notation/Delaborators.lean | 2 +- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index c742d0a4e9df21..5de3d94fd0fe6e 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -394,8 +394,8 @@ where fromTotalSpace : TermElabM FindModelResult := do match_expr e with | Bundle.TotalSpace _ F V => do - if let some m ← tryStrategy m!"From base info" (fromTotalSpace.fromBaseInfo F) then return m if let some m ← tryStrategy m!"TangentSpace" (fromTotalSpace.tangentSpace V) then return m + if let some m ← tryStrategy m!"From base info" (fromTotalSpace.fromBaseInfo F) then return m throwError "Having a TotalSpace as source is not yet supported" | _ => throwError "`{e}` is not a `Bundle.TotalSpace`." /-- Attempt to use the provided `baseInfo` to find a model. -/ @@ -423,7 +423,7 @@ where | TangentSpace _k _ _E _ _ _H _ I M _ _ => do trace[Elab.DiffGeo.MDiff] "`{V}` is the total space of the `TangentBundle` of `{M}`" let srcIT : Term ← Term.exprToSyntax I - let resTerm : Term ← ``(ModelWithCorners.prod $srcIT (ModelWithCorners.tangent $srcIT)) + let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT) Term.elabTerm resTerm none | _ => throwError "`{V}` is not a `TangentSpace`" /-- Attempt to find a model on a `TangentBundle` -/ diff --git a/MathlibTest/DifferentialGeometry/Notation/Advanced.lean b/MathlibTest/DifferentialGeometry/Notation/Advanced.lean index 2355bf61ff17c2..f6e277d4f8ae00 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Advanced.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Advanced.lean @@ -195,9 +195,7 @@ section interaction -- Note: these tests might be incomplete; extend as needed! -/-- -info: MDifferentiableAt I (I.prod (modelWithCornersSelf 𝕜 E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop --/ +/-- info: MDifferentiableAt I I.tangent fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ #guard_msgs in #check MDiffAt (T% X) @@ -234,13 +232,10 @@ Hint: Additional diagnostic information may be available using the `set_option d --- trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `TotalSpace F (TangentSpace I)` [Elab.DiffGeo.MDiff] ✅️ TotalSpace - [Elab.DiffGeo.MDiff] 💥️ From base info - [Elab.DiffGeo.MDiff] Failed with error: - No `baseInfo` provided [Elab.DiffGeo.MDiff] ✅️ TangentSpace [Elab.DiffGeo.MDiff] `TangentSpace I` is the total space of the `TangentBundle` of `M` - [Elab.DiffGeo.MDiff] Found model: `I.prod I.tangent` - [Elab.DiffGeo.MDiff] Found model: `I.prod I.tangent` + [Elab.DiffGeo.MDiff] Found model: `I.tangent` + [Elab.DiffGeo.MDiff] Found model: `I.tangent` [Elab.DiffGeo.MDiff] Finding a model with corners for: `F` [Elab.DiffGeo.MDiff] 💥️ TotalSpace [Elab.DiffGeo.MDiff] Failed with error: @@ -956,9 +951,8 @@ variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] {x : M} /-- -info: mfderiv I (I.prod (modelWithCornersSelf 𝕜 E)) (fun m ↦ TotalSpace.mk' E m (X m)) - x : ContinuousLinearMap (RingHom.id 𝕜) (TangentSpace I x) - (TangentSpace (I.prod (modelWithCornersSelf 𝕜 E)) (TotalSpace.mk' E x (X x))) +info: mfderiv I I.tangent (fun m ↦ TotalSpace.mk' E m (X m)) + x : ContinuousLinearMap (RingHom.id 𝕜) (TangentSpace I x) (TangentSpace I.tangent (TotalSpace.mk' E x (X x))) -/ #guard_msgs in #check mfderiv% (T% X) x @@ -1099,24 +1093,19 @@ variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] {x : M} /-- -info: mfderiv I (I.prod (modelWithCornersSelf 𝕜 E)) (fun m ↦ TotalSpace.mk' E m (X m)) - x : ContinuousLinearMap (RingHom.id 𝕜) (TangentSpace I x) - (TangentSpace (I.prod (modelWithCornersSelf 𝕜 E)) (TotalSpace.mk' E x (X x))) +info: mfderiv I I.tangent (fun m ↦ TotalSpace.mk' E m (X m)) + x : ContinuousLinearMap (RingHom.id 𝕜) (TangentSpace I x) (TangentSpace I.tangent (TotalSpace.mk' E x (X x))) -/ #guard_msgs in #check mfderiv% (T% X) x variable {dXm : TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, E)) (TotalSpace.mk' E x (X x))} -/-- -info: HasMFDerivAt I (I.prod (modelWithCornersSelf 𝕜 E)) (fun m ↦ TotalSpace.mk' E m (X m)) x dXm : Prop --/ +/-- info: HasMFDerivAt I I.tangent (fun m ↦ TotalSpace.mk' E m (X m)) x dXm : Prop -/ #guard_msgs in #check HasMFDerivAt% (T% X) x dXm -/-- -info: HasMFDerivWithinAt I (I.prod (modelWithCornersSelf 𝕜 E)) (fun m ↦ TotalSpace.mk' E m (X m)) t x dXm : Prop --/ +/-- info: HasMFDerivWithinAt I I.tangent (fun m ↦ TotalSpace.mk' E m (X m)) t x dXm : Prop -/ #guard_msgs in variable {t : Set M} in #check HasMFDerivAt[t] (T% X) x dXm diff --git a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean index f943715dd466e2..be21a824b56d34 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean @@ -70,7 +70,7 @@ variable #guard_msgs in #check mfderiv% f x -/-- info: mfderiv% (T% v) x : TangentSpace I x →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, E)) ⟨x, v x⟩ -/ +/-- info: mfderiv% (T% v) x : TangentSpace I x →L[ℝ] TangentSpace I.tangent ⟨x, v x⟩ -/ #guard_msgs in #check mfderiv% (T% v) x From af5bc61fbfcda97e746a8fbd5c3097ff4442034e Mon Sep 17 00:00:00 2001 From: Yizheng Zhu Date: Mon, 22 Jun 2026 09:12:55 +0000 Subject: [PATCH 0237/1300] chore(ModelTheory): fix hypo of `realize_liftAt` (#39004) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit changes the hypo of `realize_liftAt` from the incorrect `(hmn : m + n' ≤ n + 1)` to the correct `(hmn : m ≤ n)` --- Mathlib/ModelTheory/Semantics.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index dfcdfdc43b2eed..e10d87952cd7e7 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -391,7 +391,7 @@ theorem realize_relabel {m n : ℕ} {φ : L.BoundedFormula α n} {g : α → β apply realize_mapTermRel_add_castLe <;> simp theorem realize_liftAt {n n' m : ℕ} {φ : L.BoundedFormula α n} {v : α → M} {xs : Fin (n + n') → M} - (hmn : m + n' ≤ n + 1) : + (hmn : m ≤ n) : (φ.liftAt n' m).Realize v xs ↔ φ.Realize v (xs ∘ fun i => if ↑i < m then Fin.castAdd n' i else Fin.addNat i n') := by rw [liftAt] @@ -402,7 +402,7 @@ theorem realize_liftAt {n n' m : ℕ} {φ : L.BoundedFormula α n} {v : α → M | imp _ _ ih1 ih2 => simp only [mapTermRel, Realize, ih1 hmn, ih2 hmn] | @all k _ ih3 => have h : k + 1 + n' = k + n' + 1 := by rw [add_assoc, add_comm 1 n', ← add_assoc] - simp only [mapTermRel, Realize, realize_castLE_of_eq h, ih3 (hmn.trans k.succ.le_succ)] + simp only [mapTermRel, Realize, realize_castLE_of_eq h, ih3 (hmn.trans k.le_succ)] refine forall_congr' fun x => iff_eq_eq.mpr (congr rfl (funext (Fin.lastCases ?_ fun i => ?_))) · simp only [Function.comp_apply, val_last, snoc_last] refine (congr rfl (Fin.ext ?_)).trans (snoc_last _ _) From 22616d001e1813f1fff7c6f07ec73d0a94d2ac92 Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Mon, 22 Jun 2026 09:25:55 +0000 Subject: [PATCH 0238/1300] feat: add specialized grind sets (#39370) This adds two grind attributes for specialized tactics. See module doc for more information and motivation. This PR does not tag any lemmas yet. [Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/small.20specialized.20grind.20sets/with/595132109) --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + Mathlib/Tactic/Common.lean | 1 + Mathlib/Tactic/GrindAttrs.lean | 110 +++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 Mathlib/Tactic/GrindAttrs.lean diff --git a/Mathlib.lean b/Mathlib.lean index 80bad97308d364..e5d08925dd03bc 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7289,6 +7289,7 @@ public import Mathlib.Tactic.GRewrite public import Mathlib.Tactic.GRewrite.Core public import Mathlib.Tactic.GRewrite.Elab public import Mathlib.Tactic.Generalize +public import Mathlib.Tactic.GrindAttrs public import Mathlib.Tactic.Group public import Mathlib.Tactic.GuardGoalNums public import Mathlib.Tactic.GuardHypNums diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 50686dca468d2e..02d86792ef5678 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -140,6 +140,7 @@ public import Mathlib.Tactic.GRewrite public import Mathlib.Tactic.GRewrite.Core public import Mathlib.Tactic.GRewrite.Elab public import Mathlib.Tactic.Generalize +public import Mathlib.Tactic.GrindAttrs public import Mathlib.Tactic.Group public import Mathlib.Tactic.GuardGoalNums public import Mathlib.Tactic.GuardHypNums diff --git a/Mathlib/Tactic/Common.lean b/Mathlib/Tactic/Common.lean index 6eb2bcff5c13ad..e35e792b618078 100644 --- a/Mathlib/Tactic/Common.lean +++ b/Mathlib/Tactic/Common.lean @@ -63,6 +63,7 @@ public import Mathlib.Tactic.Find public import Mathlib.Tactic.FunProp public import Mathlib.Tactic.GCongr public import Mathlib.Tactic.GRewrite +public import Mathlib.Tactic.GrindAttrs public import Mathlib.Tactic.GuardGoalNums public import Mathlib.Tactic.GuardHypNums public import Mathlib.Tactic.HigherOrder diff --git a/Mathlib/Tactic/GrindAttrs.lean b/Mathlib/Tactic/GrindAttrs.lean new file mode 100644 index 00000000000000..f36fea44632151 --- /dev/null +++ b/Mathlib/Tactic/GrindAttrs.lean @@ -0,0 +1,110 @@ +/- +Copyright (c) 2026 Floris van Doorn. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Floris van Doorn +-/ + +module + +public import Lean.Meta.Tactic.Grind.RegisterCommand +public import Mathlib.Init + +/-! +# Custom grind-sets + +In this file we declare custom grind attributes and tactics that call grind using only these grind +attributes. These grind sets are helpful because they can contain a lot of specialized ways to +prove a particular problem. + +Currently, this implements the `compactness` and `closedness` grind attribute and tactic. + +## Usage Notes + +These tactics can be useful for various purposes: +* directly as a tactic: `by compactness` +* as auto-params for lemmas: `(h : IsCompact K := by compactness)` +* as discharger for other tactics, e.g. `fun_prop (disch := compactness)` +* You can also use the grind sets directly: `grind only [compactness, closedness]`. + This is especially useful if you want to combine multiple grind sets. + +## Implementation Notes + +We define these grind sets so that we can aggressively tag lemmas in one particular topic as +grind lemmas for a particular grind set. For the default grind set we should be a lot +more careful with tagging lemmas, to avoid slowing down `grind`, but since these specialized grind +attributes don't have any tagged lemmas outside its specialized domain, it should still be +performant. + +These tactics will not use the full power of grind, and could disable some of the grind engines if +these would slow down these tactics. We could have alternatively used a tactic similar to +`apply_rules` here, but we think that the efficient implementation of `grind` is helpful even for +these simpler tactics. For example, we can safely tag both the following lemmas, and `grind` will +add both pairs of hypotheses to the whiteboard without having to backtrack. +``` +IsCompact.inter_left : IsClosed s → IsCompact t → IsCompact (s ∩ t) +IsCompact.inter_right : IsCompact s → IsClosed t → IsCompact (s ∩ t) +``` + +We will tag transition theorems, e.g. `Set.Finite.isCompact : Finite s → IsCompact s` should be +tagged `@[compactness .]`, even if `compactness` won't contain lemmas about finite sets. +The advantages of this are that we can use local finiteness hypotheses, and this will ensure that +the different grind sets will interact well with each other. For the same reason we tag lemmas +that involve other properties, e.g. `IsCompact.inter_left` + +## To do + +* Implement other grind sets, e.g. `boundedness`, `countability`, `connectedness`, ... + +-/ + +open Lean Parser Tactic + +/-- A hash set of the grind attributes in Mathlib. + +When adding a new grind attribute, manually add it to this hash set as well. -/ +def Mathlib.grindAttrs : Std.HashSet Name := + {`compactness, `closedness} + +/-- The `compactness` attribute is a custom grind-set specialized to prove that sets are compact. +It is called by the `compactness` tactic. -/ +register_grind_attr compactness + +/-- +`compactness` is a simple tactic that tries various lemmas to prove that a set is compact. +It is implemented using `grind`, and has the same configuration options as `grind`. + +Use `grind only [compactness, closedness]` instead if you want to prove that the closure of sets are +compact. + +It also exists as a grind attribute, and can be combined with other grind attributes using +`grind only [compactness, ...]`. +-/ +macro (name := compactnessTac) "compactness" config:optConfig : tactic => + -- note: directly giving `compactness` as argument in the syntax quotation below is treated + -- as an unknown identifier by the hygiene system. + `(tactic|grind $config only [$(mkIdent `compactness):term]) + +@[inherit_doc compactnessTac] +macro "compactness?" config:optConfig : tactic => + `(tactic|grind? $config only [$(mkIdent `compactness):term]) + +/-- The `closedness` attribute is a custom grind-set specialized to prove that sets are closed. +It is called by the `closedness` tactic. -/ +register_grind_attr closedness + +/-- +`closedness` is a simple tactic that tries various lemmas to prove that a set is closed, +and reasoning about the closure of sets. +It is implemented using `grind`, and has the same configuration options as `grind`. + +It also exists as a grind attribute, and can be combined with other grind attributes using +`grind only [closedness, ...]`. +-/ +macro (name := closednessTac) "closedness" config:optConfig : tactic => + -- note: directly giving `closedness` as argument in the syntax quotation below is treated + -- as an unknown identifier by the hygiene system. + `(tactic|grind $config only [$(mkIdent `closedness):term]) + +@[inherit_doc closednessTac] +macro "closedness?" config:optConfig : tactic => + `(tactic|grind? $config only [$(mkIdent `closedness):term]) From 2c7836ba02cbff369f358674eff9877f27cbf0ac Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:16:19 +0000 Subject: [PATCH 0239/1300] chore(Geometry/Manifold): make some doc-strings follow the style guide (#39729) such as, by them beginning with the object they are defining as a subject. This will yield much better doc-strings for the differential geometry elaborators in #39677. It also increases conformance with the [documentation style guide](https://github.com/leanprover/lean4/blob/master/doc/style.md). Inspired by the MI retreat in Lisbon. --- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 31 +++++++++----- Mathlib/Geometry/Manifold/MFDeriv/Defs.lean | 17 ++++---- .../Manifold/MFDeriv/NormedSpace.lean | 40 +++++++++++++------ 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index e823fee3758e25..c4a9815c985c17 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -160,18 +160,22 @@ theorem contDiffWithinAtProp_id (x : H) : ContDiffWithinAtProp I I n id univ x : · simp only [mfld_simps] variable (I I') in -/-- A function is `n` times continuously differentiable within a set at a point in a manifold if -it is continuous and it is `n` times continuously differentiable in this set around this point, when -read in the preferred chart at this point. +/-- `ContMDiffWithinAt I I' n f x` indicates that the function `f : M → M'` between manifolds +is `n` times continuously differentiable at `x : M` within the set `s`. + +`f` is `n` times continuously differentiable within `s` at `x` if it is continuous and it is `n` +times continuously differentiable in this set around `x`, when read in the preferred chart at `x`. The parameter `n` belongs to `ℕ∞ω` (accessible in the `ContDiff` scope), i.e. it can be a natural number, `∞`, or `ω`, where `C^ω` corresponds to analytic functions. -/ def ContMDiffWithinAt (n : ℕ∞ω) (f : M → M') (s : Set M) (x : M) := LiftPropWithinAt (ContDiffWithinAtProp I I' n) f s x variable (I I') in -/-- A function is `n` times continuously differentiable at a point in a manifold if -it is continuous and it is `n` times continuously differentiable around this point, when -read in the preferred chart at this point. +/-- `ContMDiffAt I I' n f x` indicates that the function `f : M → M'` between manifolds +is `n` times continuously differentiable at `x : M`. + +`f` is `n` times continuously differentiable at `x` if it is continuous and it is `n` times +continuously differentiable around `x`, when read in the preferred chart at `x`. The parameter `n` belongs to `ℕ∞ω` (accessible in the `ContDiff` scope), i.e. it can be a natural number, `∞`, or `ω`, where `C^ω` corresponds to analytic functions. -/ def ContMDiffAt (n : ℕ∞ω) (f : M → M') (x : M) := @@ -185,8 +189,11 @@ theorem contMDiffAt_iff {n : ℕ∞ω} {f : M → M'} {x : M} : liftPropAt_iff.trans <| by rw [ContDiffWithinAtProp, preimage_univ, univ_inter]; rfl variable (I I') in -/-- A function is `n` times continuously differentiable in a set of a manifold if it is continuous -and, for any pair of points, it is `n` times continuously differentiable on this set in the charts +/-- `ContMDiffOn I I' n f s` indicates that the function `f : M → M'` between manifolds +is `n` times continuously differentiable in a set `s : Set M`. + +`f` is `n` times continuously differentiable on `s` if it is continuous on `s` and, +for any pair of points, it is `n` times continuously differentiable `s` in the charts around these points. The parameter `n` belongs to `ℕ∞ω` (accessible in the `ContDiff` scope), i.e. it can be a natural number, `∞`, or `ω`, where `C^ω` corresponds to analytic functions. -/ @@ -194,9 +201,11 @@ def ContMDiffOn (n : ℕ∞ω) (f : M → M') (s : Set M) := ∀ x ∈ s, ContMDiffWithinAt I I' n f s x variable (I I') in -/-- A function is `n` times continuously differentiable in a manifold if it is continuous -and, for any pair of points, it is `n` times continuously differentiable in the charts -around these points. +/-- `ContMDiff I I' n f` indicates that the function `f : M → M'` between manifolds +is `n` times continuously differentiable. + +`f` is `n` times continuously differentiable if it is continuous and, for any pair of points, +it is `n` times continuously differentiable in the charts around these points. The parameter `n` belongs to `ℕ∞ω` (accessible in the `ContDiff` scope), i.e. it can be a natural number, `∞`, or `ω`, where `C^ω` corresponds to analytic functions. -/ def ContMDiff (n : ℕ∞ω) (f : M → M') := diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean b/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean index f7e08d8e323f6f..886ab2f23b95bb 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean @@ -316,9 +316,9 @@ def HasMFDerivAt (f : M → M') (x : M) (f' : TangentSpace I x →L[𝕜] Tangen open Classical in variable (I I') in -/-- Let `f` be a function between two manifolds. Then `mfderivWithin I I' f s x` is the -derivative of `f` at `x` within `s`, as a continuous linear map from the tangent space at `x` to the -tangent space at `f x`. -/ +/-- `mfderivWithin I I' f s x`, given a function `f` between two manifolds, +is the derivative of `f` at `x` within `s`, +as a continuous linear map from the tangent space at `x` to the tangent space at `f x`. -/ def mfderivWithin (f : M → M') (s : Set M) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I' (f x) := if MDifferentiableWithinAt I I' f s x then (fderivWithin 𝕜 (writtenInExtChartAt I I' x f) ((extChartAt I x).symm ⁻¹' s ∩ range I) @@ -328,21 +328,22 @@ def mfderivWithin (f : M → M') (s : Set M) (x : M) : TangentSpace I x →L[ open Classical in variable (I I') in -/-- Let `f` be a function between two manifolds. Then `mfderiv I I' f x` is the derivative of -`f` at `x`, as a continuous linear map from the tangent space at `x` to the tangent space at -`f x`. -/ +/-- `mfderiv I I' f x`, given a function `f` between two manifolds, is the derivative of `f` at `x`, +as a continuous linear map from the tangent space at `x` to the tangent space at `f x`. -/ def mfderiv (f : M → M') (x : M) : TangentSpace I x →L[𝕜] TangentSpace I' (f x) := if MDifferentiableAt I I' f x then (fderivWithin 𝕜 (writtenInExtChartAt I I' x f : E → E') (range I) ((extChartAt I x) x) :) else 0 variable (I I') in -/-- The derivative within a set, as a map between the tangent bundles -/ +/-- `tangentMapWithin I I' f s` is the derivative of `f : M → M'` within a set `s`, +as a map between the tangent bundles `TM` and `TM'`. -/ def tangentMapWithin (f : M → M') (s : Set M) : TangentBundle I M → TangentBundle I' M' := fun p => ⟨f p.1, (mfderivWithin I I' f s p.1 : TangentSpace I p.1 → TangentSpace I' (f p.1)) p.2⟩ variable (I I') in -/-- The derivative, as a map between the tangent bundles -/ +/-- `tangentMap I I' f` is the derivative of `f : M → M'` as a map between the tangent bundles +`TM` and `TM'`. -/ def tangentMap (f : M → M') : TangentBundle I M → TangentBundle I' M' := fun p => ⟨f p.1, (mfderiv I I' f p.1 : TangentSpace I p.1 → TangentSpace I' (f p.1)) p.2⟩ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 1329b9ab42ef3b..f41ccc404fbbf6 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -9,22 +9,34 @@ public import Mathlib.Geometry.Manifold.Algebra.SMul public import Mathlib.Geometry.Manifold.ContMDiff.NormedSpace public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -/-! ## Equivalence of manifold differentiability with the basic definition for functions between +/-! # Equivalence of manifold differentiability with the basic definition for functions between vector spaces The API in this file is mostly copied from `Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean`, providing the same statements for higher smoothness. In this file, we do the same for differentiability. -In addition to the above, this file provides -* results about the differentiability of scalar multiplication (`mfderiv_smul` and friends), -* `mvfderiv`: the exterior derivative of a vector-valued function, as a section of the - cotangent bundle; adds notation `d% f` for `mvfderiv I f` via a custom elaborator scoped to the - `Manifold` namespace, with a corresponding delaborator, and - adds basic lemmas about `mvfderiv` (such as addition, subtraction, multiplication and constants). -* `mvfderivWithin` with notation `d[s]f` for `mvfderivWithin I f s` in the `Manifold` namespace: +## Main definitions + +In addition to the above, this file provides two important definitions. +* `mvfderiv I f x` is the manifold Fréchet derivative at `x : M` of a vector-valued function + `f : M → V`, but taking values in the target normed space `V` instead of `TangentSpace% (f x) V`. + Mathematically, this uses the global trivialization `T V ≅ V × V`, yielding an identification + `T_v V ≅ V` for each `v : V`. In Lean, we post-compose the differential `mfderiv% f x` with + `NormedSpace.fromTangentSpace`. If `V` is a field, this coincides with the exterior derivative + of `f` as a section of the cotangent bundle. + There is notation `d% f` for `mvfderiv I f` via a custom elaborator scoped to the + `Manifold` namespace, with a corresponding delaborator, +* `mvfderivWithin` with notation `d[s] f` for `mvfderivWithin I f s` in the `Manifold` namespace: the analogous concept within a set, with analogous API lemmas +## Main results + +This file contains +* results about the differentiability of scalar multiplication (`mfderiv_smul` and friends), +* basic lemmas about `mvfderiv` (such as addition, subtraction, multiplication and constants), +* analogous lemmas about `mvfderivWithin`. + -/ public section @@ -410,8 +422,10 @@ end smul /-! ### Exterior derivative of a vector-valued function -/ variable (I) in -/-- `mvfderiv I J f x` is the exterior derivative of a vector-valued function `g` on `M`, -as a section of the cotangent bundle. +/-- `mvfderivWithin I J f s x` is the `mfderiv` of a vector-valued function `f` on `M` at `x` +within the set `s`, but taking values in the target normed space directly. +The difference to `mfderivWithin` is explained in the module-docstring for +`Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean`. Future: this could be generalised to functions into additive torsors over abelian Lie groups. -/ @@ -421,8 +435,10 @@ noncomputable def mvfderivWithin (g : M → F) (s : Set M) : fun x ↦ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv[s] g x) variable (I) in -/-- The exterior derivative of a vector-valued function on `M`, -as a section of the cotangent bundle. +/-- `mvfderiv I J f x` is the `mfderiv` of a vector-valued function `f` on `M` at `x`, +but taking values in the target normed space directly. +The difference to `mfderiv` is explained in the module-docstring for +`Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean`. Future: this could be generalised to functions into additive torsors over abelian Lie groups. -/ From afa3779b5e1174c6e9203946595e42e9361db91d Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:16:22 +0000 Subject: [PATCH 0240/1300] fix: more complete model finding for a given manifold in context (#40075) When searching for a model with corners on a manifold, also try finding a model which is not just a local assumption, but the trivial model on a normed space or a non-trivially normed field. Minimised from an elaborator failure in Kevin Buzzard's Jacobian challenge. --- Mathlib/Geometry/Manifold/Notation.lean | 27 +++++++++++--- .../DifferentialGeometry/Notation/Basic.lean | 37 +++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 5de3d94fd0fe6e..0ed3b4eb3b185e 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -476,8 +476,8 @@ where | ChartedSpace H _ M _ => if ← withReducible (pureIsDefEq M e) then trace[Elab.DiffGeo.MDiff] "`{e}` is a charted space over `{H}` via `{inst}`" - return some H else - if ← withReducible (pureIsDefEq H e) then + return some H + else if ← withReducible (pureIsDefEq H e) then trace[Elab.DiffGeo.MDiff] "`{e}` is the charted space of `{M}` via `{inst}`" return some H else return none | _ => return none @@ -488,7 +488,24 @@ where | ModelWithCorners _ _ _ _ _ H' _ => do if ← withReducible (pureIsDefEq H' H) then return some fvar else return none | _ => return none - | throwError "Couldn't find a `ModelWithCorners` with model space `{H}` in the local context." + | trace[Elab.DiffGeo.MDiff] + "Couldn't find a `ModelWithCorners` with model space `{H}` in the local context." + -- Try a normed space, and a normed field as last alternatives. + let a ← findSomeLocalInstanceOf? ``NormedSpace fun inst type ↦ do + match_expr type with + | NormedSpace K E _ _ => + if ← withReducible (pureIsDefEq E H) then return some (inst, K) + else return none + | _ => return none + if let some (inst, K) := a then + trace[Elab.DiffGeo.MDiff] "`{H}` is a normed space over the field `{K}`" + return ← mkAppOptM ``modelWithCornersSelf #[K, none, H, none, inst] + trace[Elab.DiffGeo.MDiff] "Couldn't find a normed space structure on {H}` either: \ + assuming it is a non-trivially normed field" + -- Return the trivial model with corners: this will work if `H` is a normed field. + let eT : Term ← Term.exprToSyntax H + let iTerm : Term ← ``(𝓘($eT)) + Term.elabTerm iTerm none return m /-- Attempt to find a model with corners on a space of continuous linear maps -/ -- Note that (continuous) linear equivalences are not an abelian group, so are not a model with @@ -729,8 +746,8 @@ partial def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : Te let hint : MessageData := if e.hasExprMVar then .hint' "the expected type contains metavariables, \ maybe you need to provide an implicit argument" - else if tracing then m!"" else - .hint' "failures to find a model with corners can be debugged with the \ + else if tracing then m!"" + else .hint' "failures to find a model with corners can be debugged with the \ command `set_option trace.Elab.DiffGeo.MDiff true`." throwError "Could not find a model with corners for `{e}`.{hint}" where diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 36f1634c00a05f..4461fab938c58c 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -1035,6 +1035,43 @@ open ContDiff in -- for the ∞ notation end +/-! Inferring a model with corners on a normed space, for an `IsManifold` hypothesis -/ +section + +open scoped ContDiff + +variable {X Y : Type*} [TopologicalSpace X] [ChartedSpace ℝ X] [IsManifold 𝓘(ℝ) ω X] + [TopologicalSpace Y] [ChartedSpace ℝ Y] [IsManifold 𝓘(ℝ) ω Y] {f : X → Y} + +/-- +info: ContMDiff (modelWithCornersSelf Real Real) (modelWithCornersSelf Real Real) Top.top f : Prop +-/ +#guard_msgs in +#check CMDiff ω f + +variable {f : X → ℝ} in /-- +info: MDifferentiable (modelWithCornersSelf Real Real) (modelWithCornersSelf Real Real) f : Prop +-/ +#guard_msgs in #check MDiff f + +variable {X : Type*} [TopologicalSpace X] [ChartedSpace F X] [IsManifold 𝓘(𝕜, F) ω X] {f : X → 𝕜} in +/-- info: MDifferentiable (modelWithCornersSelf 𝕜 F) (modelWithCornersSelf 𝕜 𝕜) f : Prop -/ +#guard_msgs in +#check MDiff f + +-- This test is expected to fail: it passing would amount to guessing a model with corners on +-- a product of two normed spaces (which is ambiguous). +variable {X : Type*} [TopologicalSpace X] [ChartedSpace (F × F) X] [IsManifold 𝓘(𝕜, F × F) ω X] {f : X → 𝕜} in +/-- +error: Could not find a model with corners for `X`. + +Hint: failures to find a model with corners can be debugged with the command `set_option trace.Elab.DiffGeo.MDiff true`. +-/ +#guard_msgs in +#check MDiff f + +end + /-! Tests for the elaborators for `tangentMap(Within)` and `TangentSpace` -/ section From 3ee3f85eb48438ad4f8ce98b79a198f6573d5f70 Mon Sep 17 00:00:00 2001 From: Leo Diedering <129694072+ldiedering@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:16:24 +0000 Subject: [PATCH 0241/1300] refactor(MeasureTheory/Measure/Typeclasses/NoAtoms): rename `NoAtoms` to `NullSingletonClass` (#40809) Rename the class `NoAtoms` to `NullSingletonClass` as discussed [here](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/MeasureTheory.2ENoAtoms/with/574638121) and change all derivative names. --- Counterexamples/Phillips.lean | 2 +- Mathlib.lean | 2 +- Mathlib/Analysis/Convolution.lean | 6 +-- .../Constructions/BorelSpace/Real.lean | 4 +- Mathlib/MeasureTheory/Constructions/Pi.lean | 32 ++++++++---- .../Constructions/UnitInterval.lean | 4 +- Mathlib/MeasureTheory/Group/Measure.lean | 15 +++--- .../MeasureTheory/Integral/Bochner/Set.lean | 4 +- .../Integral/DominatedConvergence.lean | 18 +++---- .../MeasureTheory/Integral/IntegrableOn.lean | 4 +- .../Integral/IntegralEqImproper.lean | 2 +- .../Integral/IntervalAverage.lean | 16 +++--- .../Integral/IntervalIntegral/Basic.lean | 28 +++++----- Mathlib/MeasureTheory/Integral/Layercake.lean | 2 +- Mathlib/MeasureTheory/Measure/Dirac.lean | 5 +- .../Measure/Haar/NormedSpace.lean | 8 +-- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 17 ++++--- .../MeasureTheory/Measure/Lebesgue/Basic.lean | 13 +++-- Mathlib/MeasureTheory/Measure/OpenPos.lean | 4 +- Mathlib/MeasureTheory/Measure/Prod.lean | 8 +-- .../{NoAtoms.lean => NullSingletonClass.lean} | 51 +++++++++++-------- .../MeasureTheory/Measure/WithDensity.lean | 6 ++- Mathlib/MeasureTheory/Topology.lean | 4 +- .../NumberField/CanonicalEmbedding/Basic.lean | 13 ++--- .../Distributions/Gaussian/Fernique.lean | 11 ++-- .../Distributions/Gaussian/Real.lean | 6 ++- scripts/nolints_prime_decls.txt | 2 +- 27 files changed, 167 insertions(+), 120 deletions(-) rename Mathlib/MeasureTheory/Measure/Typeclasses/{NoAtoms.lean => NullSingletonClass.lean} (76%) diff --git a/Counterexamples/Phillips.lean b/Counterexamples/Phillips.lean index 1fc73e0eda9341..384d1931679214 100644 --- a/Counterexamples/Phillips.lean +++ b/Counterexamples/Phillips.lean @@ -432,7 +432,7 @@ theorem toFunctions_toMeasure [MeasurableSpace α] (μ : Measure α) [IsFiniteMe set_option backward.isDefEq.respectTransparency false in theorem toFunctions_toMeasure_continuousPart [MeasurableSpace α] [MeasurableSingletonClass α] - (μ : Measure α) [IsFiniteMeasure μ] [NoAtoms μ] (s : Set α) (hs : MeasurableSet s) : + (μ : Measure α) [IsFiniteMeasure μ] [NullSingletonClass μ] (s : Set α) (hs : MeasurableSet s) : μ.extensionToBoundedFunctions.toBoundedAdditiveMeasure.continuousPart s = μ.real s := by let f := μ.extensionToBoundedFunctions.toBoundedAdditiveMeasure change f (univ \ f.discreteSupport ∩ s) = μ.real s diff --git a/Mathlib.lean b/Mathlib.lean index e5d08925dd03bc..7a3a3e97044a3a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5590,7 +5590,7 @@ public import Mathlib.MeasureTheory.Measure.TightNormed public import Mathlib.MeasureTheory.Measure.Tilted public import Mathlib.MeasureTheory.Measure.Trim public import Mathlib.MeasureTheory.Measure.Typeclasses.Finite -public import Mathlib.MeasureTheory.Measure.Typeclasses.NoAtoms +public import Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass public import Mathlib.MeasureTheory.Measure.Typeclasses.Probability public import Mathlib.MeasureTheory.Measure.Typeclasses.SFinite public import Mathlib.MeasureTheory.Measure.Typeclasses.ZeroOne diff --git a/Mathlib/Analysis/Convolution.lean b/Mathlib/Analysis/Convolution.lean index b35fb5ee876b75..6b01e33224dd8d 100644 --- a/Mathlib/Analysis/Convolution.lean +++ b/Mathlib/Analysis/Convolution.lean @@ -946,7 +946,7 @@ noncomputable def posConvolution (f : ℝ → E) (g : ℝ → E') (L : E →L[ indicator (Ioi (0 : ℝ)) fun x => ∫ t in 0..x, L (f t) (g (x - t)) ∂ν theorem posConvolution_eq_convolution_indicator (f : ℝ → E) (g : ℝ → E') (L : E →L[ℝ] E' →L[ℝ] F) - (ν : Measure ℝ := by volume_tac) [NoAtoms ν] : + (ν : Measure ℝ := by volume_tac) [NullSingletonClass ν] : posConvolution f g L ν = convolution (indicator (Ioi 0) f) (indicator (Ioi 0) g) L ν := by ext1 x rw [convolution, posConvolution, indicator] @@ -974,7 +974,7 @@ theorem posConvolution_eq_convolution_indicator (f : ℝ → E) (g : ℝ → E') · rw [indicator_of_notMem (mem_Ioi.not.mpr ht), map_zero, zero_apply] theorem integrable_posConvolution {f : ℝ → E} {g : ℝ → E'} {μ ν : Measure ℝ} [SFinite μ] - [SFinite ν] [IsAddRightInvariant μ] [NoAtoms ν] (hf : IntegrableOn f (Ioi 0) ν) + [SFinite ν] [IsAddRightInvariant μ] [NullSingletonClass ν] (hf : IntegrableOn f (Ioi 0) ν) (hg : IntegrableOn g (Ioi 0) μ) (L : E →L[ℝ] E' →L[ℝ] F) : Integrable (posConvolution f g L ν) μ := by rw [← integrable_indicator_iff (measurableSet_Ioi : MeasurableSet (Ioi (0 : ℝ)))] at hf hg @@ -985,7 +985,7 @@ theorem integrable_posConvolution {f : ℝ → E} {g : ℝ → E'} {μ ν : Meas of their integrals over this set. (Compare `integral_convolution` for the two-sided convolution.) -/ theorem integral_posConvolution [CompleteSpace E] [CompleteSpace E'] [CompleteSpace F] {μ ν : Measure ℝ} - [SFinite μ] [SFinite ν] [IsAddRightInvariant μ] [NoAtoms ν] {f : ℝ → E} {g : ℝ → E'} + [SFinite μ] [SFinite ν] [IsAddRightInvariant μ] [NullSingletonClass ν] {f : ℝ → E} {g : ℝ → E'} (hf : IntegrableOn f (Ioi 0) ν) (hg : IntegrableOn g (Ioi 0) μ) (L : E →L[ℝ] E' →L[ℝ] F) : ∫ x : ℝ in Ioi 0, ∫ t : ℝ in 0..x, L (f t) (g (x - t)) ∂ν ∂μ = L (∫ x : ℝ in Ioi 0, f x ∂ν) (∫ x : ℝ in Ioi 0, g x ∂μ) := by diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean index c47e8ea5d91b12..f33dd9c3dc6795 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean @@ -7,7 +7,7 @@ module public import Mathlib.MeasureTheory.Constructions.BorelSpace.Order public import Mathlib.MeasureTheory.MeasurableSpace.Prod -public import Mathlib.MeasureTheory.Measure.Typeclasses.NoAtoms +public import Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass public import Mathlib.Topology.Instances.Real.Lemmas /-! @@ -573,7 +573,7 @@ lemma tendsto_measure_Icc_nhdsWithin_right (b : ℝ) : intro s hs simpa using mem_of_mem_nhds hs -lemma tendsto_measure_Icc [NoAtoms μ] (b : ℝ) : +lemma tendsto_measure_Icc [NullSingletonClass μ] (b : ℝ) : Tendsto (fun δ ↦ μ (Icc (b - δ) (b + δ))) (𝓝 (0 : ℝ)) (𝓝 0) := by rw [← nhdsLT_sup_nhdsGE, tendsto_sup] constructor diff --git a/Mathlib/MeasureTheory/Constructions/Pi.lean b/Mathlib/MeasureTheory/Constructions/Pi.lean index eb13f8536072d9..a6f81db9f328c4 100644 --- a/Mathlib/MeasureTheory/Constructions/Pi.lean +++ b/Mathlib/MeasureTheory/Constructions/Pi.lean @@ -410,11 +410,12 @@ lemma _root_.MeasureTheory.measurePreserving_eval [∀ i, IsProbabilityMeasure ( rw [Measure.pi_map_eval, Finset.prod_eq_one, one_smul] exact fun _ _ ↦ measure_univ -theorem pi_hyperplane (i : ι) [NoAtoms (μ i)] (x : α i) : +theorem pi_hyperplane (i : ι) [NullSingletonClass (μ i)] (x : α i) : Measure.pi μ { f : ∀ i, α i | f i = x } = 0 := show Measure.pi μ (eval i ⁻¹' {x}) = 0 from pi_eval_preimage_null _ (measure_singleton x) -theorem ae_eval_ne (i : ι) [NoAtoms (μ i)] (x : α i) : ∀ᵐ y : ∀ i, α i ∂Measure.pi μ, y i ≠ x := +theorem ae_eval_ne (i : ι) [NullSingletonClass (μ i)] (x : α i) : + ∀ᵐ y : ∀ i, α i ∂Measure.pi μ, y i ≠ x := compl_mem_ae_iff.2 (pi_hyperplane μ i x) theorem restrict_pi_pi (s : (i : ι) → Set (α i)) : @@ -467,7 +468,7 @@ lemma pi_map_piOptionEquivProd {β : Option ι → Type*} [∀ i, MeasurableSpac section Intervals -variable [∀ i, PartialOrder (α i)] [∀ i, NoAtoms (μ i)] +variable [∀ i, PartialOrder (α i)] [∀ i, NullSingletonClass (μ i)] theorem pi_Iio_ae_eq_pi_Iic {s : Set ι} {f : ∀ i, α i} : (pi s fun i => Iio (f i)) =ᵐ[Measure.pi μ] pi s fun i => Iic (f i) := @@ -515,18 +516,27 @@ theorem univ_pi_Ico_ae_eq_Icc {f g : ∀ i, α i} : end Intervals -/-- If one of the measures `μ i` has no atoms, them `Measure.pi µ` -has no atoms. The instance below assumes that all `μ i` have no atoms. -/ -theorem pi_noAtoms (i : ι) [NoAtoms (μ i)] : NoAtoms (Measure.pi μ) := +/-- If one of the measures `μ i` has value zero on singeltons, them `Measure.pi µ` +has value zero on singletons. The instance below assumes that all `μ i` have value zero on +singletons. -/ +theorem pi_nullSingletonClass (i : ι) [NullSingletonClass (μ i)] : + NullSingletonClass (Measure.pi μ) := ⟨fun x => flip measure_mono_null (pi_hyperplane μ i (x i)) (singleton_subset_iff.2 rfl)⟩ -instance pi_noAtoms' [h : Nonempty ι] [∀ i, NoAtoms (μ i)] : NoAtoms (Measure.pi μ) := - h.elim fun i => pi_noAtoms i +@[deprecated (since := "2026-06-09")] +alias pi_noAtoms := pi_nullSingletonClass + +instance pi_nullSingletonClass' [h : Nonempty ι] [∀ i, NullSingletonClass (μ i)] : + NullSingletonClass (Measure.pi μ) := + h.elim fun i => pi_nullSingletonClass i + +@[deprecated (since := "2026-06-09")] +alias pi_noAtoms' := pi_nullSingletonClass' instance {α : ι → Type*} [Nonempty ι] [∀ i, MeasureSpace (α i)] - [∀ i, SigmaFinite (volume : Measure (α i))] [∀ i, NoAtoms (volume : Measure (α i))] : - NoAtoms (volume : Measure (∀ i, α i)) := - pi_noAtoms' + [∀ i, SigmaFinite (volume : Measure (α i))] [∀ i, NullSingletonClass (volume : Measure (α i))] : + NullSingletonClass (volume : Measure (∀ i, α i)) := + pi_nullSingletonClass' instance pi.isLocallyFiniteMeasure [∀ i, TopologicalSpace (α i)] [∀ i, IsLocallyFiniteMeasure (μ i)] : diff --git a/Mathlib/MeasureTheory/Constructions/UnitInterval.lean b/Mathlib/MeasureTheory/Constructions/UnitInterval.lean index b84fdf2a05dbae..0b39ca13edfa63 100644 --- a/Mathlib/MeasureTheory/Constructions/UnitInterval.lean +++ b/Mathlib/MeasureTheory/Constructions/UnitInterval.lean @@ -11,7 +11,7 @@ public import Mathlib.MeasureTheory.Measure.Haar.Unique # The canonical measure on the unit interval This file provides a `MeasureTheory.MeasureSpace` instance on `unitInterval`, -and shows it is a probability measure with no atoms. +and shows it is a probability measure with value zero on singletons. It also contains some basic results on the volume of various interval sets. -/ @@ -43,7 +43,7 @@ lemma volume_apply {s : Set I} : volume s = volume (Subtype.val '' s) := lemma measurePreserving_coe : MeasurePreserving ((↑) : I → ℝ) volume (volume.restrict I) := measurePreserving_subtype_coe measurableSet_Icc -instance : NoAtoms (volume : Measure I) where +instance : NullSingletonClass (volume : Measure I) where measure_singleton x := by simp [volume_apply] @[fun_prop] diff --git a/Mathlib/MeasureTheory/Group/Measure.lean b/Mathlib/MeasureTheory/Group/Measure.lean index e38b897cfb8d77..b90e3c15db511f 100644 --- a/Mathlib/MeasureTheory/Group/Measure.lean +++ b/Mathlib/MeasureTheory/Group/Measure.lean @@ -918,20 +918,20 @@ instance prod.instIsHaarMeasure {G : Type*} [Group G] [TopologicalSpace G] {_ : (ν : Measure H) [IsHaarMeasure μ] [IsHaarMeasure ν] [SFinite μ] [SFinite ν] [MeasurableMul G] [MeasurableMul H] : IsHaarMeasure (μ.prod ν) where -/-- If the neutral element of a group is not isolated, then a Haar measure on this group has -no atoms. +/-- If the neutral element of a group is not isolated, then a Haar measure on this group has value +zero on singletons. The additive version of this instance applies in particular to show that an additive Haar measure on a nontrivial finite-dimensional real vector space has no atom. -/ @[to_additive /-- If the zero element of an additive group is not isolated, then an additive Haar measure on this -group has no atoms. +group has value zero on singletons. This applies in particular to show that an additive Haar measure on a nontrivial finite-dimensional real vector space has no atom. -/] -instance (priority := 100) IsHaarMeasure.noAtoms [IsTopologicalGroup G] [BorelSpace G] [T1Space G] - [WeaklyLocallyCompactSpace G] [(𝓝[≠] (1 : G)).NeBot] (μ : Measure G) [μ.IsHaarMeasure] : - NoAtoms μ := by +instance (priority := 100) IsHaarMeasure.nullSingletonClass [IsTopologicalGroup G] [BorelSpace G] + [T1Space G] [WeaklyLocallyCompactSpace G] [(𝓝[≠] (1 : G)).NeBot] (μ : Measure G) + [μ.IsHaarMeasure] : NullSingletonClass μ := by cases eq_or_ne (μ 1) 0 with | inl h => constructor; simpa | inr h => @@ -940,6 +940,9 @@ instance (priority := 100) IsHaarMeasure.noAtoms [IsTopologicalGroup G] [BorelSp exact absurd (K_inf.meas_eq_top ⟨_, h, fun x _ ↦ (haar_singleton _ _).ge⟩) K_compact.measure_lt_top.ne +@[deprecated (since := "2026-06-09")] +alias IsHaarMeasure.noAtoms := IsHaarMeasure.nullSingletonClass + instance IsAddHaarMeasure.domSMul {G A : Type*} [Group G] [AddCommGroup A] [DistribMulAction G A] [MeasurableSpace A] [TopologicalSpace A] [BorelSpace A] [IsTopologicalAddGroup A] [ContinuousConstSMul G A] {μ : Measure A} [μ.IsAddHaarMeasure] (g : Gᵈᵐᵃ) : diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean index 8d5f7a068e9b7f..f226cd4de8fb9d 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean @@ -666,7 +666,7 @@ theorem setIntegral_trim {X} {m m0 : MeasurableSpace X} {μ : Measure X} (hm : m /-! ### Lemmas about adding and removing interval boundaries The primed lemmas take explicit arguments about the endpoint having zero measure, while the -unprimed ones use `[NoAtoms μ]`. +unprimed ones use `[NullSingletonClass μ]`. -/ section PartialOrder @@ -701,7 +701,7 @@ theorem integral_Ici_eq_integral_Ioi' (hx : μ {x} = 0) : ∫ t in Ici x, f t ∂μ = ∫ t in Ioi x, f t ∂μ := setIntegral_congr_set (Ioi_ae_eq_Ici' hx).symm -variable [NoAtoms μ] +variable [NullSingletonClass μ] theorem integral_Icc_eq_integral_Ioc : ∫ t in Icc x y, f t ∂μ = ∫ t in Ioc x y, f t ∂μ := integral_Icc_eq_integral_Ioc' <| measure_singleton x diff --git a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean index 76231ac56f25e2..0b6c569d990aff 100644 --- a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean +++ b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean @@ -435,7 +435,7 @@ theorem continuousAt_parametric_primitive_of_dominated [FirstCountableTopology X rw [nhds_prod_eq] exact (continuous_abs.tendsto' _ _ abs_zero).comp (this.comp tendsto_snd) -variable [NoAtoms μ] +variable [NullSingletonClass μ] theorem continuousOn_primitive (h_int : IntegrableOn f (Icc a b) μ) : ContinuousOn (fun x => ∫ t in Ioc a x, f t ∂μ) (Icc a b) := by @@ -636,8 +636,8 @@ theorem continuousWithinAt_Ici_primitive_Ioi {a₀ : ℝ} (hf : IntegrableOn f ( · filter_upwards [mem_nhdsWithin_of_mem_nhds (Iio_mem_nhds hx)] with a ha using by grind · filter_upwards [self_mem_nhdsWithin] with a ha using by grind -theorem continuousOn_Ici_primitive_Ioi [NoAtoms μ] {a₀ : ℝ} (hf : IntegrableOn f (Ioi a₀) μ) : - ContinuousOn (fun b ↦ ∫ x in Ioi b, f x ∂μ) (Ici a₀) := by +theorem continuousOn_Ici_primitive_Ioi [NullSingletonClass μ] {a₀ : ℝ} + (hf : IntegrableOn f (Ioi a₀) μ) : ContinuousOn (fun b ↦ ∫ x in Ioi b, f x ∂μ) (Ici a₀) := by intro a (ha : a₀ ≤ a) rw [continuousWithinAt_iff_continuous_left_right] constructor @@ -671,8 +671,8 @@ theorem continuousWithinAt_Iic_primitive_Iio {a₀ : ℝ} (hf : IntegrableOn f ( · filter_upwards [mem_nhdsWithin_of_mem_nhds (Ioi_mem_nhds hx)] with a ha using by grind · filter_upwards [self_mem_nhdsWithin] with a ha using by grind -theorem continuousOn_Iic_primitive_Iio [NoAtoms μ] {a₀ : ℝ} (hf : IntegrableOn f (Iio a₀) μ) : - ContinuousOn (fun b ↦ ∫ x in Iio b, f x ∂μ) (Iic a₀) := by +theorem continuousOn_Iic_primitive_Iio [NullSingletonClass μ] {a₀ : ℝ} + (hf : IntegrableOn f (Iio a₀) μ) : ContinuousOn (fun b ↦ ∫ x in Iio b, f x ∂μ) (Iic a₀) := by intro a (ha : a ≤ a₀) rw [continuousWithinAt_iff_continuous_left_right] constructor @@ -688,13 +688,13 @@ theorem continuousOn_Iic_primitive_Iio [NoAtoms μ] {a₀ : ℝ} (hf : Integrabl continuousWithinAt_primitive (measure_singleton a) (by simpa [ha]) exact (continuousWithinAt_const.add h_cwa).congr h_split (h_split a (left_mem_Icc.2 ha)) -theorem continuousOn_Ici_primitive_Ici [NoAtoms μ] {a₀ : ℝ} (hf : IntegrableOn f (Ici a₀) μ) : - ContinuousOn (fun b ↦ ∫ x in Ici b, f x ∂μ) (Ici a₀) := by +theorem continuousOn_Ici_primitive_Ici [NullSingletonClass μ] {a₀ : ℝ} + (hf : IntegrableOn f (Ici a₀) μ) : ContinuousOn (fun b ↦ ∫ x in Ici b, f x ∂μ) (Ici a₀) := by simp_rw [integral_Ici_eq_integral_Ioi] exact (hf.mono_set Ioi_subset_Ici_self).continuousOn_Ici_primitive_Ioi -theorem continuousOn_Iic_primitive_Iic [NoAtoms μ] {a₀ : ℝ} (hf : IntegrableOn f (Iic a₀) μ) : - ContinuousOn (fun b ↦ ∫ x in Iic b, f x ∂μ) (Iic a₀) := by +theorem continuousOn_Iic_primitive_Iic [NullSingletonClass μ] {a₀ : ℝ} + (hf : IntegrableOn f (Iic a₀) μ) : ContinuousOn (fun b ↦ ∫ x in Iic b, f x ∂μ) (Iic a₀) := by simp_rw [integral_Iic_eq_integral_Iio] exact (hf.mono_set Iio_subset_Iic_self).continuousOn_Iic_primitive_Iio diff --git a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean index 2c5825b528ca0f..f487a4f34cfd7c 100644 --- a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean +++ b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean @@ -850,7 +850,7 @@ theorem ContinuousOn.stronglyMeasurableAtFilter_nhdsWithin {α β : Type*} [Meas /-! ### Lemmas about adding and removing interval boundaries The primed lemmas take explicit arguments about the measure being finite at the endpoint, while -the unprimed ones use `[NoAtoms μ]`. +the unprimed ones use `[NullSingletonClass μ]`. -/ @@ -908,7 +908,7 @@ theorem integrableOn_Iic_iff_integrableOn_Iio' IntegrableOn f (Iic b) μ ↔ IntegrableOn f (Iio b) μ := by rw [← Iio_union_right, integrableOn_union, eq_true (integrableOn_singleton hb'), and_true] -variable [NoAtoms μ] +variable [NullSingletonClass μ] theorem integrableOn_Icc_iff_integrableOn_Ioc (ha : ‖f a‖ₑ ≠ ∞ := by finiteness) : IntegrableOn f (Icc a b) μ ↔ IntegrableOn f (Ioc a b) μ := diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index a2553d7d8ab4cb..20e07b068a4085 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -247,7 +247,7 @@ include ha hb in theorem aecover_Ioo_of_Ioc : AECover (μ.restrict <| Ioo A B) l fun i => Ioc (a i) (b i) := (aecover_Ioo_of_Ioo ha hb).superset (fun _ ↦ Ioo_subset_Ioc_self) fun _ ↦ measurableSet_Ioc -variable [NoAtoms μ] +variable [NullSingletonClass μ] theorem aecover_Ioc_of_Icc (ha : Tendsto a l (𝓝 A)) (hb : Tendsto b l (𝓝 B)) : AECover (μ.restrict <| Ioc A B) l fun i => Icc (a i) (b i) := diff --git a/Mathlib/MeasureTheory/Integral/IntervalAverage.lean b/Mathlib/MeasureTheory/Integral/IntervalAverage.lean index 1e35b907617a8d..455b155d94887c 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalAverage.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalAverage.lean @@ -19,7 +19,7 @@ formulas for this average: * `interval_average_eq_div`: `⨍ x in a..b, f x = (∫ x in a..b, f x) / (b - a)`; * `exists_eq_interval_average_of_measure`: `∃ c ∈ Ι a b, f c = ⨍ x in Ι a b, f x ∂μ`. -* `exists_eq_interval_average_of_noAtoms`: +* `exists_eq_interval_average_of_nullSingletonClass`: `∃ c ∈ uIoo a b, f c = ⨍ x in Ι a b, f x ∂μ`. * `exists_eq_interval_average`: `∃ c ∈ uIoo a b, f c = ⨍ x in a..b, f x`. @@ -78,10 +78,10 @@ theorem exists_eq_interval_average_of_measure isCompact_uIcc measurableSet_uIoc uIoc_subset_uIcc hμfin) hμfin hμ0 /-- If `f : ℝ → ℝ` is continuous on `uIcc a b`, the interval has finite and nonzero `μ`-measure, -and `μ` has no atoms, then `∃ c ∈ uIoo a b, f c = ⨍ x in Ι a b, f x ∂μ`. -/ -theorem exists_eq_interval_average_of_noAtoms - [NoAtoms μ] (hf : ContinuousOn f (uIcc a b)) (hμfin : μ (Ι a b) ≠ ⊤) (hμ0 : μ (Ι a b) ≠ 0) : - ∃ c ∈ uIoo a b, f c = ⨍ x in Ι a b, f x ∂μ := by +and `μ` has value zero on singletons, then `∃ c ∈ uIoo a b, f c = ⨍ x in Ι a b, f x ∂μ`. -/ +theorem exists_eq_interval_average_of_nullSingletonClass + [NullSingletonClass μ] (hf : ContinuousOn f (uIcc a b)) (hμfin : μ (Ι a b) ≠ ⊤) + (hμ0 : μ (Ι a b) ≠ 0) : ∃ c ∈ uIoo a b, f c = ⨍ x in Ι a b, f x ∂μ := by have hint : IntegrableOn f (Ι a b) μ := hf.integrableOn_of_subset_isCompact isCompact_uIcc measurableSet_uIoc uIoc_subset_uIcc hμfin have h : a ≠ b := by intro hab; simp [hab] at hμ0 @@ -95,10 +95,14 @@ theorem exists_eq_interval_average_of_noAtoms (hint.mono_set hs') (measure_ne_top_of_subset hs' hμfin) hμ0' exact ⟨c, hc, by rwa [← setAverage_congr hs_ev]⟩ +@[deprecated (since := "2026-06-09")] +alias exists_eq_interval_average_of_noAtoms := exists_eq_interval_average_of_nullSingletonClass + /-- The mean value theorem for integrals: There exists a point in an interval such that the mean of a continuous function over the interval equals the value of the function at the point. -/ theorem exists_eq_interval_average (hab : a ≠ b) (hf : ContinuousOn f (uIcc a b)) : ∃ c ∈ uIoo a b, f c = ⨍ x in a..b, f x := - exists_eq_interval_average_of_noAtoms hf (by simp) (by simpa using sub_ne_zero.mpr hab.symm) + exists_eq_interval_average_of_nullSingletonClass hf (by simp) + (by simpa using sub_ne_zero.mpr hab.symm) diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean index f0b1203c751e17..e7b07212a97022 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean @@ -94,7 +94,7 @@ theorem intervalIntegrable_congr_ae {g : ℝ → ε} (h : f =ᵐ[μ.restrict (Ι IntervalIntegrable f μ a b ↔ IntervalIntegrable g μ a b := by rw [intervalIntegrable_iff, integrableOn_congr_fun_ae h, intervalIntegrable_iff] -theorem intervalIntegrable_congr_uIoo [NoAtoms μ] {g : ℝ → ε} (h : EqOn f g (uIoo a b)) : +theorem intervalIntegrable_congr_uIoo [NullSingletonClass μ] {g : ℝ → ε} (h : EqOn f g (uIoo a b)) : IntervalIntegrable f μ a b ↔ IntervalIntegrable g μ a b := by apply intervalIntegrable_congr_ae rw [uIoc, ← restrict_Ioo_eq_restrict_Ioc] @@ -105,8 +105,8 @@ theorem IntervalIntegrable.congr_ae {g : ℝ → ε} (hf : IntervalIntegrable f IntervalIntegrable g μ a b := by rwa [← intervalIntegrable_congr_ae h] -theorem IntervalIntegrable.congr_uIoo [NoAtoms μ] {g : ℝ → ε} (hf : IntervalIntegrable f μ a b) - (h : EqOn f g (uIoo a b)) : IntervalIntegrable g μ a b := +theorem IntervalIntegrable.congr_uIoo [NullSingletonClass μ] {g : ℝ → ε} + (hf : IntervalIntegrable f μ a b) (h : EqOn f g (uIoo a b)) : IntervalIntegrable g μ a b := intervalIntegrable_congr_uIoo h |>.mp hf theorem intervalIntegrable_congr {g : ℝ → ε} (h : EqOn f g (Ι a b)) : @@ -116,13 +116,13 @@ theorem intervalIntegrable_congr {g : ℝ → ε} (h : EqOn f g (Ι a b)) : alias ⟨IntervalIntegrable.congr, _⟩ := intervalIntegrable_congr /-- Interval integrability is invariant when functions change along discrete sets. -/ -theorem IntervalIntegrable.congr_codiscreteWithin {g : ℝ → ε} [NoAtoms μ] +theorem IntervalIntegrable.congr_codiscreteWithin {g : ℝ → ε} [NullSingletonClass μ] (h : f =ᶠ[codiscreteWithin (Ι a b)] g) (hf : IntervalIntegrable f μ a b) : IntervalIntegrable g μ a b := hf.congr_ae (ae_restrict_le_codiscreteWithin measurableSet_Ioc h) /-- Interval integrability is invariant when functions change along discrete sets. -/ -theorem intervalIntegrable_congr_codiscreteWithin {g : ℝ → ε} [NoAtoms μ] +theorem intervalIntegrable_congr_codiscreteWithin {g : ℝ → ε} [NullSingletonClass μ] (h : f =ᶠ[codiscreteWithin (Ι a b)] g) : IntervalIntegrable f μ a b ↔ IntervalIntegrable g μ a b := ⟨(IntervalIntegrable.congr_codiscreteWithin h ·), @@ -132,22 +132,22 @@ theorem intervalIntegrable_iff_integrableOn_Ioc_of_le (hab : a ≤ b) : IntervalIntegrable f μ a b ↔ IntegrableOn f (Ioc a b) μ := by rw [intervalIntegrable_iff, uIoc_of_le hab] -theorem intervalIntegrable_iff' [NoAtoms μ] (h : ‖f (min a b)‖ₑ ≠ ∞ := by finiteness) : +theorem intervalIntegrable_iff' [NullSingletonClass μ] (h : ‖f (min a b)‖ₑ ≠ ∞ := by finiteness) : IntervalIntegrable f μ a b ↔ IntegrableOn f (uIcc a b) μ := by rw [intervalIntegrable_iff, ← Icc_min_max, uIoc, integrableOn_Icc_iff_integrableOn_Ioc h] -theorem intervalIntegrable_iff_integrableOn_Icc_of_le [NoAtoms μ] +theorem intervalIntegrable_iff_integrableOn_Icc_of_le [NullSingletonClass μ] (hab : a ≤ b) (ha : ‖f a‖ₑ ≠ ∞ := by finiteness) : IntervalIntegrable f μ a b ↔ IntegrableOn f (Icc a b) μ := by rw [intervalIntegrable_iff_integrableOn_Ioc_of_le hab, integrableOn_Icc_iff_integrableOn_Ioc ha] -theorem intervalIntegrable_iff_integrableOn_Ico_of_le [NoAtoms μ] +theorem intervalIntegrable_iff_integrableOn_Ico_of_le [NullSingletonClass μ] (hab : a ≤ b) (ha : ‖f a‖ₑ ≠ ∞ := by finiteness) (hb : ‖f b‖ₑ ≠ ∞ := by finiteness) : IntervalIntegrable f μ a b ↔ IntegrableOn f (Ico a b) μ := by rw [intervalIntegrable_iff_integrableOn_Icc_of_le hab ha, integrableOn_Icc_iff_integrableOn_Ico hb] -theorem intervalIntegrable_iff_integrableOn_Ioo_of_le [NoAtoms μ] +theorem intervalIntegrable_iff_integrableOn_Ioo_of_le [NullSingletonClass μ] (hab : a ≤ b) (ha : ‖f a‖ₑ ≠ ∞ := by finiteness) (hb : ‖f b‖ₑ ≠ ∞ := by finiteness) : IntervalIntegrable f μ a b ↔ IntegrableOn f (Ioo a b) μ := by rw [intervalIntegrable_iff_integrableOn_Icc_of_le hab ha, @@ -1187,7 +1187,7 @@ theorem integral_Iio_sub_Iio (hf : IntegrableOn f (Iio b) μ) (hab : a ≤ b) : rw [sub_eq_iff_eq_add', ← setIntegral_union (by grind) measurableSet_Ico ha h, Iio_union_Ico_eq_Iio hab] -theorem integral_Iio_sub_Iio' [NoAtoms μ] (hf : IntegrableOn f (Iio b) μ) +theorem integral_Iio_sub_Iio' [NullSingletonClass μ] (hf : IntegrableOn f (Iio b) μ) (hg : IntegrableOn f (Iio a) μ) : ∫ x in Iio b, f x ∂μ - ∫ x in Iio a, f x ∂μ = ∫ x in a..b, f x ∂μ := by wlog! hab : a ≤ b generalizing a b @@ -1201,7 +1201,7 @@ theorem integral_Ici_sub_Ici (hf : IntegrableOn f (Ici a) μ) (hab : a ≤ b) : rw [sub_eq_iff_eq_add', ← setIntegral_union (by grind) measurableSet_Ico ha h, union_comm, Ico_union_Ici_eq_Ici hab] -theorem integral_Ici_sub_Ici' [NoAtoms μ] (hf : IntegrableOn f (Ici a) μ) +theorem integral_Ici_sub_Ici' [NullSingletonClass μ] (hf : IntegrableOn f (Ici a) μ) (hg : IntegrableOn f (Ici b) μ) : ∫ x in Ici a, f x ∂μ - ∫ x in Ici b, f x ∂μ = ∫ x in a..b, f x ∂μ := by wlog! hab : a ≤ b generalizing a b @@ -1242,13 +1242,13 @@ theorem integral_congr_ae (h : ∀ᵐ x ∂μ, x ∈ Ι a b → f x = g x) : ∫ x in a..b, f x ∂μ = ∫ x in a..b, g x ∂μ := integral_congr_ae' (ae_uIoc_iff.mp h).1 (ae_uIoc_iff.mp h).2 -theorem integral_congr_uIoo [NoAtoms μ] (h : (uIoo a b).EqOn f g) : +theorem integral_congr_uIoo [NullSingletonClass μ] (h : (uIoo a b).EqOn f g) : ∫ x in a..b, f x ∂μ = ∫ x in a..b, g x ∂μ := by apply integral_congr_ae filter_upwards [μ.ae_ne <| a ⊔ b] with x _ hx exact h ⟨hx.left, lt_of_le_of_ne hx.right ‹_›⟩ -theorem integral_congr_Ioo_of_le [NoAtoms μ] (hab : a ≤ b) (h : (Ioo a b).EqOn f g) : +theorem integral_congr_Ioo_of_le [NullSingletonClass μ] (hab : a ≤ b) (h : (Ioo a b).EqOn f g) : ∫ x in a..b, f x ∂μ = ∫ x in a..b, g x ∂μ := integral_congr_uIoo <| uIoo_of_le hab ▸ h @@ -1429,7 +1429,7 @@ theorem integral_mono_on (h : ∀ x ∈ Icc a b, f x ≤ g x) : let H x hx := h x <| Ioc_subset_Icc_self hx simpa only [integral_of_le hab] using setIntegral_mono_on hf.1 hg.1 measurableSet_Ioc H -theorem integral_mono_on_of_le_Ioo [NoAtoms μ] (h : ∀ x ∈ Ioo a b, f x ≤ g x) : +theorem integral_mono_on_of_le_Ioo [NullSingletonClass μ] (h : ∀ x ∈ Ioo a b, f x ≤ g x) : (∫ u in a..b, f u ∂μ) ≤ ∫ u in a..b, g u ∂μ := by simp only [integral_of_le hab, integral_Ioc_eq_integral_Ioo] apply setIntegral_mono_on diff --git a/Mathlib/MeasureTheory/Integral/Layercake.lean b/Mathlib/MeasureTheory/Integral/Layercake.lean index 3a5b7c938a8f4f..59e6abe4dd4696 100644 --- a/Mathlib/MeasureTheory/Integral/Layercake.lean +++ b/Mathlib/MeasureTheory/Integral/Layercake.lean @@ -84,7 +84,7 @@ theorem countable_meas_le_ne_meas_lt (g : α → R) : exact ⟨μ {a | t < g a}, this, fun s hs ↦ measure_mono (fun a ha ↦ hs.trans_le ha)⟩ theorem meas_le_ae_eq_meas_lt {R : Type*} [LinearOrder R] [MeasurableSpace R] - (ν : Measure R) [NoAtoms ν] (g : α → R) : + (ν : Measure R) [NullSingletonClass ν] (g : α → R) : (fun t => μ {a : α | t ≤ g a}) =ᵐ[ν] fun t => μ {a : α | t < g a} := Set.Countable.measure_zero (countable_meas_le_ne_meas_lt μ g) _ diff --git a/Mathlib/MeasureTheory/Measure/Dirac.lean b/Mathlib/MeasureTheory/Measure/Dirac.lean index 6dee190008edeb..c2bcd777e868f6 100644 --- a/Mathlib/MeasureTheory/Measure/Dirac.lean +++ b/Mathlib/MeasureTheory/Measure/Dirac.lean @@ -7,7 +7,7 @@ module public import Mathlib.MeasureTheory.MeasurableSpace.CountablyGenerated public import Mathlib.MeasureTheory.Measure.MutuallySingular -public import Mathlib.MeasureTheory.Measure.Typeclasses.NoAtoms +public import Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass public import Mathlib.MeasureTheory.Measure.Typeclasses.Probability public import Mathlib.MeasureTheory.Measure.Typeclasses.SFinite @@ -278,7 +278,8 @@ theorem restrict_dirac [MeasurableSingletonClass α] [Decidable (a ∈ s)] : rwa [ae_dirac_eq] · rw [restrict_eq_zero, dirac_apply, indicator_of_notMem has] -lemma mutuallySingular_dirac [MeasurableSingletonClass α] (x : α) (μ : Measure α) [NoAtoms μ] : +lemma mutuallySingular_dirac [MeasurableSingletonClass α] (x : α) (μ : Measure α) + [NullSingletonClass μ] : Measure.dirac x ⟂ₘ μ := ⟨{x}ᶜ, (MeasurableSet.singleton x).compl, by simp, by simp⟩ diff --git a/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean b/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean index a22ac24d3625df..156f47097e9380 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean @@ -25,10 +25,12 @@ namespace MeasureTheory namespace Measure -/-- The instance `MeasureTheory.Measure.IsAddHaarMeasure.noAtoms` applies in particular to show that -an additive Haar measure on a nontrivial finite-dimensional real vector space has no atom. -/ +/-- The instance `MeasureTheory.Measure.IsAddHaarMeasure.nullSingletonClass` applies in particular +to show that an additive Haar measure on a nontrivial finite-dimensional real vector space has no +atom. -/ example {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [Nontrivial E] [FiniteDimensional ℝ E] - [MeasurableSpace E] [BorelSpace E] (μ : Measure E) [IsAddHaarMeasure μ] : NoAtoms μ := by + [MeasurableSpace E] [BorelSpace E] (μ : Measure E) [IsAddHaarMeasure μ] : + NullSingletonClass μ := by infer_instance section LinearEquiv diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 4377338e2a1943..81c855665198b3 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -80,7 +80,8 @@ measures. equal to infinity on some ray `(-∞, D)` and is equal to zero on `(D, +∞)`, where `D` is a possibly infinite number called the *Hausdorff dimension* of `s`; `μH[D] s` can be zero, infinity, or anything in between. -* `MeasureTheory.Measure.noAtoms_hausdorff`: Hausdorff measure has no atoms. +* `MeasureTheory.Measure.nullSingletonClass_hausdorff`: Hausdorff measure has value zero on + singletons. ### Hausdorff measure in `ℝⁿ` @@ -601,7 +602,8 @@ theorem hausdorffMeasure_mono {d₁ d₂ : ℝ} (h : d₁ ≤ d₂) (s : Set X) rcases hausdorffMeasure_zero_or_top h s with hs | hs <;> simp [hs] variable (X) in -theorem noAtoms_hausdorff {d : ℝ} (hd : 0 < d) : NoAtoms (hausdorffMeasure d : Measure X) := by +theorem nullSingletonClass_hausdorff {d : ℝ} (hd : 0 < d) : + NullSingletonClass (hausdorffMeasure d : Measure X) := by refine ⟨fun x => ?_⟩ rw [← nonpos_iff_eq_zero, hausdorffMeasure_apply] refine iSup₂_le fun ε _ => iInf₂_le_of_le (fun _ => {x}) ?_ <| iInf_le_of_le (fun _ => ?_) ?_ @@ -609,6 +611,9 @@ theorem noAtoms_hausdorff {d : ℝ} (hd : 0 < d) : NoAtoms (hausdorffMeasure d : · simp only [ediam_singleton, zero_le] · simp [hd] +@[deprecated (since := "2026-06-09")] +alias noAtoms_hausdorff := nullSingletonClass_hausdorff + @[simp] theorem hausdorffMeasure_zero_singleton (x : X) : μH[0] ({x} : Set X) = 1 := by apply le_antisymm @@ -647,7 +652,7 @@ theorem hausdorffMeasure_le_one_of_subsingleton {s : Set X} (hs : s.Subsingleton · rw [(subsingleton_iff_singleton hx).1 hs] rcases eq_or_lt_of_le hd with (rfl | dpos) · simp only [le_refl, hausdorffMeasure_zero_singleton] - · haveI := noAtoms_hausdorff X dpos + · haveI := nullSingletonClass_hausdorff X dpos simp only [zero_le, measure_singleton] end Measure @@ -685,7 +690,7 @@ theorem hausdorffMeasure_image_le (h : HolderOnWith C r f s) (hr : 0 < r) {d : · simp only [ENNReal.rpow_zero, one_mul, mul_zero] rw [hausdorffMeasure_zero_singleton] exact one_le_hausdorffMeasure_zero_of_nonempty ⟨x, hx⟩ - · haveI := noAtoms_hausdorff Y h'd + · haveI := nullSingletonClass_hausdorff Y h'd simp only [zero_le, measure_singleton] -- Now assume `C ≠ 0` · have hCd0 : (C : ℝ≥0∞) ^ d ≠ 0 := by simp [hC0.ne'] @@ -775,7 +780,7 @@ theorem hausdorffMeasure_preimage_le (hf : AntilipschitzWith K f) (hd : 0 ≤ d) · simp only [ENNReal.rpow_zero, one_mul] rw [hausdorffMeasure_zero_singleton] exact one_le_hausdorffMeasure_zero_of_nonempty ⟨f x, hx⟩ - · haveI := noAtoms_hausdorff X h'd + · haveI := nullSingletonClass_hausdorff X h'd simp only [zero_le, measure_singleton] have hKd0 : (K : ℝ≥0∞) ^ d ≠ 0 := by simp [h0] have hKd : (K : ℝ≥0∞) ^ d ≠ ∞ := by simp [hd] @@ -1023,7 +1028,7 @@ theorem hausdorffMeasure_smul_right_image [NormedAddCommGroup E] [NormedSpace [MeasurableSpace E] [BorelSpace E] (v : E) (s : Set ℝ) : μH[1] ((fun r => r • v) '' s) = ‖v‖₊ • μH[1] s := by obtain rfl | hv := eq_or_ne v 0 - · haveI := noAtoms_hausdorff E one_pos + · haveI := nullSingletonClass_hausdorff E one_pos obtain rfl | hs := s.eq_empty_or_nonempty · simp simp [hs] diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean index a72b18d4548e7a..a94cef29b9a1a3 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean @@ -170,9 +170,12 @@ theorem volume_closedEBall (a : ℝ) (r : ℝ≥0∞) : volume (Metric.closedEBa @[deprecated (since := "2026-01-24")] alias volume_emetric_closedBall := volume_closedEBall -instance noAtoms_volume : NoAtoms (volume : Measure ℝ) := +instance nullSingletonClass_volume : NullSingletonClass (volume : Measure ℝ) := ⟨fun _ => volume_singleton⟩ +@[deprecated (since := "2026-06-09")] +alias noAtoms_volume := nullSingletonClass_volume + @[simp] theorem volume_interval {a b : ℝ} : volume (uIcc a b) = ofReal |b - a| := by rw [← Icc_min_max, volume_Icc, max_sub_min_eq_abs] @@ -619,8 +622,8 @@ end regionBetween /-- Consider a real set `s`. If a property is true almost everywhere in `s ∩ (a, b)` for all `a, b ∈ s`, then it is true almost everywhere in `s`. Formulated with `μ.restrict`. See also `ae_of_mem_of_ae_of_mem_inter_Ioo`. -/ -theorem ae_restrict_of_ae_restrict_inter_Ioo {μ : Measure ℝ} [NoAtoms μ] {s : Set ℝ} {p : ℝ → Prop} - (h : ∀ a b, a ∈ s → b ∈ s → a < b → ∀ᵐ x ∂μ.restrict (s ∩ Ioo a b), p x) : +theorem ae_restrict_of_ae_restrict_inter_Ioo {μ : Measure ℝ} [NullSingletonClass μ] {s : Set ℝ} + {p : ℝ → Prop} (h : ∀ a b, a ∈ s → b ∈ s → a < b → ∀ᵐ x ∂μ.restrict (s ∩ Ioo a b), p x) : ∀ᵐ x ∂μ.restrict s, p x := by /- By second-countability, we cover `s` by countably many intervals `(a, b)` (except maybe for two endpoints, which don't matter since `μ` does not have any atom). -/ @@ -653,8 +656,8 @@ theorem ae_restrict_of_ae_restrict_inter_Ioo {μ : Measure ℝ} [NoAtoms μ] {s /-- Consider a real set `s`. If a property is true almost everywhere in `s ∩ (a, b)` for all `a, b ∈ s`, then it is true almost everywhere in `s`. Formulated with bare membership. See also `ae_restrict_of_ae_restrict_inter_Ioo`. -/ -theorem ae_of_mem_of_ae_of_mem_inter_Ioo {μ : Measure ℝ} [NoAtoms μ] {s : Set ℝ} {p : ℝ → Prop} - (h : ∀ a b, a ∈ s → b ∈ s → a < b → ∀ᵐ x ∂μ, x ∈ s ∩ Ioo a b → p x) : +theorem ae_of_mem_of_ae_of_mem_inter_Ioo {μ : Measure ℝ} [NullSingletonClass μ] {s : Set ℝ} + {p : ℝ → Prop} (h : ∀ a b, a ∈ s → b ∈ s → a < b → ∀ᵐ x ∂μ, x ∈ s ∩ Ioo a b → p x) : ∀ᵐ x ∂μ, x ∈ s → p x := by /- By second-countability, we cover `s` by countably many intervals `(a, b)` (except maybe for two endpoints, which don't matter since `μ` does not have any atom). -/ diff --git a/Mathlib/MeasureTheory/Measure/OpenPos.lean b/Mathlib/MeasureTheory/Measure/OpenPos.lean index d5e7375f730923..46c9fb552b916b 100644 --- a/Mathlib/MeasureTheory/Measure/OpenPos.lean +++ b/Mathlib/MeasureTheory/Measure/OpenPos.lean @@ -6,7 +6,7 @@ Authors: Yury Kudryashov module public import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic -public import Mathlib.MeasureTheory.Measure.Typeclasses.NoAtoms +public import Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass public import Mathlib.MeasureTheory.Measure.Typeclasses.Probability /-! @@ -217,7 +217,7 @@ theorem measure_closedBall_pos (x : X) {r : ℝ} (hr : 0 < r) : 0 < μ (closedBa (measure_ball_pos μ x hr).trans_le (measure_mono ball_subset_closedBall) @[simp] lemma measure_closedBall_pos_iff {X : Type*} [MetricSpace X] {m : MeasurableSpace X} - (μ : Measure X) [IsOpenPosMeasure μ] [NoAtoms μ] {x : X} {r : ℝ} : + (μ : Measure X) [IsOpenPosMeasure μ] [NullSingletonClass μ] {x : X} {r : ℝ} : 0 < μ (closedBall x r) ↔ 0 < r := by refine ⟨fun h ↦ ?_, measure_closedBall_pos μ x⟩ contrapose! h diff --git a/Mathlib/MeasureTheory/Measure/Prod.lean b/Mathlib/MeasureTheory/Measure/Prod.lean index e9f92b71955eb6..90ee8c5123e0f3 100644 --- a/Mathlib/MeasureTheory/Measure/Prod.lean +++ b/Mathlib/MeasureTheory/Measure/Prod.lean @@ -202,16 +202,16 @@ theorem prod_prod_le (s : Set α) (t : Set β) : μ.prod ν (s ×ˢ t) ≤ μ s restrict_apply_univ, mul_comm] _ = μ s * ν t := by rw [measure_toMeasurable, measure_toMeasurable] -instance prod.instNoAtoms_fst [NoAtoms μ] : - NoAtoms (Measure.prod μ ν) where +instance prod.instNullSingletonClass_fst [NullSingletonClass μ] : + NullSingletonClass (Measure.prod μ ν) where measure_singleton | (x, y) => nonpos_iff_eq_zero.mp <| calc μ.prod ν {(x, y)} = μ.prod ν ({x} ×ˢ {y}) := by rw [singleton_prod_singleton] _ ≤ μ {x} * ν {y} := prod_prod_le _ _ _ = 0 := by simp -instance prod.instNoAtoms_snd [NoAtoms ν] : - NoAtoms (Measure.prod μ ν) where +instance prod.instNullSingletonClass_snd [NullSingletonClass ν] : + NullSingletonClass (Measure.prod μ ν) where measure_singleton | (x, y) => nonpos_iff_eq_zero.mp <| calc μ.prod ν {(x, y)} = μ.prod ν ({x} ×ˢ {y}) := by rw [singleton_prod_singleton] diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean similarity index 76% rename from Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean rename to Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean index c2688f3a1427d9..05a501fdba695a 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean @@ -9,13 +9,13 @@ public import Mathlib.MeasureTheory.Measure.Restrict public import Mathlib.Topology.DiscreteSubset /-! -# Measures having no atoms - -A measure `μ` has no atoms if the measure of each singleton is zero. +# Measures having value zero on singletons ## TODO -Should `NoAtoms` be redefined as `∀ s, 0 < μ s → ∃ t ⊆ s, 0 < μ t ∧ μ t < μ s`? +Add a `NoAtoms` class defined as +`∀ s, MeasurableSet s → 0 < μ s → ∃ t ⊆ s, MeasurableSet t ∧ 0 < μ t ∧ μ t < μ s`. +This implies `NullSingletonClass` but the converse is not true. -/ public section @@ -26,47 +26,49 @@ open Set Measure Filter TopologicalSpace variable {α : Type*} {m0 : MeasurableSpace α} {μ : Measure α} {s : Set α} -/-- Measure `μ` *has no atoms* if the measure of each singleton is zero. - -NB: Wikipedia assumes that for any measurable set `s` with positive `μ`-measure, -there exists a measurable `t ⊆ s` such that `0 < μ t < μ s`. While this implies `μ {x} = 0`, -the converse is not true. -/ -class NoAtoms {m0 : MeasurableSpace α} (μ : Measure α) : Prop where +/-- Measure `μ` has value zero on singletons. -/ +class NullSingletonClass {m0 : MeasurableSpace α} (μ : Measure α) : Prop where measure_singleton : ∀ x, μ {x} = 0 -export MeasureTheory.NoAtoms (measure_singleton) +@[deprecated (since := "2026-06-09")] +alias NoAtoms := NullSingletonClass + +export MeasureTheory.NullSingletonClass (measure_singleton) attribute [simp] measure_singleton -variable [NoAtoms μ] +variable [NullSingletonClass μ] -theorem _root_.Set.Subsingleton.measure_zero (hs : s.Subsingleton) (μ : Measure α) [NoAtoms μ] : +theorem _root_.Set.Subsingleton.measure_zero (hs : s.Subsingleton) (μ : Measure α) + [NullSingletonClass μ] : μ s = 0 := hs.induction_on (p := fun s => μ s = 0) measure_empty measure_singleton theorem Measure.restrict_singleton' {a : α} : μ.restrict {a} = 0 := by simp only [measure_singleton, Measure.restrict_eq_zero] -instance Measure.restrict.instNoAtoms (s : Set α) : NoAtoms (μ.restrict s) := by +instance Measure.restrict.instNullSingletonClass (s : Set α) : + NullSingletonClass (μ.restrict s) := by refine ⟨fun x => ?_⟩ obtain ⟨t, hxt, ht1, ht2⟩ := exists_measurable_superset_of_null (measure_singleton x : μ {x} = 0) apply measure_mono_null hxt rw [Measure.restrict_apply ht1] apply measure_mono_null inter_subset_left ht2 -theorem _root_.Set.Countable.measure_zero (h : s.Countable) (μ : Measure α) [NoAtoms μ] : +theorem _root_.Set.Countable.measure_zero (h : s.Countable) (μ : Measure α) [NullSingletonClass μ] : μ s = 0 := by rw [← biUnion_of_singleton s, measure_biUnion_null_iff h] simp -theorem _root_.Set.Countable.ae_notMem (h : s.Countable) (μ : Measure α) [NoAtoms μ] : +theorem _root_.Set.Countable.ae_notMem (h : s.Countable) (μ : Measure α) [NullSingletonClass μ] : ∀ᵐ x ∂μ, x ∉ s := by simpa only [ae_iff, Classical.not_not] using! h.measure_zero μ -lemma Measure.ae_ne (μ : Measure α) [NoAtoms μ] (a : α) : ∀ᵐ x ∂μ, x ≠ a := +lemma Measure.ae_ne (μ : Measure α) [NullSingletonClass μ] (a : α) : ∀ᵐ x ∂μ, x ≠ a := (countable_singleton a).ae_notMem μ -lemma _root_.Set.Countable.measure_restrict_compl (h : s.Countable) (μ : Measure α) [NoAtoms μ] : +lemma _root_.Set.Countable.measure_restrict_compl (h : s.Countable) (μ : Measure α) + [NullSingletonClass μ] : μ.restrict sᶜ = μ := restrict_eq_self_of_ae_mem <| h.ae_notMem μ @@ -74,10 +76,12 @@ lemma _root_.Set.Countable.measure_restrict_compl (h : s.Countable) (μ : Measur lemma restrict_compl_singleton (a : α) : μ.restrict ({a}ᶜ) = μ := (countable_singleton _).measure_restrict_compl μ -theorem _root_.Set.Finite.measure_zero (h : s.Finite) (μ : Measure α) [NoAtoms μ] : μ s = 0 := +theorem _root_.Set.Finite.measure_zero (h : s.Finite) (μ : Measure α) [NullSingletonClass μ] : + μ s = 0 := h.countable.measure_zero μ -theorem _root_.Finset.measure_zero (s : Finset α) (μ : Measure α) [NoAtoms μ] : μ s = 0 := +theorem _root_.Finset.measure_zero (s : Finset α) (μ : Measure α) [NullSingletonClass μ] : + μ s = 0 := s.finite_toSet.measure_zero μ theorem insert_ae_eq_self (a : α) (s : Set α) : (insert a s : Set α) =ᵐ[μ] s := @@ -86,13 +90,16 @@ theorem insert_ae_eq_self (a : α) (s : Set α) : (insert a s : Set α) =ᵐ[μ] /- If a set has positive measure under an atomless measure, then it has an accumulation point. -/ -theorem exists_accPt_of_noAtoms {X : Type*} [TopologicalSpace X] [MeasurableSpace X] - {μ : Measure X} [NoAtoms μ] {E : Set X} [SeparableSpace E] (hE : 0 < μ E) : +theorem exists_accPt_of_nullSingletonClass {X : Type*} [TopologicalSpace X] [MeasurableSpace X] + {μ : Measure X} [NullSingletonClass μ] {E : Set X} [SeparableSpace E] (hE : 0 < μ E) : ∃ x, AccPt x (𝓟 E) := by by_contra! h haveI : DiscreteTopology E := discreteTopology_of_noAccPts fun x _ => h x exact hE.ne' <| (Set.countable_coe_iff.mp <| separableSpace_iff_countable.mp ‹_›).measure_zero μ +@[deprecated (since := "2026-06-09")] +alias exists_accPt_of_noAtoms := exists_accPt_of_nullSingletonClass + section variable [PartialOrder α] {a b : α} diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index 404bcf0aa490ea..2cdfce72212c92 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -160,9 +160,13 @@ theorem withDensity_apply₀ (f : α → ℝ≥0∞) {s : Set α} (hs : NullMeas rw [← A, ← B] exact withDensity_apply _ (measurableSet_toMeasurable μ s) -instance noAtoms_withDensity [NoAtoms μ] (f : α → ℝ≥0∞) : NoAtoms (μ.withDensity f) where +instance nullSingletonClass_withDensity [NullSingletonClass μ] (f : α → ℝ≥0∞) : + NullSingletonClass (μ.withDensity f) where measure_singleton _ := withDensity_absolutelyContinuous μ f (measure_singleton _) +@[deprecated (since := "2026-06-09")] +alias noAtoms_withDensity := nullSingletonClass_withDensity + @[simp] theorem withDensity_zero : μ.withDensity 0 = 0 := by ext1 s hs diff --git a/Mathlib/MeasureTheory/Topology.lean b/Mathlib/MeasureTheory/Topology.lean index f411e33eff8304..0775598d56be28 100644 --- a/Mathlib/MeasureTheory/Topology.lean +++ b/Mathlib/MeasureTheory/Topology.lean @@ -5,7 +5,7 @@ Authors: Stefan Kebekus -/ module -public import Mathlib.MeasureTheory.Measure.Typeclasses.NoAtoms +public import Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass public import Mathlib.Topology.DiscreteSubset /-! @@ -22,7 +22,7 @@ open Filter MeasureTheory everywhere" filter of co-null sets. -/ theorem ae_restrict_le_codiscreteWithin {α : Type*} [MeasurableSpace α] [TopologicalSpace α] [SecondCountableTopology α] - {μ : Measure α} [NoAtoms μ] {U : Set α} (hU : MeasurableSet U) : + {μ : Measure α} [NullSingletonClass μ] {U : Set α} (hU : MeasurableSet U) : ae (μ.restrict U) ≤ codiscreteWithin U := by intro s hs have : DiscreteTopology ↑(sᶜ ∩ U) := isDiscrete_iff_discreteTopology.mp diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index b2a46262a4ce6e..928a5fbe2c5dfc 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -231,14 +231,15 @@ instance : IsAddHaarMeasure (volume : Measure (mixedSpace K)) := prod.instIsAddHaarMeasure volume volume open Classical in -instance : NoAtoms (volume : Measure (mixedSpace K)) := by +instance : NullSingletonClass (volume : Measure (mixedSpace K)) := by obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K)) by_cases hw : IsReal w - · have : NoAtoms (volume : Measure ({w : InfinitePlace K // IsReal w} → ℝ)) := pi_noAtoms ⟨w, hw⟩ - exact prod.instNoAtoms_fst - · have : NoAtoms (volume : Measure ({w : InfinitePlace K // IsComplex w} → ℂ)) := - pi_noAtoms ⟨w, not_isReal_iff_isComplex.mp hw⟩ - exact prod.instNoAtoms_snd + · have : NullSingletonClass (volume : Measure ({w : InfinitePlace K // IsReal w} → ℝ)) := + pi_nullSingletonClass ⟨w, hw⟩ + exact prod.instNullSingletonClass_fst + · have : NullSingletonClass (volume : Measure ({w : InfinitePlace K // IsComplex w} → ℂ)) := + pi_nullSingletonClass ⟨w, not_isReal_iff_isComplex.mp hw⟩ + exact prod.instNullSingletonClass_snd variable {K} in open Classical in diff --git a/Mathlib/Probability/Distributions/Gaussian/Fernique.lean b/Mathlib/Probability/Distributions/Gaussian/Fernique.lean index f8e1985aea8a16..c911150d3c42e7 100644 --- a/Mathlib/Probability/Distributions/Gaussian/Fernique.lean +++ b/Mathlib/Probability/Distributions/Gaussian/Fernique.lean @@ -220,16 +220,16 @@ lemma eq_dirac_of_variance_eq_zero (h : ∀ L : StrongDual ℝ E, Var[L; μ] = 0 rw [charFunDual_dirac, charFunDual_eq L, h L, integral_complex_ofReal, integral_dual L] simp -/-- If a Gaussian measure is not a Dirac, then it has no atoms. -/ -lemma noAtoms (h : ∀ x, μ ≠ Measure.dirac x) : NoAtoms μ where +/-- If a Gaussian measure is not a Dirac, then it has value zero on singletons. -/ +lemma nullSingletonClass (h : ∀ x, μ ≠ Measure.dirac x) : NullSingletonClass μ where measure_singleton x := by obtain ⟨L, hL⟩ : ∃ L : StrongDual ℝ E, Var[L; μ] ≠ 0 := by contrapose! h exact ⟨_, eq_dirac_of_variance_eq_zero h⟩ have hL_zero : μ.map L {L x} = 0 := by - have : NoAtoms (μ.map L) := by + have : NullSingletonClass (μ.map L) := by rw [map_eq_gaussianReal L] - refine noAtoms_gaussianReal ?_ + refine nullSingletonClass_gaussianReal ?_ simp only [ne_eq, Real.toNNReal_eq_zero, not_le] exact lt_of_le_of_ne (variance_nonneg _ _) hL.symm rw [measure_singleton] @@ -237,6 +237,9 @@ lemma noAtoms (h : ∀ x, μ ≠ Measure.dirac x) : NoAtoms μ where refine measure_mono_null ?_ hL_zero exact fun ⦃a⦄ ↦ congrArg ⇑L +@[deprecated (since := "2026-06-09")] +alias noAtoms := nullSingletonClass + /-- Characteristic function of a centered Gaussian measure. -/ lemma charFunDual_eq_of_integral_eq_zero (hμ : μ[id] = 0) (L : StrongDual ℝ E) : charFunDual μ L = exp (- Var[L; μ] / 2) := by diff --git a/Mathlib/Probability/Distributions/Gaussian/Real.lean b/Mathlib/Probability/Distributions/Gaussian/Real.lean index 9b7b05e1bbfa7b..89ef930b8563ac 100644 --- a/Mathlib/Probability/Distributions/Gaussian/Real.lean +++ b/Mathlib/Probability/Distributions/Gaussian/Real.lean @@ -232,10 +232,14 @@ instance instIsProbabilityMeasureGaussianReal (μ : ℝ) (v : ℝ≥0) : IsProbabilityMeasure (gaussianReal μ v) where measure_univ := by by_cases h : v = 0 <;> simp [gaussianReal_of_var_ne_zero, h] -lemma noAtoms_gaussianReal {μ : ℝ} {v : ℝ≥0} (h : v ≠ 0) : NoAtoms (gaussianReal μ v) := by +lemma nullSingletonClass_gaussianReal {μ : ℝ} {v : ℝ≥0} (h : v ≠ 0) : + NullSingletonClass (gaussianReal μ v) := by rw [gaussianReal_of_var_ne_zero _ h] infer_instance +@[deprecated (since := "2026-06-09")] +alias noAtoms_gaussianReal := nullSingletonClass_gaussianReal + lemma gaussianReal_apply (μ : ℝ) {v : ℝ≥0} (hv : v ≠ 0) (s : Set ℝ) : gaussianReal μ v s = ∫⁻ x in s, gaussianPDF μ v x := by rw [gaussianReal_of_var_ne_zero _ hv, withDensity_apply' _ s] diff --git a/scripts/nolints_prime_decls.txt b/scripts/nolints_prime_decls.txt index 98c8ef29d15948..ac4950dd3c6013 100644 --- a/scripts/nolints_prime_decls.txt +++ b/scripts/nolints_prime_decls.txt @@ -2651,7 +2651,7 @@ MeasureTheory.Measure.map_id' MeasureTheory.Measure.measurable_bind' MeasureTheory.Measure.MeasureDense.nonempty' MeasureTheory.Measure.nonpos_iff_eq_zero' -MeasureTheory.Measure.pi_noAtoms' +MeasureTheory.Measure.pi_nullSingletonClass' MeasureTheory.MeasurePreserving.integral_comp' MeasureTheory.Measure.restrict_apply₀' MeasureTheory.Measure.restrict_apply_eq_zero' From a66a71b38c4515dcad4e816123e1cd4abd8b8c8f Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 22 Jun 2026 11:37:58 +0000 Subject: [PATCH 0242/1300] chore(CategoryTheory): generalise `Comma.initial_fst` and `Comma.isCofiltered_of_initial` (#40556) We replace the `Functor.Initial L` assumption in `Comma.initial_fst` and `Comma.isCofiltered_of_initial` by the assumption that `CostructuredArrow L (R.obj b)` is cofiltered for all `b` (`L.Initial` corresponds to all `CostructuredArrow L t` being cofiltered). We also provide the dual versions. We also give a new proof for `Comma.initial_snd`, only assuming connectedness of certain `CostructuredArrow` categories, by transporting along an adjunction. From Proetale and then subsequently cleaned up and generalised by Claude Fable 5. This generalisation is used in a follow-up PR to show that morphisms between cofiltered limits where the components of the target are finitely presented can be written as a cofiltered limit of morphisms. --- Mathlib/CategoryTheory/Comma/Final.lean | 183 +++++++++--------- .../Comma/StructuredArrow/Basic.lean | 40 ++++ Mathlib/CategoryTheory/Filtered/Final.lean | 8 + .../Limits/Indization/Category.lean | 1 + 4 files changed, 143 insertions(+), 89 deletions(-) diff --git a/Mathlib/CategoryTheory/Comma/Final.lean b/Mathlib/CategoryTheory/Comma/Final.lean index 471c7c667af357..04608f5d124a3e 100644 --- a/Mathlib/CategoryTheory/Comma/Final.lean +++ b/Mathlib/CategoryTheory/Comma/Final.lean @@ -5,12 +5,8 @@ Authors: Jakob von Raumer -/ module -public import Mathlib.CategoryTheory.Functor.KanExtension.Adjunction public import Mathlib.CategoryTheory.Limits.IsConnected -public import Mathlib.CategoryTheory.Limits.Sifted public import Mathlib.CategoryTheory.Filtered.Final -public import Mathlib.CategoryTheory.Filtered.Flat -public import Mathlib.CategoryTheory.Grothendieck public import Mathlib.CategoryTheory.Comma.StructuredArrow.CommaMap /-! @@ -41,60 +37,95 @@ namespace Comma open Limits Functor CostructuredArrow -section Small - -variable {A : Type v₁} [Category.{v₁} A] -variable {B : Type v₁} [Category.{v₁} B] -variable {T : Type v₁} [Category.{v₁} T] -variable (L : A ⥤ T) (R : B ⥤ T) - -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -private lemma final_fst_small [R.Final] : (fst L R).Final := by - rw [Functor.final_iff_isIso_colimit_pre] - intro G - let i : colimit G ≅ colimit (fst L R ⋙ G) := - colimitIsoColimitGrothendieck L G ≪≫ - (Final.colimitIso (Grothendieck.pre (functor L) R) (grothendieckProj L ⋙ G)).symm ≪≫ - HasColimit.isoOfNatIso (Iso.refl _) ≪≫ - Final.colimitIso (grothendieckPrecompFunctorEquivalence L R).functor (fst L R ⋙ G) - convert! i.isIso_inv - apply colimit.hom_ext - intro ⟨a, b, f⟩ - simp only [colimit.ι_pre, comp_obj, fst_obj, grothendieckPrecompFunctorEquivalence_functor, - Iso.trans_inv, Iso.symm_inv, Category.assoc, i] - change _ = colimit.ι (fst L R ⋙ G) - ((grothendieckPrecompFunctorToComma L R).obj ⟨b, CostructuredArrow.mk f⟩) ≫ _ - simp - -end Small - -section NonSmall - variable {A : Type u₁} [Category.{v₁} A] variable {B : Type u₂} [Category.{v₂} B] variable {T : Type u₃} [Category.{v₃} T] variable (L : A ⥤ T) (R : B ⥤ T) -instance final_fst [R.Final] : (fst L R).Final := by - let sA : A ≌ AsSmall.{max u₁ u₂ u₃ v₁ v₂ v₃} A := AsSmall.equiv - let sB : B ≌ AsSmall.{max u₁ u₂ u₃ v₁ v₂ v₃} B := AsSmall.equiv - let sT : T ≌ AsSmall.{max u₁ u₂ u₃ v₁ v₂ v₃} T := AsSmall.equiv - let L' := sA.inverse ⋙ L ⋙ sT.functor - let R' := sB.inverse ⋙ R ⋙ sT.functor - let fC : Comma L R ⥤ Comma L' R' := - map (F₁ := sA.functor) (F := sT.functor) (F₂ := sB.functor) - (isoWhiskerRight sA.unitIso (L ⋙ sT.functor)).hom - (isoWhiskerRight sB.unitIso (R ⋙ sT.functor)).hom - have : Final (fst L' R') := final_fst_small _ _ - apply final_of_natIso (F := (fC ⋙ fst L' R' ⋙ sA.inverse)) - exact (Functor.associator _ _ _).symm.trans (Iso.compInverseIso (mapFst _ _)) - -instance initial_snd [L.Initial] : (snd L R).Initial := by - have : ((opFunctor L R).leftOp ⋙ fst R.op L.op).Final := - final_equivalence_comp (opEquiv L R).functor.leftOp (fst R.op L.op) - have : (snd L R).op.Final := final_of_natIso (opFunctorCompFst _ _) - apply initial_of_final_op +section Relative + +lemma isCofiltered_of_isCofiltered_costructuredArrow [IsCofiltered A] [IsCofiltered B] + [∀ b, IsCofiltered (CostructuredArrow L (R.obj b))] : IsCofiltered (Comma L R) where + nonempty := by + obtain ⟨b⟩ := IsCofiltered.nonempty (C := B) + obtain ⟨X⟩ : Nonempty (CostructuredArrow L (R.obj b)) := IsCofiltered.nonempty + exact ⟨⟨X.left, b, X.hom⟩⟩ + toIsCofilteredOrEmpty := by + refine ⟨fun j₁ j₂ ↦ ?_, fun j₁ j₂ u v ↦ ?_⟩ + · obtain ⟨Q⟩ : Nonempty (CostructuredArrow L (R.obj (IsCofiltered.min j₁.right j₂.right))) := + IsCofiltered.nonempty + obtain ⟨ia, va₁, va₂, heqa⟩ := exists_eq_of_isCofiltered_costructuredArrow L + (Q.hom ≫ R.map (IsCofiltered.minToLeft j₁.right j₂.right)) j₁.hom + obtain ⟨ib, vb₁, vb₂, heqb⟩ := exists_eq_of_isCofiltered_costructuredArrow L + (Q.hom ≫ R.map (IsCofiltered.minToRight j₁.right j₂.right)) j₂.hom + obtain ⟨i₀, il₀, ir₀, heq⟩ := IsCofiltered.cospan va₁ vb₁ + exact ⟨⟨i₀, IsCofiltered.min j₁.right j₂.right, L.map (il₀ ≫ va₁) ≫ Q.hom⟩, + ⟨il₀ ≫ va₂, IsCofiltered.minToLeft _ _, by simp [← heqa]⟩, + ⟨ir₀ ≫ vb₂, IsCofiltered.minToRight _ _, by cat_disch⟩, trivial⟩ + · obtain ⟨Q⟩ : Nonempty (CostructuredArrow L (R.obj (IsCofiltered.eq u.right v.right))) := + IsCofiltered.nonempty + obtain ⟨ia, va₁, va₂, heqa⟩ := exists_eq_of_isCofiltered_costructuredArrow L + (Q.hom ≫ R.map (IsCofiltered.eqHom u.right v.right)) j₁.hom + obtain ⟨i₀, α, β, hα, hβ⟩ := IsCofiltered.bowtie u.left (va₂ ≫ v.left) (𝟙 _) va₂ + have := IsCofiltered.eq_condition u.right v.right + exact ⟨⟨i₀, IsCofiltered.eq u.right v.right, L.map (β ≫ va₁) ≫ Q.hom⟩, + ⟨β ≫ va₂, IsCofiltered.eqHom u.right v.right, by cat_disch⟩, by cat_disch⟩ + +set_option backward.isDefEq.respectTransparency false in +lemma initial_fst_of_isCofiltered_costructuredArrow [IsCofiltered A] [IsCofiltered B] + [∀ b, IsCofiltered (CostructuredArrow L (R.obj b))] : (fst L R).Initial := by + have := isCofiltered_of_isCofiltered_costructuredArrow L R + rw [Functor.initial_iff_of_isCofiltered] + refine ⟨fun a ↦ ?_, fun {a} A' s s' ↦ ?_⟩ + · obtain ⟨b⟩ := IsCofiltered.nonempty (C := B) + obtain ⟨X⟩ : Nonempty (CostructuredArrow L (R.obj b)) := IsCofiltered.nonempty + exact ⟨⟨IsCofiltered.min a X.left, b, L.map (IsCofiltered.minToRight a X.left) ≫ X.hom⟩, + ⟨IsCofiltered.minToLeft a X.left⟩⟩ + · exact ⟨⟨_, A'.right, L.map (IsCofiltered.eqHom s s') ≫ A'.hom⟩, + ⟨IsCofiltered.eqHom s s', 𝟙 A'.right, by simp⟩, IsCofiltered.eq_condition s s'⟩ + +lemma initial_snd_of_isConnected_costructuredArrow + [∀ b, IsConnected (CostructuredArrow L (R.obj b))] : (snd L R).Initial where + out b := by + have := final_of_adjunction (costructuredArrowSndAdjunction L R b) + rw [← isConnected_iff_of_final (costructuredArrowSndInclusion L R b)] + infer_instance + +lemma isFiltered_of_isFiltered_structuredArrow [IsFiltered A] [IsFiltered B] + [∀ a, IsFiltered (StructuredArrow (L.obj a) R)] : IsFiltered (Comma L R) := by + have (a : Aᵒᵖ) : IsCofiltered (CostructuredArrow R.op (L.op.obj a)) := + IsCofiltered.of_equivalence (structuredArrowOpEquivalence R (L.obj a.unop)) + have : IsCofiltered (Comma R.op L.op) := isCofiltered_of_isCofiltered_costructuredArrow _ _ + exact IsFiltered.of_equivalence (opEquiv L R).symm + +lemma final_fst_of_isConnected_structuredArrow + [∀ a, IsConnected (StructuredArrow (L.obj a) R)] : (fst L R).Final := by + have (a : Aᵒᵖ) : IsConnected (CostructuredArrow R.op (L.op.obj a)) := + (isConnected_iff_of_equivalence (structuredArrowOpEquivalence R (L.obj a.unop))).mp + inferInstance + have : (snd R.op L.op).Initial := initial_snd_of_isConnected_costructuredArrow _ _ + have : ((opFunctor L R).leftOp ⋙ snd R.op L.op).Initial := + initial_equivalence_comp (opEquiv L R).functor.leftOp _ + have : (fst L R).op.Initial := initial_of_natIso <| opFunctorCompSnd _ _ + apply final_of_initial_op + +lemma final_snd_of_isFiltered_structuredArrow [IsFiltered A] [IsFiltered B] + [∀ a, IsFiltered (StructuredArrow (L.obj a) R)] : (snd L R).Final := by + have (a : Aᵒᵖ) : IsCofiltered (CostructuredArrow R.op (L.op.obj a)) := + IsCofiltered.of_equivalence (structuredArrowOpEquivalence R (L.obj a.unop)) + have : (fst R.op L.op).Initial := initial_fst_of_isCofiltered_costructuredArrow _ _ + have : ((opFunctor L R).leftOp ⋙ fst R.op L.op).Initial := + initial_equivalence_comp (opEquiv L R).functor.leftOp _ + have : (snd L R).op.Initial := initial_of_natIso <| opFunctorCompFst _ _ + apply final_of_initial_op + +end Relative + +instance initial_snd [L.Initial] : (snd L R).Initial := + initial_snd_of_isConnected_costructuredArrow L R + +instance final_fst [R.Final] : (fst L R).Final := + final_fst_of_isConnected_structuredArrow L R /-- `Comma L R` with `L : A ⥤ T` and `R : B ⥤ T` is connected if `R` is final and `A` is connected. -/ @@ -106,8 +137,6 @@ connected. -/ instance isConnected_comma_of_initial [IsConnected B] [L.Initial] : IsConnected (Comma L R) := by rwa [isConnected_iff_of_initial (snd L R)] -end NonSmall - set_option backward.defeqAttrib.useBackward true in /-- Let the following diagram commute up to isomorphism: @@ -148,54 +177,30 @@ lemma map_final {A : Type u₁} [Category.{v₁} A] {B : Type u₂} [Category.{v section Filtered -variable {A : Type u₁} [Category.{v₁} A] -variable {B : Type u₂} [Category.{v₂} B] -variable {T : Type u₃} [Category.{v₃} T] -variable (L : A ⥤ T) (R : B ⥤ T) - -set_option backward.defeqAttrib.useBackward true in -attribute [local instance] map_final in /-- Let `A` and `B` be filtered categories, `R : B ⥤ T` be final and `L : A ⥤ T`. Then, the comma category `Comma L R` is filtered. -/ instance isFiltered_of_final [IsFiltered A] [IsFiltered B] [R.Final] : IsFiltered (Comma L R) := by - haveI (a : A) : IsFiltered (Comma (fromPUnit (L.obj a)) R) := - R.final_iff_isFiltered_structuredArrow.mp inferInstance (L.obj a) - have (a : A) : (fromPUnit (Over.mk (𝟙 a))).Final := final_const_of_isTerminal Over.mkIdTerminal - let η (a : A) : fromPUnit (Over.mk (𝟙 a)) ⋙ Over.forget a ⋙ L ≅ fromPUnit (L.obj a) := - NatIso.ofComponents (fun _ => Iso.refl _) - have (a : A) := IsFiltered.of_final (map (L := fromPUnit (L.obj a)) (F := 𝟭 T) (η a).hom - ((Iso.refl (𝟭 B ⋙ R)).inv)) - have : RepresentablyCoflat (fst L R) := - ⟨fun a => IsFiltered.of_equivalence (CostructuredArrow.ofCommaFstEquivalence L R a).symm⟩ - apply isFiltered_of_representablyCoflat (fst L R) - -attribute [local instance] isFiltered_of_final in + have := R.final_iff_isFiltered_structuredArrow.mp inferInstance + exact isFiltered_of_isFiltered_structuredArrow L R + /-- Let `A` and `B` be cofiltered categories, `L : A ⥤ T` be initial and `R : B ⥤ T`. Then, the comma category `Comma L R` is cofiltered. -/ lemma isCofiltered_of_initial [IsCofiltered A] [IsCofiltered B] [L.Initial] : - IsCofiltered (Comma L R) := - IsCofiltered.of_equivalence (Comma.opEquiv _ _).symm + IsCofiltered (Comma L R) := by + have := L.initial_iff_isCofiltered_costructuredArrow.mp inferInstance + exact isCofiltered_of_isCofiltered_costructuredArrow L R -set_option backward.defeqAttrib.useBackward true in -attribute [local instance] final_of_isFiltered_of_pUnit in /-- Let `A` and `B` be filtered categories, `R : B ⥤ T` be final and `R : A ⥤ T`. Then, the projection `snd L R : Comma L R ⥤ B` is final. -/ instance final_snd [IsFiltered A] [IsFiltered B] [R.Final] : (snd L R).Final := by - let iL : star.{1} A ⋙ 𝟭 _ ≅ L ⋙ star _ := Iso.refl _ - let iR : 𝟭 B ⋙ star.{1} B ≅ R ⋙ star _ := Iso.refl _ - have := map_final iL iR - let s := (equivProd (𝟭 _) (star B)).trans <| prod.leftUnitorEquivalence B - let iS : map iL.hom iR.inv ⋙ s.functor ≅ snd L R := - NatIso.ofComponents (fun _ => Iso.refl _) (fun f => by simp [iL, iR, s]) - apply final_of_natIso iS + have := R.final_iff_isFiltered_structuredArrow.mp inferInstance + exact final_snd_of_isFiltered_structuredArrow L R /-- Let `A` and `B` be cofiltered categories, `L : A ⥤ T` be initial and `R : B ⥤ T`. Then, the projection `fst L R : Comma L R ⥤ A` is initial. -/ instance initial_fst [IsCofiltered A] [IsCofiltered B] [L.Initial] : (fst L R).Initial := by - have : ((opFunctor L R).leftOp ⋙ snd R.op L.op).Final := - final_equivalence_comp (opEquiv L R).functor.leftOp _ - have : (fst L R).op.Final := final_of_natIso <| opFunctorCompSnd _ _ - apply initial_of_final_op + have := L.initial_iff_isCofiltered_costructuredArrow.mp inferInstance + exact initial_fst_of_isCofiltered_costructuredArrow L R end Filtered diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean index 320b6d70cd3c9e..5e5e0000dd8dcf 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean @@ -5,6 +5,7 @@ Authors: Adam Topaz, Kim Morrison -/ module +public import Mathlib.CategoryTheory.Adjunction.Basic public import Mathlib.CategoryTheory.PUnit public import Mathlib.CategoryTheory.Limits.Shapes.IsTerminal public import Mathlib.CategoryTheory.Functor.EpiMono @@ -1271,4 +1272,43 @@ end end Prod +namespace Comma + +variable {A : Type u₁} [Category.{v₁} A] {B : Type u₂} [Category.{v₂} B] + {T : Type u₃} [Category.{v₃} T] (L : A ⥤ T) (R : B ⥤ T) + +set_option backward.defeqAttrib.useBackward true in +/-- The functor from the costructured arrow category on `snd L R` over `b : B` to the +costructured arrow category on `L` over `R.obj b`. It is left adjoint to +`costructuredArrowSndInclusion`, see `costructuredArrowSndAdjunction`. -/ +@[simps] +def costructuredArrowSndProj (b : B) : + CostructuredArrow (snd L R) b ⥤ CostructuredArrow L (R.obj b) where + obj X := CostructuredArrow.mk (X.left.hom ≫ R.map X.hom) + map f := CostructuredArrow.homMk f.left.left <| by + dsimp + rw [reassoc_of% f.left.w, ← R.map_comp, dsimp% CostructuredArrow.w f] + +set_option backward.defeqAttrib.useBackward true in +/-- The functor from the costructured arrow category on `L` over `R.obj b` to the costructured +arrow category on `snd L R` over `b : B`. -/ +@[simps] +def costructuredArrowSndInclusion (b : B) : + CostructuredArrow L (R.obj b) ⥤ CostructuredArrow (snd L R) b where + obj X := ⟨⟨X.left, b, X.hom⟩, ⟨⟨⟩⟩, 𝟙 b⟩ + map f := CostructuredArrow.homMk ⟨f.left, 𝟙 b, by simp⟩ (by simp) + +set_option backward.defeqAttrib.useBackward true in +/-- The functor `costructuredArrowSndProj` is left adjoint to `costructuredArrowSndInclusion`. -/ +@[simps] +def costructuredArrowSndAdjunction (b : B) : + costructuredArrowSndProj L R b ⊣ costructuredArrowSndInclusion L R b where + unit.app X := CostructuredArrow.homMk ⟨𝟙 X.left.left, X.hom, by simp⟩ (by simp) + unit.naturality _ _ f := by + have := CostructuredArrow.w f + cat_disch + counit.app X := CostructuredArrow.homMk (𝟙 X.left) (by simp) + +end Comma + end CategoryTheory diff --git a/Mathlib/CategoryTheory/Filtered/Final.lean b/Mathlib/CategoryTheory/Filtered/Final.lean index edd610db14229d..604403e69da7d9 100644 --- a/Mathlib/CategoryTheory/Filtered/Final.lean +++ b/Mathlib/CategoryTheory/Filtered/Final.lean @@ -92,6 +92,14 @@ theorem isCofiltered_costructuredArrow_of_isCofiltered_of_exists [IsCofilteredOr obtain ⟨c', t, ht⟩ := h₂ s.unop s'.unop exact ⟨op c', Quiver.Hom.op t, Quiver.Hom.unop_inj ht⟩ +theorem exists_eq_of_isCofiltered_costructuredArrow {d : D} + [IsCofiltered (CostructuredArrow F d)] {c₁ c₂ : C} + (s₁ : F.obj c₁ ⟶ d) (s₂ : F.obj c₂ ⟶ d) : + ∃ (c : C) (t₁ : c ⟶ c₁) (t₂ : c ⟶ c₂), F.map t₁ ≫ s₁ = F.map t₂ ≫ s₂ := by + obtain ⟨W, p₁, p₂, -⟩ := IsCofilteredOrEmpty.cone_objs + (CostructuredArrow.mk s₁) (CostructuredArrow.mk s₂) + exact ⟨W.left, p₁.left, p₂.left, (CostructuredArrow.w p₁).trans (CostructuredArrow.w p₂).symm⟩ + /-- If `C` is filtered, then we can give an explicit condition for a functor `F : C ⥤ D` to be final. The converse is also true, see `final_iff_of_isFiltered`. -/ theorem Functor.final_of_exists_of_isFiltered [IsFilteredOrEmpty C] diff --git a/Mathlib/CategoryTheory/Limits/Indization/Category.lean b/Mathlib/CategoryTheory/Limits/Indization/Category.lean index 8d05c3bbbb0845..30937a6d5a8a6a 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/Category.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/Category.lean @@ -5,6 +5,7 @@ Authors: Markus Himmel -/ module +public import Mathlib.CategoryTheory.Functor.Flat public import Mathlib.CategoryTheory.Limits.Constructions.Filtered public import Mathlib.CategoryTheory.Limits.FullSubcategory public import Mathlib.CategoryTheory.Limits.ExactFunctor From 096aa7bdd13870ac40178ca4bdb8dc9298ed77dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:14:32 +0000 Subject: [PATCH 0243/1300] feat(Algebra/Homology/Embedding): various results about truncations (#40885) --- .../Homology/Embedding/CochainComplex.lean | 57 +++++++++++++++++++ .../Homology/Embedding/TruncGEHomology.lean | 5 ++ .../Homology/Embedding/TruncLEHomology.lean | 5 ++ 3 files changed, 67 insertions(+) diff --git a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean index cd3908b34d4fc7..800a7708629da9 100644 --- a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean +++ b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean @@ -361,6 +361,63 @@ end end Preadditive +section HasZeroMorphisms + +variable {C : Type*} [Category C] [HasZeroMorphisms C] [HasZeroObject C] + (K L : CochainComplex C ℤ) (φ : K ⟶ L) (e : K ≅ L) + [∀ (i : ℤ), K.HasHomology i] [∀ (i : ℤ), L.HasHomology i] (n : ℤ) + +set_option backward.defeqAttrib.useBackward true in +/-- When `K` is a cochain complex indexed by `ℤ` and `n < i`, this is +the isomorphism `(K.truncGE n).X i ≅ K.X i`. -/ +noncomputable def truncGEXIso (n i : ℤ) (hi : n < i := by lia) : + (K.truncGE n).X i ≅ K.X i := + HomologicalComplex.truncGEXIso K (embeddingUpIntGE n) (i := (i - n).natAbs) (by + dsimp + rw [Int.natAbs_of_nonneg (by lia), add_sub_cancel]) + (fun h ↦ by + rw [boundaryGE_embeddingUpIntGE_iff, Int.natAbs_eq_zero] at h + lia) + +set_option backward.defeqAttrib.useBackward true in +/-- When `K` is a cochain complex indexed by `ℤ` and `i < n`, this is +the isomorphism `(K.truncLE n).X i ≅ K.X i`. -/ +noncomputable def truncLEXIso (n i : ℤ) (hi : i < n := by lia) : + (K.truncLE n).X i ≅ K.X i := + HomologicalComplex.truncLEXIso K (embeddingUpIntLE n) (i := (n - i).natAbs) (by + dsimp + rw [Int.natAbs_of_nonneg (by lia), sub_sub_cancel]) + (fun h ↦ by + rw [boundaryLE_embeddingUpIntLE_iff, Int.natAbs_eq_zero] at h + lia) + +/-- When `K` is a cochain complex indexed by `ℤ`, this is the isomorphism +`(K.truncGE n).X n ≅ K.opcycles n`. -/ +noncomputable def truncGEXIsoOpcycles (n : ℤ) : + (K.truncGE n).X n ≅ K.opcycles n := + HomologicalComplex.truncGEXIsoOpcycles K (embeddingUpIntGE n) (i := 0) (by simp) + (by rw [boundaryGE_embeddingUpIntGE_iff]) + +/-- When `K` is a cochain complex indexed by `ℤ`, this is the isomorphism +`(K.truncLE n).X n ≅ K.cycles n`. -/ +noncomputable def truncLEXIsoCycles (n : ℤ) : + (K.truncLE n).X n ≅ K.cycles n := + HomologicalComplex.truncLEXIsoCycles K (embeddingUpIntLE n) (i := 0) (by simp) + (by rw [boundaryLE_embeddingUpIntLE_iff]) + +lemma acyclic_truncGE_iff (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁ := by lia) : + (K.truncGE n₁).Acyclic ↔ K.IsLE n₀ := by + dsimp [truncGE] + rw [acyclic_truncGE_iff_isSupportedOutside, + (Embedding.embeddingUpInt_areComplementary n₀ n₁ h).isSupportedOutside₂_iff] + +lemma acyclic_truncLE_iff (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁ := by lia) : + (K.truncLE n₀).Acyclic ↔ K.IsGE n₁ := by + dsimp [truncLE] + rw [acyclic_truncLE_iff_isSupportedOutside, + (Embedding.embeddingUpInt_areComplementary n₀ n₁ h).isSupportedOutside₁_iff] + +end HasZeroMorphisms section Abelian diff --git a/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean b/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean index 4a3dfcb22871f7..bc11bec38b692a 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean @@ -226,6 +226,11 @@ lemma acyclic_truncGE_iff_isSupportedOutside : variable {K L} +lemma Acyclic.truncGE (hK : K.Acyclic) (e : c.Embedding c') [e.IsTruncGE] : + (K.truncGE e).Acyclic := by + rw [acyclic_truncGE_iff_isSupportedOutside] + exact ⟨fun _ ↦ hK _⟩ + lemma quasiIso_truncGEMap_iff : QuasiIso (truncGEMap φ e) ↔ ∀ (i : ι) (i' : ι') (_ : e.f i = i'), QuasiIsoAt φ i' := by have : ∀ (i : ι) (i' : ι') (_ : e.f i = i'), diff --git a/Mathlib/Algebra/Homology/Embedding/TruncLEHomology.lean b/Mathlib/Algebra/Homology/Embedding/TruncLEHomology.lean index 4dce5e6f3311e7..d502131ca9842d 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncLEHomology.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncLEHomology.lean @@ -84,6 +84,11 @@ lemma acyclic_truncLE_iff_isSupportedOutside : variable {K L} +lemma Acyclic.truncLE (hK : K.Acyclic) (e : c.Embedding c') [e.IsTruncLE] : + (K.truncLE e).Acyclic := by + rw [acyclic_truncLE_iff_isSupportedOutside] + exact ⟨fun _ ↦ hK _⟩ + lemma quasiIso_truncLEMap_iff : QuasiIso (truncLEMap φ e) ↔ ∀ (i : ι) (i' : ι') (_ : e.f i = i'), QuasiIsoAt φ i' := by rw [← quasiIso_opFunctor_map_iff] From 7303d3ac82e38d773c820841c73fffeaaf8fd46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:31:45 +0000 Subject: [PATCH 0244/1300] feat(CategoryTheory/Shift): left composition with a shift sequence (#40888) --- .../CategoryTheory/Shift/ShiftSequence.lean | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Shift/ShiftSequence.lean b/Mathlib/CategoryTheory/Shift/ShiftSequence.lean index 47ada4ddad480f..a94a1a3ff4b091 100644 --- a/Mathlib/CategoryTheory/Shift/ShiftSequence.lean +++ b/Mathlib/CategoryTheory/Shift/ShiftSequence.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.CategoryTheory.Shift.Basic +public import Mathlib.CategoryTheory.Shift.CommShift public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor /-! # Sequences of functors from a category equipped with a shift @@ -33,8 +33,9 @@ set_option backward.defeqAttrib.useBackward true open CategoryTheory Category ZeroObject Limits -variable {C A : Type*} [Category* C] [Category* A] (F : C ⥤ A) - (M : Type*) [AddMonoid M] [HasShift C M] +variable {C D A : Type*} [Category* C] [Category* D] [Category* A] (F : C ⥤ A) + {π : C ⥤ D} {H : D ⥤ A} (e : π ⋙ H ≅ F) + (M : Type*) [AddMonoid M] [HasShift C M] [HasShift D M] {G : Type*} [AddGroup G] [HasShift C G] namespace CategoryTheory @@ -283,6 +284,37 @@ end end +namespace ShiftSequence + +variable {F} in +set_option backward.isDefEq.respectTransparency false in +/-- Given an isomorphism `π ⋙ H ≅ F`, where `π` is a functor which commutes +with the shift by `M` and `H` is equipped with a shift sequence, +then this is the shift sequence for `F` induced by composition. -/ +@[implicit_reducible, simps] +def leftComp [π.CommShift M] [H.ShiftSequence M] : F.ShiftSequence M where + sequence n := π ⋙ H.shift n + isoZero := isoWhiskerLeft π (H.isoShiftZero M) ≪≫ e + shiftIso n a a' ha' := + (Functor.associator _ _ _).symm ≪≫ + isoWhiskerRight (π.commShiftIso n) _ ≪≫ Functor.associator _ _ _ ≪≫ + isoWhiskerLeft π (H.shiftIso n a a' ha') + shiftIso_zero a := by + ext K + simp [← Functor.map_comp, commShiftIso_zero] + shiftIso_add n m a a' a'' ha' ha'':= by + ext K + dsimp + simp only [H.shiftIso_add_hom_app n m a a' a'' ha' ha'', assoc, + commShiftIso_add, CommShift.isoAdd_hom_app, ← Functor.map_comp_assoc, + id_comp, Iso.inv_hom_id_app, comp_obj, comp_id] + simp + +instance [π.CommShift M] [H.ShiftSequence M] : (π ⋙ H).ShiftSequence M := + leftComp (Iso.refl _) _ + +end ShiftSequence + end Functor end CategoryTheory From 3052b11bee97540fb6feb75f8e4a392be7618add Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:53:37 +0000 Subject: [PATCH 0245/1300] feat(Algebra/Category): pushforward of quasi-coherent sheafs (#40231) We show that the pushforward of a quasi-coherent sheaf along a continuous and cocontinuous functor is quasi-coherent, if it preserves the unit. --- .../Sheaf/PushforwardContinuous.lean | 17 ++++ .../ModuleCat/Sheaf/Quasicoherent.lean | 81 +++++++++++++++++++ .../CategoryTheory/Comma/Over/Pullback.lean | 6 ++ Mathlib/CategoryTheory/Sites/Continuous.lean | 5 ++ .../CategoryTheory/Sites/CoverLifting.lean | 7 ++ Mathlib/CategoryTheory/Sites/Over.lean | 6 ++ 6 files changed, 122 insertions(+) diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean index 3686a18ae2f518..ba6bd327e13c56 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean @@ -292,6 +292,23 @@ lemma pushforwardPushforwardAdj_counit_app_val_app (M U x) : ((pushforwardPushforwardAdj adj φ ψ H₁ H₂).counit.app M).val.app U x = M.val.map (adj.unit.app U.unop).op x := rfl +set_option backward.defeqAttrib.useBackward true in +instance isLeftAdjoint_pushforward_of_isIso [F.IsCocontinuous J K] [IsIso φ] [F.IsLeftAdjoint] : + (pushforward.{u} φ).IsLeftAdjoint := by + let adj := Adjunction.ofIsLeftAdjoint F + let shAdj := adj.sheafPushforwardContinuous (E := RingCat.{u}) J K + let ψ : R ⟶ (F.rightAdjoint.sheafPushforwardContinuous RingCat.{u} K J).obj S := + shAdj.unit.app R ≫ (F.rightAdjoint.sheafPushforwardContinuous _ _ _).map (inv φ) + refine (SheafOfModules.pushforwardPushforwardAdj adj φ ψ ?_ ?_).isLeftAdjoint + · ext U : 2 + simp [ψ, shAdj] + · ext U : 2 + have := (inv φ).hom.naturality + dsimp at this + simp only [ObjectProperty.hom_inv, NatIso.isIso_inv_app, sheafPushforwardContinuous_obj_obj_obj, + IsIso.eq_inv_comp] at this + simp [ψ, shAdj, ← this, ← Functor.map_comp_assoc, ← op_comp] + noncomputable section open CategoryTheory Limits diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean index 0356d546d27ba4..dabdb76cef0767 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean @@ -282,6 +282,81 @@ instance (M : SheafOfModules.{u} R) [M.IsFinitePresentation] : obtain ⟨σ, _⟩ := IsFinitePresentation.exists_quasicoherentData M exact ⟨σ.localGeneratorsData, inferInstance⟩ +section map + +variable {D : Type u₂} [Category.{v₂, u₂} D] {K : GrothendieckTopology D} + {S : Sheaf K RingCat.{u}} [∀ (X : D), (K.over X).WEqualsLocallyBijective AddCommGrpCat] + [∀ (X : D), (K.over X).HasSheafCompose (forget₂ RingCat AddCommGrpCat)] + +variable [J.HasSheafCompose (forget₂ RingCat AddCommGrpCat)] + [K.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] + [∀ (X : C), HasSheafify (J.over X) AddCommGrpCat.{u}] + [∀ (X : D), HasSheafify (K.over X) AddCommGrpCat.{u}] + +variable (G : D ⥤ C) [G.IsContinuous K J] [G.IsCocontinuous K J] + (φ : S ⟶ (G.sheafPushforwardContinuous RingCat.{u} K J).obj R) + +/-- The pushforward of `SheafOfModules.QuasicoherentData` along a continuous +and cocontinuous functor. -/ +-- TODO: Remove the continuous assumption on `Over.post` here and below. +@[simps I X] +noncomputable def QuasicoherentData.pushforward (η : (pushforward φ).obj (unit R) ≅ unit S) + [∀ (X : D), (Over.post G).IsContinuous (K.over X) (J.over _)] + (h : ∀ (X : D) (Y : C) (f : G.obj X ⟶ Y), + PreservesColimitsOfSize.{u, u} <| + pushforward.{u} (R := (R.over Y)) (F := Over.post (X := X) G ⋙ Over.map f) + (((Over.forget X).sheafPushforwardContinuous RingCat.{u} (K.over X) K).map φ)) + {M : SheafOfModules.{u} R} (P : M.QuasicoherentData) : + QuasicoherentData ((pushforward φ).obj M) where + I := Σ (X : D) (i : P.I), G.obj X ⟶ P.X i + X i := i.1 + coversTop Y := by + refine K.superset_covering ?_ <| G.cover_lift K _ (P.coversTop (G.obj Y)) + intro Z g ⟨i, ⟨v⟩⟩ + exact ⟨⟨Z, i, v⟩, ⟨𝟙 _⟩⟩ + presentation i := by + letI overS : SheafOfModules.{u} S ⥤ SheafOfModules.{u} (S.over i.1) := + SheafOfModules.pushforward (𝟙 _) + letI G' := Over.post (X := i.1) G ⋙ Over.map i.2.2 + letI ψ : S.over i.1 ⟶ + (G'.sheafPushforwardContinuous RingCat.{u} (K.over i.1) (J.over (P.X i.2.1))).obj + (R.over (P.X i.2.1)) := + ((Over.forget i.1).sheafPushforwardContinuous RingCat.{u} (K.over i.1) K).map φ + letI e : (SheafOfModules.pushforward ψ).obj (unit (R.over (P.X i.snd.fst))) ≅ + unit (S.over i.fst) := overS.mapIso η + haveI : PreservesColimitsOfSize.{u, u, _} (SheafOfModules.pushforward ψ) := h _ _ _ + exact (P.presentation i.2.1).map (SheafOfModules.pushforward ψ) e.symm + +lemma isQuasicoherent_pushforward (η : (pushforward φ).obj (unit R) ≅ unit S) + [∀ (X : D), (Over.post G).IsContinuous (K.over X) (J.over _)] + (h : ∀ (X : D) (Y : C) (f : G.obj X ⟶ Y), + PreservesColimitsOfSize.{u, u} <| + pushforward.{u} (R := (R.over Y)) (F := Over.post (X := X) G ⋙ Over.map f) + (((Over.forget X).sheafPushforwardContinuous RingCat.{u} (K.over X) K).map φ)) + {M : SheafOfModules.{u} R} [IsQuasicoherent M] : + IsQuasicoherent ((pushforward φ).obj M) := + IsQuasicoherent.nonempty_quasicoherentData.some.pushforward G φ η h |>.isQuasicoherent + +set_option backward.isDefEq.respectTransparency false in +lemma isQuasicoherent_pushforward_of_isLeftAdjoint (η : (pushforward φ).obj (unit R) ≅ unit S) + [G.IsLeftAdjoint] [IsIso φ] + [∀ X, Functor.IsContinuous (Over.post (X := X) G) (K.over _) (J.over _)] + [HasPullbacks C] [HasPullbacks D] + {M : SheafOfModules.{u} R} [IsQuasicoherent M] : + IsQuasicoherent ((pushforward φ).obj M) := by + apply +allowSynthFailures isQuasicoherent_pushforward G φ η _ + intro X Y f + let G' := Over.post (X := X) G ⋙ Over.map f + have : G'.IsContinuous (K.over X) (J.over Y) := Functor.isContinuous_comp _ _ _ (J.over _) _ + have : G'.IsCocontinuous (K.over X) (J.over Y) := isCocontinuous_comp _ _ _ (J.over _) + let a : S.over X ⟶ + (G'.sheafPushforwardContinuous RingCat.{u} (K.over X) (J.over Y)).obj (R.over Y) := + ((Over.forget X).sheafPushforwardContinuous RingCat.{u} (K.over X) K).map φ + have : (pushforward.{u} a).IsLeftAdjoint := isLeftAdjoint_pushforward_of_isIso a + infer_instance + +end map + end noncomputable section @@ -375,6 +450,12 @@ lemma IsQuasicoherent.of_coversTop {R : Sheaf J RingCat.{u}} (QuasicoherentData.bind M X hX fun _ ↦ IsQuasicoherent.nonempty_quasicoherentData.some).isQuasicoherent +set_option backward.isDefEq.respectTransparency false in +lemma isQuasicoherent_over [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] + [HasPullbacks C] [HasBinaryProducts C] (M : SheafOfModules.{u} R) (X : C) [IsQuasicoherent M] : + IsQuasicoherent (M.over X) := + isQuasicoherent_pushforward_of_isLeftAdjoint _ _ (Iso.refl _) + end bind end SheafOfModules diff --git a/Mathlib/CategoryTheory/Comma/Over/Pullback.lean b/Mathlib/CategoryTheory/Comma/Over/Pullback.lean index 4eb249b5a8a64d..45e64ac8d25c1c 100644 --- a/Mathlib/CategoryTheory/Comma/Over/Pullback.lean +++ b/Mathlib/CategoryTheory/Comma/Over/Pullback.lean @@ -87,6 +87,12 @@ def mapPullbackAdj {X Y : C} (f : X ⟶ Y) [HasPullbacksAlong f] : · simp · simpa using (Over.w v).symm } } +instance {X Y : C} (f : X ⟶ Y) [HasPullbacksAlong f] : (Over.map f).IsLeftAdjoint := + (Over.mapPullbackAdj f).isLeftAdjoint + +instance {X Y : C} (f : X ⟶ Y) [HasPullbacksAlong f] : (Over.pullback f).IsRightAdjoint := + (Over.mapPullbackAdj f).isRightAdjoint + set_option backward.isDefEq.respectTransparency false in /-- The pullback along an epi that's preserved under pullbacks is faithful. diff --git a/Mathlib/CategoryTheory/Sites/Continuous.lean b/Mathlib/CategoryTheory/Sites/Continuous.lean index 51995a1d8a49f6..48d970342868c4 100644 --- a/Mathlib/CategoryTheory/Sites/Continuous.lean +++ b/Mathlib/CategoryTheory/Sites/Continuous.lean @@ -80,6 +80,11 @@ lemma map_id : E.map (𝟭 _) = E := lemma map_comp {D' : Type*} [Category* D'] (G : D ⥤ D') : E.map (F ⋙ G) = (E.map F).map G := rfl +lemma sieve₀_map : (E.map F).sieve₀ = Sieve.functorPushforward _ E.sieve₀ := by + rw [PreZeroHypercover.sieve₀, Sieve.ofArrows, ← PreZeroHypercover.presieve₀, + PreOneHypercover.map_toPreZeroHypercover, PreZeroHypercover.presieve₀_map, + Sieve.generate_map_eq_functorPushforward] + /-- If `F : C ⥤ D`, `P : Dᵒᵖ ⥤ A` and `E` is a 1-pre-hypercover of an object of `X`, then `(E.map F).multifork P` is a limit iff `E.multifork (F.op ⋙ P)` is a limit. -/ def isLimitMapMultiforkEquiv {A : Type u} [Category.{t} A] (P : Dᵒᵖ ⥤ A) : diff --git a/Mathlib/CategoryTheory/Sites/CoverLifting.lean b/Mathlib/CategoryTheory/Sites/CoverLifting.lean index daec56154214c6..7590a8bf0ece84 100644 --- a/Mathlib/CategoryTheory/Sites/CoverLifting.lean +++ b/Mathlib/CategoryTheory/Sites/CoverLifting.lean @@ -102,6 +102,13 @@ lemma Functor.IsCocontinuous.iff_of_iso {F G : C ⥤ D} (e : F ≅ G) : F.IsCocontinuous J K ↔ G.IsCocontinuous J K := ⟨fun _ ↦ .of_iso e, fun _ ↦ .of_iso e.symm⟩ +lemma CoverPreserving.of_comp_of_isCocontinuous {F : C ⥤ D} (G : D ⥤ E) + (h : CoverPreserving J L (F ⋙ G)) [G.IsCocontinuous K L] [G.Full] [G.Faithful] : + CoverPreserving J K F where + cover_preserve {U} S hS := by + refine K.superset_covering ?_ (G.cover_lift K _ (h.cover_preserve hS)) + rw [Sieve.functorPushforward_comp, Sieve.functorPullback_functorPushforward_eq G] + section variable {F : C ⥤ D} {G : D ⥤ C} diff --git a/Mathlib/CategoryTheory/Sites/Over.lean b/Mathlib/CategoryTheory/Sites/Over.lean index fcbd6425dcac7a..b008c77f36e1fb 100644 --- a/Mathlib/CategoryTheory/Sites/Over.lean +++ b/Mathlib/CategoryTheory/Sites/Over.lean @@ -361,6 +361,12 @@ instance {D : Type*} [Category* D] {J : GrothendieckTopology C} {K : Grothendiec ← PreOneHypercover.map_comp, Over.post_forget_eq_forget_comp, PreOneHypercover.map_comp] exact E'.mem₁ _ _ _ _ congr($(w).left) +instance {D : Type*} [Category* D] {J : GrothendieckTopology C} {K : GrothendieckTopology D} + {F : C ⥤ D} (X : C) (Y : D) (f : F.obj X ⟶ Y) + [(Over.post F).IsContinuous (J.over X) (K.over _)] : + (Over.post F ⋙ Over.map f).IsContinuous (J.over X) (K.over Y) := + Functor.isContinuous_comp _ _ _ (K.over _) _ + open Limits lemma coverPreserving_overPullback [HasPullbacks C] {X Y : C} (f : X ⟶ Y) : From aa67fe566fe0ce9a8013fe869459f81b4b0a7c1a Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:37:06 +0000 Subject: [PATCH 0246/1300] chore(Topology): remove nonterminal simps (#40883) Together with #40882, this removes all occurences of `set_option linter.flexible false in` in `Mathlib/Topology`. Co-authored-by: Batixx --- Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean | 3 +-- Mathlib/Topology/UniformSpace/Ultra/Completion.lean | 8 +++----- Mathlib/Topology/UniformSpace/Ultra/Constructions.lean | 6 ++---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean index 85e6942e6f3c1c..293cc2d1ff385e 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean @@ -220,9 +220,8 @@ instance : (conditional β).LeAtTop := ⟨support_eq_univ_iff.mp <| by simpa [eq_univ_iff_forall, support, -eventually_and] using! fun x ↦ prod_mem_prod (eventually_le_atBot x) (eventually_ge_atTop x)⟩ -set_option linter.flexible false in -- simp followed by infer_instance instance [Nonempty β] [IsDirectedOrder β] [IsCodirectedOrder β] : (conditional β).NeBot := - ⟨by simp; infer_instance⟩ + ⟨by rw [conditional_filter]; infer_instance⟩ instance [IsCountablyGenerated (atTop : Filter β)] [IsCountablyGenerated (atBot : Filter β)] : IsCountablyGenerated (conditional β).filter := diff --git a/Mathlib/Topology/UniformSpace/Ultra/Completion.lean b/Mathlib/Topology/UniformSpace/Ultra/Completion.lean index 5aec77b1f95289..d06e74a7cea05e 100644 --- a/Mathlib/Topology/UniformSpace/Ultra/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Ultra/Completion.lean @@ -36,26 +36,24 @@ instance CauchyFilter.isSymm_gen {s : SetRel X X} [s.IsSymm] : (gen s).IsSymm wh instance CauchyFilter.isTrans_gen {s : SetRel X X} [s.IsTrans] : (gen s).IsTrans where trans _ _ _ := IsTransitiveRel.mem_filter_prod_trans -set_option linter.flexible false in -- simp followed by infer_instance instance IsUltraUniformity.cauchyFilter [IsUltraUniformity X] : IsUltraUniformity (CauchyFilter X) := by apply mk_of_hasBasis (CauchyFilter.basis_uniformity IsUltraUniformity.hasBasis) - · exact fun _ ⟨_, hU, _⟩ ↦ by simp; infer_instance - · exact fun _ ⟨_, _, hU⟩ ↦ by simp; infer_instance + · exact fun _ ⟨_, hU, _⟩ ↦ by simpa using CauchyFilter.isSymm_gen + · exact fun _ ⟨_, _, hU⟩ ↦ by simpa using CauchyFilter.isTrans_gen @[simp] lemma IsUltraUniformity.cauchyFilter_iff : IsUltraUniformity (CauchyFilter X) ↔ IsUltraUniformity X := ⟨fun _ ↦ CauchyFilter.isUniformInducing_pureCauchy.isUltraUniformity, fun _ ↦ inferInstance⟩ -set_option linter.flexible false in -- simp followed by infer_instance instance IsUltraUniformity.separationQuotient [IsUltraUniformity X] : IsUltraUniformity (SeparationQuotient X) := by have := IsUltraUniformity.hasBasis.map (Prod.map SeparationQuotient.mk (SeparationQuotient.mk (X := X))) rw [← SeparationQuotient.uniformity_eq] at this apply mk_of_hasBasis this - · exact fun _ ⟨_, hU, _⟩ ↦ by simp; infer_instance + · exact fun _ ⟨_, hU, _⟩ ↦ by rw [id_eq]; infer_instance · rintro U ⟨hU', _, hU⟩ constructor rintro x y z diff --git a/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean b/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean index 04bc6ab33be7c0..452694a5ae1732 100644 --- a/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean +++ b/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean @@ -77,15 +77,13 @@ instance IsUltraUniformity.pi {ι : Type*} {X : ι → Type*} [U : Π i, Uniform simpa +instances [Pi.uniformSpace_eq _] using this exact .iInf fun i ↦ .comap (h i) (Function.eval i) -set_option linter.flexible false in -- simp followed by infer_instance instance IsUltraUniformity.bot [UniformSpace X] [DiscreteUniformity X] : IsUltraUniformity X := by have := Filter.hasBasis_principal (SetRel.id (α := X)) rw [← DiscreteUniformity.eq_principal_setRelId] at this - apply mk_of_hasBasis this <;> { simp; infer_instance } + apply mk_of_hasBasis this <;> { rw [forall_const]; infer_instance } -set_option linter.flexible false in -- simp followed by infer_instance lemma IsUltraUniformity.top : @IsUltraUniformity X (⊤ : UniformSpace X) := by letI : UniformSpace X := ⊤ have := Filter.hasBasis_top (α := (X × X)) rw [← top_uniformity] at this - apply mk_of_hasBasis this <;> { simp; infer_instance } + apply mk_of_hasBasis this <;> { rw [forall_const]; infer_instance } From 42cb1fb8e141dde687c38791d4e1822bba057b86 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:05:21 +0000 Subject: [PATCH 0247/1300] feat(Projectivization/PSL/PSL2): PSL(2, F) is simple (#40000) --- Mathlib.lean | 1 + .../Matrix/SpecialLinearGroup.lean | 222 +++++++++++++++++- .../Projectivization/PSL/PSL2.lean | 137 +++++++++++ 3 files changed, 347 insertions(+), 13 deletions(-) create mode 100644 Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7a3a3e97044a3a..319c63732033c9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5167,6 +5167,7 @@ public import Mathlib.LinearAlgebra.Projectivization.Cardinality public import Mathlib.LinearAlgebra.Projectivization.Collinear public import Mathlib.LinearAlgebra.Projectivization.Constructions public import Mathlib.LinearAlgebra.Projectivization.Independence +public import Mathlib.LinearAlgebra.Projectivization.PSL.PSL2 public import Mathlib.LinearAlgebra.Projectivization.PSL.Stabilizer public import Mathlib.LinearAlgebra.Projectivization.Subspace public import Mathlib.LinearAlgebra.QuadraticForm.AlgClosed diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index c1d4b8090487ed..1ba86b265e8534 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -489,22 +489,38 @@ variable {ι F : Type*} [DecidableEq ι] [Fintype ι] [CommRing F] /-- The transvection `1 + b · E_{i,j}` (the identity plus `b` in position `(i, j)`) as an element of `SL ι F`, when `i ≠ j`. -/ -noncomputable def SpecialLinearGroup.transvection {i j : ι} (hij : i ≠ j) (b : F) : +def SpecialLinearGroup.transvection {i j : ι} (hij : i ≠ j) (b : F) : Matrix.SpecialLinearGroup ι F := - ⟨(1 : Matrix ι ι F) + single i j b, Matrix.det_transvection_of_ne i j hij b⟩ + ⟨Matrix.transvection i j b, Matrix.det_transvection_of_ne i j hij b⟩ namespace SpecialLinearGroup lemma transvection_coe {i j : ι} (hij : i ≠ j) (b : F) : (transvection hij b) = (1 : Matrix ι ι F) + single i j b := rfl +@[simp] +lemma transvection_coeff_zero {i j : ι} (hij : i ≠ j) : + transvection hij (0 : F) = 1 := by ext; simp [transvection_coe] + /-- The transvection `transvection i j hij b` acts on `e_i = Pi.single i 1` as the identity. -/ +lemma transvection_smul_single_fst {i j : ι} (hij : i ≠ j) (b : F) : + (transvection hij b) • (Pi.single i 1 : ι → F) = Pi.single i 1 := by + simp [SpecialLinearGroup.smul_def, -mulVec_single, transvection_coe, + add_mulVec, single_mulVec_eq, hij] + +@[deprecated transvection_smul_single_fst (since := "2026-06-22")] lemma transvection_mulVec_single_self {i j : ι} (hij : i ≠ j) (b : F) : (transvection hij b).1 *ᵥ (Pi.single i (1 : F)) = Pi.single i 1 := by rw [transvection_coe] simp [-mulVec_single, add_mulVec, single_mulVec_eq, hij] /-- The transvection `transvection i j hij b` acts on `e_j = Pi.single j 1` by adding `b·e_i`. -/ +lemma transvection_smul_single_snd {i j : ι} (hij : i ≠ j) (b : F) : + (transvection hij b) • (Pi.single j 1 : ι → F) = Pi.single j 1 + b • Pi.single i 1 := by + simp [SpecialLinearGroup.smul_def, transvection_coe, -mulVec_single, + add_mulVec, single_mulVec_eq] + +@[deprecated transvection_smul_single_snd (since := "2026-06-22")] lemma transvection_mulVec_single_other {i j : ι} (hij : i ≠ j) (b : F) : (transvection hij b).1 *ᵥ (Pi.single j (1 : F)) = Pi.single j 1 + b • Pi.single i 1 := by rw [transvection_coe] @@ -512,8 +528,7 @@ lemma transvection_mulVec_single_other {i j : ι} (hij : i ≠ j) (b : F) : /-- Inverse of a transvection: `transvection i j hij b * transvection i j hij (-b) = 1`. -/ lemma transvection_mul_neg {i j : ι} (hij : i ≠ j) (b : F) : - transvection hij b * transvection hij (-b) = 1 := by - ext : 1 + transvection hij b * transvection hij (-b) = 1 := Subtype.ext <| by simp [transvection_coe, mul_add, add_mul, single_mul_single_of_ne _ _ _ _ hij.symm, ← single_neg] @@ -537,6 +552,29 @@ lemma transvection_mem_center_iff {i j : ι} (hij : i ≠ j) (b : F) : end SpecialLinearGroup +namespace TransvectionStruct + +variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] + +/-- Any transvection structure can be converted to a special linear matrix. -/ +def toSpecialLinearGroup (t : TransvectionStruct ι F) : + SpecialLinearGroup ι F := + SpecialLinearGroup.transvection t.hij t.c + +lemma toSpecialLinearGroup_def (t : TransvectionStruct ι F) : + t.toSpecialLinearGroup = SpecialLinearGroup.transvection t.hij t.c := rfl + +@[simp] +lemma toSpecialLinearGroup_coe (t : TransvectionStruct ι F) : + (t.toSpecialLinearGroup : Matrix ι ι F) = t.toMatrix := rfl + +@[simp] +lemma toSpecialLinearGroup_mk {i j : ι} (hij : i ≠ j) (c : F) : + (TransvectionStruct.mk i j hij c).toSpecialLinearGroup = + SpecialLinearGroup.transvection hij c := rfl + +end TransvectionStruct + end transvection section SL2 @@ -545,6 +583,8 @@ variable {F : Type*} [Field F] open MatrixGroups +namespace SpecialLinearGroup + /-- An element in SLₙ(F) induced by a diagonal matrix `1` on any other entries and `a`, `a⁻¹` on positition `i` and `j` respectively where `i ≠ j`. -/ noncomputable def diag2n {ι : Type*} [Fintype ι] [DecidableEq ι] {i j : ι} (hij : i ≠ j) (a : F) @@ -562,18 +602,23 @@ lemma diag2n_coe {ι : Type*} [Fintype ι] [DecidableEq ι] {i j : ι} (hij : i noncomputable abbrev diag2 (a : F) (ha : a ≠ 0) : SL(2, F) := diag2n zero_ne_one a ha +lemma diag2_def {a : F} (ha : a ≠ 0) : diag2 a ha = diag2n zero_ne_one a ha := rfl + lemma diag2_coe (a : F) (ha : a ≠ 0) : (diag2 a ha).1 = diagonal (fun i ↦ match i with | 0 => a|1 => a⁻¹) := by simp [diag2n_coe] -lemma diag2_mulVec_single_i₁ (a : F) (ha : a ≠ 0) : - (diag2 a ha).1 *ᵥ (Pi.single 0 (1 : F)) = a • Pi.single 0 (1 : F) := by - ext k; fin_cases k <;> simp [diag2_coe] +lemma diag2_coe' {a : F} (ha : a ≠ 0) : + (diag2 a ha).1 = !![a, 0; 0, a⁻¹] := by + ext i j + fin_cases i <;> fin_cases j <;> simp [diag2n_coe] + +lemma diag2_smul_single_i₁ {a : F} (ha : a ≠ 0) : + diag2 a ha • (Pi.single 0 1 : Fin 2 → F) = a • Pi.single 0 (1 : F) := by + ext k; fin_cases k <;> simp [Matrix.SpecialLinearGroup.smul_def, diag2_coe] -lemma diag2_mulVec_single_i₂ - (a : F) (ha : a ≠ 0) : - (diag2 a ha).1 *ᵥ (Pi.single 1 (1 : F)) = - a⁻¹ • Pi.single 1 (1 : F) := by - ext k; fin_cases k <;> simp [diag2_coe] +lemma diag2_smul_single_i₂ {a : F} (ha : a ≠ 0) : + diag2 a ha • (Pi.single 1 1 : Fin 2 → F) = a⁻¹ • Pi.single 1 (1 : F) := by + ext k; fin_cases k <;> simp [Matrix.SpecialLinearGroup.smul_def, diag2_coe] lemma diag2_mul_inv (a : F) (ha : a ≠ 0) : diag2 a ha * diag2 a⁻¹ (inv_ne_zero ha) = 1 := Subtype.ext <| by @@ -584,6 +629,102 @@ lemma diag2_inv (a : F) (ha : a ≠ 0) : apply inv_eq_of_mul_eq_one_right exact diag2_mul_inv a ha +section induction + +variable {ι R : Type*} [Fintype ι] [DecidableEq ι] [CommRing R] + +/-- the coercion to `Matrix ι ι R` as a monoid homomorphism -/ +def coeMonoidHom : SpecialLinearGroup ι R →* Matrix ι ι R where + toFun := Subtype.val + map_one' := rfl + map_mul' _ _ := rfl + +@[simp] +lemma coeMonoidHom_apply (g : SpecialLinearGroup ι R) : coeMonoidHom g = (g : Matrix ι ι R) := rfl + +lemma coeMonoidHom_injective : Function.Injective (coeMonoidHom : SpecialLinearGroup ι R → _) := + Subtype.val_injective + +private lemma diag_decompose (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) : + Finset.prod {i | i ≠ i₀} (fun i k ↦ if k = i then D i else + if k = i₀ then (D i)⁻¹ else 1 : ι → ι → F) = D := by + rw [det_diagonal, show Finset.univ = insert i₀ ({i | i ≠ i₀} : Finset ι) by grind, + Finset.prod_insert (by grind), mul_eq_one_iff_eq_inv₀ (by grind), + ← Finset.prod_inv_distrib] at hD + ext x + by_cases hx : x = i₀ + · simpa [hx, hD, -Finset.prod_inv_distrib] using Finset.prod_congr rfl (by grind) + · simp [hx] + +lemma diagonal_neZero (D : ι → F) (hD : det (diagonal D) = 1) (j : ι) : + D j ≠ 0 := fun h ↦ by + rw [det_diagonal, show Finset.univ = insert j ({i | i ≠ j} : Finset ι) by grind, + Finset.prod_insert (by grind), h, zero_mul] at hD + exact zero_ne_one hD + +lemma diag_commute (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) : + (({i | i ≠ i₀} : Finset ι) : Set ι).Pairwise (Function.onFun Commute fun i ↦ + if hi : i ≠ i₀ then diag2n hi (D i) (diagonal_neZero D hD i) else 1) := by + intro i1 hi1 i2 hi2 hi12 + ext i j + simp [apply_dite, diag2n_coe] + split_ifs <;> simp [diagonal_apply]; grind + +lemma diag_eq_diag2n_prod (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) : + (⟨diagonal D, hD⟩ : SpecialLinearGroup ι F) = + Finset.noncommProd {i : ι | i ≠ i₀} (fun i ↦ if hi : i ≠ i₀ then + diag2n hi (D i) (diagonal_neZero D hD i) else 1) (diag_commute i₀ D hD) := by + classical + set g : ι → ι → F := fun i k ↦ if k = i then D i else if k = i₀ then (D i)⁻¹ else 1 with hg_def + apply coeMonoidHom_injective + rw [Finset.map_noncommProd] + simp_rw [coeMonoidHom_apply, apply_dite, coe_one] + rw [Finset.noncommProd_congr (s₂ := {i | i ≠ i₀}) rfl (fun i hi ↦ + (dif_pos (Finset.mem_filter.1 hi).2 : _ = (diag2n (Finset.mem_filter.1 hi).2 _ _).1))] + convert_to! _ = Finset.noncommProd {i | i ≠ i₀} (fun x ↦ diagonal (g x)) _ + simp_rw [← diagonalRingHom_apply] + rw [← Finset.map_noncommProd _ _ (fun _ _ _ _ _ ↦ Commute.all _ _), Finset.noncommProd_eq_prod] + rw [diag_decompose i₀ D hD] + +/-- The `SpecialLinearGroup` analogue of + `Matrix.Pivot.exists_list_transvec_mul_diagonal_mul_list_transvec`: + every element of `SL(ι, F)` is a product of transvections, + a diagonal matrix of determinant `1`, and transvections. -/ +theorem exists_list_transvec_mul_diagonal_mul_list_transvec (M : SpecialLinearGroup ι F) : + ∃ (L L' : List (TransvectionStruct ι F)) (D : ι → F) (hD : det (diagonal D) = 1), + M = (L.map TransvectionStruct.toSpecialLinearGroup).prod * ⟨diagonal D, hD⟩ * + (L'.map TransvectionStruct.toSpecialLinearGroup).prod := by + obtain ⟨L, L', D, hM⟩ := Pivot.exists_list_transvec_mul_diagonal_mul_list_transvec M.1 + refine ⟨L, L', D, by simpa [hM] using M.2, Subtype.ext <| ?_⟩ + simp_rw [coe_mul, ← coeMonoidHom_apply, map_list_prod, List.map_map, Function.comp_def, + coeMonoidHom_apply, TransvectionStruct.toSpecialLinearGroup_coe, hM] + +theorem diagonal_transvection_induction' [Nontrivial ι] (P : SpecialLinearGroup ι F → Prop) + (M : SpecialLinearGroup ι F) + (hdiag : ∀ (i j : ι) (hij : i ≠ j) {c : F} (hc : c ≠ 0), P (diag2n hij c hc)) + (htransvec : ∀ (i j : ι) (hij : i ≠ j) (a : F), P (transvection hij a)) + (hmul : ∀ A B, P A → P B → P (A * B)) : P M := by + obtain ⟨i₀, j₀, hij₀⟩ := exists_pair_ne ι + have hP1 : P 1 := transvection_coeff_zero (F := F) hij₀ ▸ htransvec i₀ j₀ hij₀ 0 + have hdiagonal (D : ι → F) (hD : det (diagonal D) = 1) : P ⟨diagonal D, hD⟩ := by + rw [diag_eq_diag2n_prod i₀ D hD] + refine Finset.noncommProd_induction _ _ _ P hmul hP1 fun i hi => ?_ + simp [(Finset.mem_filter.1 hi).2, hdiag] + have hlist (L : List (TransvectionStruct ι F)) : + P (L.map TransvectionStruct.toSpecialLinearGroup).prod := by + induction L with + | nil => simpa using hP1 + | cons t L ih => + rw [List.map_cons, List.prod_cons, t.toSpecialLinearGroup_def] + exact hmul _ _ (htransvec t.i t.j t.hij t.c) ih + obtain ⟨L, L', D, hD, hM⟩ := exists_list_transvec_mul_diagonal_mul_list_transvec M + exact hM ▸ hmul _ _ (hmul _ _ (hlist L) (hdiagonal D hD)) (hlist L') + +end induction + +end SpecialLinearGroup + +open Matrix.SpecialLinearGroup open scoped commutatorElement lemma commutator_diag2_transvection (a : F) (ha : a ≠ 0) (b c : F) @@ -598,12 +739,67 @@ lemma commutator_diag2_transvection (a : F) (ha : a ≠ 0) (b c : F) /-- For any `c : F`, given `a ≠ 0` and `a² ≠ 1`, the transvection `transvection i₁ i₂ hij c` is a commutator in `SL ι F`, hence lies in `commutator (SL ι F)`. -/ -lemma transvection_mem_commutator (a : F) (ha : a ≠ 0) (hasq : a ^ 2 ≠ 1) (c : F) : +lemma transvection_mem_commutator₀ {a : F} (ha : a ≠ 0) (hasq : a ^ 2 ≠ 1) (c : F) : SpecialLinearGroup.transvection zero_ne_one c ∈ commutator SL(2, F) := by rw [← commutator_diag2_transvection a ha (c / (a ^ 2 - 1)) c (div_mul_cancel₀ c (sub_ne_zero_of_ne hasq)).symm] exact Subgroup.commutator_mem_commutator (Subgroup.mem_top _) (Subgroup.mem_top _) +lemma transvection_mem_commutator₁ {a : F} (ha : a ≠ 0) (hasq : a ^ 2 ≠ 1) (c : F) : + SpecialLinearGroup.transvection one_ne_zero c ∈ commutator SL(2, F) := by + have (b c' : F) (hc : c' = b * (a ^ 2 - 1)) : + ⁅diag2 a⁻¹ (inv_ne_zero ha), SpecialLinearGroup.transvection one_ne_zero b⁆ = + (SpecialLinearGroup.transvection one_ne_zero c' : SL(2, F)) := by + rw [commutatorElement_def, diag2_inv a⁻¹ (inv_ne_zero ha), + SpecialLinearGroup.transvection_inv one_ne_zero b] + refine Subtype.ext <| Matrix.ext fun i j ↦ ?_ + fin_cases i <;> fin_cases j <;> + simp [hc, SpecialLinearGroup.transvection_coe, diag2_coe, inv_inv, mul_add, add_mul, + mul_inv_cancel₀ ha, inv_mul_cancel₀ ha, mul_comm a b, mul_assoc b a a, ← pow_two, + mul_sub_one, ← sub_eq_add_neg] + rw [← this (c / (a ^ 2 - 1)) c (div_mul_cancel₀ c (sub_ne_zero_of_ne hasq)).symm] + exact Subgroup.commutator_mem_commutator (Subgroup.mem_top _) (Subgroup.mem_top _) + +lemma transvection_mem_commutator {a : F} (ha : a ≠ 0) (hasq : a ^ 2 ≠ 1) {i j : Fin 2} (h : i ≠ j) + (c : F) : SpecialLinearGroup.transvection h c ∈ commutator SL(2, F) := by + fin_cases i + · obtain rfl : j = 1 := by fin_cases j <;> tauto + exact transvection_mem_commutator₀ ha hasq c + · obtain rfl : j = 0 := by fin_cases j <;> tauto + exact transvection_mem_commutator₁ ha hasq c + +lemma diag2_decompose (a : F) (ha : a ≠ 0) : + diag2 a ha = SpecialLinearGroup.transvection zero_ne_one a * + SpecialLinearGroup.transvection one_ne_zero (- a⁻¹) * + SpecialLinearGroup.transvection zero_ne_one a * + SpecialLinearGroup.transvection zero_ne_one (-1) * + SpecialLinearGroup.transvection one_ne_zero 1 * + SpecialLinearGroup.transvection zero_ne_one (-1) := by + ext i j + fin_cases i <;> fin_cases j <;> + simp [diag2_coe', transvection_coe, mul_add, add_mul, mul_inv_cancel₀ ha, inv_mul_cancel₀ ha] + +theorem SL2.transvection_induction (P : SL(2, F) → Prop) + (htransvec : ∀ (i j : Fin 2) (h : i ≠ j) c, P (SpecialLinearGroup.transvection h c)) + (hmul : ∀ A B, P A → P B → P (A * B)) (A : SL(2, F)) : P A := by + refine diagonal_transvection_induction' P _ (fun i j hij c hc ↦ ?_) htransvec hmul + fin_cases i + · obtain rfl : j = 1 := by fin_cases j <;> tauto + change P (diag2 c hc) + rw [diag2_decompose c hc] + refine hmul _ _ (hmul _ _ (hmul _ _ (hmul _ _ (hmul _ _ ?_ ?_) ?_) ?_) ?_) ?_ + all_goals exact htransvec _ _ _ _ + · obtain rfl : j = 0 := by fin_cases j <;> tauto + rw [show diag2n hij c hc = diag2 c⁻¹ (inv_ne_zero hc) by + ext; simp [diag2n_coe, diagonal_apply]; grind, diag2_decompose c⁻¹ (inv_ne_zero hc)] + refine hmul _ _ (hmul _ _ (hmul _ _ (hmul _ _ (hmul _ _ ?_ ?_) ?_) ?_) ?_) ?_ + all_goals exact htransvec _ _ _ _ + +lemma SL2.commutator_eq_top {a : F} (ha : a ≠ 0) (hasq : a ^ 2 ≠ 1) : + commutator SL(2, F) = ⊤ := + le_antisymm le_top (fun A _ ↦ SL2.transvection_induction _ + (fun _ _ ↦ transvection_mem_commutator ha hasq) (fun _ _ ↦ mul_mem) A) + end SL2 end Matrix diff --git a/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean b/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean new file mode 100644 index 00000000000000..32a6e3158224af --- /dev/null +++ b/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean @@ -0,0 +1,137 @@ +/- +Copyright (c) 2026 Yunzhou Xie. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Edison Xie +-/ +module + +public import Mathlib.GroupTheory.GroupAction.Iwasawa +public import Mathlib.GroupTheory.IsPerfect +public import Mathlib.LinearAlgebra.Projectivization.PSL.Stabilizer + +/-! +-/ + +@[expose] public section + +variable {ι F : Type*} [Field F] [DecidableEq ι] [Fintype ι] + +open Matrix Matrix.SpecialLinearGroup + +open scoped MatrixGroups + +namespace SL2Gen + +/-- A transvection `transvection i j hij b` lies in `lineStab (span F {Pi.single i 1})`. -/ +lemma transvection_mem_lineStab {i j : ι} (hij : i ≠ j) (b : F) : + transvection hij b ∈ lineStab (Submodule.span F {(Pi.single i (1 : F) : ι → F)}) := + fun w ↦ Submodule.mem_span_singleton.2 ⟨b * w j, by simp [mul_smul, + Matrix.SpecialLinearGroup.smul_def, transvection_coe, add_smul, Matrix.single_mulVec_eq]⟩ + +/-- Every transvection in `SL ι F` whose indices are `(i₁, i₂)` or `(i₂, i₁)` is in the join +of `lineStab(span F {e_{i₁}})` and `lineStab(span F {e_{i₂}})`. -/ +lemma transvection_mem_lineStab_sup (t : TransvectionStruct (Fin 2) F) : + t.toSpecialLinearGroup ∈ + lineStab (Submodule.span F {(Pi.single 0 1 : Fin 2 → F)}) + ⊔ lineStab (Submodule.span F {(Pi.single 1 1 : Fin 2 → F)}) := by + obtain ⟨i, j, hij, c⟩ := t + simp only [Fin.isValue, TransvectionStruct.toSpecialLinearGroup_mk] + fin_cases i <;> fin_cases j <;> try tauto + · exact Subgroup.mem_sup_left <| transvection_mem_lineStab zero_ne_one c + · exact Subgroup.mem_sup_right <| transvection_mem_lineStab one_ne_zero c + +/-- SL-level generation: in the 2-element-index case, the join of the two `lineStab` subgroups +attached to the two coordinate axes is all of `SL ι F`. -/ +lemma SL_card_two_lineStab_sup_eq_top : + lineStab (Submodule.span F {(Pi.single 0 1: Fin 2 → F)}) ⊔ + lineStab (Submodule.span F {(Pi.single 1 1: Fin 2 → F)}) = + (⊤ : Subgroup SL(2, F)) := + le_antisymm le_top fun M _ ↦ SL2.transvection_induction _ + (fun i j hij a ↦ by simpa using transvection_mem_lineStab_sup ⟨i, j, hij, a⟩) + (fun _ _ ↦ mul_mem) M + +end SL2Gen + +open scoped LinearAlgebra.Projectivization + +/-- At the SL level: when `Fintype.card ι = 2`, the supremum over all projective points of +the `lineStab` subgroups equals `⊤` in `SL ι F`. -/ +lemma PSL.iSup_lineStab_eq_top : + (⨆ p : ℙ F (Fin 2 → F), lineStab p.submodule) = (⊤ : Subgroup SL(2, F)) := by + refine le_antisymm le_top (SL2Gen.SL_card_two_lineStab_sup_eq_top (F := F) ▸ + sup_le ?_ ?_) + <;> rw [← Projectivization.submodule_mk (K := F) _ (Pi.single_ne_zero_iff.2 one_ne_zero)] + <;> exact le_iSup_iff.2 fun b a ↦ a _ + +/-- The Iwasawa generator property: when `Fintype.card ι = 2`, the supremum of the +`iwasawaT` subgroups equals all of `PSL`. -/ +lemma PSL.iSup_iwasawaT_eq_top : + iSup (PSL.iwasawaT (F := F) (ι := Fin 2)) = ⊤ := by + have step1 : iSup (PSL.iwasawaT (F := F) (ι := Fin 2)) = + Subgroup.map (QuotientGroup.mk' (Subgroup.center (Matrix.SpecialLinearGroup (Fin 2) F))) + (⨆ p : ℙ F (Fin 2 → F), + Matrix.SpecialLinearGroup.lineStab (F := F) (ι := Fin 2) p.submodule) := by + rw [Subgroup.map_iSup] + rw [step1, PSL.iSup_lineStab_eq_top] + exact Subgroup.map_top_of_surjective _ (QuotientGroup.mk'_surjective _) + +open MulAction + +/-- The Iwasawa structure on PSL(2, F). -/ +noncomputable abbrev PSL2.Iwasawa : IwasawaStructure PSL(2, F) (ℙ F (Fin 2 → F)) where + T := PSL.iwasawaT + is_comm p := by + have hSL : IsMulCommutative (lineStab (F := F) (ι := Fin 2) p.submodule) := by + rw [← Projectivization.mk_rep p, Projectivization.submodule_mk] + exact lineStab_isMulCommutative_of_span p.rep p.rep_nonzero + exact Subgroup.map_isMulCommutative _ _ + is_conj g p := by + obtain ⟨g_SL, rfl⟩ := QuotientGroup.mk_surjective g + rw [Matrix.ProjectiveSpecialLinearGroup.smul_proj_mk] + change Subgroup.map _ _ = _ + rw [PSL.smul_submodule, Matrix.SpecialLinearGroup.lineStab_smul, + PSL.iwasawaT_map_conj] + is_generator := PSL.iSup_iwasawaT_eq_top + +namespace SL2Simple + +open Matrix.SpecialLinearGroup + +/-- `commutator (PSL ι F) = ⊤`. -/ +lemma PSL_commutator_eq_top (hF : ∃ a : F, a ≠ 0 ∧ a ^ 2 ≠ 1) : + commutator PSL(2, F) = ⊤ := by + obtain ⟨a, ha, hasq⟩ := hF + haveI : Group.IsPerfect SL(2, F) := ⟨SL2.commutator_eq_top ha hasq⟩ + have : Group.IsPerfect (Matrix.ProjectiveSpecialLinearGroup (Fin 2) F) := inferInstance + exact this.commutator_eq_top + +/-- `PSL ι F` is nontrivial whenever `ι` has at least two elements (and `F` is a field, +hence in particular nontrivial). -/ +instance PSL_nontrivial [Nontrivial ι] : + Nontrivial (Matrix.ProjectiveSpecialLinearGroup ι F) := by + obtain ⟨i₁, i₂, hij⟩ := exists_pair_ne ι + set g : Matrix.SpecialLinearGroup ι F := transvection hij 1 + refine ⟨⟨(QuotientGroup.mk g : Matrix.ProjectiveSpecialLinearGroup ι F), + 1, fun h ↦ one_ne_zero (α := F) ?_⟩⟩ + rwa [QuotientGroup.eq_one_iff, transvection_mem_center_iff] at h + +end SL2Simple + +theorem Matrix.ProjectiveSpecialLinearGroup.rank_two_simple' + (hF : ∃ a : F, a ≠ 0 ∧ a ^ 2 ≠ 1) : + IsSimpleGroup PSL(2, F) := + MulAction.IwasawaStructure.isSimpleGroup + (SL2Simple.PSL_commutator_eq_top hF) PSL2.Iwasawa inferInstance + +private lemma field_cond_of_four_le_card (hF : 4 ≤ Nat.card F) : + ∃ a : F, a ≠ 0 ∧ a ^ 2 ≠ 1 := by + have : Finite F := (Nat.card_pos_iff.1 (by omega)).2 + obtain ⟨x, hx⟩ : IsCyclic Fˣ := by infer_instance + refine ⟨x, Units.ne_zero x, fun h ↦ ?_⟩ + grw [Nat.card_eq_card_units_add_one F, ← orderOf_eq_card_of_forall_mem_zpowers hx, + orderOf_le_of_pow_eq_one zero_lt_two (Units.ext <| by simpa using h)] at hF + omega + +theorem Matrix.ProjectiveSpecialLinearGroup.rank_two_simple (hF : 4 ≤ Nat.card F) : + IsSimpleGroup PSL(2, F) := + Matrix.ProjectiveSpecialLinearGroup.rank_two_simple' (field_cond_of_four_le_card hF) From bbd5fcf3ae648b745376f9f06b251e6b6d168e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Mon, 22 Jun 2026 14:05:23 +0000 Subject: [PATCH 0248/1300] chore(LinearAlgebra/Matrix): make `det_zero` simp (#40699) This used to be provable by simp back when `det` was an `abbrev`. This changed in #33590. This dates back all the way from https://github.com/leanprover-community/mathlib3/pull/404, and in fact the code came from the even earlier https://github.com/leanprover-community/mathlib3/pull/378. Neither of the PRs offers an explanation for why this argument was explicit. From BrauerGroup and RealRooted --- Mathlib/LinearAlgebra/Determinant.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean | 2 +- Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/FinTwo.lean | 2 +- Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean | 2 +- Mathlib/LinearAlgebra/Matrix/ZPow.lean | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 80c91075db806c..9253e784a05321 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -268,7 +268,7 @@ theorem det_zero' {ι : Type*} [Finite ι] [Nonempty ι] (b : Basis ι A M) : LinearMap.det (0 : M →ₗ[A] M) = 0 := by haveI := Classical.decEq ι cases nonempty_fintype ι - rwa [← det_toMatrix b, map_zero, det_zero] + rw [← det_toMatrix b, map_zero, det_zero] /-- In a finite-dimensional vector space, the zero map has determinant `1` in dimension `0`, and `0` otherwise. We give a formula that also works in infinite dimension, where we define diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean index 87b6da663393c1..40eface05904fd 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean @@ -85,7 +85,7 @@ theorem det_diagonal {d : n → R} : det (diagonal d) = ∏ i, d i := by · simp · simp -theorem det_zero (_ : Nonempty n) : det (0 : Matrix n n R) = 0 := +@[simp] theorem det_zero [Nonempty n] : det (0 : Matrix n n R) = 0 := (detRowAlternating : (n → R) [⋀^n]→ₗ[R] R).map_zero @[simp] diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/FinTwo.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/FinTwo.lean index 0b8ea843931ff7..85a3ed415fca23 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/FinTwo.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/FinTwo.lean @@ -274,7 +274,7 @@ lemma IsParabolic.pow {g : GL (Fin 2) K} (hg : IsParabolic g) [CharZero K] refine fun ha ↦ (g ^ 2).det_ne_zero ?_ rw [ha, map_zero, zero_add] at hg rw [← hg] at hmsq - rw [Units.val_pow_eq_pow_val, hmsq, det_zero ⟨0⟩] + rw [Units.val_pow_eq_pow_val, hmsq, det_zero] lemma isParabolic_iff_of_upperTriangular {g : GL (Fin 2) K} (hg : g 1 0 = 0) : g.IsParabolic ↔ g 0 0 = g 1 1 ∧ g 0 1 ≠ 0 := diff --git a/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean b/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean index 21703a4f35bf9d..0cda6cc66b8de5 100644 --- a/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean @@ -416,7 +416,7 @@ theorem det_nonsing_inv : A⁻¹.det = A.det⁻¹ʳ := by rw [Ring.inverse_invertible, ← invOf_eq_nonsing_inv, det_invOf] cases isEmpty_or_nonempty n · rw [det_isEmpty, det_isEmpty, Ring.inverse_one] - · rw [Ring.inverse_non_unit _ h, nonsing_inv_apply_not_isUnit _ h, det_zero ‹_›] + · rw [Ring.inverse_non_unit _ h, nonsing_inv_apply_not_isUnit _ h, det_zero] theorem isUnit_nonsing_inv_det (h : IsUnit A.det) : IsUnit A⁻¹.det := .of_mul_eq_one _ (A.det_nonsing_inv_mul_det h) diff --git a/Mathlib/LinearAlgebra/Matrix/ZPow.lean b/Mathlib/LinearAlgebra/Matrix/ZPow.lean index 14df76dae44d4f..b32635593790f5 100644 --- a/Mathlib/LinearAlgebra/Matrix/ZPow.lean +++ b/Mathlib/LinearAlgebra/Matrix/ZPow.lean @@ -250,7 +250,7 @@ theorem zpow_ne_zero_of_isUnit_det [Nonempty n'] [Nontrivial R] {A : M} (ha : Is (z : ℤ) : A ^ z ≠ 0 := by have := ha.det_zpow z contrapose this - rw [this, det_zero ‹_›] + rw [this, det_zero] exact not_isUnit_zero theorem zpow_sub {A : M} (ha : IsUnit A.det) (z1 z2 : ℤ) : A ^ (z1 - z2) = A ^ z1 / A ^ z2 := by From 9f59f3b81d68fc6805c32ad1e595317b356fd748 Mon Sep 17 00:00:00 2001 From: Fabrizio Barroero <23321199+fbarroero@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:05:27 +0000 Subject: [PATCH 0249/1300] feat(RingTheory/Ideal/Operations): `pow_eq_bot` (#40836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We add ``` theorem Ideal.pow_eq_bot.{u} {R : Type u} [Semiring R] {I : Ideal R} [isReduced R] {n : ℕ} (hn : n ≠ 0) : I ^ n = ⊥ ↔ I = ⊥ ``` Co-authored-by: fbarroero --- Mathlib/Algebra/Algebra/Operations.lean | 10 ++++++++++ Mathlib/RingTheory/Ideal/Operations.lean | 8 +++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Operations.lean b/Mathlib/Algebra/Algebra/Operations.lean index 54267e7ffb5618..d31f10ca1de085 100644 --- a/Mathlib/Algebra/Algebra/Operations.lean +++ b/Mathlib/Algebra/Algebra/Operations.lean @@ -367,6 +367,16 @@ lemma restrictScalars_pow {A B C : Type*} [Semiring A] [Semiring B] | n + 2, _ => by simp [Submodule.pow_succ (n := n + 1), restrictScalars_mul, restrictScalars_pow n.succ_ne_zero] +instance instIsReduced [IsReduced A] : IsReduced (Submodule R A) where + eq_zero M hM := by + rw [Submodule.zero_eq_bot, Submodule.eq_bot_iff] + rintro m hm + obtain ⟨n, hn⟩ := hM + exact eq_zero_of_pow_eq_zero <| (M ^ n).eq_bot_iff.mp hn _ (pow_mem_pow M hm n) + +theorem pow_eq_bot [IsReduced A] {M : Submodule R A} {n : ℕ} (hn : n ≠ 0) : + M ^ n = ⊥ ↔ M = ⊥ := by refine ⟨eq_zero_of_pow_eq_zero, by aesop⟩ + end Module variable {ι : Sort uι} diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index e0824b1e53b0ca..58c363276417d0 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -397,6 +397,9 @@ end IsTwoSided theorem mul_eq_bot [NoZeroDivisors R] : I * J = ⊥ ↔ I = ⊥ ∨ J = ⊥ := Submodule.mul_eq_bot +theorem pow_eq_bot [IsReduced R] {n : ℕ} (hn : n ≠ 0) : I ^ n = ⊥ ↔ I = ⊥ := + Submodule.pow_eq_bot hn + instance {S A : Type*} [Semiring S] [SMul R S] [AddCommMonoid A] [Module R A] [Module S A] [IsScalarTower R S A] [IsTorsionFree R A] {I : Submodule S A} : IsTorsionFree R I := (I.restrictScalars R).instIsTorsionFree @@ -886,12 +889,11 @@ variable {I J} in theorem IsRadical.inf (hI : IsRadical I) (hJ : IsRadical J) : IsRadical (I ⊓ J) := by rw [IsRadical, radical_inf]; exact inf_le_inf hI hJ -lemma isRadical_bot_iff : - (⊥ : Ideal R).IsRadical ↔ IsReduced R := by +lemma isRadical_bot_iff : (⊥ : Ideal R).IsRadical ↔ IsReduced R := by simp only [IsRadical, SetLike.le_def, Ideal.mem_radical_iff, Ideal.mem_bot, forall_exists_index, isReduced_iff, IsNilpotent] -lemma isRadical_bot [IsReduced R] : (⊥ : Ideal R).IsRadical := by rwa [Ideal.isRadical_bot_iff] +lemma isRadical_bot [IsReduced R] : (⊥ : Ideal R).IsRadical := by rwa [isRadical_bot_iff] /-- `Ideal.radical` as an `InfTopHom`, bundling in that it distributes over `inf`. -/ def radicalInfTopHom : InfTopHom (Ideal R) (Ideal R) where From 3c96a300e3cf9ff4c414de6cf73e87d7f28c0bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhao=20Yuyang=20=E8=B5=B5=E9=9B=A8=E6=89=AC?= Date: Mon, 22 Jun 2026 14:41:30 +0000 Subject: [PATCH 0250/1300] chore: make `SMul.comp.smul` `implicit_reducible` (#38098) --- Mathlib/Algebra/Group/Action/Defs.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Action/Defs.lean b/Mathlib/Algebra/Group/Action/Defs.lean index 0859764ee46a7d..54914db1eafdfb 100644 --- a/Mathlib/Algebra/Group/Action/Defs.lean +++ b/Mathlib/Algebra/Group/Action/Defs.lean @@ -284,7 +284,8 @@ variable [SMul M α] /-- Auxiliary definition for `SMul.comp`, `MulAction.compHom`, `DistribMulAction.compHom`, `Module.compHom`, etc. -/ -@[to_additive (attr := simp) /-- Auxiliary definition for `VAdd.comp`, `AddAction.compHom`, etc. -/] +@[to_additive (attr := simp, implicit_reducible) +/-- Auxiliary definition for `VAdd.comp`, `AddAction.compHom`, etc. -/] def comp.smul (g : N → M) (n : N) (a : α) : α := g n • a variable (α) From c3bb4de85ee9ac96248acdd017f9e7d9e921e72a Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Mon, 22 Jun 2026 14:41:34 +0000 Subject: [PATCH 0251/1300] feat: add LinearIndependent.update (#40219) From flt-regular. --- .../LinearIndependent/Lemmas.lean | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean index 4c5aef9b9bc3e3..ab631ec1d803f9 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean @@ -523,6 +523,27 @@ theorem LinearIndependent.of_pairwise_dual_eq_zero_one (v : ι → M) (f : ι end Module +open Finsupp in +/-- A linearly independent family of vectors `f` remains linearly independent when we substitute one +of the terms with a vector `m` provided there exists a non-zero divisor `r`, such that `r • m` +belongs to the span of `f` with non-zero-divisor coefficients. -/ +lemma LinearIndependent.update [DecidableEq ι] [CommRing R] [AddCommGroup M] [Module R M] + {f : ι → M} (hf : LinearIndependent R f) (i : ι) (m : M) + (hg : ∃ r ∈ nonZeroDivisors R, ∃ l : ι →₀ R, + l i ∈ nonZeroDivisors R ∧ r • m = linearCombination R f l) : + LinearIndependent R (Function.update f i m) := by + rw [linearIndependent_iff] at hf ⊢ + obtain ⟨r, hr, l, hl, hg⟩ := hg + intros l' hl' + apply_fun (r • ·) at hl' + simp_rw [Pi.update_eq_sub_add_single, ← bilinearCombination_apply _ (S := R), map_add, map_sub, + bilinearCombination_apply, LinearMap.add_apply, LinearMap.sub_apply, + linearCombination_single_index, smul_add, smul_sub, smul_zero, smul_comm r (l' i) m, + hg, ← LinearMap.map_smul, smul_smul, ← linearCombination_single, ← map_sub, ← map_add] at hl' + replace hl' : ∀ j, (r * l' j - (single i (r * l' i)) j) + l' i * l j = 0 := + fun j ↦ DFunLike.congr_fun (hf _ hl') j + grind [mem_nonZeroDivisors_iff] + /-! ### Properties which require `DivisionRing K` From 0e09f45c127ea9f43151a07c6e92d7f553deebfe Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:41:37 +0000 Subject: [PATCH 0252/1300] feat(CategoryTheory/Preadditive): the comma category is preadditive (#40890) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we have additive functors `L : A ⥤ T` and `R : B ⥤ T` between preadditive categories, then there is a structure of preadditive category on `Comma L R` such that addition commutes with the left and right projections. We then specialize to the arrow category of a preadditive category. Co-authored-by: morel --- Mathlib.lean | 1 + Mathlib/CategoryTheory/Preadditive/Comma.lean | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 Mathlib/CategoryTheory/Preadditive/Comma.lean diff --git a/Mathlib.lean b/Mathlib.lean index 319c63732033c9..52a90964f54ae6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3226,6 +3226,7 @@ public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor public import Mathlib.CategoryTheory.Preadditive.Basic public import Mathlib.CategoryTheory.Preadditive.Biproducts public import Mathlib.CategoryTheory.Preadditive.CommGrp_ +public import Mathlib.CategoryTheory.Preadditive.Comma public import Mathlib.CategoryTheory.Preadditive.EilenbergMoore public import Mathlib.CategoryTheory.Preadditive.EndoFunctor public import Mathlib.CategoryTheory.Preadditive.FunctorCategory diff --git a/Mathlib/CategoryTheory/Preadditive/Comma.lean b/Mathlib/CategoryTheory/Preadditive/Comma.lean new file mode 100644 index 00000000000000..0037e50fefdb7a --- /dev/null +++ b/Mathlib/CategoryTheory/Preadditive/Comma.lean @@ -0,0 +1,122 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor + +/-! +# The comma category is preadditive + +If we have additive functors `L : A ⥤ T` and `R : B ⥤ T` between preadditive categories, +then there is a structure of preadditive category on `Comma L R` such that addition commutes +with the left and right projections. + +We then apply this to `Arrow T` for `T` a preadditive category. + +## Tags + +comma, arrow, preadditive +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category + +universe v₁ v₂ v₃ u₁ u₂ u₃ + +variable {A : Type u₁} [Category.{v₁} A] [Preadditive A] +variable {B : Type u₂} [Category.{v₂} B] [Preadditive B] +variable {T : Type u₃} [Category.{v₃} T] [Preadditive T] +variable (L : A ⥤ T) [L.Additive] (R : B ⥤ T) [R.Additive] +variable {u v : Comma L R} + +section Comma + +namespace CommaMorphism + +@[simps!] +instance : Add (u ⟶ v) where + add α β := CommaMorphism.mk (α.left + β.left) (α.right + β.right) (by simp) + +@[simps!] +instance : Sub (u ⟶ v) where + sub α β := CommaMorphism.mk (α.left - β.left) (α.right - β.right) (by simp) + +@[simps!] +instance : Zero (u ⟶ v) where + zero := CommaMorphism.mk 0 0 + +@[simps!] +instance : Neg (u ⟶ v) where + neg α := CommaMorphism.mk (-α.left) (-α.right) + +end CommaMorphism + +instance : AddCommGroup (u ⟶ v) where + add_assoc _ _ _ := by ext <;> simp [add_assoc] + zero_add _ := by cat_disch + add_zero _ := by cat_disch + add_comm _ _ := by ext <;> simp [add_comm] + neg_add_cancel _ := by cat_disch + sub_eq_add_neg _ _ := by ext <;> simp [sub_eq_add_neg] + nsmul n α := CommaMorphism.mk (n • α.left) (n • α.right) + (by simp [Functor.map_nsmul, Preadditive.comp_nsmul, Preadditive.nsmul_comp]) + zsmul n α := CommaMorphism.mk (n • α.left) (n • α.right) + (by simp [Functor.map_zsmul, Preadditive.comp_zsmul, Preadditive.zsmul_comp]) + nsmul_zero := by cat_disch + nsmul_succ _ _ := by ext <;> dsimp <;> simp [add_nsmul] + zsmul_zero' := by cat_disch + zsmul_succ' _ _ := by ext <;> dsimp <;> simp [add_zsmul] + zsmul_neg' _ _ := by ext <;> dsimp <;> simp [add_nsmul, add_zsmul] + +/-- If we have additive functors `L : A ⥤ T` and `R : B ⥤ T` between preadditive categories, +then the category `Comma L R` is preadditive. +-/ +instance : Preadditive (Comma L R) where + +instance : (Comma.fst L R).Additive where + +instance : (Comma.snd L R).Additive where + +end Comma + +section Arrow + +/-- If a category `T` is preadditive, then so is its category of arrows. +-/ +instance : Preadditive (Arrow T) := inferInstanceAs (Preadditive (Comma (𝟭 T) (𝟭 T))) + +instance : (Arrow.leftFunc (C := T)).Additive := + inferInstanceAs ((Comma.fst (𝟭 T) (𝟭 T))).Additive + +instance : (Arrow.rightFunc (C := T)).Additive := + inferInstanceAs ((Comma.snd (𝟭 T) (𝟭 T))).Additive + +variable {u v : Arrow T} + +@[simp] +lemma Arrow.Hom.add_left (α β : u ⟶ v) : (α + β).left = α.left + β.left := rfl + +@[simp] +lemma Arrow.Hom.add_right (α β : u ⟶ v) : (α + β).right = α.right + β.right := rfl + +@[simp] +lemma Arrow.Hom.zero_left : (0 : u ⟶ v).left = 0 := rfl + +@[simp] +lemma Arrow.Hom.zero_right : (0 : u ⟶ v).right = 0 := rfl + +@[simp] +lemma Arrow.Hom.neg_left (α : u ⟶ v) : (-α).left = -α.left := rfl + +@[simp] +lemma Arrow.Hom.neg_right (α : u ⟶ v) : (-α).right = -α.right := rfl + +end Arrow + +end CategoryTheory From 901340bc3f4d6fc607b6bef9fc1aab988635444e Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Mon, 22 Jun 2026 15:26:47 +0000 Subject: [PATCH 0253/1300] feat: more informative output messages in the flexible linter (#39296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current output messages in the flexible linter are: - If the stained location is a hypothesis: `'exact h' uses 'h'!` - If the stained location is the goal: `'exact Nat.le_succ_of_le h' uses '⊢'!` I think the first is not very informative and the second is additionally confusing. So this PR changes them to read: - For a hypothesis: `'exact h' uses 'h', which was modified by the flexible tactic 'simp' on line 40!` - And for the goal: `'exact Nat.le_succ_of_le h' modifies the current goal, which was modified by the flexible tactic 'simp_all' on line 56!` I also added some more explanation to the messages in the case that all the hypotheses and the goal were stained by `simp at *`. --- Mathlib/Tactic/Linter/FlexibleLinter.lean | 21 +- MathlibTest/Linter/Flexible/Basic.lean | 193 +++++++++++++++---- MathlibTest/Linter/Flexible/ImportHeavy.lean | 15 +- 3 files changed, 187 insertions(+), 42 deletions(-) diff --git a/Mathlib/Tactic/Linter/FlexibleLinter.lean b/Mathlib/Tactic/Linter/FlexibleLinter.lean index b7de42cc5db889..87635d731ab532 100644 --- a/Mathlib/Tactic/Linter/FlexibleLinter.lean +++ b/Mathlib/Tactic/Linter/FlexibleLinter.lean @@ -522,8 +522,12 @@ def flexibleLinter : Linter where run := withSetOptionIn fun _stx => do let suggestion? ← liftCoreM <| generateSimpSuggestion stainData stainStx -- Emit warning and suggestion let msg := match stainStx.getKind with - | ``Lean.Parser.Tactic.simp => - m!"`{stainStr}` is a flexible tactic modifying `{d}`. \ + | ``Lean.Parser.Tactic.simp => match d with + | .wildcard => m!"`{stainStr}` is a flexible tactic that potentially modifies all \ + hypotheses and the current goal with a wildcard `*`. \ + Try `simp?` and use the suggested `simp only [...]`. \ + Alternatively, use `suffices` to explicitly state the simplified form." + | _ => m!"`{stainStr}` is a flexible tactic modifying `{d}`. \ Try `simp?` and use the suggested `simp only [...]`. \ Alternatively, use `suffices` to explicitly state the simplified form." | ``Lean.Parser.Tactic.simpAll => @@ -539,7 +543,18 @@ def flexibleLinter : Linter where run := withSetOptionIn fun _stx => do if let some suggStx := suggestion? then liftCoreM <| Lean.Meta.Tactic.TryThis.addSuggestion stainStx { suggestion := .tsyntax (kind := `tactic) ⟨suggStx⟩ } (origSpan? := stainStx) - logInfoAt s m!"`{s}` uses `{d}`!" + let fm ← getFileMap + let stainLine? := stainStx.getPos?.map (Position.line ∘ fm.toPosition) + let lineStr := if let some line := stainLine? then s!" on line {line}" else "" + let atomStr := match stainStx[0] with + | .atom _ val => "the flexible tactic " ++ m!"`{val}`" + | _ => "a flexible tactic" + logInfoAt s <| match d with + | .name _ => m!"`{.group s}`\nuses `{d}`, which was modified by {atomStr}{lineStr}!" + | .goal => + m!"`{.group s}`\nmodifies the current goal, which was modified by {atomStr}{lineStr}!" + | .wildcard => m!"`{.group s}`\nuses a rigid tactic. Previously, {atomStr}, which \ + potentially modified all hypotheses and the goal with a wildcard `*`, was used{lineStr}." initialize addLinter flexibleLinter diff --git a/MathlibTest/Linter/Flexible/Basic.lean b/MathlibTest/Linter/Flexible/Basic.lean index a4bd116944c0ea..c4ea9105ae5abb 100644 --- a/MathlibTest/Linter/Flexible/Basic.lean +++ b/MathlibTest/Linter/Flexible/Basic.lean @@ -14,10 +14,12 @@ set_option linter.unusedVariables false This file contains basic tests for the flexible linter, which do not require any advanced imports. Anything which requires groups, rings or algebraic structures is considered advanced, and -tests for these can be found in `MathlibTest/ImportHeavyFlexibleLinter.lean` +tests for these can be found in `MathlibTest/Linter/Flexible/ImportHeavy.lean` +TODO: make output message appear only once for wildcard -/ + def n : Nat := 1 def m : Nat := 1 @@ -27,18 +29,33 @@ example : n = m := by simp [n] simp [m] +-- the given line number is correct /-- warning: `simp at h` is a flexible tactic modifying `h`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `exact h` uses `h`! +info: `exact h` +uses `h`, which was modified by the flexible tactic `simp` on line 43! -/ #guard_msgs in example (h : 0 + 0 = 0) : True := by simp at h try exact h +/-- +warning: `simp at h` is a flexible tactic modifying `h`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: `exact h` +uses `h`, which was modified by the flexible tactic `simp` on line +-/ +#guard_msgs (substring := true) in +example (h : 0 + 0 = 0) : True := by + simp at h + try exact h + /-- warning: `simp_all` is a flexible tactic modifying `⊢`. Try `simp_all?` and use the suggested `simp_all only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. @@ -47,13 +64,106 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp_all only [Nat.add_zero] --- -info: `exact Nat.le_succ_of_le h` uses `⊢`! +info: `exact Nat.le_succ_of_le h` +modifies the current goal, which was modified by the flexible tactic `simp_all` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example {a b : Nat} (h : a ≤ b) : a + 0 ≤ b + 1 := by simp_all exact Nat.le_succ_of_le h +/-- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: Try this: + [apply] simp only [Nat.add_zero] at * +--- +info: `exact Nat.le_succ_of_le h` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line 98. +--- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: Try this: + [apply] simp only [Nat.add_zero] at * +--- +info: `exact Nat.le_succ_of_le h` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line +-/ +#guard_msgs (substring := true) in +example {a b : Nat} (h : a ≤ b) : a + 0 ≤ b + 1 := by + simp at * + exact Nat.le_succ_of_le h + +/-- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: `exact h2` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line 118. +--- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: `exact h2` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line +-/ +#guard_msgs (substring := true) in +example {a b : Nat} (h1 : 0 + 0 = 0) (h2 : a ≤ b) : a ≤ b := by + simp at * + exact h2 + +/-- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: `exact h2` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line 138. +--- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: `exact h2` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line +-/ +#guard_msgs (substring := true) in +example {a b : Nat} (h1 : 0 + 0 = 0) (h2 : a ≤ b) : a ≤ b := by + simp at * + exact h2 + +/-- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: Try this: + [apply] simp only [Nat.add_zero] at * +--- +info: `exact h` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line 164. +--- +warning: `simp at *` is a flexible tactic that potentially modifies all hypotheses and the current goal with a wildcard `*`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. + +Note: This linter can be disabled with `set_option linter.flexible false` +--- +info: Try this: + [apply] simp only [Nat.add_zero] at * +--- +info: `exact h` +uses a rigid tactic. Previously, the flexible tactic `simp`, which potentially modified all hypotheses and the goal with a wildcard `*`, was used on line +-/ +#guard_msgs (substring := true) in +example {a b : Nat} (h : a = b) : a + 0 = b := by + simp at * + exact h + -- `subst` does not use the goal #guard_msgs in example {a b : Nat} (h : a = b) : a + 0 = b := by @@ -78,7 +188,8 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.add_zero] --- -info: `assumption` uses `⊢`! +info: `assumption` +modifies the current goal, which was modified by the flexible tactic `simp` on line 206! --- warning: `simp` is a flexible tactic modifying `⊢`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. @@ -87,9 +198,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.add_zero] --- -info: `assumption` uses `⊢`! +info: `assumption` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example {a b : Nat} (h : a = b) : a + 0 = b := by simp induction a <;> assumption @@ -99,9 +211,10 @@ warning: `simp at h` is a flexible tactic modifying `h`. Try `simp?` and use the Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `exact h` uses `h`! +info: `exact h` +uses `h`, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example (h : 0 = 0 ∨ 0 = 0) : True := by cases h <;> rename_i h <;> @@ -117,7 +230,8 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one, and_self] --- -info: `on_goal 2 => · contradiction` uses `⊢`! +info: `on_goal 2 => · contradiction` +modifies the current goal, which was modified by the flexible tactic `simp` on line 248! --- warning: `simp` is a flexible tactic modifying `⊢`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. @@ -126,9 +240,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one, and_self] --- -info: `contradiction` uses `⊢`! +info: `contradiction` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example (h : 0 = 1 ∨ 0 = 1) : 0 = 1 ∧ 0 = 1 := by cases h <;> simp on_goal 2 => · contradiction @@ -146,7 +261,8 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one, and_self] --- -info: `contradiction` uses `⊢`! +info: `contradiction` +modifies the current goal, which was modified by the flexible tactic `simp` on line 279! --- warning: `simp` is a flexible tactic modifying `⊢`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. @@ -155,9 +271,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one, and_self] --- -info: `contradiction` uses `⊢`! +info: `contradiction` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example (h : 0 = 1 ∨ 0 = 1) : 0 = 1 ∧ 0 = 1 := by cases h <;> simp · contradiction @@ -168,15 +285,17 @@ warning: `simp at h k` is a flexible tactic modifying `k`. Try `simp?` and use t Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `rw [← Classical.not_not (a := True)] at k` uses `k`! +info: `rw [← Classical.not_not (a := True)] at k` +uses `k`, which was modified by the flexible tactic `simp` on line 301! --- warning: `simp at h k` is a flexible tactic modifying `h`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `rw [← Classical.not_not (a := True)] at h` uses `h`! +info: `rw [← Classical.not_not (a := True)] at h` +uses `h`, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in -- `simp at h` stains `h` but not other locations example {h : 0 = 0} {k : 1 = 1} : True := by simp at h k; @@ -201,9 +320,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.add_zero] --- -info: `exact h.symm` uses `⊢`! +info: `exact h.symm` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in -- `congr` is allowed after `simp`, but "passes along the stain". example {a b : Nat} (h : a = b) : a + b + 0 = b + a := by simp @@ -248,9 +368,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one, and_self] --- -info: `contradiction` uses `⊢`! +info: `contradiction` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example (h : 0 = 1 ∨ 0 = 1) : 0 = 1 ∧ 0 = 1 := by cases h <;> simp · simp_all @@ -277,9 +398,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [not_true_eq_false, not_false_eq_true] at h --- -info: `rw [← Classical.not_not (a := True)] at h` uses `h`! +info: `rw [← Classical.not_not (a := True)] at h` +uses `h`, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in -- `simp at h` stains `h` but not other locations example {h : 0 = 0} {k : 1 = 1} : ¬ ¬ True := by simp at h @@ -294,15 +416,17 @@ warning: `simp at h k` is a flexible tactic modifying `k`. Try `simp?` and use t Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `rw [← Classical.not_not (a := True)] at k` uses `k`! +info: `rw [← Classical.not_not (a := True)] at k` +uses `k`, which was modified by the flexible tactic `simp` on line 432! --- warning: `simp at h k` is a flexible tactic modifying `h`. Try `simp?` and use the suggested `simp only [...]`. Alternatively, use `suffices` to explicitly state the simplified form. Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `rw [← Classical.not_not (a := True)] at h` uses `h`! +info: `rw [← Classical.not_not (a := True)] at h` +uses `h`, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in -- `simp at h` stains `h` but not other locations example {h : 0 = 0} {k : 1 = 1} : True := by simp at h k @@ -317,9 +441,10 @@ warning: `simp at h` is a flexible tactic modifying `h`. Try `simp?` and use the Note: This linter can be disabled with `set_option linter.flexible false` --- -info: `rw [← Classical.not_not (a := True)] at h` uses `h`! +info: `rw [← Classical.not_not (a := True)] at h` +uses `h`, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in -- `simp at h` stains `h` but not other locations example {h : 0 = 0} : True := by simp at h @@ -336,9 +461,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one] --- -info: `rwa [← Classical.not_not (a := False)]` uses `⊢`! +info: `rwa [← Classical.not_not (a := False)]` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example {h : False} : 0 = 1 := by simp rw [← Classical.not_not (a := False)] at h @@ -353,9 +479,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Nat.zero_ne_one] --- -info: `rwa [← Classical.not_not (a := False)]` uses `⊢`! +info: `rwa [← Classical.not_not (a := False)]` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example {h : False} : 0 = 1 ∧ 0 = 1 := by constructor · simpa diff --git a/MathlibTest/Linter/Flexible/ImportHeavy.lean b/MathlibTest/Linter/Flexible/ImportHeavy.lean index 59b961058a98f6..b9d0f275ff350a 100644 --- a/MathlibTest/Linter/Flexible/ImportHeavy.lean +++ b/MathlibTest/Linter/Flexible/ImportHeavy.lean @@ -46,9 +46,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [zero_add] --- -info: `rw [add_comm]` uses `⊢`! +info: `rw [add_comm]` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in -- `norm_num` is allowed after `simp`, but "passes along the stain". example {a : Rat} : a + (0 + 2 + 1 : Rat) = 3 + a := by simp @@ -81,9 +82,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [mul_zero, add_zero] --- -info: `positivity` uses `⊢`! +info: `positivity` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example {k l : ℤ} : 0 ≤ k ^ 2 + 4 * l * 0 := by simp positivity @@ -124,9 +126,10 @@ Note: This linter can be disabled with `set_option linter.flexible false` info: Try this: [apply] simp only [Function.comp_apply, add_zero] --- -info: `fun_prop` uses `⊢`! +info: `fun_prop` +modifies the current goal, which was modified by the flexible tactic `simp` on line -/ -#guard_msgs in +#guard_msgs (substring := true) in example {X : Type*} [TopologicalSpace X] {f : X → ℕ} {g : ℕ → X} (hf : Continuous f) (hg : Continuous g) : Continuous (fun x ↦ (f ∘ g) x + 0) := by From cba41737d24dd73bad77f2a1b10aaf1b84dea640 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Mon, 22 Jun 2026 15:26:50 +0000 Subject: [PATCH 0254/1300] feat: add Algebra.IsUnramifiedIn (#40886) --- .../RamificationInertia/Unramified.lean | 84 ++++++++++++++++++- Mathlib/RingTheory/Unramified/Locus.lean | 15 ++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/RamificationInertia/Unramified.lean b/Mathlib/NumberTheory/RamificationInertia/Unramified.lean index ccac5888695ab6..42ec187589d036 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Unramified.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Unramified.lean @@ -76,12 +76,16 @@ lemma IsUnramifiedAt.of_liesOver_of_ne_bot refine this (H.trans (Ideal.pow_right_mono ?_ _)) exact Ideal.map_le_iff_le_comap.mpr Ideal.LiesOver.over.le +section IsUnramifiedIn + +namespace Algebra + variable (R) in /-- Up to technical conditions, If `T/S/R` is a tower of algebras, `P` is a prime of `T` unramified in `R`, then `P ∩ S` (as a prime of `S`) is also unramified in `R`. -/ -lemma Algebra.IsUnramifiedAt.of_liesOver +lemma IsUnramifiedAt.of_liesOver (p : Ideal S) (P : Ideal T) [P.LiesOver p] [p.IsPrime] [P.IsPrime] [IsUnramifiedAt R P] [EssFiniteType R S] [EssFiniteType R T] [IsDedekindDomain S] [IsDomain T] [Module.IsTorsionFree S T] : IsUnramifiedAt R p := @@ -90,7 +94,7 @@ lemma Algebra.IsUnramifiedAt.of_liesOver /-- Let `R` be a domain of characteristic 0, finite rank over `ℤ`, `S` be a Dedekind domain that is a finite `R`-algebra. Let `p` be a prime of `S`, then `p` is unramified iff `e(p) = 1`. -/ -lemma Algebra.isUnramifiedAt_iff_of_isDedekindDomain +lemma isUnramifiedAt_iff_of_isDedekindDomain {p : Ideal S} [p.IsPrime] [IsDedekindDomain S] [EssFiniteType R S] [IsDomain R] [Module.Finite ℤ R] [CharZero R] [Algebra.IsIntegral R S] (hp : p ≠ ⊥) : @@ -103,3 +107,79 @@ lemma Algebra.isUnramifiedAt_iff_of_isDedekindDomain have : Finite ((p.under R).ResidueField) := IsLocalization.finite _ (nonZeroDivisors (R ⧸ p.under R)) infer_instance + +/-- In characteristic zero the generic point is unramified: if `S` is a domain that is integral +over a characteristic-zero domain `R` and `R → S` is injective, then `S` is unramified at the zero +ideal. -/ +theorem isUnramifiedAt_bot [IsDomain R] [IsDomain S] [Module.IsTorsionFree R S] [CharZero R] + [Algebra.IsIntegral R S] : IsUnramifiedAt R (⊥ : Ideal S) := by + have : IsFractionRing S (Localization.AtPrime (⊥ : Ideal S)) := by + simpa [Ideal.primeCompl_bot] using Localization.isLocalization (M := (⊥ : Ideal S).primeCompl) + let : Field (Localization.AtPrime (⊥ : Ideal S)) := IsFractionRing.toField S + have : FaithfulSMul R (Localization.AtPrime (⊥ : Ideal S)) := by + rw [faithfulSMul_iff_algebraMap_injective, + IsScalarTower.algebraMap_eq R S (Localization.AtPrime ⊥)] + exact (IsFractionRing.injective S _).comp (FaithfulSMul.algebraMap_injective R S) + let := FractionRing.liftAlgebra R (Localization.AtPrime (⊥ : Ideal S)) + have : Algebra.IsAlgebraic (FractionRing R) (Localization.AtPrime ⊥) := + isAlgebraic_of_isFractionRing R S (FractionRing R) (Localization.AtPrime (⊥ : Ideal S)) + have : FormallyUnramified (FractionRing R) (Localization.AtPrime (⊥ : Ideal S)) := + FormallyUnramified.of_isSeparable _ _ + exact FormallyUnramified.comp R (FractionRing R) (Localization.AtPrime ⊥) + +/-- In characteristic zero, the zero ideal is unramified in an integral domain extension. -/ +theorem isUnramifiedIn_bot [IsDomain R] [IsDomain S] [FaithfulSMul R S] [CharZero R] + [Algebra.IsIntegral R S] : IsUnramifiedIn S (⊥ : Ideal R) := by + intro P _ hP + simpa [Ideal.eq_bot_of_liesOver_bot R P] using isUnramifiedAt_bot + +/-- Let `S` be a Dedekind domain that is torsion-free over a domain `R`, and let `p ≠ ⊥` be an +ideal of `R`. Then `p` is unramified in `S` if and only if `S` is unramified at every maximal +ideal `P` of `S` lying over `p`. + +See `Algebra.isUnramifiedIn_iff_forall_of_isDedekindDomain` if `R` is of characteristic zero. -/ +theorem isUnramifiedIn_iff_forall_of_isDedekindDomain' [IsDomain R] [IsDedekindDomain S] + [Module.IsTorsionFree R S] {p : Ideal R} (hp : p ≠ ⊥) : + IsUnramifiedIn S p ↔ + ∀ (P : Ideal S) (_ : P.IsMaximal), P.LiesOver p → IsUnramifiedAt R P := + ⟨fun h P hP hlo ↦ h P hP.isPrime hlo, + fun h P hP hlo ↦ h P (hP.isMaximal (Ideal.ne_bot_of_liesOver_of_ne_bot hp P)) hlo⟩ + +/-- Let `S` be a Dedekind domain that is integral and torsion-free over a characteristic-zero +domain `R`. Then an ideal `p` of `R` is unramified in `S` if and only if `S` is unramified at every +maximal ideal `P` of `S` lying over `p`. -/ +theorem isUnramifiedIn_iff_forall_of_isDedekindDomain [IsDomain R] [IsDedekindDomain S] + [Module.IsTorsionFree R S] [CharZero R] [Algebra.IsIntegral R S] {p : Ideal R} : + IsUnramifiedIn S p ↔ + ∀ (P : Ideal S) (_ : P.IsMaximal), P.LiesOver p → IsUnramifiedAt R P := by + refine ⟨fun h P hP hlo ↦ h P hP.isPrime hlo, fun h P hP hlo ↦ ?_⟩ + rcases eq_or_ne P ⊥ with rfl | hPbot + · exact isUnramifiedAt_bot + · exact h P (hP.isMaximal hPbot) hlo + +/-- For a prime `𝔓` of `S` lying over an unramified prime `𝔭` of `R`, the ramification index +`e(𝔓 ∣ 𝔭)` equals `1`. -/ +theorem IsUnramifiedIn.ramificationIdx_eq_one [IsDomain R] [IsDedekindDomain S] + [Module.IsTorsionFree R S] [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] + [Algebra.IsIntegral R S] {𝔭 : Ideal R} (hunr : IsUnramifiedIn S 𝔭) (h𝔭 : 𝔭 ≠ ⊥) {𝔓 : Ideal S} + [𝔓.IsPrime] (hP : 𝔓.LiesOver 𝔭) : Ideal.ramificationIdx 𝔭 𝔓 = 1 := by + rw [(Ideal.liesOver_iff 𝔓 𝔭).mp hP] + exact (isUnramifiedAt_iff_of_isDedekindDomain (Ideal.ne_bot_of_liesOver_of_ne_bot h𝔭 𝔓)).mp + (hunr 𝔓 inferInstance hP) + +/-- A nonzero ideal of `R` is unramified in `S` if and only if every prime ideal of `S` lying +over it has ramification index `1`. -/ +theorem isUnramifiedIn_iff_forall_ramificationIdx_eq_one [IsDomain R] [IsDedekindDomain S] + [Module.IsTorsionFree R S] [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] + [Algebra.IsIntegral R S] {𝔭 : Ideal R} (h𝔭 : 𝔭 ≠ ⊥) : + IsUnramifiedIn S 𝔭 ↔ + ∀ (𝔓 : Ideal S) [𝔓.IsPrime], 𝔓.LiesOver 𝔭 → Ideal.ramificationIdx 𝔭 𝔓 = 1 := by + refine ⟨fun hunr 𝔓 _ hP ↦ hunr.ramificationIdx_eq_one h𝔭 hP, fun h 𝔓 _ hP ↦ ?_⟩ + apply (isUnramifiedAt_iff_of_isDedekindDomain + (Ideal.ne_bot_of_liesOver_of_ne_bot h𝔭 𝔓)).mpr + rw [← (Ideal.liesOver_iff 𝔓 𝔭).mp hP] + exact h 𝔓 hP + +end Algebra + +end IsUnramifiedIn diff --git a/Mathlib/RingTheory/Unramified/Locus.lean b/Mathlib/RingTheory/Unramified/Locus.lean index f227c41f69e57f..07c2c4d447fe01 100644 --- a/Mathlib/RingTheory/Unramified/Locus.lean +++ b/Mathlib/RingTheory/Unramified/Locus.lean @@ -89,6 +89,21 @@ theorem IsUnramifiedAt.residueField end +section IsUnramifiedIn + +variable {R : Type*} [CommRing R] + +/-- A prime `𝔭` of `R` is unramified in `A` if every prime ideal `𝔓` of `A` lying over `𝔭` is +unramified . -/ +def IsUnramifiedIn (A : Type*) [CommRing A] [Algebra R A] (𝔭 : Ideal R) : Prop := + ∀ (𝔓 : Ideal A) (_ : 𝔓.IsPrime), 𝔓.LiesOver 𝔭 → Algebra.IsUnramifiedAt R 𝔓 + +variable (A : Type*) [CommRing A] [Algebra R A] + +theorem isUnramifiedIn_top : IsUnramifiedIn A (⊤ : Ideal R) := + fun P hP _ ↦ (hP.ne_top ((Ideal.eq_top_iff_of_liesOver P (⊤ : Ideal R)).mpr rfl)).elim + +end IsUnramifiedIn section variable {R A : Type*} [CommRing R] [CommRing A] [Algebra R A] From 06e4a530c2ee8e5c0fc6ba40a38d4814102c8fa2 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Mon, 22 Jun 2026 15:26:53 +0000 Subject: [PATCH 0255/1300] feat: a bit more API around `ContinuousAffineEquiv.pointReflection` (#40889) Following its introduction in #40637. --- .../AffineSpace/AffineEquiv.lean | 8 ++- .../Algebra/ContinuousAffineEquiv.lean | 69 +++++++++++++------ 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean index 75f205c9b55110..5c600a01296781 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean @@ -427,6 +427,7 @@ def vaddConst (b : P₁) : V₁ ≃ᵃ[k] P₁ where map_vadd' _ _ := add_vadd _ _ _ /-- `p' ↦ p -ᵥ p'` as an equivalence. -/ +@[simps! linear apply symm_apply] def constVSub (p : P₁) : P₁ ≃ᵃ[k] V₁ where toEquiv := Equiv.constVSub p linear := LinearEquiv.neg k @@ -514,10 +515,13 @@ This is `Equiv.pointReflection` as an `AffineEquiv`. -/ def pointReflection (x : P₁) : P₁ ≃ᵃ[k] P₁ := (constVSub k x).trans (vaddConst k x) -@[simp] lemma pointReflection_apply_eq_equivPointReflection_apply (x y : P₁) : - pointReflection k x y = Equiv.pointReflection x y := +@[simp] +lemma coe_pointReflection (x y : P₁) : pointReflection k x y = Equiv.pointReflection x y := rfl +@[deprecated (since := "2026-06-22")] +alias pointReflection_apply_eq_equivPointReflection_apply := coe_pointReflection + theorem pointReflection_apply (x y : P₁) : pointReflection k x y = (x -ᵥ y) +ᵥ x := rfl diff --git a/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean b/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean index 3605d581af24e8..e0f4fb8983310f 100644 --- a/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean +++ b/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean @@ -97,18 +97,6 @@ theorem coe_coe (e : P₁ ≃ᴬ[k] P₂) : ⇑(e : P₁ ≃ᵃ[k] P₂) = e := theorem coe_toEquiv (e : P₁ ≃ᴬ[k] P₂) : ⇑e.toEquiv = e := rfl -/-- See Note [custom simps projection]. - We need to specify this projection explicitly in this case, - because it is a composition of multiple projections. -/ -def Simps.apply (e : P₁ ≃ᴬ[k] P₂) : P₁ → P₂ := - e - -/-- See Note [custom simps projection]. -/ -def Simps.symm_apply (e : P₁ ≃ᴬ[k] P₂) : P₂ → P₁ := - e.symm - -initialize_simps_projections ContinuousAffineEquiv (toFun → apply, invFun → symm_apply) - @[ext] theorem ext {e e' : P₁ ≃ᴬ[k] P₂} (h : ∀ x, e x = e' x) : e = e' := DFunLike.ext _ _ h @@ -178,6 +166,18 @@ def symm (e : P₁ ≃ᴬ[k] P₂) : P₂ ≃ᴬ[k] P₁ where continuous_toFun := e.continuous_invFun continuous_invFun := e.continuous_toFun +/-- See Note [custom simps projection]. + We need to specify this projection explicitly in this case, + because it is a composition of multiple projections. -/ +def Simps.apply (e : P₁ ≃ᴬ[k] P₂) : P₁ → P₂ := + e + +/-- See Note [custom simps projection]. -/ +def Simps.symm_apply (e : P₁ ≃ᴬ[k] P₂) : P₂ → P₁ := + e.symm + +initialize_simps_projections ContinuousAffineEquiv (toFun → apply, invFun → symm_apply) + @[simp] theorem toAffineEquiv_symm (e : P₁ ≃ᴬ[k] P₂) : e.symm.toAffineEquiv = e.toAffineEquiv.symm := rfl @@ -312,16 +312,34 @@ section variable (k) variable [TopologicalSpace V₁] [IsTopologicalAddTorsor P₁] +/-- The affine homeomorphism `V ≃ᴬ[k] P` given by `v ↦ v +ᵥ p`. This is `Equiv.vaddConst` +as a `ContinuousAffineEquiv`. -/ +@[simps! apply symm_apply] +def vaddConst (p : P₁) : V₁ ≃ᴬ[k] P₁ where + __ := AffineEquiv.vaddConst k p + __ := Homeomorph.vaddConst p + +@[simp] +lemma toAffineEquiv_vaddConst {p : P₁} : vaddConst k p = AffineEquiv.vaddConst k p := rfl + +/-- The affine homeomorphism given by `p' ↦ p -ᵥ p'`. This is `Equiv.constVSub` as a +`ContinuousAffineEquiv`. -/ +@[simps! apply symm_apply] +def constVSub (p : P₁) : P₁ ≃ᴬ[k] V₁ where + __ := AffineEquiv.constVSub k p + __ := Homeomorph.constVSub p + +@[simp] +lemma toAffineEquiv_constVSub {p : P₁} : constVSub k p = AffineEquiv.constVSub k p := rfl + /-- The affine homeomorphism given by reflection about the point `x`. This is `Equiv.pointReflection` as a `ContinuousAffineEquiv`. -/ -@[simps toAffineEquiv] -def pointReflection (x : P₁) : P₁ ≃ᴬ[k] P₁ where - toAffineEquiv := AffineEquiv.pointReflection k x - continuous_toFun := by dsimp [Equiv.pointReflection]; fun_prop - continuous_invFun := by - let : ContinuousNeg V₁ := - IsTopologicalAddTorsor.to_isTopologicalAddGroup (V := V₁) (P := P₁) |>.toContinuousNeg - dsimp [Equiv.pointReflection]; fun_prop +def pointReflection (x : P₁) : P₁ ≃ᴬ[k] P₁ := + (constVSub k x).trans (vaddConst k x) + +@[simp] +lemma coe_pointReflection (x : P₁) : + (pointReflection k x : P₁ → P₁) = Equiv.pointReflection x := rfl theorem pointReflection_apply (x y : P₁) : pointReflection k x y = (x -ᵥ y) +ᵥ x := rfl @@ -330,6 +348,17 @@ theorem pointReflection_apply (x y : P₁) : pointReflection k x y = (x -ᵥ y) theorem pointReflection_symm (x : P₁) : (pointReflection k x).symm = pointReflection k x := toAffineEquiv_injective <| AffineEquiv.pointReflection_symm k x +@[simp] +theorem toAffineEquiv_pointReflection (x : P₁) : + (pointReflection k x).toAffineEquiv = AffineEquiv.pointReflection k x := + rfl + +theorem pointReflection_self (x : P₁) : pointReflection k x x = x := + vsub_vadd _ _ + +theorem pointReflection_involutive (x : P₁) : Involutive (pointReflection k x : P₁ → P₁) := + Equiv.pointReflection_involutive x + end section From 8480e753dfcf2bacd13fad632ba8ed853f7c3dab Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:23:51 +0000 Subject: [PATCH 0256/1300] chore(Algebra): some API for `IsLocalizedModule.Away` (#40454) These are mostly analogues of what we have for `IsLocalization.Away`. The `Away` file was previously deprecated, but seems like the natural fit for the material, since the `Basic` file is currently just below the 1.5k length limit. --- .../Algebra/Module/LocalizedModule/Away.lean | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Module/LocalizedModule/Away.lean b/Mathlib/Algebra/Module/LocalizedModule/Away.lean index 1513c0b071c8c5..9d1f97c89ee111 100644 --- a/Mathlib/Algebra/Module/LocalizedModule/Away.lean +++ b/Mathlib/Algebra/Module/LocalizedModule/Away.lean @@ -1,5 +1,81 @@ -module -- shake: keep-all +/- +Copyright (c) 2026 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +module public import Mathlib.Algebra.Module.LocalizedModule.Basic -deprecated_module (since := "2026-04-23") +/-! +# API for localized modules away from an element + +We provide some specialized API for the localization of a module away from an element. +-/ + +public section + +namespace IsLocalizedModule.Away + +variable {R : Type*} [CommSemiring R] {M N : Type*} [AddCommMonoid M] [AddCommMonoid N] + [Module R M] [Module R N] {f : M →ₗ[R] N} {r : R} + +lemma mk (h₁ : IsUnit (algebraMap R (Module.End R N) r)) + (h₂ : ∀ (x : N), ∃ (n : ℕ) (y : M), r ^ n • x = f y) + (h₃ : ∀ (x y : M), f x = f y → ∃ (n : ℕ), r ^ n • x = r ^ n • y) : + IsLocalizedModule.Away r f where + map_units := fun ⟨_, ⟨n, rfl⟩⟩ ↦ by simp [h₁.pow] + surj x := by + obtain ⟨n, y, hy⟩ := h₂ x + use ⟨y, ⟨_, n, rfl⟩⟩, hy + exists_of_eq {x y} hxy := by + obtain ⟨n, hn⟩ := h₃ _ _ hxy + use ⟨_, n, rfl⟩, hn + +lemma mk_of_addCommGroup {M N : Type*} [AddCommGroup M] [AddCommGroup N] [Module R M] [Module R N] + {f : M →ₗ[R] N} {r : R} (h₁ : IsUnit (algebraMap R (Module.End R N) r)) + (h₂ : ∀ (x : N), ∃ (n : ℕ) (y : M), r ^ n • x = f y) + (h₃ : ∀ (x : M), f x = 0 → ∃ (n : ℕ), r ^ n • x = 0) : + IsLocalizedModule.Away r f := by + refine IsLocalizedModule.Away.mk h₁ h₂ fun x y hxy ↦ ?_ + have : f (x - y) = 0 := by simp [hxy] + obtain ⟨n, hn⟩ := h₃ _ this + use n + simpa [smul_sub, sub_eq_zero] using hn + +variable (r) [IsLocalizedModule.Away r f] + +variable (f) in +include f in +lemma isUnit_algebraMap : IsUnit (algebraMap R (Module.End R N) r) := + IsLocalizedModule.map_units (S := .powers r) f ⟨_, 1, by simp⟩ + +lemma exists_of_eq {x y : M} (h : f x = f y) : ∃ (n : ℕ), r ^ n • x = r ^ n • y := by + obtain ⟨⟨_, n, rfl⟩, hn⟩ := IsLocalizedModule.exists_of_eq (S := .powers r) h + use n, hn + +variable (f) in +lemma surj (y : N) : ∃ (n : ℕ) (x : M), r ^ n • y = f x := by + obtain ⟨⟨x, ⟨_, n, rfl⟩⟩, h⟩ := IsLocalizedModule.surj (S := .powers r) f y + use n, x, h + +lemma of_associated {r r' : R} (h : Associated r r') [IsLocalizedModule.Away r f] : + IsLocalizedModule.Away r' f := by + obtain ⟨u, rfl⟩ := h + rw [mul_comm] + refine .mk ?_ ?_ ?_ + · simp [IsUnit.mul, isUnit_algebraMap f r, u.isUnit.map _] + · intro y + obtain ⟨n, x, hx⟩ := surj f r y + use n, (u ^ n) • x + simp [mul_pow, ← hx, mul_smul, Units.smul_def] + · intro x y hxy + obtain ⟨n, hn⟩ := exists_of_eq r hxy + use n + simp [mul_pow, mul_smul, hn] + +lemma iff_of_associated {r r' : R} (h : Associated r r') : + IsLocalizedModule.Away r f ↔ IsLocalizedModule.Away r' f := + ⟨fun _ ↦ .of_associated h, fun _ ↦ .of_associated h.symm⟩ + +end IsLocalizedModule.Away From 8ade642d99dbfbfcdcaad4965baba903385a1e51 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:23:53 +0000 Subject: [PATCH 0257/1300] feat(CategoryTheory/Sites): pushforward and pullback of presieves (#40527) We define analogues of `Sieve.pushforward` and `Sieve.pullback` for `Presieve`s and show the Galois connection. --- .../Sites/CoproductSheafCondition.lean | 3 +- .../CategoryTheory/Sites/Hypercover/Zero.lean | 60 ++++++++++++ Mathlib/CategoryTheory/Sites/IsSheafFor.lean | 4 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 92 ++++++++++++++++++- 4 files changed, 155 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean b/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean index 9ebc9725d813d7..7c09039b9dde8d 100644 --- a/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean +++ b/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean @@ -86,7 +86,8 @@ lemma Presieve.isSheafFor_sigmaDesc_iff {ι : Type*} {X : ι → C} (f : ∀ i, [∀ i, HasPullback (f i) (Cofan.IsColimit.desc hc f)] (F : Cᵒᵖ ⥤ Type*) [PreservesLimit (Discrete.functor <| fun i ↦ op (X i)) F] - [PreservesLimit (Discrete.functor fun (ij : ι × ι) ↦ op (pullback (f ij.1) (f ij.2))) F] : + [PreservesLimit (Discrete.functor fun (ij : ι × ι) ↦ + op (Limits.pullback (f ij.1) (f ij.2))) F] : Presieve.IsSheafFor F (.singleton <| Cofan.IsColimit.desc hc f) ↔ Presieve.IsSheafFor F (.ofArrows X f) := by let E := PreZeroHypercover.mk _ _ f diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean b/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean index 45384739957a84..b245a70e8c9c81 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean @@ -377,6 +377,56 @@ lemma Hom.sieve₀_le_sieve₀ {E F : PreZeroHypercover S} (f : E.Hom F) : E.sie lemma sieve₀_eq_of_iso {E F : PreZeroHypercover S} (e : E ≅ F) : E.sieve₀ = F.sieve₀ := le_antisymm e.hom.sieve₀_le_sieve₀ e.inv.sieve₀_le_sieve₀ +/-- The equivalence on index types induced by an isomorphism of pre-`0`-hypercovers. -/ +@[simps] +def equivOfIso {E F : PreZeroHypercover.{w} S} (e : E ≅ F) : E.I₀ ≃ F.I₀ where + toFun := e.hom.s₀ + invFun := e.inv.s₀ + left_inv _ := by simp + right_inv _ := by simp + +lemma mem_of_iso {K : Precoverage C} [K.IsStableUnderComposition] [K.HasIsos] {X : C} + {E F : PreZeroHypercover.{w} X} (e : E ≅ F) (hE : E.presieve₀ ∈ K X) : + F.presieve₀ ∈ K X := by + have : F.presieve₀ = + Presieve.ofArrows (fun (i : Σ (_ : F.I₀), Unit) ↦ _) (fun i ↦ e.inv.h₀ i.1 ≫ E.f _) := by + simp only [Hom.w₀] + refine le_antisymm ?_ ?_ + · rw [Presieve.ofArrows_le_iff] + intro i + exact .mk (⟨i, ⟨⟩⟩ : Σ (_ : F.I₀), Unit) + · simp [Presieve.ofArrows_le_iff] + rw [this] + refine K.comp_mem_coverings (fun i ↦ E.f (e.inv.s₀ i)) ?_ (fun i (k : Unit) ↦ e.inv.h₀ i) ?_ + · rwa [← E.presieve₀_reindex (PreZeroHypercover.equivOfIso e.symm)] at hE + · intro i + rw [Presieve.ofArrows_pUnit] + exact K.mem_coverings_of_isIso _ + +lemma mem_iff_of_iso {K : Precoverage C} [K.IsStableUnderComposition] [K.HasIsos] {X : C} + {E F : PreZeroHypercover.{w} X} (e : E ≅ F) : + E.presieve₀ ∈ K X ↔ F.presieve₀ ∈ K X := + ⟨fun h ↦ PreZeroHypercover.mem_of_iso e h, fun h ↦ PreZeroHypercover.mem_of_iso e.symm h⟩ + +/-- Compose a pre-`0`-hypercover with a morphism on the right. -/ +@[simps] +def pushforward {X Y : C} (f : X ⟶ Y) (E : PreZeroHypercover.{w} X) : + PreZeroHypercover.{w} Y where + I₀ := E.I₀ + X := E.X + f i := E.f i ≫ f + +lemma presieve₀_pushforward {X Y : C} (f : X ⟶ Y) (E : PreZeroHypercover.{w} X) : + (E.pushforward f).presieve₀ = E.presieve₀.pushforward f := by + simp [presieve₀, Presieve.pushforward_ofArrows, pushforward] + +set_option backward.isDefEq.respectTransparency false in +/-- Pushforward along a morphism is the same as refining the singleton pre-`0`-hypercover. -/ +@[simps!] +def pushforwardIsoBind {X Y : C} (f : X ⟶ Y) (E : PreZeroHypercover.{w} X) : + E.pushforward f ≅ (singleton f).bind fun _ ↦ E := + isoMk ((Equiv.uniqueSigma fun i ↦ E.I₀).symm) (fun _ ↦ Iso.refl _) + end Category section Functoriality @@ -728,6 +778,16 @@ def weaken {K L : Precoverage C} {X : C} (E : Precoverage.ZeroHypercover K X) (h __ := E mem₀ := h _ E.mem₀ +/-- Compose a `0`-hypercover with a morphism on the right. -/ +@[simps toPreZeroHypercover] +def pushforward [J.IsStableUnderComposition] [J.HasIsos] {X Y : C} (f : X ⟶ Y) + (hf : .singleton f ∈ J _) (E : ZeroHypercover.{w} J X) : + ZeroHypercover.{w} J Y where + __ := E.toPreZeroHypercover.pushforward f + mem₀ := by + rw [PreZeroHypercover.mem_iff_of_iso (E.pushforwardIsoBind _)] + exact ((ZeroHypercover.singleton f hf).bind _).mem₀ + instance (K : Precoverage C) [K.HasPullbacks] {X Y : C} (E : K.ZeroHypercover X) (f : Y ⟶ X) : E.presieve₀.HasPullbacks f := K.hasPullbacks_of_mem _ E.mem₀ diff --git a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean index 7044c4e243f591..139fcc18e1d29f 100644 --- a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean +++ b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean @@ -1062,10 +1062,10 @@ theorem isSheafFor_trans (P : Cᵒᵖ ⥤ Type*) (R S : Sieve X) apply Presieve.isSheafFor_subsieve_aux P this · apply isSheafFor_bind _ _ _ hR hS intro Y f hf Z g - rw [← pullback_comp] + rw [← Sieve.pullback_comp] apply (hS (R.downward_closed hf _)).isSeparatedFor · intro Y f hf - have : Sieve.pullback f (Sieve.bind R fun T (k : T ⟶ X) (_ : R k) => pullback k S) = + have : Sieve.pullback f (Sieve.bind R fun T (k : T ⟶ X) (_ : R k) => Sieve.pullback k S) = R.pullback f := by ext Z g constructor diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 7838be1c2e50fd..8a23a45ba149dd 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -295,6 +295,82 @@ lemma bindOfArrows_ofArrows {ι : Type*} {S : C} {X : ι → C} (f : (i : ι) rintro W u ⟨i, v, ⟨j⟩⟩ exact ⟨Sigma.mk i j⟩ +/-- Compose a presieve on the right with a morphism. -/ +def pushforward {X Y : C} (f : X ⟶ Y) (R : Presieve X) : Presieve Y := + fun Z fg ↦ ∃ (g : Z ⟶ X), g ≫ f = fg ∧ R g + +@[grind .] +lemma pushforward_apply_comp {X Y Z : C} {f : X ⟶ Y} {R : Presieve X} {g : Z ⟶ X} (hg : R g) : + R.pushforward f (g ≫ f) := + ⟨g, rfl, hg⟩ + +lemma pushforward_ofArrows {ι : Type*} {U : ι → C} {X Y : C} (g : ∀ i, U i ⟶ X) + (f : X ⟶ Y) : (ofArrows _ g).pushforward f = ofArrows _ (g · ≫ f) := by + refine le_antisymm ?_ ?_ + · rintro _ _ ⟨u, rfl, ⟨i⟩⟩ + exact ⟨i⟩ + · rw [ofArrows_le_iff] + intro i + use g i, rfl + exact ⟨i⟩ + +lemma pushforward_singleton {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : + (singleton f).pushforward g = .singleton (f ≫ g) := by + rw [← ofArrows_pUnit.{_, _, 0}, pushforward_ofArrows, ofArrows_pUnit.{_, _, 0}] + +/-- The pullback of a presieve `R` on `Y` along a morphism `f : X ⟶ Y` is the presieve on `X` +given by all morphisms `g : Z ⟶ X` such that `f ≫ g` is in `R`. -/ +def pullback {X Y : C} (f : X ⟶ Y) (R : Presieve Y) : Presieve X := + fun _ g ↦ R (g ≫ f) + +variable {f} in +@[simp, grind =] +lemma pullback_iff {R : Presieve X} {Z : C} {g : Z ⟶ Y} : + R.pullback f g ↔ R (g ≫ f) := + .rfl + +lemma pushforward_le_iff_le_pullback (R : Presieve Y) (T : Presieve X) : + R.pushforward f ≤ T ↔ R ≤ T.pullback f := by + refine ⟨fun hle Z g hg ↦ hle _ _ (pushforward_apply_comp hg), ?_⟩ + rintro hle Z - ⟨g, rfl, hg⟩ + exact hle _ _ hg + +lemma galoisConnection_pushforward_pullback : + GaloisConnection (pushforward f) (pullback f) := + pushforward_le_iff_le_pullback f + +lemma monotone_pushforward : Monotone (pushforward f) := + (galoisConnection_pushforward_pullback f).monotone_l + +lemma monotone_pullback : Monotone (pullback f) := + (galoisConnection_pushforward_pullback f).monotone_u + +lemma pushforward_pullback_le (R : Presieve X) : (R.pullback f).pushforward f ≤ R := + (galoisConnection_pushforward_pullback f).l_u_le _ + +lemma le_pullback_pushforward (R : Presieve Y) : R ≤ (R.pushforward f).pullback f := + (galoisConnection_pushforward_pullback f).le_u_l _ + +@[simp] +lemma pullback_id (R : Presieve X) : R.pullback (𝟙 X) = R := by + funext + simp + +lemma pullback_comp (R : Presieve Z) (g : X ⟶ Z) : + R.pullback (f ≫ g) = (R.pullback g).pullback f := by + funext + simp + +@[simp] +lemma pushforward_id (R : Presieve X) : R.pushforward (𝟙 X) = R := by + funext + simp [pushforward] + +lemma pushforward_comp (R : Presieve Y) (g : X ⟶ Z) : + R.pushforward (f ≫ g) = (R.pushforward f).pushforward g := by + funext + simp [pushforward] + /-- Given a presieve on `F(X)`, we can define a presieve on `X` by taking the preimage via `F`. -/ def functorPullback (R : Presieve (F.obj X)) : Presieve X := fun _ f => R (F.map f) @@ -462,7 +538,8 @@ def uncurry : Set (Σ Y, Y ⟶ X) := obtain ⟨rfl, h⟩ := h; subst h; constructor @[simp] theorem uncurry_pullbackArrows [HasPullbacks C] {B : C} (b : B ⟶ X) : - (pullbackArrows b s).uncurry = (fun f ↦ ⟨pullback f.2 b, pullback.snd _ _⟩) '' s.uncurry := by + (pullbackArrows b s).uncurry = + (fun f ↦ ⟨Limits.pullback f.2 b, pullback.snd _ _⟩) '' s.uncurry := by ext ⟨Z, v⟩; constructor · rintro ⟨Y, u, hu⟩; exact ⟨⟨Y, u⟩, hu, rfl⟩ · rintro ⟨⟨Y, u⟩, hu, h⟩ @@ -956,6 +1033,19 @@ theorem pullbackArrows_comm {X Y : C} (f : Y ⟶ X) (R : Presieve X) [R.HasPullb have := R.hasPullback f hk exact ⟨_, _, _, Presieve.pullbackArrows.mk _ _ hk, pullback.lift_snd _ _ comm⟩ +lemma pullback_arrows {X Y : C} (f : X ⟶ Y) (S : Sieve Y) : + (S.pullback f).arrows = S.arrows.pullback f := + rfl + +lemma pushforward_arrows {X Y : C} (f : X ⟶ Y) (S : Sieve X) : + (S.pushforward f).arrows = S.arrows.pushforward f := + rfl + +lemma generate_pushforward {X Y : C} (f : X ⟶ Y) (R : Presieve X) : + generate (R.pushforward f) = (generate R).pushforward f := by + ext + grind [generate_apply, Presieve.pushforward, pushforward_apply] + section Functor variable {E : Type u₃} [Category.{v₃} E] (G : D ⥤ E) From c27dae6d362add64b9c8778a6184ca90992211bb Mon Sep 17 00:00:00 2001 From: Bolton Bailey Date: Mon, 22 Jun 2026 16:23:56 +0000 Subject: [PATCH 0258/1300] feat(NumberTheory/FactorizationProperties): add positivity lemmas (#40562) This PR proves the basic fact that abundant, deficient, and weird numbers are positive. This was done as a part of Project Numina's LeanTriathlon project with the help of AI (Claude Code and Numina's lean agent) --- Mathlib/NumberTheory/FactorisationProperties.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/NumberTheory/FactorisationProperties.lean b/Mathlib/NumberTheory/FactorisationProperties.lean index 00ed37e5c471c2..cea8ccdfdc3df0 100644 --- a/Mathlib/NumberTheory/FactorisationProperties.lean +++ b/Mathlib/NumberTheory/FactorisationProperties.lean @@ -81,6 +81,9 @@ theorem not_pseudoperfect_iff_forall : ¬ Pseudoperfect n ↔ n = 0 ∨ ∀ s ⊆ properDivisors n, ∑ i ∈ s, i ≠ n := by grind [Pseudoperfect] +theorem not_deficient_zero : ¬ Deficient 0 := by + decide + theorem deficient_one : Deficient 1 := by decide @@ -96,9 +99,21 @@ theorem not_abundant_zero : ¬ Abundant 0 := by theorem abundant_twelve : Abundant 12 := by decide +theorem not_weird_zero : ¬ Weird 0 := by + decide + theorem weird_seventy : Weird 70 := by decide +kernel +lemma Deficient.pos (h : Deficient n) : 0 < n := by + grind only [not_deficient_zero] + +lemma Abundant.pos (h : Abundant n) : 0 < n := by + grind only [not_abundant_zero] + +lemma Weird.pos (h : Weird n) : 0 < n := by + grind only [not_weird_zero] + lemma deficient_iff_not_abundant_and_not_perfect (hn : n ≠ 0) : Deficient n ↔ ¬ Abundant n ∧ ¬ Perfect n := by grind [Perfect, Abundant, Deficient] From 553eb7263d544ddfb32d37456245d9358fa4a4cd Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:23:59 +0000 Subject: [PATCH 0259/1300] chore(Topology): namespace lemmas around `IsInducing`, `IsQuotientMap` etc (#40891) The predicates `IsInducing`, `IsEmbedding`, `IsQuotientMap` etc. were moved to the `Topology` namespace in #15993, but some lemmas were not moved with them, or were added outside of the namespace later. This PR moves these lemmas to the correct namespace to enable dot notation. We do not add deprecation aliases since the lemmas only get namespaced, not renamed, and having both the lemmas and their deprecated aliases available inside the namespace could lead to trouble. --- .../AlgebraicGeometry/Morphisms/UnderlyingMap.lean | 4 ++-- Mathlib/Condensed/TopComparison.lean | 2 +- .../MeasureTheory/Constructions/BorelSpace/Basic.lean | 3 ++- Mathlib/Topology/Constructions/SumProd.lean | 11 ++++++----- Mathlib/Topology/DiscreteSubset.lean | 2 +- Mathlib/Topology/Inseparable.lean | 2 +- Mathlib/Topology/KrullDimension.lean | 8 ++++---- Mathlib/Topology/LocalAtTarget.lean | 5 +---- Mathlib/Topology/Separation/Hausdorff.lean | 2 +- 9 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean index f505798c3260fe..64b3f6a6381810 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean @@ -314,8 +314,8 @@ end SpecializingMap section GeneralizingMap instance : (topologically GeneralizingMap).RespectsIso := - topologically_respectsIso _ (fun f ↦ f.isOpenEmbedding.generalizingMap - f.isOpenEmbedding.isOpen_range.stableUnderGeneralization) (fun _ _ hf hg ↦ hf.comp hg) + topologically_respectsIso _ (fun f ↦ f.isOpenEmbedding.generalizingMap) + (fun _ _ hf hg ↦ hf.comp hg) instance : IsZariskiLocalAtSource (topologically GeneralizingMap) := topologically_isZariskiLocalAtSource' (fun _ ↦ _) fun _ _ _ hU _ ↦ hU.generalizingMap_iff_comp diff --git a/Mathlib/Condensed/TopComparison.lean b/Mathlib/Condensed/TopComparison.lean index 0fd74643ae8dbf..11985db7efee7a 100644 --- a/Mathlib/Condensed/TopComparison.lean +++ b/Mathlib/Condensed/TopComparison.lean @@ -117,7 +117,7 @@ def TopCat.toSheafCompHausLike : apply +allowSynthFailures equalizerCondition_yonedaPresheaf (CompHausLike.compHausLikeToTop.{u} P) X intro Z B π he - apply IsQuotientMap.of_surjective_continuous (hs _ he) π.hom.hom.continuous + exact .of_surjective_continuous (hs _ he) π.hom.hom.continuous /-- `TopCat.toSheafCompHausLike` yields a functor from `TopCat.{max u w}` to diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index 9bf51c1660b896..6d155826e04879 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -500,7 +500,8 @@ is ae-measurable. -/ theorem Continuous.aemeasurable {f : α → γ} (h : Continuous f) {μ : Measure α} : AEMeasurable f μ := h.measurable.aemeasurable -theorem IsClosedEmbedding.measurable {f : α → γ} (hf : IsClosedEmbedding f) : Measurable f := +theorem Topology.IsClosedEmbedding.measurable {f : α → γ} (hf : IsClosedEmbedding f) : + Measurable f := hf.continuous.measurable /-- If a function is defined piecewise in terms of functions which are continuous on their diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index 8c417843dbf7e1..ab4185bf312be4 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -800,7 +800,7 @@ theorem IsOpenMap.sumElim {f : X → Z} {g : Y → Z} (hf : IsOpenMap f) (hg : I IsOpenMap (Sum.elim f g) := isOpenMap_sumElim.2 ⟨hf, hg⟩ -lemma IsOpenEmbedding.sumElim {f : X → Z} {g : Y → Z} +lemma Topology.IsOpenEmbedding.sumElim {f : X → Z} {g : Y → Z} (hf : IsOpenEmbedding f) (hg : IsOpenEmbedding g) (h : Injective (Sum.elim f g)) : IsOpenEmbedding (Sum.elim f g) := by rw [isOpenEmbedding_iff_continuous_injective_isOpenMap] at hf hg ⊢ @@ -830,7 +830,7 @@ theorem IsClosedMap.sumElim {f : X → Z} {g : Y → Z} (hf : IsClosedMap f) (hg IsClosedMap (Sum.elim f g) := isClosedMap_sumElim.2 ⟨hf, hg⟩ -lemma IsClosedEmbedding.sumElim {f : X → Z} {g : Y → Z} +lemma Topology.IsClosedEmbedding.sumElim {f : X → Z} {g : Y → Z} (hf : IsClosedEmbedding f) (hg : IsClosedEmbedding g) (h : Injective (Sum.elim f g)) : IsClosedEmbedding (Sum.elim f g) := by rw [IsClosedEmbedding.isClosedEmbedding_iff_continuous_injective_isClosedMap] at hf hg ⊢ @@ -974,16 +974,17 @@ theorem Topology.IsInducing.disjoint_of_sumElim_aux (h : IsInducing (Sum.elim f exact disjoint_image_inl_image_inr exact B.mono_left A -theorem IsOpenEmbedding.sumSwap : IsOpenEmbedding (@Sum.swap X Y) := +theorem Topology.IsOpenEmbedding.sumSwap : IsOpenEmbedding (@Sum.swap X Y) := (Homeomorph.sumComm X Y).isOpenEmbedding -theorem IsInducing.sumSwap : IsInducing (@Sum.swap X Y) := IsOpenEmbedding.sumSwap.isInducing +theorem Topology.IsInducing.sumSwap : IsInducing (@Sum.swap X Y) := + IsOpenEmbedding.sumSwap.isInducing theorem isInducing_sumElim : IsInducing (Sum.elim f g) ↔ IsInducing f ∧ IsInducing g ∧ Disjoint (closure (range f)) (range g) ∧ Disjoint (range f) (closure (range g)) := ⟨fun h ↦ ⟨h.sumElim_left, h.sumElim_right, h.disjoint_of_sumElim_aux, - ((Sum.elim_swap ▸ h.comp IsInducing.sumSwap).disjoint_of_sumElim_aux ).symm⟩, + ((Sum.elim_swap ▸ h.comp .sumSwap).disjoint_of_sumElim_aux ).symm⟩, fun ⟨hf, hg, hFg, hfG⟩ ↦ hf.sumElim hg hFg hfG⟩ lemma Topology.IsInducing.sumElim_of_separatedNhds diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 108b7ca92a5d8d..6cfe19a31b5217 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -112,7 +112,7 @@ lemma IsOpenMap.isDiscrete_range [DiscreteTopology X] (hf : IsOpenMap f) : lemma IsDiscrete.image (hs : IsDiscrete s) (hf : IsInducing f) : IsDiscrete (f '' s) := by simp_all [isDiscrete_iff_nhdsWithin, ← hf.map_nhdsWithin_eq s] -lemma IsInducing.isDiscrete_range [DiscreteTopology X] (hf : IsInducing f) : +lemma Topology.IsInducing.isDiscrete_range [DiscreteTopology X] (hf : IsInducing f) : IsDiscrete (Set.range f) := by simpa using IsDiscrete.univ.image hf diff --git a/Mathlib/Topology/Inseparable.lean b/Mathlib/Topology/Inseparable.lean index cd48ad7ae8dc44..548e63f3a83ded 100644 --- a/Mathlib/Topology/Inseparable.lean +++ b/Mathlib/Topology/Inseparable.lean @@ -413,7 +413,7 @@ lemma Topology.IsInducing.generalizingMap (hf : IsInducing f) obtain ⟨y, rfl⟩ := h e ⟨x, rfl⟩ exact ⟨_, hf.specializes_iff.mp e, rfl⟩ -lemma IsOpenEmbedding.generalizingMap (hf : IsOpenEmbedding f) : GeneralizingMap f := +lemma Topology.IsOpenEmbedding.generalizingMap (hf : IsOpenEmbedding f) : GeneralizingMap f := hf.isInducing.generalizingMap hf.isOpen_range.stableUnderGeneralization lemma SpecializingMap.stableUnderSpecialization_range (h : SpecializingMap f) : diff --git a/Mathlib/Topology/KrullDimension.lean b/Mathlib/Topology/KrullDimension.lean index 187f1e25b66e46..0b55b422398669 100644 --- a/Mathlib/Topology/KrullDimension.lean +++ b/Mathlib/Topology/KrullDimension.lean @@ -45,7 +45,7 @@ variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] ### Main dimension theorems -/ /-- If `f : Y → X` is inducing, then `dim(Y) ≤ dim(X)`. -/ -theorem IsInducing.topologicalKrullDim_le {f : Y → X} (hf : IsInducing f) : +theorem Topology.IsInducing.topologicalKrullDim_le {f : Y → X} (hf : IsInducing f) : topologicalKrullDim Y ≤ topologicalKrullDim X := krullDim_le_of_strictMono _ (map_strictMono_of_isInducing hf) @@ -53,16 +53,16 @@ theorem IsInducing.topologicalKrullDim_le {f : Y → X} (hf : IsInducing f) : theorem IsHomeomorph.topologicalKrullDim_eq (f : X → Y) (h : IsHomeomorph f) : topologicalKrullDim X = topologicalKrullDim Y := have fwd : topologicalKrullDim X ≤ topologicalKrullDim Y := - IsInducing.topologicalKrullDim_le h.isClosedEmbedding.toIsInducing + h.isInducing.topologicalKrullDim_le have bwd : topologicalKrullDim Y ≤ topologicalKrullDim X := - IsInducing.topologicalKrullDim_le (h.homeomorph f).symm.isClosedEmbedding.toIsInducing + (h.homeomorph f).symm.isInducing.topologicalKrullDim_le le_antisymm fwd bwd /-- The topological Krull dimension of any subspace is at most the dimension of the ambient space. -/ theorem topologicalKrullDim_subspace_le (X : Type*) [TopologicalSpace X] (Y : Set X) : topologicalKrullDim Y ≤ topologicalKrullDim X := - IsInducing.topologicalKrullDim_le IsInducing.subtypeVal + IsInducing.subtypeVal.topologicalKrullDim_le theorem topologicalKrullDim_zero_of_discreteTopology (X : Type*) [TopologicalSpace X] [DiscreteTopology X] : diff --git a/Mathlib/Topology/LocalAtTarget.lean b/Mathlib/Topology/LocalAtTarget.lean index 6bb1eb268b78e7..1ff14ed4d98080 100644 --- a/Mathlib/Topology/LocalAtTarget.lean +++ b/Mathlib/Topology/LocalAtTarget.lean @@ -224,10 +224,7 @@ lemma isOpenMap_iff_comp : IsOpenMap f ↔ ∀ i, IsOpenMap (f ∘ ((↑) : U i lemma generalizingMap_iff_comp : GeneralizingMap f ↔ ∀ i, GeneralizingMap (f ∘ ((↑) : U i → α)) := by - refine ⟨fun hf ↦ fun i ↦ - ((U i).isOpenEmbedding'.generalizingMap - (U i).isOpenEmbedding'.isOpen_range.stableUnderGeneralization).comp hf, - fun hf ↦ fun x y h ↦ ?_⟩ + refine ⟨fun hf i ↦ ((U i).isOpenEmbedding'.generalizingMap).comp hf, fun hf ↦ fun x y h ↦ ?_⟩ obtain ⟨i, hi⟩ := hU.exists_mem x replace h : y ⤳ (f ∘ ((↑) : U i → α)) ⟨x, hi⟩ := h obtain ⟨a, ha, rfl⟩ := hf i h diff --git a/Mathlib/Topology/Separation/Hausdorff.lean b/Mathlib/Topology/Separation/Hausdorff.lean index 934cdd1aa08abf..bdcb3685f9d283 100644 --- a/Mathlib/Topology/Separation/Hausdorff.lean +++ b/Mathlib/Topology/Separation/Hausdorff.lean @@ -675,7 +675,7 @@ theorem Continuous.isClosedEmbedding [CompactSpace X] [T2Space Y] {f : X → Y} .of_continuous_injective_isClosedMap h hf h.isClosedMap /-- A continuous surjective map from a compact space to a Hausdorff space is a quotient map. -/ -theorem IsQuotientMap.of_surjective_continuous [CompactSpace X] [T2Space Y] {f : X → Y} +theorem Topology.IsQuotientMap.of_surjective_continuous [CompactSpace X] [T2Space Y] {f : X → Y} (hsurj : Surjective f) (hcont : Continuous f) : IsQuotientMap f := hcont.isClosedMap.isQuotientMap hcont hsurj From b0af307631dda8100752be5e78e50a28b4e4fce0 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:24:02 +0000 Subject: [PATCH 0260/1300] feat(CategoryTheory/Limits/Comma): comma categories have finite (co)limits (#40896) The original file proves the existence of limits and colimits in comma categories under suitable conditions, and prove that the forgetful functors from (co)structured arrows preserve (co)limits. This adds the specific instances for finite (co)limits. Co-authored-by: morel --- Mathlib/CategoryTheory/Limits/Comma.lean | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Mathlib/CategoryTheory/Limits/Comma.lean b/Mathlib/CategoryTheory/Limits/Comma.lean index 8d0549e47beef3..31172ac7aeb408 100644 --- a/Mathlib/CategoryTheory/Limits/Comma.lean +++ b/Mathlib/CategoryTheory/Limits/Comma.lean @@ -10,6 +10,8 @@ public import Mathlib.CategoryTheory.Comma.Over.Basic public import Mathlib.CategoryTheory.Limits.Constructions.EpiMono public import Mathlib.CategoryTheory.Limits.Creates public import Mathlib.CategoryTheory.Limits.Unit +public import Mathlib.CategoryTheory.Limits.Preserves.Finite +public import Mathlib.CategoryTheory.Limits.Preserves.Creates.Finite /-! # Limits and colimits in comma categories @@ -150,6 +152,10 @@ instance hasLimitsOfSize [HasLimitsOfSize.{w, w'} A] [HasLimitsOfSize.{w, w'} B] [PreservesLimitsOfSize.{w, w'} R] : HasLimitsOfSize.{w, w'} (Comma L R) := ⟨fun _ _ => inferInstance⟩ +instance hasFiniteLimits [HasFiniteLimits A] [HasFiniteLimits B] + [PreservesFiniteLimits R] : HasFiniteLimits (Comma L R) where + out _ _ _ := inferInstance + instance hasColimit (F : J ⥤ Comma L R) [HasColimit (F ⋙ fst L R)] [HasColimit (F ⋙ snd L R)] [PreservesColimit (F ⋙ fst L R) L] : HasColimit F := HasColimit.mk ⟨_, coconeOfPreservesIsColimit _ (colimit.isColimit _) (colimit.isColimit _)⟩ @@ -161,6 +167,10 @@ instance hasColimitsOfSize [HasColimitsOfSize.{w, w'} A] [HasColimitsOfSize.{w, [PreservesColimitsOfSize.{w, w'} L] : HasColimitsOfSize.{w, w'} (Comma L R) := ⟨fun _ _ => inferInstance⟩ +instance hasFiniteColimits [HasFiniteColimits A] [HasFiniteColimits B] + [PreservesFiniteColimits L] : HasFiniteColimits (Comma L R) where + out _ _ _ := inferInstance + instance preservesColimitsOfShape_fst [HasColimitsOfShape J A] [HasColimitsOfShape J B] [PreservesColimitsOfShape J L] : PreservesColimitsOfShape J (Comma.fst L R) where preservesColimit := @@ -188,6 +198,9 @@ instance hasLimit (F : J ⥤ Arrow T) [i₁ : HasLimit (F ⋙ leftFunc)] [i₂ : instance hasLimitsOfShape [HasLimitsOfShape J T] : HasLimitsOfShape J (Arrow T) where +instance hasFiniteLimits [HasFiniteLimits T] : HasFiniteLimits (Arrow T) where + out _ _ _ := inferInstance + instance hasLimits [HasLimits T] : HasLimits (Arrow T) := ⟨fun _ _ => inferInstance⟩ @@ -200,6 +213,9 @@ instance hasColimit (F : J ⥤ Arrow T) [i₁ : HasColimit (F ⋙ leftFunc)] instance hasColimitsOfShape [HasColimitsOfShape J T] : HasColimitsOfShape J (Arrow T) where +instance hasFiniteColimits [HasFiniteColimits T] : HasFiniteColimits (Arrow T) where + out _ _ _ := inferInstance + instance hasColimits [HasColimits T] : HasColimits (Arrow T) := ⟨fun _ _ => inferInstance⟩ @@ -230,6 +246,10 @@ instance hasLimit [i₁ : HasLimit (F ⋙ proj X G)] [i₂ : PreservesLimit (F instance hasLimitsOfShape [HasLimitsOfShape J A] [PreservesLimitsOfShape J G] : HasLimitsOfShape J (StructuredArrow X G) where +instance hasFiniteLimits [HasFiniteLimits A] [PreservesFiniteLimits G] : + HasFiniteLimits (StructuredArrow X G) where + out _ _ _ := inferInstance + instance hasLimitsOfSize [HasLimitsOfSize.{w, w'} A] [PreservesLimitsOfSize.{w, w'} G] : HasLimitsOfSize.{w, w'} (StructuredArrow X G) := ⟨fun J hJ => by infer_instance⟩ @@ -246,6 +266,10 @@ noncomputable instance createsLimit [i : PreservesLimit (F ⋙ proj X G) G] : noncomputable instance createsLimitsOfShape [PreservesLimitsOfShape J G] : CreatesLimitsOfShape J (proj X G) where +noncomputable instance createsFiniteLimits [PreservesFiniteLimits G] : + CreatesFiniteLimits (proj X G) where + createsFiniteLimits _ _ _ := inferInstance + noncomputable instance createsLimitsOfSize [PreservesLimitsOfSize.{w, w'} G] : CreatesLimitsOfSize.{w, w'} (proj X G :) where @@ -277,6 +301,10 @@ instance hasColimit [i₁ : HasColimit (F ⋙ proj G X)] [i₂ : PreservesColimi instance hasColimitsOfShape [HasColimitsOfShape J A] [PreservesColimitsOfShape J G] : HasColimitsOfShape J (CostructuredArrow G X) where +instance hasFiniteColimits [HasFiniteColimits A] [PreservesFiniteColimits G] : + HasFiniteColimits (CostructuredArrow G X) where + out _ _ _ := inferInstance + instance hasColimitsOfSize [HasColimitsOfSize.{w, w'} A] [PreservesColimitsOfSize.{w, w'} G] : HasColimitsOfSize.{w, w'} (CostructuredArrow G X) := ⟨fun _ _ => inferInstance⟩ @@ -293,6 +321,10 @@ noncomputable instance createsColimit [i : PreservesColimit (F ⋙ proj G X) G] noncomputable instance createsColimitsOfShape [PreservesColimitsOfShape J G] : CreatesColimitsOfShape J (proj G X) where +noncomputable instance createsFiniteColimits [PreservesFiniteColimits G] : + CreatesFiniteColimits (proj G X) where + createsFiniteColimits _ _ _ := inferInstance + noncomputable instance createsColimitsOfSize [PreservesColimitsOfSize.{w, w'} G] : CreatesColimitsOfSize.{w, w'} (proj G X :) where From e8f2bd8352aabd84e68ab2e392c68c9ac226931b Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:56:57 +0000 Subject: [PATCH 0261/1300] feat(IsGaloisGroup): add `restrictHom` (#38864) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds the restriction map for the Galois group for domains. Given a tower of domains `A ≤ B ≤ C`, `G` a Galois group for `C/A` and `G'` a Galois group for `B/A`, we define: - `restrictHom`: the restriction of the `G`-action on `C` to the `G'`-action on `B`. - `quotientMulEquiv`: the isomorphism between the quotient of `G` by the fixing subgroup of `B` and the Galois group of `B/A`. Supporting lemmas include: - `normal_of_isGalois`: if `G` is a finite Galois group for `L/K`, `H` is a Galois group for `L/E`, and `E/K` is Galois, then `H` is a normal subgroup of `G`. - `restrictHom_surjective`: the restriction map is surjective. --- - [x] depends on: #38902 - [x] depends on: #38464 - [x] depends on: #40804 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) Co-authored-by: Author Name Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 112 +++++++++++++++++- 1 file changed, 109 insertions(+), 3 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 1495a47a590cae..2fcbbed0106e1f 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -374,6 +374,11 @@ theorem mulEquivCongr_symm_apply_smul (g : G') (x : B) : @[deprecated (since := "2026-06-19")] alias mulEquivCongr' := mulEquivCongr @[deprecated (since := "2026-06-19")] alias mulEquivCongr'_apply_smul := mulEquivCongr_apply_smul +theorem mulEquivCongr_mapSubgroup_fixingSubgroup (S : Set B) : + (fixingSubgroup G S).map (mulEquivCongr G G' A B) = fixingSubgroup G' S := by + ext g + simp [Subgroup.map_equiv_eq_comap_symm, mem_fixingSubgroup_iff] + end IsDomain variable (H H' : Subgroup G) (F F' : IntermediateField K L) @@ -430,6 +435,17 @@ instance intermediateField [Finite G] [hGKL : IsGaloisGroup G K L] : have := hGKL.isGalois .of_mulEquiv_algEquiv e fun _ _ ↦ rfl +include K in +/-- If `G` is a Galois group on `L/K` and `L/E/K` is a tower of field extensions, +then the fixing subgroup of the image of `E` in `L` is a Galois group on `L/E`. -/ +theorem of_isScalarTower [Finite G] [IsGaloisGroup G K L] (E : Type*) [Field E] [Algebra K E] + [Algebra E L] [IsScalarTower K E L] : + IsGaloisGroup (fixingSubgroup G (Set.range (algebraMap E L))) E L := by + rw [← IsScalarTower.toAlgHom_fieldRange K E L] + refine IsGaloisGroup.of_ringEquiv _ _ _ L + (AlgHom.equivFieldRange (IsScalarTower.toAlgHom K E L)).toRingEquiv.symm fun ⟨_, ⟨x, rfl⟩⟩ ↦ ?_ + simp [AlgEquiv.symm_apply_eq, Subtype.ext_iff] + @[simp] theorem card_fixingSubgroup_eq_finrank [Finite G] [IsGaloisGroup G K L] : Nat.card (fixingSubgroup G (F : Set L)) = Module.finrank F L := @@ -566,6 +582,20 @@ theorem fixingSubgroup_range_algebraMap [Finite G] (A B C : Type*) (H : Subgroup use algebraMap B (FractionRing B) x rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply] +open Pointwise in +/-- If `G` is a finite Galois group for `L/K`, `H` is a Galois group for `L/E`, and `E/K` is +Galois, then `H` is a normal subgroup of `G`. -/ +theorem normal_of_isGalois (E : Type*) [Field E] [Algebra K E] [Algebra E L] [IsScalarTower K E L] + [Finite G] [IsGaloisGroup H E L] [IsGalois K E] : H.Normal := by + let F := (IsScalarTower.toAlgHom K E L).fieldRange + have : IsGalois K F := .of_algEquiv (IsScalarTower.toAlgHom K E L).equivFieldRange + have hFL : IsGaloisGroup H F L := inferInstanceAs (IsGaloisGroup H (algebraMap E L).range L) + have := isGalois G K L + have : Finite Gal(L/K) := Finite.of_equiv _ (mulEquivAlgEquiv G K L).toEquiv + rw [← fixingSubgroup_fixedPoints G K L H, subgroup_iff.mp hFL, + ← mulEquivCongr_mapSubgroup_fixingSubgroup Gal(L/K) G K, MulEquiv.normal_map_iff] + exact IsGalois.fixingSubgroup_normal_of_isGalois F + end IsGaloisGroup end GaloisCorrespondence @@ -635,7 +665,7 @@ theorem mulSemiringActionQuotient_smul_def [MulSemiringAction G B] [SMulDistribC refine (Quotient.liftOn'_mk'' (· • b) _ g).trans (FaithfulSMul.algebraMap_injective B C ?_) rw [algebraMap.smul', algebraMap.smul'] -theorem isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C] +instance isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C] [IsGaloisGroup N B C] [N.Normal] : letI := mulSemiringActionQuotient G B C N IsScalarTower G (G ⧸ N) B := @@ -659,7 +689,7 @@ end Semiring section Domain variable (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] [IsDomain C] [Algebra A B] - [Algebra A C] [Algebra B C] [FaithfulSMul A C] [FaithfulSMul B C] [IsScalarTower A B C] + [Algebra A C] [Algebra B C] [FaithfulSMul A B] [FaithfulSMul B C] [IsScalarTower A B C] /-- If `G` is a Galois group for `C/A`, and the normal subgroup `N ≤ G` is a Galois group for `C/B`, then the quotient `G ⧸ N` is a Galois group for `B/A`. -/ @@ -669,6 +699,7 @@ theorem quotient [Finite G] (N : Subgroup G) [N.Normal] [MulSemiringAction G C] [IsGaloisGroup N B C] : IsGaloisGroup (G ⧸ N) A B where faithful.eq_of_smul_eq_smul := fun {g₁} {g₂} ↦ Quotient.inductionOn₂' g₁ g₂ fun g₁ g₂ h ↦ by + have : FaithfulSMul A C := FaithfulSMul.trans A B C have h' : ∀ g : G, (∀ x : B, g • x = x) → g ∈ N := by simp [← fixingSubgroup_range_algebraMap G A B C N, mem_fixingSubgroup_iff, ← algebraMap.smul', (FaithfulSMul.algebraMap_injective B C).eq_iff] @@ -685,6 +716,80 @@ theorem quotient [Finite G] (N : Subgroup G) [N.Normal] [MulSemiringAction G C] have := (FaithfulSMul.algebraMap_injective B C).eq_iff.mpr <| h g rwa [MulAction.coe_quotient_smul, algebraMap.smul'] at this +/-- If `G` is a Galois group for `C/A`, the normal subgroup `N ≤ G` is a Galois group for `C/B`, +and `G'` is a Galois group for `B/A`, then `G ⧸ N ≃* G'`. -/ +noncomputable def quotientMulEquiv [Finite G] [Finite G'] (N : Subgroup G) [N.Normal] + [MulSemiringAction G C] [IsGaloisGroup G A C] [IsGaloisGroup N B C] [MulSemiringAction G' B] + [IsGaloisGroup G' A B] : + G ⧸ N ≃* G' := + haveI : IsDomain B := (FaithfulSMul.algebraMap_injective B C).isDomain + letI := mulSemiringActionOfNormal G B C N + letI := mulSemiringActionQuotient G B C N + haveI := smulCommClassQuotient G A B C N + haveI := quotient G A B C N + mulEquivCongr (G ⧸ N) G' A B + +@[simp] +theorem algebraMap_quotientMulEquiv_smul [Finite G] [Finite G'] (N : Subgroup G) [N.Normal] + [MulSemiringAction G C] [IsGaloisGroup G A C] [IsGaloisGroup N B C] [MulSemiringAction G' B] + [IsGaloisGroup G' A B] (g : G) (x : B) : + algebraMap B C (quotientMulEquiv G G' A B C N g • x) = g • algebraMap B C x := by + haveI : IsDomain B := (FaithfulSMul.algebraMap_injective B C).isDomain + letI := mulSemiringActionOfNormal G B C N + letI := mulSemiringActionQuotient G B C N + haveI := smulCommClassQuotient G A B C N + haveI := quotient G A B C N + rw [← algebraMap_smulOfNormal G B C N g x] + congr + apply mulEquivCongr_apply_smul + +attribute [local instance] FractionRing.liftAlgebra in +/-- The restriction homomorphism from the Galois group of `C/A` to the Galois group of `B/A` where +`C/B/A` is a tower of domains with `C/A` and `B/A` Galois. -/ +noncomputable def restrictHom [Finite G] [Finite G'] [MulSemiringAction G C] [IsGaloisGroup G A C] + [MulSemiringAction G' B] [IsGaloisGroup G' A B] : + G →* G' := + haveI : IsDomain B := IsDomain.of_faithfulSMul B C + haveI : IsDomain A := IsDomain.of_faithfulSMul A B + haveI : FaithfulSMul A C := FaithfulSMul.trans A B C + letI : MulSemiringAction G (FractionRing C) := + IsFractionRing.mulSemiringAction G C (FractionRing C) + letI N := fixingSubgroup G (Set.range (algebraMap (FractionRing B) (FractionRing C))) + haveI : IsGaloisGroup N (FractionRing B) (FractionRing C) := + of_isScalarTower G (FractionRing A) (FractionRing C) (FractionRing B) + letI : MulSemiringAction G' (FractionRing B) := + IsFractionRing.mulSemiringAction G' B (FractionRing B) + haveI := isGalois G' (FractionRing A) (FractionRing B) + haveI : N.Normal := normal_of_isGalois G (FractionRing A) (FractionRing C) N (FractionRing B) + (quotientMulEquiv G G' (FractionRing A) (FractionRing B) (FractionRing C) N).toMonoidHom.comp + (QuotientGroup.mk' N) + +attribute [local instance] FractionRing.liftAlgebra in +@[simp] +theorem algebraMap_restrictHom_smul [Finite G] [Finite G'] [MulSemiringAction G C] + [IsGaloisGroup G A C] [MulSemiringAction G' B] [IsGaloisGroup G' A B] (g : G) (x : B) : + algebraMap B C (restrictHom G G' A B C g • x) = g • algebraMap B C x := by + have : IsDomain B := IsDomain.of_faithfulSMul B C + have : IsDomain A := IsDomain.of_faithfulSMul A B + have : FaithfulSMul A C := FaithfulSMul.trans A B C + let : MulSemiringAction G (FractionRing C) := + IsFractionRing.mulSemiringAction G C (FractionRing C) + let : MulSemiringAction G' (FractionRing B) := + IsFractionRing.mulSemiringAction G' B (FractionRing B) + apply FaithfulSMul.algebraMap_injective C (FractionRing C) + rw [← IsScalarTower.algebraMap_apply, + IsScalarTower.algebraMap_apply B (FractionRing B) (FractionRing C)] + simp only [restrictHom, MulEquiv.toMonoidHom_eq_coe, MonoidHom.coe_comp, MonoidHom.coe_coe, + QuotientGroup.coe_mk', Function.comp_apply] + rw [algebraMap.smul', algebraMap_quotientMulEquiv_smul, ← IsScalarTower.algebraMap_apply, + algebraMap.smul', ← IsScalarTower.algebraMap_apply] + +attribute [local instance] FractionRing.liftAlgebra in +theorem restrictHom_surjective [Finite G] [Finite G'] [MulSemiringAction G C] + [IsGaloisGroup G A C] [MulSemiringAction G' B] [IsGaloisGroup G' A B] : + Function.Surjective (restrictHom G G' A B C) := by + simpa [restrictHom] using QuotientGroup.mk_surjective + end Domain noncomputable section IntermediateField @@ -733,7 +838,8 @@ theorem map_quotientMk' [Finite G] [IsGaloisGroup G K L] (h : E ≤ F) : isInvariant := ⟨fun x h ↦ by obtain ⟨a, ha⟩ := hE.isInvariant.isInvariant (algebraMap F L x) (by rintro ⟨g, hg⟩ - simpa only [← algebraMap.smul'] using! congr_arg (algebraMap F L) <| h ⟨g, ⟨g, hg, rfl⟩⟩) + rw [MulAction.subgroup_smul_def, ← algebraMap.smul'] + exact congr_arg (algebraMap F L) <| h ⟨g, ⟨g, hg, rfl⟩⟩) exact ⟨a, FaithfulSMul.algebraMap_injective F L (by rw [← IsScalarTower.algebraMap_apply, ha])⟩⟩ } From 85304ddf62264970fa4a289febc5b9ee02515760 Mon Sep 17 00:00:00 2001 From: Miguel Laredo <160270434+laredo02@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:57:00 +0000 Subject: [PATCH 0262/1300] feat(FinitelyPresentedGroup): quotient of a finitely group by a subgroup which is finitely generated under normal closure is finitely presented (#40845) Add theorem that the quotient of a finitely presented group by a subgroup whose normal closure is finitely generated is finitely presented. #38930 Also add docstring and `@[to_additive]` annotation to `of_surjective`. Co-authored-by: Hang Lu Su --- Mathlib/GroupTheory/FinitelyPresentedGroup.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean index 57f0f1f6729ce7..c72f4d89cfe415 100644 --- a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean +++ b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean @@ -103,6 +103,10 @@ theorem equiv (iso : G ≃* H) [h : IsFinitelyPresented G] : IsFinitelyPresented refine ⟨n, (iso : G →* H).comp φ, iso.surjective.comp hφsurj, ?_⟩ rwa [φ.ker_mulEquiv_comp iso] +/-- The image of a finitely presented group under a surjective homomorphism whose kernel is +finitely generated as a normal subgroup is finitely presented. -/ +@[to_additive /-- The image of a finitely presented additive group under a surjective additive +homomorphism whose kernel is finitely generated as a normal subgroup is finitely presented. -/] theorem of_surjective [hG : IsFinitelyPresented G] (f : G →* H) (hf_surj : Function.Surjective f) (hf_ker : f.ker.IsNormalClosureFG) : IsFinitelyPresented H := by @@ -111,6 +115,15 @@ theorem of_surjective [hG : IsFinitelyPresented G] (f : G →* H) rw [← MonoidHom.comap_ker] exact hf_ker.comap hφ_surj hφ_ker +/-- The quotient of a finitely presented group by a subgroup +which is finitely generated as a normal subgroup is finitely presented. -/ +@[to_additive /-- The quotient of a finitely presented additive group by an additive subgroup +which is finitely generated as a normal subgroup is finitely presented. -/] +theorem quotient [hG : IsFinitelyPresented G] (N : Subgroup G) [N.Normal] + (hN : N.IsNormalClosureFG) : IsFinitelyPresented (G ⧸ N) := + of_surjective (QuotientGroup.mk' N) (QuotientGroup.mk'_surjective N) + ((QuotientGroup.ker_mk' N).symm ▸ hN) + open QuotientGroup in theorem exists_mulEquiv_presentedGroup [hg : IsFinitelyPresented G] : ∃ n : ℕ, ∃ s : Set (FreeGroup (Fin n)), Set.Finite s ∧ Nonempty (G ≃* PresentedGroup s) := by From e568743e9c24da15c8f8347a47931d2a6c33ff85 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:57:04 +0000 Subject: [PATCH 0263/1300] chore(GroupTheory/FreeGroup): golf proof using autogenerated lemma (#40902) I forgot to add this in #40657 apparently. It seems like we don't need this lemma anyways; but thats beyond the scope of this PR. Co-authored-by: Batixx --- Mathlib/GroupTheory/FreeGroup/Basic.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 3a4a00e0b12b57..caf6340f835d4e 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -332,15 +332,13 @@ protected theorem sublist : Red L₁ L₂ → L₂ <+ L₁ := theorem length_le (h : Red L₁ L₂) : L₂.length ≤ L₁.length := h.sublist.length_le -set_option linter.auxLemma false in @[to_additive (attr := deprecated "Should not be needed." (since := "2026-04-10"))] theorem sizeof_of_step : ∀ {L₁ L₂ : List (α × Bool)}, Step L₁ L₂ → sizeOf L₂ < sizeOf L₁ | _, _, @Step.not _ L1 L2 x b => by induction L1 with | nil => - -- This was just `dsimp` prior to https://github.com/leanprover/lean4/pull/13320 - dsimp [sizeOf, _sizeOf_1] + rw [nil_append, nil_append, cons.sizeOf_spec, cons.sizeOf_spec] lia | cons hd tl ih => dsimp From eeee79132332bd6cb594939667e6ca07b55284a5 Mon Sep 17 00:00:00 2001 From: Andrew Yang <36414270+erdOne@users.noreply.github.com> Date: Mon, 22 Jun 2026 17:30:54 +0000 Subject: [PATCH 0264/1300] feat(Topology): sheaves of modules in `Over U` (#36142) --- Mathlib.lean | 1 + Mathlib/CategoryTheory/Sites/Spaces.lean | 3 + Mathlib/Topology/Sheaves/Module.lean | 50 ++++++++++++++++ Mathlib/Topology/Sheaves/Over.lean | 59 ++++++++++++++++--- .../Sheaves/SheafCondition/Sites.lean | 9 +++ 5 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 Mathlib/Topology/Sheaves/Module.lean diff --git a/Mathlib.lean b/Mathlib.lean index 52a90964f54ae6..e172db56965dbd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -8105,6 +8105,7 @@ public import Mathlib.Topology.Sheaves.Limits public import Mathlib.Topology.Sheaves.LocalPredicate public import Mathlib.Topology.Sheaves.LocallySurjective public import Mathlib.Topology.Sheaves.MayerVietoris +public import Mathlib.Topology.Sheaves.Module public import Mathlib.Topology.Sheaves.Over public import Mathlib.Topology.Sheaves.PUnit public import Mathlib.Topology.Sheaves.Points diff --git a/Mathlib/CategoryTheory/Sites/Spaces.lean b/Mathlib/CategoryTheory/Sites/Spaces.lean index 9f424a1beef31f..364e392890809d 100644 --- a/Mathlib/CategoryTheory/Sites/Spaces.lean +++ b/Mathlib/CategoryTheory/Sites/Spaces.lean @@ -57,6 +57,9 @@ def grothendieckTopology : GrothendieckTopology (Opens T) where rcases hR hf _ hU with ⟨V, g, hg, hV⟩ exact ⟨_, g ≫ f, hg, hV⟩ +lemma mem_grothendieckTopology {U : Opens T} {S : Sieve U} : + S ∈ Opens.grothendieckTopology T U ↔ ∀ x ∈ U, ∃ (V : _) (f : V ⟶ U), S f ∧ x ∈ V := .rfl + /-- The Grothendieck pretopology associated to a topological space. -/ def pretopology : Pretopology (Opens T) where coverings X := {R | ∀ x ∈ X, ∃ (U : _) (f : U ⟶ X), R f ∧ x ∈ U} diff --git a/Mathlib/Topology/Sheaves/Module.lean b/Mathlib/Topology/Sheaves/Module.lean new file mode 100644 index 00000000000000..4e7f8a2f554a7c --- /dev/null +++ b/Mathlib/Topology/Sheaves/Module.lean @@ -0,0 +1,50 @@ +/- +Copyright (c) 2026 Andrew Yang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Andrew Yang +-/ +module + +public import Mathlib.Algebra.Category.ModuleCat.Sheaf.PushforwardContinuous +public import Mathlib.Algebra.Category.Ring.Limits +public import Mathlib.Topology.Sheaves.Over +public import Mathlib.Topology.Sheaves.SheafCondition.Sites + +/-! # Specialized results for sheaves of modules over topological spaces -/ + +@[expose] public section + +noncomputable section + +open CategoryTheory + +universe w v u + +namespace TopologicalSpace.Opens + +variable {X : TopCat.{u}} (U : Opens X) (R : X.Sheaf RingCat.{v}) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- Sheaves of modules over `R.over U` are equivalent to sheaves of modules over `R |_ U`. -/ +def sheafOfModulesEquivOver : + SheafOfModules.{w} (R.over U) ≌ SheafOfModules.{w} (U.sheafRestrict.obj R) := by + refine SheafOfModules.pushforwardPushforwardEquivalence (eqv := U.overEquivalence.symm) + (U.overPullbackSheafEquivOver.app _).inv (U.sheafRestrictSheafEquivOver.app _).inv rfl ?_ + ext : 2 + simp [overPullbackSheafEquivOver, sheafRestrictSheafEquivOver, eqToHom_map, overEquivalence, + IsOpenMap.functor] + +/-- `sheafOfModulesEquivOver` takes `R.over U` to `R |_ U`. -/ +def sheafOfModulesEquivOverUnit (R : X.Sheaf RingCat.{u}) : + (U.sheafOfModulesEquivOver R).functor.obj (SheafOfModules.unit.{u} _) ≅ + SheafOfModules.unit.{u} _ := .refl _ + +/-- `sheafOfModulesEquivOver.inverse` takes `R |_ U` to `R.over U`. -/ +def sheafOfModulesEquivOverInverseUnit (R : X.Sheaf RingCat.{u}) : + (U.sheafOfModulesEquivOver R).inverse.obj (SheafOfModules.unit.{u} _) ≅ + SheafOfModules.unit.{u} _ := + (U.sheafOfModulesEquivOver R).inverse.mapIso (U.sheafOfModulesEquivOverUnit R).symm ≪≫ + ((U.sheafOfModulesEquivOver R).unitIso.app _).symm + +end TopologicalSpace.Opens diff --git a/Mathlib/Topology/Sheaves/Over.lean b/Mathlib/Topology/Sheaves/Over.lean index 9979a573d2427b..b8e74aa67472db 100644 --- a/Mathlib/Topology/Sheaves/Over.lean +++ b/Mathlib/Topology/Sheaves/Over.lean @@ -5,8 +5,10 @@ Authors: Joël Riou -/ module -public import Mathlib.Topology.Sets.Opens public import Mathlib.CategoryTheory.Comma.Over.Basic +public import Mathlib.CategoryTheory.Sites.Over +public import Mathlib.Topology.Sets.Opens +public import Mathlib.Topology.Sheaves.SheafCondition.Sites /-! # Opens and Over categories @@ -15,11 +17,7 @@ In this file, given a topological space `X`, and `U : Opens X`, we show that the category `Over U` (whose objects are the `V : Opens X` equipped with a morphism `V ⟶ U`) is equivalent to the category `Opens U`. - -## TODO -* show that both functors of the equivalence `overEquivalence U` are continuous and - induce an equivalence between `Sheaf ((Opens.grothendieckTopology X).over U) A` - and `Sheaf (Opens.grothendieckTopology U) A` for any category `A`. +This equivalence is bi-continuous, and thus induces an equivalence of sheaf categories. -/ @@ -31,7 +29,7 @@ open CategoryTheory Topology namespace TopologicalSpace -variable {X : Type u} [TopologicalSpace X] (U : Opens X) +variable {X : Type u} [TopologicalSpace X] (U : Opens X) {A : Type*} [Category* A] namespace Opens @@ -54,6 +52,53 @@ def overEquivalence : Over U ≌ Opens ↥U where apply leOfHom V.hom))) counitIso := NatIso.ofComponents (fun V ↦ eqToIso (by aesop)) +variable {U} in +@[simp] lemma mem_overEquivalence_functor_obj {V : Over U} {x : U} : + x ∈ U.overEquivalence.functor.obj V ↔ x.1 ∈ V.left := .rfl + +section grothendieckTopology + +instance : U.overEquivalence.functor.IsDenseSubsite + ((Opens.grothendieckTopology X).over U) (Opens.grothendieckTopology U) where + functorPushforward_mem_iff {V S} := by + simp only [Opens.mem_grothendieckTopology, Sieve.mem_functorPushforward_functor] + constructor + · intro H x hxV + obtain ⟨W, f, hW, hxW⟩ := H ⟨x, V.hom.le hxV⟩ hxV + exact ⟨_, ((U.overEquivalence.symm.toAdjunction.homEquiv _ _ ).symm f).left, + ⟨_, _, 𝟙 _, hW, rfl⟩, _, hxW, rfl⟩ + · intro H x hxV + obtain ⟨W, f, ⟨W', hW'V, hWW', hSW'V, rfl⟩, hxW⟩ := H x hxV + exact ⟨_, U.overEquivalence.functor.map hW'V, + S.downward_closed hSW'V (U.overEquivalence.unitInv.app W'), hWW'.le hxW⟩ + +instance : U.overEquivalence.symm.inverse.IsDenseSubsite + ((Opens.grothendieckTopology X).over U) (Opens.grothendieckTopology U) := + inferInstanceAs (U.overEquivalence.functor.IsDenseSubsite ..) + +instance : U.overEquivalence.inverse.IsDenseSubsite + (Opens.grothendieckTopology U) ((Opens.grothendieckTopology X).over U) := + inferInstanceAs (U.overEquivalence.symm.functor.IsDenseSubsite ..) + +/-- Sheaves on the over category of `U` are equivalent to sheaves on `U` as a topological space. -/ +@[simps!] def sheafEquivOver : + Sheaf ((Opens.grothendieckTopology X).over U) A ≌ Sheaf (Opens.grothendieckTopology U) A := + U.overEquivalence.sheafCongr + ((Opens.grothendieckTopology X).over U) (Opens.grothendieckTopology U) A + +/-- `overPullback` and `sheafRestrict` are isomorphic under `sheafEquivOver`. -/ +def overPullbackSheafEquivOver {X : TopCat} (U : Opens X) : + (Opens.grothendieckTopology X).overPullback A U ⋙ U.sheafEquivOver.functor ≅ + U.sheafRestrict := .refl _ + +/-- `overPullback` and `sheafRestrict` are isomorphic under `sheafEquivOver`. -/ +def sheafRestrictSheafEquivOver {X : TopCat} (U : Opens X) : + U.sheafRestrict ⋙ U.sheafEquivOver.inverse ≅ + (Opens.grothendieckTopology X).overPullback A U := + U.overPullbackSheafEquivOver.isoCompInverse.symm + +end grothendieckTopology + end Opens end TopologicalSpace diff --git a/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean b/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean index 117ca1339f2113..392e27c8a3faf4 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean @@ -174,6 +174,15 @@ theorem TopCat.Presheaf.isSheaf_of_isOpenEmbedding (h : IsOpenEmbedding f) (hF : have := h.functor_isContinuous exact Functor.op_comp_isSheaf _ _ _ ⟨_, hF⟩ +/-- The restriction functor of a sheaf to an open subspace. -/ +@[simps!] +def TopologicalSpace.Opens.sheafRestrict (U : Opens X) : + Sheaf (Opens.grothendieckTopology X) C ⥤ Sheaf (Opens.grothendieckTopology U) C := + haveI H : IsOpenEmbedding (TopCat.Hom.hom (TopCat.ofHom ⟨_, continuous_subtype_val⟩)) := + U.isOpenEmbedding + haveI := H.functor_isContinuous + H.isOpenMap.functor.sheafPushforwardContinuous C _ _ + variable (f) instance : RepresentablyFlat (Opens.map f) := by From b1e3b32001fca01c651effea67312978aa30e5c7 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Mon, 22 Jun 2026 17:30:57 +0000 Subject: [PATCH 0265/1300] feat: a few misc results about open (quotient) maps (#40715) In particular, we upgrade `IsOpen[Quotient]Map.prodMap` to an `iff` when both factors are nonempty. --- Mathlib/Topology/Constructions/SumProd.lean | 38 +++++++++++++++++++-- Mathlib/Topology/Homeomorph/Defs.lean | 16 ++++++++- Mathlib/Topology/Maps/Basic.lean | 6 ++++ Mathlib/Topology/Maps/OpenQuotient.lean | 13 +++++++ 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index ab4185bf312be4..4bfea412958fbd 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -6,7 +6,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Patrick Massot module public import Mathlib.Topology.Homeomorph.Defs -public import Mathlib.Topology.Maps.Basic +public import Mathlib.Topology.Maps.OpenQuotient public import Mathlib.Topology.Separation.SeparatedNhds /-! @@ -358,6 +358,16 @@ theorem ContinuousAt.prodMap' {f : X → Z} {g : Y → W} {x : X} {y : Y} (hf : (hg : ContinuousAt g y) : ContinuousAt (Prod.map f g) (x, y) := hf.prodMap hg +@[simp] +theorem continuousAt_prodMap_iff {f : X → Z} {g : Y → W} {x : X} {y : Y} : + ContinuousAt (Prod.map f g) (x, y) ↔ ContinuousAt f x ∧ ContinuousAt g y := by + simp [ContinuousAt, nhds_prod_eq, tendsto_iff_comap, comap_prodMap_prod] + +@[simp] +theorem continuous_prodMap_iff [Nonempty Z] [Nonempty W] {f : Z → X} {g : W → Y} : + Continuous (Prod.map f g) ↔ Continuous f ∧ Continuous g := by + simp [continuous_iff_continuousAt, forall_and] + theorem ContinuousAt.comp₂ {f : Y × Z → W} {g : X → Y} {h : X → Z} {x : X} (hf : ContinuousAt f (g x, h x)) (hg : ContinuousAt g x) (hh : ContinuousAt h x) : ContinuousAt (fun x ↦ f (g x, h x)) x := @@ -494,11 +504,17 @@ theorem isOpen_prod_iff' {s : Set X} {t : Set Y} : simp only [st.1.ne_empty, st.2.ne_empty, or_false] at H exact H.1.prod H.2 +theorem isOpenQuotientMap_fst [Nonempty Y] : IsOpenQuotientMap (Prod.fst : X × Y → X) := + ⟨Prod.fst_surjective, continuous_fst, isOpenMap_fst⟩ + +theorem isOpenQuotientMap_snd [Nonempty X] : IsOpenQuotientMap (Prod.snd : X × Y → Y) := + ⟨Prod.snd_surjective, continuous_snd, isOpenMap_snd⟩ + theorem isQuotientMap_fst [Nonempty Y] : IsQuotientMap (Prod.fst : X × Y → X) := - isOpenMap_fst.isQuotientMap continuous_fst Prod.fst_surjective + isOpenQuotientMap_fst.isQuotientMap theorem isQuotientMap_snd [Nonempty X] : IsQuotientMap (Prod.snd : X × Y → Y) := - isOpenMap_snd.isQuotientMap continuous_snd Prod.snd_surjective + isOpenQuotientMap_snd.isQuotientMap theorem closure_prod_eq {s : Set X} {t : Set Y} : closure (s ×ˢ t) = closure s ×ˢ closure t := ext fun ⟨a, b⟩ => by @@ -589,6 +605,15 @@ protected theorem IsOpenMap.prodMap {f : X → Y} {g : Z → W} (hf : IsOpenMap rw [nhds_prod_eq, nhds_prod_eq, ← Filter.prod_map_map_eq'] exact Filter.prod_mono (hf.nhds_le a) (hg.nhds_le b) +@[simp] +theorem isOpenMap_prodMap_iff [Nonempty X] [Nonempty Z] {f : X → Y} {g : Z → W} : + IsOpenMap (Prod.map f g) ↔ IsOpenMap f ∧ IsOpenMap g := by + refine ⟨fun h ↦ ⟨?_, ?_⟩, fun ⟨hf, hg⟩ ↦ hf.prodMap hg⟩ + · rw [(isOpenQuotientMap_fst (Y := Z)).isOpenMap_iff] + exact isOpenMap_fst.comp h + · rw [(isOpenQuotientMap_snd (X := X)).isOpenMap_iff] + exact isOpenMap_snd.comp h + protected lemma Topology.IsOpenEmbedding.prodMap {f : X → Y} {g : Z → W} (hf : IsOpenEmbedding f) (hg : IsOpenEmbedding g) : IsOpenEmbedding (Prod.map f g) := .of_isEmbedding_isOpenMap (hf.1.prodMap hg.1) (hf.isOpenMap.prodMap hg.isOpenMap) @@ -612,6 +637,13 @@ theorem IsOpenQuotientMap.prodMap {f : X → Y} {g : Z → W} (hf : IsOpenQuotie (hg : IsOpenQuotientMap g) : IsOpenQuotientMap (Prod.map f g) := ⟨.prodMap hf.1 hg.1, .prodMap hf.2 hg.2, .prodMap hf.3 hg.3⟩ +@[simp] +theorem isOpenQuotientMap_prodMap_iff [Nonempty X] [Nonempty Z] {f : X → Y} {g : Z → W} : + IsOpenQuotientMap (Prod.map f g) ↔ IsOpenQuotientMap f ∧ IsOpenQuotientMap g := by + have : Nonempty Y := .map f inferInstance + have : Nonempty W := .map g inferInstance + grind [isOpenQuotientMap_iff, continuous_prodMap_iff, isOpenMap_prodMap_iff, Prod.map_surjective] + theorem TopologicalSpace.prod_mono {α β : Type*} {σ₁ σ₂ : TopologicalSpace α} {τ₁ τ₂ : TopologicalSpace β} (hσ : σ₁ ≤ σ₂) (hτ : τ₁ ≤ τ₂) : @instTopologicalSpaceProd α β σ₁ τ₁ ≤ @instTopologicalSpaceProd α β σ₂ τ₂ := diff --git a/Mathlib/Topology/Homeomorph/Defs.lean b/Mathlib/Topology/Homeomorph/Defs.lean index 79ccff73ceae30..2833bea0f96d53 100644 --- a/Mathlib/Topology/Homeomorph/Defs.lean +++ b/Mathlib/Topology/Homeomorph/Defs.lean @@ -6,7 +6,7 @@ Authors: Johannes Hölzl, Patrick Massot, Sébastien Gouëzel, Zhouhang Zhou, Re module public import Mathlib.Topology.ContinuousMap.Defs -public import Mathlib.Topology.Maps.Basic +public import Mathlib.Topology.Maps.OpenQuotient /-! # Homeomorphisms @@ -342,6 +342,20 @@ theorem comp_isOpenMap_iff' (h : X ≃ₜ Y) {f : Y → Z} : IsOpenMap (f ∘ h) rw [← Function.comp_id f, ← h.self_comp_symm, ← Function.comp_assoc] exact hf.comp h.symm.isOpenMap +/-- Open quotient maps are preserved by precomposing with a homeomorphism. -/ +@[simp] +theorem isOpenQuotient_comp_iff (e : X ≃ₜ Y) {f : Y → Z} : + IsOpenQuotientMap (f ∘ e) ↔ IsOpenQuotientMap f := + ⟨fun h ↦ by simpa [Function.comp_assoc] using h.comp e.symm.isOpenQuotientMap, + fun hf ↦ hf.comp e.isOpenQuotientMap⟩ + +/-- Open quotient maps are preserved by postcomposing with a homeomorphism. -/ +@[simp] +theorem comp_isOpenQuotientMap_iff (e : Y ≃ₜ Z) {f : X → Y} : + IsOpenQuotientMap (e ∘ f) ↔ IsOpenQuotientMap f := + ⟨fun h ↦ by simpa [← Function.comp_assoc] using e.symm.isOpenQuotientMap.comp h, + fun hf ↦ e.isOpenQuotientMap.comp hf⟩ + variable (X Y) in /-- If both `X` and `Y` have a unique element, then `X ≃ₜ Y`. -/ @[simps!] diff --git a/Mathlib/Topology/Maps/Basic.lean b/Mathlib/Topology/Maps/Basic.lean index c5f7c9ca50bb24..4efc1e7e0b3e4e 100644 --- a/Mathlib/Topology/Maps/Basic.lean +++ b/Mathlib/Topology/Maps/Basic.lean @@ -369,6 +369,12 @@ protected theorem id : IsOpenMap (@id X) := fun s hs => by rwa [image_id] protected theorem comp (hg : IsOpenMap g) (hf : IsOpenMap f) : IsOpenMap (g ∘ f) := fun s hs => by rw [image_comp]; exact hg _ (hf _ hs) +/-- If `g ∘ f` is open, where `f` is continuous and surjective, then `g` is open. -/ +theorem of_comp (hf : Continuous f) (f_surj : Surjective f) (h : IsOpenMap (g ∘ f)) : + IsOpenMap g := fun s hs => by + rw [← f_surj.image_preimage s, ← image_comp] + exact h _ (hs.preimage hf) + theorem isOpen_range (hf : IsOpenMap f) : IsOpen (range f) := by rw [← image_univ] exact hf _ isOpen_univ diff --git a/Mathlib/Topology/Maps/OpenQuotient.lean b/Mathlib/Topology/Maps/OpenQuotient.lean index be2ce3cb93e7f3..139d7c8ec14f05 100644 --- a/Mathlib/Topology/Maps/OpenQuotient.lean +++ b/Mathlib/Topology/Maps/OpenQuotient.lean @@ -49,6 +49,15 @@ theorem comp {g : Y → Z} (hg : IsOpenQuotientMap g) (hf : IsOpenQuotientMap f) IsOpenQuotientMap (g ∘ f) := ⟨.comp hg.1 hf.1, .comp hg.2 hf.2, .comp hg.3 hf.3⟩ +theorem of_comp {g : Y → Z} (hf : Continuous f) (f_surj : Surjective f) (hg : Continuous g) + (h : IsOpenQuotientMap (g ∘ f)) : IsOpenQuotientMap g := + ⟨.of_comp h.surjective, hg, .of_comp hf f_surj h.isOpenMap ⟩ + +theorem of_comp_iff {g : Y → Z} (hf : IsOpenQuotientMap f) : + IsOpenQuotientMap (g ∘ f) ↔ IsOpenQuotientMap g := + ⟨fun h ↦ .of_comp hf.continuous hf.surjective + (hf.isQuotientMap.continuous_iff.mpr h.continuous) h, fun hg ↦ hg.comp hf⟩ + theorem map_nhds_eq (h : IsOpenQuotientMap f) (x : X) : map f (𝓝 x) = 𝓝 (f x) := le_antisymm h.continuous.continuousAt <| h.isOpenMap.nhds_le _ @@ -60,6 +69,10 @@ theorem continuousAt_comp_iff (h : IsOpenQuotientMap f) {g : Y → Z} {x : X} : ContinuousAt (g ∘ f) x ↔ ContinuousAt g (f x) := by simp only [ContinuousAt, ← h.map_nhds_eq, tendsto_map'_iff, comp_def] +theorem isOpenMap_iff (hf : IsOpenQuotientMap f) {g : Y → Z} : + IsOpenMap g ↔ IsOpenMap (g ∘ f) := + ⟨fun hg ↦ hg.comp hf.isOpenMap, fun h ↦ .of_comp hf.continuous hf.surjective h⟩ + theorem dense_preimage_iff (h : IsOpenQuotientMap f) {s : Set Y} : Dense (f ⁻¹' s) ↔ Dense s := ⟨fun hs ↦ h.surjective.denseRange.dense_of_mapsTo h.continuous hs (mapsTo_preimage _ _), fun hs ↦ hs.preimage h.isOpenMap⟩ From f07d1202849c903e71038bb3ba91662694a43414 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 22 Jun 2026 18:03:39 +0000 Subject: [PATCH 0266/1300] chore(CategoryTheory/Comma/Arrow): use `to_dual` (#40862) This PR uses `to_dual` to dualize the `Arrow` category. Theorems `isIso_of_isIso` and `isIso_of_isIso'` did not have a dual, and had stronger iff forms, and weren't used, so I decided to remove them (or mark private). I skipped the parts involving `eqToHom`, since `eqToHom` hasn't been tagged with `to_dual` yet. --- Mathlib/CategoryTheory/Comma/Arrow.lean | 146 ++++++++++++------------ 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/Mathlib/CategoryTheory/Comma/Arrow.lean b/Mathlib/CategoryTheory/Comma/Arrow.lean index 767eae2fdee3b1..62ee97723e7a57 100644 --- a/Mathlib/CategoryTheory/Comma/Arrow.lean +++ b/Mathlib/CategoryTheory/Comma/Arrow.lean @@ -33,7 +33,10 @@ variable (T) in squares in `T`. -/ def Arrow := Comma (𝟭 T) (𝟭 T) +to_dual_name_hint Left Right + /-- The type of morphisms in the category `Arrow T`. -/ +@[to_dual self (reorder := f g)] protected def Arrow.Hom (f g : Arrow T) := CommaMorphism f g instance : Quiver (Arrow T) where @@ -45,43 +48,31 @@ instance : Category (Arrow T) := namespace Arrow /-- The left object of an arrow. -/ +@[to_dual /-- The right object of an arrow. -/] abbrev left (X : Arrow T) : T := Comma.left X -/-- The right object of an arrow. -/ -abbrev right (X : Arrow T) : T := Comma.right X - /-- Given `X : Arrow T`, this is the morphism `X.left ⟶ X.right`. -/ abbrev hom (X : Arrow T) : X.left ⟶ X.right := Comma.hom X /-- The left part of a morphism in the category of arrows. -/ +@[to_dual /-- The right part of a morphism in the category of arrows. -/] abbrev Hom.left {X Y : Arrow T} (f : X ⟶ Y) : X.left ⟶ Y.left := CommaMorphism.left f -/-- The right part of a morphism in the category of arrows. -/ -abbrev Hom.right {X Y : Arrow T} (f : X ⟶ Y) : X.right ⟶ Y.right := CommaMorphism.right f - -@[ext] +@[ext, to_dual self (reorder := X Y, h₁ h₂)] lemma hom_ext {X Y : Arrow T} (f g : X ⟶ Y) (h₁ : f.left = g.left) (h₂ : f.right = g.right) : f = g := CommaMorphism.ext h₁ h₂ -@[simp] +@[to_dual (attr := simp)] theorem id_left (f : Arrow T) : Arrow.Hom.left (𝟙 f) = 𝟙 f.left := rfl -@[simp] -theorem id_right (f : Arrow T) : Arrow.Hom.right (𝟙 f) = 𝟙 f.right := - rfl - -@[simp, reassoc] +@[to_dual (reorder := f g) (attr := simp, reassoc)] theorem comp_left {X Y Z : Arrow T} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).left = f.left ≫ g.left := rfl -@[simp, reassoc] -theorem comp_right {X Y Z : Arrow T} (f : X ⟶ Y) (g : Y ⟶ Z) : - (f ≫ g).right = f.right ≫ g.right := rfl - /-- An object in the arrow category is simply a morphism in `T`. -/ -@[simps] +@[simps, to_dual self] def mk {X Y : T} (f : X ⟶ Y) : Arrow T where left := X right := Y @@ -92,38 +83,41 @@ theorem mk_eq (f : Arrow T) : Arrow.mk f.hom = f := by cases f rfl +@[to_dual none] lemma mk_surjective (f : Arrow T) : ∃ (X Y : T) (g : X ⟶ Y), f = Arrow.mk g := ⟨_, _, f.hom, rfl⟩ +@[to_dual self] theorem mk_injective (A B : T) : Function.Injective (Arrow.mk : (A ⟶ B) → Arrow T) := fun f g h => by cases h rfl +@[to_dual self] theorem mk_inj (A B : T) {f g : A ⟶ B} : Arrow.mk f = Arrow.mk g ↔ f = g := (mk_injective A B).eq_iff +@[to_dual self] instance {X Y : T} : CoeOut (X ⟶ Y) (Arrow T) where coe := mk -@[reassoc (attr := simp high)] +@[to_dual none, reassoc (attr := simp high)] theorem w {f g : Arrow T} (sq : f ⟶ g) : sq.left ≫ g.hom = f.hom ≫ sq.right := CommaMorphism.w sq -@[reassoc] -lemma Hom.w {f g : Arrow T} (sq : f ⟶ g) : sq.left ≫ g.hom = f.hom ≫ sq.right := by - simp +@[to_dual none, reassoc] +alias Hom.w := w +@[to_dual] theorem hom.congr_left {f g : Arrow T} {φ₁ φ₂ : f ⟶ g} (h : φ₁ = φ₂) : φ₁.left = φ₂.left := by rw [h] -theorem hom.congr_right {f g : Arrow T} {φ₁ φ₂ : f ⟶ g} (h : φ₁ = φ₂) : φ₁.right = φ₂.right := by - simp [h] - +@[to_dual none] theorem iso_w {f g : Arrow T} (e : f ≅ g) : g.hom = e.inv.left ≫ f.hom ≫ e.hom.right := by simp [← Arrow.comp_right] +@[to_dual none] theorem iso_w' {W X Y Z : T} {f : W ⟶ X} {g : Y ⟶ Z} (e : Arrow.mk f ≅ Arrow.mk g) : g = e.inv.left ≫ f ≫ e.hom.right := iso_w e @@ -171,6 +165,14 @@ def homMk {f g : Arrow T} (u : f.left ⟶ g.left) (v : f.right ⟶ g.right) right := v w := w +/-- `homMk''` is the dual of `homMk`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing homMk] +abbrev homMk'' {f g : Arrow T} (u : g.right ⟶ f.right) (v : g.left ⟶ f.left) + (w : g.hom ≫ u = v ≫ f.hom := by cat_disch) : g ⟶ f := + homMk v u +attribute [to_dual none] homMk_left homMk_right + /-- We can also build a morphism in the arrow category out of any commutative square in `T`. -/ @[simps] def homMk' {X Y : T} {f : X ⟶ Y} {P Q : T} {g : P ⟶ Q} (u : X ⟶ P) (v : Y ⟶ Q) @@ -180,24 +182,33 @@ def homMk' {X Y : T} {f : X ⟶ Y} {P Q : T} {g : P ⟶ Q} (u : X ⟶ P) (v : Y right := v w := w +/-- `homMk'''` is the dual of `homMk'`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing homMk'] +abbrev homMk''' {X Y : T} {f : Y ⟶ X} {P Q : T} {g : Q ⟶ P} (u : P ⟶ X) (v : Q ⟶ Y) + (w : g ≫ u = v ≫ f := by cat_disch) : mk g ⟶ mk f := + homMk' v u +attribute [to_dual none] homMk'_left + set_option backward.defeqAttrib.useBackward true in -@[reassoc] +@[to_dual none, reassoc] theorem w_mk_left {X Y : T} {f : X ⟶ Y} {g : Arrow T} (sq : mk f ⟶ g) : dsimp% sq.left ≫ g.hom = f ≫ sq.right := sq.w set_option backward.defeqAttrib.useBackward true in -@[reassoc (attr := simp)] +@[to_dual none, reassoc (attr := simp)] theorem w_mk_right {f : Arrow T} {X Y : T} {g : X ⟶ Y} (sq : f ⟶ mk g) : dsimp% sq.left ≫ g = f.hom ≫ sq.right := sq.w set_option backward.defeqAttrib.useBackward true in -@[reassoc] +@[to_dual none, reassoc] theorem w_mk {X Y X' Y' : T} {f : X ⟶ Y} {g : X' ⟶ Y'} (sq : mk f ⟶ mk g) : dsimp% sq.left ≫ g = f ≫ sq.right := sq.w +@[to_dual self (reorder := f g, 6 7)] theorem isIso_of_isIso_left_of_isIso_right {f g : Arrow T} (ff : f ⟶ g) [IsIso ff.left] [IsIso ff.right] : IsIso ff where out := ⟨homMk (inv ff.left) (inv ff.right), by cat_disch⟩ @@ -210,59 +221,70 @@ def isoMk {f g : Arrow T} (l : f.left ≅ g.left) (r : f.right ≅ g.right) (h : l.hom ≫ g.hom = f.hom ≫ r.hom := by cat_disch) : f ≅ g := Comma.isoMk l r h +/-- `isoMk''` is the dual of `isoMk`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing isoMk] +abbrev isoMk'' {f g : Arrow T} (l : f.right ≅ g.right) (r : f.left ≅ g.left) + (h : g.hom ≫ l.inv = r.inv ≫ f.hom := by cat_disch) : f ≅ g := + isoMk r l (by rwa [Iso.comp_inv_eq, Category.assoc, Iso.eq_inv_comp] at h) +attribute [to_dual none] isoMk_hom_left isoMk_hom_right isoMk_inv_left isoMk_inv_right + /-- A variant of `Arrow.isoMk` that creates an iso between two `Arrow.mk`s with a better type signature. -/ abbrev isoMk' {W X Y Z : T} (f : W ⟶ X) (g : Y ⟶ Z) (e₁ : W ≅ Y) (e₂ : X ≅ Z) (h : e₁.hom ≫ g = f ≫ e₂.hom := by cat_disch) : Arrow.mk f ≅ Arrow.mk g := Arrow.isoMk e₁ e₂ h +/-- `isoMk'''` is the dual of `isoMk'`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing isoMk'] +abbrev isoMk''' {W X Y Z : T} (f : X ⟶ W) (g : Z ⟶ Y) (e₁ : W ≅ Y) + (e₂ : X ≅ Z) (h : g ≫ e₁.inv = e₂.inv ≫ f := by cat_disch) : mk f ≅ mk g := + isoMk' f g e₂ e₁ (by rwa [Iso.comp_inv_eq, Category.assoc, Iso.eq_inv_comp] at h) + section variable {f g : Arrow T} (sq : f ⟶ g) +@[to_dual] instance isIso_left [IsIso sq] : IsIso sq.left := ⟨(inv sq).left, by simp [← comp_left]⟩ -instance isIso_right [IsIso sq] : IsIso sq.right := - ⟨(inv sq).right, by simp [← comp_right]⟩ - -lemma isIso_of_isIso' {f g : Arrow T} (sq : f ⟶ g) [IsIso sq] [IsIso f.hom] : +@[to_dual none] +private lemma isIso_of_isIso' {f g : Arrow T} (sq : f ⟶ g) [IsIso sq] [IsIso f.hom] : IsIso g.hom := by rw [iso_w (asIso sq)] infer_instance -lemma isIso_of_isIso {X Y : T} {f : X ⟶ Y} {g : Arrow T} (sq : mk f ⟶ g) [IsIso sq] [IsIso f] : - IsIso g.hom := by - have : IsIso (mk f).hom := by assumption - apply isIso_of_isIso' sq - +@[to_dual none] lemma isIso_hom_iff_isIso_hom_of_isIso {f g : Arrow T} (sq : f ⟶ g) [IsIso sq] : IsIso f.hom ↔ IsIso g.hom := ⟨fun _ => isIso_of_isIso' sq, fun _ => isIso_of_isIso' (inv sq)⟩ +@[to_dual none] lemma isIso_iff_isIso_of_isIso {W X Y Z : T} {f : W ⟶ X} {g : Y ⟶ Z} (sq : mk f ⟶ mk g) [IsIso sq] : IsIso f ↔ IsIso g := isIso_hom_iff_isIso_hom_of_isIso sq +@[to_dual none] lemma isIso_hom_iff_isIso_of_isIso {Y Z : T} {f : Arrow T} {g : Y ⟶ Z} (sq : f ⟶ mk g) [IsIso sq] : IsIso f.hom ↔ IsIso g := isIso_hom_iff_isIso_hom_of_isIso sq -@[simp] +@[to_dual (attr := simp, push ←)] theorem inv_left [IsIso sq] : (inv sq).left = inv sq.left := IsIso.eq_inv_of_hom_inv_id (by simp [← comp_left]) -@[simp] -theorem inv_right [IsIso sq] : (inv sq).right = inv sq.right := - IsIso.eq_inv_of_hom_inv_id (by simp [← comp_right]) - +@[to_dual none] theorem left_hom_inv_right [IsIso sq] : sq.left ≫ g.hom ≫ inv sq.right = f.hom := by simp only [← Category.assoc, IsIso.comp_inv_eq, w] +@[to_dual none] theorem inv_left_hom_right [IsIso sq] : inv sq.left ≫ f.hom ≫ sq.right = g.hom := by simp only [w, IsIso.inv_comp_eq] set_option backward.defeqAttrib.useBackward true in +@[to_dual epi_right] instance mono_left [Mono sq] : Mono sq.left where right_cancellation {Z} φ ψ h := by let aux : (Z ⟶ f.left) → (Arrow.mk (𝟙 Z) ⟶ f) := fun φ => @@ -276,34 +298,14 @@ instance mono_left [Mono sq] : Mono sq.left where · exact h · simp [this, ← Arrow.w_mk_right, reassoc_of% h] -set_option backward.defeqAttrib.useBackward true in -instance epi_right [Epi sq] : Epi sq.right where - left_cancellation {Z} φ ψ h := by - let aux : (g.right ⟶ Z) → (g ⟶ Arrow.mk (𝟙 Z)) := fun φ => - Arrow.homMk (g.hom ≫ φ) φ - change (aux φ).right = (aux ψ).right - congr 1 - rw [← cancel_epi sq] - ext - · simp only [comp_left, comp_left, aux, mk_left, homMk_left, w_assoc, h] - · exact h - -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp))] lemma hom_inv_id_left (e : f ≅ g) : e.hom.left ≫ e.inv.left = 𝟙 _ := by rw [← comp_left, e.hom_inv_id, id_left] -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp))] lemma inv_hom_id_left (e : f ≅ g) : e.inv.left ≫ e.hom.left = 𝟙 _ := by rw [← comp_left, e.inv_hom_id, id_left] -@[reassoc (attr := simp)] -lemma hom_inv_id_right (e : f ≅ g) : e.hom.right ≫ e.inv.right = 𝟙 _ := by - rw [← comp_right, e.hom_inv_id, id_right] - -@[reassoc (attr := simp)] -lemma inv_hom_id_right (e : f ≅ g) : e.inv.right ≫ e.hom.right = 𝟙 _ := by - rw [← comp_right, e.inv_hom_id, id_right] - end /-- Given a square from an arrow `i` to an isomorphism `p`, express the source part of `sq` @@ -338,15 +340,10 @@ def squareToSnd {X Y Z : C} {i : Arrow C} {f : X ⟶ Y} {g : Y ⟶ Z} (sq : i Arrow.homMk (sq.left ≫ f) (sq.right) (by simp [w_mk sq]) /-- The functor sending an arrow to its source. -/ -@[simps!] +@[to_dual (attr := simps!) /-- The functor sending an arrow to its target. -/] def leftFunc : Arrow C ⥤ C := Comma.fst _ _ -/-- The functor sending an arrow to its target. -/ -@[simps!] -def rightFunc : Arrow C ⥤ C := - Comma.snd _ _ - set_option backward.defeqAttrib.useBackward true in /-- The natural transformation from `leftFunc` to `rightFunc`, given by the arrow itself. -/ @[simps] @@ -365,7 +362,9 @@ set_option backward.defeqAttrib.useBackward true in @[simps] def mapArrow (F : C ⥤ D) : Arrow C ⥤ Arrow D where obj a := Arrow.mk (F.map a.hom) - map f := Arrow.homMk (F.map f.left) (F.map f.right) (by simp [← Functor.map_comp]) + map {X Y} f := Arrow.homMk (F.map f.left) (F.map f.right) (by simp [← Functor.map_comp]) + +attribute [to_dual self (reorder := X Y)] mapArrow_map variable (C D) @@ -375,7 +374,9 @@ a functor `F : C ⥤ D` to `F.mapArrow`. -/ @[simps] def mapArrowFunctor : (C ⥤ D) ⥤ (Arrow C ⥤ Arrow D) where obj F := F.mapArrow - map τ := { app f := Arrow.homMk (τ.app _) (τ.app _) } + map {X Y} τ := { app f := Arrow.homMk (τ.app _) (τ.app _) } + +attribute [to_dual self (reorder := X Y)] mapArrowFunctor_map_app variable {C D} @@ -431,6 +432,7 @@ def Arrow.discreteEquiv (S : Type u) : Arrow (Discrete S) ≃ S where /-- Extensionality lemma for functors `C ⥤ D` which uses as an assumption that the induced maps `Arrow C → Arrow D` coincide. -/ +@[to_dual self] lemma Arrow.functor_ext {F G : C ⥤ D} (h : ∀ ⦃X Y : C⦄ (f : X ⟶ Y), F.mapArrow.obj (Arrow.mk f) = G.mapArrow.obj (Arrow.mk f)) : F = G := From 1b0782d8191b03e0001caac10e1601d17f2cd580 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Mon, 22 Jun 2026 20:00:22 +0000 Subject: [PATCH 0267/1300] chore(cache): Stop dual-writing the cache to the legacy container (#40907) With this PR, master CI now uploads only to the `master` container, and the `legacy` (bare `mathlib4`) container stays as a read-only endpoint for pre-refactor artifacts. --- .github/workflows/build_template.yml | 17 ++--------------- Cache/Infra.lean | 9 +++++---- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 511e19544781d5..518274f97c7627 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -694,21 +694,8 @@ jobs: # $MATHLIB_CACHE_PRIMARY is set by the `Compute cache trust dispatch` # step above, from the shared composite action that owns the (repo, # branch) → container mapping for both this job and the read-side - # jobs (build, post_steps). - # Dual-write to the legacy `mathlib4` container first, then the - # primary. Only master CI dual-writes: older cache tools read only - # `legacy`, so it must stay fresh for them, while forks and nightly - # never write `legacy` (keeping low-trust artifacts out of what those - # readers trust). Writing `legacy` first keeps it a superset of - # `master` for as long as we dual-write: with `set -e`, a failed - # legacy write aborts the step before `master` gets artifacts that - # `legacy` lacks. (`put-staged` exits non-zero on real upload - # failures; already-present 409/412 blobs are not failures.) - if [ "$MATHLIB_CACHE_PRIMARY" = "master" ]; then - echo "Dual-writing to legacy container first (keeps legacy a superset of master)..." - lake env "$CACHE_BIN" put-staged --container=legacy --staging-dir="cache-staging" --repo="$REPO" - fi - + # jobs (build, post_steps). Each job writes only into its own trust-level + # container. echo "Uploading cache to Azure (container: $MATHLIB_CACHE_PRIMARY)..." lake env "$CACHE_BIN" put-staged --container="$MATHLIB_CACHE_PRIMARY" --staging-dir="cache-staging" --repo="$REPO" diff --git a/Cache/Infra.lean b/Cache/Infra.lean index 47b88f739ea583..99f6fc271f52e0 100644 --- a/Cache/Infra.lean +++ b/Cache/Infra.lean @@ -51,10 +51,11 @@ inductive Container where | nightlyTesting /-- Container for toolchain-PR test runs. -/ | prToolchainTests - /-- The bare `mathlib4` container that older cache clients read from. Only - master CI writes here (mirroring its `mathlib4-master` upload), so those - clients keep finding master-built artifacts; forks and nightly-testing stay - out to keep low-trust writes from reaching readers that predate the split. -/ + /-- The bare `mathlib4` container that older cache clients read from. CI does + not upload here; it is a read-only store of the master-built artifacts that + were mirrored from `mathlib4-master`, kept reachable so those older clients + can resolve them. The `master` container is a self-contained cache, so reads + fall back to `legacy` only for artifacts predating the write cutover. -/ | legacy deriving DecidableEq, Repr, BEq, Inhabited From cf9c5f705282a1cef9d3db3422b0092dd8ba173e Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 22 Jun 2026 20:47:05 +0000 Subject: [PATCH 0268/1300] feat(Analysis/Meromorphic): const_smul lemma (#39833) This allows more general scalar type than the existing `smul` ones --- Mathlib/Analysis/Meromorphic/Basic.lean | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 76db272de7420a..af4ae3fc44673f 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -29,6 +29,7 @@ open scoped Topology variable {𝕜 𝕜' : Type*} [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] +variable {R : Type*} [NormedRing R] [Module R E] [IsBoundedSMul R E] [SMulCommClass 𝕜 R E] /-- Meromorphy of `f` at `x` (more precisely, on a punctured neighbourhood of `x`; the value at `x` itself is irrelevant). -/ @@ -94,6 +95,12 @@ lemma smul {f : 𝕜 → 𝕜} {g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : M simp module +@[to_fun (attr := fun_prop)] +lemma const_smul {x : 𝕜} {f : 𝕜 → E} (hf : MeromorphicAt f x) (c : R) : + MeromorphicAt (c • f) x := by + rcases hf with ⟨m, hf⟩ + exact ⟨m, by simpa [smul_comm _ c _] using hf.fun_const_smul⟩ + @[to_fun (attr := fun_prop)] lemma mul {f g : 𝕜 → 𝕜'} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : MeromorphicAt (f * g) x := by @@ -550,6 +557,9 @@ include hf in MeromorphicOn (s • f) U := fun x hx ↦ (hs x hx).smul (hf x hx) +include hf in +@[to_fun] lemma const_smul (c : R) : MeromorphicOn (c • f) U := fun x hx ↦ (hf x hx).const_smul c + include hs ht in @[to_fun] lemma mul : MeromorphicOn (s * t) U := fun x hx ↦ (hs x hx).mul (ht x hx) @@ -695,6 +705,10 @@ lemma sub (hf : Meromorphic f) (hg : Meromorphic g) : lemma smul {f : 𝕜 → 𝕜} (hf : Meromorphic f) (hg : Meromorphic g) : Meromorphic (f • g) := fun x ↦ (hf x).smul (hg x) +@[to_fun (attr := fun_prop)] +lemma const_smul (hf : Meromorphic f) (c : R) : + Meromorphic (c • f) := fun x ↦ (hf x).const_smul c + @[to_fun (attr := fun_prop)] lemma mul {f g : 𝕜 → 𝕜'} (hf : Meromorphic f) (hg : Meromorphic g) : Meromorphic (f * g) := fun x ↦ (hf x).mul (hg x) From 67b53908ee491b8758b4cb294a88e2b45cade69d Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Mon, 22 Jun 2026 21:02:08 +0000 Subject: [PATCH 0269/1300] refactor(Analysis): golf `Mathlib/Analysis/Convex/BetweenList` (#40071) - rewrites `SortedLE.wbtw` using `triplewise_iff_getElem` and sorted getElem inequalities instead of nested list induction Extracted from #37968 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Analysis/Convex/BetweenList.lean | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/Mathlib/Analysis/Convex/BetweenList.lean b/Mathlib/Analysis/Convex/BetweenList.lean index abe92b3744fc36..a25c94db1e5dc7 100644 --- a/Mathlib/Analysis/Convex/BetweenList.lean +++ b/Mathlib/Analysis/Convex/BetweenList.lean @@ -180,20 +180,9 @@ variable [Field R] [LinearOrder R] [IsStrictOrderedRing R] variable {R} lemma SortedLE.wbtw {l : List R} (h : l.SortedLE) : l.Wbtw R := by - induction l with - | nil => simp - | cons head tail ih => - rw [wbtw_cons] - refine ⟨?_, ih h.pairwise.of_cons.sortedLE⟩ - clear ih - induction tail with - | nil => simp - | cons head' tail' ih => - rw [pairwise_cons] - refine ⟨?_, ih (h.pairwise.sublist ?_).sortedLE⟩ - · simp_rw [sortedLE_iff_pairwise, pairwise_cons_cons, pairwise_cons] at h - exact fun a ha ↦ .of_le_of_le h.1 (h.2.2.1 a ha) - · simp + rw [List.Wbtw, List.triplewise_iff_getElem] + intro i j k hij hjk hk + exact Wbtw.of_le_of_le (h.getElem_le_getElem_of_le hij.le) (h.getElem_le_getElem_of_le hjk.le) lemma SortedLT.sbtw {l : List R} (h : l.SortedLT) : l.Sbtw R := ⟨h.sortedLE.wbtw, h.nodup⟩ From 2c4e038a6d3721dcf3c3cd820c7820284e6b8293 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Tue, 23 Jun 2026 00:12:28 +0000 Subject: [PATCH 0270/1300] refactor: switch from RingQuot to RingCon.Quotient (#40451) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR observes that `RingQuot r` is analogous to `(ringConGen r).Quotient`, and changes all callers to use the latter. Note that `RingQuot` had some extra irreducibility that has not yet been configured for `RingCon.Quotient`, and so there is a performance drop associated with the switch. Zulip: [#mathlib4 > Canonical way to quotient a ring @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Canonical.20way.20to.20quotient.20a.20ring/near/604966059) --- Mathlib/Algebra/Lie/UniversalEnveloping.lean | 24 ++--- .../LinearAlgebra/CliffordAlgebra/Basic.lean | 48 +++++----- .../LinearAlgebra/CliffordAlgebra/Equivs.lean | 10 +- .../LinearAlgebra/CliffordAlgebra/Even.lean | 10 +- Mathlib/LinearAlgebra/FreeProduct/Basic.lean | 57 ++++++----- .../LinearAlgebra/SymmetricAlgebra/Basic.lean | 33 ++++--- .../LinearAlgebra/TensorAlgebra/Basic.lean | 50 +++++----- Mathlib/RingTheory/Congruence/Basic.lean | 2 - Mathlib/RingTheory/Congruence/Defs.lean | 7 +- Mathlib/RingTheory/Congruence/Hom.lean | 11 ++- .../RingTheory/DividedPowerAlgebra/Init.lean | 94 ++++++++++--------- 11 files changed, 193 insertions(+), 153 deletions(-) diff --git a/Mathlib/Algebra/Lie/UniversalEnveloping.lean b/Mathlib/Algebra/Lie/UniversalEnveloping.lean index dcdf160ac70a4e..8ebf54ba4ef5fa 100644 --- a/Mathlib/Algebra/Lie/UniversalEnveloping.lean +++ b/Mathlib/Algebra/Lie/UniversalEnveloping.lean @@ -6,7 +6,6 @@ Authors: Oliver Nash module public import Mathlib.Algebra.Lie.OfAssociative -public import Mathlib.Algebra.RingQuot public import Mathlib.LinearAlgebra.TensorAlgebra.Basic /-! @@ -57,11 +56,13 @@ so that our construction needs only the semiring structure of the tensor algebra inductive Rel : TensorAlgebra R L → TensorAlgebra R L → Prop | lie_compat (x y : L) : Rel (ιₜ ⁅x, y⁆ + ιₜ y * ιₜ x) (ιₜ x * ιₜ y) +/-- `Rel` as a ring congruence, used to build the quotient. -/ +@[no_expose] def ringCon : RingCon (TensorAlgebra R L) := ringConGen (Rel R L) + end UniversalEnvelopingAlgebra /-- The universal enveloping algebra of a Lie algebra. -/ -def UniversalEnvelopingAlgebra := - RingQuot (UniversalEnvelopingAlgebra.Rel R L) +def UniversalEnvelopingAlgebra := (UniversalEnvelopingAlgebra.ringCon R L).Quotient deriving Inhabited, Ring, Algebra R namespace UniversalEnvelopingAlgebra @@ -69,7 +70,7 @@ namespace UniversalEnvelopingAlgebra /-- The quotient map from the tensor algebra to the universal enveloping algebra as a morphism of associative algebras. -/ def mkAlgHom : TensorAlgebra R L →ₐ[R] UniversalEnvelopingAlgebra R L := - RingQuot.mkAlgHom R (Rel R L) + RingCon.mkₐ R _ variable {L} attribute [local instance 100] LieRing.ofAssociativeRing @@ -81,7 +82,7 @@ def ι : L →ₗ⁅R⁆ UniversalEnvelopingAlgebra R L := map_lie' := fun {x y} => by suffices mkAlgHom R L (ιₜ ⁅x, y⁆ + ιₜ y * ιₜ x) = mkAlgHom R L (ιₜ x * ιₜ y) by rw [map_mul] at this; simp [LieRing.of_associative_ring_bracket, ← this] - exact RingQuot.mkAlgHom_rel _ (Rel.lie_compat x y) } + exact Quotient.sound <| RingCon.le_ringConGen _ _ (Rel.lie_compat x y) } variable {A : Type u₃} [Ring A] [Algebra R A] (f : L →ₗ⁅R⁆ A) @@ -90,11 +91,11 @@ set_option backward.isDefEq.respectTransparency false in associative algebras lift to associative algebra morphisms from the universal enveloping algebra. -/ def lift : (L →ₗ⁅R⁆ A) ≃ (UniversalEnvelopingAlgebra R L →ₐ[R] A) where toFun f := - RingQuot.liftAlgHom R - ⟨TensorAlgebra.lift R (f : L →ₗ[R] A), by + RingCon.liftₐ _ + (TensorAlgebra.lift R (f : L →ₗ[R] A)) <| by + grw [ringCon, RingCon.ringConGen_le] intro a b h; induction h - simp only [LieRing.of_associative_ring_bracket, map_add, TensorAlgebra.lift_ι_apply, - LieHom.coe_toLinearMap, LieHom.map_lie, map_mul, sub_add_cancel]⟩ + simp [LieRing.of_associative_ring_bracket] invFun F := (F : UniversalEnvelopingAlgebra R L →ₗ⁅R⁆ A).comp (ι R) left_inv f := by ext @@ -105,10 +106,9 @@ def lift : (L →ₗ⁅R⁆ A) ≃ (UniversalEnvelopingAlgebra R L →ₐ[R] A) -- RingQuot.liftAlgHom_mkAlgHom_apply] simp only [LieHom.coe_comp, Function.comp_apply, AlgHom.coe_toLieHom, UniversalEnvelopingAlgebra.ι_apply, mkAlgHom] - simp only [UniversalEnvelopingAlgebra, RingQuot.liftAlgHom_mkAlgHom_apply, - TensorAlgebra.lift_ι_apply, LieHom.coe_toLinearMap] + simp [UniversalEnvelopingAlgebra] right_inv F := by - apply RingQuot.ringQuot_ext' + apply RingCon.Quotient.hom_extₐ ext -- Porting note: was -- simp only [ι, mkAlgHom, TensorAlgebra.lift_ι_apply, LieHom.coe_toLinearMap, diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean index b07967f77a8080..d6eb7a6bedd007 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean @@ -5,7 +5,7 @@ Authors: Eric Wieser, Utensil Song -/ module -public import Mathlib.Algebra.RingQuot +public import Mathlib.RingTheory.Congruence.Hom public import Mathlib.LinearAlgebra.TensorAlgebra.Basic public import Mathlib.LinearAlgebra.QuadraticForm.Isometry public import Mathlib.LinearAlgebra.QuadraticForm.IsometryEquiv @@ -62,12 +62,14 @@ The Clifford algebra of `M` is defined as the quotient modulo this relation. inductive Rel : TensorAlgebra R M → TensorAlgebra R M → Prop | of (m : M) : Rel (ι R m * ι R m) (algebraMap R _ (Q m)) +/-- `Rel` as a ring congruence, used to build the quotient. -/ +@[no_expose] def ringCon : RingCon (TensorAlgebra R M) := ringConGen (Rel Q) + end CliffordAlgebra /-- The Clifford algebra of an `R`-module `M` equipped with a `QuadraticForm` `Q`. -/ -def CliffordAlgebra := - RingQuot (CliffordAlgebra.Rel Q) +def CliffordAlgebra := CliffordAlgebra.ringCon Q |>.Quotient deriving Inhabited, Ring, Algebra R namespace CliffordAlgebra @@ -76,7 +78,7 @@ instance (priority := 900) instAlgebra' {R A M} [CommSemiring R] [AddCommGroup M [Algebra R A] [Module R M] [Module A M] (Q : QuadraticForm A M) [IsScalarTower R A M] : Algebra R (CliffordAlgebra Q) := - inferInstanceAs <| Algebra R (RingQuot _) + inferInstanceAs <| Algebra R (RingCon.Quotient _) -- verify there are no diamonds -- but doesn't work at `reducible_and_instances` https://github.com/leanprover-community/mathlib4/issues/10906 @@ -88,27 +90,25 @@ instance {R S A M} [CommSemiring R] [CommSemiring S] [AddCommGroup M] [CommRing [Algebra R A] [Algebra S A] [Module R M] [Module S M] [Module A M] (Q : QuadraticForm A M) [IsScalarTower R A M] [IsScalarTower S A M] : SMulCommClass R S (CliffordAlgebra Q) := - RingQuot.instSMulCommClass _ + RingCon.instSMulCommClassQuotient _ instance {R S A M} [CommSemiring R] [CommSemiring S] [AddCommGroup M] [CommRing A] [SMul R S] [Algebra R A] [Algebra S A] [Module R M] [Module S M] [Module A M] [IsScalarTower R A M] [IsScalarTower S A M] [IsScalarTower R S A] (Q : QuadraticForm A M) : IsScalarTower R S (CliffordAlgebra Q) := - RingQuot.instIsScalarTower _ + RingCon.instIsScalarTowerQuotient _ /-- The canonical linear map `M →ₗ[R] CliffordAlgebra Q`. -/ def ι : M →ₗ[R] CliffordAlgebra Q := - (RingQuot.mkAlgHom R _).toLinearMap.comp (TensorAlgebra.ι R) + (RingCon.mkₐ R _).toLinearMap.comp (TensorAlgebra.ι R) + +private theorem ι_apply (m : M) : + ι Q m = (TensorAlgebra.ι R m : CliffordAlgebra.ringCon Q |>.Quotient) := rfl /-- As well as being linear, `ι Q` squares to the quadratic form -/ @[simp] -theorem ι_sq_scalar (m : M) : ι Q m * ι Q m = algebraMap R _ (Q m) := by - rw [ι] - erw [LinearMap.comp_apply] - rw [AlgHom.toLinearMap_apply] - erw [← map_mul (RingQuot.mkAlgHom R (Rel Q))] - rw [RingQuot.mkAlgHom_rel R (Rel.of m), AlgHom.commutes] - rfl +theorem ι_sq_scalar (m : M) : ι Q m * ι Q m = algebraMap R _ (Q m) := + Quotient.sound <| RingCon.le_ringConGen _ _ (Rel.of m) variable {Q} {A : Type*} [Semiring A] [Algebra R A] @@ -126,21 +126,25 @@ from `CliffordAlgebra Q` to `A`. def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A) where toFun f := - RingQuot.liftAlgHom R - ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by - induction h - rw [AlgHom.commutes, map_mul, TensorAlgebra.lift_ι_apply, f.prop]⟩ + RingCon.liftₐ (CliffordAlgebra.ringCon Q) + (TensorAlgebra.lift R (f : M →ₗ[R] A)) + (by + exact RingCon.ringConGen_le.2 fun x y (h : Rel Q x y) => by + induction h + simp [f.prop]) invFun F := ⟨F.toLinearMap.comp (ι Q), fun m => by rw [LinearMap.comp_apply, AlgHom.toLinearMap_apply, comp_ι_sq_scalar]⟩ left_inv f := by ext x - exact (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ x) + dsimp + exact (RingCon.liftₐ_mk _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ x) right_inv F := - RingQuot.ringQuot_ext' _ _ _ <| + RingCon.Quotient.hom_extₐ <| TensorAlgebra.hom_ext <| - LinearMap.ext fun x ↦ - (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ _) + LinearMap.ext fun x ↦ by + dsimp + exact (RingCon.liftₐ_mk _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ _) @[simp] theorem ι_comp_lift (f : M →ₗ[R] A) (cond : ∀ m, f m * f m = algebraMap _ _ (Q m)) : diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean index df8a439744af44..fedb6cf5ebf965 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean @@ -355,12 +355,14 @@ protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] := (by ext : 1; simp) (by ext : 2; simp) @[simp] -theorem equiv_ι (r : R) : CliffordAlgebraDualNumber.equiv (ι (R := R) _ r) = r • ε := - (lift_ι_apply _ _ r).trans (inr_eq_smul_eps _) +theorem equiv_ι (r : R) : CliffordAlgebraDualNumber.equiv (ι (R := R) _ r) = r • ε := by + dsimp [CliffordAlgebraDualNumber.equiv, AlgEquiv.ofAlgHom] + exact (lift_ι_apply _ _ r).trans (inr_eq_smul_eps _) @[simp] theorem equiv_symm_eps : - CliffordAlgebraDualNumber.equiv.symm (eps : R[ε]) = ι (0 : QuadraticForm R R) 1 := - DualNumber.lift_apply_eps _ + CliffordAlgebraDualNumber.equiv.symm (eps : R[ε]) = ι (0 : QuadraticForm R R) 1 := by + dsimp [CliffordAlgebraDualNumber.equiv, AlgEquiv.ofAlgHom] + exact DualNumber.lift_apply_eps _ end CliffordAlgebraDualNumber diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean index f7c84a08497f7d..eb3939dd0375a8 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean @@ -203,11 +203,11 @@ theorem aux_one : aux f 1 = 1 := congr_arg Prod.fst (foldr_one _ _ _ _) @[simp] -theorem aux_ι (m₁ m₂ : M) : aux f ((even.ι Q).bilin m₁ m₂) = f.bilin m₁ m₂ := - (congr_arg Prod.fst (foldr_mul _ _ _ _ _ _)).trans - (by - rw [foldr_ι, foldr_ι] - exact mul_one _) +theorem aux_ι (m₁ m₂ : M) : aux f ((even.ι Q).bilin m₁ m₂) = f.bilin m₁ m₂ := by + rw [CliffordAlgebra.even.lift.aux_apply] + refine (congr_arg Prod.fst (foldr_mul Q (fFold f) _ _ _ _)).trans ?_ + rw [foldr_ι, foldr_ι] + exact mul_one _ @[simp] theorem aux_algebraMap (r) : diff --git a/Mathlib/LinearAlgebra/FreeProduct/Basic.lean b/Mathlib/LinearAlgebra/FreeProduct/Basic.lean index af6700f7588803..80a143e85978c8 100644 --- a/Mathlib/LinearAlgebra/FreeProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/FreeProduct/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.DirectSum.Basic public import Mathlib.LinearAlgebra.TensorAlgebra.ToTensorPower +public import Mathlib.RingTheory.Congruence.Hom /-! # The free product of $R$-algebras @@ -100,30 +101,41 @@ inductive rel : FreeTensorAlgebra R A → FreeTensorAlgebra R A → Prop (tprod R (⨁ i, A i) 2 (fun | 0 => lof R I A i a₁ | 1 => lof R I A i a₂)) (ι R <| lof R I A i (a₁ * a₂)) +/-- `rel` as a ring congruence. -/ +def ringCon : RingCon (FreeTensorAlgebra R A) := ringConGen (rel R A) + open scoped Function /-- The generating equivalence relation for elements of the power algebra that are identified in the free product -/ @[reducible, simp] def rel' := rel R A on ofDirectSum +/-- `rel'` as a ring congruence. -/ +def ringCon' : RingCon (PowerAlgebra R A) := ringConGen (rel' R A) + theorem rel_id (i : I) : rel R A (ι R <| lof R I A i 1) 1 := rel.id /-- The free product of the collection of `R`-algebras `A i`, as a quotient of `FreeTensorAlgebra R A` -/ -@[reducible] def _root_.LinearAlgebra.FreeProduct := RingQuot <| FreeProduct.rel R A +@[reducible] def _root_.LinearAlgebra.FreeProduct := FreeProduct.ringCon R A |>.Quotient /-- The free product of the collection of `R`-algebras `A i`, as a quotient of `PowerAlgebra R A` -/ -@[reducible] def asPowers := RingQuot <| FreeProduct.rel' R A +@[reducible] def asPowers := FreeProduct.ringCon' R A |>.Quotient /-- The `R`-algebra equivalence relating `FreeProduct` and `FreeProduct.asPowers`. -/ noncomputable def asPowersEquiv : asPowers R A ≃ₐ[R] FreeProduct R A := - RingQuot.algEquivQuotAlgEquiv - (powerAlgebraEquivFreeTensorAlgebra R A |>.symm) (FreeProduct.rel R A) + RingCon.congrₐ _ + (powerAlgebraEquivFreeTensorAlgebra R A |>.symm) (by + rw [ringCon', ringCon, rel'] + erw [RingCon.comap_ringConGen_ringEquiv] + congr + ext i x + simp [Function.onFun]) |>.symm -open RingQuot Function +open Function local infixr:60 " ∘ₐ " => AlgHom.comp @@ -133,27 +145,29 @@ instance instAlgebra : Algebra R (FreeProduct R A) := by infer_instance /-- The canonical quotient map `FreeTensorAlgebra R A →ₐ[R] FreeProduct R A`, as an `R`-algebra homomorphism -/ abbrev mkAlgHom : FreeTensorAlgebra R A →ₐ[R] FreeProduct R A := - RingQuot.mkAlgHom R (rel R A) + RingCon.mkₐ _ _ /-- The canonical linear map from the direct sum of the `A i` to the free product -/ -abbrev ι' : (⨁ i, A i) →ₗ[R] FreeProduct R A := +def ι' : (⨁ i, A i) →ₗ[R] FreeProduct R A := (mkAlgHom R A).toLinearMap ∘ₗ TensorAlgebra.ι R (M := ⨁ i, A i) @[simp] theorem ι_apply (x : ⨁ i, A i) : - ⟨Quot.mk (Rel <| rel R A) (TensorAlgebra.ι R x)⟩ = ι' R A x := by - aesop (add simp [ι', mkAlgHom, RingQuot.mkAlgHom, mkRingHom]) + ↑(TensorAlgebra.ι R x) = ι' R A x := by + aesop (add simp [ι', mkAlgHom]) /-- The injection into the free product of any `1 : A i` is the 1 of the free product. -/ theorem identify_one (i : I) : ι' R A (DirectSum.lof R I A i 1) = 1 := by - suffices ι' R A (DirectSum.lof R I A i 1) = mkAlgHom R A 1 by simpa - exact RingQuot.mkAlgHom_rel R <| rel_id R A (i := i) + suffices ι' R A (DirectSum.lof R I A i 1) = mkAlgHom R A 1 by simpa [← ι_apply] + exact Quotient.sound <| RingCon.le_ringConGen _ _ <| rel_id R A (i := i) /-- Multiplication in the free product of the injections of any two `aᵢ aᵢ': A i` for the same `i` is just the injection of multiplication `aᵢ * aᵢ'` in `A i`. -/ theorem mul_injections (a₁ a₂ : A i) : ι' R A (DirectSum.lof R I A i a₁) * ι' R A (DirectSum.lof R I A i a₂) = ι' R A (DirectSum.lof R I A i (a₁ * a₂)) := by - convert! RingQuot.mkAlgHom_rel R <| rel.prod + rw [← ι_apply, ← ι_apply, ← RingCon.coe_mul] + refine Quotient.sound <| RingCon.le_ringConGen _ _ <| ?_ + convert! rel.prod simp /-- The `i`th canonical injection, from `A i` to the free product, as @@ -173,34 +187,31 @@ irreducible_def ι (i : I) : A i →ₐ[R] FreeProduct R A := /-- The family of canonical injection maps, with `i` left implicit -/ irreducible_def of {i : I} : A i →ₐ[R] FreeProduct R A := ι R A i - /-- Universal property of the free product of algebras: for every `R`-algebra `B`, every family of maps `maps : (i : I) → (A i →ₐ[R] B)` lifts to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. -/ @[simps] def lift : ({i : I} → A i →ₐ[R] B) ≃ (FreeProduct R A →ₐ[R] B) where toFun maps := - RingQuot.liftAlgHom R ⟨ - TensorAlgebra.lift R <| - DirectSum.toModule R I B <| - (@maps · |>.toLinearMap), - fun x y r ↦ by + RingCon.liftₐ _ + (TensorAlgebra.lift R <| DirectSum.toModule R I B <| (@maps · |>.toLinearMap)) + <| RingCon.ringConGen_le.2 fun x y r ↦ by cases r with | id => simp - | prod => simp⟩ + | prod => simp invFun π i := π ∘ₐ ι R A i left_inv π := by ext i aᵢ - aesop (add simp [ι, ι']) + simp [ι, ← ι_apply] right_inv maps := by ext i a - aesop (add simp [ι, ι']) + simp [ι, ← ι_apply] /-- Universal property of the free product of algebras, property: for every `R`-algebra `B`, every family of maps `maps : (i : I) → (A i →ₐ[R] B)` lifts to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. -/ @[simp↓] theorem lift_comp_ι : lift R A maps ∘ₐ ι R A i = maps := by ext a - simp [lift_apply, ι] + simp [lift_apply, ι, ← ι_apply] @[simp↓] theorem lift_algebraMap (r : R) : lift R A maps (algebraMap R _ r) = algebraMap R _ r := by rw [lift_apply, AlgHom.commutes] @@ -209,6 +220,6 @@ to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. (f : FreeProduct R A →ₐ[R] B) (h : ∀ i, f ∘ₐ ι R A i = maps) : f = lift R A maps := by ext i a; simp_rw [AlgHom.ext_iff] at h; specialize h i a - simp [h.symm, ι] + simp [h.symm, ι, ← ι_apply] end LinearAlgebra.FreeProduct diff --git a/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean b/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean index 7ccbac331f11e5..4a1147d6b0fbc8 100644 --- a/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean @@ -40,19 +40,21 @@ quotiented out by. -/ inductive TensorAlgebra.SymRel : TensorAlgebra R M → TensorAlgebra R M → Prop where | mul_comm (x y : M) : SymRel (ι R x * ι R y) (ι R y * ι R x) +/-- `SymRel` as a ring congruence, used to build the quotient. -/ +@[no_expose] def TensorAlgebra.symRingCon : RingCon (TensorAlgebra R M) := ringConGen (SymRel R M) + open TensorAlgebra /-- Concrete construction of the symmetric algebra of `M` by quotienting out the tensor algebra by the commutativity relation. -/ -abbrev SymmetricAlgebra := RingQuot (SymRel R M) +abbrev SymmetricAlgebra := symRingCon R M |>.Quotient namespace SymmetricAlgebra /-- Algebra homomorphism from the tensor algebra over `M` to the symmetric algebra over `M`. -/ -abbrev algHom : TensorAlgebra R M →ₐ[R] SymmetricAlgebra R M := RingQuot.mkAlgHom R (SymRel R M) +abbrev algHom : TensorAlgebra R M →ₐ[R] SymmetricAlgebra R M := RingCon.mkₐ R _ -lemma algHom_surjective : Function.Surjective (algHom R M) := - RingQuot.mkAlgHom_surjective _ _ +lemma algHom_surjective : Function.Surjective (algHom R M) := Quotient.mk_surjective /-- Canonical inclusion of `M` into the symmetric algebra `SymmetricAlgebra R M`. -/ def ι : M →ₗ[R] SymmetricAlgebra R M := algHom R M ∘ₗ TensorAlgebra.ι R @@ -78,7 +80,9 @@ instance : CommSemiring (SymmetricAlgebra R M) where | algebraMap r => exact Algebra.commute_algebraMap_right _ _ | ι x => induction a using SymmetricAlgebra.induction with | algebraMap r => exact Algebra.commute_algebraMap_left _ _ - | ι y => simp [commute_iff_eq, ι, ← map_mul, RingQuot.mkAlgHom_rel _ (SymRel.mul_comm x y)] + | ι y => + have := RingCon.le_ringConGen (r := SymRel R M) _ _ <| SymRel.mul_comm y x + simpa [commute_iff_eq, ι, ← RingCon.coe_mul] | mul a b ha hb => exact ha.mul_left hb | add a b ha hb => exact ha.add_left hb | mul b c hb hc => exact hb.mul_right hc @@ -86,29 +90,32 @@ instance : CommSemiring (SymmetricAlgebra R M) where instance (R M) [CommRing R] [AddCommMonoid M] [Module R M] : CommRing (SymmetricAlgebra R M) where __ := (inferInstance : CommSemiring (SymmetricAlgebra R M)) - __ := (inferInstance : Ring (RingQuot (SymRel R M))) + __ := (inferInstance : Ring (SymmetricAlgebra R M)) variable {R M} {A : Type*} [CommSemiring A] [Algebra R A] /-- For any linear map `f : M →ₗ[R] A`, `SymmetricAlgebra.lift f` lifts the linear map to an R-algebra homomorphism from `SymmetricAlgebra R M` to `A`. -/ -def lift : (M →ₗ[R] A) ≃ (SymmetricAlgebra R M →ₐ[R] A) := by +def lift : (M →ₗ[R] A) ≃ (SymmetricAlgebra R M →ₐ[R] A) := let equiv : (TensorAlgebra R M →ₐ[R] A) ≃ - {f : TensorAlgebra R M →ₐ[R] A // ∀ {x y}, (TensorAlgebra.SymRel R M) x y → f x = f y} := by - refine (Equiv.subtypeUnivEquiv fun h _ _ h' ↦ ?_).symm - induction h' with | mul_comm x y => rw [map_mul, map_mul, mul_comm] - exact (TensorAlgebra.lift R).trans <| equiv.trans <| RingQuot.liftAlgHom R + {f : TensorAlgebra R M →ₐ[R] A // TensorAlgebra.symRingCon R M ≤ RingCon.ker f.toRingHom} := + (Equiv.subtypeUnivEquiv fun h _ _ h' ↦ ?_).symm + (TensorAlgebra.lift R).trans <| equiv.trans <| RingCon.liftₐEquiv (symRingCon R M) +where finally + refine RingCon.ringConGen_le.2 (fun x y h' => ?_) h' + induction h' with | mul_comm x y + rw [RingCon.ker_apply, map_mul, map_mul, mul_comm] variable (f : M →ₗ[R] A) @[simp] lemma lift_ι_apply (a : M) : lift f (ι R M a) = f a := by - simp [lift, ι, algHom] + simp [lift, ι, algHom, RingCon.liftₐEquiv] @[simp] lemma lift_comp_ι : lift f ∘ₗ ι R M = f := LinearMap.ext <| lift_ι_apply f -@[ext 1100] +@[ext 1200] theorem algHom_ext {F G : SymmetricAlgebra R M →ₐ[R] A} (h : F ∘ₗ ι R M = (G ∘ₗ ι R M : M →ₗ[R] A)) : F = G := by ext x diff --git a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean index a8e63217d9d82c..704c34f0748b31 100644 --- a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean @@ -6,10 +6,10 @@ Authors: Adam Topaz module public import Mathlib.Algebra.FreeAlgebra -public import Mathlib.Algebra.RingQuot public import Mathlib.Algebra.TrivSqZeroExt.Basic public import Mathlib.Algebra.Algebra.Operations public import Mathlib.LinearAlgebra.Multilinear.Basic +public import Mathlib.RingTheory.Congruence.Hom /-! # Tensor Algebras @@ -56,12 +56,14 @@ inductive Rel : FreeAlgebra R M → FreeAlgebra R M → Prop | smul {r : R} {a : M} : Rel (FreeAlgebra.ι R (r • a)) (algebraMap R (FreeAlgebra R M) r * FreeAlgebra.ι R a) +/-- `Rel` as a ring congruence, used to build the quotient. -/ +@[no_expose] def ringCon : RingCon (FreeAlgebra R M) := ringConGen (Rel R M) + end TensorAlgebra /-- The tensor algebra of the module `M` over the commutative semiring `R`. -/ -def TensorAlgebra := - RingQuot (TensorAlgebra.Rel R M) +def TensorAlgebra := TensorAlgebra.ringCon R M |>.Quotient deriving Inhabited, Semiring -- `IsScalarTower` is not needed, but the instance isn't really canonical without it. @@ -70,7 +72,7 @@ instance instAlgebra {R A M} [CommSemiring R] [AddCommMonoid M] [CommSemiring A] [Algebra R A] [Module R M] [Module A M] [IsScalarTower R A M] : Algebra R (TensorAlgebra A M) := - inferInstanceAs <| Algebra R (RingQuot _) + inferInstanceAs <| Algebra R (RingCon.Quotient _) -- verify there is no diamond -- but doesn't work at `reducible_and_instances` https://github.com/leanprover-community/mathlib4/issues/10906 @@ -80,18 +82,18 @@ instance {R S A M} [CommSemiring R] [CommSemiring S] [AddCommMonoid M] [CommSemi [Algebra R A] [Algebra S A] [Module R M] [Module S M] [Module A M] [IsScalarTower R A M] [IsScalarTower S A M] : SMulCommClass R S (TensorAlgebra A M) := - inferInstanceAs <| SMulCommClass R S (RingQuot _) + inferInstanceAs <| SMulCommClass R S (RingCon.Quotient _) instance {R S A M} [CommSemiring R] [CommSemiring S] [AddCommMonoid M] [CommSemiring A] [SMul R S] [Algebra R A] [Algebra S A] [Module R M] [Module S M] [Module A M] [IsScalarTower R A M] [IsScalarTower S A M] [IsScalarTower R S A] : IsScalarTower R S (TensorAlgebra A M) := - inferInstanceAs <| IsScalarTower R S (RingQuot _) + inferInstanceAs <| IsScalarTower R S (RingCon.Quotient _) namespace TensorAlgebra instance {S : Type*} [CommRing S] [Module S M] : Ring (TensorAlgebra S M) := - inferInstanceAs <| Ring (RingQuot _) + inferInstanceAs <| Ring (RingCon.Quotient _) -- verify there is no diamond -- but doesn't work at `reducible_and_instances` https://github.com/leanprover-community/mathlib4/issues/10906 @@ -104,16 +106,16 @@ set_option backward.isDefEq.respectTransparency false in /-- The canonical linear map `M →ₗ[R] TensorAlgebra R M`. -/ irreducible_def ι : M →ₗ[R] TensorAlgebra R M := - { toFun := fun m => RingQuot.mkAlgHom R _ (FreeAlgebra.ι R m) + { toFun := fun m => RingCon.toQuotient (FreeAlgebra.ι R m) map_add' := fun x y => by - rw [← map_add (RingQuot.mkAlgHom R (Rel R M))] - exact RingQuot.mkAlgHom_rel R Rel.add + rw [← RingCon.coe_add] + exact Quotient.sound <| RingConGen.Rel.of _ _ Rel.add map_smul' := fun r x => by - rw [← map_smul (RingQuot.mkAlgHom R (Rel R M))] - exact RingQuot.mkAlgHom_rel R Rel.smul } + rw [← RingCon.coe_smul] + exact Quotient.sound <| RingConGen.Rel.of _ _ <| Rel.smul} theorem ringQuot_mkAlgHom_freeAlgebra_ι_eq_ι (m : M) : - RingQuot.mkAlgHom R (Rel R M) (FreeAlgebra.ι R m) = ι R m := by + RingCon.mkₐ R (ringCon R M) (FreeAlgebra.ι R m) = ι R m := by rw [ι] rfl @@ -122,24 +124,26 @@ of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`. -/ @[simps symm_apply] def lift {A : Type*} [Semiring A] [Algebra R A] : (M →ₗ[R] A) ≃ (TensorAlgebra R M →ₐ[R] A) := - { toFun := - RingQuot.liftAlgHom R ∘ fun f => - ⟨FreeAlgebra.lift R (⇑f), fun x y (h : Rel R M x y) => by - induction h <;> - simp only [Algebra.smul_def, FreeAlgebra.lift_ι_apply, map_smulₛₗ, RingHom.id_apply, - map_mul, AlgHom.commutes, map_add]⟩ + { toFun f := + RingCon.liftₐ (ringCon R M) (FreeAlgebra.lift R (f)) <| by + grw [ringCon, RingCon.ringConGen_le] + intro x y h + induction h <;> + simp [Algebra.smul_def, FreeAlgebra.lift_ι_apply, + map_mul, AlgHom.commutes, map_add, RingCon.ker] invFun := fun F => F.toLinearMap.comp (ι R) left_inv := fun f => by rw [ι] ext1 x - exact (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (FreeAlgebra.lift_ι_apply f x) + dsimp + exact (RingCon.liftₐ_mk _ _ _ _).trans (FreeAlgebra.lift_ι_apply f x) right_inv := fun F => - RingQuot.ringQuot_ext' _ _ _ <| + RingCon.Quotient.hom_extₐ <| FreeAlgebra.hom_ext <| funext fun x => by rw [ι] - exact - (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (FreeAlgebra.lift_ι_apply _ _) } + simp + rfl } variable {R} diff --git a/Mathlib/RingTheory/Congruence/Basic.lean b/Mathlib/RingTheory/Congruence/Basic.lean index 43628cefaaa913..cbd85e276d1fab 100644 --- a/Mathlib/RingTheory/Congruence/Basic.lean +++ b/Mathlib/RingTheory/Congruence/Basic.lean @@ -26,7 +26,6 @@ Most of the time you likely want to use the `Ideal.Quotient` API that is built o ## TODO -* Use this for `RingQuot` too. * Copy across more API from `Con` and `AddCon` in `Mathlib/GroupTheory/Congruence/`. -/ @@ -259,7 +258,6 @@ theorem ringConGen_eq (r : R → R → Prop) : (fun _ _ h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc)) (sInf_le le_ringConGen) - /-- The smallest congruence relation containing a binary relation `r` is contained in any congruence relation containing `r`. -/ theorem ringConGen_le {r : R → R → Prop} {c : RingCon R} : ringConGen r ≤ c ↔ r ≤ ⇑c := diff --git a/Mathlib/RingTheory/Congruence/Defs.lean b/Mathlib/RingTheory/Congruence/Defs.lean index 1ef19c1e92172e..a8750b1c846e1b 100644 --- a/Mathlib/RingTheory/Congruence/Defs.lean +++ b/Mathlib/RingTheory/Congruence/Defs.lean @@ -26,7 +26,6 @@ Most of the time you likely want to use the `Ideal.Quotient` API that is built o ## TODO -* Use this for `RingQuot` too. * Copy across more API from `Con` and `AddCon` in `Mathlib/GroupTheory/Congruence/`. -/ @@ -410,8 +409,10 @@ instance [Add R] [CommMagma R] (c : RingCon R) : CommMagma c.Quotient := instance [Add R] [CommSemigroup R] (c : RingCon R) : CommSemigroup c.Quotient := inferInstanceAs <| CommSemigroup c.toCon.Quotient -instance [Add R] [Monoid R] (c : RingCon R) : Monoid c.Quotient := - inferInstanceAs <| Monoid c.toCon.Quotient +instance [Add R] [Monoid R] (c : RingCon R) : Monoid c.Quotient := fast_instance% + { __ : Monoid c.toCon.Quotient := inferInstanceAs _ + -- see https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/inferInstanceAs.20creates.20non-reducible.20diamonds/near/603969174 + npow n x := x ^ n } instance [Add R] [CommMonoid R] (c : RingCon R) : CommMonoid c.Quotient := inferInstanceAs <| CommMonoid c.toCon.Quotient diff --git a/Mathlib/RingTheory/Congruence/Hom.lean b/Mathlib/RingTheory/Congruence/Hom.lean index 5e7a93606ddf80..a3ad9e08b2f32b 100644 --- a/Mathlib/RingTheory/Congruence/Hom.lean +++ b/Mathlib/RingTheory/Congruence/Hom.lean @@ -502,11 +502,20 @@ theorem liftₐ_range (H : c ≤ ker f.toRingHom) : /-- Homomorphisms on the quotient of a ring by a ring congruence relation are equal if they are equal on elements that are coercions from the ring. -/ -@[ext high] -- This should have higher priority than `AlgHom.ext` +-- This should have higher priority than `AlgHom.ext`, but lower than any types implemented with +-- `Quotient`, as `ext` is lax with reducibility. +@[ext 1100] theorem Quotient.hom_extₐ {f g : c.Quotient →ₐ[R] P} (h : f.comp (c.mkₐ R) = g.comp (c.mkₐ R)) : f = g := DFunLike.ext _ _ <| c.mk'_surjective.forall.mpr fun x ↦ by exact congr($h x) +/-- `liftₐ` as an equivalence. -/ +@[simps] +def liftₐEquiv (c : RingCon M) : + { f : M →ₐ[R] P // c ≤ ker (f : M →+* P)} ≃ (c.Quotient →ₐ[R] P) where + toFun f := liftₐ c f.1 f.2 + invFun F := ⟨F.comp (c.mkₐ R), fun x y h => congr(F $(Quotient.sound h))⟩ + variable (f) in /-- The homomorphism induced on the quotient of a ring by the kernel of a ring homomorphism. -/ def kerLiftₐ : (ker f.toRingHom).Quotient →ₐ[R] P := diff --git a/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean b/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean index b5da30718aae74..3549203e60bb03 100644 --- a/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean +++ b/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean @@ -6,7 +6,8 @@ Authors: Antoine Chambert-Loir, María Inés de Frutos—Fernández module public import Mathlib.Algebra.MvPolynomial.Eval -public import Mathlib.Algebra.RingQuot +public import Mathlib.RingTheory.Congruence.Hom +public import Mathlib.RingTheory.Congruence.BigOperators public import Mathlib.RingTheory.DividedPowers.Basic /-! @@ -25,7 +26,7 @@ divided powers (`DividedPowerAlgebra.lift`). divided power algebra. * `DividedPowerAlgebra R M`: the universal divided power algebra of the `R`-module `M`, - defined as `RingQuot` of `DividedPowerAlgebra.Rel R M`. + defined as `RingCon.Quotient` of `DividedPowerAlgebra.ringCon R M`. * `DividedPowerAlgebra.dp R n m`: for `n : ℕ` and `m : M`, this is the equivalence class of `MvPolynomial.X (⟨n, m⟩)` in `DividedPowerAlgebra R M`. @@ -68,9 +69,9 @@ divided powers (`DividedPowerAlgebra.lift`). noncomputable section -open Finset Ideal MvPolynomial RingQuot +open Finset Ideal MvPolynomial -variable (R M : Type*) [CommSemiring R] [AddCommMonoid M] [Module R M] +variable (α R M : Type*) [CommSemiring R] [AddCommMonoid M] [Module R M] namespace DividedPowerAlgebra @@ -87,13 +88,16 @@ inductive Rel : MvPolynomial (ℕ × M) R → MvPolynomial (ℕ × M) R → Prop /-- The ideal of `MvPolynomial (ℕ × M) R` generated by `Rel`. -/ def RelI : Ideal (MvPolynomial (ℕ × M) R) := ofRel (DividedPowerAlgebra.Rel R M) +/-- The congruence generated by `Rel`. -/ +def ringCon : RingCon (MvPolynomial (ℕ × M) R) := ringConGen (DividedPowerAlgebra.Rel R M) + end DividedPowerAlgebra /-- The divided power algebra of a module M is defined as the ring quotient of the polynomial ring in the variables `ℕ × M` by the ring relation defined by `DividedPowerAlgebra.Rel`. We will later show that that `DividedPowerAlgebra R M` has divided powers. It satisfies a weak universal property for morphisms to rings with divided powers. -/ -abbrev DividedPowerAlgebra := RingQuot (DividedPowerAlgebra.Rel R M) +abbrev DividedPowerAlgebra := DividedPowerAlgebra.ringCon R M |>.Quotient namespace DividedPowerAlgebra @@ -101,59 +105,58 @@ open MvPolynomial variable {R M} -lemma mkAlgHom_surjective : Function.Surjective (mkAlgHom R (Rel R M)) := - RingQuot.mkAlgHom_surjective _ _ +lemma mkAlgHom_surjective : Function.Surjective (RingCon.mkₐ R (ringCon R M)) := + Quotient.mk_surjective + +@[simp] +lemma coe_C (a : R) : + ↑(C (σ := ℕ × M) a) = algebraMap R (DividedPowerAlgebra R M) a := by + rw [← MvPolynomial.algebraMap_eq, RingCon.coe_algebraMap] +@[deprecated coe_C (since := "2026-06-19")] lemma mkAlgHom_C (a : R) : - mkAlgHom R (Rel R M) (C a) = algebraMap R (DividedPowerAlgebra R M) a := by + RingCon.mkₐ R (ringCon R M) (C a) = algebraMap R (DividedPowerAlgebra R M) a := by rw [← MvPolynomial.algebraMap_eq, AlgHom.commutes] +@[deprecated coe_C (since := "2026-06-19")] lemma mkRingHom_C (a : R) : - mkRingHom (Rel R M) (C a) = algebraMap R (DividedPowerAlgebra R M) a := by - rw [← mkAlgHom_C, mkAlgHom, AlgHom.coe_mk] + RingCon.mk' (ringCon R M) (C a) = algebraMap R (DividedPowerAlgebra R M) a := + mkAlgHom_C _ variable (R) in /-- `dp R n m` is the equivalence class of `X (⟨n, m⟩)` in `DividedPowerAlgebra R M`. -/ -def dp (n : ℕ) (m : M) : DividedPowerAlgebra R M := mkAlgHom R (Rel R M) (X ⟨n, m⟩) +def dp (n : ℕ) (m : M) : DividedPowerAlgebra R M := ↑(X (n, m) : MvPolynomial (ℕ × M) R) theorem dp_def (n : ℕ) (m : M) : - dp R n m = mkAlgHom R (Rel R M) (X ⟨n, m⟩) := rfl + dp R n m = ↑(X (n, m) : MvPolynomial (ℕ × M) R) := rfl protected theorem induction_on' {P : DividedPowerAlgebra R M → Prop} (f : DividedPowerAlgebra R M) - (h_C : ∀ a, P (mkAlgHom R (Rel R M) (C a))) (h_add : ∀ f g, P f → P g → P (f + g)) + (h_C : ∀ a, P (C a : MvPolynomial (ℕ × M) R)) (h_add : ∀ f g, P f → P g → P (f + g)) (h_dp : ∀ (f : DividedPowerAlgebra R M) (n : ℕ) (m : M), P f → P (f * dp R n m)) : P f := by - obtain ⟨F, hf⟩ := RingQuot.mkRingHom_surjective (DividedPowerAlgebra.Rel R M) f - rw [← hf] - induction F using MvPolynomial.induction_on generalizing f with - | C a => - convert! h_C a using 1 - rw [mkAlgHom, AlgHom.coe_mk] + induction f using Quot.induction_on with | _ F + dsimp + induction F using MvPolynomial.induction_on with + | C a => exact h_C a | add g1 g2 hg1 hg2 => - rw [map_add] - exact h_add _ _ (hg1 ((mkRingHom (Rel R M)) g1) rfl) (hg2 ((mkRingHom (Rel R M)) g2) rfl) + rw [RingCon.coe_add] + exact h_add _ _ hg1 hg2 | mul_X g nm h => - have h' : (mkRingHom (Rel R M)) (X nm) = dp R nm.1 nm.2 := by - simp only [dp_def, Prod.mk.eta, mkAlgHom, AlgHom.coe_mk] - rw [_root_.map_mul, h'] - exact h_dp _ _ _ (h (mkRingHom (Rel R M) g) rfl) + rw [RingCon.coe_mul] + exact h_dp _ _ _ h @[elab_as_elim] protected theorem induction_on {P : DividedPowerAlgebra R M → Prop} (f : DividedPowerAlgebra R M) (C : ∀ a, P (algebraMap R _ a)) (add : ∀ f g, P f → P g → P (f + g)) (dp : ∀ (f : DividedPowerAlgebra R M) (n : ℕ) (m : M), P f → P (f * dp R n m)) : P f := - DividedPowerAlgebra.induction_on' f (fun a ↦ by rw [mkAlgHom_C]; exact C a) add dp - -theorem dp_eq_mkRingHom (n : ℕ) (m : M) : - dp R n m = mkRingHom (Rel R M) (X (⟨n, m⟩)) := by - simp [dp, mkRingHom, mkAlgHom] + DividedPowerAlgebra.induction_on' f C add dp theorem dp_zero {m : M} : dp R 0 m = 1 := by - rw [dp_def, ← map_one (mkAlgHom R (Rel R M))] - exact RingQuot.mkAlgHom_rel R Rel.zero + rw [dp_def, ← RingCon.coe_one] + exact Quotient.sound <| RingCon.le_ringConGen _ _ Rel.zero theorem dp_smul {r : R} {n : ℕ} {m : M} : dp R n (r • m) = r ^ n • dp R n m := by - rw [dp_def, dp_def, ← map_smul] - exact mkAlgHom_rel R Rel.smul + rw [dp_def, dp_def, ← RingCon.coe_smul] + exact Quotient.sound <| RingCon.le_ringConGen _ _ Rel.smul theorem dp_null {n : ℕ} : dp R n (0 : M) = if n = 0 then 1 else 0 := by cases Nat.eq_zero_or_pos n with @@ -168,14 +171,13 @@ theorem dp_null_of_ne_zero {n : ℕ} (hn : n ≠ 0) : dp R n (0 : M) = 0 := by theorem dp_mul {n p : ℕ} {m : M} : dp R n m * dp R p m = (n + p).choose n • dp R (n + p) m := by - simp only [dp_def, ← _root_.map_mul, ← map_nsmul] - exact mkAlgHom_rel R Rel.mul + simp only [dp_def, ← RingCon.coe_mul, ← RingCon.coe_nsmul] + exact Quotient.sound <| RingCon.le_ringConGen _ _ Rel.mul theorem dp_add {n : ℕ} {x y : M} : dp R n (x + y) = (antidiagonal n).sum fun k ↦ dp R k.1 x * dp R k.2 y := by - simp only [dp_def] - rw [mkAlgHom_rel (A := MvPolynomial (ℕ × M) R) R Rel.add, map_sum, - Finset.sum_congr rfl (fun k _ ↦ by rw [_root_.map_mul])] + simp_rw [dp_def, ← RingCon.coe_mul, ← RingCon.coe_finsetSum] + exact Quotient.sound <| RingCon.le_ringConGen _ _ Rel.add theorem dp_sum {ι : Type*} [DecidableEq ι] (s : Finset ι) (q : ℕ) (x : ι → M) : dp R q (s.sum x) = @@ -317,7 +319,9 @@ def lift' {f : ℕ × M → A} (hf_zero : ∀ m, f (0, m) = 1) (hf_mul : ∀ n p m, f ⟨n, m⟩ * f ⟨p, m⟩ = (n + p).choose n • f ⟨n + p, m⟩) (hf_add : ∀ n u v, f ⟨n, u + v⟩ = (antidiagonal n).sum fun (k, l) ↦ f ⟨k, u⟩ * f ⟨l, v⟩) : DividedPowerAlgebra R M →ₐ[R] A := - RingQuot.liftAlgHom R ⟨eval₂AlgHom R f, by exact lift'_imp R M hf_zero hf_smul hf_mul hf_add⟩ + RingCon.liftₐ _ (eval₂AlgHom R f) <| by + grw [ringCon, RingCon.ringConGen_le] + exact lift'_imp R M hf_zero hf_smul hf_mul hf_add @[simp] theorem lift'_apply {f : ℕ × M → A} (hf_zero : ∀ m, f (0, m) = 1) @@ -325,7 +329,7 @@ theorem lift'_apply {f : ℕ × M → A} (hf_zero : ∀ m, f (0, m) = 1) (hf_mul : ∀ n p m, f ⟨n, m⟩ * f ⟨p, m⟩ = (n + p).choose n • f ⟨n + p, m⟩) (hf_add : ∀ n u v, f ⟨n, u + v⟩ = (antidiagonal n).sum fun (k, l) ↦ f ⟨k, u⟩ * f ⟨l, v⟩) (p : MvPolynomial (ℕ × M) R) : - lift' hf_zero hf_smul hf_mul hf_add (mkAlgHom R (Rel R M) p) = aeval f p := by + lift' hf_zero hf_smul hf_mul hf_add ↑p = aeval f p := by simp [lift', aeval_eq_eval₂Hom] @[simp] @@ -354,7 +358,7 @@ variable {g} @[simp] theorem lift_apply (p : MvPolynomial (ℕ × M) R) : - lift hI g hg (mkAlgHom R (Rel R M) p) = aeval (fun nm : ℕ × M ↦ hI.dpow nm.1 (g nm.2)) p := by + lift hI g hg ↑p = aeval (fun nm : ℕ × M ↦ hI.dpow nm.1 (g nm.2)) p := by rw [lift, lift'_apply] @[simp] @@ -421,7 +425,7 @@ def map : DividedPowerAlgebra R M →ₐ[R] DividedPowerAlgebra S N := @[simp] theorem map_apply {p : MvPolynomial (ℕ × M) R} : - map S f (mkAlgHom R (Rel R M) p) = aeval (fun nm ↦ dp S nm.fst (f nm.snd)) p := by + map S f ↑p = aeval (fun nm ↦ dp S nm.fst (f nm.snd)) p := by rw [map, lift'_apply] @[simp] @@ -439,7 +443,7 @@ theorem lift_comp_embed : theorem lift_surjective {f : M →ₗ[R] N} (hf : Function.Surjective f) : Function.Surjective (map R f) := by rw [← AlgHom.range_eq_top, ← Algebra.map_top (map R f), eq_top_iff, - ← (AlgHom.range_eq_top (mkAlgHom R (Rel R N))).mpr mkAlgHom_surjective, + ← (AlgHom.range_eq_top (RingCon.mkₐ R (ringCon R N))).mpr mkAlgHom_surjective, ← Algebra.map_top, (Subalgebra.gc_map_comap _).le_iff_le, ← MvPolynomial.adjoin_range_X, Algebra.adjoin_le_iff] intro @@ -447,7 +451,7 @@ theorem lift_surjective {f : M →ₗ[R] N} (hf : Function.Surjective f) : rintro ⟨n, m, rfl⟩ obtain ⟨l, rfl⟩ := hf m simp only [Algebra.map_top, Subalgebra.coe_comap, AlgHom.coe_range, Set.mem_preimage, - Set.mem_range] + Set.mem_range, RingCon.mkₐ_apply] use dp R n l rw [map_apply_dp, dp] From b4384330e5b9d7268e11d3136e669205994fa74a Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Tue, 23 Jun 2026 03:43:55 +0000 Subject: [PATCH 0271/1300] fix(cache): carry cache misses across 'get' layers instead of using file existence as a proxy for 'done' (#40817) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `lake exe cache get!` on a fork that already has a full local cache re-downloads only from `master` and never falls through to `forks`, so a corrupt fork-only `.ltar` is never refreshed. Between containers, the next round's file set was recomputed with `filterExists` (is the `.ltar` on disk?). Under force, that proxy is wrong: a file served only by a later container whose `.ltar` is already cached looks "done" after the first round, so `remaining` empties and the chain stops. Carry forward the files a round did **not** serve instead — using the set of hashes it actually fetched — independent of disk state. Follow-up to #40035. --- Cache/Requests.lean | 122 ++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 43 deletions(-) diff --git a/Cache/Requests.lean b/Cache/Requests.lean index ddd52c5000ef8d..708ca2515f4c46 100644 --- a/Cache/Requests.lean +++ b/Cache/Requests.lean @@ -414,24 +414,54 @@ def mkGetConfigContent (container : Option Container) (repo containerURL : Strin pure <| acc ++ s!"url = {mkFileURL container repo containerURL fileName scope?}\n\ -o {(IO.CACHEDIR / (fileName ++ ".part")).toString.quote}\n" +/-- +Whether an HTTP status returned for a single-file read should be treated as a +cache miss (fall through to the next container in the chain) rather than a +transfer failure worth reporting. + +`404` is always a miss. A `403` is a miss only when `treatForbiddenAsMiss` is +set, which callers do for the `legacy` container: when its public read access is +revoked ahead of retirement it answers reads with `403`, and old clients whose +chain still lists `legacy` should fall through quietly instead of printing a +per-file transfer failure. Any other status is a real failure. +-/ +def isCacheMissStatus (httpCode : Nat) (treatForbiddenAsMiss : Bool) : Bool := + httpCode == 404 || (httpCode == 403 && treatForbiddenAsMiss) + +/-- Outcome of a single serial download: the file arrived (`served`), the server +returned a cache miss that should fall through to the next container (`miss`), or +the transfer failed for another reason that should drive the exit code +(`failed`). The parallel path draws the same distinction through +`TransferState.failed` and `isCacheMissStatus`. -/ +inductive DownloadOutcome + | served + | miss + | failed + /-- Calls `curl` to download a single file from a specific container to `CACHEDIR` -(`.cache`). Returns `true` on success, `false` on any error including 404. -`scope?` is the per-round SHA scope (see `mkGetConfigContent`). -/ +(`.cache`). `scope?` is the per-round SHA scope (see `mkGetConfigContent`). +`treatForbiddenAsMiss` mirrors the parallel path: a `legacy` `403` (public read +access revoked ahead of retirement) is a miss, not a failure. -/ def downloadFile (container : Option Container) (repo containerURL : String) - (hash : UInt64) (scope? : Option String) : IO Bool := do + (hash : UInt64) (scope? : Option String) (treatForbiddenAsMiss : Bool := false) : + IO DownloadOutcome := do let fileName := hash.asLTar let url := mkFileURL container repo containerURL fileName scope? let path := IO.CACHEDIR / fileName let partFileName := fileName ++ ".part" let partPath := IO.CACHEDIR / partFileName let out ← IO.Process.output - { cmd := (← IO.getCurl), args := #[url, "--fail", "--silent", "-o", partPath.toString] } + { cmd := (← IO.getCurl), + args := #[url, "--fail", "--silent", "--write-out", "%{http_code}", + "-o", partPath.toString] } if out.exitCode = 0 then IO.FS.rename partPath path - pure true - else - IO.FS.removeFile partPath - pure false + return .served + IO.FS.removeFile partPath + -- `--fail` exits nonzero on any HTTP error; the written-out status tells a 404 + -- miss apart from a real transfer failure (a connection error reports `000`). + let httpCode := out.stdout.trimAscii.toNat?.getD 0 + return if isCacheMissStatus httpCode treatForbiddenAsMiss then .miss else .failed /-- Extract hash from filename (e.g., "/path/to/.cache/00012345.ltar" → 0x12345). Handles both `.ltar` and `.ltar.part` files using `FilePath.fileStem`. -/ @@ -498,20 +528,6 @@ def dispatchDecompBatch (pending : Array (FilePath × Lean.Name)) (config : Deco let task ← IO.asTask (decompressBatch pending config.force config.isMathlibRoot config.mathlibDepPath) return some task -/-- -Whether an HTTP status returned for a single-file read should be treated as a -cache miss (fall through to the next container in the chain) rather than a -transfer failure worth reporting. - -`404` is always a miss. A `403` is a miss only when `treatForbiddenAsMiss` is -set, which callers do for the `legacy` container: when its public read access is -revoked ahead of retirement it answers reads with `403`, and old clients whose -chain still lists `legacy` should fall through quietly instead of printing a -per-file transfer failure. Any other status is a real failure. --/ -def isCacheMissStatus (httpCode : Nat) (treatForbiddenAsMiss : Bool) : Bool := - httpCode == 404 || (httpCode == 403 && treatForbiddenAsMiss) - /-- Whether an HTTP status is the one Azure returns for a blob that already exists, which a non-overwrite `put` (`If-None-Match: *`) hits when it declines to @@ -527,8 +543,11 @@ def monitorCurl (args : Array String) (size : Nat) (caption : String) (speedVar : String) (removeOnError := false) (decompConfig : Option DecompConfig := none) (treatForbiddenAsMiss : Bool := false) - (treatExistsAsSkip : Bool := false) : IO TransferState := do + (treatExistsAsSkip : Bool := false) : IO (TransferState × Std.HashSet UInt64) := do let useAnsi := (← IO.getEnv "TERM").isSome + -- Hashes of the files this pass fetched, used to decide what the next + -- container in the chain still needs to retry. + let servedRef ← IO.mkRef (∅ : Std.HashSet UInt64) let mkStatus (s : TransferState) : String := Id.run do let speedStr := if s.speed != 0 then @@ -561,9 +580,11 @@ def monitorCurl (args : Array String) (size : Nat) if (← System.FilePath.pathExists fn) && fn.endsWith ".part" then let finalPath := (fn.dropEnd 5).copy IO.FS.rename fn finalPath + let hash? := hashFromFileName finalPath + if let some hash := hash? then servedRef.modify (·.insert hash) -- Add to decompression queue if enabled if let some config := decompConfig then - let some hash := hashFromFileName finalPath | do + let some hash := hash? | do IO.eprintln s!"Warning: Failed to extract hash from filename: {finalPath}" decompFailed := decompFailed + 1 let some mod := config.hashToMod[hash]? | do @@ -633,18 +654,19 @@ def monitorCurl (args : Array String) (size : Nat) if s.done > 0 then -- to avoid confusingly moving on without finishing the count IO.eprintln (mkStatus s) - return s + return (s, ← servedRef.get) /-- Run one container's download pass for the given hash map. Returns the -`TransferState` produced by `monitorCurl` (or a synthesized empty state in -serial mode). Side effect: any files successfully fetched are written to -`CACHEDIR` with their final names. -/ +`TransferState` from `monitorCurl` (synthesized in serial mode, where it carries +only the transfer-failure count) and the set of hashes it fetched, so the caller +can carry the rest to the next container. Side effect: any files successfully +fetched are written to `CACHEDIR` with their final names. -/ private def downloadFilesFromContainer (container : Option Container) (repo containerURL : String) (hashMap : IO.ModuleHashMap) (parallel : Bool) (decompConfig : Option DecompConfig) (scope? : Option String) : - IO (Nat × TransferState) := do + IO (TransferState × Std.HashSet UInt64) := do let size := hashMap.size if parallel then IO.FS.writeFile IO.CURLCFG (← mkGetConfigContent container repo containerURL hashMap scope?) @@ -657,16 +679,27 @@ private def downloadFilesFromContainer -- of retirement; treat that as a miss so the chain stays quiet for clients -- whose chain still lists it. let treatForbiddenAsMiss := container == some Container.legacy - let s ← monitorCurl args size "Downloaded" "speed_download" (removeOnError := true) + let (s, served) ← monitorCurl args size "Downloaded" "speed_download" (removeOnError := true) decompConfig (treatForbiddenAsMiss := treatForbiddenAsMiss) IO.FS.removeFile IO.CURLCFG - return (s.failed, s) + return (s, served) else + -- Mirror the parallel path's miss/failure split: a `legacy` 403 is a miss. + let treatForbiddenAsMiss := container == some Container.legacy let r ← hashMap.foldM (init := []) fun acc _ hash => do - pure <| (← IO.asTask do downloadFile container repo containerURL hash scope?) :: acc - let failed := r.foldl (init := 0) fun f t => if let .ok true := t.get then f else f + 1 - let emptyState : TransferState := ⟨0, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ - return (failed, emptyState) + pure <| (hash, ← IO.asTask do + downloadFile container repo containerURL hash scope? treatForbiddenAsMiss) :: acc + -- Served hashes carry the remaining files to the next container; hard + -- failures (anything but a 404/legacy-403 miss, including a task that threw) + -- feed `TransferState.failed`, so they drive the exit code exactly as the + -- parallel path threads its own `failed` count. + let (served, failed) := r.foldl (init := ((∅ : Std.HashSet UInt64), 0)) + fun (served, failed) (hash, t) => + match t.get with + | .ok .served => (served.insert hash, failed) + | .ok .miss => (served, failed) + | _ => (served, failed + 1) + return (⟨0, 0, failed, 0, 0, #[], none, 0, 0, 0⟩, served) /-- Expand the trust-ordered container list into the concrete download rounds to run, each carrying the SHA scope to read at. A round is @@ -749,6 +782,8 @@ def downloadFiles let unsafeMode := !unsafeScopes.isEmpty let mut remaining := hashMap let mut finalState : TransferState := ⟨0, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ + -- Hard transfer failures (not 404 misses) drive the exit code; misses are + -- normal and instead surface as the "not found" hint keyed on `remaining`. let mut downloadFailed := 0 -- For the `--unsafe` summary: how many files each scoped (forks) round supplied, -- attributed by the drop in `remaining` across that round. @@ -758,13 +793,14 @@ def downloadFiles let scopeNote := match roundScope? with | some s => s!" (scope {s})" | none => "" IO.println s!"Attempting to download {remaining.size} file(s) from {repo} cache at {url}{scopeNote}" let before := remaining.size - let (failed, s) ← downloadFilesFromContainer container? repo url remaining parallel decompConfig roundScope? - -- Carry forward the decompression-related state across container rounds. - -- Counter fields (success/failed/done) reflect only the last round; we - -- aggregate `downloadFailed` separately below. + let (s, served) ← downloadFilesFromContainer container? repo url remaining parallel decompConfig roundScope? + -- Keep the latest round's pipeline state and transfer-failure count for the + -- finalization and exit-code logic below. Drop the files this round served so + -- the next container only retries genuine misses, regardless of what is + -- already on disk. finalState := s - downloadFailed := failed - remaining ← remaining.filterExists false + downloadFailed := s.failed + remaining := remaining.filter fun _ hash => !served.contains hash if unsafeMode then if let some sha := roundScope? then scopeServed := scopeServed.push (sha, before - remaining.size) @@ -782,7 +818,7 @@ def downloadFiles if remaining.size > 0 then IO.eprintln s!" {remaining.size} file(s) still missing after all scopes." - if warnOnMissing && downloadFailed > 0 && parallel then + if warnOnMissing && !remaining.isEmpty then IO.eprintln "Warning: some files were not found in the cache." IO.eprintln "This usually means that your local checkout of mathlib4 has diverged from upstream." IO.eprintln "" @@ -1049,7 +1085,7 @@ def putFilesAbsolute "-X", "PUT", "--parallel", "--retry", "5", -- there seem to be some intermittent failures "--write-out", "%{json}\n", "--config", tempConfigFilePath.toString] - let s ← monitorCurl args size "Uploaded" "speed_upload" (removeOnError := false) + let (s, _) ← monitorCurl args size "Uploaded" "speed_upload" (removeOnError := false) (decompConfig := none) (treatExistsAsSkip := !overwrite) IO.FS.removeFile tempConfigFilePath -- Surface genuine upload failures. Already-present blobs (409/412 on a From e3c61a827191573a57a3b65edb40923d22a52de0 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 23 Jun 2026 07:34:01 +0000 Subject: [PATCH 0272/1300] chore(Translate): turn off `existingAttributeWarning` for `to_dual/to_additive existing` (#40357) The existing attribute warning can often come up in `to_dual existing`/`to_additive existing`, which is kind of annoying. This PR turns off the warning in that case. Note that it was previously already turned off for `to_dual self` and `to_dual none`. This lets us remove all but one of the linter exceptions. --- Mathlib/Algebra/BigOperators/Group/List/Basic.lean | 1 - Mathlib/Algebra/BigOperators/Group/List/Defs.lean | 1 - Mathlib/Algebra/Group/Basic.lean | 11 ++++------- Mathlib/Algebra/Group/Graph.lean | 2 -- Mathlib/Algebra/Symmetrized.lean | 2 -- Mathlib/CategoryTheory/Equivalence.lean | 1 - Mathlib/CategoryTheory/Iso.lean | 3 --- Mathlib/CategoryTheory/Monoidal/Grp.lean | 1 - Mathlib/CategoryTheory/NatIso.lean | 4 ---- Mathlib/Order/RelClasses.lean | 1 - Mathlib/Tactic/ToDual.lean | 1 - Mathlib/Tactic/Translate/Core.lean | 6 +++--- 12 files changed, 7 insertions(+), 27 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List/Basic.lean b/Mathlib/Algebra/BigOperators/Group/List/Basic.lean index 1f5a5ef9210ca9..525adfce9ad649 100644 --- a/Mathlib/Algebra/BigOperators/Group/List/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/List/Basic.lean @@ -249,7 +249,6 @@ lemma prod_map_erase [DecidableEq α] (f : α → M) {a} : @[to_additive] lemma Perm.prod_eq (h : Perm l₁ l₂) : prod l₁ = prod l₂ := h.foldr_op_eq -set_option linter.existingAttributeWarning false in attribute [to_additive existing] prod_reverse @[to_additive] diff --git a/Mathlib/Algebra/BigOperators/Group/List/Defs.lean b/Mathlib/Algebra/BigOperators/Group/List/Defs.lean index dc2a0d7b276cc6..c6417cc1f53bc5 100644 --- a/Mathlib/Algebra/BigOperators/Group/List/Defs.lean +++ b/Mathlib/Algebra/BigOperators/Group/List/Defs.lean @@ -23,7 +23,6 @@ variable {ι M N : Type*} namespace List section Defs -set_option linter.existingAttributeWarning false in attribute [to_additive existing] prod prod_nil prod_cons prod_one_cons prod_append prod_concat prod_flatten prod_eq_foldl diff --git a/Mathlib/Algebra/Group/Basic.lean b/Mathlib/Algebra/Group/Basic.lean index 823ca65355f567..c28a5efa016538 100644 --- a/Mathlib/Algebra/Group/Basic.lean +++ b/Mathlib/Algebra/Group/Basic.lean @@ -31,25 +31,22 @@ variable {α β G M : Type*} section ite variable [Pow α β] -@[to_additive (attr := simp) dite_smul] +@[to_additive (attr := simp, to_additive) dite_smul] lemma pow_dite (p : Prop) [Decidable p] (a : α) (b : p → β) (c : ¬ p → β) : a ^ (if h : p then b h else c h) = if h : p then a ^ b h else a ^ c h := by split_ifs <;> rfl -@[to_additive (attr := simp) smul_dite] +@[to_additive (attr := simp, to_additive) smul_dite] lemma dite_pow (p : Prop) [Decidable p] (a : p → α) (b : ¬ p → α) (c : β) : (if h : p then a h else b h) ^ c = if h : p then a h ^ c else b h ^ c := by split_ifs <;> rfl -@[to_additive (attr := simp) ite_smul] +@[to_additive (attr := simp, to_additive) ite_smul] lemma pow_ite (p : Prop) [Decidable p] (a : α) (b c : β) : a ^ (if p then b else c) = if p then a ^ b else a ^ c := pow_dite _ _ _ _ -@[to_additive (attr := simp) smul_ite] +@[to_additive (attr := simp, to_additive) smul_ite] lemma ite_pow (p : Prop) [Decidable p] (a b : α) (c : β) : (if p then a else b) ^ c = if p then a ^ c else b ^ c := dite_pow _ _ _ _ -set_option linter.existingAttributeWarning false in -attribute [to_additive (attr := simp)] dite_smul smul_dite ite_smul smul_ite - end ite section Semigroup diff --git a/Mathlib/Algebra/Group/Graph.lean b/Mathlib/Algebra/Group/Graph.lean index afff321eb2af61..4253578e4e5926 100644 --- a/Mathlib/Algebra/Group/Graph.lean +++ b/Mathlib/Algebra/Group/Graph.lean @@ -51,7 +51,6 @@ def mgraph (f : G →* H) : Submonoid (G × H) where -- TODO: Can `to_additive` be smarter about `simps`? attribute [simps! coe] mgraph attribute [simps! coe] AddMonoidHom.mgraph -set_option linter.existingAttributeWarning false in attribute [to_additive existing] coe_mgraph @[to_additive (attr := simp)] @@ -163,7 +162,6 @@ def graph (f : G →* H) : Subgroup (G × H) where -- TODO: Can `to_additive` be smarter about `simps`? attribute [simps! coe toSubmonoid] graph attribute [simps! coe toAddSubmonoid] AddMonoidHom.graph -set_option linter.existingAttributeWarning false in attribute [to_additive existing] coe_graph graph_toSubmonoid @[to_additive] diff --git a/Mathlib/Algebra/Symmetrized.lean b/Mathlib/Algebra/Symmetrized.lean index 87503423a78036..d2127d0905153b 100644 --- a/Mathlib/Algebra/Symmetrized.lean +++ b/Mathlib/Algebra/Symmetrized.lean @@ -183,12 +183,10 @@ theorem sym_mul_sym [Mul α] [Add α] [One α] [OfNat α 2] [Invertible (2 : α) sym a * sym b = sym (⅟2 * (a * b + b * a)) := rfl -set_option linter.existingAttributeWarning false in @[simp, to_additive existing] theorem sym_inv [Inv α] (a : α) : sym a⁻¹ = (sym a)⁻¹ := rfl -set_option linter.existingAttributeWarning false in @[simp, to_additive existing] theorem unsym_inv [Inv α] (a : αˢʸᵐ) : unsym a⁻¹ = (unsym a)⁻¹ := rfl diff --git a/Mathlib/CategoryTheory/Equivalence.lean b/Mathlib/CategoryTheory/Equivalence.lean index ae7d7d853f69c6..977bf5da0969a4 100644 --- a/Mathlib/CategoryTheory/Equivalence.lean +++ b/Mathlib/CategoryTheory/Equivalence.lean @@ -214,7 +214,6 @@ def mkIso {e f : C ≌ D} (η : e.functor ≅ f.functor) : e ≅ f where hom := mkHom η.hom inv := mkHom η.inv -set_option linter.existingAttributeWarning false in attribute [to_dual existing mkIso_inv] mkIso_hom variable (C D) in diff --git a/Mathlib/CategoryTheory/Iso.lean b/Mathlib/CategoryTheory/Iso.lean index 0807fc2e94279c..c7df4b48b8681a 100644 --- a/Mathlib/CategoryTheory/Iso.lean +++ b/Mathlib/CategoryTheory/Iso.lean @@ -117,7 +117,6 @@ def refl (X : C) : X ≅ X where hom := 𝟙 X inv := 𝟙 X -set_option linter.existingAttributeWarning false in attribute [to_dual existing refl_inv] refl_hom instance : Inhabited (X ≅ X) := ⟨Iso.refl X⟩ @@ -133,7 +132,6 @@ def trans (α : X ≅ Y) (β : Y ≅ Z) : X ≅ Z where hom := α.hom ≫ β.hom inv := β.inv ≫ α.inv -set_option linter.existingAttributeWarning false in attribute [to_dual existing trans_inv] trans_hom @[simps] @@ -473,7 +471,6 @@ def mapIso (F : C ⥤ D) {X Y : C} (i : X ≅ Y) : F.obj X ≅ F.obj Y where hom := F.map i.hom inv := F.map i.inv -set_option linter.existingAttributeWarning false in attribute [to_dual existing mapIso_inv] mapIso_hom @[simp] diff --git a/Mathlib/CategoryTheory/Monoidal/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Grp.lean index b532109706244c..c515ce6f7c0a53 100644 --- a/Mathlib/CategoryTheory/Monoidal/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Grp.lean @@ -57,7 +57,6 @@ namespace GrpObj attribute [reassoc (attr := simp)] left_inv right_inv attribute [reassoc (attr := simp)] AddGrpObj.left_neg AddGrpObj.right_neg -set_option linter.existingAttributeWarning false in attribute [to_additive existing] left_inv left_inv_assoc right_inv right_inv_assoc @[to_additive] diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index 6737823ba25dc2..dac61bd6dd46be 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -55,7 +55,6 @@ def app {F G : C ⥤ D} (α : F ≅ G) (X : C) : hom := α.hom.app X inv := α.inv.app X -set_option linter.existingAttributeWarning false in attribute [to_dual existing app_inv] app_hom @[reassoc +to_dual (attr := simp), grind =] @@ -191,11 +190,9 @@ def ofComponents (app : ∀ X : C, F.obj X ≅ G.obj X) exact h } set_option linter.translateOverwrite false in -set_option linter.existingAttributeWarning false in attribute [to_dual existing ofComponents'_inv_app] ofComponents_hom_app set_option linter.translateOverwrite false in -set_option linter.existingAttributeWarning false in attribute [to_dual existing ofComponents'_hom_app] ofComponents_inv_app @[to_dual (attr := simp)] @@ -214,7 +211,6 @@ def hcomp {F G : C ⥤ D} {H I : D ⥤ E} (α : F ≅ G) (β : H ≅ I) : F ⋙ hom := α.hom ◫ β.hom inv := α.inv ◫ β.inv -set_option linter.existingAttributeWarning false in attribute [to_dual existing hcomp_inv] hcomp_hom @[to_dual self] diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index 63bc0a93b2ab8d..93485384b10b30 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -661,7 +661,6 @@ but after translation `instReflLe` becomes `instReflGe : Std.Refl (· ≥ ·)`. theorem Std.ge_refl {α : Type*} [LE α] [inst : @Std.Refl α (· ≥ ·)] (a : α) : a ≤ a := @Std.Refl.refl α (· ≥ ·) inst a -set_option linter.existingAttributeWarning false in attribute [to_dual existing Std.ge_refl] Std.le_refl @[to_dual instIsTransGe] diff --git a/Mathlib/Tactic/ToDual.lean b/Mathlib/Tactic/ToDual.lean index 188b513bd39c32..b0b0650974b835 100644 --- a/Mathlib/Tactic/ToDual.lean +++ b/Mathlib/Tactic/ToDual.lean @@ -24,7 +24,6 @@ to_dual_insert_cast_fun DecidableLT := fun inst a b ↦ inst b a, fun inst a b attribute [to_dual_do_translate] Empty PEmpty Unit PUnit attribute [to_dual_ignore_args 2] Subtype -set_option linter.existingAttributeWarning false in attribute [to_dual self] ge_iff_le gt_iff_lt attribute [to_dual le_of_eq_of_le''] le_of_eq_of_le diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 39e16b28bd0583..c59c285f0cbe5f 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -917,7 +917,7 @@ def targetName (t : TranslateData) (cfg : Config) (src : Name) : CoreM Name := d return src if cfg.none then if cfg.target != .anonymous then - logWarning m!"`{t.attrName} private` ignores the provided name {cfg.target}" + logWarning m!"`{t.attrName} none` ignores the provided name {cfg.target}" return ← withDeclNameForAuxNaming src do mkAuxDeclName <| .mkSimple ("_" ++ t.attrName.toString) -- When re-tagging an existing translation, simply return that existing translation. @@ -1149,8 +1149,8 @@ partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) (relevantArg : RelevantArg) : TermElabM (Array Name) := do -- we only copy the `instance` attribute, since it is nice to directly tag `instance` declarations copyInstanceAttribute src tgt - -- Warn users if the original declaration has an attributee - if !cfg.self && !cfg.none && linter.existingAttributeWarning.get (← getOptions) then + -- Warn users if the original declaration has an attribute + if !cfg.existing && !cfg.none && linter.existingAttributeWarning.get (← getOptions) then let appliedAttrs ← getAllSimpAttrs src if appliedAttrs.size > 0 then let appliedAttrs := ", ".intercalate (appliedAttrs.toList.map toString) From 4d0f80f9459e84794a0663e59280e78742331f3b Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:28:07 +0000 Subject: [PATCH 0273/1300] feat: properly support inferring a model with corners on a `Bundle.TotalSpace` (#40047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support inferring a model with corners on a `Bundle.TotalSpace`, both as the source and target. The current logic was wrong and incomplete. Incomplete, since it only supported inferring a model on the codomain of a map, and wrong as the algorithm used for that had a logic bug. Consider a function `f : N → TotalSpace F V`, from a manifold into the total space of a fibre bundle `V` over a manifold `M`. The correct model with corners to infer on the codomain is `I.prod (𝓘(𝕜, F))` --- where `I` is the model with corners on the base `M` of `V`. Previously, they would always use the model on the domain `N` instead of the model `I` on the bundle's base `M`. This works if `f` were a section of `V`, but is incorrect in general! Instead, determine the model with corners in a principled way (by finding a model on the base): this works in all cases. It also removes the need for the `baseInfo` parameter. --- .../Geometry/Manifold/ContMDiffMFDeriv.lean | 3 +- Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean | 9 +- .../Manifold/MFDeriv/UniqueDifferential.lean | 22 +-- Mathlib/Geometry/Manifold/Notation.lean | 102 +++++----- .../Geometry/Manifold/VectorBundle/Hom.lean | 174 ++++++++---------- .../VectorBundle/MDifferentiable.lean | 46 ++--- .../Manifold/VectorBundle/Riemannian.lean | 40 ++-- .../Notation/PR40447.lean | 96 ++++++++++ 8 files changed, 284 insertions(+), 208 deletions(-) create mode 100644 MathlibTest/DifferentialGeometry/Notation/PR40447.lean diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index fae86ea50365d1..9109509853bc05 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -278,8 +278,7 @@ theorem ContMDiffOn.contMDiffOn_tangentMapWithin let s' : Set (TangentBundle I M) := (π E (TangentSpace I) ⁻¹' s) let b₁ : TangentBundle I M → M := fun p ↦ p.1 let v : Π (y : TangentBundle I M), TangentSpace% (b₁ y) := fun y ↦ y.2 - have hv : ContMDiffWithinAt I.tangent I.tangent m (fun y ↦ (v y : TangentBundle I M)) s' x₀ := - contMDiffWithinAt_id + have hv : CMDiffAt[s'] m (fun y ↦ (v y : TangentBundle I M)) x₀ := contMDiffWithinAt_id let b₂ : TangentBundle I M → M' := f ∘ b₁ have hb₂ : CMDiffAt[s'] m b₂ x₀ := ((hf (b₁ x₀) hx₀).of_le (le_self_add.trans hmn)).comp _ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean index ad87a847c3abef..f0d5d10514ba8c 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean @@ -48,17 +48,18 @@ theorem ModelWithCorners.uniqueMDiffOn {H : Type*} [TopologicalSpace H] theorem writtenInExtChartAt_model_space : writtenInExtChartAt 𝓘(𝕜, E) 𝓘(𝕜, E') x f = f := rfl +variable {f' : TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, E') (f x)} + set_option backward.isDefEq.respectTransparency false in -theorem hasMFDerivWithinAt_iff_hasFDerivWithinAt {f'} : - HasMFDerivWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E') f s x f' ↔ HasFDerivWithinAt f f' s x := by +theorem hasMFDerivWithinAt_iff_hasFDerivWithinAt : + HasMFDerivAt[s] f x f' ↔ HasFDerivWithinAt f f' s x := by simpa only [HasMFDerivWithinAt, and_iff_right_iff_imp, mfld_simps] using HasFDerivWithinAt.continuousWithinAt alias ⟨HasMFDerivWithinAt.hasFDerivWithinAt, HasFDerivWithinAt.hasMFDerivWithinAt⟩ := hasMFDerivWithinAt_iff_hasFDerivWithinAt -theorem hasMFDerivAt_iff_hasFDerivAt {f'} : - HasMFDerivAt 𝓘(𝕜, E) 𝓘(𝕜, E') f x f' ↔ HasFDerivAt f f' x := by +theorem hasMFDerivAt_iff_hasFDerivAt : HasMFDerivAt% f x f' ↔ HasFDerivAt f f' x := by rw [← hasMFDerivWithinAt_univ, hasMFDerivWithinAt_iff_hasFDerivWithinAt, hasFDerivWithinAt_univ] alias ⟨HasMFDerivAt.hasFDerivAt, HasFDerivAt.hasMFDerivAt⟩ := hasMFDerivAt_iff_hasFDerivAt diff --git a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean index 3e0ad20b32c3a2..f85c3efacc4755 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean @@ -139,7 +139,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {Z : M → Type set_option backward.isDefEq.respectTransparency false in private lemma UniqueMDiffWithinAt.bundle_preimage_aux {p : TotalSpace F Z} (hs : UniqueMDiffAt[s] p.proj) (h's : s ⊆ (trivializationAt F Z p.proj).baseSet) : - UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) p := by + UniqueMDiffAt[π F Z ⁻¹' s] p := by suffices ((extChartAt I p.proj).symm ⁻¹' s ∩ range I) ×ˢ univ ⊆ (extChartAt (I.prod 𝓘(𝕜, F)) p).symm ⁻¹' (TotalSpace.proj ⁻¹' s) ∩ range (I.prod 𝓘(𝕜, F)) by let w := (extChartAt (I.prod 𝓘(𝕜, F)) p p).2 @@ -169,27 +169,25 @@ private lemma UniqueMDiffWithinAt.bundle_preimage_aux {p : TotalSpace F Z} /-- In a fiber bundle, the preimage under the projection of a set with unique differentials in the base has unique differentials in the bundle. -/ -theorem UniqueMDiffWithinAt.bundle_preimage {p : TotalSpace F Z} - (hs : UniqueMDiffAt[s] p.proj) : - UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) p := by - suffices UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) - (π F Z ⁻¹' (s ∩ (trivializationAt F Z p.proj).baseSet)) p from this.mono (by simp) +theorem UniqueMDiffWithinAt.bundle_preimage {p : TotalSpace F Z} (hs : UniqueMDiffAt[s] p.proj) : + UniqueMDiffAt[π F Z ⁻¹' s] p := by + suffices UniqueMDiffAt[π F Z ⁻¹' (s ∩ (trivializationAt F Z p.proj).baseSet)] p from + this.mono (by simp) apply UniqueMDiffWithinAt.bundle_preimage_aux (hs.inter _) inter_subset_right - exact IsOpen.mem_nhds (trivializationAt F Z p.proj).open_baseSet + exact (trivializationAt F Z p.proj).open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' p.proj) variable (Z) /-- In a fiber bundle, the preimage under the projection of a set with unique differentials in the base has unique differentials in the bundle. Version with a point `⟨b, x⟩`. -/ -theorem UniqueMDiffWithinAt.bundle_preimage' {b : M} (hs : UniqueMDiffAt[s] b) - (x : Z b) : UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) ⟨b, x⟩ := +theorem UniqueMDiffWithinAt.bundle_preimage' {b : M} (hs : UniqueMDiffAt[s] b) (x : Z b) : + UniqueMDiffAt[π F Z ⁻¹' s] ⟨b, x⟩ := hs.bundle_preimage (p := ⟨b, x⟩) /-- In a fiber bundle, the preimage under the projection of a set with unique differentials in the base has unique differentials in the bundle. -/ -theorem UniqueMDiffOn.bundle_preimage (hs : UniqueMDiff[s]) : - UniqueMDiffOn (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) := fun _p hp ↦ - (hs _ hp).bundle_preimage +theorem UniqueMDiffOn.bundle_preimage (hs : UniqueMDiff[s]) : UniqueMDiff[π F Z ⁻¹' s] := + fun _p hp ↦ (hs _ hp).bundle_preimage end UniqueMDiff diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 0ed3b4eb3b185e..f5618f953402fb 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -331,6 +331,29 @@ private def tryStrategy (strategyDescr : MessageData) (x : TermElabM FindModelRe s.restore true return none +/-- Given an `Expr`ession `e`, try to find a `NormedSpace` instance on `e` and return the +underlying base field. Search local instances, before recursing into product and bundled +continuous linear maps. -/ +partial def guessBaseFieldForNormedSpace (e : Expr) : TermElabM <| Option Expr := do + if let some k ← findFromLocalInstance e then return k + match_expr e with + | Prod E _F => + guessBaseFieldForNormedSpace E + | _ => + try + let (_k, E, _F) ← isCLMReduciblyDefeqCoefficients e + guessBaseFieldForNormedSpace E + catch _e => + findFromLocalInstance e +where findFromLocalInstance (e : Expr) : TermElabM <| Option Expr := do + findSomeLocalInstanceOf? ``NormedSpace fun _ type ↦ do + match_expr type with + | NormedSpace K E _ _ => + if ← withReducible (pureIsDefEq E e) then + trace[Elab.DiffGeo.MDiff] "`{e}` is a normed field over `{K}`"; return some K + else return none + | _ => pure none + set_option linter.style.emptyLine false in -- linter false positive /-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), using the local context to infer the appropriate instance. This supports the following cases: @@ -355,11 +378,6 @@ Return an expression describing the found model with corners, together with info whether the model is the trivial model with corners on a normed space. (This is important for forming products of models.) -`baseInfo` is only used for the first case, a model with corners on the total space of the vector -bundle. In this case, it contains a pair of expressions `(e, i)` describing the type of the base -and the model with corners on the base: these are required to construct the right model with -corners. - Note that the matching on `e` does not see through reducibility (e.g. we distinguish the `abbrev` `TangentBundle` from its definition), so `whnfR` should not be run on `e` prior to calling `findModel` on it. @@ -368,8 +386,7 @@ This implementation is not maximally robust yet. -/ -- TODO: better error messages when all strategies fail -- TODO: consider lowering monad to `MetaM` -def findModelInner (e : Expr) (baseInfo : Option (Expr × Expr) := none) : - TermElabM (Option FindModelResult) := do +partial def findModelInner (e : Expr) : TermElabM (Option FindModelResult) := do if let some m ← tryStrategy "TotalSpace" fromTotalSpace then return some m if let some m ← tryStrategy "TangentBundle" fromTangentBundle then return some m if let some m ← tryStrategy "NormedSpace" fromNormedSpace then return some m @@ -389,34 +406,36 @@ def findModelInner (e : Expr) (baseInfo : Option (Expr × Expr) := none) : where /- Note that errors thrown in the following are caught by `tryStrategy` and converted to trace messages. -/ - /-- Attempt to find a model from a `TotalSpace` first by attempting to use any provided - `baseInfo`, then by seeing if it is the total space of a tangent bundle. -/ + /-- Attempt to find a model from a `TotalSpace` first by seeing if it is the total space of a + tangent bundle, and otherwise by finding a model with corners on its base. -/ fromTotalSpace : TermElabM FindModelResult := do match_expr e with | Bundle.TotalSpace _ F V => do if let some m ← tryStrategy m!"TangentSpace" (fromTotalSpace.tangentSpace V) then return m - if let some m ← tryStrategy m!"From base info" (fromTotalSpace.fromBaseInfo F) then return m - throwError "Having a TotalSpace as source is not yet supported" + trace[Elab.DiffGeo.MDiff] + "{e} is the total space of a fiber bundle: trying to find a model on the base of `{V}`" + -- `V` should be of type `B → Type*`, where `B` is the base of the vector bundle. + -- Then, the desired model with corners is `I.prod (𝓘(𝕜, F))`, where `I` is the model on `B` + -- and `𝕜` is the base field for `F`. + let vtype ← whnf <| ← instantiateMVars <| ← inferType V + trace[Elab.DiffGeo.MDiff] "`{V}` has type `{vtype}`" + match vtype with + | .forallE _x base _tgt _ => + let baseModel ← withTraceNode `Elab.DiffGeo.MDiff + (fun _ ↦ pure m!"searching for a model with corners on the base `{base}`") do + let some baseI ← findModelInner base + | throwError m!"found no model with corners on the base {base} of `TotalSpace {F} {V}`" + return baseI.model + -- Very likely, `F` is a normed space over some field: let's see if `F` is a normed space + -- on the nose. + let some K ← guessBaseFieldForNormedSpace F + | throwError "Couldn't find a `NormedSpace` structure on `{F}`" + let tgtMod ← mkAppOptM ``modelWithCornersSelf #[K, none, F, none, none] + mkAppM ``ModelWithCorners.prod #[baseModel, tgtMod] + | _ => + throwError s!"{e} is a TotalSpace {F} {V}, but {V} is not a pi type --- \ + could not infer base of the bundle" | _ => throwError "`{e}` is not a `Bundle.TotalSpace`." - /-- Attempt to use the provided `baseInfo` to find a model. -/ - fromTotalSpace.fromBaseInfo (F : Expr) : TermElabM Expr := do - if let some (src, srcI) := baseInfo then - trace[Elab.DiffGeo.MDiff] "Using base info `{src}`, `{srcI}`" - let some K ← findSomeLocalInstanceOf? ``NormedSpace fun _ type ↦ do - match_expr type with - | NormedSpace K E _ _ => - if ← withReducible (pureIsDefEq E F) then - trace[Elab.DiffGeo.MDiff] "`{F}` is a normed field over `{K}`"; return some K - else return none - | _ => return none - | throwError "Couldn't find a `NormedSpace` structure on `{F}` among local instances." - let kT : Term ← Term.exprToSyntax K - let srcIT : Term ← Term.exprToSyntax srcI - let FT : Term ← Term.exprToSyntax F - let iTerm : Term ← ``(ModelWithCorners.prod $srcIT 𝓘($kT, $FT)) - Term.elabTerm iTerm none - else - throwError "No `baseInfo` provided" /-- Attempt to find a model from the total space of a tangent bundle. -/ fromTotalSpace.tangentSpace (V : Expr) : TermElabM Expr := do match_expr V with @@ -719,11 +738,6 @@ Further cases can be added as necessary. Return an expression describing the found model with corners. -`baseInfo` is only used for the first case, a model with corners on the total space of the vector -bundle. In this case, it contains a pair of expressions `(e, i)` describing the type of the base -and the model with corners on the base: these are required to construct the right model with -corners. - Note that the matching on `e` does not see through reducibility (e.g. we distinguish the `abbrev` `TangentBundle` from its definition), so `whnfR` should not be run on `e` prior to calling `findModel` on it. @@ -737,9 +751,9 @@ This implementation is not maximally robust yet. -- This should not be an issue in practice. -- FIXME: can one prove this terminates w.r.t. a suitable measure? This is only recursing into -- subexpressions (at least, after match_expr), right? -partial def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do +partial def findModel (e : Expr) : TermElabM Expr := do trace[Elab.DiffGeo.MDiff] "Finding a model with corners for: `{e}`" - if let some { model .. } ← go e baseInfo then + if let some { model .. } ← go e then return model else let tracing := (← isTracingEnabledFor `Elab.DiffGeo.MDiff) @@ -751,9 +765,9 @@ partial def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : Te command `set_option trace.Elab.DiffGeo.MDiff true`." throwError "Could not find a model with corners for `{e}`.{hint}" where - go (e : Expr) (baseInfo : Option (Expr × Expr)) : TermElabM (Option FindModelResult) := do + go (e : Expr) : TermElabM (Option FindModelResult) := do -- At first, try finding a model with corners on the space itself. - if let some m ← findModelInner e baseInfo then return some m + if let some m ← findModelInner e then return some m -- Otherwise, we recurse into the expression, -- depending whether we have an open subset of a space, a product, or a direct sum of spaces. match_expr e with @@ -774,16 +788,16 @@ where trace[Elab.DiffGeo.MDiff] "`{e}` is an open set of `{M}`, finding a model on `{M}`" -- `M` is not a open set of another manifold, as `Opens X` is (currently) not a -- topological space (and this would be strange). Therefore, do not recurse into `M`. - go M baseInfo + go M | _ => return none | _ => return none | _ => return none | _ => return none | Prod E F => trace[Elab.DiffGeo.MDiff] "Expression `{e}` is a product, recursing into each factor" - let some { model := srcE, normedSpaceInfo? := normedSpaceE } ← go E baseInfo + let some { model := srcE, normedSpaceInfo? := normedSpaceE } ← go E | throwError "Found no model with corners on first factor `{E}`" - let some { model := srcF, normedSpaceInfo? := normedSpaceF } ← go F baseInfo + let some { model := srcF, normedSpaceInfo? := normedSpaceF } ← go F | throwError "Found no model with corners on second factor `{F}`" -- If both E and F are normed spaces, we have ambiguity: warn and exit. if normedSpaceE.isSome && normedSpaceF.isSome then @@ -797,7 +811,7 @@ where | Sum E F => trace[Elab.DiffGeo.MDiff] "Expression `{e}` is a direct sum of `{E}` and `{F}`\n\ We assume the models match, and only look into the first summand" - go E baseInfo + go E | _ => return none /-- If the type of `e` is a non-dependent function between spaces `src` and `tgt`, try to find a @@ -823,7 +837,7 @@ def findModels (e : Expr) (es : Option Expr) : TermElabM (Expr × Expr) := do if !(← isDefEq estype <| ← mkAppM ``Set #[src]) then throwError "The domain `{src}` of `{e}` is not definitionally equal to the carrier type of \ the set `{es}` : `{estype}`" - let tgtI ← findModel tgt (src, srcI) + let tgtI ← findModel tgt return (srcI, tgtI) | _ => throwError "Expected{indentD e}\nof type{indentD etype}\nto be a function" diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index 20f7437e4eace3..654aab97adf6ee 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -54,9 +54,8 @@ theorem contMDiffOn_continuousLinearMapCoordChange [ContMDiffVectorBundle n F₁ E₁ IB] [ContMDiffVectorBundle n F₂ E₂ IB] [MemTrivializationAtlas e₁] [MemTrivializationAtlas e₁'] [MemTrivializationAtlas e₂] [MemTrivializationAtlas e₂'] : - ContMDiffOn IB 𝓘(𝕜, (F₁ →L[𝕜] F₂) →L[𝕜] F₁ →L[𝕜] F₂) n - (continuousLinearMapCoordChange (RingHom.id 𝕜) e₁ e₁' e₂ e₂') - (e₁.baseSet ∩ e₂.baseSet ∩ (e₁'.baseSet ∩ e₂'.baseSet)) := by + CMDiff[e₁.baseSet ∩ e₂.baseSet ∩ (e₁'.baseSet ∩ e₂'.baseSet)] n + (continuousLinearMapCoordChange (RingHom.id 𝕜) e₁ e₁' e₂ e₂') := by have h₁ := contMDiffOn_coordChangeL (IB := IB) e₁' e₁ (n := n) have h₂ := contMDiffOn_coordChangeL (IB := IB) e₂ e₂' (n := n) refine (h₁.mono ?_).cle_arrowCongr (h₂.mono ?_) <;> mfld_set_tac @@ -72,14 +71,14 @@ theorem hom_chart (y₀ y : LE₁E₂) : hom_trivializationAt_apply] theorem contMDiffWithinAt_hom_bundle (f : M → LE₁E₂) {s : Set M} {x₀ : M} : - ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) n f s x₀ ↔ + CMDiffAt[s] n f x₀ ↔ CMDiffAt[s] n (fun x ↦ (f x).1) x₀ ∧ CMDiffAt[s] n (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) x₀ := contMDiffWithinAt_totalSpace theorem contMDiffAt_hom_bundle (f : M → LE₁E₂) {x₀ : M} : - ContMDiffAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) n f x₀ ↔ + CMDiffAt n f x₀ ↔ CMDiffAt n (fun x ↦ (f x).1) x₀ ∧ CMDiffAt n (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) x₀ := contMDiffAt_totalSpace @@ -101,14 +100,14 @@ theorem mdifferentiableOn_continuousLinearMapCoordChange variable [∀ x, IsTopologicalAddGroup (E₂ x)] [∀ x, ContinuousSMul 𝕜 (E₂ x)] theorem mdifferentiableWithinAt_hom_bundle (f : M → LE₁E₂) {s : Set M} {x₀ : M} : - MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) f s x₀ ↔ + MDiffAt[s] f x₀ ↔ MDiffAt[s] (fun x ↦ (f x).1) x₀ ∧ MDiffAt[s] (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) x₀ := mdifferentiableWithinAt_totalSpace IB .. theorem mdifferentiableAt_hom_bundle (f : M → LE₁E₂) {x₀ : M} : - MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) f x₀ ↔ + MDiffAt f x₀ ↔ MDiffAt (fun x ↦ (f x).1) x₀ ∧ MDiffAt (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) x₀ := mdifferentiableAt_totalSpace .. @@ -178,9 +177,8 @@ For a version with `B₁ = B₂` and `b₁ = b₂`, in which smoothness can be e lemma ContMDiffWithinAt.clm_apply_of_inCoordinates (hϕ : CMDiffAt[s] n (fun m ↦ inCoordinates F₁ E₁ F₂ E₂ (b₁ m₀) (b₁ m) (b₂ m₀) (b₂ m) (ϕ m)) m₀) - (hv : ContMDiffWithinAt IM (IB₁.prod 𝓘(𝕜, F₁)) n (fun m ↦ (v m : TotalSpace F₁ E₁)) s m₀) - (hb₂ : CMDiffAt[s] n b₂ m₀) : - ContMDiffWithinAt IM (IB₂.prod 𝓘(𝕜, F₂)) n (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) s m₀ := by + (hv : CMDiffAt[s] n (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) (hb₂ : CMDiffAt[s] n b₂ m₀) : + CMDiffAt[s] n (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by rw [← contMDiffWithinAt_insert_self] at hϕ hv hb₂ ⊢ rw [contMDiffWithinAt_totalSpace] at hv ⊢ refine ⟨hb₂, ?_⟩ @@ -215,9 +213,8 @@ For a version with `B₁ = B₂` and `b₁ = b₂`, in which smoothness can be e -/ lemma ContMDiffAt.clm_apply_of_inCoordinates (hϕ : CMDiffAt n (fun m ↦ inCoordinates F₁ E₁ F₂ E₂ (b₁ m₀) (b₁ m) (b₂ m₀) (b₂ m) (ϕ m)) m₀) - (hv : ContMDiffAt IM (IB₁.prod 𝓘(𝕜, F₁)) n (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) - (hb₂ : CMDiffAt n b₂ m₀) : - ContMDiffAt IM (IB₂.prod 𝓘(𝕜, F₂)) n (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by + (hv : CMDiffAt n (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) (hb₂ : CMDiffAt n b₂ m₀) : + CMDiffAt n (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by rw [← contMDiffWithinAt_univ] at hϕ hv hb₂ ⊢ exact ContMDiffWithinAt.clm_apply_of_inCoordinates hϕ hv hb₂ @@ -261,12 +258,10 @@ One can apply `ϕ m` to `v m`, and the resulting map is `C^n`. We give here a version of this statement within a set at a point. -/ lemma ContMDiffWithinAt.clm_bundle_apply - (hϕ : ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) n - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) - s x) - (hv : ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s x) : - ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₂)) n - (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) s x := by + (hϕ : CMDiffAt[s] n + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) x) + (hv : CMDiffAt[s] n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : + CMDiffAt[s] n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := by simp only [contMDiffWithinAt_hom_bundle] at hϕ exact hϕ.2.clm_apply_of_inCoordinates hv hϕ.1 @@ -276,10 +271,10 @@ One can apply `ϕ m` to `v m`, and the resulting map is `C^n`. We give here a version of this statement at a point. -/ lemma ContMDiffAt.clm_bundle_apply - (hϕ : ContMDiffAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) n + (hϕ : CMDiffAt n (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) x) - (hv : ContMDiffAt IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : - ContMDiffAt IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := + (hv : CMDiffAt n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : + CMDiffAt n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := ContMDiffWithinAt.clm_bundle_apply hϕ hv /-- Consider a `C^n` map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and @@ -288,20 +283,20 @@ One can apply `ϕ m` to `v m`, and the resulting map is `C^n`. We give here a version of this statement on a set. -/ lemma ContMDiffOn.clm_bundle_apply - (hϕ : ContMDiffOn IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) n - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) s) - (hv : ContMDiffOn IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s) : - ContMDiffOn IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) s := + (hϕ : CMDiff[s] n + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m))) + (hv : CMDiff[s] n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : + CMDiff[s] n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := fun x hx ↦ (hϕ x hx).clm_bundle_apply (hv x hx) /-- Consider a `C^n` map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and linear maps `ϕ m : E₁ (b m) → E₂ (b m)` depending smoothly on `m`. One can apply `ϕ m` to `v m`, and the resulting map is `C^n`. -/ lemma ContMDiff.clm_bundle_apply - (hϕ : ContMDiff IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) n + (hϕ : CMDiff n (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m))) - (hv : ContMDiff IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : - ContMDiff IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := + (hv : CMDiff n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : + CMDiff n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := fun x ↦ (hϕ x).clm_bundle_apply (hv x) end OneVariable @@ -317,13 +312,10 @@ One can apply `ϕ m` to `v m`, and the resulting map is differentiable. We give here a version of this statement within a set at a point. -/ lemma MDifferentiableWithinAt.clm_bundle_apply - (hϕ : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) - s x) - (hv : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁)) - (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s x) : - MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₂)) - (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) s x := by + (hϕ : MDiffAt[s] + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) x) + (hv : MDiffAt[s] (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : + MDiffAt[s] (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := by simp only [mdifferentiableWithinAt_hom_bundle] at hϕ exact hϕ.2.clm_apply_of_inCoordinates hv hϕ.1 @@ -333,10 +325,10 @@ One can apply `ϕ m` to `v m`, and the resulting map is differentiable. We give here a version of this statement at a point. -/ lemma MDifferentiableAt.clm_bundle_apply - (hϕ : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) + (hϕ : MDiffAt (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) x) - (hv : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : - MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := + (hv : MDiffAt (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : + MDiffAt (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := MDifferentiableWithinAt.clm_bundle_apply hϕ hv /-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and @@ -345,20 +337,20 @@ One can apply `ϕ m` to `v m`, and the resulting map is differentiable. We give here a version of this statement on a set. -/ lemma MDifferentiableOn.clm_bundle_apply - (hϕ : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) s) - (hv : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s) : - MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) s := + (hϕ : MDiff[s] + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m))) + (hv : MDiff[s] (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : + MDiff[s] (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := fun x hx ↦ (hϕ x hx).clm_bundle_apply (hv x hx) /-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and linear maps `ϕ m : E₁ (b m) → E₂ (b m)` depending smoothly on `m`. One can apply `ϕ m` to `v m`, and the resulting map is differentiable. -/ lemma MDifferentiable.clm_bundle_apply - (hϕ : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) + (hϕ : MDiff (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m))) - (hv : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : - MDifferentiable IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := + (hv : MDiff (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : + MDiff (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := fun x ↦ (hϕ x).clm_bundle_apply (hv x) end OneVariable' @@ -374,13 +366,11 @@ One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. We give here a version of this statement within a set at a point. -/ lemma ContMDiffWithinAt.clm_bundle_apply₂ - (hψ : ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) n - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) - (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) s x) - (hv : ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s x) - (hw : ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) s x) : - ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F₃)) n - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) s x := + (hψ : CMDiffAt[s] n (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) x) + (hv : CMDiffAt[s] n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) + (hw : CMDiffAt[s] n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : + CMDiffAt[s] n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := hψ.clm_bundle_apply hv |>.clm_bundle_apply hw /-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map @@ -389,13 +379,11 @@ One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. We give here a version of this statement at a point. -/ lemma ContMDiffAt.clm_bundle_apply₂ - (hψ : ContMDiffAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) n - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (hψ : CMDiffAt n (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) x) - (hv : ContMDiffAt IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) - (hw : ContMDiffAt IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : - ContMDiffAt IM (IB.prod 𝓘(𝕜, F₃)) n - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := + (hv : CMDiffAt n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) + (hw : CMDiffAt n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : + CMDiffAt n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := ContMDiffWithinAt.clm_bundle_apply₂ hψ hv hw /-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map @@ -404,26 +392,22 @@ One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. We give here a version of this statement on a set. -/ lemma ContMDiffOn.clm_bundle_apply₂ - (hψ : ContMDiffOn IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) n - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) - (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) s) - (hv : ContMDiffOn IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s) - (hw : ContMDiffOn IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) s) : - ContMDiffOn IM (IB.prod 𝓘(𝕜, F₃)) n - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) s := + (hψ : CMDiff[s] n (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m))) + (hv : CMDiff[s] n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) + (hw : CMDiff[s] n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : + CMDiff[s] n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := fun x hx ↦ (hψ x hx).clm_bundle_apply₂ (hv x hx) (hw x hx) /-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. -/ lemma ContMDiff.clm_bundle_apply₂ - (hψ : ContMDiff IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) n - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (hψ : CMDiff n (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m))) - (hv : ContMDiff IM (IB.prod 𝓘(𝕜, F₁)) n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) - (hw : ContMDiff IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : - ContMDiff IM (IB.prod 𝓘(𝕜, F₃)) n - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := + (hv : CMDiff n (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) + (hw : CMDiff n (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : + CMDiff n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := fun x ↦ (hψ x).clm_bundle_apply₂ (hv x) (hw x) end TwoVariables @@ -439,15 +423,11 @@ One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiabl We give here a version of this statement within a set at a point. -/ lemma MDifferentiableWithinAt.clm_bundle_apply₂ - (hψ : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) - (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) s x) - (hv : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁)) - (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s x) - (hw : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₂)) - (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) s x) : - MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₃)) - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) s x := + (hψ : MDiffAt[s] (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) x) + (hv : MDiffAt[s] (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) + (hw : MDiffAt[s] (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : + MDiffAt[s] (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := hψ.clm_bundle_apply hv |>.clm_bundle_apply hw /-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map @@ -456,13 +436,11 @@ One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiabl We give here a version of this statement at a point. -/ lemma MDifferentiableAt.clm_bundle_apply₂ - (hψ : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (hψ : MDiffAt (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) x) - (hv : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) - (hw : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : - MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₃)) - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := + (hv : MDiffAt (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) + (hw : MDiffAt (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : + MDiffAt (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := MDifferentiableWithinAt.clm_bundle_apply₂ hψ hv hw /-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map @@ -471,26 +449,22 @@ One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiabl We give here a version of this statement on a set. -/ lemma MDifferentiableOn.clm_bundle_apply₂ - (hψ : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) - (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) s) - (hv : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s) - (hw : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) s) : - MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₃)) - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) s := + (hψ : MDiff[s] (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m))) + (hv : MDiff[s] (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) + (hw : MDiff[s] (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : + MDiff[s] (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := fun x hx ↦ (hψ x hx).clm_bundle_apply₂ (hv x hx) (hw x hx) /-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. -/ lemma MDifferentiable.clm_bundle_apply₂ - (hψ : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) - (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (hψ : MDiff (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m))) - (hv : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) - (hw : MDifferentiable IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : - MDifferentiable IM (IB.prod 𝓘(𝕜, F₃)) - (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := + (hv : MDiff (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) + (hw : MDiff (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : + MDiff (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := fun x ↦ (hψ x).clm_bundle_apply₂ (hv x) (hw x) end TwoVariables' diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index b47e572fc3d9b8..2d426f73f5030c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -39,7 +39,7 @@ variable [TopologicalSpace B] [ChartedSpace HB B] [FiberBundle F E] /-- Characterization of differentiable functions into a vector bundle. Version at a point within a set -/ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : - MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ + MDiffAt[s] f x₀ ↔ MDiffAt[s] (fun x => (f x).proj) x₀ ∧ MDiffAt[s] (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by simp +singlePass only [mdifferentiableWithinAt_iff_target] @@ -61,7 +61,7 @@ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M /-- Characterization of differentiable functions into a vector bundle. Version at a point -/ theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : - MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ + MDiffAt f x₀ ↔ MDiffAt (fun x => (f x).proj) x₀ ∧ MDiffAt (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f @@ -69,8 +69,7 @@ theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : /-- Characterization of differentiable sections of a vector bundle at a point within a set in terms of the preferred trivialization at that point. -/ theorem mdifferentiableWithinAt_section (s : Π b, E b) {u : Set B} {b₀ : B} : - MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (T% s) u b₀ ↔ - MDiffAt[u] (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by + MDiffAt[u] (T% s) b₀ ↔ MDiffAt[u] (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by rw [mdifferentiableWithinAt_totalSpace] change MDifferentiableWithinAt _ _ id _ _ ∧ _ ↔ _ simp [mdifferentiableWithinAt_id] @@ -85,21 +84,19 @@ namespace Bundle variable (E) {IB} -theorem mdifferentiable_proj : MDifferentiable (IB.prod 𝓘(𝕜, F)) IB (π F E) := fun x ↦ by - have : MDifferentiableAt (IB.prod 𝓘(𝕜, F)) (IB.prod 𝓘(𝕜, F)) id x := mdifferentiableAt_id +theorem mdifferentiable_proj : MDiff (π F E) := fun x ↦ by + have : MDiffAt (@id <| TotalSpace F E) x := mdifferentiableAt_id rw [mdifferentiableAt_totalSpace] at this exact this.1 -theorem mdifferentiableOn_proj {s : Set (TotalSpace F E)} : - MDifferentiableOn (IB.prod 𝓘(𝕜, F)) IB (π F E) s := +theorem mdifferentiableOn_proj {s : Set (TotalSpace F E)} : MDiff[s] (π F E) := (mdifferentiable_proj E).mdifferentiableOn -theorem mdifferentiableAt_proj {p : TotalSpace F E} : - MDifferentiableAt (IB.prod 𝓘(𝕜, F)) IB (π F E) p := +theorem mdifferentiableAt_proj {p : TotalSpace F E} : MDiffAt (π F E) p := (mdifferentiable_proj E).mdifferentiableAt theorem mdifferentiableWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace F E} : - MDifferentiableWithinAt (IB.prod 𝓘(𝕜, F)) IB (π F E) s p := + MDiffAt[s] (π F E) p := (mdifferentiableAt_proj E).mdifferentiableWithinAt variable (𝕜) [∀ x, AddCommMonoid (E x)] @@ -243,8 +240,8 @@ theorem mdifferentiableWithinAt_totalSpace_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (f : M → TotalSpace F E) {s : Set M} {x₀ : M} (he : f x₀ ∈ e.source) : - MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ - MDiffAt[s] (fun x => (f x).proj) x₀ ∧ MDiffAt[s] (fun x ↦ (e (f x)).2) x₀ := by + MDiffAt[s] f x₀ ↔ + MDiffAt[s] (fun x ↦ (f x).proj) x₀ ∧ MDiffAt[s] (fun x ↦ (e (f x)).2) x₀ := by rw [mdifferentiableWithinAt_totalSpace] apply and_congr_right intro hf @@ -257,8 +254,7 @@ theorem mdifferentiableAt_totalSpace_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (f : M → TotalSpace F E) {x₀ : M} (he : f x₀ ∈ e.source) : - MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ - MDiffAt (fun x => (f x).proj) x₀ ∧ MDiffAt (fun x ↦ (e (f x)).2) x₀ := by + MDiffAt f x₀ ↔ MDiffAt (fun x ↦ (f x).proj) x₀ ∧ MDiffAt (fun x ↦ (e (f x)).2) x₀ := by rw [mdifferentiableAt_totalSpace] apply and_congr_right intro hf @@ -273,7 +269,7 @@ theorem mdifferentiableWithinAt_section_iff (hex₀ : b₀ ∈ e.baseSet) : MDiffAt[u] (T% s) b₀ ↔ MDiffAt[u] (fun x ↦ (e (s x)).2) b₀ := by rw [e.mdifferentiableWithinAt_totalSpace_iff IB] - · change MDifferentiableWithinAt IB IB id u b₀ ∧ _ ↔ _ + · change MDiffAt[u] (@id B) b₀ ∧ _ ↔ _ simp [mdifferentiableWithinAt_id] exact (coe_mem_source e).mpr hex₀ @@ -624,10 +620,9 @@ only makes sense around a point. -/ lemma MDifferentiableWithinAt.clm_apply_of_inCoordinates (hϕ : MDiffAt[s] (fun m ↦ inCoordinates F₁ E₁ F₂ E₂ (b₁ m₀) (b₁ m) (b₂ m₀) (b₂ m) (ϕ m)) m₀) - (hv : MDifferentiableWithinAt IM (IB₁.prod 𝓘(𝕜, F₁)) (fun m ↦ (v m : TotalSpace F₁ E₁)) s m₀) + (hv : MDiffAt[s] (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) (hb₂ : MDiffAt[s] b₂ m₀) : - MDifferentiableWithinAt IM (IB₂.prod 𝓘(𝕜, F₂)) - (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) s m₀ := by + MDiffAt[s] (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by rw [mdifferentiableWithinAt_totalSpace] at hv ⊢ refine ⟨hb₂, ?_⟩ apply (MDifferentiableWithinAt.clm_apply hϕ hv.2).congr_of_eventuallyEq_insert @@ -658,9 +653,8 @@ in coordinates, only makes sense around a point. -/ lemma MDifferentiableAt.clm_apply_of_inCoordinates (hϕ : MDiffAt (fun m ↦ inCoordinates F₁ E₁ F₂ E₂ (b₁ m₀) (b₁ m) (b₂ m₀) (b₂ m) (ϕ m)) m₀) - (hv : MDifferentiableAt IM (IB₁.prod 𝓘(𝕜, F₁)) (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) - (hb₂ : MDiffAt b₂ m₀) : - MDifferentiableAt IM (IB₂.prod 𝓘(𝕜, F₂)) (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by + (hv : MDiffAt (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) (hb₂ : MDiffAt b₂ m₀) : + MDiffAt (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by rw [← mdifferentiableWithinAt_univ] at hϕ hv hb₂ ⊢ exact MDifferentiableWithinAt.clm_apply_of_inCoordinates hϕ hv hb₂ @@ -680,17 +674,17 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] lemma exists_contMDiffOn_extend [(x : M) → Module 𝕜 (V x)] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle k F V I] {x₀ : M} (σ₀ : V x₀) : - ∃ s ∈ 𝓝 x₀, ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (T% (extend F σ₀)) s := by + ∃ s ∈ 𝓝 x₀, CMDiff[s] k (T% (extend F σ₀)) := by set t := trivializationAt F V x₀ refine ⟨t.baseSet, ?_, ?_⟩ · refine t.open_baseSet.mem_nhds ?_ exact FiberBundle.mem_baseSet_trivializationAt' x₀ - suffices ContMDiffOn I 𝓘(𝕜, F) k (fun x ↦ (t ⟨x, extend F σ₀ x⟩).2) t.baseSet by + suffices CMDiff[t.baseSet] k (fun x ↦ (t ⟨x, extend F σ₀ x⟩).2) by intro x hx rw [t.contMDiffWithinAt_section _ hx] exact this x hx let w : F := (t ⟨x₀, σ₀⟩).2 - have : ContMDiffOn I 𝓘(𝕜, F) k (fun _x ↦ w) t.baseSet := contMDiffOn_const + have : CMDiff[t.baseSet] k (fun (_x : M) ↦ w) := contMDiffOn_const exact this.congr (fun x hx ↦ by simp [extend, t, w, hx]) lemma contMDiffAt_extend' {x : M} (σ₀ : V x) : @@ -708,7 +702,7 @@ lemma contMDiffAt_extend' {x : M} (σ₀ : V x) : lemma exists_mdifferentiableOn_extend [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] {x₀ : M} (σ₀ : V x₀) : - ∃ s ∈ 𝓝 x₀, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (T% (extend F σ₀)) s := by + ∃ s ∈ 𝓝 x₀, MDiff[s] (T% (extend F σ₀)) := by obtain ⟨s, hs, hsσ⟩ := exists_contMDiffOn_extend (k := 1) I F σ₀ exact ⟨s, hs, hsσ.mdifferentiableOn one_ne_zero⟩ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean b/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean index bc90f650272711..b5fc92352e7156 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean @@ -119,9 +119,9 @@ variable /-- Given two smooth maps into the same fibers of a Riemannian bundle, their scalar product is smooth. -/ lemma ContMDiffWithinAt.inner_bundle - (hv : ContMDiffWithinAt IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (v m : TotalSpace F E)) s x) - (hw : ContMDiffWithinAt IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (w m : TotalSpace F E)) s x) : - ContMDiffWithinAt IM 𝓘(ℝ) n (fun m ↦ ⟪v m, w m⟫) s x := by + (hv : CMDiffAt[s] n (fun m ↦ (v m : TotalSpace F E)) x) + (hw : CMDiffAt[s] n (fun m ↦ (w m : TotalSpace F E)) x) : + CMDiffAt[s] n (fun m ↦ ⟪v m, w m⟫) x := by rcases h.exists_contMDiff with ⟨g, g_smooth, hg⟩ have hb : CMDiffAt[s] n b x := by simp only [contMDiffWithinAt_totalSpace] at hv @@ -139,24 +139,24 @@ lemma ContMDiffWithinAt.inner_bundle /-- Given two smooth maps into the same fibers of a Riemannian bundle, their scalar product is smooth. -/ lemma ContMDiffAt.inner_bundle - (hv : ContMDiffAt IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (v m : TotalSpace F E)) x) - (hw : ContMDiffAt IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (w m : TotalSpace F E)) x) : - ContMDiffAt IM 𝓘(ℝ) n (fun b ↦ ⟪v b, w b⟫) x := + (hv : CMDiffAt n (fun m ↦ (v m : TotalSpace F E)) x) + (hw : CMDiffAt n (fun m ↦ (w m : TotalSpace F E)) x) : + CMDiffAt n (fun b ↦ ⟪v b, w b⟫) x := ContMDiffWithinAt.inner_bundle hv hw /-- Given two smooth maps into the same fibers of a Riemannian bundle, their scalar product is smooth. -/ lemma ContMDiffOn.inner_bundle - (hv : ContMDiffOn IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (v m : TotalSpace F E)) s) - (hw : ContMDiffOn IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (w m : TotalSpace F E)) s) : - ContMDiffOn IM 𝓘(ℝ) n (fun b ↦ ⟪v b, w b⟫) s := + (hv : CMDiff[s] n (fun m ↦ (v m : TotalSpace F E))) + (hw : CMDiff[s] n (fun m ↦ (w m : TotalSpace F E))) : + CMDiff[s] n (fun b ↦ ⟪v b, w b⟫) := fun x hx ↦ (hv x hx).inner_bundle (hw x hx) /-- Given two smooth maps into the same fibers of a Riemannian bundle, their scalar product is smooth. -/ lemma ContMDiff.inner_bundle - (hv : ContMDiff IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (v m : TotalSpace F E))) - (hw : ContMDiff IM (IB.prod 𝓘(ℝ, F)) n (fun m ↦ (w m : TotalSpace F E))) : + (hv : CMDiff n (fun m ↦ (v m : TotalSpace F E))) + (hw : CMDiff n (fun m ↦ (w m : TotalSpace F E))) : CMDiff n (fun b ↦ ⟪v b, w b⟫) := fun x ↦ (hv x).inner_bundle (hw x) @@ -174,11 +174,11 @@ variable /-- Given two differentiable maps into the same fibers of a Riemannian bundle, their scalar product is differentiable. -/ lemma MDifferentiableWithinAt.inner_bundle - (hv : MDifferentiableWithinAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E)) s x) - (hw : MDifferentiableWithinAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E)) s x) : + (hv : MDiffAt[s] (fun m ↦ (v m : TotalSpace F E)) x) + (hw : MDiffAt[s] (fun m ↦ (w m : TotalSpace F E)) x) : MDiffAt[s] (fun m ↦ ⟪v m, w m⟫) x := by rcases h.exists_contMDiff with ⟨g, g_smooth, hg⟩ - have hb : MDifferentiableWithinAt IM IB b s x := by + have hb : MDiffAt[s] b x := by simp only [mdifferentiableWithinAt_totalSpace] at hv exact hv.1 simp only [hg] @@ -195,24 +195,24 @@ lemma MDifferentiableWithinAt.inner_bundle /-- Given two differentiable maps into the same fibers of a Riemannian bundle, their scalar product is differentiable. -/ lemma MDifferentiableAt.inner_bundle - (hv : MDifferentiableAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E)) x) - (hw : MDifferentiableAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E)) x) : + (hv : MDiffAt (fun m ↦ (v m : TotalSpace F E)) x) + (hw : MDiffAt (fun m ↦ (w m : TotalSpace F E)) x) : MDiffAt (fun b ↦ ⟪v b, w b⟫) x := MDifferentiableWithinAt.inner_bundle hv hw /-- Given two differentiable maps into the same fibers of a Riemannian bundle, their scalar product is differentiable. -/ lemma MDifferentiableOn.inner_bundle - (hv : MDifferentiableOn IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E)) s) - (hw : MDifferentiableOn IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E)) s) : + (hv : MDiff[s] (fun m ↦ (v m : TotalSpace F E))) + (hw : MDiff[s] (fun m ↦ (w m : TotalSpace F E))) : MDiff[s] (fun b ↦ ⟪v b, w b⟫) := fun x hx ↦ (hv x hx).inner_bundle (hw x hx) /-- Given two differentiable maps into the same fibers of a Riemannian bundle, their scalar product is differentiable. -/ lemma MDifferentiable.inner_bundle - (hv : MDifferentiable IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E))) - (hw : MDifferentiable IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E))) : + (hv : MDiff (fun m ↦ (v m : TotalSpace F E))) + (hw : MDiff (fun m ↦ (w m : TotalSpace F E))) : MDiff (fun b ↦ ⟪v b, w b⟫) := fun x ↦ (hv x).inner_bundle (hw x) diff --git a/MathlibTest/DifferentialGeometry/Notation/PR40447.lean b/MathlibTest/DifferentialGeometry/Notation/PR40447.lean new file mode 100644 index 00000000000000..8b265aaa9becc2 --- /dev/null +++ b/MathlibTest/DifferentialGeometry/Notation/PR40447.lean @@ -0,0 +1,96 @@ +import Mathlib.Geometry.Manifold.Notation +import Mathlib.Geometry.Manifold.VectorBundle.Basic + +set_option pp.unicode.fun true + +open Bundle +open scoped Manifold + +-- Let `M` and `N` be smooth manifold. Suppose `V` is a vector bundle over `M` with model fiber `F`. +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {H' : Type*} [TopologicalSpace H'] (J : ModelWithCorners 𝕜 E' H') + {N : Type*} [TopologicalSpace N] [ChartedSpace H' N] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] + +-- Consider a function from `N` into the total space of `V`. +-- The correct model with corners to infer on the latter is `I.prod (𝓘(𝕜, F))` --- where +-- `I` is the model with corners on the base `M` of `V`. +/-- info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) (f x) -/ +#guard_msgs in +variable {f : N → TotalSpace F V} {x : N} in +#check mfderiv J (I.prod 𝓘(𝕜, F)) f x + +-- The elaborators used to have a bug: they would always use the model on the domain `N` instead of +-- the model `I` on the bundle's base `M`. This works if `f` were a section of `V`, +-- but is incorrect in general! +/-- info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) (f x) -/ +#guard_msgs in +variable {f : N → TotalSpace F V} {x : N} in #check mfderiv% f x + +-- Previously, projections like below were not supported: fixing the above bug properly also +-- addresses this. +/-- info: mfderiv% f x : TangentSpace (I.prod 𝓘(𝕜, F)) x →L[𝕜] TangentSpace J (f x) -/ +#guard_msgs in +variable {f : TotalSpace F V → N} {x : TotalSpace F V} in #check mfderiv% f x +/-- info: mfderiv% f x : TangentSpace (I.prod 𝓘(𝕜, F)) x →L[𝕜] TangentSpace J (f x) -/ +#guard_msgs in +variable {f : TotalSpace F V → N} {x : TotalSpace F V} in #check mfderiv (I.prod 𝓘(𝕜, F)) J f x + +-- Further tests for this feature. + +-- For a fiber bundle over a normed space, we still infer a model with corners. +/-- info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, F)) (f x) -/ +#guard_msgs in +variable {V' : E → Type*} [TopologicalSpace (TotalSpace F V')] [∀ x : E, TopologicalSpace (V' x)] + [FiberBundle F V'] {f : N → TotalSpace F V'} {x : N} in #check mfderiv% f x + +-- We don't do so for a fiber bundle over a product of normed spaces: there are several possible +-- choices for its base' model with corners. +/-- +error: Could not find a model with corners for `TotalSpace F V'`. + +Hint: failures to find a model with corners can be debugged with the command `set_option trace.Elab.DiffGeo.MDiff true`. +-/ +#guard_msgs in +variable {V' : (E × E')→ Type*} [TopologicalSpace (TotalSpace F V')] [∀ x, TopologicalSpace (V' x)] + [FiberBundle F V'] {f : N → TotalSpace F V'} {x : N} in +#check mfderiv% f x + + +-- Fiber bundles with more complicated fibers, e.g. products of normed spaces. + +/-- info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, F × F)) (f x) -/ +#guard_msgs in +variable {V' : E → Type*} [TopologicalSpace (TotalSpace (F × F) V')] [∀ x : E, TopologicalSpace (V' x)] + [FiberBundle (F × F) V'] {f : N → TotalSpace (F × F) V'} {x : N} in #check mfderiv% f x + +/-- info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, F →L[𝕜] F)) (f x) -/ +#guard_msgs in +variable {V' : E → Type*} [TopologicalSpace (TotalSpace (F →L[𝕜] F) V')] [∀ x : E, TopologicalSpace (V' x)] + [FiberBundle (F →L[𝕜] F) V'] {f : N → TotalSpace (F →L[𝕜] F) V'} {x : N} in #check mfderiv% f x + +/-- +info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, F × (F →L[𝕜] F))) (f x) +-/ +#guard_msgs in +variable {V' : E → Type*} [TopologicalSpace (TotalSpace (F × (F →L[𝕜] F)) V')] [∀ x : E, TopologicalSpace (V' x)] + [FiberBundle (F × (F →L[𝕜] F)) V'] {f : N → TotalSpace (F × (F →L[𝕜] F)) V'} {x : N} in +#check mfderiv% f x + +/-- +info: mfderiv% f x : TangentSpace J x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, F × (F →L[𝕜] F →L[𝕜] F))) (f x) +-/ +#guard_msgs in +variable {V' : E → Type*} [TopologicalSpace (TotalSpace (F × (F →L[𝕜] F →L[𝕜] F)) V')] [∀ x : E, TopologicalSpace (V' x)] + [FiberBundle (F × (F →L[𝕜] F →L[𝕜] F)) V'] {f : N → TotalSpace (F × (F →L[𝕜] F →L[𝕜] F)) V'} {x : N} in #check mfderiv% f x From a83a1c306aac0fc15753a4b7590db57c1f56fd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:28:09 +0000 Subject: [PATCH 0274/1300] feat(Algebra/Homology): more on the functoriality of categories of homological complexes (#40895) --- Mathlib/Algebra/Homology/Additive.lean | 25 ++++++++ .../Algebra/Homology/HomotopyCategory.lean | 60 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 86ab7ca1703cef..56b8a7c83daa15 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -141,6 +141,21 @@ instance Functor.mapHomologicalComplex_reflects_iso (F : W₁ ⥤ W₂) [F.Prese haveI := fun n => isIso_of_reflects_iso (f.f n) F exact HomologicalComplex.Hom.isIso_of_components f⟩ +instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] : + (F.mapHomologicalComplex c).Faithful where + map_injective {K L} f₁ f₂ h := by + ext + exact F.map_injective ((HomologicalComplex.eval W c _).congr_map h) + +instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] [F.Full] : + (F.mapHomologicalComplex c).Full where + map_surjective {X Y} f := ⟨ + { f n := F.preimage (f.f n) + comm' i j _ := by + apply F.map_injective + simp only [Functor.map_comp, Functor.map_preimage] + exact f.comm i j }, by cat_disch⟩ + variable {W₁} set_option backward.defeqAttrib.useBackward true in @@ -188,6 +203,16 @@ def NatIso.mapHomologicalComplex {F G : W₁ ⥤ W₂} [F.PreservesZeroMorphisms inv_hom_id := by simp only [← NatTrans.mapHomologicalComplex_comp, α.inv_hom_id, NatTrans.mapHomologicalComplex_id] +/-- If additive functors are related by an isomorphism `F ⋙ G ≅ H`, this is +the corresponding isomorphism for the induced functors on categories +of homological complexes. -/ +@[simps!] +def Functor.mapHomologicalComplexCompIso {W' : Type*} [Category W'] [Preadditive W'] + {F : V ⥤ W} {G : W ⥤ W'} {H : V ⥤ W'} (e : F ⋙ G ≅ H) + [F.Additive] [G.Additive] [H.Additive] (c : ComplexShape ι) : + F.mapHomologicalComplex c ⋙ G.mapHomologicalComplex c ≅ H.mapHomologicalComplex c := + NatIso.mapHomologicalComplex e c + set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories induces an equivalences between the respective categories of homological complex. diff --git a/Mathlib/Algebra/Homology/HomotopyCategory.lean b/Mathlib/Algebra/Homology/HomotopyCategory.lean index 099d7b695a351b..398b611bbac818 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory.lean @@ -285,4 +285,64 @@ instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [Linear R V] [Linear R have := Functor.linear_of_iso R (F.mapHomotopyCategoryFactors c).symm (HomotopyCategory.quotient V c).linear_of_full_essSurj_comp (F.mapHomotopyCategory c) +/-- If additive functors are related by an isomorphism `F ⋙ G ≅ H`, this is +the corresponding isomorphism for the induced functors on homotopy categories +of homological complexes. -/ +def Functor.mapHomotopyCategoryCompIso {W' : Type*} [Category W'] [Preadditive W'] + {F : V ⥤ W} {G : W ⥤ W'} {H : V ⥤ W'} (e : F ⋙ G ≅ H) + [F.Additive] [G.Additive] [H.Additive] (c : ComplexShape ι) : + F.mapHomotopyCategory c ⋙ G.mapHomotopyCategory c ≅ H.mapHomotopyCategory c := + Quotient.natIsoLift _ (isoWhiskerRight (Functor.mapHomologicalComplexCompIso e c) + (HomotopyCategory.quotient W' c)) + +variable {c} in +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- The preimage by a fully faithful functor of a homotopy between morphisms +of homological complexes. -/ +def Functor.preimageHomotopy + (F : V ⥤ W) [F.Additive] [F.Full] [F.Faithful] + {K L : HomologicalComplex V c} {f₁ f₂ : K ⟶ L} + (H : Homotopy ((F.mapHomologicalComplex c).map f₁) ((F.mapHomologicalComplex c).map f₂)) : + Homotopy f₁ f₂ where + hom i j := F.preimage (H.hom i j) + zero i j hij := F.map_injective (by simp only [map_preimage, Functor.map_zero, H.zero i j hij]) + comm i := F.map_injective (by simp [dsimp% H.comm i, dNext, prevD]) + +instance (F : V ⥤ W) [F.Full] [F.Faithful] [F.Additive] : + (F.mapHomotopyCategory c).Faithful where + map_injective := by + rintro ⟨K⟩ ⟨L⟩ f₁ f₂ h + obtain ⟨f₁, rfl⟩ := (HomotopyCategory.quotient _ _).map_surjective f₁ + obtain ⟨f₂, rfl⟩ := (HomotopyCategory.quotient _ _).map_surjective f₂ + exact HomotopyCategory.eq_of_homotopy _ _ + (F.preimageHomotopy (HomotopyCategory.homotopyOfEq _ _ h)) + +instance (F : V ⥤ W) [F.Full] [F.Faithful] [F.Additive] : + (F.mapHomotopyCategory c).Full where + map_surjective := by + rintro ⟨K⟩ ⟨L⟩ ⟨f⟩ + obtain ⟨g : K ⟶ L, rfl⟩ := (F.mapHomologicalComplex c).map_surjective f + exact ⟨(HomotopyCategory.quotient V c).map g, rfl⟩ + end CategoryTheory + +namespace HomologicalComplex + +variable {ι : Type*} {V : Type u} [Category.{v} V] [Preadditive V] {c : ComplexShape ι} + +open HomotopyCategory in +lemma isIso_quotient_map_iff_homotopyEquivalences + {K L : HomologicalComplex V c} (f : K ⟶ L) : + IsIso ((quotient _ _).map f) ↔ + homotopyEquivalences _ _ f := by + refine ⟨fun _ ↦ ?_, fun hf ↦ quotient_inverts_homotopyEquivalences V c f hf⟩ + obtain ⟨g, hg⟩ := (quotient V c).map_surjective (inv ((quotient V c).map f)) + let e : HomotopyEquiv K L := + { hom := f + inv := g + homotopyHomInvId := HomotopyCategory.homotopyOfEq _ _ (by cat_disch) + homotopyInvHomId := HomotopyCategory.homotopyOfEq _ _ (by cat_disch) } + exact ⟨e, rfl⟩ + +end HomologicalComplex From 84ecb9b7d4f18f74506eb28d83b3165849446cb9 Mon Sep 17 00:00:00 2001 From: zw810-ctrl <248219010+zw810-ctrl@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:44:05 +0000 Subject: [PATCH 0275/1300] feat(Algebra): range_prodMap for MonoidHom, RingHom, AlgHom (#40491) Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Algebra/Algebra/Subalgebra/Prod.lean | 9 ++++++++- Mathlib/Algebra/Group/Subgroup/Basic.lean | 5 +++++ Mathlib/Algebra/Group/Submonoid/Operations.lean | 6 ++++++ Mathlib/Algebra/Ring/Subring/Basic.lean | 5 +++++ Mathlib/Algebra/Ring/Subsemiring/Basic.lean | 5 +++++ Mathlib/RingTheory/Ideal/Prod.lean | 5 +++++ 6 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Prod.lean b/Mathlib/Algebra/Algebra/Subalgebra/Prod.lean index c3c9982f336797..69b915e51330eb 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Prod.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Prod.lean @@ -25,7 +25,9 @@ namespace Subalgebra open Algebra -variable {R A B : Type*} [CommSemiring R] [Semiring A] [Algebra R A] [Semiring B] [Algebra R B] +variable {R A B C D : Type*} [CommSemiring R] [Semiring A] [Algebra R A] [Semiring B] [Algebra R B] + [Semiring C] [Algebra R C] [Semiring D] [Algebra R D] + variable (S : Subalgebra R A) (S₁ : Subalgebra R B) /-- The product of two subalgebras is a subalgebra. -/ @@ -60,4 +62,9 @@ theorem prod_inf_prod {S T : Subalgebra R A} {S₁ T₁ : Subalgebra R B} : protected theorem center_prod : center R (A × B) = prod (center R A) (center R B) := SetLike.coe_injective Set.center_prod +@[simp] +theorem _root_.AlgHom.range_prodMap (f : A →ₐ[R] B) (g : C →ₐ[R] D) : + (f.prodMap g).range = f.range.prod g.range := + SetLike.coe_injective Set.range_prodMap + end Subalgebra diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index c5a07c6d1114d7..0a94a12c97fafa 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -729,6 +729,11 @@ lemma ker_snd : ker (snd G G') = .prod ⊤ ⊥ := SetLike.ext fun _ => (iff_of_e end Ker +@[to_additive (attr := simp) range_prodMap] +lemma range_prodMap {G' N' : Type*} [Group G'] [Group N'] (f : G →* N) (g : G' →* N') : + (f.prodMap g).range = f.range.prod g.range := + SetLike.coe_injective Set.range_prodMap + end MonoidHom namespace Subgroup diff --git a/Mathlib/Algebra/Group/Submonoid/Operations.lean b/Mathlib/Algebra/Group/Submonoid/Operations.lean index 82fdff1c1df514..d498ccecce2a86 100644 --- a/Mathlib/Algebra/Group/Submonoid/Operations.lean +++ b/Mathlib/Algebra/Group/Submonoid/Operations.lean @@ -677,6 +677,12 @@ theorem map_mrange (g : N →* P) (f : M →* N) : (mrange f).map g = mrange (co theorem mrange_eq_top {f : F} : mrange f = (⊤ : Submonoid N) ↔ Surjective f := SetLike.ext'_iff.trans <| Iff.trans (by rw [coe_mrange, coe_top]) Set.range_eq_univ +@[to_additive (attr := simp) mrange_prodMap] +lemma mrange_prodMap {M' N' : Type*} [MulOneClass M'] [MulOneClass N'] (f : M →* N) + (g : M' →* N') : + MonoidHom.mrange (f.prodMap g) = (MonoidHom.mrange f).prod (MonoidHom.mrange g) := + SetLike.coe_injective Set.range_prodMap + /-- The range of a surjective monoid hom is the whole of the codomain. -/ @[to_additive (attr := simp) /-- The range of a surjective `AddMonoid` hom is the whole of the codomain. -/] diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index 381b16158620ac..26fdd10daf025d 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -842,6 +842,11 @@ theorem domRestrict_comp_rangeRestrict (g : S →+* T) (f : R →+* S) : (g.domRestrict f.range).comp (f.rangeRestrict) = g.comp f := rfl +@[simp] +theorem range_prodMap {R' S' : Type*} [Ring R'] [Ring S'] (f : R →+* S) (g : R' →+* S') : + (f.prodMap g).range = f.range.prod g.range := + SetLike.coe_injective Set.range_prodMap + section eqLocus variable {S : Type v} [Semiring S] diff --git a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean index 815cc588c3d5f9..0a393c2b0c391b 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean @@ -662,6 +662,11 @@ theorem top_prod (s : Subsemiring S) : (⊤ : Subsemiring R).prod s = s.comap (R theorem top_prod_top : (⊤ : Subsemiring R).prod (⊤ : Subsemiring S) = ⊤ := (top_prod _).trans <| comap_top _ +@[simp] +theorem _root_.RingHom.rangeS_prodMap (f : R →+* S) (g : S →+* T) : + (f.prodMap g).rangeS = Subsemiring.prod f.rangeS g.rangeS := + SetLike.coe_injective Set.range_prodMap + protected theorem center_prod : center (R × S) = prod (center R) (center S) := SetLike.coe_injective Set.center_prod diff --git a/Mathlib/RingTheory/Ideal/Prod.lean b/Mathlib/RingTheory/Ideal/Prod.lean index a35ddec7659af5..2f9f38b8b60868 100644 --- a/Mathlib/RingTheory/Ideal/Prod.lean +++ b/Mathlib/RingTheory/Ideal/Prod.lean @@ -36,6 +36,11 @@ theorem coe_prod (I : Ideal R) (J : Ideal S) : ↑(prod I J) = (I ×ˢ J : Set ( theorem mem_prod {x : R × S} : x ∈ prod I J ↔ x.1 ∈ I ∧ x.2 ∈ J := Iff.rfl +@[simp] +theorem _root_.RingHom.ker_prodMap {T U : Type*} [Semiring T] [Semiring U] (f : R →+* S) + (g : T →+* U) : RingHom.ker (f.prodMap g) = (RingHom.ker f).prod (RingHom.ker g) := by + ext ⟨⟩; simp + @[simp] theorem prod_top_top : prod (⊤ : Ideal R) (⊤ : Ideal S) = ⊤ := Ideal.ext <| by simp From 66255bfc74956c7a9fb86c60509cc7bc7f06636d Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Tue, 23 Jun 2026 08:44:07 +0000 Subject: [PATCH 0276/1300] chore: remove useless lines (#40774) --- Mathlib/NumberTheory/RamificationInertia/Galois.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index 06d4f5a5d2f7c0..ec9ce3731a2995 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -279,8 +279,6 @@ theorem card_stabilizer_eq_card_inertia_mul_finrank (p : Ideal R) [p.IsPrime] (P : Ideal S) [P.LiesOver p] [P.IsPrime] [PerfectField p.ResidueField] : Nat.card (MulAction.stabilizer G P) = Nat.card (inertia G P) * P.inertiaDeg' R := by let := Localization.AtPrime.algebraOfLiesOver p P - let : Algebra (R ⧸ p) p.ResidueField := inferInstance - let : Algebra (S ⧸ P) P.ResidueField := inferInstance have heq : (algebraMap (S ⧸ P) P.ResidueField).comp (algebraMap (R ⧸ p) (S ⧸ P)) = (algebraMap p.ResidueField P.ResidueField).comp (algebraMap (R ⧸ p) p.ResidueField) := by ext From 41520dac113c0aad66a755d8229c4900f99fd58a Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 23 Jun 2026 09:25:06 +0000 Subject: [PATCH 0277/1300] feat: tag the pointwise Continuous/ContDiff/Measurable operation families with to_fun (#40872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several `fun_prop` lemma families about pointwise operations existed only in **eta-expanded** form (`Continuous (fun x => (f x)⁻¹)`), so `fun_prop` could not close the corresponding **point-free** goal (`Continuous f⁻¹`). This PR restates those families point-free and tags them with `@[to_fun (attr := …)]`, which regenerates the eta twin (`fun_inv`, `fun_sub`, `fun_pow`, …). Both forms then carry `fun_prop`, mirroring the existing `Continuous.mul` / `ContinuousOn.mul` setup, so `fun_prop` now matches goals in either shape (with one caveat, see below). Because of the name change of the eta version, many downstream invocations of these theorems have their name changed slightly (e.g., `.inv` becomes `.fun_inv`). In most cases this was a mechanical change; there were a few unusual edge cases, noted below and in the more detailed attached report. For further discussion, see [this Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Should.20one.20to_fun.20various.20fun_prop.20lemmas.3F). Functionally, this PR is similar to #35306, but now implemented over many further `fun_prop` lemmas. This PR was prepared by an AI agent, guided by myself. In particular the summary text in this comment was initially generated by AI and then edited by myself. Co-authored-by: Terence Tao --- .../NonUnital.lean | 2 +- .../ContinuousFunctionalCalculus/Unital.lean | 4 +- .../CStarAlgebra/GelfandNaimarkSegal.lean | 4 +- .../Calculus/ContDiff/Operations.lean | 38 +++++++++---------- Mathlib/Analysis/Calculus/Deriv/Inv.lean | 23 ++--------- .../Analysis/Calculus/Deriv/MeanValue.lean | 4 +- .../Analysis/Calculus/FDeriv/Analytic.lean | 2 +- Mathlib/Analysis/Complex/Basic.lean | 2 +- .../Analysis/Complex/Harmonic/Poisson.lean | 2 +- .../Analysis/Complex/LocallyUniformLimit.lean | 7 ++-- .../Fourier/FourierTransformDeriv.lean | 2 +- Mathlib/Analysis/MellinInversion.lean | 2 +- Mathlib/Analysis/ODE/Gronwall.lean | 2 +- .../SpecialFunctions/Log/NegMulLog.lean | 2 +- .../Trigonometric/Cotangent.lean | 2 +- .../Trigonometric/EulerSineProd.lean | 6 ++- Mathlib/MeasureTheory/Group/Arithmetic.lean | 12 +++--- .../Integral/CircleIntegral.lean | 2 +- .../Integral/CircleTransform.lean | 2 +- .../IntervalIntegral/FundThmCalculus.lean | 4 +- .../MeasureTheory/Measure/WithDensity.lean | 10 ++--- .../LSeries/DirichletContinuation.lean | 2 +- Mathlib/Probability/Moments/SubGaussian.lean | 2 +- Mathlib/Topology/Algebra/ConstMulAction.lean | 18 ++++----- Mathlib/Topology/Algebra/Group/Basic.lean | 20 +++++----- Mathlib/Topology/Algebra/Group/Defs.lean | 32 ++++++++-------- Mathlib/Topology/Algebra/GroupCompletion.lean | 4 +- Mathlib/Topology/Algebra/GroupWithZero.lean | 15 ++++---- .../Topology/Algebra/LinearMapCompletion.lean | 2 +- .../Algebra/Module/Spaces/WeakBilin.lean | 2 +- Mathlib/Topology/Algebra/Monoid.lean | 16 ++++---- Mathlib/Topology/Algebra/MulAction.lean | 18 ++++----- .../Topology/Algebra/UniformMulAction.lean | 2 +- Mathlib/Topology/ContinuousMap/Ideals.lean | 2 +- .../Topology/Instances/ENNReal/Lemmas.lean | 2 +- 35 files changed, 129 insertions(+), 142 deletions(-) diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index be142dd60e974d..303415eb28ff4d 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -580,7 +580,7 @@ lemma cfcₙ_neg : cfcₙ (fun x ↦ -(f x)) a = -(cfcₙ f a) := by obtain (ha | hf | h0) := h · simp [cfcₙ_apply_of_not_predicate a ha] · rw [cfcₙ_apply_of_not_continuousOn a hf, cfcₙ_apply_of_not_continuousOn, neg_zero] - exact fun hf_neg ↦ hf <| by simpa using hf_neg.neg + exact fun hf_neg ↦ hf <| by simpa using hf_neg.fun_neg · rw [cfcₙ_apply_of_not_map_zero a h0, cfcₙ_apply_of_not_map_zero, neg_zero] exact (h0 <| neg_eq_zero.mp ·) diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean index b72f01d4f986e4..e1daf6ea7a326d 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean @@ -770,7 +770,7 @@ noncomputable def cfcUnits (hf' : ∀ x ∈ spectrum R a, f x ≠ 0) lemma cfcUnits_pow (hf' : ∀ x ∈ spectrum R a, f x ≠ 0) (n : ℕ) (hf : ContinuousOn f (spectrum R a) := by cfc_cont_tac) (ha : p a := by cfc_tac) : (cfcUnits f a hf') ^ n = - cfcUnits _ _ (forall₂_imp (fun _ _ ↦ pow_ne_zero n) hf') (hf := hf.pow n) := by + cfcUnits _ _ (forall₂_imp (fun _ _ ↦ pow_ne_zero n) hf') (hf := hf.fun_pow n) := by ext cases n with | zero => simp [cfc_const_one R a] @@ -882,7 +882,7 @@ lemma cfc_neg : cfc (fun x ↦ -(f x)) a = -(cfc f a) := by · obtain (ha | hf) := not_and_or.mp h · simp [cfc_apply_of_not_predicate a ha] · rw [cfc_apply_of_not_continuousOn a hf, cfc_apply_of_not_continuousOn, neg_zero] - exact fun hf_neg ↦ hf <| by simpa using hf_neg.neg + exact fun hf_neg ↦ hf <| by simpa using hf_neg.fun_neg lemma cfc_neg' : cfc (-f) = (-cfc f : A → A) := by ext1 a; exact cfc_neg f a diff --git a/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean b/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean index 812a16c805f531..9d39ae0363b9a5 100644 --- a/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean +++ b/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean @@ -138,7 +138,9 @@ private lemma completion_leftMulMapPreGNS_map_smul (m : ℂ) (x : A) : (f.leftMulMapPreGNS (m • x)).completion = m • (f.leftMulMapPreGNS x).completion := by ext a induction a using induction_on with - | hp => apply isClosed_eq <;> fun_prop + | hp => + exact isClosed_eq (f.leftMulMapPreGNS (m • x)).completion.continuous + (m • (f.leftMulMapPreGNS x).completion).continuous | ih a => simp [smul_mul_assoc] /-- diff --git a/Mathlib/Analysis/Calculus/ContDiff/Operations.lean b/Mathlib/Analysis/Calculus/ContDiff/Operations.lean index 6a19277621a564..fcd9c1301e8602 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Operations.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Operations.lean @@ -793,50 +793,46 @@ theorem contDiffOn_inv {n} : ContDiffOn 𝕜 n (Inv.inv : 𝕜' → 𝕜') {0} variable {𝕜} -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContDiffWithinAt.inv {f : E → 𝕜'} {n} (hf : ContDiffWithinAt 𝕜 n f s x) (hx : f x ≠ 0) : - ContDiffWithinAt 𝕜 n (fun x => (f x)⁻¹) s x := + ContDiffWithinAt 𝕜 n f⁻¹ s x := (contDiffAt_inv 𝕜 hx).comp_contDiffWithinAt x hf -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContDiffOn.inv {f : E → 𝕜'} (hf : ContDiffOn 𝕜 n f s) (h : ∀ x ∈ s, f x ≠ 0) : - ContDiffOn 𝕜 n (fun x => (f x)⁻¹) s := fun x hx => (hf.contDiffWithinAt hx).inv (h x hx) + ContDiffOn 𝕜 n f⁻¹ s := fun x hx => (hf.contDiffWithinAt hx).inv (h x hx) -@[fun_prop] +@[to_fun (attr := fun_prop)] nonrec theorem ContDiffAt.inv {f : E → 𝕜'} (hf : ContDiffAt 𝕜 n f x) (hx : f x ≠ 0) : - ContDiffAt 𝕜 n (fun x => (f x)⁻¹) x := + ContDiffAt 𝕜 n f⁻¹ x := hf.inv hx -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContDiff.inv {f : E → 𝕜'} (hf : ContDiff 𝕜 n f) (h : ∀ x, f x ≠ 0) : - ContDiff 𝕜 n fun x => (f x)⁻¹ := by + ContDiff 𝕜 n f⁻¹ := by rw [contDiff_iff_contDiffAt]; exact fun x => hf.contDiffAt.inv (h x) -- TODO: generalize to `f g : E → 𝕜'` -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContDiffWithinAt.div {f g : E → 𝕜} {n} (hf : ContDiffWithinAt 𝕜 n f s x) (hg : ContDiffWithinAt 𝕜 n g s x) (hx : g x ≠ 0) : - ContDiffWithinAt 𝕜 n (fun x => f x / g x) s x := by - simpa only [div_eq_mul_inv] using hf.mul (hg.inv hx) + ContDiffWithinAt 𝕜 n (f / g) s x := by + change ContDiffWithinAt 𝕜 n (fun x => f x / g x) s x + simpa only [div_eq_mul_inv] using hf.mul (hg.fun_inv hx) -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContDiffOn.div {f g : E → 𝕜} {n} (hf : ContDiffOn 𝕜 n f s) (hg : ContDiffOn 𝕜 n g s) (h₀ : ∀ x ∈ s, g x ≠ 0) : ContDiffOn 𝕜 n (f / g) s := fun x hx => (hf x hx).div (hg x hx) (h₀ x hx) -@[fun_prop] -theorem ContDiffOn.fun_div {f g : E → 𝕜} {n} (hf : ContDiffOn 𝕜 n f s) - (hg : ContDiffOn 𝕜 n g s) (h₀ : ∀ x ∈ s, g x ≠ 0) : ContDiffOn 𝕜 n (fun x => f x / g x) s := - ContDiffOn.div hf hg h₀ - -@[fun_prop] +@[to_fun (attr := fun_prop)] nonrec theorem ContDiffAt.div {f g : E → 𝕜} {n} (hf : ContDiffAt 𝕜 n f x) - (hg : ContDiffAt 𝕜 n g x) (hx : g x ≠ 0) : ContDiffAt 𝕜 n (fun x => f x / g x) x := + (hg : ContDiffAt 𝕜 n g x) (hx : g x ≠ 0) : ContDiffAt 𝕜 n (f / g) x := hf.div hg hx -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContDiff.div {f g : E → 𝕜} {n} (hf : ContDiff 𝕜 n f) (hg : ContDiff 𝕜 n g) - (h0 : ∀ x, g x ≠ 0) : ContDiff 𝕜 n fun x => f x / g x := by + (h0 : ∀ x, g x ≠ 0) : ContDiff 𝕜 n (f / g) := by simp only [contDiff_iff_contDiffAt] at * exact fun x => (hf x).div (hg x) (h0 x) diff --git a/Mathlib/Analysis/Calculus/Deriv/Inv.lean b/Mathlib/Analysis/Calculus/Deriv/Inv.lean index 5222e9c6990361..05ff9f51b4928c 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Inv.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Inv.lean @@ -183,32 +183,17 @@ theorem DifferentiableWithinAt.div (hc : DifferentiableWithinAt 𝕜 c s x) DifferentiableWithinAt 𝕜 (c / d) s x := hc.fun_div hd hx -@[simp, fun_prop] -theorem DifferentiableAt.fun_div (hc : DifferentiableAt 𝕜 c x) (hd : DifferentiableAt 𝕜 d x) - (hx : d x ≠ 0) : DifferentiableAt 𝕜 (fun x => c x / d x) x := - (hc.hasDerivAt.div hd.hasDerivAt hx).differentiableAt - -@[simp, fun_prop] +@[to_fun (attr := simp, fun_prop)] theorem DifferentiableAt.div (hc : DifferentiableAt 𝕜 c x) (hd : DifferentiableAt 𝕜 d x) (hx : d x ≠ 0) : DifferentiableAt 𝕜 (c / d) x := - hc.fun_div hd hx - -@[fun_prop] -theorem DifferentiableOn.fun_div (hc : DifferentiableOn 𝕜 c s) (hd : DifferentiableOn 𝕜 d s) - (hx : ∀ x ∈ s, d x ≠ 0) : DifferentiableOn 𝕜 (fun x => c x / d x) s := fun x h => - (hc x h).div (hd x h) (hx x h) + (hc.hasDerivAt.div hd.hasDerivAt hx).differentiableAt -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem DifferentiableOn.div (hc : DifferentiableOn 𝕜 c s) (hd : DifferentiableOn 𝕜 d s) (hx : ∀ x ∈ s, d x ≠ 0) : DifferentiableOn 𝕜 (c / d) s := fun x h => (hc x h).div (hd x h) (hx x h) -@[simp, fun_prop] -theorem Differentiable.fun_div (hc : Differentiable 𝕜 c) (hd : Differentiable 𝕜 d) - (hx : ∀ x, d x ≠ 0) : - Differentiable 𝕜 (fun x => c x / d x) := fun x => (hc x).div (hd x) (hx x) - -@[simp, fun_prop] +@[to_fun (attr := simp, fun_prop)] theorem Differentiable.div (hc : Differentiable 𝕜 c) (hd : Differentiable 𝕜 d) (hx : ∀ x, d x ≠ 0) : Differentiable 𝕜 (c / d) := fun x => (hc x).div (hd x) (hx x) diff --git a/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean b/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean index 35fec7e28a8c2f..bb2d7794ab3b86 100644 --- a/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean +++ b/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean @@ -338,7 +338,7 @@ theorem Convex.image_sub_lt_mul_sub_of_deriv_lt {D : Set ℝ} (hD : Convex ℝ D have hf'_gt : ∀ x ∈ interior D, -C < deriv (fun y => -f y) x := fun x hx => by rw [deriv.fun_neg, neg_lt_neg_iff] exact lt_hf' x hx - linarith [hD.mul_sub_lt_image_sub_of_lt_deriv hf.neg hf'.neg hf'_gt x hx y hy hxy] + linarith [hD.mul_sub_lt_image_sub_of_lt_deriv hf.fun_neg hf'.neg hf'_gt x hx y hy hxy] /-- Let `f : ℝ → ℝ` be a differentiable function. If `f' < C`, then `f` grows slower than `C * x` on `D`, i.e., `f y - f x < C * (y - x)` whenever `x < y`. -/ @@ -358,7 +358,7 @@ theorem Convex.image_sub_le_mul_sub_of_deriv_le {D : Set ℝ} (hD : Convex ℝ D have hf'_ge : ∀ x ∈ interior D, -C ≤ deriv (fun y => -f y) x := fun x hx => by rw [deriv.fun_neg, neg_le_neg_iff] exact le_hf' x hx - linarith [hD.mul_sub_le_image_sub_of_le_deriv hf.neg hf'.neg hf'_ge x hx y hy hxy] + linarith [hD.mul_sub_le_image_sub_of_le_deriv hf.fun_neg hf'.neg hf'_ge x hx y hy hxy] /-- Let `f : ℝ → ℝ` be a differentiable function. If `f' ≤ C`, then `f` grows at most as fast as `C * x`, i.e., `f y - f x ≤ C * (y - x)` whenever `x ≤ y`. -/ diff --git a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean index e8a1130e401d16..fef5366e1c2606 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean @@ -88,7 +88,7 @@ theorem HasFPowerSeriesWithinAt.hasStrictFDerivWithinAt (h : HasFPowerSeriesWith refine h.isBigO_image_sub_norm_mul_norm_sub.trans_isLittleO (IsLittleO.of_norm_right ?_) refine isLittleO_iff_exists_eq_mul.2 ⟨fun y => ‖y - (x, x)‖, ?_, EventuallyEq.rfl⟩ apply Tendsto.mono_left _ nhdsWithin_le_nhds - refine (continuous_id.sub continuous_const).norm.tendsto' _ _ ?_ + refine (continuous_id.fun_sub continuous_const).norm.tendsto' _ _ ?_ rw [_root_.id, sub_self, norm_zero] theorem HasFPowerSeriesAt.hasStrictFDerivAt (h : HasFPowerSeriesAt f p x) : diff --git a/Mathlib/Analysis/Complex/Basic.lean b/Mathlib/Analysis/Complex/Basic.lean index 6e4accd7174eea..be3b9d791a5c2b 100644 --- a/Mathlib/Analysis/Complex/Basic.lean +++ b/Mathlib/Analysis/Complex/Basic.lean @@ -93,7 +93,7 @@ instance (priority := 900) _root_.NormedAlgebra.complexToReal {A : Type*} [Semin @[continuity, fun_prop] theorem continuous_normSq : Continuous normSq := by - simpa [← Complex.normSq_eq_norm_sq] using continuous_norm (E := ℂ).pow 2 + simpa [← Complex.normSq_eq_norm_sq] using continuous_norm (E := ℂ).fun_pow 2 theorem nnnorm_eq_one_of_pow_eq_one {ζ : ℂ} {n : ℕ} (h : ζ ^ n = 1) (hn : n ≠ 0) : ‖ζ‖₊ = 1 := (pow_left_inj₀ zero_le zero_le hn).1 <| by rw [← nnnorm_pow, h, nnnorm_one, one_pow] diff --git a/Mathlib/Analysis/Complex/Harmonic/Poisson.lean b/Mathlib/Analysis/Complex/Harmonic/Poisson.lean index dff01e6642c121..23f6f29bbb0d2f 100644 --- a/Mathlib/Analysis/Complex/Harmonic/Poisson.lean +++ b/Mathlib/Analysis/Complex/Harmonic/Poisson.lean @@ -60,7 +60,7 @@ theorem HarmonicOnNhd.circleAverage_re_herglotzRieszKernel_smul · apply h₂F grind [mem_ball] -- CircleIntegrable (fun z ↦ ((z - c + (w - c)) / (z - c - (w - c))).re • F z) c R - apply (ContinuousOn.smul _ _).circleIntegrable' + apply (ContinuousOn.fun_smul _ _).circleIntegrable' · apply (continuousOn_herglotz_riesz hw).mono grind [mem_ball, dist_eq_norm, mem_sphere_iff_norm, (pos_of_mem_ball hw)] · apply (h₁F.mono _).continuousOn (𝕜 := ℂ) diff --git a/Mathlib/Analysis/Complex/LocallyUniformLimit.lean b/Mathlib/Analysis/Complex/LocallyUniformLimit.lean index 85b8521479cb74..dfc0c7acfda663 100644 --- a/Mathlib/Analysis/Complex/LocallyUniformLimit.lean +++ b/Mathlib/Analysis/Complex/LocallyUniformLimit.lean @@ -65,13 +65,14 @@ theorem norm_cderiv_le (hr : 0 < r) (hf : ∀ w ∈ sphere z r, ‖f w‖ ≤ M) theorem cderiv_sub (hr : 0 < r) (hf : ContinuousOn f (sphere z r)) (hg : ContinuousOn g (sphere z r)) : cderiv r (f - g) z = cderiv r f z - cderiv r g z := by have h1 : ContinuousOn (fun w : ℂ => ((w - z) ^ 2)⁻¹) (sphere z r) := by - refine ((continuous_id'.sub continuous_const).pow 2).continuousOn.inv₀ fun w hw h => hr.ne ?_ + refine ((continuous_id'.fun_sub continuous_const).fun_pow 2).continuousOn.inv₀ + fun w hw h => hr.ne ?_ rwa [mem_sphere_iff_norm, sq_eq_zero_iff.mp h, norm_zero] at hw simp_rw [cderiv, ← smul_sub] congr 1 simpa only [Pi.sub_apply, smul_sub] using - circleIntegral.integral_sub ((h1.smul hf).circleIntegrable hr.le) - ((h1.smul hg).circleIntegrable hr.le) + circleIntegral.integral_sub ((h1.fun_smul hf).circleIntegrable hr.le) + ((h1.fun_smul hg).circleIntegrable hr.le) theorem norm_cderiv_lt (hr : 0 < r) (hfM : ∀ w ∈ sphere z r, ‖f w‖ < M) (hf : ContinuousOn f (sphere z r)) : ‖cderiv r f z‖ < M / r := by diff --git a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean index 5cf7150a64f798..3a84c32f77f3f7 100644 --- a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean +++ b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean @@ -310,7 +310,7 @@ lemma fourierPowSMulRight_eq_comp {f : V → E} {v : V} {n : ℕ} : lemma _root_.Continuous.fourierPowSMulRight {f : V → E} (hf : Continuous f) (n : ℕ) : Continuous (fun v ↦ fourierPowSMulRight L f v n) := by simp_rw [fourierPowSMulRight_eq_comp] - apply Continuous.const_smul + apply Continuous.fun_const_smul apply (smulRightL ℝ (fun (_ : Fin n) ↦ W) E).continuous₂.comp₂ _ hf exact Continuous.comp (map_continuous _) (continuous_pi (fun _ ↦ L.continuous)) diff --git a/Mathlib/Analysis/MellinInversion.lean b/Mathlib/Analysis/MellinInversion.lean index 6fdc84bdf207bc..26d5ba10ed9d78 100644 --- a/Mathlib/Analysis/MellinInversion.lean +++ b/Mathlib/Analysis/MellinInversion.lean @@ -112,7 +112,7 @@ theorem mellinInv_mellin_eq (σ : ℝ) (f : ℝ → E) {x : ℝ} (hx : 0 < x) (h simp_rw [neg_mul_eq_neg_mul] at this exact this replace hfx : ContinuousAt g (-Real.log x) := by - refine ContinuousAt.smul (by fun_prop) (ContinuousAt.comp ?_ (by fun_prop)) + refine ContinuousAt.fun_smul (by fun_prop) (ContinuousAt.comp ?_ (by fun_prop)) simpa [Real.exp_log hx] using hfx calc mellinInv σ (mellin f) x diff --git a/Mathlib/Analysis/ODE/Gronwall.lean b/Mathlib/Analysis/ODE/Gronwall.lean index 9529632c1d932e..bedc58a9ea540b 100644 --- a/Mathlib/Analysis/ODE/Gronwall.lean +++ b/Mathlib/Analysis/ODE/Gronwall.lean @@ -174,7 +174,7 @@ theorem dist_le_of_approx_trajectories_ODE_of_mem simp only [dist_eq_norm] at ha ⊢ have h_deriv : ∀ t ∈ Ico a b, HasDerivWithinAt (fun t => f t - g t) (f' t - g' t) (Ici t) t := fun t ht => (hf' t ht).sub (hg' t ht) - apply norm_le_gronwallBound_of_norm_deriv_right_le (hf.sub hg) h_deriv ha + apply norm_le_gronwallBound_of_norm_deriv_right_le (hf.fun_sub hg) h_deriv ha intro t ht have := dist_triangle4_right (f' t) (g' t) (v t (f t)) (v t (g t)) have := (hv t ht).dist_le_mul _ (hfs t ht) _ (hgs t ht) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/NegMulLog.lean b/Mathlib/Analysis/SpecialFunctions/Log/NegMulLog.lean index 72625a7781eea3..913cb41fbbf83a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/NegMulLog.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/NegMulLog.lean @@ -184,7 +184,7 @@ lemma negMulLog_mul (x y : ℝ) : negMulLog (x * y) = y * negMulLog x + x * negM ring @[fun_prop] lemma continuous_negMulLog : Continuous negMulLog := by - simpa only [negMulLog_eq_neg] using continuous_mul_log.neg + simpa only [negMulLog_eq_neg] using continuous_mul_log.fun_neg lemma differentiableOn_negMulLog : DifferentiableOn ℝ negMulLog {0}ᶜ := by simpa only [negMulLog_eq_neg] using! differentiableOn_mul_log.neg diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 46321ea1bf82e3..d5b7ed3e60971b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -247,7 +247,7 @@ open scoped Nat variable (k : ℕ) private lemma contDiffOn_inv_linear (d : ℤ) : ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z + d)) ℂ_ℤ := by - simpa using ContDiffOn.inv (by fun_prop) (fun x hx ↦ integerComplement_add_ne_zero hx d) + simpa using ContDiffOn.fun_inv (by fun_prop) (fun x hx ↦ integerComplement_add_ne_zero hx d) lemma eqOn_iteratedDeriv_cotTerm (d : ℕ) : EqOn (iteratedDeriv k (fun z ↦ cotTerm z d)) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/EulerSineProd.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/EulerSineProd.lean index 6597cad5fe44f4..a4a808bed3e34d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/EulerSineProd.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/EulerSineProd.lean @@ -160,8 +160,10 @@ theorem integral_cos_pow_eq (n : ℕ) : (∫ x in (0 : ℝ)..π / 2, cos x ^ n) = 1 / 2 * ∫ x in (0 : ℝ)..π, sin x ^ n := by rw [mul_comm (1 / 2 : ℝ), ← div_eq_iff (one_div_ne_zero (two_ne_zero' ℝ)), ← div_mul, div_one, mul_two] - have L : IntervalIntegrable _ volume 0 (π / 2) := (continuous_sin.pow n).intervalIntegrable _ _ - have R : IntervalIntegrable _ volume (π / 2) π := (continuous_sin.pow n).intervalIntegrable _ _ + have L : IntervalIntegrable _ volume 0 (π / 2) := + (continuous_sin.fun_pow n).intervalIntegrable _ _ + have R : IntervalIntegrable _ volume (π / 2) π := + (continuous_sin.fun_pow n).intervalIntegrable _ _ rw [← integral_add_adjacent_intervals L R] congr 1 · nth_rw 1 [(by ring : 0 = π / 2 - π / 2)] diff --git a/Mathlib/MeasureTheory/Group/Arithmetic.lean b/Mathlib/MeasureTheory/Group/Arithmetic.lean index d5e72ff2db5073..2e6e8412650755 100644 --- a/Mathlib/MeasureTheory/Group/Arithmetic.lean +++ b/Mathlib/MeasureTheory/Group/Arithmetic.lean @@ -349,23 +349,23 @@ section Inv variable {G α : Type*} [Inv G] [MeasurableSpace G] [MeasurableInv G] {m : MeasurableSpace α} {f : α → G} {μ : Measure α} -@[to_additive (attr := fun_prop)] -theorem Measurable.inv (hf : Measurable f) : Measurable fun x => (f x)⁻¹ := +@[to_fun (attr := to_additive (attr := fun_prop))] +theorem Measurable.inv (hf : Measurable f) : Measurable f⁻¹ := measurable_inv.comp hf -@[to_additive (attr := fun_prop)] -theorem AEMeasurable.inv (hf : AEMeasurable f μ) : AEMeasurable (fun x => (f x)⁻¹) μ := +@[to_fun (attr := to_additive (attr := fun_prop))] +theorem AEMeasurable.inv (hf : AEMeasurable f μ) : AEMeasurable f⁻¹ μ := measurable_inv.comp_aemeasurable hf @[to_additive (attr := simp)] theorem measurable_inv_iff {G : Type*} [InvolutiveInv G] [MeasurableSpace G] [MeasurableInv G] {f : α → G} : (Measurable fun x => (f x)⁻¹) ↔ Measurable f := - ⟨fun h => by simpa only [inv_inv] using h.inv, fun h => h.inv⟩ + ⟨fun h => by simpa only [inv_inv] using h.fun_inv, fun h => h.inv⟩ @[to_additive (attr := simp)] theorem aemeasurable_inv_iff {G : Type*} [InvolutiveInv G] [MeasurableSpace G] [MeasurableInv G] {f : α → G} : AEMeasurable (fun x => (f x)⁻¹) μ ↔ AEMeasurable f μ := - ⟨fun h => by simpa only [inv_inv] using h.inv, fun h => h.inv⟩ + ⟨fun h => by simpa only [inv_inv] using h.fun_inv, fun h => h.inv⟩ @[to_additive] instance Pi.measurableInv {ι : Type*} {α : ι → Type*} [∀ i, Inv (α i)] diff --git a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean index db48abb1c5e777..e79060068bfc98 100644 --- a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean @@ -327,7 +327,7 @@ theorem circleIntegrable_iff [NormedSpace ℂ E] {f : ℂ → E} {c : ℂ} (R : · have H : ∀ {θ}, circleMap 0 R θ * I ≠ 0 := fun {θ} => by simp [h₀, I_ne_zero] simpa only [inv_smul_smul₀ H] using ((continuous_circleMap 0 R).aestronglyMeasurable.mul_const - I).aemeasurable.inv.aestronglyMeasurable.smul h.aestronglyMeasurable + I).aemeasurable.fun_inv.aestronglyMeasurable.smul h.aestronglyMeasurable · simp [norm_smul, h₀] theorem ContinuousOn.circleIntegrable' {f : ℂ → E} {c : ℂ} {R : ℝ} diff --git a/Mathlib/MeasureTheory/Integral/CircleTransform.lean b/Mathlib/MeasureTheory/Integral/CircleTransform.lean index b26e92516f63da..0cd653c004775c 100644 --- a/Mathlib/MeasureTheory/Integral/CircleTransform.lean +++ b/Mathlib/MeasureTheory/Integral/CircleTransform.lean @@ -97,7 +97,7 @@ theorem continuousOn_prod_circle_transform_function {R r : ℝ} (hr : r < R) {z theorem continuousOn_norm_circleTransformBoundingFunction {R r : ℝ} (hr : r < R) (z : ℂ) : ContinuousOn ((‖·‖) ∘ circleTransformBoundingFunction R z) (closedBall z r ×ˢ univ) := by have : ContinuousOn (circleTransformBoundingFunction R z) (closedBall z r ×ˢ univ) := by - apply_rules [ContinuousOn.smul, continuousOn_const] + apply_rules [ContinuousOn.fun_smul, continuousOn_const] · simp only [deriv_circleMap] apply_rules [ContinuousOn.mul, (continuous_circleMap 0 R).comp_continuousOn continuousOn_snd, continuousOn_const] diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean index 540bba846097fc..c19eb558728a70 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean @@ -1098,8 +1098,8 @@ theorem integral_le_sub_of_hasDeriv_right_of_le (hab : a ≤ b) (hcont : Continu (hφg : ∀ x ∈ Ioo a b, φ x ≤ g' x) : (∫ y in a..b, φ y) ≤ g b - g a := by rw [← neg_le_neg_iff] convert! - sub_le_integral_of_hasDeriv_right_of_le hab hcont.neg (fun x hx => (hderiv x hx).neg) φint.neg - fun x hx => neg_le_neg (hφg x hx) using 1 + sub_le_integral_of_hasDeriv_right_of_le hab hcont.fun_neg (fun x hx => (hderiv x hx).neg) + φint.neg fun x hx => neg_le_neg (hφg x hx) using 1 · abel · simp only [← integral_neg]; rfl diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index 2cdfce72212c92..3337ad31fdd514 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -208,7 +208,7 @@ theorem withDensity_ofReal_mutuallySingular {f : α → ℝ} (hf : Measurable f) refine ⟨S, hS, ?_, ?_⟩ · rw [withDensity_apply _ hS, lintegral_eq_zero_iff hf.ennreal_ofReal, EventuallyEq] exact (ae_restrict_mem hS).mono fun x hx => ENNReal.ofReal_eq_zero.2 (le_of_lt hx) - · rw [withDensity_apply _ hS.compl, lintegral_eq_zero_iff hf.neg.ennreal_ofReal, EventuallyEq] + · rw [withDensity_apply _ hS.compl, lintegral_eq_zero_iff hf.fun_neg.ennreal_ofReal, EventuallyEq] exact (ae_restrict_mem hS.compl).mono fun x hx => ENNReal.ofReal_eq_zero.2 (not_lt.1 <| mt neg_pos.1 hx) @@ -486,9 +486,9 @@ theorem lintegral_withDensity_eq_lintegral_mul_non_measurable (μ : Measure α) dsimp rw [mul_comm, ← div_eq_mul_inv] exact div_le_of_le_mul' (hi x) - refine le_iSup_of_le (fun x => (f x)⁻¹ * i x) (le_iSup_of_le (f_meas.inv.mul i_meas) ?_) + refine le_iSup_of_le (fun x => (f x)⁻¹ * i x) (le_iSup_of_le (f_meas.fun_inv.mul i_meas) ?_) refine le_iSup_of_le A ?_ - rw [lintegral_withDensity_eq_lintegral_mul _ f_meas (f_meas.inv.mul i_meas)] + rw [lintegral_withDensity_eq_lintegral_mul _ f_meas (f_meas.fun_inv.mul i_meas)] apply lintegral_mono_ae filter_upwards [hf] intro x h'x @@ -550,7 +550,7 @@ theorem withDensity_mul (μ : Measure α) {f g : α → ℝ≥0∞} (hf : Measur lemma withDensity_inv_same_le {μ : Measure α} {f : α → ℝ≥0∞} (hf : AEMeasurable f μ) : (μ.withDensity f).withDensity f⁻¹ ≤ μ := by change (μ.withDensity f).withDensity (fun x ↦ (f x)⁻¹) ≤ μ - rw [← withDensity_mul₀ hf hf.inv] + rw [← withDensity_mul₀ hf hf.fun_inv] suffices (f * fun x ↦ (f x)⁻¹) ≤ᵐ[μ] 1 by refine (withDensity_mono this).trans ?_ rw [withDensity_one] @@ -560,7 +560,7 @@ lemma withDensity_inv_same_le {μ : Measure α} {f : α → ℝ≥0∞} (hf : AE lemma withDensity_inv_same₀ {μ : Measure α} {f : α → ℝ≥0∞} (hf : AEMeasurable f μ) (hf_ne_zero : ∀ᵐ x ∂μ, f x ≠ 0) (hf_ne_top : ∀ᵐ x ∂μ, f x ≠ ∞) : (μ.withDensity f).withDensity (fun x ↦ (f x)⁻¹) = μ := by - rw [← withDensity_mul₀ hf hf.inv] + rw [← withDensity_mul₀ hf hf.fun_inv] suffices (f * fun x ↦ (f x)⁻¹) =ᵐ[μ] 1 by rw [withDensity_congr_ae this, withDensity_one] filter_upwards [hf_ne_zero, hf_ne_top] with x hf_ne_zero hf_ne_top diff --git a/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean b/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean index 2d095f687b1e24..947ea4773befb0 100644 --- a/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean +++ b/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean @@ -390,7 +390,7 @@ lemma continuousOn_neg_logDeriv_LFunction_of_nontriv (hχ : χ ≠ 1) : ContinuousOn (fun s ↦ -deriv (LFunction χ) s / LFunction χ s) {s | LFunction χ s ≠ 0} := by have h := differentiable_LFunction hχ simpa [neg_div] using! ((h.contDiff.continuous_deriv le_rfl).continuousOn.div - h.continuous.continuousOn fun _ hw ↦ hw).neg + h.continuous.continuousOn fun _ hw ↦ hw).fun_neg end nontrivial diff --git a/Mathlib/Probability/Moments/SubGaussian.lean b/Mathlib/Probability/Moments/SubGaussian.lean index 7751694c849b57..0de6c2ca8428f9 100644 --- a/Mathlib/Probability/Moments/SubGaussian.lean +++ b/Mathlib/Probability/Moments/SubGaussian.lean @@ -852,7 +852,7 @@ lemma hasSubgaussianMGF_of_mem_Icc_of_integral_eq_zero [IsProbabilityMeasure μ] _ ≤ exp ((‖-a - -b‖₊ / 2) ^ 2 * (-t) ^ 2 / 2) := by apply ProbabilityTheory.mgf_le_of_mem_Icc_of_integral_eq_zero (hm.neg) · filter_upwards [hb] with ω ⟨hl, hr⟩ using ⟨neg_le_neg_iff.2 hr, neg_le_neg_iff.2 hl⟩ - · rw [integral_neg, hc, neg_zero] + · simp only [Pi.neg_apply]; rw [integral_neg, hc, neg_zero] · rwa [Left.neg_pos_iff] _ = exp (((‖b - a‖₊ / 2) ^ 2) * t ^ 2 / 2) := by ring_nf diff --git a/Mathlib/Topology/Algebra/ConstMulAction.lean b/Mathlib/Topology/Algebra/ConstMulAction.lean index 0ebae3e977eda3..69f48dd54a30fe 100644 --- a/Mathlib/Topology/Algebra/ConstMulAction.lean +++ b/Mathlib/Topology/Algebra/ConstMulAction.lean @@ -92,22 +92,22 @@ theorem Filter.Tendsto.const_smul {f : β → α} {l : Filter β} {a : α} (hf : variable [TopologicalSpace β] {g : β → α} {b : β} {s : Set β} -@[to_additive] +@[to_fun (attr := to_additive (attr := fun_prop))] nonrec theorem ContinuousWithinAt.const_smul (hg : ContinuousWithinAt g s b) (c : M) : - ContinuousWithinAt (fun x => c • g x) s b := + ContinuousWithinAt (c • g) s b := hg.const_smul c -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] nonrec theorem ContinuousAt.const_smul (hg : ContinuousAt g b) (c : M) : - ContinuousAt (fun x => c • g x) b := + ContinuousAt (c • g) b := hg.const_smul c -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousOn.const_smul (hg : ContinuousOn g s) (c : M) : - ContinuousOn (fun x => c • g x) s := fun x hx => (hg x hx).const_smul c + ContinuousOn (c • g) s := fun x hx => (hg x hx).const_smul c -@[to_additive (attr := continuity, fun_prop)] -theorem Continuous.const_smul (hg : Continuous g) (c : M) : Continuous fun x => c • g x := +@[to_fun (attr := to_additive (attr := continuity, fun_prop))] +theorem Continuous.const_smul (hg : Continuous g) (c : M) : Continuous (c • g) := (continuous_const_smul _).comp hg /-- If a scalar is central, then its right action is continuous when its left action is. -/ @@ -157,7 +157,7 @@ theorem Topology.IsInducing.continuousConstSMul {N β : Type*} [SMul N β] [Topo {g : β → α} (hg : IsInducing g) (f : N → M) (hf : ∀ {c : N} {x : β}, g (c • x) = f c • g x) : ContinuousConstSMul N β where continuous_const_smul c := by - simpa only [Function.comp_def, hf, hg.continuous_iff] using hg.continuous.const_smul (f c) + simpa only [Function.comp_def, hf, hg.continuous_iff] using hg.continuous.fun_const_smul (f c) @[to_additive] theorem smul_closure_subset (c : M) (s : Set α) : c • closure s ⊆ closure (c • s) := diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 62d93826965a48..6f485a3f813c0c 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -410,7 +410,7 @@ end LatticeOps theorem Topology.IsInducing.continuousInv {G H : Type*} [Inv G] [Inv H] [TopologicalSpace G] [TopologicalSpace H] [ContinuousInv H] {f : G → H} (hf : IsInducing f) (hf_inv : ∀ x, f x⁻¹ = (f x)⁻¹) : ContinuousInv G := - ⟨hf.continuous_iff.2 <| by simpa only [Function.comp_def, hf_inv] using hf.continuous.inv⟩ + ⟨hf.continuous_iff.2 <| by simpa only [Function.comp_def, hf_inv] using hf.continuous.fun_inv⟩ section IsTopologicalGroup @@ -465,7 +465,7 @@ section ZPow @[to_additive (attr := continuity, fun_prop)] theorem continuous_zpow : ∀ z : ℤ, Continuous fun a : G => a ^ z | Int.ofNat n => by simpa using continuous_pow n - | Int.negSucc n => by simpa using (continuous_pow (n + 1)).inv + | Int.negSucc n => by simpa using (continuous_pow (n + 1)).fun_inv instance AddGroup.continuousConstSMul_int {A} [AddGroup A] [TopologicalSpace A] [IsTopologicalAddGroup A] : ContinuousConstSMul ℤ A := @@ -475,8 +475,8 @@ instance AddGroup.continuousSMul_int {A} [AddGroup A] [TopologicalSpace A] [IsTopologicalAddGroup A] : ContinuousSMul ℤ A := ⟨continuous_prod_of_discrete_left.mpr continuous_zsmul⟩ -@[to_additive (attr := continuity, fun_prop)] -theorem Continuous.zpow {f : α → G} (h : Continuous f) (z : ℤ) : Continuous fun b => f b ^ z := +@[to_fun (attr := to_additive (attr := continuity, fun_prop))] +theorem Continuous.zpow {f : α → G} (h : Continuous f) (z : ℤ) : Continuous (f ^ z) := (continuous_zpow z).comp h @[to_additive] @@ -492,19 +492,19 @@ theorem Filter.Tendsto.zpow {α} {l : Filter α} {f : α → G} {x : G} (hf : Te (z : ℤ) : Tendsto (fun x => f x ^ z) l (𝓝 (x ^ z)) := (continuousAt_zpow _ _).tendsto.comp hf -@[to_additive] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousWithinAt.zpow {f : α → G} {x : α} {s : Set α} (hf : ContinuousWithinAt f s x) - (z : ℤ) : ContinuousWithinAt (fun x => f x ^ z) s x := + (z : ℤ) : ContinuousWithinAt (f ^ z) s x := Filter.Tendsto.zpow hf z -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousAt.zpow {f : α → G} {x : α} (hf : ContinuousAt f x) (z : ℤ) : - ContinuousAt (fun x => f x ^ z) x := + ContinuousAt (f ^ z) x := Filter.Tendsto.zpow hf z -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousOn.zpow {f : α → G} {s : Set α} (hf : ContinuousOn f s) (z : ℤ) : - ContinuousOn (fun x => f x ^ z) s := fun x hx => (hf x hx).zpow z + ContinuousOn (f ^ z) s := fun x hx => (hf x hx).zpow z end ZPow diff --git a/Mathlib/Topology/Algebra/Group/Defs.lean b/Mathlib/Topology/Algebra/Group/Defs.lean index 6a769265aea264..714d597f316ab4 100644 --- a/Mathlib/Topology/Algebra/Group/Defs.lean +++ b/Mathlib/Topology/Algebra/Group/Defs.lean @@ -72,21 +72,21 @@ theorem Filter.Tendsto.inv {f : α → G} {l : Filter α} {y : G} (h : Tendsto f variable {f : X → G} {s : Set X} {x : X} -@[to_additive (attr := continuity, fun_prop)] -theorem Continuous.inv (hf : Continuous f) : Continuous fun x => (f x)⁻¹ := +@[to_fun (attr := to_additive (attr := continuity, fun_prop))] +theorem Continuous.inv (hf : Continuous f) : Continuous f⁻¹ := continuous_inv.comp hf -@[to_additive] +@[to_fun (attr := to_additive (attr := fun_prop))] nonrec theorem ContinuousWithinAt.inv (hf : ContinuousWithinAt f s x) : - ContinuousWithinAt (fun x => (f x)⁻¹) s x := + ContinuousWithinAt f⁻¹ s x := hf.inv -@[to_additive (attr := fun_prop)] -nonrec theorem ContinuousAt.inv (hf : ContinuousAt f x) : ContinuousAt (fun x => (f x)⁻¹) x := +@[to_fun (attr := to_additive (attr := fun_prop))] +nonrec theorem ContinuousAt.inv (hf : ContinuousAt f x) : ContinuousAt f⁻¹ x := hf.inv -@[to_additive (attr := fun_prop)] -theorem ContinuousOn.inv (hf : ContinuousOn f s) : ContinuousOn (fun x => (f x)⁻¹) s := fun x hx ↦ +@[to_fun (attr := to_additive (attr := fun_prop))] +theorem ContinuousOn.inv (hf : ContinuousOn f s) : ContinuousOn f⁻¹ s := fun x hx ↦ (hf x hx).inv end ContinuousInv @@ -144,22 +144,22 @@ theorem Filter.Tendsto.div' {f g : α → G} {l : Filter α} {a b : G} (hf : Ten variable {f g : X → G} {s : Set X} {x : X} -@[to_additive (attr := fun_prop) sub] +@[to_additive (attr := to_fun (attr := fun_prop)) sub] nonrec theorem ContinuousAt.div' (hf : ContinuousAt f x) (hg : ContinuousAt g x) : - ContinuousAt (fun x => f x / g x) x := + ContinuousAt (f / g) x := hf.div' hg -@[to_additive sub] +@[to_additive (attr := to_fun (attr := fun_prop)) sub] theorem ContinuousWithinAt.div' (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : - ContinuousWithinAt (fun x => f x / g x) s x := + ContinuousWithinAt (f / g) s x := Filter.Tendsto.div' hf hg -@[to_additive (attr := fun_prop) sub] +@[to_additive (attr := to_fun (attr := fun_prop)) sub] theorem ContinuousOn.div' (hf : ContinuousOn f s) (hg : ContinuousOn g s) : - ContinuousOn (fun x => f x / g x) s := fun x hx => (hf x hx).div' (hg x hx) + ContinuousOn (f / g) s := fun x hx => (hf x hx).div' (hg x hx) -@[to_additive (attr := continuity, fun_prop) sub] -theorem Continuous.div' (hf : Continuous f) (hg : Continuous g) : Continuous fun x => f x / g x := +@[to_additive (attr := to_fun (attr := continuity, fun_prop)) sub] +theorem Continuous.div' (hf : Continuous f) (hg : Continuous g) : Continuous (f / g) := continuous_div'.comp₂ hf hg end ContinuousDiv diff --git a/Mathlib/Topology/Algebra/GroupCompletion.lean b/Mathlib/Topology/Algebra/GroupCompletion.lean index 6f0c55b83a8665..9c96a32278eae8 100644 --- a/Mathlib/Topology/Algebra/GroupCompletion.lean +++ b/Mathlib/Topology/Algebra/GroupCompletion.lean @@ -167,8 +167,8 @@ instance {M} [Monoid M] [DistribMulAction M α] [UniformContinuousConstSMul M α { (inferInstance : MulAction M <| Completion α) with smul_add := fun r x y ↦ induction_on₂ x y - (isClosed_eq ((continuous_fst.add continuous_snd).const_smul _) - ((continuous_fst.const_smul _).add (continuous_snd.const_smul _))) + (isClosed_eq ((continuous_fst.fun_add continuous_snd).fun_const_smul _) + ((continuous_fst.fun_const_smul _).fun_add (continuous_snd.fun_const_smul _))) fun a b ↦ by simp only [← coe_add, ← coe_smul, smul_add] smul_zero := fun r ↦ by rw [← coe_zero, ← coe_smul, smul_zero r] } diff --git a/Mathlib/Topology/Algebra/GroupWithZero.lean b/Mathlib/Topology/Algebra/GroupWithZero.lean index 08fe633b384d6e..f3e4162725415f 100644 --- a/Mathlib/Topology/Algebra/GroupWithZero.lean +++ b/Mathlib/Topology/Algebra/GroupWithZero.lean @@ -112,22 +112,23 @@ theorem Filter.Tendsto.inv₀ {a : G₀} (hf : Tendsto f l (𝓝 a)) (ha : a ≠ variable [TopologicalSpace α] +@[to_fun (attr := fun_prop)] nonrec theorem ContinuousWithinAt.inv₀ (hf : ContinuousWithinAt f s a) (ha : f a ≠ 0) : - ContinuousWithinAt (fun x => (f x)⁻¹) s a := + ContinuousWithinAt f⁻¹ s a := hf.inv₀ ha -@[fun_prop] +@[to_fun (attr := fun_prop)] nonrec theorem ContinuousAt.inv₀ (hf : ContinuousAt f a) (ha : f a ≠ 0) : - ContinuousAt (fun x => (f x)⁻¹) a := + ContinuousAt f⁻¹ a := hf.inv₀ ha -@[continuity, fun_prop] -theorem Continuous.inv₀ (hf : Continuous f) (h0 : ∀ x, f x ≠ 0) : Continuous fun x => (f x)⁻¹ := +@[to_fun (attr := continuity, fun_prop)] +theorem Continuous.inv₀ (hf : Continuous f) (h0 : ∀ x, f x ≠ 0) : Continuous f⁻¹ := continuous_iff_continuousAt.2 fun x => (hf.tendsto x).inv₀ (h0 x) -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem ContinuousOn.inv₀ (hf : ContinuousOn f s) (h0 : ∀ x ∈ s, f x ≠ 0) : - ContinuousOn (fun x => (f x)⁻¹) s := fun x hx => (hf x hx).inv₀ (h0 x hx) + ContinuousOn f⁻¹ s := fun x hx => (hf x hx).inv₀ (h0 x hx) end Inv₀ diff --git a/Mathlib/Topology/Algebra/LinearMapCompletion.lean b/Mathlib/Topology/Algebra/LinearMapCompletion.lean index 9506ff449605a0..65520a2f0cada7 100644 --- a/Mathlib/Topology/Algebra/LinearMapCompletion.lean +++ b/Mathlib/Topology/Algebra/LinearMapCompletion.lean @@ -42,7 +42,7 @@ noncomputable def completion (f : α →SL[σ] β) : Completion α →SL[σ] Com induction x using induction_on with | hp => exact isClosed_eq (continuous_map.comp <| continuous_const_smul r) - (continuous_map.const_smul _) + (continuous_map.fun_const_smul _) | ih x => simp [← Completion.coe_smul] @[simp] diff --git a/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean b/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean index 00a041c4b2d9f4..e75d37c8867b41 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean @@ -128,7 +128,7 @@ set_option backward.isDefEq.respectTransparency false in /-- Scalar multiplication by `𝕜` on `WeakBilin B` is continuous. -/ instance instContinuousSMul [ContinuousSMul 𝕜 𝕜] : ContinuousSMul 𝕜 (WeakBilin B) := by refine ⟨continuous_induced_rng.2 ?_⟩ - refine cast (congr_arg _ ?_) (continuous_fst.smul ((coeFn_continuous B).comp continuous_snd)) + refine cast (congr_arg _ ?_) (continuous_fst.fun_smul ((coeFn_continuous B).comp continuous_snd)) ext simp only [Function.comp_apply, Pi.smul_apply, map_smulₛₗ, RingHom.id_apply, LinearMap.smul_apply] diff --git a/Mathlib/Topology/Algebra/Monoid.lean b/Mathlib/Topology/Algebra/Monoid.lean index 1f2501628fd2d6..b175611ea822d6 100644 --- a/Mathlib/Topology/Algebra/Monoid.lean +++ b/Mathlib/Topology/Algebra/Monoid.lean @@ -809,8 +809,8 @@ instance AddMonoid.continuousSMul_nat {A} [AddMonoid A] [TopologicalSpace A] -- To properly fix this, we should make sure that `continuity` applies its -- lemmas with reducible transparency, preventing the unfolding of `^`. But this -- is quite an invasive change. -@[to_additive (attr := aesop safe -100 (rule_sets := [Continuous]), fun_prop)] -theorem Continuous.pow {f : X → M} (h : Continuous f) (n : ℕ) : Continuous fun b => f b ^ n := +@[to_fun (attr := to_additive (attr := aesop safe -100 (rule_sets := [Continuous]), fun_prop))] +theorem Continuous.pow {f : X → M} (h : Continuous f) (n : ℕ) : Continuous (f ^ n) := (continuous_pow n).comp h @[to_additive] @@ -826,19 +826,19 @@ theorem Filter.Tendsto.pow {l : Filter α} {f : α → M} {x : M} (hf : Tendsto Tendsto (fun x => f x ^ n) l (𝓝 (x ^ n)) := (continuousAt_pow _ _).tendsto.comp hf -@[to_additive] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousWithinAt.pow {f : X → M} {x : X} {s : Set X} (hf : ContinuousWithinAt f s x) - (n : ℕ) : ContinuousWithinAt (fun x => f x ^ n) s x := + (n : ℕ) : ContinuousWithinAt (f ^ n) s x := Filter.Tendsto.pow hf n -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousAt.pow {f : X → M} {x : X} (hf : ContinuousAt f x) (n : ℕ) : - ContinuousAt (fun x => f x ^ n) x := + ContinuousAt (f ^ n) x := Filter.Tendsto.pow hf n -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousOn.pow {f : X → M} {s : Set X} (hf : ContinuousOn f s) (n : ℕ) : - ContinuousOn (fun x => f x ^ n) s := fun x hx => (hf x hx).pow n + ContinuousOn (f ^ n) s := fun x hx => (hf x hx).pow n /-- If `R` acts on `A` via `A`, then continuous multiplication implies continuous scalar multiplication by constants. diff --git a/Mathlib/Topology/Algebra/MulAction.lean b/Mathlib/Topology/Algebra/MulAction.lean index 04f549af6779c9..0ec40fe17fabd7 100644 --- a/Mathlib/Topology/Algebra/MulAction.lean +++ b/Mathlib/Topology/Algebra/MulAction.lean @@ -117,22 +117,22 @@ theorem Filter.Tendsto.smul_const {f : α → M} {l : Filter α} {c : M} (hf : T variable {f : Y → M} {g : Y → X} {b : Y} {s : Set Y} -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousWithinAt.smul (hf : ContinuousWithinAt f s b) (hg : ContinuousWithinAt g s b) : - ContinuousWithinAt (fun x => f x • g x) s b := + ContinuousWithinAt (f • g) s b := Filter.Tendsto.smul hf hg -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousAt.smul (hf : ContinuousAt f b) (hg : ContinuousAt g b) : - ContinuousAt (fun x => f x • g x) b := + ContinuousAt (f • g) b := Filter.Tendsto.smul hf hg -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem ContinuousOn.smul (hf : ContinuousOn f s) (hg : ContinuousOn g s) : - ContinuousOn (fun x => f x • g x) s := fun x hx => (hf x hx).smul (hg x hx) + ContinuousOn (f • g) s := fun x hx => (hf x hx).smul (hg x hx) -@[to_additive (attr := continuity, fun_prop)] -theorem Continuous.smul (hf : Continuous f) (hg : Continuous g) : Continuous fun x => f x • g x := +@[to_fun (attr := to_additive (attr := continuity, fun_prop))] +theorem Continuous.smul (hf : Continuous f) (hg : Continuous g) : Continuous (f • g) := continuous_smul.comp (hf.prodMk hg) /-- If a scalar action is central, then its right action is continuous when its left action is. -/ @@ -191,7 +191,7 @@ lemma Topology.IsInducing.continuousSMul {N : Type*} [SMul N Y] [TopologicalSpac ContinuousSMul N Y where continuous_smul := by simpa only [hg.continuous_iff, Function.comp_def, hsmul] - using (hf.comp continuous_fst).smul <| hg.continuous.comp continuous_snd + using (hf.comp continuous_fst).fun_smul <| hg.continuous.comp continuous_snd @[to_additive] instance SMulMemClass.continuousSMul {S : Type*} [SetLike S X] [SMulMemClass S M X] (s : S) : diff --git a/Mathlib/Topology/Algebra/UniformMulAction.lean b/Mathlib/Topology/Algebra/UniformMulAction.lean index 99c5fecdd7ece9..a5969d94f8b291 100644 --- a/Mathlib/Topology/Algebra/UniformMulAction.lean +++ b/Mathlib/Topology/Algebra/UniformMulAction.lean @@ -238,7 +238,7 @@ noncomputable instance [Monoid M] [MulAction M X] [UniformContinuousConstSMul M MulAction M (Completion X) where one_smul := ext' (continuous_const_smul _) continuous_id fun a => by rw [← coe_smul, one_smul] mul_smul x y := - ext' (continuous_const_smul _) ((continuous_const_smul _).const_smul _) fun a => by + ext' (continuous_const_smul _) ((continuous_const_smul _).fun_const_smul _) fun a => by simp only [← coe_smul, mul_smul] end Completion diff --git a/Mathlib/Topology/ContinuousMap/Ideals.lean b/Mathlib/Topology/ContinuousMap/Ideals.lean index b13c306a8ecc46..7ab99056669275 100644 --- a/Mathlib/Topology/ContinuousMap/Ideals.lean +++ b/Mathlib/Topology/ContinuousMap/Ideals.lean @@ -264,7 +264,7 @@ theorem idealOfSet_ofIdeal_eq_closure (I : Ideal C(X, 𝕜)) : refine ⟨{y : X | g y ≠ 0} ∩ t, mem_nhdsWithin_iff_exists_mem_nhds_inter.mpr ⟨_, this, Set.Subset.rfl⟩, - ⟨⟨fun x => ‖g x‖₊ ^ 2, (map_continuous g).nnnorm.pow 2⟩, ?_, fun x hx => + ⟨⟨fun x => ‖g x‖₊ ^ 2, (map_continuous g).nnnorm.fun_pow 2⟩, ?_, fun x hx => pow_pos (norm_pos_iff.mpr hx.1) 2⟩⟩ convert! I.mul_mem_left (star g) hI ext diff --git a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean index 1e3ffeaae4adad..06a8d14917dfe5 100644 --- a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean @@ -464,7 +464,7 @@ theorem inv_liminf {ι : Sort _} {x : ι → ℝ≥0∞} {l : Filter ι} : @[fun_prop] protected theorem continuous_zpow : ∀ n : ℤ, Continuous (· ^ n : ℝ≥0∞ → ℝ≥0∞) | (n : ℕ) => mod_cast ENNReal.continuous_pow n - | .negSucc n => by simpa using (ENNReal.continuous_pow _).inv + | .negSucc n => by simpa using (ENNReal.continuous_pow _).fun_inv @[deprecated (since := "2026-01-15")] protected alias tendsto_inv_iff := tendsto_inv_iff From 059f3b6cd2acee40e6db108d5c9946ae2d0efa29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Jun 2026 09:25:09 +0000 Subject: [PATCH 0278/1300] feat(Algebra/Homology): existence of injective resolutions for cochain complexes (#40887) --- .../Homology/DerivedCategory/TStructure.lean | 2 +- .../Homology/Embedding/CochainComplex.lean | 20 +++++++-- .../Algebra/Homology/Factorizations/CM5a.lean | 43 ++++++++++++++++++- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean index ae92cb4c519546..085d7772a0baca 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean @@ -76,7 +76,7 @@ noncomputable def TStructure.t : TStructure (DerivedCategory C) where rw [id_comp] rfl · dsimp - rw [← Q.map_comp, CochainComplex.g_shortComplexTruncLEX₃ToTruncGE, + rw [← Q.map_comp, CochainComplex.g_shortComplexTruncLEX₃ToTruncGE .., Iso.hom_inv_id_assoc] /-- Given `X : DerivedCategory C` and `n : ℤ`, this property means diff --git a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean index 800a7708629da9..ae06df80b4d34b 100644 --- a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean +++ b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean @@ -431,19 +431,33 @@ lemma shortComplexTruncLE_shortExact (n : ℤ) : (K.shortComplexTruncLE n).ShortExact := by apply HomologicalComplex.shortComplexTruncLE_shortExact -variable (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) +variable (n₀ n₁ : ℤ) /-- The canonical morphism `(K.shortComplexTruncLE n₀).X₃ ⟶ K.truncGE n₁`. -/ -noncomputable abbrev shortComplexTruncLEX₃ToTruncGE : +noncomputable abbrev shortComplexTruncLEX₃ToTruncGE (h : n₀ + 1 = n₁ := by lia) : (K.shortComplexTruncLE n₀).X₃ ⟶ K.truncGE n₁ := HomologicalComplex.shortComplexTruncLEX₃ToTruncGE K (Embedding.embeddingUpInt_areComplementary n₀ n₁ h) @[reassoc] -lemma g_shortComplexTruncLEX₃ToTruncGE : +lemma g_shortComplexTruncLEX₃ToTruncGE (h : n₀ + 1 = n₁ := by lia) : (K.shortComplexTruncLE n₀).g ≫ K.shortComplexTruncLEX₃ToTruncGE n₀ n₁ h = K.πTruncGE n₁ := by apply HomologicalComplex.g_shortComplexTruncLEX₃ToTruncGE +lemma injective_opcycles [Injective (K.X n₀)] [Injective (K.X n₁)] + [K.IsStrictlyGE n₀] (hK : K.ExactAt n₀) (h : n₀ + 1 = n₁ := by lia) : + Injective (K.opcycles n₁) := by + let S : ShortComplex C := ShortComplex.mk (K.d n₀ n₁) (K.pOpcycles n₁) (by simp) + have : Mono S.f := by + let T := K.sc' (n₀ - 1) n₀ n₁ + have hT : T.Exact := by + rwa [← K.exactAt_iff' (n₀ - 1) n₀ n₁ (by simp) (by simpa)] + exact hT.mono_g ((K.isZero_of_isStrictlyGE n₀ _).eq_of_src ..) + have hS : S.ShortExact := + { exact := S.exact_of_g_is_cokernel (K.opcyclesIsCokernel n₀ n₁ (by simp [← h])) } + exact Retract.injective + { i := _, r := _, retract := (hS.splittingOfInjective).s_g } + end Abelian end CochainComplex diff --git a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean index 30242a2ebf1749..42fd1f3e186362 100644 --- a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean +++ b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean @@ -5,10 +5,9 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.DerivedCategory.HomologySequence +public import Mathlib.Algebra.Homology.DerivedCategory.TStructure public import Mathlib.Algebra.Homology.Factorizations.CM5b public import Mathlib.Algebra.Homology.HomologicalComplexLimitsEventuallyConstant -public import Mathlib.Algebra.Homology.Refinements public import Mathlib.Algebra.Homology.SingleHomology public import Mathlib.CategoryTheory.Category.Factorisation public import Mathlib.CategoryTheory.Functor.OfSequence @@ -49,6 +48,7 @@ lemma `cm5a_cof`. -/ + open CategoryTheory Limits Opposite Abelian HomologicalComplex Pretriangulated variable {C : Type*} [Category* C] [Abelian C] @@ -652,4 +652,43 @@ public lemma cm5a (n : ℤ) [K.IsStrictlyGE (n + 1)] [L.IsStrictlyGE n] : exact ⟨K', inferInstance, ι, π ≫ p, inferInstance, inferInstance, MorphismProperty.comp_mem _ _ _ hπ hp, by simp⟩ +open ZeroObject + +variable (K) + +public lemma exists_mono_quasiIso_injective (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁ := by lia) + [K.IsStrictlyGE n₁] : + ∃ (L : CochainComplex C ℤ) (i : K ⟶ L) (_hi : Mono i) (_hi' : QuasiIso i) + (_ : ∀ (n : ℤ), Injective (L.X n)), L.IsStrictlyGE n₀ := by + have : K.IsStrictlyGE (n₀ + 1) := by rw [h]; infer_instance + obtain ⟨L, hL, i, p, hi, hi', hp, _⟩ := cm5a (0 : K ⟶ 0) n₀ + exact ⟨L, i, hi, hi', (degreewiseEpiWithInjectiveKernel_iff_of_isZero p + (Limits.isZero_zero _)).1 hp, hL⟩ + +public lemma exists_quasiIso_injective (n : ℤ) [K.IsStrictlyGE n] : + ∃ (L : CochainComplex C ℤ) (i : K ⟶ L) (_hi' : QuasiIso i) + (_hL : ∀ (n : ℤ), Injective (L.X n)), L.IsStrictlyGE n := by + /- The proof proceeds by first applying `exists_mono_quasiIso_injective` in order to + obtain a monomorphism `K ⟶ L` that is also a quasi-isomorphism + with `L` consisting of injective objects and `L` lying in degrees `≥ n - 1`. + Then, as it is quasi-isomorphic to `K`, the cochain complex `L` is cohomologically + in degrees `≥ n`, so that the composition `K ⟶ L ⟶ L.truncGE n` is a quasi-isomorphism. + In order to conclude, one needs to show that `(L.truncGE n).X n` is injective, + i.e. that `L.opcycles n` is injective. -/ + have : HasDerivedCategory C := MorphismProperty.HasLocalization.standard _ + obtain ⟨L, i, _, _, hL, _⟩ := exists_mono_quasiIso_injective K (n - 1) n (by simp) + have : L.IsGE n := by + have hK : K.IsGE n := inferInstance + rw [← DerivedCategory.isGE_Q_obj_iff] at hK ⊢ + exact DerivedCategory.TStructure.t.isGE_of_iso (asIso (DerivedCategory.Q.map i)) n + have : QuasiIso (L.πTruncGE n) := (L.quasiIso_πTruncGE_iff n).mpr inferInstance + have : Injective (L.opcycles n) := + L.injective_opcycles (n - 1) n (L.exactAt_of_isGE n (n - 1)) + -- note: this `i ≫ L.πTruncGE n` is a mono in degrees > n, but it may not be in degree n + refine ⟨L.truncGE n, i ≫ L.πTruncGE n, inferInstance, fun q ↦ ?_, inferInstance⟩ + obtain h | rfl | h := lt_trichotomy q n + · exact (isZero_of_isStrictlyGE _ n _ h).injective + · exact Injective.of_iso (L.truncGEXIsoOpcycles q).symm inferInstance + · exact Injective.of_iso (L.truncGEXIso n q h).symm (hL q) + end CochainComplex.Plus.modelCategoryQuillen From e833f296fdce138502a72d3cddb2b45984448558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Jun 2026 09:54:05 +0000 Subject: [PATCH 0279/1300] feat(Algebra/Homology): homological complexes in full subcategories (#40892) --- Mathlib.lean | 1 + Mathlib/Algebra/Homology/FullSubcategory.lean | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 Mathlib/Algebra/Homology/FullSubcategory.lean diff --git a/Mathlib.lean b/Mathlib.lean index e172db56965dbd..7566842d733330 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -618,6 +618,7 @@ public import Mathlib.Algebra.Homology.ExactSequenceFour public import Mathlib.Algebra.Homology.Factorizations.Basic public import Mathlib.Algebra.Homology.Factorizations.CM5a public import Mathlib.Algebra.Homology.Factorizations.CM5b +public import Mathlib.Algebra.Homology.FullSubcategory public import Mathlib.Algebra.Homology.Functor public import Mathlib.Algebra.Homology.GrothendieckAbelian public import Mathlib.Algebra.Homology.HasNoLoop diff --git a/Mathlib/Algebra/Homology/FullSubcategory.lean b/Mathlib/Algebra/Homology/FullSubcategory.lean new file mode 100644 index 00000000000000..ad1d853e76f99d --- /dev/null +++ b/Mathlib/Algebra/Homology/FullSubcategory.lean @@ -0,0 +1,45 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.HomologicalComplex + +/-! +# Homological complexes in full subcategories + +-/ + +@[expose] public section + +open CategoryTheory + +namespace HomologicalComplex + +/-- Given `P : ObjectProperty V` and `K : HomologicalComplex V c`, +this is a lift of `K` in `HomologicalComplex P.FullSubcategory c` +when `K.X n` satisfies `P` for all `n`. -/ +@[simps X d] +def liftObjectProperty {ι : Type*} {c : ComplexShape ι} + {V : Type*} [Category* V] [Preadditive V] (P : ObjectProperty V) + (K : HomologicalComplex V c) (hK : ∀ (n : ι), P (K.X n)) : + HomologicalComplex P.FullSubcategory c where + X n := ⟨_, hK n⟩ + d i j := ObjectProperty.homMk (K.d i j) + +set_option backward.defeqAttrib.useBackward true in +/-- The functor `D ⥤ HomologicalComplex P.FullSubcategory c` +which is obtained by lifting a functor `D ⥤ HomologicalComplex V c` +when for any `X : D` and `n`, the object `(F.obj X).X n` +satisfies a property `P : ObjectProperty V`. -/ +@[simps] +def liftFunctorObjectProperty {D : Type*} [Category* D] {ι : Type*} {c : ComplexShape ι} + {V : Type*} [Category* V] [Preadditive V] (P : ObjectProperty V) + (F : D ⥤ HomologicalComplex V c) (hF : ∀ (X : D) (n : ι), P ((F.obj X).X n)) : + D ⥤ HomologicalComplex P.FullSubcategory c where + obj X := liftObjectProperty _ (F.obj X) (hF X) + map f := { f n := ObjectProperty.homMk ((F.map f).f n) } + +end HomologicalComplex From b1630e12590032cf0c4389a5499001644e8959c9 Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Tue, 23 Jun 2026 09:54:08 +0000 Subject: [PATCH 0280/1300] feat: add delaborators for `mfderivWithin`, `HasMFDerivWithinAt` and `HasMFDerivAt` (#40898) I also added a section in the test file for the cases that include `T%`. --- Mathlib/Geometry/Manifold/Notation.lean | 69 ++++++++++- .../Notation/Delaborators.lean | 116 +++++++++++++++++- 2 files changed, 182 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index f5618f953402fb..4165465c5cf227 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -1102,7 +1102,25 @@ arguments that can use the `T%` elaborator. -/ let fs ← withAppArg delab `(mfderiv% $fs) >>= annotateGoToSyntaxDef --- TODO: add a delaborator for mfderivWithin (with a test) +/-- Delaborator for `mfderivWithin` using the custom elaborator, and special-casing +arguments that can use the `T%` elaborator. -/ +@[app_delab mfderivWithin] meta def delabMFDerivWithin : Delab := do + whenPPOption getPPNotation do + withOverApp 22 do + let ss ← withAppArg delab + try + let fe := (← getExpr).getAppArgs[20]! + let .lam n _ b _ := fe | failure + guard <| b.isAppOf ``Bundle.TotalSpace.mk' + let σe := b.getAppArgs[4]!.getAppFn + guard <| σe.isFVar + let Tσs ← withNaryArg 20 do + let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + `(T% $σs) >>= annotateGoToSyntaxDef + `(mfderiv[$ss] ($Tσs)) >>= annotateGoToSyntaxDef + catch _ => + let fs ← withNaryArg 20 delab + `(mfderiv[$ss] $fs) >>= annotateGoToSyntaxDef /-- Delaborator for `MDifferentiable` using the custom elaborator, and special-casing arguments that can use the `T%` elaborator. -/ @@ -1182,6 +1200,53 @@ arguments that can use the `T%` elaborator. -/ let fs ← withNaryArg 20 <| delab `(MDiffAt[$ss] $fs) >>= annotateGoToSyntaxDef +/-- Delaborator for `HasMFDerivWithinAt` using the custom elaborator, and special-casing +arguments that can use the `T%` elaborator. -/ +@[app_delab HasMFDerivWithinAt] meta def delabHasMFDerivWithinAt : Delab := do + whenPPOption getPPNotation do + withOverApp 24 do + let ss ← withNaryArg 21 delab + let xs ← withNaryArg 22 delab + let f' ← withNaryArg 23 delab + try + let f := (← getExpr).getAppArgs[20]! + let .lam n _ b _ := f | failure + guard <| b.isAppOf ``Bundle.TotalSpace.mk' + let s := b.getAppArgs[4]!.getAppFn + guard <| s.isFVar + let σe := b.getAppArgs[4]!.getAppFn + guard <| σe.isFVar + let Tσs ← withNaryArg 20 do + let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + `((T% $σs)) >>= annotateGoToSyntaxDef + `(HasMFDerivAt[$ss] $Tσs $xs $f') >>= annotateGoToSyntaxDef + catch _ => + let fs ← withNaryArg 20 delab + `(HasMFDerivAt[$ss] $fs $xs $f') >>= annotateGoToSyntaxDef + +/-- Delaborator for `HasMFDerivWithinAt` using the custom elaborator, and special-casing +arguments that can use the `T%` elaborator. -/ +@[app_delab HasMFDerivAt] meta def delabHasMFDerivAt : Delab := do + whenPPOption getPPNotation do + withOverApp 23 do + let xs ← withNaryArg 21 delab + let f' ← withNaryArg 22 delab + try + let f := (← getExpr).getAppArgs[20]! + let .lam n _ b _ := f | failure + guard <| b.isAppOf ``Bundle.TotalSpace.mk' + let s := b.getAppArgs[4]!.getAppFn + guard <| s.isFVar + let σe := b.getAppArgs[4]!.getAppFn + guard <| σe.isFVar + let Tσs ← withNaryArg 20 do + let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + `((T% $σs)) >>= annotateGoToSyntaxDef + `(HasMFDerivAt% $Tσs $xs $f') >>= annotateGoToSyntaxDef + catch _ => + let fs ← withNaryArg 20 delab + `(HasMFDerivAt% $fs $xs $f') >>= annotateGoToSyntaxDef + /-- Delaborator for `UniqueMDiffOn` using the custom elaborator. -/ @[app_delab UniqueMDiffOn] meta def delabUniqueMDiffOn : Delab := do whenPPOption getPPNotation do @@ -1197,7 +1262,7 @@ arguments that can use the `T%` elaborator. -/ `(UniqueMDiffAt[$ss]) >>= annotateGoToSyntaxDef -- TODO: add more delaborators (and tests) for --- ContMDiff, ContMDiffOn, ContMDiffAt, ContMDiffWithinAt, HasMFDerivAt, HasMFDerivWithinAt +-- ContMDiff, ContMDiffOn, ContMDiffAt, ContMDiffWithinAt -- TODO: when adding more elaborators, also add the corresponding delaborators diff --git a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean index be21a824b56d34..6c43114e28e058 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean @@ -18,7 +18,7 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I ∞ M] - (f : M → M) (x : M) (s : Set M) + (f : M → M) (x : M) (s : Set M) (f' : TangentSpace I x →L[ℝ] TangentSpace I (f x)) (v : (x : M) → TangentSpace I x) /-- info: MDiff f : Prop -/ @@ -74,6 +74,14 @@ variable #guard_msgs in #check mfderiv% (T% v) x +/-- info: mfderiv[s] f x : TangentSpace I x →L[ℝ] TangentSpace I (f x) -/ +#guard_msgs in +#check mfderivWithin I I f s x + +/-- info: mfderiv[s] f x : TangentSpace I x →L[ℝ] TangentSpace I (f x) -/ +#guard_msgs in +#check mfderiv[s] f x + /-- info: ⟨x, v x⟩ : TotalSpace E (TangentSpace I) -/ #guard_msgs in #check TotalSpace.mk' E x (v x) @@ -98,6 +106,111 @@ variable #guard_msgs in #check UniqueMDiffWithinAt (𝕜 := ℝ) I s +/-- info: HasMFDerivAt[s] f x f' : Prop -/ +#guard_msgs in +#check HasMFDerivWithinAt I I f s x f' + +/-- info: HasMFDerivAt[s] f x f' : Prop -/ +#guard_msgs in +#check HasMFDerivAt[s] f x f' + +/-- info: HasMFDerivAt% f x f' : Prop -/ +#guard_msgs in +#check HasMFDerivAt I I f x f' + +/-- info: HasMFDerivAt% f x f' : Prop -/ +#guard_msgs in +#check HasMFDerivAt% f x f' + +section TotalSpace + +variable {𝕜 B : Type*} {E : B → Type*} + +variable + -- Let `E` be a fiber bundle with base `B` and fiber `F` (a vector space over `𝕜`) + [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] [∀ x, TopologicalSpace (E x)] + [NormedAddCommGroup F] [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 F] [FiberBundle F E] + -- Moreover let `E` be a vector bundle + [(x : B) → AddCommGroup (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] + -- Let the base `B` be charted over a fixed model space `HB` + {HB : Type*} [TopologicalSpace HB] [ChartedSpace HB B] + -- Moreover let `HB` be modelled on a normed space `EB` so that `B` (and hence `E`) have + -- differentiable structures + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {I : ModelWithCorners 𝕜 EB HB} + +variable {f : B → 𝕜} {a : 𝕜} {s : Π x : B, E x} {u : Set B} {x₀ : B} + {f' : TangentSpace I x₀ →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) (⟨x₀, s x₀⟩ : TotalSpace F E)} + +/-- +info: mfderiv% (T% s) : (x : B) → TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) ⟨x, s x⟩ +-/ +#guard_msgs in +#check mfderiv I (I.prod 𝓘(𝕜, F)) (T% s) + +/-- +info: mfderiv% (T% s) : (x : B) → TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) ⟨x, s x⟩ +-/ +#guard_msgs in +#check mfderiv% (T% s) + +/-- info: mfderiv[u] (T% s) x₀ : TangentSpace I x₀ →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) ⟨x₀, s x₀⟩ -/ +#guard_msgs in +#check mfderivWithin I (I.prod 𝓘(𝕜, F)) (T% s) u x₀ + +/-- info: mfderiv[u] (T% s) x₀ : TangentSpace I x₀ →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) ⟨x₀, s x₀⟩ -/ +#guard_msgs in +#check mfderiv[u] (T% s) x₀ + +/-- info: MDiff (T% s) : Prop -/ +#guard_msgs in +#check MDifferentiable I (I.prod 𝓘(𝕜, F)) (T% s) + +/-- info: MDiff (T% s) : Prop -/ +#guard_msgs in +#check MDiff (T% s) + +/-- info: MDiffAt (T% s) x₀ : Prop -/ +#guard_msgs in +#check MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (T% s) x₀ + +/-- info: MDiffAt (T% s) x₀ : Prop -/ +#guard_msgs in +#check MDiffAt (T% s) x₀ + +/-- info: MDiff[u] (T% s) : Prop -/ +#guard_msgs in +#check MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (T% s) u + +/-- info: MDiff[u] (T% s) : Prop -/ +#guard_msgs in +#check MDiff[u] (T% s) + +/-- info: MDiffAt[u] (T% s) x₀ : Prop -/ +#guard_msgs in +#check MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (T% s) u x₀ + +/-- info: MDiffAt[u] (T% s) x₀ : Prop -/ +#guard_msgs in +#check MDiffAt[u] (T% s) x₀ + +/-- info: HasMFDerivAt[u] (T% s) x₀ f' : Prop -/ +#guard_msgs in +#check HasMFDerivWithinAt I (I.prod 𝓘(𝕜, F)) (T% s) u x₀ f' + +/-- info: HasMFDerivAt[u] (T% s) x₀ f' : Prop -/ +#guard_msgs in +#check HasMFDerivAt[u] (T% s) x₀ f' + +/-- info: HasMFDerivAt% (T% s) x₀ f' : Prop -/ +#guard_msgs in +#check HasMFDerivAt I (I.prod 𝓘(𝕜, F)) (T% s) x₀ f' + +/-- info: HasMFDerivAt% (T% s) x₀ f' : Prop -/ +#guard_msgs in +#check HasMFDerivAt% (T% s) x₀ f' + +end TotalSpace + section ambiguity variable {g : E × E → M} in @@ -142,6 +255,7 @@ inst✝ : IsManifold I ∞ M f : M → M x : M s : Set M +f' : TangentSpace I x →L[ℝ] TangentSpace I (f x) v : (x : M) → TangentSpace I x g✝ g : E × E → E × E ⊢ MDiff id From 569b039f070436077c28d4080f66299e0995e91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:09:20 +0000 Subject: [PATCH 0281/1300] feat(Algebra/Homology): bounded derived categories (#40923) --- .../Homology/DerivedCategory/TStructure.lean | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean index 085d7772a0baca..8ee57cc096ea31 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean @@ -193,4 +193,29 @@ lemma exists_iso_singleFunctor_obj_of_isGE_of_isLE obtain ⟨Y, ⟨e'⟩⟩ := CochainComplex.exists_iso_single K n exact ⟨Y, ⟨e ≪≫ Q.mapIso e'⟩⟩ + +open DerivedCategory.TStructure + +variable (C) + +/-- The bounded above derived category of an abelian category. -/ +abbrev Minus : Type max u v := (t : TStructure (DerivedCategory C)).minus.FullSubcategory + +/-- The bounded below derived category of an abelian category. -/ +abbrev Plus : Type max u v := (t : TStructure (DerivedCategory C)).plus.FullSubcategory + +/-- The bounded derived category of an abelian category. -/ +abbrev Bounded : Type max u v := (t : TStructure (DerivedCategory C)).bounded.FullSubcategory + +variable {C} + +/-- The inclusion of the bounded above derived category. -/ +noncomputable abbrev Minus.ι : Minus C ⥤ DerivedCategory C := t.minus.ι + +/-- The inclusion of the bounded below derived category. -/ +noncomputable abbrev Plus.ι : Plus C ⥤ DerivedCategory C := t.plus.ι + +/-- The inclusion of the bounded derived category. -/ +noncomputable abbrev Bounded.ι : Bounded C ⥤ DerivedCategory C := t.bounded.ι + end DerivedCategory From fe35a4e191178bab40bd634844b7237425b7ab30 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:09:23 +0000 Subject: [PATCH 0282/1300] chore(CategoryTheory/Sites/Spaces): relate `IsOpenCover` and `GrothendieckTopology.CoversTop` (#40936) We also add a lemma about `TopologicalSpace.Opens.IsBasis`, which is not directly related but also used in #40052. --- Mathlib/CategoryTheory/Sites/Spaces.lean | 16 ++++++++++++++-- Mathlib/Topology/Sets/Opens.lean | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Sites/Spaces.lean b/Mathlib/CategoryTheory/Sites/Spaces.lean index 364e392890809d..637268ca43dd1b 100644 --- a/Mathlib/CategoryTheory/Sites/Spaces.lean +++ b/Mathlib/CategoryTheory/Sites/Spaces.lean @@ -5,10 +5,10 @@ Authors: Bhavik Mehta -/ module -public import Mathlib.CategoryTheory.Sites.Grothendieck +public import Mathlib.CategoryTheory.Sites.CoversTop.Basic public import Mathlib.CategoryTheory.Sites.Pretopology public import Mathlib.CategoryTheory.Limits.Lattice -public import Mathlib.Topology.Sets.Opens +public import Mathlib.Topology.Sets.OpenCover /-! # Grothendieck topology on a topological space @@ -96,4 +96,16 @@ theorem pretopology_toGrothendieck : rw [← toPretopology_grothendieckTopology] apply (Pretopology.gi (Opens T)).l_u_eq +lemma coversTop_iff {ι : Type*} (U : ι → Opens T) : + (grothendieckTopology T).CoversTop U ↔ IsOpenCover U := by + rw [GrothendieckTopology.coversTop_iff_of_isTerminal _ ⊤ isTerminalTop] + dsimp [Opens.grothendieckTopology] + simp only [IsOpenCover, eq_top_iff, SetLike.le_def, exists_and_right, Opens.mem_top, + Opens.mem_iSup, forall_const] + refine ⟨fun h x ↦ ?_, fun hU x hx ↦ ?_⟩ + · obtain ⟨V, ⟨u, ⟨i, ⟨hi⟩⟩⟩, hx⟩ := h x trivial + use i, leOfHom hi hx + · obtain ⟨i, hi⟩ := hU (x := x) + exact ⟨U i, ⟨homOfLE le_top, ⟨i, ⟨𝟙 _⟩⟩⟩, hi⟩ + end Opens diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index 13e02d1439fc4c..7c3bb782828e04 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -49,6 +49,7 @@ We define order structures on both `Opens α` (`CompleteLattice`, `Frame`) and ` @[expose] public section +universe u open Filter Function Order Set @@ -345,6 +346,14 @@ theorem isBasis_iff_cover {B : Set (Opens α)} : rcases mem_sSup.1 hx with ⟨U, Us, xU⟩ exact ⟨U, hUs Us, xU, le_sSup Us⟩ +lemma IsBasis.exists_iSup_eq {X : Type u} [TopologicalSpace X] {ι : Type*} + {U : ι → TopologicalSpace.Opens X} (hU : TopologicalSpace.Opens.IsBasis (Set.range U)) + (W : TopologicalSpace.Opens X) : ∃ (κ : Type u) (a : κ → ι), W = ⨆ (k : κ), U (a k) := by + obtain ⟨Us, hsub, hUs⟩ := Opens.isBasis_iff_cover.mp hU W + choose a ha using hsub + use Us, fun i ↦ a i.2 + simp [hUs, ha, sSup_eq_iSup' Us] + /-- If `α` has a basis consisting of compact opens, then an open set in `α` is compact open iff it is a finite union of some elements in the basis -/ theorem IsBasis.isCompact_open_iff_eq_finite_iUnion {ι : Type*} (b : ι → Opens α) From 10874878a53987127ef9f6e12d597b7d7fea4a42 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:39:03 +0000 Subject: [PATCH 0283/1300] chore(RingTheory/Invariant/Basic): split file by imports (#40928) The basic file `RingTheory/Invariant/Basic.lean` proving existence of Frobenius elements has surprisingly heavy imports (e.g., all of Galois theory). This PR splits off the heaver material into a separate file `RingTheory/Invariant/Galois.lean`. This leads to some nontrivial import reductions in downstream files. Co-authored-by: tb65536 --- Mathlib.lean | 1 + .../RamificationInertia/Galois.lean | 1 + Mathlib/RingTheory/Invariant/Basic.lean | 130 +-------------- Mathlib/RingTheory/Invariant/Galois.lean | 152 ++++++++++++++++++ 4 files changed, 160 insertions(+), 124 deletions(-) create mode 100644 Mathlib/RingTheory/Invariant/Galois.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7566842d733330..d9fda0a91062b6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6673,6 +6673,7 @@ public import Mathlib.RingTheory.IntegralClosure.IsIntegralClosure.Defs public import Mathlib.RingTheory.IntegralDomain public import Mathlib.RingTheory.Invariant.Basic public import Mathlib.RingTheory.Invariant.Defs +public import Mathlib.RingTheory.Invariant.Galois public import Mathlib.RingTheory.Invariant.Profinite public import Mathlib.RingTheory.IsAdjoinRoot public import Mathlib.RingTheory.IsPrimary diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index ec9ce3731a2995..bc63cb37041191 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -5,6 +5,7 @@ Authors: Yongle Hu, Jiedong Jiang -/ module +public import Mathlib.RingTheory.Invariant.Galois public import Mathlib.RingTheory.RamificationInertia.Basic /-! diff --git a/Mathlib/RingTheory/Invariant/Basic.lean b/Mathlib/RingTheory/Invariant/Basic.lean index 83972a5c02b355..e06ded1554491a 100644 --- a/Mathlib/RingTheory/Invariant/Basic.lean +++ b/Mathlib/RingTheory/Invariant/Basic.lean @@ -5,9 +5,9 @@ Authors: Thomas Browning -/ module +public import Mathlib.FieldTheory.Fixed +public import Mathlib.RingTheory.Ideal.GoingUp public import Mathlib.RingTheory.Invariant.Defs -public import Mathlib.RingTheory.IntegralClosure.IntegralRestrict -public import Mathlib.RingTheory.LocalRing.ResidueField.Ideal /-! # Invariant Extensions of Rings @@ -41,54 +41,11 @@ If `Q` is a prime ideal of `B` lying over a prime ideal `P` of `A`, then @[expose] public section -open scoped Pointwise +-- this file should not import any field theory beyond the contents of `FieldTheory/Fixed.lean` +-- material involving Galois theory should be placed in `RingTheory/Invariant/Galois.lean` +assert_not_exists IntermediateField.adjoin -section Galois - -variable (A K L B : Type*) [CommRing A] [CommRing B] [Field K] [Field L] - [Algebra A K] [Algebra B L] [IsFractionRing A K] [IsFractionRing B L] - [Algebra A B] [Algebra K L] [Algebra A L] [IsScalarTower A K L] [IsScalarTower A B L] - [IsIntegrallyClosed A] [IsIntegralClosure B A L] - -/-- In the AKLB setup, the Galois group of `L/K` acts on `B`. -/ -@[implicit_reducible] -noncomputable def IsIntegralClosure.MulSemiringAction [Algebra.IsAlgebraic K L] : - MulSemiringAction Gal(L/K) B := - MulSemiringAction.compHom B (galRestrict A K L B).toMonoidHom - -instance [Algebra.IsAlgebraic K L] : let := IsIntegralClosure.MulSemiringAction A K L B - SMulDistribClass Gal(L/K) B L := - let := IsIntegralClosure.MulSemiringAction A K L B - ⟨fun g b l ↦ by - simp only [Algebra.smul_def, smul_mul', mul_eq_mul_right_iff] - exact Or.inl (algebraMap_galRestrictHom_apply A K L B g b).symm⟩ - -/-- In the AKLB setup, every fixed point of `B` lies in the image of `A`. -/ -theorem Algebra.isInvariant_of_isGalois [FiniteDimensional K L] [h : IsGalois K L] : - letI := IsIntegralClosure.MulSemiringAction A K L B - Algebra.IsInvariant A B Gal(L/K) := by - replace h := ((IsGalois.tfae (F := K) (E := L)).out 0 1).mp h - letI := IsIntegralClosure.MulSemiringAction A K L B - refine ⟨fun b hb ↦ ?_⟩ - replace hb : algebraMap B L b ∈ IntermediateField.fixedField (⊤ : Subgroup Gal(L/K)) := by - rintro ⟨g, -⟩ - exact (algebraMap_galRestrict_apply A g b).symm.trans (congrArg (algebraMap B L) (hb g)) - rw [h, IntermediateField.mem_bot] at hb - obtain ⟨k, hk⟩ := hb - have hb : IsIntegral A b := IsIntegralClosure.isIntegral A L b - rw [← isIntegral_algebraMap_iff (FaithfulSMul.algebraMap_injective B L), ← hk, - isIntegral_algebraMap_iff (FaithfulSMul.algebraMap_injective K L)] at hb - obtain ⟨a, rfl⟩ := IsIntegrallyClosed.algebraMap_eq_of_integral hb - rw [← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_apply A B L, - (FaithfulSMul.algebraMap_injective B L).eq_iff] at hk - exact ⟨a, hk⟩ - -/-- A variant of `Algebra.isInvariant_of_isGalois`, replacing `Gal(L/K)` by `Aut(B/A)`. -/ -theorem Algebra.isInvariant_of_isGalois' [FiniteDimensional K L] [IsGalois K L] : - Algebra.IsInvariant A B (B ≃ₐ[A] B) := - ⟨fun b h ↦ (isInvariant_of_isGalois A K L B).1 b (fun g ↦ h (galRestrict A K L B g))⟩ - -end Galois +open scoped Pointwise section Quotient @@ -515,81 +472,6 @@ lemma Ideal.Quotient.exists_algEquiv_fixedPoint_quotient_under refine .trans ?_ (σ.apply_symm_apply _) rw [← h₂, ← e, h₁] -namespace Ideal.IsFractionRing - -variable [P.IsPrime] [Q.IsPrime] (K L : Type*) [Field K] [Field L] [Algebra K L] - [Algebra (A ⧸ P) K] [IsFractionRing (A ⧸ P) K] [Algebra (B ⧸ Q) L] [IsFractionRing (B ⧸ Q) L] - [Algebra (A ⧸ P) L] [IsScalarTower (A ⧸ P) (B ⧸ Q) L] [IsScalarTower (A ⧸ P) K L] - -open Polynomial in -include P Q G in -lemma normal : Normal K L := by - have := Algebra.IsInvariant.isIntegral A B G - have := isAlgebraic_of_isFractionRing (A ⧸ P) (B ⧸ Q) K L - constructor - intro x - obtain ⟨x, y, hy, rfl⟩ := IsFractionRing.div_surjective (B ⧸ Q) x - obtain ⟨b, a, ha, h⟩ := (Algebra.IsAlgebraic.isAlgebraic (R := A ⧸ P) y).exists_smul_eq_mul x hy - obtain ⟨a, rfl⟩ := Quotient.mk_surjective a - obtain ⟨b, rfl⟩ := Quotient.mk_surjective b - simp_rw [← Quotient.algebraMap_eq] at * - cases nonempty_fintype G - obtain ⟨p, hp, -, h_monic⟩ := lifts_and_natDegree_eq_and_monic - (Algebra.IsInvariant.charpoly_mem_lifts A B G b) (MulSemiringAction.monic_charpoly ..) - have h_eval : p.aeval b = 0 := by - rw [← eval_map_algebraMap, hp, MulSemiringAction.eval_charpoly] - let q := p.comp (C a * X) - let d := (algebraMap (B ⧸ Q) L) x / (algebraMap (B ⧸ Q) L) y - have comm₁ : (algebraMap K L).comp (algebraMap (A ⧸ P) K) = - (algebraMap (B ⧸ Q) L).comp (algebraMap (A ⧸ P) (B ⧸ Q)) := by - simp_rw [← IsScalarTower.algebraMap_eq] - have comm₂ : (algebraMap (A ⧸ P) (B ⧸ Q)).comp (algebraMap A (A ⧸ P)) = - (algebraMap B (B ⧸ Q)).comp (algebraMap A B) := by - simp_rw [← IsScalarTower.algebraMap_eq] - replace h_eval : ((q.map (algebraMap A (A ⧸ P))).map (algebraMap (A ⧸ P) K)).aeval d = 0 := by - simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X, aeval_comp, aeval_mul, aeval_C, aeval_X, - ← RingHom.comp_apply, ← RingHom.comp_assoc, comm₁, RingHom.comp_apply, d, mul_div, ← map_mul] - rw [← Algebra.smul_def, h, map_mul, mul_div_cancel_left₀ _ (by simpa using hy), - aeval_map_algebraMap, aeval_algebraMap_apply, aeval_map_algebraMap, aeval_algebraMap_apply, - h_eval, map_zero, map_zero] - replace h_splits : (p.map (algebraMap A B)).Splits := by - rw [hp] - exact MulSemiringAction.splits_charpoly G b - refine .of_dvd ?_ ?_ (map_dvd (algebraMap K L) (minpoly.dvd K d h_eval)) - · simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X] - refine .comp_of_degree_le_one ?_ (degree_C_mul_X_le _) - rw [Polynomial.map_map, Polynomial.map_map, comm₁, RingHom.comp_assoc, comm₂, - ← RingHom.comp_assoc, ← Polynomial.map_map] - apply h_splits.map - · simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X, Polynomial.map_map] - exact mt (comp_C_mul_X_eq_zero_iff (by simpa)).mp (map_monic_ne_zero h_monic) - -include P Q in -lemma finite_of_isInvariant [SMulCommClass G A B] [Algebra.IsSeparable K L] : - Module.Finite K L := by - have : IsGalois K L := { __ := normal G P Q K L } - have := Finite.of_surjective _ (IsFractionRing.stabilizerHom_surjective G P Q K L) - apply IsGalois.finiteDimensional_of_finite - -end Ideal.IsFractionRing - -attribute [local instance] Ideal.Quotient.field in -include G in -/-- -For any domain `k` containing `B ⧸ Q`, -any endomorphism of `k` can be restricted to an endomorphism of `B ⧸ Q`. -/ -lemma Ideal.Quotient.normal [P.IsMaximal] [Q.IsMaximal] : - Normal (A ⧸ P) (B ⧸ Q) := - IsFractionRing.normal G P Q (A ⧸ P) (B ⧸ Q) - -attribute [local instance] Ideal.Quotient.field in -include G in -/-- If the extension `B/Q` over `A/P` is separable, then it is finite dimensional. -/ -lemma Ideal.Quotient.finite_of_isInvariant [P.IsMaximal] [Q.IsMaximal] - [SMulCommClass G A B] [Algebra.IsSeparable (A ⧸ P) (B ⧸ Q)] : - Module.Finite (A ⧸ P) (B ⧸ Q) := - IsFractionRing.finite_of_isInvariant G P Q (A ⧸ P) (B ⧸ Q) - end normal namespace IsFractionRing diff --git a/Mathlib/RingTheory/Invariant/Galois.lean b/Mathlib/RingTheory/Invariant/Galois.lean new file mode 100644 index 00000000000000..c86f93056fb6d5 --- /dev/null +++ b/Mathlib/RingTheory/Invariant/Galois.lean @@ -0,0 +1,152 @@ +/- +Copyright (c) 2024 Thomas Browning. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Thomas Browning +-/ +module + +public import Mathlib.RingTheory.Invariant.Basic +public import Mathlib.RingTheory.IntegralClosure.IntegralRestrict + +/-! +# Invariant Extensions of Rings and Galois Theory + +Given an extension of rings `B/A` and an action of `G` on `B`, the predicate +`Algebra.IsInvariant A B G` states that every fixed point of `B` lies in the image of `A`. + +This file relates this predicate `Algebra.IsInvariant` to Galois theory. +-/ + +@[expose] public section + +open scoped Pointwise + +section Galois + +variable (A K L B : Type*) [CommRing A] [CommRing B] [Field K] [Field L] + [Algebra A K] [Algebra B L] [IsFractionRing A K] [IsFractionRing B L] + [Algebra A B] [Algebra K L] [Algebra A L] [IsScalarTower A K L] [IsScalarTower A B L] + [IsIntegrallyClosed A] [IsIntegralClosure B A L] + +/-- In the AKLB setup, the Galois group of `L/K` acts on `B`. -/ +@[implicit_reducible] +noncomputable def IsIntegralClosure.MulSemiringAction [Algebra.IsAlgebraic K L] : + MulSemiringAction Gal(L/K) B := + MulSemiringAction.compHom B (galRestrict A K L B).toMonoidHom + +instance [Algebra.IsAlgebraic K L] : let := IsIntegralClosure.MulSemiringAction A K L B + SMulDistribClass Gal(L/K) B L := + let := IsIntegralClosure.MulSemiringAction A K L B + ⟨fun g b l ↦ by + simp only [Algebra.smul_def, smul_mul', mul_eq_mul_right_iff] + exact Or.inl (algebraMap_galRestrictHom_apply A K L B g b).symm⟩ + +/-- In the AKLB setup, every fixed point of `B` lies in the image of `A`. -/ +theorem Algebra.isInvariant_of_isGalois [FiniteDimensional K L] [h : IsGalois K L] : + letI := IsIntegralClosure.MulSemiringAction A K L B + Algebra.IsInvariant A B Gal(L/K) := by + replace h := ((IsGalois.tfae (F := K) (E := L)).out 0 1).mp h + letI := IsIntegralClosure.MulSemiringAction A K L B + refine ⟨fun b hb ↦ ?_⟩ + replace hb : algebraMap B L b ∈ IntermediateField.fixedField (⊤ : Subgroup Gal(L/K)) := by + rintro ⟨g, -⟩ + exact (algebraMap_galRestrict_apply A g b).symm.trans (congrArg (algebraMap B L) (hb g)) + rw [h, IntermediateField.mem_bot] at hb + obtain ⟨k, hk⟩ := hb + have hb : IsIntegral A b := IsIntegralClosure.isIntegral A L b + rw [← isIntegral_algebraMap_iff (FaithfulSMul.algebraMap_injective B L), ← hk, + isIntegral_algebraMap_iff (FaithfulSMul.algebraMap_injective K L)] at hb + obtain ⟨a, rfl⟩ := IsIntegrallyClosed.algebraMap_eq_of_integral hb + rw [← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_apply A B L, + (FaithfulSMul.algebraMap_injective B L).eq_iff] at hk + exact ⟨a, hk⟩ + +/-- A variant of `Algebra.isInvariant_of_isGalois`, replacing `Gal(L/K)` by `Aut(B/A)`. -/ +theorem Algebra.isInvariant_of_isGalois' [FiniteDimensional K L] [IsGalois K L] : + Algebra.IsInvariant A B (B ≃ₐ[A] B) := + ⟨fun b h ↦ (isInvariant_of_isGalois A K L B).1 b (fun g ↦ h (galRestrict A K L B g))⟩ + +end Galois + +section normal + +variable {A B : Type*} [CommRing A] [CommRing B] [Algebra A B] + (G : Type*) [Finite G] [Group G] [MulSemiringAction G B] [Algebra.IsInvariant A B G] + (P : Ideal A) (Q : Ideal B) [Q.LiesOver P] + +namespace Ideal.IsFractionRing + +variable [P.IsPrime] [Q.IsPrime] (K L : Type*) [Field K] [Field L] [Algebra K L] + [Algebra (A ⧸ P) K] [IsFractionRing (A ⧸ P) K] [Algebra (B ⧸ Q) L] [IsFractionRing (B ⧸ Q) L] + [Algebra (A ⧸ P) L] [IsScalarTower (A ⧸ P) (B ⧸ Q) L] [IsScalarTower (A ⧸ P) K L] + +open Polynomial in +include P Q G in +lemma normal : Normal K L := by + have := Algebra.IsInvariant.isIntegral A B G + have := isAlgebraic_of_isFractionRing (A ⧸ P) (B ⧸ Q) K L + constructor + intro x + obtain ⟨x, y, hy, rfl⟩ := IsFractionRing.div_surjective (B ⧸ Q) x + obtain ⟨b, a, ha, h⟩ := (Algebra.IsAlgebraic.isAlgebraic (R := A ⧸ P) y).exists_smul_eq_mul x hy + obtain ⟨a, rfl⟩ := Quotient.mk_surjective a + obtain ⟨b, rfl⟩ := Quotient.mk_surjective b + simp_rw [← Quotient.algebraMap_eq] at * + cases nonempty_fintype G + obtain ⟨p, hp, -, h_monic⟩ := lifts_and_natDegree_eq_and_monic + (Algebra.IsInvariant.charpoly_mem_lifts A B G b) (MulSemiringAction.monic_charpoly ..) + have h_eval : p.aeval b = 0 := by + rw [← eval_map_algebraMap, hp, MulSemiringAction.eval_charpoly] + let q := p.comp (C a * X) + let d := (algebraMap (B ⧸ Q) L) x / (algebraMap (B ⧸ Q) L) y + have comm₁ : (algebraMap K L).comp (algebraMap (A ⧸ P) K) = + (algebraMap (B ⧸ Q) L).comp (algebraMap (A ⧸ P) (B ⧸ Q)) := by + simp_rw [← IsScalarTower.algebraMap_eq] + have comm₂ : (algebraMap (A ⧸ P) (B ⧸ Q)).comp (algebraMap A (A ⧸ P)) = + (algebraMap B (B ⧸ Q)).comp (algebraMap A B) := by + simp_rw [← IsScalarTower.algebraMap_eq] + replace h_eval : ((q.map (algebraMap A (A ⧸ P))).map (algebraMap (A ⧸ P) K)).aeval d = 0 := by + simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X, aeval_comp, aeval_mul, aeval_C, aeval_X, + ← RingHom.comp_apply, ← RingHom.comp_assoc, comm₁, RingHom.comp_apply, d, mul_div, ← map_mul] + rw [← Algebra.smul_def, h, map_mul, mul_div_cancel_left₀ _ (by simpa using hy), + aeval_map_algebraMap, aeval_algebraMap_apply, aeval_map_algebraMap, aeval_algebraMap_apply, + h_eval, map_zero, map_zero] + replace h_splits : (p.map (algebraMap A B)).Splits := by + rw [hp] + exact MulSemiringAction.splits_charpoly G b + refine .of_dvd ?_ ?_ (map_dvd (algebraMap K L) (minpoly.dvd K d h_eval)) + · simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X] + refine .comp_of_degree_le_one ?_ (degree_C_mul_X_le _) + rw [Polynomial.map_map, Polynomial.map_map, comm₁, RingHom.comp_assoc, comm₂, + ← RingHom.comp_assoc, ← Polynomial.map_map] + apply h_splits.map + · simp_rw [q, map_comp, Polynomial.map_mul, map_C, map_X, Polynomial.map_map] + exact mt (comp_C_mul_X_eq_zero_iff (by simpa)).mp (map_monic_ne_zero h_monic) + +include P Q in +lemma finite_of_isInvariant [SMulCommClass G A B] [Algebra.IsSeparable K L] : + Module.Finite K L := by + have : IsGalois K L := { __ := normal G P Q K L } + have := Finite.of_surjective _ (IsFractionRing.stabilizerHom_surjective G P Q K L) + apply IsGalois.finiteDimensional_of_finite + +end Ideal.IsFractionRing + +attribute [local instance] Ideal.Quotient.field in +include G in +/-- +For any domain `k` containing `B ⧸ Q`, +any endomorphism of `k` can be restricted to an endomorphism of `B ⧸ Q`. -/ +lemma Ideal.Quotient.normal [P.IsMaximal] [Q.IsMaximal] : + Normal (A ⧸ P) (B ⧸ Q) := + IsFractionRing.normal G P Q (A ⧸ P) (B ⧸ Q) + +attribute [local instance] Ideal.Quotient.field in +include G in +/-- If the extension `B/Q` over `A/P` is separable, then it is finite dimensional. -/ +lemma Ideal.Quotient.finite_of_isInvariant [P.IsMaximal] [Q.IsMaximal] + [SMulCommClass G A B] [Algebra.IsSeparable (A ⧸ P) (B ⧸ Q)] : + Module.Finite (A ⧸ P) (B ⧸ Q) := + IsFractionRing.finite_of_isInvariant G P Q (A ⧸ P) (B ⧸ Q) + +end normal From 2a63917e6adf6223eb965f95e5efa57eade46fbb Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:53:02 +0000 Subject: [PATCH 0284/1300] feat(Topology): generalise `Trivialization.symm` (#40903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change `Bundle.Trivialisation.symm` to get its junk values via `Classical.arbitrary` from a `Nonempty` instance, instead of requiring using `0` as the junk value and requiring `Zero` instances for that. This in particular allows us to generalise `FiberBundle.pullback` to bundles with nonempty fibres, which previously also required the bundle fibres to have zeroes. This is motivated by future work on principal bundles, whose fibres are always nonempty but have no preferred elements and hence no instances like `Zero` or `Inhabited`. `Bundle.Trivialisation.symmₗ` and `Bundle.Trivialisation.symmL` use `0` as the junk value as before; so while their definition got slightly more complicated and their underlying function no longer definitionally equal to `.symm`, all statements that were true about them previously continue to be true now. In particular, I've tested this PR against the sphere eversion project and ran into minimal breakage there. --- .../Topology/FiberBundle/Constructions.lean | 2 +- .../Topology/FiberBundle/Trivialization.lean | 44 +++++++---- Mathlib/Topology/VectorBundle/Basic.lean | 73 +++++++++++++------ .../Topology/VectorBundle/Constructions.lean | 2 +- .../ContinuousAlternatingMap.lean | 5 +- Mathlib/Topology/VectorBundle/Hom.lean | 12 +-- Mathlib/Topology/VectorBundle/Riemannian.lean | 13 ++-- 7 files changed, 97 insertions(+), 54 deletions(-) diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index 0e44b40be93d8c..98b4083007ac0f 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -301,7 +301,7 @@ theorem Pullback.continuous_totalSpaceMk [∀ x, TopologicalSpace (E x)] [FiberB exact (FiberBundle.totalSpaceMk_isInducing F E (f x)).eq_induced.le variable {E F} -variable [∀ _b, Zero (E _b)] {K : Type U} [FunLike K B' B] [ContinuousMapClass K B' B] +variable [∀ _b, Nonempty (E _b)] {K : Type U} [FunLike K B' B] [ContinuousMapClass K B' B] /-- A fiber bundle trivialization can be pulled back to a trivialization on the pullback bundle. -/ @[simps] diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index 38133c78000fab..2177900ac23584 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -223,29 +223,38 @@ theorem symm_coe_proj {x : B} {y : F} (e' : Pretrivialization F (π F E)) (h : x (e'.toPartialEquiv.symm (x, y)).1 = x := e'.proj_symm_apply' h -section Zero +section Nonempty -variable [∀ x, Zero (E x)] +variable [∀ x, Nonempty (E x)] open Classical in /-- A fiberwise inverse to `e`. This is the function `F → E b` that induces a local inverse -`B × F → TotalSpace F E` of `e` on `e.baseSet`. It is defined to be `0` outside `e.baseSet`. -/ +`B × F → TotalSpace F E` of `e` on `e.baseSet`. Outside of `e.baseSet` it takes on arbitrarily +chosen junk values. -/ protected noncomputable def symm (e : Pretrivialization F (π F E)) (b : B) (y : F) : E b := if hb : b ∈ e.baseSet then cast (congr_arg E (e.proj_symm_apply' hb)) (e.toPartialEquiv.symm (b, y)).2 - else 0 + else Classical.arbitrary _ theorem symm_apply (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : F) : e.symm b y = cast (congr_arg E (e.symm_coe_proj hb)) (e.toPartialEquiv.symm (b, y)).2 := dif_pos hb +@[deprecated "The junk values of `Pretrivialization.symm` were changed from `0` to +`Classical.arbitrary` and should not be relied on; this lemma will be removed soon. Note that this +change does not affect the linear versions `symmₗ` and `symmL`, which still retain `0` as the junk +values." (since := "2026-06-23")] theorem symm_apply_of_notMem (e : Pretrivialization F (π F E)) {b : B} (hb : b ∉ e.baseSet) - (y : F) : e.symm b y = 0 := - dif_neg hb + (y : F) : e.symm b y = Classical.arbitrary _ := by + simp [Pretrivialization.symm, hb] +@[deprecated "The junk values of `Pretrivialization.symm` were changed from `0` to +`Classical.arbitrary` and should not be relied on; this lemma will be removed soon. Note that this +change does not affect the linear versions `symmₗ` and `symmL`, which still retain `0` as the junk +values." (since := "2026-06-23")] theorem coe_symm_of_notMem (e : Pretrivialization F (π F E)) {b : B} (hb : b ∉ e.baseSet) : - (e.symm b : F → E b) = 0 := - funext fun _ => dif_neg hb + e.symm b = fun _ ↦ Classical.arbitrary _ := by + ext; exact symm_apply_of_notMem e hb _ theorem mk_symm (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : F) : TotalSpace.mk b (e.symm b y) = e.toPartialEquiv.symm (b, y) := by @@ -266,7 +275,7 @@ theorem apply_mk_symm (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.b e ⟨b, e.symm b y⟩ = (b, y) := by rw [e.mk_symm hb, e.apply_symm_apply (e.mk_mem_target.mpr hb)] -end Zero +end Nonempty /-- The restriction of a pretrivialization to a subset of the base. -/ @[simps toFun source target baseSet] @@ -668,12 +677,13 @@ theorem symm_coe_proj {x : B} {y : F} (e : Trivialization F (π F E)) (h : x ∈ (e.toOpenPartialHomeomorph.symm (x, y)).1 = x := e.proj_symm_apply' h -section Zero +section Nonempty -variable [∀ x, Zero (E x)] +variable [∀ x, Nonempty (E x)] /-- A fiberwise inverse to `e'`. The function `F → E x` that induces a local inverse -`B × F → TotalSpace F E` of `e'` on `e'.baseSet`. It is defined to be `0` outside `e'.baseSet`. -/ +`B × F → TotalSpace F E` of `e'` on `e'.baseSet`. It takes on junk values chosen using +`Classical.arbitrary` outside `e'.baseSet`. -/ protected noncomputable def symm (e : Trivialization F (π F E)) (b : B) (y : F) : E b := e.toPretrivialization.symm b y @@ -682,9 +692,13 @@ theorem symm_apply (e : Trivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet cast (congr_arg E (e.symm_coe_proj hb)) (e.toOpenPartialHomeomorph.symm (b, y)).2 := dif_pos hb +@[deprecated "The junk values of `Trivialization.symm` were changed from `0` to +`Classical.arbitrary` and should not be relied on; this lemma will be removed soon. Note that this +change does not affect the linear versions `symmₗ` and `symmL`, which still retain `0` as the junk +values." (since := "2026-06-23")] theorem symm_apply_of_notMem (e : Trivialization F (π F E)) {b : B} (hb : b ∉ e.baseSet) (y : F) : - e.symm b y = 0 := - dif_neg hb + e.symm b y = Classical.arbitrary _ := + e.toPretrivialization.symm_apply_of_notMem hb y theorem mk_symm (e : Trivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : F) : TotalSpace.mk b (e.symm b y) = e.toOpenPartialHomeomorph.symm (b, y) := @@ -715,7 +729,7 @@ theorem continuousOn_symm (e : Trivialization F (π F E)) : rw [← e.target_eq] exact e.toOpenPartialHomeomorph.continuousOn_symm -end Zero +end Nonempty /-- If `e` is a `Trivialization` of `proj : Z → B` with fiber `F` and `h` is a homeomorphism `F ≃ₜ F'`, then `e.trans_fiber_homeomorph h` is the trivialization of `proj` with the fiber `F'` diff --git a/Mathlib/Topology/VectorBundle/Basic.lean b/Mathlib/Topology/VectorBundle/Basic.lean index 21c11a5ea2ad57..ada696545834d0 100644 --- a/Mathlib/Topology/VectorBundle/Basic.lean +++ b/Mathlib/Topology/VectorBundle/Basic.lean @@ -86,15 +86,22 @@ theorem linear [AddCommMonoid F] [Module R F] [∀ x, AddCommMonoid (E x)] [∀ variable [AddCommMonoid F] [Module R F] [∀ x, AddCommMonoid (E x)] [∀ x, Module R (E x)] +open Classical in /-- A fiberwise linear inverse to `e`. -/ -@[simps!] protected def symmₗ (e : Pretrivialization F (π F E)) [e.IsLinear R] (b : B) : F →ₗ[R] E b := by - refine IsLinearMap.mk' (e.symm b) ?_ - by_cases hb : b ∈ e.baseSet - · exact (((e.linear R hb).mk' _).inverse (e.symm b) (e.symm_apply_apply_mk hb) fun v ↦ - congr_arg Prod.snd <| e.apply_mk_symm hb v).isLinear - · rw [e.coe_symm_of_notMem hb] - exact (0 : F →ₗ[R] E b).isLinear + refine if hb : b ∈ e.baseSet then IsLinearMap.mk' (e.symm b) ?_ else 0 + exact (((e.linear R hb).mk' _).inverse (e.symm b) (e.symm_apply_apply_mk hb) fun v ↦ + congr_arg Prod.snd <| e.apply_mk_symm hb v).isLinear + +@[simp] +lemma symmₗ_apply (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) + (y : F) : e.symmₗ R b y = e.symm b y := by + simp [Pretrivialization.symmₗ, hb] + +@[simp] +lemma symmₗ_apply_of_notMem (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} + (hb : b ∉ e.baseSet) (y : F) : e.symmₗ R b y = 0 := by + simp [Pretrivialization.symmₗ, hb] /-- A pretrivialization for a vector bundle defines linear equivalences between the fibers and the model space. -/ @@ -197,9 +204,19 @@ variable (R) in protected def symmₗ (e : Trivialization F (π F E)) [e.IsLinear R] (b : B) : F →ₗ[R] E b := e.toPretrivialization.symmₗ R b -theorem coe_symmₗ (e : Trivialization F (π F E)) [e.IsLinear R] (b : B) : - ⇑(e.symmₗ R b) = e.symm b := - rfl +theorem coe_symmₗ (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) : + ⇑(e.symmₗ R b) = e.symm b := by + ext y; exact e.toPretrivialization.symmₗ_apply R hb y + +@[simp] +theorem symmₗ_apply (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) + (y : F) : e.symmₗ R b y = e.symm b y := + e.toPretrivialization.symmₗ_apply R hb y + +@[simp] +theorem symmₗ_apply_of_notMem (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} + (hb : b ∉ e.baseSet) (y : F) : e.symmₗ R b y = 0 := + e.toPretrivialization.symmₗ_apply_of_notMem R hb y variable (R) in /-- A fiberwise linear map equal to `e` on `e.baseSet`. -/ @@ -230,8 +247,8 @@ theorem linearMapAt_def_of_notMem (e : Trivialization F (π F E)) [e.IsLinear R] dif_neg hb theorem symm_linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) - (y : E b) : e.symm b (e.linearMapAt R b y) = y := - e.toPretrivialization.symmₗ_linearMapAt hb y + (y : E b) : e.symm b (e.linearMapAt R b y) = y := by + simp [hb] theorem symmₗ_linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) (y : E b) : e.symmₗ R b (e.linearMapAt R b y) = y := @@ -239,8 +256,8 @@ theorem symmₗ_linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] {b : @[simp] theorem linearMapAt_symm (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) - (y : F) : e.linearMapAt R b (e.symm b y) = y := - e.toPretrivialization.linearMapAt_symmₗ hb y + (y : F) : e.linearMapAt R b (e.symm b y) = y := by + simp [hb] theorem linearMapAt_symmₗ (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) (y : F) : e.linearMapAt R b (e.symmₗ R b y) = y := @@ -395,19 +412,28 @@ lemma continuousLinearMapAt_apply_of_mem (e : Trivialization F TotalSpace.proj) simp [coe_linearMapAt_of_mem e hb] /-- Backwards map of `Bundle.Trivialization.continuousLinearEquivAt`, defined everywhere. -/ -@[simps -fullyApplied apply] def symmL (e : Trivialization F (π F E)) [e.IsLinear R] (b : B) : F →L[R] E b := { e.symmₗ R b with - toFun := e.symm b -- given explicitly to help `simps` cont := by by_cases hb : b ∈ e.baseSet · rw [(FiberBundle.totalSpaceMk_isInducing F E b).continuous_iff] + refine .congr (f := TotalSpace.mk b ∘ e.symm b) ?_ (by simp [hb]) exact e.continuousOn_symm.comp_continuous (.prodMk_right _) fun x ↦ mk_mem_prod hb (mem_univ x) - · refine continuous_zero.congr fun x => (e.symm_apply_of_notMem hb x).symm } + · exact continuous_zero.congr fun x => (e.symmₗ_apply_of_notMem hb x).symm } variable {R} +@[simp] +theorem symmL_apply (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) + (y : F) : e.symmL R b y = e.symm b y := + e.toPretrivialization.symmₗ_apply R hb y + +@[simp] +lemma symmL_apply_of_notMem (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} + (hb : b ∉ e.baseSet) (y : F) : e.symmL R b y = 0 := + e.toPretrivialization.symmₗ_apply_of_notMem _ hb _ + theorem symmL_continuousLinearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) (y : E b) : e.symmL R b (e.continuousLinearMapAt R b y) = y := e.symmₗ_linearMapAt hb y @@ -427,7 +453,7 @@ def continuousLinearEquivAt (e : Trivialization F (π F E)) [e.IsLinear R] (b : invFun := e.symm b -- given explicitly to help `simps` continuous_toFun := (e.continuousOn.comp_continuous (FiberBundle.totalSpaceMk_isInducing F E b).continuous fun _ => e.mem_source.mpr hb).snd - continuous_invFun := (e.symmL R b).continuous } + continuous_invFun := by convert (e.symmL R b).continuous; ext; simp [hb] } theorem coe_continuousLinearEquivAt_eq (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) : @@ -440,12 +466,13 @@ theorem coe_continuousLinearEquivAt_eq' (e : Trivialization F (π F E)) [e.IsLin DFunLike.coe_injective (e.coe_linearMapAt_of_mem hb).symm theorem symm_continuousLinearEquivAt_eq (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} - (hb : b ∈ e.baseSet) : ((e.continuousLinearEquivAt R b hb).symm : F → E b) = e.symmL R b := - rfl + (hb : b ∈ e.baseSet) : ((e.continuousLinearEquivAt R b hb).symm : F → E b) = e.symmL R b := by + ext; simp [hb] theorem symm_continuousLinearEquivAt_eq' (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} - (hb : b ∈ e.baseSet) : ((e.continuousLinearEquivAt R b hb).symm : F →L[R] E b) = e.symmL R b := - rfl + (hb : b ∈ e.baseSet) : + ((e.continuousLinearEquivAt R b hb).symm : F →L[R] E b) = e.symmL R b := by + ext; simp [hb] @[simp] theorem continuousLinearEquivAt_apply' (e : Trivialization F (π F E)) [e.IsLinear R] @@ -745,7 +772,7 @@ theorem trivializationAt_continuousLinearMapAt {b₀ b : B} theorem localTriv_symmL {b : B} (hb : b ∈ (Z.localTriv i).baseSet) : (Z.localTriv i).symmL R b = Z.coordChange i (Z.indexAt b) b := by ext1 v - rw [(Z.localTriv i).symmL_apply R, (Z.localTriv i).symm_apply] + rw [(Z.localTriv i).symmL_apply hb, (Z.localTriv i).symm_apply] exacts [rfl, hb] @[simp, mfld_simps] diff --git a/Mathlib/Topology/VectorBundle/Constructions.lean b/Mathlib/Topology/VectorBundle/Constructions.lean index 1ea7d3026627dc..6851c1994c7c01 100644 --- a/Mathlib/Topology/VectorBundle/Constructions.lean +++ b/Mathlib/Topology/VectorBundle/Constructions.lean @@ -74,7 +74,7 @@ instance vectorBundle : VectorBundle 𝕜 F (Bundle.Trivial B F) where @[simp] lemma symmₗ_trivialization (x : B) : (trivialization B F).symmₗ 𝕜 x = LinearMap.id := by - ext; simp [Trivialization.coe_symmₗ, trivialization_symm_apply B F] + ext; simp [trivialization_symm_apply B F] @[simp] lemma symmL_trivialization (x : B) : (trivialization B F).symmL 𝕜 x = ContinuousLinearMap.id 𝕜 F := by diff --git a/Mathlib/Topology/VectorBundle/ContinuousAlternatingMap.lean b/Mathlib/Topology/VectorBundle/ContinuousAlternatingMap.lean index 8a1fb98ff57e10..ffce633b4ed0d1 100644 --- a/Mathlib/Topology/VectorBundle/ContinuousAlternatingMap.lean +++ b/Mathlib/Topology/VectorBundle/ContinuousAlternatingMap.lean @@ -87,7 +87,7 @@ theorem inCoordinates_eq {x₀ x : B₁} {y₀ y : B₂} {ϕ : E₁ x [⋀^ι] |>.compContinuousAlternatingMap ϕ |>.compContinuousLinearMap (((trivializationAt F₁ E₁ x₀).continuousLinearEquivAt 𝕜 x hx).symm : F₁ →L[𝕜] E₁ x)) := by ext - simp [inCoordinates, *] + simp [inCoordinates, *, Function.comp_def] end ContinuousAlternatingMap @@ -277,7 +277,8 @@ def vectorPrebundle : (mem_baseSet_trivializationAt _ _ _) convert! (L₁.continuousAlternatingMapCongr L₂).toHomeomorph.isInducing ext f - simp [Trivialization.linearMapAt_def_of_mem _ (mem_baseSet_trivializationAt _ _ _), L₁, L₂] + simp [Trivialization.linearMapAt_def_of_mem _ (mem_baseSet_trivializationAt _ _ _), L₁, L₂, + Function.comp_def, mem_baseSet_trivializationAt] /-- Topology on the total space of the continuous `σ`-semilinear maps between two "normable" vector bundles over the same base. -/ diff --git a/Mathlib/Topology/VectorBundle/Hom.lean b/Mathlib/Topology/VectorBundle/Hom.lean index 2a2a8778a17f73..5162b27a435c26 100644 --- a/Mathlib/Topology/VectorBundle/Hom.lean +++ b/Mathlib/Topology/VectorBundle/Hom.lean @@ -154,10 +154,9 @@ theorem continuousLinearMapCoordChange_apply (b : B) simp_rw [continuousLinearMapCoordChange, ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.arrowCongrSL_apply, continuousLinearMap_apply, continuousLinearMap_symm_apply' σ e₁ e₂ hb.1, comp_apply, ContinuousLinearEquiv.coe_coe, - ContinuousLinearEquiv.symm_symm, Trivialization.continuousLinearMapAt_apply, - Trivialization.symmL_apply] - rw [e₂.coordChangeL_apply e₂', e₁'.coordChangeL_apply e₁, e₁.coe_linearMapAt_of_mem hb.1.1, - e₂'.coe_linearMapAt_of_mem hb.2.2] + ContinuousLinearEquiv.symm_symm, Trivialization.continuousLinearMapAt_apply] + rw [e₂.symmL_apply hb.1.2, e₁'.symmL_apply hb.2.1, e₂.coordChangeL_apply e₂', + e₁'.coordChangeL_apply e₁, e₁.coe_linearMapAt_of_mem hb.1.1, e₂'.coe_linearMapAt_of_mem hb.2.2] exacts [⟨hb.2.1, hb.1.1⟩, ⟨hb.1.2, hb.2.2⟩] end Bundle.Pretrivialization @@ -208,7 +207,8 @@ def Bundle.ContinuousLinearMap.vectorPrebundle : convert! this ext f dsimp [Pretrivialization.continuousLinearMap_apply] - rw [Trivialization.linearMapAt_def_of_mem _ (mem_baseSet_trivializationAt _ _ _)] + simp only [Trivialization.symmL_apply, mem_baseSet_trivializationAt, + Trivialization.linearMapAt_def_of_mem] rfl /-- Topology on the total space of the continuous `σ`-semilinear maps between two "normable" vector @@ -520,7 +520,7 @@ theorem inCoordinates_apply_eq₂ (trivializationAt F₃ E₃ x₀).linearMapAt 𝕜 x (ϕ ((trivializationAt F₁ E₁ x₀).symm x v) ((trivializationAt F₂ E₂ x₀).symm x w)) := by rw [inCoordinates_eq h₁x (by simp [h₂x, h₃x])] - simp [hom_trivializationAt, Trivialization.continuousLinearMap_apply] + simp [hom_trivializationAt, Trivialization.continuousLinearMap_apply, h₂x] end TwoVariables diff --git a/Mathlib/Topology/VectorBundle/Riemannian.lean b/Mathlib/Topology/VectorBundle/Riemannian.lean index cf108f20289169..a5ae4263dd779a 100644 --- a/Mathlib/Topology/VectorBundle/Riemannian.lean +++ b/Mathlib/Topology/VectorBundle/Riemannian.lean @@ -183,7 +183,8 @@ lemma eventually_norm_symmL_trivializationAt_self_comp_lt (x : B) {r : ℝ} (hr let w := (trivializationAt F E x).continuousLinearMapAt ℝ y v suffices ‖((trivializationAt F E x).symmL ℝ x) w‖ ^ 2 ≤ r' ^ 2 * ‖v‖ ^ 2 from le_of_sq_le_sq (by simpa [mul_pow]) (by positivity) - simp only [Trivialization.symmL_apply, ← real_inner_self_eq_norm_sq, hg] + simp only [Trivialization.symmL_apply, mem_baseSet_trivializationAt, + ← real_inner_self_eq_norm_sq, hg] have hgy : g y v v = g' y w w := by rw [inCoordinates_apply_eq₂ h'y h'y (Set.mem_univ _)] have A : ((trivializationAt F E x).symm y) @@ -228,8 +229,8 @@ lemma eventually_norm_trivializationAt_lt (x : B) : ((trivializationAt F E x).symmL ℝ x) = ContinuousLinearMap.id _ _ := by ext v have h'x : x ∈ (trivializationAt F E x).baseSet := FiberBundle.mem_baseSet_trivializationAt' x - simp only [Trivialization.continuousLinearMapAt_apply, Trivialization.symmL_apply, comp_apply, - id_apply] + simp only [Trivialization.continuousLinearMapAt_apply, Trivialization.symmL_apply, + mem_baseSet_trivializationAt, comp_apply, id_apply] convert! ((trivializationAt F E x).continuousLinearEquivAt ℝ _ h'x).apply_symm_apply v simp [Trivialization.coe_continuousLinearEquivAt_eq _ h'x] have : (trivializationAt F E x).continuousLinearMapAt ℝ y = @@ -286,7 +287,7 @@ lemma eventually_norm_symmL_trivializationAt_comp_self_lt (x : B) {r : ℝ} (hr let w := (trivializationAt F E x).continuousLinearMapAt ℝ x v suffices ‖((trivializationAt F E x).symmL ℝ y) w‖ ^ 2 ≤ r' ^ 2 * ‖v‖ ^ 2 from le_of_sq_le_sq (by simpa [mul_pow]) (by positivity) - simp only [Trivialization.symmL_apply, ← real_inner_self_eq_norm_sq, hg] + simp only [Trivialization.symmL_apply, h'y, ← real_inner_self_eq_norm_sq, hg] have hgx : g x v v = g' x w w := by rw [inCoordinates_apply_eq₂ h'x h'x (Set.mem_univ _)] have A : ((trivializationAt F E x).symm x) @@ -333,8 +334,8 @@ lemma eventually_norm_symmL_trivializationAt_lt (x : B) : ((trivializationAt F E x).symmL ℝ x) = ContinuousLinearMap.id _ _ := by ext v have h'x : x ∈ (trivializationAt F E x).baseSet := FiberBundle.mem_baseSet_trivializationAt' x - simp only [Trivialization.continuousLinearMapAt_apply, Trivialization.symmL_apply, comp_apply, - id_apply] + simp only [Trivialization.continuousLinearMapAt_apply, Trivialization.symmL_apply, + mem_baseSet_trivializationAt, comp_apply, id_apply] convert! ((trivializationAt F E x).continuousLinearEquivAt ℝ _ h'x).apply_symm_apply v simp [Trivialization.coe_continuousLinearEquivAt_eq _ h'x] have : (trivializationAt F E x).symmL ℝ y = From 1531e8c38272ca00718134635350fbbafbbf8c67 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 23 Jun 2026 12:01:30 +0000 Subject: [PATCH 0285/1300] feat(AlgebraicGeometry/Modules): compatibilities of `Over` and restriction along open immersions (#40935) We construct natural isomorphisms relating `Scheme.Modules.overEquiv` with `Scheme.Modules.restrictFunctor`. --- Mathlib/Algebra/Category/ModuleCat/Basic.lean | 27 +++++++ .../Category/ModuleCat/ChangeOfRings.lean | 11 +++ .../Algebra/Category/ModuleCat/Presheaf.lean | 7 ++ .../ModuleCat/Presheaf/Pushforward.lean | 9 +++ .../Sheaf/PushforwardContinuous.lean | 19 ++++- Mathlib/AlgebraicGeometry/Modules/Sheaf.lean | 77 +++++++++++++++++++ Mathlib/AlgebraicGeometry/Restrict.lean | 13 ++++ 7 files changed, 160 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Basic.lean index 4c29f9d53dd76d..8f8a97ee01b9ad 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Basic.lean @@ -585,6 +585,33 @@ def homMk : M ⟶ N where lemma forget₂_map_homMk : (forget₂ (ModuleCat R) AddCommGrpCat).map (homMk φ hφ) = φ := rfl +/-- Constructor for isomorphisms in `ModuleCat R` taking an isomorphism in `AddCommGrpCat` +and a compatibility condition. -/ +def isoMk (φ : (forget₂ (ModuleCat R) Ab).obj M ≅ (forget₂ _ _).obj N) + (hφ : ∀ r, φ.hom ≫ N.smul r = M.smul r ≫ φ.hom) : + M ≅ N := + LinearEquiv.toModuleIso + { __ := φ.addCommGroupIsoToAddEquiv + map_smul' r x := congr($(hφ r) x).symm } + +@[simp] +lemma isoMk_hom (φ : (forget₂ (ModuleCat R) Ab).obj M ≅ (forget₂ _ _).obj N) + (hφ : ∀ r, φ.hom ≫ N.smul r = M.smul r ≫ φ.hom) : + (isoMk φ hφ).hom = homMk φ.hom hφ := + rfl + +@[simp] +lemma isoMk_inv (φ : (forget₂ (ModuleCat R) Ab).obj M ≅ (forget₂ _ _).obj N) + (hφ : ∀ r, φ.hom ≫ N.smul r = M.smul r ≫ φ.hom) : + (isoMk φ hφ).inv = homMk φ.inv (ModuleCat.smul_naturality (isoMk φ hφ).inv) := + rfl + +@[simp] +lemma isoMk_symm (φ : (forget₂ (ModuleCat R) Ab).obj M ≅ (forget₂ _ _).obj N) + (hφ : ∀ r, φ.hom ≫ N.smul r = M.smul r ≫ φ.hom) : + (isoMk φ hφ).symm = isoMk φ.symm (ModuleCat.smul_naturality (isoMk φ hφ).inv) := + rfl + end instance : (forget (ModuleCat.{v} R)).ReflectsIsomorphisms where diff --git a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean index 0f4781fb157094..b162815dd0a236 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean @@ -87,6 +87,17 @@ def restrictScalars {R : Type u₁} {S : Type u₂} [Ring R] [Ring S] (f : R → obj := RestrictScalars.obj' f map := RestrictScalars.map' f +@[simp] +lemma smul_restrictScalars {R : Type u₁} {S : Type u₂} [Ring R] [Ring S] (f : R →+* S) (r : R) + (M : ModuleCat S) : + dsimp% ((ModuleCat.restrictScalars f).obj M).smul r = M.smul (f r) := + rfl + +lemma forget₂_map_restrictScalars {R : Type u₁} {S : Type u₂} [Ring R] [Ring S] (f : R →+* S) + {M N : ModuleCat S} (g : M ⟶ N) : + (forget₂ _ Ab).map ((ModuleCat.restrictScalars f).map g) = (forget₂ _ Ab).map g := + rfl + instance {R : Type u₁} {S : Type u₂} [Ring R] [Ring S] (f : R →+* S) : (restrictScalars.{v} f).Faithful where map_injective h := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean index b2d94c8c704d37..1428f49d38f65b 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean @@ -140,6 +140,13 @@ lemma presheaf_obj_coe (X : Cᵒᵖ) : lemma presheaf_map_apply_coe {X Y : Cᵒᵖ} (f : X ⟶ Y) (x : M.obj X) : DFunLike.coe (α := M.obj X) (β := fun _ ↦ M.obj Y) (M.presheaf.map f).hom x = M.map f x := rfl +@[reassoc] +lemma smul_map {U V : Cᵒᵖ} (f : U ⟶ V) (r : R.obj U) : + dsimp% ModuleCat.smul _ r ≫ M.presheaf.map f = + M.presheaf.map f ≫ ModuleCat.smul _ (R.map f r) := by + ext x + exact (M.map f).hom.map_smul r x + instance (M : PresheafOfModules R) (X : Cᵒᵖ) : Module (R.obj X) (M.presheaf.obj X) := inferInstanceAs (Module (R.obj X) (M.obj X)) diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean index db8c9a6831aa72..1b537629bacb2a 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean @@ -89,6 +89,15 @@ a morphism of presheaves of rings `S ⟶ F.op ⋙ R`. -/ noncomputable def pushforward : PresheafOfModules.{v} R ⥤ PresheafOfModules.{v} S := pushforward₀ F R ⋙ restrictScalars φ +lemma forget₂_map_pushforward_obj_map {U V : Cᵒᵖ} (f : U ⟶ V) (M : PresheafOfModules R) : + (forget₂ _ Ab).map (((PresheafOfModules.pushforward φ).obj M).map f) = + M.presheaf.map (F.map f.unop).op := + rfl + +lemma forget₂_map_pushforward_map_app {U : Cᵒᵖ} {M N : PresheafOfModules _} (g : M ⟶ N) : + (forget₂ _ Ab).map (((pushforward φ).map g).app U) = (forget₂ _ Ab).map (g.app _) := + rfl + /-- The pushforward of presheaves of modules commutes with the forgetful functor to presheaves of abelian groups. -/ noncomputable def pushforwardCompToPresheaf : diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean index ba6bd327e13c56..6ff62bcb90c789 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean @@ -48,6 +48,11 @@ noncomputable def pushforward : SheafOfModules.{v} R ⥤ SheafOfModules.{v} S wh map f := { val := (PresheafOfModules.pushforward φ.hom).map f.val } +lemma forget₂_map_pushforward_obj_val_map {U V : Cᵒᵖ} (f : U ⟶ V) (M) : + (forget₂ _ Ab).map (((pushforward.{v} φ).obj M).val.map f) = + M.val.presheaf.map (F.map f.unop).op := + rfl + variable (R) in /-- The restriction functor from sheaves of `R`-modules to sheaves of `R.over X`-modules for some `X : D`. -/ @@ -128,12 +133,13 @@ section variable {K' : GrothendieckTopology D'} {K'' : GrothendieckTopology D''} {G : D ⥤ D'} {R' : Sheaf K' RingCat.{u}} - [Functor.IsContinuous G K K'] [Functor.IsContinuous (F ⋙ G) J K'] + [Functor.IsContinuous G K K'] (ψ : R ⟶ (G.sheafPushforwardContinuous RingCat.{u} K K').obj R') /-- The composition of two pushforward functors on categories of sheaves of modules identify to the pushforward for the composition. -/ noncomputable def pushforwardComp : + haveI : Functor.IsContinuous (F ⋙ G) J K' := Functor.isContinuous_comp _ _ _ K _ pushforward.{v} ψ ⋙ pushforward.{v} φ ≅ pushforward.{v} (F := F ⋙ G) (φ ≫ (F.sheafPushforwardContinuous RingCat.{u} J K).map ψ) := Iso.refl _ @@ -149,8 +155,7 @@ lemma pushforwardComp_inv_app_val_app (M U x) : variable {G' : D' ⥤ D''} {R'' : Sheaf K'' RingCat.{u}} [Functor.IsContinuous G' K' K''] [Functor.IsContinuous (G ⋙ G') K K''] - [Functor.IsContinuous ((F ⋙ G) ⋙ G') J K''] - [Functor.IsContinuous (F ⋙ G ⋙ G') J K''] + [(F ⋙ G).IsContinuous J K'] (ψ' : R' ⟶ (G'.sheafPushforwardContinuous RingCat.{u} K' K'').obj R'') lemma pushforward_assoc : @@ -240,6 +245,14 @@ noncomputable def pushforwardNatIso (α : F ≅ G) : simp only [← Functor.map_comp, ← op_comp, Iso.hom_inv_id_app, op_id, CategoryTheory.Functor.map_id] +/-- More flexible variant of `SheafOfModules.pushforwardNatIso`. -/ +@[simps!] +noncomputable +def pushforwardCongr₂ {ψ : T ⟶ (F.sheafPushforwardContinuous RingCat J K).obj S} (e : F ≅ G) + (he : φ ≫ (Functor.sheafPushforwardContinuousNatTrans e.hom _ _ _).app S = ψ) : + pushforward.{v} φ ≅ pushforward.{v} ψ := + pushforwardNatIso _ e ≪≫ pushforwardCongr he + end NatTrans section Adjunction diff --git a/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean b/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean index b415ed001bbaa5..32ec8d0dc0624f 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean @@ -10,9 +10,11 @@ public import Mathlib.Algebra.Category.ModuleCat.Sheaf.Colimits public import Mathlib.Algebra.Category.ModuleCat.Sheaf.PullbackContinuous public import Mathlib.AlgebraicGeometry.Modules.Presheaf public import Mathlib.AlgebraicGeometry.OpenImmersion +public import Mathlib.AlgebraicGeometry.AffineScheme public import Mathlib.CategoryTheory.Bicategory.Adjunction.Adj public import Mathlib.CategoryTheory.Bicategory.Adjunction.Cat public import Mathlib.CategoryTheory.Bicategory.Functor.LocallyDiscrete +public import Mathlib.Topology.Sheaves.Module /-! # The category of sheaves of modules over a scheme @@ -381,6 +383,23 @@ instead. -/ lemma restrict_map (M : Y.Modules) (f : X ⟶ Y) [IsOpenImmersion f] {U V} (i : U ⟶ V) : (M.restrict f).presheaf.map i.op = M.presheaf.map (f.opensFunctor.map i).op := rfl +/-- `Scheme.Modules.restrict` along an open immersion `X ⟶ Y` sends `𝒪_Y` to `𝒪_X`. -/ +def restrictUnitIso (f : X ⟶ Y) [IsOpenImmersion f] : + restrict (.unit <| Y.ringCatSheaf) f ≅ .unit X.ringCatSheaf := by + refine (fullyFaithfulForget _).preimageIso <| PresheafOfModules.isoMk (fun U ↦ ?_) ?_ + · refine ModuleCat.isoMk + ((forget₂ CommRingCat RingCat ⋙ forget₂ _ Ab).mapIso (f.appIso U.unop)) ?_ + intro (r : Γ(X, U.unop)) + ext (x : Γ(Y, f ''ᵁ U.unop)) + change r * (f.appIso U.unop).hom x = (f.appIso U.unop).hom ((f.appIso U.unop).inv r * x) + simp + · intro U V g + have : Y.presheaf.map (homOfLE (by grw [leOfHom g.unop])).op ≫ + (f.appIso _).hom = (f.appIso U.unop).hom ≫ X.presheaf.map g := by + simp [Hom.appIso_hom'] + ext x + exact congr($(this) x) + /-- The restriction of a module along an open immersion. -/ def restrictFunctorAdjCounitIso : pushforward f ⋙ restrictFunctor f ≅ 𝟭 _ := letI := CategoryTheory.Functor.isContinuous_comp.{u} f.opensFunctor (Opens.map f.base) @@ -521,4 +540,62 @@ noncomputable def sheafComposePushforwardComp {R S : CommRingCat.{u}} (φ : R · cat_disch · cat_disch +/-- Sheaves of modules on `𝒪_X` restricted to `U` are equivalent to sheaves of `𝒪_U`-modules. -/ +noncomputable +def overEquiv {X : Scheme.{u}} (U : X.Opens) : + SheafOfModules (X.ringCatSheaf.over U) ≌ (U : Scheme.{u}).Modules := + TopologicalSpace.Opens.sheafOfModulesEquivOver _ _ + +set_option backward.isDefEq.respectTransparency false in +/-- Up to `Scheme.Modules.overEquiv`, `SheafOfModules.overMap` is isomorphic to +`Scheme.Modules.restrictFunctor`. -/ +noncomputable +def overMapCompOverEquiv {X : Scheme.{u}} {U V : X.Opens} (f : V ⟶ U) : + overMap X.ringCatSheaf f ⋙ (overEquiv V).functor ≅ + (overEquiv U).functor ⋙ restrictFunctor (X.homOfLE <| leOfHom f) := by + haveI : (Hom.opensFunctor (X.homOfLE <| leOfHom f)).IsContinuous + (Opens.grothendieckTopology V.toScheme) (Opens.grothendieckTopology U.carrier) := + inferInstanceAs <| + (Hom.opensFunctor (X.homOfLE <| leOfHom f)).IsContinuous _ + (Opens.grothendieckTopology U.toScheme) + haveI := U.instIsDenseSubsiteSubtypeMemOverGrothendieckTopologyOverInverseOverEquivalence + haveI : (Hom.opensFunctor (X.homOfLE <| leOfHom f)).IsContinuous + (Opens.grothendieckTopology ↥V) (Opens.grothendieckTopology U.toScheme) := + inferInstanceAs <| (X.homOfLE <| leOfHom f).opensFunctor.IsContinuous + (Opens.grothendieckTopology V.toScheme) (Opens.grothendieckTopology U.toScheme) + haveI : ((Opens.overEquivalence V).symm.functor ⋙ Over.map f).IsContinuous + (Opens.grothendieckTopology ↥V) ((Opens.grothendieckTopology X).over U) := + Functor.isContinuous_comp _ _ _ (.over (Opens.grothendieckTopology _) _) _ + haveI : (Opens.overEquivalence U).symm.functor.IsContinuous (Opens.grothendieckTopology U) + ((Opens.grothendieckTopology X).over U) := + inferInstanceAs <| U.overEquivalence.inverse.IsContinuous (Opens.grothendieckTopology U.carrier) + ((Opens.grothendieckTopology X).over U) + haveI : ((X.homOfLE (leOfHom f)).opensFunctor ⋙ + (Opens.overEquivalence U).symm.functor).IsContinuous (Opens.grothendieckTopology ↥V) + ((Opens.grothendieckTopology ↥X).over U) := + Functor.isContinuous_comp _ _ _ (Opens.grothendieckTopology _) _ + refine (SheafOfModules.pushforwardComp _ _) ≪≫ ?_ ≪≫ (SheafOfModules.pushforwardComp _ _).symm + refine SheafOfModules.pushforwardCongr₂ _ ?_ ?_ + · refine NatIso.ofComponents (fun W ↦ Over.isoMk (eqToIso ?_) ?_) ?_ + · suffices U.ι ''ᵁ ((X.homOfLE (leOfHom f)) ''ᵁ W) = V.ι ''ᵁ W by simpa + simp [← Scheme.Hom.comp_image] + · cat_disch + · cat_disch + · ext W x + suffices X.presheaf.map _ x = ((X.homOfLE <| leOfHom f).appIso _).inv x by simpa + rw [Scheme.Hom.appIso_homOfLE_inv] + rfl + +/-- Up to `Scheme.Modules.overEquiv`, `SheafOfModules.overFunctor` is isomorphic to +`Scheme.Modules.restrictFunctor`. -/ +noncomputable +def overFunctorEquiv {X : Scheme.{u}} (U : X.Opens) : + overFunctor X.ringCatSheaf U ⋙ (overEquiv U).functor ≅ restrictFunctor U.ι := by + have : ((Opens.overEquivalence U).symm.functor ⋙ Over.forget U).IsContinuous + (Opens.grothendieckTopology ↥U) (Opens.grothendieckTopology ↥X) := + Functor.isContinuous_comp _ _ _ (.over (Opens.grothendieckTopology _) U) _ + refine SheafOfModules.pushforwardComp _ _ ≪≫ SheafOfModules.pushforwardCongr ?_ + simp only [CategoryTheory.Functor.map_id, Opposite.op_unop, Opens.ι_appIso, Iso.refl_inv] + rfl + end AlgebraicGeometry.Scheme.Modules diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index a8ccc83681a2f8..2ac6b65fe87143 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -307,6 +307,19 @@ instance (X : Scheme.{u}) {U V : X.Opens} (e : U ≤ V) : IsOpenImmersion (X.hom delta Scheme.homOfLE infer_instance +set_option backward.isDefEq.respectTransparency false in +lemma Scheme.Hom.appIso_homOfLE_inv {X : Scheme.{u}} {U V : X.Opens} (h : U ≤ V) + (W : (U : Scheme.{u}).Opens) : + ((X.homOfLE h).appIso W).inv = + X.presheaf.map (.op <| homOfLE <| by + suffices V.ι ''ᵁ _ ≤ U.ι ''ᵁ W by simpa + simp [← Scheme.Hom.comp_image]) := by + rw [eq_comm, ← Iso.hom_comp_eq_id] + dsimp + simp only [appIso_hom, homOfLE_app, homOfLE_leOfHom, eqToHom_op, Opens.toScheme_presheaf_map, + eqToHom_unop, ← X.presheaf.map_comp, Category.assoc, ← X.presheaf.map_id] + rfl + @[simp] lemma Scheme.opensRange_homOfLE {U V : X.Opens} (e : U ≤ V) : (X.homOfLE e).opensRange = V.ι ⁻¹ᵁ U := From f4001a93bf4e707c723b07dfe3bbee1a588a6bf2 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 23 Jun 2026 12:20:09 +0000 Subject: [PATCH 0286/1300] feat(CategoryTheory/Limits/IsLimit): use `to_dual` on `IsLimit` (#36572) This PR makes a start at translating `IsLimit` using `to_dual`. --- .../Algebra/Category/Grp/LargeColimits.lean | 2 +- .../Category/ModuleCat/FilteredColimits.lean | 3 +- .../Abelian/GrothendieckAxioms/Colim.lean | 1 - .../Abelian/GrothendieckAxioms/Connected.lean | 1 + Mathlib/CategoryTheory/Limits/Cones.lean | 4 +- Mathlib/CategoryTheory/Limits/IsLimit.lean | 601 +++++------------- Mathlib/CategoryTheory/Limits/MonoCoprod.lean | 1 + .../Limits/MorphismProperty.lean | 2 +- .../Limits/Preserves/Basic.lean | 2 +- .../Limits/Preserves/Bifunctor.lean | 6 +- .../Limits/Shapes/Grothendieck.lean | 2 +- .../CategoryTheory/Limits/Types/Colimits.lean | 2 +- Mathlib/CategoryTheory/Monad/Limits.lean | 4 +- .../MorphismProperty/Limits.lean | 3 + .../Presentable/ColimitPresentation.lean | 2 +- Mathlib/Condensed/Discrete/Colimit.lean | 3 + 16 files changed, 196 insertions(+), 443 deletions(-) diff --git a/Mathlib/Algebra/Category/Grp/LargeColimits.lean b/Mathlib/Algebra/Category/Grp/LargeColimits.lean index 9f169824b42e8d..bc79879e2627e0 100644 --- a/Mathlib/Algebra/Category/Grp/LargeColimits.lean +++ b/Mathlib/Algebra/Category/Grp/LargeColimits.lean @@ -46,7 +46,7 @@ lemma isColimit_iff_bijective_desc [DecidableEq J] : apply ofHom_injective refine hc.hom_ext (fun j ↦ ?_) ext x - rw [ConcreteCategory.comp_apply, ConcreteCategory.comp_apply, ← Quot.ι_desc _ c j x] + erw [ConcreteCategory.comp_apply, ConcreteCategory.comp_apply, ← Quot.ι_desc _ c j x] exact DFunLike.congr_fun eq (Quot.ι F j x) · set c' : Cocone F := { pt := AddCommGrpCat.of (ULift (AddCircle (1 : ℚ))) diff --git a/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean b/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean index 1ba7a0e47b858a..0f8b07457d348c 100644 --- a/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean +++ b/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean @@ -175,9 +175,10 @@ def colimitDesc (t : Cocone F) : colimit F ⟶ t.pt := obtain ⟨j, x, rfl⟩ := M.mk_surjective F x simp [hf] } +set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma ι_colimitDesc (t : Cocone F) (j : J) : - (colimitCocone F).ι.app j ≫ colimitDesc F t = t.ι.app j := + dsimp% (colimitCocone F).ι.app j ≫ colimitDesc F t = t.ι.app j := (forget₂ _ AddCommGrpCat).map_injective ((AddCommGrpCat.FilteredColimits.colimitCoconeIsColimit (F ⋙ forget₂ _ _)).fac _ _) diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Colim.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Colim.lean index 86d80f40428592..47521a2a24aab7 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Colim.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Colim.lean @@ -109,7 +109,6 @@ short complex `c₁.pt ⟶ c₂.pt ⟶ c₃.pt`. -/ @[simps] def colim.mapShortComplex : ShortComplex C := ShortComplex.mk f g (hc₁.hom_ext (fun j ↦ by - dsimp rw [reassoc_of% (hf j), hg j, comp_zero, ← NatTrans.comp_app_assoc, S.zero, zero_app, zero_comp])) diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Connected.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Connected.lean index 80c296ebe1f07c..2d124b5e493a0d 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Connected.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Connected.lean @@ -51,6 +51,7 @@ noncomputable def IsColimit.pullbackOfHasExactColimitsOfShape [HasPullbacks C] have := hc.isIso_colimMap_ι apply hpull.isIso_snd_of_isIso +set_option backward.isDefEq.respectTransparency false in /-- Detecting equality of morphisms factoring through a connected colimit by pulling back along the inclusions of the colimit. -/ theorem IsColimit.pullback_hom_ext [HasPullbacks C] [HasColimitsOfShape J C] diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 5913294e8a5ba4..0d406a66ca30b3 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -151,13 +151,11 @@ instance inhabitedCone (F : Discrete PUnit ⥤ C) : Inhabited (Cone F) := }⟩ set_option backward.defeqAttrib.useBackward true in -@[to_dual (attr := reassoc (attr := simp))] +@[to_dual (attr := reassoc (attr := simp), elementwise)] theorem Cone.w {F : J ⥤ C} (c : Cone F) {j j' : J} (f : j ⟶ j') : dsimp% c.π.app j ≫ F.map f = c.π.app j' := by simpa using (c.π.naturality f).symm -attribute [elementwise] Cocone.w Cone.w - end variable {F : J ⥤ C} diff --git a/Mathlib/CategoryTheory/Limits/IsLimit.lean b/Mathlib/CategoryTheory/Limits/IsLimit.lean index 3045f689aa7f55..57c4bedb521de0 100644 --- a/Mathlib/CategoryTheory/Limits/IsLimit.lean +++ b/Mathlib/CategoryTheory/Limits/IsLimit.lean @@ -61,43 +61,69 @@ structure IsLimit (t : Cone F) where uniq : ∀ (s : Cone F) (m : s.pt ⟶ t.pt) (_ : ∀ j : J, m ≫ t.π.app j = s.π.app j), m = lift s := by cat_disch -attribute [reassoc (attr := simp)] IsLimit.fac +set_option backward.defeqAttrib.useBackward true in +/-- A cocone `t` on `F` is a colimit cocone if each cocone on `F` admits a unique +cocone morphism from `t`. -/ +@[stacks 002F, to_dual] +structure IsColimit (t : Cocone F) where + /-- `t.pt` maps to all other cocone covertices -/ + desc : ∀ s : Cocone F, t.pt ⟶ s.pt + /-- The map `desc` makes the diagram with the natural transformations commute -/ + fac : ∀ (s : Cocone F) (j : J), dsimp% t.ι.app j ≫ desc s = s.ι.app j := by cat_disch + /-- `desc` is the unique such map -/ + uniq : + ∀ (s : Cocone F) (m : t.pt ⟶ s.pt) (_ : ∀ j : J, t.ι.app j ≫ m = s.ι.app j), m = desc s := by + cat_disch + +attribute [reassoc (attr := simp)] IsLimit.fac IsColimit.fac + +to_dual_name_hint Lift Desc, Left Right namespace IsLimit +@[to_dual] instance subsingleton {t : Cone F} : Subsingleton (IsLimit t) := ⟨by intro P Q; cases P; cases Q; congr; cat_disch⟩ /-- Given a natural transformation `α : F ⟶ G`, we give a morphism from the cone point of any cone over `F` to the cone point of a limit cone over `G`. -/ +@[to_dual (reorder := s P t) +/-- Given a natural transformation `α : F ⟶ G`, we give a morphism from the cocone point +of a colimit cocone over `F` to the cocone point of any cocone over `G`. -/] def map {F G : J ⥤ C} (s : Cone F) {t : Cone G} (P : IsLimit t) (α : F ⟶ G) : s.pt ⟶ t.pt := P.lift ((Cone.postcompose α).obj s) -@[reassoc (attr := simp)] +-- The `set_option` is needed to make reassoc generate the right theorem +set_option backward.isDefEq.respectTransparency false in +@[to_dual (attr := reassoc (attr := simp)) (reorder := c hd d) ι_map] theorem map_π {F G : J ⥤ C} (c : Cone F) {d : Cone G} (hd : IsLimit d) (α : F ⟶ G) (j : J) : hd.map c α ≫ d.π.app j = c.π.app j ≫ α.app j := fac _ _ _ -@[simp] +@[to_dual (attr := simp)] theorem lift_self {c : Cone F} (t : IsLimit c) : t.lift c = 𝟙 c.pt := (t.uniq _ _ fun _ => id_comp _).symm -- Repackaging the definition in terms of cone morphisms. /-- The universal morphism from any other cone to a limit cone. -/ -@[simps] +@[to_dual (attr := simps) +/-- The universal morphism from a colimit cocone to any other cocone. -/] def liftConeMorphism {t : Cone F} (h : IsLimit t) (s : Cone F) : s ⟶ t where hom := h.lift s +@[to_dual] theorem uniq_cone_morphism {s t : Cone F} (h : IsLimit t) {f f' : s ⟶ t} : f = f' := have : ∀ {g : s ⟶ t}, g = h.liftConeMorphism s := by intro g; apply ConeMorphism.ext; exact h.uniq _ _ g.w this.trans this.symm /-- Restating the definition of a limit cone in terms of the ∃! operator. -/ +@[to_dual /-- Restating the definition of a colimit cocone in terms of the ∃! operator. -/] theorem existsUnique {t : Cone F} (h : IsLimit t) (s : Cone F) : ∃! l : s.pt ⟶ t.pt, ∀ j, l ≫ t.π.app j = s.π.app j := ⟨h.lift s, h.fac s, h.uniq s⟩ /-- Noncomputably make a limit cone from the existence of unique factorizations. -/ +@[to_dual /-- Noncomputably make a colimit cocone from the existence of unique factorizations. -/] def ofExistsUnique {t : Cone F} (ht : ∀ s : Cone F, ∃! l : s.pt ⟶ t.pt, ∀ j, l ≫ t.π.app j = s.π.app j) : IsLimit t := by choose s hs hs' using ht @@ -107,7 +133,11 @@ def ofExistsUnique {t : Cone F} providing a morphism of cones rather than a morphism between the cone points and separately the factorisation condition. -/ -@[simps] +@[to_dual (attr := simps) +/-- Alternative constructor for `IsColimit`, +providing a morphism of cocones rather than a morphism between the cocone points +and separately the factorisation condition. +-/] def mkConeMorphism {t : Cone F} (lift : ∀ s : Cone F, s ⟶ t) (uniq : ∀ (s : Cone F) (m : s ⟶ t), m = lift s) : IsLimit t where lift s := (lift s).hom @@ -116,7 +146,7 @@ def mkConeMorphism {t : Cone F} (lift : ∀ s : Cone F, s ⟶ t) congrArg ConeMorphism.hom this /-- Limit cones on `F` are unique up to isomorphism. -/ -@[simps] +@[to_dual (attr := simps) /-- Colimit cocones on `F` are unique up to isomorphism. -/] def uniqueUpToIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : s ≅ t where hom := Q.liftConeMorphism s inv := P.liftConeMorphism t @@ -124,56 +154,61 @@ def uniqueUpToIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : s ≅ t where inv_hom_id := Q.uniq_cone_morphism /-- Any cone morphism between limit cones is an isomorphism. -/ +@[to_dual (reorder := P Q) /-- Any cocone morphism between colimit cocones is an isomorphism. -/] theorem hom_isIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) (f : s ⟶ t) : IsIso f := ⟨⟨P.liftConeMorphism t, ⟨P.uniq_cone_morphism, Q.uniq_cone_morphism⟩⟩⟩ /-- Limits of `F` are unique up to isomorphism. -/ +@[to_dual /-- Colimits of `F` are unique up to isomorphism. -/] def conePointUniqueUpToIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : s.pt ≅ t.pt := (Cone.forget F).mapIso (uniqueUpToIso P Q) -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) comp_coconePointUniqueUpToIso_inv] theorem conePointUniqueUpToIso_hom_comp {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) (j : J) : (conePointUniqueUpToIso P Q).hom ≫ t.π.app j = s.π.app j := (uniqueUpToIso P Q).hom.w _ -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) comp_coconePointUniqueUpToIso_hom] theorem conePointUniqueUpToIso_inv_comp {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) (j : J) : (conePointUniqueUpToIso P Q).inv ≫ s.π.app j = t.π.app j := (uniqueUpToIso P Q).inv.w _ -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) coconePointUniqueUpToIso_inv_desc] theorem lift_comp_conePointUniqueUpToIso_hom {r s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : P.lift r ≫ (conePointUniqueUpToIso P Q).hom = Q.lift r := Q.uniq _ _ (by simp) -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) coconePointUniqueUpToIso_hom_desc] theorem lift_comp_conePointUniqueUpToIso_inv {r s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : Q.lift r ≫ (conePointUniqueUpToIso P Q).inv = P.lift r := P.uniq _ _ (by simp) /-- Transport evidence that a cone is a limit cone across an isomorphism of cones. -/ +@[to_dual +/-- Transport evidence that a cocone is a colimit cocone across an isomorphism of cocones. -/] def ofIsoLimit {r t : Cone F} (P : IsLimit r) (i : r ≅ t) : IsLimit t := IsLimit.mkConeMorphism (fun s => P.liftConeMorphism s ≫ i.hom) fun s m => by rw [← i.comp_inv_eq]; apply P.uniq_cone_morphism -@[simp] +@[to_dual (attr := simp)] theorem ofIsoLimit_lift {r t : Cone F} (P : IsLimit r) (i : r ≅ t) (s) : (P.ofIsoLimit i).lift s = P.lift s ≫ i.hom.hom := rfl /-- Isomorphism of cones preserves whether or not they are limiting cones. -/ +@[to_dual /-- Isomorphism of cocones preserves whether or not they are colimiting cocones. -/] def equivIsoLimit {r t : Cone F} (i : r ≅ t) : IsLimit r ≃ IsLimit t where toFun h := h.ofIsoLimit i invFun h := h.ofIsoLimit i.symm left_inv := by cat_disch right_inv := by cat_disch -@[simp] +@[to_dual (attr := simp)] theorem equivIsoLimit_apply {r t : Cone F} (i : r ≅ t) (P : IsLimit r) : equivIsoLimit i P = P.ofIsoLimit i := rfl -@[simp] +@[to_dual (attr := simp)] theorem equivIsoLimit_symm_apply {r t : Cone F} (i : r ≅ t) (P : IsLimit t) : (equivIsoLimit i).symm P = P.ofIsoLimit i.symm := rfl @@ -181,6 +216,10 @@ theorem equivIsoLimit_symm_apply {r t : Cone F} (i : r ≅ t) (P : IsLimit t) : /-- If the canonical morphism from a cone point to a limiting cone point is an iso, then the first cone was limiting also. -/ +@[to_dual +/-- If the canonical morphism to a cocone point from a colimiting cocone point is an iso, then the +first cocone was colimiting also. +-/] def ofPointIso {r t : Cone F} (P : IsLimit r) [i : IsIso (P.lift t)] : IsLimit t := ofIsoLimit P (by haveI : IsIso (P.liftConeMorphism t).hom := i @@ -191,17 +230,21 @@ def ofPointIso {r t : Cone F} (P : IsLimit r) [i : IsIso (P.lift t)] : IsLimit t variable {t : Cone F} set_option backward.defeqAttrib.useBackward true in +@[to_dual] theorem hom_lift (h : IsLimit t) {W : C} (m : W ⟶ t.pt) : m = h.lift { pt := W, π := { app := fun b => m ≫ t.π.app b } } := h.uniq { pt := W, π := { app := fun b => m ≫ t.π.app b } } m fun _ => rfl /-- Two morphisms into a limit are equal if their compositions with - each cone morphism are equal. -/ +each cone morphism are equal. -/ +@[to_dual /-- Two morphisms out of a colimit are equal if their compositions with +each cocone morphism are equal. -/] theorem hom_ext (h : IsLimit t) {W : C} {f f' : W ⟶ t.pt} (w : ∀ j, f ≫ t.π.app j = f' ≫ t.π.app j) : f = f' := by rw [h.hom_lift f, h.hom_lift f']; congr; exact funext w +@[to_dual] lemma nonempty_isLimit_iff_isIso_lift {s t : Cone F} (hs : IsLimit s) : Nonempty (IsLimit t) ↔ IsIso (hs.lift t) := ⟨fun ⟨ht⟩ ↦ ⟨ht.lift s, ht.hom_ext (by simp), hs.hom_ext (by simp)⟩, fun h ↦ ⟨hs.ofPointIso⟩⟩ @@ -209,6 +252,10 @@ lemma nonempty_isLimit_iff_isIso_lift {s t : Cone F} (hs : IsLimit s) : /-- Given a right adjoint functor between categories of cones, the image of a limit cone is a limit cone. -/ +@[to_dual +/-- Given a left adjoint functor between categories of cocones, +the image of a colimit cocone is a colimit cocone. +-/] def ofRightAdjoint {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} {left : Cone F ⥤ Cone G} {right : Cone G ⥤ Cone F} (adj : left ⊣ right) {c : Cone G} (t : IsLimit c) : IsLimit (right.obj c) := @@ -225,31 +272,56 @@ def ofConeEquiv {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} (h : Cone G left_inv := by cat_disch right_inv := by cat_disch -@[simp] -theorem ofConeEquiv_apply_desc {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} (h : Cone G ≌ Cone F) +/-- Given two functors which have equivalent categories of cocones, +we can transport a colimiting cocone across the equivalence. +-/ +@[to_dual existing] +def _root_.CategoryTheory.Limits.IsColimit.ofCoconeEquiv {D : Type u₄} [Category.{v₄} D] + {G : K ⥤ D} (h : Cocone G ≌ Cocone F) {c : Cocone G} : + IsColimit (h.functor.obj c) ≃ IsColimit c where + toFun P := IsColimit.ofIsoColimit (IsColimit.ofLeftAdjoint h.symm.toAdjunction P) + (h.unitIso.symm.app c) + invFun := IsColimit.ofLeftAdjoint h.toAdjunction + left_inv := by cat_disch + right_inv := by cat_disch + +@[to_dual (attr := simp)] +theorem ofConeEquiv_apply_lift {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} (h : Cone G ≌ Cone F) {c : Cone G} (P : IsLimit (h.functor.obj c)) (s) : (ofConeEquiv h P).lift s = ((h.unitIso.hom.app s).hom ≫ (h.inverse.map (P.liftConeMorphism (h.functor.obj s))).hom) ≫ (h.unitIso.inv.app c).hom := rfl -@[simp] -theorem ofConeEquiv_symm_apply_desc {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} +@[to_dual (attr := simp)] +theorem ofConeEquiv_symm_apply_lift {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} (h : Cone G ≌ Cone F) {c : Cone G} (P : IsLimit c) (s) : ((ofConeEquiv h).symm P).lift s = (h.counitIso.inv.app s).hom ≫ (h.functor.map (P.liftConeMorphism (h.inverse.obj s))).hom := rfl -/-- -A cone postcomposed with a natural isomorphism is a limit cone if and only if the original cone is. +@[deprecated (since := "2026-06-21")] alias ofConeEquiv_apply_desc := ofConeEquiv_apply_lift +@[deprecated (since := "2026-06-21")] +alias ofConeEquiv_symm_apply_desc := ofConeEquiv_symm_apply_lift + +/-- A cone postcomposed with a natural isomorphism is a limit cone +if and only if the original cone is. -/ +@[to_dual precomposeInvEquiv +/-- A cocone precomposed with the inverse of a natural isomorphism is a colimit cocone +if and only if the original cocone is. +-/] def postcomposeHomEquiv {F G : J ⥤ C} (α : F ≅ G) (c : Cone F) : IsLimit ((Cone.postcompose α.hom).obj c) ≃ IsLimit c := ofConeEquiv (Cone.postcomposeEquivalence α) -/-- A cone postcomposed with the inverse of a natural isomorphism is a limit cone if and only if -the original cone is. +/-- A cone postcomposed with the inverse of a natural isomorphism is a limit cone +if and only if the original cone is. -/ +@[to_dual precomposeHomEquiv +/-- A cocone precomposed with a natural isomorphism is a colimit cocone +if and only if the original cocone is. +-/] def postcomposeInvEquiv {F G : J ⥤ C} (α : F ≅ G) (c : Cone G) : IsLimit ((Cone.postcompose α.inv).obj c) ≃ IsLimit c := postcomposeHomEquiv α.symm c @@ -257,6 +329,10 @@ def postcomposeInvEquiv {F G : J ⥤ C} (α : F ≅ G) (c : Cone G) : /-- Constructing an equivalence `IsLimit c ≃ IsLimit d` from a natural isomorphism between the underlying functors, and then an isomorphism between `c` transported along this and `d`. -/ +@[to_dual +/-- Constructing an equivalence `isColimit c ≃ isColimit d` from a natural isomorphism +between the underlying functors, and then an isomorphism between `c` transported along this and `d`. +-/] def equivOfNatIsoOfIso {F G : J ⥤ C} (α : F ≅ G) (c : Cone F) (d : Cone G) (w : (Cone.postcompose α.hom).obj c ≅ d) : IsLimit c ≃ IsLimit d := (postcomposeHomEquiv α _).symm.trans (equivIsoLimit w) @@ -265,7 +341,10 @@ set_option backward.defeqAttrib.useBackward true in /-- The cone points of two limit cones for naturally isomorphic functors are themselves isomorphic. -/ -@[simps] +@[to_dual (attr := simps) +/-- The cocone points of two colimit cocones for naturally isomorphic functors +are themselves isomorphic. +-/] def conePointsIsoOfNatIso {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) : s.pt ≅ t.pt where hom := Q.map s w.hom @@ -273,25 +352,30 @@ def conePointsIsoOfNatIso {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit hom_inv_id := P.hom_ext (by simp) inv_hom_id := Q.hom_ext (by simp) -@[reassoc] +set_option linter.translateOverwrite false in +attribute [to_dual existing IsColimit.coconePointsIsoOfNatIso_inv] conePointsIsoOfNatIso_hom +set_option linter.translateOverwrite false in +attribute [to_dual existing IsColimit.coconePointsIsoOfNatIso_hom] conePointsIsoOfNatIso_inv + +@[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_inv] theorem conePointsIsoOfNatIso_hom_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) (j : J) : (conePointsIsoOfNatIso P Q w).hom ≫ t.π.app j = s.π.app j ≫ w.hom.app j := by simp -@[reassoc] +@[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_hom] theorem conePointsIsoOfNatIso_inv_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) (j : J) : (conePointsIsoOfNatIso P Q w).inv ≫ s.π.app j = t.π.app j ≫ w.inv.app j := by simp set_option backward.defeqAttrib.useBackward true in -@[reassoc] +@[to_dual (attr := reassoc) coconePointsIsoOfNatIso_inv_desc] theorem lift_comp_conePointsIsoOfNatIso_hom {F G : J ⥤ C} {r s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) : P.lift r ≫ (conePointsIsoOfNatIso P Q w).hom = Q.map r w.hom := Q.hom_ext (by simp) set_option backward.defeqAttrib.useBackward true in -@[reassoc] +@[to_dual (attr := reassoc) coconePointsIsoOfNatIso_hom_desc] theorem lift_comp_conePointsIsoOfNatIso_inv {F G : J ⥤ C} {r s : Cone G} {t : Cone F} (P : IsLimit t) (Q : IsLimit s) (w : F ≅ G) : Q.lift r ≫ (conePointsIsoOfNatIso P Q w).inv = P.map r w.inv := @@ -301,33 +385,48 @@ section Equivalence open CategoryTheory.Equivalence -/-- If `s : Cone F` is a limit cone, so is `s` whiskered by an equivalence `e`. --/ +/-- If `s : Cone F` is a limit cone, so is `s` whiskered by an equivalence `e`. -/ def whiskerEquivalence {s : Cone F} (P : IsLimit s) (e : K ≌ J) : IsLimit (s.whisker e.functor) := ofRightAdjoint (Cone.whiskeringEquivalence e).symm.toAdjunction P -/-- If `s : Cone F` whiskered by an equivalence `e` is a limit cone, so is `s`. --/ +/-- If `s : Cocone F` is a colimit cocone, so is `s` whiskered by an equivalence `e`. -/ +@[to_dual existing] +def _root_.CategoryTheory.Limits.IsColimit.whiskerEquivalence {s : Cocone F} + (P : IsColimit s) (e : K ≌ J) : IsColimit (s.whisker e.functor) := + IsColimit.ofLeftAdjoint (Cocone.whiskeringEquivalence e).toAdjunction P + +/-- If `s : Cone F` whiskered by an equivalence `e` is a limit cone, so is `s`. -/ def ofWhiskerEquivalence {s : Cone F} (e : K ≌ J) (P : IsLimit (s.whisker e.functor)) : IsLimit s := equivIsoLimit ((Cone.whiskeringEquivalence e).unitIso.app s).symm (ofRightAdjoint (Cone.whiskeringEquivalence e).toAdjunction P) -/-- Given an equivalence of diagrams `e`, `s` is a limit cone iff `s.whisker e.functor` is. --/ +/-- If `s : Cocone F` whiskered by an equivalence `e` is a colimit cocone, so is `s`. -/ +@[to_dual existing] +def _root_.CategoryTheory.Limits.IsColimit.ofWhiskerEquivalence {s : Cocone F} (e : K ≌ J) + (P : IsColimit (s.whisker e.functor)) : IsColimit s := + IsColimit.equivIsoColimit ((Cocone.whiskeringEquivalence e).unitIso.app s).symm + (IsColimit.ofLeftAdjoint (Cocone.whiskeringEquivalence e).symm.toAdjunction P) + +/-- Given an equivalence of diagrams `e`, `s` is a limit cone iff `s.whisker e.functor` is. -/ +@[to_dual +/-- Given an equivalence of diagrams `e`, `s` is a colimit cocone iff `s.whisker e.functor` is. -/] def whiskerEquivalenceEquiv {s : Cone F} (e : K ≌ J) : IsLimit s ≃ IsLimit (s.whisker e.functor) := ⟨fun h => h.whiskerEquivalence e, ofWhiskerEquivalence e, by cat_disch, by cat_disch⟩ /-- A limit cone extended by an isomorphism is a limit cone. -/ +@[to_dual /-- A colimit cocone extended by an isomorphism is a colimit cocone. -/] def extendIso {s : Cone F} {X : C} (i : X ⟶ s.pt) [IsIso i] (hs : IsLimit s) : IsLimit (s.extend i) := IsLimit.ofIsoLimit hs (Cone.extendIso s (asIso' i)) /-- A cone is a limit cone if its extension by an isomorphism is. -/ +@[to_dual /-- A cocone is a colimit cocone if its extension by an isomorphism is. -/] def ofExtendIso {s : Cone F} {X : C} (i : X ⟶ s.pt) [IsIso i] (hs : IsLimit (s.extend i)) : IsLimit s := IsLimit.ofIsoLimit hs (Cone.extendIso s (asIso' i)).symm /-- A cone is a limit cone iff its extension by an isomorphism is. -/ +@[to_dual /-- A cocone is a colimit cocone iff its extension by an isomorphism is. -/] def extendIsoEquiv {s : Cone F} {X : C} (i : X ⟶ s.pt) [IsIso i] : IsLimit s ≃ IsLimit (s.extend i) := equivOfSubsingletonOfSubsingleton (extendIso i) (ofExtendIso i) @@ -343,7 +442,16 @@ This is the most general form of uniqueness of cone points, allowing relabelling of both the indexing category (up to equivalence) and the functor (up to natural isomorphism). -/ -@[simps] +@[to_dual (attr := simps) +/-- We can prove two cocone points `(s : Cocone F).pt` and `(t : Cocone G).pt` are isomorphic if +* both cocones are colimit cocones +* their indexing categories are equivalent via some `e : J ≌ K`, +* the triangle of functors commutes up to a natural isomorphism: `e.functor ⋙ G ≅ F`. + +This is the most general form of uniqueness of cocone points, +allowing relabelling of both the indexing category (up to equivalence) +and the functor (up to natural isomorphism). +-/] def conePointsIsoOfEquivalence {F : J ⥤ C} {s : Cone F} {G : K ⥤ C} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (e : J ≌ K) (w : e.functor ⋙ G ≅ F) : s.pt ≅ t.pt := let w' : e.inverse ⋙ F ≅ G := (isoWhiskerLeft e.inverse w).symm ≪≫ invFunIdAssoc e G @@ -354,45 +462,55 @@ def conePointsIsoOfEquivalence {F : J ⥤ C} {s : Cone F} {G : K ⥤ C} {t : Con dsimp [w'] simp only [Limits.Cone.whisker_π, Limits.Cone.postcompose_obj_π, fac, whiskerLeft_app, assoc, id_comp, invFunIdAssoc_hom_app, fac_assoc, NatTrans.comp_app] - rw [counit_app_functor, ← Functor.comp_map] - have l : - NatTrans.app w.hom j = NatTrans.app w.hom ((𝟭 J).obj j) := by dsimp - rw [l, w.hom.naturality] + rw [counit_app_functor, ← Functor.comp_map, ← w.inv.naturality_assoc] simp inv_hom_id := by apply hom_ext Q cat_disch } +set_option linter.translateOverwrite false in +attribute [to_dual existing IsColimit.coconePointsIsoOfEquivalence_inv] + conePointsIsoOfEquivalence_hom +set_option linter.translateOverwrite false in +attribute [to_dual existing IsColimit.coconePointsIsoOfEquivalence_hom] + conePointsIsoOfEquivalence_inv + end Equivalence set_option backward.defeqAttrib.useBackward true in -/-- The universal property of a limit cone: a wap `W ⟶ t.pt` is the same as - a cone on `F` with cone point `W`. -/ -@[simps apply] +/-- The universal property of a limit cone: a map `W ⟶ t.pt` is the same as +a cone on `F` with cone point `W`. -/ +@[to_dual (attr := simps apply) +/-- The universal property of a colimit cocone: a map `X ⟶ W` is the same as +a cocone on `F` with cone point `W`. -/] def homEquiv (h : IsLimit t) {W : C} : (W ⟶ t.pt) ≃ ((Functor.const J).obj W ⟶ F) where toFun f := (t.extend f).π invFun π := h.lift (Cone.mk _ π) left_inv f := h.hom_ext (by simp) right_inv π := by cat_disch -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) ι_app_homEquiv_symm] lemma homEquiv_symm_π_app (h : IsLimit t) {W : C} (f : (const J).obj W ⟶ F) (j : J) : h.homEquiv.symm f ≫ t.π.app j = f.app j := by simp [homEquiv] set_option backward.defeqAttrib.useBackward true in +@[to_dual] lemma homEquiv_symm_naturality (h : IsLimit t) {W W' : C} (f : (const J).obj W ⟶ F) (g : W' ⟶ W) : h.homEquiv.symm ((Functor.const _).map g ≫ f) = g ≫ h.homEquiv.symm f := h.homEquiv.injective (by aesop) /-- The universal property of a limit cone: a map `W ⟶ X` is the same as - a cone on `F` with cone point `W`. -/ -def homIso (h : IsLimit t) (W : C) : - (ULift.{u₁} (W ⟶ t.pt : Type v₃)) ≅ ((const J).obj W ⟶ F) := +a cone on `F` with cone point `W`. -/ +@[to_dual +/-- The universal property of a colimit cocone: a map `X ⟶ W` is the same as +a cocone on `F` with cone point `W`. -/] +def homIso (h : IsLimit t) (W : C) : ULift.{u₁} (W ⟶ t.pt : Type v₃) ≅ (const J).obj W ⟶ F := Equiv.toIso (Equiv.ulift.trans h.homEquiv) +-- TODO: `to_dual` doesn't yet know that it shouldn't translate the category on `Type _`. @[simp] theorem homIso_hom (h : IsLimit t) {W : C} : (IsLimit.homIso h W).hom = ↾fun f ↦ (t.extend f.down).π := @@ -417,9 +535,12 @@ def homIso' (h : IsLimit t) (W : C) : { app := fun j => p.1 j naturality := fun j j' f => by dsimp; rw [id_comp]; exact (p.2 f).symm } } -/-- If G : C → D is a faithful functor which sends t to a limit cone, - then it suffices to check that the induced maps for the image of t - can be lifted to maps of C. -/ +/-- If `G : C → D` is a faithful functor which sends t to a limit cone, +then it suffices to check that the induced maps for the image of t +can be lifted to maps of `C`. -/ +@[to_dual /-- If `G : C → D` is a faithful functor which sends t to a colimit cocone, +then it suffices to check that the induced maps for the image of t +can be lifted to maps of `C`. -/] def ofFaithful {t : Cone F} {D : Type u₄} [Category.{v₄} D] (G : C ⥤ D) [G.Faithful] (ht : IsLimit (mapCone G t)) (lift : ∀ s : Cone F, s.pt ⟶ t.pt) (h : ∀ s, G.map (lift s) = ht.lift (mapCone G s)) : IsLimit t := @@ -434,11 +555,16 @@ def ofFaithful {t : Cone F} {D : Type u₄} [Category.{v₄} D] (G : C ⥤ D) [G /-- If `F` and `G` are naturally isomorphic, then `F.mapCone c` being a limit implies `G.mapCone c` is also a limit. -/ +@[to_dual +/-- If `F` and `G` are naturally isomorphic, then `F.mapCocone c` being a colimit implies +`G.mapCocone c` is also a colimit. +-/] def mapConeEquiv {D : Type u₄} [Category.{v₄} D] {K : J ⥤ C} {F G : C ⥤ D} (h : F ≅ G) {c : Cone K} (t : IsLimit (mapCone F c)) : IsLimit (mapCone G c) := by apply postcomposeInvEquiv (isoWhiskerLeft K h :) (mapCone G c) _ apply t.ofIsoLimit (postcomposeWhiskerLeftMapCone h.symm c).symm +-- TODO: `to_dual` doesn't yet know that it shouldn't translate the category on `Type _`. /-- A cone is a limit cone exactly if there is a unique cone morphism from any other cone. -/ @@ -533,369 +659,12 @@ end end IsLimit -/-- A cocone `t` on `F` is a colimit cocone if each cocone on `F` admits a unique -cocone morphism from `t`. -/ -@[stacks 002F] -structure IsColimit (t : Cocone F) where - /-- `t.pt` maps to all other cocone covertices -/ - desc : ∀ s : Cocone F, t.pt ⟶ s.pt - /-- The map `desc` makes the diagram with the natural transformations commute -/ - fac : ∀ (s : Cocone F) (j : J), t.ι.app j ≫ desc s = s.ι.app j := by cat_disch - /-- `desc` is the unique such map -/ - uniq : - ∀ (s : Cocone F) (m : t.pt ⟶ s.pt) (_ : ∀ j : J, t.ι.app j ≫ m = s.ι.app j), m = desc s := by - cat_disch - -attribute [reassoc (attr := simp)] IsColimit.fac namespace IsColimit -instance subsingleton {t : Cocone F} : Subsingleton (IsColimit t) := - ⟨by intro P Q; cases P; cases Q; congr; cat_disch⟩ - -/-- Given a natural transformation `α : F ⟶ G`, we give a morphism from the cocone point -of a colimit cocone over `F` to the cocone point of any cocone over `G`. -/ -def map {F G : J ⥤ C} {s : Cocone F} (P : IsColimit s) (t : Cocone G) (α : F ⟶ G) : s.pt ⟶ t.pt := - P.desc ((Cocone.precompose α).obj t) - -set_option backward.isDefEq.respectTransparency false in -- This is needed in CategoryTheory/Limits/Shapes/Biproducts.lean -@[reassoc (attr := simp)] -theorem ι_map {F G : J ⥤ C} {c : Cocone F} (hc : IsColimit c) (d : Cocone G) (α : F ⟶ G) (j : J) : - c.ι.app j ≫ IsColimit.map hc d α = α.app j ≫ d.ι.app j := - fac _ _ _ - -@[simp] -theorem desc_self {t : Cocone F} (h : IsColimit t) : h.desc t = 𝟙 t.pt := - (h.uniq _ _ fun _ => comp_id _).symm - -set_option backward.isDefEq.respectTransparency false in --- Repackaging the definition in terms of cocone morphisms. -/-- The universal morphism from a colimit cocone to any other cocone. -/ -@[simps] -def descCoconeMorphism {t : Cocone F} (h : IsColimit t) (s : Cocone F) : t ⟶ s where hom := h.desc s - -theorem uniq_cocone_morphism {s t : Cocone F} (h : IsColimit t) {f f' : t ⟶ s} : f = f' := - have : ∀ {g : t ⟶ s}, g = h.descCoconeMorphism s := by - intro g; ext; exact h.uniq _ _ g.w - this.trans this.symm - -/-- Restating the definition of a colimit cocone in terms of the ∃! operator. -/ -theorem existsUnique {t : Cocone F} (h : IsColimit t) (s : Cocone F) : - ∃! d : t.pt ⟶ s.pt, ∀ j, t.ι.app j ≫ d = s.ι.app j := - ⟨h.desc s, h.fac s, h.uniq s⟩ - -/-- Noncomputably make a colimit cocone from the existence of unique factorizations. -/ -def ofExistsUnique {t : Cocone F} - (ht : ∀ s : Cocone F, ∃! d : t.pt ⟶ s.pt, ∀ j, t.ι.app j ≫ d = s.ι.app j) : IsColimit t := by - choose s hs hs' using ht - exact ⟨s, hs, hs'⟩ - -set_option backward.defeqAttrib.useBackward true in -/-- Alternative constructor for `IsColimit`, -providing a morphism of cocones rather than a morphism between the cocone points -and separately the factorisation condition. --/ -@[simps] -def mkCoconeMorphism {t : Cocone F} (desc : ∀ s : Cocone F, t ⟶ s) - (uniq' : ∀ (s : Cocone F) (m : t ⟶ s), m = desc s) : IsColimit t where - desc s := (desc s).hom - uniq s m w := - have : CoconeMorphism.mk m w = desc s := by apply uniq' - congrArg CoconeMorphism.hom this - -/-- Colimit cocones on `F` are unique up to isomorphism. -/ -@[simps] -def uniqueUpToIso {s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) : s ≅ t where - hom := P.descCoconeMorphism t - inv := Q.descCoconeMorphism s - hom_inv_id := P.uniq_cocone_morphism - inv_hom_id := Q.uniq_cocone_morphism - -/-- Any cocone morphism between colimit cocones is an isomorphism. -/ -theorem hom_isIso {s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) (f : s ⟶ t) : IsIso f := - ⟨⟨Q.descCoconeMorphism s, ⟨P.uniq_cocone_morphism, Q.uniq_cocone_morphism⟩⟩⟩ - -/-- Colimits of `F` are unique up to isomorphism. -/ -def coconePointUniqueUpToIso {s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) : s.pt ≅ t.pt := - (Cocone.forget F).mapIso (uniqueUpToIso P Q) - -@[reassoc (attr := simp)] -theorem comp_coconePointUniqueUpToIso_hom {s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) - (j : J) : s.ι.app j ≫ (coconePointUniqueUpToIso P Q).hom = t.ι.app j := - (uniqueUpToIso P Q).hom.w _ - -@[reassoc (attr := simp)] -theorem comp_coconePointUniqueUpToIso_inv {s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) - (j : J) : t.ι.app j ≫ (coconePointUniqueUpToIso P Q).inv = s.ι.app j := - (uniqueUpToIso P Q).inv.w _ - -set_option backward.isDefEq.respectTransparency false in -@[reassoc (attr := simp)] -theorem coconePointUniqueUpToIso_hom_desc {r s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) : - (coconePointUniqueUpToIso P Q).hom ≫ Q.desc r = P.desc r := - P.uniq _ _ (by simp) - -set_option backward.isDefEq.respectTransparency false in -@[reassoc (attr := simp)] -theorem coconePointUniqueUpToIso_inv_desc {r s t : Cocone F} (P : IsColimit s) (Q : IsColimit t) : - (coconePointUniqueUpToIso P Q).inv ≫ P.desc r = Q.desc r := - Q.uniq _ _ (by simp) - -/-- Transport evidence that a cocone is a colimit cocone across an isomorphism of cocones. -/ -def ofIsoColimit {r t : Cocone F} (P : IsColimit r) (i : r ≅ t) : IsColimit t := - IsColimit.mkCoconeMorphism (fun s => i.inv ≫ P.descCoconeMorphism s) fun s m => by - rw [i.eq_inv_comp]; apply P.uniq_cocone_morphism - -@[simp] -theorem ofIsoColimit_desc {r t : Cocone F} (P : IsColimit r) (i : r ≅ t) (s) : - (P.ofIsoColimit i).desc s = i.inv.hom ≫ P.desc s := - rfl - -/-- Isomorphism of cocones preserves whether or not they are colimiting cocones. -/ -def equivIsoColimit {r t : Cocone F} (i : r ≅ t) : IsColimit r ≃ IsColimit t where - toFun h := h.ofIsoColimit i - invFun h := h.ofIsoColimit i.symm - left_inv := by cat_disch - right_inv := by cat_disch - -@[simp] -theorem equivIsoColimit_apply {r t : Cocone F} (i : r ≅ t) (P : IsColimit r) : - equivIsoColimit i P = P.ofIsoColimit i := - rfl - -@[simp] -theorem equivIsoColimit_symm_apply {r t : Cocone F} (i : r ≅ t) (P : IsColimit t) : - (equivIsoColimit i).symm P = P.ofIsoColimit i.symm := - rfl - -/-- If the canonical morphism to a cocone point from a colimiting cocone point is an iso, then the -first cocone was colimiting also. --/ -def ofPointIso {r t : Cocone F} (P : IsColimit r) [i : IsIso (P.desc t)] : IsColimit t := - ofIsoColimit P (by - haveI : IsIso (P.descCoconeMorphism t).hom := i - haveI : IsIso (P.descCoconeMorphism t) := Cocone.cocone_iso_of_hom_iso _ - apply asIso (P.descCoconeMorphism t)) variable {t : Cocone F} -set_option backward.defeqAttrib.useBackward true in -theorem hom_desc (h : IsColimit t) {W : C} (m : t.pt ⟶ W) : - m = - h.desc - { pt := W - ι := { app := fun b => t.ι.app b ≫ m } } := - h.uniq - { pt := W - ι := { app := fun b => t.ι.app b ≫ m } } - m fun _ => rfl - -/-- Two morphisms out of a colimit are equal if their compositions with - each cocone morphism are equal. -/ -theorem hom_ext (h : IsColimit t) {W : C} {f f' : t.pt ⟶ W} - (w : ∀ j, t.ι.app j ≫ f = t.ι.app j ≫ f') : f = f' := by - rw [h.hom_desc f, h.hom_desc f']; congr; exact funext w - -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -lemma nonempty_isColimit_iff_isIso_desc {s t : Cocone F} (hs : IsColimit s) : - Nonempty (IsColimit t) ↔ IsIso (hs.desc t) := - ⟨fun ⟨ht⟩ ↦ ⟨ht.desc s, hs.hom_ext (by simp), ht.hom_ext (by simp)⟩, fun h ↦ ⟨hs.ofPointIso⟩⟩ - -/-- Given a left adjoint functor between categories of cocones, -the image of a colimit cocone is a colimit cocone. --/ -def ofLeftAdjoint {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} {left : Cocone G ⥤ Cocone F} - {right : Cocone F ⥤ Cocone G} (adj : left ⊣ right) {c : Cocone G} (t : IsColimit c) : - IsColimit (left.obj c) := - mkCoconeMorphism - (fun s => (adj.homEquiv c s).symm (t.descCoconeMorphism _)) fun _ _ => - (Adjunction.homEquiv_apply_eq _ _ _).1 t.uniq_cocone_morphism - -/-- Given two functors which have equivalent categories of cocones, -we can transport a colimiting cocone across the equivalence. --/ -def ofCoconeEquiv {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} (h : Cocone G ≌ Cocone F) - {c : Cocone G} : IsColimit (h.functor.obj c) ≃ IsColimit c where - toFun P := ofIsoColimit (ofLeftAdjoint h.symm.toAdjunction P) (h.unitIso.symm.app c) - invFun := ofLeftAdjoint h.toAdjunction - left_inv := by cat_disch - right_inv := by cat_disch - -@[simp] -theorem ofCoconeEquiv_apply_desc {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} - (h : Cocone G ≌ Cocone F) {c : Cocone G} (P : IsColimit (h.functor.obj c)) (s) : - (ofCoconeEquiv h P).desc s = - (h.unit.app c).hom ≫ - (h.inverse.map (P.descCoconeMorphism (h.functor.obj s))).hom ≫ (h.unitInv.app s).hom := - rfl - -@[simp] -theorem ofCoconeEquiv_symm_apply_desc {D : Type u₄} [Category.{v₄} D] {G : K ⥤ D} - (h : Cocone G ≌ Cocone F) {c : Cocone G} (P : IsColimit c) (s) : - ((ofCoconeEquiv h).symm P).desc s = - (h.functor.map (P.descCoconeMorphism (h.inverse.obj s))).hom ≫ (h.counit.app s).hom := - rfl - -/-- A cocone precomposed with the inverse of a natural isomorphism is a colimit cocone -if and only if the original cocone is. --/ -def precomposeInvEquiv {F G : J ⥤ C} (α : F ≅ G) (c : Cocone F) : - IsColimit ((Cocone.precompose α.inv).obj c) ≃ IsColimit c := - ofCoconeEquiv (Cocone.precomposeEquivalence α) - -/-- A cocone precomposed with a natural isomorphism is a colimit cocone -if and only if the original cocone is. --/ -def precomposeHomEquiv {F G : J ⥤ C} (α : F ≅ G) (c : Cocone G) : - IsColimit ((Cocone.precompose α.hom).obj c) ≃ IsColimit c := - precomposeInvEquiv α.symm c - -/-- Constructing an equivalence `is_colimit c ≃ is_colimit d` from a natural isomorphism -between the underlying functors, and then an isomorphism between `c` transported along this and `d`. --/ -def equivOfNatIsoOfIso {F G : J ⥤ C} (α : F ≅ G) (c : Cocone F) (d : Cocone G) - (w : (Cocone.precompose α.inv).obj c ≅ d) : IsColimit c ≃ IsColimit d := - (precomposeInvEquiv α _).symm.trans (equivIsoColimit w) - -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -/-- The cocone points of two colimit cocones for naturally isomorphic functors -are themselves isomorphic. --/ -@[simps] -def coconePointsIsoOfNatIso {F G : J ⥤ C} {s : Cocone F} {t : Cocone G} (P : IsColimit s) - (Q : IsColimit t) (w : F ≅ G) : s.pt ≅ t.pt where - hom := P.map t w.hom - inv := Q.map s w.inv - hom_inv_id := P.hom_ext (by simp) - inv_hom_id := Q.hom_ext (by simp) - -@[reassoc] -theorem comp_coconePointsIsoOfNatIso_hom {F G : J ⥤ C} {s : Cocone F} {t : Cocone G} - (P : IsColimit s) (Q : IsColimit t) (w : F ≅ G) (j : J) : - s.ι.app j ≫ (coconePointsIsoOfNatIso P Q w).hom = w.hom.app j ≫ t.ι.app j := by simp - -@[reassoc] -theorem comp_coconePointsIsoOfNatIso_inv {F G : J ⥤ C} {s : Cocone F} {t : Cocone G} - (P : IsColimit s) (Q : IsColimit t) (w : F ≅ G) (j : J) : - t.ι.app j ≫ (coconePointsIsoOfNatIso P Q w).inv = w.inv.app j ≫ s.ι.app j := by simp - -set_option backward.isDefEq.respectTransparency false in -@[reassoc] -theorem coconePointsIsoOfNatIso_hom_desc {F G : J ⥤ C} {s : Cocone F} {r t : Cocone G} - (P : IsColimit s) (Q : IsColimit t) (w : F ≅ G) : - (coconePointsIsoOfNatIso P Q w).hom ≫ Q.desc r = P.map _ w.hom := - P.hom_ext (by simp) - -set_option backward.isDefEq.respectTransparency false in -@[reassoc] -theorem coconePointsIsoOfNatIso_inv_desc {F G : J ⥤ C} {s : Cocone G} {r t : Cocone F} - (P : IsColimit t) (Q : IsColimit s) (w : F ≅ G) : - (coconePointsIsoOfNatIso P Q w).inv ≫ P.desc r = Q.map _ w.inv := - Q.hom_ext (by simp) - -section Equivalence - -open CategoryTheory.Equivalence - -/-- If `s : Cocone F` is a colimit cocone, so is `s` whiskered by an equivalence `e`. --/ -def whiskerEquivalence {s : Cocone F} (P : IsColimit s) (e : K ≌ J) : - IsColimit (s.whisker e.functor) := - ofLeftAdjoint (Cocone.whiskeringEquivalence e).toAdjunction P - -/-- If `s : Cocone F` whiskered by an equivalence `e` is a colimit cocone, so is `s`. --/ -def ofWhiskerEquivalence {s : Cocone F} (e : K ≌ J) (P : IsColimit (s.whisker e.functor)) : - IsColimit s := - equivIsoColimit ((Cocone.whiskeringEquivalence e).unitIso.app s).symm - (ofLeftAdjoint (Cocone.whiskeringEquivalence e).symm.toAdjunction P) - -/-- Given an equivalence of diagrams `e`, `s` is a colimit cocone iff `s.whisker e.functor` is. --/ -def whiskerEquivalenceEquiv {s : Cocone F} (e : K ≌ J) : - IsColimit s ≃ IsColimit (s.whisker e.functor) := - ⟨fun h => h.whiskerEquivalence e, ofWhiskerEquivalence e, by cat_disch, by cat_disch⟩ - -/-- A colimit cocone extended by an isomorphism is a colimit cocone. -/ -def extendIso {s : Cocone F} {X : C} (i : s.pt ⟶ X) [IsIso i] (hs : IsColimit s) : - IsColimit (s.extend i) := - IsColimit.ofIsoColimit hs (Cocone.extendIso s (asIso i)) - -/-- A cocone is a colimit cocone if its extension by an isomorphism is. -/ -def ofExtendIso {s : Cocone F} {X : C} (i : s.pt ⟶ X) [IsIso i] (hs : IsColimit (s.extend i)) : - IsColimit s := - IsColimit.ofIsoColimit hs (Cocone.extendIso s (asIso i)).symm - -/-- A cocone is a colimit cocone iff its extension by an isomorphism is. -/ -def extendIsoEquiv {s : Cocone F} {X : C} (i : s.pt ⟶ X) [IsIso i] : - IsColimit s ≃ IsColimit (s.extend i) := - equivOfSubsingletonOfSubsingleton (extendIso i) (ofExtendIso i) - -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -/-- We can prove two cocone points `(s : Cocone F).pt` and `(t : Cocone G).pt` are isomorphic if -* both cocones are colimit cocones -* their indexing categories are equivalent via some `e : J ≌ K`, -* the triangle of functors commutes up to a natural isomorphism: `e.functor ⋙ G ≅ F`. - -This is the most general form of uniqueness of cocone points, -allowing relabelling of both the indexing category (up to equivalence) -and the functor (up to natural isomorphism). --/ -@[simps] -def coconePointsIsoOfEquivalence {F : J ⥤ C} {s : Cocone F} {G : K ⥤ C} {t : Cocone G} - (P : IsColimit s) (Q : IsColimit t) (e : J ≌ K) (w : e.functor ⋙ G ≅ F) : s.pt ≅ t.pt := - let w' : e.inverse ⋙ F ≅ G := (isoWhiskerLeft e.inverse w).symm ≪≫ invFunIdAssoc e G - { hom := P.desc ((Cocone.equivalenceOfReindexing e w).functor.obj t) - inv := Q.desc ((Cocone.equivalenceOfReindexing e.symm w').functor.obj s) - hom_inv_id := by - apply hom_ext P; intro j - dsimp [w'] - simp only [Limits.Cocone.whisker_ι, fac, invFunIdAssoc_inv_app, whiskerLeft_app, assoc, - comp_id, Limits.Cocone.precompose_obj_ι, fac_assoc, NatTrans.comp_app] - rw [counitInv_app_functor, ← Functor.comp_map, ← w.inv.naturality_assoc] - simp - inv_hom_id := by - apply hom_ext Q - cat_disch } - -end Equivalence - -set_option backward.isDefEq.respectTransparency false in -/-- The universal property of a colimit cocone: a map `X ⟶ W` is the same as - a cocone on `F` with cone point `W`. -/ -def homEquiv (h : IsColimit t) {W : C} : (t.pt ⟶ W) ≃ (F ⟶ (const J).obj W) where - toFun f := (t.extend f).ι - invFun ι := h.desc - { pt := W - ι } - left_inv f := h.hom_ext (by simp) - right_inv ι := by cat_disch - -@[simp] -lemma homEquiv_apply (h : IsColimit t) {W : C} (f : t.pt ⟶ W) : - h.homEquiv f = (t.extend f).ι := rfl - -@[reassoc (attr := simp)] -lemma ι_app_homEquiv_symm (h : IsColimit t) {W : C} - (f : F ⟶ (const J).obj W) (j : J) : - t.ι.app j ≫ h.homEquiv.symm f = f.app j := by - simp [homEquiv] - -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -lemma homEquiv_symm_naturality (h : IsColimit t) {W W' : C} - (f : F ⟶ (const J).obj W) (g : W ⟶ W') : - h.homEquiv.symm (f ≫ (Functor.const _).map g) = h.homEquiv.symm f ≫ g := - h.homEquiv.injective (by aesop) - -/-- The universal property of a colimit cocone: a map `X ⟶ W` is the same as - a cocone on `F` with cone point `W`. -/ -def homIso (h : IsColimit t) (W : C) : - ULift.{u₁} (t.pt ⟶ W : Type v₃) ≅ (F ⟶ (const J).obj W) := - Equiv.toIso (Equiv.ulift.trans h.homEquiv) @[simp] theorem homIso_hom (h : IsColimit t) {W : C} : @@ -921,28 +690,6 @@ def homIso' (h : IsColimit t) (W : C) : { app := fun j => p.1 j naturality := fun j j' f => by dsimp; rw [comp_id]; exact p.2 f } } -set_option backward.isDefEq.respectTransparency false in -/-- If G : C → D is a faithful functor which sends t to a colimit cocone, - then it suffices to check that the induced maps for the image of t - can be lifted to maps of C. -/ -def ofFaithful {t : Cocone F} {D : Type u₄} [Category.{v₄} D] (G : C ⥤ D) [G.Faithful] - (ht : IsColimit (mapCocone G t)) (desc : ∀ s : Cocone F, t.pt ⟶ s.pt) - (h : ∀ s, G.map (desc s) = ht.desc (mapCocone G s)) : IsColimit t := - { desc - fac := fun s j => by apply G.map_injective; rw [G.map_comp, h]; apply ht.fac - uniq := fun s m w => by - apply G.map_injective; rw [h] - refine ht.uniq (mapCocone G s) _ fun j => ?_ - convert! ← congrArg (fun f => G.map f) (w j) - apply G.map_comp } - -/-- If `F` and `G` are naturally isomorphic, then `F.mapCocone c` being a colimit implies -`G.mapCocone c` is also a colimit. --/ -def mapCoconeEquiv {D : Type u₄} [Category.{v₄} D] {K : J ⥤ C} {F G : C ⥤ D} (h : F ≅ G) - {c : Cocone K} (t : IsColimit (mapCocone F c)) : IsColimit (mapCocone G c) := by - apply IsColimit.ofIsoColimit _ (precomposeWhiskerLeftMapCocone h c) - apply (precomposeInvEquiv (isoWhiskerLeft K h :) _).symm t set_option backward.defeqAttrib.useBackward true in /-- A cocone is a colimit cocone exactly if diff --git a/Mathlib/CategoryTheory/Limits/MonoCoprod.lean b/Mathlib/CategoryTheory/Limits/MonoCoprod.lean index 3cf2f524ae1b5e..8f6fd6777fbe73 100644 --- a/Mathlib/CategoryTheory/Limits/MonoCoprod.lean +++ b/Mathlib/CategoryTheory/Limits/MonoCoprod.lean @@ -76,6 +76,7 @@ instance {A B : C} [MonoCoprod C] [HasBinaryCoproduct A B] : Mono (coprod.inl : instance {A B : C} [MonoCoprod C] [HasBinaryCoproduct A B] : Mono (coprod.inr : B ⟶ A ⨿ B) := binaryCofan_inr _ (colimit.isColimit _) +set_option backward.isDefEq.respectTransparency false in theorem mono_inl_iff {A B : C} {c₁ c₂ : BinaryCofan A B} (hc₁ : IsColimit c₁) (hc₂ : IsColimit c₂) : Mono c₁.inl ↔ Mono c₂.inl := by suffices diff --git a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean index 469c6f3a5e85bd..66f8eb57f06f89 100644 --- a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean @@ -121,7 +121,7 @@ lemma CostructuredArrow.isClosedUnderColimitsOfShape {J : Type*} [Category* J] isColimitOfPreserves _ d.isColimit have heq : Y.hom = hd.desc { pt := X, ι := { app j := (d.diag.obj j).hom } } := by refine hd.hom_ext fun j ↦ ?_ - simp only [Functor.const_obj_obj, IsColimit.fac] + simp only [IsColimit.fac] simp rw [P.costructuredArrowObj_iff, heq, ← hd.coconePointUniqueUpToIso_hom_desc (hc _), P.cancel_left_of_respectsIso] diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean index d9bbd2bac9030c..36706e0f7f9b90 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean @@ -778,7 +778,7 @@ lemma isIso_app_coconePt_of_preservesColimit (isColimitOfPreserves L hc) (isColimitOfPreserves L' hc) (asIso (whiskerLeft K α)) convert! (inferInstance : IsIso e.hom) apply (isColimitOfPreserves L hc).hom_ext fun j ↦ ?_ - simp only [Functor.comp_obj, Functor.mapCocone_pt, Functor.const_obj_obj, Functor.mapCocone_ι_app, + simp only [Functor.comp_obj, Functor.mapCocone_pt, Functor.mapCocone_ι_app, NatTrans.naturality, IsColimit.coconePointsIsoOfNatIso_hom, asIso_hom, e] refine (((isColimitOfPreserves L hc).ι_map (L'.mapCocone c) (whiskerLeft K α) j).trans ?_).symm simp diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean b/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean index 0c96c6d0d6de04..5dbce868ff5ce4 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean @@ -146,6 +146,7 @@ variable {c₁ : Cocone K₁} (hc₁ : IsColimit c₁) {c₃ : Cocone <| uncurry.obj (whiskeringLeft₂ C |>.obj K₁ |>.obj K₂ |>.obj G)} (hc₃ : IsColimit c₃) +set_option backward.isDefEq.respectTransparency false in /-- Characterize the inverse direction of the isomorphism `PreservesColimit₂.isoObjCoconePointsOfIsColimit` w.r.t. the canonical maps to the colimit. -/ @[reassoc (attr := simp)] @@ -231,10 +232,9 @@ instance of_preservesColimits_in_each_variable apply (P j₁).hom_ext intro j₂ haveI := (P j₁).fac s j₂ + simp only [Functor.mapCocone_pt, Functor.mapCocone_ι_app, Q₀, s] at this simp only [Functor.mapCocone_pt, - Functor.const_obj_obj, Functor.mapCocone_ι_app, Q₀, s] at this - simp only [Functor.mapCocone_pt, - Functor.const_obj_obj, Functor.mapCocone_ι_app, NatTrans.naturality, this, Q₀, s]) + Functor.mapCocone_ι_app, NatTrans.naturality, this, Q₀, s]) ⟨IsColimit.ofCoconeUncurry P <| IsColimit.precomposeHomEquiv E₀ _ <| IsColimit.ofIsoColimit (isColimitOfPreserves _ hc₁) E₁.symm⟩ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean b/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean index d81f695d3dd635..55a57cc5349fce 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean @@ -178,7 +178,7 @@ def isColimitCoconeOfFiberwiseCocone {c : Cocone (fiberwiseColimit G)} (hc : IsC desc s := hc.desc <| Cocone.mk s.pt <| { app := fun X => colimit.desc (Grothendieck.ι F X ⋙ G) (s.whisker _) } uniq s m hm := hc.hom_ext <| fun X => by - simp only [fiberwiseColimit_obj, Functor.const_obj_obj, IsColimit.fac] + simp only [fiberwiseColimit_obj, IsColimit.fac] simp only [coconeOfCoconeFiberwiseColimit_pt, Functor.const_obj_obj, coconeOfCoconeFiberwiseColimit_ι_app, Category.assoc] at hm ext d diff --git a/Mathlib/CategoryTheory/Limits/Types/Colimits.lean b/Mathlib/CategoryTheory/Limits/Types/Colimits.lean index 544a0ffbce3a6b..ae469221a059ea 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Colimits.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Colimits.lean @@ -227,7 +227,7 @@ theorem jointly_surjective_of_isColimit {F : J ⥤ Type u} {t : Cocone F} (h : I (↾fun y ↦ ULift.up (y ≠ x))) · refine h.hom_ext fun j ↦ ?_ ext y - simp only [Functor.const_obj_obj, TypeCat.Fun.toFun_apply, comp_apply, hom_ofHom, + simp only [TypeCat.Fun.toFun_apply, comp_apply, hom_ofHom, TypeCat.Fun.coe_mk, ne_eq, true_iff] exact hx j y · intro he diff --git a/Mathlib/CategoryTheory/Monad/Limits.lean b/Mathlib/CategoryTheory/Monad/Limits.lean index cb06848c5cea2d..e74d2fc24dc126 100644 --- a/Mathlib/CategoryTheory/Monad/Limits.lean +++ b/Mathlib/CategoryTheory/Monad/Limits.lean @@ -413,11 +413,11 @@ def coconePoint : Coalgebra T where A := c.pt a := t.desc (newCocone D c) counit := t.hom_ext fun j ↦ by - simp only [Functor.comp_obj, forget_obj, Functor.id_obj, Functor.const_obj_obj, + simp only [Functor.comp_obj, forget_obj, Functor.id_obj, IsColimit.fac_assoc, newCocone_ι_app, assoc, NatTrans.naturality, Functor.id_map, comp_id] rw [← Category.assoc, (D.obj j).counit, Category.id_comp] coassoc := t.hom_ext fun j ↦ by - simp only [Functor.comp_obj, forget_obj, Functor.const_obj_obj, IsColimit.fac_assoc, + simp only [Functor.comp_obj, forget_obj, IsColimit.fac_assoc, newCocone_ι_app, assoc, NatTrans.naturality, Functor.comp_map] rw [← Category.assoc, (D.obj j).coassoc, ← Functor.map_comp, t.fac (newCocone D c) j, newCocone_ι_app, Functor.map_comp, assoc] diff --git a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean index e23d976bc8ad8a..88affa6db43406 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean @@ -517,6 +517,7 @@ inductive colimitsOfShape : MorphismProperty C (h₁ : IsColimit c₁) (h₂ : IsColimit c₂) (f : X₁ ⟶ X₂) (_ : W.functorCategory J f) : colimitsOfShape (h₁.desc (Cocone.mk _ (f ≫ c₂.ι))) +set_option backward.isDefEq.respectTransparency false in variable {W J} in lemma colimitsOfShape.mk' (X₁ X₂ : J ⥤ C) (c₁ : Cocone X₁) (c₂ : Cocone X₂) (h₁ : IsColimit c₁) (h₂ : IsColimit c₂) (f : X₁ ⟶ X₂) (hf : W.functorCategory J f) @@ -599,6 +600,7 @@ class IsStableUnderColimitsOfShape : Prop where (h₁ : IsColimit c₁) (h₁ : IsColimit c₂) (f : X₁ ⟶ X₂) (_ : W.functorCategory J f) (φ : c₁.pt ⟶ c₂.pt) (hφ : ∀ j, c₁.ι.app j ≫ φ = f.app j ≫ c₂.ι.app j) : W φ +set_option backward.isDefEq.respectTransparency false in lemma isStableUnderColimitsOfShape_iff_colimitsOfShape_le : W.IsStableUnderColimitsOfShape J ↔ W.colimitsOfShape J ≤ W := by constructor @@ -668,6 +670,7 @@ lemma coproducts_of_small {X Y : C} (f : X ⟶ Y) {J : Type w'} rwa [← W.colimitsOfShape_eq_of_equivalence (Discrete.equivalence (equivShrink.{w} J))] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in lemma le_colimitsOfShape_punit : W ≤ W.colimitsOfShape (Discrete PUnit.{w + 1}) := by intro X₁ X₂ f hf have h := initialIsInitial (C := Discrete (PUnit.{w + 1})) diff --git a/Mathlib/CategoryTheory/Presentable/ColimitPresentation.lean b/Mathlib/CategoryTheory/Presentable/ColimitPresentation.lean index 3ff5e8e417ea26..cb0d056b5e23e0 100644 --- a/Mathlib/CategoryTheory/Presentable/ColimitPresentation.lean +++ b/Mathlib/CategoryTheory/Presentable/ColimitPresentation.lean @@ -151,7 +151,7 @@ def bind {X : C} (P : ColimitPresentation J X) (Q : ∀ j, ColimitPresentation ( isColimit.fac := fun c ⟨j, i⟩ ↦ by simp [P.isColimit.fac, (Q j).isColimit.fac] isColimit.uniq c m hm := by refine P.isColimit.hom_ext fun j ↦ ?_ - simp only [Functor.const_obj_obj, P.isColimit.fac] + simp only [P.isColimit.fac] refine (Q j).isColimit.hom_ext fun i ↦ ?_ simpa [(Q j).isColimit.fac] using hm (.mk _ j i) diff --git a/Mathlib/Condensed/Discrete/Colimit.lean b/Mathlib/Condensed/Discrete/Colimit.lean index 3644a930d60a4c..789a1ec6e5c50d 100644 --- a/Mathlib/Condensed/Discrete/Colimit.lean +++ b/Mathlib/Condensed/Discrete/Colimit.lean @@ -62,6 +62,7 @@ noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi dsimp rwa [dsimp% c.w, dsimp% c.w] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi (c.π.app i)] (s : Cocone ((F ⋙ toProfinite).op ⋙ locallyConstantPresheaf X)) @@ -349,6 +350,7 @@ noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi dsimp rwa [dsimp% c.w, dsimp% c.w] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi (c.π.app i)] (s : Cocone ((F ⋙ toLightProfinite).op ⋙ locallyConstantPresheaf X)) @@ -366,6 +368,7 @@ noncomputable def isColimitLocallyConstantPresheafDiagram (S : LightProfinite) : (Functor.Final.isColimitWhiskerEquiv (opOpEquivalence ℕ).inverse _).symm (isColimitLocallyConstantPresheaf _ _ S.asLimit) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma isColimitLocallyConstantPresheafDiagram_desc_apply (S : LightProfinite) (s : Cocone (S.diagram.rightOp ⋙ locallyConstantPresheaf X)) From eac05c611ebca3eca12571cba5d29b7c32049208 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 23 Jun 2026 12:20:11 +0000 Subject: [PATCH 0287/1300] feat(Combinatorics/SimpleGraph/Finite): some `minDegree`/`maxDegree` lemmas (#40622) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `G.minDegree = 0 ∧ G.maxDegree = 0` given `Subsingleton V` (we have these for `IsEmpty V`) - `G.maxDegree = 0 ↔ G = ⊥` - `G.minDegree = 0 ↔ ∃ v, G.IsIsolated v` - `G.minDegree = 0 ↔ G.support ≠ .univ` - For a set `s` that contains the support we have - `G.minDegree ≤ (G.induce s).minDegree` - `(G.induce s).maxDegree = G.maxDegree` --- Mathlib/Combinatorics/SimpleGraph/Copy.lean | 12 +++- Mathlib/Combinatorics/SimpleGraph/Finite.lean | 56 +++++++++++++++---- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Copy.lean b/Mathlib/Combinatorics/SimpleGraph/Copy.lean index 3bc1aeb011955b..79ec4ae0442ef6 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Copy.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Copy.lean @@ -341,7 +341,8 @@ lemma maxDegree_mono {H : SimpleGraph V} [Fintype V] [DecidableRel G.Adj] [Decid theorem Copy.minDegree_mono [Fintype V] [Fintype W] [DecidableRel G.Adj] [DecidableRel H.Adj] {f : Copy G H} (hf : Function.Surjective f) : G.minDegree ≤ H.minDegree := by cases isEmpty_or_nonempty W - · simp [Function.isEmpty f] + · have := Function.isEmpty f + simp refine H.le_minDegree_of_forall_le_degree _ fun w ↦ ?_ obtain ⟨v, rfl⟩ := hf w grw [← f.degree_le, ← minDegree_le_degree] @@ -354,6 +355,15 @@ theorem Hom.minDegree_mono [Fintype V] [Fintype W] [DecidableRel G.Adj] [Decidab @[deprecated (since := "2026-05-20")] alias Hom.minDegree_le := Hom.minDegree_mono +theorem maxDegree_induce_of_support_subset [Fintype V] [DecidableRel G.Adj] {s : Set V} + [DecidablePred (· ∈ s)] (h : G.support ⊆ s) : (G.induce s).maxDegree = G.maxDegree := by + apply le_antisymm <| Copy.maxDegree_mono <| Embedding.induce s |>.toCopy + refine G.maxDegree_le_of_forall_degree_le _ fun v ↦ ?_ + by_cases hv : G.IsIsolated v + · simp [hv] + grw [← degree_le_maxDegree _ ⟨v, h <| G.mem_support_iff_not_isIsolated.mpr hv⟩, + degree_induce_of_neighborSet_subset <| G.neighborSet_subset_support v |>.trans h] + end IsContained section Free diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index c5f2e356c5f83c..a3f9f29851e7b6 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -385,10 +385,8 @@ theorem exists_minimal_degree_vertex [DecidableRel G.Adj] [Nonempty V] : grind [minDegree, WithTop.untopD_coe, min_mem_image_coe <| univ_nonempty.image (G.degree ·)] /-- The minimum degree in the graph is at most the degree of any particular vertex. -/ -theorem minDegree_le_degree [DecidableRel G.Adj] (v : V) : G.minDegree ≤ G.degree v := by - obtain ⟨t, ht⟩ := Finset.min_of_mem (mem_image_of_mem (fun v => G.degree v) (mem_univ v)) - have := Finset.min_le_of_eq (mem_image_of_mem _ (mem_univ v)) ht - rwa [minDegree, ht] +theorem minDegree_le_degree [DecidableRel G.Adj] (v : V) : G.minDegree ≤ G.degree v := + WithTop.untopD_le <| Finset.min_le <| mem_image_of_mem (G.degree ·) <| mem_univ v /-- In a nonempty graph, if `k` is at most the degree of every vertex, it is at most the minimum degree. Note the assumption that the graph is nonempty is necessary as long as `G.minDegree` is @@ -399,14 +397,16 @@ theorem le_minDegree_of_forall_le_degree [DecidableRel G.Adj] [Nonempty V] (k : rw [hv] apply h -/-- If there are no vertices then the `minDegree` is zero. -/ @[simp] -lemma minDegree_of_isEmpty [DecidableRel G.Adj] [IsEmpty V] : G.minDegree = 0 := by - rw [minDegree, WithTop.untopD_eq_self_iff] - simp +lemma minDegree_of_subsingleton [DecidableRel G.Adj] [Subsingleton V] : G.minDegree = 0 := by + cases isEmpty_or_nonempty V <;> + simp [minDegree, Finset.image_const] + +@[deprecated (since := "2026-06-15")] alias minDegree_of_isEmpty := minDegree_of_subsingleton variable {G} in /-- If `G` is a subgraph of `H` then `G.minDegree ≤ H.minDegree`. -/ +@[gcongr] lemma minDegree_le_minDegree {H : SimpleGraph V} [DecidableRel G.Adj] [DecidableRel H.Adj] (hle : G ≤ H) : G.minDegree ≤ H.minDegree := by cases isEmpty_or_nonempty V @@ -438,8 +438,11 @@ theorem degree_le_maxDegree [DecidableRel G.Adj] (v : V) : G.degree v ≤ G.maxD WithBot.le_unbotD <| Finset.le_max <| mem_image_of_mem (G.degree ·) <| mem_univ v @[simp] -lemma maxDegree_of_isEmpty [DecidableRel G.Adj] [IsEmpty V] : G.maxDegree = 0 := by - rw [maxDegree, univ_eq_empty, image_empty, max_empty, WithBot.unbotD_bot] +lemma maxDegree_of_subsingleton [DecidableRel G.Adj] [Subsingleton V] : G.maxDegree = 0 := by + cases isEmpty_or_nonempty V <;> + simp [maxDegree, Finset.image_const] + +@[deprecated (since := "2026-06-15")] alias maxDegree_of_isEmpty := maxDegree_of_subsingleton /-- In a graph, if `k` is at least the degree of every vertex, then it is at least the maximum degree. -/ @@ -458,6 +461,16 @@ theorem IsRegularOfDegree.maxDegree_eq [Nonempty V] [DecidableRel G.Adj] {d : lemma maxDegree_bot_eq_zero : (⊥ : SimpleGraph V).maxDegree = 0 := Nat.le_zero.1 <| maxDegree_le_of_forall_degree_le _ _ (by simp) +variable {G} in +@[simp] +theorem maxDegree_eq_zero_iff [DecidableRel G.Adj] : G.maxDegree = 0 ↔ G = ⊥ := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · rw [eq_bot_iff_isIsolated] + intro v + grind [degree_eq_zero, G.degree_le_maxDegree v] + · convert maxDegree_bot_eq_zero + assumption + @[simp] lemma maxDegree_top [DecidableEq V] : (⊤ : SimpleGraph V).maxDegree = Fintype.card V - 1 := by cases isEmpty_or_nonempty V @@ -478,6 +491,18 @@ theorem IsRegularOfDegree.minDegree_eq [Nonempty V] [DecidableRel G.Adj] {d : lemma minDegree_bot_eq_zero : (⊥ : SimpleGraph V).minDegree = 0 := Nat.le_zero.1 <| (minDegree_le_maxDegree _).trans (by simp) +variable {G} in +theorem minDegree_eq_zero_iff [DecidableRel G.Adj] [Nonempty V] : + G.minDegree = 0 ↔ ∃ v, G.IsIsolated v := by + refine ⟨fun h ↦ ?_, fun ⟨v, hv⟩ ↦ ?_⟩ + · grind [G.exists_minimal_degree_vertex, degree_eq_zero] + · grind [G.minDegree_le_degree v, degree_eq_zero] + +variable {G} in +theorem minDegree_eq_zero_iff_support_ne [DecidableRel G.Adj] [Nonempty V] : + G.minDegree = 0 ↔ G.support ≠ .univ := by + simp [Set.ne_univ_iff_exists_notMem, minDegree_eq_zero_iff] + @[simp] lemma minDegree_top [DecidableEq V] : (⊤ : SimpleGraph V).minDegree = Fintype.card V - 1 := by cases isEmpty_or_nonempty V @@ -613,6 +638,17 @@ theorem degree_induce_support (v : G.support) : (G.induce G.support).degree v = G.degree v := degree_induce_of_support_subset subset_rfl v +theorem le_minDegree_induce_of_support_subset (h : G.support ⊆ s) : + G.minDegree ≤ (G.induce s).minDegree := by + cases isEmpty_or_nonempty V + · simp + rcases s.eq_empty_or_nonempty with (rfl | hs) + · simp [minDegree_eq_zero_iff_support_ne, Set.subset_empty_iff.mp h, Set.empty_ne_univ] + have := hs.to_subtype + refine le_minDegree_of_forall_le_degree _ _ fun v ↦ ?_ + grw [G.minDegree_le_degree v, degree_induce_of_neighborSet_subset] + grw [neighborSet_subset_support, h] + end Support section Map From 7ff2d88e920dfd955813615527b82ed3b8f45550 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 23 Jun 2026 12:44:44 +0000 Subject: [PATCH 0288/1300] feat(RingTheory/Ideal/Defs): add `Ideal.coe_mem_inertia` (#40383) This PR adds a lemma `coe_mem_inertia` for the situation when a coercion from a subgroup lies in an inertia subgroup. I added both an `AddSubgroup` version and an `Ideal` version to allow for better rewriting. Co-authored-by: tb65536 --- Mathlib/Algebra/Group/Subgroup/Basic.lean | 28 +++++++++++++++-------- Mathlib/RingTheory/Ideal/Defs.lean | 17 ++++++++++---- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 0a94a12c97fafa..0799e6710ca3cd 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -1088,26 +1088,34 @@ def noncenter (G : Type*) [Monoid G] : Set (ConjClasses G) := end ConjClasses +namespace AddSubgroup + +variable {M : Type*} [AddGroup M] (I : AddSubgroup M) (G : Type*) + [Group G] [MulAction G M] + /-- Suppose `G` acts on `M` and `I` is a subgroup of `M`. The inertia subgroup of `I` is the subgroup of `G` whose action is trivial mod `I`. -/ -def AddSubgroup.inertia {M : Type*} [AddGroup M] (I : AddSubgroup M) (G : Type*) - [Group G] [MulAction G M] : Subgroup G where +def inertia : Subgroup G where carrier := { σ | ∀ x, σ • x - x ∈ I } mul_mem' {a b} ha hb x := by simpa [mul_smul] using add_mem (ha (b • x)) (hb x) one_mem' := by simp [zero_mem] inv_mem' {a} ha x := by simpa using sub_mem_comm_iff.mp (ha (a⁻¹ • x)) -@[simp] lemma AddSubgroup.mem_inertia {M : Type*} [AddGroup M] {I : AddSubgroup M} {G : Type*} - [Group G] [MulAction G M] {σ : G} : σ ∈ I.inertia G ↔ ∀ x, σ • x - x ∈ I := .rfl +variable {I G} in +@[simp] +lemma mem_inertia {σ : G} : σ ∈ I.inertia G ↔ ∀ x, σ • x - x ∈ I := .rfl +variable {G} in @[simp] -lemma AddSubgroup.subgroupOf_inertia {M : Type*} [AddGroup M] (I : AddSubgroup M) - {G : Type*} [Group G] [MulAction G M] (H : Subgroup G) : - (I.inertia G).subgroupOf H = I.inertia H := +lemma subgroupOf_inertia (H : Subgroup G) : (I.inertia G).subgroupOf H = I.inertia H := rfl +variable {I G} in +lemma coe_mem_inertia {H : Subgroup G} {σ : H} : ↑σ ∈ I.inertia G ↔ σ ∈ I.inertia H := .rfl + +variable {G} in @[simp] -lemma AddSubgroup.inertia_map_subtype {M : Type*} [AddGroup M] (I : AddSubgroup M) - {G : Type*} [Group G] [MulAction G M] (H : Subgroup G) : - (I.inertia H).map H.subtype = I.inertia G ⊓ H := by +lemma inertia_map_subtype (H : Subgroup G) : (I.inertia H).map H.subtype = I.inertia G ⊓ H := by rw [← AddSubgroup.subgroupOf_inertia, Subgroup.subgroupOf_map_subtype] + +end AddSubgroup diff --git a/Mathlib/RingTheory/Ideal/Defs.lean b/Mathlib/RingTheory/Ideal/Defs.lean index f8a8c64474e4b2..aee2dc55cc58e9 100644 --- a/Mathlib/RingTheory/Ideal/Defs.lean +++ b/Mathlib/RingTheory/Ideal/Defs.lean @@ -146,11 +146,18 @@ theorem mul_sub_mul_mem [I.IsTwoSided] rw [show a * c - b * d = (a - b) * c + b * (c - d) by rw [sub_mul, mul_sub]; abel] exact I.add_mem (I.mul_mem_right _ h1) (I.mul_mem_left _ h2) -/-- -The subgroup of elements `g` of `G` such that `∀ x, g • x - x ∈ I`. --/ -abbrev inertia (G : Type*) [Group G] [MulAction G α] (I : Ideal α) : - Subgroup G := AddSubgroup.inertia I.toAddSubgroup G +section inertia + +variable (G : Type*) [Group G] [MulAction G α] (I : Ideal α) + +/-- The subgroup of elements `g` of `G` such that `∀ x, g • x - x ∈ I`. -/ +abbrev inertia : Subgroup G := I.toAddSubgroup.inertia G + +variable {I G} in +theorem coe_mem_inertia {H : Subgroup G} {σ : H} : ↑σ ∈ I.inertia G ↔ σ ∈ I.inertia H := + I.toAddSubgroup.coe_mem_inertia + +end inertia end Ideal From d5c56094122b41159528a7eea1d85ab706849369 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 23 Jun 2026 14:13:40 +0000 Subject: [PATCH 0289/1300] chore(FieldTheory/IsGaloisGroup): split file by imports (#40942) This PR splits off the ring-theoretic part of `FieldTheory/IsGaloisGroup.lean` to the `RingTheory` folder. Co-authored-by: tb65536 --- Mathlib.lean | 2 + Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 321 +----------------- Mathlib/RingTheory/IsGaloisGroup/Basic.lean | 251 ++++++++++++++ Mathlib/RingTheory/IsGaloisGroup/Defs.lean | 155 +++++++++ 4 files changed, 413 insertions(+), 316 deletions(-) create mode 100644 Mathlib/RingTheory/IsGaloisGroup/Basic.lean create mode 100644 Mathlib/RingTheory/IsGaloisGroup/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index d9fda0a91062b6..f0735f278b484c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6676,6 +6676,8 @@ public import Mathlib.RingTheory.Invariant.Defs public import Mathlib.RingTheory.Invariant.Galois public import Mathlib.RingTheory.Invariant.Profinite public import Mathlib.RingTheory.IsAdjoinRoot +public import Mathlib.RingTheory.IsGaloisGroup.Basic +public import Mathlib.RingTheory.IsGaloisGroup.Defs public import Mathlib.RingTheory.IsPrimary public import Mathlib.RingTheory.IsTensorProduct public import Mathlib.RingTheory.Jacobson.Artinian diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 2fcbbed0106e1f..431a89fbdd99a2 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -7,14 +7,14 @@ module public import Mathlib.FieldTheory.Galois.Infinite public import Mathlib.NumberTheory.NumberField.Basic -public import Mathlib.RingTheory.Invariant.Basic +public import Mathlib.RingTheory.IsGaloisGroup.Basic /-! -# Predicate for Galois Groups +# Galois Groups of Fields -Given an action of a group `G` on an extension of fields `L/K`, we introduce a predicate -`IsGaloisGroup G K L` saying that `G` acts faithfully on `L` with fixed field `K`. In particular, -we do not assume that `L` is an algebraic extension of `K`. +Given an action of a group `G` on an extension of fields `L/K`, the predicate `IsGaloisGroup G K L` +states that `G` acts faithfully on `L` with fixed field `K`. In particular, we do not assume that +`L` is an algebraic extension of `K`. ## Implementation notes @@ -40,218 +40,8 @@ extensions of rings `B/A` seems to outweigh these terminological issues. open Module -section CommRing - -variable (G A A' B : Type*) [Group G] [CommSemiring A] [Semiring B] [Algebra A B] - [MulSemiringAction G B] - -/-- `G` is a Galois group for `L/K` if the action of `G` on `L` is faithful with fixed field `K`. -In particular, we do not assume that `L` is an algebraic extension of `K`. - -See the implementation notes in this file for the meaning of this definition in the case of rings. --/ -class IsGaloisGroup where - faithful : FaithfulSMul G B - commutes : SMulCommClass G A B - isInvariant : Algebra.IsInvariant A B G - -variable {G A B} in -theorem IsGaloisGroup.of_mulEquiv [hG : IsGaloisGroup G A B] {H : Type*} [Group H] - [MulSemiringAction H B] (e : H ≃* G) (he : ∀ h (x : B), (e h) • x = h • x) : - IsGaloisGroup H A B where - faithful := ⟨fun h ↦ e.injective <| hG.faithful.eq_of_smul_eq_smul <| by simpa only [he]⟩ - commutes := ⟨fun x a b ↦ by simpa [he] using hG.commutes.smul_comm (e x) a b⟩ - isInvariant := ⟨fun b h ↦ - have he' : ∀ (g : G) (x : B), e.symm g • x = g • x := fun g x ↦ by simp [← he] - hG.isInvariant.isInvariant b (fun g ↦ by simpa [he'] using h (e.symm g))⟩ - -variable {G A B} in -theorem IsGaloisGroup.iff_of_mulEquiv {H : Type*} [Group H] [MulSemiringAction H B] - (e : H ≃* G) (he : ∀ h (x : B), e h • x = h • x) : - IsGaloisGroup H A B ↔ IsGaloisGroup G A B := by - refine ⟨fun h ↦ h.of_mulEquiv e.symm fun g x ↦ ?_, fun h ↦ h.of_mulEquiv e he⟩ - rw [← he, e.apply_symm_apply] - -variable {G A B} in -@[simp] -theorem IsGaloisGroup.top_iff : IsGaloisGroup (⊤ : Subgroup G) A B ↔ IsGaloisGroup G A B := - iff_of_mulEquiv Subgroup.topEquiv fun _ _ ↦ rfl - -instance [IsGaloisGroup G A B] : IsGaloisGroup (⊤ : Subgroup G) A B := - IsGaloisGroup.top_iff.mpr ‹_› - -theorem IsGaloisGroup.of_algEquiv [hG : IsGaloisGroup G A B] (B' : Type*) [Semiring B'] - [Algebra A B'] [MulSemiringAction G B'] (e : B ≃ₐ[A] B') - (he : ∀ (g : G) (x : B), e (g • x) = g • (e x)) : - IsGaloisGroup G A B' where - faithful := ⟨fun h ↦ hG.faithful.eq_of_smul_eq_smul fun b ↦ by simpa [← he] using h (e b)⟩ - commutes := ⟨fun g a b' ↦ by - have h' {x'} : e.symm (g • x') = g • e.symm x' := by - apply e.injective - simp [he] - apply e.symm.injective - simpa [h', map_smul] using hG.commutes.smul_comm g a (e.symm b')⟩ - isInvariant := ⟨fun x' hx' ↦ by - obtain ⟨a, ha⟩ := hG.isInvariant.isInvariant (e.symm x') (fun g ↦ by - apply e.injective - simp [he, hx']) - exact ⟨a, by rw [← e.commutes, ha, AlgEquiv.apply_symm_apply]⟩⟩ - -theorem IsGaloisGroup.of_ringHom_surjective [hG : IsGaloisGroup G A B] [CommSemiring A'] - [Algebra A' B] (e : A →+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) - (he' : Function.Surjective e) : IsGaloisGroup G A' B where - faithful := hG.faithful - commutes := ⟨by - intro g a' b - obtain ⟨a, rfl⟩ : ∃ a, e a = a' := he' a' - rw [Algebra.smul_def, Algebra.smul_def, he, ← Algebra.smul_def, ← Algebra.smul_def] - exact hG.commutes.smul_comm g a b⟩ - isInvariant := ⟨by - intro b h - obtain ⟨a, ha⟩ := hG.isInvariant.isInvariant b h - exact ⟨e a, by rw [he, ha]⟩⟩ - -theorem IsGaloisGroup.of_ringEquiv [hG : IsGaloisGroup G A B] [CommSemiring A'] [Algebra A' B] - (e : A ≃+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) : - IsGaloisGroup G A' B := - .of_ringHom_surjective G A A' B e he e.surjective - -attribute [instance low] IsGaloisGroup.commutes IsGaloisGroup.isInvariant - -variable {C : Type*} [CommSemiring C] [Algebra C B] - -variable {G} in -protected theorem Subgroup.smul_algebraMap {H : Subgroup G} [SMulCommClass H C B] {g : G} - (hg : g ∈ H) (x : C) : - g • algebraMap C B x = algebraMap C B x := - smul_algebraMap (⟨g, hg⟩ : H) x - -theorem IsGaloisGroup.smul_mem_of_normal (N : Subgroup G) [hN : N.Normal] - [hC : IsGaloisGroup N C B] (g : G) (x : C) : - g • algebraMap C B x ∈ Set.range (algebraMap C B) := by - apply hC.isInvariant.isInvariant (g • algebraMap C B x) - intro n - rw [← inv_smul_eq_iff, Subgroup.smul_def, ← mul_smul, ← mul_smul] - exact Subgroup.smul_algebraMap B (hN.conj_mem' n n.prop g) x - -@[deprecated (since := "2026-05-28")] alias smul_eq_self := Subgroup.smul_algebraMap -@[deprecated (since := "2026-05-28")] alias smul_mem_of_normal := IsGaloisGroup.smul_mem_of_normal - -variable [hA : IsGaloisGroup G A B] [FaithfulSMul A B] - -/-- -If `B/A` is Galois with Galois group `G`, then `A` is isomorphic to the subring of elements of `B` -fixed by `G`. --/ -@[simps apply_coe] -noncomputable def IsGaloisGroup.ringEquivFixedPoints : - A ≃+* FixedPoints.subsemiring B G where - toFun x := ⟨algebraMap A B x, fun _ ↦ by rw [smul_algebraMap]⟩ - invFun x := (hA.isInvariant.isInvariant x x.prop).choose - map_mul' _ _ := by simp [Subtype.ext_iff] - map_add' _ _ := by simp [Subtype.ext_iff] - left_inv _ := by simp - right_inv x := by simpa [Subtype.ext_iff] using (hA.isInvariant.isInvariant x x.prop).choose_spec - -@[simp] -theorem IsGaloisGroup.algebraMap_ringEquivFixedPoints_symm_apply (x : FixedPoints.subsemiring B G) : - algebraMap A B ((ringEquivFixedPoints G A B).symm x) = x := - (hA.isInvariant.isInvariant x x.prop).choose_spec - -variable [CommSemiring A'] [Algebra A' B] [FaithfulSMul A' B] [hA' : IsGaloisGroup G A' B] - -/-- -If `B/A` and `B/A'` are Galois with the same Galois group, then `A ≃+* A'`. --/ -noncomputable def IsGaloisGroup.ringEquiv : - A ≃+* A' := - (ringEquivFixedPoints G A B).trans (ringEquivFixedPoints G A' B).symm - -@[simp] -theorem IsGaloisGroup.algebraMap_ringEquiv_apply (x : A) : - algebraMap A' B (IsGaloisGroup.ringEquiv G A A' B x) = algebraMap A B x := by - simp [ringEquiv] - -@[simp] -theorem IsGaloisGroup.algebraMap_ringEquiv_symm_apply (x : A') : - algebraMap A B ((IsGaloisGroup.ringEquiv G A A' B).symm x) = algebraMap A' B x := by - simp [ringEquiv] - -end CommRing - section Field -variable (G A B K L : Type*) [Group G] [CommRing A] [CommRing B] [MulSemiringAction G B] - [Algebra A B] [Field K] [Field L] [Algebra K L] [Algebra A K] [Algebra B L] [Algebra A L] - [IsFractionRing A K] [IsFractionRing B L] [IsScalarTower A K L] [IsScalarTower A B L] - [MulSemiringAction G L] [SMulDistribClass G B L] - -instance [IsGaloisGroup G A B] : IsGaloisGroup G (algebraMap A B).range B where - faithful := IsGaloisGroup.faithful A - commutes := ⟨fun g ⟨a', ⟨a, ha⟩⟩ b ↦ by simp [Subring.smul_def, ← ha]⟩ - isInvariant := ⟨fun b hb ↦ by - obtain ⟨a, ha⟩ := Algebra.IsInvariant.isInvariant (A := A) b hb - exact ⟨⟨algebraMap A B a, ⟨a, rfl⟩⟩, ha⟩⟩ - -/-- `IsGaloisGroup` for rings implies `IsGaloisGroup` for their fraction fields. -/ -theorem IsGaloisGroup.to_isFractionRing_of_isIntegral - [Algebra.IsIntegral A B] [hGAB : IsGaloisGroup G A B] : - IsGaloisGroup G K L where - faithful := - have := hGAB.faithful - IsFractionRing.faithfulSMul G B L - commutes := IsFractionRing.smulCommClass G A B K L - isInvariant := IsFractionRing.isInvariant_of_isIntegral G A B K L - -/-- `IsGaloisGroup` for rings implies `IsGaloisGroup` for their fraction fields. -/ -theorem IsGaloisGroup.to_isFractionRing [Finite G] [hGAB : IsGaloisGroup G A B] : - IsGaloisGroup G K L := - have := hGAB.isInvariant.isIntegral - IsGaloisGroup.to_isFractionRing_of_isIntegral G A B K L - -/-- If `B` is an integral extension of an integrally closed domain `A`, then `IsGaloisGroup` for -their fraction fields implies `IsGaloisGroup` for these rings. -/ -theorem IsGaloisGroup.of_isFractionRing [hGKL : IsGaloisGroup G K L] - [IsIntegrallyClosed A] [Algebra.IsIntegral A B] : IsGaloisGroup G A B := by - have hc (a : A) : (algebraMap K L) (algebraMap A K a) = (algebraMap B L) (algebraMap A B a) := by - simp_rw [← IsScalarTower.algebraMap_apply] - refine ⟨⟨fun h ↦ ?_⟩, ⟨fun g x y ↦ IsFractionRing.injective B L ?_⟩, ⟨fun x h ↦ ?_⟩⟩ - · have := hGKL.faithful - refine eq_of_smul_eq_smul fun (y : L) ↦ ?_ - obtain ⟨a, b, hb, rfl⟩ := IsFractionRing.div_surjective B y - simp only [smul_div₀', ← algebraMap.coe_smul', h] - · simp [Algebra.smul_def, algebraMap.coe_smul', ← hc] - · obtain ⟨b, hb⟩ := hGKL.isInvariant.isInvariant (algebraMap B L x) - (by simpa [← algebraMap.coe_smul']) - have hx : IsIntegral A (algebraMap B L x) := (Algebra.IsIntegral.isIntegral x).algebraMap - rw [← hb, isIntegral_algebraMap_iff (algebraMap K L).injective, - IsIntegrallyClosedIn.isIntegral_iff] at hx - obtain ⟨a, rfl⟩ := hx - exact ⟨a, by rwa [hc, IsFractionRing.coe_inj] at hb⟩ - -/-- If `G` is finite and `A` is integrally closed then `IsGaloisGroup G A B` is equivalent to `B/A` -being integral and the fields of fractions `Frac(B)/Frac(A)` being Galois with Galois group `G`. -/ -theorem IsGaloisGroup.iff_isFractionRing [Finite G] [IsIntegrallyClosed A] : - IsGaloisGroup G A B ↔ Algebra.IsIntegral A B ∧ IsGaloisGroup G K L := - ⟨fun h ↦ ⟨h.isInvariant.isIntegral, h.to_isFractionRing G A B K L⟩, - fun ⟨_, h⟩ ↦ h.of_isFractionRing G A B K L⟩ - -@[deprecated (since := "2026-04-20")] alias FractionRing.mulSemiringAction_of_isGaloisGroup := - IsFractionRing.mulSemiringAction - -/-- -If `G` is finite and `IsGaloisGroup G A B` with `A` and `B` domains, then `G` is also -a Galois group for `FractionRing B / FractionRing A` for the action defined by -`IsFractionRing.mulSemiringAction`. --/ -instance IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [IsTorsionFree A B] [Finite G] - [IsGaloisGroup G A B] [Algebra (FractionRing A) (FractionRing B)] - [IsScalarTower A (FractionRing A) (FractionRing B)] : - letI := IsFractionRing.mulSemiringAction G B (FractionRing B) - IsGaloisGroup G (FractionRing A) (FractionRing B) := by - let := IsFractionRing.mulSemiringAction G B (FractionRing B) - apply IsGaloisGroup.to_isFractionRing G A B _ _ - open NumberField instance (K L : Type*) [Field K] [Field L] [NumberField K] [NumberField L] [Algebra K L] @@ -383,13 +173,6 @@ end IsDomain variable (H H' : Subgroup G) (F F' : IntermediateField K L) -instance (R S : Type*) [CommRing R] [CommRing S] [Algebra R S] - [MulSemiringAction G S] [hGKL : IsGaloisGroup G R S] : - IsGaloisGroup H (FixedPoints.subalgebra R S H) S where - faithful := have := hGKL.faithful; inferInstance - commutes := inferInstance - isInvariant := ⟨fun x h ↦ ⟨⟨x, h⟩, rfl⟩⟩ - instance subgroup [hGKL : IsGaloisGroup G K L] : IsGaloisGroup H (FixedPoints.intermediateField H : IntermediateField K L) L := inferInstanceAs (IsGaloisGroup H (FixedPoints.subalgebra K L H) L) @@ -602,90 +385,6 @@ end GaloisCorrespondence section Quotient -section Semiring - -variable (A B C : Type*) [CommSemiring A] [Semiring C] [Algebra A C] [MulSemiringAction G C] -variable (N : Subgroup G) [CommSemiring B] [Algebra B C] - -/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then `G` acts on `B`. -For `g : G` and `x : B`, `g • x` is the unique element of `B` whose image in `C` is -`g • algebraMap B C x`, see `algebraMap_smulOfNormal`. -/ -@[implicit_reducible] -noncomputable def smulOfNormal [N.Normal] [IsGaloisGroup N B C] : SMul G B where - smul g x := (smul_mem_of_normal G C N g x).choose - -@[simp] -theorem algebraMap_smulOfNormal [N.Normal] [IsGaloisGroup N B C] (g : G) (x : B) : - letI := smulOfNormal G B C - algebraMap B C (g • x) = g • algebraMap B C x := - (smul_mem_of_normal G C N g x).choose_spec - -/-- If `N` is normal and `IsGaloisGroup N B C`, the action `smulOfNormal G B C` satisfies -`SMulDistribClass G B C`. -/ -instance smulDistribClass_smulOfNormal [N.Normal] [IsGaloisGroup N B C] : - letI := smulOfNormal G B C - SMulDistribClass G B C := - let := smulOfNormal G B C - ⟨fun g b c ↦ by simp [Algebra.smul_def]⟩ - -variable [FaithfulSMul B C] - -/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then `G` acts on `B` as a -`MulSemiringAction`, via the action defined in `smulOfNormal`. -/ -@[implicit_reducible] -noncomputable def mulSemiringActionOfNormal [IsGaloisGroup N B C] [N.Normal] : - MulSemiringAction G B := by - let : SMul G B := smulOfNormal G B C N - have : SMulDistribClass G B C := smulDistribClass_smulOfNormal G B C N - exact mulSemiringActionOfSmulDistribClass B C G - -/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then the quotient group `G ⧸ N` -acts on `B` by `(g : G ⧸ N) • x = g • x`. -/ -@[implicit_reducible] -noncomputable def mulSemiringActionQuotient [IsGaloisGroup N B C] [N.Normal] : - MulSemiringAction (G ⧸ N) B := - letI := mulSemiringActionOfNormal G B C N - { smul q x := - Quotient.liftOn' q (· • x) fun g₁ g₂ h ↦ by - apply FaithfulSMul.algebraMap_injective B C - rw [algebraMap.smul', algebraMap.smul', smul_eq_iff_eq_inv_smul, ← smul_assoc, smul_eq_mul, - Subgroup.smul_algebraMap C (by rwa [← QuotientGroup.leftRel_apply])] - one_smul x := one_smul G x - mul_smul q₁ q₂ x := Quotient.inductionOn₂' q₁ q₂ fun g h ↦ mul_smul g h x - smul_add q x y := Quotient.inductionOn' q fun g ↦ smul_add g x y - smul_zero q := Quotient.inductionOn' q fun g ↦ smul_zero g - smul_one q := Quotient.inductionOn' q fun g ↦ smul_one g - smul_mul q x y := Quotient.inductionOn' q fun g ↦ smul_mul' g x y } - -theorem mulSemiringActionQuotient_smul_def [MulSemiringAction G B] [SMulDistribClass G B C] - [IsGaloisGroup N B C] [N.Normal] (g : G) (b : B) : - letI := mulSemiringActionQuotient G B C N - (g : G ⧸ N) • b = g • b := by - let := mulSemiringActionOfNormal G B C N - refine (Quotient.liftOn'_mk'' (· • b) _ g).trans (FaithfulSMul.algebraMap_injective B C ?_) - rw [algebraMap.smul', algebraMap.smul'] - -instance isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C] - [IsGaloisGroup N B C] [N.Normal] : - letI := mulSemiringActionQuotient G B C N - IsScalarTower G (G ⧸ N) B := - let := mulSemiringActionQuotient G B C N - ⟨fun g q b ↦ Quotient.inductionOn' q fun h ↦ by - simp [mul_smul, mulSemiringActionQuotient_smul_def]⟩ - -set_option linter.defProp false in -/-- If `G` acts on `C` commuting with `A`, then the action of `G ⧸ N` on `B` commutes with `A`. -/ -@[implicit_reducible] -def smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCommClass G A C] - [MulSemiringAction G B] [MulAction (G ⧸ N) B] [SMulDistribClass G B C] - [IsScalarTower G (G ⧸ N) B] : - SMulCommClass (G ⧸ N) A B := - ⟨fun g k x ↦ Quotient.inductionOn' g fun g ↦ - FaithfulSMul.algebraMap_injective B C (by - simp [algebraMap.smul, algebraMap.smul', smul_comm])⟩ - -end Semiring - section Domain variable (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] [IsDomain C] [Algebra A B] @@ -796,16 +495,6 @@ noncomputable section IntermediateField variable (N : Subgroup G) [N.Normal] [IsGaloisGroup N F L] -instance : MulSemiringAction (G ⧸ N) F := - letI := smulOfNormal G F L N - haveI := smulDistribClass_smulOfNormal G F L N - letI := mulSemiringActionOfSmulDistribClass F L G - mulSemiringActionQuotient G F L N - -instance [SMulCommClass G K L] [MulSemiringAction G F] [SMulDistribClass G F L] - [IsScalarTower G (G ⧸ N) F] : SMulCommClass (G ⧸ N) K F := - smulCommClassQuotient G K F L N - /-- If `G` is a finite Galois group for `L/K` and `N` is a normal subgroup of `G` that is a Galois group for `L/F`, then the quotient group `G ⧸ N` is a Galois group for `F/K`. -/ instance [Finite G] [IsGaloisGroup G K L] : IsGaloisGroup (G ⧸ N) K F := diff --git a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean new file mode 100644 index 00000000000000..19bd8b54b351a6 --- /dev/null +++ b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean @@ -0,0 +1,251 @@ +/- +Copyright (c) 2025 Thomas Browning. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Thomas Browning +-/ +module + +public import Mathlib.RingTheory.IntegralClosure.IntegrallyClosed +public import Mathlib.RingTheory.Invariant.Basic +public import Mathlib.RingTheory.IsGaloisGroup.Defs + +/-! +# Galois Groups of Rings + +Given an action of a group `G` on an extension of rings `B/A`, the predicate `IsGaloisGroup G A B` +states that `G` acts faithfully on `B` with fixed ring `A`. This file develops some of the theory +of this predicate without assuming Galois theory for fields. +-/ + +@[expose] public section + +-- this file should not import any field theory beyond the contents of `FieldTheory/Fixed.lean` +-- material involving Galois theory should be placed in `FieldTheory/IsGaloisGroup.lean` +assert_not_exists IntermediateField.adjoin + +open Module + +section CommRing + +variable (G A B : Type*) [Group G] [CommSemiring A] [Semiring B] [Algebra A B] + [MulSemiringAction G B] + +variable {C : Type*} [CommSemiring C] [Algebra C B] + +variable {G} in +protected theorem Subgroup.smul_algebraMap {H : Subgroup G} [SMulCommClass H C B] {g : G} + (hg : g ∈ H) (x : C) : + g • algebraMap C B x = algebraMap C B x := + smul_algebraMap (⟨g, hg⟩ : H) x + +theorem IsGaloisGroup.smul_mem_of_normal (N : Subgroup G) [hN : N.Normal] + [hC : IsGaloisGroup N C B] (g : G) (x : C) : + g • algebraMap C B x ∈ Set.range (algebraMap C B) := by + apply hC.isInvariant.isInvariant (g • algebraMap C B x) + intro n + rw [← inv_smul_eq_iff, Subgroup.smul_def, ← mul_smul, ← mul_smul] + exact Subgroup.smul_algebraMap B (hN.conj_mem' n n.prop g) x + +@[deprecated (since := "2026-05-28")] alias smul_eq_self := Subgroup.smul_algebraMap +@[deprecated (since := "2026-05-28")] alias smul_mem_of_normal := IsGaloisGroup.smul_mem_of_normal + +end CommRing + +section Field + +variable (G A B K L : Type*) [Group G] [CommRing A] [CommRing B] [MulSemiringAction G B] + [Algebra A B] [Field K] [Field L] [Algebra K L] [Algebra A K] [Algebra B L] [Algebra A L] + [IsFractionRing A K] [IsFractionRing B L] [IsScalarTower A K L] [IsScalarTower A B L] + [MulSemiringAction G L] [SMulDistribClass G B L] + +instance [IsGaloisGroup G A B] : IsGaloisGroup G (algebraMap A B).range B where + faithful := IsGaloisGroup.faithful A + commutes := ⟨fun g ⟨a', ⟨a, ha⟩⟩ b ↦ by simp [Subring.smul_def, ← ha]⟩ + isInvariant := ⟨fun b hb ↦ by + obtain ⟨a, ha⟩ := Algebra.IsInvariant.isInvariant (A := A) b hb + exact ⟨⟨algebraMap A B a, ⟨a, rfl⟩⟩, ha⟩⟩ + +/-- `IsGaloisGroup` for rings implies `IsGaloisGroup` for their fraction fields. -/ +theorem IsGaloisGroup.to_isFractionRing_of_isIntegral + [Algebra.IsIntegral A B] [hGAB : IsGaloisGroup G A B] : + IsGaloisGroup G K L where + faithful := + have := hGAB.faithful + IsFractionRing.faithfulSMul G B L + commutes := IsFractionRing.smulCommClass G A B K L + isInvariant := IsFractionRing.isInvariant_of_isIntegral G A B K L + +/-- `IsGaloisGroup` for rings implies `IsGaloisGroup` for their fraction fields. -/ +theorem IsGaloisGroup.to_isFractionRing [Finite G] [hGAB : IsGaloisGroup G A B] : + IsGaloisGroup G K L := + have := hGAB.isInvariant.isIntegral + IsGaloisGroup.to_isFractionRing_of_isIntegral G A B K L + +/-- If `B` is an integral extension of an integrally closed domain `A`, then `IsGaloisGroup` for +their fraction fields implies `IsGaloisGroup` for these rings. -/ +theorem IsGaloisGroup.of_isFractionRing [hGKL : IsGaloisGroup G K L] + [IsIntegrallyClosed A] [Algebra.IsIntegral A B] : IsGaloisGroup G A B := by + have hc (a : A) : (algebraMap K L) (algebraMap A K a) = (algebraMap B L) (algebraMap A B a) := by + simp_rw [← IsScalarTower.algebraMap_apply] + refine ⟨⟨fun h ↦ ?_⟩, ⟨fun g x y ↦ IsFractionRing.injective B L ?_⟩, ⟨fun x h ↦ ?_⟩⟩ + · have := hGKL.faithful + refine eq_of_smul_eq_smul fun (y : L) ↦ ?_ + obtain ⟨a, b, hb, rfl⟩ := IsFractionRing.div_surjective B y + simp only [smul_div₀', ← algebraMap.coe_smul', h] + · simp [Algebra.smul_def, algebraMap.coe_smul', ← hc] + · obtain ⟨b, hb⟩ := hGKL.isInvariant.isInvariant (algebraMap B L x) + (by simpa [← algebraMap.coe_smul']) + have hx : IsIntegral A (algebraMap B L x) := (Algebra.IsIntegral.isIntegral x).algebraMap + rw [← hb, isIntegral_algebraMap_iff (algebraMap K L).injective, + IsIntegrallyClosedIn.isIntegral_iff] at hx + obtain ⟨a, rfl⟩ := hx + exact ⟨a, by rwa [hc, IsFractionRing.coe_inj] at hb⟩ + +/-- If `G` is finite and `A` is integrally closed then `IsGaloisGroup G A B` is equivalent to `B/A` +being integral and the fields of fractions `Frac(B)/Frac(A)` being Galois with Galois group `G`. -/ +theorem IsGaloisGroup.iff_isFractionRing [Finite G] [IsIntegrallyClosed A] : + IsGaloisGroup G A B ↔ Algebra.IsIntegral A B ∧ IsGaloisGroup G K L := + ⟨fun h ↦ ⟨h.isInvariant.isIntegral, h.to_isFractionRing G A B K L⟩, + fun ⟨_, h⟩ ↦ h.of_isFractionRing G A B K L⟩ + +@[deprecated (since := "2026-04-20")] alias FractionRing.mulSemiringAction_of_isGaloisGroup := + IsFractionRing.mulSemiringAction + +/-- +If `G` is finite and `IsGaloisGroup G A B` with `A` and `B` domains, then `G` is also +a Galois group for `FractionRing B / FractionRing A` for the action defined by +`IsFractionRing.mulSemiringAction`. +-/ +instance IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [IsTorsionFree A B] [Finite G] + [IsGaloisGroup G A B] [Algebra (FractionRing A) (FractionRing B)] + [IsScalarTower A (FractionRing A) (FractionRing B)] : + letI := IsFractionRing.mulSemiringAction G B (FractionRing B) + IsGaloisGroup G (FractionRing A) (FractionRing B) := by + let := IsFractionRing.mulSemiringAction G B (FractionRing B) + apply IsGaloisGroup.to_isFractionRing G A B _ _ + +end Field + +variable (G G' K L : Type*) [Group G] [Group G'] [Field K] [Field L] [Algebra K L] + [MulSemiringAction G L] [MulSemiringAction G' L] + +namespace IsGaloisGroup + +section IsDomain + +variable (A B : Type*) [CommRing A] [CommRing B] [IsDomain B] [Algebra A B] [FaithfulSMul A B] + [MulSemiringAction G B] [MulSemiringAction G' B] [IsGaloisGroup G A B] [IsGaloisGroup G' A B] + [Finite G] [Finite G'] + +end IsDomain + +variable (H : Subgroup G) + +instance (R S : Type*) [CommRing R] [CommRing S] [Algebra R S] + [MulSemiringAction G S] [hGKL : IsGaloisGroup G R S] : + IsGaloisGroup H (FixedPoints.subalgebra R S H) S where + faithful := have := hGKL.faithful; inferInstance + commutes := inferInstance + isInvariant := ⟨fun x h ↦ ⟨⟨x, h⟩, rfl⟩⟩ + +section Quotient + +section Semiring + +variable (A B C : Type*) [CommSemiring A] [Semiring C] [Algebra A C] [MulSemiringAction G C] +variable (N : Subgroup G) [CommSemiring B] [Algebra B C] + +/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then `G` acts on `B`. +For `g : G` and `x : B`, `g • x` is the unique element of `B` whose image in `C` is +`g • algebraMap B C x`, see `algebraMap_smulOfNormal`. -/ +@[implicit_reducible] +noncomputable def smulOfNormal [N.Normal] [IsGaloisGroup N B C] : SMul G B where + smul g x := (smul_mem_of_normal G C N g x).choose + +@[simp] +theorem algebraMap_smulOfNormal [N.Normal] [IsGaloisGroup N B C] (g : G) (x : B) : + letI := smulOfNormal G B C + algebraMap B C (g • x) = g • algebraMap B C x := + (smul_mem_of_normal G C N g x).choose_spec + +/-- If `N` is normal and `IsGaloisGroup N B C`, the action `smulOfNormal G B C` satisfies +`SMulDistribClass G B C`. -/ +instance smulDistribClass_smulOfNormal [N.Normal] [IsGaloisGroup N B C] : + letI := smulOfNormal G B C + SMulDistribClass G B C := + let := smulOfNormal G B C + ⟨fun g b c ↦ by simp [Algebra.smul_def]⟩ + +variable [FaithfulSMul B C] + +/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then `G` acts on `B` as a +`MulSemiringAction`, via the action defined in `smulOfNormal`. -/ +@[implicit_reducible] +noncomputable def mulSemiringActionOfNormal [IsGaloisGroup N B C] [N.Normal] : + MulSemiringAction G B := by + let : SMul G B := smulOfNormal G B C N + have : SMulDistribClass G B C := smulDistribClass_smulOfNormal G B C N + exact mulSemiringActionOfSmulDistribClass B C G + +/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then the quotient group `G ⧸ N` +acts on `B` by `(g : G ⧸ N) • x = g • x`. -/ +@[implicit_reducible] +noncomputable def mulSemiringActionQuotient [IsGaloisGroup N B C] [N.Normal] : + MulSemiringAction (G ⧸ N) B := + letI := mulSemiringActionOfNormal G B C N + { smul q x := + Quotient.liftOn' q (· • x) fun g₁ g₂ h ↦ by + apply FaithfulSMul.algebraMap_injective B C + rw [algebraMap.smul', algebraMap.smul', smul_eq_iff_eq_inv_smul, ← smul_assoc, smul_eq_mul, + Subgroup.smul_algebraMap C (by rwa [← QuotientGroup.leftRel_apply])] + one_smul x := one_smul G x + mul_smul q₁ q₂ x := Quotient.inductionOn₂' q₁ q₂ fun g h ↦ mul_smul g h x + smul_add q x y := Quotient.inductionOn' q fun g ↦ smul_add g x y + smul_zero q := Quotient.inductionOn' q fun g ↦ smul_zero g + smul_one q := Quotient.inductionOn' q fun g ↦ smul_one g + smul_mul q x y := Quotient.inductionOn' q fun g ↦ smul_mul' g x y } + +theorem mulSemiringActionQuotient_smul_def [MulSemiringAction G B] [SMulDistribClass G B C] + [IsGaloisGroup N B C] [N.Normal] (g : G) (b : B) : + letI := mulSemiringActionQuotient G B C N + (g : G ⧸ N) • b = g • b := by + let := mulSemiringActionOfNormal G B C N + refine (Quotient.liftOn'_mk'' (· • b) _ g).trans (FaithfulSMul.algebraMap_injective B C ?_) + rw [algebraMap.smul', algebraMap.smul'] + +instance isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C] + [IsGaloisGroup N B C] [N.Normal] : + letI := mulSemiringActionQuotient G B C N + IsScalarTower G (G ⧸ N) B := + let := mulSemiringActionQuotient G B C N + ⟨fun g q b ↦ Quotient.inductionOn' q fun h ↦ by + simp [mul_smul, mulSemiringActionQuotient_smul_def]⟩ + +set_option linter.defProp false in +/-- If `G` acts on `C` commuting with `A`, then the action of `G ⧸ N` on `B` commutes with `A`. -/ +@[implicit_reducible] +def smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCommClass G A C] + [MulSemiringAction G B] [MulAction (G ⧸ N) B] [SMulDistribClass G B C] + [IsScalarTower G (G ⧸ N) B] : + SMulCommClass (G ⧸ N) A B := + ⟨fun g k x ↦ Quotient.inductionOn' g fun g ↦ + FaithfulSMul.algebraMap_injective B C (by + simp [algebraMap.smul, algebraMap.smul', smul_comm])⟩ + +end Semiring + +variable (F : IntermediateField K L) (N : Subgroup G) [N.Normal] [IsGaloisGroup N F L] + +noncomputable instance : MulSemiringAction (G ⧸ N) F := + letI := smulOfNormal G F L N + haveI := smulDistribClass_smulOfNormal G F L N + letI := mulSemiringActionOfSmulDistribClass F L G + mulSemiringActionQuotient G F L N + +instance [SMulCommClass G K L] [MulSemiringAction G F] [SMulDistribClass G F L] + [IsScalarTower G (G ⧸ N) F] : SMulCommClass (G ⧸ N) K F := + smulCommClassQuotient G K F L N + +end Quotient + +end IsGaloisGroup diff --git a/Mathlib/RingTheory/IsGaloisGroup/Defs.lean b/Mathlib/RingTheory/IsGaloisGroup/Defs.lean new file mode 100644 index 00000000000000..c0ae57e8a37fce --- /dev/null +++ b/Mathlib/RingTheory/IsGaloisGroup/Defs.lean @@ -0,0 +1,155 @@ +/- +Copyright (c) 2025 Thomas Browning. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Thomas Browning +-/ +module + +public import Mathlib.Algebra.Algebra.Subalgebra.Operations +public import Mathlib.RingTheory.Invariant.Defs + +/-! +# Predicate for Galois Groups + +Given an action of a group `G` on an extension of fields `L/K`, we introduce a predicate +`IsGaloisGroup G K L` saying that `G` acts faithfully on `L` with fixed field `K`. In particular, +we do not assume that `L` is an algebraic extension of `K`. + +## Implementation notes + +We actually define `IsGaloisGroup G A B` for extensions of rings `B/A`, with the same definition +(faithful action on `B` with fixed ring `A`). This definition turns out to axiomatize a common +setup in algebraic number theory where a Galois group `Gal(L/K)` acts on an extension of subrings +`B/A` (e.g., rings of integers). In particular, there are theorems in algebraic number theory that +naturally assume `[IsGaloisGroup G A B]` and whose statements would otherwise require assuming +`(K L : Type*) [Field K] [Field L] [Algebra K L] [IsGalois K L]` (along with predicates relating +`K` and `L` to the rings `A` and `B`) despite `K` and `L` not appearing in the conclusion. + +Unfortunately, this definition of `IsGaloisGroup G A B` for extensions of rings `B/A` is +nonstandard and clashes with other notions such as the étale fundamental group. In particular, if +`G` is finite and `A` is integrally closed, then `IsGaloisGroup G A B` is equivalent to `B/A` +being integral and the fields of fractions `Frac(B)/Frac(A)` being Galois with Galois group `G` +(see `IsGaloisGroup.iff_isFractionRing`), rather than `B/A` being étale for instance. + +But in the absence of a more suitable name, the utility of the predicate `IsGaloisGroup G A B` for +extensions of rings `B/A` seems to outweigh these terminological issues. +-/ + +@[expose] public section + +assert_not_exists IsFractionRing + +variable (G A A' B : Type*) [Group G] [CommSemiring A] [Semiring B] [Algebra A B] + [MulSemiringAction G B] + +/-- `G` is a Galois group for `L/K` if the action of `G` on `L` is faithful with fixed field `K`. +In particular, we do not assume that `L` is an algebraic extension of `K`. + +See the implementation notes in this file for the meaning of this definition in the case of rings. +-/ +class IsGaloisGroup where + faithful : FaithfulSMul G B + commutes : SMulCommClass G A B + isInvariant : Algebra.IsInvariant A B G + +namespace IsGaloisGroup + +variable {G A B} in +theorem of_mulEquiv [hG : IsGaloisGroup G A B] {H : Type*} [Group H] + [MulSemiringAction H B] (e : H ≃* G) (he : ∀ h (x : B), (e h) • x = h • x) : + IsGaloisGroup H A B where + faithful := ⟨fun h ↦ e.injective <| hG.faithful.eq_of_smul_eq_smul <| by simpa only [he]⟩ + commutes := ⟨fun x a b ↦ by simpa [he] using hG.commutes.smul_comm (e x) a b⟩ + isInvariant := ⟨fun b h ↦ + have he' : ∀ (g : G) (x : B), e.symm g • x = g • x := fun g x ↦ by simp [← he] + hG.isInvariant.isInvariant b (fun g ↦ by simpa [he'] using h (e.symm g))⟩ + +variable {G A B} in +theorem iff_of_mulEquiv {H : Type*} [Group H] [MulSemiringAction H B] + (e : H ≃* G) (he : ∀ h (x : B), e h • x = h • x) : + IsGaloisGroup H A B ↔ IsGaloisGroup G A B := by + refine ⟨fun h ↦ h.of_mulEquiv e.symm fun g x ↦ ?_, fun h ↦ h.of_mulEquiv e he⟩ + rw [← he, e.apply_symm_apply] + +variable {G A B} in +@[simp] +theorem top_iff : IsGaloisGroup (⊤ : Subgroup G) A B ↔ IsGaloisGroup G A B := + iff_of_mulEquiv Subgroup.topEquiv fun _ _ ↦ rfl + +instance [IsGaloisGroup G A B] : IsGaloisGroup (⊤ : Subgroup G) A B := + IsGaloisGroup.top_iff.mpr ‹_› + +theorem of_algEquiv [hG : IsGaloisGroup G A B] (B' : Type*) [Semiring B'] + [Algebra A B'] [MulSemiringAction G B'] (e : B ≃ₐ[A] B') + (he : ∀ (g : G) (x : B), e (g • x) = g • (e x)) : + IsGaloisGroup G A B' where + faithful := ⟨fun h ↦ hG.faithful.eq_of_smul_eq_smul fun b ↦ by simpa [← he] using h (e b)⟩ + commutes := ⟨fun g a b' ↦ by + have h' {x'} : e.symm (g • x') = g • e.symm x' := by + apply e.injective + simp [he] + apply e.symm.injective + simpa [h', map_smul] using hG.commutes.smul_comm g a (e.symm b')⟩ + isInvariant := ⟨fun x' hx' ↦ by + obtain ⟨a, ha⟩ := hG.isInvariant.isInvariant (e.symm x') (fun g ↦ by + apply e.injective + simp [he, hx']) + exact ⟨a, by rw [← e.commutes, ha, AlgEquiv.apply_symm_apply]⟩⟩ + +theorem of_ringHom_surjective [hG : IsGaloisGroup G A B] [CommSemiring A'] + [Algebra A' B] (e : A →+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) + (he' : Function.Surjective e) : IsGaloisGroup G A' B where + faithful := hG.faithful + commutes := ⟨by + intro g a' b + obtain ⟨a, rfl⟩ : ∃ a, e a = a' := he' a' + rw [Algebra.smul_def, Algebra.smul_def, he, ← Algebra.smul_def, ← Algebra.smul_def] + exact hG.commutes.smul_comm g a b⟩ + isInvariant := ⟨by + intro b h + obtain ⟨a, ha⟩ := hG.isInvariant.isInvariant b h + exact ⟨e a, by rw [he, ha]⟩⟩ + +theorem of_ringEquiv [hG : IsGaloisGroup G A B] [CommSemiring A'] [Algebra A' B] + (e : A ≃+* A') (he : ∀ a, algebraMap A' B (e a) = algebraMap A B a) : + IsGaloisGroup G A' B := + .of_ringHom_surjective G A A' B e he e.surjective + +attribute [instance low] IsGaloisGroup.commutes IsGaloisGroup.isInvariant + +variable [hA : IsGaloisGroup G A B] [FaithfulSMul A B] + +/-- If `B/A` is Galois with Galois group `G`, then `A` is isomorphic to the subring of elements of +`B` fixed by `G`. -/ +@[simps apply_coe] +noncomputable def ringEquivFixedPoints : + A ≃+* FixedPoints.subsemiring B G where + toFun x := ⟨algebraMap A B x, fun _ ↦ by rw [smul_algebraMap]⟩ + invFun x := (hA.isInvariant.isInvariant x x.prop).choose + map_mul' _ _ := by simp [Subtype.ext_iff] + map_add' _ _ := by simp [Subtype.ext_iff] + left_inv _ := by simp + right_inv x := by simpa [Subtype.ext_iff] using (hA.isInvariant.isInvariant x x.prop).choose_spec + +@[simp] +theorem algebraMap_ringEquivFixedPoints_symm_apply (x : FixedPoints.subsemiring B G) : + algebraMap A B ((ringEquivFixedPoints G A B).symm x) = x := + (hA.isInvariant.isInvariant x x.prop).choose_spec + +variable [CommSemiring A'] [Algebra A' B] [FaithfulSMul A' B] [hA' : IsGaloisGroup G A' B] + +/-- If `B/A` and `B/A'` are Galois with the same Galois group, then `A ≃+* A'`. -/ +noncomputable def ringEquiv : A ≃+* A' := + (ringEquivFixedPoints G A B).trans (ringEquivFixedPoints G A' B).symm + +@[simp] +theorem algebraMap_ringEquiv_apply (x : A) : + algebraMap A' B (IsGaloisGroup.ringEquiv G A A' B x) = algebraMap A B x := by + simp [ringEquiv] + +@[simp] +theorem algebraMap_ringEquiv_symm_apply (x : A') : + algebraMap A B ((IsGaloisGroup.ringEquiv G A A' B).symm x) = algebraMap A' B x := by + simp [ringEquiv] + +end IsGaloisGroup From a2bff7b898cdaaddae5789dc8e20445d011003ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Jun 2026 14:52:42 +0000 Subject: [PATCH 0290/1300] feat(AlgebraicTopology): a nonsingular simplicial set is the colimit of standard simplices indexed by nondegenerate simplices (#40254) --- Mathlib.lean | 1 + .../NonDegenerateSimplicesColimit.lean | 2 +- .../SimplicialSet/Nonsingular.lean | 77 ++++++++++++++++++- .../SimplicialSet/NonsingularColimit.lean | 74 ++++++++++++++++++ .../SimplicialSet/StdSimplex.lean | 60 +++++++++++++++ 5 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean diff --git a/Mathlib.lean b/Mathlib.lean index f0735f278b484c..001a649d202c66 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1604,6 +1604,7 @@ public import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplicesColi public import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplicesSubcomplex public import Mathlib.AlgebraicTopology.SimplicialSet.Nonempty public import Mathlib.AlgebraicTopology.SimplicialSet.Nonsingular +public import Mathlib.AlgebraicTopology.SimplicialSet.NonsingularColimit public import Mathlib.AlgebraicTopology.SimplicialSet.Op public import Mathlib.AlgebraicTopology.SimplicialSet.Path public import Mathlib.AlgebraicTopology.SimplicialSet.PiZero diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean index 12e7737e704c5a..f2c473ade6dfe4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean @@ -29,7 +29,7 @@ variable (X : SSet.{u}) /-- If `X : SSet`, this is the functor `X.N ⥤ SSet` which sends a nondegenerate simplex of `X` to the subcomplex of `X` that it generates. -/ -@[expose, simps! obj] +@[expose, simps! obj map] public def functorN : X.N ⥤ SSet.{u} := X.orderEmbeddingN.monotone.functor ⋙ Subcomplex.toSSetFunctor diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean index 50bb14b9e13fba..0d31bdaaec145b 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean @@ -32,7 +32,7 @@ public section universe u -open CategoryTheory MonoidalCategory Simplicial +open CategoryTheory MonoidalCategory Simplicial Opposite namespace SSet @@ -104,4 +104,79 @@ lemma Nonsingular.δ_injective [X.Nonsingular] have := mono' x hx exact injective_of_mono ((yonedaEquiv.symm x).app _) hij +lemma Nonsingular.injective_map + [X.Nonsingular] {n : ℕ} (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) + {m : SimplexCategory} {f g : m ⟶ ⦋n⦌} + (h : X.map f.op x = X.map g.op x) : + f = g := by + have := Nonsingular.mono' x hx + apply stdSimplex.{u}.map_injective + rw [← cancel_mono (yonedaEquiv.symm x)] + apply yonedaEquiv.injective + simpa [yonedaEquiv_comp, yonedaEquiv_map] + +lemma Nonsingular.isIso_toOfSimplex [X.Nonsingular] + {n : ℕ} (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) : + IsIso (Subcomplex.toOfSimplex x) := by + rw [Subcomplex.isIso_toOfSimplex_iff] + exact Nonsingular.mono' x hx + +/-- If `x : X _⦋n⦌` is a nondegenerate simplex of a nonsingular simplcial set, +this is the isomorphism `Δ[n] ≅ Subcomplex.ofSimplex x` induced by `x`. -/ +@[expose, simps! hom] +noncomputable def Nonsingular.iso + [X.Nonsingular] {n : ℕ} (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) : + Δ[n] ≅ Subcomplex.ofSimplex x := + letI := Nonsingular.isIso_toOfSimplex x hx + asIso (Subcomplex.toOfSimplex x) + +namespace N + +variable [X.Nonsingular] {x y z : X.N} (h : x ≤ y) + +include h in +lemma existsUnique_of_le : + ∃! (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌), Mono f ∧ X.map f.op y.1.2 = x.1.2 := + existsUnique_of_exists_of_unique (by + obtain ⟨f, _, hf⟩ := le_iff_exists_mono.1 h + exact ⟨f, inferInstance, hf⟩) (fun f₁ f₂ ⟨_, hf₁⟩ ⟨_, hf₂⟩ ↦ by + exact Nonsingular.injective_map _ y.nonDegenerate (by rw [hf₁, hf₂])) + +/-- Given an inequality `x ≤ y` between nondegenerate simplices of a +nonsingular simplicial set `X`, this is the corresponding morphism +`⦋x.dim⦌ ⟶ ⦋y.dim⦌` in the simplex category. -/ +noncomputable def monoOfLE : ⦋x.dim⦌ ⟶ ⦋y.dim⦌ := + (existsUnique_of_le h).exists.choose + +instance : Mono (monoOfLE h) := + (existsUnique_of_le h).exists.choose_spec.1 + +@[simp] +lemma map_monoOfLE : X.map (monoOfLE h).op y.simplex = x.simplex := + (existsUnique_of_le h).exists.choose_spec.2 + +@[reassoc, simp] +lemma stdSimplex_map_monoOfLE_yonedaEquiv_symm_simplex : + stdSimplex.map (monoOfLE h) ≫ yonedaEquiv.symm y.simplex = + yonedaEquiv.symm x.simplex := by + rw [yonedaEquiv_symm_naturality_left, map_monoOfLE] + +lemma monoOfLE_eq_iff (h : x ≤ y) (g : ⦋x.dim⦌ ⟶ ⦋y.dim⦌) [Mono g] : + monoOfLE h = g ↔ X.map g.op y.simplex = x.simplex := + ⟨by rintro rfl; simp, + fun h' ↦ (existsUnique_of_le h).unique ⟨inferInstance, by simp⟩ ⟨inferInstance, h'⟩⟩ + +variable (x) in +@[simp] +lemma monoOfLE_refl : monoOfLE (le_refl x) = 𝟙 _ := by + simp [monoOfLE_eq_iff] + +@[reassoc (attr := simp)] +lemma monoOfLE_comp (h' : y ≤ z) : + monoOfLE h ≫ monoOfLE h' = monoOfLE (h.trans h') := by + symm + simp [monoOfLE_eq_iff] + +end N + end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean new file mode 100644 index 00000000000000..15635797ca2175 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean @@ -0,0 +1,74 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.AlgebraicTopology.SimplexCategory.SemiSimplexCategory +public import Mathlib.AlgebraicTopology.SimplicialSet.Nonsingular +public import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplicesColimit + +/-! +# Nonsingular simplicial sets, as colimits of standard simplices + +In the file `Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean`, +it was shown that any simplicial set `X` is the colimit (indexed by the type `X.N` +of nondegenerate simplices) of its monogenous subcomplexes. + +In this file, we assume that `X` is nonsingular, in which case its monogenous subcomplexes +identify to standard simplices. This allows to show that `X` is the colimit +of `Δ[x.dim]` for `x : X.N`. + +-/ + +@[expose] public section + +universe u + +open CategoryTheory Simplicial Limits + +namespace SSet + +variable (X : SSet.{u}) [X.Nonsingular] + +namespace N + +set_option backward.isDefEq.respectTransparency false in +/-- If `X` is a nonsingular simplicial set, this is the functor +`X.N ⥤ SemiSimplexCategory` which sends a nondegenerate +simplex `s : X : N` to `⦋s.dim⦌ₛ` -/ +@[simps obj map] +noncomputable def toSemiSimplexCategory : X.N ⥤ SemiSimplexCategory where + obj s := ⦋s.dim⦌ₛ + map f := SemiSimplexCategory.homOfMono (N.monoOfLE (leOfHom f)) + map_id _ := SemiSimplexCategory.toSimplexCategory.map_injective (by simp) + map_comp _ _ := SemiSimplexCategory.toSimplexCategory.map_injective (by simp) + +end N + +/-- The functor `X.N ⥤ SSet` which sends `x : X.N` to `Δ[x.dim]`. -/ +noncomputable abbrev functorN' : X.N ⥤ SSet.{u} := + N.toSemiSimplexCategory X ⋙ SemiSimplexCategory.toSimplexCategory ⋙ SSet.stdSimplex + +set_option backward.defeqAttrib.useBackward true in +/-- The isomorphism `X.functorN' ≅ X.functorN` for a nonsingular simplicial set `X`. -/ +noncomputable def functorN'Iso : X.functorN' ≅ X.functorN := + NatIso.ofComponents (fun x ↦ Nonsingular.iso _ x.nonDegenerate) (fun _ ↦ by + simp [← cancel_mono (Subcomplex.ι _)]) + +/-- If `X` is a nonsingular simplicial set, this is the cocone consisting +of the (mono)morphisms `Δ[x.dim] ⟶ X` for all nondegenerate simplices `x : X.N`. -/ +@[simps] +noncomputable def coconeN' : Cocone X.functorN' where + pt := X + ι.app s := yonedaEquiv.symm s.simplex + ι.naturality _ _ f := N.stdSimplex_map_monoOfLE_yonedaEquiv_symm_simplex (leOfHom f) + +/-- If `X` is a nonsingular simplicial set, `X` is the colimit of `Δ[x.dim]` +for all nondegenerate simplices `x : X.N`. -/ +noncomputable def isColimitCoconeN' : IsColimit X.coconeN' := + (IsColimit.equivOfNatIsoOfIso + X.functorN'Iso.symm _ _ (Cocone.ext (Iso.refl _))).1 X.isColimitCoconeN + +end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index b0448158cbc584..329cf1f5e2c2ad 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -50,6 +50,13 @@ namespace stdSimplex open Finset Opposite SimplexCategory +/-- The functor `stdSimplex : SimplexCategory ⥤ SSet` is fully faithful; -/ +abbrev fullyFaithful : stdSimplex.{u}.FullyFaithful := + ULiftYoneda.fullyFaithful SimplexCategory + +instance : stdSimplex.{u}.Full := fullyFaithful.full +instance : stdSimplex.{u}.Faithful := fullyFaithful.faithful + @[simp] lemma map_id (n : SimplexCategory) : (SSet.stdSimplex.map (SimplexCategory.Hom.mk OrderHom.id : n ⟶ n)) = 𝟙 _ := @@ -302,6 +309,17 @@ lemma yonedaEquiv_symm_app_id {X : SSet.{u}} {n : ℕ} (x : X _⦋n⦌) : (yonedaEquiv.symm x).app _ (yonedaEquiv (𝟙 _)) = x := by simp +lemma yonedaEquiv_naturality {X : SSet} {m n : SimplexCategory} + (f : m ⟶ n) (g : stdSimplex.obj n ⟶ X) : + X.map f.op (yonedaEquiv g) = yonedaEquiv (stdSimplex.map f ≫ g) := + uliftYonedaEquiv_naturality _ _ + +@[reassoc] +lemma yonedaEquiv_symm_naturality_left {X : SSet} {m n : SimplexCategory} + (f : m ⟶ n) (g : X.obj (Opposite.op n)) : + stdSimplex.map f ≫ yonedaEquiv.symm g = yonedaEquiv.symm (X.map f.op g) := by + rw [← yonedaEquiv.apply_eq_iff_eq_symm_apply, ← yonedaEquiv_naturality, + yonedaEquiv.apply_symm_apply] namespace Subcomplex @@ -784,4 +802,46 @@ noncomputable def stdSimplex : SimplexCategory ⥤ SSet.Augmented.{u} where end Augmented +namespace Subcomplex + +variable {X : SSet.{u}} {n : ℕ} (x : X _⦋n⦌) + +/-- Given `x : X _⦋n⦌`, this is the epimorphism from `Δ[n]` +to the subcomplex of `X` generated by `x`. -/ +def toOfSimplex : Δ[n] ⟶ ofSimplex x := + Subcomplex.lift (yonedaEquiv.symm x) (by simp [range_eq_ofSimplex]) + +@[reassoc (attr := simp)] +lemma toOfSimplex_ι : + toOfSimplex x ≫ (ofSimplex x).ι = yonedaEquiv.symm x := rfl + +@[simp] +lemma yonedaEquiv_toOfSimplex : + yonedaEquiv (toOfSimplex x) = ⟨x, mem_ofSimplex_obj x⟩ := + yonedaEquiv.symm.injective (by cat_disch) + +set_option backward.defeqAttrib.useBackward true in +instance : Epi (toOfSimplex x) := by + rw [← range_eq_top_iff] + ext m ⟨_, u, rfl⟩ + simp only [range_eq_ofSimplex, yonedaEquiv_toOfSimplex, Subfunctor.top_obj, + Set.top_eq_univ, Set.mem_univ, iff_true] + refine ⟨u, ?_⟩ + dsimp + ext + rw [← yonedaEquiv.right_inv x] + aesop + +lemma isIso_toOfSimplex_iff : + IsIso (toOfSimplex x) ↔ Mono (yonedaEquiv.symm x) := by + constructor + · intro + rw [← toOfSimplex_ι] + infer_instance + · intro h + have := mono_of_mono_fac (toOfSimplex_ι x) + apply isIso_of_mono_of_epi + +end Subcomplex + end SSet From 247b7ec2c202a571d3f222c29f41442bba96093e Mon Sep 17 00:00:00 2001 From: "Filippo A. E. Nuccio" <65080144+faenuccio@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:06:27 +0000 Subject: [PATCH 0291/1300] doc: fix the doc of two files about group actions (#40138) Co-authored-by: faenuccio --- Mathlib/GroupTheory/GroupAction/Quotient.lean | 278 +++++++++--------- Mathlib/GroupTheory/Schreier.lean | 12 +- 2 files changed, 146 insertions(+), 144 deletions(-) diff --git a/Mathlib/GroupTheory/GroupAction/Quotient.lean b/Mathlib/GroupTheory/GroupAction/Quotient.lean index e5ac2d4b6cbbaa..5ccc2b03d56143 100644 --- a/Mathlib/GroupTheory/GroupAction/Quotient.lean +++ b/Mathlib/GroupTheory/GroupAction/Quotient.lean @@ -32,7 +32,7 @@ assert_not_exists Cardinal universe u v w -variable {α : Type u} {β : Type v} {γ : Type w} +variable {G : Type u} {X : Type v} open Function @@ -40,75 +40,75 @@ open scoped commutatorElement namespace MulAction -variable [Group α] +variable [Group G] section QuotientAction open Subgroup MulOpposite QuotientGroup -variable (β) [Monoid β] [MulAction β α] (H : Subgroup α) +variable (X) [Monoid X] [MulAction X G] (H : Subgroup G) -/-- A typeclass for when a `MulAction β α` descends to the quotient `α ⧸ H`. -/ +/-- A typeclass for when a `MulAction X G` descends to the quotient `G ⧸ H`. -/ class QuotientAction : Prop where /-- The action fulfils a normality condition on products that lie in `H`. - This ensures that the action descends to an action on the quotient `α ⧸ H`. -/ - inv_mul_mem : ∀ (b : β) {a a' : α}, a⁻¹ * a' ∈ H → (b • a)⁻¹ * b • a' ∈ H + This ensures that the action descends to an action on the quotient `G ⧸ H`. -/ + inv_mul_mem : ∀ (b : X) {a a' : G}, a⁻¹ * a' ∈ H → (b • a)⁻¹ * b • a' ∈ H -/-- A typeclass for when an `AddAction β α` descends to the quotient `α ⧸ H`. -/ -class _root_.AddAction.QuotientAction {α : Type u} (β : Type v) [AddGroup α] [AddMonoid β] - [AddAction β α] (H : AddSubgroup α) : Prop where +/-- A typeclass for when an `AddAction X G` descends to the quotient `G ⧸ H`. -/ +class _root_.AddAction.QuotientAction {G : Type u} (X : Type v) [AddGroup G] [AddMonoid X] + [AddAction X G] (H : AddSubgroup G) : Prop where /-- The action fulfils a normality condition on summands that lie in `H`. - This ensures that the action descends to an action on the quotient `α ⧸ H`. -/ - inv_mul_mem : ∀ (b : β) {a a' : α}, -a + a' ∈ H → -(b +ᵥ a) + (b +ᵥ a') ∈ H + This ensures that the action descends to an action on the quotient `G ⧸ H`. -/ + inv_mul_mem : ∀ (x : X) {g g' : G}, -g + g' ∈ H → -(x +ᵥ g) + (x +ᵥ g') ∈ H attribute [to_additive] MulAction.QuotientAction @[to_additive] -instance left_quotientAction : QuotientAction α H := +instance left_quotientAction : QuotientAction G H := ⟨fun _ _ _ _ => by rwa [smul_eq_mul, smul_eq_mul, mul_inv_rev, mul_assoc, inv_mul_cancel_left]⟩ @[to_additive] -instance right_quotientAction : QuotientAction (normalizer H : Subgroup α).op H := +instance right_quotientAction : QuotientAction (normalizer H : Subgroup G).op H := ⟨fun b c _ _ => by rwa [smul_def, smul_def, smul_eq_mul_unop, smul_eq_mul_unop, mul_inv_rev, ← mul_assoc, mem_normalizer_iff'.mp b.prop, mul_assoc, mul_inv_cancel_left]⟩ @[to_additive] -instance right_quotientAction' [hH : H.Normal] : QuotientAction αᵐᵒᵖ H := +instance right_quotientAction' [hH : H.Normal] : QuotientAction Gᵐᵒᵖ H := ⟨fun _ _ _ _ => by rwa [smul_eq_mul_unop, smul_eq_mul_unop, mul_inv_rev, mul_assoc, hH.mem_comm_iff, mul_assoc, mul_inv_cancel_right]⟩ @[to_additive] -instance quotient [QuotientAction β H] : MulAction β (α ⧸ H) where +instance quotient [QuotientAction X H] : MulAction X (G ⧸ H) where smul b := Quotient.map' (b • ·) fun _ _ h => leftRel_apply.mpr <| QuotientAction.inv_mul_mem b <| leftRel_apply.mp h - one_smul q := Quotient.inductionOn' q fun a => congr_arg Quotient.mk'' (one_smul β a) + one_smul q := Quotient.inductionOn' q fun a => congr_arg Quotient.mk'' (one_smul X a) mul_smul b b' q := Quotient.inductionOn' q fun a => congr_arg Quotient.mk'' (mul_smul b b' a) -variable {β} +variable {X} @[to_additive (attr := simp)] -theorem Quotient.smul_mk [QuotientAction β H] (b : β) (a : α) : - (b • QuotientGroup.mk a : α ⧸ H) = QuotientGroup.mk (b • a) := +theorem Quotient.smul_mk [QuotientAction X H] (b : X) (g : G) : + (b • QuotientGroup.mk g : G ⧸ H) = QuotientGroup.mk (b • g) := rfl @[to_additive (attr := simp)] -theorem Quotient.smul_coe [QuotientAction β H] (b : β) (a : α) : - b • (a : α ⧸ H) = (↑(b • a) : α ⧸ H) := +theorem Quotient.smul_coe [QuotientAction X H] (b : X) (g : G) : + b • (g : G ⧸ H) = (↑(b • g) : G ⧸ H) := rfl @[to_additive (attr := simp)] -theorem Quotient.mk_smul_out [QuotientAction β H] (b : β) (q : α ⧸ H) : +theorem Quotient.mk_smul_out [QuotientAction X H] (b : X) (q : G ⧸ H) : QuotientGroup.mk (b • q.out) = b • q := by rw [← Quotient.smul_mk, QuotientGroup.out_eq'] @[to_additive] -theorem Quotient.coe_smul_out [QuotientAction β H] (b : β) (q : α ⧸ H) : ↑(b • q.out) = b • q := by +theorem Quotient.coe_smul_out [QuotientAction X H] (b : X) (q : G ⧸ H) : ↑(b • q.out) = b • q := by simp -theorem _root_.QuotientGroup.out_conj_pow_minimalPeriod_mem (a : α) (q : α ⧸ H) : - q.out⁻¹ * a ^ Function.minimalPeriod (a • ·) q * q.out ∈ H := by +theorem _root_.QuotientGroup.out_conj_pow_minimalPeriod_mem (g : G) (q : G ⧸ H) : + q.out⁻¹ * g ^ Function.minimalPeriod (g • ·) q * q.out ∈ H := by rw [mul_assoc, ← QuotientGroup.eq, QuotientGroup.out_eq', ← smul_eq_mul, Quotient.mk_smul_out, eq_comm, pow_smul_eq_iff_minimalPeriod_dvd] @@ -117,51 +117,51 @@ end QuotientAction open QuotientGroup /-- The canonical map to the left cosets. -/ -def _root_.MulActionHom.toQuotient (H : Subgroup α) : α →[α] α ⧸ H where +def _root_.MulActionHom.toQuotient (H : Subgroup G) : G →[G] G ⧸ H where toFun := (↑); map_smul' := Quotient.smul_coe H @[simp] -theorem _root_.MulActionHom.toQuotient_apply (H : Subgroup α) (g : α) : +theorem _root_.MulActionHom.toQuotient_apply (H : Subgroup G) (g : G) : MulActionHom.toQuotient H g = g := rfl @[to_additive (attr := simp)] -theorem coe_quotient_smul {H : Subgroup α} [H.Normal] [SMul α β] - [MulAction (α ⧸ H) β] [IsScalarTower α (α ⧸ H) β] (g : α) (x : β) : - (g : α ⧸ H) • x = g • x := by - rw [← smul_one_smul (α ⧸ H) g x, ← QuotientGroup.mk_one, Quotient.smul_coe, +theorem coe_quotient_smul {H : Subgroup G} [H.Normal] [SMul G X] + [MulAction (G ⧸ H) X] [IsScalarTower G (G ⧸ H) X] (g : G) (x : X) : + (g : G ⧸ H) • x = g • x := by + rw [← smul_one_smul (G ⧸ H) g x, ← QuotientGroup.mk_one, Quotient.smul_coe, smul_eq_mul, mul_one] @[to_additive] -instance mulLeftCosetsCompSubtypeVal (H I : Subgroup α) : MulAction I (α ⧸ H) := - MulAction.compHom (α ⧸ H) (Subgroup.subtype I) +instance mulLeftCosetsCompSubtypeVal (H I : Subgroup G) : MulAction I (G ⧸ H) := + MulAction.compHom (G ⧸ H) (Subgroup.subtype I) -variable (α) -variable [MulAction α β] (x : β) +variable (G) +variable [MulAction G X] (x : X) /-- The canonical map from the quotient of the stabilizer to the set. -/ @[to_additive /-- The canonical map from the quotient of the stabilizer to the set. -/] -def ofQuotientStabilizer (g : α ⧸ MulAction.stabilizer α x) : β := +def ofQuotientStabilizer (g : G ⧸ MulAction.stabilizer G x) : X := Quotient.liftOn' g (· • x) fun g1 g2 H => calc g1 • x = g1 • (g1⁻¹ * g2) • x := congr_arg _ (leftRel_apply.mp H).symm _ = g2 • x := by rw [smul_smul, mul_inv_cancel_left] @[to_additive (attr := simp)] -theorem ofQuotientStabilizer_mk (g : α) : ofQuotientStabilizer α x (QuotientGroup.mk g) = g • x := +theorem ofQuotientStabilizer_mk (g : G) : ofQuotientStabilizer G x (QuotientGroup.mk g) = g • x := rfl @[to_additive] -theorem ofQuotientStabilizer_mem_orbit (g) : ofQuotientStabilizer α x g ∈ orbit α x := +theorem ofQuotientStabilizer_mem_orbit (g) : ofQuotientStabilizer G x g ∈ orbit G x := Quotient.inductionOn' g fun g => ⟨g, rfl⟩ @[to_additive] -theorem ofQuotientStabilizer_smul (g : α) (g' : α ⧸ MulAction.stabilizer α x) : - ofQuotientStabilizer α x (g • g') = g • ofQuotientStabilizer α x g' := +theorem ofQuotientStabilizer_smul (g : G) (g' : G ⧸ MulAction.stabilizer G x) : + ofQuotientStabilizer G x (g • g') = g • ofQuotientStabilizer G x g' := Quotient.inductionOn' g' fun _ => mul_smul _ _ _ @[to_additive] -theorem injective_ofQuotientStabilizer : Function.Injective (ofQuotientStabilizer α x) := +theorem injective_ofQuotientStabilizer : Function.Injective (ofQuotientStabilizer G x) := fun y₁ y₂ => Quotient.inductionOn₂' y₁ y₂ fun g₁ g₂ (H : g₁ • x = g₂ • x) => Quotient.sound' <| by @@ -171,29 +171,29 @@ theorem injective_ofQuotientStabilizer : Function.Injective (ofQuotientStabilize /-- **Orbit-stabilizer theorem**. -/ @[to_additive /-- Orbit-stabilizer theorem. -/] -noncomputable def orbitEquivQuotientStabilizer (b : β) : orbit α b ≃ α ⧸ stabilizer α b := +noncomputable def orbitEquivQuotientStabilizer (b : X) : orbit G b ≃ G ⧸ stabilizer G b := Equiv.symm <| - Equiv.ofBijective (fun g => ⟨ofQuotientStabilizer α b g, ofQuotientStabilizer_mem_orbit α b g⟩) - ⟨fun x y hxy => injective_ofQuotientStabilizer α b (by convert! congr_arg Subtype.val hxy), + Equiv.ofBijective (fun g => ⟨ofQuotientStabilizer G b g, ofQuotientStabilizer_mem_orbit G b g⟩) + ⟨fun x y hxy => injective_ofQuotientStabilizer G b (by convert! congr_arg Subtype.val hxy), fun ⟨_, ⟨g, hgb⟩⟩ => ⟨g, Subtype.ext hgb⟩⟩ /-- Orbit-stabilizer theorem. -/ @[to_additive AddAction.orbitProdStabilizerEquivAddGroup /-- Orbit-stabilizer theorem. -/] -noncomputable def orbitProdStabilizerEquivGroup (b : β) : orbit α b × stabilizer α b ≃ α := - (Equiv.prodCongr (orbitEquivQuotientStabilizer α _) (Equiv.refl _)).trans +noncomputable def orbitProdStabilizerEquivGroup (b : X) : orbit G b × stabilizer G b ≃ G := + (Equiv.prodCongr (orbitEquivQuotientStabilizer G _) (Equiv.refl _)).trans Subgroup.groupEquivQuotientProdSubgroup.symm /-- Orbit-stabilizer theorem. -/ @[to_additive AddAction.card_orbit_mul_card_stabilizer_eq_card_addGroup /-- Orbit-stabilizer theorem. -/] -theorem card_orbit_mul_card_stabilizer_eq_card_group (b : β) [Fintype α] [Fintype <| orbit α b] - [Fintype <| stabilizer α b] : - Fintype.card (orbit α b) * Fintype.card (stabilizer α b) = Fintype.card α := by - rw [← Fintype.card_prod, Fintype.card_congr (orbitProdStabilizerEquivGroup α b)] +theorem card_orbit_mul_card_stabilizer_eq_card_group (b : X) [Fintype G] [Fintype <| orbit G b] + [Fintype <| stabilizer G b] : + Fintype.card (orbit G b) * Fintype.card (stabilizer G b) = Fintype.card G := by + rw [← Fintype.card_prod, Fintype.card_congr (orbitProdStabilizerEquivGroup G b)] @[to_additive (attr := simp)] -theorem orbitEquivQuotientStabilizer_symm_apply (b : β) (a : α) : - ((orbitEquivQuotientStabilizer α b).symm a : β) = a • b := +theorem orbitEquivQuotientStabilizer_symm_apply (b : X) (g : G) : + ((orbitEquivQuotientStabilizer G b).symm g : X) = g • b := rfl @[to_additive (attr := simp)] @@ -202,75 +202,77 @@ theorem stabilizer_quotient {G} [Group G] (H : Subgroup G) : ext simp [QuotientGroup.eq] -variable (β) +variable (X) -local notation "Ω" => Quotient <| orbitRel α β +local notation "Ω" => Quotient <| orbitRel G X -/-- **Class formula** : given `G` a group acting on `X` and `φ` a function mapping each orbit of `X` -under this action (that is, each element of the quotient of `X` by the relation `orbitRel G X`) to -an element in this orbit, this gives a (noncomputable) bijection between `X` and the disjoint union -of `G/Stab(φ(ω))` over all orbits `ω`. In most cases you'll want `φ` to be `Quotient.out`, so we -provide `MulAction.selfEquivSigmaOrbitsQuotientStabilizer'` as a special case. -/ +/-- **Class formula** : let `G` be a group acting on `X` and let `φ` be a function mapping each +orbit of `X` under this action (that is, each element of the quotient of `G` by the relation +`orbitRel G X`) to an element in this orbit. We provide a (noncomputable) bijection between `X` +and the disjoint union of `G/Stab(φ(ω))` over all orbits `ω : Ω`. In most cases you'll want `φ` +to be `Quotient.out`, so we provide `MulAction.selfEquivSigmaOrbitsQuotientStabilizer'` as a +special case. -/ @[to_additive - /-- **Class formula** : given `G` an additive group acting on `X` and `φ` a function - mapping each orbit of `X` under this action (that is, each element of the quotient of `X` by - the relation `orbit_rel G X`) to an element in this orbit, this gives a (noncomputable) - bijection between `X` and the disjoint union of `G/Stab(φ(ω))` over all orbits `ω`. In most - cases you'll want `φ` to be `Quotient.out`, so we provide + /-- **Class formula** : let `G` be an additive group acting on `X` and let `φ` be a function + mapping each orbit of `X` under this action (that is, each element of the quotient of `X` by + the relation `orbitRel G X`) to an element in this orbit. This definition is a (noncomputable) + bijection between `X` and the disjoint union of `G/Stab(φ(ω))` over all orbits `ω : Ω`. In + most cases you'll want `φ` to be `Quotient.out`, so we provide `AddAction.selfEquivSigmaOrbitsQuotientStabilizer'` as a special case. -/] -noncomputable def selfEquivSigmaOrbitsQuotientStabilizer' {φ : Ω → β} - (hφ : LeftInverse Quotient.mk'' φ) : β ≃ Σ ω : Ω, α ⧸ stabilizer α (φ ω) := +noncomputable def selfEquivSigmaOrbitsQuotientStabilizer' {φ : Ω → X} + (hφ : LeftInverse Quotient.mk'' φ) : X ≃ Σ ω : Ω, G ⧸ stabilizer G (φ ω) := calc - β ≃ Σ ω : Ω, orbitRel.Quotient.orbit ω := selfEquivSigmaOrbits' α β - _ ≃ Σ ω : Ω, α ⧸ stabilizer α (φ ω) := + X ≃ Σ ω : Ω, orbitRel.Quotient.orbit ω := selfEquivSigmaOrbits' G X + _ ≃ Σ ω : Ω, G ⧸ stabilizer G (φ ω) := Equiv.sigmaCongrRight fun ω => (Equiv.setCongr <| orbitRel.Quotient.orbit_eq_orbit_out _ hφ).trans <| - orbitEquivQuotientStabilizer α (φ ω) + orbitEquivQuotientStabilizer G (φ ω) /-- **Class formula**. This is a special case of `MulAction.self_equiv_sigma_orbits_quotient_stabilizer'` with `φ = Quotient.out`. -/ @[to_additive /-- **Class formula**. This is a special case of `AddAction.self_equiv_sigma_orbits_quotient_stabilizer'` with `φ = Quotient.out`. -/] -noncomputable def selfEquivSigmaOrbitsQuotientStabilizer : β ≃ Σ ω : Ω, α ⧸ stabilizer α ω.out := - selfEquivSigmaOrbitsQuotientStabilizer' α β Quotient.out_eq' +noncomputable def selfEquivSigmaOrbitsQuotientStabilizer : X ≃ Σ ω : Ω, G ⧸ stabilizer G ω.out := + selfEquivSigmaOrbitsQuotientStabilizer' G X Quotient.out_eq' /-- **Burnside's lemma** : a (noncomputable) bijection between the disjoint union of all -`{x ∈ X | g • x = x}` for `g ∈ G` and the product `G × X/G`, where `G` is a group acting on `X` and -`X/G` denotes the quotient of `X` by the relation `orbitRel G X`. -/ +`{x ∈ X | g • x = x}` for `g ∈ G` and the product `G × Ω`, where `G` is a group acting on `X` +and `Ω = X/G` denotes the quotient of `X` by the relation `orbitRel G X`. -/ @[to_additive AddAction.sigmaFixedByEquivOrbitsProdAddGroup /-- **Burnside's lemma** : a (noncomputable) bijection between the disjoint union of all - `{x ∈ X | g • x = x}` for `g ∈ G` and the product `G × X/G`, where `G` is an additive group - acting on `X` and `X/G` denotes the quotient of `X` by the relation `orbitRel G X`. -/] -noncomputable def sigmaFixedByEquivOrbitsProdGroup : (Σ a : α, fixedBy β a) ≃ Ω × α := + `{x ∈ X | g • x = x}` for `g ∈ G` and the product `G × Ω`, where `G` is an additive group + acting on `X` and `Ω = X/G` denotes the quotient of `X` by the relation `orbitRel G X`. -/] +noncomputable def sigmaFixedByEquivOrbitsProdGroup : (Σ g : G, fixedBy X g) ≃ Ω × G := calc - (Σ a : α, fixedBy β a) ≃ { ab : α × β // ab.1 • ab.2 = ab.2 } := + (Σ g : G, fixedBy X g) ≃ { ab : G × X // ab.1 • ab.2 = ab.2 } := (Equiv.subtypeProdEquivSigmaSubtype _).symm - _ ≃ { ba : β × α // ba.2 • ba.1 = ba.1 } := (Equiv.prodComm α β).subtypeEquiv fun _ => Iff.rfl - _ ≃ Σ b : β, stabilizer α b := - Equiv.subtypeProdEquivSigmaSubtype fun (b : β) a => a ∈ stabilizer α b - _ ≃ Σ ωb : Σ ω : Ω, orbit α ω.out, stabilizer α (ωb.2 : β) := - (selfEquivSigmaOrbits α β).sigmaCongrLeft' - _ ≃ Σ ω : Ω, Σ b : orbit α ω.out, stabilizer α (b : β) := - Equiv.sigmaAssoc fun (ω : Ω) (b : orbit α ω.out) => stabilizer α (b : β) - _ ≃ Σ ω : Ω, Σ _ : orbit α ω.out, stabilizer α ω.out := + _ ≃ { ba : X × G // ba.2 • ba.1 = ba.1 } := (Equiv.prodComm G X).subtypeEquiv fun _ => Iff.rfl + _ ≃ Σ b : X, stabilizer G b := + Equiv.subtypeProdEquivSigmaSubtype fun (b : X) a => a ∈ stabilizer G b + _ ≃ Σ ωb : Σ ω : Ω, orbit G ω.out, stabilizer G (ωb.2 : X) := + (selfEquivSigmaOrbits G X).sigmaCongrLeft' + _ ≃ Σ ω : Ω, Σ b : orbit G ω.out, stabilizer G (b : X) := + Equiv.sigmaAssoc fun (ω : Ω) (b : orbit G ω.out) => stabilizer G (b : X) + _ ≃ Σ ω : Ω, Σ _ : orbit G ω.out, stabilizer G ω.out := Equiv.sigmaCongrRight fun _ => Equiv.sigmaCongrRight fun ⟨_, hb⟩ => (stabilizerEquivStabilizerOfOrbitRel hb).toEquiv - _ ≃ Σ ω : Ω, orbit α ω.out × stabilizer α ω.out := + _ ≃ Σ ω : Ω, orbit G ω.out × stabilizer G ω.out := Equiv.sigmaCongrRight fun _ => Equiv.sigmaEquivProd _ _ - _ ≃ Σ _ : Ω, α := Equiv.sigmaCongrRight fun ω => orbitProdStabilizerEquivGroup α ω.out - _ ≃ Ω × α := Equiv.sigmaEquivProd Ω α + _ ≃ Σ _ : Ω, G := Equiv.sigmaCongrRight fun ω => orbitProdStabilizerEquivGroup G ω.out + _ ≃ Ω × G := Equiv.sigmaEquivProd Ω G -/-- **Burnside's lemma** : given a finite group `G` acting on a set `X`, the average number of -elements fixed by each `g ∈ G` is the number of orbits. -/ +/-- **Burnside's lemma** : given a finite group `G` acting on a type `X`, the sum the orders of the +stabilisers coincides with the number of orbits multiplied by the order of `G`. -/ @[to_additive (attr := wikidata Q1330377) AddAction.sum_card_fixedBy_eq_card_orbits_mul_card_addGroup - /-- **Burnside's lemma** : given a finite additive group `G` acting on a set `X`, - the average number of elements fixed by each `g ∈ G` is the number of orbits. -/] -theorem sum_card_fixedBy_eq_card_orbits_mul_card_group [Fintype α] [∀ a : α, Fintype <| fixedBy β a] - [Fintype Ω] : (∑ a : α, Fintype.card (fixedBy β a)) = Fintype.card Ω * Fintype.card α := by + /-- **Burnside's lemma** : given a finite additive group `G` acting on a type `X`, + the sum the orders of the stabilisers coincides with the number of orbits multiplied by the + order of `G`. -/] +theorem sum_card_fixedBy_eq_card_orbits_mul_card_group [Fintype G] [∀ g : G, Fintype <| fixedBy X g] + [Fintype Ω] : (∑ g : G, Fintype.card (fixedBy X g)) = Fintype.card Ω * Fintype.card G := by rw [← Fintype.card_prod, ← Fintype.card_sigma, - Fintype.card_congr (sigmaFixedByEquivOrbitsProdGroup α β)] + Fintype.card_congr (sigmaFixedByEquivOrbitsProdGroup G X)] @[to_additive] instance isPretransitive_quotient (G) [Group G] (H : Subgroup G) : IsPretransitive G (G ⧸ H) where @@ -279,16 +281,16 @@ instance isPretransitive_quotient (G) [Group G] (H : Subgroup G) : IsPretransiti refine ⟨y * x⁻¹, QuotientGroup.eq.mpr ?_⟩ simp only [smul_eq_mul, H.one_mem, inv_mul_cancel, inv_mul_cancel_right]} -variable {α} +variable {G} @[to_additive] -instance finite_quotient_of_pretransitive_of_finite_quotient [IsPretransitive α β] {H : Subgroup α} - [Finite (α ⧸ H)] : Finite <| orbitRel.Quotient H β := by - rcases isEmpty_or_nonempty β with he | ⟨⟨b⟩⟩ +instance finite_quotient_of_pretransitive_of_finite_quotient [IsPretransitive G X] {H : Subgroup G} + [Finite (G ⧸ H)] : Finite <| orbitRel.Quotient H X := by + rcases isEmpty_or_nonempty X with he | ⟨⟨b⟩⟩ · exact Quotient.finite _ · have h' : Finite (Quotient (rightRel H)) := Finite.of_equiv _ (quotientRightRelEquivQuotientLeftRel _).symm - let f : Quotient (rightRel H) → orbitRel.Quotient H β := + let f : Quotient (rightRel H) → orbitRel.Quotient H X := fun a ↦ Quotient.liftOn' a (fun g ↦ ⟦g • b⟧) fun g₁ g₂ r ↦ by replace r := Setoid.symm' _ r rw [rightRel_eq] at r @@ -297,14 +299,14 @@ instance finite_quotient_of_pretransitive_of_finite_quotient [IsPretransitive α exact Finite.of_surjective f ((Quotient.surjective_liftOn' _).2 (Quotient.mk''_surjective.comp (MulAction.surjective_smul _ _))) -variable {β} in +variable {X} in /-- A bijection between the quotient of the action of a subgroup `H` on an orbit, and a corresponding quotient expressed in terms of `Setoid.comap Subtype.val`. -/ @[to_additive /-- A bijection between the quotient of the action of an additive subgroup `H` on an orbit, and a corresponding quotient expressed in terms of `Setoid.comap Subtype.val`. -/] -noncomputable def equivSubgroupOrbitsSetoidComap (H : Subgroup α) (ω : Ω) : +noncomputable def equivSubgroupOrbitsSetoidComap (H : Subgroup G) (ω : Ω) : orbitRel.Quotient H (orbitRel.Quotient.orbit ω) ≃ - Quotient ((orbitRel H β).comap (Subtype.val : Quotient.mk (orbitRel α β) ⁻¹' {ω} → β)) where + Quotient ((orbitRel H X).comap (Subtype.val : Quotient.mk (orbitRel G X) ⁻¹' {ω} → X)) where toFun := fun q ↦ q.liftOn' (fun x ↦ ⟦⟨↑x, by simp only [Set.mem_preimage, Set.mem_singleton_iff] have hx := x.property @@ -330,43 +332,43 @@ noncomputable def equivSubgroupOrbitsSetoidComap (H : Subgroup α) (ω : Ω) : induction q using Quotient.inductionOn' rfl -/-- A bijection between the orbits under the action of a subgroup `H` on `β`, and the orbits +/-- A bijection between the orbits under the action of a subgroup `H` on `X`, and the orbits under the action of `H` on each orbit under the action of `G`. -/ @[to_additive /-- A bijection between the orbits under the action of an additive subgroup `H` on -`β`, and the orbits under the action of `H` on each orbit under the action of `G`. -/] -noncomputable def equivSubgroupOrbits (H : Subgroup α) : - orbitRel.Quotient H β ≃ Σ ω : Ω, orbitRel.Quotient H (orbitRel.Quotient.orbit ω) := +`X`, and the orbits under the action of `H` on each orbit under the action of `G`. -/] +noncomputable def equivSubgroupOrbits (H : Subgroup G) : + orbitRel.Quotient H X ≃ Σ ω : Ω, orbitRel.Quotient H (orbitRel.Quotient.orbit ω) := (Setoid.sigmaQuotientEquivOfLe (orbitRel_subgroup_le H)).symm.trans (Equiv.sigmaCongrRight fun ω ↦ (equivSubgroupOrbitsSetoidComap H ω).symm) -variable {β} +variable {X} @[to_additive] -instance finite_quotient_of_finite_quotient_of_finite_quotient {H : Subgroup α} - [Finite (orbitRel.Quotient α β)] [Finite (α ⧸ H)] : - Finite <| orbitRel.Quotient H β := by - rw [(equivSubgroupOrbits β H).finite_iff] +instance finite_quotient_of_finite_quotient_of_finite_quotient {H : Subgroup G} + [Finite (orbitRel.Quotient G X)] [Finite (G ⧸ H)] : + Finite <| orbitRel.Quotient H X := by + rw [(equivSubgroupOrbits X H).finite_iff] infer_instance /-- Given a group acting freely and transitively, an equivalence between the orbits under the -action of a subgroup and the quotient group. -/ +action of a subgroup and the quotient of the group by the subgroup. -/ @[to_additive /-- Given an additive group acting freely and transitively, an equivalence between the -orbits under the action of an additive subgroup and the quotient group. -/] -noncomputable def equivSubgroupOrbitsQuotientGroup [IsPretransitive α β] - [IsCancelSMul α β] (H : Subgroup α) : - orbitRel.Quotient H β ≃ α ⧸ H where - toFun := fun q ↦ q.liftOn' (fun y ↦ (exists_smul_eq α y x).choose) (by +orbits under the action of an additive subgroup and the quotient of the group by the subgroup. -/] +noncomputable def equivSubgroupOrbitsQuotientGroup [IsPretransitive G X] + [IsCancelSMul G X] (H : Subgroup G) : + orbitRel.Quotient H X ≃ G ⧸ H where + toFun := fun q ↦ q.liftOn' (fun y ↦ (exists_smul_eq G y x).choose) (by intro y₁ y₂ h rw [orbitRel_apply] at h rw [Quotient.eq'', leftRel_eq] dsimp only rcases h with ⟨g, rfl⟩ dsimp only - suffices (exists_smul_eq α (g • y₂) x).choose = (exists_smul_eq α y₂ x).choose * g⁻¹ by + suffices (exists_smul_eq G (g • y₂) x).choose = (exists_smul_eq G y₂ x).choose * g⁻¹ by simp [this] refine IsCancelSMul.right_cancel _ _ (g • y₂) ?_ - rw [(exists_smul_eq α (g • y₂) x).choose_spec, Subgroup.smul_def, Subgroup.coe_inv, - smul_smul, inv_mul_cancel_right, (exists_smul_eq α y₂ x).choose_spec]) + rw [(exists_smul_eq G (g • y₂) x).choose_spec, Subgroup.smul_def, Subgroup.coe_inv, + smul_smul, inv_mul_cancel_right, (exists_smul_eq G y₂ x).choose_spec]) invFun := fun q ↦ q.liftOn' (fun g ↦ ⟦g⁻¹ • x⟧) (by intro g₁ g₂ h rw [leftRel_eq] at h @@ -377,7 +379,7 @@ noncomputable def equivSubgroupOrbitsQuotientGroup [IsPretransitive α β] simp only [Quotient.liftOn'_mk''] rw [← @Quotient.mk''_eq_mk, Quotient.eq'', orbitRel_apply] convert! mem_orbit_self _ - rw [inv_smul_eq_iff, (exists_smul_eq α _ x).choose_spec] + rw [inv_smul_eq_iff, (exists_smul_eq G _ x).choose_spec] right_inv := fun g ↦ by cases g using Quotient.inductionOn' with | _ g simp only [Quotient.liftOn'_mk'', QuotientGroup.mk] @@ -386,30 +388,30 @@ noncomputable def equivSubgroupOrbitsQuotientGroup [IsPretransitive α β] convert! one_mem H rw [inv_mul_eq_one, eq_comm, ← inv_mul_eq_one, ← Subgroup.mem_bot, ← IsCancelSMul.stabilizer_eq_bot (g⁻¹ • x), mem_stabilizer_iff, mul_smul, - (exists_smul_eq α (g⁻¹ • x) x).choose_spec] + (exists_smul_eq G (g⁻¹ • x) x).choose_spec] -/-- If `α` acts on `β` with trivial stabilizers, `β` is equivalent -to the product of the quotient of `β` by `α` and `α`. +/-- If `G` acts on `X` with trivial stabilizers, `X` is equivalent +to the product of the quotient of `X` by `G` and `G`. See `MulAction.selfEquivOrbitsQuotientProd` with `φ = Quotient.out`. -/ -@[to_additive selfEquivOrbitsQuotientProd' /-- If `α` acts freely on `β`, `β` is equivalent -to the product of the quotient of `β` by `α` and `α`. +@[to_additive selfEquivOrbitsQuotientProd' /-- If `G` acts freely on `X`, `X` is equivalent +to the product of the quotient of `X` by `G` and `G`. See `AddAction.selfEquivOrbitsQuotientProd` with `φ = Quotient.out`. -/] noncomputable def selfEquivOrbitsQuotientProd' - {φ : Quotient (MulAction.orbitRel α β) → β} (hφ : Function.LeftInverse Quotient.mk'' φ) - (h : ∀ b : β, MulAction.stabilizer α b = ⊥) : - β ≃ Quotient (MulAction.orbitRel α β) × α := - (MulAction.selfEquivSigmaOrbitsQuotientStabilizer' α β hφ).trans <| + {φ : Quotient (MulAction.orbitRel G X) → X} (hφ : Function.LeftInverse Quotient.mk'' φ) + (h : ∀ b : X, MulAction.stabilizer G b = ⊥) : + X ≃ Quotient (MulAction.orbitRel G X) × G := + (MulAction.selfEquivSigmaOrbitsQuotientStabilizer' G X hφ).trans <| (Equiv.sigmaCongrRight <| fun _ ↦ - (Subgroup.quotientEquivOfEq (h _)).trans (QuotientGroup.quotientEquivSelf α)).trans <| + (Subgroup.quotientEquivOfEq (h _)).trans (QuotientGroup.quotientEquivSelf G)).trans <| Equiv.sigmaEquivProd _ _ -/-- If `α` acts freely on `β`, `β` is equivalent to the product of the quotient of `β` by `α` and -`α`. -/ +/-- If `G` acts freely on `X`, `X` is equivalent to the product of the quotient of `X` by `G` and +`G`. -/ @[to_additive selfEquivOrbitsQuotientProd - /-- If `α` acts freely on `β`, `β` is equivalent to the product of the quotient of `β` by -`α` and `α`. -/] -noncomputable def selfEquivOrbitsQuotientProd (h : ∀ b : β, MulAction.stabilizer α b = ⊥) : - β ≃ Quotient (MulAction.orbitRel α β) × α := + /-- If `G` acts freely on `X`, `X` is equivalent to the product of the quotient of `X` by +`G` and `G`. -/] +noncomputable def selfEquivOrbitsQuotientProd (h : ∀ b : X, MulAction.stabilizer G b = ⊥) : + X ≃ Quotient (MulAction.orbitRel G X) × G := MulAction.selfEquivOrbitsQuotientProd' Quotient.out_eq' h end MulAction diff --git a/Mathlib/GroupTheory/Schreier.lean b/Mathlib/GroupTheory/Schreier.lean index f368c740032423..1133fbe3ba7e88 100644 --- a/Mathlib/GroupTheory/Schreier.lean +++ b/Mathlib/GroupTheory/Schreier.lean @@ -87,8 +87,8 @@ theorem closure_mul_image_mul_eq_top rw [mul_assoc, ← inv_inv s, ← mul_inv_rev, inv_inv] exact hR.toRightFun_mul_inv_mem (r * s⁻¹) -/-- **Schreier's Lemma**: If `R : Set G` is a `rightTransversal` of `H : Subgroup G` - with `1 ∈ R`, and if `G` is generated by `S : Set G`, then `H` is generated by the `Set` +/-- **Schreier's Lemma**: If `R : Set G` and `H : Subgroup G` are complements with `1 ∈ R`, and if +`G` is generated by `S : Set G`, then `H` is generated by the `Set` `(R * S).image (fun g ↦ g * (hR.toRightFun g)⁻¹)`. -/ @[wikidata Q3229345] theorem closure_mul_image_eq (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) @@ -108,8 +108,8 @@ theorem closure_mul_image_eq (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) · rw [Subtype.coe_mk, inv_one, mul_one] exact (H.mul_mem_cancel_left (hU hg)).mp hh -/-- **Schreier's Lemma**: If `R : Set G` is a `rightTransversal` of `H : Subgroup G` - with `1 ∈ R`, and if `G` is generated by `S : Set G`, then `H` is generated by the `Set` +/-- **Schreier's Lemma**: If `R : Set G` and `H : Subgroup G` are complements with `1 ∈ R`, and if +`G` is generated by `S : Set G`, then `H` is generated by the `Set` `(R * S).image (fun g ↦ g * (hR.toRightFun g)⁻¹)`. -/ theorem closure_mul_image_eq_top (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) (hS : closure S = ⊤) : closure ((R * S).image fun g => @@ -117,8 +117,8 @@ theorem closure_mul_image_eq_top (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) rw [eq_top_iff, ← map_subtype_le_map_subtype, MonoidHom.map_closure, Set.image_image] exact (map_subtype_le ⊤).trans (ge_of_eq (closure_mul_image_eq hR hR1 hS)) -/-- **Schreier's Lemma**: If `R : Finset G` is a `rightTransversal` of `H : Subgroup G` - with `1 ∈ R`, and if `G` is generated by `S : Finset G`, then `H` is generated by the `Finset` +/-- **Schreier's Lemma**: If `R : Finset G` and `H : Subgroup G` are complements with `1 ∈ R`, and +if `G` is generated by `S : Finset G`, then `H` is generated by the `Finset` `(R * S).image (fun g ↦ g * (hR.toRightFun g)⁻¹)`. -/ theorem closure_mul_image_eq_top' [DecidableEq G] {R S : Finset G} (hR : IsComplement (H : Set G) R) (hR1 : (1 : G) ∈ R) From 3de9307b457ac5ce7fac8a3da986f3e75b4cf09c Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:06:30 +0000 Subject: [PATCH 0292/1300] perf: lower priority for IsSimpleGroup.toNontrivial instances (#40327) These instances have very weak keys ([Nontrivial, *]), hence are always applied. Let's try lowering their priority. --- Mathlib/GroupTheory/Subgroup/Simple.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/GroupTheory/Subgroup/Simple.lean b/Mathlib/GroupTheory/Subgroup/Simple.lean index 71df18745f6fcd..9222b5b591229a 100644 --- a/Mathlib/GroupTheory/Subgroup/Simple.lean +++ b/Mathlib/GroupTheory/Subgroup/Simple.lean @@ -39,12 +39,16 @@ class IsSimpleGroup : Prop extends Nontrivial G where /-- Any normal subgroup is either `⊥` or `⊤` -/ eq_bot_or_eq_top_of_normal : ∀ H : Subgroup G, H.Normal → H = ⊥ ∨ H = ⊤ +attribute [instance 100] IsSimpleGroup.toNontrivial + /-- An `AddGroup` is simple when it has exactly two normal `AddSubgroup`s. -/ @[mk_iff] class IsSimpleAddGroup : Prop extends Nontrivial A where /-- Any normal additive subgroup is either `⊥` or `⊤` -/ eq_bot_or_eq_top_of_normal : ∀ H : AddSubgroup A, H.Normal → H = ⊥ ∨ H = ⊤ +attribute [instance 100] IsSimpleAddGroup.toNontrivial + attribute [to_additive existing] IsSimpleGroup isSimpleGroup_iff variable {G} {A} From f5681a0ca2ba7ff28bcfaeb4d7c2ebd9ac036459 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 23 Jun 2026 15:06:32 +0000 Subject: [PATCH 0293/1300] feat: `Monoid` and `Group` instances for `OrderHom` and `OrderIso` (#40515) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These will be used in an upcoming PR to turn `fun x ↦ (x * · * star x)` into a term of type `R →* (R →o R)` when `R` is a `StarOrderedRing`, and likewise also `Rˣ →* (R ≃o R)`. Co-authored-by: Eric Wieser --- Mathlib/Algebra/Order/Group/End.lean | 30 ++++++++++++++++++++++++++++ Mathlib/Data/FunLike/IsApply.lean | 15 ++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/Mathlib/Algebra/Order/Group/End.lean b/Mathlib/Algebra/Order/Group/End.lean index 92ab1280f939a9..fb0326451bc75f 100644 --- a/Mathlib/Algebra/Order/Group/End.lean +++ b/Mathlib/Algebra/Order/Group/End.lean @@ -6,10 +6,21 @@ Authors: Mario Carneiro module public import Mathlib.Algebra.Group.Defs +public import Mathlib.Order.Hom.Basic public import Mathlib.Order.RelIso.Basic +public import Mathlib.Data.FunLike.IsApply /-! # Relation isomorphisms form a group + +This file contains `Monoid` instances for `RelHom` and `OrderHom`, where multiplication is +given by composition. Likewise there is a `Group` instance for `RelIso`. Because `OrderIso` +is an abbreviation for `RelIso`, there is no need for an additional instance. + +## TODO + ++ Rename the `mul_def`/`one_def` lemmas to `mul_eq_comp`/`one_eq_id`. ++ Use the `IsMulApplyEqComp` and `IsOneApplyEqSelf` classes for `RelHom` and `RelIso`. -/ @[expose] public section @@ -87,3 +98,22 @@ theorem apply_inv_self (e : r ≃r r) (x) : e (e⁻¹ x) = x := e.apply_symm_apply x end RelIso + +namespace OrderHom + +variable [Preorder α] + +instance : Mul (α →o α) where mul f g := f.comp g +instance : One (α →o α) where one := .id +instance : IsMulApplyEqComp (α →o α) α where mul_apply_eq_comp _ _ _ := rfl +instance : IsOneApplyEqSelf (α →o α) α where one_apply_eq_self _ := rfl + +lemma mul_eq_comp (f g : α →o α) : (f * g : α →o α) = f.comp g := rfl +lemma one_eq_id : (1 : α →o α) = .id := rfl + +instance : Monoid (α →o α) where + mul_assoc f g h := by simp [DFunLike.ext_iff] + one_mul f := by simp [DFunLike.ext_iff] + mul_one f := by simp [DFunLike.ext_iff] + +end OrderHom diff --git a/Mathlib/Data/FunLike/IsApply.lean b/Mathlib/Data/FunLike/IsApply.lean index 170abd0432cac1..e8848acbcec5a7 100644 --- a/Mathlib/Data/FunLike/IsApply.lean +++ b/Mathlib/Data/FunLike/IsApply.lean @@ -6,7 +6,9 @@ Authors: Moritz Doll module public import Mathlib.Algebra.Notation.Pi.Defs +public import Mathlib.Algebra.Group.Defs public import Mathlib.Data.FunLike.Basic +public import Mathlib.Logic.Function.Iterate /-! # Typeclasses for `FunLike` and algebraic operations In this file we provide typeclasses for the compatibility of algebraic structures and `FunLike` @@ -110,6 +112,14 @@ class IsMulApplyEqComp (F : Type*) (α : outParam Type*) [FunLike F α α] [Mul @[simp, grind =] alias mul_apply_eq_comp := IsMulApplyEqComp.mul_apply_eq_comp +@[simp, grind =] +lemma pow_apply_eq_iterate {F α : Type*} [FunLike F α α] [Monoid F] [IsOneApplyEqSelf F α] + [IsMulApplyEqComp F α] (f : F) (n : ℕ) (x : α) : + (f ^ n) x = f^[n] x := by + induction n with + | zero => simp + | succ n ih => simp [pow_succ', ih, ← Function.iterate_succ_apply'] + end Add section Sub @@ -245,6 +255,11 @@ theorem coe_one_eq_id_iff [One F'] [IsOneApplyEqSelf F' α] (f : F') : (f : α theorem coe_mul_eq_comp [Mul F'] [IsMulApplyEqComp F' α] (f g : F') : ↑(f * g) = f ∘ g := by ext; simp +@[norm_cast] +lemma coe_pow_eq_iterate [Monoid F'] [IsMulApplyEqComp F' α] [IsOneApplyEqSelf F' α] + (f : F') (n : ℕ) : ⇑(f ^ n) = f^[n] := + funext <| pow_apply_eq_iterate f n + @[norm_cast] theorem coe_natCast [NatCast F'] [One F'] [SMul Nat α] [SMul Nat F'] [IsSMulApply Nat F' α α] [IsNatCastApply F' α] [IsOneApplyEqSelf F' α] (n : Nat) : From a163fd2f6fb7408d4102dbb5faaca2b635ba1c0d Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 23 Jun 2026 15:06:35 +0000 Subject: [PATCH 0294/1300] feat: introduce `SelfAdjointDecompose` class (#40530) --- Mathlib/Algebra/Order/Star/Basic.lean | 36 +++++++++++++++++++ Mathlib/Algebra/Order/Star/Real.lean | 7 ++++ .../CStarAlgebra/PositiveLinearMap.lean | 27 -------------- .../PosPart/Basic.lean | 3 ++ Mathlib/LinearAlgebra/Complex/Module.lean | 23 ++++++++++++ 5 files changed, 69 insertions(+), 27 deletions(-) diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index 9aba3e1e74e5d3..5ba1bd85cc6b43 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -81,6 +81,24 @@ class StarOrderedRing (R : Type*) [NonUnitalSemiring R] [PartialOrder R] [StarRi le_iff : ∀ x y : R, x ≤ y ↔ ∃ p, p ∈ AddSubmonoid.closure (Set.range fun s => star s * s) ∧ y = x + p +/-- A class to encode that self-adjoint elements may be expressed as the +difference of nonnegative elements. This is satisfied by any type with a +`NonUnitalContinuousFunctionalCalculus ℝ A IsSelfAdjoint` instance. +However, it can also be satisfied by continuous linear functionals equipped +with the intrinsic star operation. + +This type class can be used to guarantee `PositiveLinearMap` is a `StarHomClass`. -/ +class SelfAdjointDecompose (R : Type*) [AddGroup R] [Star R] + [PartialOrder R] where + /-- Every self-adjoint element is the difference of nonnegative elements. -/ + exists_nonneg_sub_nonneg {a : R} (ha : IsSelfAdjoint a) : + ∃ (b c : R), 0 ≤ b ∧ 0 ≤ c ∧ a = b - c + +lemma IsSelfAdjoint.exists_nonneg_sub_nonneg {R : Type*} [AddGroup R] [Star R] + [PartialOrder R] [SelfAdjointDecompose R] {a : R} (ha : IsSelfAdjoint a) : + ∃ (b c : R), 0 ≤ b ∧ 0 ≤ c ∧ a = b - c := + SelfAdjointDecompose.exists_nonneg_sub_nonneg ha + namespace StarOrderedRing section NonUnitalSemiring variable [NonUnitalSemiring R] [PartialOrder R] [StarRing R] @@ -452,6 +470,24 @@ instance (priority := 100) StarRingEquivClass.instOrderIsoClass [EquivLike F R S rw [← f_inv_f x, ← f_inv_f y] exact NonUnitalStarRingHom.map_le_map_of_map_star f_inv h +/-- While `IsSelfAdjoint.map` assumes the map is star-preserving, this lemma instead assumes the +map is an order-preserving additive map from a space where self-adjoint elements can be expressed as +differences of nonnegative elemens, and whose codomain is a star-ordered ring. When such maps are +linear over `ℂ`, they are also star-preserving, and this lemma is used to establish that one by +splitting into real and imaginary parts. -/ +@[aesop safe apply (rule_sets := [CStarAlgebra])] +lemma IsSelfAdjoint.map' {F E R : Type*} [AddCommGroup E] [PartialOrder E] [StarAddMonoid E] + [NonUnitalRing R] [PartialOrder R] [StarRing R] [StarOrderedRing R] + [SelfAdjointDecompose E] [FunLike F E R] [OrderHomClass F E R] [AddMonoidHomClass F E R] + {a : E} (ha : IsSelfAdjoint a) (f : F) : + IsSelfAdjoint (f a) := by + obtain ⟨b, c, hb, hc, rfl⟩ := ha.exists_nonneg_sub_nonneg + have h₁ := OrderHomClass.mono f hb + have h₂ := OrderHomClass.mono f hc + cfc_tac + +@[deprecated (since := "2026-06-12")] alias map_isSelfAdjoint := IsSelfAdjoint.map' + end OrderClass instance Nat.instStarOrderedRing : StarOrderedRing ℕ where diff --git a/Mathlib/Algebra/Order/Star/Real.lean b/Mathlib/Algebra/Order/Star/Real.lean index 4462717d45506f..736f21b2290e79 100644 --- a/Mathlib/Algebra/Order/Star/Real.lean +++ b/Mathlib/Algebra/Order/Star/Real.lean @@ -34,3 +34,10 @@ instance NNReal.instStarOrderedRing : StarOrderedRing ℝ≥0 := by simp only [star_trivial, mul_self_sqrt] · rintro ⟨p, -, rfl⟩ exact le_self_add + +-- for lack of a better place with the necessary imports, we place this here +-- this exists only to satisfy the trivial instances of this class +instance {R : Type*} [AddGroup R] [Lattice R] [AddLeftMono R] [Star R] : + SelfAdjointDecompose R where + exists_nonneg_sub_nonneg {a} _ := + ⟨a⁺, a⁻, posPart_nonneg a, negPart_nonneg a, by simp⟩ diff --git a/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean b/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean index a5d0adb3aab838..22ba7dd887b9cf 100644 --- a/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean +++ b/Mathlib/Analysis/CStarAlgebra/PositiveLinearMap.lean @@ -31,23 +31,6 @@ open scoped NNReal variable {A₁ A₂ B₁ B₂ : Type*} -section CFC - -variable [NonUnitalRing A₁] [Module ℂ A₁] [SMulCommClass ℝ A₁ A₁] [IsScalarTower ℝ A₁ A₁] - [StarRing A₁] [TopologicalSpace A₁] [NonUnitalContinuousFunctionalCalculus ℝ A₁ IsSelfAdjoint] - [PartialOrder A₁] [StarOrderedRing A₁] - -variable [NonUnitalRing A₂] [Module ℂ A₂] [StarRing A₂] [PartialOrder A₂] [StarOrderedRing A₂] - -@[aesop safe apply (rule_sets := [CStarAlgebra])] -lemma map_isSelfAdjoint (f : A₁ →ₚ[ℂ] A₂) (a : A₁) (ha : IsSelfAdjoint a) : - IsSelfAdjoint (f a) := by - rw [← CFC.posPart_sub_negPart a ha] - cfc_tac - -end CFC - - section CStarAlgebra namespace PositiveLinearMap @@ -134,16 +117,6 @@ instance {F : Type*} [FunLike F A₁ A₂] [LinearMapClass F ℂ A₁ A₂] [Ord exact ⟨C, h⟩ exact (LinearMap.mkContinuousOfExistsBound (f : A₁ →ₗ[ℂ] A₂) hbound).continuous -instance {F : Type*} [FunLike F A₁ A₂] [LinearMapClass F ℂ A₁ A₂] [OrderHomClass F A₁ A₂] : - StarHomClass F A₁ A₂ where - map_star f a := by - obtain ⟨y, hy_nonneg, hy_norm, hy⟩ := CStarAlgebra.exists_sum_four_nonneg a - have hy' : ∀ x : Fin 4, star (y x) = y x := fun x => by - rw [IsSelfAdjoint.star_eq (hy_nonneg x).isSelfAdjoint] - have hy'' : ∀ x : Fin 4, star (f (y x)) = f (y x) := fun x => by - rw [IsSelfAdjoint.star_eq (map_nonneg f (hy_nonneg x)).isSelfAdjoint] - simp [hy, hy', hy''] - end PositiveLinearMap end CStarAlgebra diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean index f4a81b97557852..2af2e998881d35 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean @@ -148,6 +148,9 @@ lemma negPart_nonneg (a : A) : 0 ≤ a⁻ := cfcₙ_nonneg (fun x _ ↦ by positivity) +instance : SelfAdjointDecompose A where + exists_nonneg_sub_nonneg {a} ha := ⟨a⁺, a⁻, by cfc_tac, by cfc_tac, (posPart_sub_negPart a).symm⟩ + lemma posPart_eq_of_eq_sub_negPart {a b : A} (hab : a = b - a⁻) (hb : 0 ≤ b := by cfc_tac) : a⁺ = b := by have ha := hab.symm ▸ hb.isSelfAdjoint.sub (negPart_nonneg a).isSelfAdjoint diff --git a/Mathlib/LinearAlgebra/Complex/Module.lean b/Mathlib/LinearAlgebra/Complex/Module.lean index 6b9d1cdd32c577..26fb146affe3e9 100644 --- a/Mathlib/LinearAlgebra/Complex/Module.lean +++ b/Mathlib/LinearAlgebra/Complex/Module.lean @@ -491,6 +491,19 @@ lemma ComplexStarModule.ext_iff {x y : A} : x = y ↔ ℜ x = ℜ y ∧ ℑ x = mp := by grind mpr h := ext h.1 h.2 +section StarHomClass + +variable {B F : Type*} [AddCommGroup B] [Module ℂ B] [StarAddMonoid B] [StarModule ℂ B] + [FunLike F A B] [StarHomClass F A B] [LinearMapClass F ℂ A B] + +lemma map_realPart (f : F) (x : A) : f (ℜ x) = ℜ (f x) := by + simp [realPart_apply_coe, ← Complex.coe_smul, map_star] + +lemma map_imaginaryPart (f : F) (x : A) : f (ℑ x) = ℑ (f x) := by + simp [imaginaryPart_apply_coe, ← Complex.coe_smul, map_star] + +end StarHomClass + @[simp] theorem ker_imaginaryPart : imaginaryPart.ker = selfAdjoint.submodule ℝ A := by ext x @@ -638,4 +651,14 @@ lemma mem_unitary_iff_isStarNormal_and_realPart_sq_add_imaginaryPart_sq_eq_one [ exact ⟨this, by simp [sq, ← star_mul_self_eq_realPart_sq_add_imaginaryPart_sq x, h]⟩ · simp [← hx.star_comm_self.eq, star_mul_self_eq_realPart_sq_add_imaginaryPart_sq, ← sq, h] +instance {F E A : Type*} [AddCommGroup E] [PartialOrder E] + [StarAddMonoid E] [SelfAdjointDecompose E] [Module ℂ E] [StarModule ℂ E] + [NonUnitalRing A] [PartialOrder A] [StarRing A] + [StarOrderedRing A] [Module ℂ A] [StarModule ℂ A] + [FunLike F E A] [OrderHomClass F E A] [LinearMapClass F ℂ E A] : + StarHomClass F E A where + map_star φ x := by + rw [← realPart_add_I_smul_imaginaryPart x] + simp [(ℜ x).2.map' φ, IsSelfAdjoint.star_eq, (ℑ x).2.map' φ] + end RealImaginaryPart From 8b654812405b70d267f42ee5d967ab350721c1f0 Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:46:24 +0000 Subject: [PATCH 0295/1300] doc: add wikidata attributes (#40861) This PR adds a batch of 25 `@[wikidata]` attributes. Claude helped generate the list of crossrefs (by scanning Wikidata + Mathlib). Comments are generated by [crossref-report](https://github.com/jcommelin/mathlib-crossref-report) and Wikilean. See https://wikilean.jackmccarthy.org/review?pr=40861 for reviewer UI. Co-authored-by: wikilean-bot --- Mathlib/Algebra/LinearRecurrence.lean | 2 ++ Mathlib/Analysis/InnerProductSpace/PiL2.lean | 2 ++ Mathlib/LinearAlgebra/Basis/Defs.lean | 2 ++ Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean | 2 ++ Mathlib/LinearAlgebra/Dual/Defs.lean | 2 ++ Mathlib/LinearAlgebra/RootSystem/Defs.lean | 2 ++ .../MeasureTheory/Function/ConditionalExpectation/Basic.lean | 2 ++ .../Integral/IntervalIntegral/IntegrationByParts.lean | 2 ++ .../Integral/IntervalIntegral/TrapezoidalRule.lean | 2 ++ Mathlib/NumberTheory/LSeries/RiemannZeta.lean | 1 + Mathlib/Order/Filter/Extr.lean | 2 ++ Mathlib/RingTheory/LocalRing/ResidueField/Defs.lean | 2 ++ Mathlib/Topology/Algebra/Module/LocallyConvex.lean | 2 ++ Mathlib/Topology/UniformSpace/Cauchy.lean | 2 ++ 14 files changed, 27 insertions(+) diff --git a/Mathlib/Algebra/LinearRecurrence.lean b/Mathlib/Algebra/LinearRecurrence.lean index 6634b8b7951ff4..cbbc654009610a 100644 --- a/Mathlib/Algebra/LinearRecurrence.lean +++ b/Mathlib/Algebra/LinearRecurrence.lean @@ -8,6 +8,7 @@ module public import Mathlib.Algebra.Polynomial.Degree.Operations public import Mathlib.Algebra.Polynomial.Eval.Defs public import Mathlib.LinearAlgebra.Dimension.Constructions +public import Mathlib.Tactic.CrossRefAttribute /-! # Linear recurrence @@ -48,6 +49,7 @@ open Polynomial /-- A "linear recurrence relation" over a commutative semiring is given by its order `n` and `n` coefficients. -/ +@[wikidata Q364089] structure LinearRecurrence (R : Type*) [CommSemiring R] where /-- Order of the linear recurrence -/ order : ℕ diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 9836ea7f5a2ede..f915ca4763ad8d 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.Normed.Lp.PiLp public import Mathlib.Analysis.Normed.Lp.Matrix public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas public import Mathlib.LinearAlgebra.UnitaryGroup +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Util.Superscript /-! @@ -108,6 +109,7 @@ space use `EuclideanSpace 𝕜 (Fin n)`. For the case when `n = Fin _`, there is `!₂[x, y, ...]` notation for building elements of this type, analogous to `![x, y, ...]` notation. -/ +@[wikidata Q17295] abbrev EuclideanSpace (𝕜 : Type*) (n : Type*) : Type _ := PiLp 2 fun _ : n => 𝕜 diff --git a/Mathlib/LinearAlgebra/Basis/Defs.lean b/Mathlib/LinearAlgebra/Basis/Defs.lean index c66920d1a2c6eb..c4ff6d939ed635 100644 --- a/Mathlib/LinearAlgebra/Basis/Defs.lean +++ b/Mathlib/LinearAlgebra/Basis/Defs.lean @@ -6,6 +6,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Alexander Bentkamp module public import Mathlib.LinearAlgebra.Finsupp.LinearCombination +public import Mathlib.Tactic.CrossRefAttribute /-! # Bases @@ -85,6 +86,7 @@ To turn a linear independent family of vectors spanning `M` into a basis, use `B They are internally represented as linear equivs `M ≃ₗ[R] (ι →₀ R)`, available as `Basis.repr`. -/ +@[wikidata Q189569] structure Basis where /-- `Basis.ofRepr` constructs a basis given an assignment of coordinates to each vector. -/ ofRepr :: diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean index d6eb7a6bedd007..33ca6fe5da724c 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean @@ -9,6 +9,7 @@ public import Mathlib.RingTheory.Congruence.Hom public import Mathlib.LinearAlgebra.TensorAlgebra.Basic public import Mathlib.LinearAlgebra.QuadraticForm.Isometry public import Mathlib.LinearAlgebra.QuadraticForm.IsometryEquiv +public import Mathlib.Tactic.CrossRefAttribute /-! # Clifford Algebras @@ -69,6 +70,7 @@ end CliffordAlgebra /-- The Clifford algebra of an `R`-module `M` equipped with a `QuadraticForm` `Q`. -/ +@[wikidata Q674689] def CliffordAlgebra := CliffordAlgebra.ringCon Q |>.Quotient deriving Inhabited, Ring, Algebra R diff --git a/Mathlib/LinearAlgebra/Dual/Defs.lean b/Mathlib/LinearAlgebra/Dual/Defs.lean index 62a06d2c073886..0323991b305053 100644 --- a/Mathlib/LinearAlgebra/Dual/Defs.lean +++ b/Mathlib/LinearAlgebra/Dual/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.LinearAlgebra.BilinearMap public import Mathlib.LinearAlgebra.Span.Defs +public import Mathlib.Tactic.CrossRefAttribute /-! # Dual vector spaces @@ -57,6 +58,7 @@ variable (R A M : Type*) variable [CommSemiring R] [AddCommMonoid M] [Module R M] /-- The left dual space of an R-module M is the R-module of linear maps `M → R`. -/ +@[wikidata Q752487] abbrev Dual (R M : Type*) [Semiring R] [AddCommMonoid M] [Module R M] := M →ₗ[R] R diff --git a/Mathlib/LinearAlgebra/RootSystem/Defs.lean b/Mathlib/LinearAlgebra/RootSystem/Defs.lean index 1b5b341eac3111..3dd44ce2f78b71 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Defs.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.LinearAlgebra.PerfectPairing.Basic public import Mathlib.LinearAlgebra.Reflection +public import Mathlib.Tactic.CrossRefAttribute /-! # Root data and root systems @@ -113,6 +114,7 @@ variable {ι R M N} variable (P : RootPairing ι R M N) (i j : ι) /-- A root system is a root pairing for which the roots and coroots span their ambient modules. -/ +@[wikidata Q534131] class IsRootSystem : Prop where span_root_eq_top : span R (range P.root) = ⊤ span_coroot_eq_top : span R (range P.coroot) = ⊤ diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean index fda5b38bd6fb45..6cfccad643f8bb 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean @@ -6,6 +6,7 @@ Authors: Rémy Degenne module public import Mathlib.MeasureTheory.Function.ConditionalExpectation.CondexpL1 +public import Mathlib.Tactic.CrossRefAttribute import Mathlib.MeasureTheory.Function.LpSpace.InfiniteSum @@ -97,6 +98,7 @@ It is defined as 0 if any one of the following conditions is true: - `m` is not a sub-σ-algebra of `m₀`, - `μ` is not σ-finite with respect to `m`, - `f` is not integrable. -/ +@[wikidata Q772232] noncomputable irreducible_def condExp (μ : Measure[m₀] α) (f : α → E) : α → E := if hm : m ≤ m₀ then if h : SigmaFinite (μ.trim hm) ∧ Integrable f μ then diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean index 7e7ca233026342..358f01e9d06fb1 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean @@ -7,6 +7,7 @@ module public import Mathlib.MeasureTheory.Function.JacobianOneDim public import Mathlib.MeasureTheory.Integral.IntervalIntegral.FundThmCalculus +public import Mathlib.Tactic.CrossRefAttribute /-! # Integration by parts and by substitution @@ -526,6 +527,7 @@ theorem integral_comp_mul_deriv' {f f' g : ℝ → ℝ} (h : ∀ x ∈ uIcc a b, and `g` is continuous, then we can substitute `u = f x` to get `∫ x in a..b, (g ∘ f) x * f' x = ∫ u in f a..f b, g u`. -/ +@[wikidata Q1071270] theorem integral_comp_mul_deriv {f f' g : ℝ → ℝ} (h : ∀ x ∈ uIcc a b, HasDerivAt f (f' x) x) (h' : ContinuousOn f' (uIcc a b)) (hg : Continuous g) : (∫ x in a..b, (g ∘ f) x * f' x) = ∫ x in f a..f b, g x := diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean index 243d55e8c4436f..0fe73938b60340 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean @@ -6,6 +6,7 @@ Authors: P. Michael Kielstra module public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.Field /-! @@ -29,6 +30,7 @@ open MeasureTheory intervalIntegral Interval Finset HasDerivWithinAt Set /-- Integration of `f` from `a` to `b` using the trapezoidal rule with `N+1` total evaluations of `f`. (Note the off-by-one problem here: `N` counts the number of trapezoids, not the number of evaluations.) -/ +@[wikidata Q833293] noncomputable def trapezoidal_integral (f : ℝ → ℝ) (N : ℕ) (a b : ℝ) : ℝ := ((b - a) / N) * ((f a + f b) / 2 + ∑ k ∈ range (N - 1), f (a + (k + 1) * (b - a) / N)) diff --git a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean index fdff2c94adcfd8..3c92195fce20df 100644 --- a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean +++ b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean @@ -117,6 +117,7 @@ lemma completedRiemannZeta_residue_one : -/ /-- The Riemann zeta function `ζ(s)`. -/ +@[wikidata Q187235] def riemannZeta := hurwitzZetaEven 0 lemma HurwitzZeta.hurwitzZetaEven_zero : hurwitzZetaEven 0 = riemannZeta := rfl diff --git a/Mathlib/Order/Filter/Extr.lean b/Mathlib/Order/Filter/Extr.lean index 0c646f48feabca..f8337827d8f967 100644 --- a/Mathlib/Order/Filter/Extr.lean +++ b/Mathlib/Order/Filter/Extr.lean @@ -9,6 +9,7 @@ public import Mathlib.Order.Filter.Tendsto public import Mathlib.Order.ConditionallyCompleteLattice.Indexed public import Mathlib.Algebra.Order.Group.Defs public import Mathlib.Data.Finset.Lattice.Fold +public import Mathlib.Tactic.CrossRefAttribute /-! # Minimum and maximum w.r.t. a filter and on a set @@ -114,6 +115,7 @@ def IsMaxOn := IsMaxFilter f (𝓟 s) a /-- `IsExtrOn f s a` means `IsMinOn f s a` or `IsMaxOn f s a` -/ +@[wikidata Q845060] def IsExtrOn : Prop := IsExtrFilter f (𝓟 s) a diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Defs.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Defs.lean index 5841aa7aa67bef..dd141c6c82a710 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Defs.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.RingTheory.Ideal.Quotient.Basic public import Mathlib.RingTheory.LocalRing.MaximalIdeal.Basic +public import Mathlib.Tactic.CrossRefAttribute /-! @@ -25,6 +26,7 @@ namespace IsLocalRing variable (R : Type*) [CommRing R] [IsLocalRing R] /-- The residue field of a local ring is the quotient of the ring by its maximal ideal. -/ +@[wikidata Q7315530] def ResidueField := R ⧸ maximalIdeal R deriving CommRing, Inhabited diff --git a/Mathlib/Topology/Algebra/Module/LocallyConvex.lean b/Mathlib/Topology/Algebra/Module/LocallyConvex.lean index c252b2838872f4..c73f0cfd0adb75 100644 --- a/Mathlib/Topology/Algebra/Module/LocallyConvex.lean +++ b/Mathlib/Topology/Algebra/Module/LocallyConvex.lean @@ -6,6 +6,7 @@ Authors: Anatole Dedecker module public import Mathlib.Analysis.Convex.Topology +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.Connected.LocallyPathConnected public import Mathlib.Analysis.Convex.PathConnected @@ -46,6 +47,7 @@ section Semimodule /-- A `LocallyConvexSpace` is a topological semimodule over an ordered semiring in which convex neighborhoods of a point form a neighborhood basis at that point. -/ +@[wikidata Q1572357] class LocallyConvexSpace (𝕜 E : Type*) [Semiring 𝕜] [PartialOrder 𝕜] [AddCommMonoid E] [Module 𝕜 E] [TopologicalSpace E] : Prop where convex_basis : ∀ x : E, (𝓝 x).HasBasis (fun s : Set E => s ∈ 𝓝 x ∧ Convex 𝕜 s) id diff --git a/Mathlib/Topology/UniformSpace/Cauchy.lean b/Mathlib/Topology/UniformSpace/Cauchy.lean index 343f98439c2ac3..74fd21c99e4b5b 100644 --- a/Mathlib/Topology/UniformSpace/Cauchy.lean +++ b/Mathlib/Topology/UniformSpace/Cauchy.lean @@ -5,6 +5,7 @@ Authors: Johannes Hölzl, Mario Carneiro -/ module +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.Algebra.Constructions public import Mathlib.Topology.Bases public import Mathlib.Algebra.Order.Group.Nat @@ -365,6 +366,7 @@ theorem isComplete_iUnion_separated {ι : Sort*} {s : ι → Set α} (hs : ∀ i /-- A complete space is defined here using uniformities. A uniform space is complete if every Cauchy filter converges. -/ +@[wikidata Q848569] class CompleteSpace (α : Type u) [UniformSpace α] : Prop where /-- In a complete uniform space, every Cauchy filter converges. -/ complete : ∀ {f : Filter α}, Cauchy f → ∃ x, f ≤ 𝓝 x From 778bd8fa0d3511efda61642ac6e6907c3bf481cc Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:50:10 +0000 Subject: [PATCH 0296/1300] =?UTF-8?q?feat:=20`=CF=80=E2=82=81(E=E2=A7=B8G)?= =?UTF-8?q?=20=E2=89=83*=20Multiplicative=20G`=20for=20`E`=20simply=20conn?= =?UTF-8?q?ected=20(#40947)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the additive version of #33108 --- Mathlib/GroupTheory/GroupAction/Basic.lean | 8 +++ Mathlib/Topology/Covering/Quotient.lean | 20 ++++++ Mathlib/Topology/Homotopy/Lifting.lean | 80 ++++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/Mathlib/GroupTheory/GroupAction/Basic.lean b/Mathlib/GroupTheory/GroupAction/Basic.lean index 4c8a3f07e6cf7b..73dfdc011f2e33 100644 --- a/Mathlib/GroupTheory/GroupAction/Basic.lean +++ b/Mathlib/GroupTheory/GroupAction/Basic.lean @@ -359,3 +359,11 @@ lemma Module.stabilizer_units_eq_bot_of_ne_zero {x : M} (hx : x ≠ 0) : rw [← sub_eq_zero, ← smul_eq_zero_iff_left hx, Units.val_one, sub_smul, hg, one_smul, sub_self] end + +@[simp] lemma Multiplicative.mulAction_orbit {α β : Type*} [VAdd α β] (b : β) : + MulAction.orbit (Multiplicative α) b = AddAction.orbit α b := + rfl + +@[simp] lemma Additive.mulAction_orbit {α β : Type*} [SMul α β] (b : β) : + AddAction.orbit (Additive α) b = MulAction.orbit α b := + rfl diff --git a/Mathlib/Topology/Covering/Quotient.lean b/Mathlib/Topology/Covering/Quotient.lean index 931aaa815baca6..476030c955bc6e 100644 --- a/Mathlib/Topology/Covering/Quotient.lean +++ b/Mathlib/Topology/Covering/Quotient.lean @@ -41,6 +41,26 @@ structure IsQuotientCoveringMap : Prop extends IsQuotientMap f, ContinuousConstS attribute [to_additive] isQuotientCoveringMap_iff +lemma IsAddQuotientCoveringMap.toMultiplicative (G) [AddGroup G] [AddAction G E] + (hf : IsAddQuotientCoveringMap f G) : + IsQuotientCoveringMap f (Multiplicative G) where + __ := hf.toIsQuotientMap + continuous_const_smul g := by simpa using hf.continuous_const_vadd (Multiplicative.ofAdd.symm g) + apply_eq_iff_mem_orbit {e₁ e₂} := by simp [hf.apply_eq_iff_mem_orbit] + disjoint e := by + obtain ⟨U, hU, hU'⟩ := hf.disjoint e + exact ⟨U, hU, fun g ↦ by simpa using hU' (Multiplicative.ofAdd.symm g)⟩ + +lemma IsQuotientCoveringMap.toAdditive (G) [Group G] [MulAction G E] + (hf : IsQuotientCoveringMap f G) : + IsAddQuotientCoveringMap f (Additive G) where + __ := hf.toIsQuotientMap + continuous_const_vadd g := by simpa using hf.continuous_const_smul (Additive.ofMul.symm g) + apply_eq_iff_mem_orbit {e₁ e₂} := by simp [hf.apply_eq_iff_mem_orbit] + disjoint e := by + obtain ⟨U, hU, hU'⟩ := hf.disjoint e + exact ⟨U, hU, fun g ↦ by simpa using hU' (Additive.ofMul.symm g)⟩ + namespace IsQuotientCoveringMap @[to_additive] theorem subgroup_congr (S S' : Subgroup G) (eq : S = S') : diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index 7c5fb225dd713b..d6bb44b3bfee66 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -681,3 +681,83 @@ def fundamentalGroupEquiv [SimplyConnectedSpace E] : hp.fundamentalGroupToMulOpposite_surjective e⟩ end IsQuotientCoveringMap + +namespace IsAddQuotientCoveringMap + +variable {G : Type*} [AddGroup G] [AddAction G E] (hp : IsAddQuotientCoveringMap p G) {g : G} + +theorem monodromy_toPermFiber {x y : X} {γ : Path.Homotopic.Quotient x y} {e : p ⁻¹' {x}} : + letI monodromy := hp.isCoveringMap.monodromy + monodromy γ (hp.toMultiplicative.toPermFiber x g e) = + hp.toMultiplicative.toPermFiber y g (monodromy γ e) := + hp.toMultiplicative.monodromy_toPermFiber + +theorem commute_monodromyPerm_toPermFiber {x : X} {γ : FundamentalGroup X x} : + Commute + (hp.isCoveringMap.monodromyPerm x γ) + (hp.toMultiplicative.toPermFiber x g) := + hp.toMultiplicative.commute_monodromyPerm_toPermFiber + +theorem monodromy_ext_iff {x y : X} {γ γ' : Path.Homotopic.Quotient x y} (e : p ⁻¹' {x}) : + letI monodromy := hp.isCoveringMap.monodromy + monodromy γ e = monodromy γ' e ↔ monodromy γ = monodromy γ' := + hp.toMultiplicative.monodromy_ext_iff e + +alias ⟨monodromy_ext, _⟩ := monodromy_ext_iff + +variable {x : X} (e : p ⁻¹' {x}) {γ : FundamentalGroup X x} + +theorem monodromy_eq_id_iff : + hp.isCoveringMap.monodromy γ = id ↔ hp.isCoveringMap.monodromy γ e = e := + hp.toMultiplicative.monodromy_eq_id_iff e + +theorem ker_monodromyPerm : + (hp.isCoveringMap.monodromyPerm x).ker = + (FundamentalGroup.mapOfEq ⟨p, hp.continuous⟩ e.2).range := + hp.toMultiplicative.ker_monodromyPerm e + +theorem monodromyPerm_injective [SimplyConnectedSpace E] : + Injective (hp.isCoveringMap.monodromyPerm x) := + hp.toMultiplicative.monodromyPerm_injective + +/-- Choosing an arbitrary basepoint `e ∈ f ⁻¹' {x}` induces a bijection `f ⁻¹' {x} ≃ G`, and the +`G`-action on `f ⁻¹' {x}` corresponds to left multiplication. The monodromy action commutes +with the `G`-action, so each monodromy must corresponds must correspond to a right multiplication. +-/ +def fundamentalGroupToMulOpposite : FundamentalGroup X x →* (Multiplicative G)ᵐᵒᵖ := + hp.toMultiplicative.fundamentalGroupToMulOpposite e + +variable {e} in +theorem fundamentalGroupToMulOpposite_apply_eq_Iff {g : (Multiplicative G)ᵐᵒᵖ} : + hp.fundamentalGroupToMulOpposite e γ = g ↔ g.unop • e.1 = hp.isCoveringMap.monodromy γ e := + hp.toMultiplicative.fundamentalGroupToMulOpposite_apply_eq_Iff + +variable {e} in +theorem unop_fundamentalGroupToMulOpposite_smul : + (hp.fundamentalGroupToMulOpposite e γ).unop • e.1 = hp.isCoveringMap.monodromy γ e := + hp.toMultiplicative.unop_fundamentalGroupToMulOpposite_smul + +variable {e} in +theorem fundamentalGroupToMulOpposite_eq_one_iff : + hp.fundamentalGroupToMulOpposite e γ = 1 ↔ hp.isCoveringMap.monodromy γ e = e := + hp.toMultiplicative.fundamentalGroupToMulOpposite_eq_one_iff + +theorem ker_fundamentalGroupToMulOpposite : + (hp.fundamentalGroupToMulOpposite e).ker = (hp.isCoveringMap.monodromyPerm x).ker := + hp.toMultiplicative.ker_fundamentalGroupToMulOpposite e + +theorem fundamentalGroupToMulOpposite_surjective [PathConnectedSpace E] : + Surjective (hp.fundamentalGroupToMulOpposite e) := + hp.toMultiplicative.fundamentalGroupToMulOpposite_surjective e + +lemma fundamentalGroupToMulOpposite_injective [SimplyConnectedSpace E] : + Injective (hp.fundamentalGroupToMulOpposite e) := + hp.toMultiplicative.fundamentalGroupToMulOpposite_injective e + +/-- The fundamental group of the base of simply-connected covering map is contravariantly +equivalent to the group of the covering map. -/ +def fundamentalGroupEquiv [SimplyConnectedSpace E] : + FundamentalGroup X x ≃* (Multiplicative G)ᵐᵒᵖ := + hp.toMultiplicative.fundamentalGroupEquiv e + +end IsAddQuotientCoveringMap From a0c885bf3a591b29b29120f070fa7c1e4121c951 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 23 Jun 2026 17:27:13 +0000 Subject: [PATCH 0297/1300] chore(Data/List/InsertNth): delete stub file (#40962) As the file itself explains, it can be removed now. The module was emptied in #17985. --- Mathlib.lean | 1 - Mathlib/Data/List/InsertNth.lean | 18 ------------------ 2 files changed, 19 deletions(-) delete mode 100644 Mathlib/Data/List/InsertNth.lean diff --git a/Mathlib.lean b/Mathlib.lean index 001a649d202c66..4fc076a92d63d5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4053,7 +4053,6 @@ public import Mathlib.Data.List.Indexes public import Mathlib.Data.List.Induction public import Mathlib.Data.List.Infix public import Mathlib.Data.List.InsertIdx -public import Mathlib.Data.List.InsertNth public import Mathlib.Data.List.Intervals public import Mathlib.Data.List.Iterate public import Mathlib.Data.List.Lattice diff --git a/Mathlib/Data/List/InsertNth.lean b/Mathlib/Data/List/InsertNth.lean deleted file mode 100644 index 56dc8fbabb529d..00000000000000 --- a/Mathlib/Data/List/InsertNth.lean +++ /dev/null @@ -1,18 +0,0 @@ -/- -Copyright (c) 2024 Lean FRO. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kim Morrison --/ -module - -public import Mathlib.Tactic.Common -public import Mathlib.Util.CompileInductive - -/-! -This is a stub file for importing `Mathlib/Data/List/InsertNth.lean`, -which has been renamed to `Mathlib/Data/List/InsertIdx.lean`. - -This file can be removed once the deprecation for `List.insertNth` is removed. --/ - -public section From 3a6310fe915f51a4701645394d8714192e984ca2 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Tue, 23 Jun 2026 18:34:10 +0000 Subject: [PATCH 0298/1300] fix(cache): skip fork-PR diagnostics on nightly-testing (#40958) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On `nightly-testing` / `nightly-testing-green`, `cache get` prints a spurious "no cache found for HEAD … on fork …" note and `cache query` reports "no cached CI build found for fork …", even though the cache reads fine from the `nightly-testing` container. These are fork-PR diagnostics about the per-commit `forks` namespace. They gated on "is `forks` in the read chain", which became true for the nightly-testing repo once it gained a `forks` fallback (#40770) so they now misfire on the canonical repos. Gate on a new `isCanonicalRepo` predicate instead; `cache query` on a canonical repo now says it only applies to fork PRs. Follow-up to #40770 / #40035. --- Cache/Infra.lean | 5 +++++ Cache/Query.lean | 12 +++++++++++- Cache/Warning.lean | 6 +++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Cache/Infra.lean b/Cache/Infra.lean index 99f6fc271f52e0..6379923853ba72 100644 --- a/Cache/Infra.lean +++ b/Cache/Infra.lean @@ -24,6 +24,11 @@ def MATHLIBREPO := "leanprover-community/mathlib4" /-- The full name of the Mathlib nightly-testing GitHub repository. -/ def NIGHTLY_TESTING_REPO := "leanprover-community/mathlib4-nightly-testing" +/-- Whether `repo` is a first-party Mathlib repo rather than a fork. Forks cache +into the per-commit `forks` namespace; the canonical repos do not. -/ +def isCanonicalRepo (repo : String) : Bool := + repo == MATHLIBREPO || repo == NIGHTLY_TESTING_REPO + /-- Canonical form of a GitHub `owner/repo` name for use as a cache blob path segment. diff --git a/Cache/Query.lean b/Cache/Query.lean index 8dd967501722be..2721183acdf9ea 100644 --- a/Cache/Query.lean +++ b/Cache/Query.lean @@ -161,9 +161,15 @@ def resolveQueryRepo (repoExplicit? : Option String) : IO String := do Boolean probe for a single commit: prints `cached` or `not cached` and exits with status 0 / 1 respectively. Intended for scripting. -Probes the `forks` container's per-SHA marker, the only SHA-scoped container. +Probes the `forks` per-SHA marker, the only SHA-scoped container. Canonical repos +have no per-commit namespace, so it exits non-zero with a note instead of a +misleading `not cached`. -/ def cacheQuerySingle (repo sha : String) : IO Unit := do + if isCanonicalRepo repo then + IO.eprintln s!"{repo} caches by file hash, not per commit, so there is no per-commit build to query." + (← IO.getStderr).flush + IO.Process.exit 1 let cached ← probeContainerForSHA Container.forks repo sha if cached then IO.println s!"cached: {sha}" @@ -183,6 +189,10 @@ This is a diagnostic-only command: it prints the SHA to stdout but does not auto-apply it. The user manually passes the result to `cache get` if desired. -/ def cacheQuery (repo : String) (cap : Nat := 50) (cwd : FilePath := ".") : IO Unit := do + if isCanonicalRepo repo then + IO.println s!"`cache query` locates a fork PR's per-commit cache. {repo} reads \ + its own cache container directly, so there is nothing to query for it." + return -- Determine merge base with master. If not reachable, use cap-only walk. let mergeBase? ← gitMergeBase "master" cwd let stopRef := mergeBase?.getD "" diff --git a/Cache/Warning.lean b/Cache/Warning.lean index 2aba0a12428b87..c878c90028c800 100644 --- a/Cache/Warning.lean +++ b/Cache/Warning.lean @@ -179,8 +179,8 @@ Fires only on naive `cache get` invocations: picked a scope and the non-default-scope warning is doing the talking) - no `--cache-from` override (else they've already taken explicit responsibility for the lookup chain) -- the resolved repo's default lookup chain reads from `forks` (otherwise SHA - scoping is not relevant) +- the repo is a fork, not a first-party repo: the canonical repos don't build + into the per-commit `forks` namespace this note checks - HEAD is not already an ancestor of `master`. From a personal-fork checkout sitting on `master` (or an undiverged branch), the fork's SHA-scoped marker is structurally absent, but `master` is first in the fork lookup chain and serves @@ -195,7 +195,7 @@ mix with `cache get`'s stdout output. def informIfHeadNotBuilt (repo : String) : IO Unit := do if (← getRepoScope).isSome then return if (← cacheFromOverride.get).isSome then return - unless (defaultContainersForRepo repo).contains Container.forks do return + if isCanonicalRepo repo then return -- HEAD already on (an ancestor of) master: master CI builds these commits and -- the master container (first in the fork lookup chain) serves their artifacts -- by hash, so there is nothing fork-specific to build. The forks marker is From b4c2709405383ebfbd798defaafcfcd33dd8359e Mon Sep 17 00:00:00 2001 From: FordUniver <61389961+FordUniver@users.noreply.github.com> Date: Tue, 23 Jun 2026 18:56:55 +0000 Subject: [PATCH 0299/1300] feat(Analysis/Calculus/Gradient): add `toDual_gradient` and companions (#39202) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `toDual_gradient`, `toDual_gradientWithin`, and the composed variants `toDual_comp_gradient`, `toDual_comp_gradientWithin` — the natural inverse direction of the gradient's defining equation `∇ f x := (toDual 𝕜 F).symm (fderiv 𝕜 f x)`. These identify `(toDual 𝕜 F) (∇ f x)` with `fderiv 𝕜 f x` (and the `gradientWithin` and composed forms with the corresponding fderiv versions), making the Riesz isomorphism between the two derivative views explicit. The proofs of `DifferentiableAt.hasGradientAt` and `DifferentiableWithinAt.hasGradientWithinAt` in the same file are simplified to use them. Co-authored-by: Sebastian Pokutta <23001135+pokutta@users.noreply.github.com> Co-authored-by: Christoph Spiegel --- Mathlib/Analysis/Calculus/Gradient/Basic.lean | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Gradient/Basic.lean b/Mathlib/Analysis/Calculus/Gradient/Basic.lean index 3722367d7b138f..e954b2d8320958 100644 --- a/Mathlib/Analysis/Calculus/Gradient/Basic.lean +++ b/Mathlib/Analysis/Calculus/Gradient/Basic.lean @@ -118,6 +118,24 @@ alias ⟨HasFDerivAt.hasGradientAt, _⟩ := hasFDerivAt_iff_hasGradientAt theorem gradient_eq_zero_of_not_differentiableAt (h : ¬DifferentiableAt 𝕜 f x) : ∇ f x = 0 := by rw [gradient, fderiv_zero_of_not_differentiableAt h, map_zero] +@[simp] +lemma toDual_gradientWithin : + (toDual 𝕜 F) (gradientWithin f s x) = fderivWithin 𝕜 f s x := by + rw [gradientWithin, (toDual 𝕜 F).apply_symm_apply] + +@[simp] +lemma toDual_gradient : (toDual 𝕜 F) (∇ f x) = fderiv 𝕜 f x := by + rw [gradient, (toDual 𝕜 F).apply_symm_apply] + +@[simp] +lemma toDual_comp_gradientWithin : + (toDual 𝕜 F) ∘ gradientWithin f s = fderivWithin 𝕜 f s := + funext fun _ => toDual_gradientWithin + +@[simp] +lemma toDual_comp_gradient : (toDual 𝕜 F) ∘ ∇ f = fderiv 𝕜 f := + funext fun _ => toDual_gradient + theorem HasGradientAt.unique {gradf gradg : F} (hf : HasGradientAt f gradf x) (hg : HasGradientAt f gradg x) : gradf = gradg := @@ -125,8 +143,7 @@ theorem HasGradientAt.unique {gradf gradg : F} theorem DifferentiableAt.hasGradientAt (h : DifferentiableAt 𝕜 f x) : HasGradientAt f (∇ f x) x := by - rw [hasGradientAt_iff_hasFDerivAt, gradient, (toDual 𝕜 F).apply_symm_apply (fderiv 𝕜 f x)] - exact h.hasFDerivAt + simpa [hasGradientAt_iff_hasFDerivAt] using h.hasFDerivAt theorem HasGradientAt.differentiableAt (h : HasGradientAt f f' x) : DifferentiableAt 𝕜 f x := @@ -134,9 +151,7 @@ theorem HasGradientAt.differentiableAt (h : HasGradientAt f f' x) : theorem DifferentiableWithinAt.hasGradientWithinAt (h : DifferentiableWithinAt 𝕜 f s x) : HasGradientWithinAt f (gradientWithin f s x) s x := by - rw [hasGradientWithinAt_iff_hasFDerivWithinAt, gradientWithin, - (toDual 𝕜 F).apply_symm_apply (fderivWithin 𝕜 f s x)] - exact h.hasFDerivWithinAt + simpa [hasGradientWithinAt_iff_hasFDerivWithinAt] using h.hasFDerivWithinAt theorem HasGradientWithinAt.differentiableWithinAt (h : HasGradientWithinAt f f' s x) : DifferentiableWithinAt 𝕜 f s x := From 397c8ebf720aaa3418a0f4d96591ba74e137963e Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 23 Jun 2026 20:09:38 +0000 Subject: [PATCH 0300/1300] fix(ClickSuggestions): set up the config correctly (#40956) This PR fixes the bug in `#click_suggestions` reported at https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.23click_suggestions.20doesn.27t.20find.20lemma/with/605957884 The problem was that `#click_suggestion` was using the default meta configuration, rather than the elaboration meta configuration. Unfortunately, it's not possible to add a test for this; due to how the tests work, the config there is already set to the elaboration meta config. I have verified locally that this PR fixes the original problem. --- Mathlib/Tactic/ClickSuggestions.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Tactic/ClickSuggestions.lean b/Mathlib/Tactic/ClickSuggestions.lean index 7c6ea97903033a..0164cde3a2f665 100644 --- a/Mathlib/Tactic/ClickSuggestions.lean +++ b/Mathlib/Tactic/ClickSuggestions.lean @@ -129,7 +129,7 @@ public def rpc (props : PanelWidgetProps) : RequestM (RequestTask Html) := let goals := if useAfter then tacticInfo.goalsAfter else tacticInfo.goalsBefore goals.contains loc.mvarId | return .text "#click_suggestions: Please reload the tactic state" - goal.ctx.val.runMetaM {} do loc.mvarId.withContext do + goal.ctx.val.runMetaM {} do withConfig Elab.Term.setElabConfig do loc.mvarId.withContext do let (statusHtml, statusToken) ← mkRefreshComponent let (solvedHtml, solvedToken) ← mkRefreshComponent let targetHtml ← From d9a189b1cceddaa57dd921ba74c1d5aaf51d0a13 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 23 Jun 2026 21:10:28 +0000 Subject: [PATCH 0301/1300] =?UTF-8?q?feat(RingTheory):=20category=20of=20f?= =?UTF-8?q?inite=20=C3=A9tale=20algebras=20over=20a=20separably=20closed?= =?UTF-8?q?=20field=20(#38054)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We define the category of finite étale `R`-algebras for a ring `R` and show it is equivalent to `FintypeCat` if `R` is a separably closed field. From Pi1. --- Mathlib.lean | 1 + .../IntermediateField/Adjoin/Basic.lean | 5 + Mathlib/RingTheory/Etale/Finite.lean | 193 ++++++++++++++++++ Mathlib/RingTheory/TensorProduct/Maps.lean | 13 ++ Mathlib/RingTheory/TotallySplit.lean | 6 + 5 files changed, 218 insertions(+) create mode 100644 Mathlib/RingTheory/Etale/Finite.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4fc076a92d63d5..d3f6317619d23a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6506,6 +6506,7 @@ public import Mathlib.RingTheory.EssentialFiniteness public import Mathlib.RingTheory.Etale.Basic public import Mathlib.RingTheory.Etale.Descent public import Mathlib.RingTheory.Etale.Field +public import Mathlib.RingTheory.Etale.Finite public import Mathlib.RingTheory.Etale.Kaehler public import Mathlib.RingTheory.Etale.Locus public import Mathlib.RingTheory.Etale.Pi diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean index a1f6d27897f034..b6280f1e11761d 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean @@ -784,3 +784,8 @@ theorem AdjoinPair.algebraMap_gen₂ : (algebraMap (↥K⟮x, y⟯) L) (gen₂ K end AdjoinPair end IntermediateField + +instance (R : Type*) [CommSemiring R] (K : Type*) [Field K] [Algebra R K] + (S : Type*) [Semiring S] [Algebra R S] [Module.Finite R S] : + Finite (S →ₐ[R] K) := + .of_equiv _ (Algebra.TensorProduct.liftEquivRight _ K _ _).symm diff --git a/Mathlib/RingTheory/Etale/Finite.lean b/Mathlib/RingTheory/Etale/Finite.lean new file mode 100644 index 00000000000000..18b0bc0c2ac738 --- /dev/null +++ b/Mathlib/RingTheory/Etale/Finite.lean @@ -0,0 +1,193 @@ +/- +Copyright (c) 2026 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +module + +public import Mathlib.Algebra.Category.CommAlgCat.Basic +public import Mathlib.CategoryTheory.FintypeCat +public import Mathlib.RingTheory.TotallySplit + +/-! +# Category of finite étale `R`-algebras + +In this file we define the category of finite étale `R`-algebras over a ring `R`. For any +geometric point `Ω` of `R`, we define a fiber functor sending a finite étale `R`-algebra +`S` to the finite set of `R`-algebra homomorphisms `S →ₐ[R] Ω`. + +## Main definitions + +- `CommAlgCat.FiniteEtale`: The category of finite étale `R`-algebras. +- `CommAlgCat.FiniteEtale.fiber`: For a geometric point `Ω` of `R`, the fiber functor + `S ↦ (S →ₐ[R] Ω)`. + +## Main results + +- `CommAlgCat.FiniteEtale.equivOfIsSepClosed`: If `R = Ω` is separably closed, + the category of finite étale `Ω`-algebras is anti-equivalent to `FintypeCat`. + In particular, the functor `CommAlgCat.FiniteEtale.fiber` is an equivalence + of categories in this case. +-/ + +public section + +open CategoryTheory TensorProduct + +universe v w u + +namespace CommAlgCat + +variable (R : Type u) [CommRing R] (k : Type u) [Field k] + +section + +/-- The object property of finite `R`-algebras. -/ +abbrev finite : ObjectProperty (CommAlgCat.{v} R) := + fun S ↦ Module.Finite R S + +/-- The object property of étale `R`-algebras. -/ +abbrev etale : ObjectProperty (CommAlgCat.{v} R) := + fun S ↦ Algebra.Etale R S + +/-- The object property of finite étale `R`-algebras. -/ +abbrev finiteEtale : ObjectProperty (CommAlgCat.{v} R) := + finite R ⊓ etale R + +/-- The category of finite étale `R`-algebras. -/ +abbrev FiniteEtale (R : Type u) [CommRing R] : Type _ := + (finiteEtale.{v} R).FullSubcategory + +instance : CoeSort (FiniteEtale.{v} R) (Type v) := ⟨fun R ↦ R.obj⟩ + +instance (S : FiniteEtale.{v} R) : Algebra.Etale R S := + S.property.right + +instance (S : FiniteEtale.{v} R) : Module.Finite R S := + S.property.left + +/-- Construct a term of `FiniteEtale R` from a finite étale `R`-algebra. -/ +@[simps obj] +abbrev FiniteEtale.of (S : Type v) [CommRing S] [Algebra R S] + [Module.Finite R S] [Algebra.Etale R S] : + FiniteEtale.{v} R where + obj := .of R S + property := ⟨‹_›, ‹_›⟩ + +variable {R} + +/-- Construct a morphism in `FiniteEtale R` from an algebra map. -/ +@[simps] +abbrev FiniteEtale.ofHom {S T : Type v} [CommRing S] [CommRing T] + [Algebra R S] [Algebra R T] [Module.Finite R S] [Algebra.Etale R S] [Module.Finite R T] + [Algebra.Etale R T] (f : S →ₐ[R] T) : + FiniteEtale.of R S ⟶ FiniteEtale.of R T where + hom := CommAlgCat.ofHom f + +/-- Construct an isomorphism in `FiniteEtale R` from an algebra equivalence. -/ +abbrev FiniteEtale.isoMk {S T : FiniteEtale R} (e : S.obj ≃ₐ[R] T.obj) : + S ≅ T := + ObjectProperty.isoMk _ (CommAlgCat.isoMk e) + +end + +instance (R : FiniteEtale k) : IsArtinianRing R := + have := Algebra.FormallyUnramified.finite_of_free k R + isArtinian_of_tower k inferInstance + +variable (Ω : Type w) [Field Ω] [Algebra R Ω] + (S : Type w) [CommRing S] [Algebra R S] [Algebra S Ω] [IsScalarTower R S Ω] + +/-- If `S` is an `R`-algebra, this is the base change functor `A ↦ S ⊗[R] A`. -/ +@[expose, simps] +def FiniteEtale.baseChange : FiniteEtale.{v} R ⥤ FiniteEtale.{max w v} S where + obj A := .of S (S ⊗[R] A) + map {A B} f := FiniteEtale.ofHom (Algebra.TensorProduct.map (.id _ _) f.hom.hom) + +/-- Base change from `R` to `R` is isomorphic to the identity. -/ +@[expose] +def FiniteEtale.baseChangeSelfIso : baseChange R R ≅ 𝟭 (FiniteEtale R) := + NatIso.ofComponents (fun A ↦ isoMk (Algebra.TensorProduct.lid _ _)) <| fun {A B} f ↦ by + dsimp [baseChange] + ext + simp + +/-- The fiber functor for finite étale `R`-algebras at the geometric point `Ω`: This is the +functor sending `S` to `R`-algebra homomorphisms `S →ₐ[R] Ω`. -/ +@[expose, simps] +def FiniteEtale.fiber (R : Type u) [CommRing R] (Ω : Type w) [Field Ω] [Algebra R Ω] : + (FiniteEtale.{v} R)ᵒᵖ ⥤ FintypeCat.{max v w} where + obj S := .of (S.unop →ₐ[R] Ω) + map {S T} f := FintypeCat.homMk (·.comp f.unop.hom.hom) + +/-- If `k` is a field, this is the `Spec` functor sending a finite étale `k`-algebra `R` +to its finite prime spectrum. -/ +@[expose, simps] +def FiniteEtale.finiteSpec (k : Type u) [Field k] : (FiniteEtale.{v} k)ᵒᵖ ⥤ FintypeCat.{v} where + obj R := .of (PrimeSpectrum R.unop.obj) + map f := FintypeCat.homMk (PrimeSpectrum.comap f.unop.hom.hom) + +set_option backward.defeqAttrib.useBackward true in +/-- If the geometric point `Ω` factors through `S`, the fiber can be computed after base change +to `S`. -/ +@[expose] +def FiniteEtale.fiberIsoBaseChangeFiber : + FiniteEtale.fiber.{v} R Ω ≅ + (FiniteEtale.baseChange.{v} R S).op ⋙ FiniteEtale.fiber S Ω := + NatIso.ofComponents + (fun A ↦ FintypeCat.equivEquivIso (Algebra.TensorProduct.liftEquivRight _ _ _ _)) + +/-- If `Ω` is separably closed, the fiber functor for finite étale `Ω`-algebras +is naturally isomorphic to the (finite) `Spec` functor. -/ +@[expose] +noncomputable def FiniteEtale.fiberIsoFiniteSpec [IsSepClosed Ω] : + FiniteEtale.fiber Ω Ω ≅ FiniteEtale.finiteSpec Ω := + NatIso.ofComponents + fun R ↦ FintypeCat.equivEquivIso (Algebra.IsFiniteSplit.algHomEquivPrimeSpectrum _ _) + +/-- If `Ω` is separably closed, the fiber `S →ₐ[R] Ω` +is isomorphic to the prime spectrum of the base change `Ω ⊗[R] S`. -/ +@[expose] +noncomputable def FiniteEtale.fiberIsoComp [IsSepClosed Ω] : + FiniteEtale.fiber.{v} R Ω ≅ + (FiniteEtale.baseChange.{v} R Ω).op ⋙ FiniteEtale.finiteSpec.{max w v} Ω := + fiberIsoBaseChangeFiber _ _ Ω ≪≫ Functor.isoWhiskerLeft _ (fiberIsoFiniteSpec _) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- If `Ω` is a separably closed field, the category of finite étale `Ω`-algebras is +anti-equivalent to `FintypeCat`. -/ +@[expose, simps! functor inverse_obj inverse_map] +noncomputable def FiniteEtale.equivOfIsSepClosed (Ω : Type u) [Field Ω] [IsSepClosed Ω] : + (FiniteEtale.{u} Ω)ᵒᵖ ≌ FintypeCat.{u} := .symm + { functor.obj X := .op (.of _ (X → Ω)) + functor.map {X Y} f := .op (FiniteEtale.ofHom <| AlgHom.pi fun i ↦ Pi.evalAlgHom _ _ (f i)) + inverse := FiniteEtale.finiteSpec Ω + counitIso := + NatIso.ofComponents + (fun R ↦ (FiniteEtale.isoMk (Algebra.FormallyEtale.equivPiOfIsSepClosed Ω R.unop)).op) + fun {R S} f ↦ by + apply Quiver.Hom.unop_inj + ext x + exact funext fun p ↦ Algebra.FormallyEtale.equivPiOfIsSepClosed_comap _ _ _ + unitIso := NatIso.ofComponents + fun X ↦ FintypeCat.equivEquivIso <| + (Equiv.sigmaUnique _ _).symm.trans (PrimeSpectrum.sigmaToPiHomeo _).toEquiv + functor_unitIso_comp X := by + dsimp [FiniteEtale.finiteSpec] + apply Quiver.Hom.unop_inj + ext x i + dsimp + rw [FintypeCat.equivEquivIso_apply_hom, FintypeCat.homMk_apply] + dsimp + rw [← Pi.coe_evalAlgHom Ω] + simp [Algebra.FormallyEtale.equivPiOfIsSepClosed_comap, + Algebra.FormallyEtale.equivPiOfIsSepClosed_self_apply] } + +instance (Ω : Type u) [Field Ω] [IsSepClosed Ω] : (FiniteEtale.finiteSpec.{u} Ω).IsEquivalence := + (FiniteEtale.equivOfIsSepClosed.{u} Ω).isEquivalence_functor + +instance (Ω : Type u) [Field Ω] [IsSepClosed Ω] : (FiniteEtale.fiber.{u} Ω Ω).IsEquivalence := + Functor.isEquivalence_of_iso (FiniteEtale.fiberIsoFiniteSpec _).symm + +end CommAlgCat diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index d1b56d3faa6a5e..36f0c51b51f6f2 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -209,6 +209,19 @@ def liftEquiv : {fg : (A →ₐ[S] C) × (B →ₐ[R] C) // ∀ x y, Commute (fg left_inv fg := by ext <;> simp right_inv f' := by ext <;> simp +variable (R S B) in +/-- +Algebra maps `S ⊗[R] B →ₐ[S] C` are the same as algebra maps `B →ₐ[R] C`. +Variant of `Algebra.TensorProduct.liftEquiv` where the left map is fixed. +-/ +@[simps] +def liftEquivRight (C : Type*) [CommRing C] [Algebra R C] [Algebra S C] [IsScalarTower R S C] : + (B →ₐ[R] C) ≃ (S ⊗[R] B →ₐ[S] C) where + toFun f := Algebra.TensorProduct.lift (Algebra.ofId _ _) f fun _ _ ↦ .all _ _ + invFun f := AlgHom.comp (f.restrictScalars R) Algebra.TensorProduct.includeRight + left_inv _ := by ext; simp + right_inv _ := by ext; simp + theorem restrictScalars_lift [CommSemiring R'] [Algebra R R'] [Algebra R' S] [Algebra R' A] [IsScalarTower R R' A] [IsScalarTower R' S A] [Algebra R' C] [IsScalarTower R R' C] [IsScalarTower R' S C] diff --git a/Mathlib/RingTheory/TotallySplit.lean b/Mathlib/RingTheory/TotallySplit.lean index 5e6bb5483999f0..bc0467f1d9a2cc 100644 --- a/Mathlib/RingTheory/TotallySplit.lean +++ b/Mathlib/RingTheory/TotallySplit.lean @@ -99,6 +99,7 @@ lemma bijective_algebraMap_quotient [IsFiniteSplit k R] (p : Ideal R) [p.IsPrime variable (k R) in /-- If `R` is finite split over a field `k`, the `k`-rational points of `R` are in one-to-one correspondence with its prime spectrum. -/ +@[expose] noncomputable def algHomEquivPrimeSpectrum [IsFiniteSplit k R] : (R →ₐ[k] k) ≃ PrimeSpectrum R where toFun f := ⟨RingHom.ker f, RingHom.ker_isPrime f⟩ @@ -121,6 +122,11 @@ def algHomEquivPrimeSpectrum [IsFiniteSplit k R] : (R →ₐ[k] k) ≃ PrimeSpec AlgHom.ker_coe_equiv, ← RingHom.ker_eq_comap_bot, ← RingHom.ker_coe_toRingHom, Ideal.Quotient.mkₐ_ker] +@[simp] +lemma coe_algHomEquivPrimeSpectrum [IsFiniteSplit k R] (f : R →ₐ[k] k) : + algHomEquivPrimeSpectrum k R f = RingHom.ker f := + rfl + instance [IsSepClosed k] [EssFiniteType k R] [FormallyEtale k R] : IsFiniteSplit k R := by have := FormallyUnramified.finite_of_free k R have : IsArtinianRing R := isArtinian_of_tower k inferInstance From d255f67ec87ccff56cf443418adec90ab0788342 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 23 Jun 2026 22:14:25 +0000 Subject: [PATCH 0302/1300] style: `simp [- foo]` => `simp [-foo]` (#40971) To adhere to mathlib style. I was told about this [here](https://github.com/leanprover-community/mathlib4/pull/38943#discussion_r3455400592); the `whitespace` linter would enforce this (if it were active on proof bodies). Co-authored-by: Batixx --- Mathlib/Algebra/GroupWithZero/Submonoid/Instances.lean | 2 +- Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean | 2 +- Mathlib/AlgebraicGeometry/Limits.lean | 2 +- Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean | 4 ++-- Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean | 2 +- Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean | 2 +- Mathlib/GroupTheory/SpecificGroups/Quaternion.lean | 2 +- .../Homological/GroupHomology/Functoriality.lean | 2 +- Mathlib/RingTheory/ZariskisMainTheorem.lean | 2 +- Mathlib/Topology/Algebra/Valued/WithVal.lean | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/Submonoid/Instances.lean b/Mathlib/Algebra/GroupWithZero/Submonoid/Instances.lean index 618119245f44d2..41a52266808e81 100644 --- a/Mathlib/Algebra/GroupWithZero/Submonoid/Instances.lean +++ b/Mathlib/Algebra/GroupWithZero/Submonoid/Instances.lean @@ -43,7 +43,7 @@ instance [GroupWithZero G] [GroupWithZero H] (f : G →*₀ H) : obtain ⟨y, hy⟩ := x.prop use y⁻¹ simp [← hy]⟩ - exists_pair_ne := ⟨⟨f 0, 0, rfl⟩, ⟨f 1, by simp [- map_one]⟩, by simp⟩ + exists_pair_ne := ⟨⟨f 0, 0, rfl⟩, ⟨f 1, by simp [-map_one]⟩, by simp⟩ inv_zero := Subtype.ext inv_zero mul_inv_cancel := by rintro ⟨a, ha⟩ h diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index 69443cf0fe5b99..0bfee543aed3b0 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -1174,7 +1174,7 @@ private nonrec lemma Scheme.exists_π_app_comp_eq_of_locallyOfFinitePresentation obtain ⟨R, rfl⟩ := hS wlog hX : ∃ S, X = Spec S generalizing X · obtain ⟨i, f, hf⟩ := this (a ≫ X.isoSpec.hom) (X.isoSpec.inv ≫ f) - (by simp [ha, - Functor.map_comp]) ⟨_, rfl⟩ + (by simp [ha, -Functor.map_comp]) ⟨_, rfl⟩ exact ⟨i, f ≫ X.isoSpec.inv, by simpa [← Iso.comp_inv_eq] using! hf⟩ obtain ⟨S, rfl⟩ := hX obtain ⟨φ, rfl⟩ := Spec.map_surjective f diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index a832ac5e0c047b..d2058253707e20 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -442,7 +442,7 @@ lemma isPullback_inl_inl_coprodMap {X Y X' Y' : Scheme.{u}} · simp only [coprodMk_inr, ← Scheme.Hom.comp_apply, coprod.inr_map] at hxy cases Set.disjoint_iff_forall_ne.mp (isCompl_range_inl_inr _ _).1 ⟨y, rfl⟩ ⟨_, rfl⟩ hxy · rintro _ ⟨x, rfl⟩ - exact ⟨f x, by simp [← Scheme.Hom.comp_apply, - Scheme.Hom.comp_base]⟩ + exact ⟨f x, by simp [← Scheme.Hom.comp_apply, -Scheme.Hom.comp_base]⟩ set_option backward.isDefEq.respectTransparency false in lemma isPullback_inr_inr_coprodMap {X Y X' Y' : Scheme.{u}} diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean index 897283b0a8f0f7..49fe5adb97ebef 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean @@ -212,7 +212,7 @@ protected lemma hom_ext {Z' Z : Scheme} (i : Z' ⟶ Z) (hi : IsNilpotent i.ker) Scheme.Hom.appLE_comp_appLE]⟩ let ψ₂ : Γ(X, V) →ₐ[Γ(Y, U)] Γ(Z, W) := ⟨(g₂.appLE _ _ (hWV.trans inf_le_right)).hom, fun r ↦ by simp [RingHom.algebraMap_toAlgebra, ← CategoryTheory.comp_apply, -CommRingCat.hom_comp, - Scheme.Hom.appLE_comp_appLE, hgf, - Scheme.Hom.comp_appLE]⟩ + Scheme.Hom.appLE_comp_appLE, hgf, -Scheme.Hom.comp_appLE]⟩ suffices ψ₁ = ψ₂ by simpa [ψ₁, ψ₂, -Iso.cancel_iso_hom_left, IsAffineOpen.isoSpec_hom] using congr(hW.isoSpec.hom ≫ Spec.map (CommRingCat.ofHom ($this).toRingHom) ≫ hV.fromSpec) @@ -220,7 +220,7 @@ protected lemma hom_ext {Z' Z : Scheme} (i : Z' ⟶ Z) (hi : IsNilpotent i.ker) · obtain ⟨n, hn⟩ := hi exact ⟨n, by simpa using congr(($hn).ideal ⟨W, hW⟩)⟩ · simp [ψ₁, ψ₂, ← CategoryTheory.comp_apply, -CommRingCat.hom_comp, hig, - Scheme.Hom.app_eq_appLE, Scheme.Hom.appLE_comp_appLE, - Scheme.Hom.comp_appLE] + Scheme.Hom.app_eq_appLE, Scheme.Hom.appLE_comp_appLE, -Scheme.Hom.comp_appLE] /-- To show that `f : X ⟶ Y` is formally unramified, diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean index 9c6a0fcccc6428..e9605bfa71774f 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean @@ -120,7 +120,7 @@ def IsSplitEqualizer.isEqualizer {W : C} {h : W ⟶ X} (t : IsSplitEqualizer f g IsLimit t.asFork := Fork.IsLimit.mk' _ fun s => ⟨ s.ι ≫ t.leftRetraction, - by simp [- top_rightRetraction, ← t.top_rightRetraction, s.condition_assoc], + by simp [-top_rightRetraction, ← t.top_rightRetraction, s.condition_assoc], fun hm => by simp [← hm] ⟩ end diff --git a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean index 05152c715b8756..e4fea004e81e05 100644 --- a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean @@ -122,7 +122,7 @@ theorem equiv_symm_eq_apply {X : C} {P : Cᵒᵖ ⥤ D} {S : J.Cover X} [HasMult -- We can hint `ConcreteCategory.hom (Y := P.obj (op I.Y))` below to put it into `simp`-normal -- form, but that doesn't seem to fix the `erw`s below... (Multiequalizer.ι (S.index P) I) ((Meq.equiv P S).symm x) = x I := by - simp [- GrothendieckTopology.Cover.index_left, ← equiv_apply] + simp [-GrothendieckTopology.Cover.index_left, ← equiv_apply] end Meq diff --git a/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean b/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean index cf44529992f105..8fb79b38b4cf4a 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean @@ -168,7 +168,7 @@ instance [NeZero n] : Fintype (QuaternionGroup n) := Fintype.ofEquiv _ fintypeHelper instance : Nontrivial (QuaternionGroup n) := - ⟨⟨a 0, xa 0, by simp [- a_zero]⟩⟩ + ⟨⟨a 0, xa 0, by simp [-a_zero]⟩⟩ /-- If `0 < n`, then `QuaternionGroup n` has `4n` elements. -/ diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean index 90993978ab1507..12df1c5618ad2b 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean @@ -574,7 +574,7 @@ and `Y - ∑ aᵢ·sᵢ` is a cycle. -/ rcases chains₁ToCoinvariantsKer_surjective (res S.subtype A) ⟨d₁₀ A Y, this⟩ with ⟨(Z : S →₀ A), hZ⟩ have H : d₁₀ A (Y - mapDomain S.subtype Z) = 0 := by - simpa [map_sub, sub_eq_zero, chains₁ToCoinvariantsKer, - LinearMap.sub_apply, d₁₀, + simpa [map_sub, sub_eq_zero, chains₁ToCoinvariantsKer, -LinearMap.sub_apply, d₁₀, sum_mapDomain_index_inj] using! Subtype.ext_iff.1 hZ.symm use H1π A ⟨Y - mapDomain S.subtype Z, H⟩ simp only [H1CoresCoinf_X₃, H1CoresCoinf_X₂, H1CoresCoinf_g, diff --git a/Mathlib/RingTheory/ZariskisMainTheorem.lean b/Mathlib/RingTheory/ZariskisMainTheorem.lean index 56b7325c374066..920e9ed36be5b7 100644 --- a/Mathlib/RingTheory/ZariskisMainTheorem.lean +++ b/Mathlib/RingTheory/ZariskisMainTheorem.lean @@ -241,7 +241,7 @@ lemma exists_leadingCoeff_pow_smul_mem_conductor exists_isIntegral_leadingCoeff_pow_smul_sub_of_isIntegralElem_of_mul_mem_range φ _ p (hφ.to_isIntegral (t * x)) (by convert! this using 1; ring) obtain ⟨r, hr : algebraMap _ _ r = _⟩ := hRS.le hn - exact ⟨n, (C r + q), by simp [← Polynomial.algebraMap_eq, - Polynomial.algebraMap_apply, hr]⟩ + exact ⟨n, (C r + q), by simp [← Polynomial.algebraMap_eq, -Polynomial.algebraMap_apply, hr]⟩ choose n hn using this obtain ⟨s, hs⟩ := Module.Finite.fg_top (R := R[X]) (M := S) refine ⟨s.sup n, fun x ↦ ?_⟩ diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index 6cd812ef591d80..52af5959ca41f2 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -264,7 +264,7 @@ instance {P : Type*} [Ring S] [SMul P S] [SMul R S] [SMul P R] instance {P : Type*} [Ring S] [SMul P R] [SMul S R] [SMul P S] [IsScalarTower P S R] (v : Valuation S Γ₀) : IsScalarTower P (WithVal v) R where - smul_assoc := by simp [smul_right_def, smul_left_def, - toVal_smul] + smul_assoc := by simp [smul_right_def, smul_left_def, -toVal_smul] instance [AddCommMonoid S] [Module R S] : Module (WithVal v) S := .compHom S (equiv v).toRingHom From 5cbb508e3c6d4f61810d681accf75353c5e655fc Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 23 Jun 2026 22:34:19 +0000 Subject: [PATCH 0303/1300] chore(CategoryTheory/Sites): fix order of universe variables in `Presieve.ofArrows_pUnit` (#40974) The free universe variable should be the first one in the declaration, not the third. --- Mathlib/AlgebraicGeometry/Sites/Fpqc.lean | 2 +- Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean | 2 +- Mathlib/CategoryTheory/Sites/MorphismProperty.lean | 2 +- Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean | 2 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean b/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean index 3e343f60a1f49d..77045d93db95c8 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean @@ -97,7 +97,7 @@ instance : fppfTopology.Subcanonical := lemma Hom.singleton_mem_fppfPrecoverage {X Y : Scheme.{u}} (f : X ⟶ Y) [Flat f] [Surjective f] [LocallyOfFinitePresentation f] : Presieve.singleton f ∈ fppfPrecoverage Y := by - rw [← Presieve.ofArrows_pUnit.{_, _, 0}] + rw [← Presieve.ofArrows_pUnit.{0}] exact (f.cover (P := @Flat ⊓ @LocallyOfFinitePresentation) ⟨‹_›, ‹_›⟩).mem₀ @[simp] diff --git a/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean b/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean index 7fb519d3c2dbe7..bc84f286e65bbc 100644 --- a/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean +++ b/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean @@ -88,7 +88,7 @@ lemma ofArrows_mem_precoverage_iff {S : Scheme.{u}} {ι : Type*} {X : ι → Sch @[simp] lemma singleton_mem_precoverage_iff {X S : Scheme.{u}} (f : X ⟶ S) : Presieve.singleton f ∈ precoverage P S ↔ Function.Surjective f.base ∧ P f := by - rw [← Presieve.ofArrows_pUnit.{_, _, 0}, ofArrows_mem_precoverage_iff] + rw [← Presieve.ofArrows_pUnit.{0}, ofArrows_mem_precoverage_iff] aesop lemma bot_mem_precoverage (X : Scheme.{u}) [IsEmpty X] : ⊥ ∈ Scheme.precoverage P X := diff --git a/Mathlib/CategoryTheory/Sites/MorphismProperty.lean b/Mathlib/CategoryTheory/Sites/MorphismProperty.lean index 7d6f1c72ace666..81bd3600419586 100644 --- a/Mathlib/CategoryTheory/Sites/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/Sites/MorphismProperty.lean @@ -49,7 +49,7 @@ lemma ofArrows_mem_precoverage {X : C} {ι : Type*} {Y : ι → C} {f : ∀ i, Y @[simp, grind =] lemma singleton_mem_precoverage {X Y : C} (f : X ⟶ Y) : .singleton f ∈ precoverage P Y ↔ P f := by - simp [← Presieve.ofArrows_pUnit.{_, _, 0}] + simp [← Presieve.ofArrows_pUnit.{0}] instance [P.ContainsIdentities] [P.RespectsIso] : P.precoverage.HasIsos where mem_coverings_of_isIso f _ _ _ := fun ⟨⟩ ↦ P.of_isIso f diff --git a/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean b/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean index 9ae4abb0b79848..fc344b9950c132 100644 --- a/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean @@ -232,7 +232,7 @@ lemma Presieve.isSheafFor_singleton_iff_of_iso {F : Cᵒᵖ ⥤ Type*} {S X Y : (g : Y ⟶ S) (e : X ≅ Y) (he : e.hom ≫ g = f) : (singleton f).IsSheafFor F ↔ (singleton g).IsSheafFor F := by subst he - rw [← Presieve.ofArrows_pUnit.{_, _, 0}, ← Presieve.ofArrows_pUnit, + rw [← Presieve.ofArrows_pUnit.{0}, ← Presieve.ofArrows_pUnit, Presieve.isSheafFor_ofArrows_comp_iff] open Limits diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 8a23a45ba149dd..56a4042b21ee1e 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -271,7 +271,7 @@ lemma ofArrows_of_unique {X : C} {ι : Type*} [Unique ι] {Y : ι → C} (f : obtain rfl : i = default := Subsingleton.elim _ _ simp -theorem ofArrows_pUnit : (ofArrows _ fun _ : PUnit => f) = singleton f := by +theorem ofArrows_pUnit : (ofArrows _ fun _ : PUnit.{w + 1} => f) = singleton f := by rw [ofArrows_of_unique] @[grind =] @@ -316,7 +316,7 @@ lemma pushforward_ofArrows {ι : Type*} {U : ι → C} {X Y : C} (g : ∀ i, U i lemma pushforward_singleton {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : (singleton f).pushforward g = .singleton (f ≫ g) := by - rw [← ofArrows_pUnit.{_, _, 0}, pushforward_ofArrows, ofArrows_pUnit.{_, _, 0}] + rw [← ofArrows_pUnit.{0}, pushforward_ofArrows, ofArrows_pUnit.{0}] /-- The pullback of a presieve `R` on `Y` along a morphism `f : X ⟶ Y` is the presieve on `X` given by all morphisms `g : Z ⟶ X` such that `f ≫ g` is in `R`. -/ @@ -475,7 +475,7 @@ lemma map_ofArrows {X : C} {ι : Type*} {Y : ι → C} (f : ∀ i, Y i ⟶ X) : @[simp] lemma map_singleton {X Y : C} (f : X ⟶ Y) : (singleton f).map F = singleton (F.map f) := by - rw [← ofArrows_pUnit.{_, _, 0}, map_ofArrows, ofArrows_pUnit] + rw [← ofArrows_pUnit.{0}, map_ofArrows, ofArrows_pUnit] lemma map_le_iff_le_functorPullback {R : Presieve X} {S : Presieve (F.obj X)} : R.map F ≤ S ↔ R ≤ S.functorPullback F := From 1aeada15afe7990503183188dd86b65f8a936ef7 Mon Sep 17 00:00:00 2001 From: Vasilii Nesterov <118051017+vasnesterov@users.noreply.github.com> Date: Tue, 23 Jun 2026 22:55:02 +0000 Subject: [PATCH 0304/1300] feat(Analysis/Analytic): alternating geometric series (#40029) * Define `geometricAlternatingSeries`: `1 - x + x ^ 2 - ...` as a `FormalMultilinearSeries`. * Prove the same lemmas as for existing `formalMultilinearSeries_geometric`. * Move the "Composition with a linear map" section above as it's needed to directly translate the results about `formalMultilinearSeries_geometric` to results about `geometricAlternatingSeries`. The series for `1/(1+x)` is more common in "practical" calculus than the series for `1/(1-x)`. I use it in the `compute_asymptotics` tactic to derive the series expansion of `1 / f(x)` as `x -> 0` when the series expansion of `f(x)` is known. I decompose `f(x) = C + g(x)` with `g(x) = o(1)` and derive it as `1 / (C + g(x)) = 1/C * 1/(1 + g(x)/C) = 1/C * (1 - g(x) / C + g(x)^2 / C^2 - ...)`. --- Mathlib/Analysis/Analytic/Constructions.lean | 188 ++++++++++++------- 1 file changed, 123 insertions(+), 65 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Constructions.lean b/Mathlib/Analysis/Analytic/Constructions.lean index 8d7fa921173079..8cf6ff6eaaf355 100644 --- a/Mathlib/Analysis/Analytic/Constructions.lean +++ b/Mathlib/Analysis/Analytic/Constructions.lean @@ -716,6 +716,71 @@ lemma AnalyticOnNhd.zpow_nonneg {f : E → 𝕝} {s : Set E} {n : ℤ} (hf : Ana simp_rw [(Eq.symm (Int.toNat_of_nonneg hn) : n = OfNat.ofNat n.toNat), zpow_ofNat] apply pow hf +/-! +### Composition with a linear map +-/ + +section compContinuousLinearMap + +variable {u : E →L[𝕜] F} {f : F → G} {pf : FormalMultilinearSeries 𝕜 F G} {s : Set F} {x : E} + {r : ℝ≥0∞} + +theorem HasFPowerSeriesWithinOnBall.compContinuousLinearMap + (hf : HasFPowerSeriesWithinOnBall f pf s (u x) r) : + HasFPowerSeriesWithinOnBall (f ∘ u) (pf.compContinuousLinearMap u) (u ⁻¹' s) x (r / ‖u‖ₑ) where + r_le := by + calc + _ ≤ pf.radius / ‖u‖ₑ := by + gcongr + exact hf.r_le + _ ≤ _ := pf.div_le_radius_compContinuousLinearMap _ + r_pos := by + simp only [ENNReal.div_pos_iff, ne_eq, enorm_ne_top, not_false_eq_true, and_true] + exact pos_iff_ne_zero.mp hf.r_pos + hasSum hy1 hy2 := by + convert! hf.hasSum _ _ + · simp + · simp only [Set.mem_insert_iff, add_eq_left, Set.mem_preimage, map_add] at hy1 ⊢ + rcases hy1 with (hy1 | hy1) <;> simp [hy1] + · simp only [Metric.eball, edist_zero_right, Set.mem_setOf_eq] at hy2 ⊢ + exact lt_of_le_of_lt (ContinuousLinearMap.le_opNorm_enorm _ _) (mul_lt_of_lt_div' hy2) + +theorem HasFPowerSeriesOnBall.compContinuousLinearMap (hf : HasFPowerSeriesOnBall f pf (u x) r) : + HasFPowerSeriesOnBall (f ∘ u) (pf.compContinuousLinearMap u) x (r / ‖u‖ₑ) := by + rw [← hasFPowerSeriesWithinOnBall_univ] at hf ⊢ + exact hf.compContinuousLinearMap + +theorem HasFPowerSeriesAt.compContinuousLinearMap (hf : HasFPowerSeriesAt f pf (u x)) : + HasFPowerSeriesAt (f ∘ u) (pf.compContinuousLinearMap u) x := + let ⟨r, hr⟩ := hf + ⟨r / ‖u‖ₑ, hr.compContinuousLinearMap⟩ + +theorem HasFPowerSeriesWithinAt.compContinuousLinearMap + (hf : HasFPowerSeriesWithinAt f pf s (u x)) : + HasFPowerSeriesWithinAt (f ∘ u) (pf.compContinuousLinearMap u) (u ⁻¹' s) x := + let ⟨r, hr⟩ := hf + ⟨r / ‖u‖ₑ, hr.compContinuousLinearMap⟩ + +theorem AnalyticAt.compContinuousLinearMap (hf : AnalyticAt 𝕜 f (u x)) : + AnalyticAt 𝕜 (f ∘ u) x := + let ⟨p, hp⟩ := hf + ⟨p.compContinuousLinearMap u, hp.compContinuousLinearMap⟩ + +theorem AnalyticAtWithin.compContinuousLinearMap (hf : AnalyticWithinAt 𝕜 f s (u x)) : + AnalyticWithinAt 𝕜 (f ∘ u) (u ⁻¹' s) x := + let ⟨p, hp⟩ := hf + ⟨p.compContinuousLinearMap u, hp.compContinuousLinearMap⟩ + +theorem AnalyticOn.compContinuousLinearMap (hf : AnalyticOn 𝕜 f s) : + AnalyticOn 𝕜 (f ∘ u) (u ⁻¹' s) := fun x hx => + AnalyticAtWithin.compContinuousLinearMap (hf (u x) hx) + +theorem AnalyticOnNhd.compContinuousLinearMap (hf : AnalyticOnNhd 𝕜 f s) : + AnalyticOnNhd 𝕜 (f ∘ u) (u ⁻¹' s) := fun x hx => + AnalyticAt.compContinuousLinearMap (hf (u x) hx) + +end compContinuousLinearMap + /-! ### Restriction of scalars -/ @@ -822,6 +887,53 @@ lemma analyticAt_inverse_one_sub [HasSummableGeomSeries A] : AnalyticAt 𝕜 (fun x : A ↦ (1 - x)⁻¹ʳ) 0 := ⟨_, ⟨_, hasFPowerSeriesOnBall_inverse_one_sub 𝕜 A⟩⟩ +/-- The alternating geometric series `1 - x + x ^ 2 - ...` as a `FormalMultilinearSeries`. -/ +def alternatingGeometricSeries : FormalMultilinearSeries 𝕜 A A := + .ofScalars A fun n ↦ (-1 : 𝕜) ^ n + +lemma alternatingGeometricSeries_eq_formalMultilinearSeries_geometric_comp_neg : + alternatingGeometricSeries 𝕜 A = + (formalMultilinearSeries_geometric 𝕜 A).compContinuousLinearMap + (-ContinuousLinearMap.id 𝕜 A) := by + simp [formalMultilinearSeries_geometric_eq_ofScalars, alternatingGeometricSeries, + FormalMultilinearSeries.ofScalars_comp_neg_id] + +lemma alternatingGeometricSeries_apply_norm_le (n : ℕ) : + ‖alternatingGeometricSeries 𝕜 A n‖ ≤ max 1 ‖(1 : A)‖ := by + simpa [alternatingGeometricSeries] using + ContinuousMultilinearMap.norm_mkPiAlgebraFin_le + +lemma alternatingGeometricSeries_apply_norm [NormOneClass A] (n : ℕ) : + ‖alternatingGeometricSeries 𝕜 A n‖ = 1 := by + simp [alternatingGeometricSeries] + +lemma one_le_alternatingGeometricSeries_radius [Nontrivial A] : + 1 ≤ (alternatingGeometricSeries 𝕜 A).radius := by + simpa only [FormalMultilinearSeries.radius_compNeg, + alternatingGeometricSeries_eq_formalMultilinearSeries_geometric_comp_neg] + using one_le_formalMultilinearSeries_geometric_radius 𝕜 A + +lemma alternatingGeometricSeries_radius [NormOneClass A] : + (alternatingGeometricSeries 𝕜 A).radius = 1 := + FormalMultilinearSeries.ofScalars_radius_eq_of_tendsto A _ one_ne_zero (by simp) + +lemma hasFPowerSeriesOnBall_inverse_one_add [HasSummableGeomSeries A] [Nontrivial A] : + HasFPowerSeriesOnBall (fun x : A ↦ Ring.inverse (1 + x)) + (alternatingGeometricSeries 𝕜 A) 0 1 := by + rw [alternatingGeometricSeries_eq_formalMultilinearSeries_geometric_comp_neg] + convert_to HasFPowerSeriesOnBall ((fun x ↦ Ring.inverse (1 - x)) ∘ (-ContinuousLinearMap.id 𝕜 A)) + ((formalMultilinearSeries_geometric 𝕜 A).compContinuousLinearMap (-ContinuousLinearMap.id 𝕜 A)) + 0 1 + · ext; simp + convert HasFPowerSeriesOnBall.compContinuousLinearMap _ (r := 1) + · simp [← ofReal_norm] + · simpa using (hasFPowerSeriesOnBall_inverse_one_sub 𝕜 A) + +@[fun_prop] +lemma analyticAt_inverse_one_add [HasSummableGeomSeries A] [Nontrivial A] : + AnalyticAt 𝕜 (fun x : A ↦ Ring.inverse (1 + x)) 0 := + ⟨_, ⟨_, hasFPowerSeriesOnBall_inverse_one_add 𝕜 A⟩⟩ + end Geometric /-- If `A` is a normed algebra over `𝕜` with summable geometric series, then inversion on `A` is @@ -871,6 +983,17 @@ variable (𝕝) in lemma analyticAt_inv_one_sub : AnalyticAt 𝕜 (fun x : 𝕝 ↦ (1 - x)⁻¹) 0 := ⟨_, ⟨_, hasFPowerSeriesOnBall_inv_one_sub 𝕜 𝕝⟩⟩ +variable (𝕜 𝕝) in +lemma hasFPowerSeriesOnBall_inv_one_add : + HasFPowerSeriesOnBall (fun x : 𝕝 ↦ (1 + x)⁻¹) (alternatingGeometricSeries 𝕜 𝕝) 0 1 := by + convert! hasFPowerSeriesOnBall_inverse_one_add 𝕜 𝕝 + exact Ring.inverse_eq_inv'.symm + +variable (𝕝) in +@[fun_prop] +lemma analyticAt_inv_one_add : AnalyticAt 𝕜 (fun x : 𝕝 ↦ (1 + x)⁻¹) 0 := + ⟨_, ⟨_, hasFPowerSeriesOnBall_inv_one_add 𝕜 𝕝⟩⟩ + /-- If `𝕝` is a normed field extension of `𝕜`, then the inverse map `𝕝 → 𝕝` is `𝕜`-analytic away from 0. -/ @[fun_prop] @@ -1159,68 +1282,3 @@ theorem HasFPowerSeriesWithinAt.unshift (hf : HasFPowerSeriesWithinAt f pf s x) hrf.unshift.hasFPowerSeriesWithinAt end - -/-! -### Composition with a linear map --/ - -section compContinuousLinearMap - -variable {u : E →L[𝕜] F} {f : F → G} {pf : FormalMultilinearSeries 𝕜 F G} {s : Set F} {x : E} - {r : ℝ≥0∞} - -theorem HasFPowerSeriesWithinOnBall.compContinuousLinearMap - (hf : HasFPowerSeriesWithinOnBall f pf s (u x) r) : - HasFPowerSeriesWithinOnBall (f ∘ u) (pf.compContinuousLinearMap u) (u ⁻¹' s) x (r / ‖u‖ₑ) where - r_le := by - calc - _ ≤ pf.radius / ‖u‖ₑ := by - gcongr - exact hf.r_le - _ ≤ _ := pf.div_le_radius_compContinuousLinearMap _ - r_pos := by - simp only [ENNReal.div_pos_iff, ne_eq, enorm_ne_top, not_false_eq_true, and_true] - exact pos_iff_ne_zero.mp hf.r_pos - hasSum hy1 hy2 := by - convert! hf.hasSum _ _ - · simp - · simp only [Set.mem_insert_iff, add_eq_left, Set.mem_preimage, map_add] at hy1 ⊢ - rcases hy1 with (hy1 | hy1) <;> simp [hy1] - · simp only [Metric.eball, edist_zero_right, Set.mem_setOf_eq] at hy2 ⊢ - exact lt_of_le_of_lt (ContinuousLinearMap.le_opNorm_enorm _ _) (mul_lt_of_lt_div' hy2) - -theorem HasFPowerSeriesOnBall.compContinuousLinearMap (hf : HasFPowerSeriesOnBall f pf (u x) r) : - HasFPowerSeriesOnBall (f ∘ u) (pf.compContinuousLinearMap u) x (r / ‖u‖ₑ) := by - rw [← hasFPowerSeriesWithinOnBall_univ] at hf ⊢ - exact hf.compContinuousLinearMap - -theorem HasFPowerSeriesAt.compContinuousLinearMap (hf : HasFPowerSeriesAt f pf (u x)) : - HasFPowerSeriesAt (f ∘ u) (pf.compContinuousLinearMap u) x := - let ⟨r, hr⟩ := hf - ⟨r / ‖u‖ₑ, hr.compContinuousLinearMap⟩ - -theorem HasFPowerSeriesWithinAt.compContinuousLinearMap - (hf : HasFPowerSeriesWithinAt f pf s (u x)) : - HasFPowerSeriesWithinAt (f ∘ u) (pf.compContinuousLinearMap u) (u ⁻¹' s) x := - let ⟨r, hr⟩ := hf - ⟨r / ‖u‖ₑ, hr.compContinuousLinearMap⟩ - -theorem AnalyticAt.compContinuousLinearMap (hf : AnalyticAt 𝕜 f (u x)) : - AnalyticAt 𝕜 (f ∘ u) x := - let ⟨p, hp⟩ := hf - ⟨p.compContinuousLinearMap u, hp.compContinuousLinearMap⟩ - -theorem AnalyticAtWithin.compContinuousLinearMap (hf : AnalyticWithinAt 𝕜 f s (u x)) : - AnalyticWithinAt 𝕜 (f ∘ u) (u ⁻¹' s) x := - let ⟨p, hp⟩ := hf - ⟨p.compContinuousLinearMap u, hp.compContinuousLinearMap⟩ - -theorem AnalyticOn.compContinuousLinearMap (hf : AnalyticOn 𝕜 f s) : - AnalyticOn 𝕜 (f ∘ u) (u ⁻¹' s) := fun x hx => - AnalyticAtWithin.compContinuousLinearMap (hf (u x) hx) - -theorem AnalyticOnNhd.compContinuousLinearMap (hf : AnalyticOnNhd 𝕜 f s) : - AnalyticOnNhd 𝕜 (f ∘ u) (u ⁻¹' s) := fun x hx => - AnalyticAt.compContinuousLinearMap (hf (u x) hx) - -end compContinuousLinearMap From 62dc8f267ea2dc711dd18b746f454fcf013be912 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 24 Jun 2026 00:45:07 +0000 Subject: [PATCH 0305/1300] =?UTF-8?q?feat(GroupTheory/IsPerfect):=20Gr?= =?UTF-8?q?=C3=BCn's=20lemma=20(#39956)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grün's lemma: In a perfect group (`commutator G = ⊤`), `center (G ⧸ center G) = ⊥`. Also the `derivedSeries` and the `lowerCentralSeries` are a constant `⊤`, and the `upperCentralSeries` starts with `⊥` and afterwards is a constant `center G`. --- Mathlib/Algebra/Group/Subgroup/Ker.lean | 22 +++++++++++ Mathlib/GroupTheory/Commutator/Basic.lean | 22 +++++++++++ Mathlib/GroupTheory/IsPerfect.lean | 37 +++++++++++++++++++ Mathlib/GroupTheory/Nilpotent.lean | 8 ++++ Mathlib/GroupTheory/Subgroup/Centralizer.lean | 4 ++ 5 files changed, 93 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Ker.lean b/Mathlib/Algebra/Group/Subgroup/Ker.lean index 5f0826515c0693..17796f56170410 100644 --- a/Mathlib/Algebra/Group/Subgroup/Ker.lean +++ b/Mathlib/Algebra/Group/Subgroup/Ker.lean @@ -82,6 +82,11 @@ theorem mem_range {f : G →* N} {y : N} : y ∈ f.range ↔ ∃ x, f x = y := @[to_additive] theorem range_eq_map (f : G →* N) : f.range = (⊤ : Subgroup G).map f := by ext; simp +@[to_additive (attr := simp)] +theorem comap_range_self (f : G →* N) : f.range.comap f = ⊤ := by + ext + simp + @[to_additive] instance _root_.Subgroup.range_isMulCommutative {G : Type*} [Group G] [IsMulCommutative G] {N : Type*} [Group N] (f : G →* N) : @@ -270,6 +275,10 @@ theorem comap_ker {P : Type*} [MulOneClass P] (g : N →* P) (f : G →* N) : theorem comap_bot (f : G →* N) : (⊥ : Subgroup N).comap f = f.ker := rfl +@[to_additive] +theorem ker_le_comap (f : G →* N) (H : Subgroup N) : f.ker ≤ H.comap f := + comap_mono bot_le + @[to_additive (attr := simp)] theorem ker_restrict (f : G →* M) : (f.restrict K).ker = f.ker.subgroupOf K := rfl @@ -401,6 +410,10 @@ theorem map_eq_bot_iff {f : G →* N} : H.map f = ⊥ ↔ H ≤ f.ker := theorem map_eq_bot_iff_of_injective {f : G →* N} (hf : Function.Injective f) : H.map f = ⊥ ↔ H = ⊥ := by rw [map_eq_bot_iff, f.ker_eq_bot hf, le_bot_iff] +@[to_additive (attr := simp)] +theorem map_ker_self (f : G →* N) : f.ker.map f = ⊥ := by + rw [map_eq_bot_iff] + open MonoidHom variable (f : G →* N) @@ -458,6 +471,15 @@ theorem comap_lt_comap_of_surjective {f : G →* N} {K L : Subgroup N} (hf : Fun theorem comap_injective {f : G →* N} (h : Function.Surjective f) : Function.Injective (comap f) := fun K L => by simp only [le_antisymm_iff, comap_le_comap_of_surjective h, imp_self] +@[to_additive (attr := simp)] +theorem comap_eq_ker {f : G →* N} {H : Subgroup N} : H.comap f = f.ker ↔ Disjoint H f.range := by + rw [← H.ker_le_comap f |>.ge_iff_eq', ← map_eq_bot_iff, map_comap_eq, disjoint_iff, inf_comm] + +@[to_additive] +theorem comap_eq_ker_of_surjective {f : G →* N} (hf : Surjective f) {H : Subgroup N} : + H.comap f = f.ker ↔ H = ⊥ := by + rw [comap_eq_ker, f.range_eq_top_of_surjective hf, disjoint_top] + @[to_additive] theorem comap_map_eq_self {f : G →* N} {H : Subgroup G} (h : f.ker ≤ H) : comap f (map f H) = H := by diff --git a/Mathlib/GroupTheory/Commutator/Basic.lean b/Mathlib/GroupTheory/Commutator/Basic.lean index c2602aad4ef00e..bae1b8b7e53cd9 100644 --- a/Mathlib/GroupTheory/Commutator/Basic.lean +++ b/Mathlib/GroupTheory/Commutator/Basic.lean @@ -183,6 +183,28 @@ theorem commutator_comm_le : ⁅H₁, H₂⁆ ≤ ⁅H₂, H₁⁆ := theorem commutator_comm : ⁅H₁, H₂⁆ = ⁅H₂, H₁⁆ := le_antisymm (commutator_comm_le H₁ H₂) (commutator_comm_le H₂ H₁) +@[to_additive] +theorem commutator_self_eq_bot_iff : ⁅H, H⁆ = ⊥ ↔ IsMulCommutative H := by + rw [commutator_eq_bot_iff_le_centralizer, le_centralizer_iff_isMulCommutative] + +@[to_additive (attr := simp)] +theorem commutator_top_right_eq_bot_iff_le_center : ⁅H, (⊤ : Subgroup G)⁆ = ⊥ ↔ H ≤ center G := by + rw [commutator_eq_bot_iff_le_centralizer, coe_top, centralizer_univ] + +@[to_additive (attr := simp)] +theorem commutator_top_left_eq_bot_iff_le_center : ⁅(⊤ : Subgroup G), H⁆ = ⊥ ↔ H ≤ center G := by + rw [commutator_comm, commutator_top_right_eq_bot_iff_le_center] + +variable (H) in +@[to_additive (attr := simp)] +theorem commutator_center_right : ⁅H, center G⁆ = ⊥ := by + simp [commutator_eq_bot_iff_le_centralizer] + +variable (H) in +@[to_additive (attr := simp)] +theorem commutator_center_left : ⁅center G, H⁆ = ⊥ := + commutator_eq_bot_iff_le_centralizer.mpr <| center_le_centralizer _ + section Normal @[to_additive] diff --git a/Mathlib/GroupTheory/IsPerfect.lean b/Mathlib/GroupTheory/IsPerfect.lean index 878b92ee0cd9bc..ca51df8499158c 100644 --- a/Mathlib/GroupTheory/IsPerfect.lean +++ b/Mathlib/GroupTheory/IsPerfect.lean @@ -104,4 +104,41 @@ lemma ofSurjective [IsPerfect G] (hf : Function.Surjective f) : IsPerfect G' := instance instQuotientSubgroup [H.Normal] [IsPerfect G] : IsPerfect (G ⧸ H) := ofSurjective (QuotientGroup.mk'_surjective H) +variable (G) in +@[simp] +theorem derivedSeries_eq_top [IsPerfect G] (n : ℕ) : derivedSeries G n = ⊤ := by + match n with + | 0 => simp + | n + 1 => + rw [derivedSeries_succ, derivedSeries_eq_top, commutator_eq_self] + +@[simp] +theorem lowerCentralSeries_eq_top (H : Subgroup G) [IsPerfect H] (n : ℕ) : + H.lowerCentralSeries n = H := by + match n with + | 0 => simp + | n + 1 => + rw [Subgroup.lowerCentralSeries_succ, lowerCentralSeries_eq_top, commutator_eq_self] + +variable (G) in +@[simp] +theorem upperCentralSeries_eq_center [IsPerfect G] {n : ℕ} (hn : n ≠ 0) : + Subgroup.upperCentralSeries G n = center G := by + rw [← Subgroup.upperCentralSeries_one, eq_comm] + apply Subgroup.upperCentralSeries.eq_ge_of_eq_succ <| by lia + apply le_antisymm <| Subgroup.upperCentralSeries_mono G one_le_two + rw [Subgroup.upperCentralSeries_one, ← commutator_top_right_eq_bot_iff_le_center, + ← commutator_eq_top, commutator_comm, commutator_def] + suffices ⁅⁅Subgroup.upperCentralSeries G 2, ⊤⁆, ⊤⁆ = ⊥ from + commutator_commutator_eq_bot_of_rotate (by simpa [commutator_comm]) this + rw [commutator_top_right_eq_bot_iff_le_center, ← Subgroup.upperCentralSeries_one] + apply commutator_upperCentralSeries_top_le + +variable (G) in +/-- **Grün's lemma** -/ +theorem center_quotient_center_eq_bot [IsPerfect G] : center (G ⧸ center G) = ⊥ := by + rw [← Subgroup.upperCentralSeries_one (G ⧸ center G), + ← comap_eq_ker_of_surjective <| QuotientGroup.mk'_surjective _, QuotientGroup.ker_mk', + Subgroup.comap_upperCentralSeries_quotient_center, upperCentralSeries_eq_center G <| by lia] + end Group.IsPerfect diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 65630cb084419b..f8c36afe217b70 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -218,6 +218,14 @@ theorem mem_upperCentralSeries_succ_iff {n : ℕ} {x : G} : x ∈ upperCentralSeries G (n + 1) ↔ ∀ y : G, ⁅x, y⁆ ∈ upperCentralSeries G n := Iff.rfl +variable (G) in +@[to_additive] +theorem commutator_upperCentralSeries_top_le (n : ℕ) : + ⁅upperCentralSeries G (n + 1), ⊤⁆ ≤ upperCentralSeries G n := by + apply closure_le _ |>.mpr + rintro _ ⟨h, hh, g, _, rfl⟩ + exact mem_upperCentralSeries_succ_iff.mp hh g + @[to_additive (attr := simp)] lemma comap_upperCentralSeries {H : Type*} [Group H] (e : H ≃* G) : ∀ n, (upperCentralSeries G n).comap e = upperCentralSeries H n diff --git a/Mathlib/GroupTheory/Subgroup/Centralizer.lean b/Mathlib/GroupTheory/Subgroup/Centralizer.lean index f0954a435f7858..110e7845251dea 100644 --- a/Mathlib/GroupTheory/Subgroup/Centralizer.lean +++ b/Mathlib/GroupTheory/Subgroup/Centralizer.lean @@ -74,6 +74,10 @@ theorem centralizer_le {s t : Set G} (h : s ⊆ t) : centralizer t ≤ centraliz theorem centralizer_eq_top_iff_subset {s : Set G} : centralizer s = ⊤ ↔ s ⊆ center G := SetLike.ext'_iff.trans Set.centralizer_eq_top_iff_subset +@[to_additive (attr := simp)] +theorem centralizer_center : centralizer (center G : Set G) = ⊤ := + centralizer_eq_top_iff_subset.mpr le_rfl + @[to_additive] theorem map_centralizer_le_centralizer_image (s : Set G) (f : G →* G') : (Subgroup.centralizer s).map f ≤ Subgroup.centralizer (f '' s) := by From 47e5a92e3e50719cfd16002ac2dd144af7cf947e Mon Sep 17 00:00:00 2001 From: Joris Roos <170825715+roos-j@users.noreply.github.com> Date: Wed, 24 Jun 2026 02:55:26 +0000 Subject: [PATCH 0306/1300] feat(Analysis/Calculus): add `uniqueDiffOn_uIcc` (#40702) --- Mathlib/Analysis/Calculus/TangentCone/Real.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Analysis/Calculus/TangentCone/Real.lean b/Mathlib/Analysis/Calculus/TangentCone/Real.lean index 1f389e2985e4c9..cae58175fd1a14 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Real.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Real.lean @@ -99,6 +99,9 @@ theorem uniqueDiffOn_Iio (a : ℝ) : UniqueDiffOn ℝ (Iio a) := theorem uniqueDiffOn_Icc {a b : ℝ} (hab : a < b) : UniqueDiffOn ℝ (Icc a b) := uniqueDiffOn_convex (convex_Icc a b) <| by simp only [interior_Icc, nonempty_Ioo, hab] +theorem uniqueDiffOn_uIcc {a b : ℝ} (hab : a ≠ b) : UniqueDiffOn ℝ (uIcc a b) := + uniqueDiffOn_Icc <| min_lt_max.mpr hab + theorem uniqueDiffOn_Ico (a b : ℝ) : UniqueDiffOn ℝ (Ico a b) := if hab : a < b then uniqueDiffOn_convex (convex_Ico a b) <| by simp only [interior_Ico, nonempty_Ioo, hab] From db8879cb2c88093b5b369570a01b503c871c8151 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Wed, 24 Jun 2026 03:53:14 +0000 Subject: [PATCH 0307/1300] ci: split build job so post-build chain overlaps test+lint (#40233) Peel `test` and `lint` out of the self-hosted `build` job into a new self-hosted `test_lint` job, so the GitHub-hosted post-build chain (`upload_cache` -> `post_steps`) no longer waits behind the ~300s test+lint tail of `build`. - New action `setup-build-env`: contains shared setup steps between `build` and `test_lint` (added in #40733 by @marcelolynch) - New `test_lint` job (self-hosted, `needs: [build, upload_cache]`): fetches this run's oleans from an artifact uploaded at the end of `build` + cache from `master` using the action added in #40678 + verifies the Mathlib cache is complete (mirrors `post_steps`), then runs test, lint, and the nightly-testing comment. - `build` job: `test`/`lint` removed; `noisy` moved up to right after the Counterexamples build (it only needs the just-built oleans), so it stays in `build` and `test_lint` need not fetch Archive/Counterexamples. `test`/`lint` outputs move to `test_lint`. - `final`: now also `needs: test_lint` and requires its success. Prepared with Claude code Co-authored-by: Marcelo Lynch --- .github/actions/setup-build-env/action.yml | 157 ++++++++++ .github/workflows/build_template.yml | 324 +++++++++------------ bors.toml | 2 +- 3 files changed, 302 insertions(+), 181 deletions(-) create mode 100644 .github/actions/setup-build-env/action.yml diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml new file mode 100644 index 00000000000000..31298cdb1a88d6 --- /dev/null +++ b/.github/actions/setup-build-env/action.yml @@ -0,0 +1,157 @@ +# Shared runner setup for the self-hosted `build` and `test_lint` jobs in +# build_template.yml. Both run on the same Hoskinson pool and need the same +# preparation before they diverge (build → build + stage, test_lint → +# fetch + test + lint): toolchain hygiene, jq, the cache-trust and get-tools +# wiring, the PR-branch checkout, the elan toolchain and LEAN_SRC_PATH +# environment, and the dependency download. +# +# The caller runs `Checkout local actions` (sparse `.github/actions` → +# `workflow-actions/`) before invoking this action: that checkout puts both this +# action and the sibling actions it calls (`cache-trust-dispatch`, `get-tools`) +# on disk under `workflow-actions/`, so the `uses: ./workflow-actions/...` paths +# below resolve relative to the workspace root, as in the calling workflow. +# +# Each `run:` step sets its own `shell:`, since composite steps do not inherit the +# job's landrun `defaults.run.shell`. +name: Set up build environment +description: Shared self-hosted runner setup for the build and test_lint jobs. + +inputs: + pr_branch_ref: + description: Git ref of the PR branch to check out and build. + required: true + tools_branch_ref: + description: Git ref to build the CI tools from when not using the prebuilt artifact. + required: false + default: '' + +runs: + using: composite + steps: + # Prune old toolchains from `~/.elan`. That directory is mounted from the host + # and shared across the ephemeral job containers, so toolchains accumulate and + # nothing else trims them (host-side housekeeping only trims the mathlib `.ltar` + # cache). Keep the 5 most recent plus `nightly`/`stable`. + - name: prune old toolchains + shell: bash # just deletes old files; safe to run outside landrun + run: | + # Make sure to delete both the `~/.elan/toolchains/X` directory and the `~/.elan/update-hashes/X` file. + # Skip symbolic links (`-type d`), the current directory (`! -name .`), and `nightly` and `stable`. + if cd ~/.elan/toolchains && find . -maxdepth 1 -type d ! -name . -print0 | xargs -0 ls -1td | grep -v 'nightly$' | grep -v 'stable$' | tail -n +6 | xargs -I {} sh -c 'echo {} && rm -rf "{}" && rm "../update-hashes/{}"'; then + : # Do nothing on success + else + : # Do nothing on failure, but suppress errors + fi + + # The Hoskinson runners may not have jq installed, so do that now. + - name: 'Setup jq' + uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 + + # Compute the trust-classified container target and read fallback for this + # job. Sets MATHLIB_CACHE_FROM / MATHLIB_CACHE_PRIMARY in env so every + # subsequent `cache get` inherits them without per-call flag plumbing. Loaded + # from the trust-rooted `workflow-actions/` checkout, not the PR branch. + - name: Compute cache trust dispatch + uses: ./workflow-actions/.github/actions/cache-trust-dispatch + with: + repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + branch: ${{ github.head_ref || github.ref_name }} + head-sha: ${{ github.event.pull_request.head.sha || github.sha }} + + # Checkout the PR branch into a subdirectory. HEAD only (fetch-depth: 1) is + # enough: the cache is fetched HEAD-scoped and warmed from the master snapshot, + # so no parent-commit history is needed. This is untrusted (potentially fork) + # code we build, so don't leave the GITHUB_TOKEN in pr-branch/.git/config where + # that code could read it. + - name: Checkout PR branch + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + ref: ${{ inputs.pr_branch_ref }} + fetch-depth: 1 + path: pr-branch + persist-credentials: false + + # Create empty directories so landrun doesn't complain. + - name: Create empty directories + shell: bash # We need to run this outside landrun, as it is a prerequisite for landrun! + run: | + mkdir -p pr-branch/.lake/ + mkdir -p .cache/mathlib/ + mkdir -p _work + + # NOTE: if you copy this, consider using `leanprover/lean-action` instead. + # We install manually, to avoid running lean outside landrun. + - name: install elan + shell: bash + run: | + set -o pipefail + curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh + chmod +x elan-init.sh + ./elan-init.sh -y --default-toolchain none + echo "$HOME/.elan/bin" >> "${GITHUB_PATH}" + + - name: set toolchain directory + shell: bash + run: | + cd pr-branch + # Get the lake binary path from elan and extract toolchain directory + LAKE_PATH=$(elan which lake) + echo "Lake path: $LAKE_PATH" + + # Extract the toolchain directory by removing /bin/lake from the end + TOOLCHAIN_DIR=$(dirname "$LAKE_PATH") + TOOLCHAIN_DIR=$(dirname "$TOOLCHAIN_DIR") + echo "Toolchain directory: $TOOLCHAIN_DIR" + + # Set it as an environment variable for subsequent steps + echo "TOOLCHAIN_DIR=$TOOLCHAIN_DIR" >> "$GITHUB_ENV" + + - name: set LEAN_SRC_PATH + shell: bash + run: | + cd pr-branch + + # Start with the base paths + LEAN_SRC_PATH=".:$TOOLCHAIN_DIR/src/lean/lake" + + # Extract package names from lake-manifest.json and validate them + # Only allow A-Z, a-z, 0-9, _, and - characters + # Build the LEAN_SRC_PATH by appending each validated package + PACKAGE_NAMES=$(jq -r '.packages[].name' lake-manifest.json) + for pkg in $PACKAGE_NAMES; do + if [[ "$pkg" =~ ^[A-Za-z0-9_-]+$ ]]; then + LEAN_SRC_PATH="$LEAN_SRC_PATH:.lake/packages/$pkg" + else + echo "Warning: Skipping invalid package name: $pkg" + fi + done + + echo "LEAN_SRC_PATH=$LEAN_SRC_PATH" + + # Set it as an environment variable for subsequent steps + echo "LEAN_SRC_PATH=$LEAN_SRC_PATH" >> "$GITHUB_ENV" + + # Populate `tools-branch/` with the trusted CI tooling (the `cache` binary and + # the `lake-build-*` helper scripts invoked by path). Fast path: download the + # prebuilt `tools-bin` artifact published from master (canonical mathlib4 only, + # and only when the branch under test doesn't change the cache tool — get-tools + # makes that comparison against `source_dir`). Source build otherwise. See the + # get-tools action for the full trust rationale. + - name: Get CI tools + uses: ./workflow-actions/.github/actions/get-tools + with: + use_artifact: ${{ inputs.tools_branch_ref == '' && github.repository == 'leanprover-community/mathlib4' }} + tools_source_ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} + source_dir: ${{ github.event.pull_request.head.repo.fork != true && 'pr-branch' || '' }} + github_token: ${{ github.token }} + + - name: download dependencies + # We need network access to download dependencies. We run this inside + # landrun, but restrict disk access: + # - --rox access to `~/.elan` and `~/actions-runner/_work` (GitHub CI needs this) + # - --unrestricted-network as we need this to download dependencies + # - git needs read only access to `/etc`. + shell: landrun --unrestricted-network --rox /etc --rox /usr --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} + run: | + cd pr-branch + lake env diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 518274f97c7627..9e742026b1aec5 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -57,11 +57,11 @@ jobs: archive-outcome: ${{ steps.archive.outcome }} counterexamples-outcome: ${{ steps.counterexamples.outcome }} cache-staging-has-files: ${{ steps.cache_staging_check.outputs.has_files }} - lint-outcome: ${{ steps.lint.outcome }} mk_all-outcome: ${{ steps.mk_all.outcome }} noisy-outcome: ${{ steps.noisy.outcome }} # shake-outcome: ${{ steps.shake.outcome }} - test-outcome: ${{ steps.test.outcome }} + # `test`/`lint` outcomes are exposed by the `test_lint` job (and consumed by + # its nightly-testing comment step). defaults: # On Hoskinson runners, landrun is already installed. run: # note that .pr-branch/.lake must be created in a step below before we use this shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} @@ -77,26 +77,6 @@ jobs: shell: bash # there is no script body, so this is safe to "run" outside landrun. run: | # We just populate the env vars for this step to make them viewable in the logs - - name: cleanup - shell: bash # This *just* deletes old files, so is safe to run outside landrun. - run: | - if ! find . -mindepth 1 -exec rm -rf -- {} +; then - echo "ERROR: Initial cleanup failed, waiting 5 seconds and retrying..." - sleep 5 - find . -mindepth 1 -exec rm -rf -- {} + - fi - # Delete all but the 5 most recent toolchains. - # Make sure to delete both the `~/.elan/toolchains/X` directory and the `~/.elan/update-hashes/X` file. - # Skip symbolic links (`-type d`), the current directory (`! -name .`), and `nightly` and `stable`. - if cd ~/.elan/toolchains && find . -maxdepth 1 -type d ! -name . -print0 | xargs -0 ls -1td | grep -v 'nightly$' | grep -v 'stable$' | tail -n +6 | xargs -I {} sh -c 'echo {} && rm -rf "{}" && rm "../update-hashes/{}"'; then - : # Do nothing on success - else - : # Do nothing on failure, but suppress errors - fi - - # The Hoskinson runners may not have jq installed, so do that now. - - name: 'Setup jq' - uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: Checkout local actions uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -106,43 +86,15 @@ jobs: sparse-checkout: .github/actions path: workflow-actions - # We need to 'duplicate' this step below because GitHub Actions does not let a `uses:` step - # conditionally omit a single `with:` key, and passing `ref: ''` would override - # the composite action's default to the empty string instead of falling back to it - # Note only one of the two below will actually run in any given run - - name: Get mathlib-ci - if: ${{ inputs.mathlib_ci_ref == '' }} - uses: ./workflow-actions/.github/actions/get-mathlib-ci - - - name: Get mathlib-ci - if: ${{ inputs.mathlib_ci_ref != '' }} - uses: ./workflow-actions/.github/actions/get-mathlib-ci - with: - ref: ${{ inputs.mathlib_ci_ref }} - - # Compute the trust-classified container target and read fallback - # for this job. Sets MATHLIB_CACHE_FROM / MATHLIB_CACHE_PRIMARY in - # env so every subsequent `cache get` in this job inherits them - # without per-call flag plumbing. Loaded from master via the sparse - # `workflow-actions/` checkout above, not from the PR branch — this - # keeps the trust policy out of fork-controllable file paths. - - name: Compute cache trust dispatch - uses: ./workflow-actions/.github/actions/cache-trust-dispatch + # Shared self-hosted setup (toolchain prune, jq, cache-trust dispatch, + # PR-branch checkout, elan + toolchain/LEAN_SRC_PATH env, CI tools, dependency + # download); see the action for per-step rationale. It is loaded from the + # `Checkout local actions` checkout above, which therefore runs first. + - name: Set up build environment + uses: ./workflow-actions/.github/actions/setup-build-env with: - repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - branch: ${{ github.head_ref || github.ref_name }} - head-sha: ${{ github.event.pull_request.head.sha || github.sha }} - - # Checkout the PR branch into a subdirectory - - name: Checkout PR branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - ref: ${{ inputs.pr_branch_ref }} - fetch-depth: 2 # we may fetch cache from the commit before this one (or earlier) - path: pr-branch - # This is an untrusted (potentially fork) checkout whose code we build. - # Don't leave the GITHUB_TOKEN in pr-branch/.git/config, where that code could read it. - persist-credentials: false + pr_branch_ref: ${{ inputs.pr_branch_ref }} + tools_branch_ref: ${{ inputs.tools_branch_ref }} # TEMPORARY (cache storage-layout migration, PR #40035): remove once # active branches have merged the new cache tool. @@ -194,103 +146,6 @@ jobs: cp ../lean-toolchain . echo "lean-toolchain copied successfully to DownstreamTest." - # Create empty directories so landrun doesn't complain - - name: Create empty directories - shell: bash # We need to run this outside landrun, as it is a prerequisite for landrun! - run: | - mkdir -p pr-branch/.lake/ - mkdir -p .cache/mathlib/ - mkdir -p _work - - # NOTE: if you copy this, consider using `leanprover/lean-action` instead. - # We install manually, to avoid running lean outside landrun. - - name: install elan - shell: bash - run: | - set -o pipefail - curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh - chmod +x elan-init.sh - ./elan-init.sh -y --default-toolchain none - echo "$HOME/.elan/bin" >> "${GITHUB_PATH}" - - - name: set toolchain directory - shell: bash - run: | - cd pr-branch - # Get the lake binary path from elan and extract toolchain directory - LAKE_PATH=$(elan which lake) - echo "Lake path: $LAKE_PATH" - - # Extract the toolchain directory by removing /bin/lake from the end - TOOLCHAIN_DIR=$(dirname "$LAKE_PATH") - TOOLCHAIN_DIR=$(dirname "$TOOLCHAIN_DIR") - echo "Toolchain directory: $TOOLCHAIN_DIR" - - # Set it as an environment variable for subsequent steps - echo "TOOLCHAIN_DIR=$TOOLCHAIN_DIR" >> "$GITHUB_ENV" - - - name: set LEAN_SRC_PATH - shell: bash - run: | - cd pr-branch - - # Start with the base paths - LEAN_SRC_PATH=".:$TOOLCHAIN_DIR/src/lean/lake" - - # Extract package names from lake-manifest.json and validate them - # Only allow A-Z, a-z, 0-9, _, and - characters - # Build the LEAN_SRC_PATH by appending each validated package - PACKAGE_NAMES=$(jq -r '.packages[].name' lake-manifest.json) - for pkg in $PACKAGE_NAMES; do - if [[ "$pkg" =~ ^[A-Za-z0-9_-]+$ ]]; then - LEAN_SRC_PATH="$LEAN_SRC_PATH:.lake/packages/$pkg" - else - echo "Warning: Skipping invalid package name: $pkg" - fi - done - - echo "LEAN_SRC_PATH=$LEAN_SRC_PATH" - - # Set it as an environment variable for subsequent steps - echo "LEAN_SRC_PATH=$LEAN_SRC_PATH" >> "$GITHUB_ENV" - - # Populate `tools-branch/` with the trusted CI tooling (the `cache` binary and - # the `lake-build-*` helper scripts invoked by path below). - # - # - Fast path: download the prebuilt `tools-bin` artifact published from - # `master` by `publish_tools.yml` — only on canonical mathlib4, and only - # when the branch under test doesn't change the cache tool. `get-tools` - # makes that comparison itself against `source_dir` (the already-checked- - # out `pr-branch`), so the tool-source path list lives in the action, not - # duplicated here. - # - Source build: from `tools_source_ref`, pointed at the branch *under - # test* (`pr_branch_ref`) — bors `staging`/`trying`, in-repo dev branches, - # and the nightly-testing repo (which has no `master` branch) — so the - # built tool matches the tree. Fork PRs keep `master` and skip the - # comparison (empty `source_dir`): they run master's `build_template` via - # `pull_request_target`, never this one, and their untrusted tool must - # never be built/run with cache credentials (bors exercises tool changes - # in-repo instead). - - name: Get CI tools - uses: ./workflow-actions/.github/actions/get-tools - with: - use_artifact: ${{ inputs.tools_branch_ref == '' && github.repository == 'leanprover-community/mathlib4' }} - tools_source_ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} - source_dir: ${{ github.event.pull_request.head.repo.fork != true && 'pr-branch' || '' }} - github_token: ${{ github.token }} - - - name: download dependencies - # We need network access to download dependencies - # We run this inside landrun, but restrict disk access. - # Landrun argument notes: - # - we give --rox access to `~/.elan` and `~/actions-runner/_work` (GitHub CI needs this) - # - we give --unrestricted-network as we need this to download dependencies - # - git needs read only access to `/etc`. - shell: landrun --unrestricted-network --rox /etc --rox /usr --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} - run: | - cd pr-branch - lake env - - name: validate lake-manifest.json inputRevs # Only enforce this on the main mathlib4 repository, not on nightly-testing if: github.repository == 'leanprover-community/mathlib4' && github.ref_name != 'nightly-testing' @@ -397,6 +252,24 @@ jobs: ../tools-branch/scripts/lake-build-with-retry.sh Counterexamples # results of build at pr-branch/.lake/build_summary_Counterexamples.json + # Runs in the build job because it only needs the freshly-built Mathlib/ + # Archive/Counterexamples oleans, which are present here; keeping it in + # `build` also spares `test_lint` from fetching Archive/Counterexamples. + - name: check for noisy stdout lines + id: noisy + run: | + cd pr-branch + buildMsgs="$( + ## we exploit `lake`s replay feature: since the cache is present, running + ## `lake build` will reproduce all the outputs without having to recompute + lake build -q --iofail Mathlib Archive Counterexamples + )" + if [ -n "${buildMsgs}" ] + then + printf $'%s\n' "${buildMsgs}" + exit 1 + fi + - name: prepare staging directory if: ${{ always() && (steps.build.outcome == 'success' || steps.build.outcome == 'failure' || steps.build.outcome == 'cancelled') }} shell: bash @@ -443,6 +316,8 @@ jobs: with: name: cache-staging path: cache-staging/ + # The `.ltar` files are already zstd-compressed; recompressing wastes CPU. + compression-level: 0 # Prune to this commit's `.ltar` set so the published snapshot is exactly master's # current cache (the local dir also holds the previous snapshot it warmed from). @@ -489,23 +364,127 @@ jobs: echo "'mk_all --check' passed successfully." fi + test_lint: + name: Test and lint + needs: [build] + # Runs `test` and `lint` on the same self-hosted pool as `build`, but as a + # separate job so it runs in parallel with the GitHub-hosted post-build chain + # (upload_cache -> post_steps) rather than ahead of it. `build` and `test_lint` + # run sequentially on the pool, so peak per-run concurrency is unchanged; the + # only cost is a second setup prefix on a fresh runner. + # + # It does not depend on `upload_cache`: it reconstitutes this run's oleans + # without the paid Azure round-trip, by downloading the `cache-staging` artifact + # `build` produces (this commit's freshly-built delta) and warming the rest from + # the master `cache-snapshot` via the `get-cache` action. The `verify the Mathlib + # cache is complete` step below fails loudly if that reconstitution is incomplete, + # rather than silently rebuilding under landrun (which has no network). + # + # Gating: runs when `build` succeeded or failed (not cancelled/skipped). Running + # on build FAILURE too means `lint` still reports results on a failed build, + # best-effort over whatever oleans were built. The per-step conditions below + # match: `test` only on a clean build, `lint` on success-or-failure. + if: ${{ always() && (needs.build.result == 'success' || needs.build.result == 'failure') }} + runs-on: ${{ inputs.runs_on }} + outputs: + lint-outcome: ${{ steps.lint.outcome }} + test-outcome: ${{ steps.test.outcome }} + defaults: # On Hoskinson runners, landrun is already installed. + run: # note that pr-branch/.lake must be created in a step below before we use this + shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} + steps: + - name: Checkout local actions + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + ref: ${{ github.workflow_sha }} + fetch-depth: 1 + sparse-checkout: .github/actions + path: workflow-actions + + # Shared self-hosted setup (see the action). + - name: Set up build environment + uses: ./workflow-actions/.github/actions/setup-build-env + with: + pr_branch_ref: ${{ inputs.pr_branch_ref }} + tools_branch_ref: ${{ inputs.tools_branch_ref }} + + # mathlib-ci provides the scripts for the lean-pr-testing comment at the end of + # this job, which runs only on the nightly-testing repo — so check it out only + # there. Written twice because a `uses:` step cannot conditionally omit the + # single `ref` key (`ref: ''` would override the action's pinned default). + - name: Get mathlib-ci + if: ${{ github.repository == 'leanprover-community/mathlib4-nightly-testing' && inputs.mathlib_ci_ref == '' }} + uses: ./workflow-actions/.github/actions/get-mathlib-ci + + - name: Get mathlib-ci + if: ${{ github.repository == 'leanprover-community/mathlib4-nightly-testing' && inputs.mathlib_ci_ref != '' }} + uses: ./workflow-actions/.github/actions/get-mathlib-ci + with: + ref: ${{ inputs.mathlib_ci_ref }} + + # Pre-populate the local cache with this commit's freshly-built delta: the + # `cache-staging` artifact `build` produces holds its newly-built `.ltar` — + # the oleans not already in the master snapshot. `get-cache` below then warms + # the unchanged bulk from the master `cache-snapshot` and unpacks everything, + # so the bulk of the cache is not re-downloaded from paid Azure storage. + # Gated on `cache-staging-has-files`: a full cache hit stages nothing (no + # artifact is uploaded), and `get-cache` alone then covers the commit. + - name: download cache staging artifact + if: ${{ needs.build.outputs.cache-staging-has-files == 'true' }} + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: cache-staging + path: /home/lean/.cache/mathlib + + # Warm the unchanged bulk from the master `cache-snapshot` and fetch/unpack + # this commit's oleans. The staged `.ltar` placed above are already local, so + # `get-cache`'s `cache get` decompresses them rather than re-downloading; only + # anything still missing is pulled from Azure. + - name: Get cache + uses: ./workflow-actions/.github/actions/get-cache + with: + working_directory: pr-branch + cache_bin: ../tools-branch/.lake/build/bin/cache + + - name: verify the Mathlib cache is complete + # Enforced only when the build succeeded (then the cache must be complete): + # fail fast rather than silently trying to rebuild under landrun (which has + # no network). On a failed build the cache is expected to be partial, so this + # is skipped and `lint` runs best-effort below. + if: ${{ needs.build.outputs.build-outcome == 'success' }} + # TODO: remove if there are no issues + continue-on-error: true + run: | + cd pr-branch + lake build --no-build --rehash -v Mathlib + + # `test` runs only on a clean build: `build` itself, the `mk_all` check, and + # the archive/counterexamples builds all succeeded. The condition reads those + # from the build job's outputs, and the problem-matcher wrap is gated to match. - name: begin gh-problem-match-wrap for test step + if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 with: action: add # In order to be able to run a multiline script, we need to add/remove the problem matcher before and after. linters: lean - name: test mathlib + if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} id: test run: | cd pr-branch ../tools-branch/scripts/lake-build-wrapper.py .lake/build_summary_MathlibTest.json lake --iofail test - name: end gh-problem-match-wrap for test step + if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 with: action: remove linters: lean + # `lint` runs on a build that succeeded or failed (not cancelled). On a failed + # build it lints best-effort over whatever oleans the cache has, so partial + # lint feedback is still reported. The problem-matcher wrap is gated to match. - name: begin gh-problem-match-wrap for shake and lint steps + if: ${{ always() && (needs.build.outputs.build-outcome == 'success' || needs.build.outputs.build-outcome == 'failure') }} uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 with: action: add # In order to be able to run a multiline script, we need to add/remove the problem matcher before and after. @@ -519,7 +498,7 @@ jobs: # cd pr-branch # env LEAN_ABORT_ON_PANIC=1 lake exe shake --gh-style - name: lint mathlib - if: ${{ always() && steps.build.outcome == 'success' || steps.build.outcome == 'failure' }} + if: ${{ always() && (needs.build.outputs.build-outcome == 'success' || needs.build.outputs.build-outcome == 'failure') }} id: lint timeout-minutes: 40 run: | @@ -558,29 +537,12 @@ jobs: done - name: end gh-problem-match-wrap for shake and lint steps + if: ${{ always() && (needs.build.outputs.build-outcome == 'success' || needs.build.outputs.build-outcome == 'failure') }} uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 with: action: remove linters: gcc - - name: check for noisy stdout lines - id: noisy - run: | - cd pr-branch - buildMsgs="$( - ## we exploit `lake`s replay feature: since the cache is present, running - ## `lake build` will reproduce all the outputs without having to recompute - lake build Mathlib Archive Counterexamples | - ## we filter out the output lines that begin with `✔ [xx/yy]`, where xx, yy - ## are either numbers or ?, and the "Build completed successfully." message. - ## We keep the rest, which are actual outputs of the files - awk '!($0 ~ "^\\s*✔ \\[[?0-9]*/[?0-9]*\\]" || $0 ~ "^Build completed successfully( \\([0-9]+ jobs\\))?\\.?$"){ print $0 }')" - if [ -n "${buildMsgs}" ] - then - printf $'%s\n' "${buildMsgs}" - exit 1 - fi - # Generate a fresh token just before posting comments. # GitHub App tokens expire after 1 hour, and the build can take longer than that. - name: Generate lean-pr-testing app token @@ -602,10 +564,12 @@ jobs: TOKEN: ${{ steps.lean-pr-testing-token.outputs.token }} GITHUB_CONTEXT: ${{ toJson(github) }} WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - BUILD_OUTCOME: ${{ steps.build.outcome }} - NOISY_OUTCOME: ${{ steps.noisy.outcome }} - ARCHIVE_OUTCOME: ${{ steps.archive.outcome }} - COUNTEREXAMPLES_OUTCOME: ${{ steps.counterexamples.outcome }} + # build/archive/counterexamples/noisy outcomes come from the `build` job's + # outputs; test/lint are produced by this job's own steps. + BUILD_OUTCOME: ${{ needs.build.outputs.build-outcome }} + NOISY_OUTCOME: ${{ needs.build.outputs.noisy-outcome }} + ARCHIVE_OUTCOME: ${{ needs.build.outputs.archive-outcome }} + COUNTEREXAMPLES_OUTCOME: ${{ needs.build.outputs.counterexamples-outcome }} LINT_OUTCOME: ${{ steps.lint.outcome }} TEST_OUTCOME: ${{ steps.test.outcome }} NIGHTLY_TESTING_REPO: leanprover-community/mathlib4-nightly-testing @@ -868,8 +832,8 @@ jobs: final: name: Post-CI job # ensure that this runs iff direct dependencies succeeded even if transitive dependencies were skipped - if: ${{ always() && inputs.run_post_ci && needs.style_lint.result == 'success' && needs.build.result == 'success' && needs.post_steps.result == 'success' }} - needs: [style_lint, build, post_steps] + if: ${{ always() && inputs.run_post_ci && needs.style_lint.result == 'success' && needs.build.result == 'success' && needs.test_lint.result == 'success' && needs.post_steps.result == 'success' }} + needs: [style_lint, build, test_lint, post_steps] runs-on: ubuntu-latest steps: - id: PR diff --git a/bors.toml b/bors.toml index 0dd32adf0ec53e..f9b7e3550fb4d6 100644 --- a/bors.toml +++ b/bors.toml @@ -1,4 +1,4 @@ -status = ["ci (staging) / Build", "ci (staging) / Lint style", "ci (staging) / Post-Build Step", "ci (staging) / Post-CI job"] +status = ["ci (staging) / Build", "ci (staging) / Test and lint", "ci (staging) / Lint style", "ci (staging) / Post-Build Step", "ci (staging) / Post-CI job"] use_squash_merge = true timeout_sec = 7200 block_labels = ["WIP", "blocked-by-other-PR", "merge-conflict", "awaiting-CI"] From fa97836994f0cf44850c4335da2a1df47b51f38f Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Wed, 24 Jun 2026 04:01:48 +0000 Subject: [PATCH 0308/1300] ci: let bors manage PR lifecycle labels (#40763) After https://github.com/leanprover-community/bors-ng/pull/53, bors is now capable of managing PR lifecycle labels directly from its own state (queue membership and delegations), opt-in via a `[labels]` table in `bors.toml`. This fixes `delegated` labels stranded by expirations, as well as `ready-to-merge` labels stuck on PRs that fell off the queue, and also allows us to add and manage 2 new labels: - `bors-staging`: PRs that are in the currently building batch will get this label - `awaiting-requeue`: PRs that were on the bors queue but now require a requeue due to something going wrong will get this label Changes in this PR: - bors.toml: add a `[labels]` table mapping all four lifecycle concerns to mathlib4's label names: `on_queue` -> `ready-to-merge`, `building` -> `bors-staging`, `failed` -> `awaiting-requeue`, `delegated` -> `delegated`. (`bors-staging` and `awaiting-requeue` are new labels for this repo.) - maintainer_bors.yml / maintainer_bors_wf_run.yml: strip the `ready-to-merge`/`delegated` add/remove logic (and the `Build failed:` -> `delegated` re-apply quirk and the `bors r-`/`d-` removal path) now that bors owns those labels. The workflows keep their other jobs: detecting merge/delegate commands, removing `awaiting-author` / `maintainer-merge`, and updating Zulip emoji reactions. Renamed to "Bors merge/delegate follow-up" to match, keeping the workflow_run linkage consistent. - docs/workflows.md: update the two workflow descriptions. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/maintainer_bors.yml | 36 +++++--------- .github/workflows/maintainer_bors_wf_run.yml | 51 +++++--------------- bors.toml | 7 +++ docs/workflows.md | 4 +- 4 files changed, 34 insertions(+), 64 deletions(-) diff --git a/.github/workflows/maintainer_bors.yml b/.github/workflows/maintainer_bors.yml index 44ff2d6b88e8a8..19b8e505d9488f 100644 --- a/.github/workflows/maintainer_bors.yml +++ b/.github/workflows/maintainer_bors.yml @@ -1,4 +1,4 @@ -name: Add "ready-to-merge" and "delegated" label +name: Bors merge/delegate follow-up # triggers the action when on: @@ -21,7 +21,7 @@ permissions: contents: read jobs: - add_ready_to_merge_label: + bors_command_followup: # we set some variables. The ones of the form `${{ X }}${{ Y }}` are typically not # both set simultaneously: depending on the event that triggers the PR, usually only one is set env: @@ -29,8 +29,7 @@ jobs: COMMENT_EVENT: ${{ github.event.comment.body }} COMMENT_REVIEW: ${{ github.event.review.body }} PR_NUMBER: ${{ github.event.issue.number }}${{ github.event.pull_request.number }} - HAS_DELEGATED_LABEL: ${{ contains(github.event.issue.labels.*.name, 'delegated') }} - name: Add ready-to-merge or delegated label + name: Detect bors merge/delegate command runs-on: ubuntu-latest if: >- # coarse prefilter to avoid running on irrelevant comments/reviews github.repository == 'leanprover-community/mathlib4' && @@ -38,8 +37,7 @@ jobs: ( contains(format('{0}{1}', github.event.comment.body, github.event.review.body), 'bors merge') || contains(format('{0}{1}', github.event.comment.body, github.event.review.body), 'bors d') || - contains(format('{0}{1}', github.event.comment.body, github.event.review.body), 'bors r') || - contains(format('{0}{1}', github.event.comment.body, github.event.review.body), 'Build failed:') + contains(format('{0}{1}', github.event.comment.body, github.event.review.body), 'bors r') ) steps: - name: Find bors merge/delegate @@ -51,26 +49,20 @@ jobs: # for debugging, we print some information printf '%s' "${COMMENT}" | hexdump -cC printf 'Comment:"%s"\n' "${COMMENT}" - if [ "${AUTHOR}" == 'mathlib-bors[bot]' ] && [ "${HAS_DELEGATED_LABEL}" == 'true' ] - then - m_or_d="$(printf '%s' "${COMMENT}" | - sed -n 's=^Build failed:=delegated=p' | head -1)" - else - m_or_d="$(printf '%s' "${COMMENT}" | - sed -n 's=^bors *\(merge\|r+\) *$=ready-to-merge=p; s=^bors *\(delegate\|d+\|d\=\).*=delegated=p' | head -1)" - fi - - remove_labels="$(printf '%s' "${COMMENT}" | - sed -n 's=^bors *\(merge\|r\|d\)- *$=remove-labels=p' | head -1)" + # `mOrD` records which command this is ("ready-to-merge" or "delegated"). + # It no longer drives any label: bors now manages the `ready-to-merge` and + # `delegated` lifecycle labels itself (see the `[labels]` table in bors.toml). + # It is kept only to select the Zulip emoji and to gate the + # awaiting-author/maintainer-merge cleanup in `maintainer_bors_wf_run.yml`. + m_or_d="$(printf '%s' "${COMMENT}" | + sed -n 's=^bors *\(merge\|r+\) *$=ready-to-merge=p; s=^bors *\(delegate\|d+\|d\=\).*=delegated=p' | head -1)" printf $'"bors delegate" or "bors merge" found? \'%s\'\n' "${m_or_d}" - printf $'"bors r-" or "bors d-" found? \'%s\'\n' "${remove_labels}" printf $'AUTHOR: \'%s\'\n' "${AUTHOR}" printf $'PR_NUMBER: \'%s\'\n' "${PR_NUMBER}" printf $'%s' "${PR_NUMBER}" | hexdump -cC printf $'mOrD=%s\n' "${m_or_d}" >> "${GITHUB_OUTPUT}" - printf $'removeLabels=%s\n' "${remove_labels}" >> "${GITHUB_OUTPUT}" if [ "${AUTHOR}" == 'leanprover-community-mathlib4-bot' ] || [ "${AUTHOR}" == 'leanprover-community-bot-assistant' ] || [ "${AUTHOR}" == 'mathlib-bors[bot]' ] || @@ -83,20 +75,18 @@ jobs: printf $'bot=false\n' >> "${GITHUB_OUTPUT}" fi - - if: ${{ ! steps.merge_or_delegate.outputs.mOrD == '' || ! steps.merge_or_delegate.outputs.removeLabels == '' }} + - if: ${{ ! steps.merge_or_delegate.outputs.mOrD == '' }} name: Prepare bridge outputs run: | jq -n \ --arg bot "${{ steps.merge_or_delegate.outputs.bot }}" \ - --arg removeLabels "${{ steps.merge_or_delegate.outputs.removeLabels }}" \ --arg mOrD "${{ steps.merge_or_delegate.outputs.mOrD }}" \ '{ bot: $bot, - removeLabels: $removeLabels, mOrD: $mOrD, }' > bridge-outputs.json - - if: ${{ ! steps.merge_or_delegate.outputs.mOrD == '' || ! steps.merge_or_delegate.outputs.removeLabels == '' }} + - if: ${{ ! steps.merge_or_delegate.outputs.mOrD == '' }} name: Emit bridge artifact uses: leanprover-community/privilege-escalation-bridge/emit@f5dfe313a79647c07315b451b2dc2a81a161a50d # v1.2.0 with: diff --git a/.github/workflows/maintainer_bors_wf_run.yml b/.github/workflows/maintainer_bors_wf_run.yml index d67089472846df..7d4b4f7f62a187 100644 --- a/.github/workflows/maintainer_bors_wf_run.yml +++ b/.github/workflows/maintainer_bors_wf_run.yml @@ -1,8 +1,8 @@ -name: Add "ready-to-merge" and "delegated" label (workflow_run) +name: Bors merge/delegate follow-up (workflow_run) on: workflow_run: - workflows: ['Add "ready-to-merge" and "delegated" label'] + workflows: ['Bors merge/delegate follow-up'] types: - completed @@ -12,8 +12,8 @@ permissions: jobs: - add_ready_to_merge_label: - name: Add ready-to-merge or delegated label + bors_command_followup: + name: Bors merge/delegate follow-up runs-on: ubuntu-latest if: ${{ github.repository == 'leanprover-community/mathlib4' && github.event.workflow_run.conclusion == 'success' }} permissions: @@ -26,7 +26,7 @@ jobs: uses: leanprover-community/privilege-escalation-bridge/consume@f5dfe313a79647c07315b451b2dc2a81a161a50d # v1.2.0 with: artifact: workflow-data - source_workflow: Add "ready-to-merge" and "delegated" label + source_workflow: Bors merge/delegate follow-up require_event: issue_comment,pull_request_review,pull_request_review_comment fail_on_missing: false token: ${{ github.token }} @@ -34,7 +34,6 @@ jobs: author=event.comment.user.login|event.review.user.login pr_number=meta.pr_number bot=outputs.bot - removeLabels=outputs.removeLabels mOrD=outputs.mOrD - name: Download legacy artifact (fallback) @@ -62,7 +61,6 @@ jobs: echo "author=$(jq -r '.author // empty' "${data_file}")" echo "pr_number=$(jq -r '.pr_number // empty' "${data_file}")" echo "bot=$(jq -r '.bot // empty' "${data_file}")" - echo "removeLabels=$(jq -r '.removeLabels // .remove_labels // empty' "${data_file}")" echo "mOrD=$(jq -r '.mOrD // .m_or_d // empty' "${data_file}")" } | tee -a "$GITHUB_OUTPUT" @@ -73,7 +71,6 @@ jobs: INPUT_AUTHOR: ${{ steps.bridge.outputs.author }}${{ steps.legacy.outputs.author }} INPUT_PR_NUMBER: ${{ steps.bridge.outputs.pr_number }}${{ steps.legacy.outputs.pr_number }} INPUT_BOT: ${{ steps.bridge.outputs.bot }}${{ steps.legacy.outputs.bot }} - INPUT_REMOVE_LABELS: ${{ steps.bridge.outputs.removeLabels }}${{ steps.legacy.outputs.removeLabels }} INPUT_MORD: ${{ steps.bridge.outputs.mOrD }}${{ steps.legacy.outputs.mOrD }} INPUT_SOURCE: ${{ steps.bridge.outputs.pr_number != '' && 'bridge' || (steps.legacy.outputs.pr_number != '' && 'legacy' || 'none') }} run: | @@ -81,7 +78,6 @@ jobs: echo "author=${INPUT_AUTHOR}" echo "pr_number=${INPUT_PR_NUMBER}" echo "bot=${INPUT_BOT}" - echo "removeLabels=${INPUT_REMOVE_LABELS}" echo "mOrD=${INPUT_MORD}" echo "input_source=${INPUT_SOURCE}" } | tee -a "$GITHUB_OUTPUT" @@ -94,7 +90,7 @@ jobs: - name: Check whether user is a mathlib admin id: user_permission - if: ${{ ! steps.inputs.outputs.mOrD == '' || ! steps.inputs.outputs.removeLabels == '' }} + if: ${{ ! steps.inputs.outputs.mOrD == '' }} uses: actions-cool/check-user-permission@c21884f3dda18dafc2f8b402fe807ccc9ec1aa5e # v2.4.0 with: username: ${{ steps.inputs.outputs.author }} @@ -103,7 +99,7 @@ jobs: - name: Generate app token id: app-token uses: leanprover-community/mathlib-ci/.github/actions/azure-create-github-app-token@3bb576208589a435eeaeac9b144a1b7c3e948760 - if: ${{ ! steps.inputs.outputs.mOrD == '' || ! steps.inputs.outputs.removeLabels == '' }} + if: ${{ ! steps.inputs.outputs.mOrD == '' }} with: app-id: ${{ secrets.MATHLIB_TRIAGE_APP_ID }} key-vault-name: ${{ vars.MATHLIB_AZ_KEY_VAULT_NAME }} @@ -111,23 +107,11 @@ jobs: azure-client-id: ${{ vars.GH_APP_AZURE_CLIENT_ID_TRIAGE }} azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} - - name: Add ready-to-merge or delegated label - id: add_label - if: ${{ ! steps.inputs.outputs.mOrD == '' && - ( steps.user_permission.outputs.require-result == 'true' || - steps.inputs.outputs.bot == 'true' ) }} - uses: octokit/request-action@b91aabaa861c777dcdb14e2387e30eddf04619ae # v3.0.0 - with: - route: POST /repos/:repository/issues/:issue_number/labels - # Unexpected input warning from the following is expected: - # https://github.com/octokit/request-action?tab=readme-ov-file#warnings - repository: ${{ github.repository }} - issue_number: ${{ steps.inputs.outputs.pr_number }} - labels: '["${{ steps.inputs.outputs.mOrD }}"]' - env: - # This token is masked by the token minting action and will not be logged accidentally - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - + # The `ready-to-merge` / `delegated` lifecycle labels are managed by bors + # itself (see the `[labels]` table in bors.toml); this workflow no longer + # adds or removes them. It still removes the `awaiting-author` and + # `maintainer-merge` labels and updates the Zulip emoji on a merge/delegate + # command. - if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} @@ -142,17 +126,6 @@ jobs: --header 'authorization: Bearer ${{ steps.app-token.outputs.token }}' done - - name: On bors r/d-, remove ready-to-merge or delegated label - if: ${{ ! steps.inputs.outputs.removeLabels == '' && steps.user_permission.outputs.require-result == 'true' }} - # we use curl rather than octokit/request-action so that the job won't fail - # (and send an annoying email) if the labels don't exist - run: | - for label in ready-to-merge delegated; do - curl --request DELETE \ - --url "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.inputs.outputs.pr_number }}/labels/${label}" \ - --header 'authorization: Bearer ${{ steps.app-token.outputs.token }}' - done - - name: Checkout local actions if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || diff --git a/bors.toml b/bors.toml index f9b7e3550fb4d6..acdb67c060ed84 100644 --- a/bors.toml +++ b/bors.toml @@ -6,6 +6,13 @@ delete_merged_branches = true update_base_for_deletes = true cut_body_after = "\n---" max_batch_size = 16 + +[labels] +on_queue = "ready-to-merge" # PR is on the merge queue (a batch waiting or running) +building = "bors-staging" # PR is currently building on staging (such PRs will also have the on_queue label) +failed = "awaiting-requeue" # PR's merge build failed terminally and was dropped; needs a re-queue +delegated = "delegated" # PR has at least one active (non-expired) delegation + [delegation] default_expiry_sec = 1209600 # 2 weeks # Entries below are Erlang `:glob` patterns (NOT gitignore): `*` matches across `/`, diff --git a/docs/workflows.md b/docs/workflows.md index f64770727cb929..60eef0312e97ee 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -59,7 +59,7 @@ Primary trigger for this section: PR/merge-queue events (`pull_request`, `pull_r | File | Name | Importance | Triggers | Description | |---|---|---|---|---| -| [`maintainer_bors.yml`](../.github/workflows/maintainer_bors.yml) | Add "ready-to-merge" and "delegated" label
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_bors.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_bors.yml) | High | `issue_comment, pull_request_review, pull_request_review_comment` | Processes bors merge/delegate commands, updates labels, and emits artifact/context for follow-up workflows. | +| [`maintainer_bors.yml`](../.github/workflows/maintainer_bors.yml) | Bors merge/delegate follow-up
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_bors.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_bors.yml) | High | `issue_comment, pull_request_review, pull_request_review_comment` | Detects bors merge/delegate commands and emits a bridge artifact for the privileged follow-up workflow. The `ready-to-merge`/`delegated` lifecycle labels are managed by bors itself (see `bors.toml`). | | [`maintainer_merge.yml`](../.github/workflows/maintainer_merge.yml) | Maintainer merge
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_merge.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_merge.yml) | High | `issue_comment, pull_request_review, pull_request_review_comment` | Handles maintainer merge/delegate commands, performs permission checks, and posts Zulip/PR notifications. | | [`labels_from_comment.yml`](../.github/workflows/labels_from_comment.yml) | Label PR based on Comment
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/labels_from_comment.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/labels_from_comment.yml) | Medium | `issue_comment, pull_request_review, pull_request_review_comment` | Adds/removes an allowlisted set of labels based on comment/review text commands. | | [`bot_fix_style.yaml`](../.github/workflows/bot_fix_style.yaml) | bot fix style
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/bot_fix_style.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/bot_fix_style.yaml) | Low | `issue_comment, pull_request_review, pull_request_review_comment` | Responds to review/comment events and runs `lint-style-action` in `fix` mode. | @@ -100,7 +100,7 @@ Primary trigger for this section: completion of other workflows (`workflow_run`) |---|---|---|---|---| | [`nightly_detect_failure.yml`](../.github/workflows/nightly_detect_failure.yml) | Post to zulip if the nightly-testing branch is failing.
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/nightly_detect_failure.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/nightly_detect_failure.yml) | High | `workflow_run` | Reacts to nightly-testing CI outcomes; posts status updates and performs branch/tag maintenance on success. | | [`update_dependencies_zulip.yml`](../.github/workflows/update_dependencies_zulip.yml) | Monitor Dependency Update Failures
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/update_dependencies_zulip.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/update_dependencies_zulip.yml) | High | `workflow_run` | Watches dependency-update CI runs and sends Zulip success/failure messages with PR/label handling. | -| [`maintainer_bors_wf_run.yml`](../.github/workflows/maintainer_bors_wf_run.yml) | Add "ready-to-merge" and "delegated" label (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_bors_wf_run.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_bors_wf_run.yml) | Medium | `workflow_run` | Manages labels plus Zulip emoji updates for Bors commands. | +| [`maintainer_bors_wf_run.yml`](../.github/workflows/maintainer_bors_wf_run.yml) | Bors merge/delegate follow-up (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_bors_wf_run.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_bors_wf_run.yml) | Medium | `workflow_run` | Privileged companion: removes `awaiting-author`/`maintainer-merge` and updates Zulip emoji reactions on bors merge/delegate commands. The `ready-to-merge`/`delegated` lifecycle labels are managed by bors itself. | | [`maintainer_merge_wf_run.yml`](../.github/workflows/maintainer_merge_wf_run.yml) | Maintainer merge (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_merge_wf_run.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_merge_wf_run.yml) | Medium | `workflow_run` | Manages labels and posts on Zulip for maintainer merge/delegate commands. | | [`olean_report_wf_run.yaml`](../.github/workflows/olean_report_wf_run.yaml) | olean report (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/olean_report_wf_run.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/olean_report_wf_run.yaml) | Low | `workflow_run` | Privileged companion to `olean_report.yaml`. Downloads the bridge artifact and posts or updates the olean diff as a comment on the PR. | | [`decls-diff.yml`](../.github/workflows/decls-diff.yml) | Declarations diff (post-build)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/decls-diff.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/decls-diff.yml) | Low | `workflow_run` | Post-build companion to `ci` that diffs the `import-graph` artifact of a PR build against its master merge-base and patches the `### PR summary` comment's declarations-diff section with the Lean-aware result (or a cache-miss notice). | From 2af912edc30e3960c7cf95558a834746d840dcb8 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Wed, 24 Jun 2026 07:32:42 +0000 Subject: [PATCH 0309/1300] feat(CategoryTheory/Sites): source local closure of a morphism property (#40528) Co-authored by: Edward van de Meent --- Mathlib.lean | 1 + .../Shapes/Pullback/IsPullback/Basic.lean | 50 +++++++ .../MorphismProperty/LocalClosure.lean | 141 ++++++++++++++++++ .../CategoryTheory/Sites/Hypercover/Zero.lean | 3 + 4 files changed, 195 insertions(+) create mode 100644 Mathlib/CategoryTheory/MorphismProperty/LocalClosure.lean diff --git a/Mathlib.lean b/Mathlib.lean index d3f6317619d23a..881db5f16663e8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3177,6 +3177,7 @@ public import Mathlib.CategoryTheory.MorphismProperty.IsSmall public import Mathlib.CategoryTheory.MorphismProperty.LiftingProperty public import Mathlib.CategoryTheory.MorphismProperty.Limits public import Mathlib.CategoryTheory.MorphismProperty.Local +public import Mathlib.CategoryTheory.MorphismProperty.LocalClosure public import Mathlib.CategoryTheory.MorphismProperty.LocalEpi public import Mathlib.CategoryTheory.MorphismProperty.OfObjectProperty public import Mathlib.CategoryTheory.MorphismProperty.OverAdjunction diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean index fc8dafa3356779..e598b03ba20ed7 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean @@ -994,4 +994,54 @@ end IsPullback end IsPullbackOverPullback +namespace Limits + +instance {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) {X' : C} (i : X' ⟶ X) [IsIso i] [HasPullback f g] : + HasPullback (i ≫ f) g := + IsPullback.paste_vert + (IsPullback.of_vert_isIso_mono (fst := pullback.fst _ _ ≫ inv i) (snd := 𝟙 (pullback f g)) <| + ⟨by simp⟩) (.of_hasPullback f g) |>.hasPullback + +@[simp] +lemma HasPullback.comp_left_left_iff_of_isIso + {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} {X' : C} (i : X' ⟶ X) [IsIso i] : + HasPullback (i ≫ f) g ↔ HasPullback f g := by + refine ⟨fun h ↦ ?_, fun _ ↦ inferInstance⟩ + rw [← IsIso.inv_hom_id_assoc i f] + infer_instance + +instance {X Y Z Z' : C} {f : X ⟶ Z} {g : Y ⟶ Z'} (i : Z ⟶ Z') [IsIso i] [HasPullback (f ≫ i) g] : + HasPullback f (g ≫ inv i) := by + simpa using hasPullback_of_comp_mono (f ≫ i) g (inv i) + +lemma HasPullback.comp_left_right_iff_of_isIso + {X Y Z Z' : C} {f : X ⟶ Z} {g : Y ⟶ Z'} (i : Z ⟶ Z') [IsIso i] : + HasPullback (f ≫ i) g ↔ HasPullback f (g ≫ inv i) := + ⟨fun h ↦ inferInstance, fun h ↦ by simpa using hasPullback_of_comp_mono f (g ≫ inv i) i⟩ + +instance {X Y Z : C} (f : Z ⟶ X) (g : Z ⟶ Y) {X' : C} (i : X ⟶ X') [IsIso i] [HasPushout f g] : + HasPushout (f ≫ i) g := + IsPushout.paste_horiz (.of_hasPushout f g) + (IsPushout.of_horiz_isIso_epi (inl := inv i ≫ pushout.inl _ _) (inr := 𝟙 (pushout f g)) <| + ⟨by simp⟩) |>.hasPushout + +@[simp] +lemma HasPushout.comp_left_left_iff_of_isIso + {X Y Z : C} {f : Z ⟶ X} {g : Z ⟶ Y} {X' : C} (i : X ⟶ X') [IsIso i] : + HasPushout (f ≫ i) g ↔ HasPushout f g := by + refine ⟨fun h ↦ ?_, fun _ ↦ inferInstance⟩ + rw [← Category.comp_id f, ← IsIso.hom_inv_id i, ← Category.assoc] + infer_instance + +instance {X Y Z Z' : C} {f : Z ⟶ X} {g : Z' ⟶ Y} (i : Z' ⟶ Z) [IsIso i] [HasPushout (i ≫ f) g] : + HasPushout f (inv i ≫ g) := by + simpa using hasPushout_of_epi_comp (i ≫ f) g (inv i) + +lemma HasPushout.comp_left_right_iff_of_isIso + {X Y Z Z' : C} {f : Z ⟶ X} {g : Z' ⟶ Y} (i : Z' ⟶ Z) [IsIso i] : + HasPushout (i ≫ f) g ↔ HasPushout f (inv i ≫ g) := + ⟨fun h ↦ inferInstance, fun h ↦ by simpa using hasPushout_of_epi_comp f (inv i ≫ g) i⟩ + +end Limits + end CategoryTheory diff --git a/Mathlib/CategoryTheory/MorphismProperty/LocalClosure.lean b/Mathlib/CategoryTheory/MorphismProperty/LocalClosure.lean new file mode 100644 index 00000000000000..153ee9d616bd1c --- /dev/null +++ b/Mathlib/CategoryTheory/MorphismProperty/LocalClosure.lean @@ -0,0 +1,141 @@ +/- +Copyright (c) 2025 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +module + +public import Mathlib.CategoryTheory.MorphismProperty.Local +public import Mathlib.CategoryTheory.Sites.MorphismProperty + +/-! +# Local closure of morphism properties + +We define the source local closure of a morphism property `P` w.r.t. a precoverage `K` as the +weakest property containing `P` that is `K`-local on the source. +-/ + +@[expose] public section + +universe w v u + +open CategoryTheory Limits MorphismProperty + +variable {C : Type u} [Category.{v} C] + +namespace CategoryTheory.MorphismProperty + +variable {K : Precoverage C} + +/-- The source-local closure of `P` along a precoverage `K` is the weakest property +containing `P` that is local on the source. -/ +inductive sourceLocalClosure (K : Precoverage C) (P : MorphismProperty C) : MorphismProperty C + /-- Force `P ≤ sourceLocalClosure K P`. -/ + | of {X Y : C} (f : X ⟶ Y) : P f → sourceLocalClosure K P f + /-- Force `RespectsIso`. -/ + | of_iso {X Y X' Y' : C} (f : X ⟶ Y) (g : X' ⟶ Y') (e : Arrow.mk f ≅ Arrow.mk g) : + sourceLocalClosure K P f → sourceLocalClosure K P g + | comp {X Y : C} (f : X ⟶ Y) (hf : sourceLocalClosure K P f) (R : Presieve X) (hR : R ∈ K X) + {U : C} (g : U ⟶ X) : R g → sourceLocalClosure K P (g ≫ f) + | of_presieve {X Y : C} (f : X ⟶ Y) (R : Presieve X) (hR : R ∈ K X) + (h : ∀ (U : C) (g : U ⟶ X), R g → sourceLocalClosure K P (g ≫ f)) : + sourceLocalClosure K P f + +namespace sourceLocalClosure + +attribute [grind .] of + +variable {P Q : MorphismProperty C} {X Y : C} + +instance : (sourceLocalClosure K P).IsLocalAtSource K where + precomp i hi f hf := .of_iso _ _ (Arrow.isoMk' _ _ (asIso i).symm (.refl _)) hf + postcomp i hi f hf := .of_iso _ _ (Arrow.isoMk' _ _ (.refl _) (asIso i)) hf + comp hR _ g hg hf := .comp _ hf _ hR _ hg + of_forall_comp hR h := .of_presieve _ _ hR h + +lemma le : P ≤ sourceLocalClosure K P := + fun _ _ _ ↦ .of _ + +lemma le_of_isLocalAtSource (h : P ≤ Q) [Q.IsLocalAtSource K] : sourceLocalClosure K P ≤ Q := by + intro X Y f hf + induction hf with + | of f hf => exact h _ hf + | of_iso f g e _ hf => rwa [Q.arrow_mk_iso_iff e.symm] + | comp f hf R hR g hg ih => apply IsLocalAtSource.comp hR _ hg ih + | of_presieve f R hR h ih => apply IsLocalAtSource.of_forall_comp hR fun U g hg ↦ ih _ _ hg + +instance [P.ContainsIdentities] : ContainsIdentities (sourceLocalClosure K P) where + id_mem _ := le _ (P.id_mem _) + +set_option backward.isDefEq.respectTransparency false in +instance [P.IsStableUnderBaseChange] [K.IsStableUnderBaseChange] [HasPullbacks C] : + IsStableUnderBaseChange (sourceLocalClosure K P) where + of_isPullback {Y} X W Z g f fst snd h hf := by + induction hf generalizing W snd with + | of f' hf' => exact .of _ (P.of_isPullback h hf') + | of_iso f' g' e hf' ih => + exact ih _ (g ≫ e.inv.right) (fst ≫ e.inv.left) _ (h.paste_horiz (.of_horiz_isIso ⟨e.inv.w⟩)) + | comp f' hf' R hR g' hg' ih => + let u : W ⟶ pullback g f' := pullback.lift snd (fst ≫ g') (by simp [h.w.symm]) + have : snd = u ≫ pullback.fst g f' := by simp [u] + rw [this] at h ⊢ + let e : W ≅ pullback g' (pullback.snd g f') := + IsPullback.isoPullback (.of_bot h (by simp [u]) (.flip <| .of_hasPullback _ _)) + rw [← (sourceLocalClosure K P).cancel_left_of_respectsIso e.inv, ← Category.assoc] + refine .comp _ (ih _ _ _ _ (.flip (.of_hasPullback _ _))) _ + (K.pullbackArrows_mem (pullback.snd _ _) hR) _ ?_ + simpa [e, u] using .mk _ _ hg' + | of_presieve f R hR h ih => + refine .of_presieve _ _ (K.pullbackArrows_mem fst hR) ?_ + intro U v ⟨Z, u, hu⟩ + exact ih _ _ hu _ g (pullback.fst _ _) _ (.paste_vert (.of_hasPullback _ _) h) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma sourceLocalClosure_iff_of_respectsLeft [P.RespectsIso] [P.RespectsLeft K.morphismProperty] + [K.HasIsos] [K.IsStableUnderBaseChange] [K.IsStableUnderComposition] [K.HasPullbacks] {X Y : C} + {f : X ⟶ Y} : + sourceLocalClosure K P f ↔ ∃ R ∈ K X, ∀ (U : C) (g : U ⟶ X), R g → P (g ≫ f) := by + refine ⟨?_, ?_⟩ + · intro h + induction h with + | of f hf => exact ⟨.singleton (𝟙 _), K.mem_coverings_of_isIso _, fun U g ⟨⟩ ↦ by simpa⟩ + | of_iso f g e hf h => + obtain ⟨R, hR, h⟩ := h + rw [K.mem_iff_exists_zeroHypercover] at hR + obtain ⟨E, rfl⟩ := hR + refine ⟨_, (E.pushforward e.hom.left (K.mem_coverings_of_isIso _)).mem₀, ?_⟩ + intro U v ⟨i⟩ + dsimp + simp only [Category.assoc, Arrow.w_mk_right, Arrow.mk_left, Arrow.mk_right, Arrow.mk_hom] + rw [← Category.assoc, P.cancel_right_of_respectsIso] + exact h _ _ ⟨i⟩ + | comp f hf R hR g hg ih => + obtain ⟨S, hS, h⟩ := ih + rw [K.mem_iff_exists_zeroHypercover] at hS hR + obtain ⟨E, rfl⟩ := hS + obtain ⟨F, rfl⟩ := hR + refine ⟨(E.pullback₁ g).presieve₀, (E.pullback₁ g).mem₀, ?_⟩ + intro U v ⟨i⟩ + dsimp + rw [pullback.condition_assoc] + refine RespectsLeft.precomp (Q := K.morphismProperty) _ ?_ _ ?_ + · obtain ⟨j⟩ := hg + exact (F.pullback₂ (E.f i)).morphismProperty j + · exact h _ _ ⟨i⟩ + | of_presieve f R hR h ih => + rw [K.mem_iff_exists_zeroHypercover] at hR + obtain ⟨E, rfl⟩ := hR + choose S hS h' using fun i : E.I₀ ↦ ih _ _ ⟨i⟩ + simp_rw [K.mem_iff_exists_zeroHypercover] at hS + choose F hF using hS + refine ⟨_, (E.bind F).mem₀, fun U g ⟨j⟩ ↦ ?_⟩ + dsimp + rw [Category.assoc] + exact h' _ _ _ (by simp [hF]) + · intro ⟨R, hR, h⟩ + exact .of_presieve _ _ hR (by grind) + +end sourceLocalClosure + +end CategoryTheory.MorphismProperty diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean b/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean index b245a70e8c9c81..78d156f96d8089 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean @@ -915,6 +915,9 @@ lemma le_of_zeroHypercover {J K : Precoverage C} class Small (J : Precoverage C) : Prop where zeroHypercoverSmall : ∀ {S : C} (E : ZeroHypercover.{max u v} J S), ZeroHypercover.Small.{w'} E +instance (K : Precoverage C) : Small.{max u v} K where + zeroHypercoverSmall := inferInstance + instance (J : Precoverage C) [Small.{w} J] {S : C} (E : ZeroHypercover.{w'} J S) : ZeroHypercover.Small.{w} E := by have : ZeroHypercover.Small.{w} (ZeroHypercover.restrictIndexOfSmall.{max u v} E) := From b9251c8115165ef805d290dcce9d040077cd5d37 Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Wed, 24 Jun 2026 08:46:23 +0000 Subject: [PATCH 0310/1300] chore(Topology): tag `continuous_of_indiscreteTopology` with `fun_prop` (#40987) Tag `continuous_of_indiscreteTopology` with `fun_prop`. This in particular allows `fun_prop` to prove that functions to subsingletons are continuous, which it previously couldn't do. --- Mathlib/Topology/Order.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Topology/Order.lean b/Mathlib/Topology/Order.lean index f87c4a05190af6..56f78491229fab 100644 --- a/Mathlib/Topology/Order.lean +++ b/Mathlib/Topology/Order.lean @@ -292,6 +292,7 @@ theorem closure_indiscrete [IndiscreteTopology α] {s : Set α} (h : s.Nonempty) closure s = Set.univ := Dense.closure_eq (dense_indiscrete h) /-- Every function to the indiscrete topology is continuous -/ +@[fun_prop] theorem continuous_of_indiscreteTopology {β} [TopologicalSpace β] [IndiscreteTopology β] {f : α → β} : Continuous f where isOpen_preimage := by simp [IndiscreteTopology.isOpen_iff] From 35fc73662776f4704736b39635edaccd99726fc6 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 09:59:17 +0000 Subject: [PATCH 0311/1300] chore: update Mathlib dependencies 2026-06-24 (#40989) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 07ac27b85df079..5ebacc94fd75e7 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f3f26cc72646205ca167117487c008ee1dafe816", + "rev": "f3c7bd5061bd81b4480295c524d4f245c8b7e4e2", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", From a4bf45d42ebfbd6ff32df72735270d200257f8d0 Mon Sep 17 00:00:00 2001 From: Chris Lloyd <868215+cjrl@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:56:52 +0000 Subject: [PATCH 0312/1300] feat(Data/Fintype/Card): existsUnique_notMem_image_of_injective_of_card_succ (#37720) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull requests adds a small theorem `existsUnique_notMem_image_of_injective_of_card_succ` to `Mathlib/Data/Fintype/Card` that says given an injective map f : α → β such that β has cardinality one more than α, there exists a unique element of β not in the image of f. This can be viewed as going in the opposite direction of `card_lt_of_injective_of_notMem`. This little fact is needed for our Latin Square PR #36698. Co-authored-by: Christopher J. R. Lloyd Co-authored-by: George H. Seelinger --- Mathlib/Data/Finset/Card.lean | 13 +++++++++++++ Mathlib/Data/Fintype/Card.lean | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 2fd5eac026ce27..cc5329230c10c2 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -680,6 +680,9 @@ theorem card_eq_one : #s = 1 ↔ ∃ a, s = {a} := by cases s simp only [Multiset.card_eq_one, Finset.card, ← val_inj, singleton_val] +theorem card_eq_one_iff_existsUnique : #s = 1 ↔ ∃! a, a ∈ s := by + simp [card_eq_one, Finset.singleton_iff_unique_mem] + theorem exists_eq_insert_iff [DecidableEq α] : (∃ a ∉ s, insert a s = t) ↔ s ⊆ t ∧ #s + 1 = #t := by constructor @@ -738,6 +741,16 @@ theorem one_lt_card_iff_nontrivial : 1 < #s ↔ s.Nontrivial := by rw [← not_iff_not, not_lt, Finset.Nontrivial, ← Set.nontrivial_coe_sort, not_nontrivial_iff_subsingleton, card_le_one_iff_subsingleton_coe, coe_sort_coe] +/-- Given an injective map `f : α → β` for finite sets `s ⊂ α` and `t ⊂ β` such that `t` has + cardinality one more than `s`, there exists a unique element of `t` not in `f(s)`. -/ +theorem existsUnique_notMem_image_of_injOn_of_card_eq_add_one + {t : Finset β} [DecidableEq β] + (hf : Set.InjOn f s) (hf' : Set.MapsTo f s t) (h : #t = #s + 1) : + ∃! x, x ∈ t ∧ x ∉ s.image f := by + have : #(t \ s.image f) = 1 := by + grind [card_sdiff_of_subset hf'.finsetImage_subset, card_image_of_injOn hf] + simpa [card_eq_one_iff_existsUnique] using this + /-- If a Finset in a Pi type is nontrivial (has at least two elements), then its projection to some factor is nontrivial, and the fibers of the projection are proper subsets. -/ diff --git a/Mathlib/Data/Fintype/Card.lean b/Mathlib/Data/Fintype/Card.lean index fa521717a60e9c..3d37ede9458d79 100644 --- a/Mathlib/Data/Fintype/Card.lean +++ b/Mathlib/Data/Fintype/Card.lean @@ -255,6 +255,13 @@ theorem card_lt_of_injective_of_notMem (f : α → β) (h : Function.Injective f Finset.card_lt_univ_of_notMem (x := b) <| by rwa [← mem_coe, coe_map, coe_univ, Set.image_univ] +/-- Given an injective map `f : α → β` such that `β` has cardinality one more +than `α`, there exists a unique element of `β` not in the image of `f`. -/ +theorem existsUnique_notMem_image_of_injective_of_card_eq_add_one [DecidableEq β] + (f : α → β) (hf : f.Injective) (h : card β = card α + 1) : ∃! x, x ∉ univ.image f := by + simpa using existsUnique_notMem_image_of_injOn_of_card_eq_add_one + (s := .univ) (t := .univ) (Set.injOn_of_injective hf) (by simp) (by simpa) + theorem card_lt_of_injective_not_surjective (f : α → β) (h : Function.Injective f) (h' : ¬Function.Surjective f) : card α < card β := let ⟨_y, hy⟩ := not_forall.1 h' From cd4c002ea0b293f24faf1d93a3e7af63389a9de6 Mon Sep 17 00:00:00 2001 From: zw810-ctrl <248219010+zw810-ctrl@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:56:54 +0000 Subject: [PATCH 0313/1300] feat: API and proof of `isStrictMap_prodMap` (#38937) Co-authored-by: Oliver Nash Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> Co-authored-by: ADedecker Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Anatole Dedecker --- Mathlib/Topology/Algebra/Group/Basic.lean | 7 ++++ Mathlib/Topology/Maps/Strict/Basic.lean | 49 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 6f485a3f813c0c..7d82c9db6f5b06 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -914,6 +914,13 @@ lemma MonoidHom.isOpenQuotientMap_of_isQuotientMap {A : Type*} [Group A] use x * k, hx rw [map_mul, hk, mul_one] +@[to_additive] +lemma MonoidHom.isOpenQuotientMap_iff_isQuotientMap {A : Type*} [Group A] + [TopologicalSpace A] [ContinuousMul A] {B : Type*} [Group B] [TopologicalSpace B] + {F : Type*} [FunLike F A B] [MonoidHomClass F A B] {φ : F} : + IsOpenQuotientMap φ ↔ IsQuotientMap φ := + ⟨fun hf => hf.isQuotientMap, MonoidHom.isOpenQuotientMap_of_isQuotientMap⟩ + @[to_additive] theorem IsTopologicalGroup.ext {G : Type*} [Group G] {t t' : TopologicalSpace G} (tg : @IsTopologicalGroup G t _) (tg' : @IsTopologicalGroup G t' _) diff --git a/Mathlib/Topology/Maps/Strict/Basic.lean b/Mathlib/Topology/Maps/Strict/Basic.lean index dedc38c5e810f8..ec2a2ed345a7a0 100644 --- a/Mathlib/Topology/Maps/Strict/Basic.lean +++ b/Mathlib/Topology/Maps/Strict/Basic.lean @@ -9,6 +9,8 @@ public import Mathlib.Topology.Maps.Basic public import Mathlib.Topology.Homeomorph.Quotient public import Mathlib.Topology.Constructions public import Mathlib.Data.Setoid.Basic +public import Mathlib.Topology.Algebra.Group.Quotient + /-! # Bourbaki Strict Maps @@ -33,6 +35,18 @@ We provide several equivalent ways to characterize a strict map `f`: the canonical bijection `Quotient (Setoid.ker f) ≃ Set.range f` is a homeomorphism. * `Topology.isStrictMap_iff_isEmbedding_kerLift`: `f` is strict if and only if the canonical injection `Quotient (Setoid.ker f) → Y` (`Setoid.kerLift f`) is an embedding. + +### Group homomorphisms + +In general, the product (in the sense of `Prod.map`) of two strict maps need not be strict. +But thanks to `MonoidHom.isOpenQuotientMap_of_isQuotientMap`, we can replace `IsQuotientMap` +by `IsOpenQuotientMap` in the setting of group homomorphisms. Therefore we provide several +important properties of strict group homomorphisms : + +* `isStrictMap_iff_isOpenQuotientMap_rangeRestrict`: `f` is a strict group homomorphism if + and only if the `rangeRestrict` of `f` is an open quotient map. +* `isStrictMap_prodMap`: The product (in the sense of Prod.map) of strict group homomorphisms + is strict. -/ @[expose] public section @@ -153,4 +167,39 @@ lemma isEmbedding_iff_isStrictMap_injective : (Homeomorph.Quotient.congrRight <| by simp [f_inj.eq_iff]).trans Homeomorph.quotientBot exact f_strict.comp Φ.symm.isEmbedding +/-- Strict maps are preserved when precomposing with a homeomorphism. -/ +lemma Homeomorph.isStrictMap_comp_iff (e : X ≃ₜ Y) {f : Y → Z} : + IsStrictMap (f ∘ e) ↔ IsStrictMap f := + e.isQuotientMap.isStrictMap_iff.symm + +/-- Strict maps are preserved when postcomposing with a homeomorphism. -/ +lemma Homeomorph.comp_isStrictMap_iff (e : Y ≃ₜ Z) {f : X → Y} : + IsStrictMap (e ∘ f) ↔ IsStrictMap f := + e.isEmbedding.isStrictMap_iff.symm + end Topology + +namespace MonoidHom + +variable {G H G' H' : Type*} [Group G'] [Group H'] [Group G] [Group H] (f : G →* H) (g : G' →* H') + [TopologicalSpace G] [IsTopologicalGroup G] [TopologicalSpace H] + +/-- A group homomorphism is strict if and only if its `rangeRestrict` is an open quotient map. -/ +@[to_additive] lemma isStrictMap_iff_isOpenQuotientMap_rangeRestrict : + IsStrictMap f ↔ IsOpenQuotientMap f.rangeRestrict := by + rw [isOpenQuotientMap_iff_isQuotientMap] + rfl + +variable {f g} [TopologicalSpace G'] [IsTopologicalGroup G'] [TopologicalSpace H'] + +/-- The product (in the sense of `Prod.map`) of strict group homomorphisms is strict -/ +@[to_additive isStrictMap_prodMap] lemma isStrictMap_prodMap (hf : IsStrictMap f) + (hg : IsStrictMap g) : IsStrictMap (f.prodMap g) := by + rw [isStrictMap_iff_isOpenQuotientMap_rangeRestrict] at hf hg ⊢ + let aux : (f.prodMap g).range ≃ₜ f.range × g.range := + (Homeomorph.setCongr (by simp [Subgroup.coe_prod])).trans (Homeomorph.Set.prod _ _) + exact aux.symm.isOpenQuotientMap.comp (hf.prodMap hg) + +-- TODO Add the lemma `isStrictMap_piMap` once `MonoidHom.piMap` has been defined. + +end MonoidHom From c54f3c8d2c79fb760dbffc7a25dbe18f1b8fbf5f Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:56:57 +0000 Subject: [PATCH 0314/1300] feat(Topology/CWComplex/Classical): discrete spaces are CW complexes (#38943) as well as some useful lemmas This is partly based on code by @scholzhannah I think this is notable to include, since it is pretty much the only (easy) "topological" sufficient condition for something being a CW complex there is. Co-authored-by: Batixx --- Mathlib/Algebra/Group/Fin/Tuple.lean | 3 + .../Topology/CWComplex/Classical/Basic.lean | 55 +++++++++++++++++++ Mathlib/Topology/Covering/Basic.lean | 2 +- Mathlib/Topology/DiscreteSubset.lean | 33 ++++++++++- Mathlib/Topology/Irreducible.lean | 4 +- 5 files changed, 92 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Group/Fin/Tuple.lean b/Mathlib/Algebra/Group/Fin/Tuple.lean index 7d566c015fa76d..5c332bc478acc6 100644 --- a/Mathlib/Algebra/Group/Fin/Tuple.lean +++ b/Mathlib/Algebra/Group/Fin/Tuple.lean @@ -103,6 +103,9 @@ variable [Zero α] @[simp] lemma zero_empty : (0 : Fin 0 → α) = ![] := empty_eq _ +@[simp] lemma finZeroElim_eq_zero : (@finZeroElim fun _ ↦ α) = 0 := by + rw [Matrix.empty_eq finZeroElim, Matrix.zero_empty] + @[simp] lemma cons_zero_zero : vecCons (0 : α) (0 : Fin n → α) = 0 := by ext i; exact i.cases rfl (by simp) diff --git a/Mathlib/Topology/CWComplex/Classical/Basic.lean b/Mathlib/Topology/CWComplex/Classical/Basic.lean index 97b4720eaba62a..78eab46d614820 100644 --- a/Mathlib/Topology/CWComplex/Classical/Basic.lean +++ b/Mathlib/Topology/CWComplex/Classical/Basic.lean @@ -289,6 +289,20 @@ lemma RelCWComplex.map_zero_mem_closedCell [RelCWComplex C D] (n : ℕ) (i : cel map n i 0 ∈ closedCell n i := openCell_subset_closedCell _ _ (map_zero_mem_openCell _ _) +lemma RelCWComplex.openCell_nonempty [RelCWComplex C D] (n : ℕ) (j : cell C n) : + (openCell n j).Nonempty := + ⟨(map n j) 0, map_zero_mem_openCell n j⟩ + +lemma RelCWComplex.closedCell_nonempty [RelCWComplex C D] (n : ℕ) (j : cell C n) : + (closedCell n j).Nonempty := + ⟨(map n j) 0, map_zero_mem_closedCell n j⟩ + +/-- If two open cells are equal, so are the underlying cells. -/ +lemma RelCWComplex.openCell_congr [RelCWComplex C D] (n : ℕ) {s t : cell C n} + (st : openCell n s = openCell n t) : s = t := by + contrapose! st + exact (disjoint_openCell_of_ne (by simpa)).ne (openCell_nonempty n s).ne_empty + /-- This is an auxiliary lemma used to prove `RelCWComplex.eq_of_eq_union_iUnion`. -/ private lemma RelCWComplex.subset_of_eq_union_iUnion [RelCWComplex C D] (I J : Π n, Set (cell C n)) (hIJ : D ∪ ⋃ (n : ℕ) (j : I n), openCell (C := C) n j = @@ -1061,4 +1075,45 @@ lemma RelCWComplex.disjoint_interior_base_iUnion_closedCell [T2Space X] [RelCWCo simp_rw [disjoint_iff_inter_eq_empty, inter_iUnion, disjoint_interior_base_closedCell.inter_eq, iUnion_empty] +/-- A closed discrete subset of a space is a CW complex. -/ +@[reducible, simps -isSimp] +def CWComplex.OfDiscreteClosed (hD : IsDiscrete D) (Dc : IsClosed D) : CWComplex D where + cell n := match n with + | 0 => D + | (_ + 1) => PEmpty + map n i := match n with + | 0 => PartialEquiv.single ![] i + | (_ + 1) => i.elim + source_eq n i := match n with + | 0 => by simp [ball, Matrix.empty_eq, eq_univ_iff_forall] + | (_ + 1) => i.elim + continuousOn n i := match n with + | 0 => continuousOn_const + | (_ + 1) => i.elim + continuousOn_symm n i := match n with + | 0 => continuousOn_const + | (_ + 1) => i.elim + pairwiseDisjoint' := by + simp_rw [PairwiseDisjoint, Set.Pairwise, Function.onFun] + rintro ⟨_|n, j⟩ _ ⟨_|m, i⟩ _ ne + · simp_all [Subtype.coe_injective.ne] + · exact i.elim + · tauto + · exact i.elim + mapsTo' n i := match n with + | 0 => by simp [Matrix.zero_empty, sphere_eq_empty_of_subsingleton] + | (_ + 1) => i.elim + closed' A AD _ := isClosed_of_subset_discrete_closed AD hD Dc + union' := by + apply subset_antisymm (iUnion₂_subset_iff.mpr fun n ↦ by cases n <;> simp) + intro x xD + simp only [mem_iUnion, mem_image, mem_closedBall, dist_zero_right] + refine ⟨0, ?_⟩ + simpa [-Matrix.zero_empty] + +/-- A discrete space is a CW complex. -/ +instance CWComplex.ofDiscreteTopology {X : Type*} [TopologicalSpace X] [DiscreteTopology X] : + CWComplex (univ : Set X) := + CWComplex.OfDiscreteClosed IsDiscrete.univ isClosed_univ + end Topology diff --git a/Mathlib/Topology/Covering/Basic.lean b/Mathlib/Topology/Covering/Basic.lean index 45d1952f2dde26..8400516ab95c2c 100644 --- a/Mathlib/Topology/Covering/Basic.lean +++ b/Mathlib/Topology/Covering/Basic.lean @@ -497,7 +497,7 @@ variable (f) in theorem IsDiscrete.of_openPartialHomeomorph {t : Set E} {x : X} (htx : t ⊆ f ⁻¹' {x}) (hf : ∀ e ∈ t, ∃ φ : OpenPartialHomeomorph E X, e ∈ φ.source ∧ φ = f) : IsDiscrete t := - isDiscrete_iff_forall_exists_isOpen.mpr fun e he ↦ by + isDiscrete_iff_forall_mem_exists_isOpen.mpr fun e he ↦ by obtain ⟨φ, hφ, rfl⟩ := hf e he exact ⟨_, φ.open_source, subset_antisymm (fun e' he' ↦ φ.injOn he'.1 hφ <| (htx he'.2).trans (htx he).symm) <| Set.singleton_subset_iff.mpr ⟨hφ, he⟩⟩ diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 6cfe19a31b5217..b949ac0ba8702a 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -65,10 +65,39 @@ lemma discreteTopology_subtype_iff' {S : Set Y} : simp [discreteTopology_iff_isOpen_singleton, isOpen_induced_iff, Set.ext_iff] grind -theorem isDiscrete_iff_forall_exists_isOpen {S : Set Y} : - IsDiscrete S ↔ ∀ y ∈ S, ∃ U, IsOpen U ∧ U ∩ S = {y} := by +/-- A set `s` is discrete iff for every `y ∈ s` there is an open `u` with `u ∩ s = {y}`. +See `isDiscrete_iff_forall_subset_exists_isOpen'` for a related version of this with subsets. -/ +theorem isDiscrete_iff_forall_mem_exists_isOpen {s : Set Y} : + IsDiscrete s ↔ ∀ y ∈ s, ∃ u, IsOpen u ∧ u ∩ s = {y} := by rw [isDiscrete_iff_discreteTopology, discreteTopology_subtype_iff'] +@[deprecated (since := "2026-06-24")] +alias isDiscrete_iff_forall_exists_isOpen := isDiscrete_iff_forall_mem_exists_isOpen + +/-- A set `s` is discrete iff for every `t ⊆ s` there is an open `u` with `u ∩ s = t`. +See `isDiscrete_iff_forall_mem_exists_isOpen` for a similar version of this with singletons. -/ +theorem isDiscrete_iff_forall_subset_exists_isOpen {s : Set X} : + IsDiscrete s ↔ ∀ t ⊆ s, ∃ u, IsOpen u ∧ u ∩ s = t := by + simp_rw [isDiscrete_iff_discreteTopology, discreteTopology_iff_forall_isOpen, + isOpen_induced_iff, ← image_eq_image (Subtype.val_injective), Subtype.image_preimage_coe, + Subtype.forall_set_subtype (p := fun t ↦ ∃ u, IsOpen u ∧ s ∩ u = t), inter_comm] + +/-- A set `s` is discrete iff for every `t ⊆ s` there is a closed `u` with `u ∩ s = t`. -/ +theorem isDiscrete_iff_forall_mem_exists_isClosed {S : Set X} : + IsDiscrete S ↔ ∀ s ⊆ S, ∃ U, IsClosed U ∧ U ∩ S = s := by + rw [isDiscrete_iff_forall_subset_exists_isOpen] + constructor <;> intro h s sS + · obtain ⟨U, Uo, Us⟩ := h (sᶜ ∩ S) inter_subset_right + exact ⟨Uᶜ, isClosed_compl_iff.mpr Uo, by rw [left_eq_inter.mpr sS]; simp_all [Set.ext_iff]⟩ + · obtain ⟨U, Uo, Us⟩ := h (sᶜ ∩ S) inter_subset_right + exact ⟨Uᶜ, isOpen_compl_iff.mpr Uo, by rw [left_eq_inter.mpr sS]; simp_all [Set.ext_iff]⟩ + +theorem isClosed_of_subset_discrete_closed {s t : Set X} (sd : s ⊆ t) + (ht : IsDiscrete t) (tc : IsClosed t) : IsClosed s := by + obtain ⟨_, rp, rt⟩ := isDiscrete_iff_forall_mem_exists_isClosed.mp ht s sd + rw [← rt] + exact rp.inter tc + lemma Set.Subsingleton.isDiscrete (hs : s.Subsingleton) : IsDiscrete s := have : Subsingleton s := (Set.subsingleton_coe s).mpr hs ⟨inferInstance⟩ diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 8f5fb12cf5bd77..e7e91d08c1cfee 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -524,8 +524,8 @@ end lemma IsDiscrete.subsingleton_of_isPreirreducible (hs : IsDiscrete s) (hs' : IsPreirreducible s) : s.Subsingleton := by intro x hxs y hys - obtain ⟨U, hU, hUx⟩ := isDiscrete_iff_forall_exists_isOpen.mp hs x hxs - obtain ⟨V, hV, hVy⟩ := isDiscrete_iff_forall_exists_isOpen.mp hs y hys + obtain ⟨U, hU, hUx⟩ := isDiscrete_iff_forall_mem_exists_isOpen.mp hs x hxs + obtain ⟨V, hV, hVy⟩ := isDiscrete_iff_forall_mem_exists_isOpen.mp hs y hys obtain ⟨z, hz⟩ := hs' _ _ hU hV ⟨x, by grind⟩ ⟨y, by grind⟩ exact (hUx.le (by grind)).symm.trans (b := z) (hVy.le (by grind)) From 8b553276df7d1c279d0d229506833c79c81322d6 Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:56:59 +0000 Subject: [PATCH 0315/1300] feat(Algebra/MvPolynomial/Basic): `coeff_C_of_ne_zero` and `coeff_add_single_C` (#39623) These lemmas are multivariate analogs to `Polynomial.coeff_C_of_ne_zero`, `Polynomial.coeff_C_succ` and `PowerSeries.coeff_C_of_ne_zero` and `PowerSeries.coeff_succ_C`. They are useful for defining partial derivatives for multivariate power series, see PR #39626. - [x] depends on: #39632 --- Mathlib/Algebra/MvPolynomial/Basic.lean | 9 +++++++++ Mathlib/RingTheory/MvPowerSeries/Basic.lean | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 5bc4d8845577ea..74f35d21f7e3d5 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -593,6 +593,15 @@ theorem coeff_C [DecidableEq σ] (m) (a) : coeff m (C a : MvPolynomial σ R) = if 0 = m then a else 0 := Finsupp.single_apply +theorem coeff_C_of_ne_zero {m : σ →₀ ℕ} (h : m ≠ 0) (a : R) : coeff m (C a) = 0 := by + classical rw [coeff_C, if_neg h.symm] + +-- The intended use case of this theorem is for `n = 1` (often useful for `pderiv`). +@[simp] +theorem coeff_add_single_C {n : ℕ} [NeZero n] {m : σ →₀ ℕ} (a : R) (i : σ) : + coeff (m + Finsupp.single i n) (C a) = 0 := + coeff_C_of_ne_zero (fun H ↦ by simpa [NeZero.ne] using congr($(H) i)) a + lemma eq_C_of_isEmpty [IsEmpty σ] (p : MvPolynomial σ R) : p = C (p.coeff 0) := by obtain ⟨x, rfl⟩ := C_surjective σ p diff --git a/Mathlib/RingTheory/MvPowerSeries/Basic.lean b/Mathlib/RingTheory/MvPowerSeries/Basic.lean index 741d71157d56c1..9fc6b1497de12c 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Basic.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Basic.lean @@ -351,6 +351,15 @@ theorem coeff_C [DecidableEq σ] (n : σ →₀ ℕ) (a : R) : theorem coeff_zero_C (a : R) : coeff (0 : σ →₀ ℕ) (C a) = a := coeff_monomial_same 0 a +theorem coeff_C_of_ne_zero {n : σ →₀ ℕ} (h : n ≠ 0) (a : R) : coeff n (C a) = 0 := by + classical rw [coeff_C, if_neg h] + +-- The intended use case of this theorem is for `m = 1` (often useful for `pderiv`). +@[simp] +theorem coeff_add_single_C {m : ℕ} [NeZero m] {n : σ →₀ ℕ} (a : R) (i : σ) : + coeff (n + single i m) (C a) = 0 := + coeff_C_of_ne_zero (fun H ↦ by simpa [NeZero.ne] using congr($(H) i)) a + @[grind inj] theorem C_injective : Function.Injective (C : R → MvPowerSeries σ R) := by intro a b h From 6e9880829d70296832473f9100904cbf3c5a56e6 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:57:01 +0000 Subject: [PATCH 0316/1300] chore(CategoryTheory/LiftingProperties/Basic): use `to_dual` more (#40943) This PR finishes using `to_dual` in `LiftingProperties/Basic`, finishing the work in #38174. Some missing prerequisites have also been tagged, in particular `Retract`. --- Mathlib/CategoryTheory/Balanced.lean | 10 +-- Mathlib/CategoryTheory/Comma/Arrow.lean | 3 + .../LiftingProperties/Basic.lean | 40 ++++-------- Mathlib/CategoryTheory/Retract.lean | 64 +++++++++++-------- 4 files changed, 57 insertions(+), 60 deletions(-) diff --git a/Mathlib/CategoryTheory/Balanced.lean b/Mathlib/CategoryTheory/Balanced.lean index b6499a5f170c0f..d9f2b95a9f04f7 100644 --- a/Mathlib/CategoryTheory/Balanced.lean +++ b/Mathlib/CategoryTheory/Balanced.lean @@ -27,19 +27,19 @@ namespace CategoryTheory variable {C : Type u} [Category.{v} C] -section - -variable (C) - +variable (C) in /-- A category is called balanced if any morphism that is both monic and epic is an isomorphism. -/ class Balanced : Prop where isIso_of_mono_of_epi : ∀ {X Y : C} (f : X ⟶ Y) [Mono f] [Epi f], IsIso f -end +attribute [to_dual self (reorder := X Y, 7 8)] Balanced.isIso_of_mono_of_epi +attribute [to_dual self (reorder := isIso_of_mono_of_epi (X Y, 4 5))] Balanced.mk +@[to_dual self (reorder := X Y, 7 8)] theorem isIso_of_mono_of_epi [Balanced C] {X Y : C} (f : X ⟶ Y) [Mono f] [Epi f] : IsIso f := Balanced.isIso_of_mono_of_epi _ +@[to_dual isIso_iff_epi_and_mono] theorem isIso_iff_mono_and_epi [Balanced C] {X Y : C} (f : X ⟶ Y) : IsIso f ↔ Mono f ∧ Epi f := ⟨fun _ => ⟨inferInstance, inferInstance⟩, fun ⟨_, _⟩ => isIso_of_mono_of_epi _⟩ diff --git a/Mathlib/CategoryTheory/Comma/Arrow.lean b/Mathlib/CategoryTheory/Comma/Arrow.lean index 62ee97723e7a57..5ea218a8f31358 100644 --- a/Mathlib/CategoryTheory/Comma/Arrow.lean +++ b/Mathlib/CategoryTheory/Comma/Arrow.lean @@ -78,6 +78,9 @@ def mk {X Y : T} (f : X ⟶ Y) : Arrow T where right := Y hom := f +attribute [to_dual existing] mk_left +attribute [to_dual self] mk_hom + @[simp] theorem mk_eq (f : Arrow T) : Arrow.mk f.hom = f := by cases f diff --git a/Mathlib/CategoryTheory/LiftingProperties/Basic.lean b/Mathlib/CategoryTheory/LiftingProperties/Basic.lean index dbb84330753cbc..185a3dd028503c 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/Basic.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/Basic.lean @@ -36,6 +36,8 @@ open Category variable {C : Type*} [Category* C] {A B B' X Y Y' : C} (i : A ⟶ B) (i' : B ⟶ B') (p : X ⟶ Y) (p' : Y ⟶ Y') +to_dual_name_hint Left Right, A Y, B X, I P + /-- `HasLiftingProperty i p` means that `i` has the left lifting property with respect to `p`, or equivalently that `p` has the right lifting property with respect to `i`. -/ @@ -80,7 +82,7 @@ theorem iff_unop {A B X Y : Cᵒᵖ} (i : A ⟶ B) (p : X ⟶ Y) : variable (i p) -@[to_dual of_right_iso] +@[to_dual] instance (priority := 100) of_left_iso [IsIso i] : HasLiftingProperty i p := ⟨fun {f} {g} sq => CommSq.HasLift.mk' @@ -88,7 +90,7 @@ instance (priority := 100) of_left_iso [IsIso i] : HasLiftingProperty i p := fac_left := by simp only [IsIso.hom_inv_id_assoc] fac_right := by simp only [sq.w, assoc, IsIso.inv_hom_id_assoc] }⟩ -@[to_dual of_comp_right] +@[to_dual] instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] : HasLiftingProperty (i ≫ i') p := ⟨fun {f} {g} sq => by @@ -101,52 +103,30 @@ instance of_comp_left [HasLiftingProperty i p] [HasLiftingProperty i' p] : fac_right := by simp only [CommSq.fac_right] }⟩ set_option backward.isDefEq.respectTransparency false in +@[to_dual (reorder := i i' e p)] theorem of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'} (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) [hip : HasLiftingProperty i p] : HasLiftingProperty i' p := by rw [Arrow.iso_w' e] infer_instance -set_option backward.isDefEq.respectTransparency false in -theorem of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'} - (e : Arrow.mk p ≅ Arrow.mk p') [hip : HasLiftingProperty i p] : HasLiftingProperty i p' := by - rw [Arrow.iso_w' e] - infer_instance - +@[to_dual (reorder := i i' e p)] theorem iff_of_arrow_iso_left {A B A' B' X Y : C} {i : A ⟶ B} {i' : A' ⟶ B'} (e : Arrow.mk i ≅ Arrow.mk i') (p : X ⟶ Y) : HasLiftingProperty i p ↔ HasLiftingProperty i' p := by constructor <;> intro exacts [of_arrow_iso_left e p, of_arrow_iso_left e.symm p] -theorem iff_of_arrow_iso_right {A B X Y X' Y' : C} (i : A ⟶ B) {p : X ⟶ Y} {p' : X' ⟶ Y'} - (e : Arrow.mk p ≅ Arrow.mk p') : HasLiftingProperty i p ↔ HasLiftingProperty i p' := by - constructor <;> intro - exacts [of_arrow_iso_right i e, of_arrow_iso_right i e.symm] - end HasLiftingProperty -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -lemma RetractArrow.leftLiftingProperty - {X Y Z W Z' W' : C} {g : Z ⟶ W} {g' : Z' ⟶ W'} - (h : RetractArrow g' g) (f : X ⟶ Y) [HasLiftingProperty g f] : HasLiftingProperty g' f where - sq_hasLift := fun {u v} sq ↦ by - have sq' : CommSq (h.r.left ≫ u) g f (h.r.right ≫ v) := by simp only [Arrow.mk_left, - Arrow.mk_right, Category.assoc, sq.w, Arrow.w_mk_right_assoc, Arrow.mk_hom, CommSq.mk] - exact - ⟨⟨{ l := h.i.right ≫ sq'.lift - fac_left := by - simp only [← h.i_w_assoc, sq'.fac_left, h.retract_left_assoc, - Arrow.mk_left, Category.id_comp]}⟩⟩ - set_option backward.isDefEq.respectTransparency false in +@[to_dual] lemma RetractArrow.rightLiftingProperty {X Y Z W X' Y' : C} {f : X ⟶ Y} {f' : X' ⟶ Y'} (h : RetractArrow f' f) (g : Z ⟶ W) [HasLiftingProperty g f] : HasLiftingProperty g f' where sq_hasLift := fun {u v} sq ↦ have sq' : CommSq (u ≫ h.i.left) g f (v ≫ h.i.right) := - ⟨by rw [← Category.assoc, ← sq.w, Category.assoc, RetractArrow.i_w, Category.assoc]⟩ + ⟨by rw [← sq.w_assoc, Category.assoc, RetractArrow.i_w]⟩ ⟨⟨{ l := sq'.lift ≫ h.r.left}⟩⟩ namespace Arrow @@ -154,9 +134,11 @@ namespace Arrow /-- Given a morphism `φ : f ⟶ g` in the category `Arrow C`, this is an abbreviation for the `CommSq.LiftStruct` structure for the square corresponding to `φ`. -/ +@[to_dual self] abbrev LiftStruct {f g : Arrow C} (φ : f ⟶ g) := (CommSq.mk φ.w).LiftStruct set_option backward.isDefEq.respectTransparency false in +@[to_dual self] lemma hasLiftingProperty_iff {A B X Y : C} (i : A ⟶ B) (p : X ⟶ Y) : HasLiftingProperty i p ↔ ∀ (φ : Arrow.mk i ⟶ Arrow.mk p), Nonempty (LiftStruct φ) := by @@ -172,7 +154,7 @@ end Arrow /-- Given morphisms `i : A ⟶ B`, `p : X ⟶ Y`, `t : A ⟶ X`, this is the property that a lifting exists for all squares with `i` on left, `p` on the right and `t` on the top. -/ -@[to_dual (rename := i ↔ p, t → b, A ↔ Y, B ↔ X) (reorder := i p) +@[to_dual (rename := t → b) (reorder := i p) /-- Given morphisms `i : A ⟶ B`, `p : X ⟶ Y`, `b : B ⟶ Y`, this is the property that a lifting exists for all squares with `i` on left, `p` on the right and `b` on the bottom. -/] diff --git a/Mathlib/CategoryTheory/Retract.lean b/Mathlib/CategoryTheory/Retract.lean index 455b39b836faaa..c0986d2ae21ec4 100644 --- a/Mathlib/CategoryTheory/Retract.lean +++ b/Mathlib/CategoryTheory/Retract.lean @@ -32,6 +32,11 @@ structure Retract (X Y : C) where r : Y ⟶ X retract : i ≫ r = 𝟙 X := by cat_disch +to_dual_name_hint I R, IArrow RArrow, Left Right + +attribute [to_dual existing] Retract.i +attribute [to_dual self] Retract.mk + namespace Retract attribute [reassoc (attr := simp)] retract @@ -47,6 +52,8 @@ def op : Retract (op X) (op Y) where r := h.i.op retract := by simp [← op_comp, h.retract] +attribute [to_dual existing] op_i + /-- If `X` is a retract of `Y`, then `F.obj X` is a retract of `F.obj Y`. -/ @[simps] def map (F : C ⥤ D) : Retract (F.obj X) (F.obj Y) where @@ -54,18 +61,16 @@ def map (F : C ⥤ D) : Retract (F.obj X) (F.obj Y) where r := F.map h.r retract := by rw [← F.map_comp h.i h.r, h.retract, F.map_id] +attribute [to_dual existing] map_i + /-- a retract determines a split epimorphism. -/ -@[simps] def splitEpi : SplitEpi h.r where +@[to_dual (attr := simps)/-- a retract determines a split monomorphism. -/] +def splitEpi : SplitEpi h.r where section_ := h.i -/-- a retract determines a split monomorphism. -/ -@[simps] def splitMono : SplitMono h.i where - retraction := h.r - +@[to_dual] instance : IsSplitEpi h.r := ⟨⟨h.splitEpi⟩⟩ -instance : IsSplitMono h.i := ⟨⟨h.splitMono⟩⟩ - variable (X) in /-- Any object is a retract of itself. -/ @[simps] @@ -73,12 +78,16 @@ def refl : Retract X X where i := 𝟙 X r := 𝟙 X +attribute [to_dual existing] refl_i + /-- A retract of a retract is a retract. -/ @[simps] def trans {Z : C} (h' : Retract Y Z) : Retract X Z where i := h.i ≫ h'.i r := h'.r ≫ h.r +attribute [to_dual existing] trans_i + /-- If `e : X ≅ Y`, then `X` is a retract of `Y`. -/ def ofIso (e : X ≅ Y) : Retract X Y where i := e.hom @@ -98,6 +107,7 @@ end Retract ``` A morphism `f : X ⟶ Y` is a retract of `g : Z ⟶ W` if there are morphisms `i : f ⟶ g` and `r : g ⟶ f` in the arrow category such that `i ≫ r = 𝟙 f`. -/ +@[to_dual self] abbrev RetractArrow {X Y Z W : C} (f : X ⟶ Y) (g : Z ⟶ W) := Retract (Arrow.mk f) (Arrow.mk g) namespace RetractArrow @@ -105,60 +115,58 @@ namespace RetractArrow variable {X Y Z W : C} {f : X ⟶ Y} {g : Z ⟶ W} (h : RetractArrow f g) set_option backward.isDefEq.respectTransparency false in -- This is needed for `MorphismProperty/Retract.lean` -@[reassoc] +@[to_dual none, reassoc] lemma i_w : h.i.left ≫ g = f ≫ h.i.right := h.i.w -@[reassoc] +@[to_dual none, reassoc] lemma r_w : h.r.left ≫ f = g ≫ h.r.right := h.r.w /-- The top of a retract diagram of morphisms determines a retract of objects. -/ -@[simps!] +@[to_dual (attr := simps!) +/-- The bottom of a retract diagram of morphisms determines a retract of objects. -/] def left : Retract X Z := h.map Arrow.leftFunc -/-- The bottom of a retract diagram of morphisms determines a retract of objects. -/ -@[simps!] -def right : Retract Y W := h.map Arrow.rightFunc - -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp))] lemma retract_left : h.i.left ≫ h.r.left = 𝟙 X := h.left.retract -@[reassoc (attr := simp)] -lemma retract_right : h.i.right ≫ h.r.right = 𝟙 Y := h.right.retract - +@[to_dual] instance : IsSplitEpi h.r.left := ⟨⟨h.left.splitEpi⟩⟩ +@[to_dual] instance : IsSplitEpi h.r.right := ⟨⟨h.right.splitEpi⟩⟩ -instance : IsSplitMono h.i.left := ⟨⟨h.left.splitMono⟩⟩ - -instance : IsSplitMono h.i.right := ⟨⟨h.right.splitMono⟩⟩ - /-- If a morphism `f` is a retract of `g`, then `F.map f` is a retract of `F.map g` for any functor `F`. -/ -@[simps!] +@[to_dual self, simps!] def map (F : C ⥤ D) : RetractArrow (F.map f) (F.map g) := Retract.map h F.mapArrow +attribute [to_dual existing] map_i_left map_i_right + set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- If a morphism `f` is a retract of `g`, then `f.op` is a retract of `g.op`. -/ -@[simps] +@[to_dual self, simps] def op : RetractArrow f.op g.op where i := Arrow.homMk (h.r.right.op) (h.r.left.op) (by simp [← op_comp]) r := Arrow.homMk (h.i.right.op) (h.i.left.op) (by simp [← op_comp]) retract := by ext <;> simp [← op_comp] +attribute [to_dual existing (reorder := X Y, Z W)] op_i + set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- If a morphism `f` in the opposite category is a retract of `g`, then `f.unop` is a retract of `g.unop`. -/ -@[simps] +@[to_dual self, simps] def unop {X Y Z W : Cᵒᵖ} {f : X ⟶ Y} {g : Z ⟶ W} (h : RetractArrow f g) : RetractArrow f.unop g.unop where i := Arrow.homMk (h.r.right.unop) (h.r.left.unop) (by simp [← unop_comp]) r := Arrow.homMk (h.i.right.unop) (h.i.left.unop) (by simp [← unop_comp]) retract := by ext <;> simp [← unop_comp] +attribute [to_dual existing (reorder := X Y, Z W)] unop_i + end RetractArrow namespace Iso @@ -169,16 +177,20 @@ def retract {X Y : C} (e : X ≅ Y) : Retract X Y where i := e.hom r := e.inv +attribute [to_dual existing] retract_i + end Iso set_option backward.defeqAttrib.useBackward true in /-- If `X` is a retract of `Y`, then for any natural transformation `τ`, the natural transformation `τ.app X` is a retract of `τ.app Y`. -/ -@[simps] +@[to_dual self, simps] def NatTrans.retractArrowApp {F G : C ⥤ D} (τ : F ⟶ G) {X Y : C} (h : Retract X Y) : RetractArrow (τ.app X) (τ.app Y) where i := Arrow.homMk (F.map h.i) (G.map h.i) (by simp) r := Arrow.homMk (F.map h.r) (G.map h.r) (by simp) retract := by ext <;> simp [← Functor.map_comp] +attribute [to_dual existing (reorder := F G)] NatTrans.retractArrowApp_i + end CategoryTheory From 3b0b30fd15768f38512a31e77829059749e29b0e Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:57:03 +0000 Subject: [PATCH 0317/1300] chore(CategoryTheory/EqToHom): use `to_dual none` (#40965) This PR tags `eqToHom` with `to_dual`. Unfortunately ,`eqToHom` is not conveniently self dual, because for this the direction of the equality needs to be swapped. So, we mostly use `to_dual none` to generate non-user-facing duals. This is needed to dualize some proofs later on. --- Mathlib/CategoryTheory/EqToHom.lean | 65 ++++++++++++++++------- Mathlib/CategoryTheory/Functor/Basic.lean | 1 + Mathlib/CategoryTheory/Functor/Const.lean | 2 + 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/Mathlib/CategoryTheory/EqToHom.lean b/Mathlib/CategoryTheory/EqToHom.lean index 803eb1b07b990e..84483ea2b59654 100644 --- a/Mathlib/CategoryTheory/EqToHom.lean +++ b/Mathlib/CategoryTheory/EqToHom.lean @@ -45,6 +45,12 @@ def eqToHom {C : Type u₁} [CategoryStruct.{v₁} C] {X Y : C} (p : X = Y) : rw [p] exact 𝟙 _ +/-- `eqToHom'` is the dual of `eqToHom`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing eqToHom] +abbrev eqToHom' {C : Type u₁} [CategoryStruct.{v₁} C] {X Y : C} (p : X = Y) : Y ⟶ X := + eqToHom p.symm + @[simp] theorem eqToHom_refl {C : Type u₁} [CategoryStruct.{v₁} C] (X : C) (p : X = X) : eqToHom p = 𝟙 X := @@ -52,7 +58,7 @@ theorem eqToHom_refl {C : Type u₁} [CategoryStruct.{v₁} C] (X : C) (p : X = variable {C : Type u₁} [Category.{v₁} C] -@[reassoc (attr := simp)] +@[to_dual none, reassoc (attr := simp)] theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) : eqToHom p ≫ eqToHom q = eqToHom (p.trans q) := by cases p @@ -60,95 +66,108 @@ theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) : simp /-- `eqToHom h` is heterogeneously equal to the identity of its domain. -/ +@[to_dual none] lemma eqToHom_heq_id_dom (X Y : C) (h : X = Y) : eqToHom h ≍ 𝟙 X := by subst h; rfl /-- `eqToHom h` is heterogeneously equal to the identity of its codomain. -/ +@[to_dual none] lemma eqToHom_heq_id_cod (X Y : C) (h : X = Y) : eqToHom h ≍ 𝟙 Y := by subst h; rfl /-- Two morphisms are conjugate via eqToHom if and only if they are heterogeneously equal. Note this used to be in the Functor namespace, where it doesn't belong. -/ +@[to_dual none] theorem conj_eqToHom_iff_heq {W X Y Z : C} (f : W ⟶ X) (g : Y ⟶ Z) (h : W = Y) (h' : X = Z) : f = eqToHom h ≫ g ≫ eqToHom h'.symm ↔ f ≍ g := by cases h cases h' simp +@[to_dual none] theorem conj_eqToHom_iff_heq' {C} [Category* C] {W X Y Z : C} (f : W ⟶ X) (g : Y ⟶ Z) (h : W = Y) (h' : Z = X) : f = eqToHom h ≫ g ≫ eqToHom h' ↔ f ≍ g := conj_eqToHom_iff_heq _ _ _ h'.symm +@[to_dual none] theorem comp_eqToHom_iff {X Y Y' : C} (p : Y = Y') (f : X ⟶ Y) (g : X ⟶ Y') : f ≫ eqToHom p = g ↔ f = g ≫ eqToHom p.symm := { mp h := by simp [← h] mpr h := by simp [eq_whisker h (eqToHom p)] } +@[to_dual none] theorem eqToHom_comp_iff {X X' Y : C} (p : X = X') (f : X ⟶ Y) (g : X' ⟶ Y) : eqToHom p ≫ g = f ↔ g = eqToHom p.symm ≫ f := { mp h := by simp [← h] mpr h := by simp [h] } +@[to_dual none] theorem eqToHom_comp_heq {C} [Category* C] {W X Y : C} (f : Y ⟶ X) (h : W = Y) : eqToHom h ≫ f ≍ f := by rw [← conj_eqToHom_iff_heq _ _ h rfl, eqToHom_refl, Category.comp_id] -@[simp] theorem eqToHom_comp_heq_iff {C} [Category* C] {W X Y Z Z' : C} +@[simp, to_dual none] +theorem eqToHom_comp_heq_iff {C} [Category* C] {W X Y Z Z' : C} (f : Y ⟶ X) (g : Z ⟶ Z') (h : W = Y) : eqToHom h ≫ f ≍ g ↔ f ≍ g := ⟨(eqToHom_comp_heq ..).symm.trans, (eqToHom_comp_heq ..).trans⟩ -@[simp] theorem heq_eqToHom_comp_iff {C} [Category* C] {W X Y Z Z' : C} +@[simp, to_dual none] +theorem heq_eqToHom_comp_iff {C} [Category* C] {W X Y Z Z' : C} (f : Y ⟶ X) (g : Z ⟶ Z') (h : W = Y) : g ≍ eqToHom h ≫ f ↔ g ≍ f := ⟨(·.trans (eqToHom_comp_heq ..)), (·.trans (eqToHom_comp_heq ..).symm)⟩ +@[to_dual none] theorem comp_eqToHom_heq {C} [Category* C] {X Y Z : C} (f : X ⟶ Y) (h : Y = Z) : f ≫ eqToHom h ≍ f := by rw [← conj_eqToHom_iff_heq' _ _ rfl h, eqToHom_refl, Category.id_comp] -@[simp] theorem comp_eqToHom_heq_iff {C} [Category* C] {W X Y Z Z' : C} +@[simp, to_dual none] +theorem comp_eqToHom_heq_iff {C} [Category* C] {W X Y Z Z' : C} (f : X ⟶ Y) (g : Z ⟶ Z') (h : Y = W) : f ≫ eqToHom h ≍ g ↔ f ≍ g := ⟨(comp_eqToHom_heq ..).symm.trans, (comp_eqToHom_heq ..).trans⟩ -@[simp] theorem heq_comp_eqToHom_iff {C} [Category* C] {W X Y Z Z' : C} +@[simp, to_dual none] +theorem heq_comp_eqToHom_iff {C} [Category* C] {W X Y Z Z' : C} (f : X ⟶ Y) (g : Z ⟶ Z') (h : Y = W) : g ≍ f ≫ eqToHom h ↔ g ≍ f := ⟨(·.trans (comp_eqToHom_heq ..)), (·.trans (comp_eqToHom_heq ..).symm)⟩ +@[to_dual self (reorder := X Z, X' Z', f g, f' g', eq1 eq3, H1 H2)] theorem heq_comp {C} [Category* C] {X Y Z X' Y' Z' : C} {f : X ⟶ Y} {g : Y ⟶ Z} {f' : X' ⟶ Y'} {g' : Y' ⟶ Z'} (eq1 : X = X') (eq2 : Y = Y') (eq3 : Z = Z') (H1 : f ≍ f') (H2 : g ≍ g') : f ≫ g ≍ f' ≫ g' := by - grind + congr! variable {β : Sort*} /-- We can push `eqToHom` to the left through families of morphisms. -/ -@[reassoc (attr := simp)] +@[to_dual none, reassoc (attr := simp)] theorem eqToHom_naturality {f g : β → C} (z : ∀ b, f b ⟶ g b) {j j' : β} (w : j = j') : z j ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ z j' := by cases w simp /-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/ -@[reassoc (attr := simp)] +@[to_dual none, reassoc (attr := simp)] theorem eqToHom_iso_hom_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') : (z j).hom ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').hom := by cases w simp /-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/ -@[reassoc (attr := simp)] +@[to_dual none, reassoc (attr := simp)] theorem eqToHom_iso_inv_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') : (z j).inv ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').inv := by cases w simp /-- Reducible form of `congrArg_mpr_hom_left` -/ -@[simp] +@[simp, to_dual none] theorem congrArg_cast_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) : cast (congrArg (fun W : C => W ⟶ Z) p.symm) q = eqToHom p ≫ q := by cases p @@ -161,13 +180,14 @@ we can replace the resulting `_.mpr f` term by a composition with an `eqToHom`. It may be advisable to introduce any necessary `eqToHom` morphisms manually, rather than relying on this lemma firing. -/ +@[to_dual none] theorem congrArg_mpr_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) : (congrArg (fun W : C => W ⟶ Z) p).mpr q = eqToHom p ≫ q := by cases p simp /-- Reducible form of `congrArg_mpr_hom_right` -/ -@[simp] +@[simp, to_dual none] theorem congrArg_cast_hom_right {X Y Z : C} (p : X ⟶ Y) (q : Z = Y) : cast (congrArg (fun W : C => X ⟶ W) q.symm) p = p ≫ eqToHom q.symm := by cases q @@ -180,6 +200,7 @@ we can replace the resulting `_.mpr f` term by a composition with an `eqToHom`. It may be advisable to introduce any necessary `eqToHom` morphisms manually, rather than relying on this lemma firing. -/ +@[to_dual none] theorem congrArg_mpr_hom_right {X Y Z : C} (p : X ⟶ Y) (q : Z = Y) : (congrArg (fun W : C => X ⟶ W) q).mpr p = p ≫ eqToHom q.symm := by cases q @@ -197,7 +218,7 @@ def eqToIso {X Y : C} (p : X = Y) : X ≅ Y := theorem eqToIso.hom {X Y : C} (p : X = Y) : (eqToIso p).hom = eqToHom p := rfl -@[simp] +@[simp, to_dual existing hom] theorem eqToIso.inv {X Y : C} (p : X = Y) : (eqToIso p).inv = eqToHom p.symm := rfl @@ -209,21 +230,22 @@ theorem eqToIso_refl {X : C} (p : X = X) : eqToIso p = Iso.refl X := theorem eqToIso_trans {X Y Z : C} (p : X = Y) (q : Y = Z) : eqToIso p ≪≫ eqToIso q = eqToIso (p.trans q) := by ext; simp -@[simp] +@[simp, to_dual none] theorem eqToHom_op {X Y : C} (h : X = Y) : (eqToHom h).op = eqToHom (congr_arg op h.symm) := by cases h rfl -@[simp] +@[simp, to_dual none] theorem eqToHom_unop {X Y : Cᵒᵖ} (h : X = Y) : (eqToHom h).unop = eqToHom (congr_arg unop h.symm) := by cases h rfl +@[to_dual none] instance {X Y : C} (h : X = Y) : IsIso (eqToHom h) := (eqToIso h).isIso_hom -@[simp] +@[simp, to_dual none] theorem inv_eqToHom {X Y : C} (h : X = Y) : inv (eqToHom h) = eqToHom h.symm := by cat_disch @@ -233,6 +255,7 @@ namespace Functor /-- Proving equality between functors. This isn't an extensionality lemma, because usually you don't really want to do this. -/ +@[to_dual none] theorem ext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X) (h_map : ∀ X Y f, F.map f = eqToHom (h_obj X) ≫ G.map f ≫ eqToHom (h_obj Y).symm := by cat_disch) : @@ -246,6 +269,7 @@ theorem ext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X) funext X Y f simpa using h_map X Y f +@[to_dual none] lemma ext_of_iso {F G : C ⥤ D} (e : F ≅ G) (hobj : ∀ X, F.obj X = G.obj X) (happ : ∀ X, e.hom.app X = eqToHom (hobj X) := by cat_disch) : F = G := Functor.ext hobj (fun X Y f => by @@ -253,6 +277,7 @@ lemma ext_of_iso {F G : C ⥤ D} (e : F ≅ G) (hobj : ∀ X, F.obj X = G.obj X) Category.assoc, eqToHom_trans, eqToHom_refl, Category.comp_id]) /-- Proving equality between functors using heterogeneous equality. -/ +@[to_dual none] theorem hext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X) (h_map : ∀ (X Y) (f : X ⟶ Y), F.map f ≍ G.map f) : F = G := Functor.ext h_obj fun _ _ f => (conj_eqToHom_iff_heq _ _ (h_obj _) (h_obj _)).2 <| h_map _ _ f @@ -260,7 +285,7 @@ theorem hext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X) -- Using equalities between functors. theorem congr_obj {F G : C ⥤ D} (h : F = G) (X) : F.obj X = G.obj X := by rw [h] -@[reassoc] +@[to_dual none, reassoc] theorem congr_hom {F G : C ⥤ D} (h : F = G) {X Y} (f : X ⟶ Y) : F.map f = eqToHom (congr_obj h X) ≫ G.map f ≫ eqToHom (congr_obj h Y).symm := by subst h; simp @@ -314,10 +339,11 @@ e.g. the naturality of a natural transformation. In some files it may be appropriate to use `attribute [local simp] eqToHom_map`, however. -/ +@[to_dual none] theorem eqToHom_map (F : C ⥤ D) {X Y : C} (p : X = Y) : F.map (eqToHom p) = eqToHom (congr_arg F.obj p) := by cases p; simp -@[reassoc (attr := simp)] +@[to_dual none, reassoc (attr := simp)] theorem eqToHom_map_comp (F : C ⥤ D) {X Y Z : C} (p : X = Y) (q : Y = Z) : F.map (eqToHom p) ≫ F.map (eqToHom q) = F.map (eqToHom <| p.trans q) := by cat_disch @@ -330,18 +356,21 @@ theorem eqToIso_map (F : C ⥤ D) {X Y : C} (p : X = Y) : theorem eqToIso_map_trans (F : C ⥤ D) {X Y Z : C} (p : X = Y) (q : Y = Z) : F.mapIso (eqToIso p) ≪≫ F.mapIso (eqToIso q) = F.mapIso (eqToIso <| p.trans q) := by cat_disch -@[simp] +@[simp, to_dual none] theorem eqToHom_app {F G : C ⥤ D} (h : F = G) (X : C) : (eqToHom h : F ⟶ G).app X = eqToHom (Functor.congr_obj h X) := by subst h; rfl +@[to_dual none] theorem NatTrans.congr {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (h : X = Y) : α.app X = F.map (eqToHom h) ≫ α.app Y ≫ G.map (eqToHom h.symm) := by rw [α.naturality_assoc] simp [eqToHom_map] +@[to_dual none] theorem eq_conj_eqToHom {X Y : C} (f : X ⟶ Y) : f = eqToHom rfl ≫ f ≫ eqToHom rfl := by simp only [Category.id_comp, eqToHom_refl, Category.comp_id] +@[to_dual none] theorem dcongr_arg {ι : Type*} {F G : ι → C} (α : ∀ i, F i ⟶ G i) {i j : ι} (h : i = j) : α i = eqToHom (congr_arg F h) ≫ α j ≫ eqToHom (congr_arg G h.symm) := by subst h diff --git a/Mathlib/CategoryTheory/Functor/Basic.lean b/Mathlib/CategoryTheory/Functor/Basic.lean index a17461442eee7e..9031718383e63f 100644 --- a/Mathlib/CategoryTheory/Functor/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/Basic.lean @@ -58,6 +58,7 @@ attribute [grind =] Functor.map_id attribute [grind _=_] Functor.map_comp attribute [to_dual self] Functor.map Functor.map_comp attribute [to_dual self (reorder := map (X Y), map_comp (X Z, f g))] Functor.mk +attribute [to_dual self (reorder := mk (map (X Y), map_comp (X Z, f g)))] Functor.casesOn -- Note: We manually add this lemma which could be generated by `reassoc`, -- since we will import this file into `Mathlib/Tactic/CategoryTheory/Reassoc.lean`. diff --git a/Mathlib/CategoryTheory/Functor/Const.lean b/Mathlib/CategoryTheory/Functor/Const.lean index 970b034f3908e7..bda33f17f1d728 100644 --- a/Mathlib/CategoryTheory/Functor/Const.lean +++ b/Mathlib/CategoryTheory/Functor/Const.lean @@ -39,6 +39,8 @@ def const : C ⥤ J ⥤ C where map := fun _ => 𝟙 X } map f := { app := fun _ => f } +attribute [to_dual self] const_obj_map + namespace const open Opposite From e14cf926ad86a02390bdae31e696eee6b4c1d238 Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Wed, 24 Jun 2026 11:46:53 +0000 Subject: [PATCH 0318/1300] chore: add deprecation for `OpenPartialHomeomorph.prod_toPartialEquiv` (#40992) As requested (privately) by @grunweg . --- Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean index 7da001d1a1cebe..39cc3938b52177 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean @@ -86,6 +86,11 @@ def prod (eX : OpenPartialHomeomorph X X') (eY : OpenPartialHomeomorph Y Y') : continuousOn_invFun := eX.continuousOn_symm.prodMap eY.continuousOn_symm toPartialEquiv := eX.toPartialEquiv.prod eY.toPartialEquiv +@[deprecated "deprecated in favour of `OpenPartialHomeomorph.prod_toPartialHomeomorph`" + (since := "2026-06-24")] +lemma prod_toPartialEquiv (eX : OpenPartialHomeomorph X X') (eY : OpenPartialHomeomorph Y Y') : + (eX.prod eY).toPartialHomeomorph.toPartialEquiv = eX.toPartialEquiv.prod eY.toPartialEquiv := + rfl @[simp, mfld_simps] theorem prod_symm (eX : OpenPartialHomeomorph X X') (eY : OpenPartialHomeomorph Y Y') : (eX.prod eY).symm = eX.symm.prod eY.symm := From 9e46613652ab97dc557552292f12f08b95c932ee Mon Sep 17 00:00:00 2001 From: "Filippo A. E. Nuccio" <65080144+faenuccio@users.noreply.github.com> Date: Wed, 24 Jun 2026 12:05:15 +0000 Subject: [PATCH 0319/1300] perf(RingTheory/Kaehler/JacobiZariski): remove useless instances (#40858) This PR removes some instances that were previously needed to avoid some timeouts. Co-authored-by: faenuccio --- Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index 1220b5ccd0bf32..0efb5430ddfabc 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -130,12 +130,6 @@ def CotangentSpace.compEquiv : (Q.comp P).cotangentSpaceBasis.repr.trans (Q.cotangentSpaceBasis.prod (P.cotangentSpaceBasis.baseChange T)).repr.symm -section instanceProblem - --- Note: these instances are needed to prevent instance search timeouts. -attribute [local instance 999999] Zero.toOfNat0 SemilinearMapClass.distribMulActionSemiHomClass - SemilinearEquivClass.instSemilinearMapClass instAddZeroClassTensorProduct AddZero.toZero - lemma CotangentSpace.compEquiv_symm_inr : (compEquiv Q P).symm.toLinearMap ∘ₗ LinearMap.inr T Q.toExtension.CotangentSpace (T ⊗[S] P.toExtension.CotangentSpace) = @@ -448,8 +442,6 @@ lemma exact_map_δ' (f : Hom W Q) : end H1Cotangent -end instanceProblem - end Generators variable {T : Type u₃} [CommRing T] [Algebra R T] [Algebra S T] [IsScalarTower R S T] From 2ef78a0069c7db7c2e8d4dadd6aa8fe38f5525a9 Mon Sep 17 00:00:00 2001 From: Bingyu Xia <71547343+BryceT233@users.noreply.github.com> Date: Wed, 24 Jun 2026 12:22:10 +0000 Subject: [PATCH 0320/1300] feat(RingTheory/Kaehler/JacobiZariski): exactness at the left of Jacobi-Zariski sequence under flatness assumption (#39958) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given algebras `R → S → T` and `T` flat over `S`, this PR adds the exactness of `T ⊗[S] H₁(L_{S/R}) → H₁(L_{T/R}) → H₁(L_{T/S})` at the left of Jacobi-Zariski sequence. Note that the flatness assumption here is stronger than the Tor-vanishing conditions required in the full statement of [Stacks Project, 00S2](https://stacks.math.columbia.edu/tag/00S2), this should be refactored and generalized once more results on Tor modules are available. --- Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 114 ++++++++++++++++-- 1 file changed, 106 insertions(+), 8 deletions(-) diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index 0efb5430ddfabc..3b95f71029bacd 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -8,26 +8,47 @@ module public import Mathlib.RingTheory.Extension.Cotangent.Basic public import Mathlib.RingTheory.Extension.Generators public import Mathlib.Algebra.Module.SnakeLemma +public import Mathlib.RingTheory.Flat.Basic /-! # The Jacobi-Zariski exact sequence -Given `R → S → T`, the Jacobi-Zariski exact sequence is -``` -H¹(L_{T/R}) → H¹(L_{T/S}) → T ⊗[S] Ω[S/R] → Ω[T/R] → Ω[T/S] → 0 -``` -The maps are +Given algebras $R \to S \to T$, the Jacobi-Zariski exact sequence is a long exact sequence +relating the first homology of the naive cotangent complexes and the Kähler differentials of +the respective algebras. It takes the form: +$$ +H_1(L_{T/R}) \to H_1(L_{T/S}) \to T \otimes_S \Omega_{S/R} \to \Omega_{T/R} \to \Omega_{T/S} \to 0 +$$ +The maps in the sequence are - `Algebra.H1Cotangent.map` - `Algebra.H1Cotangent.δ` - `KaehlerDifferential.mapBaseChange` - `KaehlerDifferential.map` -and the exactness lemmas are +The exactness lemmas are - `Algebra.H1Cotangent.exact_map_δ` - `Algebra.H1Cotangent.exact_δ_mapBaseChange` - `KaehlerDifferential.exact_mapBaseChange_map` - `KaehlerDifferential.map_surjective` + +When $T$ is flat over $S$, the left bottom part of the snake lemma diagram used in +the construction of the connecting homomorphism `Algebra.Generators.H1Cotangent.δ` +naturally extends via a base change map. The exactness lemma is +`Algebra.Generators.H1Cotangent.exact_liftBaseChange_map_of_flat`. Globally, this extends +the Jacobi-Zariski exact sequence to the left via a natural base change map, taking the form +$$ +T \otimes_S H_1(L_{S/R}) \to H_1(L_{T/R}) \to H_1(L_{T/S}) +$$ +The exactness lemma is `Algebra.H1Cotangent.exact_liftBaseChange_map_of_flat`. + +# TODO + +The flatness assumption in `Algebra.H1Cotangent.exact_liftBaseChange_map_of_flat` +is stronger than the `Tor`-vanishing conditions required in the full statement of +[Stacks Project, 00S2], this should be refactored and generalized once more API +for `Tor` modules is available. + -/ @[expose] public section @@ -440,6 +461,67 @@ lemma exact_map_δ' (f : Hom W Q) : rw [← Extension.H1Cotangent.map_comp, Extension.H1Cotangent.map_eq _ (Q.ofComp P).toExtensionHom] exact exact_map_δ Q P +open LinearMap in +lemma liftBaseChange_range_le : + (liftBaseChange T (Extension.H1Cotangent.map (Q.toComp P).toExtensionHom)).range ≤ + (Extension.H1Cotangent.map (Q.ofComp P).toExtensionHom).ker := by + rw [range_liftBaseChange, coe_range, Submodule.span_le, Set.range_subset_iff] + rintro ⟨x, _⟩ + obtain ⟨⟨(x : P.Ring), x_in⟩, rfl⟩ := Extension.Cotangent.mk_surjective x + ext; suffices (Q.ofComp P).toAlgHom ((Q.toComp P).toAlgHom x) ∈ Q.toExtension.ker ^ 2 by + simpa [Ideal.toCotangent_eq_zero] + rw [← Generators.ker, Generators.ker_eq_ker_aeval_val] at x_in + rw [toComp_toAlgHom, toAlgHom_ofComp_rename, Generators.algebraMap_eq, RingHom.coe_coe, + x_in, RingHom.map_zero] + exact Ideal.zero_mem _ + +private lemma auxMemKer (z : T ⊗[S] P.toExtension.H1Cotangent) : + LinearMap.liftBaseChange T (Extension.Cotangent.map (Q.toComp P).toExtensionHom) + ((LinearMap.lTensor T Extension.h1Cotangentι) z) ∈ + (Q.comp P).toExtension.cotangentComplex.ker := by + induction z with + | zero => simp + | tmul x y => simp [← Extension.CotangentSpace.map_cotangentComplex] + | add x y hx hy => simpa using Submodule.add_mem _ hx hy + +open LinearMap in +/-- When $T$ is flat over $S$, the left bottom part of the snake lemma diagram used in +the construction of the connecting homomorphism `Algebra.Generators.H1Cotangent.δ` +naturally extends via a base change map. -/ +theorem exact_liftBaseChange_map_of_flat [Module.Flat S T] : + Function.Exact ((Extension.H1Cotangent.map (toComp Q P).toExtensionHom).liftBaseChange T) + (Extension.H1Cotangent.map (ofComp Q P).toExtensionHom) := by + rw [exact_iff] + refine le_antisymm ?_ (liftBaseChange_range_le Q P) + rintro ⟨x, x_in⟩ hx + replace hx : Extension.Cotangent.map (Q.ofComp P).toExtensionHom x = 0 := by + simpa [← Extension.h1Cotangentι_injective.eq_iff] using hx + rw [← mem_ker, (Cotangent.exact Q P).linearMap_ker_eq] at hx + rcases hx with ⟨x, rfl⟩ + rw [mem_ker, ← comp_apply, ← map_comp_cotangentComplex_baseChange, comp_apply, + ← mem_ker, ker_eq_bot.mpr (CotangentSpace.map_toComp_injective Q P), Submodule.mem_bot, + baseChange_eq_ltensor, ← mem_ker, (Module.Flat.lTensor_exact T + P.toExtension.exact_hCotangentι_cotangentComplex).linearMap_ker_eq] at x_in + rcases x_in with ⟨x, rfl⟩ + use x; induction x with + | zero => ext; simp + | tmul x y => ext; simp + | add x y hx hy => ext; simp [hx (auxMemKer Q P x), hy (auxMemKer Q P y)] + +/-- A variant of `exact_liftBaseChange_map_of_flat` that takes in +arbitrary maps between generators. -/ +theorem exact_liftBaseChange_map_of_flat' [Module.Flat S T] (f : Hom W Q) (g : Hom P W) : + Function.Exact ((Extension.H1Cotangent.map g.toExtensionHom).liftBaseChange T) + (Extension.H1Cotangent.map f.toExtensionHom) := by + rw [← LinearEquiv.conj_exact_iff_exact _ _ (H1Cotangent.equiv W (Q.comp P))] + convert! exact_liftBaseChange_map_of_flat Q P + · change Extension.H1Cotangent.map (W.defaultHom (Q.comp P)).toExtensionHom ∘ₗ _ = _ + rw [LinearMap.liftBaseChange_comp, ← Extension.H1Cotangent.map_comp, + Extension.H1Cotangent.map_eq] + · change (Extension.H1Cotangent.map f.toExtensionHom).restrictScalars T ∘ₗ + (Extension.H1Cotangent.map _) = _ + rw [← Extension.H1Cotangent.map_comp, Extension.H1Cotangent.map_eq] + end H1Cotangent end Generators @@ -453,13 +535,29 @@ noncomputable def H1Cotangent.δ : H1Cotangent S T →ₗ[T] T ⊗[S] Ω[S⁄R] := Generators.H1Cotangent.δ (Generators.self S T) (Generators.self R S) -/-- Given algebras `R → S → T`, `H¹(L_{T/R}) → H¹(L_{T/S}) → T ⊗[S] Ω[S/R]` is exact. -/ +/-- Given algebras $R \to S \to T$, the sequence +$H_1(L_{T/R}) \to H_1(L_{T/S}) \to T \otimes_S \Omega_{S/R}$ +is exact. -/ +@[stacks 00S2] lemma H1Cotangent.exact_map_δ : Function.Exact (map R S T T) (δ R S T) := Generators.H1Cotangent.exact_map_δ' (Generators.self S T) (Generators.self R S) (Generators.self R T) (Generators.defaultHom _ _) -/-- Given algebras `R → S → T`, `H¹(L_{T/S}) → T ⊗[S] Ω[S/R] → Ω[T/R]` is exact. -/ +/-- Given algebras $R \to S \to T$, the sequence +$H_1(L_{T/S}) \to T \otimes_S \Omega_{S/R} \to \Omega_{T/R}$ +is exact. -/ +@[stacks 00S2] lemma H1Cotangent.exact_δ_mapBaseChange : Function.Exact (δ R S T) (mapBaseChange R S T) := Generators.H1Cotangent.exact_δ_map (Generators.self S T) (Generators.self R S) +/-- Given algebras $R \to S \to T$ and $T$ flat over $S$, the sequence +$T \otimes_S H_1(L_{S/R}) \to H_1(L_{T/R}) \to H_1(L_{T/S})$ +is exact. -/ +@[stacks 00S2] +lemma H1Cotangent.exact_liftBaseChange_map_of_flat [Module.Flat S T] : + Function.Exact ((map R R S T).liftBaseChange T) (map R S T T) := + Generators.H1Cotangent.exact_liftBaseChange_map_of_flat' + (Generators.self S T) (Generators.self R S) (Generators.self R T) + (Generators.defaultHom _ _) (Generators.defaultHom _ _) + end Algebra From 1af9e904063980cfb3b4f235d40a579e5c7e4285 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Wed, 24 Jun 2026 12:38:53 +0000 Subject: [PATCH 0321/1300] feat(AlgebraicGeometry/Modules): a quasi-coherent module has a presentation on an affine cover (#40988) This is merely a rewording of the definition in terms of the scheme API. --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 16 +++++++ Mathlib/AlgebraicGeometry/Cover/Open.lean | 4 ++ Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 44 +++++++++++++++++++- Mathlib/AlgebraicGeometry/OpenImmersion.lean | 7 ++++ Mathlib/Topology/Sets/OpenCover.lean | 8 ++++ Mathlib/Topology/Sets/Opens.lean | 13 ++++++ 6 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 06bc6b0c1d65fa..9a1138dac3fd1c 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -432,6 +432,10 @@ instance isOpenImmersion_fromSpec : @[reassoc (attr := simp)] lemma isoSpec_inv_ι : hU.isoSpec.inv ≫ U.ι = hU.fromSpec := rfl +@[reassoc (attr := simp)] +lemma isoSpec_hom_fromSpec : hU.isoSpec.hom ≫ hU.fromSpec = U.ι := by + simp [← cancel_epi hU.isoSpec.inv] + @[reassoc (attr := simp)] lemma toSpecΓ_fromSpec : U.toSpecΓ ≫ hU.fromSpec = U.ι := toSpecΓ_isoSpec_inv_assoc _ _ @@ -943,6 +947,18 @@ theorem self_le_iSup_basicOpen_iff {s : Set Γ(X, U)} : end IsAffineOpen +/-- The affine open cover given by a covering family of affine opens. -/ +@[simps I₀ X f] +def Scheme.AffineOpenCover.ofIsOpenCover {X : Scheme.{u}} {ι : Type*} (U : ι → X.Opens) + (hU : IsOpenCover U) (hU' : ∀ i, IsAffineOpen (U i)) : + AffineOpenCover X where + I₀ := ι + X i := Γ(X, U i) + f i := (hU' i).fromSpec + idx x := (hU.exists_mem x).choose + covers x := + ⟨(hU' _).isoSpec.hom ⟨_, (hU.exists_mem x).choose_spec⟩, by simp [← Scheme.Hom.comp_apply]⟩ + set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in open _root_.PrimeSpectrum in diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index 95e6a4c5d07fb0..7d4cf90cf18dc8 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -44,6 +44,10 @@ variable [∀ x, HasPullback (𝒰.f x ≫ f) g] instance (i : 𝒰.I₀) : IsOpenImmersion (𝒰.f i) := 𝒰.map_prop i +instance {𝒱 : OpenCover X} (f : 𝒰 ⟶ 𝒱) (i : 𝒰.I₀) : IsOpenImmersion (f.h₀ i) := + have : IsOpenImmersion (f.h₀ i ≫ 𝒱.f (f.s₀ i)) := by rw [f.w₀]; infer_instance + .of_comp _ (𝒱.f _) + set_option backward.isDefEq.respectTransparency false in /-- The affine cover of a scheme. -/ def affineCover (X : Scheme.{u}) : OpenCover X := by diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index 92eacec3e0c9e2..cdd5f8c98f175d 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -8,7 +8,7 @@ module public import Mathlib.Algebra.Category.ModuleCat.Localization public import Mathlib.Algebra.Category.ModuleCat.Sheaf.Quasicoherent -public import Mathlib.AlgebraicGeometry.AffineScheme +public import Mathlib.Algebra.Module.LocalizedModule.Away public import Mathlib.AlgebraicGeometry.Modules.Sheaf /-! @@ -553,6 +553,48 @@ theorem isIso_fromTildeΓ_pushforward (M : (Spec S).Modules) [h : IsIso M.fromTi end IsLocalizing +set_option backward.isDefEq.respectTransparency false in +/-- The presentation of `M.restrict f` by restricting a presentation of `M`. -/ +def Scheme.Modules.presentationRestrict {X Y : Scheme.{u}} (f : Y ⟶ X) + [IsOpenImmersion f] {M : X.Modules} (pres : M.Presentation) : + (M.restrict f).Presentation := + have : PreservesColimitsOfSize.{u, u} (Scheme.Modules.restrictFunctor f) := + inferInstance + pres.map (Scheme.Modules.restrictFunctor.{u} f) (Scheme.Modules.restrictUnitIso _).symm + +set_option backward.isDefEq.respectTransparency false in +lemma Scheme.Modules.exists_isOpenCover_presentation {X : Scheme.{u}} (M : X.Modules) + [M.IsQuasicoherent] : + ∃ (ι : Type u) (U : ι → X.Opens) (_ : ∀ i, (M.restrict (U i).ι).Presentation), + IsOpenCover U ∧ (∀ i, IsAffineOpen (U i)) := by + obtain ⟨⟨I, W, cov, pres⟩⟩ := SheafOfModules.IsQuasicoherent.nonempty_quasicoherentData (M := M) + choose κ hsub heq using fun i ↦ Opens.isBasis_iff_cover.mp X.isBasis_affineOpens (W i) + refine ⟨Σ (i : I), κ i, fun j ↦ j.2, fun i ↦ ?_, ?_, ?_⟩ + · let u := X.homOfLE (U := i.2) (V := W i.1) (by simp [heq, le_sSup]) + have : PreservesColimitsOfSize.{u, u} (restrictFunctor u) := inferInstance + let F := (overEquiv (W i.1)).functor ⋙ restrictFunctor u + let iso : SheafOfModules.overFunctor X.ringCatSheaf _ ⋙ F ≅ restrictFunctor + (Scheme.Opens.ι i.2.1) := (Functor.associator _ _ _).symm ≪≫ + Functor.isoWhiskerRight (Scheme.Modules.overFunctorEquiv _) _ ≪≫ + (restrictFunctorComp _ _).symm ≪≫ (restrictFunctorCongr (by simp [u])) + exact SheafOfModules.Presentation.ofIsIso.{u, u, u} (iso.app M).hom <| + (pres i.1).map F (Scheme.Modules.restrictUnitIso _).symm + · rw [Opens.coversTop_iff, IsOpenCover] at cov + rw [IsOpenCover, iSup_sigma, ← cov] + refine iSup_congr fun i ↦ ?_ + rw [heq i, sSup_eq_iSup'] + · intro j + exact hsub _ j.2.2 + +lemma Scheme.Modules.exists_affineOpenCover_presentation {X : Scheme.{u}} (M : X.Modules) + [M.IsQuasicoherent] : + ∃ (𝒰 : Scheme.AffineOpenCover.{u} X), + ∀ i, Nonempty (M.restrict (𝒰.f i)).Presentation := by + obtain ⟨ι, U, pres, hU, hU'⟩ := M.exists_isOpenCover_presentation + refine ⟨Scheme.AffineOpenCover.ofIsOpenCover _ hU hU', fun i ↦ ⟨?_⟩⟩ + exact SheafOfModules.Presentation.ofIsIso.{u, u, u} ((restrictFunctorComp _ _).app M).inv <| + (presentationRestrict (hU' i).isoSpec.inv (pres i)) + end IsQuasicoherent end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index aede7ae8f77c45..9a70890f5abce4 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -288,6 +288,13 @@ instance {R} [CommRing R] (f : R) : IsOpenImmersion (Spec.map (CommRingCat.ofHom (algebraMap R (Localization.Away f)))) := isOpenImmersion_SpecMap_localizationAway (R := .of R) f +@[simp] +lemma Hom.opensRange_localizationAway {R : CommRingCat.{u}} (g : R) : + (Spec.map <| CommRingCat.ofHom <| algebraMap R (Localization.Away g)).opensRange = + PrimeSpectrum.basicOpen g := by + rw [SetLike.ext'_iff] + exact PrimeSpectrum.localization_away_comap_range _ g + lemma _root_.AlgebraicGeometry.IsOpenImmersion.of_isLocalization {R S} [CommRing R] [CommRing S] [Algebra R S] (f : R) [IsLocalization.Away f S] : IsOpenImmersion (Spec.map (CommRingCat.ofHom (algebraMap R S))) := by diff --git a/Mathlib/Topology/Sets/OpenCover.lean b/Mathlib/Topology/Sets/OpenCover.lean index e821d5edeb2b03..b6b104943bea7c 100644 --- a/Mathlib/Topology/Sets/OpenCover.lean +++ b/Mathlib/Topology/Sets/OpenCover.lean @@ -61,6 +61,14 @@ lemma isTopologicalBasis (hu : IsOpenCover u) IsTopologicalBasis (⋃ i, (Subtype.val '' ·) '' B i) := isTopologicalBasis_of_cover (fun i ↦ (u i).2) hu.iSup_set_eq_univ hB +lemma exists_finite_of_compactSpace (hu : IsOpenCover u) [CompactSpace X] : + ∃ (s : Finset ι), IsOpenCover (fun i : s ↦ u i.1) := by + rw [IsOpenCover, eq_top_iff, ← SetLike.coe_subset_coe] at hu + obtain ⟨s, hs⟩ := IsCompact.elim_finite_subcover isCompact_univ _ (fun i ↦ (u i).2) + (by simpa using hu) + use s + simpa [IsOpenCover, eq_top_iff, ← SetLike.coe_subset_coe, Set.iUnion_subtype] using hs + end IsOpenCover lemma Opens.IsBasis.isOpenCover {S : Set (Opens X)} (hS : Opens.IsBasis S) : diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index 7c3bb782828e04..8ceb5f00263fea 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -354,6 +354,19 @@ lemma IsBasis.exists_iSup_eq {X : Type u} [TopologicalSpace X] {ι : Type*} use Us, fun i ↦ a i.2 simp [hUs, ha, sSup_eq_iSup' Us] +lemma IsBasis.exists_iSup_eq_of_isCompact {X : Type u} [TopologicalSpace X] {ι : Type*} + {U : ι → TopologicalSpace.Opens X} (hU : TopologicalSpace.Opens.IsBasis (Set.range U)) + (W : TopologicalSpace.Opens X) (hW : IsCompact W.1) : + ∃ (κ : Type u) (_ : Finite κ) (a : κ → ι), W = ⨆ (k : κ), U (a k) := by + obtain ⟨κ, a, heq⟩ := hU.exists_iSup_eq W + obtain ⟨s, hs⟩ := hW.elim_finite_subcover _ (fun k : κ ↦ (U (a k)).2) (by simp [heq]) + use s, s.finite_toSet, a ∘ Subtype.val + refine le_antisymm ?_ ?_ + · simpa [← SetLike.coe_subset_coe, Set.iUnion_subtype] + · rw [heq, iSup_le_iff] + intro i + exact le_iSup_of_le _ le_rfl + /-- If `α` has a basis consisting of compact opens, then an open set in `α` is compact open iff it is a finite union of some elements in the basis -/ theorem IsBasis.isCompact_open_iff_eq_finite_iUnion {ι : Type*} (b : ι → Opens α) From 359d4f8b5ce637ae1d614810c3bb9e333504fda4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:02:29 +0000 Subject: [PATCH 0322/1300] feat(Topology/Sets): compositional continuity lemma for `(Nonempty)Compacts.map` (#40046) This can be used to prove the continuity of a function containing `Compacts.map f`, where `f` itself depends on the variable. --- Mathlib/Topology/Sets/VietorisTopology.lean | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index 808104e7ce3d9b..262594a067bf4c 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -37,7 +37,7 @@ incompatible with the Vietoris topology. open Set Topology -variable {α β : Type*} [TopologicalSpace α] [TopologicalSpace β] {f : α → β} +variable {α β γ : Type*} [TopologicalSpace α] [TopologicalSpace β] [TopologicalSpace γ] {f : α → β} namespace TopologicalSpace @@ -465,10 +465,17 @@ theorem continuous_prod : Continuous fun p : Compacts α × Compacts β => p.1 (isOpen_inter_nonempty_of_isOpen hV).prod (isOpen_inter_nonempty_of_isOpen hW), ⟨x, hx, hxV⟩, ⟨y, hy, hyW⟩⟩ -@[fun_prop] theorem _root_.Continuous.compacts_map (hf : Continuous f) : Continuous (Compacts.map f hf) := isEmbedding_coe.continuous_iff.mpr <| hf.image_vietoris.comp continuous_coe +@[fun_prop] +theorem _root_.Continuous.compacts_map' {f : α → Compacts β} {g : α → β → γ} + (hf : Continuous f) (hg : Continuous g.uncurry) : + Continuous (fun x => (f x).map (g x) (by fun_prop)) := by + conv in Compacts.map _ _ _ => equals ({x} ×ˢ f x).map g.uncurry hg => ext; simp + have := hg.compacts_map + fun_prop + @[fun_prop] theorem _root_.Topology.IsInducing.compacts_map (hf : IsInducing f) : IsInducing (Compacts.map f hf.continuous) := @@ -751,11 +758,17 @@ theorem continuous_prod : simp_rw [isEmbedding_toCompacts.continuous_iff, Function.comp_def, toCompacts_prod] fun_prop -@[fun_prop] theorem _root_.Continuous.nonemptyCompacts_map (hf : Continuous f) : Continuous (NonemptyCompacts.map f hf) := isEmbedding_toCompacts.continuous_iff.mpr <| hf.compacts_map.comp continuous_toCompacts +@[fun_prop] +theorem _root_.Continuous.nonemptyCompacts_map' {f : α → NonemptyCompacts β} {g : α → β → γ} + (hf : Continuous f) (hg : Continuous g.uncurry) : + Continuous (fun x => (f x).map (g x) (by fun_prop)) := by + simp_rw [isEmbedding_toCompacts.continuous_iff, Function.comp_def, toCompacts_map] + fun_prop + @[fun_prop] theorem _root_.Topology.IsInducing.nonemptyCompacts_map (hf : IsInducing f) : IsInducing (NonemptyCompacts.map f hf.continuous) := From 8231e3b02c420c5b378165c8c0685a8e29b75fff Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:02:32 +0000 Subject: [PATCH 0323/1300] chore: remove some exceptions for `linter.unusedSimpArgs` (#40999) Removes all exceptions for the linter when it was indeed right. (tech debt) Co-authored-by: Batixx --- Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean | 4 +--- Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean | 4 +--- Mathlib/Analysis/Calculus/Monotone.lean | 4 +--- Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean | 6 ++---- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean index 942de0e5a8d33f..6adf1fe57679c8 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean @@ -365,15 +365,13 @@ lemma addX_eq_addX_negY_sub {x₁ x₂ : F} (y₁ y₂ : F) (hx : x₁ ≠ x₂) -- Non-terminal simp, used to be field_simp set_option linter.flexible false in --- see https://github.com/leanprover-community/mathlib4/issues/29041 -set_option linter.unusedSimpArgs false in /-- The formula `y(P₁)(x(P₂) - x(P₃)) + y(P₂)(x(P₃) - x(P₁)) + y(P₃)(x(P₁) - x(P₂)) = 0`, assuming that `P₁ + P₂ + P₃ = O`. -/ lemma cyclic_sum_Y_mul_X_sub_X {x₁ x₂ : F} (y₁ y₂ : F) (hx : x₁ ≠ x₂) : let x₃ := W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) y₁ * (x₂ - x₃) + y₂ * (x₃ - x₁) + W.negAddY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂) * (x₁ - x₂) = 0 := by simp_rw [slope_of_X_ne hx, negAddY, addX] - simp [field, sub_ne_zero.mpr hx] + simp [field] ring1 /-- The formula `ψ(P₁ + P₂) = (ψ(P₂)(x(P₁) - x(P₃)) - ψ(P₁)(x(P₂) - x(P₃))) / (x(P₂) - x(P₁))`, diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean index 671eb7272d0753..5e2d6d1ff2f2c2 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean @@ -271,8 +271,6 @@ lemma XYIdeal_eq₁ (x y ℓ : R) : XYIdeal W' x (C y) = XYIdeal W' x (linePolyn -- Non-terminal simp, used to be field_simp set_option linter.flexible false in --- see https://github.com/leanprover-community/mathlib4/issues/29041 -set_option linter.unusedSimpArgs false in lemma XYIdeal_eq₂ [DecidableEq F] {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂) (hxy : ¬(x₁ = x₂ ∧ y₁ = W.negY x₂ y₂)) : XYIdeal W x₂ (C y₂) = XYIdeal W x₂ (linePolynomial x₁ y₁ <| W.slope x₁ x₂ y₁ y₂) := by @@ -281,7 +279,7 @@ lemma XYIdeal_eq₂ [DecidableEq F] {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation · have hy : y₁ ≠ W.negY x₂ y₂ := fun h => hxy ⟨hx, h⟩ rcases hx, Y_eq_of_Y_ne h₁ h₂ hx hy with ⟨rfl, rfl⟩ simp [linePolynomial] - · simp [field, linePolynomial, slope_of_X_ne hx, sub_ne_zero_of_ne hx] + · simp [field, linePolynomial, slope_of_X_ne hx] ring1 nth_rw 1 [hy₂] simp only [XYIdeal, XClass, YClass, linePolynomial] diff --git a/Mathlib/Analysis/Calculus/Monotone.lean b/Mathlib/Analysis/Calculus/Monotone.lean index 30c72dc98563c3..76a4396b7ee376 100644 --- a/Mathlib/Analysis/Calculus/Monotone.lean +++ b/Mathlib/Analysis/Calculus/Monotone.lean @@ -38,8 +38,6 @@ open Set Filter Function Metric MeasureTheory MeasureTheory.Measure IsUnifLocDou open scoped Topology --- see https://github.com/leanprover-community/mathlib4/issues/29041 -set_option linter.unusedSimpArgs false in /-- If `(f y - f x) / (y - x)` converges to a limit as `y` tends to `x`, then the same goes if `y` is shifted a little bit, i.e., `f (y + (y-x)^2) - f x) / (y - x)` converges to the same limit. This lemma contains a slightly more general version of this statement (where one considers @@ -62,7 +60,7 @@ theorem tendsto_apply_add_mul_sq_div_sub {f : ℝ → ℝ} {x a c d : ℝ} {l : apply Tendsto.congr' _ Z have : ∀ᶠ y in l, y + c * (y - x) ^ 2 ≠ x := by apply Tendsto.mono_right h' hl self_mem_nhdsWithin filter_upwards [this] with y hy - simp [field, sub_ne_zero.2 hy] + simp [field] /-- A Stieltjes function is almost everywhere differentiable, with derivative equal to the Radon-Nikodym derivative of the associated Stieltjes measure with respect to Lebesgue. -/ diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean index 99ebf667e962ce..d41254b9cd1ef3 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean @@ -253,8 +253,6 @@ theorem abs_log_sub_add_sum_range_le {x : ℝ} (h : |x| < 1) (n : ℕ) : -- fourth step: conclude by massaging the inequality of the third step simpa [F, div_mul_eq_mul_div, pow_succ] using C --- see https://github.com/leanprover-community/mathlib4/issues/29041 -set_option linter.unusedSimpArgs false in /-- Compute the derivative of the difference between $\frac{1}{2} * \log(\frac{1+x}{1-x})$ and its Taylor series at `0` up to order `n`. This is an auxiliary lemma for @@ -270,14 +268,14 @@ lemma hasDerivAt_half_log_one_add_div_one_sub_sub_sum_range refine ((((((hasDerivAt_id _).const_add _).div ((hasDerivAt_id _).const_sub _) (by grind)).log ?_).const_mul _).sub (HasDerivAt.fun_sum fun i hi ↦ (hasDerivAt_pow _ _).div_const _)) |>.congr_deriv ?_ - · simp only [id_eq, div_ne_zero_iff, Pi.div_apply]; grind + · simp only [div_ne_zero_iff, Pi.div_apply]; grind have : (∑ i ∈ range n, (2 * i + 1) * y ^ (2 * i) / (2 * i + 1)) = (∑ i ∈ range n, (y ^ 2) ^ i) := by congr with i simp [field, mul_comm, ← pow_mul] have hy₃ : y ^ 2 ≠ 1 := by simp [hy₁.ne', hy₂.ne] have hy₄ : (1 - y) * (1 + y) = 1 - y ^ 2 := by ring - simp [this, field, geom_sum_eq hy₃, hy₄, sub_ne_zero_of_ne, hy₃.symm] + simp [this, field, geom_sum_eq hy₃, hy₄] ring /-- A lemma estimating the difference between $\frac{1}{2} * \log(\frac{1+x}{1-x})$ and its From abeb53aa8898625b4c1b6305227f074350a6a958 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Wed, 24 Jun 2026 13:14:59 +0000 Subject: [PATCH 0324/1300] feat(Topology): `IsMonoidHom.isStrictMap_prodMap_iff` (#40673) Co-authored-by: zw810-ctrl Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Oliver Nash Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Topology/Maps/Strict/Basic.lean | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Mathlib/Topology/Maps/Strict/Basic.lean b/Mathlib/Topology/Maps/Strict/Basic.lean index ec2a2ed345a7a0..91558107ed066b 100644 --- a/Mathlib/Topology/Maps/Strict/Basic.lean +++ b/Mathlib/Topology/Maps/Strict/Basic.lean @@ -192,13 +192,20 @@ variable {G H G' H' : Type*} [Group G'] [Group H'] [Group G] [Group H] (f : G variable {f g} [TopologicalSpace G'] [IsTopologicalGroup G'] [TopologicalSpace H'] +/-- The product (in the sense of `Prod.map`) of group homomorphisms is strict if and only if each +of the morphisms is strict. -/ +@[to_additive isStrictMap_prodMap_iff] lemma isStrictMap_prodMap_iff : + IsStrictMap (f.prodMap g) ↔ IsStrictMap f ∧ IsStrictMap g := by + simp_rw [isStrictMap_iff_isOpenQuotientMap_rangeRestrict] + let Φ : (f.prodMap g).range ≃ₜ f.range × g.range := + (Homeomorph.setCongr (by simp [Subgroup.coe_prod])).trans (Homeomorph.Set.prod _ _) + have eq : Φ ∘ (f.prodMap g).rangeRestrict = f.rangeRestrict.prodMap g.rangeRestrict := rfl + rw [← Φ.comp_isOpenQuotientMap_iff, eq, MonoidHom.coe_prodMap, isOpenQuotientMap_prodMap_iff] + /-- The product (in the sense of `Prod.map`) of strict group homomorphisms is strict -/ @[to_additive isStrictMap_prodMap] lemma isStrictMap_prodMap (hf : IsStrictMap f) - (hg : IsStrictMap g) : IsStrictMap (f.prodMap g) := by - rw [isStrictMap_iff_isOpenQuotientMap_rangeRestrict] at hf hg ⊢ - let aux : (f.prodMap g).range ≃ₜ f.range × g.range := - (Homeomorph.setCongr (by simp [Subgroup.coe_prod])).trans (Homeomorph.Set.prod _ _) - exact aux.symm.isOpenQuotientMap.comp (hf.prodMap hg) + (hg : IsStrictMap g) : IsStrictMap (f.prodMap g) := + isStrictMap_prodMap_iff.mpr ⟨hf, hg⟩ -- TODO Add the lemma `isStrictMap_piMap` once `MonoidHom.piMap` has been defined. From 8b62164d808cd0f23b7d8cc28190a6c1a1bb483a Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:15:02 +0000 Subject: [PATCH 0325/1300] chore(CategoryTheory/Limits/Shapes/StrongEpi): use `to_dual` (#40959) This PR generates declarations about `StrongMono` from those about `StrongEpi`. --- .../Limits/Shapes/StrongEpi.lean | 114 +++++------------- 1 file changed, 31 insertions(+), 83 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean b/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean index ccb8b9800f1a6c..e10bb4da61c91f 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean @@ -45,6 +45,8 @@ namespace CategoryTheory variable {C : Type u} [Category.{v} C] variable {P Q : C} +to_dual_name_hint Epi Mono + /-- A strong epimorphism `f` is an epimorphism which has the left lifting property with respect to monomorphisms. -/ class StrongEpi (f : P ⟶ Q) : Prop where @@ -53,57 +55,41 @@ class StrongEpi (f : P ⟶ Q) : Prop where /-- The left lifting property with respect to all monomorphisms -/ llp : ∀ ⦃X Y : C⦄ (z : X ⟶ Y) [Mono z], HasLiftingProperty f z - -theorem StrongEpi.mk' {f : P ⟶ Q} [Epi f] - (hf : ∀ (X Y : C) (z : X ⟶ Y) - (_ : Mono z) (u : P ⟶ X) (v : Q ⟶ Y) (sq : CommSq u f z v), sq.HasLift) : - StrongEpi f := - { epi := inferInstance - llp := fun {X Y} z hz => ⟨fun {u v} sq => hf X Y z hz u v sq⟩ } - /-- A strong monomorphism `f` is a monomorphism which has the right lifting property with respect to epimorphisms. -/ +@[to_dual] class StrongMono (f : P ⟶ Q) : Prop where /-- The monomorphism condition on `f` -/ mono : Mono f /-- The right lifting property with respect to all epimorphisms -/ rlp : ∀ ⦃X Y : C⦄ (z : X ⟶ Y) [Epi z], HasLiftingProperty z f -theorem StrongMono.mk' {f : P ⟶ Q} [Mono f] - (hf : ∀ (X Y : C) (z : X ⟶ Y) (_ : Epi z) (u : X ⟶ P) - (v : Y ⟶ Q) (sq : CommSq u z f v), sq.HasLift) : StrongMono f where - mono := inferInstance - rlp := fun {X Y} z hz => ⟨fun {u v} sq => hf X Y z hz u v sq⟩ +attribute [to_dual existing] StrongEpi.llp StrongEpi.mk -attribute [instance 100] StrongEpi.llp - -attribute [instance 100] StrongMono.rlp - -instance (priority := 100) epi_of_strongEpi (f : P ⟶ Q) [StrongEpi f] : Epi f := - StrongEpi.epi +@[to_dual (reorder := hf (X Y, u v))] +theorem StrongEpi.mk' {f : P ⟶ Q} [Epi f] + (hf : ∀ (X Y : C) (z : X ⟶ Y) (_ : Mono z) (u : P ⟶ X) + (v : Q ⟶ Y) (sq : CommSq u f z v), sq.HasLift) : StrongEpi f where + epi := inferInstance + llp {X Y} z hz := ⟨fun {u v} sq => hf X Y z hz u v sq⟩ -instance (priority := 100) mono_of_strongMono (f : P ⟶ Q) [StrongMono f] : Mono f := - StrongMono.mono +attribute [instance 100] StrongEpi.epi StrongEpi.llp StrongMono.mono StrongMono.rlp section variable {R : C} (f : P ⟶ Q) (g : Q ⟶ R) /-- The composition of two strong epimorphisms is a strong epimorphism. -/ +@[to_dual /-- The composition of two strong monomorphisms is a strong monomorphism. -/] instance strongEpi_comp [StrongEpi f] [StrongEpi g] : StrongEpi (f ≫ g) := { epi := epi_comp _ _ llp := by intros infer_instance } -/-- The composition of two strong monomorphisms is a strong monomorphism. -/ -instance strongMono_comp [StrongMono f] [StrongMono g] : StrongMono (f ≫ g) := - { mono := mono_comp _ _ - rlp := by - intros - infer_instance } - /-- If `f ≫ g` is a strong epimorphism, then so is `g`. -/ +@[to_dual (reorder := f g) (rename := f ↔ g, P ↔ R) +/-- If `f ≫ g` is a strong monomorphism, then so is `f`. -/] theorem strongEpi_of_strongEpi [StrongEpi (f ≫ g)] : StrongEpi g := { epi := epi_of_epi f g llp := fun {X Y} z _ => by @@ -115,67 +101,36 @@ theorem strongEpi_of_strongEpi [StrongEpi (f ≫ g)] : StrongEpi g := ⟨(CommSq.mk h₀).lift, by simp only [← cancel_mono z, Category.assoc, CommSq.fac_right, sq.w], by simp⟩ } -/-- If `f ≫ g` is a strong monomorphism, then so is `f`. -/ -theorem strongMono_of_strongMono [StrongMono (f ≫ g)] : StrongMono f := - { mono := mono_of_mono f g - rlp := fun {X Y} z => by - intros - constructor - intro u v sq - have h₀ : u ≫ f ≫ g = z ≫ v ≫ g := by - rw [← Category.assoc, eq_whisker sq.w, Category.assoc] - exact CommSq.HasLift.mk' ⟨(CommSq.mk h₀).lift, by simp, by simp [← cancel_epi z, sq.w]⟩ } - /-- An isomorphism is in particular a strong epimorphism. -/ +@[to_dual /-- An isomorphism is in particular a strong monomorphism. -/] instance (priority := 100) strongEpi_of_isIso [IsIso f] : StrongEpi f where epi := by infer_instance llp {_ _} _ := HasLiftingProperty.of_left_iso _ _ -/-- An isomorphism is in particular a strong monomorphism. -/ -instance (priority := 100) strongMono_of_isIso [IsIso f] : StrongMono f where - mono := by infer_instance - rlp {_ _} _ := HasLiftingProperty.of_right_iso _ _ - set_option backward.isDefEq.respectTransparency false in +@[to_dual] theorem StrongEpi.of_arrow_iso {A B A' B' : C} {f : A ⟶ B} {g : A' ⟶ B'} - (e : Arrow.mk f ≅ Arrow.mk g) [h : StrongEpi f] : StrongEpi g := - { epi := by - rw [Arrow.iso_w' e] - infer_instance - llp := fun {X Y} z => by - intro - apply HasLiftingProperty.of_arrow_iso_left e z } - -set_option backward.isDefEq.respectTransparency false in -theorem StrongMono.of_arrow_iso {A B A' B' : C} {f : A ⟶ B} {g : A' ⟶ B'} - (e : Arrow.mk f ≅ Arrow.mk g) [h : StrongMono f] : StrongMono g := - { mono := by - rw [Arrow.iso_w' e] - infer_instance - rlp := fun {X Y} z => by - intro - apply HasLiftingProperty.of_arrow_iso_right z e } - + (e : Arrow.mk f ≅ Arrow.mk g) [h : StrongEpi f] : StrongEpi g where + epi := by + rw [Arrow.iso_w' e] + infer_instance + llp := fun {X Y} z => by + intro + apply HasLiftingProperty.of_arrow_iso_left e z + +@[to_dual] theorem StrongEpi.iff_of_arrow_iso {A B A' B' : C} {f : A ⟶ B} {g : A' ⟶ B'} (e : Arrow.mk f ≅ Arrow.mk g) : StrongEpi f ↔ StrongEpi g := by constructor <;> intro exacts [StrongEpi.of_arrow_iso e, StrongEpi.of_arrow_iso e.symm] -theorem StrongMono.iff_of_arrow_iso {A B A' B' : C} {f : A ⟶ B} {g : A' ⟶ B'} - (e : Arrow.mk f ≅ Arrow.mk g) : StrongMono f ↔ StrongMono g := by - constructor <;> intro - exacts [StrongMono.of_arrow_iso e, StrongMono.of_arrow_iso e.symm] - end /-- A strong epimorphism that is a monomorphism is an isomorphism. -/ +@[to_dual /-- A strong monomorphism that is an epimorphism is an isomorphism. -/] theorem isIso_of_mono_of_strongEpi (f : P ⟶ Q) [Mono f] [StrongEpi f] : IsIso f := ⟨⟨(CommSq.mk (show 𝟙 P ≫ f = f ≫ 𝟙 Q by simp)).lift, by simp⟩⟩ -/-- A strong monomorphism that is an epimorphism is an isomorphism. -/ -theorem isIso_of_epi_of_strongMono (f : P ⟶ Q) [Epi f] [StrongMono f] : IsIso f := - ⟨⟨(CommSq.mk (show 𝟙 P ≫ f = f ≫ 𝟙 Q by simp)).lift, by simp⟩⟩ - section variable (C) @@ -186,34 +141,27 @@ class StrongEpiCategory : Prop where strongEpi_of_epi : ∀ {X Y : C} (f : X ⟶ Y) [Epi f], StrongEpi f /-- A strong mono category is a category in which every monomorphism is strong. -/ +@[to_dual] class StrongMonoCategory : Prop where /-- A strong mono category is a category in which every monomorphism is strong. -/ strongMono_of_mono : ∀ {X Y : C} (f : X ⟶ Y) [Mono f], StrongMono f +attribute [to_dual existing] StrongEpiCategory.strongEpi_of_epi StrongEpiCategory.mk + end +@[to_dual] theorem strongEpi_of_epi [StrongEpiCategory C] (f : P ⟶ Q) [Epi f] : StrongEpi f := StrongEpiCategory.strongEpi_of_epi _ -theorem strongMono_of_mono [StrongMonoCategory C] (f : P ⟶ Q) [Mono f] : StrongMono f := - StrongMonoCategory.strongMono_of_mono _ - section attribute [local instance] strongEpi_of_epi +@[to_dual] instance (priority := 100) balanced_of_strongEpiCategory [StrongEpiCategory C] : Balanced C where isIso_of_mono_of_epi _ _ _ := isIso_of_mono_of_strongEpi _ end -section - -attribute [local instance] strongMono_of_mono - -instance (priority := 100) balanced_of_strongMonoCategory [StrongMonoCategory C] : Balanced C where - isIso_of_mono_of_epi _ _ _ := isIso_of_epi_of_strongMono _ - -end - end CategoryTheory From 9ca31d8b72cf8c317e49c301bfdbfbe91fc49136 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Wed, 24 Jun 2026 14:59:29 +0000 Subject: [PATCH 0326/1300] feat(AlgebraicGeometry): `Scheme.Hom.opensFunctor` preserves `1`-hypercovers (#40990) We deduce this from the fact that it preserves pullbacks, which we deduce from general facts about thin categories. --- Mathlib/AlgebraicGeometry/OpenImmersion.lean | 39 +++++++++++++++ Mathlib/CategoryTheory/Discrete/Basic.lean | 8 ++++ Mathlib/CategoryTheory/Limits/Preorder.lean | 15 ++++++ .../Limits/Shapes/Products.lean | 21 ++++++++ .../Shapes/Pullback/IsPullback/Basic.lean | 48 +++++++++++++++++++ Mathlib/Topology/Category/TopCat/Opens.lean | 22 +++++++++ Mathlib/Topology/Sets/Opens.lean | 8 ++++ 7 files changed, 161 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index 9a70890f5abce4..a8b61e1491ec98 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -8,6 +8,7 @@ module public import Mathlib.Geometry.RingedSpace.OpenImmersion public import Mathlib.AlgebraicGeometry.Scheme public import Mathlib.CategoryTheory.MorphismProperty.Limits +public import Mathlib.CategoryTheory.Limits.Preorder /-! # Open immersions of schemes @@ -87,6 +88,37 @@ theorem mem_opensRange {f : X ⟶ Y} [IsOpenImmersion f] {y : Y} : def opensFunctor : X.Opens ⥤ Y.Opens := LocallyRingedSpace.IsOpenImmersion.opensFunctor f.toLRSHom +/-- The adjunction image-preimage adjunction for an open immersion of schemes. -/ +def opensFunctorAdjunction : f.opensFunctor ⊣ TopologicalSpace.Opens.map f.base := + IsOpenMap.adjunction ‹IsOpenImmersion f›.base_open.isOpenMap + +instance : f.opensFunctor.IsLeftAdjoint := + f.opensFunctorAdjunction.isLeftAdjoint + +instance : f.opensFunctor.IsCocontinuous (Opens.grothendieckTopology _) + (Opens.grothendieckTopology _) := by + rw [f.opensFunctorAdjunction.isCocontinuous_iff_coverPreserving] + exact coverPreserving_opens_map f.base + +instance : f.opensFunctor.Full := + have : Mono f.base := (TopCat.mono_iff_injective f.base).mpr f.isOpenEmbedding.injective + inferInstanceAs f.isOpenEmbedding.functor.Full + +lemma coverPreserving_opensFunctor : + CoverPreserving (Opens.grothendieckTopology _) (Opens.grothendieckTopology _) f.opensFunctor := + f.isOpenEmbedding.isOpenMap.coverPreserving + +instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] : + PreservesLimitsOfShape WalkingCospan (Scheme.Hom.opensFunctor f) := by + dsimp [Scheme.Hom.opensFunctor] + infer_instance + +instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] : + f.opensFunctor.PreservesOneHypercovers (Opens.grothendieckTopology _) + (Opens.grothendieckTopology _) := by + refine Functor.PreservesOneHypercovers.of_coverPreserving ?_ + exact Scheme.Hom.coverPreserving_opensFunctor f + /-- `f ''ᵁ U` is notation for the image (as an open set) of `U` under an open immersion `f`. The preferred name in lemmas is `image` and it should be treated as an infix. -/ scoped[AlgebraicGeometry] notation3:90 f:91 " ''ᵁ " U:90 => (Scheme.Hom.opensFunctor f).obj U @@ -206,6 +238,13 @@ theorem appIso_hom' (U) : (f.appIso U).hom = f.appLE (f ''ᵁ U) U (preimage_image_eq f U).ge := f.appIso_hom U +set_option backward.defeqAttrib.useBackward true in +@[reassoc (attr := simp)] +lemma appIso_hom_naturality {U V : X.Opens} (i : op U ⟶ op V) : + dsimp% Y.presheaf.map (f.opensFunctor.op.map i) ≫ (f.appIso V).hom = + (f.appIso U).hom ≫ X.presheaf.map i := by + simp [← cancel_mono (f.appIso V).inv] + @[reassoc (attr := simp)] theorem app_appIso_inv (U) : f.app U ≫ (f.appIso (f ⁻¹ᵁ U)).inv = diff --git a/Mathlib/CategoryTheory/Discrete/Basic.lean b/Mathlib/CategoryTheory/Discrete/Basic.lean index 7d03d8068c25b7..3f7a993158e56e 100644 --- a/Mathlib/CategoryTheory/Discrete/Basic.lean +++ b/Mathlib/CategoryTheory/Discrete/Basic.lean @@ -6,6 +6,7 @@ Authors: Stephen Morgan, Kim Morrison, Floris van Doorn module public import Mathlib.CategoryTheory.Pi.Basic +public import Mathlib.Data.Set.Image /-! # Discrete categories @@ -63,6 +64,9 @@ def discreteEquiv {α : Type u₁} : Discrete α ≃ α where left_inv := by cat_disch right_inv := by cat_disch +lemma Discrete.as_bijective {α : Type*} : (Discrete.as (α := α)).Bijective := + discreteEquiv.bijective + instance {α : Type u₁} [DecidableEq α] : DecidableEq (Discrete α) := discreteEquiv.decidableEq @@ -179,6 +183,10 @@ theorem functor_obj_eq_as {I : Type u₁} (F : I → C) (X : Discrete I) : (Discrete.functor F).obj X = F X.as := rfl +@[simp] +lemma range_functor {I : Type*} (X : I → C) : Set.range (Discrete.functor X).obj = Set.range X := by + simp [Discrete.functor, Set.range_comp, Discrete.as_bijective.surjective.range_eq] + @[ext] lemma functor_ext {I : Type u₁} {G F : Discrete I ⥤ C} (h : (i : I) → G.obj ⟨i⟩ = F.obj ⟨i⟩) : G = F := by diff --git a/Mathlib/CategoryTheory/Limits/Preorder.lean b/Mathlib/CategoryTheory/Limits/Preorder.lean index 2bbcb334ca57be..a4da980b0331aa 100644 --- a/Mathlib/CategoryTheory/Limits/Preorder.lean +++ b/Mathlib/CategoryTheory/Limits/Preorder.lean @@ -6,6 +6,7 @@ Authors: Sina Hazratpour, Joël Riou, Fernando Chu module public import Mathlib.CategoryTheory.Limits.Shapes.BinaryProducts +public import Mathlib.CategoryTheory.Limits.Shapes.Products public import Mathlib.Order.Bounds.Defs /-! @@ -211,4 +212,18 @@ instance (priority := low) [SemilatticeSup C] : HasBinaryCoproducts C where end +section + +/-- The product of elements in a complete lattice is the infimum. -/ +def isLimitIInf [CompleteLattice C] {ι : Type*} (X : ι → C) : + IsLimit (Fan.mk (⨅ i, X i) fun i : ι ↦ homOfLE (iInf_le X i)) := + isLimitOfIsGLB _ _ (by simp [isGLB_iInf]) + +/-- The coproduct of elements in a complete lattice is the supremum. -/ +def isColimitISup [CompleteLattice C] {ι : Type*} (X : ι → C) : + IsColimit (Cofan.mk (⨆ i, X i) fun i : ι ↦ homOfLE (le_iSup X i)) := + isColimitOfIsLUB _ _ (by simp [isLUB_iSup]) + +end + end Preorder diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index 8d0db515c200f9..3bb17a7c11f5f5 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -967,6 +967,27 @@ instance [HasColimit F] [HasCoproduct F.obj] : Epi (Sigma.desc (colimit.ι F)) w end +section Thin + +variable [Quiver.IsThin C] {J : Type*} [Category* J] {K : J ⥤ C} + +/-- If `K : J ⥤ C` is a diagram with `C` thin, a cone for `K` is limiting +if and only if the cone point is the product of the components. -/ +def isLimitEquivFanOfIsThin (c : Cone K) : IsLimit c ≃ IsLimit (Fan.mk c.pt c.π.app) where + toFun hc := Fan.IsLimit.mk _ (fun s ↦ hc.lift { pt := s.pt, π.app j := s.proj j }) + (by subsingleton) (by subsingleton) + invFun h := { lift s := Fan.IsLimit.lift h s.π.app } + +/-- If `K : J ⥤ C` is a diagram with `C` thin, a cone for `K` is limiting +if and only if the cone point is the product of the components. -/ +def isColimitEquivCofanOfIsThin (c : Cocone K) : + IsColimit c ≃ IsColimit (Cofan.mk c.pt c.ι.app) where + toFun hc := Cofan.IsColimit.mk _ (fun s ↦ hc.desc { pt := s.pt, ι.app j := s.inj j }) + (by subsingleton) (by subsingleton) + invFun h := { desc s := Cofan.IsColimit.desc h s.ι.app } + +end Thin + section Fubini variable {ι ι' : Type*} {X : ι → ι' → C} diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean index e598b03ba20ed7..842a249e0832c2 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean @@ -943,6 +943,54 @@ lemma IsPushout.iff_app [HasPushouts D] {F₁ F₂ F₃ F₄ : C ⥤ D} end Functor +section Thin + +variable [Quiver.IsThin C] + +lemma isPullback_iff_isLimit_binaryFan_of_isThin {P X Y Z : C} + {fst : P ⟶ X} {snd : P ⟶ Y} {f : X ⟶ Z} {g : Y ⟶ Z} : + IsPullback fst snd f g ↔ Nonempty (IsLimit (BinaryFan.mk fst snd)) := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · exact ⟨BinaryFan.IsLimit.mk _ (fun u v ↦ h.lift u v (by subsingleton)) + (by subsingleton) (by subsingleton) (by subsingleton)⟩ + · exact ⟨⟨by subsingleton⟩, + ⟨PullbackCone.IsLimit.mk _ (fun s ↦ BinaryFan.IsLimit.lift h.some s.fst s.snd) + (by subsingleton) (by subsingleton) (by subsingleton)⟩⟩ + +lemma isPushout_iff_isColimit_binaryCofan_of_isThin {P X Y Z : C} + {f : Z ⟶ X} {g : Z ⟶ Y} {inl : X ⟶ P} {inr : Y ⟶ P} : + IsPushout f g inl inr ↔ Nonempty (IsColimit (BinaryCofan.mk inl inr)) := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · exact ⟨BinaryCofan.IsColimit.mk _ (fun u v ↦ h.desc u v (by subsingleton)) + (by subsingleton) (by subsingleton) (by subsingleton)⟩ + · exact ⟨⟨by subsingleton⟩, + ⟨PushoutCocone.IsColimit.mk _ (fun s ↦ BinaryCofan.IsColimit.desc h.some s.inl s.inr) + (by subsingleton) (by subsingleton) (by subsingleton)⟩⟩ + +variable {D : Type*} [Category* D] [Quiver.IsThin D] (F : C ⥤ D) + +instance (priority := low) [PreservesLimitsOfShape (Discrete WalkingPair) F] : + PreservesLimitsOfShape WalkingCospan F := by + refine preservesLimitsOfShape_walkingCospan_of_forall_isPullback fun X Y Z f g hfg ↦ ?_ + use pullback f g, pullback.fst f g, pullback.snd f g, .of_hasPullback f g + rw [isPullback_iff_isLimit_binaryFan_of_isThin] + refine ⟨(BinaryFan.mk (pullback.fst f g) (pullback.snd f g)).isLimitMapConeEquiv ?_⟩ + apply isLimitOfPreserves _ (Nonempty.some ?_) + rw [← CategoryTheory.isPullback_iff_isLimit_binaryFan_of_isThin (f := f) (g := g)] + exact .of_hasPullback f g + +instance (priority := low) [PreservesColimitsOfShape (Discrete WalkingPair) F] : + PreservesColimitsOfShape WalkingSpan F := by + refine preservesColimitsOfShape_walkingCospan_of_forall_isPushout fun X Y Z f g hfg ↦ ?_ + use pushout f g, pushout.inl f g, pushout.inr f g, .of_hasPushout f g + rw [isPushout_iff_isColimit_binaryCofan_of_isThin] + refine ⟨(BinaryCofan.mk (pushout.inl f g) (pushout.inr f g)).isColimitMapConeEquiv ?_⟩ + apply isColimitOfPreserves _ (Nonempty.some ?_) + rw [← CategoryTheory.isPushout_iff_isColimit_binaryCofan_of_isThin (f := f) (g := g)] + exact .of_hasPushout f g + +end Thin + section IsPullbackOverPullback open Limits diff --git a/Mathlib/Topology/Category/TopCat/Opens.lean b/Mathlib/Topology/Category/TopCat/Opens.lean index 24e13f01622724..96f6645978055a 100644 --- a/Mathlib/Topology/Category/TopCat/Opens.lean +++ b/Mathlib/Topology/Category/TopCat/Opens.lean @@ -7,6 +7,8 @@ module public import Mathlib.CategoryTheory.Category.GaloisConnection public import Mathlib.CategoryTheory.EqToHom +public import Mathlib.CategoryTheory.Limits.Preorder +public import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Products public import Mathlib.Topology.Category.TopCat.EpiMono public import Mathlib.Topology.Sets.Opens @@ -341,6 +343,15 @@ lemma Topology.IsOpenEmbedding.functor_obj_injective {X Y : TopCat.{u}} {f : X (hf : IsOpenEmbedding f) : Function.Injective hf.functor.obj := fun _ _ e ↦ Opens.ext (Set.image_injective.mpr hf.injective (congr_arg (↑· : Opens Y → Set Y) e)) +lemma Topology.IsOpenEmbedding.functor_obj_iInf {X Y : TopCat.{u}} (f : X ⟶ Y) + (hf : Topology.IsOpenEmbedding f) {ι : Type*} [Nonempty ι] [Finite ι] + (g : ι → TopologicalSpace.Opens X) : + hf.functor.obj (⨅ i, g i) = ⨅ i, hf.functor.obj (g i) := by + ext : 1 + simp only [IsOpenMap.coe_functor_obj, TopologicalSpace.Opens.coe_iInf] + rw [Set.InjOn.image_iInter_eq] + exact hf.injective.injOn + namespace Topology.IsInducing /-- Given an inducing map `X ⟶ Y` and some `U : Opens X`, this is the union of all open sets @@ -463,4 +474,15 @@ theorem adjunction_counit_map_functor {X : TopCat.{u}} {U : Opens X} (V : Opens eqToHom (by dsimp; rw [map_functor_eq V]) := by subsingleton +open Limits in +instance {X Y : TopCat.{u}} (f : X ⟶ Y) (hf : Topology.IsOpenEmbedding f) {ι : Type*} + [Nonempty ι] [Finite ι] : + PreservesLimitsOfShape (Discrete ι) hf.functor := by + apply +allowSynthFailures preservesLimitsOfShape_of_discrete + intro g + refine preservesLimit_of_preserves_limit_cone (Preorder.isLimitIInf g) ?_ + refine (Limits.Fan.isLimitMapConeEquiv _ _ _).symm (Preorder.isLimitOfIsGLB _ _ ?_) + simp only [Discrete.range_functor, homOfLE_leOfHom, Fan.mk_pt, hf.functor_obj_iInf] + apply isGLB_iInf + end TopologicalSpace.Opens diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index 8ceb5f00263fea..c6593fd745e47b 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -5,6 +5,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Floris van Doorn -/ module +public import Mathlib.Data.Fintype.Option public import Mathlib.Order.Hom.CompleteLattice public import Mathlib.Topology.Compactness.Bases public import Mathlib.Topology.ContinuousMap.Basic @@ -232,6 +233,13 @@ instance [Nonempty α] : Nontrivial (Opens α) where theorem coe_iSup {ι} (s : ι → Opens α) : ((⨆ i, s i : Opens α) : Set α) = ⋃ i, s i := by simp [iSup] +lemma coe_iInf {ι : Type*} [Finite ι] (U : ι → TopologicalSpace.Opens α) : + (((⨅ i, U i) : Opens α) : Set α) = ⋂ i, U i := by + induction ι using Finite.induction_empty_option with + | of_equiv e ih => rw [← e.iInf_comp, ← e.surjective.iInter_comp, ih] + | h_empty => simp + | h_option ih => rw [iInf_option, Set.iInter_option, Opens.coe_inf, ih] + theorem iSup_def {ι} (s : ι → Opens α) : ⨆ i, s i = ⟨⋃ i, s i, isOpen_iUnion fun i => (s i).2⟩ := ext <| coe_iSup s From b5f56a63146c6411ebff5ef24898ca212445dbc8 Mon Sep 17 00:00:00 2001 From: "Filippo A. E. Nuccio" <65080144+faenuccio@users.noreply.github.com> Date: Wed, 24 Jun 2026 17:13:11 +0000 Subject: [PATCH 0327/1300] feat(Mathlib.Topology.Algebra.Module.Equiv): add results on IsHomeomorph (#39476) Add the construction of a `ContinuousLinearEquiv` from a `LinearEquiv` that `IsHomeomorph`, and two basic API lemmas. Also remove a `simp` tag from a lemma in about `Function.Bijective`, and change its signature a bit. Co-authored-by: faenuccio --- Mathlib/Topology/Algebra/Module/Equiv.lean | 68 ++++++++++++++++------ 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/Mathlib/Topology/Algebra/Module/Equiv.lean b/Mathlib/Topology/Algebra/Module/Equiv.lean index afc135bda2246b..1c48c97bd88454 100644 --- a/Mathlib/Topology/Algebra/Module/Equiv.lean +++ b/Mathlib/Topology/Algebra/Module/Equiv.lean @@ -12,8 +12,26 @@ public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Restrict /-! # Continuous linear equivalences +## Notation Continuous semilinear / linear / star-linear equivalences between topological modules are denoted by `M ≃SL[σ] M₂`, `M ≃L[R] M₂` and `M ≃L⋆[R] M₂`. + +## Main Definitions +* `toHomeomorph` is the homeomorphism induced by a continuous (semi)linear equivalence. +* `symm` is the inverse of a continuous linear equivalence as a continuous linear equivalence. +* `equivOfInverse` creates a `ContinuousLinearEquiv` from two `ContinuousLinearMap`s that are + inverse of each other (as functions). See also `equivOfInverse'` when they're inverse to each + other as continuous linear maps. +* `ofUnit` is the `ContinuousLinearEquiv` corresponding to a unit in the ring of continuous + endomorphisms. See `toUnit` for the inverse direction. +* `IsInvertible`: a continuous linear map is invertible if it is the forward direction of a + continuous linear equivalence. +* `ofIsHomeomorph`: a linear equivalence that is a homeomorphism is a continuous linear equivalence. + +## Main Results +* `prodComm`: the product of topological modules is commutative up to continuous linear isomorphism. +* `LinearEquiv.isHomeomorph_iff`: A linear equivalence between topological modules is a + homeomorphism if and only if it is continuous in both directions. -/ @[expose] public section @@ -26,8 +44,6 @@ open scoped Ring universe u v w u' -section - /-- Continuous linear equivalences between modules. We only put the type classes that are necessary for the definition, although in applications `M` and `M₂` will be topological modules over the topological semiring `R`. -/ @@ -223,7 +239,6 @@ theorem isClosed_image (e : M₁ ≃SL[σ₁₂] M₂) {s : Set M₁} : IsClosed theorem map_nhds_eq (e : M₁ ≃SL[σ₁₂] M₂) (x : M₁) : map e (𝓝 x) = 𝓝 (e x) := e.toHomeomorph.map_nhds_eq x --- Make some straightforward lemmas available to `simp`. theorem map_zero (e : M₁ ≃SL[σ₁₂] M₂) : e (0 : M₁) = 0 := (e : M₁ →SL[σ₁₂] M₂).map_zero @@ -280,10 +295,6 @@ def toContinuousAddEquiv (e : M₁ ≃L[R₁] M) : M₁ ≃ₜ+ M := @[simp] lemma toContinuousAddEquiv_coe (e : M₁ ≃L[R₁] M) : ⇑e.toContinuousAddEquiv = e := rfl -end - -section - variable (R₁ M₁) /-- The identity map as a continuous linear equivalence. -/ @@ -378,7 +389,7 @@ theorem prodCongr_symm [Module R₁ M₂] [Module R₁ M₃] [Module R₁ M₄] variable (R₁ M₁ M₂) set_option backward.defeqAttrib.useBackward true in -/-- Product of modules is commutative up to continuous linear isomorphism. -/ +/-- Product of topological modules is commutative up to continuous linear isomorphism. -/ @[simps! apply toLinearEquiv] def prodComm [Module R₁ M₂] : (M₁ × M₂) ≃L[R₁] M₂ × M₁ where __ := LinearEquiv.prodComm R₁ M₁ M₂ @@ -611,7 +622,8 @@ protected theorem _root_.LinearEquiv.isUniformEmbedding {E₁ E₂ : Type*} [Uni E₁ ≃SL[σ₁₂] E₂) /-- Create a `ContinuousLinearEquiv` from two `ContinuousLinearMap`s that are -inverse of each other. See also `equivOfInverse'`. -/ +inverse of each other. See also `equivOfInverse'`. +*ToDo*: Improve the naiming to make it match `LinearMap.ofLinear`. -/ def equivOfInverse (f₁ : M₁ →SL[σ₁₂] M₂) (f₂ : M₂ →SL[σ₂₁] M₁) (h₁ : Function.LeftInverse f₂ f₁) (h₂ : Function.RightInverse f₂ f₁) : M₁ ≃SL[σ₁₂] M₂ := { f₁ with @@ -630,7 +642,8 @@ theorem symm_equivOfInverse (f₁ : M₁ →SL[σ₁₂] M₂) (f₂ h₁ h₂) rfl /-- Create a `ContinuousLinearEquiv` from two `ContinuousLinearMap`s that are -inverse of each other, in the `ContinuousLinearMap.comp` sense. See also `equivOfInverse`. -/ +inverse of each other, in the `ContinuousLinearMap.comp` sense. See also `equivOfInverse`. +*ToDo*: Improve the naiming to make it match `LinearMap.ofLinear` -/ def equivOfInverse' (f₁ : M₁ →SL[σ₁₂] M₂) (f₂ : M₂ →SL[σ₂₁] M₁) (h₁ : f₁.comp f₂ = .id R₂ M₂) (h₂ : f₂.comp f₁ = .id R₁ M₁) : M₁ ≃SL[σ₁₂] M₂ := equivOfInverse f₁ f₂ @@ -1412,15 +1425,34 @@ theorem smul_trans [SMulCommClass R S V] [IsScalarTower S R G] (α : Sˣ) (e : G theorem trans_smul [IsScalarTower S R G] (α : Sˣ) (e : G ≃L[R] V) (f : V ≃L[R] W) : e.trans (α • f) = α • (e.trans f) := by ext; simp -end ContinuousLinearEquiv +section IsHomeomorph + +variable {S₁ M M₁ : Type*} [Semiring S₁] {σ : S →+* S₁} {σ' : S₁ →+* S} + [RingHomInvPair σ σ'] [RingHomInvPair σ' σ] [TopologicalSpace M] [AddCommMonoid M] [Module S M] + [TopologicalSpace M₁] [AddCommMonoid M₁] [Module S₁ M₁] + +/-- A linear equivalence that is a homeomorphism is a continuous linear equivalence. -/ +def ofIsHomeomorph (f : M ≃ₛₗ[σ] M₁) (hf : IsHomeomorph f) : M ≃SL[σ] M₁ where + __ := f + continuous_toFun := hf.continuous + continuous_invFun := (f.isHomeomorph_iff.mp hf).2 + +theorem isHomeomorph (f : M ≃SL[σ] M₁) : IsHomeomorph f := ⟨f.continuous, isOpenMap f, f.bijective⟩ + +variable {f : M ≃ₛₗ[σ] M₁} (hf : IsHomeomorph f) + +@[simp] +lemma toLinearquiv_ofIsHomeomorph : (ofIsHomeomorph f hf).toLinearEquiv = f := by + dsimp only [ofIsHomeomorph] + +@[simp] +lemma coe_ofIsHomeomorph : (ofIsHomeomorph f hf : M → M₁) = f := by dsimp [ofIsHomeomorph] /-- A linear equivalence between topological modules is a homeomorphism if and only if it is continuous in both directions. -/ -theorem LinearEquiv.isHomeomorph_iff {R S : Type*} [Semiring R] [Semiring S] - {σ : R →+* S} {σ' : S →+* R} [RingHomInvPair σ σ'] [RingHomInvPair σ' σ] - {M : Type*} [TopologicalSpace M] [AddCommMonoid M] [Module R M] - {N : Type*} [TopologicalSpace N] [AddCommMonoid N] [Module S N] - (e : M ≃ₛₗ[σ] N) : IsHomeomorph e ↔ Continuous e ∧ Continuous e.symm := - e.toEquiv.isHomeomorph_iff +theorem _root_.LinearEquiv.isHomeomorph_iff (e : M ≃ₛₗ[σ] M₁) : + IsHomeomorph e ↔ Continuous e ∧ Continuous e.symm := e.toEquiv.isHomeomorph_iff -end +end IsHomeomorph + +end ContinuousLinearEquiv From a53f9216345ba66b3a21ec82f01c008b1bbef989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Serr=C3=A9?= <56162277+gaetanserre@users.noreply.github.com> Date: Wed, 24 Jun 2026 17:51:59 +0000 Subject: [PATCH 0328/1300] feat(CStarAlgebra): `IsometricCFC` instance for square `RCLike` matrices (#40272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following @j-loreaux advices (see [#mathlib4 > `CFC.sqrt` continuous on positive (real) matrices](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.60CFC.2Esqrt.60.20continuous.20on.20positive.20.28real.29.20matrices/with/600698185)), defines an instance of `IsometricContinuousFunctionalCalculus` for `n × n` matrices with `RCLike` coefficients. --- Mathlib/Analysis/Matrix/Order.lean | 25 +++++++++++++++++++ .../Analysis/Normed/Group/Constructions.lean | 25 +++++++++++++++++++ Mathlib/Topology/ContinuousMap/Compact.lean | 7 ++++++ Mathlib/Topology/MetricSpace/Isometry.lean | 4 +++ 4 files changed, 61 insertions(+) diff --git a/Mathlib/Analysis/Matrix/Order.lean b/Mathlib/Analysis/Matrix/Order.lean index e07208296f2cec..20eec4b66f66bc 100644 --- a/Mathlib/Analysis/Matrix/Order.lean +++ b/Mathlib/Analysis/Matrix/Order.lean @@ -12,6 +12,7 @@ public import Mathlib.Analysis.Matrix.PosDef public import Mathlib.Analysis.RCLike.Sqrt public import Mathlib.Analysis.SpecialFunctions.ContinuousFunctionalCalculus.Abs public import Mathlib.LinearAlgebra.Matrix.Vec +public import Mathlib.Analysis.CStarAlgebra.Matrix /-! # The partial order on matrices @@ -339,4 +340,28 @@ def toMatrixInnerProductSpace (M : Matrix n n 𝕜) (hM : M.PosSemidef) : @[deprecated (since := "2025-11-18")] alias PosDef.matrixNormedAddCommGroup := toMatrixNormedAddCommGroup + +open scoped Norms.L2Operator in +set_option backward.isDefEq.respectTransparency false in +/-- The isometric continuous functional calculus on `Matrix n n 𝕜` arising from the operator norm +given by the identification with (continuous) linear endomorphisms of `EuclideanSpace 𝕜 n`. -/ +instance instIsometricContinuousFunctionalCalculus [DecidableEq n] : + IsometricContinuousFunctionalCalculus ℝ (Matrix n n 𝕜) IsSelfAdjoint where + isometric A hA := by + rw [← isHermitian_iff_isSelfAdjoint] at hA + rw [IsHermitian.cfcHom_eq_cfcAux hA, AddMonoidHomClass.isometry_iff_norm] + intro f + simp only [IsHermitian.cfcAux_apply, Unitary.conjStarAlgAut_apply, ← Unitary.coe_star, + CStarRing.norm_mul_coe_unitary, CStarRing.norm_coe_unitary_mul, l2_opNorm_diagonal] + rw [((algebraMap_isometry ℝ 𝕜).postcomp_pi).norm_map_of_map_zero (by ext; simp)] + let : Fintype (spectrum ℝ A) := .ofFinite _ + rw [ContinuousMap.norm_eq_norm_coeFn] + refine Function.Surjective.pi_norm_comp ?_ _ + rw [← Function.Surjective.of_comp_iff' + (Equiv.setCongr hA.spectrum_real_eq_range_eigenvalues).bijective] + exact Set.codRestrict_range_surjective hA.eigenvalues + +scoped[Matrix.Norms.L2Operator] attribute [instance] + Matrix.instIsometricContinuousFunctionalCalculus + end Matrix diff --git a/Mathlib/Analysis/Normed/Group/Constructions.lean b/Mathlib/Analysis/Normed/Group/Constructions.lean index 6ce5fd0c8b9fd0..030fcae76666bb 100644 --- a/Mathlib/Analysis/Normed/Group/Constructions.lean +++ b/Mathlib/Analysis/Normed/Group/Constructions.lean @@ -366,6 +366,31 @@ lemma pi_norm_const' [Nonempty ι] (a : E) : ‖fun _i : ι => a‖ = ‖a‖ := lemma pi_nnnorm_const' [Nonempty ι] (a : E) : ‖fun _i : ι => a‖₊ = ‖a‖₊ := NNReal.eq <| pi_norm_const' a +@[to_additive pi_norm_comp_le] +lemma pi_norm_comp_le' [Fintype F] (g : ι → E) (f : F → ι) : ‖g ∘ f‖ ≤ ‖g‖ := by + rw [pi_norm_le_iff_of_nonneg' (by positivity)] + exact fun x ↦ norm_le_pi_norm' g (f x) + +@[to_additive IsGreatest.pi_norm] +lemma IsGreatest.pi_norm' [Nonempty ι] (f : ι → E) : IsGreatest (Set.range (‖f ·‖)) ‖f‖ := by + constructor + · rw [Pi.norm_def' f] + obtain ⟨x, -, hx⟩ := (Finset.univ (α := ι)).exists_mem_eq_sup (by simp) (‖f ·‖₊) + simp [hx] + · rintro - ⟨x, rfl⟩ + exact norm_le_pi_norm' f x + +@[to_additive Function.Surjective.pi_norm_comp] +lemma Function.Surjective.pi_norm_comp' [Fintype F] {f : ι → F} (hf : Function.Surjective f) + (g : F → E) : ‖g ∘ f‖ = ‖g‖ := by + obtain (h | h) := isEmpty_or_nonempty F + · have : IsEmpty ι := f.isEmpty + simp [Subsingleton.elim g 1] + apply le_antisymm (pi_norm_comp_le' g f) + obtain ⟨⟨x, h⟩, -⟩ := IsGreatest.pi_norm' g + obtain ⟨y, rfl⟩ := hf x + exact h ▸ norm_le_pi_norm' (g ∘ f) y + /-- The $L^1$ norm is less than the $L^\infty$ norm scaled by the cardinality. -/ @[to_additive Pi.sum_norm_apply_le_norm /-- The $L^1$ norm is less than the $L^\infty$ norm scaled by the cardinality. -/] diff --git a/Mathlib/Topology/ContinuousMap/Compact.lean b/Mathlib/Topology/ContinuousMap/Compact.lean index 221cbe425e19d7..83583586041b6c 100644 --- a/Mathlib/Topology/ContinuousMap/Compact.lean +++ b/Mathlib/Topology/ContinuousMap/Compact.lean @@ -243,6 +243,13 @@ theorem norm_restrict_mono_set {X : Type*} [TopologicalSpace X] (f : C(X, E)) {K L : TopologicalSpace.Compacts X} (hKL : K ≤ L) : ‖f.restrict K‖ ≤ ‖f.restrict L‖ := (norm_le _ (norm_nonneg _)).mpr fun x => norm_coe_le_norm (f.restrict L) <| Set.inclusion hKL x +lemma norm_eq_norm_coeFn [Fintype α] : ‖f‖ = ‖(f : α → E)‖ := by + apply le_antisymm + · rw [ContinuousMap.norm_le _ (by positivity)] + exact norm_le_pi_norm _ + · rw [pi_norm_le_iff_of_nonneg (by positivity)] + exact f.norm_coe_le_norm + end section diff --git a/Mathlib/Topology/MetricSpace/Isometry.lean b/Mathlib/Topology/MetricSpace/Isometry.lean index 0fdbb686f4ca3f..c89bf11c768a84 100644 --- a/Mathlib/Topology/MetricSpace/Isometry.lean +++ b/Mathlib/Topology/MetricSpace/Isometry.lean @@ -121,6 +121,10 @@ protected lemma inr [AddZeroClass α] [AddZeroClass β] : Isometry (AddMonoidHom theorem comp {g : β → γ} {f : α → β} (hg : Isometry g) (hf : Isometry f) : Isometry (g ∘ f) := fun _ _ => (hg _ _).trans (hf _ _) +omit [PseudoEMetricSpace α] in +lemma postcomp_pi [Fintype α] {g : β → γ} (hg : Isometry g) : Isometry (fun f : α → β ↦ g ∘ f) := + fun _ _ ↦ by simp [edist_pi_def, hg.edist_eq] + /-- An isometry from a metric space is a uniform continuous map -/ protected theorem uniformContinuous (hf : Isometry f) : UniformContinuous f := hf.lipschitz.uniformContinuous From 2929a789898c9465220a5e2361032eb9edc5c928 Mon Sep 17 00:00:00 2001 From: Salvatore Mercuri <47568553+smmercuri@users.noreply.github.com> Date: Wed, 24 Jun 2026 18:12:48 +0000 Subject: [PATCH 0329/1300] chore(Algebra): `coe_algHom` -> `coe_toAlgHom` (#38950) --- Mathlib/Algebra/Algebra/Equiv.lean | 17 ++++++++----- Mathlib/Algebra/Algebra/Spectrum/Basic.lean | 2 +- .../Algebra/Subalgebra/Centralizer.lean | 2 +- Mathlib/Algebra/Azumaya/Basic.lean | 2 +- Mathlib/Algebra/MvPolynomial/Equiv.lean | 6 ++--- Mathlib/AlgebraicGeometry/AffineSpace.lean | 2 +- .../Analysis/CStarAlgebra/GelfandDuality.lean | 2 +- Mathlib/FieldTheory/Extension.lean | 2 +- Mathlib/FieldTheory/Galois/Basic.lean | 2 +- Mathlib/FieldTheory/Isaacs.lean | 2 +- Mathlib/FieldTheory/KummerExtension.lean | 6 ++--- Mathlib/FieldTheory/LinearDisjoint.lean | 2 +- Mathlib/FieldTheory/Minpoly/Field.lean | 2 +- Mathlib/FieldTheory/SeparableDegree.lean | 2 +- Mathlib/FieldTheory/SeparablyGenerated.lean | 4 +-- Mathlib/LinearAlgebra/Charpoly/Basic.lean | 2 +- .../TensorProduct/Subalgebra.lean | 2 +- Mathlib/NumberTheory/Cyclotomic/Gal.lean | 8 +++--- .../RingTheory/Algebraic/MvPolynomial.lean | 4 +-- Mathlib/RingTheory/Bialgebra/Equiv.lean | 4 +-- Mathlib/RingTheory/Bialgebra/Hom.lean | 4 ++- .../RingTheory/DividedPowerAlgebra/Init.lean | 4 +-- .../Extension/Presentation/Basic.lean | 2 +- .../Extension/Presentation/Core.lean | 2 +- Mathlib/RingTheory/GradedAlgebra/AlgHom.lean | 25 ++++++++++++------- .../GradedAlgebra/TensorProduct.lean | 4 +-- .../RingTheory/Ideal/Quotient/Operations.lean | 2 +- .../Symmetric/FundamentalTheorem.lean | 2 +- Mathlib/RingTheory/NoetherNormalization.lean | 2 +- .../Polynomial/Cyclotomic/Factorization.lean | 4 +-- Mathlib/RingTheory/Smooth/Basic.lean | 4 +-- .../RingTheory/Smooth/IntegralClosure.lean | 6 ++--- Mathlib/RingTheory/TensorProduct/Maps.lean | 6 ++--- 33 files changed, 78 insertions(+), 64 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index 5fad57bfc7b9b8..9f592f5c7127d0 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -187,12 +187,14 @@ theorem toAlgHom_apply (x : A₁) : e.toAlgHom x = e x := rfl @[simp, norm_cast] -theorem coe_algHom : DFunLike.coe e.toAlgHom = DFunLike.coe e := - rfl +theorem coe_toAlgHom : DFunLike.coe e.toAlgHom = e := rfl -theorem coe_algHom_injective : Function.Injective ((↑) : (A₁ ≃ₐ[R] A₂) → A₁ →ₐ[R] A₂) := +theorem coe_toAlgHom_injective : Function.Injective ((↑) : (A₁ ≃ₐ[R] A₂) → A₁ →ₐ[R] A₂) := fun _ _ h => ext <| AlgHom.congr_fun h +@[deprecated (since := "2026-05-05")] alias coe_algHom := coe_toAlgHom +@[deprecated (since := "2026-05-05")] alias coe_algHom_injective := coe_toAlgHom_injective + @[simp, norm_cast] lemma toAlgHom_toRingHom : ((e : A₁ →ₐ[R] A₂) : A₁ →+* A₂) = e := rfl @@ -476,15 +478,18 @@ def ofAlgHom (f : A₁ →ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ : f.comp left_inv := AlgHom.ext_iff.1 h₂ right_inv := AlgHom.ext_iff.1 h₁ } -theorem coe_algHom_ofAlgHom (f : A₁ →ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ h₂) : +theorem toAlgHom_ofAlgHom (f : A₁ →ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ h₂) : ↑(ofAlgHom f g h₁ h₂) = f := rfl @[simp] -theorem ofAlgHom_coe_algHom (f : A₁ ≃ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ h₂) : +theorem ofAlgHom_toAlgHom (f : A₁ ≃ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ h₂) : ofAlgHom (↑f) g h₁ h₂ = f := ext fun _ => rfl +@[deprecated (since := "2026-05-05")] alias coe_algHom_ofAlgHom := toAlgHom_ofAlgHom +@[deprecated (since := "2026-05-05")] alias ofAlgHom_coe_algHom := ofAlgHom_toAlgHom + theorem ofAlgHom_symm (f : A₁ →ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ h₂) : (ofAlgHom f g h₁ h₂).symm = ofAlgHom g f h₂ h₁ := rfl @@ -761,7 +766,7 @@ def algHomUnitsEquiv (R S : Type*) [CommSemiring R] [Semiring S] [Algebra R S] : /-- See also `Finite.algHom` -/ instance _root_.Finite.algEquiv [Finite (A₁ →ₐ[R] A₂)] : Finite (A₁ ≃ₐ[R] A₂) := - Finite.of_injective _ AlgEquiv.coe_algHom_injective + Finite.of_injective _ AlgEquiv.coe_toAlgHom_injective -- TODO Morally this is just `isLocalHom_equiv`: can we obviate the need for this instance? instance : IsLocalHom e.toAlgHom := by diff --git a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean index 90ae07b320afb9..16755c4c407be2 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean @@ -431,7 +431,7 @@ theorem AlgEquiv.spectrum_eq {F R A B : Type*} [CommSemiring R] [Ring A] [Ring B [Algebra R B] [EquivLike F A B] [AlgEquivClass F R A B] (f : F) (a : A) : spectrum R (f a) = spectrum R a := Set.Subset.antisymm (AlgHom.spectrum_apply_subset _ _) <| by - simpa only [AlgEquiv.coe_algHom, AlgEquiv.coe_coe_symm_apply_coe_apply] using + simpa only [AlgEquiv.coe_toAlgHom, AlgEquiv.coe_coe_symm_apply_coe_apply] using AlgHom.spectrum_apply_subset (AlgEquivClass.toAlgEquiv f : A ≃ₐ[R] B).symm (f a) section ConjugateUnits diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean b/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean index 50fffbc6381b3c..85f0870d237eb7 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean @@ -117,7 +117,7 @@ lemma centralizer_coe_image_includeRight_eq_center_tensorProduct ⟨fun h b hb ↦ (Algebra.TensorProduct.comm R A B).symm.injective <| by aesop, fun h b hb ↦ (Algebra.TensorProduct.comm R A B).injective <| by aesop⟩ · ext x - simp only [AlgHom.mem_range, mem_comap, AlgEquiv.coe_algHom] + simp only [AlgHom.mem_range, mem_comap, AlgEquiv.coe_toAlgHom] constructor · rintro ⟨x, rfl⟩ exact ⟨(Algebra.TensorProduct.comm R _ _) x, diff --git a/Mathlib/Algebra/Azumaya/Basic.lean b/Mathlib/Algebra/Azumaya/Basic.lean index cf682e3afca522..8f5035854b7b00 100644 --- a/Mathlib/Algebra/Azumaya/Basic.lean +++ b/Mathlib/Algebra/Azumaya/Basic.lean @@ -79,7 +79,7 @@ theorem of_AlgEquiv (e : A ≃ₐ[R] B) [IsAzumaya R A] : IsAzumaya R B := let _ : Module.Finite R B := .equiv e.toLinearEquiv ⟨Function.Bijective.of_comp_iff (AlgHom.mulLeftRight R B) (Algebra.TensorProduct.congr e e.op).bijective |>.1 <| by - rw [← AlgEquiv.coe_algHom, ← AlgHom.coe_comp, mulLeftRight_comp_congr] + rw [← AlgEquiv.coe_toAlgHom, ← AlgHom.coe_comp, mulLeftRight_comp_congr] simp [AlgHom.mulLeftRight_bij]⟩ end IsAzumaya diff --git a/Mathlib/Algebra/MvPolynomial/Equiv.lean b/Mathlib/Algebra/MvPolynomial/Equiv.lean index 543505a067ec91..3a90eea82c3a26 100644 --- a/Mathlib/Algebra/MvPolynomial/Equiv.lean +++ b/Mathlib/Algebra/MvPolynomial/Equiv.lean @@ -502,7 +502,7 @@ theorem optionEquivLeft_elim_eval (s : S₁ → R) (y : R) (f : MvPolynomial (Op apply MvPolynomial.algHom_ext rw [Option.forall] simp only [aeval_X, Option.elim_none, AlgHom.coe_comp, Polynomial.coe_aeval_eq_eval, - AlgHom.coe_mk, Polynomial.coe_mapRingHom, AlgEquiv.coe_algHom, comp_apply, + AlgHom.coe_mk, Polynomial.coe_mapRingHom, AlgEquiv.coe_toAlgHom, comp_apply, optionEquivLeft_apply, Polynomial.map_X, Polynomial.eval_X, Option.elim_some, Polynomial.map_C, eval_X, Polynomial.eval_C, implies_true, and_self, φ] @@ -684,7 +684,7 @@ theorem eval_eq_eval_mv_eval' (s : Fin n → R) (y : R) (f : MvPolynomial (Fin ( apply MvPolynomial.algHom_ext rw [Fin.forall_iff_succ] simp only [aeval_X, Fin.cons_zero, AlgHom.coe_comp, Polynomial.coe_aeval_eq_eval, - AlgHom.coe_mk, Polynomial.coe_mapRingHom, AlgEquiv.coe_algHom, + AlgHom.coe_mk, Polynomial.coe_mapRingHom, AlgEquiv.coe_toAlgHom, comp_apply, finSuccEquiv_apply, eval₂Hom_X', Fin.cases_zero, Polynomial.map_X, Polynomial.eval_X, Fin.cons_succ, Fin.cases_succ, Polynomial.map_C, eval_X, Polynomial.eval_C, implies_true, and_self, φ] @@ -864,7 +864,7 @@ lemma Polynomial.toMvPolynomial_eq_rename_comp (i : σ) : lemma Polynomial.toMvPolynomial_injective (i : σ) : Function.Injective (toMvPolynomial (R := R) i) := by - simp only [toMvPolynomial_eq_rename_comp, AlgHom.coe_comp, AlgEquiv.coe_algHom, + simp only [toMvPolynomial_eq_rename_comp, AlgHom.coe_comp, AlgEquiv.coe_toAlgHom, EquivLike.injective_comp] exact MvPolynomial.rename_injective (fun x ↦ i) fun _ _ _ ↦ rfl diff --git a/Mathlib/AlgebraicGeometry/AffineSpace.lean b/Mathlib/AlgebraicGeometry/AffineSpace.lean index 2ec9cee81b52b1..c886fc0dfce1a6 100644 --- a/Mathlib/AlgebraicGeometry/AffineSpace.lean +++ b/Mathlib/AlgebraicGeometry/AffineSpace.lean @@ -457,7 +457,7 @@ lemma isIntegralHom_over_iff_isEmpty : IsIntegralHom (𝔸(n; S) ↘ S) ↔ IsEm have : (rename fun _ ↦ i).comp (uniqueAlgEquiv.{_, u} _ PUnit).symm.toAlgHom p = 0 := by simp [← hp', ← algebraMap_eq] rw [AlgHom.comp_apply, map_eq_zero_iff _ (rename_injective _ (fun _ _ _ ↦ rfl))] at this - simp only [AlgEquiv.coe_algHom, EmbeddingLike.map_eq_zero_iff] at this + simp only [AlgEquiv.coe_toAlgHom, EmbeddingLike.map_eq_zero_iff] at this simp [this] at hp · rintro (_ | _) <;> infer_instance diff --git a/Mathlib/Analysis/CStarAlgebra/GelfandDuality.lean b/Mathlib/Analysis/CStarAlgebra/GelfandDuality.lean index 8fa4b863c83f0b..68ae5a326fbd8f 100644 --- a/Mathlib/Analysis/CStarAlgebra/GelfandDuality.lean +++ b/Mathlib/Analysis/CStarAlgebra/GelfandDuality.lean @@ -91,7 +91,7 @@ noncomputable def Ideal.toCharacterSpace : characterSpace ℂ A := theorem Ideal.toCharacterSpace_apply_eq_zero_of_mem {a : A} (ha : a ∈ I) : I.toCharacterSpace a = 0 := by unfold Ideal.toCharacterSpace - simp only [CharacterSpace.equivAlgHom_symm_coe, AlgHom.coe_comp, AlgEquiv.coe_algHom, + simp only [CharacterSpace.equivAlgHom_symm_coe, AlgHom.coe_comp, AlgEquiv.coe_toAlgHom, Quotient.mkₐ_eq_mk, Function.comp_apply, NormedRing.algEquivComplexOfComplete_symm_apply] simp_rw [Quotient.eq_zero_iff_mem.mpr ha, spectrum.zero_eq] exact Set.eq_of_mem_singleton (Set.singleton_nonempty (0 : ℂ)).some_mem diff --git a/Mathlib/FieldTheory/Extension.lean b/Mathlib/FieldTheory/Extension.lean index 7221fe4410be1e..7406aef78c527b 100644 --- a/Mathlib/FieldTheory/Extension.lean +++ b/Mathlib/FieldTheory/Extension.lean @@ -59,7 +59,7 @@ noncomputable instance : OrderBot (Lifts F E K) where bot := ⟨⊥, (Algebra.ofId F K).comp (botEquiv F E)⟩ bot_le L := ⟨bot_le, fun x ↦ by obtain ⟨x, rfl⟩ := (botEquiv F E).symm.surjective x - simp_rw [AlgHom.comp_apply, AlgEquiv.coe_algHom, AlgEquiv.apply_symm_apply] + simp_rw [AlgHom.comp_apply, AlgEquiv.coe_toAlgHom, AlgEquiv.apply_symm_apply] exact L.emb.commutes x⟩ noncomputable instance : Inhabited (Lifts F E K) := diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 9a8f0a6a0aed22..494394ceaf6ee4 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -447,7 +447,7 @@ open scoped Pointwise theorem map_fixingSubgroup (σ : Gal(L/K)) : (E.map σ).fixingSubgroup = (MulAut.conj σ) • E.fixingSubgroup := by ext τ - simp only [coe_map, AlgEquiv.coe_algHom, Set.mem_image, SetLike.mem_coe, AlgEquiv.smul_def, + simp only [coe_map, AlgEquiv.coe_toAlgHom, Set.mem_image, SetLike.mem_coe, AlgEquiv.smul_def, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, Subgroup.mem_pointwise_smul_iff_inv_smul_mem, ← symm_apply_eq, IntermediateField.fixingSubgroup, mem_fixingSubgroup_iff] diff --git a/Mathlib/FieldTheory/Isaacs.lean b/Mathlib/FieldTheory/Isaacs.lean index 3f214bd9523737..e29985c0cc2fe2 100644 --- a/Mathlib/FieldTheory/Isaacs.lean +++ b/Mathlib/FieldTheory/Isaacs.lean @@ -62,7 +62,7 @@ theorem nonempty_algHom_of_exists_root (h : ∀ x : E, ∃ y : K, aeval y (minpo have ⟨ω, hω⟩ := exists_algHom_adjoin_of_splits (fun s hs ↦ ⟨(alg.isIntegral).1 _, splits s hs⟩) ϕ (adjoin_simple_le_iff.mpr hα) refine ⟨ω, β, ((DFunLike.congr_fun hω <| AdjoinSimple.gen F α).trans ?_).symm⟩ - rw [AlgHom.comp_apply, AlgHom.comp_apply, AlgEquiv.coe_algHom, + rw [AlgHom.comp_apply, AlgHom.comp_apply, AlgEquiv.coe_toAlgHom, adjoinRootEquivAdjoin_symm_apply_gen, AdjoinRoot.liftAlgHom_root] rfl have ω : ∃ ω : Ω, ⊤ ≤ M ω := by diff --git a/Mathlib/FieldTheory/KummerExtension.lean b/Mathlib/FieldTheory/KummerExtension.lean index 593f21e400895f..d20b29ba748424 100644 --- a/Mathlib/FieldTheory/KummerExtension.lean +++ b/Mathlib/FieldTheory/KummerExtension.lean @@ -269,10 +269,10 @@ def autAdjoinRootXPowSubCEquiv [NeZero n] : intro e have := Fact.mk H letI : Algebra K K[n√a] := inferInstance - apply AlgEquiv.coe_algHom_injective + apply AlgEquiv.coe_toAlgHom_injective apply AdjoinRoot.algHom_ext simp only [AdjoinRootXPowSubCEquivToRootsOfUnity, AdjoinRoot.algebraMap_eq, OneHom.toFun_eq_coe, - MonoidHom.toOneHom_coe, AlgEquiv.coe_algHom, autAdjoinRootXPowSubC_root, Algebra.smul_def] + MonoidHom.toOneHom_coe, AlgEquiv.coe_toAlgHom, autAdjoinRootXPowSubC_root, Algebra.smul_def] rw [rootsOfUnityEquivOfPrimitiveRoots_symm_apply, rootsOfUnity.val_mkOfPowEq_coe] split_ifs with h · obtain rfl := not_imp_not.mp (fun hn ↦ ne_zero_of_irreducible_X_pow_sub_C' hn H) h @@ -356,7 +356,7 @@ lemma Algebra.adjoin_root_eq_top_of_isSplittingField : (adjoinRootXPowSubCEquiv hζ H hα).symm.injective rw [Algebra.map_top, (AlgHom.range_eq_top _).mpr (adjoinRootXPowSubCEquiv hζ H hα).symm.surjective, AlgHom.map_adjoin, - Set.image_singleton, AlgEquiv.coe_algHom, adjoinRootXPowSubCEquiv_symm_eq_root, + Set.image_singleton, AlgEquiv.coe_toAlgHom, adjoinRootXPowSubCEquiv_symm_eq_root, adjoinRoot_eq_top] include hζ H hα in diff --git a/Mathlib/FieldTheory/LinearDisjoint.lean b/Mathlib/FieldTheory/LinearDisjoint.lean index a9035e67cc1299..5894be8689642f 100644 --- a/Mathlib/FieldTheory/LinearDisjoint.lean +++ b/Mathlib/FieldTheory/LinearDisjoint.lean @@ -685,7 +685,7 @@ theorem isField_of_forall (A : Type v) [Field A] (B : Type w) [Field B] (AlgEquiv.ofInjective fa fa.injective) (AlgEquiv.ofInjective fb fb.injective)) := by ext <;> simp [fa, fb] replace H : Function.Injective i := by simpa only - [hi, AlgHom.coe_comp, AlgEquiv.coe_algHom, EquivLike.injective_comp, fa, this, K, fb] + [hi, AlgHom.coe_comp, AlgEquiv.coe_toAlgHom, EquivLike.injective_comp, fa, this, K, fb] change Function.Injective (Ideal.Quotient.mk M) at H rwa [RingHom.injective_iff_ker_eq_bot, Ideal.mk_ker] at H diff --git a/Mathlib/FieldTheory/Minpoly/Field.lean b/Mathlib/FieldTheory/Minpoly/Field.lean index a530c39880c1a3..f4759385159d6a 100644 --- a/Mathlib/FieldTheory/Minpoly/Field.lean +++ b/Mathlib/FieldTheory/Minpoly/Field.lean @@ -333,7 +333,7 @@ lemma minpoly_algEquiv_toLinearMap (σ : L ≃ₐ[K] L) (hσ : IsOfFinOrder σ) simp_rw [← AlgEquiv.pow_toLinearMap] at hs apply hq.ne_zero simpa using Fintype.linearIndependent_iff.mp - (((linearIndependent_algHom_toLinearMap' K L L).comp _ AlgEquiv.coe_algHom_injective).comp _ + (((linearIndependent_algHom_toLinearMap' K L L).comp _ AlgEquiv.coe_toAlgHom_injective).comp _ (Subtype.val_injective.comp ((finEquivPowers hσ).injective))) (q.coeff ∘ (↑)) hs ⟨_, H⟩ diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index 8f092165f30c70..cd80f415c6cef7 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -159,7 +159,7 @@ def embEquivOfEquiv (i : E ≃ₐ[F] K) : intro x have h := isAlgebraic_algebraMap (R := E) (A := K) (i.symm.toAlgHom x) rw [show ∀ y : E, (algebraMap E K) y = i.toAlgHom y from fun y ↦ rfl] at h - simpa only [AlgEquiv.coe_algHom, AlgEquiv.apply_symm_apply] using h + simpa only [AlgEquiv.coe_toAlgHom, AlgEquiv.apply_symm_apply] using h apply AlgEquiv.restrictScalars (R := F) (S := E) exact IsAlgClosure.equivOfAlgebraic E K (AlgebraicClosure K) (AlgebraicClosure E) diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index 5301cf752be973..1ae054816114f6 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -61,7 +61,7 @@ theorem aeval_toPolynomialAdjoinImageCompl_eq_zero {a : ι → K} {F : MvPolynomial ι k} (hFa : F.aeval a = 0) (i : ι) : (toPolynomialAdjoinImageCompl F a i).aeval (a i) = 0 := by rw [← hFa, ← AlgHom.restrictScalars_apply k] - simp_rw [toPolynomialAdjoinImageCompl, ← AlgEquiv.coe_algHom, ← AlgHom.comp_apply] + simp_rw [toPolynomialAdjoinImageCompl, ← AlgEquiv.coe_toAlgHom, ← AlgHom.comp_apply] congr; ext; aesop (add simp optionEquivLeft_X_some) (add simp optionEquivLeft_X_none) set_option backward.isDefEq.respectTransparency false in @@ -74,7 +74,7 @@ theorem irreducible_toPolynomialAdjoinImageCompl {F : MvPolynomial ι k} (hF : I hF.map (renameEquiv k (Equiv.optionSubtypeNe i).symm) |>.map (optionEquivLeft k _) |>.map (Polynomial.mapAlgEquiv (H.aevalEquiv.trans (Subalgebra.equivOfEq _ _ congr(Algebra.adjoin k $this.symm)))) - rw [← AlgEquiv.coe_algHom] + rw [← AlgEquiv.coe_toAlgHom] congr aesop diff --git a/Mathlib/LinearAlgebra/Charpoly/Basic.lean b/Mathlib/LinearAlgebra/Charpoly/Basic.lean index e7e2ce6bd931a1..c3e7afb498ccc3 100644 --- a/Mathlib/LinearAlgebra/Charpoly/Basic.lean +++ b/Mathlib/LinearAlgebra/Charpoly/Basic.lean @@ -88,7 +88,7 @@ to the linear map itself, is zero. See `Matrix.aeval_self_charpoly` for the equivalent statement about matrices. -/ theorem aeval_self_charpoly : aeval f f.charpoly = 0 := by apply (LinearEquiv.map_eq_zero_iff (algEquivMatrix (chooseBasis R M)).toLinearEquiv).1 - rw [AlgEquiv.toLinearEquiv_apply, ← AlgEquiv.coe_algHom, ← Polynomial.aeval_algHom_apply _ _ _, + rw [AlgEquiv.toLinearEquiv_apply, ← AlgEquiv.coe_toAlgHom, ← Polynomial.aeval_algHom_apply _ _ _, charpoly_def] exact Matrix.aeval_self_charpoly _ diff --git a/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean b/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean index 7ec7f4c133f8f9..174859ad12e7f1 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean @@ -248,7 +248,7 @@ variable {A B} in theorem val_mulMap'_tmul (a : A) (b : B) : (mulMap' A B (a ⊗ₜ[R] b) : S) = a.1 * b.1 := rfl theorem mulMap'_surjective : Function.Surjective (mulMap' A B) := by - simp_rw [mulMap', AlgHom.coe_comp, AlgEquiv.coe_algHom, + simp_rw [mulMap', AlgHom.coe_comp, AlgEquiv.coe_toAlgHom, EquivLike.comp_surjective, AlgHom.rangeRestrict_surjective] end Subalgebra diff --git a/Mathlib/NumberTheory/Cyclotomic/Gal.lean b/Mathlib/NumberTheory/Cyclotomic/Gal.lean index a1953f31cffa15..fb8e0532ac4489 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Gal.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Gal.lean @@ -58,9 +58,9 @@ theorem autToPow_injective : Function.Injective <| hμ.autToPow K := by intro f g hfg have : f.toAlgHom = g.toAlgHom := by apply (hμ.powerBasis K).algHom_ext - rw [AlgEquiv.coe_algHom, AlgEquiv.coe_algHom, powerBasis_gen, + rw [AlgEquiv.coe_toAlgHom, AlgEquiv.coe_toAlgHom, powerBasis_gen, ← autToPow_spec K hμ g, ← autToPow_spec K hμ f, hfg] - exact AlgEquiv.coe_algHom_injective this + exact AlgEquiv.coe_toAlgHom_injective this end IsPrimitiveRoot @@ -89,9 +89,9 @@ noncomputable def autEquivPow (h : Irreducible (cyclotomic n K)) : Gal(L/K) ≃* exact ((zeta_spec n K L).minpoly_eq_cyclotomic_of_irreducible h).symm.trans hr) left_inv := fun f => by simp only [MonoidHom.toFun_eq_coe] - apply AlgEquiv.coe_algHom_injective + apply AlgEquiv.coe_toAlgHom_injective apply (hζ.powerBasis K).algHom_ext - simp only [AlgEquiv.coe_algHom] + simp only [AlgEquiv.coe_toAlgHom] rw [PowerBasis.equivOfMinpoly_gen] simp only [IsPrimitiveRoot.powerBasis_gen, IsPrimitiveRoot.autToPow_spec] right_inv := fun x => by diff --git a/Mathlib/RingTheory/Algebraic/MvPolynomial.lean b/Mathlib/RingTheory/Algebraic/MvPolynomial.lean index 632a314528adee..40baac310e5252 100644 --- a/Mathlib/RingTheory/Algebraic/MvPolynomial.lean +++ b/Mathlib/RingTheory/Algebraic/MvPolynomial.lean @@ -44,7 +44,7 @@ theorem transcendental_supported_polynomial_aeval_X {i : σ} {s : Set σ} (h : i (Polynomial.mapAlgEquiv (supportedEquivMvPolynomial s).symm).toAlgHom replace hf : Function.Injective u := by simp only [AlgHom.coe_comp, Subalgebra.coe_val, - AlgEquiv.coe_algHom, AlgEquiv.coe_trans, Function.comp_assoc, u] + AlgEquiv.coe_toAlgHom, AlgEquiv.coe_trans, Function.comp_assoc, u] apply Subtype.val_injective.comp simp only [EquivLike.comp_injective] apply hf.comp @@ -59,7 +59,7 @@ theorem transcendental_supported_polynomial_aeval_X {i : σ} {s : Set σ} (h : i · ext1 simp [Set.subtypeInsertEquivOption, Subalgebra.algebraMap_eq, optionEquivLeft_symm_apply] · simp [Set.subtypeInsertEquivOption, h1, optionEquivLeft_symm_apply] - simpa only [h2, v, AlgHom.coe_comp, AlgEquiv.coe_algHom, + simpa only [h2, v, AlgHom.coe_comp, AlgEquiv.coe_toAlgHom, EquivLike.injective_comp, AlgHom.coe_restrictScalars'] using hf theorem transcendental_polynomial_aeval_X (i : σ) {f : R[X]} (hf : Transcendental R f) : diff --git a/Mathlib/RingTheory/Bialgebra/Equiv.lean b/Mathlib/RingTheory/Bialgebra/Equiv.lean index 819381736fc847..877a4943aae75e 100644 --- a/Mathlib/RingTheory/Bialgebra/Equiv.lean +++ b/Mathlib/RingTheory/Bialgebra/Equiv.lean @@ -280,10 +280,10 @@ lemma apply_symm_apply (e : A ≃ₐc[R] B) : ∀ x, e (e.symm x) = x := e.toEqu lemma symm_apply_apply (e : A ≃ₐc[R] B) : ∀ x, e.symm (e x) = x := e.toEquiv.symm_apply_apply @[simp] lemma comp_symm (e : A ≃ₐc[R] B) : (e : A →ₐc[R] B).comp e.symm = .id R B := - BialgHom.coe_algHom_injective e.toAlgEquiv.comp_symm + BialgHom.coe_toAlgHom_injective e.toAlgEquiv.comp_symm @[simp] lemma symm_comp (e : A ≃ₐc[R] B) : (e.symm : B →ₐc[R] A).comp e = .id R A := - BialgHom.coe_algHom_injective e.toAlgEquiv.symm_comp + BialgHom.coe_toAlgHom_injective e.toAlgEquiv.symm_comp @[simp] lemma toRingEquiv_toRingHom (e : A ≃ₐc[R] B) : ((e : A ≃+* B) : A →+* B) = e := rfl @[simp] lemma toAlgEquiv_toRingHom (e : A ≃ₐc[R] B) : ((e : A ≃ₐ[R] B) : A →+* B) = e := rfl diff --git a/Mathlib/RingTheory/Bialgebra/Hom.lean b/Mathlib/RingTheory/Bialgebra/Hom.lean index 7598da37a0d9ea..2e23be000a224b 100644 --- a/Mathlib/RingTheory/Bialgebra/Hom.lean +++ b/Mathlib/RingTheory/Bialgebra/Hom.lean @@ -194,10 +194,12 @@ theorem coe_coalgHom_injective : Function.Injective ((↑) : (A →ₐc[R] B) fun φ₁ φ₂ H => coe_fn_injective <| show ((φ₁ : A →ₗc[R] B) : A → B) = ((φ₂ : A →ₗc[R] B) : A → B) from congr_arg _ H -theorem coe_algHom_injective : Function.Injective ((↑) : (A →ₐc[R] B) → A →ₐ[R] B) := +theorem coe_toAlgHom_injective : Function.Injective ((↑) : (A →ₐc[R] B) → A →ₐ[R] B) := fun φ₁ φ₂ H => coe_fn_injective <| show ((φ₁ : A →ₐ[R] B) : A → B) = ((φ₂ : A →ₐ[R] B) : A → B) from congr_arg _ H +@[deprecated (since := "2026-05-05")] alias coe_algHom_injective := coe_toAlgHom_injective + theorem coe_linearMap_injective : Function.Injective ((↑) : (A →ₐc[R] B) → A →ₗ[R] B) := CoalgHom.coe_linearMap_injective.comp coe_coalgHom_injective diff --git a/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean b/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean index 3549203e60bb03..c36b5a97e98dfb 100644 --- a/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean +++ b/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean @@ -495,11 +495,11 @@ theorem LinearEquiv.coe_lift_symm (g : M ≃ₗ[R] N) : (mapEquiv g).symm = map R g.symm.toLinearMap := rfl theorem mapEquiv_refl : mapEquiv (LinearEquiv.refl R M) = AlgEquiv.refl := - AlgEquiv.coe_algHom_injective map_id + AlgEquiv.coe_toAlgHom_injective map_id theorem mapEquiv_trans (g : M ≃ₗ[R] N) (h : N ≃ₗ[R] P) : (mapEquiv g).trans (mapEquiv h) = mapEquiv (g.trans h) := - AlgEquiv.coe_algHom_injective (map_comp _ _).symm + AlgEquiv.coe_toAlgHom_injective (map_comp _ _).symm end IsScalarTower diff --git a/Mathlib/RingTheory/Extension/Presentation/Basic.lean b/Mathlib/RingTheory/Extension/Presentation/Basic.lean index b501c0723b700f..075657d1a4168f 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Basic.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Basic.lean @@ -210,7 +210,7 @@ lemma _root_.Algebra.Generators.ker_localizationAway : (Ideal.Quotient.mkₐ R (Ideal.span {C r * X () - 1})) := by ext x simp only [aeval_X, Generators.localizationAway_val, AlgHom.coe_comp, - AlgEquiv.coe_algHom, Ideal.Quotient.mkₐ_eq_mk, Function.comp_apply] + AlgEquiv.coe_toAlgHom, Ideal.Quotient.mkₐ_eq_mk, Function.comp_apply] rw [IsLocalization.Away.mvPolynomialQuotientEquiv_apply, aeval_X] rw [Generators.ker_eq_ker_aeval_val, this, ← RingHom.ker_coe_toRingHom, AlgHom.comp_toRingHom, ← RingHom.comap_ker] diff --git a/Mathlib/RingTheory/Extension/Presentation/Core.lean b/Mathlib/RingTheory/Extension/Presentation/Core.lean index 9ed6f073826e2c..14d4919f4ff948 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Core.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Core.lean @@ -160,7 +160,7 @@ noncomputable def tensorModelOfHasCoeffsInv : S →ₐ[R] R ⊗[R₀] P.ModelOfH rw [← P.span_range_relation_eq_ker, Ideal.span_le] rintro a ⟨i, rfl⟩ simp only [SetLike.mem_coe, RingHom.mem_ker, AlgHom.coe_comp, - AlgEquiv.coe_algHom, Function.comp_apply, algebraTensorAlgEquiv_symm_relation] + AlgEquiv.coe_toAlgHom, Function.comp_apply, algebraTensorAlgEquiv_symm_relation] simp only [TensorProduct.map_tmul, AlgHom.coe_id, id_eq, Ideal.Quotient.mkₐ_eq_mk, Ideal.Quotient.mk_span_range, tmul_zero]).comp (P.quotientEquiv.restrictScalars R).symm.toAlgHom diff --git a/Mathlib/RingTheory/GradedAlgebra/AlgHom.lean b/Mathlib/RingTheory/GradedAlgebra/AlgHom.lean index baacd12d69fcf3..6b6c5faa288492 100644 --- a/Mathlib/RingTheory/GradedAlgebra/AlgHom.lean +++ b/Mathlib/RingTheory/GradedAlgebra/AlgHom.lean @@ -98,9 +98,11 @@ initialize_simps_projections GradedAlgHom (toFun → apply) theorem coe_mks {f : A → B} (h₁ h₂ h₃ h₄ h₅ h₆) : ⇑(⟨⟨⟨⟨⟨f, h₁⟩, h₂⟩, h₃, h₄⟩, h₅⟩, h₆⟩ : 𝒜 →ₐᵍ[R] ℬ) = f := rfl -theorem coe_algHom_mk {f : A →ₐ[R] B} (h) : ((⟨f, h⟩ : 𝒜 →ₐᵍ[R] ℬ) : A →ₐ[R] B) = f := by +theorem coe_toAlgHom_mk {f : A →ₐ[R] B} (h) : ((⟨f, h⟩ : 𝒜 →ₐᵍ[R] ℬ) : A →ₐ[R] B) = f := by dsimp only +@[deprecated (since := "2026-05-05")] alias coe_algHom_mk := coe_toAlgHom_mk + variable (f : 𝒜 →ₐᵍ[R] ℬ) theorem coe_fn_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → (A → B)) := @@ -109,23 +111,25 @@ theorem coe_fn_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) theorem coe_fn_inj {f₁ f₂ : 𝒜 →ₐᵍ[R] ℬ} : (f₁ : A → B) = f₂ ↔ f₁ = f₂ := DFunLike.coe_fn_eq -theorem coe_algHom_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → A →ₐ[R] B) := +theorem coe_toAlgHom_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → A →ₐ[R] B) := fun _ _ h ↦ coe_fn_injective congr($h) +@[deprecated (since := "2026-05-05")] alias coe_algHom_injective := coe_toAlgHom_injective + theorem toGradedRingHom_injective : Function.Injective (toGradedRingHom (𝒜 := 𝒜) (ℬ := ℬ)) := fun _ _ h ↦ coe_fn_injective congr($h) theorem coe_linearMap_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → A →ₗ[R] B) := - AlgHom.toLinearMap_injective.comp coe_algHom_injective + AlgHom.toLinearMap_injective.comp coe_toAlgHom_injective theorem coe_ringHom_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → A →+* B) := - AlgHom.coe_ringHom_injective.comp coe_algHom_injective + AlgHom.coe_ringHom_injective.comp coe_toAlgHom_injective theorem coe_monoidHom_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → A →* B) := - AlgHom.coe_monoidHom_injective.comp coe_algHom_injective + AlgHom.coe_monoidHom_injective.comp coe_toAlgHom_injective theorem coe_addMonoidHom_injective : Function.Injective ((↑) : (𝒜 →ₐᵍ[R] ℬ) → A →+ B) := - AlgHom.coe_addMonoidHom_injective.comp coe_algHom_injective + AlgHom.coe_addMonoidHom_injective.comp coe_toAlgHom_injective /-- Consider using `congr($H x)` instead. -/ protected theorem congr_fun {f₁ f₂ : 𝒜 →ₐᵍ[R] ℬ} (H : f₁ = f₂) (x : A) : f₁ x = f₂ x := @@ -215,11 +219,11 @@ instance : Monoid (𝒜 →ₐᵍ[R] 𝒜) where lemma cancel_right {g₁ g₂ : ℬ →ₐᵍ[R] 𝒞} {f : 𝒜 →ₐᵍ[R] ℬ} (hf : Function.Surjective f) : g₁.comp f = g₂.comp f ↔ g₁ = g₂ := - ⟨fun h ↦ coe_algHom_injective <| (AlgHom.cancel_right hf).1 congr($h), fun h ↦ h ▸ rfl⟩ + ⟨fun h ↦ coe_toAlgHom_injective <| (AlgHom.cancel_right hf).1 congr($h), fun h ↦ h ▸ rfl⟩ lemma cancel_left {g₁ g₂ : 𝒜 →ₐᵍ[R] ℬ} {f : ℬ →ₐᵍ[R] 𝒞} (hf : Function.Injective f) : f.comp g₁ = f.comp g₂ ↔ g₁ = g₂ := - ⟨fun h ↦ coe_algHom_injective <| (AlgHom.cancel_left hf).1 congr($h), fun h ↦ h ▸ rfl⟩ + ⟨fun h ↦ coe_toAlgHom_injective <| (AlgHom.cancel_left hf).1 congr($h), fun h ↦ h ▸ rfl⟩ /-- We enrich the existing function `toAlgHom` with the structure of a `MonoidHom`, to produce a bundled function that we now call `toEnd`. -/ @@ -256,9 +260,12 @@ variable (R₀ : Type*) [CommSemiring R₀] [Algebra R₀ R] @[simp] lemma coe_restrictScalars : ⇑(f.restrictScalars R₀) = f := rfl -@[simp] lemma restrictScalars_coe_algHom : +@[simp] lemma restrictScalars_toAlgHom : (f : A →ₐ[R] B).restrictScalars R₀ = f.restrictScalars R₀ := rfl +@[deprecated (since := "2026-05-05")] +alias restrictScalars_coe_algHom := restrictScalars_toAlgHom + @[simp] lemma restrictScalars_coe_linearMap : (f : A →ₗ[R] B).restrictScalars R₀ = f.restrictScalars R₀ := rfl diff --git a/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean b/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean index 46e82e06a69fe6..5a6b85e0106a28 100644 --- a/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean +++ b/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean @@ -128,8 +128,8 @@ def liftEquiv : (𝒜 →ₐᵍ[R] (ℬ · |>.restrictScalars R)) ≃ ((𝒜 · invFun f := { AlgHom.liftEquiv R S A B |>.symm f with map_mem hx := f.map_mem <| tmul_mem_baseChange_of_mem _ hx } - left_inv f := coe_algHom_injective <| by simp - right_inv f := coe_algHom_injective <| by simp + left_inv f := coe_toAlgHom_injective <| by simp + right_inv f := coe_toAlgHom_injective <| by simp variable {𝒜 ℬ} diff --git a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean index 996128bf8ca4ef..49867700683d63 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean @@ -566,7 +566,7 @@ lemma _root_.AlgHom.liftOfSurjective_apply (f : A →ₐ[R] B) (hf : Function.Su (g : A →ₐ[R] C) (H : RingHom.ker f.toRingHom ≤ RingHom.ker g.toRingHom) (x) : AlgHom.liftOfSurjective f hf g H (f x) = g x := by dsimp [AlgHom.liftOfSurjective] - erw [AlgEquiv.coe_algHom] -- fixed after #21031 + erw [AlgEquiv.coe_toAlgHom] -- fixed after #21031 rw [Ideal.quotientKerAlgEquivOfSurjective_symm_apply] rfl diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean index a20511d3dcb445..512daafeff3a99 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean @@ -142,7 +142,7 @@ lemma esymmAlgHom_apply (p : MvPolynomial (Fin n) R) : lemma rename_esymmAlgHom (e : σ ≃ τ) : (renameSymmetricSubalgebra e).toAlgHom.comp (esymmAlgHom σ R n) = esymmAlgHom τ R n := by ext i : 2 - simp_rw [AlgHom.comp_apply, esymmAlgHom, aeval_X, AlgEquiv.coe_algHom, + simp_rw [AlgHom.comp_apply, esymmAlgHom, aeval_X, AlgEquiv.coe_toAlgHom, renameSymmetricSubalgebra_apply_coe, rename_esymm] variable (σ) in diff --git a/Mathlib/RingTheory/NoetherNormalization.lean b/Mathlib/RingTheory/NoetherNormalization.lean index 2e99d7ec0ca2a8..c3ffd0befae1f6 100644 --- a/Mathlib/RingTheory/NoetherNormalization.lean +++ b/Mathlib/RingTheory/NoetherNormalization.lean @@ -278,7 +278,7 @@ theorem exists_integral_inj_algHom_of_fg : ∃ s, ∃ g : (MvPolynomial (Fin s) set ϕ := quotientKerAlgEquivOfSurjective fsurj obtain ⟨s, _, g, injg, intg⟩ := exists_integral_inj_algHom_of_quotient (ker f) (ker_ne_top _) use s, ϕ.toAlgHom.comp g - simp only [AlgHom.coe_comp, AlgEquiv.coe_algHom, EmbeddingLike.comp_injective, + simp only [AlgHom.coe_comp, AlgEquiv.coe_toAlgHom, EmbeddingLike.comp_injective, AlgHom.toRingHom_eq_coe] exact ⟨injg, intg.trans _ _ (isIntegral_of_surjective _ ϕ.surjective)⟩ diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean index cb48fd6da6f6c2..2d1410358a3ebb 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean @@ -64,9 +64,9 @@ private theorem natDegree_of_dvd_cyclotomic_of_irreducible_of_monic (hP : P ∣ ⟨n, pos_of_ne_zero (fun h0 ↦ by simp [h0, hp.out.ne_one] at hn), hζ.pow_eq_one⟩ refine dvd_antisymm - (orderOf_dvd_iff_pow_eq_one.mpr <| AlgEquiv.coe_algHom_injective <| pB.algHom_ext ?_) + (orderOf_dvd_iff_pow_eq_one.mpr <| AlgEquiv.coe_toAlgHom_injective <| pB.algHom_ext ?_) (orderOf_dvd_iff_pow_eq_one.mpr <| Units.ext ?_) - · simp only [AlgEquiv.coe_algHom, AlgEquiv.coe_pow, AlgEquiv.one_apply, + · simp only [AlgEquiv.coe_toAlgHom, AlgEquiv.coe_pow, AlgEquiv.one_apply, coe_frobeniusAlgEquivOfAlgebraic, pow_iterate, hK] nth_rewrite 2 [← pow_one pB.gen] rw [powerBasis_gen hPirr.ne_zero, hζ'.pow_eq_pow_iff_modEq, ← hζ.eq_orderOf, diff --git a/Mathlib/RingTheory/Smooth/Basic.lean b/Mathlib/RingTheory/Smooth/Basic.lean index 1ba66377ae655e..54640dfe993ab0 100644 --- a/Mathlib/RingTheory/Smooth/Basic.lean +++ b/Mathlib/RingTheory/Smooth/Basic.lean @@ -177,7 +177,7 @@ theorem liftOfSurjective_apply [FormallySmooth R A] (f : A →ₐ[R] C) (g : B (hg : Function.Surjective g) (hg' : IsNilpotent <| RingHom.ker g) (x : A) : g (FormallySmooth.liftOfSurjective f g hg hg' x) = f x := by apply (Ideal.quotientKerAlgEquivOfSurjective hg).symm.injective - conv_rhs => rw [← AlgEquiv.coe_algHom, ← AlgHom.comp_apply, + conv_rhs => rw [← AlgEquiv.coe_toAlgHom, ← AlgHom.comp_apply, ← FormallySmooth.mk_lift (A := A) _ hg'] apply (Ideal.quotientKerAlgEquivOfSurjective hg).injective rw [AlgEquiv.apply_symm_apply, Ideal.quotientKerAlgEquivOfSurjective_apply] @@ -361,7 +361,7 @@ theorem of_comp_surjective refine ⟨g, AlgHom.ext fun x ↦ congr(f.kerSquareLift.kerLift ($hg x)).trans ?_⟩ obtain ⟨x, rfl⟩ := (Ideal.quotientKerAlgEquivOfSurjective surj).surjective x obtain ⟨x, rfl⟩ := Ideal.Quotient.mk_surjective x - simp only [AlgHom.toRingHom_eq_coe, AlgEquiv.coe_algHom, AlgEquiv.symm_apply_apply, + simp only [AlgHom.toRingHom_eq_coe, AlgEquiv.coe_toAlgHom, AlgEquiv.symm_apply_apply, AlgHom.coe_id, id_eq] simp only [Ideal.quotientKerAlgEquivOfSurjective_apply] diff --git a/Mathlib/RingTheory/Smooth/IntegralClosure.lean b/Mathlib/RingTheory/Smooth/IntegralClosure.lean index a412ca4415d48f..614a4369212324 100644 --- a/Mathlib/RingTheory/Smooth/IntegralClosure.lean +++ b/Mathlib/RingTheory/Smooth/IntegralClosure.lean @@ -66,7 +66,7 @@ lemma TensorProduct.toIntegralClosure_bijective_of_tower (AlgEquiv.ofBijective _ H').trans <| (AlgEquiv.mapIntegralClosure (Algebra.TensorProduct.cancelBaseChange ..)) convert! e.bijective - rw [← e.coe_algHom] + rw [← e.coe_toAlgHom] congr 1 ext; simp [e, toIntegralClosure] @@ -175,7 +175,7 @@ lemma TensorProduct.toIntegralClosure_bijective_of_isLocalization convert! (IsLocalization.algEquiv (Algebra.algebraMapSubmonoid (integralClosure R B) M) (S ⊗[R] integralClosure R B) (integralClosure S (S ⊗[R] B))).bijective - rw [← AlgHom.coe_restrictScalars' R, ← AlgEquiv.coe_restrictScalars' R, ← AlgEquiv.coe_algHom] + rw [← AlgHom.coe_restrictScalars' R, ← AlgEquiv.coe_restrictScalars' R, ← AlgEquiv.coe_toAlgHom] congr 1 ext1 · apply IsLocalization.algHom_ext M; ext @@ -354,7 +354,7 @@ theorem mem_adjoin_map_integralClosure_of_isStandardEtale [Algebra.IsStandardEta AlgEquiv.apply_symm_apply, map_pow, heg] simp_rw [mul_assoc, ← map_pow, show 𝓟.g.map (algebraMap R B) = 𝓟'.g from rfl, IsLocalization.mk'_spec'_mk, ← derivative_map]; rfl - · simp only [← AlgEquiv.coe_algHom, ← AlgHom.coe_toRingHom, ← RingHom.comp_apply, + · simp only [← AlgEquiv.coe_toAlgHom, ← AlgHom.coe_toRingHom, ← RingHom.comp_apply, ← coe_eval₂RingHom] congr 1 ext <;> simp [e, StandardEtalePair.equivAwayAdjoinRoot]; rfl diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index 36f0c51b51f6f2..0e7c4b8e3b4116 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -583,12 +583,12 @@ theorem congr_symm_apply (f : A ≃ₐ[S] C) (g : B ≃ₐ[R] D) (x) : @[simp] theorem congr_refl : congr (.refl : A ≃ₐ[S] A) (.refl : B ≃ₐ[R] B) = .refl := - AlgEquiv.coe_algHom_injective <| map_id + AlgEquiv.coe_toAlgHom_injective <| map_id theorem congr_trans (f₁ : A ≃ₐ[S] C) (f₂ : C ≃ₐ[S] E) (g₁ : B ≃ₐ[R] D) (g₂ : D ≃ₐ[R] F) : congr (f₁.trans f₂) (g₁.trans g₂) = (congr f₁ g₁).trans (congr f₂ g₂) := - AlgEquiv.coe_algHom_injective <| map_comp f₂.toAlgHom f₁.toAlgHom g₂.toAlgHom g₁.toAlgHom + AlgEquiv.coe_toAlgHom_injective <| map_comp f₂.toAlgHom f₁.toAlgHom g₂.toAlgHom g₁.toAlgHom theorem congr_symm (f : A ≃ₐ[S] C) (g : B ≃ₐ[R] D) : congr f.symm g.symm = (congr f g).symm := rfl @@ -746,7 +746,7 @@ def lmulEquiv [CompatibleSMul R S S S] : S ⊗[R] S ≃ₐ[S] S := theorem lmulEquiv_eq_lidOfCompatibleSMul [CompatibleSMul R S S S] : lmulEquiv R S = lidOfCompatibleSMul R S S := - AlgEquiv.coe_algHom_injective <| by ext; rfl + AlgEquiv.coe_toAlgHom_injective <| by ext; rfl /-- If `S` is commutative, for a pair of morphisms `f : A →ₐ[R] S`, `g : B →ₐ[R] S`, We obtain a map `A ⊗[R] B →ₐ[R] S` that commutes with `f`, `g` via `a ⊗ b ↦ f(a) * g(b)`. From d8f28212f72cc6595762261e85c0ba70a792c794 Mon Sep 17 00:00:00 2001 From: Chris Henson <46805207+chenson2018@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:59:37 +0000 Subject: [PATCH 0330/1300] feat: well founded relations on a nonempty type are not left/right total (#41006) Discussed in [this thread](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/finite.2C.20nonempty.20strict.20order.20is.20not.20left.2Fright.20total/with/606017061). I use `Function.swap` for the dual (as opposed to `flip`) because having this be reducible is nice. --- Mathlib/Order/WellFounded.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/Order/WellFounded.lean b/Mathlib/Order/WellFounded.lean index aa94d70693c099..b3bae400954623 100644 --- a/Mathlib/Order/WellFounded.lean +++ b/Mathlib/Order/WellFounded.lean @@ -95,6 +95,21 @@ theorem has_min {α} {r : α → α → Prop} (H : WellFounded r) (s : Set α) : not_imp_not.1 fun hne hx => hne <| ⟨x, hx, fun y hy hyx => hne <| IH y hyx hy⟩) ha +theorem not_rightTotal (wf : WellFounded r) [Nonempty α] : ¬ Relator.RightTotal r := by + intro h + obtain ⟨a, -, ha⟩ := wf.has_min Set.univ Set.univ_nonempty + obtain ⟨b, hba⟩ := h a + specialize ha b (Set.mem_univ b) + contradiction + +theorem not_leftTotal (wf : WellFounded (Function.swap r)) [Nonempty α] : + ¬ Relator.LeftTotal r := by + intro h + obtain ⟨a, -, ha⟩ := wf.has_min Set.univ Set.univ_nonempty + obtain ⟨b, hab⟩ := h a + specialize ha b (Set.mem_univ b) + contradiction + /-- A minimal element of a nonempty set in a well-founded order. If you're working with a nonempty linear order, consider defining a From ee89f2d4639074a91449870b8f7a0d0e401faba8 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 24 Jun 2026 22:06:35 +0000 Subject: [PATCH 0331/1300] chore: remove redundant exceptions of `linter.style.emptyline` (#41004) Co-authored-by: Batixx --- Mathlib/Analysis/Polynomial/MahlerMeasure.lean | 1 - Mathlib/Geometry/Manifold/Notation.lean | 2 -- 2 files changed, 3 deletions(-) diff --git a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean index f3abb35d18507e..71d466e6a1089c 100644 --- a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean +++ b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean @@ -293,7 +293,6 @@ theorem mahlerMeasure_le_sum_norm_coeff (p : ℂ[X]) : p.mahlerMeasure ≤ p.sum apply norm_sum_le_of_le p.support simp -set_option linter.style.emptyLine false in open MeasureTheory Set in /-- **Landau's inequality**: the Mahler measure of a polynomial is at most the ℓ² norm of its coefficient vector, `√(∑ ‖coeff i‖²)`. diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 4165465c5cf227..3c34b70a359791 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -354,7 +354,6 @@ where findFromLocalInstance (e : Expr) : TermElabM <| Option Expr := do else return none | _ => pure none -set_option linter.style.emptyLine false in -- linter false positive /-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), using the local context to infer the appropriate instance. This supports the following cases: - the model with corners on the total space of a vector bundle @@ -730,7 +729,6 @@ where let iTerm : Term ← ``(𝓘($eT, $eT)) Term.elabTerm iTerm none -set_option linter.style.emptyLine false in -- linter false positive /-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), using the local context to infer the appropriate instance. This supports all `ModelWithCorners` instances that are currently defined in mathlib. From 2da222063cdf16dd6df95e950e5bc8ed7d4be7ae Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Thu, 25 Jun 2026 05:38:43 +0000 Subject: [PATCH 0332/1300] chore(AlgebraicGeometry/AffineScheme): golf using `simp` (#40991) As recommended in the style guide. Extracted from https://github.com/leanprover-community/mathlib4/pull/40793. --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 49 +++++---------------- Mathlib/AlgebraicGeometry/Restrict.lean | 6 +++ 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 9a1138dac3fd1c..fb0f92073d1e68 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -964,47 +964,20 @@ set_option backward.isDefEq.respectTransparency false in open _root_.PrimeSpectrum in /-- The restriction of `Spec.map f` to a basic open `D(r)` is isomorphic to `Spec.map` of the localization of `f` away from `r`. -/ -noncomputable -def SpecMapRestrictBasicOpenIso {R S : CommRingCat} (f : R ⟶ S) (r : R) : +noncomputable def SpecMapRestrictBasicOpenIso {R S : CommRingCat} (f : R ⟶ S) (r : R) : Arrow.mk (Spec.map f ∣_ (PrimeSpectrum.basicOpen r)) ≅ Arrow.mk (Spec.map <| CommRingCat.ofHom (Localization.awayMap f.hom r)) := by - letI e₁ : Localization.Away r ≃ₐ[R] Γ(Spec R, basicOpen r) := - IsLocalization.algEquiv (Submonoid.powers r) _ _ - letI e₂ : Localization.Away (f.hom r) ≃ₐ[S] Γ(Spec S, basicOpen (f.hom r)) := - IsLocalization.algEquiv (Submonoid.powers (f.hom r)) _ _ refine Arrow.isoMk ?_ ?_ ?_ - · exact (Spec _).isoOfEq (comap_basicOpen _ _) ≪≫ - (IsAffineOpen.Spec_basicOpen (f.hom r)).isoSpec ≪≫ Scheme.Spec.mapIso e₂.toCommRingCatIso.op - · exact (IsAffineOpen.Spec_basicOpen r).isoSpec ≪≫ Scheme.Spec.mapIso e₁.toCommRingCatIso.op - · have := AlgebraicGeometry.IsOpenImmersion.of_isLocalization - (S := (Localization.Away r)) r - rw [← cancel_mono (Spec.map (CommRingCat.ofHom (algebraMap R (Localization.Away r))))] - simp only [Arrow.mk_left, Arrow.mk_right, Scheme.isoOfEq_rfl, Iso.refl_trans, - Iso.trans_hom, Functor.mapIso_hom, Iso.op_hom, Scheme.Spec_map, Quiver.Hom.unop_op, - Arrow.mk_hom, Category.assoc, ← Spec.map_comp] - conv => - congr - · enter [2, 1]; tactic => - change _ = - (f ≫ (Scheme.ΓSpecIso S).inv ≫ (Spec S).presheaf.map (homOfLE le_top).op) - ext - simp only [Localization.awayMap, IsLocalization.Away.map, - RingEquiv.toCommRingCatIso_hom, AlgEquiv.toRingEquiv_toRingHom, CommRingCat.hom_comp, - CommRingCat.hom_ofHom, RingHom.comp_apply, IsLocalization.map_eq, RingHom.coe_coe, - AlgEquiv.commutes, IsAffineOpen.algebraMap_Spec_obj] - · enter [2, 2, 1]; tactic => - change _ = (Scheme.ΓSpecIso R).inv ≫ (Spec R).presheaf.map (homOfLE le_top).op - ext - simp only [RingEquiv.toCommRingCatIso_hom, - AlgEquiv.toRingEquiv_toRingHom, CommRingCat.hom_comp, CommRingCat.hom_ofHom, - RingHom.coe_comp, RingHom.coe_coe, Function.comp_apply, AlgEquiv.commutes, - IsAffineOpen.algebraMap_Spec_obj, homOfLE_leOfHom] - simp only [IsAffineOpen.isoSpec_hom, homOfLE_leOfHom, Spec.map_comp, Category.assoc, - Scheme.Opens.toSpecΓ_SpecMap_presheaf_map_assoc, Scheme.Opens.toSpecΓ_top, - Scheme.homOfLE_ι_assoc, morphismRestrict_ι_assoc] - simp only [← SpecMap_ΓSpecIso_hom, ← Spec.map_comp, Category.assoc, Iso.inv_hom_id, - Category.comp_id, Category.id_comp] - rfl + · exact (Spec _).isoOfEq (comap_basicOpen _ _) ≪≫ basicOpenIsoSpecAway (f.hom r) + · exact basicOpenIsoSpecAway r + · have hcomp : CommRingCat.ofHom (algebraMap R (Localization.Away r)) ≫ + CommRingCat.ofHom (Localization.awayMap f.hom r) = + f ≫ CommRingCat.ofHom (algebraMap S (Localization.Away (f.hom r))) := by + ext x + simp [Localization.awayMap, IsLocalization.Away.map] + rw [← cancel_mono (Spec.map (CommRingCat.ofHom (algebraMap R _)))] + simp only [Arrow.mk_hom, Category.assoc, ← Spec.map_comp] + simp [hcomp] lemma stalkMap_injective_of_isAffine {X Y : Scheme} (f : X ⟶ Y) [IsAffine Y] (x : X) (h : ∀ g, f.stalkMap x (Y.presheaf.Γgerm (f x) g) = 0 → Y.presheaf.Γgerm (f x) g = 0) : diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index 2ac6b65fe87143..bb23bc5250d9e7 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -517,6 +517,12 @@ def basicOpenIsoSpecAway {R : CommRingCat.{u}} (f : R) : simp only [Scheme.Opens.range_ι] exact (PrimeSpectrum.localization_away_comap_range _ _).symm) +@[reassoc (attr := simp)] +lemma basicOpenIsoSpecAway_hom_SpecMap {R : CommRingCat.{u}} (f : R) : + (basicOpenIsoSpecAway f).hom ≫ Spec.map (CommRingCat.ofHom (algebraMap R _)) = + Scheme.Opens.ι (X := Spec R) (PrimeSpectrum.basicOpen f) := by + simp [basicOpenIsoSpecAway] + set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma basicOpenIsoSpecAway_inv_homOfLE {R : CommRingCat.{u}} (f g x : R) (hx : x = f * g) : From f8fd74f95c7a5f33eac4cbd4312a28a7492bda36 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Thu, 25 Jun 2026 07:54:34 +0000 Subject: [PATCH 0333/1300] chore: remove unused instances (#41013) Removes unused instances in theorems found by fixing the unused arguments linter to handle theorems in leanprover-community/batteries#1879. --- Mathlib/Algebra/Module/Submodule/Map.lean | 4 ++-- .../Algebra/Module/Submodule/RestrictScalars.lean | 2 +- Mathlib/Algebra/Module/Torsion/Basic.lean | 2 +- Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean | 3 ++- Mathlib/Algebra/SkewPolynomial/Basic.lean | 6 ++---- Mathlib/AlgebraicGeometry/Morphisms/Finite.lean | 3 +-- Mathlib/Analysis/LocallyConvex/HahnBanach.lean | 4 ++-- Mathlib/Analysis/Normed/Operator/NormedSpace.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 2 +- .../LiftingProperties/PushoutProduct.lean | 8 ++++---- Mathlib/FieldTheory/Galois/Basic.lean | 2 +- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 2 +- Mathlib/Geometry/Manifold/Algebra/SMul.lean | 3 +-- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 2 +- .../LinearAlgebra/AffineSpace/Simplex/Basic.lean | 8 ++++---- .../Constructions/BorelSpace/Metrizable.lean | 2 +- Mathlib/ModelTheory/Satisfiability.lean | 2 +- .../NumberField/Discriminant/Different.lean | 2 +- Mathlib/Probability/HasCondDistrib.lean | 2 +- Mathlib/Probability/Independence/Basic.lean | 2 +- Mathlib/Probability/Independence/Integration.lean | 14 +++++++------- .../Probability/Independence/Kernel/IndepFun.lean | 2 +- Mathlib/Probability/Martingale/Centering.lean | 7 +++---- Mathlib/RingTheory/Ideal/Operations.lean | 2 +- Mathlib/RingTheory/IsGaloisGroup/Basic.lean | 2 +- Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean | 2 +- Mathlib/RingTheory/RamificationInertia/Basic.lean | 2 +- Mathlib/RingTheory/TwoSidedIdeal/BigOperators.lean | 6 ++---- Mathlib/Topology/Algebra/Module/Complement.lean | 2 +- Mathlib/Topology/Algebra/Order/Floor.lean | 2 +- Mathlib/Topology/Order/Completion.lean | 3 +-- Mathlib/Topology/Order/ScottTopology.lean | 3 +-- .../Topology/UniformSpace/ProdApproximation.lean | 5 ++--- 33 files changed, 53 insertions(+), 62 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index c41af3f34468ea..494d9e4cd303f1 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -697,8 +697,8 @@ theorem map_restrict [RingHomSurjective σ₂₁] {p : Submodule R₂ M₂} {q : map (f.restrict h) p' = comap q.subtype (map f (map p.subtype p')) := by rw [restrict_eq_codRestrict_domRestrict, map_codRestrict, map_domRestrict] -theorem comap_restrict [RingHomSurjective σ₂₁] {p : Submodule R₂ M₂} {q : Submodule R M} - {f : M₂ →ₛₗ[σ₂₁] M} (h : ∀ x ∈ p, f x ∈ q) (p') : +theorem comap_restrict {p : Submodule R₂ M₂} {q : Submodule R M} {f : M₂ →ₛₗ[σ₂₁] M} + (h : ∀ x ∈ p, f x ∈ q) (p') : comap (f.restrict h) p' = comap p.subtype (comap f (map q.subtype p')) := by rw [restrict_eq_codRestrict_domRestrict, comap_codRestrict, comap_domRestrict] diff --git a/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean b/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean index 26aca7cdc39ede..a1d249200d4eee 100644 --- a/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean +++ b/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean @@ -56,7 +56,7 @@ theorem restrictScalars_self (V : Submodule R M) : V.restrictScalars R = V := SetLike.coe_injective rfl @[simp] theorem restrictScalars_restrictScalars - (T : Type*) [Semiring T] [SMul T R] [SMul S T] [IsScalarTower S T R] + (T : Type*) [Semiring T] [SMul T R] [SMul S T] [Module T M] [IsScalarTower S T M] [IsScalarTower T R M] (V : Submodule R M) : (V.restrictScalars T).restrictScalars S = V.restrictScalars S := diff --git a/Mathlib/Algebra/Module/Torsion/Basic.lean b/Mathlib/Algebra/Module/Torsion/Basic.lean index 73f3ab0e224fe2..6719c23989257c 100644 --- a/Mathlib/Algebra/Module/Torsion/Basic.lean +++ b/Mathlib/Algebra/Module/Torsion/Basic.lean @@ -577,7 +577,7 @@ theorem IsTorsionBy.mk_smul [(Ideal.span {r}).IsTwoSided] (hM : IsTorsionBy R M def IsTorsionBySet.module [I.IsTwoSided] (hM : IsTorsionBySet R M I) : Module (R ⧸ I) M := letI := hM.hasSMul; fast_instance% I.mkQ_surjective.moduleLeft _ (IsTorsionBySet.mk_smul hM) -instance IsTorsionBySet.isScalarTower [I.IsTwoSided] (hM : IsTorsionBySet R M I) +instance IsTorsionBySet.isScalarTower (hM : IsTorsionBySet R M I) {S : Type*} [SMul S R] [SMul S M] [IsScalarTower S R M] [IsScalarTower S R R] : @IsScalarTower S (R ⧸ I) M _ hM.hasSMul _ := -- Porting note: still needed to be fed the Module R / I M instance diff --git a/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean b/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean index 92d41588b31803..6de7d61e93f446 100644 --- a/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean +++ b/Mathlib/Algebra/Order/Ring/IsNonarchimedean.lean @@ -118,7 +118,7 @@ theorem add_eq_max_of_ne {F α : Type*} [AddGroup α] [FunLike F α R] /- TODO: Remove the funlike conditions on the lemmas required for add_max_of_ne, this will allow us to remove the CommGroup part in the below which is unnecessary. -/ -lemma add_eq_max_of_ne' {α S : Type*} [Semiring S] [LinearOrder S] [AddCommGroup α] +lemma add_eq_max_of_ne' {α S : Type*} [LinearOrder S] [AddCommGroup α] (f : α → S) (fna : IsNonarchimedean f) (Neg : ∀ a, f a = f (-a)) {a b : α} (hne : f a ≠ f b) : f (a + b) = max (f a) (f b) := by wlog hab : f a > f b generalizing a b with H @@ -223,6 +223,7 @@ theorem finset_powerset_image_add [IsStrictOrderedRing R] g (powersetCard (s.card - m) s) exact ⟨⟨b, hb_in (powersetCard_nonempty.mpr (Nat.sub_le s.card m))⟩, hb⟩ +omit [Semiring R] in lemma apply_sum_eq_of_lt {α β : Type*} [AddCommGroup α] {f : α → R} (fna : IsNonarchimedean f) (f_neg : ∀ a, f a = f (-a)) {s : Finset β} {l : β → α} {k : β} (hk : k ∈ s) (hmax : ∀ j ∈ s, j ≠ k → f (l j) < f (l k)) : f (∑ i ∈ s, l i) = f (l k) := by diff --git a/Mathlib/Algebra/SkewPolynomial/Basic.lean b/Mathlib/Algebra/SkewPolynomial/Basic.lean index 700145186964c9..0e1369bec1cfe0 100644 --- a/Mathlib/Algebra/SkewPolynomial/Basic.lean +++ b/Mathlib/Algebra/SkewPolynomial/Basic.lean @@ -173,8 +173,7 @@ def monomial : R →ₗ[R] SkewPolynomial R := lsingle R (ofAdd n) lemma monomial_zero_right : monomial n (0 : R) = 0 := single_zero _ -lemma monomial_zero_one [MulSemiringAction (Multiplicative ℕ) R] : monomial 0 (1 : R) = 1 := - rfl +lemma monomial_zero_one : monomial 0 (1 : R) = 1 := rfl lemma monomial_def (a : R) : monomial n a = single (ofAdd n) a := rfl @@ -348,8 +347,7 @@ lemma coeff_monomial : coeff (monomial n a) m = if n = m then a else 0 := @[simp] lemma coeff_zero (n : ℕ) : coeff (0 : SkewPolynomial R) n = 0 := rfl -@[simp] lemma coeff_one_zero [MulSemiringAction (Multiplicative ℕ) R] : - coeff (1 : SkewPolynomial R) 0 = 1 := coeff_monomial +@[simp] lemma coeff_one_zero : coeff (1 : SkewPolynomial R) 0 = 1 := coeff_monomial lemma coeff_one [MulSemiringAction (Multiplicative ℕ) R] (n : ℕ) : coeff (1 : SkewPolynomial R) n = if 0 = n then 1 else 0 := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean b/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean index 86a83253b590f5..e57a1ed93c8f18 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean @@ -154,8 +154,7 @@ instance {U V X : Scheme.{u}} (f : U ⟶ X) (g : V ⟶ X) [IsFinite f] [IsFinite end IsFinite -lemma Scheme.Hom.finite_appTop {X Y : Scheme.{u}} (f : X ⟶ Y) [IsAffine X] [IsAffine Y] - [IsFinite f] : +lemma Scheme.Hom.finite_appTop {X Y : Scheme.{u}} (f : X ⟶ Y) [IsAffine Y] [IsFinite f] : f.appTop.hom.Finite := (HasAffineProperty.iff_of_isAffine (P := @IsFinite).mp inferInstance).2 diff --git a/Mathlib/Analysis/LocallyConvex/HahnBanach.lean b/Mathlib/Analysis/LocallyConvex/HahnBanach.lean index 22754bba9a8f0f..1082d18d304e88 100644 --- a/Mathlib/Analysis/LocallyConvex/HahnBanach.lean +++ b/Mathlib/Analysis/LocallyConvex/HahnBanach.lean @@ -68,8 +68,8 @@ variable [TopologicalSpace E] /-- **Hahn-Banach theorem** for linear functionals dominated by a continuous seminorm on polynormable spaces over `ℝ`. -/ -theorem Module.Dual.exists_continuous_extension_of_le_seminorm_real [IsTopologicalAddGroup E] - [Module ℝ E] [ContinuousSMul ℝ E] [PolynormableSpace ℝ E] (S : Subspace ℝ E) (f : Dual ℝ S) +theorem Module.Dual.exists_continuous_extension_of_le_seminorm_real + [Module ℝ E] [PolynormableSpace ℝ E] (S : Subspace ℝ E) (f : Dual ℝ S) {p : Seminorm ℝ E} (hp_cont : Continuous p) (hp : ∀ x, f x ≤ p x) : ∃ g : StrongDual ℝ E, (∀ x : S, g x = f x) ∧ ∀ x, |g x| ≤ p x := by obtain ⟨g, hg, hl⟩ := f.exists_extension_of_le_seminorm_real S hp diff --git a/Mathlib/Analysis/Normed/Operator/NormedSpace.lean b/Mathlib/Analysis/Normed/Operator/NormedSpace.lean index 360f0ccdb8be29..74ba95d31cf2bd 100644 --- a/Mathlib/Analysis/Normed/Operator/NormedSpace.lean +++ b/Mathlib/Analysis/Normed/Operator/NormedSpace.lean @@ -438,7 +438,7 @@ lemma ContinuousLinearMap.norm_inl [SeminormedAddCommGroup E] [NontrivialTopolog ‖ContinuousLinearMap.inl 𝕜 E F‖ = 1 := (LinearIsometry.inl 𝕜 E F).norm_toContinuousLinearMap -lemma ContinuousLinearMap.norm_inr [SeminormedAddCommGroup E] [NontrivialTopology E] +lemma ContinuousLinearMap.norm_inr [SeminormedAddCommGroup E] [NormedSpace 𝕜 E] [SeminormedAddCommGroup F] [NormedSpace 𝕜 F] [NontrivialTopology F] : ‖ContinuousLinearMap.inr 𝕜 E F‖ = 1 := (LinearIsometry.inr 𝕜 E F).norm_toContinuousLinearMap diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index 5cb671c016ff74..7e79c81ce21402 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -1175,7 +1175,7 @@ theorem continuous_of_le [TopologicalSpace E] [IsTopologicalAddGroup E] exact isOpen_lt hq continuous_const /-- The sum over a finite set of continuous seminorms is continuous. -/ -theorem continuous_finsetSum [TopologicalSpace E] [IsTopologicalAddGroup E] +theorem continuous_finsetSum [TopologicalSpace E] {p : ι → Seminorm 𝕝 E} {s : Finset ι} (hp : ∀ i ∈ s, Continuous (p i)) : Continuous ((∑ i ∈ s, p i : Seminorm 𝕝 E) : E → ℝ) := by change Continuous (fun x ↦ coeFnAddMonoidHom _ _ (∑ i ∈ s, p i) x) diff --git a/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean b/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean index 6be256b72cd9bc..6f6fecc53e31cd 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean @@ -68,7 +68,7 @@ lemma hasLiftingProperty_mk_iff' [HasPushouts C] [HasPullbacks C] set_option backward.defeqAttrib.useBackward true in /-- `(∅ ⟶ B) □ g` lifts against `X ⟶ Y` if and only if `g` lifts against `B ⟹ X ⟶ B ⟹ Y`. -/ -lemma hasLiftingProperty_mk_isInitial_iff [HasPushouts C] [HasPullbacks C] +lemma hasLiftingProperty_mk_isInitial_iff [HasPushouts C] [CartesianMonoidalCategory C] [MonoidalClosed C] [BraidedCategory C] {A B K L X Y : C} {g : K ⟶ L} {h : X ⟶ Y} (i : IsInitial A) : @@ -80,7 +80,7 @@ lemma hasLiftingProperty_mk_isInitial_iff [HasPushouts C] [HasPullbacks C] exact Adjunction.hasLiftingProperty_iff (ihom.adjunction B) g h /-- `f □ (∅ ⟶ L)` lifts against `X ⟶ Y` if and only if `f` lifts against `L ⟹ X ⟶ L ⟹ Y`. -/ -lemma hasLiftingProperty_mk_isInitial_iff' [HasPushouts C] [HasPullbacks C] +lemma hasLiftingProperty_mk_isInitial_iff' [HasPushouts C] [CartesianMonoidalCategory C] [MonoidalClosed C] [BraidedCategory C] {A B K L X Y : C} {f : A ⟶ B} {h : X ⟶ Y} (i : IsInitial K) : @@ -100,7 +100,7 @@ lemma hasLiftingProperty_mk_isTerminal_iff [HasPushouts C] [HasPullbacks C] exact HasLiftingProperty.iff_of_arrow_iso_right g (PullbackHom.isTerminalIso _ t) /-- `(∅ ⟶ B) □ g` lifts against `X ⟶ ⋆` if and only if `g` lifts against `(B ⟹ X) ⟶ ⋆`. -/ -lemma hasLiftingProperty_mk_isInitial_isTerminal_iff [HasPushouts C] [HasPullbacks C] +lemma hasLiftingProperty_mk_isInitial_isTerminal_iff [HasPushouts C] [CartesianMonoidalCategory C] [MonoidalClosed C] [BraidedCategory C] {A B K L X Y : C} {g : K ⟶ L} (i : IsInitial A) (t : IsTerminal Y) : @@ -112,7 +112,7 @@ lemma hasLiftingProperty_mk_isInitial_isTerminal_iff [HasPushouts C] [HasPullbac (t.hom_ext _ _)) /-- `f □ (∅ ⟶ L)` lifts against `X ⟶ ⋆` if and only if `f` lifts against `(L ⟹ X) ⟶ ⋆`. -/ -lemma hasLiftingProperty_mk_isInitial_isTerminal_iff' [HasPushouts C] [HasPullbacks C] +lemma hasLiftingProperty_mk_isInitial_isTerminal_iff' [HasPushouts C] [CartesianMonoidalCategory C] [MonoidalClosed C] [BraidedCategory C] {A B K L X Y : C} {f : A ⟶ B} (i : IsInitial K) (t : IsTerminal Y) : diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 494394ceaf6ee4..eb5609d304f505 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -181,7 +181,7 @@ instance isGalois_bot : IsGalois F (⊥ : IntermediateField F E) := (IntermediateField.botEquiv F E).transfer_galois.mpr (IsGalois.self F) theorem IsGalois.of_equiv_equiv {M N : Type*} [Field N] [Field M] [Algebra M N] - [Algebra.IsAlgebraic F E] [h : IsGalois F E] {f : F ≃+* M} {g : E ≃+* N} + [h : IsGalois F E] {f : F ≃+* M} {g : E ≃+* N} (hcomp : (algebraMap M N).comp f = (g : E →+* N).comp (algebraMap F E)) : IsGalois M N := isGalois_iff.mpr ⟨Algebra.IsSeparable.of_equiv_equiv f g hcomp, Normal.of_equiv_equiv hcomp⟩ diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 431a89fbdd99a2..dd462f855e2f75 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -317,7 +317,7 @@ theorem fixedPoints_fixingSubgroup [Finite G] : /-- If `G` acts as a Galois group on `L/K` and the subgroup `H` acts as a Galois group on `L/B`, then the fixed points of `H` equals the range of `algebraMap B L`. -/ -theorem fixedPoints_eq_range_algebraMap [Finite G] (B : Type*) +theorem fixedPoints_eq_range_algebraMap (B : Type*) [CommSemiring B] [Algebra B L] [IsGaloisGroup H B L] : (FixedPoints.intermediateField H : IntermediateField K L) = Set.range (algebraMap B L) := by ext diff --git a/Mathlib/Geometry/Manifold/Algebra/SMul.lean b/Mathlib/Geometry/Manifold/Algebra/SMul.lean index b9680bc87af096..0f2d1913bd6bb9 100644 --- a/Mathlib/Geometry/Manifold/Algebra/SMul.lean +++ b/Mathlib/Geometry/Manifold/Algebra/SMul.lean @@ -173,8 +173,7 @@ instance {n : ℕ∞ω} : ContMDiffSMul 𝓘(𝕜) 𝓘(𝕜, E) n 𝕜 E where exact contDiff_smul.contMDiff.comp h /-- The monoid `E →L[𝕜] E` of continuous linear endomorphisms of `E` acts smoothly on `E`. -/ -instance [CompleteSpace E] {n : ℕ∞ω} : - ContMDiffSMul 𝓘(𝕜, E →L[𝕜] E) 𝓘(𝕜, E) n (E →L[𝕜] E) E where +instance {n : ℕ∞ω} : ContMDiffSMul 𝓘(𝕜, E →L[𝕜] E) 𝓘(𝕜, E) n (E →L[𝕜] E) E where contMDiff_smul := by have h : ContMDiff (𝓘(𝕜, E →L[𝕜] E).prod 𝓘(𝕜, E)) 𝓘(𝕜, (E →L[𝕜] E) × E) n (@id ((E →L[𝕜] E) × E)) := by diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index c1c0e5ecbf1239..04fc8658e10cff 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -242,7 +242,7 @@ variable {e : OpenPartialHomeomorph M H} {e' : OpenPartialHomeomorph M' H'} open IsManifold theorem mdifferentiableWithinAt_iff_source_of_mem_maximalAtlas - [IsManifold I 1 M] (he : e ∈ maximalAtlas I 1 M) (hx : x ∈ e.source) : + (he : e ∈ maximalAtlas I 1 M) (hx : x ∈ e.source) : MDifferentiableWithinAt I I' f s x ↔ MDifferentiableWithinAt 𝓘(𝕜, E) I' (f ∘ (e.extend I).symm) ((e.extend I).symm ⁻¹' s ∩ range I) (e.extend I x) := by diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean index 4e8ea4567aa25a..8ec160506c7636 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean @@ -643,7 +643,7 @@ theorem closedInterior_face_ssubset_closedInterior [Nontrivial k] [ZeroLEOneClas apply (Set.ssubset_iff_of_subset (s.closedInterior_face_subset_closedInterior h)).mpr exact ⟨s.points a, s.point_mem_closedInterior a, fun hs ↦ ha (by simpa using hs)⟩ -theorem disjoint_interior_closedInterior_face [Nontrivial k] [ZeroLEOneClass k] {n : ℕ} +theorem disjoint_interior_closedInterior_face {n : ℕ} (s : Simplex k P n) {fs : Finset (Fin (n + 1))} (hfs : fs ≠ .univ) {m : ℕ} (h : #fs = m + 1) : Disjoint s.interior (s.face h).closedInterior := by refine Set.disjoint_left.mpr fun p hleft hright ↦ ?_ @@ -669,8 +669,8 @@ theorem closedInterior_faceOpposite_ssubset_closedInterior [Nontrivial k] [ZeroL (s.faceOpposite i).closedInterior ⊂ s.closedInterior := s.closedInterior_face_ssubset_closedInterior (by simp) _ -theorem disjoint_interior_closedInterior_faceOpposite [Nontrivial k] [ZeroLEOneClass k] {n : ℕ} - [NeZero n] (s : Simplex k P n) (i : Fin (n + 1)) : +theorem disjoint_interior_closedInterior_faceOpposite {n : ℕ} [NeZero n] + (s : Simplex k P n) (i : Fin (n + 1)) : Disjoint s.interior (s.faceOpposite i).closedInterior := s.disjoint_interior_closedInterior_face (by simp) _ @@ -705,7 +705,7 @@ theorem closedInterior_eq_interior_union [IsOrderedAddMonoid k] [ZeroLEOneClass · refine Set.union_subset s.interior_subset_closedInterior (Set.iUnion_subset fun i ↦ ?_) exact s.closedInterior_faceOpposite_subset_closedInterior i -theorem closedInterior_sdiff_interior [Nontrivial k] [IsOrderedAddMonoid k] [ZeroLEOneClass k] +theorem closedInterior_sdiff_interior [IsOrderedAddMonoid k] [ZeroLEOneClass k] {n : ℕ} [NeZero n] (s : Simplex k P n) : s.closedInterior \ s.interior = ⋃ i : Fin (n + 1), (s.faceOpposite i).closedInterior := by simpa [closedInterior_eq_interior_union] using diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean index b96f72d46a923a..69fa66fdf6c2eb 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean @@ -103,7 +103,7 @@ theorem measurable_of_tendsto_metrizable_ae {μ : Measure α} [μ.IsComplete] {f aemeasurable_iff_measurable.mp (aemeasurable_of_tendsto_metrizable_ae' (fun i => (hf i).aemeasurable) h_ae_tendsto) -theorem measurable_limit_of_tendsto_metrizable_ae {ι} [Countable ι] [Nonempty ι] {μ : Measure α} +theorem measurable_limit_of_tendsto_metrizable_ae {ι} [Nonempty ι] {μ : Measure α} {f : ι → α → β} {L : Filter ι} [L.IsCountablyGenerated] (hf : ∀ n, AEMeasurable (f n) μ) (h_ae_tendsto : ∀ᵐ x ∂μ, ∃ l : β, Tendsto (fun n => f n x) L (𝓝 l)) : ∃ f_lim : α → β, Measurable f_lim ∧ ∀ᵐ x ∂μ, Tendsto (fun n => f n x) L (𝓝 (f_lim x)) := by diff --git a/Mathlib/ModelTheory/Satisfiability.lean b/Mathlib/ModelTheory/Satisfiability.lean index ff95887b9bc350..c36c9f809fde4c 100644 --- a/Mathlib/ModelTheory/Satisfiability.lean +++ b/Mathlib/ModelTheory/Satisfiability.lean @@ -196,7 +196,7 @@ variable (L) into `M`, but is not by type a substructure of `M`, and thus can be chosen to belong to the universe of the cardinal `κ`. -/ -theorem exists_elementaryEmbedding_card_eq_of_le (M : Type w') [L.Structure M] [Nonempty M] +theorem exists_elementaryEmbedding_card_eq_of_le (M : Type w') [L.Structure M] (κ : Cardinal.{w}) (h1 : ℵ₀ ≤ κ) (h2 : lift.{w} L.card ≤ Cardinal.lift.{max u v} κ) (h3 : lift.{w'} κ ≤ Cardinal.lift.{w} #M) : ∃ N : Bundled L.Structure, Nonempty (N ↪ₑ[L] M) ∧ #N = κ := by diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean index ea87dce51ac262..ae67c5f9b4a1d0 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean @@ -87,7 +87,7 @@ lemma discr_mem_differentIdeal : ↑(discr K) ∈ differentIdeal ℤ 𝒪 := by attribute [local instance] FractionRing.liftAlgebra in theorem natAbs_discr_eq_absNorm_differentIdeal_mul_natAbs_discr_pow (L 𝒪' : Type*) [Field L] - [NumberField L] [CommRing 𝒪'] [Algebra 𝒪' L] [IsFractionRing 𝒪' L] [IsIntegralClosure 𝒪' ℤ L] + [NumberField L] [CommRing 𝒪'] [Algebra 𝒪' L] [IsFractionRing 𝒪' L] [IsDedekindDomain 𝒪'] [CharZero 𝒪'] [Algebra K L] [Algebra 𝒪 𝒪'] [Algebra 𝒪 L] [IsScalarTower 𝒪 K L] [IsScalarTower 𝒪 𝒪' L] [IsTorsionFree 𝒪 𝒪'] [Free ℤ 𝒪'] [Module.Finite ℤ 𝒪'] [Module.Finite 𝒪 𝒪'] : diff --git a/Mathlib/Probability/HasCondDistrib.lean b/Mathlib/Probability/HasCondDistrib.lean index b70e76eb7ace7b..68b6d95b1793bb 100644 --- a/Mathlib/Probability/HasCondDistrib.lean +++ b/Mathlib/Probability/HasCondDistrib.lean @@ -49,7 +49,7 @@ lemma HasCondDistrib.aemeasurable_fst (h : HasCondDistrib Y X κ P) : lemma HasCondDistrib.aemeasurable_snd (h : HasCondDistrib Y X κ P) : AEMeasurable Y P := h.aemeasurable.snd -lemma HasLaw.prodMk_of_hasCondDistrib {Q : Measure 𝓧} [IsSFiniteKernel κ] +lemma HasLaw.prodMk_of_hasCondDistrib {Q : Measure 𝓧} (h1 : HasLaw X Q P) (h2 : HasCondDistrib Y X κ P) : HasLaw (fun ω ↦ (X ω, Y ω)) (Q ⊗ₘ κ) P := by rwa [← h1.map_eq] diff --git a/Mathlib/Probability/Independence/Basic.lean b/Mathlib/Probability/Independence/Basic.lean index 680f9930fa7ed5..41ce7f824cf9d6 100644 --- a/Mathlib/Probability/Independence/Basic.lean +++ b/Mathlib/Probability/Independence/Basic.lean @@ -1036,7 +1036,7 @@ theorem iIndepSet.iIndepFun_indicator [Zero β] [One β] {m : MeasurableSpace β Kernel.iIndepSet.iIndepFun_indicator hs lemma Indep.indicator_indepFun {m : MeasurableSpace Ω} {M 𝓧 : Type*} - [Zero M] [MeasurableSpace M] (c : M) [NeZero c] {m𝓧 : MeasurableSpace 𝓧} {A : Set Ω} + [Zero M] [MeasurableSpace M] (c : M) {m𝓧 : MeasurableSpace 𝓧} {A : Set Ω} {X : Ω → 𝓧} (hA : MeasurableSet[m] A) (h : Indep m (m𝓧.comap X) μ) : (A.indicator (fun _ ↦ c)) ⟂ᵢ[μ] X := Kernel.Indep.indicator_const_indepFun c hA h diff --git a/Mathlib/Probability/Independence/Integration.lean b/Mathlib/Probability/Independence/Integration.lean index b3e84ccd379466..dde2dfa2836440 100644 --- a/Mathlib/Probability/Independence/Integration.lean +++ b/Mathlib/Probability/Independence/Integration.lean @@ -312,11 +312,11 @@ theorem IndepFun.integral_bilin_comp_comp' /-- If `X` and `Y` are independent and integrable random variables and `B` is a continuous bilinear map, then `∫ ω, B (X ω) (Y ω) ∂μ = B μ[X] μ[Y].` -/ theorem IndepFun.integral_bilin - [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedSpace 𝕜 E] [CompleteSpace E] + [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] [MeasurableSpace E] [BorelSpace E] - [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F] [CompleteSpace F] + [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] [MeasurableSpace F] [BorelSpace F] - [NormedAddCommGroup G] [NormedSpace ℝ G] [NormedSpace 𝕜 G] [CompleteSpace G] + [NormedAddCommGroup G] [NormedSpace ℝ G] [CompleteSpace G] {X : Ω → E} {Y : Ω → F} (hXY : X ⟂ᵢ[μ] Y) (hX : Integrable X μ) (hY : Integrable Y μ) (B : E →L[ℝ] F →L[ℝ] G) : ∫ ω, B (X ω) (Y ω) ∂μ = B μ[X] μ[Y] := @@ -333,11 +333,11 @@ The assumption on `B` allows to drop the integrability condition in `IndepFun.integral_bilin'`, which is useful for the versions where `B` is the scalar multiplication or the multiplication. -/ theorem IndepFun.integral_bilin' - [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedSpace 𝕜 E] [CompleteSpace E] + [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] [MeasurableSpace E] [BorelSpace E] - [NormedAddCommGroup F] [NormedSpace ℝ F] [NormedSpace 𝕜 F] [CompleteSpace F] + [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] [MeasurableSpace F] [BorelSpace F] - [NormedAddCommGroup G] [NormedSpace ℝ G] [NormedSpace 𝕜 G] [CompleteSpace G] + [NormedAddCommGroup G] [NormedSpace ℝ G] [CompleteSpace G] {X : Ω → E} {Y : Ω → F} (hXY : X ⟂ᵢ[μ] Y) (hX : AEStronglyMeasurable X μ) (hY : AEStronglyMeasurable Y μ) (B : E →L[ℝ] F →L[ℝ] G) (c : ℝ≥0) (hc : c ≠ 0) (hB : ∀ x y, c * ‖x‖ * ‖y‖ ≤ ‖B x y‖) : @@ -405,7 +405,7 @@ lemma IndepFun.integral_smul_eq_smul_integral (hX : AEStronglyMeasurable X μ) (hY : AEStronglyMeasurable Y μ) : μ[X • Y] = μ[X] • μ[Y] := by by_cases hE : CompleteSpace E - · exact hXY.integral_bilin' (𝕜 := 𝕜) hX hY (.lsmul ℝ 𝕜) 1 (by simp) (by simp [norm_smul]) + · exact hXY.integral_bilin' hX hY (.lsmul ℝ 𝕜) 1 (by simp) (by simp [norm_smul]) · simp [integral, hE] lemma IndepFun.integral_mul_eq_mul_integral diff --git a/Mathlib/Probability/Independence/Kernel/IndepFun.lean b/Mathlib/Probability/Independence/Kernel/IndepFun.lean index bd59b14882e064..56935576fa75f9 100644 --- a/Mathlib/Probability/Independence/Kernel/IndepFun.lean +++ b/Mathlib/Probability/Independence/Kernel/IndepFun.lean @@ -695,7 +695,7 @@ theorem iIndepSet.iIndepFun_indicator [Zero β] [One β] {m : MeasurableSpace β · exact @MeasurableSet.empty _ (generateFrom {s i}) lemma Indep.indicator_const_indepFun {m : MeasurableSpace Ω} {M 𝓧 : Type*} - [Zero M] [MeasurableSpace M] (c : M) [NeZero c] {m𝓧 : MeasurableSpace 𝓧} {A : Set Ω} + [Zero M] [MeasurableSpace M] (c : M) {m𝓧 : MeasurableSpace 𝓧} {A : Set Ω} {X : Ω → 𝓧} (hA : MeasurableSet[m] A) (h : Indep m (m𝓧.comap X) κ μ) : IndepFun (A.indicator (fun _ ↦ c)) X κ μ := indep_of_indep_of_le_left h (measurable_const.indicator hA).comap_le diff --git a/Mathlib/Probability/Martingale/Centering.lean b/Mathlib/Probability/Martingale/Centering.lean index 4fdfd483e7f7a0..0581c5562ca25a 100644 --- a/Mathlib/Probability/Martingale/Centering.lean +++ b/Mathlib/Probability/Martingale/Centering.lean @@ -99,8 +99,8 @@ lemma Submartingale.predictablePart_nonneg filter_upwards [hf.monotone_predictablePart] with ω hω n simpa [predictablePart_zero] using hω (Nat.zero_le n) -lemma IsStronglyPredictable.predictablePart_eq [SecondCountableTopology E] [MeasurableSpace E] - [BorelSpace E] [SigmaFiniteFiltration μ ℱ] (hf : IsStronglyPredictable ℱ f) +lemma IsStronglyPredictable.predictablePart_eq + [SigmaFiniteFiltration μ ℱ] (hf : IsStronglyPredictable ℱ f) (hfint : ∀ n, Integrable (f n) μ) (n : ℕ) : predictablePart f ℱ μ n =ᵐ[μ] f n - f 0 := by simp only [predictablePart, ← Finset.sum_range_sub] @@ -148,8 +148,7 @@ lemma Martingale.martingalePart_eq [CompleteSpace E] (hf : Martingale f ℱ μ) filter_upwards [hf.predictablePart_eq_zero n] with ω hω simp [martingalePart, hω] -lemma IsPredictable.martingalePart_eq [SecondCountableTopology E] [MeasurableSpace E] - [BorelSpace E] [SigmaFiniteFiltration μ ℱ] (hf : IsStronglyPredictable ℱ f) +lemma IsPredictable.martingalePart_eq [SigmaFiniteFiltration μ ℱ] (hf : IsStronglyPredictable ℱ f) (hfint : ∀ n, Integrable (f n) μ) (n : ℕ) : martingalePart f ℱ μ n =ᵐ[μ] f 0 := by filter_upwards [hf.predictablePart_eq (μ := μ) hfint n] with ω hω diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 58c363276417d0..7017583d9e6b72 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -438,7 +438,7 @@ theorem span_singleton_mul_left_inj [IsDomain R] [I.IsTwoSided] [J.IsTwoSided] theorem mul_le_inf [I.IsTwoSided] : I * J ≤ I ⊓ J := mul_le.2 fun r hri s hsj => ⟨I.mul_mem_right s hri, J.mul_mem_left r hsj⟩ -lemma inf_ne_bot_of_ne_bot [NoZeroDivisors R] {I J : Ideal R} [I.IsTwoSided] [J.IsTwoSided] +lemma inf_ne_bot_of_ne_bot [NoZeroDivisors R] {I J : Ideal R} [I.IsTwoSided] (hI : I ≠ ⊥) (hJ : J ≠ ⊥) : I ⊓ J ≠ ⊥ := by grw [← bot_lt_iff_ne_bot, ← mul_le_inf, bot_lt_iff_ne_bot, Ne, mul_eq_bot] diff --git a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean index 19bd8b54b351a6..f2df00cd008376 100644 --- a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean +++ b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean @@ -116,7 +116,7 @@ If `G` is finite and `IsGaloisGroup G A B` with `A` and `B` domains, then `G` is a Galois group for `FractionRing B / FractionRing A` for the action defined by `IsFractionRing.mulSemiringAction`. -/ -instance IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [IsTorsionFree A B] [Finite G] +instance IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [Finite G] [IsGaloisGroup G A B] [Algebra (FractionRing A) (FractionRing B)] [IsScalarTower A (FractionRing A) (FractionRing B)] : letI := IsFractionRing.mulSemiringAction G B (FractionRing B) diff --git a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean index db2ea3a8a78c2e..b26a1d6e4c6903 100644 --- a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean +++ b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean @@ -180,7 +180,7 @@ lemma ultrametric_strict (na : IsNonarchimedean f) variable [Semiring S] lemma Finset.Nonempty.map_sum_le_sup'_map - {α S : Type*} [Semiring S] [LinearOrder S] [AddCommMonoid α] (g : α → S) + {α S : Type*} [LinearOrder S] [AddCommMonoid α] (g : α → S) {ι : Type*} {s : Finset ι} (hs : s.Nonempty) (f : ι → α) (na : ∀ a b, g (a + b) ≤ max (g a) (g b)) : g (∑ i ∈ s, f i) ≤ s.sup' hs fun x ↦ g (f x) := by diff --git a/Mathlib/RingTheory/RamificationInertia/Basic.lean b/Mathlib/RingTheory/RamificationInertia/Basic.lean index eba20d69cb7d25..e9529d9886d084 100644 --- a/Mathlib/RingTheory/RamificationInertia/Basic.lean +++ b/Mathlib/RingTheory/RamificationInertia/Basic.lean @@ -42,7 +42,7 @@ variable {R : Type*} [CommRing R] (p : Ideal R) [p.IsPrime] (S : Type*) [CommRin open IsLocalRing Module OrderIso PrimeSpectrum in theorem sum_ramification_inertia_eq_finrank_fiber - [Algebra.QuasiFinite R S] [Flat R S] [Fintype (p.primesOver S)] : + [Algebra.QuasiFinite R S] [Fintype (p.primesOver S)] : ∑ q : p.primesOver S, q.1.ramificationIdx' R * q.1.inertiaDeg' R = finrank p.ResidueField (p.Fiber S) := by let := Fintype.ofFinite (PrimeSpectrum (p.Fiber S)) diff --git a/Mathlib/RingTheory/TwoSidedIdeal/BigOperators.lean b/Mathlib/RingTheory/TwoSidedIdeal/BigOperators.lean index 1fc23328611068..31958c93682821 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/BigOperators.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/BigOperators.lean @@ -81,10 +81,8 @@ lemma finsetProd_mem {ι : Type*} (s : Finset ι) (f : ι → R) (hs : ∃ x ∈ rcases s simpa using multiSetProd_mem (hs := hs) -lemma finsuppProd_mem {ι : Type*} {β : Type*} {M : Type*} - [Add M] [CommMonoid M] [Zero β] - (h : ι → β → R) {f : ι →₀ β} (H : ∃ i ∈ f.support, h i (f i) ∈ I) : - f.prod h ∈ I := +lemma finsuppProd_mem {ι : Type*} {β : Type*} [Zero β] + (h : ι → β → R) {f : ι →₀ β} (H : ∃ i ∈ f.support, h i (f i) ∈ I) : f.prod h ∈ I := finsetProd_mem _ _ _ H lemma dfinsuppProd_mem {ι : Type*} {β : ι → Type*} diff --git a/Mathlib/Topology/Algebra/Module/Complement.lean b/Mathlib/Topology/Algebra/Module/Complement.lean index 74c43d16d84cce..68b2429b536667 100644 --- a/Mathlib/Topology/Algebra/Module/Complement.lean +++ b/Mathlib/Topology/Algebra/Module/Complement.lean @@ -284,7 +284,7 @@ lemma projectionL_eq_id_sub_projectionL [IsTopologicalAddGroup M] (h : IsTopComp ContinuousLinearMap.ext <| projectionL_eq_self_sub_projectionL h /-- The projection to `p` along `q` of `x` equals `x` if and only if `x ∈ p`. -/ -lemma projectionL_eq_self_iff [ContinuousSub M] (h : IsTopCompl p q) (x : M) : +lemma projectionL_eq_self_iff (h : IsTopCompl p q) (x : M) : p.projectionL q h x = x ↔ x ∈ p := projection_eq_self_iff h.isCompl x diff --git a/Mathlib/Topology/Algebra/Order/Floor.lean b/Mathlib/Topology/Algebra/Order/Floor.lean index fca55d68eb8cb1..5f59c6fa74b19c 100644 --- a/Mathlib/Topology/Algebra/Order/Floor.lean +++ b/Mathlib/Topology/Algebra/Order/Floor.lean @@ -86,7 +86,7 @@ theorem continuousOn_floor (n : ℤ) : ContinuousOn (fun x => floor x : α → α) (Ico n (n + 1) : Set α) := (continuousOn_congr <| floor_eq_on_Ico' n).mpr continuousOn_const -theorem continuousOn_ceil [IsStrictOrderedRing α] (n : ℤ) : +theorem continuousOn_ceil (n : ℤ) : ContinuousOn (fun x => ceil x : α → α) (Ioc (n - 1) n : Set α) := (continuousOn_congr <| ceil_eq_on_Ioc' n).mpr continuousOn_const diff --git a/Mathlib/Topology/Order/Completion.lean b/Mathlib/Topology/Order/Completion.lean index 050b3668cc531f..a7521c3468d4dd 100644 --- a/Mathlib/Topology/Order/Completion.lean +++ b/Mathlib/Topology/Order/Completion.lean @@ -63,8 +63,7 @@ namespace Fill instance : TopologicalSpace (Fill α) := Preorder.topology _ -instance [TopologicalSpace α] [OrderTopology α] : OrderTopology (Fill α) := - ⟨rfl⟩ +instance : OrderTopology (Fill α) := ⟨rfl⟩ /-- A continuous embedding of `α` into `Fill α`. -/ def some : α ↪o Fill α where diff --git a/Mathlib/Topology/Order/ScottTopology.lean b/Mathlib/Topology/Order/ScottTopology.lean index 583db890a253ff..5e77f371f9f738 100644 --- a/Mathlib/Topology/Order/ScottTopology.lean +++ b/Mathlib/Topology/Order/ScottTopology.lean @@ -101,8 +101,7 @@ and closed sets are `DirSupClosedOn D`. -/ class IsScottHausdorff (α) (D : Set (Set α)) [Preorder α] [TopologicalSpace α] : Prop where topology_eq_scottHausdorff : ‹TopologicalSpace α› = scottHausdorff α D -instance (α) (D : Set (Set α)) [Preorder α] [TopologicalSpace α] : - @IsScottHausdorff α D _ (scottHausdorff α D) := +instance (α) (D : Set (Set α)) [Preorder α] : @IsScottHausdorff α D _ (scottHausdorff α D) := @IsScottHausdorff.mk _ _ _ (scottHausdorff α D) rfl namespace IsScottHausdorff diff --git a/Mathlib/Topology/UniformSpace/ProdApproximation.lean b/Mathlib/Topology/UniformSpace/ProdApproximation.lean index 9975b76d1389d5..7ee1f6bc4a8a3c 100644 --- a/Mathlib/Topology/UniformSpace/ProdApproximation.lean +++ b/Mathlib/Topology/UniformSpace/ProdApproximation.lean @@ -95,9 +95,8 @@ lemma tensorHom_tmul (f : C(X, R)) (g : C(Y, R)) : tensorHom (f ⊗ₜ g) = prodMul f g := by rw [tensorHom, TensorProduct.lift.tmul] -lemma denseRange_tensorHom [CompactSpace X] [T2Space X] [CompactSpace Y] [T2Space Y] - [TotallyDisconnectedSpace X] : - DenseRange (tensorHom : C(X, R) ⊗[R] C(Y, R) → C(X × Y, R)) := by +lemma denseRange_tensorHom [CompactSpace X] [T2Space X] [CompactSpace Y] + [TotallyDisconnectedSpace X] : DenseRange (tensorHom : C(X, R) ⊗[R] C(Y, R) → C(X × Y, R)) := by let : UniformSpace R := IsTopologicalAddGroup.rightUniformSpace R let : IsUniformAddGroup R := isUniformAddGroup_of_addCommGroup intro f From 96aedd613e0924fd4519f64cf7c67c6f9d73d751 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:33:39 +0000 Subject: [PATCH 0334/1300] chore(Geometry/Euclidean/Angle): fix an `erw` (#41014) This one is easy Co-authored-by: Batixx --- Mathlib/Geometry/Euclidean/Angle/Unoriented/RightAngle.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Euclidean/Angle/Unoriented/RightAngle.lean b/Mathlib/Geometry/Euclidean/Angle/Unoriented/RightAngle.lean index c059c3844d66a2..e0887fd418d0f1 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Unoriented/RightAngle.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Unoriented/RightAngle.lean @@ -328,8 +328,8 @@ variable {V : Type*} {P : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V theorem dist_sq_eq_dist_sq_add_dist_sq_iff_angle_eq_pi_div_two (p₁ p₂ p₃ : P) : dist p₁ p₃ * dist p₁ p₃ = dist p₁ p₂ * dist p₁ p₂ + dist p₃ p₂ * dist p₃ p₂ ↔ ∠ p₁ p₂ p₃ = π / 2 := by - erw [dist_comm p₃ p₂, dist_eq_norm_vsub V p₁ p₃, dist_eq_norm_vsub V p₁ p₂, - dist_eq_norm_vsub V p₂ p₃, ← norm_sub_sq_eq_norm_sq_add_norm_sq_iff_angle_eq_pi_div_two, + rw [dist_comm p₃ p₂, dist_eq_norm_vsub V p₁ p₃, dist_eq_norm_vsub V p₁ p₂, + dist_eq_norm_vsub V p₂ p₃, angle, ← norm_sub_sq_eq_norm_sq_add_norm_sq_iff_angle_eq_pi_div_two, vsub_sub_vsub_cancel_right p₁, ← neg_vsub_eq_vsub_rev p₂ p₃, norm_neg] /-- An angle in a right-angled triangle expressed using `arccos`. -/ From 609d880957e96da2065c4bbcc5ca9cf87fadf079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:42:39 +0000 Subject: [PATCH 0335/1300] chore: deprecating module LinearAlgebra.PiTensorProduct (#26987) --- Mathlib.lean | 1 + Mathlib/LinearAlgebra/PiTensorProduct.lean | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 Mathlib/LinearAlgebra/PiTensorProduct.lean diff --git a/Mathlib.lean b/Mathlib.lean index 881db5f16663e8..be8188b36cd456 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5154,6 +5154,7 @@ public import Mathlib.LinearAlgebra.PID public import Mathlib.LinearAlgebra.PerfectPairing.Basic public import Mathlib.LinearAlgebra.PerfectPairing.Restrict public import Mathlib.LinearAlgebra.Pi +public import Mathlib.LinearAlgebra.PiTensorProduct public import Mathlib.LinearAlgebra.PiTensorProduct.Basic public import Mathlib.LinearAlgebra.PiTensorProduct.Basis public import Mathlib.LinearAlgebra.PiTensorProduct.DFinsupp diff --git a/Mathlib/LinearAlgebra/PiTensorProduct.lean b/Mathlib/LinearAlgebra/PiTensorProduct.lean new file mode 100644 index 00000000000000..68ff7ebd53b1ad --- /dev/null +++ b/Mathlib/LinearAlgebra/PiTensorProduct.lean @@ -0,0 +1,5 @@ +module + +public import Mathlib.LinearAlgebra.PiTensorProduct.Basic + +deprecated_module (since := "2026-06-18") From b12383cf6da7a4bf69e11b5ebaa6c4037c5c545e Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Thu, 25 Jun 2026 08:42:42 +0000 Subject: [PATCH 0336/1300] chore(RingTheory/Derivation/DifferentialRing): unsqueeze terminal `simp`s (#40837) As recommended in the style guide. Extracted from #40793. --- Mathlib/RingTheory/Derivation/DifferentialRing.lean | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/Derivation/DifferentialRing.lean b/Mathlib/RingTheory/Derivation/DifferentialRing.lean index b1d7fb96ad0c88..94b6c54691de99 100644 --- a/Mathlib/RingTheory/Derivation/DifferentialRing.lean +++ b/Mathlib/RingTheory/Derivation/DifferentialRing.lean @@ -93,8 +93,4 @@ lemma DifferentialAlgebra.equiv {A : Type*} [CommRing A] [Differential A] letI := Differential.equiv h.toRingEquiv ⟨fun a ↦ by change (LinearMap.comp ..) _ = _ - simp only [RingHom.toAddMonoidHom_eq_coe, - RingEquiv.toRingHom_eq_coe, AlgEquiv.toRingEquiv_toRingHom, LinearMap.coe_comp, - AddMonoidHom.coe_toIntLinearMap, AddMonoidHom.coe_coe, RingHom.coe_coe, Derivation.coeFn_coe, - Function.comp_apply, AlgEquiv.commutes, deriv_algebraMap] - apply h.symm.commutes⟩ + simp [deriv_algebraMap]⟩ From d64a465b46a637c851ca8035ce55f0a2ecd45992 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:51:58 +0000 Subject: [PATCH 0337/1300] feat(AlgebraicGeometry): essential image of tilde is quasi-coherent modules (#40052) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We show that for a quasi-coherent module `M` over `Spec R`, the counit `M.fromTildeΓ` is an isomorphism, i.e., `M` is isomorphic to the tilde of the global sections of `M`. Co-authored-by: Andrew Yang Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com> --- Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 260 +++++++++++++++++++ 1 file changed, 260 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index cdd5f8c98f175d..f8c2feffe37612 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -10,6 +10,7 @@ public import Mathlib.Algebra.Category.ModuleCat.Localization public import Mathlib.Algebra.Category.ModuleCat.Sheaf.Quasicoherent public import Mathlib.Algebra.Module.LocalizedModule.Away public import Mathlib.AlgebraicGeometry.Modules.Sheaf +public import Mathlib.Data.Fintype.Order /-! @@ -595,6 +596,265 @@ lemma Scheme.Modules.exists_affineOpenCover_presentation {X : Scheme.{u}} (M : X exact SheafOfModules.Presentation.ofIsIso.{u, u, u} ((restrictFunctorComp _ _).app M).inv <| (presentationRestrict (hU' i).isoSpec.inv (pres i)) +namespace QuasicoherentTilde + +variable (M : (Spec R).Modules) + +/-- Auxiliary structure used in the proof of `Scheme.Modules.isIso_fromTildeΓ_of_isQuasicoherent`. +These are conditions d1) and d2) from [Theoreme 1.4.1, grothendieck-1971]. -/ +-- TODO: Generalise this to a general scheme, replacing `f : R` by sections over a suitable set. +private structure Aux (V : (Spec R).Opens) where + existence (f : R) (hf : basicOpen f ≤ V) (s : Γ(M, basicOpen f)) : + ∃ (n : ℕ) (t : Γ(M, V)), M.presheaf.map (homOfLE hf).op t = f ^ n • s + uniqueness (f : R) (hf : basicOpen f ≤ V) (t : Γ(M, V)) : + M.presheaf.map (.op <| homOfLE hf) t = (0 : Γ(M, basicOpen f)) → + ∃ (n : ℕ), f ^ n • t = 0 + +set_option backward.isDefEq.respectTransparency false in +private lemma Aux.of_le {M : (Spec R).Modules} {V : (Spec R).Opens} (g : R) (hg : basicOpen g ≤ V) + (hV : Aux M V) : + Aux M (basicOpen g) where + existence f hfg s := by + obtain ⟨n, t, ht⟩ := hV.existence f (le_trans hfg hg) s + use n, M.presheaf.map (homOfLE hg).op t + simp [← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp, ht] + uniqueness f hfg t ht := by + obtain ⟨n, t', ht'⟩ := hV.existence g hg t + obtain ⟨m, hm⟩ := hV.uniqueness _ (le_trans hfg hg) t' <| by + rw [← homOfLE_comp hfg hg, op_comp, M.presheaf.map_comp_apply, ht', M.map_smul_Spec, ht] + simp + refine ⟨m, ((M.isSMulRegular_of_le_basicOpen le_rfl).pow n).right_eq_zero_of_smul ?_⟩ + simp [smul_comm, ← ht', ← M.map_smul_Spec, hm] + +set_option backward.isDefEq.respectTransparency false in +/-- This is the key computation for the proof of +`Scheme.Modules.isQuasicoherent_iff_isIso_fromTildeΓ`. + [Lemme 1.4.1.1][grothendieck-1971] -/ +private lemma Aux.of_eq_iSup_basicOpen {M : (Spec R).Modules} (V : (Spec R).Opens) + {ι : Type*} [Finite ι] (g : ι → R) (hg : V = ⨆ i, basicOpen (g i)) + (h₁ : ∀ (i : ι), Aux M (basicOpen (g i))) : + Aux M V := by + have h₂ (i j : ι) : Aux M (basicOpen (g i * g j)) := + .of_le _ (basicOpen_mul_le_left _ _) (h₁ i) + have hgle (i : ι) : basicOpen (g i) ≤ V := by rw [hg]; exact le_iSup_of_le _ le_rfl + have hug (i : ι) (m : ℕ) : + IsUnit (algebraMap R (Module.End R Γ(M, basicOpen (g i))) (g i ^ m)) := by + rw [map_pow] + exact (Scheme.Modules.isUnit_algebraMap_end_of_le_basicOpen (g i) le_rfl).pow m + -- We show existence and uniqueness separately. + refine ⟨fun f hf s ↦ ?_, fun f hf t hs ↦ ?_⟩ + · have hfgi (i : ι) : basicOpen (f * g i) ≤ basicOpen (g i) := basicOpen_mul_le_right f (g i) + let s' (i : ι) : Γ(M, basicOpen (f * g i)) := + M.presheaf.map (homOfLE <| basicOpen_mul_le_left f (g i)).op s + /- By `h₁`, up to a factor of `f ^ N`, the restrictions of `s` to `D(f) ∩ D(gᵢ)` lift + to sections `tᵢ` over `D(gᵢ)`. -/ + obtain ⟨N, t, ht⟩ : ∃ (N : ℕ) (t : ∀ i, Γ(M, basicOpen (g i))), + ∀ i, f ^ N • s' i = M.presheaf.map (homOfLE (basicOpen_mul_le_right f (g i))).op (t i) := by + have (i : ι) : ∃ (n : ℕ) (t : Γ(M, basicOpen (g i))), + f ^ n • s' i = M.presheaf.map (homOfLE (hfgi i)).op t := by + obtain ⟨n, t', ht'⟩ := (h₁ i).existence (f * g i) (hfgi i) (s' i) + rw [mul_pow, mul_smul, smul_comm] at ht' + obtain ⟨ψ, hψ⟩ := IsUnit.exists_right_inv (hug i n) + use n, ψ t' + apply (M.isSMulRegular_of_le_basicOpen (basicOpen_mul_le_right f (g i))).pow n + dsimp + rw [← ht', ← Scheme.Modules.map_smul_Spec] + congr 1 + exact congr($hψ t').symm + choose n t' ht' using this + have (i : ι) : n i ≤ ⨆ i, n i := le_ciSup (Finite.bddAbove_range _) _ + have hN (i : ι) : ⨆ i, n i = ((⨆ i, n i) - n i) + n i := by grind + refine ⟨⨆ i, n i, fun i ↦ f ^ ((⨆ i, n i) - n i) • t' i, fun i ↦ ?_⟩ + conv_lhs => rw [hN i] + rw [pow_add, mul_smul, ht', M.map_smul_Spec] + /- By `h₂`, up to a factor of `f ^ K`, the restrictions of `tᵢ` and `tⱼ` to + to `D(gᵢ) ∩ D(gⱼ)` agree. -/ + obtain ⟨K, hK⟩ : ∃ (K : ℕ), ∀ (i j : ι), + M.presheaf.map (homOfLE (basicOpen_mul_le_left (g i) (g j))).op (f ^ K • t i) = + M.presheaf.map (homOfLE (basicOpen_mul_le_right (g i) (g j))).op (f ^ K • t j) := by + have (i j : ι) : ∃ (m : ℕ), + M.presheaf.map (homOfLE (basicOpen_mul_le_left (g i) (g j))).op (f ^ m • t i) = + M.presheaf.map (homOfLE (basicOpen_mul_le_right (g i) (g j))).op (f ^ m • t j) := by + have := (h₂ i j).uniqueness (f * (g i * g j)) (basicOpen_mul_le_right _ _) + (M.presheaf.map (homOfLE (basicOpen_mul_le_left (g i) (g j))).op (t i) - + M.presheaf.map (homOfLE (basicOpen_mul_le_right (g i) (g j))).op (t j)) ?_ + · obtain ⟨m, hm⟩ := this + use m + apply (M.isSMulRegular_of_le_basicOpen le_rfl).pow m + simpa [M.map_smul_Spec _ (f ^ m), ← mul_smul, ← mul_smul, ← mul_pow, ← mul_comm f, + smul_sub, sub_eq_zero] using hm + · have hfgigi : basicOpen (f * (g i * g j)) ≤ basicOpen (f * g i) := by + rw [← mul_assoc] + exact basicOpen_mul_le_left _ _ + have hfgigj : basicOpen (f * (g i * g j)) ≤ basicOpen (f * g j) := by + rw [mul_comm (g i) (g j), ← mul_assoc] + exact basicOpen_mul_le_left _ _ + rw [map_sub, ← M.presheaf.map_comp_apply, ← op_comp, ← M.presheaf.map_comp_apply, + ← op_comp, homOfLE_comp, homOfLE_comp, ← homOfLE_comp hfgigi (hfgi i), + ← homOfLE_comp hfgigj (hfgi j), op_comp, M.presheaf.map_comp_apply, ← ht i, + M.map_smul_Spec, ← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp, op_comp, + M.presheaf.map_comp_apply, ← ht j, M.map_smul_Spec, ← M.presheaf.map_comp_apply, + ← op_comp, homOfLE_comp] + simp + choose m hm using this + let K := ⨆ i, ⨆ j, m i j + refine ⟨K, fun i j ↦ ?_⟩ + have : m i j ≤ K := + le_ciSup_of_le (Finite.bddAbove_range _) i (le_ciSup (Finite.bddAbove_range _) _) + have : K = (K - m i j) + m i j := by lia + rw [this, pow_add, mul_smul, mul_smul, M.map_smul_Spec, M.map_smul_Spec _ (f ^ (K - m i j)), + hm i j] + -- So up to a factor of `f ^ (N + K)`, the `tᵢ` glue. + refine ⟨N + K, ?_⟩ + have := TopCat.Sheaf.existsUnique_gluing' ⟨_, M.isSheaf⟩ (fun i ↦ basicOpen (g i)) V + (fun i ↦ homOfLE (by rw [hg]; exact le_iSup_of_le _ le_rfl)) (by simp [hg]) + (fun i ↦ f ^ K • t i) ?_ + · obtain ⟨a, ha, -⟩ := this + use a + refine TopCat.Sheaf.eq_of_locally_eq' ⟨_, M.isSheaf⟩ (fun i ↦ basicOpen (f * g i)) _ + (fun i ↦ homOfLE (basicOpen_mul_le_left f (g i))) ?_ _ _ ?_ + · rw [left_eq_inf.mpr hf, hg, inf_iSup_eq] + simp_rw [basicOpen_mul] + exact le_rfl + · intro i + rw [← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp, + ← homOfLE_comp (basicOpen_mul_le_right _ _) (hgle i), op_comp, M.presheaf.map_comp_apply, + M.map_smul_Spec, ha, M.map_smul_Spec, pow_add, mul_smul, smul_comm, ht i] + · intro i j + have : Function.Injective (M.presheaf.map (eqToHom <| (basicOpen_mul (g i) (g j))).op) := + ConcreteCategory.injective_of_mono_of_preservesPullback _ + apply this + dsimp [Opens.infLELeft, Opens.infLERight] + simp_rw [← M.presheaf.map_comp_apply, ← op_comp, eqToHom_comp_homOfLE] + exact hK i j + · have (i : ι) : ∃ (n : ℕ), M.presheaf.map (homOfLE (hgle i)).op (f ^ n • t) = 0 := by + have := (h₁ i).uniqueness (f * g i) (basicOpen_mul_le_right f (g i)) + (M.presheaf.map (homOfLE (hgle i)).op t) ?_ + · obtain ⟨n, hn⟩ := this + use n + rw [mul_pow, mul_comm, mul_smul, ← Scheme.Modules.map_smul_Spec] at hn + exact ((M.isSMulRegular_of_le_basicOpen le_rfl).pow n).right_eq_zero_of_smul hn + · rw [← M.presheaf.map_comp_apply, ← op_comp, homOfLE_comp, + ← homOfLE_comp ((basicOpen_mul_le_left f (g i))) hf, op_comp, M.presheaf.map_comp_apply] + simp [hs] + choose n hn using this + use ⨆ i, n i + apply TopCat.Sheaf.eq_of_locally_eq' ⟨_, M.isSheaf⟩ (fun i ↦ basicOpen (g i)) _ + (fun i ↦ homOfLE (by rw [hg]; exact le_iSup_of_le _ le_rfl)) + · simp [hg] + · intro i + have : n i ≤ ⨆ i, n i := le_ciSup (Finite.bddAbove_range _) _ + have : ⨆ i, n i = ((⨆ i, n i) - n i) + n i := by lia + rw [this, pow_add, mul_smul, Scheme.Modules.map_smul_Spec, hn i] + simp + +private lemma isLocalizing_iff_aux (M : (Spec R).Modules) : + IsLocalizing (modulesSpecToSheaf.obj M) ↔ Aux M ⊤ := by + let φ (f : R) := ((modulesSpecToSheaf.obj M).obj.map (basicOpen f).leTop.op).hom + refine ⟨fun h ↦ ?_, fun h f ↦ IsLocalizedModule.Away.mk_of_addCommGroup ?_ ?_ ?_⟩ + · have hf (f : R) : IsLocalizedModule.Away f (φ f) := h f + refine ⟨fun f hle s ↦ ?_, fun f hle s hs ↦ ?_⟩ + · obtain ⟨n, y, hy⟩ := (hf f).surj _ _ s + use n, y, hy.symm + · obtain ⟨⟨_, n, rfl⟩, hn⟩ := (IsLocalizedModule.eq_zero_iff (.powers f) (φ f)).mp hs + use n, hn + · exact Scheme.Modules.isUnit_algebraMap_end_of_le_basicOpen f le_rfl + · intro x + obtain ⟨n, t, ht⟩ := h.existence _ _ x + use n, t, ht.symm + · intro x hx + obtain ⟨n, hn⟩ := h.uniqueness _ _ _ hx + use n, hn + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +private lemma aux_basicOpen_of_aux_restrict (M : (Spec R).Modules) (g : R) + (h : Aux (M.restrict <| + Spec.map <| CommRingCat.ofHom <| algebraMap R <| Localization.Away g) ⊤) : + Aux M (basicOpen g) := by + let a : R ⟶ CommRingCat.of (Localization.Away g) := + CommRingCat.ofHom <| algebraMap R _ + set ψ : Spec (.of <| Localization.Away g) ⟶ Spec (.of R) := Spec.map a + set M' : (Spec (.of <| Localization.Away g)).Modules := M.restrict ψ + have heq (f : R) (hf : basicOpen f ≤ basicOpen g) : + basicOpen f = ψ ''ᵁ basicOpen (a f) := by + rw [← SpecMap_preimage_basicOpen, Scheme.Hom.image_preimage_eq_opensRange_inf] + simp [a, ψ, hf] + let iso : Γ(M.restrict ψ, ⊤) ≅ Γ(M, basicOpen g) := + M.restrictAppIso _ _ ≪≫ M.presheaf.mapIso (eqToIso <| by simp [ψ, a]).op + let e (f : R) (hf : basicOpen f ≤ basicOpen g) : Γ(M', basicOpen (a f)) ≅ Γ(M, basicOpen f) := + M.restrictAppIso ψ (basicOpen (a f)) ≪≫ M.presheaf.mapIso (eqToIso <| heq f hf).op + refine ⟨fun f hf s ↦ ?_, fun f hf t ht ↦ ?_⟩ + · obtain ⟨n, t, ht⟩ := h.existence (a f) le_top ((e _ hf).inv s) + use n, iso.hom t + have := congr((e _ hf).hom $ht) + dsimp [M'] at this + rw [← ConcreteCategory.comp_apply] at this + simp only [homOfLE_leOfHom, Iso.trans_hom, Functor.mapIso_hom, Iso.op_hom, eqToIso.hom, + eqToHom_op, Iso.trans_inv, Functor.mapIso_inv, Iso.op_inv, eqToIso.inv, e, iso] at this ⊢ + simp only [homOfLE_leOfHom, Scheme.Modules.map_restrictAppIso_hom_assoc, AddCommGrpCat.hom_comp, + AddMonoidHom.coe_comp, Function.comp_apply, ← map_pow, ψ] at this + rw [Scheme.Modules.restrictAppIso_smul_Spec] at this + simpa [← Functor.map_comp_apply, eqToHom_comp_homOfLE_op, homOfLE_op_comp_eqToHom] using this + · obtain ⟨n, hn⟩ := h.uniqueness (a f) le_top (iso.inv t) <| by + simpa [M', iso, ← M.presheaf.map_comp_apply, homOfLE_op_comp_eqToHom, e] using + congr((e _ hf).inv $ht) + use n + have := congr(iso.hom $hn) + dsimp [iso, ψ] at this + rw [eqToHom_op, map_zero, ← map_pow, Scheme.Modules.restrictAppIso_smul_Spec, + M.map_smul_Spec, Iso.inv_hom_id_apply] at this + simpa using this + +end QuasicoherentTilde + +open QuasicoherentTilde in +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- If `M` is a quasi-coherent `𝒪_{Spec R}` module, it is isomorphic to `Γ(M)^~`. -/ +instance Scheme.Modules.isIso_fromTildeΓ_of_isQuasicoherent (M : (Spec R).Modules) + [M.IsQuasicoherent] : IsIso M.fromTildeΓ := by + rw [isIso_fromTildeΓ_iff_isLocalizing, isLocalizing_iff_aux] + obtain ⟨ι, U, pres, hU, hU'⟩ := M.exists_isOpenCover_presentation + obtain ⟨s, hs⟩ := hU.exists_finite_of_compactSpace + choose κ hκ a ha using fun i : s ↦ + PrimeSpectrum.isBasis_basic_opens.exists_iSup_eq_of_isCompact (U i) (hU' i).isCompact + refine Aux.of_eq_iSup_basicOpen _ (fun i : Sigma κ ↦ a _ i.2) ?_ ?_ + · rw [IsOpenCover] at hs + rw [eq_comm, iSup_sigma, ← hs] + exact iSup_congr fun i ↦ (ha i).symm + · intro i + let t := (Spec R).homOfLE (U := PrimeSpectrum.basicOpen (a _ i.2)) (V := U i.1) + (by rw [ha]; exact le_iSup_of_le _ le_rfl) + let iso : restrictFunctor (U i.1).ι ⋙ restrictFunctor ((basicOpenIsoSpecAway _).inv ≫ t) ≅ + restrictFunctor (Spec.map (CommRingCat.ofHom <| algebraMap _ _)) := + (restrictFunctorComp _ _).symm ≪≫ + restrictFunctorCongr (by simp [t, basicOpenIsoSpecAway]) + let pres := SheafOfModules.Presentation.ofIsIso.{u, u, u} (iso.app M).hom <| + presentationRestrict ((basicOpenIsoSpecAway _).inv ≫ t) (pres i.1) + have : IsIso _ := isIso_fromTildeΓ_of_presentation (M.restrict _) pres + rw [isIso_fromTildeΓ_iff_isLocalizing, isLocalizing_iff_aux] at this + exact aux_basicOpen_of_aux_restrict _ _ this + +set_option backward.isDefEq.respectTransparency false in +/-- An `𝒪_{Spec R}` module `M` is quasicoherent if and only if it is isomorphic to `Γ(M)^~`. -/ +theorem isQuasicoherent_iff_isIso_fromTildeΓ (M : (Spec R).Modules) : + M.IsQuasicoherent ↔ IsIso M.fromTildeΓ := by + refine ⟨fun h ↦ inferInstance, fun h ↦ ?_⟩ + exact (SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf).prop_of_iso + (asIso <| M.fromTildeΓ) inferInstance + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma essImage_tilde : (tilde.functor R).essImage = + SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf := by + refine le_antisymm ?_ ?_ + · intro M ⟨N, ⟨e⟩⟩ + exact (SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf).prop_of_iso e + (by dsimp; infer_instance) + · intro M (h : M.IsQuasicoherent) + exact ⟨((modulesSpecToSheaf.obj M).presheaf.obj (.op ⊤)), ⟨asIso <| M.fromTildeΓ⟩⟩ + end IsQuasicoherent end AlgebraicGeometry From 22a6ad55f8437ddf229103cd067d7411feb6038b Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 25 Jun 2026 09:00:38 +0000 Subject: [PATCH 0338/1300] feat: define LinearMap.IsQuasiInverse (#39475) If the name "QuasiInverse" is considered too vague, I am open to suggestions. This was written by @PatrickMassot and @CoolRmal at the May 2026 ICERM workshop as part of the project on Fredholm operators. Co-authored-by: Rmal <97214596+CoolRmal@users.noreply.github.com> --- .../Algebra/Module/LinearMap/FiniteRange.lean | 172 +++++++++++++++++- 1 file changed, 169 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean index ec403ae2982f64..a04166c0c38750 100644 --- a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean +++ b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2026 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Anatole Dedecker +Authors: Patrick Massot, Anatole Dedecker, Yongxi Lin -/ module @@ -32,6 +32,9 @@ In this file, we define: noetherian ring, in which case the two notions agree. This is an instance in the scope `LinearMap.FiniteRangeSetoid`, so opening this scope allows this relation to be denoted by `≈`. +* `LinearMap.IsQuasiInverse`: two linear maps `u` and `v` are **quasi-inverses** if we have + `u ∘ₗ v ≈ id` and `v ∘ₗ u ≈ id` modulo linear maps with noetherian ranges. + -/ @[expose] public section @@ -50,10 +53,12 @@ variable [Semiring K] [AddCommMonoid V₃] [Module K V₃] /-- A linear map **has Noetherian range** if its range is a Noetherian module. -/ -def HasNoetherianRange (f : V →ₗ[K] V₂) := IsNoetherian K f.range +def HasNoetherianRange (f : V →ₗ[K] V₂) : Prop := + IsNoetherian K f.range /-- A linear map **has finite range** if its range is finitely generated. -/ -def HasFiniteRange (f : V →ₗ[K] V₂) := f.range.FG +def HasFiniteRange (f : V →ₗ[K] V₂) : Prop := + f.range.FG lemma hasNoetherianRange_iff_range {f : V →ₗ[K] V₂} : f.HasNoetherianRange ↔ IsNoetherian K f.range := @@ -268,4 +273,165 @@ end FiniteRangeSetoid end Setoid +section QuasiInverse + +variable [CommRing K] + [AddCommGroup V] [Module K V] + [AddCommGroup V₂] [Module K V₂] + [AddCommGroup V₃] [Module K V₃] + +open scoped LinearMap.FiniteRangeSetoid + +/-- `u` is a **left quasi-inverse** to `v` if `u ∘ₗ v ≈ id` modulo +linear maps with noetherian ranges. Recall that if the scalar ring is noetherian +(e.g a field), then "noetherian range" can be replaced by "finitely generated range". -/ +def IsLeftQuasiInverse (u : V →ₗ[K] V₂) (v : V₂ →ₗ[K] V) : Prop := + u ∘ₗ v ≈ .id + +/-- `u` is a **right quasi-inverse** to `v` if `v ∘ₗ u ≈ id` modulo +linear maps with noetherian ranges. Recall that if the scalar ring is noetherian +(e.g a field), then "noetherian range" can be replaced by "finitely generated range". -/ +def IsRightQuasiInverse (u : V₃ →ₗ[K] V₂) (v : V₂ →ₗ[K] V₃) : Prop := + v ∘ₗ u ≈ .id + +/-- `u` is a **quasi-inverse** to `v` if `u ∘ₗ v ≈ id` and `v ∘ₗ u ≈ id` modulo +linear maps with noetherian ranges. Recall that if the scalar ring is noetherian +(e.g a field), then "noetherian range" can be replaced by "finitely generated range". -/ +def IsQuasiInverse (u : V₃ →ₗ[K] V₂) (v : V₂ →ₗ[K] V₃) : Prop := + u.IsLeftQuasiInverse v ∧ u.IsRightQuasiInverse v + +lemma isLeftQuasiInverse_iff_isRightQuasiInverse_swap {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} : + u.IsLeftQuasiInverse v ↔ v.IsRightQuasiInverse u := Iff.rfl + +alias ⟨IsLeftQuasiInverse.isRightQuasiInverse, IsRightQuasiInverse.isLeftQuasiInverse⟩ := + isLeftQuasiInverse_iff_isRightQuasiInverse_swap + +lemma IsLeftQuasiInverse.equiv {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + (h : u.IsLeftQuasiInverse v) : u ∘ₗ v ≈ .id := h + +lemma IsRightQuasiInverse.equiv {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + (h : u.IsRightQuasiInverse v) : v ∘ₗ u ≈ .id := h + +@[symm] +lemma IsQuasiInverse.symm {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + (h : u.IsQuasiInverse v) : v.IsQuasiInverse u := + And.symm h + +@[gcongr] +lemma IsLeftQuasiInverse.congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (h : u.IsLeftQuasiInverse v) (hu : u' ≈ u) (hv : v' ≈ v) : + u'.IsLeftQuasiInverse v' := by + unfold IsLeftQuasiInverse at * + grw [hu, hv] + assumption + +@[gcongr] +lemma isLeftQuasiInverse_congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (hu : u' ≈ u) (hv : v' ≈ v) : + u.IsLeftQuasiInverse v ↔ u'.IsLeftQuasiInverse v' := + ⟨fun H ↦ H.congr hu hv, fun H ↦ H.congr (Setoid.symm hu) (Setoid.symm hv)⟩ + +@[gcongr] +lemma IsRightQuasiInverse.congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (h : u.IsRightQuasiInverse v) (hu : u' ≈ u) (hv : v' ≈ v) : + u'.IsRightQuasiInverse v' := + h.isLeftQuasiInverse.congr hv hu |>.isRightQuasiInverse + +lemma isRightQuasiInverse_congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (hu : u' ≈ u) (hv : v' ≈ v) : + u.IsRightQuasiInverse v ↔ u'.IsRightQuasiInverse v' := + ⟨fun H ↦ H.congr hu hv, fun H ↦ H.congr (Setoid.symm hu) (Setoid.symm hv)⟩ + +@[gcongr] +lemma IsQuasiInverse.congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (h : u.IsQuasiInverse v) (hu : u' ≈ u) (hv : v' ≈ v) : + u'.IsQuasiInverse v' := + ⟨h.1.congr hu hv, h.2.congr hu hv⟩ + +lemma isQuasiInverse_congr {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (hu : u' ≈ u) (hv : v' ≈ v) : + u.IsQuasiInverse v ↔ u'.IsQuasiInverse v' := by + simp [IsQuasiInverse, isLeftQuasiInverse_congr hu hv, isRightQuasiInverse_congr hu hv] + +lemma IsQuasiInverse.equiv_of_left {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (h : u.IsQuasiInverse v) (h' : u'.IsQuasiInverse v') (hu : u ≈ u') : + v ≈ v' := by + calc + v = v ∘ₗ .id := by simp + _ ≈ v ∘ₗ (u' ∘ₗ v') := by grw [h'.1.equiv] + _ ≈ v ∘ₗ (u ∘ₗ v') := by grw [hu] + _ = (v ∘ₗ u) ∘ₗ v' := by rw [comp_assoc] + _ ≈ .id ∘ₗ v' := by grw [h.2.equiv] + _ = v' := by simp + +lemma IsQuasiInverse.equiv_of_right {u u' : V₃ →ₗ[K] V₂} {v v' : V₂ →ₗ[K] V₃} + (h : u.IsQuasiInverse v) (h' : u'.IsQuasiInverse v') (hv : v ≈ v') : + u ≈ u' := + h.symm.equiv_of_left h'.symm hv + +/-- Left quasi-inverses compose in the opposite order. -/ +lemma IsLeftQuasiInverse.comp {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} {u' : V₂ →ₗ[K] V} + {v' : V₃ →ₗ[K] V₂} (hu : u'.IsLeftQuasiInverse u) (hv : v'.IsLeftQuasiInverse v) : + (u' ∘ₗ v').IsLeftQuasiInverse (v ∘ₗ u) := + calc + _ = u' ∘ₗ (v' ∘ₗ v) ∘ₗ u := rfl + _ ≈ u' ∘ₗ .id ∘ₗ u := by grw [hv.equiv] + _ ≈ .id := hu.equiv + +/-- Right quasi-inverses compose in the opposite order. -/ +lemma IsRightQuasiInverse.comp {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} {u' : V₂ →ₗ[K] V} + {v' : V₃ →ₗ[K] V₂} (hu : u'.IsRightQuasiInverse u) (hv : v'.IsRightQuasiInverse v) : + (u' ∘ₗ v').IsRightQuasiInverse (v ∘ₗ u) := + hv.isLeftQuasiInverse.comp hu.isLeftQuasiInverse |>.isRightQuasiInverse + +/-- Quasi-inverses compose in the opposite order. -/ +lemma IsQuasiInverse.comp {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} {u' : V₂ →ₗ[K] V} + {v' : V₃ →ₗ[K] V₂} (hu : u'.IsQuasiInverse u) (hv : v'.IsQuasiInverse v) : + (u' ∘ₗ v').IsQuasiInverse (v ∘ₗ u) := + ⟨hu.1.comp hv.1, hu.2.comp hv.2⟩ + +/-- If `u'` is a right quasi-inverse of `u` and `w` is a left quasi-inverse of `v ∘ₗ u`, +then `u ∘ₗ w` is a left quasi-inverse of `v`. -/ +lemma IsLeftQuasiInverse.of_comp_left {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + {u' : V₂ →ₗ[K] V} {w : V₃ →ₗ[K] V} (hu : u'.IsRightQuasiInverse u) + (hw : w.IsLeftQuasiInverse (v ∘ₗ u)) : + (u ∘ₗ w).IsLeftQuasiInverse v := by + calc + _ = ((u ∘ₗ w) ∘ₗ v) ∘ₗ .id := rfl + _ ≈ ((u ∘ₗ w) ∘ₗ v) ∘ₗ (u ∘ₗ u') := by grw [hu.equiv] + _ = u ∘ₗ (w ∘ₗ (v ∘ₗ u)) ∘ₗ u' := rfl + _ ≈ u ∘ₗ .id ∘ₗ u' := by grw [hw.equiv] + _ ≈ .id := hu.equiv + +/-- If `u'` is a quasi-inverse of `u` and `w` is a quasi-inverse of `v ∘ₗ u`, then +`u ∘ₗ w` is a quasi-inverse of `v`. -/ +lemma IsQuasiInverse.of_comp_left {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + {u' : V₂ →ₗ[K] V} {w : V₃ →ₗ[K] V} (hu : u'.IsQuasiInverse u) + (hw : w.IsQuasiInverse (v ∘ₗ u)) : + (u ∘ₗ w).IsQuasiInverse v := + ⟨.of_comp_left hu.2 hw.1, hw.2⟩ + +/-- If `v'` is a left quasi-inverse of `v` and `w` is a right quasi-inverse of `v ∘ₗ u`, +then `w ∘ₗ v` is a right quasi-inverse of `u`. -/ +lemma IsRightQuasiInverse.of_comp_right {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + {v' : V₃ →ₗ[K] V₂} {w : V₃ →ₗ[K] V} (hv : v'.IsLeftQuasiInverse v) + (hw : w.IsRightQuasiInverse (v ∘ₗ u)) : + (w ∘ₗ v).IsRightQuasiInverse u := by + calc + _ = .id ∘ₗ (u ∘ₗ (w ∘ₗ v)) := rfl + _ ≈ (v' ∘ₗ v) ∘ₗ (u ∘ₗ (w ∘ₗ v)) := by grw [hv.equiv] + _ = v' ∘ₗ ((v ∘ₗ u) ∘ₗ w) ∘ₗ v := rfl + _ ≈ v' ∘ₗ .id ∘ₗ v := by grw [hw.equiv] + _ ≈ .id := hv.equiv + +/-- If `v'` is a quasi-inverse of `v` and `w` is a quasi-inverse of `v ∘ₗ u`, then +`w ∘ₗ v` is a quasi-inverse of `u`. -/ +lemma IsQuasiInverse.of_comp_right {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} + {v' : V₃ →ₗ[K] V₂} {w : V₃ →ₗ[K] V} (hv : v'.IsQuasiInverse v) + (hw : w.IsQuasiInverse (v ∘ₗ u)) : + (w ∘ₗ v).IsQuasiInverse u := + ⟨hw.1, IsRightQuasiInverse.of_comp_right hv.1 hw.2⟩ + +end QuasiInverse + end LinearMap From b8ddb2552a4c4746d01b48ccbfc3549d7f2f9627 Mon Sep 17 00:00:00 2001 From: Leo Diedering <129694072+ldiedering@users.noreply.github.com> Date: Thu, 25 Jun 2026 09:10:25 +0000 Subject: [PATCH 0339/1300] refactor(MeasureTheory/Measure/Typeclasses/NoAtoms): add deprecation for `NoAtoms` (#40815) Add module deprecation for `MeasureTheory/Measure/Typeclasses/NoAtoms`. --- Mathlib.lean | 1 + Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean diff --git a/Mathlib.lean b/Mathlib.lean index be8188b36cd456..26884b65969460 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5595,6 +5595,7 @@ public import Mathlib.MeasureTheory.Measure.TightNormed public import Mathlib.MeasureTheory.Measure.Tilted public import Mathlib.MeasureTheory.Measure.Trim public import Mathlib.MeasureTheory.Measure.Typeclasses.Finite +public import Mathlib.MeasureTheory.Measure.Typeclasses.NoAtoms public import Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass public import Mathlib.MeasureTheory.Measure.Typeclasses.Probability public import Mathlib.MeasureTheory.Measure.Typeclasses.SFinite diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean new file mode 100644 index 00000000000000..10b58e0c999fe1 --- /dev/null +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/NoAtoms.lean @@ -0,0 +1,9 @@ +module + +/-! # NoAtoms +This file is deprecated. Please use `Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass` +instead. +-/ + +deprecated_module "use Mathlib.MeasureTheory.Measure.Typeclasses.NullSingletonClass instead" + (since := "2026-06-19") From 25e35a45b208f060b7165770fc7f723b8b92a53e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 25 Jun 2026 09:10:27 +0000 Subject: [PATCH 0340/1300] feat(Algebra/Homology): the bounded below derived category (#40944) In this PR, we show that the bounded below derived category is the localization of the bounded below homotopy category with respect to quasi-isomorphisms. --- Mathlib.lean | 1 + .../Homology/DerivedCategory/Basic.lean | 2 +- .../DerivedCategory/HomologySequence.lean | 16 ++ .../Homology/DerivedCategory/Plus.lean | 228 ++++++++++++++++++ .../Homology/DerivedCategory/TStructure.lean | 1 - .../Homology/HomotopyCategory/Plus.lean | 60 ++++- 6 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 Mathlib/Algebra/Homology/DerivedCategory/Plus.lean diff --git a/Mathlib.lean b/Mathlib.lean index 26884b65969460..4017194f141030 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -589,6 +589,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.HomologySequence public import Mathlib.Algebra.Homology.DerivedCategory.KInjective public import Mathlib.Algebra.Homology.DerivedCategory.KProjective public import Mathlib.Algebra.Homology.DerivedCategory.Linear +public import Mathlib.Algebra.Homology.DerivedCategory.Plus public import Mathlib.Algebra.Homology.DerivedCategory.ShortExact public import Mathlib.Algebra.Homology.DerivedCategory.SingleTriangle public import Mathlib.Algebra.Homology.DerivedCategory.SmallShiftedHom diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean index 72369bf49d4c35..d78c2f9f096135 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean @@ -237,7 +237,7 @@ their compatibilities with shifts. -/ def singleFunctors : SingleFunctors C (DerivedCategory C) ℤ := (HomotopyCategory.singleFunctors C).postcomp Qh -/-- The shift functor `C ⥤ DerivedCategory C` which sends `X : C` to the +/-- The single functor `C ⥤ DerivedCategory C` which sends `X : C` to the single cochain complex with `X` sitting in degree `n : ℤ`. -/ abbrev singleFunctor (n : ℤ) := (singleFunctors C).functor n diff --git a/Mathlib/Algebra/Homology/DerivedCategory/HomologySequence.lean b/Mathlib/Algebra/Homology/DerivedCategory/HomologySequence.lean index 8ca61a1c2e2c22..0a5406598d9864 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/HomologySequence.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/HomologySequence.lean @@ -85,6 +85,22 @@ lemma isIso_Qh_map_iff {X Y : HomotopyCategory C (ComplexShape.up ℤ)} (f : X infer_instance · exact Localization.inverts Qh (HomotopyCategory.quasiIso _ _) _ +lemma isIso_iff {K L : DerivedCategory C} (f : K ⟶ L) : + IsIso f ↔ ∀ (n : ℤ), IsIso ((homologyFunctor C n).map f) := by + refine ⟨fun hf n ↦ inferInstance, fun hf ↦ ?_⟩ + refine ((MorphismProperty.isomorphisms (DerivedCategory C)).arrow_iso_iff + (Qh.mapArrow.objObjPreimageIso (Arrow.mk f))).1 ?_ + let g := Qh.mapArrow.objPreimage (Arrow.mk f) + change IsIso (Qh.map g.hom) + rw [isIso_Qh_map_iff, HomotopyCategory.mem_quasiIso_iff] + intro n + have e : Arrow.mk ((homologyFunctor C n).map f) ≅ + Arrow.mk ((HomotopyCategory.homologyFunctor _ _ n).map g.hom) := + ((homologyFunctor C n).mapArrow.mapIso + ((Qh.mapArrow.objObjPreimageIso (Arrow.mk f)).symm)) ≪≫ + ((Functor.mapArrowFunctor _ _).mapIso (homologyFunctorFactorsh C n)).app (Arrow.mk g.hom) + exact ((MorphismProperty.isomorphisms C).arrow_iso_iff e).1 (hf n) + instance (n : ℤ) : (homologyFunctor C n).IsHomological := Functor.isHomological_of_localization Qh (homologyFunctor C n) _ (homologyFunctorFactorsh C n) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Plus.lean b/Mathlib/Algebra/Homology/DerivedCategory/Plus.lean new file mode 100644 index 00000000000000..72b30ddd52edf2 --- /dev/null +++ b/Mathlib/Algebra/Homology/DerivedCategory/Plus.lean @@ -0,0 +1,228 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.KInjective +public import Mathlib.Algebra.Homology.DerivedCategory.TStructure +public import Mathlib.Algebra.Homology.HomotopyCategory.Plus +public import Mathlib.CategoryTheory.Triangulated.LocalizingSubcategory +public import Mathlib.CategoryTheory.Triangulated.TStructure.Induced + +/-! +# The bounded below derived category + +Let `C` be an abelian category. In this file, we show that +the bounded below derived category `DerivedCategory.Plus C` (defined +as a full subcategory of `DerivedCategory C`) is the localization +of the bounded below homotopy category `HomotopyCategory.Plus C` +with respect to quasi-isomorphisms. + +-/ + +@[expose] public section + +open CategoryTheory Category Triangulated Limits + +variable {C : Type*} [Category* C] [Abelian C] + +namespace HomotopyCategory.Plus + +variable (C) + +/-- The property of objects in `HomotopyCategory.Plus C` that is satisfied +by acyclic complexes. -/ +abbrev subcategoryAcyclic : + ObjectProperty (HomotopyCategory.Plus C) := + (HomotopyCategory.subcategoryAcyclic C).inverseImage (HomotopyCategory.Plus.ι C) + +set_option backward.defeqAttrib.useBackward true in +lemma quasiIso_eq_subcategoryAcyclic_trW : + HomotopyCategory.Plus.quasiIso C = (subcategoryAcyclic C).trW := by + ext K L f + obtain ⟨M, g, h, mem⟩ := CategoryTheory.Pretriangulated.distinguished_cocone_triangle f + have := (HomotopyCategory.subcategoryAcyclic C).trW_iff_of_distinguished _ + ((HomotopyCategory.Plus.ι C).map_distinguished _ mem) + rw [← HomotopyCategory.quasiIso_eq_trW_subcategoryAcyclic] at this + rwa [dsimp% (subcategoryAcyclic C).trW_iff_of_distinguished _ mem] + +end HomotopyCategory.Plus + +namespace DerivedCategory + +open TStructure + +variable [HasDerivedCategory C] + +namespace Plus + +/-- The localization functor `HomotopyCategory.Plus C ⥤ DerivedCategory.Plus C`. -/ +noncomputable def Qh : HomotopyCategory.Plus C ⥤ Plus C := + t.plus.lift (HomotopyCategory.Plus.ι _ ⋙ DerivedCategory.Qh) (by + rintro ⟨K, hK⟩ + obtain ⟨K, rfl⟩ := HomotopyCategory.quotient_obj_surjective K + obtain ⟨n, _⟩ := (HomotopyCategory.plus_quotient_obj_iff _).mp hK + exact ⟨n, t.isGE_of_iso ((quotientCompQhIso C).symm.app K) n⟩) + +noncomputable instance : (Qh : _ ⥤ Plus C).CommShift ℤ := by + dsimp only [Qh] + infer_instance + +set_option backward.isDefEq.respectTransparency false in +instance : (Qh : _ ⥤ Plus C).IsTriangulated := by + dsimp only [Qh] + infer_instance + +set_option backward.isDefEq.respectTransparency false in +lemma Qh_map_bijective_of_isKInjective (K L : HomotopyCategory.Plus C) + (_ : CochainComplex.IsKInjective L.1.as) : Function.Bijective (Qh.map : (K ⟶ L) → _) := by + have := CochainComplex.IsKInjective.Qh_map_bijective K.1 L.1.as + rw [← Function.Bijective.of_comp_iff _ + ((HomotopyCategory.Plus.fullyFaithfulι C).map_bijective _ _)] at this + rwa [← Function.Bijective.of_comp_iff' (t.plus.fullyFaithfulι.map_bijective _ _)] + +instance : (HomotopyCategory.plus C).IsVerdierRightLocalizing + (HomotopyCategory.subcategoryAcyclic C) where + fac {K L} φ hK hL := by + obtain ⟨K : CochainComplex _ _, rfl⟩ := HomotopyCategory.quotient_obj_surjective K + obtain ⟨L : CochainComplex _ _, rfl⟩ := HomotopyCategory.quotient_obj_surjective L + simp only [HomotopyCategory.plus_quotient_obj_iff] at hL + obtain ⟨n, hn⟩ := hL + obtain ⟨φ, rfl⟩ := (HomotopyCategory.quotient _ _).map_surjective φ + rw [HomotopyCategory.quotient_obj_mem_subcategoryAcyclic_iff_acyclic] at hK + refine ⟨(HomotopyCategory.quotient _ _).obj (K.truncGE n), + (HomotopyCategory.quotient _ _).map (K.πTruncGE n), + (HomotopyCategory.quotient _ _).map (CochainComplex.truncGEMap φ n ≫ inv (L.πTruncGE n)), + ?_, ?_, by simp [← Functor.map_comp]⟩ + · simp only [HomotopyCategory.plus_quotient_obj_iff] + exact ⟨n, inferInstance⟩ + · rw [HomotopyCategory.quotient_obj_mem_subcategoryAcyclic_iff_acyclic] + exact hK.truncGE _ + +variable (C) + +/-- The functor `DerivedCategory.Plus.Qh : HomotopyCategory.Plus C ⥤ DerivedCategory.Plus C` +is induced by `DerivedCategory.Qh : HomotopyCategory C (.up ℤ) ⥤ DerivedCategory C`. -/ +noncomputable def QhCompιIsoιCompQh : + Qh ⋙ Plus.ι ≅ HomotopyCategory.Plus.ι C ⋙ DerivedCategory.Qh := Iso.refl _ + +instance : (Qh (C := C)).EssSurj where + mem_essImage := by + intro ⟨X, n, K, e, h⟩ + refine ⟨⟨(HomotopyCategory.quotient C (ComplexShape.up ℤ)).obj K, ?_⟩, + ⟨Plus.ι.preimageIso ((quotientCompQhIso C).app _ ≪≫ e.symm)⟩⟩ + simp only [HomotopyCategory.plus_quotient_obj_iff] + exact ⟨n, h⟩ + +instance : Qh.IsLocalization (HomotopyCategory.Plus.subcategoryAcyclic C).trW := + ((HomotopyCategory.plus C).triangulatedLocalizerMorphism + (HomotopyCategory.subcategoryAcyclic C)).isLocalization_of_isLocalizedFullyFaithful + (QhCompιIsoιCompQh C).symm + +instance : Qh.IsLocalization (HomotopyCategory.Plus.quasiIso C) := by + rw [HomotopyCategory.Plus.quasiIso_eq_subcategoryAcyclic_trW] + infer_instance + +/-- The single functors `C ⥤ DerivedCategory.Plus C` for all `n : ℤ` along with +their compatibilities with shifts. -/ +noncomputable def singleFunctors : SingleFunctors C (Plus C) ℤ := + SingleFunctors.lift (DerivedCategory.singleFunctors C) Plus.ι + (fun n => t.plus.lift (DerivedCategory.singleFunctor C n) + (fun _ => ⟨n, inferInstance⟩)) + (fun _ => Iso.refl _) + +/-- The single functor `C ⥤ DerivedCategory.Plus C` which sends `X : C` to the +single cochain complex with `X` sitting in degree `n : ℤ`. -/ +noncomputable abbrev singleFunctor (n : ℤ) : C ⥤ Plus C := (singleFunctors C).functor n + +/-- The single functors on `DerivedCategory.Plus C` are induced by the +single functors on `DerivedCategory C`. -/ +noncomputable def singleFunctorιIso (n : ℤ) : + singleFunctor C n ⋙ Plus.ι ≅ DerivedCategory.singleFunctor C n := + Iso.refl _ + +instance (n : ℤ) : (singleFunctor C n).Additive := by + dsimp [singleFunctor, singleFunctors] + infer_instance + +/-- The homology functor `DerivedCategory.Plus C ⥤ C` in degree `n : ℤ`. -/ +noncomputable def homologyFunctor (n : ℤ) : Plus C ⥤ C := + Plus.ι ⋙ DerivedCategory.homologyFunctor C n +deriving Functor.IsHomological + +instance : (Qh (C := C)).mapArrow.EssSurj := + Localization.essSurj_mapArrow _ + (HomotopyCategory.Plus.subcategoryAcyclic C).trW + +variable {C} + +/-- The canonical t-structure on `DerivedCategory.Plus C`. -/ +noncomputable abbrev TStructure.t : TStructure (DerivedCategory.Plus C) := + (DerivedCategory.TStructure.t (C := C)).plus.tStructure DerivedCategory.TStructure.t + +/-- Given `X : DerivedCategory.Plus C` and `n : ℤ`, this property means +that `X` is `≥ n` for the canonical t-structure. -/ +abbrev IsGE (X : Plus C) (n : ℤ) : Prop := Plus.TStructure.t.IsGE X n + +/-- Given `X : DerivedCategory.Plus C` and `n : ℤ`, this property means +that `X` is `≤ n` for the canonical t-structure. -/ +abbrev IsLE (X : Plus C) (n : ℤ) : Prop := Plus.TStructure.t.IsLE X n + +lemma isGE_ι_obj_iff (X : Plus C) (n : ℤ) : + (ι.obj X).IsGE n ↔ X.IsGE n := by + constructor + all_goals exact fun h ↦ ⟨h.1⟩ + +lemma isLE_ι_obj_iff (X : Plus C) (n : ℤ) : + (ι.obj X).IsLE n ↔ X.IsLE n := by + constructor + all_goals exact fun h ↦ ⟨h.1⟩ + +instance (X : Plus C) (n : ℤ) [X.IsGE n] : (ι.obj X).IsGE n := by + rw [isGE_ι_obj_iff] + infer_instance + +instance (X : Plus C) (n : ℤ) [X.IsLE n] : (ι.obj X).IsLE n := by + rw [isLE_ι_obj_iff] + infer_instance + +noncomputable instance : (DerivedCategory.Plus.homologyFunctor C 0).ShiftSequence ℤ := + inferInstanceAs ((ι ⋙ DerivedCategory.homologyFunctor C 0).ShiftSequence ℤ) + +instance (X : C) (n : ℤ) : ((singleFunctor C n).obj X).IsGE n := by + rw [← isGE_ι_obj_iff] + change DerivedCategory.TStructure.t.IsGE ((DerivedCategory.singleFunctor C n).obj X) n + infer_instance + +instance (X : C) (n : ℤ) : ((singleFunctor C n).obj X).IsLE n := by + rw [← isLE_ι_obj_iff] + change DerivedCategory.TStructure.t.IsLE ((DerivedCategory.singleFunctor C n).obj X) n + infer_instance + +lemma isZero_homology_of_isGE + (X : Plus C) (n : ℤ) [X.IsGE n] (i : ℤ) (hi : i < n) : + IsZero ((homologyFunctor C i).obj X) := + (ι.obj X).isZero_of_isGE n i hi + +lemma isZero_homology_of_isLE + (X : Plus C) (n : ℤ) [X.IsLE n] (i : ℤ) (hi : n < i) : + IsZero ((homologyFunctor C i).obj X) := + (ι.obj X).isZero_of_isLE n i hi + +lemma isIso_iff {X Y : Plus C} (f : X ⟶ Y) : + IsIso f ↔ ∀ (n : ℤ), IsIso ((homologyFunctor C n).map f) := by + refine ⟨fun _ _ ↦ inferInstance, fun _ ↦ ?_⟩ + have : IsIso (ι.map f) := by rwa [DerivedCategory.isIso_iff] + exact isIso_of_fully_faithful ι _ + +/-- The localization functor `CochainComplex.Plus C ⥤ DerivedCategory.Plus C`. -/ +noncomputable def Q : CochainComplex.Plus C ⥤ DerivedCategory.Plus C := + HomotopyCategory.Plus.quotient C ⋙ Qh + +-- TODO: show that `Q` is indeed a localization functor with respect to quasi-isomorphisms + +end Plus + +end DerivedCategory diff --git a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean index 8ee57cc096ea31..1cc81f41cfa053 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean @@ -193,7 +193,6 @@ lemma exists_iso_singleFunctor_obj_of_isGE_of_isLE obtain ⟨Y, ⟨e'⟩⟩ := CochainComplex.exists_iso_single K n exact ⟨Y, ⟨e ≪≫ Q.mapIso e'⟩⟩ - open DerivedCategory.TStructure variable (C) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean index 505b25c297c77f..352d3a8ee1bca5 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean @@ -23,7 +23,7 @@ of `HomotopyCategory C (.up ℤ)` consisting of bounded below cochain complexes. open CategoryTheory Limits ZeroObject Pretriangulated HomotopicalAlgebra -variable (C : Type*) [Category* C] [Preadditive C] +variable (C D : Type*) [Category* C] [Category* D] [Preadditive C] [Preadditive D] (A : Type*) [Category* A] [Abelian A] namespace CochainComplex @@ -248,3 +248,61 @@ end end Plus end HomotopyCategory + +namespace CategoryTheory + +namespace Functor + +variable {C D} +variable (F : C ⥤ D) [F.Additive] + +set_option backward.defeqAttrib.useBackward true in +/-- The functor between bounded below homotopy categories that is induced +by an additive functor. -/ +def mapHomotopyCategoryPlus : HomotopyCategory.Plus C ⥤ HomotopyCategory.Plus D := + (HomotopyCategory.plus D).lift + (HomotopyCategory.Plus.ι C ⋙ F.mapHomotopyCategory (ComplexShape.up ℤ)) (by + rintro ⟨X, hX⟩ + obtain ⟨K, rfl⟩ := HomotopyCategory.quotient_obj_surjective X + dsimp + simp only [HomotopyCategory.plus_quotient_obj_iff] at hX ⊢ + obtain ⟨n, _⟩ := hX + exact ⟨n, inferInstanceAs (CochainComplex.IsStrictlyGE + ((F.mapHomologicalComplex _).obj K) n)⟩) + +noncomputable instance : + F.mapHomotopyCategoryPlus.CommShift ℤ := + inferInstanceAs (((HomotopyCategory.plus D).lift (HomotopyCategory.Plus.ι C ⋙ + F.mapHomotopyCategory (.up ℤ)) _).CommShift ℤ) + +set_option backward.isDefEq.respectTransparency false in +instance [HasZeroObject C] [HasBinaryBiproducts C] [HasZeroObject D] [HasBinaryBiproducts D] : + (F.mapHomotopyCategoryPlus).IsTriangulated := by + dsimp only [mapHomotopyCategoryPlus] + infer_instance + +instance [Full F] [Faithful F] : Full F.mapHomotopyCategoryPlus where + map_surjective f := + ⟨ObjectProperty.homMk ((F.mapHomotopyCategory _).preimage f.hom), by + ext + exact (F.mapHomotopyCategory _).map_preimage f.hom⟩ + +instance [Full F] [Faithful F] : Faithful F.mapHomotopyCategoryPlus where + map_injective h := by + ext + exact (F.mapHomotopyCategory _).map_injective ((ObjectProperty.ι _).congr_map h) + +/-- Given additive functors that are related by an isomorphism `F ⋙ G ≅ H`, this is +the corresponding isomorphism on the corresponding functor between +the bounded below homotopy categories. -/ +def mapHomotopyCategoryPlusCompIso {E : Type*} [Category* E] [Preadditive E] + {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} (e : F ⋙ G ≅ H) + [F.Additive] [G.Additive] [H.Additive] : + F.mapHomotopyCategoryPlus ⋙ G.mapHomotopyCategoryPlus ≅ H.mapHomotopyCategoryPlus := + ((HomotopyCategory.plus _).fullyFaithfulι.whiskeringRight _).preimageIso + (isoWhiskerLeft (HomotopyCategory.Plus.ι C) + (mapHomotopyCategoryCompIso e (.up ℤ))) + +end Functor + +end CategoryTheory From a8d8ebb9327970a699d0d5eb3ce0ddf275bfd4f6 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Thu, 25 Jun 2026 09:58:27 +0000 Subject: [PATCH 0341/1300] chore(CategoryTheory/Limits/Shapes/Pullbacks/HasPullback): fix typo (#41024) Change definition `pullback.desc'` (which is about pushouts) to `pushout.desc'`. Co-authored-by: morel --- .../Limits/Shapes/Pullback/HasPullback.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean index 3cf75a355296f5..ad855e72608a3d 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean @@ -194,16 +194,19 @@ theorem pushout.inr_desc {W X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} [HasPushout f `l : W ⟶ pullback f g` such that `l ≫ pullback.fst = h` and `l ≫ pullback.snd = k`. -/ def pullback.lift' {W X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasPullback f g] (h : W ⟶ X) (k : W ⟶ Y) (w : h ≫ f = k ≫ g) : - { l : W ⟶ pullback f g // l ≫ pullback.fst f g = h ∧ l ≫ pullback.snd f g = k } := + { l : W ⟶ pullback f g // l ≫ pullback.fst f g = h ∧ l ≫ pullback.snd f g = k } := ⟨pullback.lift h k w, pullback.lift_fst _ _ _, pullback.lift_snd _ _ _⟩ /-- A pair of morphisms `h : Y ⟶ W` and `k : Z ⟶ W` satisfying `f ≫ h = g ≫ k` induces a morphism `l : pushout f g ⟶ W` such that `pushout.inl _ _ ≫ l = h` and `pushout.inr _ _ ≫ l = k`. -/ -def pullback.desc' {W X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} [HasPushout f g] (h : Y ⟶ W) (k : Z ⟶ W) +def pushout.desc' {W X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} [HasPushout f g] (h : Y ⟶ W) (k : Z ⟶ W) (w : f ≫ h = g ≫ k) : - { l : pushout f g ⟶ W // pushout.inl _ _ ≫ l = h ∧ pushout.inr _ _ ≫ l = k } := + { l : pushout f g ⟶ W // pushout.inl _ _ ≫ l = h ∧ pushout.inr _ _ ≫ l = k } := ⟨pushout.desc h k w, pushout.inl_desc _ _ _, pushout.inr_desc _ _ _⟩ +@[deprecated (since := "2026-06-25")] +alias CategoryTheory.Limits.pullback.desc' := pushout.desc' + @[reassoc] theorem pullback.condition {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasPullback f g] : pullback.fst f g ≫ f = pullback.snd f g ≫ g := From 50a441759cb137dbfc5ee2b83a8b42115e4ce0e4 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Thu, 25 Jun 2026 10:21:48 +0000 Subject: [PATCH 0342/1300] chore(CategoryTheory): lemmas for morphisms into colimits (#41011) We add some variants of lemmas with presentability replaced by `Hom(X, _)` preserving certain colimits. From Proetale. --- Mathlib/CategoryTheory/Presentable/Basic.lean | 61 ++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Presentable/Basic.lean b/Mathlib/CategoryTheory/Presentable/Basic.lean index 36fd4d00df525e..f1d14fbe781e7c 100644 --- a/Mathlib/CategoryTheory/Presentable/Basic.lean +++ b/Mathlib/CategoryTheory/Presentable/Basic.lean @@ -237,35 +237,80 @@ lemma isCardinalPresentable_iff_of_isEquivalence · intro infer_instance +section + +variable {J : Type*} [Category* J] {D : J ⥤ C} + +lemma Limits.exists_hom_of_preservesColimit_coyoneda {c : Cocone D} (hc : IsColimit c) {X : C} + [PreservesColimit D (coyoneda.obj (.op X))] (f : X ⟶ c.pt) : + ∃ (j : J) (p : X ⟶ D.obj j), p ≫ c.ι.app j = f := + Types.jointly_surjective_of_isColimit (isColimitOfPreserves (coyoneda.obj (.op X)) hc) f + +lemma Limits.exists_eq_of_preservesColimit_coyoneda [IsFiltered J] {c : Cocone D} + (hc : IsColimit c) {X : C} [PreservesColimit D (coyoneda.obj (.op X))] + {i j : J} (f : X ⟶ D.obj i) (g : X ⟶ D.obj j) (h : f ≫ c.ι.app i = g ≫ c.ι.app j) : + ∃ (k : J) (u : i ⟶ k) (v : j ⟶ k), f ≫ D.map u = g ≫ D.map v := + (Types.FilteredColimit.isColimit_eq_iff _ (isColimitOfPreserves (coyoneda.obj (.op X)) hc)).mp h + +lemma Limits.exists_eq_of_preservesColimit_coyoneda_self [IsFiltered J] {c : Cocone D} + (hc : IsColimit c) {X : C} [PreservesColimit D (coyoneda.obj (.op X))] + {i : J} (f g : X ⟶ D.obj i) (h : f ≫ c.ι.app i = g ≫ c.ι.app i) : + ∃ (j : J) (a : i ⟶ j), f ≫ D.map a = g ≫ D.map a := + (Types.FilteredColimit.isColimit_eq_iff' + (isColimitOfPreserves (coyoneda.obj (.op X)) hc) f g).mp h + +lemma Limits.exists_hom_of_preservesColimit_yoneda {c : Cone D} (hc : IsLimit c) {X : C} + [PreservesColimit D.op (yoneda.obj X)] (f : c.pt ⟶ X) : + ∃ (j : J) (p : D.obj j ⟶ X), c.π.app j ≫ p = f := by + obtain ⟨j, p, hp⟩ := Types.jointly_surjective_of_isColimit + (isColimitOfPreserves (yoneda.obj X) hc.op) f + exact ⟨j.unop, p, hp⟩ + +lemma Limits.exists_eq_of_preservesColimit_yoneda [IsCofiltered J] {c : Cone D} (hc : IsLimit c) + {X : C} [PreservesColimit D.op (yoneda.obj X)] + {i j : J} (f : D.obj i ⟶ X) (g : D.obj j ⟶ X) (h : c.π.app i ≫ f = c.π.app j ≫ g) : + ∃ (k : J) (u : k ⟶ i) (v : k ⟶ j), D.map u ≫ f = D.map v ≫ g := by + obtain ⟨k, u, v, huv⟩ := + (Types.FilteredColimit.isColimit_eq_iff _ (isColimitOfPreserves (yoneda.obj X) hc.op)).mp h + exact ⟨k.unop, u.unop, v.unop, huv⟩ + +lemma Limits.exists_eq_of_preservesColimit_yoneda_self [IsCofiltered J] {c : Cone D} + (hc : IsLimit c) {X : C} [PreservesColimit D.op (yoneda.obj X)] + {i : J} (f g : D.obj i ⟶ X) (h : c.π.app i ≫ f = c.π.app i ≫ g) : + ∃ (j : J) (a : j ⟶ i), D.map a ≫ f = D.map a ≫ g := by + obtain ⟨j, a, ha⟩ := (Types.FilteredColimit.isColimit_eq_iff' + (isColimitOfPreserves (yoneda.obj X) hc.op) f g).mp h + exact ⟨j.unop, a.unop, ha⟩ + variable {X} in lemma IsCardinalPresentable.exists_hom_of_isColimit [IsCardinalPresentable X κ] - {J : Type u₂} [Category.{v₂} J] [EssentiallySmall.{w} J] [IsCardinalFiltered J κ] + [EssentiallySmall.{w} J] [IsCardinalFiltered J κ] {F : J ⥤ C} {c : Cocone F} (hc : IsColimit c) (f : X ⟶ c.pt) : ∃ (j : J) (f' : X ⟶ F.obj j), f' ≫ c.ι.app j = f := by have := preservesColimitsOfShape_of_isCardinalPresentable_of_essentiallySmall X κ J - exact Types.jointly_surjective_of_isColimit (isColimitOfPreserves (coyoneda.obj (op X)) hc) f + exact exists_hom_of_preservesColimit_coyoneda hc f variable {X} in lemma IsCardinalPresentable.exists_eq_of_isColimit [IsCardinalPresentable X κ] - {J : Type u₂} [Category.{v₂} J] [EssentiallySmall.{w} J] [IsCardinalFiltered J κ] + [EssentiallySmall.{w} J] [IsCardinalFiltered J κ] {F : J ⥤ C} {c : Cocone F} (hc : IsColimit c) {i₁ i₂ : J} (f₁ : X ⟶ F.obj i₁) (f₂ : X ⟶ F.obj i₂) (hf : f₁ ≫ c.ι.app i₁ = f₂ ≫ c.ι.app i₂) : ∃ (j : J) (u : i₁ ⟶ j) (v : i₂ ⟶ j), f₁ ≫ F.map u = f₂ ≫ F.map v := by have := preservesColimitsOfShape_of_isCardinalPresentable_of_essentiallySmall X κ J have := isFiltered_of_isCardinalFiltered J κ - exact (Types.FilteredColimit.isColimit_eq_iff _ - (isColimitOfPreserves (coyoneda.obj (op X)) hc)).1 hf + exact exists_eq_of_preservesColimit_coyoneda hc f₁ f₂ hf variable {X} in lemma IsCardinalPresentable.exists_eq_of_isColimit' [IsCardinalPresentable X κ] - {J : Type u₂} [Category.{v₂} J] [EssentiallySmall.{w} J] [IsCardinalFiltered J κ] + [EssentiallySmall.{w} J] [IsCardinalFiltered J κ] {F : J ⥤ C} {c : Cocone F} (hc : IsColimit c) {i : J} (f₁ f₂ : X ⟶ F.obj i) (hf : f₁ ≫ c.ι.app i = f₂ ≫ c.ι.app i) : ∃ (j : J) (u : i ⟶ j), f₁ ≫ F.map u = f₂ ≫ F.map u := by have := preservesColimitsOfShape_of_isCardinalPresentable_of_essentiallySmall X κ J have := isFiltered_of_isCardinalFiltered J κ - exact (Types.FilteredColimit.isColimit_eq_iff' - (isColimitOfPreserves (coyoneda.obj (op X)) hc) f₁ f₂).1 hf + exact exists_eq_of_preservesColimit_coyoneda_self hc f₁ f₂ hf + +end lemma isCardinalPresentable_iff_isCardinalAccessible_uliftCoyoneda_obj : IsCardinalPresentable X κ ↔ (uliftCoyoneda.{t}.obj (op X)).IsCardinalAccessible κ := by From c3bd83c0a77fbb61e1417b2974ac87cd93970be6 Mon Sep 17 00:00:00 2001 From: William Coram Date: Thu, 25 Jun 2026 10:54:58 +0000 Subject: [PATCH 0343/1300] feat: final lemmas needed for showing gaussNorm on MvPowerSeries is an absolute value (#40997) We finish our section on showing that the gaussNorm on MvRestricted power series will be an absolute value by giving the neg and mul_eq_mul lemmas. Co-authored-by: WilliamCoram --- .../RingTheory/MvPowerSeries/GaussNorm.lean | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean index b26a1d6e4c6903..37d55774ebae66 100644 --- a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean +++ b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean @@ -33,6 +33,13 @@ the set of all values of `v (coeff t f) * ∏ i : t.support, c i` for all `t : * `MvPowerSeries.gaussNorm_add_le_max`: if `v` is a non-negative non-archimedean function and the set of values `v (coeff t f) * ∏ i : t.support, c i` is bounded above (similarly for `g`), then the Gauss norm has the non-archimedean property. + +* `MvPowerSeries.AchievesGaussNorm`: a type `i` is said to achieve gauss norm if + `v (coeff i f) * i.prod (c · ^ ·) = gaussNorm v c f`. + +* `MvPowerSeries.gaussNorm_neg`: if `v` has the property that `∀ i, v i = v (-i)` then + `gaussNorm v c (-f) = gaussNorm v c f `. + -/ @[expose] public section @@ -164,6 +171,12 @@ variable [Ring R] abbrev AchievesGaussNorm (i : σ →₀ ℕ) : Prop := v (coeff i f) * i.prod (c · ^ ·) = gaussNorm v c f +lemma gaussNorm_neg (vNeg : ∀ x, v (-x) = v x) (f : MvPowerSeries σ R) : + gaussNorm v c (-f) = gaussNorm v c f := by + simp_rw [gaussNorm] + have (t : σ →₀ ℕ) : (coeff t) (-f) = - (coeff t) f := by rfl + simp_rw [this, vNeg] + section absoluteValue variable {α S : Type*} [LinearOrder S] [AddCommGroup α] (f : α → S) @@ -226,6 +239,30 @@ lemma gaussNorm_le_mul (vMulEq : ∀ a b, v (a * b) = v a * v b) rw [antidiagonal_dominant v f g i₀ j₀ vna vMulEq vNeg hdom'] _ ≤ gaussNorm v c (f * g) := le_gaussNorm v c (f * g) hbfg (i₀ + j₀) +lemma gaussNorm_mul_eq_mul (f g : MvPowerSeries σ R) (hf : HasGaussNorm v c f) + (hg : HasGaussNorm v c g) (hfg : HasGaussNorm v c (f * g)) + (vNonneg : ∀ a, v a ≥ 0) (vZero : v 0 = 0) (vNA : IsNonarchimedean v) + (vMulEq : ∀ (a b : R), v (a * b) = v a * v b) (vNeg : ∀ (a : R), v (-a) = v a) + (h_eq_zero : ∀ (x : R), v x = 0 → x = 0) (hc : ∀ (i : σ), 0 < c i) + (hdom : ∃ i j, AchievesGaussNorm v c f i ∧ AchievesGaussNorm v c g j ∧ + ∀ p ∈ Finset.antidiagonal (i + j), p ≠ (i, j) → v (coeff p.1 f * coeff p.2 g) < + v (coeff i f) * v (coeff j g)) : + gaussNorm v c (f * g) = gaussNorm v c f * gaussNorm v c g := by + by_cases hf' : f = 0 + · simp [hf', gaussNorm_zero v c vZero] + by_cases hg' : g = 0 + · simp [hg', gaussNorm_zero v c vZero] + have hf1 : gaussNorm v c f ≠ 0 := by + convert gaussNorm_eq_zero_iff v c f vZero vNonneg h_eq_zero hc hf + grind + have hg1 : gaussNorm v c g ≠ 0 := by + convert gaussNorm_eq_zero_iff v c g vZero vNonneg h_eq_zero hc hg + grind + apply ge_antisymm_iff.mpr + constructor + · exact gaussNorm_le_mul v c f g vMulEq vNA (by grind) hfg hdom + · exact gaussNorm_mul_le v c f g (StrongLT.le hc) vNonneg (by grind) vNA vZero hf hg + end absoluteValue end MvPowerSeries From 008653f6c054a0cfcc8b43992bcffe5b7c20b410 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Thu, 25 Jun 2026 11:32:15 +0000 Subject: [PATCH 0344/1300] feat(AlgebraicGeometry): restriction of quasi-coherent sheaf is quasi-coherent (#37766) --- Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index f8c2feffe37612..a7fa7625846a7f 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -554,6 +554,21 @@ theorem isIso_fromTildeΓ_pushforward (M : (Spec S).Modules) [h : IsIso M.fromTi end IsLocalizing +set_option backward.isDefEq.respectTransparency false in +instance Scheme.Modules.isQuasicoherent_restrictFunctor {X Y : Scheme.{u}} (f : X ⟶ Y) + [IsOpenImmersion f] (M : Y.Modules) [M.IsQuasicoherent] : + ((restrictFunctor f).obj M).IsQuasicoherent := by + let α : X.presheaf ⟶ f.opensFunctor.op ⋙ Y.presheaf := { app U := (f.appIso U.unop).inv } + have hα : IsIso α := NatIso.isIso_of_isIso_app _ + let φ : X.ringCatSheaf ⟶ (f.opensFunctor.sheafPushforwardContinuous _ _ _).obj Y.ringCatSheaf := + ⟨Functor.whiskerRight α (forget₂ CommRingCat RingCat)⟩ + have : IsIso φ := by + rw [← isIso_iff_of_reflects_iso _ (ObjectProperty.ι _)] + dsimp [φ] + infer_instance + exact SheafOfModules.isQuasicoherent_pushforward_of_isLeftAdjoint.{u} + f.opensFunctor φ (Scheme.Modules.restrictUnitIso _) + set_option backward.isDefEq.respectTransparency false in /-- The presentation of `M.restrict f` by restricting a presentation of `M`. -/ def Scheme.Modules.presentationRestrict {X Y : Scheme.{u}} (f : Y ⟶ X) From 0eabedc61dc068bde900285b55b7a174278ebf3e Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 25 Jun 2026 12:00:33 +0000 Subject: [PATCH 0345/1300] feat: if S is disjoint from a finite-codim closed submodule T, then S is complemented (#41033) On the road towards Fredholm operators --- Mathlib/Topology/Algebra/Module/FiniteDimension.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean index 67c5ce664b99c6..9e16cef2540d80 100644 --- a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean +++ b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.LocallyConvex.Bounded public import Mathlib.Analysis.Normed.Module.Basic public import Mathlib.Analysis.SpecificLimits.Normed public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas +public import Mathlib.RingTheory.Finiteness.Cofinite public import Mathlib.RingTheory.LocalRing.Basic public import Mathlib.Topology.Algebra.Module.Determinant public import Mathlib.Topology.Algebra.Module.ModuleTopology @@ -739,6 +740,14 @@ theorem Submodule.ClosedComplemented.of_finiteDimensional_quotient {p : Submodul alias Submodule.ClosedComplemented.of_quotient_finiteDimensional := Submodule.ClosedComplemented.of_finiteDimensional_quotient +theorem Submodule.ClosedComplemented.of_disjoint_of_finiteDimensional_quotient + {A B : Submodule 𝕜 E} [B_cofg : FiniteDimensional 𝕜 (E ⧸ B)] (hB : IsClosed (B : Set E)) + (hAB : Disjoint A B) : A.ClosedComplemented := by + obtain ⟨C, B_le_C, C_compl_A⟩ := hAB.symm.exists_isCompl + have C_cofg : FiniteDimensional 𝕜 (E ⧸ C) := CoFG.of_le B_le_C B_cofg + have hC : IsClosed (C : Set E) := isClosed_mono_of_finiteDimensional_quotient hB B_le_C + exact C_compl_A.isTopCompl_of_finiteDimensional_quotient hC |>.symm.closedComplemented + lemma Submodule.ClosedComplemented.of_finiteDimensional_of_le {A B : Submodule 𝕜 E} [FiniteDimensional 𝕜 A] (hA : A.ClosedComplemented) [T2Space A] (hB : B ≤ A) : B.ClosedComplemented := by From 918d46759650d493222b403b05dae2d7ecfd04b8 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 25 Jun 2026 12:17:16 +0000 Subject: [PATCH 0346/1300] feat: a submodule disjoint from a coFG module is FG (#41008) ... over a noetherian ring. Also, over an arbitrary ring, a submodule codisjoint from a fg module is cofg. This is a prerequisite for Fredholm operators. --- Mathlib/RingTheory/Finiteness/Cofinite.lean | 16 +++++++++++++--- Mathlib/RingTheory/Noetherian/Basic.lean | 6 ++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/Finiteness/Cofinite.lean b/Mathlib/RingTheory/Finiteness/Cofinite.lean index 7e23470116e2b4..98924e5a4a6fcd 100644 --- a/Mathlib/RingTheory/Finiteness/Cofinite.lean +++ b/Mathlib/RingTheory/Finiteness/Cofinite.lean @@ -49,10 +49,20 @@ theorem _root_.Module.Finite.iff_cofg_bot : (⊥ : Submodule R M).CoFG ↔ Modul theorem CoFG.fg_of_isCompl {S T : Submodule R M} (hST : IsCompl S T) (hS : S.CoFG) : T.FG := Module.Finite.iff_fg.mp <| Module.Finite.equiv <| quotientEquivOfIsCompl S T hST +/-- Over a noetherian ring, if `S` and `T` are disjoint and `T` is CoFG, then `S` is FG. -/ +theorem CoFG.fg_of_disjoint [IsNoetherianRing R] {S T : Submodule R M} (hST : Disjoint S T) + (hT : T.CoFG) : S.FG := + .of_disjoint_of_isNoetherian_quotient hST + +/-- If `S` and `T` are co-disjoint and `S` is FG, then `T` is CoFG. -/ +theorem FG.cofg_of_codisjoint {S T : Submodule R M} (hST : Codisjoint S T) (hS : S.FG) : + T.CoFG := + have := Module.Finite.iff_fg.mpr hS + .of_surjective (T.mkQ.domRestrict S) (by simp [← LinearMap.range_eq_top, hST.symm.eq_top]) + /-- A complement of an FG submodule is CoFG. -/ -theorem FG.cofg_of_isCompl {S T : Submodule R M} (hST : IsCompl S T) (hS : S.FG) : T.CoFG := by - haveI := Module.Finite.iff_fg.mpr hS - exact Module.Finite.equiv (quotientEquivOfIsCompl T S hST.symm).symm +theorem FG.cofg_of_isCompl {S T : Submodule R M} (hST : IsCompl S T) (hS : S.FG) : T.CoFG := + hS.cofg_of_codisjoint hST.codisjoint /-- A submodule that contains a CoFG submodule is CoFG. -/ theorem CoFG.of_le {S T : Submodule R M} (hT : S ≤ T) (hS : S.CoFG) : T.CoFG := by diff --git a/Mathlib/RingTheory/Noetherian/Basic.lean b/Mathlib/RingTheory/Noetherian/Basic.lean index 8e31fb6142f586..324118d0f9e31a 100644 --- a/Mathlib/RingTheory/Noetherian/Basic.lean +++ b/Mathlib/RingTheory/Noetherian/Basic.lean @@ -382,6 +382,12 @@ lemma FG.of_le [IsNoetherianRing R] {S T : Submodule R M} (hT : T.FG) (hST : S rw [← Module.Finite.iff_fg] at hT exact FG.of_le_of_isNoetherian hST +/-- If `S` is disjoint from `T` and `M ⧸ T` is a noetherian module, then `S` is FG. +See also `Submodule.CoFG.fg_of_disjoint`. -/ +theorem FG.of_disjoint_of_isNoetherian_quotient {S T : Submodule R M} [IsNoetherian R (M ⧸ T)] + (hST : Disjoint S T) : S.FG := + Module.Finite.iff_fg.mp <| .of_injective (T.mkQ.domRestrict S) (by simp [hST.eq_bot]) + end Submodule universe w v u From 9e80b1a3dbfb369c229f1f0e62fbf48032cf9c9b Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:17:18 +0000 Subject: [PATCH 0347/1300] fix(Geometry/Manifold/VectorBundle/Hom): fix typo in doc-string (#41025) Discovered while working on #36036. --- Mathlib/Geometry/Manifold/VectorBundle/Hom.lean | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index 654aab97adf6ee..661dd8ab0a85c0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -360,7 +360,7 @@ section TwoVariables variable [∀ x, IsTopologicalAddGroup (E₃ x)] [∀ x, ContinuousSMul 𝕜 (E₃ x)] {ψ : ∀ x, (E₁ (b x) →L[𝕜] E₂ (b x) →L[𝕜] E₃ (b x))} {w : ∀ x, E₂ (b x)} -/-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider `C^n` maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. @@ -373,7 +373,7 @@ lemma ContMDiffWithinAt.clm_bundle_apply₂ CMDiffAt[s] n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := hψ.clm_bundle_apply hv |>.clm_bundle_apply hw -/-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider `C^n` maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. @@ -386,7 +386,7 @@ lemma ContMDiffAt.clm_bundle_apply₂ CMDiffAt n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := ContMDiffWithinAt.clm_bundle_apply₂ hψ hv hw -/-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider `C^n` maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. @@ -399,7 +399,7 @@ lemma ContMDiffOn.clm_bundle_apply₂ CMDiff[s] n (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := fun x hx ↦ (hψ x hx).clm_bundle_apply₂ (hv x hx) (hw x hx) -/-- Consider `C^n` maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider `C^n` maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is `C^n`. -/ lemma ContMDiff.clm_bundle_apply₂ @@ -417,7 +417,7 @@ section TwoVariables' variable [∀ x, IsTopologicalAddGroup (E₃ x)] [∀ x, ContinuousSMul 𝕜 (E₃ x)] {ψ : ∀ x, (E₁ (b x) →L[𝕜] E₂ (b x) →L[𝕜] E₃ (b x))} {w : ∀ x, E₂ (b x)} -/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider differentiable maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. @@ -430,7 +430,7 @@ lemma MDifferentiableWithinAt.clm_bundle_apply₂ MDiffAt[s] (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := hψ.clm_bundle_apply hv |>.clm_bundle_apply hw -/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider differentiable maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. @@ -443,7 +443,7 @@ lemma MDifferentiableAt.clm_bundle_apply₂ MDiffAt (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := MDifferentiableWithinAt.clm_bundle_apply₂ hψ hv hw -/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider differentiable maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. @@ -456,7 +456,7 @@ lemma MDifferentiableOn.clm_bundle_apply₂ MDiff[s] (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := fun x hx ↦ (hψ x hx).clm_bundle_apply₂ (hv x hx) (hw x hx) -/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +/-- Consider differentiable maps `v : M → E₁` and `w : M → E₂` to vector bundles, over a base map `b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. -/ lemma MDifferentiable.clm_bundle_apply₂ From 38f43abaf3ed4853a783dd1f99f9ef28884ea77c Mon Sep 17 00:00:00 2001 From: Wenrong Zou <141128015+WenrongZou@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:42:13 +0000 Subject: [PATCH 0348/1300] feat(Date/Choose): add some lemmas about choose of prime pow (#38317) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this PR, I add some lemma about choose of prime pow. 1) For primes `p` and positive integer `n`, assume that for all `i ∈ Icc 1 (n - 1)`, `choose n i` congruent to `0` module `p`, then `n = p ^ multiplicity p n`. 2) For a prime power `n`, the greatest common divisor of `choose n 1, ⋯, choose n (n - 1)` is actually the minimal prime factor of `n`. 3) For a natural number `n` greater than `1`, assume that `n` is not a prime power, then the greatest common divisor of `choose n 1, ⋯, choose n (n - 1)` is `1`. Co-authored-by: WenrongZou --- Mathlib/Data/Nat/Choose/Lucas.lean | 93 ++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/Mathlib/Data/Nat/Choose/Lucas.lean b/Mathlib/Data/Nat/Choose/Lucas.lean index 5b7ca9df72bacb..cc7f66fdd02fa5 100644 --- a/Mathlib/Data/Nat/Choose/Lucas.lean +++ b/Mathlib/Data/Nat/Choose/Lucas.lean @@ -132,4 +132,97 @@ theorem choose_pow_mul_pow_mul_modEq_choose_nat : rw [← Int.natCast_modEq_iff] exact_mod_cast choose_pow_mul_pow_mul_modEq_choose +/-- For primes `p` and positive integer `n`, assume that for all `i ∈ Icc 1 (n - 1)`, +`choose n i` congruent to `0` module `p`, then `n = p ^ multiplicity p n`. +Also see `eq_pow_multiplicity_of_choose_modEq_zero_nat` for the version with `MOD`. -/ +theorem eq_pow_multiplicity_of_choose_modEq_zero (hn : 0 < n) + (h : ∀ i ∈ Icc 1 (n - 1), n.choose i ≡ 0 [ZMOD p]) : n = p ^ multiplicity p n := by + rename_i hp + by_contra! hn₀ + obtain ⟨m, hm⟩ := pow_multiplicity_dvd p n + specialize h (p ^ multiplicity p n) (by grind [le_of_dvd hn (pow_multiplicity_dvd p n)]) + nth_grw 1 [← mul_one (p ^ _), hm, choose_pow_mul_pow_mul_modEq_choose, choose_one_right] at h + suffices multiplicity p n + 1 ≤ multiplicity p n by lia + rw [← FiniteMultiplicity.pow_dvd_iff_le_multiplicity] + · nth_rw 2 [hm] + simpa [pow_add] using Nat.mul_dvd_mul_left _ (dvd_iff_mod_eq_zero.mpr (by exact_mod_cast h)) + · exact finiteMultiplicity_iff.mpr ⟨hp.out.ne_one, hn⟩ + +/-- For primes `p` and positive integer `n`, assume that for all `i ∈ Icc 1 (n - 1)`, +`choose n i` congruent to `0` module `p`, then `n = p ^ multiplicity p n`. +Also see `eq_pow_multiplicity_of_choose_modEq_zero` for the version with `ZMOD`. -/ +theorem eq_pow_multiplicity_of_choose_modEq_zero_nat (hn : 0 < n) + (h : ∀ i ∈ Icc 1 (n - 1), n.choose i ≡ 0 [MOD p]) : n = p ^ multiplicity p n := + eq_pow_multiplicity_of_choose_modEq_zero hn (by exact_mod_cast h) + +/-- For a prime power `n`, the minimal prime factor divides the greatest common divisor of +`choose n 1, ⋯, choose n (n - 1)`. -/ +theorem minFac_dvd_gcd_choose_of_isPrimePow (h : IsPrimePow n) : + n.minFac ∣ (Icc 1 (n - 1)).gcd n.choose := by + obtain ⟨k, _, _, hn₁⟩ := (isPrimePow_nat_iff_bounded_log_minFac _).mp h + exact dvd_gcd_iff.mpr fun i hi => by + nth_rw 2 [hn₁] + exact Prime.dvd_choose_pow (minFac_prime_iff.mpr h.ne_one) (by grind) (by grind) + +lemma minFac_sq_ndvd_gcd_choose_of_isPrimePow (h : IsPrimePow n) : + ¬ n.minFac ^ 2 ∣ (Icc 1 (n - 1)).gcd n.choose := by + obtain ⟨k, _, k_pos, hn₁⟩ := (isPrimePow_nat_iff_bounded_log_minFac _).mp h + have isPrime := minFac_prime_iff.mpr (IsPrimePow.ne_one h) + refine mt Finset.dvd_gcd_iff.mp ?_ + simp only [mem_Icc, not_forall] + have : n.minFac ^ (k - 1) ≤ n.minFac ^ k := Nat.pow_le_pow_right (minFac_pos n) (sub_le k 1) + refine ⟨n.minFac ^ (k - 1), ⟨one_le_pow _ _ (minFac_pos n), ?_⟩, ?_⟩ + · refine le_sub_one_of_lt ?_ + nth_rw 2 [hn₁] + exact Nat.pow_lt_pow_of_lt (Prime.one_lt isPrime) (sub_one_lt_of_lt k_pos) + · refine emultiplicity_lt_iff_not_dvd.mp ?_ + nth_rw 2 [hn₁] + rw [Nat.Prime.emultiplicity_choose_prime_pow isPrime this (pow_ne_zero _ + (Nat.Prime.ne_zero isPrime)), multiplicity_pow_self_of_prime (prime_iff.mp isPrime)] + norm_cast + grind + +lemma primeFactors_gcd_choose_of_isPrimePow (h : IsPrimePow n) : + ((Icc 1 (n - 1)).gcd n.choose).primeFactors = {n.minFac} := by + have ne_zero : (Icc 1 (n - 1)).gcd n.choose ≠ 0 := + gcd_ne_zero_iff.mpr ⟨1, by simp; grind [IsPrimePow.two_le h]⟩ + have isPrime := minFac_prime_iff.mpr (IsPrimePow.ne_one h) + refine eq_singleton_iff_unique_mem.mpr ⟨isPrime.mem_primeFactors + (minFac_dvd_gcd_choose_of_isPrimePow h) ne_zero, ?_⟩ + intro p hp + simp only [mem_primeFactors, ne_eq] at hp + obtain ⟨hp₁, hp₂, hp₃⟩ := hp + haveI : Fact (Nat.Prime p) := ⟨hp₁⟩ + simp_rw [Finset.dvd_gcd_iff, ← modEq_zero_iff_dvd] at hp₂ + have := eq_pow_multiplicity_of_choose_modEq_zero_nat h.pos hp₂ + have dvd_pow : n.minFac ∣ p ^ multiplicity p n := this ▸ minFac_dvd _ + exact (Nat.prime_dvd_prime_iff_eq isPrime hp₁).mp (isPrime.dvd_of_dvd_pow dvd_pow)|>.symm + +/-- For a prime power `n`, the greatest common divisor of `choose n 1, ⋯, choose n (n - 1)` +is actually the minimal prime factor of `n`. -/ +theorem gcd_choose_eq_minFac_of_isPrimePow (h : IsPrimePow n) : + (Icc 1 (n - 1)).gcd n.choose = n.minFac := by + have ne_zero : (Icc 1 (n - 1)).gcd n.choose ≠ 0 := + gcd_ne_zero_iff.mpr ⟨1, by simp; grind [IsPrimePow.two_le h]⟩ + have isPrime := minFac_prime_iff.mpr (IsPrimePow.ne_one h) + have : multiplicity n.minFac ((Icc 1 (n - 1)).gcd n.choose) = 1 := by + refine multiplicity_eq_of_dvd_of_not_dvd ?_ (minFac_sq_ndvd_gcd_choose_of_isPrimePow h) + simpa using minFac_dvd_gcd_choose_of_isPrimePow h + rw [Nat.prod_pow_primeFactors_factorization ne_zero, primeFactors_gcd_choose_of_isPrimePow h] + simp [← Nat.multiplicity_eq_factorization isPrime ne_zero, this] + +/-- For a natural number `n` greater than `1`, assume that `n` is not a prime power, then +the greatest common divisor of `choose n 1, ⋯, choose n (n - 1)` is `1`. -/ +theorem gcd_choose_eq_one_of_not_isPrimePow (hn : 1 < n) (hpn : ¬ IsPrimePow n) : + (Icc 1 (n - 1)).gcd n.choose = 1 := by + contrapose! hpn + obtain ⟨q, hq, h⟩ := Nat.exists_prime_and_dvd hpn + simp_rw [Finset.dvd_gcd_iff, ← modEq_zero_iff_dvd] at h + haveI : Fact (Nat.Prime q) := ⟨hq⟩ + have := eq_pow_multiplicity_of_choose_modEq_zero_nat (zero_lt_of_lt hn) h + refine (isPrimePow_nat_iff n).mpr ⟨q, _, hq, Dvd.multiplicity_pos ?_, this.symm⟩ + specialize h 1 (by grind) + rw [choose_one_right, modEq_zero_iff_dvd] at h + exact h + end Choose From 23f4bd67e1dc779023290f1189e088c46ced3a45 Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:42:15 +0000 Subject: [PATCH 0349/1300] feat: local homeomorphisms are covering maps for compact domains (#41031) --- Mathlib/Analysis/Complex/CoveringMap.lean | 2 +- Mathlib/Topology/Covering/Basic.lean | 42 ++++++++++++++++++----- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/Complex/CoveringMap.lean b/Mathlib/Analysis/Complex/CoveringMap.lean index 95872f8372379f..2d5b9fa2902f01 100644 --- a/Mathlib/Analysis/Complex/CoveringMap.lean +++ b/Mathlib/Analysis/Complex/CoveringMap.lean @@ -53,7 +53,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [ProperSpace 𝕜] theorem Polynomial.isCoveringMapOn_eval (p : 𝕜[X]) : IsCoveringMapOn p.eval (p.eval '' {k | p.derivative.eval k = 0})ᶜ := by - refine p.isClosedMap_eval.isCoveringMapOn_of_openPartialHomeomorph (fun x hx ↦ ?_) + refine p.isClosedMap_eval.isCoveringMapOn_of_isLocalHomeomorphOn (fun x hx ↦ ?_) fun x hx ↦ ⟨_, ((p.hasStrictDerivAt x).hasStrictFDerivAt_equiv fun h ↦ hx ⟨x, h, rfl⟩).mem_toOpenPartialHomeomorph_source, by simp⟩ obtain rfl | ne := eq_or_ne p (C x) diff --git a/Mathlib/Topology/Covering/Basic.lean b/Mathlib/Topology/Covering/Basic.lean index 8400516ab95c2c..ad257b2dbc7685 100644 --- a/Mathlib/Topology/Covering/Basic.lean +++ b/Mathlib/Topology/Covering/Basic.lean @@ -555,11 +555,18 @@ theorem IsClosedMap.isEvenlyCovered_of_openPartialHomeomorph [T2Space E] {x : X} /-- If `f : E → X` is a closed map between topological spaces with `E` Hausdorff, and `s` is a subset of `X` on which `f` has finite fibers, such that `f` restricts to a homeomorphism on a neighborhood of every point of `f ⁻¹' s`, then `f` is a covering map on `s`. -/ -theorem IsClosedMap.isCoveringMapOn_of_openPartialHomeomorph [T2Space E] +theorem IsClosedMap.isCoveringMapOn_of_isLocalHomeomorphOn [T2Space E] (hf : IsClosedMap f) (hs : ∀ x ∈ s, (f ⁻¹' {x}).Finite) - (h : ∀ e ∈ f ⁻¹' s, ∃ φ : OpenPartialHomeomorph E X, e ∈ φ.source ∧ φ = f) : - IsCoveringMapOn f s := - fun x hx ↦ hf.isEvenlyCovered_of_openPartialHomeomorph (hs x hx) fun e he ↦ h e (by apply he ▸ hx) + (h : IsLocalHomeomorphOn f (f ⁻¹' s)) : + IsCoveringMapOn f s := by + intro x hx + refine hf.isEvenlyCovered_of_openPartialHomeomorph (hs x hx) fun e he ↦ ?_ + obtain ⟨φ, hφ, rfl⟩ := h e (by aesop) + aesop + +@[deprecated (since := "2026-06-25")] +alias IsClosedMap.isCoveringMapOn_of_openPartialHomeomorph := + IsClosedMap.isCoveringMapOn_of_isLocalHomeomorphOn /-- If `f : E → X` is a continuous map between Hausdorff spaces with `E` compact, and `f` restricts to a homeomorphism on a neighborhood of every point of a fiber `f ⁻¹' {x}`, @@ -578,8 +585,27 @@ then `f` is a covering map on `s`. For example, `s` can be taken to be the set of regular values of a C¹ map `f : E → X` where `E` and `X` are manifolds of the same dimension with `E` compact, according to the inverse function theorem (see `ContDiffAt.toOpenPartialHomeomorph`). -/ -theorem IsCoveringMapOn.of_openPartialHomeomorph +theorem IsCoveringMapOn.of_isLocalHomeomorphOn [T2Space E] [T2Space X] [CompactSpace E] (hf : Continuous f) - (h : ∀ e ∈ f ⁻¹' s, ∃ φ : OpenPartialHomeomorph E X, e ∈ φ.source ∧ φ = f) : - IsCoveringMapOn f s := - fun x hx ↦ .of_openPartialHomeomorph hf fun e he ↦ h e (by apply he ▸ hx) + (h : IsLocalHomeomorphOn f (f ⁻¹' s)) : + IsCoveringMapOn f s := by + intro x hx + refine .of_openPartialHomeomorph hf fun e he ↦ ?_ + obtain ⟨φ, hφ, rfl⟩ := h e (by aesop) + aesop + +@[deprecated (since := "2026-06-25")] +alias IsCoveringMapOn.of_openPartialHomeomorph := IsCoveringMapOn.of_isLocalHomeomorphOn + +@[simp] +lemma isLocalHomeomorph_iff_isCoveringMap [T2Space E] [T2Space X] [CompactSpace E] : + IsLocalHomeomorph f ↔ IsCoveringMap f := by + refine ⟨fun h ↦ ?_, IsCoveringMap.isLocalHomeomorph⟩ + have hf : Continuous f := by + rw [continuous_iff_continuousAt] + intro e + obtain ⟨φ, hφ, rfl⟩ := h e + exact φ.continuousAt hφ + rw [isCoveringMap_iff_isCoveringMapOn_univ] + apply IsCoveringMapOn.of_isLocalHomeomorphOn hf + simpa [← isLocalHomeomorph_iff_isLocalHomeomorphOn_univ] From bb39487d795eef69f1218b2d28abc5eb3dcad0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:10:36 +0000 Subject: [PATCH 0350/1300] feat(CategoryTheory/ObjectProperty): preservation of limits is closed under isomorphisms (#41036) This is only the translation of this statement in terms of some `ObjectProperty` in functor categories. --- .../ObjectProperty/CompleteLattice.lean | 7 +++++++ .../FunctorCategory/PreservesLimits.lean | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Mathlib/CategoryTheory/ObjectProperty/CompleteLattice.lean b/Mathlib/CategoryTheory/ObjectProperty/CompleteLattice.lean index 51dd57c087bcb7..6152f84f2e3d72 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/CompleteLattice.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/CompleteLattice.lean @@ -97,6 +97,13 @@ instance [∀ a, (P a).IsClosedUnderIsomorphisms] : simp only [isClosedUnderIsomorphisms_iff_isoClosure_eq_self, isoClosure_iSup, isoClosure_eq_self] +instance [∀ a, (P a).IsClosedUnderIsomorphisms] : + ((⨅ (a : α), P a)).IsClosedUnderIsomorphisms where + of_iso e h := by + simp only [iInf_apply, iInf_Prop_eq] at h ⊢ + intro a + exact (P a).prop_of_iso e (h a) + end @[push] diff --git a/Mathlib/CategoryTheory/ObjectProperty/FunctorCategory/PreservesLimits.lean b/Mathlib/CategoryTheory/ObjectProperty/FunctorCategory/PreservesLimits.lean index a160c062fe8b4a..cceb19b3174f4c 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/FunctorCategory/PreservesLimits.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/FunctorCategory/PreservesLimits.lean @@ -45,6 +45,9 @@ lemma congr_preservesLimit {F F' : K ⥤ J} (e : F ≅ F') : exact ⟨fun h ↦ preservesLimit_of_iso_diagram _ e, fun h ↦ preservesLimit_of_iso_diagram _ e.symm⟩ +instance (F : K ⥤ J) : (preservesLimit (C := C) F).IsClosedUnderIsomorphisms where + of_iso e _ := preservesLimit_of_natIso _ e + variable {K} in /-- The property of objects in the functor category `J ⥤ C` which preserves the colimit of a functor `F : K ⥤ J`. -/ @@ -61,6 +64,9 @@ lemma congr_preservesColimit {F F' : K ⥤ J} (e : F ≅ F') : exact ⟨fun h ↦ preservesColimit_of_iso_diagram _ e, fun h ↦ preservesColimit_of_iso_diagram _ e.symm⟩ +instance (F : K ⥤ J) : (preservesColimit (C := C) F).IsClosedUnderIsomorphisms where + of_iso e _ := preservesColimit_of_natIso _ e + /-- The property of objects in the functor category `J ⥤ C` which preserves limits of shape `K`. -/ abbrev preservesLimitsOfShape : ObjectProperty (J ⥤ C) := PreservesLimitsOfShape K @@ -84,6 +90,10 @@ lemma congr_preservesLimitsOfShape (e : K ≌ K') : exact ⟨fun _ ↦ preservesLimitsOfShape_of_equiv e _, fun _ ↦ preservesLimitsOfShape_of_equiv e.symm _⟩ +instance : (preservesLimitsOfShape (J := J) (C := C) K).IsClosedUnderIsomorphisms := by + rw [preservesLimitsOfShape_eq_iSup] + infer_instance + /-- The property of objects in the functor category `J ⥤ C` which preserves colimits of shape `K`. -/ abbrev preservesColimitsOfShape : ObjectProperty (J ⥤ C) := PreservesColimitsOfShape K @@ -107,6 +117,10 @@ lemma congr_preservesColimitsOfShape (e : K ≌ K') : exact ⟨fun _ ↦ preservesColimitsOfShape_of_equiv e _, fun _ ↦ preservesColimitsOfShape_of_equiv e.symm _⟩ +instance : (preservesColimitsOfShape (J := J) (C := C) K).IsClosedUnderIsomorphisms := by + rw [preservesColimitsOfShape_eq_iSup] + infer_instance + /-- The property of objects in the functor category `J ⥤ C` which preserves finite limits. -/ abbrev preservesFiniteLimits : ObjectProperty (J ⥤ C) := PreservesFiniteLimits @@ -115,10 +129,16 @@ abbrev preservesFiniteLimits : ObjectProperty (J ⥤ C) := PreservesFiniteLimits lemma preservesFiniteLimits_iff (F : J ⥤ C) : preservesFiniteLimits F ↔ PreservesFiniteLimits F := Iff.rfl +instance : (preservesFiniteLimits (J := J) (C := C)).IsClosedUnderIsomorphisms where + of_iso e _ := preservesFiniteLimits_of_natIso e + /-- The property of objects in the functor category `J ⥤ C` which preserves finite colimits. -/ abbrev preservesFiniteColimits : ObjectProperty (J ⥤ C) := PreservesFiniteColimits +instance : (preservesFiniteColimits (J := J) (C := C)).IsClosedUnderIsomorphisms where + of_iso e _ := preservesFiniteColimits_of_natIso e + @[simp] lemma preservesFiniteColimits_iff (F : J ⥤ C) : preservesFiniteColimits F ↔ PreservesFiniteColimits F := Iff.rfl From d31b5731def4cfc9061d0f273418b3d1c0df2101 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:30:18 +0000 Subject: [PATCH 0351/1300] feat(AlgebraicGeometry): define algebraic cycles (#37901) In this PR we define the notion of algebraic cycles on a scheme, and define the pushforward of an algebraic cycle by a quasicompact morhphism. This was originally defined in #26304, but after some refactoring it was decided that it would be best to split this definition into a separate PR. Co-authored-by: Raph-DG --- Mathlib.lean | 1 + .../AlgebraicCycle/Basic.lean | 79 +++++++++++++++++++ Mathlib/AlgebraicGeometry/ResidueField.lean | 14 ++++ 3 files changed, 94 insertions(+) create mode 100644 Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4017194f141030..766e023cdb5735 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1346,6 +1346,7 @@ public import Mathlib.AlgebraicGeometry.AffineScheme public import Mathlib.AlgebraicGeometry.AffineSpace public import Mathlib.AlgebraicGeometry.AffineTransitionLimit public import Mathlib.AlgebraicGeometry.AlgClosed.Basic +public import Mathlib.AlgebraicGeometry.AlgebraicCycle.Basic public import Mathlib.AlgebraicGeometry.Artinian public import Mathlib.AlgebraicGeometry.Birational.Dominant public import Mathlib.AlgebraicGeometry.Birational.RationalMap diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean new file mode 100644 index 00000000000000..22d69227a54f40 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean @@ -0,0 +1,79 @@ +/- +Copyright (c) 2026 Raphael Douglas Giles. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Raphael Douglas Giles +-/ +module + +public import Mathlib.AlgebraicGeometry.Morphisms.QuasiCompact +public import Mathlib.AlgebraicGeometry.Properties +public import Mathlib.Topology.LocallyFinsupp.Pushforward +public import Mathlib.AlgebraicGeometry.ResidueField + +/-! +# Algebraic Cycles + +In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide +some basic API for working with them. We define an algebraic cycle on a scheme `X` with +coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. + +## Implementation notes + +Here we're making use of the equivalence between irreducible closed subsets of a scheme and their +generic points in order to reuse the API in `Function.locallyFinsupp`, hence the slightly +nonstandard definition. +-/ + +@[expose] public section + +namespace AlgebraicGeometry + +open CategoryTheory + +universe u v +variable {X Y : Scheme.{u}} {R : Type*} + +/-- +Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` +with locally finite support (see the module docstring for more details). + +Note: currently this is an abbrev to save some effort in duplicating API. This seems fine for now, +but be aware of this if there is ever an instance clash involving algebraic cycles. +-/ +@[stacks 02QR] +abbrev AlgebraicCycle (X : Scheme.{u}) (R : Type*) [Zero R] := + Function.locallyFinsupp X R + +variable (f : X ⟶ Y) [Semiring R] (c : AlgebraicCycle X R) (x : X) (z : Y) +namespace AlgebraicCycle + +/-- +Implementation detail for `AlgebraicCycle.map`: function used to define the coefficient of the +pushforward of a cycle `c` at a point `z = f x`. +-/ +@[stacks 02R3] +noncomputable def mapCoeff {N : Type*} [DecidableEq N] {Y : Scheme} (f : X ⟶ Y) (wx : X → N) + (wy : Y → N) (x : X) : ℕ := if wx x = wy (f.base x) then f.residueDegree x else 0 + +/-- +The pushforward of algebraic cycles with respect to a quasicompact morphism of schemes. The +arguments `wx` and `wy` are certain weight functions used to calculate how the weights of the +algebraic cycle should be adjusted to make the pushforward operation functorial. Typically in +applications these will be some notions of dimension or codimension. The most common notion of +dimension is `Order.height`, and the most common notion of codimension is `Order.coheight`, though +more sophisticated notions exist in the literature which are useful when sufficient +equidimensionality hypotheses cannot be assumed. +-/ +@[stacks 02R3] +noncomputable +def map [QuasiCompact f] {N : Type*} [DecidableEq N] (wx : X → N) (wy : Y → N) + (c : AlgebraicCycle X R) : AlgebraicCycle Y R := + Function.locallyFinsupp.map f (Nat.cast (R := R) <| mapCoeff f wx wy ·) f.isSpectralMap c + +@[simp] +lemma map_id {N : Type*} [DecidableEq N] (wx : X → N) (c : AlgebraicCycle X R) : + map (𝟙 _) wx wx c = c := by + apply Function.locallyFinsupp.map_id + simp [mapCoeff] + +end AlgebraicGeometry.AlgebraicCycle diff --git a/Mathlib/AlgebraicGeometry/ResidueField.lean b/Mathlib/AlgebraicGeometry/ResidueField.lean index 3aa4861abd5d33..20c400e69b5ca9 100644 --- a/Mathlib/AlgebraicGeometry/ResidueField.lean +++ b/Mathlib/AlgebraicGeometry/ResidueField.lean @@ -140,6 +140,20 @@ lemma residueFieldMap_comp {Z : Scheme.{u}} (g : Y ⟶ Z) (x : X) : (f ≫ g).residueFieldMap x = g.residueFieldMap (f x) ≫ f.residueFieldMap x := LocallyRingedSpace.residueFieldMap_comp _ _ _ +/-- +Degree of `f` at a point `x` is defined to be the degree of the associated field extension +from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is infinite. +-/ +def Hom.residueDegree (f : X ⟶ Y) (x : X) : ℕ := + letI := (f.residueFieldMap x).hom.toAlgebra + Module.finrank (Y.residueField (f x)) (X.residueField x) + +@[simp] +lemma Hom.residueDegree_id (x : X) : (𝟙 _ : X ⟶ X).residueDegree x = 1 := by + dsimp [residueDegree] + rw [residueFieldMap_id] + exact CommSemiring.finrank_self _ + @[reassoc] lemma evaluation_naturality {V : Opens Y} (x : X) (hx : f x ∈ V) : Y.evaluation V (f x) hx ≫ f.residueFieldMap x = From 0cd556a586391216f097067ee3785af582e78fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Thu, 25 Jun 2026 13:30:21 +0000 Subject: [PATCH 0352/1300] feat: generalize `ae_hasDerivAt_integral` to Banach spaces (#40976) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalize both interval-version Lebesgue differentiation theorems `LocallyIntegrable.ae_hasDerivAt_integral` and `IntervalIntegrable.ae_hasDerivAt_integral` from real-valued functions `f : ℝ → ℝ` to functions `f : ℝ → E` valued in a Banach space `E`. The existing proof already goes through the vector-valued averaging theorem `VitaliFamily.ae_tendsto_average`, so the only change is replacing scalar multiplication `*` by `•` in the slope computation. This is a prerequisite for https://github.com/leanprover-community/mathlib4/pull/40973. AI usage disclosure: I used Claude Opus 4.8 to implement this and manually tested it with the other PR and my other separate project. --- .../LebesgueDifferentiationThm.lean | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/LebesgueDifferentiationThm.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/LebesgueDifferentiationThm.lean index 2654b47e2e7e3b..23dad80410b6b8 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/LebesgueDifferentiationThm.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/LebesgueDifferentiationThm.lean @@ -15,11 +15,11 @@ public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic This file proves the interval version of the Lebesgue Differentiation Theorem. There are two versions in this file. -* `LocallyIntegrable.ae_hasDerivAt_integral` is the global version. It states that if `f : ℝ → ℝ` - is locally integrable, then for almost every `x`, for any `c : ℝ`, the derivative of - `∫ (t : ℝ) in c..x, f t` at `x` is equal to `f x`. +* `LocallyIntegrable.ae_hasDerivAt_integral` is the global version. It states that if `f : ℝ → E` + is locally integrable (`E` a Banach space), then for almost every `x`, for any `c : ℝ`, the + derivative of `∫ (t : ℝ) in c..x, f t` at `x` is equal to `f x`. -* `IntervalIntegrable.ae_hasDerivAt_integral` is the local version. It states that if `f : ℝ → ℝ` +* `IntervalIntegrable.ae_hasDerivAt_integral` is the local version. It states that if `f : ℝ → E` is interval integrable on `a..b`, then for almost every `x ∈ uIcc a b`, for any `c ∈ uIcc a b`, the derivative of `∫ (t : ℝ) in c..x, f t` at `x` is equal to `f x`. -/ @@ -30,10 +30,12 @@ open MeasureTheory Set Filter Function IsUnifLocDoublingMeasure open scoped Topology -/-- The (global) interval version of the *Lebesgue Differentiation Theorem*: if `f : ℝ → ℝ` is +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] + +/-- The (global) interval version of the *Lebesgue Differentiation Theorem*: if `f : ℝ → E` is locally integrable, then for almost every `x`, for any `c : ℝ`, the derivative of `∫ (t : ℝ) in c..x, f t` at `x` is equal to `f x`. -/ -theorem LocallyIntegrable.ae_hasDerivAt_integral {f : ℝ → ℝ} (hf : LocallyIntegrable f volume) : +theorem LocallyIntegrable.ae_hasDerivAt_integral {f : ℝ → E} (hf : LocallyIntegrable f volume) : ∀ᵐ x, ∀ c, HasDerivAt (fun x => ∫ (t : ℝ) in c..x, f t) (f x) x := by have hg (x y : ℝ) : IntervalIntegrable f volume x y := intervalIntegrable_iff.mpr <| @@ -48,24 +50,24 @@ theorem LocallyIntegrable.ae_hasDerivAt_integral {f : ℝ → ℝ} (hf : Locally · refine Filter.tendsto_congr' ?_ |>.mpr (hx.comp x.tendsto_Icc_vitaliFamily_left) filter_upwards [self_mem_nhdsWithin] with y hy replace hy : y ≤ x := hy.le - suffices -((y - x)⁻¹ * ∫ (t : ℝ) in Icc y x, f t) = (x - y)⁻¹ * ∫ (t : ℝ) in Icc y x, f t by + suffices -((y - x)⁻¹ • ∫ (t : ℝ) in Icc y x, f t) = (x - y)⁻¹ • ∫ (t : ℝ) in Icc y x, f t by simpa [slope, average, intervalIntegral.integral_interval_sub_left, hg, intervalIntegral.integral_of_ge, hy, h] - rw [← neg_mul, neg_inv, neg_sub] + rw [← neg_smul, neg_inv, neg_sub] · refine Filter.tendsto_congr' ?_ |>.mpr (hx.comp x.tendsto_Icc_vitaliFamily_right) filter_upwards [self_mem_nhdsWithin] with y hy replace hy : x ≤ y := hy.le simp [slope, average, intervalIntegral.integral_interval_sub_left, hg, intervalIntegral.integral_of_le, hy, h] -/-- The (local) interval version of the *Lebesgue Differentiation Theorem*: if `f : ℝ → ℝ` is +/-- The (local) interval version of the *Lebesgue Differentiation Theorem*: if `f : ℝ → E` is interval integrable on `a..b`, then for almost every `x ∈ uIcc a b`, for any `c ∈ uIcc a b`, the derivative of `∫ (t : ℝ) in c..x, f t` at `x` is equal to `f x`. -/ -theorem IntervalIntegrable.ae_hasDerivAt_integral {f : ℝ → ℝ} {a b : ℝ} +theorem IntervalIntegrable.ae_hasDerivAt_integral {f : ℝ → E} {a b : ℝ} (hf : IntervalIntegrable f volume a b) : ∀ᵐ x, x ∈ uIcc a b → ∀ c ∈ uIcc a b, HasDerivAt (fun x => ∫ (t : ℝ) in c..x, f t) (f x) x := by wlog hab : a ≤ b - · exact uIcc_comm b a ▸ @this f b a hf.symm (by linarith) + · exact uIcc_comm b a ▸ this hf.symm (by linarith) rw [uIcc_of_le hab] have h₁ : ∀ᵐ x, x ≠ a := by simp [ae_iff, measure_singleton] have h₂ : ∀ᵐ x, x ≠ b := by simp [ae_iff, measure_singleton] From aea5d67c4f9b8f29ea3e43c6540b3d69b8be7501 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:57:32 +0000 Subject: [PATCH 0353/1300] chore(MeasureTheory): minor clean up of seminorm lemmas (#40986) Remove a duplicate lemma and generalize some lemmas to support two different codomains. --- .../Function/LpSeminorm/Basic.lean | 23 ++++++++----------- .../Function/LpSeminorm/Indicator.lean | 8 +++---- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index 96fc1608bff08b..1e18c385d5293c 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -285,17 +285,17 @@ theorem eLpNorm'_mono_ae {f : α → F} {g : α → G} (hq : 0 ≤ q) (h : ∀ eLpNorm' f q μ ≤ eLpNorm' g q μ := eLpNorm'_mono_enorm_ae hq (by simpa only [enorm_le_iff_norm_le] using h) -theorem eLpNorm'_congr_enorm_ae {f g : α → ε} (hfg : ∀ᵐ x ∂μ, ‖f x‖ₑ = ‖g x‖ₑ) : +theorem eLpNorm'_congr_enorm_ae {f : α → ε} {g : α → ε'} (hfg : ∀ᵐ x ∂μ, ‖f x‖ₑ = ‖g x‖ₑ) : eLpNorm' f q μ = eLpNorm' g q μ := by have : (‖f ·‖ₑ ^ q) =ᵐ[μ] (‖g ·‖ₑ ^ q) := hfg.mono fun x hx ↦ by simp [hx] simp only [eLpNorm'_eq_lintegral_enorm, lintegral_congr_ae this] -theorem eLpNorm'_congr_nnnorm_ae {f g : α → F} (hfg : ∀ᵐ x ∂μ, ‖f x‖₊ = ‖g x‖₊) : +theorem eLpNorm'_congr_nnnorm_ae {f : α → F} {g : α → G} (hfg : ∀ᵐ x ∂μ, ‖f x‖₊ = ‖g x‖₊) : eLpNorm' f q μ = eLpNorm' g q μ := by have : (‖f ·‖ₑ ^ q) =ᵐ[μ] (‖g ·‖ₑ ^ q) := hfg.mono fun x hx ↦ by simp [enorm, hx] simp only [eLpNorm'_eq_lintegral_enorm, lintegral_congr_ae this] -theorem eLpNorm'_congr_norm_ae {f g : α → F} (hfg : ∀ᵐ x ∂μ, ‖f x‖ = ‖g x‖) : +theorem eLpNorm'_congr_norm_ae {f : α → F} {g : α → G} (hfg : ∀ᵐ x ∂μ, ‖f x‖ = ‖g x‖) : eLpNorm' f q μ = eLpNorm' g q μ := eLpNorm'_congr_nnnorm_ae <| hfg.mono fun _x hx => NNReal.eq hx @@ -306,11 +306,11 @@ theorem eLpNormEssSup_congr_ae {f g : α → ε} (hfg : f =ᵐ[μ] g) : eLpNormEssSup f μ = eLpNormEssSup g μ := essSup_congr_ae (hfg.fun_comp enorm) -theorem eLpNormEssSup_mono_enorm_ae {f g : α → ε} (hfg : ∀ᵐ x ∂μ, ‖f x‖ₑ ≤ ‖g x‖ₑ) : +theorem eLpNormEssSup_mono_enorm_ae {f : α → ε} {g : α → ε'} (hfg : ∀ᵐ x ∂μ, ‖f x‖ₑ ≤ ‖g x‖ₑ) : eLpNormEssSup f μ ≤ eLpNormEssSup g μ := essSup_mono_ae <| hfg -theorem eLpNormEssSup_mono_nnnorm_ae {f g : α → F} (hfg : ∀ᵐ x ∂μ, ‖f x‖₊ ≤ ‖g x‖₊) : +theorem eLpNormEssSup_mono_nnnorm_ae {f : α → F} {g : α → G} (hfg : ∀ᵐ x ∂μ, ‖f x‖₊ ≤ ‖g x‖₊) : eLpNormEssSup f μ ≤ eLpNormEssSup g μ := essSup_mono_ae <| hfg.mono fun _x hx => ENNReal.coe_le_coe.mpr hx @@ -319,7 +319,7 @@ theorem eLpNorm_mono_enorm_ae {f : α → ε} {g : α → ε'} (h : ∀ᵐ x ∂ simp only [eLpNorm] split_ifs · exact le_rfl - · exact essSup_mono_ae h + · exact eLpNormEssSup_mono_enorm_ae h · exact eLpNorm'_mono_enorm_ae ENNReal.toReal_nonneg h theorem eLpNorm_mono_nnnorm_ae {f : α → F} {g : α → G} (h : ∀ᵐ x ∂μ, ‖f x‖₊ ≤ ‖g x‖₊) : @@ -330,10 +330,7 @@ theorem eLpNorm_mono_ae {f : α → F} {g : α → G} (h : ∀ᵐ x ∂μ, ‖f eLpNorm f p μ ≤ eLpNorm g p μ := eLpNorm_mono_enorm_ae (by simpa only [enorm_le_iff_norm_le] using h) -theorem eLpNorm_mono_ae' {ε' : Type*} [ENorm ε'] - {f : α → ε} {g : α → ε'} (h : ∀ᵐ x ∂μ, ‖f x‖ₑ ≤ ‖g x‖ₑ) : - eLpNorm f p μ ≤ eLpNorm g p μ := - eLpNorm_mono_enorm_ae (by simpa only [enorm_le_iff_norm_le] using h) +@[deprecated (since := "2026-06-24")] alias eLpNorm_mono_ae' := eLpNorm_mono_enorm_ae theorem eLpNorm_mono_ae_real {f : α → F} {g : α → ℝ} (h : ∀ᵐ x ∂μ, ‖f x‖ ≤ g x) : eLpNorm f p μ ≤ eLpNorm g p μ := @@ -501,7 +498,7 @@ variable {ε ε' : Type*} theorem MemLp.of_le_enorm {f : α → ε} {g : α → ε'} (hg : MemLp g p μ) (hf : AEStronglyMeasurable f μ) (hfg : ∀ᵐ x ∂μ, ‖f x‖ₑ ≤ ‖g x‖ₑ) : MemLp f p μ := - ⟨hf, (eLpNorm_mono_ae' hfg).trans_lt (by finiteness)⟩ + ⟨hf, (eLpNorm_mono_enorm_ae hfg).trans_lt (by finiteness)⟩ theorem MemLp.of_le {f : α → E} {g : α → F} (hg : MemLp g p μ) (hf : AEStronglyMeasurable f μ) (hfg : ∀ᵐ x ∂μ, ‖f x‖ ≤ ‖g x‖) : MemLp f p μ := @@ -762,8 +759,8 @@ theorem eLpNorm_eq_zero_of_ae_zero {f : α → ε} (hf : f =ᵐ[μ] 0) : eLpNorm theorem eLpNorm'_eq_zero_of_ae_eq_zero {f : α → ε} {p : ℝ} (hp : 0 < p) (hf : ∀ᵐ (x : α) ∂μ, ‖f x‖ₑ = 0) : eLpNorm' f p μ = 0 := by - rw [← eLpNorm'_zero hp (μ := μ) (ε := ε), eLpNorm'_congr_enorm_ae] - simp only [hf, Pi.zero_apply, enorm_zero] + rw [← eLpNorm'_zero hp (μ := μ) (ε := ε)] + exact eLpNorm'_congr_enorm_ae (by simp [hf]) variable {ε : Type*} [ENorm ε] in theorem ae_le_eLpNormEssSup {f : α → ε} : ∀ᵐ y ∂μ, ‖f y‖ₑ ≤ eLpNormEssSup f μ := diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean index 7a4da8882b40b4..4bfab0e33c6d3a 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean @@ -60,13 +60,13 @@ lemma eLpNorm_restrict_le (f : α → ε') (p : ℝ≥0∞) (μ : Measure α) (s lemma eLpNorm_indicator_le (f : α → ε) : eLpNorm (s.indicator f) p μ ≤ eLpNorm f p μ := by - refine eLpNorm_mono_ae' <| .of_forall fun x ↦ ?_ - rw [enorm_indicator_eq_indicator_enorm] - exact s.indicator_le_self _ x + apply eLpNorm_mono_enorm + simp_rw [enorm_indicator_eq_indicator_enorm] + exact s.indicator_le_self _ lemma eLpNormEssSup_indicator_le (s : Set α) (f : α → ε) : eLpNormEssSup (s.indicator f) μ ≤ eLpNormEssSup f μ := by - refine essSup_mono_ae (Eventually.of_forall fun x => ?_) + refine essSup_mono_ae (.of_forall fun x => ?_) simp_rw [enorm_indicator_eq_indicator_enorm] exact Set.indicator_le_self s _ x From 83a37978d0b810119c3f74efe0c2b0a6264a5de9 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:57:46 +0000 Subject: [PATCH 0354/1300] chore: add star lemmas for congruence relations (#40919) This can in future replace a similar lemma for `RingQuot`. The old copyright is because this was derived from `Mathlib/Algebra/Star/RingQuot.lean`. --- Mathlib.lean | 2 + Mathlib/GroupTheory/Congruence/Star.lean | 53 ++++++++++++++++++++++++ Mathlib/RingTheory/Congruence/Star.lean | 38 +++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 Mathlib/GroupTheory/Congruence/Star.lean create mode 100644 Mathlib/RingTheory/Congruence/Star.lean diff --git a/Mathlib.lean b/Mathlib.lean index 766e023cdb5735..92067dc839f781 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4715,6 +4715,7 @@ public import Mathlib.GroupTheory.Congruence.BigOperators public import Mathlib.GroupTheory.Congruence.Defs public import Mathlib.GroupTheory.Congruence.Hom public import Mathlib.GroupTheory.Congruence.Opposite +public import Mathlib.GroupTheory.Congruence.Star public import Mathlib.GroupTheory.Coprod.Basic public import Mathlib.GroupTheory.CoprodI public import Mathlib.GroupTheory.Coset.Basic @@ -6474,6 +6475,7 @@ public import Mathlib.RingTheory.Congruence.BigOperators public import Mathlib.RingTheory.Congruence.Defs public import Mathlib.RingTheory.Congruence.Hom public import Mathlib.RingTheory.Congruence.Opposite +public import Mathlib.RingTheory.Congruence.Star public import Mathlib.RingTheory.Coprime.Basic public import Mathlib.RingTheory.Coprime.Ideal public import Mathlib.RingTheory.Coprime.Lemmas diff --git a/Mathlib/GroupTheory/Congruence/Star.lean b/Mathlib/GroupTheory/Congruence/Star.lean new file mode 100644 index 00000000000000..dc4db4b4432140 --- /dev/null +++ b/Mathlib/GroupTheory/Congruence/Star.lean @@ -0,0 +1,53 @@ +/- +Copyright (c) 2020 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ +module + +public import Mathlib.GroupTheory.Congruence.Basic +public import Mathlib.Algebra.Star.Basic + +/-! +# Helpers for working with star operators on quotients. + +TODO: consider defining `Star` versions of `Con` and `AddCon`. +-/ + +@[expose] public section + +section Mul +variable {M : Type*} [Mul M] [StarMul M] {r : M → M → Prop} + +theorem ConGen.Rel.star (hr : ∀ a b, r a b → r (star a) (star b)) + ⦃a b : M⦄ : Rel r a b → Rel r (star a) (star b) + | refl _ => .refl _ + | symm h => .symm <| h.star hr + | trans h1 h2 => .trans (h1.star hr) (h2.star hr) + | of _ _ h => .of _ _ (hr _ _ h) + | mul h1 h2 => by + rw [star_mul, star_mul] + exact (h2.star hr).mul (h1.star hr) + +theorem conGen_star (hr : ∀ a b, r a b → r (star a) (star b)) ⦃a b : M⦄ : + conGen r a b → conGen r (star a) (star b) := (ConGen.Rel.star hr ·) + +end Mul + +section Add +variable {A : Type*} [AddMonoid A] [StarAddMonoid A] {r : A → A → Prop} + +theorem AddConGen.Rel.star (hr : ∀ a b, r a b → r (star a) (star b)) + ⦃a b : A⦄ : Rel r a b → Rel r (star a) (star b) + | refl _ => .refl _ + | symm h => .symm <| h.star hr + | trans h1 h2 => .trans (h1.star hr) (h2.star hr) + | of _ _ h => .of _ _ (hr _ _ h) + | add h1 h2 => by + rw [star_add, star_add] + exact (h1.star hr).add (h2.star hr) + +theorem addConGen_star (hr : ∀ a b, r a b → r (star a) (star b)) ⦃a b : A⦄ : + addConGen r a b → addConGen r (star a) (star b) := (AddConGen.Rel.star hr ·) + +end Add diff --git a/Mathlib/RingTheory/Congruence/Star.lean b/Mathlib/RingTheory/Congruence/Star.lean new file mode 100644 index 00000000000000..b8ed4c30fc26b2 --- /dev/null +++ b/Mathlib/RingTheory/Congruence/Star.lean @@ -0,0 +1,38 @@ +/- +Copyright (c) 2020 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ +module + +public import Mathlib.RingTheory.Congruence.Basic +public import Mathlib.Algebra.Star.Basic + +/-! +# Helpers for working with star operators on quotients. + +TODO: consider defining `Star` versions of `RingCon`. +-/ + +@[expose] public section + +section Ring +variable {R : Type*} [NonUnitalNonAssocSemiring R] [StarRing R] {r : R → R → Prop} + +theorem RingConGen.Rel.star (hr : ∀ a b, r a b → r (star a) (star b)) + ⦃a b : R⦄ : Rel r a b → Rel r (star a) (star b) + | refl _ => .refl _ + | symm h => .symm <| h.star hr + | trans h1 h2 => .trans (h1.star hr) (h2.star hr) + | of _ _ h => .of _ _ (hr _ _ h) + | mul h1 h2 => by + rw [star_mul, star_mul] + exact (h2.star hr).mul (h1.star hr) + | add h1 h2 => by + rw [star_add, star_add] + exact (h1.star hr).add (h2.star hr) + +theorem ringConGen_star (hr : ∀ a b, r a b → r (star a) (star b)) ⦃a b : R⦄ : + ringConGen r a b → ringConGen r (star a) (star b) := (RingConGen.Rel.star hr ·) + +end Ring From 20711864f1a4827da127b722f1e2fa5e90486f6d Mon Sep 17 00:00:00 2001 From: Arend Mellendijk <8759745+amellendijk@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:06:05 +0000 Subject: [PATCH 0355/1300] feat(Tactic): `polynomial(_nf)` tactics (#31513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement tactic for proving equality of polynomials. This tactic is part of a larger suite (see https://github.com/leanprover-community/mathlib4/pull/30374). Also generalize the preprocessing step for `algebra` so that it always replaces `algebraMap R A r` with `r • 1` instead of only when `R` is `Nat` or `Int`. This was an oversight in `algebra` that broke `polynomial`. - [x] depends on: #31508 --- Mathlib.lean | 3 + Mathlib/Algebra/MvPolynomial/Basic.lean | 20 ++- Mathlib/RingTheory/Polynomial/Basic.lean | 2 +- Mathlib/Tactic.lean | 3 + Mathlib/Tactic/Algebra/AlgebraNF.lean | 77 ++++++++++ Mathlib/Tactic/Algebra/Basic.lean | 51 +------ Mathlib/Tactic/Polynomial/Basic.lean | 179 +++++++++++++++++++++++ Mathlib/Tactic/Polynomial/Core.lean | 100 +++++++++++++ MathlibTest/Tactic/Polynomial.lean | 82 +++++++++++ 9 files changed, 468 insertions(+), 49 deletions(-) create mode 100644 Mathlib/Tactic/Algebra/AlgebraNF.lean create mode 100644 Mathlib/Tactic/Polynomial/Basic.lean create mode 100644 Mathlib/Tactic/Polynomial/Core.lean create mode 100644 MathlibTest/Tactic/Polynomial.lean diff --git a/Mathlib.lean b/Mathlib.lean index 92067dc839f781..66d8dccb727666 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7165,6 +7165,7 @@ public import Mathlib.SetTheory.ZFC.VonNeumann public import Mathlib.Tactic public import Mathlib.Tactic.Abel public import Mathlib.Tactic.AdaptationNote +public import Mathlib.Tactic.Algebra.AlgebraNF public import Mathlib.Tactic.Algebra.Basic public import Mathlib.Tactic.Algebra.Lemmas public import Mathlib.Tactic.Algebraize @@ -7421,6 +7422,8 @@ public import Mathlib.Tactic.Order.ToInt public import Mathlib.Tactic.PNatToNat public import Mathlib.Tactic.PPWithUniv public import Mathlib.Tactic.Peel +public import Mathlib.Tactic.Polynomial.Basic +public import Mathlib.Tactic.Polynomial.Core public import Mathlib.Tactic.Polyrith public import Mathlib.Tactic.Positivity public import Mathlib.Tactic.Positivity.Basic diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 74f35d21f7e3d5..8c0bd485a58ea7 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -15,6 +15,7 @@ public import Mathlib.Algebra.Regular.Pow public import Mathlib.Data.Finsupp.Antidiagonal public import Mathlib.Data.Finsupp.Order public import Mathlib.Order.SymmDiff +public meta import Mathlib.Tactic.Polynomial.Core /-! # Multivariate polynomials @@ -106,10 +107,14 @@ def C : R →+* MvPolynomial σ R := variable (R σ) -@[simp] +@[simp, polynomial_post] theorem algebraMap_eq : algebraMap R (MvPolynomial σ R) = C := rfl +@[polynomial_pre] +theorem C_eq_algebraMap : MvPolynomial.C = algebraMap R (MvPolynomial σ R) := + rfl + variable {R σ} @[simp] @@ -1078,4 +1083,17 @@ end coeffsIn end CommSemiring +meta section Meta + +open Mathlib.Tactic.Polynomial in +/-- Infer base ring for `MvPolynomial _ R`. Used by the `polynomial` tactic. -/ +@[polynomial_infer_base] +def mvPolynomialInferBaseImpl : PolynomialExt where + infer e := do + match_expr e with + | MvPolynomial _ R _ => pure R + | _ => failure + +end Meta + end MvPolynomial diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index efa4f23011e935..96e51ee43704b3 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -926,7 +926,7 @@ lemma aeval_natDegree_le {R : Type*} [CommSemiring R] {m n : ℕ} apply (Polynomial.natDegree_sum_le _ _).trans apply Finset.sup_le intro d hd - simp_rw [Function.comp_apply, ← C_eq_algebraMap] + simp_rw [Function.comp_apply, ← Polynomial.C_eq_algebraMap] apply (Polynomial.natDegree_C_mul_le _ _).trans apply (Polynomial.natDegree_prod_le _ _).trans have : ∑ i ∈ d.support, (d i) * n ≤ m * n := by diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 02d86792ef5678..b09c506d6e6a86 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -2,6 +2,7 @@ module -- shake: keep-all --deprecated_module: ignore public import Mathlib.Tactic.Abel public import Mathlib.Tactic.AdaptationNote +public import Mathlib.Tactic.Algebra.AlgebraNF public import Mathlib.Tactic.Algebra.Basic public import Mathlib.Tactic.Algebra.Lemmas public import Mathlib.Tactic.Algebraize @@ -258,6 +259,8 @@ public import Mathlib.Tactic.Order.ToInt public import Mathlib.Tactic.PNatToNat public import Mathlib.Tactic.PPWithUniv public import Mathlib.Tactic.Peel +public import Mathlib.Tactic.Polynomial.Basic +public import Mathlib.Tactic.Polynomial.Core public import Mathlib.Tactic.Polyrith public import Mathlib.Tactic.Positivity public import Mathlib.Tactic.Positivity.Basic diff --git a/Mathlib/Tactic/Algebra/AlgebraNF.lean b/Mathlib/Tactic/Algebra/AlgebraNF.lean new file mode 100644 index 00000000000000..04730c671c32ba --- /dev/null +++ b/Mathlib/Tactic/Algebra/AlgebraNF.lean @@ -0,0 +1,77 @@ +/- +Copyright (c) 2025 Arend Mellendijk. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Arend Mellendijk +-/ +module + +public import Mathlib.Tactic.Algebra.Basic + +/-! # The `algebra_nf` tactic + +This file contains helper functions for the (currently unimplemented) `algebra_nf` tactic. + +The defnitions in this file are currently only used by `polynomial_nf`. +-/ + +public meta section + +open Lean Meta Qq Mathlib.Tactic.Ring + +namespace Mathlib.Tactic.Algebra + +/-- Clean up the normal form into a more human-friendly format. This does everything + `RingNF.cleanup` does and also pulls the scalar multiplication from the end of of each term to + the start. i.e. x * y * (r • 1) → r • (x * y) + Used by `cleanup`. -/ +def cleanupSMul (cfg : RingNF.Config) (r : Simp.Result) : MetaM Simp.Result := do + let thms : SimpTheorems := {} + let thms ← [``add_zero, ``add_assoc_rev, ``_root_.mul_one, ``mul_assoc_rev, ``_root_.pow_one, + ``mul_neg, ``add_neg, ``one_smul, ``mul_smul_comm, ``Algebra.algebraMap_eq_smul_one + ].foldlM (·.addConst ·) thms + let thms ← [``nat_rawCast_0, ``nat_rawCast_1, ``nat_rawCast_2, ``int_rawCast_neg, + ``nnrat_rawCast, ``rat_rawCast_neg].foldlM (·.addConst · (post := false)) thms + let ctx ← Simp.mkContext { zetaDelta := cfg.zetaDelta } + (simpTheorems := #[thms]) + (congrTheorems := ← getSimpCongrTheorems) + pure <| ← + r.mkEqTrans (← Simp.main r.expr ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 + +/-- Turn scalar multiplication by an explicit constant in `R` into multiplication in `A`. + +e.g. `(4 : ℚ) • x` becomes `4 * x` but `↑n • x` stays `↑n • x`. +-/ +def cleanupConsts (cfg : RingNF.Config) (r : Simp.Result) : MetaM Simp.Result := do + let thms : SimpTheorems := {} + let thms ← [``add_zero, ``_root_.one_mul, ``_root_.mul_one, + ``neg_mul, ``add_neg].foldlM (·.addConst ·) thms + let thms ← [``ofNat_smul, ``neg_ofNat_smul, ``neg_1_smul, ``nnRat_ofNat_smul_1, + ``nnRat_ofNat_smul_2, ``rat_ofNat_smul_1, ``rat_ofNat_smul_2 + ].foldlM (·.addConst · (post := false)) thms + let ctx ← Simp.mkContext { zetaDelta := cfg.zetaDelta } + (simpTheorems := #[thms]) + (congrTheorems := ← getSimpCongrTheorems) + pure <| ← + r.mkEqTrans (← Simp.main r.expr ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 + +/-- The core of `algebra_nf with R` - normalize the expression `e` over the base ring `R` +Also used internally in `polynomial_nf`. -/ +meta def evalExpr {u : Lean.Level} (R : Q(Type u)) (e : Expr) : AtomM Simp.Result := do + let e ← withReducible <| whnf e + guard e.isApp -- all interesting ring expressions are applications + let ⟨v, A, e⟩ ← inferTypeQ' e + let sA ← synthInstanceQ q(CommSemiring $A) + let sR ← synthInstanceQ q(CommSemiring $R) + let sAlg ← synthInstanceQ q(Algebra $R $A) + let cr ← Algebra.mkCache sR + let ca ← Algebra.mkCache sA + assumeInstancesCommute + let ⟨a, _, pa⟩ ← match + ← Common.isAtomOrDerivable (Algebra.ringCompute q($sAlg) cr ca) ca.toCache q($e) with + -- `none` indicates that `eval` will find something algebraic. + | none => Common.eval rcℕ (Algebra.ringCompute sAlg cr ca) ca.toCache e + | some none => failure -- No point rewriting atoms + | some (some r) => pure r -- Nothing algebraic for `eval` to use, but `norm_num` simplifies. + pure { expr := a, proof? := pa } + +end Mathlib.Tactic.Algebra diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index cda5ca25b7cf19..a01cf768db41cd 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -9,7 +9,6 @@ public meta import Lean.Meta.Tactic.NormCast public import Mathlib.Tactic.Algebra.Lemmas public import Mathlib.Tactic.Ring.RingNF - /-! # The `algebra` tactic A suite of three tactics for solving equations in commutative algebras over commutative (semi)rings, @@ -295,59 +294,17 @@ open Lean Parser.Tactic Elab Command Elab.Tactic Meta Qq theorem Nat.cast_eq_algebraMap (A : Type*) [CommSemiring A] (n : ℕ) : Nat.cast n = algebraMap ℕ A n := rfl -theorem Nat.algebraMap_eq_cast (A : Type*) [CommSemiring A] (n : ℕ) : - algebraMap ℕ A n = Nat.cast n := rfl - theorem Int.cast_eq_algebraMap (A : Type*) [CommRing A] (n : ℤ) : Int.cast n = algebraMap ℤ A n := rfl -theorem Int.algebraMap_eq_cast (A : Type*) [CommRing A] (n : ℤ) : - algebraMap ℤ A n = Int.cast n := rfl - /-- Remove some nonstandard spellings of `algebraMap` such as `Nat.cast` -/ -def preprocess (mvarId : MVarId) : MetaM MVarId := do +def preprocess (e : Expr) : MetaM Simp.Result := do -- collect the available `push_cast` lemmas let thms : SimpTheorems := {} let thms ← [``Nat.cast_eq_algebraMap, ``Int.cast_eq_algebraMap, ``Algebra.algebraMap_eq_smul_one].foldlM (·.addConst ·) thms let ctx ← Simp.mkContext { failIfUnchanged := false } (simpTheorems := #[thms]) - let (some r, _) ← simpTarget mvarId ctx (simprocs := #[]) | - throwError "internal error in polynomial tactic: preprocessing should not close goals" - return r - -/-- Clean up the normal form into a more human-friendly format. This does everything - `RingNF.cleanup` does and also pulls the scalar multiplication from the end of of each term to - the start. i.e. x * y * (r • 1) → r • (x * y) - Used by `cleanup`. -/ -def cleanupSMul (cfg : RingNF.Config) (r : Simp.Result) : MetaM Simp.Result := do - let thms : SimpTheorems := {} - let thms ← [``add_zero, ``add_assoc_rev, ``_root_.mul_one, ``mul_assoc_rev, ``_root_.pow_one, - ``mul_neg, ``add_neg, ``one_smul, ``mul_smul_comm, ``Nat.algebraMap_eq_cast, - ``Int.algebraMap_eq_cast].foldlM (·.addConst ·) thms - let thms ← [``nat_rawCast_0, ``nat_rawCast_1, ``nat_rawCast_2, ``int_rawCast_neg, - ``nnrat_rawCast, ``rat_rawCast_neg].foldlM (·.addConst · (post := false)) thms - let ctx ← Simp.mkContext { zetaDelta := cfg.zetaDelta } - (simpTheorems := #[thms]) - (congrTheorems := ← getSimpCongrTheorems) - pure <| ← - r.mkEqTrans (← Simp.main r.expr ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 - -/-- Turn scalar multiplication by an explicit constant in `R` into multiplication in `A`. - -e.g. `(4 : ℚ) • x` becomes `4 * x` but `↑n • x` stays `↑n • x`. --/ -def cleanupConsts (cfg : RingNF.Config) (r : Simp.Result) : MetaM Simp.Result := do - let thms : SimpTheorems := {} - let thms ← [``add_zero, ``_root_.one_mul, ``_root_.mul_one, - ``neg_mul, ``add_neg].foldlM (·.addConst ·) thms - let thms ← [``ofNat_smul, ``neg_ofNat_smul, ``neg_1_smul, ``nnRat_ofNat_smul_1, - ``nnRat_ofNat_smul_2, ``rat_ofNat_smul_1, ``rat_ofNat_smul_2 - ].foldlM (·.addConst · (post := false)) thms - let ctx ← Simp.mkContext { zetaDelta := cfg.zetaDelta } - (simpTheorems := #[thms]) - (congrTheorems := ← getSimpCongrTheorems) - pure <| ← - r.mkEqTrans (← Simp.main r.expr ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 + return (← Simp.main e ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 /-- Collect all scalar rings from scalar multiplications using a state monad for performance. @@ -477,14 +434,14 @@ automatically. -/ elab (name := algebra) "algebra":tactic => withMainContext do - liftMetaTactic' preprocess + liftMetaTactic1 (transformAtTarget (fun e _ ↦ preprocess e) "algebra" .silent · default) let g ← getMainGoal AtomM.run .default (proveEq none g) @[tactic_alt algebra] elab (name := algebraWith) "algebra" " with " R:term : tactic => withMainContext do - liftMetaTactic' preprocess + liftMetaTactic1 (transformAtTarget (fun e _ ↦ preprocess e) "algebra" .silent · default) let ⟨u, R⟩ ← getLevelQ' (← elabTerm R none) let g ← getMainGoal AtomM.run .default (proveEq (some ⟨u, R⟩) g) diff --git a/Mathlib/Tactic/Polynomial/Basic.lean b/Mathlib/Tactic/Polynomial/Basic.lean new file mode 100644 index 00000000000000..c2c74e5d77e67f --- /dev/null +++ b/Mathlib/Tactic/Polynomial/Basic.lean @@ -0,0 +1,179 @@ +/- +Copyright (c) 2025 Arend Mellendijk. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Arend Mellendijk +-/ + +module + +public import Mathlib.Algebra.Polynomial.AlgebraMap +public import Mathlib.Algebra.Polynomial.Coeff +public import Mathlib.Tactic.Algebra.Basic +public import Mathlib.Tactic.Algebra.AlgebraNF +public import Mathlib.Tactic.Polynomial.Core + +/-! +# Polynomial +An extensible tactic for proving equality of polynomial expressions implemented using `algebra`. +To add support for a new polynomial-like type, one needs to do three things: +* Implement a polynomial extension that lets `polynomial` infer the base ring from the algebraic + type. For example: +``` +@[polynomial_infer_base] +def polynomialInferBase : PolynomialExt where + infer e := do + match_expr e with + | Polynomial R _ => pure R + | _ => failure +``` +* Tag any preprocessing lemmas with @[polynomial_pre]. This would include a lemma saying that +`C = algebraMap _ _` so that `algebra` knows how to normalize it. +* Tag any postprocessing lemmas with @[polynomial_post], so that `polynomial_nf` produces a pretty +expression. +-/ + +open Lean Mathlib.Tactic Mathlib.Tactic.Algebra Parser.Tactic Elab Meta Qq + +public meta section + +namespace Mathlib.Tactic.Polynomial + +/-- Infer base ring for `Polynomial R` -/ +@[polynomial_infer_base] +def polynomialInferBase : PolynomialExt where + infer e := do + match_expr e with + | Polynomial R _ => pure R + | _ => failure + +section Lemmas + +variable {σ R A : Type*} [CommSemiring R] [CommSemiring A] [Algebra R A] + +attribute [polynomial_post] mul_one Algebra.smul_def Polynomial.algebraMap_eq + +@[polynomial_pre] +theorem monomial_eq_smul (a : R) (n : ℕ) : Polynomial.monomial n a = a • (.X ^ n) := by + rw [← Polynomial.C_mul_X_pow_eq_monomial, Polynomial.smul_eq_C_mul] + +-- `polynomial_pre` contains a lemma sending `C -> algebraMap`, so `C` is not simp normal form. +@[polynomial_pre] +theorem map_algebraMap (r : R) : + Polynomial.map (algebraMap R A) (algebraMap R (Polynomial R) r) = + algebraMap A (Polynomial A) (algebraMap R A r) := by + simp + +end Lemmas + +open Mathlib.Meta AtomM + +attribute [polynomial_pre] Polynomial.C_eq_algebraMap + Polynomial.monomial_eq_smul Polynomial.map_add Polynomial.map_mul Polynomial.map_pow + Polynomial.map_X Polynomial.map_natCast Polynomial.map_intCast + +/- TODO: we don't currently have a good way to normalize monomials of MvPolynomials. These are +indexed by finsupps, making it difficult to turn into the appropriate normal form. -/ +/-- Run the `polynomial_pre` simpset to turn nonstandard spellings of `algebraMap` such as +`Polynomial.C` into `algebraMap` -/ +def preprocess (e : Expr) : MetaM Simp.Result := do + let preThms ← polynomialPreExt.getTheorems + let ctx ← Simp.mkContext { failIfUnchanged := false } (simpTheorems := #[preThms]) + pure (← Simp.main e ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 + +open Tactic + +/-- `polynomial` solves equalities of `Polynomial`s and similar types. + +Given a goal which is an equality in `Polynomial R` with a commutative ring `R`, `polynomial` +turns both sides of the equation into a normal form by expanding out the brackets. It then closes +the goal if both sides contain the same terms and fails otherwise. `polynomial_nf` normalizes all +subexpressions at a given location. + +Variants of `polynomial` include: +* `polynomial`: normalize both sides of an equation and close the goal if they are equal +* `polynomial!`: run `polynomial` at default transparency +* `polynomial_nf`: normalize all subexpression of the goal +* `polynomial_nf at h₁ h₂ ⊢`: normalize all subexpressions at hypotheses `h₁` `h₁` and the goal +* `polynomial_nf at *`: normalize all subexpressions of all local hypotheses and the goal +* `polynomial_nf!`: run `polynomial_nf` at default transparency + +The `polynomial` tactic can be extended to work with algebras other than `Polynomial` using the +attributes `polynomial_infer_base`, `polynomial_pre` and `polynomial_post`. This is only possible +if the base ring can be inferred from the structure of the type. + +Examples: + +``` +example (a : ℚ) : (X + C a) * (X - C a) = X^2 + C (a^2) := by polynomial + +example {P : ℚ[X] → Prop} (h : P (X ^ 2 + X + C 4⁻¹)) : P ((X + C 2⁻¹) ^ 2) := by + polynomial_nf at h ⊢ + exact h +``` + +-/ +elab (name := polynomial) "polynomial" tk:"!"? : tactic => + withMainContext do + let g ← getMainGoal + let some (α, _, _) := (← whnfR <|← instantiateMVars <|← g.getType).eq? + | throwError "polynomial failed: not an equality" + let mut β : Expr := default + try + β ← Polynomial.inferBase α + catch _ => + throwError "polynomial failed: not an equality of (mv)polynomials" + let some g ← transformAtTarget (fun e _ ↦ Polynomial.preprocess e) "polynomial" .silent g + default | done + let some g ← transformAtTarget (fun e _ ↦ Algebra.preprocess e) "polynomial" .silent g + default | done + AtomM.run (if tk.isSome then .default else .reducible) + (Algebra.proveEq (some (← getLevelQ' β)) g) + +@[tactic_alt polynomial] +macro "polynomial!" : tactic => `(tactic| polynomial !) + +/-- A cleanup routine, which simplifies normalized expressions to a more human-friendly format. +This is the `algebra_nf` cleanup routine with a little extra work to turn scalar multiplication +into `(MV)Polynomial.C` -/ +def cleanup (cfg : RingNF.Config) (r : Simp.Result) : MetaM Simp.Result := do + match cfg.mode with + | .raw => pure r + | .SOP => do + let r ← cleanupSMul cfg r + let thms : SimpTheorems ← polynomialPostExt.getTheorems + let ctx ← Simp.mkContext { zetaDelta := cfg.zetaDelta } + (simpTheorems := #[thms]) + (congrTheorems := ← getSimpCongrTheorems) + pure <| ← + r.mkEqTrans (← Simp.main r.expr ctx (methods := Lean.Meta.Simp.mkDefaultMethodsCore {})).1 + +/-- Normalize a polynomial expression into standard form. Used by `polynomial_nf`. -/ +def evalExprPoly (e : Expr) : AtomM Simp.Result := do + let ⟨_, α, e⟩ ← inferTypeQ e + let mut R : Expr := default + try R ← inferBase α + catch _ => throwError "not a polynomial" + let r₁ ← Polynomial.preprocess e + let r₂ ← Algebra.preprocess r₁.expr + let ⟨_, R'⟩ ← getLevelQ' R + let r₃ ← evalExpr R' r₂.expr + (← r₁.mkEqTrans r₂).mkEqTrans r₃ + +@[tactic_alt polynomial] +elab (name := polynomialNF) "polynomial_nf" tk:"!"? loc:(location)? : tactic => withMainContext do + let mut cfg := {} + if tk.isSome then cfg := { cfg with red := .default, zetaDelta := true } + let loc := (loc.map expandLocation).getD (.targets #[] true) + let s ← IO.mkRef {} + let m := AtomM.recurse s cfg.toConfig (wellBehavedDischarge := true) (evalExprPoly) (cleanup cfg) + transformAtLocation (m ·) "polynomial_nf" loc cfg.ifUnchanged false + +@[tactic_alt polynomial] +macro "polynomial_nf!" loc:(location)? : tactic => + `(tactic| polynomial_nf ! $(loc)?) + +end Mathlib.Tactic.Polynomial + +open Polynomial + +end diff --git a/Mathlib/Tactic/Polynomial/Core.lean b/Mathlib/Tactic/Polynomial/Core.lean new file mode 100644 index 00000000000000..1c7ab0c3e182c1 --- /dev/null +++ b/Mathlib/Tactic/Polynomial/Core.lean @@ -0,0 +1,100 @@ +/- +Copyright (c) 2025 Arend Mellendijk. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Arend Mellendijk +-/ +module + +meta import Lean.Compiler.IR.CompilerM +public meta import Lean.Meta.Tactic.Simp.Attr +public import Mathlib.Init + +/-! +# Setup for the `polynomial` tactic + +This file initializes the environment extensions and simp sets used by the `polynomial` tactic. + +These extensions let downstream users use their own polynomial-like types (such as `PowerSeries`) +with the `polynomial` tactic suite. +-/ + +namespace Mathlib.Tactic.Polynomial + +open Lean Lean.Meta Lean.Elab Term + +public meta section + +/-- `polynomial_pre` marks a theorem to be used by the `polynomial` tactic as a preprocessing lemma. +These serve the purpose of removing any definitions specific to polynomials that `algebra` can't +handle. e.g. `Polynomial.C` and `Polynomial.map` -/ +initialize polynomialPreExt : SimpExtension ← + registerSimpAttr `polynomial_pre "\ + The `polynomial_pre` simp attribute uses preprocessing lemmas \ + to turn specialized functions into `algebraMap`s" + +/-- `polynomial_post` marks a theorem to be used by the `polynomial_nf` tactic as a postprocessing +lemma. Used only by polynomial_nf. These serve the purpose of rewriting expressions in `algebra` +normal form into a more readable form. e.g. `a • X` -> `algebraMap _ _ a * X` -> `C a * X`. -/ +initialize polynomialPostExt : SimpExtension ← + registerSimpAttr `polynomial_post "\ + The `polynomial_post` simp attribute uses postprocessing lemmas \ + to turn `algebraMap`s into more specialized functions." + +/-- `polynomial_infer_base` marks a procedure used by the `polynomial` tactic to infer +the base ring of polynomial-like types. -/ +syntax (name := PolyInferBaseAttr) "polynomial_infer_base" : attr + +/-- An extension for `polynomial`. -/ +structure PolynomialExt where + /-- Attempts to infer the base `R` of an `Algebra R A` based only on `A`. e.g. returns `R` given + `Polynomial R`. -/ + infer : Expr → MetaM Expr + +/-- Read a `polynomial` extension from a declaration of the right type. -/ +def mkPolynomialExt (n : Name) : ImportM PolynomialExt := do + let { env, opts, .. } ← read + IO.ofExcept <| unsafe env.evalConstCheck PolynomialExt opts ``PolynomialExt n + +/-- Environment extensions for `polynomial` declarations -/ +initialize polynomialExt : PersistentEnvExtension Name (Name × PolynomialExt) + (List Name × List (Name × PolynomialExt)) ← + registerPersistentEnvExtension { + mkInitial := pure ([], {}) + addImportedFn := fun s => do + let dt ← s.foldlM (init := {}) fun dt s => s.foldlM (init := dt) fun dt n => do + return (n, ← mkPolynomialExt n) :: dt + pure ([], dt) + addEntryFn := fun (entries, s) (n, ext) => (n :: entries, (n, ext) :: s) + exportEntriesFn := fun s => s.1.reverse.toArray + } + +initialize registerBuiltinAttribute { + name := `PolyInferBaseAttr + descr := "adds a polynomial extension that infers the base ring of a polynomial-like type" + applicationTime := .afterCompilation + add := fun declName stx kind => match stx with + | `(attr| polynomial_infer_base) => do + unless kind == AttributeKind.global do + throwError "invalid attribute 'polynomial_infer_base', must be global" + let env ← getEnv + unless (env.getModuleIdxFor? declName).isNone do + throwError "invalid attribute 'polynomial_infer_base', declaration is in an imported module" + if (IR.getSorryDep env declName).isSome then return -- ignore in progress definitions + let ext ← mkPolynomialExt declName + setEnv <| polynomialExt.addEntry env (declName, ext) + | _ => throwUnsupportedSyntax +} + +/-- Infer the base ring of `Polynomial`-like types that are registered using the `polynomial` +environment extensions. Includes e.g. `Polynomial` and `MvPolynomial`. -/ +def inferBase (e : Expr) : MetaM Expr := do + for ⟨_, ext⟩ in (polynomialExt.getState (← getEnv)).2 do + try + return ← ext.infer e + catch _ => + continue + failure + +end + +end Mathlib.Tactic.Polynomial diff --git a/MathlibTest/Tactic/Polynomial.lean b/MathlibTest/Tactic/Polynomial.lean new file mode 100644 index 00000000000000..72444858f74bb8 --- /dev/null +++ b/MathlibTest/Tactic/Polynomial.lean @@ -0,0 +1,82 @@ +module +import Mathlib.Tactic.Polynomial.Basic +import Mathlib.RingTheory.MvPolynomial + + +/-! # The `polynomial` tactic -/ + +axiom sorryPolynomialTest {P : Prop} : P + +section poly +open Polynomial + +example (a : ℚ) : (X + C a)^2 = X^2 + C (2*a) * X + C (a^2) := by + polynomial + +example (a : ℚ) : (X + C a)^2 = X^2 + (2*a) • X + C (a^2) := by + polynomial + +example (a : ℚ) : (2*X + C a)^2 = 4 * monomial 2 1 + monomial 1 (4*a) + monomial 0 (a^2) := by + polynomial + +example (a : ℚ) : (X - C a)*(X + C a) = X^2 - C (a^2) := by + polynomial + +example (a : ℚ) : (C a * X + C 4)^2 = 0 := by + polynomial_nf + guard_target = C 16 + C (a * 8) * X + C (a ^ 2) * X ^ 2 = 0 + apply sorryPolynomialTest + +example (a b c : ℚ) : (X + C a)^2 = X^2 + C c * X + C b := by + polynomial_nf + guard_target = C (a ^ 2) + C (a * 2) * X + X ^ 2 = C b + C c * X + X ^ 2 + apply sorryPolynomialTest + +example (a : ℚ) (n : ℕ) : (X^n + C a)^2 = 0 := by + polynomial_nf + guard_target = C (a ^ 2) + C (a * 2) * X ^ n + X ^ (n * 2) = 0 + apply sorryPolynomialTest + +variable {R A : Type*} [CommRing R] [CommRing A] [Algebra R A] {r₁ : R} {a₁ : A} in +example : Polynomial.map (algebraMap R A) (C r₁ * X) = C a₁ * X := by + polynomial_nf + guard_target = C ((algebraMap R A) r₁) * X = C a₁ * X + apply sorryPolynomialTest + +example {P : ℚ[X] → Prop} (h : P (X ^ 2 + X + C 4⁻¹)) : P ((X + C 2⁻¹) ^ 2) := by + polynomial_nf at h ⊢ + exact h + +end poly + +section mvpoly +open MvPolynomial + +example (a : ℚ) : (X 0 + C a)^2 = X 0^2 + C (2*a) * X 0 + C (a^2) := by + polynomial + +example (a : ℚ) : (X 0 + C a)^2 = X 0^2 + (2*a) • X 0 + C (a^2) := by + polynomial + +example (a : ℚ) : (X 0 - C a)*(X 0 + C a) = (X 0)^2 - C (a^2) := by + polynomial + +example (a : ℚ) : (X 0 - X 1 * C a)*(X 0 + X 1 * C a) = (X 0)^2 - (X 1) ^ 2 * C (a^2) := by + polynomial + +example (a : ℚ) : ((X 0 + C a)^2).eval (fun _ ↦ -a) = 0 := by + polynomial_nf + guard_target = (eval fun i => -a) (C (a ^ 2) + C (a * 2) * X 0 + X 0 ^ 2) = 0 + apply sorryPolynomialTest + +example (a b c : ℤ) : (X 0 * C a + X 1 * X 37 * C (b*(c-1)))^2 * (X 0 - 1) = 0 := by + polynomial_nf + guard_target = C (a * b * 2 - a * b * c * 2) * (X 0 * X 1 * X 37) + + C (b ^ 2 - b ^ 2 * c * 2 + b ^ 2 * c ^ 2) * (X 0 * X 1 ^ 2 * X 37 ^ 2) + + C (-a ^ 2) * X 0 ^ 2 + + C (-(a * b * 2) + a * b * c * 2) * (X 0 ^ 2 * X 1 * X 37) + + C (a ^ 2) * X 0 ^ 3 + + C (-b ^ 2 + (b ^ 2 * c * 2 - b ^ 2 * c ^ 2)) * (X 1 ^ 2 * X 37 ^ 2) = 0 + apply sorryPolynomialTest + +end mvpoly From 4364cadca3fd031315c292bf81a8e79cb2828a22 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:32:54 +0000 Subject: [PATCH 0356/1300] feat(Order/Hom/Basic): equivalences of `Order{Hom/Embedding/Iso}` (#38667) - `OrderHom`s are equivalent to `RelHom`s of `LE` (unlike `OrderEmbedding`/`OrderIso` they aren't defined using it) - Congruence equivs for `OrderEmbedding`/`OrderIso` when the two sides are order-isomorphic. This already exists for `OrderHom`. --- Mathlib/Order/Hom/Basic.lean | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 5714f402520d64..22ef5cfb8f190a 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -285,6 +285,14 @@ def id : α →o α := instance : Inhabited (α →o α) := ⟨id⟩ +variable (α β) in +/-- Order homomorphisms are equivalent to relation homomorphisms between `LE` relations. -/ +def equivRelHom : (α →o β) ≃ @RelHom α β (· ≤ ·) (· ≤ ·) where + toFun f := ⟨f, @f.monotone⟩ + invFun f := ⟨f, @f.map_rel⟩ + left_inv _ := rfl + right_inv _ := rfl + /-- The preorder structure of `α →o β` is pointwise inequality: `f ≤ g ↔ ∀ a, f a ≤ g a`. -/ instance : Preorder (α →o β) := @Preorder.lift (α →o β) (α → β) _ DFunLike.coe @@ -929,6 +937,52 @@ from `α` and `β` to themselves are order-isomorphic. -/ def conj {α β} [Preorder α] [Preorder β] (f : α ≃o β) : (α →o α) ≃ (β →o β) := arrowCongr f f +/-- Transport an `OrderEmbedding` across a pair of `OrderIso`s, by pre- and post-composition. + +This is `Equiv.embeddingCongr`/`RelIso.relEmbeddingCongr` for `OrderEmbedding`. -/ +abbrev orderEmbeddingCongr (f : α ≃o γ) (g : β ≃o δ) : (α ↪o β) ≃ (γ ↪o δ) := + RelIso.relEmbeddingCongr f g + +@[simp] +theorem orderEmbeddingCongr_apply (f : α ≃o γ) (g : β ≃o δ) (h : α ↪o β) : + orderEmbeddingCongr f g h = .trans (.trans f.symm h) g := + rfl + +@[simp] +theorem orderEmbeddingCongr_symm_apply (f : α ≃o γ) (g : β ≃o δ) (h : γ ↪o δ) : + (orderEmbeddingCongr f g).symm h = .trans (.trans f h) g.symm := + rfl + +/-- Transport an `OrderIso` across a pair of `OrderIso`s, by pre- and post-composition. + +This is `Equiv.equivCongr`/`RelIso.relIsoCongr` for `OrderIso`. -/ +abbrev orderIsoCongr (f : α ≃o γ) (g : β ≃o δ) : (α ≃o β) ≃ (γ ≃o δ) := + RelIso.relIsoCongr f g + +@[simp] +theorem orderIsoCongr_apply (f : α ≃o γ) (g : β ≃o δ) (h : α ≃o β) : + orderIsoCongr f g h = .trans (.trans f.symm h) g := + rfl + +@[simp] +theorem orderIsoCongr_symm_apply (f : α ≃o γ) (g : β ≃o δ) (h : γ ≃o δ) : + (orderIsoCongr f g).symm h = .trans (.trans f h) g.symm := + rfl + +/-- A surjective order embedding is an order isomorphism. -/ +@[simps!] +noncomputable def ofSurjective (f : α ↪o β) (hf : Function.Surjective f) : α ≃o β := + RelIso.ofSurjective f hf + +/-- Surjective order embeddings are equivalent to order isomorphisms. -/ +@[simps apply symm_apply] +noncomputable def equivEmbeddingSurjective : + α ≃o β ≃ { f : α ↪o β // Function.Surjective f } where + toFun f := ⟨f, f.surjective⟩ + invFun f := ofSurjective f f.prop + left_inv _ := by ext; rfl + right_inv _ := rfl + /-- `Prod.swap` as an `OrderIso`. -/ def prodComm : α × β ≃o β × α where toEquiv := Equiv.prodComm α β From 5a07c5fc4c150dd4aa57cba67a56ebde2075bbf7 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Thu, 25 Jun 2026 16:37:52 +0000 Subject: [PATCH 0357/1300] feat: add nthRootsFinset_eq_of_prime and related lemmas (#40662) From flt-regular. --- Mathlib/GroupTheory/OrderOfElement.lean | 11 ++++++ .../RootsOfUnity/PrimitiveRoots.lean | 39 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index a3c866e905e6ff..b7ee3e5669e10e 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -275,6 +275,17 @@ theorem orderOf_dvd_iff_pow_eq_one {n : ℕ} : orderOf x ∣ n ↔ x ^ n = 1 := ⟨fun h => by rw [← pow_mod_orderOf, Nat.mod_eq_zero_of_dvd h, _root_.pow_zero], orderOf_dvd_of_pow_eq_one⟩ +/-- If `x ^ p = 1` for some odd `p`, then every power of `x` is an even power of `x`. -/ +@[to_additive /-- If `p • x = 0` for some odd `p`, then every multiple of `x` is an even +multiple of `x`. -/] +theorem exists_pow_eq_pow_two_mul {p : ℕ} (hx : x ^ p = 1) (hp : Odd p) (n : ℕ) : + ∃ m, x ^ n = x ^ (2 * m) := by + obtain ⟨r, rfl⟩ := hp + have key : x ^ (2 * (r + 1)) = x := by + have h2 : 2 * (r + 1) = 2 * r + 1 + 1 := by omega + rw [h2, pow_succ, hx, one_mul] + exact ⟨(r + 1) * n, by rw [← mul_assoc, pow_mul, key]⟩ + @[to_additive addOrderOf_smul_dvd] theorem orderOf_pow_dvd (n : ℕ) : orderOf (x ^ n) ∣ orderOf x := by rw [orderOf_dvd_iff_pow_eq_one, pow_right_comm, pow_orderOf_eq_one, one_pow] diff --git a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean index 783f533a4c74fe..b3e330e84338aa 100644 --- a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean +++ b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean @@ -33,6 +33,8 @@ monoids, expressing that an element is a primitive root of unity. has a primitive `k`-th root of unity, then it has `φ k` of them. * `primitiveRootsPowEquivOfCoprime`: An equivalence between `primitiveRoots k R` that takes each root to a coprime power `a`. +* `nthRootsFinset_eq_of_prime`: for `p` prime, the `p`-th roots of unity are the primitive `p`-th + roots of unity together with `1`. ## Implementation details @@ -240,6 +242,12 @@ theorem pow_of_dvd (h : IsPrimitiveRoot ζ k) {p : ℕ} (hp : p ≠ 0) (hdiv : p rw [← orderOf_pow_of_dvd hp hdiv] exact IsPrimitiveRoot.orderOf _ +/-- If `ζ` is a primitive `k`-th root of unity with `k` odd, then every power of `ζ` is an even +power of `ζ`. -/ +theorem exists_pow_eq_pow_two_mul (h : IsPrimitiveRoot ζ k) (hk : Odd k) (n : ℕ) : + ∃ m, ζ ^ n = ζ ^ (2 * m) := + _root_.exists_pow_eq_pow_two_mul h.pow_eq_one hk n + protected theorem mem_rootsOfUnity {ζ : Mˣ} {n : ℕ} (h : IsPrimitiveRoot ζ n) : ζ ∈ rootsOfUnity n M := h.pow_eq_one @@ -830,6 +838,37 @@ end Automorphisms end IsPrimitiveRoot +section nthRootsFinsetPrime + +open IsPrimitiveRoot + +variable [CommRing R] [IsDomain R] {p : ℕ} + +/-- If `p` is prime, the `p`-th roots of unity in an integral domain are exactly the primitive +`p`-th roots of unity together with `1`. -/ +theorem nthRootsFinset_eq_of_prime [DecidableEq R] (hp : p.Prime) : + nthRootsFinset p (1 : R) = primitiveRoots p R ∪ {1} := by + simp [nthRoots_one_eq_biUnion_primitiveRoots, hp.divisors] + +/-- For `p` prime, an element of `R` is a `p`-th root of unity if and only if it is either a +primitive `p`-th root of unity or `1`. -/ +theorem mem_nthRootsFinset_iff_of_prime (hp : p.Prime) {η : R} : + η ∈ nthRootsFinset p (1 : R) ↔ IsPrimitiveRoot η p ∨ η = 1 := by + classical + simp [nthRootsFinset_eq_of_prime hp, mem_primitiveRoots hp.pos, or_comm] + +/-- A `p`-th root of unity that is not `1`, with `p` prime, satisfies `IsPrimitiveRoot η p`. -/ +theorem isPrimitiveRoot_of_mem_nthRootsFinset (hp : p.Prime) {η : R} + (hη : η ∈ nthRootsFinset p (1 : R)) (hne1 : η ≠ 1) : IsPrimitiveRoot η p := + ((mem_nthRootsFinset_iff_of_prime hp).1 hη).resolve_right hne1 + +/-- A `p`-th root of unity that is not `1`, with `p` prime, is a primitive `p`-th root of unity. -/ +theorem mem_primitiveRoots_of_mem_nthRootsFinset (hp : p.Prime) {η : R} + (hη : η ∈ nthRootsFinset p (1 : R)) (hne1 : η ≠ 1) : η ∈ primitiveRoots p R := + (mem_primitiveRoots hp.pos).2 (isPrimitiveRoot_of_mem_nthRootsFinset hp hη hne1) + +end nthRootsFinsetPrime + section cyclic /-- If `G` is cyclic of order `n` and `G'` contains a primitive `n`th root of unity, From 609b527e6490d27b11731f8e4b49b7f5e0576909 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Thu, 25 Jun 2026 16:37:54 +0000 Subject: [PATCH 0358/1300] feat: add isCoprime_of_not_zeta_sub_one_dvd and related lemmas (#40906) From flt-regular. --- .../NumberField/Cyclotomic/Basic.lean | 4 ++ .../NumberField/Cyclotomic/Ideal.lean | 50 +++++++++++++++++-- .../RootsOfUnity/CyclotomicUnits.lean | 14 +++--- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index 35c65e0e82bdfa..c2a381225da3d1 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -187,6 +187,10 @@ end CharZero lemma coe_toInteger {k : ℕ} [NeZero k] (hζ : IsPrimitiveRoot ζ k) : hζ.toInteger.1 = ζ := rfl +@[simp] +lemma toInteger_coe {k : ℕ} [NeZero k] {x : 𝓞 K} (hx : IsPrimitiveRoot (x : K) k) : + hx.toInteger = x := rfl + /-- `𝓞 K ⧸ Ideal.span {ζ - 1}` is finite. -/ lemma finite_quotient_toInteger_sub_one [NumberField K] {k : ℕ} (hk : 1 < k) (hζ : IsPrimitiveRoot ζ k) : diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index e8061a821c8f55..59947f078ff144 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -47,9 +47,9 @@ namespace IsCyclotomicExtension.Rat open Ideal NumberField RingOfIntegers variable (n m p k : ℕ) [hp : Fact (Nat.Prime p)] (K : Type*) [Field K] [NumberField K] - (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver (Ideal.span {(p : ℤ)})] + (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver (span {(p : ℤ)})] -local notation3 "𝒑" => (Ideal.span {(p : ℤ)}) +local notation3 "𝒑" => (span {(p : ℤ)}) section PrimePow @@ -57,7 +57,7 @@ variable {K} [hK : IsCyclotomicExtension {p ^ (k + 1)} ℚ K] {ζ : K} (hζ : IsPrimitiveRoot ζ (p ^ (k + 1))) instance isPrime_span_zeta_sub_one : IsPrime (span {hζ.toInteger - 1}) := by - rw [Ideal.span_singleton_prime] + rw [span_singleton_prime] · exact hζ.zeta_sub_one_prime · exact Prime.ne_zero hζ.zeta_sub_one_prime @@ -77,7 +77,7 @@ theorem absNorm_span_zeta_sub_one : absNorm (span {hζ.toInteger - 1}) = p := by span_singleton_eq_span_singleton.mpr <| associated_norm_zeta_sub_one p k hζ theorem p_mem_span_zeta_sub_one : (p : 𝓞 K) ∈ span {hζ.toInteger - 1} := by - convert! Ideal.absNorm_mem _ + convert! absNorm_mem _ exact (absNorm_span_zeta_sub_one ..).symm theorem span_zeta_sub_one_ne_bot : span {hζ.toInteger - 1} ≠ ⊥ := @@ -85,7 +85,7 @@ theorem span_zeta_sub_one_ne_bot : span {hζ.toInteger - 1} ≠ ⊥ := instance liesOver_span_zeta_sub_one : (span {hζ.toInteger - 1}).LiesOver 𝒑 := by rw [liesOver_iff] - refine Ideal.IsMaximal.eq_of_le (Int.ideal_span_isMaximal_of_prime p) IsPrime.ne_top' ?_ + refine IsMaximal.eq_of_le (Int.ideal_span_isMaximal_of_prime p) IsPrime.ne_top' ?_ rw [span_singleton_le_iff_mem, mem_comap, algebraMap_int_eq, map_natCast] exact p_mem_span_zeta_sub_one p k hζ @@ -182,6 +182,46 @@ instance isPrime_span_zeta_sub_one' : IsPrime (span {hζ.toInteger - 1}) := by rw [← pow_one p] at hK hζ exact isPrime_span_zeta_sub_one p 0 hζ +/-- If `2 < p`, then `2` is not in the ideal `(ζ - 1)`, where `ζ` is a primitive `p`-th root of +unity. -/ +theorem two_not_mem_span_zeta_sub_one' (h : 2 < p) : (2 : 𝓞 K) ∉ span {hζ.toInteger - 1} := by + rw [mem_span_singleton] + rw [← pow_one p] at hK hζ + exact hζ.toInteger_sub_one_not_dvd_two h.ne' + +omit hp hK [NumberField K] in +lemma associated_sub_one_of_isPrimitiveRoot [NeZero p] {η : K} (hη : IsPrimitiveRoot η p) : + Associated (hζ.toInteger - 1) (hη.toInteger - 1) := by + obtain ⟨i, -, hi, hζη⟩ := hζ.isPrimitiveRoot_iff.mp hη + rw [show hη.toInteger = hζ.toInteger ^ i from RingOfIntegers.ext hζη.symm] + exact hζ.toInteger_isPrimitiveRoot.associated_sub_one_pow_sub_one_of_coprime hi + +omit [NumberField K] hK in +open Polynomial in +/-- `(ζ - 1) ^ (p - 1)` is associated to `p`, where `ζ` is a primitive `p`-th root of unity and +`p` is prime. -/ +theorem associated_zeta_sub_one_pow_prime : + Associated ((hζ.toInteger - 1) ^ (p - 1)) (p : 𝓞 K) := by + rw [← eval_one_cyclotomic_prime (R := 𝓞 K) (p := p), + cyclotomic_eq_prod_X_sub_primitiveRoots hζ.toInteger_isPrimitiveRoot, eval_prod] + simp only [eval_sub, eval_X, eval_C] + rw [← Nat.totient_prime hp.out, ← hζ.toInteger_isPrimitiveRoot.card_primitiveRoots, + ← Finset.prod_const] + refine Associated.prod _ _ _ fun η hη ↦ ?_ + have hη' : IsPrimitiveRoot (η : K) p := + (isPrimitiveRoot_of_mem_primitiveRoots hη).map_of_injective RingOfIntegers.coe_injective + simpa using (associated_sub_one_of_isPrimitiveRoot p hζ hη').neg_right + +/-- If `ζ - 1` does not divide `x`, then `p` and `x` are coprime, where `ζ` is a primitive `p`-th +root of unity and `p` is prime. -/ +theorem isCoprime_of_not_zeta_sub_one_dvd {x : 𝓞 K} (hx : ¬ hζ.toInteger - 1 ∣ x) : + IsCoprime (p : 𝓞 K) x := by + rwa [← isCoprime_span_singleton_iff, ← span_singleton_eq_span_singleton.mpr + (associated_zeta_sub_one_pow_prime p hζ), ← span_singleton_pow, + IsCoprime.pow_left_iff (by grind [hp.out.one_lt]), isCoprime_iff_gcd, + (prime_span_singleton_iff.mpr + hζ.zeta_sub_one_prime').irreducible.gcd_eq_one_iff, dvd_span_singleton, mem_span_singleton] + theorem inertiaDeg_span_zeta_sub_one' : inertiaDeg' (span {hζ.toInteger - 1}) ℤ = 1 := by rw [← pow_one p] at hK hζ exact inertiaDeg_span_zeta_sub_one p 0 hζ diff --git a/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean b/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean index 04235887b02e7e..3da9cd567185af 100644 --- a/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean +++ b/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean @@ -118,15 +118,13 @@ theorem associated_pow_add_sub_sub_one (hζ : IsPrimitiveRoot ζ n) (hn : 2 ≤ /-- If `p` is prime and `ζ` is a `p`-th primitive root of unity, then `ζ - 1` and `η₁ - η₂` are associated for all distinct `p`-th roots of unity `η₁` and `η₂`. -/ -lemma ntRootsFinset_pairwise_associated_sub_one_sub_of_prime (hζ : IsPrimitiveRoot ζ p) +lemma nthRootsFinset_pairwise_associated_sub_one_sub_of_prime (hζ : IsPrimitiveRoot ζ p) (hp : p.Prime) : - Set.Pairwise (nthRootsFinset p (1 : A)) (fun η₁ η₂ ↦ Associated (ζ - 1) (η₁ - η₂)) := by + Set.Pairwise (nthRootsFinset p (1 : A)) fun η₁ η₂ ↦ Associated (ζ - 1) (η₁ - η₂) := by intro η₁ hη₁ η₂ hη₂ e have : NeZero p := ⟨hp.ne_zero⟩ - obtain ⟨i, hi, rfl⟩ := - hζ.eq_pow_of_pow_eq_one ((Polynomial.mem_nthRootsFinset hp.pos 1).1 hη₁) - obtain ⟨j, hj, rfl⟩ := - hζ.eq_pow_of_pow_eq_one ((Polynomial.mem_nthRootsFinset hp.pos 1).1 hη₂) + obtain ⟨i, hi, rfl⟩ := hζ.eq_pow_of_pow_eq_one ((Polynomial.mem_nthRootsFinset hp.pos 1).1 hη₁) + obtain ⟨j, hj, rfl⟩ := hζ.eq_pow_of_pow_eq_one ((Polynomial.mem_nthRootsFinset hp.pos 1).1 hη₂) wlog hij : j ≤ i · simpa using (this hζ ‹_› ‹_› _ hj ‹_› _ hi ‹_› e.symm (by lia)).neg_right have H : (i - j).Coprime p := (coprime_of_lt_prime (by grind) (by grind) hp).symm @@ -134,4 +132,8 @@ lemma ntRootsFinset_pairwise_associated_sub_one_sub_of_prime (hζ : IsPrimitiveR simp only [hij, add_tsub_cancel_of_le] at h rw [← h, associated_mul_unit_right_iff] +@[deprecated (since := "2026-06-23")] +alias ntRootsFinset_pairwise_associated_sub_one_sub_of_prime := + nthRootsFinset_pairwise_associated_sub_one_sub_of_prime + end IsPrimitiveRoot From 51801adf31b3f9b44f0a1072aac68344dd2f82b2 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:37:57 +0000 Subject: [PATCH 0359/1300] chore(RingTheory/TensorProduct): remove left-over `noncomputable`s (#41041) These probably became non-`noncomputable` with the new compiler. --- Mathlib/RingTheory/TensorProduct/Maps.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index 0e7c4b8e3b4116..10c1e8486bc3c8 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -412,7 +412,7 @@ omit [Algebra S A] [IsScalarTower R S A] attribute [local instance] Algebra.TensorProduct.rightAlgebra in /-- `S`-linear version of `Algebra.TensorProduct.comm` when `A ⊗[R] S` is viewed as an `S`-algebra via the right component. -/ -noncomputable def commRight : S ⊗[R] A ≃ₐ[S] A ⊗[R] S where +def commRight : S ⊗[R] A ≃ₐ[S] A ⊗[R] S where __ := Algebra.TensorProduct.comm R S A commutes' _ := rfl @@ -554,11 +554,11 @@ lemma comm_comp_map_apply (f : A →ₐ[R] C) (g : B →ₐ[R] D) (x) : variable (A) in /-- `lTensor A g : A ⊗ B →ₐ A ⊗ D` is the natural algebra morphism induced by `g : B →ₐ D`. -/ -noncomputable abbrev lTensor (g : B →ₐ[R] D) : (A ⊗[R] B) →ₐ[S] (A ⊗[R] D) := map (.id S A) g +abbrev lTensor (g : B →ₐ[R] D) : (A ⊗[R] B) →ₐ[S] (A ⊗[R] D) := map (.id S A) g variable (B) in /-- `rTensor B f : A ⊗ B →ₐ C ⊗ B` is the natural algebra morphism induced by `f : A →ₐ C`. -/ -noncomputable abbrev rTensor (f : A →ₐ[S] C) : A ⊗[R] B →ₐ[S] C ⊗[R] B := map f (.id R B) +abbrev rTensor (f : A →ₐ[S] C) : A ⊗[R] B →ₐ[S] C ⊗[R] B := map f (.id R B) /-- Construct an isomorphism between tensor products of an S-algebra with an R-algebra from S- and R- isomorphisms between the tensor factors. From 1f12a578d8573f0cc67f167cac9f0a1c96bde283 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:37:59 +0000 Subject: [PATCH 0360/1300] chore: update Mathlib dependencies 2026-06-25 (#41044) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 5ebacc94fd75e7..1dfeee55bef0ed 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "7d1b02eb63b526dff04cb990cf05b06b38ccbd3f", + "rev": "09c267c2706119a09606e6cde3f6cef5bb2ab72a", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 7af6b0b0f3e733d1c5a71471dcfd91bb35b2f913 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Thu, 25 Jun 2026 18:31:41 +0000 Subject: [PATCH 0361/1300] feat: add prime_units_mul and variants (#40220) From flt-regular. --- Mathlib/Algebra/Prime/Lemmas.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/Algebra/Prime/Lemmas.lean b/Mathlib/Algebra/Prime/Lemmas.lean index 704735cad894a0..0095606c2e6a93 100644 --- a/Mathlib/Algebra/Prime/Lemmas.lean +++ b/Mathlib/Algebra/Prime/Lemmas.lean @@ -62,6 +62,21 @@ theorem MulEquiv.prime_iff {E : Type*} [EquivLike E M N] [MulEquivClass E M N] ( end Map +variable {x y : M} + +theorem prime_units_mul (u : Mˣ) : Prime (↑u * y) ↔ Prime y := by simp [Prime] + +theorem prime_isUnit_mul (h : IsUnit x) : Prime (x * y) ↔ Prime y := + let ⟨u, hu⟩ := h + hu ▸ prime_units_mul u + +theorem prime_mul_units (u : Mˣ) : Prime (y * ↑u) ↔ Prime y := by + rw [mul_comm, prime_units_mul] + +theorem prime_mul_isUnit (h : IsUnit x) : Prime (y * x) ↔ Prime y := + let ⟨u, hu⟩ := h + hu ▸ prime_mul_units u + end Prime section IsCancelMulZero From 12e0e35303caf39265f1afeed6f1d655aeefaef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 25 Jun 2026 18:31:44 +0000 Subject: [PATCH 0362/1300] feat(Algebra/Homology): applying an additive functor to the homotopy (co)fiber (#40924) --- Mathlib/Algebra/Homology/HomotopyCofiber.lean | 206 +++++++++++++++++- Mathlib/Algebra/Homology/HomotopyFiber.lean | 42 ++++ 2 files changed, 246 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCofiber.lean b/Mathlib/Algebra/Homology/HomotopyCofiber.lean index aceb7b4f4d7f86..96920cb78c75bc 100644 --- a/Mathlib/Algebra/Homology/HomotopyCofiber.lean +++ b/Mathlib/Algebra/Homology/HomotopyCofiber.lean @@ -145,6 +145,33 @@ lemma inrX_fstX (i j : ι) (hij : c.Rel i j) : obtain rfl := c.next_eq' hij simp [inrX, fstX, dif_pos hij] +@[reassoc (attr := simp)] +lemma inlX_XIsoBiprod_hom (i j : ι) (hij : c.Rel j i) : + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + inlX φ i j hij ≫ (XIsoBiprod φ j i hij).hom = biprod.inl := by + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + simp [inlX] + +@[reassoc (attr := simp)] +lemma inl_XIsoBiprod_inv (i j : ι) (hij : c.Rel j i) : + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + biprod.inl ≫ (XIsoBiprod φ j i hij).inv = inlX φ i j hij := by + simp [inlX] + +@[reassoc (attr := simp)] +lemma inrX_XIsoBiprod_hom (i j : ι) (hij : c.Rel j i) : + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + inrX φ j ≫ (XIsoBiprod φ j i hij).hom = biprod.inr := by + obtain rfl := c.next_eq' hij + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + simp [inrX, XIsoBiprod, dif_pos hij] + +@[reassoc (attr := simp)] +lemma inr_XIsoBiprod_inv (i j : ι) (hij : c.Rel j i) : + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + biprod.inr ≫ (XIsoBiprod φ j i hij).inv = inrX φ j := by + rw [← inrX_XIsoBiprod_hom φ i j hij, Category.assoc, Iso.hom_inv_id, Category.comp_id] + /-- The `d` field of the homological complex `homotopyCofiber φ`. -/ noncomputable def d (i j : ι) : X φ i ⟶ X φ j := if hij : c.Rel i j @@ -175,9 +202,9 @@ lemma ext_from_X (i j : ι) (hij : c.Rel j i) {A : C} {f g : X φ j ⟶ A} haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij rw [← cancel_epi (XIsoBiprod φ j i hij).inv] apply biprod.hom_ext' - · simpa [inlX] using h₁ + · simpa · obtain rfl := c.next_eq' hij - simpa [inrX, dif_pos hij] using h₂ + simpa [-inr_XIsoBiprod_inv, -inr_XIsoBiprod_inv_assoc, inrX, dif_pos hij] using h₂ lemma ext_from_X' (i : ι) (hi : ¬ c.Rel i (c.next i)) {A : C} {f g : X φ i ⟶ A} (h : inrX φ i ≫ f = inrX φ i ≫ g) : f = g := by @@ -384,6 +411,131 @@ noncomputable def descEquiv (K : HomologicalComplex C c) (hc : ∀ j, ∃ i, c.R rw [descSigma_ext_iff] cat_disch +section + +variable {F' F'' G' G'' : HomologicalComplex C c} (φ' : F' ⟶ G') (φ'' : F'' ⟶ G'') + [HasHomotopyCofiber φ'] [HasHomotopyCofiber φ''] + (H : ∀ (j : ι), ∃ i, c.Rel i j) + +set_option backward.defeqAttrib.useBackward true in +/-- The morphism between homotopy cofibers that is induced by a +morphism of arrows. -/ +noncomputable def mapArrowHom (α : Arrow.mk φ ⟶ Arrow.mk φ') : + homotopyCofiber φ ⟶ homotopyCofiber φ' := + desc _ (α.right ≫ homotopyCofiber.inr φ') + ((Homotopy.ofEq (by + simp [reassoc_of% dsimp% α.w])).trans (((inrCompHomotopy φ' H).compLeft α.left).trans + (Homotopy.ofEq (by simp)))) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma mapArrowHom_id : mapArrowHom φ φ H (𝟙 _) = 𝟙 _ := by + ext i + dsimp + by_cases hi : c.Rel i (c.next i) + · refine ext_to_X _ _ _ hi ?_ ?_ + all_goals simp [mapArrowHom, desc_f _ _ _ _ _ hi, inrCompHomotopy_hom _ _ _ _ hi] + · exact ext_to_X' _ _ hi (by simp [mapArrowHom, desc_f' _ _ _ _ hi]) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +@[reassoc] +lemma mapArrowHom_comp + (α : Arrow.mk φ ⟶ Arrow.mk φ') (β : Arrow.mk φ' ⟶ Arrow.mk φ'') : + mapArrowHom φ φ'' H (α ≫ β) = mapArrowHom φ φ' H α ≫ mapArrowHom φ' φ'' H β := by + ext i + dsimp + by_cases hi : c.Rel i (c.next i) + · refine ext_to_X _ _ _ hi ?_ ?_ + all_goals simp [mapArrowHom, desc_f _ _ _ _ _ hi, inrCompHomotopy_hom _ _ _ _ hi] + · exact ext_to_X' _ _ hi (by simp [mapArrowHom, desc_f' _ _ _ _ hi]) + +/-- The isomorphism between homotopy cofibers that is induced by an +isomorphism of arrows. -/ +@[simps] +noncomputable def mapArrowIso (α : Arrow.mk φ ≅ Arrow.mk φ') : + homotopyCofiber φ ≅ homotopyCofiber φ' where + hom := mapArrowHom φ φ' H α.hom + inv := mapArrowHom φ' φ H α.inv + hom_inv_id := by rw [← mapArrowHom_comp, Iso.hom_inv_id, mapArrowHom_id] + inv_hom_id := by rw [← mapArrowHom_comp, Iso.inv_hom_id, mapArrowHom_id] + +end + +section + +variable {D : Type*} [Category* D] [Preadditive D] (H : C ⥤ D) [H.Additive] + [HasHomotopyCofiber ((H.mapHomologicalComplex c).map φ)] + +/-- Auxiliary definition for `mapHomologicalComplexObjIso`. -/ +noncomputable def mapHomologicalComplexObjXIso (i : ι) : + H.obj ((homotopyCofiber φ).X i) ≅ + (homotopyCofiber ((H.mapHomologicalComplex c).map φ)).X i := + if hi : c.Rel i (c.next i) + then by + haveI := preservesBinaryBiproducts_of_preservesBiproducts H + haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hi + haveI := HasHomotopyCofiber.hasBinaryBiproduct ((H.mapHomologicalComplex c).map φ) _ _ hi + exact H.mapIso (homotopyCofiber.XIsoBiprod φ _ _ hi) ≪≫ H.mapBiprod _ _ ≪≫ + (homotopyCofiber.XIsoBiprod ((H.mapHomologicalComplex c).map φ) _ _ hi).symm + else H.mapIso (homotopyCofiber.XIso φ i hi) ≪≫ + (homotopyCofiber.XIso ((H.mapHomologicalComplex c).map φ) i hi).symm + +set_option backward.isDefEq.respectTransparency false in +@[reassoc (attr := simp)] +lemma inlX_mapHomologicalComplexObjXIso_inv + (i j : ι) (hij : c.Rel j i) : + inlX ((H.mapHomologicalComplex c).map φ) i j hij ≫ + (mapHomologicalComplexObjXIso φ H j).inv = H.map (inlX φ i j hij) := by + obtain rfl := c.next_eq' hij + simp [mapHomologicalComplexObjXIso, dif_pos hij, ← Functor.map_comp] + +set_option backward.isDefEq.respectTransparency false in +@[reassoc (attr := simp)] +lemma inrX_mapHomologicalComplexObjXIso_inv (i : ι) : + inrX ((H.mapHomologicalComplex c).map φ) i ≫ + (mapHomologicalComplexObjXIso φ H i).inv = H.map (inrX φ i) := by + by_cases hi : c.Rel i (c.next i) + · simp [mapHomologicalComplexObjXIso, dif_pos hi, ← Functor.map_comp] + · dsimp [mapHomologicalComplexObjXIso, XIso, inrX] + simp [dif_neg hi] + +set_option backward.isDefEq.respectTransparency false in +@[reassoc (attr := simp)] +lemma map_inrX_mapHomologicalComplexObjXIso_hom (i : ι) : + H.map (inrX φ i) ≫ (mapHomologicalComplexObjXIso φ H i).hom = + inrX ((H.mapHomologicalComplex c).map φ) i := by + rw [← inrX_mapHomologicalComplexObjXIso_inv_assoc, Iso.inv_hom_id, comp_id] + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- The isomorphism expressing the commutation between taking +the homotopy cofiber of a morphism of homological complexes and +applying an additive functor. -/ +noncomputable def mapHomologicalComplexObjIso : + (H.mapHomologicalComplex c).obj (homotopyCofiber φ) ≅ + homotopyCofiber ((H.mapHomologicalComplex c).map φ) := + Iso.symm (HomologicalComplex.Hom.isoOfComponents + (fun i ↦ (mapHomologicalComplexObjXIso φ H i).symm) + (fun i j hij ↦ by + dsimp + apply ext_from_X _ _ _ hij + · by_cases hj : c.Rel j (c.next j) + · simp [← Functor.map_comp, inlX_d _ _ _ _ _ hj, inlX_d_assoc _ _ _ _ _ hj] + · simp [← Functor.map_comp, inlX_d' _ _ _ _ hj, inlX_d'_assoc _ _ _ _ hj] + · simp [← Functor.map_comp])) + +set_option backward.isDefEq.respectTransparency false in +@[reassoc (attr := simp)] +lemma inr_mapHomologicalComplexObjIso_hom : + (H.mapHomologicalComplex c).map (inr φ) ≫ + (mapHomologicalComplexObjIso φ H).hom = inr _ := by + ext + simp [mapHomologicalComplexObjIso] + +end + end homotopyCofiber section @@ -565,6 +717,56 @@ lemma map_ι₀_eq_map_ι₁ {D : Type*} [Category* D] (H : HomologicalComplex C end + +section + +variable (F) {D : Type*} [Category* D] [Preadditive D] (H : C ⥤ D) [H.Additive] + [∀ i, HasBinaryBiproduct (F.X i) (F.X i)] + [HasHomotopyCofiber (biprod.lift (𝟙 F) (-𝟙 F))] + [∀ i, HasBinaryBiproduct (((H.mapHomologicalComplex c).obj F).X i) + (((H.mapHomologicalComplex c).obj F).X i)] + [HasHomotopyCofiber (biprod.lift (𝟙 ((H.mapHomologicalComplex c).obj F)) + (-𝟙 ((H.mapHomologicalComplex c).obj F)))] + [HasHomotopyCofiber ((H.mapHomologicalComplex c).map (biprod.lift (𝟙 F) (-𝟙 F)))] + (hc : ∀ (j : ι), ∃ i, c.Rel i j) + +attribute [local instance] preservesBinaryBiproduct_of_preservesBiproduct + +set_option backward.defeqAttrib.useBackward true in +/-- The isomorphism expressing the commutation between taking +the cylinder of a homological complex and applying an additive functor. -/ +noncomputable def mapHomologicalComplexObjIso : + (H.mapHomologicalComplex c).obj (cylinder F) ≅ + cylinder ((H.mapHomologicalComplex c).obj F) := + homotopyCofiber.mapHomologicalComplexObjIso _ H ≪≫ + homotopyCofiber.mapArrowIso _ _ hc + (Arrow.isoMk (Iso.refl _) ((H.mapHomologicalComplex c).mapBiprod F F) (by + apply biprod.hom_ext <;> simp [← Functor.map_comp])) + +set_option backward.defeqAttrib.useBackward true in +@[reassoc (attr := simp)] +lemma map_ι₀_mapHomologicalComplexObjIso_hom : + (H.mapHomologicalComplex c).map (cylinder.ι₀ F) ≫ (mapHomologicalComplexObjIso F H hc).hom = + cylinder.ι₀ _ := by + dsimp [mapHomologicalComplexObjIso, ι₀, homotopyCofiber.mapArrowHom] + rw [Functor.map_comp, assoc, homotopyCofiber.inr_mapHomologicalComplexObjIso_hom_assoc, + homotopyCofiber.inr_desc, ← Category.assoc] + congr 1 + apply biprod.hom_ext <;> simp [← Functor.map_comp] + +set_option backward.defeqAttrib.useBackward true in +@[reassoc (attr := simp)] +lemma map_ι₁_mapHomologicalComplexObjIso_hom : + (H.mapHomologicalComplex c).map (cylinder.ι₁ F) ≫ (mapHomologicalComplexObjIso F H hc).hom = + cylinder.ι₁ _ := by + dsimp [mapHomologicalComplexObjIso, ι₁, homotopyCofiber.mapArrowHom] + rw [Functor.map_comp, assoc, homotopyCofiber.inr_mapHomologicalComplexObjIso_hom_assoc, + homotopyCofiber.inr_desc, ← Category.assoc] + congr 1 + apply biprod.hom_ext <;> simp [← Functor.map_comp] + +end + end cylinder omit [DecidableRel c.Rel] in diff --git a/Mathlib/Algebra/Homology/HomotopyFiber.lean b/Mathlib/Algebra/Homology/HomotopyFiber.lean index 1705df5e21c76b..24d5c09a3cec5c 100644 --- a/Mathlib/Algebra/Homology/HomotopyFiber.lean +++ b/Mathlib/Algebra/Homology/HomotopyFiber.lean @@ -161,6 +161,48 @@ lemma lift_π₁ : lift φ₀ φ₁ h ≫ π₁ K = φ₁ := end +section + +variable (F) {D : Type*} [Category* D] [Preadditive D] (H : C ⥤ D) [H.Additive] + [∀ (i : α), HasBinaryBiproduct (((H.mapHomologicalComplex c).obj K).X i) + (((H.mapHomologicalComplex c).obj K).X i)] + [((H.mapHomologicalComplex c).obj K).HasPathObject] + +variable + [∀ (i : α), + HasBinaryBiproduct (((H.op.mapHomologicalComplex c.symm).obj K.op).X i) + (((H.op.mapHomologicalComplex c.symm).obj K.op).X i)] + [HasHomotopyCofiber (biprod.lift (𝟙 ((H.op.mapHomologicalComplex c.symm).obj K.op)) + (-𝟙 ((H.op.mapHomologicalComplex c.symm).obj K.op)))] + [HasHomotopyCofiber ((H.op.mapHomologicalComplex c.symm).map (biprod.lift (𝟙 K.op) (-𝟙 K.op)))] + [∀ (i : α), HasBinaryBiproduct (K.op.X i) (K.op.X i)] + +variable (hc : ∀ (i : α), ∃ j, c.Rel i j) + +/-- The isomorphism expressing the commutation between taking +the path object of a homological complex and applying an additive functor. -/ +@[no_expose] +noncomputable def mapHomologicalComplexObjIso : + (H.mapHomologicalComplex c).obj (K.pathObject) ≅ + pathObject ((H.mapHomologicalComplex c).obj K) := + (unopFunctor _ _).mapIso (cylinder.mapHomologicalComplexObjIso K.op H.op hc).op.symm + +@[reassoc (attr := simp)] +lemma mapHomologicalComplexObjIso_inv_map_π₀ : + (mapHomologicalComplexObjIso K H hc).inv ≫ (H.mapHomologicalComplex c).map (π₀ K) = + π₀ _ := + Quiver.Hom.op_inj ((opFunctor _ _).map_injective + (cylinder.map_ι₀_mapHomologicalComplexObjIso_hom K.op H.op hc)) + +@[reassoc (attr := simp)] +lemma mapHomologicalComplexObjIso_inv_map_π₁ : + (mapHomologicalComplexObjIso K H hc).inv ≫ (H.mapHomologicalComplex c).map (π₁ K) = + π₁ _ := + Quiver.Hom.op_inj ((opFunctor _ _).map_injective + (cylinder.map_ι₁_mapHomologicalComplexObjIso_hom K.op H.op hc)) + +end + end pathObject end HomologicalComplex From ac06f381f4f7d5f7aa4617251e1c9f346dbad20a Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:06:36 +0000 Subject: [PATCH 0363/1300] feat: add a `LawfulXor` typeclass (#37712) I've put this in mathlib since it can use `Function.Involutive`; it can of course be upstreamed at a later date. Having this generalization encourages downstream code in cslib to be expressed in terms of involutive functions, rather than just `^^^` on bitvectors. --- Mathlib.lean | 1 + Mathlib/Data/LawfulXor.lean | 129 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 Mathlib/Data/LawfulXor.lean diff --git a/Mathlib.lean b/Mathlib.lean index 66d8dccb727666..f892e89c8d8f8e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4035,6 +4035,7 @@ public import Mathlib.Data.Int.Sqrt public import Mathlib.Data.Int.Star public import Mathlib.Data.Int.SuccPred public import Mathlib.Data.Int.WithZero +public import Mathlib.Data.LawfulXor public import Mathlib.Data.List.AList public import Mathlib.Data.List.Basic public import Mathlib.Data.List.Chain diff --git a/Mathlib/Data/LawfulXor.lean b/Mathlib/Data/LawfulXor.lean new file mode 100644 index 00000000000000..bb486390d9a029 --- /dev/null +++ b/Mathlib/Data/LawfulXor.lean @@ -0,0 +1,129 @@ +/- +Copyright (c) 2026 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ + +module +public import Mathlib.Logic.Function.Basic + +/-! +# The `LawfulXor` typeclass + +This file generalizes basic lemmas about the `^^^` operator across numeric types. +-/ + +@[expose] public section + +/-- A typeclass indicating that the xor operation, `^^^`, is lawful. -/ +class LawfulXor (α : Type*) [XorOp α] [Zero α] where + xor_assoc (a b c : α) : (a ^^^ b) ^^^ c = a ^^^ (b ^^^ c) + xor_self (a : α) : a ^^^ a = 0 + xor_zero (a : α) : a ^^^ 0 = a + xor_comm (a b : α) : a ^^^ b = b ^^^ a + +export LawfulXor (xor_assoc xor_self xor_zero xor_comm) + +variable {α : Type*} [XorOp α] [Zero α] [LawfulXor α] + +attribute [simp] xor_zero LawfulXor.xor_self + +@[simp] +theorem zero_xor (a : α) : 0 ^^^ a = a := by rw [LawfulXor.xor_comm, xor_zero] + +instance : Std.Commutative (α := α) XorOp.xor where comm := xor_comm +instance : Std.Associative (α := α) XorOp.xor where assoc := xor_assoc + +instance : Std.LawfulCommIdentity (α := α) XorOp.xor 0 where + left_id := zero_xor + right_id := xor_zero + +@[simp] +theorem xor_cancel_right (a b : α) : (a ^^^ b) ^^^ b = a := by + rw [xor_assoc, LawfulXor.xor_self, xor_zero] + +@[simp] +theorem xor_cancel_left (a b : α) : a ^^^ (a ^^^ b) = b := by + rw [← xor_assoc, LawfulXor.xor_self, zero_xor] + +instance : LawfulXor Nat where + xor_assoc := Nat.xor_assoc + xor_comm := Nat.xor_comm + xor_self := Nat.xor_self + xor_zero := Nat.xor_zero + +instance {w : Nat} : LawfulXor (BitVec w) where + xor_assoc := BitVec.xor_assoc + xor_comm := BitVec.xor_comm + xor_self _ := BitVec.xor_self + xor_zero _ := BitVec.xor_zero + +instance : LawfulXor UInt8 where + xor_assoc := UInt8.xor_assoc + xor_comm := UInt8.xor_comm + xor_self _ := UInt8.xor_self + xor_zero _ := UInt8.xor_zero + +instance : LawfulXor UInt16 where + xor_assoc := UInt16.xor_assoc + xor_comm := UInt16.xor_comm + xor_self _ := UInt16.xor_self + xor_zero _ := UInt16.xor_zero + +instance : LawfulXor UInt32 where + xor_assoc := UInt32.xor_assoc + xor_comm := UInt32.xor_comm + xor_self _ := UInt32.xor_self + xor_zero _ := UInt32.xor_zero + +instance : LawfulXor UInt64 where + xor_assoc := UInt64.xor_assoc + xor_comm := UInt64.xor_comm + xor_self _ := UInt64.xor_self + xor_zero _ := UInt64.xor_zero + +instance : LawfulXor USize where + xor_assoc := USize.xor_assoc + xor_comm := USize.xor_comm + xor_self _ := USize.xor_self + xor_zero _ := USize.xor_zero + +instance : LawfulXor Int8 where + xor_assoc := Int8.xor_assoc + xor_comm := Int8.xor_comm + xor_self _ := Int8.xor_self + xor_zero _ := Int8.xor_zero + +instance : LawfulXor Int16 where + xor_assoc := Int16.xor_assoc + xor_comm := Int16.xor_comm + xor_self _ := Int16.xor_self + xor_zero _ := Int16.xor_zero + +instance : LawfulXor Int32 where + xor_assoc := Int32.xor_assoc + xor_comm := Int32.xor_comm + xor_self _ := Int32.xor_self + xor_zero _ := Int32.xor_zero + +instance : LawfulXor Int64 where + xor_assoc := Int64.xor_assoc + xor_comm := Int64.xor_comm + xor_self _ := Int64.xor_self + xor_zero _ := Int64.xor_zero + +instance : LawfulXor ISize where + xor_assoc := ISize.xor_assoc + xor_comm := ISize.xor_comm + xor_self _ := ISize.xor_self + xor_zero _ := ISize.xor_zero + +lemma xor_right_involutive (a : α) : Function.Involutive (a ^^^ ·) := xor_cancel_left a + +lemma xor_left_involutive (a : α) : Function.Involutive (· ^^^ a) := (xor_cancel_right · a) + +lemma xor_eq_iff_left_eq (a b c : α) : + a ^^^ b = c ↔ a = c ^^^ b := xor_left_involutive _ |>.eq_iff + +lemma xor_eq_iff_right_eq (a b c : α) : + a ^^^ b = c ↔ b = a ^^^ c := xor_right_involutive _ |>.eq_iff From 68b30e537da83f057bd4f15dae11632af0a198eb Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:06:39 +0000 Subject: [PATCH 0364/1300] feat: `NSMul`/`NPow` type class (#38036) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR is adds `NSMul`, `NPow`, `ZSMul` and `ZPow` classes for the `nsmul`, `npow`, `zsmul`, `zpow` data fields. This has a few advantages: - If you first declare a `SMul` instance, then you don't need to manually write `nsmul := (· • ·)` and `zsmul := (· • ·)` . For `Pow`, the extra benefit is that inferring the instance is preferred over the default field `npowRecAuto`. So this helps avoid accidental diamonds. - If you first declare a `SMul` instance on a type synonym, then `inferInstanceAs` will infer the `nsmul` field from the `SMul` instance. This makes it easier to avoid diamonds on type synonyms like `Matrix` and `MonoidAlgebra`. - The not-yet-merged instance diamond linter will be able to detect cases where the `NSMul` and `SMul` classes do not agree. In the process of making this PR, I have identified two existing `NPow` diamonds: - In `Mathlib.Algebra.Order.Positive.Field`, there were two conflicting `NPow` instances. - For `Fin`, there are two conflicting `NPow` instances. I have overwritten the one in core lean with the one from mathlib that is more computationally efficient. TODO: the same for `QSMul` and `NNQSMul`. --- Mathlib/Algebra/Colimit/DirectLimit.lean | 22 ++- Mathlib/Algebra/FreeAlgebra.lean | 4 +- Mathlib/Algebra/Group/Action/Opposite.lean | 2 +- Mathlib/Algebra/Group/Defs.lean | 94 +++++++----- Mathlib/Algebra/Group/Ext.lean | 4 +- Mathlib/Algebra/Group/Int/Defs.lean | 4 +- Mathlib/Algebra/Group/Opposite.lean | 1 + Mathlib/Algebra/Group/Prod.lean | 4 +- .../Algebra/Group/Submonoid/Membership.lean | 9 +- Mathlib/Algebra/Group/TypeTags/Basic.lean | 46 +++--- Mathlib/Algebra/Group/Units/Defs.lean | 10 +- .../GroupWithZero/Action/Opposite.lean | 2 +- Mathlib/Algebra/Module/NatInt.lean | 23 +-- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 13 +- .../Order/Monoid/Unbundled/WithTop.lean | 6 +- Mathlib/Algebra/Order/Positive/Field.lean | 8 +- Mathlib/Algebra/Order/Ring/Archimedean.lean | 2 - Mathlib/Algebra/Order/Ring/WithTop.lean | 4 +- Mathlib/Algebra/Ring/MinimalAxioms.lean | 3 +- Mathlib/Algebra/RingQuot.lean | 1 - Mathlib/CategoryTheory/Preadditive/Comma.lean | 12 +- .../CategoryTheory/Triangulated/Basic.lean | 2 - Mathlib/Data/BitVec.lean | 3 +- Mathlib/Data/Complex/Basic.lean | 2 - Mathlib/Data/Rat/Defs.lean | 6 +- Mathlib/Data/ZMod/Defs.lean | 47 +++--- Mathlib/Data/ZMod/IntUnitsPower.lean | 4 +- Mathlib/FieldTheory/RatFunc/Basic.lean | 2 - Mathlib/GroupTheory/GroupAction/Hom.lean | 2 - Mathlib/LinearAlgebra/Matrix/Defs.lean | 16 +- Mathlib/LinearAlgebra/Matrix/ZPow.lean | 3 +- .../LinearAlgebra/TensorProduct/Basic.lean | 1 - Mathlib/LinearAlgebra/TensorProduct/Defs.lean | 6 +- .../NumberTheory/ArithmeticFunction/Defs.lean | 1 - Mathlib/RingTheory/PolynomialLaw/Basic.lean | 18 ++- .../Valuation/ValuativeRel/Basic.lean | 4 +- Mathlib/SetTheory/Cardinal/Order.lean | 2 +- Mathlib/Tactic/Abel.lean | 8 +- Mathlib/Tactic/Translate/ToAdditive.lean | 4 +- Mathlib/Topology/Algebra/GroupCompletion.lean | 144 ++++++++---------- .../Module/ContinuousLinearMap/Basic.lean | 2 - MathlibTest/InstanceDiamonds.lean | 10 +- 42 files changed, 283 insertions(+), 278 deletions(-) diff --git a/Mathlib/Algebra/Colimit/DirectLimit.lean b/Mathlib/Algebra/Colimit/DirectLimit.lean index 7898ffcdedf41e..3a000c17f440e7 100644 --- a/Mathlib/Algebra/Colimit/DirectLimit.lean +++ b/Mathlib/Algebra/Colimit/DirectLimit.lean @@ -220,8 +220,12 @@ variable [∀ i j h, MonoidHomClass (T h) (G i) (G j)] [∀ i, MonoidHomClass (H one_mul := one_mul mul_one := mul_one npow n := map _ _ (fun _ ↦ (· ^ n)) fun _ _ _ x ↦ map_pow _ x n - npow_zero := DirectLimit.induction _ fun i _ ↦ by simp_rw [map_def, pow_zero, one_def i] - npow_succ n := DirectLimit.induction _ fun i _ ↦ by simp_rw [map_def, pow_succ, mul_def] + npow_zero := DirectLimit.induction _ fun i _ ↦ by + simp_rw [HPow.hPow, Pow.pow] + simp_rw [map_def, pow_zero, one_def i] + npow_succ n := DirectLimit.induction _ fun i _ ↦ by + simp_rw [HPow.hPow, Pow.pow] + simp_rw [map_def, pow_succ, mul_def] @[to_additive] theorem npow_def (i x) (n : ℕ) : ⟦⟨i, x⟩⟧ ^ n = (⟦⟨i, x ^ n⟩⟧ : DirectLimit G f) := rfl @@ -256,11 +260,12 @@ variable [∀ i j h, MonoidHomClass (T h) (G i) (G j)] [∀ i, MonoidHomClass (H zpow n := map _ _ (fun _ ↦ (· ^ n)) fun _ _ _ x ↦ map_zpow _ x n div_eq_mul_inv := DirectLimit.induction₂ _ fun i _ _ ↦ show map₂ .. = _ * map .. by simp_rw [map₂_def, map_def, div_eq_mul_inv, mul_def] - zpow_zero' := DirectLimit.induction _ fun i _ ↦ by simp_rw [map_def, zpow_zero, one_def i] + zpow_zero' := DirectLimit.induction _ fun i _ ↦ by + simp_rw [HPow.hPow, Pow.pow, map_def, zpow_zero, one_def i] zpow_succ' n := DirectLimit.induction _ fun i x ↦ by - simp_rw [map_def, mul_def]; congr; apply DivInvMonoid.zpow_succ' + simp_rw [HPow.hPow, Pow.pow, map_def, mul_def]; congr; apply DivInvMonoid.zpow_succ' zpow_neg' n := DirectLimit.induction _ fun i x ↦ by - simp_rw +instances [map_def]; congr; apply DivInvMonoid.zpow_neg' + simp_rw [HPow.hPow, Pow.pow, map_def]; congr; apply DivInvMonoid.zpow_neg' inv_mul_cancel := DirectLimit.induction _ fun i _ ↦ by simp_rw [map_def, mul_def, inv_mul_cancel, one_def i] @@ -341,11 +346,12 @@ instance : GroupWithZero (DirectLimit G f) where zpow n := map _ _ (fun _ ↦ (· ^ n)) fun _ _ _ x ↦ map_zpow₀ _ x n div_eq_mul_inv := DirectLimit.induction₂ _ fun i _ _ ↦ show map₂ .. = _ * map .. by simp_rw [map₂_def, map_def, div_eq_mul_inv, mul_def] - zpow_zero' := DirectLimit.induction _ fun i _ ↦ by simp_rw [map_def, zpow_zero, one_def i] + zpow_zero' := DirectLimit.induction _ fun i _ ↦ by + simp_rw [HPow.hPow, Pow.pow, map_def, zpow_zero, one_def i] zpow_succ' n := DirectLimit.induction _ fun i x ↦ by - simp_rw [map_def, mul_def]; congr; apply DivInvMonoid.zpow_succ' + simp_rw [HPow.hPow, Pow.pow, map_def, mul_def]; congr; apply DivInvMonoid.zpow_succ' zpow_neg' n := DirectLimit.induction _ fun i x ↦ by - simp_rw [map_def]; congr; apply DivInvMonoid.zpow_neg' + simp_rw [HPow.hPow, Pow.pow, map_def]; congr; apply DivInvMonoid.zpow_neg' inv_zero := show ⟦_⟧ = ⟦_⟧ by simp_rw [inv_zero] mul_inv_cancel := DirectLimit.induction _ fun i x ne ↦ by have : x ≠ 0 := by rintro rfl; exact ne (zero_def i).symm diff --git a/Mathlib/Algebra/FreeAlgebra.lean b/Mathlib/Algebra/FreeAlgebra.lean index a3df9a637be7b2..2db44e9cca6e07 100644 --- a/Mathlib/Algebra/FreeAlgebra.lean +++ b/Mathlib/Algebra/FreeAlgebra.lean @@ -201,7 +201,6 @@ instance instMonoidWithZero : MonoidWithZero (FreeAlgebra R X) where mul_assoc := by rintro ⟨⟩ ⟨⟩ ⟨⟩ exact Quot.sound Rel.mul_assoc - one := Quot.mk _ 1 one_mul := by rintro ⟨⟩ exact Quot.sound Rel.one_mul @@ -237,7 +236,6 @@ instance instAddCommMonoid : AddCommMonoid (FreeAlgebra R X) where add_comm := by rintro ⟨⟩ ⟨⟩ exact Quot.sound Rel.add_comm - nsmul := (· • ·) nsmul_zero := by rintro ⟨⟩ change Quot.mk _ (_ * _) = _ @@ -245,7 +243,7 @@ instance instAddCommMonoid : AddCommMonoid (FreeAlgebra R X) where exact Quot.sound Rel.zero_mul nsmul_succ n := by rintro ⟨a⟩ - dsimp +instances only [HSMul.hSMul, instSMul, Quot.map] + dsimp only [HSMul.hSMul, SMul.smul, NSMul.nsmul, Quot.map] rw [map_add, map_one, mk_mul, mk_mul, ← add_one_mul (_ : FreeAlgebra R X)] congr 1 exact Quot.sound Rel.add_scalar diff --git a/Mathlib/Algebra/Group/Action/Opposite.lean b/Mathlib/Algebra/Group/Action/Opposite.lean index ac0b3d9268b373..0725bd5184a37f 100644 --- a/Mathlib/Algebra/Group/Action/Opposite.lean +++ b/Mathlib/Algebra/Group/Action/Opposite.lean @@ -15,7 +15,7 @@ This file defines the actions on the opposite type `SMul R Mᵐᵒᵖ`, and acti type, `SMul Rᵐᵒᵖ M`. Note that `MulOpposite.smul` is provided in an earlier file as it is needed to -provide the `AddMonoid.nsmul` and `AddCommGroup.zsmul` fields. +provide the `NSMul.nsmul` and `ZSMul.zsmul` fields. ## Notation diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 8da0e62370f626..fce530fbd241ac 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -637,38 +637,51 @@ theorem npowRec_eq_npowBinRec : @npowRecAuto = @npowBinRecAuto := by iterate 2 rw [← npowBinRecAuto, ← npowRec_eq_npowBinRec] rfl -/-- An `AddMonoid` is an `AddSemigroup` with an element `0` such that `0 + a = a + 0 = a`. -/ -class AddMonoid (M : Type u) extends AddSemigroup M, AddZeroClass M where +/-- `NSMul` is an implementation detail of `AddMonoid`. It is needed because it is +impossible to extend `SMUl ℕ M` and `SMul ℤ M` at the same time. -/ +class NSMul (M : Type u) where /-- Multiplication by a natural number. Set this to `nsmulRec` unless `Module` diamonds are possible. -/ protected nsmul : ℕ → M → M + +/-- `NPow` is an implementation detail of `Monoid`. It is needed because it is +impossible to extend `Pow M ℕ` and `Pow M ℤ` at the same time. -/ +@[to_additive] +class NPow (M : Type u) where + /-- Raising to the power of a natural number. -/ + protected npow : ℕ → M → M + +@[default_instance high, to_additive toSMul] +instance NPow.toPow {M : Type*} [NPow M] : Pow M ℕ := + ⟨fun x n ↦ NPow.npow n x⟩ + +@[to_additive ofSMul] +instance NPow.ofPow {M : Type*} [Pow M ℕ] : NPow M := ⟨fun n x ↦ Pow.pow x n⟩ + +/-- An `AddMonoid` is an `AddSemigroup` with an element `0` such that `0 + a = a + 0 = a`. -/ +class AddMonoid (M : Type u) extends AddSemigroup M, AddZeroClass M, NSMul M where /-- Multiplication by `(0 : ℕ)` gives `0`. -/ - protected nsmul_zero : ∀ x, nsmul 0 x = 0 := by intros; rfl + protected nsmul_zero (x : M) : 0 • x = 0 := by intros; rfl /-- Multiplication by `(n + 1 : ℕ)` behaves as expected. -/ - protected nsmul_succ : ∀ (n : ℕ) (x), nsmul (n + 1) x = nsmul n x + x := by intros; rfl + protected nsmul_succ (n : ℕ) (x : M) : (n + 1) • x = n • x + x := by intros; rfl attribute [instance 150] AddSemigroup.toAdd attribute [instance 50] AddZero.toAdd /-- A `Monoid` is a `Semigroup` with an element `1` such that `1 * a = a * 1 = a`. -/ @[to_additive] -class Monoid (M : Type u) extends Semigroup M, MulOneClass M where - /-- Raising to the power of a natural number. -/ - protected npow : ℕ → M → M := npowRecAuto +class Monoid (M : Type u) extends Semigroup M, MulOneClass M, NPow M where + npow := npowRecAuto /-- Raising to the power `(0 : ℕ)` gives `1`. -/ - protected npow_zero : ∀ x, npow 0 x = 1 := by intros; rfl + protected npow_zero (x : M) : x ^ 0 = 1 := by intros; rfl /-- Raising to the power `(n + 1 : ℕ)` behaves as expected. -/ - protected npow_succ : ∀ (n : ℕ) (x), npow (n + 1) x = npow n x * x := by intros; rfl - -@[default_instance high, to_additive] -instance Monoid.toPow {M : Type*} [Monoid M] : Pow M ℕ := - ⟨fun x n ↦ Monoid.npow n x⟩ + protected npow_succ (n : ℕ) (x : M) : x ^ (n + 1) = x ^ n * x := by intros; rfl section Monoid variable {M : Type*} [Monoid M] {a b c : M} @[to_additive (attr := simp) nsmul_eq_smul] -theorem npow_eq_pow (n : ℕ) (x : M) : Monoid.npow n x = x ^ n := +theorem npow_eq_pow (n : ℕ) (x : M) : NPow.npow n x = x ^ n := rfl @[to_additive] lemma left_inv_eq_right_inv (hba : b * a = 1) (hac : a * c = 1) : b = c := by @@ -941,6 +954,27 @@ field of individual `DivInvMonoid`s constructed using that default value will no `.instance` transparency. -/ def DivInvMonoid.div' {G : Type u} [Monoid G] [Inv G] (a b : G) : G := a * b⁻¹ +/-- `ZSMul` is an implementation detail of `SubNegMonoid`. It is needed because it is +impossible to extend `SMUl ℕ M` and `SMul ℤ M` at the same time. -/ +class ZSMul (G : Type u) where + /-- Multiplication by an integer. + Set this to `zsmulRec` unless `Module` diamonds are possible. -/ + protected zsmul : ℤ → G → G + +/-- `ZPow` is an implementation detail of `DivInvMonoid`. It is needed because it is +impossible to extend `Pow M ℕ` and `Pow M ℤ` at the same time. -/ +@[to_additive] +class ZPow (G : Type u) where + /-- The power operation: `a ^ n = a * ··· * a`; `a ^ (-n) = a⁻¹ * ··· a⁻¹` (`n` times) -/ + protected zpow : ℤ → G → G + +@[to_additive toSMul] +instance ZPow.toPow {M : Type*} [ZPow M] : Pow M ℤ := + ⟨fun x n ↦ ZPow.zpow n x⟩ + +@[to_additive ofSMul] +instance ZPow.ofPow {M : Type*} [Pow M ℤ] : ZPow M := ⟨fun n x ↦ Pow.pow x n⟩ + /-- A `DivInvMonoid` is a `Monoid` with operations `/` and `⁻¹` satisfying `div_eq_mul_inv : ∀ a b, a / b = a * b⁻¹`. @@ -959,19 +993,18 @@ In the same way, adding a `zpow` field makes it possible to avoid definitional f in diamonds. See the definition of `Monoid` and Note [forgetful inheritance] for more explanations on this. -/ -class DivInvMonoid (G : Type u) extends Monoid G, Inv G, Div G where +class DivInvMonoid (G : Type u) extends Monoid G, Inv G, Div G, ZPow G where protected div := DivInvMonoid.div' /-- `a / b := a * b⁻¹` -/ protected div_eq_mul_inv : ∀ a b : G, a / b = a * b⁻¹ := by intros; rfl - /-- The power operation: `a ^ n = a * ··· * a`; `a ^ (-n) = a⁻¹ * ··· a⁻¹` (`n` times) -/ - protected zpow : ℤ → G → G := zpowRec npowRec + zpow := zpowRec npowRec /-- `a ^ 0 = 1` -/ - protected zpow_zero' : ∀ a : G, zpow 0 a = 1 := by intros; rfl + protected zpow_zero' (a : G) : a ^ (0 : ℤ) = 1 := by intros; rfl /-- `a ^ (n + 1) = a ^ n * a` -/ - protected zpow_succ' (n : ℕ) (a : G) : zpow n.succ a = zpow n a * a := by + protected zpow_succ' (n : ℕ) (a : G) : a ^ (n.succ : ℤ) = a ^ (n : ℤ) * a := by intros; rfl /-- `a ^ -(n + 1) = (a ^ (n + 1))⁻¹` -/ - protected zpow_neg' (n : ℕ) (a : G) : zpow (Int.negSucc n) a = (zpow n.succ a)⁻¹ := by intros; rfl + protected zpow_neg' (n : ℕ) (a : G) : a ^ Int.negSucc n = (a ^ (n.succ : ℤ))⁻¹ := by intros; rfl /-- In a class equipped with instances of both `AddMonoid` and `Neg`, this definition records what the default definition for `Sub` would be: `a + -b`. This is later provided as the default value @@ -1001,29 +1034,18 @@ In the same way, adding a `zsmul` field makes it possible to avoid definitional in diamonds. See the definition of `AddMonoid` and Note [forgetful inheritance] for more explanations on this. -/ -class SubNegMonoid (G : Type u) extends AddMonoid G, Neg G, Sub G where +class SubNegMonoid (G : Type u) extends AddMonoid G, Neg G, Sub G, ZSMul G where protected sub := SubNegMonoid.sub' protected sub_eq_add_neg : ∀ a b : G, a - b = a + -b := by intros; rfl - /-- Multiplication by an integer. - Set this to `zsmulRec` unless `Module` diamonds are possible. -/ - protected zsmul : ℤ → G → G - protected zsmul_zero' : ∀ a : G, zsmul 0 a = 0 := by intros; rfl + protected zsmul_zero' (a : G) : (0 : ℤ) • a = 0 := by intros; rfl protected zsmul_succ' (n : ℕ) (a : G) : - zsmul n.succ a = zsmul n a + a := by + (n.succ : ℤ) • a = (n : ℤ) • a + a := by intros; rfl - protected zsmul_neg' (n : ℕ) (a : G) : zsmul (Int.negSucc n) a = -zsmul n.succ a := by + protected zsmul_neg' (n : ℕ) (a : G) : (Int.negSucc n) • a = -((n.succ : ℤ) • a) := by intros; rfl attribute [to_additive SubNegMonoid] DivInvMonoid -instance DivInvMonoid.toZPow {M} [DivInvMonoid M] : Pow M ℤ := - ⟨fun x n ↦ DivInvMonoid.zpow n x⟩ - -instance SubNegMonoid.toZSMul {M} [SubNegMonoid M] : SMul ℤ M := - ⟨SubNegMonoid.zsmul⟩ - -attribute [to_additive existing] DivInvMonoid.toZPow - /-- A group is called *cyclic* if it is generated by a single element. -/ class IsAddCyclic (G : Type u) [SMul ℤ G] : Prop where protected exists_zsmul_surjective : ∃ g : G, Function.Surjective (· • g : ℤ → G) @@ -1043,7 +1065,7 @@ section DivInvMonoid variable [DivInvMonoid G] @[to_additive (attr := simp) zsmul_eq_smul] theorem zpow_eq_pow (n : ℤ) (x : G) : - DivInvMonoid.zpow n x = x ^ n := + ZPow.zpow n x = x ^ n := rfl @[to_additive (attr := simp) zero_zsmul] theorem zpow_zero (a : G) : a ^ (0 : ℤ) = 1 := diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index 3874fa32780c75..279b4d658c69ac 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -47,7 +47,7 @@ theorem Monoid.ext {M : Type u} ⦃m₁ m₂ : Monoid M⦄ have : m₁.npow = m₂.npow := by ext n x exact @MonoidHom.map_pow M M m₁ m₂ f x n - rcases m₁ with @⟨@⟨⟨_⟩⟩, ⟨_⟩⟩ + rcases m₁ with @⟨@⟨⟨_⟩⟩, ⟨_⟩, _, _, ⟨_⟩⟩ congr @[to_additive] @@ -134,7 +134,7 @@ theorem DivInvMonoid.ext {M : Type*} ⦃m₁ m₂ : DivInvMonoid M⦄ exact (@div_eq_mul_inv _ m₁ a b).trans (((congr_fun (congr_fun h_mul a) _).trans (congr_arg _ (congr_fun h_inv b))).trans (@div_eq_mul_inv _ m₂ a b).symm) - rcases m₁ with @⟨_, ⟨_⟩, ⟨_⟩⟩ + rcases m₁ with @⟨_, ⟨_⟩, ⟨_⟩, ⟨_⟩⟩ congr @[to_additive] diff --git a/Mathlib/Algebra/Group/Int/Defs.lean b/Mathlib/Algebra/Group/Int/Defs.lean index 09c73fe1a74bd5..9e06bbccfe336d 100644 --- a/Mathlib/Algebra/Group/Int/Defs.lean +++ b/Mathlib/Algebra/Group/Int/Defs.lean @@ -47,8 +47,8 @@ instance instAddCommGroup : AddCommGroup ℤ where zsmul := (· * ·) zsmul_zero' := Int.zero_mul zsmul_succ' m n := by - simp only [natCast_succ, Int.add_mul, Int.add_comm, Int.one_mul] - zsmul_neg' m n := by simp only [negSucc_eq, natCast_succ, Int.neg_mul] + simp only [HSMul.hSMul, SMul.smul, natCast_succ, Int.add_mul, Int.add_comm, Int.one_mul] + zsmul_neg' m n := by simp only [HSMul.hSMul, SMul.smul, negSucc_eq, natCast_succ, Int.neg_mul] sub_eq_add_neg _ _ := Int.sub_eq_add_neg -- This instance can also be found from the `LinearOrderedCommMonoidWithZero ℤ` instance by diff --git a/Mathlib/Algebra/Group/Opposite.lean b/Mathlib/Algebra/Group/Opposite.lean index 68a9347be830d8..5668d2f7882e82 100644 --- a/Mathlib/Algebra/Group/Opposite.lean +++ b/Mathlib/Algebra/Group/Opposite.lean @@ -142,6 +142,7 @@ instance instDivInvMonoid [DivInvMonoid α] : DivInvMonoid αᵐᵒᵖ where zpow n a := op <| a.unop ^ n zpow_zero' _ := unop_injective <| zpow_zero _ zpow_succ' _ _ := unop_injective <| by + simp_rw [HPow.hPow, Pow.pow] rw [unop_op, zpow_natCast, pow_succ', unop_mul, unop_op, zpow_natCast] zpow_neg' _ _ := unop_injective <| DivInvMonoid.zpow_neg' _ _ diff --git a/Mathlib/Algebra/Group/Prod.lean b/Mathlib/Algebra/Group/Prod.lean index 7c8bf82d187fa0..12b8deaed8d2d4 100644 --- a/Mathlib/Algebra/Group/Prod.lean +++ b/Mathlib/Algebra/Group/Prod.lean @@ -87,7 +87,7 @@ instance instMulOneClass [MulOneClass M] [MulOneClass N] : MulOneClass (M × N) @[to_additive] instance instMonoid [Monoid M] [Monoid N] : Monoid (M × N) := - { npow := fun z a => ⟨Monoid.npow z a.1, Monoid.npow z a.2⟩, + { npow := fun z a => ⟨NPow.npow z a.1, NPow.npow z a.2⟩, npow_zero := fun _ => Prod.ext (Monoid.npow_zero _) (Monoid.npow_zero _), npow_succ := fun _ _ => Prod.ext (Monoid.npow_succ _ _) (Monoid.npow_succ _ _), one_mul := by simp, @@ -102,7 +102,7 @@ instance instIsMulTorsionFree [Monoid M] [Monoid N] [IsMulTorsionFree M] [IsMulT @[to_additive Prod.subNegMonoid] instance [DivInvMonoid G] [DivInvMonoid H] : DivInvMonoid (G × H) where div_eq_mul_inv _ _ := by ext <;> exact div_eq_mul_inv .. - zpow z a := ⟨DivInvMonoid.zpow z a.1, DivInvMonoid.zpow z a.2⟩ + zpow z a := ⟨ZPow.zpow z a.1, ZPow.zpow z a.2⟩ zpow_zero' _ := by ext <;> exact DivInvMonoid.zpow_zero' _ zpow_succ' _ _ := by ext <;> exact DivInvMonoid.zpow_succ' .. zpow_neg' _ _ := by ext <;> exact DivInvMonoid.zpow_neg' .. diff --git a/Mathlib/Algebra/Group/Submonoid/Membership.lean b/Mathlib/Algebra/Group/Submonoid/Membership.lean index 9c81e885c1eef0..0e5c544e78d9ea 100644 --- a/Mathlib/Algebra/Group/Submonoid/Membership.lean +++ b/Mathlib/Algebra/Group/Submonoid/Membership.lean @@ -361,8 +361,12 @@ abbrev groupPowers {x : M} {n : ℕ} (hpos : 0 < n) (hx : x ^ n = 1) : Group (po simp only [coe_one, coe_mul, SubmonoidClass.coe_pow] rw [← pow_succ, Nat.sub_add_cancel hpos, ← pow_mul, mul_comm, pow_mul, hx, one_pow] zpow z x := x ^ z.natMod n - zpow_zero' z := by simp only [Int.natMod, Int.zero_emod, Int.toNat_zero, pow_zero] - zpow_neg' m x := Subtype.ext <| by + zpow_zero' z := by + simp_rw [HPow.hPow, Pow.pow] + simp only [Int.natMod, Int.zero_emod, Int.toNat_zero, pow_zero] + zpow_neg' m x := by + change x ^ (Int.natMod _ n) = (x ^ (Int.natMod _ n)) ^ (n - 1) + ext obtain ⟨_, k, rfl⟩ := x simp only [← pow_mul, Int.natMod, SubmonoidClass.coe_pow] rw [Int.negSucc_eq, ← Int.natCast_succ, ← Int.add_mul_emod_self_right (b := (m + 1 : ℕ))] @@ -372,6 +376,7 @@ abbrev groupPowers {x : M} {n : ℕ} (hpos : 0 < n) (hx : x ^ n = 1) : Group (po rw [mul_comm, pow_mul, ← pow_eq_pow_mod _ hx, mul_comm k, mul_assoc, pow_mul _ (_ % _), ← pow_eq_pow_mod _ hx, pow_mul, pow_mul] zpow_succ' m x := Subtype.ext <| by + simp_rw [HPow.hPow, Pow.pow] obtain ⟨_, k, rfl⟩ := x simp only [← pow_mul, Int.natMod, SubmonoidClass.coe_pow, coe_mul] norm_cast diff --git a/Mathlib/Algebra/Group/TypeTags/Basic.lean b/Mathlib/Algebra/Group/TypeTags/Basic.lean index 07c87018aaf344..a07b3ee9363195 100644 --- a/Mathlib/Algebra/Group/TypeTags/Basic.lean +++ b/Mathlib/Algebra/Group/TypeTags/Basic.lean @@ -261,17 +261,15 @@ instance Multiplicative.mulOneClass [AddZeroClass α] : MulOneClass (Multiplicat one_mul := @zero_add α _ mul_one := @add_zero α _ -instance Additive.addMonoid [h : Monoid α] : AddMonoid (Additive α) := - { Additive.addZeroClass, Additive.addSemigroup with - nsmul := @Monoid.npow α h - nsmul_zero := @Monoid.npow_zero α h - nsmul_succ := @Monoid.npow_succ α h } +instance Additive.addMonoid [h : Monoid α] : AddMonoid (Additive α) where + nsmul := h.npow + nsmul_zero := h.npow_zero + nsmul_succ := h.npow_succ -instance Multiplicative.monoid [h : AddMonoid α] : Monoid (Multiplicative α) := - { Multiplicative.mulOneClass, Multiplicative.semigroup with - npow := @AddMonoid.nsmul α h - npow_zero := @AddMonoid.nsmul_zero α h - npow_succ := @AddMonoid.nsmul_succ α h } +instance Multiplicative.monoid [h : AddMonoid α] : Monoid (Multiplicative α) where + npow := h.nsmul + npow_zero := h.nsmul_zero + npow_succ := h.nsmul_succ @[simp] theorem ofMul_pow [Monoid α] (n : ℕ) (a : α) : ofMul (a ^ n) = n • ofMul a := @@ -415,21 +413,19 @@ instance Additive.involutiveNeg [InvolutiveInv α] : InvolutiveNeg (Additive α) instance Multiplicative.involutiveInv [InvolutiveNeg α] : InvolutiveInv (Multiplicative α) := { Multiplicative.inv with inv_inv := @neg_neg α _ } -instance Additive.subNegMonoid [DivInvMonoid α] : SubNegMonoid (Additive α) := - { Additive.neg, Additive.sub, Additive.addMonoid with - sub_eq_add_neg := @div_eq_mul_inv α _ - zsmul := @DivInvMonoid.zpow α _ - zsmul_zero' := @DivInvMonoid.zpow_zero' α _ - zsmul_succ' := @DivInvMonoid.zpow_succ' α _ - zsmul_neg' := @DivInvMonoid.zpow_neg' α _ } - -instance Multiplicative.divInvMonoid [SubNegMonoid α] : DivInvMonoid (Multiplicative α) := - { Multiplicative.inv, Multiplicative.div, Multiplicative.monoid with - div_eq_mul_inv := @sub_eq_add_neg α _ - zpow := @SubNegMonoid.zsmul α _ - zpow_zero' := @SubNegMonoid.zsmul_zero' α _ - zpow_succ' := @SubNegMonoid.zsmul_succ' α _ - zpow_neg' := @SubNegMonoid.zsmul_neg' α _ } +instance Additive.subNegMonoid [h : DivInvMonoid α] : SubNegMonoid (Additive α) where + sub_eq_add_neg := h.div_eq_mul_inv + zsmul := h.zpow + zsmul_zero' := h.zpow_zero' + zsmul_succ' := h.zpow_succ' + zsmul_neg' := h.zpow_neg' + +instance Multiplicative.divInvMonoid [h : SubNegMonoid α] : DivInvMonoid (Multiplicative α) where + div_eq_mul_inv := h.sub_eq_add_neg + zpow := h.zsmul + zpow_zero' := h.zsmul_zero' + zpow_succ' := h.zsmul_succ' + zpow_neg' := h.zsmul_neg' @[simp] theorem ofMul_zpow [DivInvMonoid α] (z : ℤ) (a : α) : ofMul (a ^ z) = z • ofMul a := diff --git a/Mathlib/Algebra/Group/Units/Defs.lean b/Mathlib/Algebra/Group/Units/Defs.lean index 96dd3018a9281f..3a7b7dd89014d1 100644 --- a/Mathlib/Algebra/Group/Units/Defs.lean +++ b/Mathlib/Algebra/Group/Units/Defs.lean @@ -233,8 +233,8 @@ instance instMonoid : Monoid αˣ := inv := a⁻¹ ^ n val_inv := by rw [← a.commute_coe_inv.mul_pow]; simp inv_val := by rw [← a.commute_inv_coe.mul_pow]; simp } - npow_zero := fun a ↦ by ext; simp - npow_succ := fun n a ↦ by ext; simp [pow_succ] } + npow_zero := fun a ↦ by simp only [HPow.hPow, Pow.pow]; ext; simp + npow_succ := fun n a ↦ by simp only [HPow.hPow, Pow.pow]; ext; simp [pow_succ] } /-- Units of a monoid have division -/ @[to_additive /-- Additive units of an additive monoid have subtraction. -/] @@ -251,9 +251,9 @@ instance instDivInvMonoid : DivInvMonoid αˣ where zpow := fun n a ↦ match n, a with | Int.ofNat n, a => a ^ n | Int.negSucc n, a => (a ^ n.succ)⁻¹ - zpow_zero' := fun a ↦ by simp - zpow_succ' := fun n a ↦ by simp [pow_succ] - zpow_neg' := fun n a ↦ by simp + zpow_zero' := fun a ↦ by simp only [HPow.hPow, Pow.pow]; simp + zpow_succ' := fun n a ↦ by simp only [HPow.hPow, Pow.pow]; simp [pow_succ] + zpow_neg' := fun n a ↦ rfl /-- Units of a monoid form a group. -/ @[to_additive /-- Additive units of an additive monoid form an additive group. -/] diff --git a/Mathlib/Algebra/GroupWithZero/Action/Opposite.lean b/Mathlib/Algebra/GroupWithZero/Action/Opposite.lean index 3bf4735533a0d3..90c30e1bd6160f 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Opposite.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Opposite.lean @@ -17,7 +17,7 @@ This file defines the actions on the opposite type `SMul R Mᵐᵒᵖ`, and acti type, `SMul Rᵐᵒᵖ M`. Note that `MulOpposite.smul` is provided in an earlier file as it is needed to -provide the `AddMonoid.nsmul` and `AddCommGroup.zsmul` fields. +provide the `NSMul.nsmul` and `ZSMul.zsmul` fields. ## Notation diff --git a/Mathlib/Algebra/Module/NatInt.lean b/Mathlib/Algebra/Module/NatInt.lean index 9daa84aa1c71eb..80968cbeb8c4a2 100644 --- a/Mathlib/Algebra/Module/NatInt.lean +++ b/Mathlib/Algebra/Module/NatInt.lean @@ -90,17 +90,18 @@ variable (R) in structure. See note [reducible non-instances]. -/ abbrev Module.addCommMonoidToAddCommGroup - [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M := - { (inferInstance : AddCommMonoid M) with - neg := fun a => (-1 : R) • a - neg_add_cancel := fun a => - show (-1 : R) • a + a = 0 by - nth_rw 2 [← one_smul R a] - rw [← add_smul, neg_add_cancel, zero_smul] - zsmul := fun z a => (z : R) • a - zsmul_zero' := fun a => by simpa only [Int.cast_zero] using zero_smul R a - zsmul_succ' := fun z a => by simp [add_comm, add_smul] - zsmul_neg' := fun z a => by simp [← smul_assoc] } + [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M where + neg := fun a => (-1 : R) • a + neg_add_cancel := fun a => + show (-1 : R) • a + a = 0 by + nth_rw 2 [← one_smul R a] + rw [← add_smul, neg_add_cancel, zero_smul] + zsmul z a := (z : R) • a + zsmul_zero' a := by simp_rw [HSMul.hSMul, SMul.smul, Int.cast_zero]; exact zero_smul R a + zsmul_succ' z a := by simp_rw [HSMul.hSMul, SMul.smul]; simp [add_comm, add_smul] + zsmul_neg' z a := by + change (Int.negSucc z : R) • a = -1 • ((z.succ : ℤ) : R) • a + simp [← smul_assoc] section AddCommMonoid diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index f88a130a9fc3c9..8dbf75acb2780e 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -156,9 +156,12 @@ lemma ofCoeff_inj {x y : M →₀ R} : ofCoeff x = ofCoeff y ↔ x = y := ofCoef inferInstanceAs <| DecidableEq <| M →₀ R -- TODO: this instance abuses definitional equality with `Finsupp.mapRange` +@[to_additive (dont_translate := A)] +instance {A : Type*} [SMulZeroClass A R] : SMul A R[M] where + smul a x := x.mapRange (a • ·) (smul_zero _) + @[to_additive] instance addCommMonoid : AddCommMonoid R[M] := - fast_instance% { (inferInstance : AddCommMonoid <| M →₀ R) with - nsmul n x := x.mapRange (n • ·) (smul_zero _) } + inferInstanceAs <| AddCommMonoid <| M →₀ R @[to_additive] instance instIsCancelAdd [IsCancelAdd R] : IsCancelAdd R[M] := inferInstanceAs <| IsCancelAdd <| M →₀ R @@ -260,15 +263,13 @@ Further results on scalar multiplication can be found in variable {A : Type*} [SMulZeroClass A R] --- TODO: this instance abuses definitional equality with `Finsupp.mapRange` @[to_additive (dont_translate := A) smulZeroClass] instance smulZeroClass : SMulZeroClass A R[M] := - fast_instance% { (inferInstance : SMulZeroClass A (M →₀ R)) with - smul a x := x.mapRange (a • ·) (smul_zero _) } + inferInstanceAs <| SMulZeroClass A (M →₀ R) section -- Ensure that the different smul instances do not create a diamond. -example : (smulZeroClass (A := ℕ) (R := R) (M := M)).toSMul = addCommMonoid.toNSMul := by +example : (smulZeroClass (A := ℕ) (R := R) (M := M)).smul = addCommMonoid.nsmul := by with_reducible_and_instances rfl -- Ensure that smul has good defeq properties diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean index b2576064241f69..54a80da3c58f50 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean @@ -264,8 +264,10 @@ instance addMonoid : AddMonoid (WithTop α) where | (a : α), n => ↑(n • a) | ⊤, 0 => 0 | ⊤, _n + 1 => ⊤ - nsmul_zero a := by cases a <;> simp [zero_nsmul] - nsmul_succ n a := by cases a <;> cases n <;> simp [succ_nsmul, coe_add] + nsmul_zero a := by simp_rw [HSMul.hSMul, SMul.smul]; cases a <;> simp [zero_nsmul] + nsmul_succ n a := by + simp_rw [HSMul.hSMul, SMul.smul] + cases a <;> cases n <;> simp [succ_nsmul, coe_add] @[simp, norm_cast] lemma coe_nsmul (a : α) (n : ℕ) : ↑(n • a) = n • (a : WithTop α) := rfl diff --git a/Mathlib/Algebra/Order/Positive/Field.lean b/Mathlib/Algebra/Order/Positive/Field.lean index 2c32175910675c..d2eda796258759 100644 --- a/Mathlib/Algebra/Order/Positive/Field.lean +++ b/Mathlib/Algebra/Order/Positive/Field.lean @@ -35,8 +35,10 @@ instance : Pow { x : K // 0 < x } ℤ := theorem coe_zpow (x : { x : K // 0 < x }) (n : ℤ) : ↑(x ^ n) = (x : K) ^ n := rfl -instance : CommGroup { x : K // 0 < x } := - { Positive.commMonoid with - inv_mul_cancel := fun a => Subtype.ext <| inv_mul_cancel₀ a.2.ne' } +instance : CommGroup { x : K // 0 < x } where + inv_mul_cancel a := Subtype.ext <| inv_mul_cancel₀ a.2.ne' + zpow_zero' x := Subtype.ext <| zpow_zero _ + zpow_succ' n x := Subtype.ext <| DivInvMonoid.zpow_succ' _ _ + zpow_neg' n x := Subtype.ext <| DivInvMonoid.zpow_neg' _ _ end Positive diff --git a/Mathlib/Algebra/Order/Ring/Archimedean.lean b/Mathlib/Algebra/Order/Ring/Archimedean.lean index ad71ce19de201b..333b72c4ef4ae7 100644 --- a/Mathlib/Algebra/Order/Ring/Archimedean.lean +++ b/Mathlib/Algebra/Order/Ring/Archimedean.lean @@ -101,7 +101,6 @@ instance : AddCommMonoid (ArchimedeanClass R) where add_assoc := private add_assoc' zero_add := private zero_add' add_zero x := private add_comm x _ ▸ zero_add' x - nsmul n x := n • x nsmul_zero x := by induction x with | mk x => rw [← mk_pow, pow_zero, mk_one] nsmul_succ n x := by induction x with | mk x => rw [← mk_pow, pow_succ, mk_mul, mk_pow] @@ -308,7 +307,6 @@ noncomputable instance : LinearOrderedAddCommGroupWithTop (ArchimedeanClass R) w add_neg_cancel_of_ne_top x h := by induction x with | mk x simp [← mk_inv, ← mk_mul, mul_inv_cancel₀ (mk_eq_top_iff.not.1 h)] - zsmul n x := n • x zsmul_zero' x := by induction x with | mk x => rw [← mk_zpow, zpow_zero, mk_one] zsmul_succ' := by exact zsmul_succ' zsmul_neg' n x := by diff --git a/Mathlib/Algebra/Order/Ring/WithTop.lean b/Mathlib/Algebra/Order/Ring/WithTop.lean index 0ca11df2f6c5c6..a7a8bc4d82a7bd 100644 --- a/Mathlib/Algebra/Order/Ring/WithTop.lean +++ b/Mathlib/Algebra/Order/Ring/WithTop.lean @@ -173,8 +173,8 @@ instance instMonoidWithZero : MonoidWithZero (WithTop α) where | (a : α), n => ↑(a ^ n) | ⊤, 0 => 1 | ⊤, _n + 1 => ⊤ - npow_zero a := by cases a <;> simp - npow_succ n a := by cases n <;> cases a <;> simp [pow_succ] + npow_zero a := by simp_rw [HPow.hPow, Pow.pow]; cases a <;> simp + npow_succ n a := by simp_rw [HPow.hPow, Pow.pow]; cases n <;> cases a <;> simp [pow_succ] @[simp, norm_cast] lemma coe_pow (a : α) (n : ℕ) : (↑(a ^ n) : WithTop α) = a ^ n := rfl diff --git a/Mathlib/Algebra/Ring/MinimalAxioms.lean b/Mathlib/Algebra/Ring/MinimalAxioms.lean index 77dcc4cb9c8d32..984584c77b6929 100644 --- a/Mathlib/Algebra/Ring/MinimalAxioms.lean +++ b/Mathlib/Algebra/Ring/MinimalAxioms.lean @@ -69,8 +69,7 @@ abbrev Ring.ofMinimalAxioms {R : Type u} mul_assoc := mul_assoc one_mul := one_mul mul_one := mul_one - neg_add_cancel := neg_add_cancel - zsmul := (· • ·) } + neg_add_cancel := neg_add_cancel } /-- Define a `CommRing` structure on a Type by proving a minimized set of axioms. Note that this uses the default definitions for `npow`, `nsmul`, `zsmul` and `sub` diff --git a/Mathlib/Algebra/RingQuot.lean b/Mathlib/Algebra/RingQuot.lean index b5a17e7e40604c..86352ce1c777b7 100644 --- a/Mathlib/Algebra/RingQuot.lean +++ b/Mathlib/Algebra/RingQuot.lean @@ -278,7 +278,6 @@ instance instRing {R : Type uR} [Ring R] (r : R → R → Prop) : Ring (RingQuot sub_eq_add_neg := by rintro ⟨⟨⟩⟩ ⟨⟨⟩⟩ simp [neg_quot, sub_quot, add_quot, sub_eq_add_neg] - zsmul := (· • ·) zsmul_zero' := by rintro ⟨⟨⟩⟩ simp [smul_quot, ← zero_quot] diff --git a/Mathlib/CategoryTheory/Preadditive/Comma.lean b/Mathlib/CategoryTheory/Preadditive/Comma.lean index 0037e50fefdb7a..0b7ab15aba7870 100644 --- a/Mathlib/CategoryTheory/Preadditive/Comma.lean +++ b/Mathlib/CategoryTheory/Preadditive/Comma.lean @@ -68,11 +68,13 @@ instance : AddCommGroup (u ⟶ v) where (by simp [Functor.map_nsmul, Preadditive.comp_nsmul, Preadditive.nsmul_comp]) zsmul n α := CommaMorphism.mk (n • α.left) (n • α.right) (by simp [Functor.map_zsmul, Preadditive.comp_zsmul, Preadditive.zsmul_comp]) - nsmul_zero := by cat_disch - nsmul_succ _ _ := by ext <;> dsimp <;> simp [add_nsmul] - zsmul_zero' := by cat_disch - zsmul_succ' _ _ := by ext <;> dsimp <;> simp [add_zsmul] - zsmul_neg' _ _ := by ext <;> dsimp <;> simp [add_nsmul, add_zsmul] + nsmul_zero := by simp_rw [HSMul.hSMul, SMul.smul]; cat_disch + nsmul_succ _ _ := by simp_rw [HSMul.hSMul, SMul.smul]; ext <;> dsimp <;> simp [add_nsmul] + zsmul_zero' := by simp_rw [HSMul.hSMul, SMul.smul]; cat_disch + zsmul_succ' _ _ := by simp_rw [HSMul.hSMul, SMul.smul]; ext <;> dsimp <;> simp [add_zsmul] + zsmul_neg' _ _ := by + simp_rw [HSMul.hSMul, SMul.smul] + ext <;> dsimp <;> simp [add_nsmul, add_zsmul] /-- If we have additive functors `L : A ⥤ T` and `R : B ⥤ T` between preadditive categories, then the category `Comma L R` is preadditive. diff --git a/Mathlib/CategoryTheory/Triangulated/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Basic.lean index 59f0b77bf32158..f19199686ad02f 100644 --- a/Mathlib/CategoryTheory/Triangulated/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Basic.lean @@ -289,10 +289,8 @@ instance : AddCommGroup (T₁ ⟶ T₂) where add_comm f g := by ext <;> apply add_comm neg_add_cancel f := by ext <;> apply neg_add_cancel sub_eq_add_neg f g := by ext <;> apply sub_eq_add_neg - nsmul n f := n • f nsmul_zero f := by cat_disch nsmul_succ n f := by ext <;> apply AddMonoid.nsmul_succ - zsmul n f := n • f zsmul_zero' := by cat_disch zsmul_succ' n f := by ext <;> apply SubNegMonoid.zsmul_succ' zsmul_neg' n f := by ext <;> apply SubNegMonoid.zsmul_neg' diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index c76df5a6a66593..7e2da761f6c3bf 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -71,6 +71,7 @@ lemma toFin_zsmul (z : ℤ) (x : BitVec w) : toFin (z • x) = z • x.toFin := open scoped Fin.CommRing in simp only [zsmul_eq_mul, toFin_intCast] +set_option backward.isDefEq.respectTransparency false in lemma toFin_pow (x : BitVec w) (n : ℕ) : toFin (x ^ n) = x.toFin ^ n := by induction n with | zero => simp @@ -81,7 +82,7 @@ lemma toFin_pow (x : BitVec w) (n : ℕ) : toFin (x ^ n) = x.toFin ^ n := by -/ -- Verify that the `HPow` instance from Lean agrees definitionally with the instance via `Monoid`. -example : @instHPow (Fin (2 ^ w)) ℕ Monoid.toPow = Lean.Grind.Fin.instHPowFinNatOfNeZero := rfl +example : @instHPow (Fin (2 ^ w)) ℕ NPow.toPow = Lean.Grind.Fin.instHPowFinNatOfNeZero := rfl instance : CommSemiring (BitVec w) := open Fin.CommRing in diff --git a/Mathlib/Data/Complex/Basic.lean b/Mathlib/Data/Complex/Basic.lean index feb4b396fd8848..12f58340718e32 100644 --- a/Mathlib/Data/Complex/Basic.lean +++ b/Mathlib/Data/Complex/Basic.lean @@ -323,8 +323,6 @@ theorem real_smul {x : ℝ} {z : ℂ} : x • z = x * z := end SMul instance addCommGroup : AddCommGroup ℂ where - nsmul := (· • ·) - zsmul := (· • ·) zsmul_zero' := by intros; ext <;> simp [smul_re, smul_im] nsmul_zero := by intros; ext <;> simp [smul_re, smul_im] nsmul_succ := by intros; ext <;> simp [smul_re, smul_im] <;> ring diff --git a/Mathlib/Data/Rat/Defs.lean b/Mathlib/Data/Rat/Defs.lean index 1b3f964e3a1f79..c252257fc8dd95 100644 --- a/Mathlib/Data/Rat/Defs.lean +++ b/Mathlib/Data/Rat/Defs.lean @@ -160,8 +160,10 @@ instance addCommGroup : AddCommGroup ℚ where rw [Rat.intCast_add, Rat.add_mul, Rat.intCast_one, Rat.one_mul] rfl zsmul_zero' := Rat.zero_mul - zsmul_succ' _ _ := by simp [Rat.add_mul] - zsmul_neg' _ _ := by rw [Int.negSucc_eq, Rat.intCast_neg, Rat.neg_mul]; rfl + zsmul_succ' _ _ := by simp_rw [HSMul.hSMul, SMul.smul]; simp [Rat.add_mul] + zsmul_neg' _ _ := by + simp_rw [HSMul.hSMul, SMul.smul] + rw [Int.negSucc_eq, Rat.intCast_neg, Rat.neg_mul]; rfl instance addGroup : AddGroup ℚ := by infer_instance diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index e1b9832a88d149..e6b35cc6f970f0 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -65,17 +65,22 @@ open scoped Fin.IntCast Fin.NatCast lia /-- Multiplicative commutative semigroup structure on `Fin n`. -/ -instance instCommSemigroup (n : ℕ) : CommSemigroup (Fin n) := - { (inferInstance : Mul (Fin n)) with - mul_assoc := fun ⟨a, _⟩ ⟨b, _⟩ ⟨c, _⟩ => - Fin.eq_of_val_eq <| - calc - a * b % n * c ≡ a * b * c [MOD n] := (Nat.mod_modEq _ _).mul_right _ - _ ≡ a * (b * c) [MOD n] := by rw [mul_assoc] - _ ≡ a * (b * c % n) [MOD n] := (Nat.mod_modEq _ _).symm.mul_left _ - mul_comm := Fin.mul_comm } - -set_option backward.privateInPublic true in +instance instCommSemigroup (n : ℕ) : CommSemigroup (Fin n) where + mul_assoc := fun ⟨a, _⟩ ⟨b, _⟩ ⟨c, _⟩ => + Fin.eq_of_val_eq <| + calc + a * b % n * c ≡ a * b * c [MOD n] := (Nat.mod_modEq _ _).mul_right _ + _ ≡ a * (b * c) [MOD n] := by rw [mul_assoc] + _ ≡ a * (b * c % n) [MOD n] := (Nat.mod_modEq _ _).symm.mul_left _ + mul_comm := Fin.mul_comm + +-- Shortcut instances to replace the power operation on `Fin` with a more efficient one +instance (n : ℕ) [NeZero n] : HPow (Fin n) ℕ (Fin n) where + hPow a m := npowRecAuto m a + +instance (n : ℕ) [NeZero n] : Pow (Fin n) ℕ where + pow a m := npowRecAuto m a + private theorem left_distrib_aux (n : ℕ) : ∀ a b c : Fin n, a * (b + c) = a * b + a * c := fun ⟨a, _⟩ ⟨b, _⟩ ⟨c, _⟩ => Fin.eq_of_val_eq <| @@ -84,19 +89,13 @@ private theorem left_distrib_aux (n : ℕ) : ∀ a b c : Fin n, a * (b + c) = a _ ≡ a * b + a * c [MOD n] := by rw [mul_add] _ ≡ a * b % n + a * c % n [MOD n] := (Nat.mod_modEq _ _).symm.add (Nat.mod_modEq _ _).symm -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Distributive structure on `Fin n`. -/ -instance instDistrib (n : ℕ) : Distrib (Fin n) := - { Fin.addCommSemigroup n, Fin.instCommSemigroup n with - left_distrib := left_distrib_aux n - right_distrib := fun a b c => by - rw [mul_comm, left_distrib_aux, mul_comm _ b, mul_comm] } +instance instDistrib (n : ℕ) : Distrib (Fin n) where + left_distrib := private left_distrib_aux n + right_distrib := fun a b c => by + rw [mul_comm, left_distrib_aux, mul_comm _ b, mul_comm] instance instNonUnitalCommRing (n : ℕ) [NeZero n] : NonUnitalCommRing (Fin n) where - __ := Fin.addCommGroup n - __ := Fin.instCommSemigroup n - __ := Fin.instDistrib n zero_mul := Fin.zero_mul mul_zero := Fin.mul_zero @@ -106,7 +105,6 @@ instance instCommMonoid (n : ℕ) [NeZero n] : CommMonoid (Fin n) where /-- Note this is more general than `Fin.instCommRing` as it applies (vacuously) to `Fin 0` too. -/ instance instHasDistribNeg (n : ℕ) : HasDistribNeg (Fin n) where - toInvolutiveNeg := Fin.instInvolutiveNeg n mul_neg := Nat.casesOn n finZeroElim fun _i => mul_neg neg_mul := Nat.casesOn n finZeroElim fun _i => neg_mul @@ -126,11 +124,6 @@ silently introducing wraparound arithmetic. -/ @[instance_reducible] def instCommRing (n : ℕ) [NeZero n] : CommRing (Fin n) where - __ := Fin.instAddMonoidWithOne n - __ := Fin.addCommGroup n - __ := Fin.instCommSemigroup n - __ := Fin.instNonUnitalCommRing n - __ := Fin.instCommMonoid n intCast n := Fin.intCast n namespace CommRing diff --git a/Mathlib/Data/ZMod/IntUnitsPower.lean b/Mathlib/Data/ZMod/IntUnitsPower.lean index 687842a20a1f6a..e341f184756521 100644 --- a/Mathlib/Data/ZMod/IntUnitsPower.lean +++ b/Mathlib/Data/ZMod/IntUnitsPower.lean @@ -65,8 +65,8 @@ instance Int.instUnitsPow : Pow ℤˣ R where -- The above instances form no typeclass diamonds with the standard power operators -- but we will need `reducible_and_instances` which currently fails https://github.com/leanprover-community/mathlib4/issues/10906 -example : Int.instUnitsPow = Monoid.toPow := rfl -example : Int.instUnitsPow = DivInvMonoid.toZPow := rfl +example : Int.instUnitsPow = NPow.toPow := rfl +example : Int.instUnitsPow = ZPow.toPow := rfl @[simp] lemma ofMul_uzpow (u : ℤˣ) (r : R) : Additive.ofMul (u ^ r) = r • Additive.ofMul u := rfl diff --git a/Mathlib/FieldTheory/RatFunc/Basic.lean b/Mathlib/FieldTheory/RatFunc/Basic.lean index fb732adde49cc6..d99cb6ca38a10a 100644 --- a/Mathlib/FieldTheory/RatFunc/Basic.lean +++ b/Mathlib/FieldTheory/RatFunc/Basic.lean @@ -290,10 +290,8 @@ def instAddCommGroup : AddCommGroup K⟮X⟯ where add_zero := by frac_tac neg_add_cancel := by frac_tac sub_eq_add_neg := by frac_tac - nsmul := (· • ·) nsmul_zero := by smul_tac nsmul_succ _ := by smul_tac - zsmul := (· • ·) zsmul_zero' := by smul_tac zsmul_succ' _ := by smul_tac zsmul_neg' _ := by smul_tac diff --git a/Mathlib/GroupTheory/GroupAction/Hom.lean b/Mathlib/GroupTheory/GroupAction/Hom.lean index c1906b4166e9c1..4ba57e5936c038 100644 --- a/Mathlib/GroupTheory/GroupAction/Hom.lean +++ b/Mathlib/GroupTheory/GroupAction/Hom.lean @@ -448,7 +448,6 @@ lemma coe_add [SMul M X] [AddZeroClass Y] [DistribSMul N Y] (f g : X →ₑ[σ] instance [SMul M X] [AddMonoid Y] [DistribSMul N Y] : AddMonoid (X →ₑ[σ] Y) where add_assoc _ _ _ := ext fun _ ↦ add_assoc _ _ _ - nsmul n f := n • f nsmul_zero f := ext fun x ↦ AddMonoid.nsmul_zero (f x) nsmul_succ n f := ext fun x ↦ AddMonoid.nsmul_succ n (f x) @@ -484,7 +483,6 @@ instance [SMul M X] [AddGroup Y] [DistribSMul N Y] : AddGroup (X →ₑ[σ] Y) w neg f := ⟨-f, by simp⟩ neg_add_cancel f := ext fun _ ↦ neg_add_cancel _ sub_eq_add_neg _ _ := ext fun _ ↦ sub_eq_add_neg _ _ - zsmul z f := z • f zsmul_zero' f := ext fun x ↦ SubNegMonoid.zsmul_zero' _ zsmul_neg' _ _ := ext fun x ↦ SubNegMonoid.zsmul_neg' _ _ zsmul_succ' _ _ := ext fun x ↦ SubNegMonoid.zsmul_succ' _ _ diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index 73ad6a744b33d9..12896de854d302 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -153,6 +153,9 @@ instance inhabited [Inhabited α] : Inhabited (Matrix m n α) := instance add [Add α] : Add (Matrix m n α) := inferInstanceAs <| Add (m → n → α) +instance smul [SMul R α] : SMul R (Matrix m n α) where + smul a b := fun i ↦ a • b i + instance addSemigroup [AddSemigroup α] : AddSemigroup (Matrix m n α) := inferInstanceAs <| AddSemigroup (m → n → α) @@ -165,9 +168,8 @@ instance zero [Zero α] : Zero (Matrix m n α) := instance addZeroClass [AddZeroClass α] : AddZeroClass (Matrix m n α) := inferInstanceAs <| AddZeroClass (m → n → α) -instance addMonoid [AddMonoid α] : AddMonoid (Matrix m n α) where - __ : AddMonoid (Matrix m n α) := inferInstanceAs <| AddMonoid (m → n → α) - nsmul a b := fun i ↦ a • b i +instance addMonoid [AddMonoid α] : AddMonoid (Matrix m n α) := + inferInstanceAs <| AddMonoid (m → n → α) instance addCommMonoid [AddCommMonoid α] : AddCommMonoid (Matrix m n α) := inferInstanceAs <| AddCommMonoid (m → n → α) @@ -181,9 +183,8 @@ instance involutiveNeg [InvolutiveNeg α] : InvolutiveNeg (Matrix m n α) := instance sub [Sub α] : Sub (Matrix m n α) := inferInstanceAs <| Sub (m → n → α) -instance addGroup [AddGroup α] : AddGroup (Matrix m n α) where - __ : AddGroup (Matrix m n α) := inferInstanceAs <| AddGroup (m → n → α) - zsmul a b := fun i ↦ a • b i +instance addGroup [AddGroup α] : AddGroup (Matrix m n α) := + inferInstanceAs <| AddGroup (m → n → α) instance addCommGroup [AddCommGroup α] : AddCommGroup (Matrix m n α) := inferInstanceAs <| AddCommGroup (m → n → α) @@ -197,9 +198,6 @@ instance subsingleton [Subsingleton α] : Subsingleton (Matrix m n α) := instance nonempty [Nonempty m] [Nonempty n] [Nontrivial α] : Nontrivial (Matrix m n α) := Function.nontrivial -instance smul [SMul R α] : SMul R (Matrix m n α) where - smul a b := fun i ↦ a • b i - instance smulCommClass [SMul R α] [SMul S α] [SMulCommClass R S α] : SMulCommClass R S (Matrix m n α) := Pi.smulCommClass diff --git a/Mathlib/LinearAlgebra/Matrix/ZPow.lean b/Mathlib/LinearAlgebra/Matrix/ZPow.lean index b32635593790f5..0ba75ca5ab6ff3 100644 --- a/Mathlib/LinearAlgebra/Matrix/ZPow.lean +++ b/Mathlib/LinearAlgebra/Matrix/ZPow.lean @@ -97,8 +97,7 @@ theorem inv_zpow (A : M) : ∀ n : ℤ, A⁻¹ ^ n = (A ^ n)⁻¹ @[simp] theorem zpow_neg_one (A : M) : A ^ (-1 : ℤ) = A⁻¹ := by - convert! DivInvMonoid.zpow_neg' 0 A - simp only [zpow_one, Int.ofNat_zero, Int.natCast_succ, zpow_eq_pow, zero_add] + simpa using DivInvMonoid.zpow_neg' 0 A @[simp] theorem zpow_neg_natCast (A : M) (n : ℕ) : A ^ (-n : ℤ) = (A ^ n)⁻¹ := by diff --git a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean index e7526ce6d6d11e..4784cba63d32aa 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean @@ -393,7 +393,6 @@ protected theorem neg_add_cancel (x : M ⊗[R] N) : -x + x = 0 := instance addCommGroup : AddCommGroup (M ⊗[R] N) where neg_add_cancel := fun x => TensorProduct.neg_add_cancel x - zsmul := (· • ·) zsmul_zero' := by simp zsmul_succ' := by simp [add_comm, TensorProduct.add_smul] zsmul_neg' := fun n x => by diff --git a/Mathlib/LinearAlgebra/TensorProduct/Defs.lean b/Mathlib/LinearAlgebra/TensorProduct/Defs.lean index 528e297c60fed3..0a0180c5d21455 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Defs.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Defs.lean @@ -224,7 +224,7 @@ Note that in the special case that `R = R'`, since `R` is commutative, we just g action on a tensor product of two modules. This special case is important enough that, for performance reasons, we define it explicitly below. -/ instance leftHasSMul : SMul R' (M ⊗[R] N) := - ⟨fun r => + id ⟨fun r => (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <| AddCon.addConGen_le.2 fun x y hxy => match x, y, hxy with @@ -270,10 +270,8 @@ protected theorem add_smul (r s : R'') (x : M ⊗[R] N) : (r + s) • x = r • rw [ihx, ihy, add_add_add_comm] instance addMonoid : AddMonoid (M ⊗[R] N) where - nsmul := fun n v => n • v nsmul_zero := by simp [TensorProduct.zero_smul] - nsmul_succ := by simp only [TensorProduct.one_smul, TensorProduct.add_smul, add_comm, - forall_const] + nsmul_succ := by simp only [TensorProduct.one_smul, TensorProduct.add_smul, forall_const] instance addCommMonoid : AddCommMonoid (M ⊗[R] N) where diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean b/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean index 4c83802fcc713f..60325c75a83656 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean @@ -294,7 +294,6 @@ instance [CommSemiring R] : CommSemiring (ArithmeticFunction R) where instance [CommRing R] : CommRing (ArithmeticFunction R) where neg_add_cancel := neg_add_cancel mul_comm := mul_comm - zsmul n f := n • f instance {S : Type*} [Semiring R] [AddCommMonoid S] [Module R S] : Module R (ArithmeticFunction S) where diff --git a/Mathlib/RingTheory/PolynomialLaw/Basic.lean b/Mathlib/RingTheory/PolynomialLaw/Basic.lean index 586d31ab7c3f83..1a1843e362c313 100644 --- a/Mathlib/RingTheory/PolynomialLaw/Basic.lean +++ b/Mathlib/RingTheory/PolynomialLaw/Basic.lean @@ -165,8 +165,10 @@ instance : AddCommMonoid (M →ₚₗ[R] N) where zero_add f := by ext; simp only [add_def, zero_add, zero_def] add_zero f := by ext; simp only [add_def, add_zero, zero_def] nsmul n f := (n : R) • f - nsmul_zero f := by simp only [Nat.cast_zero, zero_smul f] - nsmul_succ n f := by simp only [Nat.cast_add, Nat.cast_one, add_smul, one_smul] + nsmul_zero f := by simp_rw [HSMul.hSMul, SMul.smul]; simp only [Nat.cast_zero, zero_smul f] + nsmul_succ n f := by + simp_rw [HSMul.hSMul, SMul.smul] + simp only [Nat.cast_add, Nat.cast_one, add_smul, one_smul] add_comm f g := by ext; simp only [add_def, add_comm] instance : Module R (M →ₚₗ[R] N) where @@ -195,15 +197,17 @@ theorem neg_def (S : Type u) [CommSemiring S] [Algebra R S] : instance : AddCommGroup (M →ₚₗ[R] N) where zsmul n f := (n : R) • f - zsmul_zero' f := by simp only [Int.cast_zero, zero_smul] - zsmul_succ' n f := by simp only [Nat.cast_succ, Int.cast_add, Int.cast_natCast, - Int.cast_one, add_smul, _root_.one_smul] + zsmul_zero' f := by simp_rw [HSMul.hSMul, SMul.smul]; simp only [Int.cast_zero, zero_smul] + zsmul_succ' n f := by + simp_rw [HSMul.hSMul, SMul.smul] + simp only [Nat.cast_succ, Int.cast_add, Int.cast_natCast, Int.cast_one, add_smul, one_smul] zsmul_neg' n f := by + simp_rw [HSMul.hSMul, SMul.smul] ext S _ _ m rw [neg_def] - simp only [Int.cast_negSucc, Nat.cast_add, Nat.cast_one, neg_add_rev, _root_.add_smul, + simp only [Int.cast_negSucc, Nat.cast_add, Nat.cast_one, neg_add_rev, add_smul, add_def_apply, smul_def_apply, Nat.succ_eq_add_one, Int.cast_add, Int.cast_natCast, - Int.cast_one, _root_.one_smul, add_def, smul_def, Pi.smul_apply, Pi.add_apply, smul_add, + Int.cast_one, one_smul, add_def, smul_def, Pi.smul_apply, Pi.add_apply, smul_add, smul_smul, neg_mul, one_mul] rw [add_comm] neg_add_cancel f := by diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 26f6b4663daee7..0cb1d9d4957031 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -568,8 +568,8 @@ instance : CommMonoidWithZero (ValueGroupWithZero R) where simp only [pow_succ, ← ValueGroupWithZero.mk_mul_mk, ih] apply congrArg (_ * ·) exact ValueGroupWithZero.sound h₁ h₂ - npow_zero := ValueGroupWithZero.ind (by simp) - npow_succ n := ValueGroupWithZero.ind (by simp [pow_succ]) + npow_zero := ValueGroupWithZero.ind (by simp_rw [HPow.hPow, Pow.pow]; simp) + npow_succ n := ValueGroupWithZero.ind (by simp_rw [HPow.hPow, Pow.pow]; simp [pow_succ]) instance : LE (ValueGroupWithZero R) where le := ValueGroupWithZero.lift₂ (fun a s b t => a * t ≤ᵥ b * s) <| by diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index eabd0ad6e5b4c1..600df08519e708 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -231,7 +231,7 @@ instance commSemiring : CommSemiring Cardinal.{u} where nsmul := nsmulRec npow n c := c ^ (n : Cardinal) npow_zero := power_zero - npow_succ n c := by rw [cast_succ, power_add, power_one] + npow_succ n c := by simp_rw [HPow.hPow, Pow.pow]; rw [cast_succ, power_add, power_one] natCast n := lift #(Fin n) natCast_zero := rfl natCast_succ n := cast_succ n diff --git a/Mathlib/Tactic/Abel.lean b/Mathlib/Tactic/Abel.lean index 757090587b50a7..32543310433274 100644 --- a/Mathlib/Tactic/Abel.lean +++ b/Mathlib/Tactic/Abel.lean @@ -377,11 +377,11 @@ partial def eval (e : Expr) : M (NormalExpr × Expr) := do let (e₁, p₁) ← eval e let (e₂, p₂) ← evalNeg e₁ return (e₂, ← iapp `Mathlib.Tactic.Abel.subst_into_neg #[e, e₁, e₂, p₁, p₂]) - | (``AddMonoid.nsmul, #[_, _, e₁, e₂]) => do + | (``NSMul.nsmul, #[_, _, e₁, e₂]) => do let n ← if (← read).isGroup then mkAppM ``Int.ofNat #[e₁] else pure e₁ let (e', p) ← eval <| ← iapp ``smul #[n, e₂] return (e', ← iapp ``unfold_smul #[e₁, e₂, e', p]) - | (``SubNegMonoid.zsmul, #[_, _, e₁, e₂]) => do + | (``ZSMul.zsmul, #[_, _, e₁, e₂]) => do if ¬ (← read).isGroup then failure let (e', p) ← eval <| ← iapp ``smul #[e₁, e₂] return (e', (← read).app ``unfold_zsmul (← read).inst #[e₁, e₂, e', p]) @@ -411,8 +411,8 @@ def isAtom (e : Expr) : Bool := | (``HAdd.hAdd, #[_, _, _, _, _, _]) | (``HSub.hSub, #[_, _, _, _, _, _]) | (``Neg.neg, #[_, _, _]) - | (``AddMonoid.nsmul, #[_, _, _, _]) - | (``SubNegMonoid.zsmul, #[_, _, _, _]) + | (``NSMul.nsmul, #[_, _, _, _]) + | (``ZSMul.zsmul, #[_, _, _, _]) | (``SMul.smul, #[.const ``Int _, _, _, _, _]) | (``SMul.smul, #[.const ``Nat _, _, _, _, _]) | (``HSMul.hSMul, #[.const ``Int _, _, _, _, _, _]) diff --git a/Mathlib/Tactic/Translate/ToAdditive.lean b/Mathlib/Tactic/Translate/ToAdditive.lean index 0ce40eceb1fac7..bb007e638676af 100644 --- a/Mathlib/Tactic/Translate/ToAdditive.lean +++ b/Mathlib/Tactic/Translate/ToAdditive.lean @@ -190,8 +190,8 @@ mismatch error. This likely only happens when the multiplicative declaration involves `pow`/`^`. Solutions: * Ensure that the order of arguments of all relevant declarations are the same for the multiplicative and additive version. This might mean that arguments have an "unnatural" order - (e.g. `Monoid.npow n x` corresponds to `x ^ n`, but it is convenient that `Monoid.npow` has this - argument order, since it matches `AddMonoid.nsmul n x`. + (e.g. `NPow.npow n x` corresponds to `x ^ n`, but it is convenient that `NPow.npow` has this + argument order, since it matches `NSMul.nsmul n x`. * If this is not possible, add `(reorder := ...)` argument to `to_additive`. If neither of these solutions work, and `to_additive` is unable to automatically generate the diff --git a/Mathlib/Topology/Algebra/GroupCompletion.lean b/Mathlib/Topology/Algebra/GroupCompletion.lean index 9c96a32278eae8..82cc3cda791079 100644 --- a/Mathlib/Topology/Algebra/GroupCompletion.lean +++ b/Mathlib/Topology/Algebra/GroupCompletion.lean @@ -70,12 +70,11 @@ open UniformSpace section Zero instance [UniformSpace α] [MonoidWithZero M] [Zero α] [MulActionWithZero M α] - [UniformContinuousConstSMul M α] : MulActionWithZero M (Completion α) := - { (inferInstance : MulAction M <| Completion α) with - smul_zero := fun r ↦ by rw [← coe_zero, ← coe_smul, MulActionWithZero.smul_zero r] - zero_smul := - ext' (continuous_const_smul _) continuous_const fun a ↦ by - rw [← coe_smul, zero_smul, coe_zero] } + [UniformContinuousConstSMul M α] : MulActionWithZero M (Completion α) where + smul_zero := fun r ↦ by rw [← coe_zero, ← coe_smul, MulActionWithZero.smul_zero r] + zero_smul := + ext' (continuous_const_smul _) continuous_const fun a ↦ by + rw [← coe_smul, zero_smul, coe_zero] end Zero @@ -95,82 +94,73 @@ theorem coe_sub (a b : α) : ((a - b : α) : Completion α) = a - b := theorem coe_add (a b : α) : ((a + b : α) : Completion α) = a + b := (map₂_coe_coe a b (· + ·) uniformContinuous_add).symm -instance : AddMonoid (Completion α) := - { (inferInstance : Zero <| Completion α), - (inferInstance : Add <| Completion α) with - zero_add := fun a ↦ - Completion.induction_on a - (isClosed_eq (continuous_map₂ continuous_const continuous_id) continuous_id) fun a ↦ - show 0 + (a : Completion α) = a by rw [← coe_zero, ← coe_add, zero_add] - add_zero := fun a ↦ - Completion.induction_on a - (isClosed_eq (continuous_map₂ continuous_id continuous_const) continuous_id) fun a ↦ - show (a : Completion α) + 0 = a by rw [← coe_zero, ← coe_add, add_zero] - add_assoc := fun a b c ↦ - Completion.induction_on₃ a b c - (isClosed_eq - (continuous_map₂ (continuous_map₂ continuous_fst (by fun_prop)) (by fun_prop)) - (continuous_map₂ continuous_fst (continuous_map₂ (by fun_prop) (by fun_prop)))) - fun a b c ↦ - show (a : Completion α) + b + c = a + (b + c) by repeat' rw_mod_cast [add_assoc] - nsmul := (· • ·) - nsmul_zero := fun a ↦ - Completion.induction_on a (isClosed_eq continuous_map continuous_const) fun a ↦ - show 0 • (a : Completion α) = 0 by rw [← coe_smul, ← coe_zero, zero_smul] - nsmul_succ := fun n a ↦ - Completion.induction_on a - (isClosed_eq continuous_map <| continuous_map₂ continuous_map continuous_id) fun a ↦ - show (n + 1) • (a : Completion α) = n • (a : Completion α) + (a : Completion α) by - rw [← coe_smul, succ_nsmul, coe_add, coe_smul] } - -instance : SubNegMonoid (Completion α) := - { (inferInstance : AddMonoid <| Completion α), - (inferInstance : Neg <| Completion α), - (inferInstance : Sub <| Completion α) with - sub_eq_add_neg := fun a b ↦ - Completion.induction_on₂ a b - (isClosed_eq (continuous_map₂ continuous_fst continuous_snd) - (continuous_map₂ continuous_fst (Completion.continuous_map.comp continuous_snd))) - fun a b ↦ mod_cast congr_arg ((↑) : α → Completion α) (sub_eq_add_neg a b) - zsmul := (· • ·) - zsmul_zero' := fun a ↦ - Completion.induction_on a (isClosed_eq continuous_map continuous_const) fun a ↦ - show (0 : ℤ) • (a : Completion α) = 0 by rw [← coe_smul, ← coe_zero, zero_smul] - zsmul_succ' := fun n a ↦ - Completion.induction_on a - (isClosed_eq continuous_map <| continuous_map₂ continuous_map continuous_id) fun a ↦ - show (n.succ : ℤ) • (a : Completion α) = _ by - rw [← coe_smul, show (n.succ : ℤ) • a = (n : ℤ) • a + a from - SubNegMonoid.zsmul_succ' n a, coe_add, coe_smul] - zsmul_neg' := fun n a ↦ - Completion.induction_on a - (isClosed_eq continuous_map <| Completion.continuous_map.comp continuous_map) fun a ↦ - show (Int.negSucc n) • (a : Completion α) = _ by - rw [← coe_smul, show (Int.negSucc n) • a = -((n.succ : ℤ) • a) from - SubNegMonoid.zsmul_neg' n a, coe_neg, coe_smul] } - -instance addGroup : AddGroup (Completion α) := - { (inferInstance : SubNegMonoid <| Completion α) with - neg_add_cancel := fun a ↦ - Completion.induction_on a - (isClosed_eq (continuous_map₂ Completion.continuous_map continuous_id) continuous_const) - fun a ↦ - show -(a : Completion α) + a = 0 by - rw_mod_cast [neg_add_cancel] - rfl } +instance : AddMonoid (Completion α) where + zero_add a := + Completion.induction_on a + (isClosed_eq (continuous_map₂ continuous_const continuous_id) continuous_id) fun a ↦ + show 0 + (a : Completion α) = a by rw [← coe_zero, ← coe_add, zero_add] + add_zero a := + Completion.induction_on a + (isClosed_eq (continuous_map₂ continuous_id continuous_const) continuous_id) fun a ↦ + show (a : Completion α) + 0 = a by rw [← coe_zero, ← coe_add, add_zero] + add_assoc := fun a b c ↦ + Completion.induction_on₃ a b c + (isClosed_eq + (continuous_map₂ (continuous_map₂ continuous_fst (by fun_prop)) (by fun_prop)) + (continuous_map₂ continuous_fst (continuous_map₂ (by fun_prop) (by fun_prop)))) + fun a b c ↦ + show (a : Completion α) + b + c = a + (b + c) by repeat' rw_mod_cast [add_assoc] + nsmul_zero a := + Completion.induction_on a (isClosed_eq continuous_map continuous_const) fun a ↦ + show 0 • (a : Completion α) = 0 by rw [← coe_smul, ← coe_zero, zero_smul] + nsmul_succ n a := + Completion.induction_on a + (isClosed_eq continuous_map <| continuous_map₂ continuous_map continuous_id) fun a ↦ + show (n + 1) • (a : Completion α) = n • (a : Completion α) + (a : Completion α) by + rw [← coe_smul, succ_nsmul, coe_add, coe_smul] + +instance : SubNegMonoid (Completion α) where + sub_eq_add_neg a b := + Completion.induction_on₂ a b + (isClosed_eq (continuous_map₂ continuous_fst continuous_snd) + (continuous_map₂ continuous_fst (Completion.continuous_map.comp continuous_snd))) + fun a b ↦ mod_cast congr_arg ((↑) : α → Completion α) (sub_eq_add_neg a b) + zsmul_zero' a := + Completion.induction_on a (isClosed_eq continuous_map continuous_const) fun a ↦ + show (0 : ℤ) • (a : Completion α) = 0 by rw [← coe_smul, ← coe_zero, zero_smul] + zsmul_succ' n a := + Completion.induction_on a + (isClosed_eq continuous_map <| continuous_map₂ continuous_map continuous_id) fun a ↦ + show (n.succ : ℤ) • (a : Completion α) = _ by + rw [← coe_smul, show (n.succ : ℤ) • a = (n : ℤ) • a + a from + SubNegMonoid.zsmul_succ' n a, coe_add, coe_smul] + zsmul_neg' n a := + Completion.induction_on a + (isClosed_eq continuous_map <| Completion.continuous_map.comp continuous_map) fun a ↦ + show (Int.negSucc n) • (a : Completion α) = _ by + rw [← coe_smul, show (Int.negSucc n) • a = -((n.succ : ℤ) • a) from + SubNegMonoid.zsmul_neg' n a, coe_neg, coe_smul] + +instance addGroup : AddGroup (Completion α) where + neg_add_cancel a := + Completion.induction_on a + (isClosed_eq (continuous_map₂ Completion.continuous_map continuous_id) continuous_const) + fun a ↦ + show -(a : Completion α) + a = 0 by + rw_mod_cast [neg_add_cancel] + rfl instance isUniformAddGroup : IsUniformAddGroup (Completion α) := ⟨uniformContinuous_map₂ Sub.sub⟩ instance {M} [Monoid M] [DistribMulAction M α] [UniformContinuousConstSMul M α] : - DistribMulAction M (Completion α) := - { (inferInstance : MulAction M <| Completion α) with - smul_add := fun r x y ↦ - induction_on₂ x y - (isClosed_eq ((continuous_fst.fun_add continuous_snd).fun_const_smul _) - ((continuous_fst.fun_const_smul _).fun_add (continuous_snd.fun_const_smul _))) - fun a b ↦ by simp only [← coe_add, ← coe_smul, smul_add] - smul_zero := fun r ↦ by rw [← coe_zero, ← coe_smul, smul_zero r] } + DistribMulAction M (Completion α) where + smul_add r x y := + induction_on₂ x y + (isClosed_eq ((continuous_fst.fun_add continuous_snd).fun_const_smul _) + ((continuous_fst.fun_const_smul _).fun_add (continuous_snd.fun_const_smul _))) + fun a b ↦ by simp only [← coe_add, ← coe_smul, smul_add] + smul_zero := fun r ↦ by rw [← coe_zero, ← coe_smul, smul_zero r] /-- The map from a group to its completion as a group hom. -/ @[simps] diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean index f0f7d0b1425042..b05b66b66b0ea6 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean @@ -450,7 +450,6 @@ instance : AddMonoid (M₁ →SL[σ₁₂] M₂) where intros ext apply_rules [zero_add, add_assoc, add_zero, neg_add_cancel, add_comm] - nsmul := (· • ·) nsmul_zero f := by ext simp @@ -883,7 +882,6 @@ instance : IsSubApply (M →SL[σ₁₂] M₂) M M₂ where -- Todo: figure out how to use `FunLike.addCommGroup` here instance addCommGroup : AddCommGroup (M →SL[σ₁₂] M₂) where sub_eq_add_neg _ _ := by ext; apply sub_eq_add_neg - zsmul := (· • ·) zsmul_zero' f := by ext; simp zsmul_succ' n f := by ext; simp [add_smul, add_comm] zsmul_neg' n f := by ext; simp [add_smul] diff --git a/MathlibTest/InstanceDiamonds.lean b/MathlibTest/InstanceDiamonds.lean index 291be1c646dcb5..17ead3a7c8b831 100644 --- a/MathlibTest/InstanceDiamonds.lean +++ b/MathlibTest/InstanceDiamonds.lean @@ -24,7 +24,7 @@ section SMul open scoped Polynomial -example : (SubNegMonoid.toZSMul : SMul ℤ ℂ) = (Complex.SMul.instSMulRealComplex : SMul ℤ ℂ) := by +example : (ZSMul.toSMul : SMul ℤ ℂ) = (Complex.SMul.instSMulRealComplex : SMul ℤ ℂ) := by with_reducible_and_instances rfl example : Module.restrictScalars ℝ ℂ ℂ = Complex.instModule := by @@ -35,19 +35,19 @@ example : Algebra.restrictScalars ℝ ℂ ℂ = Complex.instAlgebraOfReal := by rfl example (α β : Type _) [AddMonoid α] [AddMonoid β] : - (Prod.instSMul : SMul ℕ (α × β)) = AddMonoid.toNSMul := by + (Prod.instSMul : SMul ℕ (α × β)) = NSMul.toSMul := by with_reducible_and_instances rfl example (α β : Type _) [SubNegMonoid α] [SubNegMonoid β] : - (Prod.instSMul : SMul ℤ (α × β)) = SubNegMonoid.toZSMul := by + (Prod.instSMul : SMul ℤ (α × β)) = ZSMul.toSMul := by with_reducible_and_instances rfl example (α : Type _) (β : α → Type _) [∀ a, AddMonoid (β a)] : - (Pi.instSMul : SMul ℕ (∀ a, β a)) = AddMonoid.toNSMul := by + (Pi.instSMul : SMul ℕ (∀ a, β a)) = NSMul.toSMul := by with_reducible_and_instances rfl example (α : Type _) (β : α → Type _) [∀ a, SubNegMonoid (β a)] : - (Pi.instSMul : SMul ℤ (∀ a, β a)) = SubNegMonoid.toZSMul := by + (Pi.instSMul : SMul ℤ (∀ a, β a)) = ZSMul.toSMul := by with_reducible_and_instances rfl namespace TensorProduct From 5c985547b4e1ed70f8bc6e4d3a341912b221ff9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20In=C3=A9s=20de=20Frutos-Fern=C3=A1ndez?= <88536493+mariainesdff@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:06:42 +0000 Subject: [PATCH 0365/1300] feat(Algebra/Order/Antidiag/Prod): add HasMulAntidiagonal (#38623) We add a multiplicative version of `Finset.HasAntidiagonal`, called `Finset.HasMulAntidiagonal`. This requires some naming changes (since otherwise, for instance, there would be a clash between [Finset.swap_mem_mulAntidiagonal](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Finset/MulAntidiagonal.html#Finset.swap_mem_mulAntidiagonal) and the corresponding lemma in Mathlib.Algebra.Order.Antidiag.Prod). We made the following naming choices: - Since the additive version will be much more commonly used, we still keep `Finset.HasAntidiagonal` for the additive version, and translate `mulAntidiagonal` to `antidiagonal` rather than to `addAntidiagonal`. Note that in particular this affects the API in Mathlib.Data.Finset.MulAntidiagonal, which used `addAntidiagonal`. - We move most of the results in `Mathlib.Algebra.Order.Antidiag.Prod` into the `Has(Mul)Antidiagonal` namespace, so that e.g. `Finset.swap_mem_antidiagonal` and `Finset.HasAntidiagonal.mem_antidiagonal` can co-exist. Note that some deprecation tags (e.g., for Finset.antidiagonal, Finset.antidiagonal.fst_le, ...) are intentionally missing. The reason is that `antidiagonal` and related lemmas are normally used inside an open `Finset` namespace, and since these declarations have moved into `Finset.HasAntidiagonal`, the deprecation causes errors which would require to explicitly add `HasAntidiagonal` in many places. An easier solution is just to open `Finset.HasAntidiagonal`, after which the preexisting code works. Co-authored-by : @xgenereux Co-authored-by: mariainesdff --- .../Algebra/BigOperators/NatAntidiagonal.lean | 2 + Mathlib/Algebra/Order/Antidiag/Pi.lean | 4 +- Mathlib/Algebra/Order/Antidiag/Prod.lean | 205 ++++++++++++------ .../Enumerative/Catalan/Tree.lean | 2 +- Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean | 2 +- Mathlib/Data/Finset/MulAntidiagonal.lean | 13 +- Mathlib/Data/Finset/NatAntidiagonal.lean | 2 + Mathlib/NumberTheory/Bernoulli.lean | 3 +- Mathlib/RingTheory/Binomial.lean | 2 +- Mathlib/RingTheory/HahnSeries/HEval.lean | 6 +- .../RingTheory/HahnSeries/Multiplication.lean | 34 +-- .../RingTheory/HahnSeries/PowerSeries.lean | 8 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 10 +- Mathlib/RingTheory/MvPowerSeries/Basic.lean | 8 +- .../MvPowerSeries/LinearTopology.lean | 6 +- .../RingTheory/PowerSeries/CoeffMulMem.lean | 4 +- .../PowerSeries/WeierstrassPreparation.lean | 4 +- Mathlib/Tactic/Translate/ToAdditive.lean | 1 + .../Topology/Algebra/InfiniteSum/Ring.lean | 6 +- 19 files changed, 211 insertions(+), 111 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/NatAntidiagonal.lean b/Mathlib/Algebra/BigOperators/NatAntidiagonal.lean index 3a1586e333a224..c3e776db575321 100644 --- a/Mathlib/Algebra/BigOperators/NatAntidiagonal.lean +++ b/Mathlib/Algebra/BigOperators/NatAntidiagonal.lean @@ -20,6 +20,8 @@ variable {M N : Type*} [CommMonoid M] [AddCommMonoid N] namespace Finset +open HasAntidiagonal + namespace Nat theorem prod_antidiagonal_succ {n : ℕ} {f : ℕ × ℕ → M} : diff --git a/Mathlib/Algebra/Order/Antidiag/Pi.lean b/Mathlib/Algebra/Order/Antidiag/Pi.lean index b9f0282abd1dda..9202ca123bbffc 100644 --- a/Mathlib/Algebra/Order/Antidiag/Pi.lean +++ b/Mathlib/Algebra/Order/Antidiag/Pi.lean @@ -162,8 +162,8 @@ lemma pairwiseDisjoint_piAntidiag_map_addRightEmbedding (hi : i ∉ s) (n : μ) (antidiagonal n : Set (μ × μ)).PairwiseDisjoint fun p ↦ map (addRightEmbedding fun j ↦ if j = i then p.1 else 0) (s.piAntidiag p.2) := by rintro ⟨a, b⟩ hab ⟨c, d⟩ hcd - simp only [ne_eq, antidiagonal_congr' hab hcd, disjoint_left, mem_map, mem_piAntidiag, - addRightEmbedding_apply, not_exists, not_and, and_imp, forall_exists_index] + simp only [ne_eq, HasAntidiagonal.antidiagonal_congr' hab hcd, disjoint_left, mem_map, + mem_piAntidiag, addRightEmbedding_apply, not_exists, not_and, and_imp, forall_exists_index] rintro hfg _ f rfl - rfl g rfl - hgf exact hfg <| by simpa [sum_add_distrib, hi] using congr_arg (∑ j ∈ s, · j) hgf.symm diff --git a/Mathlib/Algebra/Order/Antidiag/Prod.lean b/Mathlib/Algebra/Order/Antidiag/Prod.lean index e53c0810966ba6..58db0a53be1126 100644 --- a/Mathlib/Algebra/Order/Antidiag/Prod.lean +++ b/Mathlib/Algebra/Order/Antidiag/Prod.lean @@ -5,6 +5,7 @@ Authors: Antoine Chambert-Loir, María Inés de Frutos-Fernández, Bhavik Mehta, -/ module +public import Mathlib.Algebra.Group.TypeTags.Basic public import Mathlib.Algebra.Order.Monoid.Canonical.Defs public import Mathlib.Algebra.Order.Sub.Defs public import Mathlib.Data.Finset.Basic @@ -16,6 +17,10 @@ We define a type class `Finset.HasAntidiagonal A` which contains a function `antidiagonal : A → Finset (A × A)` such that `antidiagonal n` is the finset of all pairs adding to `n`, as witnessed by `mem_antidiagonal`. +Analogously, the type class `Finset.HasMulAntidiagonal A` contains a function +`mulAntidiagonal : A → Finset (A × A)` such that `mulAntidiagonal n` +is the finset of all pairs multiplying to `n`, as witnessed by `mem_mulAntidiagonal`. + When `A` is a canonically ordered additive monoid with locally finite order this typeclass can be instantiated with `Finset.antidiagonalOfLocallyFinite`. This applies in particular when `A` is `ℕ`, more generally or `σ →₀ ℕ`, @@ -27,8 +32,9 @@ and any finiteness condition would be OK.) For computational reasons it is better to manually provide instances for `ℕ` and `σ →₀ ℕ`, to avoid quadratic runtime performance. -These instances are provided as `Finset.Nat.instHasAntidiagonal` and `Finsupp.instHasAntidiagonal`. -This is why `Finset.antidiagonalOfLocallyFinite` is an `abbrev` and not an `instance`. +These instances are provided as `Finset.Nat.instHasAntidiagonal` and +`Finsupp.instHasAntidiagonal`. +This is why `Finset.mulAntidiagonalOfLocallyFinite` is an `abbrev` and not an `instance`. This definition does not exactly match with that of `Multiset.antidiagonal` defined in `Mathlib/Data/Multiset/Antidiagonal.lean`, because of the multiplicities. @@ -45,8 +51,7 @@ def s : Multiset ℕ := {0, 0, 0} ## TODO -* Define `HasMulAntidiagonal` (for monoids). - For `PNat`, we will recover the set of divisors of a strictly positive integer. +* For `PNat`, `HasMulAntidiagonal` will recover the set of divisors of a strictly positive integer. -/ @[expose] public section @@ -55,9 +60,10 @@ open Function namespace Finset -/-- The class of additive monoids with an antidiagonal -/ +/-- The class of additive monoids with an antidiagonal. -/ class HasAntidiagonal (A : Type*) [AddMonoid A] where - /-- The antidiagonal of an element `n` is the finset of pairs `(i, j)` such that `i + j = n`. -/ + /-- The antidiagonal of an element `n` is the finset of pairs `(i, j)` such that + `i + j = n`. -/ antidiagonal : A → Finset (A × A) /-- A pair belongs to `antidiagonal n` iff the sum of its components is equal to `n`. -/ mem_antidiagonal {n} {a} : a ∈ antidiagonal n ↔ a.fst + a.snd = n @@ -66,88 +72,127 @@ export HasAntidiagonal (antidiagonal mem_antidiagonal) attribute [simp] mem_antidiagonal +/-- The class of (multiplicative) monoids with a mulAntidiagonal. -/ +class HasMulAntidiagonal (A : Type*) [Monoid A] where + /-- The mulAntidiagonal of an element `n` is the finset of pairs `(i, j)` such that + `i * j = n`. -/ + mulAntidiagonal : A → Finset (A × A) + /-- A pair belongs to `mulAntidiagonal n` iff the product of its components is equal to `n`. -/ + mem_mulAntidiagonal {n} {a} : a ∈ mulAntidiagonal n ↔ a.fst * a.snd = n + +attribute [to_additive] HasMulAntidiagonal + +export HasMulAntidiagonal (mulAntidiagonal mem_mulAntidiagonal) + +attribute [simp] HasMulAntidiagonal.mem_mulAntidiagonal + variable {A : Type*} -/-- All `HasAntidiagonal` instances are equal -/ -instance [AddMonoid A] : Subsingleton (HasAntidiagonal A) where +namespace HasMulAntidiagonal + +/-- All `HasMulAntidiagonal` instances are equal -/ +@[to_additive /-- All `HasAntidiagonal` instances are equal -/] +instance [Monoid A] : Subsingleton (HasMulAntidiagonal A) where allEq := by rintro ⟨a, ha⟩ ⟨b, hb⟩ congr with n xy rw [ha, hb] --- The goal of this lemma is to allow to rewrite antidiagonal +-- The goal of this lemma is to allow to rewrite mulAntidiagonal/antidiagonal -- when the decidability instances obfuscate Lean set_option linter.overlappingInstances false in -lemma hasAntidiagonal_congr (A : Type*) [AddMonoid A] - [H1 : HasAntidiagonal A] [H2 : HasAntidiagonal A] : - H1.antidiagonal = H2.antidiagonal := by congr!; subsingleton +@[to_additive] +lemma congr (A : Type*) [Monoid A] + [H1 : HasMulAntidiagonal A] [H2 : HasMulAntidiagonal A] : + H1.mulAntidiagonal = H2.mulAntidiagonal := by congr!; subsingleton -theorem swap_mem_antidiagonal [AddCommMonoid A] [HasAntidiagonal A] {n : A} {xy : A × A} : - xy.swap ∈ antidiagonal n ↔ xy ∈ antidiagonal n := by - simp [add_comm] +@[to_additive] +theorem swap_mem_mulAntidiagonal [CommMonoid A] [HasMulAntidiagonal A] {n : A} {xy : A × A} : + xy.swap ∈ mulAntidiagonal n ↔ xy ∈ mulAntidiagonal n := by + simp [mul_comm] -@[simp] theorem map_prodComm_antidiagonal [AddCommMonoid A] [HasAntidiagonal A] {n : A} : - (antidiagonal n).map (Equiv.prodComm A A) = antidiagonal n := - Finset.ext fun ⟨a, b⟩ => by simp [add_comm] +@[to_additive (attr := simp) map_prodComm_antidiagonal] +theorem map_prodComm_mulAntidiagonal [CommMonoid A] [HasMulAntidiagonal A] {n : A} : + (mulAntidiagonal n).map (Equiv.prodComm A A) = mulAntidiagonal n := + Finset.ext fun ⟨a, b⟩ => by simp [mul_comm] -/-- See also `Finset.map_prodComm_antidiagonal`. -/ -@[simp] theorem map_swap_antidiagonal [AddCommMonoid A] [HasAntidiagonal A] {n : A} : - (antidiagonal n).map ⟨Prod.swap, Prod.swap_injective⟩ = antidiagonal n := - map_prodComm_antidiagonal +/-- See also `Finset.map_prodComm_mulAntidiagonal`. -/ +@[to_additive (attr := simp)] +theorem map_swap_mulAntidiagonal [CommMonoid A] [HasMulAntidiagonal A] {n : A} : + (mulAntidiagonal n).map ⟨Prod.swap, Prod.swap_injective⟩ = mulAntidiagonal n := + map_prodComm_mulAntidiagonal -section AddCancelMonoid -variable [AddCancelMonoid A] [HasAntidiagonal A] {p q : A × A} {n : A} +section CancelMonoid +variable [CancelMonoid A] [HasMulAntidiagonal A] {p q : A × A} {n : A} + +/-- A point in the mulAntidiagonal is determined by its first coordinate. + +See also `Finset.mulAntidiagonal_congr'`. -/ +@[to_additive /-- A point in the antidiagonal is determined by its first coordinate. -See also `Finset.antidiagonal_congr'`. -/ -theorem antidiagonal_congr (hp : p ∈ antidiagonal n) (hq : q ∈ antidiagonal n) : +See also `Finset.antidiagonal_congr'`. -/] +theorem mulAntidiagonal_congr (hp : p ∈ mulAntidiagonal n) (hq : q ∈ mulAntidiagonal n) : p = q ↔ p.1 = q.1 := by - refine ⟨congr_arg Prod.fst, fun h ↦ Prod.ext h ((add_right_inj q.fst).mp ?_)⟩ - rw [mem_antidiagonal] at hp hq + refine ⟨congr_arg Prod.fst, fun h ↦ Prod.ext h ((mul_right_inj q.fst).mp ?_)⟩ + rw [mem_mulAntidiagonal] at hp hq rw [hq, ← h, hp] +/-- A point in the mulAntidiagonal is determined by its first co-ordinate (subtype version of +`Finset.mulAntidiagonal_congr`). This lemma is used by the `ext` tactic. -/ +@[to_additive (attr := ext) /-- A point in the antidiagonal is determined by its first co-ordinate (subtype version of -`Finset.antidiagonal_congr`). This lemma is used by the `ext` tactic. -/ -@[ext] theorem antidiagonal_subtype_ext {p q : antidiagonal n} (h : p.val.1 = q.val.1) : p = q := - Subtype.ext ((antidiagonal_congr p.prop q.prop).mpr h) +`Finset.antidiagonal_congr`). This lemma is used by the `ext` tactic. -/] +theorem mulAntidiagonal_subtype_ext {p q : mulAntidiagonal n} (h : p.val.1 = q.val.1) : p = q := + Subtype.ext ((mulAntidiagonal_congr p.prop q.prop).mpr h) + +end CancelMonoid -end AddCancelMonoid +section CancelCommMonoid +variable [CancelCommMonoid A] [HasMulAntidiagonal A] {p q : A × A} {n : A} -section AddCancelCommMonoid -variable [AddCancelCommMonoid A] [HasAntidiagonal A] {p q : A × A} {n : A} +/-- A point in the mulAntidiagonal is determined by its second coordinate. -/-- A point in the antidiagonal is determined by its second coordinate. +See also `Finset.mulAntidiagonal_congr`. -/ +@[to_additive /-- A point in the antidiagonal is determined by its second coordinate. -See also `Finset.antidiagonal_congr`. -/ -lemma antidiagonal_congr' (hp : p ∈ antidiagonal n) (hq : q ∈ antidiagonal n) : +See also `Finset.antidiagonal_congr`. -/] +lemma mulAntidiagonal_congr' (hp : p ∈ mulAntidiagonal n) (hq : q ∈ mulAntidiagonal n) : p = q ↔ p.2 = q.2 := by rw [← Prod.swap_inj] - exact antidiagonal_congr (swap_mem_antidiagonal.2 hp) (swap_mem_antidiagonal.2 hq) + exact mulAntidiagonal_congr (swap_mem_mulAntidiagonal.2 hp) (swap_mem_mulAntidiagonal.2 hq) -end AddCancelCommMonoid +end CancelCommMonoid -section CanonicallyOrderedAdd -variable [AddCommMonoid A] [PartialOrder A] [CanonicallyOrderedAdd A] [HasAntidiagonal A] +section CanonicallyOrderedMul -@[simp] -theorem antidiagonal_zero : antidiagonal (0 : A) = {(0, 0)} := by +variable [CommMonoid A] [PartialOrder A] [CanonicallyOrderedMul A] [HasMulAntidiagonal A] + +@[to_additive (attr := simp)] +theorem mulAntidiagonal_one : mulAntidiagonal (1 : A) = {(1, 1)} := by ext ⟨x, y⟩ simp -theorem antidiagonal.fst_le {n : A} {kl : A × A} (hlk : kl ∈ antidiagonal n) : kl.1 ≤ n := by - rw [le_iff_exists_add] +@[to_additive] +theorem mulAntidiagonal.fst_le {n : A} {kl : A × A} (hlk : kl ∈ mulAntidiagonal n) : kl.1 ≤ n := by + rw [le_iff_exists_mul] use kl.2 - rwa [mem_antidiagonal, eq_comm] at hlk + rwa [mem_mulAntidiagonal, eq_comm] at hlk -theorem antidiagonal.snd_le {n : A} {kl : A × A} (hlk : kl ∈ antidiagonal n) : kl.2 ≤ n := by - rw [le_iff_exists_add] +@[to_additive] +theorem mulAntidiagonal.snd_le {n : A} {kl : A × A} (hlk : kl ∈ mulAntidiagonal n) : kl.2 ≤ n := by + rw [le_iff_exists_mul] use kl.1 - rwa [mem_antidiagonal, eq_comm, add_comm] at hlk + rwa [mem_mulAntidiagonal, eq_comm, mul_comm] at hlk + +end CanonicallyOrderedMul -end CanonicallyOrderedAdd +end HasMulAntidiagonal +namespace HasAntidiagonal section OrderedSub + variable [AddCommMonoid A] [PartialOrder A] [CanonicallyOrderedAdd A] [Sub A] [OrderedSub A] variable [AddLeftReflectLE A] variable [HasAntidiagonal A] @@ -173,30 +218,66 @@ theorem filter_snd_eq_antidiagonal (n m : A) [DecidablePred (· = m)] [Decidable end OrderedSub -/-- The disjoint union of antidiagonals `Σ (n : A), antidiagonal n` is equivalent to the product - `A × A`. This is such an equivalence, obtained by mapping `(n, (k, l))` to `(k, l)`. -/ -@[simps] -def sigmaAntidiagonalEquivProd [AddMonoid A] [HasAntidiagonal A] : - (Σ n : A, antidiagonal n) ≃ A × A where +end HasAntidiagonal + +namespace HasMulAntidiagonal + +/-- The disjoint union of mulAntidiagonals `Σ (n : A), mulAntidiagonal n` is equivalent to the + product `A × A`. This is such an equivalence, obtained by mapping `(n, (k, l))` to `(k, l)`. -/ +@[to_additive (attr := simps) sigmaAntidiagonalEquivProd +/-- The disjoint union of antidiagonals `Σ (n : A), antidiagonal n` is equivalent to the + product `A × A`. This is such an equivalence, obtained by mapping `(n, (k, l))` to `(k, l)`. -/] +def sigmaMulAntidiagonalEquivProd [Monoid A] [HasMulAntidiagonal A] : + (Σ n : A, mulAntidiagonal n) ≃ A × A where toFun x := x.2 - invFun x := ⟨x.1 + x.2, x, mem_antidiagonal.mpr rfl⟩ + invFun x := ⟨x.1 * x.2, x, mem_mulAntidiagonal.mpr rfl⟩ left_inv := by rintro ⟨n, ⟨k, l⟩, h⟩ - rw [mem_antidiagonal] at h + rw [mem_mulAntidiagonal] at h exact Sigma.subtype_ext h rfl +section + variable {A : Type*} - [AddCommMonoid A] [PartialOrder A] [CanonicallyOrderedAdd A] + [CommMonoid A] [PartialOrder A] [CanonicallyOrderedMul A] [LocallyFiniteOrderBot A] [DecidableEq A] +/-- In a canonically ordered multiplicative monoid, the mulAntidiagonal can be constructed by +filtering. + +Note that this is not an instance, as for sometimes a more efficient algorithm is available. -/ +@[to_additive /-- In a canonically ordered additive monoid, the antidiagonal can be construct by filtering. -Note that this is not an instance, as for some times a more efficient algorithm is available. -/ -abbrev antidiagonalOfLocallyFinite : HasAntidiagonal A where - antidiagonal n := {uv ∈ Iic n ×ˢ Iic n | uv.fst + uv.snd = n} - mem_antidiagonal {n} {a} := by +Note that this is not an instance, as for some times a more efficient algorithm is available. -/] +abbrev mulAntidiagonalOfLocallyFinite : HasMulAntidiagonal A where + mulAntidiagonal n := {uv ∈ Iic n ×ˢ Iic n | uv.fst * uv.snd = n} + mem_mulAntidiagonal {n} {a} := by simp only [mem_filter, and_iff_right_iff_imp] intro h simp [← h] +end + +section Multiplicative + +open Multiplicative + +variable {A : Type*} [AddMonoid A] [HasAntidiagonal A] + +instance : HasMulAntidiagonal (Multiplicative A) where + mulAntidiagonal a := + (antidiagonal (toAdd a)).map ⟨fun p ↦ (ofAdd p.1 , ofAdd p.2), fun _ _ h ↦ by aesop⟩ + mem_mulAntidiagonal {a p} := by aesop + +lemma mem_mulAntidiagonal_ofAdd_iff_toAdd_mem_antidiagonal {a : A} + {p : Multiplicative A × Multiplicative A} : + p ∈ mulAntidiagonal (ofAdd a) ↔ (toAdd p.1, toAdd p.2) ∈ antidiagonal a := by + simp only [mem_mulAntidiagonal, mem_antidiagonal] + rw [Multiplicative.ext_iff, toAdd_mul, toAdd_ofAdd] + +end Multiplicative + +end HasMulAntidiagonal + end Finset diff --git a/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean b/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean index c29da1292184a8..007aa07a4cbc53 100644 --- a/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean +++ b/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean @@ -26,7 +26,7 @@ import Mathlib.Tactic.Field open Finset -open Finset.antidiagonal (fst_le snd_le) +open Finset.HasAntidiagonal.antidiagonal (fst_le snd_le) namespace BinaryTree diff --git a/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean b/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean index 980e2e2030d76d..9a7d516485437b 100644 --- a/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean +++ b/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean @@ -234,7 +234,7 @@ section EquivProd /-- The disjoint union of antidiagonal tuples `Σ n, antidiagonalTuple k n` is equivalent to the `k`-tuple `Fin k → ℕ`. This is such an equivalence, obtained by mapping `(n, x)` to `x`. -This is the tuple version of `Finset.sigmaAntidiagonalEquivProd`. -/ +This is the tuple version of `Finset..HasAntidiagonal.sigmaAntidiagonalEquivProd`. -/ @[simps] def sigmaAntidiagonalTupleEquivTuple (k : ℕ) : (Σ n, antidiagonalTuple k n) ≃ (Fin k → ℕ) where toFun x := x.2 diff --git a/Mathlib/Data/Finset/MulAntidiagonal.lean b/Mathlib/Data/Finset/MulAntidiagonal.lean index 0390ccad26f580..f3da3e9b6a94e3 100644 --- a/Mathlib/Data/Finset/MulAntidiagonal.lean +++ b/Mathlib/Data/Finset/MulAntidiagonal.lean @@ -57,7 +57,7 @@ variable [CommMonoid α] [PartialOrder α] [IsOrderedCancelMonoid α] /-- `Finset.mulAntidiagonal hs ht a` is the set of all pairs of an element in `s` and an element in `t` that multiply to `a`, but its construction requires proofs that `s` and `t` are well-ordered. -/ -@[to_additive /-- `Finset.addAntidiagonal hs ht a` is the set of all pairs of an element in +@[to_additive /-- `Finset.antidiagonal hs ht a` is the set of all pairs of an element in `s` and an element in `t` that add to `a`, but its construction requires proofs that `s` and `t` are well-ordered. -/] noncomputable def mulAntidiagonal : Finset (α × α) := @@ -108,4 +108,15 @@ theorem mulAntidiagonal_min_mul_min {α} [CommMonoid α] [LinearOrder α] [IsOrd · rintro ⟨rfl, rfl⟩ exact ⟨hs.min_mem _, ht.min_mem _, rfl⟩ +@[deprecated (since := "2026-06-08")] alias addAntidiagonal := antidiagonal +@[deprecated (since := "2026-06-08")] alias mem_addAntidiagonal := mem_antidiagonal +@[deprecated (since := "2026-06-08")] alias addAntidiagonal_mono_left := antidiagonal_mono_left +@[deprecated (since := "2026-06-08")] alias addAntidiagonal_mono_right := antidiagonal_mono_right +@[deprecated (since := "2026-06-08")] alias swap_mem_addAntidiagonal := swap_mem_antidiagonal +@[deprecated (since := "2026-06-08")] +alias support_addAntidiagonal_subset_add := support_antidiagonal_subset_add +@[deprecated (since := "2026-06-08")] +alias isPWO_support_addAntidiagonal := isPWO_support_antidiagonal +@[deprecated (since := "2026-06-08")] alias addAntidiagonal_min_mul_min := antidiagonal_min_add_min + end Finset diff --git a/Mathlib/Data/Finset/NatAntidiagonal.lean b/Mathlib/Data/Finset/NatAntidiagonal.lean index a9bc329d17e3ee..9bfb92c051c2aa 100644 --- a/Mathlib/Data/Finset/NatAntidiagonal.lean +++ b/Mathlib/Data/Finset/NatAntidiagonal.lean @@ -30,6 +30,8 @@ open Function namespace Finset +open Finset.HasAntidiagonal + namespace Nat /-- The antidiagonal of a natural number `n` is diff --git a/Mathlib/NumberTheory/Bernoulli.lean b/Mathlib/NumberTheory/Bernoulli.lean index 1e723409e73cf4..9a289e32988008 100644 --- a/Mathlib/NumberTheory/Bernoulli.lean +++ b/Mathlib/NumberTheory/Bernoulli.lean @@ -262,7 +262,8 @@ theorem bernoulli_spec' (n : ℕ) : convert! eq_sub_of_add_eq' H using 1 · refine sum_congr rfl fun p h => ?_ obtain ⟨h', h''⟩ : p ∈ _ ∧ p ≠ _ := by rwa [mem_sdiff, mem_singleton] at h - simp [bernoulli_eq_bernoulli'_of_ne_one ((not_congr (antidiagonal_congr h' h₁)).mp h'')] + simp [bernoulli_eq_bernoulli'_of_ne_one + ((not_congr (HasAntidiagonal.antidiagonal_congr h' h₁)).mp h'')] · simp [field, h₃] norm_num diff --git a/Mathlib/RingTheory/Binomial.lean b/Mathlib/RingTheory/Binomial.lean index 48cf0d55e89325..ede4089fd6784e 100644 --- a/Mathlib/RingTheory/Binomial.lean +++ b/Mathlib/RingTheory/Binomial.lean @@ -523,7 +523,7 @@ theorem add_choose_eq [Ring R] [BinomialRing R] {r s : R} (k : ℕ) (h : Commute ← descPochhammer_eq_factorial_smul_choose, smul_sum, descPochhammer_smeval_add _ h] refine sum_congr rfl ?_ intro x hx - rw [← Nat.choose_mul_factorial_mul_factorial (antidiagonal.fst_le hx), + rw [← Nat.choose_mul_factorial_mul_factorial (HasAntidiagonal.antidiagonal.fst_le hx), tsub_eq_of_eq_add_rev (List.Nat.mem_antidiagonal.mp hx).symm, mul_assoc, nsmul_eq_mul, Nat.cast_mul, Nat.cast_mul, ← mul_assoc _ (x.1.factorial : R), mul_assoc _ (x.2.factorial : R), ← mul_assoc (x.2.factorial : R), Nat.cast_commute x.2.factorial, diff --git a/Mathlib/RingTheory/HahnSeries/HEval.lean b/Mathlib/RingTheory/HahnSeries/HEval.lean index c5d26e685b07bb..1fd494bca65b66 100644 --- a/Mathlib/RingTheory/HahnSeries/HEval.lean +++ b/Mathlib/RingTheory/HahnSeries/HEval.lean @@ -94,7 +94,7 @@ theorem support_powerSeriesFamily_subset {x : V⟦Γ⟧} (a b : PowerSeries R) ( ((powers x) n).coeff g ≠ 0 := by refine exists_ne_zero_of_sum_ne_zero ?_ simpa [PowerSeries.coeff_mul, sum_smul, mul_smul, h] using hn - simp only [powers_of_orderTop_pos h, mem_antidiagonal] at he + simp only [powers_of_orderTop_pos h, HasAntidiagonal.mem_antidiagonal] at he obtain ⟨c, hcn, hc⟩ := he simp only [coe_image, Set.Finite.coe_toFinset, Set.mem_image] use c @@ -129,7 +129,7 @@ theorem hsum_powerSeriesFamily_mul {x : V⟦Γ⟧} (a b : PowerSeries R) : (fun _ _ => by simp [smul_smul, mul_comm, pow_add])).symm · intro ij hij simp only [coe_sigma, coe_image, Set.mem_sigma_iff, Set.mem_image, Prod.exists, mem_coe, - mem_antidiagonal, and_true] + HasAntidiagonal.mem_antidiagonal, and_true] use ij.1, ij.2 simp_all · intro i hi his @@ -140,7 +140,7 @@ theorem hsum_powerSeriesFamily_mul {x : V⟦Γ⟧} (a b : PowerSeries R) : simp only [powers_of_orderTop_pos h, Set.Finite.coe_toFinset, Set.mem_image, Function.mem_support, ne_eq, Prod.exists, not_exists, not_and] at his exact his m n - simp only [mem_sigma, mem_antidiagonal] at hi + simp only [mem_sigma, HasAntidiagonal.mem_antidiagonal] at hi rw [mul_comm ((PowerSeries.coeff i.snd.1) a), ← hi.2, mul_smul, pow_add] exact hisc i.snd.1 i.snd.2 <| Sigma.eq hi.2 (by simp) · simp only [h, not_false_eq_true, powerSeriesFamily_of_not_orderTop_pos, diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index b79bc4fe3c4980..f5c2ba2c1e6c99 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -400,7 +400,7 @@ theorem of_symm_smul_of_eq_mul [NonUnitalNonAssocSemiring R] {x y : R⟦Γ⟧} : theorem coeff_mul [NonUnitalNonAssocSemiring R] {x y : R⟦Γ⟧} {a : Γ} : (x * y).coeff a = - ∑ ij ∈ addAntidiagonal x.isPWO_support y.isPWO_support a, x.coeff ij.fst * y.coeff ij.snd := + ∑ ij ∈ antidiagonal x.isPWO_support y.isPWO_support a, x.coeff ij.fst * y.coeff ij.snd := rfl protected lemma map_mul [NonUnitalNonAssocSemiring R] [NonUnitalNonAssocSemiring S] (f : R →ₙ+* S) @@ -408,9 +408,9 @@ protected lemma map_mul [NonUnitalNonAssocSemiring R] [NonUnitalNonAssocSemiring ext simp only [map_coeff, coeff_mul, map_sum, map_mul] refine Eq.symm (sum_subset (fun gh hgh => ?_) (fun gh hgh hz => ?_)) - · simp_all only [mem_addAntidiagonal, mem_support, map_coeff, ne_eq, and_true] + · simp_all only [mem_antidiagonal, mem_support, map_coeff, ne_eq, and_true] exact ⟨fun h => hgh.1 (map_zero f ▸ congrArg f h), fun h => hgh.2.1 (map_zero f ▸ congrArg f h)⟩ - · simp_all only [mem_addAntidiagonal, mem_support, ne_eq, map_coeff, and_true, + · simp_all only [mem_antidiagonal, mem_support, ne_eq, map_coeff, and_true, not_and, not_not] by_cases h : f (x.coeff gh.1) = 0 · exact mul_eq_zero_of_left h (f (y.coeff gh.2)) @@ -419,13 +419,13 @@ protected lemma map_mul [NonUnitalNonAssocSemiring R] [NonUnitalNonAssocSemiring theorem coeff_mul_left' [NonUnitalNonAssocSemiring R] {x y : R⟦Γ⟧} {a : Γ} {s : Set Γ} (hs : s.IsPWO) (hxs : x.support ⊆ s) : (x * y).coeff a = - ∑ ij ∈ addAntidiagonal hs y.isPWO_support a, x.coeff ij.fst * y.coeff ij.snd := + ∑ ij ∈ antidiagonal hs y.isPWO_support a, x.coeff ij.fst * y.coeff ij.snd := HahnModule.coeff_smul_left hs hxs theorem coeff_mul_right' [NonUnitalNonAssocSemiring R] {x y : R⟦Γ⟧} {a : Γ} {s : Set Γ} (hs : s.IsPWO) (hys : y.support ⊆ s) : (x * y).coeff a = - ∑ ij ∈ addAntidiagonal x.isPWO_support hs a, x.coeff ij.fst * y.coeff ij.snd := + ∑ ij ∈ antidiagonal x.isPWO_support hs a, x.coeff ij.fst * y.coeff ij.snd := HahnModule.coeff_smul_right hs hys instance [NonUnitalNonAssocSemiring R] : Distrib R⟦Γ⟧ where @@ -453,14 +453,14 @@ theorem coeff_mul_single_add [NonUnitalNonAssocSemiring R] {r : R} {x : R⟦Γ rw [sum_congr _ fun _ _ => rfl, sum_empty] ext ⟨a1, a2⟩ simp only [notMem_empty, not_and, Set.mem_singleton_iff, - mem_addAntidiagonal, iff_false] + mem_antidiagonal, iff_false] rintro h2 rfl h1 rw [← add_right_cancel h1] at hx exact h2 hx trans ∑ ij ∈ {(a, b)}, x.coeff ij.fst * (single b r).coeff ij.snd · apply sum_congr _ fun _ _ => rfl ext ⟨a1, a2⟩ - simp only [Set.mem_singleton_iff, Prod.mk_inj, mem_addAntidiagonal, mem_singleton] + simp only [Set.mem_singleton_iff, Prod.mk_inj, mem_antidiagonal, mem_singleton] constructor · rintro ⟨_, rfl, h1⟩ exact ⟨add_right_cancel h1, rfl⟩ @@ -621,7 +621,7 @@ instance [NonUnitalCommSemiring R] : NonUnitalCommSemiring R⟦Γ⟧ where mul_comm x y := by ext simp_rw [coeff_mul, mul_comm] - exact Finset.sum_equiv (Equiv.prodComm _ _) (fun _ ↦ swap_mem_addAntidiagonal.symm) <| by simp + exact Finset.sum_equiv (Equiv.prodComm _ _) (fun _ ↦ swap_mem_antidiagonal.symm) <| by simp instance [CommSemiring R] : CommSemiring R⟦Γ⟧ where instance [NonUnitalNonAssocRing R] : NonUnitalNonAssocRing R⟦Γ⟧ where @@ -780,7 +780,7 @@ theorem single_mul_single {a b : Γ} {r s : R} : · rw [h, coeff_mul_single_add] simp · rw [coeff_single_of_ne h, coeff_mul, sum_eq_zero] - simp_rw [mem_addAntidiagonal] + simp_rw [mem_antidiagonal] rintro ⟨y, z⟩ ⟨hy, hz, rfl⟩ rw [eq_of_mem_support_single hy, eq_of_mem_support_single hz] at h exact (h rfl).elim @@ -863,13 +863,13 @@ theorem embDomain_mul [NonUnitalNonAssocSemiring R] (f : Γ ↪o Γ') simp only [coeff_mul, embDomain_coeff] trans ∑ ij ∈ - (addAntidiagonal x.isPWO_support y.isPWO_support g).map + (antidiagonal x.isPWO_support y.isPWO_support g).map (f.toEmbedding.prodMap f.toEmbedding), (embDomain f x).coeff ij.1 * (embDomain f y).coeff ij.2 · simp apply sum_subset · rintro ⟨i, j⟩ hij - simp only [mem_map, mem_addAntidiagonal, + simp only [mem_map, mem_antidiagonal, Function.Embedding.coe_prodMap, mem_support, Prod.exists] at hij obtain ⟨i, j, ⟨hx, hy, rfl⟩, rfl, rfl⟩ := hij simp [hx, hy, hf] @@ -877,9 +877,9 @@ theorem embDomain_mul [NonUnitalNonAssocSemiring R] (f : Γ ↪o Γ') contrapose! h2 obtain ⟨i, _, rfl⟩ := support_embDomain_subset (ne_zero_and_ne_zero_of_mul h2).1 obtain ⟨j, _, rfl⟩ := support_embDomain_subset (ne_zero_and_ne_zero_of_mul h2).2 - simp only [mem_map, mem_addAntidiagonal, + simp only [mem_map, mem_antidiagonal, Function.Embedding.coe_prodMap, mem_support, Prod.exists] - simp only [mem_addAntidiagonal, embDomain_coeff, mem_support, ← hf, + simp only [mem_antidiagonal, embDomain_coeff, mem_support, ← hf, OrderEmbedding.eq_iff_eq] at h1 exact ⟨i, j, h1, rfl⟩ · rw [embDomain_notin_range hg, eq_comm] @@ -975,11 +975,11 @@ instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where have ha : y.coeff a ≠ z.coeff a := this.min_mem hyz refine ⟨x.order + a, ?_⟩ rwa [coeff_mul, coeff_mul, sum_subset subset_union_left, - sum_subset (s₁ := addAntidiagonal _ _ _) subset_union_right, + sum_subset (s₁ := antidiagonal _ _ _) subset_union_right, sum_eq_sum_iff_single (i := (x.order, a)), mul_right_inj' (coeff_order_eq_zero.not.2 hx)] · simp [hx] grind - · simp +contextual only [mem_union, mem_addAntidiagonal, mul_eq_mul_left_iff, Prod.mk.injEq, + · simp +contextual only [mem_union, mem_antidiagonal, mul_eq_mul_left_iff, Prod.mk.injEq, ne_eq, ← and_or_left, ← or_and_right, or_false, and_imp, Prod.forall, mem_support, not_and] rintro b c hxb - hbc hbc' contrapose! hbc' @@ -997,11 +997,11 @@ instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where have ha : y.coeff a ≠ z.coeff a := this.min_mem hyz refine ⟨a + x.order, ?_⟩ rwa [coeff_mul, coeff_mul, sum_subset subset_union_left, - sum_subset (s₁ := addAntidiagonal _ _ _) subset_union_right, + sum_subset (s₁ := antidiagonal _ _ _) subset_union_right, sum_eq_sum_iff_single (i := (a, x.order)), mul_left_inj' (coeff_order_eq_zero.not.2 hx)] · simp [hx] grind - · simp +contextual only [mem_union, mem_addAntidiagonal, mul_eq_mul_right_iff, Prod.mk.injEq, + · simp +contextual only [mem_union, mem_antidiagonal, mul_eq_mul_right_iff, Prod.mk.injEq, ne_eq, ← or_and_right, or_false, and_imp, Prod.forall, mem_support, not_and] rintro b c - hxb hbc hbc' contrapose! hbc' diff --git a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean index 0dec034a06063a..38e71a494b1d20 100644 --- a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean +++ b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean @@ -70,8 +70,8 @@ def toPowerSeries : R⟦ℕ⟧ ≃+* PowerSeries R where refine (sum_filter_ne_zero _).symm.trans <| (sum_congr ?_ fun _ _ ↦ rfl).trans <| sum_filter_ne_zero _ ext m - simp only [mem_antidiagonal, mem_addAntidiagonal, and_congr_left_iff, mem_filter, - mem_support] + simp only [HasAntidiagonal.mem_antidiagonal, Finset.mem_antidiagonal, and_congr_left_iff, + mem_filter, mem_support] rintro h rw [and_iff_right (left_ne_zero_of_mul h), and_iff_right (right_ne_zero_of_mul h)] @@ -169,8 +169,8 @@ def toMvPowerSeries {σ : Type*} [Finite σ] : R⟦σ →₀ ℕ⟧ ≃+* MvPowe refine (sum_filter_ne_zero _).symm.trans <| (sum_congr ?_ fun _ _ ↦ rfl).trans <| sum_filter_ne_zero _ ext m - simp only [and_congr_left_iff, mem_addAntidiagonal, mem_filter, mem_support, - Finset.mem_antidiagonal] + simp only [and_congr_left_iff, Finset.mem_antidiagonal, mem_filter, mem_support, + HasAntidiagonal.mem_antidiagonal] rintro h rw [and_iff_right (left_ne_zero_of_mul h), and_iff_right (right_ne_zero_of_mul h)] diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 022cf4cf2e1e47..7894e2b75bb025 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -555,7 +555,7 @@ theorem mul_eq_smul (s : SummableFamily Γ R α) (t : SummableFamily Γ R β) : rfl theorem coeff_hsum_mul (s : SummableFamily Γ R α) (t : SummableFamily Γ R β) (g : Γ) : - (mul s t).hsum.coeff g = ∑ gh ∈ addAntidiagonal s.isPWO_iUnion_support + (mul s t).hsum.coeff g = ∑ gh ∈ antidiagonal s.isPWO_iUnion_support t.isPWO_iUnion_support g, (s.hsum.coeff gh.1) * (t.hsum.coeff gh.2) := by simp_rw [← smul_eq_mul, mul_eq_smul] exact coeff_smul s t g @@ -694,17 +694,17 @@ theorem pow_finite_co_support {x : R⟦Γ⟧} (hx : 0 < x.orderTop) (g : Γ) : swap; · exact Set.finite_empty.subset fun n hn => hg (Set.mem_iUnion.2 ⟨n, hn⟩) apply hpwo.isWF.induction hg intro y ys hy - refine ((((addAntidiagonal x.isPWO_support hpwo y).finite_toSet.biUnion - fun ij hij => hy ij.snd (mem_addAntidiagonal.1 (mem_coe.1 hij)).2.1 ?_).image Nat.succ).union + refine ((((antidiagonal x.isPWO_support hpwo y).finite_toSet.biUnion + fun ij hij => hy ij.snd (mem_antidiagonal.1 (mem_coe.1 hij)).2.1 ?_).image Nat.succ).union (Set.finite_singleton 0)).subset ?_ - · obtain ⟨hi, _, rfl⟩ := mem_addAntidiagonal.1 (mem_coe.1 hij) + · obtain ⟨hi, _, rfl⟩ := mem_antidiagonal.1 (mem_coe.1 hij) exact lt_add_of_pos_left ij.2 <| lt_of_lt_of_le ((zero_lt_orderTop_iff h0).mp hx) <| order_le_of_coeff_ne_zero <| Function.mem_support.mp hi · rintro (_ | n) hn · exact Set.mem_union_right _ (Set.mem_singleton 0) · obtain ⟨i, hi, j, hj, rfl⟩ := support_mul_subset hn refine Set.mem_union_left _ ⟨n, Set.mem_iUnion.2 ⟨⟨j, i⟩, Set.mem_iUnion.2 ⟨?_, hi⟩⟩, rfl⟩ - simp only [mem_coe, mem_addAntidiagonal, mem_support, ne_eq, Set.mem_iUnion] + simp only [mem_coe, mem_antidiagonal, mem_support, ne_eq, Set.mem_iUnion] exact ⟨hj, ⟨n, hi⟩, add_comm j i⟩ /-- A summable family of powers of a Hahn series `x`. If `x` has non-positive `orderTop`, then diff --git a/Mathlib/RingTheory/MvPowerSeries/Basic.lean b/Mathlib/RingTheory/MvPowerSeries/Basic.lean index 9fc6b1497de12c..08e0614e76f1b0 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Basic.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Basic.lean @@ -234,8 +234,8 @@ theorem coeff_monomial_mul (a : R) : ∀ p ∈ antidiagonal m, coeff (p : (σ →₀ ℕ) × (σ →₀ ℕ)).1 (monomial n a) * coeff p.2 φ ≠ 0 → p.1 = n := fun p _ hp => eq_of_coeff_monomial_ne_zero (left_ne_zero_of_mul hp) - rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.filter_fst_eq_antidiagonal _ n, - Finset.sum_ite_index] + rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.HasAntidiagonal.filter_fst_eq_antidiagonal + _ n, Finset.sum_ite_index] simp only [Finset.sum_singleton, coeff_monomial_same, Finset.sum_empty] theorem coeff_mul_monomial (a : R) : @@ -245,8 +245,8 @@ theorem coeff_mul_monomial (a : R) : ∀ p ∈ antidiagonal m, coeff (p : (σ →₀ ℕ) × (σ →₀ ℕ)).1 φ * coeff p.2 (monomial n a) ≠ 0 → p.2 = n := fun p _ hp => eq_of_coeff_monomial_ne_zero (right_ne_zero_of_mul hp) - rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.filter_snd_eq_antidiagonal _ n, - Finset.sum_ite_index] + rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.HasAntidiagonal.filter_snd_eq_antidiagonal + _ n, Finset.sum_ite_index] simp only [Finset.sum_singleton, coeff_monomial_same, Finset.sum_empty] theorem coeff_add_monomial_mul (a : R) : diff --git a/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean b/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean index b74e68083b7fd5..c47f513096cff1 100644 --- a/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean @@ -61,13 +61,15 @@ noncomputable def basis (σ : Type*) (R : Type*) [Ring R] (Jd : TwoSidedIdeal R rw [coeff_mul] apply sum_mem rintro uv huv - exact TwoSidedIdeal.mul_mem_left _ _ _ (hg _ (le_trans (Finset.antidiagonal.snd_le huv) he))) + exact TwoSidedIdeal.mul_mem_left _ _ _ + (hg _ (le_trans (Finset.HasAntidiagonal.antidiagonal.snd_le huv) he))) (fun {f g} hf e he ↦ by classical rw [coeff_mul] apply sum_mem rintro uv huv - exact TwoSidedIdeal.mul_mem_right _ _ _ (hf _ (le_trans (Finset.antidiagonal.fst_le huv) he))) + exact TwoSidedIdeal.mul_mem_right _ _ _ + (hf _ (le_trans (Finset.HasAntidiagonal.antidiagonal.fst_le huv) he))) variable {σ : Type*} {R : Type*} [Ring R] diff --git a/Mathlib/RingTheory/PowerSeries/CoeffMulMem.lean b/Mathlib/RingTheory/PowerSeries/CoeffMulMem.lean index aa70f8948a49ca..cff3f91d0f39c4 100644 --- a/Mathlib/RingTheory/PowerSeries/CoeffMulMem.lean +++ b/Mathlib/RingTheory/PowerSeries/CoeffMulMem.lean @@ -45,8 +45,8 @@ theorem coeff_mul_mem_ideal_mul_ideal_of_coeff_mem_ideal (hf : ∀ i ≤ n, coef (hg : ∀ i ≤ n, coeff i g ∈ J) : ∀ i ≤ n, coeff i (f * g) ∈ I * J := fun i hi ↦ by rw [coeff_mul] exact Ideal.sum_mem _ fun p hp ↦ Ideal.mul_mem_mul - (hf _ ((Finset.antidiagonal.fst_le hp).trans hi)) - (hg _ ((Finset.antidiagonal.snd_le hp).trans hi)) + (hf _ ((Finset.HasAntidiagonal.antidiagonal.fst_le hp).trans hi)) + (hg _ ((Finset.HasAntidiagonal.antidiagonal.snd_le hp).trans hi)) theorem coeff_mul_mem_ideal_mul_ideal_of_coeff_mem_ideal' (hf : ∀ i, coeff i f ∈ I) (hg : ∀ i, coeff i g ∈ J) : ∀ i, coeff i (f * g) ∈ I * J := diff --git a/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean b/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean index a0dc12fa468ee4..ac4b409fb6d2a3 100644 --- a/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean +++ b/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean @@ -746,9 +746,9 @@ theorem IsWeierstrassDivision.isUnit_of_map_ne_zero · rw [coeff_of_lt_order p.1 ?_] · rw [zero_mul] · rw [← ENat.lt_lift_iff (h := order_finite_iff_ne_zero.2 hg), ENat.lift_eq_toNat_of_lt_top] - refine (Finset.antidiagonal.fst_le hp).lt_of_ne ?_ + refine (Finset.HasAntidiagonal.antidiagonal.fst_le hp).lt_of_ne ?_ contrapose hnotMem - rwa [Finset.mem_singleton, Finset.antidiagonal_congr hp (by simp)] + rwa [Finset.mem_singleton, Finset.HasAntidiagonal.antidiagonal_congr hp (by simp)] theorem IsWeierstrassDivision.isWeierstrassFactorization {g q : A⟦X⟧} {r : A[X]} (hg : g.map (IsLocalRing.residue A) ≠ 0) diff --git a/Mathlib/Tactic/Translate/ToAdditive.lean b/Mathlib/Tactic/Translate/ToAdditive.lean index bb007e638676af..0b1719bb2b5cd6 100644 --- a/Mathlib/Tactic/Translate/ToAdditive.lean +++ b/Mathlib/Tactic/Translate/ToAdditive.lean @@ -351,6 +351,7 @@ def abbreviationDict : Std.HashMap String String := .ofList [ ("le_zero", "Nonpos"), ("ltzero", "Neg"), ("lt_zero", "Neg"), + ("addAntidiagonal", "Antidiagonal"), ("addSingle", "Single"), ("addSupport", "Support"), ("addTSupport", "TSupport"), diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean b/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean index d806ef213421b3..e925b80f9c5ff0 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean @@ -214,7 +214,7 @@ variable [TopologicalSpace α] [NonUnitalNonAssocSemiring α] {f g : A → α} theorem summable_mul_prod_iff_summable_mul_sigma_antidiagonal : (Summable fun x : A × A ↦ f x.1 * g x.2) ↔ Summable fun x : Σ n : A, antidiagonal n ↦ f (x.2 : A × A).1 * g (x.2 : A × A).2 := - Finset.sigmaAntidiagonalEquivProd.summable_iff.symm + Finset.HasAntidiagonal.sigmaAntidiagonalEquivProd.summable_iff.symm variable [T3Space α] [IsTopologicalSemiring α] @@ -226,7 +226,7 @@ theorem summable_sum_mul_antidiagonal_of_summable_mul exact h.sigma' fun n ↦ (hasSum_fintype _).summable /-- The **Cauchy product formula** for the product of two infinite sums indexed by `ℕ`, expressed -by summing on `Finset.antidiagonal`. +by summing on `Finset.HasAntidiagonal.antidiagonal`. See also `tsum_mul_tsum_eq_tsum_sum_antidiagonal_of_summable_norm` if `f` and `g` are absolutely summable. -/ @@ -234,7 +234,7 @@ protected theorem Summable.tsum_mul_tsum_eq_tsum_sum_antidiagonal (hf : Summable (hg : Summable g) (hfg : Summable fun x : A × A ↦ f x.1 * g x.2) : ((∑' n, f n) * ∑' n, g n) = ∑' n, ∑ kl ∈ antidiagonal n, f kl.1 * g kl.2 := by conv_rhs => congr; ext; rw [← Finset.sum_finset_coe, ← tsum_fintype (L := .unconditional _)] - rw [hf.tsum_mul_tsum hg hfg, ← sigmaAntidiagonalEquivProd.tsum_eq (_ : A × A → α)] + rw [hf.tsum_mul_tsum hg hfg, ← HasAntidiagonal.sigmaAntidiagonalEquivProd.tsum_eq (_ : A × A → α)] exact (summable_mul_prod_iff_summable_mul_sigma_antidiagonal.mp hfg).tsum_sigma' (fun n ↦ (hasSum_fintype _).summable) From e7c715d39466d958a1b956dad3072a8dce6b37a3 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:06:44 +0000 Subject: [PATCH 0366/1300] chore: fix non-reducible diamond in `StarRingEnd` (#41047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following fails before the PR, works after it ``` example : starRingEnd ℝ = RingHom.id ℝ := by with_reducible_and_instances rfl ``` Co-authored-by: sgouezel --- Mathlib/Algebra/Star/Basic.lean | 16 +++++++++++----- Mathlib/Analysis/CStarAlgebra/Basic.lean | 3 +-- Mathlib/NumberTheory/MulChar/Lemmas.lean | 5 ++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Star/Basic.lean b/Mathlib/Algebra/Star/Basic.lean index f37f1dc5d07931..c109f8adb81226 100644 --- a/Mathlib/Algebra/Star/Basic.lean +++ b/Mathlib/Algebra/Star/Basic.lean @@ -94,8 +94,10 @@ theorem star_inj [InvolutiveStar R] {x y : R} : star x = star y ↔ x = y := /-- `star` as an equivalence when it is involutive. -/ @[simps! apply] -protected def Equiv.Perm.star [InvolutiveStar R] : Equiv.Perm R := - star_involutive.toPerm _ +protected def Equiv.Perm.star [InvolutiveStar R] : Equiv.Perm R where + toFun := star + invFun := star + __ : Equiv.Perm R := star_involutive.toPerm _ @[simp] theorem Equiv.Perm.symm_star [InvolutiveStar R] : @@ -213,7 +215,7 @@ theorem star_div [CommGroup R] [StarMul R] (x y : R) : star (x / y) = star x / s See note [reducible non-instances]. -/ abbrev starMulOfComm {R : Type*} [CommMonoid R] : StarMul R where - star := id + star x := x star_involutive _ := rfl star_mul := mul_comm @@ -324,7 +326,8 @@ variable [CommSemiring R] [StarRing R] /-- `star` as a ring automorphism, for commutative `R`. -/ @[simps apply] -def starRingAut : RingAut R := { starAddEquiv, starMulAut (R := R) with toFun := star } +def starRingAut : RingAut R := + { starAddEquiv, starMulAut (R := R) with toFun := star, invFun := star } variable (R) in /-- `star` as a ring endomorphism, for commutative `R`. This is used to denote complex @@ -334,7 +337,10 @@ Note that this is the preferred form (over `starRingAut`, available under the sa because the notation `E →ₗ⋆[R] F` for an `R`-conjugate-linear map (short for `E →ₛₗ[starRingEnd R] F`) does not pretty-print if there is a coercion involved, as would be the case for `(↑starRingAut : R →* R)`. -/ -def starRingEnd : R →+* R := @starRingAut R _ _ +@[implicit_reducible] +def starRingEnd : R →+* R where + toFun := star + __ := (@starRingAut R _ _).toRingHom @[inherit_doc] scoped[ComplexConjugate] notation "conj" => starRingEnd _ diff --git a/Mathlib/Analysis/CStarAlgebra/Basic.lean b/Mathlib/Analysis/CStarAlgebra/Basic.lean index d8a77466ce59d5..59c88f4ea228c1 100644 --- a/Mathlib/Analysis/CStarAlgebra/Basic.lean +++ b/Mathlib/Analysis/CStarAlgebra/Basic.lean @@ -90,8 +90,7 @@ class CStarRing (E : Type*) [NonUnitalNormedRing E] [StarRing E] : Prop where norm_mul_self_le : ∀ x : E, ‖x‖ * ‖x‖ ≤ ‖x⋆ * x‖ instance : CStarRing ℝ where - norm_mul_self_le x := by - simp only [Real.norm_eq_abs, abs_mul_abs_self, star, id, norm_mul, le_refl] + norm_mul_self_le x := by simp namespace CStarRing diff --git a/Mathlib/NumberTheory/MulChar/Lemmas.lean b/Mathlib/NumberTheory/MulChar/Lemmas.lean index 1f2af16ecf0116..a12ad1c2c010eb 100644 --- a/Mathlib/NumberTheory/MulChar/Lemmas.lean +++ b/Mathlib/NumberTheory/MulChar/Lemmas.lean @@ -51,11 +51,10 @@ instance instStarMul [StarRing R'] : StarMul (MulChar R R') where star := starComp star_involutive χ := by ext1 - simp only [starComp_apply, RingHomCompTriple.comp_apply, RingHom.id_apply] + simp [starComp_apply] star_mul χ χ' := by ext1 - simp only [starComp_apply, starRingEnd, coeToFun_mul, Pi.mul_apply, map_mul, RingHom.coe_coe, - starRingAut_apply, mul_comm] + simp [starComp_apply, mul_comm] @[simp] lemma star_apply [StarRing R'] (χ : MulChar R R') (a : R) : (star χ) a = star (χ a) := From f50308756c78c29d5a859b850967def7b94b7c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 25 Jun 2026 20:10:56 +0000 Subject: [PATCH 0367/1300] feat(CategoryTheory/Localization): small additions (#40884) This PR adds a few properties about localization with respect to isomorphisms. The lemma `LocalizerMorphism.Derives.isIso` is renamed `isIso_of_isRightDerivedFunctor`, because we shall need the dual lemma in the future. --- .../Localization/DerivabilityStructure/Derives.lean | 8 +++++--- .../CategoryTheory/Localization/LocalizerMorphism.lean | 3 +++ Mathlib/CategoryTheory/Localization/Predicate.lean | 3 +++ Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean | 5 +++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean index 1944773a64883d..a9539a1d84d6dc 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean @@ -65,7 +65,7 @@ section variable {L₂ : C₂ ⥤ D₂} [L₂.IsLocalization W₂] {RF : D₂ ⥤ H} (α : F ⟶ L₂ ⋙ RF) -lemma isIso (X₁ : C₁) [RF.IsRightDerivedFunctor α W₂] : +lemma isIso_of_isRightDerivedFunctor (X₁ : C₁) [RF.IsRightDerivedFunctor α W₂] : IsIso (α.app (Φ.functor.obj X₁)) := by let G : W₁.Localization ⥤ H := Localization.lift (Φ.functor ⋙ F) h W₁.Q let eG := Localization.Lifting.iso W₁.Q W₁ (Φ.functor ⋙ F) G @@ -74,12 +74,14 @@ lemma isIso (X₁ : C₁) [RF.IsRightDerivedFunctor α W₂] : rw [← Φ.isIso_iff_of_isRightDerivabilityStructure W₁.Q L₂ F G eG.inv RF α] infer_instance +@[deprecated (since := "2026-06-22")] alias isIso := isIso_of_isRightDerivedFunctor + set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in lemma isRightDerivedFunctor_of_isIso (hα : ∀ (X₁ : C₁), IsIso (α.app (Φ.functor.obj X₁))) : RF.IsRightDerivedFunctor α W₂ := by have := h.hasPointwiseRightDerivedFunctor - have := h.isIso (F.totalRightDerivedUnit L₂ W₂) + have := h.isIso_of_isRightDerivedFunctor (F.totalRightDerivedUnit L₂ W₂) have := Φ.essSurj_of_hasRightResolutions L₂ let φ := (F.totalRightDerived L₂ W₂).rightDerivedDesc (F.totalRightDerivedUnit L₂ W₂) W₂ RF α have hφ : F.totalRightDerivedUnit L₂ W₂ ≫ Functor.whiskerLeft L₂ φ = α := @@ -97,7 +99,7 @@ lemma isRightDerivedFunctor_of_isIso (hα : ∀ (X₁ : C₁), IsIso (α.app (Φ lemma isRightDerivedFunctor_iff_isIso : RF.IsRightDerivedFunctor α W₂ ↔ ∀ (X₁ : C₁), IsIso (α.app (Φ.functor.obj X₁)) := - ⟨fun _ _ ↦ h.isIso α _, h.isRightDerivedFunctor_of_isIso α⟩ + ⟨fun _ _ ↦ h.isIso_of_isRightDerivedFunctor α _, h.isRightDerivedFunctor_of_isIso α⟩ end diff --git a/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean b/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean index d69534f721a440..2be304d60b9ec4 100644 --- a/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean +++ b/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean @@ -64,6 +64,9 @@ def id : LocalizerMorphism W₁ W₁ where functor := 𝟭 C₁ map _ _ _ hf := hf +instance : (id W₁).functor.IsEquivalence := + inferInstanceAs (𝟭 C₁).IsEquivalence + variable {W₁ W₂ W₃} /-- The composition of two localizers morphisms. -/ diff --git a/Mathlib/CategoryTheory/Localization/Predicate.lean b/Mathlib/CategoryTheory/Localization/Predicate.lean index 28242d1d57c21d..c882cb52d75bcb 100644 --- a/Mathlib/CategoryTheory/Localization/Predicate.lean +++ b/Mathlib/CategoryTheory/Localization/Predicate.lean @@ -127,6 +127,9 @@ theorem IsLocalization.for_id (hW : W ≤ MorphismProperty.isomorphisms C) : ( IsLocalization.mk' _ _ (Localization.strictUniversalPropertyFixedTargetId W _ hW) (Localization.strictUniversalPropertyFixedTargetId W _ hW) +instance : (𝟭 C).IsLocalization (MorphismProperty.isomorphisms C) := + IsLocalization.for_id _ (by rfl) + end Functor namespace Localization diff --git a/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean b/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean index 8c5678c5a04da0..2f3a35a8d1f94f 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean @@ -173,6 +173,11 @@ lemma IsInvertedBy.map_iff {C₁ C₂ C₃ : Type*} [Category* C₁] [Category* (W.map F).IsInvertedBy G ↔ W.IsInvertedBy (F ⋙ G) := by simp only [IsInvertedBy.iff_map_le_isomorphisms, map_map] +lemma isInvertedBy_isomorphisms (F : C ⥤ D) : (isomorphisms C).IsInvertedBy F := by + intro _ _ _ hf + simp only [isomorphisms.iff] at hf + infer_instance + end MorphismProperty end CategoryTheory From 81bc6062d7bebe880f7a60d8f6ccaf474e7c29c0 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Thu, 25 Jun 2026 20:24:28 +0000 Subject: [PATCH 0368/1300] feat(Logic/Function/Defs): Add dcomp lemmas (#39195) This PR adds API lemmas about `dcomp` that were previously missing. --- Mathlib/Logic/Function/Defs.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Logic/Function/Defs.lean b/Mathlib/Logic/Function/Defs.lean index 04b9b63554da8d..3208b2496fc569 100644 --- a/Mathlib/Logic/Function/Defs.lean +++ b/Mathlib/Logic/Function/Defs.lean @@ -31,6 +31,19 @@ def dcomp {β : α → Sort u₂} {φ : ∀ {x : α}, β x → Sort u₃} (f : @[inherit_doc] infixr:80 " ∘' " => Function.dcomp +section DComp + +variable {ι} {β : ι → Sort*} {φ : ∀ {i : ι}, β i → Sort*} (f : ∀ {i : ι} (y : β i), φ y) + (g : ∀ i, β i) (i : ι) + +theorem dcomp_def : @f ∘' g = fun i => f (g i) := rfl + +theorem dcomp_apply : dcomp @f g i = f (g i) := rfl + +@[simp] theorem dcomp_eq_comp {α β γ} (f : β → γ) (g : α → β) : f ∘' g = f ∘ g := rfl + +end DComp + /-- Product of functions: `Function.prod f g i = (f i, g i)`, where the types of `f i` and `g i` may depend on `i`. -/ protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : From 737969ff4c952612b17c953921eeecfb8d6df26c Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Thu, 25 Jun 2026 20:24:31 +0000 Subject: [PATCH 0369/1300] feat: PiLp.equivOfUnique (#40634) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the isomorphism between `PiLp` over any `Unique` index type and the corresponding individual type. Generalise `PiLp.linearEquiv` to topological vector spaces, then this is straightforward. This will be used in #29077, to yield an equivalence `EuclideanSpace 𝕜 (Fin 1) ≃L[𝕜] 𝕜`. --- Mathlib/Analysis/Normed/Lp/PiLp.lean | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 5bc4fbdc2b7368..7da73c0fdbdcec 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -1129,13 +1129,13 @@ end Fintype section -variable [Semiring 𝕜] [∀ i, SeminormedAddCommGroup (β i)] [∀ i, Module 𝕜 (β i)] +variable [Semiring 𝕜] [∀ i, AddCommGroup (β i)] [∀ i, Module 𝕜 (β i)] [∀ i, TopologicalSpace (β i)] -set_option backward.defeqAttrib.useBackward true in /-- `WithLp.linearEquiv` as a continuous linear equivalence. -/ @[simps! apply symm_apply] def continuousLinearEquiv : PiLp p β ≃L[𝕜] ∀ i, β i where toLinearEquiv := WithLp.linearEquiv _ _ _ + continuous_invFun := (by fun_prop : Continuous fun (a : Π i, β i) ↦ toLp p a) lemma coe_continuousLinearEquiv : ⇑(PiLp.continuousLinearEquiv p 𝕜 β) = ofLp := rfl @@ -1143,6 +1143,18 @@ lemma coe_continuousLinearEquiv : lemma coe_symm_continuousLinearEquiv : ⇑(PiLp.continuousLinearEquiv p 𝕜 β).symm = toLp p := rfl +/-- The natural equivalence between `PiLp p β` and `β default`, +for any index type `ι` with a unique element. -/ +@[simps! apply symm_apply] +def equivOfUnique [Unique ι] : PiLp p β ≃L[𝕜] β default := + (continuousLinearEquiv p 𝕜 β).trans <| .piUnique 𝕜 β + +end + +section + +variable [Semiring 𝕜] [∀ i, NormedAddCommGroup (β i)] [∀ i, Module 𝕜 (β i)] + variable {𝕜} in /-- The projection on the `i`-th coordinate of `PiLp p β`, as a continuous linear map. -/ @[simps!] From 99d6cda6e33df5cb5ef77971cd7997a4e15e0a25 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Thu, 25 Jun 2026 20:24:33 +0000 Subject: [PATCH 0370/1300] fix: correct deprecation for `orthogonalProjection_mem_subspace_orthogonalComplement_eq_zero` (#40722) #38970 tried to create one, but made a slip (and created a deprecated alias for a declaration that never existed). Correct this oversight. Noticed during leanprover-community/sphere-eversion#143. --- Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean index 95e52bd3f93f08..09797f0b3d9bc8 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean @@ -434,7 +434,8 @@ theorem orthogonalProjectionOnto_apply_of_mem_orthogonal [K.HasOrthogonalProjection] {v : E} (hv : v ∈ Kᗮ) : K.orthogonalProjectionOnto v = 0 := orthogonalProjectionOnto_eq_zero_iff.mpr hv -@[deprecated (since := "2026-05-06")] alias orthogonalProjection_apply_of_mem_orthogonal := +@[deprecated (since := "2026-05-06")] alias +orthogonalProjection_mem_subspace_orthogonalComplement_eq_zero := orthogonalProjectionOnto_apply_of_mem_orthogonal /-- The projection into `U` from an orthogonal submodule `V` is the zero map. -/ From 3afead49a87418666bb06b2814383a1eaa2f878d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 25 Jun 2026 21:17:52 +0000 Subject: [PATCH 0371/1300] feat(Algebra/Homology): the injective derivability structure (#41000) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let `C` be an abelian category with enough injectives. In this file, we define a localizer morphism `CochainComplex.Plus.localizerMorphism` (relatively to quasi-isomorphisms) which is given by the (fully faithful) functor `CochainComplex.Plus (InjectiveObject C) ⥤ CochainComplex.Plus C`, and we show that it is a right derivability structure in the sense of Kahn and Maltsiniotis. (The proof proceeds by showing that up to equivalences of categories, this functor is the inclusion of the full subcategory of fibrant objects in the model category `CochainComplex.Plus C`.) --- Mathlib.lean | 2 + .../DerivabilityStructureInjectives.lean | 121 ++++++++++++++++++ .../CategoryWithCofibrations.lean | 4 + .../Injective/InjectiveObject.lean | 60 +++++++++ 4 files changed, 187 insertions(+) create mode 100644 Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean create mode 100644 Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean diff --git a/Mathlib.lean b/Mathlib.lean index f892e89c8d8f8e..32975106c2b8df 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -573,6 +573,7 @@ public import Mathlib.Algebra.Homology.ComplexShape public import Mathlib.Algebra.Homology.ComplexShapeSigns public import Mathlib.Algebra.Homology.ConcreteCategory public import Mathlib.Algebra.Homology.DerivedCategory.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.DerivabilityStructureInjectives public import Mathlib.Algebra.Homology.DerivedCategory.ExactFunctor public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic public import Mathlib.Algebra.Homology.DerivedCategory.Ext.EnoughInjectives @@ -3238,6 +3239,7 @@ public import Mathlib.CategoryTheory.Preadditive.FunctorCategory public import Mathlib.CategoryTheory.Preadditive.HomOrthogonal public import Mathlib.CategoryTheory.Preadditive.Indization public import Mathlib.CategoryTheory.Preadditive.Injective.Basic +public import Mathlib.CategoryTheory.Preadditive.Injective.InjectiveObject public import Mathlib.CategoryTheory.Preadditive.Injective.LiftingProperties public import Mathlib.CategoryTheory.Preadditive.Injective.Preserves public import Mathlib.CategoryTheory.Preadditive.Injective.Resolution diff --git a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean new file mode 100644 index 00000000000000..4d93315312b95a --- /dev/null +++ b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean @@ -0,0 +1,121 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.FullSubcategory +public import Mathlib.Algebra.Homology.ModelCategory.Injective +public import Mathlib.AlgebraicTopology.ModelCategory.DerivabilityStructureFibrant +public import Mathlib.CategoryTheory.Localization.DerivabilityStructure.OfLocalizedEquivalences +public import Mathlib.CategoryTheory.Preadditive.Injective.InjectiveObject + +/-! +# The injective derivability structure + +Let `C` be an abelian category with enough injectives. +In this file, we define a localizer morphism `CochainComplex.Plus.localizerMorphism` +(relative to quasi-isomorphisms) which is given by the (fully faithful) functor +`CochainComplex.Plus (InjectiveObject C) ⥤ CochainComplex.Plus C`, and we show +that it is a right derivability structure. (The proof proceeds by showing that +up to equivalences of categories, this functor is the inclusion of the full +subcategory of fibrant objects in the model category `CochainComplex.Plus C`.) + +TODO(@joelriou): obtain similar results for the bounded below homotopy category. + +-/ + +@[expose] public section + +open HomotopicalAlgebra CategoryTheory Limits ZeroObject Category + +variable (C : Type*) [Category* C] [Abelian C] + +namespace CochainComplex.Plus + +/-- The localizer morphism (relative to quasi-isomorphisms) that is +given by the "inclusion functor" +`CochainComplex.Plus (InjectiveObject C) ⥤ CochainComplex.Plus C`. -/ +@[simps] +def localizerMorphism : + LocalizerMorphism ((quasiIso C).inverseImage (InjectiveObject.ι C).mapCochainComplexPlus) + (quasiIso C) where + functor := (InjectiveObject.ι C).mapCochainComplexPlus + map := by rfl + +instance : (localizerMorphism C).IsInduced where + inverseImage_eq := rfl + +instance (K : Plus (InjectiveObject C)) (n : ℤ) : + Injective (K.obj.X n).obj := + (K.obj.X n).property + +variable [EnoughInjectives C] + +open modelCategoryQuillen + +instance (K : FibrantObject (Plus C)) (n : ℤ) : + Injective (K.obj.obj.X n) := by + obtain ⟨K, hK⟩ := K + rw [fibrantObjects, modelCategoryQuillen.isFibrant_iff] at hK + dsimp + infer_instance + +set_option backward.defeqAttrib.useBackward true in +/-- The equivalence between `CochainComplex.Plus (InjectiveObject C)` +and the category of fibrant object in `CochainComplex.Plus C` for the +Quillen model category structure. -/ +def fibrantObjectEquivalence : + Plus (InjectiveObject C) ≌ FibrantObject (Plus C) where + functor := ObjectProperty.lift _ (InjectiveObject.ι C).mapCochainComplexPlus (fun K ↦ by + dsimp [fibrantObjects] + rw [modelCategoryQuillen.isFibrant_iff] + intro n + dsimp + infer_instance) + inverse := ObjectProperty.lift _ + (HomologicalComplex.liftFunctorObjectProperty _ (FibrantObject.ι ⋙ Plus.ι C) + (fun K n ↦ by dsimp; infer_instance)) (by + rintro ⟨⟨K, n, hn⟩, _⟩ + refine ⟨n, ?_⟩ + rw [isStrictlyGE_iff] + intro i hi + rw [IsZero.iff_id_eq_zero] + ext + apply (K.isZero_of_isStrictlyGE n i hi).eq_of_tgt) + unitIso := Iso.refl _ + counitIso := Iso.refl _ + +/-- The localizer morphism (relative to quasi-isomorphisms) that is +given by the equivalence of categories +`CochainComplex.Plus (InjectiveObject C) ≌ FibrantObject (CochainComplex.Plus C)`. -/ +@[simps] +def fibrantObjectLocalizerMorphism : + LocalizerMorphism ((quasiIso C).inverseImage (InjectiveObject.ι C).mapCochainComplexPlus) + (weakEquivalences (FibrantObject (Plus C))) where + functor := (fibrantObjectEquivalence C).functor + map := by rfl + +instance : (fibrantObjectLocalizerMorphism C).IsInduced where + inverseImage_eq := rfl + +set_option backward.defeqAttrib.useBackward true in +instance : (fibrantObjectLocalizerMorphism C).functor.IsEquivalence := by + dsimp; infer_instance + +set_option backward.isDefEq.respectTransparency false in +instance : (localizerMorphism C).IsRightDerivabilityStructure := by + rw [LocalizerMorphism.isRightDerivabilityStructure_iff_of_equivalences + (T := localizerMorphism C) (B := FibrantObject.localizerMorphism (Plus C)) + (R := .id _) (L := fibrantObjectLocalizerMorphism C) (Iso.refl _)] + infer_instance + +set_option backward.isDefEq.respectTransparency false in +instance : (localizerMorphism C).arrow.HasRightResolutions := by + rw [LocalizerMorphism.hasRightResolutions_arrow_iff_of_equivalences + (T := localizerMorphism C) (B := FibrantObject.localizerMorphism (Plus C)) + (R := .id _) (L := fibrantObjectLocalizerMorphism C) (Iso.refl _)] + infer_instance + +end CochainComplex.Plus diff --git a/Mathlib/AlgebraicTopology/ModelCategory/CategoryWithCofibrations.lean b/Mathlib/AlgebraicTopology/ModelCategory/CategoryWithCofibrations.lean index b088b3d15ccb4b..bd654074d1fbd5 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/CategoryWithCofibrations.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/CategoryWithCofibrations.lean @@ -267,6 +267,10 @@ instance [(weakEquivalences C).IsMultiplicative] : (weakEquivalences P.FullSubcategory).IsMultiplicative := inferInstanceAs ((weakEquivalences C).inverseImage P.ι).IsMultiplicative +instance [(weakEquivalences C).RespectsIso] : + (weakEquivalences P.FullSubcategory).RespectsIso := + inferInstanceAs ((weakEquivalences C).inverseImage P.ι).RespectsIso + lemma weakEquivalence_iff_of_objectProperty {X Y : P.FullSubcategory} (f : X ⟶ Y) : WeakEquivalence f ↔ WeakEquivalence f.hom := by diff --git a/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean b/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean new file mode 100644 index 00000000000000..ddbe6ccb6f79dd --- /dev/null +++ b/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean @@ -0,0 +1,60 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.Limits.FullSubcategory +public import Mathlib.CategoryTheory.Preadditive.Biproducts +public import Mathlib.CategoryTheory.Preadditive.Injective.Basic + +/-! +# The full subcategory of injective objects + +-/ + +@[expose] public section + +universe v u + +namespace CategoryTheory + +open Limits ZeroObject + +variable (C : Type u) [Category.{v} C] + +/-- The full subcategory of injective objects in a category `C`. -/ +abbrev InjectiveObject : Type u := ObjectProperty.FullSubcategory (isInjective C) + +namespace InjectiveObject + +instance (J : Type*) : + ObjectProperty.IsClosedUnderLimitsOfShape (isInjective C) (Discrete J) where + limitsOfShape_le := by + rintro Y ⟨p⟩ + have (j : J) : Injective (p.diag.obj ⟨j⟩) := p.prop_diag_obj _ + exact ⟨fun q i _ ↦ ⟨p.isLimit.lift (Cone.mk _ + (Discrete.natTrans (fun ⟨j⟩ ↦ (Injective.factorThru (q ≫ p.π.app ⟨j⟩) i :)))), + p.isLimit.hom_ext (fun ⟨j⟩ ↦ by simp [p.isLimit.fac])⟩⟩ + +instance [HasFiniteProducts C] : HasFiniteProducts (InjectiveObject C) where + out _ := inferInstance + +instance [Preadditive C] [HasFiniteProducts C] : HasFiniteBiproducts (InjectiveObject C) := + HasFiniteBiproducts.of_hasFiniteProducts + +instance [HasZeroMorphisms C] [HasZeroObject C] : (isInjective C).ContainsZero where + exists_zero := ⟨0, by simp [IsZero.iff_id_eq_zero], Injective.zero_injective⟩ + +/-- The inclusion `InjectiveObject C ⥤ C` of the full subcategory of +injective objects in `C`. -/ +abbrev ι : InjectiveObject C ⥤ C := ObjectProperty.ι _ + +instance (X : InjectiveObject C) : Injective ((ι C).obj X) := X.2 + +instance (X : InjectiveObject C) : Injective X.obj := X.2 + +end InjectiveObject + +end CategoryTheory From 11b908e5cdd941b2d54b1b2ab55d069f5d8281d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Renison?= <85908989+IvanRenison@users.noreply.github.com> Date: Thu, 25 Jun 2026 22:37:49 +0000 Subject: [PATCH 0372/1300] feat(Combinatorics/SimpleGraph/Girth): add lemma `Walk.IsCircuit.egirth_le_length` (#37578) Co-authored-by: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> --- Mathlib/Combinatorics/SimpleGraph/Girth.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Girth.lean b/Mathlib/Combinatorics/SimpleGraph/Girth.lean index 13b8b3f6dfd40e..409d1ea7b00153 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Girth.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Girth.lean @@ -43,6 +43,17 @@ lemma le_egirth {n : ℕ∞} : n ≤ G.egirth ↔ ∀ a (w : G.Walk a a), w.IsCy lemma egirth_le_length {a} {w : G.Walk a a} (h : w.IsCycle) : G.egirth ≤ w.length := le_egirth.mp le_rfl a w h +lemma Walk.IsCircuit.egirth_le_length {a} {w : G.Walk a a} (hwc : w.IsCircuit) : + G.egirth ≤ w.length := by + classical + by_contra! hlg + let w' : G.Walk a a := w.cycleBypass + have hwc' : w'.IsCycle := hwc.isCycle_cycleBypass + have hwlg' : w'.length < G.egirth := by + grw [w.length_cycleBypass_le_length] + exact hlg + exact not_le_of_gt hwlg' (SimpleGraph.egirth_le_length hwc') + @[simp] lemma egirth_eq_top : G.egirth = ⊤ ↔ G.IsAcyclic := by simp [egirth, IsAcyclic] @@ -104,6 +115,10 @@ protected alias ⟨_, IsAcyclic.girth_eq_zero⟩ := girth_eq_zero lemma girth_anti {G' : SimpleGraph α} (hab : G ≤ G') (h : ¬ G.IsAcyclic) : G'.girth ≤ G.girth := ENat.toNat_le_toNat (egirth_anti hab) <| egirth_eq_top.not.mpr h +lemma Walk.IsCircuit.girth_le_length {a} {w : G.Walk a a} (hwc : w.IsCircuit) : + G.girth ≤ w.length := + ENat.coe_le_coe.mp <| G.egirth.coe_toNat_le_self.trans <| hwc.egirth_le_length + lemma exists_girth_eq_length : (∃ (a : α) (w : G.Walk a a), w.IsCycle ∧ G.girth = w.length) ↔ ¬ G.IsAcyclic := by refine ⟨by tauto, fun h ↦ ?_⟩ From 490fac787fde80783e0ce38d133a20cf0e039ec9 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Fri, 26 Jun 2026 07:58:21 +0000 Subject: [PATCH 0373/1300] feat(RepresentationTheory/Homological): add more APIs to groupCohomology and groupHomology (#40714) This is another upstreaming PR originated from the [CFT](https://github.com/kbuzzard/ClassFieldTheory) repo, it's a collaborative work from 2025 Clay Summer School on Formalizing Class Field Theory. --- .../GroupCohomology/Functoriality.lean | 27 +++++++++++++++++++ .../GroupHomology/Functoriality.lean | 27 +++++++++++++++++++ Mathlib/RepresentationTheory/Rep/Res.lean | 2 ++ 3 files changed, 56 insertions(+) diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean index fb27295e645d1f..a4845a06718d8c 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean @@ -112,6 +112,11 @@ noncomputable abbrev cocyclesMap (n : ℕ) : groupCohomology.cocycles A n ⟶ groupCohomology.cocycles B n := HomologicalComplex.cyclesMap (cochainsMap f φ) n +lemma cochainsMap_congr {f g : G →* H} {φ : res f A ⟶ B} {ψ : res g A ⟶ B} (hfg : f = g) + (hφψ : φ.hom.toLinearMap = ψ.hom.toLinearMap) : + cochainsMap f φ = cochainsMap g ψ := by + subst hfg; congr; ext; simp [hφψ] + @[simp] lemma cocyclesMap_id : cocyclesMap (MonoidHom.id G) (𝟙 B) n = 𝟙 _ := HomologicalComplex.cyclesMap_id _ _ @@ -137,6 +142,11 @@ noncomputable abbrev map (n : ℕ) : groupCohomology A n ⟶ groupCohomology B n := HomologicalComplex.homologyMap (cochainsMap f φ) n +lemma map_congr {f g : G →* H} {φ : res f A ⟶ B} {ψ : res g A ⟶ B} (hfg : f = g) + (hφψ : φ.hom.toLinearMap = ψ.hom.toLinearMap) (n : ℕ) : + map f φ n = map g ψ n := by + subst hfg; congr; ext; simp [hφψ] + set_option backward.isDefEq.respectTransparency false in @[reassoc, elementwise] theorem π_map (n : ℕ) : @@ -161,6 +171,23 @@ theorem map_id_comp {A B C : Rep k G} (φ : A ⟶ B) (ψ : B ⟶ C) (n : ℕ) : map (MonoidHom.id G) φ n ≫ map (MonoidHom.id G) ψ n := by rw [map, cochainsMap_id_comp, HomologicalComplex.homologyMap_comp] +/-- The isomorphism between cohomology groups induced by a group isomorphism `e : G ≃* H` and a +isomorphism between representations (restricted by `e`). -/ +@[simps] +noncomputable def mapIso (e : G ≃* H) (e' : B.V ≃ₗ[k] A.V) + (he : ∀ g, e' ∘ₗ B.ρ g = A.ρ (e g) ∘ₗ e') (n : ℕ) : + groupCohomology B n ≅ groupCohomology A n where + hom := groupCohomology.map e.symm (ofHom ⟨e', fun h ↦ by simp [he]⟩) n + inv := groupCohomology.map e (ofHom ⟨e'.symm, fun g ↦ by + rw [e'.toLinearMap_symm_comp_eq, ← LinearMap.comp_assoc] + simp [he, LinearMap.comp_assoc]⟩) n + hom_inv_id := by + rw [← groupCohomology.map_comp, ← groupCohomology.map_id] + exact map_congr (by simp) (by simp [res_id]) n + inv_hom_id := by + rw [← groupCohomology.map_comp, ← groupCohomology.map_id] + exact groupCohomology.map_congr (by simp) e'.comp_symm n + /-- Given a group homomorphism `f : G →* H` and a representation morphism `φ : Res(f)(A) ⟶ B`, this is the induced map sending `x : H → A` to `(g : G) ↦ φ (x (f g))`. -/ noncomputable abbrev cochainsMap₁ : diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean index 12df1c5618ad2b..f63037ce882e3d 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean @@ -64,6 +64,11 @@ noncomputable def chainsMap : simp [Fin.comp_contractNth, map_add, inhomogeneousChains.d, Rep.hom_comm_apply φ] rfl +lemma chainsMap_congr {f g : G →* H} {φ : A ⟶ res f B} {ψ : A ⟶ res g B} (hfg : f = g) + (hφψ : φ.hom.toLinearMap = ψ.hom.toLinearMap) : + chainsMap f φ = chainsMap g ψ := by + subst hfg; congr; ext; simp [hφψ] + @[reassoc (attr := simp)] lemma lsingle_comp_chainsMap_f (n : ℕ) (x : Fin n → G) : ModuleCat.ofHom (lsingle x) ≫ (chainsMap f φ).f n = @@ -153,6 +158,11 @@ noncomputable abbrev map (n : ℕ) : groupHomology A n ⟶ groupHomology B n := HomologicalComplex.homologyMap (chainsMap f φ) n +lemma map_congr {f g : G →* H} {φ : A ⟶ res f B} {ψ : A ⟶ res g B} (hfg : f = g) + (hφψ : φ.hom.toLinearMap = ψ.hom.toLinearMap) (n : ℕ) : + map f φ n = map g ψ n := by + subst hfg; congr; ext; simp [hφψ] + set_option backward.isDefEq.respectTransparency false in @[reassoc, elementwise] theorem π_map (n : ℕ) : @@ -177,6 +187,23 @@ theorem map_id_comp {A B C : Rep k G} (φ : A ⟶ B) (ψ : B ⟶ C) (n : ℕ) : map (MonoidHom.id G) φ n ≫ map (MonoidHom.id G) ψ n := by rw [map, chainsMap_id_comp, HomologicalComplex.homologyMap_comp] +/-- The isomorphism between homology groups induced by a group isomorphism `e : G ≃* H` and a +isomorphism between representations (restricted by `e`). -/ +@[simps] +noncomputable def mapIso (e : G ≃* H) (e' : A.V ≃ₗ[k] B.V) + (he : ∀ g, e' ∘ₗ A.ρ g = B.ρ (e g) ∘ₗ e') (n : ℕ) : + groupHomology A n ≅ groupHomology B n where + hom := groupHomology.map (A := A) e (ofHom ⟨e', by simp [he]⟩) n + inv := groupHomology.map (A := B) e.symm (ofHom ⟨e'.symm, fun h ↦ by + rw [LinearEquiv.toLinearMap_symm_comp_eq, ← LinearMap.comp_assoc] + simp [he, LinearMap.comp_assoc]⟩) n + hom_inv_id := by + rw [← groupHomology.map_comp, ← groupHomology.map_id] + exact groupHomology.map_congr e.coe_monoidHom_symm_comp_coe_monoidHom e'.symm_comp n + inv_hom_id := by + rw [← groupHomology.map_comp, ← groupHomology.map_id] + exact groupHomology.map_congr e.coe_monoidHom_comp_coe_monoidHom_symm e'.comp_symm n + /-- Given a group homomorphism `f : G →* H` and a representation morphism `φ : A ⟶ Res(f)(B)`, this is the induced map sending `∑ aᵢ·gᵢ : G →₀ A` to `∑ φ(aᵢ)·f(gᵢ) : H →₀ B`. -/ noncomputable abbrev chainsMap₁ : ModuleCat.of k (G →₀ A) ⟶ ModuleCat.of k (H →₀ B) := diff --git a/Mathlib/RepresentationTheory/Rep/Res.lean b/Mathlib/RepresentationTheory/Rep/Res.lean index 55467f78b051bd..5ccc77a7f66c4e 100644 --- a/Mathlib/RepresentationTheory/Rep/Res.lean +++ b/Mathlib/RepresentationTheory/Rep/Res.lean @@ -35,6 +35,8 @@ abbrev res (f : H →* G) (M : Rep k G) := (resFunctor f).obj M variable (f : H →* G) (M : Rep k G) +lemma res_id : res (MonoidHom.id G) M = M := rfl + @[simp] lemma res_obj_ρ : (res f M).ρ = (M.ρ.comp f) := rfl lemma coe_res_obj_ρ' (h : H) : (res f M).ρ h = M.ρ (f h) := rfl From 88f283c91564068ad6925562300f93ec6ec033f1 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 26 Jun 2026 07:58:23 +0000 Subject: [PATCH 0374/1300] chore(Algebra/Algebra/Basic): delete redundant `Algebra.ofSubring` instance (#40914) The instance `Algebra.ofSubring` is a specialization of `Algebra.ofSubsemiring` and is causing diamonds in #40912. Co-authored-by: tb65536 Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Algebra/Algebra/Basic.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Basic.lean b/Mathlib/Algebra/Algebra/Basic.lean index 9cbe3d32bdbb75..7888df545f1144 100644 --- a/Mathlib/Algebra/Algebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Basic.lean @@ -113,10 +113,6 @@ theorem coe_algebraMap_ofSubsemiring (S : C) : (algebraMap S R : S → R) = Subt theorem algebraMap_ofSubsemiring_apply (S : C) (x : S) : algebraMap S R x = x := rfl -/-- Algebra over a subring. This builds upon `Subring.module`. -/ -instance ofSubring {R A : Type*} [CommRing R] [Ring A] [Algebra R A] (S : Subring R) : - Algebra S A := inferInstance - theorem algebraMap_ofSubring {R : Type*} [CommRing R] (S : Subring R) : (algebraMap S R : S →+* R) = S.subtype := rfl From 087d8a23b1152e4cac684614729d4690a24345bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Fri, 26 Jun 2026 08:33:19 +0000 Subject: [PATCH 0375/1300] feat(CategoryTheory/Presentable): the category of types is locally presentable (#41048) --- Mathlib/CategoryTheory/Presentable/Type.lean | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Presentable/Type.lean b/Mathlib/CategoryTheory/Presentable/Type.lean index 81f42fa1a9c37d..e7b611774ca7f3 100644 --- a/Mathlib/CategoryTheory/Presentable/Type.lean +++ b/Mathlib/CategoryTheory/Presentable/Type.lean @@ -5,8 +5,8 @@ Authors: Joël Riou -/ module -public import Mathlib.CategoryTheory.Presentable.Basic -public import Mathlib.CategoryTheory.Limits.Types.Filtered +public import Mathlib.CategoryTheory.Generator.Type +public import Mathlib.CategoryTheory.Presentable.StrongGenerator public import Mathlib.CategoryTheory.Types.Set /-! @@ -145,6 +145,27 @@ instance (X : Type u) : IsPresentable.{u} X := by have := hX.isCardinalPresentable exact isPresentable_of_isCardinalPresentable X κ +lemma isStrongGenerator_punit : + (ObjectProperty.singleton (PUnit.{u + 1})).IsStrongGenerator := by + rw [ObjectProperty.isStrongGenerator_iff] + refine ⟨isSeparator_punit, fun _ _ i hi₁ hi₂ ↦ ?_⟩ + · rw [mono_iff_injective] at hi₁ + rw [isIso_iff_bijective] + refine ⟨hi₁, fun y ↦ ?_⟩ + obtain ⟨f, hf⟩ := hi₂ PUnit ⟨.unit⟩ (↾fun _ ↦ y) + exact ⟨f .unit, ConcreteCategory.congr_hom hf .unit⟩ + +instance (κ : Cardinal.{u}) [Fact κ.IsRegular] : + IsCardinalLocallyPresentable (Type u) κ := by + rw [IsCardinalLocallyPresentable.iff_exists_isStrongGenerator] + exact ⟨.singleton PUnit, inferInstance, isStrongGenerator_punit, by + simp only [ObjectProperty.singleton_le_iff, + CategoryTheory.isCardinalPresentable_iff, isCardinalPresentable_iff] + exact hasCardinalLT_of_finite _ _ (Cardinal.IsRegular.aleph0_le Fact.out)⟩ + +instance : IsLocallyPresentable.{u} (Type u) where + exists_cardinal := ⟨_, Cardinal.fact_isRegular_aleph0, inferInstance⟩ + end Types end CategoryTheory From 165cce0299b3eaa398bf56cbee85e86ff948dc5f Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Fri, 26 Jun 2026 09:08:36 +0000 Subject: [PATCH 0376/1300] feat: add lemmas about primitive roots (#40555) --- .../NumberTheory/NumberField/Units/Basic.lean | 5 +++++ .../RootsOfUnity/CyclotomicUnits.lean | 20 +++++++++++++++++++ .../RootsOfUnity/PrimitiveRoots.lean | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/Mathlib/NumberTheory/NumberField/Units/Basic.lean b/Mathlib/NumberTheory/NumberField/Units/Basic.lean index 6a5ddcb0ad9a36..6a8326e2412435 100644 --- a/Mathlib/NumberTheory/NumberField/Units/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Units/Basic.lean @@ -77,6 +77,11 @@ variable {K} theorem coe_coe (u : (𝓞 K)ˣ) : ((u : 𝓞 K) : K) = (u : K) := rfl +theorem _root_.IsPrimitiveRoot.coe_coe_iff {ν : (𝓞 K)ˣ} {n : ℕ} : + IsPrimitiveRoot (ν : K) n ↔ IsPrimitiveRoot ν n := + IsPrimitiveRoot.map_iff_of_injective + (f := (algebraMap (𝓞 K) K).toMonoidHom.comp (Units.coeHom (𝓞 K))) (coe_injective K) + theorem coe_mul (x y : (𝓞 K)ˣ) : ((x * y : (𝓞 K)ˣ) : K) = (x : K) * (y : K) := rfl theorem coe_pow (x : (𝓞 K)ˣ) (n : ℕ) : ((x ^ n : (𝓞 K)ˣ) : K) = (x : K) ^ n := by diff --git a/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean b/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean index 3da9cd567185af..fc7e3eb66e9157 100644 --- a/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean +++ b/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean @@ -39,6 +39,20 @@ variable {n i j p : ℕ} {A K : Type*} {ζ : A} variable [CommRing A] [IsDomain A] {R : Type*} [CommRing R] [Algebra R A] +/-- If `ζ ^ n = 1` and `ζ ≠ 1`, then `ζ - 1` divides `n`. This does not require `ζ` to be a + primitive root of unity, only a root of unity different from `1`. -/ +theorem sub_one_dvd_natCast_of_pow_eq_one (hζ : ζ ^ n = 1) (hζ1 : ζ ≠ 1) : ζ - 1 ∣ (n : A) := by + have key : (n : A) = ∑ i ∈ range n, (1 - ζ ^ i) := by + have hgs : ∑ i ∈ range n, ζ ^ i = 0 := by + have := geom_sum_mul ζ n + rw [hζ, sub_self] at this + exact (mul_eq_zero.1 this).resolve_right fun h ↦ hζ1 (sub_eq_zero.1 h) + rw [Finset.sum_sub_distrib, hgs, sub_zero, Finset.sum_const, card_range, nsmul_eq_mul, mul_one] + rw [key] + refine Finset.dvd_sum fun i _ ↦ ?_ + have h : ζ - 1 ∣ ζ ^ i - 1 := by simpa using sub_dvd_pow_sub_pow ζ 1 i + rwa [← dvd_neg, neg_sub] at h + namespace IsPrimitiveRoot /-- Given an `n`-th primitive root of unity `ζ,` we have that `ζ - 1` and `ζ ^ j - 1` are associated @@ -136,4 +150,10 @@ lemma nthRootsFinset_pairwise_associated_sub_one_sub_of_prime (hζ : IsPrimitive alias ntRootsFinset_pairwise_associated_sub_one_sub_of_prime := nthRootsFinset_pairwise_associated_sub_one_sub_of_prime +/-- Given an `n`-th primitive root of unity `ζ`, where `1 < n`, we have that `ζ - 1` divides `n`. + In particular, if `ζ` is a `p`-th primitive root of unity with `p` prime, then `ζ - 1` divides + `p`. -/ +theorem sub_one_dvd_natCast (hζ : IsPrimitiveRoot ζ n) (hn : 1 < n) : ζ - 1 ∣ (n : A) := + sub_one_dvd_natCast_of_pow_eq_one hζ.pow_eq_one (hζ.ne_one hn) + end IsPrimitiveRoot diff --git a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean index b3e330e84338aa..be1a3f7a9616f5 100644 --- a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean +++ b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean @@ -156,6 +156,10 @@ theorem one_right_iff : IsPrimitiveRoot ζ 1 ↔ ζ = 1 := by · intro h; rw [← pow_one ζ, h.pow_eq_one] · rintro rfl; exact one +@[simp] +theorem one_left_iff : IsPrimitiveRoot (1 : M) k ↔ k = 1 := + ⟨fun h ↦ Nat.dvd_one.mp (h.dvd_of_pow_eq_one 1 (one_pow _)), fun e ↦ e ▸ one⟩ + @[simp] theorem coe_submonoidClass_iff {M B : Type*} [CommMonoid M] [SetLike B M] [SubmonoidClass B M] {N : B} {ζ : N} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoot ζ k := by From 179c414389904eae3185dd468ff162b0384966ea Mon Sep 17 00:00:00 2001 From: Andrew Yang <36414270+erdOne@users.noreply.github.com> Date: Fri, 26 Jun 2026 09:39:03 +0000 Subject: [PATCH 0377/1300] feat(RingTheory): etale local decomposition of finite extensions (#41034) --- Mathlib.lean | 1 + Mathlib/Logic/Equiv/Fin/Basic.lean | 3 + Mathlib/RingTheory/Etale/QuasiFinite.lean | 196 ++++++++++++++++++ Mathlib/RingTheory/Ideal/Quotient/Over.lean | 38 ++++ Mathlib/RingTheory/Idempotents.lean | 41 ++++ .../LocalRing/ResidueField/Ideal.lean | 3 + .../RingTheory/TensorProduct/Quotient.lean | 41 ++++ 7 files changed, 323 insertions(+) create mode 100644 Mathlib/RingTheory/Ideal/Quotient/Over.lean diff --git a/Mathlib.lean b/Mathlib.lean index 32975106c2b8df..1e5e2a2ac83c42 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6664,6 +6664,7 @@ public import Mathlib.RingTheory.Ideal.Quotient.Index public import Mathlib.RingTheory.Ideal.Quotient.Nilpotent public import Mathlib.RingTheory.Ideal.Quotient.Noetherian public import Mathlib.RingTheory.Ideal.Quotient.Operations +public import Mathlib.RingTheory.Ideal.Quotient.Over public import Mathlib.RingTheory.Ideal.Quotient.PowTransition public import Mathlib.RingTheory.Ideal.Span public import Mathlib.RingTheory.IdealFilter.Basic diff --git a/Mathlib/Logic/Equiv/Fin/Basic.lean b/Mathlib/Logic/Equiv/Fin/Basic.lean index 341c95b6f54503..5bea2e2b9b043e 100644 --- a/Mathlib/Logic/Equiv/Fin/Basic.lean +++ b/Mathlib/Logic/Equiv/Fin/Basic.lean @@ -126,6 +126,9 @@ theorem finSuccEquiv_zero : (finSuccEquiv n) 0 = none := theorem finSuccEquiv_succ (m : Fin n) : (finSuccEquiv n) m.succ = some m := finSuccEquiv'_above (Fin.zero_le _) +@[simp] +theorem finSuccEquiv_last (n : ℕ) : finSuccEquiv (n + 1) (Fin.last (n + 1)) = Fin.last n := rfl + @[simp] theorem finSuccEquiv_symm_none : (finSuccEquiv n).symm none = 0 := finSuccEquiv'_symm_none _ diff --git a/Mathlib/RingTheory/Etale/QuasiFinite.lean b/Mathlib/RingTheory/Etale/QuasiFinite.lean index 41233a5afde995..b9b01203bd9345 100644 --- a/Mathlib/RingTheory/Etale/QuasiFinite.lean +++ b/Mathlib/RingTheory/Etale/QuasiFinite.lean @@ -7,6 +7,7 @@ module public import Mathlib.RingTheory.Polynomial.UniversalFactorizationRing public import Mathlib.RingTheory.ZariskisMainTheorem +public import Mathlib.RingTheory.Ideal.Quotient.Over /-! # Etale local structure of finite maps @@ -435,3 +436,198 @@ lemma Algebra.exists_etale_isIdempotentElem_forall_liesOver_eq (Localization.Away f ⊗[R] S) (.powers (f ⊗ₜ 1)) (a₁ := ⟨P'', ‹_›⟩) (a₂ := ⟨P'f, ‹_›⟩) (PrimeSpectrum.ext ?_)).1) exact (H (P''.under _) inferInstance inferInstance hP'').trans (P'f.over_def P') + +open TensorProduct + +attribute [local instance] RingHom.ker_isPrime + +open scoped nonZeroDivisors + +attribute [local instance] Localization.AtPrime.algebraOfLiesOver + +/-- A key induction step of `exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq`. -/ +private theorem Algebra.exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq_aux + {R : Type u} {S : Type (max u v)} [CommRing R] [CommRing S] [Algebra R S] [Module.Finite R S] + (p : Ideal R) [p.IsPrime] (q : Ideal S) [q.IsPrime] + [q.LiesOver p] (R' : Type u) [CommRing R'] [Algebra R R'] [Algebra.Etale R R'] (P : Ideal R') + [P.IsPrime] [P.LiesOver p] (e : R' ⊗[R] S) (P' : Ideal (R' ⊗[R] S)) + [P'.IsPrime] [P'.LiesOver P] + (hP'q : Ideal.comap Algebra.TensorProduct.includeRight.toRingHom P' = q) + (heP' : e ∉ P') (hpP : Function.Bijective + (Ideal.ResidueField.mapₐ p P (Algebra.ofId _ _) (P.over_def p))) + (H : ∀ (P'' : Ideal (R' ⊗[R] S)), P''.IsPrime → P''.LiesOver P → e ∉ P'' → P'' = P') + (R'' : Type u) [CommRing R''] [Algebra R' R''] [Algebra R R''] [IsScalarTower R R' R''] + [Algebra.Etale R' R''] (Q : Ideal R'') + [Q.IsPrime] [Q.LiesOver P] (n : ℕ) + (e' : Fin ((n + 1) + 1) → R'' ⊗[R] S) + (he' : CompleteOrthogonalIdempotents e') + (he'0 : e' 0 = Algebra.TensorProduct.map (Algebra.ofId R' R'') (AlgHom.id R S) e) + (Q' : Fin n → Ideal (R'' ⊗[R] S)) [∀ i, (Q' i).IsPrime] [∀ i, (Q' i).LiesOver Q] + (hPQ : Function.Bijective (Ideal.ResidueField.mapₐ P Q (Algebra.ofId _ _) (Q.over_def P))) + (hQ' : ∀ (i : Fin n), e' i.succ.castSucc ∉ Q' i) + (H' : ∀ (P'' : Ideal (R'' ⊗[R] S)), e' 0 ∈ P'' → P''.IsPrime → P''.LiesOver Q → + e' (.last _) ∈ P'' ∧ ∀ (i : Fin n), e' i.succ.castSucc ∉ P'' → P'' = Q' i) : + ∃ (R' : Type u) (_ : CommRing R') (_ : Algebra R R') (_ : Algebra.Etale R R') (P : Ideal R') + (_ : P.IsPrime) (_ : P.LiesOver p) (n : ℕ) (e : Fin (n + 1) → R' ⊗[R] S) + (_ : CompleteOrthogonalIdempotents e) (P' : Fin n → Ideal (R' ⊗[R] S)) + (_ : ∀ i, (P' i).IsPrime) (_ : ∀ i, (P' i).LiesOver P), + Function.Bijective (Ideal.ResidueField.mapₐ p P (Algebra.ofId _ _) (P.over_def p)) ∧ + (∀ i, e i.castSucc ∉ P' i) ∧ + ∀ (P'' : Ideal (R' ⊗[R] S)), P''.IsPrime → P''.LiesOver P → + e (.last n) ∈ P'' ∧ ∀ i, e i.castSucc ∉ P'' → P'' = P' i := by + let φ := Algebra.TensorProduct.map (Algebra.ofId R' R'') (AlgHom.id R S) + have : Q.LiesOver p := .trans _ P _ + have hpQ : + Function.Bijective (Ideal.ResidueField.mapₐ p Q (Algebra.ofId _ _) (Q.over_def p)) := by + convert hPQ.comp hpP + rw [← @AlgHom.coe_restrictScalars' R R', ← AlgHom.coe_comp]; congr 1; ext + let P'φ := (Ideal.fiberIsoOfBijectiveResidueField hpQ).symm + (Ideal.fiberIsoOfBijectiveResidueField hpP ⟨P', ‹_›, ‹_›⟩) + have : P'φ.1.LiesOver P := .trans _ Q _ + have : (P'φ.1.comap φ.toRingHom).LiesOver P := inferInstanceAs ((P'φ.1.comap φ).LiesOver P) + have hP'φ : P'φ.1.comap φ.toRingHom = P' := by + apply Ideal.eq_of_comap_eq_comap_of_bijective_residueFieldMap hpP + rw [Ideal.comap_comap] + convert Ideal.comap_fiberIsoOfBijectiveResidueField_symm hpQ _ + · ext; simp [φ] + · simp; rfl + refine ⟨R'', inferInstance, _, .comp R R' R'', Q, ‹_›, .trans _ P _, _, _, he', Fin.cons P'φ + Q', Fin.cases P'φ.2.1 ?_, Fin.cases P'φ.2.2 ?_, hpQ, Fin.cases ?_ ?_, ?_⟩ + · intro P'' _ _ + by_cases heP'' : e ∈ P''.comap φ + · obtain ⟨h₁, h₂⟩ := H' P'' (by simpa [he'0]) inferInstance inferInstance + exact ⟨h₁, Fin.cases (fun h ↦ (h (by simpa [he'0])).elim) (by simpa)⟩ + · have : P''.LiesOver P := .trans _ Q _ + obtain rfl := H _ inferInstance inferInstance heP'' + have : ∀ i ≠ 0, e' i ∈ P'' := by + intro j hj + rw [← Ideal.IsPrime.mul_mem_left_iff (I := P'') heP''] + simp [φ, ← he'0, he'.ortho hj.symm] + refine ⟨by simp [this], Fin.cases (fun _ ↦ ?_) (by simp [this])⟩ + simp only [Fin.cons_zero] + apply Ideal.eq_of_comap_eq_comap_of_bijective_residueFieldMap hpQ + have : (φ.restrictScalars _).comp Algebra.TensorProduct.includeRight = + Algebra.TensorProduct.includeRight := by ext; simp [φ] + rw [← this] + exact congr(($hP'φ).comap Algebra.TensorProduct.includeRight).symm + · simp only [Fin.cons_succ]; infer_instance + · simp only [Fin.cons_succ]; infer_instance + · rw [← hP'φ] at heP'; simpa [he'0] + · simpa + +set_option backward.isDefEq.respectTransparency false in +/-- A less universe polymorphic version of +`exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq`. Use that instead. -/ +private lemma Algebra.exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq' + {R : Type u} {S : Type max u v} [CommRing R] [CommRing S] [Algebra R S] [Module.Finite R S] + (p : Ideal R) [p.IsPrime] : + ∃ (R' : Type u) (_ : CommRing R') (_ : Algebra R R') (_ : Algebra.Etale R R') (P : Ideal R') + (_ : P.IsPrime) (_ : P.LiesOver p) (n : ℕ) (e : Fin (n + 1) → R' ⊗[R] S) + (_ : CompleteOrthogonalIdempotents e) (P' : Fin n → Ideal (R' ⊗[R] S)) + (_ : ∀ i, (P' i).IsPrime) (_ : ∀ i, (P' i).LiesOver P), + Function.Bijective (Ideal.ResidueField.mapₐ p P (Algebra.ofId _ _) (P.over_def p)) ∧ + (∀ i, e i.castSucc ∉ P' i) ∧ + ∀ (P'' : Ideal (R' ⊗[R] S)), P''.IsPrime → P''.LiesOver P → + e (.last n) ∈ P'' ∧ ∀ i, e i.castSucc ∉ P'' → P'' = P' i := by + induction h : (p.primesOver S).ncard using Nat.strong_induction_on generalizing R S with + | h n IH => + have : IsArtinianRing (p.ResidueField ⊗[R] S) := IsArtinianRing.of_finite p.ResidueField _ + have hpSfin : (p.primesOver S).Finite := + (PrimeSpectrum.primesOverOrderIsoFiber R S p).finite_iff.mpr inferInstance + cases n with + | zero => + have := (Set.ncard_eq_zero hpSfin).mp h + refine ⟨R, inferInstance, inferInstance, inferInstance, p, inferInstance, ⟨rfl⟩, 0, 1, + ⟨⟨by simp [IsIdempotentElem], + by simp only [Nat.reduceAdd, Pi.one_apply, mul_one, Subsingleton.pairwise]⟩, + by simp⟩, nofun, nofun, nofun, ?_, nofun, ?_⟩ + · rw! [ofId_self, Ideal.ResidueField.mapₐ_id]; exact Function.bijective_id + · exact fun P h₁ h₂ ↦ (this.le + ⟨show (P.comap Algebra.TensorProduct.includeRight.toRingHom).IsPrime from inferInstance, + ⟨by simp [P.over_def p, Ideal.under, Ideal.comap_comap]⟩⟩).elim + | succ n => + obtain ⟨q, hq, hq'⟩ := Set.nonempty_of_ncard_ne_zero (h.trans_ne (by simp)) + obtain ⟨R', _, _, _, P, _, _, e, he, P', _, _, hP'q, heP', hpP, _, H⟩ := + Algebra.exists_etale_isIdempotentElem_forall_liesOver_eq p q + have : (P.primesOver (R' ⊗[R] S ⧸ Ideal.span {e})).ncard < n + 1 := by + let F := Ideal.fiberIsoOfBijectiveResidueField hpP (S := S) + refine (Ideal.ncard_primesOver_quotient_singleton_lt_of_notMem _ _ + P' heP' (F.finite_iff.mpr hpSfin)).trans_le ?_ + rw [← h, ← Nat.card_coe_set_eq, ← Nat.card_coe_set_eq, Nat.card_congr F.toEquiv] + obtain ⟨R'', _, _, _, Q, _, _, n, e' : _ → R'' ⊗[R'] (R' ⊗[R] S ⧸ Ideal.span {e}), + he', Q' : _ → Ideal (R'' ⊗[R'] (R' ⊗[R] S ⧸ Ideal.span {e})), _, _, hPQ, hQ', H'⟩ := + IH _ this (R := R') (S := R' ⊗[R] S ⧸ Ideal.span {e}) P rfl + let : Algebra R R'' := .compHom _ (algebraMap R R') + have : IsScalarTower R R' R'' := .of_algebraMap_eq' rfl + let φ := Algebra.TensorProduct.map (Algebra.ofId R' R'') (AlgHom.id R S) + let e₁ : R'' ⊗[R'] (R' ⊗[R] S ⧸ Ideal.span {e}) ≃ₐ[R''] (R'' ⊗[R] S ⧸ Ideal.span {φ e}) := + tensorQuotientTensorEquiv (R'' := R'') e + obtain ⟨e'', he'', he''e'⟩ := CompleteOrthogonalIdempotents.exists_eq_comp_of_ker_eq_span + (Ideal.Quotient.mk (Ideal.span {φ e})) (I := Fin (n + 1)) (φ e) (he.map φ) (by simp) + (e₁ ∘ e') (he'.map e₁.toRingHom) (fun _ ↦ Ideal.Quotient.mk_surjective _) + have he''e'' (i : _) : e₁ (e' i) = e'' i := congr_fun he''e' i + have hψe'' (i : _) : (e' i) = e₁.symm (e'' i) := e₁.eq_symm_apply.mpr (he''e'' i) + refine exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq_aux p q R' P e P' + hP'q heP' hpP (fun P'' h₁ h₂ heP'' ↦ H P'' h₁ h₂ heP'') R'' Q n _ + ((CompleteOrthogonalIdempotents.equiv (finSuccEquiv _)).mpr he'') rfl + (Q' · |>.comap (e₁.symm.toAlgHom.comp (Ideal.Quotient.mkₐ _ _))) hPQ + (fun i ↦ by rw [Function.comp_def]; simpa [← hψe''] using hQ' i) ?_ + simp only [Function.comp_apply, finSuccEquiv_zero, finSuccEquiv_last, Fin.castSucc_succ, + finSuccEquiv_succ] + intro P'' heP'' _ _ + have : (P''.map (Ideal.Quotient.mk (.span {φ e}))).IsPrime := + Ideal.map_isPrime_of_surjective Ideal.Quotient.mk_surjective (by simpa [Ideal.span_le]) + have : (P''.map (Ideal.Quotient.mk (.span {φ e}))).LiesOver Q := ⟨by + have : P'' ⊔ Ideal.span {φ e} = P'' := by simpa [Ideal.span_le] + rw [← Ideal.under_under (B := R'' ⊗[R] S)] + simpa [Ideal.under, Ideal.comap_map_of_surjective _ Ideal.Quotient.mk_surjective, + ← RingHom.ker_eq_comap_bot, this] using P''.over_def Q⟩ + have := H' ((P''.map (Ideal.Quotient.mk (.span {φ e}))).comap e₁) inferInstance + (inferInstanceAs <| ((P''.map (Ideal.Quotient.mk (.span {φ e}))).comap + e₁.toAlgHom).LiesOver Q) + have hP'' : (1 - φ e) ∉ P'' := + fun h ↦ ‹P''.IsPrime›.one_notMem (by convert add_mem heP'' h; ring) + simp only [Ideal.mem_comap, he''e'', + Ideal.mem_map_span_singleton_iff_of_isIdempotentElem (he.map φ), + Ideal.IsPrime.mul_mem_left_iff hP''] at this + refine ⟨this.1, fun i hi ↦ (this.2 i hi).symm ▸ ?_⟩ + -- TODO: clean-up when `Ideal.comap` is refactored to take a `RingHom` + change _ = Ideal.comap (Ideal.Quotient.mk _) (Ideal.comap (e₁.symm.trans e₁).toRingHom _) + simp only [AlgEquiv.symm_trans_self, RingEquiv.toRingHom_eq_coe, + AlgEquiv.toRingEquiv_toRingHom, AlgEquiv.refl_toRingHom, Ideal.comap_id] + rw [Ideal.comap_map_of_surjective _ Ideal.Quotient.mk_surjective] + simpa [left_eq_sup, ← RingHom.ker_eq_comap_bot, Ideal.span_le] using heP'' + +/-- +If `S` is finite over `R`, and `p` is a prime of `R`, then there exists an étale neighborhood +`(R', P)` of `p` with `κ(p) = κ(P)` such that `R' ⊗[R] S ≃ₐ[R'] R₁ × ... × Rₙ × A`, +each `Rᵢ` has a unique prime `Pᵢ` lying over `P`, and no other prime in `R' ⊗[R] S` lies over `P`. + +This is merely an iterated application of `exists_etale_isIdempotentElem_forall_liesOver_eq`. +This is weaker than the corresponding statement of stacks project (in particular we asked for +`Module.Finite` instead of quasi finite when localized at `p`, so that we don't need to keep +track of this when passing to quotients and tensor products), and the only reason is that +the corresponding stronger statement is even harder to state and even more annoying to prove. +-/ +@[stacks 00UL] +lemma Algebra.exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq + {R : Type u} {S : Type v} [CommRing R] [CommRing S] [Algebra R S] [Module.Finite R S] + (p : Ideal R) [p.IsPrime] : + ∃ (R' : Type u) (_ : CommRing R') (_ : Algebra R R') (_ : Algebra.Etale R R') (P : Ideal R') + (_ : P.IsPrime) (_ : P.LiesOver p) (n : ℕ) (e : Fin (n + 1) → R' ⊗[R] S) + (_ : CompleteOrthogonalIdempotents e) (P' : Fin n → Ideal (R' ⊗[R] S)) + (_ : ∀ i, (P' i).IsPrime) (_ : ∀ i, (P' i).LiesOver P), + Function.Bijective (Ideal.ResidueField.mapₐ p P (Algebra.ofId _ _) (P.over_def p)) ∧ + (∀ i, e i.castSucc ∉ P' i) ∧ + ∀ (P'' : Ideal (R' ⊗[R] S)), P''.IsPrime → P''.LiesOver P → + e (.last n) ∈ P'' ∧ ∀ i, e i.castSucc ∉ P'' → P'' = P' i := by + have ⟨R', _, _, _, P, _, _, n, e, he, P', _, _, hP, hP', H⟩ := + exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq' (S := ULift.{u} S) p + let e₁ : R' ⊗[R] S ≃ₐ[R'] R' ⊗[R] ULift.{u} S := + Algebra.TensorProduct.congr .refl ULift.algEquiv.symm + refine ⟨R', _, _, ‹_›, P, ‹_›, ‹_›, n, e₁.symm ∘ e, he.map _, + fun i ↦ (P' i).comap e₁.toAlgHom, inferInstance, inferInstance, hP, by simpa, + fun P'' _ _ ↦ ?_⟩ + have := H (P''.comap e₁.symm.toAlgHom) inferInstance inferInstance + refine ⟨by simpa using this.1, fun i hi ↦ ?_⟩ + simp [← this.2 i (by simpa), Ideal.comap_comapₐ] diff --git a/Mathlib/RingTheory/Ideal/Quotient/Over.lean b/Mathlib/RingTheory/Ideal/Quotient/Over.lean new file mode 100644 index 00000000000000..8758ad62465ed9 --- /dev/null +++ b/Mathlib/RingTheory/Ideal/Quotient/Over.lean @@ -0,0 +1,38 @@ +/- +Copyright (c) 2026 Andrew Yang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Andrew Yang +-/ +module + +public import Mathlib.Data.Set.Card +public import Mathlib.RingTheory.Ideal.Over + +/-! # Lemmas about `primesOver` in quotient rings. -/ + +@[expose] public section + +variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] + +/-- Given a prime `P` of `R` and an ideal `I` in an `R`-algebra `S`. +Suppose we can find a prime `P'` over `P`, not containing `I`, +then the number of primes of `S / I` over `P` +is strictly less than primes of `S` over `P` (provided they are finite). + +The lemma is stated in terms of surjections for syntactic generality. -/ +lemma Ideal.ncard_primesOver_lt_of_not_le + (f : S →ₐ[R] T) (Hf : Function.Surjective f) + (P : Ideal R) (P' : Ideal S) [P'.IsPrime] [P'.LiesOver P] + (hkP' : ¬ RingHom.ker f.toRingHom ≤ P') (H : (P.primesOver S).Finite) : + (P.primesOver T).ncard < (P.primesOver S).ncard := by + rw [← Set.ncard_image_of_injective _ (Ideal.comap_injective_of_surjective _ Hf)] + refine Set.ncard_lt_ncard (Set.ssubset_iff_exists.mpr ⟨?_, P', ⟨‹_›, ‹_›⟩, ?_⟩) H + · rintro _ ⟨q, ⟨_, _⟩, rfl⟩ + exact ⟨inferInstance, inferInstanceAs ((q.comap f).LiesOver _)⟩ + · rintro ⟨q, ⟨_, _⟩, rfl⟩; exact hkP' (Ideal.ker_le_comap _) + +lemma Ideal.ncard_primesOver_quotient_singleton_lt_of_notMem + (P : Ideal R) (e : S) (P' : Ideal S) [P'.IsPrime] [P'.LiesOver P] + (heP' : e ∉ P') (H : (P.primesOver S).Finite) : + (P.primesOver (S ⧸ Ideal.span {e})).ncard < (P.primesOver S).ncard := + Ideal.ncard_primesOver_lt_of_not_le _ (Ideal.Quotient.mkₐ_surjective R _) _ P' (by simpa) H diff --git a/Mathlib/RingTheory/Idempotents.lean b/Mathlib/RingTheory/Idempotents.lean index 32e9eb9f8daab6..815c057d4267b7 100644 --- a/Mathlib/RingTheory/Idempotents.lean +++ b/Mathlib/RingTheory/Idempotents.lean @@ -8,6 +8,7 @@ module public import Mathlib.Algebra.BigOperators.Fin public import Mathlib.Algebra.Ring.GeomSum public import Mathlib.RingTheory.Ideal.Quotient.Operations +public import Mathlib.Tactic.LinearCombination /-! @@ -478,6 +479,36 @@ noncomputable def AlgEquiv.prodQuotientOfIsIdempotentElem AlgEquiv.ofBijective ((Ideal.Quotient.mkₐ _ _).prod (Ideal.Quotient.mkₐ _ _)) <| RingHom.prod_bijective_of_isIdempotentElem he hf hef₁ hef₂ +/-- One can lift a family of complete orthogonal idempotents of `R/e₀` to get one on `R`. + +Note that the lemma itself is stated in terms of surjections (where `T = S / I`) +instead for syntactic generality. -/ +lemma CompleteOrthogonalIdempotents.exists_eq_comp_of_ker_eq_span + (f : R →+* S) (e₀ : R) (he₀ : IsIdempotentElem e₀) (hfe₀ : RingHom.ker f = .span {e₀}) + (e : I → S) (he : CompleteOrthogonalIdempotents e) (hef : ∀ i, e i ∈ f.range) : + ∃ e', CompleteOrthogonalIdempotents (Option.rec e₀ e') ∧ e = f ∘ e' := by + choose e' he' using hef + choose k hk using fun i ↦ Ideal.mem_span_singleton.mp + (hfe₀.le (show f (e' i * e' i - e' i) = 0 by simp [he', (he.1.1 i).eq])) + refine ⟨(1 - e₀) • e', ⟨⟨Option.rec he₀ fun i ↦ ?_, ?_⟩, ?_⟩, ?_⟩ + · rintro (_|i) (_|j) h + · simp at h + · dsimp; linear_combination - he₀.eq * e' j + · dsimp; linear_combination - he₀.eq * e' i + · obtain ⟨k, hk⟩ := Ideal.mem_span_singleton.mp + (hfe₀.le (show f (e' i * e' j) = 0 by simp [he', he.1.2 (by simpa using h)])) + dsimp + rw [mul_mul_mul_comm, hk, he₀.one_sub.eq, ← mul_assoc, he₀.one_sub_mul_self, zero_mul] + · obtain ⟨k, hk⟩ := Ideal.mem_span_singleton.mp + (hfe₀.le (show f (∑ i, e' i - 1) = 0 by simpa [he', sub_eq_zero] using he.2)) + simp only [Fintype.sum_option, Pi.smul_apply, smul_eq_mul, ← Finset.mul_sum, + sub_eq_iff_eq_add.mp hk] + linear_combination - he₀.eq * k + · have : f e₀ = 0 := by simpa using hfe₀.ge (Ideal.mem_span_singleton_self _) + aesop + · dsimp [IsIdempotentElem] + linear_combination congr($(he₀.eq) * ((e' i) ^ 2 - k i) + (1 - e₀) * $(hk i)) + end CommRing section corner @@ -589,4 +620,14 @@ def CompleteOrthogonalIdempotents.ringEquivOfComm [CommSemiring R] (he : CompleteOrthogonalIdempotents e) : R ≃+* Π i, (he.idem i).Corner := he.ringEquivOfIsMulCentral fun _ ↦ Semigroup.mem_center_iff.mpr fun _ ↦ mul_comm .. +lemma Ideal.mem_map_span_singleton_iff_of_isIdempotentElem + [CommRing R] {e r : R} (he : IsIdempotentElem e) {I : Ideal R} : + Ideal.Quotient.mk _ r ∈ I.map (Ideal.Quotient.mk (Ideal.span {e})) ↔ (1 - e) * r ∈ I := by + simp only [Ideal.mem_map_iff_of_surjective _ Ideal.Quotient.mk_surjective, + Ideal.Quotient.mk_eq_mk_iff_sub_mem, Ideal.mem_span_singleton] + refine ⟨?_, fun H ↦ ⟨_, H, by simp [sub_mul]⟩⟩ + intro ⟨s, hs, t, hrst⟩ + convert I.mul_mem_left (1 - e) hs using 1 + linear_combination he.eq * t - (1 - e) * hrst + end corner diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean index f6d7e2c2ee8dfd..e76b5c7af8ce7c 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean @@ -246,3 +246,6 @@ lemma Ideal.ResidueField.ringHom_ext {I : Ideal R} [I.IsPrime] lemma Ideal.ResidueField.algHom_ext {I : Ideal A} [I.IsPrime] {f g : I.ResidueField →ₐ[R] B} (H : f.comp (IsScalarTower.toAlgHom R A _) = g.comp (IsScalarTower.toAlgHom R A _)) : f = g := AlgHom.coe_ringHom_injective (ringHom_ext congr($H)) + +@[simp] lemma Ideal.ResidueField.mapₐ_id (I : Ideal A) [I.IsPrime] : + Ideal.ResidueField.mapₐ I I (.id R A) rfl = .id _ _ := by ext; simp diff --git a/Mathlib/RingTheory/TensorProduct/Quotient.lean b/Mathlib/RingTheory/TensorProduct/Quotient.lean index f12cad92295d8e..14602fe0fed508 100644 --- a/Mathlib/RingTheory/TensorProduct/Quotient.lean +++ b/Mathlib/RingTheory/TensorProduct/Quotient.lean @@ -150,3 +150,44 @@ lemma Ideal.subtype_rTensor_range {R : Type*} [CommRing R] (M : Type*) [AddCommG ← Submodule.map_symm_eq_iff, ← Submodule.comap_equiv_eq_map_symm, ← LinearMap.ker_comp, ← TensorProduct.quotTensorEquivQuotSMul_comp_mkQ_rTensor, LinearEquiv.ker_comp] exact LinearMap.exact_iff.mp (rTensor_exact M (LinearMap.exact_subtype_mkQ I) I.mkQ_surjective) + +section + +variable {R R' R'' S : Type*} [CommRing R] [CommRing R'] [CommRing R''] [CommRing S] + [Algebra R R'] [Algebra R R''] [Algebra R' R''] [IsScalarTower R R' R''] [Algebra R S] + +variable (R'') in +set_option backward.isDefEq.respectTransparency false in +attribute [local ext high] Ideal.Quotient.algHom_ext in +/-- Let `e` be an element of `R' ⊗[R] S`. Then `R'' ⊗[R'] ((R' ⊗[R] S) / e)` is isomorphic to +`(R'' ⊗[R] S) / e` as `R''`-algebras. -/ +noncomputable +def Algebra.tensorQuotientTensorEquiv (e : R' ⊗[R] S) : + R'' ⊗[R'] (R' ⊗[R] S ⧸ Ideal.span {e}) ≃ₐ[R''] + (R'' ⊗[R] S ⧸ Ideal.span {Algebra.TensorProduct.rTensor S (Algebra.ofId R' R'') e}) := + letI φ := Algebra.TensorProduct.rTensor S (Algebra.ofId R' R'') + letI ψ : R'' ⊗[R] S →ₐ[R''] R'' ⊗[R'] (R' ⊗[R] S ⧸ Ideal.span {e}) := + Algebra.TensorProduct.lift (Algebra.ofId _ _) + ((Algebra.TensorProduct.includeRight.restrictScalars R).comp + ((Ideal.Quotient.mkₐ _ _).comp Algebra.TensorProduct.includeRight)) fun _ _ ↦ .all _ _ + haveI hψφ : (ψ.restrictScalars R').comp φ = + (Algebra.TensorProduct.includeRight.restrictScalars R').comp (Ideal.Quotient.mkₐ _ _) := by + ext; simp [ψ, φ] + haveI heψ : Ideal.span {φ e} ≤ RingHom.ker ψ := by simpa [Ideal.span_le] using congr($hψφ e) + AlgEquiv.ofAlgHom (Algebra.TensorProduct.lift (Algebra.ofId _ _) (Ideal.quotientMapₐ _ φ + (Ideal.map_le_iff_le_comap.mp (by simp [Ideal.map_span, φ]))) fun _ _ ↦ .all _ _) + (Ideal.Quotient.liftₐ _ ψ heψ) (by ext; simp [ψ, φ]) (by ext; simp [φ, ψ]) + +@[simp] +lemma Algebra.tensorQuotientTensorEquiv_tmul (e : R' ⊗[R] S) (a : R'') (b : R') (c : S) : + Algebra.tensorQuotientTensorEquiv R'' e (a ⊗ₜ Ideal.Quotient.mk _ (b ⊗ₜ c)) = + Ideal.Quotient.mk _ ((a * algebraMap R' R'' b) ⊗ₜ c) := by + simp [Algebra.tensorQuotientTensorEquiv, ← Ideal.Quotient.mk_algebraMap, ← map_mul] + +@[simp] +lemma Algebra.tensorQuotientTensorEquiv_symm_tmul (e : R' ⊗[R] S) (a : R'') (b : S) : + (Algebra.tensorQuotientTensorEquiv R'' e).symm (Ideal.Quotient.mk _ (a ⊗ₜ b)) = + a ⊗ₜ Ideal.Quotient.mk _ (1 ⊗ₜ b) := by + simp [Algebra.tensorQuotientTensorEquiv] + +end From 31bbfafb600ea1426f9a651da991b724feb0bb3d Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:13:09 +0000 Subject: [PATCH 0378/1300] fix(ClickSuggestions): instantiate all metavariables in the local context (#41001) This PR fixes the panic in `#click_suggestions` that was reported at https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.23click_suggestions.20doesn.27t.20find.20lemma/near/606231763 There are two separate problems that this PR fixes: 1. The implementation of `#click_suggestion` assumes all metavariables have already been instantiated. This is valid because they are all instantiated at the very beginning. However, this was not done properly, causing the types of free variables to still be able to contain metavariables. 2. The function `viewKAbstractSubExpr` was able to reach its `unreachable!` block. The reason is that `kabstractPositions` calls `instantiateMVars` on the expression `e` but not on the pattern `p`, causing a discrepancy. This is fixed by removing the `instantiateMVars` call. This is fine, because in both of the use cases (`rw??` and `#click_suggestions`), the expressions already have instantiated metavariables at this point. --- Mathlib/Lean/Meta/KAbstractPositions.lean | 1 - Mathlib/Tactic/ClickSuggestions.lean | 5 +++-- MathlibTest/ClickSuggestions/Test.lean | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Mathlib/Lean/Meta/KAbstractPositions.lean b/Mathlib/Lean/Meta/KAbstractPositions.lean index 836b353cdcef16..55291bb6c9111e 100644 --- a/Mathlib/Lean/Meta/KAbstractPositions.lean +++ b/Mathlib/Lean/Meta/KAbstractPositions.lean @@ -33,7 +33,6 @@ namespace Lean.Meta /-- Return the positions that `kabstract` would abstract for pattern `p` in expression `e`. i.e. the positions that unify with `p`. -/ def kabstractPositions (p e : Expr) : MetaM (Array SubExpr.Pos) := do - let e ← instantiateMVars e let mctx ← getMCtx let pHeadIdx := p.toHeadIndex let pNumArgs := p.headNumArgs diff --git a/Mathlib/Tactic/ClickSuggestions.lean b/Mathlib/Tactic/ClickSuggestions.lean index 0164cde3a2f665..9ef3d8ebeedff3 100644 --- a/Mathlib/Tactic/ClickSuggestions.lean +++ b/Mathlib/Tactic/ClickSuggestions.lean @@ -72,12 +72,13 @@ def viewKAbstractSubExpr' {m α} /-- Compute the suggestions. Use `token` for the output. -/ public def generateSuggestions (loc : SubExpr.GoalsLocation) (parentDecl? : Option Name) (token : RefreshToken) : ClickSuggestionsM Unit := withReducible do + -- Instantiate all metavariables, so that we won't need to worry about this later on. + instantiateMVarDeclMVars loc.mvarId + loc.mvarId.withContext do -- TODO: instead of just putting `✝` after inaccessible names, -- we should figure out how to use `rename_i` to actually refer to shadowed local variables. let lctx := (← getLCtx).sanitizeNames.run' { options := (← getOptions) } Meta.withLCtx' lctx do - -- Instantiate all metavariables, so that we will not need to do this later on. - instantiateMVarDeclMVars loc.mvarId trackingComputation "click_suggestions" do let (fvarId?, pos) ← match loc.loc with | .hypType fvarId pos => pure (some fvarId, pos) diff --git a/MathlibTest/ClickSuggestions/Test.lean b/MathlibTest/ClickSuggestions/Test.lean index 4bac764b6ddc0d..884700e3f7b4ae 100644 --- a/MathlibTest/ClickSuggestions/Test.lean +++ b/MathlibTest/ClickSuggestions/Test.lean @@ -184,3 +184,10 @@ example (a b c : Nat) : a + b + c = a + b := by click_test "/1" => "nth_rw 2 [Nat.add_comm a b]" click_test "/0/1/0/1" => "nth_rw 1 [Nat.add_comm a b]" exact test_sorry + +-- This example used to panic +example : True := by + by_cases h : False + · click_test h "" => "rw [← true_eq_false_of_false h] at h" + trivial + · trivial From d7d52d2a2ff057635f3eada6f0bc7ec113fa62ac Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:02:03 +0000 Subject: [PATCH 0379/1300] feat(Algebra/MvPolynomial/PDeriv): a coefficient formula for `pderiv` (#39624) This formula is useful for defining partial derivatives of multivariate power series, see PR #39626. --- Mathlib/Algebra/MvPolynomial/PDeriv.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/Algebra/MvPolynomial/PDeriv.lean b/Mathlib/Algebra/MvPolynomial/PDeriv.lean index c70e5c5bb4f250..929abd0a853464 100644 --- a/Mathlib/Algebra/MvPolynomial/PDeriv.lean +++ b/Mathlib/Algebra/MvPolynomial/PDeriv.lean @@ -118,6 +118,21 @@ theorem pderiv_pow {i : σ} {f : MvPolynomial σ R} {n : ℕ} : theorem pderiv_C_mul {f : MvPolynomial σ R} {i : σ} : pderiv i (C a * f) = C a * pderiv i f := by rw [C_mul', Derivation.map_smul, C_mul'] +theorem coeff_pderiv {i : σ} (p : MvPolynomial σ R) (m : σ →₀ ℕ) : + coeff m (pderiv i p) = coeff (m + single i 1) p * (m i + 1) := by + classical + induction p using MvPolynomial.induction_on' with + | add p q hp hq => simp [hp, hq, add_mul] + | monomial n a => + rw [pderiv_monomial, coeff_monomial, coeff_monomial] + by_cases h : n = m + single i 1 + · simp [h] + simp only [h, ↓reduceIte, zero_mul] + by_cases hn : n i = 0 + · simp [hn] + apply if_neg + rwa [tsub_eq_iff_eq_add_of_le (fun _ ↦ by grind)] + theorem pderiv_map {S} [CommSemiring S] {φ : R →+* S} {f : MvPolynomial σ R} {i : σ} : pderiv i (map φ f) = map φ (pderiv i f) := by apply induction_on f (fun r ↦ by simp) (fun p q hp hq ↦ by simp [hp, hq]) fun p j eq ↦ ?_ From cd86c80f970f42ac97c5494ed7d3bfa61d05c27d Mon Sep 17 00:00:00 2001 From: Suzuka Yu <109365723+Yu-Misaka@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:02:06 +0000 Subject: [PATCH 0380/1300] feat(LinearAlgebra): preliminary APIs for symplectic matrices (#40449) Greetings! This PR attempts to provide some basic APIs for #40352. Involving `Matrix.mulVec_apply`, `Matrix.map_J` and `SymplecticGroup.map_mem`. Honestly I'm not sure if, for example, `Matrix.mulVec_apply` exists somewhere else in the library (I tried my best but didn't find it) --- Mathlib/Data/Matrix/Mul.lean | 12 ++++++++++++ Mathlib/LinearAlgebra/SymplecticGroup.lean | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/Mathlib/Data/Matrix/Mul.lean b/Mathlib/Data/Matrix/Mul.lean index 6eaadb3b0e2fa1..e9b9cc920a2be9 100644 --- a/Mathlib/Data/Matrix/Mul.lean +++ b/Mathlib/Data/Matrix/Mul.lean @@ -701,6 +701,12 @@ def mulVec [Fintype n] (M : Matrix m n α) (v : n → α) : m → α @[inherit_doc] scoped infixr:73 " *ᵥ " => Matrix.mulVec +lemma mulVec_apply [Fintype n] (M : Matrix m n α) (v : n → α) (i : m) : + (M *ᵥ v) i = M.row i ⬝ᵥ v := rfl + +lemma mulVec_apply_eq_sum [Fintype n] (M : Matrix m n α) (v : n → α) (i : m) : + (M *ᵥ v) i = ∑ j : n, M i j * v j := rfl + /-- `v ᵥ* M` (notation for `vecMul v M`) is the vector-matrix product of vector `v` and matrix `M`, where `v` is seen as a row vector. @@ -714,6 +720,12 @@ def vecMul [Fintype m] (v : m → α) (M : Matrix m n α) : n → α @[inherit_doc] scoped infixl:73 " ᵥ* " => Matrix.vecMul +lemma vecMul_apply [Fintype m] (v : m → α) (M : Matrix m n α) (i : n) : + (v ᵥ* M) i = v ⬝ᵥ M.col i := rfl + +lemma vecMul_apply_eq_sum [Fintype m] (v : m → α) (M : Matrix m n α) (i : n) : + (v ᵥ* M) i = ∑ j : m, v j * M j i := rfl + /-- Left multiplication by a matrix, as an `AddMonoidHom` from vectors to vectors. -/ @[simps] def mulVec.addMonoidHomLeft [Fintype n] (v : n → α) : Matrix m n α →+ m → α where diff --git a/Mathlib/LinearAlgebra/SymplecticGroup.lean b/Mathlib/LinearAlgebra/SymplecticGroup.lean index f45df9b46ce4d0..c5ae74d50bf355 100644 --- a/Mathlib/LinearAlgebra/SymplecticGroup.lean +++ b/Mathlib/LinearAlgebra/SymplecticGroup.lean @@ -39,6 +39,13 @@ section JMatrixLemmas def J : Matrix (l ⊕ l) (l ⊕ l) R := Matrix.fromBlocks 0 (-1) 1 0 +variable {R} in +@[simp] +theorem map_J {F S : Type*} [CommRing S] [FunLike F R S] + [AddMonoidHomClass F R S] [OneHomClass F R S] (f : F) : + (J l R).map f = J l S := by + simp [J, fromBlocks_map, Matrix.map_neg] + @[simp] theorem J_transpose : (J l R)ᵀ = -J l R := by rw [J, fromBlocks_transpose, ← neg_one_smul R (fromBlocks _ _ _ _ : Matrix (l ⊕ l) (l ⊕ l) R), @@ -129,6 +136,10 @@ theorem symplectic_det (hA : A ∈ symplecticGroup l R) : IsUnit <| det A := by rw [mul_comm A.det, mul_assoc] at hA exact hA +theorem map_mem {F S : Type*} [CommRing S] [FunLike F R S] [RingHomClass F R S] + (hA : A ∈ symplecticGroup l R) (f : F) : A.map f ∈ symplecticGroup l S := by + simp_rw [mem_iff, ← transpose_map, ← map_J _ f, ← Matrix.map_mul, mem_iff.mp hA] + theorem transpose_mem (hA : A ∈ symplecticGroup l R) : Aᵀ ∈ symplecticGroup l R := by rw [mem_iff] at hA ⊢ rw [transpose_transpose] From e2102acfd2d7fcf51dec47cbeaad829f419c1dd0 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:02:08 +0000 Subject: [PATCH 0381/1300] chore(Algebra/Ring/Periodic): automated extraction from #38483 (#40669) Co-authored-by: jessealama <56691+jessealama@users.noreply.github.com> --- Mathlib/Algebra/Ring/Periodic.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Ring/Periodic.lean b/Mathlib/Algebra/Ring/Periodic.lean index bb0a228b59f6d7..71fcf017b9bc3e 100644 --- a/Mathlib/Algebra/Ring/Periodic.lean +++ b/Mathlib/Algebra/Ring/Periodic.lean @@ -415,4 +415,11 @@ theorem Antiperiodic.mul [Add α] [Mul β] [HasDistribNeg β] (hf : Antiperiodic theorem Antiperiodic.div [Add α] [DivisionMonoid β] [HasDistribNeg β] (hf : Antiperiodic f c) (hg : Antiperiodic g c) : Periodic (f / g) c := by simp_all [neg_div_neg_eq] +/-- For an antiperiodic function `f` with antiperiod `c`, summing `f` over a `Finset` shifted by +`c` (via `addRightEmbedding c`) negates the sum over the original `Finset`. -/ +theorem Antiperiodic.sum_map_addRightEmbedding [Add α] [IsRightCancelAdd α] + [SubtractionCommMonoid β] (hf : Antiperiodic f c) (s : Finset α) : + ∑ k ∈ s.map (addRightEmbedding c), f k = -∑ k ∈ s, f k := by + simp [hf _] + end Function From 8f49886e72d0b26ec9bc6366ee218afd0b6d1e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:02:10 +0000 Subject: [PATCH 0382/1300] feat(Algebra/Homology): the injective derivability structure on the homotopy category (#41063) --- .../DerivabilityStructureInjectives.lean | 311 +++++++++++++++++- .../Homology/Embedding/CochainComplex.lean | 18 + .../Homology/Embedding/IsSupported.lean | 7 + .../Injective/InjectiveObject.lean | 3 + 4 files changed, 323 insertions(+), 16 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean index 4d93315312b95a..d5764ce6531e99 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean @@ -5,9 +5,12 @@ Authors: Joël Riou -/ module +public import Mathlib.Algebra.Homology.DerivedCategory.Plus public import Mathlib.Algebra.Homology.FullSubcategory public import Mathlib.Algebra.Homology.ModelCategory.Injective public import Mathlib.AlgebraicTopology.ModelCategory.DerivabilityStructureFibrant +public import Mathlib.CategoryTheory.GuitartExact.Quotient +public import Mathlib.CategoryTheory.Localization.DerivabilityStructure.Derives public import Mathlib.CategoryTheory.Localization.DerivabilityStructure.OfLocalizedEquivalences public import Mathlib.CategoryTheory.Preadditive.Injective.InjectiveObject @@ -22,18 +25,80 @@ that it is a right derivability structure. (The proof proceeds by showing that up to equivalences of categories, this functor is the inclusion of the full subcategory of fibrant objects in the model category `CochainComplex.Plus C`.) -TODO(@joelriou): obtain similar results for the bounded below homotopy category. +We also obtain a similar right derivability structure `HomotopyCategory.Plus.localizerMorphism` +for the functor `HomotopyCategory.Plus (InjectiveObject C) ⥤ HomotopyCategory.Plus C`, where +the target category is equipped with the class of quasi-isomorphisms while +the source category `HomotopyCategory.Plus (InjectiveObject C)` is equipped +with the class of isomorphisms (which is exactly the same as quasi-isomorphisms). +The consequence is that any functor from the category `HomotopyCategory.Plus C` +has a right derived functor, and we show that the unit natural transformation for +such a derived functor is an isomorphism on objects coming from +`HomotopyCategory.Plus (InjectiveObject C)`. -/ @[expose] public section -open HomotopicalAlgebra CategoryTheory Limits ZeroObject Category +open HomotopicalAlgebra CategoryTheory Limits -variable (C : Type*) [Category* C] [Abelian C] +variable {C H : Type*} [Category* C] [Abelian C] [Category* H] namespace CochainComplex.Plus +instance (X : HomotopyCategory.Plus (InjectiveObject C)) (n : ℤ) : + Injective (((InjectiveObject.ι C).mapHomotopyCategoryPlus.obj X).obj.as.X n) := + inferInstanceAs (Injective ((InjectiveObject.ι C).obj (X.obj.as.X n))) + +set_option backward.defeqAttrib.useBackward true in +instance (K : CochainComplex.Plus (InjectiveObject C)) : + CochainComplex.IsKInjective + (((InjectiveObject.ι C).mapHomologicalComplex (.up ℤ)).obj K.obj) := by + obtain ⟨K, n, hn⟩ := K + let L := ((InjectiveObject.ι C).mapHomologicalComplex (.up ℤ)).obj K + have (n : ℤ) : Injective (L.X n) := by dsimp [L]; infer_instance + exact CochainComplex.isKInjective_of_injective L n + +lemma exists_quasiIso_injective [EnoughInjectives C] + (K : CochainComplex.Plus C) (n : ℤ) [K.obj.IsStrictlyGE n] : + ∃ (L : CochainComplex.Plus (InjectiveObject C)) (_ : L.obj.IsStrictlyGE n) + (i : K ⟶ (InjectiveObject.ι C).mapCochainComplexPlus.obj L), + quasiIso C i := by + obtain ⟨L, i, _, _, _⟩ := modelCategoryQuillen.exists_quasiIso_injective K.obj n + let L' : CochainComplex (InjectiveObject C) ℤ := + HomologicalComplex.liftObjectProperty _ L inferInstance + have hL' : L'.IsStrictlyGE n := by + rwa [← isStrictlyGE_mapHomologicalComplex_obj_iff _ (InjectiveObject.ι _)] + exact ⟨⟨L', n, hL'⟩, hL', ObjectProperty.homMk i, by assumption⟩ + +end CochainComplex.Plus + +namespace DerivedCategory.Plus + +variable [HasDerivedCategory C] + +/-- Let `K` be an object in the bounded below derived category of an abelian category `C` +with enough injectives. Assume that `K` is cohomologically `≥ n`. Then, `K` +admits an "injective resolution", in the sense that there exists a cochain +complex `L` consisting of injective object and lying in degrees `≥ n`, such that `K` +is isomorphic to the image of `L`. -/ +lemma exists_injective_nonempty_iso [EnoughInjectives C] (K : DerivedCategory.Plus C) + (n : ℤ) [K.IsGE n] : + ∃ (L : CochainComplex.Plus (InjectiveObject C)) (_ : L.obj.IsStrictlyGE n), + Nonempty (DerivedCategory.Plus.Q.obj + ((InjectiveObject.ι C).mapCochainComplexPlus.obj L) ≅ K) := by + have : K.obj.IsGE n := (K.isGE_ι_obj_iff n).2 (by assumption) + obtain ⟨L, _, ⟨e⟩⟩ := DerivedCategory.exists_iso_Q_obj_of_isGE K.obj n + obtain ⟨M, _, i, hi⟩ := + CochainComplex.Plus.exists_quasiIso_injective ⟨L, ⟨n, inferInstance⟩⟩ n + have : QuasiIso i.hom := by assumption + exact ⟨M, inferInstance, + ⟨DerivedCategory.Plus.ι.preimageIso ((asIso (DerivedCategory.Q.map i.hom)).symm ≪≫ e.symm)⟩⟩ + +end DerivedCategory.Plus + +namespace CochainComplex.Plus + +variable (C) in /-- The localizer morphism (relative to quasi-isomorphisms) that is given by the "inclusion functor" `CochainComplex.Plus (InjectiveObject C) ⥤ CochainComplex.Plus C`. -/ @@ -59,9 +124,9 @@ instance (K : FibrantObject (Plus C)) (n : ℤ) : Injective (K.obj.obj.X n) := by obtain ⟨K, hK⟩ := K rw [fibrantObjects, modelCategoryQuillen.isFibrant_iff] at hK - dsimp infer_instance +variable (C) in set_option backward.defeqAttrib.useBackward true in /-- The equivalence between `CochainComplex.Plus (InjectiveObject C)` and the category of fibrant object in `CochainComplex.Plus C` for the @@ -77,21 +142,17 @@ def fibrantObjectEquivalence : inverse := ObjectProperty.lift _ (HomologicalComplex.liftFunctorObjectProperty _ (FibrantObject.ι ⋙ Plus.ι C) (fun K n ↦ by dsimp; infer_instance)) (by - rintro ⟨⟨K, n, hn⟩, _⟩ + rintro ⟨⟨_, n, _⟩, _⟩ refine ⟨n, ?_⟩ - rw [isStrictlyGE_iff] - intro i hi - rw [IsZero.iff_id_eq_zero] - ext - apply (K.isZero_of_isStrictlyGE n i hi).eq_of_tgt) + rwa [← isStrictlyGE_mapHomologicalComplex_obj_iff _ (InjectiveObject.ι _)]) unitIso := Iso.refl _ counitIso := Iso.refl _ +variable (C) in /-- The localizer morphism (relative to quasi-isomorphisms) that is given by the equivalence of categories `CochainComplex.Plus (InjectiveObject C) ≌ FibrantObject (CochainComplex.Plus C)`. -/ -@[simps] -def fibrantObjectLocalizerMorphism : +abbrev fibrantObjectLocalizerMorphism : LocalizerMorphism ((quasiIso C).inverseImage (InjectiveObject.ι C).mapCochainComplexPlus) (weakEquivalences (FibrantObject (Plus C))) where functor := (fibrantObjectEquivalence C).functor @@ -100,10 +161,6 @@ def fibrantObjectLocalizerMorphism : instance : (fibrantObjectLocalizerMorphism C).IsInduced where inverseImage_eq := rfl -set_option backward.defeqAttrib.useBackward true in -instance : (fibrantObjectLocalizerMorphism C).functor.IsEquivalence := by - dsimp; infer_instance - set_option backward.isDefEq.respectTransparency false in instance : (localizerMorphism C).IsRightDerivabilityStructure := by rw [LocalizerMorphism.isRightDerivabilityStructure_iff_of_equivalences @@ -119,3 +176,225 @@ instance : (localizerMorphism C).arrow.HasRightResolutions := by infer_instance end CochainComplex.Plus + +namespace HomotopyCategory.Plus + +variable (C) in +/-- The localizer morphism that is given by the "inclusion functor" +`HomotopyCategory.Plus (InjectiveObject C) ⥤ HomotopyCategory.Plus C`. +The target category is equipped with the class of quasi-isomorphisms while +the source category `HomotopyCategory.Plus (InjectiveObject C)` is equipped +with the class of isomorphisms (which is exactly the same as quasi-isomorphisms). -/ +abbrev localizerMorphism : LocalizerMorphism + (MorphismProperty.isomorphisms (HomotopyCategory.Plus (InjectiveObject C))) + (HomotopyCategory.Plus.quasiIso C) where + functor := (InjectiveObject.ι C).mapHomotopyCategoryPlus + map K L f (hf : IsIso f) := by + dsimp only [MorphismProperty.inverseImage, HomotopyCategory.Plus.quasiIso] + rw [HomotopyCategory.mem_quasiIso_iff] + intro n + infer_instance + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma isIso_quotient_map_iff + {K L : CochainComplex.Plus (InjectiveObject C)} (f : K ⟶ L) : + IsIso ((quotient _).map f) ↔ + CochainComplex.Plus.quasiIso C ((InjectiveObject.ι C).mapCochainComplexPlus.map f) := by + rw [← isIso_iff_of_reflects_iso _ (HomotopyCategory.Plus.ι (InjectiveObject C)), + ← isIso_iff_of_reflects_iso _ (Functor.mapHomotopyCategory (InjectiveObject.ι C) (.up ℤ))] + dsimp + rw [HomologicalComplex.isIso_quotient_map_iff_homotopyEquivalences, + ← CochainComplex.IsKInjective.quasiIso_iff] + rfl + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +open HomologicalComplex in +lemma inverseImage_quasiIso_mapCochainComplexPlus_injectiveObjectι : + (CochainComplex.Plus.quasiIso C).inverseImage (InjectiveObject.ι C).mapCochainComplexPlus = + (homotopyEquivalences (InjectiveObject C) (.up ℤ)).inverseImage + (CochainComplex.Plus.ι (InjectiveObject C)) := by + ext K L f + simp [CochainComplex.Plus.quasiIso, Functor.mapCochainComplexPlus, + ← HomologicalComplex.isIso_quotient_map_iff_homotopyEquivalences, + CochainComplex.IsKInjective.quasiIso_iff, + ← isIso_iff_of_reflects_iso _ ((InjectiveObject.ι C).mapHomotopyCategory (.up ℤ))] + +instance : + (HomotopyCategory.Plus.quotient (InjectiveObject C)).IsLocalization + ((CochainComplex.Plus.quasiIso C).inverseImage + (InjectiveObject.ι C).mapCochainComplexPlus) := by + rw [inverseImage_quasiIso_mapCochainComplexPlus_injectiveObjectι] + infer_instance + +set_option backward.isDefEq.respectTransparency false in +open HomologicalComplex in +instance (L : Plus C ⥤ H) [L.IsLocalization (quasiIso C)] : + (quotient C ⋙ L).IsLocalization (CochainComplex.Plus.quasiIso C) := by + refine Functor.IsLocalization.comp _ _ + ((homotopyEquivalences C (.up ℤ)).inverseImage (CochainComplex.Plus.ι C)) + (quasiIso C) _ ?_ ?_ ?_ + · intro _ _ f hf + refine Localization.inverts L (quasiIso C) _ ?_ + simpa [quasiIso, quotient_map_mem_quasiIso_iff] + · intro K L f hf + exact homotopyEquivalences_le_quasiIso _ _ _ hf + · rintro K L f hf + obtain ⟨K, rfl⟩ := Plus.quotient_obj_surjective K + obtain ⟨L, rfl⟩ := Plus.quotient_obj_surjective L + obtain ⟨f, rfl⟩ := (Plus.quotient C).map_surjective f + apply MorphismProperty.map_mem_map + simpa [quasiIso, quotient_map_mem_quasiIso_iff] using! hf + +namespace isRightDerivabilityStructure + +/-! The following private definitions are used to deduce that +`HomotopyCategory.Plus.localizerMorphism` is a right derivability structure +from the fact that `CochainComplex.Plus.localizerMorphism` is. + +The strategy is to observe that the following commutative square +of localizer morphisms gives a Guitart exact square: +``` + CochainComplex.Plus.localizerMorphism C +CochainComplex.Plus (InjectiveObject C) ----------> CochainComplex.Plus C + | | + L C | | R C + v v +HomotopyCategory.Plus (InjectiveObject C) --------> HomotopyCategory.Plus C + HomotopyCategory.Plus.localizerMorphism C +``` +That the square is Guitart exact will follow from the lemma +`TwoSquare.GuitartExact.quotient_of_nonempty_rightHomotopy` +from the file `Mathlib/CategoryTheory/GuitartExact/Quotient.lean`. + +-/ + +open MorphismProperty + +variable (C) in +/-- The left localizer morphism in the Guitart exact square `iso`. -/ +private abbrev L : LocalizerMorphism + ((CochainComplex.Plus.quasiIso C).inverseImage (InjectiveObject.ι C).mapCochainComplexPlus) + (isomorphisms (Plus (InjectiveObject C))) where + functor := HomotopyCategory.Plus.quotient (InjectiveObject C) + map _ _ f hf := (isIso_quotient_map_iff f).2 hf + +private instance : (L C).IsInduced where + inverseImage_eq := by ext; apply isIso_quotient_map_iff + +variable (C) in +set_option backward.isDefEq.respectTransparency false in +/-- The right localizer morphism in the Guitart exact square `iso`. -/ +private abbrev R : LocalizerMorphism (CochainComplex.Plus.quasiIso C) (quasiIso C) where + functor := HomotopyCategory.Plus.quotient C + map _ _ _ _ := by simpa [quasiIso, quotient_map_mem_quasiIso_iff] + +private instance : (R C).IsInduced where + inverseImage_eq := by ext; apply quotient_map_mem_quasiIso_iff + +private instance : (L C).IsLocalizedEquivalence := by + have : + ((L C).functor ⋙ 𝟭 (Plus (InjectiveObject C))).IsLocalization + ((CochainComplex.Plus.quasiIso C).inverseImage + (InjectiveObject.ι C).mapCochainComplexPlus) := + inferInstanceAs ((HomotopyCategory.Plus.quotient (InjectiveObject C)).IsLocalization _) + exact LocalizerMorphism.IsLocalizedEquivalence.of_isLocalization_of_isLocalization (L C) (𝟭 _) + +private instance : (R C).IsLocalizedEquivalence := + LocalizerMorphism.IsLocalizedEquivalence.of_isLocalization_of_isLocalization + (R C) ((quasiIso C).Q) + +variable (C) in +/-- The "commutative" square of functors involving the underlying functors +of the localizer morphisms `CochainComplex.Plus.localizerMorphism C` +and `HomotopyCategory.Plus.localizerMorphism C`. -/ +private def iso : + (CochainComplex.Plus.localizerMorphism C).functor ⋙ (R C).functor ≅ + (L C).functor ⋙ (localizerMorphism C).functor := Iso.refl _ + +set_option backward.defeqAttrib.useBackward true in +open HomologicalComplex CochainComplex in +private instance : TwoSquare.GuitartExact (iso C).hom := + TwoSquare.GuitartExact.quotient_of_nonempty_rightHomotopy (iso C).symm (by + rintro ⟨K₁, n₁, hn₁⟩ ⟨K₂, n₂, hn₂⟩ f₀ f₁ hf + obtain ⟨f₀, rfl⟩ := ObjectProperty.homMk_surjective f₀ + obtain ⟨f₁, rfl⟩ := ObjectProperty.homMk_surjective f₁ + dsimp [Functor.mapCochainComplexPlus] at f₀ f₁ + refine ⟨Plus.prepathObject _, ?_, ⟨?_⟩⟩ + · ext : 1 + exact eq_of_homotopy _ _ (pathObject.homotopy₀₁ _ (fun n ↦ ⟨n + 1, by simp⟩)) + · refine PrepathObject.RightHomotopy.fullSubcategoryEquiv.symm + { h := pathObject.lift f₀ f₁ (homotopyOfEq _ _ + ((HomotopyCategory.Plus.ι C).congr_map hf)) ≫ + (pathObject.mapHomologicalComplexObjIso K₂ (InjectiveObject.ι C) + (fun n ↦ ⟨n + 1, by simp⟩)).inv + h₀ := ?_ + h₁ := ?_ } + all_goals + dsimp [Functor.mapCochainComplexPlus] + cat_disch) + +end isRightDerivabilityStructure + +variable [EnoughInjectives C] + +instance isRightDerivabilityStructure : (localizerMorphism C).IsRightDerivabilityStructure := + LocalizerMorphism.isRightDerivabilityStructure_of_isLocalizedEquivalence + (isRightDerivabilityStructure.iso C) + +instance : (HomotopyCategory.Plus.localizerMorphism C).arrow.HasRightResolutions := + LocalizerMorphism.hasRightResolutions_arrow_of_essSurj_of_full + (isRightDerivabilityStructure.iso C) + +instance [HasDerivedCategory C] : + ((InjectiveObject.ι C).mapHomotopyCategoryPlus ⋙ DerivedCategory.Plus.Qh).EssSurj where + mem_essImage K := by + let r : (HomotopyCategory.Plus.localizerMorphism C).RightResolution + (DerivedCategory.Plus.Qh.objPreimage K) := Classical.arbitrary _ + have := Localization.inverts DerivedCategory.Plus.Qh _ _ r.hw + exact ⟨r.X₁, ⟨(asIso (DerivedCategory.Plus.Qh.map r.w)).symm ≪≫ + DerivedCategory.Plus.Qh.objObjPreimageIso K⟩⟩ + +section + +variable (F : HomotopyCategory.Plus C ⥤ H) + +omit [EnoughInjectives C] in +lemma localizerMorphism_derives : (localizerMorphism C).Derives F := + MorphismProperty.isInvertedBy_isomorphisms _ + +/-- Any functor from the bounded below homotopy category has a right derived functor +with respect to quasi-isomorphisms. -/ +instance : F.HasPointwiseRightDerivedFunctor (HomotopyCategory.Plus.quasiIso C) := + (localizerMorphism_derives F).hasPointwiseRightDerivedFunctor + +variable [HasDerivedCategory C] (F' : DerivedCategory.Plus C ⥤ H) + (α : F ⟶ DerivedCategory.Plus.Qh ⋙ F') + [F'.IsRightDerivedFunctor α (HomotopyCategory.Plus.quasiIso C)] + +instance (K : HomotopyCategory.Plus C) [(∀ (n : ℤ), Injective (K.obj.as.X n))] : + IsIso (α.app K) := by + have (Y : HomotopyCategory.Plus (InjectiveObject C)) : + IsIso (α.app ((InjectiveObject.ι C).mapHomotopyCategoryPlus.obj Y)) := + (localizerMorphism_derives F).isIso_of_isRightDerivedFunctor _ _ + obtain ⟨Y, ⟨e⟩⟩ : (InjectiveObject.ι C).mapHomotopyCategoryPlus.essImage K := by + obtain ⟨X, hX⟩ := K + obtain ⟨K, rfl⟩ := HomotopyCategory.quotient_obj_surjective X + refine ⟨(quotient _).obj + ((CochainComplex.Plus.fibrantObjectEquivalence C).inverse.obj + ⟨⟨K, by simpa using hX⟩, ?_⟩), ⟨Iso.refl _⟩⟩ + dsimp [fibrantObjects] + rwa [CochainComplex.Plus.modelCategoryQuillen.isFibrant_iff] + rw [← NatTrans.isIso_app_iff_of_iso α e] + infer_instance + +example (X : HomotopyCategory.Plus (InjectiveObject C)) : + IsIso ((F.totalRightDerivedUnit DerivedCategory.Plus.Qh + (HomotopyCategory.Plus.quasiIso C)).app + ((InjectiveObject.ι C).mapHomotopyCategoryPlus.obj X)) := by + infer_instance + +end + +end HomotopyCategory.Plus diff --git a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean index ae06df80b4d34b..ad35d9c62b186f 100644 --- a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean +++ b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean @@ -313,6 +313,24 @@ lemma quasiIso_truncLEMap_iff : end +section + +variable {D : Type*} [Category* D] [HasZeroMorphisms D] + +lemma isStrictlyGE_mapHomologicalComplex_obj_iff + (F : C ⥤ D) [F.Faithful] [F.PreservesZeroMorphisms] (n : ℤ) : + CochainComplex.IsStrictlyGE ((F.mapHomologicalComplex (.up ℤ)).obj K) n ↔ + K.IsStrictlyGE n := + isStrictlySupported_mapHomologicalComplex_obj_iff .. + +lemma isStrictlyLE_mapHomologicalComplex_obj_iff + (F : C ⥤ D) [F.Faithful] [F.PreservesZeroMorphisms] (n : ℤ) : + CochainComplex.IsStrictlyLE ((F.mapHomologicalComplex (.up ℤ)).obj K) n ↔ + K.IsStrictlyLE n := + isStrictlySupported_mapHomologicalComplex_obj_iff .. + +end + end HasZeroMorphisms section Preadditive diff --git a/Mathlib/Algebra/Homology/Embedding/IsSupported.lean b/Mathlib/Algebra/Homology/Embedding/IsSupported.lean index 9a1987a6598c4e..9f7fbefa73e179 100644 --- a/Mathlib/Algebra/Homology/Embedding/IsSupported.lean +++ b/Mathlib/Algebra/Homology/Embedding/IsSupported.lean @@ -161,6 +161,13 @@ instance map_isStrictlySupported [K.IsStrictlySupported e] : dsimp rw [← F.map_id, (K.isZero_X_of_isStrictlySupported e i' hi').eq_of_src (𝟙 _) 0, F.map_zero] +lemma isStrictlySupported_mapHomologicalComplex_obj_iff [F.Faithful] : + ((F.mapHomologicalComplex c').obj K).IsStrictlySupported e ↔ K.IsStrictlySupported e := by + refine ⟨fun _ ↦ ⟨fun i' hi' ↦ ?_⟩, fun _ ↦ inferInstance⟩ + rw [IsZero.iff_id_eq_zero] + exact F.map_injective ((isZero_X_of_isStrictlySupported + ((F.mapHomologicalComplex c').obj K) e i' hi').eq_of_src _ _) + end end HomologicalComplex diff --git a/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean b/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean index ddbe6ccb6f79dd..d8955a1baf21ae 100644 --- a/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean +++ b/Mathlib/CategoryTheory/Preadditive/Injective/InjectiveObject.lean @@ -44,6 +44,9 @@ instance [HasFiniteProducts C] : HasFiniteProducts (InjectiveObject C) where instance [Preadditive C] [HasFiniteProducts C] : HasFiniteBiproducts (InjectiveObject C) := HasFiniteBiproducts.of_hasFiniteProducts +instance [Preadditive C] [HasBinaryBiproducts C] : HasBinaryBiproducts (InjectiveObject C) := + HasBinaryBiproducts.of_hasBinaryProducts + instance [HasZeroMorphisms C] [HasZeroObject C] : (isInjective C).ContainsZero where exists_zero := ⟨0, by simp [IsZero.iff_id_eq_zero], Injective.zero_injective⟩ From cce5343a273fb368713331e6b357cdf9d79cd2cb Mon Sep 17 00:00:00 2001 From: Michael Stoll <99838730+MichaelStollBayreuth@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:09:41 +0000 Subject: [PATCH 0383/1300] feat(NumberTheory/Height/NumberField): Northcott property (#39744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR finally adds a proof of the *Northcott property* for heights on number fields: ```lean theorem NumberField.finite_setOf_mulHeight₁_le (B : ℝ) : {x : K | mulHeight₁ x ≤ B}.Finite ``` Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/NumberTheory/Height/NumberField.lean | 224 ++++++++++++++++++- 1 file changed, 222 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/Height/NumberField.lean b/Mathlib/NumberTheory/Height/NumberField.lean index 3c154daa059b4d..852c8132ed30e9 100644 --- a/Mathlib/NumberTheory/Height/NumberField.lean +++ b/Mathlib/NumberTheory/Height/NumberField.lean @@ -5,8 +5,9 @@ Authors: Michael Stoll, Ralf Stephan -/ module -public import Mathlib.NumberTheory.NumberField.ProductFormula public import Mathlib.NumberTheory.Height.Basic +public import Mathlib.NumberTheory.Height.Northcott +public import Mathlib.NumberTheory.NumberField.ProductFormula import Mathlib.Algebra.FiniteSupport.Basic import Mathlib.Algebra.Order.Hom.Lattice @@ -19,6 +20,14 @@ import Mathlib.NumberTheory.NumberField.InfinitePlace.TotallyRealComplex We provide an instance of `Height.AdmissibleAbsValues` for algebraic number fields and set up some API. +## Main results + +* Heights on number fields satisfy the **Northcott property**: If `K` is a number field, + then the set of elements of `K` of bounded (multiplicative or logarithmic) height is finite; + see `NumberField.finite_setOf_mulHeight₁_le` and `NumberField.finite_setOf_logHeight₁_le`. + We also provide instances for `Northcott (mulHeight₁ (K := K))` (which automatically leads + also to `Northcott (logHeight₁ (K := K))`). + ## TODO When this file gets long, split the material on heights over `ℚ` off into a file `Rat.lean`. @@ -96,7 +105,6 @@ lemma sum_nonarchAbsVal_eq {M : Type*} [AddCommMonoid M] (f : AbsoluteValue K (∑ᶠ v : nonarchAbsVal, f v.val) = ∑ᶠ v : FinitePlace K, f v.val := rfl - /-- This is the familiar definition of the multiplicative height on a number field. -/ lemma mulHeight₁_eq (x : K) : mulHeight₁ x = @@ -184,6 +192,218 @@ lemma absNorm_mul_finprod_finitePlace_eq_one (hx : x ≠ 0) : end NumberField +/-! +### The Northcott property for heights on number fields + +We show that a number field `K` has the **Northcott property** with respect to the multiplicative +and with respect to the logarithmic height, i.e., for any `B : ℝ` the set of elements `x : K` +such that `mulHeight₁ x ≤ B` (resp., `logHeight₁ x ≤ B`) is finite. +See `NumberField.finite_setOf_mulHeight₁_le` and `NumberField.finite_setOf_logHeight₁_le`. + +The main idea of the proof is as follows. We show that for every `x : K` there is `n : ℕ` such that +`n * x` is an algebraic integer and `n ≤ mulHeight₁ x`; see `NumberField.exists_nat_le_mulHeight₁`. +We also show that the set of `a : 𝓞 K` such that `mulHeight₁ (a / n)` is bounded is finite; +see `NumberField.finite_setOf_prod_infinitePlace_iSup_le`. The result for the multiplicative height +follows by combining these two ingredients, and the result for the logarithmic height follows +from that for any field with a family of admissible absolute values +(see `Mathlib.NumberTheory.Height.Northcott`). +-/ + +section Northcott + +namespace NumberField + +variable {K : Type*} [Field K] [NumberField K] + +section withIdeal + +open Ideal + +private lemma relIndex_span_span_nat_mul (m : ℕ) {n : ℕ} (hn : n ≠ 0) (a : 𝓞 K) : + (span {(m : 𝓞 K)}).toAddSubgroup.relIndex (span {↑m, a}).toAddSubgroup = + (span {(n * m : 𝓞 K)}).toAddSubgroup.relIndex (span {↑(n * m), n * a}).toAddSubgroup := by + let f : 𝓞 K →ₗ[𝓞 K] 𝓞 K := .mulLeft _ n + have hf : Function.Injective (f : 𝓞 K →+ 𝓞 K) := + (injective_iff_map_eq_zero f).mpr fun _ _ ↦ by simp_all [f] + have H₁ : span {(n * m : 𝓞 K)} = Submodule.map f (span {↑m}) := by + simp [LinearMap.map_span, f] + have H₂ : span {↑(n * m), n * a} = Submodule.map f (span {↑m, a}) := by + simp [LinearMap.map_span, f, Set.image_pair] + rw [H₁, H₂] + exact AddSubgroup.relIndex_map_map_of_injective _ _ hf |>.symm + +private lemma relIndex_span_span_eq_relIndex_span_span {m n : ℕ} (hm : m ≠ 0) (hn : n ≠ 0) + {a b : 𝓞 K} (h : n * a = m * b) : + (span {(m : 𝓞 K)}).toAddSubgroup.relIndex (span {↑m, a}).toAddSubgroup = + (span {(n : 𝓞 K)}).toAddSubgroup.relIndex (span {↑n, b}).toAddSubgroup := by + refine (relIndex_span_span_nat_mul m hn a).trans ?_ + rw [mul_comm, mul_comm n, h] + exact (relIndex_span_span_nat_mul n hm b).symm + +open Module AddSubgroup LinearMap in +lemma exists_nat_ne_zero_exists_integer_mul_eq_and_absNorm_span_eq_pow (x : K) : + ∃ n : ℕ, n ≠ 0 ∧ ∃ a : 𝓞 K, n * x = a ∧ + (span {(n : 𝓞 K), a}).absNorm = n ^ (Module.finrank ℚ K - 1) := by + have hx : IsAlgebraic ℤ x := IsFractionRing.isAlgebraic_iff ℤ _ _ |>.mpr (.of_finite ℚ x) + obtain ⟨m, r, hm, hmr⟩ := hx.exists_nsmul_eq (𝓞 K) + rw [← RingOfIntegers.coe_eq_algebraMap r] at hmr + set n := (span {(m : 𝓞 K)}).toAddSubgroup.relIndex (span {(m : 𝓞 K), r}).toAddSubgroup with hndef + have hn : n ≠ 0 := isFiniteRelIndex (by simp [hm]) _ |>.relIndex_ne_zero + obtain ⟨a, ha'⟩ : ∃ a, m * a = n * r := by + have : n • r ∈ span {(m : 𝓞 K)} := + (span {(m : 𝓞 K)}).toAddSubgroup.nsmul_relIndex_mem <| Submodule.mem_span_of_mem <| by grind + simpa [mem_span_singleton', mul_comm] using this + have ha : n * x = a := by + refine mul_left_cancel₀ (mod_cast hm : (m : K) ≠ 0) ?_ + rw [mul_left_comm, ← nsmul_eq_mul m, hmr] + exact_mod_cast ha'.symm + refine ⟨n, hn, a, ha, mul_left_cancel₀ hn ?_⟩ + nth_rewrite 1 [hndef] + rw [absNorm_eq_index, mul_pow_sub_one finrank_pos.ne', ← RingOfIntegers.rank, + ← absNorm_span_natCast, absNorm_eq_index, ← relIndex_span_span_eq_relIndex_span_span hn hm ha'] + exact relIndex_mul_index <| Submodule.toAddSubgroup_mono <| span_mono <| by grind + +open Height in +private lemma one_le_pow_totalWeight_mul_finprod {n : ℕ} (hn : n ≠ 0) (a : 𝓞 K) : + 1 ≤ (n ^ totalWeight K : ℝ) * ∏ᶠ (v : FinitePlace K), ⨆ i, v (![↑a, ↑n] i) := by + have Hw : (0 : ℝ) < n ^ totalWeight K := by positivity + rw_mod_cast [totalWeight_eq_finrank, ← RingOfIntegers.rank, ← absNorm_span_natCast] at Hw ⊢ + rw [← absNorm_mul_finprod_finitePlace_eq_one (show ![a, n] ≠ 0 by simp [hn])] + gcongr + · exact finprod_nonneg fun _ ↦ Real.iSup_nonneg_of_nonnegHomClass .. + · exact Nat.le_of_dvd Hw <| absNorm_dvd_absNorm_of_le <| span_mono <| by simp + · apply le_of_eq; congr; ext; congr; ext i; fin_cases i <;> simp + +end withIdeal + +open Height + +section withFinset + +open Finset + +/-- If `x : K` (for a number field `K`), then we can find a nonzero `n : ℕ` such that +`n ≤ mulHeight₁ x` and `n * x` is integral. I.e., the denominator of `x` can be bounded by +its multplicative height. -/ +-- TODO: Use this to show `natDenominator x ≤ mulHeight₁ x` once #39872 is merged. +lemma exists_nat_le_mulHeight₁ (x : K) : + ∃ n : ℕ, n ≠ 0 ∧ n ≤ mulHeight₁ x ∧ IsIntegral ℤ (n * x) := by + obtain ⟨n, hn, a, ha₁, ha₂⟩ := exists_nat_ne_zero_exists_integer_mul_eq_and_absNorm_span_eq_pow x + refine ⟨n, hn, ?_, ha₁ ▸ a.isIntegral_coe⟩ + rw [← totalWeight_eq_finrank] at ha₂ + have hv (i : Fin 2) : (![a, n] i : K) = ![(a : K), n] i := by fin_cases i <;> rfl + rw [← mul_div_cancel_left₀ x (mod_cast hn : (n : K) ≠ 0), ha₁, mulHeight₁_div_eq_mulHeight, + mulHeight_eq (by simp [hn])] + refine le_of_mul_le_mul_left ?_ (show (0 : ℝ) < n ^ (totalWeight K - 1) by positivity) + have : n ^ (totalWeight K - 1) * ∏ᶠ (v : FinitePlace K), ⨆ i, v (![(a : K), n] i) = 1 := by + simpa [ha₂, hv] using absNorm_mul_finprod_finitePlace_eq_one (show ![a, n] ≠ 0 by simp [hn]) + rw [pow_sub_one_mul (totalWeight_pos K).ne', mul_left_comm, this, mul_one, + totalWeight_eq_sum_mult, ← prod_pow_eq_pow_sum univ] + gcongr + exact Finite.le_ciSup_of_le 1 <| by simp + +private lemma pow_totalWeight_sub_one_eq [DecidableEq (InfinitePlace K)] {n : ℕ} (hn : n ≠ 0) + (v : InfinitePlace K) : + (n ^ (totalWeight K - 1) : ℝ) = (∏ w ∈ univ.erase v, (n ^ w.mult : ℝ)) * n ^ (v.mult - 1) := by + refine mul_right_cancel₀ (b := (n : ℝ)) (mod_cast hn) ?_ + rw [pow_sub_one_mul (totalWeight_pos K).ne', totalWeight_eq_sum_mult, ← prod_pow_eq_pow_sum, + ← prod_erase_mul _ _ (mem_univ v), ← pow_sub_one_mul v.mult_ne_zero, ← mul_assoc] + +private lemma infinitePlace_apply_le_of_prod_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) {x : 𝓞 K} + (h : ∏ v : InfinitePlace K, (⨆ i, v (![(x : K), n] i)) ^ v.mult ≤ B) (v : InfinitePlace K) : + v x ≤ B / n ^ (totalWeight K - 1) := by + classical + rw [le_div_iff₀' (by positivity)] + calc + _ ≤ n ^ (totalWeight K - 1) * ⨆ i, v (![(x : K), n] i) := by + gcongr; exact Finite.le_ciSup_of_le 0 le_rfl + _ ≤ (∏ v' ∈ univ.erase v, (⨆ i, v' (![↑x, ↑n] i)) ^ v'.mult) * + (⨆ i, v (![↑x, ↑n] i)) ^ (v.mult - 1) * ⨆ i, v (![(x : K), n] i) := by + rw [pow_totalWeight_sub_one_eq hn] + gcongr + · exact Real.iSup_nonneg_of_nonnegHomClass .. + · exact prod_nonneg fun _ _ ↦ pow_nonneg (Real.iSup_nonneg_of_nonnegHomClass ..) _ + all_goals exact Finite.le_ciSup_of_le 1 <| by simp + _ ≤ B := by + rwa [mul_assoc, pow_sub_one_mul v.mult_ne_zero, prod_erase_mul _ _ (mem_univ v)] + +end withFinset + +lemma finite_setOf_prod_infinitePlace_iSup_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : + {x : 𝓞 K | ∏ v : InfinitePlace K, (⨆ i, v (![(x : K), n] i)) ^ v.mult ≤ B}.Finite := by + set B' := B / n ^ (totalWeight K - 1) + suffices Set.BijOn ((↑) : 𝓞 K → K) {x | ∀ (v : InfinitePlace K), v x ≤ B'} + {x | IsIntegral ℤ x ∧ ∀ (φ : K →+* ℂ), ‖φ x‖ ≤ B'} from + this.finite_iff_finite.mpr (Embeddings.finite_of_norm_le K ℂ B') |>.subset + fun _ _ ↦ by grind [infinitePlace_apply_le_of_prod_le hn B] + refine .mk (fun x hx ↦ ?_) (fun _ _ _ _ ↦ RingOfIntegers.ext) fun a ha ↦ ?_ <;> + simp only [Set.mem_image, Set.mem_setOf_eq] at * + · exact ⟨x.isIntegral_coe, fun φ ↦ hx <| .mk φ⟩ + · rw [← mem_integralClosure_iff ℤ K] at ha + exact ⟨⟨a, ha.1⟩, fun v ↦ v.norm_embedding_eq a ▸ ha.2 v.embedding, rfl⟩ + +/-- The set of `a : 𝓞 K` such that `mulHeight₁ (a / n) = mulHeight ![a, n]` is bounded +(for some given nonzero `n : ℕ`) is finite. -/ +lemma finite_setOf_mulHeight_nat_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : + {a : 𝓞 K | mulHeight ![(a : K), n] ≤ B}.Finite := by + suffices {a : 𝓞 K | mulHeight ![(a : K), n] ≤ B} ⊆ + {a | ∏ v : InfinitePlace K, (⨆ i, v (![(a : K), n] i)) ^ v.mult ≤ n ^ totalWeight K * B} from + (finite_setOf_prod_infinitePlace_iSup_le hn _).subset this + refine Set.setOf_subset_setOf_of_imp fun a ha ↦ ?_ + rw [mulHeight_eq <| by simp [hn], mul_comm] at ha + grw [← ha, ← mul_assoc, ← one_le_pow_totalWeight_mul_finprod hn, one_mul] + -- nonnegativity side goal + exact Finset.prod_nonneg fun _ _ ↦ pow_nonneg (Real.iSup_nonneg_of_nonnegHomClass ..) _ + +variable (K) in +/- The set of `x : K` such that `mulHeight₁ x` is bounded and `n * x` is integral +(for some given nonzero `n : ℕ`) is finite. +This is a stepping stone for the proof of the next result, which is strictly stronger. -/ +private lemma finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : + {x : K | IsIntegral ℤ (n * x) ∧ mulHeight₁ x ≤ B}.Finite := by + have hn' : (n : K) ≠ 0 := mod_cast hn + suffices Set.BijOn (fun a : 𝓞 K ↦ (a / n : K)) {a | mulHeight ![(a : K), n] ≤ B} + {x | IsIntegral ℤ (n * x) ∧ mulHeight₁ x ≤ B} from + this.finite_iff_finite.mp <| finite_setOf_mulHeight_nat_le hn B + refine .mk (fun a ha ↦ ?_) (fun a _ b _ h ↦ ?_) fun x ⟨hx₁, hx₂⟩ ↦ ?_ + · simp only [Set.mem_setOf_eq] at ha ⊢ + rw [mul_div_cancel₀ (a : K) hn', mulHeight₁_div_eq_mulHeight] + exact ⟨a.isIntegral_coe, ha⟩ + · rwa [div_left_inj' hn', RingOfIntegers.eq_iff] at h + · simp only [Set.mem_setOf_eq, Set.mem_image] + obtain ⟨a, ha⟩ : ∃ a : 𝓞 K, n * x = a := ⟨⟨_, hx₁⟩, rfl⟩ + refine ⟨a, ?_, (EuclideanDomain.eq_div_of_mul_eq_right hn' ha).symm⟩ + rwa [← ha, ← mulHeight₁_div_eq_mulHeight, mul_div_cancel_left₀ x hn'] + +variable (K) in +/-- A number field `K` satisfies the **Northcott property**: +The set of elements of bounded multiplicative height is finite. -/ +theorem finite_setOf_mulHeight₁_le (B : ℝ) : {x : K | mulHeight₁ x ≤ B}.Finite := by + have H : {x : K | mulHeight₁ x ≤ B} = + ⋃ n : Fin ⌊B⌋₊, {x : K | IsIntegral ℤ ((n + 1) * x) ∧ mulHeight₁ x ≤ B} := by + ext x : 1 + obtain ⟨n, hn₀, hn₁, hn⟩ := exists_nat_le_mulHeight₁ x + simp only [Set.mem_setOf_eq, Set.mem_iUnion, exists_and_right, iff_and_self] + refine fun h ↦ ⟨⟨n - 1, by grind [Nat.le_floor <| hn₁.trans h]⟩, ?_⟩ + rwa [← Nat.cast_add_one, Nat.sub_one_add_one hn₀] + rw [H] + exact Set.finite_iUnion fun n ↦ + mod_cast finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le K (Nat.zero_ne_add_one n).symm B + +instance : Northcott (mulHeight₁ (K := K)) where + finite_le := finite_setOf_mulHeight₁_le K + +variable (K) in +/-- A number field `K` satisfies the **Northcott property**: +The set of elements of bounded logarithmic height is finite. -/ +theorem finite_setOf_logHeight₁_le (B : ℝ) : + {x : K | logHeight₁ x ≤ B}.Finite := + Northcott.finite_le B + +end NumberField + +end Northcott + /-! ### Positivity extension for totalWeight on number fields -/ From 96b5d752df4a2a4e43850cecf0b21cb0598605b4 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Fri, 26 Jun 2026 12:17:48 +0000 Subject: [PATCH 0384/1300] feat: add zeta_sub_one_dvd_intCast_iff and related declarations (#40232) --- .../NumberField/Cyclotomic/Ideal.lean | 15 +++++++++++++++ .../RingTheory/RootsOfUnity/CyclotomicUnits.lean | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 59947f078ff144..af04ef34127885 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -72,6 +72,14 @@ theorem associated_norm_zeta_sub_one : Associated (Algebra.norm ℤ (hζ.toInteg rw [hζ.norm_toInteger_sub_one_of_eq_two_pow, h, Int.ofNat_two] · rw [hζ.norm_toInteger_sub_one_of_prime_ne_two h] +/-- An integer `n` is divisible by `ζ - 1` in `𝓞 K` if and only if it is divisible by `p`, +where `ζ` is a primitive `p ^ (k + 1)`-th root of unity. -/ +theorem zeta_sub_one_dvd_intCast_iff {n : ℤ} : + hζ.toInteger - 1 ∣ (n : 𝓞 K) ↔ (p : ℤ) ∣ n := by + have h := associated_norm_zeta_sub_one p k hζ + rw [← Ideal.norm_dvd_iff (h.symm.prime (Nat.prime_iff_prime_int.mp hp.out))] + exact h.dvd_iff_dvd_left + theorem absNorm_span_zeta_sub_one : absNorm (span {hζ.toInteger - 1}) = p := by simpa using congr_arg absNorm <| span_singleton_eq_span_singleton.mpr <| associated_norm_zeta_sub_one p k hζ @@ -231,6 +239,13 @@ theorem ramificationIdx_span_zeta_sub_one' : rw [← pow_one p] at hK hζ rw [ramificationIdx_span_zeta_sub_one p 0 hζ, pow_zero, one_mul] +/-- An integer `n` is divisible by `ζ - 1` in `𝓞 K` if and only if it is divisible by `p`, +where `ζ` is a primitive `p`-th root of unity. -/ +theorem zeta_sub_one_dvd_intCast_iff' {n : ℤ} : + hζ.toInteger - 1 ∣ (n : 𝓞 K) ↔ (p : ℤ) ∣ n := by + rw [← pow_one p] at hK hζ + exact zeta_sub_one_dvd_intCast_iff p 0 hζ + variable (K) include hK in diff --git a/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean b/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean index fc7e3eb66e9157..2b2c98494c996d 100644 --- a/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean +++ b/Mathlib/RingTheory/RootsOfUnity/CyclotomicUnits.lean @@ -150,6 +150,16 @@ lemma nthRootsFinset_pairwise_associated_sub_one_sub_of_prime (hζ : IsPrimitive alias ntRootsFinset_pairwise_associated_sub_one_sub_of_prime := nthRootsFinset_pairwise_associated_sub_one_sub_of_prime +/-- If `p` is prime and `ζ` is a `p`-th primitive root of unity, then `ζ - 1` divides `η₁ - η₂` +for all `p`-th roots of unity `η₁` and `η₂`. -/ +lemma sub_one_dvd_sub (hζ : IsPrimitiveRoot ζ p) (hp : p.Prime) + {η₁ : A} (hη₁ : η₁ ∈ nthRootsFinset p (1 : A)) + {η₂ : A} (hη₂ : η₂ ∈ nthRootsFinset p (1 : A)) : + ζ - 1 ∣ η₁ - η₂ := by + rcases eq_or_ne η₁ η₂ with rfl | h + · simp + · exact (hζ.nthRootsFinset_pairwise_associated_sub_one_sub_of_prime hp hη₁ hη₂ h).dvd + /-- Given an `n`-th primitive root of unity `ζ`, where `1 < n`, we have that `ζ - 1` divides `n`. In particular, if `ζ` is a `p`-th primitive root of unity with `p` prime, then `ζ - 1` divides `p`. -/ From 7e24eee7495b5b71447e07ce99c7d2dfedd09702 Mon Sep 17 00:00:00 2001 From: Luigi Massacci <48868075+luigi-massacci@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:17:50 +0000 Subject: [PATCH 0385/1300] feat: the space of Schwartz maps is T3 (#40931) Proves that the space of Schwartz functions is T2. The proof is basically a copy-paste of the same proof for `TestFunction`. Thanks to @BenKBreen for pointing out this was missing. Co-Authored by: Luigi Massacci @luigimassacci-ax Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean index 8216465d129539..6246742ddac1b8 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean @@ -1202,6 +1202,15 @@ theorem toBoundedContinuousFunctionCLM_apply (f : 𝓢(E, F)) (x : E) : toBoundedContinuousFunctionCLM 𝕜 E F f x = f x := rfl +theorem toBoundedContinuousFunctionCLM_injective : + Function.Injective (toBoundedContinuousFunctionCLM .. : 𝓢(E, F) →L[𝕜] E →ᵇ F) := + fun _ _ h ↦ DFunLike.ext _ _ fun x ↦ DFunLike.congr_fun h x + +instance : T3Space 𝓢(E, F) := + suffices T2Space 𝓢(E, F) from inferInstance + .of_injective_continuous (toBoundedContinuousFunctionCLM_injective ℝ ..) + (ContinuousLinearMap.continuous _) + end BoundedContinuousFunction section ZeroAtInfty From 8afd8c533914c66035fbf86679b10d75536bc294 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:17:52 +0000 Subject: [PATCH 0386/1300] feat(CategoryTheory/Preadditive/AdditiveFunctor): finite products in a quotient preadditive category (#41067) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove that, if `F : C ⥤ D` is an additive essentially surjective functor between preadditive categories and `C` has finite products, then `D` also has finite products. Use this to shorten the proof that the localization of an abelian category by a Serre class has finite products (in `CategoryTheory/Abelian/SerreClass/Localization`). Co-authored-by: morel --- .../Abelian/SerreClass/Localization.lean | 24 +++++++------------ .../Preadditive/AdditiveFunctor.lean | 6 +++++ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean b/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean index f92126f9c75b86..6c7b58e5c62803 100644 --- a/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean +++ b/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean @@ -5,10 +5,9 @@ Authors: Joël Riou -/ module +public import Mathlib.Algebra.Homology.ShortComplex.ExactFunctor public import Mathlib.CategoryTheory.Abelian.SerreClass.MorphismProperty public import Mathlib.CategoryTheory.Localization.CalculusOfFractions.Preadditive -public import Mathlib.Algebra.Homology.ShortComplex.ExactFunctor -public import Mathlib.CategoryTheory.Limits.ExactFunctor /-! # Localization with respect to a Serre class @@ -29,7 +28,7 @@ universe v'' v' v u'' u' u namespace CategoryTheory -open Limits ZeroObject +open Limits namespace ObjectProperty @@ -139,9 +138,6 @@ lemma isZero_obj_iff (X : C) : rintro ⟨Y, h⟩ simpa using h.2 -lemma hasZeroObject : HasZeroObject D := - ⟨L.obj 0, by simpa [isZero_obj_iff L P] using P.prop_zero⟩ - lemma map_eq_zero_iff {X Y : C} (f : X ⟶ Y) : L.map f = 0 ↔ P (Abelian.image f) := by rw [← L.map_zero, MorphismProperty.map_eq_iff_precomp L P.isoModSerre] @@ -381,17 +377,9 @@ lemma hasCoequalizers : HasCoequalizers D := Preadditive.hasCoequalizer_of_hasCokernel _ _ hasCoequalizers_of_hasColimit_parallelPair _ -lemma hasBinaryProducts : HasBinaryProducts D := - have := Localization.essSurj L P.isoModSerre - have (X Y : D) : HasBinaryProduct X Y := - hasLimit_of_iso (show Limits.pair _ _ ≅ _ from - mapPairIso (L.objObjPreimageIso X) (L.objObjPreimageIso Y)) - hasBinaryProducts_of_hasLimit_pair D - lemma hasFiniteProducts : HasFiniteProducts D := - have := hasZeroObject L P - have := hasBinaryProducts L P - hasFiniteProducts_of_has_binary_and_terminal + have := Localization.essSurj L P.isoModSerre + L.hasFiniteProducts_of_additive_of_essSurj lemma isNormalMonoCategory : IsNormalMonoCategory D where normalMonoOfMono f hf := by @@ -438,6 +426,10 @@ def abelian : Abelian D := by have := isNormalEpiCategory L P constructor +lemma hasZeroObject : HasZeroObject D := + have := abelian L P + Abelian.hasZeroObject + lemma preservesFiniteLimits : PreservesFiniteLimits L := by letI := abelian L P rw [((Functor.preservesFiniteLimits_tfae L).out 3 2 :)] diff --git a/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean b/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean index 364ab457c95d6e..c8554346bf6ea6 100644 --- a/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean +++ b/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean @@ -218,6 +218,12 @@ instance (priority := 100) preservesFiniteProductsOfAdditive [Additive F] : PreservesFiniteProducts F where preserves _ := preservesProductsOfShape_of_preservesBiproductsOfShape F +lemma hasFiniteProducts_of_additive_of_essSurj [HasFiniteProducts C] [Additive F] + [EssSurj F] : HasFiniteProducts D := + ⟨fun _ ↦ ⟨fun K ↦ hasLimit_of_iso + (F := Discrete.functor (fun i ↦ F.objPreimage (K.obj ⟨i⟩)) ⋙ F) + (Discrete.natIso (fun _ ↦ F.objObjPreimageIso _))⟩⟩ + theorem additive_of_preservesBinaryBiproducts [HasBinaryBiproducts C] [PreservesZeroMorphisms F] [PreservesBinaryBiproducts F] : Additive F where map_add {X Y f g} := by From 44ae7119e3a75cd737b4063c240db888c57fb7fd Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:32:05 +0000 Subject: [PATCH 0387/1300] feat(RingTheory/MvPowerSeries/Trunc): generalize truncation lemmas (#39625) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalize `coeff_trunc_mul_trunc_eq_coeff_mul` (and its analogs for `truncFinset` and `trunc'`) to allow for different truncation levels for the two arguments. This matches the API for univariate power series, where we already have `PowerSeries.coeff_mul_eq_coeff_trunc_mul_trunc₂`. This is useful for defining partial derivatives of multivariate power series, see PR #39626. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/RingTheory/MvPowerSeries/Trunc.lean | 46 +++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean index 2816b558c8d744..0f01f106605e17 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean @@ -126,16 +126,24 @@ theorem truncFinset_map [CommSemiring S] (f : R →+* S) (p : MvPowerSeries σ R ext x by_cases x ∈ s <;> grind [coeff_map, MvPolynomial.coeff_map] -theorem coeff_truncFinset_mul_truncFinset_eq_coeff_mul (hs : IsLowerSet (s : Set (σ →₀ ℕ))) - {x : σ →₀ ℕ} (f g : MvPowerSeries σ R) (hx : x ∈ s) : - (truncFinset R s f * truncFinset R s g).coeff x = coeff x (f * g) := by +/-- A coefficient of a product of finset-truncated power series equals the coefficient of the +untruncated product, with the two truncation finsets `s` and `t` allowed to differ. -/ +theorem coeff_truncFinset_mul_truncFinset_eq_coeff_mul₂ {t : Finset (σ →₀ ℕ)} + (hs : IsLowerSet (s : Set (σ →₀ ℕ))) (ht : IsLowerSet (t : Set (σ →₀ ℕ))) + {x : σ →₀ ℕ} (f g : MvPowerSeries σ R) (hxs : x ∈ s) (hxt : x ∈ t) : + (truncFinset R s f * truncFinset R t g).coeff x = coeff x (f * g) := by classical simp only [MvPowerSeries.coeff_mul, MvPolynomial.coeff_mul] apply sum_congr rfl rintro ⟨i, j⟩ hij simp only [mem_antidiagonal] at hij - rw [coeff_truncFinset_of_mem _ (hs (show i ≤ x by simp [← hij]) hx), - coeff_truncFinset_of_mem _ (hs (show j ≤ x by simp [← hij]) hx)] + rw [coeff_truncFinset_of_mem _ (hs (show i ≤ x by simp [← hij]) hxs), + coeff_truncFinset_of_mem _ (ht (show j ≤ x by simp [← hij]) hxt)] + +theorem coeff_truncFinset_mul_truncFinset_eq_coeff_mul (hs : IsLowerSet (s : Set (σ →₀ ℕ))) + {x : σ →₀ ℕ} (f g : MvPowerSeries σ R) (hx : x ∈ s) : + (truncFinset R s f * truncFinset R s g).coeff x = coeff x (f * g) := + coeff_truncFinset_mul_truncFinset_eq_coeff_mul₂ hs hs f g hx hx theorem truncFinset_truncFinset_pow (hs : IsLowerSet (s : Set (σ →₀ ℕ))) {k : ℕ} (hk : 1 ≤ k) (p : MvPowerSeries σ R) : truncFinset R s ((truncFinset R s p) ^ k) = @@ -200,6 +208,21 @@ theorem trunc_C_mul (n : σ →₀ ℕ) (a : R) (p : MvPowerSeries σ R) : theorem trunc_map [CommSemiring S] (n : σ →₀ ℕ) (f : R →+* S) (p : MvPowerSeries σ R) : trunc S n (map f p) = MvPolynomial.map f (trunc R n p) := truncFinset_map f p +/-- A coefficient of a product of truncated power series equals the coefficient of the untruncated +product, with the two truncation levels `n₁` and `n₂` allowed to differ. -/ +theorem coeff_trunc_mul_trunc_eq_coeff_mul₂ (n₁ n₂ : σ →₀ ℕ) + (f g : MvPowerSeries σ R) {m : σ →₀ ℕ} (h₁ : m < n₁) (h₂ : m < n₂) : + (trunc R n₁ f * trunc R n₂ g).coeff m = coeff m (f * g) := + coeff_truncFinset_mul_truncFinset_eq_coeff_mul₂ (by grind [IsLowerSet]) (by grind [IsLowerSet]) + f g (by simpa) (by simpa) + +/-- A coefficient of a product of truncated power series equals the coefficient of the untruncated +product. Both factors are truncated at the same level `n`. -/ +theorem coeff_trunc_mul_trunc_eq_coeff_mul (n : σ →₀ ℕ) + (f g : MvPowerSeries σ R) {m : σ →₀ ℕ} (h : m < n) : + (trunc R n f * trunc R n g).coeff m = coeff m (f * g) := + coeff_trunc_mul_trunc_eq_coeff_mul₂ n n f g h h + end TruncLT section TruncLE @@ -232,11 +255,20 @@ theorem trunc'_one (n : σ →₀ ℕ) : trunc' R n 1 = 1 := truncFinset_one (by theorem trunc'_C (n : σ →₀ ℕ) (a : R) : trunc' R n (C a) = MvPolynomial.C a := truncFinset_C (by simp) a -/-- Coefficients of the truncation of a product of two multivariate power series -/ +/-- A coefficient of a product of truncated power series equals the coefficient of the untruncated +product, with the two truncation levels `n₁` and `n₂` allowed to differ. -/ +theorem coeff_trunc'_mul_trunc'_eq_coeff_mul₂ (n₁ n₂ : σ →₀ ℕ) + (f g : MvPowerSeries σ R) {m : σ →₀ ℕ} (h₁ : m ≤ n₁) (h₂ : m ≤ n₂) : + (trunc' R n₁ f * trunc' R n₂ g).coeff m = coeff m (f * g) := + coeff_truncFinset_mul_truncFinset_eq_coeff_mul₂ (by grind [IsLowerSet]) (by grind [IsLowerSet]) + f g (by simpa) (by simpa) + +/-- A coefficient of a product of truncated power series equals the coefficient of the untruncated +product. Both factors are truncated at the same level `n`. -/ theorem coeff_trunc'_mul_trunc'_eq_coeff_mul (n : σ →₀ ℕ) (f g : MvPowerSeries σ R) {m : σ →₀ ℕ} (h : m ≤ n) : (trunc' R n f * trunc' R n g).coeff m = coeff m (f * g) := - coeff_truncFinset_mul_truncFinset_eq_coeff_mul (by intro; grind) f g (by simpa) + coeff_trunc'_mul_trunc'_eq_coeff_mul₂ n n f g h h @[deprecated coeff_trunc'_mul_trunc'_eq_coeff_mul (since := "2026-02-20")] theorem coeff_mul_eq_coeff_trunc'_mul_trunc' (n : σ →₀ ℕ) (f g : MvPowerSeries σ R) {m : σ →₀ ℕ} From 24434ef5d5de06bd81beb9fc0c864d8d95fb7f65 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:32:07 +0000 Subject: [PATCH 0388/1300] feat(RepresentationTheory/Basic): add one API (#41076) --- Mathlib/RepresentationTheory/Basic.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/RepresentationTheory/Basic.lean b/Mathlib/RepresentationTheory/Basic.lean index b7ba95cae0da1a..ffa02a90949dc8 100644 --- a/Mathlib/RepresentationTheory/Basic.lean +++ b/Mathlib/RepresentationTheory/Basic.lean @@ -101,6 +101,10 @@ theorem self_inv_apply (g : G) (x : V) : ρ g (ρ g⁻¹ x) = x := by simp [← Module.End.mul_apply, ← map_mul] +lemma inv_apply_eq_iff {g : G} {x y : V} : + ρ g⁻¹ x = y ↔ x = ρ g y := by + constructor <;> rintro rfl <;> simp + lemma apply_bijective (g : G) : Function.Bijective (ρ g) := Equiv.bijective ⟨ρ g, ρ g⁻¹, inv_self_apply ρ g, self_inv_apply ρ g⟩ From d6772ece85d5c7148c45528396c8ad514db3ff40 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:41:43 +0000 Subject: [PATCH 0389/1300] feat(Data/Nat): a number divides a power of its own radical (#40170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A few factorization lemmas, including: - `∀ n : ℕ`, `n ∣ radical n ^ n` - `∀ n k : ℕ`, `n ∣ k ^ n ↔ n.primeFactors ⊆ k.primeFactors` - `∀ n k : ℕ`, `radical n ∣ k ↔ n.primeFactors ⊆ k.primeFactors` - In any `UniqueFactorizationMonoid M`, `∀ a : M`, `∃ n, a ∣ radical a ^ n` [#Is there code for X? > A number divides a power of its square-free component](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/A.20number.20divides.20a.20power.20of.20its.20square-free.20component/with/599339469) --- Mathlib/Algebra/Order/Group/Multiset.lean | 24 ++++++++++------- Mathlib/Data/Nat/Choose/Lucas.lean | 2 +- Mathlib/Data/Nat/Factorization/Basic.lean | 33 ++++++++++++++++++++--- Mathlib/Data/Nat/MaxPowDiv.lean | 13 +++++++++ Mathlib/Data/Nat/Squarefree.lean | 10 +++++++ Mathlib/Data/ZMod/QuotientRing.lean | 2 +- Mathlib/RingTheory/Radical/Basic.lean | 22 +++++++++++++++ Mathlib/RingTheory/Radical/NatInt.lean | 14 +++++++--- 8 files changed, 102 insertions(+), 18 deletions(-) diff --git a/Mathlib/Algebra/Order/Group/Multiset.lean b/Mathlib/Algebra/Order/Group/Multiset.lean index e55ebb61b5dbba..586d3ee1b45cce 100644 --- a/Mathlib/Algebra/Order/Group/Multiset.lean +++ b/Mathlib/Algebra/Order/Group/Multiset.lean @@ -63,6 +63,12 @@ lemma mem_nsmul {a : α} {s : Multiset α} {n : ℕ} : a ∈ n • s ↔ n ≠ 0 lemma mem_nsmul_of_ne_zero {a : α} {s : Multiset α} {n : ℕ} (h0 : n ≠ 0) : a ∈ n • s ↔ a ∈ s := by simp [*] +theorem smul_subset_self (s : Multiset α) (n : ℕ) : n • s ⊆ s := + subset_iff.mpr fun _ ↦ mem_of_mem_nsmul + +theorem subset_smul_self_of_ne_zero (s : Multiset α) {n : ℕ} (hn : n ≠ 0) : s ⊆ n • s := + subset_iff.mpr fun _ ↦ mem_nsmul_of_ne_zero hn |>.mpr + lemma nsmul_cons {s : Multiset α} (n : ℕ) (a : α) : n • (a ::ₘ s) = n • ({a} : Multiset α) + n • s := by rw [← singleton_add, nsmul_add] @@ -180,6 +186,14 @@ lemma count_nsmul (a : α) (n s) : count a (n • s) = n * count a s := by end +theorem le_card_smul_iff_subset {s t : Multiset α} : s ≤ s.card • t ↔ s ⊆ t := by + classical + refine ⟨fun hle ↦ Subset.trans (subset_of_le hle) (t.smul_subset_self s.card), ?_⟩ + refine fun hsub ↦ le_iff_count.mpr fun a ↦ ?_ + by_cases! has : a ∉ s + · simp [count_eq_zero_of_notMem has] + grw [count_le_card, count_nsmul, ← one_le_count_iff_mem.mpr <| mem_of_subset hsub has, mul_one] + -- TODO: This should be `addMonoidHom_ext` @[ext] lemma addHom_ext [AddZeroClass β] ⦃f g : Multiset α →+ β⦄ (h : ∀ x, f {x} = g {x}) : f = g := by @@ -189,14 +203,6 @@ lemma addHom_ext [AddZeroClass β] ⦃f g : Multiset α →+ β⦄ (h : ∀ x, f | cons a s ih => simp only [← singleton_add, _root_.map_add, ih, h] theorem le_smul_dedup [DecidableEq α] (s : Multiset α) : ∃ n : ℕ, s ≤ n • dedup s := - ⟨(s.map fun a => count a s).fold max 0, - le_iff_count.2 fun a => by - rw [count_nsmul]; by_cases h : a ∈ s - · grw [← one_le_count_iff_mem.2 <| mem_dedup.2 h] - have : count a s ≤ fold max 0 (map (fun a => count a s) (a ::ₘ erase s a)) := by - simp - rw [cons_erase h] at this - simpa [mul_succ] using this - · simp [count_eq_zero.2 h, Nat.zero_le]⟩ + ⟨s.card, le_card_smul_iff_subset.mpr s.subset_dedup⟩ end Multiset diff --git a/Mathlib/Data/Nat/Choose/Lucas.lean b/Mathlib/Data/Nat/Choose/Lucas.lean index cc7f66fdd02fa5..b2192eea6d83e0 100644 --- a/Mathlib/Data/Nat/Choose/Lucas.lean +++ b/Mathlib/Data/Nat/Choose/Lucas.lean @@ -208,7 +208,7 @@ theorem gcd_choose_eq_minFac_of_isPrimePow (h : IsPrimePow n) : have : multiplicity n.minFac ((Icc 1 (n - 1)).gcd n.choose) = 1 := by refine multiplicity_eq_of_dvd_of_not_dvd ?_ (minFac_sq_ndvd_gcd_choose_of_isPrimePow h) simpa using minFac_dvd_gcd_choose_of_isPrimePow h - rw [Nat.prod_pow_primeFactors_factorization ne_zero, primeFactors_gcd_choose_of_isPrimePow h] + rw [Nat.prod_primeFactors_coe_pow_factorization ne_zero, primeFactors_gcd_choose_of_isPrimePow h] simp [← Nat.multiplicity_eq_factorization isPrime ne_zero, this] /-- For a natural number `n` greater than `1`, assume that `n` is not a prime power, then diff --git a/Mathlib/Data/Nat/Factorization/Basic.lean b/Mathlib/Data/Nat/Factorization/Basic.lean index 7ba209ef2b7730..ef73fda01a634c 100644 --- a/Mathlib/Data/Nat/Factorization/Basic.lean +++ b/Mathlib/Data/Nat/Factorization/Basic.lean @@ -477,11 +477,16 @@ theorem prod_pow_prime_padicValNat (n : Nat) (hn : n ≠ 0) (m : Nat) (pr : n < · intro p hp simp [factorization_def n (prime_of_mem_primeFactors hp)] -lemma prod_pow_primeFactors_factorization (hn : n ≠ 0) : +theorem prod_primeFactors_pow_factorization (hn : n ≠ 0) : + n = ∏ p ∈ n.primeFactors, p ^ n.factorization p := + prod_factorization_pow_eq_self hn |>.symm.trans <| prod_factorization_eq_prod_primeFactors _ + +lemma prod_primeFactors_coe_pow_factorization (hn : n ≠ 0) : n = ∏ (p : n.primeFactors), (p : ℕ) ^ (n.factorization p) := by - nth_rw 1 [← prod_factorization_pow_eq_self hn] - rw [prod_factorization_eq_prod_primeFactors _] - exact prod_subtype n.primeFactors (fun _ ↦ Iff.rfl) fun a ↦ a ^ n.factorization a + simpa using prod_primeFactors_pow_factorization hn + +@[deprecated (since := "2026-06-24")] +alias prod_pow_primeFactors_factorization := prod_primeFactors_coe_pow_factorization lemma pairwise_coprime_pow_primeFactors_factorization : Pairwise (Function.onFun Nat.Coprime fun (p : n.primeFactors) ↦ p ^ n.factorization p) := by @@ -491,6 +496,26 @@ lemma pairwise_coprime_pow_primeFactors_factorization : · exact Nat.prime_of_mem_primeFactors p1.2 · exact Nat.prime_of_mem_primeFactors p2.2 +theorem dvd_prod_primeFactors_pow_self {n : ℕ} (hn : n ≠ 0) : + n ∣ (∏ p ∈ n.primeFactors, p) ^ n := by + nth_rw 1 [← Finset.prod_pow, prod_primeFactors_pow_factorization hn] + refine prod_dvd_prod_of_dvd _ _ fun i hi ↦ pow_dvd_pow i ?_ + grw [n.factorization_def <| prime_of_mem_primeFactors hi, padicValNat_le_self] + +theorem dvd_pow_self_iff {n k : ℕ} (hn : n ≠ 0) (hk : k ≠ 0) : + n ∣ k ^ n ↔ n.primeFactors ⊆ k.primeFactors := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · grw [← Nat.primeFactors_pow k hn, Nat.primeFactors_mono h <| pow_ne_zero n hk] + · grw [dvd_prod_primeFactors_pow_self hn, prod_dvd_prod_of_subset _ _ _ h, prod_primeFactors_dvd] + +theorem exists_dvd_pow_iff {n k : ℕ} (hn : n ≠ 0) (hk : k ≠ 0) : + (∃ m, n ∣ k ^ m) ↔ n.primeFactors ⊆ k.primeFactors := by + refine ⟨fun ⟨m, h⟩ ↦ ?_, fun h ↦ ⟨n, dvd_pow_self_iff hn hk |>.mpr h⟩⟩ + rcases eq_or_ne m 0 with (rfl | hm) + · simp_all + rw [← Nat.primeFactors_pow k hm] + exact Nat.primeFactors_mono h <| pow_ne_zero m hk + /-! ### Lemmas about factorizations of particular functions -/ /-- Exactly `n / p` naturals in `[1, n]` are multiples of `p`. diff --git a/Mathlib/Data/Nat/MaxPowDiv.lean b/Mathlib/Data/Nat/MaxPowDiv.lean index ab67e60daed00f..caa09ce3da8c43 100644 --- a/Mathlib/Data/Nat/MaxPowDiv.lean +++ b/Mathlib/Data/Nat/MaxPowDiv.lean @@ -136,6 +136,19 @@ theorem pow_padicValNat_mul_divMaxPow (p n : ℕ) : p ^ padicValNat p n * divMax theorem _root_.pow_padicValNat_dvd {p n : ℕ} : p ^ padicValNat p n ∣ n := ⟨divMaxPow n p, by simp⟩ +theorem padicValNat_lt_self {p n : ℕ} (hn : n ≠ 0) : padicValNat p n < n := by + match p with + | 0 | 1 => simp [Nat.pos_of_ne_zero hn] + | p + 2 => + apply (p + 2 |>.pow_lt_pow_iff_right <| by lia).mp + apply Nat.lt_of_le_of_lt ?_ <| Nat.lt_pow_self <| by lia + exact le_of_dvd (Nat.pos_of_ne_zero hn) pow_padicValNat_dvd + +theorem padicValNat_le_self {p : ℕ} (n : ℕ) : padicValNat p n ≤ n := by + rcases eq_or_ne n 0 with rfl | hn + · simp + · exact Nat.le_of_lt <| padicValNat_lt_self hn + theorem not_dvd_divMaxPow {p n : ℕ} (hp : 1 < p) (hn : n ≠ 0) : ¬p ∣ divMaxPow n p := by simp [divMaxPow, maxPowDvdDiv, maxPowDvdDiv.go_spec, *] diff --git a/Mathlib/Data/Nat/Squarefree.lean b/Mathlib/Data/Nat/Squarefree.lean index f4fb20713370c4..f856139103cf4a 100644 --- a/Mathlib/Data/Nat/Squarefree.lean +++ b/Mathlib/Data/Nat/Squarefree.lean @@ -373,6 +373,16 @@ lemma primeFactors_prod (hs : ∀ p ∈ s, p.Prime) : primeFactors (∏ p ∈ s, rintro ⟨hp, q, hq, hpq⟩ rwa [← ((hs _ hq).dvd_iff_eq hp.ne_one).1 hpq] +theorem primeFactors_prod_primeFactors (n : ℕ) : + (∏ p ∈ n.primeFactors, p).primeFactors = n.primeFactors := + primeFactors_prod fun _ hp ↦ n.mem_primeFactors.mp hp |>.left + +theorem prod_primeFactors_dvd_iff {n k : ℕ} (hk : k ≠ 0) : + (∏ p ∈ n.primeFactors, p) ∣ k ↔ n.primeFactors ⊆ k.primeFactors := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · grw [← Nat.primeFactors_mono h hk, primeFactors_prod_primeFactors] + · grw [← k.prod_primeFactors_dvd, Finset.prod_dvd_prod_of_subset _ _ _ h] + lemma primeFactors_div_gcd (hm : Squarefree m) (hn : n ≠ 0) : primeFactors (m / m.gcd n) = primeFactors m \ primeFactors n := by ext p diff --git a/Mathlib/Data/ZMod/QuotientRing.lean b/Mathlib/Data/ZMod/QuotientRing.lean index a2902af0327b75..b7161c061e2515 100644 --- a/Mathlib/Data/ZMod/QuotientRing.lean +++ b/Mathlib/Data/ZMod/QuotientRing.lean @@ -87,7 +87,7 @@ def ZMod.prodEquivPi {ι : Type*} [Fintype ι] (a : ι → ℕ) /-- The **Chinese remainder theorem**, version for `ZMod n`. -/ def ZMod.equivPi (hn : n ≠ 0) : ZMod n ≃+* Π (p : n.primeFactors), ZMod (p ^ (n.factorization p)) := - (ringEquivCongr <| Nat.prod_pow_primeFactors_factorization hn).trans + (ringEquivCongr <| Nat.prod_primeFactors_coe_pow_factorization hn).trans <| prodEquivPi (fun (p : n.primeFactors) ↦ (p : ℕ) ^ (n.factorization p)) n.pairwise_coprime_pow_primeFactors_factorization diff --git a/Mathlib/RingTheory/Radical/Basic.lean b/Mathlib/RingTheory/Radical/Basic.lean index 66ee3710ca9be3..2b536c44fb969e 100644 --- a/Mathlib/RingTheory/Radical/Basic.lean +++ b/Mathlib/RingTheory/Radical/Basic.lean @@ -56,6 +56,12 @@ open scoped Classical in def primeFactors (a : M) : Finset M := (normalizedFactors a).toFinset +@[simp] +theorem toFinset_normalizedFactors [DecidableEq M] : + (normalizedFactors a).toFinset = primeFactors a := by + unfold primeFactors + convert rfl + lemma mem_primeFactors : a ∈ primeFactors b ↔ a ∈ normalizedFactors b := by simp only [primeFactors, Multiset.mem_toFinset] @@ -296,6 +302,22 @@ theorem radical_dvd_iff_primeFactors_subset (hb : b ≠ 0) : rw [← dvd_radical_iff isRadical_radical hb, radical_dvd_radical_iff_primeFactors_subset_primeFactors] +theorem exists_dvd_pow_iff_radical_dvd (ha : a ≠ 0) : (∃ n, a ∣ b ^ n) ↔ radical a ∣ b := by + rcases eq_or_ne b 0 with (rfl | hb) + · exact ⟨by simp, fun _ ↦ ⟨1, by simp⟩⟩ + refine ⟨fun ⟨n, hdvd⟩ ↦ ?_, fun h ↦ ⟨normalizedFactors a |>.card, ?_⟩⟩ + · rcases eq_or_ne n 0 with (rfl | hn) + · simp [radical_of_isUnit <| isUnit_of_dvd_one <| pow_zero b ▸ hdvd] + grw [radical_dvd_radical hdvd <| pow_ne_zero _ hb, radical_pow b hn, radical_dvd_self] + · classical + rwa [dvd_iff_normalizedFactors_le_normalizedFactors ha <| pow_ne_zero _ hb, + normalizedFactors_pow, Multiset.le_card_smul_iff_subset, ← Multiset.toFinset_subset, + toFinset_normalizedFactors, toFinset_normalizedFactors, + ← radical_dvd_iff_primeFactors_subset hb] + +theorem exists_dvd_radical_self_pow (ha : a ≠ 0) : ∃ n, a ∣ radical a ^ n := by + rw [exists_dvd_pow_iff_radical_dvd ha] + /-- Radical is multiplicative for relatively prime elements. -/ theorem radical_mul (hc : IsRelPrime a b) : radical (a * b) = radical a * radical b := by diff --git a/Mathlib/RingTheory/Radical/NatInt.lean b/Mathlib/RingTheory/Radical/NatInt.lean index bb14afc78a1ea0..fa1204627a638b 100644 --- a/Mathlib/RingTheory/Radical/NatInt.lean +++ b/Mathlib/RingTheory/Radical/NatInt.lean @@ -6,12 +6,10 @@ Authors: Bhavik Mehta, Arend Mellendijk, Jeremy Tan module public import Mathlib.Algebra.EuclideanDomain.Int -public import Mathlib.Algebra.GCDMonoid.Nat public import Mathlib.Data.Nat.Prime.Int -public import Mathlib.Data.Nat.PrimeFin +public import Mathlib.Data.Nat.Squarefree public import Mathlib.RingTheory.PrincipalIdealDomain public import Mathlib.RingTheory.Radical.Basic -public import Mathlib.RingTheory.UniqueFactorizationDomain.Nat /-! # The radical in `ℕ` and `ℤ` @@ -73,6 +71,16 @@ lemma radical_pos (n) : 0 < radical n := pos_of_ne_zero radical_ne_zero @[simp] lemma self_lt_radical_iff : n < radical n ↔ n = 0 := by simpa only [not_le, not_not] using radical_le_self_iff.not +theorem primeFactors_radical (n : ℕ) : (radical n).primeFactors = n.primeFactors := by + rw [radical_eq_prod_primeFactors, primeFactors_prod_primeFactors] + +theorem radical_dvd_iff {n k : ℕ} (hk : k ≠ 0) : + radical n ∣ k ↔ n.primeFactors ⊆ k.primeFactors := by + rw [radical_eq_prod_primeFactors, prod_primeFactors_dvd_iff hk] + +theorem dvd_radical_pow_self {n : ℕ} (hn : n ≠ 0) : n ∣ radical n ^ n := by + grw [radical_eq_prod_primeFactors, ← dvd_prod_primeFactors_pow_self hn] + open Qq Lean Mathlib.Meta Finset namespace Mathlib.Meta.Positivity From 7f60f15d435f4835fda6e999cbd2d08ad8963bfa Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Fri, 26 Jun 2026 12:58:25 +0000 Subject: [PATCH 0390/1300] ci: bump actions/checkout to v7.0.0 (#41055) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps `actions/checkout` to v7.0.0 across all workflows. v7 refuses to check out fork-PR code under `pull_request_target`/`workflow_run` unless `allow-unsafe-pr-checkout: true` is set. Three steps intentionally check out fork-PR code, and we already defend against the malicious case (no persisted credentials; only trusted, base-built tooling runs against the checkout), so they get the opt-in: ``` ┌────────────────────────────────────────────┬──────────────────────────────────┬─────────────────────────────────────────────────────────┐ │ File │ Step │ Checked-out ref │ ├────────────────────────────────────────────┼──────────────────────────────────┼─────────────────────────────────────────────────────────┤ │ .github/workflows/add_label_from_diff.yaml │ "Checkout branch to label" (L50) │ ${{ github.event.pull_request.head.sha || github.sha }} │ ├────────────────────────────────────────────┼──────────────────────────────────┼─────────────────────────────────────────────────────────┤ │ .github/workflows/PR_summary.yml │ "Checkout code" (L29) │ ${{ github.event.pull_request.head.sha }} │ ├────────────────────────────────────────────┼──────────────────────────────────┼─────────────────────────────────────────────────────────┤ │ .github/workflows/decls-diff.yml │ "Checkout new commit" (L67) │ ${{ steps.meta.outputs.new-sha }} │ └────────────────────────────────────────────┴──────────────────────────────────┴─────────────────────────────────────────────────────────┘ ``` --- .github/actions/get-mathlib-ci/README.md | 2 +- .github/actions/get-mathlib-ci/action.yml | 2 +- .github/actions/get-tools/action.yml | 2 +- .github/actions/setup-build-env/action.yml | 2 +- .github/workflows/PR_summary.yml | 7 +++++-- .github/workflows/actionlint.yml | 4 ++-- .github/workflows/add_label_from_diff.yaml | 7 +++++-- .github/workflows/build_template.yml | 12 ++++++------ .github/workflows/cache_test.yml | 2 +- .github/workflows/check_pr_titles.yaml | 2 +- .github/workflows/commit_verification.yml | 4 ++-- .github/workflows/daily-master-tag.yml | 2 +- .github/workflows/daily.yml | 18 +++++++++--------- .github/workflows/decls-diff.yml | 7 +++++-- .github/workflows/docker_build.yml | 2 +- .github/workflows/lake_cache_shadow.yml | 8 ++++---- .github/workflows/latest_import.yml | 4 ++-- .github/workflows/long_file_report.yml | 4 ++-- .github/workflows/maintainer_bors_wf_run.yml | 2 +- .github/workflows/maintainer_merge_wf_run.yml | 2 +- .github/workflows/nightly_bump_and_merge.yml | 4 ++-- .github/workflows/nightly_detect_failure.yml | 8 ++++---- .github/workflows/nightly_merge_master.yml | 2 +- .github/workflows/nolints.yml | 2 +- .github/workflows/olean_report.yaml | 8 ++++---- .github/workflows/pr_check_downstream.yml | 2 +- .github/workflows/pre-commit.yml | 2 +- .github/workflows/publish_tools.yml | 2 +- .github/workflows/remove_deprecated_decls.yml | 2 +- .github/workflows/rm_set_option.yml | 2 +- .github/workflows/shake.yaml | 2 +- .github/workflows/technical_debt_metrics.yml | 4 ++-- .github/workflows/update_dependencies.yml | 2 +- .../workflows/update_dependencies_zulip.yml | 8 ++++---- .../workflows/validate_mathlib_ci_paths.yml | 4 ++-- .github/workflows/weekly-lints.yml | 4 ++-- .github/workflows/zulip_emoji_ci_status.yaml | 2 +- .github/workflows/zulip_emoji_closed_pr.yaml | 2 +- .github/workflows/zulip_emoji_labelling.yaml | 2 +- .../workflows/zulip_emoji_merge_delegate.yaml | 4 ++-- 40 files changed, 86 insertions(+), 77 deletions(-) diff --git a/.github/actions/get-mathlib-ci/README.md b/.github/actions/get-mathlib-ci/README.md index 77be1f2a6f15c9..96a1e071c4eb0f 100644 --- a/.github/actions/get-mathlib-ci/README.md +++ b/.github/actions/get-mathlib-ci/README.md @@ -25,7 +25,7 @@ then use the local action: ```yaml - name: Checkout local actions - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 0a0ba2f7ebcb9a..6b593d3115f957 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -33,7 +33,7 @@ runs: using: composite steps: - name: Get mathlib-ci - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: leanprover-community/mathlib-ci ref: ${{ inputs.ref }} diff --git a/.github/actions/get-tools/action.yml b/.github/actions/get-tools/action.yml index 6e195f21ea308e..185b6b03c4b069 100644 --- a/.github/actions/get-tools/action.yml +++ b/.github/actions/get-tools/action.yml @@ -139,7 +139,7 @@ runs: - name: Checkout tools branch (source build) if: ${{ steps.finalize.outputs.result == 'build' }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.tools_source_ref }} path: ${{ inputs.path }} diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index 31298cdb1a88d6..0872e2bd7531de 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -64,7 +64,7 @@ runs: # code we build, so don't leave the GITHUB_TOKEN in pr-branch/.git/config where # that code could read it. - name: Checkout PR branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.pr_branch_ref }} fetch-depth: 1 diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index e29630eafe1a55..5d73c1426fc510 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -17,16 +17,19 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 path: pr-branch # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false + # Only trusted base-repo scripts run against this checkout, so checking out + # fork PR code under pull_request_target is safe. + allow-unsafe-pr-checkout: true - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index be2b1e7f6c7b39..0320272d125fcc 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: suggester / actionlint uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1.72.0 @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # Using our fork's PR branch until upstream merges the improved error reporting: # https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/pull/288 diff --git a/.github/workflows/add_label_from_diff.yaml b/.github/workflows/add_label_from_diff.yaml index a2257f8076023d..3738c9c273d046 100644 --- a/.github/workflows/add_label_from_diff.yaml +++ b/.github/workflows/add_label_from_diff.yaml @@ -22,7 +22,7 @@ jobs: if: github.repository == 'leanprover-community/mathlib4' steps: - name: Checkout master branch to build autolabel from - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master path: tools @@ -38,13 +38,16 @@ jobs: run: | lake build autolabel - name: Checkout branch to label - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} fetch-depth: 0 path: pr-branch # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false + # autolabel is built from the trusted base checkout and only reads these files, + # so checking out fork PR code under pull_request_target is safe. + allow-unsafe-pr-checkout: true - name: Run autolabel working-directory: pr-branch run: | diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 9e742026b1aec5..7d05038424111f 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -79,7 +79,7 @@ jobs: # We just populate the env vars for this step to make them viewable in the logs - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -394,7 +394,7 @@ jobs: shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} steps: - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -604,7 +604,7 @@ jobs: # `build_template` via `pull_request_target`, never this one — so # `pr_branch_ref` is always a trusted ref here. Fork PRs keep `master`. - name: Checkout tools branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} fetch-depth: 1 @@ -674,7 +674,7 @@ jobs: contents: read steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.pr_branch_ref }} # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. @@ -684,7 +684,7 @@ jobs: # below loads from a trust-rooted source, not from PR-branch-controlled # content. Mirrors the `Checkout local actions` step in the `build` job. - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -748,7 +748,7 @@ jobs: lake exe graph - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/cache_test.yml b/.github/workflows/cache_test.yml index 3348e82783dbce..69a965e6678d62 100644 --- a/.github/workflows/cache_test.yml +++ b/.github/workflows/cache_test.yml @@ -41,7 +41,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # Install elan and the toolchain cross-platform. Build/test/lint, the # Mathlib cache, and the GitHub cache are all disabled, so this is a diff --git a/.github/workflows/check_pr_titles.yaml b/.github/workflows/check_pr_titles.yaml index edbe9058ecd2a8..7d995d59b2c69c 100644 --- a/.github/workflows/check_pr_titles.yaml +++ b/.github/workflows/check_pr_titles.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master - name: Configure Lean diff --git a/.github/workflows/commit_verification.yml b/.github/workflows/commit_verification.yml index b117d8f7235ac6..e14544cb1ad433 100644 --- a/.github/workflows/commit_verification.yml +++ b/.github/workflows/commit_verification.yml @@ -33,14 +33,14 @@ jobs: # This is a quick check to avoid unnecessary runs steps: - name: Checkout PR head - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # Checkout the actual PR head, not the merge commit GitHub creates ref: ${{ github.event.pull_request.head.sha }} # Fetch full history to access all PR commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/daily-master-tag.yml b/.github/workflows/daily-master-tag.yml index 83007e40169d7e..96aeefcb3382ae 100644 --- a/.github/workflows/daily-master-tag.yml +++ b/.github/workflows/daily-master-tag.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'leanprover-community/mathlib4' steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index cd75a4c5e8c103..d737a444edb805 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -31,7 +31,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -52,7 +52,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -82,7 +82,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Get job status and URLs id: get-status @@ -156,7 +156,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -177,7 +177,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -205,7 +205,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Get job status and URLs id: get-status @@ -279,7 +279,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -300,7 +300,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -370,7 +370,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Get job status and URLs id: get-status diff --git a/.github/workflows/decls-diff.yml b/.github/workflows/decls-diff.yml index aca4899a3af3ad..d4405ca5107524 100644 --- a/.github/workflows/decls-diff.yml +++ b/.github/workflows/decls-diff.yml @@ -58,10 +58,13 @@ jobs: } | tee -a "$GITHUB_OUTPUT" - name: Checkout new commit - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ steps.meta.outputs.new-sha }} fetch-depth: 0 + # `new-sha` is fork PR code already built by build_fork.yml; allow the + # fork checkout under this workflow_run. + allow-unsafe-pr-checkout: true - name: Resolve merge-base against master id: resolve @@ -136,7 +139,7 @@ jobs: # Tooling is checked out unconditionally: the patcher (from CI_SCRIPTS_DIR) # is needed on the cache-miss path too, to post the warning notice. - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index b8b6c0fa81ac43..c46e08fd9934d8 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -27,7 +27,7 @@ jobs: steps: # documentation at # https://docs.github.com/en/actions/use-cases-and-examples/publishing-packages/publishing-docker-images - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Log in to the container registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 50ce19d3b21d59..099472ca7b57f0 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -98,13 +98,13 @@ jobs: uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: Checkout tools branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master path: tools-branch - name: Checkout mathlib (pr-branch) - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.mathlib_ref || 'master' }} fetch-depth: 2 @@ -278,7 +278,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT }} steps: - name: Checkout mathlib (for lean-toolchain pin) - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch @@ -410,7 +410,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT_PUBLIC }} steps: - name: Checkout mathlib - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch diff --git a/.github/workflows/latest_import.yml b/.github/workflows/latest_import.yml index eeb9d92bda388a..447160b95b43eb 100644 --- a/.github/workflows/latest_import.yml +++ b/.github/workflows/latest_import.yml @@ -26,10 +26,10 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/long_file_report.yml b/.github/workflows/long_file_report.yml index 034ae752cd59f4..f0febf9b6d215f 100644 --- a/.github/workflows/long_file_report.yml +++ b/.github/workflows/long_file_report.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_bors_wf_run.yml b/.github/workflows/maintainer_bors_wf_run.yml index 7d4b4f7f62a187..95353cb9b2b22b 100644 --- a/.github/workflows/maintainer_bors_wf_run.yml +++ b/.github/workflows/maintainer_bors_wf_run.yml @@ -130,7 +130,7 @@ jobs: if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_merge_wf_run.yml b/.github/workflows/maintainer_merge_wf_run.yml index 81ed3364171722..44208ccbb8619d 100644 --- a/.github/workflows/maintainer_merge_wf_run.yml +++ b/.github/workflows/maintainer_merge_wf_run.yml @@ -163,7 +163,7 @@ jobs: - name: Checkout local actions if: ${{ steps.authorized.outputs.authorized == 'true' }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_bump_and_merge.yml b/.github/workflows/nightly_bump_and_merge.yml index 5418ef6c3ba2fc..a04e35e02d2573 100644 --- a/.github/workflows/nightly_bump_and_merge.yml +++ b/.github/workflows/nightly_bump_and_merge.yml @@ -39,14 +39,14 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: nightly-testing fetch-depth: 0 # Fetch all branches and history token: ${{ steps.app-token.outputs.token }} - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_detect_failure.yml b/.github/workflows/nightly_detect_failure.yml index 8a2010877288a3..9e7159289f748e 100644 --- a/.github/workflows/nightly_detect_failure.yml +++ b/.github/workflows/nightly_detect_failure.yml @@ -122,7 +122,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # Pin to the SHA whose CI just succeeded, not the current tip of `nightly-testing`, # which may have advanced while CI was running. Without this, the tag and @@ -216,7 +216,7 @@ jobs: # The create-github-app-token README states that this token is masked and will not be logged accidentally. - name: Checkout Lean repository if: steps.tag.outputs.is_nightly == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: leanprover/lean4 token: ${{ steps.lean-pr-testing-token.outputs.token }} @@ -418,7 +418,7 @@ jobs: azure-client-id: ${{ vars.GH_APP_AZURE_CLIENT_ID_NIGHTLY_TESTING }} azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} - name: Checkout Mathlib4 repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' with: ref: nightly-testing # checkout nightly-testing branch (shouldn't matter which) @@ -427,7 +427,7 @@ jobs: - name: Checkout local actions if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_merge_master.yml b/.github/workflows/nightly_merge_master.yml index e371f9e9b4cd10..39725897ccfa3e 100644 --- a/.github/workflows/nightly_merge_master.yml +++ b/.github/workflows/nightly_merge_master.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing from fork - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: leanprover-community/mathlib4-nightly-testing ref: nightly-testing diff --git a/.github/workflows/nolints.yml b/.github/workflows/nolints.yml index 9716c0526a6205..e1addcf674c915 100644 --- a/.github/workflows/nolints.yml +++ b/.github/workflows/nolints.yml @@ -14,7 +14,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/olean_report.yaml b/.github/workflows/olean_report.yaml index 4c3fb07cece678..b517ba84538107 100644 --- a/.github/workflows/olean_report.yaml +++ b/.github/workflows/olean_report.yaml @@ -48,7 +48,7 @@ jobs: - name: Checkout local actions if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -82,7 +82,7 @@ jobs: # We fetch full depth so that we can compute the merge base. - name: Checkout PR head if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} ref: refs/pull/${{ github.event.issue.number }}/head @@ -95,7 +95,7 @@ jobs: # here so that a single binary can fetch oleans for both checkouts. - name: Checkout tools branch (master) if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} ref: master @@ -117,7 +117,7 @@ jobs: - name: Checkout merge base if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} ref: ${{ steps.merge_base.outputs.sha }} diff --git a/.github/workflows/pr_check_downstream.yml b/.github/workflows/pr_check_downstream.yml index ba7756d551c3e2..b099ba488b7c4b 100644 --- a/.github/workflows/pr_check_downstream.yml +++ b/.github/workflows/pr_check_downstream.yml @@ -170,7 +170,7 @@ jobs: # via a sparse checkout so we can run it; we never need the # rest of the mathlib4 working tree on this runner. - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 15f6cbbb285324..a9817759d84d61 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -20,7 +20,7 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.x diff --git a/.github/workflows/publish_tools.yml b/.github/workflows/publish_tools.yml index 028cd32bdc2fb6..999cd7a8c676e9 100644 --- a/.github/workflows/publish_tools.yml +++ b/.github/workflows/publish_tools.yml @@ -40,7 +40,7 @@ jobs: # Build under `tools-branch/`, the same directory `build_template.yml` unpacks # the tools into, in case the build bakes its own location into the binary. - name: Checkout master - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master path: tools-branch diff --git a/.github/workflows/remove_deprecated_decls.yml b/.github/workflows/remove_deprecated_decls.yml index 553f222523dcfa..c50056fdc031a2 100644 --- a/.github/workflows/remove_deprecated_decls.yml +++ b/.github/workflows/remove_deprecated_decls.yml @@ -112,7 +112,7 @@ jobs: echo "from_date=$from_date" >> "$GITHUB_OUTPUT" echo "to_date=$to_date" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/rm_set_option.yml b/.github/workflows/rm_set_option.yml index 780af2bdfb07d5..3bfee558a9f5e6 100644 --- a/.github/workflows/rm_set_option.yml +++ b/.github/workflows/rm_set_option.yml @@ -31,7 +31,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/shake.yaml b/.github/workflows/shake.yaml index 1bd86610cc16ca..cc3f1e433173e8 100644 --- a/.github/workflows/shake.yaml +++ b/.github/workflows/shake.yaml @@ -26,7 +26,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/technical_debt_metrics.yml b/.github/workflows/technical_debt_metrics.yml index 506f868b7a4a1e..f4792818ced7f3 100644 --- a/.github/workflows/technical_debt_metrics.yml +++ b/.github/workflows/technical_debt_metrics.yml @@ -12,12 +12,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # checkout all history so that we can compare across commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/update_dependencies.yml b/.github/workflows/update_dependencies.yml index b6213824640b54..30e6e281b12a8e 100644 --- a/.github/workflows/update_dependencies.yml +++ b/.github/workflows/update_dependencies.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/update_dependencies_zulip.yml b/.github/workflows/update_dependencies_zulip.yml index 5f440f10c8aac1..d511ecd7ca857a 100644 --- a/.github/workflows/update_dependencies_zulip.yml +++ b/.github/workflows/update_dependencies_zulip.yml @@ -17,13 +17,13 @@ jobs: id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -108,12 +108,12 @@ jobs: id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/validate_mathlib_ci_paths.yml b/.github/workflows/validate_mathlib_ci_paths.yml index 29c0e856c66f4c..96731cdcd805ca 100644 --- a/.github/workflows/validate_mathlib_ci_paths.yml +++ b/.github/workflows/validate_mathlib_ci_paths.yml @@ -29,10 +29,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/weekly-lints.yml b/.github/workflows/weekly-lints.yml index 17615f854293f1..5df2eddf43434a 100644 --- a/.github/workflows/weekly-lints.yml +++ b/.github/workflows/weekly-lints.yml @@ -26,12 +26,12 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_ci_status.yaml b/.github/workflows/zulip_emoji_ci_status.yaml index 02d9ed31903483..b2a46fccb8c0d2 100644 --- a/.github/workflows/zulip_emoji_ci_status.yaml +++ b/.github/workflows/zulip_emoji_ci_status.yaml @@ -74,7 +74,7 @@ jobs: - name: Checkout local actions if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_closed_pr.yaml b/.github/workflows/zulip_emoji_closed_pr.yaml index 91d05bc2cdd41e..b0488d76541fe2 100644 --- a/.github/workflows/zulip_emoji_closed_pr.yaml +++ b/.github/workflows/zulip_emoji_closed_pr.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout local actions if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || github.event_name == 'reopened' }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_labelling.yaml b/.github/workflows/zulip_emoji_labelling.yaml index f92bb24fd007fe..d462d1a878eeb4 100644 --- a/.github/workflows/zulip_emoji_labelling.yaml +++ b/.github/workflows/zulip_emoji_labelling.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_merge_delegate.yaml b/.github/workflows/zulip_emoji_merge_delegate.yaml index 176bda34b93689..7d701d874aa6c4 100644 --- a/.github/workflows/zulip_emoji_merge_delegate.yaml +++ b/.github/workflows/zulip_emoji_merge_delegate.yaml @@ -15,12 +15,12 @@ jobs: steps: - name: Checkout mathlib4 repository history - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 # download the full repository - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 From 7bc792d5985b7bc725540bf2cf41943da33695d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:47:58 +0000 Subject: [PATCH 0391/1300] feat(Topology/Sets): second-countability of `(Nonempty)Compacts` (#34271) --- Mathlib/Topology/MetricSpace/Closeds.lean | 76 --------------------- Mathlib/Topology/Sets/VietorisTopology.lean | 17 +++++ 2 files changed, 17 insertions(+), 76 deletions(-) diff --git a/Mathlib/Topology/MetricSpace/Closeds.lean b/Mathlib/Topology/MetricSpace/Closeds.lean index 4590e00f483bd8..84b99c80909c4a 100644 --- a/Mathlib/Topology/MetricSpace/Closeds.lean +++ b/Mathlib/Topology/MetricSpace/Closeds.lean @@ -277,82 +277,6 @@ theorem isClosed_in_closeds [CompleteSpace α] : IsClosed (range <| @NonemptyCompacts.toCloseds α _ _) := NonemptyCompacts.isClosedEmbedding_toCloseds.isClosed_range -/-- In a second countable space, the type of nonempty compact subsets is second countable -/ -instance instSecondCountableTopology [SecondCountableTopology α] : - SecondCountableTopology (NonemptyCompacts α) := - haveI : SeparableSpace (NonemptyCompacts α) := by - /- To obtain a countable dense subset of `NonemptyCompacts α`, start from - a countable dense subset `s` of α, and then consider all its finite nonempty subsets. - This set is countable and made of nonempty compact sets. It turns out to be dense: - by total boundedness, any compact set `t` can be covered by finitely many small balls, and - approximations in `s` of the centers of these balls give the required finite approximation - of `t`. -/ - rcases exists_countable_dense α with ⟨s, cs, s_dense⟩ - let v0 := { t : Set α | t.Finite ∧ t ⊆ s } - let v : Set (NonemptyCompacts α) := { t : NonemptyCompacts α | (t : Set α) ∈ v0 } - refine ⟨⟨v, ?_, ?_⟩⟩ - · have : v0.Countable := countable_setOf_finite_subset cs - exact this.preimage SetLike.coe_injective - · refine fun t => EMetric.mem_closure_iff.2 fun ε εpos => ?_ - -- t is a compact nonempty set, that we have to approximate uniformly by a a set in `v`. - rcases exists_between εpos with ⟨δ, δpos, δlt⟩ - have δpos' : 0 < δ / 2 := ENNReal.half_pos δpos.ne' - -- construct a map F associating to a point in α an approximating point in s, up to δ/2. - have Exy : ∀ x, ∃ y, y ∈ s ∧ edist x y < δ / 2 := by - intro x - rcases EMetric.mem_closure_iff.1 (s_dense x) (δ / 2) δpos' with ⟨y, ys, hy⟩ - exact ⟨y, ⟨ys, hy⟩⟩ - let F x := (Exy x).choose - have Fspec : ∀ x, F x ∈ s ∧ edist x (F x) < δ / 2 := fun x => (Exy x).choose_spec - -- cover `t` with finitely many balls. Their centers form a set `a` - have : TotallyBounded (t : Set α) := t.isCompact.totallyBounded - obtain ⟨a : Set α, af : Set.Finite a, ta : (t : Set α) ⊆ ⋃ y ∈ a, Metric.eball y (δ / 2)⟩ := - EMetric.totallyBounded_iff.1 this (δ / 2) δpos' - -- replace each center by a nearby approximation in `s`, giving a new set `b` - let b := F '' a - have : b.Finite := af.image _ - have tb : ∀ x ∈ t, ∃ y ∈ b, edist x y < δ := by - intro x hx - rcases mem_iUnion₂.1 (ta hx) with ⟨z, za, Dxz⟩ - exists F z, mem_image_of_mem _ za - calc - edist x (F z) ≤ edist x z + edist z (F z) := edist_triangle _ _ _ - _ < δ / 2 + δ / 2 := ENNReal.add_lt_add Dxz (Fspec z).2 - _ = δ := ENNReal.add_halves _ - -- keep only the points in `b` that are close to point in `t`, yielding a new set `c` - let c := { y ∈ b | ∃ x ∈ t, edist x y < δ } - have : c.Finite := ‹b.Finite›.subset fun x hx => hx.1 - -- points in `t` are well approximated by points in `c` - have tc : ∀ x ∈ t, ∃ y ∈ c, edist x y ≤ δ := by - intro x hx - rcases tb x hx with ⟨y, yv, Dxy⟩ - have : y ∈ c := by simpa [c, -mem_image] using ⟨yv, ⟨x, hx, Dxy⟩⟩ - exact ⟨y, this, le_of_lt Dxy⟩ - -- points in `c` are well approximated by points in `t` - have ct : ∀ y ∈ c, ∃ x ∈ t, edist y x ≤ δ := by - rintro y ⟨_, x, xt, Dyx⟩ - have : edist y x ≤ δ := - calc - edist y x = edist x y := edist_comm _ _ - _ ≤ δ := le_of_lt Dyx - exact ⟨x, xt, this⟩ - -- it follows that their Hausdorff distance is small - have : hausdorffEDist (t : Set α) c ≤ δ := hausdorffEDist_le_of_mem_edist tc ct - have Dtc : hausdorffEDist (t : Set α) c < ε := this.trans_lt δlt - -- the set `c` is not empty, as it is well approximated by a nonempty set - have hc : c.Nonempty := nonempty_of_hausdorffEDist_ne_top t.nonempty (ne_top_of_lt Dtc) - -- let `d` be the version of `c` in the type `NonemptyCompacts α` - let d : NonemptyCompacts α := ⟨⟨c, ‹c.Finite›.isCompact⟩, hc⟩ - have : c ⊆ s := by - intro x hx - rcases (mem_image _ _ _).1 hx.1 with ⟨y, ⟨_, yx⟩⟩ - rw [← yx] - exact (Fspec y).1 - have : d ∈ v := ⟨‹c.Finite›, this⟩ - -- we have proved that `d` is a good approximation of `t` as requested - exact ⟨d, ‹d ∈ v›, Dtc⟩ - UniformSpace.secondCountable_of_separable (NonemptyCompacts α) - theorem isometry_singleton : Isometry ({·} : α → NonemptyCompacts α) := fun _ _ => hausdorffEDist_singleton diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index 262594a067bf4c..812e1615152237 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -560,6 +560,15 @@ theorem regularSpace_iff : RegularSpace (Compacts α) ↔ RegularSpace α := theorem t3Space_iff : T3Space (Compacts α) ↔ T3Space α := ⟨fun _ => isEmbedding_singleton.t3Space, fun _ => inferInstance⟩ +instance [SecondCountableTopology α] : SecondCountableTopology (Compacts α) := by + obtain ⟨b, hb₁, -, hb₂⟩ := exists_countable_basis α + exact hb₂.compacts.secondCountableTopology <| (countable_setOf_finite_subset hb₁).image _ + +@[simp] +theorem secondCountableTopology_iff : + SecondCountableTopology (Compacts α) ↔ SecondCountableTopology α := + ⟨fun _ => isEmbedding_singleton.secondCountableTopology, fun _ => inferInstance⟩ + theorem isCompact_subsets_of_isCompact {K : Set α} (hK : IsCompact K) : IsCompact {L : Compacts α | ↑L ⊆ K} := by rw [isEmbedding_coe.isCompact_iff] @@ -819,6 +828,14 @@ theorem regularSpace_iff : RegularSpace (NonemptyCompacts α) ↔ RegularSpace theorem t3Space_iff : T3Space (NonemptyCompacts α) ↔ T3Space α := ⟨fun _ => isEmbedding_singleton.t3Space, fun _ => inferInstance⟩ +instance [SecondCountableTopology α] : SecondCountableTopology (NonemptyCompacts α) := + isEmbedding_toCompacts.secondCountableTopology + +@[simp] +theorem secondCountableTopology_iff : + SecondCountableTopology (NonemptyCompacts α) ↔ SecondCountableTopology α := + ⟨fun _ => isEmbedding_singleton.secondCountableTopology, fun _ => inferInstance⟩ + instance [CompactSpace α] : CompactSpace (NonemptyCompacts α) := isClosedEmbedding_toCompacts.compactSpace From 33633b7d7081460ec2d82103e7dd831faaa4084a Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:08:34 +0000 Subject: [PATCH 0392/1300] ci: revert #41055 (#41078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7f60f15d435f4835fda6e999cbd2d08ad8963bfa. cf. [#PR reviews > CI refusing to check out fork pull request code @ 💬](https://leanprover.zulipchat.com/#narrow/channel/144837-PR-reviews/topic/CI.20refusing.20to.20check.20out.20fork.20pull.20request.20code/near/606724422) --- .github/actions/get-mathlib-ci/README.md | 2 +- .github/actions/get-mathlib-ci/action.yml | 2 +- .github/actions/get-tools/action.yml | 2 +- .github/actions/setup-build-env/action.yml | 2 +- .github/workflows/PR_summary.yml | 7 ++----- .github/workflows/actionlint.yml | 4 ++-- .github/workflows/add_label_from_diff.yaml | 7 ++----- .github/workflows/build_template.yml | 12 ++++++------ .github/workflows/cache_test.yml | 2 +- .github/workflows/check_pr_titles.yaml | 2 +- .github/workflows/commit_verification.yml | 4 ++-- .github/workflows/daily-master-tag.yml | 2 +- .github/workflows/daily.yml | 18 +++++++++--------- .github/workflows/decls-diff.yml | 7 ++----- .github/workflows/docker_build.yml | 2 +- .github/workflows/lake_cache_shadow.yml | 8 ++++---- .github/workflows/latest_import.yml | 4 ++-- .github/workflows/long_file_report.yml | 4 ++-- .github/workflows/maintainer_bors_wf_run.yml | 2 +- .github/workflows/maintainer_merge_wf_run.yml | 2 +- .github/workflows/nightly_bump_and_merge.yml | 4 ++-- .github/workflows/nightly_detect_failure.yml | 8 ++++---- .github/workflows/nightly_merge_master.yml | 2 +- .github/workflows/nolints.yml | 2 +- .github/workflows/olean_report.yaml | 8 ++++---- .github/workflows/pr_check_downstream.yml | 2 +- .github/workflows/pre-commit.yml | 2 +- .github/workflows/publish_tools.yml | 2 +- .github/workflows/remove_deprecated_decls.yml | 2 +- .github/workflows/rm_set_option.yml | 2 +- .github/workflows/shake.yaml | 2 +- .github/workflows/technical_debt_metrics.yml | 4 ++-- .github/workflows/update_dependencies.yml | 2 +- .../workflows/update_dependencies_zulip.yml | 8 ++++---- .../workflows/validate_mathlib_ci_paths.yml | 4 ++-- .github/workflows/weekly-lints.yml | 4 ++-- .github/workflows/zulip_emoji_ci_status.yaml | 2 +- .github/workflows/zulip_emoji_closed_pr.yaml | 2 +- .github/workflows/zulip_emoji_labelling.yaml | 2 +- .../workflows/zulip_emoji_merge_delegate.yaml | 4 ++-- 40 files changed, 77 insertions(+), 86 deletions(-) diff --git a/.github/actions/get-mathlib-ci/README.md b/.github/actions/get-mathlib-ci/README.md index 96a1e071c4eb0f..77be1f2a6f15c9 100644 --- a/.github/actions/get-mathlib-ci/README.md +++ b/.github/actions/get-mathlib-ci/README.md @@ -25,7 +25,7 @@ then use the local action: ```yaml - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 6b593d3115f957..0a0ba2f7ebcb9a 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -33,7 +33,7 @@ runs: using: composite steps: - name: Get mathlib-ci - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: leanprover-community/mathlib-ci ref: ${{ inputs.ref }} diff --git a/.github/actions/get-tools/action.yml b/.github/actions/get-tools/action.yml index 185b6b03c4b069..6e195f21ea308e 100644 --- a/.github/actions/get-tools/action.yml +++ b/.github/actions/get-tools/action.yml @@ -139,7 +139,7 @@ runs: - name: Checkout tools branch (source build) if: ${{ steps.finalize.outputs.result == 'build' }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.tools_source_ref }} path: ${{ inputs.path }} diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index 0872e2bd7531de..31298cdb1a88d6 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -64,7 +64,7 @@ runs: # code we build, so don't leave the GITHUB_TOKEN in pr-branch/.git/config where # that code could read it. - name: Checkout PR branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.pr_branch_ref }} fetch-depth: 1 diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index 5d73c1426fc510..e29630eafe1a55 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -17,19 +17,16 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 path: pr-branch # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false - # Only trusted base-repo scripts run against this checkout, so checking out - # fork PR code under pull_request_target is safe. - allow-unsafe-pr-checkout: true - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index 0320272d125fcc..be2b1e7f6c7b39 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: suggester / actionlint uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1.72.0 @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 # Using our fork's PR branch until upstream merges the improved error reporting: # https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/pull/288 diff --git a/.github/workflows/add_label_from_diff.yaml b/.github/workflows/add_label_from_diff.yaml index 3738c9c273d046..a2257f8076023d 100644 --- a/.github/workflows/add_label_from_diff.yaml +++ b/.github/workflows/add_label_from_diff.yaml @@ -22,7 +22,7 @@ jobs: if: github.repository == 'leanprover-community/mathlib4' steps: - name: Checkout master branch to build autolabel from - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: master path: tools @@ -38,16 +38,13 @@ jobs: run: | lake build autolabel - name: Checkout branch to label - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} fetch-depth: 0 path: pr-branch # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false - # autolabel is built from the trusted base checkout and only reads these files, - # so checking out fork PR code under pull_request_target is safe. - allow-unsafe-pr-checkout: true - name: Run autolabel working-directory: pr-branch run: | diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 7d05038424111f..9e742026b1aec5 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -79,7 +79,7 @@ jobs: # We just populate the env vars for this step to make them viewable in the logs - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -394,7 +394,7 @@ jobs: shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} steps: - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -604,7 +604,7 @@ jobs: # `build_template` via `pull_request_target`, never this one — so # `pr_branch_ref` is always a trusted ref here. Fork PRs keep `master`. - name: Checkout tools branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} fetch-depth: 1 @@ -674,7 +674,7 @@ jobs: contents: read steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.pr_branch_ref }} # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. @@ -684,7 +684,7 @@ jobs: # below loads from a trust-rooted source, not from PR-branch-controlled # content. Mirrors the `Checkout local actions` step in the `build` job. - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -748,7 +748,7 @@ jobs: lake exe graph - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/cache_test.yml b/.github/workflows/cache_test.yml index 69a965e6678d62..3348e82783dbce 100644 --- a/.github/workflows/cache_test.yml +++ b/.github/workflows/cache_test.yml @@ -41,7 +41,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 # Install elan and the toolchain cross-platform. Build/test/lint, the # Mathlib cache, and the GitHub cache are all disabled, so this is a diff --git a/.github/workflows/check_pr_titles.yaml b/.github/workflows/check_pr_titles.yaml index 7d995d59b2c69c..edbe9058ecd2a8 100644 --- a/.github/workflows/check_pr_titles.yaml +++ b/.github/workflows/check_pr_titles.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: master - name: Configure Lean diff --git a/.github/workflows/commit_verification.yml b/.github/workflows/commit_verification.yml index e14544cb1ad433..b117d8f7235ac6 100644 --- a/.github/workflows/commit_verification.yml +++ b/.github/workflows/commit_verification.yml @@ -33,14 +33,14 @@ jobs: # This is a quick check to avoid unnecessary runs steps: - name: Checkout PR head - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: # Checkout the actual PR head, not the merge commit GitHub creates ref: ${{ github.event.pull_request.head.sha }} # Fetch full history to access all PR commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/daily-master-tag.yml b/.github/workflows/daily-master-tag.yml index 96aeefcb3382ae..83007e40169d7e 100644 --- a/.github/workflows/daily-master-tag.yml +++ b/.github/workflows/daily-master-tag.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'leanprover-community/mathlib4' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: master diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index d737a444edb805..cd75a4c5e8c103 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -31,7 +31,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -52,7 +52,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -82,7 +82,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Get job status and URLs id: get-status @@ -156,7 +156,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -177,7 +177,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -205,7 +205,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Get job status and URLs id: get-status @@ -279,7 +279,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -300,7 +300,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -370,7 +370,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Get job status and URLs id: get-status diff --git a/.github/workflows/decls-diff.yml b/.github/workflows/decls-diff.yml index d4405ca5107524..aca4899a3af3ad 100644 --- a/.github/workflows/decls-diff.yml +++ b/.github/workflows/decls-diff.yml @@ -58,13 +58,10 @@ jobs: } | tee -a "$GITHUB_OUTPUT" - name: Checkout new commit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ steps.meta.outputs.new-sha }} fetch-depth: 0 - # `new-sha` is fork PR code already built by build_fork.yml; allow the - # fork checkout under this workflow_run. - allow-unsafe-pr-checkout: true - name: Resolve merge-base against master id: resolve @@ -139,7 +136,7 @@ jobs: # Tooling is checked out unconditionally: the patcher (from CI_SCRIPTS_DIR) # is needed on the cache-miss path too, to post the warning notice. - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index c46e08fd9934d8..b8b6c0fa81ac43 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -27,7 +27,7 @@ jobs: steps: # documentation at # https://docs.github.com/en/actions/use-cases-and-examples/publishing-packages/publishing-docker-images - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Log in to the container registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 099472ca7b57f0..50ce19d3b21d59 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -98,13 +98,13 @@ jobs: uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: Checkout tools branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: master path: tools-branch - name: Checkout mathlib (pr-branch) - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ inputs.mathlib_ref || 'master' }} fetch-depth: 2 @@ -278,7 +278,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT }} steps: - name: Checkout mathlib (for lean-toolchain pin) - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch @@ -410,7 +410,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT_PUBLIC }} steps: - name: Checkout mathlib - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch diff --git a/.github/workflows/latest_import.yml b/.github/workflows/latest_import.yml index 447160b95b43eb..eeb9d92bda388a 100644 --- a/.github/workflows/latest_import.yml +++ b/.github/workflows/latest_import.yml @@ -26,10 +26,10 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/long_file_report.yml b/.github/workflows/long_file_report.yml index f0febf9b6d215f..034ae752cd59f4 100644 --- a/.github/workflows/long_file_report.yml +++ b/.github/workflows/long_file_report.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_bors_wf_run.yml b/.github/workflows/maintainer_bors_wf_run.yml index 95353cb9b2b22b..7d4b4f7f62a187 100644 --- a/.github/workflows/maintainer_bors_wf_run.yml +++ b/.github/workflows/maintainer_bors_wf_run.yml @@ -130,7 +130,7 @@ jobs: if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_merge_wf_run.yml b/.github/workflows/maintainer_merge_wf_run.yml index 44208ccbb8619d..81ed3364171722 100644 --- a/.github/workflows/maintainer_merge_wf_run.yml +++ b/.github/workflows/maintainer_merge_wf_run.yml @@ -163,7 +163,7 @@ jobs: - name: Checkout local actions if: ${{ steps.authorized.outputs.authorized == 'true' }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_bump_and_merge.yml b/.github/workflows/nightly_bump_and_merge.yml index a04e35e02d2573..5418ef6c3ba2fc 100644 --- a/.github/workflows/nightly_bump_and_merge.yml +++ b/.github/workflows/nightly_bump_and_merge.yml @@ -39,14 +39,14 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: nightly-testing fetch-depth: 0 # Fetch all branches and history token: ${{ steps.app-token.outputs.token }} - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_detect_failure.yml b/.github/workflows/nightly_detect_failure.yml index 9e7159289f748e..8a2010877288a3 100644 --- a/.github/workflows/nightly_detect_failure.yml +++ b/.github/workflows/nightly_detect_failure.yml @@ -122,7 +122,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: # Pin to the SHA whose CI just succeeded, not the current tip of `nightly-testing`, # which may have advanced while CI was running. Without this, the tag and @@ -216,7 +216,7 @@ jobs: # The create-github-app-token README states that this token is masked and will not be logged accidentally. - name: Checkout Lean repository if: steps.tag.outputs.is_nightly == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: leanprover/lean4 token: ${{ steps.lean-pr-testing-token.outputs.token }} @@ -418,7 +418,7 @@ jobs: azure-client-id: ${{ vars.GH_APP_AZURE_CLIENT_ID_NIGHTLY_TESTING }} azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} - name: Checkout Mathlib4 repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' with: ref: nightly-testing # checkout nightly-testing branch (shouldn't matter which) @@ -427,7 +427,7 @@ jobs: - name: Checkout local actions if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_merge_master.yml b/.github/workflows/nightly_merge_master.yml index 39725897ccfa3e..e371f9e9b4cd10 100644 --- a/.github/workflows/nightly_merge_master.yml +++ b/.github/workflows/nightly_merge_master.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing from fork - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: leanprover-community/mathlib4-nightly-testing ref: nightly-testing diff --git a/.github/workflows/nolints.yml b/.github/workflows/nolints.yml index e1addcf674c915..9716c0526a6205 100644 --- a/.github/workflows/nolints.yml +++ b/.github/workflows/nolints.yml @@ -14,7 +14,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/olean_report.yaml b/.github/workflows/olean_report.yaml index b517ba84538107..4c3fb07cece678 100644 --- a/.github/workflows/olean_report.yaml +++ b/.github/workflows/olean_report.yaml @@ -48,7 +48,7 @@ jobs: - name: Checkout local actions if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -82,7 +82,7 @@ jobs: # We fetch full depth so that we can compute the merge base. - name: Checkout PR head if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ${{ github.repository }} ref: refs/pull/${{ github.event.issue.number }}/head @@ -95,7 +95,7 @@ jobs: # here so that a single binary can fetch oleans for both checkouts. - name: Checkout tools branch (master) if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ${{ github.repository }} ref: master @@ -117,7 +117,7 @@ jobs: - name: Checkout merge base if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ${{ github.repository }} ref: ${{ steps.merge_base.outputs.sha }} diff --git a/.github/workflows/pr_check_downstream.yml b/.github/workflows/pr_check_downstream.yml index b099ba488b7c4b..ba7756d551c3e2 100644 --- a/.github/workflows/pr_check_downstream.yml +++ b/.github/workflows/pr_check_downstream.yml @@ -170,7 +170,7 @@ jobs: # via a sparse checkout so we can run it; we never need the # rest of the mathlib4 working tree on this runner. - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index a9817759d84d61..15f6cbbb285324 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -20,7 +20,7 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.x diff --git a/.github/workflows/publish_tools.yml b/.github/workflows/publish_tools.yml index 999cd7a8c676e9..028cd32bdc2fb6 100644 --- a/.github/workflows/publish_tools.yml +++ b/.github/workflows/publish_tools.yml @@ -40,7 +40,7 @@ jobs: # Build under `tools-branch/`, the same directory `build_template.yml` unpacks # the tools into, in case the build bakes its own location into the binary. - name: Checkout master - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: master path: tools-branch diff --git a/.github/workflows/remove_deprecated_decls.yml b/.github/workflows/remove_deprecated_decls.yml index c50056fdc031a2..553f222523dcfa 100644 --- a/.github/workflows/remove_deprecated_decls.yml +++ b/.github/workflows/remove_deprecated_decls.yml @@ -112,7 +112,7 @@ jobs: echo "from_date=$from_date" >> "$GITHUB_OUTPUT" echo "to_date=$to_date" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/rm_set_option.yml b/.github/workflows/rm_set_option.yml index 3bfee558a9f5e6..780af2bdfb07d5 100644 --- a/.github/workflows/rm_set_option.yml +++ b/.github/workflows/rm_set_option.yml @@ -31,7 +31,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/shake.yaml b/.github/workflows/shake.yaml index cc3f1e433173e8..1bd86610cc16ca 100644 --- a/.github/workflows/shake.yaml +++ b/.github/workflows/shake.yaml @@ -26,7 +26,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/technical_debt_metrics.yml b/.github/workflows/technical_debt_metrics.yml index f4792818ced7f3..506f868b7a4a1e 100644 --- a/.github/workflows/technical_debt_metrics.yml +++ b/.github/workflows/technical_debt_metrics.yml @@ -12,12 +12,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: # checkout all history so that we can compare across commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/update_dependencies.yml b/.github/workflows/update_dependencies.yml index 30e6e281b12a8e..b6213824640b54 100644 --- a/.github/workflows/update_dependencies.yml +++ b/.github/workflows/update_dependencies.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/update_dependencies_zulip.yml b/.github/workflows/update_dependencies_zulip.yml index d511ecd7ca857a..5f440f10c8aac1 100644 --- a/.github/workflows/update_dependencies_zulip.yml +++ b/.github/workflows/update_dependencies_zulip.yml @@ -17,13 +17,13 @@ jobs: id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -108,12 +108,12 @@ jobs: id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/validate_mathlib_ci_paths.yml b/.github/workflows/validate_mathlib_ci_paths.yml index 96731cdcd805ca..29c0e856c66f4c 100644 --- a/.github/workflows/validate_mathlib_ci_paths.yml +++ b/.github/workflows/validate_mathlib_ci_paths.yml @@ -29,10 +29,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/weekly-lints.yml b/.github/workflows/weekly-lints.yml index 5df2eddf43434a..17615f854293f1 100644 --- a/.github/workflows/weekly-lints.yml +++ b/.github/workflows/weekly-lints.yml @@ -26,12 +26,12 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: master - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_ci_status.yaml b/.github/workflows/zulip_emoji_ci_status.yaml index b2a46fccb8c0d2..02d9ed31903483 100644 --- a/.github/workflows/zulip_emoji_ci_status.yaml +++ b/.github/workflows/zulip_emoji_ci_status.yaml @@ -74,7 +74,7 @@ jobs: - name: Checkout local actions if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_closed_pr.yaml b/.github/workflows/zulip_emoji_closed_pr.yaml index b0488d76541fe2..91d05bc2cdd41e 100644 --- a/.github/workflows/zulip_emoji_closed_pr.yaml +++ b/.github/workflows/zulip_emoji_closed_pr.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout local actions if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || github.event_name == 'reopened' }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_labelling.yaml b/.github/workflows/zulip_emoji_labelling.yaml index d462d1a878eeb4..f92bb24fd007fe 100644 --- a/.github/workflows/zulip_emoji_labelling.yaml +++ b/.github/workflows/zulip_emoji_labelling.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_merge_delegate.yaml b/.github/workflows/zulip_emoji_merge_delegate.yaml index 7d701d874aa6c4..176bda34b93689 100644 --- a/.github/workflows/zulip_emoji_merge_delegate.yaml +++ b/.github/workflows/zulip_emoji_merge_delegate.yaml @@ -15,12 +15,12 @@ jobs: steps: - name: Checkout mathlib4 repository history - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 # download the full repository - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 From 571b8a8e54219b4d393f75f4b8653fac08197fcc Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:27:24 +0000 Subject: [PATCH 0393/1300] feat: more API for set integrals wrt vector measures (#40808) This is essentially an adapted copy of the API we already have for the Bochner integral --- .../VectorMeasure/SetIntegral.lean | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) diff --git a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean index 9bf93cfca754e6..82fd1a22fb2ad9 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean @@ -277,4 +277,315 @@ theorem integral_singleton [MeasurableSingletonClass X] {a : X} [CompleteSpace G ∫ᵛ a in {a}, f a ∂[B; μ] = B (f a) (μ {a}) := by simp only [restrict_singleton, integral_dirac] +theorem setIntegral_union_eq_left_of_ae (hs : MeasurableSet s) (ht : MeasurableSet t) + (ht_eq : ∀ᵐ x ∂μ.variation.restrict t, f x = 0) : + ∫ᵛ x in s ∪ t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by + classical + rw [← integral_indicator hs, ← integral_indicator (hs.union ht)] + apply integral_congr_ae + rw [ae_restrict_iff' ht] at ht_eq + filter_upwards [ht_eq] with x hx + classical + simp only [indicator_apply, mem_union] + grind + +theorem setIntegral_union_eq_left_of_forall (hs : MeasurableSet s) (ht : MeasurableSet t) + (ht_eq : ∀ x ∈ t, f x = 0) : ∫ᵛ x in s ∪ t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by + apply setIntegral_union_eq_left_of_ae hs ht + rw [ae_restrict_iff' ht] + filter_upwards with x using ht_eq x + +theorem setIntegral_eq_of_subset_of_ae_sdiff_eq_zero (hs : MeasurableSet s) (ht : MeasurableSet t) + (hts : s ⊆ t) (h't : ∀ᵐ x ∂μ.variation.restrict (t \ s), f x = 0) : + ∫ᵛ x in t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by + rwa [← union_sdiff_cancel hts, setIntegral_union_eq_left_of_ae hs (ht.diff hs)] + +/-- If a function vanishes on `t \ s` with `s ⊆ t`, then its integrals on `s` +and `t` coincide. -/ +theorem setIntegral_eq_of_subset_of_forall_sdiff_eq_zero + (hs : MeasurableSet s) (ht : MeasurableSet t) (hts : s ⊆ t) + (h't : ∀ x ∈ t \ s, f x = 0) : ∫ᵛ x in t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by + apply setIntegral_eq_of_subset_of_ae_sdiff_eq_zero hs ht hts + apply (ae_restrict_iff' (ht.diff hs)).2 + filter_upwards with x using h't x + +/-- If a function vanishes almost everywhere on `sᶜ`, then its integral on `s` +coincides with its integral on the whole space. -/ +theorem setIntegral_eq_integral_of_ae_compl_eq_zero (hs : MeasurableSet s) + (h : ∀ᵐ x ∂μ.variation, x ∉ s → f x = 0) : + ∫ᵛ x in s, f x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] := by + symm + nth_rw 1 [← setIntegral_univ] + apply setIntegral_eq_of_subset_of_ae_sdiff_eq_zero hs MeasurableSet.univ (subset_univ _) + apply (ae_restrict_iff' (MeasurableSet.univ.diff hs)).2 + filter_upwards [h] with x hx h'x using hx h'x.2 + +/-- If a function vanishes on `sᶜ`, then its integral on `s` coincides with its integral on the +whole space. -/ +theorem setIntegral_eq_integral_of_forall_compl_eq_zero (hs : MeasurableSet s) + (h : ∀ x, x ∉ s → f x = 0) : + ∫ᵛ x in s, f x ∂[B; μ] = ∫ᵛ x, f x ∂[B; μ] := + setIntegral_eq_integral_of_ae_compl_eq_zero hs (Eventually.of_forall h) + +theorem setIntegral_const [CompleteSpace G] [IsFiniteMeasure (μ.variation.restrict s)] + (c : E) : ∫ᵛ _ in s, c ∂[B; μ] = B c (μ s) := by + by_cases hs : MeasurableSet s + · have : IsFiniteMeasure (μ.restrict s).variation := by + rwa [variation_restrict hs] + rw [integral_const, restrict_apply _ hs MeasurableSet.univ, univ_inter] + · simp [setIntegral_eq_zero_of_not_measurableSet hs, μ.not_measurable hs] + +@[simp] +theorem integral_indicator_const [CompleteSpace G] + (e : E) ⦃s : Set X⦄ [IsFiniteMeasure (μ.variation.restrict s)] + (s_meas : MeasurableSet s) : + ∫ᵛ x, s.indicator (fun _ : X ↦ e) x ∂[B; μ] = B e (μ s) := by + rw [integral_indicator s_meas, ← setIntegral_const] + +theorem setIntegral_map {β : Type*} [MeasurableSpace β] + {φ : X → β} (hφ : Measurable φ) {f : β → E} {s : Set β} (hs : MeasurableSet s) + (hfm : AEStronglyMeasurable f ((μ.restrict (φ ⁻¹' s)).variation.map φ)) + (hfi' : μ.Integrable (f ∘ φ)) : + ∫ᵛ y in s, f y ∂[B; μ.map φ] = ∫ᵛ x in φ ⁻¹' s, f (φ x) ∂[B; μ] := by + rw [restrict_map μ hφ hs, integral_map hφ hfm hfi'.integrableOn] + +theorem _root_.MeasurableEmbedding.setIntegral_map_vectorMeasure {β : Type*} [MeasurableSpace β] + {φ : X → β} {f : β → E} (hφ : MeasurableEmbedding φ) {s : Set β} (hs : MeasurableSet s) : + ∫ᵛ y in s, f y ∂[B; μ.map φ] = ∫ᵛ x in φ ⁻¹' s, f (φ x) ∂[B; μ] := by + rw [restrict_map μ hφ.measurable hs, hφ.integral_map_vectorMeasure] + +theorem _root_.Topology.IsClosedEmbedding.setIntegral_map_vectorMeasure + [TopologicalSpace X] [BorelSpace X] {β : Type*} + [MeasurableSpace β] [TopologicalSpace β] [BorelSpace β] {φ : X → β} {f : β → E} {s : Set β} + (hs : MeasurableSet s) (hφ : IsClosedEmbedding φ) : + ∫ᵛ y in s, f y ∂[B; μ.map φ] = ∫ᵛ x in φ ⁻¹' s, f (φ x) ∂[B; μ] := + hφ.measurableEmbedding.setIntegral_map_vectorMeasure hs + +theorem setIntegral_map_equiv {β : Type*} [MeasurableSpace β] {e : X ≃ᵐ β} {f : β → E} {s : Set β} + (hs : MeasurableSet s) : + ∫ᵛ y in s, f y ∂[B; μ.map e] = ∫ᵛ x in e ⁻¹' s, f (e x) ∂[B; μ] := + e.measurableEmbedding.setIntegral_map_vectorMeasure hs + +theorem continuousLinearMap_apply_integral + [CompleteSpace G] [CompleteSpace H] + {C : G →L[ℝ] H} (hf : Integrable f μ.variation) : + C (∫ᵛ y, f y ∂[B; μ]) = ∫ᵛ y, f y ∂[((compL ℝ F G H C) ∘L B); μ] := by + apply hf.induction (P := fun f ↦ C (∫ᵛ y, f y ∂[B; μ]) = ∫ᵛ y, f y ∂[((compL ℝ F G H C) ∘L B); μ]) + · intro c s hs hc + have : IsFiniteMeasure (μ.variation.restrict s) := ⟨by simpa⟩ + simp [integral_indicator_const _ hs] + · intro f g _ f_int g_int hf hg + simp only [Pi.add_apply] + simp [integral_fun_add, f_int, g_int, hf, hg] + · apply isClosed_eq + · apply C.continuous.comp continuous_integral + · exact continuous_integral + · intro f g hfg _ hf + rw [← integral_congr_ae hfg, ← integral_congr_ae hfg, hf] + +theorem integral_continuousLinearMap_comp + {f : X → H} {C : H →L[ℝ] E} (hf : Integrable f μ.variation) : + ∫ᵛ y, C (f y) ∂[B; μ] = ∫ᵛ y, f y ∂[B ∘L C; μ] := by + by_cases hG : CompleteSpace G; swap + · simp [integral_of_not_completeSpace hG] + apply hf.induction (P := fun f ↦ ∫ᵛ y, C (f y) ∂[B; μ] = ∫ᵛ y, f y ∂[B ∘L C; μ]) + · intro c s hs hc + have : IsFiniteMeasure (μ.variation.restrict s) := ⟨by simpa⟩ + rw [integral_indicator_const _ hs] + have : (fun y ↦ C (s.indicator (fun x ↦ c) y)) = s.indicator (fun x ↦ C c) := by + ext; simp only [indicator]; grind + simp_rw [this] + rw [integral_indicator_const _ hs] + rfl + · intro f g _ f_int g_int hf hg + simp only [Pi.add_apply, _root_.map_add] + rw [integral_fun_add (C.integrable_comp f_int) (C.integrable_comp g_int), hf, hg, + integral_fun_add f_int g_int] + · apply isClosed_eq + · have I (f : Lp H 1 μ.variation) : ∫ᵛ x, C (f x) ∂[B; μ] = ∫ᵛ x, (C.compLp f) x ∂[B; μ] := + (integral_congr_ae (coeFn_compLp _ _)).symm + simp_rw [I] + exact continuous_integral.comp (C.compLpL 1 μ.variation).continuous + · exact continuous_integral + · intro f g hfg _ hf + have : ∀ᵐ x ∂μ.variation, C (f x) = C (g x) := by + filter_upwards [hfg] with x hx using by simp [hx] + rw [← integral_congr_ae hfg, ← integral_congr_ae this, hf] + +theorem enorm_setIntegral_le_of_enorm_le_const_ae {C : ℝ≥0∞} + (hC : ∀ᵐ x ∂μ.variation.restrict s, ‖f x‖ₑ ≤ C) : + ‖∫ᵛ x in s, f x ∂[B; μ]‖ₑ ≤ C * ‖B‖ₑ * μ.variation s := by + by_cases hs : MeasurableSet s; swap + · simp [setIntegral_eq_zero_of_not_measurableSet hs] + rw [← variation_restrict hs] at hC + apply (enorm_integral_le_of_enorm_le_const hC).trans + rw [variation_restrict hs, Measure.restrict_apply MeasurableSet.univ] + simp + +theorem enorm_setIntegral_le_of_enorm_le_const {C : ℝ≥0∞} + (hC : ∀ x ∈ s, ‖f x‖ₑ ≤ C) : + ‖∫ᵛ x in s, f x ∂[B; μ]‖ₑ ≤ C * ‖B‖ₑ * μ.variation s := by + by_cases hs : MeasurableSet s; swap + · simp [setIntegral_eq_zero_of_not_measurableSet hs] + apply enorm_setIntegral_le_of_enorm_le_const_ae + apply (ae_restrict_iff' hs).2 + filter_upwards with x using hC x + +theorem norm_setIntegral_le_of_norm_le_const_ae {C : ℝ} + [h : IsFiniteMeasure (μ.variation.restrict s)] + (hC : ∀ᵐ x ∂μ.variation.restrict s, ‖f x‖ ≤ C) : + ‖∫ᵛ x in s, f x ∂[B; μ]‖ ≤ C * ‖B‖ * μ.variation.real s := by + by_cases hs : MeasurableSet s; swap + · simp only [setIntegral_eq_zero_of_not_measurableSet hs, norm_zero] + by_cases h's : μ.variation s = 0 + · simp [Measure.real, h's] + · have : NeBot (ae (μ.variation.restrict s)) := by simpa using h's + obtain ⟨x, hx⟩ : ∃ x, ‖f x‖ ≤ C := hC.exists + have : 0 ≤ C := le_trans (norm_nonneg _) hx + positivity + rw [← variation_restrict hs] at hC h + apply (norm_integral_le_of_norm_le_const hC).trans_eq + simp [variation_restrict hs] + +theorem norm_setIntegral_le_of_norm_le_const {C : ℝ} + [h : IsFiniteMeasure (μ.variation.restrict s)] + (hC : ∀ x ∈ s, ‖f x‖ ≤ C) : + ‖∫ᵛ x in s, f x ∂[B; μ]‖ ≤ C * ‖B‖ * μ.variation.real s := by + rcases eq_empty_or_nonempty s with rfl | ⟨x, hx⟩ + · simp + by_cases hs : MeasurableSet s; swap + · simp only [setIntegral_eq_zero_of_not_measurableSet hs, norm_zero] + have : 0 ≤ C := le_trans (norm_nonneg _) (hC x hx) + positivity + apply norm_setIntegral_le_of_norm_le_const_ae + filter_upwards [ae_restrict_mem hs] with x hx using hC x hx + +theorem enorm_setIntegral_le_lintegral_enorm : + ‖∫ᵛ x in s, f x ∂[B; μ]‖ₑ ≤ ‖B‖ₑ * ∫⁻ x in s, ‖f x‖ₑ ∂μ.variation := by + grw [enorm_integral_le_lintegral_enorm, variation_restrict_le] + +theorem enorm_setIntegral_le_lintegral_enorm_transpose : + ‖∫ᵛ x in s, f x ∂[B; μ]‖ₑ ≤ ∫⁻ x in s, ‖f x‖ₑ ∂(μ.transpose B).variation := by + grw [enorm_integral_le_lintegral_enorm_transpose, transpose_restrict,variation_restrict_le] + +private theorem hasSum_setIntegral_iUnion_nat {s : ℕ → Set X} + (hm : ∀ i, MeasurableSet (s i)) (hd : Pairwise (Disjoint on s)) + (hfi : μ.IntegrableOn f (⋃ i, s i)) : + HasSum (fun n ↦ ∫ᵛ x in s n, f x ∂[B; μ]) (∫ᵛ x in ⋃ n, s n, f x ∂[B; μ]) := by + by_cases hG : CompleteSpace G; swap + · simp [integral_of_not_completeSpace hG] + have I : ∑' i, ‖B‖ₑ * ∫⁻ x in s i, ‖f x‖ₑ ∂μ.variation < ∞ := calc + ∑' i, ‖B‖ₑ * ∫⁻ x in s i, ‖f x‖ₑ ∂μ.variation + _ = ‖B‖ₑ * ∫⁻ x in (⋃ i, s i), ‖f x‖ₑ ∂μ.variation := by + rw [ENNReal.tsum_mul_left, lintegral_iUnion hm hd] + _ < ∞ := by + simp only [VectorMeasure.IntegrableOn, VectorMeasure.Integrable, + variation_restrict (MeasurableSet.iUnion hm)] at hfi + exact ENNReal.mul_lt_top (by simp) hfi.2 + have : Summable (fun n ↦ ∫ᵛ x in s n, f x ∂[B; μ]) := by + apply Summable.of_enorm (lt_of_le_of_lt _ I).ne + gcongr + exact enorm_setIntegral_le_lintegral_enorm + apply (Summable.hasSum_iff_tendsto_nat this).2 + simp_rw [tendsto_iff_edist_tendsto_0, edist_eq_enorm_sub, enorm_sub_rev] + apply tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds + (ENNReal.tendsto_sum_nat_add _ I.ne) (by positivity) (fun N ↦ ?_) + have : ⋃ n, s n = (⋃ n ∈ Finset.range N, s n) ∪ (⋃ n, s (n + N)) := by + ext x + have : (∃ i, x ∈ s (i + N)) ↔ (∃ i ≥ N, x ∈ s i) := + ⟨fun ⟨i, hi⟩ ↦ ⟨i + N, by grind⟩, fun ⟨i, hi, h'i⟩ ↦ ⟨i - N, by grind⟩⟩ + simp only [mem_iUnion, Finset.mem_range, mem_union, exists_prop, this, ge_iff_le] + grind + rw [this, setIntegral_union]; rotate_left + · simp only [Finset.mem_range, disjoint_iUnion_right, disjoint_iUnion_left] + intro i j hi + apply hd (by grind) + · apply MeasurableSet.biUnion (Finset.countable_toSet _) (fun i hi ↦ hm i) + · apply MeasurableSet.iUnion (fun i ↦ hm _) + · apply hfi.mono (MeasurableSet.iUnion hm) (by simp [subset_iUnion s]) + · apply hfi.mono (MeasurableSet.iUnion hm) (by simp [subset_iUnion s]) + rw [setIntegral_biUnion_finset]; rotate_left + · exact fun i hi ↦ hm i + · exact fun i hi j hj hij ↦ hd hij + · exact fun i hi ↦ hfi.mono (MeasurableSet.iUnion hm) (by simp [subset_iUnion s]) + simp only [add_sub_cancel_left] + apply enorm_setIntegral_le_lintegral_enorm.trans_eq + rw [lintegral_iUnion (fun i ↦ hm _), ENNReal.tsum_mul_left] + exact fun i j hij ↦ hd (by grind) + +theorem hasSum_setIntegral_iUnion {ι : Type*} [Countable ι] {s : ι → Set X} + (hm : ∀ i, MeasurableSet (s i)) (hd : Pairwise (Disjoint on s)) + (hfi : μ.IntegrableOn f (⋃ i, s i)) : + HasSum (fun n ↦ ∫ᵛ x in s n, f x ∂[B; μ]) (∫ᵛ x in ⋃ n, s n, f x ∂[B; μ]) := by + classical + rcases finite_or_infinite ι with hι | hι + · letI : Fintype ι := Fintype.ofFinite ι + have : ∫ᵛ x in ⋃ n, s n, f x ∂[B; μ] = ∑ i, ∫ᵛ x in s i, f x ∂[B; μ] := by + rw [setIntegral_iUnion_fintype hm hd (fun i ↦ ?_)] + exact hfi.mono (MeasurableSet.iUnion hm) (by simp [subset_iUnion s]) + rw [this] + apply hasSum_fintype + obtain ⟨e⟩ : Nonempty (ι ≃ ℕ) := nonempty_equiv_of_countable + rw [← e.symm.surjective.iUnion_comp, ← e.symm.hasSum_iff] + apply hasSum_setIntegral_iUnion_nat (fun i ↦ hm _) (fun i j hij ↦ hd (by simp [hij])) + rwa [e.symm.surjective.iUnion_comp] + +theorem integral_iUnion {ι : Type*} [Countable ι] {s : ι → Set X} (hm : ∀ i, MeasurableSet (s i)) + (hd : Pairwise (Disjoint on s)) (hfi : μ.IntegrableOn f (⋃ i, s i)) : + ∫ᵛ x in ⋃ n, s n, f x ∂[B; μ] = ∑' n, ∫ᵛ x in s n, f x ∂[B; μ] := + (HasSum.tsum_eq (hasSum_setIntegral_iUnion hm hd hfi)).symm + +@[simp] theorem setIntegral_toSignedMeasure {μ : Measure X} [IsFiniteMeasure μ] + {f : X → G} {s : Set X} (hs : MeasurableSet s) : + ∫ᵛ x in s, f x ∂<•μ.toSignedMeasure = ∫ x in s, f x ∂μ := by + rw [← integral_toSignedMeasure, restrict_toSignedMeasure hs] + +/-- If `f` is integrable, then `∫ᵛ x in s, f x ∂[B; μ]` is absolutely continuous in `s`: +it tends to zero as `μ.variation s` tends to zero. -/ +theorem Integrable.tendsto_setIntegral_nhds_zero {ι : Type*} + (hf : μ.Integrable f) {l : Filter ι} {s : ι → Set X} + (hs : Tendsto (μ.variation ∘ s) l (𝓝 0)) : + Tendsto (fun i ↦ ∫ᵛ x in s i, f x ∂[B; μ]) l (𝓝 0) := by + rw [tendsto_zero_iff_norm_tendsto_zero] + simp_rw [← coe_nnnorm, ← NNReal.coe_zero, NNReal.tendsto_coe, ← ENNReal.tendsto_coe, + ENNReal.coe_zero] + have : Tendsto (fun i ↦ ‖B‖ₑ * ∫⁻ (x : X) in s i, ‖f x‖ₑ ∂μ.variation) l (𝓝 (‖B‖ₑ * 0)) := + ENNReal.Tendsto.const_mul (tendsto_setLIntegral_zero (ne_of_lt hf.2) hs) (by simp) + rw [mul_zero] at this + apply tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds this (fun i ↦ zero_le) + intro i + apply enorm_integral_le_lintegral_enorm.trans + dsimp + gcongr + exact variation_restrict_le + +/-- If `F i → f` in `L1`, then `∫ᵛ x in s, F i x ∂[B; μ] → ∫ᵛ x in s, f x ∂[B; μ]`. -/ +lemma tendsto_setIntegral_of_L1 {ι} (f : X → E) + (hfi : AEStronglyMeasurable f μ.variation) {F : ι → X → E} + {l : Filter ι} (hFi : ∀ᶠ i in l, μ.Integrable (F i)) + (hF : Tendsto (fun i ↦ ∫⁻ x, ‖F i x - f x‖ₑ ∂μ.variation) l (𝓝 0)) + (s : Set X) : + Tendsto (fun i ↦ ∫ᵛ x in s, F i x ∂[B; μ]) l (𝓝 (∫ᵛ x in s, f x ∂[B; μ])) := by + refine tendsto_integral_of_L1 f ?_ ?_ ?_ + · apply hfi.mono_measure + grw [variation_restrict_le, Measure.restrict_le_self] + · filter_upwards [hFi] with i hi using hi.restrict + · simp_rw [← eLpNorm_one_eq_lintegral_enorm] at hF ⊢ + apply tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds hF (fun _ ↦ zero_le) + (fun i ↦ ?_) + apply eLpNorm_mono_measure + grw [variation_restrict_le] + apply Measure.restrict_le_self + +/-- If `F i → f` in `L1`, then `∫ᵛ x in s, F i x ∂[B; μ] → ∫ᵛ x in s, f x ∂[B; μ]`. -/ +lemma tendsto_setIntegral_of_L1' {ι} (f : X → E) + (hfi : AEStronglyMeasurable f μ.variation) {F : ι → X → E} + {l : Filter ι} (hFi : ∀ᶠ i in l, μ.Integrable (F i)) + (hF : Tendsto (fun i ↦ eLpNorm (F i - f) 1 μ.variation) l (𝓝 0)) + (s : Set X) : + Tendsto (fun i ↦ ∫ᵛ x in s, F i x ∂[B; μ]) l (𝓝 (∫ᵛ x in s, f x ∂[B; μ])) := by + refine tendsto_setIntegral_of_L1 f hfi hFi ?_ s + simp_rw [eLpNorm_one_eq_lintegral_enorm, Pi.sub_apply] at hF + exact hF + end MeasureTheory.VectorMeasure From 69b0edc5e8efbd9c94db5367ce91754a5e1cb064 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Fri, 26 Jun 2026 17:48:43 +0000 Subject: [PATCH 0394/1300] ci: bump actions/checkout to v7.0.0 (#41084) Bumps `actions/checkout` to v7.0.0 across all workflows. v7 refuses to check out fork-PR code under `pull_request_target` / `workflow_run` unless `allow-unsafe-pr-checkout: true` is set. Five steps intentionally check out fork-PR code in those contexts. Each is already hardened, the fork code is either built inside the landrun sandbox or run with only `contents: read`, while trust-rooted tooling is loaded from the base-repo checkout. | File | Step | Checked-out ref | Trigger | |---|---|---|---| | `.github/actions/setup-build-env/action.yml` | Checkout PR branch | `inputs.pr_branch_ref` | build_fork (`pull_request_target`) | | `.github/workflows/build_template.yml` | `post_steps` checkout | `inputs.pr_branch_ref` | build_fork (`pull_request_target`) | | `.github/workflows/PR_summary.yml` | Checkout code | `github.event.pull_request.head.sha` | `pull_request_target` | | `.github/workflows/add_label_from_diff.yaml` | Checkout branch to label | `github.event.pull_request.head.sha \|\| github.sha` | `pull_request_target` | | `.github/workflows/decls-diff.yml` | Checkout new commit | `steps.meta.outputs.new-sha` | `workflow_run` | Reapplies #41055 (reverted in #41078) #41055 opted in the three workflow-file steps but missed the two on the fork-build path `setup-build-env`'s `Checkout PR branch` (used by the `build` and `test_lint` jobs) and `build_template.yml`'s `post_steps` checkout. --- .github/actions/get-mathlib-ci/README.md | 2 +- .github/actions/get-mathlib-ci/action.yml | 2 +- .github/actions/get-tools/action.yml | 2 +- .github/actions/setup-build-env/action.yml | 5 ++++- .github/workflows/PR_summary.yml | 7 +++++-- .github/workflows/actionlint.yml | 4 ++-- .github/workflows/add_label_from_diff.yaml | 7 +++++-- .github/workflows/build_template.yml | 15 +++++++++------ .github/workflows/cache_test.yml | 2 +- .github/workflows/check_pr_titles.yaml | 2 +- .github/workflows/commit_verification.yml | 4 ++-- .github/workflows/daily-master-tag.yml | 2 +- .github/workflows/daily.yml | 18 +++++++++--------- .github/workflows/decls-diff.yml | 7 +++++-- .github/workflows/docker_build.yml | 2 +- .github/workflows/lake_cache_shadow.yml | 8 ++++---- .github/workflows/latest_import.yml | 4 ++-- .github/workflows/long_file_report.yml | 4 ++-- .github/workflows/maintainer_bors_wf_run.yml | 2 +- .github/workflows/maintainer_merge_wf_run.yml | 2 +- .github/workflows/nightly_bump_and_merge.yml | 4 ++-- .github/workflows/nightly_detect_failure.yml | 8 ++++---- .github/workflows/nightly_merge_master.yml | 2 +- .github/workflows/nolints.yml | 2 +- .github/workflows/olean_report.yaml | 8 ++++---- .github/workflows/pr_check_downstream.yml | 2 +- .github/workflows/pre-commit.yml | 2 +- .github/workflows/publish_tools.yml | 2 +- .github/workflows/remove_deprecated_decls.yml | 2 +- .github/workflows/rm_set_option.yml | 2 +- .github/workflows/shake.yaml | 2 +- .github/workflows/technical_debt_metrics.yml | 4 ++-- .github/workflows/update_dependencies.yml | 2 +- .../workflows/update_dependencies_zulip.yml | 8 ++++---- .../workflows/validate_mathlib_ci_paths.yml | 4 ++-- .github/workflows/weekly-lints.yml | 4 ++-- .github/workflows/zulip_emoji_ci_status.yaml | 2 +- .github/workflows/zulip_emoji_closed_pr.yaml | 2 +- .github/workflows/zulip_emoji_labelling.yaml | 2 +- .../workflows/zulip_emoji_merge_delegate.yaml | 4 ++-- 40 files changed, 92 insertions(+), 77 deletions(-) diff --git a/.github/actions/get-mathlib-ci/README.md b/.github/actions/get-mathlib-ci/README.md index 77be1f2a6f15c9..96a1e071c4eb0f 100644 --- a/.github/actions/get-mathlib-ci/README.md +++ b/.github/actions/get-mathlib-ci/README.md @@ -25,7 +25,7 @@ then use the local action: ```yaml - name: Checkout local actions - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 0a0ba2f7ebcb9a..6b593d3115f957 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -33,7 +33,7 @@ runs: using: composite steps: - name: Get mathlib-ci - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: leanprover-community/mathlib-ci ref: ${{ inputs.ref }} diff --git a/.github/actions/get-tools/action.yml b/.github/actions/get-tools/action.yml index 6e195f21ea308e..185b6b03c4b069 100644 --- a/.github/actions/get-tools/action.yml +++ b/.github/actions/get-tools/action.yml @@ -139,7 +139,7 @@ runs: - name: Checkout tools branch (source build) if: ${{ steps.finalize.outputs.result == 'build' }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.tools_source_ref }} path: ${{ inputs.path }} diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index 31298cdb1a88d6..f4a0e092a7eb50 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -64,12 +64,15 @@ runs: # code we build, so don't leave the GITHUB_TOKEN in pr-branch/.git/config where # that code could read it. - name: Checkout PR branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.pr_branch_ref }} fetch-depth: 1 path: pr-branch persist-credentials: false + # The build runs this fork PR code sandboxed (landrun) with no persisted + # credentials, so checking it out under pull_request_target is safe. + allow-unsafe-pr-checkout: true # Create empty directories so landrun doesn't complain. - name: Create empty directories diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index e29630eafe1a55..5d73c1426fc510 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -17,16 +17,19 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 path: pr-branch # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false + # Only trusted base-repo scripts run against this checkout, so checking out + # fork PR code under pull_request_target is safe. + allow-unsafe-pr-checkout: true - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index be2b1e7f6c7b39..0320272d125fcc 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: suggester / actionlint uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1.72.0 @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # Using our fork's PR branch until upstream merges the improved error reporting: # https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/pull/288 diff --git a/.github/workflows/add_label_from_diff.yaml b/.github/workflows/add_label_from_diff.yaml index a2257f8076023d..3738c9c273d046 100644 --- a/.github/workflows/add_label_from_diff.yaml +++ b/.github/workflows/add_label_from_diff.yaml @@ -22,7 +22,7 @@ jobs: if: github.repository == 'leanprover-community/mathlib4' steps: - name: Checkout master branch to build autolabel from - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master path: tools @@ -38,13 +38,16 @@ jobs: run: | lake build autolabel - name: Checkout branch to label - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} fetch-depth: 0 path: pr-branch # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false + # autolabel is built from the trusted base checkout and only reads these files, + # so checking out fork PR code under pull_request_target is safe. + allow-unsafe-pr-checkout: true - name: Run autolabel working-directory: pr-branch run: | diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 9e742026b1aec5..3ab58099ebbc78 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -79,7 +79,7 @@ jobs: # We just populate the env vars for this step to make them viewable in the logs - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -394,7 +394,7 @@ jobs: shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} steps: - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -604,7 +604,7 @@ jobs: # `build_template` via `pull_request_target`, never this one — so # `pr_branch_ref` is always a trusted ref here. Fork PRs keep `master`. - name: Checkout tools branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} fetch-depth: 1 @@ -674,17 +674,20 @@ jobs: contents: read steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.pr_branch_ref }} # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. persist-credentials: false + # This job runs with only `contents: read` and no persisted credentials, + # so checking out fork PR code under pull_request_target is safe. + allow-unsafe-pr-checkout: true # Sparse-checkout master's `.github/actions/` so the trust dispatch # below loads from a trust-rooted source, not from PR-branch-controlled # content. Mirrors the `Checkout local actions` step in the `build` job. - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -748,7 +751,7 @@ jobs: lake exe graph - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/cache_test.yml b/.github/workflows/cache_test.yml index 3348e82783dbce..69a965e6678d62 100644 --- a/.github/workflows/cache_test.yml +++ b/.github/workflows/cache_test.yml @@ -41,7 +41,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # Install elan and the toolchain cross-platform. Build/test/lint, the # Mathlib cache, and the GitHub cache are all disabled, so this is a diff --git a/.github/workflows/check_pr_titles.yaml b/.github/workflows/check_pr_titles.yaml index edbe9058ecd2a8..7d995d59b2c69c 100644 --- a/.github/workflows/check_pr_titles.yaml +++ b/.github/workflows/check_pr_titles.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master - name: Configure Lean diff --git a/.github/workflows/commit_verification.yml b/.github/workflows/commit_verification.yml index b117d8f7235ac6..e14544cb1ad433 100644 --- a/.github/workflows/commit_verification.yml +++ b/.github/workflows/commit_verification.yml @@ -33,14 +33,14 @@ jobs: # This is a quick check to avoid unnecessary runs steps: - name: Checkout PR head - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # Checkout the actual PR head, not the merge commit GitHub creates ref: ${{ github.event.pull_request.head.sha }} # Fetch full history to access all PR commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/daily-master-tag.yml b/.github/workflows/daily-master-tag.yml index 83007e40169d7e..96aeefcb3382ae 100644 --- a/.github/workflows/daily-master-tag.yml +++ b/.github/workflows/daily-master-tag.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'leanprover-community/mathlib4' steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index cd75a4c5e8c103..d737a444edb805 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -31,7 +31,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -52,7 +52,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -82,7 +82,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Get job status and URLs id: get-status @@ -156,7 +156,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -177,7 +177,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -205,7 +205,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Get job status and URLs id: get-status @@ -279,7 +279,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -300,7 +300,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -370,7 +370,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Get job status and URLs id: get-status diff --git a/.github/workflows/decls-diff.yml b/.github/workflows/decls-diff.yml index aca4899a3af3ad..d4405ca5107524 100644 --- a/.github/workflows/decls-diff.yml +++ b/.github/workflows/decls-diff.yml @@ -58,10 +58,13 @@ jobs: } | tee -a "$GITHUB_OUTPUT" - name: Checkout new commit - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ steps.meta.outputs.new-sha }} fetch-depth: 0 + # `new-sha` is fork PR code already built by build_fork.yml; allow the + # fork checkout under this workflow_run. + allow-unsafe-pr-checkout: true - name: Resolve merge-base against master id: resolve @@ -136,7 +139,7 @@ jobs: # Tooling is checked out unconditionally: the patcher (from CI_SCRIPTS_DIR) # is needed on the cache-miss path too, to post the warning notice. - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index b8b6c0fa81ac43..c46e08fd9934d8 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -27,7 +27,7 @@ jobs: steps: # documentation at # https://docs.github.com/en/actions/use-cases-and-examples/publishing-packages/publishing-docker-images - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Log in to the container registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 50ce19d3b21d59..099472ca7b57f0 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -98,13 +98,13 @@ jobs: uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 - name: Checkout tools branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master path: tools-branch - name: Checkout mathlib (pr-branch) - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ inputs.mathlib_ref || 'master' }} fetch-depth: 2 @@ -278,7 +278,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT }} steps: - name: Checkout mathlib (for lean-toolchain pin) - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch @@ -410,7 +410,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT_PUBLIC }} steps: - name: Checkout mathlib - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch diff --git a/.github/workflows/latest_import.yml b/.github/workflows/latest_import.yml index eeb9d92bda388a..447160b95b43eb 100644 --- a/.github/workflows/latest_import.yml +++ b/.github/workflows/latest_import.yml @@ -26,10 +26,10 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/long_file_report.yml b/.github/workflows/long_file_report.yml index 034ae752cd59f4..f0febf9b6d215f 100644 --- a/.github/workflows/long_file_report.yml +++ b/.github/workflows/long_file_report.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_bors_wf_run.yml b/.github/workflows/maintainer_bors_wf_run.yml index 7d4b4f7f62a187..95353cb9b2b22b 100644 --- a/.github/workflows/maintainer_bors_wf_run.yml +++ b/.github/workflows/maintainer_bors_wf_run.yml @@ -130,7 +130,7 @@ jobs: if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_merge_wf_run.yml b/.github/workflows/maintainer_merge_wf_run.yml index 81ed3364171722..44208ccbb8619d 100644 --- a/.github/workflows/maintainer_merge_wf_run.yml +++ b/.github/workflows/maintainer_merge_wf_run.yml @@ -163,7 +163,7 @@ jobs: - name: Checkout local actions if: ${{ steps.authorized.outputs.authorized == 'true' }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_bump_and_merge.yml b/.github/workflows/nightly_bump_and_merge.yml index 5418ef6c3ba2fc..a04e35e02d2573 100644 --- a/.github/workflows/nightly_bump_and_merge.yml +++ b/.github/workflows/nightly_bump_and_merge.yml @@ -39,14 +39,14 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing branch - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: nightly-testing fetch-depth: 0 # Fetch all branches and history token: ${{ steps.app-token.outputs.token }} - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_detect_failure.yml b/.github/workflows/nightly_detect_failure.yml index 8a2010877288a3..9e7159289f748e 100644 --- a/.github/workflows/nightly_detect_failure.yml +++ b/.github/workflows/nightly_detect_failure.yml @@ -122,7 +122,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # Pin to the SHA whose CI just succeeded, not the current tip of `nightly-testing`, # which may have advanced while CI was running. Without this, the tag and @@ -216,7 +216,7 @@ jobs: # The create-github-app-token README states that this token is masked and will not be logged accidentally. - name: Checkout Lean repository if: steps.tag.outputs.is_nightly == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: leanprover/lean4 token: ${{ steps.lean-pr-testing-token.outputs.token }} @@ -418,7 +418,7 @@ jobs: azure-client-id: ${{ vars.GH_APP_AZURE_CLIENT_ID_NIGHTLY_TESTING }} azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} - name: Checkout Mathlib4 repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' with: ref: nightly-testing # checkout nightly-testing branch (shouldn't matter which) @@ -427,7 +427,7 @@ jobs: - name: Checkout local actions if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_merge_master.yml b/.github/workflows/nightly_merge_master.yml index e371f9e9b4cd10..39725897ccfa3e 100644 --- a/.github/workflows/nightly_merge_master.yml +++ b/.github/workflows/nightly_merge_master.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing from fork - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: leanprover-community/mathlib4-nightly-testing ref: nightly-testing diff --git a/.github/workflows/nolints.yml b/.github/workflows/nolints.yml index 9716c0526a6205..e1addcf674c915 100644 --- a/.github/workflows/nolints.yml +++ b/.github/workflows/nolints.yml @@ -14,7 +14,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/olean_report.yaml b/.github/workflows/olean_report.yaml index 4c3fb07cece678..b517ba84538107 100644 --- a/.github/workflows/olean_report.yaml +++ b/.github/workflows/olean_report.yaml @@ -48,7 +48,7 @@ jobs: - name: Checkout local actions if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -82,7 +82,7 @@ jobs: # We fetch full depth so that we can compute the merge base. - name: Checkout PR head if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} ref: refs/pull/${{ github.event.issue.number }}/head @@ -95,7 +95,7 @@ jobs: # here so that a single binary can fetch oleans for both checkouts. - name: Checkout tools branch (master) if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} ref: master @@ -117,7 +117,7 @@ jobs: - name: Checkout merge base if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: ${{ github.repository }} ref: ${{ steps.merge_base.outputs.sha }} diff --git a/.github/workflows/pr_check_downstream.yml b/.github/workflows/pr_check_downstream.yml index ba7756d551c3e2..b099ba488b7c4b 100644 --- a/.github/workflows/pr_check_downstream.yml +++ b/.github/workflows/pr_check_downstream.yml @@ -170,7 +170,7 @@ jobs: # via a sparse checkout so we can run it; we never need the # rest of the mathlib4 working tree on this runner. - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 15f6cbbb285324..a9817759d84d61 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -20,7 +20,7 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.x diff --git a/.github/workflows/publish_tools.yml b/.github/workflows/publish_tools.yml index 028cd32bdc2fb6..999cd7a8c676e9 100644 --- a/.github/workflows/publish_tools.yml +++ b/.github/workflows/publish_tools.yml @@ -40,7 +40,7 @@ jobs: # Build under `tools-branch/`, the same directory `build_template.yml` unpacks # the tools into, in case the build bakes its own location into the binary. - name: Checkout master - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master path: tools-branch diff --git a/.github/workflows/remove_deprecated_decls.yml b/.github/workflows/remove_deprecated_decls.yml index 553f222523dcfa..c50056fdc031a2 100644 --- a/.github/workflows/remove_deprecated_decls.yml +++ b/.github/workflows/remove_deprecated_decls.yml @@ -112,7 +112,7 @@ jobs: echo "from_date=$from_date" >> "$GITHUB_OUTPUT" echo "to_date=$to_date" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/rm_set_option.yml b/.github/workflows/rm_set_option.yml index 780af2bdfb07d5..3bfee558a9f5e6 100644 --- a/.github/workflows/rm_set_option.yml +++ b/.github/workflows/rm_set_option.yml @@ -31,7 +31,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/shake.yaml b/.github/workflows/shake.yaml index 1bd86610cc16ca..cc3f1e433173e8 100644 --- a/.github/workflows/shake.yaml +++ b/.github/workflows/shake.yaml @@ -26,7 +26,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/technical_debt_metrics.yml b/.github/workflows/technical_debt_metrics.yml index 506f868b7a4a1e..f4792818ced7f3 100644 --- a/.github/workflows/technical_debt_metrics.yml +++ b/.github/workflows/technical_debt_metrics.yml @@ -12,12 +12,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # checkout all history so that we can compare across commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/update_dependencies.yml b/.github/workflows/update_dependencies.yml index b6213824640b54..30e6e281b12a8e 100644 --- a/.github/workflows/update_dependencies.yml +++ b/.github/workflows/update_dependencies.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/update_dependencies_zulip.yml b/.github/workflows/update_dependencies_zulip.yml index 5f440f10c8aac1..d511ecd7ca857a 100644 --- a/.github/workflows/update_dependencies_zulip.yml +++ b/.github/workflows/update_dependencies_zulip.yml @@ -17,13 +17,13 @@ jobs: id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -108,12 +108,12 @@ jobs: id-token: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/validate_mathlib_ci_paths.yml b/.github/workflows/validate_mathlib_ci_paths.yml index 29c0e856c66f4c..96731cdcd805ca 100644 --- a/.github/workflows/validate_mathlib_ci_paths.yml +++ b/.github/workflows/validate_mathlib_ci_paths.yml @@ -29,10 +29,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/weekly-lints.yml b/.github/workflows/weekly-lints.yml index 17615f854293f1..5df2eddf43434a 100644 --- a/.github/workflows/weekly-lints.yml +++ b/.github/workflows/weekly-lints.yml @@ -26,12 +26,12 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: master - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_ci_status.yaml b/.github/workflows/zulip_emoji_ci_status.yaml index 02d9ed31903483..b2a46fccb8c0d2 100644 --- a/.github/workflows/zulip_emoji_ci_status.yaml +++ b/.github/workflows/zulip_emoji_ci_status.yaml @@ -74,7 +74,7 @@ jobs: - name: Checkout local actions if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_closed_pr.yaml b/.github/workflows/zulip_emoji_closed_pr.yaml index 91d05bc2cdd41e..b0488d76541fe2 100644 --- a/.github/workflows/zulip_emoji_closed_pr.yaml +++ b/.github/workflows/zulip_emoji_closed_pr.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout local actions if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || github.event_name == 'reopened' }} - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_labelling.yaml b/.github/workflows/zulip_emoji_labelling.yaml index f92bb24fd007fe..d462d1a878eeb4 100644 --- a/.github/workflows/zulip_emoji_labelling.yaml +++ b/.github/workflows/zulip_emoji_labelling.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_merge_delegate.yaml b/.github/workflows/zulip_emoji_merge_delegate.yaml index 176bda34b93689..7d701d874aa6c4 100644 --- a/.github/workflows/zulip_emoji_merge_delegate.yaml +++ b/.github/workflows/zulip_emoji_merge_delegate.yaml @@ -15,12 +15,12 @@ jobs: steps: - name: Checkout mathlib4 repository history - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 # download the full repository - name: Checkout local actions - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 From 8d0d1cff7b60e52af96ad2efa0d52fcf73570b29 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 26 Jun 2026 18:00:15 +0000 Subject: [PATCH 0395/1300] feat(Analysis/Meromorphic): meromorphicOrderAt of derivative (#40080) --- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 4 +++ Mathlib/Analysis/Meromorphic/Order.lean | 40 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index e474eb729abbb5..e52733ae9f6973 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -168,17 +168,21 @@ theorem iter_deriv_inv_linear_sub (k : ℕ) (c d : 𝕜) : variable {f : E → 𝕜} {t : Set E} {a : E} +@[fun_prop] theorem DifferentiableWithinAt.zpow (hf : DifferentiableWithinAt 𝕜 f t a) (h : f a ≠ 0 ∨ 0 ≤ m) : DifferentiableWithinAt 𝕜 (fun x => f x ^ m) t a := (differentiableAt_zpow.2 h).comp_differentiableWithinAt a hf +@[fun_prop] theorem DifferentiableAt.zpow (hf : DifferentiableAt 𝕜 f a) (h : f a ≠ 0 ∨ 0 ≤ m) : DifferentiableAt 𝕜 (fun x => f x ^ m) a := (differentiableAt_zpow.2 h).comp a hf +@[fun_prop] theorem DifferentiableOn.zpow (hf : DifferentiableOn 𝕜 f t) (h : (∀ x ∈ t, f x ≠ 0) ∨ 0 ≤ m) : DifferentiableOn 𝕜 (fun x => f x ^ m) t := fun x hx => (hf x hx).zpow <| h.imp_left fun h => h x hx +@[fun_prop] theorem Differentiable.zpow (hf : Differentiable 𝕜 f) (h : (∀ x, f x ≠ 0) ∨ 0 ≤ m) : Differentiable 𝕜 fun x => f x ^ m := fun x => (hf x).zpow <| h.imp_left fun h => h x diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index fef6d7fd10eb99..dd421392c0de3e 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -892,3 +892,43 @@ lemma meromorphicOrderAt_mul_of_ne_zero {f : 𝕜 → 𝕜} (hg : AnalyticAt meromorphicOrderAt_smul_of_ne_zero hg hg' end smul + +/-! +## Order at a Point of the Derivative +-/ + +section deriv + +/-- The meromorphic order of the derivative is one less than the order of the original function. +This however is not true if the characteristic of the domain field divides the original order, +where the order of the derivative can rise to a larger integer. -/ +lemma meromorphicOrderAt_deriv_eq_sub_one [CompleteSpace E] {f : 𝕜 → E} {x : 𝕜} {n : ℤ} + (hn : (n : 𝕜) ≠ 0) (hf : meromorphicOrderAt f x = ↑n) : + meromorphicOrderAt (deriv f) x = ↑(n - 1) := by + have hmero : MeromorphicAt f x := meromorphicAt_of_meromorphicOrderAt_ne_zero (by aesop) + rw [meromorphicOrderAt_eq_int_iff hmero] at hf + rw [meromorphicOrderAt_eq_int_iff hmero.deriv] + obtain ⟨g, hga, hg0, (hg : f =ᶠ[𝓝[≠] x] fun z ↦ (z - x) ^ n • g z)⟩ := hf + refine ⟨fun z ↦ (n : 𝕜) • g z + (z - x) • deriv g z, by fun_prop, by simpa using ⟨hn, hg0⟩, ?_⟩ + filter_upwards [hga.eventually_analyticAt.filter_mono (nhdsWithin_le_nhds), + eventually_mem_nhdsWithin, hg.nhdsNE_deriv] with z hgz hmem hz + have hzx : z - x ≠ 0 := by simpa [sub_eq_zero] using hmem + calc + deriv f z = deriv (fun z ↦ (z - x) ^ n • g z) z := + hz + _ = (z - x) ^ n • deriv g z + deriv ((· ^ n) ∘ (· - x)) z • g z := + deriv_fun_smul (by fun_prop (disch := grind)) hgz.differentiableAt + _ = (z - x) ^ n • deriv g z + (n * (z - x) ^ (n - 1)) • g z := by + rw [deriv_comp _ (by fun_prop (disch := grind)) (by fun_prop)] + simp [deriv_zpow] + _ = (z - x) ^ (n - 1) • ((n : 𝕜) • g z + (z - x) • deriv g z) := by + simp [smul_smul, ← zpow_add_one₀ hzx, add_comm, mul_comm] + +/-- Equivalent to `meromorphicOrderAt_deriv_eq_sub_one` with a slightly different statement so the +conclusion matches more targets -/ +lemma meromorphicOrderAt_deriv [CompleteSpace E] {f : 𝕜 → E} {x : 𝕜} {n : ℤ} + (hn : (↑(n + 1) : 𝕜) ≠ 0) (hf : meromorphicOrderAt f x = ↑(n + 1)) : + meromorphicOrderAt (deriv f) x = ↑n := by + simpa using meromorphicOrderAt_deriv_eq_sub_one hn hf + +end deriv From a592298ec0fdbd7c1d2f1e14915b44441039fbfd Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Fri, 26 Jun 2026 19:10:12 +0000 Subject: [PATCH 0396/1300] feat: introduce typeclass `LinearMap.IsWeak` for weak topologies induced by bilinear forms (#40489) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given a bilinear form `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜`, the weak topology on `E` is the coarsest topology such that for all `y : F` every map `(B · y)` is continuous; equivalently, it is the topology on `E` induced by the map `(B · · : E → (F → 𝕜))`. This file defines a `Prop`-valued typeclass `LinearMap.IsWeak` expressing that an existing topology on `E` is the weak topology. Although this could be passed around explicitly as a hypothesis `Topology.IsInducing (B · ·)`, given the ubiquity of weak topologies in functional analysis, the numerous properties that can be deduced because the inducing map `B` is bilinear, the fact that several theorems (e.g., one version of the bipolar theorem) require this hypothesis, and we can instantiate this class for several extant types in Mathlib, we choose to make this a typeclass instead. Note that establishing `LinearMap.IsWeak` before proving theorems about a particular type can help prevent abuse of definitional equalities. This because spaces equipped with a weak topology are frequently type synonyms of some other type `E'`. For example, suppose `E'` is a type (potentially with some extant topology other than the weak topology) and `B' : E' →ₗ[𝕜] F →ₗ[𝕜] 𝕜` is a bilinear form. To consider the weak topology on `E'` induced by `B'`, in practice we must create a type synonym `E` with an instance `TopologicalSpace E := .induced (B' · ·) Pi.topologicalSpace`. It would then be tempting to create theorems such as: ```lean example (y : F) : Continuous (fun x : E ↦ B' x y) := sorry ``` However, this statement contains an abuse of the the definitional equality `E := E'` since `x : E`, but `B'` has domain `E'`. Morever, one might be tempted to say that `B'.IsWeak`, but this is impossible because the domain of `B'` is `E'`, which is equipped with the incorrect topology. Instead, what one should do is to first define a new bilinear form `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜` by composing `B'` with the linear equivalence between `E` and `E'`, and then establish `B.IsWeak`. If then one proves theorems about `E` using only the `LinearMap.IsWeak` API, then one can have more confidence that the statements are type correct. --- Mathlib.lean | 1 + Mathlib/Topology/Algebra/Module/IsWeak.lean | 180 ++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 Mathlib/Topology/Algebra/Module/IsWeak.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1e5e2a2ac83c42..4308c4d1d9eeb9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7609,6 +7609,7 @@ public import Mathlib.Topology.Algebra.Module.Determinant public import Mathlib.Topology.Algebra.Module.Equiv public import Mathlib.Topology.Algebra.Module.FiniteDimension public import Mathlib.Topology.Algebra.Module.FiniteDimensionBilinear +public import Mathlib.Topology.Algebra.Module.IsWeak public import Mathlib.Topology.Algebra.Module.LinearMap public import Mathlib.Topology.Algebra.Module.LinearMapPiProd public import Mathlib.Topology.Algebra.Module.LinearPMap diff --git a/Mathlib/Topology/Algebra/Module/IsWeak.lean b/Mathlib/Topology/Algebra/Module/IsWeak.lean new file mode 100644 index 00000000000000..841dc9ef2932b4 --- /dev/null +++ b/Mathlib/Topology/Algebra/Module/IsWeak.lean @@ -0,0 +1,180 @@ +/- +Copyright (c) 2026 Jireh Loreaux. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jireh Loreaux +-/ +module + +public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Basic +public import Mathlib.Topology.Algebra.Module.Equiv +public import Mathlib.LinearAlgebra.BilinearMap + +/-! # Weak topologies on modules + +Given a bilinear form `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜`, the weak topology on `E` is the coarsest topology +such that for all `y : F` every map `(B · y)` is continuous; equivalently, it is the topology +on `E` induced by the map `(B · · : E → (F → 𝕜))`. + +This file defines a `Prop`-valued typeclass `LinearMap.IsWeak` expressing that an existing topology +on `E` is the weak topology. Although this could be passed around explicitly as a hypothesis +`Topology.IsInducing (B · ·)`, given the ubiquity of weak topologies in functional analysis, the +numerous properties that can be deduced because the inducing map `B` is bilinear, the fact that +several theorems (e.g., one version of the bipolar theorem) require this hypothesis, and we can +instantiate this class for several extant types in Mathlib, we choose to make this a typeclass +instead. + +Note that establishing `LinearMap.IsWeak` before proving theorems about a particular type can help +prevent abuse of definitional equalities. This because spaces equipped with a weak topology are +frequently type synonyms of some other type `E'`. For example, suppose `E'` is a type (potentially +with some extant topology other than the weak topology) and `B' : E' →ₗ[𝕜] F →ₗ[𝕜] 𝕜` is a +bilinear form. To consider the weak topology on `E'` induced by `B'`, in practice we must create a +type synonym `E` with an instance `TopologicalSpace E := .induced (B' · ·) Pi.topologicalSpace`. +It would then be tempting to create theorems such as: + +```lean +example (y : F) : Continuous (fun x : E ↦ B' x y) := sorry +``` + +However, this statement contains an abuse of the the definitional equality `E := E'` since `x : E`, +but `B'` has domain `E'`. Morever, one might be tempted to say that `B'.IsWeak`, but this is +impossible because the domain of `B'` is `E'`, which is equipped with the incorrect topology. +Instead, what one should do is to first define a new bilinear form `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜` by +composing `B'` with the linear equivalence between `E` and `E'`, and then establish `B.IsWeak`. +If then one proves theorems about `E` using only the `LinearMap.IsWeak` API, then one can have more +confidence that the statements are type correct. + +## Main definitions + ++ `LinearMap.IsWeak`: a typeclass expressing that the topology on `E` is the weak topology induced + by the bilinear form `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜`. ++ `LinearMap.IsWeak.eval`: the evaluation map `F →ₗ[𝕜] StrongDual 𝕜 E` sending `y : F` to the + continuous linear functional `(B · y)`. + +## Main results + +We prove the following results characterizing the weak topology: + +* `LinearMap.IsWeak.continuous_eval`: For any `y : F`, the evaluation mapping `(B · y)` is + continuous. +* `LinearMap.IsWeak.continuous_of_continuous_eval`: For a mapping to `WeakBilin B` to be continuous, + it suffices that its compositions with pairing with `B` at all points `y : F` is continuous. +* `LinearMap.IsWeak.tendsto_iff_forall_eval_tendsto`: Convergence in `WeakBilin B` can be + characterized in terms of convergence of the evaluations at all points `y : F`. + +-/ + +@[expose] public section + +open Topology Filter + +section Basic + +variable {α 𝕜 E F E' F' : Type*} [CommSemiring 𝕜] [TopologicalSpace 𝕜] + [AddCommMonoid E] [Module 𝕜 E] + [AddCommMonoid F] [Module 𝕜 F] + +/-- Typeclass expressing that the topology on `E` is the weak topology induced +by the bilinear form `B`. -/ +@[mk_iff] +class LinearMap.IsWeak [t : TopologicalSpace E] (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) : Prop where + eq_induced : t = .induced (B · ·) Pi.topologicalSpace + +variable [inst : TopologicalSpace E] (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) [hB : B.IsWeak] + +namespace LinearMap.IsWeak + +instance : B.flip.flip.IsWeak := hB + +/-- The coercion `(B · ·) : E → (F → 𝕜)` is continuous. -/ +theorem coeFn_continuous : Continuous (B · ·) := + hB.eq_induced ▸ continuous_induced_dom + +/-- The evaluation map `(B · y) : E → 𝕜` is continuous for each `y : F`. -/ +@[fun_prop] +lemma continuous_eval (y : F) : Continuous (B · y) := + continuous_pi_iff.mp (coeFn_continuous B) _ + +/-- A map `f : α → E` is continuous if all the maps `fun a ↦ B (f a) y` are continuous +for each `y : F`. -/ +lemma continuous_of_continuous_eval {α : Type*} [TopologicalSpace α] + {f : α → E} (hf : ∀ y, Continuous (fun x ↦ B (f x) y)) : + Continuous f := + hB.eq_induced ▸ continuous_induced_rng.mpr (continuous_pi_iff.mpr hf) + +lemma continuous_iff {α : Type*} [TopologicalSpace α] {f : α → E} : + Continuous f ↔ ∀ y, Continuous (fun x ↦ B (f x) y) := + ⟨fun _ ↦ by fun_prop, hB.continuous_of_continuous_eval⟩ + +/-- The coercion `(B · ·) : E → (F → 𝕜)` is an embedding. -/ +theorem isInducing : IsInducing (B · ·) where + eq_induced := hB.eq_induced + +variable {B} in +/-- The coercion `(B · ·) : E → (F → 𝕜)` is an embedding. -/ +theorem isEmbedding (hB_inj : Function.Injective B) : + IsEmbedding (B · ·) := by + convert! (LinearMap.coe_injective.comp hB_inj |>.isEmbedding_induced) + exact hB.eq_induced + +variable {B} in +theorem tendsto_iff_forall_eval_tendsto {α : Type*} {l : Filter α} {f : α → E} {x : E} + (hB_inj : Function.Injective B) : + Tendsto f l (𝓝 x) ↔ ∀ y, Tendsto (fun i ↦ B (f i) y) l (𝓝 (B x y)) := by + rw [← tendsto_pi_nhds, (isEmbedding hB_inj).tendsto_nhds_iff, Function.comp_def] + +/-- Suppose `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜` and `B' : E' →ₗ[𝕜] F' →ₗ[𝕜] 𝕜` are bilinear maps such that +`E ≃L[𝕜] E'` and `F ≃ₗ[𝕜] F'`. If `B.IsWeak`, then so also `B'.IsWeak`. -/ +protected theorem congr [AddCommMonoid E'] [Module 𝕜 E'] + [AddCommMonoid F'] [Module 𝕜 F'] [TopologicalSpace E'] + (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) (B' : E' →ₗ[𝕜] F' →ₗ[𝕜] 𝕜) (e : E ≃L[𝕜] E') (f : F ≃ₗ[𝕜] F') + (hBB' : e.toLinearEquiv.arrowCongr (f.arrowCongr (.refl ..)) B = B') [hB : B.IsWeak] : + B'.IsWeak where + eq_induced := by + rw [e.symm.toHomeomorph.induced_eq.symm] + apply congr(TopologicalSpace.induced e.symm $(hB.eq_induced)).trans + simp_rw [induced_compose, ← hBB', induced_to_pi] + rw [f.toEquiv.iInf_congr] + simp + +/-- Map `F` into the topological dual of `E` with the weak topology induced by `F` -/ +def eval [ContinuousAdd 𝕜] [ContinuousConstSMul 𝕜 𝕜] : F →ₗ[𝕜] StrongDual 𝕜 E where + toFun f := ⟨B.flip f, by fun_prop⟩ + map_add' _ _ := by ext; simp + map_smul' _ _ := by ext; simp + +include hB in +/-- Addition in `E` is continuous when `E` is equipped with a `LinearMap.IsWeak` topology. -/ +theorem continuousAdd [ContinuousAdd 𝕜] : ContinuousAdd E where + continuous_add := by + let t₁ : TopologicalSpace E := .induced (B · ·) Pi.topologicalSpace + have : B.IsWeak := ⟨rfl⟩ + rw [hB.eq_induced, continuous_induced_rng] + simp only [Function.comp_def, map_add, add_apply] + fun_prop + +include hB in +/-- Scalar multiplication in `E` is continuous when `E` is equipped with a `LinearMap.IsWeak` +topology. -/ +theorem continuousSMul [ContinuousSMul 𝕜 𝕜] : ContinuousSMul 𝕜 E where + continuous_smul := by + let t₁ : TopologicalSpace E := .induced (B · ·) Pi.topologicalSpace + have : B.IsWeak := ⟨rfl⟩ + rw [hB.eq_induced, continuous_induced_rng] + simp only [Function.comp_def, map_smul, smul_apply] + fun_prop + +/-- `E` is a `IsTopologicalAddGroup` when `E` is equipped with a `LinearMap.IsWeak` topology. -/ +theorem isTopologicalAddGroup {𝕜 E F : Type*} [CommRing 𝕜] [TopologicalSpace 𝕜] + [AddCommGroup E] [Module 𝕜 E] [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace E] + [ContinuousAdd 𝕜] (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) [hB : B.IsWeak] : IsTopologicalAddGroup E where + toContinuousAdd := continuousAdd B + continuous_neg := by + let t₁ : TopologicalSpace E := .induced (B · ·) Pi.topologicalSpace + have : B.IsWeak := ⟨rfl⟩ + rw [hB.eq_induced, continuous_induced_rng, continuous_pi_iff] + simp_rw [Function.comp_apply, map_neg, neg_apply, ← map_neg (B _)] + fun_prop + +end LinearMap.IsWeak + +end Basic From ba1e3bb0bf5c36d34a9d7e0b57ca95e8948f18bc Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Fri, 26 Jun 2026 19:29:53 +0000 Subject: [PATCH 0397/1300] chore: extract API from #38807 and golf (#39230) I wanted to understand why these two proofs in #38807 were long (and also play around more with the API in this corner of the library) so I walked through them with Claude Opus. prepared with Claude code --- Mathlib/Order/Bounds/Basic.lean | 11 ++++++++ Mathlib/Order/DirSupClosed.lean | 49 ++++++++------------------------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index bdd91821551caa..8931a089fb9421 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -132,6 +132,10 @@ lemma DirectedOn.isCofinalFor_fst_image_prod_snd_image {β : Type*} [Preorder β obtain ⟨z, hz, hxz, hyz⟩ := hs _ hx _ hy exact ⟨z, hz, hxz.1, hyz.2⟩ +@[to_dual] +lemma IsCofinalFor.nonempty (h : IsCofinalFor s t) (hs : s.Nonempty) : t.Nonempty := + let ⟨_, ha⟩ := hs; let ⟨b, hb, _⟩ := h ha; ⟨b, hb⟩ + theorem IsCofinalFor.union_left (hc : IsCofinalFor s t) : IsCofinalFor (s ∪ t) t := by rintro a (has | hat) · exact hc has @@ -226,6 +230,13 @@ theorem IsLUB.of_subset_of_superset {s t p : Set α} (hs : IsLUB s a) (hp : IsLU (htp : t ⊆ p) : IsLUB t a := ⟨upperBounds_mono_set htp hp.1, lowerBounds_mono_set (upperBounds_mono_set hst) hs.2⟩ +/-- The least upper bound of a set is also the least upper bound of any cofinal subset. -/ +@[to_dual /-- The greatest lower bound of a set is also the greatest lower bound of any +coinitial subset. -/] +theorem IsLUB.of_isCofinalFor {s t : Set α} (hs : IsLUB s a) (hts : t ⊆ s) + (hst : IsCofinalFor s t) : IsLUB t a := + ⟨upperBounds_mono_set hts hs.1, fun _b hb ↦ hs.2 (upperBounds_mono_of_isCofinalFor hst hb)⟩ + @[to_dual] theorem IsLeast.mono (ha : IsLeast s a) (hb : IsLeast t b) (hst : s ⊆ t) : b ≤ a := hb.2 (hst ha.1) diff --git a/Mathlib/Order/DirSupClosed.lean b/Mathlib/Order/DirSupClosed.lean index ead09bf1ac225a..2ea2a0708286fc 100644 --- a/Mathlib/Order/DirSupClosed.lean +++ b/Mathlib/Order/DirSupClosed.lean @@ -171,32 +171,14 @@ theorem DirSupClosedOn.union (hDL : IsLowerSet D) (hs : DirSupClosedOn D s) (ht : DirSupClosedOn D t) : DirSupClosedOn D (s ∪ t) := by intro d hD hdu hd₀ hd₁ a ha have hdst : d ∩ s ∪ d ∩ t = d := by grind - rw [← hdst] at hd₀ hd₁ - wlog h : DirectedOn (· ≤ ·) (d ∩ s) ∧ (d ∩ s).Nonempty - · rw [union_comm] at hdu hd₀ hd₁ hdst ⊢ + wlog h : DirectedOn (· ≤ ·) (d ∩ s) ∧ IsCofinalFor (d ∩ t) (d ∩ s) + · rw [union_comm] at hdu hdst ⊢ exact this hDL ht hs hD hdu hd₀ hd₁ ha hdst <| - (directedOn_or_directedOn_of_union' hd₀ hd₁).resolve_right h - obtain ⟨hds, hn⟩ := h - by_cases had : a ∈ lowerBounds (upperBounds (d ∩ s)) - · exact .inl <| hs (hDL inter_subset_left hD) inter_subset_right hn hds - ⟨fun b hb ↦ ha.1 hb.1, had⟩ - · simp only [lowerBounds, mem_setOf_eq, not_forall] at had - obtain ⟨b, hb, hb'⟩ := had - have key : {x ∈ d | ¬ x ≤ b} ⊆ d ∩ t := fun a ⟨had, hab⟩ ↦ - ⟨had, (hdu had).resolve_left fun has ↦ hab <| hb ⟨had, has⟩⟩ - obtain ⟨w, hw⟩ : {x ∈ d | ¬ x ≤ b}.Nonempty := by - contrapose! hb' - apply ha.2 - aesop - refine Or.inr <| ht (hDL inter_subset_left hD) (key.trans inter_subset_right) - ⟨w, hw⟩ (fun x hx y hy ↦ ?_) ?_ - · obtain ⟨z, hz, hz'⟩ := hd₁ _ (.inr (key hx)) _ (.inr (key hy)) - exact ⟨z, ⟨⟨hdst ▸ hz, mt hz'.1.trans hx.2⟩, hz'⟩⟩ - · refine ⟨fun x hx ↦ ha.1 hx.1, fun x hx ↦ ha.2 fun y hy ↦ ?_⟩ - by_cases hyb : y ≤ b - · obtain ⟨z, hz, hxz, hyz⟩ := hd₁ _ (hdst ▸ hy) _ (.inr (key hw)) - exact hxz.trans (hx ⟨hdst ▸ hz, fun hzb ↦ hw.2 (hyz.trans hzb)⟩) - exact hx ⟨hy, hyb⟩ + (directedOn_union_iff.mp (by rwa [hdst])).resolve_right h + obtain ⟨hds, hcof⟩ := h + have hcof' : IsCofinalFor d (d ∩ s) := hcof.union_right.mono_left hdst.ge + exact .inl <| hs (hDL inter_subset_left hD) inter_subset_right + (hcof'.nonempty hd₀) hds (ha.of_isCofinalFor inter_subset_left hcof') theorem DirSupInaccOn.inter (hDL : IsLowerSet D) (hs : DirSupInaccOn D s) (ht : DirSupInaccOn D t) : DirSupInaccOn D (s ∩ t) := by @@ -228,18 +210,11 @@ theorem dirSupInaccOn_iff_inter_subset (hDL : IsLowerSet D) : mpr := .of_inter_subset mp h t hD ht₀ ht₁ a ha has := by by_contra! H - have H : ∀ b : t, ∃ c, b.1 ≤ c ∧ c ∈ t ∧ c ∉ s := by simpa [not_subset, and_assoc] using H - choose f hf using H - have := ht₀.to_subtype - have hft : range f ⊆ t := by grind - apply (h (hDL hft hD) (range_nonempty f) _ _ has).ne_empty - · aesop - · intro a ha b hb - obtain ⟨c, hc, _, _⟩ := ht₁ _ (hft ha) _ (hft hb) - have := hf ⟨c, hc⟩ - grind - · exact ⟨upperBounds_mono_set hft ha.1, - fun b hb ↦ ha.2 fun c hc ↦ (hf ⟨c, hc⟩).1.trans (hb <| by simp)⟩ + have hcof : IsCofinalFor t (t \ s) := by grind [IsCofinalFor, not_subset] + obtain ⟨x, hx, hxs⟩ := h (hDL sdiff_subset hD) (hcof.nonempty ht₀) + (ht₁.of_isCofinalFor sdiff_subset hcof) + (ha.of_isCofinalFor sdiff_subset hcof) has + exact hx.2 hxs /-- The condition `(d ∩ s).Nonempty` in `DirSupInacc` can be replaced with the stronger `∃ b ∈ d, Ici b ∩ d ⊆ s`. -/ From 0ee7df2241bfe98d50fd7e434b12ed24e5da648f Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Sat, 27 Jun 2026 02:57:04 +0000 Subject: [PATCH 0398/1300] chore: use `NeBot` in left and right limits (#41079) Co-authored-by: sgouezel --- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 2 -- Mathlib/Topology/Order/LeftRightLim.lean | 37 +++++++++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index f61f16fa6b1d78..eaa70d12d2e15b 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -148,8 +148,6 @@ theorem iInf_Ioi_eq [OrderTopology R] [DenselyOrdered R] [NoMaxOrder R] (f : StieltjesFunction R) (x : R) : ⨅ r : Ioi x, f r = f x := by suffices Function.rightLim f x = ⨅ r : Ioi x, f r by rw [← this, f.rightLim_eq] rw [f.mono.rightLim_eq_sInf, sInf_image'] - rw [← neBot_iff] - infer_instance theorem iInf_rat_gt_eq (f : StieltjesFunction ℝ) (x : ℝ) : ⨅ r : { r' : ℚ // x < r' }, f r = f x := by diff --git a/Mathlib/Topology/Order/LeftRightLim.lean b/Mathlib/Topology/Order/LeftRightLim.lean index e423bb8009f047..349daa40030a6a 100644 --- a/Mathlib/Topology/Order/LeftRightLim.lean +++ b/Mathlib/Topology/Order/LeftRightLim.lean @@ -64,18 +64,17 @@ noncomputable def Function.rightLim (f : α → β) (a : α) : β := open Function theorem leftLim_eq_of_tendsto [hα : TopologicalSpace α] [h'α : OrderTopology α] [T2Space β] - {f : α → β} {a : α} {y : β} (h : 𝓝[<] a ≠ ⊥) (h' : Tendsto f (𝓝[<] a) (𝓝 y)) : + {f : α → β} {a : α} {y : β} [h : (𝓝[<] a).NeBot] (h' : Tendsto f (𝓝[<] a) (𝓝 y)) : leftLim f a = y := by have h'' : ∃ y, Tendsto f (𝓝[<] a) (𝓝 y) := ⟨y, h'⟩ rw [h'α.topology_eq_generate_intervals] at h h' h'' - simp only [leftLim, h, h'', not_true, or_self_iff, if_false] - haveI := neBot_iff.2 h + simp only [leftLim, neBot_iff.mp h, h'', not_true, or_self_iff, if_false] exact lim_eq h' theorem rightLim_eq_of_tendsto [TopologicalSpace α] [OrderTopology α] [T2Space β] - {f : α → β} {a : α} {y : β} (h : 𝓝[>] a ≠ ⊥) (h' : Tendsto f (𝓝[>] a) (𝓝 y)) : + {f : α → β} {a : α} {y : β} [h : (𝓝[>] a).NeBot] (h' : Tendsto f (𝓝[>] a) (𝓝 y)) : Function.rightLim f a = y := - leftLim_eq_of_tendsto (α := αᵒᵈ) h h' + leftLim_eq_of_tendsto (α := αᵒᵈ) (h := h) h' theorem leftLim_eq_of_eq_bot [hα : TopologicalSpace α] [h'α : OrderTopology α] (f : α → β) {a : α} (h : 𝓝[<] a = ⊥) : leftLim f a = f a := by @@ -111,9 +110,9 @@ theorem rightLim_eq_of_isTop {f : α → β} {a : α} (ha : IsTop a) : theorem ContinuousWithinAt.leftLim_eq [TopologicalSpace α] [OrderTopology α] [T2Space β] {f : α → β} {a : α} (hf : ContinuousWithinAt f (Iic a) a) : leftLim f a = f a := by - rcases eq_or_ne (𝓝[<] a) ⊥ with h' | h' + rcases eq_or_neBot (𝓝[<] a) with h' | h' · simp [leftLim_eq_of_eq_bot f h'] - apply leftLim_eq_of_tendsto h' + apply leftLim_eq_of_tendsto exact hf.tendsto.mono_left (nhdsWithin_mono _ Iio_subset_Iic_self) theorem ContinuousWithinAt.rightLim_eq [TopologicalSpace α] [OrderTopology α] [T2Space β] @@ -195,7 +194,7 @@ theorem leftLim_rightLim [TopologicalSpace α] [OrderTopology α] [T3Space β] {f : α → β} {a : α} (h : Tendsto f (𝓝[<] a) (𝓝 (f.leftLim a))) [h' : (𝓝[<] a).NeBot] : f.rightLim.leftLim a = f.leftLim a := by obtain ⟨b, hb⟩ : (Iio a).Nonempty := Filter.nonempty_of_mem (self_mem_nhdsWithin (a := a)) - apply leftLim_eq_of_tendsto (neBot_iff.mp h') + apply leftLim_eq_of_tendsto apply (closed_nhds_basis (f.leftLim a)).tendsto_right_iff.2 rintro s ⟨s_mem, s_closed⟩ obtain ⟨u, au, hu⟩ : ∃ u, u < a ∧ Ioo u a ⊆ {x | f x ∈ s} := by @@ -273,24 +272,23 @@ variable {α β : Type*} [LinearOrder α] [ConditionallyCompleteLinearOrder β] [OrderTopology β] {f : α → β} (hf : Monotone f) {x y : α} include hf -theorem leftLim_eq_sSup [TopologicalSpace α] [OrderTopology α] (h : 𝓝[<] x ≠ ⊥) : +theorem leftLim_eq_sSup [TopologicalSpace α] [OrderTopology α] [(𝓝[<] x).NeBot] : leftLim f x = sSup (f '' Iio x) := - leftLim_eq_of_tendsto h (hf.tendsto_nhdsLT x) + leftLim_eq_of_tendsto (hf.tendsto_nhdsLT x) -theorem rightLim_eq_sInf [TopologicalSpace α] [OrderTopology α] (h : 𝓝[>] x ≠ ⊥) : +theorem rightLim_eq_sInf [TopologicalSpace α] [OrderTopology α] [(𝓝[>] x).NeBot] : rightLim f x = sInf (f '' Ioi x) := - rightLim_eq_of_tendsto h (hf.tendsto_nhdsGT x) + rightLim_eq_of_tendsto (hf.tendsto_nhdsGT x) theorem leftLim_le (h : x ≤ y) : leftLim f x ≤ f y := by letI : TopologicalSpace α := Preorder.topology α haveI : OrderTopology α := ⟨rfl⟩ - rcases eq_or_ne (𝓝[<] x) ⊥ with (h' | h') + rcases eq_or_neBot (𝓝[<] x) with h' | h' · simpa [leftLim, h'] using hf h - haveI A : NeBot (𝓝[<] x) := neBot_iff.2 h' - rw [leftLim_eq_sSup hf h'] + rw [leftLim_eq_sSup hf] refine csSup_le ?_ ?_ · simp only [image_nonempty] - exact (forall_mem_nonempty_iff_neBot.2 A) _ self_mem_nhdsWithin + exact (forall_mem_nonempty_iff_neBot.2 h') _ self_mem_nhdsWithin · simp only [mem_image, mem_Iio, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] intro z hz exact hf (hz.le.trans h) @@ -298,10 +296,10 @@ theorem leftLim_le (h : x ≤ y) : leftLim f x ≤ f y := by theorem le_leftLim (h : x < y) : f x ≤ leftLim f y := by letI : TopologicalSpace α := Preorder.topology α haveI : OrderTopology α := ⟨rfl⟩ - rcases eq_or_ne (𝓝[<] y) ⊥ with (h' | h') + rcases eq_or_neBot (𝓝[<] y) with h' | h' · rw [leftLim_eq_of_eq_bot _ h'] exact hf h.le - rw [leftLim_eq_sSup hf h'] + rw [leftLim_eq_sSup hf] refine le_csSup ⟨f y, ?_⟩ (mem_image_of_mem _ h) simp only [upperBounds, mem_image, mem_Iio, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq] @@ -356,9 +354,8 @@ theorem tendsto_rightLim_within (x : α) : Tendsto f (𝓝[>] x) (𝓝[≥] righ coincides with the value of the function. -/ theorem continuousWithinAt_Iio_iff_leftLim_eq : ContinuousWithinAt f (Iio x) x ↔ leftLim f x = f x := by - rcases eq_or_ne (𝓝[<] x) ⊥ with (h' | h') + rcases eq_or_neBot (𝓝[<] x) with h' | h' · simp [leftLim_eq_of_eq_bot f h', ContinuousWithinAt, h'] - haveI : (𝓝[Iio x] x).NeBot := neBot_iff.2 h' refine ⟨fun h => tendsto_nhds_unique (hf.tendsto_leftLim x) h.tendsto, fun h => ?_⟩ have := hf.tendsto_leftLim x rwa [h] at this From 6568acd0b703246d6858e3a7d189b078389d20b0 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Sat, 27 Jun 2026 08:11:23 +0000 Subject: [PATCH 0399/1300] chore(AlgebraicGeometry): add `LocallyRingedSpace.residue` (#41087) This aligns the API with the `Scheme` case. --- .../RingedSpace/LocallyRingedSpace.lean | 2 +- .../LocallyRingedSpace/ResidueField.lean | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index 9cde91f2d687b5..b5d34121cfec62 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -99,7 +99,7 @@ instance : Quiver LocallyRingedSpace := /-- A morphism of locally ringed spaces `f : X ⟶ Y` induces a local ring homomorphism from `Y.stalk (f x)` to `X.stalk x` for any `x : X`. -/ -noncomputable def Hom.stalkMap {X Y : LocallyRingedSpace.{u}} (f : Hom X Y) (x : X) : +noncomputable def Hom.stalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : Y.presheaf.stalk (f.1.1 x) ⟶ X.presheaf.stalk x := f.toShHom.hom.stalkMap x diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean index 07e65e02bcb462..4175f420b82bb0 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean @@ -48,6 +48,16 @@ def residueField (x : X) : CommRingCat := instance (x : X) : Field (X.residueField x) := inferInstanceAs <| Field (IsLocalRing.ResidueField (X.presheaf.stalk x)) +/-- The residue map from the stalk to the residue field. -/ +def residue (X : LocallyRingedSpace.{u}) (x : X) : X.presheaf.stalk x ⟶ X.residueField x := + CommRingCat.ofHom (IsLocalRing.residue (X.presheaf.stalk x)) + +lemma residue_surjective (x : X) : Function.Surjective (X.residue x) := + Ideal.Quotient.mk_surjective + +instance (x : X) : Epi (X.residue x) := + ConcreteCategory.epi_of_surjective _ (X.residue_surjective x) + /-- If `U` is an open of `X` containing `x`, we have a canonical ring map from the sections over `U` to the residue field of `x`. @@ -56,9 +66,7 @@ If we interpret sections over `U` as functions of `X` defined on `U`, then this corresponds to evaluation at `x`. -/ def evaluation (x : U) : X.presheaf.obj (op U) ⟶ X.residueField x := - -- TODO: make a new definition wrapping - -- `CommRingCat.ofHom (IsLocalRing.residue (X.presheaf.stalk _))`? - X.presheaf.germ U x.1 x.2 ≫ CommRingCat.ofHom (IsLocalRing.residue (X.presheaf.stalk _)) + X.presheaf.germ U x.1 x.2 ≫ X.residue _ /-- The global evaluation map from `Γ(X, ⊤)` to the residue field at `x`. -/ def Γevaluation (x : X) : X.presheaf.obj (op ⊤) ⟶ X.residueField x := @@ -97,10 +105,9 @@ a morphism of residue fields in the other direction. -/ def residueFieldMap (x : X) : Y.residueField (f.base x) ⟶ X.residueField x := CommRingCat.ofHom (IsLocalRing.ResidueField.map (f.stalkMap x).hom) +@[reassoc] lemma residue_comp_residueFieldMap_eq_stalkMap_comp_residue (x : X) : - CommRingCat.ofHom (IsLocalRing.residue (Y.presheaf.stalk (f.base x))) ≫ - residueFieldMap f x = f.stalkMap x ≫ - CommRingCat.ofHom (IsLocalRing.residue (X.presheaf.stalk x)) := by + Y.residue _ ≫ residueFieldMap f x = f.stalkMap x ≫ X.residue _ := by simp [residueFieldMap] rfl From 3b9fc57e284c5399761653bd6c646c78ca6fda95 Mon Sep 17 00:00:00 2001 From: rshlyakh <157648681+rshlyakh@users.noreply.github.com> Date: Sat, 27 Jun 2026 10:03:15 +0000 Subject: [PATCH 0400/1300] feat(RingTheory/IntegralClosure): add integrality of kerLift (#41058) Add `RingHom.IsIntegral.kerLift` which proves that the `kerLift` of an integral ring homomorphism is integral. --- .../RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean index 13ef5f6e66b7ec..865dc6869a9008 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean @@ -599,6 +599,9 @@ theorem isIntegral_quotientMap_iff {I : Ideal S} : refine this ▸ RingHom.IsIntegral.trans g (Ideal.quotientMap I f le_rfl) ?_ h exact g.isIntegral_of_surjective Ideal.Quotient.mk_surjective +theorem RingHom.IsIntegral.kerLift {f : S →+* T} (hf : f.IsIntegral) : f.kerLift.IsIntegral := + RingHom.IsIntegral.tower_top (Ideal.Quotient.mk (RingHom.ker f)) f.kerLift hf + theorem RingHom.IsIntegral.isLocalHom {f : R →+* S} (hf : f.IsIntegral) (inj : Function.Injective f) : IsLocalHom f where map_nonunit a ha := by From 0f320b07b214a5ce015b3da2cac08946c4b5a506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sat, 27 Jun 2026 13:04:58 +0000 Subject: [PATCH 0401/1300] feat(Topology/MetricSpace): the L^p direct sum of metric spaces (#40212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Endow the direct sum `ι →₀ X` of `ι`-many copies of a metric space `X` with the L^p metric for any `1 ≤ p < ∞`. `p = ∞` is theoretically possible too but currently annoying due to defects in our tactics/`WithTop` API. I am leaving it as future work. [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/What.20topology.20on.20Finsupp.3F/with/600119738) --- Mathlib.lean | 1 + .../Algebra/MvPolynomial/SchwartzZippel.lean | 1 - .../Algebra/Order/Monoid/Canonical/Basic.lean | 9 -- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 2 +- Mathlib/Analysis/Normed/Lp/Finsupp.lean | 102 ++++++++++++++++++ Mathlib/Analysis/Normed/Lp/WithLp.lean | 3 + Mathlib/Data/ENNReal/Basic.lean | 6 ++ Mathlib/Data/Finset/Lattice/Fold.lean | 14 ++- Mathlib/Data/NNReal/Defs.lean | 1 + 9 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 Mathlib/Analysis/Normed/Lp/Finsupp.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4308c4d1d9eeb9..a19ff93a09e8e4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2180,6 +2180,7 @@ public import Mathlib.Analysis.Normed.Group.Tannery public import Mathlib.Analysis.Normed.Group.Ultra public import Mathlib.Analysis.Normed.Group.Uniform public import Mathlib.Analysis.Normed.Group.ZeroAtInfty +public import Mathlib.Analysis.Normed.Lp.Finsupp public import Mathlib.Analysis.Normed.Lp.LpEquiv public import Mathlib.Analysis.Normed.Lp.Matrix public import Mathlib.Analysis.Normed.Lp.MeasurableSpace diff --git a/Mathlib/Algebra/MvPolynomial/SchwartzZippel.lean b/Mathlib/Algebra/MvPolynomial/SchwartzZippel.lean index e857251935b284..fd6e51dbdf0f9f 100644 --- a/Mathlib/Algebra/MvPolynomial/SchwartzZippel.lean +++ b/Mathlib/Algebra/MvPolynomial/SchwartzZippel.lean @@ -197,7 +197,6 @@ lemma schwartz_zippel_totalDegree {n} {p : MvPolynomial (Fin n) R} (hp : p ≠ 0 _ = p.totalDegree / #S := by obtain rfl | hs := S.eq_empty_or_nonempty · simp - simp only [← _root_.bot_eq_zero, sup_bot] simp_rw [totalDegree, Nat.cast_finsetSup] rw [sup_div₀ (by positivity)] simp [← sum_div, Finsupp.sum_fintype] diff --git a/Mathlib/Algebra/Order/Monoid/Canonical/Basic.lean b/Mathlib/Algebra/Order/Monoid/Canonical/Basic.lean index 66c74dc9c18512..d0ba27e66c2599 100644 --- a/Mathlib/Algebra/Order/Monoid/Canonical/Basic.lean +++ b/Mathlib/Algebra/Order/Monoid/Canonical/Basic.lean @@ -15,15 +15,6 @@ public import Mathlib.Algebra.Order.Sub.Unbundled.Basic public section -namespace Finset -variable {ι α : Type*} [AddCommMonoid α] [LinearOrder α] [OrderBot α] [CanonicallyOrderedAdd α] - {s : Finset ι} {f : ι → α} - -@[simp] lemma sup_eq_zero : s.sup f = 0 ↔ ∀ i ∈ s, f i = 0 := by simp [← bot_eq_zero'] -@[simp] lemma sup'_eq_zero (hs) : s.sup' hs f = 0 ↔ ∀ i ∈ s, f i = 0 := by simp [sup'_eq_sup] - -end Finset - namespace Set variable {α : Type*} [AddCommMonoid α] [PartialOrder α] [CanonicallyOrderedAdd α] [Sub α] [OrderedSub α] {β : Type*} {f : α → β} {k : α} diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index f915ca4763ad8d..d276095cf3211b 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -1321,7 +1321,7 @@ open Matrix LinearMap EuclideanSpace in theorem InnerProductSpace.symm_toEuclideanLin_rankOne {𝕜 m n : Type*} [RCLike 𝕜] [Fintype m] [Fintype n] [DecidableEq n] (x : EuclideanSpace 𝕜 m) (y : EuclideanSpace 𝕜 n) : toEuclideanLin.symm (rankOne 𝕜 x y) = .vecMulVec x (star y) := by - simp [toLpLin, toMatrix', ← ext_iff, vecMulVec_apply, inner_single_right, mul_comm] + simp [toLpLin, toMatrix', ← Matrix.ext_iff, vecMulVec_apply, inner_single_right, mul_comm] namespace FiniteDimensional variable [Unique ι] (h : Module.finrank 𝕜 E = 1) {v : E} (hv : ‖v‖ = 1) diff --git a/Mathlib/Analysis/Normed/Lp/Finsupp.lean b/Mathlib/Analysis/Normed/Lp/Finsupp.lean new file mode 100644 index 00000000000000..b9ae2f1afb8f32 --- /dev/null +++ b/Mathlib/Analysis/Normed/Lp/Finsupp.lean @@ -0,0 +1,102 @@ +/- +Copyright (c) 2026 Yaël Dillies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies +-/ +module + +public import Mathlib.Algebra.BigOperators.Finsupp.Basic +public import Mathlib.Analysis.Normed.Lp.WithLp +public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal +public import Mathlib.Topology.MetricSpace.Basic + +import Mathlib.Algebra.Order.BigOperators.Group.Finset +import Mathlib.Analysis.MeanInequalities +import Mathlib.Data.ENNReal.BigOperators +import Mathlib.Tactic.Positivity.Finset + +/-! +# Direct sum of metric spaces + +This files endows the direct sum `ι →₀ X` of `ι`-many copies of a metric space `X` with the +L^p metric. + +## TODO + +Allow the L^∞ metric too. Currently, there is no easy way to perform the proofs: +`match` on `ℝ≥0∞` exposes the underlying `Option` and `induction p using ENNReal.recTopCoe` in the +`EMetricSpace` instance chokes on the `PseudoEMetricSpace` one. +-/ + +open scoped ENNReal NNReal + +public section + +namespace Finsupp +variable {ι X : Type*} [Zero X] {p : ℝ≥0} [Fact (1 ≤ p)] + +/-- The L^1 extended metric on `ι`-many copies of a metric space `X` -/ +noncomputable instance [PseudoEMetricSpace X] : PseudoEMetricSpace (WithLp p <| ι →₀ X) where + edist f g := + ((f.ofLp.zipWith edist (edist_self _) g.ofLp).sum fun i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) + edist_self f := by + have : 0 < p := zero_lt_one.trans_le Fact.out + simp [sum, *] + edist_comm f g := by + simp only [sum, zipWith_apply, edist_comm] + congr 2 + ext i + simp [edist_comm] + edist_triangle f g h := by + classical + have : 0 < p := zero_lt_one.trans_le Fact.out + let s := f.ofLp.support ∪ g.ofLp.support ∪ h.ofLp.support + rw [sum_of_support_subset (s := s) _ (by grind [support_zipWith]) _ (by simp [*]), + sum_of_support_subset (s := s) _ (by grind [support_zipWith]) _ (by simp [*]), + sum_of_support_subset (s := s) _ (by grind [support_zipWith]) _ (by simp [*])] + simp only [zipWith_apply, ← one_div] + grw [← ENNReal.Lp_add_le _ _ _ (mod_cast Fact.out)] + gcongr + exact edist_triangle .. + +lemma edist_def [PseudoEMetricSpace X] {p : ℝ≥0} [Fact (1 ≤ p)] + (f g : WithLp p <| ι →₀ X) : + edist f g = + ((f.ofLp.zipWith edist (edist_self _) g.ofLp).sum fun _i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) := rfl + +/-- The L^1 extended metric on `ι`-many copies of a metric space `X` -/ +noncomputable instance [EMetricSpace X] : EMetricSpace (WithLp p <| ι →₀ X) where + eq_of_edist_eq_zero {f g} hfg := by simp_all [edist_def, sum, WithLp.ext_iff, DFunLike.ext_iff] + +/-- The L^1 metric on `ι`-many copies of a metric space `X` -/ +noncomputable instance [PseudoMetricSpace X] : PseudoMetricSpace (WithLp p <| ι →₀ X) := + PseudoEMetricSpace.toPseudoMetricSpaceOfDist + (fun f g ↦ ((f.ofLp.zipWith dist (dist_self _) g.ofLp).sum fun i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ)) + (fun f g ↦ by dsimp [sum]; positivity) fun f g ↦ by + simp only [edist_def, sum, zipWith_apply, ← coe_nnreal_ennreal_nndist, NNReal.zero_le_coe, + ← ENNReal.coe_rpow_of_nonneg, ← ENNReal.ofNNReal_finsetSum, inv_nonneg, ← coe_nndist, + ← NNReal.coe_rpow, ← NNReal.coe_sum, ENNReal.ofReal_coe_nnreal, ENNReal.coe_inj] + congr! 2 + ext i + simp [← coe_nndist, ← coe_nnreal_ennreal_nndist] + +lemma dist_def [PseudoMetricSpace X] (f g : WithLp p <| ι →₀ X) : + dist f g = + ((f.ofLp.zipWith dist (dist_self _) g.ofLp).sum fun _i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) := rfl + +lemma nndist_def [PseudoMetricSpace X] (f g : WithLp p <| ι →₀ X) : + nndist f g = + ((f.ofLp.zipWith nndist (nndist_self _) g.ofLp).sum fun _i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) := by + ext + simp only [coe_nndist, dist_def, sum, zipWith_apply, NNReal.coe_sum, NNReal.coe_rpow] + congr 2 + ext i + simp [← coe_nndist] + +/-- The L^1 metric on `ι`-many copies of a metric space `X` -/ +noncomputable instance [MetricSpace X] : MetricSpace (WithLp p <| ι →₀ X) := + EMetricSpace.toMetricSpaceOfDist + (fun f g ↦ ((f.ofLp.zipWith dist (dist_self _) g.ofLp).sum fun i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ)) + (fun f g ↦ by dsimp [sum]; positivity) fun f g ↦ by rw [edist_dist, dist_def] + +end Finsupp diff --git a/Mathlib/Analysis/Normed/Lp/WithLp.lean b/Mathlib/Analysis/Normed/Lp/WithLp.lean index 847baeb70474e4..cbf50d3dfae4e3 100644 --- a/Mathlib/Analysis/Normed/Lp/WithLp.lean +++ b/Mathlib/Analysis/Normed/Lp/WithLp.lean @@ -101,6 +101,9 @@ variable {K V} lemma ofLp_toLp (x : V) : ofLp (toLp p x) = x := rfl @[simp] lemma toLp_ofLp (x : WithLp p V) : toLp p (ofLp x) = x := rfl +lemma ext_iff {x y : WithLp p V} : x = y ↔ x.ofLp = y.ofLp := + (WithLp.equiv p V).injective.eq_iff.symm + lemma ofLp_surjective : Function.Surjective (@ofLp p V) := Function.RightInverse.surjective <| ofLp_toLp _ diff --git a/Mathlib/Data/ENNReal/Basic.lean b/Mathlib/Data/ENNReal/Basic.lean index 8679db698faccf..218392836d7fad 100644 --- a/Mathlib/Data/ENNReal/Basic.lean +++ b/Mathlib/Data/ENNReal/Basic.lean @@ -191,6 +191,12 @@ instance : Inhabited ℝ≥0∞ := ⟨0⟩ def recTopCoe {C : ℝ≥0∞ → Sort*} (top : C ∞) (coe : ∀ x : ℝ≥0, C x) (x : ℝ≥0∞) : C x := WithTop.recTopCoe top coe x +@[simp] lemma recTopCoe_top {C : ℝ≥0∞ → Sort*} (top : C ∞) (coe : ∀ x : ℝ≥0, C x) : + recTopCoe top coe ∞ = top := rfl + +@[simp] lemma recTopCoe_ofNNReal {C : ℝ≥0∞ → Sort*} (top : C ∞) (coe : ∀ x : ℝ≥0, C x) (x : ℝ≥0) : + recTopCoe top coe x = coe x := rfl + instance canLift : CanLift ℝ≥0∞ ℝ≥0 ofNNReal (· ≠ ∞) := WithTop.canLift @[simp] theorem none_eq_top : (none : ℝ≥0∞) = ∞ := rfl diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index b2f3b900f734bb..0f82aa39ee7c54 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -260,6 +260,10 @@ theorem sup_mem (s : Set α) (w₁ : ⊥ ∈ s) (w₂ : ∀ᵉ (x ∈ s) (y ∈ protected theorem sup_eq_bot_iff (f : β → α) (S : Finset β) : S.sup f = ⊥ ↔ ∀ s ∈ S, f s = ⊥ := by classical induction S using Finset.induction <;> simp [*] +@[to_additive (attr := simp)] +lemma sup_eq_one [One α] [IsBotOneClass α] : s.sup f = 1 ↔ ∀ i ∈ s, f i = 1 := by + simp [← bot_eq_one] + @[to_dual (attr := simp)] lemma sup_disjSum (s : Finset β) (t : Finset γ) (f : β ⊕ γ → α) : (s.disjSum t).sup f = (s.sup fun x ↦ f (.inl x)) ⊔ (t.sup fun x ↦ f (.inr x)) := @@ -663,14 +667,18 @@ end Sup' section Sup -variable [SemilatticeSup α] [OrderBot α] +variable [SemilatticeSup α] [OrderBot α] {s : Finset β} {f : β → α} @[to_dual] -theorem sup'_eq_sup {s : Finset β} (H : s.Nonempty) (f : β → α) : s.sup' H f = s.sup f := +theorem sup'_eq_sup (H : s.Nonempty) (f : β → α) : s.sup' H f = s.sup f := le_antisymm (sup'_le H f fun _ => le_sup) (Finset.sup_le fun _ => le_sup' f) +@[to_additive (attr := simp)] +lemma sup'_eq_one [One α] [IsBotOneClass α] (hs) : s.sup' hs f = 1 ↔ ∀ i ∈ s, f i = 1 := by + simp [sup'_eq_sup] + @[to_dual] -theorem coe_sup_of_nonempty {s : Finset β} (h : s.Nonempty) (f : β → α) : +theorem coe_sup_of_nonempty (h : s.Nonempty) (f : β → α) : (↑(s.sup f) : WithBot α) = s.sup ((↑) ∘ f) := by simp only [← sup'_eq_sup h, coe_sup' h] end Sup diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index 1e2243a3c8284b..f67fe2b24c949d 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -165,6 +165,7 @@ theorem _root_.Real.le_coe_toNNReal (r : ℝ) : r ≤ Real.toNNReal r := le_max_left r 0 @[bound] theorem coe_nonneg (r : ℝ≥0) : (0 : ℝ) ≤ r := r.2 +@[simp] lemma not_toReal_neg {r : ℝ≥0} : ¬ r.toReal < 0 := r.coe_nonneg.not_gt @[simp, norm_cast] theorem coe_mk (a : ℝ) (ha) : toReal (.mk a ha) = a := rfl From 2899f1514b0e12bd6c2dfa77f6f6bb0031cf7f21 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Sat, 27 Jun 2026 15:40:18 +0000 Subject: [PATCH 0402/1300] perf(CategoryTheory/Triangulated/TriangleShift): replace `cat_disch` by faster tactic (#41106) Replace `cat_disch` with `intros; ext <;> simp` in `Triangle.shiftFunctorAdd'`. See [Zulip](https://leanprover.zulipchat.com/#narrow/channel/116290-rss/topic/Significant.20commits.20to.20mathlib4/near/606901493). --- Mathlib/CategoryTheory/Triangulated/TriangleShift.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean b/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean index d2307a55e1cbaa..07fe07961a8c2f 100644 --- a/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean +++ b/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean @@ -111,7 +111,7 @@ noncomputable def Triangle.shiftFunctorAdd' (a b n : ℤ) (h : a + b = n) : ← dsimp% (CategoryTheory.shiftFunctorAdd' C a b (a + b) rfl).hom.naturality_assoc] simp only [shiftFunctorAdd'_eq_shiftFunctorAdd, Int.negOnePow_add, shiftFunctorComm_hom_app_comp_shift_shiftFunctorAdd_hom_app, add_comm a])) - (by cat_disch) + (by intros; ext <;> simp) set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in From 46c74195cd0b364ba4a771726ae86743748c8bcb Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Sat, 27 Jun 2026 18:13:43 +0000 Subject: [PATCH 0403/1300] feat(AlgebraicGeometry/Birational): Birationality and rationality of schemes (#39122) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a first step (of hopefully many) towards some basic birational geometry. This PR adds `Birational/Birational.lean`, which defines predicates `Birational`, `BirationalOver` and `IsRationalOver` for arbitrary schemes and provides basic API (e.g. that they are equivalence relations, and that affine space is rational). Some notes on the choice of definitions: There are multiple ways to define what it means for two schemes to be birational to each other. A common one is: "There exists a rational map with a rational inverse". However, this would require defining composition of rational maps, which is not always defined (In order to compose `f : X ⤏ Y` with `g : Y ⤏ Z`, you need at least `X` preirreducible, `Y` nonempty and `f` dominant). On the other hand, I can define "There exist dense subsets `U : Opens X` and `V : Opens Y` such that `U ≅ V` as schemes" for any two schemes `X` and `Y`, with no conditions. Hence I chose that as a definition. I'm also working on defining composition of rational maps (#39445), and once that's done, there should be a theorem connecting the two definitions. - [x] depends on: #39316 Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 1 + .../Birational/Birational.lean | 292 ++++++++++++++++++ Mathlib/AlgebraicGeometry/Restrict.lean | 2 + 3 files changed, 295 insertions(+) create mode 100644 Mathlib/AlgebraicGeometry/Birational/Birational.lean diff --git a/Mathlib.lean b/Mathlib.lean index a19ff93a09e8e4..e16fd6872a03c4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1349,6 +1349,7 @@ public import Mathlib.AlgebraicGeometry.AffineTransitionLimit public import Mathlib.AlgebraicGeometry.AlgClosed.Basic public import Mathlib.AlgebraicGeometry.AlgebraicCycle.Basic public import Mathlib.AlgebraicGeometry.Artinian +public import Mathlib.AlgebraicGeometry.Birational.Birational public import Mathlib.AlgebraicGeometry.Birational.Dominant public import Mathlib.AlgebraicGeometry.Birational.RationalMap public import Mathlib.AlgebraicGeometry.ColimitsOver diff --git a/Mathlib/AlgebraicGeometry/Birational/Birational.lean b/Mathlib/AlgebraicGeometry/Birational/Birational.lean new file mode 100644 index 00000000000000..a191e2e295f390 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/Birational/Birational.lean @@ -0,0 +1,292 @@ +/- +Copyright (c) 2026 Justus Springer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Justus Springer +-/ +module + +public import Mathlib.AlgebraicGeometry.AffineSpace +public import Mathlib.AlgebraicGeometry.Birational.RationalMap + +/-! +# Birationality and Rationality of schemes. + +This file defines partial isomorphisms between schemes and uses them to formalize +birationality and rationality. + +## Main definitions + +- `Scheme.PartialIso X Y`: an isomorphism between a dense open subscheme of `X` and a + dense open subscheme of `Y`. +- `Scheme.Birational X Y`: `X` and `Y` are birational, i.e. there exists a `PartialIso X Y`. +- `Scheme.BirationalOver sX sY`: `X` and `Y` are birational over `S` via structure maps + `sX : X ⟶ S` and `sY : Y ⟶ S`. +- `Scheme.IsRationalOver sX`: `X` is rational over `S` via structure map `sX : X ⟶ S`, + i.e. birational over `S` to some affine space `𝔸(n; S)`. + +-/ + +@[expose] public section + +universe u + +open CategoryTheory + +namespace AlgebraicGeometry.Scheme + +/-- A partial isomorphism from `X` to `Y` is an isomorphism between dense open subschemes +of `X` and `Y`. -/ +structure PartialIso (X Y : Scheme.{u}) where + /-- The source open subscheme of a partial isomorphism. -/ + source : X.Opens + dense_source : Dense (source : Set X) + /-- The target open subscheme of a partial isomorphism. -/ + target : Y.Opens + dense_target : Dense (target : Set Y) + /-- The underlying isomorphism of a partial isomorphism. -/ + iso : source.toScheme ≅ target.toScheme + +namespace PartialIso + +variable {X Y Z S : Scheme.{u}} {sX : X ⟶ S} {sY : Y ⟶ S} {sZ : Z ⟶ S} + +variable (sX sY) in +/-- A partial iso is an `S`-map if the underlying morphism is. -/ +abbrev IsOver (f : X.PartialIso Y) : Prop := + f.iso.hom ≫ f.target.ι ≫ sY = f.source.ι ≫ sX + +lemma ext_iff (f g : X.PartialIso Y) : + f = g ↔ ∃ (e : f.source = g.source) (e' : g.target = f.target), + f.iso = X.isoOfEq e ≪≫ g.iso ≪≫ Y.isoOfEq e' := by + constructor + · rintro rfl + simp + · obtain ⟨U₁, hU₁, U₂, hU₂, f⟩ := f + obtain ⟨V₁, hV₁, V₂, hU₂, g⟩ := g + simp only [forall_exists_index] + rintro rfl rfl e + simpa using e + +@[ext] +lemma ext (f g : X.PartialIso Y) (e : f.source = g.source) (e' : g.target = f.target) + (H : f.iso = X.isoOfEq e ≪≫ g.iso ≪≫ Y.isoOfEq e') : f = g := by + rw [ext_iff] + exact ⟨e, e', H⟩ + +variable (X) in +/-- The identity partial isomorphism on `X`, defined on all of `X`. -/ +@[refl, simps] +def refl : X.PartialIso X where + source := ⊤ + dense_source := dense_univ + target := ⊤ + dense_target := dense_univ + iso := Iso.refl _ + +/-- The inverse of a partial isomorphism. -/ +@[symm, simps] +def symm (f : X.PartialIso Y) : Y.PartialIso X where + source := f.target + dense_source := f.dense_target + target := f.source + dense_target := f.dense_source + iso := f.iso.symm + +set_option backward.defeqAttrib.useBackward true in +lemma IsOver.symm {f : X.PartialIso Y} (hf : f.IsOver sX sY) : f.symm.IsOver sY sX := by + simpa [IsOver, ← cancel_epi f.iso.hom] using Eq.symm hf + +/-- Compose two partial isomorphisms along a proof that the target of `f` equals the source +of `g`. See `trans` for the version that does not require this. -/ +@[simps] +noncomputable def trans' (f : X.PartialIso Y) (g : Y.PartialIso Z) (e : f.target = g.source) : + X.PartialIso Z where + source := f.source + dense_source := f.dense_source + target := g.target + dense_target := g.dense_target + iso := f.iso ≪≫ Y.isoOfEq e ≪≫ g.iso + +set_option backward.defeqAttrib.useBackward true in +lemma IsOver.trans' {f : X.PartialIso Y} {g : Y.PartialIso Z} {e : f.target = g.source} + (hf : f.IsOver sX sY) (hg : g.IsOver sY sZ) : (trans' f g e).IsOver sX sZ := by + simp [IsOver, ← hf, hg] + +/-- Restrict the source of a partial isomorphism to a smaller dense open. -/ +@[simps] +noncomputable def restrictSource (f : X.PartialIso Y) (U : Opens X) (hU : Dense (U : Set X)) + (hU' : U ≤ f.source) : X.PartialIso Y where + source := U + dense_source := hU + target := f.target.ι ''ᵁ f.iso.hom ''ᵁ f.source.ι ⁻¹ᵁ U + dense_target := + have := Opens.isDominant_ι f.dense_target + f.target.ι.denseRange.dense_image f.target.ι.continuous <| + f.iso.hom.denseRange.dense_image f.iso.hom.continuous <| + hU.preimage f.source.ι.isOpenEmbedding.isOpenMap + iso := (Opens.isoOfLE hU').symm ≪≫ + (f.iso.hom.isoImage (f.source.ι ⁻¹ᵁ U)) ≪≫ + (f.target.ι.isoImage (f.iso.hom ''ᵁ f.source.ι ⁻¹ᵁ U)) + +set_option backward.defeqAttrib.useBackward true in +lemma IsOver.restrictSource {f : X.PartialIso Y} (hf : f.IsOver sX sY) (U : Opens X) + (hU : Dense (U : Set X)) (hU' : U ≤ f.source) : + (f.restrictSource U hU hU').IsOver sX sY := by + simp [IsOver, hf] + +/-- Restrict the target of a partial isomorphism to a smaller dense open. -/ +@[simps! source target iso] +noncomputable def restrictTarget (f : X.PartialIso Y) (U : Opens Y) (hU : Dense (U : Set Y)) + (hU' : U ≤ f.target) : X.PartialIso Y := + (f.symm.restrictSource U hU hU').symm + +lemma IsOver.restrictTarget {f : X.PartialIso Y} (hf : f.IsOver sX sY) (U : Opens Y) + (hU : Dense (U : Set Y)) (hU' : U ≤ f.target) : + (f.restrictTarget U hU hU').IsOver sX sY := + (hf.symm.restrictSource U hU hU').symm + +/-- Compose two partial isomorphisms, restricting to the intersection of the intermediate opens. -/ +@[trans, simps! source target iso] +noncomputable def trans (f : X.PartialIso Y) (g : Y.PartialIso Z) : X.PartialIso Z := + have := f.dense_target.inter_of_isOpen_right g.dense_source g.source.2 + (f.restrictTarget _ this inf_le_left).trans' (g.restrictSource _ this inf_le_right) rfl + +lemma IsOver.trans {f : X.PartialIso Y} {g : Y.PartialIso Z} (hf : f.IsOver sX sY) + (hg : g.IsOver sY sZ) : (f.trans g).IsOver sX sZ := + (hf.restrictTarget _ _ _).trans' (hg.restrictSource _ _ _) + +/-- The underlying partial map of a partial isomorphism. -/ +@[simps] +def toPartialMap (f : X.PartialIso Y) : X.PartialMap Y where + domain := f.source + dense_domain := f.dense_source + hom := f.iso.hom ≫ f.target.ι + +/-- The underlying rational map of a partial isomorphism. -/ +abbrev toRationalMap (f : X.PartialIso Y) : X ⤏ Y := f.toPartialMap.toRationalMap + +/-- A scheme isomorphism viewed as a partial isomorphism defined on all of `X` and `Y`. -/ +@[simps] +noncomputable def ofIso (f : X ≅ Y) : X.PartialIso Y where + source := ⊤ + dense_source := dense_univ + target := ⊤ + dense_target := dense_univ + iso := X.topIso ≪≫ f ≪≫ Y.topIso.symm + +end PartialIso + +/-- `X` and `Y` are birational if there exists a partial isomorphism between them. -/ +@[stacks 0A20 "(1)"] +def Birational (X Y : Scheme.{u}) : Prop := Nonempty (PartialIso X Y) + +/-- Choose a partial isomorphism witnessing that `X` and `Y` are birational. -/ +noncomputable def Birational.partialIso {X Y : Scheme.{u}} (h : Birational X Y) : + PartialIso X Y := + Classical.choice h + +@[refl] +lemma Birational.refl (X : Scheme.{u}) : Birational X X := + ⟨.refl X⟩ + +@[symm] +lemma Birational.symm {X Y : Scheme.{u}} (h : Birational X Y) : Birational Y X := + ⟨h.partialIso.symm⟩ + +@[trans] +lemma Birational.trans {X Y Z : Scheme.{u}} (h₁ : Birational X Y) (h₂ : Birational Y Z) : + Birational X Z := + ⟨h₁.partialIso.trans h₂.partialIso⟩ + +/-- `X` and `Y` are birational over `S` if there exists a partial isomorphism between them +that is compatible with the structure maps to `S`. -/ +def BirationalOver {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) : Prop := + ∃ f : PartialIso X Y, f.IsOver sX sY + +/-- Choose a partial isomorphism witnessing that `X` and `Y` are birational over `S`. -/ +noncomputable def BirationalOver.partialIso {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) + (h : BirationalOver sX sY) := + h.choose + +lemma BirationalOver.partialIso_isOver {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) + (h : BirationalOver sX sY) : h.partialIso.IsOver sX sY := + h.choose_spec + +set_option backward.defeqAttrib.useBackward true in +lemma BirationalOver.refl {S X : Scheme.{u}} (sX : X ⟶ S) : BirationalOver sX sX := + ⟨.refl X, by simp [PartialIso.IsOver]⟩ + +lemma BirationalOver.symm {S X Y : Scheme.{u}} {sX : X ⟶ S} {sY : Y ⟶ S} + (h : BirationalOver sX sY) : BirationalOver sY sX := + ⟨h.partialIso.symm, h.partialIso_isOver.symm⟩ + +lemma BirationalOver.trans {S X Y Z : Scheme.{u}} {sX : X ⟶ S} {sY : Y ⟶ S} {sZ : Z ⟶ S} + (h₁ : BirationalOver sX sY) (h₂ : BirationalOver sY sZ) : + BirationalOver sX sZ := + ⟨h₁.partialIso.trans h₂.partialIso, h₁.partialIso_isOver.trans h₂.partialIso_isOver⟩ + +/-- `X` is rational over `S` (or `S`-rational) if it is birational over `S` to some +affine space `𝔸(n; S)`. Note that we do not require `n` to be finite here. -/ +@[mk_iff] +class IsRationalOver {S X : Scheme.{u}} (sX : X ⟶ S) : Prop where + exists_birationalOver_affineSpace (sX) : ∃ (n : Type u), BirationalOver sX (𝔸(n; S) ↘ S) + +instance (S : Scheme.{u}) (n : Type u) : IsRationalOver (𝔸(n; S) ↘ S) where + exists_birationalOver_affineSpace := ⟨n, .refl _⟩ + +/-- If a scheme `X` is `S`-birational to an `S`-rational scheme `Y`, then `X` is `S`-rational. -/ +lemma BirationalOver.isRationalOver {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) + [IsRationalOver sY] (h : BirationalOver sX sY) : IsRationalOver sX := by + obtain ⟨n, hn⟩ := IsRationalOver.exists_birationalOver_affineSpace sY + exact ⟨n, h.trans hn⟩ + +section DenseOpen + +variable {X S : Scheme.{u}} (U : Opens X) (sX : X ⟶ S) + +/-- A dense open set `U : Opens X` induces a partial isomorphism between `U` and `X`. -/ +@[simps] +def Opens.partialIsoOfDense (hU : Dense (U : Set X)) : PartialIso U X where + source := ⊤ + dense_source := dense_univ + target := U + dense_target := hU + iso := U.toScheme.topIso + +/-- A dense open set `U : Opens X` is birational to `X`. -/ +lemma Opens.birational_of_dense (hU : Dense (U : Set X)) : Birational U X := + ⟨U.partialIsoOfDense hU⟩ + +set_option backward.defeqAttrib.useBackward true in +/-- A dense open set `U : Opens X` of a scheme `X` over `S` is `S`-birational to `X`. -/ +lemma Opens.birationalOver_of_dense (hU : Dense (U : Set X)) : BirationalOver (U.ι ≫ sX) sX := + ⟨U.partialIsoOfDense hU, by simp [PartialIso.IsOver]⟩ + +/-- A dense open set `U : Opens X` of a `S`-rational scheme `X` is `S`-rational. -/ +lemma Opens.isRationalOver_of_dense (hU : Dense (U : Set X)) [IsRationalOver sX] : + IsRationalOver (U.ι ≫ sX) := by + obtain ⟨n, hn⟩ := IsRationalOver.exists_birationalOver_affineSpace sX + exact ⟨n, (U.birationalOver_of_dense sX hU).trans hn⟩ + +end DenseOpen + +section OpenImmersion + +variable {X U S : Scheme.{u}} + +/-- A dominant open immersion `f : U ⟶ X` induces a partial isomorphism between `U` and `X`. -/ +@[simps! source target iso] +noncomputable def Hom.partialIso (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] : U.PartialIso X := + (PartialIso.ofIso f.isoOpensRange).trans' (f.opensRange.partialIsoOfDense f.denseRange) rfl + +lemma Hom.birational (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] : Birational U X := + ⟨f.partialIso⟩ + +set_option backward.defeqAttrib.useBackward true in +lemma Hom.birationalOver (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] (sX : X ⟶ S) (sU : U ⟶ S) + (hf : f ≫ sX = sU) : BirationalOver sU sX := + ⟨f.partialIso, by simp [PartialIso.IsOver, hf]⟩ + +end OpenImmersion + +end AlgebraicGeometry.Scheme diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index bb23bc5250d9e7..6e9b51c80d71e1 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -59,6 +59,8 @@ instance : IsOpenImmersion U.ι := inferInstanceAs (IsOpenImmersion (X.ofRestric @[simps! over] instance : U.toScheme.CanonicallyOver X where hom := U.ι +lemma ι_comp_over (S : Scheme.{u}) [X.Over S] : U.ι ≫ X ↘ S = U.toScheme ↘ S := rfl + instance (U : X.Opens) : U.ι.IsOver X where lemma toScheme_carrier : (U : Type u) = (U : Set X) := rfl From e4bf531c0c6668a99814005f730f3b8ada39feee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Renison?= <85908989+IvanRenison@users.noreply.github.com> Date: Sat, 27 Jun 2026 18:57:53 +0000 Subject: [PATCH 0404/1300] feat(Combinatorics/SimpleGraph/Coloring): add lemmas about coloring and maps (#37598) --- .../SimpleGraph/Coloring/Vertex.lean | 36 ++++++++++++++----- Mathlib/Combinatorics/SimpleGraph/Maps.lean | 3 ++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean index 0d06d645712f83..f8091d4860295c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean @@ -127,6 +127,11 @@ theorem Coloring.isIndepSet_colorClass (c : α) : G.IsIndepSet <| C.colorClass c theorem Coloring.color_classes_independent (c : α) : IsAntichain G.Adj (C.colorClass c) := C.isIndepSet_colorClass c +/-- Coloring induced from a homomorphism to a colored graph. -/ +abbrev Coloring.comap {V' : Type*} {G' : SimpleGraph V'} {α : Type*} (C : G'.Coloring α) + (f : G →g G') : G.Coloring α := + C.comp f + -- TODO make this computable noncomputable instance [Fintype V] [Fintype α] : Fintype (Coloring G α) := by classical @@ -289,9 +294,9 @@ noncomputable def Colorable.toColoring [Fintype α] {n : ℕ} (hc : G.Colorable rw [← Fintype.card_fin n] at hn exact G.recolorOfCardLE hn hc.some -theorem Colorable.of_hom {V' : Type*} {G' : SimpleGraph V'} (f : G →g G') {n : ℕ} +theorem Colorable.of_hom {V' : Type*} {G' : SimpleGraph V'} {n : ℕ} (f : G →g G') (h : G'.Colorable n) : G.Colorable n := - ⟨(h.toColoring (by simp)).comp f⟩ + ⟨h.some.comap f⟩ theorem colorable_iff_exists_bdd_nat_coloring (n : ℕ) : G.Colorable n ↔ ∃ C : G.Coloring ℕ, ∀ v, C v < n := by @@ -406,9 +411,9 @@ theorem chromaticNumber_mono (G' : SimpleGraph V) (h : G ≤ G') : G.chromaticNumber ≤ G'.chromaticNumber := chromaticNumber_le_of_forall_imp fun _ => Colorable.mono_left h -theorem chromaticNumber_mono_of_hom {V' : Type*} {G' : SimpleGraph V'} - (f : G →g G') : G.chromaticNumber ≤ G'.chromaticNumber := - chromaticNumber_le_of_forall_imp fun _ => Colorable.of_hom f +theorem chromaticNumber_mono_of_hom {V' : Type*} {G' : SimpleGraph V'} (f : G →g G') : + G.chromaticNumber ≤ G'.chromaticNumber := + chromaticNumber_le_of_forall_imp fun _ hc => hc.of_hom f lemma card_le_chromaticNumber_iff_forall_surjective [Fintype α] : card α ≤ G.chromaticNumber ↔ ∀ C : G.Coloring α, Surjective C := by @@ -615,10 +620,23 @@ theorem colorable_of_cliqueFree (f : ∀ (i : ι), V i) end completeMultipartiteGraph +variable {W : Type*} {H : SimpleGraph W} + /-- If `H` is not `n`-colorable and `G` is `n`-colorable, then `G` is `H.Free`. -/ -theorem free_of_colorable {W : Type*} {H : SimpleGraph W} - (nhc : ¬H.Colorable n) (hc : G.Colorable n) : H.Free G := by - contrapose nhc with hc' - exact ⟨hc.some.comp hc'.some.toHom⟩ +theorem free_of_colorable (nhc : ¬H.Colorable n) (hc : G.Colorable n) : H.Free G := by + contrapose! nhc with hc' + exact hc.of_hom hc'.some.toHom + +/-! ### Isomorphisms -/ + +/-- Equivalence of colorings induced by isomorphisms of graphs and equivalence of colors. -/ +def coloringCongr (f : G ≃g H) (g : α ≃ β) : G.Coloring α ≃ H.Coloring β := + f.homCongr (Iso.completeGraph g) + +lemma colorable_congr (f : G ≃g H) : G.Colorable n ↔ H.Colorable n := + ⟨fun hc ↦ hc.of_hom f.symm.toHom, fun hc ↦ hc.of_hom f.toHom⟩ + +lemma chromaticNumber_congr (f : G ≃g H) : G.chromaticNumber = H.chromaticNumber := + le_antisymm (chromaticNumber_mono_of_hom f.toHom) (chromaticNumber_mono_of_hom f.symm.toHom) end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index 07a8cc9ab92df0..404a8eca0f79ef 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -730,6 +730,9 @@ theorem toEmbedding_completeGraph {α β : Type*} (f : α ≃ β) : variable {G'' : SimpleGraph X} {G''' : SimpleGraph Y} +/-- Equivalence of homomorphisms induced by isomorphisms of graphs. -/ +abbrev homCongr (f' : G'' ≃g G''') : G →g G'' ≃ G' →g G''' := RelIso.relHomCongr f f' + /-- Composition of graph isomorphisms. -/ abbrev comp (f' : G' ≃g G'') (f : G ≃g G') : G ≃g G'' := f.trans f' From 48fca283afb57d96c5a4dbd7c5dbe5efcf13154c Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Sat, 27 Jun 2026 19:41:43 +0000 Subject: [PATCH 0405/1300] chore(ci): bump pinned GitHub Actions to latest (#41089) - actions/attest-build-provenance: v4.1.0 -> v4.1.1 - actions/setup-python: v6.2.0 -> v6.3.0 - softprops/action-gh-release: v3.0.0 -> v3.0.1 - actions/cache: v5.0.5 -> v6.1.0 (ESM migration + read-only cache handling) - zulip/github-actions-zulip/send-message: v2.0.1 -> v2.0.2 - leanprover-community/privilege-escalation-bridge: v1.2.0 -> v1.3.0 - leanprover-community/gh-problem-matcher-wrap: pin to the node24 build (clears the Node 20 deprecation warning) - kim-em/github-actions-ensure-sha-pinned-actions: pin to v5.0.0 instead of a feature branch - dcarbone/install-jq-action: v3.2.0 -> v4.0.1 (default jq -> 1.8.2) actions/checkout was already bumped to v7.0.0 on master (#41084). --- .github/actions/setup-build-env/action.yml | 2 +- .github/workflows/PR_summary.yml | 2 +- .github/workflows/build_template.yml | 12 ++++++------ .github/workflows/commit_verification.yml | 2 +- .github/workflows/commit_verification_wf_run.yml | 2 +- .github/workflows/daily.yml | 12 ++++++------ .github/workflows/docker_build.yml | 2 +- .github/workflows/lake_cache_shadow.yml | 4 ++-- .github/workflows/latest_import.yml | 4 ++-- .github/workflows/long_file_report.yml | 2 +- .github/workflows/maintainer_bors.yml | 2 +- .github/workflows/maintainer_bors_wf_run.yml | 4 ++-- .github/workflows/maintainer_merge.yml | 2 +- .github/workflows/maintainer_merge_wf_run.yml | 4 ++-- .github/workflows/nightly_bump_and_merge.yml | 2 +- .github/workflows/nightly_detect_failure.yml | 6 +++--- .github/workflows/olean_report.yaml | 2 +- .github/workflows/olean_report_wf_run.yaml | 2 +- .github/workflows/pre-commit.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/remove_deprecated_decls.yml | 6 +++--- .github/workflows/rm_set_option.yml | 8 ++++---- .github/workflows/shake.yaml | 4 ++-- .github/workflows/technical_debt_metrics.yml | 2 +- .github/workflows/update_dependencies.yml | 2 +- .github/workflows/update_dependencies_zulip.yml | 8 ++++---- .github/workflows/weekly-lints.yml | 6 +++--- .github/workflows/zulip_emoji_ci_status.yaml | 2 +- .github/workflows/zulip_emoji_closed_pr.yaml | 2 +- .github/workflows/zulip_emoji_labelling.yaml | 2 +- .github/workflows/zulip_emoji_merge_delegate.yaml | 2 +- 31 files changed, 58 insertions(+), 58 deletions(-) diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index f4a0e092a7eb50..e24ab2e2a92876 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -45,7 +45,7 @@ runs: # The Hoskinson runners may not have jq installed, so do that now. - name: 'Setup jq' - uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 + uses: dcarbone/install-jq-action@4fcb5062d7ce9bc4382d1a352d19ba3ba2c317c1 # v4.0.1 # Compute the trust-classified container target and read fallback for this # job. Sets MATHLIB_CACHE_FROM / MATHLIB_CACHE_PRIMARY in env so every diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index 5d73c1426fc510..4565d89484f7cd 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -67,7 +67,7 @@ jobs: fi - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: 3.12 diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 3ab58099ebbc78..de0366348b2616 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -190,7 +190,7 @@ jobs: lake exe mk_all --check - name: begin gh-problem-match-wrap for build step - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: add # In order to be able to run a multiline script, we need to add/remove the problem matcher before and after. linters: lean @@ -211,7 +211,7 @@ jobs: ../tools-branch/scripts/lake-build-with-retry.sh Mathlib # results of build at pr-branch/.lake/build_summary_Mathlib.json - name: end gh-problem-match-wrap for build step - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: remove linters: lean @@ -463,7 +463,7 @@ jobs: # from the build job's outputs, and the problem-matcher wrap is gated to match. - name: begin gh-problem-match-wrap for test step if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: add # In order to be able to run a multiline script, we need to add/remove the problem matcher before and after. linters: lean @@ -475,7 +475,7 @@ jobs: ../tools-branch/scripts/lake-build-wrapper.py .lake/build_summary_MathlibTest.json lake --iofail test - name: end gh-problem-match-wrap for test step if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: remove linters: lean @@ -485,7 +485,7 @@ jobs: # lint feedback is still reported. The problem-matcher wrap is gated to match. - name: begin gh-problem-match-wrap for shake and lint steps if: ${{ always() && (needs.build.outputs.build-outcome == 'success' || needs.build.outputs.build-outcome == 'failure') }} - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: add # In order to be able to run a multiline script, we need to add/remove the problem matcher before and after. linters: gcc @@ -538,7 +538,7 @@ jobs: - name: end gh-problem-match-wrap for shake and lint steps if: ${{ always() && (needs.build.outputs.build-outcome == 'success' || needs.build.outputs.build-outcome == 'failure') }} - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: remove linters: gcc diff --git a/.github/workflows/commit_verification.yml b/.github/workflows/commit_verification.yml index e14544cb1ad433..d62c03386f5ba2 100644 --- a/.github/workflows/commit_verification.yml +++ b/.github/workflows/commit_verification.yml @@ -111,7 +111,7 @@ jobs: }' > bridge-outputs.json - name: Emit bridge artifact - uses: leanprover-community/privilege-escalation-bridge/emit@f5dfe313a79647c07315b451b2dc2a81a161a50d # v1.2.0 + uses: leanprover-community/privilege-escalation-bridge/emit@ea7d63d1c8ece92a8e89b6a6d8fda40603167a91 # v1.3.0 with: artifact: workflow-data outputs_file: bridge-outputs.json diff --git a/.github/workflows/commit_verification_wf_run.yml b/.github/workflows/commit_verification_wf_run.yml index 622820aae6f452..dec43f0e0a8bdb 100644 --- a/.github/workflows/commit_verification_wf_run.yml +++ b/.github/workflows/commit_verification_wf_run.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Consume bridge artifact id: bridge - uses: leanprover-community/privilege-escalation-bridge/consume@f5dfe313a79647c07315b451b2dc2a81a161a50d # v1.2.0 + uses: leanprover-community/privilege-escalation-bridge/consume@ea7d63d1c8ece92a8e89b6a6d8fda40603167a91 # v1.3.0 with: token: ${{ github.token }} artifact: workflow-data diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index d737a444edb805..3865c77fd5e2b4 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -122,7 +122,7 @@ jobs: - name: Post success message for leanchecker on Zulip if: steps.get-status.outputs.job_conclusion == 'success' - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' @@ -135,7 +135,7 @@ jobs: - name: Post failure / cancelled message for leanchecker on Zulip if: steps.get-status.outputs.job_conclusion != 'success' - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' @@ -245,7 +245,7 @@ jobs: - name: Post success message for mathlib_test_executable on Zulip if: steps.get-status.outputs.job_conclusion == 'success' - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' @@ -258,7 +258,7 @@ jobs: - name: Post failure / cancelled message for mathlib_test_executable on Zulip if: steps.get-status.outputs.job_conclusion != 'success' - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' @@ -410,7 +410,7 @@ jobs: - name: Post success message for nanoda on Zulip if: steps.get-status.outputs.job_conclusion == 'success' - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' @@ -423,7 +423,7 @@ jobs: - name: Post failure / cancelled message for nanoda on Zulip if: steps.get-status.outputs.job_conclusion != 'success' - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index c46e08fd9934d8..3e0c28a07aaa7c 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -59,7 +59,7 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - name: Generate artifact attestation - uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 with: subject-name: ${{ env.REGISTRY }}/${{ env.REPO_NAME }}/${{ matrix.image }} subject-digest: ${{ steps.push.outputs.digest }} diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 099472ca7b57f0..68a7710e79bc1c 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -95,7 +95,7 @@ jobs: run: echo "::notice::Lake cache shadow on ref ${{ inputs.mathlib_ref || 'master' }} run ${{ github.run_id }}" - name: Setup jq - uses: dcarbone/install-jq-action@b7ef57d46ece78760b4019dbc4080a1ba2a40b45 # v3.2.0 + uses: dcarbone/install-jq-action@4fcb5062d7ce9bc4382d1a352d19ba3ba2c317c1 # v4.0.1 - name: Checkout tools branch uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -544,7 +544,7 @@ jobs: } >> "$GITHUB_OUTPUT" - name: Send to Zulip - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/latest_import.yml b/.github/workflows/latest_import.yml index 447160b95b43eb..8aacc26bd9584d 100644 --- a/.github/workflows/latest_import.yml +++ b/.github/workflows/latest_import.yml @@ -68,7 +68,7 @@ jobs: - name: build mathlib id: build - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: linters: lean run: | @@ -86,7 +86,7 @@ jobs: tee "$GITHUB_OUTPUT" - name: Post output to Zulip - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/long_file_report.yml b/.github/workflows/long_file_report.yml index f0febf9b6d215f..03e0a37bf3400c 100644 --- a/.github/workflows/long_file_report.yml +++ b/.github/workflows/long_file_report.yml @@ -30,7 +30,7 @@ jobs: printf $'summary<> "$GITHUB_OUTPUT" - name: Post output to Zulip - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/update_dependencies.yml b/.github/workflows/update_dependencies.yml index 30e6e281b12a8e..5974d14528aab1 100644 --- a/.github/workflows/update_dependencies.yml +++ b/.github/workflows/update_dependencies.yml @@ -206,7 +206,7 @@ jobs: - name: Send Zulip message (failure) if: ${{ failure() }} - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/update_dependencies_zulip.yml b/.github/workflows/update_dependencies_zulip.yml index d511ecd7ca857a..f0520210cfa84d 100644 --- a/.github/workflows/update_dependencies_zulip.yml +++ b/.github/workflows/update_dependencies_zulip.yml @@ -33,7 +33,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.x' @@ -89,7 +89,7 @@ jobs: return output; - name: Send Zulip message - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' @@ -123,7 +123,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.x' @@ -168,7 +168,7 @@ jobs: - name: Send Zulip message if: ${{ steps.construct_message.outputs.result != '' }} - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/weekly-lints.yml b/.github/workflows/weekly-lints.yml index 5df2eddf43434a..515906d8713e11 100644 --- a/.github/workflows/weekly-lints.yml +++ b/.github/workflows/weekly-lints.yml @@ -66,7 +66,7 @@ jobs: lake build Mathlib.Init - name: Add GitHub problem matcher wrapper - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: add linters: lean @@ -88,13 +88,13 @@ jobs: "${CI_SCRIPTS_DIR}/reporting/zulip_build_report.sh" "${lean_outfile}" > "${GITHUB_OUTPUT}" - name: Remove GitHub problem matcher wrapper - uses: leanprover-community/gh-problem-matcher-wrap@20007cb926a46aa324653a387363b52f07709845 # 2025-04-23 + uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: remove linters: lean - name: Post output to Zulip - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/zulip_emoji_ci_status.yaml b/.github/workflows/zulip_emoji_ci_status.yaml index b2a46fccb8c0d2..8ab30ec4c2ef23 100644 --- a/.github/workflows/zulip_emoji_ci_status.yaml +++ b/.github/workflows/zulip_emoji_ci_status.yaml @@ -86,7 +86,7 @@ jobs: - name: Set up Python if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_closed_pr.yaml b/.github/workflows/zulip_emoji_closed_pr.yaml index b0488d76541fe2..2dbf54efff0875 100644 --- a/.github/workflows/zulip_emoji_closed_pr.yaml +++ b/.github/workflows/zulip_emoji_closed_pr.yaml @@ -47,7 +47,7 @@ jobs: - name: Set up Python if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || github.event_name == 'reopened' }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_labelling.yaml b/.github/workflows/zulip_emoji_labelling.yaml index d462d1a878eeb4..5a019050928fdc 100644 --- a/.github/workflows/zulip_emoji_labelling.yaml +++ b/.github/workflows/zulip_emoji_labelling.yaml @@ -27,7 +27,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_merge_delegate.yaml b/.github/workflows/zulip_emoji_merge_delegate.yaml index 7d701d874aa6c4..9883c1f0263082 100644 --- a/.github/workflows/zulip_emoji_merge_delegate.yaml +++ b/.github/workflows/zulip_emoji_merge_delegate.yaml @@ -30,7 +30,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.x' From b2b425516745501699f012f5a96fb50a826b3281 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sat, 27 Jun 2026 21:54:37 +0000 Subject: [PATCH 0406/1300] chore: use more `mkApp(Opt)M` in the differential geometry elaborators (#40933) This is more concise (and perhaps even more efficient) than converting an existing expression to Syntax and re-elaborating that. No need for this. --- Mathlib/Geometry/Manifold/Notation.lean | 37 +++++-------------- .../Notation/Advanced.lean | 12 +++--- .../DifferentialGeometry/Notation/Basic.lean | 4 +- .../DifferentialGeometry/Notation/Sphere.lean | 4 +- 4 files changed, 19 insertions(+), 38 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 3c34b70a359791..a3d519596a8156 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -430,7 +430,7 @@ where let some K ← guessBaseFieldForNormedSpace F | throwError "Couldn't find a `NormedSpace` structure on `{F}`" let tgtMod ← mkAppOptM ``modelWithCornersSelf #[K, none, F, none, none] - mkAppM ``ModelWithCorners.prod #[baseModel, tgtMod] + mkAppM ``ModelWithCorners.prod #[baseModel, tgtMod] | _ => throwError s!"{e} is a TotalSpace {F} {V}, but {V} is not a pi type --- \ could not infer base of the bundle" @@ -440,18 +440,14 @@ where match_expr V with | TangentSpace _k _ _E _ _ _H _ I M _ _ => do trace[Elab.DiffGeo.MDiff] "`{V}` is the total space of the `TangentBundle` of `{M}`" - let srcIT : Term ← Term.exprToSyntax I - let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT) - Term.elabTerm resTerm none + mkAppM ``ModelWithCorners.tangent #[I] | _ => throwError "`{V}` is not a `TangentSpace`" /-- Attempt to find a model on a `TangentBundle` -/ fromTangentBundle : TermElabM Expr := do match_expr e with | TangentBundle _k _ _E _ _ _H _ I M _ _ => do trace[Elab.DiffGeo.MDiff] "`{e}` is a `TangentBundle` over model `{I}` on `{M}`" - let srcIT : Term ← Term.exprToSyntax I - let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT) - Term.elabTerm resTerm none + mkAppM ``ModelWithCorners.tangent #[I] | _ => throwError "`{e}` is not a `TangentBundle`" /-- Attempt to find the trivial model on a normed space. -/ fromNormedSpace : TermElabM FindModelResult := do @@ -534,18 +530,13 @@ where -- the standard model with corners. -- Therefore, we only check definitional equality at reducible transparency. let (k, _E, _F) ← isCLMReduciblyDefeqCoefficients e - let eK : Term ← Term.exprToSyntax k - let eT : Term ← Term.exprToSyntax e - let iTerm : Term ← ``(𝓘($eK, $eT)) - Term.elabTerm iTerm none + mkAppOptM ``modelWithCornersSelf #[k, none, e, none, none] /-- Attempt to find a model with corners on a Euclidean space, half-space or quadrant -/ fromEuclideanSpace : TermElabM Expr := do -- We don't use `match_expr` to avoid importing `EuclideanHalfSpace`. match (← instantiateMVars e).cleanupAnnotations with | mkApp2 (.const `EuclideanSpace _) k _n => - let eK : Term ← Term.exprToSyntax k - let eT : Term ← Term.exprToSyntax e - Term.elabTerm (← ``(𝓘($eK, $eT))) none + mkAppOptM ``modelWithCornersSelf #[k, none, e, none, none] | mkApp2 (.const `EuclideanHalfSpace _) n _ => mkAppOptM `modelWithCornersEuclideanHalfSpace #[n, none] | mkApp (.const `EuclideanQuadrant _) n => @@ -606,9 +597,7 @@ where | _ => return none if let some (k, R) := searchNormedAlgebra then trace[Elab.DiffGeo.MDiff] "found a normed algebra: `{α}` is a normed `{k}`-algebra" - let eK : Term ← Term.exprToSyntax k - let eR : Term ← Term.exprToSyntax R - Term.elabTerm (← ``(𝓘($eK, $eR))) none + mkAppOptM ``modelWithCornersSelf #[k, none, R, none, none] else trace[Elab.DiffGeo.MDiff] "`{α}` is not a normed algebra on the nose: try via a space of \ continuous linear maps" @@ -633,9 +622,7 @@ where match normedSpace? with | some (k, _R) => trace[Elab.DiffGeo.MDiff] "found a normed space: `{V}` is a normed space over `{k}`" - let eK : Term ← Term.exprToSyntax k - let eα : Term ← Term.exprToSyntax α - Term.elabTerm (← ``(𝓘($eK, $eα))) none + mkAppOptM ``modelWithCornersSelf #[k, none, α, none, none] | _ => throwError "Found no `NormedSpace` structure on `{V}` among local instances" else -- NB. If further instances of `NormedAlgebra` arise in practice, adding another check @@ -724,10 +711,7 @@ where | _ => throwError "`{e}` is not a sphere in a real normed space" /-- Attempt to find a model with corners from a normed field. We attempt to find a global instance here. -/ - fromNormedField : TermElabM Expr := do - let eT : Term ← Term.exprToSyntax e - let iTerm : Term ← ``(𝓘($eT, $eT)) - Term.elabTerm iTerm none + fromNormedField : TermElabM Expr := mkAppOptM ``modelWithCornersSelf #[e, none, e, none, none] /-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), using the local context to infer the appropriate instance. @@ -802,10 +786,7 @@ where throwError "`{e}` is a product of normed spaces, so there are two potential models with \ corners\nFor now, please specify the model by hand." -- Otherwise, we are not a normed space, and normally form the product model. - let eTerm : Term ← Term.exprToSyntax srcE - let fTerm : Term ← Term.exprToSyntax srcF - let iTerm : Term ← ``(ModelWithCorners.prod $eTerm $fTerm) - return some { model := ← Term.elabTerm iTerm none } + return some { model := ← mkAppM ``ModelWithCorners.prod #[srcE, srcF] } | Sum E F => trace[Elab.DiffGeo.MDiff] "Expression `{e}` is a direct sum of `{E}` and `{F}`\n\ We assume the models match, and only look into the first summand" diff --git a/MathlibTest/DifferentialGeometry/Notation/Advanced.lean b/MathlibTest/DifferentialGeometry/Notation/Advanced.lean index f6e277d4f8ae00..1f0384072fa830 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Advanced.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Advanced.lean @@ -378,10 +378,10 @@ trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `M` `ContinuousLinearMap id' E'' E'''` is not a coercion of a set to a type [Elab.DiffGeo.MDiff] 💥️ NormedField [Elab.DiffGeo.MDiff] Failed with error: - failed to synthesize instance of type class + failed to synthesize NontriviallyNormedField (ContinuousLinearMap id' E'' E''') ⏎ - Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command. + Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. [Elab.DiffGeo.MDiff] 💥️ InnerProductSpace [Elab.DiffGeo.MDiff] Failed with error: Couldn't find an `InnerProductSpace` structure on `ContinuousLinearMap id' E'' E'''` among local instances. @@ -481,10 +481,10 @@ trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `M` `ContinuousLinearMap σ E'' E''''` is not a coercion of a set to a type [Elab.DiffGeo.MDiff] 💥️ NormedField [Elab.DiffGeo.MDiff] Failed with error: - failed to synthesize instance of type class + failed to synthesize NontriviallyNormedField (ContinuousLinearMap σ E'' E'''') ⏎ - Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command. + Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. [Elab.DiffGeo.MDiff] 💥️ InnerProductSpace [Elab.DiffGeo.MDiff] Failed with error: Couldn't find an `InnerProductSpace` structure on `ContinuousLinearMap σ E'' E''''` among local instances. @@ -686,10 +686,10 @@ trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `↑(Set.Icc x y)` `Set.Icc x y` is not a sphere in a real normed space [Elab.DiffGeo.MDiff] 💥️ NormedField [Elab.DiffGeo.MDiff] Failed with error: - failed to synthesize instance of type class + failed to synthesize NontriviallyNormedField ↑(Set.Icc x y) ⏎ - Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command. + Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. [Elab.DiffGeo.MDiff] 💥️ InnerProductSpace [Elab.DiffGeo.MDiff] Failed with error: Couldn't find an `InnerProductSpace` structure on `↑(Set.Icc x y)` among local instances. diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 4461fab938c58c..055a66b9f12458 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -1470,10 +1470,10 @@ trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `Unit` `Unit` is not a coercion of a set to a type [Elab.DiffGeo.MDiff] 💥️ NormedField [Elab.DiffGeo.MDiff] Failed with error: - failed to synthesize instance of type class + failed to synthesize NontriviallyNormedField Unit ⏎ - Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command. + Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. [Elab.DiffGeo.MDiff] 💥️ InnerProductSpace [Elab.DiffGeo.MDiff] Failed with error: Couldn't find an `InnerProductSpace` structure on `Unit` among local instances. diff --git a/MathlibTest/DifferentialGeometry/Notation/Sphere.lean b/MathlibTest/DifferentialGeometry/Notation/Sphere.lean index 8d22d6a5804056..854d1cd7dcfd97 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Sphere.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Sphere.lean @@ -230,10 +230,10 @@ trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `↑(Metric.sphere Found no fact `finrank ℝ E'' = n + 1` in the local context [Elab.DiffGeo.MDiff] 💥️ NormedField [Elab.DiffGeo.MDiff] Failed with error: - failed to synthesize instance of type class + failed to synthesize NontriviallyNormedField ↑(Metric.sphere 0 1) ⏎ - Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command. + Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. [Elab.DiffGeo.MDiff] 💥️ InnerProductSpace [Elab.DiffGeo.MDiff] Failed with error: Couldn't find an `InnerProductSpace` structure on `↑(Metric.sphere 0 1)` among local instances. From 70ba12a7d8c6241f0e608ca5896504c856f671d2 Mon Sep 17 00:00:00 2001 From: Rida Hamadani Date: Sun, 28 Jun 2026 09:16:42 +0000 Subject: [PATCH 0407/1300] feat(SimpleGraph): `dropLast` of a cycle is a path (#35295) --- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index a5813a65160535..62a598da27c8db 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -358,6 +358,9 @@ lemma IsPath.tail {p : G.Walk u v} (hp : p.IsPath) : p.tail.IsPath := by | cons hadj p => simp_all [Walk.isPath_def] +theorem IsCycle.isPath_dropLast {p : G.Walk u u} (h : p.IsCycle) : p.dropLast.IsPath := + .mk' <| p.support_dropLast h.not_nil ▸ h.nodup_dropLast_support + theorem IsPath.dropLast (hp : p.IsPath) : p.dropLast.IsPath := hp.take _ From c8b35d4b1b468c70850db3b6e9fd0332fc9ed5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sun, 28 Jun 2026 09:35:23 +0000 Subject: [PATCH 0408/1300] feat(RingTheory): adjoining a root is preserved under base change (#40360) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From Toric Co-authored-by: Andrew Yang Co-authored-by: Michał Mrugała --- Mathlib/RingTheory/AdjoinRoot.lean | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index 42bca0ed2495bc..bf58bd9bd4f793 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -977,6 +977,42 @@ theorem quotEquivQuotMap_symm_apply_mk (f g : R[X]) (I : Ideal R) : end +section TensorProduct +variable {R S T U : Type*} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] + [CommRing U] [Algebra R U] {p : Polynomial S} + +open Algebra TensorProduct + +variable (p) in +/-- Adjoining a root is preserved under base change. -/ +def tensorAlgEquiv (p : S[X]) (q : (T ⊗[R] S)[X]) (h : p.map includeRight.toRingHom = q) : + T ⊗[R] AdjoinRoot p ≃ₐ[T] AdjoinRoot q := by + refine .ofAlgHom + (Algebra.TensorProduct.lift (algHom T T _) + (mapAlgHom includeRight p q <| by exact h.symm.dvd) fun _ _ ↦ .all ..) + (liftAlgHom _ (Algebra.TensorProduct.map (AlgHom.id T T) + (((Algebra.ofId S (AdjoinRoot p))).restrictScalars R)) (1 ⊗ₜ root _) ?_) ?_ ?_ + · simp only [← h, AlgHom.toRingHom_eq_coe] + rw [Polynomial.eval₂_map] + change Polynomial.eval₂ ((Algebra.TensorProduct.map (AlgHom.id R T) _).comp _).toRingHom _ _ = _ + simp only [map_comp_includeRight, AlgHom.toRingHom_eq_coe, AlgHom.comp_toRingHom, + AlgHom.coe_restrictScalars, ← Polynomial.eval₂_map] + change Polynomial.eval₂ _ ((RingHomClass.toRingHom includeRight) (root p)) (p.map (of _)) = _ + rw [Polynomial.eval₂_hom] + simp [Polynomial.eval_map] + · ext + · simp [Algebra.ofId_apply] + simp + · ext : 3 <;> simp + +@[simp] lemma tensorAlgEquiv_root (p : S[X]) (q : Polynomial (T ⊗[R] S)) (h) : + tensorAlgEquiv p q h (1 ⊗ₜ root p) = root q := by simp [tensorAlgEquiv] + +@[simp] lemma tensorAlgEquiv_of (p : S[X]) (q : Polynomial (T ⊗[R] S)) (h) {x : S} : + tensorAlgEquiv p q h (1 ⊗ₜ of p x) = of q (1 ⊗ₜ x):= by simp [tensorAlgEquiv] + +end TensorProduct + end AdjoinRoot namespace PowerBasis From b3efe7e8a0863c414a6eb8b1fa19c429f95a81e2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sun, 28 Jun 2026 14:03:13 +0000 Subject: [PATCH 0409/1300] chore: adaptations for batteries#1863 (#40820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the `defLemma` being removed, we delete all corresponding `nolint` entries. Co-authored-by: mathlib-nightly-testing[bot] Co-authored-by: F. G. Dorais Co-authored-by: François G. Dorais --- Mathlib/CategoryTheory/Category/Preorder.lean | 2 +- Mathlib/Combinatorics/Hindman.lean | 6 +++--- Mathlib/Data/Nat/Fib/Zeckendorf.lean | 2 +- Mathlib/Logic/Basic.lean | 2 +- Mathlib/Topology/Algebra/WithZeroTopology.lean | 4 ---- lake-manifest.json | 2 +- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Mathlib/CategoryTheory/Category/Preorder.lean b/Mathlib/CategoryTheory/Category/Preorder.lean index 8e91d464d4b631..4f84c09560328b 100644 --- a/Mathlib/CategoryTheory/Category/Preorder.lean +++ b/Mathlib/CategoryTheory/Category/Preorder.lean @@ -81,7 +81,7 @@ theorem leOfHom {x y : X} (h : x ⟶ y) : x ≤ y := h.down.down set_option linter.defProp false in -@[nolint defLemma, inherit_doc leOfHom] +@[inherit_doc leOfHom] abbrev _root_.Quiver.Hom.le := @leOfHom @[simp] diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index 8e12c26ea959be..1faeeab5012304 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -107,17 +107,17 @@ variable {M} [Semigroup M] (a : Stream' M) (m : M) (h : FP a.tail m) set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.head'`. -/ -@[to_additive (attr := match_pattern, nolint defLemma) +@[to_additive (attr := match_pattern) /-- Constructor for `FS`. This is the preferred spelling over `FS.head'`. -/] abbrev FP.head : a.head ∈ FP a := FP.head' a set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.tail'`. -/ -@[to_additive (attr := match_pattern, nolint defLemma) +@[to_additive (attr := match_pattern) /-- Constructor for `FS`. This is the preferred spelling over `FS.tail'`. -/] abbrev FP.tail : m ∈ FP a := FP.tail' a m h set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.cons'`. -/ -@[to_additive (attr := match_pattern, nolint defLemma) +@[to_additive (attr := match_pattern) /-- Constructor for `FS`. This is the preferred spelling over `FS.cons'`. -/] abbrev FP.cons : a.head * m ∈ FP a := FP.cons' a m h diff --git a/Mathlib/Data/Nat/Fib/Zeckendorf.lean b/Mathlib/Data/Nat/Fib/Zeckendorf.lean index baf33830ad15dc..5e417a6752f26e 100644 --- a/Mathlib/Data/Nat/Fib/Zeckendorf.lean +++ b/Mathlib/Data/Nat/Fib/Zeckendorf.lean @@ -37,7 +37,7 @@ fibonacci, zeckendorf, digit open List Nat -- TODO: The `local` attribute makes this not considered as an instance by linters -@[nolint defLemma docBlame] +@[nolint docBlame] local instance : IsTrans ℕ fun a b ↦ b + 2 ≤ a where trans _a _b _c hba hcb := hcb.trans <| le_self_add.trans hba diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index b20343ec1ec3f1..e1f659e30a1de0 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -734,7 +734,7 @@ lemma eq_true_intro {a : Prop} (h : a) : a = True := propext (iff_true_intro h) lemma eq_false_intro {a : Prop} (h : ¬a) : a = False := propext (iff_false_intro h) -- FIXME: `alias` creates `def Iff.eq := propext` instead of `lemma Iff.eq := propext` -@[nolint defLemma] alias Iff.eq := propext +alias Iff.eq := propext lemma iff_eq_eq {a b : Prop} : (a ↔ b) = (a = b) := propext ⟨propext, Eq.to_iff⟩ diff --git a/Mathlib/Topology/Algebra/WithZeroTopology.lean b/Mathlib/Topology/Algebra/WithZeroTopology.lean index 1fdd828d8d99c0..760e23fee1833b 100644 --- a/Mathlib/Topology/Algebra/WithZeroTopology.lean +++ b/Mathlib/Topology/Algebra/WithZeroTopology.lean @@ -140,7 +140,6 @@ theorem isOpen_Iio {a : Γ₀} : IsOpen (Iio a) := /-- The topology on a linearly ordered group with zero element adjoined is compatible with the order structure: the set `{p : Γ₀ × Γ₀ | p.1 ≤ p.2}` is closed. -/ -@[nolint defLemma] scoped instance (priority := 100) orderClosedTopology : OrderClosedTopology Γ₀ where isClosed_le' := by simp only [← isOpen_compl_iff, compl_setOf, not_le, isOpen_iff_mem_nhds] @@ -149,7 +148,6 @@ scoped instance (priority := 100) orderClosedTopology : OrderClosedTopology Γ exact Iio_mem_nhds hab /-- The topology on a linearly ordered group with zero element adjoined is T₅. -/ -@[nolint defLemma] scoped instance (priority := 100) t5Space : T5Space Γ₀ where completely_normal := fun s t h₁ h₂ => by by_cases hs : 0 ∈ s @@ -159,7 +157,6 @@ scoped instance (priority := 100) t5Space : T5Space Γ₀ where /-- The topology on a linearly ordered group with zero element adjoined makes it a topological monoid. -/ -@[nolint defLemma] scoped instance (priority := 100) : ContinuousMul Γ₀ where continuous_mul := by simp only [continuous_iff_continuousAt, ContinuousAt] @@ -182,7 +179,6 @@ scoped instance (priority := 100) : ContinuousMul Γ₀ where rw [nhds_prod_eq, nhds_of_ne_zero hx, nhds_of_ne_zero hy, prod_pure_pure] exact pure_le_nhds (x * y) -@[nolint defLemma] scoped instance (priority := 100) : ContinuousInv₀ Γ₀ := ⟨fun γ h => by rw [ContinuousAt, nhds_of_ne_zero h] diff --git a/lake-manifest.json b/lake-manifest.json index 1dfeee55bef0ed..4291b508ab7539 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "09c267c2706119a09606e6cde3f6cef5bb2ab72a", + "rev": "77d3cc514f987c1f42f2bbd8a8d56855012dc115", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 8681f8234faba644788c28a4980fecd4a794b6c0 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sun, 28 Jun 2026 14:58:17 +0000 Subject: [PATCH 0410/1300] doc(Algebra/Group/Defs): fix typo in `NSMul`s docstring (#41059) `SMUl` -> `SMul` --- Mathlib/Algebra/Group/Defs.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index fce530fbd241ac..d948baeee2b0ef 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -638,7 +638,7 @@ theorem npowRec_eq_npowBinRec : @npowRecAuto = @npowBinRecAuto := by rfl /-- `NSMul` is an implementation detail of `AddMonoid`. It is needed because it is -impossible to extend `SMUl ℕ M` and `SMul ℤ M` at the same time. -/ +impossible to extend `SMul ℕ M` and `SMul ℤ M` at the same time. -/ class NSMul (M : Type u) where /-- Multiplication by a natural number. Set this to `nsmulRec` unless `Module` diamonds are possible. -/ From 0723fe72056c374fc4b2873821900910dbd766f3 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Sun, 28 Jun 2026 14:58:19 +0000 Subject: [PATCH 0411/1300] chore(FieldTheory/IsGaloisGroup): move `mulEquivAlgEquiv` to ring theory folder (#41071) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The isomorphism `G ≃* Gal(B/A)` does not require Galois theory to be proved so it can be moved to the ring theory folder. I also cleaned up some messed up variables left over from the file split. Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 15 ------------- Mathlib/RingTheory/IsGaloisGroup/Basic.lean | 21 +++++++++++++++---- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index dd462f855e2f75..f560e44b014c81 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -126,21 +126,6 @@ theorem card_eq_finrank' : Nat.card G = Module.finrank A B := by rw [IsGaloisGroup.card_eq_finrank G (FractionRing A) (FractionRing B), Algebra.IsAlgebraic.finrank_of_isFractionRing A (FractionRing A) B (FractionRing B)] -attribute [local instance] FractionRing.liftAlgebra in -/-- If `G` is a finite Galois group for `B/A`, then `G` is isomorphic to `Gal(B/A)`. -/ -@[simps!] noncomputable def mulEquivAlgEquiv : G ≃* Gal(B/A) := - MulEquiv.ofBijective (MulSemiringAction.toAlgAut G A B) (by - have := IsDomain.of_faithfulSMul A B - letI K := FractionRing A - letI L := FractionRing B - letI := IsFractionRing.mulSemiringAction G B L - have := isGalois G K L - have := finiteDimensional G K L - refine .of_comp_left ?_ (IsFractionRing.fieldEquivOfAlgEquivHom_injective A B K L) - rw [Nat.bijective_iff_injective_and_card, card_eq_finrank G K L, - IsGalois.card_aut_eq_finrank K L] - exact ⟨fun _ _ ↦ (faithful K).eq_of_smul_eq_smul ∘ DFunLike.ext_iff.mp, rfl⟩) - @[simp] theorem map_mulEquivAlgEquiv_fixingSubgroup [IsGaloisGroup G K L] (F : IntermediateField K L) : (fixingSubgroup G (F : Set L)).map (mulEquivAlgEquiv G K L) = F.fixingSubgroup := by diff --git a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean index f2df00cd008376..8dd8974d9fb075 100644 --- a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean +++ b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean @@ -126,16 +126,27 @@ instance IsGaloisGroup.toFractionRing [IsDomain A] [IsDomain B] [Finite G] end Field -variable (G G' K L : Type*) [Group G] [Group G'] [Field K] [Field L] [Algebra K L] - [MulSemiringAction G L] [MulSemiringAction G' L] +variable (G : Type*) [Group G] namespace IsGaloisGroup section IsDomain variable (A B : Type*) [CommRing A] [CommRing B] [IsDomain B] [Algebra A B] [FaithfulSMul A B] - [MulSemiringAction G B] [MulSemiringAction G' B] [IsGaloisGroup G A B] [IsGaloisGroup G' A B] - [Finite G] [Finite G'] + [MulSemiringAction G B] [IsGaloisGroup G A B] [Finite G] + +attribute [local instance] FractionRing.liftAlgebra in +/-- If `G` is a finite Galois group for `B/A`, then `G` is isomorphic to `Gal(B/A)`. -/ +@[simps!] noncomputable def mulEquivAlgEquiv : G ≃* Gal(B/A) := + MulEquiv.ofBijective (MulSemiringAction.toAlgAut G A B) (by + have := IsDomain.of_faithfulSMul A B + have : FaithfulSMul G B := IsGaloisGroup.faithful A + refine ⟨fun _ _ ↦ eq_of_smul_eq_smul ∘ DFunLike.ext_iff.mp, fun φ ↦ ?_⟩ + obtain ⟨g, hg⟩ := Ideal.Quotient.stabilizerHom_surjective G ⊥ ⊥ + (Ideal.Quotient.algEquivOfEqMap (⊥ : Ideal A) φ Ideal.map_bot.symm) + use g + rw [AlgEquiv.ext_iff] at hg ⊢ + exact fun x ↦ (AlgEquiv.quotientBot A B).symm.injective (hg x)) end IsDomain @@ -234,6 +245,8 @@ def smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCo end Semiring +variable {K L : Type*} [Field K] [Field L] [Algebra K L] [MulSemiringAction G L] + variable (F : IntermediateField K L) (N : Subgroup G) [N.Normal] [IsGaloisGroup N F L] noncomputable instance : MulSemiringAction (G ⧸ N) F := From c402bebf78ab971d9749ba6fe8186f265d1705c0 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sun, 28 Jun 2026 14:58:21 +0000 Subject: [PATCH 0412/1300] chore: remove redundant `backward.proofsInPublic` exceptions (#41096) These are all (no more exceptions). I guess it is now possible to remove them due to some proofs having been golfed Co-authored-by: Batixx --- Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean b/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean index 1b889bb5c7f259..7f49ecb19f8495 100644 --- a/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean +++ b/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean @@ -82,7 +82,6 @@ lemma Presieve.EffectiveEpimorphic.isSheafFor_of_isRepresentable {X : C} {R : Pr exact hR _ set_option backward.defeqAttrib.useBackward true in -set_option backward.proofsInPublic true in /-- Implementation: This is a construction which will be used in the proof that the sieve generated by a single arrow is effective epimorphic if and only if @@ -197,7 +196,6 @@ lemma Sieve.generateFamily_eq {B : C} {α : Type*} (X : α → C) (π : (a : α) exact ⟨_, g, π a, ⟨a⟩, rfl⟩ set_option backward.defeqAttrib.useBackward true in -set_option backward.proofsInPublic true in /-- Implementation: This is a construction which will be used in the proof that the sieve generated by a family of arrows is effective epimorphic if and only if From 21c622e6836d174a64c0c9b4f76d1fb74825736b Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sun, 28 Jun 2026 14:58:23 +0000 Subject: [PATCH 0413/1300] chore: fix some adaption notes (#41117) By restoring the original proofs when they still work, or removing the workarounds they describe. Co-authored-by: Batixx --- .../Algebra/Homology/SpectralObject/Page.lean | 5 +---- Mathlib/Analysis/Convex/StdSimplex.lean | 8 ++------ .../Limits/Shapes/Multiequalizer.lean | 17 ----------------- Mathlib/Topology/Algebra/PontryaginDual.lean | 4 ---- .../Category/TopCat/GrothendieckTopology.lean | 4 +--- 5 files changed, 4 insertions(+), 34 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/Page.lean b/Mathlib/Algebra/Homology/SpectralObject/Page.lean index 4b7662ad43bb1e..e238bd05a5dfd6 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Page.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Page.lean @@ -236,11 +236,8 @@ noncomputable def πE (hn₁ : n₀ + 1 = n₁ := by lia) (hn₂ : n₁ + 1 = n (X.cyclesIso f₁ f₂ f₃ n₀ n₁ n₂).inv ≫ (X.shortComplex f₁ f₂ f₃ n₀ n₁ n₂).homologyπ -#adaptation_note /-- nightly-2026-03-04 -The `deriving` keyword on a `def` should just apply `noncomputable` to all -instances automatically if the main `def` is already `noncomputable`. -/ set_option backward.isDefEq.respectTransparency false in -deriving noncomputable instance Epi for πE +deriving instance Epi for πE set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] diff --git a/Mathlib/Analysis/Convex/StdSimplex.lean b/Mathlib/Analysis/Convex/StdSimplex.lean index 9836e956e90d08..46b59101d93b89 100644 --- a/Mathlib/Analysis/Convex/StdSimplex.lean +++ b/Mathlib/Analysis/Convex/StdSimplex.lean @@ -87,17 +87,13 @@ theorem ite_eq_mem_stdSimplex (i : ι) : (if i = · then (1 : 𝕜) else 0) ∈ variable [IsOrderedRing 𝕜] set_option linter.overlappingInstances false - -#adaptation_note /-- nightly-2024-03-11 -we need a type annotation on the segment in the following two lemmas. -/ - /-- The edges are contained in the simplex. -/ lemma segment_single_subset_stdSimplex (i j : ι) : - ([Pi.single i 1 -[𝕜] Pi.single j 1] : Set (ι → 𝕜)) ⊆ stdSimplex 𝕜 ι := + [Pi.single i 1 -[𝕜] Pi.single j 1] ⊆ stdSimplex 𝕜 ι := (convex_stdSimplex 𝕜 ι).segment_subset (single_mem_stdSimplex _ _) (single_mem_stdSimplex _ _) lemma stdSimplex_fin_two : - stdSimplex 𝕜 (Fin 2) = ([Pi.single 0 1 -[𝕜] Pi.single 1 1] : Set (Fin 2 → 𝕜)) := by + stdSimplex 𝕜 (Fin 2) = [Pi.single 0 1 -[𝕜] Pi.single 1 1] := by refine Subset.antisymm ?_ (segment_single_subset_stdSimplex 𝕜 (0 : Fin 2) 1) rintro f ⟨hf₀, hf₁⟩ rw [Fin.sum_univ_two] at hf₁ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index aa78bf468b47b3..4ea64dd9d69f3e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -689,28 +689,11 @@ def ofPiFork | WalkingMulticospan.left _ => a.ι ≫ c.proj _ | WalkingMulticospan.right _ => a.ι ≫ I.fstPiMapOfIsLimit c hd ≫ d.proj _ π.naturality := by - #adaptation_note /-- Proof repaired after leanprover/lean4#13363. - The proof used to finish from this point as - ``` rintro (_ | _) (_ | _) (_ | _ | _) · simp · simp · dsimp; rw [a.condition_assoc]; simp · simp - ``` - The replacement proof is a short-term fix, and we request that the authors/maintainers of - this file review the proof, and either approve it by removing this note, revise - the proof or the prerequisites appropriately, or minimize a problem in lean4 that still - needs addressing. -/ - rintro (_ | _) (_ | _) (_ | _ | _) - · simp only [WalkingMulticospan.Hom.id_eq_id, Functor.map_id, - Functor.const_obj_map, Category.comp_id] - exact Category.id_comp _ - · simp - · dsimp; rw [a.condition_assoc]; simp - · simp only [WalkingMulticospan.Hom.id_eq_id, Functor.map_id, - Functor.const_obj_map, Category.comp_id] - exact Category.id_comp _ @[simp] theorem ofPiFork_ι (a : Fork (I.fstPiMapOfIsLimit c hd) (I.sndPiMapOfIsLimit c hd)) (i) : diff --git a/Mathlib/Topology/Algebra/PontryaginDual.lean b/Mathlib/Topology/Algebra/PontryaginDual.lean index 769f32e134617a..2dd281ea6672e0 100644 --- a/Mathlib/Topology/Algebra/PontryaginDual.lean +++ b/Mathlib/Topology/Algebra/PontryaginDual.lean @@ -61,10 +61,6 @@ namespace PontryaginDual open ContinuousMonoidHom -#adaptation_note /-- nightly-2026-03-31 -This `set_option` is necessary because of a compiler bug. --/ -set_option backward.inferInstanceAs.wrap.data false in instance : CommGroup (PontryaginDual A) := inferInstanceAs (CommGroup (A →ₜ* Circle)) deriving instance diff --git a/Mathlib/Topology/Category/TopCat/GrothendieckTopology.lean b/Mathlib/Topology/Category/TopCat/GrothendieckTopology.lean index 4de1c96a203ce1..cf9d1ffe5faa15 100644 --- a/Mathlib/Topology/Category/TopCat/GrothendieckTopology.lean +++ b/Mathlib/Topology/Category/TopCat/GrothendieckTopology.lean @@ -66,9 +66,7 @@ def precoverage : Precoverage TopCat.{u} := Types.jointlySurjectivePrecoverage.comap (forget TopCat) ⊓ isOpenEmbedding.precoverage deriving Precoverage.HasIsos, Precoverage.IsStableUnderComposition -#adaptation_note /-- nightly-2026-03-04: Strange we need `noncomputable` for a `Prop` instance. -Will be fixed by https://github.com/leanprover/lean4/pull/12789 -/ -deriving noncomputable instance Precoverage.IsStableUnderBaseChange for precoverage +deriving instance Precoverage.IsStableUnderBaseChange for precoverage /-- The Grothendieck topology on the category of topological spaces is the topology given by jointly surjective open embeddings. -/ From 9e03f6c352bcc289b28edeba64b80fb591d5cf63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Sun, 28 Jun 2026 15:48:49 +0000 Subject: [PATCH 0414/1300] =?UTF-8?q?feat(Algebra/Homology):=20the=20right?= =?UTF-8?q?=20derived=20functor=20`RF=20:=20D^+(C)=20=E2=A5=A4=20D^+(D)`?= =?UTF-8?q?=20(#40863)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If `F : C ⥤ D` is an additive functor between abelian categories, where `C` has enough injectives, we define the right derived functor `F.rightDerivedFunctorPlus : DerivedCategory.Plus C ⥤ DerivedCategory.Plus D` between the corresponding bounded below derived categories. This definition follows from the fact that any functor from the homotopy category `K^+(C)` admits a right derived functor. In order to show this, we use the model category structure on bounded below cochain complexes in `C` #38850 and construct derivability structures on the category of bounded below cochain complexes and its homotopy category. --- Mathlib.lean | 1 + .../DerivabilityStructureInjectives.lean | 11 ++- .../RightDerivedFunctorPlus.lean | 70 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean diff --git a/Mathlib.lean b/Mathlib.lean index e16fd6872a03c4..a8fa4a3ffd3f6d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -591,6 +591,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.KInjective public import Mathlib.Algebra.Homology.DerivedCategory.KProjective public import Mathlib.Algebra.Homology.DerivedCategory.Linear public import Mathlib.Algebra.Homology.DerivedCategory.Plus +public import Mathlib.Algebra.Homology.DerivedCategory.RightDerivedFunctorPlus public import Mathlib.Algebra.Homology.DerivedCategory.ShortExact public import Mathlib.Algebra.Homology.DerivedCategory.SingleTriangle public import Mathlib.Algebra.Homology.DerivedCategory.SmallShiftedHom diff --git a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean index d5764ce6531e99..2699d12c106b74 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean @@ -373,7 +373,7 @@ variable [HasDerivedCategory C] (F' : DerivedCategory.Plus C ⥤ H) (α : F ⟶ DerivedCategory.Plus.Qh ⋙ F') [F'.IsRightDerivedFunctor α (HomotopyCategory.Plus.quasiIso C)] -instance (K : HomotopyCategory.Plus C) [(∀ (n : ℤ), Injective (K.obj.as.X n))] : +instance (K : HomotopyCategory.Plus C) [∀ (n : ℤ), Injective (K.obj.as.X n)] : IsIso (α.app K) := by have (Y : HomotopyCategory.Plus (InjectiveObject C)) : IsIso (α.app ((InjectiveObject.ι C).mapHomotopyCategoryPlus.obj Y)) := @@ -389,6 +389,15 @@ instance (K : HomotopyCategory.Plus C) [(∀ (n : ℤ), Injective (K.obj.as.X n) rw [← NatTrans.isIso_app_iff_of_iso α e] infer_instance +instance (K : CochainComplex.Plus C) (n : ℤ) [Injective (K.obj.X n)] : + Injective (((HomotopyCategory.Plus.quotient C).obj K).obj.as.X n) := by + assumption + +instance (K : CochainComplex.Plus (InjectiveObject C)) (n : ℤ) : + Injective (((HomotopyCategory.Plus.quotient C).obj + ((InjectiveObject.ι C).mapCochainComplexPlus.obj K)).obj.as.X n) := + (K.obj.X n).property + example (X : HomotopyCategory.Plus (InjectiveObject C)) : IsIso ((F.totalRightDerivedUnit DerivedCategory.Plus.Qh (HomotopyCategory.Plus.quasiIso C)).app diff --git a/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean b/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean new file mode 100644 index 00000000000000..1fbd95aa538737 --- /dev/null +++ b/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean @@ -0,0 +1,70 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.DerivabilityStructureInjectives + +/-! +# The right derived functor on the bounded below derived category + +If `F : C ⥤ D` is an additive functor between abelian categories, +where `C` has enough injectives, we define the right derived functor +`F.rightDerivedFunctorPlus : DerivedCategory.Plus C ⥤ DerivedCategory.Plus D` +between the corresponding bounded below derived categories. + +TODO(@joelriou): show that this functor is triangulated and refactor +the definiton of `Functor.rightDerived` + +-/ + +@[expose] public section + +namespace CategoryTheory + +namespace Functor + +variable {C D : Type*} [Category* C] [Category* D] [Abelian C] [Abelian D] + [HasDerivedCategory C] [HasDerivedCategory D] + (F : C ⥤ D) [F.Additive] [EnoughInjectives C] + +/-- The right derived functor `DerivedCategory.Plus C ⥤ DerivedCategory.Plus D` +when `F : C ⥤ D` is an additive functor between abelian categories and +`C` has enough injectives. -/ +noncomputable def rightDerivedFunctorPlus : + DerivedCategory.Plus C ⥤ DerivedCategory.Plus D := + (F.mapHomotopyCategoryPlus ⋙ DerivedCategory.Plus.Qh).totalRightDerived DerivedCategory.Plus.Qh + (HomotopyCategory.Plus.quasiIso C) + +/-- The natural transformation that is part of the data of +the right derived functor `DerivedCategory.Plus C ⥤ DerivedCategory.Plus D` +when `F : C ⥤ D` is an additive functor between abelian categories and +`C` has enough injectives. -/ +noncomputable def rightDerivedFunctorPlusUnit : + F.mapHomotopyCategoryPlus ⋙ DerivedCategory.Plus.Qh ⟶ + DerivedCategory.Plus.Qh ⋙ F.rightDerivedFunctorPlus := + (F.mapHomotopyCategoryPlus ⋙ DerivedCategory.Plus.Qh).totalRightDerivedUnit + DerivedCategory.Plus.Qh (HomotopyCategory.Plus.quasiIso C) + +instance : + F.rightDerivedFunctorPlus.IsRightDerivedFunctor + F.rightDerivedFunctorPlusUnit (HomotopyCategory.Plus.quasiIso C) := by + dsimp only [rightDerivedFunctorPlus, rightDerivedFunctorPlusUnit] + infer_instance + +example (X : HomotopyCategory.Plus (InjectiveObject C)) : + IsIso (F.rightDerivedFunctorPlusUnit.app + ((InjectiveObject.ι C).mapHomotopyCategoryPlus.obj X)) := by + infer_instance + +example (K : CochainComplex.Plus (InjectiveObject C)) : + IsIso (F.rightDerivedFunctorPlusUnit.app + ((HomotopyCategory.Plus.quotient C).obj + ((InjectiveObject.ι C).mapCochainComplexPlus.obj K))) := by + infer_instance + +end Functor + +end CategoryTheory From a730529ad47aa327c8315453cfe41815ca7d429c Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sun, 28 Jun 2026 17:46:34 +0000 Subject: [PATCH 0415/1300] chore: remove unused `linter.unusedVariables` exception (#41003) Seems like at some point the option was changed to allowed name instances, so this works now. (This is the only instance of the option in mathlib where we can remove it.) Co-authored-by: Batixx --- Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index c2a381225da3d1..0c4e4d90f647ed 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -224,9 +224,7 @@ theorem integralPowerBasisOfPrimePow_gen [hcycl : IsCyclotomicExtension {p ^ k} simp only [adjoinEquivRingOfIntegersOfPrimePow_apply, IsIntegralClosure.algebraMap_lift] rfl -set_option linter.unusedVariables false in -/- We name `hcycl` so it can be used as a named argument, but this is unused in the declaration -otherwise, so we need to disable the linter. -/ +/- We name `hcycl` so it can be used as a named argument. -/ @[simp] theorem integralPowerBasisOfPrimePow_dim [hcycl : IsCyclotomicExtension {p ^ k} ℚ K] (hζ : IsPrimitiveRoot ζ (p ^ k)) : hζ.integralPowerBasisOfPrimePow.dim = φ (p ^ k) := by From aaedc74a09fbe1da58b11cf4d27806a6fa1a86eb Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Sun, 28 Jun 2026 18:04:23 +0000 Subject: [PATCH 0416/1300] chore(RepresentationTheory): remove some set_option backwards (#41057) Removes several `set_option backward.defeqAttrib.useBackward true` / `set_option backward.isDefEq.respectTransparency false` workarounds in `Mathlib/RepresentationTheory`, replacing them with the `@[implicit_reducible]` attribute on the relevant functor definitions and simplifying a few proofs accordingly. --- Mathlib/RepresentationTheory/Coinduced.lean | 8 ++------ Mathlib/RepresentationTheory/Coinvariants.lean | 7 +------ Mathlib/RepresentationTheory/FiniteIndex.lean | 17 +++++------------ Mathlib/RepresentationTheory/Induced.lean | 4 +--- Mathlib/RepresentationTheory/Invariants.lean | 3 +-- Mathlib/RepresentationTheory/Rep/Basic.lean | 2 +- 6 files changed, 11 insertions(+), 30 deletions(-) diff --git a/Mathlib/RepresentationTheory/Coinduced.lean b/Mathlib/RepresentationTheory/Coinduced.lean index e23be2bcc66fa5..51fb493a80f113 100644 --- a/Mathlib/RepresentationTheory/Coinduced.lean +++ b/Mathlib/RepresentationTheory/Coinduced.lean @@ -128,13 +128,11 @@ noncomputable abbrev coindMap {A B : Rep k G} (f : A ⟶ B) : coind φ A ⟶ coi variable (k) in /-- Given a monoid homomorphism `φ : G →* H`, this is the functor sending a `G`-representation `A` to the coinduced `H`-representation `coind φ A`, with action on maps given by postcomposition. -/ -@[simps obj map] +@[implicit_reducible, simps obj map] noncomputable def coindFunctor : Rep.{t} k G ⥤ Rep k H where obj A := coind φ A map f := coindMap φ f -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance {G : Type v'} [Group G] (S : Subgroup G) : (coindFunctor k S.subtype).PreservesEpimorphisms where preserves {X Y} f := (epi_iff_surjective _).2 fun y => by @@ -199,7 +197,7 @@ noncomputable def coindMap' {A B : Rep k G} (f : A ⟶ B) : coind' φ A ⟶ coin variable (k) in /-- Given a monoid homomorphism `φ : G →* H`, this is the functor sending a `G`-representation `A` to the coinduced `H`-representation `coind' φ A`, with action on maps given by postcomposition. -/ -@[simps obj map] +@[implicit_reducible, simps obj map] noncomputable def coindFunctor' : Rep k G ⥤ Rep k H where obj A := coind' φ A map f := coindMap' φ f @@ -228,8 +226,6 @@ noncomputable def coindVEquiv : noncomputable def coindIso : coind φ A ≅ coind' φ A := Rep.mkIso <| .mk (coindVEquiv φ A) fun h => by ext; simp [homEquiv] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given a monoid homomorphism `φ : G →* H`, the coinduction functors `Rep k G ⥤ Rep k H` given by `coindFunctor k φ` and `coindFunctor' k φ` are naturally isomorphic, with isomorphism on objects given by `coindIso φ`. -/ diff --git a/Mathlib/RepresentationTheory/Coinvariants.lean b/Mathlib/RepresentationTheory/Coinvariants.lean index 93c225bec61f57..7182029e0d4dc9 100644 --- a/Mathlib/RepresentationTheory/Coinvariants.lean +++ b/Mathlib/RepresentationTheory/Coinvariants.lean @@ -343,7 +343,7 @@ end variable (k G) [Monoid G] (A B : Rep.{w} k G) /-- The functor sending a representation to its coinvariants. -/ -@[simps! obj_carrier map_hom] +@[implicit_reducible, simps! obj_carrier map_hom] noncomputable def coinvariantsFunctor : Rep.{w} k G ⥤ ModuleCat k where obj A := ModuleCat.of k A.ρ.Coinvariants map f := ModuleCat.ofHom (Representation.Coinvariants.map _ _ f.hom) @@ -378,7 +378,6 @@ instance : (coinvariantsFunctor k G).Additive where instance : (coinvariantsFunctor k G).Linear k where set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The adjunction between the functor sending a representation to its coinvariants and the functor equipping a module with the trivial representation. -/ @[simps] @@ -394,7 +393,6 @@ theorem coinvariantsAdjunction_homEquiv_apply_hom {X : Rep.{w} k G} {Y : ModuleC rfl set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] theorem coinvariantsAdjunction_homEquiv_symm_apply_hom {X : Rep.{w} k G} {Y : ModuleCat k} (f : X ⟶ (trivialFunctor k G).obj Y) : @@ -437,7 +435,6 @@ section variable (k : Type u) {G : Type v} [CommRing k] [Group G] -set_option backward.isDefEq.respectTransparency false in /-- Given a normal subgroup `S ≤ G`, this is the functor sending a `G`-representation `A` to the `G ⧸ S`-representation it induces on `A_S`. -/ @[simps! obj_V map_hom_toLinearMap] @@ -466,7 +463,6 @@ noncomputable def coinvariantsTensorFreeToFinsupp : variable {α} -set_option backward.isDefEq.respectTransparency false in @[simp] lemma coinvariantsTensorFreeToFinsupp_mk_tmul_single (x : A) (i : α) (g : G) (r : k) : DFunLike.coe (F := (A.ρ.tprod (Representation.free k G α)).Coinvariants →ₗ[k] α →₀ A.V) @@ -487,7 +483,6 @@ noncomputable def finsuppToCoinvariantsTensorFree : variable {A α} set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] lemma finsuppToCoinvariantsTensorFree_single (i : α) (x : A) : DFunLike.coe (F := (α →₀ A.V) →ₗ[k] (A.ρ.tprod (Representation.free k G α)).Coinvariants) diff --git a/Mathlib/RepresentationTheory/FiniteIndex.lean b/Mathlib/RepresentationTheory/FiniteIndex.lean index 8e0ccd7172bf78..49c52f3cd7e9cd 100644 --- a/Mathlib/RepresentationTheory/FiniteIndex.lean +++ b/Mathlib/RepresentationTheory/FiniteIndex.lean @@ -177,10 +177,9 @@ noncomputable def indCoindIso (A : Rep.{max w u} k S) : variable (k S) -set_option backward.defeqAttrib.useBackward true in /-- Given a finite index subgroup `S ≤ G`, this is a natural isomorphism between the `Ind_S^G` and `Coind_G^S` functors `Rep k S ⥤ Rep k G`. -/ -@[simps! hom_app inv_app] +@[implicit_reducible, simps! hom_app inv_app] noncomputable def indCoindNatIso : indFunctor k S.subtype ≅ coindFunctor.{max w u} k S.subtype := NatIso.ofComponents (fun (A : Rep k S) => indCoindIso A) fun f => by @@ -194,7 +193,6 @@ noncomputable def resIndAdjunction : resFunctor.{max w u v} S.subtype ⊣ indFunctor.{max w u v} k S.subtype := (resCoindAdjunction.{max w u v} k S.subtype).ofNatIsoRight (indCoindNatIso.{max w u v} k S).symm - omit [DecidableRel (QuotientGroup.rightRel S)] in @[instance] -- Note: we must use `@[instance] theorem` here due to [lean4#5595](https://github.com/leanprover/lean4/issues/5595). theorem instIsRightAdjointSubtypeMemSubgroupIndFunctorSubtype : @@ -215,8 +213,6 @@ lemma resIndAdjunction_unit_app (B : Rep.{max w u v} k G) : (resCoindAdjunction.{max w u} k S.subtype).unit.app B ≫ (indCoindIso.{max w (max u v)} (res S.subtype B)).inv := rfl -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma resIndAdjunction_homEquiv_apply (A : Rep.{max w u v} k S) {B : Rep.{max w u v} k G} (f : res S.subtype B ⟶ A) : (resIndAdjunction.{w, u, v} k S).homEquiv _ _ f = @@ -228,7 +224,7 @@ lemma resIndAdjunction_homEquiv_symm_apply (A : Rep.{max w u v} k S) {B : Rep.{max w u v} k G} (f : B ⟶ (indFunctor k S.subtype).obj A) : ((resIndAdjunction k S).homEquiv _ _).symm f = - (resCoindHomEquiv.{max w u v} S.subtype B A).symm (f ≫ (indCoindIso.{max w u v} A).hom) := by + (resCoindHomEquiv.{max w u v} S.subtype B A).symm (f ≫ (indCoindIso.{max w u v} A).hom) := rfl variable (k S) in @@ -248,7 +244,7 @@ theorem instIsLeftAdjointSubtypeMemSubgroupCoindFunctorSubtype : lemma coindResAdjunction_counit_app (B : Rep.{max w u v} k G) : (coindResAdjunction.{w, u, v} k S).counit.app B = (indCoindIso.{max w u v} (res S.subtype B)).inv ≫ - (indResAdjunction k S.subtype).counit.app B := by + (indResAdjunction k S.subtype).counit.app B := rfl set_option backward.isDefEq.respectTransparency false in @@ -257,8 +253,7 @@ lemma coindResAdjunction_unit_app (A : Rep.{max w u v} k S) : (coindResAdjunction k S).unit.app A = (indResAdjunction k S.subtype).unit.app A ≫ (resFunctor S.subtype).map (indCoindIso.{max w u v} A).hom := by ext - simp [coindResAdjunction, Adjunction.ofNatIsoLeft, - indResAdjunction, indCoindIso] + simp [coindResAdjunction] lemma coindResAdjunction_homEquiv_apply (A : Rep.{max w u v} k S) {B : Rep k G} (f : coind S.subtype A ⟶ B) : @@ -270,9 +265,7 @@ lemma coindResAdjunction_homEquiv_symm_apply (A : Rep.{max w u v} k S) {B : Rep k G} (f : A ⟶ res S.subtype B) : ((coindResAdjunction.{max w u v} k S).homEquiv _ _).symm f = (indCoindIso.{max w u v} A).inv ≫ (indResHomEquiv S.subtype A B).symm f := by - simp only [coindResAdjunction, indResAdjunction, + simp [coindResAdjunction, indResHomEquiv, indResAdjunction, Adjunction.homEquiv_ofNatIsoLeft_symm_apply _] - simp - rfl end Rep diff --git a/Mathlib/RepresentationTheory/Induced.lean b/Mathlib/RepresentationTheory/Induced.lean index 9033419a235a77..2645fae382cf50 100644 --- a/Mathlib/RepresentationTheory/Induced.lean +++ b/Mathlib/RepresentationTheory/Induced.lean @@ -110,7 +110,7 @@ noncomputable def indMap {A B : Rep k G} (f : A ⟶ B) : ind φ A ⟶ ind φ B : variable (k) in /-- Given a group homomorphism `φ : G →* H`, this is the functor sending a `G`-representation `A` to the induced `H`-representation `ind φ A`, with action on maps induced by left tensoring. -/ -@[simps obj map] +@[implicit_reducible, simps obj map] noncomputable def indFunctor : Rep.{w} k G ⥤ Rep k H where obj A := ind φ A map f := indMap φ f @@ -152,8 +152,6 @@ noncomputable def indResHomEquiv (A : Rep.{max w v' u} k G) (B : Rep.{max w v' u simpa using (hom_comm_apply f h⁻¹ (IndV.mk φ A.ρ 1 a)).symm right_inv _ := by ext; simp -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in variable (k) in /-- Given a group homomorphism `φ : G →* H`, the induction functor `Rep k G ⥤ Rep k H` is left adjoint to the restriction functor along `φ`. -/ diff --git a/Mathlib/RepresentationTheory/Invariants.lean b/Mathlib/RepresentationTheory/Invariants.lean index f6394781abb975..33aa95d7e1c96f 100644 --- a/Mathlib/RepresentationTheory/Invariants.lean +++ b/Mathlib/RepresentationTheory/Invariants.lean @@ -246,7 +246,7 @@ abbrev quotientToInvariants : Rep k (G ⧸ S) := Rep.of (A.ρ.quotientToInvarian variable (k G) /-- The functor sending a representation to its submodule of invariants. -/ -@[simps! obj_carrier map_hom] +@[implicit_reducible, simps! obj_carrier map_hom] noncomputable def invariantsFunctor : Rep.{w} k G ⥤ ModuleCat k where obj A := ModuleCat.of k A.ρ.invariants map {A B} f := ModuleCat.ofHom <| (f.hom ∘ₗ A.ρ.invariants.subtype).codRestrict @@ -258,7 +258,6 @@ instance : (invariantsFunctor k G).PreservesZeroMorphisms where instance : (invariantsFunctor k G).Additive where instance : (invariantsFunctor k G).Linear k where -set_option backward.isDefEq.respectTransparency false in variable {G} in /-- Given a normal subgroup S ≤ G, this is the functor sending a `G`-representation `A` to the `G ⧸ S`-representation it induces on `A^S`. -/ diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index fdbabd2bf828ba..4733606c6e9568 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -436,7 +436,7 @@ end setup variable (k G) in /-- The functor equipping a module with the trivial representation. -/ -@[simps! obj_V map_hom] +@[implicit_reducible, simps! obj_V map_hom] def trivialFunctor : ModuleCat.{w} k ⥤ Rep.{w} k G where obj V := trivial k G V map f := ofHom ⟨f.hom, fun _ ↦ rfl⟩ From 6cc0969466dc9a1043de33485f78471e3aaa1bd8 Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Mon, 29 Jun 2026 05:09:39 +0000 Subject: [PATCH 0417/1300] doc: add wikidata attributes (#40970) This PR adds a batch of 8 `@[wikidata]` attributes. Claude helped generate the list of crossrefs (by scanning Wikidata + Mathlib). Comments are generated by [crossref-report](https://github.com/jcommelin/mathlib-crossref-report) and Wikilean. See https://wikilean.jackmccarthy.org/review?pr=40970 for reviewer UI. Co-authored-by: wikilean-bot --- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 1 + Mathlib/Analysis/Normed/Operator/Compact/Basic.lean | 2 ++ Mathlib/Data/Tree/Basic.lean | 1 + Mathlib/Geometry/Convex/Cone/Basic.lean | 2 ++ Mathlib/MeasureTheory/Constructions/Polish/Basic.lean | 2 ++ Mathlib/Probability/ConditionalProbability.lean | 2 ++ Mathlib/Probability/Distributions/Exponential.lean | 2 ++ 7 files changed, 12 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index d276095cf3211b..a50a9e11c88999 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -156,6 +156,7 @@ theorem EuclideanSpace.real_norm_sq_eq {n : Type*} [Fintype n] (x : EuclideanSpa ‖x‖ ^ 2 = ∑ i, (x i) ^ 2 := by simp [EuclideanSpace.norm_sq_eq] +@[wikidata Q847073] theorem EuclideanSpace.dist_eq {𝕜 : Type*} [RCLike 𝕜] {n : Type*} [Fintype n] (x y : EuclideanSpace 𝕜 n) : dist x y = √(∑ i, dist (x i) (y i) ^ 2) := PiLp.dist_eq_of_L2 x y diff --git a/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean b/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean index 7a8e40734c48b4..9a8ca0e373bacc 100644 --- a/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean @@ -6,6 +6,7 @@ Authors: Anatole Dedecker module public import Mathlib.Analysis.LocallyConvex.Bounded +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.Algebra.Module.Spaces.ContinuousLinearMap /-! @@ -66,6 +67,7 @@ but we choose a definition which involves fewer existential quantifiers and repl with preimages. We prove the equivalence in `isCompactOperator_iff_exists_mem_nhds_image_subset_compact`. -/ +@[wikidata Q1780743] def IsCompactOperator {M₁ M₂ : Type*} [Zero M₁] [TopologicalSpace M₁] [TopologicalSpace M₂] (f : M₁ → M₂) : Prop := ∃ K, IsCompact K ∧ f ⁻¹' K ∈ (𝓝 0 : Filter M₁) diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 993a21a4c1953e..2a510b039f784b 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -6,6 +6,7 @@ Authors: Mario Carneiro, Wojciech Nawrocki module public import Mathlib.Data.Nat.Notation +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Util.CompileInductive import Batteries.Tactic.Alias diff --git a/Mathlib/Geometry/Convex/Cone/Basic.lean b/Mathlib/Geometry/Convex/Cone/Basic.lean index 835f9e94b4093c..71b6c33e5bdce0 100644 --- a/Mathlib/Geometry/Convex/Cone/Basic.lean +++ b/Mathlib/Geometry/Convex/Cone/Basic.lean @@ -6,6 +6,7 @@ Authors: Yury Kudryashov, Frédéric Dupuis module public import Mathlib.Analysis.Convex.Hull +public import Mathlib.Tactic.CrossRefAttribute /-! # Convex cones @@ -55,6 +56,7 @@ variable [Semiring R] [PartialOrder R] variable (R M) in /-- A convex cone is a subset `s` of an `R`-module such that `a • x + b • y ∈ s` whenever `a, b > 0` and `x, y ∈ s`. -/ +@[wikidata Q2256541] structure ConvexCone [AddCommMonoid M] [SMul R M] where /-- The **carrier set** underlying this cone: the set of points contained in it -/ carrier : Set M diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index ea39c5a407cc7f..c1c595f7b275db 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -6,6 +6,7 @@ Authors: Sébastien Gouëzel, Felix Weilacher module public import Mathlib.MeasureTheory.Constructions.BorelSpace.Metrizable +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.MetricSpace.Perfect public import Mathlib.Topology.Separation.CountableSeparatingOn @@ -76,6 +77,7 @@ the natural topology in a space is non-Polish. To endow a standard Borel space `α` with a compatible Polish topology, use `letI := upgradeStandardBorel α`. One can then use `eq_borel_upgradeStandardBorel α` to rewrite the `MeasurableSpace α` instance to `borel α t`, where `t` is the new topology. -/ +@[wikidata Q25378068] class StandardBorelSpace [MeasurableSpace α] : Prop where /-- There exists a compatible Polish topology. -/ polish : ∃ _ : TopologicalSpace α, BorelSpace α ∧ PolishSpace α diff --git a/Mathlib/Probability/ConditionalProbability.lean b/Mathlib/Probability/ConditionalProbability.lean index ce97e0f5c8dae4..75bba5fe9df894 100644 --- a/Mathlib/Probability/ConditionalProbability.lean +++ b/Mathlib/Probability/ConditionalProbability.lean @@ -6,6 +6,7 @@ Authors: Rishikesh Vaishnav module public import Mathlib.MeasureTheory.Measure.Typeclasses.Probability +public import Mathlib.Tactic.CrossRefAttribute /-! # Conditional Probability @@ -71,6 +72,7 @@ variable (μ) in /-- The conditional probability measure of measure `μ` on set `s` is `μ` restricted to `s` and scaled by the inverse of `μ s` (to make it a probability measure): `(μ s)⁻¹ • μ.restrict s`. -/ +@[wikidata Q327069] def cond (s : Set Ω) : Measure Ω := (μ s)⁻¹ • μ.restrict s diff --git a/Mathlib/Probability/Distributions/Exponential.lean b/Mathlib/Probability/Distributions/Exponential.lean index 5f03844c8318b2..20f6e8d2b2bedc 100644 --- a/Mathlib/Probability/Distributions/Exponential.lean +++ b/Mathlib/Probability/Distributions/Exponential.lean @@ -7,6 +7,7 @@ module public import Mathlib.Probability.CDF public import Mathlib.Probability.Distributions.Gamma +public import Mathlib.Tactic.CrossRefAttribute /-! # Exponential distributions over ℝ @@ -90,6 +91,7 @@ end ExponentialPDF open MeasureTheory /-- Measure defined by the exponential distribution -/ +@[wikidata Q237193] noncomputable def expMeasure (r : ℝ) : Measure ℝ := gammaMeasure 1 r From 41066cdc724cae81659908b18e47b58879c034c7 Mon Sep 17 00:00:00 2001 From: Seewoo Lee <49933279+seewoo5@users.noreply.github.com> Date: Mon, 29 Jun 2026 08:46:34 +0000 Subject: [PATCH 0418/1300] feat(ModularForms): SL2 action and Serre derivative (#36963) --- .../Complex/UpperHalfPlane/Manifold.lean | 14 +++ .../NumberTheory/ModularForms/Derivative.lean | 87 ++++++++++++++++++- 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean index 2585e242b97ebe..44e3e2b3ed77f9 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean @@ -158,6 +158,20 @@ TODO(MR): investigate if using `mvfderiv` can avoid the "pain" above, and be a c section Complex +/-- Derivative of `z ↦ (denom g z) ^ k`: $\frac{d}{dz}[(cz+d)^k] = k \cdot c \cdot (cz+d)^{k-1}$. -/ +lemma hasDerivAt_denom_zpow (g : GL (Fin 2) ℝ) (k : ℤ) (τ : ℍ) : + HasDerivAt (fun z ↦ denom g z ^ k) (k * g 1 0 * denom g τ ^ (k - 1)) τ := by + have hd : HasDerivAt (denom g ·) (g 1 0) τ := by + simpa [denom] using hasDerivAt_id _ |>.const_mul _ |>.add_const (g 1 1 : ℂ) + have := (hasDerivAt_zpow k (denom g τ) (Or.inl (denom_ne_zero g τ))).comp _ hd + simpa only [Function.comp_def, mul_right_comm] using this + +/-- Derivative of `z ↦ (denom g z) ^ k`: +$\frac{d}{dz}[(cz+d)^k] = k \cdot c \cdot (cz+d)^{k-1}$. -/ +lemma deriv_denom_zpow (g : GL (Fin 2) ℝ) (k : ℤ) (τ : ℍ) : + deriv (fun z ↦ denom g z ^ k) τ = k * g 1 0 * denom g τ ^ (k - 1) := + (hasDerivAt_denom_zpow g k τ).deriv + lemma hasStrictDerivAt_smul {g : GL (Fin 2) ℝ} (hg : 0 < g.val.det) (τ : ℍ) : HasStrictDerivAt (fun z ↦ ↑(g • ofComplex z) : ℂ → ℂ) (g.val.det / denom g τ ^ 2) τ := by suffices HasStrictDerivAt (num g / denom g) (g.val.det / denom g τ ^ 2) τ by diff --git a/Mathlib/NumberTheory/ModularForms/Derivative.lean b/Mathlib/NumberTheory/ModularForms/Derivative.lean index e7f4df6c11143a..4fca1821ea6dde 100644 --- a/Mathlib/NumberTheory/ModularForms/Derivative.lean +++ b/Mathlib/NumberTheory/ModularForms/Derivative.lean @@ -6,12 +6,19 @@ Authors: Seewoo Lee module public import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2.MDifferentiable +public import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2.Transform /-! # Derivatives of modular forms This file defines normalized derivative $D = \frac{1}{2\pi i} \frac{d}{dz}$ -and serre dervative $\partial_k := D - \frac{k}{12} E_2$ of modular forms. +and (Ramanujan-)Serre derivative $\partial_k := D - \frac{k}{12} E_2$ of modular forms. + +## Main Definitions and Theorems + +- `normalizedDerivOfComplex`: $D = \frac{1}{2\pi i} \frac{d}{dz}$ +- `serreDerivative`: $\partial_k F := D F - \frac{k}{12} E_2 F$ +- `serreDerivative_slash_equivariant`: Serre derivative is equivariant under the slash action. TODO: - Serre derivative preserves modularity, i.e. $\partial_k (M_k) \subseteq M_{k+2}$. @@ -21,7 +28,7 @@ TODO: open UpperHalfPlane hiding I open Real Complex -open scoped Manifold +open scoped Manifold MatrixGroups ModularForm Topology namespace Derivative @@ -151,8 +158,8 @@ theorem serreDerivative_smul (k : ℂ) (c : ℂ) (F : ℍ → ℂ) (hF : MDiff F ring_nf theorem serreDerivative_mul (k₁ k₂ : ℂ) (F G : ℍ → ℂ) (hF : MDiff F) (hG : MDiff G) : - serreDerivative (k₁ + k₂) (F * G) = (serreDerivative k₁ F) * G + F * (serreDerivative k₂ G) - := by + serreDerivative (k₁ + k₂) (F * G) = + (serreDerivative k₁ F) * G + F * (serreDerivative k₂ G) := by ext z simp [serreDerivative, normalizedDerivOfComplex_mul F G hF hG] ring_nf @@ -169,6 +176,78 @@ theorem serreDerivative_mdifferentiable {F : ℍ → ℂ} (k : ℂ) (hF : MDiff MDiff (fun z ↦ (k * 12⁻¹) * (EisensteinSeries.E2 z * F z))) simp [Pi.mul_apply, mul_assoc, mul_left_comm, mul_comm] +open ModularGroup + +/-- How `D` interacts with the slash action. -/ +lemma normalizedDerivOfComplex_slash {k : ℤ} {F : ℍ → ℂ} (hF : MDiff F) + {g : GL (Fin 2) ℝ} (hg : 0 < g.val.det) : + D (F ∣[k] g) = fun z : ℍ ↦ (g.val.det : ℂ)⁻¹ * (D F ∣[k + 2] g) z - + (k : ℂ) * (2 * π * I)⁻¹ * (g 1 0 / denom g z) * (F ∣[k] g) z := by + have hdet : g.det.val = g.val.det := Matrix.GeneralLinearGroup.val_det_apply g + have hdetℂ : (g.val.det : ℂ) ≠ 0 := Complex.ofReal_ne_zero.mpr hg.ne' + have hσ (x) : σ g x = x := by grind [σ, ContinuousAlgEquiv.refl_apply] + ext z + simp only [normalizedDerivOfComplex, ModularForm.slash_apply] + have hz := denom_ne_zero g z + have h_smul : HasDerivAt (fun w ↦ ↑(g • ofComplex w) : ℂ → ℂ) + ((g.val.det : ℂ) / denom g z ^ 2) ↑z := (hasStrictDerivAt_smul hg z).hasDerivAt + have h_F : HasDerivAt (F ∘ ofComplex) (deriv (F ∘ ofComplex) ↑(g • ofComplex (z : ℂ))) + ↑(g • ofComplex (z : ℂ)) := + (ofComplex_apply z).symm ▸ (mdifferentiableAt_iff.mp (hF (g • z))).hasDerivAt + have h_denom : HasDerivAt (fun w ↦ (denom g w) ^ (-k)) + (-k * (g 1 0 : ℂ) * (denom g z) ^ (-k - 1)) ↑z := by + simpa using hasDerivAt_denom_zpow g (-k) z + have hcomp : ((F ∣[k] g) ∘ ofComplex) =ᶠ[𝓝 ↑z] + fun w ↦ (g.val.det : ℂ) ^ (k - 1) * + ((F ∘ ofComplex) ↑(g • ofComplex w) * (denom g w) ^ (-k)) := by + filter_upwards [isOpen_upperHalfPlaneSet.mem_nhds z.im_pos] with w hw + grind [ofComplex_apply_of_im_pos, ofComplex_apply, ModularForm.slash_apply] + rw [((((h_F.comp (z : ℂ) h_smul).mul h_denom).const_mul _).congr_of_eventuallyEq hcomp).deriv] + simp only [hσ, hdet, abs_of_pos hg, ofComplex_apply, Function.comp_apply] + rw [show k + 2 - 1 = (k - 1) + 2 by ring, show -(k + 2) = -k + -2 by ring, + zpow_add₀ hdetℂ, zpow_add₀ hz, zpow_sub_one₀ hz] + field + +/-- The `SL(2, ℤ)` case of `normalizedDerivOfComplex_slash`, where the determinant factor is `1`. -/ +lemma normalizedDerivOfComplex_SL_slash {k : ℤ} {F : ℍ → ℂ} (hF : MDiff F) {γ : SL(2, ℤ)} : + D (F ∣[k] γ) = (D F ∣[k + 2] γ) - + (fun z : ℍ ↦ (k : ℂ) * (2 * π * I)⁻¹ * (γ 1 0 / denom γ z) * (F ∣[k] γ) z) := by + have hdet : (γ : GL (Fin 2) ℝ).val.det = 1 := by + rw [← Matrix.GeneralLinearGroup.val_det_apply]; simp + ext z + have := congrFun + (normalizedDerivOfComplex_slash (k := k) hF (g := (γ : GL (Fin 2) ℝ)) (by grind)) z + rw [hdet] at this + simpa [ModularForm.SL_slash] using this + +/-- +Serre derivative is equivariant under the slash action. More precisely, +$\partial_k (F ∣[k] γ) = (\partial_k F) ∣[k + 2] \gamma$ for all $\gamma \in SL(2, \mathbb{Z})$. +-/ +theorem serreDerivative_slash_equivariant {k : ℤ} {F : ℍ → ℂ} (hF : MDiff F) {γ : SL(2, ℤ)} : + serreDerivative k F ∣[k + 2] γ = serreDerivative k (F ∣[k] γ) := by + ext z + have hLHS : (serreDerivative (k : ℂ) F ∣[k + 2] γ) z = + (D F ∣[k + 2] γ) z - ↑k * 12⁻¹ * ((EisensteinSeries.E2 ∣[(2 : ℤ)] γ) z * (F ∣[k] γ) z) := by + grind [ModularForm.SL_slash_apply, serreDerivative_apply, Pi.mul_apply, + congrFun (ModularForm.mul_slash_SL2 2 k γ EisensteinSeries.E2 F) z] + have hDz : (D (F ∣[k] γ)) z = (D F ∣[k + 2] γ) z - + (k * (2 * π * I)⁻¹ * (γ 1 0 / denom γ z) * (F ∣[k] γ) z) := by + simp [normalizedDerivOfComplex_SL_slash hF] + have hE2z : (EisensteinSeries.E2 ∣[(2 : ℤ)] γ) z = + EisensteinSeries.E2 z - 1 / (2 * riemannZeta 2) * EisensteinSeries.D2 γ z := by + simp [EisensteinSeries.E2_slash_action] + grind [serreDerivative_apply, EisensteinSeries.D2, riemannZeta_two, I_sq] + +/-- +As a corollary, if `F` is invariant under the slash action of weight `k`, then +`serreDerivative k F` is invariant under the slash action of weight `k + 2`. +-/ +theorem serreDerivative_slash_invariant {k : ℤ} {F : ℍ → ℂ} (hF : MDiff F) {γ : SL(2, ℤ)} + (h : F ∣[k] γ = F) : + serreDerivative k F ∣[k + 2] γ = serreDerivative k F := by + grind [serreDerivative_slash_equivariant] + end end Derivative From e752928d1223d1202d969b623a6f27cc79866e9c Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Mon, 29 Jun 2026 08:56:20 +0000 Subject: [PATCH 0419/1300] feat(RingTheory): UFD criteria via height `1` prime ideals and localization (#36739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We prove the following UFD criteria via height `1` prime ideals and localization: 1. Let `R` be a Noetherian domain. Then `R` is a UFD if and only if every height `1` prime ideal is principal. 2. Let `R` be a Noetherian domain, `x ∈ R` be a prime element. If `Rₓ` is a UFD, then `R` is also a UFD. Co-authored-by: Thmoas-Guan <150537269+Thmoas-Guan@users.noreply.github.com> --- Mathlib.lean | 2 + Mathlib/RingTheory/Ideal/Height.lean | 28 ++++- Mathlib/RingTheory/Ideal/Maximal.lean | 3 + Mathlib/RingTheory/Ideal/UFD.lean | 112 ++++++++++++++++++ .../RingTheory/Localization/Away/Basic.lean | 10 +- .../RingTheory/Localization/Away/Lemmas.lean | 24 ++++ .../UniqueFactorizationDomain/Defs.lean | 8 ++ .../Localization.lean | 50 ++++++++ 8 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 Mathlib/RingTheory/Ideal/UFD.lean create mode 100644 Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean diff --git a/Mathlib.lean b/Mathlib.lean index a8fa4a3ffd3f6d..7d538bd87f4316 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6670,6 +6670,7 @@ public import Mathlib.RingTheory.Ideal.Quotient.Operations public import Mathlib.RingTheory.Ideal.Quotient.Over public import Mathlib.RingTheory.Ideal.Quotient.PowTransition public import Mathlib.RingTheory.Ideal.Span +public import Mathlib.RingTheory.Ideal.UFD public import Mathlib.RingTheory.IdealFilter.Basic public import Mathlib.RingTheory.IdealFilter.Topology public import Mathlib.RingTheory.Idempotents @@ -7054,6 +7055,7 @@ public import Mathlib.RingTheory.UniqueFactorizationDomain.Finsupp public import Mathlib.RingTheory.UniqueFactorizationDomain.GCDMonoid public import Mathlib.RingTheory.UniqueFactorizationDomain.Ideal public import Mathlib.RingTheory.UniqueFactorizationDomain.Kaplansky +public import Mathlib.RingTheory.UniqueFactorizationDomain.Localization public import Mathlib.RingTheory.UniqueFactorizationDomain.Moebius public import Mathlib.RingTheory.UniqueFactorizationDomain.Multiplicative public import Mathlib.RingTheory.UniqueFactorizationDomain.Multiplicity diff --git a/Mathlib/RingTheory/Ideal/Height.lean b/Mathlib/RingTheory/Ideal/Height.lean index 457a89a3fc05a2..6fc30fe2b79b4e 100644 --- a/Mathlib/RingTheory/Ideal/Height.lean +++ b/Mathlib/RingTheory/Ideal/Height.lean @@ -6,7 +6,6 @@ Authors: Wanyi He, Jiedong Jiang, Jingting Wang, Andrew Yang, Shouxin Zhang module public import Mathlib.Algebra.Module.SpanRank -public import Mathlib.RingTheory.Ideal.MinimalPrime.Localization public import Mathlib.RingTheory.Ideal.MinimalPrime.Noetherian public import Mathlib.RingTheory.Spectrum.Prime.Topology @@ -50,6 +49,12 @@ lemma Ideal.height_eq_inf_minimalPrimes : I.height = ⨅ J ∈ I.minimalPrimes, have := hp.isPrime exact (Ideal.height_eq_primeHeight _).symm +lemma Ideal.exists_isPrime_height_eq {I : Ideal R} {n : ℕ} (hI : I.height = n) : + ∃ (p : Ideal R) (_ : p.IsPrime) (_ : I ≤ p), p.height = n := by + simp only [Ideal.height, ENat.iInf_eq_coe_iff] at hI + rcases hI with ⟨⟨p, ⟨⟨⟨hpp, hIp⟩, _⟩, h⟩, -⟩, -⟩ + exact ⟨p, hpp, hIp, h ▸ p.height_eq_primeHeight⟩ + /-- An ideal has finite height if it is either the unit ideal or its height is finite. We include the unit ideal in order to have the instance `IsNoetherianRing R → FiniteHeight I`. -/ @[mk_iff] @@ -247,6 +252,17 @@ lemma Ideal.height_bot [Nontrivial R] : (⊥ : Ideal R).height = 0 := by simp only [ENat.iInf_eq_zero] refine ⟨p, hp, haveI := hp.isPrime; height_eq_zero_iff.mpr hp⟩ +@[simp] +lemma Ideal.height_eq_zero_iff_eq_bot [IsDomain R] {I : Ideal R} : I.height = 0 ↔ I = ⊥ := by + refine ⟨fun hI ↦ ?_, fun hI0 ↦ by simp [hI0]⟩ + rcases exists_isPrime_height_eq hI with ⟨p, _, hIp, hp0⟩ + rw [CharP.cast_eq_zero, height_eq_zero_iff, IsDomain.minimalPrimes_eq_singleton_bot, + Set.mem_singleton_iff] at hp0 + exact bot_unique (hIp.trans_eq hp0) + +theorem Ideal.ne_bot_of_height_eq_one [IsDomain R] {I : Ideal R} (h : I.height = 1) : I ≠ ⊥ := + I.height_eq_zero_iff_eq_bot.not.mp (ne_zero_of_eq_one h) + /-- In a trivial commutative ring, the height of any ideal is `∞`. -/ @[simp, nontriviality] lemma Ideal.height_of_subsingleton [Subsingleton R] : I.height = ⊤ := by @@ -542,3 +558,13 @@ lemma Ring.krullDimLE_of_isLocalization_maximal {n : ℕ} exact h P end isLocalization + +lemma Ideal.eq_span_singleton_of_height_eq_one [IsDomain R] {p : Ideal R} [p.IsPrime] + (h1 : p.height = 1) {x : R} (hx : x ∈ p) (hxp : Prime x) : p = span {x} := by + have : (span {x}).IsPrime := by simp [span_singleton_prime hxp.ne_zero, hxp] + have : p.FiniteHeight := by simp [p.finiteHeight_iff, h1] + by_contra! hne + apply hxp.ne_zero + rw [← span_singleton_eq_bot, ← height_eq_zero_iff_eq_bot, ← Order.lt_one_iff, ← h1] + refine height_strict_mono_of_isPrime_of_isPrime (lt_of_le_of_ne ?_ hne.symm) + simp only [p.span_singleton_le_iff_mem, hx] diff --git a/Mathlib/RingTheory/Ideal/Maximal.lean b/Mathlib/RingTheory/Ideal/Maximal.lean index c6cae02a1be57a..f4cfefe052d189 100644 --- a/Mathlib/RingTheory/Ideal/Maximal.lean +++ b/Mathlib/RingTheory/Ideal/Maximal.lean @@ -148,6 +148,9 @@ variable [CommSemiring α] (I : Ideal α) theorem span_singleton_prime {p : α} (hp : p ≠ 0) : IsPrime (span ({p} : Set α)) ↔ Prime p := by simp [isPrime_iff, Prime, span_singleton_eq_top, hp, mem_span_singleton] +theorem isPrime_span_singleton_of_prime {p : α} (hp : Prime p) : (span {p}).IsPrime := by + simp [Ideal.span_singleton_prime hp.ne_zero, hp] + theorem IsMaximal.isPrime {I : Ideal α} (H : I.IsMaximal) : I.IsPrime := ⟨H.1.1, @fun x y hxy => or_iff_not_imp_left.2 fun hx => by diff --git a/Mathlib/RingTheory/Ideal/UFD.lean b/Mathlib/RingTheory/Ideal/UFD.lean new file mode 100644 index 00000000000000..5581830415eec3 --- /dev/null +++ b/Mathlib/RingTheory/Ideal/UFD.lean @@ -0,0 +1,112 @@ +/- +Copyright (c) 2026 Yongle Hu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yongle Hu +-/ +module + +public import Mathlib.RingTheory.Ideal.KrullsHeightTheorem +public import Mathlib.RingTheory.Localization.Away.Lemmas +public import Mathlib.RingTheory.UniqueFactorizationDomain.Localization + +/-! +# UFD criteria via height `1` prime ideals and localization + +## Main results +* `UniqueFactorizationMonoid.iff_forall_isPrincipal_of_height_eq_one` : Let `R` be a + Noetherian domain. Then `R` is a UFD if and only if every height `1` prime ideal is principal. + +* `UniqueFactorizationMonoid.iff_localizationAway_of_prime` : Let `R` be a Noetherian domain, + `x ∈ R` be a prime element. Then `R` is a UFD if and only if `Rₓ` is a UFD. +-/ + +public section + +variable {R : Type*} [CommRing R] [IsDomain R] + +namespace Ideal + +variable [WfDvdMonoid R] {x : R} (hx : Prime x) {p : Ideal R} [p.IsPrime] (hxp : x ∉ p) + +include hx hxp + +theorem isPrincipal_of_isPrincipal_isLocalizationAway_of_prime + (S : Type*) [CommRing S] [Algebra R S] [IsLocalization.Away x S] + (hp : (map (algebraMap R S) p).IsPrincipal) : p.IsPrincipal := by + have := (disjoint_powers_iff_notMem_of_isPrime x).mpr hxp + by_cases hpbot : p = ⊥ + · simp [hpbot, bot_isPrincipal] + · have hi := IsLocalization.injective S (powers_le_nonZeroDivisors_of_noZeroDivisors hx.ne_zero) + have hpb : map (algebraMap R S) p ≠ ⊥ := by simp [Ideal.map_eq_bot_iff_of_injective hi, hpbot] + obtain ⟨g, hg⟩ := hp + have hg0 : g ≠ 0 := fun hg0 ↦ hpb <| by simp [hg0, hg] + obtain ⟨a, n, hxa, hag⟩ := exists_reduced_fraction' x S hg0 hx.irreducible + have hu : IsUnit (selfZPow x S n) := + IsUnit.of_mul_eq_one (selfZPow x S (- n)) (selfZPow_mul_neg x S n) + refine ⟨a, Ideal.eq_of_map_algebraMap_le S x ?_ (by simp [IsPrime.mul_mem_left_iff hxp]) ?_⟩ + · simp [hg, map_span, ← span_singleton_mul_left_unit hu (algebraMap R S a), hag] + · intro y hy + rw [mem_span_singleton] at hy ⊢ + exact (hx.left_dvd_or_dvd_right_of_dvd_mul hy).resolve_left hxa + +theorem isPrincipal_of_isPrincipal_localizationAway_of_prime + (hp : (map (algebraMap R (Localization.Away x)) p).IsPrincipal) : p.IsPrincipal := + p.isPrincipal_of_isPrincipal_isLocalizationAway_of_prime hx hxp (Localization.Away x) hp + +end Ideal + +namespace UniqueFactorizationMonoid + +theorem isPrincipal_of_height_eq_one [UniqueFactorizationMonoid R] + {p : Ideal R} [p.IsPrime] (hph : p.height = 1) : p.IsPrincipal := by + have hpn : p ≠ ⊥ := p.ne_bot_of_height_eq_one hph + obtain ⟨x, hxmem, hxp⟩ := Ideal.IsPrime.exists_mem_prime_of_ne_bot ‹_› hpn + exact ⟨x, p.eq_span_singleton_of_height_eq_one hph hxmem hxp⟩ + +variable [IsNoetherianRing R] + +theorem of_forall_isPrincipal_of_height_eq_one + (h : ∀ (p : Ideal R) [p.IsPrime], p.height = 1 → p.IsPrincipal) : + UniqueFactorizationMonoid R := by + rw [iff_exists_prime_mem_of_isPrime] + intro I hIn _ + rcases I.ne_bot_iff.mp hIn with ⟨x, hxI, hx0⟩ + rcases Ideal.exists_minimalPrimes_le (I.span_singleton_le_iff_mem.mpr hxI) with ⟨p, hpmin, hpl⟩ + have : p.IsPrime := hpmin.isPrime + have hpn : p ≠ ⊥ := fun hpb ↦ hx0 <| + Ideal.span_singleton_eq_bot.mp <| bot_unique (hpmin.le.trans_eq hpb) + have hpp : p.IsPrincipal := h p <| le_antisymm + (Ideal.height_le_one_of_isPrincipal_of_mem_minimalPrimes _ p hpmin) + (by simpa [Order.one_le_iff_ne_zero]) + exact ⟨hpp.generator p, hpl (hpp.generator_mem p), hpp.prime_generator_of_isPrime p hpn⟩ + +/-- Let `R` be a Noetherian domain. Then `R` is a UFD if and only if every height `1` prime ideal is + principal. -/ +@[stacks 0AFT] +theorem iff_forall_isPrincipal_of_height_eq_one : + UniqueFactorizationMonoid R ↔ ∀ (p : Ideal R) [p.IsPrime], p.height = 1 → p.IsPrincipal := + ⟨fun _ _ _ ↦ isPrincipal_of_height_eq_one, of_forall_isPrincipal_of_height_eq_one⟩ + +theorem iff_of_isLocalizationAway_of_prime {x : R} (hx : Prime x) + (S : Type*) [CommRing S] [Algebra R S] [IsLocalization.Away x S] : + UniqueFactorizationMonoid R ↔ UniqueFactorizationMonoid S := by + have : IsDomain S := IsLocalization.Away.isDomain S hx.ne_zero + refine ⟨fun _ ↦ of_isLocalization (Submonoid.powers x) S, fun _ ↦ ?_⟩ + rw [iff_forall_isPrincipal_of_height_eq_one] + intro p hp h1 + by_cases hxp : x ∈ p + · exact ⟨x, p.eq_span_singleton_of_height_eq_one h1 hxp hx⟩ + · have hd := by rwa [← Ideal.disjoint_powers_iff_notMem_of_isPrime x] at hxp + have := IsLocalization.isPrime_of_isPrime_disjoint (Submonoid.powers x) S p hp hd + refine p.isPrincipal_of_isPrincipal_isLocalizationAway_of_prime hx hxp S + (isPrincipal_of_height_eq_one ?_) + rw [← IsLocalization.height_under (Submonoid.powers x), + IsLocalization.under_map_of_isPrime_disjoint (Submonoid.powers x) S hp hd, h1] + +/-- Let `R` be a Noetherian domain, `x ∈ R` be a prime element. Then `R` is a UFD if and only if + `Rₓ` is a UFD. -/ +theorem iff_localizationAway_of_prime {x : R} (hx : Prime x) : + UniqueFactorizationMonoid R ↔ UniqueFactorizationMonoid (Localization.Away x) := + iff_of_isLocalizationAway_of_prime hx (Localization.Away x) + +end UniqueFactorizationMonoid diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index e6c6f68d598a64..2a0c932cff60c2 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -5,8 +5,8 @@ Authors: Kenny Lau, Mario Carneiro, Johan Commelin, Amelia Livingston, Anne Baan -/ module -public import Mathlib.GroupTheory.MonoidLocalization.Away public import Mathlib.Algebra.Algebra.Pi +public import Mathlib.GroupTheory.MonoidLocalization.Away public import Mathlib.RingTheory.Ideal.Maps public import Mathlib.RingTheory.Localization.Basic public import Mathlib.RingTheory.UniqueFactorizationDomain.Multiplicity @@ -310,6 +310,10 @@ lemma commutes {R : Type*} [CommSemiring R] (S₁ S₂ T : Type*) [CommSemiring ext x simp +theorem isDomain [IsDomain R] {x : R} (hx : x ≠ 0) [IsLocalization.Away x S] : IsDomain S := + IsLocalization.isDomain_of_le_nonZeroDivisors S + (powers_le_nonZeroDivisors_of_noZeroDivisors hx) + end Away end Away @@ -590,6 +594,10 @@ theorem existsUnique_algebraMap_eq_of_span_eq_top (s : Set R) (span_eq : Ideal.s simp_rw [← map_pow, eq, ← map_mul, Finset.sum_mul, mul_assoc, eq2 _ a, mul_left_comm (c _), ← Finset.mul_sum, ← smul_eq_mul (a := c _), eq1, mul_one] +/-- If `x ≠ 0`, then the localization of a domain away from `x` is again a domain. -/ +theorem Away.isDomain [IsDomain R] {x : R} (hx : x ≠ 0) : IsDomain (Localization.Away x) := + IsLocalization.Away.isDomain (Localization.Away x) hx + end Localization end CommSemiring diff --git a/Mathlib/RingTheory/Localization/Away/Lemmas.lean b/Mathlib/RingTheory/Localization/Away/Lemmas.lean index 70a7c32959e6a2..36c6b0d1ac3b95 100644 --- a/Mathlib/RingTheory/Localization/Away/Lemmas.lean +++ b/Mathlib/RingTheory/Localization/Away/Lemmas.lean @@ -68,3 +68,27 @@ lemma quotient_of_isIdempotentElem {e : R} (he : IsIdempotentElem e) : away_of_isIdempotentElem he Ideal.mk_ker Quotient.mk_surjective end IsLocalization.Away + +section saturated + +variable {R : Type*} (S : Type*) [CommSemiring R] [CommSemiring S] + [Algebra R S] (x : R) [IsLocalization.Away x S] {I J : Ideal R} + +lemma Ideal.le_of_map_algebraMap_le (hle : I.map (algebraMap R S) ≤ J.map (algebraMap R S)) + (hxJ : ∀ y : R, x * y ∈ J → y ∈ J) : I ≤ J := by + intro y hy + have hin : algebraMap R S y ∈ I.map (algebraMap R S) := Ideal.mem_map_of_mem (algebraMap R S) hy + grw [hle, IsLocalization.algebraMap_mem_map_algebraMap_iff (Submonoid.powers x)] at hin + obtain ⟨m, ⟨n, hn, rfl⟩, h⟩ := hin + dsimp at h + induction n with + | zero => simpa using h + | succ n ih => + rw [add_comm, pow_add, pow_one, mul_assoc] at h + exact ih <| hxJ _ h + +lemma Ideal.eq_of_map_algebraMap_le (heq : I.map (algebraMap R S) = J.map (algebraMap R S)) + (hxI : ∀ y : R, x * y ∈ I → y ∈ I) (hxJ : ∀ y : R, x * y ∈ J → y ∈ J) : I = J := + le_antisymm (le_of_map_algebraMap_le S x heq.le hxJ) (le_of_map_algebraMap_le S x heq.ge hxI) + +end saturated diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean index 3da613e7b67574..68c3a1a67d99de 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean @@ -174,6 +174,14 @@ end UniqueFactorizationMonoid namespace UniqueFactorizationMonoid variable [CommMonoidWithZero α] + +variable (α) in +theorem of_subsingleton [Subsingleton α] : UniqueFactorizationMonoid α where + mul_left_cancel_of_ne_zero _ a b _ := Subsingleton.elim a b + mul_right_cancel_of_ne_zero _ a b _ := Subsingleton.elim a b + wf := ⟨fun a ↦ Acc.intro a fun b ⟨hb, _⟩ ↦ (hb (Subsingleton.elim b 0)).elim⟩ + irreducible_iff_prime {a} := by simp [Subsingleton.elim a 0] + variable [UniqueFactorizationMonoid α] open Classical in diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean new file mode 100644 index 00000000000000..1c4b0fae487db3 --- /dev/null +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean @@ -0,0 +1,50 @@ +/- +Copyright (c) 2026 Yongle Hu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yongle Hu +-/ +module + +public import Mathlib.RingTheory.Localization.Ideal +public import Mathlib.RingTheory.UniqueFactorizationDomain.Kaplansky + +/-! +# Localization of a UFD + +## Main results +* `UniqueFactorizationMonoid.localization` : The localization of a UFD is still a UFD. +-/ + +public section + +namespace UniqueFactorizationMonoid + +variable {R : Type*} [CommRing R] [UniqueFactorizationMonoid R] [IsDomain R] + +/-- If `S` is the localization of a UFD `R`, then `S` is also a UFD. -/ +theorem of_isLocalization (M : Submonoid R) + (S : Type*) [CommRing S] [Algebra R S] [IsLocalization M S] : UniqueFactorizationMonoid S := by + by_cases h0 : 0 ∈ M + · have : Subsingleton S := IsLocalization.subsingleton h0 + exact of_subsingleton S + have hM : M ≤ nonZeroDivisors R := le_nonZeroDivisors_of_noZeroDivisors h0 + have : IsDomain S := IsLocalization.isDomain_of_le_nonZeroDivisors S hM + rw [UniqueFactorizationMonoid.iff_exists_prime_mem_of_isPrime] + intro p hpb _ + obtain ⟨x, hxp, hpx⟩ := Ideal.IsPrime.exists_mem_prime_of_ne_bot + inferInstance (IsLocalization.bot_lt_under_prime M S hM p hpb).ne' + use algebraMap R S x, hxp + rw [← Ideal.span_singleton_prime] + · rw [← Set.image_singleton, ← Ideal.map_span] + refine IsLocalization.isPrime_of_isPrime_disjoint M S _ + (Ideal.isPrime_span_singleton_of_prime hpx) ?_ + rw [← IsLocalization.map_algebraMap_ne_top_iff_disjoint M S] + intro h + exact Ideal.IsPrime.ne_top' (top_unique (h.symm.trans_le (by simpa [Ideal.map_span] using hxp))) + · simp [map_ne_zero_iff _ (IsLocalization.injective S hM), hpx.ne_zero] + +/-- The localization of a UFD is still a UFD. -/ +instance localization (M : Submonoid R) : UniqueFactorizationMonoid (Localization M) := + of_isLocalization M (Localization M) + +end UniqueFactorizationMonoid From 8fe98ac2574a5edbc45dfce69f098e2189699d1d Mon Sep 17 00:00:00 2001 From: William Coram Date: Mon, 29 Jun 2026 09:26:40 +0000 Subject: [PATCH 0420/1300] feat: define multivariate restricted power series (#32692) We define multivariate restricted power series over a normed ring R, and show the properties that they form a ring when R has the ultrametric property. This work generalises my previous work in #26089 which will need to be refactored. Co-authored-by: WilliamCoram --- Mathlib.lean | 2 + Mathlib/Algebra/Order/Antidiag/Prod.lean | 5 + Mathlib/Algebra/Order/Antidiag/Tendsto.lean | 39 ++++++ .../RingTheory/MvPowerSeries/Restricted.lean | 112 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 Mathlib/Algebra/Order/Antidiag/Tendsto.lean create mode 100644 Mathlib/RingTheory/MvPowerSeries/Restricted.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7d538bd87f4316..bee535a6da7157 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -925,6 +925,7 @@ public import Mathlib.Algebra.Order.Antidiag.FinsuppEquiv public import Mathlib.Algebra.Order.Antidiag.Nat public import Mathlib.Algebra.Order.Antidiag.Pi public import Mathlib.Algebra.Order.Antidiag.Prod +public import Mathlib.Algebra.Order.Antidiag.Tendsto public import Mathlib.Algebra.Order.Archimedean.Basic public import Mathlib.Algebra.Order.Archimedean.Class public import Mathlib.Algebra.Order.Archimedean.Defs @@ -6811,6 +6812,7 @@ public import Mathlib.RingTheory.MvPowerSeries.NoZeroDivisors public import Mathlib.RingTheory.MvPowerSeries.Order public import Mathlib.RingTheory.MvPowerSeries.PiTopology public import Mathlib.RingTheory.MvPowerSeries.Rename +public import Mathlib.RingTheory.MvPowerSeries.Restricted public import Mathlib.RingTheory.MvPowerSeries.Substitution public import Mathlib.RingTheory.MvPowerSeries.Trunc public import Mathlib.RingTheory.Nakayama diff --git a/Mathlib/Algebra/Order/Antidiag/Prod.lean b/Mathlib/Algebra/Order/Antidiag/Prod.lean index 58db0a53be1126..398a5813e4bc4f 100644 --- a/Mathlib/Algebra/Order/Antidiag/Prod.lean +++ b/Mathlib/Algebra/Order/Antidiag/Prod.lean @@ -98,6 +98,11 @@ instance [Monoid A] : Subsingleton (HasMulAntidiagonal A) where congr with n xy rw [ha, hb] +@[to_additive] +lemma nonempty_antidiagonal {M : Type*} [Monoid M] [Finset.HasMulAntidiagonal M] (a : M) : + (Finset.mulAntidiagonal a).Nonempty := + ⟨(1, a), by simp⟩ + -- The goal of this lemma is to allow to rewrite mulAntidiagonal/antidiagonal -- when the decidability instances obfuscate Lean set_option linter.overlappingInstances false in diff --git a/Mathlib/Algebra/Order/Antidiag/Tendsto.lean b/Mathlib/Algebra/Order/Antidiag/Tendsto.lean new file mode 100644 index 00000000000000..34a9de60c58691 --- /dev/null +++ b/Mathlib/Algebra/Order/Antidiag/Tendsto.lean @@ -0,0 +1,39 @@ +/- +Copyright (c) 2026 William Coram. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: William Coram +-/ +module + +public import Mathlib.Algebra.Group.Pointwise.Set.Finite +public import Mathlib.Algebra.Order.Antidiag.Prod +public import Mathlib.Order.Filter.Cofinite + +/-! +# Antidiagonal tendsto + +`tendsto_sup'_antidiagonal_cofinite`: If a function `f : M × M → R` on a Finset `M`, that has the + antidiagonal propertry, tends to to a filter `F` under the cofinite filter then so does the + function assigning to `x : M` its supremum of its antidiagonal. +-/ + +@[expose] public section + +namespace Finset.HasAntidiagonal + +open Filter + +variable {M R : Type*} [AddMonoid M] [HasAntidiagonal M] {f : M × M → R} [LinearOrder R] + {F : Filter R} + +lemma tendsto_sup'_antidiagonal_cofinite (hf : Tendsto f cofinite F) : Tendsto + (fun a ↦ (Finset.antidiagonal a).sup' (nonempty_antidiagonal _) f) cofinite F := by + intro U hU + refine ((((hf hU).image Prod.fst)).add ((hf hU).image Prod.snd)).subset ?_ + simp only [Set.subset_def, Set.mem_compl_iff, Set.mem_preimage] + intro x hx + obtain ⟨i, hi, e⟩ := Finset.exists_mem_eq_sup' (nonempty_antidiagonal x) f + obtain rfl : i.1 + i.2 = x := by simpa using hi + exact Set.add_mem_add (by simpa using ⟨i.2, e ▸ hx⟩) (by simpa using ⟨i.1, e ▸ hx⟩) + +end Finset.HasAntidiagonal diff --git a/Mathlib/RingTheory/MvPowerSeries/Restricted.lean b/Mathlib/RingTheory/MvPowerSeries/Restricted.lean new file mode 100644 index 00000000000000..72d90d9acdcb90 --- /dev/null +++ b/Mathlib/RingTheory/MvPowerSeries/Restricted.lean @@ -0,0 +1,112 @@ +/- +Copyright (c) 2025 William Coram. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: William Coram +-/ +module + +public import Mathlib.Algebra.Order.Antidiag.Tendsto +public import Mathlib.Algebra.Order.GroupWithZero.Finset +public import Mathlib.Analysis.Normed.Field.Basic +public import Mathlib.Analysis.Normed.Group.Ultra +public import Mathlib.RingTheory.MvPowerSeries.Basic + +/-! +# Multivariate restricted power series + +`IsRestricted` : We say a multivariate power series over a normed ring `R` is restricted for a +tuple `c` if `‖coeff t f‖ * ∏ i ∈ t.support, c i ^ t i → 0` under the cofinite filter. + +-/ + +@[expose] public section + +namespace MvPowerSeries + +open Filter +open scoped Topology Pointwise + +variable {R : Type*} [NormedRing R] {σ : Type*} + +/-- A multivariate powe0r series over a normed ring `R` is restricted for a + tuple `c` if `‖coeff t f‖ * ∏ i ∈ t.support, c i ^ t i → 0` under the cofinite filter. -/ +def IsRestricted (c : σ → ℝ) (f : MvPowerSeries σ R) := + Tendsto (fun (t : σ →₀ ℕ) ↦ ‖coeff t f‖ * t.prod (c · ^ ·)) cofinite (𝓝 0) + +@[simp] +lemma isRestricted_abs_iff (c : σ → ℝ) (f : MvPowerSeries σ R) : + IsRestricted |c| f ↔ IsRestricted c f := by + simp [IsRestricted, NormedAddGroup.tendsto_nhds_zero, Finsupp.prod] + +lemma isRestricted_zero (c : σ → ℝ) : IsRestricted c (0 : MvPowerSeries σ R) := by + simpa [IsRestricted] using tendsto_const_nhds + +lemma isRestricted_monomial (c : σ → ℝ) (n : σ →₀ ℕ) (a : R) : + IsRestricted c (monomial n a) := by + classical + refine tendsto_nhds_of_eventually_eq (Set.Subsingleton.finite ?_) + simp [Set.Subsingleton, coeff_monomial] + +lemma isRestricted_one (c : σ → ℝ) : IsRestricted c (1 : MvPowerSeries σ R) := + isRestricted_monomial c 0 1 + +lemma isRestricted_C (c : σ → ℝ) (a : R) : IsRestricted c (C a) := by + simpa [monomial_zero_eq_C_apply] using isRestricted_monomial c 0 a + +lemma isRestricted.add (c : σ → ℝ) {f g : MvPowerSeries σ R} (hf : IsRestricted c f) + (hg : IsRestricted c g) : IsRestricted c (f + g) := by + rw [← isRestricted_abs_iff, IsRestricted] at * + refine tendsto_const_nhds.squeeze (add_zero (0 : ℝ) ▸ hf.add hg) (fun n ↦ ?_) fun n ↦ ?_ + · dsimp [Finsupp.prod]; positivity -- TODO: add positivity extension for Finsupp.prod + rw [← add_mul] + exact mul_le_mul_of_nonneg_right (norm_add_le ..) (by dsimp [Finsupp.prod]; positivity) + +lemma isRestricted.neg (c : σ → ℝ) {f : MvPowerSeries σ R} (hf : IsRestricted c f) : + IsRestricted c (-f) := by + rw [← isRestricted_abs_iff, IsRestricted] at * + simpa [IsRestricted] using hf + +open IsUltrametricDist + +open Finset.HasAntidiagonal in +lemma tendsto_antidiagonal {M S : Type*} [AddMonoid M] [Finset.HasAntidiagonal M] [NormedRing S] + [IsUltrametricDist S] {C : M → ℝ} (hC : ∀ a b, C (a + b) = C a * C b) {f g : M → S} + (hf : Tendsto (fun i ↦ ‖f i‖ * C i) cofinite (𝓝 0)) + (hg : Tendsto (fun i ↦ ‖g i‖ * C i) cofinite (𝓝 0)) : + Tendsto (fun a ↦ ‖∑ p ∈ Finset.antidiagonal a, (f p.1 * g p.2)‖ * C a) cofinite (𝓝 0) := by + wlog hC' : 0 ≤ C generalizing C + · rw [tendsto_zero_iff_norm_tendsto_zero] + simpa using this (C := |C|) (by simp [hC]) (by simpa using hf.norm) + (by simpa using hg.norm) (fun _ => by simp) + refine .squeeze tendsto_const_nhds + (tendsto_sup'_antidiagonal_cofinite (tendsto_mul_cofinite_nhds_zero hf hg)) + (fun x ↦ mul_nonneg (by simp) (hC' x)) fun a ↦ ?_ + have : 0 ≤ C a := hC' a + grw [(nonempty_antidiagonal _).norm_sum_le_sup'_norm, Finset.sup'_mul₀ this] + refine Finset.sup'_mono_fun fun x hx ↦ ?_ + grw [mul_mul_mul_comm, ← hC, Finset.mem_antidiagonal.mp hx, ← norm_mul_le] + +lemma isRestricted.mul [IsUltrametricDist R] (c : σ → ℝ) {f g : MvPowerSeries σ R} + (hf : IsRestricted c f) (hg : IsRestricted c g) : IsRestricted c (f * g) := by + classical + rw [← isRestricted_abs_iff, IsRestricted] at * + exact tendsto_antidiagonal (by simp [Finsupp.prod_add_index', pow_add]) hf hg + +namespace IsRestricted + +/-- Restricted power series as an additive subgroup of `MvPowerSeries σ R`. -/ +protected def addSubgroup (c : σ → ℝ) : AddSubgroup (MvPowerSeries σ R) where + carrier := IsRestricted c + zero_mem' := isRestricted_zero c + add_mem' := isRestricted.add c + neg_mem' := isRestricted.neg c + +variable [IsUltrametricDist R] + +/-- Restricted power series as a subring of `MvPowerSeries σ R`. -/ +protected def subring (c : σ → ℝ) : Subring (MvPowerSeries σ R) where + __ := IsRestricted.addSubgroup c + one_mem' := isRestricted_one c + mul_mem' := isRestricted.mul c + +end MvPowerSeries.IsRestricted From f0215624e0491f1be187815fff95cec6f58ecd84 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 29 Jun 2026 09:26:42 +0000 Subject: [PATCH 0421/1300] feat(AlgebraicGeometry/Modules): `tilde` as an equivalence of categories (#41142) Follow-up to #40052. --- .../ModuleCat/Sheaf/Quasicoherent.lean | 3 +++ Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean index dabdb76cef0767..db68ba2f1ee0af 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean @@ -260,6 +260,9 @@ variable (R) in abbrev isQuasicoherent : ObjectProperty (SheafOfModules.{u} R) := IsQuasicoherent +instance (M : (isQuasicoherent R).FullSubcategory) : M.obj.IsQuasicoherent := + M.property + /-- A sheaf of modules is finitely presented if it is locally the cokernel of a morphism between coproducts of finitely many copies of the sheaf of rings. -/ class IsFinitePresentation (M : SheafOfModules.{u} R) : Prop where diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index a7fa7625846a7f..d32e5611a85a5b 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -451,6 +451,9 @@ def presentationTilde (s : Set M) (hs : Submodule.span R s = ⊤) instance : (tilde M).IsQuasicoherent := (presentationTilde.{u} _ .univ (by simp) _ (Submodule.span_eq _)).isQuasicoherent +instance : ((tilde.functor R).obj M).IsQuasicoherent := + inferInstanceAs <| (tilde M).IsQuasicoherent + set_option backward.isDefEq.respectTransparency false in lemma isIso_fromTildeΓ_of_presentation (M : (Spec R).Modules) (P : M.Presentation) : IsIso M.fromTildeΓ := by @@ -870,6 +873,27 @@ lemma essImage_tilde : (tilde.functor R).essImage = · intro M (h : M.IsQuasicoherent) exact ⟨((modulesSpecToSheaf.obj M).presheaf.obj (.op ⊤)), ⟨asIso <| M.fromTildeΓ⟩⟩ +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- `M ↦ M^~` is an equivalence of categories from `ModuleCat R` to the full subcategory +of quasi-coherent `𝒪_{Spec R}`-modules. -/ +@[simps! functor inverse unitIso counitIso_hom_app_hom] +def tildeEquiv : + ModuleCat R ≌ (SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf).FullSubcategory where + functor := ObjectProperty.lift _ (tilde.functor R) fun _ ↦ by + dsimp [SheafOfModules.isQuasicoherent] + infer_instance + inverse := ObjectProperty.ι _ ⋙ moduleSpecΓFunctor (R := R) + unitIso := tilde.toTildeΓNatIso + counitIso := + haveI (M : (SheafOfModules.isQuasicoherent (Spec R).ringCatSheaf).FullSubcategory) : + IsIso (Scheme.Modules.fromTildeΓ M.obj) := inferInstance + NatIso.ofComponents + (fun M ↦ ObjectProperty.isoMk _ (asIso <| Scheme.Modules.fromTildeΓ M.obj)) + fun f ↦ ObjectProperty.hom_ext _ (tilde.adjunction (R := R).counit.naturality f.hom) + functor_unitIso_comp M := + ObjectProperty.hom_ext _ (tilde.adjunction (R := R).left_triangle_components M) + end IsQuasicoherent end AlgebraicGeometry From 8857f7aae14e734f103a4279a19711e4e74d81db Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:32:32 +0000 Subject: [PATCH 0422/1300] feat: more results on bounded variation functions (#41099) Co-authored-by: sgouezel --- .../EMetricSpace/BoundedVariation.lean | 450 +++++++++++++++--- 1 file changed, 376 insertions(+), 74 deletions(-) diff --git a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean index 6d75d4a004f477..ad2563a2b56bfb 100644 --- a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean +++ b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean @@ -159,6 +159,19 @@ theorem mono (f : α → E) {s t : Set α} (hst : t ⊆ s) : eVariationOn f t rintro ⟨n, ⟨u, hu, ut⟩⟩ exact sum_le hu fun i => hst (ut i) +theorem eq_biSup_inter_Icc {f : α → E} {s : Set α} : eVariationOn f s = + ⨆ p ∈ {p : α × α | p.1 ∈ s ∧ p.2 ∈ s ∧ p.1 ≤ p.2}, eVariationOn f (s ∩ Icc p.1 p.2) := by + apply le_antisymm ?_ (by simp [iSup_le_iff, mono f inter_subset_left]) + rw [eVariationOn] + simp only [iSup_le_iff, Prod.forall, Subtype.forall, and_imp] + intro n u hu hus + calc ∑ x ∈ Finset.range n, edist (f (u (x + 1))) (f (u x)) + _ ≤ eVariationOn f (s ∩ Icc (u 0) (u n)) := + sum_le_of_monotoneOn_Iic (hu.monotoneOn _) (by grind [Monotone]) + _ ≤ ⨆ p ∈ {p : α × α | p.1 ∈ s ∧ p.2 ∈ s ∧ p.1 ≤ p.2}, eVariationOn f (s ∩ Icc p.1 p.2) := by + apply le_biSup (f := fun (p : α × α) ↦ eVariationOn f (s ∩ Icc p.1 p.2)) (i := (u 0, u n)) + grind [Monotone] + theorem _root_.BoundedVariationOn.mono {f : α → E} {s : Set α} (h : BoundedVariationOn f s) {t : Set α} (ht : t ⊆ s) : BoundedVariationOn f t := ne_top_of_le_ne_top h (eVariationOn.mono f ht) @@ -493,7 +506,8 @@ open OrderDual convert! comp_eq_of_antitoneOn f ofDual fun _ _ _ _ => id simp only [Equiv.image_preimage] -lemma _root_.BoundedVariationOn.ofDual {f : α → E} {s : Set α} (hf : BoundedVariationOn f s) : +protected lemma _root_.BoundedVariationOn.ofDual + {f : α → E} {s : Set α} (hf : BoundedVariationOn f s) : BoundedVariationOn (f ∘ ofDual) (ofDual ⁻¹' s) := by simpa [BoundedVariationOn] using hf @@ -501,51 +515,109 @@ lemma _root_.BoundedVariationOn.ofDual {f : α → E} {s : Set α} (hf : Bounded BoundedVariationOn (f ∘ ofDual) (ofDual ⁻¹' s) ↔ BoundedVariationOn f s := ⟨fun h ↦ h.ofDual, fun h ↦ h.ofDual⟩ +protected lemma _root_.LocallyBoundedVariationOn.ofDual {f : α → E} {s : Set α} + (hf : LocallyBoundedVariationOn f s) : + LocallyBoundedVariationOn (f ∘ ofDual) (ofDual ⁻¹' s) := by + intro x y hx hy + rw [← toDual_ofDual x, ← toDual_ofDual y, Icc_toDual, ← preimage_inter] + apply BoundedVariationOn.ofDual (hf (ofDual y) (ofDual x) hy hx) + +@[simp] lemma locallyBoundedVariation_ofDual {f : α → E} {s : Set α} : + LocallyBoundedVariationOn (f ∘ ofDual) (ofDual ⁻¹' s) ↔ LocallyBoundedVariationOn f s := + ⟨fun h ↦ h.ofDual, fun h ↦ h.ofDual⟩ + end Monotone /-! ### Left and right limits of bounded variation functions -/ +/-- The variation of a function on `Iic a` is the sum of the variation on `Iio a` and the +contribution of `a`, i.e., the distance between the left limit and the value at `a`. +We give a version relative to a set `s`. -/ +theorem eVariationOn_on_inter_Iic_eq_Iio_add_edist + [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {a : α} {l : E} + (h : (𝓝[s ∩ Iio a] a).NeBot) (ha : a ∈ s) + (h'f : Tendsto f (𝓝[s ∩ Iio a] a) (𝓝 l)) : + eVariationOn f (s ∩ Iic a) = eVariationOn f (s ∩ Iio a) + edist (f a) l := by + refine le_antisymm ?_ ?_ + · rw [eVariationOn_eq_strictMonoOn] + apply iSup_le + rintro ⟨n, u, u_mono, u_mem⟩ + have : u n ≤ a := (u_mem n (by simp)).2 + rcases this.eq_or_lt with hn | hn; swap + · exact (sum_le_of_monotoneOn_Iic u_mono.monotoneOn (by grind [StrictMonoOn])).trans le_self_add + cases n with + | zero => simp + | succ n => + have : Tendsto (fun y ↦ eVariationOn f (s ∩ Iio a) + edist (f a) (f y)) (𝓝[s ∩ Iio a] a) + (𝓝 (eVariationOn f (s ∩ Iio a) + edist (f a) l)) := + (Tendsto.edist tendsto_const_nhds h'f).const_add _ + apply ge_of_tendsto this + have : s ∩ Ioo (u n) a ∈ 𝓝[s ∩ Iio a] a := + inter_mem_nhdsWithin_inter self_mem_nhdsWithin (Ioo_mem_nhdsLT (by grind [StrictMonoOn])) + filter_upwards [this] with y hy + let v i := if i ≤ n then u i else if i = n + 1 then y else a + have A : ∑ i ∈ Finset.range (n + 1), edist (f (u (i + 1))) (f (u i)) + ≤ ∑ i ∈ Finset.range (n + 2), edist (f (v (i + 1))) (f (v i)) := by + simp only [Finset.sum_range_succ, add_assoc] + gcongr with i h + · grind + · grw [add_comm (edist _ _), ← edist_triangle] + grind + have B : ∑ i ∈ Finset.range (n + 2), edist (f (v (i + 1))) (f (v i)) ≤ + eVariationOn f (s ∩ Iio a) + edist (f a) (f y) := by + rw [Finset.sum_range_succ] + gcongr + · apply sum_le_of_monotoneOn_Iic <;> grind [MonotoneOn, StrictMonoOn] + · grind + exact A.trans B + · obtain ⟨b, hb⟩ : (s ∩ Iio a).Nonempty := by contrapose! h; simp [h] + have : Nonempty ((n : ℕ) × { u // StrictMonoOn u (Iic n) ∧ ∀ i ∈ Iic n, u i ∈ s ∩ Iio a }) := + ⟨0, ⟨fun i ↦ b, by grind [StrictMonoOn]⟩⟩ + rw [eVariationOn_eq_strictMonoOn, ENNReal.iSup_add] + apply iSup_le + rintro ⟨n, u, u_mono, u_mem⟩ + have : Tendsto (fun y ↦ ∑ i ∈ Finset.range n, + edist (f (u (i + 1))) (f (u i)) + edist (f a) (f y)) (𝓝[s ∩ Iio a] a) + (𝓝 (∑ i ∈ Finset.range n, edist (f (u (i + 1))) (f (u i)) + edist (f a) l)) := + (Tendsto.edist tendsto_const_nhds h'f).const_add _ + apply le_of_tendsto this + have : s ∩ Ioo (u n) a ∈ 𝓝[s ∩ Iio a] a := + inter_mem_nhdsWithin_inter self_mem_nhdsWithin (Ioo_mem_nhdsLT (by grind [StrictMonoOn])) + filter_upwards [this, self_mem_nhdsWithin] with y hy h'y + let v i := if i ≤ n then u i else if i = n + 1 then y else a + have A : ∑ i ∈ Finset.range n, edist (f (u (i + 1))) (f (u i)) + edist (f a) (f y) + ≤ ∑ i ∈ Finset.range (n + 2), edist (f (v (i + 1))) (f (v i)) := by + simp only [Finset.sum_range_succ, add_assoc] + gcongr with i h + · grind + · exact le_add_left (by grind) + have B : ∑ i ∈ Finset.range (n + 2), edist (f (v (i + 1))) (f (v i)) ≤ + eVariationOn f (s ∩ Iic a) := + sum_le_of_monotoneOn_Iic (by grind [MonotoneOn, StrictMonoOn]) (by grind) + exact A.trans B + +/-- The variation of a function on `Ici a` is the sum of the variation on `Ioi a` and the +contribution of `a`, i.e., the distance between the right limit and the value at `a`. +We give a version relative to a set `s`. -/ +theorem eVariationOn_on_inter_Ici_eq_Ioi_add_edist + [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {a : α} {l : E} + (h : (𝓝[s ∩ Ioi a] a).NeBot) (ha : a ∈ s) + (h'f : Tendsto f (𝓝[s ∩ Ioi a] a) (𝓝 l)) : + eVariationOn f (s ∩ Ici a) = eVariationOn f (s ∩ Ioi a) + edist (f a) l := by + rw [← comp_ofDual f, ← comp_ofDual f] + exact eVariationOn_on_inter_Iic_eq_Iio_add_edist h ha h'f + /-- If a function is continuous on the left at a point `a`, then its variations on `Iio a` and on `Iic a` coincide. We give a version relative to a set `s`. -/ lemma eVariationOn_inter_Iio_eq_inter_Iic_of_continuousWithinAt [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {a : α} (h : (𝓝[s ∩ Iio a] a).NeBot) (h' : ContinuousWithinAt f (s ∩ Iic a) a) : eVariationOn f (s ∩ Iio a) = eVariationOn f (s ∩ Iic a) := by - apply le_antisymm (eVariationOn.mono _ (by grind)) - rw [eVariationOn_eq_strictMonoOn] - apply iSup_le - rintro ⟨n, u, u_mono, u_mem⟩ - have : u n ≤ a := (u_mem n (by simp)).2 - rcases this.eq_or_lt with hn | hn; swap - · exact sum_le_of_monotoneOn_Iic u_mono.monotoneOn (by grind [StrictMonoOn]) - cases n with - | zero => simp - | succ n => - simp only [Finset.range_add_one, Finset.mem_range, lt_self_iff_false, not_false_eq_true, - Finset.sum_insert, ge_iff_le] - have : Tendsto (fun b ↦ edist (f b) (f (u n)) - + ∑ i ∈ Finset.range n, edist (f (u (i + 1))) (f (u i))) (𝓝[s ∩ Iio a] a) - (𝓝 (edist (f (u (n + 1))) (f (u n)) - + ∑ i ∈ Finset.range n, edist (f (u (i + 1))) (f (u i)))) := by - apply Tendsto.add_const - apply Tendsto.edist _ tendsto_const_nhds - rw [hn] - apply h'.tendsto.mono_left - exact nhdsWithin_mono _ (by grind) - apply le_of_tendsto this - have : s ∩ Ioo (u n) (u (n + 1)) ∈ 𝓝[s ∩ Iio a] a := by - rw [hn] - apply inter_mem_nhdsWithin_inter self_mem_nhdsWithin - exact Ioo_mem_nhdsLT (by grind [StrictMonoOn]) - filter_upwards [this] with b hb - let v i := if i ≤ n then u i else b - calc edist (f b) (f (u n)) + ∑ i ∈ Finset.range n, edist (f (u (i + 1))) (f (u i)) - _ = ∑ i ∈ Finset.range (n + 1), edist (f (v (i + 1))) (f (v i)) := by - simp only [Finset.range_add_one, Finset.mem_range, lt_self_iff_false, not_false_eq_true, - Finset.sum_insert] - congr 1 <;> grind [Finset.sum_congr] - _ ≤ eVariationOn f (s ∩ Iio a) := - sum_le_of_monotoneOn_Iic (by grind [MonotoneOn, StrictMonoOn]) (by grind [StrictMonoOn]) + by_cases ha : a ∈ s + · have : Tendsto f (𝓝[s ∩ Iio a] a) (𝓝 (f a)) := h'.mono (by grind) + simp [eVariationOn_on_inter_Iic_eq_Iio_add_edist h ha this] + · congr 1 + grind /-- If a function is continuous on the right at a point `a`, then its variations on `Ioi a` and on `Ici a` coincide. We give a version relative to a set `s`. -/ @@ -556,6 +628,41 @@ lemma eVariationOn_inter_Ioi_eq_inter_Ici_of_continuousWithinAt rw [← comp_ofDual f, ← comp_ofDual f] exact eVariationOn_inter_Iio_eq_inter_Iic_of_continuousWithinAt h h' +lemma eVariationOn_Ioc_eq_Icc_of_continuousWithinAt' + [TopologicalSpace α] [OrderTopology α] {f : α → E} {a b : α} + [h : (𝓝[>] a).NeBot] (h' : ContinuousWithinAt f (Ici a) a) : + eVariationOn f (Ioc a b) = eVariationOn f (Icc a b) := by + rcases le_or_gt b a with hab | hab + · simp [hab] + have : (𝓝[Iic b ∩ Ioi a] a).NeBot := by + convert h using 1 + exact nhdsWithin_inter_of_mem (mem_nhdsWithin_of_mem_nhds (Iic_mem_nhds hab)) + convert eVariationOn_inter_Ioi_eq_inter_Ici_of_continuousWithinAt this + (h'.mono inter_subset_right) <;> grind + +lemma eVariationOn_Ioc_eq_Icc_of_continuousWithinAt + [TopologicalSpace α] [OrderTopology α] [DenselyOrdered α] {f : α → E} {a b : α} + (h' : ContinuousWithinAt f (Ici a) a) : + eVariationOn f (Ioc a b) = eVariationOn f (Icc a b) := by + rcases le_or_gt b a with hab | hab + · simp [hab] + have : (𝓝[Ioi a] a).NeBot := nhdsGT_neBot_of_exists_gt ⟨b, hab⟩ + exact eVariationOn_Ioc_eq_Icc_of_continuousWithinAt' h' + +lemma eVariationOn_Ico_eq_Icc_of_continuousWithinAt' + [TopologicalSpace α] [OrderTopology α] {f : α → E} {a b : α} + [h : (𝓝[<] a).NeBot] (h' : ContinuousWithinAt f (Iic a) a) : + eVariationOn f (Ico b a) = eVariationOn f (Icc b a) := by + rw [← comp_ofDual f, ← comp_ofDual f, ← Ioc_toDual, ← Icc_toDual] + exact eVariationOn_Ioc_eq_Icc_of_continuousWithinAt' h' + +lemma eVariationOn_Ico_eq_Icc_of_continuousWithinAt + [TopologicalSpace α] [OrderTopology α] [DenselyOrdered α] {f : α → E} {a b : α} + (h' : ContinuousWithinAt f (Iic a) a) : + eVariationOn f (Ico b a) = eVariationOn f (Icc b a) := by + rw [← comp_ofDual f, ← comp_ofDual f, ← Ioc_toDual, ← Icc_toDual] + exact eVariationOn_Ioc_eq_Icc_of_continuousWithinAt h' + lemma exists_lt_eVariationOn_inter_Icc {f : α → E} {ε : ℝ≥0∞} {s : Set α} (h : ε < eVariationOn f s) : ∃ a ∈ s, ∃ b ∈ s, a < b ∧ ε < eVariationOn f (s ∩ Icc a b) := by obtain ⟨n, u, ⟨u_mono, u_mem⟩, hu⟩ : ∃ n u, (Monotone u ∧ ∀ (i : ℕ), u i ∈ s) ∧ @@ -683,6 +790,134 @@ theorem _root_.BoundedVariationOn.tendsto_eVariationOn_Ioc_zero [TopologicalSpac rw [this] exact hf.ofDual.tendsto_eVariationOn_Ico_zero (toDual x) +/-- A bounded variation function has a limit on its left within a set. -/ +theorem _root_.BoundedVariationOn.exists_tendsto_left [CompleteSpace E] [TopologicalSpace α] + [OrderTopology α] {f : α → E} {s : Set α} (hf : BoundedVariationOn f s) (x : α) : + ∃ l, Tendsto f (𝓝[s ∩ Iio x] x) (𝓝 l) := by + rcases eq_empty_or_nonempty (s ∩ Iio x) with hs | hs + · simp only [hs, nhdsWithin_empty, tendsto_bot, exists_const_iff, and_true] + exact ⟨f x⟩ + exact BoundedVariationOn.exists_tendsto_left_of_filter (s := s ∩ Iio x) + (hf.mono inter_subset_left) _ (fun y hy ↦ inter_mem_nhdsWithin _ (Ici_mem_nhds hy.2)) hs + +/-- A bounded variation function has a limit on its right within a set. -/ +theorem _root_.BoundedVariationOn.exists_tendsto_right [CompleteSpace E] [TopologicalSpace α] + [OrderTopology α] {f : α → E} {s : Set α} (hf : BoundedVariationOn f s) (x : α) : + ∃ l, Tendsto f (𝓝[s ∩ Ioi x] x) (𝓝 l) := + hf.ofDual.exists_tendsto_left (toDual x) + +/-- A bounded variation function tends to its left-limit on its left. -/ +theorem _root_.BoundedVariationOn.tendsto_leftLim [CompleteSpace E] [TopologicalSpace α] + [OrderTopology α] {f : α → E} (hf : BoundedVariationOn f univ) (x : α) : + Tendsto f (𝓝[<] x) (𝓝 (f.leftLim x)) := by + apply tendsto_leftLim_of_tendsto + convert! hf.exists_tendsto_left x + simp + +/-- A bounded variation function tends to its right-limit on its right. -/ +theorem _root_.BoundedVariationOn.tendsto_rightLim [CompleteSpace E] [TopologicalSpace α] + [OrderTopology α] {f : α → E} (hf : BoundedVariationOn f univ) (x : α) : + Tendsto f (𝓝[>] x) (𝓝 (f.rightLim x)) := + hf.ofDual.tendsto_leftLim x + +theorem _root_.BoundedVariationOn.eVariationOn_Iic_eq_Iio_add_edist [CompleteSpace E] + [DenselyOrdered α] {f : α → E} {a : α} (hf : BoundedVariationOn f univ) : + eVariationOn f (Iic a) = eVariationOn f (Iio a) + edist (f a) (f.leftLim a) := by + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ + by_cases ha : IsBot a + · have A : Iic a = {a} := by ext x; grind [ha x] + have B : Iio a = ∅ := by simp [ha.isMin] + simp [A, B, leftLim_eq_of_isBot ha] + have : (𝓝[<] a).NeBot := nhdsLT_neBot_of_exists_lt (by simpa [IsBot] using ha) + have : eVariationOn f (univ ∩ Iic a) = eVariationOn f (univ ∩ Iio a) + + edist (f a) (f.leftLim a) := by + apply eVariationOn_on_inter_Iic_eq_Iio_add_edist (by simpa) (mem_univ _) + simpa only [univ_inter] using hf.tendsto_leftLim _ + simpa using this + +theorem _root_.BoundedVariationOn.eVariationOn_Ici_eq_Ioi_add_edist [CompleteSpace E] + [DenselyOrdered α] {f : α → E} {a : α} (hf : BoundedVariationOn f univ) : + eVariationOn f (Ici a) = eVariationOn f (Ioi a) + edist (f a) (f.rightLim a) := by + rw [← eVariationOn.comp_ofDual f, ← eVariationOn.comp_ofDual f] + exact hf.ofDual.eVariationOn_Iic_eq_Iio_add_edist (a := toDual a) + +/-- If a function has bounded variation, then the variation on +small closed intervals to the left of this point tends to the contribution of the point, i.e., +the distance between the left limit and the value at the point -/ +theorem _root_.BoundedVariationOn.tendsto_eVariationOn_Icc_left + [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {l : E} + (hf : BoundedVariationOn f s) {x : α} (h'f : Tendsto f (𝓝[s ∩ Iio x] x) (𝓝 l)) (hx : x ∈ s) : + Tendsto (fun y ↦ eVariationOn f (s ∩ Icc y x)) (𝓝[s ∩ Iio x] x) (𝓝 (edist (f x) l)) := by + rcases eq_or_neBot (𝓝[s ∩ Iio x] x) with h | h + · simp [h] + suffices H : Tendsto (fun y ↦ eVariationOn f (s ∩ Ico y x) + edist (f x) l) + (𝓝[s ∩ Iio x] x) (𝓝 (0 + edist (f x) l)) by + simp only [zero_add] at H + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with y hy + have N : 𝓝[s ∩ Ici y ∩ Iio x] x = 𝓝[s ∩ Iio x] x := by + rw [show s ∩ Ici y ∩ Iio x = s ∩ Iio x ∩ Ici y by grind, nhdsWithin_inter_of_mem'] + exact mem_nhdsWithin_of_mem_nhds (Ici_mem_nhds hy.2) + rw [show s ∩ Icc y x = (s ∩ Ici y) ∩ Iic x by grind, + eVariationOn_on_inter_Iic_eq_Iio_add_edist (l := l)] + · congr 2; grind + · convert h using 1 + · exact ⟨hx, hy.2.le⟩ + · convert h'f + apply Tendsto.add ?_ tendsto_const_nhds + exact (hf.tendsto_eVariationOn_Ico_zero x).mono_left (nhdsWithin_mono _ inter_subset_left) + +/-- If a function has bounded variation, then the variation on +small closed intervals to the right of this point tends to the contribution of the point, i.e., +the distance between the right limit and the value at the point -/ +theorem _root_.BoundedVariationOn.tendsto_eVariationOn_Icc_right + [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {l : E} + (hf : BoundedVariationOn f s) {x : α} (h'f : Tendsto f (𝓝[s ∩ Ioi x] x) (𝓝 l)) (hx : x ∈ s) : + Tendsto (fun y ↦ eVariationOn f (s ∩ Icc x y)) (𝓝[s ∩ Ioi x] x) (𝓝 (edist (f x) l)) := by + have : (fun y ↦ eVariationOn f (s ∩ Icc x y)) = + (fun y ↦ eVariationOn (f ∘ ofDual) (ofDual ⁻¹' s ∩ Icc (toDual y) (toDual x))) := by + ext y + rw [Icc_toDual, ← preimage_inter, comp_ofDual] + rw [this] + exact hf.ofDual.tendsto_eVariationOn_Icc_left h'f hx + +/-- If a function has locally bounded variation, then the variation on +small closed intervals to the left of this point tends to the contribution of the point, i.e., +the distance between the left limit and the value at the point -/ +theorem _root_.LocallyBoundedVariationOn.tendsto_eVariationOn_Icc_left + [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {l : E} + (hf : LocallyBoundedVariationOn f s) {x : α} + (h'f : Tendsto f (𝓝[s ∩ Iio x] x) (𝓝 l)) (hx : x ∈ s) : + Tendsto (fun y ↦ eVariationOn f (s ∩ Icc y x)) (𝓝[s ∩ Iio x] x) (𝓝 (edist (f x) l)) := by + rcases eq_or_neBot (𝓝[s ∩ Iio x] x) with h | h + · simp [h] + obtain ⟨y, hy⟩ : (s ∩ Iio x).Nonempty := by contrapose! h; simp [h] + have : 𝓝[s ∩ Iio x] x = 𝓝[(s ∩ Icc y x) ∩ Iio x] x := by + rw [show (s ∩ Icc y x) ∩ Iio x = (s ∩ Iio x) ∩ Icc y x by grind, eq_comm] + apply nhdsWithin_inter_of_mem' (nhdsWithin_mono _ inter_subset_right (Icc_mem_nhdsLT hy.2)) + rw [this] at h'f ⊢ + have : BoundedVariationOn f (s ∩ Icc y x) := hf _ _ hy.1 hx + apply Tendsto.congr' _ (this.tendsto_eVariationOn_Icc_left h'f ⟨hx, by grind⟩) + filter_upwards [self_mem_nhdsWithin] with z hz + congr 1 + grind + +/-- If a function has locally bounded variation, then the variation on +small closed intervals to the right of this point tends to the contribution of the point, i.e., +the distance between the right limit and the value at the point -/ +theorem _root_.LocallyBoundedVariationOn.tendsto_eVariationOn_Icc_right + [TopologicalSpace α] [OrderTopology α] {f : α → E} {s : Set α} {l : E} + (hf : LocallyBoundedVariationOn f s) {x : α} + (h'f : Tendsto f (𝓝[s ∩ Ioi x] x) (𝓝 l)) (hx : x ∈ s) : + Tendsto (fun y ↦ eVariationOn f (s ∩ Icc x y)) (𝓝[s ∩ Ioi x] x) (𝓝 (edist (f x) l)) := by + have : (fun y ↦ eVariationOn f (s ∩ Icc x y)) = + (fun y ↦ eVariationOn (f ∘ ofDual) (ofDual ⁻¹' s ∩ Icc (toDual y) (toDual x))) := by + ext y + rw [Icc_toDual, ← preimage_inter, comp_ofDual] + rw [this] + exact hf.ofDual.tendsto_eVariationOn_Icc_left h'f hx + /-- If a function has bounded variation and is left-continuous at a point, then the variation on small closed intervals to the left of this point tends to `0`. -/ theorem _root_.BoundedVariationOn.tendsto_eVariationOn_Icc_zero_left @@ -721,36 +956,6 @@ theorem _root_.BoundedVariationOn.tendsto_eVariationOn_Icc_zero_right rw [this] exact hf.ofDual.tendsto_eVariationOn_Icc_zero_left h -/-- A bounded variation function has a limit on its left within a set. -/ -theorem _root_.BoundedVariationOn.exists_tendsto_left [CompleteSpace E] [TopologicalSpace α] - [OrderTopology α] {f : α → E} {s : Set α} (hf : BoundedVariationOn f s) (x : α) : - ∃ l, Tendsto f (𝓝[s ∩ Iio x] x) (𝓝 l) := by - rcases eq_empty_or_nonempty (s ∩ Iio x) with hs | hs - · simp only [hs, nhdsWithin_empty, tendsto_bot, exists_const_iff, and_true] - exact ⟨f x⟩ - exact BoundedVariationOn.exists_tendsto_left_of_filter (s := s ∩ Iio x) - (hf.mono inter_subset_left) _ (fun y hy ↦ inter_mem_nhdsWithin _ (Ici_mem_nhds hy.2)) hs - -/-- A bounded variation function has a limit on its right within a set. -/ -theorem _root_.BoundedVariationOn.exists_tendsto_right [CompleteSpace E] [TopologicalSpace α] - [OrderTopology α] {f : α → E} {s : Set α} (hf : BoundedVariationOn f s) (x : α) : - ∃ l, Tendsto f (𝓝[s ∩ Ioi x] x) (𝓝 l) := - hf.ofDual.exists_tendsto_left (toDual x) - -/-- A bounded variation function tends to its left-limit on its left. -/ -theorem _root_.BoundedVariationOn.tendsto_leftLim [CompleteSpace E] [TopologicalSpace α] - [OrderTopology α] {f : α → E} (hf : BoundedVariationOn f univ) (x : α) : - Tendsto f (𝓝[<] x) (𝓝 (f.leftLim x)) := by - apply tendsto_leftLim_of_tendsto - convert! hf.exists_tendsto_left x - simp - -/-- A bounded variation function tends to its right-limit on its right. -/ -theorem _root_.BoundedVariationOn.tendsto_rightLim [CompleteSpace E] [TopologicalSpace α] - [OrderTopology α] {f : α → E} (hf : BoundedVariationOn f univ) (x : α) : - Tendsto f (𝓝[>] x) (𝓝 (f.rightLim x)) := - hf.ofDual.tendsto_leftLim x - /-- If a function `g` is at each point `x` a limit of `f` to the left or to the right (or more generally a cluster point of the values of `f` around `x`) then the variation of `g` is bounded by that of `f`. -/ @@ -804,23 +1009,27 @@ private lemma eVariationOn_le_of_mapClusterPt grind exact sum_le_of_monotoneOn_Iic v_mono.monotoneOn (by grind) -lemma eVariationOn_leftLim_le [TopologicalSpace α] [OrderTopology α] {f : α → E} : - eVariationOn f.leftLim univ ≤ eVariationOn f univ := by +lemma eVariationOn_leftLim_le [TopologicalSpace α] [OrderTopology α] {f : α → E} + {s : Set α} (hs : IsOpen s) : + eVariationOn f.leftLim s ≤ eVariationOn f s := by apply eVariationOn_le_of_mapClusterPt (fun x hx ↦ ?_) - apply (mapClusterPt_leftLim f x).mono (nhdsWithin_mono _ (subset_univ _)) + rw [IsOpen.nhdsWithin_eq hs hx] + exact (mapClusterPt_leftLim f x).mono nhdsWithin_le_nhds -lemma eVariationOn_rightLim_le [TopologicalSpace α] [OrderTopology α] {f : α → E} : - eVariationOn f.rightLim univ ≤ eVariationOn f univ := by +lemma eVariationOn_rightLim_le [TopologicalSpace α] [OrderTopology α] {f : α → E} + {s : Set α} (hs : IsOpen s) : + eVariationOn f.rightLim s ≤ eVariationOn f s := by apply eVariationOn_le_of_mapClusterPt (fun x hx ↦ ?_) - apply (mapClusterPt_rightLim f x).mono (nhdsWithin_mono _ (subset_univ _)) + rw [IsOpen.nhdsWithin_eq hs hx] + exact (mapClusterPt_rightLim f x).mono nhdsWithin_le_nhds lemma _root_.BoundedVariationOn.leftLim [TopologicalSpace α] [OrderTopology α] {f : α → E} (hf : BoundedVariationOn f univ) : BoundedVariationOn f.leftLim univ := - (eVariationOn_leftLim_le.trans_lt hf.lt_top).ne + ((eVariationOn_leftLim_le isOpen_univ).trans_lt hf.lt_top).ne lemma _root_.BoundedVariationOn.rightLim [TopologicalSpace α] [OrderTopology α] {f : α → E} (hf : BoundedVariationOn f univ) : BoundedVariationOn f.rightLim univ := - (eVariationOn_rightLim_le.trans_lt hf.lt_top).ne + ((eVariationOn_rightLim_le isOpen_univ).trans_lt hf.lt_top).ne lemma _root_.BoundedVariationOn.continuousWithinAt_leftLim [TopologicalSpace α] [OrderTopology α] [CompleteSpace E] [T3Space E] {f : α → E} (hf : BoundedVariationOn f univ) {x : α} : @@ -909,6 +1118,17 @@ theorem MonotoneOn.locallyBoundedVariationOn {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s := fun _ _ as bs => ((hf.eVariationOn_le as bs).trans_lt ENNReal.ofReal_lt_top).ne +theorem MonotoneOn.boundedVariationOn + {f : α → ℝ} {s : Set α} {C : ℝ} (hf : MonotoneOn f s) (h : ∀ x ∈ s, |f x| ≤ C) : + BoundedVariationOn f s := by + suffices eVariationOn f s ≤ ENNReal.ofReal (2 * C) from + ne_of_lt (this.trans_lt (by simp [ENNReal.mul_lt_top])) + rw [eVariationOn.eq_biSup_inter_Icc] + simp only [mem_setOf_eq, iSup_le_iff, and_imp, Prod.forall] + intro a b as bs hab + grw [hf.eVariationOn_le as bs] + exact ENNReal.ofReal_mono (by grind) + /-- The **signed** variation of `f` on the interval `Icc a b` intersected with the set `s`, squashed to a real (therefore only really meaningful if the variation is finite) -/ @@ -967,6 +1187,16 @@ protected theorem add {f : α → E} {s : Set α} (hf : LocallyBoundedVariationO variationOnFromTo.eq_of_le f s (xy.trans yz), ← ENNReal.toReal_add (hf x y xs ys) (hf y z ys zs), eVariationOn.Icc_add_Icc f xy yz ys] +protected theorem sub_right {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} + (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : + variationOnFromTo f s a b - variationOnFromTo f s a c = variationOnFromTo f s c b := by + rw [← variationOnFromTo.add hf ha hc hb, add_sub_cancel_left] + +protected theorem sub_left {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} + (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : + variationOnFromTo f s a b - variationOnFromTo f s c b = variationOnFromTo f s a c := by + rw [← variationOnFromTo.add hf ha hc hb, add_sub_cancel_right] + variable {f s} in protected theorem edist_zero_of_eq_zero (hf : LocallyBoundedVariationOn f s) {a b : α} (ha : a ∈ s) (hb : b ∈ s) (h : variationOnFromTo f s a b = 0) : @@ -1061,6 +1291,78 @@ protected theorem comp_eq_of_monotoneOn {β : Type*} [LinearOrder β] (f : α · rw [variationOnFromTo.eq_of_ge _ _ h, variationOnFromTo.eq_of_ge _ _ (hφ hy hx h), eVariationOn.comp_inter_Icc_eq_of_monotoneOn f φ hφ hy hx] +/-- The jump of `variationOnFromTo` on the left of a point is given by the distance between the +left limit and the value of the function. -/ +theorem tendsto_left {E : Type*} [PseudoMetricSpace E] [TopologicalSpace α] [OrderTopology α] + {f : α → E} {l : E} {a b : α} (ha : a ∈ s) (hb : b ∈ s) + (hf : LocallyBoundedVariationOn f s) (h'f : Tendsto f (𝓝[s ∩ Iio b] b) (𝓝 l)) : + Tendsto (variationOnFromTo f s a) (𝓝[s ∩ Iio b] b) + (𝓝 (variationOnFromTo f s a b - dist (f b) l)) := by + suffices H : Tendsto (fun x ↦ variationOnFromTo f s a b - variationOnFromTo f s x b) + (𝓝[s ∩ Iio b] b) (𝓝 (variationOnFromTo f s a b - dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx + rw [variationOnFromTo.sub_left hf ha hb hx.1] + apply Tendsto.const_sub + suffices H : Tendsto (fun x ↦ (eVariationOn f (s ∩ Icc x b)).toReal) (𝓝[s ∩ Iio b] b) + (𝓝 (dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx using by simp [variationOnFromTo, hx.2.le] + rw [dist_edist] + exact (ENNReal.tendsto_toReal (by simp)).comp (hf.tendsto_eVariationOn_Icc_left h'f hb) + +/-- The jump of `variationOnFromTo` on the right of a point is given by the distance between the +right limit and the value of the function. -/ +theorem tendsto_right {E : Type*} [PseudoMetricSpace E] [TopologicalSpace α] [OrderTopology α] + {f : α → E} {l : E} {a b : α} (ha : a ∈ s) (hb : b ∈ s) + (hf : LocallyBoundedVariationOn f s) (h'f : Tendsto f (𝓝[s ∩ Ioi b] b) (𝓝 l)) : + Tendsto (variationOnFromTo f s a) (𝓝[s ∩ Ioi b] b) + (𝓝 (variationOnFromTo f s a b + dist (f b) l)) := by + suffices H : Tendsto (fun x ↦ variationOnFromTo f s a b + variationOnFromTo f s b x) + (𝓝[s ∩ Ioi b] b) (𝓝 (variationOnFromTo f s a b + dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx + rw [variationOnFromTo.add hf ha hb hx.1] + apply Tendsto.const_add + suffices H : Tendsto (fun x ↦ (eVariationOn f (s ∩ Icc b x)).toReal) (𝓝[s ∩ Ioi b] b) + (𝓝 (dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx using by simp [variationOnFromTo, hx.2.le] + rw [dist_edist] + exact (ENNReal.tendsto_toReal (by simp)).comp (hf.tendsto_eVariationOn_Icc_right h'f hb) + +/-- The jump of `variationOnFromTo` on the left of a point is given by the distance between the +left limit and the value of the function. -/ +theorem leftLim_eq {E : Type*} [PseudoMetricSpace E] [CompleteSpace E] + {f : α → E} {a b : α} (hf : BoundedVariationOn f univ) : + (variationOnFromTo f univ a).leftLim b = + variationOnFromTo f univ a b - dist (f b) (f.leftLim b) := by + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ + rcases eq_or_neBot (𝓝[<] b) with hb | hb + · simp [leftLim_eq_of_eq_bot _ hb] + apply leftLim_eq_of_tendsto + have := variationOnFromTo.tendsto_left (f := f) (l := f.leftLim b) (mem_univ a) (mem_univ b) + hf.locallyBoundedVariationOn + simp only [univ_inter] at this + exact this (hf.tendsto_leftLim _) + +/-- The jump of `variationOnFromTo` on the right of a point is given by the distance between the +right limit and the value of the function. -/ +theorem rightLim_eq {E : Type*} [PseudoMetricSpace E] [CompleteSpace E] + {f : α → E} {a b : α} (hf : BoundedVariationOn f univ) : + (variationOnFromTo f univ a).rightLim b = + variationOnFromTo f univ a b + dist (f b) (f.rightLim b) := by + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ + rcases eq_or_neBot (𝓝[>] b) with hb | hb + · simp [rightLim_eq_of_eq_bot _ hb] + apply rightLim_eq_of_tendsto + have := variationOnFromTo.tendsto_right (f := f) (l := f.rightLim b) (mem_univ a) (mem_univ b) + hf.locallyBoundedVariationOn + simp only [univ_inter] at this + exact this (hf.tendsto_rightLim _) + theorem _root_.BoundedVariationOn.continuousWithinAt_variationOnFromTo_Ici [TopologicalSpace α] [OrderTopology α] (hf : BoundedVariationOn f univ) {a x : α} (hx : ContinuousWithinAt f (Ici x) x) : From 7a9fb529febe853b3c1f33f126a83449cd4c09b5 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:42:22 +0000 Subject: [PATCH 0423/1300] feat: vector measures with density wrt vector measures (#41080) Co-authored-by: sgouezel --- Mathlib.lean | 1 + .../VectorMeasure/WithDensityVec.lean | 397 ++++++++++++++++++ 2 files changed, 398 insertions(+) create mode 100644 Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean diff --git a/Mathlib.lean b/Mathlib.lean index bee535a6da7157..91377af2589b28 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5646,6 +5646,7 @@ public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic public import Mathlib.MeasureTheory.VectorMeasure.Variation.Defs public import Mathlib.MeasureTheory.VectorMeasure.Variation.Semivariation public import Mathlib.MeasureTheory.VectorMeasure.WithDensity +public import Mathlib.MeasureTheory.VectorMeasure.WithDensityVec public import Mathlib.ModelTheory.Algebra.Field.Basic public import Mathlib.ModelTheory.Algebra.Field.CharP public import Mathlib.ModelTheory.Algebra.Field.IsAlgClosed diff --git a/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean b/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean new file mode 100644 index 00000000000000..4b87371e6e8109 --- /dev/null +++ b/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean @@ -0,0 +1,397 @@ +/- +Copyright (c) 2026 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral +public import Mathlib.MeasureTheory.VectorMeasure.WithDensity + +/-! +# Vector measure with density with respect to a vector measure + +Given a vector measure `μ`, a function `f` and a pairing `B`, we define the vector measure +with density `f` and pairing `B`, denoted `μ.withDensity f B`. It associates to a +measurable set the mass `∫ᵛ x in s, f x ∂[B; μ]`. + +This file implements the basic property of this notion. Notably, we show in `variation_withDensity` +that the variation of the vector measure `μ.withDensity f B` is the positive measure with +density `‖f‖` with respect to the positive measure `μ.variation`. +-/ + +open Set Filter +open scoped Topology ENNReal + +@[expose] public section + +namespace MeasureTheory.VectorMeasure + +local infixr:25 " →ₛ " => SimpleFunc + +variable {X E F G : Type*} {mX : MeasurableSpace X} + [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + [NormedAddCommGroup G] [NormedSpace ℝ G] + {μ : VectorMeasure X F} {f g : X → E} {B : E →L[ℝ] F →L[ℝ] G} {s : Set X} + +open scoped Classical in +/-- The vector measure with density `f` with respect to a vector measure `μ`, associating to a +measurable set the mass `∫ᵛ x in s, f x ∂[B; μ]`. +If `f` is not integrable, we use the junk value `0`. -/ +noncomputable def withDensity (μ : VectorMeasure X F) (f : X → E) (B : E →L[ℝ] F →L[ℝ] G) : + VectorMeasure X G := + if h : μ.Integrable f then + { measureOf' s := ∫ᵛ x in s, f x ∂[B; μ] + empty' := by simp + not_measurable' s hs := setIntegral_eq_zero_of_not_measurableSet hs + m_iUnion' s s_meas s_disj := hasSum_setIntegral_iUnion s_meas s_disj h.integrableOn } + else 0 + +lemma withDensity_apply (hf : μ.Integrable f) : + μ.withDensity f B s = ∫ᵛ x in s, f x ∂[B; μ] := by + simp [withDensity, hf] + +lemma withDensity_apply_univ : μ.withDensity f B univ = ∫ᵛ x, f x ∂[B; μ] := by + by_cases hf : μ.Integrable f + · simp [withDensity_apply hf] + · simp [withDensity, hf, integral_undef] + +@[simp] +lemma withDensity_zero_vectorMeasure : (0 : VectorMeasure X F).withDensity f B = 0 := by + ext s hs + simp [withDensity_apply] + +@[to_fun (attr := simp) withDensity_fun_zero] +lemma withDensity_zero : μ.withDensity 0 B = 0 := by + ext s hs + simp [withDensity_apply] + +lemma withDensity_congr (h : f =ᵐ[μ.variation] g) : + μ.withDensity f B = μ.withDensity g B := by + by_cases hf : μ.Integrable f + · simp only [withDensity, hf, ↓reduceDIte, Integrable.congr hf h, mk.injEq] + ext s + apply setIntegral_congr_ae + filter_upwards [h] with x hx xs using hx + · have : ¬(μ.Integrable g) := by simpa [← integrable_congr h] using hf + simp [withDensity, hf, this] + +lemma restrict_withDensity (hf : μ.Integrable f) : + (μ.withDensity f B).restrict s = (μ.restrict s).withDensity f B := by + by_cases hs : MeasurableSet s; swap + · simp [restrict_not_measurable _ hs] + · ext t ht + simp only [hs, ht, restrict_apply] + rw [withDensity_apply hf, withDensity_apply hf.restrict, restrict_restrict _ ht hs] + +lemma variation_WithDensity_le : + (μ.withDensity f B).variation ≤ (μ.transpose B).variation.withDensity (fun x ↦ ‖f x‖ₑ) := by + by_cases hf : μ.Integrable f + · apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) + rw [withDensity_apply hf, MeasureTheory.withDensity_apply _ hs] + apply enorm_setIntegral_le_lintegral_enorm_transpose + · simp [withDensity, hf, Measure.zero_le ] + +/-- If `‖B x y‖ = ‖B · y‖ * ‖x‖` for all `x, y`, then the variation of a vector measure with +density `f` wrt `μ` is the measure with density `‖f‖ₑ` with respect to the variation of `μ`. + +The condition on `B` is necessary: for a counterexample without it, let `B` be the scalar +product in `ℝ²` and `f x` everywhere horizontal and `μ s` everywhere vertical. +Then `μ.withDensity f B = 0` so its variation is zero, while the integral of `‖f‖ₑ` is not. + +See also `variation_withDensity` under the very common condition `‖B x y‖ = ‖x‖ ‖y‖`. +-/ +lemma variation_withDensity' [CompleteSpace G] + (hf : μ.Integrable f) (hB : ∀ x y, ‖B x y‖₊ = ‖B.flip y‖₊ * ‖x‖₊) : + (μ.withDensity f B).variation = (μ.transpose B).variation.withDensity (fun x ↦ ‖f x‖ₑ) := by + apply le_antisymm variation_WithDensity_le + apply Measure.le_iff.2 (fun s hs ↦ ?_) + /- For the nontrivial direction, we have to show that for each measurable set `s`, + `∫⁻ (a : X) in s, ‖f a‖ₑ ∂(μ.transpose B).variation ≤ (μ.withDensity f B).variation s`. + As the variation is a supremum over finite partitions, we need to exhibit a partition. For this, + we approximate `f` by a simple function `g`. Then the left term is approximately + `∑ i, ‖g i‖ₑ * (μ.transpose B).variation (g ⁻¹' {i})` (where everything is intersected with `s`). + By definition, the variation of `g ⁻¹' {i}` is close to a sum `∑ j, ‖(μ.transpose B) Pᵢⱼ‖ₑ` over + a partition `Pᵢⱼ` of `g ⁻¹' {i}`. Putting all these together, one gets the desired + partition of `s`, for which `∫⁻ a in s, ‖f a‖ₑ ∂(μ.transpose B).variation` is close to + `∑ i j, ‖∫ x in Pᵢⱼ, f x ∂[B; μ]‖ₑ`, i.e., `∑ i j, ‖(μ.withDensity f B) Pᵢⱼ‖ₑ`. The latter sum + is bounded by `(μ.withDensity f B).variation s` as desired. -/ + rw [MeasureTheory.withDensity_apply _ hs] + apply ENNReal.le_of_forall_pos_le_add + rintro ε εpos - + let δ := ε / 3 + have δpos : 0 < δ := div_pos εpos (by norm_num) + -- first step: approximate `f` by a simple function `g`. + obtain ⟨g, hg, gmem⟩ : ∃ (g : X →ₛ E), eLpNorm (f - ⇑g) 1 (μ.transpose B).variation ≤ δ + ∧ MemLp (⇑g) 1 μ.variation := by + obtain ⟨ρ, ρpos, hδ⟩ : ∃ ρ > 0, ‖B‖₊ * ρ ≤ δ := by + rcases eq_or_ne (‖B‖₊) 0 with hB | hB + · exact ⟨1, zero_lt_one, by simp [hB]⟩ + · refine ⟨‖B‖₊ ⁻¹ * δ, by positivity, ?_⟩ + rw [← mul_assoc] + apply mul_le_of_le_one_left (by positivity) mul_inv_le_one + obtain ⟨g, h'g, gmem⟩ : ∃ (g : X →ₛ E), eLpNorm (f - ⇑g) 1 μ.variation < ρ + ∧ MemLp (⇑g) 1 μ.variation := + (memLp_one_iff_integrable.2 hf).exists_simpleFunc_eLpNorm_sub_lt (by simp) + (by simpa using ρpos.ne') + refine ⟨g, ?_, gmem⟩ + grw [variation_transpose_le] + rw [eLpNorm_smul_measure_of_ne_top' (by simp)] + grw [h'g.le] + simp only [ENNReal.toReal_one, inv_one, NNReal.rpow_one, ENNReal.smul_def, smul_eq_mul] + exact_mod_cast hδ + -- the integral of `‖f‖ₑ` is approximated up to `δ` by that of `‖g‖ₑ`. + have I1 : ∫⁻ a in s, ‖f a‖ₑ ∂(μ.transpose B).variation + ≤ ∫⁻ a in s, ‖g a‖ₑ ∂(μ.transpose B).variation + δ := calc + _ ≤ ∫⁻ a in s, ‖f a - g a‖ₑ + ‖g a‖ₑ ∂(μ.transpose B).variation := by + gcongr with a + nth_rw 1 [show f a = (f a - g a) + g a by abel] + exact enorm_add_le (f a - g a) (g a) + _ = ∫⁻ a in s, ‖g a‖ₑ ∂(μ.transpose B).variation + + ∫⁻ a in s, ‖f a - g a‖ₑ ∂(μ.transpose B).variation := by + rw [lintegral_add_right, add_comm] + exact g.stronglyMeasurable.enorm + _ ≤ ∫⁻ a in s, ‖g a‖ₑ ∂(μ.transpose B).variation + + ∫⁻ a, ‖f a - g a‖ₑ ∂(μ.transpose B).variation := by + gcongr + exact Measure.restrict_le_self + _ ≤ ∫⁻ a in s, ‖g a‖ₑ ∂(μ.transpose B).variation + δ := by + rw [eLpNorm_one_eq_lintegral_enorm] at hg + gcongr + exact hg + -- the integral of `‖g‖ₑ` can be rewritten as a weighted sum of measures, as `g` is a simple + -- function. + have I2 : ∫⁻ a in s, ‖g a‖ₑ ∂(μ.transpose B).variation = + ∑ i ∈ g.range, ‖i‖ₑ * ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) := calc + _ = (g.map (‖·‖ₑ)).lintegral ((μ.transpose B).variation.restrict s) := + SimpleFunc.lintegral_eq_lintegral _ _ + _ = ∑ i ∈ g.range, ‖i‖ₑ * (μ.transpose B).variation.restrict s (g ⁻¹' {i}) := + SimpleFunc.map_lintegral _ _ + _ = ∑ i ∈ g.range, ‖i‖ₑ * ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) := by + simp_rw [variation_restrict hs] + -- For each `i`, choose a partition `P i` of `g ⁻¹' {i}` such that the sum of the enorms + -- of their measures approximates well enough the variation, by definition of the variation. + obtain ⟨ρ,ρpos, hρ⟩ : ∃ ρ > 0, ∑ i ∈ g.range, ‖i‖ₑ * ρ ≤ δ := by + refine ⟨δ * (∑ i ∈ g.range, ‖i‖ₑ)⁻¹, by simp [δpos], ?_⟩ + grw [← Finset.sum_mul, mul_comm (δ : ℝ≥0∞), ← mul_assoc, ENNReal.mul_inv_le_one, one_mul] + have C i : ∃ (P : Finset (Set X)), (∀ t ∈ P, t ⊆ g ⁻¹' {i}) + ∧ ((P : Set (Set X)).PairwiseDisjoint id) ∧ + (∀ t ∈ P, MeasurableSet t) ∧ + ‖i‖ₑ * ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) ≤ + ‖i‖ₑ * (∑ p ∈ P, ‖(μ.transpose B).restrict s p‖ₑ + ρ) := by + rcases eq_or_ne i 0 with rfl | hi + · exact ⟨∅, by simp⟩ + suffices ∃ (P : Finset (Set X)), (∀ t ∈ P, t ⊆ g ⁻¹' {i}) + ∧ ((P : Set (Set X)).PairwiseDisjoint id) ∧ (∀ t ∈ P, MeasurableSet t) ∧ + ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) ≤ + (∑ p ∈ P, ‖(μ.transpose B).restrict s p‖ₑ + ρ) by + obtain ⟨P, hP, h'P, h''P, h'''P⟩ := this + exact ⟨P, hP, h'P, h''P, by gcongr⟩ + apply exists_variation_le_add' _ (g.measurableSet_fiber i) ρpos + rw [variation_restrict hs] + have : MemLp (⇑g) 1 (μ.transpose B).variation := + gmem.of_measure_le_smul (c := ‖B‖₊) (by simp) (variation_transpose_le _ _) + exact (g.integrable_iff.1 (memLp_one_iff_integrable.1 this).restrict i hi).ne + choose P Pg Pdisj Pmeas hP using C + -- rewrite everything in terms of the global partition made by putting together the `Pᵢ`, + -- and register that the resulting error is bounded by `δ`. + have I3 : ∑ i ∈ g.range, ‖i‖ₑ * ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) ≤ + ∑ i ∈ g.range.sigma P, ‖i.1‖ₑ * ‖(μ.transpose B).restrict s i.2‖ₑ + δ := calc + ∑ i ∈ g.range, ‖i‖ₑ * ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) + _ ≤ ∑ i ∈ g.range, ‖i‖ₑ * ((∑ p ∈ P i, ‖(μ.transpose B).restrict s p‖ₑ) + ρ) := by + gcongr 1 with i hi + exact hP i + _ ≤ ∑ i ∈ g.range, ∑ p ∈ P i, ‖i‖ₑ * ‖(μ.transpose B).restrict s p‖ₑ + δ := by + simp_rw [mul_add, Finset.sum_add_distrib, Finset.mul_sum] + gcongr + _ = ∑ i ∈ g.range.sigma P, ‖i.1‖ₑ * ‖(μ.transpose B).restrict s i.2‖ₑ + δ := by + rw [Finset.sum_sigma'] + -- in the above sum, replace the values of `g` by `f`, as these two functions are close + -- in `L^1` norm. + have I4 : ∑ i ∈ g.range.sigma P, ‖i.1‖ₑ * ‖(μ.transpose B).restrict s i.2‖ₑ + ≤ ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ + δ := calc + ∑ i ∈ g.range.sigma P, ‖i.1‖ₑ * ‖(μ.transpose B).restrict s i.2‖ₑ + _ = ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, i.1 ∂[B; μ.restrict s]‖ₑ := by + congr! with ⟨i, p⟩ hi + rcases eq_or_ne i 0 with rfl | h'i + · simp + simp only [Finset.mem_sigma] at hi + have pmeas : MeasurableSet p := Pmeas i _ hi.2 + have : IsFiniteMeasure ((μ.restrict s).variation.restrict p) := by + constructor + rw [variation_restrict hs, Measure.restrict_restrict pmeas, + MeasureTheory.Measure.restrict_apply_univ] + apply lt_of_le_of_lt ?_ (g.integrable_iff.1 (memLp_one_iff_integrable.1 gmem) i h'i) + exact measure_mono (inter_subset_left.trans (Pg i _ hi.2)) + rw [setIntegral_const, restrict_apply _ hs pmeas, restrict_apply _ hs pmeas] + simp [transpose, hB, enorm_eq_nnnorm, mul_comm] + _ = ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, g x ∂[B; μ.restrict s]‖ₑ := by + congr! 2 with ⟨i, p⟩ hi + simp only [Finset.mem_sigma] at hi + apply setIntegral_congr_ae + filter_upwards with x hx using (Pg i _ hi.2 hx).symm + _ = ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, (g x - f x) + f x ∂[B; μ.restrict s]‖ₑ := by simp + _ = ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, (g x - f x) ∂[B; μ.restrict s] + + ∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ := by + congr! with i hi + rw [integral_fun_add] + · apply Integrable.restrict + apply Integrable.restrict + apply Integrable.sub (memLp_one_iff_integrable.1 gmem) hf + · apply hf.restrict.restrict + _ ≤ ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, (g x - f x) ∂[B; μ.restrict s]‖ₑ + + ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ := by + rw [← Finset.sum_add_distrib] + gcongr with i hi + apply enorm_add_le + _ ≤ ∑ i ∈ g.range.sigma P, ∫⁻ x in i.2, ‖g x - f x‖ₑ ∂(μ.transpose B).variation + + ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ := by + gcongr with i hi + grw [enorm_setIntegral_le_lintegral_enorm_transpose] + apply lintegral_mono' _ le_rfl + apply Measure.restrict_mono le_rfl + rw [transpose_restrict, variation_restrict hs] + apply Measure.restrict_le_self + _ = ∫⁻ x in (⋃ i ∈ g.range.sigma P, i.2), ‖g x - f x‖ₑ ∂(μ.transpose B).variation + + ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ := by + rw [lintegral_biUnion_finset] + · rintro ⟨i, p⟩ hi ⟨j, q⟩ hj hijpq + simp only [Finset.coe_sigma, SimpleFunc.coe_range, mem_sigma_iff, mem_range, + SetLike.mem_coe] at hi hj + rcases eq_or_ne i j with rfl | hij + · simp only [ne_eq, Sigma.mk.injEq, heq_eq_eq, true_and] at hijpq + exact Pdisj i hi.2 hj.2 hijpq + · have : Disjoint (g ⁻¹' {i}) (g ⁻¹' {j}) := by grind + exact this.mono (Pg i p hi.2) (Pg j q hj.2) + · rintro ⟨i, p⟩ hip + simp only [Finset.mem_sigma, SimpleFunc.mem_range, mem_range] at hip + exact Pmeas i p hip.2 + _ ≤ ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ + + ∫⁻ x, ‖g x - f x‖ₑ ∂(μ.transpose B).variation := by + rw [add_comm] + gcongr + apply Measure.restrict_le_self + _ ≤ ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ + δ := by + gcongr + simp_rw [enorm_sub_rev, ← eLpNorm_one_eq_lintegral_enorm] + exact hg + -- register that the sum of the enorms of the integrals of `f` over the pieces `Pᵢⱼ` of the + -- partition is bounded by the variation of `μ.withDensity f B`, by definition of the variation. + have I5 : ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ + ≤ (μ.withDensity f B).variation s := by + let Q : Finset (Set X) := (g.range.sigma P).image (fun p ↦ p.2 ∩ s) + calc ∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ + _ = ∑ j ∈ Q, ‖∫ᵛ x in j, f x ∂[B; μ]‖ₑ := by + simp only [Q] + rw [Finset.sum_image_of_pairwise_eq_zero]; swap + · rintro ⟨i, p⟩ hi ⟨j, q⟩ hj hijpq h'ij + simp only [Finset.coe_sigma, SimpleFunc.coe_range, mem_sigma_iff, mem_range, + SetLike.mem_coe] at hi hj + suffices H : Disjoint p q by + have : Disjoint (p ∩ s) (q ∩ s) := H.mono inter_subset_left inter_subset_left + rw [← h'ij, disjoint_self] at this + simp [this] + rcases eq_or_ne i j with rfl | hij + · simp only [ne_eq, Sigma.mk.injEq, heq_eq_eq, true_and] at hijpq + exact Pdisj i hi.2 hj.2 hijpq + · have : Disjoint (g ⁻¹' {i}) (g ⁻¹' {j}) := by grind + exact this.mono (Pg i p hi.2) (Pg j q hj.2) + apply Finset.sum_congr rfl + rintro ⟨i, p⟩ hi + simp only [Finset.mem_sigma, SimpleFunc.mem_range, mem_range] at hi + rw [restrict_restrict _ (Pmeas i p hi.2) hs] + _ = ∑ j ∈ Q, ‖μ.withDensity f B j‖ₑ := + Finset.sum_congr rfl (fun t ht ↦ by rw [withDensity_apply hf]) + _ ≤ (μ.withDensity f B).variation s := by + apply le_variation _ hs + · intro t ht + simp only [Finset.mem_image, Finset.mem_sigma, SimpleFunc.mem_range, mem_range, + Sigma.exists, ↓existsAndEq, true_and, exists_and_right, Q] at ht + rcases ht with ⟨p, -, rfl⟩ + exact inter_subset_right + · intro t ht u hu htu + simp only [Finset.coe_image, Finset.coe_sigma, SimpleFunc.coe_range, mem_image, + mem_sigma_iff, mem_range, SetLike.mem_coe, Sigma.exists, ↓existsAndEq, true_and, + exists_and_right, Q] at ht hu + rcases ht with ⟨p, ⟨i, hi⟩, rfl⟩ + rcases hu with ⟨q, ⟨j, hj⟩, rfl⟩ + have hpq : p ≠ q := by grind only + suffices H : Disjoint p q from H.mono inter_subset_left inter_subset_left + rcases eq_or_ne (g i) (g j) with hij | hij + · rw [← hij] at hj + exact Pdisj (g i) hi hj hpq + · have : Disjoint (g ⁻¹' {g i}) (g ⁻¹' {g j}) := by grind + exact this.mono (Pg (g i) p hi) (Pg (g j) q hj) + -- finally, put together the above inequalities, and argue that the overall error `3δ` is + -- bounded by `ε` by design. + calc ∫⁻ (a : X) in s, ‖f a‖ₑ ∂(μ.transpose B).variation + _ ≤ ∫⁻ a in s, ‖g a‖ₑ ∂(μ.transpose B).variation + δ := I1 + _ = ∑ i ∈ g.range, ‖i‖ₑ * ((μ.transpose B).restrict s).variation (g ⁻¹' {i}) + δ := by rw [I2] + _ ≤ (∑ i ∈ g.range.sigma P, ‖i.1‖ₑ * ‖(μ.transpose B).restrict s i.2‖ₑ + δ) + δ := by gcongr + _ ≤ ((∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ + δ) + δ) + δ := by gcongr + _ = (∑ i ∈ g.range.sigma P, ‖∫ᵛ x in i.2, f x ∂[B; μ.restrict s]‖ₑ) + 3 * δ := by ring + _ ≤ (μ.withDensity f B).variation s + 3 * δ := by gcongr + _ ≤ (μ.withDensity f B).variation s + ε := by + simp only [ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, ENNReal.coe_div, ENNReal.coe_ofNat, δ] + rw [ENNReal.mul_div_cancel (by simp) (by simp)] + +/-- If `‖B x y‖ = ‖x‖ * ‖y‖` for all `x, y`, then the variation of a vector measure with +density `f` wrt `μ` is the measure with density `‖f‖ₑ` with respect to the variation of `μ`. + +The condition on `B` is necessary: for a counterexample without it, let `B` be the scalar +product in `ℝ²` and `f x` everywhere horizontal and `μ s` everywhere vertical. +Then `μ.withDensity f B = 0` so its variation is zero, while the integral of `‖f‖ₑ` is not. +-/ +lemma variation_withDensity [CompleteSpace G] + (hf : μ.Integrable f) (hB : ∀ x y, ‖B x y‖₊ = ‖x‖₊ * ‖y‖₊) : + (μ.withDensity f B).variation = (μ.transpose B).variation.withDensity (fun x ↦ ‖f x‖ₑ) := by + apply variation_withDensity' hf (fun x y ↦ ?_) + refine le_antisymm (ContinuousLinearMap.le_opNorm (B.flip y) x) ?_ + rw [hB, mul_comm] + gcongr + apply ContinuousLinearMap.opNNNorm_le_bound + simp [hB, mul_comm] + +/-- The variation of a vecture measure with density `f` with respect to a positive measure `μ` +is the measure with density `‖f‖ₑ` with respect to `μ`. -/ +lemma _root_.MeasureTheory.Measure.variation_withDensityᵥ [CompleteSpace E] + {μ : Measure X} {f : X → E} (hf : Integrable f μ) : + (μ.withDensityᵥ f).variation = μ.withDensity (fun x ↦ ‖f x‖ₑ) := by + /- We deduce this statement from the statement `variation_withDensity` for vector measures + with density. For this, we write `μ.withDensityᵥ f` as the vector measure with density `f / ‖f‖` + with respect to the measure `μ.withDensity ‖f‖` interpreted as a signed measure. -/ + rcases subsingleton_or_nontrivial E with hE | hE + · simp [show f = 0 from Subsingleton.elim _ _] + have : IsFiniteMeasure (μ.withDensity fun x ↦ ‖f x‖ₑ) := ⟨by simpa using! hf.2⟩ + have I : (μ.withDensity fun x ↦ ‖f x‖ₑ).toSignedMeasure.Integrable (fun x ↦ ‖f x‖⁻¹ • f x) := by + simp only [VectorMeasure.Integrable, Measure.variation_toSignedMeasure] + apply Integrable.of_bound (C := 1) + · apply AEStronglyMeasurable.mono_ac (withDensity_absolutelyContinuous _ _) + exact hf.aestronglyMeasurable.norm.inv₀.smul hf.aestronglyMeasurable + · filter_upwards with x using by simp [norm_smul, inv_mul_le_one] + have : μ.withDensityᵥ f = (μ.withDensity (‖f ·‖ₑ)).toSignedMeasure.withDensity + (fun x ↦ ‖f x‖⁻¹ • f x) (ContinuousLinearMap.lsmul ℝ ℝ).flip := by + ext s hs + rw [withDensityᵥ_apply hf hs, withDensity_apply I, setIntegral_toSignedMeasure hs, + setIntegral_withDensity_eq_setIntegral_toReal_smul₀ _ _ _ hs]; rotate_left + · exact hf.aestronglyMeasurable.restrict.enorm + · filter_upwards with x using by simp + congr with x + rcases eq_or_ne (f x) 0 with hx | hx + · simp [hx] + simp only [toReal_enorm, smul_smul] + rw [mul_inv_cancel₀, one_smul] + simpa using hx + rw [this, variation_withDensity I (by simp [nnnorm_smul, mul_comm]), + variation_transpose_eq _ _ (by simp [nnnorm_smul, mul_comm]), Measure.variation_toSignedMeasure, + ← withDensity_mul₀ hf.aestronglyMeasurable.enorm]; swap + · exact (hf.aestronglyMeasurable.norm.inv₀.smul hf.aestronglyMeasurable).enorm + congr with x + rcases eq_or_ne (f x) 0 with hx | hx + · simp [hx] + have h'x : ‖f x‖ ≠ 0 := by simp [hx] + simp only [enorm_smul, Pi.mul_apply, ne_eq, h'x, not_false_eq_true, enorm_inv, enorm_norm] + rw [ENNReal.inv_mul_cancel (by simpa using hx) (by simp), mul_one] + +end MeasureTheory.VectorMeasure From 930ff2668ce8a1d98904cc5fb758bb576222e2bc Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:42:24 +0000 Subject: [PATCH 0424/1300] =?UTF-8?q?chore(Algebra/Polynomial/Eval/Defs):?= =?UTF-8?q?=20`eval=E2=82=82RingHom=5Fcomp=5FC`=20(#41124)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR was automatically created from PR #39865 by @eliasjudin via a [review comment](https://github.com/leanprover-community/mathlib4/pull/39865#discussion_r3487794637) by @themathqueen. Co-authored-by: eliasjudin <48514516+eliasjudin@users.noreply.github.com> --- Mathlib/Algebra/Polynomial/Eval/Defs.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Algebra/Polynomial/Eval/Defs.lean b/Mathlib/Algebra/Polynomial/Eval/Defs.lean index 6cfdf3fe6d567d..c42ff574f95219 100644 --- a/Mathlib/Algebra/Polynomial/Eval/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Eval/Defs.lean @@ -219,6 +219,11 @@ def eval₂RingHom (f : R →+* S) (x : S) : R[X] →+* S := theorem coe_eval₂RingHom (f : R →+* S) (x) : ⇑(eval₂RingHom f x) = eval₂ f x := rfl +@[simp] +theorem eval₂RingHom_comp_C (f : R →+* S) (x : S) : (eval₂RingHom f x).comp C = f := by + ext + simp + theorem eval₂_pow (n : ℕ) : (p ^ n).eval₂ f x = p.eval₂ f x ^ n := (eval₂RingHom _ _).map_pow _ _ From 872d8ee681ebdf6bf42310a82aa82d1cf1b07698 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 29 Jun 2026 12:10:41 +0000 Subject: [PATCH 0425/1300] chore(LinearAlgebra/Matrix): avoid defeq abuse in cRank (#40128) The previous definition of cRank uses Matrix as a function to the parameter of Set.range. This causes difficulties in downstream proofs when unfolding and applying lemmas. The new definition uses col to explicitly convert from Matrix to function. --- Mathlib/LinearAlgebra/Matrix/Defs.lean | 3 +++ Mathlib/LinearAlgebra/Matrix/Rank.lean | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index 12896de854d302..2d18b759ff2821 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -258,6 +258,9 @@ section @[simp] theorem zero_apply [Zero α] (i : m) (j : n) : (0 : Matrix m n α) i j = 0 := rfl +@[simp] +theorem of_symm_zero [Zero α] : of.symm (0 : Matrix m n α) = (0 : m → n → α) := rfl + @[simp] theorem add_apply [Add α] (A B : Matrix m n α) (i : m) (j : n) : (A + B) i j = (A i j) + (B i j) := rfl diff --git a/Mathlib/LinearAlgebra/Matrix/Rank.lean b/Mathlib/LinearAlgebra/Matrix/Rank.lean index bd582b3ec5338e..d2e68d01aad5b4 100644 --- a/Mathlib/LinearAlgebra/Matrix/Rank.lean +++ b/Mathlib/LinearAlgebra/Matrix/Rank.lean @@ -44,7 +44,7 @@ section Infinite variable [Semiring R] /-- The rank of a matrix, defined as the dimension of its column space, as a cardinal. -/ -noncomputable def cRank (A : Matrix m n R) : Cardinal := Module.rank R <| span R <| range Aᵀ +noncomputable def cRank (A : Matrix m n R) : Cardinal := Module.rank R <| span R <| range A.col @[simp] theorem cRank_subsingleton [Subsingleton R] (A : Matrix m n R) : A.cRank = 1 := @@ -59,8 +59,8 @@ lemma lift_cRank_submatrix_le (A : Matrix m n R) (r : m₀ → m) (c : n₀ → Submodule.rank_mono <| span_mono <| by rintro _ ⟨x, rfl⟩; exact ⟨c x, rfl⟩ refine (Cardinal.lift_monotone h).trans ?_ let f : (m → R) →ₗ[R] (m₀ → R) := LinearMap.funLeft R R r - have h_eq : Submodule.map f (span R (range Aᵀ)) = span R (range (A.submatrix r id)ᵀ) := by - rw [LinearMap.map_span, ← image_univ, image_image, transpose_submatrix] + have h_eq : Submodule.map f (span R (range A.col)) = span R (range (A.submatrix r id).col) := by + simp_rw [LinearMap.map_span, ← image_univ, image_image, col_eq_transpose, transpose_submatrix] aesop rw [cRank, ← h_eq] have hwin := lift_rank_map_le f (span R (range Aᵀ)) @@ -78,7 +78,8 @@ lemma cRank_le_card_height [StrongRankCondition R] [Fintype m] (A : Matrix m n R lemma cRank_le_card_width [StrongRankCondition R] [Fintype n] (A : Matrix m n R) : A.cRank ≤ Fintype.card n := - (rank_span_le ..).trans <| by simpa using Cardinal.mk_range_le_lift (f := Aᵀ) + (rank_span_le ..).trans <| + by simpa [col_eq_transpose] using Cardinal.mk_range_le_lift (f := A.col) /-- The rank of a matrix, defined as the dimension of its column space, as a term in `ℕ∞`. -/ noncomputable def eRank (A : Matrix m n R) : ℕ∞ := A.cRank.toENat @@ -125,9 +126,9 @@ theorem rank_subsingleton [CommSemiring R] [Subsingleton R] (A : Matrix m n R) : @[simp] theorem cRank_one [Semiring R] [Nontrivial R] [DecidableEq m] [StrongRankCondition R] : (cRank (1 : Matrix m m R)) = lift.{uR} #m := by - have h : LinearIndependent R (1 : Matrix m m R)ᵀ := by + have h : LinearIndependent R (1 : Matrix m m R).col := by convert! Pi.linearIndependent_single_one m R - simp [funext_iff, Matrix.one_eq_pi_single] + simp [funext_iff, one_apply, Pi.single_apply] rw [cRank, rank_span h, ← lift_umax, ← Cardinal.mk_range_eq_of_injective h.injective, lift_id'] @[simp] theorem eRank_one [Semiring R] [Nontrivial R] [DecidableEq m] [StrongRankCondition R] : @@ -143,12 +144,12 @@ theorem rank_one [CommSemiring R] [DecidableEq n] [StrongRankCondition R] : theorem rank_zero [CommSemiring R] [Nontrivial R] : rank (0 : Matrix m n R) = 0 := by rw [rank, mulVecLin_zero, LinearMap.range_zero, finrank_bot] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem cRank_zero {m n : Type*} [Semiring R] [Nontrivial R] : cRank (0 : Matrix m n R) = 0 := by obtain hn | hn := isEmpty_or_nonempty n · rw [cRank, range_eq_empty, span_empty, rank_bot] - rw [cRank, transpose_zero, range_zero, span_zero_singleton, rank_bot] + rw [cRank, col_eq_transpose, transpose_zero, of_symm_zero, range_zero, span_zero_singleton, + rank_bot] @[simp] theorem eRank_zero {m n : Type*} [Semiring R] [Nontrivial R] : eRank (0 : Matrix m n R) = 0 := by @@ -337,9 +338,9 @@ theorem cRank_diagonal [DecidableEq m] (w : m → R) : convert! hli'.comp Subtype.val Subtype.val_injective ext ⟨j, hj⟩ k simp [w', diagonal, hj, Pi.single_apply, eq_comm] - have hrw : insert 0 (range (diagonal w)ᵀ) = insert 0 (range w') := by + have hrw : insert 0 (range (diagonal w).col) = insert 0 (range w') := by suffices ∀ a, diagonal w a = 0 ∨ ∃ b, w b ≠ 0 ∧ diagonal w b = diagonal w a - by simpa [subset_antisymm_iff, subset_def, w'] + by aesop (add simp [col_eq_transpose, subset_def]) simp_rw [or_iff_not_imp_right, not_exists, not_and, not_imp_not] simp +contextual [funext_iff, diagonal] rw [cRank, ← span_insert_zero, hrw, span_insert_zero, rank_span h, From 20d9d3de08efaec4df2b78e8931bcf32dbc149de Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 29 Jun 2026 15:33:28 +0000 Subject: [PATCH 0426/1300] feat(Algebra/Category): `TensorAlgebra` as a left-adjoint to the forgetful functor from algebras to modules (#41151) We also add the basic API for restriction of scalars functors in `AlgCat`. --- Mathlib.lean | 1 + Mathlib/Algebra/Category/AlgCat/Basic.lean | 80 +++++++++++++++++++ .../Category/AlgCat/TensorAlgebra.lean | 77 ++++++++++++++++++ Mathlib/CategoryTheory/Adjunction/Basic.lean | 36 +++++++++ 4 files changed, 194 insertions(+) create mode 100644 Mathlib/Algebra/Category/AlgCat/TensorAlgebra.lean diff --git a/Mathlib.lean b/Mathlib.lean index 91377af2589b28..c192f9b909c0f2 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -100,6 +100,7 @@ public import Mathlib.Algebra.Category.AlgCat.FilteredColimits public import Mathlib.Algebra.Category.AlgCat.Limits public import Mathlib.Algebra.Category.AlgCat.Monoidal public import Mathlib.Algebra.Category.AlgCat.Symmetric +public import Mathlib.Algebra.Category.AlgCat.TensorAlgebra public import Mathlib.Algebra.Category.BialgCat.Basic public import Mathlib.Algebra.Category.BialgCat.Monoidal public import Mathlib.Algebra.Category.BoolRing diff --git a/Mathlib/Algebra/Category/AlgCat/Basic.lean b/Mathlib/Algebra/Category/AlgCat/Basic.lean index e2ac960488e9b5..5ce0fe4c889ec0 100644 --- a/Mathlib/Algebra/Category/AlgCat/Basic.lean +++ b/Mathlib/Algebra/Category/AlgCat/Basic.lean @@ -252,3 +252,83 @@ instance AlgCat.forget_reflects_isos : (forget (AlgCat.{v} R)).ReflectsIsomorphi let i := asIso ((forget (AlgCat.{v} R)).map f) let e : X ≃ₐ[R] Y := { f.hom, i.toEquiv with } exact e.toAlgebraIso.isIso_hom + +namespace AlgCat + +/-- The restriction of scalars functor `AlgCat S ⥤ AlgCat R` induced by a ring homomorphism +`R →+* S`. -/ +@[simps] +def restrictScalars {R S : Type*} [CommRing R] [CommRing S] (f : R →+* S) : + AlgCat.{v} S ⥤ AlgCat.{v} R where + obj A := + letI : Algebra R A := Algebra.compHom _ f + AlgCat.of R A + map {A B} g := + letI : Algebra R A := Algebra.compHom _ f + letI : Algebra R B := Algebra.compHom _ f + letI : Algebra R S := f.toAlgebra + haveI : IsScalarTower R S A := .of_algebraMap_eq' rfl + haveI : IsScalarTower R S B := .of_algebraMap_eq' rfl + AlgCat.ofHom (g.hom.restrictScalars _) + +-- The option makes `simps` produce the correct lemmas +set_option backward.isDefEq.respectTransparency false in +/-- Restricting scalars along the identity is isomorphic to the identity. -/ +@[simps!] +def restrictScalarsId' {R : Type*} [CommRing R] (f : R →+* R) (hf : f = .id R) : + AlgCat.restrictScalars.{v} f ≅ 𝟭 _ := + NatIso.ofComponents + fun A ↦ AlgEquiv.toAlgebraIso <| + @AlgEquiv.ofRingEquiv (f := RingEquiv.refl _) _ _ _ _ _ _ + ((restrictScalars f).obj A).isAlgebra _ fun _ ↦ by subst hf; rfl + +-- The option makes `simps` produce the correct lemmas +set_option backward.isDefEq.respectTransparency false in +/-- Restricting scalars along a composition is isomorphic to the composition +of restriction of scalars. -/ +@[simps!] +def restrictScalarsComp' {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] (f : R →+* S) + (g : S →+* T) (gf : R →+* T) (hfg : gf = g.comp f) : + AlgCat.restrictScalars.{v} gf ≅ + AlgCat.restrictScalars.{v} g ⋙ AlgCat.restrictScalars.{v} f := + NatIso.ofComponents + fun A ↦ AlgEquiv.toAlgebraIso <| + @AlgEquiv.ofRingEquiv (f := RingEquiv.refl _) _ _ _ _ _ _ + ((restrictScalars gf).obj A).isAlgebra + ((restrictScalars f).obj ((restrictScalars g).obj A)).isAlgebra + fun _ ↦ by subst hfg; rfl + +/-- A ring isomorphism induces an equivalence of categories of algebras. -/ +@[simps] +def restrictScalarsEquivalenceOfRingEquiv {R S : Type*} [CommRing R] [CommRing S] (e : R ≃+* S) : + AlgCat.{u} S ≌ AlgCat.{u} R where + functor := restrictScalars e.toRingHom + inverse := restrictScalars e.symm.toRingHom + unitIso := (restrictScalarsId' _ rfl).symm ≪≫ + restrictScalarsComp' _ _ _ e.toRingHom_comp_symm_toRingHom.symm + counitIso := (restrictScalarsComp' _ _ _ e.symm_toRingHom_comp_toRingHom.symm).symm ≪≫ + restrictScalarsId' _ rfl + +instance {R S : Type*} [CommRing R] [CommRing S] (e : R ≃+* S) : + (restrictScalars e.toRingHom).IsEquivalence := + inferInstanceAs <| (restrictScalarsEquivalenceOfRingEquiv e).functor.IsEquivalence + +instance {R S : Type*} [CommRing R] [CommRing S] (e : R ≃+* S) : + (restrictScalars e.symm.toRingHom).IsEquivalence := + inferInstanceAs <| (restrictScalarsEquivalenceOfRingEquiv e).inverse.IsEquivalence + +/-- The equivalence of categories of `ℤ`-algebras and rings. -/ +@[simps! (dsimpLhs := true) functor inverse_obj inverse_map_hom unitIso_hom_app_hom_apply counitIso] +def intEquivalence : AlgCat.{u} ℤ ≌ RingCat.{u} where + functor := forget₂ _ _ + inverse.obj A := AlgCat.of ℤ A + inverse.map f := AlgCat.ofHom f.hom.toIntAlgHom + unitIso := NatIso.ofComponents + fun A ↦ AlgEquiv.toAlgebraIso (@.ofRingEquiv (f := RingEquiv.refl _) + _ _ _ _ _ _ _ (Ring.toIntAlgebra _) fun _ ↦ by simp) + counitIso := Iso.refl _ + +instance : (forget₂ (AlgCat.{u} ℤ) RingCat.{u}).IsEquivalence := + inferInstanceAs <| intEquivalence.functor.IsEquivalence + +end AlgCat diff --git a/Mathlib/Algebra/Category/AlgCat/TensorAlgebra.lean b/Mathlib/Algebra/Category/AlgCat/TensorAlgebra.lean new file mode 100644 index 00000000000000..8c91ec30bdbcae --- /dev/null +++ b/Mathlib/Algebra/Category/AlgCat/TensorAlgebra.lean @@ -0,0 +1,77 @@ +/- +Copyright (c) 2026 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +module + +public import Mathlib.Algebra.Category.AlgCat.Basic +public import Mathlib.Algebra.Category.Grp.ZModuleEquivalence +public import Mathlib.Algebra.Category.ModuleCat.ChangeOfRings +public import Mathlib.Algebra.Ring.Shrink +public import Mathlib.LinearAlgebra.TensorAlgebra.Basic + +/-! +# `TensorAlgebra` as a functor `ModuleCat R ⥤ AlgCat R` + +In this file we define the functor `AlgCat.tensorAlgebra : ModuleCat R ⥤ AlgCat R` +sending an `R`-module `M` to the tensor algebra `TensorAlgebra R M`. We +show that this functor is a left-adjoint to the forgetful functor `AlgCat R ⥤ ModuleCat R`. +-/ + +@[expose] public section + +universe w v u + +open CategoryTheory + +namespace AlgCat + +/-- The functor sending an `R`-module `M` to its tensor algebra over `R`. -/ +@[simps] +def tensorAlgebra (R : Type u) [CommRing R] : ModuleCat.{w} R ⥤ AlgCat.{max u w} R where + obj M := AlgCat.of R (TensorAlgebra R M) + map f := AlgCat.ofHom (TensorAlgebra.lift _ (TensorAlgebra.ι _ ∘ₗ f.hom)) + +variable (R : Type u) [CommRing R] + +set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in +/-- Taking the tensor algebra forms a left adjoint of the forgetful functor from `AlgCat R` to +`ModuleCat R`. -/ +@[simps] +def tensorAlgebraAdj : tensorAlgebra.{u} R ⊣ forget₂ (AlgCat.{u} R) (ModuleCat.{u} R) where + unit.app M := ModuleCat.ofHom (TensorAlgebra.ι _) + counit.app A := AlgCat.ofHom (TensorAlgebra.lift R .id) + counit.naturality _ _ _ := by + ext : 1 + apply TensorAlgebra.hom_ext + ext + simp + left_triangle_components _ := by + ext : 1 + dsimp + ext + simp + +set_option backward.isDefEq.respectTransparency false in +instance (R : Type v) [CommRing R] [Small.{u} R] : + (forget₂ (AlgCat.{u} R) (ModuleCat.{u} R)).IsRightAdjoint := by + let e : AlgCat.{u} R ≌ AlgCat.{u} (Shrink.{u} R) := + restrictScalarsEquivalenceOfRingEquiv (Shrink.ringEquiv R) + have : e.inverse ⋙ forget₂ (AlgCat R) (ModuleCat R) = forget₂ _ _ ⋙ + (ModuleCat.restrictScalarsEquivalenceOfRingEquiv (Shrink.ringEquiv R)).inverse := + rfl + rw [← Functor.isRightAdjoint_comp_iff_right e.inverse, this] + have := (tensorAlgebraAdj (Shrink.{u} R)).isRightAdjoint + infer_instance + +instance : (forget₂ RingCat.{u} AddCommGrpCat.{u}).IsRightAdjoint := by + rw [← Functor.isRightAdjoint_comp_iff_right (forget₂ (AlgCat.{u} ℤ) RingCat.{u})] + have heq : forget₂ (AlgCat.{u} ℤ) _ ⋙ forget₂ (ModuleCat.{u} ℤ) AddCommGrpCat.{u} = + forget₂ (AlgCat.{u} ℤ) RingCat.{u} ⋙ forget₂ RingCat.{u} AddCommGrpCat.{u} := + rfl + rw [← heq] + infer_instance + +end AlgCat diff --git a/Mathlib/CategoryTheory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Adjunction/Basic.lean index ebe5a05c0cbd52..6a55b63965bfc6 100644 --- a/Mathlib/CategoryTheory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Adjunction/Basic.lean @@ -799,6 +799,42 @@ instance (priority := 10) isRightAdjoint_of_isEquivalence {F : C ⥤ D} [F.IsEqu IsRightAdjoint F := F.asEquivalence.isRightAdjoint_functor +lemma isLeftAdjoint_comp_iff_right {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) (G : D ⥤ E) + [F.IsEquivalence] : + (F ⋙ G).IsLeftAdjoint ↔ G.IsLeftAdjoint := by + refine ⟨fun h ↦ ?_, fun h ↦ inferInstance⟩ + let iso : G ≅ F.asEquivalence.inverse ⋙ F ⋙ G := + (Functor.leftUnitor _).symm ≪≫ Functor.isoWhiskerRight (F.asEquivalence.counitIso).symm _ ≪≫ + Functor.associator _ _ _ + exact isLeftAdjoint_of_iso iso.symm + +lemma isRightAdjoint_comp_iff_right {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) (G : D ⥤ E) + [F.IsEquivalence] : + (F ⋙ G).IsRightAdjoint ↔ G.IsRightAdjoint := by + refine ⟨fun h ↦ ?_, fun h ↦ inferInstance⟩ + let iso : G ≅ F.asEquivalence.inverse ⋙ F ⋙ G := + (Functor.leftUnitor _).symm ≪≫ Functor.isoWhiskerRight (F.asEquivalence.counitIso).symm _ ≪≫ + Functor.associator _ _ _ + exact isRightAdjoint_of_iso iso.symm + +lemma isLeftAdjoint_comp_iff_left {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) (G : D ⥤ E) + [G.IsEquivalence] : + (F ⋙ G).IsLeftAdjoint ↔ F.IsLeftAdjoint := by + refine ⟨fun h ↦ ?_, fun h ↦ inferInstance⟩ + let iso : F ≅ (F ⋙ G) ⋙ G.asEquivalence.inverse := + (Functor.rightUnitor _).symm ≪≫ Functor.isoWhiskerLeft _ G.asEquivalence.unitIso ≪≫ + (Functor.associator _ _ _).symm + exact isLeftAdjoint_of_iso iso.symm + +lemma isRightAdjoint_comp_iff_left {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) (G : D ⥤ E) + [G.IsEquivalence] : + (F ⋙ G).IsRightAdjoint ↔ F.IsRightAdjoint := by + refine ⟨fun h ↦ ?_, fun h ↦ inferInstance⟩ + let iso : F ≅ (F ⋙ G) ⋙ G.asEquivalence.inverse := + (Functor.rightUnitor _).symm ≪≫ Functor.isoWhiskerLeft _ G.asEquivalence.unitIso ≪≫ + (Functor.associator _ _ _).symm + exact isRightAdjoint_of_iso iso.symm + end Functor end CategoryTheory From 95fdbd69e13b7e6b08d6b2ea72cbb6dd26d0d5f8 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:01:33 +0000 Subject: [PATCH 0427/1300] =?UTF-8?q?chore:=20clean=20up=20`backward.priva?= =?UTF-8?q?teInPublic`=20around=20`d=E2=82=82=E2=82=83`=20(#40228)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inlines a single-use private declaration, which allows us to get rid of a couple `backward.privateInPublic`s. This reduces instructions in that file by ~29% (but this gets swallowed in the overall noise). Note: before this PR, `LieModule.Cohomology.d₂₃_aux._proof_17` was the biggest proof in mathlib (counted with sharing). :) This PR changes it to `CategoryTheory.Functor.IsDenseSubsite.isIso_ranCounit_app_of_isDenseSubsite`. --- Mathlib/Algebra/Lie/Cochain.lean | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/Mathlib/Algebra/Lie/Cochain.lean b/Mathlib/Algebra/Lie/Cochain.lean index b51e93210a2d31..d31d324d5838a4 100644 --- a/Mathlib/Algebra/Lie/Cochain.lean +++ b/Mathlib/Algebra/Lie/Cochain.lean @@ -117,26 +117,20 @@ lemma d₁₂_apply_apply_ofTrivial [LieModule.IsTrivial L M] (f : oneCochain R d₁₂ R L M f x y = - f ⁅x, y⁆ := by simp [trivial_lie_zero] -set_option backward.privateInPublic true in /-- The coboundary operator taking degree 2 cochains to a space containing degree 3 cochains. -/ -private def d₂₃Aux (a : twoCochain R L M) : L →ₗ[R] L →ₗ[R] L →ₗ[R] M where - toFun x := - { toFun y := - { toFun z := ⁅x, a y z⁆ - ⁅y, a x z⁆ + ⁅z, a x y⁆ - a ⁅x, y⁆ z + a ⁅x, z⁆ y - a ⁅y, z⁆ x - map_add' _ _ := by simp; abel - map_smul' _ _ := by abel_nf; simp } +def d₂₃ : twoCochain R L M →ₗ[R] L →ₗ[R] L →ₗ[R] L →ₗ[R] M where + toFun a := { + toFun x := { + toFun y := { + toFun z := ⁅x, a y z⁆ - ⁅y, a x z⁆ + ⁅z, a x y⁆ - a ⁅x, y⁆ z + a ⁅x, z⁆ y - a ⁅y, z⁆ x + map_add' _ _ := by simp; abel + map_smul' _ _ := by simp; abel_nf; simp } map_add' _ _ := by ext; simp; abel - map_smul' _ _ := by ext; abel_nf; simp } + map_smul' _ _ := by ext; simp; abel_nf; simp } + map_add' _ _ := by ext; simp; abel + map_smul' _ _ := by ext; simp; abel_nf; simp } map_add' _ _ := by ext; simp; abel - map_smul' _ _ := by ext; abel_nf; simp - -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in -/-- The coboundary operator taking degree 2 cochains to a space containing degree 3 cochains. -/ -def d₂₃ : twoCochain R L M →ₗ[R] L →ₗ[R] L →ₗ[R] L →ₗ[R] M where - toFun := d₂₃Aux R L M - map_add' _ _ := by ext; simp [d₂₃Aux]; abel - map_smul' _ _ := by ext; simp [d₂₃Aux]; abel_nf; simp + map_smul' _ _ := by ext; simp; abel_nf; simp @[simp] lemma d₂₃_apply (a : twoCochain R L M) (x y z : L) : From 35ab429f5240fa22c680dfc666e76b7406114151 Mon Sep 17 00:00:00 2001 From: "M. Winter" <112132359+martinwintermath@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:21:24 +0000 Subject: [PATCH 0428/1300] feat(LinearAlgebra/SesquilinearForm): moving orthogonality to own file (#37963) Move `Submodule.orthogonalBilin` and all lemmas that use it from SesquilinearForm/Basic.lean to its own file SesquilinearForm/Orthogonal.lean. We also add `gcongr` to `orthogonalBilin_le`. Co-authored-by: Martin Winter --- Mathlib.lean | 1 + .../InnerProductSpace/Orthogonal.lean | 2 +- .../BilinearForm/Orthogonal.lean | 1 + .../LinearAlgebra/QuadraticForm/Basic.lean | 1 + .../LinearAlgebra/SesquilinearForm/Basic.lean | 109 -------------- .../SesquilinearForm/Orthogonal.lean | 140 ++++++++++++++++++ 6 files changed, 144 insertions(+), 110 deletions(-) create mode 100644 Mathlib/LinearAlgebra/SesquilinearForm/Orthogonal.lean diff --git a/Mathlib.lean b/Mathlib.lean index c192f9b909c0f2..439e0d6f37b4b1 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5237,6 +5237,7 @@ public import Mathlib.LinearAlgebra.SModEq.Pointwise public import Mathlib.LinearAlgebra.SModEq.Pow public import Mathlib.LinearAlgebra.Semisimple public import Mathlib.LinearAlgebra.SesquilinearForm.Basic +public import Mathlib.LinearAlgebra.SesquilinearForm.Orthogonal public import Mathlib.LinearAlgebra.SesquilinearForm.Star public import Mathlib.LinearAlgebra.Span.Basic public import Mathlib.LinearAlgebra.Span.Defs diff --git a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean index 82411d48abf41a..7a191b6d044670 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean @@ -6,7 +6,7 @@ Authors: Zhouhang Zhou, Sébastien Gouëzel, Frédéric Dupuis module public import Mathlib.Analysis.InnerProductSpace.Subspace -public import Mathlib.LinearAlgebra.SesquilinearForm.Basic +public import Mathlib.LinearAlgebra.SesquilinearForm.Orthogonal public import Mathlib.Topology.Algebra.Module.ClosedSubmodule /-! diff --git a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean index 6400c41c3c9ff0..d837239375be43 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.GroupWithZero.NonZeroDivisors public import Mathlib.LinearAlgebra.BilinearForm.Properties +public import Mathlib.LinearAlgebra.SesquilinearForm.Orthogonal /-! # Bilinear form diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index 7a28de8535feb4..1bd2bf12f0d792 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -6,6 +6,7 @@ Authors: Anne Baanen, Kexing Ying, Eric Wieser module public import Mathlib.Data.Finset.Sym +public import Mathlib.LinearAlgebra.SesquilinearForm.Orthogonal public import Mathlib.LinearAlgebra.BilinearMap public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean index bd8ccfce7388c1..2bdabb1c709851 100644 --- a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean @@ -26,7 +26,6 @@ basic lemmas about construction and elementary calculations are found there. ## Main declarations * `IsSymm`, `IsAlt`: states that a sesquilinear form is symmetric and alternating, respectively -* `orthogonalBilin` provides the orthogonal complement with respect to a sesquilinear map ## References @@ -358,102 +357,8 @@ end Alternating end LinearMap -namespace Submodule - -/-! ### The orthogonal complement -/ - -variable [CommSemiring R] [CommSemiring R₁] [CommSemiring R₂] -variable [AddCommMonoid M] [Module R M] -variable [AddCommMonoid M₁] [Module R₁ M₁] -variable [AddCommMonoid M₂] [Module R₂ M₂] -variable {N L : Submodule R₁ M₁} - -section - -variable {I₁ : R₁ →+* R} {I₂ : R₂ →+* R} {B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M} - -variable (B) in -/-- The orthogonal complement of a submodule `N` with respect to some bilinear map is the set of -elements `x` which are orthogonal to all elements of `N`; i.e., for all `y` in `N`, `B x y = 0`. - -Note that for general (neither symmetric nor antisymmetric) bilinear maps this definition has a -chirality; in addition to this "left" orthogonal complement one could define a "right" orthogonal -complement for which, for all `y` in `N`, `B y x = 0`. This variant definition is not currently -provided in mathlib. -/ -def orthogonalBilin (N : Submodule R₁ M₁) : Submodule R₂ M₂ where - carrier := { m | ∀ n ∈ N, B n m = 0 } - zero_mem' x _ := map_zero _ - add_mem' {u v} hu hv x hx := by simp [hu _ hx, hv _ hx] - smul_mem' c y hy x hx := by simp [hy _ hx] - -@[simp] -theorem mem_orthogonalBilin_iff {m : M₂} : m ∈ N.orthogonalBilin B ↔ ∀ n ∈ N, B n m = 0:= - Iff.rfl - -theorem orthogonalBilin_le (h : N ≤ L) : L.orthogonalBilin B ≤ N.orthogonalBilin B := - fun _ hn l hl ↦ hn l (h hl) - -end - -section - -variable {I₁ : R₁ →+* R} {I₂ : R₁ →+* R} {B : M₁ →ₛₗ[I₁] M₁ →ₛₗ[I₂] M} - -theorem le_orthogonalBilin_orthogonalBilin (b : B.IsRefl) : - N ≤ (N.orthogonalBilin B).orthogonalBilin B := fun n hn _m hm ↦ b _ _ (hm n hn) - -end - -end Submodule - namespace LinearMap -section Orthogonal - -variable [Field K] [AddCommGroup V] [Module K V] [Field K₁] [AddCommGroup V₁] [Module K₁ V₁] - [AddCommGroup V₂] [Module K V₂] {J : K →+* K} {J₁ : K₁ →+* K} {J₁' : K₁ →+* K} - --- ↓ This lemma only applies in fields as we require `a * b = 0 → a = 0 ∨ b = 0` -theorem span_singleton_inf_orthogonal_eq_bot (B : V₁ →ₛₗ[J₁] V₁ →ₛₗ[J₁'] V₂) (x : V₁) - (hx : B x x ≠ 0) : (K₁ ∙ x) ⊓ (K₁ ∙ x).orthogonalBilin B = ⊥ := by - rw [← Finset.coe_singleton] - refine eq_bot_iff.2 fun y h ↦ ?_ - obtain ⟨μ, -, rfl⟩ := Submodule.mem_span_finset.1 h.1 - replace h := h.2 x (by simp [Submodule.mem_span] : x ∈ Submodule.span K₁ ({x} : Finset V₁)) - rw [Finset.sum_singleton] at h ⊢ - suffices hμzero : μ x = 0 by rw [hμzero, zero_smul, Submodule.mem_bot] - rw [map_smulₛₗ] at h - exact Or.elim (smul_eq_zero.mp h) - (fun y ↦ by simpa using y) - (fun hfalse ↦ False.elim <| hx hfalse) - --- ↓ This lemma only applies in fields since we use the `mul_eq_zero` -theorem orthogonal_span_singleton_eq_to_lin_ker {B : V →ₗ[K] V →ₛₗ[J] V₂} (x : V) : - (K ∙ x).orthogonalBilin B = LinearMap.ker (B x) := by - ext y - simp_rw [Submodule.mem_orthogonalBilin_iff, LinearMap.mem_ker, Submodule.mem_span_singleton] - constructor - · exact fun h ↦ h x ⟨1, one_smul _ _⟩ - · rintro h _ ⟨z, rfl⟩ - rw [map_smulₛₗ₂, smul_eq_zero] - exact Or.intro_right _ h - --- todo: Generalize this to sesquilinear maps -theorem span_singleton_sup_orthogonal_eq_top {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : B x x ≠ 0) : - (K ∙ x) ⊔ (K ∙ x).orthogonalBilin B = ⊤ := by - rw [orthogonal_span_singleton_eq_to_lin_ker] - exact (B x).span_singleton_sup_ker_eq_top hx - --- todo: Generalize this to sesquilinear maps -/-- Given a bilinear form `B` and some `x` such that `B x x ≠ 0`, the span of the singleton of `x` - is complement to its orthogonal complement. -/ -theorem isCompl_span_singleton_orthogonal {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : B x x ≠ 0) : - IsCompl (K ∙ x) ((K ∙ x).orthogonalBilin B) := - { disjoint := disjoint_iff.2 <| span_singleton_inf_orthogonal_eq_bot B x hx - codisjoint := codisjoint_iff.2 <| span_singleton_sup_orthogonal_eq_top hx } - -end Orthogonal - /-! ### Adjoint pairs -/ section AdjointPair @@ -829,20 +734,6 @@ lemma IsSymm.nondegenerate_restrict_of_isCompl_ker {B : M →ₗ[R] M →ₗ[R] exact hx' u hu simpa [hW.inf_eq_bot] using! hx' -/-- The restriction of a reflexive bilinear map `B` onto a submodule `W` is -nondegenerate if `W` has trivial intersection with its orthogonal complement, -that is `Disjoint W (W.orthogonalBilin B)`. -/ -theorem nondegenerate_restrict_of_disjoint_orthogonal {B : M →ₗ[R] M →ₗ[R] M₁} (hB : B.IsRefl) - {W : Submodule R M} (hW : Disjoint W (W.orthogonalBilin B)) : - (B.domRestrict₁₂ W W).Nondegenerate := by - rw [(hB.domRestrict W).nondegenerate_iff_separatingLeft] - rintro ⟨x, hx⟩ b₁ - rw [Submodule.mk_eq_zero, ← Submodule.mem_bot R] - refine hW.le_bot ⟨hx, fun y hy ↦ ?_⟩ - specialize b₁ ⟨y, hy⟩ - simp_rw [domRestrict₁₂_apply] at b₁ - exact hB.eq_zero b₁ - end CommRing section IsOrthoᵢ diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Orthogonal.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Orthogonal.lean new file mode 100644 index 00000000000000..958634cd279a05 --- /dev/null +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Orthogonal.lean @@ -0,0 +1,140 @@ +/- +Copyright (c) 2022 Moritz Doll. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Moritz Doll, Christopher Hoskin +-/ +module + +public import Mathlib.LinearAlgebra.SesquilinearForm.Basic + +import Mathlib.Algebra.Module.Torsion.Field + +/-! +# Orthogonal complement + +This file defines the orthogonal submodule of a submodule with respect to a sesqui-blinear map. + +## Main declarations + +* `orthogonalBilin` provides the orthogonal complement with respect to a sesqui-bilinear map +-/ + +@[expose] public section + +open Module LinearMap + +variable {R R₁ R₂ M M₁ M₂ : Type*} + +namespace Submodule + +/-! ### The orthogonal complement -/ + +variable [CommSemiring R] [CommSemiring R₁] [CommSemiring R₂] +variable [AddCommMonoid M] [Module R M] +variable [AddCommMonoid M₁] [Module R₁ M₁] +variable [AddCommMonoid M₂] [Module R₂ M₂] +variable {I₁ : R₁ →+* R} {I₂ : R₂ →+* R} +variable {B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M} +variable {S T : Submodule R₁ M₁} + +variable (B S) in +/-- The orthogonal complement of a submodule `N` with respect to some bilinear map is the set of +elements `x` which are orthogonal to all elements of `N`; i.e., for all `y` in `N`, `B x y = 0`. + +Note that for general (neither symmetric nor antisymmetric) bilinear maps this definition has a +chirality; in addition to this "left" orthogonal complement one could define a "right" orthogonal +complement for which, for all `y` in `N`, `B y x = 0`. This variant definition is not currently +provided in mathlib. -/ +def orthogonalBilin : Submodule R₂ M₂ where + carrier := {y | ∀ x ∈ S, B x y = 0} + zero_mem' := by simp + add_mem' {u v} hu hv x hx := by simp [hu _ hx, hv _ hx] + smul_mem' c y hy x hx := by simp [hy _ hx] + +@[simp] theorem mem_orthogonalBilin_iff {m : M₂} : + m ∈ S.orthogonalBilin B ↔ ∀ n ∈ S, B n m = 0 := .rfl + +@[gcongr] theorem orthogonalBilin_le (h : S ≤ T) : + orthogonalBilin B T ≤ orthogonalBilin B S := fun _ hy _ hx ↦ hy _ (h hx) + +section IsRefl + +variable {I₂ : R₁ →+* R} {B : M₁ →ₛₗ[I₁] M₁ →ₛₗ[I₂] M} + +theorem le_orthogonalBilin_orthogonalBilin (b : B.IsRefl) : + S ≤ (S.orthogonalBilin B).orthogonalBilin B := fun n hn _m hm ↦ b _ _ (hm n hn) + +end IsRefl + +end Submodule + +namespace LinearMap + +section Orthogonal + +variable {K K₁ V V₁ V₂ : Type*} +variable [Field K] [AddCommGroup V] [Module K V] [Field K₁] [AddCommGroup V₁] [Module K₁ V₁] + [AddCommGroup V₂] [Module K V₂] {J : K →+* K} {J₁ : K₁ →+* K} {J₁' : K₁ →+* K} + +-- ↓ This lemma only applies in fields as we require `a * b = 0 → a = 0 ∨ b = 0` +theorem span_singleton_inf_orthogonal_eq_bot (B : V₁ →ₛₗ[J₁] V₁ →ₛₗ[J₁'] V₂) (x : V₁) + (hx : B x x ≠ 0) : (K₁ ∙ x) ⊓ (K₁ ∙ x).orthogonalBilin B = ⊥ := by + rw [← Finset.coe_singleton] + refine eq_bot_iff.2 fun y h ↦ ?_ + obtain ⟨μ, -, rfl⟩ := Submodule.mem_span_finset.1 h.1 + replace h := h.2 x (by simp [Submodule.mem_span] : x ∈ Submodule.span K₁ ({x} : Finset V₁)) + rw [Finset.sum_singleton] at h ⊢ + suffices hμzero : μ x = 0 by rw [hμzero, zero_smul, Submodule.mem_bot] + rw [map_smulₛₗ] at h + exact Or.elim (smul_eq_zero.mp h) + (fun y ↦ by simpa using y) + (fun hfalse ↦ False.elim <| hx hfalse) + +-- ↓ This lemma only applies in fields since we use the `mul_eq_zero` +theorem orthogonal_span_singleton_eq_to_lin_ker {B : V →ₗ[K] V →ₛₗ[J] V₂} (x : V) : + (K ∙ x).orthogonalBilin B = LinearMap.ker (B x) := by + ext y + simp_rw [Submodule.mem_orthogonalBilin_iff, LinearMap.mem_ker, Submodule.mem_span_singleton] + constructor + · exact fun h ↦ h x ⟨1, one_smul _ _⟩ + · rintro h _ ⟨z, rfl⟩ + rw [map_smulₛₗ₂, smul_eq_zero] + exact Or.intro_right _ h + +-- todo: Generalize this to sesquilinear maps +theorem span_singleton_sup_orthogonal_eq_top {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : B x x ≠ 0) : + (K ∙ x) ⊔ (K ∙ x).orthogonalBilin B = ⊤ := by + rw [orthogonal_span_singleton_eq_to_lin_ker] + exact (B x).span_singleton_sup_ker_eq_top hx + +-- todo: Generalize this to sesquilinear maps +/-- Given a bilinear form `B` and some `x` such that `B x x ≠ 0`, the span of the singleton of `x` + is complement to its orthogonal complement. -/ +theorem isCompl_span_singleton_orthogonal {B : V →ₗ[K] V →ₗ[K] K} {x : V} (hx : B x x ≠ 0) : + IsCompl (K ∙ x) ((K ∙ x).orthogonalBilin B) := + { disjoint := disjoint_iff.2 <| span_singleton_inf_orthogonal_eq_bot B x hx + codisjoint := codisjoint_iff.2 <| span_singleton_sup_orthogonal_eq_top hx } + +end Orthogonal + +section CommRing + +variable [CommRing R] [AddCommGroup M] [Module R M] [AddCommGroup M₁] [Module R M₁] {I I' : R →+* R} + +/-- The restriction of a reflexive bilinear map `B` onto a submodule `W` is +nondegenerate if `W` has trivial intersection with its orthogonal complement, +that is `Disjoint W (W.orthogonalBilin B)`. -/ +theorem nondegenerate_restrict_of_disjoint_orthogonal {B : M →ₗ[R] M →ₗ[R] M₁} (hB : B.IsRefl) + {W : Submodule R M} (hW : Disjoint W (W.orthogonalBilin B)) : + (B.domRestrict₁₂ W W).Nondegenerate := by + rw [(hB.domRestrict W).nondegenerate_iff_separatingLeft] + rintro ⟨x, hx⟩ b₁ + rw [Submodule.mk_eq_zero, ← Submodule.mem_bot R] + refine hW.le_bot ⟨hx, fun y hy ↦ ?_⟩ + specialize b₁ ⟨y, hy⟩ + simp_rw [domRestrict₁₂_apply] at b₁ + exact hB.eq_zero b₁ + +end CommRing + +end LinearMap From d0c53be53a14413fd6ace433b17beecd7acfc243 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Mon, 29 Jun 2026 22:19:07 +0000 Subject: [PATCH 0429/1300] feat(NumberTheory/NumberField/Discriminant): add `not_dvd_discr_iff_isUnramifiedIn` (#40951) A prime `p` does not divide `discr K` if and only if `p` is unramified in the ring of integers, phrased using the `Algebra.IsUnramifiedIn` predicate. This complements the existing `not_dvd_discr_iff_forall_liesOver` and `not_dvd_discr_iff_forall_mem`. --- .../NumberField/Discriminant/Different.lean | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean index ae67c5f9b4a1d0..1c68503bdc453f 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean @@ -193,6 +193,20 @@ lemma not_dvd_discr_iff_forall_liesOver [IsIntegralClosure 𝒪 ℤ K] {p : ℤ} ← Int.natAbs_pow, Int.natAbs_dvd_natAbs] at this exact (dvd_pow_self _ (Ideal.inertiaDeg_pos' ..).ne').trans this +/-- A prime `p` does not divide `discr K` if and only if `p` (as the ideal `span {p}`) is +unramified in the ring of integers `𝒪`. + +Also see `not_dvd_discr_iff_forall_liesOver` and `not_dvd_discr_iff_forall_mem` for variants +whose RHS does not use `Algebra.IsUnramifiedIn`. -/ +lemma not_dvd_discr_iff_isUnramifiedIn [IsIntegralClosure 𝒪 ℤ K] {p : ℤ} (hp : Prime p) : + ¬ p ∣ discr K ↔ Algebra.IsUnramifiedIn 𝒪 (Ideal.span {p}) := by + have := (IsIntegralClosure.algebraMap_injective 𝒪 ℤ K).isDomain + have := IsIntegralClosure.isDedekindDomain ℤ ℚ K 𝒪 + have := CharZero.of_module (R := 𝒪) K + rw [not_dvd_discr_iff_forall_liesOver K 𝒪 hp] + exact (Algebra.isUnramifiedIn_iff_forall_of_isDedekindDomain' + (Ideal.span_singleton_eq_bot.not.mpr hp.ne_zero)).symm + /-- Also see `not_dvd_discr_iff_forall_liesOver` for a slightly easier to prove RHS. -/ lemma not_dvd_discr_iff_forall_mem [IsIntegralClosure 𝒪 ℤ K] {p : ℤ} (hp : Prime p) : ¬ p ∣ discr K ↔ ∀ (P : Ideal 𝒪) (_ : P.IsPrime), ↑p ∈ P → From cb4d969bd780de9e4f2b32e303ad4cb45108747a Mon Sep 17 00:00:00 2001 From: Adam Topaz <5577687+adamtopaz@users.noreply.github.com> Date: Mon, 29 Jun 2026 22:55:20 +0000 Subject: [PATCH 0430/1300] feat(LinearAlgebra): fill two proof_wanted declarations (#39046) ... and generalize `AlgHom.bijective` and move to earlier file. Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/LinearAlgebra/Determinant.lean | 10 ++++++---- Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean | 4 ++++ Mathlib/LinearAlgebra/Trace.lean | 10 ++++++---- Mathlib/RingTheory/Algebraic/Integral.lean | 3 --- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 9253e784a05321..8390d28ac03e97 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -17,6 +17,7 @@ public import Mathlib.RingTheory.Finiteness.Cardinality public import Mathlib.Tactic.FieldSimp import Mathlib.LinearAlgebra.GeneralLinearGroup.AlgEquiv +import Mathlib.RingTheory.SimpleRing.Matrix /-! # Determinant of families of vectors @@ -474,11 +475,12 @@ end LinearEquiv LinearMap.det_map ((Matrix.toLinAlgEquiv'.symm.trans (AlgEquivClass.toAlgEquiv f)).trans Matrix.toLinAlgEquiv') x.toLin' --- TODO: show `(f x).det = x.det` for when `f : Matrix m m K →ₐ[K] Matrix m m K` --- (using Skolem-Noether) -proof_wanted Matrix.det_map' {K m F : Type*} [Field K] [Fintype m] [DecidableEq m] +@[simp] theorem Matrix.det_map' {K m F : Type*} [Field K] [Fintype m] [DecidableEq m] [FunLike F (Matrix m m K) (Matrix m m K)] [AlgHomClass F K _ _] (f : F) (x : Matrix m m K) : - (f x).det = x.det + (f x).det = x.det := by + by_cases! Nonempty m + · exact det_map (AlgEquiv.ofBijective _ (AlgHomClass.toAlgHom f).bijective) x + · simp /-- The determinants of a `LinearEquiv` and its inverse multiply to 1. -/ @[simp] diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index ee2d03392f3e52..ce0aff98a36521 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -666,3 +666,7 @@ theorem ker_pow_constant {f : End K V} {k : ℕ} end End end Module + +theorem AlgHom.bijective {K S : Type*} [Field K] [Ring S] [IsSimpleRing S] + [Algebra K S] [FiniteDimensional K S] (f : S →ₐ[K] S) : Function.Bijective f := + ⟨f.toRingHom.injective, f.toLinearMap.injective_iff_surjective.mp f.toRingHom.injective⟩ diff --git a/Mathlib/LinearAlgebra/Trace.lean b/Mathlib/LinearAlgebra/Trace.lean index ee5b930430840d..7eaacb4b1b6dc9 100644 --- a/Mathlib/LinearAlgebra/Trace.lean +++ b/Mathlib/LinearAlgebra/Trace.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.TensorProduct.Finite public import Mathlib.RingTheory.TensorProduct.Free import Mathlib.LinearAlgebra.GeneralLinearGroup.AlgEquiv +import Mathlib.RingTheory.SimpleRing.Matrix /-! # Trace of a linear map @@ -325,11 +326,12 @@ theorem trace_conj' (f : M →ₗ[R] M) (e : M ≃ₗ[R] N) : trace R N (e.conj LinearMap.trace_map ((Matrix.toLinAlgEquiv'.symm.trans (AlgEquivClass.toAlgEquiv f)).trans Matrix.toLinAlgEquiv') x.toLin' --- TODO: show `(f x).trace = x.trace` for when `f : Matrix m m K →ₐ[K] Matrix m m K` --- (using Skolem-Noether) -proof_wanted _root_.Matrix.trace_map' {K m F : Type*} [Field K] [Fintype m] [DecidableEq m] +@[simp] theorem _root_.Matrix.trace_map' {K m F : Type*} [Field K] [Fintype m] [DecidableEq m] [FunLike F (Matrix m m K) (Matrix m m K)] [AlgHomClass F K _ _] (f : F) (x : Matrix m m K) : - (f x).trace = x.trace + (f x).trace = x.trace := by + by_cases! Nonempty m + · exact Matrix.trace_map (AlgEquiv.ofBijective _ (AlgHomClass.toAlgHom f).bijective) x + · simp theorem IsProj.trace {p : Submodule R M} {f : M →ₗ[R] M} (h : IsProj p f) [Module.Free R p] [Module.Finite R p] [Module.Free R (ker f)] [Module.Finite R (ker f)] : diff --git a/Mathlib/RingTheory/Algebraic/Integral.lean b/Mathlib/RingTheory/Algebraic/Integral.lean index 7cf576e5fdc5b7..7d74915b28c242 100644 --- a/Mathlib/RingTheory/Algebraic/Integral.lean +++ b/Mathlib/RingTheory/Algebraic/Integral.lean @@ -129,9 +129,6 @@ theorem transcendental_aeval_iff {r : A} {f : K[X]} : variable [Field L] [Algebra K L] -theorem AlgHom.bijective [FiniteDimensional K L] (ϕ : L →ₐ[K] L) : Function.Bijective ϕ := - (Algebra.IsAlgebraic.of_finite K L).algHom_bijective ϕ - variable (K L) in /-- Bijection between algebra equivalences and algebra homomorphisms -/ noncomputable abbrev algEquivEquivAlgHom [FiniteDimensional K L] : From 0ba66b4719c09029159d54107d1db4d4a91ed7dd Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:19:41 +0000 Subject: [PATCH 0431/1300] chore(RingTheory/Localization/Ideal): add `liesOver_map_of_isPrime_disjoint` (#40779) This PR adds `liesOver_map_of_isPrime_disjoint`, a restatement of `under_map_of_isPrime_disjoint` that already "exists in the wild". Co-authored-by: tb65536 --- Mathlib/RingTheory/Etale/QuasiFinite.lean | 6 +++--- Mathlib/RingTheory/Localization/Ideal.lean | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/Etale/QuasiFinite.lean b/Mathlib/RingTheory/Etale/QuasiFinite.lean index b9b01203bd9345..58240404b83dde 100644 --- a/Mathlib/RingTheory/Etale/QuasiFinite.lean +++ b/Mathlib/RingTheory/Etale/QuasiFinite.lean @@ -394,8 +394,8 @@ lemma Algebra.exists_etale_isIdempotentElem_forall_liesOver_eq let Pf := P.map (algebraMap _ (Localization.Away f)) have : Pf.IsPrime := IsLocalization.isPrime_of_isPrime_disjoint (.powers f) _ _ ‹_› (by rwa [Ideal.disjoint_powers_iff_notMem_of_isPrime]) - have : Pf.LiesOver P := ⟨(IsLocalization.under_map_of_isPrime_disjoint (.powers f) _ ‹_› (by - rwa [Ideal.disjoint_powers_iff_notMem _ (Ideal.IsPrime.isRadical ‹_›)])).symm⟩ + have : Pf.LiesOver P := IsLocalization.liesOver_map_of_isPrime_disjoint (.powers f) _ (by + rwa [Ideal.disjoint_powers_iff_notMem _ (Ideal.IsPrime.isRadical ‹_›)]) let φ : R' ⊗[R] S →ₐ[R'] Localization.Away f ⊗[R] S := Algebra.TensorProduct.map (Algebra.ofId _ _) (.id _ _) let := φ.toAlgebra @@ -411,7 +411,7 @@ lemma Algebra.exists_etale_isIdempotentElem_forall_liesOver_eq change f ∉ P'.under _ rwa [← P'.over_def P] have : P'f.IsPrime := IsLocalization.isPrime_of_isPrime_disjoint _ _ _ ‹_› hP'f - have : P'f.LiesOver P' := ⟨(IsLocalization.under_map_of_isPrime_disjoint _ _ ‹_› hP'f).symm⟩ + have : P'f.LiesOver P' := IsLocalization.liesOver_map_of_isPrime_disjoint _ _ hP'f have : P'f.LiesOver P := .trans _ P' _ have : P'f.LiesOver Pf := ⟨congr($(PrimeSpectrum.localization_comap_injective (Localization.Away f) (.powers f) (a₁ := ⟨Pf, ‹_›⟩) diff --git a/Mathlib/RingTheory/Localization/Ideal.lean b/Mathlib/RingTheory/Localization/Ideal.lean index f2cb0211365cf5..35ae3cd89208ca 100644 --- a/Mathlib/RingTheory/Localization/Ideal.lean +++ b/Mathlib/RingTheory/Localization/Ideal.lean @@ -169,6 +169,10 @@ theorem under_map_of_isPrime_disjoint {I : Ideal R} (hI : I.IsPrime) (hM : Disjo @[deprecated (since := "2026-04-09")] alias comap_map_of_isPrime_disjoint := under_map_of_isPrime_disjoint +theorem liesOver_map_of_isPrime_disjoint {I : Ideal R} [I.IsPrime] (hM : Disjoint (M : Set R) I) : + (I.map (algebraMap R S)).LiesOver I := + ⟨(under_map_of_isPrime_disjoint M S ‹_› hM).symm⟩ + /-- If `S` is the localization of `R` at a submonoid, the ordering of ideals of `S` is embedded in the ordering of ideals of `R`. -/ def orderEmbedding : Ideal S ↪o Ideal R where From 8406f7ab1f0fd5eb9280b94678dd32c5ce250db0 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:19:43 +0000 Subject: [PATCH 0432/1300] chore(RingTheory/Ideal/Norm/RelNorm): switch over to new definitions of `ramificationIdx` and `inertiaDeg` (#41077) This PR switches the file `RingTheory/Ideal/Norm/RelNorm.lean` over to the new definitions of `ramificationIdx` and `inertiaDeg`. Co-authored-by: tb65536 --- .../DedekindDomain/Factorization.lean | 8 +++--- Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 22 +++++++--------- .../RamificationInertia/Ramification.lean | 26 ++++++++++++++----- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index b64b302700dde9..5faa374f16acf2 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -5,7 +5,7 @@ Authors: María Inés de Frutos-Fernández -/ module -public import Mathlib.NumberTheory.RamificationInertia.Basic +public import Mathlib.RingTheory.RamificationInertia.Basic public import Mathlib.Order.Filter.Cofinite public import Mathlib.RingTheory.UniqueFactorizationDomain.Finsupp @@ -819,7 +819,7 @@ If `p` is a maximal ideal, then the lift of `p` in an extension is the product o over `p` to the power the ramification index. -/ theorem Ideal.map_algebraMap_eq_finsetProd_pow {p : Ideal S} [p.IsMaximal] (hp : p ≠ 0) : - map (algebraMap S R) p = ∏ P ∈ p.primesOver R, P ^ p.ramificationIdx P := by + map (algebraMap S R) p = ∏ P ∈ p.primesOver R, P ^ P.ramificationIdx' S := by classical have h : map (algebraMap S R) p ≠ 0 := map_ne_bot_of_ne_bot hp rw [← finprod_heightOneSpectrum_factorization (I := p.map (algebraMap S R)) h] @@ -830,8 +830,8 @@ theorem Ideal.map_algebraMap_eq_finsetProd_pow {p : Ideal S} [p.IsMaximal] (hp : ← Finset.prod_set_coe] · let _ : Fintype {v : HeightOneSpectrum R // v.asIdeal ∣ map (algebraMap S R) p} := hF refine Fintype.prod_equiv (equivPrimesOver _ hp) _ _ fun ⟨v, _⟩ ↦ ?_ - simp [maxPowDividing_eq_pow_multiset_count _ h, - ramificationIdx_eq_factors_count h v.isPrime v.ne_bot] + have : v.asIdeal.LiesOver p := by rwa [Ideal.liesOver_iff_dvd_map v.2.ne_top] + simp [maxPowDividing_eq_pow_multiset_count _ h, ramificationIdx'_eq_factors_count p v h] · intro v hv simpa [maxPowDividing, Function.mem_mulSupport, IsPrime.ne_top _, Associates.count_ne_zero_iff_dvd h (irreducible v)] using hv diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index 86337c0e1acc2c..4998fe11081a7d 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -398,27 +398,26 @@ See `Ideal.relNorm_eq_pow_of_isMaximal` for a statement that does not require th be Galois. -/ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] - [IsGalois (FractionRing R) (FractionRing S)] : relNorm R P = p ^ p.inertiaDeg P := by + [IsGalois (FractionRing R) (FractionRing S)] : relNorm R P = p ^ P.inertiaDeg' R := by have : P.IsMaximal := IsMaximal.of_liesOver_isMaximal P p let G := Gal(FractionRing S/FractionRing R) let := IsIntegralClosure.MulSemiringAction R (FractionRing R) (FractionRing S) S have := IsGaloisGroup.of_isFractionRing G R S (FractionRing R) (FractionRing S) by_cases hp : p = ⊥ - · have h : p.inertiaDeg P ≠ 0 := Nat.ne_zero_iff_zero_lt.mpr <| inertiaDeg_pos p P + · have h : P.inertiaDeg' R ≠ 0 := (inertiaDeg'_pos P R).ne' have hP : P = ⊥ := by rw [hp] at hPp exact eq_bot_of_liesOver_bot R P rw [hp, hP, relNorm_bot, bot_pow] - rwa [hp, hP] at h + rwa [hP] at h obtain ⟨s, hs⟩ := exists_relNorm_eq_pow_of_isPrime P p - suffices s = p.inertiaDeg P by rwa [this] at hs + suffices s = P.inertiaDeg' R by rwa [this] at hs have h₀ : ∀ Q ∈ (p.primesOver S).toFinset, - relNorm R Q ^ ramificationIdx p Q = p ^ ((p.ramificationIdxIn S) * s) := by + relNorm R Q ^ Q.ramificationIdx' R = p ^ ((p.ramificationIdxIn S) * s) := by intro Q hQ rw [Set.mem_toFinset] at hQ have : Q.IsPrime := hQ.1 have : Q.LiesOver p := hQ.2 - rw [ramificationIdx_eq_ramificationIdx' p Q hp] rw [← ramificationIdxIn_eq_ramificationIdx p Q G] obtain ⟨σ, rfl⟩ := Ideal.exists_smul_eq_of_isGaloisGroup p P Q G rw [relNorm_smul, hs, ← pow_mul, mul_comm] @@ -430,13 +429,12 @@ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] ← Set.ncard_eq_toFinset_card', ((IsLeftCancelMulZero.mul_left_cancel_of_ne_zero hp).pow_injective _).eq_iff, mul_right_inj' (IsDedekindDomain.primesOver_ncard_ne_zero p S), - mul_right_inj' (ramificationIdxIn_ne_zero G), - inertiaDegIn_eq_inertiaDeg p P G, ← inertiaDeg_eq_inertiaDeg' p P] at h + mul_right_inj' (ramificationIdxIn_ne_zero G), inertiaDegIn_eq_inertiaDeg p P G] at h rw [one_eq_top] exact IsMaximal.ne_top inferInstance theorem relNorm_eq_pow_of_isMaximal [PerfectField (FractionRing R)] [P.IsMaximal] [p.IsMaximal] : - relNorm R P = p ^ p.inertiaDeg P := by + relNorm R P = p ^ P.inertiaDeg' R := by let T := Ring.NormalClosure R S obtain ⟨Q, hQ₁, hQ₂⟩ : ∃ Q : Ideal T, Q.IsMaximal ∧ Q.LiesOver P := exists_maximal_ideal_liesOver_of_isIntegral P @@ -445,8 +443,7 @@ theorem relNorm_eq_pow_of_isMaximal [PerfectField (FractionRing R)] [P.IsMaximal have : IsGalois (FractionRing S) (FractionRing T) := IsGalois.tower_top_of_isGalois (FractionRing R) (FractionRing S) (FractionRing T) rwa [← relNorm_relNorm R S, relNorm_eq_pow_of_isPrime_isGalois Q P, map_pow, - inertiaDeg_algebra_tower p P Q, pow_mul, pow_left_inj] at h - exact Nat.ne_zero_iff_zero_lt.mpr <| inertiaDeg_pos P Q + inertiaDeg'_tower (R := R) P Q, pow_mul, pow_left_inj (inertiaDeg'_pos Q S).ne'] at h end relNorm_prime @@ -477,7 +474,8 @@ theorem absNorm_relNorm [PerfectField (FractionRing R)] (I : Ideal S) : have : Fact (p.Prime) := ⟨Nat.absNorm_under_prime _⟩ have hp : Prime (p : ℤ) := Nat.prime_iff_prime_int.mp <| Nat.absNorm_under_prime _ rw [relNorm_eq_pow_of_isMaximal Q P, map_pow, absNorm_eq_pow_inertiaDeg Q hp, - absNorm_eq_pow_inertiaDeg P hp, inertiaDeg_algebra_tower (span {(p : ℤ)}) P Q, pow_mul] + absNorm_eq_pow_inertiaDeg P hp, inertiaDeg_algebra_tower (span {(p : ℤ)}) P Q, pow_mul, + ← inertiaDeg_eq_inertiaDeg' P] theorem relNorm_int (I : Ideal S) : relNorm ℤ I = Ideal.span {(absNorm I : ℤ)} := by diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index 87cdea6fc27042..d5c5087ee3342a 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -122,14 +122,11 @@ theorem ramificationIdx'_eq [q.LiesOver p] [q.IsPrime] : rw [ramificationIdx'_def, over_def q p] open Localization IsLocalization.AtPrime in -theorem ramificationIdx_eq_ramificationIdx' - [IsDomain R] [IsDedekindDomain S] [Module.IsTorsionFree R S] - [q.LiesOver p] [hq : q.IsPrime] (hp : p ≠ ⊥) : +theorem ramificationIdx_eq_ramificationIdx'' [IsDedekindDomain S] + [q.LiesOver p] [hq : q.IsPrime] (hpS : p.map (algebraMap R S) ≠ ⊥) : p.ramificationIdx q = q.ramificationIdx' R := by - have : p.IsPrime := isPrime_of_liesOver q p - have hq' : q ≠ ⊥ := ne_bot_of_liesOver_of_ne_bot hp q + have hq' : q ≠ ⊥ := ne_bot_of_le_ne_bot hpS (map_le_of_le_comap (q.over_def p).le) have : q.IsMaximal := hq.isMaximal hq' - have hpS : p.map (algebraMap R S) ≠ ⊥ := map_ne_bot_of_ne_bot hp obtain ⟨I, hqI, h⟩ := Ideal.eq_prime_pow_mul_coprime hpS q replace hqI : ¬ I ≤ q := by contrapose! hqI @@ -142,6 +139,23 @@ theorem ramificationIdx_eq_ramificationIdx' have hSq := isDiscreteValuationRing_of_dedekind_domain S hq' (Localization.AtPrime q) rw [ramificationIdx'_eq p q, h, hSq.length_quotient_pow_maximalIdeal, ENat.toNat_coe] +theorem ramificationIdx_eq_ramificationIdx' [IsDomain R] [IsDedekindDomain S] + [Module.IsTorsionFree R S] [q.LiesOver p] [hq : q.IsPrime] (hp : p ≠ ⊥) : + p.ramificationIdx q = q.ramificationIdx' R := by + have hpS : p.map (algebraMap R S) ≠ ⊥ := map_ne_bot_of_ne_bot hp + exact ramificationIdx_eq_ramificationIdx'' p q hpS + +open UniqueFactorizationMonoid in +theorem IsDedekindDomain.ramificationIdx'_eq_factors_count [IsDedekindDomain S] + [q.LiesOver p] (hp0 : p.map (algebraMap R S) ≠ ⊥) : + q.ramificationIdx' R = (factors (p.map (algebraMap R S))).count q := by + by_cases hq : q.IsPrime; swap + · rw [ramificationIdx'_of_not_isPrime q R hq, eq_comm, Multiset.count_eq_zero] + contrapose! hq + exact isPrime_of_prime (prime_of_factor q hq) + have hq0 : q ≠ ⊥ := ne_bot_of_le_ne_bot hp0 (map_le_of_le_comap (q.over_def p).le) + rw [← ramificationIdx_eq_ramificationIdx'' p q hp0, ramificationIdx_eq_factors_count hp0 ‹_› hq0] + /-- See `ramificationIdx'_tower` for a version that does not assume primality. -/ theorem ramificationIdx'_tower' [q.IsPrime] [r.IsPrime] [r.LiesOver q] [Algebra (Localization.AtPrime q) (Localization.AtPrime r)] From 01749d4fe32e56ef026abea2c864b3552d27110f Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:19:45 +0000 Subject: [PATCH 0433/1300] chore(Algebra/Category/Sheaf): remove superfluous `HasSheafCompose` assumptions (#41152) Since #41151, we have that the forgetful functor from `RingCat` to `AddCommGrpCat` has a left-adjoint, so it preserves limits of arbitrary size. This implies that `HasSheafCompose` is now automatic for this functor. --- Mathlib/Algebra/Category/ModuleCat/Sheaf.lean | 3 +-- .../Category/ModuleCat/Sheaf/Free.lean | 2 -- .../Category/ModuleCat/Sheaf/Generators.lean | 6 +---- .../Category/ModuleCat/Sheaf/LocallyFree.lean | 10 +++------ .../ModuleCat/Sheaf/PullbackFree.lean | 3 --- .../Sheaf/PushforwardContinuous.lean | 4 +--- .../ModuleCat/Sheaf/Quasicoherent.lean | 22 +++++-------------- 7 files changed, 12 insertions(+), 38 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf.lean index 68e4a7101d9812..e61222033fe2d3 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf.lean @@ -5,6 +5,7 @@ Authors: Joël Riou -/ module +public import Mathlib.Algebra.Category.AlgCat.TensorAlgebra public import Mathlib.Algebra.Category.ModuleCat.Presheaf public import Mathlib.Algebra.Category.ModuleCat.Limits public import Mathlib.CategoryTheory.Sites.LocallyBijective @@ -166,8 +167,6 @@ def sectionsFunctor : SheafOfModules.{v} R ⥤ Type _ where obj M := M.sections map f := ↾(sectionsMap f) -variable [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - variable (R) in /-- The obvious free sheaf of modules of rank `1`. -/ @[simps] diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean index b19bc3ec15312c..4f00bd861e4819 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean @@ -32,7 +32,6 @@ open CategoryTheory Limits variable {C : Type u₁} [Category.{v₁} C] {J : GrothendieckTopology C} {R : Sheaf J RingCat.{u}} [HasWeakSheafify J AddCommGrpCat.{u}] [J.WEqualsLocallyBijective AddCommGrpCat.{u}] - [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] namespace SheafOfModules @@ -175,7 +174,6 @@ section variable {C' : Type u₂} [Category.{v₂} C'] {J' : GrothendieckTopology C'} {S : Sheaf J' RingCat.{u}} [HasSheafify J' AddCommGrpCat.{u}] [J'.WEqualsLocallyBijective AddCommGrpCat.{u}] - [J'.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] (F : SheafOfModules.{u} R ⥤ SheafOfModules.{u} S) (I : Type u) /-- Let `F` be a functor from the category of sheaves of `R`-modules to sheaves of `S`-modules. diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Generators.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Generators.lean index 4c736dd68e9cc4..6b6e2d92053be6 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Generators.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Generators.lean @@ -35,7 +35,6 @@ open CategoryTheory Limits variable {C : Type u'} [Category.{v'} C] {J : GrothendieckTopology C} {R : Sheaf J RingCat.{u}} [HasWeakSheafify J AddCommGrpCat.{u}] [J.WEqualsLocallyBijective AddCommGrpCat.{u}] - [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] namespace SheafOfModules @@ -108,7 +107,6 @@ section variable [∀ (X : C), HasWeakSheafify (J.over X) AddCommGrpCat.{u}] [∀ (X : C), (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] - [∀ (X : C), (J.over X).HasSheafCompose (forget₂ RingCat AddCommGrpCat.{u})] /-- The data of generating sections of the restriction of a sheaf of modules over a covering of the terminal object. -/ @@ -151,7 +149,6 @@ noncomputable section variable {C' : Type u₁} [Category.{v₁} C'] {J' : GrothendieckTopology C'} {S : Sheaf J' RingCat.{u}} [HasSheafify J' AddCommGrpCat] [J'.WEqualsLocallyBijective AddCommGrpCat] - [J'.HasSheafCompose (forget₂ RingCat AddCommGrpCat)] variable {M : SheafOfModules.{u} R} (G : M.GeneratingSections) (F : SheafOfModules.{u} R ⥤ SheafOfModules.{u} S) [PreservesColimitsOfSize.{u, u} F] @@ -189,8 +186,7 @@ instance [IsIso G.π] : IsIso (G.map F η).π := by rw [GeneratingSections.map_π_eq] infer_instance -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] [HasBinaryProducts C] +variable [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] [HasBinaryProducts C] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] /-- Given `G : M.GeneratingSections`, we naturally obtain `M.LocalGeneratorsData` using the diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/LocallyFree.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/LocallyFree.lean index 8a538d40092774..c157a2ada79219 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/LocallyFree.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/LocallyFree.lean @@ -37,8 +37,7 @@ namespace SheafOfModules section -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ X, HasWeakSheafify (J.over X) AddCommGrpCat.{u}] +variable [∀ X, HasWeakSheafify (J.over X) AddCommGrpCat.{u}] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] namespace LocalGeneratorsData @@ -70,7 +69,6 @@ end section variable [HasWeakSheafify J AddCommGrpCat.{u}] [J.WEqualsLocallyBijective AddCommGrpCat.{u}] - [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] /-- The generating sections of the free sheaf of modules. -/ @[expose, simps] @@ -91,8 +89,7 @@ instance (I : Type u) : IsIso (free.generatingSections (R := R) I).π := by rw [free.generatingSections_π] infer_instance -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] [HasBinaryProducts C] +variable [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] [HasBinaryProducts C] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] [HasSheafify J AddCommGrpCat] set_option backward.defeqAttrib.useBackward true in @@ -110,8 +107,7 @@ end section -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] +variable [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] namespace LocalGeneratorsData diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean index 763ff98768043c..abdf63e2098e0f 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean @@ -55,9 +55,6 @@ lemma bijective_pushforwardSections [F.Final] : Function.Bijective (pushforwardSections φ (M := M)) := Functor.bijective_sectionsPrecomp _ _ -variable [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [K.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - /-- The canonical morphism `unit S ⟶ (pushforward.{u} φ).obj (unit R)` of sheaves of modules corresponding to a continuous map between ringed sites. -/ noncomputable def unitToPushforwardObjUnit : unit S ⟶ (pushforward.{u} φ).obj (unit R) where diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean index 6ff62bcb90c789..e0d9552472687d 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean @@ -88,9 +88,7 @@ noncomputable def overFunctorMap {X Y : D} (f : X ⟶ Y) : /-- The pushforward of `R.over Y` along `Over.map f` is isomorphic to `R.over X`. -/ @[simps! +dsimpLhs] -noncomputable def overMapUnitIso {X Y : D} - [(K.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [(K.over Y).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] (f : X ⟶ Y) : +noncomputable def overMapUnitIso {X Y : D} (f : X ⟶ Y) : (overMap.{u} R f).obj (.unit (R.over Y)) ≅ .unit (R.over X) := Iso.refl _ diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean index db68ba2f1ee0af..cecd0a5950edee 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean @@ -36,7 +36,6 @@ namespace SheafOfModules section variable [HasWeakSheafify J AddCommGrpCat.{u}] [J.WEqualsLocallyBijective AddCommGrpCat.{u}] - [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] /-- A global presentation of a sheaf of modules `M` consists of a family `generators.s` of sections `s` which generate `M`, and a family of sections which generate @@ -66,7 +65,7 @@ noncomputable section variable {C : Type u₁} [Category.{v₁} C] {J : GrothendieckTopology C} {R : Sheaf J RingCat.{u}} [HasSheafify J AddCommGrpCat] [J.WEqualsLocallyBijective AddCommGrpCat] - [J.HasSheafCompose (forget₂ RingCat AddCommGrpCat)] {ι σ : Type u} + {ι σ : Type u} /-- Given two morphisms of sheaves of `R`-modules `f : free ι ⟶ free σ` and `g : free σ ⟶ M` satisfying `H : f ≫ g = 0` and `IsColimit (CokernelCofork.ofπ g H)`, we obtain @@ -144,7 +143,6 @@ instance {M N : SheafOfModules.{u} R} (f : M ⟶ N) [IsIso f] variable {C' : Type u₂} [Category.{v₂} C'] {J' : GrothendieckTopology C'} {S : Sheaf J' RingCat.{u}} [HasSheafify J' AddCommGrpCat] [J'.WEqualsLocallyBijective AddCommGrpCat] - [J'.HasSheafCompose (forget₂ RingCat AddCommGrpCat)] variable {M : SheafOfModules.{u} R} (P : Presentation M) (F : SheafOfModules.{u} R ⥤ SheafOfModules.{u} S) [PreservesColimitsOfSize.{u, u} F] @@ -194,8 +192,7 @@ end section -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ X, HasWeakSheafify (J.over X) AddCommGrpCat.{u}] +variable [∀ X, HasWeakSheafify (J.over X) AddCommGrpCat.{u}] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] /-- This structure contains the data of a family of objects `X i` which cover @@ -289,11 +286,8 @@ section map variable {D : Type u₂} [Category.{v₂, u₂} D] {K : GrothendieckTopology D} {S : Sheaf K RingCat.{u}} [∀ (X : D), (K.over X).WEqualsLocallyBijective AddCommGrpCat] - [∀ (X : D), (K.over X).HasSheafCompose (forget₂ RingCat AddCommGrpCat)] -variable [J.HasSheafCompose (forget₂ RingCat AddCommGrpCat)] - [K.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ (X : C), HasSheafify (J.over X) AddCommGrpCat.{u}] +variable [∀ (X : C), HasSheafify (J.over X) AddCommGrpCat.{u}] [∀ (X : D), HasSheafify (K.over X) AddCommGrpCat.{u}] variable (G : D ⥤ C) [G.IsContinuous K J] [G.IsCocontinuous K J] @@ -368,10 +362,8 @@ open CategoryTheory Limits variable {C : Type u₁} [Category.{v₁} C] [HasBinaryProducts C] {J : GrothendieckTopology C} {R : Sheaf J RingCat.{u}} [HasSheafify J AddCommGrpCat] [J.WEqualsLocallyBijective AddCommGrpCat] - [J.HasSheafCompose (forget₂ RingCat AddCommGrpCat)] -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat AddCommGrpCat)] - [∀ X, HasSheafify (J.over X) AddCommGrpCat] +variable [∀ X, HasSheafify (J.over X) AddCommGrpCat] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat] /-- Given a sheaf of `R`-modules `M` and a `Presentation M`, we may construct the quasi-coherent @@ -422,10 +414,8 @@ end section bind -variable [∀ X, (J.over X).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] - [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] +variable [∀ X, HasSheafify (J.over X) AddCommGrpCat.{u}] [∀ X, (J.over X).WEqualsLocallyBijective AddCommGrpCat.{u}] - [∀ X Y, ((J.over X).over Y).HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] [∀ X Y, HasSheafify ((J.over X).over Y) AddCommGrpCat.{u}] [∀ X Y, ((J.over X).over Y).WEqualsLocallyBijective AddCommGrpCat.{u}] @@ -454,7 +444,7 @@ lemma IsQuasicoherent.of_coversTop {R : Sheaf J RingCat.{u}} IsQuasicoherent.nonempty_quasicoherentData.some).isQuasicoherent set_option backward.isDefEq.respectTransparency false in -lemma isQuasicoherent_over [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})] +lemma isQuasicoherent_over [HasPullbacks C] [HasBinaryProducts C] (M : SheafOfModules.{u} R) (X : C) [IsQuasicoherent M] : IsQuasicoherent (M.over X) := isQuasicoherent_pushforward_of_isLeftAdjoint _ _ (Iso.refl _) From f6d7788a636b69e98bbf199ae9f4d7ab35fd122b Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 30 Jun 2026 00:07:39 +0000 Subject: [PATCH 0434/1300] chore(CategoryTheory): some API for `FormalCoproducts` (#41126) This is used in the construction of hypercovers. Co-authored by: Robin Carlier --- .../Limits/FormalCoproducts/Basic.lean | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean b/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean index 6e237d4593500a..2c1324ea862275 100644 --- a/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean @@ -240,6 +240,31 @@ lemma fromIncl_comp_cofanPtIsoSelf_inv (i : X.I) : Hom.fromIncl i (𝟙 (X.obj i)) ≫ (coproductIsoSelf X).inv = Sigma.ι X.toFun i := (Iso.comp_inv_eq _).2 (ι_comp_coproductIsoSelf_hom _ _).symm +/-- Given an object `X : FormalCoproduct C` and an equality of indices `i = j`, this is +the induced isomorphism `Xᵢ ≅ Xⱼ`. -/ +def objIsoOfEq (X : FormalCoproduct.{w} C) {i j : X.I} (hij : i = j) : + X.obj i ≅ X.obj j := + eqToIso (by rw [hij]) + +@[simp] +lemma objIsoOfEq_rfl (X : FormalCoproduct.{w} C) (i : X.I) : + X.objIsoOfEq (rfl : i = i) = Iso.refl _ := + rfl + +@[simp] +lemma objIsoOfEq_trans (X : FormalCoproduct.{w} C) {i j k : X.I} + (hij : i = j) (hjk : j = k) : + X.objIsoOfEq hij ≪≫ X.objIsoOfEq hjk = X.objIsoOfEq (hij.trans hjk) := by + subst hij hjk + simp + +@[simp] +lemma objIsoOfEq_symm (X : FormalCoproduct.{w} C) {i j : X.I} + (hij : i = j) : + (X.objIsoOfEq hij).symm = X.objIsoOfEq hij.symm := by + subst hij + simp + end Coproduct section Terminal @@ -375,6 +400,22 @@ instance : PreservesColimit (Discrete.functor f) ((eval.{w} C A).obj F) := instance : PreservesColimitsOfShape (Discrete J) ((eval.{w} C A).obj F) := preservesColimitsOfShape_of_discrete _ +/-- The yoneda embedding of `FormalCoproduct.{v} C` into `v`-presheaves. -/ +protected noncomputable abbrev yoneda : + FormalCoproduct.{v} C ⥤ Cᵒᵖ ⥤ Type v := + (eval _ _).obj yoneda + +/-- The yoneda embedding of `FormalCoproduct.{w} C` into `max w v`-presheaves. -/ +protected noncomputable abbrev uliftYoneda : + FormalCoproduct.{w} C ⥤ Cᵒᵖ ⥤ Type (max w v) := + (eval _ _).obj uliftYoneda + +/-- The yoneda embedding of `FormalCoproduct.{w} C` into `w`-presheaves for a locally +`w`-small category. -/ +protected noncomputable abbrev shrinkYoneda [LocallySmall.{w} C] : + FormalCoproduct.{w} C ⥤ Cᵒᵖ ⥤ Type w := + (eval _ _).obj shrinkYoneda + end HasCoproducts noncomputable section HasProducts From c7369ee587c9dfd4504b25097dc3cfe20c954cef Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Tue, 30 Jun 2026 05:06:14 +0000 Subject: [PATCH 0435/1300] feat(MeasureTheory): use `IsApply` for `OuterMeasure` (#40945) --- Mathlib/MeasureTheory/Measure/Map.lean | 4 +- .../MeasureTheory/Measure/MeasureSpace.lean | 2 +- .../MeasureTheory/OuterMeasure/Induced.lean | 2 +- .../OuterMeasure/Operations.lean | 62 ++++++++----------- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Map.lean b/Mathlib/MeasureTheory/Measure/Map.lean index 71761db206640f..fa9fb8055d9343 100644 --- a/Mathlib/MeasureTheory/Measure/Map.lean +++ b/Mathlib/MeasureTheory/Measure/Map.lean @@ -49,10 +49,10 @@ def liftLinear [MeasurableSpace β] (f : OuterMeasure α →ₗ[ℝ≥0∞] Oute toFun μ := (f μ.toOuterMeasure).toMeasure (hf μ) map_add' μ₁ μ₂ := ext fun s hs => by simp only [map_add, coe_add, Pi.add_apply, toMeasure_apply, add_toOuterMeasure, - OuterMeasure.coe_add, hs] + FunLike.coe_add, hs] map_smul' c μ := ext fun s hs => by simp only [map_smulₛₗ, Pi.smul_apply, toMeasure_apply, smul_toOuterMeasure (R := ℝ≥0∞), - OuterMeasure.coe_smul (R := ℝ≥0∞), smul_apply, hs] + FunLike.coe_smul, smul_apply, hs] lemma liftLinear_apply₀ {f : OuterMeasure α →ₗ[ℝ≥0∞] OuterMeasure β} (hf) {s : Set β} (hs : NullMeasurableSet s (liftLinear f hf μ)) : liftLinear f hf μ s = f μ.toOuterMeasure s := diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index b3f45e6a32eb42..4f1e08faed2b5d 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -929,7 +929,7 @@ instance instSMul {_ : MeasurableSpace α} : SMul R (Measure α) := ⟨fun c μ => { toOuterMeasure := c • μ.toOuterMeasure m_iUnion := fun s hs hd => by - simp only [OuterMeasure.smul_apply, coe_toOuterMeasure, ENNReal.tsum_const_smul, + simp only [smul_apply, coe_toOuterMeasure, ENNReal.tsum_const_smul, measure_iUnion hd hs] trim_le := by rw [OuterMeasure.trim_smul, μ.trimmed] }⟩ diff --git a/Mathlib/MeasureTheory/OuterMeasure/Induced.lean b/Mathlib/MeasureTheory/OuterMeasure/Induced.lean index 7754fe892632d7..fdf6b35f557d89 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Induced.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Induced.lean @@ -437,7 +437,7 @@ theorem trim_add (m₁ m₂ : OuterMeasure α) : (m₁ + m₂).trim = m₁.trim /-- `trim` respects scalar multiplication. -/ theorem trim_smul {R : Type*} [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] (c : R) (m : OuterMeasure α) : (c • m).trim = c • m.trim := - ext <| trim_op (smul_apply c m) + ext <| trim_op (smul_apply m c) /-- `trim` sends the supremum of two outer measures to the supremum of the trimmed measures. -/ theorem trim_sup (m₁ m₂ : OuterMeasure α) : (m₁ ⊔ m₂).trim = m₁.trim ⊔ m₂.trim := diff --git a/Mathlib/MeasureTheory/OuterMeasure/Operations.lean b/Mathlib/MeasureTheory/OuterMeasure/Operations.lean index 895650c2ddcde1..e928f1711c0649 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Operations.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Operations.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Order.Group.Indicator public import Mathlib.MeasureTheory.OuterMeasure.Basic +public import Mathlib.Data.FunLike.Module /-! # Operations on outer measures @@ -45,9 +46,10 @@ instance instZero : Zero (OuterMeasure α) := mono _ := le_rfl iUnion_nat _ _ := zero_le }⟩ -@[simp] -theorem coe_zero : ⇑(0 : OuterMeasure α) = 0 := - rfl +instance : IsZeroApply (OuterMeasure α) (Set α) ℝ≥0∞ where + zero_apply _ := rfl + +@[deprecated (since := "2026-06-23")] alias coe_zero := FunLike.coe_zero instance instInhabited : Inhabited (OuterMeasure α) := ⟨0⟩ @@ -63,12 +65,12 @@ instance instAdd : Add (OuterMeasure α) := add_le_add (measure_iUnion_le s) (measure_iUnion_le s) _ = _ := ENNReal.tsum_add.symm }⟩ -@[simp] -theorem coe_add (m₁ m₂ : OuterMeasure α) : ⇑(m₁ + m₂) = m₁ + m₂ := - rfl +instance : IsAddApply (OuterMeasure α) (Set α) ℝ≥0∞ where + add_apply _ _ _ := rfl -theorem add_apply (m₁ m₂ : OuterMeasure α) (s : Set α) : (m₁ + m₂) s = m₁ s + m₂ s := - rfl +@[deprecated (since := "2026-06-23")] alias coe_add := FunLike.coe_add + +@[deprecated (since := "2026-06-23")] protected alias add_apply := add_apply section SMul @@ -86,49 +88,39 @@ instance instSMul : SMul R (OuterMeasure α) := simp_rw [← smul_one_mul c (m _), ENNReal.tsum_mul_left] exact mul_right_mono (measure_iUnion_le _) }⟩ -@[simp] -theorem coe_smul (c : R) (m : OuterMeasure α) : ⇑(c • m) = c • ⇑m := - rfl +instance : IsSMulApply R (OuterMeasure α) (Set α) ℝ≥0∞ where + smul_apply _ _ _ := rfl -theorem smul_apply (c : R) (m : OuterMeasure α) (s : Set α) : (c • m) s = c • m s := - rfl +@[deprecated (since := "2026-06-23")] alias coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-06-23")] protected alias smul_apply := smul_apply instance instSMulCommClass [SMulCommClass R R' ℝ≥0∞] : SMulCommClass R R' (OuterMeasure α) := - ⟨fun _ _ _ => ext fun _ => smul_comm _ _ _⟩ + FunLike.smulCommClass instance instIsScalarTower [SMul R R'] [IsScalarTower R R' ℝ≥0∞] : - IsScalarTower R R' (OuterMeasure α) := - ⟨fun _ _ _ => ext fun _ => smul_assoc _ _ _⟩ + IsScalarTower R R' (OuterMeasure α) := FunLike.isScalarTower instance instIsCentralScalar [SMul Rᵐᵒᵖ ℝ≥0∞] [IsCentralScalar R ℝ≥0∞] : - IsCentralScalar R (OuterMeasure α) := - ⟨fun _ _ => ext fun _ => op_smul_eq_smul _ _⟩ + IsCentralScalar R (OuterMeasure α) := FunLike.isCentralScalar end SMul instance instMulAction {R : Type*} [Monoid R] [MulAction R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] : - MulAction R (OuterMeasure α) := - Injective.mulAction _ coe_fn_injective coe_smul + MulAction R (OuterMeasure α) := fast_instance% FunLike.mulAction + +instance addCommMonoid : AddCommMonoid (OuterMeasure α) := fast_instance% FunLike.addCommMonoid -instance addCommMonoid : AddCommMonoid (OuterMeasure α) := - Injective.addCommMonoid (show OuterMeasure α → Set α → ℝ≥0∞ from _) coe_fn_injective rfl - (fun _ _ => rfl) fun _ _ => rfl +@[deprecated (since := "2026-06-23")] alias coeFnAddMonoidHom := FunLike.coeAddMonoidHom -/-- `(⇑)` as an `AddMonoidHom`. -/ -@[simps] -def coeFnAddMonoidHom : OuterMeasure α →+ Set α → ℝ≥0∞ where - toFun := (⇑) - map_zero' := coe_zero - map_add' := coe_add +@[deprecated (since := "2026-06-23")] alias coeFnAddMonoidHom_apply := FunLike.coeAddMonoidHom_apply instance instDistribMulAction {R : Type*} [Monoid R] [DistribMulAction R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] : - DistribMulAction R (OuterMeasure α) := - Injective.distribMulAction coeFnAddMonoidHom coe_fn_injective coe_smul + DistribMulAction R (OuterMeasure α) := fast_instance% FunLike.distribMulAction instance instModule {R : Type*} [Semiring R] [Module R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] : - Module R (OuterMeasure α) := - Injective.module R coeFnAddMonoidHom coe_fn_injective coe_smul + Module R (OuterMeasure α) := fast_instance% FunLike.module instance instBot : Bot (OuterMeasure α) := ⟨0⟩ @@ -148,7 +140,7 @@ instance instIsOrderedAddMonoid {α : Type*} : IsOrderedAddMonoid (OuterMeasure instance orderBot : OrderBot (OuterMeasure α) := { bot := 0, - bot_le := fun a s => by simp only [coe_zero, Pi.zero_apply, zero_le] } + bot_le := fun a s => by simp only [zero_apply, zero_le] } theorem univ_eq_zero_iff (m : OuterMeasure α) : m univ = 0 ↔ m = 0 := ⟨fun h => bot_unique fun s => (measure_mono <| subset_univ s).trans_eq h, fun h => h.symm ▸ rfl⟩ @@ -346,7 +338,7 @@ theorem comap_map {β} {f : α → β} (hf : Injective f) (m : OuterMeasure α) @[simp] theorem top_apply {s : Set α} (h : s.Nonempty) : (⊤ : OuterMeasure α) s = ∞ := let ⟨a, as⟩ := h - top_unique <| le_trans (by simp [smul_dirac_apply, as]) (le_iSup₂ (∞ • dirac a) trivial) + top_unique <| le_trans (by simp [as]) (le_iSup₂ (∞ • dirac a) trivial) theorem top_apply' (s : Set α) : (⊤ : OuterMeasure α) s = ⨅ _ : s = ∅, 0 := s.eq_empty_or_nonempty.elim (fun h => by simp [h]) fun h => by simp [h, h.ne_empty] From 6ffe5eaeb3c0c7a29e43fe0cbeebd8acea7c77f6 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 30 Jun 2026 05:25:30 +0000 Subject: [PATCH 0436/1300] chore(NumberTheory/Femat): fix defeq abuse (#41171) Co-authored-by: Batixx --- Mathlib/NumberTheory/Fermat.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index c5b50d9a5d15ab..10b0bb353af85e 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -127,11 +127,11 @@ theorem pow_of_pow_add_prime {a n : ℕ} (ha : 1 < a) (hn : n ≠ 0) (hP : (a ^ rw [one_pow, hP.dvd_iff_eq (Nat.lt_add_right 1 ha).ne', add_left_inj, pow_eq_self_iff ha] at h rw [h, mul_one] -set_option backward.isDefEq.respectTransparency false in /-- `Fₙ = 2^(2^n)+1` is prime if `3^(2^(2^n-1)) = -1 mod Fₙ` (**Pépin's test**). -/ lemma pepin_primality (n : ℕ) (h : 3 ^ (2 ^ (2 ^ n - 1)) = (-1 : ZMod (fermatNumber n))) : (fermatNumber n).Prime := by have := Fact.mk (two_lt_fermatNumber n) + unfold fermatNumber at h this have key : 2 ^ n = 2 ^ n - 1 + 1 := (Nat.sub_add_cancel Nat.one_le_two_pow).symm apply lucas_primality (p := 2 ^ (2 ^ n) + 1) (a := 3) · rw [Nat.add_sub_cancel, key, pow_succ, pow_mul, ← pow_succ, ← key, h, neg_one_sq] From c25a7b5c6e63612f70532c9ee12e7617079ca428 Mon Sep 17 00:00:00 2001 From: Jeremy Tan Jie Rui <54175463+Parcly-Taxel@users.noreply.github.com> Date: Tue, 30 Jun 2026 06:04:26 +0000 Subject: [PATCH 0437/1300] chore: delete deprecated modules to the end of 2025 (#41168) Co-authored-by: Parcly Taxel --- Mathlib.lean | 18 ------------------ Mathlib/Algebra/Lie/CartanMatrix.lean | 7 ------- Mathlib/Algebra/Order/Module/Algebra.lean | 14 -------------- Mathlib/Algebra/Polynomial/Factors.lean | 6 ------ .../Analysis/Normed/Module/ENormedSpace.lean | 5 ----- .../Trigonometric/Chebyshev.lean | 5 ----- Mathlib/CategoryTheory/Subpresheaf/Basic.lean | 8 -------- .../CategoryTheory/Subpresheaf/Equalizer.lean | 10 ---------- Mathlib/CategoryTheory/Subpresheaf/Finite.lean | 10 ---------- Mathlib/CategoryTheory/Subpresheaf/Image.lean | 10 ---------- .../CategoryTheory/Subpresheaf/OfSection.lean | 10 ---------- Mathlib/CategoryTheory/Subpresheaf/Sieves.lean | 10 ---------- .../CategoryTheory/Subpresheaf/Subobject.lean | 10 ---------- Mathlib/Data/Nat/Choose/Mul.lean | 10 ---------- .../NumberTheory/TsumDivsorsAntidiagonal.lean | 10 ---------- .../Compactness/HilbertCubeEmbedding.lean | 8 -------- .../Compactness/PseudometrizableLindelof.lean | 15 --------------- Mathlib/Topology/Covering.lean | 5 ----- Mathlib/Topology/Semicontinuous.lean | 8 -------- 19 files changed, 179 deletions(-) delete mode 100644 Mathlib/Algebra/Lie/CartanMatrix.lean delete mode 100644 Mathlib/Algebra/Order/Module/Algebra.lean delete mode 100644 Mathlib/Algebra/Polynomial/Factors.lean delete mode 100644 Mathlib/Analysis/Normed/Module/ENormedSpace.lean delete mode 100644 Mathlib/Analysis/SpecialFunctions/Trigonometric/Chebyshev.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/Basic.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/Equalizer.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/Finite.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/Image.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/OfSection.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/Sieves.lean delete mode 100644 Mathlib/CategoryTheory/Subpresheaf/Subobject.lean delete mode 100644 Mathlib/Data/Nat/Choose/Mul.lean delete mode 100644 Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean delete mode 100644 Mathlib/Topology/Compactness/HilbertCubeEmbedding.lean delete mode 100644 Mathlib/Topology/Compactness/PseudometrizableLindelof.lean delete mode 100644 Mathlib/Topology/Covering.lean delete mode 100644 Mathlib/Topology/Semicontinuous.lean diff --git a/Mathlib.lean b/Mathlib.lean index 439e0d6f37b4b1..feceaf0c28726e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -720,7 +720,6 @@ public import Mathlib.Algebra.Lie.Basic public import Mathlib.Algebra.Lie.Basis public import Mathlib.Algebra.Lie.CartanCriterion public import Mathlib.Algebra.Lie.CartanExists -public import Mathlib.Algebra.Lie.CartanMatrix public import Mathlib.Algebra.Lie.CartanSubalgebra public import Mathlib.Algebra.Lie.Character public import Mathlib.Algebra.Lie.Classical @@ -1037,7 +1036,6 @@ public import Mathlib.Algebra.Order.Interval.Set.SuccPred public import Mathlib.Algebra.Order.Invertible public import Mathlib.Algebra.Order.IsBotOne public import Mathlib.Algebra.Order.Kleene -public import Mathlib.Algebra.Order.Module.Algebra public import Mathlib.Algebra.Order.Module.Archimedean public import Mathlib.Algebra.Order.Module.Basic public import Mathlib.Algebra.Order.Module.Defs @@ -1172,7 +1170,6 @@ public import Mathlib.Algebra.Polynomial.Eval.Irreducible public import Mathlib.Algebra.Polynomial.Eval.SMul public import Mathlib.Algebra.Polynomial.Eval.Subring public import Mathlib.Algebra.Polynomial.Expand -public import Mathlib.Algebra.Polynomial.Factors public import Mathlib.Algebra.Polynomial.FieldDivision public import Mathlib.Algebra.Polynomial.GroupRingAction public import Mathlib.Algebra.Polynomial.HasseDeriv @@ -2210,7 +2207,6 @@ public import Mathlib.Analysis.Normed.Module.ContinuousInverse public import Mathlib.Analysis.Normed.Module.Convex public import Mathlib.Analysis.Normed.Module.DoubleDual public import Mathlib.Analysis.Normed.Module.Dual -public import Mathlib.Analysis.Normed.Module.ENormedSpace public import Mathlib.Analysis.Normed.Module.Extr public import Mathlib.Analysis.Normed.Module.FiniteDimension public import Mathlib.Analysis.Normed.Module.HahnBanach @@ -2404,7 +2400,6 @@ public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan public import Mathlib.Analysis.SpecialFunctions.Trigonometric.ArctanDeriv public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Basic public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Bounds -public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Chebyshev public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Chebyshev.Basic public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Chebyshev.ChebyshevGauss public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Chebyshev.Extremal @@ -3461,13 +3456,6 @@ public import Mathlib.CategoryTheory.Subobject.NoetherianObject public import Mathlib.CategoryTheory.Subobject.Presheaf public import Mathlib.CategoryTheory.Subobject.Types public import Mathlib.CategoryTheory.Subobject.WellPowered -public import Mathlib.CategoryTheory.Subpresheaf.Basic -public import Mathlib.CategoryTheory.Subpresheaf.Equalizer -public import Mathlib.CategoryTheory.Subpresheaf.Finite -public import Mathlib.CategoryTheory.Subpresheaf.Image -public import Mathlib.CategoryTheory.Subpresheaf.OfSection -public import Mathlib.CategoryTheory.Subpresheaf.Sieves -public import Mathlib.CategoryTheory.Subpresheaf.Subobject public import Mathlib.CategoryTheory.Subterminal public import Mathlib.CategoryTheory.Sums.Associator public import Mathlib.CategoryTheory.Sums.Basic @@ -4186,7 +4174,6 @@ public import Mathlib.Data.Nat.Choose.Central public import Mathlib.Data.Nat.Choose.Dvd public import Mathlib.Data.Nat.Choose.Factorization public import Mathlib.Data.Nat.Choose.Lucas -public import Mathlib.Data.Nat.Choose.Mul public import Mathlib.Data.Nat.Choose.Multinomial public import Mathlib.Data.Nat.Choose.Sum public import Mathlib.Data.Nat.Choose.Vandermonde @@ -5913,7 +5900,6 @@ public import Mathlib.NumberTheory.Transcendental.Liouville.LiouvilleWith public import Mathlib.NumberTheory.Transcendental.Liouville.Measure public import Mathlib.NumberTheory.Transcendental.Liouville.Residual public import Mathlib.NumberTheory.TsumDivisorsAntidiagonal -public import Mathlib.NumberTheory.TsumDivsorsAntidiagonal public import Mathlib.NumberTheory.WellApproximable public import Mathlib.NumberTheory.Wilson public import Mathlib.NumberTheory.ZetaValues @@ -7804,13 +7790,11 @@ public import Mathlib.Topology.Compactness.CompactlyCoherentSpace public import Mathlib.Topology.Compactness.CompactlyGeneratedSpace public import Mathlib.Topology.Compactness.CountablyCompact public import Mathlib.Topology.Compactness.DeltaGeneratedSpace -public import Mathlib.Topology.Compactness.HilbertCubeEmbedding public import Mathlib.Topology.Compactness.Lindelof public import Mathlib.Topology.Compactness.LocallyCompact public import Mathlib.Topology.Compactness.LocallyFinite public import Mathlib.Topology.Compactness.NhdsKer public import Mathlib.Topology.Compactness.Paracompact -public import Mathlib.Topology.Compactness.PseudometrizableLindelof public import Mathlib.Topology.Compactness.SigmaCompact public import Mathlib.Topology.Connected.Basic public import Mathlib.Topology.Connected.CardComponents @@ -7863,7 +7847,6 @@ public import Mathlib.Topology.Convenient.GeneratedBy public import Mathlib.Topology.Convenient.HomSpace public import Mathlib.Topology.Convenient.Localization public import Mathlib.Topology.Convenient.OpenClosed -public import Mathlib.Topology.Covering public import Mathlib.Topology.Covering.AddCircle public import Mathlib.Topology.Covering.Basic public import Mathlib.Topology.Covering.Quotient @@ -8097,7 +8080,6 @@ public import Mathlib.Topology.Semicontinuity.Basic public import Mathlib.Topology.Semicontinuity.Defs public import Mathlib.Topology.Semicontinuity.Hemicontinuity public import Mathlib.Topology.Semicontinuity.Lindelof -public import Mathlib.Topology.Semicontinuous public import Mathlib.Topology.SeparatedMap public import Mathlib.Topology.Separation.AlexandrovDiscrete public import Mathlib.Topology.Separation.Basic diff --git a/Mathlib/Algebra/Lie/CartanMatrix.lean b/Mathlib/Algebra/Lie/CartanMatrix.lean deleted file mode 100644 index f9cb2e5bcd63b5..00000000000000 --- a/Mathlib/Algebra/Lie/CartanMatrix.lean +++ /dev/null @@ -1,7 +0,0 @@ -module -- shake: keep-all - -import Mathlib.Data.Finset.Attr -import Mathlib.Data.Sym.Sym2.Init -import Mathlib.Tactic.NormNum.GCD - -deprecated_module (since := "2025-12-13") diff --git a/Mathlib/Algebra/Order/Module/Algebra.lean b/Mathlib/Algebra/Order/Module/Algebra.lean deleted file mode 100644 index 5ce7dabc6d718e..00000000000000 --- a/Mathlib/Algebra/Order/Module/Algebra.lean +++ /dev/null @@ -1,14 +0,0 @@ -/- -Copyright (c) 2020 Kim Morrison. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kim Morrison --/ -module -- shake: keep-all - -public import Mathlib.Algebra.Order.Algebra - -deprecated_module (since := "2025-12-16") - -public section - -@[deprecated (since := "2025-12-16")] alias algebraMap_monotone := algebraMap_mono diff --git a/Mathlib/Algebra/Polynomial/Factors.lean b/Mathlib/Algebra/Polynomial/Factors.lean deleted file mode 100644 index b445b2271cfa6e..00000000000000 --- a/Mathlib/Algebra/Polynomial/Factors.lean +++ /dev/null @@ -1,6 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Tactic.NormNum -public import Mathlib.Tactic.Positivity - -deprecated_module (since := "2025-12-16") diff --git a/Mathlib/Analysis/Normed/Module/ENormedSpace.lean b/Mathlib/Analysis/Normed/Module/ENormedSpace.lean deleted file mode 100644 index f67330db283dfc..00000000000000 --- a/Mathlib/Analysis/Normed/Module/ENormedSpace.lean +++ /dev/null @@ -1,5 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Analysis.Normed.Group.Basic - -deprecated_module (since := "2025-12-18") diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Chebyshev.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Chebyshev.lean deleted file mode 100644 index cce68ab67fd702..00000000000000 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Chebyshev.lean +++ /dev/null @@ -1,5 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Chebyshev.Basic - -deprecated_module (since := "2025-12-15") diff --git a/Mathlib/CategoryTheory/Subpresheaf/Basic.lean b/Mathlib/CategoryTheory/Subpresheaf/Basic.lean deleted file mode 100644 index 7b11436e10dd84..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/Basic.lean +++ /dev/null @@ -1,8 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/CategoryTheory/Subpresheaf/Equalizer.lean b/Mathlib/CategoryTheory/Subpresheaf/Equalizer.lean deleted file mode 100644 index 43d021ec127875..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/Equalizer.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/CategoryTheory/Subpresheaf/Finite.lean b/Mathlib/CategoryTheory/Subpresheaf/Finite.lean deleted file mode 100644 index 43d021ec127875..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/Finite.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/CategoryTheory/Subpresheaf/Image.lean b/Mathlib/CategoryTheory/Subpresheaf/Image.lean deleted file mode 100644 index 43d021ec127875..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/Image.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/CategoryTheory/Subpresheaf/OfSection.lean b/Mathlib/CategoryTheory/Subpresheaf/OfSection.lean deleted file mode 100644 index 43d021ec127875..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/OfSection.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/CategoryTheory/Subpresheaf/Sieves.lean b/Mathlib/CategoryTheory/Subpresheaf/Sieves.lean deleted file mode 100644 index 43d021ec127875..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/Sieves.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/CategoryTheory/Subpresheaf/Subobject.lean b/Mathlib/CategoryTheory/Subpresheaf/Subobject.lean deleted file mode 100644 index 43d021ec127875..00000000000000 --- a/Mathlib/CategoryTheory/Subpresheaf/Subobject.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/Data/Nat/Choose/Mul.lean b/Mathlib/Data/Nat/Choose/Mul.lean deleted file mode 100644 index eb091c41ea5773..00000000000000 --- a/Mathlib/Data/Nat/Choose/Mul.lean +++ /dev/null @@ -1,10 +0,0 @@ -/- -Copyright (c) 2024 Antoine Chambert-Loir & María-Inés de Frutos—Fernández. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Antoine Chambert-Loir, María-Inés de Frutos—Fernández --/ -module -- shake: keep-all - -public import Mathlib.Tactic.Common - -deprecated_module (since := "2025-12-15") diff --git a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean deleted file mode 100644 index f6faf763281802..00000000000000 --- a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Algebra.Order.Field.Power -public import Mathlib.Analysis.Normed.Group.Basic -public import Mathlib.Data.EReal.Inv -public import Mathlib.NumberTheory.ArithmeticFunction.Misc -public import Mathlib.Topology.Algebra.InfiniteSum.Order -public import Mathlib.Topology.MetricSpace.Bounded - -deprecated_module (since := "2025-12-19") diff --git a/Mathlib/Topology/Compactness/HilbertCubeEmbedding.lean b/Mathlib/Topology/Compactness/HilbertCubeEmbedding.lean deleted file mode 100644 index b3558a83cc2ad7..00000000000000 --- a/Mathlib/Topology/Compactness/HilbertCubeEmbedding.lean +++ /dev/null @@ -1,8 +0,0 @@ -module -- shake: keep-all - -import Mathlib.Analysis.Normed.Group.Basic -import Mathlib.Data.EReal.Inv -import Mathlib.Topology.Algebra.InfiniteSum.Order -import Mathlib.Topology.MetricSpace.Bounded - -deprecated_module (since := "2025-12-18") diff --git a/Mathlib/Topology/Compactness/PseudometrizableLindelof.lean b/Mathlib/Topology/Compactness/PseudometrizableLindelof.lean deleted file mode 100644 index 571e1749539bd4..00000000000000 --- a/Mathlib/Topology/Compactness/PseudometrizableLindelof.lean +++ /dev/null @@ -1,15 +0,0 @@ -/- -Copyright (c) 2023 Josha Dekker. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Josha Dekker --/ -module -- shake: keep-all - -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Continuity -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2025-12-10") diff --git a/Mathlib/Topology/Covering.lean b/Mathlib/Topology/Covering.lean deleted file mode 100644 index f1bd5c1e8ed341..00000000000000 --- a/Mathlib/Topology/Covering.lean +++ /dev/null @@ -1,5 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Topology.Covering.Basic - -deprecated_module (since := "2025-12-10") diff --git a/Mathlib/Topology/Semicontinuous.lean b/Mathlib/Topology/Semicontinuous.lean deleted file mode 100644 index bf09eea3bd4835..00000000000000 --- a/Mathlib/Topology/Semicontinuous.lean +++ /dev/null @@ -1,8 +0,0 @@ -module -- shake: keep-all - -import Mathlib.Algebra.Order.Module.Field -import Mathlib.Data.EReal.Operations -import Mathlib.Topology.Algebra.InfiniteSum.Order -import Mathlib.Topology.MetricSpace.Bounded - -deprecated_module (since := "2025-12-17") From e695991a088208f40bfc4ab2fb4b4f8ca7e26ffa Mon Sep 17 00:00:00 2001 From: Wenrong Zou <141128015+WenrongZou@users.noreply.github.com> Date: Tue, 30 Jun 2026 06:44:20 +0000 Subject: [PATCH 0438/1300] feat(FormalGroup): `F(X,0)=X` and `F(0,X)=X` (#38052) In this PR, I prove that given a formal group law `F`, then `F(X,0) = X` and `F(0,X) = X`. And modify the definition of `FormalGroup.Point` to be a subtype. And prove that this subtype is a `AddZeroClass`. Eventually we will prove that this is a `AddGroup`. Co-authored-by: WenrongZou --- Mathlib/RingTheory/FormalGroup/Basic.lean | 227 ++++++++++++++++-- .../MvPowerSeries/Substitution.lean | 57 +++-- Mathlib/RingTheory/PowerSeries/Basic.lean | 8 +- .../RingTheory/PowerSeries/Evaluation.lean | 2 +- .../RingTheory/PowerSeries/Substitution.lean | 11 +- 5 files changed, 267 insertions(+), 38 deletions(-) diff --git a/Mathlib/RingTheory/FormalGroup/Basic.lean b/Mathlib/RingTheory/FormalGroup/Basic.lean index 27e991b35e0781..4c6d3bf0156cb7 100644 --- a/Mathlib/RingTheory/FormalGroup/Basic.lean +++ b/Mathlib/RingTheory/FormalGroup/Basic.lean @@ -12,8 +12,8 @@ public import Mathlib.Tactic.Ring.NamePowerVars Let `R` be a commutative ring, a one dimensional formal group law is a formal power series `F(X,Y) ∈ R⟦X,Y⟧` such that -· `F(X,Y) = X + Y + higher order terms`. -· `F(F(X,Y),Z) = F(X,F(Y,Z))`. + * `F(X,Y) = X + Y + higher order terms`. + * `F(F(X,Y),Z) = F(X,F(Y,Z))`. Under this definition, we can prove that `F(X,0) = X` and `F(0,X) = X`. Moreover, there is a unique power series `i(X)` such that `F(X, i(X)) = 0`, which is considered to be the inverse @@ -21,14 +21,17 @@ of the formal group law `F(X,Y)`. ## Main definitions/lemmas -* Definition of one dimensional formal group law. +* `FormalGroup R`: definition of one dimensional formal group law over commutative ring `R`. -* Properties: `F(X,0) = 0` and `F(0,X) = X`. +* Properties: `F(X,0) = X` and `F(0,X) = X`. -* Additive formal group laws and multiplicative formal group laws. +* Additive formal group laws `𝔾ₐ` and multiplicative formal group laws `𝔾ₘ`. -* Instance: Group instance defined by the formal group law `F` over the ideal - `PowerSeries.hasEvalIdeal`. +* `F.Point σ` taking values in the formal power series ring `MvPowerSeries σ R` with the property +that constant coefficient is nilpotent. We have the following typeclass: +- `AddMonoid (F.Point σ)` +when `F` is a commutative formal group law +- `AddCommMonoid (F.Point σ)` ## References * [Hazewinkel, Michiel. Formal Groups and Applications][hazewinkel1978] @@ -37,7 +40,7 @@ of the formal group law `F(X,Y)`. @[expose] public section -variable {R : Type*} [CommRing R] {S : Type*} [CommRing S] [Algebra R S] {σ τ : Type*} +variable {R : Type*} [CommRing R] {S : Type*} [CommRing S] {σ τ : Type*} noncomputable section @@ -71,24 +74,71 @@ instance FormalGroup.coeToPowerSeries : Coe (FormalGroup R) (MvPowerSeries (Fin class FormalGroup.IsComm (F : FormalGroup R) : Prop where comm : F = (F : MvPowerSeries (Fin 2) R).subst ![X₁, X₀] +lemma FormalGroup.assoc' (F : FormalGroup R) {f₀ f₁ f₂ : MvPowerSeries σ R} + (h₀ : PowerSeries.HasSubst f₀) (h₁ : PowerSeries.HasSubst f₁) (h₂ : PowerSeries.HasSubst f₂) : + F.toPowerSeries.subst ![F.toPowerSeries.subst ![f₀, f₁], f₂] = + F.toPowerSeries.subst ![f₀, F.toPowerSeries.subst ![f₁, f₂]] := by + obtain aux₁ := HasSubst.cons_subst_zero_left (0 : Fin 3) 1 2 F.zero_constantCoeff + obtain aux₂ := HasSubst.cons_subst_zero_right (0 : Fin 3) 1 2 F.zero_constantCoeff + have : HasSubst ![f₀, f₁, f₂] := + hasSubst_of_constantCoeff_nilpotent fun s => by fin_cases s <;> simpa + calc + _ = (F.toPowerSeries.subst ![F.toPowerSeries.subst ![Y₀, Y₁], Y₂]).subst ![f₀, f₁, f₂] := by + rw [subst_comp_subst_apply aux₁ this] + congr! 2 with s + fin_cases s + · simp only [Nat.succ_eq_add_one, Nat.reduceAdd, Fin.zero_eta, Fin.isValue, + Matrix.cons_val_zero, subst_comp_subst_apply HasSubst.X_X this] + congr! 2 with s + fin_cases s <;> simp [subst_X this] + · simp [subst_X this] + _ = _ := by + rw [F.assoc, subst_comp_subst_apply aux₂ this] + congr! 2 with s + fin_cases s + · simp [subst_X this] + · simp only [Fin.mk_one, Matrix.cons_val_one, Matrix.cons_val_fin_one, + subst_comp_subst_apply HasSubst.X_X this] + congr! 2 with s + fin_cases s <;> simp [subst] + +lemma FormalGroup.comm' (F : FormalGroup R) [F.IsComm] {f g : MvPowerSeries σ R} + (hf : PowerSeries.HasSubst f) (hg : PowerSeries.HasSubst g) : + F.toPowerSeries.subst ![f, g] = F.toPowerSeries.subst ![g, f] := by + nth_rw 1 [IsComm.comm] + rw [subst_comp_subst_apply HasSubst.X_X <| hasSubst_of_constantCoeff_nilpotent (by simp [hf, hg])] + congr! 2 with s + fin_cases s <;> simp [subst] + namespace FormalGroup -variable {σ : Type} (F : FormalGroup R) +variable {σ : Type*} (F : FormalGroup R) set_option linter.unusedVariables false in -/-- `Point F σ` represents the mathematical space of points of a formal group $F$ -taking values in the formal power series ring `R⟦X_σ⟧`. +/-- `F.Point σ` represents the mathematical space of points of a formal group $F$ +taking values in the formal power series ring `MvPowerSeries σ R` with the property +that constant coefficient is nilpotent. -Mathematically, a 1-dimensional formal group law $F$ over a ring $R$ defines a group +TODO: Mathematically, a 1-dimensional formal group law $F$ over a ring $R$ defines a group structure on the elements of a complete local $R$-algebra (specifically, its maximal ideal) via the substitution operation $x +_F y = F(x, y)$. -/ @[nolint unusedArguments] -def Point (F : FormalGroup R) (σ : Type) := MvPowerSeries σ R +def Point (F : FormalGroup R) (σ : Type*) := {f : MvPowerSeries σ R // PowerSeries.HasSubst f} instance : Add (F.Point σ) where - add x y := (F : MvPowerSeries (Fin 2) R).subst ![x, y] + add x y := ⟨F.toPowerSeries.subst ![x.val, y.val], + IsNilpotent_subst (by simp [hasSubst_of_constantCoeff_nilpotent, x.prop, y.prop]) + (F.zero_constantCoeff ▸ IsNilpotent.zero)⟩ + +@[simp] +lemma add_apply {x y : F.Point σ} : (x + y).val = F.toPowerSeries.subst ![x.val, y.val] := by + rfl + +instance : Zero (F.Point σ) where + zero := ⟨0, PowerSeries.HasSubst.zero⟩ -/- TODO : Zero, SMul, Inv instance. -/ +@[simp] +lemma zero_apply : (0 : F.Point σ).val = (0 : MvPowerSeries σ R) := rfl /-- Additive formal group law `𝔾ₐ(X,Y) = X + Y`. -/ @[simps] @@ -127,7 +177,6 @@ def 𝔾ₘ : FormalGroup R where instance : (𝔾ₘ (R := R)).IsComm where comm := by simp [subst_add .X_X, subst_mul .X_X, subst_X .X_X, add_comm, mul_comm] -omit [Algebra R S] in /-- Given an algebra map `f : R →+* S` and a formal group law `F` over `R`, then `f_* F` is a formal group law formal group law over `S`. This is constructed by applying `f` to all coefficients of the underlying power series. -/ @@ -145,3 +194,149 @@ def map (f : R →+* S) : FormalGroup S where ← map_subst (HasSubst.cons_subst_zero_right (0 : Fin 3) 1 2 F.zero_constantCoeff)] end FormalGroup + +section + +namespace FormalGroup + +variable (F : FormalGroup R) + +/-- An abbreviation of $F(X,0)$ for a formal group $F$. -/ +abbrev Xzero : PowerSeries R := subst ![PowerSeries.X, 0] F.toPowerSeries + +lemma constantCoeff_Xzero : F.Xzero.constantCoeff = 0 := by + simp [PowerSeries.constantCoeff, Xzero, PowerSeries.X, MvPowerSeries.constantCoeff_subst_eq_zero + HasSubst.X_zero _ F.zero_constantCoeff] + +@[simp] +lemma coeff_one_Xzero : F.Xzero.coeff 1 = 1 := by + rw [PowerSeries.coeff, coeff_subst, finsum_eq_single _ (single 0 1)] + · simp [F.lin_coeff_X] + · intro d hd + by_cases hd₁ : d 1 = 0 + · by_cases hd₀ : d 0 = 0 + · simp [hd₀, hd₁] + simp [hd₁, PowerSeries.coeff_X_pow] + grind + simp [hd₁] + · exact HasSubst.X_zero + +@[simp] +lemma Xzero_subst_Xzero : F.Xzero.subst F.Xzero = F.Xzero := by + calc + _ = F.toPowerSeries.subst ![F.toPowerSeries.subst ![PowerSeries.X, 0], 0] := by + have : PowerSeries.HasSubst (subst ![PowerSeries.X (R := R), 0] F.toPowerSeries) := by + refine PowerSeries.HasSubst.of_constantCoeff_zero' ?_ + rw [PowerSeries.constantCoeff, PowerSeries.X, constantCoeff_subst_eq_zero HasSubst.X_zero + (by simp) F.zero_constantCoeff] + rw [PowerSeries.subst, subst_comp_subst_apply _ this.const] + · congr! 2 with d + fin_cases d + · simp [← PowerSeries.subst_def, PowerSeries.subst_X this] + · simp [← PowerSeries.subst_def, ← PowerSeries.coe_substAlgHom this] + · exact HasSubst.X_zero + _ = _ := by + have : ![0, 0] = (0 : Fin 2 → PowerSeries R) := by + ext x : 1; fin_cases x <;> rfl + simp [F.assoc', this, subst_zero_of_constantCoeff_zero F.zero_constantCoeff, + PowerSeries.HasSubst.X', PowerSeries.HasSubst] + +lemma Xzero_eq_X : F.Xzero = PowerSeries.X := by + haveI : Invertible (F.Xzero.coeff 1) := (coeff_one_Xzero F) ▸ invertibleOne + calc + _ = F.Xzero.substInv.subst (F.Xzero.subst F.Xzero) := by + have aux₀ : PowerSeries.HasSubst F.Xzero := + PowerSeries.HasSubst.of_constantCoeff_zero' <| constantCoeff_Xzero F + rw [← PowerSeries.subst_comp_subst_apply aux₀ aux₀, PowerSeries.subst_substInv_left _ + F.constantCoeff_Xzero , PowerSeries.subst_X aux₀, Xzero] + _ = _ := by + rw [Xzero_subst_Xzero, F.Xzero.subst_substInv_left F.constantCoeff_Xzero] + +/-- An abbreviation of $F(0,X)$ for a formal group $F$. -/ +abbrev zeroX : PowerSeries R := subst ![0, PowerSeries.X] F.toPowerSeries + +lemma constantCoeff_zeroX : F.zeroX.constantCoeff = 0 := by + simp [PowerSeries.constantCoeff, zeroX, PowerSeries.X, MvPowerSeries.constantCoeff_subst_eq_zero + HasSubst.zero_X _ F.zero_constantCoeff] + +@[simp] +lemma coeff_one_zeroX : F.zeroX.coeff 1 = 1 := by + rw [PowerSeries.coeff, coeff_subst, finsum_eq_single _ (single 1 1)] + · simp [F.lin_coeff_Y] + · intro d hd + by_cases hd₁ : d 0 = 0 + · by_cases hd₀ : d 1 = 0 + · simp [hd₀, hd₁] + simp [hd₁, PowerSeries.coeff_X_pow] + grind + simp [hd₁] + · exact HasSubst.zero_X + +@[simp] +lemma zeroX_subst_zeroX : F.zeroX.subst F.zeroX = F.zeroX := by + calc + _ = F.toPowerSeries.subst ![0, F.toPowerSeries.subst ![0, PowerSeries.X]] := by + have : PowerSeries.HasSubst (subst ![0, PowerSeries.X (R := R)] F.toPowerSeries) := by + refine PowerSeries.HasSubst.of_constantCoeff_zero' ?_ + rw [PowerSeries.constantCoeff, PowerSeries.X, constantCoeff_subst_eq_zero HasSubst.zero_X + (by simp) F.zero_constantCoeff] + rw [PowerSeries.subst, subst_comp_subst_apply _ this.const] + · congr! 2 with d + fin_cases d + · simp [← PowerSeries.subst_def, ← PowerSeries.coe_substAlgHom this] + · simp [← PowerSeries.subst_def, PowerSeries.subst_X this] + · exact HasSubst.zero_X + _ = _ := by + have : ![0, 0] = (0 : Fin 2 → PowerSeries R) := by ext x : 1; fin_cases x <;> rfl + simp [← F.assoc', this, subst_zero_of_constantCoeff_zero F.zero_constantCoeff, + PowerSeries.HasSubst.X', PowerSeries.HasSubst] + +lemma zeroX_eq_X : F.zeroX = PowerSeries.X := by + haveI : Invertible (F.zeroX.coeff 1) := (coeff_one_zeroX F) ▸ invertibleOne + calc + _ = F.zeroX.substInv.subst (F.zeroX.subst F.zeroX) := by + have aux₀ : PowerSeries.HasSubst F.zeroX := + PowerSeries.HasSubst.of_constantCoeff_zero' <| F.constantCoeff_zeroX + rw [← PowerSeries.subst_comp_subst_apply aux₀ aux₀, PowerSeries.subst_substInv_left _ + F.constantCoeff_zeroX, PowerSeries.subst_X aux₀, zeroX] + _ = _ := by + rw [zeroX_subst_zeroX, F.zeroX.subst_substInv_left F.constantCoeff_zeroX] + +theorem add_zero {f : MvPowerSeries σ R} (hf : PowerSeries.HasSubst f) : + F.toPowerSeries.subst ![f, 0] = f := by + calc + _ = PowerSeries.subst f (F.toPowerSeries.subst ![PowerSeries.X (R := R), 0]) := by + rw [PowerSeries.subst, subst_comp_subst_apply _ hf.const] + · congr! 2 with s + fin_cases s + · simp [PowerSeries.X, subst] + · simp [subst, eval₂] + exact HasSubst.X_zero + _ = _ := by + simp [Xzero_eq_X, PowerSeries.subst_X hf] + +theorem zero_add {f : MvPowerSeries σ R} (hf : PowerSeries.HasSubst f) : + F.toPowerSeries.subst ![0, f] = f := by + calc + _ = PowerSeries.subst f (F.toPowerSeries.subst ![0, PowerSeries.X (R := R)]) := by + rw [PowerSeries.subst, subst_comp_subst_apply _ hf.const] + · congr! 2 with s + fin_cases s + · simp [subst, eval₂] + · simp [PowerSeries.X, subst] + · exact HasSubst.zero_X + _ = _ := by + simp [zeroX_eq_X, PowerSeries.subst_X hf] + +instance : AddMonoid (F.Point σ) where + zero_add x := Subtype.ext (zero_add F x.prop) + add_zero x := Subtype.ext (add_zero F x.prop) + nsmul := nsmulRec + add_assoc x y z := Subtype.ext <| F.assoc' x.prop y.prop z.prop + +instance [F.IsComm] : AddCommMonoid (F.Point σ) where + add_comm x y := Subtype.ext <| F.comm' x.prop y.prop + +end FormalGroup + +end diff --git a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean index 19bb2310ea5c87..4bf62eae37dcea 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean @@ -160,6 +160,12 @@ theorem hasSubst_of_constantCoeff_zero [Finite σ] lemma HasSubst.X_X {i j : σ} : HasSubst (S := R) ![X i, X j] := hasSubst_of_constantCoeff_zero (by simp) +lemma HasSubst.X_zero {i : σ} : HasSubst ![X i (R := R), 0] := + hasSubst_of_constantCoeff_zero (by simp) + +lemma HasSubst.zero_X {i : σ} : HasSubst ![0, X i (R := R)] := + hasSubst_of_constantCoeff_zero (by simp) + protected lemma HasSubst.pow {n : ℕ} (hn : n ≠ 0) {a : σ → MvPowerSeries τ S} (h : HasSubst a) : HasSubst (a ^ n) := hasSubstIdeal.pow_mem_of_mem h _ (by lia) @@ -351,6 +357,23 @@ theorem map_subst {a : σ → MvPowerSeries τ R} (ha : HasSubst a) {h : R →+* simp [smul_eq_mul, RingHom.toAddMonoidHom_eq_coe, AddMonoidHom.coe_coe, map_mul, ← coeff_map, Finsupp.prod] +lemma subst_zero_eq_C_constantCoeff {f : MvPowerSeries σ R} : + f.subst (0 : σ → MvPowerSeries τ S) = (C f.constantCoeff).map (algebraMap R S) := by + classical + ext n + rw [coeff_subst (by simp [hasSubst_def]), coeff_map, finsum_eq_single _ 0] + · by_cases hn : n = 0 + · simp [hn, Algebra.algebraMap_eq_smul_one] + simp [coeff_C_of_ne_zero hn, coeff_one, hn] + intro d hd + obtain ⟨i, hi⟩ : d.support.Nonempty := d.support_nonempty_iff.mpr hd + simp [Finsupp.prod, Finset.prod_eq_zero hi, coeff_zero, zero_pow <| d.mem_support_iff.mp hi] + +@[simp] +lemma subst_zero_of_constantCoeff_zero {f : MvPowerSeries σ R} (hf : f.constantCoeff = 0) : + f.subst (0 : σ → MvPowerSeries τ S) = 0 := by + simp [subst_zero_eq_C_constantCoeff, hf] + lemma HasSubst.cons_subst_zero_left {f : MvPowerSeries (Fin 2) R} (i j k : σ) (hF : constantCoeff f = 0) : HasSubst (![subst ![X i, X j] f, X k]) (S := R) := hasSubst_of_constantCoeff_zero fun s => by @@ -403,32 +426,30 @@ variable {υ : Type*} {T : Type*} [CommRing T] [Algebra R T] [Algebra S T] [IsScalarTower R S T] {b : τ → MvPowerSeries υ T} -theorem IsNilpotent_subst (ha : HasSubst a) - {f : MvPowerSeries σ R} (hf : IsNilpotent (constantCoeff f)) : - IsNilpotent (constantCoeff (substAlgHom ha f)) := by +lemma IsNilpotent_subst (ha : HasSubst a) + {f : MvPowerSeries σ R} (hf : IsNilpotent f.constantCoeff) : + IsNilpotent (constantCoeff (f.subst a)) := by classical - rw [coe_substAlgHom, constantCoeff_subst ha] - apply isNilpotent_finsum - intro d + rw [constantCoeff_subst ha] + refine isNilpotent_finsum fun d => ?_ by_cases hd : d = 0 · rw [← algebraMap_smul S, smul_eq_mul, mul_comm, ← smul_eq_mul, hd] apply IsNilpotent.smul simpa using IsNilpotent.map hf (algebraMap R S) - · apply IsNilpotent.smul - rw [← ne_eq, Finsupp.ne_iff] at hd - obtain ⟨t, hs⟩ := hd - rw [← Finsupp.prod_filter_mul_prod_filter_not (fun i ↦ i = t), map_mul, - mul_comm, ← smul_eq_mul] - apply IsNilpotent.smul - rw [Finsupp.prod_eq_single t] - · simpa using IsNilpotent.pow_of_pos (ha.const_coeff t) hs - · intro t' htt' ht' - simp [ht'] at htt' - · exact fun _ ↦ by rw [pow_zero] + obtain ⟨i, hi⟩ : d.support.Nonempty := d.support_nonempty_iff.mpr hd + rw [Finsupp.prod, map_prod, ← Finset.prod_erase_mul _ _ hi, ← algebraMap_smul S, + smul_eq_mul, ← mul_assoc, map_pow] + exact Commute.isNilpotent_mul_left (Commute.all _ _) + <| (IsNilpotent.pow_iff_pos (d.mem_support_iff.mp hi)).mpr (ha.const_coeff i) + +theorem IsNilpotent_substAlgHom (ha : HasSubst a) + {f : MvPowerSeries σ R} (hf : IsNilpotent (constantCoeff f)) : + IsNilpotent (constantCoeff (substAlgHom ha f)) := by + simpa using IsNilpotent_subst ha hf theorem HasSubst.comp (ha : HasSubst a) (hb : HasSubst b) : HasSubst (fun s ↦ substAlgHom hb (a s)) where - const_coeff s := IsNilpotent_subst hb (ha.const_coeff s) + const_coeff s := IsNilpotent_substAlgHom hb (ha.const_coeff s) coeff_zero := by letI : UniformSpace S := ⊥ letI : UniformSpace T := ⊥ diff --git a/Mathlib/RingTheory/PowerSeries/Basic.lean b/Mathlib/RingTheory/PowerSeries/Basic.lean index b9c69c2a9e360c..6363eb10d7665b 100644 --- a/Mathlib/RingTheory/PowerSeries/Basic.lean +++ b/Mathlib/RingTheory/PowerSeries/Basic.lean @@ -88,6 +88,10 @@ theorem coeff_def {s : Unit →₀ ℕ} {n : ℕ} (h : s () = n) : coeff (R := R) n = MvPowerSeries.coeff s := by rw [coeff, ← h, ← Finsupp.unique_single s] +@[simp] +lemma coeff_coeToMvPowerSeries {f : R⟦X⟧} (n : ℕ) : + MvPowerSeries.coeff (Finsupp.single () n) f = f.coeff n := rfl + /-- Two formal power series are equal if all their coefficients are equal. -/ @[ext] theorem ext {φ ψ : R⟦X⟧} (h : ∀ n, coeff n φ = coeff n ψ) : φ = ψ := @@ -228,12 +232,12 @@ theorem X_ne_zero [Nontrivial R] : (X : R⟦X⟧) ≠ 0 := fun H => by theorem X_pow_eq (n : ℕ) : (X : R⟦X⟧) ^ n = monomial n 1 := MvPowerSeries.X_pow_eq _ n +@[simp, grind =] theorem coeff_X_pow (m n : ℕ) : coeff m ((X : R⟦X⟧) ^ n) = if m = n then 1 else 0 := by rw [X_pow_eq, coeff_monomial] -@[simp] theorem coeff_X_pow_self (n : ℕ) : coeff n ((X : R⟦X⟧) ^ n) = 1 := by - rw [coeff_X_pow, if_pos rfl] + simp @[simp] theorem coeff_one (n : ℕ) : coeff n (1 : R⟦X⟧) = if n = 0 then 1 else 0 := diff --git a/Mathlib/RingTheory/PowerSeries/Evaluation.lean b/Mathlib/RingTheory/PowerSeries/Evaluation.lean index c09f9380cc32d7..8e4a47c6184849 100644 --- a/Mathlib/RingTheory/PowerSeries/Evaluation.lean +++ b/Mathlib/RingTheory/PowerSeries/Evaluation.lean @@ -179,7 +179,7 @@ theorem hasSum_eval₂ (hφ : Continuous φ) (ha : HasEval a) (f : PowerSeries R have := MvPowerSeries.hasSum_eval₂ hφ (hasEval ha) f simp only [PowerSeries.eval₂] rw [← (Finsupp.single_injective ()).hasSum_iff] at this - · convert! this; simp; congr + · convert this; simp · intro d hd exact False.elim (hd ⟨d (), by ext; simp⟩) diff --git a/Mathlib/RingTheory/PowerSeries/Substitution.lean b/Mathlib/RingTheory/PowerSeries/Substitution.lean index 1ae3a665099d6d..594ec0f9357e8b 100644 --- a/Mathlib/RingTheory/PowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/PowerSeries/Substitution.lean @@ -196,6 +196,15 @@ theorem subst_sub (ha : HasSubst a) (f g : PowerSeries R) : subst a (f - g) = subst a f - subst a g := by rw [← coe_substAlgHom ha, map_sub] +lemma subst_zero_eq_C_constantCoeff {f : PowerSeries R} : + f.subst 0 = (MvPowerSeries.C f.constantCoeff (σ := τ)).map (algebraMap R S) := + MvPowerSeries.subst_zero_eq_C_constantCoeff + +@[simp] +theorem subst_zero_of_constantCoeff_zero {f : PowerSeries R} (hf : f.constantCoeff = 0) : + subst (0 : MvPowerSeries τ S) f = 0 := + MvPowerSeries.subst_zero_of_constantCoeff_zero hf + theorem subst_pow (ha : HasSubst a) (f : PowerSeries R) (n : ℕ) : subst a (f ^ n) = (subst a f) ^ n := by rw [← coe_substAlgHom ha, map_pow] @@ -362,7 +371,7 @@ end theorem HasSubst.comp {a : PowerSeries S} (ha : HasSubst a) {b : MvPowerSeries υ T} (hb : HasSubst b) : HasSubst (substAlgHom hb a) := - MvPowerSeries.IsNilpotent_subst hb.const ha + MvPowerSeries.IsNilpotent_substAlgHom hb.const ha variable {a : PowerSeries S} {b : MvPowerSeries υ T} {a' : MvPowerSeries τ S} {b' : τ → MvPowerSeries υ T} [IsScalarTower R S T] From 717304de0c6c79468a1cee2a76f798f792c252be Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:31:34 +0000 Subject: [PATCH 0439/1300] chore(MeasureTheory/Measure/DiracProba): remove some defEq abuse (#40649) Co-authored-by: Batixx --- Mathlib/MeasureTheory/Measure/DiracProba.lean | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/DiracProba.lean b/Mathlib/MeasureTheory/Measure/DiracProba.lean index a2189b3c2f9972..ff2bc3cf3fd822 100644 --- a/Mathlib/MeasureTheory/Measure/DiracProba.lean +++ b/Mathlib/MeasureTheory/Measure/DiracProba.lean @@ -52,13 +52,11 @@ variable {X : Type*} [MeasurableSpace X] noncomputable def diracProba (x : X) : ProbabilityMeasure X := ⟨Measure.dirac x, Measure.dirac.isProbabilityMeasure⟩ -set_option backward.isDefEq.respectTransparency false in /-- The assignment `x ↦ diracProba x` is injective if all singletons are measurable. -/ lemma injective_diracProba {X : Type*} [MeasurableSpace X] [MeasurableSpace.SeparatesPoints X] : Function.Injective (fun (x : X) ↦ diracProba x) := by intro x y x_eq_y - rw [← dirac_eq_dirac_iff] - rwa [Subtype.ext_iff] at x_eq_y + simpa [diracProba, dirac_eq_dirac_iff] using congr(ProbabilityMeasure.toMeasure $x_eq_y) @[simp] lemma diracProba_toMeasure_apply' (x : X) {A : Set X} (A_mble : MeasurableSet A) : (diracProba x).toMeasure A = A.indicator 1 x := Measure.dirac_apply' x A_mble @@ -98,8 +96,7 @@ lemma not_tendsto_diracProba_of_not_tendsto [CompletelyRegularSpace X] {x : X} ( refine ⟨Ioi 0, Ioi_mem_nhds (by simp only [ENNReal.coe_one, zero_lt_one]), hU.mp (Eventually.of_forall ?_)⟩ intro x x_notin_U - rw [f_vanishes_outside x - (compl_subset_compl.mpr (show interior U ⊆ U from interior_subset) x_notin_U)] + rw [f_vanishes_outside x (compl_subset_compl.mpr interior_subset x_notin_U)] simp only [ENNReal.coe_zero, mem_Ioi, lt_self_iff_false, not_false_eq_true] lemma tendsto_diracProba_iff_tendsto [CompletelyRegularSpace X] {x : X} (L : Filter X) : From ed585ca0f67ec631ea987466127e022c11849b43 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Tue, 30 Jun 2026 08:24:21 +0000 Subject: [PATCH 0440/1300] chore: unsimp `Set.coe_setOf` (#39582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See [#mathlib4 > `Set.coe_setOf` @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.60Set.2Ecoe_setOf.60/near/579579409) --- Archive/Imo/Imo1987Q1.lean | 5 ++-- .../SimplicialSet/StdSimplex.lean | 6 ++-- .../Trigonometric/Inverse.lean | 3 +- .../CategoryTheory/GradedObject/Monoidal.lean | 4 +-- .../Sites/Coherent/RegularSheaves.lean | 7 +++-- Mathlib/CategoryTheory/Sites/IsSheafFor.lean | 2 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 4 +-- .../SimpleGraph/Connectivity/Finite.lean | 6 ++-- Mathlib/Data/Set/Basic.lean | 1 - Mathlib/Data/Set/Finite/Lattice.lean | 2 +- Mathlib/FieldTheory/SeparablyGenerated.lean | 22 +++++++------- Mathlib/GroupTheory/Perm/Finite.lean | 10 ++----- .../LinearAlgebra/RootSystem/OfBilinear.lean | 4 +-- Mathlib/NumberTheory/KummerDedekind.lean | 30 +++++++++---------- .../DedekindDomain/Ideal/Lemmas.lean | 2 +- 15 files changed, 52 insertions(+), 56 deletions(-) diff --git a/Archive/Imo/Imo1987Q1.lean b/Archive/Imo/Imo1987Q1.lean index 20c83703c77438..c352c7910d960e 100644 --- a/Archive/Imo/Imo1987Q1.lean +++ b/Archive/Imo/Imo1987Q1.lean @@ -44,9 +44,10 @@ def fixedPointsEquiv : { σx : α × Perm α // σx.2 σx.1 = σx.1 } ≃ Σ x : theorem card_fixed_points : card { σx : α × Perm α // σx.2 σx.1 = σx.1 } = card α * (card α - 1)! := by simp only [card_congr (fixedPointsEquiv α), card_sigma, card_perm] - have (x : _) : ({x}ᶜ : Set α) = Finset.filter (· ≠ x) Finset.univ := by + have h (x : α) : ({x}ᶜ : Set α) = Finset.univ.erase x := by ext; simp - simp [this] + simp_rw [h, Fintype.card_subtype, SetLike.mem_coe, Finset.filter_univ_mem] + simp /-- Given `α : Type*` and `k : ℕ`, `fiber α k` is the set of permutations of `α` with exactly `k` fixed points. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 329cf1f5e2c2ad..2e06c56fee1cb4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -625,12 +625,10 @@ identify to subsets of `Fin (n + 1)` of cardinality `d + 1`. -/ (Δ[n] : SSet.{u}).nonDegenerate d ≃ { S : Finset (Fin (n + 1)) | S.card = d + 1 } := Equiv.ofBijective _ (bijective_image_objEquiv_toOrderHom_univ n d) -set_option backward.isDefEq.respectTransparency false in lemma nonDegenerateEquiv'_iff {n d : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate d) (j : Fin (n + 1)) : j ∈ (nonDegenerateEquiv' x).val ↔ ∃ (i : Fin (d + 1)), x.val i = j := by - simp only [Set.mem_setOf_eq, Set.coe_setOf] - dsimp [nonDegenerateEquiv'] - aesop + unfold nonDegenerateEquiv' + simp set_option backward.defeqAttrib.useBackward true in /-- If `x` is a nondegenerate `d`-simplex of `Δ[n]`, this is the order isomorphism diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Inverse.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Inverse.lean index 0ce590a12f66f8..806794b8a9289b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Inverse.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Inverse.lean @@ -40,7 +40,8 @@ set_option backward.isDefEq.respectTransparency false in @[simp] theorem range_arcsin : range arcsin = Icc (-(π / 2)) (π / 2) := by rw [arcsin, range_comp Subtype.val] - simp [Icc] + ext + simp theorem arcsin_le_pi_div_two (x : ℝ) : arcsin x ≤ π / 2 := (arcsin_mem_Icc x).2 diff --git a/Mathlib/CategoryTheory/GradedObject/Monoidal.lean b/Mathlib/CategoryTheory/GradedObject/Monoidal.lean index f76ec435b1c719..23473068c5b53a 100644 --- a/Mathlib/CategoryTheory/GradedObject/Monoidal.lean +++ b/Mathlib/CategoryTheory/GradedObject/Monoidal.lean @@ -610,8 +610,8 @@ instance (n : ℕ) : Finite ({ i : (ℕ × ℕ × ℕ) | i.1 + i.2.1 + i.2.2 = n refine Finite.of_injective (fun ⟨⟨i₁, i₂, i₃⟩, (hi : i₁ + i₂ + i₃ = n)⟩ => (⟨⟨i₁, by lia⟩, ⟨i₂, by lia⟩, ⟨i₃, by lia⟩⟩ : Fin (n + 1) × Fin (n + 1) × Fin (n + 1))) ?_ - rintro ⟨⟨_, _, _⟩, _⟩ ⟨⟨_, _, _⟩, _⟩ h - simpa using h + intro _ _ h + exact Subtype.ext (congrArg (fun x => (x.1.1, x.2.1.1, x.2.2.1)) h) /-! The monoidal category structure on `GradedObject ℕ C` can be inferred diff --git a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean index 994ca69622a51f..50b5cccb9a70d0 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean @@ -107,7 +107,7 @@ theorem EqualizerCondition.bijective_mapToEqualizer_pullback' {P : Cᵒᵖ ⥤ T simpa [mapToEqualizer] using! ha₁ · intro y h apply ha₂ y - simpa [mapToEqualizer, Subtype.ext_iff] using! h + simpa [mapToEqualizer] using Subtype.ext_iff.1 h theorem EqualizerCondition.bijective_mapToEqualizer_pullback {P : Cᵒᵖ ⥤ Type*} (hP : EqualizerCondition P) {X B : C} (π : X ⟶ B) [EffectiveEpi π] [HasPullback π π] : @@ -126,10 +126,11 @@ theorem EqualizerCondition.mk' (P : Cᵒᵖ ⥤ Type*) intro b hb obtain ⟨a, ha₁, ha₂⟩ := hP ⟨b, hb⟩ refine ⟨a, ?_, ?_⟩ - · simpa [Subtype.ext_iff, mapToEqualizer] using! ha₁ + · simpa [mapToEqualizer] using Subtype.ext_iff.1 ha₁ · intro y h apply ha₂ y - simpa [mapToEqualizer, Subtype.ext_iff] using! h + ext + simpa [mapToEqualizer] using h set_option backward.isDefEq.respectTransparency false in theorem EqualizerCondition.mk (P : Cᵒᵖ ⥤ Type*) diff --git a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean index 139fcc18e1d29f..c80ad160c9acd2 100644 --- a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean +++ b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean @@ -557,7 +557,7 @@ theorem isSheafFor_iff_yonedaSheafCondition {P : Cᵒᵖ ⥤ Type v₁} : dsimp [functor] simp only [Subtype.forall, shrinkYonedaObjObjEquiv.forall_congr_left, Equiv.apply_symm_apply] congr! - simp [Equiv.subtypeEquiv] + simp /-- If `P` is a sheaf for the sieve `S` on `X`, a natural transformation from `S` (viewed as a functor) diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 56a4042b21ee1e..45cd429c4147d0 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -1440,7 +1440,7 @@ def shrinkFunctorUliftFunctorIso [LocallySmall.{w} C] [LocallySmall.{max w' w} C fun {U V} f ↦ by dsimp ext - dsimp [Equiv.subtypeEquiv] + dsimp [Equiv.subtypeEquiv_apply] rw [shrinkYonedaObjObjEquiv_obj_map, shrinkYonedaObjObjEquiv_symm_comp] simp @@ -1459,7 +1459,7 @@ variable (S) in noncomputable def shrinkFunctorIsoFunctor : (shrinkFunctor.{v₁} S).toFunctor ≅ S.functor := NatIso.ofComponents (fun Y ↦ Equiv.toIso <| Equiv.subtypeEquiv shrinkYonedaObjObjEquiv (by simp)) fun {U V} f ↦ by - dsimp [Equiv.subtypeEquiv] + dsimp [Equiv.subtypeEquiv_apply] ext simp [shrinkYonedaObjObjEquiv_obj_map] diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean index c1359d16dac765..0c265c4bdd44f5 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean @@ -114,9 +114,9 @@ lemma ncard_oddComponents_mono [Finite V] {G' : SimpleGraph V} (h : G ≤ G') : G'.oddComponents.ncard ≤ G.oddComponents.ncard := by have aux (c : G'.ConnectedComponent) (hc : Odd c.supp.ncard) : {c' : G.ConnectedComponent | Odd c'.supp.ncard ∧ c'.supp ⊆ c.supp}.Nonempty := by - refine Set.nonempty_of_ncard_ne_zero fun h' ↦ ?_ - simpa [-Nat.card_eq_fintype_card, -Set.coe_setOf, h'] - using (c.odd_oddComponents_ncard_subset_supp _ h).2 hc + refine Set.nonempty_of_ncard_ne_zero fun h' ↦ Nat.not_odd_zero ?_ + rw [← h'] + exact (c.odd_oddComponents_ncard_subset_supp _ h).2 hc let f : G'.oddComponents → G.oddComponents := fun ⟨c, hc⟩ ↦ ⟨(aux c hc).choose, (aux c hc).choose_spec.1⟩ refine Nat.card_le_card_of_injective f fun c c' fcc' ↦ ?_ diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index ba08bcb023d83b..9b17d3c22a16e8 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -142,7 +142,6 @@ instance (s : Set α) : CoeTC s α := ⟨fun x => x.1⟩ theorem Set.coe_eq_subtype (s : Set α) : ↥s = { x // x ∈ s } := rfl -@[simp] theorem Set.coe_setOf (p : α → Prop) : ↥{ x | p x } = { x // p x } := rfl diff --git a/Mathlib/Data/Set/Finite/Lattice.lean b/Mathlib/Data/Set/Finite/Lattice.lean index b748f7e9056729..5722f01641983a 100644 --- a/Mathlib/Data/Set/Finite/Lattice.lean +++ b/Mathlib/Data/Set/Finite/Lattice.lean @@ -269,7 +269,7 @@ variable {s t : Set α} theorem infinite_iUnion {ι : Type*} [Infinite ι] {s : ι → Set α} (hs : Function.Injective s) : (⋃ i, s i).Infinite := fun hfin ↦ @not_injective_infinite_finite ι _ _ hfin.finite_subsets.to_subtype - (fun i ↦ ⟨s i, subset_iUnion _ _⟩) fun i j h_eq ↦ hs (by simpa using h_eq) + (fun i ↦ ⟨s i, subset_iUnion _ _⟩) fun _ _ h_eq ↦ hs (Subtype.ext_iff.1 h_eq) theorem Infinite.biUnion {ι : Type*} {s : ι → Set α} {a : Set ι} (ha : a.Infinite) (hs : a.InjOn s) : (⋃ i ∈ a, s i).Infinite := by diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index 1ae054816114f6..64e81115ac3599 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -64,19 +64,21 @@ theorem aeval_toPolynomialAdjoinImageCompl_eq_zero simp_rw [toPolynomialAdjoinImageCompl, ← AlgEquiv.coe_toAlgHom, ← AlgHom.comp_apply] congr; ext; aesop (add simp optionEquivLeft_X_some) (add simp optionEquivLeft_X_none) -set_option backward.isDefEq.respectTransparency false in theorem irreducible_toPolynomialAdjoinImageCompl {F : MvPolynomial ι k} (hF : Irreducible F) (i : ι) (H : AlgebraicIndependent k fun x : {j | j ≠ i} ↦ a x) : Irreducible (toPolynomialAdjoinImageCompl F a i) := by - have : a '' {i}ᶜ = Set.range (fun x : {j | j ≠ i} ↦ a x) := by ext; simp - delta toPolynomialAdjoinImageCompl - convert! - hF.map (renameEquiv k (Equiv.optionSubtypeNe i).symm) |>.map (optionEquivLeft k _) |>.map - (Polynomial.mapAlgEquiv - (H.aevalEquiv.trans (Subalgebra.equivOfEq _ _ congr(Algebra.adjoin k $this.symm)))) - rw [← AlgEquiv.coe_toAlgHom] - congr - aesop + classical + unfold toPolynomialAdjoinImageCompl + have hc : a '' {i}ᶜ = Set.range (fun x : {j | j ≠ i} ↦ a x) := by ext; simp + let d : {j // j ≠ i} ≃ {j | j ≠ i} := .subtypeEquivRight (by simp) + refine (congrArg Irreducible ?_).mp <| + hF.map (renameEquiv k ((Equiv.optionSubtypeNe i).symm)) |>.map + (optionEquivLeft k _) |>.map (Polynomial.mapAlgEquiv <| + (renameEquiv k d).trans <| H.aevalEquiv.trans + (Subalgebra.equivOfEq _ _ congr(Algebra.adjoin k $hc.symm))) + rw [Polynomial.coe_mapAlgEquiv, Polynomial.coe_mapAlgHom] + refine congrFun (congrArg Polynomial.map ?_) _ + ext <;> simp [d] -- Suppose `F` has minimal total degree among the relations of `a`. variable {F : MvPolynomial ι k} diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index 929c5833c09478..4fbb18d909c321 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -125,7 +125,6 @@ theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : obtain ⟨y, hy⟩ := h ⟨r, rfl⟩ grind -set_option backward.isDefEq.respectTransparency false in theorem mem_sumCongrHom_range_of_perm_mapsTo_inl {m n : Type*} [Finite m] [Finite n] {σ : Perm (m ⊕ n)} (h : Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl)) : σ ∈ (sumCongrHom m n).range := by @@ -143,14 +142,11 @@ theorem mem_sumCongrHom_range_of_perm_mapsTo_inl {m n : Type*} [Finite m] [Finit rw [Perm.sumCongrHom_apply] ext (a | b) · rw [Equiv.sumCongr_apply, Sum.map_inl, permCongr_apply, Equiv.symm_symm, - apply_ofInjective_symm Sum.inl_injective] - rw [ofInjective_apply, Subtype.coe_mk, Subtype.coe_mk] - dsimp [Set.range] - rw [subtypePerm_apply] + apply_ofInjective_symm Sum.inl_injective, ofInjective_apply] + rfl · rw [Equiv.sumCongr_apply, Sum.map_inr, permCongr_apply, Equiv.symm_symm, apply_ofInjective_symm Sum.inr_injective, ofInjective_apply] - dsimp [Set.range] - rw [subtypePerm_apply] + rfl nonrec theorem Disjoint.orderOf {σ τ : Perm α} (hστ : Disjoint σ τ) : orderOf (σ * τ) = Nat.lcm (orderOf σ) (orderOf τ) := diff --git a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean index 6e3c62637c840b..ef492ed032e12a 100644 --- a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean +++ b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean @@ -160,8 +160,8 @@ def ofBilinear [IsReflexive R M] (B : M →ₗ[R] M →ₗ[R] R) (hNB : LinearMa right_inv := by intro y simp [involutive_reflection (coroot_apply_self B x.2) y] } - reflectionPerm_root x y := by - simp [Module.reflection_apply] + reflectionPerm_root := by + simp [coe_setOf, Module.reflection_apply] reflectionPerm_coroot x y := by simp only [coe_setOf, mem_setOf_eq, Embedding.coeFn_mk, Embedding.subtype_apply, Dual.eval_apply, Equiv.coe_fn_mk] diff --git a/Mathlib/NumberTheory/KummerDedekind.lean b/Mathlib/NumberTheory/KummerDedekind.lean index a295f1c42605fb..047f50d41348f1 100644 --- a/Mathlib/NumberTheory/KummerDedekind.lean +++ b/Mathlib/NumberTheory/KummerDedekind.lean @@ -205,8 +205,6 @@ theorem Ideal.irreducible_map_of_irreducible_minpoly (hI : IsMaximal I) (hI' : I rw [Multiset.attach_map_val, Multiset.map_singleton, Subtype.coe_mk] exact normalizedFactors_irreducible hf -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in open Set Classical in /-- Let `Q` be a lift of factor of the minimal polynomial of `x`, a generator of `S` over `R`, taken `mod I`. Then (the reduction of) `Q` corresponds via @@ -218,19 +216,19 @@ theorem normalizedFactorsMapEquivNormalizedFactorsMinPolyMk_symm_apply_eq_span (hI' : I ≠ ⊥) (hx : (conductor R x).comap (algebraMap R S) ⊔ I = ⊤) (hx' : IsIntegral R x) : ((normalizedFactorsMapEquivNormalizedFactorsMinPolyMk hI hI' hx hx').symm ⟨_, hQ⟩).val = span (I.map (algebraMap R S) ∪ {Q.aeval x}) := by - dsimp [normalizedFactorsMapEquivNormalizedFactorsMinPolyMk, - Ideal.normalizedFactorsEquivSpanNormalizedFactors] - rw [IsDedekindDomain.normalizedFactorsEquivOfQuotEquiv_symm] - dsimp [IsDedekindDomain.normalizedFactorsEquivOfQuotEquiv, - IsDedekindDomain.idealFactorsEquivOfQuotEquiv, OrderIso.ofHomInv] - simp only [map_span, image_singleton, coe_coe, quotMapEquivQuotQuotMap_symm_apply hx hx' Q] - refine le_antisymm (fun a ha ↦ ?_) (span_le.mpr <| union_subset_iff.mpr <| - ⟨le_comap_of_map_le (by simp), by simp⟩) - rw [mem_comap, Ideal.mem_span_singleton] at ha - obtain ⟨a', ha'⟩ := ha - obtain ⟨b, hb⟩ := Ideal.Quotient.mk_surjective a' - rw [← hb, ← map_mul, Quotient.mk_eq_mk_iff_sub_mem] at ha' - rw [union_comm, span_union, span_eq, mem_span_singleton_sup] - exact ⟨b, a - Q.aeval x * b, ha', by ring⟩ + unfold normalizedFactorsMapEquivNormalizedFactorsMinPolyMk + Ideal.normalizedFactorsEquivSpanNormalizedFactors + rw [Equiv.symm_trans_apply, IsDedekindDomain.normalizedFactorsEquivOfQuotEquiv_symm] + unfold IsDedekindDomain.normalizedFactorsEquivOfQuotEquiv + rw [Equiv.coe_fn_mk, Equiv.symm_symm, Equiv.ofBijective_apply] + dsimp only + unfold IsDedekindDomain.idealFactorsEquivOfQuotEquiv + rw [OrderIso.ofHomInv_apply] + erw [IsDedekindDomain.idealFactorsFunOfQuotHom_coe_coe] + dsimp only + rw [map_span, image_singleton, map_span, image_singleton, coe_coe, + quotMapEquivQuotQuotMap_symm_apply, span_union, span_eq, sup_comm, + ← image_singleton, ← map_span, Ideal.comap_map_of_surjective' _ Ideal.Quotient.mk_surjective, + Ideal.mk_ker] end KummerDedekind diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index edbb53bbc80601..9ee3f36a59bbc5 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -744,7 +744,7 @@ def normalizedFactorsEquivOfQuotEquiv (hI : I ≠ ⊥) (hJ : J ≠ ⊥) : idealFactorsEquivOfQuotEquiv_mem_normalizedFactors_of_mem_normalizedFactors f.symm hI j.prop⟩ left_inv := fun ⟨j, hj⟩ => by simp - right_inv := fun ⟨j, hj⟩ => by simp [-Set.coe_setOf] + right_inv := fun ⟨j, hj⟩ => by simp @[deprecated (since := "2026-04-16")] alias _root_.normalizedFactorsEquivOfQuotEquiv := normalizedFactorsEquivOfQuotEquiv From dc5088fcb8249e1d4a2fd6bbb3a7cce0afbc592b Mon Sep 17 00:00:00 2001 From: Sidharth Hariharan <64404030+thefundamentaltheor3m@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:14:58 +0000 Subject: [PATCH 0441/1300] feat: Monotonicity of `setIntegral` for nonnegative functions (#25778) This PR makes it easier to prove monotonicity of the Bochner integral on sets for nonnegative functions by removing the stronger assumption required by the general monotonicity lemma that both of the functions being compared must be integrable. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/MeasureTheory/Integral/Bochner/Set.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean index f226cd4de8fb9d..b1dce490b5b59a 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean @@ -885,6 +885,23 @@ lemma integral_le_measure {f : X → ℝ} {s : Set X} · intro x hx simpa [g] using h's x hx +lemma setIntegral_mono_of_nonneg {g : X → ℝ} (hf : ∀ x ∈ s, 0 ≤ f x) + (h : ∀ x ∈ s, f x ≤ g x) (hg : IntegrableOn g s μ) : + ∫ x in s, f x ∂μ ≤ ∫ x in s, g x ∂μ := by + by_cases h'f : AEStronglyMeasurable f (μ.restrict s); swap + · rw [integral_non_aestronglyMeasurable h'f] + apply integral_nonneg_of_ae + apply (ae_restrict_iff₀ ?_).2 + · filter_upwards with x hx using (hf x hx).trans (h x hx) + · exact nullMeasurableSet_le aemeasurable_const hg.aemeasurable + refine integral_mono_of_nonneg ?_ hg ?_ + · apply (ae_restrict_iff₀ ?_).2 + · filter_upwards with x hx using hf x hx + · exact nullMeasurableSet_le aemeasurable_const h'f.aemeasurable + · apply (ae_restrict_iff₀ ?_).2 + · filter_upwards with x hx using h x hx + · exact nullMeasurableSet_le h'f.aemeasurable hg.aemeasurable + end Nonneg section IntegrableUnion From 967fd0f04d607cf08e1c3d7051d2c8c4aaa80295 Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:15:01 +0000 Subject: [PATCH 0442/1300] feat(CategoryTheory): add `shrinkCoyoneda` (#41150) Add API for the co-Yoneda embedding of locally small categories, dual to the existing `shrinkYoneda`. --- Mathlib/CategoryTheory/ShrinkYoneda.lean | 184 +++++++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/Mathlib/CategoryTheory/ShrinkYoneda.lean b/Mathlib/CategoryTheory/ShrinkYoneda.lean index 9de58282348005..4973283a9cef7f 100644 --- a/Mathlib/CategoryTheory/ShrinkYoneda.lean +++ b/Mathlib/CategoryTheory/ShrinkYoneda.lean @@ -69,6 +69,8 @@ end FunctorToTypes variable [LocallySmall.{w} C] +section Yoneda + set_option backward.defeqAttrib.useBackward true in instance (X : C) : FunctorToTypes.Small.{w} (yoneda.obj X) := fun _ ↦ by dsimp; infer_instance @@ -249,4 +251,186 @@ def shrinkYonedaRepresentableBy (X : C) : (shrinkYoneda.{w}.obj X).Representable instance (X : C) : (shrinkYoneda.{w}.obj X).IsRepresentable := (shrinkYonedaRepresentableBy X).isRepresentable +end Yoneda + +section Coyoneda + +set_option backward.defeqAttrib.useBackward true in +instance (X : Cᵒᵖ) : FunctorToTypes.Small.{w} (coyoneda.obj X) := + fun _ ↦ by dsimp; infer_instance + +/-- The co-Yoneda embedding `Cᵒᵖ ⥤ C ⥤ Type w` for a locally `w`-small category `C`. -/ +@[pp_with_univ] +noncomputable abbrev shrinkCoyoneda : Cᵒᵖ ⥤ C ⥤ Type w := shrinkYoneda.flip + +lemma shrinkCoyoneda_obj {X : Cᵒᵖ} : + shrinkCoyoneda.obj X = FunctorToTypes.shrink (coyoneda.obj X) := rfl + +lemma shrinkCoyoneda_map {X Y : Cᵒᵖ} {f : X ⟶ Y} : + shrinkCoyoneda.map f = FunctorToTypes.shrinkMap (coyoneda.map f) := rfl + +/-- The type `(shrinkCoyoneda.obj X).obj Y` is equivalent to `X.unop ⟶ Y`. -/ +noncomputable abbrev shrinkCoyonedaObjObjEquiv {X : Cᵒᵖ} {Y : C} : + ((shrinkCoyoneda.{w}.obj X).obj Y) ≃ (X.unop ⟶ Y) := + shrinkYonedaObjObjEquiv + +lemma shrinkCoyoneda_obj_map_shrinkCoyonedaObjObjEquiv_symm + {X : Cᵒᵖ} {Y Y' : C} (g : Y ⟶ Y') (f : X.unop ⟶ Y) : + (shrinkCoyoneda.obj _).map g (shrinkCoyonedaObjObjEquiv.symm f) = + shrinkCoyonedaObjObjEquiv.symm (f ≫ g) := + shrinkYoneda_map_app_shrinkYonedaObjObjEquiv_symm f g + +lemma shrinkCoyonedaObjObjEquiv_symm_comp {X Y Y' : C} (g : Y' ⟶ Y) (f : Y ⟶ X) : + shrinkCoyonedaObjObjEquiv.symm (g ≫ f) = + (shrinkCoyoneda.obj _).map f (shrinkCoyonedaObjObjEquiv.symm g) := + (shrinkCoyoneda_obj_map_shrinkCoyonedaObjObjEquiv_symm f g).symm + +lemma shrinkCoyoneda_map_app_shrinkCoyonedaObjObjEquiv_symm + {X X' : Cᵒᵖ} {Y : C} (f : X.unop ⟶ Y) (g : X ⟶ X') : + (shrinkCoyoneda.map g).app _ (shrinkCoyonedaObjObjEquiv.symm f) = + shrinkCoyonedaObjObjEquiv.symm (g.unop ≫ f) := + shrinkYoneda_obj_map_shrinkYonedaObjObjEquiv_symm g f + +@[reassoc] +lemma shrinkCoyonedaObjObjEquiv_map_app + {X X' : Cᵒᵖ} {Y : C} (f : (shrinkCoyoneda.{w, v, u}.obj X).obj Y) (g : X ⟶ X') : + shrinkCoyonedaObjObjEquiv ((shrinkCoyoneda.map g).app Y f) = + g.unop ≫ shrinkCoyonedaObjObjEquiv f := + shrinkYonedaObjObjEquiv_obj_map g f + +@[reassoc] +lemma shrinkCoyonedaObjObjEquiv_obj_map {X : Cᵒᵖ} {Y Y' : C} (g : Y ⟶ Y') + (f : (shrinkCoyoneda.{w}.obj X).obj Y) : + shrinkCoyonedaObjObjEquiv ((shrinkCoyoneda.{w}.obj X).map g f) = + shrinkCoyonedaObjObjEquiv f ≫ g := + shrinkYonedaObjObjEquiv_map_app f g + +set_option backward.isDefEq.respectTransparency false in +/-- The type of natural transformations `shrinkCoyoneda.{w}.obj X ⟶ P` +with `X : Cᵒᵖ` and `P : C ⥤ Type w` is equivalent to `P.obj (op X)`. -/ +noncomputable def shrinkCoyonedaEquiv {X : Cᵒᵖ} {P : C ⥤ Type w} : + (shrinkCoyoneda.{w}.obj X ⟶ P) ≃ P.obj X.unop where + toFun τ := τ.app _ (equivShrink.{w} _ (𝟙 X.unop)) + invFun x := + { app Y := ↾fun f ↦ P.map ((equivShrink.{w} _).symm f) x + naturality Y Z g := by ext; simp [shrinkYoneda] } + left_inv τ := by + ext Y f + obtain ⟨f, rfl⟩ := (equivShrink _).surjective f + simpa [shrinkYoneda] using ((τ.naturality_apply f) (equivShrink _ (𝟙 X.unop))).symm + right_inv x := by simp + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma map_shrinkCoyonedaEquiv {X Y : Cᵒᵖ} {P : C ⥤ Type w} (f : shrinkCoyoneda.obj X ⟶ P) + (g : Y ⟶ X) : P.map g.unop (shrinkCoyonedaEquiv f) = + f.app Y.unop (shrinkCoyonedaObjObjEquiv.symm g.unop) := by + simp [shrinkYonedaObjObjEquiv, shrinkCoyonedaEquiv, shrinkYoneda, + ← comp_apply, ← NatTrans.naturality] + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma shrinkCoyonedaEquiv_shrinkCoyoneda_map {X Y : Cᵒᵖ} (f : X ⟶ Y) : + shrinkCoyonedaEquiv (shrinkCoyoneda.{w}.map f) = shrinkCoyonedaObjObjEquiv.symm f.unop := by + simp [shrinkCoyonedaEquiv, shrinkYoneda, shrinkYonedaObjObjEquiv] + +lemma shrinkCoyonedaEquiv_comp {X : Cᵒᵖ} {P Q : C ⥤ Type w} (α : shrinkCoyoneda.obj X ⟶ P) + (β : P ⟶ Q) : + shrinkCoyonedaEquiv (α ≫ β) = β.app _ (shrinkCoyonedaEquiv α) := by + simp [shrinkCoyonedaEquiv] + +set_option backward.isDefEq.respectTransparency false in +lemma shrinkCoyonedaEquiv_naturality {X Y : Cᵒᵖ} {P : C ⥤ Type w} + (f : shrinkCoyoneda.obj X ⟶ P) (g : Y ⟶ X) : + P.map g.unop (shrinkCoyonedaEquiv f) = shrinkCoyonedaEquiv (shrinkCoyoneda.map g ≫ f) := by + simpa [shrinkCoyonedaEquiv, shrinkYoneda] + using (f.naturality_apply g.unop ((equivShrink _) (𝟙 _))).symm + +@[reassoc] +lemma shrinkCoyonedaEquiv_symm_map {X Y : C} (f : X ⟶ Y) {P : C ⥤ Type w} (t : P.obj X) : + shrinkCoyonedaEquiv.symm (P.map f t) = + shrinkCoyoneda.map f.op ≫ shrinkCoyonedaEquiv.symm t := + shrinkCoyonedaEquiv.injective (by + obtain ⟨t, rfl⟩ := shrinkCoyonedaEquiv.surjective t + rw [← shrinkCoyonedaEquiv_naturality] + simp) + +lemma shrinkCoyonedaEquiv_symm_app_shrinkCoyonedaObjObjEquiv_symm {X : Cᵒᵖ} {P : C ⥤ Type w} + (s : P.obj X.unop) {Y : Cᵒᵖ} (f : Y ⟶ X) : + (shrinkCoyonedaEquiv.symm s).app Y.unop (shrinkCoyonedaObjObjEquiv.symm f.unop) = + P.map f.unop s := by + obtain ⟨g, rfl⟩ := shrinkCoyonedaEquiv.surjective s + simp [map_shrinkCoyonedaEquiv] + +variable (C) in +/-- The functor `shrinkCoyoneda : Cᵒᵖ ⥤ C ⥤ Type w` for a locally `w`-small category `C` +is fully faithful. -/ +noncomputable def fullyFaithfulShrinkCoyoneda : + (shrinkCoyoneda.{w} (C := C)).FullyFaithful where + preimage f := (shrinkCoyonedaObjObjEquiv (shrinkCoyonedaEquiv f)).op + map_preimage f := by + obtain ⟨f, rfl⟩ := shrinkCoyonedaEquiv.symm.surjective f + cat_disch + preimage_map f := by simp [shrinkCoyonedaEquiv_shrinkCoyoneda_map] + +instance : (shrinkCoyoneda.{w} (C := C)).Faithful := (fullyFaithfulShrinkCoyoneda C).faithful + +instance : (shrinkCoyoneda.{w} (C := C)).Full := (fullyFaithfulShrinkCoyoneda C).full + +set_option backward.defeqAttrib.useBackward true in +/-- `shrinkCoyoneda` at the morphism universe level is `coyoneda`. -/ +@[simps! hom_app inv_app] +noncomputable +def shrinkCoyonedaIsoCoyoneda : shrinkCoyoneda.{v} ≅ coyoneda (C := C) := + NatIso.ofComponents + (fun X ↦ NatIso.ofComponents (fun Y ↦ shrinkCoyonedaObjObjEquiv.toIso) + (by intros; ext; simp [shrinkYonedaObjObjEquiv_map_app])) + (by intros; ext; simp [shrinkYonedaObjObjEquiv_obj_map]) + +set_option backward.defeqAttrib.useBackward true in +/-- `shrinkCoyoneda` is compatible with `uliftFunctor`. -/ +noncomputable +def shrinkCoyonedaUliftFunctorIso [LocallySmall.{max w w'} C] : + shrinkCoyoneda.{w} ⋙ (Functor.whiskeringRight Cᵒᵖ _ _).obj uliftFunctor.{w', w} ≅ + shrinkCoyoneda := + NatIso.ofComponents + (fun X ↦ FunctorToTypes.shrinkCompUliftFunctorIso.{w, v} (coyoneda.obj X)) + fun _ ↦ by ext; simp [shrinkYoneda] + +/-- `uliftCoyoneda` identifies to `shrinkCoyoneda`. -/ +noncomputable def uliftYonedaIsoShrinkCoyoneda : + uliftCoyoneda.{w'} (C := C) ≅ shrinkCoyoneda.{max w' v} := + NatIso.ofComponents (fun X ↦ NatIso.ofComponents + (fun Y ↦ (Equiv.ulift.trans shrinkCoyonedaObjObjEquiv.symm).toIso) (fun f ↦ by + ext + exact (shrinkCoyoneda_obj_map_shrinkCoyonedaObjObjEquiv_symm _ _).symm)) (fun g ↦ by + ext + exact (shrinkCoyoneda_map_app_shrinkCoyonedaObjObjEquiv_symm _ _).symm) + +set_option backward.defeqAttrib.useBackward true in +/-- The functor `shrinkCoyoneda.{w}` followed by the evaluation +at `Y : C` and `uliftFunctor.{v}` identifies to `yoneda.obj Y` followed +by `uliftFunctor.{w}`. -/ +noncomputable def shrinkCoyonedaCompEvaluationCompUliftFunctorIsoUliftFunctor (Y : C) : + shrinkCoyoneda.{w} ⋙ (evaluation C _).obj Y ⋙ uliftFunctor.{v} ≅ + yoneda.obj Y ⋙ uliftFunctor.{w} := + NatIso.ofComponents (fun X ↦ (Equiv.ulift.trans + (shrinkCoyonedaObjObjEquiv.trans Equiv.ulift.symm)).toIso) (fun f ↦ by + ext ⟨g⟩ + obtain ⟨g, rfl⟩ := shrinkCoyonedaObjObjEquiv.symm.surjective g + simp [shrinkYoneda, shrinkYonedaObjObjEquiv]) + +/-- `shrinkCoyoneda.obj X` is corepresented by `X`. -/ +@[simps] +noncomputable +def shrinkCoyonedaCorepresentableBy (X : Cᵒᵖ) : + (shrinkCoyoneda.{w}.obj X).CorepresentableBy X.unop where + homEquiv := shrinkCoyonedaObjObjEquiv.symm + homEquiv_comp f g := shrinkCoyonedaObjObjEquiv_symm_comp g f + +instance (X : Cᵒᵖ) : (shrinkCoyoneda.{w}.obj X).IsCorepresentable := + (shrinkCoyonedaCorepresentableBy X).isCorepresentable + +end Coyoneda + end CategoryTheory From b53180c4e86592936310cfdf78dc749285f34890 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:15:04 +0000 Subject: [PATCH 0443/1300] feat: more API around enorms of operators (#41155) Co-authored-by: sgouezel --- Mathlib/Analysis/Analytic/Constructions.lean | 2 +- Mathlib/Analysis/Normed/Group/Continuity.lean | 5 ++++ Mathlib/Analysis/Normed/Operator/Basic.lean | 20 ------------- .../Analysis/Normed/Operator/Bilinear.lean | 22 +++++++++++--- Mathlib/Analysis/Normed/Operator/Mul.lean | 19 ++++++++++++ Mathlib/Analysis/Normed/Operator/NNNorm.lean | 30 ++++++++++++++++++- .../Geometry/Manifold/Riemannian/Basic.lean | 4 +-- .../MeasureTheory/VectorMeasure/Integral.lean | 2 +- .../Variation/Semivariation.lean | 4 +-- .../Moments/CovarianceBilinDual.lean | 4 +-- 10 files changed, 79 insertions(+), 33 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Constructions.lean b/Mathlib/Analysis/Analytic/Constructions.lean index 8cf6ff6eaaf355..44c8d8cc59f201 100644 --- a/Mathlib/Analysis/Analytic/Constructions.lean +++ b/Mathlib/Analysis/Analytic/Constructions.lean @@ -743,7 +743,7 @@ theorem HasFPowerSeriesWithinOnBall.compContinuousLinearMap · simp only [Set.mem_insert_iff, add_eq_left, Set.mem_preimage, map_add] at hy1 ⊢ rcases hy1 with (hy1 | hy1) <;> simp [hy1] · simp only [Metric.eball, edist_zero_right, Set.mem_setOf_eq] at hy2 ⊢ - exact lt_of_le_of_lt (ContinuousLinearMap.le_opNorm_enorm _ _) (mul_lt_of_lt_div' hy2) + exact lt_of_le_of_lt (ContinuousLinearMap.le_opENorm _ _) (mul_lt_of_lt_div' hy2) theorem HasFPowerSeriesOnBall.compContinuousLinearMap (hf : HasFPowerSeriesOnBall f pf (u x) r) : HasFPowerSeriesOnBall (f ∘ u) (pf.compContinuousLinearMap u) x (r / ‖u‖ₑ) := by diff --git a/Mathlib/Analysis/Normed/Group/Continuity.lean b/Mathlib/Analysis/Normed/Group/Continuity.lean index bce9c2ecb79818..e4e9048e9eaae7 100644 --- a/Mathlib/Analysis/Normed/Group/Continuity.lean +++ b/Mathlib/Analysis/Normed/Group/Continuity.lean @@ -313,6 +313,11 @@ theorem tendsto_iff_norm_div_tendsto_zero {f : α → E} {a : Filter α} {b : E} Tendsto f a (𝓝 b) ↔ Tendsto (fun e => ‖f e / b‖) a (𝓝 0) := by simp only [← dist_eq_norm_div, ← tendsto_iff_dist_tendsto_zero] +@[to_additive] +theorem tendsto_iff_enorm_div_tendsto_zero {f : α → E} {a : Filter α} {b : E} : + Tendsto f a (𝓝 b) ↔ Tendsto (fun e => ‖f e / b‖ₑ) a (𝓝 0) := by + simp only [← edist_eq_enorm_div, ← tendsto_iff_edist_tendsto_0] + @[to_additive] theorem SeminormedCommGroup.mem_closure_iff {s : Set E} : a ∈ closure s ↔ ∀ ε, 0 < ε → ∃ b ∈ s, ‖a / b‖ < ε := by diff --git a/Mathlib/Analysis/Normed/Operator/Basic.lean b/Mathlib/Analysis/Normed/Operator/Basic.lean index ce13673e1274a1..ada43ae7b633c5 100644 --- a/Mathlib/Analysis/Normed/Operator/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Basic.lean @@ -412,26 +412,6 @@ variable [RingHomIsometric σ₁₂] (f : E →SL[σ₁₂] F) @[simp, nontriviality] theorem opNorm_subsingleton [Subsingleton E] : ‖f‖ = 0 := norm_of_subsingleton f -/-- The fundamental property of the operator norm, expressed with extended norms: -`‖f x‖ₑ ≤ ‖f‖ₑ * ‖x‖ₑ`. -/ -lemma le_opNorm_enorm (x : E) : ‖f x‖ₑ ≤ ‖f‖ₑ * ‖x‖ₑ := by - simp_rw [← ofReal_norm] - rw [← ENNReal.ofReal_mul (by positivity)] - gcongr - exact f.le_opNorm x - -/-- If one controls the enorm of every `f x`, then one controls the enorm of `f`. -/ -theorem opENorm_le_bound (f : E →SL[σ₁₂] F) {M : ℝ≥0∞} (hM : ∀ x, ‖f x‖ₑ ≤ M * ‖x‖ₑ) : - ‖f‖ₑ ≤ M := by - rcases eq_top_or_lt_top M with rfl | h'M - · simp - lift M to NNReal using h'M.ne - simp only [← ofReal_norm, ENNReal.ofReal_le_coe] - apply opNorm_le_bound _ (by positivity) (fun x ↦ ?_) - specialize hM x - simp only [← ofReal_norm, ← ENNReal.ofReal_coe_nnreal] at hM - rwa [← ENNReal.ofReal_mul (by positivity), ENNReal.ofReal_le_ofReal_iff (by positivity)] at hM - variable {f} in theorem homothety_norm [NontrivialTopology E] (f : E →SL[σ₁₂] F) {a : ℝ} (hf : ∀ x, ‖f x‖ = a * ‖x‖) : ‖f‖ = a := by diff --git a/Mathlib/Analysis/Normed/Operator/Bilinear.lean b/Mathlib/Analysis/Normed/Operator/Bilinear.lean index 187148928cc83d..d8d68e766caf5d 100644 --- a/Mathlib/Analysis/Normed/Operator/Bilinear.lean +++ b/Mathlib/Analysis/Normed/Operator/Bilinear.lean @@ -5,7 +5,7 @@ Authors: Jan-David Salchow, Sébastien Gouëzel, Jean Lo -/ module -public import Mathlib.Analysis.Normed.Operator.Basic +public import Mathlib.Analysis.Normed.Operator.NNNorm public import Mathlib.Analysis.Normed.Operator.LinearIsometry public import Mathlib.Analysis.Normed.Operator.ContinuousLinearMap @@ -59,24 +59,30 @@ theorem opNorm_ext [RingHomIsometric σ₁₃] (f : E →SL[σ₁₂] F) (g : E rw [← h z] exact h₂ z - variable [RingHomIsometric σ₂₃] theorem opNorm_le_bound₂ (f : E →SL[σ₁₃] F →SL[σ₂₃] G) {C : ℝ} (h0 : 0 ≤ C) (hC : ∀ x y, ‖f x y‖ ≤ C * ‖x‖ * ‖y‖) : ‖f‖ ≤ C := f.opNorm_le_bound h0 fun x => (f x).opNorm_le_bound (by positivity) <| hC x - theorem le_opNorm₂ [RingHomIsometric σ₁₃] (f : E →SL[σ₁₃] F →SL[σ₂₃] G) (x : E) (y : F) : ‖f x y‖ ≤ ‖f‖ * ‖x‖ * ‖y‖ := (f x).le_of_opNorm_le (f.le_opNorm x) y - theorem le_of_opNorm₂_le_of_le [RingHomIsometric σ₁₃] (f : E →SL[σ₁₃] F →SL[σ₂₃] G) {x : E} {y : F} {a b c : ℝ} (hf : ‖f‖ ≤ a) (hx : ‖x‖ ≤ b) (hy : ‖y‖ ≤ c) : ‖f x y‖ ≤ a * b * c := (f x).le_of_opNorm_le_of_le (f.le_of_opNorm_le_of_le hf hx) hy +open scoped ENNReal + +theorem opENorm_le_bound₂ [RingHomIsometric σ₁₃] (f : E →SL[σ₁₃] F →SL[σ₂₃] G) {C : ℝ≥0∞} + (hC : ∀ x y, ‖f x y‖ₑ ≤ C * ‖x‖ₑ * ‖y‖ₑ) : ‖f‖ₑ ≤ C := + f.opENorm_le_bound fun x => (f x).opENorm_le_bound <| hC x + +theorem le_opENorm₂ [RingHomIsometric σ₁₃] (f : E →SL[σ₁₃] F →SL[σ₂₃] G) (x : E) (y : F) : + ‖f x y‖ₑ ≤ ‖f‖ₑ * ‖x‖ₑ * ‖y‖ₑ := + (f x).le_of_opENorm_le (f.le_opENorm x) y end OpNorm @@ -165,6 +171,14 @@ theorem flip_flip (f : E →SL[σ₁₃] F →SL[σ₂₃] G) : f.flip.flip = f theorem opNorm_flip (f : E →SL[σ₁₃] F →SL[σ₂₃] G) : ‖f.flip‖ = ‖f‖ := le_antisymm (by simpa only [flip_flip] using le_norm_flip f.flip) (le_norm_flip f) +@[simp] +theorem opNNNorm_flip (f : E →SL[σ₁₃] F →SL[σ₂₃] G) : ‖f.flip‖₊ = ‖f‖₊ := by + simp [← NNReal.coe_inj] + +@[simp] +theorem opENorm_flip (f : E →SL[σ₁₃] F →SL[σ₂₃] G) : ‖f.flip‖ₑ = ‖f‖ₑ := by + simp [enorm_eq_nnnorm] + @[simp] lemma flip_zero : flip (0 : E →SL[σ₁₃] F →SL[σ₂₃] G) = 0 := rfl diff --git a/Mathlib/Analysis/Normed/Operator/Mul.lean b/Mathlib/Analysis/Normed/Operator/Mul.lean index 1ed482a0a80254..3cf11c69837973 100644 --- a/Mathlib/Analysis/Normed/Operator/Mul.lean +++ b/Mathlib/Analysis/Normed/Operator/Mul.lean @@ -221,6 +221,10 @@ theorem opNNNorm_lsmul_le : ‖(lsmul 𝕜 R : R →L[𝕜] E →L[𝕜] E)‖ rw [← NNReal.coe_le_coe] simpa using opNorm_lsmul_le +theorem opENorm_lsmul_le : ‖(lsmul 𝕜 R : R →L[𝕜] E →L[𝕜] E)‖ₑ ≤ 1 := by + rw [enorm_eq_nnnorm] + simpa using opNNNorm_lsmul_le + end SMulLinear end ContinuousLinearMap @@ -247,6 +251,10 @@ theorem opNorm_mul : ‖mul 𝕜 R‖ = 1 := theorem opNNNorm_mul : ‖mul 𝕜 R‖₊ = 1 := Subtype.ext <| opNorm_mul 𝕜 R +@[simp] +theorem opENorm_mul : ‖mul 𝕜 R‖ₑ = 1 := by + simp [enorm_eq_nnnorm] + end /-- The norm of `lsmul` equals 1 in any nontrivial normed group. @@ -268,6 +276,11 @@ theorem opNNNorm_lsmul [NormedDivisionRing R] [NormedAlgebra 𝕜 R] [Module R E rw [← NNReal.coe_inj] simp +@[simp] +theorem opENorm_lsmul [NormedDivisionRing R] [NormedAlgebra 𝕜 R] [Module R E] [NormSMulClass R E] + [IsScalarTower 𝕜 R E] [Nontrivial E] : ‖(lsmul 𝕜 R : R →L[𝕜] E →L[𝕜] E)‖ₑ = 1 := by + simp [enorm_eq_nnnorm] + /-- The norm of `lsmul x` equals `‖x‖` in any nontrivial normed group. This is `ContinuousLinearMap.opNorm_lsmul_apply_le` as an equality. -/ @@ -288,6 +301,12 @@ theorem opNNNorm_lsmul_apply [NormedDivisionRing R] [NormedAlgebra 𝕜 R] [Modu rw [← NNReal.coe_inj] simp +@[simp] +theorem opENorm_lsmul_apply [NormedDivisionRing R] [NormedAlgebra 𝕜 R] [Module R E] + [NormSMulClass R E] [IsScalarTower 𝕜 R E] [Nontrivial E] {a : R} : + ‖(lsmul 𝕜 R a : E →L[𝕜] E)‖ₑ = ‖a‖ₑ := by + simp [enorm_eq_nnnorm] + end ContinuousLinearMap end Normed diff --git a/Mathlib/Analysis/Normed/Operator/NNNorm.lean b/Mathlib/Analysis/Normed/Operator/NNNorm.lean index 0eff611679c554..f2ae9cbd2f6026 100644 --- a/Mathlib/Analysis/Normed/Operator/NNNorm.lean +++ b/Mathlib/Analysis/Normed/Operator/NNNorm.lean @@ -21,7 +21,7 @@ suppress_compilation open Bornology open Filter hiding map_smul -open scoped NNReal Topology Uniformity +open scoped NNReal Topology Uniformity ENNReal open Metric ContinuousLinearMap open Set Real @@ -88,6 +88,34 @@ theorem le_opNNNorm (f : E →SL[σ₁₂] F) (x : E) : ‖f x‖₊ ≤ ‖f‖ lemma le_opENorm (f : E →SL[σ₁₂] F) (x : E) : ‖f x‖ₑ ≤ ‖f‖ₑ * ‖x‖ₑ := by dsimp [enorm]; exact mod_cast le_opNNNorm .. +@[deprecated (since := "2026-06-27")] alias le_opNorm_enorm := le_opENorm + +/-- If one controls the enorm of every `f x`, then one controls the enorm of `f`. -/ +theorem opENorm_le_bound (f : E →SL[σ₁₂] F) {M : ℝ≥0∞} (hM : ∀ x, ‖f x‖ₑ ≤ M * ‖x‖ₑ) : + ‖f‖ₑ ≤ M := by + rcases eq_top_or_lt_top M with rfl | h'M + · simp + lift M to NNReal using h'M.ne + simp only [← ofReal_norm, ENNReal.ofReal_le_coe] + apply opNorm_le_bound _ (by positivity) (fun x ↦ ?_) + specialize hM x + simp only [← ofReal_norm, ← ENNReal.ofReal_coe_nnreal] at hM + rwa [← ENNReal.ofReal_mul (by positivity), ENNReal.ofReal_le_ofReal_iff (by positivity)] at hM + +theorem le_of_opENorm_le_of_le (f : E →SL[σ₁₂] F) {x} {a b : ℝ≥0∞} (hf : ‖f‖ₑ ≤ a) (hx : ‖x‖ₑ ≤ b) : + ‖f x‖ₑ ≤ a * b := + (f.le_opENorm x).trans <| by gcongr + +theorem le_opENorm_of_le (f : E →SL[σ₁₂] F) {c : ℝ≥0∞} {x} (h : ‖x‖ₑ ≤ c) : ‖f x‖ₑ ≤ ‖f‖ₑ * c := + f.le_of_opENorm_le_of_le le_rfl h + +theorem le_of_opENorm_le (f : E →SL[σ₁₂] F) {c : ℝ≥0∞} (h : ‖f‖ₑ ≤ c) (x : E) : ‖f x‖ₑ ≤ c * ‖x‖ₑ := + f.le_of_opENorm_le_of_le h le_rfl + +theorem opENorm_le_iff {f : E →SL[σ₁₂] F} {M : ℝ≥0∞} : + ‖f‖ₑ ≤ M ↔ ∀ x, ‖f x‖ₑ ≤ M * ‖x‖ₑ := + ⟨f.le_of_opENorm_le, opENorm_le_bound f⟩ + theorem nndist_le_opNNNorm (f : E →SL[σ₁₂] F) (x y : E) : nndist (f x) (f y) ≤ ‖f‖₊ * nndist x y := dist_le_opNorm f x y diff --git a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean index 7ddda591cfd451..aca6592592b743 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean @@ -363,7 +363,7 @@ lemma eventually_riemannianEDist_le_edist_extChartAt (x : M) : have : mfderiv[Icc 0 1] γ t 1 = (mfderiv[range I] (extChartAt I x).symm (η t)) (mfderiv[Icc 0 1] η t 1) := congr($this 1) rw [this] - apply (ContinuousLinearMap.le_opNorm_enorm _ _).trans + apply (ContinuousLinearMap.le_opENorm _ _).trans gcongr · exact (hη.2 ht).le · simp only [mfderivWithin_eq_fderivWithin] @@ -474,7 +474,7 @@ lemma setOf_riemannianEDist_lt_subset_nhds [RegularSpace M] {x : M} {s : Set M} (mfderiv% (extChartAt I x) (γ t')) (mfderiv[Icc 0 t₁] γ t' 1) := congr($this 1) rw [this] - apply (ContinuousLinearMap.le_opNorm_enorm _ _).trans + apply (ContinuousLinearMap.le_opENorm _ _).trans gcongr refine (hu ?_).le apply t₁_mem ht' diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index bc0a720f0b4a69..d82e901ee3ed54 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -174,7 +174,7 @@ lemma variation_transpose_le : apply opENorm_le_bound _ (fun x ↦ ?_) simp only [transpose, mapRange_apply, LinearMap.toAddMonoidHom_coe, coe_coe, flip_apply, Measure.smul_apply, Measure.nnreal_smul_coe_apply] - grw [le_opNorm_enorm, le_opNorm_enorm, enorm_measure_le_variation, ← enorm_eq_nnnorm] + grw [le_opENorm, le_opENorm, enorm_measure_le_variation, ← enorm_eq_nnnorm] exact le_of_eq (by ring) lemma absolutelyContinuous_variation_transpose (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean index 06c83d0549c4b9..baa4b3ca053d65 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean @@ -74,7 +74,7 @@ lemma semivariation_le_variation : μ.semivariation s ≤ μ.variation s := by apply variation_le_of_forall_enorm_le (fun t ht ↦ ?_) simp only [mapRange_apply, AddMonoidHom.coe_coe] apply le_trans ?_ (enorm_measure_le_variation _ _) - exact (ContinuousLinearMap.le_opNorm_enorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) + exact (ContinuousLinearMap.le_opENorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) lemma enorm_apply_le_semivariation : ‖μ s‖ₑ ≤ μ.semivariation s := by by_cases hs : MeasurableSet s; swap @@ -102,7 +102,7 @@ lemma exists_subset_lt_enorm_apply_of_lt_semivariation (hs : MeasurableSet s) SignedMeasure.exists_subset_lt_enorm_apply_of_lt_variation _ hs h'ℓ refine ⟨t, ts, t_meas, ht.trans_le ?_⟩ gcongr - exact (ContinuousLinearMap.le_opNorm_enorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) + exact (ContinuousLinearMap.le_opENorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) private lemma exists_one_le_enorm_apply_of_semivariation_eq_top (hs : MeasurableSet s) (h's : μ.semivariation s = ∞) : diff --git a/Mathlib/Probability/Moments/CovarianceBilinDual.lean b/Mathlib/Probability/Moments/CovarianceBilinDual.lean index 4e017ec7919830..b6270b417c8f6b 100644 --- a/Mathlib/Probability/Moments/CovarianceBilinDual.lean +++ b/Mathlib/Probability/Moments/CovarianceBilinDual.lean @@ -91,7 +91,7 @@ lemma norm_toLpₗ_le [OpensMeasurableSpace E] (L : StrongDual 𝕜 E) : gcongr · rw [ENNReal.essSup_const_mul] exact ENNReal.mul_ne_top (by simp) h_Lp.eLpNorm_ne_top - · exact essSup_mono_ae <| ae_of_all _ L.le_opNorm_enorm + · exact essSup_mono_ae <| ae_of_all _ L.le_opENorm have h0 : 0 < p.toReal := by simp [ENNReal.toReal_pos_iff, pos_iff_ne_zero, hp, Ne.lt_top hp_top] suffices ‖L.toLpₗ μ p‖ ≤ (‖L‖ₑ ^ p.toReal * ∫⁻ x, ‖x‖ₑ ^ p.toReal ∂μ).toReal ^ p.toReal⁻¹ by @@ -119,7 +119,7 @@ lemma norm_toLpₗ_le [OpensMeasurableSpace E] (L : StrongDual 𝕜 E) : rw [← ENNReal.mul_rpow_of_nonneg] swap; · positivity gcongr - exact L.le_opNorm_enorm x + exact L.le_opENorm x _ = ‖L‖ₑ ^ p.toReal * ∫⁻ x, ‖x‖ₑ ^ p.toReal ∂μ := by rw [lintegral_const_mul]; fun_prop end LinearMap From 80c8d53c29ea05793f75cffa8adf32229c4eaf38 Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:15:06 +0000 Subject: [PATCH 0444/1300] feat(Geometry/Manifold): models with corners are smooth embeddings (#41164) Every model with corners is a smooth embedding of the model space into the model vector space. --- Mathlib/Geometry/Manifold/Immersion.lean | 26 +++++++++++++++++++ .../Geometry/Manifold/SmoothEmbedding.lean | 6 +++++ 2 files changed, 32 insertions(+) diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index 852f775a9a4acd..8d81f03d5e84e4 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -54,6 +54,7 @@ This shortens the overall argument, as the definition of submersions has the sam * `IsImmersion.id`: the identity map is an immersion * `IsImmersion.of_opens`: the inclusion of an open subset `s → M` of a smooth manifold is a smooth immersion +* `ModelWithCorners.isImmersion`: every model with corners is itself an immersion * `IsImmersionOfComplement.sumInl` and `IsImmersionOfComplement.sumInr`: given `C^n` manifolds `M` and `N`, `Sum.inl : M → M ⊕ N` and `Sum.inr : N → M ⊕ N` are `C^n` immersions * `IsImmersionAt.contMDiffAt`: if f is an immersion at `x`, it is `C^n` at `x`. @@ -391,6 +392,14 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) (y : s) : suffices I ((chartAt H ↑y) ((chartAt H y).symm (I.symm x))) = x by simpa +contextual simp_all +/-- Every `ModelWithCorners 𝕜 E H` is an immersion when viewed as a map `H → E`. -/ +protected lemma _root_.ModelWithCorners.isImmersionAtOfComplement {n : ℕ} {x : H} : + IsImmersionAtOfComplement PUnit I 𝓘(𝕜, E) n I x := + Manifold.IsImmersionAtOfComplement.mk_of_continuousAt I.continuousAt + (.prodUnique _ _ _) (.refl _) (.refl _) (by simp) (by simp) + (IsManifold.subset_maximalAtlas (by simp)) (IsManifold.subset_maximalAtlas (by simp)) + (by simp [Function.comp_def]) + @[deprecated (since := "2025-12-16")] alias ofOpen := of_opens /-- Prefer using `IsImmersionAtOfComplement.continuousAt` instead -/ @@ -589,6 +598,12 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) (hx : x ∈ s) @[deprecated (since := "2025-12-16")] alias ofOpen := of_opens +/-- Every `ModelWithCorners 𝕜 E H` is an immersion when viewed as a map `H → E`. -/ +protected lemma _root_.ModelWithCorners.isImmersionAt {n : ℕ} {x : H} : + IsImmersionAt I (modelWithCornersSelf 𝕜 E) n I x := by + use PUnit, by infer_instance, by infer_instance + exact I.isImmersionAtOfComplement + /-- Prefer using `IsImmersionAt.continuousAt` instead -/ theorem continuousOn (h : IsImmersionAt I J n f x) : ContinuousOn f h.domChart.source := h.isImmersionAtOfComplement_complement.continuousOn @@ -699,6 +714,11 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) : IsImmersionOfComplement PUnit I I n (Subtype.val : s → M) := fun y ↦ IsImmersionAtOfComplement.of_opens s y +/-- Every `ModelWithCorners 𝕜 E H` is an immersion when viewed as a map `H → E`. -/ +protected lemma _root_.ModelWithCorners.isImmersionOfComplement {n : ℕ} : + IsImmersionOfComplement PUnit I (modelWithCornersSelf 𝕜 E) n I := + fun _ ↦ I.isImmersionAtOfComplement + /-- Given `C^n` manifolds `M` and `N` over the same model `I`, `Sum.inl : M → M ⊕ N` is a `C^n` immersion with complement `Unit` -/ lemma sumInl {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] [IsManifold I n M] @@ -794,6 +814,12 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) : @[deprecated (since := "2025-12-16")] alias ofOpen := of_opens +/-- Every `ModelWithCorners 𝕜 E H` is an immersion when viewed as a map `H → E`. -/ +protected lemma _root_.ModelWithCorners.isImmersion {n : ℕ} : + IsImmersion I (modelWithCornersSelf 𝕜 E) n I := by + use PUnit, by infer_instance, by infer_instance + exact I.isImmersionOfComplement + /-- A `C^n` immersion is `C^n`. -/ theorem contMDiff (h : IsImmersion I J n f) : CMDiff n f := diff --git a/Mathlib/Geometry/Manifold/SmoothEmbedding.lean b/Mathlib/Geometry/Manifold/SmoothEmbedding.lean index 14656f059daa50..622c8297de17e2 100644 --- a/Mathlib/Geometry/Manifold/SmoothEmbedding.lean +++ b/Mathlib/Geometry/Manifold/SmoothEmbedding.lean @@ -22,6 +22,7 @@ This will be useful to define embedded submanifolds. * `IsSmoothEmbedding.id`: the identity map is a smooth embedding * `IsSmoothEmbedding.of_opens`: the inclusion of an open subset `s → M` of a smooth manifold is a smooth embedding +* `ModelWithCorners.isSmoothEmbedding`: every model with corners is itself a smooth embedding * `IsSmoothEmbedding.sumInl` and `IsSmoothEmbedding.sumInr`: given `C^n` manifolds `M` and `N`, `Sum.inl : M → M ⊕ N` and `Sum.inr : N → M ⊕ N` are `C^n` embeddings * `IsSmoothEmbedding.contMDiff`: if `f` is a `C^n` embedding, it is automatically `C^n` @@ -94,6 +95,11 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) : rw [isSmoothEmbedding_iff] exact ⟨IsImmersion.of_opens s, IsEmbedding.subtypeVal⟩ +/-- Every `ModelWithCorners 𝕜 E H` is a smooth embedding when viewed as a map `H → E`. -/ +protected lemma _root_.ModelWithCorners.isSmoothEmbedding {n : ℕ} : + IsSmoothEmbedding I (modelWithCornersSelf 𝕜 E₁) n I := + ⟨I.isImmersion, I.isClosedEmbedding.isEmbedding⟩ + /-- Given `C^n` manifolds `M` and `N`, `Sum.inl : M → M ⊕ N` is a `C^n` embedding. -/ lemma sumInl {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] [IsManifold I n M] [IsManifold I n M'] : IsSmoothEmbedding I I n (@Sum.inl M M') := From c108fbdaf5f6b7e61785f23298686744492d949c Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:52:40 +0000 Subject: [PATCH 0445/1300] chore(CategoryTheory): thin categories have strict initial and terminal objects (#41037) --- Mathlib/CategoryTheory/Iso.lean | 3 +++ .../CategoryTheory/Limits/Shapes/StrictInitial.lean | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/Mathlib/CategoryTheory/Iso.lean b/Mathlib/CategoryTheory/Iso.lean index c7df4b48b8681a..e2018dc0a520f5 100644 --- a/Mathlib/CategoryTheory/Iso.lean +++ b/Mathlib/CategoryTheory/Iso.lean @@ -391,6 +391,9 @@ theorem isIso_of_hom_comp_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : g ≫ rw [(hom_comp_eq_id _).mp h] infer_instance +lemma isIso_iff_of_thin [Quiver.IsThin C] {X Y : C} (f : X ⟶ Y) : IsIso f ↔ Nonempty (Y ⟶ X) := + ⟨fun _ ↦ ⟨inv f⟩, fun g ↦ ⟨g.some, Subsingleton.elim _ _, Subsingleton.elim _ _⟩⟩ + namespace Iso @[aesop apply safe (rule_sets := [CategoryTheory]), to_dual none] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean b/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean index a6b167a4344f0d..4b0713b479ab5b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean @@ -156,6 +156,11 @@ theorem hasStrictInitialObjects_of_initial_is_strict [HasInitial C] haveI := h A (f ≫ hI.to _) ⟨⟨hI.to _ ≫ inv (f ≫ hI.to (⊥_ C)), by rw [← assoc, IsIso.hom_inv_id], hI.hom_ext _ _⟩⟩ } +instance [Quiver.IsThin C] : HasStrictInitialObjects C where + out {I A} f hI := by + rw [isIso_iff_of_thin] + exact ⟨hI.to _⟩ + end StrictInitial section StrictTerminal @@ -252,6 +257,11 @@ theorem hasStrictTerminalObjects_of_terminal_is_strict (I : C) (h : ∀ (A) (f : haveI := h A (hI'.from _ ≫ f) ⟨⟨inv (hI'.from I ≫ f) ≫ hI'.from I, hI'.hom_ext _ _, by rw [assoc, IsIso.inv_hom_id]⟩⟩ } +instance [Quiver.IsThin C] : HasStrictTerminalObjects C where + out {I A} f hI := by + rw [CategoryTheory.isIso_iff_of_thin] + exact ⟨hI.from _⟩ + end StrictTerminal end Limits From 4b0d02203f92fc9bcb84761589e03295a148fca8 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:21:17 +0000 Subject: [PATCH 0446/1300] feat(Data/Set/Basic,Data/Finset/Empty): forall_mem_const for nonempty s (#40745) Add variants of the `forall_const` `@simp` lemma that localize to a `Nonempty` `Set` or `Finset`. Here we use the instance form of `Nonempty` (in contrast to the existing `Finset.Nonempty.forall_const`) in order to make `simp` work painlessly. Co-authored-by: Terence Tao --- Mathlib/Data/Finset/Empty.lean | 4 ++++ Mathlib/Data/Set/Basic.lean | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/Mathlib/Data/Finset/Empty.lean b/Mathlib/Data/Finset/Empty.lean index 3064902c8f0a7a..d6c6804b82af3e 100644 --- a/Mathlib/Data/Finset/Empty.lean +++ b/Mathlib/Data/Finset/Empty.lean @@ -74,6 +74,10 @@ theorem Nonempty.forall_const {s : Finset α} (h : s.Nonempty) {p : Prop} : (∀ let ⟨x, hx⟩ := h ⟨fun h => h x hx, fun h _ _ => h⟩ +@[simp] +theorem forall_mem_const {s : Finset α} [Nonempty s] {p : Prop} : (∀ x ∈ s, p) ↔ p := + (nonempty_coe_sort.mp ‹_›).forall_const + theorem Nonempty.to_subtype {s : Finset α} : s.Nonempty → Nonempty s := nonempty_coe_sort.2 diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index 9b17d3c22a16e8..33b1e76ca63b6a 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -505,6 +505,14 @@ theorem subset_eq_empty {s t : Set α} (h : t ⊆ s) (e : s = ∅) : t = ∅ := theorem forall_mem_empty {p : α → Prop} : (∀ x ∈ (∅ : Set α), p x) ↔ True := iff_true_intro fun _ => False.elim +theorem Nonempty.forall_const (h : s.Nonempty) {p : Prop} : (∀ x ∈ s, p) ↔ p := + let ⟨x, hx⟩ := h + ⟨fun h ↦ h x hx, fun h _ _ ↦ h⟩ + +@[simp] +theorem forall_mem_const {p : Prop} [Nonempty s] : (∀ x ∈ s, p) ↔ p := + (nonempty_coe_sort.mp ‹_›).forall_const + instance (α : Type u) : IsEmpty.{u + 1} (↥(∅ : Set α)) := ⟨fun x => x.2⟩ From 67b4a95857388cc2d4b7fffd8804c7449f459ceb Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:21:20 +0000 Subject: [PATCH 0447/1300] refactor(RingTheory/Localization/AtPrime/Extension): switch to new definition of ramification index (#40781) This PR switches `RingTheory/Localization/AtPrime/Extension.lean` over to the new definition of ramification index. Co-authored-by: tb65536 --- .../Localization/AtPrime/Extension.lean | 61 ++++++++----------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean index e75652d57a4887..4de0e95c68da68 100644 --- a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean +++ b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean @@ -5,7 +5,7 @@ Authors: Xavier Roblot -/ module -public import Mathlib.NumberTheory.RamificationInertia.Basic +public import Mathlib.RingTheory.RamificationInertia.Basic /-! # Primes in an extension of localization at prime @@ -175,32 +175,28 @@ theorem inertiaDeg_map_eq_inertiaDeg [p.IsMaximal] [P.IsMaximal] ext x exact algebraMap_equivQuotMaximalIdeal_symm_apply p Rₚ Sₚ P x -theorem ramificationIdx_map_eq_ramificationIdx [IsDomain R] [IsTorsionFree R S] [IsTorsionFree R Rₚ] - [IsTorsionFree S Sₚ] [IsTorsionFree Rₚ Sₚ] [IsDedekindDomain S] [IsDedekindDomain Rₚ] - [IsDedekindDomain Sₚ] (hp : p ≠ ⊥) [P.IsPrime] : - (maximalIdeal Rₚ).ramificationIdx (P.map (algebraMap S Sₚ)) = - p.ramificationIdx P := by - have h₁ : maximalIdeal Rₚ ≠ ⊥ := by - rw [← map_eq_maximalIdeal p] - exact map_ne_bot_of_ne_bot hp - have : (P.map (algebraMap S Sₚ)).IsPrime := isPrime_map_of_liesOver S p Sₚ P - by_cases hP : P = ⊥ - · simp_rw [hP, Ideal.map_bot, ramificationIdx_bot' hp - (FaithfulSMul.algebraMap_injective _ _), - ramificationIdx_bot' h₁ (FaithfulSMul.algebraMap_injective Rₚ Sₚ)] - have : P.IsMaximal := IsPrime.isMaximal inferInstance hP - have : (Ideal.map (algebraMap S Sₚ) P).LiesOver (maximalIdeal Rₚ) := - liesOver_map_of_liesOver p Rₚ Sₚ P - have : (Ideal.map (algebraMap S Sₚ) P).LiesOver P := by - rw [liesOver_iff, under_def, comap_map_eq_self_of_isMaximal _ (IsPrime.ne_top')] - have h_main := - (ramificationIdx_algebra_tower' p (maximalIdeal Rₚ) (Ideal.map (algebraMap S Sₚ) P)).symm.trans - <| ramificationIdx_algebra_tower' p P (Ideal.map (algebraMap S Sₚ) P) - rwa [ramificationIdx_map_self_eq_one IsPrime.ne_top' (map_ne_bot_of_ne_bot hP), mul_one, - ← map_eq_maximalIdeal p, ramificationIdx_map_self_eq_one _ (map_ne_bot_of_ne_bot hp), one_mul, - map_eq_maximalIdeal p] at h_main - rw [map_eq_maximalIdeal] - exact IsPrime.ne_top' +include p in +theorem ramificationIdx_map_eq_ramificationIdx [P.IsPrime] : + (P.map (algebraMap S Sₚ)).ramificationIdx' Rₚ = P.ramificationIdx' R := by + have := liesOver_map_of_liesOver p Rₚ Sₚ P + have := IsLocalization.liesOver_map_of_isPrime_disjoint (algebraMapSubmonoid S p.primeCompl) Sₚ + (Set.disjoint_image_left.mpr (Set.disjoint_compl_left_iff_subset.mpr hPp.over.ge)) + have := isPrime_map_of_liesOver S p Sₚ P + rw [ramificationIdx'_eq (maximalIdeal Rₚ) (P.map (algebraMap S Sₚ)), ramificationIdx'_eq p P] + let R₁ := Localization.AtPrime (P.map (algebraMap S Sₚ)) + let R₂ := Localization.AtPrime P + let : Algebra R₂ R₁ := Localization.AtPrime.algebraOfLiesOver P (P.map (algebraMap S Sₚ)) + have : IsLocalization.AtPrime R₁ P := by + convert isLocalization_isLocalization_atPrime_isLocalization + (algebraMapSubmonoid S p.primeCompl) R₁ (P.map (algebraMap S Sₚ)) + rw [← Ideal.under_def, ← Ideal.over_def (P.map (algebraMap S Sₚ)) P] + have h : Function.Bijective (algebraMap R₂ R₁) := + (Localization.algEquiv P.primeCompl R₁).bijective + have key : p.map (algebraMap R R₂) = + ((maximalIdeal Rₚ).map (algebraMap Rₚ R₁)).comap (algebraMap R₂ R₁) := by + rw [← IsLocalization.AtPrime.map_eq_maximalIdeal p, p.map_map, ← IsScalarTower.algebraMap_eq, + IsScalarTower.algebraMap_eq R R₂ R₁, ← p.map_map, comap_map_of_bijective _ h] + rw [Module.length_quotient, Module.length_quotient, key, coheight_comap_of_surjective _ h.2] end IsLocalization.AtPrime @@ -250,12 +246,9 @@ theorem primesOverEquivPrimesOver_inertiagDeg_eq [p.IsMaximal] (hp : p ≠ ⊥) have : (P.1.map (algebraMap S Sₚ)).LiesOver (maximalIdeal Rₚ) := liesOver_map_of_liesOver p _ _ _ exact inertiaDeg_map_eq_inertiaDeg p _ _ _ -theorem primesOverEquivPrimesOver_ramificationIdx_eq (hp : p ≠ ⊥) [NoZeroSMulDivisors R Rₚ] - [NoZeroSMulDivisors S Sₚ] [NoZeroSMulDivisors Rₚ Sₚ] [IsDedekindDomain Rₚ] [IsDedekindDomain Sₚ] - (P : p.primesOver S) : - (maximalIdeal Rₚ).ramificationIdx - (primesOverEquivPrimesOver p Rₚ Sₚ hp P : Ideal Sₚ) = - p.ramificationIdx P.val := - ramificationIdx_map_eq_ramificationIdx p _ _ _ hp +theorem primesOverEquivPrimesOver_ramificationIdx_eq (hp : p ≠ ⊥) (P : p.primesOver S) : + (primesOverEquivPrimesOver p Rₚ Sₚ hp P : Ideal Sₚ).ramificationIdx' Rₚ = + P.val.ramificationIdx' R := + ramificationIdx_map_eq_ramificationIdx p _ _ _ end IsDedekindDomain From 48b12e19b82cbb6c7354fc0a67435be6cb00da90 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:21:23 +0000 Subject: [PATCH 0448/1300] feat: tag the pointwise MeasureTheory operation families with to_fun (#41091) Co-authored-by: Terence Tao --- Mathlib/Analysis/Calculus/Rademacher.lean | 4 +-- .../Analysis/Fourier/FourierTransform.lean | 4 +-- .../Fourier/FourierTransformDeriv.lean | 6 ++-- .../Function/SpecialFunctions/Basic.lean | 2 +- .../Function/SpecialFunctions/RCLike.lean | 4 +-- .../AEStronglyMeasurable.lean | 31 ++++++++-------- .../Function/StronglyMeasurable/Basic.lean | 31 ++++++++-------- Mathlib/MeasureTheory/Group/Arithmetic.lean | 36 +++++++++---------- .../Integral/CircleIntegral.lean | 2 +- .../Integral/MeanInequalities.lean | 2 +- .../Measure/Decomposition/Lebesgue.lean | 2 +- .../MeasureTheory/Measure/WithDensity.lean | 6 ++-- Mathlib/MeasureTheory/Order/Lattice.lean | 34 +++++++----------- .../Probability/Independence/Conditional.lean | 2 +- .../Probability/Independence/Integration.lean | 4 +-- Mathlib/Probability/Kernel/Proper.lean | 2 +- 16 files changed, 80 insertions(+), 92 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Rademacher.lean b/Mathlib/Analysis/Calculus/Rademacher.lean index d582d301482c81..fb1a4980548a2d 100644 --- a/Mathlib/Analysis/Calculus/Rademacher.lean +++ b/Mathlib/Analysis/Calculus/Rademacher.lean @@ -109,7 +109,7 @@ theorem integral_inv_smul_sub_mul_tendsto_integral_lineDeriv_mul apply tendsto_integral_filter_of_dominated_convergence (fun x ↦ (C * ‖v‖) * ‖g x‖) · filter_upwards with t apply AEStronglyMeasurable.mul ?_ hg.aestronglyMeasurable - apply aestronglyMeasurable_const.smul + apply aestronglyMeasurable_const.fun_smul apply AEStronglyMeasurable.sub _ hf.continuous.measurable.aestronglyMeasurable apply AEMeasurable.aestronglyMeasurable exact hf.continuous.measurable.comp_aemeasurable' (aemeasurable_id'.add_const _) @@ -134,7 +134,7 @@ theorem integral_inv_smul_sub_mul_tendsto_integral_lineDeriv_mul' (K.indicator (fun x ↦ (C * ‖v‖) * ‖g x‖)) · filter_upwards with t apply AEStronglyMeasurable.mul ?_ hg.aestronglyMeasurable - apply aestronglyMeasurable_const.smul + apply aestronglyMeasurable_const.fun_smul apply AEStronglyMeasurable.sub _ hf.continuous.measurable.aestronglyMeasurable apply AEMeasurable.aestronglyMeasurable exact hf.continuous.measurable.comp_aemeasurable' (aemeasurable_id'.add_const _) diff --git a/Mathlib/Analysis/Fourier/FourierTransform.lean b/Mathlib/Analysis/Fourier/FourierTransform.lean index 6e4d3c70e1a79f..7d12ab08d9f1e3 100644 --- a/Mathlib/Analysis/Fourier/FourierTransform.lean +++ b/Mathlib/Analysis/Fourier/FourierTransform.lean @@ -140,7 +140,7 @@ theorem fourierIntegral_convergent_iff (he : Continuous e) have aux {g : V → E} (hg : Integrable g μ) (x : W) : Integrable (fun v : V ↦ e (-L v x) • g v) μ := by have c : Continuous fun v ↦ e (-L v x) := he.comp (hL.comp (.prodMk_left _)).neg - simp_rw [← integrable_norm_iff (c.aestronglyMeasurable.smul hg.1), Circle.norm_smul] + simp_rw [← integrable_norm_iff (c.aestronglyMeasurable.fun_smul hg.1), Circle.norm_smul] exact hg.norm -- then use it for both directions refine ⟨fun hf ↦ ?_, fun hf ↦ aux hf w⟩ @@ -196,7 +196,7 @@ theorem integral_fourierIntegral_swap apply this.mono · change AEStronglyMeasurable (fun p : W × V ↦ (M (g p.1) (e (-(L p.2) p.1) • f p.2))) _ have A : AEStronglyMeasurable (fun (p : W × V) ↦ e (-L p.2 p.1) • f p.2) (ν.prod μ) := by - refine (Continuous.aestronglyMeasurable ?_).smul hf.1.comp_snd + refine (Continuous.aestronglyMeasurable ?_).fun_smul hf.1.comp_snd exact he.comp (hL.comp continuous_swap).neg have A' : AEStronglyMeasurable (fun p ↦ (g p.1, e (-(L p.2) p.1) • f p.2) : W × V → F × E) (Measure.prod ν μ) := hg.1.comp_fst.prodMk A diff --git a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean index 3a84c32f77f3f7..15d25a14e6e7a9 100644 --- a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean +++ b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean @@ -197,7 +197,7 @@ lemma _root_.MeasureTheory.AEStronglyMeasurable.fourierSMulRight {L : V →L[ℝ] W →L[ℝ] ℝ} {f : V → E} {μ : Measure V} (hf : AEStronglyMeasurable f μ) : AEStronglyMeasurable (fun v ↦ fourierSMulRight L f v) μ := by - apply AEStronglyMeasurable.const_smul' + apply AEStronglyMeasurable.fun_const_smul have aux0 : Continuous fun p : (W →L[ℝ] ℝ) × E ↦ p.1.smulRight p.2 := (ContinuousLinearMap.smulRightL ℝ W E).continuous₂ have aux1 : AEStronglyMeasurable (fun v ↦ (L v, f v)) μ := @@ -224,7 +224,7 @@ theorem hasFDerivAt_fourierIntegral have h1 : ∀ᶠ w' in 𝓝 w, AEStronglyMeasurable (F w') μ := Eventually.of_forall (fun w' ↦ (h0 w').aestronglyMeasurable) have h3 : AEStronglyMeasurable (F' w) μ := by - refine .smul ?_ hf.1.fourierSMulRight + refine .fun_smul ?_ hf.1.fourierSMulRight refine (continuous_fourierChar.comp ?_).aestronglyMeasurable fun_prop have h4 : (∀ᵐ v ∂μ, ∀ (w' : W), w' ∈ Metric.ball w 1 → ‖F' w' v‖ ≤ B v) := by @@ -433,7 +433,7 @@ lemma _root_.MeasureTheory.AEStronglyMeasurable.fourierPowSMulRight (hf : AEStronglyMeasurable f μ) (n : ℕ) : AEStronglyMeasurable (fun v ↦ fourierPowSMulRight L f v n) μ := by simp_rw [fourierPowSMulRight_eq_comp] - apply AEStronglyMeasurable.const_smul' + apply AEStronglyMeasurable.fun_const_smul apply (smulRightL ℝ (fun (_ : Fin n) ↦ W) E).continuous₂.comp_aestronglyMeasurable₂ _ hf apply Continuous.aestronglyMeasurable exact Continuous.comp (map_continuous _) (continuous_pi (fun _ ↦ L.continuous)) diff --git a/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean b/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean index 53c2f9e66bc6f4..8fdb92ba8a019d 100644 --- a/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean +++ b/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean @@ -56,7 +56,7 @@ lemma aemeasurable_of_aemeasurable_exp_mul {t : ℝ} (ht : t ≠ 0) (hf : AEMeasurable (fun x ↦ exp (t * f x)) μ) : AEMeasurable f μ := by simpa only [mul_div_cancel_left₀ _ ht] - using (aemeasurable_of_aemeasurable_exp hf).div (aemeasurable_const (b := t)) + using (aemeasurable_of_aemeasurable_exp hf).fun_div (aemeasurable_const (b := t)) theorem measurable_sin : Measurable sin := continuous_sin.measurable diff --git a/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean b/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean index c22984209c3549..703f87f29b7afa 100644 --- a/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean +++ b/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean @@ -66,14 +66,14 @@ theorem RCLike.measurable_ofReal : Measurable ((↑) : ℝ → 𝕜) := theorem measurable_of_re_im (hre : Measurable fun x => RCLike.re (f x)) (him : Measurable fun x => RCLike.im (f x)) : Measurable f := by convert! - Measurable.add (M := 𝕜) (RCLike.measurable_ofReal.comp hre) + Measurable.fun_add (M := 𝕜) (RCLike.measurable_ofReal.comp hre) ((RCLike.measurable_ofReal.comp him).mul_const RCLike.I) exact (RCLike.re_add_im _).symm theorem aemeasurable_of_re_im (hre : AEMeasurable (fun x => RCLike.re (f x)) μ) (him : AEMeasurable (fun x => RCLike.im (f x)) μ) : AEMeasurable f μ := by convert! - AEMeasurable.add (M := 𝕜) (RCLike.measurable_ofReal.comp_aemeasurable hre) + AEMeasurable.fun_add (M := 𝕜) (RCLike.measurable_ofReal.comp_aemeasurable hre) ((RCLike.measurable_ofReal.comp_aemeasurable him).mul_const RCLike.I) exact (RCLike.re_add_im _).symm diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index ca9765aa83f906..2159a038b2d446 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -296,7 +296,7 @@ lemma of_measurableSpace_le_on {m' m₀ : MeasurableSpace α} {μ : Measure[m₀ section Arithmetic -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem mul [Mul β] [ContinuousMul β] (hf : AEStronglyMeasurable[m] f μ) (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (f * g) μ := ⟨hf.mk f * hg.mk g, by fun_prop, hf.ae_eq_mk.mul hg.ae_eq_mk⟩ @@ -311,17 +311,17 @@ protected theorem const_mul [Mul β] [ContinuousMul β] (hf : AEStronglyMeasurab AEStronglyMeasurable[m] (fun x => c * f x) μ := aestronglyMeasurable_const.mul hf -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem inv [Inv β] [ContinuousInv β] (hf : AEStronglyMeasurable[m] f μ) : AEStronglyMeasurable[m] f⁻¹ μ := ⟨(hf.mk f)⁻¹, hf.stronglyMeasurable_mk.inv, hf.ae_eq_mk.inv⟩ -@[fun_prop] +@[to_fun (attr := fun_prop)] theorem inv₀ [GroupWithZero β] [ContinuousInv₀ β] [MetrizableSpace β] (hf : AEStronglyMeasurable[m] f μ) : AEStronglyMeasurable[m] f⁻¹ μ := ⟨(hf.mk f)⁻¹, hf.stronglyMeasurable_mk.inv₀, hf.ae_eq_mk.inv⟩ -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem div [Group β] [IsTopologicalGroup β] (hf : AEStronglyMeasurable[m] f μ) (hg : AEStronglyMeasurable[m] g μ) : AEStronglyMeasurable[m] (f / g) μ := ⟨hf.mk f / hg.mk g, hf.stronglyMeasurable_mk.div' hg.stronglyMeasurable_mk, @@ -345,26 +345,27 @@ theorem mul_iff_left [CommGroup β] [IsTopologicalGroup β] (hf : AEStronglyMeas AEStronglyMeasurable[m] (g * f) μ ↔ AEStronglyMeasurable[m] g μ := mul_comm g f ▸ AEStronglyMeasurable.mul_iff_right hf -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem smul {𝕜} [TopologicalSpace 𝕜] [SMul 𝕜 β] [ContinuousSMul 𝕜 β] {f : α → 𝕜} {g : α → β} (hf : AEStronglyMeasurable[m] f μ) (hg : AEStronglyMeasurable[m] g μ) : - AEStronglyMeasurable[m] (fun x => f x • g x) μ := + AEStronglyMeasurable[m] (f • g) μ := continuous_smul.comp_aestronglyMeasurable (hf.prodMk hg) -@[to_additive (attr := fun_prop) const_nsmul] +@[to_additive (attr := to_fun (attr := fun_prop)) const_nsmul] protected theorem pow [Monoid β] [ContinuousMul β] (hf : AEStronglyMeasurable[m] f μ) (n : ℕ) : AEStronglyMeasurable[m] (f ^ n) μ := ⟨hf.mk f ^ n, hf.stronglyMeasurable_mk.pow _, hf.ae_eq_mk.pow_const _⟩ -@[to_additive (attr := fun_prop)] +@[to_additive (attr := to_fun (attr := fun_prop))] protected theorem const_smul {𝕜} [SMul 𝕜 β] [ContinuousConstSMul 𝕜 β] (hf : AEStronglyMeasurable[m] f μ) (c : 𝕜) : AEStronglyMeasurable[m] (c • f) μ := ⟨c • hf.mk f, hf.stronglyMeasurable_mk.const_smul c, hf.ae_eq_mk.const_smul c⟩ -@[to_additive (attr := fun_prop)] -protected theorem const_smul' {𝕜} [SMul 𝕜 β] [ContinuousConstSMul 𝕜 β] - (hf : AEStronglyMeasurable[m] f μ) (c : 𝕜) : AEStronglyMeasurable[m] (fun x => c • f x) μ := - hf.const_smul c +@[deprecated (since := "2026-06-26")] +alias const_smul' := AEStronglyMeasurable.fun_const_smul + +@[deprecated (since := "2026-06-26")] +alias const_vadd' := AEStronglyMeasurable.fun_const_vadd @[to_additive (attr := fun_prop)] protected theorem smul_const {𝕜} [TopologicalSpace 𝕜] [SMul 𝕜 β] [ContinuousSMul 𝕜 β] {f : α → 𝕜} @@ -384,13 +385,13 @@ end Star section Order -@[fun_prop] +@[to_fun (attr := fun_prop)] protected theorem sup [SemilatticeSup β] [ContinuousSup β] (hf : AEStronglyMeasurable f μ) (hg : AEStronglyMeasurable g μ) : AEStronglyMeasurable (f ⊔ g) μ := ⟨hf.mk f ⊔ hg.mk g, hf.stronglyMeasurable_mk.sup hg.stronglyMeasurable_mk, hf.ae_eq_mk.sup hg.ae_eq_mk⟩ -@[fun_prop] +@[to_fun (attr := fun_prop)] protected theorem inf [SemilatticeInf β] [ContinuousInf β] (hf : AEStronglyMeasurable f μ) (hg : AEStronglyMeasurable g μ) : AEStronglyMeasurable (f ⊓ g) μ := ⟨hf.mk f ⊓ hg.mk g, hf.stronglyMeasurable_mk.inf hg.stronglyMeasurable_mk, @@ -836,7 +837,7 @@ variable [GroupWithZero G₀] [MulAction G₀ β] [ContinuousConstSMul G₀ β] theorem _root_.aestronglyMeasurable_const_smul_iff (c : G) : AEStronglyMeasurable (fun x => c • f x) μ ↔ AEStronglyMeasurable f μ := - ⟨fun h => by simpa only [inv_smul_smul] using h.const_smul' c⁻¹, fun h => h.const_smul c⟩ + ⟨fun h => by simpa only [inv_smul_smul] using h.fun_const_smul c⁻¹, fun h => h.const_smul c⟩ nonrec theorem _root_.IsUnit.aestronglyMeasurable_const_smul_iff {c : M} (hc : IsUnit c) : AEStronglyMeasurable (fun x => c • f x) μ ↔ AEStronglyMeasurable f μ := diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 8f3b79ed9a1d30..6f81c159bb59af 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -391,7 +391,7 @@ section Arithmetic variable {mα : MeasurableSpace α} [TopologicalSpace β] -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem mul [Mul β] [ContinuousMul β] (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : StronglyMeasurable (f * g) := ⟨fun n => hf.approx n * hg.approx n, fun x => (hf.tendsto_approx x).mul (hg.tendsto_approx x)⟩ @@ -406,17 +406,17 @@ theorem const_mul [Mul β] [ContinuousMul β] (hf : StronglyMeasurable f) (c : StronglyMeasurable fun x => c * f x := stronglyMeasurable_const.mul hf -@[to_additive (attr := fun_prop) const_nsmul] +@[to_additive (attr := to_fun (attr := fun_prop)) const_nsmul] protected theorem pow [Monoid β] [ContinuousMul β] (hf : StronglyMeasurable f) (n : ℕ) : StronglyMeasurable (f ^ n) := ⟨fun k => hf.approx k ^ n, fun x => (hf.tendsto_approx x).pow n⟩ -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem inv [Inv β] [ContinuousInv β] (hf : StronglyMeasurable f) : StronglyMeasurable f⁻¹ := ⟨fun n => (hf.approx n)⁻¹, fun x => (hf.tendsto_approx x).inv⟩ -@[fun_prop] +@[to_fun (attr := fun_prop)] protected theorem inv₀ [GroupWithZero β] [ContinuousInv₀ β] [MetrizableSpace β] (hf : StronglyMeasurable f) : StronglyMeasurable f⁻¹ := by borelize β @@ -431,7 +431,7 @@ protected theorem inv₀ [GroupWithZero β] [ContinuousInv₀ β] [MetrizableSpa Pi.inv_apply, mem_setOf_eq, not_false_eq_true, indicator_of_mem] apply (hf.tendsto_approx x).inv₀ h -@[to_additive (attr := fun_prop) sub] +@[to_additive (attr := to_fun (attr := fun_prop)) sub] protected theorem div' [Div β] [ContinuousDiv β] (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : StronglyMeasurable (f / g) := ⟨fun n => hf.approx n / hg.approx n, fun x => (hf.tendsto_approx x).div' (hg.tendsto_approx x)⟩ @@ -468,21 +468,22 @@ theorem mul_iff_left [CommGroup β] [IsTopologicalGroup β] (hf : StronglyMeasur StronglyMeasurable (g * f) ↔ StronglyMeasurable g := mul_comm g f ▸ mul_iff_right hf -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] protected theorem smul {𝕜} [TopologicalSpace 𝕜] [SMul 𝕜 β] [ContinuousSMul 𝕜 β] {f : α → 𝕜} {g : α → β} (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : - StronglyMeasurable fun x => f x • g x := + StronglyMeasurable (f • g) := continuous_smul.comp_stronglyMeasurable (hf.prodMk hg) -@[to_additive (attr := fun_prop)] +@[to_additive (attr := to_fun (attr := fun_prop))] protected theorem const_smul {𝕜} [SMul 𝕜 β] [ContinuousConstSMul 𝕜 β] (hf : StronglyMeasurable f) (c : 𝕜) : StronglyMeasurable (c • f) := ⟨fun n => c • hf.approx n, fun x => (hf.tendsto_approx x).const_smul c⟩ -@[to_additive (attr := fun_prop)] -protected theorem const_smul' {𝕜} [SMul 𝕜 β] [ContinuousConstSMul 𝕜 β] (hf : StronglyMeasurable f) - (c : 𝕜) : StronglyMeasurable fun x => c • f x := - hf.const_smul c +@[deprecated (since := "2026-06-26")] +alias const_smul' := StronglyMeasurable.fun_const_smul + +@[deprecated (since := "2026-06-26")] +alias const_vadd' := StronglyMeasurable.fun_const_vadd @[to_additive (attr := fun_prop)] protected theorem smul_const {𝕜} [TopologicalSpace 𝕜] [SMul 𝕜 β] [ContinuousSMul 𝕜 β] {f : α → 𝕜} @@ -546,7 +547,7 @@ variable [GroupWithZero G₀] [MulAction G₀ β] [ContinuousConstSMul G₀ β] theorem _root_.stronglyMeasurable_const_smul_iff {m : MeasurableSpace α} (c : G) : (StronglyMeasurable fun x => c • f x) ↔ StronglyMeasurable f := - ⟨fun h => by simpa only [inv_smul_smul] using h.const_smul' c⁻¹, fun h => h.const_smul c⟩ + ⟨fun h => by simpa only [inv_smul_smul] using h.fun_const_smul c⁻¹, fun h => h.const_smul c⟩ nonrec theorem _root_.IsUnit.stronglyMeasurable_const_smul_iff {_ : MeasurableSpace α} {c : M} (hc : IsUnit c) : @@ -566,13 +567,13 @@ variable [MeasurableSpace α] [TopologicalSpace β] open Filter -@[fun_prop] +@[to_fun (attr := fun_prop)] protected theorem sup [Max β] [ContinuousSup β] (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : StronglyMeasurable (f ⊔ g) := ⟨fun n => hf.approx n ⊔ hg.approx n, fun x => (hf.tendsto_approx x).sup_nhds (hg.tendsto_approx x)⟩ -@[fun_prop] +@[to_fun (attr := fun_prop)] protected theorem inf [Min β] [ContinuousInf β] (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : StronglyMeasurable (f ⊓ g) := ⟨fun n => hf.approx n ⊓ hg.approx n, fun x => diff --git a/Mathlib/MeasureTheory/Group/Arithmetic.lean b/Mathlib/MeasureTheory/Group/Arithmetic.lean index 2e6e8412650755..f4f7730d6a9db9 100644 --- a/Mathlib/MeasureTheory/Group/Arithmetic.lean +++ b/Mathlib/MeasureTheory/Group/Arithmetic.lean @@ -114,9 +114,9 @@ theorem AEMeasurable.mul_const [MeasurableMul M] (hf : AEMeasurable f μ) (c : M AEMeasurable (fun x => f x * c) μ := (measurable_mul_const c).comp_aemeasurable hf -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem Measurable.mul [MeasurableMul₂ M] (hf : Measurable f) (hg : Measurable g) : - Measurable fun a => f a * g a := + Measurable (f * g) := measurable_mul.comp (hf.prodMk hg) /-- Compositional version of `Measurable.mul` for use by `fun_prop`. -/ @@ -126,15 +126,13 @@ lemma Measurable.mul' [MeasurableMul₂ M] {f g : α → β → M} {h : α → (hg : Measurable ↿g) (hh : Measurable h) : Measurable fun a ↦ (f a * g a) (h a) := by dsimp; fun_prop -@[to_additive (attr := fun_prop)] -theorem AEMeasurable.mul' [MeasurableMul₂ M] (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : +@[to_fun (attr := to_additive (attr := fun_prop))] +theorem AEMeasurable.mul [MeasurableMul₂ M] (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : AEMeasurable (f * g) μ := measurable_mul.comp_aemeasurable (hf.prodMk hg) -@[to_additive (attr := fun_prop)] -theorem AEMeasurable.mul [MeasurableMul₂ M] (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (fun a => f a * g a) μ := - measurable_mul.comp_aemeasurable (hf.prodMk hg) +@[deprecated (since := "2026-06-26")] alias AEMeasurable.mul' := AEMeasurable.mul +@[deprecated (since := "2026-06-26")] alias AEMeasurable.add' := AEMeasurable.add @[to_additive] instance (priority := 100) MeasurableMul₂.toMeasurableMul [MeasurableMul₂ M] : @@ -267,9 +265,9 @@ theorem AEMeasurable.div_const [MeasurableDiv G] (hf : AEMeasurable f μ) (c : G AEMeasurable (fun x => f x / c) μ := (MeasurableDiv.measurable_div_const c).comp_aemeasurable hf -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem Measurable.div [MeasurableDiv₂ G] (hf : Measurable f) (hg : Measurable g) : - Measurable fun a => f a / g a := + Measurable (f / g) := measurable_div.comp (hf.prodMk hg) @[to_additive (attr := fun_prop)] @@ -277,15 +275,13 @@ lemma Measurable.div' [MeasurableDiv₂ G] {f g : α → β → G} {h : α → (hg : Measurable ↿g) (hh : Measurable h) : Measurable fun a ↦ (f a / g a) (h a) := by dsimp; fun_prop -@[to_additive (attr := fun_prop)] -theorem AEMeasurable.div' [MeasurableDiv₂ G] (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : +@[to_fun (attr := to_additive (attr := fun_prop))] +theorem AEMeasurable.div [MeasurableDiv₂ G] (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : AEMeasurable (f / g) μ := measurable_div.comp_aemeasurable (hf.prodMk hg) -@[to_additive (attr := fun_prop)] -theorem AEMeasurable.div [MeasurableDiv₂ G] (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (fun a => f a / g a) μ := - measurable_div.comp_aemeasurable (hf.prodMk hg) +@[deprecated (since := "2026-06-26")] alias AEMeasurable.div' := AEMeasurable.div +@[deprecated (since := "2026-06-26")] alias AEMeasurable.sub' := AEMeasurable.sub @[to_additive] instance (priority := 100) MeasurableDiv₂.toMeasurableDiv [MeasurableDiv₂ G] : @@ -535,9 +531,9 @@ end MeasurableConstSMul variable [MeasurableSpace M] -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem Measurable.smul [MeasurableSMul₂ M X] (hf : Measurable f) (hg : Measurable g) : - Measurable fun x => f x • g x := + Measurable (f • g) := measurable_smul.comp (hf.prodMk hg) /-- Compositional version of `Measurable.smul` for use by `fun_prop`. -/ @@ -547,9 +543,9 @@ lemma Measurable.smul' [MeasurableSMul₂ M X] {f : α → β → M} {g : α → (hf : Measurable ↿f) (hg : Measurable ↿g) (hh : Measurable h) : Measurable fun a ↦ (f a • g a) (h a) := by dsimp; fun_prop -@[to_additive (attr := fun_prop)] +@[to_fun (attr := to_additive (attr := fun_prop))] theorem AEMeasurable.smul [MeasurableSMul₂ M X] {μ : Measure α} (hf : AEMeasurable f μ) - (hg : AEMeasurable g μ) : AEMeasurable (fun x => f x • g x) μ := + (hg : AEMeasurable g μ) : AEMeasurable (f • g) μ := MeasurableSMul₂.measurable_smul.comp_aemeasurable (hf.prodMk hg) @[to_additive] diff --git a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean index e79060068bfc98..87e7993b83201f 100644 --- a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean @@ -327,7 +327,7 @@ theorem circleIntegrable_iff [NormedSpace ℂ E] {f : ℂ → E} {c : ℂ} (R : · have H : ∀ {θ}, circleMap 0 R θ * I ≠ 0 := fun {θ} => by simp [h₀, I_ne_zero] simpa only [inv_smul_smul₀ H] using ((continuous_circleMap 0 R).aestronglyMeasurable.mul_const - I).aemeasurable.fun_inv.aestronglyMeasurable.smul h.aestronglyMeasurable + I).aemeasurable.fun_inv.aestronglyMeasurable.fun_smul h.aestronglyMeasurable · simp [norm_smul, h₀] theorem ContinuousOn.circleIntegrable' {f : ℂ → E} {c : ℂ} {R : ℝ} diff --git a/Mathlib/MeasureTheory/Integral/MeanInequalities.lean b/Mathlib/MeasureTheory/Integral/MeanInequalities.lean index f2410ebba2583e..719a35fba6e1e0 100644 --- a/Mathlib/MeasureTheory/Integral/MeanInequalities.lean +++ b/Mathlib/MeasureTheory/Integral/MeanInequalities.lean @@ -338,7 +338,7 @@ theorem lintegral_rpow_add_le_add_eLpNorm_mul_lintegral_rpow_add {p q : ℝ} ∫⁻ a : α, (f a + g a) * (f + g) a ^ (p - 1) ∂μ := rfl simp_rw [h_add_apply, add_mul] - rw [lintegral_add_left' (hf.mul h_add_m)] + rw [lintegral_add_left' (hf.fun_mul h_add_m)] _ ≤ ((∫⁻ a, f a ^ p ∂μ) ^ (1 / p) + (∫⁻ a, g a ^ p ∂μ) ^ (1 / p)) * (∫⁻ a, (f a + g a) ^ p ∂μ) ^ (1 / q) := by diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean index 58230699d62e8d..bc7219a36a8c60 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean @@ -470,7 +470,7 @@ theorem singularPart_add (μ₁ μ₂ ν : Measure α) [HaveLebesgueDecompositio (μ₁ + μ₂).singularPart ν = μ₁.singularPart ν + μ₂.singularPart ν := by refine (eq_singularPart ((measurable_rnDeriv μ₁ ν).add (measurable_rnDeriv μ₂ ν)) ((mutuallySingular_singularPart _ _).add_left (mutuallySingular_singularPart _ _)) ?_).symm - rw [← Pi.add_def, withDensity_add_left (measurable_rnDeriv μ₁ ν)] + rw [withDensity_add_left (measurable_rnDeriv μ₁ ν)] conv_rhs => rw [add_assoc, add_comm (μ₂.singularPart ν), ← add_assoc, ← add_assoc] rw [← haveLebesgueDecomposition_add μ₁ ν, add_assoc, add_comm (ν.withDensity (μ₂.rnDeriv ν)), ← haveLebesgueDecomposition_add μ₂ ν] diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index 3337ad31fdd514..f875151d22a688 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -403,10 +403,10 @@ theorem lintegral_withDensity_eq_lintegral_mul (μ : Measure α) {f : α → ℝ · intro c s h_ms simp [*, mul_comm _ c, ← indicator_mul_right] · intro g h _ h_mea_g _ h_ind_g h_ind_h - simp [mul_add, *, Measurable.mul] + simp [mul_add, *, Measurable.fun_mul] · intro g h_mea_g h_mono_g h_ind have : Monotone fun n a => f a * g n a := fun m n hmn x => by dsimp; grw [h_mono_g hmn x] - simp [lintegral_iSup, ENNReal.mul_iSup, h_mf.mul (h_mea_g _), *] + simp [lintegral_iSup, ENNReal.mul_iSup, h_mf.fun_mul (h_mea_g _), *] theorem setLIntegral_withDensity_eq_setLIntegral_mul (μ : Measure α) {f g : α → ℝ≥0∞} (hf : Measurable f) (hg : Measurable g) {s : Set α} (hs : MeasurableSet s) : @@ -488,7 +488,7 @@ theorem lintegral_withDensity_eq_lintegral_mul_non_measurable (μ : Measure α) exact div_le_of_le_mul' (hi x) refine le_iSup_of_le (fun x => (f x)⁻¹ * i x) (le_iSup_of_le (f_meas.fun_inv.mul i_meas) ?_) refine le_iSup_of_le A ?_ - rw [lintegral_withDensity_eq_lintegral_mul _ f_meas (f_meas.fun_inv.mul i_meas)] + rw [lintegral_withDensity_eq_lintegral_mul _ f_meas (f_meas.fun_inv.fun_mul i_meas)] apply lintegral_mono_ae filter_upwards [hf] intro x h'x diff --git a/Mathlib/MeasureTheory/Order/Lattice.lean b/Mathlib/MeasureTheory/Order/Lattice.lean index a699073554a52c..ba451d7bb82e49 100644 --- a/Mathlib/MeasureTheory/Order/Lattice.lean +++ b/Mathlib/MeasureTheory/Order/Lattice.lean @@ -120,23 +120,18 @@ section MeasurableSup₂ variable [MeasurableSup₂ M] -@[fun_prop] -theorem Measurable.sup' (hf : Measurable f) (hg : Measurable g) : Measurable (f ⊔ g) := +@[to_fun (attr := fun_prop)] +theorem Measurable.sup (hf : Measurable f) (hg : Measurable g) : Measurable (f ⊔ g) := measurable_sup.comp (hf.prodMk hg) -@[fun_prop] -theorem Measurable.sup (hf : Measurable f) (hg : Measurable g) : Measurable fun a => f a ⊔ g a := - measurable_sup.comp (hf.prodMk hg) +@[deprecated (since := "2026-06-26")] alias Measurable.sup' := Measurable.sup -@[fun_prop] -theorem AEMeasurable.sup' (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : +@[to_fun (attr := fun_prop)] +theorem AEMeasurable.sup (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : AEMeasurable (f ⊔ g) μ := measurable_sup.comp_aemeasurable (hf.prodMk hg) -@[fun_prop] -theorem AEMeasurable.sup (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (fun a => f a ⊔ g a) μ := - measurable_sup.comp_aemeasurable (hf.prodMk hg) +@[deprecated (since := "2026-06-26")] alias AEMeasurable.sup' := AEMeasurable.sup instance (priority := 100) MeasurableSup₂.toMeasurableSup : MeasurableSup M where @@ -176,23 +171,18 @@ section MeasurableInf₂ variable [MeasurableInf₂ M] -@[fun_prop] -theorem Measurable.inf' (hf : Measurable f) (hg : Measurable g) : Measurable (f ⊓ g) := +@[to_fun (attr := fun_prop)] +theorem Measurable.inf (hf : Measurable f) (hg : Measurable g) : Measurable (f ⊓ g) := measurable_inf.comp (hf.prodMk hg) -@[fun_prop] -theorem Measurable.inf (hf : Measurable f) (hg : Measurable g) : Measurable fun a => f a ⊓ g a := - measurable_inf.comp (hf.prodMk hg) +@[deprecated (since := "2026-06-26")] alias Measurable.inf' := Measurable.inf -@[fun_prop] -theorem AEMeasurable.inf' (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : +@[to_fun (attr := fun_prop)] +theorem AEMeasurable.inf (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : AEMeasurable (f ⊓ g) μ := measurable_inf.comp_aemeasurable (hf.prodMk hg) -@[fun_prop] -theorem AEMeasurable.inf (hf : AEMeasurable f μ) (hg : AEMeasurable g μ) : - AEMeasurable (fun a => f a ⊓ g a) μ := - measurable_inf.comp_aemeasurable (hf.prodMk hg) +@[deprecated (since := "2026-06-26")] alias AEMeasurable.inf' := AEMeasurable.inf instance (priority := 100) MeasurableInf₂.to_hasMeasurableInf : MeasurableInf M where diff --git a/Mathlib/Probability/Independence/Conditional.lean b/Mathlib/Probability/Independence/Conditional.lean index 5200e504eb8cb3..6d834c8d87db06 100644 --- a/Mathlib/Probability/Independence/Conditional.lean +++ b/Mathlib/Probability/Independence/Conditional.lean @@ -230,7 +230,7 @@ lemma condIndepSets_iff (s1 s2 : Set (Set Ω)) (hs1 : ∀ s ∈ s1, MeasurableSe filter_upwards [hs1_eq s hs, hs2_eq t ht, hs12_eq s hs t ht, h'] with ω hs_eq ht_eq hst_eq h' rw [← hst_eq, Pi.mul_apply, ← hs_eq, ← ht_eq, h', ENNReal.toReal_mul] · refine ((stronglyMeasurable_condExpKernel ((hs1 s hs).inter (hs2 t ht))).ae_eq_trim_iff hm' - ((measurable_condExpKernel (hs1 s hs)).mul + ((measurable_condExpKernel (hs1 s hs)).fun_mul (measurable_condExpKernel (hs2 t ht))).stronglyMeasurable).mpr ?_ filter_upwards [hs1_eq s hs, hs2_eq t ht, hs12_eq s hs t ht, h] with ω hs_eq ht_eq hst_eq h have h_ne_top : condExpKernel μ m' ω (s ∩ t) ≠ ∞ := measure_ne_top (condExpKernel μ m' ω) _ diff --git a/Mathlib/Probability/Independence/Integration.lean b/Mathlib/Probability/Independence/Integration.lean index dde2dfa2836440..36bfa475e2706e 100644 --- a/Mathlib/Probability/Independence/Integration.lean +++ b/Mathlib/Probability/Independence/Integration.lean @@ -95,8 +95,8 @@ theorem lintegral_mul_eq_lintegral_mul_lintegral_of_independent_measurableSpace · intro f' g _ h_measMg_f' _ h_ind_f' h_ind_g' have h_measM_f' : Measurable f' := h_measMg_f'.mono hMg le_rfl simp_rw [Pi.add_apply, left_distrib] - rw [lintegral_add_left h_measM_f', lintegral_add_left (h_measM_f.mul h_measM_f'), left_distrib, - h_ind_f', h_ind_g'] + rw [lintegral_add_left h_measM_f', + lintegral_add_left (h_measM_f.fun_mul h_measM_f'), left_distrib, h_ind_f', h_ind_g'] · intro f' h_meas_f' h_mono_f' h_ind_f' have h_measM_f' : ∀ n, Measurable (f' n) := fun n => (h_meas_f' n).mono hMg le_rfl simp_rw [mul_iSup] diff --git a/Mathlib/Probability/Kernel/Proper.lean b/Mathlib/Probability/Kernel/Proper.lean index dfea5904dda58c..61beb895b36e20 100644 --- a/Mathlib/Probability/Kernel/Proper.lean +++ b/Mathlib/Probability/Kernel/Proper.lean @@ -135,7 +135,7 @@ lemma IsProper.lintegral_mul (hπ : IsProper π) (h𝓑𝓧 : 𝓑 ≤ 𝓧) (hf · exact (hg₂_meas.mono h𝓑𝓧 le_rfl).mul hf · rintro g' hg'_meas hg'_mono hg' simp_rw [ENNReal.iSup_mul] - rw [lintegral_iSup (fun n ↦ ((hg'_meas _).mono h𝓑𝓧 le_rfl).mul hf) + rw [lintegral_iSup (fun n ↦ ((hg'_meas _).mono h𝓑𝓧 le_rfl).fun_mul hf) (hg'_mono.mul_const zero_le)] simp_rw [hg'] From e5f41401cb152c67977db531cab21e3ba8f3df4b Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:14:34 +0000 Subject: [PATCH 0449/1300] feat(MeasureTheory/MeasurableSpace/Constructions): add MeasurableSpace (Finset _) structure (#41062) Add an instance of `MeasurableSpace (Finset _)` (derived from the existing instance of `MeasurableSpace (Set _)` and provide some basic API for this instance, in particular that this instance is `MeasurableSingletonClass` (and hence `DiscreteMeasurableSpace`, by `inferInstance`, though we leave this implicit) in the `Countable` case, Co-authored-by: Terence Tao --- .../MeasurableSpace/Constructions.lean | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index fbca0ba2d91c90..05898d572f1af7 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -962,6 +962,46 @@ protected lemma Measurable.subset {s t : β → Set α} (hs : Measurable s) (hs end Set +section Finset +variable [MeasurableSpace β] {g : β → Finset α} + +/-- We give `Finset α` the measurable structure inherited from `Set α`. + +This is the smallest sigma-algebra generated by `(a ∈ ·)` for all `a : α`. +See `measurable_finset_iff`. -/ +instance Finset.instMeasurableSpace : MeasurableSpace (Finset α) := + .comap SetLike.coe inferInstance + +lemma measurable_finset_iff_measurable_set : Measurable g ↔ Measurable (fun x ↦ (g x : Set α)) := + measurable_comap_iff + +lemma measurable_finset_iff : Measurable g ↔ ∀ a, Measurable (a ∈ g ·) := by + rw [measurable_finset_iff_measurable_set, measurable_set_iff]; rfl + +lemma measurableSet_finset_iff (S : Set (Finset α)) : MeasurableSet S ↔ + ∃ S' : Set (Set α), MeasurableSet S' ∧ { s : Finset α | ↑s ∈ S'} = S := + MeasurableSpace.measurableSet_comap + +@[fun_prop] +lemma measurable_finset_mem (a : α) : Measurable fun s : Finset α ↦ a ∈ s := + (measurable_set_mem a).comp (comap_measurable _) + +lemma measurable_finset_notMem (a : α) : Measurable fun s : Finset α ↦ a ∉ s := + (measurable_set_notMem a).comp (comap_measurable _) + +lemma measurableSet_mem_finset (a : α) : MeasurableSet {s : Finset α | a ∈ s} := + measurableSet_setOf.2 <| measurable_finset_mem _ + +lemma measurableSet_notMem_finset (a : α) : MeasurableSet {s : Finset α | a ∉ s} := + measurableSet_setOf.2 <| measurable_finset_notMem _ + +variable [Countable α] + +instance Finset.instMeasurableSingletonClass : MeasurableSingletonClass (Finset α) := + .mk fun S ↦ (measurableSet_finset_iff _).mpr ⟨{↑S}, by simp, by ext; simp⟩ + +end Finset + section curry variable {ι : Type*} From c82fea15599208dffc053c1d6353e4a978097387 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:14:37 +0000 Subject: [PATCH 0450/1300] feat(MeasureTheory/MeasurableSpace/Basic): add map_comap_eq_of_surjective and measurable_comap_iff_right (#41090) [We have nine map_comap_eq_of_surjective lemmas](https://loogle.lean-lang.org/?q=%22map_comap_eq_self_of_surjective%22) for `Submonoid`, `Subgroup`, `Subring`, etc., but were lacking one for `MeasurableSpace`. This PR adds the analogous lemma; as an application it also establishes a dual version of `measurable_comap_iff` involving composition on the right rather than the left. Co-authored-by: Terence Tao --- Mathlib/MeasureTheory/MeasurableSpace/Basic.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean index f092dbf255e704..b6c6a77ec7f4fb 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean @@ -152,6 +152,11 @@ theorem comap_map_le : (m.map f).comap f ≤ m := theorem le_map_comap : m ≤ (m.comap g).map g := (gc_comap_map g).le_u_l _ +theorem map_comap_eq_of_surjective (hg : Function.Surjective g) : (m.comap g).map g = m := by + refine le_antisymm (fun S hS => ?_) le_map_comap + rw [map_def, measurableSet_comap] at hS + aesop + end Functors @[simp] theorem map_const {m} (b : β) : MeasurableSpace.map (fun _a : α ↦ b) m = ⊤ := @@ -200,6 +205,10 @@ lemma measurable_comap_iff {mα : MeasurableSpace α} {mγ : MeasurableSpace γ} {f : α → β} {g : β → γ} : Measurable[mα, mγ.comap g] f ↔ Measurable (g ∘ f) := by simp [measurable_iff_comap_le] +lemma measurable_comap_iff_right {mβ : MeasurableSpace β} {mγ : MeasurableSpace γ} {g : α → β} + {f : β → γ} (hg : Function.Surjective g) : Measurable f ↔ Measurable[mβ.comap g] (f ∘ g) := by + rw [measurable_iff_le_map, measurable_iff_le_map, ← map_comp, map_comap_eq_of_surjective hg] + theorem Measurable.mono {ma ma' : MeasurableSpace α} {mb mb' : MeasurableSpace β} {f : α → β} (hf : @Measurable α β ma mb f) (ha : ma ≤ ma') (hb : mb' ≤ mb) : @Measurable α β ma' mb' f := fun _t ht => ha _ <| hf <| hb _ ht From 8a9a2284f07b10a6038730dffa7fee78249f9337 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:14:39 +0000 Subject: [PATCH 0451/1300] refactor(NumberTheory/NumberField/Ideal/KummerDedekind): switch to new definitions of ramification index and inertia degree (#41185) This PR switches `KummerDedekind.lean` over to the new definitions of ramification index and inertia degree. Co-authored-by: tb65536 --- .../NumberField/Cyclotomic/Ideal.lean | 3 +-- .../NumberField/Ideal/KummerDedekind.lean | 26 +++++++++++-------- .../RamificationInertia/Ramification.lean | 24 +++++++++++++++-- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index af04ef34127885..2d590f3a66b38d 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -305,7 +305,6 @@ theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : rw [Multiset.mem_toFinset, Polynomial.mem_normalizedFactors_iff (map_monic_ne_zero (minpoly.monic ζ.isIntegral))] at h₂ have : P.IsMaximal := .of_liesOver_isMaximal P 𝒑 - rw [← inertiaDeg_eq_inertiaDeg' 𝒑] rw [h₃, natDegree_of_dvd_cyclotomic_of_irreducible (by simp) hm (f := 1) _ h₂.1] · simpa using (orderOf_injective _ Units.coeHom_injective (ZMod.unitOfCoprime p hm)).symm · refine dvd_trans h₂.2.2 ?_ @@ -327,7 +326,7 @@ theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : simp only [Subtype.coe_eta, Equiv.symm_apply_apply] at h₃ rw [Multiset.mem_toFinset, Polynomial.mem_normalizedFactors_iff (map_monic_ne_zero (minpoly.monic ζ.isIntegral))] at h₂ - rw [← ramificationIdx_eq_ramificationIdx' 𝒑 P (by simpa using hp.out.ne_zero), h₃] + rw [h₃] refine multiplicity_eq_of_emultiplicity_eq_some (le_antisymm ?_ ?_) · apply emultiplicity_le_one_of_separable · exact isUnit_iff_degree_eq_zero.not.mpr (Irreducible.degree_pos h₂.1).ne' diff --git a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean index aa4c253c42aaef..2927ab9ed755d9 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean @@ -7,7 +7,7 @@ module public import Mathlib.NumberTheory.KummerDedekind public import Mathlib.NumberTheory.NumberField.Basic -public import Mathlib.NumberTheory.RamificationInertia.Basic +public import Mathlib.RingTheory.RamificationInertia.Basic public import Mathlib.RingTheory.Ideal.Int /-! @@ -209,20 +209,24 @@ The residual degree of the ideal corresponding to the class of `Q ∈ ℤ[X]` mo -/ theorem inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ exponent θ) {Q : ℤ[X]} (hQ : Q.map (Int.castRingHom (ZMod p)) ∈ monicFactorsMod θ p) : - inertiaDeg (span {(p : ℤ)}) ((primesOverSpanEquivMonicFactorsMod hp).symm - ⟨Q.map (Int.castRingHom (ZMod p)), hQ⟩ : Ideal (𝓞 K)) = + inertiaDeg' ((primesOverSpanEquivMonicFactorsMod hp).symm + ⟨Q.map (Int.castRingHom (ZMod p)), hQ⟩ : Ideal (𝓞 K)) ℤ = natDegree (Q.map (Int.castRingHom (ZMod p))) := by -- This is needed for `inertiaDeg_algebraMap` below to work + have : (span {↑p, (aeval θ) Q}).IsMaximal := by + rw [← Ideal.primesOverSpanEquivMonicFactorsMod_symm_apply_eq_span hp hQ] + apply Ideal.primesOver.isMaximal have := liesOver_primesOverSpanEquivMonicFactorsMod_symm hp hQ - rw [primesOverSpanEquivMonicFactorsMod_symm_apply_eq_span, inertiaDeg_algebraMap, + rw [primesOverSpanEquivMonicFactorsMod_symm_apply_eq_span, + ← inertiaDeg_eq_inertiaDeg' (span {(p : ℤ)}), inertiaDeg_algebraMap, ← finrank_quotient_span_eq_natDegree] refine Algebra.finrank_eq_of_equiv_equiv (Int.quotientSpanNatEquivZMod p) ?_ (by ext; simp) exact (ZModXQuotSpanEquivQuotSpanPair hp hQ).symm theorem inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply' (hp : ¬ p ∣ exponent θ) {Q : (ZMod p)[X]} (hQ : Q ∈ monicFactorsMod θ p) : - inertiaDeg (span {(p : ℤ)}) - ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q, hQ⟩ : Ideal (𝓞 K)) = natDegree Q := by + inertiaDeg' + ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q, hQ⟩ : Ideal (𝓞 K)) ℤ = natDegree Q := by obtain ⟨S, rfl⟩ := (map_surjective _ (ZMod.ringHom_surjective (Int.castRingHom (ZMod p)))) Q rw [inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply] @@ -233,12 +237,12 @@ The ramification index of the ideal corresponding to the class of `Q ∈ ℤ[X]` -/ theorem ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ exponent θ) {Q : ℤ[X]} (hQ : Q.map (Int.castRingHom (ZMod p)) ∈ monicFactorsMod θ p) : - ramificationIdx (span {(p : ℤ)}) + ramificationIdx' ((primesOverSpanEquivMonicFactorsMod hp).symm - ⟨Q.map (Int.castRingHom (ZMod p)), hQ⟩ : Ideal (𝓞 K)) = + ⟨Q.map (Int.castRingHom (ZMod p)), hQ⟩ : Ideal (𝓞 K)) ℤ = multiplicity (Q.map (Int.castRingHom (ZMod p))) ((minpoly ℤ θ).map (Int.castRingHom (ZMod p))) := by - rw [ramificationIdx_eq_multiplicity (map_ne_bot_of_ne_bot (by simp [NeZero.ne p])) inferInstance] + rw [ramificationIdx'_eq_multiplicity (span {↑p}) _ (map_ne_bot_of_ne_bot (by simp [NeZero.ne p]))] · apply multiplicity_eq_of_emultiplicity_eq rw [← emultiplicity_map_eq (mapEquiv (Int.quotientSpanNatEquivZMod p).symm), emultiplicity_factors_map_eq_emultiplicity inferInstance (by simp [NeZero.ne p]) @@ -251,8 +255,8 @@ theorem ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p theorem ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply' (hp : ¬ p ∣ exponent θ) {Q : (ZMod p)[X]} (hQ : Q ∈ monicFactorsMod θ p) : - ramificationIdx (span {(p : ℤ)}) - ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q, hQ⟩ : Ideal (𝓞 K)) = + ramificationIdx' + ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q, hQ⟩ : Ideal (𝓞 K)) ℤ = multiplicity Q ((minpoly ℤ θ).map (Int.castRingHom (ZMod p))) := by obtain ⟨S, rfl⟩ := (map_surjective _ (ZMod.ringHom_surjective (Int.castRingHom (ZMod p)))) Q rw [ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply] diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index d5c5087ee3342a..efa78e6c1f7753 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -145,8 +145,11 @@ theorem ramificationIdx_eq_ramificationIdx' [IsDomain R] [IsDedekindDomain S] have hpS : p.map (algebraMap R S) ≠ ⊥ := map_ne_bot_of_ne_bot hp exact ramificationIdx_eq_ramificationIdx'' p q hpS -open UniqueFactorizationMonoid in -theorem IsDedekindDomain.ramificationIdx'_eq_factors_count [IsDedekindDomain S] +namespace IsDedekindDomain + +open UniqueFactorizationMonoid + +theorem ramificationIdx'_eq_factors_count [IsDedekindDomain S] [q.LiesOver p] (hp0 : p.map (algebraMap R S) ≠ ⊥) : q.ramificationIdx' R = (factors (p.map (algebraMap R S))).count q := by by_cases hq : q.IsPrime; swap @@ -156,6 +159,23 @@ theorem IsDedekindDomain.ramificationIdx'_eq_factors_count [IsDedekindDomain S] have hq0 : q ≠ ⊥ := ne_bot_of_le_ne_bot hp0 (map_le_of_le_comap (q.over_def p).le) rw [← ramificationIdx_eq_ramificationIdx'' p q hp0, ramificationIdx_eq_factors_count hp0 ‹_› hq0] +open UniqueFactorizationMonoid in +theorem ramificationIdx'_eq_normalizedFactors_count [IsDedekindDomain S] + [q.LiesOver p] (hp0 : p.map (algebraMap R S) ≠ ⊥) : + q.ramificationIdx' R = (normalizedFactors (p.map (algebraMap R S))).count q := by + rw [← factors_eq_normalizedFactors, ← ramificationIdx'_eq_factors_count p q hp0] + +open UniqueFactorizationMonoid in +theorem ramificationIdx'_eq_multiplicity [IsDedekindDomain S] + [q.IsPrime] [q.LiesOver p] (hp : p.map (algebraMap R S) ≠ ⊥) : + q.ramificationIdx' R = multiplicity q (p.map (algebraMap R S)) := by + have hq : q ≠ ⊥ := ne_bot_of_le_ne_bot hp (map_le_of_le_comap (q.over_def p).le) + rw [ramificationIdx'_eq_normalizedFactors_count p q hp, + multiplicity_eq_of_emultiplicity_eq_some (emultiplicity_eq_count_normalizedFactors + (prime_of_isPrime hq inferInstance).irreducible hp), normalize_eq] + +end IsDedekindDomain + /-- See `ramificationIdx'_tower` for a version that does not assume primality. -/ theorem ramificationIdx'_tower' [q.IsPrime] [r.IsPrime] [r.LiesOver q] [Algebra (Localization.AtPrime q) (Localization.AtPrime r)] From caf2c7a12044ea9685e72fe9b5d709daeb1d5c51 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:30:35 +0000 Subject: [PATCH 0452/1300] chore(MeasureTheory): remove redundant imports (#40832) This PR removes redundant imports in `MeasureTheory`. In particular, it checks for every file for each import if it can be removed and the file still built. This of course can be done in the entirety of mathlib as well, but that would be a bit much (since this PR is already big). In rare cases, some imports needed to be brought back / added, due to stuff like: A imports B, B imports C (but doesnt use it), but A uses it. Obviously this was done with a script. Co-authored-by: Batixx --- Mathlib/Analysis/Complex/Harmonic/Liouville.lean | 1 + Mathlib/Analysis/Complex/Schwarz.lean | 1 + Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean | 2 -- Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean | 1 - Mathlib/MeasureTheory/Constructions/HaarToSphere.lean | 1 - Mathlib/MeasureTheory/Constructions/Pi.lean | 2 -- Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean | 1 - Mathlib/MeasureTheory/Covering/DensityTheorem.lean | 1 - Mathlib/MeasureTheory/Covering/Differentiation.lean | 1 - Mathlib/MeasureTheory/Covering/Vitali.lean | 1 - Mathlib/MeasureTheory/Function/AEEqFun/DomAct.lean | 2 -- Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean | 1 - .../Function/ConditionalExpectation/CondexpL1.lean | 1 - .../Function/ConditionalExpectation/CondexpL2.lean | 1 - .../Function/ConditionalExpectation/LebesgueBochner.lean | 2 +- .../Function/ConditionalExpectation/RadonNikodym.lean | 3 +-- Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean | 1 - Mathlib/MeasureTheory/Function/ContinuousMapDense.lean | 2 -- Mathlib/MeasureTheory/Function/EssSup.lean | 2 -- Mathlib/MeasureTheory/Function/FactorsThrough.lean | 1 - Mathlib/MeasureTheory/Function/Jacobian.lean | 4 ---- Mathlib/MeasureTheory/Function/L2Space.lean | 2 -- Mathlib/MeasureTheory/Function/LpOrder.lean | 2 -- Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean | 1 - Mathlib/MeasureTheory/Function/LpSeminorm/CompareExp.lean | 1 - Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean | 1 - Mathlib/MeasureTheory/Function/LpSeminorm/Prod.lean | 1 - .../MeasureTheory/Function/LpSpace/CompleteOfCompleteLp.lean | 3 --- .../MeasureTheory/Function/LpSpace/ContinuousFunctions.lean | 1 - Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean | 1 - Mathlib/MeasureTheory/Function/SpecialFunctions/Sinc.lean | 1 - .../MeasureTheory/Function/StronglyMeasurable/Lemmas.lean | 1 - Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean | 1 - Mathlib/MeasureTheory/Function/UnifTight.lean | 1 - Mathlib/MeasureTheory/Function/UniformIntegrable.lean | 1 - Mathlib/MeasureTheory/Group/AEStabilizer.lean | 1 - Mathlib/MeasureTheory/Group/Action.lean | 3 --- Mathlib/MeasureTheory/Group/AddCircle.lean | 1 - Mathlib/MeasureTheory/Group/FoelnerFilter.lean | 2 -- Mathlib/MeasureTheory/Group/FundamentalDomain.lean | 3 --- Mathlib/MeasureTheory/Group/Integral.lean | 1 + Mathlib/MeasureTheory/Group/IntegralConvolution.lean | 1 - Mathlib/MeasureTheory/Group/Measure.lean | 1 - Mathlib/MeasureTheory/Group/ModularCharacter.lean | 5 ----- Mathlib/MeasureTheory/Group/Prod.lean | 1 - Mathlib/MeasureTheory/Integral/Asymptotics.lean | 1 - Mathlib/MeasureTheory/Integral/Bochner/Basic.lean | 4 ---- Mathlib/MeasureTheory/Integral/Bochner/SumMeasure.lean | 1 + .../MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean | 3 --- Mathlib/MeasureTheory/Integral/CircleAverage.lean | 1 - Mathlib/MeasureTheory/Integral/CircleTransform.lean | 1 - Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean | 1 - Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean | 1 - Mathlib/MeasureTheory/Integral/DominatedConvergence.lean | 1 - Mathlib/MeasureTheory/Integral/ExpDecay.lean | 1 - Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean | 2 -- .../Integral/IntervalIntegral/AbsolutelyContinuousFun.lean | 1 - .../Integral/IntervalIntegral/DerivIntegrable.lean | 1 - .../Integral/IntervalIntegral/DistLEIntegral.lean | 2 -- .../Integral/IntervalIntegral/FundThmCalculus.lean | 2 -- .../MeasureTheory/Integral/IntervalIntegral/Periodic.lean | 2 -- Mathlib/MeasureTheory/Integral/Prod.lean | 2 -- Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean | 1 - Mathlib/MeasureTheory/Integral/TorusIntegral.lean | 2 -- Mathlib/MeasureTheory/MeasurableSpace/Defs.lean | 1 - .../MeasureTheory/Measure/CharacteristicFunction/Basic.lean | 2 -- Mathlib/MeasureTheory/Measure/Content.lean | 1 - Mathlib/MeasureTheory/Measure/Count.lean | 1 - Mathlib/MeasureTheory/Measure/FiniteMeasure.lean | 1 - Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean | 1 - Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean | 2 -- Mathlib/MeasureTheory/Measure/Haar/Extension.lean | 1 - Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean | 1 - Mathlib/MeasureTheory/Measure/Haar/Quotient.lean | 3 --- Mathlib/MeasureTheory/Measure/Haar/Unique.lean | 3 --- Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean | 1 + Mathlib/MeasureTheory/Measure/Hausdorff.lean | 1 - Mathlib/MeasureTheory/Measure/IntegralCharFun.lean | 1 - Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean | 3 --- Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean | 5 ----- Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean | 2 -- Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean | 1 - Mathlib/MeasureTheory/Measure/NullMeasurable.lean | 1 - Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean | 1 - Mathlib/MeasureTheory/Measure/RegularityCompacts.lean | 3 --- Mathlib/MeasureTheory/Measure/Restrict.lean | 2 -- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 1 - Mathlib/MeasureTheory/Measure/SubFinite.lean | 1 - Mathlib/MeasureTheory/Measure/WithDensity.lean | 1 - Mathlib/MeasureTheory/Order/Group/Lattice.lean | 1 - Mathlib/MeasureTheory/Order/UpperLower.lean | 1 - Mathlib/MeasureTheory/OuterMeasure/Basic.lean | 3 --- Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean | 1 - Mathlib/MeasureTheory/SetSemiring.lean | 3 --- Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean | 1 - Mathlib/MeasureTheory/VectorMeasure/Basic.lean | 1 - Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean | 1 - Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean | 1 + .../MeasureTheory/VectorMeasure/Variation/Semivariation.lean | 1 - 99 files changed, 8 insertions(+), 146 deletions(-) diff --git a/Mathlib/Analysis/Complex/Harmonic/Liouville.lean b/Mathlib/Analysis/Complex/Harmonic/Liouville.lean index 4440e10c032cda..bd948e355b8688 100644 --- a/Mathlib/Analysis/Complex/Harmonic/Liouville.lean +++ b/Mathlib/Analysis/Complex/Harmonic/Liouville.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Complex.Liouville public import Mathlib.Analysis.Complex.Harmonic.Analytic +public import Mathlib.Analysis.Normed.Module.HahnBanach /-! # Liouville's Theorem for Harmonic Functions on the Complex Plane diff --git a/Mathlib/Analysis/Complex/Schwarz.lean b/Mathlib/Analysis/Complex/Schwarz.lean index 930b181880faae..075078ce6ae7c6 100644 --- a/Mathlib/Analysis/Complex/Schwarz.lean +++ b/Mathlib/Analysis/Complex/Schwarz.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Complex.AbsMax public import Mathlib.Analysis.Complex.RemovableSingularity +public import Mathlib.Analysis.Normed.Module.HahnBanach /-! # Schwarz lemma diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index 6d155826e04879..966522788b9a5e 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -7,8 +7,6 @@ module public import Mathlib.MeasureTheory.Group.Arithmetic public import Mathlib.Topology.GDelta.MetrizableSpace -public import Mathlib.Topology.Instances.EReal.Lemmas -public import Mathlib.Topology.Instances.Rat /-! # Borel (measurable) space diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index e21b260f6f9a0e..20c22dc9b98969 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -5,7 +5,6 @@ Authors: Johannes Hölzl, Yury Kudryashov, Kexing Ying -/ module -public import Mathlib.Topology.Semicontinuity.Basic public import Mathlib.MeasureTheory.Function.AEMeasurableSequence public import Mathlib.MeasureTheory.Order.Lattice public import Mathlib.Topology.Order.Lattice diff --git a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean index 73adacc13b0eb5..63ebf1c46e112e 100644 --- a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean +++ b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean @@ -9,7 +9,6 @@ public import Mathlib.Algebra.Order.Field.Pointwise public import Mathlib.Analysis.Normed.Module.Ball.RadialEquiv public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic public import Mathlib.MeasureTheory.Integral.Prod -public import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar /-! # Generalized polar coordinate change diff --git a/Mathlib/MeasureTheory/Constructions/Pi.lean b/Mathlib/MeasureTheory/Constructions/Pi.lean index a6f81db9f328c4..c025ed63bbb813 100644 --- a/Mathlib/MeasureTheory/Constructions/Pi.lean +++ b/Mathlib/MeasureTheory/Constructions/Pi.lean @@ -9,8 +9,6 @@ public import Mathlib.Algebra.BigOperators.Fin public import Mathlib.Logic.Encodable.Pi public import Mathlib.MeasureTheory.Group.Measure public import Mathlib.MeasureTheory.MeasurableSpace.Pi -public import Mathlib.MeasureTheory.Measure.Prod -public import Mathlib.Topology.Constructions /-! # Indexed product measures diff --git a/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean b/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean index 932bfe42ec0516..2d53c3ab68fcff 100644 --- a/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean +++ b/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean @@ -8,7 +8,6 @@ module public import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar public import Mathlib.MeasureTheory.Covering.Besicovitch public import Mathlib.Tactic.AdaptationNote -public import Mathlib.Algebra.EuclideanDomain.Basic /-! # Satellite configurations for Besicovitch covering lemma in vector spaces diff --git a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean index 27704ab5d8d7e9..f1e975f25ca496 100644 --- a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean +++ b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean @@ -5,7 +5,6 @@ Authors: Oliver Nash -/ module -public import Mathlib.MeasureTheory.Measure.Doubling public import Mathlib.MeasureTheory.Covering.Vitali public import Mathlib.MeasureTheory.Covering.Differentiation diff --git a/Mathlib/MeasureTheory/Covering/Differentiation.lean b/Mathlib/MeasureTheory/Covering/Differentiation.lean index e90d23eca85b0d..f9dc88c5d184dd 100644 --- a/Mathlib/MeasureTheory/Covering/Differentiation.lean +++ b/Mathlib/MeasureTheory/Covering/Differentiation.lean @@ -9,7 +9,6 @@ public import Mathlib.MeasureTheory.Covering.VitaliFamily public import Mathlib.MeasureTheory.Function.AEMeasurableOrder public import Mathlib.MeasureTheory.Integral.Average public import Mathlib.MeasureTheory.Measure.Decomposition.Lebesgue -public import Mathlib.MeasureTheory.Measure.Regular /-! # Differentiation of measures diff --git a/Mathlib/MeasureTheory/Covering/Vitali.lean b/Mathlib/MeasureTheory/Covering/Vitali.lean index bc367b164c4593..f708ea56c5007e 100644 --- a/Mathlib/MeasureTheory/Covering/Vitali.lean +++ b/Mathlib/MeasureTheory/Covering/Vitali.lean @@ -7,7 +7,6 @@ module public import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic public import Mathlib.MeasureTheory.Covering.VitaliFamily -public import Mathlib.Data.Set.Pairwise.Lattice /-! # Vitali covering theorems diff --git a/Mathlib/MeasureTheory/Function/AEEqFun/DomAct.lean b/Mathlib/MeasureTheory/Function/AEEqFun/DomAct.lean index 3e35fb46c6846f..06992682a92cf0 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun/DomAct.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun/DomAct.lean @@ -6,8 +6,6 @@ Authors: Yury Kudryashov module public import Mathlib.MeasureTheory.Function.AEEqFun -public import Mathlib.MeasureTheory.Group.Action -public import Mathlib.GroupTheory.GroupAction.DomAct.Basic public import Mathlib.MeasureTheory.Function.StronglyMeasurable.Lemmas /-! # Action of `DomMulAct` and `DomAddAct` on `α →ₘ[μ] β` diff --git a/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean b/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean index 93dc03e76b71ef..498d2a02cd2f96 100644 --- a/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean +++ b/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean @@ -5,7 +5,6 @@ Authors: Rémy Degenne -/ module -public import Mathlib.MeasureTheory.MeasurableSpace.Basic public import Mathlib.MeasureTheory.Measure.MeasureSpaceDef /-! diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean index 02e96a6e6284dd..2e679c127c22f6 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean @@ -7,7 +7,6 @@ module public import Mathlib.MeasureTheory.Function.LpSpace.CompleteOfCompleteLp public import Mathlib.MeasureTheory.Function.ConditionalExpectation.CondexpL2 -public import Mathlib.MeasureTheory.Measure.Real /-! # Conditional expectation in L1 diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean index 34ade67b737921..11d4636a70d5e6 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean @@ -5,7 +5,6 @@ Authors: Rémy Degenne -/ module -public import Mathlib.Analysis.InnerProductSpace.Projection.Basic public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Unique public import Mathlib.MeasureTheory.Function.L2Space diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/LebesgueBochner.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/LebesgueBochner.lean index 9f349a7be4eaba..8da069eb28fccc 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/LebesgueBochner.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/LebesgueBochner.lean @@ -6,8 +6,8 @@ Authors: Rémy Degenne module -public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Basic public import Mathlib.MeasureTheory.Function.ConditionalLExpectation +public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Basic /-! # Results about both conditional expectations diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/RadonNikodym.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/RadonNikodym.lean index 14f9101d8a0118..a4cfeffc82916c 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/RadonNikodym.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/RadonNikodym.lean @@ -5,9 +5,8 @@ Authors: Rémy Degenne -/ module -public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Basic public import Mathlib.MeasureTheory.Function.ConditionalLExpectation -public import Mathlib.MeasureTheory.Measure.Decomposition.Lebesgue +public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Basic import Mathlib.MeasureTheory.Measure.Decomposition.IntegralRNDeriv import Mathlib.MeasureTheory.Function.ConditionalExpectation.LebesgueBochner diff --git a/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean b/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean index dc91e30d562b2c..4e7c80eed2058a 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean @@ -9,7 +9,6 @@ public import Mathlib.MeasureTheory.Measure.Decomposition.Lebesgue import Mathlib.MeasureTheory.Measure.Decomposition.RadonNikodym import Mathlib.Probability.Notation -public import Mathlib.Probability.Notation /-! # Conditional Lebesgue expectation diff --git a/Mathlib/MeasureTheory/Function/ContinuousMapDense.lean b/Mathlib/MeasureTheory/Function/ContinuousMapDense.lean index 347078a2082a36..81038233b5104e 100644 --- a/Mathlib/MeasureTheory/Function/ContinuousMapDense.lean +++ b/Mathlib/MeasureTheory/Function/ContinuousMapDense.lean @@ -5,8 +5,6 @@ Authors: Heather Macbeth -/ module -public import Mathlib.MeasureTheory.Measure.Regular -public import Mathlib.MeasureTheory.Function.SimpleFuncDenseLp public import Mathlib.Topology.UrysohnsLemma public import Mathlib.MeasureTheory.Function.LpSpace.ContinuousFunctions public import Mathlib.MeasureTheory.Integral.Bochner.Basic diff --git a/Mathlib/MeasureTheory/Function/EssSup.lean b/Mathlib/MeasureTheory/Function/EssSup.lean index 8e9f3f7228b0e8..042866c1a7e53f 100644 --- a/Mathlib/MeasureTheory/Function/EssSup.lean +++ b/Mathlib/MeasureTheory/Function/EssSup.lean @@ -5,8 +5,6 @@ Authors: Rémy Degenne -/ module -public import Mathlib.MeasureTheory.Constructions.BorelSpace.Order -public import Mathlib.MeasureTheory.Measure.Count public import Mathlib.Order.Filter.ENNReal public import Mathlib.Probability.UniformOn diff --git a/Mathlib/MeasureTheory/Function/FactorsThrough.lean b/Mathlib/MeasureTheory/Function/FactorsThrough.lean index ac036aed412880..11d9a0fc7c5160 100644 --- a/Mathlib/MeasureTheory/Function/FactorsThrough.lean +++ b/Mathlib/MeasureTheory/Function/FactorsThrough.lean @@ -5,7 +5,6 @@ Authors: Etienne Marion -/ module -public import Mathlib.MeasureTheory.Constructions.Polish.StronglyMeasurable public import Mathlib.Probability.Process.Filtration /-! diff --git a/Mathlib/MeasureTheory/Function/Jacobian.lean b/Mathlib/MeasureTheory/Function/Jacobian.lean index e18fc62dd59fa7..4df52b8c00a28a 100644 --- a/Mathlib/MeasureTheory/Function/Jacobian.lean +++ b/Mathlib/MeasureTheory/Function/Jacobian.lean @@ -8,11 +8,7 @@ module public import Mathlib.Analysis.Calculus.FDeriv.Congr public import Mathlib.MeasureTheory.Constructions.BorelSpace.ContinuousLinearMap public import Mathlib.MeasureTheory.Covering.BesicovitchVectorSpace -public import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar -public import Mathlib.Analysis.Normed.Module.Ball.Pointwise -public import Mathlib.MeasureTheory.Constructions.Polish.Basic public import Mathlib.Analysis.Calculus.InverseFunctionTheorem.ApproximatesLinearOn -public import Mathlib.Topology.Algebra.Module.Determinant /-! # Change of variables in higher-dimensional integrals diff --git a/Mathlib/MeasureTheory/Function/L2Space.lean b/Mathlib/MeasureTheory/Function/L2Space.lean index 4f5c79ce5e14dc..8431ba00bd432c 100644 --- a/Mathlib/MeasureTheory/Function/L2Space.lean +++ b/Mathlib/MeasureTheory/Function/L2Space.lean @@ -6,8 +6,6 @@ Authors: Rémy Degenne module public import Mathlib.Analysis.InnerProductSpace.GramMatrix -public import Mathlib.Analysis.InnerProductSpace.LinearMap -public import Mathlib.Analysis.RCLike.Lemmas public import Mathlib.MeasureTheory.Function.LpSpace.ContinuousFunctions public import Mathlib.MeasureTheory.Function.StronglyMeasurable.Inner public import Mathlib.MeasureTheory.Integral.Bochner.ContinuousLinearMap diff --git a/Mathlib/MeasureTheory/Function/LpOrder.lean b/Mathlib/MeasureTheory/Function/LpOrder.lean index e28f57d227f38a..c846924343ac54 100644 --- a/Mathlib/MeasureTheory/Function/LpOrder.lean +++ b/Mathlib/MeasureTheory/Function/LpOrder.lean @@ -5,9 +5,7 @@ Authors: Rémy Degenne -/ module -public import Mathlib.Analysis.Normed.Order.Lattice public import Mathlib.MeasureTheory.Function.ConvergenceInMeasure -public import Mathlib.MeasureTheory.Function.LpSpace.Basic /-! # Order related properties of Lp spaces diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index 1e18c385d5293c..15c786f85e26ca 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -9,7 +9,6 @@ public import Mathlib.Data.Fintype.Order public import Mathlib.MeasureTheory.Function.AEEqFun public import Mathlib.MeasureTheory.Function.LpSeminorm.Defs public import Mathlib.MeasureTheory.Function.SpecialFunctions.Basic -public import Mathlib.MeasureTheory.Integral.Lebesgue.Countable /-! # Basic theorems about ℒp space diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/CompareExp.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/CompareExp.lean index bef5c5cfd5ee27..876635b9437d6d 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/CompareExp.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/CompareExp.lean @@ -5,7 +5,6 @@ Authors: Rémy Degenne, Eric Wieser -/ module -public import Mathlib.Data.ENNReal.Holder public import Mathlib.MeasureTheory.Function.LpSeminorm.Indicator public import Mathlib.MeasureTheory.Function.LpSeminorm.SMul public import Mathlib.MeasureTheory.Integral.MeanInequalities diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean index 3149a3d292d58f..1bf1d4daa46fff 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean @@ -8,7 +8,6 @@ module public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal public import Mathlib.MeasureTheory.Function.EssSup public import Mathlib.MeasureTheory.Function.StronglyMeasurable.AEStronglyMeasurable -public import Mathlib.MeasureTheory.Integral.Lebesgue.Basic /-! # ℒp space diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Prod.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Prod.lean index 31d12b1d172ce2..61c3be1d93ee87 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Prod.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Prod.lean @@ -6,7 +6,6 @@ Authors: Rémy Degenne module public import Mathlib.MeasureTheory.Function.LpSeminorm.Basic -public import Mathlib.MeasureTheory.Measure.Prod /-! # ℒp spaces and products diff --git a/Mathlib/MeasureTheory/Function/LpSpace/CompleteOfCompleteLp.lean b/Mathlib/MeasureTheory/Function/LpSpace/CompleteOfCompleteLp.lean index 82649b61808f46..298438c512f99e 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/CompleteOfCompleteLp.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/CompleteOfCompleteLp.lean @@ -5,9 +5,6 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.Analysis.Normed.Operator.Mul -public import Mathlib.MeasureTheory.Function.ConvergenceInMeasure -public import Mathlib.MeasureTheory.Function.LpSpace.Complete public import Mathlib.MeasureTheory.Function.StronglyMeasurable.Lp /-! diff --git a/Mathlib/MeasureTheory/Function/LpSpace/ContinuousFunctions.lean b/Mathlib/MeasureTheory/Function/LpSpace/ContinuousFunctions.lean index 787dd02b647672..890ac7da030e22 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/ContinuousFunctions.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/ContinuousFunctions.lean @@ -7,7 +7,6 @@ module public import Mathlib.Analysis.Normed.Operator.NormedSpace public import Mathlib.MeasureTheory.Function.LpSpace.Basic -public import Mathlib.MeasureTheory.Measure.OpenPos public import Mathlib.Topology.ContinuousMap.Compact /-! diff --git a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean index b81ea770d8eefd..96eff255ca78e7 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean @@ -6,7 +6,6 @@ Authors: Zhouhang Zhou, Yury Kudryashov, Heather Macbeth module public import Mathlib.MeasureTheory.Function.L1Space.AEEqFun -public import Mathlib.MeasureTheory.Function.LpSpace.Complete public import Mathlib.MeasureTheory.Function.LpSpace.Indicator /-! diff --git a/Mathlib/MeasureTheory/Function/SpecialFunctions/Sinc.lean b/Mathlib/MeasureTheory/Function/SpecialFunctions/Sinc.lean index dce1607860fa43..ad8628019735d1 100644 --- a/Mathlib/MeasureTheory/Function/SpecialFunctions/Sinc.lean +++ b/Mathlib/MeasureTheory/Function/SpecialFunctions/Sinc.lean @@ -6,7 +6,6 @@ Authors: Rémy Degenne module public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Sinc -public import Mathlib.MeasureTheory.Function.SpecialFunctions.Basic public import Mathlib.MeasureTheory.Function.L1Space.Integrable /-! diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean index 179b8d2e1e18f4..f861c5f6d0e688 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean @@ -6,7 +6,6 @@ Authors: Rémy Degenne, Sébastien Gouëzel module public import Mathlib.Analysis.Normed.Operator.BoundedLinearMaps -public import Mathlib.Dynamics.Ergodic.MeasurePreserving public import Mathlib.MeasureTheory.Function.StronglyMeasurable.AEStronglyMeasurable public import Mathlib.MeasureTheory.Measure.WithDensity public import Mathlib.Topology.Algebra.Module.FiniteDimension diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean index fd29fbb9e2cff4..9655fb43723819 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean @@ -6,7 +6,6 @@ Authors: Rémy Degenne module public import Mathlib.MeasureTheory.Function.SimpleFuncDenseLp -public import Mathlib.MeasureTheory.Function.StronglyMeasurable.Lemmas /-! # Finitely strongly measurable functions in `Lp` diff --git a/Mathlib/MeasureTheory/Function/UnifTight.lean b/Mathlib/MeasureTheory/Function/UnifTight.lean index da99d5069c6ba9..8ae43e2c33eb48 100644 --- a/Mathlib/MeasureTheory/Function/UnifTight.lean +++ b/Mathlib/MeasureTheory/Function/UnifTight.lean @@ -5,7 +5,6 @@ Authors: Igor Khavkine -/ module -public import Mathlib.MeasureTheory.Function.ConvergenceInMeasure public import Mathlib.MeasureTheory.Function.UniformIntegrable /-! diff --git a/Mathlib/MeasureTheory/Function/UniformIntegrable.lean b/Mathlib/MeasureTheory/Function/UniformIntegrable.lean index 8844cd4a0538c6..8d2058fb69dd68 100644 --- a/Mathlib/MeasureTheory/Function/UniformIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/UniformIntegrable.lean @@ -5,7 +5,6 @@ Authors: Kexing Ying -/ module -public import Mathlib.MeasureTheory.Function.ConvergenceInMeasure public import Mathlib.MeasureTheory.Function.L1Space.Integrable /-! diff --git a/Mathlib/MeasureTheory/Group/AEStabilizer.lean b/Mathlib/MeasureTheory/Group/AEStabilizer.lean index 974575ccfaa36c..063144fc54b2bf 100644 --- a/Mathlib/MeasureTheory/Group/AEStabilizer.lean +++ b/Mathlib/MeasureTheory/Group/AEStabilizer.lean @@ -6,7 +6,6 @@ Authors: Yury Kudryashov module public import Mathlib.MeasureTheory.Group.Action -public import Mathlib.Order.Filter.EventuallyConst /-! # A.e. stabilizer of a set diff --git a/Mathlib/MeasureTheory/Group/Action.lean b/Mathlib/MeasureTheory/Group/Action.lean index 1c421500555465..eeb56066690caa 100644 --- a/Mathlib/MeasureTheory/Group/Action.lean +++ b/Mathlib/MeasureTheory/Group/Action.lean @@ -7,11 +7,8 @@ module public import Mathlib.Dynamics.Ergodic.MeasurePreserving public import Mathlib.Dynamics.Minimal -public import Mathlib.GroupTheory.GroupAction.Hom -public import Mathlib.MeasureTheory.Group.MeasurableEquiv public import Mathlib.MeasureTheory.Measure.Regular public import Mathlib.MeasureTheory.Group.Defs -public import Mathlib.Order.Filter.EventuallyConst /-! # Measures invariant under group actions diff --git a/Mathlib/MeasureTheory/Group/AddCircle.lean b/Mathlib/MeasureTheory/Group/AddCircle.lean index c6349dc3a5d5ec..1274c8372799de 100644 --- a/Mathlib/MeasureTheory/Group/AddCircle.lean +++ b/Mathlib/MeasureTheory/Group/AddCircle.lean @@ -6,7 +6,6 @@ Authors: Oliver Nash module public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Periodic -public import Mathlib.Data.ZMod.QuotientGroup public import Mathlib.MeasureTheory.Group.AEStabilizer /-! diff --git a/Mathlib/MeasureTheory/Group/FoelnerFilter.lean b/Mathlib/MeasureTheory/Group/FoelnerFilter.lean index 054aa9a3ad1d93..2586b9b844e4c1 100644 --- a/Mathlib/MeasureTheory/Group/FoelnerFilter.lean +++ b/Mathlib/MeasureTheory/Group/FoelnerFilter.lean @@ -5,9 +5,7 @@ Authors: Yaël Dillies, Stefano Rocca -/ module -public import Mathlib.MeasureTheory.Group.Defs public import Mathlib.MeasureTheory.Group.Action -public import Mathlib.MeasureTheory.Measure.Typeclasses.Finite /-! # Følner sequences and filters - definitions and properties diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index b1f075c9200048..237ae6b34da3f9 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -5,9 +5,6 @@ Authors: Yury Kudryashov, Alex Kontorovich, Heather Macbeth -/ module -public import Mathlib.MeasureTheory.Group.Action -public import Mathlib.MeasureTheory.Group.Pointwise -public import Mathlib.MeasureTheory.Integral.Lebesgue.Map public import Mathlib.MeasureTheory.Integral.Bochner.Set /-! diff --git a/Mathlib/MeasureTheory/Group/Integral.lean b/Mathlib/MeasureTheory/Group/Integral.lean index df6e5ee5a0de4f..2b0913a40a5b65 100644 --- a/Mathlib/MeasureTheory/Group/Integral.lean +++ b/Mathlib/MeasureTheory/Group/Integral.lean @@ -6,6 +6,7 @@ Authors: Floris van Doorn module public import Mathlib.MeasureTheory.Integral.Bochner.Basic +public import Mathlib.MeasureTheory.Integral.IntegrableOn public import Mathlib.MeasureTheory.Group.Measure /-! diff --git a/Mathlib/MeasureTheory/Group/IntegralConvolution.lean b/Mathlib/MeasureTheory/Group/IntegralConvolution.lean index a2c0da03a44d25..3693c5c4ca3b52 100644 --- a/Mathlib/MeasureTheory/Group/IntegralConvolution.lean +++ b/Mathlib/MeasureTheory/Group/IntegralConvolution.lean @@ -5,7 +5,6 @@ Authors: Rémy Degenne -/ module -public import Mathlib.MeasureTheory.Group.Convolution public import Mathlib.MeasureTheory.Integral.Prod /-! diff --git a/Mathlib/MeasureTheory/Group/Measure.lean b/Mathlib/MeasureTheory/Group/Measure.lean index b90e3c15db511f..8686ad446ae983 100644 --- a/Mathlib/MeasureTheory/Group/Measure.lean +++ b/Mathlib/MeasureTheory/Group/Measure.lean @@ -12,7 +12,6 @@ public import Mathlib.MeasureTheory.Group.Pointwise public import Mathlib.MeasureTheory.Measure.Prod public import Mathlib.Topology.Algebra.Module.Equiv public import Mathlib.Topology.ContinuousMap.CocompactMap -public import Mathlib.Topology.Algebra.ContinuousMonoidHom /-! # Measures on Groups diff --git a/Mathlib/MeasureTheory/Group/ModularCharacter.lean b/Mathlib/MeasureTheory/Group/ModularCharacter.lean index f3b7f584eb3649..9ac2976d854fc5 100644 --- a/Mathlib/MeasureTheory/Group/ModularCharacter.lean +++ b/Mathlib/MeasureTheory/Group/ModularCharacter.lean @@ -5,12 +5,7 @@ Authors: Noam Atar -/ module -public import Mathlib.MeasureTheory.Function.LocallyIntegrable -public import Mathlib.MeasureTheory.Group.Integral -public import Mathlib.MeasureTheory.Group.Measure -public import Mathlib.Topology.Metrizable.Urysohn public import Mathlib.MeasureTheory.Measure.Haar.Unique -public import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic /-! # Modular character of a locally compact group diff --git a/Mathlib/MeasureTheory/Group/Prod.lean b/Mathlib/MeasureTheory/Group/Prod.lean index 50a52b5efd9f88..c26346b3c3955a 100644 --- a/Mathlib/MeasureTheory/Group/Prod.lean +++ b/Mathlib/MeasureTheory/Group/Prod.lean @@ -6,7 +6,6 @@ Authors: Floris van Doorn module public import Mathlib.MeasureTheory.Group.Measure -public import Mathlib.MeasureTheory.Measure.Prod /-! # Measure theory in the product of groups diff --git a/Mathlib/MeasureTheory/Integral/Asymptotics.lean b/Mathlib/MeasureTheory/Integral/Asymptotics.lean index bc9f1f337f9e9f..e942352e0cca11 100644 --- a/Mathlib/MeasureTheory/Integral/Asymptotics.lean +++ b/Mathlib/MeasureTheory/Integral/Asymptotics.lean @@ -5,7 +5,6 @@ Authors: Lawrence Wu -/ module -public import Mathlib.MeasureTheory.Group.Measure public import Mathlib.MeasureTheory.Integral.Bochner.ContinuousLinearMap /-! diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index 87f7e189d926d1..fab92ef18f6c86 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -5,11 +5,7 @@ Authors: Zhouhang Zhou, Yury Kudryashov, Sébastien Gouëzel, Rémy Degenne -/ module -public import Mathlib.MeasureTheory.Group.MeasurableEquiv public import Mathlib.MeasureTheory.Integral.Bochner.L1 -public import Mathlib.MeasureTheory.Integral.IntegrableOn -public import Mathlib.MeasureTheory.Measure.OpenPos -public import Mathlib.MeasureTheory.Measure.Real /-! # Bochner integral diff --git a/Mathlib/MeasureTheory/Integral/Bochner/SumMeasure.lean b/Mathlib/MeasureTheory/Integral/Bochner/SumMeasure.lean index 3eebbeb46aa873..a34b52e13c7423 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/SumMeasure.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/SumMeasure.lean @@ -6,6 +6,7 @@ Authors: Etienne Marion module public import Mathlib.MeasureTheory.Integral.Bochner.Basic +public import Mathlib.MeasureTheory.Integral.IntegrableOn import Mathlib.Analysis.Normed.Module.FiniteDimension diff --git a/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean b/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean index 1c83d9a1c4c386..58a130612dcecb 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean @@ -5,10 +5,7 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.MeasureTheory.Measure.Regular -public import Mathlib.Topology.Semicontinuity.Basic public import Mathlib.MeasureTheory.Integral.Bochner.Basic -public import Mathlib.Topology.Instances.EReal.Lemmas /-! # Vitali-Carathéodory theorem diff --git a/Mathlib/MeasureTheory/Integral/CircleAverage.lean b/Mathlib/MeasureTheory/Integral/CircleAverage.lean index 73b84211699661..11d99983cbf002 100644 --- a/Mathlib/MeasureTheory/Integral/CircleAverage.lean +++ b/Mathlib/MeasureTheory/Integral/CircleAverage.lean @@ -7,7 +7,6 @@ module public import Mathlib.MeasureTheory.Integral.CircleIntegral public import Mathlib.MeasureTheory.Integral.IntervalAverage -public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Periodic /-! # Circle Averages diff --git a/Mathlib/MeasureTheory/Integral/CircleTransform.lean b/Mathlib/MeasureTheory/Integral/CircleTransform.lean index 0cd653c004775c..72e288c0158436 100644 --- a/Mathlib/MeasureTheory/Integral/CircleTransform.lean +++ b/Mathlib/MeasureTheory/Integral/CircleTransform.lean @@ -5,7 +5,6 @@ Authors: Chris Birkbeck -/ module -public import Mathlib.Data.Complex.Basic public import Mathlib.MeasureTheory.Integral.CircleIntegral /-! diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index 4d7d68eff2b176..dd62fc98ff3080 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -9,7 +9,6 @@ public import Mathlib.Algebra.Order.Field.Pointwise public import Mathlib.Analysis.Calculus.ContDiff.Deriv public import Mathlib.Analysis.Calculus.Deriv.AffineMap public import Mathlib.Analysis.Calculus.Deriv.Shift -public import Mathlib.Analysis.Normed.Module.Convex public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic /-! diff --git a/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean b/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean index e921a2785fab91..018872f8d0a00e 100644 --- a/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean +++ b/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean @@ -10,7 +10,6 @@ public import Mathlib.Analysis.BoxIntegral.Integrability public import Mathlib.Analysis.Calculus.Deriv.Basic public import Mathlib.Analysis.Calculus.FDeriv.Equiv public import Mathlib.MeasureTheory.Integral.Prod -public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic /-! # Divergence theorem for Bochner integral diff --git a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean index 0b6c569d990aff..9ddda1d5559bff 100644 --- a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean +++ b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean @@ -5,7 +5,6 @@ Authors: Zhouhang Zhou, Yury Kudryashov, Patrick Massot, Louis (Yiyang) Liu -/ module -public import Mathlib.MeasureTheory.Constructions.Polish.StronglyMeasurable public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic import Mathlib.Topology.Algebra.IsUniformGroup.Order diff --git a/Mathlib/MeasureTheory/Integral/ExpDecay.lean b/Mathlib/MeasureTheory/Integral/ExpDecay.lean index ddb9bf1a14abed..3f64e043d49cfb 100644 --- a/Mathlib/MeasureTheory/Integral/ExpDecay.lean +++ b/Mathlib/MeasureTheory/Integral/ExpDecay.lean @@ -6,7 +6,6 @@ Authors: David Loeffler module public import Mathlib.MeasureTheory.Integral.Asymptotics -public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic public import Mathlib.MeasureTheory.Integral.IntegralEqImproper /-! diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index 20e07b068a4085..52175f6b0a4e31 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -5,9 +5,7 @@ Authors: Anatole Dedecker, Bhavik Mehta -/ module -public import Mathlib.Analysis.Calculus.Deriv.Support public import Mathlib.Analysis.SpecialFunctions.Pow.Deriv -public import Mathlib.MeasureTheory.Function.JacobianOneDim public import Mathlib.MeasureTheory.Integral.IntervalIntegral.IntegrationByParts public import Mathlib.MeasureTheory.Measure.Haar.NormedSpace public import Mathlib.MeasureTheory.Measure.Haar.Unique diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean index 463190f5939235..f3dc5eb2192ae7 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean @@ -6,7 +6,6 @@ Authors: Yizheng Zhu module public import Mathlib.Algebra.BigOperators.Group.Finset.Gaps -public import Mathlib.Analysis.Calculus.Deriv.Mul public import Mathlib.MeasureTheory.Integral.IntervalIntegral.DerivIntegrable public import Mathlib.MeasureTheory.Integral.IntervalIntegral.LebesgueDifferentiationThm diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DerivIntegrable.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DerivIntegrable.lean index c7b202caf80b38..2c076ad33ed806 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DerivIntegrable.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DerivIntegrable.lean @@ -5,7 +5,6 @@ Authors: Yizheng Zhu -/ module -public import Mathlib.Analysis.BoundedVariation public import Mathlib.MeasureTheory.Function.AbsolutelyContinuous public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Slope import Mathlib.Algebra.Order.Interval.Set.Group diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean index 734ba83cf45c3e..19e966083ae3d0 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean @@ -5,14 +5,12 @@ Authors: Yury G. Kudryashov -/ module -public import Mathlib.Analysis.Calculus.Deriv.Basic public import Mathlib.Analysis.Calculus.DiffContOnCl public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic public import Mathlib.Analysis.Calculus.LineDeriv.Basic import Mathlib.Analysis.Calculus.MeanValue import Mathlib.MeasureTheory.Integral.IntervalIntegral.FundThmCalculus -import Mathlib.Analysis.Normed.Module.Completion /-! # Displacement is at most the integral of the speed diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean index c19eb558728a70..4faffca6cfa62f 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean @@ -5,10 +5,8 @@ Authors: Yury Kudryashov, Patrick Massot, Sébastien Gouëzel -/ module -public import Mathlib.Analysis.Calculus.Deriv.Add public import Mathlib.Analysis.Calculus.Deriv.Comp public import Mathlib.Analysis.Calculus.FDeriv.Measurable -public import Mathlib.Analysis.Normed.Module.Dual public import Mathlib.MeasureTheory.Integral.Bochner.FundThmCalculus public import Mathlib.MeasureTheory.Integral.Bochner.VitaliCaratheodory public import Mathlib.MeasureTheory.Integral.DominatedConvergence diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean index 1658960da401b1..dfcd118af50d5e 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean @@ -7,9 +7,7 @@ module public import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar public import Mathlib.MeasureTheory.Measure.Haar.Quotient -public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic public import Mathlib.Topology.Algebra.Order.Floor -public import Mathlib.Topology.Instances.AddCircle.Real /-! # Integrals of periodic functions diff --git a/Mathlib/MeasureTheory/Integral/Prod.lean b/Mathlib/MeasureTheory/Integral/Prod.lean index da0f8ba97080c1..db1b5939973c22 100644 --- a/Mathlib/MeasureTheory/Integral/Prod.lean +++ b/Mathlib/MeasureTheory/Integral/Prod.lean @@ -7,8 +7,6 @@ module public import Mathlib.MeasureTheory.Function.LpSeminorm.Prod public import Mathlib.MeasureTheory.Integral.DominatedConvergence -public import Mathlib.MeasureTheory.Integral.Bochner.Set -public import Mathlib.MeasureTheory.Measure.Prod /-! # Integration with respect to the product measure diff --git a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean index f7835beb238390..1ce3bc6e7b5db6 100644 --- a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean +++ b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean @@ -8,7 +8,6 @@ module public import Mathlib.MeasureTheory.Integral.Bochner.Set public import Mathlib.MeasureTheory.Integral.CompactlySupported public import Mathlib.MeasureTheory.Integral.RieszMarkovKakutani.Basic -public import Mathlib.MeasureTheory.Measure.Regular public import Mathlib.Order.Interval.Set.Union /-! diff --git a/Mathlib/MeasureTheory/Integral/TorusIntegral.lean b/Mathlib/MeasureTheory/Integral/TorusIntegral.lean index e008fbecf59ce4..02860db94b2dec 100644 --- a/Mathlib/MeasureTheory/Integral/TorusIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/TorusIntegral.lean @@ -7,8 +7,6 @@ module public import Mathlib.MeasureTheory.Integral.CircleIntegral public import Mathlib.MeasureTheory.Integral.Prod -public import Mathlib.Order.Fin.Tuple -public import Mathlib.Util.Superscript /-! # Integral over a torus in `ℂⁿ` diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index d7965599471eca..33747c548193a4 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -6,7 +6,6 @@ Authors: Johannes Hölzl, Mario Carneiro module public import Mathlib.Data.Set.Countable -public import Mathlib.Order.ConditionallyCompleteLattice.Basic public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.FunProp.Attr public import Mathlib.Tactic.Measurability diff --git a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean index 82478cadf73698..abf7c13acae298 100644 --- a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean @@ -8,8 +8,6 @@ module public import Mathlib.Analysis.Fourier.BoundedContinuousFunctionChar public import Mathlib.Analysis.Fourier.FourierTransform public import Mathlib.Analysis.InnerProductSpace.Dual -public import Mathlib.Analysis.InnerProductSpace.ProdL2 -public import Mathlib.Analysis.Normed.Lp.MeasurableSpace public import Mathlib.MeasureTheory.Group.IntegralConvolution public import Mathlib.MeasureTheory.Integral.Pi public import Mathlib.MeasureTheory.Measure.FiniteMeasureExt diff --git a/Mathlib/MeasureTheory/Measure/Content.lean b/Mathlib/MeasureTheory/Measure/Content.lean index 54b3e752cbf3cc..284f7f517b31fb 100644 --- a/Mathlib/MeasureTheory/Measure/Content.lean +++ b/Mathlib/MeasureTheory/Measure/Content.lean @@ -5,7 +5,6 @@ Authors: Floris van Doorn -/ module -public import Mathlib.MeasureTheory.Measure.MeasureSpace public import Mathlib.MeasureTheory.Measure.Regular public import Mathlib.Topology.Sets.Compacts diff --git a/Mathlib/MeasureTheory/Measure/Count.lean b/Mathlib/MeasureTheory/Measure/Count.lean index 259adf3b2090ca..da9b3412674521 100644 --- a/Mathlib/MeasureTheory/Measure/Count.lean +++ b/Mathlib/MeasureTheory/Measure/Count.lean @@ -6,7 +6,6 @@ Authors: Johannes Hölzl module public import Mathlib.MeasureTheory.Measure.Dirac -public import Mathlib.Topology.Algebra.InfiniteSum.ENNReal /-! # Counting measure diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean index ce729bd2c8f65f..76562fe0173c36 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean @@ -8,7 +8,6 @@ module public import Mathlib.Analysis.RCLike.Lemmas public import Mathlib.MeasureTheory.Integral.Bochner.ContinuousLinearMap public import Mathlib.MeasureTheory.Measure.HasOuterApproxClosed -public import Mathlib.MeasureTheory.Measure.Prod public import Mathlib.Topology.Algebra.Module.Spaces.WeakDual public import Mathlib.Topology.TietzeExtension diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean index b579ae7da8e2cf..c80dbc9d83fc47 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean @@ -6,7 +6,6 @@ Authors: Kalle Kytölä module public import Mathlib.MeasureTheory.Measure.LevyProkhorovMetric -public import Mathlib.MeasureTheory.Measure.Prod /-! # Products of finite measures and probability measures diff --git a/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean b/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean index cf2c3f61be737f..210f423f434634 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean @@ -5,8 +5,6 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.MeasureTheory.Measure.Haar.Basic -public import Mathlib.Analysis.Normed.Module.FiniteDimension public import Mathlib.MeasureTheory.Measure.Haar.Unique /-! diff --git a/Mathlib/MeasureTheory/Measure/Haar/Extension.lean b/Mathlib/MeasureTheory/Measure/Haar/Extension.lean index 5b48903ac5d26f..263f6c3b681fd6 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Extension.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Extension.lean @@ -5,7 +5,6 @@ Authors: Thomas Browning -/ module -public import Mathlib.Analysis.InnerProductSpace.Basic public import Mathlib.MeasureTheory.Group.Integral public import Mathlib.MeasureTheory.Integral.RieszMarkovKakutani.Real public import Mathlib.Topology.Algebra.Group.Extension diff --git a/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean b/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean index 156f47097e9380..d50348a103a29f 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/NormedSpace.lean @@ -6,7 +6,6 @@ Authors: Floris van Doorn, Sébastien Gouëzel module public import Mathlib.MeasureTheory.Measure.Haar.InnerProductSpace -public import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar public import Mathlib.MeasureTheory.Integral.Bochner.Set /-! diff --git a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean index 3d3fd8c253abcf..568e8541bf3d58 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean @@ -5,11 +5,8 @@ Authors: Alex Kontorovich, Heather Macbeth -/ module -public import Mathlib.Algebra.Group.Opposite -public import Mathlib.MeasureTheory.Constructions.Polish.Basic public import Mathlib.MeasureTheory.Group.FundamentalDomain public import Mathlib.MeasureTheory.Integral.DominatedConvergence -public import Mathlib.MeasureTheory.Measure.Haar.Basic /-! # Haar quotient measure diff --git a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean index 218a060a1bf085..dd3a0f69aaeb57 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean @@ -5,12 +5,9 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.MeasureTheory.Function.LocallyIntegrable public import Mathlib.MeasureTheory.Group.Integral public import Mathlib.MeasureTheory.Integral.Prod -public import Mathlib.MeasureTheory.Integral.Bochner.Set public import Mathlib.MeasureTheory.Measure.EverywherePos -public import Mathlib.MeasureTheory.Measure.Haar.Basic public import Mathlib.Topology.Metrizable.Urysohn public import Mathlib.Topology.ContinuousMap.Ordered diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean index 0f8e45df09884c..82b1e677a1f03b 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean @@ -6,6 +6,7 @@ Authors: Kalle Kytölä module public import Mathlib.MeasureTheory.Integral.BoundedContinuousFunction +public import Mathlib.MeasureTheory.Integral.IntegrableOn public import Mathlib.Topology.MetricSpace.ThickenedIndicator /-! diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 81c855665198b3..cd679e0ec0a1e1 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -6,7 +6,6 @@ Authors: Yury Kudryashov module public import Mathlib.Analysis.Convex.Between -public import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic public import Mathlib.MeasureTheory.Measure.Lebesgue.Basic public import Mathlib.Topology.MetricSpace.Holder public import Mathlib.Topology.MetricSpace.MetricSeparated diff --git a/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean b/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean index 3bd1c948d35cb9..cae25b2ff94c6a 100644 --- a/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean +++ b/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean @@ -5,7 +5,6 @@ Authors: Rémy Degenne -/ module -public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic public import Mathlib.MeasureTheory.Function.SpecialFunctions.Sinc public import Mathlib.MeasureTheory.Measure.CharacteristicFunction.Basic diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean index a94cef29b9a1a3..817ddd25d63ce9 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean @@ -5,10 +5,7 @@ Authors: Johannes Hölzl, Sébastien Gouëzel, Yury Kudryashov -/ module -public import Mathlib.Dynamics.Ergodic.MeasurePreserving -public import Mathlib.LinearAlgebra.Determinant public import Mathlib.LinearAlgebra.Matrix.Diagonal -public import Mathlib.LinearAlgebra.Matrix.Transvection public import Mathlib.MeasureTheory.Group.LIntegral public import Mathlib.MeasureTheory.Integral.Marginal public import Mathlib.MeasureTheory.Measure.Stieltjes diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean index 3de4107fcc30b7..70624b7e155506 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean @@ -5,11 +5,6 @@ Authors: Floris van Doorn, Sébastien Gouëzel -/ module -public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas -public import Mathlib.MeasureTheory.Constructions.BorelSpace.Metric -public import Mathlib.MeasureTheory.Group.Pointwise -public import Mathlib.MeasureTheory.Measure.Doubling -public import Mathlib.MeasureTheory.Measure.Haar.Basic public import Mathlib.MeasureTheory.Measure.Lebesgue.Basic /-! diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean index 40cd194ef17765..02ea8b19c7aa47 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean @@ -5,8 +5,6 @@ Authors: Johannes Hölzl, Sébastien Gouëzel, Yury Kudryashov -/ module -public import Mathlib.MeasureTheory.Integral.Bochner.Set -public import Mathlib.MeasureTheory.Measure.Lebesgue.Basic public import Mathlib.MeasureTheory.Measure.Haar.Unique /-! # Properties of integration with respect to the Lebesgue measure -/ diff --git a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean index 2cb94134114021..c33e6c53d47498 100644 --- a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean +++ b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean @@ -8,7 +8,6 @@ module public import Mathlib.MeasureTheory.Measure.Portmanteau public import Mathlib.MeasureTheory.Integral.DominatedConvergence public import Mathlib.MeasureTheory.Integral.Layercake -public import Mathlib.MeasureTheory.Integral.BoundedContinuousFunction /-! # The Lévy-Prokhorov distance on spaces of finite measures and probability measures diff --git a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean index 3f645566c47cc3..32f7c49a57ec86 100644 --- a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean @@ -6,7 +6,6 @@ Authors: Johannes Hölzl, Mario Carneiro, Yury Kudryashov module public import Mathlib.MeasureTheory.MeasurableSpace.EventuallyMeasurable -public import Mathlib.MeasureTheory.MeasurableSpace.Basic public import Mathlib.MeasureTheory.Measure.AEDisjoint /-! diff --git a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean index 9b226f23179f49..6546d9f12b53b9 100644 --- a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean @@ -7,7 +7,6 @@ module public import Mathlib.MeasureTheory.Measure.FiniteMeasure public import Mathlib.MeasureTheory.Integral.Average -public import Mathlib.MeasureTheory.Measure.Prod /-! # Probability measures diff --git a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean index 876922d32cf586..31eda309cefffb 100644 --- a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean +++ b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean @@ -5,11 +5,8 @@ Authors: Rémy Degenne, Peter Pfaffelhuber -/ module -public import Mathlib.Analysis.SpecificLimits.Basic public import Mathlib.MeasureTheory.Measure.Regular -public import Mathlib.Topology.GDelta.MetrizableSpace public import Mathlib.Topology.MetricSpace.Polish -public import Mathlib.Topology.UniformSpace.Cauchy /-! # Inner regularity of finite measures diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index 7d145ac05dc563..8c50c7c32662ea 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -6,8 +6,6 @@ Authors: Johannes Hölzl, Mario Carneiro module public import Mathlib.MeasureTheory.Measure.Comap -public import Mathlib.MeasureTheory.Measure.QuasiMeasurePreserving -public import Mathlib.Data.Set.Card /-! # Restricting a measure to a subset or a subtype diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index eaa70d12d2e15b..72ca1eecf4560c 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -7,7 +7,6 @@ module public import Mathlib.MeasureTheory.Constructions.BorelSpace.Order public import Mathlib.MeasureTheory.Measure.Typeclasses.Probability -public import Mathlib.Topology.Algebra.UniformMulAction public import Mathlib.Topology.Order.LeftRightLim /-! diff --git a/Mathlib/MeasureTheory/Measure/SubFinite.lean b/Mathlib/MeasureTheory/Measure/SubFinite.lean index e520f646bfceb3..6e0c40c30c160e 100644 --- a/Mathlib/MeasureTheory/Measure/SubFinite.lean +++ b/Mathlib/MeasureTheory/Measure/SubFinite.lean @@ -8,7 +8,6 @@ module public import Mathlib.MeasureTheory.Measure.Sub import Mathlib.MeasureTheory.Integral.Lebesgue.Sub -public import Mathlib.Analysis.Normed.Group.Basic public import Mathlib.MeasureTheory.Measure.Decomposition.Hahn public import Mathlib.MeasureTheory.Measure.WithDensity diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index f875151d22a688..1ea3e12cc85665 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -5,7 +5,6 @@ Authors: Mario Carneiro, Johannes Hölzl -/ module -public import Mathlib.MeasureTheory.Integral.Lebesgue.Countable public import Mathlib.MeasureTheory.Measure.Decomposition.Exhaustion public import Mathlib.MeasureTheory.Group.Convolution public import Mathlib.Analysis.LConvolution diff --git a/Mathlib/MeasureTheory/Order/Group/Lattice.lean b/Mathlib/MeasureTheory/Order/Group/Lattice.lean index 91276c853ca089..0f9321d2d36a79 100644 --- a/Mathlib/MeasureTheory/Order/Group/Lattice.lean +++ b/Mathlib/MeasureTheory/Order/Group/Lattice.lean @@ -5,7 +5,6 @@ Authors: Xavier Roblot -/ module -public import Mathlib.Algebra.Order.Group.PosPart public import Mathlib.MeasureTheory.Group.Arithmetic public import Mathlib.MeasureTheory.Order.Lattice diff --git a/Mathlib/MeasureTheory/Order/UpperLower.lean b/Mathlib/MeasureTheory/Order/UpperLower.lean index a53a76ce446326..a0fb96c8e8f241 100644 --- a/Mathlib/MeasureTheory/Order/UpperLower.lean +++ b/Mathlib/MeasureTheory/Order/UpperLower.lean @@ -7,7 +7,6 @@ module public import Mathlib.Analysis.Normed.Order.UpperLower public import Mathlib.MeasureTheory.Covering.BesicovitchVectorSpace -public import Mathlib.Topology.Order.DenselyOrdered /-! # Order-connected sets are null-measurable diff --git a/Mathlib/MeasureTheory/OuterMeasure/Basic.lean b/Mathlib/MeasureTheory/OuterMeasure/Basic.lean index bbc0b368cd857e..b9bf43ad126a20 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Basic.lean @@ -5,9 +5,6 @@ Authors: Johannes Hölzl, Mario Carneiro -/ module -public import Mathlib.Data.Countable.Basic -public import Mathlib.Data.Fin.VecNotation -public import Mathlib.Order.Disjointed public import Mathlib.MeasureTheory.OuterMeasure.Defs public import Mathlib.Topology.Algebra.InfiniteSum.ENNReal diff --git a/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean b/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean index c93d32bd045461..239c7d93657e88 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean @@ -5,7 +5,6 @@ Authors: Rémy Degenne, Peter Pfaffelhuber -/ module -public import Mathlib.MeasureTheory.SetSemiring public import Mathlib.MeasureTheory.Measure.AddContent public import Mathlib.MeasureTheory.Measure.Trim diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 55d406b20306b8..6c8c36d2502f7f 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -5,11 +5,8 @@ Authors: Rémy Degenne, Peter Pfaffelhuber -/ module -public import Mathlib.Data.Set.Pairwise.Lattice public import Mathlib.MeasureTheory.PiSystem -public import Mathlib.Order.Lattice.Nat public import Mathlib.Order.Partition.Finpartition -public import Mathlib.Order.SetAccumulate public import Mathlib.Order.SupClosed /-! # Semirings and rings of sets diff --git a/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean b/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean index 7b5d033e1a0802..3f7e457ac04f41 100644 --- a/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean +++ b/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean @@ -6,7 +6,6 @@ Authors: Anatole Dedecker module public import Mathlib.Topology.ContinuousMap.Compact -public import Mathlib.Topology.ContinuousMap.Algebra public import Mathlib.MeasureTheory.Integral.IntegrableOn /-! diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index 3f8ee9b91f4a05..ace2e7cfc59cc5 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -6,7 +6,6 @@ Authors: Kexing Ying module public import Mathlib.MeasureTheory.Measure.Real -public import Mathlib.MeasureTheory.Measure.Typeclasses.Finite public import Mathlib.Topology.Algebra.InfiniteSum.Module /-! diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean index 79ff56ab497813..c654aaef8b65ad 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean @@ -6,7 +6,6 @@ Authors: Kexing Ying module public import Mathlib.MeasureTheory.VectorMeasure.Basic -public import Mathlib.Order.SymmDiff /-! # Hahn decomposition diff --git a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean index 82fd1a22fb2ad9..47c85aa59371b4 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean @@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel -/ module +public import Mathlib.MeasureTheory.Integral.IntegrableOn public import Mathlib.MeasureTheory.VectorMeasure.Integral /-! diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean index baa4b3ca053d65..93253fa2861639 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean @@ -8,7 +8,6 @@ module public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic import Mathlib.Analysis.Normed.Module.HahnBanach -import Mathlib.Analysis.Normed.Operator.NormedSpace /-! # The semivariation of a vector measure From a8661465d2624a0ccb7a86a72ad25175a840f12d Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 12:19:05 +0000 Subject: [PATCH 0453/1300] refactor(NumberTheory/RamificationInertia/Unramified): switch to new definition of ramification index (#41191) This PR switches `NumberTheory/RamificationInertia/Unramified.lean` over to the new definition of ramification index. Co-authored-by: tb65536 --- .../NumberField/Cyclotomic/Basic.lean | 1 + .../RamificationInertia/Unramified.lean | 59 +++++++------------ .../RingTheory/DedekindDomain/Different.lean | 4 +- .../Ideal/Quotient/HasFiniteQuotients.lean | 4 +- .../RamificationInertia/Ramification.lean | 1 + 5 files changed, 28 insertions(+), 41 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index 0c4e4d90f647ed..143a86b664bc52 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -5,6 +5,7 @@ Authors: Riccardo Brasca -/ module +public import Mathlib.LinearAlgebra.FreeModule.IdealQuotient public import Mathlib.NumberTheory.Cyclotomic.Discriminant public import Mathlib.NumberTheory.NumberField.Cyclotomic.Embeddings public import Mathlib.NumberTheory.NumberField.Discriminant.Different diff --git a/Mathlib/NumberTheory/RamificationInertia/Unramified.lean b/Mathlib/NumberTheory/RamificationInertia/Unramified.lean index 42ec187589d036..fbfcbe164c0aed 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Unramified.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Unramified.lean @@ -5,10 +5,8 @@ Authors: Andrew Yang -/ module -public import Mathlib.NumberTheory.RamificationInertia.Basic -public import Mathlib.RingTheory.LocalRing.ResidueField.Instances -public import Mathlib.RingTheory.Unramified.LocalRing -public import Mathlib.LinearAlgebra.FreeModule.IdealQuotient +public import Mathlib.RingTheory.Ideal.Quotient.HasFiniteQuotients +public import Mathlib.RingTheory.RamificationInertia.Basic /-! @@ -29,18 +27,14 @@ variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] variable [Algebra R S] [Algebra S T] [Algebra R T] [IsScalarTower R S T] local notation3 "e(" P "|" R ")" => - Ideal.ramificationIdx (Ideal.under R P) P + Ideal.ramificationIdx' P R open IsLocalRing Algebra lemma Ideal.ramificationIdx_eq_one_of_isUnramifiedAt - {p : Ideal S} [p.IsPrime] [IsNoetherianRing S] [IsUnramifiedAt R p] - (hp : p ≠ ⊥) [IsDomain S] [EssFiniteType R S] : + {p : Ideal S} [p.IsPrime] [IsUnramifiedAt R p] [EssFiniteType R S] : e(p|R) = 1 := - let := Localization.AtPrime.algebraOfLiesOver (p.under R) p - (Ideal.ramificationIdx_eq_one_of_map_localization Ideal.map_comap_le hp - p.primeCompl_le_nonZeroDivisors - ((isUnramifiedAt_iff_map_eq R (p.under R) p).mp ‹_›).2) + p.ramificationIdx'_eq_one R variable (R) in lemma IsUnramifiedAt.of_liesOver_of_ne_bot @@ -92,21 +86,15 @@ lemma IsUnramifiedAt.of_liesOver IsUnramifiedAt.of_liesOver_of_ne_bot R p P P.primeCompl_le_nonZeroDivisors (Ideal.ne_bot_of_liesOver_of_ne_bot · P) + /-- Let `R` be a domain of characteristic 0, finite rank over `ℤ`, `S` be a Dedekind domain that is a finite `R`-algebra. Let `p` be a prime of `S`, then `p` is unramified iff `e(p) = 1`. -/ +@[deprecated "Use `Ideal.ramificationIdx'_eq_one_iff` instead." (since := "2026-06-30")] lemma isUnramifiedAt_iff_of_isDedekindDomain - {p : Ideal S} [p.IsPrime] [IsDedekindDomain S] [EssFiniteType R S] [IsDomain R] - [Module.Finite ℤ R] [CharZero R] [Algebra.IsIntegral R S] - (hp : p ≠ ⊥) : - Algebra.IsUnramifiedAt R p ↔ e(p|R) = 1 := by - let := Localization.AtPrime.algebraOfLiesOver (p.under R) p - rw [isUnramifiedAt_iff_map_eq R (p.under R) p, and_iff_right, - Ideal.IsDedekindDomain.ramificationIdx_eq_one_iff hp Ideal.map_comap_le] - have : Finite (R ⧸ p.under R) := - Ideal.finiteQuotientOfFreeOfNeBot _ (mt Ideal.eq_bot_of_comap_eq_bot hp) - have : Finite ((p.under R).ResidueField) := IsLocalization.finite _ - (nonZeroDivisors (R ⧸ p.under R)) - infer_instance + {p : Ideal S} [p.IsPrime] [EssFiniteType R S] [IsDomain R] + [Module.Finite ℤ R] [CharZero R] [Algebra.IsIntegral R S] : + Algebra.IsUnramifiedAt R p ↔ e(p|R) = 1 := + Ideal.ramificationIdx'_eq_one_iff.symm /-- In characteristic zero the generic point is unramified: if `S` is a domain that is integral over a characteristic-zero domain `R` and `R → S` is injective, then `S` is unramified at the zero @@ -159,25 +147,22 @@ theorem isUnramifiedIn_iff_forall_of_isDedekindDomain [IsDomain R] [IsDedekindDo /-- For a prime `𝔓` of `S` lying over an unramified prime `𝔭` of `R`, the ramification index `e(𝔓 ∣ 𝔭)` equals `1`. -/ -theorem IsUnramifiedIn.ramificationIdx_eq_one [IsDomain R] [IsDedekindDomain S] - [Module.IsTorsionFree R S] [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] - [Algebra.IsIntegral R S] {𝔭 : Ideal R} (hunr : IsUnramifiedIn S 𝔭) (h𝔭 : 𝔭 ≠ ⊥) {𝔓 : Ideal S} - [𝔓.IsPrime] (hP : 𝔓.LiesOver 𝔭) : Ideal.ramificationIdx 𝔭 𝔓 = 1 := by - rw [(Ideal.liesOver_iff 𝔓 𝔭).mp hP] - exact (isUnramifiedAt_iff_of_isDedekindDomain (Ideal.ne_bot_of_liesOver_of_ne_bot h𝔭 𝔓)).mp +theorem IsUnramifiedIn.ramificationIdx_eq_one [IsDomain R] + [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] + [Algebra.IsIntegral R S] {𝔭 : Ideal R} (hunr : IsUnramifiedIn S 𝔭) {𝔓 : Ideal S} + [𝔓.IsPrime] (hP : 𝔓.LiesOver 𝔭) : Ideal.ramificationIdx' 𝔓 R = 1 := + Ideal.ramificationIdx'_eq_one_iff.mpr (hunr 𝔓 inferInstance hP) /-- A nonzero ideal of `R` is unramified in `S` if and only if every prime ideal of `S` lying over it has ramification index `1`. -/ -theorem isUnramifiedIn_iff_forall_ramificationIdx_eq_one [IsDomain R] [IsDedekindDomain S] - [Module.IsTorsionFree R S] [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] - [Algebra.IsIntegral R S] {𝔭 : Ideal R} (h𝔭 : 𝔭 ≠ ⊥) : +theorem isUnramifiedIn_iff_forall_ramificationIdx_eq_one [IsDomain R] + [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] + [Algebra.IsIntegral R S] {𝔭 : Ideal R} : IsUnramifiedIn S 𝔭 ↔ - ∀ (𝔓 : Ideal S) [𝔓.IsPrime], 𝔓.LiesOver 𝔭 → Ideal.ramificationIdx 𝔭 𝔓 = 1 := by - refine ⟨fun hunr 𝔓 _ hP ↦ hunr.ramificationIdx_eq_one h𝔭 hP, fun h 𝔓 _ hP ↦ ?_⟩ - apply (isUnramifiedAt_iff_of_isDedekindDomain - (Ideal.ne_bot_of_liesOver_of_ne_bot h𝔭 𝔓)).mpr - rw [← (Ideal.liesOver_iff 𝔓 𝔭).mp hP] + ∀ (𝔓 : Ideal S) [𝔓.IsPrime], 𝔓.LiesOver 𝔭 → Ideal.ramificationIdx' 𝔓 R = 1 := by + refine ⟨fun hunr 𝔓 _ hP ↦ hunr.ramificationIdx_eq_one hP, fun h 𝔓 _ hP ↦ ?_⟩ + rw [← Ideal.ramificationIdx'_eq_one_iff] exact h 𝔓 hP end Algebra diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index e0189143a01d15..a79a15b79c5be4 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -947,8 +947,8 @@ theorem not_dvd_differentIdeal_iff simpa [Ideal.dvd_iff_le] using H · intro H obtain ⟨Q, h₁, h₂⟩ := Ideal.eq_prime_pow_mul_coprime hp' P - rw [← Ideal.IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hp' ‹_› hPbot, - Ideal.ramificationIdx_eq_one_of_isUnramifiedAt hPbot, pow_one] at h₂ + rw [← Ideal.IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count _ _ hp', + Ideal.ramificationIdx_eq_one_of_isUnramifiedAt, pow_one] at h₂ obtain ⟨h₃, h₄⟩ := (Algebra.isUnramifiedAt_iff_map_eq (p := P.under A) _ _).mp H exact not_dvd_differentIdeal_of_isCoprime_of_isSeparable A P Q (Ideal.isCoprime_iff_sup_eq.mpr h₁) h₂.symm diff --git a/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean b/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean index d08ae5b3b4f52a..656fc378d3e3d2 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean @@ -166,7 +166,7 @@ instance : HasFiniteQuotients ℤ where exact inferInstanceAs <| Finite (ℤ ⧸ Ideal.span {n}) /-- A domain that is finitely generated has finite quotients. -/ -instance [IsDomain R] [AddGroup.FG R] : HasFiniteQuotients R := - of_module_finite ℤ R +instance [IsDomain R] [Module.Finite ℤ R] : HasFiniteQuotients R := + .of_module_finite ℤ R end Ring.HasFiniteQuotients diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index efa78e6c1f7753..4cfbeea36fe3c7 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -92,6 +92,7 @@ theorem ramificationIdx'_eq_one [q.IsPrime] [Algebra.EssFiniteType R S] IsScalarTower.algebraMap_eq R Rp Sq, ← map_map, Localization.AtPrime.map_eq_maximalIdeal] exact Algebra.FormallyUnramified.map_maximalIdeal +variable {q R} in theorem ramificationIdx'_eq_one_iff [q.IsPrime] [Algebra.EssFiniteType R S] [Algebra.IsIntegral R S] [PerfectField (q.under R).ResidueField] : q.ramificationIdx' R = 1 ↔ Algebra.IsUnramifiedAt R q := by From b122ba8eba3d1104382d08a830bde86654c9ea08 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 30 Jun 2026 12:29:47 +0000 Subject: [PATCH 0454/1300] =?UTF-8?q?chore:=20namespace=20`contMDiffAt=5Fe?= =?UTF-8?q?xtend`=20and=20friends=20under=20`OpenPartialH=E2=80=A6=20(#411?= =?UTF-8?q?74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …omeomorph` The lemmas `contMDiffAt_extend` and `FiberBundle.contMDiffAt_extend'` have very similar-looking names, but are about very different objects: the former is about `OpenPartialHomeomorph.extend`, the latter about `FiberBundle.extend`. Namespace the former, so we can deprime the latter (and avoid ambiguity when the `FiberBundle` namespace is open). Making them protected instead would be too onerous in practice. To avoid said ambiguity, we don't add a deprecated alias. --- Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean index 78a63c9fcaf56b..811c6456c64ac7 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean @@ -88,17 +88,18 @@ theorem contMDiffOn_chart_symm [IsManifold I n M] : ContMDiffOn I I n (chartAt H x).symm (chartAt H x).target := contMDiffOn_symm_of_mem_maximalAtlas <| chart_mem_maximalAtlas x -theorem contMDiffAt_extend {x : M} (he : e ∈ maximalAtlas I n M) (hx : x ∈ e.source) : +theorem OpenPartialHomeomorph.contMDiffAt_extend {x : M} + (he : e ∈ maximalAtlas I n M) (hx : x ∈ e.source) : ContMDiffAt I 𝓘(𝕜, E) n (e.extend I) x := (I.contMDiff _).comp x <| contMDiffAt_of_mem_maximalAtlas he hx -theorem contMDiffOn_extend (he : e ∈ maximalAtlas I n M) : +theorem OpenPartialHomeomorph.contMDiffOn_extend (he : e ∈ maximalAtlas I n M) : ContMDiffOn I 𝓘(𝕜, E) n (e.extend I) e.source := - fun _x' hx' ↦ (contMDiffAt_extend he hx').contMDiffWithinAt + fun _x' hx' ↦ (e.contMDiffAt_extend he hx').contMDiffWithinAt theorem contMDiffAt_extChartAt' [IsManifold I n M] {x' : M} (h : x' ∈ (chartAt H x).source) : ContMDiffAt I 𝓘(𝕜, E) n (extChartAt I x) x' := - contMDiffAt_extend (chart_mem_maximalAtlas x) h + (chartAt H x).contMDiffAt_extend (chart_mem_maximalAtlas x) h theorem contMDiffAt_extChartAt : ContMDiffAt I 𝓘(𝕜, E) n (extChartAt I x) x := by rw [contMDiffAt_iff_source] @@ -108,7 +109,7 @@ theorem contMDiffAt_extChartAt : ContMDiffAt I 𝓘(𝕜, E) n (extChartAt I x) theorem contMDiffOn_extChartAt [IsManifold I n M] : ContMDiffOn I 𝓘(𝕜, E) n (extChartAt I x) (chartAt H x).source := - contMDiffOn_extend (chart_mem_maximalAtlas x) + (chartAt H x).contMDiffOn_extend (chart_mem_maximalAtlas x) theorem contMDiffOn_extend_symm (he : e ∈ maximalAtlas I n M) : ContMDiffOn 𝓘(𝕜, E) I n (e.extend I).symm (I '' e.target) := by From 0baa6353c99f7614437a669b585ef251b622c87f Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:00:28 +0000 Subject: [PATCH 0455/1300] chore: deprime FiberBundle.contMDiffAt_extend' (#41175) The original name was primed to avoid ambiguity with `contMDiffAt_extend`: a previous PR moved this under the `OpenPartialHomeomorph` namespace, so this ambiguity is no longer present. --- .../Geometry/Manifold/VectorBundle/MDifferentiable.lean | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 2d426f73f5030c..389c63c3be81ce 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -687,8 +687,7 @@ lemma exists_contMDiffOn_extend [(x : M) → Module 𝕜 (V x)] [VectorBundle have : CMDiff[t.baseSet] k (fun (_x : M) ↦ w) := contMDiffOn_const exact this.congr (fun x hx ↦ by simp [extend, t, w, hx]) -lemma contMDiffAt_extend' {x : M} (σ₀ : V x) : - CMDiffAt k (T% (extend F σ₀)) x := by +lemma contMDiffAt_extend {x : M} (σ₀ : V x) : CMDiffAt k (T% (extend F σ₀)) x := by rw [contMDiffAt_section] set t := trivializationAt F V x let w : F := (t ⟨x, σ₀⟩).2 @@ -700,6 +699,8 @@ lemma contMDiffAt_extend' {x : M} (σ₀ : V x) : simp [extend, t, hx, w] · exact FiberBundle.mem_baseSet_trivializationAt' x +@[deprecated (since := "2026-06-30")] alias contMDiffAt_extend' := contMDiffAt_extend + lemma exists_mdifferentiableOn_extend [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] {x₀ : M} (σ₀ : V x₀) : ∃ s ∈ 𝓝 x₀, MDiff[s] (T% (extend F σ₀)) := by @@ -708,7 +709,7 @@ lemma exists_mdifferentiableOn_extend [∀ x, Module 𝕜 (V x)] [VectorBundle lemma mdifferentiableAt_extend {x : M} (σ₀ : V x) : MDiffAt (T% (extend F σ₀)) x := - (contMDiffAt_extend' (k := 1) I F σ₀).mdifferentiableAt one_ne_zero + (contMDiffAt_extend (k := 1) I F σ₀).mdifferentiableAt one_ne_zero variable (V) in lemma _root_.VectorBundle.injective_eval_mdifferentiableAt_sec [∀ x, Module 𝕜 (V x)] @@ -728,7 +729,7 @@ lemma _root_.VectorBundle.injective_eval_contMDiffAt_sec {n : WithTop ℕ∞} [ fun (Z : Π x, V x) (_ : CMDiffAt n (T% Z) x) ↦ A (Z x)) := by intro X X' h ext σ₀ - simpa using congr($h (extend F σ₀) (contMDiffAt_extend' ..)) + simpa using congr($h (extend F σ₀) (contMDiffAt_extend ..)) end FiberBundle end extend From d0ae44ee0634fd3f037352a648c32b804a4de9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:58:50 +0000 Subject: [PATCH 0456/1300] feat(CategoryTheory): properties of objects in comma categories (#41182) --- Mathlib.lean | 1 + .../CategoryTheory/ObjectProperty/Comma.lean | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 Mathlib/CategoryTheory/ObjectProperty/Comma.lean diff --git a/Mathlib.lean b/Mathlib.lean index feceaf0c28726e..137a5754107586 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3199,6 +3199,7 @@ public import Mathlib.CategoryTheory.ObjectProperty.ClosureShift public import Mathlib.CategoryTheory.ObjectProperty.ColimitsCardinalClosure public import Mathlib.CategoryTheory.ObjectProperty.ColimitsClosure public import Mathlib.CategoryTheory.ObjectProperty.ColimitsOfShape +public import Mathlib.CategoryTheory.ObjectProperty.Comma public import Mathlib.CategoryTheory.ObjectProperty.CompleteLattice public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero public import Mathlib.CategoryTheory.ObjectProperty.EpiMono diff --git a/Mathlib/CategoryTheory/ObjectProperty/Comma.lean b/Mathlib/CategoryTheory/ObjectProperty/Comma.lean new file mode 100644 index 00000000000000..d44f62cc8caa94 --- /dev/null +++ b/Mathlib/CategoryTheory/ObjectProperty/Comma.lean @@ -0,0 +1,69 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.ObjectProperty.Retract + +/-! +# Properties of objects in comma categories + +-/ + +universe w + +@[expose] public section + +namespace CategoryTheory.ObjectProperty + +variable {C₁ C₂ D : Type*} [Category* C₁] [Category* C₂] [Category* D] + (F₁ : C₁ ⥤ D) (F₂ : C₂ ⥤ D) + (P₁ : ObjectProperty C₁) (P₂ : ObjectProperty C₂) + +/-- Given functors `F₁ : C₁ ⥤ D` and `F₂ : C₂ ⥤ D`, and properties +of objects `P₁ : ObjectProperty C₁` and `P₂ : ObjectProperty C₂`, +this is the property of objects in `Comma F₁ F₂` satisfying +by the objects corresponding to morphisms `F₁.obj X₁ ⟶ F₂.obj X₂` +where `P₁ X₁` and `P₂ X₂` hold. -/ +def comma : ObjectProperty (Comma F₁ F₂) := + P₁.inverseImage (Comma.fst _ _) ⊓ P₂.inverseImage (Comma.snd _ _) + +variable {F₁ F₂} in +@[simp] +lemma comma_iff (X : Comma F₁ F₂) : + comma F₁ F₂ P₁ P₂ X ↔ P₁ X.left ∧ P₂ X.right := Iff.rfl + +instance [P₁.IsStableUnderRetracts] [P₂.IsStableUnderRetracts] : + (comma F₁ F₂ P₁ P₂).IsStableUnderRetracts where + of_retract r h := + ⟨P₁.prop_of_retract (r.map (Comma.fst _ _)) h.1, + P₂.prop_of_retract (r.map (Comma.snd _ _)) h.2⟩ + +instance [P₁.IsClosedUnderIsomorphisms] [P₂.IsClosedUnderIsomorphisms] : + (comma F₁ F₂ P₁ P₂).IsClosedUnderIsomorphisms where + of_iso e h := + ⟨P₁.prop_of_iso ((Comma.fst _ _).mapIso e) h.1, + P₂.prop_of_iso ((Comma.snd _ _).mapIso e) h.2⟩ + +instance [ObjectProperty.Small.{w} P₁] [ObjectProperty.Small.{w} P₂] [LocallySmall.{w} D] : + ObjectProperty.Small.{w} (comma F₁ F₂ P₁ P₂) := + small_of_surjective + (α := Σ (X₁ : Subtype P₁) (X₂ : Subtype P₂), F₁.obj X₁.val ⟶ F₂.obj X₂.val) + (f := fun ⟨X₁, X₂, f⟩ ↦ ⟨Comma.mk _ _ f, X₁.prop, X₂.prop⟩) + (fun f ↦ ⟨⟨⟨_, f.prop.1⟩, ⟨_, f.prop.2⟩, f.val.hom⟩, rfl⟩) + +instance [ObjectProperty.EssentiallySmall.{w} P₁] + [ObjectProperty.EssentiallySmall.{w} P₂] [LocallySmall.{w} D] : + ObjectProperty.EssentiallySmall.{w} (comma F₁ F₂ P₁ P₂) := by + obtain ⟨Q₁, _, h₁, h₁'⟩ := EssentiallySmall.exists_small_le.{w} P₁ + obtain ⟨Q₂, _, h₂, h₂'⟩ := EssentiallySmall.exists_small_le.{w} P₂ + refine ⟨comma F₁ F₂ Q₁ Q₂, inferInstance, fun f hf ↦ ?_⟩ + simp only [comma_iff] at hf + obtain ⟨X₁, hX₁, ⟨e₁⟩⟩ := h₁' _ hf.1 + obtain ⟨X₂, hX₂, ⟨e₂⟩⟩ := h₂' _ hf.2 + exact ⟨Comma.mk _ _ (F₁.map e₁.inv ≫ f.hom ≫ F₂.map e₂.hom), by tauto, + ⟨Comma.isoMk e₁ e₂⟩⟩ + +end CategoryTheory.ObjectProperty From 240b4d264f40cdb2c768f8e6390622c88b033214 Mon Sep 17 00:00:00 2001 From: Christian Merten <136261474+chrisflav@users.noreply.github.com> Date: Tue, 30 Jun 2026 14:08:10 +0000 Subject: [PATCH 0457/1300] feat(Algebra/Category/ModuleCat): submodules of presheaves of modules (#41159) We define submodules of presheaves of modules as restriction-stable families of `Submodule`s and construct the associated presheaf of modules. --- Mathlib.lean | 1 + .../Algebra/Category/ModuleCat/Presheaf.lean | 13 ++ .../ModuleCat/Presheaf/Submodule.lean | 140 ++++++++++++++++++ Mathlib/Algebra/Module/Submodule/Map.lean | 9 +- 4 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 Mathlib/Algebra/Category/ModuleCat/Presheaf/Submodule.lean diff --git a/Mathlib.lean b/Mathlib.lean index 137a5754107586..e1572c3a4a6b20 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -194,6 +194,7 @@ public import Mathlib.Algebra.Category.ModuleCat.Presheaf.Pushforward public import Mathlib.Algebra.Category.ModuleCat.Presheaf.PushforwardZeroMonoidal public import Mathlib.Algebra.Category.ModuleCat.Presheaf.Sheafification public import Mathlib.Algebra.Category.ModuleCat.Presheaf.Sheafify +public import Mathlib.Algebra.Category.ModuleCat.Presheaf.Submodule public import Mathlib.Algebra.Category.ModuleCat.Products public import Mathlib.Algebra.Category.ModuleCat.Projective public import Mathlib.Algebra.Category.ModuleCat.ProjectiveDimension diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean index 1428f49d38f65b..f0044570af4178 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean @@ -77,6 +77,19 @@ lemma map_comp_apply {U V W : Cᵒᵖ} (i : U ⟶ V) (j : V ⟶ W) (x) : M.map (i ≫ j) x = M.map j (M.map i x) := by rw [M.map_comp]; rfl +set_option backward.isDefEq.respectTransparency false in +/-- The restriction map `M.map f` of a presheaf of modules `M`, bundled as a semilinear map +along the ring map `R.map f`. -/ +noncomputable def restrictₛₗ {X Y : Cᵒᵖ} (f : X ⟶ Y) : + M.obj X →ₛₗ[(R.map f).hom] M.obj Y where + toFun m := M.map f m + map_add' := map_add (M.map f).hom + map_smul' r m := M.map_smul f r m + +@[simp] +lemma restrictₛₗ_apply {X Y : Cᵒᵖ} (f : X ⟶ Y) (m : M.obj X) : + M.restrictₛₗ f m = M.map f m := rfl + /-- A morphism of presheaves of modules consists of a family of linear maps which satisfy the naturality condition. -/ @[ext] diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Submodule.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Submodule.lean new file mode 100644 index 00000000000000..8becc6ba619651 --- /dev/null +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Submodule.lean @@ -0,0 +1,140 @@ +/- +Copyright (c) 2026 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +module + +public import Mathlib.Algebra.Category.ModuleCat.Presheaf.EpiMono + +/-! +# Submodules of presheaves of modules + +Given a presheaf of modules `M` over a presheaf of rings `R` and a family of +submodules `N X` of `M.obj X` that is stable under the restriction maps of `M`, +we construct the corresponding subobject of `M` in the category +`PresheafOfModules R`. + +## Main definitions + +- `PresheafOfModules.Submodule M`: a family of submodules of `M`, stable + under restriction. +- `PresheafOfModules.Submodule.toPresheafOfModules`: the associated + presheaf of modules. + +The families of submodules of `M` form a `CompleteLattice`, with all the lattice +operations computed pointwise. +-/ + +@[expose] public section + +universe v v₁ u₁ u + +open CategoryTheory + +namespace PresheafOfModules + +variable {C : Type u₁} [Category.{v₁} C] {R : Cᵒᵖ ⥤ RingCat.{u}} + +/-- A family of submodules `N X` of `M.obj X`, for a presheaf of modules `M`, stable +under the restriction maps of `M`. This defines a subobject of `M` in `PresheafOfModules R`. -/ +structure Submodule (M : PresheafOfModules.{v} R) where + /-- the submodule of `M.obj X` -/ + obj (X : Cᵒᵖ) : _root_.Submodule (R.obj X) (M.obj X) + /-- the family is stable under restriction -/ + map {X Y : Cᵒᵖ} (f : X ⟶ Y) : obj X ≤ (obj Y).comap (M.restrictₛₗ f) + +namespace Submodule + +variable {M : PresheafOfModules.{v} R} (N : M.Submodule) + +@[ext] +lemma ext {N₁ N₂ : M.Submodule} (h : ∀ X, N₁.obj X = N₂.obj X) : + N₁ = N₂ := by + cases N₁; cases N₂; congr 1; ext X : 1; exact h X + +@[grind .] +lemma map_mem {X Y : Cᵒᵖ} (f : X ⟶ Y) {x : M.obj X} (hx : x ∈ N.obj X) : + M.map f x ∈ N.obj Y := + N.map f hx + +attribute [local simp] LinearMap.restrict_apply ModuleCat.semilinearMapAddEquiv in +set_option backward.isDefEq.respectTransparency false in +/-- The presheaf of modules associated to a submodule. -/ +@[simps! obj] +noncomputable def toPresheafOfModules : PresheafOfModules.{v} R where + obj X := ModuleCat.of (R.obj X) (N.obj X) + map {X Y} f := + ModuleCat.semilinearMapAddEquiv _ _ _ <| + (M.restrictₛₗ f).restrict (p := N.obj X) (q := N.obj Y) (fun _ hc ↦ N.map_mem _ hc) + +@[simp] +lemma toPresheafOfModules_map_apply {X Y : Cᵒᵖ} (f : X ⟶ Y) (m : N.obj X) : + dsimp% ((N.toPresheafOfModules).map f m).val = M.map f m.val := by + rfl + +/-- The inclusion of a submodule into the ambient presheaf of modules. -/ +@[simps!] +noncomputable def ι : N.toPresheafOfModules ⟶ M := + homMk { app X := AddCommGrpCat.ofHom (N.obj X).subtype.toAddMonoidHom } (by cat_disch) + +instance : Mono N.ι := mono_of_injective fun _ ↦ Subtype.val_injective + +instance : PartialOrder M.Submodule := + PartialOrder.lift _ fun _ _ h ↦ ext (congrFun h) + +lemma le_iff {N₁ N₂ : M.Submodule} : N₁ ≤ N₂ ↔ ∀ X, N₁.obj X ≤ N₂.obj X := + .rfl + +/-- If `N₁` and `N₂` are submodule with `N₁ ≤ N₂`, this is the associated inclusion +of presheaves of modules. -/ +@[simps!] +noncomputable def homOfLE {N₁ N₂ : M.Submodule} (hle : N₁ ≤ N₂) : + N₁.toPresheafOfModules ⟶ N₂.toPresheafOfModules := + homMk { app X := AddCommGrpCat.ofHom (Submodule.inclusion (hle X)).toAddMonoidHom } (by cat_disch) + +instance (N₁ N₂ : M.Submodule) (hle : N₁ ≤ N₂) : Mono (homOfLE hle) := + mono_of_injective fun _ ↦ Submodule.inclusion_injective (hle _) + +@[reassoc (attr := simp)] +lemma homOfLE_ι {N₁ N₂ : M.Submodule} (hle : N₁ ≤ N₂) : homOfLE hle ≫ N₂.ι = N₁.ι := rfl + +@[simps sup_obj inf_obj sSup_obj sInf_obj top_obj bot_obj] +instance : CompleteLattice M.Submodule where + sup F G := + { obj X := F.obj X ⊔ G.obj X + map f := sup_le ((F.map f).trans (Submodule.comap_mono le_sup_left)) + ((G.map f).trans (Submodule.comap_mono le_sup_right)) } + le_sup_left _ _ _ := le_sup_left + le_sup_right _ _ _ := le_sup_right + sup_le _ _ _ h₁ h₂ X := sup_le (h₁ X) (h₂ X) + inf F G := + { obj X := F.obj X ⊓ G.obj X + map f := le_inf (inf_le_left.trans (F.map f)) (inf_le_right.trans (G.map f)) } + inf_le_left _ _ _ := inf_le_left + inf_le_right _ _ _ := inf_le_right + le_inf _ _ _ h₁ h₂ X := le_inf (h₁ X) (h₂ X) + sSup s := + { obj X := ⨆ N ∈ s, N.obj X + map f := iSup₂_le fun N hN ↦ (N.map f).trans + (Submodule.comap_mono (le_iSup₂_of_le N hN le_rfl)) } + isLUB_sSup _ := + ⟨fun N hN _ ↦ le_iSup₂_of_le N hN le_rfl, fun _ hb X ↦ iSup₂_le fun _ hN ↦ hb hN X⟩ + sInf s := + { obj X := ⨅ N ∈ s, N.obj X + map f := by + simp_rw [Submodule.comap_iInf, le_iInf₂_iff] + intro N hN + refine iInf₂_le_of_le _ hN (N.map _) } + isGLB_sInf _ := + ⟨fun N hN _ ↦ iInf₂_le N hN, fun _ hb X ↦ le_iInf₂ fun _ hN ↦ hb hN X⟩ + bot.obj := ⊥ + bot.map _ := bot_le + bot_le _ _ := bot_le + top.obj := ⊤ + top.map _ := le_top + le_top _ _ := le_top + +end Submodule + +end PresheafOfModules diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 494d9e4cd303f1..2e2f7d8ae98dc0 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -245,12 +245,13 @@ theorem comap_inf (f : M →ₛₗ[σ₁₂] M₂) : comap f (q ⊓ q') = comap rfl @[simp] -theorem comap_iInf [RingHomSurjective σ₁₂] {ι : Sort*} (f : M →ₛₗ[σ₁₂] M₂) - (p : ι → Submodule R₂ M₂) : comap f (⨅ i, p i) = ⨅ i, comap f (p i) := - (gc_map_comap f).u_iInf +theorem comap_iInf {ι : Sort*} (f : M →ₛₗ[σ₁₂] M₂) + (p : ι → Submodule R₂ M₂) : comap f (⨅ i, p i) = ⨅ i, comap f (p i) := by + ext + simp @[simp] -theorem comap_finsetInf [RingHomSurjective σ₁₂] {ι : Type*} (f : M →ₛₗ[σ₁₂] M₂) +theorem comap_finsetInf {ι : Type*} (f : M →ₛₗ[σ₁₂] M₂) (s : Finset ι) (p : ι → Submodule R₂ M₂) : comap f (s.inf p) = s.inf fun i ↦ comap f (p i) := by simp [Finset.inf_eq_iInf] From 00249b1489259615cd9c73a6f2c01de8ed7c993c Mon Sep 17 00:00:00 2001 From: Oliver Butterley <51876429+oliver-butterley@users.noreply.github.com> Date: Tue, 30 Jun 2026 14:45:09 +0000 Subject: [PATCH 0458/1300] =?UTF-8?q?feat(MeasureTheory.VectorMeasure):=20?= =?UTF-8?q?add=20lemma=20which=20shows=20that=20variation=20of=20a=20`?= =?UTF-8?q?=E2=84=9D=E2=89=A50=E2=88=9E`=20VectorMeasure=20is=20equal=20to?= =?UTF-8?q?=20itself=20(#26165)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a lemma for the variation of a VectorMeasure which tells that if `μ` is `VectorMeasure X ℝ≥0∞` then ``μ.ennrealVariation = μ`. Co-authored-by: @yoh-tanimoto --- .../MeasureTheory/Measure/PreVariation.lean | 9 +++++ .../VectorMeasure/Variation/Basic.lean | 37 +++++++++++++++++++ Mathlib/Order/Partition/Finpartition.lean | 18 +++++++++ 3 files changed, 64 insertions(+) diff --git a/Mathlib/MeasureTheory/Measure/PreVariation.lean b/Mathlib/MeasureTheory/Measure/PreVariation.lean index d0cd3fbe68d460..b407ad6c372e07 100644 --- a/Mathlib/MeasureTheory/Measure/PreVariation.lean +++ b/Mathlib/MeasureTheory/Measure/PreVariation.lean @@ -55,6 +55,15 @@ noncomputable def preVariationFun (s : Set X) : ℝ≥0∞ := ⨆ (P : Finpartition (⟨s, h⟩ : Subtype MeasurableSet)), ∑ p ∈ P.parts, f p else 0 +lemma preVariationFun_apply {s : Set X} (h : MeasurableSet s) : + preVariationFun f s = + ⨆ (P : Finpartition (⟨s, h⟩ : Subtype MeasurableSet)), ∑ p ∈ P.parts, f p := by + simp [preVariationFun, h] + +lemma preVariationFun_of_not_measurableSet {s : Set X} (h : ¬ MeasurableSet s) : + preVariationFun f s = 0 := by + simp [preVariationFun, h] + end namespace preVariation diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean index 27c729bf7e976e..70a8a696c203ed 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean @@ -23,6 +23,7 @@ such vector-valued measures. * `variation_zero`: `(0 : VectorMeasure X V).variation = 0`. * `variation_neg`: `(-μ).variation = μ.variation`. * `absolutelyContinuous`: `μ ≪ᵥ μ.variation`. +* `ennrealVariation_eq_self`: if `μ : VectorMeasure X ℝ≥0∞` then `μ.ennrealVariation = μ`. ## References @@ -39,6 +40,13 @@ namespace MeasureTheory.VectorMeasure variable {X V : Type*} {mX : MeasurableSpace X} +/-- The sum of a vector measure `μ` on a `Finpartition` of `Subtype MeasurableSet` equals `μ s`. -/ +lemma sum_finpartition [AddCommMonoid V] [TopologicalSpace V] [T2Space V] + (μ : VectorMeasure X V) {s : Set X} {hs : MeasurableSet s} + (P : Finpartition (⟨s, hs⟩ : Subtype MeasurableSet)) : ∑ p ∈ P.parts, μ p.val = μ s := by + rw [← μ.of_biUnion_finset (P.pairwiseDisjoint_apply (fun _ _ => rfl) rfl) (fun p _ => p.prop), + ← Finset.sup_set_eq_biUnion, P.sup_parts_apply (fun _ _ => rfl) rfl] + section Basic variable [TopologicalSpace V] [ENormedAddCommMonoid V] [T2Space V] @@ -404,4 +412,33 @@ lemma _root_.MeasureTheory.SignedMeasure.exists_subset_lt_enorm_apply_of_lt_vari end NormedAddCommGroup +section ENNReal + +variable (μ : VectorMeasure X ℝ≥0∞) + +/-- For `μ : VectorMeasure X ℝ≥0∞` and measurable `s`, the supremum over Finpartitions of +`⟨s, hs⟩ : Subtype MeasurableSet` of the sum of `μ` over parts equals `μ s`. -/ +@[simp] +lemma iSup_sum_finpartition_parts {s : Set X} (hs : MeasurableSet s) : + ⨆ (P : Finpartition (⟨s, hs⟩ : Subtype MeasurableSet)), ∑ p ∈ P.parts, μ p.val = μ s := by + simp_rw [μ.sum_finpartition, iSup_const] + +/-- For `μ : VectorMeasure X ℝ≥0∞`, `preVariationFun μ s = μ s` for any `s`. -/ +lemma preVariationFun_apply_of_ennreal (s : Set X) : preVariationFun μ s = μ s := by + by_cases h : MeasurableSet s + · rw [preVariationFun_apply] + exact iSup_sum_finpartition_parts μ h + · rw [preVariationFun_of_not_measurableSet μ h, not_measurable μ h] + +theorem variation_eq_ennrealToMeasure : μ.variation = μ.ennrealToMeasure := by + ext _ hs + simp [preVariationFun_apply_of_ennreal, variation_apply, preVariation_apply, + ennrealPreVariation_apply, ennrealToMeasure_apply hs] + +@[simp] +theorem ennrealVariation_eq_self : μ.ennrealVariation = μ := by + simp [variation_eq_ennrealToMeasure, ennrealVariation] + +end ENNReal + end MeasureTheory.VectorMeasure diff --git a/Mathlib/Order/Partition/Finpartition.lean b/Mathlib/Order/Partition/Finpartition.lean index 7971be757c1bf9..5cd94e49929259 100644 --- a/Mathlib/Order/Partition/Finpartition.lean +++ b/Mathlib/Order/Partition/Finpartition.lean @@ -195,6 +195,24 @@ theorem ne_bot {b : α} (hb : b ∈ P.parts) : b ≠ ⊥ := by protected theorem disjoint : (P.parts : Set α).PairwiseDisjoint id := P.supIndep.pairwiseDisjoint +section Apply + +variable {β : Type*} {f : α → β} + +/-- The `sup` of a sup-bot-preserving map `f` over the parts of a `Finpartition` equals `f a`. -/ +theorem sup_parts_apply [SemilatticeSup β] [OrderBot β] (hf : ∀ x y, f (x ⊔ y) = f x ⊔ f y) + (hbot : f ⊥ = ⊥) : P.parts.sup f = f a := + (apply_sup_eq_sup_comp f hf hbot).symm.trans (congrArg f P.sup_parts) + +/-- Parts of a `Finpartition` are pairwise disjoint under an inf-bot-preserving map. -/ +theorem pairwiseDisjoint_apply [SemilatticeInf β] [OrderBot β] (hf : ∀ x y, f (x ⊓ y) = f x ⊓ f y) + (hbot : f ⊥ = ⊥) : (P.parts : Set α).PairwiseDisjoint f := by + intro _ hx _ hy hxy + have := (P.disjoint hx hy hxy).eq_bot + simp_all [disjoint_iff, ← hf] + +end Apply + variable {P} @[simp] From 2a3f6b952cac82834211eaa2be2cbb6a560ae88a Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Tue, 30 Jun 2026 14:45:11 +0000 Subject: [PATCH 0459/1300] doc: norm_num imports for primality testing (#41186) Add remark in the `norm_num` docstring saying what imports are needed to use `norm_num` for primality testing. --- Mathlib/Data/Nat/Prime/Defs.lean | 6 ++++++ Mathlib/Tactic/NormNum/Core.lean | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Mathlib/Data/Nat/Prime/Defs.lean b/Mathlib/Data/Nat/Prime/Defs.lean index 852308e4137880..5a4bb9cd22784d 100644 --- a/Mathlib/Data/Nat/Prime/Defs.lean +++ b/Mathlib/Data/Nat/Prime/Defs.lean @@ -162,6 +162,12 @@ much faster. instance decidablePrime (p : ℕ) : Decidable (Prime p) := decidable_of_iff' _ prime_def_lt' +/-! +### Specific small primes + +It is recommended not to add further lemmas to this list; instead, import +`Mathlib.Tactic.NormNum.Prime` in downstream files and use `norm_num` for primality proofs. +-/ theorem prime_two : Prime 2 := by decide theorem prime_three : Prime 3 := by decide diff --git a/Mathlib/Tactic/NormNum/Core.lean b/Mathlib/Tactic/NormNum/Core.lean index 07d76133491ac1..a82d5d3ca3e269 100644 --- a/Mathlib/Tactic/NormNum/Core.lean +++ b/Mathlib/Tactic/NormNum/Core.lean @@ -275,11 +275,11 @@ open Lean.Parser.Tactic Meta.NormNum `ℕ`, `ℤ`, `ℚ`, `ℝ`, `ℂ`. In addition to evaluating numerical expressions, `norm_num` will use `simp` to simplify the goal. If the goal has the form `A = B`, `A ≠ B`, `A < B` or `A ≤ B`, where `A` and `B` are numerical expressions, `norm_num` will try to close it. It also has a relatively simple -primality prover. +primality prover (available if you import `Mathlib.Tactic.NormNum.Prime`). This tactic is extensible. Extensions can allow `norm_num` to evaluate more kinds of expressions, or -to prove more kinds of propositions. See the `@[norm_num]` attribute for further information on -extending `norm_num`. +to prove more kinds of propositions (such as, primality of natural numbers). See the `@[norm_num]` +attribute for further information on extending `norm_num`. * `norm_num at l` normalizes at location(s) `l`. * `norm_num [h1, ...]` adds the arguments `h1, ...` to the `simp` set in addition to the default From a788c76c6fd8d84b390fa32460bd749c948a09f0 Mon Sep 17 00:00:00 2001 From: damiano Date: Tue, 30 Jun 2026 15:26:16 +0000 Subject: [PATCH 0460/1300] feat(CI): check that Mathlib files have lean or md extension (#25473) Twice recently there have been files with an "intended" `.lean` extension in `Mathlib/`: * #24942, ending in `;lean`; * #25457, ending in `.Lean`. `mk_all` does not add these files to `Mathlib.lean`, since they do not end in `.lean` and this later causes problems. This CI step checks that all files in `Mathlib/` end with `.lean` or `.md`. See #25474 for a test where the new step [correctly fails](https://github.com/leanprover-community/mathlib4/actions/runs/15464097783/job/43532018379?pr=25474). --- .github/workflows/lint_and_suggest_pr.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/lint_and_suggest_pr.yml b/.github/workflows/lint_and_suggest_pr.yml index 903e230f59a719..3f350e695ca77c 100644 --- a/.github/workflows/lint_and_suggest_pr.yml +++ b/.github/workflows/lint_and_suggest_pr.yml @@ -13,3 +13,13 @@ jobs: with: mode: suggest lint-bib-file: true + - name: All Mathlib files have a .lean or .md extension + run: | + exc="$(git ls-files 'Mathlib/*' | grep -v "\.\(lean\|md\)$" || true)" + printf '%s\n' "${exc}" + if [ -n "${exc}" ]; + then + printf $'There are files whose extension is neither \'.lean\' nor \'.md\' in Mathlib/:\n\n%s\n' "${exc}" + printf $'\nPlease, make sure that this is really what you want!\n' + exit 1 + fi From 8a75b5a58e58edffd02e817c24c6db2e4f2e5ee4 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:18 +0000 Subject: [PATCH 0461/1300] feat(Combinatorics/SimpleGraph/Paths): some cycle lemmas are true for circuits (#38528) Add `IsCircuit.{not_of_nil,ne_bot,three_le_length}` by using their corresponding `IsCycle` proofs. Also golfs a bit. --- Mathlib/Combinatorics/SimpleGraph/Girth.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 26 +++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Girth.lean b/Mathlib/Combinatorics/SimpleGraph/Girth.lean index 409d1ea7b00153..0be68f1c752e88 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Girth.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Girth.lean @@ -73,7 +73,7 @@ lemma exists_egirth_eq_length : exact ciInf_mem _ lemma three_le_egirth : 3 ≤ G.egirth := by - simpa using fun _ _ a ↦ Walk.IsCycle.three_le_length a + simpa using fun _ _ h ↦ h.three_le_length @[simp] lemma egirth_bot : egirth (⊥ : SimpleGraph α) = ⊤ := by simp diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 62a598da27c8db..575623eea77d78 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -298,25 +298,27 @@ lemma IsPath.ne_of_mem_support_of_append {p : G.Walk u v} {q : G.Walk v w} exact IsPath.disjoint_support_of_append hpq hq hx hx' @[simp] -theorem IsCycle.not_of_nil {u : V} : ¬(nil : G.Walk u u).IsCycle := fun h => h.ne_nil rfl +theorem not_isCircuit_nil {u : V} : ¬(nil : G.Walk u u).IsCircuit := + (·.ne_nil rfl) -lemma IsCycle.ne_bot : ∀ {p : G.Walk u u}, p.IsCycle → G ≠ ⊥ - | nil, hp => by cases hp.ne_nil rfl +@[simp] +theorem not_isCycle_nil {u : V} : ¬(nil : G.Walk u u).IsCycle := + (·.ne_nil rfl) + +@[deprecated (since := "2026-06-16")] alias IsCycle.not_of_nil := not_isCycle_nil + +lemma IsCircuit.ne_bot : ∀ {p : G.Walk u u}, p.IsCircuit → G ≠ ⊥ | cons h _, hp => by rintro rfl; exact h -lemma IsCycle.three_le_length {v : V} {p : G.Walk v v} (hp : p.IsCycle) : 3 ≤ p.length := by - have ⟨⟨hp, hp'⟩, _⟩ := hp +lemma IsCircuit.three_le_length {p : G.Walk v v} (hp : p.IsCircuit) : 3 ≤ p.length := by match p with - | .nil => simp at hp' - | .cons h .nil => simp at h - | .cons _ (.cons _ .nil) => simp at hp - | .cons _ (.cons _ (.cons _ _)) => simp_rw [SimpleGraph.Walk.length_cons]; lia + | .cons hadj .nil => simp at hadj + | .cons _ <| .cons _ .nil => simpa using hp.isTrail + | .cons _ <| .cons _ <| .cons _ _ => grind [length_cons] lemma not_nil_of_isCycle_cons {p : G.Walk u v} {h : G.Adj v u} (hc : (Walk.cons h p).IsCycle) : ¬ p.Nil := by - have := Walk.length_cons _ _ ▸ Walk.IsCycle.three_le_length hc - rw [Walk.not_nil_iff_lt_length] - lia + grind [not_nil_iff_lt_length, hc.three_le_length, length_cons] theorem cons_isCycle_iff {u v : V} (p : G.Walk v u) (h : G.Adj u v) : (Walk.cons h p).IsCycle ↔ p.IsPath ∧ s(u, v) ∉ p.edges := by From fd90ca978de4d1a0ce25d6ef417299b498dd97d7 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 30 Jun 2026 15:26:20 +0000 Subject: [PATCH 0462/1300] refactor(Analysis): golf `Mathlib/Analysis/Normed/Unbundled/AlgebraNorm` (#39898) - refactors `Normed/Unbundled/AlgebraNorm` by using structure inheritance in `MulRingNorm.toRingNorm` --- Mathlib/Analysis/Normed/Unbundled/AlgebraNorm.lean | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/Normed/Unbundled/AlgebraNorm.lean b/Mathlib/Analysis/Normed/Unbundled/AlgebraNorm.lean index 607ec63d94e17e..55997cb1fd7839 100644 --- a/Mathlib/Analysis/Normed/Unbundled/AlgebraNorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/AlgebraNorm.lean @@ -211,15 +211,11 @@ namespace MulRingNorm variable {R : Type*} [NonAssocRing R] -set_option linter.style.whitespace false in -- manual alignment is not recognised /-- The ring norm underlying a multiplicative ring norm. -/ def toRingNorm (f : MulRingNorm R) : RingNorm R where - toFun := f - map_zero' := f.map_zero' - add_le' := f.add_le' - neg' := f.neg' + toFun := f + __ := f mul_le' x y := le_of_eq (f.map_mul' x y) - eq_zero_of_map_eq_zero' := f.eq_zero_of_map_eq_zero' /-- A multiplicative ring norm is power-multiplicative. -/ theorem isPowMul {A : Type*} [Ring A] (f : MulRingNorm A) : IsPowMul f := fun x n hn => by From f4c90700f05a21644f5f196727f34d5b34203107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:22 +0000 Subject: [PATCH 0463/1300] chore: tag `(Continuous)LinearEquiv.prodCongr_symm` with `@[simp]` (#39975) This is consistent with the other `prodCongr`s. Note that this also changes the type of `PiLp.sumPiLpEquivProdLpPiLp_symm_apply_ofLp`, which is now fully simplified. --- Mathlib/LinearAlgebra/Prod.lean | 1 + Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean | 2 +- Mathlib/Topology/Algebra/Module/Equiv.lean | 7 +++---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Prod.lean b/Mathlib/LinearAlgebra/Prod.lean index 21f532a1db5fc0..67074813e619c5 100644 --- a/Mathlib/LinearAlgebra/Prod.lean +++ b/Mathlib/LinearAlgebra/Prod.lean @@ -765,6 +765,7 @@ protected def prodCongr : (M × M₃) ≃ₗ[R] M₂ × M₄ := { e₁.toAddEquiv.prodCongr e₂.toAddEquiv with map_smul' := fun c _x => Prod.ext (e₁.map_smulₛₗ c _) (e₂.map_smulₛₗ c _) } +@[simp] theorem prodCongr_symm : (e₁.prodCongr e₂).symm = e₁.symm.prodCongr e₂.symm := rfl diff --git a/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean b/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean index ded8c0bfb1516a..6fdb13e36dee52 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean @@ -192,7 +192,7 @@ theorem WithLp.volume_preserving_symm_measurableEquiv_toLp_prod : convert! this ext uv <;> simp [volumePreservingSymmMeasurableEquivToLpProdAux, MeasurableEquiv.coe_sumPiEquivProdPi, - LinearEquiv.prodCongr_symm, MeasurableEquiv.prodCongr] + MeasurableEquiv.prodCongr] refine (LinearIsometryEquiv.measurePreserving _).trans ?_ refine (EuclideanSpace.volume_preserving_symm_measurableEquiv_toLp _).trans ?_ refine (measurePreserving_sumPiEquivProdPi _).trans ?_ diff --git a/Mathlib/Topology/Algebra/Module/Equiv.lean b/Mathlib/Topology/Algebra/Module/Equiv.lean index 1c48c97bd88454..b3ade728418b0f 100644 --- a/Mathlib/Topology/Algebra/Module/Equiv.lean +++ b/Mathlib/Topology/Algebra/Module/Equiv.lean @@ -366,10 +366,8 @@ theorem trans_toLinearEquiv (e₁ : M₁ ≃SL[σ₁₂] M₂) (e₂ : M₂ ≃S /-- Product of two continuous linear equivalences. The map comes from `Equiv.prodCongr`. -/ def prodCongr [Module R₁ M₂] [Module R₁ M₃] [Module R₁ M₄] (e : M₁ ≃L[R₁] M₂) (e' : M₃ ≃L[R₁] M₄) : - (M₁ × M₃) ≃L[R₁] M₂ × M₄ := - { e.toLinearEquiv.prodCongr e'.toLinearEquiv with - continuous_toFun := e.continuous_toFun.prodMap e'.continuous_toFun - continuous_invFun := e.continuous_invFun.prodMap e'.continuous_invFun } + (M₁ × M₃) ≃L[R₁] M₂ × M₄ where + __ := e.toLinearEquiv.prodCongr e'.toLinearEquiv @[simp, norm_cast] theorem prodCongr_apply [Module R₁ M₂] [Module R₁ M₃] [Module R₁ M₄] (e : M₁ ≃L[R₁] M₂) @@ -382,6 +380,7 @@ theorem coe_prodCongr [Module R₁ M₂] [Module R₁ M₃] [Module R₁ M₄] ( (e.prodCongr e' : M₁ × M₃ →L[R₁] M₂ × M₄) = (e : M₁ →L[R₁] M₂).prodMap (e' : M₃ →L[R₁] M₄) := rfl +@[simp] theorem prodCongr_symm [Module R₁ M₂] [Module R₁ M₃] [Module R₁ M₄] (e : M₁ ≃L[R₁] M₂) (e' : M₃ ≃L[R₁] M₄) : (e.prodCongr e').symm = e.symm.prodCongr e'.symm := rfl From b4d8056a1b640243232bd386d962cff88c29d6f8 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:25 +0000 Subject: [PATCH 0464/1300] chore(Tactic/Linarith/Parsing): remove local abbrev for `TreeMap` (#40668) We can now write `TreeMap`, and `Ord.compare` is filled in automatically. --- Mathlib/Tactic/Linarith/Parsing.lean | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Mathlib/Tactic/Linarith/Parsing.lean b/Mathlib/Tactic/Linarith/Parsing.lean index 4aa27c1689a328..bca51df08a21ba 100644 --- a/Mathlib/Tactic/Linarith/Parsing.lean +++ b/Mathlib/Tactic/Linarith/Parsing.lean @@ -62,13 +62,10 @@ local instance {α β : Type*} {c : α → α → Ordering} [Add β] [Zero β] [ namespace Mathlib.Tactic.Linarith -/-- A local abbreviation for `TreeMap` so we don't need to write `Ord.compare` each time. -/ -abbrev Map (α β) [Ord α] := TreeMap α β Ord.compare - /-! ### Parsing datatypes -/ /-- Variables (represented by natural numbers) map to their power. -/ -abbrev Monom : Type := Map ℕ ℕ +abbrev Monom : Type := TreeMap ℕ ℕ /-- `1` is represented by the empty monomial, the product of no variables. -/ def Monom.one : Monom := TreeMap.empty @@ -83,7 +80,7 @@ instance : Ord Monom where compare x y := if x.lt y then .lt else if x == y then .eq else .gt /-- Linear combinations of monomials are represented by mapping monomials to coefficients. -/ -abbrev Sum : Type := Map Monom ℤ +abbrev Sum : Type := TreeMap Monom ℤ /-- `1` is represented as the singleton sum of the monomial `Monom.one` with coefficient 1. -/ def Sum.one : Sum := TreeMap.empty.insert Monom.one 1 @@ -200,7 +197,7 @@ The output `TreeMap ℕ ℤ` has the same structure as `s : Sum`, but each monomial key is replaced with its index according to `map`. If any new monomials are encountered, they are assigned variable numbers and `map` is updated. -/ -def elimMonom (s : Sum) (m : Map Monom ℕ) : Map Monom ℕ × Map ℕ ℤ := +def elimMonom (s : Sum) (m : TreeMap Monom ℕ) : TreeMap Monom ℕ × TreeMap ℕ ℤ := s.foldr (fun mn coeff ⟨map, out⟩ ↦ match map[mn]? with | some n => ⟨map, out.insert n coeff⟩ @@ -216,8 +213,8 @@ into a `comp` object. `e_map` maps atomic expressions to indices; `monom_map` maps monomials to indices. Both of these are updated during processing and returned. -/ -def toComp (red : TransparencyMode) (e : Expr) (e_map : ExprMap) (monom_map : Map Monom ℕ) : - MetaM (Comp × ExprMap × Map Monom ℕ) := do +def toComp (red : TransparencyMode) (e : Expr) (e_map : ExprMap) (monom_map : TreeMap Monom ℕ) : + MetaM (Comp × ExprMap × TreeMap Monom ℕ) := do let (iq, e) ← parseCompAndExpr e let (m', comp') ← linearFormOfExpr red e_map e let ⟨nm, mm'⟩ := elimMonom comp' monom_map @@ -228,8 +225,8 @@ def toComp (red : TransparencyMode) (e : Expr) (e_map : ExprMap) (monom_map : Ma `toCompFold red e_map exprs monom_map` folds `toComp` over `exprs`, updating `e_map` and `monom_map` as it goes. -/ -def toCompFold (red : TransparencyMode) : ExprMap → List Expr → Map Monom ℕ → - MetaM (List Comp × ExprMap × Map Monom ℕ) +def toCompFold (red : TransparencyMode) : ExprMap → List Expr → TreeMap Monom ℕ → + MetaM (List Comp × ExprMap × TreeMap Monom ℕ) | m, [], mm => return ([], m, mm) | m, (h::t), mm => do let (c, m', mm') ← toComp red h m mm From 8d4799baa33c3a1582616be08f14f18445866810 Mon Sep 17 00:00:00 2001 From: "Malhar A. Patel" <142735852+Mal-Pat@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:27 +0000 Subject: [PATCH 0465/1300] doc(Combinatorics/SimpleGraph/Girth): fix incorrect TODO statement (#40787) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TODO statement `G.egirth ≤ 2 * G.ediam + 1` on its own is incorrect - a finite acyclic graph has `G.egirth = ∞` with finite `G.ediam`. The condition that `G` must not be acyclic has been added to the statement to make it correct. Also, the condition that the diameter must be non-zero is not required to prove `¬ G.IsAcyclic → G.egirth ≤ 2 * G.ediam + 1`. --- Mathlib/Combinatorics/SimpleGraph/Girth.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Girth.lean b/Mathlib/Combinatorics/SimpleGraph/Girth.lean index 0be68f1c752e88..1a0b3b537b12a9 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Girth.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Girth.lean @@ -16,8 +16,8 @@ cycle, they give `0` or `∞` respectively if the graph is acyclic. ## TODO -- Prove that `G.egirth ≤ 2 * G.ediam + 1` and `G.girth ≤ 2 * G.diam + 1` when the diameter is - non-zero. +- Prove that `G.egirth ≤ 2 * G.ediam + 1` when `G` is not acyclic +- Prove that `G.girth ≤ 2 * G.diam + 1` when the diameter is non-zero -/ From f9c485bdb99bfe34e3624ee0d36b8c4a3ace85f7 Mon Sep 17 00:00:00 2001 From: "Malhar A. Patel" <142735852+Mal-Pat@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:29 +0000 Subject: [PATCH 0466/1300] =?UTF-8?q?feat(Combinatorics/SimpleGraph/Paths)?= =?UTF-8?q?:=20`p.IsPath=20=E2=86=92=20p.bypass=20=3D=20p`=20(#40801)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A useful lemma - if `p` is a path, then `p.bypass = p`. --- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 575623eea77d78..085e35d3b587c2 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -907,6 +907,10 @@ lemma bypass_eq_self_of_length_le_length_bypass (p : G.Walk u v) (h : p.length @[deprecated (since := "2026-05-25")] alias bypass_eq_self_of_length_le := bypass_eq_self_of_length_le_length_bypass +@[grind →] +lemma IsPath.bypass_eq_self {p : G.Walk u v} (hp : p.IsPath) : p.bypass = p := by + induction p <;> simp_all [cons_isPath_iff, bypass] + theorem darts_toPath_subset_darts (p : G.Walk u v) : (p.toPath : G.Walk u v).darts ⊆ p.darts := p.darts_bypass_subset_darts From 957d4de9077e5d79b6dd1b5b5123118f66810c63 Mon Sep 17 00:00:00 2001 From: Sidharth Hariharan <64404030+thefundamentaltheor3m@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:32 +0000 Subject: [PATCH 0467/1300] feat(NumberTheory/Primorial): a few simple facts (#40980) We prove - the primorial is squarefree - the prime factors of the primorial are precisely `primesLE` We also add that it is non-zero (mere convenience API). Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib/NumberTheory/Primorial.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/NumberTheory/Primorial.lean b/Mathlib/NumberTheory/Primorial.lean index 4b40516e23a162..147e83d499d4d4 100644 --- a/Mathlib/NumberTheory/Primorial.lean +++ b/Mathlib/NumberTheory/Primorial.lean @@ -43,6 +43,10 @@ local notation x "#" => primorial x lemma primorial_eq_prod_primesLE (n : ℕ) : n # = ∏ p ∈ primesLE n, p := rfl +lemma primeFactors_primorial (n : ℕ) : primeFactors (n#) = primesLE n := by + rw [primorial_eq_prod_primesLE] + exact primeFactors_prod fun _ hp ↦ prime_of_mem_primesLE hp + @[simp] theorem primorial_zero : 0 # = 1 := by decide @[simp] theorem primorial_one : 1 # = 1 := by decide @@ -52,6 +56,8 @@ lemma primorial_eq_prod_primesLE (n : ℕ) : n # = ∏ p ∈ primesLE n, p := rf theorem primorial_pos (n : ℕ) : 0 < n# := prod_pos fun _p hp ↦ (mem_filter.1 hp).2.pos +lemma primorial_ne_zero (n : ℕ) : n# ≠ 0 := (primorial_pos n).ne' + theorem primorial_mono {m n : ℕ} (h : m ≤ n) : m# ≤ n# := prod_le_prod_of_subset_of_one_le' (by gcongr) (by grind) @@ -139,3 +145,10 @@ theorem primorial_le_four_pow (n : ℕ) : n# ≤ 4 ^ n := by · exact (primorial_lt_four_pow n hn).le @[deprecated (since := "2026-03-21")] alias primorial_le_4_pow := primorial_le_four_pow + +lemma squarefree_primorial (n : ℕ) : Squarefree (n#) := by + rw [primorial_eq_prod_primesLE] + refine Finset.squarefree_prod_of_pairwise_isCoprime (fun _ hp _ hq hpq ↦ ?_) + fun _ hp ↦ (prime_of_mem_primesLE hp).squarefree + simp only [← coprime_iff_isRelPrime] + exact (coprime_primes (prime_of_mem_primesLE hp) (prime_of_mem_primesLE hq)).mpr hpq From ef089a7279321321105167bd189308b2288017e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= <4094732+RemyDegenne@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:34 +0000 Subject: [PATCH 0468/1300] chore(downstream_repos): add Lean Machine Learning (#41020) This PR adds the Lean Machine Learning repository to downstream_repos.yml (hence to the page https://leanprover-community.github.io/lean_projects.html). Co-authored-by: Remy Degenne --- scripts/downstream_repos.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/downstream_repos.yml b/scripts/downstream_repos.yml index 2c29d75c188d29..419a9addf503af 100644 --- a/scripts/downstream_repos.yml +++ b/scripts/downstream_repos.yml @@ -92,6 +92,15 @@ build: push.yml docs: push.yml release-tag: lean-release-tag.yml +- github: https://github.com/LeanMachineLearning/LML + default_branch: main + name: Lean Machine Learning + zulip-contact: Rémy Degenne + workflows: + build: blueprint.yml + docs: blueprint.yml + release-tag: create-release.yml + update: update.yml - github: https://github.com/RemyDegenne/brownian-motion default_branch: master name: Brownian motion project From f412ff5ab5f59b294ec527de45ca5f09a4a6be51 Mon Sep 17 00:00:00 2001 From: gnahz04 <7452518+gnahz04@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:37 +0000 Subject: [PATCH 0469/1300] feat(Analysis/InnerProductSpace): bounded point evaluation in an RKHS (#41129) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `RKHS.norm_eval_le`, the element-wise bound `‖f x‖ ≤ ‖f‖ * √‖kernel H x x‖` on point evaluations in a reproducing kernel Hilbert space, complementing the existing matrix-level bound `norm_kernel_le`. It is stated directly on `f x` (like `continuous_eval`), so it does not depend on the explicit `eval` from #37666. Discussed and named on Zulip: [#mathlib4 > RKHS bounded point evaluation](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/RKHS.20bounded.20point.20evaluation) (thanks to Hampus Nyberg, Amlal El Mahrouss, Tjeerd Jan Heeringa, Yaël Dillies). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Hao Zhang Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib/Analysis/InnerProductSpace/Reproducing.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/Reproducing.lean b/Mathlib/Analysis/InnerProductSpace/Reproducing.lean index 7d3d0ed6787d99..afe6444ebe321c 100644 --- a/Mathlib/Analysis/InnerProductSpace/Reproducing.lean +++ b/Mathlib/Analysis/InnerProductSpace/Reproducing.lean @@ -108,6 +108,12 @@ lemma kerFun_apply (y : X) (v : V) (x : X) : kerFun H y v x = kernel H x y v := lemma kernel_apply (x y : X) : kernel H x y = (kerFun H x).adjoint ∘L kerFun H y := by simp [kerFun, kernel] +variable {H} in +/-- Point evaluation `f ↦ f x` is the adjoint of the kernel function `kerFun H x`. -/ +@[simp] +lemma adjoint_kerFun (x : X) (f : H) : (kerFun H x).adjoint f = f x := by + simp [kerFun] + variable {H} in /-- The "reproducing" property of the kernel functions, left version. -/ @[simp] @@ -138,6 +144,12 @@ lemma norm_kernel_le (x y) : ‖kernel H x y‖ ≤ √‖kernel H x x‖ * √ lemma norm_kernel_sq_le (x y) : ‖kernel H x y‖ ^ 2 ≤ ‖kernel H x x‖ * ‖kernel H y y‖ := by grw [norm_kernel_le]; simp [mul_pow] +variable {H} in +/-- The evaluation of an element `f` of a reproducing kernel Hilbert space at a point `x` is +bounded by `‖f‖` times the square root of the kernel diagonal `‖kernel H x x‖` at `x`. -/ +lemma norm_apply_le (f : H) (x : X) : ‖f x‖ ≤ ‖f‖ * √‖kernel H x x‖ := by + grw [← adjoint_kerFun, le_opNorm, norm_map, norm_kerFun_eq_sqrt_norm_kernel, mul_comm] + /-- The span of the kernel functions is dense. -/ theorem kerFun_dense : topologicalClosure (span 𝕜 {kerFun H x v | (x) (v)}) = ⊤ := by refine (orthogonal_eq_bot_iff.mp ((Submodule.eq_bot_iff _).mpr fun f fin ↦ DFunLike.ext f 0 ?_)) From 0ca2949f8ad61d7705cbf2c3afe0efa1f5c2bfca Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:26:39 +0000 Subject: [PATCH 0470/1300] chore: rename MDifferentiable.smul and friends to fun_smul (#41173) By the style guide, this is how they should be named anyway. Add the point-free versions, and use to_fun to auto-generate the eta-expanded versions. The point-free version was needed in #40508, for use in a side condition of a rw lemma. --- Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index f41ccc404fbbf6..bbf7333557df2e 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -310,15 +310,18 @@ theorem MDifferentiableWithinAt.smul ((contMDiff_smul.of_le le_top).mdifferentiable one_ne_zero _).comp_mdifferentiableWithinAt x (hf.prodMk hg) +@[to_fun] theorem MDifferentiableAt.smul (hf : MDiffAt f x) - (hg : MDiffAt g x) : MDiffAt (fun p ↦ f p • g p) x := + (hg : MDiffAt g x) : MDiffAt (f • g) x := ((contMDiff_smul.of_le le_top).mdifferentiable one_ne_zero _).comp x (hf.prodMk hg) +@[to_fun] theorem MDifferentiableOn.smul (hf : MDiff[s] f) - (hg : MDiff[s] g) : MDiff[s] (fun p ↦ f p • g p) := + (hg : MDiff[s] g) : MDiff[s] (f • g) := fun x hx ↦ (hf x hx).smul (hg x hx) -theorem MDifferentiable.smul (hf : MDiff f) (hg : MDiff g) : MDiff fun p ↦ f p • g p := +@[to_fun] +theorem MDifferentiable.smul (hf : MDiff f) (hg : MDiff g) : MDiff (f • g) := fun x ↦ (hf x).smul (hg x) -- TODO: deprecate in favour of `mvfderiv_smul`, then delete this lemma From 19c7b8c2b5f166b9d9df7e8ad78b674861e6fdcb Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 30 Jun 2026 16:05:00 +0000 Subject: [PATCH 0471/1300] feat(LinearAlgebra/AffineSpace): parallel cross-section of a simplex (#36018) This shows that the intersection of `AffineSubspace.shift` of the base of a simplex and the interior of the simplex is a smaller simplex. This is preparing to calculate the volume of a simplex by integrating this cross-section. Part of #37910. Co-authored-by: Junyan Xu --- .../AffineSpace/AffineSubspace/Shift.lean | 130 +++++++++++++++++- .../AffineSpace/Simplex/Basic.lean | 4 + 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean index 37edd698fd6839..1fb399ba99ebad 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean @@ -5,7 +5,7 @@ Authors: Weiyi Wang -/ module -public import Mathlib.LinearAlgebra.AffineSpace.AffineSubspace.Basic +public import Mathlib.LinearAlgebra.AffineSpace.Simplex.Basic /-! # Shifting an affine subspace towards a point @@ -97,6 +97,50 @@ theorem shift_one (s : AffineSubspace k P) (c : P) : s.shift c 1 = s := by have h : Nonempty s := by simpa using! h simp [shift, h] +/-- Consider a point `A` with barycentric coordinates associated to a collection of points `P`. +If the coordinate associated to one of the points `Pᵢ` is `r`, then the point `A` is on the span +of `P \ {Pᵢ}` shifted towards `Pᵢ` with parameter `1 - r`. -/ +theorem affineCombination_mem_shift {ι : Type*} [Fintype ι] [Nontrivial ι] + (p : ι → P) (i : ι) {w : ι → k} (hw : ∑ i, w i = 1) : + affineCombination k univ p w ∈ (affineSpan k <| p '' {i}ᶜ).shift (p i) (1 - w i) := by + cases subsingleton_or_nontrivial k + · suffices (affineSpan k <| p '' {i}ᶜ) = ⊤ by simp [this] + have : Subsingleton P := (AddTorsor.subsingleton_iff V P).mp <| Module.subsingleton k V + simp + classical + obtain ⟨j, hj⟩ := exists_ne i + rw [shift_eq ⟨p j, mem_affineSpan k <| Set.mem_image_of_mem _ hj⟩] + suffices ∃ q ∈ affineSpan k (p '' {i}ᶜ), w i • (p i -ᵥ p j) +ᵥ q = affineCombination k univ p w by + simpa + refine ⟨-(w i • (p i -ᵥ p j)) +ᵥ affineCombination k univ p w, ?_, by simp⟩ + rw [← affineCombination_piSingle k _ p (mem_univ i), + ← affineCombination_piSingle k _ p (mem_univ j), affineCombination_vsub, ← map_smul, ← map_neg, + weightedVSub_vadd_affineCombination] + refine affineCombination_mem_affineSpan_image ?_ (fun i' _ hi ↦ by aesop) _ + simp [sum_add_distrib, ← mul_sum, hw] + +/-- The iff version of `affineCombination_mem_shift` for affine independent points. -/ +theorem _root_.AffineIndependent.affineCombination_mem_shift_iff + {ι : Type*} [Fintype ι] [Nontrivial ι] {p : ι → P} + (h : AffineIndependent k p) (i : ι) {w : ι → k} (hw : ∑ i, w i = 1) (c : k) : + affineCombination k univ p w ∈ (affineSpan k <| p '' {i}ᶜ).shift (p i) c ↔ + w i = 1 - c := by + classical + refine ⟨?_, fun h ↦ by simpa [h] using affineCombination_mem_shift p i hw⟩ + obtain ⟨j, hj⟩ := exists_ne i + rw [shift_eq ⟨p j, mem_affineSpan k <| Set.mem_image_of_mem _ hj⟩] + suffices ∀ q ∈ affineSpan k (p '' {i}ᶜ), + (1 - c) • (p i -ᵥ p j) +ᵥ q = affineCombination k univ p w → w i = 1 - c by simpa + intro q hqmem heq + obtain ⟨t, w', ht, hw', rfl⟩ := eq_affineCombination_of_mem_affineSpan_image hqmem + have ht : (t : Set ι).indicator w' i = 0 := Set.indicator_of_notMem (by simpa using ht) w' + rw [affineCombination_indicator_subset _ _ t.subset_univ, + ← affineCombination_piSingle k _ p (mem_univ i), + ← affineCombination_piSingle k _ p (mem_univ j), affineCombination_vsub, ← map_smul, + weightedVSub_vadd_affineCombination, h.affineCombination_eq_iff_eq ?_ hw] at heq + · simpa [hj.symm, ht] using (heq i (mem_univ i)).symm + · simp [sum_add_distrib, sum_indicator_subset, ← mul_sum, hw'] + end Ring section CommRing @@ -130,3 +174,87 @@ theorem shift_eq_map_homothety (s : AffineSubspace k P) (c : P) {r : k} (hr : Is end CommRing end AffineSubspace + +namespace Affine.Simplex + +section Ring +variable [Ring k] [PartialOrder k] [IsOrderedAddMonoid k] [AddCommGroup V] [AddTorsor V P] + [Module k V] {n : ℕ} [NeZero n] (s : Affine.Simplex k P n) (i : Fin (n + 1)) + +/-- The base of a simplex shifted with parameter 0 intersects the closed interior only at the +vertex. -/ +theorem closedInterior_inter_shift_zero [ZeroLEOneClass k] : + s.closedInterior ∩ (affineSpan k <| s.points '' {i}ᶜ).shift (s.points i) 0 = + {s.points i} := by + refine subset_antisymm (fun p ⟨hp, hshift⟩ ↦ ?_) (by simp [s.point_mem_closedInterior i]) + obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype <| + s.closedInterior_subset_affineSpan hp + suffices w = Pi.single i 1 by simp [this] + rw [affineCombination_mem_closedInterior_iff hw] at hp + rw [SetLike.mem_coe, s.independent.affineCombination_mem_shift_iff i hw, sub_zero] at hshift + ext j + by_cases hj : j = i + · aesop + rw [← univ.sum_erase_add w (mem_univ i), hshift, add_eq_right, + sum_eq_zero_iff_of_nonneg fun j _ ↦ (hp j).1] at hw + simp [hw j (by simpa using hj), hj] + +/-- The base of a simplex shifted with parameter outside $[0, 1]$ does not intersect the closed +interior. -/ +theorem disjoint_closedInterior_shift {x : k} (hx : x < 0 ∨ 1 < x) : + Disjoint s.closedInterior <| (affineSpan k (s.points '' {i}ᶜ)).shift (s.points i) x := by + refine Set.disjoint_left.mpr fun p hleft hright ↦ ?_ + obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype <| + s.closedInterior_subset_affineSpan hleft + rw [SetLike.mem_coe, s.independent.affineCombination_mem_shift_iff i hw] at hright + rw [affineCombination_mem_closedInterior_iff hw] at hleft + grind + +end Ring + +section Field +variable [Field k] [LinearOrder k] [IsOrderedRing k] [AddCommGroup V] [Module k V] [AddTorsor V P] + +private theorem closedInterior_inter_shift_aux {n : ℕ} (i : Fin n) {x : k} (hxpos : 0 < x) + (hx1 : x ≤ 1) {w : Fin n → k} (hw : ∑ i, w i = 1) : + (∀ j, w j ∈ Set.Icc 0 1) ∧ w i = 1 - x ↔ + (∀ j, j ≠ i → x⁻¹ * w j ∈ Set.Icc 0 1) ∧ x⁻¹ * (w i - 1) + 1 = 0 := by + rw [show x⁻¹ * (w i - 1) + 1 = 0 ↔ w i = 1 - x by grind] + refine and_congr_left fun hi ↦ ⟨fun hj j hji ↦ ⟨?_, ?_⟩, fun hj ↦ ?_⟩ + · exact mul_nonneg (by simpa using hxpos.le) (hj j).1 + · rw [eq_sub_iff_add_eq, add_comm, ← eq_sub_iff_add_eq] at hi + rw [inv_mul_le_one₀ hxpos, hi, le_sub_iff_add_le, ← hw] + exact add_le_sum (fun i _ ↦ (hj i).1) (mem_univ j) (mem_univ i) hji + · suffices ∀ j, 0 ≤ w j from + fun j ↦ ⟨this j, hw ▸ Finset.single_le_sum (fun j _ ↦ this j) (mem_univ j)⟩ + intro j + by_cases hji : j = i <;> aesop + +/-- A parallel cross-section of a simplex is the image of the base under a homothety. -/ +theorem closedInterior_inter_shift_eq_homothety {n : ℕ} [NeZero n] (s : Affine.Simplex k P n) + (i : Fin (n + 1)) {x : k} (hx : x ∈ Set.Icc 0 1) : + s.closedInterior ∩ (affineSpan k (s.points '' {i}ᶜ)).shift (s.points i) x = + homothety (s.points i) x '' (s.faceOpposite i).closedInterior := by + rcases hx.1.eq_or_lt with hx0 | hxpos + · simpa [hx0.symm, nonempty_closedInterior] using s.closedInterior_inter_shift_zero i + ext p + by_cases hp : p ∈ affineSpan k (.range s.points) + · obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype hp + rw [Set.mem_inter_iff, SetLike.mem_coe, s.independent.affineCombination_mem_shift_iff i hw, + affineCombination_mem_closedInterior_iff hw, Set.mem_image] + simp_rw [AffineMap.homothety_eq_iff_of_mul_eq_one (mul_inv_cancel₀ hxpos.ne.symm), + univ.homothety_affineCombination _ _ (mem_univ i)] + simp only [↓existsAndEq, and_true] + rw [faceOpposite, affineCombination_mem_closedInterior_face_iff_mem_Icc, + closedInterior_inter_shift_aux i hxpos hx.2 hw] + · simp only [mem_compl, mem_singleton, not_not, forall_eq] + congrm (∀ j, (hj : _) → $(by simp [lineMap_apply, hj])) ∧ $(by simp [lineMap_apply]) + · simp [AffineMap.lineMap_apply, Finset.sum_add_distrib, ← Finset.mul_sum, + Finset.sum_sub_distrib, hw] + · apply iff_of_false (hp <| s.closedInterior_subset_affineSpan ·.1) + rintro ⟨q, hq, rfl⟩ + exact hp <| homothety_mem (mem_affineSpan _ (by simp)) _ <| + affineSpan_mono _ (by simp) ((s.faceOpposite i).closedInterior_subset_affineSpan hq) + +end Field +end Affine.Simplex diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean index 8ec160506c7636..9137bd70e99de2 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean @@ -497,6 +497,10 @@ lemma point_mem_closedInterior [ZeroLEOneClass k] {n : ℕ} (s : Simplex k P n) intro j obtain rfl | hj := eq_or_ne j i <;> simp_all +lemma nonempty_closedInterior [ZeroLEOneClass k] {n : ℕ} (s : Simplex k P n) : + s.closedInterior.Nonempty := + ⟨s.points 0, s.point_mem_closedInterior 0⟩ + lemma interior_ssubset_closedInterior [ZeroLEOneClass k] {n : ℕ} (s : Simplex k P n) : s.interior ⊂ s.closedInterior := by rw [Set.ssubset_iff_exists] From 818de64f411d8a041dc0c83c84895675d2caea53 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 30 Jun 2026 16:05:03 +0000 Subject: [PATCH 0472/1300] doc(1000.yaml): note more formalised theorems (#38358) --- docs/1000.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/1000.yaml b/docs/1000.yaml index a500e287af5204..3b3cef90ecd4b2 100644 --- a/docs/1000.yaml +++ b/docs/1000.yaml @@ -241,6 +241,7 @@ Q225973: Q226014: title: Poincaré recurrence theorem + decl: MeasureTheory.Conservative.ae_mem_imp_frequently_image_mem Q230848: title: Lamé’s theorem @@ -365,6 +366,7 @@ Q332465: Q338886: title: Divergence theorem + decl: MeasureTheory.integral_divergence_of_hasFDerivAt_off_countable Q339495: title: Symphonic theorem @@ -681,7 +683,7 @@ Q656176: Q656198: title: Maschke's theorem - # `RepresentationTheory/Maschke` comes very close, but doesn't prove the standard form yet... + decl: MonoidAlgebra.Submodule.exists_isCompl Q656645: title: Hilbert's basis theorem @@ -1400,6 +1402,7 @@ Q1139524: Q1140119: title: Morera's theorem + decl: Complex.isConservativeOn_and_continuousOn_iff_isDifferentiableOn Q1140200: title: PCP theorem @@ -2245,6 +2248,9 @@ Q2621667: Q2631152: title: Carathéodory's extension theorem + decls: + - MeasureTheory.AddContent.measure + - MeasureTheory.AddContent.measure_eq Q2635326: title: Structured program theorem @@ -2481,7 +2487,7 @@ Q3527162: Q3527166: title: Steinhaus theorem - # not difficult, but seemingly missing + decl: MeasureTheory.Measure.div_mem_nhds_one_of_haar_pos Q3527171: title: Synge's theorem @@ -4156,6 +4162,7 @@ Q20278711: Q20971632: title: Lie's theorem + decl: LieModule.exists_nontrivial_weightSpace_of_isSolvable Q22952648: title: Uncountability of the continuum From 05960695f71916de572f5925f257da8dae193b0a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky <5342086+pechersky@users.noreply.github.com> Date: Tue, 30 Jun 2026 16:05:07 +0000 Subject: [PATCH 0473/1300] feat(Algebra/Group/Hom): upgrade a MulHom to a MonoidHomClass when codomain is left-cancellative (#40694) Allows for easier manipulation when inv and div is taken over terms mapped by MulHoms --- Mathlib/Algebra/Group/Hom/Defs.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index ab1fcb1515dab3..87ff9898f913a9 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -714,6 +714,23 @@ theorem map_exists_left_inv (f : F) {x : M} (hx : ∃ y, y * x = 1) : ∃ y, y * @[deprecated (since := "2025-12-14")] alias isDedekindFiniteMonoid_of_injective := IsDedekindFiniteMonoid.of_injective +@[to_additive] +instance {M N : Type*} [Monoid M] [LeftCancelMonoid N] : MonoidHomClass (M →ₙ* N) M N where + map_mul := MulHom.map_mul' + map_one f := by + have h : f 1 * 1 = f 1 * f 1 := by simpa using f.map_mul' 1 1 + exact (mul_left_cancel h).symm + +@[to_additive] +instance {M N : Type*} [Monoid M] [RightCancelMonoid N] : MonoidHomClass (M →ₙ* N) M N where + map_mul := MulHom.map_mul' + map_one f := by + have h : 1 * f 1 = f 1 * f 1 := by simpa using f.map_mul' 1 1 + exact (mul_right_cancel h).symm + +@[to_additive] +instance {M N : Type*} [Monoid M] [CancelMonoid N] : MonoidHomClass (M →ₙ* N) M N where + end MonoidHom /-- The identity map from a type with 1 to itself. -/ From ca158545413b9fc388b53e8a9bf6342234d5ba06 Mon Sep 17 00:00:00 2001 From: Alexey Milovanov <217577786+AlexeyMilovanov@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:09 +0000 Subject: [PATCH 0474/1300] =?UTF-8?q?refactor(Computability.Encoding):=20u?= =?UTF-8?q?nbundle=20=CE=93=20and=20remove=20FinEncoding=20(#37928)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR unbundles the alphabet `Γ` from the `Encoding` structure and completely removes `FinEncoding`. `Encoding`: The alphabet `Γ` is now an explicit parameter: `structure Encoding (α : Type u) (Γ : Type v)`. `FinEncoding`: Removed. Finiteness is now handled via standard typeclasses (e.g., `[Fintype Γ] (e : Encoding α Γ)`). Combinators: Functions like `finEncodingPair` are simplified to `encodingPair`, dropping the `fin` prefix and `[Fintype]` requirements where no longer needed. Downstream: Mechanically updated `Mathlib.Computability` and `Mathlib.ModelTheory` to pass the explicit `Γ` and use `[Fintype Γ]` where `FinEncoding` was previously required. Co-authored-by: AlexeyMilovanov --- Mathlib/Computability/Encoding.lean | 144 ++++++++++++++++------------ Mathlib/ModelTheory/Encoding.lean | 10 +- 2 files changed, 87 insertions(+), 67 deletions(-) diff --git a/Mathlib/Computability/Encoding.lean b/Mathlib/Computability/Encoding.lean index 38066ea8ffc561..4cd65ae2e2275e 100644 --- a/Mathlib/Computability/Encoding.lean +++ b/Mathlib/Computability/Encoding.lean @@ -14,23 +14,22 @@ public import Mathlib.Tactic.DeriveFintype /-! # Encodings -This file contains the definition of a (finite) encoding, a map from a type to +This file contains the definition of an encoding, a map from a type to strings in an alphabet, used in defining computability by Turing machines. It also contains several examples: ## Examples -- `finEncodingNatBool` : a binary encoding of `ℕ` in a simple alphabet. -- `finEncodingNatΓ'` : a binary encoding of `ℕ` in the alphabet used for TM's. -- `unaryFinEncodingNat` : a unary encoding of `ℕ` -- `finEncodingBoolBool` : an encoding of `Bool`. -- `finEncodingList` : an encoding of `List α` in the alphabet `α`. -- `finEncodingPair` : an encoding of `α × β` from encodings of `α` and `β`. +- `encodingNatBool` : a binary encoding of `ℕ` in a simple alphabet. +- `encodingNatΓ'` : a binary encoding of `ℕ` in the alphabet used for TM's. +- `unaryEncodingNat` : a unary encoding of `ℕ` +- `encodingBoolBool` : an encoding of `Bool`. +- `encodingList` : an encoding of `List α` in the alphabet `α`. +- `encodingProd` : an encoding of `α × β` from encodings of `α` and `β`. -/ @[expose] public section - universe u v open Cardinal @@ -38,9 +37,7 @@ open Cardinal namespace Computability /-- An encoding of a type in a certain alphabet, together with a decoding. -/ -structure Encoding (α : Type u) where - /-- The alphabet of the encoding -/ - Γ : Type v +structure Encoding (α : Type u) (Γ : Type v) where /-- The encoding function -/ encode : α → List Γ /-- The decoding function -/ @@ -50,18 +47,10 @@ structure Encoding (α : Type u) where attribute [simp] Encoding.decode_encode -theorem Encoding.encode_injective {α : Type u} (e : Encoding α) : Function.Injective e.encode := by +theorem Encoding.encode_injective {α Γ} (e : Encoding α Γ) : Function.Injective e.encode := by refine fun _ _ h => Option.some_injective _ ?_ rw [← e.decode_encode, ← e.decode_encode, h] -/-- An `Encoding` plus a guarantee of finiteness of the alphabet. -/ -structure FinEncoding (α : Type u) extends Encoding.{u, 0} α where - /-- The alphabet of the encoding is finite -/ - ΓFin : Fintype Γ - -instance Γ.fintype {α : Type u} (e : FinEncoding α) : Fintype e.toEncoding.Γ := - e.ΓFin - /-- A standard Turing machine alphabet, consisting of blank,bit0,bit1,bra,ket,comma. -/ inductive Γ' | blank @@ -141,27 +130,17 @@ theorem encodePosNum_nonempty (n : PosNum) : encodePosNum n ≠ [] := exact congr_arg ((↑) : Num → ℕ) (decode_encodeNum n) /-- A binary `Encoding` of `ℕ` in `Bool`. -/ -def encodingNatBool : Encoding ℕ where - Γ := Bool +def encodingNatBool : Encoding ℕ Bool where encode := encodeNat decode n := some (decodeNat n) decode_encode n := congr_arg _ (decode_encodeNat n) -/-- A binary encoding of `ℕ` in `Bool`, as a `FinEncoding`. -/ -def finEncodingNatBool : FinEncoding ℕ := - ⟨encodingNatBool, Bool.fintype⟩ - /-- A binary `Encoding` of `ℕ` in `Γ'`. -/ -def encodingNatΓ' : Encoding ℕ where - Γ := Γ' +def encodingNatΓ' : Encoding ℕ Γ' where encode x := List.map inclusionBoolΓ' (encodeNat x) decode x := some (decodeNat (List.map sectionΓ'Bool x)) decode_encode x := congr_arg _ <| by simp [Function.comp_def] -/-- A binary `FinEncoding` of `ℕ` in `Γ'`. -/ -def finEncodingNatΓ' : FinEncoding ℕ := - ⟨encodingNatΓ', inferInstanceAs (Fintype Γ')⟩ - /-- A unary encoding function of `ℕ` in `Bool`. -/ def unaryEncodeNat : Nat → List Bool | 0 => [] @@ -174,13 +153,11 @@ def unaryDecodeNat : List Bool → Nat := @[simp] theorem unary_decode_encode_nat : ∀ n, unaryDecodeNat (unaryEncodeNat n) = n := fun n => Nat.rec rfl (fun (_m : ℕ) hm => (congr_arg Nat.succ hm.symm).symm) n -/-- A unary `FinEncoding` of `ℕ` in `Bool`. -/ -def unaryFinEncodingNat : FinEncoding ℕ where - Γ := Bool +/-- A unary `Encoding` of `ℕ` in `Bool`. -/ +def unaryEncodingNat : Encoding ℕ Bool where encode := unaryEncodeNat decode n := some (unaryDecodeNat n) decode_encode n := congr_arg _ (unary_decode_encode_nat n) - ΓFin := Bool.fintype /-- An encoding function of `Bool` in `Bool`. -/ def encodeBool : Bool → List Bool := pure @@ -192,53 +169,98 @@ def decodeBool : List Bool → Bool @[simp] theorem decode_encodeBool (b : Bool) : decodeBool (encodeBool b) = b := rfl -/-- A `FinEncoding` of `Bool` in `Bool`. -/ -def finEncodingBoolBool : FinEncoding Bool where - Γ := Bool +/-- An `Encoding` of `Bool` in `Bool`. -/ +def encodingBoolBool : Encoding Bool Bool where encode := encodeBool decode x := some (decodeBool x) decode_encode x := congr_arg _ (decode_encodeBool x) - ΓFin := Bool.fintype - -instance inhabitedFinEncoding : Inhabited (FinEncoding Bool) := - ⟨finEncodingBoolBool⟩ -instance inhabitedEncoding : Inhabited (Encoding Bool) := - ⟨finEncodingBoolBool.toEncoding⟩ +instance inhabitedEncoding : Inhabited (Encoding Bool Bool) := + ⟨encodingBoolBool⟩ -theorem Encoding.card_le_card_list {α : Type u} (e : Encoding.{u, v} α) : - Cardinal.lift.{v} #α ≤ Cardinal.lift.{u} #(List e.Γ) := +theorem Encoding.card_le_card_list {α : Type u} {Γ : Type v} (e : Encoding α Γ) : + Cardinal.lift.{v} #α ≤ Cardinal.lift.{u} #(List Γ) := Cardinal.lift_mk_le'.2 ⟨⟨e.encode, e.encode_injective⟩⟩ -theorem Encoding.card_le_aleph0 {α : Type u} (e : Encoding.{u, v} α) [Countable e.Γ] : +theorem Encoding.card_le_aleph0 {α Γ} (e : Encoding α Γ) [Countable Γ] : #α ≤ ℵ₀ := haveI : Countable α := e.encode_injective.countable Cardinal.mk_le_aleph0 -theorem FinEncoding.card_le_aleph0 {α : Type u} (e : FinEncoding α) : #α ≤ ℵ₀ := - e.toEncoding.card_le_aleph0 - -/-- A `FinEncoding` of a `List α` in (finite) alphabet `α`, encoded directly. -/ -def finEncodingList (α : Type) [Fintype α] : FinEncoding (List α) where - Γ := α +/-- An `Encoding` of a `List α` in alphabet `α`, encoded directly. -/ +def encodingList (α : Type) : Encoding (List α) α where encode := id decode := Option.some decode_encode _ := rfl - ΓFin := inferInstance /-- -Given `FinEncoding` of `α` and `β`, -constructs a `FinEncoding` of `α × β` by concatenating the encodings, +Given an `Encoding` of `α` and `β`, +constructs an `Encoding` of `α × β` by concatenating the encodings, mapping the symbols from the first encoding with `Sum.inl` and those from the second with `Sum.inr`. -/ -def finEncodingPair {α β : Type*} (ea : FinEncoding α) (eb : FinEncoding β) : - FinEncoding (α × β) where - Γ := ea.Γ ⊕ eb.Γ +def encodingProd {α β Γ₁ Γ₂ : Type*} (ea : Encoding α Γ₁) (eb : Encoding β Γ₂) : + Encoding (α × β) (Γ₁ ⊕ Γ₂) where encode x := (ea.encode x.1).map .inl ++ (eb.encode x.2).map .inr decode x := Option.map₂ Prod.mk (ea.decode (x.filterMap Sum.getLeft?)) (eb.decode (x.filterMap Sum.getRight?)) decode_encode x := by simp - ΓFin := inferInstance + +/-! ### Deprecated aliases for `FinEncoding` and unbundled `Γ` -/ + +/-- Deprecated: Use `Encoding α Γ` along with `[Fintype Γ]` instead. -/ +@[reducible, nolint unusedArguments, + deprecated "Use `Encoding α Γ` along with `[Fintype Γ]` instead" (since := "2026-05-07")] +def FinEncoding (α : Type u) {Γ : Type v} [Fintype Γ] := Encoding α Γ + +/-- Deprecated: `Γ` is now an explicit parameter of `Encoding`. -/ +@[reducible, nolint unusedArguments, + deprecated "Γ is now an explicit parameter of `Encoding`" (since := "2026-05-07")] +def Encoding.Γ {α : Type u} {Γ : Type v} (_ : Encoding α Γ) : Type v := Γ + +/-- Deprecated: Use `inferInstanceAs (Fintype Γ)` instead. -/ +@[reducible, nolint unusedArguments, + deprecated "Use `inferInstanceAs (Fintype Γ)` instead" (since := "2026-05-07")] +def FinEncoding.ΓFin {α : Type u} {Γ : Type v} [h : Fintype Γ] + (_ : Encoding α Γ) : Fintype Γ := h + +/-- Deprecated: Use the encoding directly. -/ +@[reducible, nolint unusedArguments, + deprecated "Use the encoding directly" (since := "2026-05-07")] +def FinEncoding.toEncoding {α : Type u} {Γ : Type v} [Fintype Γ] + (e : Encoding α Γ) : Encoding α Γ := e + +/-- Deprecated alias for `encodingNatBool`. -/ +@[deprecated encodingNatBool (since := "2026-05-07")] +abbrev finEncodingNatBool := encodingNatBool + +/-- Deprecated alias for `encodingNatΓ'`. -/ +@[deprecated encodingNatΓ' (since := "2026-05-07")] +abbrev finEncodingNatΓ' := encodingNatΓ' + +/-- Deprecated alias for `unaryEncodingNat`. -/ +@[deprecated unaryEncodingNat (since := "2026-05-07")] +abbrev unaryFinEncodingNat := unaryEncodingNat + +/-- Deprecated alias for `encodingBoolBool`. -/ +@[deprecated encodingBoolBool (since := "2026-05-07")] +abbrev finEncodingBoolBool := encodingBoolBool + +/-- Deprecated alias for `encodingList`. -/ +@[reducible, nolint unusedArguments, + deprecated encodingList (since := "2026-05-07")] +def finEncodingList (α : Type) [Fintype α] := encodingList α + +/-- Deprecated alias for `encodingProd`. -/ +@[reducible, nolint unusedArguments, + deprecated encodingProd (since := "2026-05-07")] +def finEncodingPair {α β Γ₁ Γ₂ : Type*} [Fintype Γ₁] [Fintype Γ₂] + (ea : Encoding α Γ₁) (eb : Encoding β Γ₂) := + encodingProd ea eb + +/-- Deprecated alias for `Encoding.card_le_aleph0`. -/ +@[deprecated Encoding.card_le_aleph0 (since := "2026-05-07")] +theorem FinEncoding.card_le_aleph0 {α Γ} [Countable Γ] (e : Encoding α Γ) : #α ≤ ℵ₀ := + e.card_le_aleph0 end Computability diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index 13dcf2aa6d7aa3..9be97dac9e4207 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -93,8 +93,7 @@ theorem listDecode_encode_list (l : List (L.Term α)) : /-- An encoding of terms as lists. -/ @[simps] -protected def encoding : Encoding (L.Term α) where - Γ := α ⊕ (Σ i, L.Functions i) +protected def encoding : Encoding (L.Term α) (α ⊕ (Σ i, L.Functions i)) where encode := listEncode decode l := (listDecode l).head?.join decode_encode t := by @@ -275,8 +274,8 @@ theorem listDecode_encode_list (l : List (Σ n, L.BoundedFormula α n)) : /-- An encoding of bounded formulas as lists. -/ @[simps] -protected def encoding : Encoding (Σ n, L.BoundedFormula α n) where - Γ := (Σ k, L.Term (α ⊕ Fin k)) ⊕ ((Σ n, L.Relations n) ⊕ ℕ) +protected def encoding : Encoding (Σ n, L.BoundedFormula α n) + ((Σ k, L.Term (α ⊕ Fin k)) ⊕ ((Σ n, L.Relations n) ⊕ ℕ)) where encode φ := φ.2.listEncode decode l := (listDecode l)[0]? decode_encode φ := by @@ -292,8 +291,7 @@ theorem listEncode_sigma_injective : theorem card_le : #(Σ n, L.BoundedFormula α n) ≤ max ℵ₀ (Cardinal.lift.{max u v} #α + Cardinal.lift.{u'} L.card) := by refine lift_le.1 (BoundedFormula.encoding.card_le_card_list.trans ?_) - rw [encoding_Γ, mk_list_eq_max_mk_aleph0, lift_max, lift_aleph0, lift_max, lift_aleph0, - max_le_iff] + rw [mk_list_eq_max_mk_aleph0, lift_max, lift_aleph0, lift_max, lift_aleph0, max_le_iff] refine ⟨?_, le_max_left _ _⟩ rw [mk_sum, Term.card_sigma, mk_sum, ← add_eq_max le_rfl, mk_sum, mk_nat] simp only [lift_add, lift_lift, lift_aleph0] From e70da6c7d2830933c43e546621fc6533ff1ea903 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:12 +0000 Subject: [PATCH 0475/1300] chore(NumberTheory/RamificationInertia/Galois): remove hypotheses from `ncard_primesOver_mul_ncard_primesOver` (#40638) This PR removes many hypotheses from `ncard_primesOver_mul_ncard_primesOver` by giving a direct proof from transitivity of the Galois action rather than via the ramification-inertia formula. Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 6 ++ .../NumberField/Cyclotomic/Ideal.lean | 2 +- .../RamificationInertia/Galois.lean | 58 +++++++++++-------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index f560e44b014c81..e0dfc49e91897b 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -474,6 +474,12 @@ theorem restrictHom_surjective [Finite G] [Finite G'] [MulSemiringAction G C] Function.Surjective (restrictHom G G' A B C) := by simpa [restrictHom] using QuotientGroup.mk_surjective +open Pointwise in +theorem restrictHom_smul_under [Finite G] [Finite G'] [MulSemiringAction G C] + [IsGaloisGroup G A C] [MulSemiringAction G' B] [IsGaloisGroup G' A B] (g : G) (I : Ideal C) : + restrictHom G G' A B C g • I.under B = (g • I).under B := by + simp [Ideal.ext_iff, Ideal.mem_pointwise_smul_iff_inv_smul_mem, ← map_inv] + end Domain noncomputable section IntermediateField diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 2d590f3a66b38d..5f78d15ce9efbb 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -401,7 +401,7 @@ private theorem inertiaDegIn_ramificationIdxIn_aux (hn : n = p ^ (k + 1) * m) (h ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 Fₘ) Gal(Fₘ/ℚ), ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 Fₚ) Gal(Fₚ/ℚ), ← ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝒑 (𝓞 K) Gal(K/ℚ), - ← ncard_primesOver_mul_ncard_primesOver Pₘ Gal(Fₘ/ℚ) (𝓞 K) Gal(K/ℚ) Gal(K/Fₘ), + ← ncard_primesOver_mul_ncard_primesOver Pₘ Gal(Fₘ/ℚ) (𝓞 K) Gal(K/ℚ), ramificationIdxIn_eq_of_not_dvd p Fₘ hm, inertiaDegIn_eq_of_prime_pow p k Fₚ, ncard_primesOver_of_prime_pow p k Fₚ, one_mul, one_mul, mul_one, mul_assoc, mul_assoc, mul_right_inj' (IsDedekindDomain.primesOver_ncard_ne_zero 𝒑 _), ← mul_assoc, diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index bc63cb37041191..467b607a9f0cca 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -232,37 +232,45 @@ end fundamental_identity section tower -variable {A B : Type*} [CommRing A] [IsDomain A] [CommRing B] [IsDomain B] - [Algebra A B] [Flat A B] {p : Ideal A} (P : Ideal B) [p.IsPrime] +variable {A B : Type*} [CommRing A] [CommRing B] + [Algebra A B] [FaithfulSMul A B] {p : Ideal A} (P : Ideal B) [P.IsPrime] [P.LiesOver p] (G : Type*) [Group G] [Finite G] [MulSemiringAction G B] [IsGaloisGroup G A B] (C : Type*) [CommRing C] [IsDomain C] [Algebra A C] - [Algebra B C] [Module.Finite A B] [Module.Finite A C] [Module.Finite B C] [Flat A C] - [Flat B C] [IsScalarTower A B C] + [Algebra B C] [FaithfulSMul B C] [IsScalarTower A B C] (GAC : Type*) [Group GAC] [Finite GAC] [MulSemiringAction GAC C] [IsGaloisGroup GAC A C] - (GBC : Type*) [Group GBC] [Finite GBC] [MulSemiringAction GBC C] [IsGaloisGroup GBC B C] --- todo: use transitivity to prove this under much weaker assumptions -include G GAC GBC in +include G GAC in +open IsGaloisGroup MulAction in theorem ncard_primesOver_mul_ncard_primesOver : (p.primesOver B).ncard * (P.primesOver C).ncard = (p.primesOver C).ncard := by - let := IsFractionRing.mulSemiringAction G B (FractionRing B) - let := IsFractionRing.mulSemiringAction GAC C (FractionRing C) - let := IsFractionRing.mulSemiringAction GBC C (FractionRing C) - have : p.ramificationIdxIn C * p.inertiaDegIn C ≠ 0 := - mul_ne_zero (ramificationIdxIn_ne_zero GAC) (inertiaDegIn_ne_zero GAC) - rw [← Nat.mul_left_inj this, ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p C GAC] - calc - _ = ((p.primesOver B).ncard * (p.ramificationIdxIn B * p.inertiaDegIn B)) * - ((P.primesOver C).ncard * (P.ramificationIdxIn C * P.inertiaDegIn C)) := by - rw [← inertiaDegIn_mul_inertiaDegIn p P G C GAC GBC, - ← ramificationIdxIn_mul_ramificationIdxIn P G C GAC GBC] - ring - _ = Nat.card GAC := by - rw [ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p B G, - ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn P C GBC, - (IsGaloisGroup.toFractionRing G A B).card_eq_finrank, - (IsGaloisGroup.toFractionRing GAC A C).card_eq_finrank, - (IsGaloisGroup.toFractionRing GBC B C).card_eq_finrank, Module.finrank_mul_finrank] + have : Algebra.IsIntegral A C := isInvariant.isIntegral A C GAC + have : Algebra.IsIntegral B C := Algebra.IsIntegral.tower_top A + let f := restrictHom GAC G A B C + let H := (stabilizer G P).comap f + have key (Q Q' : Ideal C) [Q.LiesOver P] [Q'.LiesOver P] g (hg : g • Q = Q') : g ∈ H := by + simpa [← restrictHom_smul_under GAC G A, ← over_def _ P, H] using congr_arg (under B) hg + obtain ⟨Q, _, _⟩ := (inferInstance : Nonempty (P.primesOver C)) + have : Q.LiesOver p := .trans Q P p + have orbit_eq : orbit H Q = P.primesOver C := by + ext Q' + constructor + · rintro ⟨g, rfl : g • Q = Q'⟩ + refine ⟨inferInstance, ?_⟩ + rw [liesOver_iff, H.smul_def, ← restrictHom_smul_under GAC G A B C, ← Q.over_def P] + exact g.2.symm + · rintro ⟨_, _⟩ + have : Q'.LiesOver p := .trans Q' P p + obtain ⟨g, hg⟩ := + IsInvariant.exists_smul_of_under_eq A C GAC Q Q' ((Q.over_def p).symm.trans (Q'.over_def p)) + exact ⟨⟨g, key Q Q' g hg.symm⟩, by simpa [Subgroup.smul_def] using hg.symm⟩ + have stabilizer_eq : stabilizer H Q = (stabilizer GAC Q).subgroupOf H := by + simp [Subgroup.ext_iff, Subgroup.mem_subgroupOf] + rw [← IsInvariant.orbit_eq_primesOver A B G p P, ← index_stabilizer, + ← orbit_eq, ← index_stabilizer, stabilizer_eq, ← Subgroup.relIndex, + ← IsInvariant.orbit_eq_primesOver A C GAC p Q, ← index_stabilizer, + ← (stabilizer G P).index_comap_of_surjective (restrictHom_surjective GAC G A B C), + mul_comm, Subgroup.relIndex_mul_index] + exact key Q Q end tower From 09d0fe8689fb514b4c4f180780b9448c4befe664 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:15 +0000 Subject: [PATCH 0476/1300] chore(Algebra/Algebra/Tower): upgrade `extendScalarsOfSurjective` to an equiv (#40913) This PR upgrades `AlgHom.extendScalarsOfSurjective` and `AlgEquiv.extendScalarsOfSurjective` to `Equiv`s and adds `MulEquiv` versions. Co-authored-by: tb65536 --- Mathlib/Algebra/Algebra/Tower.lean | 43 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Tower.lean b/Mathlib/Algebra/Algebra/Tower.lean index 16847ed505be3f..464f3228d15a2c 100644 --- a/Mathlib/Algebra/Algebra/Tower.lean +++ b/Mathlib/Algebra/Algebra/Tower.lean @@ -204,19 +204,27 @@ section variable {R} -/-- Any `f : A →ₐ[R] B` is also an `R ⧸ I`-algebra homomorphism if the `R`-algebra structure on -`A` and `B` factors via `R ⧸ I`. -/ -@[simps! apply] -def extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) - (f : A →ₐ[R] B) : A →ₐ[S] B where - toRingHom := f - commutes' := by simp [h.forall, ← IsScalarTower.algebraMap_apply] +/-- Any `f : A →ₐ[R] B` is also an `S`-algebra homomorphism if the `R`-algebra structure on +`A` and `B` factors via a surjective ring homomorphism `R →+* S`. -/ +@[simps! apply symm_apply] +def extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) : + (A →ₐ[R] B) ≃ (A →ₐ[S] B) where + toFun f := { f with commutes' := by simp [h.forall, ← IsScalarTower.algebraMap_apply] } + invFun := restrictScalars R @[simp] lemma restrictScalars_extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) (f : A →ₐ[R] B) : (f.extendScalarsOfSurjective h).restrictScalars R = f := rfl +/-- Any `f : A →ₐ[R] B` is also an `S`-algebra homomorphism if the `R`-algebra structure on +`A` and `B` factors via a surjective ring homomorphism `R →+* S`. -/ +@[simps! apply symm_apply] +def extendScalarsHomOfSurjective (h : Function.Surjective (algebraMap R S)) : + (A →ₐ[R] A) ≃* (A →ₐ[S] A) where + __ := extendScalarsOfSurjective h + map_mul' _ _ := rfl + end end AlgHom @@ -263,12 +271,13 @@ section variable {R} -/-- Any `f : A ≃ₐ[R] B` is also an `R ⧸ I`-algebra isomorphism if the `R`-algebra structure on -`A` and `B` factors via `R ⧸ I`. -/ -def extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) - (f : A ≃ₐ[R] B) : A ≃ₐ[S] B where - toRingEquiv := f - commutes' := (f.toAlgHom.extendScalarsOfSurjective h).commutes' +/-- Any `f : A ≃ₐ[R] B` is also an `S`-algebra isomorphism if the `R`-algebra structure on +`A` and `B` factors via a surjective ring homomorphism `R →+* S`. -/ +@[simps! apply symm_apply] +def extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) : + (A ≃ₐ[R] B) ≃ A ≃ₐ[S] B where + toFun f := { f with commutes' := (f.toAlgHom.extendScalarsOfSurjective h).commutes' } + invFun := AlgEquiv.restrictScalars R @[simp] lemma coe_extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) (f : A ≃ₐ[R] B) : ⇑(extendScalarsOfSurjective h f) = f := rfl @@ -283,6 +292,14 @@ lemma extendScalarsOfSurjective_symm (h : Function.Surjective (algebraMap R S)) (f : A ≃ₐ[R] B) : (f.extendScalarsOfSurjective h).symm = f.symm.extendScalarsOfSurjective h := rfl +/-- Any `f : A ≃ₐ[R] B` is also an `S`-algebra isomorphism if the `R`-algebra structure on +`A` and `B` factors via a surjective ring homomorphism `R →+* S`. -/ +@[simps! apply symm_apply] +def extendScalarsHomOfSurjective (h : Function.Surjective ⇑(algebraMap R S)) : + (A ≃ₐ[R] A) ≃* (A ≃ₐ[S] A) where + __ := extendScalarsOfSurjective h + map_mul' _ _ := rfl + end end AlgEquiv From 23fb79f18e356271f602be25f50cfb03ca3203bc Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:17 +0000 Subject: [PATCH 0477/1300] chore(FieldTheory/Galois/IsGaloisGroup): remove redundant `have` statements (#40954) Now that `isScalarTower_mulSemiringActionQuotient` is an instance, we can remove a few redundant `have` statements. Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index e0dfc49e91897b..718a1f72439570 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -492,7 +492,6 @@ instance [Finite G] [IsGaloisGroup G K L] : IsGaloisGroup (G ⧸ N) K F := letI := smulOfNormal G F L N haveI := smulDistribClass_smulOfNormal G F L N letI := mulSemiringActionOfSmulDistribClass F L G - haveI := isScalarTower_mulSemiringActionQuotient G F L N quotient G K F L N variable (E : IntermediateField K L) [hE : IsGaloisGroup H E L] @@ -508,7 +507,6 @@ theorem map_quotientMk' [Finite G] [IsGaloisGroup G K L] (h : E ≤ F) : have : SMulDistribClass G F L := smulDistribClass_smulOfNormal G F L N let := mulSemiringActionOfSmulDistribClass F L G have : IsScalarTower E F L := IsScalarTower.of_algebraMap_eq' rfl - have := isScalarTower_mulSemiringActionQuotient G F L N { faithful := have := (inferInstance : IsGaloisGroup (G ⧸ N) K F).faithful; inferInstance commutes := ⟨by intro ⟨_, g, hg, rfl⟩ x y From 7d6ecd37d61e8612ce94b29ea58cd3b3d8e7ce47 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:21 +0000 Subject: [PATCH 0478/1300] refactor(RepresentationTheory/Rep/Res): refactor resFunctor (#41054) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR refactors the definition of `resFunctor`, in the current master since the whole definition is an `abbrev`, everything is exposed and if one does `ext; simp` one of the possible outcome in the infoview would be ``` ofHom { toLinearMap := (Hom.hom ..).toLinearMap, isIntertwining' := ⋯ } ``` which is not helpful unfolds too much, this PR seals the `map` part of the functor to make it less transparent while keep the definition of `resFunctor` as an `abbrev` to maintain the full transparency on the underlying type. --- .../GroupCohomology/Functoriality.lean | 2 +- .../GroupHomology/Functoriality.lean | 4 +- Mathlib/RepresentationTheory/Induced.lean | 3 +- Mathlib/RepresentationTheory/Invariants.lean | 2 +- Mathlib/RepresentationTheory/Rep/Res.lean | 40 +++++++++++-------- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean index a4845a06718d8c..f7db8e10cb5783 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean @@ -551,7 +551,7 @@ noncomputable def resNatTrans (n : ℕ) : simp only [functor_map, Functor.comp_map, ← cancel_epi (groupCohomology.π _ n), HomologicalComplex.homologyπ_naturality_assoc, HomologicalComplex.homologyπ_naturality, ← HomologicalComplex.cyclesMap_comp_assoc, - ← cochainsMap_comp, res_obj_ρ, Category.comp_id, Rep.hom_id] + ← cochainsMap_comp, res_obj_ρ, Category.comp_id] rfl set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean index f63037ce882e3d..7367d9ff4f49ff 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean @@ -853,11 +853,9 @@ noncomputable def coresNatTrans (n : ℕ) : simp only [← cancel_epi (groupHomology.π _ n), Functor.comp_map, functor_map, HomologicalComplex.homologyπ_naturality_assoc, HomologicalComplex.homologyπ_naturality, ← HomologicalComplex.cyclesMap_comp_assoc, - ← chainsMap_comp, res_obj_ρ, Rep.hom_id, Category.id_comp] + ← chainsMap_comp, Category.id_comp] rfl - - set_option backward.isDefEq.respectTransparency false in /-- Given a normal subgroup `S ≤ G`, this sends `A : Rep k G` to the `n`th "coinflation" map `Hₙ(G, A) ⟶ Hₙ(G ⧸ S, A_S)` induced by the quotient maps `G →* G ⧸ S` and `A →ₗ A_S`. -/ diff --git a/Mathlib/RepresentationTheory/Induced.lean b/Mathlib/RepresentationTheory/Induced.lean index 2645fae382cf50..c7bfc7fafff3a5 100644 --- a/Mathlib/RepresentationTheory/Induced.lean +++ b/Mathlib/RepresentationTheory/Induced.lean @@ -260,8 +260,7 @@ noncomputable def coinvariantsTensorIndNatIso : (coinvariantsTensor k H).obj (ind φ A) ≅ resFunctor φ ⋙ (coinvariantsTensor k G).obj A := NatIso.ofComponents (fun B => coinvariantsTensorIndIso φ A B) fun {X Y} f => by ext - simp [coinvariantsTensorIndHom, coinvariantsTensorMk, - hom_comm_apply, Representation.IntertwiningMap.toLinearMap_apply] + simp [coinvariantsTensorIndHom, coinvariantsTensorMk, hom_comm_apply] end end Rep diff --git a/Mathlib/RepresentationTheory/Invariants.lean b/Mathlib/RepresentationTheory/Invariants.lean index 33aa95d7e1c96f..e78c870f3f9f46 100644 --- a/Mathlib/RepresentationTheory/Invariants.lean +++ b/Mathlib/RepresentationTheory/Invariants.lean @@ -265,7 +265,7 @@ noncomputable def quotientToInvariantsFunctor (S : Subgroup G) [S.Normal] : Rep.{w} k G ⥤ Rep k (G ⧸ S) where obj X := X.quotientToInvariants S map {X Y} f := Rep.ofHom ⟨((invariantsFunctor k S).map ((Rep.resFunctor S.subtype).map f)).hom, - fun g ↦ QuotientGroup.induction_on g fun g ↦ by ext x; simp [hom_comm_apply]⟩ + fun g ↦ QuotientGroup.induction_on g fun g ↦ by ext; simp [hom_comm_apply]⟩ set_option backward.isDefEq.respectTransparency false in /-- The adjunction between the functor equipping a module with the trivial representation, and diff --git a/Mathlib/RepresentationTheory/Rep/Res.lean b/Mathlib/RepresentationTheory/Rep/Res.lean index 5ccc77a7f66c4e..387fa047a261c6 100644 --- a/Mathlib/RepresentationTheory/Rep/Res.lean +++ b/Mathlib/RepresentationTheory/Rep/Res.lean @@ -25,10 +25,17 @@ open CategoryTheory namespace Rep +/-- The map induced by a monoid homomorphism `f : H →* G` on morphisms between +`G`-representations. -/ +@[expose, implicit_reducible] +def resMap {X Y : Rep k G} (f : H →* G) (p : X ⟶ Y) : + of (X := X.V) (X.ρ.comp f) ⟶ of (X := Y.V) (Y.ρ.comp f) := + ofHom ⟨p.hom, fun h ↦ by simpa using p.hom.2 (f h)⟩ + /-- The restriction functor `Rep R G ⥤ Rep R H` for a subgroup `H` of `G`. -/ abbrev resFunctor (f : H →* G) : Rep.{t} k G ⥤ Rep k H where obj A := of (X := A.V) (A.ρ.comp f) - map f' := ofHom ⟨f'.hom, fun h ↦ by simpa using f'.hom.2 (f h)⟩ + map f' := resMap f f' /-- The restriction of `X : Rep k G` associated to a monoid homomorphism `f : H →* G` -/ abbrev res (f : H →* G) (M : Rep k G) := (resFunctor f).obj M @@ -43,16 +50,23 @@ lemma coe_res_obj_ρ' (h : H) : (res f M).ρ h = M.ρ (f h) := rfl lemma res_obj_V : (res f M).V = M.V := rfl -lemma res_map_hom_toLinearMap {M N : Rep k G} (p : M ⟶ N) : - ((resFunctor f).map p).hom.toLinearMap = p.hom.toLinearMap := rfl +@[simp] +lemma resMap_hom_toLinearMap {M N : Rep k G} (p : M ⟶ N) : + (resMap f p).hom.toLinearMap = p.hom.toLinearMap := rfl + +@[deprecated (since := "26/06/2026")] +alias res_map_hom_toLinearMap := resMap_hom_toLinearMap + +@[simp] +lemma resMap_hom_apply {M N : Rep k G} (p : M ⟶ N) (x : M.V) : + @DFunLike.coe (Representation.IntertwiningMap (M.ρ.comp f) (N.ρ.comp f)) _ _ _ + (resMap f p).hom x = p.hom x := rfl section instance : (resFunctor (k := k) f).Faithful where map_injective h := by - ext : 2 - rw [Rep.hom_ext_iff, Representation.IntertwiningMap.ext_iff] at h - simpa using h + simpa [Rep.hom_ext_iff, Representation.IntertwiningMap.ext_iff] using h /-- Morphism between `X Y : Rep k G` can be lifted from restrictions associated with `f : H →* G` when `f` is surjective. -/ @@ -65,21 +79,13 @@ lemma liftHomOfSurj_toLinearMap {X Y : Rep k G} (hf : Function.Surjective f) f'.hom.toLinearMap := rfl lemma full_res (hf : (⇑f).Surjective) : (resFunctor (k := k) f).Full where - map_surjective {X Y} f' := ⟨liftHomOfSurj f hf f', by - ext : 2; rw [res_map_hom_toLinearMap, liftHomOfSurj_toLinearMap]⟩ + map_surjective {X Y} f' := ⟨liftHomOfSurj f hf f', by ext; simp⟩ instance : (resFunctor (k := k) f).Additive where - map_add {_ _} _ _ := by - ext : 2; - simp only [add_hom, Representation.IntertwiningMap.add_toLinearMap] - rfl + map_add {_ _} _ _ := by ext : 2; simp [add_hom] instance {k : Type u} [CommSemiring k] : (resFunctor (k := k) f).Linear k where - map_smul {X Y} l r := by - ext : 2; - rw [smul_hom, Representation.IntertwiningMap.toLinearMap_smul, - res_map_hom_toLinearMap, smul_hom, Representation.IntertwiningMap.toLinearMap_smul, - res_map_hom_toLinearMap] + map_smul {_ _} _ _ := by ext : 2; simp [smul_hom] noncomputable section From ebc5666ed6f8a7d6b8ce7930d7206407e572be13 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:24 +0000 Subject: [PATCH 0479/1300] chore(Algebra/Polynomial/Splits): remove field hypothesis from `map_aroots_algebraMap` (#41056) Currently `Polynomial.Splits.map_aroots_algebraMap` assumes that `A` is a field. But actually it is enough to assume that the map from `A` to `B` is injective. This PR also adds a `rootSet` version `Polynomial.Splits.image_rootSet_algebraMap`. Co-authored-by: tb65536 --- Mathlib/Algebra/Polynomial/Splits.lean | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index ffdd56c46e4e78..8035ef9225714b 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -572,11 +572,6 @@ section variable {A B : Type*} [CommRing R] [Field A] [Algebra R A] [CommRing B] [IsDomain B] [Algebra R B] {f : R[X]} -theorem Splits.map_aroots_algebraMap [Algebra A B] [IsScalarTower R A B] - (hf : (f.map (algebraMap R A)).Splits) : - (f.aroots A).map (algebraMap A B) = f.aroots B := by - rw [← aroots_map B A, aroots, aroots, hf.roots_map] - theorem Splits.image_rootSet (hf : (f.map (algebraMap R A)).Splits) (g : A →ₐ[R] B) : g '' f.rootSet A = f.rootSet B := by classical @@ -591,6 +586,23 @@ theorem Splits.adjoin_rootSet_eq_range end +section + +variable {A B : Type*} [CommRing R] [CommRing A] [IsDomain A] [Algebra R A] [CommRing B] + [IsDomain B] [Algebra R B] [Algebra A B] [FaithfulSMul A B] [IsScalarTower R A B] {f : R[X]} + +theorem Splits.map_aroots_algebraMap (hf : (f.map (algebraMap R A)).Splits) : + (f.aroots A).map (algebraMap A B) = f.aroots B := by + rw [← aroots_map B A, aroots, aroots, + hf.roots_map_of_injective (FaithfulSMul.algebraMap_injective A B)] + +theorem Splits.image_rootSet_algebraMap (hf : (f.map (algebraMap R A)).Splits) : + (algebraMap A B) '' f.rootSet A = f.rootSet B := by + classical + rw [rootSet, ← Finset.coe_image, ← Multiset.toFinset_map, hf.map_aroots_algebraMap, ← rootSet] + +end + variable [Field R] {f g : R[X]} theorem Splits.dvd_of_roots_le_roots (hp : f.Splits) (hp0 : f ≠ 0) (hq : f.roots ≤ g.roots) : From 59a563a14480b87bbc2c5b782e2dda8d21f6d5e6 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:51:27 +0000 Subject: [PATCH 0480/1300] chore(NumberTheory/*): remove last `ramificationIdx_eq_ramificationIdx'` (#41196) This PR removes the last occurrences of `ramificationIdx_eq_ramificationIdx'`. Co-authored-by: tb65536 --- .../NumberField/Cyclotomic/Ideal.lean | 5 ++--- .../RamificationInertia/HilbertTheory.lean | 4 +--- .../RamificationInertia/Ramification.lean | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 5f78d15ce9efbb..92659de900efb3 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -126,9 +126,8 @@ theorem ramificationIdx_span_zeta_sub_one : ramificationIdx' (span {hζ.toInteger - 1}) ℤ = p ^ k * (p - 1) := by have h := isPrime_span_zeta_sub_one p k hζ have hp0 : 𝒑 ≠ ⊥ := by simpa using hp.out.ne_zero - rw [← ramificationIdx_eq_ramificationIdx' 𝒑 _ hp0, - ← Nat.totient_prime_pow_succ hp.out, ← finrank _ K, - IsDedekindDomain.ramificationIdx_eq_multiplicity _ h, map_eq_span_zeta_sub_one_pow p k hζ, + rw [← Nat.totient_prime_pow_succ hp.out, ← finrank _ K, + IsDedekindDomain.ramificationIdx'_eq_multiplicity 𝒑, map_eq_span_zeta_sub_one_pow p k hζ, multiplicity_pow_self (span_zeta_sub_one_ne_bot p k hζ) (isUnit_iff.not.mpr h.ne_top)] exact map_ne_bot_of_ne_bot hp0 diff --git a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean index d5378c4a94dcc3..70c772f8186510 100644 --- a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean +++ b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean @@ -294,9 +294,7 @@ private lemma ramificationIdxIn_eq_and_inertiaDegIn_eq (hp : p ≠ ⊥) : · exact Nat.pos_of_ne_zero <| inertiaDegIn_ne_zero (stabilizer Gal(L/K) P) · rw [ramificationIdxIn_eq_ramificationIdx p P Gal(L/K), ramificationIdxIn_eq_ramificationIdx _ P (stabilizer Gal(L/K) P)] - rw [← ramificationIdx_eq_ramificationIdx' p _ hp, - ← ramificationIdx_eq_ramificationIdx' 𝓟D _ h𝓟] - exact IsDedekindDomain.ramificationIdx_le_ramificationIdx _ _ _ hp + exact 𝓟D.ramificationIdx'_above_le P · rw [inertiaDegIn_eq_inertiaDeg p P Gal(L/K), inertiaDegIn_eq_inertiaDeg _ P (stabilizer Gal(L/K) P)] rw [← inertiaDeg_eq_inertiaDeg' p, ← inertiaDeg_eq_inertiaDeg' 𝓟D] diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index 4cfbeea36fe3c7..a905864ef3e591 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -201,6 +201,24 @@ theorem ramificationIdx'_tower [r.LiesOver q] [Module.Flat S T] : apply ramificationIdx'_tower' · rw [ramificationIdx'_of_not_isPrime r R hr, ramificationIdx'_of_not_isPrime r S hr, mul_zero] +theorem ramificationIdx'_below_dvd [r.LiesOver q] [Module.Flat S T] : + q.ramificationIdx' R ∣ r.ramificationIdx' R := by + use r.ramificationIdx' S + rw [← ramificationIdx'_tower] + +theorem ramificationIdx'_above_dvd [r.LiesOver q] [Module.Flat S T] : + r.ramificationIdx' S ∣ r.ramificationIdx' R := by + use q.ramificationIdx' R + rw [mul_comm, ← ramificationIdx'_tower] + +theorem ramificationIdx'_below_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] [Module.Flat S T] : + q.ramificationIdx' R ≤ r.ramificationIdx' R := + Nat.le_of_dvd (r.ramificationIdx'_pos R) (q.ramificationIdx'_below_dvd r) + +theorem ramificationIdx'_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] [Module.Flat S T] : + r.ramificationIdx' S ≤ r.ramificationIdx' R := + Nat.le_of_dvd (r.ramificationIdx'_pos R) (q.ramificationIdx'_above_dvd r) + variable (R) in open Pointwise in @[simp] From 40b6a8fca5db9cdc615363950ef879dd02b1dec1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:26:29 +0000 Subject: [PATCH 0481/1300] chore(MathlibTest): move test files for linters into the Linter subdirectory (#40397) This means we can use the auto-labelling mechanism to also suggest appropriate labels for these files. Co-authored-by: Jon Eugster --- Mathlib/Tactic/Linter/Header.lean | 3 ++- MathlibTest/{ => Linter}/DoubleUnderscore.lean | 9 +++++++++ MathlibTest/{Lint.lean => Linter/DupNamespace.lean} | 10 ---------- .../GlobalAttributeIn.lean} | 0 .../HashCommand.lean} | 0 .../{HaveLetLinter.lean => Linter/HaveLet.lean} | 0 MathlibTest/{Header.lean => Linter/Header/Basic.lean} | 0 .../{HeaderFail.lean => Linter/Header/Fail.lean} | 0 .../{VersoHeader.lean => Linter/Header/Verso.lean} | 0 MathlibTest/{ => Linter}/LongFile.lean | 0 MathlibTest/{ => Linter}/Multigoal.lean | 0 MathlibTest/{ => Linter}/UnusedTactic.lean | 0 .../{WhitespaceLinter.lean => Linter/Whitespace.lean} | 0 13 files changed, 11 insertions(+), 11 deletions(-) rename MathlibTest/{ => Linter}/DoubleUnderscore.lean (64%) rename MathlibTest/{Lint.lean => Linter/DupNamespace.lean} (82%) rename MathlibTest/{globalAttributeIn.lean => Linter/GlobalAttributeIn.lean} (100%) rename MathlibTest/{HashCommandLinter.lean => Linter/HashCommand.lean} (100%) rename MathlibTest/{HaveLetLinter.lean => Linter/HaveLet.lean} (100%) rename MathlibTest/{Header.lean => Linter/Header/Basic.lean} (100%) rename MathlibTest/{HeaderFail.lean => Linter/Header/Fail.lean} (100%) rename MathlibTest/{VersoHeader.lean => Linter/Header/Verso.lean} (100%) rename MathlibTest/{ => Linter}/LongFile.lean (100%) rename MathlibTest/{ => Linter}/Multigoal.lean (100%) rename MathlibTest/{ => Linter}/UnusedTactic.lean (100%) rename MathlibTest/{WhitespaceLinter.lean => Linter/Whitespace.lean} (100%) diff --git a/Mathlib/Tactic/Linter/Header.lean b/Mathlib/Tactic/Linter/Header.lean index 73ecfad1d38d45..40b79e7b281843 100644 --- a/Mathlib/Tactic/Linter/Header.lean +++ b/Mathlib/Tactic/Linter/Header.lean @@ -366,7 +366,8 @@ The set of files outside the `Mathlib` package to run the header style linter on because they are files that test the linter. -/ def headerTestFiles : NameSet := .ofList - [`MathlibTest.Header, `MathlibTest.HeaderFail, `MathlibTest.VersoHeader, `MathlibTest.DirectoryDependencyLinter.Test] + [`MathlibTest.Linter.Header.Basic, `MathlibTest.Linter.Header.Fail, `MathlibTest.Linter.Header.Verso, + `MathlibTest.DirectoryDependencyLinter.Test] @[inherit_doc Mathlib.Linter.linter.style.header] def headerLinter : Linter where run := withSetOptionIn fun stx ↦ do diff --git a/MathlibTest/DoubleUnderscore.lean b/MathlibTest/Linter/DoubleUnderscore.lean similarity index 64% rename from MathlibTest/DoubleUnderscore.lean rename to MathlibTest/Linter/DoubleUnderscore.lean index c345d518b3efc5..af1b7edaa42780 100644 --- a/MathlibTest/DoubleUnderscore.lean +++ b/MathlibTest/Linter/DoubleUnderscore.lean @@ -18,3 +18,12 @@ Note: This linter can be disabled with `set_option linter.style.nameCheck false` -/ #guard_msgs in def double__underscore : Unit := () + +/-- +warning: The declaration 'double__underscore'' contains '__', which does not follow the mathlib naming conventions. Consider using single underscores instead. + +Note: This linter can be disabled with `set_option linter.style.nameCheck false` +-/ +#guard_msgs in +set_option linter.style.nameCheck true in +theorem double__underscore' : True := trivial diff --git a/MathlibTest/Lint.lean b/MathlibTest/Linter/DupNamespace.lean similarity index 82% rename from MathlibTest/Lint.lean rename to MathlibTest/Linter/DupNamespace.lean index 391ebca8357334..b5013fb0c8d7c5 100644 --- a/MathlibTest/Lint.lean +++ b/MathlibTest/Linter/DupNamespace.lean @@ -62,13 +62,3 @@ Note: This linter can be disabled with `set_option linter.dupNamespace false` export Nat (add add_comm add) end add - -/-- -warning: The declaration 'double__underscore' contains '__', -which does not follow the mathlib naming conventions. Consider using single underscores instead. - -Note: This linter can be disabled with `set_option linter.style.nameCheck false` --/ -#guard_msgs in -set_option linter.style.nameCheck true in -theorem double__underscore : True := trivial diff --git a/MathlibTest/globalAttributeIn.lean b/MathlibTest/Linter/GlobalAttributeIn.lean similarity index 100% rename from MathlibTest/globalAttributeIn.lean rename to MathlibTest/Linter/GlobalAttributeIn.lean diff --git a/MathlibTest/HashCommandLinter.lean b/MathlibTest/Linter/HashCommand.lean similarity index 100% rename from MathlibTest/HashCommandLinter.lean rename to MathlibTest/Linter/HashCommand.lean diff --git a/MathlibTest/HaveLetLinter.lean b/MathlibTest/Linter/HaveLet.lean similarity index 100% rename from MathlibTest/HaveLetLinter.lean rename to MathlibTest/Linter/HaveLet.lean diff --git a/MathlibTest/Header.lean b/MathlibTest/Linter/Header/Basic.lean similarity index 100% rename from MathlibTest/Header.lean rename to MathlibTest/Linter/Header/Basic.lean diff --git a/MathlibTest/HeaderFail.lean b/MathlibTest/Linter/Header/Fail.lean similarity index 100% rename from MathlibTest/HeaderFail.lean rename to MathlibTest/Linter/Header/Fail.lean diff --git a/MathlibTest/VersoHeader.lean b/MathlibTest/Linter/Header/Verso.lean similarity index 100% rename from MathlibTest/VersoHeader.lean rename to MathlibTest/Linter/Header/Verso.lean diff --git a/MathlibTest/LongFile.lean b/MathlibTest/Linter/LongFile.lean similarity index 100% rename from MathlibTest/LongFile.lean rename to MathlibTest/Linter/LongFile.lean diff --git a/MathlibTest/Multigoal.lean b/MathlibTest/Linter/Multigoal.lean similarity index 100% rename from MathlibTest/Multigoal.lean rename to MathlibTest/Linter/Multigoal.lean diff --git a/MathlibTest/UnusedTactic.lean b/MathlibTest/Linter/UnusedTactic.lean similarity index 100% rename from MathlibTest/UnusedTactic.lean rename to MathlibTest/Linter/UnusedTactic.lean diff --git a/MathlibTest/WhitespaceLinter.lean b/MathlibTest/Linter/Whitespace.lean similarity index 100% rename from MathlibTest/WhitespaceLinter.lean rename to MathlibTest/Linter/Whitespace.lean From 3aa856245edd098a53eada75aca477c9cf9a7e57 Mon Sep 17 00:00:00 2001 From: Xmask19 <43860179+Xmask19@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:26:31 +0000 Subject: [PATCH 0482/1300] feat: add TendstoCofinite lemma for polynomial functions (#40807) Add `Polynomial.tendstoCofinite_of_natDegree_ne_zero`, which states that a non-constant (univariate) polynomial over a domain has finite fibres. Co-authored-by: Bhavik Mehta Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib/Algebra/Polynomial/Degree/Defs.lean | 10 +++++----- Mathlib/Algebra/Polynomial/Roots.lean | 10 ++++++++++ Mathlib/RingTheory/PowerBasis.lean | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Degree/Defs.lean b/Mathlib/Algebra/Polynomial/Degree/Defs.lean index 2baa8b38271173..3119fcb7074168 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Defs.lean @@ -73,11 +73,11 @@ theorem Monic.leadingCoeff {p : R[X]} (hp : p.Monic) : leadingCoeff p = 1 := theorem Monic.coeff_natDegree {p : R[X]} (hp : p.Monic) : p.coeff p.natDegree = 1 := hp -@[simp] +@[simp, grind =] theorem degree_zero : degree (0 : R[X]) = ⊥ := rfl -@[simp] +@[simp, grind =] theorem natDegree_zero : natDegree (0 : R[X]) = 0 := rfl @@ -161,18 +161,18 @@ theorem degree_C_lt : degree (C a) < 1 := theorem degree_one_le : degree (1 : R[X]) ≤ (0 : WithBot ℕ) := by rw [← C_1]; exact degree_C_le -@[simp] +@[simp, grind =] theorem natDegree_C (a : R) : natDegree (C a) = 0 := by by_cases ha : a = 0 · have : C a = 0 := by rw [ha, C_0] rw [natDegree, degree_eq_bot.2 this, WithBot.unbotD_bot] · rw [natDegree, degree_C ha, WithBot.unbotD_zero] -@[simp] +@[simp, grind =] theorem natDegree_one : natDegree (1 : R[X]) = 0 := natDegree_C 1 -@[simp] +@[simp, grind =] theorem natDegree_natCast (n : ℕ) : natDegree (n : R[X]) = 0 := by simp only [← C_eq_natCast, natDegree_C] diff --git a/Mathlib/Algebra/Polynomial/Roots.lean b/Mathlib/Algebra/Polynomial/Roots.lean index af24b26f063b34..c55613f8ce6cd2 100644 --- a/Mathlib/Algebra/Polynomial/Roots.lean +++ b/Mathlib/Algebra/Polynomial/Roots.lean @@ -12,6 +12,7 @@ public import Mathlib.Data.Set.Finite.Lemmas public import Mathlib.RingTheory.Coprime.Lemmas public import Mathlib.RingTheory.Localization.FractionRing public import Mathlib.SetTheory.Cardinal.Order +public import Mathlib.Order.Filter.TendstoCofinite /-! # Theory of univariate polynomials @@ -157,6 +158,15 @@ theorem eq_of_infinite_eval_eq (p q : R[X]) (h : Set.Infinite { x | eval x p = e apply eq_zero_of_infinite_isRoot simpa only [IsRoot, eval_sub, sub_eq_zero] +/-- Non-constant polynomials have finite fibres, provided the coefficients are a domain. -/ +lemma tendstoCofinite_of_natDegree_ne_zero {R : Type} [CommRing R] [IsDomain R] (p : R[X]) + (hp : p.natDegree ≠ 0) : Filter.TendstoCofinite p.eval := by + rw [Filter.tendstoCofinite_iff_finite_preimage_singleton] + intro x + by_contra! hx + obtain ⟨rfl⟩ : p = C x := p.eq_of_infinite_eval_eq (C x) (by simpa) + simp at hp + theorem roots_mul {p q : R[X]} (hpq : p * q ≠ 0) : (p * q).roots = p.roots + q.roots := by classical exact Multiset.ext.mpr fun r => by diff --git a/Mathlib/RingTheory/PowerBasis.lean b/Mathlib/RingTheory/PowerBasis.lean index d2d640b5e11137..4b16f4168d621b 100644 --- a/Mathlib/RingTheory/PowerBasis.lean +++ b/Mathlib/RingTheory/PowerBasis.lean @@ -115,7 +115,7 @@ theorem mem_span_pow {x y : S} {d : ℕ} (hd : d ≠ 0) : · rintro ⟨f, h, hy⟩ refine ⟨f, ?_, hy⟩ by_cases hf : f = 0 - · simp only [hf, natDegree_zero, degree_zero] at h ⊢ + · simp only [hf, natDegree_zero, Polynomial.degree_zero] at h ⊢ first | exact lt_of_le_of_ne (Nat.zero_le d) hd.symm | exact WithBot.bot_lt_coe d simpa [degree_eq_natDegree hf] using h From c36598a9261afbbbf473310c19d6c2344f73426f Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:26:34 +0000 Subject: [PATCH 0483/1300] feat(Data/Nat/DivSequence): add divisibility sequences and strong divisibility sequences (#41204) This PR moves divisibility sequences from `NumberTheory/EllipticDivisibilitySequence.lean` to a new file `Data/Nat/DivSequence.lean` and adds strong divisibility sequences. Co-authored-by: tb65536 --- Mathlib.lean | 1 + Mathlib/Data/Nat/DvdSequence.lean | 89 +++++++++++++++++++ Mathlib/Data/Nat/Fib/Basic.lean | 10 ++- .../EllipticDivisibilitySequence.lean | 16 ++-- 4 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 Mathlib/Data/Nat/DvdSequence.lean diff --git a/Mathlib.lean b/Mathlib.lean index e1572c3a4a6b20..95dbf986d7e640 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4184,6 +4184,7 @@ public import Mathlib.Data.Nat.Digits.Defs public import Mathlib.Data.Nat.Digits.Div public import Mathlib.Data.Nat.Digits.Lemmas public import Mathlib.Data.Nat.Dist +public import Mathlib.Data.Nat.DvdSequence public import Mathlib.Data.Nat.EvenOddRec public import Mathlib.Data.Nat.Factorial.Basic public import Mathlib.Data.Nat.Factorial.BigOperators diff --git a/Mathlib/Data/Nat/DvdSequence.lean b/Mathlib/Data/Nat/DvdSequence.lean new file mode 100644 index 00000000000000..dcb4abb9a28910 --- /dev/null +++ b/Mathlib/Data/Nat/DvdSequence.lean @@ -0,0 +1,89 @@ +/- +Copyright (c) 2026 Thomas Browning. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Thomas Browning +-/ +module + +public import Mathlib.Algebra.Divisibility.Basic +public import Mathlib.Algebra.Group.Action.Pi + +/-! +# Divisibility sequences + +A sequence `f : ℕ → ℕ` is a *divisibility sequence* if it satisfies `f a ∣ f b` whenever `a ∣ b`. + +A sequence `f : ℕ → ℕ` is a *strong divisibility sequence* if `gcd (f a) (f b) = f (gcd a b)`. + +This file defines divisibility sequences and strong divisibility sequences, and provides some basic +API for these definitions. + +## Main definitions + +* `IsDvdSeq`: A function `f` is a divisibility sequence if `a ∣ b` implies `f a ∣ f b`. +* `Nat.IsStrongDvdSeq`: A function `f : ℕ → ℕ` is a strong divisibility sequence if `f` satisfies + `gcd (f a) (f b) = f (gcd a b)`. +-/ + +@[expose] public section + +variable {α β γ : Type*} + +-- this lemma regarding interaction between `smul` and `dvd` does not have a good home in mathlib +lemma smul_dvd_smul [Monoid α] [Monoid β] [SMul α β] [IsScalarTower α β β] + [IsScalarTower α α β] [SMulCommClass α β β] {a b : α} {c d : β} + (hab : a ∣ b) (hcd : c ∣ d) : (a • c) ∣ (b • d) := by + obtain ⟨⟨x, rfl⟩, ⟨y, rfl⟩⟩ := hab, hcd + exact ⟨x • y, mul_smul_mul_comm a x c y⟩ + +/-- A function `f : α → β` is a divisibility sequence if `a ∣ b` implies `f a ∣ f b`. -/ +def IsDvdSequence [Dvd α] [Dvd β] (f : α → β) : Prop := + ∀ a b, a ∣ b → f a ∣ f b + +namespace IsDvdSequence + +variable (α) in +protected theorem id [Dvd α] : IsDvdSequence (id : α → α) := + fun _ _ ↦ id + +variable (α) in +protected theorem const [Dvd α] [Monoid β] (b : β) : IsDvdSequence (fun _ : α ↦ b) := by + simp [IsDvdSequence] + +protected theorem smul' [Dvd α] [Monoid β] [Monoid γ] {f : α → β} {g : α → γ} [SMul β γ] + [IsScalarTower β γ γ] [IsScalarTower β β γ] [SMulCommClass β γ γ] + (hf : IsDvdSequence f) (hg : IsDvdSequence g) : IsDvdSequence (f • g) := + fun a b hab ↦ smul_dvd_smul (hf a b hab) (hg a b hab) + +protected theorem mul [Dvd α] [CommMonoid β] {f g : α → β} + (hf : IsDvdSequence f) (hg : IsDvdSequence g) : IsDvdSequence (f * g) := + .smul' hf hg + +protected theorem smul [Dvd α] [Monoid β] [Monoid γ] {f : α → γ} [SMul β γ] + [IsScalarTower β γ γ] [IsScalarTower β β γ] [SMulCommClass β γ γ] + (b : β) (hg : IsDvdSequence f) : IsDvdSequence (b • f) := + .smul' (.const α b) hg + +end IsDvdSequence + +namespace Nat + +/-- A function `f : ℕ → ℕ` is a strong divisibility sequence if `gcd (f a) (f b) = f (gcd a b)`. -/ +def IsStrongDvdSequence (f : ℕ → ℕ) : Prop := + ∀ a b, (f a).gcd (f b) = f (a.gcd b) + +namespace IsStrongDvdSequence + +theorem isDvdSequence {f : ℕ → ℕ} (hf : IsStrongDvdSequence f) : IsDvdSequence f := by + intro a b hab + simpa [gcd_eq_left hab, gcd_eq_left_iff_dvd] using hf a b + +protected theorem id : IsStrongDvdSequence (id : ℕ → ℕ) := + fun _ _ ↦ rfl + +protected theorem const (n : ℕ) : IsStrongDvdSequence (fun _ ↦ n) := by + simp [IsStrongDvdSequence] + +end IsStrongDvdSequence + +end Nat diff --git a/Mathlib/Data/Nat/Fib/Basic.lean b/Mathlib/Data/Nat/Fib/Basic.lean index 06ccbf89cac39b..133e9d9b25fa94 100644 --- a/Mathlib/Data/Nat/Fib/Basic.lean +++ b/Mathlib/Data/Nat/Fib/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Data.Finset.NatAntidiagonal public import Mathlib.Data.Nat.GCD.Basic public import Mathlib.Data.Nat.BinaryRec +public import Mathlib.Data.Nat.DvdSequence public import Mathlib.Logic.Function.Iterate public import Mathlib.Tactic.Ring public import Mathlib.Tactic.Zify @@ -243,8 +244,13 @@ theorem fib_gcd (m n : ℕ) : fib (gcd m n) = gcd (fib m) (fib n) := by conv_rhs => rw [← mod_add_div' n m] rwa [gcd_fib_add_mul_self m (n % m) (n / m), gcd_comm (fib m) _] -theorem fib_dvd (m n : ℕ) (h : m ∣ n) : fib m ∣ fib n := by - rwa [← gcd_eq_left_iff_dvd, ← fib_gcd, gcd_eq_left_iff_dvd.mpr] +theorem isStrongDvdSequence_fib : IsStrongDvdSequence fib := + fun m n ↦ (fib_gcd m n).symm + +theorem isDvdSequence_fib : IsDvdSequence fib := + isStrongDvdSequence_fib.isDvdSequence + +alias fib_dvd := isDvdSequence_fib theorem fib_succ_eq_sum_choose : ∀ n : ℕ, fib (n + 1) = ∑ p ∈ Finset.antidiagonal n, choose p.1 p.2 := diff --git a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean index 3da2f1ca10dc78..649c86acda9939 100644 --- a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean +++ b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean @@ -5,6 +5,7 @@ Authors: David Kurniadi Angdinata -/ module +public import Mathlib.Data.Nat.DvdSequence public import Mathlib.Data.Nat.EvenOddRec public import Mathlib.Tactic.Linarith public import Mathlib.Tactic.LinearCombination @@ -30,7 +31,6 @@ Some examples of EDSs include ## Main definitions * `IsEllSequence`: a sequence indexed by integers is an elliptic sequence. -* `IsDivSequence`: a sequence indexed by integers is a divisibility sequence. * `IsEllDivSequence`: a sequence indexed by integers is an EDS. * `preNormEDS'`: the auxiliary sequence for a normalised EDS indexed by `ℕ`. * `preNormEDS`: the auxiliary sequence for a normalised EDS indexed by `ℤ`. @@ -83,23 +83,20 @@ def IsEllSequence : Prop := ∀ m n r : ℤ, W (m + n) * W (m - n) * W r ^ 2 = W (m + r) * W (m - r) * W n ^ 2 - W (n + r) * W (n - r) * W m ^ 2 -/-- The proposition that a sequence indexed by integers is a divisibility sequence. -/ -def IsDivSequence : Prop := - ∀ m n : ℕ, m ∣ n → W m ∣ W n +@[deprecated (since := "2026-06-30")] alias IsDivSequence := IsDvdSequence /-- The proposition that a sequence indexed by integers is an EDS. -/ def IsEllDivSequence : Prop := - IsEllSequence W ∧ IsDivSequence W + IsEllSequence W ∧ IsDvdSequence W lemma isEllSequence_id : IsEllSequence id := fun _ _ _ => by simp_rw [id_eq]; ring1 -lemma isDivSequence_id : IsDivSequence id := - fun _ _ => Int.ofNat_dvd.mpr +@[deprecated (since := "2026-06-30")] alias isDivSequence_id := IsDvdSequence.id /-- The identity sequence is an EDS. -/ theorem isEllDivSequence_id : IsEllDivSequence id := - ⟨isEllSequence_id, isDivSequence_id⟩ + ⟨isEllSequence_id, .id ℤ⟩ variable {W} @@ -107,8 +104,7 @@ lemma IsEllSequence.smul (h : IsEllSequence W) (x : R) : IsEllSequence (x • W) fun m n r => by linear_combination (norm := (simp_rw [Pi.smul_apply, smul_eq_mul]; ring1)) x ^ 4 * h m n r -lemma IsDivSequence.smul (h : IsDivSequence W) (x : R) : IsDivSequence (x • W) := - fun m n r => mul_dvd_mul_left x <| h m n r +@[deprecated (since := "2026-06-30")] alias IsDivSequence.smul := IsDvdSequence.smul lemma IsEllDivSequence.smul (h : IsEllDivSequence W) (x : R) : IsEllDivSequence (x • W) := ⟨h.left.smul x, h.right.smul x⟩ From a9ca7e2570010e1aadfeab41d18fcf39f4ce4899 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:24:03 +0000 Subject: [PATCH 0484/1300] fix(Tactic/Convert): support over-applications again (#40740) This PR fixes a regression introduced in #38071, which had caused the congruence algorithm of `convert` to not support over-applications. I added a test to show this now works again. --- Mathlib/Tactic/CongrExclamation.lean | 2 +- Mathlib/Tactic/Convert.lean | 1 - MathlibTest/Tactic/Convert/Basic.lean | 7 +++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Mathlib/Tactic/CongrExclamation.lean b/Mathlib/Tactic/CongrExclamation.lean index dbad9c4977c1c8..fdf409fcf2fed4 100644 --- a/Mathlib/Tactic/CongrExclamation.lean +++ b/Mathlib/Tactic/CongrExclamation.lean @@ -130,7 +130,7 @@ structure Congr!.Config where This can be used to control which side's definitions are expanded when applying the congruence lemma (if `preferLHS = true` then the RHS can be expanded). -/ preferLHS : Bool := true - /-- Allow both sides to be partial applications. + /-- Allow both sides to be partial applications, and allow overapplications. When false, given an equality `f a b = g x y z` this means we never consider proving `f a = g x y`. diff --git a/Mathlib/Tactic/Convert.lean b/Mathlib/Tactic/Convert.lean index eb74ff924a4cec..7af3d0a8cb73da 100644 --- a/Mathlib/Tactic/Convert.lean +++ b/Mathlib/Tactic/Convert.lean @@ -77,7 +77,6 @@ between `Convert.CheapConfig` and `Convert.ExpensiveConfig` based on other flags -/ structure Convert.CheapConfig extends Congr!.Config where postTransparency := .reducible - partialApp := false sameFun := true /-- Internal elaborator for `Convert.CheapConfig`: use `Convert.elabConfig` instead. -/ diff --git a/MathlibTest/Tactic/Convert/Basic.lean b/MathlibTest/Tactic/Convert/Basic.lean index 6c41f450e271e8..a6ccf70ca7e7a3 100644 --- a/MathlibTest/Tactic/Convert/Basic.lean +++ b/MathlibTest/Tactic/Convert/Basic.lean @@ -2,6 +2,7 @@ module import Mathlib.Tactic.Convert import Mathlib.Algebra.Group.Basic import Mathlib.Data.Set.Image +import Mathlib.Algebra.Notation.Pi.Defs private axiom test_sorry : ∀ {α}, α set_option autoImplicit true @@ -153,4 +154,10 @@ example (P : ℕ → Prop) {a b : ℕ} (hab : b = a) (h : P a) : P (semireducibl example (P : ℕ → Prop) {a b : ℕ} (hab : b = a) (h : P (semireducibleId a)) : P b := by convert! h +-- Test that overapplications are supported +example (f g h k : Nat → Nat) (H : (f + g) 1 = 0) : (h + k) 1 = 0 := by + convert H + guard_target =ₛ h = f + all_goals exact test_sorry + end Tests From 2f5414e57d7977710a37f78b64bfbf7a52563008 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:16:39 +0000 Subject: [PATCH 0485/1300] =?UTF-8?q?feat(Combinatorics/SimpleGraph/Girth)?= =?UTF-8?q?:=20`egirth=20=E2=8A=A4=20=3D=203`=20when=20there=20are=20at=20?= =?UTF-8?q?least=203=20vertices=20(#38529)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since `Nontrivial` is not enough, we use the condition `3 ≤ ENat.card α`. --- Mathlib/Combinatorics/SimpleGraph/Girth.lean | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Girth.lean b/Mathlib/Combinatorics/SimpleGraph/Girth.lean index 1a0b3b537b12a9..7b9df7bf40e396 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Girth.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Girth.lean @@ -77,6 +77,19 @@ lemma three_le_egirth : 3 ≤ G.egirth := by @[simp] lemma egirth_bot : egirth (⊥ : SimpleGraph α) = ⊤ := by simp +theorem egirth_top (h : 3 ≤ ENat.card α) : egirth (⊤ : SimpleGraph α) = 3 := by + classical + refine le_antisymm ?_ three_le_egirth + obtain ⟨s, hcard⟩ := Cardinal.exists_finset_eq_card <| Cardinal.ofNat_le_toENat.mp h + obtain ⟨x, y, z, hxy, hxz, hyz, -⟩ := s.card_eq_three.mp hcard.symm + set w : Walk ⊤ x x := .cons hxy <| .cons hyz <| .cons hxz.symm .nil with hw + have : w.IsCycle := + { edges_nodup := by aesop + ne_nil := by aesop + support_nodup := by aesop } + grw [egirth_le_length this] + simp [hw] + @[gcongr only] lemma IsContained.egirth_le (h : G ⊑ G') : G'.egirth ≤ G.egirth := by by_cases hacyc : G.IsAcyclic @@ -129,6 +142,9 @@ lemma exists_girth_eq_length : @[simp] lemma girth_bot : girth (⊥ : SimpleGraph α) = 0 := by simp [girth] +theorem girth_top (h : 3 ≤ ENat.card α) : girth (⊤ : SimpleGraph α) = 3 := by + simp [girth, egirth_top h] + lemma IsContained.girth_le (h : G ⊑ G') (hG : ¬G.IsAcyclic) : G'.girth ≤ G.girth := ENat.toNat_le_toNat h.egirth_le <| egirth_eq_top.not.mpr hG From 4e984885102e80244f4a6e48b7da1350f1d4343f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhao=20Yuyang=20=E8=B5=B5=E9=9B=A8=E6=89=AC?= Date: Tue, 30 Jun 2026 20:16:41 +0000 Subject: [PATCH 0486/1300] perf: lower the priority of `Normed*.to*` instances (#40144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR further lowers the priority of these instances, since lower instance priority usually means priority 100, whereas we want these instances to have an even lower priority. Only one file got significantly slower from searching for AddCommMonoid ↥(Lp ?m 1 ?m') during unification. Lean tries AddSubgroupClass.toAddCommGroup and then gets stuck on the metavariables. Adding a shortcut instance for Lp resolves it directly and avoids any further search. --- Mathlib/Analysis/Normed/Field/Basic.lean | 6 +++++ Mathlib/Analysis/Normed/Group/Defs.lean | 24 +++++++++---------- Mathlib/Analysis/Normed/Ring/Basic.lean | 20 ++++++++++++---- .../MeasureTheory/Function/LpSpace/Basic.lean | 3 +++ 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/Mathlib/Analysis/Normed/Field/Basic.lean b/Mathlib/Analysis/Normed/Field/Basic.lean index 9a0b0745f1b610..5b987828d26609 100644 --- a/Mathlib/Analysis/Normed/Field/Basic.lean +++ b/Mathlib/Analysis/Normed/Field/Basic.lean @@ -43,6 +43,9 @@ class NormedDivisionRing (α : Type*) extends Norm α, DivisionRing α, MetricSp /-- The norm is multiplicative. -/ protected norm_mul : ∀ a b, norm (a * b) = norm a * norm b +-- see Note [lower instance priority] +attribute [instance 10] NormedDivisionRing.toDivisionRing + -- see Note [lower instance priority] /-- A normed division ring is a normed ring. -/ instance (priority := 100) NormedDivisionRing.toNormedRing [β : NormedDivisionRing α] : @@ -154,6 +157,9 @@ class NormedField (α : Type*) extends Norm α, Field α, MetricSpace α where /-- The norm is multiplicative. -/ protected norm_mul : ∀ a b, norm (a * b) = norm a * norm b +-- see Note [lower instance priority] +attribute [instance 10] NormedField.toField + /-- A nontrivially normed field is a normed field in which there is an element of norm different from `0` and `1`. This makes it possible to bring any element arbitrarily close to `0` by multiplication by the powers of any element, and thus to relate algebra and topology. -/ diff --git a/Mathlib/Analysis/Normed/Group/Defs.lean b/Mathlib/Analysis/Normed/Group/Defs.lean index 986529b3cc34e4..91d2e8006fe908 100644 --- a/Mathlib/Analysis/Normed/Group/Defs.lean +++ b/Mathlib/Analysis/Normed/Group/Defs.lean @@ -117,7 +117,7 @@ class ESeminormedAddMonoid (E : Type*) [TopologicalSpace E] protected enorm_add_le : ∀ x y : E, ‖x + y‖ₑ ≤ ‖x‖ₑ + ‖y‖ₑ -- see Note [lower instance priority] -attribute [instance 200] ESeminormedAddMonoid.toAddMonoid +attribute [instance 10] ESeminormedAddMonoid.toAddMonoid /-- An enormed monoid is an additive monoid endowed with a continuous enorm, which is positive definite: in other words, this is an `ESeminormedAddMonoid` with a positive @@ -134,7 +134,7 @@ class ESeminormedMonoid (E : Type*) [TopologicalSpace E] extends ContinuousENorm enorm_mul_le : ∀ x y : E, ‖x * y‖ₑ ≤ ‖x‖ₑ + ‖y‖ₑ -- see Note [lower instance priority] -attribute [instance 200] ESeminormedMonoid.toMonoid +attribute [instance 10] ESeminormedMonoid.toMonoid /-- An enormed monoid is a monoid endowed with a continuous enorm, which is positive definite: in other words, this is an `ESeminormedMonoid` with a positive @@ -153,7 +153,7 @@ class ESeminormedAddCommMonoid (E : Type*) [TopologicalSpace E] extends ESeminormedAddMonoid E, AddCommMonoid E where -- see Note [lower instance priority] -attribute [instance 200] ESeminormedAddCommMonoid.toAddCommMonoid +attribute [instance 10] ESeminormedAddCommMonoid.toAddCommMonoid /-- An enormed commutative monoid is an additive commutative monoid endowed with a continuous enorm which is positive definite. @@ -170,7 +170,7 @@ class ESeminormedCommMonoid (E : Type*) [TopologicalSpace E] extends ESeminormedMonoid E, CommMonoid E where -- see Note [lower instance priority] -attribute [instance 200] ESeminormedCommMonoid.toCommMonoid +attribute [instance 10] ESeminormedCommMonoid.toCommMonoid /-- An enormed commutative monoid is a commutative monoid endowed with a continuous enorm which is positive definite. -/ @@ -186,7 +186,7 @@ class SeminormedAddGroup (E : Type*) extends Norm E, AddGroup E, PseudoMetricSpa dist_eq : ∀ x y, dist x y = ‖-x + y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] SeminormedAddGroup.toAddGroup +attribute [instance 10] SeminormedAddGroup.toAddGroup /-- A seminormed group is a group endowed with a norm for which `dist x y = ‖x⁻¹ * y‖` defines a pseudometric space structure. -/ @@ -197,7 +197,7 @@ class SeminormedGroup (E : Type*) extends Norm E, Group E, PseudoMetricSpace E w dist_eq : ∀ x y, dist x y = ‖x⁻¹ * y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] SeminormedGroup.toGroup +attribute [instance 10] SeminormedGroup.toGroup /-- A normed group is an additive group endowed with a norm for which `dist x y = ‖-x + y‖` defines a metric space structure. -/ @@ -207,7 +207,7 @@ class NormedAddGroup (E : Type*) extends Norm E, AddGroup E, MetricSpace E where dist_eq : ∀ x y, dist x y = ‖-x + y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] NormedAddGroup.toAddGroup +attribute [instance 10] NormedAddGroup.toAddGroup /-- A normed group is a group endowed with a norm for which `dist x y = ‖x⁻¹ * y‖` defines a metric space structure. -/ @@ -218,7 +218,7 @@ class NormedGroup (E : Type*) extends Norm E, Group E, MetricSpace E where dist_eq : ∀ x y, dist x y = ‖x⁻¹ * y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] NormedGroup.toGroup +attribute [instance 10] NormedGroup.toGroup /-- A seminormed group is an additive group endowed with a norm for which `dist x y = ‖-x + y‖` defines a pseudometric space structure. -/ @@ -229,7 +229,7 @@ class SeminormedAddCommGroup (E : Type*) extends Norm E, AddCommGroup E, dist_eq : ∀ x y, dist x y = ‖-x + y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] SeminormedAddCommGroup.toAddCommGroup +attribute [instance 10] SeminormedAddCommGroup.toAddCommGroup /-- A seminormed group is a group endowed with a norm for which `dist x y = ‖x⁻¹ * y‖` defines a pseudometric space structure. -/ @@ -240,7 +240,7 @@ class SeminormedCommGroup (E : Type*) extends Norm E, CommGroup E, PseudoMetricS dist_eq : ∀ x y, dist x y = ‖x⁻¹ * y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] SeminormedCommGroup.toCommGroup +attribute [instance 10] SeminormedCommGroup.toCommGroup /-- A normed group is an additive group endowed with a norm for which `dist x y = ‖-x + y‖` defines a metric space structure. -/ @@ -250,7 +250,7 @@ class NormedAddCommGroup (E : Type*) extends Norm E, AddCommGroup E, MetricSpace dist_eq : ∀ x y, dist x y = ‖-x + y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] NormedAddCommGroup.toAddCommGroup +attribute [instance 10] NormedAddCommGroup.toAddCommGroup /-- A normed group is a group endowed with a norm for which `dist x y = ‖x⁻¹ * y‖` defines a metric space structure. -/ @@ -261,7 +261,7 @@ class NormedCommGroup (E : Type*) extends Norm E, CommGroup E, MetricSpace E whe dist_eq : ∀ x y, dist x y = ‖x⁻¹ * y‖ := by aesop -- see Note [lower instance priority] -attribute [instance 200] NormedCommGroup.toCommGroup +attribute [instance 10] NormedCommGroup.toCommGroup -- See note [lower instance priority] @[to_additive] diff --git a/Mathlib/Analysis/Normed/Ring/Basic.lean b/Mathlib/Analysis/Normed/Ring/Basic.lean index 377e845d613b2b..5ffd65f31cb975 100644 --- a/Mathlib/Analysis/Normed/Ring/Basic.lean +++ b/Mathlib/Analysis/Normed/Ring/Basic.lean @@ -43,6 +43,9 @@ class NonUnitalSeminormedRing (α : Type*) extends Norm α, NonUnitalRing α, /-- The norm is submultiplicative. -/ protected norm_mul_le : ∀ a b, norm (a * b) ≤ norm a * norm b +-- see Note [lower instance priority] +attribute [instance 10] NonUnitalSeminormedRing.toNonUnitalRing + /-- A seminormed ring is a ring endowed with a seminorm which satisfies the inequality `‖x y‖ ≤ ‖x‖ ‖y‖`. -/ class SeminormedRing (α : Type*) extends Norm α, Ring α, PseudoMetricSpace α where @@ -51,6 +54,9 @@ class SeminormedRing (α : Type*) extends Norm α, Ring α, PseudoMetricSpace α /-- The norm is submultiplicative. -/ norm_mul_le : ∀ a b, norm (a * b) ≤ norm a * norm b +-- see Note [lower instance priority] +attribute [instance 10] SeminormedRing.toRing + -- see Note [lower instance priority] /-- A seminormed ring is a non-unital seminormed ring. -/ instance (priority := 100) SeminormedRing.toNonUnitalSeminormedRing [β : SeminormedRing α] : @@ -65,6 +71,9 @@ class NonUnitalNormedRing (α : Type*) extends Norm α, NonUnitalRing α, Metric /-- The norm is submultiplicative. -/ norm_mul_le : ∀ a b, norm (a * b) ≤ norm a * norm b +-- see Note [lower instance priority] +attribute [instance 10] NonUnitalNormedRing.toNonUnitalRing + -- see Note [lower instance priority] /-- A non-unital normed ring is a non-unital seminormed ring. -/ instance (priority := 100) NonUnitalNormedRing.toNonUnitalSeminormedRing @@ -78,6 +87,9 @@ class NormedRing (α : Type*) extends Norm α, Ring α, MetricSpace α where /-- The norm is submultiplicative. -/ norm_mul_le : ∀ a b, norm (a * b) ≤ norm a * norm b +-- see Note [lower instance priority] +attribute [instance 10] NormedRing.toRing + -- see Note [lower instance priority] /-- A normed ring is a seminormed ring. -/ instance (priority := 100) NormedRing.toSeminormedRing [β : NormedRing α] : SeminormedRing α := @@ -95,14 +107,14 @@ class NonUnitalSeminormedCommRing (α : Type*) extends NonUnitalSeminormedRing α, NonUnitalCommRing α where -- see Note [lower instance priority] -attribute [instance 100] NonUnitalSeminormedCommRing.toNonUnitalCommRing +attribute [instance 10] NonUnitalSeminormedCommRing.toNonUnitalCommRing /-- A non-unital normed commutative ring is a non-unital commutative ring endowed with a norm which satisfies the inequality `‖x y‖ ≤ ‖x‖ ‖y‖`. -/ class NonUnitalNormedCommRing (α : Type*) extends NonUnitalNormedRing α, NonUnitalCommRing α where -- see Note [lower instance priority] -attribute [instance 100] NonUnitalNormedCommRing.toNonUnitalCommRing +attribute [instance 10] NonUnitalNormedCommRing.toNonUnitalCommRing -- see Note [lower instance priority] /-- A non-unital normed commutative ring is a non-unital seminormed commutative ring. -/ @@ -115,14 +127,14 @@ the inequality `‖x y‖ ≤ ‖x‖ ‖y‖`. -/ class SeminormedCommRing (α : Type*) extends SeminormedRing α, CommRing α where -- see Note [lower instance priority] -attribute [instance 100] SeminormedCommRing.toCommRing +attribute [instance 10] SeminormedCommRing.toCommRing /-- A normed commutative ring is a commutative ring endowed with a norm which satisfies the inequality `‖x y‖ ≤ ‖x‖ ‖y‖`. -/ class NormedCommRing (α : Type*) extends NormedRing α, CommRing α where -- see Note [lower instance priority] -attribute [instance 100] NormedCommRing.toCommRing +attribute [instance 10] NormedCommRing.toCommRing -- see Note [lower instance priority] /-- A seminormed commutative ring is a non-unital seminormed commutative ring. -/ diff --git a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean index f66de7c766a34e..8873829b2833e9 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean @@ -381,7 +381,10 @@ theorem norm_le_of_ae_bound [IsFiniteMeasure μ] {f : Lp E p μ} {C : ℝ} (hC : have := nnnorm_le_of_ae_bound hfC rwa [← NNReal.coe_le_coe, NNReal.coe_mul, NNReal.coe_rpow] at this +instance instAddCommGroup : AddCommGroup (Lp E p μ) := inferInstance + instance instNormedAddCommGroup [hp : Fact (1 ≤ p)] : NormedAddCommGroup (Lp E p μ) := + fast_instance% { AddGroupNorm.toNormedAddCommGroup { toFun := (norm : Lp E p μ → ℝ) map_zero' := norm_zero From 39ba0f9405e5a40e45a6ccb4226b590bdc875016 Mon Sep 17 00:00:00 2001 From: Joris Roos <170825715+roos-j@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:16:43 +0000 Subject: [PATCH 0487/1300] chore(Analysis/Calculus): generalize `HasDerivWithinAt.inv` etc (#40743) --- Mathlib/Analysis/Calculus/Deriv/Inv.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/Deriv/Inv.lean b/Mathlib/Analysis/Calculus/Deriv/Inv.lean index 05ff9f51b4928c..e81a21975b47f2 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Inv.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Inv.lean @@ -98,7 +98,8 @@ theorem fderivWithin_inv (x_ne_zero : x ≠ 0) (hxs : UniqueDiffWithinAt 𝕜 s rw [DifferentiableAt.fderivWithin (differentiableAt_inv x_ne_zero) hxs] exact fderiv_inv -variable {c : 𝕜 → 𝕜} {c' : 𝕜} +variable {𝕜' : Type*} [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] +variable {c : 𝕜 → 𝕜'} {c' : 𝕜'} @[to_fun] theorem HasDerivWithinAt.inv (hc : HasDerivWithinAt c c' s x) (hx : c x ≠ 0) : From 4bf1ddaebedf582efe64474559c68cafa5df2cb2 Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:40:24 +0000 Subject: [PATCH 0488/1300] refactor: change definitions to avoid `ConvexCone` (#37420) Change the definitions of `PointedCone.positive` and `PointedCone.closure` to avoid mentioning `ConvexCone`. This PR is part of a series deprecating `ConvexCone`: https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Replacing.20.60ConvexCone.60.20with.20.60PointedCone.60/with/582738985 Co-authored-by: artie2000 --- Mathlib/Analysis/Convex/Cone/Closure.lean | 7 +++++-- Mathlib/Geometry/Convex/Cone/Pointed.lean | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Convex/Cone/Closure.lean b/Mathlib/Analysis/Convex/Cone/Closure.lean index 2d1e5ffe4a67cf..d7edaf16a33634 100644 --- a/Mathlib/Analysis/Convex/Cone/Closure.lean +++ b/Mathlib/Analysis/Convex/Cone/Closure.lean @@ -60,8 +60,11 @@ lemma toConvexCone_closure_pointed (K : PointedCone 𝕜 E) : (K : ConvexCone /-- The closure of a pointed cone inside a topological space as a pointed cone. This construction is mainly used for defining maps between proper cones. -/ -protected def closure (K : PointedCone 𝕜 E) : PointedCone 𝕜 E := - K.toConvexCone.closure.toPointedCone K.toConvexCone_closure_pointed +protected def closure (K : PointedCone 𝕜 E) : PointedCone 𝕜 E where + carrier := closure ↑K + zero_mem' := subset_closure (zero_mem K) + smul_mem' c _ h₁ := map_mem_closure (continuous_const_smul c.1) h₁ fun _ h₂ ↦ K.smul_mem c.2 h₂ + add_mem' h₁ h₂ := map_mem_closure₂ continuous_add h₁ h₂ (fun _ ha _ hb ↦ K.add_mem ha hb) @[simp, norm_cast] theorem coe_closure (K : PointedCone 𝕜 E) : (K.closure : Set E) = closure K := diff --git a/Mathlib/Geometry/Convex/Cone/Pointed.lean b/Mathlib/Geometry/Convex/Cone/Pointed.lean index 9ce1c7fa9c4d0b..fc557380f4d469 100644 --- a/Mathlib/Geometry/Convex/Cone/Pointed.lean +++ b/Mathlib/Geometry/Convex/Cone/Pointed.lean @@ -6,6 +6,7 @@ Authors: Apurva Nakade module public import Mathlib.Algebra.Group.Submonoid.Support +public import Mathlib.Algebra.Order.Monoid.Submonoid public import Mathlib.Algebra.Order.Nonneg.Module public import Mathlib.Geometry.Convex.Cone.Basic @@ -278,8 +279,10 @@ variable [AddCommMonoid E] [PartialOrder E] [IsOrderedAddMonoid E] [Module R E] /-- The positive cone is the pointed cone formed by the set of nonnegative elements in an ordered module. -/ -def positive : PointedCone R E := - (ConvexCone.positive R E).toPointedCone ConvexCone.pointed_positive +@[simps!] +def positive : PointedCone R E where + __ := AddSubmonoid.nonneg E + smul_mem' c _ hx := by simpa using smul_nonneg c.property hx @[simp] theorem mem_positive {x : E} : x ∈ positive R E ↔ 0 ≤ x := From 4568a3518cbd6928b7e5dfbb28db9e3f31833755 Mon Sep 17 00:00:00 2001 From: TJHeeringa <16029718+TJHeeringa@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:40:27 +0000 Subject: [PATCH 0489/1300] feat(Analysis/InnerProductSpace/TensorProduct): Add TensorProduct.mapL (#40074) This PR defines `TensorProduct.mapL`, the continuous version of `TensorProduct.map`. Co-authored-by: Heeringa Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- .../InnerProductSpace/TensorProduct.lean | 260 +++++++++++++++++- .../Normed/Operator/LinearIsometry.lean | 3 + 2 files changed, 254 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean b/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean index 8a195258189685..e2360e5c1d9801 100644 --- a/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean +++ b/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean @@ -8,6 +8,8 @@ module public import Mathlib.Analysis.InnerProductSpace.Adjoint public import Mathlib.LinearAlgebra.TensorProduct.Finiteness public import Mathlib.RingTheory.TensorProduct.Finite +import Mathlib.Analysis.InnerProductSpace.GramMatrix +import Mathlib.Analysis.InnerProductSpace.Positive /-! @@ -32,13 +34,13 @@ inner product spaces. * `TensorProduct.commIsometry`: the linear isometry version of `TensorProduct.comm`. * `TensorProduct.lidIsometry`: the linear isometry version of `TensorProduct.lid`. * `TensorProduct.assocIsometry`: the linear isometry version of `TensorProduct.assoc`. +* `TensorProduct.mapL`: the continuous version of `TensorProduct.map f g` when + `f` and `g` are continuous linear maps. * `OrthonormalBasis.tensorProduct`: the orthonormal basis of the tensor product of two orthonormal bases. ## TODO: -* Define the continuous linear map version of `TensorProduct.map`. -* Complete space of tensor products. * Define the normed space without needing inner products, this should be analogous to `Mathlib/Analysis/NormedSpace/PiTensorProduct/InjectiveSeminorm.lean`. @@ -409,21 +411,261 @@ noncomputable def assocIsometry : E ⊗[𝕜] F ⊗[𝕜] G ≃ₗᵢ[𝕜] E end isometry --- TODO: upgrade `map` to a `ContinuousLinearMap` -@[simp] theorem adjoint_map [FiniteDimensional 𝕜 E] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 G] - [FiniteDimensional 𝕜 H] (f : E →ₗ[𝕜] F) (g : G →ₗ[𝕜] H) : - LinearMap.adjoint (map f g) = map (LinearMap.adjoint f) (LinearMap.adjoint g) := - ext' fun _ _ => by simp [TensorProduct.ext_iff_inner_right, LinearMap.adjoint_inner_left] +end TensorProduct + +namespace ContinuousLinearMap + +open TensorProduct + +variable (G) + +/-- `LinearMap.rTensor` as a continuous linear map, i.e. the continuous linear map `f` extended to +the map `x ⊗ₜ[𝕜] y ↦ f(x) ⊗ₜ[𝕜] y`. -/ +noncomputable def rTensor (f : E →L[𝕜] F) : (E ⊗[𝕜] G) →L[𝕜] (F ⊗[𝕜] G) := + (f.toLinearMap.rTensor G).mkContinuous ‖f‖ fun x ↦ by + /- + Any tensor `x` can be written as a linear combination of pure tensors, `x = ∑ e n ⊗ₜ g n`. This + induces three Gram matrices, one based on `e`, one on `f ∘ e` and one on `g`. Up to a constant, + the `e`-based Gram matrix is larger than the `f ∘ e`-based one. This implies the existence of + a matrix, whose form is used to show that `‖f‖ ^ 2 * ‖x‖ ^ 2 - ‖f x‖ ^ 2` is a sum of + nonnegative terms. + -/ + obtain ⟨n, e, g, hx⟩ := exists_sum_tmul_eq x + obtain ⟨c, hc_supp, hc⟩ := Submodule.mem_span_set.mp + ((span_tmul_eq_top 𝕜 E G) ▸ Submodule.mem_top (x := x)) + obtain ⟨m, A, hA⟩ := Matrix.posSemidef_iff_eq_sum_vecMulVec.mp + (Matrix.posSemidef_opNorm_smul_gram_sub_gram e f) + apply (sq_le_sq₀ (norm_nonneg _) (by positivity)).mp + simp_rw [sub_eq_iff_eq_add', ← sub_eq_iff_eq_add, ← Matrix.ext_iff, Matrix.sub_apply, + Matrix.smul_apply, Matrix.gram_apply, Function.comp_apply] at hA + simp_rw [mul_pow, hx, map_sum, LinearMap.rTensor_tmul, coe_coe, + ← inner_self_eq_norm_sq (𝕜 := 𝕜), inner_sum, sum_inner, inner_tmul, ← hA, sub_mul, + Finset.sum_sub_distrib, map_sub, ← RCLike.smul_re, Finset.smul_sum, smul_mul_assoc, + sub_le_self_iff, Matrix.sum_apply, mul_comm, Finset.mul_sum] + simp_rw +singlePass [Finset.sum_comm_cycle, Matrix.vecMulVec, Matrix.of_apply, Pi.star_apply, + ← mul_left_comm, ← mul_assoc, ← starRingEnd_self_apply (A _ _), ← inner_smul_left] + simp [mul_comm, ← inner_smul_right, ← sum_inner, ← inner_sum, Finset.sum_nonneg] + +variable {G} in +@[simp] lemma rTensor_apply (f : E →L[𝕜] F) (x : E ⊗ G) : + f.rTensor G x = f.toLinearMap.rTensor G x := rfl + +variable {G} in +lemma rTensor_tmul (f : E →L[𝕜] F) (m : E) (n : G) : f.rTensor G (m ⊗ₜ n) = f m ⊗ₜ n := rfl + +@[simp] lemma toLinearMap_rTensor (f : E →L[𝕜] F) : + (f.rTensor G).toLinearMap = f.toLinearMap.rTensor G := rfl + +@[simp] lemma _root_.LinearIsometry.toContinuousLinearMap_rTensor (f : E →ₗᵢ[𝕜] F) : + (f.rTensor G).toContinuousLinearMap = f.toContinuousLinearMap.rTensor G := rfl + +theorem norm_rTensor_le (f : E →L[𝕜] F) : ‖f.rTensor G‖ ≤ ‖f‖ := + LinearMap.mkContinuous_norm_le _ (norm_nonneg _) _ + +@[simp] lemma rTensor_add (f₁ f₂ : E →L[𝕜] F) : + (f₁ + f₂).rTensor G = f₁.rTensor G + f₂.rTensor G := by ext; simp + +@[simp] lemma rTensor_smul (r : 𝕜) (f : E →L[𝕜] F) : + (r • f).rTensor G = r • f.rTensor G := by ext; simp + +@[simp] lemma rTensor_id : (.id 𝕜 E : E →L[𝕜] E).rTensor G = .id 𝕜 _ := by ext; simp +@[simp] lemma rTensor_one : (1 : E →L[𝕜] E).rTensor G = 1 := rTensor_id _ +@[simp] lemma rTensor_zero : (0 : E →L[𝕜] F).rTensor G = 0 := by ext; simp +@[simp] lemma rTensor_neg (f : E →L[𝕜] F) : (-f).rTensor G = -f.rTensor G := by ext; simp + +@[simp] lemma rTensor_sub (f₁ f₂ : E →L[𝕜] F) : + (f₁ - f₂).rTensor G = f₁.rTensor G - f₂.rTensor G := by ext; simp + +lemma rTensor_comp (f₁ : E →L[𝕜] F) (f₂ : H →L[𝕜] E) : + (f₁ ∘L f₂).rTensor G = f₁.rTensor G ∘L f₂.rTensor G := by ext; simp [LinearMap.rTensor_comp] + +lemma rTensor_mul (f₁ f₂ : E →L[𝕜] E) : (f₁ * f₂).rTensor G = f₁.rTensor G * f₂.rTensor G := + rTensor_comp _ _ _ + +@[simp] lemma rTensor_pow (f : E →L[𝕜] E) (n : ℕ) : (f ^ n).rTensor G = (f.rTensor G) ^ n := by + simp [← coe_inj] + +/-- `LinearMap.lTensor` as a continuous linear map, i.e. the continuous linear map `g` extended to +the map `x ⊗ₜ[𝕜] y ↦ x ⊗ₜ[𝕜] g(y)`. -/ +noncomputable def lTensor (g : E →L[𝕜] F) : (G ⊗[𝕜] E) →L[𝕜] (G ⊗[𝕜] F) := + commIsometry 𝕜 F G ∘L g.rTensor G ∘L commIsometry 𝕜 G E + +variable {G} in +@[simp] lemma lTensor_apply (g : G →L[𝕜] H) (x : E ⊗ G) : + g.lTensor E x = g.toLinearMap.lTensor E x := by + simp [lTensor, ← LinearMap.comm_comp_rTensor_comp_comm_eq] + +lemma lTensor_tmul (g : E →L[𝕜] F) (m : G) (n : E) : g.lTensor G (m ⊗ₜ n) = m ⊗ₜ g n := rfl + +theorem commIsometry_comp_lTensor_comp_commIsometry_eq (g : E →L[𝕜] F) : + commIsometry 𝕜 F G ∘L g.rTensor G ∘L commIsometry 𝕜 G E = g.lTensor G := + rfl + +theorem commIsometry_comp_rTensor_comp_commIsometry_eq (f : E →L[𝕜] F) : + commIsometry 𝕜 G F ∘L f.lTensor G ∘L commIsometry 𝕜 E G = f.rTensor G := by + ext; simp [lTensor] + +theorem lTensor_comp_commIsometry (f : E →L[𝕜] F) : + f.lTensor G ∘L commIsometry 𝕜 E G = commIsometry 𝕜 F G ∘L f.rTensor G := by + ext; simp [lTensor] + +theorem rTensor_comp_commIsometry (g : E →L[𝕜] F) : + g.rTensor G ∘L commIsometry 𝕜 G E = commIsometry 𝕜 G F ∘L g.lTensor G := by + ext; simp [lTensor] + +@[simp] lemma toLinearMap_lTensor (g : E →L[𝕜] F) : + (g.lTensor G).toLinearMap = g.toLinearMap.lTensor G := by ext; simp + +@[simp] lemma _root_.LinearIsometry.toContinuousLinearMap_lTensor (g : E →ₗᵢ[𝕜] F) : + (g.lTensor G).toContinuousLinearMap = g.toContinuousLinearMap.lTensor G := by ext; simp + +theorem norm_lTensor_le (g : E →L[𝕜] F) : ‖g.lTensor G‖ ≤ ‖g‖ := by + simp_rw [lTensor, ← LinearIsometryEquiv.toContinuousLinearMap_toLinearIsometry] + grw [opNorm_comp_le, opNorm_comp_le, LinearIsometry.norm_toContinuousLinearMap_le, + LinearIsometry.norm_toContinuousLinearMap_le, mul_one, one_mul, norm_rTensor_le] + +@[simp] lemma lTensor_add (f₁ f₂ : E →L[𝕜] F) : + (f₁ + f₂).lTensor G = f₁.lTensor G + f₂.lTensor G := by ext; simp + +@[simp] lemma lTensor_smul (r : 𝕜) (f : E →L[𝕜] F) : (r • f).lTensor G = r • f.lTensor G := by + ext; simp + +@[simp] lemma lTensor_id : (.id 𝕜 E : E →L[𝕜] E).lTensor G = .id 𝕜 _ := by ext; simp +@[simp] lemma lTensor_one : (1 : E →L[𝕜] E).lTensor G = 1 := lTensor_id _ +@[simp] lemma lTensor_zero : (0 : E →L[𝕜] F).lTensor G = 0 := by ext; simp +@[simp] lemma lTensor_neg (f : E →L[𝕜] F) : (-f).lTensor G = -f.lTensor G := by ext; simp + +@[simp] lemma lTensor_sub (f₁ f₂ : E →L[𝕜] F) : + (f₁ - f₂).lTensor G = f₁.lTensor G - f₂.lTensor G := by ext; simp + +lemma lTensor_comp (f₁ : E →L[𝕜] F) (f₂ : H →L[𝕜] E) : + (f₁ ∘L f₂).lTensor G = f₁.lTensor G ∘L f₂.lTensor G := by ext; simp [LinearMap.lTensor_comp] + +lemma lTensor_mul (f₁ f₂ : E →L[𝕜] E) : (f₁ * f₂).lTensor G = f₁.lTensor G * f₂.lTensor G := + lTensor_comp _ _ _ + +@[simp] lemma lTensor_pow (f : E →L[𝕜] E) (n : ℕ) : (f ^ n).lTensor G = (f.lTensor G) ^ n := by + simp [← coe_inj] + +end ContinuousLinearMap + +namespace TensorProduct + +/-- `TensorProduct.map` as a continuous linear map, i.e. the continuous linear map +`x ⊗ₜ[𝕜] y ↦ f(x) ⊗ₜ[𝕜] g(y)` formed from the continuous linear maps `f` and `g`. -/ +noncomputable def mapL (f : E →L[𝕜] F) (g : G →L[𝕜] H) : (E ⊗[𝕜] G) →L[𝕜] (F ⊗[𝕜] H) := + f.rTensor H ∘L g.lTensor E + +theorem norm_mapL_le (f : E →L[𝕜] F) (g : G →L[𝕜] H) : ‖mapL f g‖ ≤ ‖f‖ * ‖g‖ := by + grw [mapL, ContinuousLinearMap.opNorm_comp_le, ContinuousLinearMap.norm_rTensor_le, + ContinuousLinearMap.norm_lTensor_le] + +@[simp] lemma mapL_apply (f : E →L[𝕜] F) (g : G →L[𝕜] H) (x) : + mapL f g x = map f.toLinearMap g.toLinearMap x := by + simp [mapL, ← LinearMap.rTensor_comp_lTensor] + +lemma mapL_tmul (f : E →L[𝕜] F) (g : G →L[𝕜] H) (m : E) (n : G) : + mapL f g (m ⊗ₜ n) = f m ⊗ₜ g n := rfl + +@[simp] lemma mapL_zero_left (f : E →L[𝕜] F) : mapL (0 : G →L[𝕜] H) f = 0 := by simp [mapL] +@[simp] lemma mapL_zero_right (f : E →L[𝕜] F) : mapL f (0 : G →L[𝕜] H) = 0 := by simp [mapL] +@[simp] lemma mapL_id_id : mapL (.id 𝕜 E) (.id 𝕜 G) = .id 𝕜 _ := by simp [mapL] + +lemma mapL_comp_commIsometry (f : E →L[𝕜] F) (g : G →L[𝕜] H) : + mapL f g ∘L commIsometry 𝕜 G E = commIsometry 𝕜 H F ∘L mapL g f := by ext; simp [map_comm] + +lemma mapL_add_left (f₁ f₂ : E →L[𝕜] F) (g : G →L[𝕜] H) : + mapL (f₁ + f₂) g = mapL f₁ g + mapL f₂ g := by ext; simp [map_add_left] + +lemma mapL_add_right (f : E →L[𝕜] F) (g₁ g₂ : G →L[𝕜] H) : + mapL f (g₁ + g₂) = mapL f g₁ + mapL f g₂ := by ext; simp [map_add_right] + +lemma mapL_smul_left (r : 𝕜) (f : E →L[𝕜] F) (g : G →L[𝕜] H) : + mapL (r • f) g = r • mapL f g := by ext; simp [map_smul_left] + +lemma mapL_smul_right (r : 𝕜) (f : E →L[𝕜] F) (g : G →L[𝕜] H) : + mapL f (r • g) = r • mapL f g := by ext; simp [map_smul_right] + +@[simp] lemma toLinearMap_mapL (f : E →L[𝕜] F) (g : G →L[𝕜] H) : + (mapL f g).toLinearMap = map f g := by ext; simp + +@[simp] lemma toContinuousLinearMap_mapIsometry (f : E →ₗᵢ[𝕜] F) (g : G →ₗᵢ[𝕜] H) : + (mapIsometry f g).toContinuousLinearMap = + mapL f.toContinuousLinearMap g.toContinuousLinearMap := by + ext; simp + +section comp + +variable {A B : Type*} [NormedAddCommGroup A] [InnerProductSpace 𝕜 A] [NormedAddCommGroup B] + [InnerProductSpace 𝕜 B] + +lemma mapL_comp (f₁ : E →L[𝕜] F) (f₂ : A →L[𝕜] E) (g₁ : G →L[𝕜] H) (g₂ : B →L[𝕜] G) : + mapL (f₁ ∘L f₂) (g₁ ∘L g₂) = mapL f₁ g₁ ∘L mapL f₂ g₂ := by ext; simp [map_map] + +lemma mapL_mul (f₁ f₂ : E →L[𝕜] E) (g₁ g₂ : F →L[𝕜] F) : + mapL (f₁ * f₂) (g₁ * g₂) = mapL f₁ g₁ * mapL f₂ g₂ := mapL_comp _ _ _ _ + +@[simp] lemma mapL_pow (f : E →L[𝕜] E) (g : F →L[𝕜] F) (n : ℕ) : + (mapL f g) ^ n = mapL (f ^ n) (g ^ n) := by simp [← ContinuousLinearMap.coe_inj] + +@[simp] lemma _root_.ContinuousLinearMap.mapL_comp_rTensor (f₁ : E →L[𝕜] F) (f₂ : A →L[𝕜] E) + (g : G →L[𝕜] H) : mapL f₁ g ∘L f₂.rTensor G = mapL (f₁ ∘L f₂) g := by ext; simp + +@[simp] lemma _root_.ContinuousLinearMap.mapL_comp_lTensor (f : E →L[𝕜] F) (g₁ : G →L[𝕜] H) + (g₂ : A →L[𝕜] G) : mapL f g₁ ∘L g₂.lTensor E = mapL f (g₁ ∘L g₂) := by ext; simp + +@[simp] lemma _root_.ContinuousLinearMap.rTensor_comp_mapL (f₁ : E →L[𝕜] F) (f₂ : A →L[𝕜] E) + (g : G →L[𝕜] H) : f₁.rTensor H ∘L mapL f₂ g = mapL (f₁ ∘L f₂) g := by ext; simp + +@[simp] lemma _root_.ContinuousLinearMap.lTensor_comp_mapL (f : E →L[𝕜] F) (g₁ : G →L[𝕜] H) + (g₂ : A →L[𝕜] G) : g₁.lTensor F ∘L mapL f g₂ = mapL f (g₁ ∘L g₂) := by ext; simp + +end comp + +variable (G) in +theorem _root_.ContinuousLinearMap.rTensor_eq_mapL (f : E →L[𝕜] F) : + f.rTensor G = mapL f (.id 𝕜 G) := by simp [mapL] + +variable (E) in +theorem _root_.ContinuousLinearMap.lTensor_eq_mapL (g : G →L[𝕜] H) : + g.lTensor E = mapL (.id 𝕜 E) g := by simp [mapL] + +@[simp] lemma _root_.ContinuousLinearMap.lTensor_comp_rTensor (f : E →L[𝕜] F) (g : G →L[𝕜] H) : + f.lTensor H ∘L g.rTensor E = mapL g f := by ext; simp [← LinearMap.lTensor_comp_rTensor] + +@[simp] lemma _root_.ContinuousLinearMap.rTensor_comp_lTensor (f : E →L[𝕜] F) (g : G →L[𝕜] H) : + f.rTensor H ∘L g.lTensor E = mapL f g := rfl + +@[simp] theorem adjoint_mapL [CompleteSpace E] [CompleteSpace G] [CompleteSpace (E ⊗[𝕜] G)] + [CompleteSpace F] [CompleteSpace H] [CompleteSpace (F ⊗[𝕜] H)] + (f : E →L[𝕜] F) (g : G →L[𝕜] H) : (mapL f g).adjoint = mapL f.adjoint g.adjoint := by + apply ContinuousLinearMap.coe_inj.mp <| ext' ?_ + simp [TensorProduct.ext_iff_inner_right, ContinuousLinearMap.adjoint_inner_left] + +variable (G) in +@[simp] theorem _root_.ContinuousLinearMap.adjoint_rTensor [CompleteSpace E] [CompleteSpace G] + [CompleteSpace (E ⊗[𝕜] G)] [CompleteSpace (F ⊗[𝕜] G)] [CompleteSpace F] (f : E →L[𝕜] F) : + (f.rTensor G).adjoint = f.adjoint.rTensor G := by simp [ContinuousLinearMap.rTensor_eq_mapL] + +variable (E) in +@[simp] theorem _root_.ContinuousLinearMap.adjoint_lTensor [CompleteSpace E] [CompleteSpace G] + [CompleteSpace (E ⊗[𝕜] H)] [CompleteSpace (E ⊗[𝕜] G)] [CompleteSpace H] (g : G →L[𝕜] H) : + (g.lTensor E).adjoint = g.adjoint.lTensor E := by simp [ContinuousLinearMap.lTensor_eq_mapL] open LinearMap +@[simp] theorem adjoint_map [FiniteDimensional 𝕜 E] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 G] + [FiniteDimensional 𝕜 H] (f : E →ₗ[𝕜] F) (g : G →ₗ[𝕜] H) : + (map f g).adjoint = map f.adjoint g.adjoint := + ext' fun _ _ => by simp [TensorProduct.ext_iff_inner_right, adjoint_inner_left] + @[simp] theorem _root_.LinearMap.adjoint_rTensor [FiniteDimensional 𝕜 E] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 G] (f : E →ₗ[𝕜] F) : - adjoint (rTensor G f) = rTensor G f.adjoint := by simp [rTensor] + (f.rTensor G).adjoint = f.adjoint.rTensor G := by simp [rTensor] @[simp] theorem _root_.LinearMap.adjoint_lTensor [FiniteDimensional 𝕜 E] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 G] (f : E →ₗ[𝕜] F) : - adjoint (lTensor G f) = lTensor G f.adjoint := by simp [lTensor] + (f.lTensor G).adjoint = f.adjoint.lTensor G := by simp [lTensor] /-- Given `x, y : E ⊗ (F ⊗ G)`, `x = y` iff `⟪x, a ⊗ₜ (b ⊗ₜ c)⟫ = ⟪y, a ⊗ₜ (b ⊗ₜ c)⟫` for all `a, b, c`. diff --git a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean index 9ab76683e106c2..bca3379c205e6f 100644 --- a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean +++ b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean @@ -284,6 +284,9 @@ theorem diam_range : Metric.diam (range f) = Metric.diam (univ : Set E) := def toContinuousLinearMap : E →SL[σ₁₂] E₂ := ⟨f.toLinearMap, f.continuous⟩ +@[simp] lemma toLinearMap_toContinuousLinearMap (f : E →ₛₗᵢ[σ₁₂] E₂) : + f.toContinuousLinearMap.toLinearMap = f.toLinearMap := rfl + theorem toContinuousLinearMap_injective : Function.Injective (toContinuousLinearMap : _ → E →SL[σ₁₂] E₂) := fun x _ h => coe_injective (congr_arg _ h : ⇑x.toContinuousLinearMap = _) From 8ac592862756bcd5db9a253c60e2707a83882524 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:40:30 +0000 Subject: [PATCH 0490/1300] chore(Combinatorics/SimpleGraph/Acyclic): golf `IsAcyclic.path_unique` (#40818) using #33506 --- .../Combinatorics/SimpleGraph/Acyclic.lean | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index 3e06e3752f8d9f..18e6d521401d7b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -186,31 +186,8 @@ alias isAcyclic_iff_forall_edge_isBridge := isAcyclic_iff_forall_isBridge theorem IsAcyclic.path_unique {G : SimpleGraph V} (h : G.IsAcyclic) {v w : V} (p q : G.Path v w) : p = q := by - obtain ⟨p, hp⟩ := p - obtain ⟨q, hq⟩ := q - rw [Subtype.mk.injEq] - induction p with - | nil => - exact isPath_iff_nil.mp hq |>.eq_nil.symm - | @cons u v _ ph p ih => - rw [isAcyclic_iff_forall_isBridge] at h - specialize h (e := s(u, v)) (by simpa) - rw [isBridge_iff_forall_walk_mem_edges] at h - replace h := h (q.append p.reverse) - simp only [Walk.edges_append, Walk.edges_reverse, List.mem_append, List.mem_reverse] at h - rcases h with h | h - · cases q with - | nil => simp at hp - | cons _ q => - rw [Walk.cons_isPath_iff] at hp hq - simp only [Walk.edges_cons, List.mem_cons, Sym2.eq_iff, true_and] at h - rcases h with (⟨h, rfl⟩ | ⟨rfl, rfl⟩) | h - · cases ih hp.1 q hq.1 - rfl - · simp at hq - · exact absurd (Walk.fst_mem_support_of_mem_edges _ h) hq.2 - · rw [Walk.cons_isPath_iff] at hp - exact absurd (Walk.fst_mem_support_of_mem_edges _ h) hp.2 + have := p.isPath.exists_isCycle_of_ne q.isPath + grind [IsAcyclic, Subtype.coe_inj] theorem isAcyclic_of_path_unique (h : ∀ (v w : V) (p q : G.Path v w), p = q) : G.IsAcyclic := by intro v c hc From d6e37a2f76514294c46b423b03ac3faddf51bcc4 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Tue, 30 Jun 2026 21:02:39 +0000 Subject: [PATCH 0491/1300] chore(SimpleGraph): move `cycleGraph` to its own file (#37930) PR #34797 re-defined `cycleGraph` independent of `circulantGraph`. Now move the definition of `cycleGraph` to its own file so that the definition can be used without importing the algebra hierarchy. --- Mathlib.lean | 1 + .../Combinatorics/SimpleGraph/Circulant.lean | 147 +-------------- .../Combinatorics/SimpleGraph/CycleGraph.lean | 169 ++++++++++++++++++ 3 files changed, 171 insertions(+), 146 deletions(-) create mode 100644 Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean diff --git a/Mathlib.lean b/Mathlib.lean index 95dbf986d7e640..ff49b998f216bb 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3631,6 +3631,7 @@ public import Mathlib.Combinatorics.SimpleGraph.Connectivity.Subgraph public import Mathlib.Combinatorics.SimpleGraph.Connectivity.WalkCounting public import Mathlib.Combinatorics.SimpleGraph.Connectivity.WalkDecomp public import Mathlib.Combinatorics.SimpleGraph.Copy +public import Mathlib.Combinatorics.SimpleGraph.CycleGraph public import Mathlib.Combinatorics.SimpleGraph.Dart public import Mathlib.Combinatorics.SimpleGraph.DegreeSum public import Mathlib.Combinatorics.SimpleGraph.DeleteEdges diff --git a/Mathlib/Combinatorics/SimpleGraph/Circulant.lean b/Mathlib/Combinatorics/SimpleGraph/Circulant.lean index 3ef93ddc16cd5f..e206f4e14024ba 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Circulant.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Circulant.lean @@ -5,9 +5,8 @@ Authors: Iván Renison, Bhavik Mehta -/ module -public import Mathlib.Algebra.Group.Fin.Basic -public import Mathlib.Combinatorics.SimpleGraph.Hasse public import Mathlib.Algebra.Group.Pointwise.Set.Basic +public import Mathlib.Combinatorics.SimpleGraph.CycleGraph /-! # Definition of circulant graphs @@ -19,15 +18,12 @@ are adjacent if and only if `u - v ∈ s` or `v - u ∈ s`. The elements of `s` ## Main declarations * `SimpleGraph.circulantGraph s`: the circulant graph over `G` with jumps `s`. -* `SimpleGraph.cycleGraph n`: the cycle graph over `Fin n`. -/ @[expose] public section namespace SimpleGraph -open Walk - /-- Circulant graph over additive group `G` with jumps `s` -/ @[simps!] def circulantGraph {G : Type*} [AddGroup G] (s : Set G) : SimpleGraph G := @@ -60,150 +56,9 @@ instance [DecidableEq G] [DecidablePred (· ∈ s)] : DecidableRel (circulantGra theorem circulantGraph_adj_translate {s : Set G} {u v d : G} : (circulantGraph s).Adj (u + d) (v + d) ↔ (circulantGraph s).Adj u v := by simp -/-- Cycle graph over `Fin n` -/ -def cycleGraph : (n : ℕ) → SimpleGraph (Fin n) - | 0 | 1 => ⊥ - | _ + 2 => { - Adj a b := a - b = 1 ∨ b - a = 1 - } - -instance : (n : ℕ) → DecidableRel (cycleGraph n).Adj - | 0 | 1 => fun _ _ => inferInstanceAs (Decidable False) - | _ + 2 => by unfold cycleGraph; infer_instance - theorem cycleGraph_eq_circulantGraph (n : ℕ) : cycleGraph (n + 1) = circulantGraph {1} := by cases n · exact edgeFinset_inj.mp rfl · aesop -theorem cycleGraph_zero_adj {u v : Fin 0} : ¬(cycleGraph 0).Adj u v := id - -theorem cycleGraph_zero_eq_bot : cycleGraph 0 = ⊥ := Subsingleton.elim _ _ -theorem cycleGraph_one_eq_bot : cycleGraph 1 = ⊥ := Subsingleton.elim _ _ -theorem cycleGraph_zero_eq_top : cycleGraph 0 = ⊤ := Subsingleton.elim _ _ -theorem cycleGraph_one_eq_top : cycleGraph 1 = ⊤ := Subsingleton.elim _ _ - -theorem cycleGraph_two_eq_top : cycleGraph 2 = ⊤ := by - simp only [SimpleGraph.ext_iff, funext_iff] - decide - -theorem cycleGraph_three_eq_top : cycleGraph 3 = ⊤ := by - simp only [SimpleGraph.ext_iff, funext_iff] - decide - -theorem cycleGraph_one_adj {u v : Fin 1} : ¬(cycleGraph 1).Adj u v := by - simp [cycleGraph_one_eq_bot] - -theorem cycleGraph_adj {n : ℕ} {u v : Fin (n + 2)} : - (cycleGraph (n + 2)).Adj u v ↔ u - v = 1 ∨ v - u = 1 := Iff.rfl - -theorem cycleGraph_adj' {n : ℕ} {u v : Fin n} : - (cycleGraph n).Adj u v ↔ (u - v).val = 1 ∨ (v - u).val = 1 := by - match n with - | 0 => exact u.elim0 - | 1 => simp [cycleGraph_one_adj] - | n + 2 => simp [cycleGraph_adj, Fin.ext_iff] - -theorem cycleGraph_neighborSet {n : ℕ} {v : Fin (n + 2)} : - (cycleGraph (n + 2)).neighborSet v = {v - 1, v + 1} := by - ext w - simp only [mem_neighborSet, Set.mem_insert_iff, Set.mem_singleton_iff] - rw [cycleGraph_adj, sub_eq_iff_eq_add', sub_eq_iff_eq_add', eq_sub_iff_add_eq, eq_comm] - -theorem cycleGraph_neighborFinset {n : ℕ} {v : Fin (n + 2)} : - (cycleGraph (n + 2)).neighborFinset v = {v - 1, v + 1} := by - simp [neighborFinset, cycleGraph_neighborSet] - -theorem cycleGraph_degree_two_le {n : ℕ} {v : Fin (n + 2)} : - (cycleGraph (n + 2)).degree v = Finset.card {v - 1, v + 1} := by - rw [SimpleGraph.degree, cycleGraph_neighborFinset] - -theorem cycleGraph_degree_three_le {n : ℕ} {v : Fin (n + 3)} : - (cycleGraph (n + 3)).degree v = 2 := by - rw [cycleGraph_degree_two_le, Finset.card_pair] - simp only [ne_eq, sub_eq_iff_eq_add, add_assoc v, left_eq_add] - exact ne_of_beq_false rfl - -theorem pathGraph_le_cycleGraph {n : ℕ} : pathGraph n ≤ cycleGraph n := by - match n with - | 0 | 1 => simp - | n + 2 => - intro u v h - rw [pathGraph_adj] at h - rw [cycleGraph_adj'] - cases h with - | inl h | inr h => - simp [Fin.coe_sub_iff_le.mpr (Nat.lt_of_succ_le h.le).le, Nat.eq_sub_of_add_eq' h] - -theorem cycleGraph_preconnected {n : ℕ} : (cycleGraph n).Preconnected := - (pathGraph_preconnected n).mono pathGraph_le_cycleGraph - -theorem cycleGraph_connected {n : ℕ} : (cycleGraph (n + 1)).Connected := - (pathGraph_connected n).mono pathGraph_le_cycleGraph - -section cycle - -set_option backward.privateInPublic true in -private def cycleGraph.cycleCons (n : ℕ) : ∀ m : Fin (n + 3), (cycleGraph (n + 3)).Walk m 0 - | ⟨0, h⟩ => Walk.nil - | ⟨m + 1, h⟩ => - have hadj : (cycleGraph (n + 3)).Adj ⟨m + 1, h⟩ ⟨m, Nat.lt_of_succ_lt h⟩ := by - simp [cycleGraph_adj, Fin.ext_iff, Fin.sub_val_of_le] - Walk.cons hadj (cycleGraph.cycleCons n ⟨m, Nat.lt_of_succ_lt h⟩) - -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in -/-- The Eulerian cycle of `cycleGraph (n + 3)` -/ -def cycleGraph.cycle (n : ℕ) : (cycleGraph (n + 3)).Walk 0 0 := - have hadj : (cycleGraph (n + 3)).Adj 0 (Fin.last (n + 2)) := by - simp [cycleGraph_adj] - Walk.cons hadj (cycleGraph.cycleCons n (Fin.last (n + 2))) - -@[deprecated (since := "2026-02-15")] -alias cycleGraph_EulerianCircuit := cycleGraph.cycle - -private theorem cycleGraph.length_cycle_cons (n : ℕ) : - ∀ m : Fin (n + 3), (cycleGraph.cycleCons n m).length = m.val - | ⟨0, h⟩ => by - unfold cycleGraph.cycleCons - rfl - | ⟨m + 1, h⟩ => by - unfold cycleGraph.cycleCons - simp only [Walk.length_cons] - rw [cycleGraph.length_cycle_cons n] - -variable {n : ℕ} - -@[simp, grind =] -theorem cycleGraph.length_cycle : (cycleGraph.cycle n).length = n + 3 := by - unfold cycleGraph.cycle - simp [cycleGraph.length_cycle_cons] - -@[deprecated (since := "2026-02-15")] -alias cycleGraph_EulerianCircuit_length := cycleGraph.length_cycle - -private theorem cycleGraph.getVert_cycleCons (m : Fin (n + 3)) (i : ℕ) (hi : i ≤ m.val) : - (cycleGraph.cycleCons n m).getVert i = (m - i) % (n + 3) := by - obtain ⟨m, hm⟩ := m - induction i generalizing m - · simp [Nat.mod_eq_of_lt hm] - · cases m <;> grind +locals [getVert_cons_succ] - -theorem cycleGraph.getVert_cycle {m : ℕ} (hm : m ≤ n + 3) : - (cycleGraph.cycle n).getVert m = ⟨(n + 3 - m) % (n + 3), Nat.mod_lt _ (by lia)⟩ := by - cases m - · simp - · grind +locals [getVert_cons_succ, cycleGraph.getVert_cycleCons] - -theorem cycleGraph.isPath_tail_cycle : (cycleGraph.cycle n).tail.IsPath := by - refine isPath_iff_injective_get_support _ |>.mpr fun ⟨i, hi⟩ ⟨j, hj⟩ hij ↦ ?_ - rw [support_tail_of_not_nil _ (of_decide_eq_false rfl)] at hi hj - simp only [List.get_eq_getElem, support_getElem_eq_getVert, getVert_tail] at hij - grind [← Nat.mod_eq_of_lt, cycleGraph.getVert_cycle] - -theorem cycleGraph.isCycle_cycle : (cycleGraph.cycle n).IsCycle := - isCycle_iff_isPath_tail_and_le_length.mpr ⟨cycleGraph.isPath_tail_cycle, by simp⟩ - -end cycle - end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean b/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean new file mode 100644 index 00000000000000..60f046bbb2fded --- /dev/null +++ b/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean @@ -0,0 +1,169 @@ +/- +Copyright (c) 2024 Iván Renison, Bhavik Mehta. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Iván Renison, Bhavik Mehta +-/ +module + +public import Mathlib.Combinatorics.SimpleGraph.Hasse + +/-! +# Definition of cycle graphs + +This file defines and proves several fact about cycle graphs on `n` vertices and the cycle around +the cycle graph when `n ≥ 3`. + +## Main declarations + +* `SimpleGraph.cycleGraph n`: the cycle graph over `Fin n`. +* `(SimpleGraph.cycleGraph n).cycle`: the cycle around `cycleGraph (n + 3)` starting at 0. +-/ + +@[expose] public section + +namespace SimpleGraph + +open Walk + +/-- Cycle graph over `Fin n` -/ +def cycleGraph : (n : ℕ) → SimpleGraph (Fin n) + | 0 | 1 => ⊥ + | _ + 2 => { + Adj a b := a - b = 1 ∨ b - a = 1 + } + +instance : (n : ℕ) → DecidableRel (cycleGraph n).Adj + | 0 | 1 => fun _ _ => inferInstanceAs (Decidable False) + | _ + 2 => by unfold cycleGraph; infer_instance + +theorem cycleGraph_zero_adj {u v : Fin 0} : ¬(cycleGraph 0).Adj u v := id + +theorem cycleGraph_zero_eq_bot : cycleGraph 0 = ⊥ := Subsingleton.elim _ _ +theorem cycleGraph_one_eq_bot : cycleGraph 1 = ⊥ := Subsingleton.elim _ _ +theorem cycleGraph_zero_eq_top : cycleGraph 0 = ⊤ := Subsingleton.elim _ _ +theorem cycleGraph_one_eq_top : cycleGraph 1 = ⊤ := Subsingleton.elim _ _ + +theorem cycleGraph_two_eq_top : cycleGraph 2 = ⊤ := by + simp only [SimpleGraph.ext_iff, funext_iff] + decide + +theorem cycleGraph_three_eq_top : cycleGraph 3 = ⊤ := by + simp only [SimpleGraph.ext_iff, funext_iff] + decide + +theorem cycleGraph_one_adj {u v : Fin 1} : ¬(cycleGraph 1).Adj u v := by + simp [cycleGraph_one_eq_bot] + +theorem cycleGraph_adj {n : ℕ} {u v : Fin (n + 2)} : + (cycleGraph (n + 2)).Adj u v ↔ u - v = 1 ∨ v - u = 1 := Iff.rfl + +theorem cycleGraph_adj' {n : ℕ} {u v : Fin n} : + (cycleGraph n).Adj u v ↔ (u - v).val = 1 ∨ (v - u).val = 1 := by + match n with + | 0 => exact u.elim0 + | 1 => simp [cycleGraph_one_adj] + | n + 2 => simp [cycleGraph_adj, Fin.ext_iff] + +theorem cycleGraph_neighborSet {n : ℕ} {v : Fin (n + 2)} : + (cycleGraph (n + 2)).neighborSet v = {v - 1, v + 1} := by + ext w + simp only [mem_neighborSet, Set.mem_insert_iff, Set.mem_singleton_iff] + rw [cycleGraph_adj, sub_eq_iff_eq_add', sub_eq_iff_eq_add', eq_sub_iff_add_eq, eq_comm] + +theorem cycleGraph_neighborFinset {n : ℕ} {v : Fin (n + 2)} : + (cycleGraph (n + 2)).neighborFinset v = {v - 1, v + 1} := by + simp [neighborFinset, cycleGraph_neighborSet] + +theorem cycleGraph_degree_two_le {n : ℕ} {v : Fin (n + 2)} : + (cycleGraph (n + 2)).degree v = Finset.card {v - 1, v + 1} := by + rw [SimpleGraph.degree, cycleGraph_neighborFinset] + +theorem cycleGraph_degree_three_le {n : ℕ} {v : Fin (n + 3)} : + (cycleGraph (n + 3)).degree v = 2 := by + rw [cycleGraph_degree_two_le, Finset.card_pair] + simp only [ne_eq, sub_eq_iff_eq_add, add_assoc v, left_eq_add] + exact ne_of_beq_false rfl + +theorem pathGraph_le_cycleGraph {n : ℕ} : pathGraph n ≤ cycleGraph n := by + match n with + | 0 | 1 => simp + | n + 2 => + intro u v h + rw [pathGraph_adj] at h + rw [cycleGraph_adj'] + cases h with + | inl h | inr h => + simp [Fin.coe_sub_iff_le.mpr (Nat.lt_of_succ_le h.le).le, Nat.eq_sub_of_add_eq' h] + +theorem cycleGraph_preconnected {n : ℕ} : (cycleGraph n).Preconnected := + (pathGraph_preconnected n).mono pathGraph_le_cycleGraph + +theorem cycleGraph_connected {n : ℕ} : (cycleGraph (n + 1)).Connected := + (pathGraph_connected n).mono pathGraph_le_cycleGraph + +section cycle + +set_option backward.privateInPublic true in +private def cycleGraph.cycleCons (n : ℕ) : ∀ m : Fin (n + 3), (cycleGraph (n + 3)).Walk m 0 + | ⟨0, h⟩ => Walk.nil + | ⟨m + 1, h⟩ => + have hadj : (cycleGraph (n + 3)).Adj ⟨m + 1, h⟩ ⟨m, Nat.lt_of_succ_lt h⟩ := by + simp [cycleGraph_adj, Fin.ext_iff, Fin.sub_val_of_le] + Walk.cons hadj (cycleGraph.cycleCons n ⟨m, Nat.lt_of_succ_lt h⟩) + +set_option backward.privateInPublic true in +set_option backward.privateInPublic.warn false in +/-- The Eulerian cycle of `cycleGraph (n + 3)` -/ +def cycleGraph.cycle (n : ℕ) : (cycleGraph (n + 3)).Walk 0 0 := + have hadj : (cycleGraph (n + 3)).Adj 0 (Fin.last (n + 2)) := by + simp [cycleGraph_adj] + Walk.cons hadj (cycleGraph.cycleCons n (Fin.last (n + 2))) + +@[deprecated (since := "2026-02-15")] +alias cycleGraph_EulerianCircuit := cycleGraph.cycle + +private theorem cycleGraph.length_cycle_cons (n : ℕ) : + ∀ m : Fin (n + 3), (cycleGraph.cycleCons n m).length = m.val + | ⟨0, h⟩ => by + unfold cycleGraph.cycleCons + rfl + | ⟨m + 1, h⟩ => by + unfold cycleGraph.cycleCons + simp only [Walk.length_cons] + rw [cycleGraph.length_cycle_cons n] + +variable {n : ℕ} + +@[simp, grind =] +theorem cycleGraph.length_cycle : (cycleGraph.cycle n).length = n + 3 := by + unfold cycleGraph.cycle + simp [cycleGraph.length_cycle_cons] + +@[deprecated (since := "2026-02-15")] +alias cycleGraph_EulerianCircuit_length := cycleGraph.length_cycle + +private theorem cycleGraph.getVert_cycleCons (m : Fin (n + 3)) (i : ℕ) (hi : i ≤ m.val) : + (cycleGraph.cycleCons n m).getVert i = (m - i) % (n + 3) := by + obtain ⟨m, hm⟩ := m + induction i generalizing m + · simp [Nat.mod_eq_of_lt hm] + · cases m <;> grind +locals [getVert_cons_succ] + +theorem cycleGraph.getVert_cycle {m : ℕ} (hm : m ≤ n + 3) : + (cycleGraph.cycle n).getVert m = ⟨(n + 3 - m) % (n + 3), Nat.mod_lt _ (by lia)⟩ := by + cases m + · simp + · grind +locals [getVert_cons_succ, cycleGraph.getVert_cycleCons] + +theorem cycleGraph.isPath_tail_cycle : (cycleGraph.cycle n).tail.IsPath := by + refine isPath_iff_injective_get_support _ |>.mpr fun ⟨i, hi⟩ ⟨j, hj⟩ hij ↦ ?_ + rw [support_tail_of_not_nil _ (of_decide_eq_false rfl)] at hi hj + simp only [List.get_eq_getElem, support_getElem_eq_getVert, getVert_tail] at hij + grind [← Nat.mod_eq_of_lt, cycleGraph.getVert_cycle] + +theorem cycleGraph.isCycle_cycle : (cycleGraph.cycle n).IsCycle := + isCycle_iff_isPath_tail_and_le_length.mpr ⟨cycleGraph.isPath_tail_cycle, by simp⟩ + +end cycle + +end SimpleGraph From 1ce279678026a82a090c5e4089e4ece12dc175c3 Mon Sep 17 00:00:00 2001 From: Kevin Wilson <1527442+khwilson@users.noreply.github.com> Date: Tue, 30 Jun 2026 22:07:05 +0000 Subject: [PATCH 0492/1300] chore(Analysis/Convex/Gauge): rename lemmas involving `{x | prop (gauge s x)}` (#40710) Lemmas in `Mathlib.Analysis.Convex.Gauge` whose conclusions are of the form `{x | prop (gauge s x)}` are renamed to include `setOf_gauge` in the name rather than just `gauge` in line with recent work related to minkowski's second theorem. Deprecation aliases are added for all non-private renames. Two downstream callers (`AbsConvexOpen.lean`, `Bernstein.lean`) are updated to use the new names. Also moved `Balanced.starConvex` further up the import chain. AI Disclosure: Generated with claude code Co-authored-by: Kevin H Wilson --- Mathlib/Analysis/Convex/Gauge.lean | 63 ++++++++++++------- .../Analysis/LocallyConvex/AbsConvexOpen.lean | 2 +- Mathlib/Analysis/LocallyConvex/Basic.lean | 4 ++ .../Analysis/SpecialFunctions/Bernstein.lean | 2 +- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/Mathlib/Analysis/Convex/Gauge.lean b/Mathlib/Analysis/Convex/Gauge.lean index 6e2eea7f3179a9..f9f9a4716a3155 100644 --- a/Mathlib/Analysis/Convex/Gauge.lean +++ b/Mathlib/Analysis/Convex/Gauge.lean @@ -67,7 +67,7 @@ theorem gauge_def' : gauge s x = sInf {r ∈ Set.Ioi (0 : ℝ) | r⁻¹ • x congrm sInf {r | ?_} exact and_congr_right fun hr => mem_smul_set_iff_inv_smul_mem₀ hr.ne' _ _ -private theorem gauge_set_bddBelow : BddBelow { r : ℝ | 0 < r ∧ x ∈ r • s } := +private theorem bddBelow_gauge_set : BddBelow { r : ℝ | 0 < r ∧ x ∈ r • s } := ⟨0, fun _ hr => hr.1.le⟩ /-- If the given subset is `Absorbent` then the set we take an infimum over in `gauge` is nonempty, @@ -79,7 +79,7 @@ theorem Absorbent.gauge_set_nonempty (absorbs : Absorbent ℝ s) : theorem gauge_mono (hs : Absorbent ℝ s) (h : s ⊆ t) : gauge t ≤ gauge s := fun _ => by unfold gauge - gcongr; exacts [gauge_set_bddBelow, hs.gauge_set_nonempty] + gcongr; exacts [bddBelow_gauge_set, hs.gauge_set_nonempty] theorem exists_lt_of_gauge_lt (absorbs : Absorbent ℝ s) (h : gauge s x < a) : ∃ b, 0 < b ∧ b < a ∧ x ∈ b • s := by @@ -131,10 +131,10 @@ theorem gauge_neg_set_eq_gauge_neg (x : E) : gauge (-s) x = gauge s (-x) := by theorem gauge_le_of_mem (ha : 0 ≤ a) (hx : x ∈ a • s) : gauge s x ≤ a := by obtain rfl | ha' := ha.eq_or_lt · rw [mem_singleton_iff.1 (zero_smul_set_subset _ hx), gauge_zero] - · exact csInf_le gauge_set_bddBelow ⟨ha', hx⟩ + · exact csInf_le bddBelow_gauge_set ⟨ha', hx⟩ -theorem gauge_le_eq (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : Absorbent ℝ s) (ha : 0 ≤ a) : - { x | gauge s x ≤ a } = ⋂ (r : ℝ) (_ : a < r), r • s := by +theorem setOf_gauge_le_eq (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : Absorbent ℝ s) + (ha : 0 ≤ a) : { x | gauge s x ≤ a } = ⋂ (r : ℝ) (_ : a < r), r • s := by ext x simp_rw [Set.mem_iInter, Set.mem_setOf_eq] refine ⟨fun h r hr => ?_, fun h => le_of_forall_pos_lt_add fun ε hε => ?_⟩ @@ -148,7 +148,9 @@ theorem gauge_le_eq (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : Abso exact hδr.le · linarith [gauge_le_of_mem (by linarith) <| h (a + ε / 2) (by linarith)] -theorem gauge_lt_eq' (absorbs : Absorbent ℝ s) (a : ℝ) : +@[deprecated (since := "2026-06-17")] alias gauge_le_eq := setOf_gauge_le_eq + +theorem setOf_gauge_lt_eq' (absorbs : Absorbent ℝ s) (a : ℝ) : { x | gauge s x < a } = ⋃ (r : ℝ) (_ : 0 < r) (_ : r < a), r • s := by ext simp_rw [mem_setOf, mem_iUnion, exists_prop] @@ -156,7 +158,9 @@ theorem gauge_lt_eq' (absorbs : Absorbent ℝ s) (a : ℝ) : ⟨exists_lt_of_gauge_lt absorbs, fun ⟨r, hr₀, hr₁, hx⟩ => (gauge_le_of_mem hr₀.le hx).trans_lt hr₁⟩ -theorem gauge_lt_eq (absorbs : Absorbent ℝ s) (a : ℝ) : +@[deprecated (since := "2026-06-17")] alias gauge_lt_eq' := setOf_gauge_lt_eq' + +theorem setOf_gauge_lt_eq (absorbs : Absorbent ℝ s) (a : ℝ) : { x | gauge s x < a } = ⋃ r ∈ Set.Ioo 0 (a : ℝ), r • s := by ext simp_rw [mem_setOf, mem_iUnion, exists_prop, mem_Ioo, and_assoc] @@ -164,17 +168,22 @@ theorem gauge_lt_eq (absorbs : Absorbent ℝ s) (a : ℝ) : ⟨exists_lt_of_gauge_lt absorbs, fun ⟨r, hr₀, hr₁, hx⟩ => (gauge_le_of_mem hr₀.le hx).trans_lt hr₁⟩ +@[deprecated (since := "2026-06-17")] alias gauge_lt_eq := setOf_gauge_lt_eq + theorem mem_openSegment_of_gauge_lt_one (absorbs : Absorbent ℝ s) (hgauge : gauge s x < 1) : ∃ y ∈ s, x ∈ openSegment ℝ 0 y := by rcases exists_lt_of_gauge_lt absorbs hgauge with ⟨r, hr₀, hr₁, y, hy, rfl⟩ refine ⟨y, hy, 1 - r, r, ?_⟩ simp [*] -theorem gauge_lt_one_subset_self (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Absorbent ℝ s) : - { x | gauge s x < 1 } ⊆ s := fun _x hx ↦ +theorem setOf_gauge_lt_one_subset_self (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) + (absorbs : Absorbent ℝ s) : { x | gauge s x < 1 } ⊆ s := fun _x hx ↦ let ⟨_y, hys, hx⟩ := mem_openSegment_of_gauge_lt_one absorbs hx hs.openSegment_subset h₀ hys hx +@[deprecated (since := "2026-06-17")] +alias gauge_lt_one_subset_self := setOf_gauge_lt_one_subset_self + theorem gauge_le_one_of_mem {x : E} (hx : x ∈ s) : gauge s x ≤ 1 := gauge_le_of_mem zero_le_one <| by rwa [one_smul] @@ -196,19 +205,20 @@ theorem gauge_sum_le {ι : Type*} (hs : Convex ℝ s) (absorbs : Absorbent ℝ s (f : ι → E) : gauge s (∑ i ∈ t, f i) ≤ ∑ i ∈ t, gauge s (f i) := Finset.le_sum_of_subadditive _ gauge_zero.le (gauge_add_le hs absorbs) _ _ -theorem self_subset_gauge_le_one : s ⊆ { x | gauge s x ≤ 1 } := fun _ => gauge_le_one_of_mem +theorem self_subset_setOf_gauge_le_one : s ⊆ { x | gauge s x ≤ 1 } := fun _ => gauge_le_one_of_mem -theorem Convex.gauge_le (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Absorbent ℝ s) (a : ℝ) : - Convex ℝ { x | gauge s x ≤ a } := by +@[deprecated (since := "2026-06-17")] +alias self_subset_gauge_le_one := self_subset_setOf_gauge_le_one + +theorem Convex.setOf_gauge_le (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Absorbent ℝ s) + (a : ℝ) : Convex ℝ { x | gauge s x ≤ a } := by by_cases ha : 0 ≤ a - · rw [gauge_le_eq hs h₀ absorbs ha] + · rw [setOf_gauge_le_eq hs h₀ absorbs ha] exact convex_iInter fun i => convex_iInter fun _ => hs.smul _ · convert! convex_empty (𝕜 := ℝ) exact eq_empty_iff_forall_notMem.2 fun x hx => ha <| (gauge_nonneg _).trans hx -theorem Balanced.starConvex (hs : Balanced ℝ s) : StarConvex ℝ 0 s := - starConvex_zero_iff.2 fun _ hx a ha₀ ha₁ => - hs _ (by rwa [Real.norm_of_nonneg ha₀]) (smul_mem_smul_set hx) +@[deprecated (since := "2026-06-17")] alias Convex.gauge_le := Convex.setOf_gauge_le theorem le_gauge_of_notMem (hs₀ : StarConvex ℝ 0 s) (hs₂ : Absorbs ℝ s {x}) (hx : x ∉ a • s) : a ≤ gauge s x := by @@ -357,12 +367,16 @@ theorem interior_subset_gauge_lt_one (s : Set E) : interior s ⊆ { x | gauge s rcases H₂.exists with ⟨r, hxr, hr₀, hr₁⟩ exact (gauge_le_of_mem hr₀.le hxr).trans_lt hr₁ -theorem gauge_lt_one_eq_self_of_isOpen (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : IsOpen s) : - { x | gauge s x < 1 } = s := by - refine (gauge_lt_one_subset_self hs₁ ‹_› <| absorbent_nhds_zero <| hs₂.mem_nhds hs₀).antisymm ?_ +theorem setOf_gauge_lt_one_eq_self_of_isOpen (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) + (hs₂ : IsOpen s) : { x | gauge s x < 1 } = s := by + refine (setOf_gauge_lt_one_subset_self hs₁ ‹_› <| absorbent_nhds_zero <| + hs₂.mem_nhds hs₀).antisymm ?_ convert! interior_subset_gauge_lt_one s exact hs₂.interior_eq.symm +@[deprecated (since := "2026-06-17")] +alias gauge_lt_one_eq_self_of_isOpen := setOf_gauge_lt_one_eq_self_of_isOpen + theorem gauge_lt_one_of_mem_of_isOpen (hs₂ : IsOpen s) {x : E} (hx : x ∈ s) : gauge s x < 1 := interior_subset_gauge_lt_one s <| by rwa [hs₂.interior_eq] @@ -378,7 +392,7 @@ theorem mem_closure_of_gauge_le_one (hc : Convex ℝ s) (hs₀ : 0 ∈ s) (ha : (h : gauge s x ≤ 1) : x ∈ closure s := by have : ∀ᶠ r : ℝ in 𝓝[<] 1, r • x ∈ s := by filter_upwards [Ico_mem_nhdsLT one_pos] with r ⟨hr₀, hr₁⟩ - apply gauge_lt_one_subset_self hc hs₀ ha + apply setOf_gauge_lt_one_subset_self hc hs₀ ha rw [mem_setOf_eq, gauge_smul_of_nonneg hr₀] exact mul_lt_one_of_nonneg_of_lt_one_left hr₀ hr₁ h refine mem_closure_of_tendsto ?_ this @@ -446,15 +460,18 @@ is continuous. If the ambient space is a normed space, then `gauge s` is Lipschi theorem continuous_gauge (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : Continuous (gauge s) := continuous_iff_continuousAt.2 fun _ ↦ continuousAt_gauge hc hs₀ -theorem gauge_lt_one_eq_interior (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : +theorem setOf_gauge_lt_one_eq_interior (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : { x | gauge s x < 1 } = interior s := by refine Subset.antisymm (fun x hx ↦ ?_) (interior_subset_gauge_lt_one s) rcases mem_openSegment_of_gauge_lt_one (absorbent_nhds_zero hs₀) hx with ⟨y, hys, hxy⟩ exact hc.openSegment_interior_self_subset_interior (mem_interior_iff_mem_nhds.2 hs₀) hys hxy +@[deprecated (since := "2026-06-17")] +alias gauge_lt_one_eq_interior := setOf_gauge_lt_one_eq_interior + theorem gauge_lt_one_iff_mem_interior (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : gauge s x < 1 ↔ x ∈ interior s := - Set.ext_iff.1 (gauge_lt_one_eq_interior hc hs₀) _ + Set.ext_iff.1 (setOf_gauge_lt_one_eq_interior hc hs₀) _ theorem gauge_le_one_iff_mem_closure (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : gauge s x ≤ 1 ↔ x ∈ closure s := @@ -487,7 +504,7 @@ theorem gaugeSeminorm_lt_one_of_isOpen (hs : IsOpen s) {x : E} (hx : x ∈ s) : theorem gaugeSeminorm_ball_one (hs : IsOpen s) : (gaugeSeminorm hs₀ hs₁ hs₂).ball 0 1 = s := by rw [Seminorm.ball_zero_eq] - exact gauge_lt_one_eq_self_of_isOpen hs₁ hs₂.zero_mem hs + exact setOf_gauge_lt_one_eq_self_of_isOpen hs₁ hs₂.zero_mem hs end RCLike diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean index 812c09cfba3a10..3ea3c4d5852ae0 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean @@ -100,7 +100,7 @@ theorem gaugeSeminormFamily_ball (s : AbsConvexOpenSets 𝕜 E) : dsimp only [gaugeSeminormFamily] rw [Seminorm.ball_zero_eq] simp_rw [gaugeSeminorm_toFun] - exact gauge_lt_one_eq_self_of_isOpen (s.coe_convex.lift ℝ) s.coe_zero_mem s.coe_isOpen + exact setOf_gauge_lt_one_eq_self_of_isOpen (s.coe_convex.lift ℝ) s.coe_zero_mem s.coe_isOpen variable [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] variable [LocallyConvexSpace 𝕜 E] diff --git a/Mathlib/Analysis/LocallyConvex/Basic.lean b/Mathlib/Analysis/LocallyConvex/Basic.lean index 33fa61bc088e4b..cdfd69065a23f7 100644 --- a/Mathlib/Analysis/LocallyConvex/Basic.lean +++ b/Mathlib/Analysis/LocallyConvex/Basic.lean @@ -305,4 +305,8 @@ theorem balanced_iff_neg_mem (hs : Convex ℝ s) : Balanced ℝ s ↔ ∀ ⦃x exact hs (h hx) hx (div_nonneg (sub_nonneg_of_le ha.2) zero_le_two) (div_nonneg (sub_nonneg_of_le ha.1) zero_le_two) (by ring) +theorem Balanced.starConvex (hs : Balanced ℝ s) : StarConvex ℝ 0 s := + starConvex_zero_iff.2 fun _ hx a ha₀ ha₁ => + hs _ (by rwa [Real.norm_of_nonneg ha₀]) (smul_mem_smul_set hx) + end Real diff --git a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean index ca7fffbc5653b5..b6bbf6d738c11c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean +++ b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean @@ -193,7 +193,7 @@ theorem bernsteinApproximation_uniform [LocallyConvexSpace ℝ E] (f : C(I, E)) |>.compactConvergenceUniformity_of_compact |> nhds_basis_uniformity |>.tendsto_right_iff] rintro U ⟨hU₀, hcU⟩ filter_upwards [this U hU₀ hcU] with n hn x - exact gauge_lt_one_subset_self hcU (mem_of_mem_nhds hU₀) (absorbent_nhds_zero hU₀) (hn x) + exact setOf_gauge_lt_one_subset_self hcU (mem_of_mem_nhds hU₀) (absorbent_nhds_zero hU₀) (hn x) intro U hU₀ hUc /- Choose a constant `C` such that `‖f x - f y‖_U ≤ C` for all `x`, `y`. For a normed space, this would be twice the norm of `f`. -/ From 8e2ecc9911c93836f2b425b1c4eeb820dab2bfdf Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Tue, 30 Jun 2026 22:28:45 +0000 Subject: [PATCH 0493/1300] feat(SimpleGraph): add universal vertex predicate (#38589) Add the predicate `G.IsUniversal v` to indicate that `v` is a universal vertex, i.e. connected to all other vertices in `G`. This matches the recently added `G.IsIsolated v` predicate for isolated vertices. Co-authored-by: Justin Lai --- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 64 ++++++++++++++++++- .../SimpleGraph/Connectivity/Connected.lean | 11 ++++ Mathlib/Combinatorics/SimpleGraph/Finite.lean | 22 +++++++ Mathlib/Combinatorics/SimpleGraph/Star.lean | 15 +++-- Mathlib/Combinatorics/SimpleGraph/Tutte.lean | 14 ++-- .../SimpleGraph/UniversalVerts.lean | 6 +- 6 files changed, 114 insertions(+), 18 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index e5a45faaf3d37a..7f274aa1ba3bcc 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -1019,10 +1019,72 @@ theorem Adj.not_isIsolated_right (h : G.Adj u v) : ¬G.IsIsolated v := h.symm.not_isIsolated_left @[simp] -theorem isIsolated_bot : IsIsolated ⊥ v := +protected theorem IsIsolated.bot : IsIsolated ⊥ v := neighborSet_eq_empty _ |>.mp neighborSet_bot +@[deprecated (since := "2026-06-19")] +alias isIsolated_bot := IsIsolated.bot + theorem eq_bot_iff_isIsolated : G = ⊥ ↔ ∀ v, G.IsIsolated v := by simp [eq_bot_iff_forall_not_adj, ← neighborSet_eq_empty, Set.eq_empty_iff_forall_notMem] +section IsUniversal + +variable {G} + +/-- A vertex in a graph is universal if it's adjacent to every other vertex. -/ +def IsUniversal (G : SimpleGraph V) (v : V) : Prop := ∀ ⦃w⦄, v ≠ w → G.Adj v w + +@[simp] lemma insert_neighborSet_eq_univ : + insert v (G.neighborSet v) = Set.univ ↔ G.IsUniversal v := by + simp only [Set.ext_iff, Set.mem_insert_iff, mem_neighborSet, IsUniversal] + grind + +@[simp] lemma neighborSet_eq_compl_singleton : G.neighborSet v = {v}ᶜ ↔ G.IsUniversal v := by + grind [insert_neighborSet_eq_univ, notMem_neighborSet_self] + +protected alias ⟨IsUniversal.of_neighborSet_eq, IsUniversal.neighborSet_eq⟩ := + neighborSet_eq_compl_singleton + +@[simp] +theorem IsUniversal.of_subsingleton [Subsingleton V] : G.IsUniversal v := + fun _ hne ↦ False.elim <| hne (Subsingleton.elim ..) + +theorem IsUniversal.not_isIsolated [Nontrivial V] (h : G.IsUniversal v) (w : V) : + ¬G.IsIsolated w := by + by_cases h' : v = w + · obtain ⟨u, hu⟩ := exists_ne v + exact h' ▸ Adj.not_isIsolated_left (h hu.symm) + · exact Adj.not_isIsolated_right (h h') + +theorem IsIsolated.not_isUniversal [Nontrivial V] (h : G.IsIsolated v) (w : V) : + ¬G.IsUniversal w := by + contrapose! h + exact h.not_isIsolated v + +@[simp] +theorem isUniversal_compl_iff_isIsolated : Gᶜ.IsUniversal v ↔ G.IsIsolated v := by + refine ⟨fun h x hx ↦ ?_, fun h x hx ↦ ?_⟩ + · simpa [hx] using h hx.ne + · simpa [hx] using h x + +alias ⟨IsIsolated.of_isUniversal_compl, _⟩ := isUniversal_compl_iff_isIsolated + +@[simp] +theorem isIsolated_compl_iff_isUniversal : Gᶜ.IsIsolated v ↔ G.IsUniversal v := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · simpa using isUniversal_compl_iff_isIsolated.mpr h + · exact isUniversal_compl_iff_isIsolated.mp (by simpa) + +alias ⟨IsUniversal.of_isIsolated_compl, _⟩ := isIsolated_compl_iff_isUniversal + +theorem eq_top_iff_forall_isUniversal : G = ⊤ ↔ ∀ v, G.IsUniversal v := by + simp [eq_top_iff_forall_ne_adj, IsUniversal] + +@[simp] +protected theorem IsUniversal.top : IsUniversal ⊤ v := + eq_top_iff_forall_isUniversal.mp rfl v + +end IsUniversal + end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean index d0cffcec45ec13..d0cabb0db4a0e8 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean @@ -197,6 +197,12 @@ lemma Reachable.degree_pos_right {G : SimpleGraph V} {u v : V} [Fintype (G.neigh (huv : u ≠ v) (hreach : G.Reachable u v) : 0 < G.degree v := hreach.symm.degree_pos_left huv.symm +lemma Reachable.of_isUniversal {G : SimpleGraph V} {u : V} (v : V) (h : G.IsUniversal u) : + G.Reachable u v := by + by_cases! h' : u = v + · exact h' ▸ Reachable.rfl + · exact (h h').reachable + lemma not_reachable_of_neighborSet_left_eq_empty {G : SimpleGraph V} {u v : V} (huv : u ≠ v) (hu : G.neighborSet u = ∅) : ¬G.Reachable u v := (Reachable.nonempty_neighborSet_left huv).mt (Set.not_nonempty_iff_eq_empty.mpr hu) @@ -374,6 +380,11 @@ theorem connected_or_preconnected_compl : G.Connected ∨ Gᶜ.Preconnected := b theorem connected_or_connected_compl [Nonempty V] : G.Connected ∨ Gᶜ.Connected := G.connected_or_preconnected_compl.elim .inl (.inr ⟨·⟩) +variable {G v} in +lemma Connected.of_isUniversal (h : G.IsUniversal v) : G.Connected := by + refine connected_iff _ |>.mpr ⟨fun u w ↦ ?_, ⟨v⟩⟩ + exact (Reachable.of_isUniversal u h).symm.trans (Reachable.of_isUniversal w h) + /-- The quotient of `V` by the `SimpleGraph.Reachable` relation gives the connected components of a graph. -/ def ConnectedComponent := Quot G.Reachable diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index a3f9f29851e7b6..e8b42995533a41 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -547,6 +547,28 @@ theorem card_commonNeighbors_top [DecidableEq V] {v w : V} (h : v ≠ w) : Fintype.card (commonNeighbors ⊤ v w) = Fintype.card V - 2 := by simp [commonNeighbors_top_eq, ← Set.toFinset_card, Finset.card_sdiff, h] +@[simp] lemma insert_neighborFinset_eq_univ [DecidableEq V] [DecidableRel G.Adj] (v : V) : + insert v (G.neighborFinset v) = univ ↔ G.IsUniversal v := by + simp only [Finset.ext_iff, mem_insert, mem_neighborFinset, IsUniversal] + grind + +@[simp] lemma neighborFinset_eq_erase_univ [DecidableEq V] [DecidableRel G.Adj] (v : V) : + G.neighborFinset v = univ.erase v ↔ G.IsUniversal v := by + grind [insert_neighborFinset_eq_univ, notMem_neighborFinset_self] + +@[simp] +lemma degree_eq_card_sub_one [DecidableRel G.Adj] (v : V) : + G.degree v = Fintype.card V - 1 ↔ G.IsUniversal v := by + classical + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · rw [← G.insert_neighborFinset_eq_univ v, ← Finset.card_eq_iff_eq_univ] + simp [h, Nat.sub_add_cancel <| Fintype.card_pos_iff.mpr ⟨v⟩] + · simp [← card_neighborFinset_eq_degree, (G.neighborFinset_eq_erase_univ v).mpr h] + +lemma degree_lt_card_sub_one [DecidableRel G.Adj] (v : V) : + G.degree v < Fintype.card V - 1 ↔ ¬ G.IsUniversal v := by + grind [degree_eq_card_sub_one, Nat.le_sub_one_of_lt <| G.degree_lt_card_verts v] + end Finite namespace Iso diff --git a/Mathlib/Combinatorics/SimpleGraph/Star.lean b/Mathlib/Combinatorics/SimpleGraph/Star.lean index 13dc86ac80611e..24d026a8c3b2de 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Star.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Star.lean @@ -43,6 +43,11 @@ instance [DecidableEq V] (r : V) : DecidableRel (starGraph r).Adj := lemma starGraph_adj {r x y : V} : (starGraph r).Adj x y ↔ x ≠ y ∧ (x = r ∨ y = r) := by simp [starGraph, fromRel] +@[simp] +lemma isUniversal_starGraph_self {r : V} : (starGraph r).IsUniversal r := by + intro _ _ + simpa + /-- On (starGraph r), r is adjacent to v iff v ≠ r. -/ lemma starGraph_adj_center_iff {r v : V} : (starGraph r).Adj r v ↔ r ≠ v := by simp @@ -52,12 +57,8 @@ lemma starGraph_center_adj {r v : V} (h : r ≠ v) : (starGraph r).Adj r v := lemma starGraph_center_adj' {r v : V} (h : r ≠ v) : (starGraph r).Adj v r := (starGraph_center_adj h).symm -lemma connected_starGraph (r : V) : (starGraph r).Connected := by - have (v : V) : (starGraph r).Reachable r v := by - by_cases! h : r = v - · exact h ▸ Reachable.rfl - · exact (starGraph_center_adj h).reachable - exact connected_iff _ |>.mpr ⟨fun u v ↦ (this u).symm.trans (this v), ⟨r⟩⟩ +lemma connected_starGraph (r : V) : (starGraph r).Connected := + .of_isUniversal isUniversal_starGraph_self lemma isAcyclic_starGraph (r : V) : (starGraph r).IsAcyclic := by refine isAcyclic_iff_forall_adj_isBridge.mpr fun v w hadj ↦ ?_ @@ -81,6 +82,6 @@ lemma degree_starGraph_of_ne_center [Fintype V] [DecidableEq V] {r v : V} (h : v /-- The center vertex of a starGraph has degree (card V) - 1. -/ lemma degree_starGraph_center [Fintype V] [DecidableEq V] {r : V} : (starGraph r).degree r = Fintype.card V - 1 := by - simp [degree, neighborFinset_eq_filter (starGraph r), starGraph_adj, Finset.univ.filter_ne r] + simp end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean index e905473f5226e5..7640e0a025927f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean @@ -294,21 +294,21 @@ lemma exists_isTutteViolator (h : ∀ (M : G.Subgraph), ¬M.IsPerfectMatching) obtain ⟨p, hp⟩ := Reachable.exists_path_of_dist (K.connected_toSimpleGraph x y) obtain ⟨x, a, b, hxa, hxb, hnadjxb, hnxb⟩ := Walk.exists_adj_adj_not_adj_ne hp.2 (p.reachable.one_lt_dist_of_ne_of_not_adj hxy.1 hxy.2) - simp only [ConnectedComponent.toSimpleGraph, deleteUniversalVerts, universalVerts, ne_eq, + simp only [ConnectedComponent.toSimpleGraph, deleteUniversalVerts, universalVerts, Subgraph.verts_top, comap_adj, Function.Embedding.coe_subtype, Subgraph.coe_adj, Subgraph.induce_adj, Subtype.coe_prop, Subgraph.top_adj, true_and] at hxa hxb hnadjxb - obtain ⟨c, hc⟩ : ∃ (c : V), (a : V) ≠ c ∧ ¬ Gmax.Adj c a := by - simpa [universalVerts] using a.1.2.2 - have hbnec : b.val.val ≠ c := by rintro rfl; exact hc.2 hxb.symm + obtain ⟨c, hc⟩ : ∃ (c : V), (a : V) ≠ c ∧ ¬ Gmax.Adj a c := by + simpa [universalVerts, IsUniversal] using a.1.2.2 + have hbnec : b.val.val ≠ c := by rintro rfl; exact hc.2 hxb obtain ⟨_, hG1⟩ := hMaximal _ <| left_lt_sup.mpr (by rw [edge_le_iff (v := x.1.1) (w := b.1.1)] simp [hnadjxb, Subtype.val_injective.ne <| Subtype.val_injective.ne hnxb]) obtain ⟨_, hG2⟩ := hMaximal _ <| left_lt_sup.mpr (by - rwa [edge_le_iff (v := a.1.1) (w := c), adj_comm, not_or]) - have hcnex : c ≠ x.val.val := by rintro rfl; exact hc.2 hxa + rwa [edge_le_iff (v := a.1.1) (w := c), not_or]) + have hcnex : x.val.val ≠ c := by rintro rfl; exact hc.2 hxa.symm obtain ⟨Mcon, hMcon⟩ := tutte_exists_isPerfectMatching_of_near_matchings hxa - hxb hnadjxb (fun hadj ↦ hc.2 hadj.symm) (by lia) hcnex.symm hc.1 hbnec hG1 hG2 + hxb hnadjxb (fun hadj ↦ hc.2 hadj) (by lia) hcnex hc.1 hbnec hG1 hG2 exact hMatchingFree Mcon hMcon /-- **Tutte's theorem** diff --git a/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean b/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean index 2cd61fb77f16f0..79107f325d24c5 100644 --- a/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean +++ b/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean @@ -33,10 +33,10 @@ variable {V : Type*} {G : SimpleGraph V} /-- The set of vertices that are connected to all other vertices. -/ -def universalVerts (G : SimpleGraph V) : Set V := {v : V | ∀ ⦃w⦄, v ≠ w → G.Adj w v} +def universalVerts (G : SimpleGraph V) : Set V := {v : V | G.IsUniversal v} lemma isClique_universalVerts (G : SimpleGraph V) : G.IsClique G.universalVerts := - fun _ _ _ hy hxy ↦ hy hxy.symm + fun _ hx _ _ hxy ↦ hx hxy /-- The subgraph of `G` with the universal vertices removed. @@ -53,7 +53,7 @@ lemma Subgraph.IsMatching.exists_of_universalVerts [Finite V] {s : Set V} obtain ⟨f⟩ : Nonempty (s ≃ t) := by rw [← Cardinal.eq, ← t.cast_ncard t.toFinite, ← s.cast_ncard s.toFinite, ht.2] letI hd := Set.disjoint_of_subset_left ht.1 h - have hadj (v : s) : G.Adj v (f v) := ht.1 (f v).2 (hd.ne_of_mem (f v).2 v.2) + have hadj (v : s) : G.Adj v (f v) := ht.1 (f v).2 (hd.ne_of_mem (f v).2 v.2) |>.symm exact Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv hd.symm f hadj lemma disjoint_image_val_universalVerts (s : Set G.deleteUniversalVerts.verts) : From 2ccc1072353391c5faf82a69a64e8271e7259b9b Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Wed, 1 Jul 2026 01:02:22 +0000 Subject: [PATCH 0494/1300] feat: pointwise limit of a sequence of monotone functions is monotone (#40526) Adds lemmas showing that the pointwise limit of a sequence of frequently monotone functions is monotone in an order-closed topology. It also adds the corresponding antitone variants via the order dual. Created with a little bit help from codex :) Co-authored-by: Yongxi Lin --- Mathlib/Topology/Order/OrderClosed.lean | 49 ++++++++++++++++++++----- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/Mathlib/Topology/Order/OrderClosed.lean b/Mathlib/Topology/Order/OrderClosed.lean index 6fe8f916cb1921..6388ad265d4940 100644 --- a/Mathlib/Topology/Order/OrderClosed.lean +++ b/Mathlib/Topology/Order/OrderClosed.lean @@ -48,6 +48,8 @@ see their statements. * `le_of_tendsto`, `ge_of_tendsto` : if `f` converges to `a` and eventually `f x ≤ b` (resp., `b ≤ f x`), then `a ≤ b` (resp., `b ≤ a`); we also provide primed versions that assume the inequalities to hold for all `x`. +* `monotone_of_frequently_monotone_of_tendsto`, `antitone_of_frequently_antitone_of_tendsto` : the + pointwise limit of frequently monotone or antitone functions is monotone or antitone. ### Min, max, `sSup` and `sInf` @@ -514,25 +516,54 @@ theorem IsClosed.epigraph [TopologicalSpace β] {f : β → α} {s : Set β} (hs (hf : ContinuousOn f s) : IsClosed { p : β × α | p.1 ∈ s ∧ f p.1 ≤ p.2 } := (hs.preimage continuous_fst).isClosed_le (hf.comp continuousOn_fst Subset.rfl) continuousOn_snd +section Tendsto + +variable {ι : Type*} {l : Filter ι} [Preorder β] {F : ι → β → α} {f : β → α} {s : Set β} + +/-- The limit of a collection of functions that is frequently monotone on a set is monotone on +that set. -/ +lemma monotoneOn_of_frequently_monotoneOn_of_tendsto (hF : ∃ᶠ i in l, MonotoneOn (F i) s) + (hlim : ∀ x ∈ s, Tendsto (fun i ↦ F i x) l (𝓝 (f x))) : MonotoneOn f s := + fun a ha b hb hab ↦ le_of_tendsto_of_tendsto_of_frequently (hlim a ha) (hlim b hb) <| + hF.mono fun _ hi ↦ hi ha hb hab + +/-- The limit of a collection of functions that is frequently monotone is monotone. -/ +lemma monotone_of_frequently_monotone_of_tendsto (hF : ∃ᶠ i in l, Monotone (F i)) + (hlim : ∀ x, Tendsto (fun i ↦ F i x) l (𝓝 (f x))) : Monotone f := + monotoneOn_univ.1 <| monotoneOn_of_frequently_monotoneOn_of_tendsto + (hF.mono fun _ hi ↦ hi.monotoneOn _) fun x _ ↦ hlim x + +/-- The limit of a collection of functions that is frequently antitone on a set is antitone on +that set. -/ +lemma antitoneOn_of_frequently_antitoneOn_of_tendsto (hF : ∃ᶠ i in l, AntitoneOn (F i) s) + (hlim : ∀ x ∈ s, Tendsto (fun i ↦ F i x) l (𝓝 (f x))) : AntitoneOn f s := + monotoneOn_of_frequently_monotoneOn_of_tendsto (α := αᵒᵈ) hF hlim + +/-- The limit of a collection of functions that is frequently antitone is antitone. -/ +lemma antitone_of_frequently_antitone_of_tendsto (hF : ∃ᶠ i in l, Antitone (F i)) + (hlim : ∀ x, Tendsto (fun i ↦ F i x) l (𝓝 (f x))) : Antitone f := + monotone_of_frequently_monotone_of_tendsto (α := αᵒᵈ) hF hlim + /-- The set of monotone functions on a set is closed. -/ -theorem isClosed_monotoneOn [Preorder β] {s : Set β} : IsClosed {f : β → α | MonotoneOn f s} := by +theorem isClosed_monotoneOn : IsClosed {f : β → α | MonotoneOn f s} := by simp only [isClosed_iff_clusterPt, clusterPt_principal_iff_frequently] - intro g hg a ha b hb hab - have hmain (x) : Tendsto (fun f' ↦ f' x) (𝓝 g) (𝓝 (g x)) := continuousAt_apply x _ - exact le_of_tendsto_of_tendsto_of_frequently (hmain a) (hmain b) (hg.mono fun g h ↦ h ha hb hab) + exact fun g hg => monotoneOn_of_frequently_monotoneOn_of_tendsto hg + fun x _ ↦ continuousAt_apply x g /-- The set of monotone functions is closed. -/ -theorem isClosed_monotone [Preorder β] : IsClosed {f : β → α | Monotone f} := by +theorem isClosed_monotone : IsClosed {f : β → α | Monotone f} := by simp_rw [← monotoneOn_univ] exact isClosed_monotoneOn /-- The set of antitone functions on a set is closed. -/ -theorem isClosed_antitoneOn [Preorder β] {s : Set β} : IsClosed {f : β → α | AntitoneOn f s} := - isClosed_monotoneOn (α := αᵒᵈ) (β := β) +theorem isClosed_antitoneOn : IsClosed {f : β → α | AntitoneOn f s} := + isClosed_monotoneOn (α := αᵒᵈ) /-- The set of antitone functions is closed. -/ -theorem isClosed_antitone [Preorder β] : IsClosed {f : β → α | Antitone f} := - isClosed_monotone (α := αᵒᵈ) (β := β) +theorem isClosed_antitone : IsClosed {f : β → α | Antitone f} := + isClosed_monotone (α := αᵒᵈ) + +end Tendsto end Preorder From d52d26fc2f36d4af5215e91892b33c96dc33915a Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 1 Jul 2026 01:31:20 +0000 Subject: [PATCH 0495/1300] =?UTF-8?q?chore(Logic/Relation):=20use=20`?= =?UTF-8?q?=E2=89=A4`=20to=20spell=20subrelation=20(#30526)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace every `∀ x y, r x y → r' x y` with `r ≤ r'` --- Mathlib/CategoryTheory/IsConnected.lean | 2 +- .../Limits/Types/Coequalizers.lean | 2 +- .../CategoryTheory/Limits/Types/Filtered.lean | 2 +- Mathlib/GroupTheory/FreeGroup/Basic.lean | 17 +- Mathlib/Logic/Relation.lean | 156 ++++++++++-------- Mathlib/Order/Interval/Finset/Basic.lean | 6 +- Mathlib/Topology/Gluing.lean | 2 +- 7 files changed, 101 insertions(+), 86 deletions(-) diff --git a/Mathlib/CategoryTheory/IsConnected.lean b/Mathlib/CategoryTheory/IsConnected.lean index 2da559ece4f308..9ba6de15ee9e52 100644 --- a/Mathlib/CategoryTheory/IsConnected.lean +++ b/Mathlib/CategoryTheory/IsConnected.lean @@ -381,7 +381,7 @@ def Zigzag.setoid (J : Type u₂) [Category.{v₁} J] : Setoid J where -/ theorem zigzag_prefunctor_obj_of_zigzag (F : J ⥤q K) {j₁ j₂ : J} (h : Zigzag j₁ j₂) : Zigzag (F.obj j₁) (F.obj j₂) := - h.lift _ fun _ _ => Or.imp (Nonempty.map fun f => F.map f) (Nonempty.map fun f => F.map f) + h.lift F.obj fun _ _ => Or.imp (Nonempty.map fun f => F.map f) (Nonempty.map fun f => F.map f) /-- If there is a zigzag from `j₁` to `j₂`, then there is a zigzag from `F j₁` to `F j₂` as long as `F` is a functor. diff --git a/Mathlib/CategoryTheory/Limits/Types/Coequalizers.lean b/Mathlib/CategoryTheory/Limits/Types/Coequalizers.lean index 1fca1ad2404cdb..f9625eedfb509b 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Coequalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Coequalizers.lean @@ -65,7 +65,7 @@ theorem coequalizer_preimage_image_eq_of_preimage_eq (π : Y ⟶ Z) (e : f ≫ (mono_iff_injective (h.coconePointUniqueUpToIso (coequalizerColimit f g).isColimit).inv).mp inferInstance - refine (eqv.eqvGen_iff.mp (Relation.EqvGen.mono lem (Quot.eqvGen_exact ?_))).mp hy + refine (eqv.eqvGen_iff.mp (Relation.EqvGen.mono lem y _ (Quot.eqvGen_exact ?_))).mp hy apply e'' convert! e' · exact fun hx => ⟨_, hx, rfl⟩ diff --git a/Mathlib/CategoryTheory/Limits/Types/Filtered.lean b/Mathlib/CategoryTheory/Limits/Types/Filtered.lean index 013c92339f0080..2d406b4c347a5b 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Filtered.lean @@ -117,7 +117,7 @@ protected theorem rel_eq_eqvGen_colimitTypeRel : constructor · apply eqvGen_colimitTypeRel_of_rel · rw [← (FilteredColimit.rel_equiv F).eqvGen_iff] - exact Relation.EqvGen.mono (rel_of_colimitTypeRel F) + exact Relation.EqvGen.mono (rel_of_colimitTypeRel F) _ _ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index caf6340f835d4e..4fdc5d6b3b1b88 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -203,7 +203,7 @@ theorem church_rosser : Red L₁ L₂ → Red L₁ L₃ → Join Red L₂ L₃ : @[to_additive] theorem cons_cons {p} : Red L₁ L₂ → Red (p :: L₁) (p :: L₂) := - ReflTransGen.lift (List.cons p) fun _ _ => Step.cons + ReflTransGen.lift (List.cons p) (fun _ _ => Step.cons) L₁ L₂ @[to_additive] theorem cons_cons_iff (p) : Red (p :: L₁) (p :: L₂) ↔ Red L₁ L₂ := @@ -322,11 +322,8 @@ theorem Step.sublist (H : Red.Step L₁ L₂) : L₂ <+ L₁ := by @[to_additive /-- If `w₁ w₂` are words such that `w₁` reduces to `w₂`, then `w₂` is a sublist of `w₁`. -/] protected theorem sublist : Red L₁ L₂ → L₂ <+ L₁ := - @reflTransGen_of_isTrans_reflexive - _ (fun a b => b <+ a) _ _ _ - ⟨List.Sublist.refl⟩ - ⟨fun _a _b _c hab hbc => List.Sublist.trans hbc hab⟩ - (fun _ _ => Red.Step.sublist) + @reflTransGen_le_of_le _ (fun a b => b <+ a) _ ⟨List.Sublist.refl⟩ + ⟨fun _a _b _c hab hbc => List.Sublist.trans hbc hab⟩ (fun _ _ => Red.Step.sublist) L₁ L₂ @[to_additive] theorem length_le (h : Red L₁ L₂) : L₂.length ≤ L₁.length := @@ -369,7 +366,7 @@ theorem equivalence_join_red : Equivalence (Join (@Red α)) := @[to_additive] theorem join_red_of_step (h : Red.Step L₁ L₂) : Join Red L₁ L₂ := by unfold Red - exact join_of_single h.to_red + exact le_join_of_refl L₁ L₂ h.to_red @[to_additive] theorem eqvGen_step_iff_join_red : EqvGen Red.Step L₁ L₂ ↔ Join Red L₁ L₂ := @@ -377,8 +374,8 @@ theorem eqvGen_step_iff_join_red : EqvGen Red.Step L₁ L₂ ↔ Join Red L₁ L (fun h => have : EqvGen (Join Red) L₁ L₂ := h.mono fun _ _ => join_red_of_step equivalence_join_red.eqvGen_iff.1 this) - (join_of_equivalence (Relation.EqvGen.is_equivalence _) fun _ _ => - reflTransGen_of_equivalence (Relation.EqvGen.is_equivalence _) EqvGen.rel) + (join_le_of_equivalence_of_le (Relation.EqvGen.is_equivalence _) + (reflTransGen_le_of_equivalence_of_le (Relation.EqvGen.is_equivalence _) EqvGen.rel) L₁ L₂) /-! ### Reduced words -/ @@ -589,7 +586,7 @@ theorem Red.Step.invRev {L₁ L₂ : List (α × Bool)} (h : Red.Step L₁ L₂) @[to_additive] theorem Red.invRev {L₁ L₂ : List (α × Bool)} (h : Red L₁ L₂) : Red (invRev L₁) (invRev L₂) := - Relation.ReflTransGen.lift _ (fun _a _b => Red.Step.invRev) h + Relation.ReflTransGen.lift FreeGroup.invRev (fun _a _b => Red.Step.invRev) L₁ L₂ h @[to_additive (attr := simp)] theorem Red.step_invRev_iff : diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 8607a7d2f4a46c..953a9a444d0101 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -9,6 +9,7 @@ public import Mathlib.Logic.Relator public import Mathlib.Tactic.Use public import Mathlib.Tactic.MkIffOfInductiveProp public import Mathlib.Tactic.SimpRw +public import Mathlib.Order.Defs.Prop public import Mathlib.Order.Defs.Unbundled public import Batteries.Logic public import Batteries.Tactic.Trans @@ -53,7 +54,7 @@ the bundled version, see `Rel`. open Function -variable {α β γ δ ε ζ : Sort*} +variable {α β γ δ ε ζ : Type*} section NeImp @@ -76,19 +77,21 @@ theorem Std.Refl.ne_imp_iff [Std.Refl r] {x y : α} : x ≠ y → r x y ↔ r x ⟨Std.Refl.rel_of_ne_imp, fun hr _ ↦ hr⟩ @[deprecated (since := "2026-03-27")] alias Reflexive.ne_imp_iff := Std.Refl.ne_imp_iff - @[deprecated (since := "2026-03-27")] alias reflexive_ne_imp_iff := Std.Refl.ne_imp_iff -theorem refl_iff_subrelation_eq : Std.Refl r ↔ Subrelation Eq r := by - grind [Std.Refl, Subrelation] +theorem refl_iff_eq_le : Std.Refl r ↔ Eq ≤ r := by + unfold Pi.hasLe Prop.le + grind [Std.Refl] -@[deprecated (since := "2026-03-27")] alias reflexive_iff_subrelation_eq := refl_iff_subrelation_eq +@[deprecated (since := "2026-06-30")] alias refl_iff_subrelation_eq := refl_iff_eq_le +@[deprecated (since := "2026-03-27")] alias reflexive_iff_subrelation_eq := refl_iff_eq_le -theorem irrefl_iff_subrelation_ne : Std.Irrefl r ↔ Subrelation r Ne := by - grind [Std.Irrefl, Subrelation] +theorem irrefl_iff_le_ne : Std.Irrefl r ↔ r ≤ Ne := by + unfold Pi.hasLe Prop.le + grind [Std.Irrefl] -@[deprecated (since := "2026-02-12")] -alias irreflexive_iff_subrelation_ne := irrefl_iff_subrelation_ne +@[deprecated (since := "2026-06-30")] alias irrefl_iff_subrelation_ne := irrefl_iff_le_ne +@[deprecated (since := "2026-02-12")] alias irreflexive_iff_subrelation_ne := irrefl_iff_le_ne protected theorem Std.Symm.iff [Std.Symm r] (x y : α) : r x y ↔ r y x := ⟨symm_of r, symm_of r⟩ @@ -280,13 +283,12 @@ lemma map_equivalence {r : α → α → Prop} (hr : Equivalence r) (f : α → symm := @(hr.stdSymm.map f |>.symm) trans := @(hr.isTrans.map hf_ker |>.trans) --- TODO: state this using `≤`, after adjusting imports. -lemma map_mono {r s : α → β → Prop} {f : α → γ} {g : β → δ} (h : ∀ x y, r x y → s x y) : - ∀ x y, Relation.Map r f g x y → Relation.Map s f g x y := +lemma map_mono {r s : α → β → Prop} {f : α → γ} {g : β → δ} (h : r ≤ s) : + Relation.Map r f g ≤ Relation.Map s f g := fun _ _ ⟨x, y, hxy, hx, hy⟩ => ⟨x, y, h _ _ hxy, hx, hy⟩ -lemma le_onFun_map {r : α → α → Prop} (f : α → β) : Subrelation r (Relation.Map r f f on f) := by - intro +lemma le_onFun_map {r : α → α → Prop} (f : α → β) : r ≤ (Relation.Map r f f on f) := by + unfold Pi.hasLe Prop.le grind [Relation.Map] lemma onFun_map_eq_of_injective {r : α → α → Prop} {f : α → β} (hinj : f.Injective) : @@ -294,8 +296,8 @@ lemma onFun_map_eq_of_injective {r : α → α → Prop} {f : α → β} (hinj : ext x y exact ⟨fun ⟨x', y', hr, hx, hy⟩ ↦ hinj hx ▸ hinj hy ▸ hr, fun h ↦ ⟨x, y, h, rfl, rfl⟩⟩ -lemma map_onFun_le {r : β → β → Prop} (f : α → β) : Subrelation (Relation.Map (r on f) f f) r := by - intro +lemma map_onFun_le {r : β → β → Prop} (f : α → β) : Relation.Map (r on f) f f ≤ r := by + unfold Pi.hasLe Prop.le grind [Relation.Map] lemma map_onFun_eq_of_surjective {r : β → β → Prop} {f : α → β} (hsurj : f.Surjective) : @@ -355,13 +357,16 @@ inductive EqvGen : α → α → Prop attribute [mk_iff] TransGen attribute [grind] TransGen +theorem reflGen_le_reflTransGen : ReflGen r ≤ ReflTransGen r + | a, _, .refl => by rfl + | _, _, .single h => ReflTransGen.tail ReflTransGen.refl h + namespace ReflGen -theorem to_reflTransGen : ∀ {a b}, ReflGen r a b → ReflTransGen r a b - | a, _, refl => by rfl - | _, _, single h => ReflTransGen.tail ReflTransGen.refl h +theorem to_reflTransGen {a b} : ReflGen r a b → ReflTransGen r a b := + reflGen_le_reflTransGen a b -theorem mono {p : α → α → Prop} (hp : ∀ a b, r a b → p a b) : ∀ {a b}, ReflGen r a b → ReflGen p a b +theorem mono {p : α → α → Prop} (hp : r ≤ p) : ReflGen r ≤ ReflGen p | a, _, ReflGen.refl => by rfl | a, b, single h => single (hp a b h) @@ -436,6 +441,9 @@ theorem trans (hab : ReflTransGen r a b) (hbc : ReflTransGen r b c) : ReflTransG theorem single (hab : r a b) : ReflTransGen r a b := refl.tail hab +theorem le_reflTransGen : r ≤ ReflTransGen r := + fun _ _ ↦ single + theorem head (hab : r a b) (hbc : ReflTransGen r b c) : ReflTransGen r a c := by induction hbc with | refl => exact refl.tail hab @@ -497,13 +505,17 @@ theorem total_of_right_unique (U : Relator.RightUnique r) (ab : ReflTransGen r a end ReflTransGen -namespace TransGen - -theorem to_reflTransGen {a b} (h : TransGen r a b) : ReflTransGen r a b := by +theorem transGen_le_reflTransGen : TransGen r ≤ ReflTransGen r := by + intro a _ h induction h with | single h => exact ReflTransGen.single h | tail _ bc ab => exact ReflTransGen.tail ab bc +namespace TransGen + +theorem to_reflTransGen {a b} : TransGen r a b → ReflTransGen r a b := + transGen_le_reflTransGen a b + theorem trans_left (hab : TransGen r a b) (hbc : ReflTransGen r b c) : TransGen r a c := by induction hbc with | refl => assumption @@ -586,9 +598,8 @@ lemma reflGen_eq_self [Std.Refl r] : ReflGen r = r := by @[deprecated inferInstance (since := "2026-03-27")] lemma reflexive_reflGen : Std.Refl (ReflGen r) := inferInstance -lemma reflGen_minimal {r' : α → α → Prop} [Std.Refl r'] (h : ∀ x y, r x y → r' x y) {x y : α} - (hxy : ReflGen r x y) : r' x y := by - simpa [reflGen_eq_self] using ReflGen.mono h hxy +lemma reflGen_minimal {r' : α → α → Prop} [Std.Refl r'] (h : r ≤ r') : ReflGen r ≤ r' := by + simpa [reflGen_eq_self] using ReflGen.mono h end reflGen @@ -641,40 +652,39 @@ theorem transitive_transGen : IsTrans α (TransGen r) := inferInstance theorem transGen_idem : TransGen (TransGen r) = TransGen r := transGen_eq_self -theorem TransGen.lift {p : β → β → Prop} {a b : α} (f : α → β) (h : ∀ a b, r a b → p (f a) (f b)) - (hab : TransGen r a b) : TransGen p (f a) (f b) := by +theorem TransGen.lift {p : β → β → Prop} (f : α → β) (h : r ≤ (p on f)) : + TransGen r ≤ (TransGen p on f) := by + intro a _ hab induction hab with | single hac => exact TransGen.single (h a _ hac) | tail _ hcd hac => exact TransGen.tail hac (h _ _ hcd) -theorem TransGen.lift' {p : β → β → Prop} {a b : α} (f : α → β) - (h : ∀ a b, r a b → TransGen p (f a) (f b)) (hab : TransGen r a b) : - TransGen p (f a) (f b) := by +theorem TransGen.lift' {p : β → β → Prop} (f : α → β) (h : r ≤ (TransGen p on f)) : + TransGen r ≤ (TransGen p on f) := by + intro _ _ hab simpa [transGen_eq_self] using hab.lift f h -theorem TransGen.closed {p : α → α → Prop} : - (∀ a b, r a b → TransGen p a b) → TransGen r a b → TransGen p a b := +theorem TransGen.closed {p : α → α → Prop} : r ≤ TransGen p → TransGen r ≤ TransGen p := TransGen.lift' id lemma TransGen.closed' {P : α → Prop} (dc : ∀ {a b}, r a b → P b → P a) {a b : α} (h : TransGen r a b) : P b → P a := h.head_induction_on dc fun hr _ hi ↦ dc hr ∘ hi -theorem TransGen.mono {p : α → α → Prop} : - (∀ a b, r a b → p a b) → TransGen r a b → TransGen p a b := +theorem TransGen.mono {p : α → α → Prop} : r ≤ p → TransGen r ≤ TransGen p := TransGen.lift id -lemma transGen_minimal {r' : α → α → Prop} [IsTrans α r'] (h : ∀ x y, r x y → r' x y) {x y : α} - (hxy : TransGen r x y) : r' x y := by - simpa [transGen_eq_self] using TransGen.mono h hxy +lemma transGen_minimal {r' : α → α → Prop} [IsTrans α r'] (h : r ≤ r') : TransGen r ≤ r' := by + simpa [transGen_eq_self] using TransGen.mono h -theorem TransGen.swap (h : TransGen r b a) : TransGen (swap r) a b := by +theorem TransGen.swap : swap (TransGen r) ≤ TransGen (swap r) := by + intro _ _ h induction h with | single h => exact TransGen.single h | tail _ hbc ih => exact ih.head hbc theorem transGen_swap : TransGen (swap r) a b ↔ TransGen r b a := - ⟨TransGen.swap, TransGen.swap⟩ + ⟨TransGen.swap b a, TransGen.swap a b⟩ end TransGen @@ -696,12 +706,11 @@ theorem reflTransGen_iff_eq_or_transGen : ReflTransGen r a b ↔ b = a ∨ Trans · rfl · exact h.to_reflTransGen -theorem ReflTransGen.lift {p : β → β → Prop} {a b : α} (f : α → β) - (h : ∀ a b, r a b → p (f a) (f b)) (hab : ReflTransGen r a b) : ReflTransGen p (f a) (f b) := - ReflTransGen.trans_induction_on hab (fun _ ↦ refl) (ReflTransGen.single ∘ h _ _) fun _ _ ↦ trans +theorem ReflTransGen.lift {p : β → β → Prop} (f : α → β) (h : r ≤ (p on f)) : + ReflTransGen r ≤ (ReflTransGen p on f) := + fun _ _ hab ↦ trans_induction_on hab (fun _ ↦ refl) (single ∘ h _ _) fun _ _ ↦ trans -theorem ReflTransGen.mono {p : α → α → Prop} : (∀ a b, r a b → p a b) → - ReflTransGen r a b → ReflTransGen p a b := +theorem ReflTransGen.mono {p : α → α → Prop} : r ≤ p → ReflTransGen r ≤ ReflTransGen p := ReflTransGen.lift id @[grind =] @@ -734,22 +743,23 @@ theorem transitive_reflTransGen : IsTrans α (ReflTransGen r) := inferInstance theorem reflTransGen_idem : ReflTransGen (ReflTransGen r) = ReflTransGen r := reflTransGen_eq_self -theorem ReflTransGen.lift' {p : β → β → Prop} {a b : α} (f : α → β) - (h : ∀ a b, r a b → ReflTransGen p (f a) (f b)) - (hab : ReflTransGen r a b) : ReflTransGen p (f a) (f b) := by +theorem ReflTransGen.lift' {p : β → β → Prop} (f : α → β) (h : r ≤ (ReflTransGen p on f)) : + ReflTransGen r ≤ (ReflTransGen p on f) := by + intro _ _ hab simpa [reflTransGen_eq_self] using hab.lift f h theorem reflTransGen_closed {p : α → α → Prop} : - (∀ a b, r a b → ReflTransGen p a b) → ReflTransGen r a b → ReflTransGen p a b := + r ≤ ReflTransGen p → ReflTransGen r ≤ ReflTransGen p := ReflTransGen.lift' id -theorem ReflTransGen.swap (h : ReflTransGen r b a) : ReflTransGen (swap r) a b := by +theorem ReflTransGen.swap : swap (ReflTransGen r) ≤ ReflTransGen (swap r) := by + intro _ _ h induction h with | refl => rfl | tail _ hbc ih => exact ih.head hbc theorem reflTransGen_swap : ReflTransGen (swap r) a b ↔ ReflTransGen r b a := - ⟨ReflTransGen.swap, ReflTransGen.swap⟩ + ⟨ReflTransGen.swap b a, ReflTransGen.swap a b⟩ @[simp, grind =] lemma reflGen_transGen : ReflGen (TransGen r) = ReflTransGen r := by ext x y @@ -758,10 +768,10 @@ theorem reflTransGen_swap : ReflTransGen (swap r) a b ↔ ReflTransGen r b a := @[simp, grind =] lemma transGen_reflGen : TransGen (ReflGen r) = ReflTransGen r := by ext x y refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ - · simpa [reflTransGen_eq_self] using (h.mono fun _ _ ↦ ReflGen.to_reflTransGen).to_reflTransGen + · simpa [reflTransGen_eq_self] using h.mono reflGen_le_reflTransGen x y |>.to_reflTransGen · obtain (rfl | h) := reflTransGen_iff_eq_or_transGen.mp h · exact .single .refl - · exact TransGen.mono (fun _ _ ↦ .single) h + · exact h.mono (fun _ _ ↦ .single) x y @[simp, grind =] lemma reflTransGen_reflGen : ReflTransGen (ReflGen r) = ReflTransGen r := by simp only [← transGen_reflGen, reflGen_eq_self] @@ -794,8 +804,8 @@ see for example `Quot.eqvGen_exact` and `Quot.eqvGen_sound`. -/ def setoid : Setoid α := Setoid.mk _ (EqvGen.is_equivalence r) -theorem mono {r p : α → α → Prop} (hrp : ∀ a b, r a b → p a b) (h : EqvGen r a b) : - EqvGen p a b := by +theorem mono {r p : α → α → Prop} (hrp : r ≤ p) : EqvGen r ≤ EqvGen p := by + intro _ _ h induction h with | rel a b h => exact EqvGen.rel _ _ (hrp _ _ h) | refl => exact EqvGen.refl _ @@ -840,9 +850,10 @@ theorem church_rosser (h : ∀ a b c, r a b → r a c → ∃ d, ReflGen r b d | refl => exact ⟨b, hea, hcb⟩ | single hba => exact ⟨a, hea, hcb.tail hba⟩ +theorem le_join_of_refl [Std.Refl r] : r ≤ Join r := + fun _ b hab ↦ ⟨b, hab, refl b⟩ -theorem join_of_single [Std.Refl r] (hab : r a b) : Join r a b := - ⟨b, hab, refl b⟩ +@[deprecated (since := "2026-06-30")] alias join_of_single := le_join_of_refl protected instance Join.symm : Std.Symm (Join r) where symm _ _ := fun ⟨c, hac, hcb⟩ ↦ ⟨c, hcb, hac⟩ @@ -871,23 +882,30 @@ theorem equivalence_join_reflTransGen Equivalence (Join (ReflTransGen r)) := equivalence_join fun _ _ _ ↦ church_rosser h -theorem join_of_equivalence {r' : α → α → Prop} (hr : Equivalence r) (h : ∀ a b, r' a b → r a b) : - Join r' a b → r a b - | ⟨_, hac, hbc⟩ => hr.trans (h _ _ hac) (hr.symm <| h _ _ hbc) +theorem join_le_of_equivalence_of_le {r' : α → α → Prop} (hr : Equivalence r) (h : r' ≤ r) : + Join r' ≤ r := + fun a b ⟨c, hac, hbc⟩ ↦ hr.trans (h a c hac) (hr.symm <| h b c hbc) -theorem reflTransGen_of_isTrans_reflexive {r' : α → α → Prop} [Std.Refl r] [IsTrans α r] - (h : ∀ a b, r' a b → r a b) (h' : ReflTransGen r' a b) : r a b := by - simpa [reflTransGen_eq_self] using ReflTransGen.mono h h' +@[deprecated (since := "2026-06-30")] alias join_of_equivalence := join_le_of_equivalence_of_le + +theorem reflTransGen_le_of_le {r' : α → α → Prop} [Std.Refl r] [IsTrans α r] + (h : r' ≤ r) : ReflTransGen r' ≤ r := by + simpa [reflTransGen_eq_self] using ReflTransGen.mono h + +@[deprecated (since := "2026-06-30")] +alias reflTransGen_of_isTrans_reflexive := reflTransGen_le_of_le @[deprecated (since := "2026-02-21")] -alias reflTransGen_of_transitive_reflexive := reflTransGen_of_isTrans_reflexive +alias reflTransGen_of_transitive_reflexive := reflTransGen_le_of_le + +@[deprecated (since := "2025-12-17")] alias reflTransGen_minimal := reflTransGen_le_of_le -@[deprecated (since := "2025-12-17")] alias reflTransGen_minimal := - reflTransGen_of_transitive_reflexive +theorem reflTransGen_le_of_equivalence_of_le {r' : α → α → Prop} (hr : Equivalence r) : + r' ≤ r → ReflTransGen r' ≤ r := + @reflTransGen_le_of_le _ _ _ hr.stdRefl hr.isTrans -theorem reflTransGen_of_equivalence {r' : α → α → Prop} (hr : Equivalence r) : - (∀ a b, r' a b → r a b) → ReflTransGen r' a b → r a b := - @reflTransGen_of_isTrans_reflexive _ _ _ _ _ hr.stdRefl hr.isTrans +@[deprecated (since := "2026-06-30")] +alias reflTransGen_of_equivalence := reflTransGen_le_of_equivalence_of_le end Join diff --git a/Mathlib/Order/Interval/Finset/Basic.lean b/Mathlib/Order/Interval/Finset/Basic.lean index 47635befe8c107..e8e2ff53069fcd 100644 --- a/Mathlib/Order/Interval/Finset/Basic.lean +++ b/Mathlib/Order/Interval/Finset/Basic.lean @@ -1143,21 +1143,21 @@ restricted to pairs satisfying `a ⩿ b`. -/ lemma monotone_iff_forall_wcovBy [Preorder α] [LocallyFiniteOrder α] [Preorder β] (f : α → β) : Monotone f ↔ ∀ a b : α, a ⩿ b → f a ≤ f b := by refine ⟨fun hf _ _ h ↦ hf h.le, fun h a b hab ↦ ?_⟩ - simpa [transGen_eq_self] using TransGen.lift f h <| le_iff_transGen_wcovBy.mp hab + simpa [transGen_eq_self] using TransGen.lift f h a b <| le_iff_transGen_wcovBy.mp hab /-- A function from a locally finite partial order is monotone if and only if it is monotone when restricted to pairs satisfying `a ⋖ b`. -/ lemma monotone_iff_forall_covBy [PartialOrder α] [LocallyFiniteOrder α] [Preorder β] (f : α → β) : Monotone f ↔ ∀ a b : α, a ⋖ b → f a ≤ f b := by refine ⟨fun hf _ _ h ↦ hf h.le, fun h a b hab ↦ ?_⟩ - simpa [reflTransGen_eq_self] using ReflTransGen.lift f h <| le_iff_reflTransGen_covBy.mp hab + simpa [reflTransGen_eq_self] using ReflTransGen.lift f h a b <| le_iff_reflTransGen_covBy.mp hab /-- A function from a locally finite preorder is strictly monotone if and only if it is strictly monotone when restricted to pairs satisfying `a ⋖ b`. -/ lemma strictMono_iff_forall_covBy [Preorder α] [LocallyFiniteOrder α] [Preorder β] (f : α → β) : StrictMono f ↔ ∀ a b : α, a ⋖ b → f a < f b := by refine ⟨fun hf _ _ h ↦ hf h.lt, fun h a b hab ↦ ?_⟩ - have := Relation.TransGen.lift f h (a := a) (b := b) + have := Relation.TransGen.lift f h a b rw [← lt_iff_transGen_covBy, transGen_eq_self] at this exact this hab diff --git a/Mathlib/Topology/Gluing.lean b/Mathlib/Topology/Gluing.lean index 2e21faac2ffbe4..136fdc6e0b5abe 100644 --- a/Mathlib/Topology/Gluing.lean +++ b/Mathlib/Topology/Gluing.lean @@ -184,7 +184,7 @@ theorem ι_eq_iff_rel (i j : D.J) (x : D.U i) (y : D.U j) : show _ = Sigma.mk j y from ConcreteCategory.congr_hom (sigmaIsoSigma.{_, u} D.U).inv_hom_id _] change InvImage D.Rel (sigmaIsoSigma.{_, u} D.U).hom _ _ rw [← (InvImage.equivalence _ _ D.rel_equiv).eqvGen_iff] - refine Relation.EqvGen.mono ?_ (D.eqvGen_of_π_eq h :) + refine Relation.EqvGen.mono ?_ _ _ (D.eqvGen_of_π_eq h :) rintro _ _ ⟨x⟩ obtain ⟨⟨⟨i, j⟩, y⟩, rfl⟩ := (ConcreteCategory.bijective_of_isIso (sigmaIsoSigma.{u, u} _).inv).2 x From 2fed563e7340ab0b2014cfd78e33d0889da58274 Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Wed, 1 Jul 2026 01:31:22 +0000 Subject: [PATCH 0496/1300] refactor(Analysis/Convex/Cone): use `PointedCone` in Riesz extension theorem (#37053) Change the statement of the Riesz extension theorem to take a `PointedCone` rather than a `ConvexCone`. This PR is part of a series replacing `ConvexCone` with `PointedCone`. https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Replacing.20.60ConvexCone.60.20with.20.60PointedCone.60/near/581184307 Co-authored-by: artie2000 --- Mathlib/Analysis/Convex/Cone/Extension.lean | 21 +++++++++------------ Mathlib/Geometry/Convex/Cone/Pointed.lean | 5 +++++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Mathlib/Analysis/Convex/Cone/Extension.lean b/Mathlib/Analysis/Convex/Cone/Extension.lean index 0cb73ec103fc24..234e879eb8eb5a 100644 --- a/Mathlib/Analysis/Convex/Cone/Extension.lean +++ b/Mathlib/Analysis/Convex/Cone/Extension.lean @@ -6,7 +6,7 @@ Authors: Yury Kudryashov, Frédéric Dupuis module public import Mathlib.Algebra.Order.Archimedean.Real.Basic -public import Mathlib.Geometry.Convex.Cone.Basic +public import Mathlib.Geometry.Convex.Cone.Pointed public import Mathlib.LinearAlgebra.LinearPMap /-! @@ -56,7 +56,7 @@ namespace RieszExtension open Submodule -variable (s : ConvexCone ℝ E) (f : E →ₗ.[ℝ] ℝ) +variable (s : PointedCone ℝ E) (f : E →ₗ.[ℝ] ℝ) /-- Induction step in M. Riesz extension theorem. Given a convex cone `s` in a vector space `E`, a partially defined linear map `f : f.domain → ℝ`, assume that `f` is nonnegative on `f.domain ∩ p` @@ -142,7 +142,7 @@ end RieszExtension and a linear `f : p → ℝ`, assume that `f` is nonnegative on `p ∩ s` and `p + s = E`. Then there exists a globally defined linear function `g : E → ℝ` that agrees with `f` on `p`, and is nonnegative on `s`. -/ -theorem riesz_extension (s : ConvexCone ℝ E) (f : E →ₗ.[ℝ] ℝ) +theorem riesz_extension (s : PointedCone ℝ E) (f : E →ₗ.[ℝ] ℝ) (nonneg : ∀ x : f.domain, (x : E) ∈ s → 0 ≤ f x) (dense : ∀ y, ∃ x : f.domain, (x : E) + y ∈ s) : ∃ g : E →ₗ[ℝ] ℝ, (∀ x : f.domain, g x = f x) ∧ ∀ x ∈ s, 0 ≤ g x := by @@ -160,21 +160,18 @@ theorem exists_extension_of_le_sublinear (f : E →ₗ.[ℝ] ℝ) (N : E → ℝ (N_hom : ∀ c : ℝ, 0 < c → ∀ x, N (c • x) = c * N x) (N_add : ∀ x y, N (x + y) ≤ N x + N y) (hf : ∀ x : f.domain, f x ≤ N x) : ∃ g : E →ₗ[ℝ] ℝ, (∀ x : f.domain, g x = f x) ∧ ∀ x, g x ≤ N x := by - let s : ConvexCone ℝ (E × ℝ) := + have N_0 : N 0 = 0 := by grind [N_hom 2 (by norm_num) 0, smul_zero] + let s : PointedCone ℝ (E × ℝ) := { carrier := { p : E × ℝ | N p.1 ≤ p.2 } - smul_mem' := fun c hc p hp => - calc - N (c • p.1) = c * N p.1 := N_hom c hc p.1 - _ ≤ c * p.2 := by gcongr; exact hp - add_mem' := fun x hx y hy => (N_add _ _).trans (add_le_add hx hy) } + zero_mem' := by simp [N_0] + smul_mem' := fun ⟨_, hc⟩ _ _ => by rcases eq_or_lt_of_le' hc <;> simp_all + add_mem' := fun hx hy => (N_add _ _).trans (add_le_add hx hy) } set f' := (-f).coprod (LinearMap.id.toPMap ⊤) have hf'_nonneg : ∀ x : f'.domain, x.1 ∈ s → 0 ≤ f' x := fun x (hx : N x.1.1 ≤ x.1.2) ↦ by simpa [f'] using le_trans (hf ⟨x.1.1, x.2.1⟩) hx have hf'_dense : ∀ y : E × ℝ, ∃ x : f'.domain, ↑x + y ∈ s := by rintro ⟨x, y⟩ - refine ⟨⟨(0, N x - y), ⟨f.domain.zero_mem, trivial⟩⟩, ?_⟩ - simp only [s, ConvexCone.mem_mk, mem_setOf_eq, Prod.fst_add, Prod.snd_add, zero_add, - sub_add_cancel, le_rfl] + exact ⟨⟨(0, N x - y), ⟨f.domain.zero_mem, trivial⟩⟩, by simp [s]⟩ obtain ⟨g, g_eq, g_nonneg⟩ := riesz_extension s f' hf'_nonneg hf'_dense replace g_eq : ∀ (x : f.domain) (y : ℝ), g (x, y) = y - f x := fun x y ↦ (g_eq ⟨(x, y), ⟨x.2, trivial⟩⟩).trans (sub_eq_neg_add _ _).symm diff --git a/Mathlib/Geometry/Convex/Cone/Pointed.lean b/Mathlib/Geometry/Convex/Cone/Pointed.lean index fc557380f4d469..f2370255b2ba01 100644 --- a/Mathlib/Geometry/Convex/Cone/Pointed.lean +++ b/Mathlib/Geometry/Convex/Cone/Pointed.lean @@ -129,6 +129,11 @@ lemma convex (C : PointedCone R E) : Convex R (C : Set E) := C.toConvexCone.conv nonrec lemma smul_mem (C : PointedCone R E) (hr : 0 ≤ r) (hx : x ∈ C) : r • x ∈ C := C.smul_mem ⟨r, hr⟩ hx +lemma smul_mem_iff {𝕜 M : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] + [AddCommMonoid M] [Module 𝕜 M] (C : PointedCone 𝕜 M) + {c : 𝕜} (hc : 0 < c) {x : M} : c • x ∈ C ↔ x ∈ C := + ⟨fun h => inv_smul_smul₀ hc.ne' x ▸ C.smul_mem (inv_pos.2 hc).le h, C.smul_mem hc.le⟩ + /-- The `PointedCone` constructed from a pointed `ConvexCone`. -/ def _root_.ConvexCone.toPointedCone (C : ConvexCone R E) (hC : C.Pointed) : PointedCone R E where carrier := C From 79841fc9bca4f7a96164d2664b96fb6942113c0e Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Wed, 1 Jul 2026 01:31:25 +0000 Subject: [PATCH 0497/1300] feat: expand lemmas about `Function.prod` (#41148) --- Mathlib/Logic/Function/Defs.lean | 56 ++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/Mathlib/Logic/Function/Defs.lean b/Mathlib/Logic/Function/Defs.lean index 3208b2496fc569..0c3098fed6abe8 100644 --- a/Mathlib/Logic/Function/Defs.lean +++ b/Mathlib/Logic/Function/Defs.lean @@ -49,13 +49,57 @@ end DComp protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : α i × β i := (f i, g i) -@[simp] lemma prod_apply {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : - Function.prod f g i = (f i , g i) := rfl +section DProd -lemma prod_fst_snd {α β} : Function.prod (Prod.fst : α × β → α) (Prod.snd : α × β → β) = id := - rfl -lemma prod_snd_fst {α β} : Function.prod (Prod.snd : α × β → β) (Prod.fst : α × β → α) = .swap := - rfl +variable {ι} {α β : ι → Type*} (f f' : ∀ i, α i) (g g' : ∀ i, β i) + +theorem prod_def : Function.prod f g = fun i : ι => (f i, g i) := rfl + +@[simp, grind =] lemma prod_apply (i : ι) : Function.prod f g i = (f i, g i) := rfl + +variable {f f' g g'} in +@[simp] theorem prod_inj : Function.prod f g = Function.prod f' g' ↔ f = f' ∧ g = g' := by + simp [funext_iff, Prod.ext_iff, forall_and] + +end DProd + +section Prod + +variable {α β : Type*} {ι : Sort*} (f : ι → α) (g : ι → β) + +theorem prod_ext_iff {h h' : ι → α × β} : + h = h' ↔ Prod.fst ∘ h = Prod.fst ∘ h' ∧ Prod.snd ∘ h = Prod.snd ∘ h' := + prod_inj + +@[simp] lemma prod_fst_snd : Function.prod (Prod.fst : _ → α) (Prod.snd : _ → β) = id := rfl +@[simp] lemma prod_snd_fst : Function.prod (Prod.snd : _ → β) (Prod.fst : _ → α) = .swap := rfl + +@[simp] theorem fst_comp_prod : Prod.fst ∘ Function.prod f g = f := rfl +@[simp] theorem snd_comp_prod : Prod.snd ∘ Function.prod f g = g := rfl + +@[simp] theorem prod_fst_comp_snd_comp (h : ι → α × β) : + Function.prod (Prod.fst ∘ h) (Prod.snd ∘ h) = h := rfl + +theorem const_prod (p : α × β) : const ι p = Function.prod (const ι p.1) (const ι p.2) := rfl + +@[simp] theorem prod_const_const (a : α) (b : β) : + Function.prod (const ι a) (const ι b) = const ι (a, b) := rfl + +theorem prod_comp {κ} (h : κ → ι) : Function.prod f g ∘ h = Function.prod (f ∘ h) (g ∘ h) := rfl + +@[simp] theorem prod_comp_fst_comp_snd {α₁ α₂ β₁ β₂} (f : α₁ → α₂) (g : β₁ → β₂) : + Function.prod (f ∘ Prod.fst) (g ∘ Prod.snd) = Prod.map f g := rfl + +@[simp] theorem map_comp_prod {γ δ} (h : α → γ) (k : β → δ) : + Prod.map h k ∘ Function.prod f g = Function.prod (h ∘ f) (k ∘ g) := rfl + +theorem prod_comp_prod {γ δ} (h : α × β → γ) (k : α × β → δ) : + Function.prod h k ∘ Function.prod f g = + Function.prod (h ∘ Function.prod f g) (k ∘ Function.prod f g) := rfl + +@[simp] theorem swap_comp_prod : Prod.swap ∘ Function.prod f g = Function.prod g f := rfl + +end Prod /-- Given functions `f : β → β → φ` and `g : α → β`, produce a function `α → α → φ` that evaluates `g` on each argument, then applies `f` to the results. Can be used, e.g., to transfer a relation From 256af211f97764461eb4a6b90abd29b43a78ff25 Mon Sep 17 00:00:00 2001 From: Luigi Massacci <48868075+luigi-massacci@users.noreply.github.com> Date: Wed, 1 Jul 2026 02:59:11 +0000 Subject: [PATCH 0498/1300] feat(Analysis/Distribution/Support): version for D' of existing lemmas for S' (#40796) This is an almost direct copy-paste of the existing lemmas for tempered distributions to generic distributions. --- .../Analysis/Distribution/Distribution.lean | 5 ++ Mathlib/Analysis/Distribution/Support.lean | 90 ++++++++++++++++++- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/Distribution/Distribution.lean b/Mathlib/Analysis/Distribution/Distribution.lean index a9731fcfaa4774..141a771d758926 100644 --- a/Mathlib/Analysis/Distribution/Distribution.lean +++ b/Mathlib/Analysis/Distribution/Distribution.lean @@ -259,6 +259,11 @@ lemma lineDerivOp_eq_lineDerivCLM {v : E} {T : 𝓓'(Ω, F)} : ∂_{v} T = lineDerivCLM v T := rfl +@[simp] +theorem lineDerivOp_apply_apply (f : 𝓓'(Ω, F)) (g : 𝓓(Ω, ℝ)) (m : E) : + ∂_{m} f g = f (- ∂_{m} g) := by + rw [map_neg]; rfl + noncomputable instance : LineDerivAdd E 𝓓'(Ω, F) 𝓓'(Ω, F) where lineDerivOp_add v := map_add (lineDerivCLM v) lineDerivOp_left_add _ _ T := congr($lineDerivCLM_add T) diff --git a/Mathlib/Analysis/Distribution/Support.lean b/Mathlib/Analysis/Distribution/Support.lean index b1e1c0da3d5c20..aea1884470473b 100644 --- a/Mathlib/Analysis/Distribution/Support.lean +++ b/Mathlib/Analysis/Distribution/Support.lean @@ -6,6 +6,7 @@ Authors: Moritz Doll, Anatole Dedecker module public import Mathlib.Analysis.Distribution.TemperedDistribution +public import Mathlib.Analysis.Distribution.Distribution /-! # Support of distributions @@ -24,7 +25,8 @@ compactly supported) and all basic properties are proved in an abstract setting distribution vanishes on the complement of the set. ## Main statements -* `TemperedDistribution.dsupport_delta`: The support of the delta distribution is a single point. +* `dsupport_delta`: The support of the delta distribution is a single point. Available for tempered + and classical distributions. -/ @@ -169,6 +171,8 @@ end normed open SchwartzMap Distribution TemperedDistribution +namespace TemperedDistribution + variable [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedSpace ℝ E] [NormedSpace ℂ F] variable {f : 𝓢'(E, F)} {s : Set E} @@ -185,13 +189,16 @@ theorem smulLeftCLM (hf : IsVanishingOn f s) {g : E → ℂ} (hg : g.HasTemperat rw [SchwartzMap.smulLeftCLM_apply hg] exact (tsupport_smul_subset_right g u).trans hu +@[deprecated (since := "2026-06-27")] alias Distribution.IsVanishingOn.smulLeftCLM := + Distribution.TemperedDistribution.IsVanishingOn.smulLeftCLM + open LineDeriv @[fun_prop] theorem lineDerivOp (hf : IsVanishingOn f s) (m : E) : IsVanishingOn (∂_{m} f : 𝓢'(E, F)) s := by intro u hu - simp only [lineDerivOp_apply_apply, map_neg, neg_eq_zero] + simp only [TemperedDistribution.lineDerivOp_apply_apply, map_neg, neg_eq_zero] exact hf (∂_{m} u) <| (tsupport_fderiv_apply_subset ℝ m).trans hu @[fun_prop] @@ -201,7 +208,7 @@ theorem iteratedLineDerivOp {n : ℕ} (hf : IsVanishingOn f s) (m : Fin n → E) | zero => exact hf | succ n IH => - exact (IH <| Fin.tail m).lineDerivOp (m 0) + exact lineDerivOp (IH <| Fin.tail m) (m 0) @[fun_prop] theorem _root_.TemperedDistribution.isVanishingOn_delta (x : E) : @@ -218,6 +225,9 @@ theorem dsupport_smulLeftCLM_subset {g : E → ℂ} (hg : g.HasTemperateGrowth) dsupport (smulLeftCLM F g f) ⊆ dsupport f := by gcongr; fun_prop +@[deprecated (since := "2026-06-27")] alias Distribution.dsupport_smulLeftCLM_subset := + Distribution.TemperedDistribution.dsupport_smulLeftCLM_subset + open LineDeriv theorem dsupport_lineDerivOp_subset (m : E) : dsupport (∂_{m} f : 𝓢'(E, F)) ⊆ dsupport f := by @@ -245,4 +255,78 @@ theorem dsupport_delta [FiniteDimensional ℝ E] (x : E) : end Support +end TemperedDistribution + +/-! ## Classical distributions -/ + +open TopologicalSpace Distributions + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {Ω : Opens E} + {F : Type*} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] + {n : ℕ∞} + +variable {f : 𝓓'(Ω, F)} {s : Set E} + +namespace IsVanishingOn + +open scoped Topology + +open LineDeriv + +@[fun_prop] +theorem lineDerivOp (hf : IsVanishingOn f s) (m : E) : + IsVanishingOn (∂_{m} f : 𝓓'(Ω, F)) s := by + intro u hu + simp only [Distribution.lineDerivOp_apply_apply, map_neg, neg_eq_zero] + exact hf (∂_{m} u) <| (tsupport_fderiv_apply_subset ℝ m).trans hu + +@[fun_prop] +theorem iteratedLineDerivOp {n : ℕ} (hf : IsVanishingOn f s) (m : Fin n → E) : + IsVanishingOn (∂^{m} f : 𝓓'(Ω, F)) s := by + induction n with + | zero => + exact hf + | succ n IH => + exact lineDerivOp (IH <| Fin.tail m) (m 0) + +@[fun_prop] +theorem _root_.Distribution.isVanishingOn_delta (x : E) : + IsVanishingOn (Distribution.delta x : 𝓓'^{n}(Ω, ℝ)) {x}ᶜ := by + intro u hu + rw [Set.subset_compl_singleton_iff] at hu + apply image_eq_zero_of_notMem_tsupport hu + +end IsVanishingOn + +section Support + +open LineDeriv + +theorem dsupport_lineDerivOp_subset (m : E) : dsupport (∂_{m} f : 𝓓'(Ω, F)) ⊆ dsupport f := by + gcongr; fun_prop + +theorem dsupport_iteratedLineDerivOp_subset {n : ℕ} (m : Fin n → E) : + dsupport (∂^{m} f : 𝓓'(Ω, F)) ⊆ dsupport f := by + gcongr; fun_prop + +theorem dsupport_delta [FiniteDimensional ℝ E] (x : E) (hx : x ∈ Ω) : + dsupport (Distribution.delta x : 𝓓'^{n}(Ω, ℝ)) = {x} := by + apply subset_antisymm + · intro x' hx' + rw [mem_dsupport_iff] at hx' + exact hx' {x} (isVanishingOn_delta x) (T1Space.t1 x) + rintro x rfl + rw [mem_dsupport_iff_forall_exists_ne] + intro s hxs hs + set t := s ∩ Ω + have ht : IsOpen t := hs.inter Ω.isOpen + have htx : x ∈ t := Set.mem_inter hxs hx + obtain ⟨u, h₁, h₂, h₃, -, h₄⟩ := + exists_contDiff_tsupport_subset (n := n) ((IsOpen.mem_nhds_iff ht).mpr htx) + exact ⟨⟨u, h₃, h₂, by aesop⟩, ⟨by aesop, by simp [h₄]⟩⟩ + +end Support + end Distribution From 9dcbf323f32d24bd59bdd5ef495cebe1f9d1e07e Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:09:11 +0000 Subject: [PATCH 0499/1300] =?UTF-8?q?feat(Order/ConditionallyCompleteLatti?= =?UTF-8?q?ce):=20`sSup=20(f=20''=20s)=20=E2=89=A4=20f=20(sSup=20s)`=20(#3?= =?UTF-8?q?5822)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConditionallyCompleteLattice/Basic.lean | 24 ++++++++++++++++++- .../ConditionallyCompleteLattice/Finset.lean | 17 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index 31ad01f242423e..70cd9673351c01 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -742,7 +742,11 @@ end WithTop namespace Monotone -variable [Preorder α] [ConditionallyCompleteLattice β] {f : α → β} (h_mono : Monotone f) +variable [ConditionallyCompleteLattice β] + +section Preorder + +variable [Preorder α] {f : α → β} (h_mono : Monotone f) include h_mono /-! A monotone function into a conditionally complete lattice preserves the ordering properties of @@ -758,6 +762,24 @@ theorem csSup_image_le {s : Set α} (hs : s.Nonempty) {B : α} (hB : B ∈ upper sSup (f '' s) ≤ f B := csSup_le (Nonempty.image f hs) (h_mono.mem_upperBounds_image hB) +end Preorder + +section ConditionallyCompleteLattice + +variable [ConditionallyCompleteLattice α] +variable {f : α → β} {s : Set α} (hs : s.Nonempty) (hf : Monotone f) +include hs hf + +theorem csSup_image_le_map_csSup (hbdd : BddAbove s := by bddDefault) : + sSup (f '' s) ≤ f (sSup s) := + csSup_image_le hf hs <| isLUB_csSup hs hbdd |>.left + +theorem map_csInf_le_csInf_image (hbdd : BddBelow s := by bddDefault) : + f (sInf s) ≤ sInf (f '' s) := + le_csInf_image hf hs <| isGLB_csInf hs hbdd |>.left + +end ConditionallyCompleteLattice + end Monotone lemma MonotoneOn.csInf_eq_of_subset_of_forall_exists_le diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 386e4e5f5ff243..13265fb034c9c9 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -51,6 +51,23 @@ theorem Set.Finite.csSup_lt_iff (hs : s.Finite) (h : s.Nonempty) : sSup s < a theorem Set.Finite.lt_csInf_iff (hs : s.Finite) (h : s.Nonempty) : a < sInf s ↔ ∀ x ∈ s, a < x := @Set.Finite.csSup_lt_iff αᵒᵈ _ _ _ hs h +section ConditionallyCompleteLattice + +variable [ConditionallyCompleteLattice β] {f : α → β} (hmono : Monotone f) +include hmono + +theorem Set.Finite.map_sSup_of_monotone {s : Set α} (hne : s.Nonempty) (hfin : s.Finite) : + f (sSup s) = sSup (f '' s) := + le_antisymm (hmono.le_csSup_image (hne.csSup_mem hfin) hfin.bddAbove) + (hmono.csSup_image_le_map_csSup hne hfin.bddAbove) + +theorem Set.Finite.map_sInf_of_monotone {s : Set α} (hne : s.Nonempty) (hfin : s.Finite) : + f (sInf s) = sInf (f '' s) := + le_antisymm (hmono.map_csInf_le_csInf_image hne hfin.bddBelow) + (hmono.csInf_image_le (hne.csInf_mem hfin) hfin.bddBelow) + +end ConditionallyCompleteLattice + variable (f : ι → α) theorem Finset.ciSup_eq_max'_image {s : Finset ι} (h : ∃ x ∈ s, sSup ∅ ≤ f x) From 28c4f6cb1875f8a1e4638bd5abcd122ace73ef11 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:09:13 +0000 Subject: [PATCH 0500/1300] chore(Data/Matrix/Basic): mention `mopMatrix` in `transpose{Ring/Alg}Equiv`s docstring and vice versa (#39123) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `RingEquiv.mopMatrix` and `transposeRingEquiv` differ by a `ᵐᵒᵖ` since the latter assumes `CommMagma α` instead of `Mul α` - `AlgEquiv.mopMatrix` and `transposeAlgEquiv` differ by a `ᵐᵒᵖ` since the latter assumes `CommSemiring α` instead of `Semiring α` --- Mathlib/Data/Matrix/Basic.lean | 29 ++++++++++++++++---------- Mathlib/LinearAlgebra/Matrix/Defs.lean | 11 +++++++++- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Mathlib/Data/Matrix/Basic.lean b/Mathlib/Data/Matrix/Basic.lean index fdb89e65825736..6511fb8b1a3a9d 100644 --- a/Mathlib/Data/Matrix/Basic.lean +++ b/Mathlib/Data/Matrix/Basic.lean @@ -639,17 +639,16 @@ theorem mapMatrix_trans (f : α ≃+* β) (g : β ≃+* γ) : rfl open MulOpposite in -/-- -For any ring `R`, we have ring isomorphism `Matₙₓₙ(Rᵒᵖ) ≅ (Matₙₓₙ(R))ᵒᵖ` given by transpose. --/ +/-- For any ring `α`, we have ring isomorphism `Matₙₓₙ(αᵒᵖ) ≅ (Matₙₓₙ(α))ᵒᵖ` given by transpose. + +See also `Matrix.transposeRingEquiv` for a version that doesn't take the opposite of `α`, +given that its multiplication is commutative. -/ @[simps apply symm_apply] def mopMatrix {α} [Mul α] [AddCommMonoid α] : Matrix m m αᵐᵒᵖ ≃+* (Matrix m m α)ᵐᵒᵖ where toFun M := op (M.transpose.map unop) invFun M := M.unop.transpose.map op - left_inv _ := by aesop - right_inv _ := by aesop - map_mul' _ _ := unop_injective <| by ext; simp [transpose, mul_apply] - map_add' _ _ := by aesop + map_mul' _ _ := unop_injective <| by ext; simp [mul_apply] + map_add' _ _ := rfl end RingEquiv @@ -721,8 +720,10 @@ theorem mapMatrix_trans (f : α ≃ₐ[R] β) (g : β ≃ₐ[R] γ) : rfl /-- For any algebra `α` over a ring `R`, we have an `R`-algebra isomorphism -`Matₙₓₙ(αᵒᵖ) ≅ (Matₙₓₙ(R))ᵒᵖ` given by transpose. If `α` is commutative, -we can get rid of the `ᵒᵖ` in the left-hand side, see `Matrix.transposeAlgEquiv`. -/ +`Matₙₓₙ(αᵒᵖ) ≅ (Matₙₓₙ(R))ᵒᵖ` given by transpose. + +See also `Matrix.transposeAlgEquiv` for a version that doesn't take the opposite of `α`, +given that its multiplication is commutative. -/ @[simps!] def mopMatrix : Matrix m m αᵐᵒᵖ ≃ₐ[R] (Matrix m m α)ᵐᵒᵖ where __ := RingEquiv.mopMatrix commutes' _ := MulOpposite.unop_injective <| by @@ -894,7 +895,10 @@ theorem transposeLinearEquiv_symm [Semiring R] [AddCommMonoid α] [Module R α] variable {m n R α} variable (m α) -/-- `Matrix.transpose` as a `RingEquiv` to the opposite ring -/ +/-- `Matrix.transpose` as a `RingEquiv` to the opposite ring. + +See also `RingEquiv.mopMatrix` for a version that doesn't require `α` to have commutative +multiplication, by taking its opposite. -/ @[simps!] def transposeRingEquiv [AddCommMonoid α] [CommMagma α] [Fintype m] : Matrix m m α ≃+* (Matrix m m α)ᵐᵒᵖ where @@ -914,7 +918,10 @@ theorem transpose_list_prod [CommSemiring α] [Fintype m] [DecidableEq m] (l : L variable (R m α) -/-- `Matrix.transpose` as an `AlgEquiv` to the opposite ring -/ +/-- `Matrix.transpose` as an `AlgEquiv` to the opposite ring. + +See also `AlgEquiv.mopMatrix` for a version that doesn't require `α` to have commutative +multiplication, by taking its opposite. -/ @[simps!] def transposeAlgEquiv [CommSemiring R] [CommSemiring α] [Fintype m] [DecidableEq m] [Algebra R α] : Matrix m m α ≃ₐ[R] (Matrix m m α)ᵐᵒᵖ where diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index 2d18b759ff2821..e36bc8ec9d5b62 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -135,7 +135,16 @@ theorem map_injective {f : α → β} (hf : Function.Injective f) : theorem map_involutive {f : α → α} (hf : Function.Involutive f) : Function.Involutive fun M : Matrix m n α ↦ M.map f := by intro; simp [hf] -/-- The transpose of a matrix. -/ +/-- The transpose of a matrix. + +This is available in bundled forms as: +* `Matrix.transposeAddEquiv` +* `Matrix.transposeLinearEquiv` +* `Matrix.transposeRingEquiv` +* `Matrix.transposeAlgEquiv` +* `RingEquiv.mopMatrix` +* `AlgEquiv.mopMatrix` +-/ def transpose (M : Matrix m n α) : Matrix n m α := of fun x y => M y x From ad6b66075be33b728fbc0277b33cf7b8a9f4d5e6 Mon Sep 17 00:00:00 2001 From: Li Jiale <185082061+Scarlett-le@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:09:15 +0000 Subject: [PATCH 0501/1300] feat(Geometry/Euclidean/Sphere): add lemmas about points on a sphere (#41143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds three lemmas to `Mathlib/Geometry/Euclidean/Sphere/Basic.lean`. - `Sphere.ne_center_of_mem_of_mem_of_ne`: a point of a sphere that differs from another point of the sphere is not its center. Extracted at a reviewer's suggestion; this fact was reproved inline four times across #41121 and #41123. - `norm_vsub_center_eq_radius`: for a point `p` on a sphere `s`, `‖p -ᵥ s.center‖ = s.radius`. This pattern occurs ten times in #34164 and four more times in the present file (twice in `inner_vsub_center_vsub_pos` and twice in `Sphere.dist_center_lt_radius_of_sbtw`); those four in-file occurrences are golfed to use it here. - `Sphere.center_mem_affineSpan_pair_iff_isDiameter`: for two distinct points of a sphere, the center lies on the line through them if and only if those points are the endpoints of a diameter. No mathematical content changes; the existing proofs are only shortened. Co-authored-by: Scarlett-le <735979178@qq.com> Co-authored-by: Jireh Loreaux --- Mathlib/Geometry/Euclidean/Sphere/Basic.lean | 30 +++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean index e641855739337f..89c2f614e760ed 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean @@ -138,6 +138,11 @@ lemma Sphere.radius_nonneg_of_mem {s : Sphere P} {p : P} (h : p ∈ s) : 0 ≤ s @[simp] lemma Sphere.center_mem_iff {s : Sphere P} : s.center ∈ s ↔ s.radius = 0 := by simp [mem_sphere, eq_comm] +/-- A point of a sphere that differs from another point of the sphere is not its center. -/ +lemma Sphere.ne_center_of_mem_of_mem_of_ne {s : Sphere P} {p q : P} + (hp : p ∈ s) (hq : q ∈ s) (hpq : p ≠ q) : p ≠ s.center := by + grind [dist_eq_zero, mem_sphere'] + /-- A set of points is cospherical if they are equidistant from some point. In two dimensions, this is the same thing as being concyclic. -/ @@ -206,6 +211,12 @@ theorem Cospherical.subtype_val {S : AffineSubspace ℝ P} [Nonempty S] {ps : Se (hps : Cospherical ps) : Cospherical (Subtype.val '' ps) := Isometry.cospherical S.subtypeₐᵢ.isometry hps +omit [NormedSpace ℝ V] in +/-- For a point on a sphere, the norm of its displacement from the center equals the radius. -/ +theorem norm_vsub_center_eq_radius {s : Sphere P} {p : P} (hp : p ∈ s) : + ‖p -ᵥ s.center‖ = s.radius := by + rw [← dist_eq_norm_vsub']; exact mem_sphere'.mp hp + lemma Sphere.nonempty_iff [Nontrivial V] {s : Sphere P} : (s : Set P).Nonempty ↔ 0 ≤ s.radius := by refine ⟨fun ⟨p, hp⟩ ↦ radius_nonneg_of_mem hp, fun h ↦ ?_⟩ obtain ⟨v, hv⟩ := (NormedSpace.sphere_nonempty (x := (0 : V)) (r := s.radius)).2 h @@ -456,8 +467,8 @@ theorem Sphere.dist_center_lt_radius_of_sbtw {p₁ p₂ p : P} {s : Sphere P} have ht₁' : t < 1 := lt_of_le_of_ne ht₁ fun h => hne₂ <| by rw [← hpt, h, AffineMap.lineMap_apply_one] set u := p₁ -ᵥ o; set v := p₂ -ᵥ o - have hu : ‖u‖ = s.radius := by rw [← dist_eq_norm_vsub]; exact mem_sphere.mp hp₁ - have hv : ‖v‖ = s.radius := by rw [← dist_eq_norm_vsub]; exact mem_sphere.mp hp₂ + have hu : ‖u‖ = s.radius := norm_vsub_center_eq_radius hp₁ + have hv : ‖v‖ = s.radius := norm_vsub_center_eq_radius hp₂ have huv : u ≠ v := fun h => hne₁ <| by rw [← hpt, vsub_left_cancel h, AffineMap.lineMap_same, AffineMap.const_apply] have hpo : p -ᵥ o = (1 - t) • u + t • v := by @@ -551,8 +562,8 @@ the radius vector at one endpoint is negative. -/ theorem inner_vsub_center_vsub_pos {p₁ p₂ : P} {s : Sphere P} (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (hp₁p₂ : p₁ ≠ p₂) : 0 < ⟪p₂ -ᵥ p₁, s.center -ᵥ p₁⟫ := by - have hp₁' : ‖p₁ -ᵥ s.center‖ = s.radius := by rw [← dist_eq_norm_vsub']; exact mem_sphere'.mp hp₁ - have hp₂' : ‖p₂ -ᵥ s.center‖ = s.radius := by rw [← dist_eq_norm_vsub']; exact mem_sphere'.mp hp₂ + have hp₁' : ‖p₁ -ᵥ s.center‖ = s.radius := norm_vsub_center_eq_radius hp₁ + have hp₂' : ‖p₂ -ᵥ s.center‖ = s.radius := norm_vsub_center_eq_radius hp₂ have hd : ‖p₂ -ᵥ s.center‖ ^ 2 = ‖p₂ -ᵥ p₁‖ ^ 2 + 2 * ⟪p₂ -ᵥ p₁, p₁ -ᵥ s.center⟫ + ‖p₁ -ᵥ s.center‖ ^ 2 := by rw [← vsub_add_vsub_cancel p₂ p₁ s.center, norm_add_sq_real] @@ -593,6 +604,17 @@ lemma isDiameter_iff_mem_and_mem_and_wbtw : rw [mem_sphere.1 h₁, mem_sphere'.1 h₂, ← two_mul, eq_comm] at hd exact isDiameter_iff_mem_and_mem_and_dist.2 ⟨h₁, h₂, hd⟩ +/-- The center lies on the line through two distinct points of a sphere if and only if those +points are the endpoints of a diameter. -/ +theorem center_mem_affineSpan_pair_iff_isDiameter + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (hp₁p₂ : p₁ ≠ p₂) : + s.center ∈ line[ℝ, p₁, p₂] ↔ s.IsDiameter p₁ p₂ := by + rw [isDiameter_iff_mem_and_mem_and_wbtw] + refine ⟨fun h => ⟨hp₁, hp₂, ?_⟩, fun h => h.2.2.mem_affineSpan⟩ + refine wbtw_of_collinear_of_dist_center_le_radius ?_ hp₁ ?_ hp₂ hp₁p₂ + · rw [Set.insert_comm]; exact collinear_insert_of_mem_affineSpan_pair h + · simpa using radius_nonneg_of_mem hp₁ + end Sphere end EuclideanSpace From c8aed1aceb1712c2d808e0081ce69dc53918bad4 Mon Sep 17 00:00:00 2001 From: Chris Lloyd <868215+cjrl@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:52:49 +0000 Subject: [PATCH 0502/1300] feat(Combinatorics): set-valued pigeonhole principle (#37190) This PR contributes two theorems to combinatorics: - `exists_lt_card_cover_of_card_biUnion_lt_card` is a set-valued version of the pigeonhole principle. - `sum_card_eq_sum_card_cover_biUnion` is a set theoretic corollary of a double counting result proved for bipartite graphs (`Finset.sum_card_bipartiteAbove_eq_sum_card_bipartiteBelow`). This was needed to prove the above pigeonhole principle. The motivation for these results is our Latin Square PR #36698. These results were proved in less general terms in that PR, but are independent of Latin Square considerations and so we have generalized and moved them into more relevant files. Co-authored-by: Christopher J. R. Lloyd Co-authored-by: George H. Seelinger --- .../Enumerative/DoubleCounting.lean | 10 +++++++ Mathlib/Combinatorics/Pigeonhole.lean | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean b/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean index dcaf5eec09d35a..cefd3bfb853fe6 100644 --- a/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean +++ b/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean @@ -203,6 +203,16 @@ theorem card_le_card_of_forall_subsingleton' (ht : ∀ b ∈ t, ∃ a, a ∈ s (hs : ∀ a ∈ s, ({ b ∈ t | r a b } : Set β).Subsingleton) : #t ≤ #s := card_le_card_of_forall_subsingleton (swap r) ht hs +/-- Given a finite collection of finite subsets $B_1, \ldots, B_k$ +and, for every $x \in \bigcup_i B_i$, let $C_x$ be the set of indices +of the $B_i$'s that contain $x$. Then, $\sum_i |B_i| = \sum_x |C_x|$. -/ +lemma sum_card_eq_sum_biUnion_card [Fintype α] [DecidableEq α] [DecidableEq β] + (B : α → Finset β) (s : Finset α) : + ∑ j ∈ s, #(B j) = ∑ x ∈ s.biUnion B, #{j | j ∈ s ∧ x ∈ B j} := by + convert sum_card_bipartiteAbove_eq_sum_card_bipartiteBelow (fun j x => x ∈ B j) + · grind [bipartiteAbove] + · grind [bipartiteBelow] + end Bipartite end Finset diff --git a/Mathlib/Combinatorics/Pigeonhole.lean b/Mathlib/Combinatorics/Pigeonhole.lean index f76c77f931577d..8c2b16d3c1cbe9 100644 --- a/Mathlib/Combinatorics/Pigeonhole.lean +++ b/Mathlib/Combinatorics/Pigeonhole.lean @@ -11,6 +11,8 @@ public import Mathlib.Data.Nat.ModEq public import Mathlib.Order.Preorder.Finite public import Mathlib.Algebra.Order.BigOperators.Group.Finset +import Mathlib.Combinatorics.Enumerative.DoubleCounting + /-! # Pigeonhole principles @@ -45,6 +47,8 @@ The versions vary by: (`∀ x ∈ s, f x ∈ t`), or assume that for `y ∉ t`, the total weight of the pigeons in this pigeonhole `∑ x ∈ s with f x = y, w x` is nonpositive or nonnegative depending on the inequality we are proving. +* in the case where the "holes" are not necessarily disjoint, that is, a pigeon could be in multiple + holes at the same time, a set-valued version is provided. Lemma names follow `mathlib` convention (e.g., `Finset.exists_lt_sum_fiber_of_maps_to_of_nsmul_lt_sum`); "pigeonhole principle" is mentioned in the @@ -288,6 +292,31 @@ theorem exists_card_fiber_le_of_card_le_mul (ht : t.Nonempty) (hn : #s ≤ #t * ∃ y ∈ t, #{x ∈ s | f x = y} ≤ n := exists_card_fiber_le_of_card_le_nsmul ht hn +/-- A version of the pigeonhole principle for set-valued functions. + +Given a family of sets `f : α → Finset β` and a choice of indices `s : Finset α`. +Let `k` denote the minimum cardinality of the `f j`s. +If the cardinality of the union `s.biUnion f` is less than `s.card`, then +there exists an element `x ∈ s.biUnion f` which is covered by more than `k` of the sets +`f j` (i.e., `k < #{j ∈ s | x ∈ f j}`). + +This is a double-counting variant of the pigeonhole principle. +Unlike the classical pigeonhole principle (see +`Finset.exists_lt_card_fiber_of_nsmul_lt_card_of_maps_to`), +this formulation handles a *set-valued* assignment where elements may belong to +multiple sets simultaneously. -/ +lemma exists_mem_exists_mem_inf'_card_lt [DecidableEq α] [Fintype α] {f : α → Finset β} + (h₁ : s.Nonempty) (h₂ : ∀ j ∈ s, 0 < #(f j)) (h₃ : #(s.biUnion f) < #s) : + ∃ a ∈ s, ∃ x ∈ f a, (s.inf' h₁ fun j ↦ #(f j)) < #{j | j ∈ s ∧ x ∈ f j} := by + set k := s.inf' h₁ (fun j ↦ #(f j)) with hk + contrapose! h₃ + suffices #s • k ≤ #(s.biUnion f) • k by simp_all + simp only [← Finset.sum_const] + calc ∑ j ∈ s, k + _ ≤ ∑ j ∈ s, #(f j) := by gcongr with i hi; exact inf'_le _ hi + _ = ∑ x ∈ s.biUnion f, #{j | j ∈ s ∧ x ∈ f j} := by rw [sum_card_eq_sum_biUnion_card] + _ ≤ ∑ x ∈ s.biUnion f, k := by gcongr; grind + end Finset namespace Fintype From 73c4ee2acf7f227c4d78dd6651462c59511b27d6 Mon Sep 17 00:00:00 2001 From: Kevin Wilson <1527442+khwilson@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:52:52 +0000 Subject: [PATCH 0503/1300] feat(Topology/Semicontinuity/Hemicontinuity): characterizations of hemicontinuous notions (#38601) In the previous PR we introduced two new notions attached to correspondences: having open lower sections and having an open graph. This commit introduces several useful characterizations of these notions and uses them to prove several constructions around hemicontinuous maps Co-authored-by: Kevin H Wilson --- .../Semicontinuity/Hemicontinuity.lean | 142 +++++++++++++++--- 1 file changed, 118 insertions(+), 24 deletions(-) diff --git a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean index 4f232c3b43625d..7e3e18d8a77616 100644 --- a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean +++ b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean @@ -10,7 +10,6 @@ public import Mathlib.Topology.NhdsWithin public import Mathlib.Topology.Separation.Regular public import Mathlib.Topology.Defs.Sequences import Mathlib.Topology.Sequences -import Mathlib.Topology.ContinuousOn /-! # Hemicontinuity @@ -63,7 +62,7 @@ alias ⟨UpperHemicontinuous.forall_isOpen, UpperHemicontinuous.of_forall_isOpen /-! ### Characterization in terms of preimages of intervals of sets -/ lemma upperHemicontinuousWithinAt_iff_preimage_Iic : - UpperHemicontinuousWithinAt f s x ↔ ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' (Iic u) ∈ 𝓝[s] x := by + UpperHemicontinuousWithinAt f s x ↔ ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' Iic u ∈ 𝓝[s] x := by simp_rw [upperHemicontinuousWithinAt_iff] rw [hasBasis_nhdsSet (f x) |>.forall_iff ?h₁, hasBasis_nhdsSet (f x) |>.forall_iff ?h₂] case h₂ => @@ -77,24 +76,24 @@ lemma upperHemicontinuousWithinAt_iff_preimage_Iic : simp [hu.mem_nhdsSet, eventually_iff, Iic] lemma upperHemicontinuousAt_iff_preimage_Iic : - UpperHemicontinuousAt f x ↔ ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' (Iic u) ∈ 𝓝 x := by + UpperHemicontinuousAt f x ↔ ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' Iic u ∈ 𝓝 x := by simpa [upperHemicontinuousWithinAt_univ_iff] using upperHemicontinuousWithinAt_iff_preimage_Iic (s := univ) lemma upperHemicontinuousOn_iff_preimage_Iic : - UpperHemicontinuousOn f s ↔ ∀ x ∈ s, ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' (Iic u) ∈ 𝓝[s] x := by + UpperHemicontinuousOn f s ↔ ∀ x ∈ s, ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' Iic u ∈ 𝓝[s] x := by simp [upperHemicontinuousOn_iff, upperHemicontinuousWithinAt_iff_preimage_Iic] lemma upperHemicontinuous_iff_preimage_Iic : - UpperHemicontinuous f ↔ ∀ x, ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' (Iic u) ∈ 𝓝 x := by + UpperHemicontinuous f ↔ ∀ x, ∀ u ∈ 𝓝ˢ (f x), f ⁻¹' Iic u ∈ 𝓝 x := by simp [upperHemicontinuous_iff, upperHemicontinuousAt_iff_preimage_Iic] /-- A correspondence `f : α → Set β` is upper hemicontinuous if and only if its *upper inverse* (i.e., `u : Set β ↦ f ⁻¹' (Iic u)`, note that `f ⁻¹' (Iic u) = {x | f x ⊆ u}`) sends open sets to open sets. -/ lemma upperHemicontinuous_iff_isOpen_preimage_Iic : - UpperHemicontinuous f ↔ ∀ u, IsOpen u → IsOpen (f ⁻¹' (Iic u)) := by - simp_rw [upperHemicontinuous_iff_preimage_Iic, isOpen_iff_mem_nhds (s := f ⁻¹' (Iic _))] + UpperHemicontinuous f ↔ ∀ u, IsOpen u → IsOpen (f ⁻¹' Iic u) := by + simp_rw [upperHemicontinuous_iff_preimage_Iic, isOpen_iff_mem_nhds (s := f ⁻¹' Iic _)] conv => enter [1, x] rw [hasBasis_nhdsSet (f x) |>.forall_iff <| @@ -105,7 +104,7 @@ lemma upperHemicontinuous_iff_isOpen_preimage_Iic : (i.e., `u : Set β ↦ (f ⁻¹' (Iic uᶜ))ᶜ`, note that `f ⁻¹' (Iic u) = {x | (f x ∩ u).Nonempty}`) sends closed sets to closed sets. -/ lemma upperHemicontinuous_iff_isClosed_compl_preimage_Iic_compl : - UpperHemicontinuous f ↔ ∀ u, IsClosed u → IsClosed (f ⁻¹' (Iic uᶜ))ᶜ := by + UpperHemicontinuous f ↔ ∀ u, IsClosed u → IsClosed (f ⁻¹' Iic uᶜ)ᶜ := by conv_rhs => rw [compl_surjective.forall] simp [← isOpen_compl_iff] @@ -116,21 +115,25 @@ lemma isClosedMap_iff_upperHemicontinuous {f : α → β} : rw [isClosedMap_iff_kernImage, upperHemicontinuous_iff_isOpen_preimage_Iic] aesop +lemma lowerHemicontinuous_iff_isOpen_inter_nonempty : + LowerHemicontinuous f ↔ ∀ u, IsOpen u → IsOpen {x | (f x ∩ u).Nonempty} := by + simp_rw [lowerHemicontinuous_iff, lowerHemicontinuousAt_iff, isOpen_iff_mem_nhds, + forall_comm (α := α), mem_setOf, Filter.Eventually] + /-- A correspondence `f : α → Set β` is lower hemicontinuous if and only if its *lower inverse* (i.e., `u : Set β ↦ (f ⁻¹' (Iic uᶜ))ᶜ`, note that `f ⁻¹' (Iic u) = {x | (f x ∩ u).Nonempty}`) sends open sets to open sets. -/ lemma lowerHemicontinuous_iff_isOpen_compl_preimage_Iic_compl : - LowerHemicontinuous f ↔ ∀ u, IsOpen u → IsOpen (f ⁻¹' (Iic uᶜ))ᶜ := by + LowerHemicontinuous f ↔ ∀ u, IsOpen u → IsOpen (f ⁻¹' Iic uᶜ)ᶜ := by have (u : Set β) : (f ⁻¹' (Iic uᶜ))ᶜ = {x | (f x ∩ u).Nonempty} := by simp [Set.ext_iff, Iic, Set.mem_compl_iff, Set.not_subset, Set.Nonempty] - simp_rw [lowerHemicontinuous_iff, lowerHemicontinuousAt_iff, this, isOpen_iff_mem_nhds, - forall_comm (α := α), mem_setOf, Filter.Eventually] + simpa [this] using lowerHemicontinuous_iff_isOpen_inter_nonempty /-- A correspondence `f : α → Set β` is lower hemicontinuous if and only if its *upper inverse* (i.e., `u : Set β ↦ f ⁻¹' (Iic u)`, note that `f ⁻¹' (Iic u) = {x | f x ⊆ u}`) sends closed sets to closed sets. -/ lemma lowerHemicontinuous_iff_isClosed_preimage_Iic : - LowerHemicontinuous f ↔ ∀ u, IsClosed u → IsClosed (f ⁻¹' (Iic u)) := by + LowerHemicontinuous f ↔ ∀ u, IsClosed u → IsClosed (f ⁻¹' Iic u) := by conv_rhs => rw [compl_surjective.forall] simp [← isOpen_compl_iff] @@ -141,13 +144,24 @@ lemma isOpenMap_iff_lowerHemicontinuous {f : α → β} : rw [isOpenMap_iff_kernImage, lowerHemicontinuous_iff_isClosed_preimage_Iic] aesop -/-! ### Singleton maps -/ +section singleton_maps + +/-! ### Singleton maps + +Functions `f : α → β` are continuous if and only if they are lower hemicontinuous if and only if +they are upper hemicontinuous. This is in the sense that the map `g : α → Set β` given by +`g x = {f x}` is both lower or upper hemicontinuous. + +This section also provides dot notation to access this fact for continuous functions. +-/ + +variable {f : α → β} {s : Set α} {x : α} lemma upperHemicontinuous_singleton_id : UpperHemicontinuous ({·} : α → Set α) := by simp [upperHemicontinuous_iff, upperHemicontinuousAt_iff] @[simp] -lemma upperHemicontinuousWithinAt_singleton_iff {f : α → β} {s : Set α} {x : α} : +lemma upperHemicontinuousWithinAt_singleton_iff : UpperHemicontinuousWithinAt ({f ·}) s x ↔ ContinuousWithinAt f s x := by refine ⟨?_, fun hf ↦ upperHemicontinuous_singleton_id.upperHemicontinuousWithinAt _ _ |>.comp hf (mapsTo_image _ _)⟩ @@ -157,21 +171,68 @@ lemma upperHemicontinuousWithinAt_singleton_iff {f : α → β} {s : Set α} {x filter_upwards [h t ht] with x exact mem_of_mem_nhds +alias ⟨_, ContinuousWithinAt.upperHemicontinuousWithinAt⟩ := + upperHemicontinuousWithinAt_singleton_iff + @[simp] -lemma upperHemicontinuousAt_singleton_iff {f : α → β} {x : α} : +lemma upperHemicontinuousAt_singleton_iff : UpperHemicontinuousAt ({f ·}) x ↔ ContinuousAt f x := by simp [← upperHemicontinuousWithinAt_univ_iff, continuousWithinAt_univ] +alias ⟨_, ContinuousAt.upperHemicontinuousAt⟩ := upperHemicontinuousAt_singleton_iff + @[simp] -lemma upperHemicontinuousOn_singleton_iff {f : α → β} {s : Set α} : +lemma upperHemicontinuousOn_singleton_iff : UpperHemicontinuousOn ({f ·}) s ↔ ContinuousOn f s := forall₂_congr <| fun _ _ ↦ upperHemicontinuousWithinAt_singleton_iff +alias ⟨_, ContinuousOn.upperHemicontinuousOn⟩ := upperHemicontinuousOn_singleton_iff + @[simp] -lemma upperHemicontinuous_singleton_iff {f : α → β} : +lemma upperHemicontinuous_singleton_iff : UpperHemicontinuous ({f ·}) ↔ Continuous f := by simp [← upperHemicontinuousOn_univ_iff] +alias ⟨_, Continuous.upperHemicontinuous⟩ := upperHemicontinuous_singleton_iff + +lemma lowerHemicontinuous_singleton_id : LowerHemicontinuous ({·} : α → Set α) := by + intro x t ⟨ht, hne⟩ + filter_upwards [ht.mem_nhds (Set.singleton_inter_nonempty.mp hne)] with x' hx' + exact ⟨ht, Set.singleton_inter_nonempty.mpr hx'⟩ + +@[simp] +lemma lowerHemicontinuousWithinAt_singleton_iff : + LowerHemicontinuousWithinAt ({f ·}) s x ↔ ContinuousWithinAt f s x := by + refine ⟨?_, fun hf ↦ (lowerHemicontinuous_singleton_id.lowerHemicontinuousWithinAt _ _).comp + hf (mapsTo_image _ _)⟩ + simp only [lowerHemicontinuousWithinAt_iff, Set.singleton_inter_nonempty, + ContinuousWithinAt, tendsto_iff_forall_eventually_mem] + intro h t ht + obtain ⟨u, hut, huo, hux⟩ := mem_nhds_iff.mp ht + exact (h u huo hux).mono fun _ hx' ↦ hut hx' + +alias ⟨_, ContinuousWithinAt.lowerHemicontinuousWithinAt⟩ := + lowerHemicontinuousWithinAt_singleton_iff + +@[simp] +lemma lowerHemicontinuousAt_singleton_iff : LowerHemicontinuousAt ({f ·}) x ↔ ContinuousAt f x := by + simp [← lowerHemicontinuousWithinAt_univ_iff, continuousWithinAt_univ] + +alias ⟨_, ContinuousAt.lowerHemicontinuousAt⟩ := lowerHemicontinuousAt_singleton_iff + +@[simp] +lemma lowerHemicontinuousOn_singleton_iff : LowerHemicontinuousOn ({f ·}) s ↔ ContinuousOn f s := + forall₂_congr <| fun _ _ ↦ lowerHemicontinuousWithinAt_singleton_iff + +alias ⟨_, ContinuousOn.lowerHemicontinuousOn⟩ := lowerHemicontinuousOn_singleton_iff + +@[simp] +lemma lowerHemicontinuous_singleton_iff : LowerHemicontinuous ({f ·}) ↔ Continuous f := by + simp [← lowerHemicontinuousOn_univ_iff] + +alias ⟨_, Continuous.lowerHemicontinuous⟩ := lowerHemicontinuous_singleton_iff + +end singleton_maps /-! ### Union and intersection, and post-composition with the preimage map -/ @@ -280,8 +341,7 @@ end Inducing The more general fact is that if `f` is upper hemicontinuous at `x₀` within `s`, and if `x₀` is a cluster point of `s ∩ {x | (f x).Nonempty}`, then `(f x₀).Nonempty`. -/ -lemma UpperHemicontinuous.isClosed_domain {α β : Type*} [TopologicalSpace α] - [TopologicalSpace β] {f : α → Set β} (hf : UpperHemicontinuous f) : +lemma UpperHemicontinuous.isClosed_domain (hf : UpperHemicontinuous f) : IsClosed {x | (f x).Nonempty} := by simp only [← isOpen_compl_iff, compl_setOf, not_nonempty_iff_eq_empty, isOpen_iff_mem_nhds] intro x (hx : f x = ∅) @@ -297,8 +357,7 @@ of sequences `x : ℕ → α` and `y : ℕ → β` such that `x` tends to `x₀` set containing all `f x'` for `x'` sufficiently close to `x`. This is a partial converse of `UpperHemicontinuousAt.mem_of_tendsto`. -/ -lemma UpperHemicontinuousAt.of_sequences {α β : Type*} [TopologicalSpace α] - [TopologicalSpace β] {f : α → Set β} {x₀ : α} [(𝓝 x₀).IsCountablyGenerated] +lemma UpperHemicontinuousAt.of_sequences {x₀ : α} [(𝓝 x₀).IsCountablyGenerated] {K : Set β} (hK : IsSeqCompact K) (hf : ∀ᶠ x in 𝓝 x₀, f x ⊆ K) (h : ∀ x : ℕ → α, Tendsto x atTop (𝓝 x₀) → ∀ y : ℕ → β, (∀ n, y n ∈ f (x n)) → ∀ y₀, Tendsto y atTop (𝓝 y₀) → y₀ ∈ f x₀) : @@ -319,9 +378,8 @@ closed, then for any sequences `x` and `y` (in `α` and `β`, respectively) tend respectively, if `y n ∈ f (x n)` frequently, then `y₀ ∈ f x₀`. This is a partial converse of `UpperHemicontinuousAt.of_sequences`. -/ -lemma UpperHemicontinuousAt.mem_of_tendsto {α β ι : Type*} [TopologicalSpace α] - [TopologicalSpace β] [RegularSpace β] {f : α → Set β} {x₀ : α} {l : Filter ι} - (hf : UpperHemicontinuousAt f x₀) (hf_closed : IsClosed (f x₀)) +lemma UpperHemicontinuousAt.mem_of_tendsto {ι : Type*} [RegularSpace β] {x₀ : α} + {l : Filter ι} (hf : UpperHemicontinuousAt f x₀) (hf_closed : IsClosed (f x₀)) {x : ι → α} (hx : Tendsto x l (𝓝 x₀)) {y : ι → β} (hy : ∃ᶠ n in l, y n ∈ f (x n)) {y₀ : β} (hy₀ : Tendsto y l (𝓝 y₀)) : y₀ ∈ f x₀ := by @@ -335,3 +393,39 @@ lemma UpperHemicontinuousAt.mem_of_tendsto {α β ι : Type*} [TopologicalSpace filter_upwards [hx (hf s hs)] with n hn hyn simp only [← subset_interior_iff_mem_nhdsSet, preimage_setOf_eq, mem_setOf_eq] at hn exact interior_subset <| hn hyn + +/-! ### Open lower sections -/ + +omit [TopologicalSpace β] in +/-- A correspondence `f : α → Set β` has open lower sections if and only if its *lower inverse* +(i.e., `b : β ↦ (f ⁻¹' (Iic {b}ᶜ))ᶜ = {x | b ∈ f x}`) sends every point to an open set. -/ +lemma hasOpenLowerSections_iff_isOpen_compl_preimage_Iic_compl : + HasOpenLowerSections f ↔ ∀ b, IsOpen (f ⁻¹' Iic {b}ᶜ)ᶜ := by + have h (b : β) : (f ⁻¹' (Iic {b}ᶜ))ᶜ = {x | b ∈ f x} := by + simp [Set.ext_iff, Iic, Set.mem_compl_iff] + simp_rw [h, hasOpenLowerSections_iff_isOpen] + +omit [TopologicalSpace β] in +/-- A correspondence `f : α → Set β` has open lower sections if and only if its *upper inverse* +(i.e., `b : β ↦ f ⁻¹' (Iic {b}ᶜ) = {x | b ∉ f x}`) sends every point to a closed set. -/ +lemma hasOpenLowerSections_iff_isClosed_preimage_Iic : + HasOpenLowerSections f ↔ ∀ b, IsClosed (f ⁻¹' Iic {b}ᶜ) := by + simp_rw [← isOpen_compl_iff] + exact hasOpenLowerSections_iff_isOpen_compl_preimage_Iic_compl + +/-! ### Open Graphs -/ + +/-- A lower hemicontinuous function intersected with a function with an open graph is lower +hemicontinuous. -/ +lemma LowerHemicontinuous.inter_hasOpenCGraph {f g : α → Set β} + (hf : LowerHemicontinuous f) (hg : HasOpenCGraph g) : + LowerHemicontinuous (fun x ↦ f x ∩ g x) := by + simp_rw [lowerHemicontinuous_iff_isOpen_inter_nonempty] at ⊢ hf + intro t ht + rw [isOpen_iff_forall_mem_open] + intro x ⟨y, ⟨hyf, hyg⟩, hyt⟩ + obtain ⟨U, V, hU, hV, hxU, hyV, hUV⟩ := (isOpen_prod_iff.mp hg) x y hyg + refine ⟨U ∩ {x' | (f x' ∩ (t ∩ V)).Nonempty}, ?_, hU.inter (hf _ (ht.inter hV)), + ⟨hxU, y, hyf, hyt, hyV⟩⟩ + intro x' ⟨hx'U, z, hzf, hzt, hzV⟩ + exact ⟨z, ⟨hzf, hUV (Set.mk_mem_prod hx'U hzV)⟩, hzt⟩ From 9ae96ab97edd1c2aab1325e687da235f9c628e8e Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Wed, 1 Jul 2026 03:52:54 +0000 Subject: [PATCH 0504/1300] feat(Analysis/Asymptotics): a function continuous at a point is bounded near it (#41201) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `ContinuousAt.isBigO`: if `f` is continuous at `x` then `f =O[𝓝 x] (fun _ ↦ 1)`. This is a corollary of `continuousAt_iff_isLittleO` and has been placed accordingly. Co-authored-by: Terence Tao --- Mathlib/Analysis/Asymptotics/Lemmas.lean | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Asymptotics/Lemmas.lean b/Mathlib/Analysis/Asymptotics/Lemmas.lean index fed7b0cf783739..026a39b13ca486 100644 --- a/Mathlib/Analysis/Asymptotics/Lemmas.lean +++ b/Mathlib/Analysis/Asymptotics/Lemmas.lean @@ -192,11 +192,21 @@ theorem IsLittleO.trans_tendsto (hfg : f'' =o[l] g'') (hg : Tendsto g'' l (𝓝 lemma isLittleO_id_one [One F''] [NeZero (1 : F'')] : (fun x : E'' => x) =o[𝓝 0] (1 : E'' → F'') := isLittleO_id_const one_ne_zero -theorem continuousAt_iff_isLittleO {α : Type*} {E : Type*} [NormedRing E] [NormOneClass E] +theorem continuousAt_iff_isLittleO {α : Type*} {E : Type*} [NormedRing E] [One F] [NormOneClass F] [TopologicalSpace α] {f : α → E} {x : α} : - (ContinuousAt f x) ↔ (fun (y : α) ↦ f y - f x) =o[𝓝 x] (fun (_ : α) ↦ (1 : E)) := by + (ContinuousAt f x) ↔ (f · - f x) =o[𝓝 x] (fun (_ : α) ↦ (1 : F)) := by simp [ContinuousAt, ← tendsto_sub_nhds_zero_iff] +theorem _root_.ContinuousAt.isLittleO {α : Type*} {E : Type*} [NormedRing E] [One F] + [NormOneClass F] [TopologicalSpace α] {f : α → E} {x : α} (hcont : ContinuousAt f x) : + (f · - f x) =o[𝓝 x] (fun _ ↦ (1 : F)) := + continuousAt_iff_isLittleO.mp hcont + +theorem _root_.ContinuousAt.isBigO {α : Type*} {E : Type*} [NormedRing E] [One F] [NormOneClass F] + [TopologicalSpace α] {f : α → E} {x : α} (hcont : ContinuousAt f x) : + f =O[𝓝 x] (fun _ ↦ (1 : F)) := + hcont.isLittleO.isBigO.congr_of_sub.mpr (isBigO_const_one ..) + /-! ### Multiplication -/ theorem IsBigO.of_pow {f : α → 𝕜} {g : α → R} {n : ℕ} (hn : n ≠ 0) (h : (f ^ n) =O[l] (g ^ n)) : From 3e314e58470254d088f4ae0ac01f2ca82b846466 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 1 Jul 2026 05:08:33 +0000 Subject: [PATCH 0505/1300] feat: Cartan's formula of Value Distribution Theory (#40696) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove Cartan's formula, which expresses the characteristic function of a meromorphic function `f` at `⊤` as a circle average of the logarithmic counting function. As an application, establish that the characteristic function is monotone on `(0, ∞)`. Disclaimer: Claude Code was used in the preparation of this PR. --- .../Complex/ValueDistribution/Cartan.lean | 98 +++++++++++++++++-- 1 file changed, 90 insertions(+), 8 deletions(-) diff --git a/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean b/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean index 06ec0547d43ab6..1c44cf7fabd4a0 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean @@ -6,7 +6,8 @@ Authors: Matteo Cipollina, Stefan Kebekus module -public import Mathlib.Analysis.SpecialFunctions.Integrals.PosLogEqCircleAverage +public import Mathlib.Analysis.Complex.ValueDistribution.FirstMainTheorem +public import Mathlib.Analysis.Complex.ValueDistribution.Proximity.IntegralPresentation /-! # Cartan's Formula @@ -27,19 +28,13 @@ At present, this file establishes circle integrability of the function See Section VI.2 of [Lang, *Introduction to Complex Hyperbolic Spaces*][MR886677] for a detailed discussion. - - -## TODO - -- Establish Cartan's Formula in full -- Prove monotonicity of the characteristic function -/ public section open Filter Metric Real Set Topology -variable {f : ℂ → ℂ} +variable {f : ℂ → ℂ} {R : ℝ} namespace ValueDistribution @@ -136,4 +131,91 @@ theorem circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_ rw [meromorphicOrderAt_const] aesop +/- Specialized Jensen-type identity -/ +private lemma logCounting_add_log_trailingCoeff_eq_circleAverage_add_logCounting_top + (h : Meromorphic f) (hR : R ≠ 0) (a : ℂ) : + logCounting f a R + log ‖meromorphicTrailingCoeffAt (f · - a) 0‖ = + circleAverage (log ‖f · - a‖) 0 R + logCounting f ⊤ R := by + have : logCounting f a R - logCounting f ⊤ R = circleAverage (log ‖f · - a‖) 0 R + - log ‖meromorphicTrailingCoeffAt (f · - a) 0‖ := by + rw [logCounting_coe_eq_logCounting_sub_const_zero, ← logCounting_sub_const h] + exact logCounting_zero_sub_logCounting_top_eq_circleAverage_sub_const (by fun_prop) hR + linarith + +/-- +Circle integrability of the term `logCounting f · R` that appears in Cartan's formula. +-/ +theorem circleIntegrable_logCounting (h : Meromorphic f) : + CircleIntegrable (logCounting f · R) 0 1 := by + by_cases hR : R = 0 + · simp [hR, ValueDistribution.logCounting_eval_zero] + convert circleIntegrable_circleAverage_log_norm_sub h |>.add + (circleIntegrable_const (logCounting f ⊤ R) 0 1) |>.sub + circleIntegrable_log_meromorphicTrailingCoeffAt + simpa using eq_sub_of_add_eq + (logCounting_add_log_trailingCoeff_eq_circleAverage_add_logCounting_top h hR _) + +/-! +## Cartan's formula +-/ + +/-- +**Cartan's formula** with the additive constant written explicitly as a circle average of the +logarithm of the first nonzero Laurent coefficient of `f - a` at the origin. + +See `circleIntegrable_logCounting` and `circleIntegrable_log_trailingCoeff_of_meromorphic` for the +facts that the summands are actually circle integrable. +-/ +theorem characteristic_top_eq_circleAverage_add_circleAverage (h : Meromorphic f) (hR : R ≠ 0) : + characteristic f ⊤ R = circleAverage (logCounting f · R) 0 1 + + circleAverage (fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖) 0 1 := calc + characteristic f ⊤ R + = circleAverage (fun a ↦ circleAverage (log ‖f · - a‖) 0 R + logCounting f ⊤ R) 0 1 := by + simp only [characteristic, proximity, ↓reduceDIte, Pi.add_apply] + rw [← proximity_top, ← circleAverage_circleAverage_eq_proximity_top h, + circleAverage_fun_add (circleIntegrable_circleAverage_log_norm_sub h) + (circleIntegrable_const (logCounting f ⊤ R) 0 1), circleAverage_const] + _ = circleAverage (logCounting f · R) 0 1 + + circleAverage (fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖) 0 1 := by + rw [← circleAverage_add (circleIntegrable_logCounting h) + circleIntegrable_log_meromorphicTrailingCoeffAt, circleAverage_congr_sphere] + intro a ha + simp [logCounting_add_log_trailingCoeff_eq_circleAverage_add_logCounting_top h hR a] + +/-- +**Cartan's formula** in case where `0 < meromorphicOrderAt f 0`. +-/ +theorem characteristic_top_eq_circleAverage_of_meromorphicOrderAt_pos + (h₁f : Meromorphic f) (h₂f : 0 < meromorphicOrderAt f 0) (hR : R ≠ 0) : + characteristic f ⊤ R = circleAverage (logCounting f · R) 0 1 := by + rw [characteristic_top_eq_circleAverage_add_circleAverage h₁f hR] + simp [circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_pos h₂f] + +/-- +Qualitative version of **Cartan's formula**: Away from the point `0`, the difference between +`characteristic f ⊤` and `circleAverage (logCounting f · ·) 0 1` is constant. This qualitative +version of Cartan's formula exists because the specific value of the constant does not matter in +practise. +-/ +theorem characteristic_top_eq_circleAverage_add_const (h : Meromorphic f) : + ∃ const, ∀ R ≠ 0, characteristic f ⊤ R = circleAverage (logCounting f · R) 0 1 + const := + ⟨circleAverage (fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖) 0 1, + fun _ hr ↦ characteristic_top_eq_circleAverage_add_circleAverage h hr⟩ + +/-! +## Application: Monotonicity of the Characteristic Function +-/ + +/-- +The characteristic function is monotone on `(0, ∞)`. This result is surprisingly non-trivial, given +that the proximity function is not monotone in general. +-/ +theorem characteristic_monotoneOn (h : Meromorphic f) : + MonotoneOn (characteristic f ⊤) (Set.Ioi 0) := by + intro a ha b hb hab + rw [characteristic_top_eq_circleAverage_add_circleAverage h ha.ne', + characteristic_top_eq_circleAverage_add_circleAverage h hb.ne'] + gcongr <;> try exact circleIntegrable_logCounting h + exact logCounting_monotoneOn ha hb hab + end ValueDistribution From 2ab24a114da4733623c18d5d2b943f4ad12ef8dd Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 1 Jul 2026 05:51:10 +0000 Subject: [PATCH 0506/1300] feat: Bounded Range versus `IsBigO` Asymptotics (#40664) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Show that for a continuous function `f : ℝ → E` into a seminormed space, having bounded range is equivalent to being `O(1)` along both `atTop` and `atBot`. If `f` is even, then a single `O(1)` bound along `atTop` already suffices. This material is used in Value Distribution Theory, where boundedness is traditionally expressed as being `O(1)`. --- Mathlib/Algebra/Group/EvenFunction.lean | 6 ++ .../Asymptotics/SpecificAsymptotics.lean | 68 +++++++++++++++++-- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Group/EvenFunction.lean b/Mathlib/Algebra/Group/EvenFunction.lean index 0547bcd2a4bc90..fac96be08157c8 100644 --- a/Mathlib/Algebra/Group/EvenFunction.lean +++ b/Mathlib/Algebra/Group/EvenFunction.lean @@ -34,12 +34,18 @@ protected def Even (f : α → β) : Prop := ∀ a, f (-a) = f a /-- A function `f` is _odd_ if it satisfies `f (-x) = -f x` for all `x`. -/ protected def Odd [Neg β] (f : α → β) : Prop := ∀ a, f (-a) = -(f a) +/-- An even function `f` satisfies `f (-x) = f x`. -/ +lemma Even.eq {f : α → β} (hf : f.Even) (x : α) : f (-x) = f x := hf x + /-- Any constant function is even. -/ lemma Even.const (b : β) : Function.Even (fun _ : α ↦ b) := fun _ ↦ rfl /-- The zero function is even. -/ lemma Even.zero [Zero β] : Function.Even (fun (_ : α) ↦ (0 : β)) := Even.const 0 +/-- An odd function `f` satisfies `f (-x) = -f x`. -/ +lemma Odd.eq [Neg β] {f : α → β} (hf : f.Odd) (x : α) : f (-x) = -f x := hf x + /-- The zero function is odd. -/ lemma Odd.zero [NegZeroClass β] : Function.Odd (fun (_ : α) ↦ (0 : β)) := fun _ ↦ neg_zero.symm diff --git a/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean b/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean index d3f80d779673f2..5b01e03ea44e57 100644 --- a/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean +++ b/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean @@ -18,10 +18,7 @@ theory developed in `Mathlib/Analysis/Asymptotics/Defs.lean` and public section - -open Filter Asymptotics - -open Topology +open Bornology Filter Asymptotics Set Topology section NormedField @@ -209,3 +206,66 @@ theorem Asymptotics.isEquivalent_nat_ceil : isEquivalent_of_tendsto_one tendsto_nat_ceil_div_atTop end NormedLinearOrderedField + +section boundedRange + +/-! +## Bounded Range versus `IsBigO` Asymptotics + +For a continuous function `f` into a seminormed space, defined on an unbounded linear order whose +order topology has compact intervals, having bounded range is equivalent to being `O(1)` along both +`atTop` and `atBot` (`Continuous.isBounded_range_iff_isBigO_atTop_atBot`). For an even function a +single `O(1)` bound along `atTop` already suffices +(`Continuous.isBounded_range_iff_isBigO_atTop_of_even`), since `Function.Even` transports an `atTop` +bound to an `atBot` bound (`Function.Even.isBigO_atTop_iff_isBigO_atBot`). +-/ + +variable + {E : Type*} [SeminormedAddCommGroup E] + {D : Type*} [TopologicalSpace D] + {β : Type*} [TopologicalSpace β] [LinearOrder β] [OrderClosedTopology β] [CompactIccSpace β] + [NoMaxOrder β] [NoMinOrder β] + +/-- +A continuous function `f` has bounded range if and only if it is `O(1)` with respect to the +cocompact filter. +-/ +theorem Continuous.isBounded_range_iff_isBigO {f : D → E} (hf : Continuous f) : + IsBounded (range f) ↔ f =O[cocompact D] (1 : D → ℝ) := by + constructor <;> intro h + · rw [isBounded_iff_forall_norm_le] at h + obtain ⟨c, hc⟩ := h + simp only [Set.mem_range, forall_exists_index, forall_apply_eq_imp_iff] at hc + rw [isBigO_iff] + use c + apply Eventually.of_forall + simpa using hc + · simp_rw [isBigO_iff, Filter.Eventually, Filter.mem_cocompact] at h + simp only [Pi.one_apply, norm_one, mul_one] at h + obtain ⟨c, t, hcompact, h⟩ := h + rw [← Set.image_union_image_compl_eq_range (s := t)] + apply IsBounded.union + · apply (IsCompact.image hcompact hf).isBounded + · rw [isBounded_iff_forall_norm_le] + refine ⟨c, fun x hx ↦ ?_⟩ + rw [Set.mem_image] at hx + obtain ⟨y, hy, rfl⟩ := hx + simpa using mem_of_mem_of_subset hy h + +/-- +A continuous function `f` on an unbounded linear order with compact intervals has bounded range if +and only if it is `O(1)` at both `atTop` and `atBot`. +-/ +theorem Continuous.isBounded_range_iff_isBigO_atTop_atBot {f : β → E} (hf : Continuous f) : + IsBounded (range f) ↔ f =O[atTop] (1 : β → ℝ) ∧ f =O[atBot] (1 : β → ℝ) := by + rw [hf.isBounded_range_iff_isBigO, cocompact_eq_atBot_atTop, isBigO_sup, and_comm] + +/-- A continuous even function has bounded range if and only if `f =O[atTop] 1`. -/ +theorem Continuous.isBounded_range_iff_isBigO_atTop_of_even [AddCommGroup β] [IsOrderedAddMonoid β] + {f : β → E} (hf : Continuous f) (heven : Function.Even f) : + IsBounded (range f) ↔ f =O[atTop] (1 : β → ℝ) := + ⟨fun h ↦ (hf.isBounded_range_iff_isBigO_atTop_atBot.mp h).1, + fun h ↦ hf.isBounded_range_iff_isBigO_atTop_atBot.mpr + ⟨h, by simpa only [← neg_atTop, ← Filter.map_neg, isBigO_map, Function.comp_def, heven.eq]⟩⟩ + +end boundedRange From f9c3ad4d269a17caaeceebabb291a82e7f0d1f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 1 Jul 2026 06:16:30 +0000 Subject: [PATCH 0507/1300] =?UTF-8?q?feat(Order):=20`Ici=20(1=20:=20=CE=B1?= =?UTF-8?q?)=20=3D=20univ`=20when=20`IsBotOneClass=20=CE=B1`=20(#40762)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From PFR --- Mathlib/Algebra/Order/Group/Pointwise/Interval.lean | 4 ---- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 8 ++++---- Mathlib/Order/Interval/Finset/Defs.lean | 3 +++ Mathlib/Order/Interval/Set/Basic.lean | 3 +++ 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean b/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean index 7efe689aefe6b4..1101a11f3267ee 100644 --- a/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean +++ b/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean @@ -898,10 +898,6 @@ theorem Ici_pow_eq {a : α} : | 1, _ => by simp | n + 2, _ => by simp [pow_succ _ n.succ, Ici_pow_eq, Ici_mul_Ici_eq] -omit [MulRightMono α] in -@[to_additive] -lemma Ici_one_eq_univ : Set.Ici (1 : α) = Set.univ := by aesop - end CanonicallyOrdered end Set diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index cd679e0ec0a1e1..8a42736fa80c53 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -343,9 +343,9 @@ theorem mkMetric_top : (mkMetric (fun _ => ∞ : ℝ≥0∞ → ℝ≥0∞) : Ou intro b hb simpa using hb ⊤ -/-- If `m₁ d ≤ m₂ d` for `d < ε` for some `ε > 0` (we use `≤ᶠ[𝓝[≥] 0]` to state this), then +/-- If `m₁ d ≤ m₂ d` for `d < ε` for some `ε > 0` (we use `≤ᶠ[𝓝 0]` to state this), then `mkMetric m₁ hm₁ ≤ mkMetric m₂ hm₂`. -/ -theorem mkMetric_mono {m₁ m₂ : ℝ≥0∞ → ℝ≥0∞} (hle : m₁ ≤ᶠ[𝓝[≥] 0] m₂) : +theorem mkMetric_mono {m₁ m₂ : ℝ≥0∞ → ℝ≥0∞} (hle : m₁ ≤ᶠ[𝓝 0] m₂) : (mkMetric m₁ : OuterMeasure X) ≤ mkMetric m₂ := by convert! @mkMetric_mono_smul X _ _ m₂ _ ENNReal.one_ne_top one_ne_zero _ <;> simp [*] @@ -455,9 +455,9 @@ theorem mkMetric_top : (mkMetric (fun _ => ∞ : ℝ≥0∞ → ℝ≥0∞) : Me apply toOuterMeasure_injective rw [mkMetric_toOuterMeasure, OuterMeasure.mkMetric_top, toOuterMeasure_top] -/-- If `m₁ d ≤ m₂ d` for `d < ε` for some `ε > 0` (we use `≤ᶠ[𝓝[≥] 0]` to state this), then +/-- If `m₁ d ≤ m₂ d` for `d < ε` for some `ε > 0` (we use `≤ᶠ[𝓝 0]` to state this), then `mkMetric m₁ hm₁ ≤ mkMetric m₂ hm₂`. -/ -theorem mkMetric_mono {m₁ m₂ : ℝ≥0∞ → ℝ≥0∞} (hle : m₁ ≤ᶠ[𝓝[≥] 0] m₂) : +theorem mkMetric_mono {m₁ m₂ : ℝ≥0∞ → ℝ≥0∞} (hle : m₁ ≤ᶠ[𝓝 0] m₂) : (mkMetric m₁ : Measure X) ≤ mkMetric m₂ := by convert! @mkMetric_mono_smul X _ _ _ _ m₂ _ ENNReal.one_ne_top one_ne_zero _ <;> simp [*] diff --git a/Mathlib/Order/Interval/Finset/Defs.lean b/Mathlib/Order/Interval/Finset/Defs.lean index 8eb21b9f6320a4..a5bffe2d632411 100644 --- a/Mathlib/Order/Interval/Finset/Defs.lean +++ b/Mathlib/Order/Interval/Finset/Defs.lean @@ -389,6 +389,9 @@ theorem _root_.Fintype.card_Ioi (a : α) [Fintype (Set.Ioi a)] : Fintype.card (Set.Ioi a) = #(Ioi a) := Fintype.card_of_finset' _ fun _ ↦ by simp +@[to_additive (attr := simp)] +lemma Ici_one_eq_univ [One α] [IsBotOneClass α] [Fintype α] : Ici (1 : α) = univ := by ext; simp + end LocallyFiniteOrderTop section OrderTop diff --git a/Mathlib/Order/Interval/Set/Basic.lean b/Mathlib/Order/Interval/Set/Basic.lean index b986fff1612786..27a3b28f92ab03 100644 --- a/Mathlib/Order/Interval/Set/Basic.lean +++ b/Mathlib/Order/Interval/Set/Basic.lean @@ -464,6 +464,9 @@ section matched_intervals end matched_intervals +@[to_additive (attr := simp)] +lemma Ici_one_eq_univ [One α] [IsBotOneClass α] : Ici (1 : α) = univ := by ext; simp + end Preorder section PartialOrder From a05b35ba366daea5cb11303fdd04bf3af175b107 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Wed, 1 Jul 2026 07:16:29 +0000 Subject: [PATCH 0508/1300] refactor(CategoryTheory/Limits/Shape/Kernels): remove duplicate lemma (#41207) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lemma `Limits.kernel.ι_of_zero` was saying the same thing as instance `Limits.kernel.ι_zero_isIso`, that is, that `kernel.ι 0` is an isomorphism; the proofs were also identical. Rewrite the lemma to make it say that `kernel.ι f` is an isomorphism provided that `f = 0`; this follows immediately from `equalizer.ι_of_eq` but might still be useful. Same with `Limits.cokernel.π_of_zero` and `Limits.cokernel.π_zero_isIso`. Co-authored-by: morel --- Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean | 12 ++++-------- Mathlib/CategoryTheory/Simple.lean | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean index 379087c149ca81..a22d7fc62767be 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean @@ -579,11 +579,9 @@ end Transport section -variable (X Y) - /-- The kernel morphism of a zero morphism is an isomorphism -/ -theorem kernel.ι_of_zero : IsIso (kernel.ι (0 : X ⟶ Y)) := - equalizer.ι_of_self _ +theorem kernel.ι_of_zero {f : X ⟶ Y} [HasKernel f] (eq : f = 0) : + IsIso (kernel.ι f) := equalizer.ι_of_eq eq end @@ -1118,11 +1116,9 @@ end HasImage section -variable (X Y) - /-- The cokernel of a zero morphism is an isomorphism -/ -theorem cokernel.π_of_zero : IsIso (cokernel.π (0 : X ⟶ Y)) := - coequalizer.π_of_self _ +theorem cokernel.π_of_zero {f : X ⟶ Y} [HasCokernel f] (eq : f = 0) : + IsIso (cokernel.π f) := coequalizer.π_of_eq eq end diff --git a/Mathlib/CategoryTheory/Simple.lean b/Mathlib/CategoryTheory/Simple.lean index f77beb3d2d1d1b..a832ffb3c19617 100644 --- a/Mathlib/CategoryTheory/Simple.lean +++ b/Mathlib/CategoryTheory/Simple.lean @@ -142,7 +142,7 @@ theorem simple_of_cosimple (X : C) (h : ∀ {Z : C} (f : X ⟶ Z) [Epi f], IsIso have hx := cokernel.π_of_epi f by_contra h subst h - exact (h _).mp (cokernel.π_of_zero _ _) hx + exact (h _).mp inferInstance hx · intro hf suffices Epi f by exact isIso_of_mono_of_epi _ apply Preadditive.epi_of_cokernel_zero From 0cbbb171ac35715c996c659fdb3fe56a276b8f1b Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2026 07:36:50 +0000 Subject: [PATCH 0509/1300] chore(CategoryTheory/Limits): fix `simp` lemmas for `productUniqueIso` #41083 (#41202) The previously by `simps!` generated lemmas leaked through the production abstraction barrier. This PR was automatically created from PR #41083 by @peabrainiac via a [review comment](https://github.com/leanprover-community/mathlib4/pull/41083#discussion_r3499775883) by @chrisflav. Co-authored-by: peabrainiac <43812953+peabrainiac@users.noreply.github.com> --- .../Limits/Shapes/Products.lean | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index 3bb17a7c11f5f5..e7c71c245c1e4f 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -826,10 +826,21 @@ instance (priority := 100) hasProduct_unique [Nonempty β] [Subsingleton β] (f let ⟨_⟩ := nonempty_unique β; HasLimit.mk (limitConeOfUnique f) /-- A product over an index type with exactly one term is just the object over that term. -/ -@[simps!] def productUniqueIso [Unique β] (f : β → C) : ∏ᶜ f ≅ f default := IsLimit.conePointUniqueUpToIso (limit.isLimit _) (limitConeOfUnique f).isLimit +@[simp] +lemma productUniqueIso_hom [Unique β] (f : β → C) : (productUniqueIso f).hom = Pi.π f default := + rfl + +@[reassoc (attr := simp)] +lemma productUniqueIso_inv_π [Unique β] (f : β → C) (b : β) : + (productUniqueIso f).inv ≫ Pi.π f b = eqToHom (congrArg _ <| Subsingleton.allEq _ _) := by + obtain rfl := Subsingleton.allEq b default + simp [Iso.inv_comp_eq] + +@[deprecated (since := "2026-06-30")] alias productUniqueIso_inv := productUniqueIso_inv_π + set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism is the projection from a single object product. -/ def Fan.isLimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : @@ -863,10 +874,23 @@ instance (priority := 100) hasCoproduct_unique [Nonempty β] [Subsingleton β] ( let ⟨_⟩ := nonempty_unique β; HasColimit.mk (colimitCoconeOfUnique f) /-- A coproduct over an index type with exactly one term is just the object over that term. -/ -@[simps!] def coproductUniqueIso [Unique β] (f : β → C) : ∐ f ≅ f default := IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) (colimitCoconeOfUnique f).isColimit +@[simp] +lemma coproductUniqueIso_inv [Unique β] (f : β → C) : + (coproductUniqueIso f).inv = Sigma.ι f default := + rfl + +@[reassoc (attr := simp)] +lemma ι_coproductUniqueIso_hom [Unique β] (f : β → C) (b : β) : + Sigma.ι f b ≫ (coproductUniqueIso f).hom = eqToHom (congrArg _ <| Subsingleton.allEq _ _) := by + obtain rfl := Subsingleton.allEq b default + symm + simp [← Iso.comp_inv_eq] + +@[deprecated (since := "2026-06-30")] alias coproductUniqueIso_hom := ι_coproductUniqueIso_hom + set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism is the projection from a single object product. -/ def Cofan.isColimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : From fef8766a40e890c95c4f928407bf70512a33b098 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Wed, 1 Jul 2026 07:58:18 +0000 Subject: [PATCH 0510/1300] feat: generalize a few measure theory lemmas (#41209) Co-authored-by: sgouezel --- .../Polish/StronglyMeasurable.lean | 18 ++++++++++++++---- Mathlib/MeasureTheory/Measure/Prod.lean | 11 ++++++++++- Mathlib/MeasureTheory/Measure/WithDensity.lean | 14 +++++++++----- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean b/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean index 1676161053d094..2582708a2b5916 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean @@ -82,12 +82,22 @@ variable {X E ι : Type*} [MeasurableSpace X] [CommMonoid E] [TopologicalSpace E section -variable [IsCompletelyPseudoMetrizableSpace E] [ContinuousMul E] - [Countable ι] {L : SummationFilter ι} [L.NeBot] [L.filter.IsCountablyGenerated] +variable [ContinuousMul E] {L : SummationFilter ι} [L.NeBot] [L.filter.IsCountablyGenerated] -/-- The product of strongly measurable functions is measurable. -/ +/-- The infinite product of strongly measurable functions is measurable, `HasProd` version. -/ @[to_additive (attr := fun_prop) -/-- The sum of strongly measurable functions is measurable. -/] +/-- The infinite sum of strongly measurable functions is measurable, `HasSum` version. -/] +theorem StronglyMeasurable.hasProd [PseudoMetrizableSpace E] {f : ι → X → E} {g : X → E} + (h : ∀ i : ι, StronglyMeasurable (f i)) (h' : ∀ x, HasProd (fun i ↦ f i x) (g x) L) : + StronglyMeasurable g := by + refine stronglyMeasurable_of_tendsto L.filter ?_ (tendsto_pi_nhds.mpr h') + fun_prop + +variable [IsCompletelyPseudoMetrizableSpace E] [Countable ι] + +/-- The infinite product of strongly measurable functions is measurable. -/ +@[to_additive (attr := fun_prop) +/-- The infinite sum of strongly measurable functions is measurable. -/] theorem StronglyMeasurable.tprod {f : ι → X → E} (h : ∀ i : ι, StronglyMeasurable (f i)) : StronglyMeasurable (fun x => ∏'[L] i : ι, f i x) := by let E := { x | Multipliable (f · x) L } diff --git a/Mathlib/MeasureTheory/Measure/Prod.lean b/Mathlib/MeasureTheory/Measure/Prod.lean index 90ee8c5123e0f3..2f3c5ca3e1db60 100644 --- a/Mathlib/MeasureTheory/Measure/Prod.lean +++ b/Mathlib/MeasureTheory/Measure/Prod.lean @@ -419,6 +419,14 @@ theorem AbsolutelyContinuous.prod [SFinite ν'] (h1 : μ ≪ μ') (h2 : ν ≪ rw [measure_prod_null hs] at h2s exact (h2s.filter_mono h1.ae_le).mono fun _ h => h2 h +omit [SFinite ν] in +@[gcongr] theorem prod_mono [SFinite ν'] (h1 : μ ≤ μ') (h2 : ν ≤ ν') : μ.prod ν ≤ μ'.prod ν' := by + apply Measure.le_iff.2 (fun s hs ↦ ?_) + calc μ.prod ν s + _ ≤ ∫⁻ x, ν (Prod.mk x ⁻¹' s) ∂μ := prod_apply_le hs + _ ≤ ∫⁻ x, ν' (Prod.mk x ⁻¹' s) ∂μ' := by gcongr + _ = (μ'.prod ν') s := (prod_apply hs).symm + /-- Note: the converse is not true. For a counterexample, see Walter Rudin *Real and Complex Analysis*, example (c) in section 8.9. It is true if the set is measurable, see `ae_prod_mem_iff_ae_ae_mem`. -/ @@ -835,7 +843,8 @@ theorem map_prod_map {δ} [MeasurableSpace δ] {f : α → β} {g : γ → δ} ( -- `prod_smul_right` needs an instance to get `SFinite (c • ν)` from `SFinite ν`, -- hence it is placed in the `WithDensity` file, where the instance is defined. -lemma prod_smul_left {μ : Measure α} (c : ℝ≥0∞) : (c • μ).prod ν = c • (μ.prod ν) := by +lemma prod_smul_left {μ : Measure α} {R : Type*} [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] + (c : R) : (c • μ).prod ν = c • (μ.prod ν) := by ext s hs rw [prod_apply hs, Measure.smul_apply, prod_apply hs] simp diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index 1ea3e12cc85665..a142193dbad040 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -663,8 +663,10 @@ instance Measure.withDensity.instSFinite [SFinite μ] {f : α → ℝ≥0∞} : rw [key] infer_instance -instance [SFinite μ] (c : ℝ≥0∞) : SFinite (c • μ) := by - rw [← withDensity_const] +instance [SFinite μ] {R : Type*} [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] (c : R) : + SFinite (c • μ) := by + have : c • μ = c • ((1 : ℝ≥0∞) • μ) := by simp + rw [this, ← smul_assoc, ← withDensity_const] infer_instance /-- If `μ ≪ ν` and `ν` is s-finite, then `μ` is s-finite. -/ @@ -727,10 +729,12 @@ theorem prod_withDensity {f : α → ℝ≥0∞} {g : β → ℝ≥0∞} (hf : M -- `prod_smul_left` is in the `Prod` file. This lemma is here because this is the file in which -- we prove the instance that gives `SFinite (c • ν)`. -lemma Measure.prod_smul_right (c : ℝ≥0∞) : μ.prod (c • ν) = c • (μ.prod ν) := by +lemma Measure.prod_smul_right {R : Type*} [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] (c : R) : + μ.prod (c • ν) = c • (μ.prod ν) := by ext s hs - simp_rw [Measure.prod_apply hs, Measure.smul_apply, Measure.prod_apply hs, smul_eq_mul] - rw [lintegral_const_mul] + have A (s : Set β) : c • ν s = (c • 1) * ν s := by simp + simp_rw [Measure.prod_apply hs, Measure.smul_apply, Measure.prod_apply hs, A] + rw [lintegral_const_mul, smul_one_mul] exact measurable_measure_prodMk_left hs end Prod From b4b33fa6e8ea63d5069f99824ea1d84d5201961e Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Wed, 1 Jul 2026 08:33:44 +0000 Subject: [PATCH 0511/1300] feat: simplify proof of `IsAdjoinRootMonic.mkOfAdjoinEqTop'` (#38189) * Simplify the proof of `IsAdjoinRootMonic.mkOfAdjoinEqTop'` by factoring out a lemma `OrzechProperty.bijective_of_surjective_of_finrank_le` and making use of the existing lemma `finrank_le_iff_exists_linearMap`. Co-authored-by: artie2000 --- Mathlib/LinearAlgebra/Dimension/Free.lean | 12 +++++++++ Mathlib/RingTheory/IsAdjoinRoot.lean | 32 ++++++++--------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index 865262acab6c98..c7f81be130be3c 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -328,6 +328,18 @@ theorem basisUnique_repr_eq_zero_iff {ι : Type*} [Unique ι] (basisUnique ι h).repr.map_eq_zero_iff.mp (Finsupp.ext fun j => Subsingleton.elim i j ▸ hv), fun hv => by rw [hv, map_zero, Finsupp.zero_apply]⟩ +omit [StrongRankCondition R] in +theorem _root_.OrzechProperty.bijective_of_surjective_of_finrank_le + [OrzechProperty R] [Module.Finite R M] [Module.Finite R M'] + (f : M →ₗ[R] M') (hf : Function.Surjective f) (h : Module.finrank R M ≤ Module.finrank R M') : + Function.Bijective f := by + cases subsingleton_or_nontrivial R + -- TODO : figure out how to make `nontriviality` work here nicely + · have := Module.subsingleton R M + exact ⟨Function.injective_of_subsingleton f, hf⟩ + rcases finrank_le_iff_exists_linearMap.mp h with ⟨_, hi⟩ + exact OrzechProperty.bijective_of_surjective_of_injective _ _ hi hf + variable {R : Type*} [CommSemiring R] [StrongRankCondition R] {M : Type*} [AddCommMonoid M] [Module R M] [Module.Free R M] diff --git a/Mathlib/RingTheory/IsAdjoinRoot.lean b/Mathlib/RingTheory/IsAdjoinRoot.lean index eb6034e89f1241..07ee4861ca3196 100644 --- a/Mathlib/RingTheory/IsAdjoinRoot.lean +++ b/Mathlib/RingTheory/IsAdjoinRoot.lean @@ -649,30 +649,20 @@ theorem minpoly_eq [IsDomain R] [IsDomain S] [IsTorsionFree R S] [IsIntegrallyCl then `S` is given by adjoining a root of `minpoly R α`. Does not require that `R` is an integral domain, unlike `mkOfAdjoinEqTop`. -/ @[simps] -def mkOfAdjoinEqTop' - [Module.Finite R S] [Module.Free R S] - {α : S} (hα : Algebra.adjoin R {α} = ⊤) : +def mkOfAdjoinEqTop' [Module.Finite R S] [Module.Free R S] {α : S} (hα : Algebra.adjoin R {α} = ⊤) : IsAdjoinRootMonic S (minpoly R α) where __ : IsAdjoinRoot S (minpoly R α) := - let f := minpoly R α - have hf := minpoly.monic (Algebra.IsIntegral.isIntegral (R := R) α) - let φ : AdjoinRoot f →ₐ[R] S := - AdjoinRoot.liftAlgHom f (Algebra.ofId R S) α (minpoly.aeval R α) + have monic := minpoly.monic (Algebra.IsIntegral.isIntegral (R := R) α) + haveI := monic.free_adjoinRoot + haveI := monic.finite_adjoinRoot + let φ := AdjoinRoot.liftAlgHom _ (Algebra.ofId R S) _ (minpoly.aeval R α) IsAdjoinRoot.ofAdjoinRootEquiv <| AlgEquiv.ofBijective φ <| by - have hφ : Function.Surjective φ := by - rw [Algebra.adjoin_singleton_eq_range_aeval, AlgHom.range_eq_top] at hα - intro s; obtain ⟨p, hp⟩ := hα s - exact ⟨AdjoinRoot.mk f p, by simp [φ, ← aeval_def, hp]⟩ - haveI := hf.free_adjoinRoot; haveI := hf.finite_adjoinRoot - by_cases h : Nontrivial R - · letI e := LinearEquiv.ofFinrankEq (R := R) (AdjoinRoot f) S <| - le_antisymm (finrank_quotient_span_eq_natDegree' hf ▸ minpoly.natDegree_le α) - (LinearMap.finrank_le_finrank_of_surjective (f := φ.toLinearMap) hφ) - exact OrzechProperty.bijective_of_surjective_of_injective - e.toLinearMap φ e.injective hφ - · apply not_nontrivial_iff_subsingleton.mp at h - haveI := Module.subsingleton R (AdjoinRoot f) - exact ⟨Function.injective_of_subsingleton φ, hφ⟩ + refine OrzechProperty.bijective_of_surjective_of_finrank_le φ.toLinearMap (fun s ↦ ?_) ?_ + · rw [Algebra.adjoin_singleton_eq_range_aeval, AlgHom.range_eq_top] at hα + rcases hα s with ⟨p, hp⟩ + exact ⟨AdjoinRoot.mk (minpoly R α) p, by simp [φ, ← aeval_def, hp]⟩ + · nontriviality R + exact finrank_quotient_span_eq_natDegree' monic ▸ minpoly.natDegree_le α map := aeval α monic := minpoly.monic (Algebra.IsIntegral.isIntegral α) From 908c3471deaaa63a8265bfd047ac2b476283512b Mon Sep 17 00:00:00 2001 From: Jean-Guillaume Durand <113947520+jeangud@users.noreply.github.com> Date: Wed, 1 Jul 2026 08:58:37 +0000 Subject: [PATCH 0512/1300] fix(Tactic/Linter/DocString): avoid false positive in syntax quotation patterns (#40088) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a false-positive in the `linter.style.docString.empty` linter with pattern matching: ```lean /-- Checks if a command has the `AMS` attribute. -/ def toAMS (stx : TSyntax ``Command.declModifiers) : CommandElabM (Array <| TSyntaxArray `num) := do match stx with | `(declModifiers| $(_)? @[$[$atts],*] $(_)? $(_)? $(_)? $(_)?) => atts.filterMapM fun att ↦ do match att with | `(attrInstance | AMS $nums*) => return some nums | _ => return none | _ => return #[] ``` This can be addressed by ensuring the syntax kind of the doc string is ``` ``Parser.Command.docComment``` as syntax quotation uses an antiquotation syntax instead. - :robot: Implemented and test with **Gemini 3.1 Pro**. This change is pretty targeted so I did not have much to redo except reviewing. --- Mathlib/Tactic/Linter/DocString.lean | 2 ++ MathlibTest/Linter/DocString.lean | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Mathlib/Tactic/Linter/DocString.lean b/Mathlib/Tactic/Linter/DocString.lean index 8b3182d24d9ca4..2fcbff3dfc4ddb 100644 --- a/Mathlib/Tactic/Linter/DocString.lean +++ b/Mathlib/Tactic/Linter/DocString.lean @@ -149,6 +149,8 @@ def docStringLinter : Linter where run := withSetOptionIn fun stx ↦ do let currIndent := fm.toPosition pos |>.column if docStx.isMissing then continue -- this is probably superfluous, thanks to `some pos` above. + -- ignore antiquotations from syntax patterns like `$(_)?` + unless docStx.getKind == ``Parser.Command.docComment do continue -- `docString` contains e.g. trailing spaces before the `-/`, but does not contain -- any leading whitespace before the actual string starts. let docString ← try getDocStringText ⟨docStx⟩ catch _ => continue diff --git a/MathlibTest/Linter/DocString.lean b/MathlibTest/Linter/DocString.lean index 63dd55d1b24bd5..08269628e06d26 100644 --- a/MathlibTest/Linter/DocString.lean +++ b/MathlibTest/Linter/DocString.lean @@ -127,6 +127,23 @@ structure X where -/ y : Unit +-- Syntax quotation patterns involving `declModifiers` should not trigger a false +-- "empty docstring" warning. This is a regression test for a false positive where +-- `getDeclModifiers` would recurse into definition bodies and find `declModifiers` +-- nodes from syntax quotation patterns, treating their empty docstring slots as +-- actual empty docstrings. +section +open Lean Elab Command Parser Term in +#guard_msgs in +/-- A function that pattern-matches on `declModifiers`. -/ +def extractAttrs (stx : TSyntax ``Command.declModifiers) : + CommandElabM (Array <| TSyntax ``attrInstance) := do + match stx with + | `(declModifiers| $(_)? @[$[$atts],*] $(_)? $(_)? $(_)? $(_)?) => + return atts + | _ => return #[] +end + /-! # Tests for Verso-compatible docstrings -/ From e5b7d95572119a01b1be28f189ae2ce21d4ab09e Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 1 Jul 2026 08:58:39 +0000 Subject: [PATCH 0513/1300] feat(RingTheory/RamificationInertia/Inertia): add pow lemmas for new definition of inertia degree (#41215) This PR adds add pow lemmas for the new definition of inertia degree. Co-authored-by: tb65536 --- .../NumberTheory/NumberField/ClassNumber.lean | 3 +-- .../NumberField/Cyclotomic/Galois.lean | 2 +- .../NumberField/Cyclotomic/Ideal.lean | 3 +-- .../NumberField/Discriminant/Different.lean | 4 +-- Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 9 ++----- .../RamificationInertia/Inertia.lean | 27 +++++++++++++++++++ 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/ClassNumber.lean b/Mathlib/NumberTheory/NumberField/ClassNumber.lean index 488c642d93a9bf..1f63affdc3fca9 100644 --- a/Mathlib/NumberTheory/NumberField/ClassNumber.lean +++ b/Mathlib/NumberTheory/NumberField/ClassNumber.lean @@ -161,8 +161,7 @@ theorem isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_I refine le_floor ?_ have : P.IsMaximal := hP.isMaximal (by simpa using HP.2) have : (span {p}).IsMaximal := (hpprime (.under ℤ P)).isMaximal_span_singleton - simpa only [hspan, ← cast_pow, absNorm_eq_pow_inertiaDeg P (hpprime (hP.under _)), - inertiaDeg_eq_inertiaDeg'] using hPN + simpa only [hspan, ← cast_pow, ← natAbs_pow_inertiaDeg' p P] using hPN have hpabsprime := Int.prime_iff_natAbs_prime.mp (hpprime (hP.under _)) refine h _ ?_ hpabsprime _ ⟨hP, ?_⟩ hple · suffices 0 < P.inertiaDeg' ℤ by diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean index a83cce9bee0610..6e5aec0b04a07a 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean @@ -122,7 +122,7 @@ theorem mem_zpowers_galEquivZMod_of_mem_stabilizer {σ : Gal(K/ℚ)} (hσ : σ have h₀ : IsPrimitiveRoot (Ideal.Quotient.mk P hζ.toInteger) n := by refine hζ.toInteger_isPrimitiveRoot.idealQuotient_mk (by simpa using IsMaximal.ne_top inferInstance) ?_ - rw [Ideal.absNorm_eq_pow_inertiaDeg' _ hp.out] + rw [← pow_inertiaDeg' p] exact Nat.Coprime.pow_left _ hn have h₁ := IsFractionRing.stabilizerHom_apply_apply_mk Gal(K/ℚ) (Ideal.span {(p : ℤ)}) P (ℤ ⧸ span {(p : ℤ)}) (𝓞 K ⧸ P) ⟨σ, hσ⟩ hζ.toInteger diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 92659de900efb3..bcfd32e01331cd 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -99,8 +99,7 @@ instance liesOver_span_zeta_sub_one : (span {hζ.toInteger - 1}).LiesOver 𝒑 : theorem inertiaDeg_span_zeta_sub_one : inertiaDeg' (span {hζ.toInteger - 1}) ℤ = 1 := by have : IsMaximal (span {hζ.toInteger - 1}) := .of_liesOver_isMaximal _ 𝒑 - rw [← inertiaDeg_eq_inertiaDeg' 𝒑] - rw [← Nat.pow_right_inj hp.out.one_lt, pow_one, ← absNorm_eq_pow_inertiaDeg' _ hp.out, + rw [← Nat.pow_right_inj hp.out.one_lt, pow_one, pow_inertiaDeg', absNorm_span_zeta_sub_one] attribute [local instance] FractionRing.liftAlgebra in diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean index 1c68503bdc453f..ba9f70b1c8c348 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean @@ -189,9 +189,9 @@ lemma not_dvd_discr_iff_forall_liesOver [IsIntegralClosure 𝒪 ℤ K] {p : ℤ} exact ⟨P, hP, ⟨h₁.symm⟩, h₂⟩ · rintro ⟨P, hP, hP', hP''⟩ have := Ideal.absNorm_dvd_absNorm_of_le (Ideal.dvd_iff_le.mp hP'') - rw [absNorm_differentIdeal K, Ideal.absNorm_eq_pow_inertiaDeg P hp, + rw [absNorm_differentIdeal K, ← Ideal.natAbs_pow_inertiaDeg' p, ← Int.natAbs_pow, Int.natAbs_dvd_natAbs] at this - exact (dvd_pow_self _ (Ideal.inertiaDeg_pos' ..).ne').trans this + exact (dvd_pow_self _ (Ideal.inertiaDeg'_pos ..).ne').trans this /-- A prime `p` does not divide `discr K` if and only if `p` (as the ideal `span {p}`) is unramified in the ring of integers `𝒪`. diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index 4998fe11081a7d..5e4c54f5a6c01a 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -468,14 +468,9 @@ theorem absNorm_relNorm [PerfectField (FractionRing R)] (I : Ideal S) : have : Q.IsMaximal := Ring.DimensionLEOne.maximalOfPrime hQ' hQ.1 let P := under R Q let p := absNorm (under ℤ P) - have : NeZero P := ⟨under_ne_bot R hQ'⟩ - have : Q.LiesOver P := by simp [liesOver_iff, P] have : Q.LiesOver (span {(p : ℤ)}) := LiesOver.trans Q P _ - have : Fact (p.Prime) := ⟨Nat.absNorm_under_prime _⟩ - have hp : Prime (p : ℤ) := Nat.prime_iff_prime_int.mp <| Nat.absNorm_under_prime _ - rw [relNorm_eq_pow_of_isMaximal Q P, map_pow, absNorm_eq_pow_inertiaDeg Q hp, - absNorm_eq_pow_inertiaDeg P hp, inertiaDeg_algebra_tower (span {(p : ℤ)}) P Q, pow_mul, - ← inertiaDeg_eq_inertiaDeg' P] + rw [relNorm_eq_pow_of_isMaximal Q P, map_pow, ← pow_inertiaDeg' p, ← pow_inertiaDeg' p, + ← pow_mul, ← inertiaDeg'_tower] theorem relNorm_int (I : Ideal S) : relNorm ℤ I = Ideal.span {(absNorm I : ℤ)} := by diff --git a/Mathlib/RingTheory/RamificationInertia/Inertia.lean b/Mathlib/RingTheory/RamificationInertia/Inertia.lean index b36614f2b52344..43dccb0c21f83a 100644 --- a/Mathlib/RingTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/RingTheory/RamificationInertia/Inertia.lean @@ -120,6 +120,33 @@ theorem inertiaDeg'_smul {G : Type*} [Group G] [MulSemiringAction G S] [SMulComm let e₂ := Ideal.residueFieldAlgEquiv' p (g • q) q f₀.symm (comap_symm f₀.toRingEquiv).symm exact e₂.toLinearEquiv.finrank_eq +theorem cardQuot_pow_inertiaDeg' [Module.Finite R S] [p.IsMaximal] [q.IsMaximal] [q.LiesOver p] : + p.cardQuot ^ q.inertiaDeg' R = q.cardQuot := by + let _ : Field (R ⧸ p) := Quotient.field p + rw [← inertiaDeg_eq_inertiaDeg' p q, inertiaDeg_algebraMap p q] + exact Module.natCard_eq_pow_finrank.symm + +theorem absNorm_pow_inertiaDeg' [Module.Finite R S] [q.IsPrime] [q.LiesOver p] + [IsDedekindDomain R] [IsDedekindDomain S] [Module.Free ℤ R] [Module.Free ℤ S] : + p.absNorm ^ q.inertiaDeg' R = q.absNorm := by + by_cases hp : p = ⊥ + · subst hp + simpa [eq_bot_of_liesOver_bot R q] using (inertiaDeg'_pos q R).ne' + have := isPrime_of_liesOver q p + have := isMaximal_of_isPrime_of_ne_bot p hp + have := IsMaximal.of_liesOver_isMaximal q p + exact cardQuot_pow_inertiaDeg' p q + +theorem natAbs_pow_inertiaDeg' [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] (p : ℤ) + (P : Ideal R) [P.IsPrime] [P.LiesOver (span {p})] : + p.natAbs ^ P.inertiaDeg' ℤ = absNorm P := by + simpa using absNorm_pow_inertiaDeg' (span {p}) P + +theorem pow_inertiaDeg' [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] (p : ℕ) + (P : Ideal R) [P.IsPrime] [P.LiesOver (span {(p : ℤ)})] : + p ^ P.inertiaDeg' ℤ = absNorm P := + natAbs_pow_inertiaDeg' p P + end end Ideal From a6949c0d5c069bda3c3b1020d5476cd4a1a02b85 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Wed, 1 Jul 2026 11:23:41 +0000 Subject: [PATCH 0514/1300] feat: homeomorphisms are precisely bijective strict maps (#41231) --- Mathlib/Topology/Maps/Strict/Basic.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Topology/Maps/Strict/Basic.lean b/Mathlib/Topology/Maps/Strict/Basic.lean index 91558107ed066b..df5a1e96472a03 100644 --- a/Mathlib/Topology/Maps/Strict/Basic.lean +++ b/Mathlib/Topology/Maps/Strict/Basic.lean @@ -167,6 +167,12 @@ lemma isEmbedding_iff_isStrictMap_injective : (Homeomorph.Quotient.congrRight <| by simp [f_inj.eq_iff]).trans Homeomorph.quotientBot exact f_strict.comp Φ.symm.isEmbedding +/-- Homeomorphisms are precisely bijective strict maps. -/ +lemma isHomeomorph_iff_isStrictMap_bijective : + IsHomeomorph f ↔ IsStrictMap f ∧ Bijective f := by + simp [isHomeomorph_iff_isEmbedding_surjective, isEmbedding_iff_isStrictMap_injective, Bijective, + and_assoc] + /-- Strict maps are preserved when precomposing with a homeomorphism. -/ lemma Homeomorph.isStrictMap_comp_iff (e : X ≃ₜ Y) {f : Y → Z} : IsStrictMap (f ∘ e) ↔ IsStrictMap f := From bb27e2144159b193d0aefed2ea9223ba8903388f Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:03:29 +0000 Subject: [PATCH 0515/1300] chore(LinearAlgebra/Dimension/Free): naming consistency (#41211) * Renames from discussion at https://github.com/leanprover-community/mathlib4/pull/37959/#discussion_r3142239137 Co-authored-by: artie2000 --- Mathlib/LinearAlgebra/Basis/MulOpposite.lean | 2 +- Mathlib/LinearAlgebra/Complex/FiniteDimensional.lean | 2 +- Mathlib/LinearAlgebra/Dimension/Free.lean | 12 +++++++++--- Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean | 8 ++++---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Mathlib/LinearAlgebra/Basis/MulOpposite.lean b/Mathlib/LinearAlgebra/Basis/MulOpposite.lean index e0f9bb47f3ff86..5661acfbf191f0 100644 --- a/Mathlib/LinearAlgebra/Basis/MulOpposite.lean +++ b/Mathlib/LinearAlgebra/Basis/MulOpposite.lean @@ -58,7 +58,7 @@ instance [Semiring R] [AddCommMonoid H] [Module R H] theorem rank [Semiring R] [StrongRankCondition R] [AddCommMonoid H] [Module R H] [Module.Free R H] : Module.rank R Hᵐᵒᵖ = Module.rank R H := - LinearEquiv.nonempty_equiv_iff_rank_eq.mp ⟨(opLinearEquiv R).symm⟩ + Module.nonempty_linearEquiv_iff_rank_eq.mp ⟨(opLinearEquiv R).symm⟩ theorem finrank [DivisionRing R] [AddCommGroup H] [Module R H] : Module.finrank R Hᵐᵒᵖ = Module.finrank R H := by diff --git a/Mathlib/LinearAlgebra/Complex/FiniteDimensional.lean b/Mathlib/LinearAlgebra/Complex/FiniteDimensional.lean index e96472678489d0..f100705876f12b 100644 --- a/Mathlib/LinearAlgebra/Complex/FiniteDimensional.lean +++ b/Mathlib/LinearAlgebra/Complex/FiniteDimensional.lean @@ -76,6 +76,6 @@ lemma Complex.rank_rat_complex : Module.rank ℚ ℂ = continuum := by /-- `ℂ` and `ℝ` are isomorphic as vector spaces over `ℚ`, or equivalently, as additive groups. -/ theorem Complex.nonempty_linearEquiv_real : Nonempty (ℂ ≃ₗ[ℚ] ℝ) := - LinearEquiv.nonempty_equiv_iff_rank_eq.mpr <| by simp + Module.nonempty_linearEquiv_iff_rank_eq.mpr <| by simp end Rational diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index c7f81be130be3c..7e159ff9705648 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -14,7 +14,7 @@ public import Mathlib.SetTheory.Cardinal.Finsupp # Rank of free modules ## Main result -- `LinearEquiv.nonempty_equiv_iff_lift_rank_eq`: +- `Module.nonempty_equiv_iff_lift_rank_eq`: Two free modules are isomorphic iff they have the same dimension. - `Module.finBasis`: An arbitrary basis of a finite free module indexed by `Fin n` given `finrank R M = n`. @@ -193,15 +193,21 @@ def LinearEquiv.ofRankEq (cond : Module.rank R M = Module.rank R M₁) : M ≃ end /-- Two vector spaces are isomorphic if and only if they have the same dimension. -/ -theorem LinearEquiv.nonempty_equiv_iff_lift_rank_eq : Nonempty (M ≃ₗ[R] M') ↔ +theorem Module.nonempty_linearEquiv_iff_lift_rank_eq : Nonempty (M ≃ₗ[R] M') ↔ Cardinal.lift.{v'} (Module.rank R M) = Cardinal.lift.{v} (Module.rank R M') := ⟨fun ⟨h⟩ => LinearEquiv.lift_rank_eq h, fun h => nonempty_linearEquiv_of_lift_rank_eq h⟩ +@[deprecated (since := "2026-06-30")] +alias LinearEquiv.nonempty_equiv_iff_lift_rank_eq := Module.nonempty_linearEquiv_iff_lift_rank_eq + /-- Two vector spaces are isomorphic if and only if they have the same dimension. -/ -theorem LinearEquiv.nonempty_equiv_iff_rank_eq : +theorem Module.nonempty_linearEquiv_iff_rank_eq : Nonempty (M ≃ₗ[R] M₁) ↔ Module.rank R M = Module.rank R M₁ := ⟨fun ⟨h⟩ => LinearEquiv.rank_eq h, fun h => nonempty_linearEquiv_of_rank_eq h⟩ +@[deprecated (since := "2026-06-30")] +alias LinearEquiv.nonempty_equiv_iff_rank_eq := Module.nonempty_linearEquiv_iff_rank_eq + /-- Two finite and free modules are isomorphic if they have the same (finite) rank. -/ theorem FiniteDimensional.nonempty_linearEquiv_of_finrank_eq [Module.Finite R M] [Module.Finite R M'] (cond : finrank R M = finrank R M') : diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index ce0aff98a36521..6c211003650168 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -96,11 +96,11 @@ theorem _root_.Submodule.exists_linearEquiv_restrict_eq let eQ' := W'.prodEquivOfIsCompl Q' hQ' suffices Nonempty (Q ≃ₗ[K] Q') from ⟨eQ.symm ≪≫ₗ (LinearEquiv.prodCongr f this.some) ≪≫ₗ eQ', by aesop⟩ - refine LinearEquiv.nonempty_equiv_iff_rank_eq.mpr ?_ + refine Module.nonempty_linearEquiv_iff_rank_eq.mpr ?_ rw [← Cardinal.add_right_inj_of_lt_aleph0 (γ := Module.rank K W), - add_comm, ← rank_prod', LinearEquiv.nonempty_equiv_iff_rank_eq.mp ⟨eQ⟩, - add_comm, LinearEquiv.nonempty_equiv_iff_rank_eq.mp ⟨f⟩, - ← rank_prod', LinearEquiv.nonempty_equiv_iff_rank_eq.mp ⟨eQ'⟩] + add_comm, ← rank_prod', Module.nonempty_linearEquiv_iff_rank_eq.mp ⟨eQ⟩, + add_comm, Module.nonempty_linearEquiv_iff_rank_eq.mp ⟨f⟩, + ← rank_prod', Module.nonempty_linearEquiv_iff_rank_eq.mp ⟨eQ'⟩] exact Module.rank_lt_aleph0 K ↥W section From b3b5cf9c9d5fdb66d0b825cb0e5ca6311bbc0d59 Mon Sep 17 00:00:00 2001 From: Li Jiale <185082061+Scarlett-le@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:28:01 +0000 Subject: [PATCH 0516/1300] feat(Geometry/Euclidean): unoriented angle addition along a ray (#40497) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds two lemmas to `Mathlib/Geometry/Euclidean/Triangle.lean` describing how the unoriented angle at a point splits across a segment. * `angle_add_angle_eq_of_sbtw`: if `x` lies strictly between `a` and `c`, then `∠ a p x + ∠ x p c = ∠ a p c`, with no nondegeneracy hypothesis on the apex `p`. This complements the existing `angle_add_of_ne_of_ne`: that lemma allows weak betweenness of the foot but requires `p ≠ a` and `p ≠ c`, whereas here strict betweenness already supplies enough nondegeneracy to drop both hypotheses on `p`. * `angle_add_angle_eq_of_sbtw_of_sameRay`: the same decomposition when `b` lies on the same ray from `p` as a point `x` strictly between `a` and `c`, i.e. `∠ a p b + ∠ b p c = ∠ a p c`. Co-authored-by: Scarlett-le <735979178@qq.com> Co-authored-by: Oliver Nash --- .../Euclidean/Angle/Unoriented/Affine.lean | 28 +++++++++++++------ Mathlib/Geometry/Euclidean/Triangle.lean | 25 +++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean index 45bf2de5808eef..f583bf76b20867 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean @@ -117,6 +117,18 @@ theorem angle_const_sub (v : V) (v₁ v₂ v₃ : V) : ∠ (v - v₁) (v - v₂) theorem angle_neg (v₁ v₂ v₃ : V) : ∠ (-v₁) (-v₂) (-v₃) = ∠ v₁ v₂ v₃ := by simpa only [zero_sub] using angle_const_sub 0 v₁ v₂ v₃ +theorem angle_smul_right_of_pos (p₁ : P) {p₂ p₃ p₄ : P} {r : ℝ} (hr : 0 < r) + (hrv : r • (p₄ -ᵥ p₂) = p₃ -ᵥ p₂) : + ∠ p₁ p₂ p₃ = ∠ p₁ p₂ p₄ := by + simp only [angle, ← hrv] + exact InnerProductGeometry.angle_smul_right_of_pos (p₁ -ᵥ p₂) (p₄ -ᵥ p₂) hr + +theorem angle_smul_left_of_pos {p₁ p₂ p₄ : P} (p₃ : P) {r : ℝ} (hr : 0 < r) + (hrv : r • (p₄ -ᵥ p₂) = p₁ -ᵥ p₂) : + ∠ p₁ p₂ p₃ = ∠ p₄ p₂ p₃ := by + simp only [angle, ← hrv] + exact InnerProductGeometry.angle_smul_left_of_pos (p₄ -ᵥ p₂) (p₃ -ᵥ p₂) hr + /-- The angle at a point does not depend on the order of the other two points. -/ nonrec theorem angle_comm (p₁ p₂ p₃ : P) : ∠ p₁ p₂ p₃ = ∠ p₃ p₂ p₁ := @@ -167,9 +179,11 @@ theorem angle_eq_angle_of_angle_eq_pi (p₁ : P) {p₂ p₃ p₄ : P} (h : ∠ p unfold angle at * rcases angle_eq_pi_iff.1 h with ⟨_, ⟨r, ⟨hr, hpr⟩⟩⟩ rw [eq_comm] - convert! angle_smul_right_of_pos (p₁ -ᵥ p₂) (p₃ -ᵥ p₂) (add_pos (neg_pos_of_neg hr) zero_lt_one) - rw [add_smul, ← neg_vsub_eq_vsub_rev p₂ p₃, smul_neg, neg_smul, ← hpr] - simp + replace hpr : (-r + 1) • (p₃ -ᵥ p₂) = p₄ -ᵥ p₂ := by + rw [add_smul, ← neg_vsub_eq_vsub_rev p₂ p₃, smul_neg, neg_smul, ← hpr] + simp + replace hr : 0 < -r + 1 := by linarith + exact angle_smul_right_of_pos p₁ hr hpr /-- If ∠BCD = π, then ∠ACB + ∠ACD = π. -/ nonrec theorem angle_add_angle_eq_pi_of_angle_eq_pi (p₁ : P) {p₂ p₃ p₄ : P} (h : ∠ p₂ p₃ p₄ = π) : @@ -227,11 +241,9 @@ theorem dist_eq_abs_sub_dist_iff_angle_eq_zero {p₁ p₂ p₃ : P} (hp₁p₂ : /-- If M is the midpoint of the segment AB, then ∠AMB = π. -/ theorem angle_midpoint_eq_pi (p₁ p₂ : P) (hp₁p₂ : p₁ ≠ p₂) : ∠ p₁ (midpoint ℝ p₁ p₂) p₂ = π := by - simp only [angle, left_vsub_midpoint, invOf_eq_inv, right_vsub_midpoint, inv_pos, zero_lt_two, - angle_smul_right_of_pos, angle_smul_left_of_pos] - rw [← neg_vsub_eq_vsub_rev p₁ p₂] - apply angle_self_neg_of_nonzero - simpa only [ne_eq, vsub_eq_zero_iff_eq] + suffices dist p₁ p₂ = dist p₁ (midpoint ℝ p₁ p₂) + dist (midpoint ℝ p₁ p₂) p₂ by + rwa [← dist_eq_add_dist_iff_angle_eq_pi (by simpa) (by simpa), dist_comm p₂] + simp [dist_eq_norm_vsub V, left_vsub_midpoint, midpoint_vsub_right, norm_smul, ← two_mul] /-- If M is the midpoint of the segment AB and C is the same distance from A as it is from B then ∠CMA = π / 2. -/ diff --git a/Mathlib/Geometry/Euclidean/Triangle.lean b/Mathlib/Geometry/Euclidean/Triangle.lean index f8e9b497040c23..30fe0c9dafd0b5 100644 --- a/Mathlib/Geometry/Euclidean/Triangle.lean +++ b/Mathlib/Geometry/Euclidean/Triangle.lean @@ -357,6 +357,31 @@ lemma angle_add_of_ne_of_ne {a b c p : P} (hb : a ≠ b) (hc : a ≠ c) (hp : Wb have ep := angle_add_angle_eq_pi_of_angle_eq_pi a hp linarith only [ea, eb, ec, ep] +/-- If `X` lies strictly between `A` and `C`, then `∠ A P X + ∠ X P C = ∠ A P C`, +with no nondegeneracy assumption on the point `P`. -/ +lemma angle_add_angle_eq_of_sbtw {a c p x : P} (hx : Sbtw ℝ a x c) : + ∠ a p x + ∠ x p c = ∠ a p c := by + rcases eq_or_ne p a with rfl | hpa + · simp [(hx.angle_eq_right x).symm.trans (angle_self_of_ne hx.ne_left)] + rcases eq_or_ne p c with rfl | hpc + · simp [(hx.symm.angle_eq_right a).trans (angle_self_of_ne hx.left_ne_right)] + exact angle_add_of_ne_of_ne hpa hpc hx.wbtw + +/-- If `B` lies on the same ray from `P` as a point `X` strictly between `A` and `C`, +then `∠ A P B + ∠ B P C = ∠ A P C`. -/ +theorem angle_add_angle_eq_of_sbtw_of_sameRay {a b c p x : P} + (hx : Sbtw ℝ a x c) (hxb : SameRay ℝ (x -ᵥ p) (b -ᵥ p)) (hb : b ≠ p) : + ∠ a p b + ∠ b p c = ∠ a p c := by + rcases eq_or_ne p x with rfl | hpx + · have hpi : ∠ a p c = π := hx.angle₁₂₃_eq_pi + rw [hpi, angle_comm a p b] + exact angle_add_angle_eq_pi_of_angle_eq_pi b hpi + obtain ⟨r, hr, hrb⟩ := (exists_pos_left_iff_sameRay (by aesop) (by aesop)).2 hxb + have hab : ∠ a p b = ∠ a p x := angle_smul_right_of_pos a hr hrb + have hbc : ∠ b p c = ∠ x p c := angle_smul_left_of_pos c hr hrb + rw [hab, hbc] + exact angle_add_angle_eq_of_sbtw hx + /-- **Stewart's Theorem**. -/ theorem dist_sq_mul_dist_add_dist_sq_mul_dist (a b c p : P) (h : ∠ b p c = π) : dist a b ^ 2 * dist c p + dist a c ^ 2 * dist b p = From ceb4ceb97af8e721c14bb3245f0b545c80fa3c87 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:28:03 +0000 Subject: [PATCH 0517/1300] fix(Tactic/Push): ensure `push` is idempotent (#40760) This PR fixes a bug in `push` where it would stop normalizing while there were still more possible normalizations to do. The default value of `post` returns `.done` instead of `.continue`, which caused the problem --- Mathlib/Tactic/Push.lean | 8 ++++++-- MathlibTest/Tactic/Push/Basic.lean | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Mathlib/Tactic/Push.lean b/Mathlib/Tactic/Push.lean index 4a40d1ee13b244..bffb4f1db6b571 100644 --- a/Mathlib/Tactic/Push.lean +++ b/Mathlib/Tactic/Push.lean @@ -127,8 +127,12 @@ def pushCore (head : Head) (cfg : Config) (disch? : Option Simp.Discharge) (tgt (simpTheorems := #[]) (congrTheorems := ← getSimpCongrTheorems) let methods := match disch? with - | none => { pre := pushStep head cfg } - | some disch => { pre := pushStep head cfg, discharge? := disch, wellBehavedDischarge := false } + | none => { pre := pushStep head cfg, post _ := return .continue } + | some disch => { + pre := pushStep head cfg, + post _ := return .continue, + discharge? := disch, + wellBehavedDischarge := false } (·.1) <$> Simp.main tgt ctx (methods := methods) /-- Try to rewrite using a `pull` lemma. -/ diff --git a/MathlibTest/Tactic/Push/Basic.lean b/MathlibTest/Tactic/Push/Basic.lean index b1827f78c30fdd..ffcb6348d50aa1 100644 --- a/MathlibTest/Tactic/Push/Basic.lean +++ b/MathlibTest/Tactic/Push/Basic.lean @@ -1,4 +1,5 @@ module + import Mathlib.Tactic.Push import Mathlib.Data.Nat.Cast.Basic import Mathlib.Data.Set.Basic @@ -23,6 +24,10 @@ variable {p q r : Prop} #guard_msgs in #push _ ∧ _ => (p ∨ True) ∧ (q ∨ r) +/-- info: (∃ x x_1, x ≠ x_1) ∨ True -/ +#guard_msgs in +#push ∃ _, _ => ∃ a : Nat, ∃ b, a ≠ b ∨ True + example {r : ℕ → Prop} : ∀ n : ℕ, p ∨ r n ∧ q ∧ n = 1 := by push ∀ n, _ guard_target =ₛ p ∨ (∀ n, r n) ∧ q ∧ ∀ n : ℕ, n = 1 From 6813d5785d0b0bd69f6ff677c55cd28fa83dc144 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:28:06 +0000 Subject: [PATCH 0518/1300] feat(CategoryTheory/Limits/WeakLimits): weak limits (#41075) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define weak limits and add some minimal API for them. Also consider the special cases of weak equalizers, weak kernels and weak pullbacks. Prove that a category with weak equalizers and pullbacks has weak pullbacks, and that a preadditive category has weak equalizers if and only if it has weak kernels. If `F : J ⥤ C` is a functor and `c : Cone F`, we say that `c` is a weak limit of `F` if every cone over `F` admits a (not necessarily unique) morphism to `c`. In other words, a weak limit satisfies the same "versal property" as a limit, without the uniqueness condition. In particular, weak limits are not unique, and they are not functorial. TODO: * Prove that a triangulated category has weak kernels: this is #41162. * If `C` is an additive category with weak limits, then its cokernel completion (also TODO) is an abelian category. Co-authored-by: morel Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 4 + .../Limits/WeakLimits/Basic.lean | 259 ++++++++++++++++++ .../Limits/WeakLimits/WeakEqualizers.lean | 127 +++++++++ .../Limits/WeakLimits/WeakKernels.lean | 138 ++++++++++ .../Limits/WeakLimits/WeakPullbacks.lean | 249 +++++++++++++++++ docs/references.bib | 11 + 6 files changed, 788 insertions(+) create mode 100644 Mathlib/CategoryTheory/Limits/WeakLimits/Basic.lean create mode 100644 Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean create mode 100644 Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean create mode 100644 Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean diff --git a/Mathlib.lean b/Mathlib.lean index ff49b998f216bb..7c01f4ec4aadf7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2994,6 +2994,10 @@ public import Mathlib.CategoryTheory.Limits.Types.Pushouts public import Mathlib.CategoryTheory.Limits.Types.Yoneda public import Mathlib.CategoryTheory.Limits.Unit public import Mathlib.CategoryTheory.Limits.VanKampen +public import Mathlib.CategoryTheory.Limits.WeakLimits.Basic +public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakEqualizers +public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakKernels +public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakPullbacks public import Mathlib.CategoryTheory.Limits.Yoneda public import Mathlib.CategoryTheory.Linear.Basic public import Mathlib.CategoryTheory.Linear.FunctorCategory diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/Basic.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/Basic.lean new file mode 100644 index 00000000000000..c071c30f351fd3 --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/Basic.lean @@ -0,0 +1,259 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Limits.HasLimits + +/-! +# Weak limits + +If `F : J ⥤ C` is a functor and `c : Cone F`, we say that `c` is a weak limit of `F` if +every cone over `F` admits a (not necessarily unique) morphism to `c`. In other words, a +weak limit satisfies the same "versal property" as a limit, without the uniqueness +condition. In particular, weak limits are not unique, and they are not functorial. + +We set up some API for weak limits, mostly copied from that for limits, prove that any +limit cone is a weak limit cone, and that, if a limit exists, then it is a retract of any +weak limit (see `IsWeakLimit.retractOfIsLimit`). + +In the files `WeakEqualizers.lean`, `WeakKernels.lean` and `WeakPullbacks.lean`, we specialize +to weak equalizers, weak kernels and weak pullbacks, and give some API for those shapes, +again inspired from the non-weak case. We prove that a category with weak equalizers and +pullbacks has weak pullbacks, and that a preadditive category has weak equalizers if and only +if it has weak kernels. + +## References + +* [Peter J Freyd, *Representations in Abelian categories*, p. 99][freyd1966repabelian] + +-/ + +@[expose] public section + +noncomputable section + +open CategoryTheory Category Limits + +variable {J : Type*} [Category* J] {K : Type*} [Category* K] {C : Type*} + [Category* C] {F : Functor J C} {D : Type*} [Category* D] {G : Functor K D} + +namespace CategoryTheory.Limits + +/-- A cone `t` over `F` is a weak limit cone if each cone over `F` admits a +cone morphism to `t`. -/ +structure IsWeakLimit (t : Cone F) where + /-- There is a morphism from any cone point to `t.pt` -/ + lift : ∀ s : Cone F, s.pt ⟶ t.pt + /-- The map makes the triangle with the two natural transformations commute -/ + fac : ∀ (s : Cone F) (j : J), lift s ≫ t.π.app j = s.π.app j := by cat_disch + +attribute [reassoc (attr := simp)] IsWeakLimit.fac + +/-- +If `F` has a limit, then it is a retract of any weak limit of `F`. +-/ +def IsWeakLimit.retractOfIsLimit {t t' : Cone F} (l : IsLimit t) (l' : IsWeakLimit t') : + Retract t.pt t'.pt where + i := l'.lift t + r := l.lift t' + retract := l.hom_ext (fun _ ↦ by rw [assoc, id_comp, l.fac t', l'.fac t]) + +/-- +If `c : Cone F` is a limit, then it is a weak limit. +-/ +def IsLimit.isWeakLimit {t : Cone F} (l : IsLimit t) : IsWeakLimit t where + lift := l.lift + fac := l.fac + +/-- `WeakLimitCone F` contains a cone over `F` together with the information that it is +a weak limit. -/ +structure WeakLimitCone (F : J ⥤ C) where + /-- The cone itself -/ + cone : Cone F + /-- The proof that is the weak limit cone -/ + isWeakLimit : IsWeakLimit cone + +/-- +Any limit cone defines a weak limit cone with the same underlying cone over `F` and the same +lifts. +-/ +def WeakLimitCone.ofLimitCone {F : J ⥤ C} (c : LimitCone F) : WeakLimitCone F where + cone := c.cone + isWeakLimit := c.isLimit.isWeakLimit + +/-- `HasWeakLimit F` represents the mere existence of a weak limit for `F`. -/ +class HasWeakLimit (F : J ⥤ C) : Prop where mk' :: + /-- There is some weak limit cone for `F` -/ + exists_weakLimitCone : Nonempty (WeakLimitCone F) + +/-- +If `F` has a limit, then it has a weak limit. +-/ +instance (F : J ⥤ C) [HasLimit F] : HasWeakLimit F where + exists_weakLimitCone := Nonempty.intro (WeakLimitCone.ofLimitCone (getLimitCone F)) + +theorem HasWeakLimit.mk {F : J ⥤ C} (d : WeakLimitCone F) : HasWeakLimit F := + ⟨Nonempty.intro d⟩ + +/-- Use the axiom of choice to extract explicit `WeakLimitCone F` from `HasWeakLimit F`. -/ +@[no_expose] +def getWeakLimitCone (F : J ⥤ C) [HasWeakLimit F] : WeakLimitCone F := + Classical.choice <| HasWeakLimit.exists_weakLimitCone + +variable (J C) in +/-- `C` has weak limits of shape `J` if there exists a weak limit for every functor +`F : J ⥤ C`. -/ +class HasWeakLimitsOfShape : Prop where + /-- All functors `F : J ⥤ C` from `J` have weak limits -/ + hasWeakLimit : ∀ F : J ⥤ C, HasWeakLimit F := by infer_instance + +attribute [instance] HasWeakLimitsOfShape.hasWeakLimit + +instance (priority := 100) [HasLimitsOfShape J C] : HasWeakLimitsOfShape J C where + +-- Interface to the `HasWeakLimit` class. +/-- An arbitrary choice of weak limit cone for a functor. -/ +def weakLimit.cone (F : J ⥤ C) [HasWeakLimit F] : Cone F := + (getWeakLimitCone F).cone + +/-- An arbitrary choice of weak limit object of a functor. -/ +def weakLimit (F : J ⥤ C) [HasWeakLimit F] := + (weakLimit.cone F).pt + +/-- The projection from the weak limit object to a value of the functor. -/ +def weakLimit.π (F : J ⥤ C) [HasWeakLimit F] (j : J) : weakLimit F ⟶ F.obj j := + (weakLimit.cone F).π.app j + +@[reassoc] +theorem weakLimit.π_comp_eqToHom (F : J ⥤ C) [HasWeakLimit F] {j j' : J} (hj : j = j') : + weakLimit.π F j ≫ eqToHom (by subst hj; rfl) = weakLimit.π F j' := by + subst hj + simp + +@[simp] +theorem weakLimit.cone_pt {F : J ⥤ C} [HasWeakLimit F] : + (weakLimit.cone F).pt = weakLimit F := rfl + +@[simp] +theorem weakLimit.cone_π {F : J ⥤ C} [HasWeakLimit F] : + (weakLimit.cone F).π.app = weakLimit.π _ := rfl + +@[reassoc (attr := simp)] +theorem weakLimit.w (F : J ⥤ C) [HasWeakLimit F] {j j' : J} (f : j ⟶ j') : + weakLimit.π F j ≫ F.map f = weakLimit.π F j' := + (weakLimit.cone F).w f + +/-- Evidence that the arbitrary choice of cone provided by `weakLimit.cone F` +is a weak limit cone. -/ +def weakLimit.isWeakLimit (F : J ⥤ C) [HasWeakLimit F] : + IsWeakLimit (weakLimit.cone F) := + (getWeakLimitCone F).isWeakLimit + +/-- A morphism from the cone point of any other cone to the weak limit object. -/ +def weakLimit.lift (F : J ⥤ C) [HasWeakLimit F] (c : Cone F) : + c.pt ⟶ weakLimit F := + (weakLimit.isWeakLimit F).lift c + +@[simp] +theorem weakLimit.isWeakLimit_lift {F : J ⥤ C} [HasWeakLimit F] (c : Cone F) : + (weakLimit.isWeakLimit F).lift c = weakLimit.lift F c := + rfl + +@[reassoc (attr := simp)] +theorem weakLimit.lift_π {F : J ⥤ C} [HasWeakLimit F] (c : Cone F) (j : J) : + weakLimit.lift F c ≫ weakLimit.π F j = c.π.app j := + IsWeakLimit.fac _ c j + +namespace IsWeakLimit + +/-- Transport evidence that a cone is a weak limit cone across an isomorphism of cones. -/ +@[simps] +def ofIsoWeakLimit {r t : Cone F} (P : IsWeakLimit r) (i : r ≅ t) : IsWeakLimit t where + lift s := P.lift s ≫ i.hom.hom + +/-- Isomorphism of cones preserves whether or not they are weak limit cones. -/ +def equivIsoWeakLimit {r t : Cone F} (i : r ≅ t) : IsWeakLimit r ≃ IsWeakLimit t where + toFun h := h.ofIsoWeakLimit i + invFun h := h.ofIsoWeakLimit i.symm + left_inv _ := by simp [ofIsoWeakLimit] + right_inv _ := by simp [ofIsoWeakLimit] + +@[simp] +theorem equivIsoWeakLimit_apply {r t : Cone F} (i : r ≅ t) (P : IsWeakLimit r) : + equivIsoWeakLimit i P = P.ofIsoWeakLimit i := + rfl + +@[simp] +theorem equivIsoWeakLimit_symm_apply {r t : Cone F} (i : r ≅ t) (P : IsWeakLimit t) : + (equivIsoWeakLimit i).symm P = P.ofIsoWeakLimit i.symm := + rfl + +/-- The versal morphism from any other cone to a weak limit cone. -/ +@[simps] +def liftConeMorphism {t : Cone F} (h : IsWeakLimit t) (s : Cone F) : s ⟶ t where hom := h.lift s + +/-- Alternative constructor for `isWeakLimit`, +providing a morphism of cones rather than a morphism between the cone points +and separately the factorisation condition. +-/ +@[simps] +def mkOfConeMorphism {t : Cone F} (lift : ∀ s : Cone F, s ⟶ t) : IsWeakLimit t where + lift s := (lift s).hom + +/-- Given a right adjoint functor between categories of cones, +the image of a weak limit cone is a weak limit cone. +-/ +def ofRightAdjoint {left : Cone F ⥤ Cone G} {right : Cone G ⥤ Cone F} + (adj : left ⊣ right) {c : Cone G} (t : IsWeakLimit c) : IsWeakLimit (right.obj c) := + mkOfConeMorphism (fun s => adj.homEquiv s c (t.liftConeMorphism _)) + +/-- Given two functors which have equivalent categories of cones, we can transport evidence of +a weak limit cone across the equivalence. +-/ +lemma iff_of_cone_equiv {D : Type*} [Category* D] {G : K ⥤ D} (h : Cone G ≌ Cone F) {c : Cone G} : + Nonempty (IsWeakLimit (h.functor.obj c)) ↔ Nonempty (IsWeakLimit c) := + ⟨fun P ↦ Nonempty.intro (IsWeakLimit.ofIsoWeakLimit + (IsWeakLimit.ofRightAdjoint h.toAdjunction P.some) (h.unitIso.symm.app c)), + fun P ↦ Nonempty.intro (IsWeakLimit.ofRightAdjoint h.symm.toAdjunction P.some)⟩ + +/-- A cone postcomposed with a natural isomorphism is a weak limit cone +if and only if the original cone is. +-/ +lemma postcompose_hom_iff_of_iso {F G : J ⥤ C} (α : F ≅ G) (c : Cone F) : + Nonempty (IsWeakLimit ((Cone.postcompose α.hom).obj c)) ↔ Nonempty (IsWeakLimit c) := + iff_of_cone_equiv (Cone.postcomposeEquivalence α) + +/-- A cone postcomposed with the inverse of a natural isomorphism is a weak limit cone +if and only if the original cone is. +-/ +lemma postcompose_inv_iff_of_iso {F G : J ⥤ C} (α : F ≅ G) (c : Cone G) : + Nonempty (IsWeakLimit ((Cone.postcompose α.inv).obj c)) ↔ Nonempty (IsWeakLimit c) := + postcompose_hom_iff_of_iso α.symm c + +/-- Constructing an equivalence between `Nonempty (IsWeakLimit c)` and `Nonempty (IsWeakLimit d)` +from a natural isomorphism between the underlying functors, and then an isomorphism between `c` +transported along this and `d`. +-/ +lemma iff_of_natIso_of_iso {F G : J ⥤ C} (α : F ≅ G) (c : Cone F) (d : Cone G) + (w : (Cone.postcompose α.hom).obj c ≅ d) : + Nonempty (IsWeakLimit c) ↔ Nonempty (IsWeakLimit d) := + (postcompose_hom_iff_of_iso α _).symm.trans (IsWeakLimit.equivIsoWeakLimit w).nonempty_congr + +end IsWeakLimit + +/-- If a functor `F` has a weak limit, so does any naturally isomorphic functor. +-/ +theorem hasWeakLimit_of_iso {F G : J ⥤ C} [HasWeakLimit F] (α : F ≅ G) : HasWeakLimit G := + HasWeakLimit.mk + { cone := (Cone.postcompose α.hom).obj (weakLimit.cone F) + isWeakLimit := + Nonempty.some ((IsWeakLimit.postcompose_hom_iff_of_iso α _ ).mpr + (Nonempty.intro (weakLimit.isWeakLimit F))) } + +theorem hasWeakLimit_iff_of_iso {F G : J ⥤ C} (α : F ≅ G) : HasWeakLimit F ↔ HasWeakLimit G := + ⟨fun _ ↦ hasWeakLimit_of_iso α, fun _ ↦ hasWeakLimit_of_iso α.symm⟩ + +end CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean new file mode 100644 index 00000000000000..ce51e6a949d41c --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean @@ -0,0 +1,127 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Limits.WeakLimits.Basic +public import Mathlib.CategoryTheory.Limits.Shapes.Equalizers + +/-! +# Weak equalizers + +These are weak limits for diagrams of shape `WalkingParallelPair`. + +-/ + +@[expose] public section + +universe u v w + +noncomputable section + +open CategoryTheory Category Limits + +variable {C : Type*} [Category* C] + +namespace CategoryTheory.Limits + +variable {X Y : C} (f g : X ⟶ Y) + +/-- Two parallel morphisms `f` and `g` have a weak equalizer if the diagram `parallelPair f g` +has a weak limit. -/ +abbrev HasWeakEqualizer := + HasWeakLimit (parallelPair f g) + +variable [HasWeakEqualizer f g] + +/-- If a weak equalizer of `f` and `g` exists, we can access an arbitrary choice of such by +saying `weakEqualizer f g`. -/ +noncomputable abbrev weakEqualizer : C := + weakLimit (parallelPair f g) + +/-- If a weak equalizer of `f` and `g` exists, we can access the morphism +`weakEqualizer f g ⟶ X` by saying `weakEqualizer.ι f g`. -/ +noncomputable abbrev weakEqualizer.ι : weakEqualizer f g ⟶ X := + weakLimit.π (parallelPair f g) WalkingParallelPair.zero + +/-- A weak equalizer cone for a parallel pair `f` and `g` -/ +noncomputable abbrev weakEqualizer.fork : Fork f g := + weakLimit.cone (parallelPair f g) + +@[simp] +theorem weakEqualizer.fork_ι : (weakEqualizer.fork f g).ι = weakEqualizer.ι f g := + rfl + +@[simp] +theorem weakEqualizer.fork_π_app_zero : + (weakEqualizer.fork f g).π.app WalkingParallelPair.zero = weakEqualizer.ι f g := + rfl + +@[reassoc] +theorem weakEqualizer.condition : weakEqualizer.ι f g ≫ f = weakEqualizer.ι f g ≫ g := + Fork.condition <| weakLimit.cone <| parallelPair f g + +set_option backward.defeqAttrib.useBackward true in +/-- The weak equalizer built from `weakEqualizer.ι f g` is weakly limiting. -/ +def weakEqualizerIsWeakEqualizer : IsWeakLimit (Fork.ofι (weakEqualizer.ι f g) + (weakEqualizer.condition f g)) := + IsWeakLimit.ofIsoWeakLimit (weakLimit.isWeakLimit _) (Fork.ext (Iso.refl _) (by simp)) + +variable {f g} + +/-- A morphism `k : W ⟶ X` satisfying `k ≫ f = k ≫ g` factors through the weak equalizer of +`f` and `g` via `weakEqualizer.lift : W ⟶ weakEqualizer f g`. -/ +noncomputable abbrev weakEqualizer.lift {W : C} (k : W ⟶ X) (h : k ≫ f = k ≫ g) : + W ⟶ weakEqualizer f g := + weakLimit.lift (parallelPair f g) (Fork.ofι k h) + +@[reassoc] +theorem weakEqualizer.lift_ι {W : C} (k : W ⟶ X) (h : k ≫ f = k ≫ g) : + weakEqualizer.lift k h ≫ weakEqualizer.ι f g = k := + weakLimit.lift_π _ _ + +/-- A morphism `k : W ⟶ X` satisfying `k ≫ f = k ≫ g` induces a morphism +`l : W ⟶ weakEqualizer f g` satisfying `l ≫ weakEqualizer.ι f g = k`. -/ +def weakEqualizer.lift' {W : C} (k : W ⟶ X) (h : k ≫ f = k ≫ g) : + { l : W ⟶ weakEqualizer f g // l ≫ weakEqualizer.ι f g = k } := + ⟨weakEqualizer.lift k h, weakEqualizer.lift_ι _ _⟩ + +variable (C) + +/-- A category `HasWeakEqualizers` if it has all weak limits of shape `WalkingParallelPair`, +i.e. if it has a weak equalizer for every parallel pair of morphisms. -/ +abbrev HasWeakEqualizers := + HasWeakLimitsOfShape WalkingParallelPair C + +/-- A category with equalizers has weak equalizers. -/ +instance (priority := 100) HasWeakEqualizersOfHasEqualizers [HasEqualizers C] : + HasWeakEqualizers C where + +/-- If `C` has all weak limits of diagrams `parallelPair f g`, then it has all weak equalizers -/ +theorem hasWeakEqualizers_of_hasWeakLimit_parallelPair + [∀ {X Y : C} {f g : X ⟶ Y}, HasWeakLimit (parallelPair f g)] : HasWeakEqualizers C where + hasWeakLimit F := hasWeakLimit_of_iso (diagramIsoParallelPair F).symm + +variable {C} + +/-- This is a slightly more convenient method to verify that a fork is a weak limit cone. It +only asks for a proof of facts that carry any mathematical content -/ +@[simps] +def Fork.IsWeakLimit.mk (t : Fork f g) (lift : ∀ s : Fork f g, s.pt ⟶ t.pt) + (fac : ∀ s : Fork f g, lift s ≫ Fork.ι t = Fork.ι s) : IsWeakLimit t := + { lift + fac s j := + WalkingParallelPair.casesOn j (fac s) <| by + simp [← Category.assoc, fac] } + +/-- This is another convenient method to verify that a fork is a weak limit cone. It +only asks for a proof of facts that carry any mathematical content, and allows access to the +same `s` for all parts. -/ +def Fork.IsWeakLimit.mk' {X Y : C} {f g : X ⟶ Y} (t : Fork f g) + (create : ∀ s : Fork f g, { l // l ≫ t.ι = s.ι}) : + IsWeakLimit t := + Fork.IsWeakLimit.mk t (fun s => (create s).1) (fun s => (create s).2) + +end CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean new file mode 100644 index 00000000000000..7e0cb008f5d725 --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean @@ -0,0 +1,138 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakEqualizers +public import Mathlib.CategoryTheory.Limits.Shapes.Kernels +public import Mathlib.CategoryTheory.Preadditive.Basic + +/-! +# Weak kernels + +These are weak equalizes for functors of the form `ParallelPair f 0`. + +If the category is preadditive, then weak equalizers exist if and only if weak kernels exist. +(See `hasWeakEqualizer_of_hasWeakKernel` and `hasWeakKernel_of_hasWeakEqualizer`.) + +-/ + +@[expose] public section + +universe u v w + +noncomputable section + +open CategoryTheory Category Limits + +variable {C : Type*} [Category* C] + +namespace CategoryTheory.Limits + +variable [HasZeroMorphisms C] {X Y : C} (f g : X ⟶ Y) + +/-- A morphism `f` has a weak kernel if the functor `ParallelPair f 0` has a weak limit. -/ +abbrev HasWeakKernel : Prop := + HasWeakLimit (parallelPair f 0) + +variable (C) in +/-- `HasWeakKernels` represents the existence of weak kernels for every morphism. -/ +class HasWeakKernels : Prop where + hasWeakLimit : ∀ {X Y : C} (f : X ⟶ Y), HasWeakKernel f := by infer_instance + +attribute [instance 100] HasWeakKernels.hasWeakLimit + +/-- If a category has kernels, then it has weak kernels. -/ +instance (priority := 100) HasWeakKernelsOfHasKernels [HasKernels C] : + HasWeakKernels C where + +section + +variable [HasWeakKernel f] + +/-- The weak kernel of a morphism. -/ +abbrev weakKernel : C := + weakEqualizer f 0 + +/-- The map from `weakKernel f` into the source of `f`. -/ +abbrev weakKernel.ι : weakKernel f ⟶ X := + weakEqualizer.ι f 0 + +@[simp] +theorem weakEqualizer_as_weakKernel : weakEqualizer.ι f 0 = weakKernel.ι f := rfl + +@[reassoc (attr := simp)] +theorem weakKernel.condition : weakKernel.ι f ≫ f = 0 := + KernelFork.condition _ + +set_option backward.defeqAttrib.useBackward true in +/-- The weak kernel built from `weakKernel.ι f` is weakly limiting. -/ +def weakKernelIsWeakKernel : + IsWeakLimit (Fork.ofι (weakKernel.ι f) ((weakKernel.condition f).trans comp_zero.symm)) := + IsWeakLimit.ofIsoWeakLimit (weakLimit.isWeakLimit _) (Fork.ext (Iso.refl _) (by simp)) + +/-- Given any morphism `k : W ⟶ X` satisfying `k ≫ f = 0`, `k` factors through +`weakKernel.ι f` via `weakKernel.lift : W ⟶ weakKernel f`. -/ +abbrev weakKernel.lift {W : C} (k : W ⟶ X) (h : k ≫ f = 0) : W ⟶ weakKernel f := + (weakKernelIsWeakKernel f).lift (KernelFork.ofι k h) + +@[reassoc (attr := simp)] +theorem weakKernel.lift_ι {W : C} (k : W ⟶ X) (h : k ≫ f = 0) : + weakKernel.lift f k h ≫ weakKernel.ι f = k := + (weakKernelIsWeakKernel f).fac (KernelFork.ofι k h) WalkingParallelPair.zero + +/-- Any morphism `k : W ⟶ X` satisfying `k ≫ f = 0` induces a morphism `l : W ⟶ weakKernel f` +such that `l ≫ weakKernel.ι f = k`. -/ +def weakKernel.lift' {W : C} (k : W ⟶ X) (h : k ≫ f = 0) : + { l : W ⟶ weakKernel f // l ≫ weakKernel.ι f = k } := + ⟨weakKernel.lift f k h, weakKernel.lift_ι _ _ _⟩ + +end + +end Limits + +namespace Preadditive + +variable [Preadditive C] {X Y : C} {f g : X ⟶ Y} + +/-- A weak kernel of `f - g` is a weak equalizer of `f` and `g`. -/ +def isWeakLimitForkOfKernelFork {c : KernelFork (f - g)} (i : IsWeakLimit c) : + IsWeakLimit (forkOfKernelFork c) := + Fork.IsWeakLimit.mk' _ fun s => ⟨i.lift (kernelForkOfFork s), i.fac _ _⟩ + +@[simp] +theorem isWeakLimitForkOfKernelFork_lift {c : KernelFork (f - g)} (i : IsWeakLimit c) + (s : Fork f g) : (isWeakLimitForkOfKernelFork i).lift s = i.lift (kernelForkOfFork s) := + rfl + +/-- A weak equalizer of `f` and `g` is a weak kernel of `f - g`. -/ +def isWeakLimitKernelForkOfFork {c : Fork f g} (i : IsWeakLimit c) : + IsWeakLimit (kernelForkOfFork c) := + Fork.IsWeakLimit.mk' _ fun s => ⟨i.lift (forkOfKernelFork s), i.fac _ _⟩ + +variable (f g) + +/-- A preadditive category has a weak equalizer for `f` and `g` if it has a weak +kernel for `f - g`. -/ +theorem hasWeakEqualizer_of_hasWeakKernel [HasWeakKernel (f - g)] : HasWeakEqualizer f g := + HasWeakLimit.mk + { cone := forkOfKernelFork _ + isWeakLimit := isWeakLimitForkOfKernelFork (weakEqualizerIsWeakEqualizer (f - g) 0) } + +/-- A preadditive category has a weak kernel for `f - g` if it has a weak equalizer +for `f` and `g`. -/ +theorem hasWeakKernel_of_hasWeakEqualizer [HasWeakEqualizer f g] : HasWeakKernel (f - g) := + HasWeakLimit.mk + { cone := kernelForkOfFork (weakEqualizer.fork f g) + isWeakLimit := isWeakLimitKernelForkOfFork (weakLimit.isWeakLimit (parallelPair f g)) } + +/-- If a preadditive category has all weak kernels, then it also has all weak equalizers. -/ +theorem hasWeakEqualizers_of_hasWeakKernels [HasWeakKernels C] : HasWeakEqualizers C := + have {X Y : C} (f g : X ⟶ Y) := hasWeakEqualizer_of_hasWeakKernel f g + hasWeakEqualizers_of_hasWeakLimit_parallelPair C + +end Preadditive + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean new file mode 100644 index 00000000000000..bfee2bd6539aad --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean @@ -0,0 +1,249 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakEqualizers + +/-! +# Weak pullbacks + +These are weak limits for diagrams of shape `WalkingCospan`. + +If a category has binary products and weak equalizers, then it has weak kernels +(see `hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakKernels`). + +-/ + +@[expose] public section + +universe u v w + +noncomputable section + +open CategoryTheory Category Limits + +variable {C : Type*} [Category* C] + +namespace CategoryTheory.Limits + +variable {W X Y Z : C} + +/-- Two morphisms `f : X ⟶ Z` and `g : Y ⟶ Z` have a weak pullback if the diagram +`cospan f g` has a weak limit. -/ +abbrev HasWeakPullback {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) := + HasWeakLimit (cospan f g) + +/-- `weakPullback f g` computes the weak pullback of a pair of morphisms +with the same target. -/ +abbrev weakPullback {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakPullback f g] := + weakLimit (cospan f g) + +/-- The cone associated to the weak pullback of `f` and `g` -/ +abbrev weakPullback.cone {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) + [HasWeakPullback f g] : PullbackCone f g := + weakLimit.cone (cospan f g) + +/-- The first projection of the weak pullback of `f` and `g`. -/ +abbrev weakPullback.fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakPullback f g] : + weakPullback f g ⟶ X := + weakLimit.π (cospan f g) WalkingCospan.left + +/-- The second projection of the weak pullback of `f` and `g`. -/ +abbrev weakPullback.snd {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakPullback f g] : + weakPullback f g ⟶ Y := + weakLimit.π (cospan f g) WalkingCospan.right + +/-- A pair of morphisms `h : W ⟶ X` and `k : W ⟶ Y` satisfying `h ≫ f = k ≫ g` induces a morphism +`weakPullback.lift : W ⟶ weakPullback f g`. -/ +abbrev weakPullback.lift {W X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasWeakPullback f g] (h : W ⟶ X) + (k : W ⟶ Y) (w : h ≫ f = k ≫ g := by cat_disch) : W ⟶ weakPullback f g := + weakLimit.lift _ (PullbackCone.mk h k w) + +set_option backward.isDefEq.respectTransparency false in +lemma weakPullback.exists_lift {W X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakPullback f g] + (h : W ⟶ X) (k : W ⟶ Y) (w : h ≫ f = k ≫ g := by cat_disch) : + ∃ (l : W ⟶ weakPullback f g), + l ≫ weakPullback.fst f g = h ∧ l ≫ weakPullback.snd f g = k := + ⟨weakPullback.lift h k, by simp⟩ + +/-- The cone associated to a weak pullback is a weak limit cone. -/ +abbrev weakPullback.isWeakLimit {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakPullback f g] : + IsWeakLimit (weakPullback.cone f g) := + weakLimit.isWeakLimit (cospan f g) + +@[simp] +theorem weakLimit.pullbackConeFst_cone_cospan {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) + [HasWeakLimit (cospan f g)] : + PullbackCone.fst (weakLimit.cone (cospan f g)) = weakPullback.fst f g := rfl + +@[simp] +theorem weakLimit.pullbackConeSnd_cone_cospan {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) + [HasWeakLimit (cospan f g)] : + PullbackCone.snd (weakLimit.cone (cospan f g)) = weakPullback.snd f g := rfl + +@[reassoc] +theorem weakPullback.lift_fst {W X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} + [HasWeakPullback f g] (h : W ⟶ X) (k : W ⟶ Y) (w : h ≫ f = k ≫ g) : + weakPullback.lift h k w ≫ weakPullback.fst f g = h := + weakLimit.lift_π _ _ + +@[reassoc] +theorem weakPullback.lift_snd {W X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} + [HasWeakPullback f g] (h : W ⟶ X) (k : W ⟶ Y) (w : h ≫ f = k ≫ g) : + weakPullback.lift h k w ≫ weakPullback.snd f g = k := + weakLimit.lift_π _ _ + +/-- A pair of morphisms `h : W ⟶ X` and `k : W ⟶ Y` satisfying `h ≫ f = k ≫ g` induces a morphism +`l : W ⟶ weakPullback f g` such that `l ≫ weakPullback.fst = h` and `l ≫ weakPullback.snd = k`. -/ +def weakPullback.lift' {W X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasWeakPullback f g] + (h : W ⟶ X) (k : W ⟶ Y) (w : h ≫ f = k ≫ g) : + { l : W ⟶ weakPullback f g // + l ≫ weakPullback.fst f g = h ∧ l ≫ weakPullback.snd f g = k } := + ⟨weakPullback.lift h k w, weakPullback.lift_fst _ _ _, weakPullback.lift_snd _ _ _⟩ + +@[reassoc] +theorem weakPullback.condition {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasWeakPullback f g] : + weakPullback.fst f g ≫ f = weakPullback.snd f g ≫ g := + PullbackCone.condition _ + +/-- Given such a diagram, then there is a natural morphism from the weak pullback of +`W ⟶ S` and `X ⟶ S` to the weak pullback of `Y ⟶ T` and `Z ⟶ T`. + +``` +W ⟶ Y + ↘ ↘ + S ⟶ T + ↗ ↗ +X ⟶ Z +``` +-/ +abbrev weakPullback.map {W X Y Z S T : C} (f₁ : W ⟶ S) (f₂ : X ⟶ S) [HasWeakPullback f₁ f₂] + (g₁ : Y ⟶ T) (g₂ : Z ⟶ T) [HasWeakPullback g₁ g₂] (i₁ : W ⟶ Y) (i₂ : X ⟶ Z) (i₃ : S ⟶ T) + (eq₁ : f₁ ≫ i₃ = i₁ ≫ g₁) (eq₂ : f₂ ≫ i₃ = i₂ ≫ g₂) : + weakPullback f₁ f₂ ⟶ weakPullback g₁ g₂ := + weakPullback.lift (weakPullback.fst f₁ f₂ ≫ i₁) (weakPullback.snd f₁ f₂ ≫ i₂) + (by simp only [Category.assoc, ← eq₁, ← eq₂, weakPullback.condition_assoc]) + +/-- A morphism from the weak pullback of `W ⟶ S` and `X ⟶ S` to the weak pullback of +`Y ⟶ T` and `Z ⟶ T` given `S ⟶ T`. -/ +abbrev weakPullback.mapDesc {X Y S T : C} (f : X ⟶ S) (g : Y ⟶ S) (i : S ⟶ T) [HasWeakPullback f g] + [HasWeakPullback (f ≫ i) (g ≫ i)] : weakPullback f g ⟶ weakPullback (f ≫ i) (g ≫ i) := + weakPullback.map f g (f ≫ i) (g ≫ i) (𝟙 _) (𝟙 _) i (Category.id_comp _).symm + (Category.id_comp _).symm + +namespace PullbackCone + +variable {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} + +/-- This is a slightly more convenient method to verify that a pullback cone is a weak limit cone. +It only asks for a proof of facts that carry any mathematical content -/ +def isWeakLimitAux (t : PullbackCone f g) (lift : ∀ s : PullbackCone f g, s.pt ⟶ t.pt) + (fac_left : ∀ s : PullbackCone f g, lift s ≫ t.fst = s.fst) + (fac_right : ∀ s : PullbackCone f g, lift s ≫ t.snd = s.snd) : IsWeakLimit t := + { lift + fac := fun s j => Option.casesOn j (by + rw [← s.w WalkingCospan.Hom.inl, ← t.w WalkingCospan.Hom.inl, ← Category.assoc] + congr + exact fac_left s) + fun j' => WalkingPair.casesOn j' (fac_left s) (fac_right s)} + +/-- This is another convenient method to verify that a pullback cone is a weak limit cone. It +only asks for a proof of facts that carry any mathematical content, and allows access to the +same `s` for all parts. -/ +def isWeakLimitAux' (t : PullbackCone f g) + (create : + ∀ s : PullbackCone f g, { l // l ≫ t.fst = s.fst ∧ l ≫ t.snd = s.snd}) : + Limits.IsWeakLimit t := + PullbackCone.isWeakLimitAux t (fun s => (create s).1) + (fun s => (create s).2.1) (fun s => (create s).2.2) + +/-- This is a more convenient formulation to show that a `PullbackCone` constructed using +`PullbackCone.mk` is a weak limit cone. +-/ +def IsWeakLimit.mk {W : C} {fst : W ⟶ X} {snd : W ⟶ Y} (eq : fst ≫ f = snd ≫ g) + (lift : ∀ s : PullbackCone f g, s.pt ⟶ W) + (fac_left : ∀ s : PullbackCone f g, lift s ≫ fst = s.fst) + (fac_right : ∀ s : PullbackCone f g, lift s ≫ snd = s.snd) : + IsWeakLimit (PullbackCone.mk fst snd eq) := + isWeakLimitAux _ lift fac_left fac_right + +/-- If `t` is a weak limit pullback cone over `f` and `g` and `h : W ⟶ X` and `k : W ⟶ Y` are such +that `h ≫ f = k ≫ g`, then we get `l : W ⟶ t.pt`, which satisfies `l ≫ fst t = h` +and `l ≫ snd t = k`, see `IsWeakLimit.lift_fst` and `IsWeakLimit.lift_snd`. -/ +def IsWeakLimit.lift {t : PullbackCone f g} (ht : IsWeakLimit t) {W : C} (h : W ⟶ X) (k : W ⟶ Y) + (w : h ≫ f = k ≫ g) : W ⟶ t.pt := + ht.lift <| PullbackCone.mk _ _ w + +@[reassoc (attr := simp)] +lemma IsWeakLimit.lift_fst {t : PullbackCone f g} (ht : IsWeakLimit t) {W : C} (h : W ⟶ X) + (k : W ⟶ Y) (w : h ≫ f = k ≫ g) : IsWeakLimit.lift ht h k w ≫ PullbackCone.fst t = h := + ht.fac _ _ + +@[reassoc (attr := simp)] +lemma IsWeakLimit.lift_snd {t : PullbackCone f g} (ht : IsWeakLimit t) {W : C} (h : W ⟶ X) + (k : W ⟶ Y) (w : h ≫ f = k ≫ g) : IsWeakLimit.lift ht h k w ≫ PullbackCone.snd t = k := + ht.fac _ _ + +/-- If `t` is a weak limit pullback cone over `f` and `g` and `h : W ⟶ X` and `k : W ⟶ Y` are such +that `h ≫ f = k ≫ g`, then we have `l : W ⟶ t.pt` satisfying `l ≫ fst t = h` and `l ≫ snd t = k`. +-/ +def IsWeakLimit.lift' {t : PullbackCone f g} (ht : IsWeakLimit t) {W : C} (h : W ⟶ X) (k : W ⟶ Y) + (w : h ≫ f = k ≫ g) : + { l : W ⟶ t.pt // l ≫ PullbackCone.fst t = h ∧ l ≫ PullbackCone.snd t = k } := + ⟨IsWeakLimit.lift ht h k w, by simp⟩ + +/-- The pullback cone reconstructed using `PullbackCone.mk` from a pullback cone that is a +weak limit, is also a weak limit. -/ +def mkSelfIsWeakLimit {t : PullbackCone f g} (ht : IsWeakLimit t) : + IsWeakLimit (PullbackCone.mk t.fst t.snd t.condition) := + IsWeakLimit.ofIsoWeakLimit ht (PullbackCone.eta t) + +end PullbackCone + +/-- The weak pullback cone built from the weak pullback projections is a weak pullback. -/ +def weakPullbackIsWeakPullback {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakPullback f g] : + IsWeakLimit (PullbackCone.mk (weakPullback.fst f g) (weakPullback.snd f g) + weakPullback.condition) := + PullbackCone.mkSelfIsWeakLimit <| weakPullback.isWeakLimit f g + +variable (C) + +/-- A category `HasPullbacks` if it has all weak limits of shape `WalkingCospan`, i.e. if it +has a weak pullback for every pair of morphisms with the same codomain. -/ +abbrev HasWeakPullbacks := + HasWeakLimitsOfShape WalkingCospan C + +instance (priority := 100) HasWeakPullbacksOfHasPullbacks [HasPullbacks C] : + HasWeakPullbacks C where + +variable (f : X ⟶ Z) (g : Y ⟶ Z) + +set_option backward.isDefEq.respectTransparency false in +/-- If the product `X ⨯ Y` and the weak equalizer of `π₁ ≫ f` and `π₂ ≫ g` exist, then the +weak pullback of `f` and `g` exists: it is given by composing the equalizer with the projections. -/ +theorem hasWeakLimit_cospan_of_hasLimit_pair_of_hasWeakLimit_parallelPair [HasLimit (pair X Y)] + [HasWeakLimit (parallelPair (prod.fst ≫ f) (prod.snd ≫ g))] : HasWeakLimit (cospan f g) := + HasWeakLimit.mk + { cone := + PullbackCone.mk (weakEqualizer.ι (prod.fst ≫ f) (prod.snd ≫ g) ≫ prod.fst) + (weakEqualizer.ι _ _ ≫ prod.snd) <| by + rw [Category.assoc, weakEqualizer.condition] + simp + isWeakLimit := + PullbackCone.IsWeakLimit.mk _ (fun s ↦ weakEqualizer.lift + (prod.lift (s.π.app .left) (s.π.app .right)) <| by + simp [limit.lift_π_assoc, PullbackCone.condition]) + (by simp) (by simp) } + +attribute [local instance] hasWeakLimit_cospan_of_hasLimit_pair_of_hasWeakLimit_parallelPair in +/-- If a category has all binary products and all weak equalizers, then it also has all +weak pullbacks. As usual, this is not an instance, since there may be a more direct way to +construct weak pullbacks. -/ +theorem hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakKernels + [HasBinaryProducts C] [HasWeakEqualizers C] : HasWeakPullbacks C where + hasWeakLimit F := hasWeakLimit_of_iso (diagramIsoCospan F).symm + +end CategoryTheory.Limits diff --git a/docs/references.bib b/docs/references.bib index dc0ca63035b90c..10a72574e5e57c 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -2159,6 +2159,17 @@ @Book{ freyd1964abelian publisher = {Harper \& Row New York} } +@Misc{ freyd1966repabelian, + author = {Freyd, P.}, + title = {Representations in {Abelian} categories}, + year = {1966}, + language = {English}, + howpublished = {Proc. {Conf}. {Categor}. {Algebra}, {La} {Jolla} 1965, + 95-120 (1966).}, + zbmath = {3321315}, + zbl = {0202.32402} +} + @Book{ friedmanscarr2005, author = {Yaakov {Friedman}}, title = {{Physical applications of homogeneous balls. With the From dc54c8994cfb03acc2755a9ff00bb6b46f71cb13 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:18:51 +0000 Subject: [PATCH 0519/1300] chore(NumberTheory/NumberField/Units/Basic): use `Nat.card` instead of `Fintype.card` (#41210) This PR switches `NumberTheory/NumberField/Units/Basic.lean` and some downstream files from `Fintype.card` to `Nat.card`. Co-authored-by: tb65536 --- .../Cyclotomic/CyclotomicCharacter.lean | 36 ++++++++++--------- Mathlib/NumberTheory/NumberField/CMField.lean | 3 +- .../CanonicalEmbedding/FundamentalCone.lean | 4 +-- .../NumberField/Cyclotomic/Basic.lean | 4 +-- .../NumberTheory/NumberField/Ideal/Basic.lean | 2 +- .../NumberTheory/NumberField/Units/Basic.lean | 29 +++++++-------- Mathlib/RingTheory/RootsOfUnity/Basic.lean | 11 +++--- Mathlib/RingTheory/RootsOfUnity/Complex.lean | 2 +- .../RootsOfUnity/EnoughRootsOfUnity.lean | 2 +- .../RootsOfUnity/PrimitiveRoots.lean | 28 +++++---------- Mathlib/RingTheory/ZMod/Torsion.lean | 1 - 11 files changed, 56 insertions(+), 66 deletions(-) diff --git a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean index cd69509024e11b..7718d034225e03 100644 --- a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean +++ b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean @@ -121,7 +121,7 @@ theorem modularCyclotomicCharacter.pow_dvd_aux_pow_sub_aux_pow `modularCyclotomicCharacter.toFun n g` is the `j : ZMod d` such that `g(ζ)=ζ^j` for all `n`-th roots of unity. Here `d` is the number of `n`th roots of unity in `L`. -/ noncomputable def modularCyclotomicCharacter.toFun (n : ℕ) [NeZero n] (g : L ≃+* L) : - ZMod (Fintype.card (rootsOfUnity n L)) := + ZMod (Nat.card (rootsOfUnity n L)) := modularCyclotomicCharacter.aux g n namespace modularCyclotomicCharacter @@ -131,10 +131,11 @@ local notation "χ₀" => modularCyclotomicCharacter.toFun /-- The formula which characterises the output of `modularCyclotomicCharacter g n`. -/ theorem toFun_spec (g : L ≃+* L) {n : ℕ} [NeZero n] (t : rootsOfUnity n L) : g (t : Lˣ) = (t ^ (χ₀ n g).val : Lˣ) := by + have : NeZero (Nat.card (rootsOfUnity n L)) := ⟨Nat.card_pos.ne'⟩ rw [modularCyclotomicCharacter.aux_spec g n t, ← zpow_natCast, modularCyclotomicCharacter.toFun, ZMod.val_intCast, ← Subgroup.coe_zpow] exact Units.ext_iff.1 <| SetCoe.ext_iff.2 <| - zpow_eq_zpow_emod _ pow_card_eq_one (G := rootsOfUnity n L) + zpow_eq_zpow_emod _ pow_card_eq_one' (G := rootsOfUnity n L) theorem toFun_spec' (g : L ≃+* L) {n : ℕ} [NeZero n] {t : Lˣ} (ht : t ∈ rootsOfUnity n L) : g t = t ^ (χ₀ n g).val := @@ -145,29 +146,30 @@ theorem toFun_spec'' (g : L ≃+* L) {n : ℕ} [NeZero n] {t : L} (ht : IsPrimit toFun_spec' g (SetLike.coe_mem ht.toRootsOfUnity) /-- If g(t)=t^c for all roots of unity, then c=χ(g). -/ -theorem toFun_unique (g : L ≃+* L) (c : ZMod (Fintype.card (rootsOfUnity n L))) +theorem toFun_unique (g : L ≃+* L) (c : ZMod (Nat.card (rootsOfUnity n L))) (hc : ∀ t : rootsOfUnity n L, g (t : Lˣ) = (t ^ c.val : Lˣ)) : c = χ₀ n g := by - apply IsCyclic.ext Nat.card_eq_fintype_card (fun ζ ↦ ?_) + apply IsCyclic.ext rfl (fun ζ ↦ ?_) specialize hc ζ suffices ((ζ ^ c.val : Lˣ) : L) = (ζ ^ (χ₀ n g).val : Lˣ) by exact_mod_cast this rw [← toFun_spec g ζ, hc] -theorem toFun_unique' (g : L ≃+* L) (c : ZMod (Fintype.card (rootsOfUnity n L))) +theorem toFun_unique' (g : L ≃+* L) (c : ZMod (Nat.card (rootsOfUnity n L))) (hc : ∀ t ∈ rootsOfUnity n L, g t = t ^ c.val) : c = χ₀ n g := toFun_unique n g c (fun ⟨_, ht⟩ ↦ hc _ ht) lemma id : χ₀ n (RingEquiv.refl L) = 1 := by refine (toFun_unique n (RingEquiv.refl L) 1 <| fun t ↦ ?_).symm - have : 1 ≤ Fintype.card { x // x ∈ rootsOfUnity n L } := Fin.size_positive' + have : 1 ≤ Nat.card { x // x ∈ rootsOfUnity n L } := Nat.card_pos obtain (h | h) := this.lt_or_eq · have := Fact.mk h simp [ZMod.val_one] - · have := Fintype.card_le_one_iff_subsingleton.mp h.ge + · have := Finite.card_le_one_iff_subsingleton.mp h.ge obtain rfl : t = 1 := Subsingleton.elim t 1 simp lemma comp (g h : L ≃+* L) : χ₀ n (g * h) = χ₀ n g * χ₀ n h := by + have : NeZero (Nat.card (rootsOfUnity n L)) := ⟨Nat.card_pos.ne'⟩ refine (toFun_unique n (g * h) _ <| fun ζ ↦ ?_).symm change g (h (ζ : Lˣ)) = _ rw [toFun_spec, ← Subgroup.coe_pow, toFun_spec, mul_comm, Subgroup.coe_pow, ← pow_mul, @@ -175,7 +177,7 @@ lemma comp (g h : L ≃+* L) : χ₀ n (g * h) = congr 2 norm_cast simp only [pow_eq_pow_iff_modEq, ← ZMod.natCast_eq_natCast_iff, - ZMod.natCast_val, Nat.cast_mul, ZMod.cast_mul (m := orderOf ζ) orderOf_dvd_card] + ZMod.natCast_val, Nat.cast_mul, ZMod.cast_mul (m := orderOf ζ) (orderOf_dvd_natCard _)] end modularCyclotomicCharacter @@ -188,18 +190,18 @@ characterised by the property that `g(ζ)=ζ^(modularCyclotomicCharacter n g)` for `g` an automorphism of `L` and `ζ` an `n`th root of unity. -/ noncomputable def modularCyclotomicCharacter' (n : ℕ) [NeZero n] : - (L ≃+* L) →* (ZMod (Fintype.card { x // x ∈ rootsOfUnity n L }))ˣ := MonoidHom.toHomUnits + (L ≃+* L) →* (ZMod (Nat.card { x // x ∈ rootsOfUnity n L }))ˣ := MonoidHom.toHomUnits { toFun := modularCyclotomicCharacter.toFun n map_one' := modularCyclotomicCharacter.id n map_mul' := modularCyclotomicCharacter.comp n } lemma modularCyclotomicCharacter'.spec' (g : L ≃+* L) {t : Lˣ} (ht : t ∈ rootsOfUnity n L) : g t = t ^ ((modularCyclotomicCharacter' L n g) : ZMod - (Fintype.card { x // x ∈ rootsOfUnity n L })).val := + (Nat.card { x // x ∈ rootsOfUnity n L })).val := modularCyclotomicCharacter.toFun_spec' g ht lemma modularCyclotomicCharacter'.unique' (g : L ≃+* L) - {c : ZMod (Fintype.card { x // x ∈ rootsOfUnity n L })} + {c : ZMod (Nat.card { x // x ∈ rootsOfUnity n L })} (hc : ∀ t ∈ rootsOfUnity n L, g t = t ^ c.val) : c = modularCyclotomicCharacter' L n g := modularCyclotomicCharacter.toFun_unique' _ _ _ hc @@ -210,14 +212,14 @@ automorphisms of `L` to `(ℤ/nℤ)ˣ`. It is uniquely characterised by the prop `g(ζ)=ζ^(modularCyclotomicCharacter n g)` for `g` an automorphism of `L` and `ζ` any `n`th root of unity. -/ noncomputable def modularCyclotomicCharacter {n : ℕ} [NeZero n] - (hn : Fintype.card { x // x ∈ rootsOfUnity n L } = n) : + (hn : Nat.card { x // x ∈ rootsOfUnity n L } = n) : (L ≃+* L) →* (ZMod n)ˣ := (Units.mapEquiv <| (ZMod.ringEquivCongr hn).toMulEquiv).toMonoidHom.comp (modularCyclotomicCharacter' L n) namespace modularCyclotomicCharacter -variable {n : ℕ} [NeZero n] (hn : Fintype.card { x // x ∈ rootsOfUnity n L } = n) +variable {n : ℕ} [NeZero n] (hn : Nat.card { x // x ∈ rootsOfUnity n L } = n) lemma spec (g : L ≃+* L) {t : Lˣ} (ht : t ∈ rootsOfUnity n L) : g t = t ^ ((modularCyclotomicCharacter L hn g) : ZMod n).val := by @@ -283,8 +285,8 @@ theorem toFun_apply : open modularCyclotomicCharacter in theorem toZModPow_toFun (n : ℕ) : (χ p g).toZModPow n = - (modularCyclotomicCharacter _ (Fintype.card_eq_nat_card.trans - (HasEnoughRootsOfUnity.natCard_rootsOfUnity L (p ^ n))) g).val := by + (modularCyclotomicCharacter _ + (HasEnoughRootsOfUnity.natCard_rootsOfUnity L (p ^ n)) g).val := by rw [toFun_apply] refine (PadicInt.toZModPow_ofIntSeq_of_pow_dvd_sub (aux g <| p ^ ·) _ (fun i ↦ pow_dvd_aux_pow_sub_aux_pow g p i.le_succ) n).trans ?_ @@ -328,8 +330,8 @@ theorem cyclotomicCharacter.spec (p : ℕ) [Fact p.Prime] {n : ℕ} theorem cyclotomicCharacter.toZModPow (p : ℕ) [Fact p.Prime] {n : ℕ} [∀ i, HasEnoughRootsOfUnity L (p ^ i)] (g : L ≃+* L) : (cyclotomicCharacter L p g).val.toZModPow n = - (modularCyclotomicCharacter _ (Fintype.card_eq_nat_card.trans - (HasEnoughRootsOfUnity.natCard_rootsOfUnity L (p ^ n))) g).val := + (modularCyclotomicCharacter _ + (HasEnoughRootsOfUnity.natCard_rootsOfUnity L (p ^ n)) g).val := toZModPow_toFun _ _ _ open IntermediateField in diff --git a/Mathlib/NumberTheory/NumberField/CMField.lean b/Mathlib/NumberTheory/NumberField/CMField.lean index 28a239a583205c..2e648b6a6623ec 100644 --- a/Mathlib/NumberTheory/NumberField/CMField.lean +++ b/Mathlib/NumberTheory/NumberField/CMField.lean @@ -349,7 +349,7 @@ theorem index_unitsMulComplexConjInv_range_dvd : refine this ▸ Subgroup.index_dvd_of_le ?_ rintro _ ⟨ζ, _, rfl⟩ exact ⟨ζ, Subtype.ext_iff.mpr (by simp [pow_two])⟩ - rw [IsCyclic.index_powMonoidHom_range, Nat.gcd_eq_right_iff_dvd, Nat.card_eq_fintype_card] + rw [IsCyclic.index_powMonoidHom_range, Nat.gcd_eq_right_iff_dvd] exact Even.two_dvd <| even_torsionOrder K /-- @@ -364,7 +364,6 @@ theorem indexRealUnits_mul_eq : convert! (Subgroup.index_map (torsion K) (unitsMulComplexConjInv K)).symm · rw [unitsMulComplexConjInv_ker] · rw [map_unitsMulComplexConjInv_torsion, IsCyclic.index_powMonoidHom_range, Nat.gcd_eq_right] - rw [Nat.card_eq_fintype_card] exact even_iff_two_dvd.mp (even_torsionOrder K) /-- diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean index 61cbe0591ffcd4..0d867ec9dcca5a 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean @@ -470,7 +470,7 @@ theorem card_isPrincipal_norm_eq_mul_torsion (n : ℕ) : Nat.card {I : (Ideal (𝓞 K))⁰ | IsPrincipal (I : Ideal (𝓞 K)) ∧ absNorm (I : Ideal (𝓞 K)) = n} * torsionOrder K = Nat.card {a : integerSet K | mixedEmbedding.norm (a : mixedSpace K) = n} := by - rw [torsionOrder, ← Nat.card_eq_fintype_card, ← Nat.card_prod] + rw [torsionOrder, ← Nat.card_prod] exact Nat.card_congr (integerSetEquivNorm K n).symm variable (J : (Ideal (𝓞 K))⁰) @@ -578,7 +578,7 @@ theorem card_isPrincipal_dvd_norm_le (s : ℝ) : Nat.card {a : idealSet K J // mixedEmbedding.norm (a : mixedSpace K) ≤ s} := by obtain hs | hs := le_or_gt 0 s · simp_rw [← intNorm_idealSetEquiv_apply, ← Nat.le_floor_iff hs] - rw [torsionOrder, ← Nat.card_eq_fintype_card, ← Nat.card_prod] + rw [torsionOrder, ← Nat.card_prod] refine Nat.card_congr <| @Equiv.ofFiberEquiv _ (γ := Finset.Iic ⌊s⌋₊) _ (fun I ↦ ⟨absNorm I.1.val.1, Finset.mem_Iic.mpr I.1.prop.2.2⟩) (fun a ↦ ⟨intNorm (idealSetEquiv K J a.1).1, Finset.mem_Iic.mpr a.prop⟩) fun ⟨i, hi⟩ ↦ ?_ diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index 143a86b664bc52..bbe59167a2159f 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -902,9 +902,8 @@ section NumberField open Units -theorem NumberField.Units.dvd_torsionOrder_of_isPrimitiveRoot [NeZero n] [NumberField K] {ζ : K} +theorem NumberField.Units.dvd_torsionOrder_of_isPrimitiveRoot [NeZero n] {ζ : K} (hζ : IsPrimitiveRoot ζ n) : n ∣ torsionOrder K := by - rw [torsionOrder, Fintype.card_eq_nat_card] replace hζ := (hζ.toInteger_isPrimitiveRoot).isUnit_unit (NeZero.ne n) convert! orderOf_dvd_natCard (⟨(hζ.isUnit (NeZero.ne n)).unit, ?_⟩ : torsion K) · rw [Subgroup.orderOf_mk] @@ -923,7 +922,6 @@ theorem IsCyclotomicExtension.Rat.torsionOrder_eq [NeZero n] [NumberField K] have hζ := hK.zeta_spec -- We first prove that `K` contains a primitive root of order `torsionOrder K` obtain ⟨μ, hμ⟩ : ∃ μ : torsion K, orderOf μ = torsionOrder K := by - rw [torsionOrder, Fintype.card_eq_nat_card] exact IsCyclic.exists_ofOrder_eq_natCard rw [← IsPrimitiveRoot.iff_orderOf, ← IsPrimitiveRoot.coe_submonoidClass_iff, ← IsPrimitiveRoot.coe_units_iff] at hμ diff --git a/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean b/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean index bfc25c1c16882b..885aaaba9c7c07 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean @@ -114,7 +114,7 @@ theorem NumberField.torsionOrder_dvd_absNorm_sub_one {P : Ideal (𝓞 K)} (hP₀ let _ := Ideal.Quotient.field P have hP₃ : absNorm P ≠ 1 := absNorm_eq_one_iff.not.mpr <| IsPrime.ne_top hP₁ have h := Subgroup.card_dvd_of_injective _ (torsionMapQuot_injective hP₃ hP₂) - rwa [Nat.card_eq_fintype_card, Nat.card_units] at h + rwa [Nat.card_units] at h end torsionMapQuot diff --git a/Mathlib/NumberTheory/NumberField/Units/Basic.lean b/Mathlib/NumberTheory/NumberField/Units/Basic.lean index 6a8326e2412435..29c9a43acfd3ea 100644 --- a/Mathlib/NumberTheory/NumberField/Units/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Units/Basic.lean @@ -159,8 +159,7 @@ theorem mem_torsion {x : (𝓞 K)ˣ} : NumberField.RingOfIntegers.coe_eq_algebraMap, coe_one]⟩ /-- The torsion subgroup is finite. -/ -instance : Fintype (torsion K) := by - refine @Fintype.ofFinite _ (Set.finite_coe_iff.mpr ?_) +instance : Finite (torsion K) := by refine Set.Finite.of_finite_image ?_ (coe_injective K).injOn refine (Embeddings.finite_of_norm_le K ℂ 1).subset (fun a ⟨u, ⟨h_tors, h_ua⟩⟩ => ⟨?_, fun φ => ?_⟩) @@ -173,17 +172,18 @@ instance : Fintype (torsion K) := by instance : IsCyclic (torsion K) := isCyclic_subgroup_units _ /-- The order of the torsion subgroup. -/ -def torsionOrder : ℕ := Fintype.card (torsion K) +def torsionOrder : ℕ := Nat.card (torsion K) -instance : NeZero (torsionOrder K) := - inferInstanceAs (NeZero (Fintype.card (torsion K))) +theorem torsionOrder_pos : 0 < torsionOrder K := + Nat.card_pos -theorem torsionOrder_ne_zero : - torsionOrder K ≠ 0 := NeZero.ne (torsionOrder K) +theorem torsionOrder_ne_zero : torsionOrder K ≠ 0 := + (torsionOrder_pos K).ne' -theorem torsionOrder_pos : - 0 < torsionOrder K := Nat.pos_of_neZero (torsionOrder K) +instance : NeZero (torsionOrder K) := + ⟨torsionOrder_ne_zero K⟩ +omit [NumberField K] in /-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of order dividing `k`. -/ theorem rootsOfUnity_eq_one {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K)) @@ -196,7 +196,7 @@ theorem rootsOfUnity_eq_one {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K)) rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one] exact ⟨k, k.prop, h⟩ rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)] - exact orderOf_dvd_card + apply orderOf_dvd_natCard /-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion group. -/ @@ -207,7 +207,7 @@ theorem rootsOfUnity_eq_torsion : refine ⟨fun h => ?_, fun h => ?_⟩ · rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one] exact ⟨torsionOrder K, torsionOrder_pos K, h⟩ - · exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ _ ⟨ζ, h⟩) + · exact Subtype.ext_iff.mp (@pow_card_eq_one' (torsion K) _ ⟨ζ, h⟩) /-- The image of `torsion K` by a complex embedding is the group of complex roots of unity of @@ -220,14 +220,13 @@ theorem map_complexEmbedding_torsion (φ : K →+* ℂ) : exact map_rootsOfUnity _ (torsionOrder K) · let e := ((torsion K).equivMapOfInjective (Units.complexEmbedding φ) (Units.complexEmbedding_injective φ)).symm.toEquiv - rw [Nat.card_eq_fintype_card, Complex.card_rootsOfUnity, Nat.card_congr e, torsionOrder, - Nat.card_eq_fintype_card] + rw [Complex.card_rootsOfUnity, Nat.card_congr e, torsionOrder] theorem even_torsionOrder : Even (torsionOrder K) := by suffices orderOf (⟨-1, neg_one_mem_torsion⟩ : torsion K) = 2 by rw [even_iff_two_dvd, ← this] - exact orderOf_dvd_card + apply orderOf_dvd_natCard rw [← Subgroup.orderOf_coe, ← orderOf_units, Units.val_neg, val_one, orderOf_neg_one, ringChar.eq_zero, if_neg (by decide)] @@ -251,6 +250,8 @@ theorem torsion_eq_one_or_neg_one_of_odd_finrank theorem torsionOrder_eq_two_of_odd_finrank (h : Odd (Module.finrank ℚ K)) : torsionOrder K = 2 := by classical + let := Fintype.ofFinite (torsion K) + rw [torsionOrder, Nat.card_eq_fintype_card] refine (Finset.card_eq_two.2 ⟨1, ⟨-1, neg_one_mem_torsion⟩, by simp [← Subtype.coe_ne_coe], Finset.ext fun x ↦ ⟨fun _ ↦ ?_, fun _ ↦ Finset.mem_univ _⟩⟩) rw [Finset.mem_insert, Finset.mem_singleton, ← Subtype.val_inj, ← Subtype.val_inj] diff --git a/Mathlib/RingTheory/RootsOfUnity/Basic.lean b/Mathlib/RingTheory/RootsOfUnity/Basic.lean index df52d96eddf247..cd6d861a10e498 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Basic.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Basic.lean @@ -242,18 +242,19 @@ theorem rootsOfUnityEquivNthRoots_symm_apply (x : { x // x ∈ nthRoots k (1 : R variable (k R) -instance rootsOfUnity.fintype : Fintype (rootsOfUnity k R) := by +instance : Finite (rootsOfUnity k R) := by classical - exact Fintype.ofEquiv { x // x ∈ nthRoots k (1 : R) } (rootsOfUnityEquivNthRoots R k).symm + exact .of_equiv { x // x ∈ nthRoots k (1 : R) } (rootsOfUnityEquivNthRoots R k).symm instance rootsOfUnity.isCyclic : IsCyclic (rootsOfUnity k R) := isCyclic_of_injective_ringHom ((Units.coeHom R).comp (rootsOfUnity k R).subtype) coe_injective -theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k := by +theorem card_rootsOfUnity : Nat.card (rootsOfUnity k R) ≤ k := by classical calc - Fintype.card (rootsOfUnity k R) = Fintype.card { x // x ∈ nthRoots k (1 : R) } := - Fintype.card_congr (rootsOfUnityEquivNthRoots R k) + Nat.card (rootsOfUnity k R) = Nat.card { x // x ∈ nthRoots k (1 : R) } := + Nat.card_congr (rootsOfUnityEquivNthRoots R k) + _ = Fintype.card { x // x ∈ nthRoots k (1 : R) } := Nat.card_eq_fintype_card _ ≤ Multiset.card (nthRoots k (1 : R)).attach := Multiset.card_le_card (Multiset.dedup_le _) _ = Multiset.card (nthRoots k (1 : R)) := Multiset.card_attach _ ≤ k := card_nthRoots k 1 diff --git a/Mathlib/RingTheory/RootsOfUnity/Complex.lean b/Mathlib/RingTheory/RootsOfUnity/Complex.lean index f982dac2e96d73..aec808d1ed3b3b 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Complex.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Complex.lean @@ -119,7 +119,7 @@ nonrec theorem mem_rootsOfUnity (n : ℕ) [NeZero n] (x : Units ℂ) : use i simp [field] -theorem card_rootsOfUnity (n : ℕ) [NeZero n] : Fintype.card (rootsOfUnity n ℂ) = n := +theorem card_rootsOfUnity (n : ℕ) [NeZero n] : Nat.card (rootsOfUnity n ℂ) = n := (isPrimitiveRoot_exp n NeZero.out).card_rootsOfUnity theorem card_primitiveRoots (k : ℕ) : (primitiveRoots k ℂ).card = φ k := by diff --git a/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean b/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean index 2def918eb743b2..d4ca6499816676 100644 --- a/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean +++ b/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean @@ -80,7 +80,7 @@ lemma natCard_rootsOfUnity (M : Type*) [CommMonoid M] (n : ℕ) [NeZero n] rw [← Units.val_inj, Units.val_pow_eq_pow_val, IsUnit.unit_spec, h.pow_eq_one, Units.val_one] lemma of_card_le {R : Type*} [CommRing R] [IsDomain R] {n : ℕ} [NeZero n] - (h : n ≤ Fintype.card (rootsOfUnity n R)) : HasEnoughRootsOfUnity R n where + (h : n ≤ Nat.card (rootsOfUnity n R)) : HasEnoughRootsOfUnity R n where prim := card_rootsOfUnity_eq_iff_exists_isPrimitiveRoot.mp (le_antisymm (card_rootsOfUnity R n) h) cyc := rootsOfUnity.isCyclic R n diff --git a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean index be1a3f7a9616f5..7195f3618a935e 100644 --- a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean +++ b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean @@ -514,15 +514,11 @@ variable [IsDomain R] theorem zpowers_eq {k : ℕ} [NeZero k] {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) : Subgroup.zpowers ζ = rootsOfUnity k R := by - apply SetLike.coe_injective - have F : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ h.zmodEquivZPowers.toEquiv - refine - @Set.eq_of_subset_of_card_le Rˣ _ _ F (rootsOfUnity.fintype R k) - (Subgroup.zpowers_le_of_mem <| show ζ ∈ rootsOfUnity k R from h.pow_eq_one) ?_ + apply Subgroup.eq_of_le_of_card_ge (Subgroup.zpowers_le_of_mem h.pow_eq_one) calc - Fintype.card (rootsOfUnity k R) ≤ k := card_rootsOfUnity R k - _ = Fintype.card (ZMod k) := (ZMod.card k).symm - _ = Fintype.card (Subgroup.zpowers ζ) := Fintype.card_congr h.zmodEquivZPowers.toEquiv + Nat.card (rootsOfUnity k R) ≤ k := card_rootsOfUnity R k + _ = Nat.card (ZMod k) := (Nat.card_zmod k).symm + _ = Nat.card (Subgroup.zpowers ζ) := Nat.card_congr h.zmodEquivZPowers.toEquiv lemma map_rootsOfUnity {S F} [CommRing S] [IsDomain S] [FunLike F R S] [MonoidHomClass F R S] {ζ : R} {n : ℕ} [NeZero n] (hζ : IsPrimitiveRoot ζ n) {f : F} (hf : Function.Injective f) : @@ -646,26 +642,20 @@ theorem card_nthRoots {n : ℕ} {ζ : R} (hζ : IsPrimitiveRoot ζ n) (a : R) : /-- A variant of `IsPrimitiveRoot.card_rootsOfUnity` for `ζ : Rˣ`. -/ theorem card_rootsOfUnity' {n : ℕ} [NeZero n] (h : IsPrimitiveRoot ζ n) : - Fintype.card (rootsOfUnity n R) = n := by - let e := h.zmodEquivZPowers - have : Fintype (Subgroup.zpowers ζ) := Fintype.ofEquiv _ e.toEquiv - calc - Fintype.card (rootsOfUnity n R) = Fintype.card (Subgroup.zpowers ζ) := - Fintype.card_congr <| by rw [h.zpowers_eq] - _ = Fintype.card (ZMod n) := Fintype.card_congr e.toEquiv.symm - _ = n := ZMod.card n + Nat.card (rootsOfUnity n R) = n := by + rw [← h.zpowers_eq, Nat.card_zpowers, h.eq_orderOf] theorem card_rootsOfUnity {ζ : R} {n : ℕ} [NeZero n] (h : IsPrimitiveRoot ζ n) : - Fintype.card (rootsOfUnity n R) = n := by + Nat.card (rootsOfUnity n R) = n := by obtain ⟨ζ, hζ⟩ := h.isUnit NeZero.out rw [← hζ, IsPrimitiveRoot.coe_units_iff] at h exact h.card_rootsOfUnity' lemma _root_.card_rootsOfUnity_eq_iff_exists_isPrimitiveRoot {n : ℕ} [NeZero n] : - Fintype.card (rootsOfUnity n R) = n ↔ ∃ ζ : R, IsPrimitiveRoot ζ n := by + Nat.card (rootsOfUnity n R) = n ↔ ∃ ζ : R, IsPrimitiveRoot ζ n := by refine ⟨fun h ↦ ?_, fun ⟨ζ, hζ⟩ ↦ hζ.card_rootsOfUnity⟩ obtain ⟨⟨ζ, hζ'⟩, hζ⟩ := (rootsOfUnity.isCyclic R n).exists_ofOrder_eq_natCard - rw [Nat.card_eq_fintype_card, h, ← IsPrimitiveRoot.iff_orderOf, ← coe_submonoidClass_iff, + rw [h, ← IsPrimitiveRoot.iff_orderOf, ← coe_submonoidClass_iff, ← IsPrimitiveRoot.coe_units_iff] at hζ use ζ diff --git a/Mathlib/RingTheory/ZMod/Torsion.lean b/Mathlib/RingTheory/ZMod/Torsion.lean index 88361d25c8bd28..04cac9f1a5b4f4 100644 --- a/Mathlib/RingTheory/ZMod/Torsion.lean +++ b/Mathlib/RingTheory/ZMod/Torsion.lean @@ -28,7 +28,6 @@ instance {p : ℕ} [Fact p.Prime] : HasEnoughRootsOfUnity (ZMod p) (p - 1) := by have : NeZero (p - 1) := ⟨by have : 2 ≤ p := Nat.Prime.two_le Fact.out; grind⟩ refine HasEnoughRootsOfUnity.of_card_le ?_ have := Nat.card_congr (MulEquiv.subgroupCongr (ZMod.rootsOfUnity_eq_top (p := p))).toEquiv - rw [Nat.card_eq_fintype_card] at this rw [this] simp [Fintype.card_units] From 786a9864a453a3d1d100a4eead3630f9871b0825 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:55:19 +0000 Subject: [PATCH 0520/1300] chore(CategoryTheory/Preadditive/LeftExact): fix doc strings (#41237) Fix insufficiently dualized doc strings. --- Mathlib/CategoryTheory/Preadditive/LeftExact.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean index 7eef13254cee94..a601510f6b4612 100644 --- a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean +++ b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean @@ -17,7 +17,7 @@ preserves kernels. The dual result holds for right exact functors and cokernels. ## Main results -* We first derive preservation of binary product in the lemma +* We first derive preservation of binary products in the lemma `preservesBinaryProductsOfPreservesKernels`, * then show the preservation of equalizers in `preservesEqualizerOfPreservesKernels`, * and then derive the preservation of all finite limits with the usual construction. @@ -187,8 +187,8 @@ lemma preservesCoequalizer_of_preservesCokernels (isColimitCoforkOfCokernelCofork ((IsColimit.precomposeHomEquiv p.symm _).symm iFc)) (Cofork.ext (Iso.refl _) (by simp [p])) -/-- A functor between preadditive categories preserves all coequalizers if it preserves all kernels. --/ +/-- A functor between preadditive categories preserves all coequalizers if it preserves all +cokernels. -/ lemma preservesCoequalizers_of_preservesCokernels [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesColimitsOfShape WalkingParallelPair F where @@ -197,8 +197,8 @@ lemma preservesCoequalizers_of_preservesCokernels (K.map Limits.WalkingParallelPairHom.right) apply preservesColimit_of_iso_diagram F (diagramIsoParallelPair K).symm -/-- A functor between preadditive categories which preserves kernels preserves all finite limits. --/ +/-- A functor between preadditive categories which preserves cokernels preserves all finite +colimits. -/ lemma preservesFiniteColimits_of_preservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C] [HasZeroObject C] [HasZeroObject D] [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by From 25ba496717dd75b80778088457c0954275e9eef4 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 1 Jul 2026 14:15:11 +0000 Subject: [PATCH 0521/1300] chore(RingTheory/RamificationInertia/RamificationIdx): swap primes on `ramificationIdx` and `ramificationIdx'` (#41234) There's still a bit of work left to do, but I think now is a reasonable time to swap which of `ramificationIdx` and `ramificationIdx'` is primed. Co-authored-by: tb65536 --- .../NumberField/Cyclotomic/Ideal.lean | 14 +- .../NumberField/ExistsRamified.lean | 4 +- .../NumberField/Ideal/KummerDedekind.lean | 6 +- .../RamificationInertia/Basic.lean | 40 +-- .../RamificationInertia/Galois.lean | 12 +- .../RamificationInertia/HilbertTheory.lean | 8 +- .../RamificationInertia/Ramification.lean | 245 +++++++++++------- .../RamificationInertia/Unramified.lean | 20 +- .../RamificationInertia/Valuation.lean | 13 +- .../RingTheory/DedekindDomain/Different.lean | 6 +- .../DedekindDomain/Factorization.lean | 4 +- Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 2 +- .../Localization/AtPrime/Extension.lean | 8 +- .../RingTheory/RamificationInertia/Basic.lean | 8 +- .../RamificationInertia/Ramification.lean | 163 +++++++----- 15 files changed, 325 insertions(+), 228 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index bcfd32e01331cd..1858926305d56b 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -122,11 +122,11 @@ theorem map_eq_span_zeta_sub_one_pow : ← Nat.card_eq_fintype_card, IsGalois.card_aut_eq_finrank] theorem ramificationIdx_span_zeta_sub_one : - ramificationIdx' (span {hζ.toInteger - 1}) ℤ = p ^ k * (p - 1) := by + ramificationIdx (span {hζ.toInteger - 1}) ℤ = p ^ k * (p - 1) := by have h := isPrime_span_zeta_sub_one p k hζ have hp0 : 𝒑 ≠ ⊥ := by simpa using hp.out.ne_zero rw [← Nat.totient_prime_pow_succ hp.out, ← finrank _ K, - IsDedekindDomain.ramificationIdx'_eq_multiplicity 𝒑, map_eq_span_zeta_sub_one_pow p k hζ, + IsDedekindDomain.ramificationIdx_eq_multiplicity 𝒑, map_eq_span_zeta_sub_one_pow p k hζ, multiplicity_pow_self (span_zeta_sub_one_ne_bot p k hζ) (isUnit_iff.not.mpr h.ne_top)] exact map_ne_bot_of_ne_bot hp0 @@ -161,7 +161,7 @@ theorem inertiaDeg_eq_of_prime_pow (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP include hK in theorem ramificationIdx_eq_of_prime_pow (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - ramificationIdx' P ℤ = p ^ k * (p - 1) := by + ramificationIdx P ℤ = p ^ k * (p - 1) := by rw [eq_span_zeta_sub_one_of_liesOver p k K hK.zeta_spec P, ramificationIdx_span_zeta_sub_one] include hK in @@ -233,7 +233,7 @@ theorem inertiaDeg_span_zeta_sub_one' : inertiaDeg' (span {hζ.toInteger - 1}) exact inertiaDeg_span_zeta_sub_one p 0 hζ theorem ramificationIdx_span_zeta_sub_one' : - ramificationIdx' (span {hζ.toInteger - 1}) ℤ = p - 1 := by + ramificationIdx (span {hζ.toInteger - 1}) ℤ = p - 1 := by rw [← pow_one p] at hK hζ rw [ramificationIdx_span_zeta_sub_one p 0 hζ, pow_zero, one_mul] @@ -264,7 +264,7 @@ theorem inertiaDeg_eq_of_prime (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : include hK in theorem ramificationIdx_eq_of_prime (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - ramificationIdx' P ℤ = p - 1 := by + ramificationIdx P ℤ = p - 1 := by rw [eq_span_zeta_sub_one_of_liesOver' p K hK.zeta_spec P, ramificationIdx_span_zeta_sub_one'] include hK in @@ -314,7 +314,7 @@ theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : alias inertiaDeg_of_not_dvd := inertiaDeg_eq_of_not_dvd theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : - ramificationIdx' P ℤ = 1 := by + ramificationIdx P ℤ = 1 := by let ζ := (zeta_spec m ℚ K).toInteger have h₁ : ¬ p ∣ exponent ζ := by rw [exponent_eq_one_iff.mpr <| adjoin_singleton_eq_top (zeta_spec m ℚ K)] @@ -432,7 +432,7 @@ theorem inertiaDeg_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : rw [← inertiaDegIn_eq_inertiaDeg 𝒑 P Gal(K/ℚ), inertiaDegIn_eq n K hn hm] theorem ramificationIdx_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : - ramificationIdx' P ℤ = p ^ k * (p - 1) := by + ramificationIdx P ℤ = p ^ k * (p - 1) := by have : IsGalois ℚ K := isGalois {n} ℚ K rw [← ramificationIdxIn_eq_ramificationIdx 𝒑 P Gal(K/ℚ), ramificationIdxIn_eq n K hn hm] diff --git a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean index f1c8f469117601..b811fa5699d1d3 100644 --- a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean +++ b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean @@ -84,6 +84,6 @@ lemma NumberField.exists_not_isUnramifiedAt_int_of_isGalois [IsGalois ℚ K] (map_dvd (algebraMap _ _) p.associated_natAbs.symm.dvd) (by simpa using hQ) have : .span {p} = Ideal.under ℤ Q := ((Ideal.liesOver_span_iff Ideal.IsPrime.ne_top' this).mpr hQ).1 - rwa [← Ideal.ramificationIdx'_eq_one_iff, + rwa [← Ideal.ramificationIdx_eq_one_iff, ← Ideal.ramificationIdxIn_eq_ramificationIdx (Q.under ℤ) _ Gal(K/ℚ), ← this, ← hp, - Ideal.ramificationIdxIn_eq_ramificationIdx _ P Gal(K/ℚ), Ideal.ramificationIdx'_eq_one_iff] + Ideal.ramificationIdxIn_eq_ramificationIdx _ P Gal(K/ℚ), Ideal.ramificationIdx_eq_one_iff] diff --git a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean index 2927ab9ed755d9..bc6ad76777c640 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean @@ -237,12 +237,12 @@ The ramification index of the ideal corresponding to the class of `Q ∈ ℤ[X]` -/ theorem ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ exponent θ) {Q : ℤ[X]} (hQ : Q.map (Int.castRingHom (ZMod p)) ∈ monicFactorsMod θ p) : - ramificationIdx' + ramificationIdx ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q.map (Int.castRingHom (ZMod p)), hQ⟩ : Ideal (𝓞 K)) ℤ = multiplicity (Q.map (Int.castRingHom (ZMod p))) ((minpoly ℤ θ).map (Int.castRingHom (ZMod p))) := by - rw [ramificationIdx'_eq_multiplicity (span {↑p}) _ (map_ne_bot_of_ne_bot (by simp [NeZero.ne p]))] + rw [ramificationIdx_eq_multiplicity (span {↑p}) _ (map_ne_bot_of_ne_bot (by simp [NeZero.ne p]))] · apply multiplicity_eq_of_emultiplicity_eq rw [← emultiplicity_map_eq (mapEquiv (Int.quotientSpanNatEquivZMod p).symm), emultiplicity_factors_map_eq_emultiplicity inferInstance (by simp [NeZero.ne p]) @@ -255,7 +255,7 @@ theorem ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p theorem ramificationIdx_primesOverSpanEquivMonicFactorsMod_symm_apply' (hp : ¬ p ∣ exponent θ) {Q : (ZMod p)[X]} (hQ : Q ∈ monicFactorsMod θ p) : - ramificationIdx' + ramificationIdx ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q, hQ⟩ : Ideal (𝓞 K)) ℤ = multiplicity Q ((minpoly ℤ θ).map (Int.castRingHom (ZMod p))) := by obtain ⟨S, rfl⟩ := (map_surjective _ (ZMod.ringHom_surjective (Int.castRingHom (ZMod p)))) Q diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index f6a8da54d09d38..3ff906756fa8ad 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -271,12 +271,12 @@ end FinrankQuotientMap section FactLeComap -local notation "e" => ramificationIdx p P +local notation "e" => ramificationIdx' p P /-- `R / p` has a canonical map to `S / (P ^ e)`, where `e` is the ramification index of `P` over `p`. -/ noncomputable instance Quotient.algebraQuotientPowRamificationIdx : Algebra (R ⧸ p) (S ⧸ P ^ e) := - Quotient.algebraQuotientOfLEComap (Ideal.map_le_iff_le_comap.mp le_pow_ramificationIdx) + Quotient.algebraQuotientOfLEComap (Ideal.map_le_iff_le_comap.mp le_pow_ramificationIdx') @[simp] theorem Quotient.algebraMap_quotient_pow_ramificationIdx (x : R) : @@ -289,7 +289,7 @@ This can't be an instance since the map `f : R → S` is generally not inferable @[instance_reducible] def Quotient.algebraQuotientOfRamificationIdxNeZero [hfp : NeZero e] : Algebra (R ⧸ p) (S ⧸ P) := - Quotient.algebraQuotientOfLEComap (le_comap_of_ramificationIdx_ne_zero hfp.out) + Quotient.algebraQuotientOfLEComap (le_comap_of_ramificationIdx'_ne_zero hfp.out) attribute [local instance] Ideal.Quotient.algebraQuotientOfRamificationIdxNeZero @@ -336,7 +336,7 @@ theorem quotientToQuotientRangePowQuotSuccAux_mk {i : ℕ} {a : S} (a_mem : a apply Quotient.map'_mk'' section -variable [hfp : NeZero (ramificationIdx p P)] +variable [hfp : NeZero (ramificationIdx' p P)] /-- `S ⧸ P` embeds into the quotient by `P^(i+1) ⧸ P^e` as a subspace of `P^i ⧸ P^e`. -/ noncomputable def quotientToQuotientRangePowQuotSucc @@ -502,13 +502,13 @@ instance Factors.isPrime (P : (factors (map (algebraMap R S) p)).toFinset) : open scoped Classical in theorem Factors.ramificationIdx_ne_zero (P : (factors (map (algebraMap R S) p)).toFinset) : - ramificationIdx p P.1 ≠ 0 := - IsDedekindDomain.ramificationIdx_ne_zero (ne_zero_of_mem_factors (Multiset.mem_toFinset.mp P.2)) + ramificationIdx' p P.1 ≠ 0 := + IsDedekindDomain.ramificationIdx'_ne_zero (ne_zero_of_mem_factors (Multiset.mem_toFinset.mp P.2)) (Factors.isPrime p P) (Ideal.le_of_dvd (dvd_of_mem_factors (Multiset.mem_toFinset.mp P.2))) open scoped Classical in instance Factors.fact_ramificationIdx_neZero (P : (factors (map (algebraMap R S) p)).toFinset) : - NeZero (ramificationIdx p P.1) := + NeZero (ramificationIdx' p P.1) := ⟨Factors.ramificationIdx_ne_zero p P⟩ attribute [local instance] Quotient.algebraQuotientOfRamificationIdxNeZero @@ -526,15 +526,15 @@ instance Factors.liesOver [p.IsMaximal] (P : (factors (map (algebraMap R S) p)). open scoped Classical in theorem Factors.finrank_pow_ramificationIdx [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : - finrank (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx p P.1) = - ramificationIdx p P.1 * inertiaDeg p (P : Ideal S) := by + finrank (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) = + ramificationIdx' p P.1 * inertiaDeg p (P : Ideal S) := by rw [finrank_prime_pow_ramificationIdx, inertiaDeg_algebraMap] exacts [Factors.ne_bot p P, NeZero.ne _] open scoped Classical in instance Factors.finiteDimensional_quotient_pow [Module.Finite R S] [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : - FiniteDimensional (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx p P.1) := by + FiniteDimensional (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) := by refine .of_finrank_pos ?_ rw [pos_iff_ne_zero, Factors.finrank_pow_ramificationIdx] exact mul_ne_zero (Factors.ramificationIdx_ne_zero p P) (inertiaDeg_pos p P.1).ne' @@ -547,14 +547,14 @@ factors in `S` as `∏ i, P i ^ e i`, then `S ⧸ I` factors as `Π i, R ⧸ (P noncomputable def Factors.piQuotientEquiv (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) : S ⧸ map (algebraMap R S) p ≃+* ∀ P : (factors (map (algebraMap R S) p)).toFinset, - S ⧸ (P : Ideal S) ^ ramificationIdx p P.1 := + S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1 := (IsDedekindDomain.quotientEquivPiFactors hp).trans <| @RingEquiv.piCongrRight (factors (map (algebraMap R S) p)).toFinset (fun P => S ⧸ (P : Ideal S) ^ (factors (map (algebraMap R S) p)).count (P : Ideal S)) - (fun P => S ⧸ (P : Ideal S) ^ ramificationIdx p P.1) _ _ + (fun P => S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) _ _ fun P : (factors (map (algebraMap R S) p)).toFinset => Ideal.quotEquivOfEq <| by - rw [IsDedekindDomain.ramificationIdx_eq_factors_count hp (Factors.isPrime p P) + rw [IsDedekindDomain.ramificationIdx'_eq_factors_count hp (Factors.isPrime p P) (Factors.ne_bot p P)] @[simp] @@ -575,7 +575,7 @@ then `S ⧸ I` factors `R ⧸ I`-linearly as `Π i, R ⧸ (P i ^ e i)`. -/ noncomputable def Factors.piQuotientLinearEquiv (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) : (S ⧸ map (algebraMap R S) p) ≃ₗ[R ⧸ p] ∀ P : (factors (map (algebraMap R S) p)).toFinset, - S ⧸ (P : Ideal S) ^ ramificationIdx p P.1 := + S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1 := { Factors.piQuotientEquiv p hp with map_smul' := by rintro ⟨c⟩ ⟨x⟩; ext P @@ -595,8 +595,8 @@ here `S` is a finite `R`-module (and thus `Frac(S) : Frac(R)` is a finite extens is maximal. -/ theorem sum_ramification_inertia {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : ∑ P ∈ IsDedekindDomain.primesOverFinset p S, - ramificationIdx p P * inertiaDeg p P = finrank K L := by - set e := ramificationIdx p (S := S) + ramificationIdx' p P * inertiaDeg p P = finrank K L := by + set e := ramificationIdx' p (S := S) calc ∑ P ∈ (factors (map (algebraMap R S) p)).toFinset, e P * inertiaDeg p P = ∑ P ∈ (factors (map (algebraMap R S) p)).toFinset.attach, @@ -622,11 +622,11 @@ theorem inertiaDeg_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaxima (IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mpr ⟨hP₁, hP₂⟩ rw [← sum_ramification_inertia S K L hp0, ← Finset.add_sum_erase _ _ hP] refine le_trans (Nat.le_mul_of_pos_left _ ?_) (Nat.le_add_right _ _) - exact Nat.pos_iff_ne_zero.mpr <| IsDedekindDomain.ramificationIdx_ne_zero_of_liesOver _ hp0 + exact Nat.pos_iff_ne_zero.mpr <| IsDedekindDomain.ramificationIdx'_ne_zero_of_liesOver _ hp0 theorem ramificationIdx_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (P : Ideal S) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver p] : - p.ramificationIdx P ≤ Module.finrank K L := by + p.ramificationIdx' P ≤ Module.finrank K L := by classical by_cases hp0 : p = ⊥ · simp [hp0] @@ -643,13 +643,13 @@ theorem card_primesOverFinset_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} have : P.IsPrime := ((IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mp hP).1 have : P.LiesOver p := ((IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mp hP).2 refine Right.one_le_mul ?_ ?_ - · exact Nat.pos_iff_ne_zero.mpr <| IsDedekindDomain.ramificationIdx_ne_zero_of_liesOver _ hp0 + · exact Nat.pos_iff_ne_zero.mpr <| IsDedekindDomain.ramificationIdx'_ne_zero_of_liesOver _ hp0 · exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg_ne_zero p P /-- `Ideal.sum_ramification_inertia`, in the local (DVR) case. -/ lemma ramificationIdx_mul_inertiaDeg_of_isLocalRing [IsLocalRing S] {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : - ramificationIdx p (IsLocalRing.maximalIdeal S) * + ramificationIdx' p (IsLocalRing.maximalIdeal S) * p.inertiaDeg (IsLocalRing.maximalIdeal S) = Module.finrank K L := by have := FaithfulSMul.of_field_isFractionRing R S K L simp_rw [← sum_ramification_inertia S K L hp0, IsLocalRing.primesOverFinset_eq S hp0, diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index 467b607a9f0cca..d4ce38c6669b64 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -58,7 +58,7 @@ open scoped Classical in maximal ideal `p` of `A` are the same, which we define as `Ideal.ramificationIdxIn`. -/ noncomputable def ramificationIdxIn {A : Type*} [CommRing A] (p : Ideal A) (B : Type*) [CommRing B] [Algebra A B] : ℕ := - if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then h.choose.ramificationIdx' A + if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then h.choose.ramificationIdx A else 0 open scoped Classical in @@ -138,9 +138,9 @@ instance isPretransitive_of_isGaloisGroup : MulAction.IsPretransitive G (primesO include p G in /-- All the `Ideal.ramificationIdx` over a fixed maximal ideal are the same. -/ theorem ramificationIdx_eq_of_isGaloisGroup : - P.ramificationIdx' A = Q.ramificationIdx' A := by + P.ramificationIdx A = Q.ramificationIdx A := by rcases exists_smul_eq_of_isGaloisGroup p P Q G with ⟨σ, rfl⟩ - rw [ramificationIdx'_smul] + rw [ramificationIdx_smul] include p G in /-- All the `Ideal.inertiaDeg` over a fixed maximal ideal are the same. -/ @@ -152,7 +152,7 @@ theorem inertiaDeg_eq_of_isGaloisGroup : include p G in /-- The `ramificationIdxIn` is equal to any ramification index over the same ideal. -/ theorem ramificationIdxIn_eq_ramificationIdx : - ramificationIdxIn p B = P.ramificationIdx' A := by + ramificationIdxIn p B = P.ramificationIdx A := by have h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p := ⟨P, hPp, hp⟩ obtain ⟨_, _⟩ := h.choose_spec rw [ramificationIdxIn, dif_pos h] @@ -163,7 +163,7 @@ theorem ramificationIdxIn_ne_zero [Module.Finite A B] [FaithfulSMul A B] {p : Id p.ramificationIdxIn B ≠ 0 := by obtain ⟨P⟩ := (inferInstance : Nonempty (primesOver p B)) rw [ramificationIdxIn_eq_ramificationIdx p P G] - exact (P.1.ramificationIdx'_pos A).ne' + exact (P.1.ramificationIdx_pos A).ne' include G in /-- The `inertiaDegIn` is equal to any ramification index over the same ideal. -/ @@ -203,7 +203,7 @@ theorem ramificationIdxIn_mul_ramificationIdxIn [Flat B C] : obtain ⟨⟨Q, _, hQ⟩⟩ := (inferInstance : Nonempty (primesOver P C)) have : Q.LiesOver p := LiesOver.trans Q P p rw [ramificationIdxIn_eq_ramificationIdx p P G, ramificationIdxIn_eq_ramificationIdx p Q GAC, - ramificationIdxIn_eq_ramificationIdx P Q GBC, ← ramificationIdx'_tower P Q] + ramificationIdxIn_eq_ramificationIdx P Q GBC, ← ramificationIdx_tower P Q] @[deprecated (since := "2026-06-18")] alias ramificationIdxIn_mul_ramificationIdxIn' := ramificationIdxIn_mul_ramificationIdxIn diff --git a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean index 70c772f8186510..cd3d07a89320a5 100644 --- a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean +++ b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean @@ -294,7 +294,7 @@ private lemma ramificationIdxIn_eq_and_inertiaDegIn_eq (hp : p ≠ ⊥) : · exact Nat.pos_of_ne_zero <| inertiaDegIn_ne_zero (stabilizer Gal(L/K) P) · rw [ramificationIdxIn_eq_ramificationIdx p P Gal(L/K), ramificationIdxIn_eq_ramificationIdx _ P (stabilizer Gal(L/K) P)] - exact 𝓟D.ramificationIdx'_above_le P + exact 𝓟D.ramificationIdx_above_le P · rw [inertiaDegIn_eq_inertiaDeg p P Gal(L/K), inertiaDegIn_eq_inertiaDeg _ P (stabilizer Gal(L/K) P)] rw [← inertiaDeg_eq_inertiaDeg' p, ← inertiaDeg_eq_inertiaDeg' 𝓟D] @@ -328,12 +328,12 @@ Let `D` be the decomposition field of `P` in `L/K`. Let `𝓟D` be a prime ideal then `𝓟D` is unramified over `K`. -/ theorem ramificationIdx_eq (hp : p ≠ ⊥) : - 𝓟D.ramificationIdx' A = 1 := by + 𝓟D.ramificationIdx A = 1 := by obtain ⟨_, _, _, _, _, h𝓟⟩ := instances A K L P D 𝓞D 𝓟D hp - have := ramificationIdx'_tower (R := A) 𝓟D P + have := ramificationIdx_tower (R := A) 𝓟D P rwa [← ramificationIdxIn_eq_ramificationIdx 𝓟D P (stabilizer Gal(L/K) P), ramificationIdxIn_eq A K L P D 𝓞D 𝓟D hp, ramificationIdxIn_eq_ramificationIdx p P Gal(L/K), - right_eq_mul₀ <| (ramificationIdx'_pos P A).ne'] at this + right_eq_mul₀ <| (ramificationIdx_pos P A).ne'] at this include K L D P in /-- diff --git a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean index 7013facf35c31a..4e5a335aecebcf 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean @@ -14,7 +14,7 @@ public import Mathlib.RingTheory.DedekindDomain.Ideal.Lemmas Given `P : Ideal S` lying over `p : Ideal R` for the ring extension `f : R →+* S` (assuming `P` and `p` are prime or maximal where needed), -the **ramification index** `Ideal.ramificationIdx p P` is the multiplicity of `P` in `map f p`. +the **ramification index** `Ideal.ramificationIdx' p P` is the multiplicity of `P` in `map f p`. ## Implementation notes @@ -59,38 +59,44 @@ section DecEq In particular, if `p` is not contained in `P^n`, then the ramification index is 0. -If there is no largest such `n` (e.g. because `p = ⊥`), then `ramificationIdx` is +If there is no largest such `n` (e.g. because `p = ⊥`), then `ramificationIdx'` is defined to be 0. -Note: This definition of ramification index will eventually be replaced by `Ideal.ramificationIdx'`. +Note: This definition of ramification index will eventually be replaced by `Ideal.ramificationIdx`. -/ -noncomputable def ramificationIdx : ℕ := sSup {n | map f p ≤ P ^ n} +noncomputable def ramificationIdx' : ℕ := sSup {n | map f p ≤ P ^ n} variable {p P} -theorem ramificationIdx_eq_find [DecidablePred fun n ↦ ∀ (k : ℕ), map f p ≤ P ^ k → k ≤ n] +theorem ramificationIdx'_eq_find [DecidablePred fun n ↦ ∀ (k : ℕ), map f p ≤ P ^ k → k ≤ n] (h : ∃ n, ∀ k, map f p ≤ P ^ k → k ≤ n) : - ramificationIdx p P = Nat.find h := by + ramificationIdx' p P = Nat.find h := by convert! Nat.sSup_def h -theorem ramificationIdx_eq_zero (h : ∀ n : ℕ, ∃ k, map f p ≤ P ^ k ∧ n < k) : - ramificationIdx p P = 0 := +@[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_find := ramificationIdx'_eq_find + +theorem ramificationIdx'_eq_zero (h : ∀ n : ℕ, ∃ k, map f p ≤ P ^ k ∧ n < k) : + ramificationIdx' p P = 0 := dif_neg (by push Not; exact h) -theorem ramificationIdx_spec {n : ℕ} (hle : map f p ≤ P ^ n) (hgt : ¬map f p ≤ P ^ (n + 1)) : - ramificationIdx p P = n := by +@[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_zero := ramificationIdx'_eq_zero + +theorem ramificationIdx'_spec {n : ℕ} (hle : map f p ≤ P ^ n) (hgt : ¬map f p ≤ P ^ (n + 1)) : + ramificationIdx' p P = n := by classical let Q : ℕ → Prop := fun m => ∀ k : ℕ, map f p ≤ P ^ k → k ≤ m have : Q n := by intro k hk refine le_of_not_gt fun hnk => ?_ exact hgt (hk.trans (Ideal.pow_le_pow_right hnk)) - rw [ramificationIdx_eq_find ⟨n, this⟩] + rw [ramificationIdx'_eq_find ⟨n, this⟩] refine le_antisymm (Nat.find_min' _ this) (le_of_not_gt fun h : Nat.find _ < n => ?_) obtain this' := Nat.find_spec ⟨n, this⟩ exact h.not_ge (this' _ hle) -theorem ramificationIdx_lt {n : ℕ} (hgt : ¬map f p ≤ P ^ n) : ramificationIdx p P < n := by +@[deprecated (since := "2026-07-01")] alias ramificationIdx_spec := ramificationIdx'_spec + +theorem ramificationIdx'_lt {n : ℕ} (hgt : ¬map f p ≤ P ^ n) : ramificationIdx' p P < n := by classical rcases n with - | n · simp at hgt @@ -98,45 +104,66 @@ theorem ramificationIdx_lt {n : ℕ} (hgt : ¬map f p ≤ P ^ n) : ramificationI have : ∀ k, map f p ≤ P ^ k → k ≤ n := by refine fun k hk => le_of_not_gt fun hnk => ?_ exact hgt (hk.trans (Ideal.pow_le_pow_right hnk)) - rw [ramificationIdx_eq_find ⟨n, this⟩] + rw [ramificationIdx'_eq_find ⟨n, this⟩] exact Nat.find_min' ⟨n, this⟩ this +@[deprecated (since := "2026-07-01")] alias ramificationIdx_lt := ramificationIdx'_lt + @[simp] -theorem ramificationIdx_bot : ramificationIdx (⊥ : Ideal R) P = 0 := +theorem ramificationIdx'_bot : ramificationIdx' (⊥ : Ideal R) P = 0 := dif_neg <| not_exists.mpr fun n hn => n.lt_succ_self.not_ge (hn _ (by simp)) +@[deprecated (since := "2026-07-01")] alias ramificationIdx_bot := ramificationIdx'_bot + @[simp] -theorem ramificationIdx_of_not_le (h : ¬map f p ≤ P) : ramificationIdx p P = 0 := - ramificationIdx_spec (by simp) (by simpa using h) +theorem ramificationIdx'_of_not_le (h : ¬map f p ≤ P) : ramificationIdx' p P = 0 := + ramificationIdx'_spec (by simp) (by simpa using h) + +@[deprecated (since := "2026-07-01")] alias ramificationIdx_of_not_le := ramificationIdx'_of_not_le -theorem ramificationIdx_bot' (hp : p ≠ ⊥) (hf : Function.Injective f) : - ramificationIdx p (⊥ : Ideal S) = 0 := - ramificationIdx_of_not_le <| le_bot_iff.not.mpr <| (map_eq_bot_iff_of_injective hf).not.mpr hp +theorem ramificationIdx'_bot' (hp : p ≠ ⊥) (hf : Function.Injective f) : + ramificationIdx' p (⊥ : Ideal S) = 0 := + ramificationIdx'_of_not_le <| le_bot_iff.not.mpr <| (map_eq_bot_iff_of_injective hf).not.mpr hp -theorem ramificationIdx_ne_zero {e : ℕ} (he : e ≠ 0) (hle : map f p ≤ P ^ e) - (hnle : ¬map f p ≤ P ^ (e + 1)) : ramificationIdx p P ≠ 0 := by - rwa [ramificationIdx_spec hle hnle] +@[deprecated (since := "2026-07-01")] alias ramificationIdx_bot' := ramificationIdx'_bot' -theorem le_pow_of_le_ramificationIdx {n : ℕ} (hn : n ≤ ramificationIdx p P) : +theorem ramificationIdx'_ne_zero {e : ℕ} (he : e ≠ 0) (hle : map f p ≤ P ^ e) + (hnle : ¬map f p ≤ P ^ (e + 1)) : ramificationIdx' p P ≠ 0 := by + rwa [ramificationIdx'_spec hle hnle] + +@[deprecated (since := "2026-07-01")] alias ramificationIdx_ne_zero := ramificationIdx'_ne_zero + +theorem le_pow_of_le_ramificationIdx' {n : ℕ} (hn : n ≤ ramificationIdx' p P) : map f p ≤ P ^ n := by contrapose! hn - exact ramificationIdx_lt hn + exact ramificationIdx'_lt hn + +@[deprecated (since := "2026-07-01")] alias le_pow_of_le_ramificationIdx := + le_pow_of_le_ramificationIdx' + +theorem le_pow_ramificationIdx' : map f p ≤ P ^ ramificationIdx' p P := + le_pow_of_le_ramificationIdx' (le_refl _) + +@[deprecated (since := "2026-07-01")] alias le_pow_ramificationIdx := le_pow_ramificationIdx' + +theorem le_comap_pow_ramificationIdx' : p ≤ comap f (P ^ ramificationIdx' p P) := + map_le_iff_le_comap.mp le_pow_ramificationIdx' -theorem le_pow_ramificationIdx : map f p ≤ P ^ ramificationIdx p P := - le_pow_of_le_ramificationIdx (le_refl _) +@[deprecated (since := "2026-07-01")] alias le_comap_pow_ramificationIdx := + le_comap_pow_ramificationIdx' -theorem le_comap_pow_ramificationIdx : p ≤ comap f (P ^ ramificationIdx p P) := - map_le_iff_le_comap.mp le_pow_ramificationIdx +theorem le_comap_of_ramificationIdx'_ne_zero (h : ramificationIdx' p P ≠ 0) : p ≤ comap f P := + Ideal.map_le_iff_le_comap.mp <| le_pow_ramificationIdx'.trans <| Ideal.pow_le_self <| h -theorem le_comap_of_ramificationIdx_ne_zero (h : ramificationIdx p P ≠ 0) : p ≤ comap f P := - Ideal.map_le_iff_le_comap.mp <| le_pow_ramificationIdx.trans <| Ideal.pow_le_self <| h +@[deprecated (since := "2026-07-01")] alias le_comap_of_ramificationIdx_ne_zero := + le_comap_of_ramificationIdx'_ne_zero variable {S₁ : Type*} [CommRing S₁] [Algebra R S₁] variable (p) in -lemma ramificationIdx_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : - ramificationIdx p (P.comap e) = ramificationIdx p P := by - dsimp only [ramificationIdx] +lemma ramificationIdx'_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : + ramificationIdx' p (P.comap e) = ramificationIdx' p P := by + dsimp only [ramificationIdx'] congr 1 ext n simp only [Set.mem_setOf_eq, Ideal.map_le_iff_le_comap] @@ -145,20 +172,24 @@ lemma ramificationIdx_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : comap_comap, RingEquiv.symm_symm, e.toRingEquiv_toRingHom, ← e.toAlgHom_toRingHom, AlgHom.comp_algebraMap] +@[deprecated (since := "2026-07-01")] alias ramificationIdx_comap_eq := ramificationIdx'_comap_eq + variable (p) in -lemma ramificationIdx_map_eq {E : Type*} [EquivLike E S S₁] [AlgEquivClass E R S S₁] +lemma ramificationIdx'_map_eq {E : Type*} [EquivLike E S S₁] [AlgEquivClass E R S S₁] (P : Ideal S) (e : E) : - ramificationIdx p (P.map e) = ramificationIdx p P := by + ramificationIdx' p (P.map e) = ramificationIdx' p P := by rw [show P.map e = _ from P.map_comap_of_equiv (RingEquivClass.toRingEquiv e : S ≃+* S₁)] - exact p.ramificationIdx_comap_eq (AlgEquivClass.toAlgEquiv e).symm P + exact p.ramificationIdx'_comap_eq (AlgEquivClass.toAlgEquiv e).symm P + +@[deprecated (since := "2026-07-01")] alias ramificationIdx_map_eq := ramificationIdx'_map_eq -lemma ramificationIdx_ne_one_iff (hp : map f p ≤ P) : - ramificationIdx p P ≠ 1 ↔ p.map f ≤ P ^ 2 := by +lemma ramificationIdx'_ne_one_iff (hp : map f p ≤ P) : + ramificationIdx' p P ≠ 1 ↔ p.map f ≤ P ^ 2 := by classical by_cases! H : ∀ n : ℕ, ∃ k, p.map f ≤ P ^ k ∧ n < k · obtain ⟨k, hk, h2k⟩ := H 2 - simp [Ideal.ramificationIdx_eq_zero H, hk.trans (Ideal.pow_le_pow_right h2k.le)] - rw [Ideal.ramificationIdx_eq_find H] + simp [Ideal.ramificationIdx'_eq_zero H, hk.trans (Ideal.pow_le_pow_right h2k.le)] + rw [Ideal.ramificationIdx'_eq_find H] constructor · intro he have : 1 ≤ Nat.find H := Nat.find_spec H 1 (by simpa) @@ -170,15 +201,18 @@ lemma ramificationIdx_ne_one_iff (hp : map f p ≤ P) : have := Nat.find_spec H 2 he lia +@[deprecated (since := "2026-07-01")] alias ramificationIdx_ne_one_iff := + ramificationIdx'_ne_one_iff + open IsLocalRing in /-- The converse is true when `S` is a Dedekind domain. -See `Ideal.ramificationIdx_eq_one_iff_of_isDedekindDomain`. -/ -lemma ramificationIdx_eq_one_of_map_localization +See `Ideal.ramificationIdx'_eq_one_iff_of_isDedekindDomain`. -/ +lemma ramificationIdx'_eq_one_of_map_localization {p : Ideal R} {P : Ideal S} [P.IsPrime] [IsNoetherianRing S] (hpP : map (algebraMap R S) p ≤ P) (hp : P ≠ ⊥) (hp' : P.primeCompl ≤ nonZeroDivisors S) (H : p.map (algebraMap R (Localization.AtPrime P)) = maximalIdeal (Localization.AtPrime P)) : - ramificationIdx p P = 1 := by - rw [← not_ne_iff (b := 1), Ideal.ramificationIdx_ne_one_iff hpP] + ramificationIdx' p P = 1 := by + rw [← not_ne_iff (b := 1), Ideal.ramificationIdx'_ne_one_iff hpP] intro h₂ replace h₂ := Ideal.map_mono («f» := algebraMap S (Localization.AtPrime P)) h₂ rw [Ideal.map_pow, Localization.AtPrime.map_eq_maximalIdeal, Ideal.map_map, @@ -189,82 +223,96 @@ lemma ramificationIdx_eq_one_of_map_localization · exact hp this · exact IsLocalization.injective _ hp' -theorem ramificationIdx_map_self_eq_one [IsDedekindDomain S] (h₁ : map f p ≠ ⊤) (h₂ : map f p ≠ ⊥) : - ramificationIdx p (map f p) = 1 := by - refine ramificationIdx_spec (by simp) fun h ↦ ?_ +@[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_one_of_map_localization := + ramificationIdx'_eq_one_of_map_localization + +theorem ramificationIdx'_map_self_eq_one [IsDedekindDomain S] + (h₁ : map f p ≠ ⊤) (h₂ : map f p ≠ ⊥) : ramificationIdx' p (map f p) = 1 := by + refine ramificationIdx'_spec (by simp) fun h ↦ ?_ have : map f p ^ 1 = (map f p) ^ 2 := by rw [pow_one] exact le_antisymm h <| pow_le_self two_ne_zero have := IsMulTorsionFree.pow_right_injective₀ (by rwa [one_eq_top]) h₂ this simp_all +@[deprecated (since := "2026-07-01")] alias ramificationIdx_map_self_eq_one := + ramificationIdx'_map_self_eq_one + variable (p P) in -theorem ramificationIdx_le_ramificationIdx {T : Type*} [CommRing T] [Algebra R T] +theorem ramificationIdx'_le_ramificationIdx' {T : Type*} [CommRing T] [Algebra R T] [Algebra S T] [IsScalarTower R S T] (Q : Ideal T) (hp : p = comap f P) - (h : ramificationIdx p Q ≠ 0) : ramificationIdx P Q ≤ ramificationIdx p Q := by - simp_rw [ramificationIdx, Ne] at * + (h : ramificationIdx' p Q ≠ 0) : ramificationIdx' P Q ≤ ramificationIdx' p Q := by + simp_rw [ramificationIdx', Ne] at * refine csSup_le_csSup' (h.imp_symm Nat.sSup_of_not_bddAbove) fun n hn ↦ ?_ simp_rw [hp, IsScalarTower.algebraMap_eq R S T, ← map_map, map_le_iff_le_comap] exact comap_mono <| by rwa [← map_le_iff_le_comap] +@[deprecated (since := "2026-07-01")] alias ramificationIdx_le_ramificationIdx := + ramificationIdx'_le_ramificationIdx' + namespace IsDedekindDomain variable [IsDedekindDomain S] -theorem ramificationIdx_eq_normalizedFactors_count +theorem ramificationIdx'_eq_normalizedFactors_count (hp0 : map f p ≠ ⊥) (hP : P.IsPrime) - (hP0 : P ≠ ⊥) : ramificationIdx p P = (normalizedFactors (map f p)).count P := by + (hP0 : P ≠ ⊥) : ramificationIdx' p P = (normalizedFactors (map f p)).count P := by have hPirr := (Ideal.prime_of_isPrime hP0 hP).irreducible - refine ramificationIdx_spec (Ideal.le_of_dvd ?_) (mt Ideal.dvd_iff_le.mpr ?_) <;> + refine ramificationIdx'_spec (Ideal.le_of_dvd ?_) (mt Ideal.dvd_iff_le.mpr ?_) <;> rw [dvd_iff_normalizedFactors_le_normalizedFactors (pow_ne_zero _ hP0) hp0, normalizedFactors_pow, normalizedFactors_irreducible hPirr, normalize_eq, Multiset.nsmul_singleton, ← Multiset.le_count_iff_replicate_le] exact (Nat.lt_succ_self _).not_ge -theorem ramificationIdx_eq_multiplicity (hp : map f p ≠ ⊥) (hP : P.IsPrime) : - ramificationIdx p P = multiplicity P (Ideal.map f p) := by +theorem ramificationIdx'_eq_multiplicity (hp : map f p ≠ ⊥) (hP : P.IsPrime) : + ramificationIdx' p P = multiplicity P (Ideal.map f p) := by classical by_cases hP₂ : P = ⊥ · rw [hP₂, ← Ideal.zero_eq_bot, multiplicity_zero_eq_zero_of_ne_zero _ hp] - exact Ideal.ramificationIdx_of_not_le (mt le_bot_iff.mp hp) + exact Ideal.ramificationIdx'_of_not_le (mt le_bot_iff.mp hp) rw [multiplicity_eq_of_emultiplicity_eq_some] - rw [ramificationIdx_eq_normalizedFactors_count hp hP hP₂, ← normalize_eq P, + rw [ramificationIdx'_eq_normalizedFactors_count hp hP hP₂, ← normalize_eq P, ← UniqueFactorizationMonoid.emultiplicity_eq_count_normalizedFactors _ hp, normalize_eq] exact irreducible_iff_prime.mpr <| prime_of_isPrime hP₂ hP -theorem ramificationIdx_eq_factors_count +theorem ramificationIdx'_eq_factors_count (hp0 : map f p ≠ ⊥) (hP : P.IsPrime) (hP0 : P ≠ ⊥) : - ramificationIdx p P = (factors (map f p)).count P := by - rw [IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hp0 hP hP0, + ramificationIdx' p P = (factors (map f p)).count P := by + rw [IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hp0 hP hP0, factors_eq_normalizedFactors] -theorem ramificationIdx_ne_zero (hp0 : map f p ≠ ⊥) (hP : P.IsPrime) (le : map f p ≤ P) : - ramificationIdx p P ≠ 0 := by +theorem ramificationIdx'_ne_zero (hp0 : map f p ≠ ⊥) (hP : P.IsPrime) (le : map f p ≤ P) : + ramificationIdx' p P ≠ 0 := by classical have hP0 : P ≠ ⊥ := by rintro rfl exact hp0 (le_bot_iff.mp le) have hPirr := (Ideal.prime_of_isPrime hP0 hP).irreducible - rw [IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hp0 hP hP0] + rw [IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hp0 hP hP0] obtain ⟨P', hP', P'_eq⟩ := exists_mem_normalizedFactors_of_dvd hp0 hPirr (Ideal.dvd_iff_le.mpr le) rwa [Multiset.count_ne_zero, associated_iff_eq.mp P'_eq] -theorem ramificationIdx_ne_zero_of_liesOver [IsDomain R] [IsTorsionFree R S] +@[deprecated (since := "2026-07-01")] alias ramificationIdx_ne_zero := ramificationIdx'_ne_zero + +theorem ramificationIdx'_ne_zero_of_liesOver [IsDomain R] [IsTorsionFree R S] (P : Ideal S) [hP : P.IsPrime] {p : Ideal R} (hp : p ≠ ⊥) [hPp : P.LiesOver p] : - ramificationIdx p P ≠ 0 := - IsDedekindDomain.ramificationIdx_ne_zero (map_ne_bot_of_ne_bot hp) hP <| + ramificationIdx' p P ≠ 0 := + IsDedekindDomain.ramificationIdx'_ne_zero (map_ne_bot_of_ne_bot hp) hP <| map_le_iff_le_comap.mpr <| le_of_eq <| (liesOver_iff _ _).mp hPp +@[deprecated (since := "2026-07-01")] alias ramificationIdx_ne_zero_of_liesOver := + ramificationIdx'_ne_zero_of_liesOver + open IsLocalRing in -lemma ramificationIdx_eq_one_iff +lemma ramificationIdx'_eq_one_iff {p : Ideal R} {P : Ideal S} [P.IsPrime] (hp : P ≠ ⊥) (hpP : p.map (algebraMap R S) ≤ P) : - ramificationIdx p P = 1 ↔ + ramificationIdx' p P = 1 ↔ p.map (algebraMap R (Localization.AtPrime P)) = maximalIdeal (Localization.AtPrime P) := by - refine ⟨?_, ramificationIdx_eq_one_of_map_localization hpP hp (primeCompl_le_nonZeroDivisors _)⟩ + refine ⟨?_, ramificationIdx'_eq_one_of_map_localization hpP hp (primeCompl_le_nonZeroDivisors _)⟩ let Sₚ := Localization.AtPrime P - rw [← not_ne_iff (b := 1), ramificationIdx_ne_one_iff hpP, pow_two] + rw [← not_ne_iff (b := 1), ramificationIdx'_ne_one_iff hpP, pow_two] intro H₁ obtain ⟨a, ha⟩ : P ∣ p.map (algebraMap R S) := Ideal.dvd_iff_le.mpr hpP have ha' : ¬ a ≤ P := fun h ↦ H₁ (ha.trans_le (Ideal.mul_mono_right h)) @@ -275,12 +323,18 @@ lemma ramificationIdx_eq_one_iff rw [← not_ne_iff, IsLocalization.map_algebraMap_ne_top_iff_disjoint P.primeCompl] simpa [primeCompl, Set.disjoint_compl_left_iff_subset] -theorem ramificationIdx_le_ramificationIdx [IsDomain R] [IsTorsionFree R S] {S₀ : Type*} +@[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_one_iff := + ramificationIdx'_eq_one_iff + +theorem ramificationIdx'_le_ramificationIdx' [IsDomain R] [IsTorsionFree R S] {S₀ : Type*} [CommRing S₀] [Algebra R S₀] [Algebra S₀ S] [IsScalarTower R S₀ S] (p : Ideal R) (P : Ideal S₀) (Q : Ideal S) [Q.LiesOver p] [hP : P.LiesOver p] [Q.IsPrime] (hp : p ≠ ⊥) : - Ideal.ramificationIdx P Q ≤ Ideal.ramificationIdx p Q := - p.ramificationIdx_le_ramificationIdx P Q ((liesOver_iff ..).mp hP) <| - ramificationIdx_ne_zero_of_liesOver _ hp + Ideal.ramificationIdx' P Q ≤ Ideal.ramificationIdx' p Q := + p.ramificationIdx'_le_ramificationIdx' P Q ((liesOver_iff ..).mp hP) <| + ramificationIdx'_ne_zero_of_liesOver _ hp + +@[deprecated (since := "2026-07-01")] alias ramificationIdx_le_ramificationIdx := + ramificationIdx'_le_ramificationIdx' theorem emultiplicity_map_eq_zero_of_ne [IsDedekindDomain R] {v : Ideal R} {w : Ideal S} {p : Ideal R} (hv : Irreducible v) (hp : Prime p) (hvp : v ≠ p) [w.LiesOver v] : @@ -289,17 +343,17 @@ theorem emultiplicity_map_eq_zero_of_ne [IsDedekindDomain R] {v : Ideal R} rw [Ideal.dvd_iff_le, Ideal.map_le_iff_le_comap, ← under_def, ← Ideal.over_def w v] at h exact ((isPrime_of_prime hp).isMaximal hp.ne_zero).eq_of_le (isPrime_of_prime hv.prime).ne_top h -/-- Use the more general result `emultiplicity_map_eq_ramificationIdx_mul`. +/-- Use the more general result `emultiplicity_map_eq_ramificationIdx'_mul`. This is a helper lemma. -/ -private theorem emultiplicity_map_eq_ramificationIdx_mul_of_prime [IsDedekindDomain R] +private theorem emultiplicity_map_eq_ramificationIdx'_mul_of_prime [IsDedekindDomain R] [FaithfulSMul R S] {v : Ideal R} {w : Ideal S} {p : Ideal R} (hv : Irreducible v) (hp : Prime p) (hw : Irreducible w) (hw_bot : w ≠ ⊥) [w.LiesOver v] : emultiplicity w (p.map (algebraMap R S)) = - v.ramificationIdx w * emultiplicity v p := by + v.ramificationIdx' w * emultiplicity v p := by have hp_bot : p.map (algebraMap R S) ≠ ⊥ := map_ne_bot_of_ne_bot hp.ne_zero by_cases hvp : v = p · simp [hvp, (FiniteMultiplicity.of_prime_left hp hp.ne_zero).emultiplicity_self, - ramificationIdx_eq_normalizedFactors_count hp_bot (isPrime_of_prime hw.prime) hw_bot, + ramificationIdx'_eq_normalizedFactors_count hp_bot (isPrime_of_prime hw.prime) hw_bot, emultiplicity_eq_count_normalizedFactors hw hp_bot] · rw [emultiplicity_eq_zero_of_irreducible_ne hv hp.irreducible hvp, mul_zero, emultiplicity_map_eq_zero_of_ne hv hp hvp] @@ -307,11 +361,11 @@ private theorem emultiplicity_map_eq_ramificationIdx_mul_of_prime [IsDedekindDom /-- If `v` is an irreducible ideal of `R`, `w` is an irreducible ideal of `S` lying over `v`, and `I` is an ideal of `R`, then the multiplicity of `w` in `I.map (algebraMap R S)` is given by the multiplicity of `v` in `I` multiplied by the ramification index of `w` over `v`. -/ -theorem emultiplicity_map_eq_ramificationIdx_mul [IsDedekindDomain R] +theorem emultiplicity_map_eq_ramificationIdx'_mul [IsDedekindDomain R] [FaithfulSMul R S] {v : Ideal R} {w : Ideal S} {I : Ideal R} (h : I ≠ ⊥) (hv : Irreducible v) (hw : Irreducible w) (hw_bot : w ≠ ⊥) [w.LiesOver v] : emultiplicity w (I.map (algebraMap R S)) = - v.ramificationIdx w * emultiplicity v I := by + v.ramificationIdx' w * emultiplicity v I := by induction I using induction_on_prime with | h₁ => aesop | h₂ I hI => @@ -321,7 +375,10 @@ theorem emultiplicity_map_eq_ramificationIdx_mul [IsDedekindDomain R] simp | h₃ I p hI hp IH => rw [Ideal.map_mul, emultiplicity_mul hw.prime, emultiplicity_mul hv.prime, IH hI, mul_add, - emultiplicity_map_eq_ramificationIdx_mul_of_prime hv hp hw hw_bot] + emultiplicity_map_eq_ramificationIdx'_mul_of_prime hv hp hw hw_bot] + +@[deprecated (since := "2026-07-01")] alias emultiplicity_map_eq_ramificationIdx_mul := + emultiplicity_map_eq_ramificationIdx'_mul end IsDedekindDomain @@ -334,12 +391,12 @@ variable [Algebra R S] [Algebra S T] [Algebra R T] [IsScalarTower R S T] /-- Let `T / S / R` be a tower of algebras, `p, P, Q` be ideals in `R, S, T` respectively, and `P` and `Q` are prime. If `P = Q ∩ S`, then `e (Q | p) = e (P | p) * e (Q | P)`. -/ -theorem ramificationIdx_algebra_tower [IsDedekindDomain S] [IsDedekindDomain T] +theorem ramificationIdx'_algebra_tower [IsDedekindDomain S] [IsDedekindDomain T] {p : Ideal R} {P : Ideal S} {Q : Ideal T} [hpm : P.IsPrime] [hqm : Q.IsPrime] (hg0 : map (algebraMap S T) P ≠ ⊥) (hfg : map (algebraMap R T) p ≠ ⊥) (hg : map (algebraMap S T) P ≤ Q) : - ramificationIdx p Q = - ramificationIdx p P * ramificationIdx P Q := by + ramificationIdx' p Q = + ramificationIdx' p P * ramificationIdx' P Q := by classical have hf0 : map (algebraMap R S) p ≠ ⊥ := by rw [IsScalarTower.algebraMap_eq R S T, ← map_map] at hfg @@ -347,9 +404,9 @@ theorem ramificationIdx_algebra_tower [IsDedekindDomain S] [IsDedekindDomain T] have hp0 : P ≠ ⊥ := ne_bot_of_map_ne_bot hg0 have hq0 : Q ≠ ⊥ := ne_bot_of_le_ne_bot hg0 hg letI : P.IsMaximal := Ring.DimensionLEOne.maximalOfPrime hp0 hpm - rw [IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hf0 hpm hp0, - IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hg0 hqm hq0, - IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hfg hqm hq0, + rw [IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hf0 hpm hp0, + IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hg0 hqm hq0, + IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hfg hqm hq0, IsScalarTower.algebraMap_eq R S T, ← map_map] rcases eq_prime_pow_mul_coprime hf0 P with ⟨I, hcp, heq⟩ have hcp : ⊤ = map (algebraMap S T) P ⊔ map (algebraMap S T) I := by rw [← map_sup, hcp, map_top] @@ -361,13 +418,14 @@ theorem ramificationIdx_algebra_tower [IsDedekindDomain S] [IsDedekindDomain T] exact add_eq_left.mpr <| Decidable.byContradiction fun h ↦ hntq <| hcp.trans_le <| sup_le hg <| le_of_dvd <| dvd_of_mem_normalizedFactors <| Multiset.count_ne_zero.mp h -@[deprecated (since := "2026-03-25")] alias ramificationIdx_tower := ramificationIdx_algebra_tower +@[deprecated (since := "2026-07-01")] alias ramificationIdx_algebra_tower := + ramificationIdx'_algebra_tower -theorem ramificationIdx_algebra_tower' [IsDedekindDomain S] [IsDedekindDomain T] [IsDomain R] +theorem ramificationIdx'_algebra_tower' [IsDedekindDomain S] [IsDedekindDomain T] [IsDomain R] [Module.IsTorsionFree R S] [Module.IsTorsionFree S T] (p : Ideal R) (P : Ideal S) (Q : Ideal T) [Q.IsPrime] [Q.LiesOver P] [P.LiesOver p] : - ramificationIdx p Q = - ramificationIdx p P * ramificationIdx P Q := by + ramificationIdx' p Q = + ramificationIdx' p P * ramificationIdx' P Q := by obtain rfl | hp := eq_or_ne p ⊥ · simp have : P.IsPrime := isPrime_of_liesOver Q P @@ -375,9 +433,12 @@ theorem ramificationIdx_algebra_tower' [IsDedekindDomain S] [IsDedekindDomain T] refine Module.IsTorsionFree.of_smul_eq_zero fun r m h ↦ ?_ rwa [algebra_compatible_smul S, smul_eq_zero, FaithfulSMul.algebraMap_eq_zero_iff] at h have hP : P ≠ ⊥ := ne_bot_of_liesOver_of_ne_bot hp _ - exact ramificationIdx_algebra_tower (map_ne_bot_of_ne_bot hP) (map_ne_bot_of_ne_bot hp) + exact ramificationIdx'_algebra_tower (map_ne_bot_of_ne_bot hP) (map_ne_bot_of_ne_bot hp) <| map_le_iff_le_comap.mpr <| le_of_eq <| over_def Q P +@[deprecated (since := "2026-07-01")] alias ramificationIdx_algebra_tower' := + ramificationIdx'_algebra_tower' + end tower end Ideal diff --git a/Mathlib/NumberTheory/RamificationInertia/Unramified.lean b/Mathlib/NumberTheory/RamificationInertia/Unramified.lean index fbfcbe164c0aed..c484d8c00d5481 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Unramified.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Unramified.lean @@ -27,14 +27,14 @@ variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] variable [Algebra R S] [Algebra S T] [Algebra R T] [IsScalarTower R S T] local notation3 "e(" P "|" R ")" => - Ideal.ramificationIdx' P R + Ideal.ramificationIdx P R open IsLocalRing Algebra lemma Ideal.ramificationIdx_eq_one_of_isUnramifiedAt {p : Ideal S} [p.IsPrime] [IsUnramifiedAt R p] [EssFiniteType R S] : e(p|R) = 1 := - p.ramificationIdx'_eq_one R + p.ramificationIdx_eq_one R variable (R) in lemma IsUnramifiedAt.of_liesOver_of_ne_bot @@ -59,12 +59,12 @@ lemma IsUnramifiedAt.of_liesOver_of_ne_bot exact le_bot_iff.mp (Ideal.map_comap_le) rw [IsScalarTower.algebraMap_eq _ S, ← Ideal.map_map, this, Localization.AtPrime.map_eq_maximalIdeal] - rw [← Ideal.IsDedekindDomain.ramificationIdx_eq_one_iff hp Ideal.map_comap_le, - ← not_ne_iff, Ideal.ramificationIdx_ne_one_iff Ideal.map_comap_le] + rw [← Ideal.IsDedekindDomain.ramificationIdx'_eq_one_iff hp Ideal.map_comap_le, + ← not_ne_iff, Ideal.ramificationIdx'_ne_one_iff Ideal.map_comap_le] intro H - have := Ideal.ramificationIdx_eq_one_of_map_localization + have := Ideal.ramificationIdx'_eq_one_of_map_localization (hp₀ ▸ Ideal.map_comap_le) (hP₂ hp) hP₁ h₂ - rw [← not_ne_iff, Ideal.ramificationIdx_ne_one_iff (hp₀ ▸ Ideal.map_comap_le)] at this + rw [← not_ne_iff, Ideal.ramificationIdx'_ne_one_iff (hp₀ ▸ Ideal.map_comap_le)] at this replace H := Ideal.map_mono (f := algebraMap S T) H rw [Ideal.map_map, ← IsScalarTower.algebraMap_eq, Ideal.map_pow] at H refine this (H.trans (Ideal.pow_right_mono ?_ _)) @@ -150,8 +150,8 @@ theorem isUnramifiedIn_iff_forall_of_isDedekindDomain [IsDomain R] [IsDedekindDo theorem IsUnramifiedIn.ramificationIdx_eq_one [IsDomain R] [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] [Algebra.IsIntegral R S] {𝔭 : Ideal R} (hunr : IsUnramifiedIn S 𝔭) {𝔓 : Ideal S} - [𝔓.IsPrime] (hP : 𝔓.LiesOver 𝔭) : Ideal.ramificationIdx' 𝔓 R = 1 := - Ideal.ramificationIdx'_eq_one_iff.mpr + [𝔓.IsPrime] (hP : 𝔓.LiesOver 𝔭) : Ideal.ramificationIdx 𝔓 R = 1 := + Ideal.ramificationIdx_eq_one_iff.mpr (hunr 𝔓 inferInstance hP) /-- A nonzero ideal of `R` is unramified in `S` if and only if every prime ideal of `S` lying @@ -160,9 +160,9 @@ theorem isUnramifiedIn_iff_forall_ramificationIdx_eq_one [IsDomain R] [Module.Finite ℤ R] [CharZero R] [EssFiniteType R S] [Algebra.IsIntegral R S] {𝔭 : Ideal R} : IsUnramifiedIn S 𝔭 ↔ - ∀ (𝔓 : Ideal S) [𝔓.IsPrime], 𝔓.LiesOver 𝔭 → Ideal.ramificationIdx' 𝔓 R = 1 := by + ∀ (𝔓 : Ideal S) [𝔓.IsPrime], 𝔓.LiesOver 𝔭 → Ideal.ramificationIdx 𝔓 R = 1 := by refine ⟨fun hunr 𝔓 _ hP ↦ hunr.ramificationIdx_eq_one hP, fun h 𝔓 _ hP ↦ ?_⟩ - rw [← Ideal.ramificationIdx'_eq_one_iff] + rw [← Ideal.ramificationIdx_eq_one_iff] exact h 𝔓 hP end Algebra diff --git a/Mathlib/NumberTheory/RamificationInertia/Valuation.lean b/Mathlib/NumberTheory/RamificationInertia/Valuation.lean index 70e22aa5a5bef1..8af1bd6a3711a9 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Valuation.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Valuation.lean @@ -42,19 +42,20 @@ variable [Algebra B L] [IsFractionRing B L] [IsScalarTower A B L] variable (v : HeightOneSpectrum A) (w : HeightOneSpectrum B) [w.asIdeal.LiesOver v.asIdeal] theorem intValuation_liesOver (x : A) : - v.intValuation x ^ (v.asIdeal.ramificationIdx w.asIdeal) = + v.intValuation x ^ (v.asIdeal.ramificationIdx' w.asIdeal) = w.intValuation (algebraMap A B x) := by - rcases eq_or_ne x 0 with rfl | hx; · simp [ramificationIdx_ne_zero_of_liesOver w.asIdeal v.ne_bot] + rcases eq_or_ne x 0 with rfl | hx + · simp [ramificationIdx'_ne_zero_of_liesOver w.asIdeal v.ne_bot] rw [intValuation_eq_exp_neg_multiplicity v hx, intValuation_eq_exp_neg_multiplicity w (by simpa), ← Set.image_singleton, ← Ideal.map_span, exp_neg, exp_neg, inv_pow, ← exp_nsmul, Int.nsmul_eq_mul, inv_inj, exp_inj, ← Nat.cast_mul, Nat.cast_inj] refine multiplicity_eq_of_emultiplicity_eq_some ?_ |>.symm replace hx : Ideal.span {x} ≠ ⊥ := by simp [hx] - rw [emultiplicity_map_eq_ramificationIdx_mul hx v.irreducible w.irreducible w.ne_bot, + rw [emultiplicity_map_eq_ramificationIdx'_mul hx v.irreducible w.irreducible w.ne_bot, Nat.cast_mul, (FiniteMultiplicity.of_prime_left v.prime hx).emultiplicity_eq_multiplicity] theorem valuation_liesOver (x : K) : - v.valuation K x ^ v.asIdeal.ramificationIdx w.asIdeal = + v.valuation K x ^ v.asIdeal.ramificationIdx' w.asIdeal = w.valuation L (algebraMap K L x) := by obtain ⟨x, y, hy, rfl⟩ := IsFractionRing.div_surjective (A := A) x simp [valuation_of_algebraMap, div_pow, ← IsScalarTower.algebraMap_apply A K L, @@ -81,7 +82,7 @@ theorem uniformContinuous_algebraMap_liesOver : v v `γL : ValuativeRel.ValueGroupWithZero Lʷ` `γK: ValuativeRel.ValueGroupWithZero Kᵛ` -/ - let e := v.asIdeal.ramificationIdx w.asIdeal + let e := v.asIdeal.ramificationIdx' w.asIdeal -- push `γL` to `ℤᵐ⁰` let σL := WithVal.valueGroupOrderIso₀ (w.valuation L) let σw := valueGroup₀_equiv_withZeroMulInt (w.valuation L) @@ -110,7 +111,7 @@ theorem uniformContinuous_algebraMap_liesOver : ← log_lt_log (by simp_all) (by simp [EmbeddingLike.map_eq_zero_iff (f := σwV)]), log_pow, nsmul_eq_mul, mul_comm] exact Int.mul_lt_of_lt_ediv - (mod_cast pos_of_ne_zero (ramificationIdx_ne_zero_of_liesOver w.asIdeal v.ne_bot)) hx + (mod_cast pos_of_ne_zero (ramificationIdx'_ne_zero_of_liesOver w.asIdeal v.ne_bot)) hx end AKLB diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index a79a15b79c5be4..88a9307503810b 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -938,8 +938,8 @@ theorem not_dvd_differentIdeal_iff · suffices Algebra.IsSeparable (A ⧸ P.under A) (B ⧸ P) by infer_instance contrapose H exact dvd_differentIdeal_of_not_isSeparable A hp P H - · rw [← Ideal.IsDedekindDomain.ramificationIdx_eq_one_iff hPbot Ideal.map_comap_le] - apply Ideal.ramificationIdx_spec + · rw [← Ideal.IsDedekindDomain.ramificationIdx'_eq_one_iff hPbot Ideal.map_comap_le] + apply Ideal.ramificationIdx'_spec · simp [Ideal.map_le_iff_le_comap] · contrapose H rw [← pow_one P, show 1 = 2 - 1 by simp] @@ -947,7 +947,7 @@ theorem not_dvd_differentIdeal_iff simpa [Ideal.dvd_iff_le] using H · intro H obtain ⟨Q, h₁, h₂⟩ := Ideal.eq_prime_pow_mul_coprime hp' P - rw [← Ideal.IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count _ _ hp', + rw [← Ideal.IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count _ _ hp', Ideal.ramificationIdx_eq_one_of_isUnramifiedAt, pow_one] at h₂ obtain ⟨h₃, h₄⟩ := (Algebra.isUnramifiedAt_iff_map_eq (p := P.under A) _ _).mp H exact not_dvd_differentIdeal_of_isCoprime_of_isSeparable diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 5faa374f16acf2..3481ab85dc8195 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -819,7 +819,7 @@ If `p` is a maximal ideal, then the lift of `p` in an extension is the product o over `p` to the power the ramification index. -/ theorem Ideal.map_algebraMap_eq_finsetProd_pow {p : Ideal S} [p.IsMaximal] (hp : p ≠ 0) : - map (algebraMap S R) p = ∏ P ∈ p.primesOver R, P ^ P.ramificationIdx' S := by + map (algebraMap S R) p = ∏ P ∈ p.primesOver R, P ^ P.ramificationIdx S := by classical have h : map (algebraMap S R) p ≠ 0 := map_ne_bot_of_ne_bot hp rw [← finprod_heightOneSpectrum_factorization (I := p.map (algebraMap S R)) h] @@ -831,7 +831,7 @@ theorem Ideal.map_algebraMap_eq_finsetProd_pow {p : Ideal S} [p.IsMaximal] (hp : · let _ : Fintype {v : HeightOneSpectrum R // v.asIdeal ∣ map (algebraMap S R) p} := hF refine Fintype.prod_equiv (equivPrimesOver _ hp) _ _ fun ⟨v, _⟩ ↦ ?_ have : v.asIdeal.LiesOver p := by rwa [Ideal.liesOver_iff_dvd_map v.2.ne_top] - simp [maxPowDividing_eq_pow_multiset_count _ h, ramificationIdx'_eq_factors_count p v h] + simp [maxPowDividing_eq_pow_multiset_count _ h, ramificationIdx_eq_factors_count p v h] · intro v hv simpa [maxPowDividing, Function.mem_mulSupport, IsPrime.ne_top _, Associates.count_ne_zero_iff_dvd h (irreducible v)] using hv diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index 5e4c54f5a6c01a..e55fb5aae24973 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -413,7 +413,7 @@ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] obtain ⟨s, hs⟩ := exists_relNorm_eq_pow_of_isPrime P p suffices s = P.inertiaDeg' R by rwa [this] at hs have h₀ : ∀ Q ∈ (p.primesOver S).toFinset, - relNorm R Q ^ Q.ramificationIdx' R = p ^ ((p.ramificationIdxIn S) * s) := by + relNorm R Q ^ Q.ramificationIdx R = p ^ ((p.ramificationIdxIn S) * s) := by intro Q hQ rw [Set.mem_toFinset] at hQ have : Q.IsPrime := hQ.1 diff --git a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean index 4de0e95c68da68..7a87b43cdb7204 100644 --- a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean +++ b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean @@ -177,12 +177,12 @@ theorem inertiaDeg_map_eq_inertiaDeg [p.IsMaximal] [P.IsMaximal] include p in theorem ramificationIdx_map_eq_ramificationIdx [P.IsPrime] : - (P.map (algebraMap S Sₚ)).ramificationIdx' Rₚ = P.ramificationIdx' R := by + (P.map (algebraMap S Sₚ)).ramificationIdx Rₚ = P.ramificationIdx R := by have := liesOver_map_of_liesOver p Rₚ Sₚ P have := IsLocalization.liesOver_map_of_isPrime_disjoint (algebraMapSubmonoid S p.primeCompl) Sₚ (Set.disjoint_image_left.mpr (Set.disjoint_compl_left_iff_subset.mpr hPp.over.ge)) have := isPrime_map_of_liesOver S p Sₚ P - rw [ramificationIdx'_eq (maximalIdeal Rₚ) (P.map (algebraMap S Sₚ)), ramificationIdx'_eq p P] + rw [ramificationIdx_eq (maximalIdeal Rₚ) (P.map (algebraMap S Sₚ)), ramificationIdx_eq p P] let R₁ := Localization.AtPrime (P.map (algebraMap S Sₚ)) let R₂ := Localization.AtPrime P let : Algebra R₂ R₁ := Localization.AtPrime.algebraOfLiesOver P (P.map (algebraMap S Sₚ)) @@ -247,8 +247,8 @@ theorem primesOverEquivPrimesOver_inertiagDeg_eq [p.IsMaximal] (hp : p ≠ ⊥) exact inertiaDeg_map_eq_inertiaDeg p _ _ _ theorem primesOverEquivPrimesOver_ramificationIdx_eq (hp : p ≠ ⊥) (P : p.primesOver S) : - (primesOverEquivPrimesOver p Rₚ Sₚ hp P : Ideal Sₚ).ramificationIdx' Rₚ = - P.val.ramificationIdx' R := + (primesOverEquivPrimesOver p Rₚ Sₚ hp P : Ideal Sₚ).ramificationIdx Rₚ = + P.val.ramificationIdx R := ramificationIdx_map_eq_ramificationIdx p _ _ _ end IsDedekindDomain diff --git a/Mathlib/RingTheory/RamificationInertia/Basic.lean b/Mathlib/RingTheory/RamificationInertia/Basic.lean index e9529d9886d084..1ff5e1a804766a 100644 --- a/Mathlib/RingTheory/RamificationInertia/Basic.lean +++ b/Mathlib/RingTheory/RamificationInertia/Basic.lean @@ -43,7 +43,7 @@ variable {R : Type*} [CommRing R] (p : Ideal R) [p.IsPrime] (S : Type*) [CommRin open IsLocalRing Module OrderIso PrimeSpectrum in theorem sum_ramification_inertia_eq_finrank_fiber [Algebra.QuasiFinite R S] [Fintype (p.primesOver S)] : - ∑ q : p.primesOver S, q.1.ramificationIdx' R * q.1.inertiaDeg' R = + ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg' R = finrank p.ResidueField (p.Fiber S) := by let := Fintype.ofFinite (PrimeSpectrum (p.Fiber S)) rw [IsArtinianRing.finrank_eq_sum_primeSpectrum, ← (primesOverOrderIsoFiber R S p).symm.sum_comp] @@ -52,7 +52,7 @@ theorem sum_ramification_inertia_eq_finrank_fiber simp_rw [toEquiv_symm, coe_symm_toEquiv, coe_primesOverOrderIsoFiber_symm_apply] set r := q.1.comap Algebra.TensorProduct.includeRight let := Localization.AtPrime.algebraOfLiesOver p r - rw [ramificationIdx'_eq p r, inertiaDeg'_eq p r] + rw [ramificationIdx_eq p r, inertiaDeg'_eq p r] let Rp := Localization.AtPrime p let Sq := Localization.AtPrime q.1 let Sr := Localization.AtPrime r @@ -71,7 +71,7 @@ ideal of `R`. Then the sum over all prime ideals `q` of `S` lying over `p` of th index of `q` times the inertia degree of `q` equals the rank of `S` as an `R`-module. -/ theorem sum_ramification_inertia_eq_finrank [IsDomain R] [Module.Finite R S] [Module.Flat R S] [Fintype (p.primesOver S)] : - ∑ q : p.primesOver S, q.1.ramificationIdx' R * q.1.inertiaDeg' R = Module.finrank R S := by + ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg' R = Module.finrank R S := by rw [sum_ramification_inertia_eq_finrank_fiber, finrank_fiber_eq_finrank] /-- Let `S/R` be a finite flat extension of integral domains, and let `p` be prime ideal of `R`. @@ -81,7 +81,7 @@ degree of `q` equals the cardinality of `G`. -/ theorem sum_ramification_inertia_eq_card [IsDomain R] [IsDomain S] [Module.Finite R S] [Module.Flat R S] [Fintype (p.primesOver S)] {G : Type*} [Group G] [MulSemiringAction G S] [IsGaloisGroup G R S] : - ∑ q : p.primesOver S, q.1.ramificationIdx' R * q.1.inertiaDeg' R = Nat.card G := by + ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg' R = Nat.card G := by let := IsGaloisGroup.finite G R S rw [sum_ramification_inertia_eq_finrank, IsGaloisGroup.card_eq_finrank' G R S] diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index a905864ef3e591..ffd80a1f9d4b0a 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -21,13 +21,13 @@ an `Sq`-module. ## Main definitions -* `Ideal.ramificationIdx' q R`: The ramification index of `q` over `R`. +* `Ideal.ramificationIdx q R`: The ramification index of `q` over `R`. ## Main statements -* `ramificationIdx_eq_ramificationIdx'`: The ramification index agrees with the usual definition in +* `ramificationIdx'_eq_ramificationIdx`: The ramification index agrees with the usual definition in the case of Dedekind domains. -* `ramificationIdx'_tower`: Ramification index is multiplicative in towers. +* `ramificationIdx_tower`: Ramification index is multiplicative in towers. -/ @@ -47,25 +47,30 @@ an `Sq`-module. When `q` is not prime, we use a junk value of `0`. -This will eventually replace the existing definition of `Ideal.ramificationIdx`. -/ -noncomputable def ramificationIdx' : ℕ := +This will eventually replace the existing definition of `Ideal.ramificationIdx'`. -/ +noncomputable def ramificationIdx : ℕ := if _ : q.IsPrime then letI Sq := Localization.AtPrime q (Module.length Sq (Sq ⧸ (q.under R).map (algebraMap R Sq))).toNat else 0 -theorem ramificationIdx'_def [q.IsPrime] : +theorem ramificationIdx_def [q.IsPrime] : letI Sq := Localization.AtPrime q - q.ramificationIdx' R = (Module.length Sq (Sq ⧸ (q.under R).map (algebraMap R Sq))).toNat := + q.ramificationIdx R = (Module.length Sq (Sq ⧸ (q.under R).map (algebraMap R Sq))).toNat := dif_pos _ -theorem ramificationIdx'_of_not_isPrime (hq : ¬ q.IsPrime) : q.ramificationIdx' R = 0 := +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_def := ramificationIdx_def + +theorem ramificationIdx_of_not_isPrime (hq : ¬ q.IsPrime) : q.ramificationIdx R = 0 := dif_neg hq -theorem ramificationIdx'_pos [q.IsPrime] [Module.Finite R S] : 0 < q.ramificationIdx' R := by +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_of_not_isPrime := + ramificationIdx_of_not_isPrime + +theorem ramificationIdx_pos [q.IsPrime] [Module.Finite R S] : 0 < q.ramificationIdx R := by let p := q.under R let Sq := Localization.AtPrime q - rw [ramificationIdx'_def] + rw [ramificationIdx_def] apply ENat.toNat_pos · rw [← pos_iff_ne_zero, Module.length_pos_iff, Submodule.Quotient.nontrivial_iff, IsScalarTower.algebraMap_eq R S, ← map_map, ← lt_top_iff_ne_top] @@ -80,24 +85,28 @@ theorem ramificationIdx'_pos [q.IsPrime] [Module.Finite R S] : 0 < q.ramificatio rwa [Module.length_eq_of_surjective (R := Sq ⧸ p.map (algebraMap R Sq)) Quotient.mk_surjective, Module.length_ne_top_iff, ← isArtinianRing_iff_isFiniteLength] -theorem ramificationIdx'_eq_one [q.IsPrime] [Algebra.EssFiniteType R S] - [Algebra.IsUnramifiedAt R q] : q.ramificationIdx' R = 1 := by +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_pos := ramificationIdx_pos + +theorem ramificationIdx_eq_one [q.IsPrime] [Algebra.EssFiniteType R S] + [Algebra.IsUnramifiedAt R q] : q.ramificationIdx R = 1 := by let p := q.under R let Rp := Localization.AtPrime p let Sq := Localization.AtPrime q let : Algebra Rp Sq := Localization.AtPrime.algebraOfLiesOver p q have : Algebra.EssFiniteType Rp Sq := Algebra.EssFiniteType.of_comp R Rp Sq - rw [ramificationIdx'_def, ENat.toNat_eq_iff_eq_coe, Nat.cast_one, Module.length_eq_one_iff, + rw [ramificationIdx_def, ENat.toNat_eq_iff_eq_coe, Nat.cast_one, Module.length_eq_one_iff, isSimpleModule_iff_isCoatom, ← Ideal.isMaximal_def, IsLocalRing.isMaximal_iff, IsScalarTower.algebraMap_eq R Rp Sq, ← map_map, Localization.AtPrime.map_eq_maximalIdeal] exact Algebra.FormallyUnramified.map_maximalIdeal +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_eq_one := ramificationIdx_eq_one + variable {q R} in -theorem ramificationIdx'_eq_one_iff [q.IsPrime] [Algebra.EssFiniteType R S] +theorem ramificationIdx_eq_one_iff [q.IsPrime] [Algebra.EssFiniteType R S] [Algebra.IsIntegral R S] [PerfectField (q.under R).ResidueField] : - q.ramificationIdx' R = 1 ↔ Algebra.IsUnramifiedAt R q := by - refine ⟨fun h ↦ ?_, fun _ ↦ ramificationIdx'_eq_one q R⟩ - rw [ramificationIdx'_def, ENat.toNat_eq_iff_eq_coe, Nat.cast_one, Module.length_eq_one_iff, + q.ramificationIdx R = 1 ↔ Algebra.IsUnramifiedAt R q := by + refine ⟨fun h ↦ ?_, fun _ ↦ ramificationIdx_eq_one q R⟩ + rw [ramificationIdx_def, ENat.toNat_eq_iff_eq_coe, Nat.cast_one, Module.length_eq_one_iff, isSimpleModule_iff_isCoatom, ← Ideal.isMaximal_def, IsLocalRing.isMaximal_iff] at h let p := q.under R let Rp := Localization.AtPrime p @@ -109,6 +118,9 @@ theorem ramificationIdx'_eq_one_iff [q.IsPrime] [Algebra.EssFiniteType R S] ← Localization.AtPrime.map_eq_maximalIdeal, map_map, ← IsScalarTower.algebraMap_eq] exact ⟨Algebra.IsAlgebraic.isSeparable_of_perfectField, h⟩ +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_eq_one_iff := + ramificationIdx_eq_one_iff + end section @@ -117,15 +129,17 @@ variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] [Algebra S T] [IsScalarTower R S T] (p : Ideal R) (q : Ideal S) (r : Ideal T) -theorem ramificationIdx'_eq [q.LiesOver p] [q.IsPrime] : +theorem ramificationIdx_eq [q.LiesOver p] [q.IsPrime] : letI Sq := Localization.AtPrime q - q.ramificationIdx' R = (Module.length Sq (Sq ⧸ p.map (algebraMap R Sq))).toNat := by - rw [ramificationIdx'_def, over_def q p] + q.ramificationIdx R = (Module.length Sq (Sq ⧸ p.map (algebraMap R Sq))).toNat := by + rw [ramificationIdx_def, over_def q p] + +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_eq := ramificationIdx_eq open Localization IsLocalization.AtPrime in -theorem ramificationIdx_eq_ramificationIdx'' [IsDedekindDomain S] +theorem ramificationIdx'_eq_ramificationIdx' [IsDedekindDomain S] [q.LiesOver p] [hq : q.IsPrime] (hpS : p.map (algebraMap R S) ≠ ⊥) : - p.ramificationIdx q = q.ramificationIdx' R := by + p.ramificationIdx' q = q.ramificationIdx R := by have hq' : q ≠ ⊥ := ne_bot_of_le_ne_bot hpS (map_le_of_le_comap (q.over_def p).le) have : q.IsMaximal := hq.isMaximal hq' obtain ⟨I, hqI, h⟩ := Ideal.eq_prime_pow_mul_coprime hpS q @@ -133,99 +147,118 @@ theorem ramificationIdx_eq_ramificationIdx'' [IsDedekindDomain S] contrapose! hqI rw [sup_of_le_left hqI] exact hq.ne_top - rw [← IsDedekindDomain.ramificationIdx_eq_normalizedFactors_count hpS hq hq'] at h + rw [← IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hpS hq hq'] at h apply_fun (map (algebraMap S (Localization.AtPrime q))) at h rw [map_map, ← IsScalarTower.algebraMap_eq, Ideal.map_mul, Ideal.map_pow, map_eq_top_of_not_le (Localization.AtPrime q) hqI, mul_top, AtPrime.map_eq_maximalIdeal] at h have hSq := isDiscreteValuationRing_of_dedekind_domain S hq' (Localization.AtPrime q) - rw [ramificationIdx'_eq p q, h, hSq.length_quotient_pow_maximalIdeal, ENat.toNat_coe] + rw [ramificationIdx_eq p q, h, hSq.length_quotient_pow_maximalIdeal, ENat.toNat_coe] -theorem ramificationIdx_eq_ramificationIdx' [IsDomain R] [IsDedekindDomain S] +@[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_ramificationIdx'' := + ramificationIdx'_eq_ramificationIdx' + +theorem ramificationIdx'_eq_ramificationIdx [IsDomain R] [IsDedekindDomain S] [Module.IsTorsionFree R S] [q.LiesOver p] [hq : q.IsPrime] (hp : p ≠ ⊥) : - p.ramificationIdx q = q.ramificationIdx' R := by + p.ramificationIdx' q = q.ramificationIdx R := by have hpS : p.map (algebraMap R S) ≠ ⊥ := map_ne_bot_of_ne_bot hp - exact ramificationIdx_eq_ramificationIdx'' p q hpS + exact ramificationIdx'_eq_ramificationIdx' p q hpS + +@[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_ramificationIdx' := + ramificationIdx'_eq_ramificationIdx namespace IsDedekindDomain open UniqueFactorizationMonoid -theorem ramificationIdx'_eq_factors_count [IsDedekindDomain S] +theorem ramificationIdx_eq_factors_count [IsDedekindDomain S] [q.LiesOver p] (hp0 : p.map (algebraMap R S) ≠ ⊥) : - q.ramificationIdx' R = (factors (p.map (algebraMap R S))).count q := by + q.ramificationIdx R = (factors (p.map (algebraMap R S))).count q := by by_cases hq : q.IsPrime; swap - · rw [ramificationIdx'_of_not_isPrime q R hq, eq_comm, Multiset.count_eq_zero] + · rw [ramificationIdx_of_not_isPrime q R hq, eq_comm, Multiset.count_eq_zero] contrapose! hq exact isPrime_of_prime (prime_of_factor q hq) have hq0 : q ≠ ⊥ := ne_bot_of_le_ne_bot hp0 (map_le_of_le_comap (q.over_def p).le) - rw [← ramificationIdx_eq_ramificationIdx'' p q hp0, ramificationIdx_eq_factors_count hp0 ‹_› hq0] + rw [← ramificationIdx'_eq_ramificationIdx' p q hp0, ramificationIdx'_eq_factors_count hp0 ‹_› hq0] open UniqueFactorizationMonoid in -theorem ramificationIdx'_eq_normalizedFactors_count [IsDedekindDomain S] +theorem ramificationIdx_eq_normalizedFactors_count [IsDedekindDomain S] [q.LiesOver p] (hp0 : p.map (algebraMap R S) ≠ ⊥) : - q.ramificationIdx' R = (normalizedFactors (p.map (algebraMap R S))).count q := by - rw [← factors_eq_normalizedFactors, ← ramificationIdx'_eq_factors_count p q hp0] + q.ramificationIdx R = (normalizedFactors (p.map (algebraMap R S))).count q := by + rw [← factors_eq_normalizedFactors, ← ramificationIdx_eq_factors_count p q hp0] open UniqueFactorizationMonoid in -theorem ramificationIdx'_eq_multiplicity [IsDedekindDomain S] +theorem ramificationIdx_eq_multiplicity [IsDedekindDomain S] [q.IsPrime] [q.LiesOver p] (hp : p.map (algebraMap R S) ≠ ⊥) : - q.ramificationIdx' R = multiplicity q (p.map (algebraMap R S)) := by + q.ramificationIdx R = multiplicity q (p.map (algebraMap R S)) := by have hq : q ≠ ⊥ := ne_bot_of_le_ne_bot hp (map_le_of_le_comap (q.over_def p).le) - rw [ramificationIdx'_eq_normalizedFactors_count p q hp, + rw [ramificationIdx_eq_normalizedFactors_count p q hp, multiplicity_eq_of_emultiplicity_eq_some (emultiplicity_eq_count_normalizedFactors (prime_of_isPrime hq inferInstance).irreducible hp), normalize_eq] end IsDedekindDomain -/-- See `ramificationIdx'_tower` for a version that does not assume primality. -/ -theorem ramificationIdx'_tower' [q.IsPrime] [r.IsPrime] [r.LiesOver q] +/-- See `ramificationIdx_tower` for a version that does not assume primality. -/ +theorem ramificationIdx_tower' [q.IsPrime] [r.IsPrime] [r.LiesOver q] [Algebra (Localization.AtPrime q) (Localization.AtPrime r)] [Localization.AtPrime.IsLiesOverAlgebra q r] [Module.Flat (Localization.AtPrime q) (Localization.AtPrime r)] : - r.ramificationIdx' R = q.ramificationIdx' R * r.ramificationIdx' S := by + r.ramificationIdx R = q.ramificationIdx R * r.ramificationIdx S := by have : q.LiesOver (r.under R) := LiesOver.tower_bot r q (r.under R) let f := (Ideal.quotientEquivAlgOfEq (Localization.AtPrime r) (by rw [map_map, ← IsScalarTower.algebraMap_eq])).trans (Algebra.TensorProduct.quotIdealMapEquivTensorQuot (Localization.AtPrime r) ((r.under R).map (algebraMap R (Localization.AtPrime q)))) - rw [ramificationIdx'_def, ramificationIdx'_eq (r.under R), ramificationIdx'_eq q, + rw [ramificationIdx_def, ramificationIdx_eq (r.under R), ramificationIdx_eq q, f.toLinearEquiv.length_eq, IsLocalRing.length_baseChange, ENat.toNat_mul, ← Localization.AtPrime.map_eq_maximalIdeal, map_map, ← IsScalarTower.algebraMap_eq] -/-- See `ramificationIdx'_tower'` for a version that only assumes local flatness. -/ -theorem ramificationIdx'_tower [r.LiesOver q] [Module.Flat S T] : - r.ramificationIdx' R = q.ramificationIdx' R * r.ramificationIdx' S := by +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_tower' := ramificationIdx_tower' + +/-- See `ramificationIdx_tower'` for a version that only assumes local flatness. -/ +theorem ramificationIdx_tower [r.LiesOver q] [Module.Flat S T] : + r.ramificationIdx R = q.ramificationIdx R * r.ramificationIdx S := by by_cases hr : r.IsPrime · have : q.IsPrime := isPrime_of_liesOver r q let := Localization.AtPrime.algebraOfLiesOver q r - apply ramificationIdx'_tower' - · rw [ramificationIdx'_of_not_isPrime r R hr, ramificationIdx'_of_not_isPrime r S hr, mul_zero] + apply ramificationIdx_tower' + · rw [ramificationIdx_of_not_isPrime r R hr, ramificationIdx_of_not_isPrime r S hr, mul_zero] + +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_tower := ramificationIdx_tower + +theorem ramificationIdx_below_dvd [r.LiesOver q] [Module.Flat S T] : + q.ramificationIdx R ∣ r.ramificationIdx R := by + use r.ramificationIdx S + rw [← ramificationIdx_tower] + +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_below_dvd := ramificationIdx_below_dvd -theorem ramificationIdx'_below_dvd [r.LiesOver q] [Module.Flat S T] : - q.ramificationIdx' R ∣ r.ramificationIdx' R := by - use r.ramificationIdx' S - rw [← ramificationIdx'_tower] +theorem ramificationIdx_above_dvd [r.LiesOver q] [Module.Flat S T] : + r.ramificationIdx S ∣ r.ramificationIdx R := by + use q.ramificationIdx R + rw [mul_comm, ← ramificationIdx_tower] -theorem ramificationIdx'_above_dvd [r.LiesOver q] [Module.Flat S T] : - r.ramificationIdx' S ∣ r.ramificationIdx' R := by - use q.ramificationIdx' R - rw [mul_comm, ← ramificationIdx'_tower] +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_above_dvd := ramificationIdx_above_dvd -theorem ramificationIdx'_below_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] [Module.Flat S T] : - q.ramificationIdx' R ≤ r.ramificationIdx' R := - Nat.le_of_dvd (r.ramificationIdx'_pos R) (q.ramificationIdx'_below_dvd r) +theorem ramificationIdx_below_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] [Module.Flat S T] : + q.ramificationIdx R ≤ r.ramificationIdx R := + Nat.le_of_dvd (r.ramificationIdx_pos R) (q.ramificationIdx_below_dvd r) -theorem ramificationIdx'_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] [Module.Flat S T] : - r.ramificationIdx' S ≤ r.ramificationIdx' R := - Nat.le_of_dvd (r.ramificationIdx'_pos R) (q.ramificationIdx'_above_dvd r) +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_below_le := + ramificationIdx_below_le + +theorem ramificationIdx_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] [Module.Flat S T] : + r.ramificationIdx S ≤ r.ramificationIdx R := + Nat.le_of_dvd (r.ramificationIdx_pos R) (q.ramificationIdx_above_dvd r) + +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_above_le := ramificationIdx_above_le variable (R) in open Pointwise in @[simp] -theorem ramificationIdx'_smul {G : Type*} [Group G] [MulSemiringAction G S] [SMulCommClass G R S] - (g : G) : (g • q).ramificationIdx' R = q.ramificationIdx' R := by +theorem ramificationIdx_smul {G : Type*} [Group G] [MulSemiringAction G S] [SMulCommClass G R S] + (g : G) : (g • q).ramificationIdx R = q.ramificationIdx R := by by_cases hq : q.IsPrime; swap - · rw [ramificationIdx'_of_not_isPrime, ramificationIdx'_of_not_isPrime] <;> simpa + · rw [ramificationIdx_of_not_isPrime, ramificationIdx_of_not_isPrime] <;> simpa · let p := q.under R let f₀ := MulSemiringAction.toAlgAut G R S g have hg : g • q = q.map f₀ := q.pointwise_smul_def @@ -239,9 +272,11 @@ theorem ramificationIdx'_smul {G : Type*} [Group G] [MulSemiringAction G S] [SMu Ideal.quotientEquivAlg _ _ (AlgEquiv.ofBijective (Algebra.ofId Sq Sq') f.bijective) (by rw [IsScalarTower.algebraMap_eq R Sq Sq', Ideal.map_map, ← AlgEquiv.toAlgHom_toRingHom, AlgEquiv.toAlgHom_ofBijective, Algebra.toRingHom_ofId]) - rw [hg, ramificationIdx'_eq p q, ramificationIdx'_eq p (q.map f₀), + rw [hg, ramificationIdx_eq p q, ramificationIdx_eq p (q.map f₀), e.toLinearEquiv.length_eq, Module.length_eq_of_surjective f.surjective] +@[deprecated (since := "2026-07-01")] alias ramificationIdx'_smul := ramificationIdx_smul + end end Ideal From 8405ede16e1d3ab3ee515c0499e7822210a20bc6 Mon Sep 17 00:00:00 2001 From: Sabrina Jewson <58880148+SabrinaJewson@users.noreply.github.com> Date: Wed, 1 Jul 2026 14:49:56 +0000 Subject: [PATCH 0522/1300] feat(Order/Cover): intervals equal singletons iff (#37722) To complement `Set.Icc_eq_singleton_iff`, this introduces: - `Set.Ioc_eq_singleton_iff` / `Set.Ico_eq_singleton_iff` - `Set.Ico_eq_singleton_left_iff` / `Set.Ioc_eq_singleton_right_iff` - `Set.Ioi_eq_singleton_iff` / `Set.Iio_eq_singleton_iff` - `Set.Ioi_eq_singleton_top_iff` / `Set.Iio_eq_singleton_bot_iff` - `Set.Ioo_eq_singleton_iff` Co-authored-by: SabrinaJewson --- Mathlib/Order/Atoms.lean | 6 ++++++ Mathlib/Order/Cover.lean | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index 2eaea790ae9e8e..b91cbff332c5ee 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -115,6 +115,9 @@ lemma IsAtom.ne_bot_iff_eq (ha : IsAtom a) (hba : b ≤ a) : b ≠ ⊥ ↔ b = a theorem IsAtom.Iic_eq (h : IsAtom a) : Set.Iic a = {⊥, a} := Set.ext fun _ => h.le_iff +lemma Set.Iio_eq_singleton_bot_iff : Iio a = {⊥} ↔ IsAtom a := by + simp [IsAtom, superset_antisymm_iff, bot_lt_iff_ne_bot] + @[simp] theorem bot_covBy_iff : ⊥ ⋖ a ↔ IsAtom a := by simp only [CovBy, bot_lt_iff_ne_bot, IsAtom, not_imp_not] @@ -209,6 +212,9 @@ lemma IsCoatom.ne_top_iff_eq (ha : IsCoatom a) (hab : a ≤ b) : b ≠ ⊤ ↔ b theorem IsCoatom.Ici_eq (h : IsCoatom a) : Set.Ici a = {⊤, a} := h.dual.Iic_eq +lemma Set.Ioi_eq_singleton_top_iff : Ioi a = {⊤} ↔ IsCoatom a := by + simp [IsCoatom, superset_antisymm_iff, lt_top_iff_ne_top] + @[simp] theorem covBy_top_iff : a ⋖ ⊤ ↔ IsCoatom a := toDual_covBy_toDual_iff.symm.trans bot_covBy_iff diff --git a/Mathlib/Order/Cover.lean b/Mathlib/Order/Cover.lean index 869ec148622016..ba26438da4ee20 100644 --- a/Mathlib/Order/Cover.lean +++ b/Mathlib/Order/Cover.lean @@ -384,6 +384,19 @@ theorem CovBy.Ico_eq (h : a ⋖ b) : Ico a b = {a} := by theorem CovBy.Icc_eq (h : a ⋖ b) : Icc a b = {a, b} := h.wcovBy.Icc_eq +@[to_dual] +theorem Set.Ico_eq_singleton_iff : Ico a b = {c} ↔ a = c ∧ a ⋖ b where + mp h := by + simp_rw [Set.ext_iff, mem_Ico, mem_singleton_iff] at h + have ⟨hac, hcb⟩ := (h c).mpr rfl + obtain rfl := (h a).mp ⟨le_refl a, hac.trans_lt hcb⟩ + exact ⟨rfl, ⟨hcb, fun d hcd hdb ↦ hcd.ne ((h d).mp ⟨hcd.le, hdb⟩).symm⟩⟩ + mpr := fun ⟨rfl, hcov⟩ ↦ hcov.Ico_eq + +@[to_dual Ioc_eq_singleton_right_iff] +lemma Set.Ico_eq_singleton_left_iff : Ico a b = {a} ↔ a ⋖ b := by + simp [Ico_eq_singleton_iff] + end PartialOrder section LinearOrder @@ -409,6 +422,26 @@ theorem CovBy.Iio_eq (h : a ⋖ b) : Iio b = Iic a := by theorem CovBy.Ioo_eq_Ico (h : a ⋖ b) (c : α) : Ioo a c = Ico b c := subset_antisymm (fun _x hx ↦ ⟨h.ge_of_gt hx.1, hx.2⟩) <| Ico_subset_Ioo_left h.lt +@[to_dual none] +theorem Set.Ioo_eq_singleton_iff : Ioo a b = {c} ↔ a ⋖ c ∧ c ⋖ b where + mp h := by + simp_rw [Set.ext_iff, mem_Ioo, mem_singleton_iff] at h + have ⟨hac, hcb⟩ := (h c).mpr rfl + exact ⟨⟨hac, fun d had hdc ↦ hdc.ne ((h d).mp ⟨had, hdc.trans hcb⟩)⟩, + ⟨hcb, fun d hcd hdb ↦ hcd.ne ((h d).mp ⟨hac.trans hcd, hdb⟩).symm⟩⟩ + mpr := fun ⟨hac, hcb⟩ ↦ by + rw [← Ioc_union_Ico_eq_Ioo hac.lt hcb.lt, hac.Ioc_eq, hcb.Ico_eq, union_self] + +@[to_dual] +theorem Set.Ioi_eq_singleton_iff : Ioi a = {b} ↔ IsTop b ∧ a ⋖ b where + mp h := by + simp_rw [Set.ext_iff, mem_Ioi, mem_singleton_iff] at h + have hb : a < b := (h b).mpr rfl + exact ⟨fun c ↦ not_lt.mp fun hc ↦ hc.ne.symm ((h c).mp (hb.trans hc)), + ⟨hb, fun c hac hcb ↦ hcb.ne ((h c).mp hac)⟩⟩ + mpr := fun ⟨hb, hab⟩ ↦ by + cases b, hb using IsTop.rec; rwa [← Ioc_top, Ioc_eq_singleton_right_iff] + @[to_dual unique_right] theorem CovBy.unique_left (ha : a ⋖ c) (hb : b ⋖ c) : a = b := (hb.le_of_lt ha.lt).antisymm <| ha.le_of_lt hb.lt From aec43494bb90f852a6f55b61be0bcefef0cdec4d Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Wed, 1 Jul 2026 15:35:11 +0000 Subject: [PATCH 0523/1300] feat(CategoryTheory/Triangulated/WeakKernels): pretriangulated categories have weak kernels (#41162) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove that pretriangulated categories have weak kernels. More precisely, if `f : X ⟶ Y` is a morphism in a pretriangulated category and if we complete it to a distinguished triangle `Z ⟶ X ⟶ Y ⟶ Z⟦1⟧`, then the first morphism `Z ⟶ Y` of that triangle is a weak kernel of `f`. - [x] depends on: #41075 Co-authored-by: morel --- Mathlib.lean | 1 + .../Triangulated/WeakKernels.lean | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 Mathlib/CategoryTheory/Triangulated/WeakKernels.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7c01f4ec4aadf7..af8a66d0fcb56b 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3497,6 +3497,7 @@ public import Mathlib.CategoryTheory.Triangulated.TStructure.TruncLEGT public import Mathlib.CategoryTheory.Triangulated.TStructure.TruncLTGE public import Mathlib.CategoryTheory.Triangulated.TriangleShift public import Mathlib.CategoryTheory.Triangulated.Triangulated +public import Mathlib.CategoryTheory.Triangulated.WeakKernels public import Mathlib.CategoryTheory.Triangulated.Yoneda public import Mathlib.CategoryTheory.Types.Basic public import Mathlib.CategoryTheory.Types.Epimorphisms diff --git a/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean b/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean new file mode 100644 index 00000000000000..1e7ed57910eb57 --- /dev/null +++ b/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean @@ -0,0 +1,52 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Triangulated.Pretriangulated +public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakKernels + + +/-! +# Weak kernels in pretriangulated categories + +We prove that pretriangulated categories have weak kernels: if `f : X ⟶ Y` is a morphism in +a pretriangulated category and if we complete it to a distinguished triangle +`Z ⟶ X ⟶ Y ⟶ Z⟦1⟧`, then the first morphism `Z ⟶ Y` of that triangle is a weak kernel of `f`. + +TODO: Weak cokernels. +-/ + +@[expose] public section + +noncomputable section + +namespace CategoryTheory.Pretriangulated + +open Limits Category Preadditive Pretriangulated + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] + [∀ n : ℤ, Functor.Additive (shiftFunctor C n)] [Pretriangulated C] + +variable {X Y : C} (f : X ⟶ Y) + +/-- If `T` is a distinguished triangle, then `T.mor₁` defines a kernel fork for `T.mor₂`. -/ +def kernelForkOfDistTriangle (T : Triangle C) (dT : T ∈ distTriang C) : + KernelFork T.mor₂ := KernelFork.ofι T.mor₁ (comp_distTriang_mor_zero₁₂ _ dT) + +/-- If `T` is a distinguished triangle, then the kernel fork for `T.mor₂` defined in +`kernelForkOfDistTriangle` is a weak kernel fork. -/ +def isWeakLimitKernelForkOfDistTriangle (T : Triangle C) (dT : T ∈ distTriang C) : + IsWeakLimit (kernelForkOfDistTriangle _ dT) := + Fork.IsWeakLimit.mk' _ + (fun s ↦ ⟨_, (T.coyoneda_exact₂ dT _ (KernelFork.condition s)).choose_spec.symm⟩) + +/-- A pretriangulated category has weak kernels. -/ +instance : HasWeakKernels C where + hasWeakLimit f := ⟨by + obtain ⟨K, i, p, h⟩ := distinguished_cocone_triangle₁ f + exact ⟨_, isWeakLimitKernelForkOfDistTriangle _ h⟩⟩ + +end CategoryTheory.Pretriangulated From a901d484f045b331be5a1b26ba389644e5f4f0f4 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Wed, 1 Jul 2026 15:54:56 +0000 Subject: [PATCH 0524/1300] feat(Analysis/Complex/RealDeriv,CauchyIntegral): real and complex differentiability lemmas (#41176) Some easy `@[fun_prop]` lemmas on the real-differentiability of various complex functions, and the fact that the derivative of an entire function is entire. ~~Also some very minor golf of `CauchyIntegral.lean`.~~ Co-authored-by: Terence Tao --- Mathlib/Analysis/Complex/CauchyIntegral.lean | 5 +++ Mathlib/Analysis/Complex/RealDeriv.lean | 32 ++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/Mathlib/Analysis/Complex/CauchyIntegral.lean b/Mathlib/Analysis/Complex/CauchyIntegral.lean index 8dbb1d187028aa..7ab35a8eefd071 100644 --- a/Mathlib/Analysis/Complex/CauchyIntegral.lean +++ b/Mathlib/Analysis/Complex/CauchyIntegral.lean @@ -656,6 +656,11 @@ protected theorem _root_.Differentiable.contDiff ContDiff ℂ n f := contDiff_iff_contDiffAt.mpr fun z ↦ (hf.analyticAt z).contDiffAt +@[fun_prop] +theorem _root_.Differentiable.deriv {f : ℂ → E} (hf : Differentiable ℂ f) : + Differentiable ℂ (deriv f) := + hf.contDiff.differentiable_deriv_two + /-- When `f : ℂ → E` is differentiable, the `cauchyPowerSeries f z R` represents `f` as a power series centered at `z` in the entirety of `ℂ`, regardless of `R : ℝ≥0`, with `0 < R`. -/ protected theorem _root_.Differentiable.hasFPowerSeriesOnBall {f : ℂ → E} (h : Differentiable ℂ f) diff --git a/Mathlib/Analysis/Complex/RealDeriv.lean b/Mathlib/Analysis/Complex/RealDeriv.lean index c9888b6c0f21ce..dbf10e546853b9 100644 --- a/Mathlib/Analysis/Complex/RealDeriv.lean +++ b/Mathlib/Analysis/Complex/RealDeriv.lean @@ -109,4 +109,36 @@ theorem HasDerivWithinAt.ofReal_comp {f : ℝ → ℝ} {s : Set ℝ} {u : ℝ} simpa only [Function.comp_apply, ofRealCLM_apply] using! ofRealCLM.hasFDerivAt.comp_hasDerivWithinAt z hf +@[fun_prop] +lemma Complex.differentiable_re : Differentiable ℝ Complex.re := reCLM.differentiable + +@[fun_prop] +lemma Complex.differentiable_im : Differentiable ℝ Complex.im := imCLM.differentiable + +@[fun_prop] +lemma Complex.differentiable_ofReal : Differentiable ℝ Complex.ofReal := ofRealCLM.differentiable + +open ComplexConjugate in +@[fun_prop] +lemma Complex.differentiable_conj : Differentiable ℝ (conj : ℂ → ℂ) := conjCLE.differentiable + +variable {f : ℂ → E} {s : Set ℂ} {z : ℂ} + +@[fun_prop] +lemma Differentiable.real_of_complex (hf : Differentiable ℂ f) : Differentiable ℝ f := + hf.restrictScalars (𝕜 := ℝ) + +@[fun_prop] +lemma DifferentiableAt.real_of_complex (hf : DifferentiableAt ℂ f z) : DifferentiableAt ℝ f z := + hf.restrictScalars (𝕜 := ℝ) + +@[fun_prop] +lemma DifferentiableWithinAt.real_of_complex (hf : DifferentiableWithinAt ℂ f s z) : + DifferentiableWithinAt ℝ f s z := + hf.restrictScalars (𝕜 := ℝ) + +@[fun_prop] +lemma DifferentiableOn.real_of_complex (hf : DifferentiableOn ℂ f s) : DifferentiableOn ℝ f s := + hf.restrictScalars (𝕜 := ℝ) + end RealDerivOfComplex From 66e0cf207c51b61a19b05bc1cfca5ece3daec625 Mon Sep 17 00:00:00 2001 From: Marygold-Dusk <224445679+Marygold-Dusk@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:10:50 +0000 Subject: [PATCH 0525/1300] feat: submersions are `C^n` (#40547) The conventional textbook definition demands that a submersion be smooth. When asking for the submersion to have local slice charts (as we do), this implies smoothness automatically. Co-authored-by: Michael Rothgang . Co-authored-by: Michael Rothgang Co-authored-by: Samantha M. Naranjo Co-authored-by: Samantha Naranjo --- Mathlib/Geometry/Manifold/Submersion.lean | 64 ++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Submersion.lean b/Mathlib/Geometry/Manifold/Submersion.lean index af48f831ada3a6..95d305ffd1405f 100644 --- a/Mathlib/Geometry/Manifold/Submersion.lean +++ b/Mathlib/Geometry/Manifold/Submersion.lean @@ -5,10 +5,12 @@ Authors: Michael Rothgang, Samantha Naranjo Guevara -/ module -public import Mathlib.Geometry.Manifold.IsManifold.ExtChartAt public import Mathlib.Geometry.Manifold.LocalSourceTargetProperty public import Mathlib.Analysis.Normed.Module.Shrink public import Mathlib.Topology.Algebra.Module.TransferInstance +public import Mathlib.Geometry.Manifold.ContMDiff.Atlas +public import Mathlib.Geometry.Manifold.ContMDiff.NormedSpace +public import Mathlib.Geometry.Manifold.Notation /-! # Smooth submersions @@ -46,6 +48,9 @@ if there exist charts near `x` and `f x` in which `f` looks like the standard pr the set of points where `IsSubmersionAt(OfComplement)` holds is open. * `IsSubmersionAt.prodMap` and `IsSubmersion.prodMap`: the product of two submersions (at a point) is a submersion (at the product point). +* `IsSubmersionAt.contMDiffAt`: if `f` is a submersion at `x`, it is `C^n` at `x`. +* `IsSubmersion.contMDiff`: if `f` is a submersion, it is automatically `C^n` + in the sense of `ContMDiff`. ## Implementation notes @@ -58,8 +63,6 @@ The implementation strategy is identical to the one for immersions. See the impl ## TODO * The converse to `IsSubmersionAtOfComplement.congr_F` also holds: any two complements are isomorphic, as they are isomorphic to the kernel of the differential `mfderiv I J f x`. -* `IsSubmersionAt.contMDiffAt`: if f is a submersion at `x`, it is `C^n` at `x`. -* `IsSubmersion.contMDiff`: if f is a submersion, it is `C^n`. * If `f` is a submersion at `x`, its differential `mfderiv I J f x` admits a continuous right inverse, in particular is surjective. * If `f : M → N` is a map between Banach manifolds, `mfderiv I J f x` having a continuous right @@ -87,9 +90,8 @@ This will be the topic of Samantha Naranjo's master's thesis, and it's nice to c public noncomputable section -open scoped Topology ContDiff - -open Function Set +open scoped Topology ContDiff Manifold +open OpenPartialHomeomorph Function Set namespace Manifold @@ -142,7 +144,7 @@ NB. We don't know the particular atlasses used for `M` and `N`, so asking for ` in the `atlas` would be too optimistic: lying in the `maximalAtlas` is sufficient. This definition has a fixed parameter `F`, which is a choice of complement of `E''` in `E`: -being an immersion at `x` includes a choice of linear isomorphism between `E'' × F` and `E`. +being an submersion at `x` includes a choice of linear isomorphism between `E'' × F` and `E`. While the particular choice of complement is often not important, choosing a complement is useful in some settings, such as proving that embedded submanifolds are locally given either by an immersion or a submersion. @@ -236,6 +238,10 @@ lemma source_subset_preimage_source (h : IsSubmersionAtOfComplement F I J n f x) h.domChart.source ⊆ f ⁻¹' h.codChart.source := LiftSourceTargetPropertyAt.source_subset_preimage_source h +lemma mapsto_domChart_source_codChart_source (h : IsSubmersionAtOfComplement F I J n f x) : + MapsTo f h.domChart.source h.codChart.source := + h.source_subset_preimage_source + /-- A linear equivalence `E ≃L[𝕜] E'' × F` which belongs to the data of a submersion `f` at `x`: the particular equivalence is arbitrary, but this choice matches the witnesses given by `h.domChart` and `h.codChart`. -/ @@ -353,6 +359,31 @@ lemma isSubmersionAt (h : IsSubmersionAtOfComplement F I J n f x) : use h.smallComplement, by infer_instance, by infer_instance exact (IsSubmersionAtOfComplement.congr_F h.smallEquiv).mp h +/-- If `f` is a `C^n` submersion at `x`, then `f` is `C^n` on its domain chart's source, +in particular on an open neighbourhood of `x`. + +Prefer using `IsSubmersionAtOfComplement.contMDiffAt` instead. -/ +theorem contMDiffOn (h : IsSubmersionAtOfComplement F I J n f x) : + ContMDiffOn I J n f h.domChart.source := by + rw [← contMDiffOn_writtenInExtend_iff h.domChart_mem_maximalAtlas + h.codChart_mem_maximalAtlas le_rfl h.mapsto_domChart_source_codChart_source, + ← h.domChart.extend_target_eq_image_source] + have : CMDiff n (Prod.fst ∘ h.equiv) := by + -- Note that we cannot use `h₁.comp contMDiff_fst` since `h₁` and `contMDiff_fst` require + -- different models with corners on `E'' × F`. The former uses `𝓘(𝕜, E'' × F)` while the latter + -- uses `(𝓘(𝕜, E'')).prod (𝓘(𝕜, F)`. + have h₁ : ContMDiff 𝓘(𝕜, E) 𝓘(𝕜, E'' × F) n h.equiv := by + rw [contMDiff_iff_contDiff] + exact h.equiv.contDiff + apply ContMDiff.comp ?_ h₁ + rw [contMDiff_iff_contDiff] + exact contDiff_fst + exact this.contMDiffOn.congr h.writtenInCharts + +/-- A `C^n` submersion at `x` is `C^n` at `x`. -/ +theorem contMDiffAt (h : IsSubmersionAtOfComplement F I J n f x) : CMDiffAt n f x := + h.contMDiffOn.contMDiffAt (h.domChart.open_source.mem_nhds (mem_domChart_source h)) + end IsSubmersionAtOfComplement namespace IsSubmersionAt @@ -492,6 +523,17 @@ theorem prodMap {f : M → N} {g : M' → N'} {x' : M'} hf.isSubmersionAtOfComplement_complement.prodMap hg.isSubmersionAtOfComplement_complement |>.isSubmersionAt +/-- If `f` is a submersion at `x`, then `f` is `C^n` on its domain chart's source, +in particular on an open neighbourhood of `x`.` + +Prefer using `IsSubmersionAt.contMDiffAt` instead -/ +theorem contMDiffOn (h : IsSubmersionAt I J n f x) : CMDiff[h.domChart.source] n f := + h.isSubmersionAtOfComplement_complement.contMDiffOn + +/-- A `C^n` submersion at `x` is `C^n` at `x`. -/ +theorem contMDiffAt (h : IsSubmersionAt I J n f x) : CMDiffAt n f x := + h.isSubmersionAtOfComplement_complement.contMDiffAt + end IsSubmersionAt variable (F I J n) in @@ -576,6 +618,10 @@ protected lemma id [IsManifold I n M] : IsSubmersionOfComplement PUnit I I n (@i rw [(chartAt H x).right_inv (by simp_all), I.right_inv (by simp_all)] simpa +/-- A `C^n` submersion is `C^n` -/ +theorem contMDiff (h : IsSubmersionOfComplement F I J n f) : CMDiff n f := + fun x ↦ (h x).contMDiffAt + end IsSubmersionOfComplement namespace IsSubmersion @@ -616,6 +662,10 @@ protected lemma id [IsManifold I n M] : IsSubmersion I I n (@id M) := by use PUnit, by infer_instance, by infer_instance exact IsSubmersionOfComplement.id +/-- A `C^n` submersion is `C^n` -/ +theorem contMDiff (h : IsSubmersion I J n f) : CMDiff n f := + h.isSubmersionOfComplement_complement.contMDiff + end IsSubmersion end Manifold From 376675027013a468cc3dcf4ce0ff5c8001c563e8 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Wed, 1 Jul 2026 17:12:24 +0000 Subject: [PATCH 0526/1300] feat: characterize when projections are almost 0 or almost id (#41038) in the sense of `LinearMap.FiniteRangeSetoid`. --- .../Algebra/Module/LinearMap/FiniteRange.lean | 31 +++++++++++++++++++ Mathlib/Data/Setoid/Basic.lean | 3 ++ 2 files changed, 34 insertions(+) diff --git a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean index a04166c0c38750..7524d72a26c15f 100644 --- a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean +++ b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean @@ -235,6 +235,13 @@ lemma equiv_iff_hasFiniteRange [IsNoetherianRing K] {u v : V →ₗ[K] V₂} : u ≈ v ↔ (u - v).HasFiniteRange := by rw [equiv_iff_hasNoetherianRange, hasNoetherianRange_iff_hasFiniteRange] +lemma equiv_zero_iff_hasNoetherianRange {u : V →ₗ[K] V₂} : u ≈ 0 ↔ u.HasNoetherianRange := by + simp [equiv_iff_hasNoetherianRange] + +lemma equiv_zero_iff_hasFiniteRange [IsNoetherianRing K] {u : V →ₗ[K] V₂} : + u ≈ 0 ↔ u.HasFiniteRange := by + simp [equiv_iff_hasFiniteRange] + lemma equiv_iff_isNoetherian_quotient_eqLocus {u v : V →ₗ[K] V₂} : u ≈ v ↔ IsNoetherian K (V ⧸ eqLocus u v) := by rw [equiv_iff_hasNoetherianRange, hasNoetherianRange_iff_quotient_ker, eqLocus_eq_ker_sub] @@ -269,6 +276,23 @@ lemma equiv_comp {u v : V →ₗ[K] V₂} {u' v' : V₂ →ₗ[K] V₃} (h : u u' ∘ₗ u ≈ v' ∘ₗ v := by grw [equiv_comp_right h', equiv_comp_left h] +lemma projection_equiv_zero_iff_isNoetherian {S T : Submodule K V} (hST : IsCompl S T) : + S.projection T hST ≈ 0 ↔ IsNoetherian K S := by + rw [equiv_zero_iff_hasNoetherianRange, hasNoetherianRange_iff_range, range_projection] + +lemma projection_equiv_zero {S T : Submodule K V} [IsNoetherian K S] (hST : IsCompl S T) : + S.projection T hST ≈ 0 := + projection_equiv_zero_iff_isNoetherian hST |>.mpr inferInstance + +lemma projection_equiv_id_iff_isNoetherian {S T : Submodule K V} (hST : IsCompl S T) : + S.projection T hST ≈ id ↔ IsNoetherian K T := by + rw [Setoid.comm, equiv_iff_hasNoetherianRange, ← projection_eq_id_sub_projection, + hasNoetherianRange_iff_range, range_projection] + +lemma projection_equiv_id {S T : Submodule K V} [IsNoetherian K T] (hST : IsCompl S T) : + S.projection T hST ≈ id := + projection_equiv_id_iff_isNoetherian hST |>.mpr inferInstance + end FiniteRangeSetoid end Setoid @@ -432,6 +456,13 @@ lemma IsQuasiInverse.of_comp_right {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V (w ∘ₗ v).IsQuasiInverse u := ⟨hw.1, IsRightQuasiInverse.of_comp_right hv.1 hw.2⟩ +lemma isQuasiInverse_subtype_projectionOnto {S T : Submodule K V} [IsNoetherian K T] + (hST : IsCompl S T) : + IsQuasiInverse S.subtype (S.projectionOnto T hST) := by + constructor + · grw [IsLeftQuasiInverse, ← FiniteRangeSetoid.projection_equiv_id hST, projection] + · simp [IsRightQuasiInverse, projectionOnto_comp_subtype] + end QuasiInverse end LinearMap diff --git a/Mathlib/Data/Setoid/Basic.lean b/Mathlib/Data/Setoid/Basic.lean index 29e735ede15619..993671add13f70 100644 --- a/Mathlib/Data/Setoid/Basic.lean +++ b/Mathlib/Data/Setoid/Basic.lean @@ -69,6 +69,9 @@ theorem trans' (r : Setoid α) : ∀ {x y z}, r x y → r y z → r x z := r.ise theorem comm' (s : Setoid α) {x y} : s x y ↔ s y x := ⟨s.symm', s.symm'⟩ +theorem comm [Setoid α] {x y : α} : x ≈ y ↔ y ≈ x := + ⟨Setoid.symm, Setoid.symm⟩ + open scoped Function -- required for scoped `on` notation /-- The kernel of a function is an equivalence relation. -/ From b49d30f68e4cf14987f1724c5db8b3b193af6b9f Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:54:30 +0000 Subject: [PATCH 0527/1300] feat(LinearAlgebra/Matrix/Nondegenerate): more API and generalize to non-domains (#39634) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Syntactically generalize the bilinear form identities to non-square matrices - Prove iff and transpose theorems for `SeparatingLeft`/`SeparatingRight`/`Nondegenerate` - Prove `M *ᵥ v = 0 → v = 0` and `v ᵥ* M = 0 → v = 0` given `Nondegenerate` (extracted from the existing `eq_zero_of_*_eq_zero`) - Generalize `M.det ≠ 0 → M.Nondegenerate` to `M.det ∈ R⁰ → M.Nondegenerate` (over any `CommRing`) - Add `M *ᵥ v = 0 → v = 0` and `v ᵥ* M = 0 → v = 0` theorems given `M.det ∈ R⁰` - Allow `NonUnitalNonAssocSemiring`s in the `def`s --- Mathlib/Data/Matrix/Mul.lean | 8 +- .../LinearAlgebra/Matrix/Nondegenerate.lean | 123 ++++++++++++++---- .../LinearAlgebra/Matrix/ToLinearEquiv.lean | 73 ++++++----- 3 files changed, 139 insertions(+), 65 deletions(-) diff --git a/Mathlib/Data/Matrix/Mul.lean b/Mathlib/Data/Matrix/Mul.lean index e9b9cc920a2be9..19bcf3414eab9c 100644 --- a/Mathlib/Data/Matrix/Mul.lean +++ b/Mathlib/Data/Matrix/Mul.lean @@ -1093,13 +1093,13 @@ theorem vecMul_transpose [Fintype n] (A : Matrix m n α) (x : n → α) : x ᵥ* apply dotProduct_comm /-- Bilinear form identity: `x ⬝ᵥ Aᵀ *ᵥ y = y ⬝ᵥ A *ᵥ x` for commutative semirings. -/ -theorem dotProduct_transpose_mulVec [Fintype m] (A : Matrix m m α) (x y : m → α) : - x ⬝ᵥ Aᵀ *ᵥ y = y ⬝ᵥ A *ᵥ x := by +theorem dotProduct_transpose_mulVec [Fintype m] [Fintype n] (A : Matrix m n α) (x : n → α) + (y : m → α) : x ⬝ᵥ Aᵀ *ᵥ y = y ⬝ᵥ A *ᵥ x := by rw [dotProduct_mulVec, dotProduct_comm, vecMul_transpose] /-- Bilinear form identity: `(x ᵥ* Aᵀ) ⬝ᵥ y = (y ᵥ* A) ⬝ᵥ x` for commutative semirings. -/ -theorem dotProduct_vecMul_transpose [Fintype m] (A : Matrix m m α) (x y : m → α) : - (x ᵥ* Aᵀ) ⬝ᵥ y = (y ᵥ* A) ⬝ᵥ x := by +theorem dotProduct_vecMul_transpose [Fintype m] [Fintype n] (A : Matrix m n α) (x : n → α) + (y : m → α) : (x ᵥ* Aᵀ) ⬝ᵥ y = (y ᵥ* A) ⬝ᵥ x := by simpa [dotProduct_mulVec] using dotProduct_transpose_mulVec (A := A) (x := x) (y := y) theorem mulVec_vecMul [Fintype n] [Fintype o] (A : Matrix m n α) (B : Matrix o n α) (x : o → α) : diff --git a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean index b83592c1b37c2a..ef2b5bee37197c 100644 --- a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean @@ -26,7 +26,7 @@ namespace Matrix section Finite -variable {m n R A : Type*} [CommRing R] [Finite m] [Finite n] (M : Matrix m n R) +variable {m n R A : Type*} [NonUnitalNonAssocSemiring R] [Finite m] [Finite n] (M : Matrix m n R) attribute [local instance] Fintype.ofFinite @@ -39,29 +39,87 @@ def SeparatingLeft : Prop := (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) /-- A matrix `M` is nondegenerate if it is both left-separating and right-separating. -/ +@[mk_iff] structure Nondegenerate (M : Matrix m n R) : Prop where separatingLeft : SeparatingLeft M separatingRight : SeparatingRight M end Finite -variable {m n R A : Type*} [CommRing R] [Fintype m] [Fintype n] [CommRing A] [IsDomain A] - {M : Matrix m n R} +variable {m n R : Type*} [CommRing R] {M : Matrix m n R} -lemma separatingRight_def : M.SeparatingRight ↔ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0) → w = 0) := by +lemma separatingRight_def [Fintype m] [Fintype n] : + M.SeparatingRight ↔ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0) → w = 0) := by refine forall_congr' fun w ↦ ⟨fun hM hw ↦ hM ?_, fun hM hw ↦ hM ?_⟩ <;> convert! hw -lemma separatingLeft_def : M.SeparatingLeft ↔ (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) := by +lemma separatingLeft_def [Fintype m] [Fintype n] : + M.SeparatingLeft ↔ (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) := by refine forall_congr' fun v ↦ ⟨fun hM hv ↦ hM ?_, fun hM hv ↦ hM ?_⟩ <;> convert! hv -lemma nondegenerate_def : M.Nondegenerate ↔ - (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) ∧ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0) → w = 0) := by +lemma nondegenerate_def [Fintype m] [Fintype n] : + M.Nondegenerate ↔ + (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) ∧ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0) → w = 0) := by constructor · exact fun h ↦ ⟨separatingLeft_def.mp h.1, separatingRight_def.mp h.2⟩ · exact fun h ↦ ⟨separatingLeft_def.mpr h.1, separatingRight_def.mpr h.2⟩ +theorem separatingLeft_iff_forall_vecMul_eq_zero [Fintype m] [Finite n] : + M.SeparatingLeft ↔ ∀ v, v ᵥ* M = 0 → v = 0 := by + have := Fintype.ofFinite n + rw [separatingLeft_def] + refine ⟨fun h v hv ↦ h v fun w ↦ ?_, fun h w hw ↦ h w <| funext fun i ↦ ?_⟩ + · simp [dotProduct_mulVec, hv] + · classical simpa using! hw <| Pi.single i 1 + +theorem separatingRight_iff_forall_mulVec_eq_zero [Finite m] [Fintype n] : + M.SeparatingRight ↔ ∀ v, M *ᵥ v = 0 → v = 0 := by + have := Fintype.ofFinite m + rw [separatingRight_def] + refine ⟨fun h v hv ↦ h v fun w ↦ ?_, fun h w hw ↦ h w <| funext fun i ↦ ?_⟩ + · simp [hv] + · classical simpa using hw <| Pi.single i 1 + +theorem SeparatingLeft.eq_zero_of_vecMul_eq_zero [Fintype m] [Finite n] (hM : M.SeparatingLeft) + {v : m → R} (hv : v ᵥ* M = 0) : v = 0 := + separatingLeft_iff_forall_vecMul_eq_zero.mp hM v hv + +theorem SeparatingRight.eq_zero_of_mulVec_eq_zero [Finite m] [Fintype n] (hM : M.SeparatingRight) + {v : n → R} (hv : M *ᵥ v = 0) : v = 0 := + separatingRight_iff_forall_mulVec_eq_zero.mp hM v hv + +theorem nondegenerate_iff_forall_vecMul_and_mulVec_eq_zero [Fintype m] [Fintype n] : + M.Nondegenerate ↔ (∀ v, v ᵥ* M = 0 → v = 0) ∧ (∀ v, M *ᵥ v = 0 → v = 0) := by + rw [nondegenerate_iff, separatingLeft_iff_forall_vecMul_eq_zero, + separatingRight_iff_forall_mulVec_eq_zero] + +@[simp] +theorem separatingLeft_transpose_iff [Finite m] [Finite n] : + Mᵀ.SeparatingLeft ↔ M.SeparatingRight := by + have := Fintype.ofFinite m + have := Fintype.ofFinite n + simp_rw [separatingLeft_def, separatingRight_def, dotProduct_transpose_mulVec] + +alias ⟨_, SeparatingRight.separatingLeft_transpose⟩ := separatingLeft_transpose_iff + +@[simp] +theorem separatingRight_transpose_iff [Finite m] [Finite n] : + Mᵀ.SeparatingRight ↔ M.SeparatingLeft := by + have := Fintype.ofFinite m + have := Fintype.ofFinite n + simp_rw [separatingRight_def, separatingLeft_def, dotProduct_transpose_mulVec] + +alias ⟨_, SeparatingLeft.separatingRight_transpose⟩ := separatingRight_transpose_iff + +@[simp] +theorem nondegenerate_transpose_iff [Finite m] [Finite n] : Mᵀ.Nondegenerate ↔ M.Nondegenerate := by + simp [nondegenerate_iff, and_comm] + +alias ⟨_, Nondegenerate.transpose⟩ := nondegenerate_transpose_iff + +variable [Fintype m] [Fintype n] + /-- If `M` is nondegenerate and `w * M * v = 0` for all `w`, then `v = 0`. -/ theorem Nondegenerate.eq_zero_of_ortho (hM : Nondegenerate M) {v : m → R} (hv : ∀ w, v ⬝ᵥ M *ᵥ w = 0) : v = 0 := @@ -73,42 +131,51 @@ theorem Nondegenerate.exists_not_ortho_of_ne_zero (hM : Nondegenerate M) not_forall.mp (mt hM.eq_zero_of_ortho hv) /-- If `M` is nondegenerate and `w * M * v = 0` for all `v`, then `w = 0`. -/ -theorem Nondegenerate.eq_zero_of_ortho' {M : Matrix m n R} (hM : Nondegenerate M) {w : n → R} +theorem Nondegenerate.eq_zero_of_ortho' (hM : Nondegenerate M) {w : n → R} (hw : ∀ v, v ⬝ᵥ M *ᵥ w = 0) : w = 0 := (nondegenerate_def.mp hM).2 w hw /-- If `M` is nondegenerate and `w ≠ 0`, then there is some `v` such that `v * M * w ≠ 0`. -/ -theorem Nondegenerate.exists_not_ortho_of_ne_zero' {M : Matrix m n R} (hM : Nondegenerate M) - {w : n → R} (hw : w ≠ 0) : ∃ v, v ⬝ᵥ M *ᵥ w ≠ 0 := +theorem Nondegenerate.exists_not_ortho_of_ne_zero' (hM : Nondegenerate M) {w : n → R} (hw : w ≠ 0) : + ∃ v, v ⬝ᵥ M *ᵥ w ≠ 0 := not_forall.mp (mt hM.eq_zero_of_ortho' hw) section Determinant -variable [DecidableEq m] {M : Matrix m m A} +variable [DecidableEq m] {M : Matrix m m R} + +open scoped nonZeroDivisors + +private theorem SeparatingLeft.of_det_mem_nonZeroDivisors (hM : M.det ∈ R⁰) : M.SeparatingLeft := by + refine separatingLeft_def.mpr fun v h ↦ funext fun i ↦ mem_nonZeroDivisors_iff_left.mp hM _ ?_ + simpa using h <| M.cramer <| Pi.single i 1 + +theorem Nondegenerate.of_det_mem_nonZeroDivisors (hM : M.det ∈ R⁰) : M.Nondegenerate where + separatingLeft := .of_det_mem_nonZeroDivisors hM + separatingRight := separatingLeft_transpose_iff.mp <| .of_det_mem_nonZeroDivisors <| by simpa -/-- If `M` is square and has nonzero determinant, then `M` as a bilinear form on `n → A` is +/-- If `M` is square and has nonzero determinant, then `M` as a bilinear form on `n → R` is nondegenerate. The "iff" implication, `nondegenerate_iff_det_ne_zero`, is proved in a later file. See also `BilinForm.nondegenerateOfDetNeZero'` and `BilinForm.nondegenerateOfDetNeZero`. -/ -theorem nondegenerate_of_det_ne_zero (hM : M.det ≠ 0) : Nondegenerate M := by - refine nondegenerate_def.mpr ⟨fun v h ↦ ?_, fun w h ↦ ?_⟩ - · ext i - specialize h (M.cramer (Pi.single i 1)) - simp_all - · ext i - contrapose! h - use Pi.single i 1 ᵥ* M.adjugate - rw [dotProduct_mulVec, vecMul_vecMul, adjugate_mul] - simp_all [dotProduct, smul_apply, smul_eq_mul, Matrix.one_apply] - -theorem eq_zero_of_vecMul_eq_zero (hM : M.det ≠ 0) {v : m → A} +theorem nondegenerate_of_det_ne_zero [NoZeroDivisors R] (hM : M.det ≠ 0) : M.Nondegenerate := + .of_det_mem_nonZeroDivisors <| mem_nonZeroDivisors_of_ne_zero hM + +theorem eq_zero_of_det_mem_nonZeroDivisors_of_vecMul_eq_zero (hM : M.det ∈ R⁰) + {v : m → R} (hv : v ᵥ* M = 0) : v = 0 := + Nondegenerate.of_det_mem_nonZeroDivisors hM |>.separatingLeft.eq_zero_of_vecMul_eq_zero hv + +theorem eq_zero_of_vecMul_eq_zero [NoZeroDivisors R] (hM : M.det ≠ 0) {v : m → R} (hv : v ᵥ* M = 0) : v = 0 := - (nondegenerate_of_det_ne_zero hM).eq_zero_of_ortho fun w => by - rw [dotProduct_mulVec, hv, zero_dotProduct] + nondegenerate_of_det_ne_zero hM |>.separatingLeft.eq_zero_of_vecMul_eq_zero hv + +theorem eq_zero_of_det_mem_nonZeroDivisors_of_mulVec_eq_zero (hM : M.det ∈ R⁰) + {v : m → R} (hv : M *ᵥ v = 0) : v = 0 := + Nondegenerate.of_det_mem_nonZeroDivisors hM |>.separatingRight.eq_zero_of_mulVec_eq_zero hv -theorem eq_zero_of_mulVec_eq_zero (hM : M.det ≠ 0) {v : m → A} +theorem eq_zero_of_mulVec_eq_zero [NoZeroDivisors R] (hM : M.det ≠ 0) {v : m → R} (hv : M *ᵥ v = 0) : v = 0 := - eq_zero_of_vecMul_eq_zero (by rwa [det_transpose]) ((vecMul_transpose M v).trans hv) + nondegenerate_of_det_ne_zero hM |>.separatingRight.eq_zero_of_mulVec_eq_zero hv end Determinant diff --git a/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean b/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean index fd43268977d2e8..0fff49a15762ba 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean @@ -158,54 +158,61 @@ private theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq RingHom.mapMatrix_apply, Pi.smul_apply, smul_eq_mul, Algebra.smul_def] · rw [mulVec_smul, mul_eq, Pi.smul_apply, Pi.zero_apply, smul_zero] -theorem exists_mulVec_eq_zero_iff {A : Type*} [DecidableEq n] [CommRing A] [IsDomain A] - {M : Matrix n n A} : (∃ v ≠ 0, M *ᵥ v = 0) ↔ M.det = 0 := +variable {A : Type*} [CommRing A] [IsDomain A] {M N : Matrix n n A} + +theorem exists_mulVec_eq_zero_iff [DecidableEq n] : (∃ v ≠ 0, M *ᵥ v = 0) ↔ M.det = 0 := exists_mulVec_eq_zero_iff' (FractionRing A) -theorem exists_vecMul_eq_zero_iff {A : Type*} [DecidableEq n] [CommRing A] [IsDomain A] - {M : Matrix n n A} : (∃ v ≠ 0, v ᵥ* M = 0) ↔ M.det = 0 := by +theorem exists_vecMul_eq_zero_iff [DecidableEq n] : (∃ v ≠ 0, v ᵥ* M = 0) ↔ M.det = 0 := by simpa only [← M.det_transpose, ← mulVec_transpose] using exists_mulVec_eq_zero_iff -theorem nondegenerate_iff_det_ne_zero {A : Type*} [DecidableEq n] [CommRing A] [IsDomain A] - {M : Matrix n n A} : Nondegenerate M ↔ M.det ≠ 0 := by - refine ⟨?_, nondegenerate_of_det_ne_zero⟩ - rw [ne_eq, ← exists_vecMul_eq_zero_iff] - push Not - intro hM v hv hMv - obtain ⟨w, hwMv⟩ := hM.exists_not_ortho_of_ne_zero hv - simp [dotProduct_mulVec, hMv, zero_dotProduct, ne_eq] at hwMv - -lemma separatingLeft_iff_det_ne_zero {A : Type*} [DecidableEq n] [CommRing A] [IsDomain A] - {M : Matrix n n A} : SeparatingLeft M ↔ M.det ≠ 0 := by - refine ⟨fun h hc ↦ ?_, fun h ↦ (nondegenerate_of_det_ne_zero h).1⟩ - obtain ⟨v, hvne, hv⟩ := exists_vecMul_eq_zero_iff.mpr hc - refine hvne (separatingLeft_def.mp h v ?_) - simp [dotProduct_mulVec, hv] - -lemma separatingRight_iff_det_ne_zero {A : Type*} [DecidableEq n] [CommRing A] [IsDomain A] - {M : Matrix n n A} : SeparatingRight M ↔ M.det ≠ 0 := by - refine ⟨fun h hc ↦ ?_, fun h ↦ (nondegenerate_of_det_ne_zero h).2⟩ - obtain ⟨v, hvne, hv⟩ := exists_mulVec_eq_zero_iff.mpr hc - refine hvne (separatingRight_def.mp h v ?_) - simp [hv] - -theorem Nondegenerate.mul_iff_right {A : Type*} [CommRing A] [IsDomain A] - {M N : Matrix n n A} (h : N.Nondegenerate) : +theorem nondegenerate_iff_det_ne_zero [DecidableEq n] : Nondegenerate M ↔ M.det ≠ 0 := by + grind [nondegenerate_iff_forall_vecMul_and_mulVec_eq_zero, exists_mulVec_eq_zero_iff, + exists_vecMul_eq_zero_iff] + +lemma separatingLeft_iff_det_ne_zero [DecidableEq n] : SeparatingLeft M ↔ M.det ≠ 0 := by + grind [separatingLeft_iff_forall_vecMul_eq_zero, exists_vecMul_eq_zero_iff] + +lemma separatingRight_iff_det_ne_zero [DecidableEq n] : SeparatingRight M ↔ M.det ≠ 0 := by + grind [separatingRight_iff_forall_mulVec_eq_zero, exists_mulVec_eq_zero_iff] + +omit [Fintype n] in +theorem nondegenerate_iff_separatingLeft [Finite n] : M.Nondegenerate ↔ M.SeparatingLeft := by + classical + have := Fintype.ofFinite n + rw [nondegenerate_iff_det_ne_zero, separatingLeft_iff_det_ne_zero] + +alias ⟨_, SeparatingLeft.nondegenerate⟩ := nondegenerate_iff_separatingLeft + +omit [Fintype n] in +theorem nondegenerate_iff_separatingRight [Finite n] : M.Nondegenerate ↔ M.SeparatingRight := by + classical + have := Fintype.ofFinite n + rw [nondegenerate_iff_det_ne_zero, separatingRight_iff_det_ne_zero] + +alias ⟨_, SeparatingRight.nondegenerate⟩ := nondegenerate_iff_separatingRight + +omit [Fintype n] in +theorem separatingLeft_iff_separatingRight [Finite n] : M.SeparatingLeft ↔ M.SeparatingRight := + nondegenerate_iff_separatingLeft.symm.trans nondegenerate_iff_separatingRight + +alias ⟨SeparatingLeft.separatingRight, SeparatingRight.separatingLeft⟩ := + separatingLeft_iff_separatingRight + +theorem Nondegenerate.mul_iff_right (h : N.Nondegenerate) : (M * N).Nondegenerate ↔ M.Nondegenerate := by classical simp only [nondegenerate_iff_det_ne_zero, det_mul] at h ⊢ exact mul_ne_zero_iff_right h -theorem Nondegenerate.mul_iff_left {A : Type*} [CommRing A] [IsDomain A] - {M N : Matrix n n A} (h : M.Nondegenerate) : +theorem Nondegenerate.mul_iff_left (h : M.Nondegenerate) : (M * N).Nondegenerate ↔ N.Nondegenerate := by classical simp only [nondegenerate_iff_det_ne_zero, det_mul] at h ⊢ exact mul_ne_zero_iff_left h omit [Fintype n] in -theorem Nondegenerate.smul_iff [Finite n] {A : Type*} [CommRing A] [IsDomain A] - {M : Matrix n n A} {t : A} (h : t ≠ 0) : +theorem Nondegenerate.smul_iff [Finite n] {t : A} (h : t ≠ 0) : (t • M).Nondegenerate ↔ M.Nondegenerate := by have := Fintype.ofFinite rw [nondegenerate_def, nondegenerate_def] From 6eacf8db4e1a524ea1a2c3784d5c3d5948f03650 Mon Sep 17 00:00:00 2001 From: Aditya Menon <63695868+menon-codes@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:54:32 +0000 Subject: [PATCH 0528/1300] feat: IMO 2000 Q2 (#40286) Feat: adding IMO 2000 Q2. Formalizes a solution of IMO 2000 Q2 from [The Art of Problem Solving](https://artofproblemsolving.com/wiki/index.php?title=2000_IMO_Problems/Problem_2). See [this Zulip chat](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Feedback.20on.20first.20PR.20.28IMO.20problem.29/) Co-authored-by: Oliver Nash --- Archive.lean | 1 + Archive/Imo/Imo2000Q2.lean | 100 +++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Archive/Imo/Imo2000Q2.lean diff --git a/Archive.lean b/Archive.lean index 8ca03e8bc806d9..990ddbc04a894f 100644 --- a/Archive.lean +++ b/Archive.lean @@ -30,6 +30,7 @@ import Archive.Imo.Imo1988Q6 import Archive.Imo.Imo1994Q1 import Archive.Imo.Imo1997Q3 import Archive.Imo.Imo1998Q2 +import Archive.Imo.Imo2000Q2 import Archive.Imo.Imo2001Q2 import Archive.Imo.Imo2001Q3 import Archive.Imo.Imo2001Q4 diff --git a/Archive/Imo/Imo2000Q2.lean b/Archive/Imo/Imo2000Q2.lean new file mode 100644 index 00000000000000..94d7670e8d0faa --- /dev/null +++ b/Archive/Imo/Imo2000Q2.lean @@ -0,0 +1,100 @@ +/- +Copyright (c) 2026 Aditya Menon. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Aditya Menon +-/ +import Mathlib.Algebra.Order.Archimedean.Real.Basic + +/-! +# IMO 2000 Q2 + +Let `A`, `B`, `C` be positive reals with `ABC = 1`. Prove that +`(A - 1 + 1 / B)(B - 1 + 1 / C)(C - 1 + 1 / A) ≤ 1`. + +## Solution + +We follow the first solution from +. + +We parametrize `A = x / y`, `B = y / z`, `C = z / x` where `x, y, z > 0`. +This reduces the problem to proving `(x - y + z)(y - z + x)(z - x + y) ≤ 8xyz`. + +We then reparametrize `x = q + r`, `y = r + p`, `z = p + q` where `p, q, r ∈ ℝ`, +which transforms the inequality to `8pqr ≤ (q + r)(r + p)(p + q)`. + +The proof splits into cases based on the signs of `p`, `q`, `r`. +When all are positive, AM-GM gives the result. +When at least one is negative or zero, the inequality is verified by sign analysis. + +## Implementation notes + +- The inequality is reduced via `A = x / y`, `B = y / z`, `C = z / x`, then the substitution + `x = q + r`, `y = r + p`, `z = p + q`. +- Helper lemmas prove `8pqr ≤ (p + q)(r + p)(q + r)` by AM-GM when `p, q, r > 0` and by sign + analysis otherwise; the main proof closes with `grind`. + +## References + +* + +-/ + +namespace Imo2000Q2 + +/-- When `p`, `q`, `r > 0`, `8pqr ≤ (p + q)(r + p)(q + r)`, by writing the difference of squares as +a sum of nonnegative squares. -/ +lemma eight_mul_le_prod_add_of_pos {p q r : ℝ} (p_pos : 0 < p) + (q_pos : 0 < q) (r_pos : 0 < r) : + 8 * p * q * r ≤ (p + q) * (q + r) * (r + p) := by + suffices 0 ≤ ((p + q) * (q + r) * (r + p)) ^ 2 - (8 * p * q * r) ^ 2 from + le_of_sq_le_sq (le_of_sub_nonneg this) (by positivity) + calc 0 ≤ (p * (q - r) ^ 2 + q * (r - p) ^ 2 + r * (p - q) ^ 2) + * ((p + q) * (q + r) * (r + p) + 8 * p * q * r) := by positivity + _ = ((p + q) * (q + r) * (r + p)) ^ 2 - (8 * p * q * r) ^ 2 := by ring + +/-- When `p ≤ 0` but `q`, `r > 0` and both pairwise sums are positive, the left side is +nonpositive so the inequality holds. -/ +lemma eight_mul_le_prod_add_of_nonpos {p q r : ℝ} (p_nonpos : p ≤ 0) (r_pos : 0 < r) (q_pos : 0 < q) + (p_add_q_pos : 0 < p + q) (r_add_p_pos : 0 < r + p) : + 8 * p * q * r ≤ (p + q) * (r + p) * (q + r) := by + calc 8 * p * q * r ≤ 0 := by grw [mul_nonpos_of_nonpos_of_nonneg ?_ (by positivity)] + grw [mul_nonpos_of_nonpos_of_nonneg (by grind) (by positivity)] + _ ≤ (p + q) * (r + p) * (q + r) := by positivity + +/-- When all three pairwise sums `p + q`, `r + p`, `q + r` are positive, the inequality holds by +casing on the signs of `p`, `q`, `r`. -/ +lemma eight_mul_le_prod_add_of_add_pos (p q r : ℝ) + (hpq : 0 < p + q := by grind) + (hqr : 0 < q + r := by grind) + (hrp : 0 < r + p := by grind) : + 8 * p * q * r ≤ (p + q) * (q + r) * (r + p) := by + rcases lt_or_ge 0 p with p_pos | p_nonpos <;> + rcases lt_or_ge 0 q with q_pos | q_nonpos <;> + rcases lt_or_ge 0 r with r_pos | r_nonpos + -- At most one of `p`, `q`, `r` can be negative; otherwise some pairwise sum is nonpositive. + · exact eight_mul_le_prod_add_of_pos p_pos q_pos r_pos + · -- `r` is the unique nonpositive variable. + convert eight_mul_le_prod_add_of_nonpos r_nonpos q_pos p_pos hrp hqr using 1 <;> ring + · -- `q` is the unique nonpositive variable. + convert eight_mul_le_prod_add_of_nonpos q_nonpos p_pos r_pos hqr hpq using 1 <;> ring + · linarith + · -- `p` is the unique nonpositive variable. + convert eight_mul_le_prod_add_of_nonpos p_nonpos r_pos q_pos hpq hrp using 1; ring + · linarith + · linarith + · linarith + +/-- **IMO 2000 Q2**. If `A`, `B`, `C > 0` and `ABC = 1`, then +`(A - 1 + 1 / B)(B - 1 + 1 / C)(C - 1 + 1 / A) ≤ 1`. -/ +theorem imo2000_q2 {A B C : ℝ} + (A_pos : 0 < A) (B_pos : 0 < B) (C_pos : 0 < C) (h_prod : A * B * C = 1) : + (A - 1 + 1 / B) * (B - 1 + 1 / C) * (C - 1 + 1 / A) ≤ 1 := by + obtain ⟨x, y, z, x_pos, y_pos, z_pos, rfl, rfl, rfl⟩ : + ∃ x y z, 0 < x ∧ 0 < y ∧ 0 < z ∧ A = x / y ∧ B = y / z ∧ C = z / x := + ⟨A, 1, 1 / B, by grind only [inv_pos]⟩ + -- If `x = q + r`, `y = r + p`, `z = p + q`, it suffices to show `8pqr ≤ (q + r)(r + p)(p + q)`. + have := eight_mul_le_prod_add_of_add_pos ((y + z - x) / 2) ((z + x - y) / 2) ((x + y - z) / 2) + field_simp + grind + +end Imo2000Q2 From b39dd4b50b1216c8fa417596cfed4601056c495e Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Wed, 1 Jul 2026 17:54:39 +0000 Subject: [PATCH 0529/1300] chore: cleanup API around LinearMap.surjective_domRestrict_iff (#41235) - semilinearize [LinearMap.range_domRestrict](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Module/Submodule/Range.html#LinearMap.range_domRestrict) - add `map_eq_range_iff` as a replacement for [LinearMap.range_domRestrict_eq_range_iff](https://leanprover-community.github.io/mathlib4_docs/Mathlib/LinearAlgebra/Span/Basic.html#LinearMap.range_domRestrict_eq_range_iff), with a golfed proof. - use `Codisjoint` in [LinearMap.surjective_domRestrict_iff](https://leanprover-community.github.io/mathlib4_docs/Mathlib/LinearAlgebra/Span/Basic.html#LinearMap.surjective_domRestrict_iff) --- Mathlib/Algebra/Module/Submodule/Range.lean | 3 +- Mathlib/LinearAlgebra/Span/Basic.lean | 29 ++++++++----------- .../Measure/Haar/Disintegration.lean | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/Range.lean b/Mathlib/Algebra/Module/Submodule/Range.lean index af73d5e971206b..8197d95db2ec94 100644 --- a/Mathlib/Algebra/Module/Submodule/Range.lean +++ b/Mathlib/Algebra/Module/Submodule/Range.lean @@ -114,7 +114,7 @@ theorem range_neg {R : Type*} {R₂ : Type*} {M : Type*} {M₂ : Type*} [Semirin change range ((-LinearMap.id : M₂ →ₗ[R₂] M₂).comp f) = _ rw [range_comp, Submodule.map_neg, Submodule.map_id] -@[simp] lemma range_domRestrict [Module R M₂] (K : Submodule R M) (f : M →ₗ[R] M₂) : +@[simp] lemma range_domRestrict [RingHomSurjective τ₁₂] (K : Submodule R M) (f : M →ₛₗ[τ₁₂] M₂) : range (domRestrict f K) = K.map f := by ext; simp lemma range_domRestrict_le_range [RingHomSurjective τ₁₂] (f : M →ₛₗ[τ₁₂] M₂) (S : Submodule R M) : @@ -303,6 +303,7 @@ open LinearMap @[simp] theorem map_top [RingHomSurjective τ₁₂] (f : M →ₛₗ[τ₁₂] M₂) : map f ⊤ = range f := (range_eq_map f).symm + @[simp] theorem range_subtype : range p.subtype = p := by simpa using map_comap_subtype p ⊤ diff --git a/Mathlib/LinearAlgebra/Span/Basic.lean b/Mathlib/LinearAlgebra/Span/Basic.lean index 8869671a304345..2f16a8eb65657b 100644 --- a/Mathlib/LinearAlgebra/Span/Basic.lean +++ b/Mathlib/LinearAlgebra/Span/Basic.lean @@ -529,6 +529,8 @@ end AddCommGroup section AddCommGroup +-- TODO: Multiple lemmas in this section should be in earlier files + variable [Semiring R] [Semiring R₂] variable [AddCommGroup M] [Module R M] [AddCommGroup M₂] [Module R₂ M₂] variable {τ₁₂ : R →+* R₂} [RingHomSurjective τ₁₂] @@ -539,6 +541,11 @@ theorem comap_map_eq (f : M →ₛₗ[τ₁₂] M₂) (p : Submodule R M) : rintro x ⟨y, hy, e⟩ exact mem_sup.2 ⟨y, hy, x - y, by simpa using sub_eq_zero.2 e.symm, by simp⟩ +theorem map_eq_range_iff {f : M →ₛₗ[τ₁₂] M₂} {p : Submodule R M} : + map f p = f.range ↔ Codisjoint p f.ker := by + simp_rw [le_antisymm_iff, LinearMap.map_le_range, true_and, ← map_top, map_le_iff_le_comap, + comap_map_eq, codisjoint_iff_le_sup] + theorem map_lt_map_of_le_of_sup_lt_sup {p p' : Submodule R M} {f : M →ₛₗ[τ₁₂] M₂} (hab : p ≤ p') (h : p ⊔ LinearMap.ker f < p' ⊔ LinearMap.ker f) : Submodule.map f p < Submodule.map f p' := by simp_rw [← comap_map_eq] at h @@ -587,28 +594,16 @@ lemma comap_covBy_of_surjective {f : M →ₛₗ[τ₁₂] M₂} (hf : Surjectiv rwa [← comap_lt_comap_iff_of_surjective hf, comap_map_eq, sup_eq_left.mpr] refine (LinearMap.ker_le_comap (f : M →ₛₗ[τ₁₂] M₂)).trans h₁.le +@[deprecated map_eq_range_iff (since := "2026-07-01")] lemma _root_.LinearMap.range_domRestrict_eq_range_iff {f : M →ₛₗ[τ₁₂] M₂} {S : Submodule R M} : - LinearMap.range (f.domRestrict S) = LinearMap.range f ↔ S ⊔ (LinearMap.ker f) = ⊤ := by - refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ - · rw [eq_top_iff] - intro x _ - have : f x ∈ LinearMap.range f := LinearMap.mem_range_self f x - rw [← h] at this - obtain ⟨y, hy⟩ : ∃ y : S, f.domRestrict S y = f x := this - have : (y : M) + (x - y) ∈ S ⊔ (LinearMap.ker f) := Submodule.add_mem_sup y.2 (by simp [← hy]) - simpa using this - · refine le_antisymm (LinearMap.range_domRestrict_le_range f S) ?_ - rintro x ⟨y, rfl⟩ - obtain ⟨s, hs, t, ht, rfl⟩ : ∃ s, s ∈ S ∧ ∃ t, t ∈ LinearMap.ker f ∧ s + t = y := - Submodule.mem_sup.1 (by simp [h]) - exact ⟨⟨s, hs⟩, by simp [LinearMap.mem_ker.1 ht]⟩ + LinearMap.range (f.domRestrict S) = LinearMap.range f ↔ Codisjoint S f.ker := by + simp [map_eq_range_iff] @[simp] lemma _root_.LinearMap.surjective_domRestrict_iff {f : M →ₛₗ[τ₁₂] M₂} {S : Submodule R M} (hf : Surjective f) : - Surjective (f.domRestrict S) ↔ S ⊔ LinearMap.ker f = ⊤ := by + Surjective (f.domRestrict S) ↔ Codisjoint S f.ker := by rw [← LinearMap.range_eq_top] at hf ⊢ - rw [← hf] - exact LinearMap.range_domRestrict_eq_range_iff + rw [← hf, LinearMap.range_domRestrict, map_eq_range_iff] lemma biSup_comap_eq_top_of_surjective {ι : Type*} (s : Set ι) (hs : s.Nonempty) (p : ι → Submodule R₂ M₂) (hp : ⨆ i ∈ s, p i = ⊤) diff --git a/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean b/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean index 210f423f434634..db49d722bf57cf 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean @@ -64,7 +64,7 @@ theorem LinearMap.exists_map_addHaar_eq_smul_addHaar' (h : Function.Surjective L have P_cont : Continuous P := LinearMap.continuous_of_finiteDimensional _ have I : Function.Bijective (LinearMap.domRestrict L T) := ⟨LinearMap.injective_domRestrict_iff.2 (IsCompl.inf_eq_bot hT.symm), - (LinearMap.surjective_domRestrict_iff h).2 hT.symm.sup_eq_top⟩ + (LinearMap.surjective_domRestrict_iff h).2 hT.symm.codisjoint⟩ let L' : T ≃ₗ[𝕜] F := LinearEquiv.ofBijective (LinearMap.domRestrict L T) I have L'_cont : Continuous L' := LinearMap.continuous_of_finiteDimensional _ have A : L = (L' : T →ₗ[𝕜] F).comp (P.comp (M.symm : E →ₗ[𝕜] (S × T))) := by From 24fff1c8867e78ff5160257c95219b399508236d Mon Sep 17 00:00:00 2001 From: Suzuka Yu <109365723+Yu-Misaka@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:54:41 +0000 Subject: [PATCH 0530/1300] chore(RepresentationTheory): invert ordering `FDRep` with `Representation` namespace sections (#41242) Split from #40665. The motivation here is: I proved a result for `Representation`, and I can derive analogy for `FDRep`, but the reverse direction seems to run into universe issues with [FDRep.of](https://leanprover-community.github.io/mathlib4_docs/Mathlib/RepresentationTheory/FDRep.html#FDRep.of), see the zulip link [here](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/Integrality.20of.20character/with/603655189). --- Mathlib/RepresentationTheory/Character.lean | 192 ++++++++++---------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/Mathlib/RepresentationTheory/Character.lean b/Mathlib/RepresentationTheory/Character.lean index 5b1acb384378ab..795db39cd34eaf 100644 --- a/Mathlib/RepresentationTheory/Character.lean +++ b/Mathlib/RepresentationTheory/Character.lean @@ -43,102 +43,6 @@ open CategoryTheory LinearMap CategoryTheory.MonoidalCategory Representation Mod variable {k : Type u} [Field k] -namespace FDRep - -section Monoid - -variable {G : Type v} [Monoid G] - -/-- The character of a representation `V : FDRep k G` is the function associating to `g : G` the -trace of the linear map `V.ρ g`. -/ -def character (V : FDRep k G) (g : G) := - LinearMap.trace k V (V.ρ g) - -theorem char_mul_comm (V : FDRep k G) (g : G) (h : G) : - V.character (h * g) = V.character (g * h) := by simp only [trace_mul_comm, character, map_mul] - -@[simp] -theorem char_one (V : FDRep k G) : V.character 1 = Module.finrank k V := by - simp only [character, map_one, trace_one] - -/-- The character is multiplicative under the tensor product. -/ -@[simp] -theorem char_tensor (V W : FDRep k G) : (V ⊗ W).character = V.character * W.character := by - ext g; convert! trace_tensorProduct' (V.ρ g) (W.ρ g) - -/-- The character of isomorphic representations is the same. -/ -theorem char_iso {V W : FDRep k G} (i : V ≅ W) : V.character = W.character := by - ext g - simp only [character, FDRep.Iso.conj_ρ i] - exact (trace_conj' (V.ρ g) _).symm - -end Monoid - -section Group - -variable {G : Type v} [Group G] - -/-- The character of a representation is constant on conjugacy classes. -/ -@[simp] -theorem char_conj (V : FDRep k G) (g : G) (h : G) : V.character (h * g * h⁻¹) = V.character g := by - rw [char_mul_comm, inv_mul_cancel_left] - -@[simp] -theorem char_dual (V : FDRep k G) (g : G) : (of (dual V.ρ)).character g = V.character g⁻¹ := - trace_transpose' (V.ρ g⁻¹) - -@[simp] -theorem char_linHom (V W : FDRep k G) (g : G) : - (of (linHom V.ρ W.ρ)).character g = V.character g⁻¹ * W.character g := by - rw [← char_iso (dualTensorIsoLinHom _ _), char_tensor, Pi.mul_apply, char_dual] - -variable [Fintype G] [Invertible (Fintype.card G : k)] - -theorem average_char_eq_finrank_invariants (V : FDRep k G) : - ⅟(Fintype.card G : k) • ∑ g : G, V.character g = finrank k (invariants V.ρ) := by - rw [← (isProj_averageMap V.ρ).trace] - simp [character, GroupAlgebra.average, _root_.map_sum] - -/-- -If `V` are `W` are finite-dimensional representations of a finite group, then the -scalar product of their characters is equal to the dimension of the space of -equivariant maps from `V` to `W`. --/ -theorem scalar_product_char_eq_finrank_equivariant (V W : FDRep k G) : - ⅟(Fintype.card G : k) • ∑ g : G, W.character g * V.character g⁻¹ = - Module.finrank k (V ⟶ W) := by - conv_lhs => congr; rfl; congr; rfl; intro _; rw [mul_comm, ← FDRep.char_linHom] - -- The scalar product is the character of `Hom(V, W).` - rw [FDRep.average_char_eq_finrank_invariants, ← LinearEquiv.finrank_eq - (Representation.linHom.invariantsEquivFDRepHom V W), of_ρ'] - -- The average over the group of the character of a representation equals the dimension of the - -- space of invariants, and the space of invariants of `Hom(W, V)` is the subspace of - --`G`-equivariant linear maps, `Hom_G(W, V)`. - -end Group - -section Orthogonality - -variable {G : Type v} [Group G] [IsAlgClosed k] - -variable [Fintype G] [Invertible (Fintype.card G : k)] - -open scoped Classical in -/-- Orthogonality of characters for irreducible representations of finite group over an -algebraically closed field whose characteristic doesn't divide the order of the group. -/ -theorem char_orthonormal (V W : FDRep k G) [Simple V] [Simple W] : - ⅟(Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ = - if Nonempty (V ≅ W) then ↑1 else ↑0 := by - rw [scalar_product_char_eq_finrank_equivariant] - -- The scalar products of the characters is equal to the dimension of the space of - -- equivariant maps `W ⟶ V`. - rw_mod_cast [finrank_hom_simple_simple W V, Iso.nonempty_iso_symm] - -- By Schur's Lemma, the dimension of `Hom_G(W, V)` is `1` is `V ≅ W` and `0` otherwise. - -end Orthogonality - -end FDRep - namespace Representation section Monoid @@ -240,3 +144,99 @@ theorem char_orthonormal [IsIrreducible ρ] [IsIrreducible σ] : end Orthogonality end Representation + +namespace FDRep + +section Monoid + +variable {G : Type v} [Monoid G] + +/-- The character of a representation `V : FDRep k G` is the function associating to `g : G` the +trace of the linear map `V.ρ g`. -/ +def character (V : FDRep k G) (g : G) := + LinearMap.trace k V (V.ρ g) + +theorem char_mul_comm (V : FDRep k G) (g : G) (h : G) : + V.character (h * g) = V.character (g * h) := by simp only [trace_mul_comm, character, map_mul] + +@[simp] +theorem char_one (V : FDRep k G) : V.character 1 = Module.finrank k V := by + simp only [character, map_one, trace_one] + +/-- The character is multiplicative under the tensor product. -/ +@[simp] +theorem char_tensor (V W : FDRep k G) : (V ⊗ W).character = V.character * W.character := by + ext g; convert! trace_tensorProduct' (V.ρ g) (W.ρ g) + +/-- The character of isomorphic representations is the same. -/ +theorem char_iso {V W : FDRep k G} (i : V ≅ W) : V.character = W.character := by + ext g + simp only [character, FDRep.Iso.conj_ρ i] + exact (trace_conj' (V.ρ g) _).symm + +end Monoid + +section Group + +variable {G : Type v} [Group G] + +/-- The character of a representation is constant on conjugacy classes. -/ +@[simp] +theorem char_conj (V : FDRep k G) (g : G) (h : G) : V.character (h * g * h⁻¹) = V.character g := by + rw [char_mul_comm, inv_mul_cancel_left] + +@[simp] +theorem char_dual (V : FDRep k G) (g : G) : (of (dual V.ρ)).character g = V.character g⁻¹ := + trace_transpose' (V.ρ g⁻¹) + +@[simp] +theorem char_linHom (V W : FDRep k G) (g : G) : + (of (linHom V.ρ W.ρ)).character g = V.character g⁻¹ * W.character g := by + rw [← char_iso (dualTensorIsoLinHom _ _), char_tensor, Pi.mul_apply, char_dual] + +variable [Fintype G] [Invertible (Fintype.card G : k)] + +theorem average_char_eq_finrank_invariants (V : FDRep k G) : + ⅟(Fintype.card G : k) • ∑ g : G, V.character g = finrank k (invariants V.ρ) := by + rw [← (isProj_averageMap V.ρ).trace] + simp [character, GroupAlgebra.average, _root_.map_sum] + +/-- +If `V` are `W` are finite-dimensional representations of a finite group, then the +scalar product of their characters is equal to the dimension of the space of +equivariant maps from `V` to `W`. +-/ +theorem scalar_product_char_eq_finrank_equivariant (V W : FDRep k G) : + ⅟(Fintype.card G : k) • ∑ g : G, W.character g * V.character g⁻¹ = + Module.finrank k (V ⟶ W) := by + conv_lhs => congr; rfl; congr; rfl; intro _; rw [mul_comm, ← FDRep.char_linHom] + -- The scalar product is the character of `Hom(V, W).` + rw [FDRep.average_char_eq_finrank_invariants, ← LinearEquiv.finrank_eq + (Representation.linHom.invariantsEquivFDRepHom V W), of_ρ'] + -- The average over the group of the character of a representation equals the dimension of the + -- space of invariants, and the space of invariants of `Hom(W, V)` is the subspace of + --`G`-equivariant linear maps, `Hom_G(W, V)`. + +end Group + +section Orthogonality + +variable {G : Type v} [Group G] [IsAlgClosed k] + +variable [Fintype G] [Invertible (Fintype.card G : k)] + +open scoped Classical in +/-- Orthogonality of characters for irreducible representations of finite group over an +algebraically closed field whose characteristic doesn't divide the order of the group. -/ +theorem char_orthonormal (V W : FDRep k G) [Simple V] [Simple W] : + ⅟(Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ = + if Nonempty (V ≅ W) then ↑1 else ↑0 := by + rw [scalar_product_char_eq_finrank_equivariant] + -- The scalar products of the characters is equal to the dimension of the space of + -- equivariant maps `W ⟶ V`. + rw_mod_cast [finrank_hom_simple_simple W V, Iso.nonempty_iso_symm] + -- By Schur's Lemma, the dimension of `Hom_G(W, V)` is `1` is `V ≅ W` and `0` otherwise. + +end Orthogonality + +end FDRep From a1566c2f4d274e9b63354191b802765e617e73bc Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Wed, 1 Jul 2026 19:08:10 +0000 Subject: [PATCH 0531/1300] feat(SimpleGraph): `cycleGraph` is contained in every graph with a cycle (#35255) --- .../Combinatorics/SimpleGraph/CycleGraph.lean | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean b/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean index 60f046bbb2fded..ffe1ab2347a633 100644 --- a/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean @@ -166,4 +166,39 @@ theorem cycleGraph.isCycle_cycle : (cycleGraph.cycle n).IsCycle := end cycle +section IsContained + +variable {V : Type*} {G : SimpleGraph V} + +lemma cycleGraph_isContained_iff {n : ℕ} (hn : 2 < n) : + cycleGraph n ⊑ G ↔ ∃ (v : V) (p : G.Walk v v), p.IsCycle ∧ p.length = n := by + refine ⟨fun ⟨h⟩ ↦ ?_, fun h' ↦ ?_⟩ + · have : n = n - 3 + 3 := by lia + rw [this] at h + refine ⟨h.toHom ⟨0, by lia⟩, Walk.map h.toHom <| cycleGraph.cycle (n - 3), ?_, ?_⟩ + · exact (map_isCycle_iff_of_injective h.injective).mpr cycleGraph.isCycle_cycle + · simp [cycleGraph.length_cycle, ← this] + · obtain ⟨a, p, hp₁, hp₂⟩ := h' + refine ⟨⟨⟨fun n ↦ p.support[n.succ]'(?_), ?_⟩, ?_⟩⟩ + · grind [hp₁.three_le_length, length_tail_add_one, not_nil_iff_lt_length] + · intro ⟨x, hx⟩ ⟨y, hy⟩ hab + have hne : x ≠ y := fun _ ↦ by simp_all + wlog hle : x > y + · exact this hn a p hp₁ hp₂ y hy x hx hab.symm hne.symm (by lia) |>.symm + rcases cycleGraph_adj'.mp hab with hab | hab + · simp_rw [show x = y + 1 by grind [Fin.sub_val_of_le]] + exact p.isChain_adj_support.getElem _ _ |>.symm + · rw [Fin.coe_sub_iff_lt.mpr hle] at hab + simp_rw [show x = n - 1 by lia, show y = 0 by lia, Fin.succ_mk, show n - 1 + 1 = n by lia] + simp [← hp₂, p.adj_snd hp₁.not_nil] + · have hlen : p.tail.support.length = n := by + grind [length_tail_add_one, not_nil_iff_lt_length] + have (m : Fin n) : p.support[m.succ]'(by grind) = p.tail.support[m] := by + simp [p.support_tail_of_not_nil hp₁.not_nil] + simp_rw [this] + have := IsPath.mk' <| (support_tail_of_not_nil _ hp₁.not_nil) ▸ hp₁.support_nodup + exact hlen ▸ (isPath_iff_injective_get_support _ |>.mp this) + +end IsContained + end SimpleGraph From 88d006abbcd1f157f567bd21c7a33c271df9b83b Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 1 Jul 2026 23:47:21 +0000 Subject: [PATCH 0532/1300] feat: make the `dupNamespace` linter catch any duplicate namespace(s) (#39793) Before this PR, the `dupNamespace` linter would only flag a namespace as duplicate if it was repeated in two consecutive positions: `Foo.Foo.bar` would be linted, but neither `Foo.Bar.Foo.Bar.baz` nor `Foo.Bar.Foo.Baz.baz` would be (even though they are very likely unintentional). Strengthen the linter check, to error if any namespace component is duplicated. This has few false positives (which we manually annotate), but catches many pre-existing cases where the duplication was clearly unintentional and undesirable. Most of the mathlib adaptation was done in #39794. Co-authored-by: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> --- Mathlib/Algebra/Polynomial/Bivariate.lean | 2 + Mathlib/Analysis/Distribution/Support.lean | 4 +- .../InnerProductSpace/JointEigenspace.lean | 1 + .../Bicategory/Adjunction/Adj.lean | 5 + .../CategoryTheory/Groupoid/VertexGroup.lean | 2 + .../Limits/Shapes/Pullback/HasPullback.lean | 3 +- .../Subobject/Classifier/Defs.lean | 16 +++ Mathlib/Data/Set/FiniteExhaustion.lean | 1 + .../VectorBundle/MDifferentiable.lean | 1 + Mathlib/GroupTheory/Submonoid/Inverses.lean | 1 + Mathlib/LinearAlgebra/FreeModule/Basic.lean | 1 + Mathlib/Logic/Equiv/Set.lean | 1 + .../NumberField/Completion/FinitePlace.lean | 13 ++ .../NumberField/InfinitePlace/Basic.lean | 1 + Mathlib/Order/Filter/Germ/Basic.lean | 1 + Mathlib/RingTheory/Etale/Basic.lean | 2 + Mathlib/RingTheory/Finiteness/Basic.lean | 1 + Mathlib/RingTheory/TensorProduct/Maps.lean | 1 + Mathlib/Tactic/Linter/Lint.lean | 38 +++--- MathlibTest/Linter/DupNamespace.lean | 120 +++++++++++++++++- 20 files changed, 190 insertions(+), 25 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Bivariate.lean b/Mathlib/Algebra/Polynomial/Bivariate.lean index c2064ba46b87fb..19e5486a598d95 100644 --- a/Mathlib/Algebra/Polynomial/Bivariate.lean +++ b/Mathlib/Algebra/Polynomial/Bivariate.lean @@ -353,6 +353,7 @@ lemma pderiv_zero_equivMvPolynomial {R : Type*} [CommRing R] (p : R[X][Y]) : simp_rw [← Polynomial.C_mul_X_pow_eq_monomial] simp [map_nsmul] +set_option linter.dupNamespace false in @[deprecated (since := "2025-12-09")] alias Polynomial.Bivariate.pderiv_zero_equivMvPolynomial := pderiv_zero_equivMvPolynomial @@ -367,6 +368,7 @@ lemma pderiv_one_equivMvPolynomial (p : R[X][Y]) : simp_rw [← Polynomial.C_mul_X_pow_eq_monomial] simp [derivative_pow] +set_option linter.dupNamespace false in @[deprecated (since := "2025-12-09")] alias Polynomial.Bivariate.pderiv_one_equivMvPolynomial := pderiv_one_equivMvPolynomial diff --git a/Mathlib/Analysis/Distribution/Support.lean b/Mathlib/Analysis/Distribution/Support.lean index aea1884470473b..1598e7ae0ae86b 100644 --- a/Mathlib/Analysis/Distribution/Support.lean +++ b/Mathlib/Analysis/Distribution/Support.lean @@ -189,7 +189,7 @@ theorem smulLeftCLM (hf : IsVanishingOn f s) {g : E → ℂ} (hg : g.HasTemperat rw [SchwartzMap.smulLeftCLM_apply hg] exact (tsupport_smul_subset_right g u).trans hu -@[deprecated (since := "2026-06-27")] alias Distribution.IsVanishingOn.smulLeftCLM := +@[deprecated (since := "2026-07-01")] alias _root_.Distribution.IsVanishingOn.smulLeftCLM := Distribution.TemperedDistribution.IsVanishingOn.smulLeftCLM open LineDeriv @@ -225,7 +225,7 @@ theorem dsupport_smulLeftCLM_subset {g : E → ℂ} (hg : g.HasTemperateGrowth) dsupport (smulLeftCLM F g f) ⊆ dsupport f := by gcongr; fun_prop -@[deprecated (since := "2026-06-27")] alias Distribution.dsupport_smulLeftCLM_subset := +@[deprecated (since := "2026-07-01")] alias _root_.Distribution.dsupport_smulLeftCLM_subset := Distribution.TemperedDistribution.dsupport_smulLeftCLM_subset open LineDeriv diff --git a/Mathlib/Analysis/InnerProductSpace/JointEigenspace.lean b/Mathlib/Analysis/InnerProductSpace/JointEigenspace.lean index a2b446dbaae0ef..97df41135bc48e 100644 --- a/Mathlib/Analysis/InnerProductSpace/JointEigenspace.lean +++ b/Mathlib/Analysis/InnerProductSpace/JointEigenspace.lean @@ -140,6 +140,7 @@ theorem directSum_isInternal_of_pairwise_commute [DecidableEq (n → 𝕜)] · rw [iSup_iInf_eq_top_of_commute hT hC, top_orthogonal_eq_bot] · exact orthogonalFamily_iInf_eigenspaces hT +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias LinearMap.IsSymmetric.directSum_isInternal_of_pairwise_commute := directSum_isInternal_of_pairwise_commute diff --git a/Mathlib/CategoryTheory/Bicategory/Adjunction/Adj.lean b/Mathlib/CategoryTheory/Bicategory/Adjunction/Adj.lean index c8a557f1e6ca79..52352ccc4076a4 100644 --- a/Mathlib/CategoryTheory/Bicategory/Adjunction/Adj.lean +++ b/Mathlib/CategoryTheory/Bicategory/Adjunction/Adj.lean @@ -131,23 +131,27 @@ def iso₂Mk {α β : a ⟶ b} (el : α.l ≅ β.l) (er : β.r ≅ α.r) namespace Bicategory +set_option linter.dupNamespace false in /-- The associator in the bicategory `Adj B`. -/ @[simps!] def associator (α : a ⟶ b) (β : b ⟶ c) (γ : c ⟶ d) : (α ≫ β) ≫ γ ≅ α ≫ β ≫ γ := iso₂Mk (α_ _ _ _) (α_ _ _ _) (conjugateEquiv_associator_hom _ _ _) +set_option linter.dupNamespace false in /-- The left unitor in the bicategory `Adj B`. -/ @[simps!] def leftUnitor (α : a ⟶ b) : 𝟙 a ≫ α ≅ α := iso₂Mk (λ_ _) (ρ_ _).symm (by simpa using conjugateEquiv_id_comp_right_apply α.adj α.adj (𝟙 _)) +set_option linter.dupNamespace false in /-- The right unitor in the bicategory `Adj B`. -/ @[simps!] def rightUnitor (α : a ⟶ b) : α ≫ 𝟙 b ≅ α := iso₂Mk (ρ_ _) (λ_ _).symm (by simpa using conjugateEquiv_comp_id_right_apply α.adj α.adj (𝟙 _)) +set_option linter.dupNamespace false in /-- The left whiskering in the bicategory `Adj B`. -/ @[simps] def whiskerLeft (α : a ⟶ b) {β β' : b ⟶ c} (y : β ⟶ β') : α ≫ β ⟶ α ≫ β' where @@ -156,6 +160,7 @@ def whiskerLeft (α : a ⟶ b) {β β' : b ⟶ c} (y : β ⟶ β') : α ≫ β conjugateEquiv_τl := by simp [conjugateEquiv_whiskerLeft, Hom₂.conjugateEquiv_τl] +set_option linter.dupNamespace false in /-- The right whiskering in the bicategory `Adj B`. -/ @[simps] def whiskerRight {α α' : a ⟶ b} (x : α ⟶ α') (β : b ⟶ c) : α ≫ β ⟶ α' ≫ β where diff --git a/Mathlib/CategoryTheory/Groupoid/VertexGroup.lean b/Mathlib/CategoryTheory/Groupoid/VertexGroup.lean index 289facce1b9efe..df6fd2c21367e8 100644 --- a/Mathlib/CategoryTheory/Groupoid/VertexGroup.lean +++ b/Mathlib/CategoryTheory/Groupoid/VertexGroup.lean @@ -83,9 +83,11 @@ def _root_.CategoryTheory.Functor.mapVertexGroup {D : Type v} [Groupoid D] (φ : map_one' := φ.map_id c map_mul' := φ.map_comp +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias CategoryTheory.Functor.mapVertexGroup := CategoryTheory.Functor.mapVertexGroup +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias CategoryTheory.Functor.mapVertexGroup_apply := CategoryTheory.Functor.mapVertexGroup_apply diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean index ad855e72608a3d..d1cc9b3eb0f9bc 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean @@ -204,8 +204,7 @@ def pushout.desc' {W X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} [HasPushout f g] (h { l : pushout f g ⟶ W // pushout.inl _ _ ≫ l = h ∧ pushout.inr _ _ ≫ l = k } := ⟨pushout.desc h k w, pushout.inl_desc _ _ _, pushout.inr_desc _ _ _⟩ -@[deprecated (since := "2026-06-25")] -alias CategoryTheory.Limits.pullback.desc' := pushout.desc' +@[deprecated (since := "2026-06-25")] alias pullback.desc' := pushout.desc' @[reassoc] theorem pullback.condition {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasPullback f g] : diff --git a/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean b/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean index ce1187d910572b..bce43342532765 100644 --- a/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean +++ b/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean @@ -392,6 +392,7 @@ namespace SubobjectRepresentableBy given `h : SubobjectRepresentableBy Ω`. -/ def Ω₀ : Subobject Ω := h.homEquiv (𝟙 Ω) +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.Ω₀ := Ω₀ @[deprecated (since := "2026-03-06")] @@ -403,6 +404,7 @@ lemma homEquiv_eq {X : C} (f : X ⟶ Ω) : h.homEquiv f = (Subobject.pullback f).obj h.Ω₀ := by simpa using! h.homEquiv_comp f (𝟙 _) +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.homEquiv_eq := homEquiv_eq @[deprecated (since := "2026-03-06")] @@ -414,6 +416,7 @@ lemma pullback_homEquiv_symm_obj_Ω₀ {X : C} (x : Subobject X) : (Subobject.pullback (h.homEquiv.symm x)).obj h.Ω₀ = x := by rw [← homEquiv_eq, Equiv.apply_symm_apply] +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.pullback_homEquiv_symm_obj_Ω₀ := pullback_homEquiv_symm_obj_Ω₀ @@ -428,6 +431,7 @@ variable {U X : C} (m : U ⟶ X) [Mono m] /-- `h.χ m` is the characteristic map of monomorphism `m` given by the bijection `h.homEquiv`. -/ def χ : X ⟶ Ω := h.homEquiv.symm (Subobject.mk m) +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.χ := χ @[deprecated (since := "2026-03-06")] @@ -440,6 +444,7 @@ noncomputable def iso : MonoOver.mk m ≅ (Subobject.representativeIso (.mk m)).symm ≪≫ Subobject.representative.mapIso (eqToIso (h.pullback_homEquiv_symm_obj_Ω₀ (.mk m)).symm) +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso := iso @[deprecated (since := "2026-03-06")] @@ -459,6 +464,7 @@ alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.iso := iso noncomputable def π : U ⟶ Subobject.underlying.obj h.Ω₀ := (h.iso m).hom.hom.left ≫ Subobject.pullbackπ (h.χ m) h.Ω₀ +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.π := π @[deprecated (since := "2026-03-06")] @@ -473,6 +479,7 @@ lemma iso_inv_left_π : convert! Category.id_comp _ using 2 exact (MonoOver.forget _ ⋙ Over.forget _).congr_map (h.iso m).inv_hom_id +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_left_π := iso_inv_left_π @[deprecated (since := "2026-03-06")] @@ -484,6 +491,7 @@ lemma iso_inv_hom_left_comp : ((Subobject.pullback (h.χ m)).obj h.Ω₀).arrow := MonoOver.w (h.iso m).inv +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_hom_left_comp := iso_inv_hom_left_comp @@ -491,6 +499,7 @@ alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_hom_left_ alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_hom_left_comp := iso_inv_hom_left_comp +set_option linter.dupNamespace false in @[deprecated (since := "2025-12-18")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_left_comp := iso_inv_hom_left_comp @@ -503,6 +512,7 @@ lemma isPullback {U X : C} (m : U ⟶ X) [Mono m] : (Iso.refl _) (Iso.refl _) all_goals simp [MonoOver.forget] +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.isPullback := isPullback @[deprecated (since := "2026-03-06")] @@ -515,6 +525,7 @@ lemma uniq {χ' : X ⟶ Ω} {π : U ⟶ h.Ω₀} simp only [χ, Equiv.apply_symm_apply, homEquiv_eq] simpa using! Subobject.pullback_obj_mk sq.flip +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.uniq := uniq @[deprecated (since := "2026-03-06")] @@ -532,6 +543,7 @@ noncomputable def isTerminalΩ₀ : IsTerminal (h.Ω₀ : C) := rw [← cancel_mono h.Ω₀.arrow, h.uniq this, ← (h.isPullback (𝟙 X)).w, Category.id_comp]) +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.isTerminalΩ₀ := isTerminalΩ₀ @[deprecated (since := "2026-03-06")] @@ -540,6 +552,7 @@ alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.isTerminalΩ₀ /-- The unique map to the terminal object. -/ noncomputable def χ₀ (U : C) : U ⟶ h.Ω₀ := h.isTerminalΩ₀.from U +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.χ₀ := χ₀ @[deprecated (since := "2026-03-06")] @@ -548,6 +561,7 @@ alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.χ₀ := χ₀ include h in lemma hasTerminal : HasTerminal C := h.isTerminalΩ₀.hasTerminal +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.hasTerminal := hasTerminal @[deprecated (since := "2026-03-06")] @@ -559,6 +573,7 @@ variable [HasTerminal C] noncomputable def isoΩ₀ : (h.Ω₀ : C) ≅ ⊤_ C := h.isTerminalΩ₀.conePointUniqueUpToIso (limit.isLimit _) +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.isoΩ₀ := isoΩ₀ @[deprecated (since := "2026-03-06")] @@ -582,6 +597,7 @@ noncomputable def classifier : Subobject.Classifier C where (by simp) (h.isTerminalΩ₀.hom_ext _ _) (by simp) (by simp) exact h.uniq this +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-06")] alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.classifier := classifier @[deprecated (since := "2026-03-06")] diff --git a/Mathlib/Data/Set/FiniteExhaustion.lean b/Mathlib/Data/Set/FiniteExhaustion.lean index 1d9bd2db3e8194..10b3a9449870e0 100644 --- a/Mathlib/Data/Set/FiniteExhaustion.lean +++ b/Mathlib/Data/Set/FiniteExhaustion.lean @@ -80,6 +80,7 @@ lemma _root_.Set.nonempty_finiteExhaustion_iff {s : Set α} : rw [← K.iUnion_eq] exact countable_iUnion <| fun i ↦ (K.finite i).countable +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias Set.nonempty_finiteExhaustion_iff := Set.nonempty_finiteExhaustion_iff diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 389c63c3be81ce..77f7642f8e1a13 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -317,6 +317,7 @@ theorem mdifferentiable [ContMDiffVectorBundle 1 F Z I] e.MDifferentiable (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) := ⟨e.contMDiffOn.mdifferentiableOn one_ne_zero, e.contMDiffOn_symm.mdifferentiableOn one_ne_zero⟩ +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias Bundle.Trivialization.mdifferentiable := mdifferentiable end diff --git a/Mathlib/GroupTheory/Submonoid/Inverses.lean b/Mathlib/GroupTheory/Submonoid/Inverses.lean index 847d5ddb31f104..d4efa62017f0eb 100644 --- a/Mathlib/GroupTheory/Submonoid/Inverses.lean +++ b/Mathlib/GroupTheory/Submonoid/Inverses.lean @@ -56,6 +56,7 @@ theorem _root_.IsUnit.submonoid.coe_inv [Monoid M] (x : IsUnit.submonoid M) : @[deprecated (since := "2026-05-24")] alias _root_.AddSubmonoid.IsUnit.Submonoid.coe_neg := IsAddUnit.addSubmonoid.coe_neg +set_option linter.dupNamespace false in @[to_additive existing, deprecated (since := "2026-05-24")] alias IsUnit.Submonoid.coe_inv := IsUnit.submonoid.coe_inv diff --git a/Mathlib/LinearAlgebra/FreeModule/Basic.lean b/Mathlib/LinearAlgebra/FreeModule/Basic.lean index 4e9d8b89e6b7bf..37d796cf745408 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Basic.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Basic.lean @@ -149,6 +149,7 @@ lemma iff_of_equiv {R R' M M'} [Semiring R] [AddCommMonoid M] [Module R M] instance shrink [Small.{w} M] : Module.Free R (Shrink.{w} M) := Module.Free.of_equiv (Shrink.linearEquiv R M).symm +set_option linter.dupNamespace false in @[deprecated (since := "2026-04-18")] alias Module.free_shrink := shrink variable (R M N) diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index c1a73bf4892d9d..b430f0e1e4d1cf 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -249,6 +249,7 @@ protected def singleton {α} (a : α) : ({a} : Set α) ≃ PUnit.{u} := lemma _root_.Equiv.strictMono_setCongr {α : Type*} [Preorder α] {S T : Set α} (h : S = T) : StrictMono (setCongr h) := fun _ _ ↦ id +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias Equiv.strictMono_setCongr := Equiv.strictMono_setCongr /-- If `a ∉ s`, then `insert a s` is equivalent to `s ⊕ PUnit`. -/ diff --git a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean index ff7e2f7603593e..32dfaa31d15c60 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean @@ -175,58 +175,71 @@ theorem adicAbv_natCast_le_one (n : ℕ) : adicAbv K v n ≤ 1 := theorem adicAbv_intCast_le_one (n : ℤ) : adicAbv K v n ≤ 1 := (isNonarchimedean_adicAbv K v).apply_intCast_le_one +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.one_lt_absNorm := one_lt_absNorm @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.one_lt_absNorm := one_lt_absNorm +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.one_lt_absNorm_nnreal := one_lt_absNorm_nnreal @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.one_lt_absNorm_nnreal := one_lt_absNorm_nnreal +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.absNorm_ne_zero := absNorm_ne_zero @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.absNorm_ne_zero := absNorm_ne_zero +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv := adicAbv @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv := adicAbv +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_def := adicAbv_def @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_def := adicAbv_def +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.isNonarchimedean_adicAbv := isNonarchimedean_adicAbv @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.isNonarchimedean_adicAbv := isNonarchimedean_adicAbv +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.instRankOneAdicCompletion := instRankOneAdicCompletion @[deprecated (since := "2026-03-11")] alias _root_.NumberField.instRankOneAdicCompletion := instRankOneAdicCompletion +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.instNormedFieldValuedAdicCompletion := instNormedFieldValuedAdicCompletion @[deprecated (since := "2026-03-11")] alias _root_.NumberField.instNormedFieldValuedAdicCompletion := instNormedFieldValuedAdicCompletion +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.rankOne_hom'_def := rankOne_hom'_def @[deprecated (since := "2026-03-11")] alias _root_.NumberField.rankOne_hom'_def := rankOne_hom'_def +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.toNNReal_valued_eq_adicAbv := toNNReal_valued_eq_adicAbv @[deprecated (since := "2026-03-11")] alias _root_.NumberField.toNNReal_valued_eq_adicAbv := toNNReal_valued_eq_adicAbv +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_add_le_max := adicAbv_add_le_max @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_add_le_max := adicAbv_add_le_max +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_natCast_le_one := adicAbv_natCast_le_one @[deprecated (since := "2026-03-11")] alias _root_.NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_natCast_le_one := adicAbv_natCast_le_one +set_option linter.dupNamespace false in @[deprecated (since := "2026-03-11")] alias NumberField.RingOfIntegers.HeightOneSpectrum.adicAbv_intCast_le_one := adicAbv_intCast_le_one @[deprecated (since := "2026-03-11")] diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index d5ffa594968644..5f6e2279bcd393 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -309,6 +309,7 @@ open scoped Classical in protected noncomputable instance fintype [NumberField K] : Fintype (InfinitePlace K) := Set.fintypeRange _ +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias NumberField.InfinitePlace.fintype := InfinitePlace.fintype diff --git a/Mathlib/Order/Filter/Germ/Basic.lean b/Mathlib/Order/Filter/Germ/Basic.lean index dd0aa8723d3e62..8e4bdba81b88d5 100644 --- a/Mathlib/Order/Filter/Germ/Basic.lean +++ b/Mathlib/Order/Filter/Germ/Basic.lean @@ -256,6 +256,7 @@ theorem _root_.Filter.Tendsto.congr_germ {f g : β → γ} {l : Filter α} {l' : (h : f =ᶠ[l'] g) {φ : α → β} (hφ : Tendsto φ l l') : (f ∘ φ : Germ l γ) = g ∘ φ := EventuallyEq.germ_eq (h.comp_tendsto hφ) +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias Filter.Tendsto.congr_germ := Filter.Tendsto.congr_germ lemma isConstant_comp_tendsto {lc : Filter γ} {g : γ → α} diff --git a/Mathlib/RingTheory/Etale/Basic.lean b/Mathlib/RingTheory/Etale/Basic.lean index 1277c23b518a03..c941952589073a 100644 --- a/Mathlib/RingTheory/Etale/Basic.lean +++ b/Mathlib/RingTheory/Etale/Basic.lean @@ -130,6 +130,7 @@ lemma _root_.Algebra.FormallySmooth.iff_restrictScalars [FormallyEtale R A] : Algebra.FormallySmooth R B ↔ Algebra.FormallySmooth A B := ⟨fun _ ↦ .of_restrictScalars R _ _, fun _ ↦ .comp _ A _⟩ +set_option linter.dupNamespace false in @[deprecated (since := "2025-12-09")] alias Algebra.FormallyEtale.of_restrictScalars := of_restrictScalars @@ -142,6 +143,7 @@ lemma iff_of_surjective rw [FormallyEtale.iff_formallyUnramified_and_formallySmooth, ← FormallySmooth.iff_of_surjective h, and_iff_right (FormallyUnramified.of_surjective (Algebra.ofId R S) h)] +set_option linter.dupNamespace false in @[deprecated (since := "2025-12-09")] alias Algebra.FormallyEtale.iff_of_surjective := iff_of_surjective diff --git a/Mathlib/RingTheory/Finiteness/Basic.lean b/Mathlib/RingTheory/Finiteness/Basic.lean index 4ea58f2b32969a..7cb4b5fed17525 100644 --- a/Mathlib/RingTheory/Finiteness/Basic.lean +++ b/Mathlib/RingTheory/Finiteness/Basic.lean @@ -324,6 +324,7 @@ universe u in instance shrink [Module.Finite R M] [Small.{u} M] : Module.Finite R (Shrink.{u} M) := Module.Finite.equiv (Shrink.linearEquiv R M).symm +set_option linter.dupNamespace false in @[deprecated (since := "2026-04-18")] alias Module.finite_shrink := shrink /-- A submodule is finite as a module iff it is finitely generated. -/ diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index 10c1e8486bc3c8..bc903ffb8e07dd 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -426,6 +426,7 @@ attribute [local instance] Algebra.TensorProduct.rightAlgebra in lemma commRight_symm_tmul (s : S) (a : A) : (commRight R S A).symm (a ⊗ₜ[R] s) = s ⊗ₜ a := rfl +set_option linter.dupNamespace false in @[deprecated (since := "2026-05-24")] alias Algebra.TensorProduct.commRight_symm_tmul := commRight_symm_tmul diff --git a/Mathlib/Tactic/Linter/Lint.lean b/Mathlib/Tactic/Linter/Lint.lean index 1b1bd995958ab8..b46f67dd8ccc4a 100644 --- a/Mathlib/Tactic/Linter/Lint.lean +++ b/Mathlib/Tactic/Linter/Lint.lean @@ -11,7 +11,6 @@ module public import Batteries.Tactic.Lint -- shake: keep public import Lean.Linter.Deprecated public import Mathlib.Tactic.DeclarationNames -public import Batteries.Tactic.Lint.Basic /-! # Linters for Mathlib @@ -63,21 +62,19 @@ namespace Mathlib.Linter /-! ### `dupNamespace` linter -The `dupNamespace` linter produces a warning when a declaration contains the same namespace -at least twice consecutively. +The `dupNamespace` linter produces a warning when a component of a declaration name is repeated +several times. The repetition does not have to be consecutive. Examples: `Nat.Nat.foo`, +`One.two.two`, `Nat.One.Nat`, `Nat.Prime.Nat.Prime.foo`, `Nat.Prime.Nat.bar` -For instance, `Nat.Nat.foo` and `One.two.two` trigger a warning, while `Nat.One.Nat` does not. +The linter also warns about auto-generated declarations (such as, those generated by `to_additive`). -/ /-- -The `dupNamespace` linter is set on by default. Lean emits a warning on any declaration that -contains the same namespace at least twice consecutively. +The `dupNamespace` linter produces a warning when a component of a declaration name is repeated +several times. The repetition does not have to be consecutive. Examples: `Nat.Nat.foo`, +`One.two.two`, `Nat.One.Nat`, `Nat.Prime.Nat.Prime.foo`, `Nat.Prime.Nat.bar` -For instance, `Nat.Nat.foo` and `One.two.two` trigger a warning, while `Nat.One.Nat` does not. - -*Note.* -This linter will not detect duplication in namespaces of autogenerated declarations -(other than the one whose `declId` is present in the source declaration). +The linter also warns about auto-generated declarations (such as, those generated by `to_additive`). -/ public register_option linter.dupNamespace : Bool := { defValue := true @@ -96,12 +93,23 @@ def dupNamespace : Linter where run := withSetOptionIn fun stx ↦ do aliases ← getAliasSyntax exp for id in (← getNamesFrom (stx.getPos?.getD default)) ++ aliases do let declName := id.getId + -- We intentionally *do* lint deprecated declarations: + -- this is important since people can forget to add a `_root_` when adding deprecations. if declName.hasMacroScopes || isPrivateName declName then continue let nm := declName.components - let some (dup, _) := nm.zip (nm.tailD []) |>.find? fun (x, y) ↦ x == y - | continue - Linter.logLint linter.dupNamespace id - m!"The namespace '{dup}' is duplicated in the declaration '{declName}'" + -- Collect distinct components which appear more than once. + let duplicated := List.eraseDups <| nm.filter (fun comp ↦ nm.count comp > 1) + match duplicated with + | [] => continue + | [ns] => + Linter.logLint linter.dupNamespace id + m!"The namespace `{ns}` is duplicated in the declaration \ + `{.ofConstName (fullNames := true) declName}`." + | dup => + let ns := MessageData.andList (duplicated.map (m!"`{·}`")) + Linter.logLint linter.dupNamespace id + m!"The namespaces {ns} are duplicated in the declaration \ + `{.ofConstName (fullNames := true) declName}`." initialize addLinter dupNamespace diff --git a/MathlibTest/Linter/DupNamespace.lean b/MathlibTest/Linter/DupNamespace.lean index b5013fb0c8d7c5..56e0180ba9b60d 100644 --- a/MathlibTest/Linter/DupNamespace.lean +++ b/MathlibTest/Linter/DupNamespace.lean @@ -2,7 +2,7 @@ import Batteries.Tactic.Alias import Mathlib.Tactic.Linter.Lint import Mathlib.Tactic.ToAdditive /-- -warning: The namespace 'add' is duplicated in the declaration 'add.add' +warning: The namespace `add` is duplicated in the declaration `add.add`. Note: This linter can be disabled with `set_option linter.dupNamespace false` -/ @@ -12,7 +12,7 @@ def add.add := True namespace Foo /-- -warning: The namespace 'Foo' is duplicated in the declaration 'Foo.Foo.foo' +warning: The namespace `Foo` is duplicated in the declaration `Foo.Foo.foo`. Note: This linter can be disabled with `set_option linter.dupNamespace false` -/ @@ -21,7 +21,7 @@ def Foo.foo := True set_option linter.translateRedundant false in /-- -warning: The namespace 'add' is duplicated in the declaration 'Foo.add.add' +warning: The namespace `add` is duplicated in the declaration `Foo.add.add`. Note: This linter can be disabled with `set_option linter.dupNamespace false` -/ @@ -37,7 +37,7 @@ run_cmd Lean.Elab.Command.liftTermElabM do namespace Nat /-- -warning: The namespace 'Nat' is duplicated in the declaration 'Foo.Nat.Nat.Nats' +warning: The namespace `Nat` is duplicated in the declaration `Foo.Nat.Nat.Nats`. Note: This linter can be disabled with `set_option linter.dupNamespace false` -/ @@ -50,11 +50,11 @@ end Foo namespace add /-- -warning: The namespace 'add' is duplicated in the declaration 'add.add' +warning: The namespace `add` is duplicated in the declaration `add.add`. Note: This linter can be disabled with `set_option linter.dupNamespace false` --- -warning: The namespace 'add' is duplicated in the declaration 'add.add' +warning: The namespace `add` is duplicated in the declaration `add.add`. Note: This linter can be disabled with `set_option linter.dupNamespace false` -/ @@ -62,3 +62,111 @@ Note: This linter can be disabled with `set_option linter.dupNamespace false` export Nat (add add_comm add) end add + +/-- +warning: The namespace `Foo` is duplicated in the declaration `Foo.Foo`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Foo : True := trivial + +/-- +warning: The namespace `Foo` is duplicated in the declaration `Bar.Foo.Foo`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Bar.Foo.Foo : True := trivial + +/-- +warning: The namespace `Foo` is duplicated in the declaration `Foo.Foo.Bar`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Foo.Bar : True := trivial + +/-- +warning: The namespace `Foo` is duplicated in the declaration `Foo.Foo.Bar.Baz.hoge`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Foo.Bar.Baz.hoge : True := trivial + +#guard_msgs in +lemma Foo.Foos.Bar.Baz : True := trivial + +/-- +warning: The namespace `Foo` is duplicated in the declaration `Foo.Bar.Foo.baz`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Bar.Foo.baz : True := trivial + +/-- +warning: The namespaces `Foo` and `Bar` are duplicated in the declaration `Foo.Bar.Foo.Bar.baz`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Bar.Foo.Bar.baz : True := trivial + +/-- +warning: The namespaces `Foo` and `Baz` are duplicated in the declaration `Foo.Bar.Baz.Hoge.Foo.Baz.baz`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Bar.Baz.Hoge.Foo.Baz.baz : True := trivial + +/-- +warning: The namespaces `Foo` and `Bar` are duplicated in the declaration `Foo.Bar.Baz.Hoge.Foo.Bar.baz`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Bar.Baz.Hoge.Foo.Bar.baz : True := trivial + +/-- +warning: The namespaces `Foo`, `Bar`, and `Baz` are duplicated in the declaration `Foo.Bar.Baz.Hoge.Foo.Bar.Baz.az`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +lemma Foo.Bar.Baz.Hoge.Foo.Bar.Baz.az : True := trivial + +-- The linter detects the final name and not just what's written in the syntax. +namespace Foo.Bar +/-- +warning: The namespaces `Foo` and `Bar` are duplicated in the declaration `Foo.Bar.Foo.Bar.baz'`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +def Foo.Bar.baz' := 42 +end Foo.Bar + +-- We detect additional generated names. +/-- +warning: The namespace `AddSubgroup` is duplicated in the declaration `AddSubgroup.AddSubgroup.foo`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +@[to_additive AddSubgroup.AddSubgroup.foo] +def Subgroup.AddSubgroup.foo := 42 +-- (`AddSubgroup` is duplicated but only after translation) + +-- The linter works on deprecated decls: this is important +-- since people can forget to add a `_root_` when adding deprecations. +/-- +warning: The namespace `Foo` is duplicated in the declaration `Foo.Bar.Foo.baz'`. + +Note: This linter can be disabled with `set_option linter.dupNamespace false` +-/ +#guard_msgs in +@[deprecated "" (since := "")] +def Foo.Bar.Foo.baz' := 42 From af4123a60c150d588ffbc6228a83c27ef133fe0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= <4094732+RemyDegenne@users.noreply.github.com> Date: Thu, 2 Jul 2026 07:07:38 +0000 Subject: [PATCH 0533/1300] feat: lemmas about operations on EReal (#41246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaëtan Serré Co-authored-by: Remy Degenne --- Mathlib/Data/EReal/Operations.lean | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Mathlib/Data/EReal/Operations.lean b/Mathlib/Data/EReal/Operations.lean index 53bf367a596b7d..da8c1992221660 100644 --- a/Mathlib/Data/EReal/Operations.lean +++ b/Mathlib/Data/EReal/Operations.lean @@ -419,6 +419,11 @@ lemma toENNReal_sub {x y : EReal} (hy : 0 ≤ y) : ofReal_sub x (EReal.coe_nonneg.mp hy)] simp +lemma add_sub_add_comm {a b c d : EReal} (h1 : c ≠ ⊥ ∨ d ≠ ⊤) (h2 : c ≠ ⊤ ∨ d ≠ ⊥) : + a + b - (c + d) = (a - c) + (b - d) := by + rw [sub_eq_add_neg, sub_eq_add_neg, sub_eq_add_neg, EReal.neg_add h1 h2, sub_eq_add_neg] + grind + lemma add_sub_cancel_right {a : EReal} {b : Real} : a + b - b = a := by cases a <;> norm_cast exact _root_.add_sub_cancel_right _ _ @@ -488,6 +493,27 @@ lemma sub_lt_of_lt_add {a b c : EReal} (h : a < b + c) : a - c < b := lemma sub_lt_of_lt_add' {a b c : EReal} (h : a < b + c) : a - b < c := sub_lt_of_lt_add <| by rwa [add_comm] +lemma sub_lt_sub_of_le_of_gt {x y z t : EReal} (h : x ≤ y) (h' : z < t) + (hx_top : x ≠ ⊤) (hy_bot : y ≠ ⊥) : + x - t < y - z := by + refine sub_lt_of_lt_add' ?_ + rw [add_sub_assoc', add_comm, add_sub_assoc] + by_cases hy_top : y = ⊤ + · rw [hy_top, top_add_of_ne_bot] + · exact hx_top.lt_top + · exact ne_bot_of_le_ne_bot (by simp) (sub_pos.mpr h').le + by_cases hxy : x = y + · rw [hxy] + lift y to ℝ using ⟨hy_top, hy_bot⟩ + by_cases htz_top : t - z = ⊤ + · simp_all + rw [← coe_toReal htz_top <| ne_bot_of_le_ne_bot (by simp) (sub_pos.mpr h').le] + norm_cast + refine lt_add_of_pos_right y ?_ + exact EReal.toReal_pos (sub_pos.mpr h') htz_top + · rw [← add_zero x] + exact add_lt_add (by grind) (sub_pos.mpr h') + /-! ### Addition and order -/ lemma le_of_forall_lt_iff_le {x y : EReal} : (∀ z : ℝ, x < z → y ≤ z) ↔ y ≤ x := by @@ -790,6 +816,11 @@ lemma left_distrib_of_nonneg {a b c : EReal} (ha : 0 ≤ a) (hb : 0 ≤ b) : nth_rewrite 1 [EReal.mul_comm]; nth_rewrite 2 [EReal.mul_comm]; nth_rewrite 3 [EReal.mul_comm] exact right_distrib_of_nonneg ha hb +lemma mul_sub_of_nonneg_of_nonpos {a b c : EReal} (hb : 0 ≤ b) (hc : c ≤ 0) : + a * (b - c) = a * b - a * c := by + rw [sub_eq_add_neg, left_distrib_of_nonneg hb (by simpa)] + simp [← neg_mul, sub_eq_add_neg] + lemma left_distrib_of_nonneg_of_ne_top {x : EReal} (hx_nonneg : 0 ≤ x) (hx_ne_top : x ≠ ⊤) (y z : EReal) : x * (y + z) = x * y + x * z := by @@ -805,6 +836,16 @@ lemma right_distrib_of_nonneg_of_ne_top {x : EReal} (hx_nonneg : 0 ≤ x) (y + z) * x = y * x + z * x := by simpa only [EReal.mul_comm] using left_distrib_of_nonneg_of_ne_top hx_nonneg hx_ne_top y z +lemma mul_sub_of_nonneg_of_ne_top {a b c : EReal} (ha : 0 ≤ a) (ha' : a ≠ ⊤) : + a * (b - c) = a * b - a * c := by + rw [sub_eq_add_neg, left_distrib_of_nonneg_of_ne_top ha ha'] + simp [← neg_mul, sub_eq_add_neg] + +lemma sub_mul_of_nonneg_of_ne_top {a b c : EReal} (ha : 0 ≤ a) (ha' : a ≠ ⊤) : + (b - c) * a = b * a - c * a := by + rw [sub_eq_add_neg, right_distrib_of_nonneg_of_ne_top ha ha'] + simp [← neg_mul, sub_eq_add_neg] + @[simp] lemma nsmul_eq_mul (n : ℕ) (x : EReal) : n • x = n * x := by induction n with From a22faf7b71a717c172640d940a5be690949d2f85 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 2 Jul 2026 07:36:41 +0000 Subject: [PATCH 0534/1300] doc(CategoryTheory/Preadditive/LeftExact): fix stale declaration names in module docstring (#41270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates two references in the module docstring to the actual (underscore-style) declaration names `preservesBinaryProducts_of_preservesKernels` and `preservesEqualizer_of_preservesKernels`, completing the docstring fixes of https://github.com/leanprover-community/mathlib4/pull/41237. 🤖 Prepared with Claude Code --- Mathlib/CategoryTheory/Preadditive/LeftExact.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean index a601510f6b4612..def108ecf37a58 100644 --- a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean +++ b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean @@ -18,8 +18,8 @@ preserves kernels. The dual result holds for right exact functors and cokernels. ## Main results * We first derive preservation of binary products in the lemma - `preservesBinaryProductsOfPreservesKernels`, -* then show the preservation of equalizers in `preservesEqualizerOfPreservesKernels`, + `preservesBinaryProducts_of_preservesKernels`, +* then show the preservation of equalizers in `preservesEqualizer_of_preservesKernels`, * and then derive the preservation of all finite limits with the usual construction. -/ From 3061958a997aa0f8eaab14dfee32353968cd991f Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 2 Jul 2026 07:46:42 +0000 Subject: [PATCH 0535/1300] chore(CategoryTheory/Triangulated/WeakKernels): remove unused variable (#41265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR removes an unused `variable {X Y : C} (f : X ⟶ Y)` line and a stray double blank line in `WeakKernels.lean`. Neither def in the file uses these binders (both take `T : Triangle C`, and the `HasWeakKernels` instance binds its own `f`), so the `variable` command is inert. A follow-up to https://github.com/leanprover-community/mathlib4/pull/41162. 🤖 Prepared with Claude Code --- Mathlib/CategoryTheory/Triangulated/WeakKernels.lean | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean b/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean index 1e7ed57910eb57..980bf83c792ae4 100644 --- a/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean +++ b/Mathlib/CategoryTheory/Triangulated/WeakKernels.lean @@ -8,7 +8,6 @@ module public import Mathlib.CategoryTheory.Triangulated.Pretriangulated public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakKernels - /-! # Weak kernels in pretriangulated categories @@ -30,8 +29,6 @@ open Limits Category Preadditive Pretriangulated variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] [∀ n : ℤ, Functor.Additive (shiftFunctor C n)] [Pretriangulated C] -variable {X Y : C} (f : X ⟶ Y) - /-- If `T` is a distinguished triangle, then `T.mor₁` defines a kernel fork for `T.mor₂`. -/ def kernelForkOfDistTriangle (T : Triangle C) (dT : T ∈ distTriang C) : KernelFork T.mor₂ := KernelFork.ofι T.mor₁ (comp_distTriang_mor_zero₁₂ _ dT) From 42e335ab819aaa0c2283686ec0a7bbd9bccedc9f Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 2 Jul 2026 07:46:43 +0000 Subject: [PATCH 0536/1300] chore(CategoryTheory/Limits/WeakLimits): fix weak pullbacks theorem name and docstrings (#41266) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR renames `hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakKernels` to `hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakEqualizers`, since its hypothesis is `HasWeakEqualizers`, not weak kernels, and fixes several docstring typos in `WeakPullbacks.lean` and `WeakKernels.lean`. These are follow-ups to https://github.com/leanprover-community/mathlib4/pull/41075. 🤖 Prepared with Claude Code --- Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean | 2 +- .../CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean index 7e0cb008f5d725..d6a9baeaf14f22 100644 --- a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakKernels.lean @@ -12,7 +12,7 @@ public import Mathlib.CategoryTheory.Preadditive.Basic /-! # Weak kernels -These are weak equalizes for functors of the form `ParallelPair f 0`. +These are weak equalizers for functors of the form `parallelPair f 0`. If the category is preadditive, then weak equalizers exist if and only if weak kernels exist. (See `hasWeakEqualizer_of_hasWeakKernel` and `hasWeakKernel_of_hasWeakEqualizer`.) diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean index bfee2bd6539aad..259502b1308092 100644 --- a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean @@ -12,8 +12,8 @@ public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakEqualizers These are weak limits for diagrams of shape `WalkingCospan`. -If a category has binary products and weak equalizers, then it has weak kernels -(see `hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakKernels`). +If a category has binary products and weak equalizers, then it has weak pullbacks +(see `hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakEqualizers`). -/ @@ -211,7 +211,7 @@ def weakPullbackIsWeakPullback {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasWeakP variable (C) -/-- A category `HasPullbacks` if it has all weak limits of shape `WalkingCospan`, i.e. if it +/-- A category `HasWeakPullbacks` if it has all weak limits of shape `WalkingCospan`, i.e. if it has a weak pullback for every pair of morphisms with the same codomain. -/ abbrev HasWeakPullbacks := HasWeakLimitsOfShape WalkingCospan C @@ -242,7 +242,7 @@ attribute [local instance] hasWeakLimit_cospan_of_hasLimit_pair_of_hasWeakLimit_ /-- If a category has all binary products and all weak equalizers, then it also has all weak pullbacks. As usual, this is not an instance, since there may be a more direct way to construct weak pullbacks. -/ -theorem hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakKernels +theorem hasWeakPullbacks_of_hasBinaryProducts_of_hasWeakEqualizers [HasBinaryProducts C] [HasWeakEqualizers C] : HasWeakPullbacks C where hasWeakLimit F := hasWeakLimit_of_iso (diagramIsoCospan F).symm From 564ff5af9b5f3b50769a51c10def6bbdcf9c9471 Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:25:40 +0000 Subject: [PATCH 0537/1300] chore(LinearAlgebra/Dimension/Free): fix docstring (#41257) * Fix https://github.com/leanprover-community/mathlib4/pull/41211/#discussion_r3505416094 Co-authored-by: artie2000 --- Mathlib/LinearAlgebra/Dimension/Free.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index 7e159ff9705648..e61fdf32557a31 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -14,7 +14,7 @@ public import Mathlib.SetTheory.Cardinal.Finsupp # Rank of free modules ## Main result -- `Module.nonempty_equiv_iff_lift_rank_eq`: +- `Module.nonempty_linearEquiv_iff_lift_rank_eq`: Two free modules are isomorphic iff they have the same dimension. - `Module.finBasis`: An arbitrary basis of a finite free module indexed by `Fin n` given `finrank R M = n`. From db73cf1a4b64b689cd8fa77fcfef2c895028588a Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:50:40 +0000 Subject: [PATCH 0538/1300] feat(Algebra/Module/LinearMap/FiniteRange): iff version of isQuasiInverse_subtype_projectionOnto (#41272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR strengthens `isQuasiInverse_subtype_projectionOnto` to an iff (`... ↔ IsNoetherian K T`), matching the iff/instance lemma pairs established in https://github.com/leanprover-community/mathlib4/pull/41038, and derives the original statement from it. 🤖 Prepared with Claude Code --- Mathlib/Algebra/Module/LinearMap/FiniteRange.lean | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean index 7524d72a26c15f..c3109ab524ca7b 100644 --- a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean +++ b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean @@ -456,12 +456,16 @@ lemma IsQuasiInverse.of_comp_right {u : V →ₗ[K] V₂} {v : V₂ →ₗ[K] V (w ∘ₗ v).IsQuasiInverse u := ⟨hw.1, IsRightQuasiInverse.of_comp_right hv.1 hw.2⟩ +lemma isQuasiInverse_subtype_projectionOnto_iff {S T : Submodule K V} (hST : IsCompl S T) : + IsQuasiInverse S.subtype (S.projectionOnto T hST) ↔ IsNoetherian K T := by + rw [IsQuasiInverse, and_iff_left (by simp [IsRightQuasiInverse, projectionOnto_comp_subtype]), + IsLeftQuasiInverse, ← projection, + FiniteRangeSetoid.projection_equiv_id_iff_isNoetherian hST] + lemma isQuasiInverse_subtype_projectionOnto {S T : Submodule K V} [IsNoetherian K T] (hST : IsCompl S T) : - IsQuasiInverse S.subtype (S.projectionOnto T hST) := by - constructor - · grw [IsLeftQuasiInverse, ← FiniteRangeSetoid.projection_equiv_id hST, projection] - · simp [IsRightQuasiInverse, projectionOnto_comp_subtype] + IsQuasiInverse S.subtype (S.projectionOnto T hST) := + isQuasiInverse_subtype_projectionOnto_iff hST |>.mpr inferInstance end QuasiInverse From af2f0a4b1dacaae7569a82641960b7f833bc3a69 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:50:42 +0000 Subject: [PATCH 0539/1300] feat(SetTheory/Cardinal/Finite): add a NeZero instance for Nat.card (#41274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds `instance [Nonempty α] [Finite α] : NeZero (Nat.card α)`, paralleling the existing `NeZero (Fintype.card α)` instance, and removes the two manual `have : NeZero (Nat.card _)` workarounds it obsoletes in `CyclotomicCharacter.lean`. Prompted by https://github.com/leanprover-community/mathlib4/pull/41210, whose `Fintype.card` → `Nat.card` migration needed exactly this instance. 🤖 Prepared with Claude Code --- Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean | 2 -- Mathlib/SetTheory/Cardinal/Finite.lean | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean index 7718d034225e03..eaa68d6f06b3d3 100644 --- a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean +++ b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean @@ -131,7 +131,6 @@ local notation "χ₀" => modularCyclotomicCharacter.toFun /-- The formula which characterises the output of `modularCyclotomicCharacter g n`. -/ theorem toFun_spec (g : L ≃+* L) {n : ℕ} [NeZero n] (t : rootsOfUnity n L) : g (t : Lˣ) = (t ^ (χ₀ n g).val : Lˣ) := by - have : NeZero (Nat.card (rootsOfUnity n L)) := ⟨Nat.card_pos.ne'⟩ rw [modularCyclotomicCharacter.aux_spec g n t, ← zpow_natCast, modularCyclotomicCharacter.toFun, ZMod.val_intCast, ← Subgroup.coe_zpow] exact Units.ext_iff.1 <| SetCoe.ext_iff.2 <| @@ -169,7 +168,6 @@ lemma id : χ₀ n (RingEquiv.refl L) = 1 := by lemma comp (g h : L ≃+* L) : χ₀ n (g * h) = χ₀ n g * χ₀ n h := by - have : NeZero (Nat.card (rootsOfUnity n L)) := ⟨Nat.card_pos.ne'⟩ refine (toFun_unique n (g * h) _ <| fun ζ ↦ ?_).symm change g (h (ζ : Lˣ)) = _ rw [toFun_spec, ← Subgroup.coe_pow, toFun_spec, mul_comm, Subgroup.coe_pow, ← pow_mul, diff --git a/Mathlib/SetTheory/Cardinal/Finite.lean b/Mathlib/SetTheory/Cardinal/Finite.lean index b473a4c4dc3384..e765a8b236bf85 100644 --- a/Mathlib/SetTheory/Cardinal/Finite.lean +++ b/Mathlib/SetTheory/Cardinal/Finite.lean @@ -84,6 +84,8 @@ lemma card_pos_iff : 0 < Nat.card α ↔ Nonempty α ∧ Finite α := by @[simp] lemma card_pos [Nonempty α] [Finite α] : 0 < Nat.card α := card_pos_iff.2 ⟨‹_›, ‹_›⟩ +instance [Nonempty α] [Finite α] : NeZero (Nat.card α) := ⟨card_pos.ne'⟩ + theorem finite_of_card_ne_zero (h : Nat.card α ≠ 0) : Finite α := (card_ne_zero.1 h).2 theorem card_congr (f : α ≃ β) : Nat.card α = Nat.card β := From 40b45a066a39ea5a58a2acf3cf85bf513fc0e241 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:24:24 +0000 Subject: [PATCH 0540/1300] feat: generalize some lemmas by using conditional Jensen (#36888) This PR includes two possible ways of generalizing `integral_abs_condExp_le`: 1. Replace absolute values with norms. 2. Consider absolute values defined on a lattice with a solid norm. We also prove that if a function is in Lp then its conditional expectation is also in Lp. In order to prove these results, some of the lemmas about essSup are generalized to conditionally complete lattices. Created with the help of Codex. Co-authored-by: Yongxi(Aaron) Lin Co-authored-by: Yongxi Lin --- .../ConditionalExpectation/Basic.lean | 27 -- .../ConditionalExpectation/CondJensen.lean | 20 +- .../Function/ConditionalExpectation/Real.lean | 294 +++++++++++++----- Mathlib/MeasureTheory/Measure/Trim.lean | 26 +- Mathlib/Probability/CondVar.lean | 9 +- .../Probability/Martingale/BorelCantelli.lean | 9 +- Mathlib/Probability/Martingale/Centering.lean | 22 +- .../Probability/Martingale/Convergence.lean | 2 +- 8 files changed, 266 insertions(+), 143 deletions(-) diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean index 6cfccad643f8bb..049a6f52ee004e 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean @@ -404,33 +404,6 @@ end RCLike end NormedSpace -section Real -variable [InnerProductSpace ℝ E] [CompleteSpace E] - --- TODO: Generalize via the conditional Jensen inequality -lemma eLpNorm_condExp_le : eLpNorm (μ[f | m]) 2 μ ≤ eLpNorm f 2 μ := by - by_cases hm : m ≤ m₀; swap - · simp [condExp_of_not_le hm] - by_cases hfμ : SigmaFinite (μ.trim hm); swap - · rw [condExp_of_not_sigmaFinite hm hfμ] - simp - by_cases hfi : Integrable f μ; swap - · rw [condExp_of_not_integrable hfi] - simp - obtain hf | hf := eq_or_ne (eLpNorm f 2 μ) ∞ - · simp [hf] - replace hf : MemLp f 2 μ := ⟨hfi.1, Ne.lt_top' fun a ↦ hf a.symm⟩ - rw [← eLpNorm_congr_ae (hf.condExpL2_ae_eq_condExp' (𝕜 := ℝ) hm hfi)] - refine le_trans (eLpNorm_condExpL2_le hm _) ?_ - rw [eLpNorm_congr_ae hf.coeFn_toLp] - -protected lemma MemLp.condExp (hf : MemLp f 2 μ) : MemLp (μ[f | m]) 2 μ := by - by_cases hm : m ≤ m₀ - · exact ⟨(stronglyMeasurable_condExp.mono hm).aestronglyMeasurable, - eLpNorm_condExp_le.trans_lt hf.eLpNorm_lt_top⟩ - · simp [condExp_of_not_le hm] - -end Real end NormedAddCommGroup section NormedRing diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean index 7d25c166b20b66..bea52d41254491 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean @@ -243,7 +243,7 @@ theorem ConcaveOn.condExp_map_le_trim_univ {mE : MeasurableSpace E} [BorelSpace /-- In a Banach space `E` with a measure `μ`, then for any `f : α → E`, we have `‖𝔼[f | m]‖ ≤ᵐ[μ] 𝔼[‖f‖ | m]`. -/ -theorem norm_condExp_le : (‖μ[f | m] ·‖) ≤ᵐ[μ] μ[(‖f ·‖) | m] := by +theorem norm_condExp_le (f : α → E) : (‖μ[f | m] ·‖) ≤ᵐ[μ] μ[(‖f ·‖) | m] := by by_cases! hm : ¬ m ≤ mα · simp [condExp_of_not_le hm]; aesop by_cases! hμm : ¬ SigmaFinite (μ.trim hm) @@ -255,6 +255,24 @@ theorem norm_condExp_le : (‖μ[f | m] ·‖) ≤ᵐ[μ] μ[(‖f ·‖) | m] : exact convexOn_univ_norm.map_condExp_le_univ hm continuous_norm.lowerSemicontinuous hf_int hf_int.norm +theorem Integrable.norm_condExp_rpow_le {p : ℝ} (hp : 1 ≤ p) + (hfint : Integrable (fun x => ‖f x‖ ^ p) μ) : + (‖μ[f | m] ·‖ ^ p) ≤ᵐ[μ] μ[(‖f ·‖ ^ p) | m] := by + have hp' : 0 < p := by linarith + by_cases! hm : ¬ m ≤ mα + · simp [condExp_of_not_le hm, Real.zero_rpow hp'.ne.symm]; aesop + by_cases! hμm : ¬ SigmaFinite (μ.trim hm) + · simp [condExp_of_not_sigmaFinite hm hμm, Real.zero_rpow hp'.ne.symm]; aesop + by_cases! hf_int : ¬ Integrable f μ + · simp only [condExp_of_not_integrable hf_int, Pi.zero_apply, norm_zero, + Real.zero_rpow hp'.ne.symm] + apply condExp_nonneg + filter_upwards with a; positivity + have hl := (Real.continuous_rpow_const hp'.le).lowerSemicontinuous.lowerSemicontinuousOn (Ici 0) + have := (convexOn_rpow hp).map_condExp_le hm hl (by simp) isClosed_Ici hf_int.norm hfint + filter_upwards [norm_condExp_le f, this] with a ha hb + exact (Real.rpow_le_rpow (norm_nonneg _) ha hp'.le).trans hb + /-- **Conditional Jensen's inequality**: in a finite dimensional Banach space `E` with a measure `μ` that is σ-finite on a sub-σ-algebra `m`, if `φ : E → ℝ` is convex, then for any `f : α → E` such that `f` and `φ ∘ f` are integrable, we have `φ (𝔼[f | m]) ≤ᵐ[μ] 𝔼[φ ∘ f | m]`. -/ diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean index 8ff2777d878b7e..24c3958e3457f9 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean @@ -9,6 +9,9 @@ public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Indicator public import Mathlib.MeasureTheory.Function.UniformIntegrable public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.RadonNikodym +import Mathlib.MeasureTheory.Function.ConditionalExpectation.CondJensen +import Mathlib.MeasureTheory.Function.LpSeminorm.LpNorm + /-! # Conditional expectation of real-valued functions @@ -21,8 +24,6 @@ This file proves some results regarding the conditional expectation of real-valu Radon-Nikodym derivative of `fμ` restricted on `m` with respect to `μ` restricted on `m`. * `MeasureTheory.Integrable.uniformIntegrable_condExp`: the conditional expectation of a function form a uniformly integrable class. -* `MeasureTheory.condExp_mul_of_stronglyMeasurable_left`: the pull-out property of the conditional - expectation. -/ @@ -55,88 +56,105 @@ theorem rnDeriv_ae_eq_condExp {hm : m ≤ m0} [hμm : SigmaFinite (μ.trim hm)] exact (SignedMeasure.measurable_rnDeriv _ _).stronglyMeasurable · exact (SignedMeasure.measurable_rnDeriv _ _).stronglyMeasurable.aestronglyMeasurable --- TODO: the following couple of lemmas should be generalized and proved using Jensen's inequality --- for the conditional expectation (not in mathlib yet) . -theorem eLpNorm_one_condExp_le_eLpNorm (f : α → ℝ) : eLpNorm (μ[f | m]) 1 μ ≤ eLpNorm f 1 μ := by - by_cases hf : Integrable f μ - swap; · rw [condExp_of_not_integrable hf, eLpNorm_zero]; exact zero_le - by_cases hm : m ≤ m0 - swap; · rw [condExp_of_not_le hm, eLpNorm_zero]; exact zero_le - by_cases hsig : SigmaFinite (μ.trim hm) - swap; · rw [condExp_of_not_sigmaFinite hm hsig, eLpNorm_zero]; exact zero_le +section HasSolidNorm + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] + +lemma condExp_le_nonneg_const [PartialOrder E] [ClosedIciTopology E] [IsOrderedAddMonoid E] + [IsOrderedModule ℝ E] {f : α → E} {c : E} (hc : 0 ≤ c) (hfc : ∀ᵐ x ∂μ, f x ≤ c) : + ∀ᵐ x ∂μ, μ[f | m] x ≤ c := by + by_cases! hm : ¬ m ≤ m0 + · filter_upwards with a using by simpa [condExp_of_not_le hm] + by_cases! hfint : ¬ Integrable f μ + · filter_upwards with a using by simpa [condExp_of_not_integrable hfint] + by_cases! hsig : ¬ SigmaFinite (μ.trim hm) + · filter_upwards with a using by simpa [condExp_of_not_sigmaFinite hm hsig] + refine (isCountablySpanning_spanningSets (μ.trim hm)).null_of_forall_restrict_null ?_ ?_ <;> + rintro - ⟨n, rfl⟩ + · exact hm _ (measurableSet_spanningSets (μ.trim hm) n) + · have h1 := condExp_restrict_ae_eq_restrict hm (measurableSet_spanningSets (μ.trim hm) n) hfint + have h2 := condExp_mono (μ := μ.restrict (spanningSets (μ.trim hm) n)) (m := m) + hfint.restrict (integrable_const c) (ae_restrict_of_ae hfc) + filter_upwards [h1, h2] with a ha hb + grw [← ha, hb, condExp_const hm] + +variable [Lattice E] [HasSolidNorm E] [IsOrderedAddMonoid E] [IsOrderedModule ℝ E] + +theorem abs_condExp_ae_le_condExp_abs (f : α → E) : |(μ[f | m])| ≤ᵐ[μ] μ[|f| | m] := by + by_cases! hfint : ¬Integrable f μ + · simp only [condExp_of_not_integrable hfint, abs_zero] + apply condExp_nonneg + filter_upwards with a using abs_nonneg (f a) + have h1 := condExp_mono (m := m) hfint hfint.abs (.of_forall (fun x => le_abs_self f x)) + have h2 := condExp_mono (m := m) hfint.neg hfint.abs (.of_forall fun x => neg_le_abs (f x)) + filter_upwards [h1, h2, condExp_neg f m] with a ha hb hc + exact abs_le'.2 ⟨ha, hc.symm.le.trans hb⟩ + +theorem integral_abs_condExp_le (f : α → E) : ∫ x, |μ[f | m] x| ∂μ ≤ ∫ x, |f x| ∂μ := by + by_cases! hm : ¬ m ≤ m0 + · simpa [condExp_of_not_le hm] using integral_nonneg (fun x => abs_nonneg f x) + by_cases! hsig : ¬ SigmaFinite (μ.trim hm) + · simpa [condExp_of_not_sigmaFinite hm hsig] using integral_nonneg (fun x => abs_nonneg f x) calc - eLpNorm (μ[f | m]) 1 μ ≤ eLpNorm (μ[(|f|) | m]) 1 μ := by - refine eLpNorm_mono_ae ?_ - filter_upwards [condExp_mono hf hf.abs - (ae_of_all μ (fun x => le_abs_self (f x) : ∀ x, f x ≤ |f x|)), - (condExp_neg ..).symm.le.trans (condExp_mono hf.neg hf.abs - (ae_of_all μ (fun x => neg_le_abs (f x) : ∀ x, -f x ≤ |f x|)))] with x hx₁ hx₂ - exact abs_le_abs hx₁ hx₂ - _ = eLpNorm f 1 μ := by - rw [eLpNorm_one_eq_lintegral_enorm, eLpNorm_one_eq_lintegral_enorm, - ← ENNReal.toReal_eq_toReal_iff' (hasFiniteIntegral_iff_enorm.mp integrable_condExp.2).ne - (hasFiniteIntegral_iff_enorm.mp hf.2).ne, - ← integral_norm_eq_lintegral_enorm - (stronglyMeasurable_condExp.mono hm).aestronglyMeasurable, - ← integral_norm_eq_lintegral_enorm hf.1] - simp_rw [Real.norm_eq_abs] - rw (config := { occs := .pos [2] }) [← integral_condExp hm] - refine integral_congr_ae ?_ - have : 0 ≤ᵐ[μ] μ[(|f|) | m] := by - rw [← condExp_zero] - exact condExp_mono (integrable_zero _ _ _) hf.abs - (ae_of_all μ (fun x => abs_nonneg (f x) : ∀ x, 0 ≤ |f x|)) - filter_upwards [this] with x hx - exact abs_eq_self.2 hx - -theorem integral_abs_condExp_le (f : α → ℝ) : ∫ x, |(μ[f | m]) x| ∂μ ≤ ∫ x, |f x| ∂μ := by - by_cases hm : m ≤ m0 - swap - · simp_rw [condExp_of_not_le hm, Pi.zero_apply, abs_zero, integral_zero] - positivity - by_cases hfint : Integrable f μ - swap - · simp only [condExp_of_not_integrable hfint, Pi.zero_apply, abs_zero, integral_const, - smul_eq_mul, mul_zero] - positivity - rw [integral_eq_lintegral_of_nonneg_ae, integral_eq_lintegral_of_nonneg_ae] - · apply ENNReal.toReal_mono <;> simp_rw [← Real.norm_eq_abs, ofReal_norm] - · exact hfint.2.ne - · rw [← eLpNorm_one_eq_lintegral_enorm, ← eLpNorm_one_eq_lintegral_enorm] - exact eLpNorm_one_condExp_le_eLpNorm _ - · filter_upwards with x using abs_nonneg _ - · simp_rw [← Real.norm_eq_abs] - exact hfint.1.norm - · filter_upwards with x using abs_nonneg _ - · simp_rw [← Real.norm_eq_abs] - exact (stronglyMeasurable_condExp.mono hm).aestronglyMeasurable.norm + _ ≤ ∫ x, μ[|f| | m] x ∂μ := + integral_mono_ae integrable_condExp.abs integrable_condExp (abs_condExp_ae_le_condExp_abs f) + _ = _ := integral_condExp hm -theorem setIntegral_abs_condExp_le {s : Set α} (hs : MeasurableSet[m] s) (f : α → ℝ) : - ∫ x in s, |(μ[f | m]) x| ∂μ ≤ ∫ x in s, |f x| ∂μ := by - by_cases hnm : m ≤ m0 - swap - · simp_rw [condExp_of_not_le hnm, Pi.zero_apply, abs_zero, integral_zero] - positivity - by_cases hfint : Integrable f μ - swap - · simp only [condExp_of_not_integrable hfint, Pi.zero_apply, abs_zero, integral_const, - smul_eq_mul, mul_zero] - positivity - have : ∫ x in s, |(μ[f | m]) x| ∂μ = ∫ x, |(μ[s.indicator f | m]) x| ∂μ := by - rw [← integral_indicator (hnm _ hs)] - refine integral_congr_ae ?_ - have : (fun x => |(μ[s.indicator f | m]) x|) =ᵐ[μ] fun x => |s.indicator (μ[f | m]) x| := - (condExp_indicator hfint hs).fun_comp abs - refine EventuallyEq.trans (Eventually.of_forall fun x => ?_) this.symm - rw [← Real.norm_eq_abs, norm_indicator_eq_indicator_norm] - simp only [Real.norm_eq_abs] - rw [this, ← integral_indicator (hnm _ hs)] - refine (integral_abs_condExp_le _).trans - (le_of_eq <| integral_congr_ae <| Eventually.of_forall fun x => ?_) - simp_rw [← Real.norm_eq_abs, norm_indicator_eq_indicator_norm] +/-- Note that this is not trivial as we don't assume that `f` is integrable. -/ +lemma integral_condExp_le_of_ae_nonneg {f : α → ℝ} (hf : 0 ≤ᵐ[μ] f) : + ∫ x, μ[f | m] x ∂μ ≤ ∫ x, f x ∂μ := calc + ∫ x, μ[f | m] x ∂μ = ∫ x, |μ[f | m] x| ∂μ := by + apply integral_congr_ae + filter_upwards [condExp_nonneg hf] with ω hω using (abs_of_nonneg hω).symm + _ ≤ ∫ x, |f x| ∂μ := integral_abs_condExp_le f + _ = ∫ x, f x ∂μ := by + apply integral_congr_ae + filter_upwards [hf] with ω hω using abs_of_nonneg hω + +theorem setIntegral_abs_condExp_le {s : Set α} (hs : MeasurableSet[m] s) (f : α → E) : + ∫ x in s, |μ[f | m] x| ∂μ ≤ ∫ x in s, |f x| ∂μ := by + by_cases! hm : ¬ m ≤ m0 + · simpa [condExp_of_not_le hm] using integral_nonneg (fun x => abs_nonneg f x) + by_cases! hfint : ¬ Integrable f μ + · simpa [condExp_of_not_integrable hfint] using integral_nonneg (fun x => abs_nonneg f x) + by_cases! hsig : ¬ SigmaFinite (μ.trim hm) + · simpa [condExp_of_not_sigmaFinite hm hsig] using integral_nonneg (fun x => abs_nonneg f x) + calc + _ = ∫ x in s, |(μ.restrict s)[f | m] x| ∂μ := + (integral_congr_ae ((condExp_restrict_ae_eq_restrict hm hs hfint).fun_comp abs)).symm + _ ≤ _ := integral_abs_condExp_le f + +/-- Note that this is not trivial as we don't assume that `f` is integrable. -/ +lemma setIntegral_condExp_le_of_ae_restrict_nonneg {s : Set α} (hs : MeasurableSet[m] s) {f : α → ℝ} + (hf : 0 ≤ᵐ[μ.restrict s] f) : + ∫ x in s, μ[f | m] x ∂μ ≤ ∫ x in s, f x ∂μ := by + by_cases! hm : ¬ m ≤ m0 + · simpa [condExp_of_not_le hm] using setIntegral_nonneg_of_ae_restrict hf + by_cases! hfint : ¬ Integrable f μ + · simpa [condExp_of_not_integrable hfint] using setIntegral_nonneg_of_ae_restrict hf + by_cases! hsig : ¬ SigmaFinite (μ.trim hm) + · simpa [condExp_of_not_sigmaFinite hm hsig] using setIntegral_nonneg_of_ae_restrict hf + calc + ∫ x in s, μ[f | m] x ∂μ = ∫ x in s, (μ.restrict s)[f | m] x ∂μ := + integral_congr_ae (condExp_restrict_ae_eq_restrict hm hs hfint).symm + _ ≤ ∫ x in s, f x ∂μ := integral_condExp_le_of_ae_nonneg hf + +lemma setIntegral_condExp_le_of_ae_nonneg {s : Set α} (hs : MeasurableSet[m] s) {f : α → ℝ} + (hf : 0 ≤ᵐ[μ] f) : + ∫ x in s, μ[f | m] x ∂μ ≤ ∫ x in s, f x ∂μ := + setIntegral_condExp_le_of_ae_restrict_nonneg hs (ae_restrict_le hf) + +/-- If `|f|` is bounded almost everywhere by `R`, then so is its conditional expectation. -/ +theorem ae_bdd_abs_condExp_of_ae_bdd_abs {R : E} {f : α → E} (hbdd : ∀ᵐ x ∂μ, |f x| ≤ R) : + ∀ᵐ x ∂μ, |μ[f | m] x| ≤ R := by + by_cases! hn : {x | |f x| ≤ R} = ∅ + · exact measure_mono_null (by simp) <| ae_eq_empty.1 (hn ▸ (ae_eq_univ.2 hbdd).symm) + have hR : 0 ≤ R := (abs_nonneg _).trans hn.some_mem + exact (abs_condExp_ae_le_condExp_abs f).trans (condExp_le_nonneg_const (m := m) hR hbdd) /-- If the real-valued function `f` is bounded almost everywhere by `R`, then so is its conditional expectation. -/ +@[deprecated ae_bdd_abs_condExp_of_ae_bdd_abs (since := "2026-05-05")] theorem ae_bdd_condExp_of_ae_bdd {R : ℝ≥0} {f : α → ℝ} (hbdd : ∀ᵐ x ∂μ, |f x| ≤ R) : ∀ᵐ x ∂μ, |(μ[f | m]) x| ≤ R := by by_cases hnm : m ≤ m0 @@ -169,6 +187,120 @@ theorem ae_bdd_condExp_of_ae_bdd {R : ℝ≥0} {f : α → ℝ} (hbdd : ∀ᵐ x rw [enorm_eq_nnnorm, enorm_eq_nnnorm, ENNReal.coe_le_coe, Real.nnnorm_of_nonneg R.coe_nonneg] exact Subtype.mk_le_mk.2 (le_of_lt hx) +end HasSolidNorm + +section NormedSpace + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] + +theorem integral_norm_condExp_rpow_le {p : ℝ} (hp : 1 ≤ p) {f : α → E} + (hf : Integrable (‖f ·‖ ^ p) μ) : + ∫ x, ‖μ[f | m] x‖ ^ p ∂μ ≤ ∫ x, ‖f x‖ ^ p ∂μ := calc + _ ≤ ∫ x, μ[(fun x => ‖f x‖ ^ p) | m] x ∂μ := by + refine integral_mono_of_nonneg ?_ integrable_condExp (Integrable.norm_condExp_rpow_le hp hf) + filter_upwards with a using by positivity + _ ≤ _ := by + apply integral_condExp_le_of_ae_nonneg + filter_upwards with ω using by positivity + +theorem integral_norm_condExp_le (f : α → E) : ∫ x, ‖μ[f | m] x‖ ∂μ ≤ ∫ x, ‖f x‖ ∂μ := by + by_cases! hfint : ¬ Integrable f μ + · simpa [condExp_of_not_integrable hfint] using integral_nonneg (fun x => norm_nonneg (f x)) + simpa using integral_norm_condExp_rpow_le le_rfl (by simpa using hfint.norm) + +theorem setIntegral_norm_condExp_rpow_le {p : ℝ} (hp : 1 ≤ p) {f : α → E} {s : Set α} + (hs : MeasurableSet[m] s) (hf : Integrable (‖f ·‖ ^ p) μ) : + ∫ x in s, ‖μ[f | m] x‖ ^ p ∂μ ≤ ∫ x in s, ‖f x‖ ^ p ∂μ := by + have hp' : p ≠ 0 := by linarith + by_cases! hm : ¬ m ≤ m0 + · simpa [condExp_of_not_le hm, hp'] using integral_nonneg (fun x => by positivity) + by_cases! hsig : ¬ SigmaFinite (μ.trim hm) + · simpa [condExp_of_not_sigmaFinite hm hsig, hp'] using integral_nonneg (fun x => by positivity) + calc + _ ≤ ∫ x in s, μ[(fun x => ‖f x‖ ^ p) | m] x ∂μ := by + refine integral_mono_of_nonneg ?_ ?_ ?_ + · filter_upwards with a using by positivity + · exact integrable_condExp.congr (condExp_restrict_ae_eq_restrict hm hs hf) + · exact ae_restrict_le (Integrable.norm_condExp_rpow_le hp hf) + _ ≤ _ := by + apply setIntegral_condExp_le_of_ae_nonneg hs + filter_upwards with ω using by positivity + +theorem setIntegral_norm_condExp_le {s : Set α} (hs : MeasurableSet[m] s) (f : α → E) : + ∫ x in s, ‖(μ[f | m]) x‖ ∂μ ≤ ∫ x in s, ‖f x‖ ∂μ := by + by_cases! hfint : ¬ Integrable f μ + · simpa [condExp_of_not_integrable hfint] using integral_nonneg (fun x => norm_nonneg (f x)) + simpa using setIntegral_norm_condExp_rpow_le le_rfl hs (by simpa using hfint.norm) + +/-- If `‖f‖` is bounded almost everywhere by `R`, then so is its conditional expectation. -/ +theorem ae_bdd_norm_condExp_of_ae_bdd_norm {R : ℝ} {f : α → E} (hbdd : ∀ᵐ x ∂μ, ‖f x‖ ≤ R) : + ∀ᵐ x ∂μ, ‖μ[f | m] x‖ ≤ R := by + by_cases! hn : {x | ‖f x‖ ≤ R} = ∅ + · exact measure_mono_null (by simp) <| ae_eq_empty.1 (hn ▸ (ae_eq_univ.2 hbdd).symm) + exact (norm_condExp_le f).trans (condExp_le_nonneg_const ((norm_nonneg _).trans hn.some_mem) hbdd) + +theorem MemLp.ae_norm_condExp_le_essSup {f : α → E} (hf : MemLp f ∞ μ) : + ∀ᵐ (x : α) ∂μ, ‖μ[f | m] x‖ ≤ essSup (‖f ·‖) μ := + ae_bdd_norm_condExp_of_ae_bdd_norm (ae_le_essSup ⟨_, ae_le_lpNorm_exponent_top hf⟩) + +theorem MemLp.essSup_norm_condExp_le_essSup_norm [NeZero μ] {f : α → E} (hf : MemLp f ∞ μ) : + essSup (fun x ↦ ‖μ[f | m] x‖) μ ≤ essSup (fun x ↦ ‖f x‖) μ := + essSup_le_of_ae_le _ hf.ae_norm_condExp_le_essSup + (isCoboundedUnder_le_of_le _ (fun _ => norm_nonneg _)) + +theorem MemLp.lpNorm_condExp_le_lpNorm {f : α → E} {p : ℝ≥0∞} (hp : 1 ≤ p) (hf : MemLp f p μ) : + lpNorm μ[f | m] p μ ≤ lpNorm f p μ := by + by_cases NeZero μ + · have hp' : 0 < p := zero_lt_one.trans_le hp + by_cases! hm : ¬ m ≤ m0 + · simp [condExp_of_not_le hm] + by_cases! hsig : ¬ SigmaFinite (μ.trim hm) + · simp [condExp_of_not_sigmaFinite hm hsig] + · by_cases! hpt : p ≠ ⊤ + · rw [lpNorm_eq_integral_norm_rpow_toReal hp'.ne.symm hpt hf.1, + lpNorm_eq_integral_norm_rpow_toReal hp'.ne.symm hpt integrable_condExp.1] + gcongr ?_ ^ ?_ + have : 1 ≤ p.toReal := by + rwa [← ENNReal.toReal_one, ENNReal.toReal_le_toReal ENNReal.one_ne_top hpt] + exact integral_norm_condExp_rpow_le this <| + (integrable_norm_rpow_iff hf.1 hp'.ne.symm hpt).2 hf + · by_cases! h : MemLp μ[f | m] ⊤ μ + · simp_all only [lpNorm_exponent_top_eq_essSup] + exact hf.essSup_norm_condExp_le_essSup_norm + · simp_all + · simp_all [not_neZero] + +theorem MemLp.condExp {f : α → E} {p : ℝ≥0∞} (hp : 1 ≤ p) (hf : MemLp f p μ) : + MemLp (μ[f | m]) p μ := by + have hp' : 0 < p := zero_lt_one.trans_le hp + by_cases! hpt : p ≠ ⊤ + · rw [← integrable_norm_rpow_iff integrable_condExp.1 hp'.ne.symm hpt] + have hp : 1 ≤ p.toReal := by + rwa [← ENNReal.toReal_one, ENNReal.toReal_le_toReal ENNReal.one_ne_top hpt] + have := Integrable.norm_condExp_rpow_le (m := m) hp <| + (integrable_norm_rpow_iff hf.1 hp'.ne.symm hpt).2 hf + refine Integrable.mono_nonneg integrable_condExp ?_ ?_ this + · fun_prop (discharger := simp) + · filter_upwards with a; positivity + · simp_all only + exact memLp_top_of_bound integrable_condExp.1 (essSup (‖f ·‖) μ) hf.ae_norm_condExp_le_essSup + +theorem eLpNorm_condExp_le_eLpNorm (f : α → E) {p : ℝ≥0∞} (hp : 1 ≤ p) : + eLpNorm (μ[f | m]) p μ ≤ eLpNorm f p μ := by + by_cases! hf : MemLp f p μ + · rw [← ofReal_lpNorm hf, ← ofReal_lpNorm (hf.condExp hp)] + exact ENNReal.ofReal_le_ofReal (hf.lpNorm_condExp_le_lpNorm hp) + · simp only [MemLp, not_and, not_lt, top_le_iff] at hf + by_cases! ha : AEStronglyMeasurable f μ + · simp [hf ha] + · simp [condExp_of_not_integrable (fun h => ha h.aestronglyMeasurable)] + +@[deprecated eLpNorm_condExp_le_eLpNorm (since := "2026-07-01")] +theorem eLpNorm_one_condExp_le_eLpNorm (f : α → E) : eLpNorm (μ[f | m]) 1 μ ≤ eLpNorm f 1 μ := + eLpNorm_condExp_le_eLpNorm f (refl 1) + +end NormedSpace + /-- Given an integrable function `g`, the conditional expectations of `g` with respect to a sequence of sub-σ-algebras is uniformly integrable. -/ theorem Integrable.uniformIntegrable_condExp {ι : Type*} [IsFiniteMeasure μ] {g : α → ℝ} @@ -209,12 +341,12 @@ theorem Integrable.uniformIntegrable_condExp {ι : Type*} [IsFiniteMeasure μ] { hC, NNReal.inv_mk, ENNReal.coe_mul, ENNReal.coe_toNNReal hg.eLpNorm_lt_top.ne, ← mul_assoc, ← ENNReal.ofReal_eq_coe_nnreal, ← ENNReal.ofReal_mul hδ.le, mul_inv_cancel₀ hδ.ne', ENNReal.ofReal_one, one_mul, ENNReal.rpow_one] - exact eLpNorm_one_condExp_le_eLpNorm _ + exact eLpNorm_condExp_le_eLpNorm _ le_rfl refine ⟨C, fun n => le_trans ?_ (h {x : α | C ≤ ‖(μ[g|ℱ n]) x‖₊} (hmeas n C) (this n))⟩ have hmeasℱ : MeasurableSet[ℱ n] {x : α | C ≤ ‖(μ[g|ℱ n]) x‖₊} := @measurableSet_le _ _ _ _ _ (ℱ n) _ _ _ _ _ measurable_const (@Measurable.nnnorm _ _ _ _ _ (ℱ n) _ stronglyMeasurable_condExp.measurable) rw [← eLpNorm_congr_ae (condExp_indicator hint hmeasℱ)] - exact eLpNorm_one_condExp_le_eLpNorm _ + exact eLpNorm_condExp_le_eLpNorm _ le_rfl end MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/Trim.lean b/Mathlib/MeasureTheory/Measure/Trim.lean index c5484091922868..8d0dab87fee50e 100644 --- a/Mathlib/MeasureTheory/Measure/Trim.lean +++ b/Mathlib/MeasureTheory/Measure/Trim.lean @@ -112,6 +112,15 @@ theorem restrict_trim (hm : m ≤ m0) (μ : Measure α) (hs : @MeasurableSet α Measure.restrict_apply (hm t ht), trim_measurableSet_eq hm (@MeasurableSet.inter α m t s ht hs)] +theorem measure_spanningSets_trim_lt_top (hm : m ≤ m0) (μ : Measure α) [SigmaFinite (μ.trim hm)] + (n : ℕ) : + μ (spanningSets (μ.trim hm) n) < ⊤ := + (le_trim hm).trans_lt (measure_spanningSets_lt_top (μ.trim hm) n) + +instance (hm : m ≤ m0) (μ : Measure α) [SigmaFinite (μ.trim hm)] (n : ℕ) : + IsFiniteMeasure (μ.restrict (spanningSets (μ.trim hm) n)) := + isFiniteMeasure_restrict.2 (measure_spanningSets_trim_lt_top hm μ n).ne + instance isFiniteMeasure_trim (hm : m ≤ m0) [IsFiniteMeasure μ] : IsFiniteMeasure (μ.trim hm) where measure_univ_lt_top := by rw [trim_measurableSet_eq hm (@MeasurableSet.univ _ m)] @@ -119,19 +128,12 @@ instance isFiniteMeasure_trim (hm : m ≤ m0) [IsFiniteMeasure μ] : IsFiniteMea theorem sigmaFiniteTrim_mono {m m₂ m0 : MeasurableSpace α} {μ : Measure α} (hm : m ≤ m0) (hm₂ : m₂ ≤ m) [SigmaFinite (μ.trim (hm₂.trans hm))] : SigmaFinite (μ.trim hm) := by - refine ⟨⟨?_⟩⟩ - refine - { set := spanningSets (μ.trim (hm₂.trans hm)) + have : SigmaFinite ((μ.trim hm).trim hm₂) := by simpa [trim_trim] + exact ⟨⟨ + { set := spanningSets ((μ.trim hm).trim hm₂) set_mem := fun _ => Set.mem_univ _ - finite := fun i => ?_ - spanning := iUnion_spanningSets _ } - calc - (μ.trim hm) (spanningSets (μ.trim (hm₂.trans hm)) i) = - ((μ.trim hm).trim hm₂) (spanningSets (μ.trim (hm₂.trans hm)) i) := by - rw [@trim_measurableSet_eq α m₂ m (μ.trim hm) _ hm₂ (measurableSet_spanningSets _ _)] - _ = (μ.trim (hm₂.trans hm)) (spanningSets (μ.trim (hm₂.trans hm)) i) := by - rw [@trim_trim _ _ μ _ _ hm₂ hm] - _ < ∞ := measure_spanningSets_lt_top _ _ + finite := fun i => measure_spanningSets_trim_lt_top hm₂ (μ.trim hm) i + spanning := iUnion_spanningSets _ }⟩⟩ lemma SigmaFinite.of_trim {m m0 : MeasurableSpace α} {μ : Measure α} (hm : m ≤ m0) [SigmaFinite (μ.trim hm)] : SigmaFinite μ := by diff --git a/Mathlib/Probability/CondVar.lean b/Mathlib/Probability/CondVar.lean index 287665ed244df8..87f0c269da18e4 100644 --- a/Mathlib/Probability/CondVar.lean +++ b/Mathlib/Probability/CondVar.lean @@ -6,6 +6,7 @@ Authors: Yaël Dillies module public import Mathlib.MeasureTheory.Function.ConditionalExpectation.PullOut +public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Real public import Mathlib.MeasureTheory.Integral.Average public import Mathlib.Probability.Moments.Variance @@ -113,8 +114,8 @@ lemma condVar_ae_eq_condExp_sq_sub_sq_condExp (hm : m ≤ m₀) [IsFiniteMeasure have aux₀ : Integrable (X ^ 2) μ := hX.integrable_sq have aux₁ : Integrable (2 * X * μ[X | m]) μ := by rw [mul_assoc] - exact (memLp_one_iff_integrable.1 <| hX.condExp.mul hX).const_mul _ - have aux₂ : Integrable (μ[X | m] ^ 2) μ := hX.condExp.integrable_sq + exact (memLp_one_iff_integrable.1 <| (hX.condExp one_le_two).mul hX).const_mul _ + have aux₂ : Integrable (μ[X | m] ^ 2) μ := (hX.condExp one_le_two).integrable_sq filter_upwards [condExp_add (m := m) (aux₀.sub aux₁) aux₂, condExp_sub (m := m) aux₀ aux₁, condExp_mul_of_stronglyMeasurable_right stronglyMeasurable_condExp aux₁ ((hX.integrable one_le_two).const_mul _), condExp_ofNat (m := m) 2 X] @@ -138,10 +139,10 @@ lemma integral_condVar_add_variance_condExp (hm : m ≤ m₀) [IsProbabilityMeas _ = μ[(μ[X ^ 2 | m] - μ[X | m] ^ 2 : Ω → ℝ)] + (μ[μ[X | m] ^ 2] - μ[μ[X | m]] ^ 2) := by congr 1 · exact integral_congr_ae <| condVar_ae_eq_condExp_sq_sub_sq_condExp hm hX - · exact variance_eq_sub hX.condExp + · exact variance_eq_sub (hX.condExp one_le_two) _ = μ[X ^ 2] - μ[μ[X | m] ^ 2] + (μ[μ[X | m] ^ 2] - μ[X] ^ 2) := by rw [integral_sub' integrable_condExp, integral_condExp hm, integral_condExp hm] - exact hX.condExp.integrable_sq + exact (hX.condExp one_le_two).integrable_sq _ = Var[X; μ] := by rw [variance_eq_sub hX]; ring lemma condVar_bot' [NeZero μ] (X : Ω → ℝ) : diff --git a/Mathlib/Probability/Martingale/BorelCantelli.lean b/Mathlib/Probability/Martingale/BorelCantelli.lean index ef5a464411616d..ae70ff31aa470b 100644 --- a/Mathlib/Probability/Martingale/BorelCantelli.lean +++ b/Mathlib/Probability/Martingale/BorelCantelli.lean @@ -283,10 +283,11 @@ theorem tendsto_sum_indicator_atTop_iff [IsFiniteMeasure μ] (hint : ∀ n, Integrable (f n) μ) (hbdd : ∀ᵐ ω ∂μ, ∀ n, |f (n + 1) ω - f n ω| ≤ R) : ∀ᵐ ω ∂μ, Tendsto (fun n => f n ω) atTop atTop ↔ Tendsto (fun n => predictablePart f ℱ μ n ω) atTop atTop := by - have h₁ := (martingale_martingalePart hf hint).ae_not_tendsto_atTop_atTop - (martingalePart_bdd_difference ℱ hbdd) - have h₂ := (martingale_martingalePart hf hint).ae_not_tendsto_atTop_atBot - (martingalePart_bdd_difference ℱ hbdd) + simp only [← Real.norm_eq_abs] at hbdd + have h₀ := martingalePart_bdd_difference ℱ hbdd + simp only [Real.norm_eq_abs, ← NNReal.coe_ofNat, ← NNReal.coe_mul 2 R] at h₀ + have h₁ := (martingale_martingalePart hf hint).ae_not_tendsto_atTop_atTop h₀ + have h₂ := (martingale_martingalePart hf hint).ae_not_tendsto_atTop_atBot h₀ have h₃ : ∀ᵐ ω ∂μ, ∀ n, 0 ≤ (μ[f (n + 1) - f n | ℱ n]) ω := by refine ae_all_iff.2 fun n => condExp_nonneg ?_ filter_upwards [ae_all_iff.1 hfmono n] with ω hω using sub_nonneg.2 hω diff --git a/Mathlib/Probability/Martingale/Centering.lean b/Mathlib/Probability/Martingale/Centering.lean index 0581c5562ca25a..09243a048a6c1f 100644 --- a/Mathlib/Probability/Martingale/Centering.lean +++ b/Mathlib/Probability/Martingale/Centering.lean @@ -244,22 +244,18 @@ theorem predictablePart_add_ae_eq [CompleteSpace E] [SigmaFiniteFiltration μ section Difference -theorem predictablePart_bdd_difference {R : ℝ≥0} {f : ℕ → Ω → ℝ} (ℱ : Filtration ℕ m0) - (hbdd : ∀ᵐ ω ∂μ, ∀ i, |f (i + 1) ω - f i ω| ≤ R) : - ∀ᵐ ω ∂μ, ∀ i, |predictablePart f ℱ μ (i + 1) ω - predictablePart f ℱ μ i ω| ≤ R := by +theorem predictablePart_bdd_difference [CompleteSpace E] {R : ℝ} {f : ℕ → Ω → E} + (ℱ : Filtration ℕ m0) (hbdd : ∀ᵐ ω ∂μ, ∀ i, ‖f (i + 1) ω - f i ω‖ ≤ R) : + ∀ᵐ ω ∂μ, ∀ i, ‖predictablePart f ℱ μ (i + 1) ω - predictablePart f ℱ μ i ω‖ ≤ R := by simp_rw [predictablePart, Finset.sum_apply, Finset.sum_range_succ_sub_sum] - exact ae_all_iff.2 fun i => ae_bdd_condExp_of_ae_bdd <| ae_all_iff.1 hbdd i + exact ae_all_iff.2 fun i => ae_bdd_norm_condExp_of_ae_bdd_norm <| ae_all_iff.1 hbdd i -theorem martingalePart_bdd_difference {R : ℝ≥0} {f : ℕ → Ω → ℝ} (ℱ : Filtration ℕ m0) - (hbdd : ∀ᵐ ω ∂μ, ∀ i, |f (i + 1) ω - f i ω| ≤ R) : - ∀ᵐ ω ∂μ, ∀ i, |martingalePart f ℱ μ (i + 1) ω - martingalePart f ℱ μ i ω| ≤ ↑(2 * R) := by +theorem martingalePart_bdd_difference [CompleteSpace E] {R : ℝ} {f : ℕ → Ω → E} + (ℱ : Filtration ℕ m0) (hbdd : ∀ᵐ ω ∂μ, ∀ i, ‖f (i + 1) ω - f i ω‖ ≤ R) : + ∀ᵐ ω ∂μ, ∀ i, ‖martingalePart f ℱ μ (i + 1) ω - martingalePart f ℱ μ i ω‖ ≤ 2 * R := by filter_upwards [hbdd, predictablePart_bdd_difference ℱ hbdd] with ω hω₁ hω₂ i - simp only [two_mul, martingalePart, Pi.sub_apply] - have : |f (i + 1) ω - predictablePart f ℱ μ (i + 1) ω - (f i ω - predictablePart f ℱ μ i ω)| = - |f (i + 1) ω - f i ω - (predictablePart f ℱ μ (i + 1) ω - predictablePart f ℱ μ i ω)| := by - ring_nf -- `ring` suggests `ring_nf` despite proving the goal - rw [this] - exact (abs_sub _ _).trans (add_le_add (hω₁ i) (hω₂ i)) + simpa [two_mul, martingalePart, sub_sub_sub_comm] using + (norm_sub_le _ _).trans (add_le_add (hω₁ i) (hω₂ i)) end Difference diff --git a/Mathlib/Probability/Martingale/Convergence.lean b/Mathlib/Probability/Martingale/Convergence.lean index 580e50c3b1d632..f304cfd1f359f9 100644 --- a/Mathlib/Probability/Martingale/Convergence.lean +++ b/Mathlib/Probability/Martingale/Convergence.lean @@ -335,7 +335,7 @@ theorem Martingale.eq_condExp_of_tendsto_eLpNorm {μ : Measure Ω} (hf : Marting have ht : Tendsto (fun m => eLpNorm (μ[f m - g | ℱ n]) 1 μ) atTop (𝓝 0) := haveI hint : ∀ m, Integrable (f m - g) μ := fun m => (hf.integrable m).sub hg tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds hgtends (fun m => zero_le) - fun m => eLpNorm_one_condExp_le_eLpNorm _ + fun m => eLpNorm_condExp_le_eLpNorm _ le_rfl have hev : ∀ m ≥ n, eLpNorm (μ[f m - g | ℱ n]) 1 μ = eLpNorm (f n - μ[g | ℱ n]) 1 μ := by refine fun m hm => eLpNorm_congr_ae ((condExp_sub (hf.integrable m) hg _).trans ?_) filter_upwards [hf.2 n m hm] with x hx From 42b23e7cd99f2a4b5b76e7f6a34056529201ccb9 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:30:00 +0000 Subject: [PATCH 0541/1300] chore(GroupTheory/*): remove more `NeZero (Nat.card G)` (#41287) This PR is a follow-up to #41274, removing more occurrences of `NeZero (Nat.card G)`. Co-authored-by: tb65536 --- Mathlib/GroupTheory/SpecificGroups/Cyclic.lean | 2 -- Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean | 1 - Mathlib/RepresentationTheory/FinGroupCharZero.lean | 6 ------ Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean | 1 - 4 files changed, 10 deletions(-) diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean index 04744ce257b361..673b7378410d62 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean @@ -599,7 +599,6 @@ noncomputable def IsCyclic.mulAutMulEquiv [Group G] [h : IsCyclic G] : variable (G) in theorem IsCyclic.card_mulAut [Group G] [Finite G] [h : IsCyclic G] : Nat.card (MulAut G) = Nat.totient (Nat.card G) := by - have : NeZero (Nat.card G) := ⟨Nat.card_pos.ne'⟩ rw [← ZMod.card_units_eq_totient, ← Nat.card_eq_fintype_card] exact Nat.card_congr (mulAutMulEquiv G) @@ -796,7 +795,6 @@ theorem not_isAddCyclic_prod_of_infinite_nontrivial (M N : Type*) [AddGroup M] [ have := isAddCyclic_of_surjective (f.prodMap f) (Prod.map_surjective.mpr ⟨hf, hf⟩) simpa using coprime_card_of_isAddCyclic_prod (ZMod 2) (ZMod 2) let ZN := ZMod (Nat.card N) - have : NeZero (Nat.card N) := ⟨Nat.card_pos.ne'⟩ have := isAddCyclic_of_surjective ((ZMod.castHom (dvd_zero _) ZN).toAddMonoidHom.prodMap (.id ZN)) (Prod.map_surjective.mpr ⟨ZMod.castHom_surjective (dvd_zero _), Function.surjective_id⟩) exact Finite.one_lt_card (α := N).ne' (by simpa [ZN] using coprime_card_of_isAddCyclic_prod ZN ZN) diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean index cfd567da7754a6..77641c60d15f4b 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean @@ -414,7 +414,6 @@ theorem IsCyclic.image_range_card (ha : ∀ x : α, x ∈ zpowers a) : @[to_additive] lemma IsCyclic.ext [Finite G] [IsCyclic G] {d : ℕ} {a b : ZMod d} (hGcard : Nat.card G = d) (h : ∀ t : G, t ^ a.val = t ^ b.val) : a = b := by - have : NeZero (Nat.card G) := ⟨Nat.card_pos.ne'⟩ obtain ⟨g, hg⟩ := IsCyclic.exists_generator (α := G) specialize h g subst hGcard diff --git a/Mathlib/RepresentationTheory/FinGroupCharZero.lean b/Mathlib/RepresentationTheory/FinGroupCharZero.lean index 22633b0e48855b..9cacfc1a33730d 100644 --- a/Mathlib/RepresentationTheory/FinGroupCharZero.lean +++ b/Mathlib/RepresentationTheory/FinGroupCharZero.lean @@ -121,9 +121,6 @@ then an object of `FDRep k G` is simple if and only if its character has norm `1 lemma simple_iff_char_is_norm_one [CharZero k] [Fintype G] (V : FDRep k G) : Simple V ↔ ∑ g : G, V.character g * V.character g⁻¹ = Nat.card G where mp h := by - have : NeZero (Nat.card G : k) := by - rw [← @Fintype.card_eq_nat_card G (by assumption)] - exact NeZero.charZero have := invertibleOfNonzero (NeZero.ne (Nat.card G : k)) have := invertibleOfNonzero (NeZero.ne (Fintype.card G : k)) classical @@ -134,9 +131,6 @@ lemma simple_iff_char_is_norm_one [CharZero k] [Fintype G] (V : FDRep k G) : rwa [mul_comm, ← smul_eq_mul, smul_smul, Fintype.card_eq_nat_card, mul_invOf_self, smul_eq_mul, one_mul, one_mul] at this mpr h := by - have : NeZero (Nat.card G : k) := by - rw [← @Fintype.card_eq_nat_card G (by assumption)] - exact NeZero.charZero have := invertibleOfNonzero (NeZero.ne (Fintype.card G : k)) have := invertibleOfNonzero (NeZero.ne (Nat.card G : k)) have eq := FDRep.scalar_product_char_eq_finrank_equivariant V V diff --git a/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean b/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean index d4ca6499816676..d9b3704e3ad231 100644 --- a/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean +++ b/Mathlib/RingTheory/RootsOfUnity/EnoughRootsOfUnity.lean @@ -104,7 +104,6 @@ group of units of a ring `M` with all roots of unity is isomorphic to `G` -/ lemma IsCyclic.monoidHom_equiv_self (G M : Type*) [CommGroup G] [Finite G] [IsCyclic G] [CommMonoid M] [HasEnoughRootsOfUnity M (Nat.card G)] : Nonempty ((G →* Mˣ) ≃* G) := by - have : NeZero (Nat.card G) := ⟨Nat.card_pos.ne'⟩ have hord := HasEnoughRootsOfUnity.natCard_rootsOfUnity M (Nat.card G) let e := (IsCyclic.monoidHom_mulEquiv_rootsOfUnity G Mˣ).some exact ⟨e.trans (rootsOfUnityUnitsMulEquiv M (Nat.card G)) |>.trans (mulEquivOfCyclicCardEq hord)⟩ From b9df47b72b287802f6d40cf7588dada976bc657d Mon Sep 17 00:00:00 2001 From: mitchell-horner <29882987+mitchell-horner@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:53:35 +0000 Subject: [PATCH 0542/1300] =?UTF-8?q?feat(Combinatorics/SimpleGraph):=20pr?= =?UTF-8?q?ove=20the=20minimal-degree=20version=20of=20the=20Erd=C5=91s-St?= =?UTF-8?q?one=20theorem=20(#28685)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Proves the minimal degree-version of the Erdős-Stone theorem: If `G` has a minimal degree of at least `(1 - 1 / r + o(1)) * card V`, then `G` contains a copy of a `completeEquipartiteGraph` in `r + 1` parts each of size `t`. The double-counting construction from the proof is available in `namespace ErdosStone`. --- Mathlib.lean | 1 + .../Extremal/ErdosStoneSimonovits.lean | 328 ++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean diff --git a/Mathlib.lean b/Mathlib.lean index af8a66d0fcb56b..b096679913bdd1 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3646,6 +3646,7 @@ public import Mathlib.Combinatorics.SimpleGraph.EdgeLabeling public import Mathlib.Combinatorics.SimpleGraph.Ends.Defs public import Mathlib.Combinatorics.SimpleGraph.Ends.Properties public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic +public import Mathlib.Combinatorics.SimpleGraph.Extremal.ErdosStoneSimonovits public import Mathlib.Combinatorics.SimpleGraph.Extremal.Turan public import Mathlib.Combinatorics.SimpleGraph.Extremal.TuranDensity public import Mathlib.Combinatorics.SimpleGraph.Finite diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean new file mode 100644 index 00000000000000..ef28446b9a0883 --- /dev/null +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean @@ -0,0 +1,328 @@ +/- +Copyright (c) 2026 Mitchell Horner. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Mitchell Horner +-/ +module + +public import Mathlib.Combinatorics.Pigeonhole +public import Mathlib.Combinatorics.SimpleGraph.Bipartite +public import Mathlib.Combinatorics.SimpleGraph.CompleteMultipartite +public import Mathlib.Analysis.Real.Sqrt + +/-! +# The Erdős-Stone-Simonovits theorem + +This file proves the **Erdős-Stone-Simonovits theorem** for simple graphs. + +## Main definitions + +* `SimpleGraph.eventually_completeEquipartiteGraph_isContained_of_minDegree` is the proof of the + minimal degree version of the **Erdős-Stone theorem** for simple graphs. +-/ + +open Filter Finset Fintype Real Topology + +namespace SimpleGraph + +variable {n : ℕ} {G : SimpleGraph (Fin n)} [DecidableRel G.Adj] + {W : Type*} [Fintype W] {H : SimpleGraph W} + +section ErdosStone + +namespace ErdosStone + +variable {ε : ℝ} {r t t' : ℕ} (K : G.CompleteEquipartiteSubgraph r t') + +/-- `ErdosStone.filter` is the set of vertices in the complement of a complete equipartite +subgraph, in `r` parts each of size `t'`, adjacent to at least `t` vertices in each part of the +complete equipartite subgraph. + +This is an auxiliary definition for the Erdős-Stone theorem. -/ +def filter (t : ℕ) : Finset (Fin n) := + { v ∈ K.vertsᶜ | ∀ p ∈ K.parts, ∃ s ∈ p.powersetCard t, ∀ w ∈ s, G.Adj v w } + +theorem filter_subset_compl_verts : filter K t ⊆ K.vertsᶜ := + filter_subset _ K.vertsᶜ + +omit [DecidableRel G.Adj] in +theorem between_verts_isBipartiteWith : + (G.between K.verts K.vertsᶜ).IsBipartiteWith K.verts ↑K.vertsᶜ := by + rw [coe_compl K.verts] + exact between_isBipartiteWith (disjoint_compl_right) + +lemma le_card_edgeFinset_between_verts : + (#K.verts * (G.minDegree - #K.verts) : ℝ) ≤ #(G.between K.verts K.vertsᶜ).edgeFinset := by + rw [← isBipartiteWith_sum_degrees_eq_card_edges (between_verts_isBipartiteWith K), + ← nsmul_eq_mul, ← sum_const, Nat.cast_sum] + exact sum_le_sum (fun v hv ↦ sub_le_iff_le_add.mpr <| + mod_cast (G.minDegree_le_degree v).trans (degree_le_between_add hv)) + +/-- For `v ∈ K.vertsᶜ \ ErdosStone.filter`, since `v` is adjacent to fewer than `t` +vertices in at least one part of the complete equipartite subgraph, it follows that `v` is +adjacent to fewer than `#K.verts - (t' - t)` vertices in `K.verts`. + +This is an auxiliary lemma for the Erdős-Stone theorem. -/ +lemma degree_between_verts_lt_of_mem_sdiff + {v : Fin n} (hv : v ∈ K.vertsᶜ \ filter K t) (ht'_pos : 0 < t') : + (G.between K.verts K.vertsᶜ).degree v < #K.verts - t' + t := by + simp_rw [Finset.mem_sdiff, ErdosStone.filter, mem_filter, not_and_or, and_or_left, + and_not_self_iff, false_or, not_forall, not_exists, not_and_or, not_forall, exists_prop] at hv + obtain ⟨hv, p, hp, hs⟩ := hv + rw [← card_neighborFinset_eq_degree, + isBipartiteWith_neighborFinset' (between_verts_isBipartiteWith K) hv] + conv => + enter [1, 1, 2] + unfold CompleteEquipartiteSubgraph.verts + rw [filter_disjiUnion, card_disjiUnion, sum_eq_sum_sdiff_singleton_add hp] + apply add_lt_add_of_le_of_lt + · conv_rhs => + rw [K.card_verts, ← Nat.sub_one_mul, ← K.card_parts.resolve_right ht'_pos.ne', + ← card_singleton p, ← Finset.card_sdiff_of_subset (singleton_subset_iff.mpr hp), + ← smul_eq_mul, ← sum_const, + ← Finset.sum_congr rfl fun _ h ↦ K.card_mem_parts (mem_sdiff.mp h).1] + exact sum_le_sum (fun _ _ ↦ card_filter_le _ _) + · contrapose! hs + obtain ⟨s, hs⟩ := powersetCard_nonempty.mpr hs + have hs' : s ∈ p.powersetCard t := powersetCard_mono (filter_subset _ _) hs + refine ⟨s, hs', fun w hw ↦ ?_⟩ + obtain ⟨_, hadj, _⟩ := by + rw [mem_powersetCard] at hs + apply hs.1 at hw + rwa [mem_filter, between_adj] at hw + exact hadj.symm + +lemma card_edgeFinset_between_verts_le (hr_pos : 0 < r) (ht'_pos : 0 < t') : + (#(G.between K.verts K.vertsᶜ).edgeFinset : ℝ) + ≤ (n - #K.verts) * (#K.verts - (t' - t)) + + #(filter K t) * (t' - t) := + calc (#(G.between K.verts K.vertsᶜ).edgeFinset : ℝ) + _ = ∑ v ∈ K.vertsᶜ \ filter K t, ((G.between K.verts K.vertsᶜ).degree v : ℝ) + + ∑ v ∈ filter K t, ((G.between K.verts K.vertsᶜ).degree v : ℝ) := by + rw [ErdosStone.filter, sum_sdiff (filter_subset _ K.vertsᶜ), eq_comm] + exact_mod_cast isBipartiteWith_sum_degrees_eq_card_edges' + (between_verts_isBipartiteWith K) + _ ≤ ∑ _ ∈ K.vertsᶜ \ filter K t, (#K.verts - t' + t : ℝ) + + ∑ _ ∈ filter K t, (#K.verts : ℝ) := by + apply add_le_add <;> refine sum_le_sum (fun v hv ↦ ?_) + · rw [← Nat.cast_sub ((Nat.le_mul_of_pos_left t' hr_pos).trans_eq K.card_verts.symm)] + exact_mod_cast (degree_between_verts_lt_of_mem_sdiff K hv ht'_pos).le + · exact_mod_cast isBipartiteWith_degree_le' + (between_verts_isBipartiteWith K) (filter_subset_compl_verts K hv) + _ = (n - #K.verts) * (#K.verts - (t' - t)) + + #(filter K t) * (t' - t) := by + rw [sum_const, nsmul_eq_mul, card_sdiff_of_subset (filter_subset_compl_verts K), + Nat.cast_sub (card_le_card (filter_subset_compl_verts K)), card_compl, + Nat.cast_sub (card_le_univ K.verts), Fintype.card_fin, sum_const, nsmul_eq_mul, sub_mul, + sub_add (#K.verts : ℝ) _ _, mul_sub (#(filter K t) : ℝ) _ _, + ← sub_add, sub_add_eq_add_sub, sub_add_cancel] + +/-- `#ErdosStone.filter` is arbitrarily large with respect to `n`. + +This is an auxiliary lemma for the Erdős-Stone theorem. -/ +lemma mul_le_card_filter_mul (hr_pos : 0 < r) (ht'_pos : 0 < t') + (hδ : G.minDegree ≥ (1 - 1 / r + ε) * n) + {N : ℕ} (hN : (N + r * t') * (t' - t) ≤ n * (r * t' * ε - t)) : + (N * (t' - t) : ℝ) ≤ (#(filter K t) * (t' - t) : ℝ) := + calc (N * (t' - t) : ℝ) + _ ≤ n * (r * t' * ε - t) - r * t' * (t' - t) := by + rw [← add_sub_cancel_right (N : ℝ) (r * t' : ℝ), sub_mul] + exact sub_le_sub_right hN _ + _ = #K.verts * ((1 - 1 / r + ε) * n - #K.verts) + - (n - #K.verts) * (#K.verts - (t' - t)) := by + conv_rhs => rw [sub_eq_add_neg, ← neg_mul, neg_sub, sub_mul, mul_sub, ← add_sub_assoc, + mul_sub, ← add_sub_assoc, sub_add_cancel, sub_right_comm, ← mul_assoc, ← mul_rotate, + mul_assoc, ← mul_sub, mul_add, mul_sub (#K.verts : ℝ) _ _, mul_one, + sub_add_eq_add_sub, add_sub_assoc, add_sub_sub_cancel, K.card_verts, Nat.cast_mul, + mul_one_div, mul_div_cancel_left₀ (t' : ℝ) (mod_cast hr_pos.ne'), sub_add_sub_cancel] + _ ≤ #K.verts * (G.minDegree - #K.verts) - (n - #K.verts) * (#K.verts - (t' - t)) := + sub_le_sub_right (mul_le_mul_of_nonneg_left + (sub_le_sub_right hδ _) (#K.verts).cast_nonneg) _ + _ ≤ #(filter K t) * (t' - t) := + sub_left_le_of_le_add <| (le_card_edgeFinset_between_verts K).trans + (card_edgeFinset_between_verts_le K hr_pos ht'_pos) + +/-- For `w ∈ ErdosStone.filter`, there exists a `r` subets of vertices of size `t < t'` +adjacent to `w`. + +This is an auxiliary definition for the Erdős-Stone theorem. -/ +noncomputable def filter.pi : + filter K t → K.parts.pi (·.powersetCard t) := + fun ⟨_, h⟩ ↦ + let s := Multiset.of_mem_filter h + ⟨fun p hp ↦ (s p hp).choose, Finset.mem_pi.mpr fun p hp ↦ (s p hp).choose_spec.1⟩ + +theorem filter.pi.mem_val {p} (hp : p ∈ K.parts) (w : filter K t) : + ∀ v ∈ (filter.pi K w).val p hp, G.Adj w v := + let s := Multiset.of_mem_filter w.prop p hp + s.choose_spec.right + +/-- If `#ErdosStone.filter` is sufficiently large, then there exist a `y` such that there +are least `t` vertices in the fiber `ErdosStone.filter.pi A · = y`. + +This is an auxiliary theorem for the Erdős-Stone theorem. -/ +theorem filter.pi.exists_le_card_fiber (hr_pos : 0 < r) (ht'_pos : 0 < t') + (ht_lt_t' : t < t') (hδ : G.minDegree ≥ (1 - 1 / r + ε) * n) + (hN : (t'.choose t ^ r * t + r * t') * (t' - t) ≤ n * (r * t' * ε - t)) : + ∃ y : K.parts.pi (·.powersetCard t), t ≤ #{ w | filter.pi K w = y } := by + have : Nonempty (K.parts.pi (·.powersetCard t)) := by + simp_rw [nonempty_coe_sort, pi_nonempty, powersetCard_nonempty] + intro p hp + rw [K.card_mem_parts hp] + exact ht_lt_t'.le + apply exists_le_card_fiber_of_mul_le_card + simp_rw [card_coe] + calc #(K.parts.pi (·.powersetCard t)) * t + _ = (∏ x ∈ K.parts, (#x).choose t) * t := by + simp_rw [Finset.card_pi, card_powersetCard] + _ = (∏ p ∈ K.parts, t'.choose t) * t := + congrArg (· * t) <| prod_congr rfl + fun p hp ↦ congrArg (Nat.choose · t) <| K.card_mem_parts hp + _ ≤ t'.choose t ^ r * t := by + rw [prod_const, K.card_parts.resolve_right ht'_pos.ne'] + _ ≤ #(filter K t) := by + refine Nat.le_of_mul_le_mul_right ?_ (Nat.sub_pos_of_lt ht_lt_t') + rw [← @Nat.cast_le ℝ, Nat.cast_mul _ (t' - t), Nat.cast_mul _ (t' - t), + Nat.cast_sub ht_lt_t'.le] + exact mul_le_card_filter_mul K hr_pos ht'_pos hδ (mod_cast hN) + +end ErdosStone + +/-- If `G` has a minimal degree of at least `(1 - 1 / r + o(1)) * n`, then `G` contains a +copy of a `completeEquipartiteGraph` in `r + 1` parts each of size `t`. + +This is the minimal-degree version of the **Erdős-Stone theorem**. -/ +public theorem eventually_completeEquipartiteGraph_isContained_of_minDegree + {ε : ℝ} (hε : 0 < ε) (r t : ℕ) : + ∀ᶠ n in atTop, ∀ {G : SimpleGraph (Fin n)} [DecidableRel G.Adj], + G.minDegree ≥ (1 - 1 / r + ε) * n + → completeEquipartiteGraph (r + 1) t ⊑ G := by + rcases show (r = 0 ∨ t = 0) ∨ r ≠ 0 ∧ t ≠ 0 by tauto with h0 | ⟨hr_pos, ht_pos⟩ + · rw [← Nat.le_zero_eq, ← @Nat.add_le_add_iff_right r 0 1, zero_add] at h0 + rw [eventually_atTop] + refine ⟨(r + 1) * t, fun n hn {G} _ _ ↦ ?_⟩ + rw [completeEquipartiteGraph_eq_bot_iff.mpr h0, bot_isContained_iff_card_le, + card_prod, Fintype.card_fin, Fintype.card_fin, Fintype.card_fin] + exact hn + · rw [← Nat.pos_iff_ne_zero] at hr_pos ht_pos + -- choose `ε'` to ensure `G.minDegree` is large enough + let ε' := 1 / (↑(r - 1) * r) + ε + have hε' : 0 < ε' := by positivity + -- choose `t'` larger than `t / (r * ε)` + let t' := ⌊t / (r * ε)⌋₊ + 1 + have ht_lt_rt'ε : t < r * t' * ε := by + rw [mul_comm (r : ℝ) (t' : ℝ), mul_assoc, ← div_lt_iff₀ (by positivity), Nat.cast_add_one] + exact Nat.lt_floor_add_one (t / (r * ε)) + have ht'_pos : 0 < t' := by positivity + have ⟨N', ih⟩ := eventually_atTop.mp <| + eventually_completeEquipartiteGraph_isContained_of_minDegree hε' (r - 1) t' + -- choose `N` at least `(t'.choose t ^ r * t + r * t') * (t '- t) / (r * t' * ε - t)` to + -- satisfy the pigeonhole principle + let N := max (max 1 N') ⌈(t'.choose t ^ r * t + r * t') * (t' - t) / (r * t' * ε - t)⌉₊ + refine eventually_atTop.mpr ⟨N, fun n hn {G} _ hδ ↦ ?_⟩ + have : Nonempty (Fin n) := by + rw [← Fin.pos_iff_nonempty] + exact hn.trans_lt' (lt_max_of_lt_left (lt_max_of_lt_left zero_lt_one)) + -- `r` is less than `1 / ε` otherwise `G.minDegree = n` + have hrε_lt_1 : r * ε < 1 := by + have hδ_lt_card : (G.minDegree : ℝ) < (n : ℝ) := by + conv_rhs => + rw [← Fintype.card_fin n] + exact_mod_cast G.minDegree_lt_card + contrapose! hδ_lt_card with h1_le_rε + rw [← div_le_iff₀' (by positivity), ← sub_nonpos, + ← le_sub_self_iff 1, ← sub_add] at h1_le_rε + exact hδ.trans' (le_mul_of_one_le_left n.cast_nonneg h1_le_rε) + have ht_lt_t' : t < t' := by + rw [mul_comm (r : ℝ) (t' : ℝ), mul_assoc] at ht_lt_rt'ε + exact_mod_cast ht_lt_rt'ε.trans_le (mul_le_of_le_one_right (mod_cast ht'_pos.le) hrε_lt_1.le) + -- identify a `completeEquipartiteGraph r t'` in `G` from the inductive hypothesis + replace ih : completeEquipartiteGraph r t' ⊑ G := by + rcases eq_or_ne r 1 with hr_eq_1 | hr_ne_1 + -- if `r = 1` then `completeEquipartiteGraph r t' = ⊥` + · have h0 : r ≤ 1 ∨ t' = 0 := Or.inl hr_eq_1.le + rw [completeEquipartiteGraph_eq_bot_iff.mpr h0, bot_isContained_iff_card_le, + card_prod, Fintype.card_fin, Fintype.card_fin, hr_eq_1, one_mul, Fintype.card_fin] + apply hn.trans' + exact_mod_cast calc (t' : ℝ) + _ ≤ r * t' := le_mul_of_one_le_left (by positivity) (mod_cast hr_pos) + _ ≤ t'.choose t ^ r * t + r * t' := le_add_of_nonneg_left (by positivity) + _ ≤ (t'.choose t ^ r * t + r * t') * (t' - t) / (r * t' * ε - t) := by + rw [mul_div_assoc, le_mul_iff_one_le_right (by positivity), + one_le_div (sub_pos.mpr ht_lt_rt'ε), sub_le_sub_iff_right, + mul_comm (r : ℝ) (t' : ℝ), mul_assoc, mul_le_iff_le_one_right (by positivity)] + exact hrε_lt_1.le + _ ≤ ⌈(t'.choose t ^ r * t + r * t') * (t' - t) / (r * t' * ε - t)⌉₊ := Nat.le_ceil _ + _ ≤ N := Nat.cast_le.mpr (le_max_right _ _) + -- if `r > 1` then `G` satisfies the inductive hypothesis + · have hδ' := calc (G.minDegree : ℝ) + _ ≥ (1 - 1 / (r - 1) + (1 / (r - 1) - 1 / r) + ε) * n := by + rwa [← sub_add_sub_cancel _ (1 / (r - 1) : ℝ) _] at hδ + _ = (1 - 1 / ↑(r - 1) + ε') * n := by + rw [← one_div_mul_sub_mul_one_div_eq_one_div_add_one_div + (sub_ne_zero_of_ne (mod_cast hr_ne_1)) (mod_cast hr_pos.ne'), + sub_sub_cancel, mul_one, one_div_mul_one_div_rev, mul_comm (r : ℝ) _, + ← Nat.cast_pred hr_pos, add_assoc] + rw [← Nat.succ_pred_eq_of_pos hr_pos] + exact ih n (hn.trans' (le_max_of_le_left (le_max_right 1 N'))) hδ' + obtain ⟨K⟩ := completeEquipartiteGraph_isContained_iff.mp ih + -- find `t` vertices not in `K` adjacent to `t` vertices in each `K.parts` using the + -- pigeonhole principle + obtain ⟨⟨y, hy⟩, ht_le_card_filter⟩ := by classical + apply ErdosStone.filter.pi.exists_le_card_fiber K hr_pos ht'_pos ht_lt_t' hδ + rw [← div_le_iff₀ (sub_pos_of_lt ht_lt_rt'ε)] + trans (N : ℝ) + · exact (Nat.le_ceil _).trans (Nat.cast_le.mpr <| le_max_right _ _) + · exact_mod_cast hn + rw [Finset.mem_pi] at hy + have ⟨s, hs_subset, hcards⟩ := exists_subset_card_eq ht_le_card_filter + -- identify the `t` vertices in each `K.parts` as a `CompleteEquipartiteSubgraph r t` in `K` + let K' : G.CompleteEquipartiteSubgraph r t := by + refine ⟨univ.map ⟨fun p : K.parts ↦ y p.val p.prop, fun p₁ p₂ (heq : y p₁ _ = y p₂ _) ↦ ?_⟩, + ?_, fun {p} hp ↦ ?_, fun p₁ hp₁ p₂ hp₂ hne v₁ hv₁ v₂ hv₂ ↦ ?_⟩ + · have hy₁' := mem_powersetCard.mp (hy p₁.val p₁.prop) + have hy₂' := mem_powersetCard.mp (hy p₂.val p₂.prop) + rw [← heq] at hy₂' + obtain ⟨v, hv⟩ : (y p₁ _).Nonempty := by + rw [← Finset.card_pos, hy₁'.right] + exact ht_pos + by_contra! hne + absurd K.isCompleteBetween p₁.prop p₂.prop + (Subtype.ext_iff.ne.mp hne) (hy₁'.left hv) (hy₂'.left hv) + exact G.loopless.irrefl v + · simp_rw [card_map, card_univ, card_coe] + exact .inl (K.card_parts.resolve_right ht'_pos.ne') + · simp_rw [univ_eq_attach, Finset.mem_map, mem_attach, + Function.Embedding.coeFn_mk, true_and, Subtype.exists] at hp + replace ⟨p, hp, hyp⟩ := hp + rw [← hyp] + have hy' := mem_powersetCard.mp (hy p hp) + exact hy'.right + · simp_rw [univ_eq_attach, coe_map, Function.Embedding.coeFn_mk, + Set.mem_image, mem_coe, mem_attach, true_and, Subtype.exists] at hp₁ hp₂ + replace ⟨p₁, hp₁, hyp₁⟩ := hp₁ + rw [← hyp₁] at hv₁ hne + have hy₁' := mem_powersetCard.mp (hy p₁ hp₁) + replace ⟨p₂, hp₂, hyp₂⟩ := hp₂ + rw [← hyp₂] at hv₂ hne + have hy₂' := mem_powersetCard.mp (hy p₂ hp₂) + refine K.isCompleteBetween hp₁ hp₂ ?_ (hy₁'.left hv₁) (hy₂'.left hv₂) + by_contra! heq + simp [← heq] at hne + -- identify the `t` vertices not in `K` and the `CompleteEquipartiteSubgraph r t` in `K` + -- as a `CompleteEquipartiteSubgraph (r + 1) t` in `G` + refine completeEquipartiteGraph_succ_isContained_iff.mpr + ⟨K', s.map (.subtype _), by rwa [← card_map] at hcards, fun p' hp' v hv w hw ↦ ?_⟩ + obtain ⟨w', hw'_mem, (hw'_eq : ↑w' = w)⟩ := Finset.mem_map.mp hw + simp_rw [K', univ_eq_attach, Finset.mem_map, mem_attach, + Function.Embedding.coeFn_mk, true_and, Subtype.exists] at hp' + obtain ⟨p, hp, hp'_eq⟩ : ∃ p, ∃ (h : p ∈ K.parts), y p h = p' := hp' + apply hs_subset at hw'_mem + simp_rw [mem_filter, mem_univ, true_and, ErdosStone.filter.pi, Subtype.mk.injEq] at hw'_mem + rw [← hp'_eq, mem_coe, ← hw'_mem] at hv + rw [← hw'_eq] + exact (ErdosStone.filter.pi.mem_val K hp w' v hv).symm + +end ErdosStone + +end SimpleGraph From 52b549a28077070173094a1ee121f6326cb555e2 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:53:38 +0000 Subject: [PATCH 0543/1300] =?UTF-8?q?feat(Data/List/Chain):=20generalize?= =?UTF-8?q?=20`WellFounded.asymmetric=E2=82=83`=20to=20chains=20(#36922)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing `WellFounded.asymmetric` shows `r a b → ¬r b a`, and `WellFounded.asymmetric₃` shows `r a b → r b c → ¬r c a`. This adds `WellFounded.asymmetricₙ` which shows `l.IsChain r → ¬r l.getLast l.head`. --- Mathlib/Data/List/Chain.lean | 45 ++++++++++++++++++++++++++------- Mathlib/Data/List/Pairwise.lean | 7 +++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Mathlib/Data/List/Chain.lean b/Mathlib/Data/List/Chain.lean index 0c4f488326a865..5e240bbd46b04e 100644 --- a/Mathlib/Data/List/Chain.lean +++ b/Mathlib/Data/List/Chain.lean @@ -8,8 +8,8 @@ module public import Mathlib.Data.List.Forall2 public import Mathlib.Data.List.Induction public import Mathlib.Data.List.Lex +public import Mathlib.Data.List.Pairwise public import Mathlib.Logic.Function.Iterate -public import Mathlib.Logic.Relation /-! # Relation chain @@ -25,13 +25,11 @@ public section assert_not_imported Mathlib.Algebra.Order.Group.Nat -universe u v - open Nat -namespace List +variable {α β : Type*} {R r : α → α → Prop} {l l₁ l₂ : List α} {a b : α} -variable {α : Type u} {β : Type v} {R r : α → α → Prop} {l l₁ l₂ : List α} {a b : α} +namespace List mk_iff_of_inductive_prop List.IsChain List.isChain_iff @@ -193,12 +191,17 @@ protected theorem IsChain.rel_cons [Trans R R R] (hl : (a :: l).IsChain R) (hb : theorem IsChain.tail {l : List α} (h : IsChain R l) : IsChain R l.tail := by grind +splitIndPred -theorem IsChain.rel_head {x y l} (h : IsChain R (x :: y :: l)) : R x y := - List.rel_of_isChain_cons_cons h +@[deprecated (since := "2026-06-25")] alias IsChain.rel_head := IsChain.rel theorem IsChain.rel_head? {x l} (h : IsChain R (x :: l)) ⦃y⦄ (hy : y ∈ head? l) : R x y := by rw [← cons_head?_tail hy] at h - exact h.rel_head + exact h.rel + +theorem IsChain.rel_getLast_dropLast {l : List α} (h : l.IsChain R) (hne : l.dropLast ≠ []) : + R (l.dropLast.getLast hne) (l.getLast <| by grind) := + match l with + | [_, _] => h.rel + | _ :: _ :: _ :: _ => h.tail.rel_getLast_dropLast <| by simp theorem IsChain.cons {x} : ∀ {l : List α}, IsChain R l → (∀ y ∈ l.head?, R x y) → IsChain R (x :: l) @@ -232,6 +235,12 @@ theorem IsChain.left_of_append (h : IsChain R (l₁ ++ l₂)) : IsChain R l₁ : theorem IsChain.right_of_append (h : IsChain R (l₁ ++ l₂)) : IsChain R l₂ := (isChain_append.1 h).2.1 +theorem IsChain.rel_getLast_head_of_append {l₁ l₂ : List α} (h : (l₁ ++ l₂).IsChain R) + (h₁ : l₁ ≠ []) (h₂ : l₂ ≠ []) : R (l₁.getLast h₁) (l₂.head h₂) := + match l₁, l₂ with + | [_], _ :: _ => h.rel + | _ :: _ :: _, _ :: _ => h.tail.rel_getLast_head_of_append (by simp) (by simp) + theorem IsChain.infix (h : IsChain R l) (h' : l₁ <:+: l) : IsChain R l₁ := by rcases h' with ⟨l₂, l₃, rfl⟩ exact h.left_of_append.right_of_append @@ -455,11 +464,29 @@ theorem isChain_cons_eq_iff_eq_replicate {a : α} {l : List α} : end List +theorem WellFoundedRelation.asymmetricₙ [WellFoundedRelation α] {l : List α} (hne : l ≠ []) + (h : l.IsChain WellFoundedRelation.rel) : + ¬WellFoundedRelation.rel (l.getLast hne) (l.head hne) := + match l with + | [x] => irrefl x + | _ :: _ :: _ => + fun hr ↦ asymmetricₙ (List.cons_ne_nil _ _) (h.dropLast.cons_cons hr) (h.rel_getLast_dropLast _) +termination_by l.head hne + +theorem WellFounded.asymmetricₙ (wf : WellFounded r) (hne : l ≠ []) (h : l.IsChain r) : + ¬r (l.getLast hne) (l.head hne) := + @WellFoundedRelation.asymmetricₙ α ⟨r, wf⟩ l hne h + +theorem WellFounded.listPairwise_reverse_compl (wf : WellFounded r) (h : l.IsChain r) : + l.reverse.Pairwise rᶜ := by + refine List.pairwise_iff_forall_infix.mpr fun l' hne hsub ↦ ?_ + have := wf.asymmetricₙ (by grind) <| h.infix <| l.reverse_reverse ▸ hsub.reverse + simpa /-! In this section, we consider the type of `r`-decreasing chains (`List.IsChain (flip r)`) equipped with lexicographic order `List.Lex r`. -/ -variable {α : Type*} (r : α → α → Prop) +variable (r) /-- The type of `r`-decreasing chains -/ abbrev List.chains := { l : List α // l.IsChain (flip r) } diff --git a/Mathlib/Data/List/Pairwise.lean b/Mathlib/Data/List/Pairwise.lean index 4ea247eb21099f..7860619d193500 100644 --- a/Mathlib/Data/List/Pairwise.lean +++ b/Mathlib/Data/List/Pairwise.lean @@ -40,6 +40,13 @@ mk_iff_of_inductive_prop List.Pairwise List.pairwise_iff /-! ### Pairwise -/ +theorem pairwise_iff_forall_infix {α : Type*} {l : List α} {R : α → α → Prop} : + l.Pairwise R ↔ + ∀ l', (h : 1 < l'.length) → l' <:+: l → R (l'.head <| by grind) (l'.getLast <| by grind) := by + refine l.pairwise_iff_getElem.trans ⟨fun h l' hne ⟨l₁, l₂, hl⟩ ↦ ?_, fun h i j hi hj hij ↦ ?_⟩ + · grind [getElem_append_left', getElem_append_right'] + · grind [h _ _ <| List.drop_suffix i _ |>.isInfix.trans <| l.take_prefix (j + 1) |>.isInfix] + theorem Pairwise.forall_of_forall [Std.Symm R] (H₁ : ∀ x ∈ l, R x x) (H₂ : l.Pairwise R) : ∀ ⦃x⦄, x ∈ l → ∀ ⦃y⦄, y ∈ l → R x y := H₂.forall_of_forall_of_flip H₁ <| by rwa [Std.Symm.flip_eq] From c19037a8100134c62a19bc5dbaffb633c4b9f3b4 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:53:39 +0000 Subject: [PATCH 0544/1300] fix(Translate): fix universe reorder inference (#40493) This PR fixes the way `to_dual` determines the universe reordering. Previously, the universe reordering was inferred using a heuristic. But, this heuristic fails on `Adjunction.comp`, because there we are reordering two arguments whose types themselves reorder their universes. This PR removes the heuristic, and instead uses unification to figure out the universe reordering (in the case of `to_dual self`/`to_dual existing`. When generating a new declaration, universes are now never reordered. I verified locally that `Adjunction.comp` can now be tagged with `to_dual`. --- Mathlib/Tactic/Translate/Core.lean | 30 +++++++++-------- Mathlib/Tactic/Translate/Reorder.lean | 37 +++++---------------- MathlibTest/Attribute/ToAdditive/Basic.lean | 8 +++-- MathlibTest/Attribute/ToDual.lean | 29 +++++++--------- 4 files changed, 43 insertions(+), 61 deletions(-) diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index c59c285f0cbe5f..4ae75b243cbdca 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -615,20 +615,19 @@ def applyReplacementLambda (t : TranslateData) (dontTranslate : List Nat) (e : E /-- Run `applyReplacementFun` on the given `srcDecl` to make a new declaration with name `tgt`. -/ def updateDecl (t : TranslateData) (tgt : Name) (srcDecl : ConstantInfo) - (reorder : Reorder) (dont : List Nat) + (reorder : ArgReorder) (dont : List Nat) (unfoldBoundaries? : Option UnfoldBoundary.UnfoldBoundaries) (rename : NameMap Name) : MetaM (ConstantInfo × Option RelevantArg) := do unless srcDecl.all == [srcDecl.name] do throwError "`{t.attrName}` does not support mutually recursive declarations." let decl := srcDecl.updateName tgt let decl := decl.updateAll [tgt] - let decl := decl.updateLevelParams (reorder.univReorder.permuteList! decl.levelParams) let mut value := decl.value! (allowOpaque := true) if let some b := unfoldBoundaries? then value ← b.cast (← b.insertBoundaries value t.attrName) decl.type t.attrName trace[translate] "Value before translation:{indentExpr value}" let (value', relevantArg₁) ← applyReplacementLambda t dont value - value ← reorderLambda reorder.reorder value' + value ← reorderLambda reorder value' if let some b := unfoldBoundaries? then value ← b.unfoldInsertions value let decl := decl.updateValue value @@ -637,7 +636,7 @@ def updateDecl (t : TranslateData) (tgt : Name) (srcDecl : ConstantInfo) type ← b.insertBoundaries decl.type t.attrName let (type', relevantArg₂) ← applyReplacementForall t dont <| renameBinderNames (t.guessNameExt.getState (← getEnv)) rename type - type ← reorderForall reorder.reorder type' + type ← reorderForall reorder type' if let some b := unfoldBoundaries? then type ← b.unfoldInsertions type return (decl.updateType type, .merge .min relevantArg₁ relevantArg₂) @@ -650,7 +649,7 @@ and only if that fails do we try to include them. The reason is that in the most common case, `to_dual` succeeds without needing to insert unfold boundaries, and figuring out whether to insert them can be quite expensive. -/ def updateAndAddDecl (t : TranslateData) (tgt : Name) (srcDecl : ConstantInfo) - (reorder : Reorder) (dont : List Nat) (rename : NameMap Name) : + (reorder : ArgReorder) (dont : List Nat) (rename : NameMap Name) : MetaM (ConstantInfo × Option RelevantArg) := -- Set `Elab.async` to `false` so that we can catch kernel errors. withOptions (Elab.async.set · false) do @@ -793,7 +792,6 @@ partial def transformDeclRec (t : TranslateData) (cfg : Config) (rootSrc rootTgt let namesPre := (← getConstInfo rootSrc).type.getForallBinderNames let namesSrc := (← getConstInfo src).type.getForallBinderNames pure <| cfg.dontTranslate.filterMap (namesPre[·]? >>= namesSrc.idxOf?) - let reorder := { reorder, univReorder := guessUnivReorder reorder srcDecl } -- now transform the source declaration let (tgtDecl, relevantArg?) ← MetaM.run' <| updateAndAddDecl t tgt srcDecl reorder dontTranslate rename @@ -802,7 +800,7 @@ partial def transformDeclRec (t : TranslateData) (cfg : Config) (rootSrc rootTgt getRelevantArg t cfg relevantArg? src else pure (relevantArg?.getD .noArg) - insertTranslation t src tgt reorder relevantArg cfg.ref + insertTranslation t src tgt { reorder } relevantArg cfg.ref if src == rootSrc && srcDecl.isThm && tgtDecl.type == srcDecl.type then Linter.logLintIf linter.translateRedundant cfg.ref m!"`{t.attrName}` did not change the type \ of theorem `{.ofConstName src}`. Please remove the attribute." @@ -964,9 +962,9 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config MetaM (Reorder × RelevantArg) := withoutExporting do let srcDecl ← getConstInfo src let tgtDecl ← getConstInfo tgt - unless srcDecl.levelParams.length == tgtDecl.levelParams.length do - throwError "`{t.attrName}` validation failed:\n expected {srcDecl.levelParams.length} \ - universe levels, but '{tgt}' has {tgtDecl.levelParams.length} universe levels" + unless srcDecl.numLevelParams == tgtDecl.numLevelParams do + throwError "`{t.attrName}` validation failed:\n expected {srcDecl.numLevelParams} \ + universe levels, but '{tgt}' has {tgtDecl.numLevelParams} universe levels" let mut srcType := srcDecl.type let unfoldBoundaries? ← t.unfoldBoundaries?.mapM (return ·.getState (← getEnv)) if let some b := unfoldBoundaries? then @@ -984,7 +982,6 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config pure reorder else pure reorder' - let univReorder := guessUnivReorder reorder srcDecl if cfg.self && reorder.isEmpty then Linter.logLintIf linter.translateRedundant cfg.ref m!"\ `{t.attrName} self` is redundant when none of the arguments are reordered.\n\ @@ -994,12 +991,19 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config srcType ← reorderForall reorder srcType if let some b := unfoldBoundaries? then srcType ← b.unfoldInsertions srcType - srcType := srcType.instantiateLevelParams - (univReorder.permuteList! srcDecl.levelParams) (tgtDecl.levelParams.map mkLevelParam) + -- We rely on unification to determine how the universe parameters need to be reordered. + let levels ← mkFreshLevelMVars srcDecl.numLevelParams + srcType := srcType.instantiateLevelParams srcDecl.levelParams levels let tgtType := tgtDecl.type unless ← withReducible <| isDefEq srcType tgtType do throwError "`{t.attrName}` validation failed: expected{indentExpr srcType}\nbut '{tgt}' has \ type{indentExpr tgtType}" + let params ← levels.mapM fun level ↦ do match ← instantiateLevelMVars level with + | .param u => return u + | _ => throwError "inferred universe `{level}` in `{srcType}` is not a parameter." + let some univReorder := getPermutation params.toArray tgtDecl.levelParams.toArray | + throwError "inferred universe parameters {params} \ + are not a reordering of {srcDecl.levelParams}." return ({ univReorder, reorder }, ← getRelevantArg t cfg relevantArg? src) /-- if `f src = #[a_1, ..., a_n]` and `f tgt = #[b_1, ... b_n]` then `proceedFieldsAux src tgt f` diff --git a/Mathlib/Tactic/Translate/Reorder.lean b/Mathlib/Tactic/Translate/Reorder.lean index bf27e65901608e..979689c87bedb4 100644 --- a/Mathlib/Tactic/Translate/Reorder.lean +++ b/Mathlib/Tactic/Translate/Reorder.lean @@ -246,34 +246,15 @@ private def decomposePerm {n} (map : Vector (Option (Fin n)) n) : Permutation := perm := cycle :: perm return perm -/-- Determine the universe level reorder for `decl`, given the argument reorder. -For each reordering in `reorder`, we find any corresponding universe reorderings, -which are then combined to get the result. -/ -def guessUnivReorder (reorder : ArgReorder) (decl : ConstantInfo) : Permutation := Id.run do - let mut map := .replicate decl.levelParams.length none - for ⟨cycle, _⟩ in reorder.perm do - for i in cycle, i' in cycle.tail ++ [cycle.head (by grind)] do - for (u, u') in matchingUnivs (getNthHyp i decl.type) (getNthHyp i' decl.type) do - let some p := getParam? u | pure () - let some p' := getParam? u' | pure () - if p != p' then - let some n := decl.levelParams.finIdxOf? p | pure () - let some n' := decl.levelParams.finIdxOf? p' | pure () - map := map.set n n' - return decomposePerm map -where - getNthHyp : Nat → Expr → Expr - | 0, e => e.bindingDomain! - | n + 1, e => getNthHyp n e.bindingBody! - matchingUnivs (e e' : Expr) : List (Level × Level) := - match e.getAppFn, e'.getAppFn with - | .const n us, .const n' us' => if n == n' then us.zip us' else [] - | .sort u, .sort u' => [(u, u')] - | _, _ => [] - getParam? : Level → Option Name - | .param p => some p - | .succ u => getParam? u - | _ => none +/-- Return the permutation that sends `src` to `tgt`, if it exists. -/ +def getPermutation {α : Type*} [BEq α] (src : Array α) (tgt : Array α) : Option Permutation := do + let n := src.size + if h : n = tgt.size then + have src : Vector α n := src.toVector + have tgt : Vector α n := h ▸ tgt.toVector + return decomposePerm (← src.mapM (some <$> tgt.finIdxOf? ·)) + else + none /-- Determine how many forall binders should be introduced to get a non-dependent conclusion. -/ private def depForallDepth : Expr → Nat diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index f4e097c49bfab5..4e815db07b96e8 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -96,17 +96,19 @@ class my_has_scalar (M : Type u) (α : Type v) where instance : my_has_scalar Nat Nat := ⟨fun a b => a * b⟩ attribute [to_additive (reorder := α β) my_has_scalar] my_has_pow +set_option pp.mvars.anonymous false in /-- error: `to_additive` validation failed: expected - {α : Type u} → {β : Type v} → [self : my_has_scalar β α] → α → β → α + {α : Type _} → {β : Type _} → [self : my_has_scalar β α] → α → β → α but 'Test.my_has_scalar.smul' has type {M : Type u} → {α : Type v} → [self : my_has_scalar M α] → M → α → α -/ #guard_msgs in attribute [to_additive existing] my_has_pow.pow +set_option pp.mvars.anonymous false in /-- error: `to_additive` validation failed: expected - {β : Type u} → {α : Type v} → [self : my_has_scalar β α] → α → β → α + {β : Type _} → {α : Type _} → [self : my_has_scalar β α] → α → β → α but 'Test.my_has_scalar.smul' has type {M : Type u} → {α : Type v} → [self : my_has_scalar M α] → M → α → α -/ @@ -583,7 +585,7 @@ lemma one_eq_one'' {α : Type*} [One α] : (1 : α) = 1 := rfl /-- error: `to_additive` validation failed: expected - ∀ {α : Type u} [inst : Zero α], 0 = 0 + ∀ {α : Type ?u.1} [inst : Zero α], 0 = 0 but 'Eq.trans' has type ∀ {α : Sort u} {a b c : α}, a = b → b = c → a = c -/ diff --git a/MathlibTest/Attribute/ToDual.lean b/MathlibTest/Attribute/ToDual.lean index 7a3676cc8633b0..cc33c6b6d4b891 100644 --- a/MathlibTest/Attribute/ToDual.lean +++ b/MathlibTest/Attribute/ToDual.lean @@ -391,37 +391,32 @@ info: eq_of_max_of_min {α : Type} [PartialOrder α] (a b : α) (hmin : ∀ (x : theorem le_of_lt_and_le_of_lt {β} [Preorder β] (a b : α) (c d : β) : (a < b → a ≤ b) ∧ (c < d → c ≤ d) := ⟨le_of_lt, (fun γ [Preorder γ] (c d : γ) ↦ @le_of_lt γ _ c d) β c d⟩ --- Test the reordering of universes -@[to_dual (reorder := α β γ) universeTest1'] -def universeTest1.{u,v,w} (α : Type u) (β : Type v) (γ : Type w) := α × β × γ +/-! Test the reordering of universes -/ -/-- info: universeTest1'.{w, u, v} (γ : Type w) (α : Type u) (β : Type v) : Type (max u w v) -/ -#guard_msgs in -#check universeTest1' +def universeTest1.{u,v,w} (α : Type u) (β : Type v) (γ : Type w) := α × β × γ +@[to_dual existing (reorder := α β γ) universeTest1] +def universeTest1'.{v,w,u} (α : Type u) (β : Type v) (γ : Type w) := α × β × γ +@[to_dual none] alias universeTest1'' := universeTest1 @[to_dual (reorder := u₁ u₂) universeTest2'] def universeTest2.{u,v} (u₁ : PUnit.{u}) (u₂ : PUnit.{v}) := PProd.mk u₁ u₂ -/-- info: universeTest2'.{v, u} (u₂ : PUnit) (u₁ : PUnit) : PUnit ×' PUnit -/ +/-- info: universeTest2'.{u, v} (u₂ : PUnit) (u₁ : PUnit) : PUnit ×' PUnit -/ #guard_msgs in #check universeTest2' -@[to_dual (reorder := u₁ u₂) universeTest3'] -def universeTest3.{u,u',v,v'} (u₁ : PProd PUnit.{u} PUnit.{u'}) (u₂ : PProd PUnit.{v} PUnit.{v'}) := - PProd.mk u₁ u₂ - -/-- -info: universeTest3'.{v, v', u, u'} (u₂ : PUnit ×' PUnit) (u₁ : PUnit ×' PUnit) : (PUnit ×' PUnit) ×' PUnit ×' PUnit --/ -#guard_msgs in -#check universeTest3' - class Category.{v,u} (c : Type u) where bla : Type v @[to_dual self (reorder := A B, 2 4)] structure Comma {A : Type u} [Category.{v} A] {B : Type u'} [Category.{v'} B] where +@[to_dual self (reorder := α β, 3 4)] +axiom HLE {α β : Type*} : α → β → Prop + +@[to_dual self (reorder := α γ, a c, 7 8)] +axiom hle_trans {α β γ : Type*} (a : α) (b : β) (c : γ) : HLE a b → HLE b c → HLE a c + open Mathlib.Tactic Translate ToDual /-- info: "leftMono" -/ From 5fe4bfd593b85d063af1dff2ede334da193e7d71 Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:46:50 +0000 Subject: [PATCH 0545/1300] doc(LinearAlgebra/FreeModule/StrongRankCondition): clarify context of `commRing_strongRankCondition` (#38347) * Clarify that the file `Mathlib.LinearAlgebra.FreeModule.StrongRankCondition` comprises a shortcut instance `commRing_strongRankCondition` * Signpost `commRing_strongRankCondition` at both its parent instances * Increase priority of shortcut instance `commRing_strongRankCondition` above that of its parent instances Co-authored-by: artie2000 --- .../FreeModule/StrongRankCondition.lean | 21 +++++++---------- .../LinearAlgebra/InvariantBasisNumber.lean | 23 +++++++++++-------- Mathlib/RingTheory/FiniteType.lean | 10 ++++++-- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/Mathlib/LinearAlgebra/FreeModule/StrongRankCondition.lean b/Mathlib/LinearAlgebra/FreeModule/StrongRankCondition.lean index 4e8dc56053307c..6d6e235b901027 100644 --- a/Mathlib/LinearAlgebra/FreeModule/StrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/FreeModule/StrongRankCondition.lean @@ -12,10 +12,10 @@ public import Mathlib.LinearAlgebra.InvariantBasisNumber # Strong rank condition for commutative rings -We prove that any nontrivial commutative ring satisfies `StrongRankCondition`, meaning that -if there is an injective linear map `(Fin n → R) →ₗ[R] Fin m → R`, then `n ≤ m`. This implies that -any commutative ring satisfies `InvariantBasisNumber`: the rank of a finitely generated free -module is well defined. +We provide a shortcut instance for the fact that any nontrivial commutative ring satisfies +`StrongRankCondition`, meaning that if there is an injective linear map +`(Fin n → R) →ₗ[R] Fin m → R`, then `n ≤ m`. This implies that any commutative ring satisfies +`InvariantBasisNumber`: the rank of a finitely generated free module is well defined. ## Main result @@ -27,7 +27,6 @@ the `OrzechProperty`, that is, for any finitely generated `R`-module `M`, any surjective homomorphism `f : N → M` from a submodule `N` of `M` to `M` is injective. - ## References * [Orzech, Morris. *Onto endomorphisms are isomorphisms*][orzech1971] @@ -37,11 +36,7 @@ is injective. -/ -public section - - -variable (R : Type*) [CommRing R] [Nontrivial R] - -/-- Any nontrivial commutative ring satisfies the `StrongRankCondition`. -/ -instance (priority := 100) commRing_strongRankCondition : StrongRankCondition R := - inferInstance +/-- Shortcut instance for the fact that any nontrivial commutative ring satisfies +the strong rank condition. -/ +public instance (priority := 200) commRing_strongRankCondition + (R : Type*) [CommRing R] [Nontrivial R] : StrongRankCondition R := inferInstance diff --git a/Mathlib/LinearAlgebra/InvariantBasisNumber.lean b/Mathlib/LinearAlgebra/InvariantBasisNumber.lean index 4bb87559796efa..61512f8a35ca17 100644 --- a/Mathlib/LinearAlgebra/InvariantBasisNumber.lean +++ b/Mathlib/LinearAlgebra/InvariantBasisNumber.lean @@ -296,15 +296,20 @@ section attribute [local instance] Ideal.Quotient.field -/-- Nontrivial commutative rings have the invariant basis number property. - -There are two stronger results in mathlib: `commRing_strongRankCondition`, which says that any -nontrivial commutative ring satisfies the strong rank condition, and -`rankCondition_of_nontrivial_of_commSemiring`, which says that any nontrivial commutative semiring -satisfies the rank condition. - -We prove this instance separately to avoid dependency on -`Mathlib/LinearAlgebra/Charpoly/Basic.lean` or `Mathlib/LinearAlgebra/Matrix/ToLin.lean`. -/ +/-- +Nontrivial commutative rings satisfy the invariant basis number property. + +There are two stronger results in mathlib: +1. `CommRing.orzechProperty` in `Mathlib.RingTheory.FiniteType`, + which says that any commutative ring satisfies the Orzech property, and hence + (by `strongRankCondition_of_orzechProperty`) that nontrivial commutative rings satisfy + the strong rank condition. A shortcut instance `commRing_strongRankCondition` is also provided. +2. `rankCondition_of_nontrivial_of_commSemiring` in + `Mathlib.LinearAlgebra.Matrix.InvariantBasisNumber`, which says that + any nontrivial commutative semiring satisfies the rank condition. + +We prove this instance here anyway to reduce the required imports. +-/ instance (priority := 100) invariantBasisNumber_of_nontrivial_of_commRing {R : Type u} [CommRing R] [Nontrivial R] : InvariantBasisNumber R := ⟨fun e => diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index 3748e2ff54e2fb..68ec9e65447b48 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -611,7 +611,8 @@ end MonoidAlgebra section Orzech open Submodule Module Module.Finite in -/-- Any commutative ring `R` satisfies the `OrzechProperty`, that is, for any finitely generated +/-- +Any commutative ring `R` satisfies the `OrzechProperty`, that is, for any finitely generated `R`-module `M`, any surjective homomorphism `f : N →ₗ[R] M` from a submodule `N` of `M` to `M` is injective. @@ -630,7 +631,12 @@ then it's easy to see that `i` and `f` restrict to `N' →ₗ[A] M'`, and the restricted version of `f` is surjective, hence by Noetherian case, it is also injective, in particular, if `f n = 0`, then `n = 0`. -See also Orzech's original paper: *Onto endomorphisms are isomorphisms* [orzech1971]. -/ +See also Orzech's original paper: *Onto endomorphisms are isomorphisms* [orzech1971]. + +This implies that nontrivial commutative rings satisfy the strong rank condition: +see `strongRankCondition_of_orzechProperty` in `Mathlib.LinearAlgebra.InvariantBasisNumber`. +A shortcut instance `commRing_strongRankCondition` is also provided. +-/ instance (priority := 100) CommRing.orzechProperty (R : Type*) [CommRing R] : OrzechProperty R := by refine ⟨fun {M} _ _ _ {N} f hf ↦ ?_⟩ From 4f548c102d53c65f8b60e5811a9f54a72fcaeaec Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:28:45 +0000 Subject: [PATCH 0546/1300] feat(Topology/Order/IntermediateValue): images of intervals under monotone continuous functions (#41130) Add `ContinuousOn.image_{Icc,Ico,Ioc,Ioo,uIcc,Ici,Iic,Ioi,Iio}_of_{monotone,antitone,strictMono,strictAnti}On`, computing the image of a (bounded or unbounded) interval under a monotone/antitone continuous map, together with the unbounded intermediate value theorems `intermediate_value_{Ici,Iic,Ioi,Iio}` (and primed variants) they build on. Co-authored-by: Terence Tao --- Mathlib/Topology/Order/Compact.lean | 13 -- Mathlib/Topology/Order/IntermediateValue.lean | 157 ++++++++++++++++++ 2 files changed, 157 insertions(+), 13 deletions(-) diff --git a/Mathlib/Topology/Order/Compact.lean b/Mathlib/Topology/Order/Compact.lean index 8f328aaa190157..f0d3709f69b256 100644 --- a/Mathlib/Topology/Order/Compact.lean +++ b/Mathlib/Topology/Order/Compact.lean @@ -543,17 +543,4 @@ theorem le_sSup_image_Icc (h : ContinuousOn f <| Icc a b) (hc : c ∈ Icc a b) : rw [h.image_Icc (hc.1.trans hc.2)] at this exact this.2 -theorem image_Icc_of_monotoneOn (hab : a ≤ b) (h : ContinuousOn f <| Icc a b) - (h' : MonotoneOn f <| Icc a b) : f '' Icc a b = Icc (f a) (f b) := by - rw [h.image_Icc hab] - congr! - · exact h'.sInf_image_Icc hab - · exact h'.sSup_image_Icc hab - -theorem image_Icc_of_antitoneOn (hab : a ≤ b) (h : ContinuousOn f <| Icc a b) - (h' : AntitoneOn f <| Icc a b) : f '' Icc a b = Icc (f b) (f a) := by - have : Icc (f b) (f a) = Icc (toDual (f a)) (toDual (f b)) := by rw [Icc_toDual]; rfl - rw [this] - exact image_Icc_of_monotoneOn (β := βᵒᵈ) hab h h'.dual_right - end ContinuousOn diff --git a/Mathlib/Topology/Order/IntermediateValue.lean b/Mathlib/Topology/Order/IntermediateValue.lean index b42d4b31e012d3..3bcb0694485bac 100644 --- a/Mathlib/Topology/Order/IntermediateValue.lean +++ b/Mathlib/Topology/Order/IntermediateValue.lean @@ -633,6 +633,50 @@ theorem intermediate_value_Ioo' {a b : α} (hab : a ≤ b) {f : α → δ} ((hf.continuousWithinAt ⟨hab, refl b⟩).mono Ioo_subset_Icc_self) ((hf.continuousWithinAt ⟨refl a, hab⟩).mono Ioo_subset_Icc_self) +theorem intermediate_value_Ici {a : α} {f : α → δ} (hf : ContinuousOn f (Ici a)) + (htop : Tendsto f atTop atTop) : Ici (f a) ⊆ f '' Ici a := + isPreconnected_Ici.intermediate_value_Ici self_mem_Ici + (le_principal_iff.mpr (Ici_mem_atTop a)) hf htop + +theorem intermediate_value_Ici' {a : α} {f : α → δ} (hf : ContinuousOn f (Ici a)) + (htop : Tendsto f atTop atBot) : Iic (f a) ⊆ f '' Ici a := + isPreconnected_Ici.intermediate_value_Iic self_mem_Ici + (le_principal_iff.mpr (Ici_mem_atTop a)) hf htop + +theorem intermediate_value_Iic {a : α} {f : α → δ} (hf : ContinuousOn f (Iic a)) + (hbot : Tendsto f atBot atBot) : Iic (f a) ⊆ f '' Iic a := + isPreconnected_Iic.intermediate_value_Iic self_mem_Iic + (le_principal_iff.mpr (Iic_mem_atBot a)) hf hbot + +theorem intermediate_value_Iic' {a : α} {f : α → δ} (hf : ContinuousOn f (Iic a)) + (hbot : Tendsto f atBot atTop) : Ici (f a) ⊆ f '' Iic a := + isPreconnected_Iic.intermediate_value_Ici self_mem_Iic + (le_principal_iff.mpr (Iic_mem_atBot a)) hf hbot + +theorem intermediate_value_Ioi {a : α} {f : α → δ} (hf : ContinuousOn f (Ici a)) + (htop : Tendsto f atTop atTop) : Ioi (f a) ⊆ f '' Ioi a := by + intro y hy + have := intermediate_value_Ici hf htop (mem_Ici_of_Ioi hy) + grind + +theorem intermediate_value_Ioi' {a : α} {f : α → δ} (hf : ContinuousOn f (Ici a)) + (htop : Tendsto f atTop atBot) : Iio (f a) ⊆ f '' Ioi a := by + intro y hy + have := intermediate_value_Ici' hf htop (mem_Iic_of_Iio hy) + grind + +theorem intermediate_value_Iio {a : α} {f : α → δ} (hf : ContinuousOn f (Iic a)) + (hbot : Tendsto f atBot atBot) : Iio (f a) ⊆ f '' Iio a := by + intro y hy + have := intermediate_value_Iic hf hbot (mem_Iic_of_Iio hy) + grind + +theorem intermediate_value_Iio' {a : α} {f : α → δ} (hf : ContinuousOn f (Iic a)) + (hbot : Tendsto f atBot atTop) : Ioi (f a) ⊆ f '' Iio a := by + intro y hy + have := intermediate_value_Iic' hf hbot (mem_Ici_of_Ioi hy) + grind + /-- **Intermediate value theorem**: if `f` is continuous on an order-connected set `s` and `a`, `b` are two points of this set, then `f` sends `s` to a superset of `Icc (f a) (f b)`. -/ theorem ContinuousOn.surjOn_Icc {s : Set α} [hs : OrdConnected s] {f : α → δ} @@ -678,6 +722,10 @@ theorem ContinuousOn.surjOn_of_tendsto' {f : α → δ} {s : Set α} [OrdConnect (htop : Tendsto (fun x : s => f x) atTop atBot) : SurjOn f s univ := ContinuousOn.surjOn_of_tendsto (δ := δᵒᵈ) hs hf hbot htop +/-! +### Monotonicity of injective continuous functions +-/ + theorem Continuous.strictMono_of_inj_boundedOrder [BoundedOrder α] {f : α → δ} (hf_c : Continuous f) (hf : f ⊥ ≤ f ⊤) (hf_i : Injective f) : StrictMono f := by intro a b hab @@ -787,3 +835,112 @@ theorem ContinuousOn.strictMonoOn_of_injOn_Ioo {a b : α} {f : α → δ} (hab : have : StrictMono g ∨ StrictAnti g := Continuous.strictMono_of_inj hf_c.restrict hf_i.injective exact this.imp strictMono_restrict.mp strictAntiOn_iff_strictAnti.mpr + +/-! +### Images of continuous monotone functions +-/ + +variable {a b : α} {f : α → δ} + +theorem ContinuousOn.image_Icc_of_monotoneOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : MonotoneOn f (Icc a b)) : f '' Icc a b = Icc (f a) (f b) := + subset_antisymm (hmono.image_Icc_subset) (intermediate_value_Icc hab hf) + +theorem ContinuousOn.image_Icc_of_antitoneOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : AntitoneOn f (Icc a b)) : f '' Icc a b = Icc (f b) (f a) := + subset_antisymm (hmono.image_Icc_subset) (intermediate_value_Icc' hab hf) + +theorem ContinuousOn.image_Ico_of_strictMonoOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : StrictMonoOn f (Icc a b)) : f '' Ico a b = Ico (f a) (f b) := + subset_antisymm (hmono.image_Ico_subset) (intermediate_value_Ico hab hf) + +theorem ContinuousOn.image_Ico_of_strictAntiOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : StrictAntiOn f (Icc a b)) : f '' Ico a b = Ioc (f b) (f a) := + subset_antisymm (hmono.image_Ico_subset) (intermediate_value_Ico' hab hf) + +theorem ContinuousOn.image_Ioc_of_strictMonoOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : StrictMonoOn f (Icc a b)) : f '' Ioc a b = Ioc (f a) (f b) := + subset_antisymm (hmono.image_Ioc_subset) (intermediate_value_Ioc hab hf) + +theorem ContinuousOn.image_Ioc_of_strictAntiOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : StrictAntiOn f (Icc a b)) : f '' Ioc a b = Ico (f b) (f a) := + subset_antisymm (hmono.image_Ioc_subset) (intermediate_value_Ioc' hab hf) + +theorem ContinuousOn.image_Ioo_of_strictMonoOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : StrictMonoOn f (Icc a b)) : f '' Ioo a b = Ioo (f a) (f b) := + subset_antisymm (hmono.image_Ioo_subset) (intermediate_value_Ioo hab hf) + +theorem ContinuousOn.image_Ioo_of_strictAntiOn (hab : a ≤ b) (hf : ContinuousOn f (Icc a b)) + (hmono : StrictAntiOn f (Icc a b)) : f '' Ioo a b = Ioo (f b) (f a) := + subset_antisymm (hmono.image_Ioo_subset) (intermediate_value_Ioo' hab hf) + +theorem ContinuousOn.image_uIcc_of_monotoneOn (hf : ContinuousOn f [[a, b]]) + (hmono : MonotoneOn f [[a, b]]) : f '' [[a, b]] = [[f a, f b]] := + subset_antisymm (hmono.image_uIcc_subset) (intermediate_value_uIcc hf) + +theorem ContinuousOn.image_uIcc_of_antitoneOn (hf : ContinuousOn f [[a, b]]) + (hmono : AntitoneOn f [[a, b]]) : f '' [[a, b]] = [[f a, f b]] := + subset_antisymm (hmono.image_uIcc_subset) (intermediate_value_uIcc hf) + +theorem ContinuousOn.image_Ici_of_monotoneOn (hf : ContinuousOn f (Ici a)) + (hmono : MonotoneOn f (Ici a)) (htop : Tendsto f atTop atTop) : f '' Ici a = Ici (f a) := + subset_antisymm (hmono.image_Ici_subset) (intermediate_value_Ici hf htop) + +theorem ContinuousOn.image_Ici_of_antitoneOn (hf : ContinuousOn f (Ici a)) + (hmono : AntitoneOn f (Ici a)) (htop : Tendsto f atTop atBot) : f '' Ici a = Iic (f a) := + subset_antisymm (hmono.image_Ici_subset) (intermediate_value_Ici' hf htop) + +theorem ContinuousOn.image_Iic_of_monotoneOn (hf : ContinuousOn f (Iic a)) + (hmono : MonotoneOn f (Iic a)) (hbot : Tendsto f atBot atBot) : f '' Iic a = Iic (f a) := + subset_antisymm (hmono.image_Iic_subset) (intermediate_value_Iic hf hbot) + +theorem ContinuousOn.image_Iic_of_antitoneOn (hf : ContinuousOn f (Iic a)) + (hmono : AntitoneOn f (Iic a)) (hbot : Tendsto f atBot atTop) : f '' Iic a = Ici (f a) := + subset_antisymm (hmono.image_Iic_subset) (intermediate_value_Iic' hf hbot) + +theorem ContinuousOn.image_Ioi_of_strictMonoOn (hf : ContinuousOn f (Ici a)) + (hmono : StrictMonoOn f (Ici a)) (htop : Tendsto f atTop atTop) : f '' Ioi a = Ioi (f a) := + subset_antisymm (hmono.image_Ioi_subset) (intermediate_value_Ioi hf htop) + +theorem ContinuousOn.image_Ioi_of_strictAntiOn (hf : ContinuousOn f (Ici a)) + (hmono : StrictAntiOn f (Ici a)) (htop : Tendsto f atTop atBot) : f '' Ioi a = Iio (f a) := + subset_antisymm (hmono.image_Ioi_subset) (intermediate_value_Ioi' hf htop) + +theorem ContinuousOn.image_Iio_of_strictMonoOn (hf : ContinuousOn f (Iic a)) + (hmono : StrictMonoOn f (Iic a)) (hbot : Tendsto f atBot atBot) : f '' Iio a = Iio (f a) := + subset_antisymm (hmono.image_Iio_subset) (intermediate_value_Iio hf hbot) + +theorem ContinuousOn.image_Iio_of_strictAntiOn (hf : ContinuousOn f (Iic a)) + (hmono : StrictAntiOn f (Iic a)) (hbot : Tendsto f atBot atTop) : f '' Iio a = Ioi (f a) := + subset_antisymm (hmono.image_Iio_subset) (intermediate_value_Iio' hf hbot) + +/-! +### Order-agnostic images under continuous strictly monotone maps + +If `f` is *globally* continuous and strictly monotone, each interval maps to the interval of its +endpoint images with no `a ≤ b` hypothesis: when `a > b`, both sides are empty (since `f a > f b`). +-/ + +theorem Continuous.image_Icc_of_strictMono (hf_c : Continuous f) (hf : StrictMono f) : + f '' Icc a b = Icc (f a) (f b) := by + rcases le_or_gt a b with hab | hab + · exact hf_c.continuousOn.image_Icc_of_monotoneOn hab (hf.monotone.monotoneOn _) + · simp [not_le.mpr hab, not_le.mpr (hf hab)] + +theorem Continuous.image_Ico_of_strictMono (hf_c : Continuous f) (hf : StrictMono f) : + f '' Ico a b = Ico (f a) (f b) := by + rcases le_or_gt a b with hab | hab + · exact hf_c.continuousOn.image_Ico_of_strictMonoOn hab (hf.strictMonoOn _) + · simp [lt_asymm hab, lt_asymm (hf hab)] + +theorem Continuous.image_Ioc_of_strictMono (hf_c : Continuous f) (hf : StrictMono f) : + f '' Ioc a b = Ioc (f a) (f b) := by + rcases le_or_gt a b with hab | hab + · exact hf_c.continuousOn.image_Ioc_of_strictMonoOn hab (hf.strictMonoOn _) + · simp [lt_asymm hab, lt_asymm (hf hab)] + +theorem Continuous.image_Ioo_of_strictMono (hf_c : Continuous f) (hf : StrictMono f) : + f '' Ioo a b = Ioo (f a) (f b) := by + rcases le_or_gt a b with hab | hab + · exact hf_c.continuousOn.image_Ioo_of_strictMonoOn hab (hf.strictMonoOn _) + · simp [lt_asymm hab, lt_asymm (hf hab)] From 48489ec86e768e6d248d33fa9ea9b05c97e32b17 Mon Sep 17 00:00:00 2001 From: Harald Husum Date: Thu, 2 Jul 2026 14:51:33 +0000 Subject: [PATCH 0547/1300] chore: add an empty line after module headers (#39428) This makes the docs easier to read. --- Archive/Imo/Imo1998Q2.lean | 1 + Archive/Imo/Imo2001Q6.lean | 1 + Archive/Imo/Imo2005Q3.lean | 1 + Archive/Imo/Imo2008Q2.lean | 1 + Archive/Imo/Imo2008Q3.lean | 1 + Archive/Imo/Imo2008Q4.lean | 1 + Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean | 1 + Counterexamples/PeanoCurve.lean | 1 + Counterexamples/Pseudoelement.lean | 1 + Mathlib/Algebra/Algebra/Spectrum/Basic.lean | 1 + Mathlib/Algebra/Category/Grp/EpiMono.lean | 1 + Mathlib/Algebra/Category/ModuleCat/Stalk.lean | 2 +- Mathlib/Algebra/EuclideanDomain/Field.lean | 1 + Mathlib/Algebra/EuclideanDomain/Int.lean | 1 + Mathlib/Algebra/Homology/Opposite.lean | 1 + Mathlib/Algebra/Lie/Cochain.lean | 1 + Mathlib/Algebra/Lie/Extension.lean | 1 + Mathlib/Algebra/Lie/Loop.lean | 1 + Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean | 1 + Mathlib/Algebra/Order/AddTorsor.lean | 1 + Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean | 1 + Mathlib/Algebra/Squarefree/Basic.lean | 1 + Mathlib/Algebra/Vertex/HVertexOperator.lean | 1 + Mathlib/Algebra/Vertex/VertexOperator.lean | 1 + Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean | 1 + .../AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean | 1 + Mathlib/Analysis/Analytic/RadiusLiminf.lean | 1 + Mathlib/Analysis/Normed/Affine/Convex.lean | 1 + Mathlib/Analysis/Normed/Lp/PiLp.lean | 1 + Mathlib/Analysis/Normed/Lp/ProdLp.lean | 1 + Mathlib/Analysis/Normed/Unbundled/SeminormFromBounded.lean | 1 + Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean | 1 + Mathlib/CategoryTheory/DinatTrans.lean | 1 + Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean | 1 + Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean | 1 + Mathlib/CategoryTheory/PathCategory/Basic.lean | 1 + Mathlib/CategoryTheory/Preadditive/Schur.lean | 1 + Mathlib/CategoryTheory/Sites/Abelian.lean | 1 + Mathlib/CategoryTheory/Sites/LeftExact.lean | 1 + Mathlib/CategoryTheory/Thin.lean | 1 + Mathlib/Combinatorics/Configuration.lean | 1 + Mathlib/Data/Bracket.lean | 1 + Mathlib/Data/Bundle.lean | 1 + Mathlib/Data/Finsupp/BigOperators.lean | 2 +- Mathlib/Data/Nat/Squarefree.lean | 1 + Mathlib/Data/PSigma/Order.lean | 1 + Mathlib/Data/SProd.lean | 1 + Mathlib/Data/Set/Enumerate.lean | 1 + Mathlib/Data/Set/UnionLift.lean | 1 + Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean | 1 + Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean | 1 + Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean | 1 + Mathlib/FieldTheory/RatFunc/AsPolynomial.lean | 1 + Mathlib/Geometry/Manifold/Algebra/Monoid.lean | 1 + Mathlib/Geometry/Manifold/Diffeomorph.lean | 1 + Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean | 1 + Mathlib/GroupTheory/CommutingProbability.lean | 1 + Mathlib/LinearAlgebra/Multilinear/Curry.lean | 1 + Mathlib/LinearAlgebra/RootSystem/Finite/CanonicalBilinear.lean | 1 + Mathlib/LinearAlgebra/RootSystem/Hom.lean | 1 + Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean | 1 + Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean | 1 + Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean | 1 + Mathlib/Logic/Lemmas.lean | 1 + Mathlib/MeasureTheory/Function/EssSup.lean | 1 + Mathlib/MeasureTheory/Group/Prod.lean | 1 + Mathlib/ModelTheory/PartialEquiv.lean | 1 + Mathlib/NumberTheory/ClassNumber/AdmissibleAbs.lean | 1 + Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean | 1 + Mathlib/NumberTheory/ClassNumber/Finite.lean | 1 + Mathlib/NumberTheory/Cyclotomic/Discriminant.lean | 1 + Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean | 1 + Mathlib/NumberTheory/FLT/Four.lean | 1 + Mathlib/NumberTheory/FLT/Three.lean | 1 + Mathlib/NumberTheory/NumberField/Basic.lean | 1 + Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean | 1 + Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean | 1 + Mathlib/NumberTheory/NumberField/Cyclotomic/Embeddings.lean | 1 + Mathlib/NumberTheory/NumberField/Cyclotomic/PID.lean | 1 + Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean | 1 + Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean | 1 + Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean | 1 + Mathlib/NumberTheory/NumberField/EquivReindex.lean | 2 +- Mathlib/NumberTheory/NumberField/ExistsRamified.lean | 1 + Mathlib/NumberTheory/NumberField/House.lean | 2 +- Mathlib/NumberTheory/NumberField/Norm.lean | 1 + Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean | 1 + Mathlib/Order/Bounded.lean | 1 + Mathlib/Probability/Distributions/Uniform.lean | 1 + Mathlib/RepresentationTheory/Rep/Res.lean | 1 + Mathlib/RingTheory/AdicCompletion/RingHom.lean | 1 + Mathlib/RingTheory/Conductor.lean | 1 + Mathlib/RingTheory/Coprime/Lemmas.lean | 1 + Mathlib/RingTheory/DedekindDomain/AdicValuation.lean | 1 + Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean | 1 + Mathlib/RingTheory/DedekindDomain/Instances.lean | 1 + Mathlib/RingTheory/HahnSeries/Addition.lean | 1 + Mathlib/RingTheory/HahnSeries/Binomial.lean | 1 + Mathlib/RingTheory/HahnSeries/Multiplication.lean | 1 + Mathlib/RingTheory/HahnSeries/PowerSeries.lean | 1 + Mathlib/RingTheory/HahnSeries/Summable.lean | 1 + Mathlib/RingTheory/NoetherNormalization.lean | 1 + Mathlib/RingTheory/Nullstellensatz.lean | 1 + Mathlib/RingTheory/Perfectoid/FontaineTheta.lean | 1 + Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean | 1 + Mathlib/RingTheory/Polynomial/Eisenstein/Basic.lean | 1 + Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean | 1 + Mathlib/RingTheory/Polynomial/GaussNorm.lean | 1 + Mathlib/RingTheory/PowerSeries/Binomial.lean | 1 + Mathlib/RingTheory/PowerSeries/GaussNorm.lean | 1 + Mathlib/RingTheory/Prime.lean | 1 + Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean | 1 + Mathlib/Tactic/Algebra/Basic.lean | 1 + Mathlib/Tactic/ApplyWith.lean | 1 + Mathlib/Tactic/Choose.lean | 1 + Mathlib/Tactic/ExistsI.lean | 1 + Mathlib/Tactic/Linter/ValidatePRTitle.lean | 1 + Mathlib/Tactic/Rename.lean | 1 + Mathlib/Topology/Sheaves/Abelian.lean | 1 + 119 files changed, 119 insertions(+), 4 deletions(-) diff --git a/Archive/Imo/Imo1998Q2.lean b/Archive/Imo/Imo1998Q2.lean index fe51caef4ee585..2badc27f504822 100644 --- a/Archive/Imo/Imo1998Q2.lean +++ b/Archive/Imo/Imo1998Q2.lean @@ -13,6 +13,7 @@ import Mathlib.Tactic.Ring /-! # IMO 1998 Q2 + In a competition, there are `a` contestants and `b` judges, where `b ≥ 3` is an odd integer. Each judge rates each contestant as either "pass" or "fail". Suppose `k` is a number such that, for any two judges, their ratings coincide for at most `k` contestants. Prove that `k / a ≥ (b - 1) / (2b)`. diff --git a/Archive/Imo/Imo2001Q6.lean b/Archive/Imo/Imo2001Q6.lean index a9398555e019e6..fe5fe2494095ed 100644 --- a/Archive/Imo/Imo2001Q6.lean +++ b/Archive/Imo/Imo2001Q6.lean @@ -9,6 +9,7 @@ import Mathlib.Tactic.LinearCombination /-! # IMO 2001 Q6 + Let $a$, $b$, $c$, $d$ be integers with $a > b > c > d > 0$. Suppose that $$ a*c + b*d = (a + b - c + d) * (-a + b + c + d). $$ diff --git a/Archive/Imo/Imo2005Q3.lean b/Archive/Imo/Imo2005Q3.lean index 5202b5de1bd618..952e5fd6ce5762 100644 --- a/Archive/Imo/Imo2005Q3.lean +++ b/Archive/Imo/Imo2005Q3.lean @@ -11,6 +11,7 @@ import Mathlib.Tactic.Ring /-! # IMO 2005 Q3 + Let `x`, `y` and `z` be positive real numbers such that `xyz ≥ 1`. Prove that: `(x^5 - x^2)/(x^5 + y^2 + z^2) + (y^5 - y^2)/(y^5 + z^2 + x^2) + (z^5 - z^2)/(z^5 + x^2 + y^2) ≥ 0` diff --git a/Archive/Imo/Imo2008Q2.lean b/Archive/Imo/Imo2008Q2.lean index 485185b47bd7bf..695b32fc2160d6 100644 --- a/Archive/Imo/Imo2008Q2.lean +++ b/Archive/Imo/Imo2008Q2.lean @@ -12,6 +12,7 @@ import Mathlib.Tactic.Ring /-! # IMO 2008 Q2 + (a) Prove that ``` x^2 / (x-1)^2 + y^2 / (y-1)^2 + z^2 / (z-1)^2 ≥ 1 diff --git a/Archive/Imo/Imo2008Q3.lean b/Archive/Imo/Imo2008Q3.lean index 8749329ce9d0ce..fcb23b005b7df6 100644 --- a/Archive/Imo/Imo2008Q3.lean +++ b/Archive/Imo/Imo2008Q3.lean @@ -12,6 +12,7 @@ import Mathlib.Tactic.LinearCombination /-! # IMO 2008 Q3 + Prove that there exist infinitely many positive integers `n` such that `n^2 + 1` has a prime divisor which is greater than `2n + √(2n)`. diff --git a/Archive/Imo/Imo2008Q4.lean b/Archive/Imo/Imo2008Q4.lean index 3cb69c48a8537c..69bd134ea246ff 100644 --- a/Archive/Imo/Imo2008Q4.lean +++ b/Archive/Imo/Imo2008Q4.lean @@ -10,6 +10,7 @@ import Mathlib.Tactic.LinearCombination /-! # IMO 2008 Q4 + Find all functions `f : (0,∞) → (0,∞)` (so, `f` is a function from the positive real numbers to the positive real numbers) such that ``` diff --git a/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean b/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean index c671fb9407ba99..bd6548b6cf585d 100644 --- a/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean +++ b/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean @@ -7,6 +7,7 @@ import Mathlib.Analysis.SpecificLimits.Basic /-! # Discrete uniformities and discrete topology + Exactly as different metrics can induce equivalent topologies on a space, it is possible that different uniform structures (a notion that generalises that of a metric structure) induce the same topology on a space. In this file we are concerned in particular with the *discrete topology*, diff --git a/Counterexamples/PeanoCurve.lean b/Counterexamples/PeanoCurve.lean index c919bfda630107..cf1843125341fa 100644 --- a/Counterexamples/PeanoCurve.lean +++ b/Counterexamples/PeanoCurve.lean @@ -8,6 +8,7 @@ import Mathlib.Topology.MetricSpace.HausdorffAlexandroff /-! # Peano curve + This file proves the existence of a Peano curve -- continuous surjective map from the interval `[0, 1]` onto the square `[0, 1] × [0, 1]`. -/ diff --git a/Counterexamples/Pseudoelement.lean b/Counterexamples/Pseudoelement.lean index f6307491cc1b0e..fa640e6f0af98e 100644 --- a/Counterexamples/Pseudoelement.lean +++ b/Counterexamples/Pseudoelement.lean @@ -8,6 +8,7 @@ import Mathlib.Algebra.Category.ModuleCat.Biproducts /-! # Pseudoelements and pullbacks + Borceux claims in Proposition 1.9.5 that the pseudoelement constructed in `CategoryTheory.Abelian.Pseudoelement.pseudo_pullback` is unique. We show here that this claim is false. This means in particular that we cannot have an extensionality principle for pullbacks in diff --git a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean index 16755c4c407be2..4970815af4ca2f 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean @@ -13,6 +13,7 @@ public import Mathlib.Tactic.NoncommRing /-! # Spectrum of an element in an algebra + This file develops the basic theory of the spectrum of an element of an algebra. This theory will serve as the foundation for spectral theory in Banach algebras. diff --git a/Mathlib/Algebra/Category/Grp/EpiMono.lean b/Mathlib/Algebra/Category/Grp/EpiMono.lean index 441946c54d9b03..1414285658ead5 100644 --- a/Mathlib/Algebra/Category/Grp/EpiMono.lean +++ b/Mathlib/Algebra/Category/Grp/EpiMono.lean @@ -13,6 +13,7 @@ public import Mathlib.GroupTheory.QuotientGroup.Defs /-! # Monomorphisms and epimorphisms in `Group` + In this file, we prove monomorphisms in the category of groups are injective homomorphisms and epimorphisms are surjective homomorphisms. -/ diff --git a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean index de9b7f189934c7..96073610f7a15f 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean @@ -12,8 +12,8 @@ public import Mathlib.CategoryTheory.Limits.Filtered public import Mathlib.Topology.Sheaves.Stalks /-! - # Module structure on stalks + Let `M` be a presheaf of `R`-modules on a topological space. We endow `M.presheaf.stalk x` with an `R.stalk x`-module structure. diff --git a/Mathlib/Algebra/EuclideanDomain/Field.lean b/Mathlib/Algebra/EuclideanDomain/Field.lean index 3ba135fab0f1ae..4d0ea217367aac 100644 --- a/Mathlib/Algebra/EuclideanDomain/Field.lean +++ b/Mathlib/Algebra/EuclideanDomain/Field.lean @@ -11,6 +11,7 @@ public import Mathlib.Algebra.GroupWithZero.Units.Basic /-! # Instances for Euclidean domains + * `Field.toEuclideanDomain`: shows that any field is a Euclidean domain. -/ diff --git a/Mathlib/Algebra/EuclideanDomain/Int.lean b/Mathlib/Algebra/EuclideanDomain/Int.lean index 18b3e76133fd71..578e1b6d52a3c3 100644 --- a/Mathlib/Algebra/EuclideanDomain/Int.lean +++ b/Mathlib/Algebra/EuclideanDomain/Int.lean @@ -12,6 +12,7 @@ public import Mathlib.Algebra.Ring.Int.Defs /-! # Instances for Euclidean domains + * `Int.euclideanDomain`: shows that `ℤ` is a Euclidean domain. -/ diff --git a/Mathlib/Algebra/Homology/Opposite.lean b/Mathlib/Algebra/Homology/Opposite.lean index ede453bfc5cf30..f839402d2fa9bc 100644 --- a/Mathlib/Algebra/Homology/Opposite.lean +++ b/Mathlib/Algebra/Homology/Opposite.lean @@ -13,6 +13,7 @@ public import Mathlib.Algebra.Homology.QuasiIso /-! # Opposite categories of complexes + Given a preadditive category `V`, the opposite of its category of chain complexes is equivalent to the category of cochain complexes of objects in `Vᵒᵖ`. We define this equivalence, and another analogous equivalence (for a general category of homological complexes with a general diff --git a/Mathlib/Algebra/Lie/Cochain.lean b/Mathlib/Algebra/Lie/Cochain.lean index d31d324d5838a4..4370193d343ebc 100644 --- a/Mathlib/Algebra/Lie/Cochain.lean +++ b/Mathlib/Algebra/Lie/Cochain.lean @@ -9,6 +9,7 @@ public import Mathlib.Algebra.Lie.Abelian /-! # Lie algebra cohomology in low degree + This file defines low degree cochains of Lie algebras with coefficients given by a module. They are useful in the construction of central extensions, so we treat these easier cases separately from the general theory of Lie algebra cohomology. diff --git a/Mathlib/Algebra/Lie/Extension.lean b/Mathlib/Algebra/Lie/Extension.lean index d4de489559e2ba..54f1fa462d7f6a 100644 --- a/Mathlib/Algebra/Lie/Extension.lean +++ b/Mathlib/Algebra/Lie/Extension.lean @@ -10,6 +10,7 @@ public import Mathlib.Algebra.Lie.Cochain /-! # Extensions of Lie algebras + This file defines extensions of Lie algebras, given by short exact sequences of Lie algebra homomorphisms. They are implemented in two ways: `IsExtension` is a `Prop`-valued class taking two homomorphisms as parameters, and `Extension` is a structure that includes the middle Lie algebra. diff --git a/Mathlib/Algebra/Lie/Loop.lean b/Mathlib/Algebra/Lie/Loop.lean index cf87330901b7ed..071293eeccbd6a 100644 --- a/Mathlib/Algebra/Lie/Loop.lean +++ b/Mathlib/Algebra/Lie/Loop.lean @@ -12,6 +12,7 @@ public import Mathlib.Algebra.Polynomial.Laurent /-! # Loop Lie algebras and their central extensions + Given a Lie algebra `L`, the loop algebra is the Lie algebra of maps from a circle into `L`. This can mean many different things, e.g., continuous maps, smooth maps, polynomial maps. In this file, we consider the simplest case of polynomial maps, meaning we take a base change with the ring of diff --git a/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean b/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean index c62c2e40b5261a..ca705f9ea50a82 100644 --- a/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean +++ b/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean @@ -10,6 +10,7 @@ public import Mathlib.Data.Finset.SMulAntidiagonal /-! # Scalar multiplication by (additive) monoid rings on formal functions. + Given sets `G` and `P`, with a left-cancellative scalar-multiplication (or vector-addition) of `G` on `P`, together with a module `V` over a semiring `R`, we define a convolution action of the monoid algebra `R[G]` on the set of functions `P → V`. diff --git a/Mathlib/Algebra/Order/AddTorsor.lean b/Mathlib/Algebra/Order/AddTorsor.lean index edd40c9ab230b6..18392fee332b1b 100644 --- a/Mathlib/Algebra/Order/AddTorsor.lean +++ b/Mathlib/Algebra/Order/AddTorsor.lean @@ -10,6 +10,7 @@ public import Mathlib.Algebra.Order.Monoid.Defs /-! # Ordered scalar multiplication and vector addition + This file defines ordered scalar multiplication and vector addition, and proves some properties. In the additive case, a motivating example is given by the additive action of `ℤ` on subsets of reals that are closed under integer translation. The order compatibility allows for a treatment of diff --git a/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean b/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean index c4158ac10aa9e8..61be60c432d313 100644 --- a/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean +++ b/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean @@ -14,6 +14,7 @@ public import Mathlib.SetTheory.Cardinal.Finite /-! # Cardinality and limit of sum of indicators + This file contains results relating the cardinality of subsets of ℕ and limits, limsups of sums of indicators. diff --git a/Mathlib/Algebra/Squarefree/Basic.lean b/Mathlib/Algebra/Squarefree/Basic.lean index 79091abbce8d52..af8d698b23388d 100644 --- a/Mathlib/Algebra/Squarefree/Basic.lean +++ b/Mathlib/Algebra/Squarefree/Basic.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.UniqueFactorizationDomain.Multiplicity /-! # Squarefree elements of monoids + An element of a monoid is squarefree when it is not divisible by any squares except the squares of units. diff --git a/Mathlib/Algebra/Vertex/HVertexOperator.lean b/Mathlib/Algebra/Vertex/HVertexOperator.lean index f997c5f9059696..4573070993920c 100644 --- a/Mathlib/Algebra/Vertex/HVertexOperator.lean +++ b/Mathlib/Algebra/Vertex/HVertexOperator.lean @@ -9,6 +9,7 @@ public import Mathlib.RingTheory.HahnSeries.Multiplication /-! # Vertex operators + In this file we introduce heterogeneous vertex operators using Hahn series. When `R = ℂ`, `V = W`, and `Γ = ℤ`, then this is the usual notion of "meromorphic left-moving 2D field". The notion we use here allows us to consider composites and scalar-multiply by multivariable Laurent series. diff --git a/Mathlib/Algebra/Vertex/VertexOperator.lean b/Mathlib/Algebra/Vertex/VertexOperator.lean index 2edd8712cec5fd..635dcc0682f0a4 100644 --- a/Mathlib/Algebra/Vertex/VertexOperator.lean +++ b/Mathlib/Algebra/Vertex/VertexOperator.lean @@ -10,6 +10,7 @@ public import Mathlib.Data.Int.Interval /-! # Vertex operators + In this file we introduce vertex operators as linear maps to Laurent series. ## Definitions diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean index 210b35e6d26059..42bd9e368c72b8 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean @@ -12,6 +12,7 @@ public import Mathlib.Topology.Homotopy.Product /-! # Fundamental groupoid preserves products + In this file, we give the following definitions/theorems: - `FundamentalGroupoidFunctor.piIso` An isomorphism between Π i, (π Xᵢ) and π (Πi, Xᵢ), whose diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean index 568422865c68c9..55c5697d31858a 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean @@ -13,6 +13,7 @@ public import Mathlib.AlgebraicTopology.FundamentalGroupoid.PUnit /-! # Simply connected spaces + This file defines simply connected spaces. A topological space is simply connected if its fundamental groupoid is equivalent to `Unit`. diff --git a/Mathlib/Analysis/Analytic/RadiusLiminf.lean b/Mathlib/Analysis/Analytic/RadiusLiminf.lean index caed24f310e47f..ccc2f2d675757f 100644 --- a/Mathlib/Analysis/Analytic/RadiusLiminf.lean +++ b/Mathlib/Analysis/Analytic/RadiusLiminf.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal /-! # Representation of `FormalMultilinearSeries.radius` as a `liminf` + In this file we prove that the radius of convergence of a `FormalMultilinearSeries` is equal to $\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. This lemma can't go to `Analysis.Analytic.Basic` because this would create a circular dependency once we redefine `exp` using diff --git a/Mathlib/Analysis/Normed/Affine/Convex.lean b/Mathlib/Analysis/Normed/Affine/Convex.lean index 301069917cad6a..16bebba8cb4ea2 100644 --- a/Mathlib/Analysis/Normed/Affine/Convex.lean +++ b/Mathlib/Analysis/Normed/Affine/Convex.lean @@ -12,6 +12,7 @@ public import Mathlib.Analysis.Normed.Module.Convex /-! # Simplices in normed affine spaces + We prove the following facts: * `exists_mem_interior_convexHull_affineBasis` : We can intercalate a simplex between a point and diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 7da73c0fdbdcec..c82470b0c99e0b 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -12,6 +12,7 @@ public import Mathlib.Analysis.Normed.Lp.ProdLp /-! # `L^p` distance on finite products of metric spaces + Given finitely many metric spaces, one can put the max distance on their product, but there is also a whole family of natural distances, indexed by a parameter `p : ℝ≥0∞`, that also induce the product topology. We define them in this file. For `0 < p < ∞`, the distance on `Π i, α i` diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index c48b16bc11de1b..46c7a52ff50c8a 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.Normed.Lp.WithLp /-! # `L^p` distance on products of two metric spaces + Given two metric spaces, one can put the max distance on their product, but there is also a whole family of natural distances, indexed by a parameter `p : ℝ≥0∞`, that also induce the product topology. We define them in this file. For `0 < p < ∞`, the distance on `α × β` diff --git a/Mathlib/Analysis/Normed/Unbundled/SeminormFromBounded.lean b/Mathlib/Analysis/Normed/Unbundled/SeminormFromBounded.lean index f9928117449d40..2c06c768cb8bc9 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SeminormFromBounded.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SeminormFromBounded.lean @@ -9,6 +9,7 @@ public import Mathlib.Analysis.Normed.Unbundled.RingSeminorm /-! # seminormFromBounded + In this file, we prove [BGR, Proposition 1.2.1/2][bosch-guntzer-remmert] : given a nonzero additive group seminorm on a commutative ring `R` such that for some `c : ℝ` and every `x y : R`, the inequality `f (x * y) ≤ c * f x * f y)` is satisfied, we create a ring seminorm on `R`. diff --git a/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean b/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean index b6c8e7970aadac..9e515e621bb23f 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean @@ -14,6 +14,7 @@ public import Mathlib.Topology.Algebra.Order.LiminfLimsup /-! # smoothingSeminorm + In this file, we prove [BGR, Proposition 1.3.2/1][bosch-guntzer-remmert]: if `μ` is a nonarchimedean seminorm on a commutative ring `R`, then `iInf (fun (n : PNat), (μ(x ^ (n : ℕ))) ^ (1 / (n : ℝ)))` is a power-multiplicative nonarchimedean diff --git a/Mathlib/CategoryTheory/DinatTrans.lean b/Mathlib/CategoryTheory/DinatTrans.lean index 1924ec1fe102c7..4a3d5405a4a801 100644 --- a/Mathlib/CategoryTheory/DinatTrans.lean +++ b/Mathlib/CategoryTheory/DinatTrans.lean @@ -9,6 +9,7 @@ public import Mathlib.CategoryTheory.Opposites /-! # Dinatural transformations + Dinatural transformations are special kinds of transformations between functors `F G : Cᵒᵖ ⥤ C ⥤ D` which depend both covariantly and contravariantly on the same category (also known as difunctors). diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean index ba98dbaaf5d1d6..6e746297d1eeca 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean @@ -10,6 +10,7 @@ public import Mathlib.CategoryTheory.Filtered.Basic /-! # Preservation of filtered colimits and cofiltered limits. + Typically forgetful functors from algebraic categories preserve filtered colimits (although not general colimits). See e.g. `Mathlib/Algebra/Category/MonCat/FilteredColimits.lean`. diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean index d1cc9b3eb0f9bc..e2e5e749c297f5 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean @@ -9,6 +9,7 @@ public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.PullbackCone /-! # HasPullback + `HasPullback f g` and `pullback f g` provides API for `HasLimit` and `limit` in the case of pullbacks. diff --git a/Mathlib/CategoryTheory/PathCategory/Basic.lean b/Mathlib/CategoryTheory/PathCategory/Basic.lean index ad3b72ce3b1c92..335601a33bc996 100644 --- a/Mathlib/CategoryTheory/PathCategory/Basic.lean +++ b/Mathlib/CategoryTheory/PathCategory/Basic.lean @@ -9,6 +9,7 @@ public import Mathlib.CategoryTheory.Quotient /-! # The category paths on a quiver. + When `C` is a quiver, `paths C` is the category of paths. ## When the quiver is itself a category diff --git a/Mathlib/CategoryTheory/Preadditive/Schur.lean b/Mathlib/CategoryTheory/Preadditive/Schur.lean index 254cf45acf2c65..4b32d29f7232e4 100644 --- a/Mathlib/CategoryTheory/Preadditive/Schur.lean +++ b/Mathlib/CategoryTheory/Preadditive/Schur.lean @@ -13,6 +13,7 @@ public import Mathlib.FieldTheory.IsAlgClosed.Spectrum /-! # Schur's lemma + We first prove the part of Schur's Lemma that holds in any preadditive category with kernels, that any nonzero morphism between simple objects is an isomorphism. diff --git a/Mathlib/CategoryTheory/Sites/Abelian.lean b/Mathlib/CategoryTheory/Sites/Abelian.lean index 4eb95550cd3161..d5250edfc56c2d 100644 --- a/Mathlib/CategoryTheory/Sites/Abelian.lean +++ b/Mathlib/CategoryTheory/Sites/Abelian.lean @@ -11,6 +11,7 @@ public import Mathlib.CategoryTheory.Sites.ConstantSheaf /-! # Category of sheaves is abelian + Let `C, D` be categories and `J` be a Grothendieck topology on `C`, when `D` is abelian and sheafification is possible in `C`, `Sheaf J D` is abelian as well (`sheafIsAbelian`). diff --git a/Mathlib/CategoryTheory/Sites/LeftExact.lean b/Mathlib/CategoryTheory/Sites/LeftExact.lean index e44d4e52fd62da..2b595f5006ae30 100644 --- a/Mathlib/CategoryTheory/Sites/LeftExact.lean +++ b/Mathlib/CategoryTheory/Sites/LeftExact.lean @@ -12,6 +12,7 @@ public import Mathlib.CategoryTheory.Sites.ConcreteSheafification /-! # Left exactness of sheafification + In this file we show that sheafification commutes with finite limits. -/ diff --git a/Mathlib/CategoryTheory/Thin.lean b/Mathlib/CategoryTheory/Thin.lean index bcdb471330e201..5a37064b6da206 100644 --- a/Mathlib/CategoryTheory/Thin.lean +++ b/Mathlib/CategoryTheory/Thin.lean @@ -9,6 +9,7 @@ public import Mathlib.CategoryTheory.Functor.Category /-! # Thin categories + A thin category (also known as a sparse category) is a category with at most one morphism between each pair of objects. Examples include posets, but also some indexing categories (diagrams) for special shapes of diff --git a/Mathlib/Combinatorics/Configuration.lean b/Mathlib/Combinatorics/Configuration.lean index 2b1f5a6ad5d985..051a7cb6b3de49 100644 --- a/Mathlib/Combinatorics/Configuration.lean +++ b/Mathlib/Combinatorics/Configuration.lean @@ -11,6 +11,7 @@ public import Mathlib.LinearAlgebra.Projectivization.Constructions /-! # Configurations of Points and lines + This file introduces abstract configurations of points and lines, and proves some basic properties. ## Main definitions diff --git a/Mathlib/Data/Bracket.lean b/Mathlib/Data/Bracket.lean index 1468d018300c55..f7a0dc76ffe27a 100644 --- a/Mathlib/Data/Bracket.lean +++ b/Mathlib/Data/Bracket.lean @@ -9,6 +9,7 @@ public import Mathlib.Init /-! # Bracket Notation + This file provides notation which can be used for the Lie bracket, for the commutator of two subgroups, and for other similar operations. diff --git a/Mathlib/Data/Bundle.lean b/Mathlib/Data/Bundle.lean index 55c2b8f33e0929..d5e4ee0e06bc92 100644 --- a/Mathlib/Data/Bundle.lean +++ b/Mathlib/Data/Bundle.lean @@ -9,6 +9,7 @@ public import Mathlib.Data.Set.Basic /-! # Bundle + Basic data structure to implement fiber bundles, vector bundles (maybe fibrations?), etc. This file should contain all possible results that do not involve any topology. diff --git a/Mathlib/Data/Finsupp/BigOperators.lean b/Mathlib/Data/Finsupp/BigOperators.lean index c05a5d5fee340e..686b4a2f52a53a 100644 --- a/Mathlib/Data/Finsupp/BigOperators.lean +++ b/Mathlib/Data/Finsupp/BigOperators.lean @@ -10,8 +10,8 @@ public import Mathlib.Algebra.Group.Finsupp public import Mathlib.Data.Finset.Pairwise /-! - # Sums of collections of Finsupp, and their support + This file provides results about the `Finsupp.support` of sums of collections of `Finsupp`, including sums of `List`, `Multiset`, and `Finset`. diff --git a/Mathlib/Data/Nat/Squarefree.lean b/Mathlib/Data/Nat/Squarefree.lean index f856139103cf4a..5fd20e08fc8cfd 100644 --- a/Mathlib/Data/Nat/Squarefree.lean +++ b/Mathlib/Data/Nat/Squarefree.lean @@ -13,6 +13,7 @@ public import Mathlib.RingTheory.UniqueFactorizationDomain.Nat /-! # Lemmas about squarefreeness of natural numbers + A number is squarefree when it is not divisible by any squares except the squares of units. ## Main Results diff --git a/Mathlib/Data/PSigma/Order.lean b/Mathlib/Data/PSigma/Order.lean index d1f28e41cd256b..7a68fb944536a1 100644 --- a/Mathlib/Data/PSigma/Order.lean +++ b/Mathlib/Data/PSigma/Order.lean @@ -14,6 +14,7 @@ public import Mathlib.Order.Lex /-! # Lexicographic order on a sigma type + This file defines the lexicographic order on `Σₗ' i, α i`. `a` is less than `b` if its summand is strictly less than the summand of `b` or they are in the same summand and `a` is less than `b` there. diff --git a/Mathlib/Data/SProd.lean b/Mathlib/Data/SProd.lean index d18a913698b421..e69e918107300b 100644 --- a/Mathlib/Data/SProd.lean +++ b/Mathlib/Data/SProd.lean @@ -9,6 +9,7 @@ public import Mathlib.Tactic.FBinop /-! # Set Product Notation + This file provides notation for a product of sets, and other similar types. ## Main Definitions diff --git a/Mathlib/Data/Set/Enumerate.lean b/Mathlib/Data/Set/Enumerate.lean index 8784e9c8ee2bc8..ba8b7a5df130d1 100644 --- a/Mathlib/Data/Set/Enumerate.lean +++ b/Mathlib/Data/Set/Enumerate.lean @@ -11,6 +11,7 @@ public import Mathlib.Data.Set.Insert /-! # Set enumeration + This file allows enumeration of sets given a choice function. The definition does not assume `sel` actually is a choice function, i.e. `sel s ∈ s` and `sel s = none ↔ s = ∅`. These assumptions are added to the lemmas needing them. diff --git a/Mathlib/Data/Set/UnionLift.lean b/Mathlib/Data/Set/UnionLift.lean index 297bbe7e714ed3..85d18856b04edf 100644 --- a/Mathlib/Data/Set/UnionLift.lean +++ b/Mathlib/Data/Set/UnionLift.lean @@ -10,6 +10,7 @@ public import Mathlib.Order.Directed /-! # Union lift + This file defines `Set.iUnionLift` to glue together functions defined on each of a collection of sets to make a function on the Union of those sets. diff --git a/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean index 57ebe6ab8a6807..346c6c706000b4 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean @@ -11,6 +11,7 @@ public import Mathlib.Dynamics.TopologicalEntropy.DynamicalEntourage /-! # Topological entropy via covers + We implement Bowen-Dinaburg's definitions of the topological entropy, via covers. All is stated in the vocabulary of uniform spaces. For compact spaces, the uniform structure diff --git a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean index b466bb29c842c9..853778648ef964 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean @@ -9,6 +9,7 @@ public import Mathlib.Dynamics.TopologicalEntropy.CoverEntropy /-! # Topological entropy via nets + We implement Bowen-Dinaburg's definitions of the topological entropy, via nets. The major design decisions are the same as in diff --git a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean index 2dda7201c9e185..5ab181c92b7d3c 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean @@ -9,6 +9,7 @@ public import Mathlib.Dynamics.TopologicalEntropy.CoverEntropy /-! # Topological entropy of the image of a set under a semiconjugacy + Consider two dynamical systems `(X, S)` and `(Y, T)` together with a semiconjugacy `φ`: diff --git a/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean b/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean index 4b327f1accb048..cbd35a8c1442d5 100644 --- a/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean +++ b/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean @@ -15,6 +15,7 @@ import Mathlib.RingTheory.Valuation.IsTrivialOn /-! # Generalities on the polynomial structure of rational functions + * Main evaluation properties * Study of the X-adic valuation diff --git a/Mathlib/Geometry/Manifold/Algebra/Monoid.lean b/Mathlib/Geometry/Manifold/Algebra/Monoid.lean index fd7802b4573944..46a6e8ae92fe01 100644 --- a/Mathlib/Geometry/Manifold/Algebra/Monoid.lean +++ b/Mathlib/Geometry/Manifold/Algebra/Monoid.lean @@ -11,6 +11,7 @@ public import Mathlib.Geometry.Manifold.MFDeriv.Basic /-! # `C^n` monoid + A `C^n` monoid is a monoid that is also a `C^n` manifold, in which multiplication is a `C^n` map of the product manifold `G` × `G` into `G`. diff --git a/Mathlib/Geometry/Manifold/Diffeomorph.lean b/Mathlib/Geometry/Manifold/Diffeomorph.lean index f99ed00f458dd2..8aec58763bbdb0 100644 --- a/Mathlib/Geometry/Manifold/Diffeomorph.lean +++ b/Mathlib/Geometry/Manifold/Diffeomorph.lean @@ -10,6 +10,7 @@ public import Mathlib.Geometry.Manifold.MFDeriv.UniqueDifferential /-! # Diffeomorphisms + This file implements diffeomorphisms. ## Definitions diff --git a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean index 6673d261c8b031..08e68119c83dde 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean @@ -13,6 +13,7 @@ import Mathlib.Analysis.LocallyConvex.Separation /-! # Interior and boundary of a manifold + Define the interior and boundary of a manifold. ## Main definitions diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index d77c56889a52fb..bb35843efbde61 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -13,6 +13,7 @@ public import Mathlib.Tactic.Qify /-! # Commuting Probability + This file introduces the commuting probability of finite groups. ## Main definitions diff --git a/Mathlib/LinearAlgebra/Multilinear/Curry.lean b/Mathlib/LinearAlgebra/Multilinear/Curry.lean index c4c1768e87dc5c..6b7e3551c8a396 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Curry.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Curry.lean @@ -10,6 +10,7 @@ public import Mathlib.LinearAlgebra.Multilinear.Basic /-! # Currying of multilinear maps + We register isomorphisms corresponding to currying or uncurrying variables, transforming a multilinear function `f` on `n+1` variables into a linear function taking values in multilinear functions in `n` variables, and into a multilinear function in `n` variables taking values in linear diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/CanonicalBilinear.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/CanonicalBilinear.lean index 59047ee9a4c205..80834459fb174b 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/CanonicalBilinear.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/CanonicalBilinear.lean @@ -10,6 +10,7 @@ public import Mathlib.LinearAlgebra.RootSystem.RootPositive /-! # The canonical bilinear form on a finite root pairing + Given a finite root pairing, we define a canonical map from weight space to coweight space, and the corresponding bilinear form. This form is symmetric and Weyl-invariant, and if the base ring is linearly ordered, then the form is root-positive, positive-semidefinite on the weight space, and diff --git a/Mathlib/LinearAlgebra/RootSystem/Hom.lean b/Mathlib/LinearAlgebra/RootSystem/Hom.lean index 6f2f01644153eb..8bf34ac72f09d8 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Hom.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Hom.lean @@ -10,6 +10,7 @@ public import Mathlib.LinearAlgebra.RootSystem.Defs /-! # Morphisms of root pairings + This file defines morphisms of root pairings, following the definition of morphisms of root data given in SGA III Exp. 21 Section 6. diff --git a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean index ef492ed032e12a..e2474956fc6557 100644 --- a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean +++ b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean @@ -9,6 +9,7 @@ public import Mathlib.LinearAlgebra.RootSystem.Defs /-! # Root pairings made from bilinear forms + A common construction of root systems is given by taking the set of all vectors in an integral lattice for which reflection yields an automorphism of the lattice. In this file, we generalize this construction, replacing the ring of integers with an arbitrary commutative ring and the diff --git a/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean b/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean index db462a0ecddf90..0360126e568c25 100644 --- a/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean +++ b/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean @@ -10,6 +10,7 @@ public import Mathlib.CategoryTheory.Category.Basic /-! # The category of root pairings + This file defines the category of root pairings, following the definition of category of root data given in SGA III Exp. 21 Section 6. diff --git a/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean b/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean index c794d873bf0dad..62346e7cdc23b3 100644 --- a/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean +++ b/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean @@ -10,6 +10,7 @@ public import Mathlib.RepresentationTheory.Basic /-! # The Weyl group of a root pairing + This file defines the Weyl group of a root pairing as the subgroup of automorphisms generated by reflection automorphisms. This deviates from the existing literature, which typically defines the Weyl group as the subgroup of linear transformations of the weight space generated by linear diff --git a/Mathlib/Logic/Lemmas.lean b/Mathlib/Logic/Lemmas.lean index 0266bda809af21..0957d6c7208bcd 100644 --- a/Mathlib/Logic/Lemmas.lean +++ b/Mathlib/Logic/Lemmas.lean @@ -12,6 +12,7 @@ public import Mathlib.Tactic.Tauto /-! # More basic logic properties + A few more logic lemmas. These are in their own file, rather than `Logic.Basic`, because it is convenient to be able to use the `tauto` or `split_ifs` tactics. diff --git a/Mathlib/MeasureTheory/Function/EssSup.lean b/Mathlib/MeasureTheory/Function/EssSup.lean index 042866c1a7e53f..62d7b80de3e784 100644 --- a/Mathlib/MeasureTheory/Function/EssSup.lean +++ b/Mathlib/MeasureTheory/Function/EssSup.lean @@ -10,6 +10,7 @@ public import Mathlib.Probability.UniformOn /-! # Essential supremum and infimum + We define the essential supremum and infimum of a function `f : α → β` with respect to a measure `μ` on `α`. The essential supremum is the infimum of the constants `c : β` such that `f x ≤ c` almost everywhere. diff --git a/Mathlib/MeasureTheory/Group/Prod.lean b/Mathlib/MeasureTheory/Group/Prod.lean index c26346b3c3955a..f5676f16cc5dd7 100644 --- a/Mathlib/MeasureTheory/Group/Prod.lean +++ b/Mathlib/MeasureTheory/Group/Prod.lean @@ -9,6 +9,7 @@ public import Mathlib.MeasureTheory.Group.Measure /-! # Measure theory in the product of groups + In this file we show properties about measure theory in products of measurable groups and properties of iterated integrals in measurable groups. diff --git a/Mathlib/ModelTheory/PartialEquiv.lean b/Mathlib/ModelTheory/PartialEquiv.lean index 972b174ab5080c..c3aa3c1e79dc8b 100644 --- a/Mathlib/ModelTheory/PartialEquiv.lean +++ b/Mathlib/ModelTheory/PartialEquiv.lean @@ -10,6 +10,7 @@ public import Mathlib.Order.Ideal /-! # Partial Isomorphisms + This file defines partial isomorphisms between first-order structures. ## Main Definitions diff --git a/Mathlib/NumberTheory/ClassNumber/AdmissibleAbs.lean b/Mathlib/NumberTheory/ClassNumber/AdmissibleAbs.lean index d8552bc6d3a10c..9462819c2bd446 100644 --- a/Mathlib/NumberTheory/ClassNumber/AdmissibleAbs.lean +++ b/Mathlib/NumberTheory/ClassNumber/AdmissibleAbs.lean @@ -11,6 +11,7 @@ public import Mathlib.NumberTheory.ClassNumber.AdmissibleAbsoluteValue /-! # Admissible absolute value on the integers + This file defines an admissible absolute value `AbsoluteValue.absIsAdmissible` which we use to show the class number of the ring of integers of a number field is finite. diff --git a/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean b/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean index 681bb81828ef4f..9bb6058a90ae1f 100644 --- a/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean +++ b/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean @@ -11,6 +11,7 @@ public import Mathlib.Algebra.Order.AbsoluteValue.Euclidean /-! # Admissible absolute values + This file defines a structure `AbsoluteValue.IsAdmissible` which we use to show the class number of the ring of integers of a global field is finite. diff --git a/Mathlib/NumberTheory/ClassNumber/Finite.lean b/Mathlib/NumberTheory/ClassNumber/Finite.lean index 09e640cfb8fd15..2c77f086215cd8 100644 --- a/Mathlib/NumberTheory/ClassNumber/Finite.lean +++ b/Mathlib/NumberTheory/ClassNumber/Finite.lean @@ -15,6 +15,7 @@ public import Mathlib.RingTheory.Norm.Basic /-! # Class numbers of global fields + In this file, we use the notion of "admissible absolute value" to prove finiteness of the class group for number fields and function fields. diff --git a/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean b/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean index afbbbb7152d1ea..21e681b2319ffd 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean @@ -11,6 +11,7 @@ public import Mathlib.NumberTheory.NumberField.Discriminant.Defs /-! # Discriminant of cyclotomic fields + We compute the discriminant of a `p ^ n`-th cyclotomic extension. ## Main results diff --git a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean index fa7216ad7b0435..39cdd13911878b 100644 --- a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean +++ b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean @@ -17,6 +17,7 @@ public import Mathlib.RingTheory.SimpleModule.Basic /-! # Primitive roots in cyclotomic fields + If `IsCyclotomicExtension {n} A B`, we define an element `zeta n A B : B` that is a primitive `n`th-root of unity in `B` and we study its properties. We also prove related theorems under the more general assumption of just being a primitive root, for reasons described in the implementation diff --git a/Mathlib/NumberTheory/FLT/Four.lean b/Mathlib/NumberTheory/FLT/Four.lean index ecaa9ad5254fa0..6f17dfbc8a98a0 100644 --- a/Mathlib/NumberTheory/FLT/Four.lean +++ b/Mathlib/NumberTheory/FLT/Four.lean @@ -13,6 +13,7 @@ public import Mathlib.Tactic.LinearCombination /-! # Fermat's Last Theorem for the case n = 4 + There are no non-zero integers `a`, `b` and `c` such that `a ^ 4 + b ^ 4 = c ^ 4`. -/ diff --git a/Mathlib/NumberTheory/FLT/Three.lean b/Mathlib/NumberTheory/FLT/Three.lean index 711bf57d10cf26..80e14f9531a959 100644 --- a/Mathlib/NumberTheory/FLT/Three.lean +++ b/Mathlib/NumberTheory/FLT/Three.lean @@ -13,6 +13,7 @@ public import Mathlib.Algebra.Ring.Divisibility.Lemmas /-! # Fermat Last Theorem in the case `n = 3` + The goal of this file is to prove Fermat's Last Theorem in the case `n = 3`. ## Main results diff --git a/Mathlib/NumberTheory/NumberField/Basic.lean b/Mathlib/NumberTheory/NumberField/Basic.lean index c9e3ddec84ca4b..250a8d6db21c0b 100644 --- a/Mathlib/NumberTheory/NumberField/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Basic.lean @@ -13,6 +13,7 @@ public import Mathlib.RingTheory.DedekindDomain.IntegralClosure /-! # Number fields + This file defines a number field and the ring of integers corresponding to it. ## Main definitions diff --git a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean index 32dfaa31d15c60..4241695e4ee78e 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean @@ -18,6 +18,7 @@ import Mathlib.Algebra.FiniteSupport.Basic /-! # Finite places of number fields + This file defines finite places of a number field `K` as absolute values coming from an embedding into a completion of `K` associated to a non-zero prime ideal of `𝓞 K`. diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index bbe59167a2159f..e177981d40d19d 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -14,6 +14,7 @@ public import Mathlib.RingTheory.Prime /-! # Ring of integers of cyclotomic fields + We gather results about cyclotomic extensions of `ℚ`. In particular, we compute the ring of integers of a cyclotomic extension of `ℚ`. diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Embeddings.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Embeddings.lean index da237c16e2618c..ef93768b70ba99 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Embeddings.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Embeddings.lean @@ -10,6 +10,7 @@ public import Mathlib.NumberTheory.NumberField.InfinitePlace.TotallyRealComplex /-! # Cyclotomic extensions of `ℚ` are totally complex number fields. + We prove that cyclotomic extensions of `ℚ` are totally complex, meaning that `NrRealPlaces K = 0` if `IsCyclotomicExtension {n} ℚ K` and `2 < n`. diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/PID.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/PID.lean index 78d7a5298fd7f1..69f3a4c6633b1f 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/PID.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/PID.lean @@ -11,6 +11,7 @@ public import Mathlib.NumberTheory.NumberField.Cyclotomic.Embeddings /-! # Cyclotomic fields whose ring of integers is a PID. + We prove that `ℤ [ζₚ]` is a PID for specific values of `p`. The result holds for `p ≤ 19`, but the proof is more and more involved. diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean index c352aef3079703..6f903bf65bab97 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.Fintype /-! # Third Cyclotomic Field + We gather various results about the third cyclotomic field. The following notations are used in this file: `K` is a number field such that `IsCyclotomicExtension {3} ℚ K`, `ζ` is any primitive `3`-rd root of unity in `K`, `η` is the element in the units of the ring of integers corresponding to `ζ` diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean index d144b529ff71ee..b07cdf0a60b849 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean @@ -15,6 +15,7 @@ public import Mathlib.Analysis.SpecialFunctions.Log.Base /-! # Number field discriminant + This file defines the discriminant of a number field. ## Main result diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean index 202534b3bb135d..505f6e860e994c 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean @@ -10,6 +10,7 @@ public import Mathlib.RingTheory.Localization.NormTrace /-! # Number field discriminant + This file defines the discriminant of a number field. ## Main definitions diff --git a/Mathlib/NumberTheory/NumberField/EquivReindex.lean b/Mathlib/NumberTheory/NumberField/EquivReindex.lean index c2ac127cc3b9b0..1eaf27e1199dea 100644 --- a/Mathlib/NumberTheory/NumberField/EquivReindex.lean +++ b/Mathlib/NumberTheory/NumberField/EquivReindex.lean @@ -8,8 +8,8 @@ module public import Mathlib.NumberTheory.NumberField.CanonicalEmbedding.Basic /-! - # Reindexed basis + This file introduces an equivalence between the set of embeddings of `K` into `ℂ` and the index set of the chosen basis of the ring of integers of `K`. diff --git a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean index b811fa5699d1d3..35f327d8b447ed 100644 --- a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean +++ b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean @@ -13,6 +13,7 @@ public import Mathlib.RingTheory.Unramified.Dedekind /-! # Every number field has a ramified prime over `ℚ` + ...except `ℚ` itself. This is a trivial corollary of `NumberField.not_dvd_discr_iff_forall_mem` and diff --git a/Mathlib/NumberTheory/NumberField/House.lean b/Mathlib/NumberTheory/NumberField/House.lean index 403ac21e762d0f..7c54a42afb9a35 100644 --- a/Mathlib/NumberTheory/NumberField/House.lean +++ b/Mathlib/NumberTheory/NumberField/House.lean @@ -10,8 +10,8 @@ public import Mathlib.NumberTheory.NumberField.CanonicalEmbedding.Basic public import Mathlib.NumberTheory.NumberField.EquivReindex /-! - # House of an algebraic number + This file defines the house of an algebraic number `α`, which is the largest of the modulus of its conjugates. diff --git a/Mathlib/NumberTheory/NumberField/Norm.lean b/Mathlib/NumberTheory/NumberField/Norm.lean index 5b6a741f521008..5df13dd08fc944 100644 --- a/Mathlib/NumberTheory/NumberField/Norm.lean +++ b/Mathlib/NumberTheory/NumberField/Norm.lean @@ -11,6 +11,7 @@ public import Mathlib.RingTheory.Norm.Transitivity /-! # Norm in number fields + Given a finite extension of number fields, we define the norm morphism as a function between the rings of integers. diff --git a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean index d39044e1cfc65e..c9a4d626332a35 100644 --- a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean +++ b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean @@ -12,6 +12,7 @@ public import Mathlib.NumberTheory.NumberField.Units.Basic /-! # Dirichlet theorem on the group of units of a number field + This file is devoted to the proof of Dirichlet unit theorem that states that the group of units `(𝓞 K)ˣ` of units of the ring of integers `𝓞 K` of a number field `K` modulo its torsion subgroup is a free `ℤ`-module of rank `card (InfinitePlace K) - 1`. diff --git a/Mathlib/Order/Bounded.lean b/Mathlib/Order/Bounded.lean index f051832f17f380..53310a06b47475 100644 --- a/Mathlib/Order/Bounded.lean +++ b/Mathlib/Order/Bounded.lean @@ -11,6 +11,7 @@ public import Mathlib.Order.Bounds.Defs /-! # Bounded and unbounded sets + We prove miscellaneous lemmas about bounded and unbounded sets. Many of these are just variations on the same ideas, or similar results with a few minor differences. The file is divided into these different general ideas. diff --git a/Mathlib/Probability/Distributions/Uniform.lean b/Mathlib/Probability/Distributions/Uniform.lean index ba27e336293991..ccf3e23c43c6fe 100644 --- a/Mathlib/Probability/Distributions/Uniform.lean +++ b/Mathlib/Probability/Distributions/Uniform.lean @@ -11,6 +11,7 @@ public import Mathlib.Probability.ProbabilityMassFunction.Constructions /-! # Uniform distributions and probability mass functions + This file defines two related notions of uniform distributions, which will be unified in the future. ## Uniform distributions diff --git a/Mathlib/RepresentationTheory/Rep/Res.lean b/Mathlib/RepresentationTheory/Rep/Res.lean index 387fa047a261c6..284c9079d71112 100644 --- a/Mathlib/RepresentationTheory/Rep/Res.lean +++ b/Mathlib/RepresentationTheory/Rep/Res.lean @@ -9,6 +9,7 @@ public import Mathlib.RepresentationTheory.Rep.Basic /-! # Restriction of representations + Given a group homomorphism `f : H →* G`, we have the restriction functor `resFunctor f : Rep k G ⥤ Rep k H` which sends a `G`-representation `ρ` to the `H`-representation `ρ.comp f`. diff --git a/Mathlib/RingTheory/AdicCompletion/RingHom.lean b/Mathlib/RingTheory/AdicCompletion/RingHom.lean index 29a6258f804c40..a2fe215427b9c7 100644 --- a/Mathlib/RingTheory/AdicCompletion/RingHom.lean +++ b/Mathlib/RingTheory/AdicCompletion/RingHom.lean @@ -9,6 +9,7 @@ public import Mathlib.RingTheory.AdicCompletion.Algebra /-! # Lift of ring homomorphisms to adic completions + Let `R`, `S` be rings, `I` be an ideal of `S`. In this file we prove that a compatible family of ring homomorphisms from a ring `R` to `S ⧸ I ^ n` can be lifted to a ring homomorphism `R →+* AdicCompletion I S`. diff --git a/Mathlib/RingTheory/Conductor.lean b/Mathlib/RingTheory/Conductor.lean index 69273c05b667de..e858142535f2eb 100644 --- a/Mathlib/RingTheory/Conductor.lean +++ b/Mathlib/RingTheory/Conductor.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.PowerBasis /-! # The conductor ideal + This file defines the conductor ideal of an element `x` of `R`-algebra `S`. This is the ideal of `S` consisting of all elements `a` such that for all `b` in `S`, the product `a * b` lies in the `R`-subalgebra of `S` generated by `x`. diff --git a/Mathlib/RingTheory/Coprime/Lemmas.lean b/Mathlib/RingTheory/Coprime/Lemmas.lean index 438852e8a02a2e..6f47cd085daf75 100644 --- a/Mathlib/RingTheory/Coprime/Lemmas.lean +++ b/Mathlib/RingTheory/Coprime/Lemmas.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.Coprime.Basic /-! # Additional lemmas about elements of a ring satisfying `IsCoprime` + and elements of a monoid satisfying `IsRelPrime` These lemmas are in a separate file to the definition of `IsCoprime` or `IsRelPrime` diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index 52ceddba6f60ca..f3cb0b5d1c25ae 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -15,6 +15,7 @@ public import Mathlib.RingTheory.Valuation.Discrete.Basic /-! # Adic valuations on Dedekind domains + Given a Dedekind domain `R` of Krull dimension 1 and a maximal ideal `v` of `R`, we define the `v`-adic valuation on `R` and its extension to the field of fractions `K` of `R`. We prove several properties of this valuation, including the existence of uniformizers. diff --git a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean index 98386a33a30df8..7f5ce30facd4e0 100644 --- a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean +++ b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean @@ -12,6 +12,7 @@ public import Mathlib.Topology.Algebra.RestrictedProduct.Units /-! # The finite adèle ring of a Dedekind domain + We define the ring of finite adèles of a Dedekind domain `R`. ## Main definitions diff --git a/Mathlib/RingTheory/DedekindDomain/Instances.lean b/Mathlib/RingTheory/DedekindDomain/Instances.lean index 982a7cf3602f09..87a52e52b08453 100644 --- a/Mathlib/RingTheory/DedekindDomain/Instances.lean +++ b/Mathlib/RingTheory/DedekindDomain/Instances.lean @@ -11,6 +11,7 @@ public import Mathlib.RingTheory.RingHom.Finite /-! # Instances for Dedekind domains + This file contains various instances to work with localization of a ring extension. A very common situation in number theory is to have an extension of (say) Dedekind domains `R` and diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index 3980046d3b6e78..7bd4bb28ae90f8 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -16,6 +16,7 @@ public import Mathlib.Tactic.FastInstance /-! # Additive properties of Hahn series + If `Γ` is ordered and `R` has zero, then `R⟦Γ⟧` consists of formal series over `Γ` with coefficients in `R`, whose supports are partially well-ordered. With further structure on `R` and `Γ`, we can add further structure on `R⟦Γ⟧`. When `R` has an addition operation, `R⟦Γ⟧` also has addition by adding diff --git a/Mathlib/RingTheory/HahnSeries/Binomial.lean b/Mathlib/RingTheory/HahnSeries/Binomial.lean index 46ec61006315cc..dbdb40cbe67f5d 100644 --- a/Mathlib/RingTheory/HahnSeries/Binomial.lean +++ b/Mathlib/RingTheory/HahnSeries/Binomial.lean @@ -10,6 +10,7 @@ public import Mathlib.RingTheory.PowerSeries.Binomial /-! # Binomial expansions of powers of Hahn Series + We introduce binomial expansions using `embDomain`. ## Main Definitions diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index f5c2ba2c1e6c99..fe2d366daab26a 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -15,6 +15,7 @@ public import Mathlib.RingTheory.HahnSeries.Addition /-! # Multiplicative properties of Hahn series + If `Γ` is ordered and `R` has zero, then `R⟦Γ⟧` consists of formal series over `Γ` with coefficients in `R`, whose supports are partially well-ordered. This module introduces multiplication and scalar multiplication on Hahn series. If `Γ` is an ordered cancellative diff --git a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean index 38e71a494b1d20..a5bb85af445c40 100644 --- a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean +++ b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean @@ -12,6 +12,7 @@ public import Mathlib.Data.Finsupp.PWO /-! # Comparison between Hahn series and power series + If `Γ` is ordered and `R` has zero, then `R⟦Γ⟧` consists of formal series over `Γ` with coefficients in `R`, whose supports are partially well-ordered. With further structure on `R` and `Γ`, we can add further structure on `R⟦Γ⟧`. When `R` is a semiring and `Γ = ℕ`, then diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 7894e2b75bb025..1816db6f432fe3 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -11,6 +11,7 @@ public import Mathlib.Data.Rat.Cast.Lemmas /-! # Summable families of Hahn Series + We introduce a notion of formal summability for families of Hahn series, and define a formal sum function. This theory is applied to characterize invertible Hahn series whose coefficients are in a commutative domain. diff --git a/Mathlib/RingTheory/NoetherNormalization.lean b/Mathlib/RingTheory/NoetherNormalization.lean index c3ffd0befae1f6..c30969e30f41e9 100644 --- a/Mathlib/RingTheory/NoetherNormalization.lean +++ b/Mathlib/RingTheory/NoetherNormalization.lean @@ -10,6 +10,7 @@ public import Mathlib.Data.List.Indexes public import Mathlib.RingTheory.IntegralClosure.IsIntegralClosure.Basic /-! # Noether normalization lemma + This file contains a proof by Nagata of the Noether normalization lemma. ## Main Results diff --git a/Mathlib/RingTheory/Nullstellensatz.lean b/Mathlib/RingTheory/Nullstellensatz.lean index 104ec198650cdd..34fd73c572fca6 100644 --- a/Mathlib/RingTheory/Nullstellensatz.lean +++ b/Mathlib/RingTheory/Nullstellensatz.lean @@ -11,6 +11,7 @@ public import Mathlib.RingTheory.Spectrum.Prime.Basic /-! # Nullstellensatz + This file establishes a version of Hilbert's classical Nullstellensatz for `MvPolynomial`s. The main statement of the theorem is `MvPolynomial.vanishingIdeal_zeroLocus_eq_radical`. diff --git a/Mathlib/RingTheory/Perfectoid/FontaineTheta.lean b/Mathlib/RingTheory/Perfectoid/FontaineTheta.lean index 03f25093599e07..98f4f4b1358bf5 100644 --- a/Mathlib/RingTheory/Perfectoid/FontaineTheta.lean +++ b/Mathlib/RingTheory/Perfectoid/FontaineTheta.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.WittVector.TeichmullerSeries /-! # Fontaine's θ map + In this file, we define Fontaine's `θ` map, which is a ring homomorphism from the Witt vector `𝕎 R♭` of the tilt of a perfectoid ring `R` to `R` itself. Our definition of `θ` does not require that `R` is perfectoid in the first place. diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean index 6214c9b651a270..9e7bea20b4441b 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean @@ -13,6 +13,7 @@ public import Mathlib.Analysis.Complex.Arg /-! # Evaluating cyclotomic polynomials + This file states some results about evaluating cyclotomic polynomials in various different ways. ## Main definitions diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/Basic.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/Basic.lean index ae2a68d66e31c3..6245e18877a991 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/Basic.lean @@ -11,6 +11,7 @@ public import Mathlib.RingTheory.Polynomial.ScaleRoots /-! # Eisenstein polynomials + Given an ideal `𝓟` of a commutative semiring `R`, we say that a polynomial `f : R[X]` is *Eisenstein at `𝓟`* if `f.leadingCoeff ∉ 𝓟`, `∀ n, n < f.natDegree → f.coeff n ∈ 𝓟` and `f.coeff 0 ∉ 𝓟 ^ 2`. In this file we gather miscellaneous results about Eisenstein polynomials. diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean index 68d0a280a013c0..c8a0f9e6b53d1f 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean @@ -12,6 +12,7 @@ public import Mathlib.RingTheory.Polynomial.Cyclotomic.Expand /-! # Eisenstein polynomials + In this file we gather more miscellaneous results about Eisenstein polynomials ## Main results diff --git a/Mathlib/RingTheory/Polynomial/GaussNorm.lean b/Mathlib/RingTheory/Polynomial/GaussNorm.lean index 04250ee856e304..4b6d9d9f6afa1a 100644 --- a/Mathlib/RingTheory/Polynomial/GaussNorm.lean +++ b/Mathlib/RingTheory/Polynomial/GaussNorm.lean @@ -10,6 +10,7 @@ public import Mathlib.RingTheory.PowerSeries.GaussNorm /-! # Gauss norm for polynomials + This file defines the Gauss norm for polynomials. Given a polynomial `p` in `R[X]`, a function `v : R → ℝ` and a real number `c`, the Gauss norm is defined as the supremum of the set of all values of `v (p.coeff i) * c ^ i` for all `i` in the support of `p`. diff --git a/Mathlib/RingTheory/PowerSeries/Binomial.lean b/Mathlib/RingTheory/PowerSeries/Binomial.lean index ef0f975ab87e94..d6ed9c2db77f59 100644 --- a/Mathlib/RingTheory/PowerSeries/Binomial.lean +++ b/Mathlib/RingTheory/PowerSeries/Binomial.lean @@ -11,6 +11,7 @@ public import Mathlib.Tactic.SuppressCompilation /-! # Binomial Power Series + We introduce formal power series of the form `(1 + X) ^ r`, where `r` is an element of a commutative binomial ring `R`. diff --git a/Mathlib/RingTheory/PowerSeries/GaussNorm.lean b/Mathlib/RingTheory/PowerSeries/GaussNorm.lean index b62a12ac78d3e8..7c2192ae7391c3 100644 --- a/Mathlib/RingTheory/PowerSeries/GaussNorm.lean +++ b/Mathlib/RingTheory/PowerSeries/GaussNorm.lean @@ -11,6 +11,7 @@ public import Mathlib.RingTheory.MvPowerSeries.GaussNorm /-! # Gauss norm for power series + This file defines the Gauss norm for power series using the gaussNorm for multivariate power series. Given a power series `f` in `R⟦X⟧`, a function `v : R → ℝ` and a real number `c`, the Gauss norm is defined as the supremum of the set of all values of `v (f.coeff i) * c ^ i` for all `i : ℕ`. diff --git a/Mathlib/RingTheory/Prime.lean b/Mathlib/RingTheory/Prime.lean index d738fa082bb8bd..44dbde483bb308 100644 --- a/Mathlib/RingTheory/Prime.lean +++ b/Mathlib/RingTheory/Prime.lean @@ -13,6 +13,7 @@ public import Mathlib.Algebra.BigOperators.Group.Finset.Basic /-! # Prime elements in rings + This file contains lemmas about prime elements of commutative rings. -/ diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean index eab91759c51dd9..d71c4fdea1e966 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean @@ -9,6 +9,7 @@ public import Mathlib.RingTheory.ClassGroup.Basic /-! # The class group of a Unique Factorization Domain is trivial + This file proves that the ideal class group of a Normalized GCD Domain is trivial. The main application is to Unique Factorization Domains, which are known to be Normalized GCD Domains. diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index a01cf768db41cd..638cb205531b08 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -11,6 +11,7 @@ public import Mathlib.Tactic.Ring.RingNF /-! # The `algebra` tactic + A suite of three tactics for solving equations in commutative algebras over commutative (semi)rings, where the exponents can also contain variables. diff --git a/Mathlib/Tactic/ApplyWith.lean b/Mathlib/Tactic/ApplyWith.lean index c0a6fd2370523e..d5845ff1618f8f 100644 --- a/Mathlib/Tactic/ApplyWith.lean +++ b/Mathlib/Tactic/ApplyWith.lean @@ -12,6 +12,7 @@ public meta import Lean.Elab.ConfigEval /-! # The `applyWith` tactic + The `applyWith` tactic is like `apply`, but allows passing a custom configuration to the underlying `apply` operation. -/ diff --git a/Mathlib/Tactic/Choose.lean b/Mathlib/Tactic/Choose.lean index 83a4547af5ff6f..7575ea37b1f770 100644 --- a/Mathlib/Tactic/Choose.lean +++ b/Mathlib/Tactic/Choose.lean @@ -9,6 +9,7 @@ public import Mathlib.Logic.Function.Basic /-! # `choose` tactic + Performs Skolemization, that is, given `h : ∀ a:α, ∃ b:β, p a b |- G` produces `f : α → β, hf: ∀ a, p a (f a) |- G`. diff --git a/Mathlib/Tactic/ExistsI.lean b/Mathlib/Tactic/ExistsI.lean index 0b988ef9d731a2..c2e9e49a513c80 100644 --- a/Mathlib/Tactic/ExistsI.lean +++ b/Mathlib/Tactic/ExistsI.lean @@ -8,6 +8,7 @@ module public import Mathlib.Init /-! # The `existsi` tactic + This file defines the `existsi` tactic: its purpose is to instantiate existential quantifiers. Internally, it applies the `refine` tactic. -/ diff --git a/Mathlib/Tactic/Linter/ValidatePRTitle.lean b/Mathlib/Tactic/Linter/ValidatePRTitle.lean index 29db84c14bc984..2c3bc34f5aabb4 100644 --- a/Mathlib/Tactic/Linter/ValidatePRTitle.lean +++ b/Mathlib/Tactic/Linter/ValidatePRTitle.lean @@ -11,6 +11,7 @@ import Mathlib.Tactic.Linter.TextBased.UnicodeLinter /-! # Checker for well-formed title and labels + This script checks if a PR title matches [mathlib's commit conventions](https://leanprover-community.github.io/contribute/commit.html). Not all checks from the commit conventions are implemented: for instance, no effort is made to diff --git a/Mathlib/Tactic/Rename.lean b/Mathlib/Tactic/Rename.lean index 8fed33ca313a27..638721ead3adcc 100644 --- a/Mathlib/Tactic/Rename.lean +++ b/Mathlib/Tactic/Rename.lean @@ -10,6 +10,7 @@ public import Mathlib.Init /-! # The `rename'` tactic + The `rename'` tactic renames one or several hypotheses. -/ diff --git a/Mathlib/Topology/Sheaves/Abelian.lean b/Mathlib/Topology/Sheaves/Abelian.lean index 4b6fd98bf3aefd..7a9b0d10e6652d 100644 --- a/Mathlib/Topology/Sheaves/Abelian.lean +++ b/Mathlib/Topology/Sheaves/Abelian.lean @@ -13,6 +13,7 @@ public import Mathlib.Topology.Sheaves.Skyscraper /-! # Sheaves over Abelian categories + We provide instances for categories of sheaves over Abelian categories. ## Main Results From 765274a7959afcd210149efc10b904d71bc2edcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:51:35 +0000 Subject: [PATCH 0548/1300] feat(CategoryTheory/Limits): definition of weighted limits (#41163) This PR defines weighted limits (in the non enriched situation). This is an adaptation of code from https://github.com/joelriou/reedy in order to allow uses both for Reedy categories and applications to hypercovers #41125. Co-authored-by: Yun Liu --- Mathlib.lean | 1 + .../Limits/Weighted/HasWeightedLimit.lean | 254 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean diff --git a/Mathlib.lean b/Mathlib.lean index b096679913bdd1..abe373aae11031 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2998,6 +2998,7 @@ public import Mathlib.CategoryTheory.Limits.WeakLimits.Basic public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakEqualizers public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakKernels public import Mathlib.CategoryTheory.Limits.WeakLimits.WeakPullbacks +public import Mathlib.CategoryTheory.Limits.Weighted.HasWeightedLimit public import Mathlib.CategoryTheory.Limits.Yoneda public import Mathlib.CategoryTheory.Linear.Basic public import Mathlib.CategoryTheory.Linear.FunctorCategory diff --git a/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean b/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean new file mode 100644 index 00000000000000..d5a8ae9fbe39b0 --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean @@ -0,0 +1,254 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou, Yun Liu, Christian Merten, Robin Carlier +-/ +module + +public import Mathlib.CategoryTheory.Elements +public import Mathlib.CategoryTheory.Limits.HasLimits + +/-! +# Weighted limits + +In this file, we define weighted limits (in the non enriched case). +Given a weight `W : J ⥤ Type w` and a functor `F : J ⥤ C`, +the `W`-weighted limit of `J` is the limit of the functor +`CategoryOfElements.π W ⋙ F : W.Elements ⥤ C`. + +## References +* https://ncatlab.org/nlab/show/weighted+limit + +-/ + +@[expose] public section + +universe w v u v' u' + +namespace CategoryTheory + +open Limits Opposite + +namespace Limits + +variable {J : Type u} [Category.{v} J] {C : Type u'} [Category.{v'} C] + +/-- Given `W : J ⥤ Type w` and `F : J ⥤ C`, this is the type of cones for +the functor `CategoryOfElements.π W ⋙ F : W.Elements ⥤ C`. -/ +abbrev WeightedCone (W : J ⥤ Type w) (F : J ⥤ C) := + Cone (CategoryOfElements.π W ⋙ F) + +/-- Given a weight `W : J ⥤ Type w` and `F : J ⥤ C`, we say that +the `W`-weighted limit of `F` exists if the functor +`CategoryOfElements.π W ⋙ F : W.Elements ⥤ C` has a limit. -/ +abbrev HasWeightedLimit (W : J ⥤ Type w) (F : J ⥤ C) : Prop := + HasLimit (CategoryOfElements.π W ⋙ F) + +namespace WeightedCone + +variable {W : J ⥤ Type w} {F : J ⥤ C} + +/-- The projection `c.pt ⟶ F.obj j` for `c : WeightedCone W F` +and `x : W.obj j`. -/ +protected abbrev π (c : WeightedCone W F) {j : J} (x : W.obj j) : + c.pt ⟶ F.obj j := + (Cone.π c).app (Functor.elementsMk _ _ x) + +@[reassoc (attr := simp)] +protected lemma w (c : WeightedCone W F) {i j : J} (x : W.obj i) (f : i ⟶ j) : + c.π x ≫ F.map f = c.π (W.map f x) := + Cone.w c (CategoryOfElements.homMk (Functor.elementsMk _ _ x) + (Functor.elementsMk _ _ (W.map f x)) f rfl) + +variable (pt : C) (π : ∀ ⦃j : J⦄ (_ : W.obj j), pt ⟶ F.obj j) + (hπ : ∀ ⦃j₁ j₂ : J⦄ (x : W.obj j₁) (f : j₁ ⟶ j₂), + π x ≫ F.map f = π (W.map f x)) + +set_option backward.defeqAttrib.useBackward true in +/-- Constructor for weighted cones. -/ +@[simps pt] +def mk : WeightedCone W F where + pt := pt + π.app x := π x.snd + π.naturality x₁ x₂ f := by simpa using (hπ x₁.snd f.val).symm + +@[simp] +lemma mk_π {j : J} (x : W.obj j) : + (mk pt π hπ).π x = π x := rfl + +/-- A weighted cone `c : WeightedCone W F` is a limit if it is so +as a cone of `CategoryOfElements.π W ⋙ F : W.Elements ⥤ C`. -/ +protected abbrev IsLimit (c : WeightedCone W F) := Limits.IsLimit c + +namespace IsLimit + +variable {c : WeightedCone W F} (hc : c.IsLimit) {Z : C} + +include hc in +lemma hasWeightedLimit : HasWeightedLimit W F := ⟨_, hc⟩ + +section + +variable + (π : ∀ ⦃j : J⦄ (_ : W.obj j), Z ⟶ F.obj j) + (hπ : ∀ ⦃j₁ j₂ : J⦄ (x : W.obj j₁) (f : j₁ ⟶ j₂), + π x ≫ F.map f = π (W.map f x)) + +/-- Constructor for morphisms from the point of a limit weighted cone. -/ +def lift : Z ⟶ c.pt := + Limits.IsLimit.lift hc (WeightedCone.mk Z π hπ) + +@[reassoc (attr := simp)] +lemma fac {j : J} (x : W.obj j) : + hc.lift π hπ ≫ c.π x = π x := + Limits.IsLimit.fac hc (WeightedCone.mk Z π hπ) (Functor.elementsMk _ _ x) + +end + +include hc in +lemma hom_ext {f g : Z ⟶ c.pt} (h : ∀ {j : J} (x : W.obj j), f ≫ c.π x = g ≫ c.π x) : + f = g := + Limits.IsLimit.hom_ext hc (fun _ ↦ h _) + +end IsLimit + +open Opposite in +set_option backward.defeqAttrib.useBackward true in +/-- If the weight is `coyoneda.obj (op j) : J ⥤ Type _`, this is the limit +weighted cone for `F : J ⥤ C` with point `F.obj j`. -/ +@[simps] +protected abbrev coyoneda (F : J ⥤ C) (j : J) : + WeightedCone (coyoneda.obj (op j)) F where + pt := F.obj j + π.app u := F.map u.snd + π.naturality _ _ f := by simp [← Functor.map_comp, Category.id_comp, f.prop.symm] + +set_option backward.defeqAttrib.useBackward true in +/-- The weighted limit of `F` for the weight `coyoneda.obj (op j)` is `F.obj j`. -/ +def isLimitCoyoneda (F : J ⥤ C) (j : J) : (WeightedCone.coyoneda F j).IsLimit where + lift s := WeightedCone.π s (𝟙 j) + fac s x := by + simpa using s.w (CategoryOfElements.homMk (Functor.elementsMk _ j (𝟙 j)) x x.snd (by simp)) + uniq s m hm := by + simpa using hm (Functor.elementsMk _ j (𝟙 j)) + +end WeightedCone + +end Limits + +namespace Functor + +section + +variable {J : Type u} [Category.{v} J] {C : Type u'} [Category.{v'} C] + (W W' W'' : J ⥤ Type w) (g : W ⟶ W') (g' : W' ⟶ W'') (F : J ⥤ C) + [HasWeightedLimit W F] [HasWeightedLimit W' F] [HasWeightedLimit W'' F] + +/-- Given a weight `W : J ⥤ Type w` and `F : J ⥤ C`, this is the `W`-weighted +limit of `F`. -/ +noncomputable def weightedLimObjObj : C := + limit (CategoryOfElements.π W ⋙ F) + +/-- The projections from the weighted limit. -/ +@[no_expose] +noncomputable def weightedLimObjObjπ ⦃j : J⦄ (x : W.obj j) : + W.weightedLimObjObj F ⟶ F.obj j := + limit.π (CategoryOfElements.π W ⋙ F) (Functor.elementsMk _ _ x) + +@[reassoc (attr := simp)] +lemma weightedLimObjObj_w ⦃j₁ j₂ : J⦄ (x : W.obj j₁) + (f : j₁ ⟶ j₂) : + W.weightedLimObjObjπ F x ≫ F.map f = + W.weightedLimObjObjπ F (W.map f x) := + limit.w (CategoryOfElements.π W ⋙ F) + (CategoryOfElements.homMk (Functor.elementsMk _ _ x) (Functor.elementsMk _ _ + (W.map f x)) f rfl) + +/-- A choice of limit weighted cone. -/ +noncomputable abbrev weightedLimCone : + WeightedCone W F := + WeightedCone.mk (W.weightedLimObjObj F) + (fun j x ↦ W.weightedLimObjObjπ F x) + (fun j₁ j₂ x f ↦ by simp) + +/-- The weighted cone `W.weightedLimCone F` is a limit. -/ +@[no_expose] +noncomputable def isLimitWeightedLimCone : + (W.weightedLimCone F).IsLimit := + limit.isLimit _ + +@[reassoc (attr := simp)] +lemma isLimitWeightedLimCone_fac {Z} (π) (hπ) ⦃j : J⦄ (x : W.obj j) : + (W.isLimitWeightedLimCone F).lift (Z := Z) π hπ ≫ W.weightedLimObjObjπ F x = π x := + (W.isLimitWeightedLimCone F).fac .. + +variable {W F} in +@[ext] +lemma weightedLimObjObj.hom_ext {Z : C} {f g : Z ⟶ W.weightedLimObjObj F} + (h : ∀ {j : J} (x : W.obj j), + f ≫ W.weightedLimObjObjπ F x = g ≫ W.weightedLimObjObjπ F x) : + f = g := + (W.isLimitWeightedLimCone F).hom_ext h + +/-- Functoriality of the weighted limits with fixed weight `W : J ⥤ Type w` +with respect to the functor in `J ⥤ C`. -/ +@[no_expose] +noncomputable def weightedLimObjMap {F₁ F₂ : J ⥤ C} + [HasWeightedLimit W F₁] [HasWeightedLimit W F₂] (f : F₁ ⟶ F₂) : + W.weightedLimObjObj F₁ ⟶ W.weightedLimObjObj F₂ := + limMap (whiskerLeft _ f) + +@[reassoc (attr := simp)] +lemma weightedLimObjMap_π {F₁ F₂ : J ⥤ C} + [HasWeightedLimit W F₁] [HasWeightedLimit W F₂] (f : F₁ ⟶ F₂) + ⦃j : J⦄ (x : W.obj j) : + W.weightedLimObjMap f ≫ W.weightedLimObjObjπ F₂ x = + W.weightedLimObjObjπ F₁ x ≫ f.app j := + limit.lift_π .. + +@[simp] +lemma weightedLimObjMap_id (F : J ⥤ C) [HasWeightedLimit W F] : + W.weightedLimObjMap (𝟙 F) = 𝟙 _ := by + cat_disch + +@[reassoc] +lemma weightedLimObjMap_comp {F₁ F₂ F₃ : J ⥤ C} + [HasWeightedLimit W F₁] [HasWeightedLimit W F₂] [HasWeightedLimit W F₃] + (f : F₁ ⟶ F₂) (g : F₂ ⟶ F₃) : + W.weightedLimObjMap (f ≫ g) = W.weightedLimObjMap f ≫ W.weightedLimObjMap g := by + cat_disch + +section + +variable {W W' W''} + +/-- The (contravariant) functoriality of weighted limits with respect to the weight. -/ +noncomputable def weightedLimFlipObjMap : + W'.weightedLimObjObj F ⟶ W.weightedLimObjObj F := + (W.isLimitWeightedLimCone F).lift + (fun j x ↦ W'.weightedLimObjObjπ F (g.app j x)) (by simp) + +@[reassoc (attr := simp)] +lemma weightedLimObjObjMap_π ⦃j : J⦄ (x : W.obj j) : + weightedLimFlipObjMap g F ≫ W.weightedLimObjObjπ F x = + W'.weightedLimObjObjπ F (g.app j x) := + (W.isLimitWeightedLimCone F).fac .. + +@[simp] +lemma weightedLimFlipObjMap_id : + weightedLimFlipObjMap (𝟙 W) F = 𝟙 _ := by + cat_disch + +@[reassoc] +lemma weightedLimFlipObjMap_comp : + weightedLimFlipObjMap g' F ≫ weightedLimFlipObjMap g F = + weightedLimFlipObjMap (g ≫ g') F := by + cat_disch + +end + +end + +end Functor + +end CategoryTheory From 8f5331973a3e2b3cc5fd307208f456ccd6d3b467 Mon Sep 17 00:00:00 2001 From: Suzuka Yu <109365723+Yu-Misaka@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:51:38 +0000 Subject: [PATCH 0549/1300] chore(RepresentationTheory/Character): golf some results in FDRep (#41278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Greetings! This PR comes with four major parts: 1. ~I golfed the following results using their analogue for `Representation`: ...~ reverted due to defeq abuse. 2. I changed instance `Invertible (Fintype.card G : k)` to `Invertible (Nat.card G : k)` in: - `FDRep.average_char_eq_finrank_invariants` - `FDRep.scalar_product_char_eq_finrank_equivariant` - `FDRep.char_orthonormal` 3. I changed `⅟↑(Fintype.card G) •` to `(Nat.card G : k)⁻¹ *` in: - `FDRep.average_char_eq_finrank_invariants` - `FDRep.scalar_product_char_eq_finrank_equivariant` - `FDRep.char_orthonormal` 4. Some typos in docstring are fixed. No.2 and No.3 are to make the statements align better with those in `Representation`, and to golf `FDRep.simple_iff_char_is_norm_one`. --- Mathlib/RepresentationTheory/Character.lean | 26 ++++++++++--------- .../FinGroupCharZero.lean | 24 +++++------------ 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/Mathlib/RepresentationTheory/Character.lean b/Mathlib/RepresentationTheory/Character.lean index 795db39cd34eaf..768f3d7f3dd200 100644 --- a/Mathlib/RepresentationTheory/Character.lean +++ b/Mathlib/RepresentationTheory/Character.lean @@ -27,7 +27,7 @@ Irreducible representations are implemented categorically, using the `CategoryTh defined in `Mathlib/CategoryTheory/Simple.lean` ## TODO -* Once we have the monoidal closed structure on `FdRep k G` and a better API for the rigid +* Once we have the monoidal closed structure on `FDRep k G` and a better API for the rigid structure, `char_dual` and `char_linHom` should probably be stated in terms of `Vᘁ` and `ihom V W`. -/ @@ -108,7 +108,7 @@ theorem card_inv_mul_sum_char_eq_finrank : simp [character, GroupAlgebra.average, _root_.map_sum] /-- -If `V` are `W` are finite-dimensional representations of a finite group, then the +If `V` and `W` are finite-dimensional representations of a finite group, then the scalar product of their characters is equal to the dimension of the space of equivariant maps from `V` to `W`. -/ @@ -194,28 +194,30 @@ theorem char_linHom (V W : FDRep k G) (g : G) : (of (linHom V.ρ W.ρ)).character g = V.character g⁻¹ * W.character g := by rw [← char_iso (dualTensorIsoLinHom _ _), char_tensor, Pi.mul_apply, char_dual] -variable [Fintype G] [Invertible (Fintype.card G : k)] +variable [Fintype G] [Invertible (Nat.card G : k)] theorem average_char_eq_finrank_invariants (V : FDRep k G) : - ⅟(Fintype.card G : k) • ∑ g : G, V.character g = finrank k (invariants V.ρ) := by + (Nat.card G : k)⁻¹ * ∑ g : G, V.character g = finrank k (invariants V.ρ) := by + have : Invertible (Fintype.card G : k) := by + rwa [Fintype.card_eq_nat_card] rw [← (isProj_averageMap V.ρ).trace] simp [character, GroupAlgebra.average, _root_.map_sum] /-- -If `V` are `W` are finite-dimensional representations of a finite group, then the +If `V` and `W` are finite-dimensional representations of a finite group, then the scalar product of their characters is equal to the dimension of the space of equivariant maps from `V` to `W`. -/ theorem scalar_product_char_eq_finrank_equivariant (V W : FDRep k G) : - ⅟(Fintype.card G : k) • ∑ g : G, W.character g * V.character g⁻¹ = + (Nat.card G : k)⁻¹ * ∑ g : G, W.character g * V.character g⁻¹ = Module.finrank k (V ⟶ W) := by conv_lhs => congr; rfl; congr; rfl; intro _; rw [mul_comm, ← FDRep.char_linHom] -- The scalar product is the character of `Hom(V, W).` rw [FDRep.average_char_eq_finrank_invariants, ← LinearEquiv.finrank_eq (Representation.linHom.invariantsEquivFDRepHom V W), of_ρ'] -- The average over the group of the character of a representation equals the dimension of the - -- space of invariants, and the space of invariants of `Hom(W, V)` is the subspace of - --`G`-equivariant linear maps, `Hom_G(W, V)`. + -- space of invariants, and the space of invariants of `Hom(V, W)` is the subspace of + -- `G`-equivariant linear maps, `Hom_G(V, W)`. end Group @@ -223,19 +225,19 @@ section Orthogonality variable {G : Type v} [Group G] [IsAlgClosed k] -variable [Fintype G] [Invertible (Fintype.card G : k)] +variable [Fintype G] [Invertible (Nat.card G : k)] open scoped Classical in /-- Orthogonality of characters for irreducible representations of finite group over an algebraically closed field whose characteristic doesn't divide the order of the group. -/ theorem char_orthonormal (V W : FDRep k G) [Simple V] [Simple W] : - ⅟(Fintype.card G : k) • ∑ g : G, V.character g * W.character g⁻¹ = + (Nat.card G : k)⁻¹ * ∑ g : G, V.character g * W.character g⁻¹ = if Nonempty (V ≅ W) then ↑1 else ↑0 := by rw [scalar_product_char_eq_finrank_equivariant] - -- The scalar products of the characters is equal to the dimension of the space of + -- The scalar product of the characters is equal to the dimension of the space of -- equivariant maps `W ⟶ V`. rw_mod_cast [finrank_hom_simple_simple W V, Iso.nonempty_iso_symm] - -- By Schur's Lemma, the dimension of `Hom_G(W, V)` is `1` is `V ≅ W` and `0` otherwise. + -- By Schur's Lemma, the dimension of `Hom_G(W, V)` is `1` if `V ≅ W` and `0` otherwise. end Orthogonality diff --git a/Mathlib/RepresentationTheory/FinGroupCharZero.lean b/Mathlib/RepresentationTheory/FinGroupCharZero.lean index 9cacfc1a33730d..6191fee0b4a04b 100644 --- a/Mathlib/RepresentationTheory/FinGroupCharZero.lean +++ b/Mathlib/RepresentationTheory/FinGroupCharZero.lean @@ -119,24 +119,12 @@ If `G` is finite and `k` an algebraically closed field of characteristic `0`, then an object of `FDRep k G` is simple if and only if its character has norm `1`. -/ lemma simple_iff_char_is_norm_one [CharZero k] [Fintype G] (V : FDRep k G) : - Simple V ↔ ∑ g : G, V.character g * V.character g⁻¹ = Nat.card G where - mp h := by - have := invertibleOfNonzero (NeZero.ne (Nat.card G : k)) - have := invertibleOfNonzero (NeZero.ne (Fintype.card G : k)) - classical - have : ⅟(Nat.card G : k) • ∑ g, V.character g * V.character g⁻¹ = 1 := by - simpa only [Nonempty.intro (Iso.refl V), ↓reduceIte, Fintype.card_eq_nat_card] - using char_orthonormal V V - apply_fun (· * (Fintype.card G : k)) at this - rwa [mul_comm, ← smul_eq_mul, smul_smul, Fintype.card_eq_nat_card, mul_invOf_self, smul_eq_mul, - one_mul, one_mul] at this - mpr h := by - have := invertibleOfNonzero (NeZero.ne (Fintype.card G : k)) - have := invertibleOfNonzero (NeZero.ne (Nat.card G : k)) - have eq := FDRep.scalar_product_char_eq_finrank_equivariant V V - rw [h] at eq - simp only [invOf_eq_inv, smul_eq_mul, inv_mul_cancel_of_invertible, Fintype.card_eq_nat_card] - at eq + Simple V ↔ ∑ g : G, V.character g * V.character g⁻¹ = Nat.card G := by + have := invertibleOfNonzero (NeZero.ne (Nat.card G : k)) + constructor <;> intro h + · symm; simpa [Nonempty.intro (Iso.refl V), inv_mul_eq_one₀] using char_orthonormal V V + · have eq := V.scalar_product_char_eq_finrank_equivariant V + rw [h, inv_mul_cancel_of_invertible] at eq rw [simple_iff_end_is_rank_one, ← Nat.cast_inj (R := k), ← eq, Nat.cast_one] end FDRep From 52846449a4fa62c105e3af4a11b4c375b23c1645 Mon Sep 17 00:00:00 2001 From: Sabrina Jewson <58880148+SabrinaJewson@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:44:04 +0000 Subject: [PATCH 0550/1300] =?UTF-8?q?refactor(Order/OrdContinuous):=20rede?= =?UTF-8?q?fine=20left=20and=20right=20order=20continuity=20to=20not=20req?= =?UTF-8?q?uire=20preserving=20=E2=8A=A5/=E2=8A=A4=20(#37682)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `LeftOrdContinuous` currently requires that `f ⊥ = ⊥`, but this means that many functions that are perhaps intuitively left-continuous (like `f x = x + 1` on `ℝ≥0`) are not. In particular, this change means that functions between conditionally complete lattices are `LeftOrdContinuous` iff they are monotone and topologically left continuous (see `MonotoneOn.map_csSup_of_continuousWithinAt` for the reverse direction). If one wants the concept that existed before, one can either accept the `f ⊥ = ⊥` hypothesis separately or, if the function is between complete lattices, use the left side of a `GaloisConnection` (which is equivalent, although I think this is not yet in Mathlib). `LeftOrdContinuous.continuousWithinAt_Iic` is rewritten to accomodate these changes; the superfluous `DenselyOrdered` assumption is also removed. [Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/LeftOrdContinuous.20requires.20f.28.E2.8A.A5.29.20.3D.20.E2.8A.A5/near/582932491) Co-authored-by: Zhao Yuyang 赵雨扬 Co-authored-by: SabrinaJewson --- Mathlib/Order/OrdContinuous.lean | 43 +++++++++++++++++-------------- Mathlib/Order/SemiconjSup.lean | 4 +-- Mathlib/Topology/Order/Basic.lean | 22 +++++++++++----- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/Mathlib/Order/OrdContinuous.lean b/Mathlib/Order/OrdContinuous.lean index e9ba9f618c3f10..2c7ab0a6024db4 100644 --- a/Mathlib/Order/OrdContinuous.lean +++ b/Mathlib/Order/OrdContinuous.lean @@ -34,15 +34,15 @@ open Function OrderDual Set -/ -/-- A function `f` between preorders is left order continuous if it preserves all suprema. We -define it using `IsLUB` instead of `sSup` so that the proof works both for complete lattices and -conditionally complete lattices. -/ +/-- A function `f` between preorders is left order continuous if it preserves all suprema of +nonempty sets. We define it using `IsLUB` instead of `sSup` so that the proof works both for +complete lattices and conditionally complete lattices. -/ @[to_dual -/-- A function `f` between preorders is right order continuous if it preserves all infima. We -define it using `IsGLB` instead of `sInf` so that the proof works both for complete lattices and -conditionally complete lattices. -/] +/-- A function `f` between preorders is right order continuous if it preserves all infima of +nonempty sets. We define it using `IsGLB` instead of `sInf` so that the proof works both for +complete lattices and conditionally complete lattices. -/] def LeftOrdContinuous [Preorder α] [Preorder β] (f : α → β) := - ∀ ⦃s : Set α⦄ ⦃x⦄, IsLUB s x → IsLUB (f '' s) (f x) + ∀ ⦃s : Set α⦄ ⦃x⦄, s.Nonempty → IsLUB s x → IsLUB (f '' s) (f x) namespace LeftOrdContinuous @@ -51,7 +51,7 @@ section Preorder variable (α) [Preorder α] [Preorder β] [Preorder γ] {g : β → γ} {f : α → β} @[to_dual] -protected theorem id : LeftOrdContinuous (id : α → α) := fun s x h => by +protected theorem id : LeftOrdContinuous (id : α → α) := fun s _ x h => by simpa only [image_id] using! h variable {α} @@ -69,7 +69,7 @@ protected theorem dual : @[to_dual] theorem map_isGreatest (hf : LeftOrdContinuous f) {s : Set α} {x : α} (h : IsGreatest s x) : IsGreatest (f '' s) (f x) := - ⟨mem_image_of_mem f h.1, (hf h.isLUB).1⟩ + ⟨mem_image_of_mem f h.1, (hf ⟨x, h.1⟩ h.isLUB).1⟩ @[to_dual] theorem mono (hf : LeftOrdContinuous f) : Monotone f := fun a₁ a₂ h => @@ -78,7 +78,7 @@ theorem mono (hf : LeftOrdContinuous f) : Monotone f := fun a₁ a₂ h => @[to_dual] theorem comp (hg : LeftOrdContinuous g) (hf : LeftOrdContinuous f) : LeftOrdContinuous (g ∘ f) := - fun s x h => by simpa only [image_image] using! hg (hf h) + fun s x hs h => by simpa only [image_image] using! hg (.image _ hs) (hf hs h) @[to_dual] protected theorem iterate {f : α → α} (hf : LeftOrdContinuous f) (n : ℕ) : @@ -95,7 +95,7 @@ variable [SemilatticeSup α] [SemilatticeSup β] {f : α → β} @[to_dual] theorem map_sup (hf : LeftOrdContinuous f) (x y : α) : f (x ⊔ y) = f x ⊔ f y := - (hf isLUB_pair).unique <| by simp only [image_pair, isLUB_pair] + (hf (insert_nonempty ..) isLUB_pair).unique <| by simp only [image_pair, isLUB_pair] @[to_dual] theorem le_iff (hf : LeftOrdContinuous f) (h : Injective f) {x y} : f x ≤ f y ↔ x ≤ y := by @@ -127,16 +127,19 @@ section CompleteLattice variable [CompleteLattice α] [CompleteLattice β] {f : α → β} @[to_dual] -theorem map_sSup' (hf : LeftOrdContinuous f) (s : Set α) : f (sSup s) = sSup (f '' s) := - (hf <| isLUB_sSup s).sSup_eq.symm +theorem map_sSup' (hf : LeftOrdContinuous f) {s : Set α} (hs : s.Nonempty) : + f (sSup s) = sSup (f '' s) := + (hf hs <| isLUB_sSup s).sSup_eq.symm @[to_dual] -theorem map_sSup (hf : LeftOrdContinuous f) (s : Set α) : f (sSup s) = ⨆ x ∈ s, f x := by - rw [hf.map_sSup', sSup_image] +theorem map_sSup (hf : LeftOrdContinuous f) {s : Set α} (hs : s.Nonempty) : + f (sSup s) = ⨆ x ∈ s, f x := by + rw [hf.map_sSup' hs, sSup_image] @[to_dual] -theorem map_iSup (hf : LeftOrdContinuous f) (g : ι → α) : f (⨆ i, g i) = ⨆ i, f (g i) := by - simp only [iSup, hf.map_sSup', ← range_comp] +theorem map_iSup (hf : LeftOrdContinuous f) [Nonempty ι] (g : ι → α) : + f (⨆ i, g i) = ⨆ i, f (g i) := by + simp only [iSup, hf.map_sSup' (range_nonempty g), ← range_comp] rfl end CompleteLattice @@ -148,7 +151,7 @@ variable [ConditionallyCompleteLattice α] [ConditionallyCompleteLattice β] [No @[to_dual] theorem map_csSup (hf : LeftOrdContinuous f) {s : Set α} (sne : s.Nonempty) (sbdd : BddAbove s) : f (sSup s) = sSup (f '' s) := - ((hf <| isLUB_csSup sne sbdd).csSup_eq <| sne.image f).symm + ((hf sne <| isLUB_csSup sne sbdd).csSup_eq <| sne.image f).symm @[to_dual] theorem map_ciSup (hf : LeftOrdContinuous f) {g : ι → α} (hg : BddAbove (range g)) : @@ -165,11 +168,11 @@ variable [Preorder α] [Preorder β] {f : α → β} {g : β → α} /-- A left adjoint in a Galois connection is left-continuous in the order-theoretic sense. -/ lemma leftOrdContinuous (gc : GaloisConnection f g) : LeftOrdContinuous f := - fun _ _ ↦ gc.isLUB_l_image + fun _ _ _ ↦ gc.isLUB_l_image /-- A right adjoint in a Galois connection is right-continuous in the order-theoretic sense. -/ lemma rightOrdContinuous (gc : GaloisConnection f g) : RightOrdContinuous g := - fun _ _ ↦ gc.isGLB_u_image + fun _ _ _ ↦ gc.isGLB_u_image end GaloisConnection diff --git a/Mathlib/Order/SemiconjSup.lean b/Mathlib/Order/SemiconjSup.lean index 9a8fca764974b4..e7ab5076672a2b 100644 --- a/Mathlib/Order/SemiconjSup.lean +++ b/Mathlib/Order/SemiconjSup.lean @@ -89,7 +89,7 @@ theorem Semiconj.symm_adjoint [PartialOrder α] [Preorder β] {fa : α ≃o α} Function.Semiconj g' fb fa := by refine fun y => (hg' _).unique ?_ rw [← fa.surjective.image_preimage { x | g x ≤ fb y }, preimage_setOf_eq] - simp only [h.eq, fb.le_iff_le, fa.leftOrdContinuous (hg' _)] + simp only [h.eq, fb.le_iff_le, fa.isLUB_image'.mpr (hg' _)] variable {G : Type*} @@ -97,7 +97,7 @@ theorem semiconj_of_isLUB [PartialOrder α] [Group G] (f₁ f₂ : G →* α ≃ (H : ∀ x, IsLUB (range fun g' => (f₁ g')⁻¹ (f₂ g' x)) (h x)) (g : G) : Function.Semiconj h (f₂ g) (f₁ g) := by refine fun y => (H _).unique ?_ - have := (f₁ g).leftOrdContinuous (H y) + have := (f₁ g).isLUB_image'.mpr (H y) rw [← range_comp, ← (Equiv.mulRight g).surjective.range_comp _] at this simpa [comp_def] using this diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index 47c36e01f50ace..bee708fa11f2b7 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -777,25 +777,33 @@ end LinearOrder section ConditionallyCompleteLinearOrder variable {X : Type*} [ConditionallyCompleteLinearOrder X] [TopologicalSpace X] [OrderTopology X] variable {Y : Type*} [ConditionallyCompleteLinearOrder Y] [TopologicalSpace Y] [OrderTopology Y] -variable [DenselyOrdered X] {f : X → Y} {x : X} +variable {f : X → Y} {x : X} /-- An order-theoretically left-continuous function is topologically left-continuous, assuming -the function is between conditionally complete linear orders with order topologies, and the domain -is densely ordered. -/ +the function is between conditionally complete linear orders with order topologies. -/ lemma LeftOrdContinuous.continuousWithinAt_Iic (hf : LeftOrdContinuous f) : ContinuousWithinAt f (Iic x) x := by rw [ContinuousWithinAt, OrderTopology.topology_eq_generate_intervals (α := Y)] simp_rw [TopologicalSpace.tendsto_nhds_generateFrom_iff, mem_nhdsWithin] rintro V ⟨z, rfl | rfl⟩ hxz -- The case `V = Ioi z`. - · obtain ⟨_, ⟨a, hax, rfl⟩, hza⟩ := (lt_isLUB_iff <| hf isLUB_Iio).mp hxz - exact ⟨Ioi a, isOpen_Ioi, hax, fun b hab ↦ hza.trans_le <| hf.mono hab.1.le⟩ + · obtain hz | ne := em' (f ⁻¹' Iic z).Nonempty + · exact ⟨univ, isOpen_univ, mem_univ _, fun a ha ↦ not_le.mp fun h ↦ hz ⟨a, h⟩⟩ + have bdd : BddAbove (f ⁻¹' Iic z) := ⟨x, fun a ha ↦ (hf.mono.reflect_lt (ha.trans_lt hxz)).le⟩ + have u_eq : Ioi (sSup (f ⁻¹' Iic z)) = f ⁻¹' Ioi z := by + refine Set.ext fun a ↦ ⟨fun ha ↦ ?_, fun ha ↦ ?_⟩ + · exact not_le.mp fun h ↦ ha.not_ge (le_csSup bdd h) + · apply lt_of_le_of_ne + · exact csSup_le ne fun b hb ↦ (hf.mono.reflect_lt (hb.trans_lt ha)).le + · have : sSup (f '' f ⁻¹' Iic z) ≤ z := csSup_le (.image _ ne) fun _ ⟨b, hb, heq⟩ ↦ heq ▸ hb + exact fun h ↦ this.not_gt ((h ▸ ha).trans_eq (hf.map_csSup ne bdd)) + exact ⟨f ⁻¹' Ioi z, u_eq ▸ isOpen_Ioi, hxz, fun _ h ↦ h.1⟩ -- The case `V = Iio z`. · exact ⟨univ, isOpen_univ, trivial, fun a ha ↦ (hf.mono ha.2).trans_lt hxz⟩ /-- An order-theoretically right-continuous function is topologically right-continuous, assuming -the function is between conditionally complete linear orders with order topologies, and the domain -is densely ordered. -/ +the function is between conditionally complete linear orders with order topologies. -/ +@[to_dual existing] lemma RightOrdContinuous.continuousWithinAt_Ici (hf : RightOrdContinuous f) : ContinuousWithinAt f (Ici x) x := hf.dual.continuousWithinAt_Iic From 36d9c9f455679093c901bcab147fbe8bc1c1ec2c Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:44:07 +0000 Subject: [PATCH 0551/1300] feat(GRewrite): strict rewriting (#38868) This PR makes use of the new `grw` implementation from #38318, to implement strict rewriting. That is, you can now rewrite with a strict inequality to change the relation in the goal from strict to non-strict. The `gcongr` and `grw` tactics now look up slightly differently in the `gcongrExt` environment extension, because `gcongr` knows the constant on both sides of the relation, while `grw` knows it on only one side. It would be possible to have two separate dictionaries in the environment for these two use cases. However, I have implemented it with just a single dictionary in the environment, as this reduces the overhead of having the environment extension. Note: in order to make strict rewriting have priority over the old behaviour, `lt_of_lt_of_le` and `lt_of_lt_of_le'` need to be preferred over `le_imp_le_of_le_of_le` and `lt_imp_lt_of_le_of_le`. Luckily this is the case because the former have fewer varying arguments than the latter. So, we don't need to explicitly set a high priority. --- Mathlib/Algebra/Order/Ring/GeomSum.lean | 2 +- Mathlib/Analysis/Convex/MetricSpace.lean | 2 +- .../Analysis/Convex/StrictCombination.lean | 4 +- .../Covering/Differentiation.lean | 4 +- .../Integral/CircleIntegral.lean | 3 +- Mathlib/Order/Basic.lean | 2 + Mathlib/Order/Interval/Set/Basic.lean | 6 +- Mathlib/Order/SuccPred/Basic.lean | 14 +- Mathlib/Tactic/GCongr/Core.lean | 262 +++++++++++------- Mathlib/Tactic/GRewrite/Core.lean | 9 +- Mathlib/Tactic/GRewrite/Elab.lean | 43 ++- MathlibTest/Tactic/GRewrite.lean | 74 ++++- 12 files changed, 261 insertions(+), 164 deletions(-) diff --git a/Mathlib/Algebra/Order/Ring/GeomSum.lean b/Mathlib/Algebra/Order/Ring/GeomSum.lean index a0129ce9cfe784..0fcf496eb09ac5 100644 --- a/Mathlib/Algebra/Order/Ring/GeomSum.lean +++ b/Mathlib/Algebra/Order/Ring/GeomSum.lean @@ -84,7 +84,7 @@ lemma geom_sum_alternating_of_lt_neg_one (hx : x + 1 < 0) (hn : 1 < n) : split_ifs at ihn ⊢ with hn' · rw [lt_add_iff_pos_left] exact mul_pos_of_neg_of_neg hx0 ihn - · grw [← hx] + · grw [← hx.le] gcongr simpa only [mul_one] using mul_lt_mul_of_neg_left ihn hx0 diff --git a/Mathlib/Analysis/Convex/MetricSpace.lean b/Mathlib/Analysis/Convex/MetricSpace.lean index f9926781d7352f..848ed2f4e6d82d 100644 --- a/Mathlib/Analysis/Convex/MetricSpace.lean +++ b/Mathlib/Analysis/Convex/MetricSpace.lean @@ -240,7 +240,7 @@ lemma continuous_convexCombPair_of_isBounded (add_sub_cancel ..) (x t) (y j)), dist_convexCombPair_convexCombPair_le] simp only [dist_self, mul_zero, add_zero, dist_convexCombPair_left] grw [abs_sub_comm, ← le_abs_self] at hj' - grw [hj, hj', hf1, hD] + grw [hj.le, hj'.le, hf1, hD] · field_simp; norm_num · exact hf0 _ diff --git a/Mathlib/Analysis/Convex/StrictCombination.lean b/Mathlib/Analysis/Convex/StrictCombination.lean index 7466e912b7b343..d0b40eae1ca35d 100644 --- a/Mathlib/Analysis/Convex/StrictCombination.lean +++ b/Mathlib/Analysis/Convex/StrictCombination.lean @@ -56,9 +56,7 @@ lemma StrictConvex.centerMass_mem_interior {s : Set V} {t : Finset ι} {w : ι · have hwi : w i + ∑ j ∈ t, w j ≠ 0 := by refine LT.lt.ne' ?_ have hwi : 0 < w i := by grind - grw [hwi] - simp only [lt_add_iff_pos_right] - exact (sum_nonneg hs₀).lt_of_ne' hsum_t + grw [← hwi, ← sum_nonneg hs₀, add_zero] simp only [hzi, ← add_smul, ← add_div, ne_eq, hwi, not_false_eq_true, div_self, one_smul] by_cases! hijt : ∃ i'' j'', i'' ∈ t ∧ j'' ∈ t ∧ z i'' ≠ z j'' ∧ w i'' ≠ 0 ∧ w j'' ≠ 0 · grind diff --git a/Mathlib/MeasureTheory/Covering/Differentiation.lean b/Mathlib/MeasureTheory/Covering/Differentiation.lean index f9dc88c5d184dd..7daede20a4718e 100644 --- a/Mathlib/MeasureTheory/Covering/Differentiation.lean +++ b/Mathlib/MeasureTheory/Covering/Differentiation.lean @@ -200,9 +200,7 @@ theorem ae_eventually_measure_zero_of_singular (hρ : ρ ⟂ₘ μ) : obtain ⟨n, hn⟩ : ∃ n, u n < w := ((tendsto_order.1 u_lim).2 w (ENNReal.coe_pos.1 w_pos)).exists filter_upwards [hx n, h'x, v.eventually_measure_lt_top x] intro a ha μa_pos μa_lt_top - grw [ENNReal.div_lt_iff (.inl μa_pos.ne') (.inl μa_lt_top.ne), ha, hn] - gcongr - exact μa_lt_top.ne + grw [ENNReal.div_lt_iff (.inl μa_pos.ne') (.inl μa_lt_top.ne), ha, hn, w_lt] section AbsolutelyContinuous diff --git a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean index 87e7993b83201f..be51d85b30cd1a 100644 --- a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean @@ -413,8 +413,7 @@ theorem _root_.TendstoUniformlyOn.tendsto_circleIntegral_of_continuousOn intro ε hε rcases exists_pos_mul_lt hε R with ⟨δ, hδ₀, hRδ⟩ refine (h δ hδ₀).mono fun i hi x hx ↦ ?_ - grw [hi (circleMap c R x) (by simp [hR])] - exact hRδ + grw [← hRδ, hi (circleMap c R x) (by simp [hR])] namespace circleIntegral diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 24ba1c2d27cb80..cff09b9564d8aa 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -189,6 +189,8 @@ theorem ge_imp_ge_of_le_of_le (h₁ : a ≤ c) (h₂ : d ≤ b) : a ≥ b → c theorem gt_imp_gt_of_le_of_le (h₁ : a ≤ c) (h₂ : d ≤ b) : a > b → c > d := fun hab ↦ (h₂.trans_lt hab).trans_le h₁ +attribute [gcongr strict] lt_of_lt_of_le lt_of_lt_of_le' + namespace Mathlib.Tactic.GCongr open Lean Meta diff --git a/Mathlib/Order/Interval/Set/Basic.lean b/Mathlib/Order/Interval/Set/Basic.lean index 27a3b28f92ab03..bc913bfeaa7fcf 100644 --- a/Mathlib/Order/Interval/Set/Basic.lean +++ b/Mathlib/Order/Interval/Set/Basic.lean @@ -266,7 +266,7 @@ theorem Iic_ssubset_Iic : Iic a ⊂ Iic b ↔ a < b where mpr h := (ssubset_iff_of_subset (Iic_subset_Iic.mpr h.le)).mpr ⟨b, self_mem_Iic, fun h' => h.not_ge h'⟩ -@[to_dual (attr := simp)] +@[to_dual (attr := simp, gcongr strict)] theorem Iic_subset_Iio : Iic a ⊆ Iio b ↔ a < b := ⟨fun h => h self_mem_Iic, fun h _ hx => lt_of_le_of_lt hx h⟩ @@ -324,7 +324,7 @@ theorem Icc_ssubset_Icc_left (h₂ : a₂ ≤ b₂) (ha : a₂ < a₁) (hb : b theorem Ico_subset_Ioo (ha : a₂ < a₁) (hb : b₁ ≤ b₂) : Ico a₁ b₁ ⊆ Ioo a₂ b₂ := fun _ hx ↦ ⟨ha.trans_le hx.1, hx.2.trans_le hb⟩ -@[to_dual] +@[to_dual (attr := gcongr strict)] theorem Ico_subset_Ioo_left (h : a₁ < a₂) : Ico a₂ b ⊆ Ioo a₁ b := Ico_subset_Ioo h le_rfl @@ -332,7 +332,7 @@ theorem Ico_subset_Ioo_left (h : a₁ < a₂) : Ico a₂ b ⊆ Ioo a₁ b := theorem Icc_subset_Ioc (ha : a₂ < a₁) (hb : b₁ ≤ b₂) : Icc a₁ b₁ ⊆ Ioc a₂ b₂ := fun _ hx ↦ ⟨ha.trans_le hx.1, hx.2.trans hb⟩ -@[to_dual] +@[to_dual (attr := gcongr strict)] theorem Icc_subset_Ioc_left (h : a₁ < a₂) : Icc a₂ b ⊆ Ioc a₁ b := Icc_subset_Ioc h le_rfl diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 6536f5edf298ea..b6947eeac6659e 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -232,9 +232,11 @@ theorem isMax_iterate_succ_of_eq_of_ne {n m : ℕ} (h_eq : succ^[n] a = succ^[m] · rw [h_eq] exact isMax_iterate_succ_of_eq_of_lt h_eq.symm (lt_of_le_of_ne h h_ne.symm) -@[to_dual] -theorem Iic_subset_Iio_succ_of_not_isMax (ha : ¬IsMax a) : Iic a ⊆ Iio (succ a) := - fun _ => (lt_succ_of_le_of_not_isMax · ha) +@[to_dual (attr := deprecated "use `gcongr`/`grw` and `lt_succ_of_not_isMax" + (since := "2026-06-06"))] +theorem Iic_subset_Iio_succ_of_not_isMax (ha : ¬IsMax a) : Iic a ⊆ Iio (succ a) := by + gcongr + exact lt_succ_of_not_isMax ha @[to_dual] theorem Ici_succ_of_not_isMax (ha : ¬IsMax a) : Ici (succ a) = Ioi a := @@ -242,15 +244,13 @@ theorem Ici_succ_of_not_isMax (ha : ¬IsMax a) : Ici (succ a) = Ioi a := @[to_dual Icc_subset_Ioc_pred_left_of_not_isMin] theorem Icc_subset_Ico_succ_right_of_not_isMax (hb : ¬IsMax b) : Icc a b ⊆ Ico a (succ b) := by - rw [← Ici_inter_Iio, ← Ici_inter_Iic] gcongr - exact Iic_subset_Iio_succ_of_not_isMax hb + exact lt_succ_of_not_isMax hb @[to_dual Ico_subset_Ioo_pred_left_of_not_isMin] theorem Ioc_subset_Ioo_succ_right_of_not_isMax (hb : ¬IsMax b) : Ioc a b ⊆ Ioo a (succ b) := by - rw [← Ioi_inter_Iio, ← Ioi_inter_Iic] gcongr - exact Iic_subset_Iio_succ_of_not_isMax hb + exact lt_succ_of_not_isMax hb @[to_dual Icc_pred_right_of_not_isMin] theorem Icc_succ_left_of_not_isMax (ha : ¬IsMax a) : Icc (succ a) b = Ioc a b := by diff --git a/Mathlib/Tactic/GCongr/Core.lean b/Mathlib/Tactic/GCongr/Core.lean index 9a3592bba6c1e7..82658fddf1dd60 100644 --- a/Mathlib/Tactic/GCongr/Core.lean +++ b/Mathlib/Tactic/GCongr/Core.lean @@ -144,7 +144,7 @@ public meta section namespace Mathlib.Tactic.GCongr open Lean Meta -/-- `GCongrKey` is the key used in the hashmap for looking up `gcongr` lemmas. -/ +/-- `GCongrKey` is the key used in the dictionary for looking up `gcongr` lemmas. -/ structure GCongrKey where /-- The name of the relation. For example, `a + b ≤ a + c` has ``relName := `LE.le``. -/ relName : Name @@ -176,8 +176,9 @@ structure GCongrHyp where /-- Structure recording the data for a "generalized congruence" (`gcongr`) lemma. -/ structure GCongrLemma where - /-- The key under which the lemma is stored. -/ - key : GCongrKey + /-- The keys under which the lemma is stored. This is usually one key, + but for `gcongr strict` lemmas, this stores two keys, for the LHS and RHS respectively. -/ + keys : List GCongrKey /-- The name of the lemma. -/ declName : Name /-- `mainSubgoals` are the subgoals on which `gcongr` will be recursively called. -/ @@ -202,11 +203,11 @@ abbrev GCongrLemmas := Std.TreeMap GCongrKey (List GCongrLemma) def GCongrLemma.prioLE (a b : GCongrLemma) : Bool := (compare a.prio b.prio).then (compare b.numVarying a.numVarying) |>.isLE -/-- Insert a `GCongrLemma` in a collection of lemmas, making sure that the lemmas are sorted. -/ +/-- Insert a `GCongrLemma` in a collection of lemmas, making sure they are sorted by priority. -/ def addGCongrLemmaEntry (m : GCongrLemmas) (l : GCongrLemma) : GCongrLemmas := - m.alter l.key fun - | none => [l] - | some es => insert l es + l.keys.foldl (init := m) fun m key ↦ m.alter key fun + | none => [l] + | some es => insert l es where /--- Insert a `GCongrLemma` in the correct place in a list of lemmas. -/ insert (l : GCongrLemma) : List GCongrLemma → List GCongrLemma @@ -220,6 +221,27 @@ initialize gcongrExt : SimpleScopedEnvExtension GCongrLemma GCongrLemmas ← initial := {} } +/-- Return the `gcongr` lemmas whose conclusion has the shape `relName (lhs ..) (rhs ..)`, +where `arity` is the number of arguments in `..`. This is used by the `gcongr` tactic. -/ +def findGCongrLemmas? (relName lhs rhs : Name) (arity : Nat) : CoreM (List GCongrLemma) := do + let lemmas := gcongrExt.getState (← getEnv) + let key := { relName, head := lhs, arity } + let some lemmas := lemmas.get? key | return [] + let keys := if lhs == rhs then [key] else [key, { key with head := rhs }] + return lemmas.filter (·.keys == keys) + +/-- Get the `gcongr` lemmas whose conclusion has the shape +`relName (head ..) _`, if `forward := true`, or `rel _ (head ..)`, if `forward := false`. +`arity` is the number of arguments in `..`. This is used by the `grw` tactic. -/ +def findGCongrLemmas?' (relName head : Name) (forward : Bool) (arity : Nat) : + CoreM (List GCongrLemma) := do + let lemmas := gcongrExt.getState (← getEnv) + let some lemmas := lemmas.get? { relName, head, arity } | return [] + if forward then + return lemmas.filter (·.keys.head!.head == head) + else + return lemmas.filter (·.keys.getLast!.head == head) + /-- Given an application `f a₁ .. aₙ`, return the name of `f`, and the array of arguments `aᵢ`. -/ def getCongrAppFnArgs (e : Expr) : Option (Name × Array Expr) := match e.cleanupAnnotations with @@ -254,17 +276,23 @@ def updateRel (r e : Expr) (isLhs : Bool) : Expr := /-- Try to construct the `GCongrLemma` for a lemma with hypotheses `hyps` and conclusion `target`. -/ def makeGCongrLemma (hyps : Array Expr) (target : Expr) (declName : Name) (prio : Nat) - (forGrw : Bool) : MetaM GCongrLemma := do + (strict forGrw : Bool) : MetaM GCongrLemma := do let fail {α} (m : MessageData) : MetaM α := throwError "\ @[gcongr] attribute only applies to lemmas proving f x₁ ... xₙ ∼ f x₁' ... xₙ'.\n \ {m} in {target}" -- verify that conclusion of the lemma is of the form `f x₁ ... xₙ ∼ f x₁' ... xₙ'` let some (relName, lhs, rhs) := getRel (← whnf target) | fail "No relation found" let lhs := lhs.headBeta; let rhs := rhs.headBeta -- this is required for `Monotone fun x => ⋯` - let some (head, lhsArgs) := getCongrAppFnArgs lhs | fail "LHS is not suitable for congruence" - let some (head', rhsArgs) := getCongrAppFnArgs rhs | fail "RHS is not suitable for congruence" - unless head == head' && lhsArgs.size == rhsArgs.size do - fail "LHS and RHS do not have the same head function and arity" + let some (lhsHead, lhsArgs) := getCongrAppFnArgs lhs | fail "LHS is not suitable for congruence" + let some (rhsHead, rhsArgs) := getCongrAppFnArgs rhs | fail "RHS is not suitable for congruence" + if strict then + if lhsHead == rhsHead then + fail "LHS and RHS have the same head function." + else + if lhsHead != rhsHead then + fail "LHS and RHS do not have the same head function." + if lhsArgs.size != rhsArgs.size then + fail "LHS and RHS do not have the same number of arguments." let mut pairs := #[] -- iterate through each pair of corresponding (LHS/RHS) inputs to the head function `head` in -- the conclusion of the lemma @@ -274,7 +302,9 @@ def makeGCongrLemma (hyps : Array Expr) (target : Expr) (declName : Name) (prio if ← isDefEq lhs rhs <||> (isProof lhs <&&> isProof rhs) then continue let lhs := lhs.eta; let rhs := rhs.eta -- verify that the "varying argument" pairs are free variables (after eta-reduction) - unless lhs.isFVar && rhs.isFVar do fail "Not all varying arguments are free variables" + unless lhs.isFVar && rhs.isFVar do + if strict then continue -- When comparing `a ≤ b` with `a < b`, the instances are different. + fail "Not all varying arguments are free variables" -- Instance implicit arguments should be synthesized, rather than solved by congruence if (← lhs.fvarId!.getBinderInfo).isInstImplicit && (← rhs.fvarId!.getBinderInfo).isInstImplicit then @@ -320,110 +350,143 @@ def makeGCongrLemma (hyps : Array Expr) (target : Expr) (declName : Name) (prio This means that the `@[gcongr]` lemma cannot be used in the `grw` tactic. \ Please use `@[gcongr only]` instead." -- store all the information from this parse of the lemma's structure in a `GCongrLemma` - let key := { relName, head, arity := lhsArgs.size } - return { key, declName, mainSubgoals, numHyps := hyps.size, prio, numVarying, forGrw } + let mut keys := [{ relName, head := rhsHead, arity := lhsArgs.size }] + if strict then + keys := { relName, head := lhsHead, arity := lhsArgs.size } :: keys + return { keys, declName, mainSubgoals, numHyps := hyps.size, prio, numVarying, forGrw } /-- Attribute marking "generalized congruence" (`gcongr`) lemmas. Such lemmas must have a conclusion of a form such as `f x₁ y z₁ ∼ f x₂ y z₂`; that is, a relation between the application of a function to two argument lists, in which the "varying argument" pairs (here `x₁`/`x₂` and -`z₁`/`z₂`) are all free variables. +`z₁`/`z₂`) are all free variables. These lemmas are used by the `gcongr` and `grw` tactics. The antecedents of such a lemma are classified as generating "main goals" if they are of the form `x₁ ≈ x₂` for some "varying argument" pair `x₁`/`x₂` (and a possibly different relation `≈` to `∼`), or more generally of the form `∀ i h h' j h'', f₁ i j ≈ f₂ i j` (say) for some "varying argument" pair `f₁`/`f₂`, where the arguments of `f₁` and `f₂` are the same list of variables which have to be bound by the preceding `∀`. (Other antecedents are considered to generate "side goals".) -Use `gcongr only` to relax these conditions. A `gcongr only` lemma is not used by `grw`. If a lemma such as `add_le_add : a ≤ b → c ≤ d → a + c ≤ b + d` has been tagged with `gcongr`, then a direct consequence like `a ≤ b → a + c ≤ b + c` does *not* need to be tagged. However, if a more specific lemma has fewer side conditions, it should also be tagged with `gcongr`. For example, `mul_le_mul_of_nonneg_right` and `mul_le_mul_of_nonneg_left` are both tagged. -Lemmas involving `<` or `≤` can also be marked `@[bound]` for use in the related `bound` tactic. -/ -syntax (name := gcongrAttr) "gcongr" (&" only")? (prio)? : attr +* `gcongr only` relaxes some checks that ensure that the lemma is suitable for use in `grw`. + So, a lemma tagged `gcongr only` is not used by `grw`, but it may still be used by `gcongr`. +* `gcongr strict` lets you tag lemmas where the conclusion relates two different constants, + instead of a constant with itself. + This allows `grw` to replace one constant with another while doing a rewrite. + In particular, we use this to have special support for rewriting with strict inequalities (`<`). + This is done by applying `gcongr strict` to `lt_of_lt_of_le`, which has the conclusion + `b ≤ c → a < c` that relates `LE.le` with `LT.lt` (and similarly for `lt_of_lt_of_le'`). + As a result, a rewrite with a strict inequality can turn `<` into `≤`, or `≤` into `<`, + depending on whether this appears in positive or negative position. +-/ +syntax (name := gcongrAttr) "gcongr" (&" strict")? (&" only")? (prio)? : attr + +/-- Mark `declName` with the `gcongr` attribute. -/ +def addGCongrLemma (declName : Name) (stx : Syntax) (kind : AttributeKind) : MetaM Unit := + withReducible do + let strict := !stx[1].isNone + let forGrw := stx[2].isNone + let prio ← getAttrParamOptPrio stx[3] + let cinfo ← getConstInfo declName + let type := cinfo.type + forallTelescope type fun xs type => do + -- Special case the unfolding of `Monotone`-like conclusions. + if type.getAppFn.constName? matches + `Monotone | `Antitone | `StrictMono | `StrictAnti | + `MonotoneOn | `AntitoneOn | `StrictMonoOn | `StrictAntiOn then + forallTelescope (← withDefault <| unfoldDefinition type) fun xs' type => do + gcongrExt.add (← makeGCongrLemma (xs ++ xs') type declName prio strict forGrw) kind + return + -- If the conclusion is a free variable, it is a lemma like `imp_imp_imp` or `forall_imp`, + -- so we revert the last two variables. + if type.getAppFn.isFVar then + let type ← mkForallFVars xs[(xs.size-2)...xs.size] type + gcongrExt.add (← makeGCongrLemma xs.pop.pop type declName prio strict forGrw) kind + return + try + -- Add a `gcongr` lemma in the "normal" way. + gcongrExt.add (← makeGCongrLemma xs type declName prio strict forGrw) kind + catch e => try + match_expr type with + | Iff lhs rhs => addIffGCongrLemma prio strict forGrw cinfo xs lhs rhs + | _ => addImpGCongrLemma prio strict forGrw cinfo xs type + catch _ => + -- If none of the methods work, we throw the error thrown by the "normal" attempt. + throw e +where + /-- Assuming the lemma has conslusion `lhs ↔ rhs`, mark one of the implications + `lhs → rhs` or `rhs → lhs` as a `gcongr` lemma. -/ + addIffGCongrLemma (prio : Nat) (strict forGrw : Bool) (cinfo : ConstantInfo) + (xs : Array Expr) (lhs rhs : Expr) : MetaM Unit := do + try + -- Try using the `←` implication. + withLocalDeclD `_a rhs fun x => do + let gcongrLemma ← makeGCongrLemma (xs.push x) lhs declName prio strict forGrw + let auxType ← mkForallFVars (xs.push x) lhs + let auxValue ← mkLambdaFVars xs <| mkApp3 (.const ``Iff.mpr []) lhs rhs <| + mkAppN (.const declName (cinfo.levelParams.map .param)) xs + let auxDeclName ← mkAuxLemma cinfo.levelParams auxType auxValue (kind? := `_gcongr) + (forceExpose := true) + gcongrExt.add { gcongrLemma with declName := auxDeclName } kind + catch _ => + -- Try using the `→` implication. + withLocalDeclD `_a lhs fun x => do + let gcongrLemma ← makeGCongrLemma (xs.push x) rhs declName prio strict forGrw + let auxType ← mkForallFVars (xs.push x) rhs + let auxValue ← mkLambdaFVars xs <| mkApp3 (.const ``Iff.mp []) lhs rhs <| + mkAppN (.const declName (cinfo.levelParams.map .param)) xs + let auxDeclName ← mkAuxLemma cinfo.levelParams auxType auxValue (kind? := `_gcongr) + (forceExpose := true) + gcongrExt.add { gcongrLemma with declName := auxDeclName } kind + /-- + Mark the lemma as a `gcongr` lemma, using implication as the relation. + For example, `Or.imp : (a → c) → (b → d) → a ∨ b → c ∨ d`. In the non-strict case, + we want to support such lemmas even if the hypotheses are given in a different order. + So, we find the last hypothesis whose head matches that of the conclusion, + and move it to the end. + -/ + addImpGCongrLemma (prio : Nat) (strict forGrw : Bool) (cinfo : ConstantInfo) + (xs : Array Expr) (type : Expr) : MetaM Unit := do + if strict then + let some x := xs.back? | failure + let type ← mkForallFVars #[x] type + let gcongrLemma ← makeGCongrLemma xs.pop type declName prio strict forGrw + gcongrExt.add gcongrLemma kind + else + let .const c _ := type.getAppFn | failure + let rec findIdx (i : Nat) (h : i ≤ xs.size) : MetaM (Fin xs.size) := + match i with + | 0 => failure + | i + 1 => do + if (← inferType xs[i]).getAppFn.isConstOf c then + return ⟨i, by lia⟩ + else + findIdx i (by lia) + let i ← findIdx xs.size xs.size.le_refl + let type ← mkForallFVars #[xs[i]] type + let xs' := xs.eraseIdx i i.isLt + let gcongrLemma ← makeGCongrLemma xs' type declName prio strict forGrw + if i == xs.size - 1 then + -- The argument order is already correct. + gcongrExt.add gcongrLemma kind + else + -- We need to make an auxiliary theorem with the correct argument order. + let auxType ← mkForallFVars xs' type + let auxValue ← mkLambdaFVars (xs'.push xs[i]) <| + mkAppN (.const declName (cinfo.levelParams.map .param)) xs + let auxDeclName ← mkAuxLemma cinfo.levelParams auxType auxValue (kind? := `_gcongr) + (forceExpose := true) + gcongrExt.add { gcongrLemma with declName := auxDeclName } kind @[inherit_doc gcongrAttr] initialize registerBuiltinAttribute { name := `gcongrAttr descr := "generalized congruence" - add := fun declName stx kind ↦ MetaM.run' do withReducible do - let forGrw := stx[1].isNone - let prio ← getAttrParamOptPrio stx[2] - let cinfo ← getConstInfo declName - let type := cinfo.type - forallTelescope type fun xs type => do - -- Special case the unfolding of `Monotone`-like conclusions. - if type.getAppFn.constName? matches - `Monotone | `Antitone | `StrictMono | `StrictAnti | - `MonotoneOn | `AntitoneOn | `StrictMonoOn | `StrictAntiOn then - forallTelescope (← withDefault <| unfoldDefinition type) fun xs' type => do - gcongrExt.add (← makeGCongrLemma (xs ++ xs') type declName prio forGrw) kind - return - -- If the conclusion is a free variable, it is a lemma like `imp_imp_imp` or `forall_imp`, - -- so we revert the last two variables. - if type.getAppFn.isFVar then - let type ← mkForallFVars xs[(xs.size-2)...xs.size] type - gcongrExt.add (← makeGCongrLemma xs.pop.pop type declName prio forGrw) kind - return - try - -- Add a `gcongr` lemma in the "normal" way. - gcongrExt.add (← makeGCongrLemma xs type declName prio forGrw) kind - catch e => try - match_expr type with - | Iff lhs rhs => - -- When the goal is an `↔`, try to use either of the implications. - try - -- Try using the `←` implication. - withLocalDeclD `_a rhs fun x => do - let gcongrLemma ← makeGCongrLemma (xs.push x) lhs declName prio forGrw - let auxType ← mkForallFVars (xs.push x) lhs - let auxValue ← mkLambdaFVars xs <| mkApp3 (.const ``Iff.mpr []) lhs rhs <| - mkAppN (.const declName (cinfo.levelParams.map .param)) xs - let auxDeclName ← mkAuxLemma cinfo.levelParams auxType auxValue (kind? := `_gcongr) - gcongrExt.add { gcongrLemma with declName := auxDeclName } kind - catch _ => - -- Try using the `→` implication. - withLocalDeclD `_a lhs fun x => do - let gcongrLemma ← makeGCongrLemma (xs.push x) rhs declName prio forGrw - let auxType ← mkForallFVars (xs.push x) rhs - let auxValue ← mkLambdaFVars xs <| mkApp3 (.const ``Iff.mp []) lhs rhs <| - mkAppN (.const declName (cinfo.levelParams.map .param)) xs - let auxDeclName ← mkAuxLemma cinfo.levelParams auxType auxValue (kind? := `_gcongr) - gcongrExt.add { gcongrLemma with declName := auxDeclName } kind - | _ => - -- Try to interpret the lemma as an implicational `gcongr` lemma, - -- such as `Or.imp : (a → c) → (b → d) → a ∨ b → c ∨ d`. - -- We want to support such lemmas even if the hypotheses are given in a different order. - -- So, we find the last hypothesis whose head matches that of the conclusion, - -- and move it to the end. - let .const c _ := type.getAppFn | failure - let rec findIdx (i : Nat) (h : i ≤ xs.size) : MetaM (Fin xs.size) := - match i with - | 0 => failure - | i + 1 => do - if (← inferType xs[i]).getAppFn.isConstOf c then - return ⟨i, by lia⟩ - else - findIdx i (by lia) - let i ← findIdx xs.size xs.size.le_refl - let type ← mkForallFVars #[xs[i]] type - let xs' := xs.eraseIdx i i.isLt - let gcongrLemma ← makeGCongrLemma xs' type declName prio forGrw - if i == xs.size - 1 then - -- The argument order is already correct. - gcongrExt.add gcongrLemma kind - else - -- We need to make an auxiliary theorem with the correct argument order. - let auxType ← mkForallFVars xs' type - let auxValue ← mkLambdaFVars (xs'.push xs[i]) <| - mkAppN (.const declName (cinfo.levelParams.map .param)) xs - let auxDeclName ← mkAuxLemma cinfo.levelParams auxType auxValue (kind? := `_gcongr) - gcongrExt.add { gcongrLemma with declName := auxDeclName } kind - catch _ => - -- If none of the methods work, we throw the error thrown by the "normal" attempt. - throw e + add := (addGCongrLemma · · · |>.run') } initialize registerTraceClass `Meta.gcongr @@ -554,7 +617,7 @@ def relImpRelLemma (arity : Nat) : List GCongrLemma := declName := ``rel_imp_rel mainSubgoals := #[⟨5, 3, 7, [], true⟩, ⟨4, 6, 8, [], false⟩] numHyps := 9 - key := default, prio := default, numVarying := default, forGrw := true + keys := default, prio := default, numVarying := default, forGrw := true }] end Trans @@ -709,14 +772,13 @@ partial def _root_.Lean.MVarId.gcongr let some (rhsHead, rhsArgs) := getCongrAppFnArgs rhs | if mdataLhs?.isNone then pushNewGoal g; return false throwTacticEx `gcongr g m!"the head of {rhs} is not a constant" - unless lhsHead == rhsHead && lhsArgs.size == rhsArgs.size do + unless lhsArgs.size == rhsArgs.size do if mdataLhs?.isNone then pushNewGoal g; return false - throwTacticEx `gcongr g m!"{lhs} and {rhs} are not of the same shape" + throwTacticEx `gcongr g m!"{lhs} and {rhs} have a different number of arguments" let mctx ← getMCtx -- Look up the `@[gcongr]` lemmas whose conclusion has the same relation and head function as -- the goal - let key := { relName, head := lhsHead, arity := lhsArgs.size } - let mut lemmas := (gcongrExt.getState (← getEnv)).getD key [] + let mut lemmas ← findGCongrLemmas? relName lhsHead rhsHead lhsArgs.size if relName == `_Implies then lemmas := lemmas ++ relImpRelLemma lhsArgs.size for lem in lemmas do diff --git a/Mathlib/Tactic/GRewrite/Core.lean b/Mathlib/Tactic/GRewrite/Core.lean index 298658490b1842..1b5311dcc33df0 100644 --- a/Mathlib/Tactic/GRewrite/Core.lean +++ b/Mathlib/Tactic/GRewrite/Core.lean @@ -16,10 +16,10 @@ This module defines the core of the `grw`/`grewrite` tactic. This file provides two implementations of the tactic: 1. The simple implementation uses `kabstract` to determine where to rewrite, and then calls `MVarId.gcongr` to prove that the rewrite is valid. - This is used by `nth_grw` and `grw'` + This is used by `nth_grw` and `grw +useKAbstract`. 2. The more sophisticated implementation has its own congruence loop, applying `gcongr` lemmas to - create the replacement expression, while at the same time proving that this is related to the - original expression. + create the replacement expression, and to prove that this is related to the original expression. + This supports the use of strict inequalities to change the strictness in the goal. This is used by `grw` and `apply_rw`. -/ @@ -313,8 +313,7 @@ partial def grewriteCore (relName : Name) (rel? : Option Expr) (e : Expr) (forwa return (mvar, goal) -- Try all applicable `@[gcongr]` lemmas. if let some (head, args) := getCongrAppFnArgs e then - let key := { relName, head, arity := args.size } - let mut lemmas := (gcongrExt.getState (← getEnv)).getD key [] + let mut lemmas ← findGCongrLemmas?' relName head forward args.size if relName == `_Implies then lemmas := lemmas ++ relImpRelLemma args.size let mctx ← getMCtx diff --git a/Mathlib/Tactic/GRewrite/Elab.lean b/Mathlib/Tactic/GRewrite/Elab.lean index 97a31d8929e9f2..213dfd28dc98df 100644 --- a/Mathlib/Tactic/GRewrite/Elab.lean +++ b/Mathlib/Tactic/GRewrite/Elab.lean @@ -120,8 +120,7 @@ declare_config_elab elabGRewriteConfig GRewrite.Config /-- `grewrite [e₁, ..., eₙ]` uses each expression `eᵢ : Rᵢ aᵢ bᵢ` (where `Rᵢ` is any two-argument relation) as a generalized rewrite rule on the main goal, replacing occurrences of `aᵢ` with `bᵢ`. -Occurrences of `bᵢ` are not rewritten, even if logically possible. Use `grewrite [← eᵢ]` to rewrite -in the other direction, replacing occurrences of `bᵢ` with `aᵢ`. +Use `grewrite [← eᵢ]` to rewrite in the other direction, replacing occurrences of `bᵢ` with `aᵢ`. If an expression `e` is a defined constant, then the equational theorems associated with `e` are used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to @@ -131,13 +130,12 @@ after unification will create side goals. To be able to use `grewrite`, the relevant lemmas need to be tagged with `@[gcongr]`. To rewrite inside a transitive relation, you can also give it an `IsTrans` instance. -The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it. -A future version of `grewrite` may get special support for making better use of strict inequalities. + +Rewriting with a strict inequality `a < b` may change a constant in the goal, +such as changing `<` to `≤`. If this is not possible, then `a < b` is treated the same as `a ≤ b`. `grw` is like `grewrite` but tries to close the goal afterwards by "cheap" (reducible) `rfl`. To rewrite only in the `n`-th position, use `nth_grewrite n`. -This is useful when `grewrite` tries to rewrite in a position that is not valid for the given -relation. `apply_rewrite [e₁, ..., eₙ]` is a shorthand for `grewrite +implicationHyp [e₁, ..., eₙ]`: it interprets `· → ·` as a relation instead of adding the hypothesis as a side condition. @@ -166,8 +164,7 @@ public def evalGRewriteSeq : Tactic := fun stx => do `grw [e₁, ..., eₙ]` uses each expression `eᵢ : Rᵢ aᵢ bᵢ` (where `Rᵢ` is any two-argument relation) as a generalized rewrite rule on the main goal, replacing occurrences of `aᵢ` with `bᵢ`, then tries to close the main goal by "cheap" (reducible) `rfl`. -Occurrences of `bᵢ` are not rewritten, even if logically possible. Use `grw [← eᵢ]` to rewrite -in the other direction, replacing occurrences of `bᵢ` with `aᵢ`. +Use `grw [← eᵢ]` to rewrite in the other direction, replacing occurrences of `bᵢ` with `aᵢ`. If an expression `e` is a defined constant, then the equational theorems associated with `e` are used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to @@ -177,14 +174,14 @@ after unification will create side goals. To be able to use `grw`, the relevant lemmas need to be tagged with `@[gcongr]`. To rewrite inside a transitive relation, you can also give it an `IsTrans` instance. -The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it. -A future version of `grw` may get special support for making better use of strict inequalities. + +Rewriting with a strict inequality `a < b` may change the goal, such as changing `<` to `≤`. +If this is not possible, then `a < b` is treated the same as `a ≤ b`. `grewrite` is like `grw` but does not try to apply `rfl` afterwards. To rewrite only in the `n`-th position, use `nth_grw n`. -This is useful when `grw` tries to rewrite in a position that is not valid for the given relation. -`apply_rw [rules]` is a shorthand for `grw +implicationHyp [rules]`: it interprets `· → ·` as a -relation instead of adding the hypothesis as a side condition. +`apply_rw [e₁, ..., eₙ]` is a shorthand for `grw +implicationHyp [e₁, ..., eₙ]`: it interprets +`· → ·` as a relation instead of adding the hypothesis as a side condition. * `grw [← e]` applies the rewrite rule `e : R a b` in the reverse direction, replacing occurrences of `b` with `a`. @@ -192,7 +189,7 @@ relation instead of adding the hypothesis as a side condition. details. * To let `grw` unfold more aggressively, as in `erw`, use `grw (transparency := default) [e₁, ..., eₙ]`. - * `grw +implicationHyp [e₁, ..., e\_n]` interprets `· → ·` as a relation (see `apply_rw`). + * `grw +implicationHyp [e₁, ..., eₙ]` interprets `· → ·` as a relation (see `apply_rw`). * `grw [e₁, ..., eₙ] at l` rewrites at the location(s) `l`. Examples: @@ -263,8 +260,7 @@ macro (name := applyRwSeq) "apply_rw " c:optConfig s:rwRuleSeq loc:(location)? : /-- `nth_grewrite n₁ ... nₖ [e₁, ..., eₙ]` is a variant of `grewrite` that for each expression `eᵢ : R aᵢ bᵢ` only replaces the `n₁, ..., nₖ`th occurrence of `aᵢ` with `bᵢ`. -Occurrences of `bᵢ` are not rewritten, even if logically possible. Use -`nth_grewrite n₁ ... nₖ [← eᵢ]` to rewrite in the other direction, replacing occurrences of `bᵢ` +Use `nth_grewrite n₁ ... nₖ [← eᵢ]` to rewrite in the other direction, replacing occurrences of `bᵢ` with `aᵢ`. If an expression `e` is a defined constant, then the equational theorems associated with `e` are @@ -275,9 +271,8 @@ after unification will create side goals. To be able to use `nth_grewrite`, the relevant lemmas need to be tagged with `@[gcongr]`. To rewrite inside a transitive relation, you can also give it an `IsTrans` instance. -The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it. -A future version of `nth_grewrite` may get special support for making better use of strict -inequalities. +Rewriting with a strict inequality `a < b` may change the strictness of the goal, +replacing a goal `_ < _` by `_ ≤ _`. If this is not possible, then `a < b` is treated as `a ≤ b`. * `nth_grewrite n₁ ... nₖ [← e]` applies the rewrite rule `e : R a b` in the reverse direction, replacing the `n₁, ..., nₖ`th occurrences of `b` with `a`. @@ -294,9 +289,8 @@ macro "nth_grewrite" c:optConfig ppSpace nums:(num)+ s:rwRuleSeq loc:(location)? /-- `nth_grw n₁ ... nₖ [e₁, ..., eₙ]` is a variant of `grw` that for each expression `eᵢ : R aᵢ bᵢ` only -replaces the `n₁, ..., nₖ`th occurrence of `aᵢ` with `bᵢ`. Occurrences of `bᵢ` are not rewritten, -even if logically possible. Use `nth_grw n₁ ... nₖ [← eᵢ]` to rewrite in the other direction, -replacing occurrences of `bᵢ` with `aᵢ`. +replaces the `n₁, ..., nₖ`th occurrence of `aᵢ` with `bᵢ`. Use `nth_grw n₁ ... nₖ [← eᵢ]` to rewrite +in the other direction, replacing occurrences of `bᵢ` with `aᵢ`. If an expression `e` is a defined constant, then the equational theorems associated with `e` are used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to @@ -306,9 +300,8 @@ after unification will create side goals. To be able to use `nth_grw`, the relevant lemmas need to be tagged with `@[gcongr]`. To rewrite inside a transitive relation, you can also give it an `IsTrans` instance. -The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it. -A future version of `nth_grw` may get special support for making better use of strict -inequalities. +Rewriting with a strict inequality `a < b` may change the strictness of the goal, +replacing a goal `_ < _` by `_ ≤ _`. If this is not possible, then `a < b` is treated as `a ≤ b`. * `nth_grw n₁ ... nₖ [← e]` applies the rewrite rule `e : R a b` in the reverse direction, replacing the `n₁, ..., nₖ`th occurrences of `b` with `a`. diff --git a/MathlibTest/Tactic/GRewrite.lean b/MathlibTest/Tactic/GRewrite.lean index 634586f7fad85e..62a69dee5f6a3f 100644 --- a/MathlibTest/Tactic/GRewrite.lean +++ b/MathlibTest/Tactic/GRewrite.lean @@ -48,8 +48,8 @@ example (h₁ : c ≤ b) (h₂ : a + 5 < c + 6) : a + 5 < b + 6 := by example (h₁ : a + e ≤ b + e) (h₂ : b < c) (h₃ : c ≤ d) : a + e ≤ d + e := by grw [h₂, h₃] at h₁ - guard_hyp h₁ :ₛ a + e ≤ d + e - exact h₁ + guard_hyp h₁ :ₛ a + e < d + e + exact le_of_lt h₁ example (f g : α → α) (h : ∀ x : α, f x ≤ g x) (h₂ : g a + g b ≤ 5) : f a + f b ≤ 5 := by grw [h] @@ -84,15 +84,9 @@ example (h₁ : a ≤ b) : a * c ≤ b * c := by guard_target =ₛ 0 ≤ c exact test_sorry -/- This example has behaviour which might be weaker than some users would desire: it would be -mathematically sound to transform the goal here to `2 * y ≤ z`, not `2 * y < z`. - -However, the current behavior is easier to implement, and preserves the form of the goal (`?_ < z`), -which is a useful invariant. -/ example {x y z : ℤ} (hx : x < y) : 2 * x < z := by grw [hx] - fail_if_success guard_target =ₛ 2 * y < z - guard_target = 2 * y < z + guard_target = 2 * y ≤ z exact test_sorry end inequalities @@ -126,11 +120,11 @@ a b : ℕ h : a < b f : ℕ → ℕ hf : ∀ (i : ℕ), 0 ≤ f i -⊢ ∑ i ∈ {a | a ≤ b}.toFinset, f i ≤ ∑ i ∈ {x | x ≤ b}.toFinset, f i +⊢ ∑ i ∈ {a | a < b}.toFinset, f i ≤ ∑ i ∈ {x | x < b}.toFinset, f i -/ #guard_msgs in example {a b : Nat} (h : a < b) (f : Nat → Nat) (hf : ∀ i, 0 ≤ f i) : - ∑ j ∈ ({z | z ≤ a} : Set Nat), f j ≤ ∑ i ∈ ({x | x ≤ b} : Set Nat), f i := by + ∑ j ∈ ({z | z ≤ a} : Set Nat), f j ≤ ∑ i ∈ ({x | x < b} : Set Nat), f i := by grewrite [h] trace_state rfl @@ -142,7 +136,7 @@ section rationals example (x x' y z w : ℚ) (h0 : x' = x) (h₁ : x < z) (h₂ : w ≤ y + 4) (h₃ : z + 1 < 5 * w) : x' + 1 < 5 * (y + 4) := by grw [h0, h₁, ← h₂] - exact h₃ + exact le_of_lt h₃ example {x y z : ℚ} (f g : ℚ → ℚ) (h : ∀ t, f t = g t) : 2 * f x * f y * f x ≤ z := by grw [h] @@ -201,7 +195,7 @@ example {a b : ℤ} (h1 : a ≡ 3 [ZMOD 5]) (h2 : b ≡ a ^ 2 + 1 [ZMOD 5]) : example {x y a b : ℚ} (h : x < y) (h1 : a ≤ 3 * x) : 2 * x ≤ b := by grw [h] at * guard_hyp h :ₛ x < y -- `grw [h] at *` does not rewrite at `h` - guard_hyp h1 : a ≤ 3 * y + guard_hyp h1 : a < 3 * y guard_target = 2 * y ≤ b exact test_sorry @@ -344,7 +338,7 @@ example : ∃ n, n < 2 := by refine ⟨?_, ?_⟩ on_goal 2 => grw [← one_lt_two] exact 0 - refine zero_lt_one + refine zero_le_one section zmod @@ -454,3 +448,55 @@ example {a b c d e f g h i j k : Rat} : a * b * c * d * e * f * g * h * i * j * exact test_sorry end cache + +section strict + +variable {α : Type u} [LinearOrder α] {a b c d : α} + +example (h₁ : a < b) (h₂ : b ≤ c) : a < c := by + grw [h₁, h₂] + +example (h₁ : a < b) (h₂ : b ≤ c) : a < c := by + grw [← h₂, ← h₁] + +example (h₁ : a ≤ b) (h₂ : b < c) : a < c := by + grw [h₁, h₂] + +example (h₁ : a ≤ b) (h₂ : b < c) : a < c := by + grw [← h₂, ← h₁] + +example (h₁ : a < b) (h₂ : b ≤ c) : a < c := by + by_contra!; grw [h₁, h₂] at this; contrapose! this; rfl + +example (h₁ : a < b) (h₂ : b ≤ c) : a < c := by + by_contra!; grw [← h₂, ← h₁] at this; contrapose! this; rfl + +example (h₁ : a ≤ b) (h₂ : b < c) : a < c := by + by_contra!; grw [h₁, h₂] at this; contrapose! this; rfl + +example (h₁ : a ≤ b) (h₂ : b < c) : a < c := by + by_contra!; grw [← h₂, ← h₁] at this; contrapose! this; rfl + +-- Strict inequalities can also be used as non-strict ones: +example (h₁ : a < b) (h₂ : b < c) : a ≤ c := by + grw [h₁, h₂] + +variable [CommRing α] [IsStrictOrderedRing α] in +example (h : a < b) (_ : 0 ≤ a) : 1 + 2 * a ^ 2 < 9 := by + grw [h] + guard_target = 1 + 2 * b ^ 2 ≤ 9 + exact test_sorry + +example (h₁ : a < b) (h₂ : c < d) : Set.Icc b c ⊆ Set.Ioo a d := by + grw [h₁, h₂] + +example (h₁ : a < b) (h₂ : c < d) : Set.Icc b c ⊆ Set.Ioo a d := by + grw [h₂, h₁] + +example (h₁ : a < b) : Set.Iic a ⊆ Set.Iio b := by + grw [h₁] + +example (h₁ : a < b) : Set.Ici b ⊆ Set.Ioi a := by + grw [h₁] + +end strict From 05742115c13f3a461ea7b6f07afa80f99dfb1531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= <4094732+RemyDegenne@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:44:09 +0000 Subject: [PATCH 0552/1300] chore: generalize `instPosPart` to SubNegMonoid (#41247) This PR generalizes the `OneLePart` and `LeOnePart` instances to `DivInvMonoid` instead of `Group`, and similarly for their additive versions. My goal is to have `PosPart` for `EReal`. Co-authored-by: Remy Degenne --- Mathlib/Algebra/Order/Group/PosPart.lean | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/Order/Group/PosPart.lean b/Mathlib/Algebra/Order/Group/PosPart.lean index 384a848a2ec75d..6f94e2f0ebf43a 100644 --- a/Mathlib/Algebra/Order/Group/PosPart.lean +++ b/Mathlib/Algebra/Order/Group/PosPart.lean @@ -46,8 +46,8 @@ variable {α : Type*} section Lattice variable [Lattice α] -section Group -variable [Group α] {a b : α} +section DivInvMonoid +variable [DivInvMonoid α] {a b : α} /-- The *positive part* of an element `a` in a lattice ordered group is `a ⊔ 1`, denoted `a⁺ᵐ`. -/ @[to_additive @@ -72,11 +72,11 @@ instance instLeOnePart : LeOnePart α where @[to_additive (attr := simp high)] lemma oneLePart_one : (1 : α)⁺ᵐ = 1 := sup_idem _ -@[to_additive (attr := simp)] lemma leOnePart_one : (1 : α)⁻ᵐ = 1 := by simp [leOnePart] - -@[to_additive posPart_nonneg] lemma one_le_oneLePart (a : α) : 1 ≤ a⁺ᵐ := le_sup_right +@[to_additive (attr := simp) posPart_nonneg] +lemma one_le_oneLePart (a : α) : 1 ≤ a⁺ᵐ := le_sup_right -@[to_additive negPart_nonneg] lemma one_le_leOnePart (a : α) : 1 ≤ a⁻ᵐ := le_sup_right +@[to_additive (attr := simp) negPart_nonneg] +lemma one_le_leOnePart (a : α) : 1 ≤ a⁻ᵐ := le_sup_right -- TODO: `to_additive` guesses `nonposPart` @[to_additive le_posPart] lemma le_oneLePart (a : α) : a ≤ a⁺ᵐ := le_sup_left @@ -108,12 +108,19 @@ lemma leOnePart_le_one' : a⁻ᵐ ≤ 1 ↔ a⁻¹ ≤ 1 := by simp [leOnePart] @[to_additive (attr := simp)] lemma oneLePart_inv (a : α) : a⁻¹⁺ᵐ = a⁻ᵐ := rfl -@[to_additive (attr := simp)] lemma leOnePart_inv (a : α) : a⁻¹⁻ᵐ = a⁺ᵐ := by - simp [oneLePart, leOnePart] - @[to_additive] lemma oneLePart_max (a b : α) : (max a b)⁺ᵐ = max a⁺ᵐ b⁺ᵐ := by simp [oneLePart, sup_sup_distrib_right] +end DivInvMonoid + +section Group +variable [Group α] {a b : α} + +@[to_additive (attr := simp)] lemma leOnePart_one : (1 : α)⁻ᵐ = 1 := by simp [leOnePart] + +@[to_additive (attr := simp)] lemma leOnePart_inv (a : α) : a⁻¹⁻ᵐ = a⁺ᵐ := by + simp [oneLePart, leOnePart] + section MulLeftMono variable [MulLeftMono α] From d530c3afdcda4ac38c10f6fec4556806d91e29a0 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:44:12 +0000 Subject: [PATCH 0553/1300] chore(LinearAlgebra/Matrix/Nondegenerate): generalize lemmas to CommSemiring (#41271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR generalizes the `SeparatingLeft`/`SeparatingRight`/`Nondegenerate` lemmas from `CommRing` to `CommSemiring` (the determinant section keeps `CommRing`), and golfs `nondegenerate_def` using the `@[mk_iff]`-generated `nondegenerate_iff`. Follow-up to https://github.com/leanprover-community/mathlib4/pull/39634, which generalized the definitions but left the lemmas at `CommRing`. 🤖 Prepared with Claude Code --- Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean index ef2b5bee37197c..3a8f262c4f5e2f 100644 --- a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean @@ -46,7 +46,9 @@ structure Nondegenerate (M : Matrix m n R) : Prop where end Finite -variable {m n R : Type*} [CommRing R] {M : Matrix m n R} +section CommSemiring + +variable {m n R : Type*} [CommSemiring R] {M : Matrix m n R} lemma separatingRight_def [Fintype m] [Fintype n] : M.SeparatingRight ↔ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0) → w = 0) := by @@ -61,9 +63,7 @@ lemma separatingLeft_def [Fintype m] [Fintype n] : lemma nondegenerate_def [Fintype m] [Fintype n] : M.Nondegenerate ↔ (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) ∧ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0) → w = 0) := by - constructor - · exact fun h ↦ ⟨separatingLeft_def.mp h.1, separatingRight_def.mp h.2⟩ - · exact fun h ↦ ⟨separatingLeft_def.mpr h.1, separatingRight_def.mpr h.2⟩ + rw [nondegenerate_iff, separatingLeft_def, separatingRight_def] theorem separatingLeft_iff_forall_vecMul_eq_zero [Fintype m] [Finite n] : M.SeparatingLeft ↔ ∀ v, v ᵥ* M = 0 → v = 0 := by @@ -140,8 +140,10 @@ theorem Nondegenerate.exists_not_ortho_of_ne_zero' (hM : Nondegenerate M) {w : n ∃ v, v ⬝ᵥ M *ᵥ w ≠ 0 := not_forall.mp (mt hM.eq_zero_of_ortho' hw) +end CommSemiring + section Determinant -variable [DecidableEq m] {M : Matrix m m R} +variable {m R : Type*} [CommRing R] [Fintype m] [DecidableEq m] {M : Matrix m m R} open scoped nonZeroDivisors From 6620bef8f0671aa4d2827604649f6475fe4ba9ba Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:39:26 +0000 Subject: [PATCH 0554/1300] feat(AlgebraicGeometry): Order of vanishing of elements of the function field of locally noetherian, integral schemes (#29774) In this PR, we define the order of vanishing of elements of the function field of locally noetherian, integral schemes at points of codimension 1. This is essentially just a wrapper around the API for the order of vanishing for rings (i.e. Ring.ord and Ring.ordFrac), but I think it's good to have this too for usability. Co-authored-by: Raph-DG --- Mathlib.lean | 1 + Mathlib/Algebra/Group/WithOne/Defs.lean | 38 ++++- .../Order/GroupWithZero/Canonical.lean | 52 +++++++ Mathlib/AlgebraicGeometry/FunctionField.lean | 30 ++++ .../AlgebraicGeometry/OrderOfVanishing.lean | 135 ++++++++++++++++++ Mathlib/AlgebraicGeometry/Properties.lean | 7 + Mathlib/Tactic/Translate/ToAdditive.lean | 4 +- Mathlib/Topology/Sheaves/Stalks.lean | 1 + 8 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 Mathlib/AlgebraicGeometry/OrderOfVanishing.lean diff --git a/Mathlib.lean b/Mathlib.lean index abe373aae11031..7a0a0bf5b574fe 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1442,6 +1442,7 @@ public import Mathlib.AlgebraicGeometry.Morphisms.WeaklyEtale public import Mathlib.AlgebraicGeometry.Noetherian public import Mathlib.AlgebraicGeometry.Normalization public import Mathlib.AlgebraicGeometry.OpenImmersion +public import Mathlib.AlgebraicGeometry.OrderOfVanishing public import Mathlib.AlgebraicGeometry.Over public import Mathlib.AlgebraicGeometry.PointsPi public import Mathlib.AlgebraicGeometry.ProjectiveSpectrum.Basic diff --git a/Mathlib/Algebra/Group/WithOne/Defs.lean b/Mathlib/Algebra/Group/WithOne/Defs.lean index 188f0777955777..b61d5187b8f4a6 100644 --- a/Mathlib/Algebra/Group/WithOne/Defs.lean +++ b/Mathlib/Algebra/Group/WithOne/Defs.lean @@ -125,15 +125,15 @@ lemma recOneCoe_coe {motive : WithOne α → Sort*} (h₁ h₂) (a : α) : rfl /-- Deconstruct an `x : WithOne α` to the underlying value in `α`, given a proof that `x ≠ 1`. -/ -@[to_additive unzero +@[to_additive /-- Deconstruct an `x : WithZero α` to the underlying value in `α`, given a proof that `x ≠ 0`. -/] def unone : ∀ {x : WithOne α}, x ≠ 1 → α | (x : α), _ => x -@[to_additive (attr := simp) unzero_coe] +@[to_additive (attr := simp)] theorem unone_coe {x : α} (hx : (x : WithOne α) ≠ 1) : unone hx = x := rfl -@[to_additive (attr := simp) coe_unzero] +@[to_additive (attr := simp)] lemma coe_unone : ∀ {x : WithOne α} (hx : x ≠ 1), unone hx = x | (x : α), _ => rfl @@ -194,4 +194,36 @@ instance instCommMonoid [CommSemigroup α] : CommMonoid (WithOne α) where theorem coe_inv [Inv α] (a : α) : ((a⁻¹ : α) : WithOne α) = (a : WithOne α)⁻¹ := rfl +/-- +Specialization of `Option.getD` to values in `WithOne α` that respects API boundaries. +-/ +@[to_additive + /-- Specialization of `Option.getD` to values in `WithZero α` that respects API boundaries. -/] +def unoneD (d : α) (x : WithOne α) : α := recOneCoe d id x + +@[to_additive (attr := simp)] +theorem unoneD_one (d : α) : unoneD d 1 = d := + rfl + +@[to_additive (attr := simp)] +theorem unoneD_coe (d x : α) : unoneD d x = x := + rfl + +@[to_additive] +theorem unoneD_eq_iff {d y : α} {x : WithOne α} : unoneD d x = y ↔ x = y ∨ x = 1 ∧ y = d := by + induction x <;> simp [@eq_comm _ d] + +@[to_additive (attr := simp)] +theorem unoneD_eq_self_iff {d : α} {x : WithOne α} : unoneD d x = d ↔ x = d ∨ x = 1 := by + simp [unoneD_eq_iff] + +@[to_additive] +theorem unoneD_eq_unoneD_iff {d : α} {x y : WithOne α} : + unoneD d x = unoneD d y ↔ x = y ∨ x = d ∧ y = 1 ∨ x = 1 ∧ y = d := by + induction y <;> simp [unoneD_eq_iff, or_comm] + +@[to_additive] +lemma unoneD_eq_unone {d : α} {x : WithOne α} (hx : x ≠ 1) : unoneD d x = unone hx := by + simp [unoneD_eq_iff] + end WithOne diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 94095610485d23..44aff65f23f2b0 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -386,6 +386,10 @@ theorem le_ofAdd_iff a ≤ ofAdd b ↔ toAdd (unzero ha) ≤ b := ⟨toAdd_unzero_le_of_lt_ofAdd ha, le_ofAdd_of_toAdd_unzero_le ha⟩ +lemma toAdd_unzero_eq_iff {α : Type*} {a : WithZero (Multiplicative α)} (h : a ≠ 0) + (b : α) : (WithZero.unzero h).toAdd = b ↔ a = Multiplicative.ofAdd b := + ⟨fun k ↦ by subst k; exact (coe_unzero h).symm, fun k ↦ by subst k; rfl⟩ + end Multiplicative end Preorder @@ -601,4 +605,52 @@ lemma le_exp_log {x : Gᵐ⁰} : · simp · rfl +section LE + +-- This section is not generated by `to_additive` because `WithOne` does not have a `LE` instance. + +variable [LE α] {x y : WithZero α} {a b : α} + +lemma le_unzeroD_iff (hx : x ≠ 0) : b ≤ x.unzeroD a ↔ b ≤ x := by + lift x to α using hx; simp + +lemma unzeroD_le_iff (hx : x = 0 → a ≤ b) : x.unzeroD a ≤ b ↔ x ≤ b := by + cases x <;> simp [hx] + +lemma unzeroD_mono (hx : x ≠ 0) (h : x ≤ y) : x.unzeroD a ≤ y.unzeroD a := by + lift x to α using hx + cases y <;> simp_all + +end LE + +section LT + +variable [LT α] {x y : WithZero α} {a b : α} + +lemma lt_unzeroD_iff (hx : x ≠ 0) : b < x.unzeroD a ↔ b < x := by + lift x to α using hx; simp + +lemma unzeroD_lt_iff (hx : x = 0 → a < b) : x.unzeroD a < b ↔ x < b := by + cases x <;> simp [hx] + +end LT + +section Preorder + +variable [Preorder α] {x y : WithZero α} {a b : α} + +theorem le_coe_unzeroD (x : WithZero α) (b : α) : x ≤ x.unzeroD b := by cases x <;> simp + +end Preorder + +section PartialOrder + +variable [PartialOrder α] {x y : WithZero α} {a b : α} + +lemma le_unzeroD (hy : b ≤ y) : b ≤ y.unzeroD a := by + have hne : y ≠ 0 := ne_bot_of_le_ne_bot WithZero.coe_ne_zero hy + rwa [le_unzeroD_iff hne] + +end PartialOrder + end WithZero diff --git a/Mathlib/AlgebraicGeometry/FunctionField.lean b/Mathlib/AlgebraicGeometry/FunctionField.lean index 04b8ec01e7439f..0c18e17f26aaf6 100644 --- a/Mathlib/AlgebraicGeometry/FunctionField.lean +++ b/Mathlib/AlgebraicGeometry/FunctionField.lean @@ -91,6 +91,13 @@ instance functionField_isScalarTower [IrreducibleSpace X] (U : X.Opens) (x : U) change _ = (X.presheaf.germ U x x.2 ≫ _).hom rw [X.presheaf.germ_stalkSpecializes] +@[simp] +lemma Scheme.algebraMap_germ_eq_germToFunctionField [IrreducibleSpace X] + {U : X.Opens} [Nonempty U] {x : X} (hx : x ∈ U) (f : Γ(X, U)) : + algebraMap (X.presheaf.stalk x) X.functionField (X.presheaf.germ U x hx f) = + X.germToFunctionField U f := by + simp [RingHom.algebraMap_toAlgebra, ← ConcreteCategory.comp_apply] + noncomputable instance (R : CommRingCat.{u}) [IsDomain R] : Algebra R (Spec R).functionField := -- TODO: can we write this normally after the refactor finishes? @@ -171,4 +178,27 @@ instance [IsIntegral X] (x : X) : instance [IsIntegral X] {x : X} : IsDomain (X.presheaf.stalk x) := Function.Injective.isDomain _ (IsFractionRing.injective (X.presheaf.stalk x) (X.functionField)) +/-- +For `f` an element of the function field of `X`, there exists some open set `U ⊆ X` such that +`f` is a unit in `Γ(X, U)`. +-/ +lemma exists_isUnit_germ_eq [IsIntegral X] (f : X.functionField) (hf : f ≠ 0) : + ∃ U ∈ X.affineOpens, ∃ f' : Γ(X, U), ∃ _ : Nonempty U, + X.germToFunctionField U f' = f ∧ IsUnit f' := by + obtain ⟨U, hU, g, hg⟩ := X.presheaf.exists_germ_eq f + obtain ⟨_, ⟨A, hA, rfl⟩, hxA, hAU⟩ := + X.isBasis_affineOpens.exists_subset_of_mem_open hU U.isOpen + have : Nonempty A := ⟨_, hxA⟩ + let gA : Γ(X, A) := X.presheaf.map (homOfLE hAU).op g + have h_germ_gA : X.presheaf.germ A (genericPoint X) hxA gA = f := by + simp only [← hg, ← X.presheaf.germ_res_apply (homOfLE hAU) (genericPoint X) hxA g, gA] + rfl + have hxV : genericPoint X ∈ X.basicOpen gA := by + rwa [Scheme.mem_basicOpen X gA (genericPoint X) hxA, h_germ_gA, isUnit_iff_ne_zero] + have : Nonempty (X.basicOpen gA) := ⟨⟨_, hxV⟩⟩ + refine ⟨X.basicOpen gA, hA.basicOpen gA, + X.presheaf.map (X.basicOpen_le gA).hom.op gA, ‹_›, ?_, + X.toRingedSpace.isUnit_res_basicOpen gA⟩ + simpa using h_germ_gA + end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean b/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean new file mode 100644 index 00000000000000..3fb564c22a695d --- /dev/null +++ b/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean @@ -0,0 +1,135 @@ +/- +Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Raphael Douglas Giles +-/ +module + +public import Mathlib.AlgebraicGeometry.FunctionField +public import Mathlib.AlgebraicGeometry.Noetherian +public import Mathlib.RingTheory.OrderOfVanishing.Noetherian + +/-! +# Order of vanishing in a scheme + +In this file we define the order of vanishing of an element of the function field of a locally +Noetherian integral scheme at a point of codimension `1`. +-/ + +@[expose] public section + +open WithZero AlgebraicGeometry Order TopologicalSpace CategoryTheory + +universe u + +variable {X : Scheme.{u}} + +namespace AlgebraicGeometry.Scheme + +variable [IsIntegral X] [IsLocallyNoetherian X] + +/-- +Order of vanishing on a locally Noetherian integral scheme as a monoid with zero hom to `ℤᵐ⁰`. +-/ +noncomputable +def ordHom (z : X) (hz : coheight z = 1) : X.functionField →*₀ ℤᵐ⁰ := + haveI : Ring.KrullDimLE 1 (X.presheaf.stalk z) := krullDimLE_of_coheight_le hz.le + Ring.ordFrac (X.presheaf.stalk z) + +lemma ordHom_of_isUnit {U : X.Opens} + [Nonempty U] {f : Γ(X, U)} (hf : IsUnit f) {x : X} (hx : coheight x = 1) (hx' : x ∈ U) : + ordHom x hx (X.germToFunctionField U f) = 1 := by + have : Ring.KrullDimLE 1 (X.presheaf.stalk x) := krullDimLE_of_coheight_le hx.le + rw [← algebraMap_germ_eq_germToFunctionField _ hx'] + exact Ring.ordFrac_of_isUnit (hf.map (X.presheaf.germ U x hx').hom) + +/-- +The order of vanishing of an element of the function field of a locally Noetherian integral scheme +at a point. This has a junk value of `0` if `f = 0` or if `coheight z ≠ 1`. +-/ +@[no_expose] +noncomputable +def ord (f : X.functionField) (z : X) : ℤ := + if hz : coheight z = 1 + then Multiplicative.toAdd <| (X.ordHom z hz f).unzeroD 1 + else 0 + +lemma ord_eq_ordHom_of_coheight_eq_one {z : X} (hz : coheight z = 1) (f : X.functionField) : + ord f z = Multiplicative.toAdd ((X.ordHom z hz f).unzeroD 1) := dif_pos hz + +@[simp] +lemma ord_eq_zero_of_coheight_neq_one {z : X} (hz : coheight z ≠ 1) (f : X.functionField) : + ord f z = 0 := dif_neg hz + +@[simp] +lemma ord_zero : ord (0 : X.functionField) = 0 := by + ext z + by_cases h : coheight z = 1 + · simp [ord_eq_ordHom_of_coheight_eq_one h, unzeroD] + · simp [h] + +lemma ord_eq_unzero_ordHom {x : X} (hx : coheight x = 1) {f : X.functionField} (hf : f ≠ 0) : + ord f x = (WithZero.unzero ((map_ne_zero (ordHom x hx)).mpr hf)).toAdd := by + simp [ord, hx, unzeroD_eq_unzero ((map_ne_zero (ordHom x hx)).mpr hf)] + +lemma ord_eq_iff {z : X} (hz : coheight z = 1) {f : X.functionField} (hf : f ≠ 0) {n : ℤ} : + ord f z = n ↔ ordHom z hz f = Multiplicative.ofAdd n := by + rw [ord_eq_unzero_ordHom hz hf] + exact WithZero.toAdd_unzero_eq_iff _ _ + +@[simp] +lemma ord_mul {x : X} {f g : X.functionField} + (hf : f ≠ 0) (hg : g ≠ 0) : ord (f * g) x = ord f x + ord g x := by + by_cases! hx : coheight x ≠ 1 + · simp [hx] + rw [ord_eq_iff hx <| (mul_ne_zero_iff_right hg).mpr hf] + simp [hf, hg, ord_eq_ordHom_of_coheight_eq_one hx, unzeroD_eq_unzero] + +lemma ord_of_isUnit {U : X.Opens} [Nonempty U] {f : Γ(X, U)} (hf : IsUnit f) {x : X} + (hx' : x ∈ U) : ord (X.germToFunctionField U f) x = 0 := by + by_cases! hx : coheight x ≠ 1 + · simp [hx] + simp [map_ne_zero_iff, germToFunctionField_injective, IsUnit.ne_zero hf, + ord_eq_iff hx, ordHom_of_isUnit hf hx hx'] + +lemma ord_le_ord_iff {x y : X} (hx : coheight x = 1) (hy : coheight y = 1) {f g : X.functionField} + (hf : f ≠ 0) (hg : g ≠ 0) : + ord f x ≤ ord g y ↔ ordHom x hx f ≤ ordHom y hy g := by + simp [ord_eq_unzero_ordHom hx hf, ord_eq_unzero_ordHom hy hg, Multiplicative.toAdd_le] + +lemma le_ord_iff {x : X} (hx : coheight x = 1) {f : X.functionField} + (hf : f ≠ 0) {n : ℤ} : + n ≤ ord f x ↔ Multiplicative.ofAdd n ≤ ordHom x hx f := by + rw [ord_eq_unzero_ordHom hx hf] + nth_rw 1 [← toAdd_ofAdd n] + rw [Multiplicative.toAdd_le, le_unzero_iff] + +lemma ord_add {x : X} [IsDiscreteValuationRing (X.presheaf.stalk x)] + {f g : X.functionField} (hfg : f + g ≠ 0) : + min (ord f x) (ord g x) ≤ ord (f + g) x := by + by_cases hf : f = 0 + · simp [hf] + by_cases hg : g = 0 + · simp [hg] + by_cases! hx : coheight x ≠ 1 + · simp [hx] + rw [inf_le_iff, ord_le_ord_iff hx hx hf hfg, ord_le_ord_iff hx hx hg hfg] + exact inf_le_iff.mp <| Ring.ordFrac_add (R := X.presheaf.stalk x) _ _ hfg + +lemma ord_le_smul {x : X} {U : X.Opens} [Nonempty U] (hxU : x ∈ U) + {a : Γ(X, U)} (ha : a ≠ 0) (f : X.functionField) : ord f x ≤ ord (a • f) x := by + by_cases! hx : coheight x ≠ 1 + · simp [hx] + by_cases hf : f = 0 + · simp [hf] + have : a • f ≠ 0 := by simp [ha, Algebra.smul_def, hf, germToFunctionField_injective, + RingHom.algebraMap_toAlgebra, map_ne_zero_iff] + rw [ord_le_ord_iff hx hx hf this] + algebraize [(X.presheaf.germ U x hxU).hom] + have : Ring.KrullDimLE 1 ↑(X.presheaf.stalk x) := krullDimLE_of_coheight_le hx.le + have : IsScalarTower ↑Γ(X, U) ↑(X.presheaf.stalk x) ↑X.functionField := + functionField_isScalarTower X U ⟨x, hxU⟩ + simp [ordHom, Ring.ordFrac_le_smul, RingHom.algebraMap_toAlgebra, map_ne_zero_iff, + germ_injective_of_isIntegral, ha] + +end AlgebraicGeometry.Scheme diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index bd9f2c72578d47..6d7e1302696a37 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -386,6 +386,13 @@ lemma ringKrullDim_stalk_eq_coheight {X : Scheme} (x : X) : apply WithBot.coe_eq_coe.mpr exact idealHeight_eq_coheight R x +open Order in +variable {X} in +lemma krullDimLE_of_coheight_le + {z : X} {n : ℕ} (hz : coheight z ≤ n) : Ring.KrullDimLE n (X.presheaf.stalk z) := by + rw [Ring.krullDimLE_iff, ringKrullDim_stalk_eq_coheight z] + exact_mod_cast hz + lemma isField_of_isIntegral_of_subsingleton (X : Scheme.{u}) [IsIntegral X] [Subsingleton X] : IsField Γ(X, ⊤) := by rw [← PrimeSpectrum.t1Space_iff_isField] diff --git a/Mathlib/Tactic/Translate/ToAdditive.lean b/Mathlib/Tactic/Translate/ToAdditive.lean index 0b1719bb2b5cd6..0a5c69fd01a934 100644 --- a/Mathlib/Tactic/Translate/ToAdditive.lean +++ b/Mathlib/Tactic/Translate/ToAdditive.lean @@ -391,7 +391,9 @@ def abbreviationDict : Std.HashMap String String := .ofList [ ("mapMod", "MapAddMod"), ("modObj", "AddModObj"), ("yonedaMon", "YonedaAddMon"), - ("conGen", "AddConGen")] + ("conGen", "AddConGen"), + ("unoneD", "unzeroD"), + ("unone", "unzero")] @[inherit_doc GuessName.GuessNameExt] initialize guessNameExt : GuessName.GuessNameExt ← diff --git a/Mathlib/Topology/Sheaves/Stalks.lean b/Mathlib/Topology/Sheaves/Stalks.lean index 9403faaec5932e..b700bd02c76c02 100644 --- a/Mathlib/Topology/Sheaves/Stalks.lean +++ b/Mathlib/Topology/Sheaves/Stalks.lean @@ -117,6 +117,7 @@ lemma map_germ_eq_Γgerm (F : X.Presheaf C) {U : Opens X} {i : U ⟶ ⊤} (x : X variable {FC : C → C → Type*} {CC : C → Type*} [∀ X Y, FunLike (FC X Y) (CC X) (CC Y)] +@[simp] theorem germ_res_apply (F : X.Presheaf C) {U V : Opens X} (i : U ⟶ V) (x : X) (hx : x ∈ U) [ConcreteCategory C FC] (s) : F.germ U x hx (F.map i.op s) = F.germ V x (i.le hx) s := by From d1559735ab907f0a1f7a5c28c6ac1826ea0d1d6f Mon Sep 17 00:00:00 2001 From: Li Jiale <185082061+Scarlett-le@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:39:29 +0000 Subject: [PATCH 0555/1300] feat: same/opposite side of an affine subspace from scalar multiples of a common vector (#40245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `sameRay_smul_smul_of_mul_nonneg` to `Mathlib/LinearAlgebra/Ray.lean`: two scalar multiples `c₁ • v` and `c₂ • v` of a common vector lie on a common ray whenever `0 ≤ c₁ * c₂`. Using it, add four lemmas to `Mathlib/Analysis/Convex/Side.lean` giving sufficient conditions for a pair of points to be (weakly/strictly) on the same or opposite side of an affine subspace, from the displacements `x -ᵥ p₁ = c₁ • m` and `y -ᵥ p₂ = c₂ • m`. The sign of `c₁ * c₂` determines same vs opposite side: * `AffineSubspace.wSameSide_of_vsub_eq_smul` / `sSameSide_of_vsub_eq_smul` * `AffineSubspace.wOppSide_of_vsub_eq_smul` / `sOppSide_of_vsub_eq_smul` Co-authored-by: Scarlett-le <735979178@qq.com> --- Mathlib/Analysis/Convex/Side.lean | 40 +++++++++++++++++++++++++++++++ Mathlib/LinearAlgebra/Ray.lean | 13 ++++++++++ 2 files changed, 53 insertions(+) diff --git a/Mathlib/Analysis/Convex/Side.lean b/Mathlib/Analysis/Convex/Side.lean index 000cf596517e4f..6cf3ee3d020915 100644 --- a/Mathlib/Analysis/Convex/Side.lean +++ b/Mathlib/Analysis/Convex/Side.lean @@ -347,6 +347,46 @@ theorem _root_.Wbtw.wOppSide₃₁ {s : AffineSubspace R P} {x y z : P} (h : Wbt end StrictOrderedCommRing +section LinearOrderedCommRing + +variable [CommRing R] [LinearOrder R] [IsStrictOrderedRing R] + [AddCommGroup V] [Module R V] [AddTorsor V P] + +/-- If `x` and `y` are displaced from points of `s` by multiples of a common vector whose +coefficients have nonnegative product, they are weakly on the same side of `s`. -/ +theorem wSameSide_of_vsub_eq_smul {s : AffineSubspace R P} {x y p₁ p₂ : P} {m : V} {c₁ c₂ : R} + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (h₁ : x -ᵥ p₁ = c₁ • m) (h₂ : y -ᵥ p₂ = c₂ • m) + (hc : 0 ≤ c₁ * c₂) : s.WSameSide x y := by + refine ⟨p₁, hp₁, p₂, hp₂, ?_⟩ + rw [h₁, h₂] + exact sameRay_smul_smul_of_mul_nonneg hc + +/-- If `x` and `y` are displaced from points of `s` by multiples of a common vector whose +coefficients have nonpositive product, they are weakly on opposite sides of `s`. -/ +theorem wOppSide_of_vsub_eq_smul {s : AffineSubspace R P} {x y p₁ p₂ : P} {m : V} {c₁ c₂ : R} + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (h₁ : x -ᵥ p₁ = c₁ • m) (h₂ : y -ᵥ p₂ = c₂ • m) + (hc : c₁ * c₂ ≤ 0) : s.WOppSide x y := by + refine ⟨p₁, hp₁, p₂, hp₂, ?_⟩ + have h₂' : p₂ -ᵥ y = (-c₂) • m := by rw [← neg_vsub_eq_vsub_rev, h₂, neg_smul] + rw [h₁, h₂'] + exact sameRay_smul_smul_of_mul_nonneg (by rw [mul_neg]; exact neg_nonneg.2 hc) + +/-- If `x` and `y` lie off `s` and are displaced from points of `s` by multiples of a common +vector whose coefficients have nonnegative product, they are strictly on the same side of `s`. -/ +theorem sSameSide_of_vsub_eq_smul {s : AffineSubspace R P} {x y p₁ p₂ : P} {m : V} {c₁ c₂ : R} + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (h₁ : x -ᵥ p₁ = c₁ • m) (h₂ : y -ᵥ p₂ = c₂ • m) + (hc : 0 ≤ c₁ * c₂) (hx : x ∉ s) (hy : y ∉ s) : s.SSameSide x y := + ⟨wSameSide_of_vsub_eq_smul hp₁ hp₂ h₁ h₂ hc, hx, hy⟩ + +/-- If `x` and `y` lie off `s` and are displaced from points of `s` by multiples of a common +vector whose coefficients have nonpositive product, they are strictly on opposite sides of `s`. -/ +theorem sOppSide_of_vsub_eq_smul {s : AffineSubspace R P} {x y p₁ p₂ : P} {m : V} {c₁ c₂ : R} + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (h₁ : x -ᵥ p₁ = c₁ • m) (h₂ : y -ᵥ p₂ = c₂ • m) + (hc : c₁ * c₂ ≤ 0) (hx : x ∉ s) (hy : y ∉ s) : s.SOppSide x y := + ⟨wOppSide_of_vsub_eq_smul hp₁ hp₂ h₁ h₂ hc, hx, hy⟩ + +end LinearOrderedCommRing + section LinearOrderedField variable [Field R] [LinearOrder R] [IsStrictOrderedRing R] diff --git a/Mathlib/LinearAlgebra/Ray.lean b/Mathlib/LinearAlgebra/Ray.lean index e857c07e686827..9e85bdedf8806f 100644 --- a/Mathlib/LinearAlgebra/Ray.lean +++ b/Mathlib/LinearAlgebra/Ray.lean @@ -464,6 +464,19 @@ theorem units_inv_smul (u : Rˣ) (v : Module.Ray R M) : u⁻¹ • v = u • v : u⁻¹ • v = (u * u) • u⁻¹ • v := Eq.symm <| (u⁻¹ • v).units_smul_of_pos _ (by exact this) _ = u • v := by rw [mul_smul, smul_inv_smul] +/-- Two scalar multiples of a common vector whose coefficients have nonnegative product +lie on a common ray. -/ +theorem sameRay_smul_smul_of_mul_nonneg {v : M} {c₁ c₂ : R} (h : 0 ≤ c₁ * c₂) : + SameRay R (c₁ • v) (c₂ • v) := by + rcases eq_or_ne c₁ 0 with hc₁ | hc₁ + · rw [hc₁, zero_smul]; exact SameRay.zero_left _ + rcases eq_or_ne c₂ 0 with hc₂ | hc₂ + · rw [hc₂, zero_smul]; exact SameRay.zero_right _ + have hpos : 0 < c₁ * c₂ := h.lt_of_ne (mul_ne_zero hc₁ hc₂).symm + rcases mul_pos_iff.mp hpos with ⟨h₁, h₂⟩ | ⟨h₁, h₂⟩ + · exact Or.inr (Or.inr ⟨c₂, c₁, h₂, h₁, by module⟩) + · exact Or.inr (Or.inr ⟨-c₂, -c₁, neg_pos.2 h₂, neg_pos.2 h₁, by module⟩) + section variable [IsTorsionFree R M] From e653de1ef841324b650fee5424cdeaa7f23faa85 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 2 Jul 2026 16:39:32 +0000 Subject: [PATCH 0556/1300] chore: cleanup API around LinearMap.injective_domRestrict_iff (#41229) * Use `Disjoint` in [LinearMap.injective_domRestrict_iff](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Module/Submodule/Ker.html#LinearMap.injective_domRestrict_iff), and simplify the proof greatly. * Allow linear maps between two different spaces in [LinearMap.injective_restrict_iff_disjoint](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Module/Submodule/Ker.html#LinearMap.injective_restrict_iff_disjoint), and rename it to `LinearMap.injective_restrict_iff` for consistency with the former * Add `LinearMap.injective_codRestrict_iff` for completeness Co-authored-by: @JonBannon --- Mathlib/Algebra/Module/Submodule/Ker.lean | 32 +++++++++---------- Mathlib/Data/Subtype.lean | 4 +++ .../LinearAlgebra/Dimension/RankNullity.lean | 2 +- .../FiniteDimensional/Basic.lean | 2 +- .../Measure/Haar/Disintegration.lean | 2 +- Mathlib/RingTheory/Noetherian/Basic.lean | 2 +- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/Ker.lean b/Mathlib/Algebra/Module/Submodule/Ker.lean index 876ecf85efa630..d052a15cceb08c 100644 --- a/Mathlib/Algebra/Module/Submodule/Ker.lean +++ b/Mathlib/Algebra/Module/Submodule/Ker.lean @@ -197,23 +197,21 @@ theorem ker_eq_bot {f : M →ₛₗ[τ₁₂] M₂} : ker f = ⊥ ↔ Injective alias _root_.LinearMapClass.ker_eq_bot := ker_eq_bot @[simp] lemma injective_domRestrict_iff {f : M →ₛₗ[τ₁₂] M₂} {S : Submodule R M} : - Injective (f.domRestrict S) ↔ S ⊓ LinearMap.ker f = ⊥ := by - rw [← LinearMap.ker_eq_bot] - refine ⟨fun h ↦ le_bot_iff.1 ?_, fun h ↦ le_bot_iff.1 ?_⟩ - · intro x ⟨hx, h'x⟩ - have : ⟨x, hx⟩ ∈ LinearMap.ker (LinearMap.domRestrict f S) := by simpa using h'x - rw [h] at this - simpa [mk_eq_zero] using this - · rintro ⟨x, hx⟩ h'x - have : x ∈ S ⊓ LinearMap.ker f := ⟨hx, h'x⟩ - rw [h] at this - simpa [mk_eq_zero] using this - -@[simp] theorem injective_restrict_iff_disjoint {p : Submodule R M} {f : M →ₗ[R] M} - (hf : ∀ x ∈ p, f x ∈ p) : - Injective (f.restrict hf) ↔ Disjoint p (ker f) := by - rw [← ker_eq_bot, ker_restrict hf, ← ker_domRestrict, ker_eq_bot, injective_domRestrict_iff, - disjoint_iff] + Injective (f.domRestrict S) ↔ Disjoint S f.ker := by + simp [← ker_eq_bot, ker_domRestrict, disjoint_iff_comap_eq_bot] + +@[simp] +theorem injective_restrict_iff {p : Submodule R M} {q : Submodule R₂ M₂} {f : M →ₛₗ[τ₁₂] M₂} + (hf : ∀ x ∈ p, f x ∈ q) : Injective (f.restrict hf) ↔ Disjoint p (ker f) := by + simp [← ker_eq_bot, ker_restrict, disjoint_iff_comap_eq_bot] + +@[deprecated (since := "2026-07-01")] +alias injective_restrict_iff_disjoint := injective_restrict_iff + +@[simp] +theorem injective_codRestrict_iff {q : Submodule R₂ M₂} {f : M →ₛₗ[τ₁₂] M₂} + (hf : ∀ x, f x ∈ q) : Injective (f.codRestrict q hf) ↔ Injective f := + Set.injective_codRestrict _ end Ring diff --git a/Mathlib/Data/Subtype.lean b/Mathlib/Data/Subtype.lean index 84c50fde8f3a6a..abce50412ff816 100644 --- a/Mathlib/Data/Subtype.lean +++ b/Mathlib/Data/Subtype.lean @@ -135,6 +135,10 @@ def coind {α β} (f : α → β) {p : β → Prop} (h : ∀ a, p (f a)) : α theorem coind_injective {α β} {f : α → β} {p : β → Prop} (h : ∀ a, p (f a)) (hf : Injective f) : Injective (coind f h) := fun x y hxy ↦ hf <| by apply congr_arg Subtype.val hxy +@[simp] theorem coind_injective_iff {α β} {f : α → β} {p : β → Prop} (h : ∀ a, p (f a)) : + Injective (coind f h) ↔ Injective f := + ⟨Subtype.coe_injective.comp, coind_injective h⟩ + /-- Restriction of a function to a function on subtypes. -/ @[simps] def map {p : α → Prop} {q : β → Prop} (f : α → β) (h : ∀ a, p a → q (f a)) : diff --git a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean index 9f6f1ba0053b2f..1d820f2b0b100c 100644 --- a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean +++ b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean @@ -260,7 +260,7 @@ lemma Submodule.disjoint_ker_of_finrank_le [IsDomain R] [IsTorsionFree R M] {N : [AddCommGroup N] [Module R N] {L : Submodule R M} [Module.Finite R L] (f : M →ₗ[R] N) (h : finrank R L ≤ finrank R (L.map f)) : Disjoint L (LinearMap.ker f) := by - refine disjoint_iff.mpr <| LinearMap.injective_domRestrict_iff.mp <| LinearMap.ker_eq_bot.mp <| + refine LinearMap.injective_domRestrict_iff.mp <| LinearMap.ker_eq_bot.mp <| Submodule.rank_eq_zero.mp ?_ rw [← Submodule.finrank_eq_rank, Nat.cast_eq_zero] rw [← LinearMap.range_domRestrict] at h diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index 6c211003650168..b948b99d513e9d 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -383,7 +383,7 @@ theorem comap_eq_sup_ker_of_disjoint {p : Submodule K V} [FiniteDimensional K p] p.comap f = p ⊔ ker f := by refine le_antisymm (fun x hx ↦ ?_) (sup_le_iff.mpr ⟨h, ker_le_comap _⟩) obtain ⟨⟨y, hy⟩, hxy⟩ := - surjective_of_injective ((injective_restrict_iff_disjoint h).mpr h') ⟨f x, hx⟩ + surjective_of_injective ((injective_restrict_iff h).mpr h') ⟨f x, hx⟩ replace hxy : f y = f x := by simpa [Subtype.ext_iff] using hxy exact Submodule.mem_sup.mpr ⟨y, hy, x - y, by simp [hxy], add_sub_cancel y x⟩ diff --git a/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean b/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean index db49d722bf57cf..02e80e2e752add 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Disintegration.lean @@ -63,7 +63,7 @@ theorem LinearMap.exists_map_addHaar_eq_smul_addHaar' (h : Function.Surjective L let P : S × T →ₗ[𝕜] T := LinearMap.snd 𝕜 S T have P_cont : Continuous P := LinearMap.continuous_of_finiteDimensional _ have I : Function.Bijective (LinearMap.domRestrict L T) := - ⟨LinearMap.injective_domRestrict_iff.2 (IsCompl.inf_eq_bot hT.symm), + ⟨LinearMap.injective_domRestrict_iff.2 hT.disjoint.symm, (LinearMap.surjective_domRestrict_iff h).2 hT.symm.codisjoint⟩ let L' : T ≃ₗ[𝕜] F := LinearEquiv.ofBijective (LinearMap.domRestrict L T) I have L'_cont : Continuous L' := LinearMap.continuous_of_finiteDimensional _ diff --git a/Mathlib/RingTheory/Noetherian/Basic.lean b/Mathlib/RingTheory/Noetherian/Basic.lean index 324118d0f9e31a..e2457ce2c3363d 100644 --- a/Mathlib/RingTheory/Noetherian/Basic.lean +++ b/Mathlib/RingTheory/Noetherian/Basic.lean @@ -386,7 +386,7 @@ lemma FG.of_le [IsNoetherianRing R] {S T : Submodule R M} (hT : T.FG) (hST : S See also `Submodule.CoFG.fg_of_disjoint`. -/ theorem FG.of_disjoint_of_isNoetherian_quotient {S T : Submodule R M} [IsNoetherian R (M ⧸ T)] (hST : Disjoint S T) : S.FG := - Module.Finite.iff_fg.mp <| .of_injective (T.mkQ.domRestrict S) (by simp [hST.eq_bot]) + Module.Finite.iff_fg.mp <| .of_injective (T.mkQ.domRestrict S) (by simp [hST]) end Submodule From 53781e1df46ee23e5b891c071f42346bf12fa070 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:39:34 +0000 Subject: [PATCH 0557/1300] chore(CategoryTheory/Adjunction/Basic): `to_dual` for `Adjunction.comp` (#41296) This PR tags `Adjunction.comp` with `to_dual`, which is now possible thanks to #40493. --- Mathlib/CategoryTheory/Adjunction/Basic.lean | 11 +++++------ Mathlib/CategoryTheory/Adjunction/Mates.lean | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Adjunction/Basic.lean index 6a55b63965bfc6..4ad3606f6184e9 100644 --- a/Mathlib/CategoryTheory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Adjunction/Basic.lean @@ -575,12 +575,12 @@ def compUliftCoyonedaIso (adj : F ⊣ G) : section -variable {E : Type u₃} [ℰ : Category.{v₃} E] {H : D ⥤ E} {I : E ⥤ D} +variable {E : Type u₃} [Category.{v₃} E] {F : C ⥤ D} {G : D ⥤ C} {H : D ⥤ E} {I : E ⥤ D} (adj₁ : F ⊣ G) (adj₂ : H ⊣ I) set_option backward.isDefEq.respectTransparency false in /-- Composition of adjunctions. -/ -@[simps! -isSimp unit counit, stacks 0DV0] +@[to_dual self (reorder := C E, 2 6, F I, G H, adj₁ adj₂), simps! -isSimp unit counit, stacks 0DV0] def comp : F ⋙ H ⊣ I ⋙ G := mk' { homEquiv := fun _ _ ↦ Equiv.trans (adj₂.homEquiv _ _) (adj₁.homEquiv _ _) @@ -589,13 +589,12 @@ def comp : F ⋙ H ⊣ I ⋙ G := counit := (associator _ _ _).inv ≫ whiskerRight ((associator _ _ _).hom ≫ whiskerLeft _ adj₁.counit ≫ I.rightUnitor.hom) _ ≫ adj₂.counit } -@[simp, reassoc] -lemma comp_unit_app (X : C) : +lemma comp_unit_app (X : C) : dsimp% (adj₁.comp adj₂).unit.app X = adj₁.unit.app X ≫ G.map (adj₂.unit.app (F.obj X)) := by simp [Adjunction.comp] -@[simp, reassoc] -lemma comp_counit_app (X : E) : +@[to_dual existing (attr := simp, reassoc) comp_unit_app] +lemma comp_counit_app (X : E) : dsimp% (adj₁.comp adj₂).counit.app X = H.map (adj₁.counit.app (I.obj X)) ≫ adj₂.counit.app X := by simp [Adjunction.comp] diff --git a/Mathlib/CategoryTheory/Adjunction/Mates.lean b/Mathlib/CategoryTheory/Adjunction/Mates.lean index c458821adaf0d6..4e9e887d029919 100644 --- a/Mathlib/CategoryTheory/Adjunction/Mates.lean +++ b/Mathlib/CategoryTheory/Adjunction/Mates.lean @@ -523,7 +523,7 @@ lemma conjugateEquiv_associator_hom conjugateEquiv (adj₀₁.comp (adj₁₂.comp adj₂₃)) ((adj₀₁.comp adj₁₂).comp adj₂₃) (associator _ _ _).hom = (associator _ _ _).hom := by ext X - simp only [comp_obj, conjugateEquiv_apply_app, Adjunction.comp_unit_app, id_obj, + simp only [comp_obj, conjugateEquiv_apply_app, Adjunction.comp_unit_app, Functor.comp_map, Category.assoc, ← map_comp, associator_hom_app, map_id, Adjunction.comp_counit_app, Category.id_comp] simp @@ -557,7 +557,7 @@ lemma conjugateEquiv_whiskerRight conjugateEquiv (adj₁.comp adj) (adj₂.comp adj) (whiskerRight τ L) = whiskerLeft R (conjugateEquiv adj₁ adj₂ τ) := by ext X - simp only [comp_obj, conjugateEquiv_apply_app, comp_unit_app, id_obj, Functor.whiskerRight_app, + simp only [comp_obj, conjugateEquiv_apply_app, comp_unit_app, Functor.whiskerRight_app, Functor.comp_map, comp_counit_app, ← map_comp, assoc, Functor.whiskerLeft_app] simp From b52778b7fd2457de81066394a0e0877e81c1dcce Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:37:20 +0000 Subject: [PATCH 0558/1300] feat: linear map from `L^p (mu)` to `L^p (nu)` when `nu` is bounded by a multiple of `mu` (#40811) Co-authored-by: sgouezel --- .../Function/LpSeminorm/Basic.lean | 19 ++++-- .../MeasureTheory/Function/LpSpace/Basic.lean | 62 ++++++++++++++++++- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index 15c786f85e26ca..f22688a5976fb8 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -657,6 +657,12 @@ theorem eLpNorm_smul_measure_of_ne_zero {c : ℝ≥0∞} (hc : c ≠ 0) (f : α · simp [*] exact eLpNorm_smul_measure_of_ne_zero_of_ne_top hp0 hp_top c +theorem eLpNorm_smul_measure_le (c : ℝ≥0∞) (f : α → ε) (p : ℝ≥0∞) (μ : Measure α) : + eLpNorm f p (c • μ) ≤ c ^ (1 / p).toReal • eLpNorm f p μ := by + rcases eq_or_ne c 0 with rfl | hc + · simp + · exact (eLpNorm_smul_measure_of_ne_zero hc f p μ).le + /-- See `eLpNorm_smul_measure_of_ne_zero` for a version with scalar multiplication by `ℝ≥0∞`. -/ lemma eLpNorm_smul_measure_of_ne_zero' {c : ℝ≥0} (hc : c ≠ 0) (f : α → ε) (p : ℝ≥0∞) (μ : Measure α) : eLpNorm f p (c • μ) = c ^ p.toReal⁻¹ • eLpNorm f p μ := @@ -680,15 +686,16 @@ theorem eLpNorm_one_smul_measure {f : α → ε} (c : ℝ≥0∞) : eLpNorm f 1 (c • μ) = c * eLpNorm f 1 μ := by rw [eLpNorm_smul_measure_of_ne_top] <;> simp +theorem eLpNorm_le_of_measure_le_smul {c : ℝ≥0∞} + {μ μ' : Measure α} (h : μ' ≤ c • μ) {f : α → ε} {p : ℝ≥0∞} : + eLpNorm f p μ' ≤ c ^ (1 / p).toReal • eLpNorm f p μ := by + grw [eLpNorm_mono_measure f h, eLpNorm_smul_measure_le] + theorem MemLp.of_measure_le_smul {μ' : Measure α} {c : ℝ≥0∞} (hc : c ≠ ∞) (hμ'_le : μ' ≤ c • μ) {f : α → ε} (hf : MemLp f p μ) : MemLp f p μ' := by refine ⟨hf.1.mono_ac (Measure.absolutelyContinuous_of_le_smul hμ'_le), ?_⟩ - refine (eLpNorm_mono_measure f hμ'_le).trans_lt ?_ - by_cases hc0 : c = 0 - · simp [hc0] - rw [eLpNorm_smul_measure_of_ne_zero hc0, smul_eq_mul] - refine ENNReal.mul_lt_top (Ne.lt_top ?_) hf.2 - simp [hc, hc0] + grw [eLpNorm_le_of_measure_le_smul hμ'_le] + exact ENNReal.mul_lt_top (Ne.lt_top (by simp [hc])) hf.2 theorem MemLp.smul_measure {f : α → ε} {c : ℝ≥0∞} (hf : MemLp f p μ) (hc : c ≠ ∞) : MemLp f p (c • μ) := diff --git a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean index 8873829b2833e9..da03fba965ce30 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean @@ -232,7 +232,6 @@ theorem nnnorm_def (f : Lp E p μ) : ‖f‖₊ = ENNReal.toNNReal (eLpNorm f p protected theorem coe_nnnorm (f : Lp E p μ) : (‖f‖₊ : ℝ) = ‖f‖ := rfl -@[simp] theorem enorm_def (f : Lp E p μ) : ‖f‖ₑ = eLpNorm f p μ := ENNReal.coe_toNNReal <| Lp.eLpNorm_ne_top f @@ -245,6 +244,7 @@ theorem nnnorm_toLp (f : α → E) (hf : MemLp f p μ) : ‖hf.toLp f‖₊ = ENNReal.toNNReal (eLpNorm f p μ) := NNReal.eq <| norm_toLp f hf +@[simp] lemma enorm_toLp {f : α → E} (hf : MemLp f p μ) : ‖hf.toLp f‖ₑ = eLpNorm f p μ := by simp_rw [enorm, nnnorm_toLp f hf, ENNReal.coe_toNNReal hf.2.ne] @@ -872,6 +872,66 @@ end ContinuousLinearMap namespace MeasureTheory.Lp +section LpToLpOfMeasureLeSMul + +variable [NormedSpace ℝ E] {ν : Measure α} {c : ℝ≥0∞} + +/-- The canonical map from `Lᵖ ν` to `Lᵖ μ` when `μ` is bounded by a finite multiple of `ν`. +This is the linear map version. Use instead the continuous linear map +version `LpToLpOfMeasureLeSMul` -/ +private noncomputable def LpToLpOfMeasureLeSMulₗ (hc : c ≠ ∞) (h : μ ≤ c • ν) : + Lp E p ν →ₗ[ℝ] Lp E p μ where + toFun f := ((Lp.memLp f).of_measure_le_smul hc h).toLp f + map_add' f g := by + ext + grw [MemLp.coeFn_toLp, Lp.coeFn_add, MemLp.coeFn_toLp, MemLp.coeFn_toLp] + have : μ ≪ ν := Measure.absolutelyContinuous_of_le_smul h + apply this.ae_eq + grw [Lp.coeFn_add] + map_smul' c f := by + ext + grw [MemLp.coeFn_toLp, Lp.coeFn_smul, MemLp.coeFn_toLp] + have : μ ≪ ν := Measure.absolutelyContinuous_of_le_smul h + apply this.ae_eq + grw [Lp.coeFn_smul] + rfl + +private lemma coeFn_LpToLpOfMeasureLeSMulₗ (hc : c ≠ ∞) (h : μ ≤ c • ν) (f : Lp E p ν) : + LpToLpOfMeasureLeSMulₗ hc h f =ᵐ[μ] f := by + simp [LpToLpOfMeasureLeSMulₗ, MemLp.coeFn_toLp] + +private lemma enorm_LpToLpOfMeasureLeSMulₗ_apply_le + (hc : c ≠ ∞) (h : μ ≤ c • ν) [Fact (1 ≤ p)] {f : Lp E p ν} : + ‖LpToLpOfMeasureLeSMulₗ hc h f‖ₑ ≤ c ^ (1 / p).toReal * ‖f‖ₑ := by + simp only [Lp.enorm_def] + rw [eLpNorm_congr_ae (coeFn_LpToLpOfMeasureLeSMulₗ hc h f)] + exact eLpNorm_le_of_measure_le_smul h + +private lemma norm_LpToLpOfMeasureLeSMulₗ_apply_le + (hc : c ≠ ∞) (h : μ ≤ c • ν) [Fact (1 ≤ p)] {f : Lp E p ν} : + ‖LpToLpOfMeasureLeSMulₗ hc h f‖ ≤ c.toReal ^ (1 / p).toReal * ‖f‖ := by + simp only [← toReal_enorm] + rw [ENNReal.toReal_rpow, ← ENNReal.toReal_mul] + grw [enorm_LpToLpOfMeasureLeSMulₗ_apply_le] + simp [ENNReal.mul_eq_top, hc] + +/-- The canonical map from `Lᵖ ν` to `Lᵖ μ` when `μ` is bounded by a finite multiple of `ν`. -/ +@[no_expose] +noncomputable def LpToLpOfMeasureLeSMul [Fact (1 ≤ p)] (hc : c ≠ ∞) (h : μ ≤ c • ν) : + Lp E p ν →L[ℝ] Lp E p μ := + LinearMap.mkContinuous (LpToLpOfMeasureLeSMulₗ hc h) (c.toReal ^ (1 / p).toReal) + (fun _ ↦ norm_LpToLpOfMeasureLeSMulₗ_apply_le hc h) + +lemma coeFn_LpToLpOfMeasureLeSMul [Fact (1 ≤ p)] (hc : c ≠ ∞) (h : μ ≤ c • ν) (f : Lp E p ν) : + LpToLpOfMeasureLeSMul hc h f =ᵐ[μ] f := + coeFn_LpToLpOfMeasureLeSMulₗ hc h f + +lemma norm_LpToLpOfMeasureLeSMul_le [Fact (1 ≤ p)] (hc : c ≠ ∞) (h : μ ≤ c • ν) : + ‖(LpToLpOfMeasureLeSMul hc h : Lp E p ν →L[ℝ] Lp E p μ)‖ ≤ c.toReal ^ (1 / p).toReal := + LinearMap.mkContinuous_norm_le _ (Real.rpow_nonneg (by simp) _) _ + +end LpToLpOfMeasureLeSMul + section PosPart theorem lipschitzWith_pos_part : LipschitzWith 1 fun x : ℝ => max x 0 := From 944dc915566d52b1c75b046444f708d6eabc0b42 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:37:23 +0000 Subject: [PATCH 0559/1300] feat(NumberTheory/Harmonic/ZetaAsymp): asymptotics and representation for riemannZeta near s=1 (#41205) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR expresses `riemannZeta s` either additively as `(s-1)⁻¹ + riemannZeta₀ s` and multiplicatively as `(s-1)⁻¹ * riemannZeta₁ s` for certain entire functions `riemannZeta₀`, `riemannZeta₁`. As a consequence, asymptotics for `deriv riemannZeta s`, `log riemannZeta s`, `deriv riemannZeta s / riemannZeta s`, and `1 / riemannZeta s` are established. Co-authored-by: Terence Tao Co-authored-by: David Loeffler Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean | 168 ++++++++++++++++++- 1 file changed, 166 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean b/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean index 5d61f148abc523..3220e94f093a8a 100644 --- a/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean +++ b/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean @@ -1,12 +1,13 @@ /- Copyright (c) 2024 David Loeffler. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: David Loeffler +Authors: David Loeffler, Terence Tao -/ module -public import Mathlib.NumberTheory.LSeries.RiemannZeta +public import Mathlib.NumberTheory.LSeries.Dirichlet public import Mathlib.NumberTheory.Harmonic.GammaDeriv +public import Mathlib.Analysis.Asymptotics.Lemmas /-! # Asymptotics of `ζ s` as `s → 1` or `s → 0` @@ -20,6 +21,10 @@ The goal of this file is to evaluate the limit of `ζ s - 1 / (s - 1)` as `s → * `deriv_riemannZeta_zero`: `ζ'(0) = -log(2π) / 2`, which derives from the above. * `riemannZeta_one_ne_zero`: with our definition of `ζ 1` (which is characterised as the limit of `ζ s - 1 / (s - 1) / Gammaℝ s` as `s → 1`), we have `ζ 1 ≠ 0`. +* Representation of `riemannZeta s` as `(s-1)⁻¹ + riemannZeta₀ s` or `(s-1)⁻¹ * riemannZeta₁ s` + for certain entire functions `riemannZeta₀` and `riemannZeta₁`. +* Asymptotics for `deriv riemannZeta s`, `log (riemannZeta s)`, + `(deriv riemannZeta s) / (riemannZeta s)` and `(riemannZeta s)⁻¹` as `s → 1`. ### Outline of arguments @@ -473,3 +478,162 @@ theorem deriv_riemannZeta_zero : open ComplexOrder in repeat rw [log_mul (by positivity) (by positivity) (by simp [arg, LT.lt.le, Real.pi_pos])] ring + +section near_one + +/-! +## More asymptotics near `s = 1` + +To facilitate the analysis of `riemannZeta` near `s = 1`, we write `riemannZeta s` additively as +`(s-1)⁻¹ + riemannZeta₀ s` and multiplicatively as `(s-1)⁻¹ * riemannZeta₁ s` for certain +entire functions `riemannZeta₀`, `riemannZeta₁`. +-/ + +open Asymptotics + +/-- `riemannZeta₀ s` is the completion of `riemannZeta s - (s-1)⁻¹` at `s = 1`. -/ +noncomputable def riemannZeta₀ (s : ℂ) : ℂ := + if s = 1 then γ else riemannZeta s - (s-1)⁻¹ + +/-- `riemannZeta₁ s` is the completion of `(s-1) * riemannZeta s` at `s = 1`. -/ +noncomputable def riemannZeta₁ (s : ℂ) : ℂ := 1 + (s - 1) * riemannZeta₀ s + +@[simp] +lemma riemannZeta₀_one : riemannZeta₀ 1 = γ := by simp [riemannZeta₀] + +@[simp] +lemma riemannZeta₁_one : riemannZeta₁ 1 = 1 := by simp [riemannZeta₁] + +lemma riemannZeta_eq_inv_sub_add {s : ℂ} (hs : s ≠ 1) : + riemannZeta s = (s - 1)⁻¹ + riemannZeta₀ s := by simp [riemannZeta₀, hs] + +lemma riemannZeta_eq_inv_sub_mul {s : ℂ} (hs : s ≠ 1) : + riemannZeta s = (s - 1)⁻¹ * riemannZeta₁ s := by grind [riemannZeta₁, riemannZeta₀] + +@[fun_prop] +lemma differentiable_riemannZeta₀ : Differentiable ℂ riemannZeta₀ := by + rw [← differentiableOn_univ, ← differentiableOn_compl_singleton_and_continuousAt_iff + (univ_mem : _ ∈ 𝓝 (1 : ℂ)), continuousAt_iff_punctured_nhds, ← compl_eq_univ_sdiff] + constructor + · refine .congr (f := fun s ↦ riemannZeta s - (s - 1)⁻¹) ?_ (by simp +contextual [riemannZeta₀]) + exact differentiableOn_riemannZeta.fun_sub (by fun_prop (disch := grind)) + · convert tendsto_nhdsWithin_congr ?_ tendsto_riemannZeta_sub_one_div <;> + simp +contextual [riemannZeta₀] + +@[fun_prop] +lemma differentiable_riemannZeta₁ : Differentiable ℂ riemannZeta₁ := by + unfold riemannZeta₁; fun_prop + +lemma riemannZeta₁_ne_zero_of_near_one : ∀ᶠ s in 𝓝 1, riemannZeta₁ s ≠ 0 := by + refine Tendsto.eventually_ne ?_ one_ne_zero + simpa using (differentiable_riemannZeta₁.continuous.continuousAt (x := 1)).tendsto + +@[simp] +lemma deriv_riemannZeta₁_one : deriv riemannZeta₁ 1 = γ := by + unfold riemannZeta₁ + rw [deriv_const_add, deriv_fun_mul (by fun_prop) (by fun_prop)] + simp + +lemma deriv_riemannZeta_eq_neg_inv_sub_sq_add {s : ℂ} (hs : s ≠ 1) : + deriv riemannZeta s = - ((s - 1)⁻¹) ^ 2 + deriv riemannZeta₀ s := by + have := sub_ne_zero_of_ne hs + convert EventuallyEq.deriv_eq (f := fun s ↦ (s - 1)⁻¹ + riemannZeta₀ s) ?_ + · rw [deriv_fun_add (by fun_prop) (by fun_prop), deriv_fun_inv'' (by fun_prop) (by exact this)] + simp [field] + · filter_upwards [compl_singleton_mem_nhds hs] using by grind [riemannZeta_eq_inv_sub_add] + +lemma deriv_riemannZeta_eq_neg_inv_sub_sq_mul_add {s : ℂ} (hs : s ≠ 1) : + deriv riemannZeta s = + - ((s - 1)⁻¹) ^ 2 * (riemannZeta₁ s) + (s - 1)⁻¹ * deriv riemannZeta₁ s := by + have := sub_ne_zero_of_ne hs + convert EventuallyEq.deriv_eq (f := fun s ↦ (s - 1)⁻¹ * riemannZeta₁ s) ?_ + · rw [deriv_fun_mul (by fun_prop) (by fun_prop), deriv_fun_inv'' (by fun_prop) (by exact this)] + simp [field] + · filter_upwards [compl_singleton_mem_nhds hs] using by grind [riemannZeta_eq_inv_sub_mul] + +lemma deriv_riemannZeta_add_inv_sub_sq_bounded : + (fun s ↦ deriv riemannZeta s + ((s - 1)⁻¹) ^ 2) =O[𝓝[≠] 1] (fun _ ↦ (1 : ℂ)) := + (differentiable_riemannZeta₀.deriv.continuous.continuousAt.isBigO.mono nhdsWithin_le_nhds).congr' + (eventually_nhdsWithin_of_forall (by simp +contextual [deriv_riemannZeta_eq_neg_inv_sub_sq_add])) + .rfl + +lemma log_riemannZeta_eq_neg_log_sub_add_ofReal {s : ℝ} (hs : s > 1) : + (riemannZeta s).re.log = - (s - 1).log + (riemannZeta₁ s).re.log := by + have : (riemannZeta s).re = (s - 1)⁻¹ * (riemannZeta₁ s).re := by + rw_mod_cast [riemannZeta_eq_inv_sub_mul (by aesop), re_ofReal_mul] + rw [this, Real.log_mul, Real.log_inv] <;> + grind [riemannZeta_re_pos_of_one_lt hs] + +lemma log_riemannZeta_add_log_sub_isBigO_ofReal : + (fun (s : ℝ) ↦ (riemannZeta s).re.log + (s - 1).log) =O[𝓝[>] 1] (· - 1) := by + suffices (fun (s : ℝ) ↦ (riemannZeta₁ s).re.log) =O[𝓝 1] (· - 1) by + refine (this.mono nhdsWithin_le_nhds).congr' + (eventually_nhdsWithin_of_forall (fun s hs ↦ ?_)) .rfl + simp [log_riemannZeta_eq_neg_log_sub_add_ofReal hs] + suffices DifferentiableAt ℝ (fun (s : ℝ) ↦ (riemannZeta₁ s).re.log) 1 by + simpa using this.isBigO_sub + have : Differentiable ℝ riemannZeta₀ := by fun_prop + fun_prop (disch := simp) + +lemma log_riemannZeta_add_log_sub_isLittleO_ofReal : + (fun (s : ℝ) ↦ (riemannZeta s).re.log + (s - 1).log) =o[𝓝[>] (1 : ℝ)] (fun _ ↦ (1 : ℝ)) := + log_riemannZeta_add_log_sub_isBigO_ofReal.trans_isLittleO + (continuous_id.continuousAt.isLittleO.mono nhdsWithin_le_nhds) + +lemma log_deriv_riemannZeta_eq_neg_inv_sub_add : + ∀ᶠ s in 𝓝[≠] 1, (deriv riemannZeta s) / (riemannZeta s) + = - (s - 1)⁻¹ + (deriv riemannZeta₁ s) / (riemannZeta₁ s) := by + filter_upwards [eventually_mem_nhdsWithin, + riemannZeta₁_ne_zero_of_near_one.filter_mono nhdsWithin_le_nhds] + grind [deriv_riemannZeta_eq_neg_inv_sub_sq_mul_add, riemannZeta_eq_inv_sub_mul] + +lemma log_deriv_riemannZeta_add_inv_sub_sub_isBigO : + (fun s ↦ (deriv riemannZeta s) / (riemannZeta s) + (s - 1)⁻¹ - γ) + =O[𝓝[≠] 1] (· - 1) := by + suffices (fun s ↦ (deriv riemannZeta₁ s) / (riemannZeta₁ s) - γ) =O[𝓝 1] (· - 1) by + refine (this.mono nhdsWithin_le_nhds).congr' ?_ .rfl + filter_upwards [log_deriv_riemannZeta_eq_neg_inv_sub_add] + simp +contextual + suffices DifferentiableAt ℂ (fun s ↦ (deriv riemannZeta₁ s) / (riemannZeta₁ s)) 1 by + simpa using this.isBigO_sub + fun_prop (disch := simp) + +lemma log_deriv_riemannZeta_add_inv_sub_sub_isLittleO : + (fun s ↦ (deriv riemannZeta s) / (riemannZeta s) + (s - 1)⁻¹ - γ) + =o[𝓝[≠] 1] (fun _ ↦ (1 : ℂ)) := + log_deriv_riemannZeta_add_inv_sub_sub_isBigO.trans_isLittleO + (continuous_id.continuousAt.isLittleO.mono nhdsWithin_le_nhds) + +lemma log_deriv_riemannZeta_add_inv_sub_bounded : + (fun s ↦ (deriv riemannZeta s) / (riemannZeta s) + (s - 1)⁻¹) + =O[𝓝[≠] 1] (fun _ ↦ (1 : ℂ)) := + (isBigO_const_one ..).sub_iff_left.mp log_deriv_riemannZeta_add_inv_sub_sub_isLittleO.isBigO + +lemma inv_riemannZeta_eq_sub_mul : + ∀ᶠ s in 𝓝[≠] 1, (riemannZeta s)⁻¹ = (s - 1) * (riemannZeta₁ s)⁻¹ := by + filter_upwards [eventually_mem_nhdsWithin, + riemannZeta₁_ne_zero_of_near_one.filter_mono nhdsWithin_le_nhds] with s hs + simp [riemannZeta_eq_inv_sub_mul hs, field] + +lemma inv_riemannZeta_sub_sub_isBigO : + (fun s ↦ (riemannZeta s)⁻¹ - (s - 1)) =O[𝓝[≠] 1] (fun s ↦ (s - 1) ^ 2) := by + suffices (fun s ↦ (s - 1) * ((riemannZeta₁ s)⁻¹ - 1)) =O[𝓝 1] (fun s ↦ (s - 1) ^ 2) by + refine (this.mono nhdsWithin_le_nhds).congr' ?_ .rfl + filter_upwards [inv_riemannZeta_eq_sub_mul] + simp +contextual [field] + suffices (fun s ↦ ((riemannZeta₁ s)⁻¹ - 1)) =O[𝓝 1] (· - 1) by + simpa [pow_two] using (isBigO_refl ..).mul this + simpa using ((differentiable_riemannZeta₁.differentiableAt (x := 1)).inv (by simp)).isBigO_sub + +lemma inv_riemannZeta_sub_sub_isLittleO : + (fun s ↦ (riemannZeta s)⁻¹ - (s - 1)) =o[𝓝[≠] 1] (· - 1) := by + apply inv_riemannZeta_sub_sub_isBigO.trans_isLittleO + suffices (· - 1) =o[𝓝 1] (fun _ : ℂ ↦ (1 : ℂ)) by + simpa [pow_two] using (this.mul_isBigO <| isBigO_refl ..).mono nhdsWithin_le_nhds + exact ContinuousAt.isLittleO (by fun_prop) + +lemma inv_riemannZeta_isBigO : + (fun s ↦ (riemannZeta s)⁻¹) =O[𝓝[≠] 1] (· - 1) := + (isBigO_refl ..).sub_iff_left.mp inv_riemannZeta_sub_sub_isLittleO.isBigO + +end near_one From 26ea12749a6aa5808dc5ed7246c7341f33699f4b Mon Sep 17 00:00:00 2001 From: Ben Eltschig <43812953+peabrainiac@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:54:19 +0000 Subject: [PATCH 0560/1300] feat(CategoryTheory/Sites): local sites (#41083) A local site is a site with a terminal object whose only covering sieve is the trivial one. We define local sites, construct a functor `coconstantSheaf` on them that is right-adjoint to the global sections functor, and prove that this functor and hence also the constant sheaf functor are fully faithful. Co-authored-by: Christian Merten --- Mathlib.lean | 1 + Mathlib/CategoryTheory/ShrinkYoneda.lean | 14 +- Mathlib/CategoryTheory/Sites/LocalSite.lean | 213 ++++++++++++++++++++ 3 files changed, 225 insertions(+), 3 deletions(-) create mode 100644 Mathlib/CategoryTheory/Sites/LocalSite.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7a0a0bf5b574fe..dbdff85e5cd1f5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3382,6 +3382,7 @@ public import Mathlib.CategoryTheory.Sites.JointlySurjective public import Mathlib.CategoryTheory.Sites.LeftExact public import Mathlib.CategoryTheory.Sites.Limits public import Mathlib.CategoryTheory.Sites.LocalProperties +public import Mathlib.CategoryTheory.Sites.LocalSite public import Mathlib.CategoryTheory.Sites.Localization public import Mathlib.CategoryTheory.Sites.LocallyBijective public import Mathlib.CategoryTheory.Sites.LocallyFullyFaithful diff --git a/Mathlib/CategoryTheory/ShrinkYoneda.lean b/Mathlib/CategoryTheory/ShrinkYoneda.lean index 4973283a9cef7f..40a9ffa06c34ff 100644 --- a/Mathlib/CategoryTheory/ShrinkYoneda.lean +++ b/Mathlib/CategoryTheory/ShrinkYoneda.lean @@ -87,13 +87,16 @@ noncomputable def shrinkYonedaObjObjEquiv {X : C} {Y : Cᵒᵖ} : ((shrinkYoneda.{w}.obj X).obj Y) ≃ (Y.unop ⟶ X) := (equivShrink _).symm -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in +lemma shrinkYoneda_obj_map {X : C} {Y Y' : Cᵒᵖ} (g : Y ⟶ Y') (f : (shrinkYoneda.obj X).obj Y) : + (shrinkYoneda.obj _).map g f = + shrinkYonedaObjObjEquiv.symm (g.unop ≫ shrinkYonedaObjObjEquiv f) := + rfl + lemma shrinkYoneda_obj_map_shrinkYonedaObjObjEquiv_symm {X : C} {Y Y' : Cᵒᵖ} (g : Y ⟶ Y') (f : Y.unop ⟶ X) : (shrinkYoneda.obj _).map g (shrinkYonedaObjObjEquiv.symm f) = shrinkYonedaObjObjEquiv.symm (g.unop ≫ f) := by - simp [shrinkYoneda, shrinkYonedaObjObjEquiv] + simp [shrinkYoneda_obj_map] lemma shrinkYonedaObjObjEquiv_symm_comp {X Y Y' : C} (g : Y' ⟶ Y) (f : Y ⟶ X) : shrinkYonedaObjObjEquiv.symm (g ≫ f) = @@ -274,6 +277,11 @@ noncomputable abbrev shrinkCoyonedaObjObjEquiv {X : Cᵒᵖ} {Y : C} : ((shrinkCoyoneda.{w}.obj X).obj Y) ≃ (X.unop ⟶ Y) := shrinkYonedaObjObjEquiv +lemma shrinkCoyoneda_obj_map {X : Cᵒᵖ} {Y Y' : C} (g : Y ⟶ Y') (f : (shrinkCoyoneda.obj X).obj Y) : + (shrinkCoyoneda.obj _).map g f = + shrinkCoyonedaObjObjEquiv.symm (shrinkCoyonedaObjObjEquiv f ≫ g) := + rfl + lemma shrinkCoyoneda_obj_map_shrinkCoyonedaObjObjEquiv_symm {X : Cᵒᵖ} {Y Y' : C} (g : Y ⟶ Y') (f : X.unop ⟶ Y) : (shrinkCoyoneda.obj _).map g (shrinkCoyonedaObjObjEquiv.symm f) = diff --git a/Mathlib/CategoryTheory/Sites/LocalSite.lean b/Mathlib/CategoryTheory/Sites/LocalSite.lean new file mode 100644 index 00000000000000..5deba23c853f0a --- /dev/null +++ b/Mathlib/CategoryTheory/Sites/LocalSite.lean @@ -0,0 +1,213 @@ +/- +Copyright (c) 2025 Ben Eltschig. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Ben Eltschig +-/ +module + +public import Mathlib.CategoryTheory.Adjunction.Triple +public import Mathlib.CategoryTheory.Limits.Elements +public import Mathlib.CategoryTheory.Sites.GlobalSections +public import Mathlib.CategoryTheory.Sites.Point.Skyscraper + +/-! +# Local sites + +A site is called local if it has a terminal object whose only covering sieve is trivial - +this makes it possible to define coconstant sheaves on it, giving its sheaf topos the structure +of a local topos. This is one of the conditions of cohesive sites. + +Sheaves of types on any local site form a local topos (i.e. a topos whose global sections functor +has a fully faithful right adjoint), and a subcanonical site is local if and only if its topos of +sheaves of types is (see TODOs). + +## Main definitions / results + +* `J.IsLocalSite`: typeclass stating that `J` makes the category it is defined on into a local site. +* `IsLocalSite.point J`: the canonical point of any local site, whose fibre functor is given by + the coyoneda embedding of the terminal object and extends to the global sections functors on + presheaves and sheaves. +* `coconstantSheaf J A`: the coconstant sheaf functor `A ⥤ Sheaf J A` for any local site and + sufficiently nice target category `A`, defined as the skyscraper sheaf functor of the canonical + point. +* `ΓCoconstantSheafAdj J A`: the adjunction between the global sections functor `Γ J A` and + `coconstantSheaf J A`. +* `fullyFaithfulCoconstantSheaf`: `coconstantSheaf` is fully faithful. +* `fullyFaithfulConstantSheaf`: on local sites, the constant sheaf functor is fully faithful. + +## References + +* https://ncatlab.org/nlab/show/local+site + +## TODO + +* Define local topoi and prove that sheaves on any local site form a local topos +* Show that a subcanonical site is local if and only if its global sections functor has a fully + faithful right adjoint +-/ + +universe w u v u' v' + +@[expose] public section + +open CategoryTheory Limits Sheaf Opposite GrothendieckTopology + +namespace CategoryTheory + +variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) + +/-- A local site is a site that has a terminal object with only a single covering sieve. -/ +class GrothendieckTopology.IsLocalSite extends HasTerminal C where + /-- The only covering sieve of the terminal object is the trivial sieve. -/ + eq_top_of_mem : ∀ S ∈ J (⊤_ C), S = ⊤ + +namespace GrothendieckTopology.IsLocalSite + +/-- On a local site, every covering sieve contains every morphism from the terminal object. -/ +lemma from_terminal_mem_of_mem [J.IsLocalSite] {X : C} (f : ⊤_ C ⟶ X) {S : Sieve X} + (hS : S ∈ J X) : S.arrows f := + (S.mem_iff_pullback_eq_top f).mpr <| eq_top_of_mem _ <| J.pullback_stable f hS + +/-- Every category with a terminal object becomes a local site with the trivial topology. -/ +instance {C : Type u} [Category.{v} C] [HasTerminal C] : (trivial C).IsLocalSite where + eq_top_of_mem _ := trivial_covering.mp + +/-- Every local site has a canonical point, given as a fibre functor by the coyoneda embedding of +the terminal object `⊤_ C`. -/ +noncomputable def point [LocallySmall.{w} C] [J.IsLocalSite] : Point.{w} J where + fiber := shrinkCoyoneda.obj (op (⊤_ C)) + jointly_surjective R hR x := + ⟨(⊤_ C), shrinkCoyonedaObjObjEquiv x, + (from_terminal_mem_of_mem J (shrinkCoyonedaObjObjEquiv x) hR), + shrinkCoyonedaObjObjEquiv.symm (𝟙 _), by + rw [shrinkCoyoneda_obj_map_shrinkCoyonedaObjObjEquiv_symm] + simp⟩ + +variable [LocallySmall.{w} C] [J.IsLocalSite] (A : Type u') [Category.{v'} A] + +/-- The right adjoint to the global sections functor that exists over any local site. This is +implemented as the skyscraper functor associated to `point.{w} J`, but can be thought of +as taking any object `X : A` to the sheaf that sends each `Y : C` to the product over copies of `A` +indexed by the points `⊤_ C ⟶ Y` of `Y`. + +Note this takes in an extra universe parameter `w` that does not appear in the output type +`A ⥤ Sheaf J A` but is required for the construction; it should always be given explicitly when +referring to this functor, as in e.g. `coconstantSheaf.{w} J A`. -/ +noncomputable def coconstantSheaf [HasProducts.{w} A] : A ⥤ Sheaf J A := + (point.{w} J).skyscraperSheafFunctor + +variable [HasColimitsOfSize.{w, w} A] + +variable {A} in +/-- The fibre of any presheaf `P : Cᵒᵖ ⥤ A` at `point J` is just `P` evaluated at +the terminal object. -/ +noncomputable def pointPresheafFiberIso (P : Cᵒᵖ ⥤ A) : + (point J).presheafFiber.obj P ≅ P.obj (op (⊤_ C)) := + (colimit.isColimit _).coconePointUniqueUpToIso + (colimitOfDiagramTerminal (Functor.Elements.isInitialOfCorepresentableBy + <| shrinkCoyonedaCorepresentableBy <| op (⊤_ C)).op _) + +variable {A} in +set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in +@[reassoc (attr := simp)] +lemma toPresheafFiber_pointPresheafFiberIso_hom {P : Cᵒᵖ ⥤ A} (X : C) (x : (point J).fiber.obj X) : + (point J).toPresheafFiber _ x _ ≫ (pointPresheafFiberIso J P).hom = + P.map (.op <| shrinkCoyonedaObjObjEquiv x) := by + simp [Point.toPresheafFiber, pointPresheafFiberIso] + rfl + +variable {A} in +@[reassoc (attr := simp)] +lemma pointPresheafFiberIso_naturality {P P' : Cᵒᵖ ⥤ A} (F : P ⟶ P') : + (point J).presheafFiber.map F ≫ (pointPresheafFiberIso J P').hom = + (pointPresheafFiberIso J P).hom ≫ F.app (op (⊤_ C)) := by + cat_disch + +/-- The presheaf fibre functor of `point J` is given by evaluation at the terminal +object. -/ +noncomputable def pointPresheafFiberNatIso : + ((point J).presheafFiber : _ ⥤ A) ≅ (evaluation _ _).obj (op (⊤_ C)) := + NatIso.ofComponents (pointPresheafFiberIso J) fun F ↦ pointPresheafFiberIso_naturality J F + +/-- The sheaf fibre functor of `point J` is the global sections functor. -/ +noncomputable def pointSheafFiberIso + [HasWeakSheafify J A] : (point J).sheafFiber ≅ Γ J A := + ((sheafToPresheaf J A).isoWhiskerLeft (pointPresheafFiberNatIso J A)).trans + (ΓNatIsoSheafSections J A terminalIsTerminal).symm + +variable [HasProducts.{w} A] [HasWeakSheafify J A] + +/-- On local sites, the global sections functor `Γ` is left-adjoint to the coconstant functor. -/ +noncomputable def ΓCoconstantSheafAdj : Γ J A ⊣ coconstantSheaf.{w} J A := + (point.{w} J).skyscraperSheafAdjunction.ofNatIsoLeft (pointSheafFiberIso J A) + +/-- On any locally `w`-small local site, the global sections functor to any category with colimits +and products of size `w` is a left adjoint. A variant of this without the universe parameter `w` +is registered as an instance. -/ +lemma Γ_isLeftAdjoint : (Γ J A).IsLeftAdjoint := + ⟨coconstantSheaf.{w} J A, ⟨ΓCoconstantSheafAdj J A⟩⟩ + +/-- On any local site with morphism types in `Type v`, the global sections functor to any category +with colimits and products of size `v` is a left adjoint. See `ΓIsLeftAdjoint` for a +version for `w`-locally small sites that can't be registered as an instance because of the extra +universe parameter `w`. -/ +instance (A : Type u') [Category.{v'} A] [HasColimitsOfSize.{v, v} A] + [HasProducts.{v} A] [HasWeakSheafify J A] : (Γ J A).IsLeftAdjoint := + Γ_isLeftAdjoint.{v} J A + +instance : (coconstantSheaf.{w} J A).IsRightAdjoint := + ⟨Γ J A, ⟨ΓCoconstantSheafAdj J A⟩⟩ + +set_option backward.defeqAttrib.useBackward true in +/-- The global sections of the coconstant sheaf on a type are naturally isomorphic to that type. -/ +noncomputable def coconstantSheafΓNatIsoId : + IsLocalSite.coconstantSheaf.{w} J A ⋙ Γ J A ≅ 𝟭 A := + letI : Unique (unop ((IsLocalSite.point J).fiber.op.obj (op (⊤_ C)))) := + (equivShrink (⊤_ C ⟶ ⊤_ C)).symm.unique + (Functor.isoWhiskerLeft _ (ΓNatIsoSheafSections J _ terminalIsTerminal)) ≪≫ + NatIso.ofComponents (fun X ↦ productUniqueIso _) (by simp [IsLocalSite.coconstantSheaf]) + +/-- `coconstantSheaf` is fully faithful. -/ +noncomputable def fullyFaithfulCoconstantSheaf : + (coconstantSheaf.{w} J A).FullyFaithful := + (ΓCoconstantSheafAdj J A).fullyFaithfulROfCompIsoId (coconstantSheafΓNatIsoId J A) + +instance : (coconstantSheaf.{w} J A).Full := + (fullyFaithfulCoconstantSheaf J A).full + +instance : (coconstantSheaf.{w} J A).Faithful := + (fullyFaithfulCoconstantSheaf J A).faithful + +/-- The adjoint triple `constantSheaf J A ⊣ Γ J A ⊣ coconstantSheaf J A` on any local site. -/ +noncomputable abbrev constantΓCoconstantTriple : + Adjunction.Triple (constantSheaf J A) (Γ J A) (coconstantSheaf.{w} J A) where + adj₁ := constantSheafΓAdj J A + adj₂ := ΓCoconstantSheafAdj J A + +/-- On local sites, the constant sheaf functor is fully faithful. -/ +noncomputable def fullyFaithfulConstantSheaf : (constantSheaf J A).FullyFaithful := + (constantΓCoconstantTriple J A).fullyFaithfulEquiv.symm <| + fullyFaithfulCoconstantSheaf.{w} J A + +lemma full_constantSheaf : (constantSheaf J A).Full := + (fullyFaithfulConstantSheaf.{w} J A).full + +lemma faithful_constantSheaf : (constantSheaf J A).Faithful := + (fullyFaithfulConstantSheaf.{w} J A).faithful + +/-- See `IsLocalSite.full_constantSheaf` for a version for `w`-locally small sites. -/ +instance {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) [J.IsLocalSite] + (A : Type u') [Category.{v'} A] [HasColimitsOfSize.{v, v} A] + [HasProducts.{v} A] [HasWeakSheafify J A] : (constantSheaf J A).Full := + full_constantSheaf.{v} J A + +/-- See `IsLocalSite.faithful_constantSheaf` for a version for `w`-locally small sites. -/ +instance {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) [J.IsLocalSite] + (A : Type u') [Category.{v'} A] [HasColimitsOfSize.{v, v} A] + [HasProducts.{v} A] [HasWeakSheafify J A] : (constantSheaf J A).Faithful := + faithful_constantSheaf.{v} J A + +end GrothendieckTopology.IsLocalSite + +end CategoryTheory From 3d85a6f48b455e56c0e1a732db41319db7e9dffc Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:54:21 +0000 Subject: [PATCH 0561/1300] feat(RepresentationTheory/Homological): redefine continuous cohomology (#41144) This PR moves `ContinuousCohomology` into the right folder and refactored it using `TopRep` --- Mathlib.lean | 3 +- .../Category/ContinuousCohomology/Basic.lean | 215 ------------------ .../Continuous/Basic.lean | 21 +- .../Continuous/TopRep.lean | 43 +++- .../Homological/ContCohomology/Basic.lean | 139 +++++++++++ .../Homological/ContCohomology/LowDegree.lean | 89 ++++++++ .../Tactic/Linter/DirectoryDependency.lean | 1 + 7 files changed, 292 insertions(+), 219 deletions(-) delete mode 100644 Mathlib/Algebra/Category/ContinuousCohomology/Basic.lean create mode 100644 Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean create mode 100644 Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean diff --git a/Mathlib.lean b/Mathlib.lean index dbdff85e5cd1f5..b1e9ba98809ce5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -112,7 +112,6 @@ public import Mathlib.Algebra.Category.CommAlgCat.FiniteType public import Mathlib.Algebra.Category.CommAlgCat.Monoidal public import Mathlib.Algebra.Category.CommBialgCat public import Mathlib.Algebra.Category.CommHopfAlgCat -public import Mathlib.Algebra.Category.ContinuousCohomology.Basic public import Mathlib.Algebra.Category.FGModuleCat.Abelian public import Mathlib.Algebra.Category.FGModuleCat.Basic public import Mathlib.Algebra.Category.FGModuleCat.Colimits @@ -6381,6 +6380,8 @@ public import Mathlib.RepresentationTheory.Equiv public import Mathlib.RepresentationTheory.FDRep public import Mathlib.RepresentationTheory.FinGroupCharZero public import Mathlib.RepresentationTheory.FiniteIndex +public import Mathlib.RepresentationTheory.Homological.ContCohomology.Basic +public import Mathlib.RepresentationTheory.Homological.ContCohomology.LowDegree public import Mathlib.RepresentationTheory.Homological.FiniteCyclic public import Mathlib.RepresentationTheory.Homological.GroupCohomology.Basic public import Mathlib.RepresentationTheory.Homological.GroupCohomology.FiniteCyclic diff --git a/Mathlib/Algebra/Category/ContinuousCohomology/Basic.lean b/Mathlib/Algebra/Category/ContinuousCohomology/Basic.lean deleted file mode 100644 index 266fd78fe69811..00000000000000 --- a/Mathlib/Algebra/Category/ContinuousCohomology/Basic.lean +++ /dev/null @@ -1,215 +0,0 @@ -/- -Copyright (c) 2025 Richard Hill. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Richard Hill, Andrew Yang --/ -module - -public import Mathlib.Algebra.Category.ModuleCat.Topology.Homology -public import Mathlib.Algebra.Homology.Embedding.Restriction -public import Mathlib.Algebra.Homology.Functor -public import Mathlib.Algebra.Homology.ShortComplex.HomologicalComplex -public import Mathlib.CategoryTheory.Action.Limits -public import Mathlib.Topology.ContinuousMap.Algebra - -/-! - -# Continuous cohomology - -We define continuous cohomology as the homology of homogeneous cochains. - -## Implementation details - -We define homogeneous cochains as `g`-invariant continuous function in `C(G, C(G,...,C(G, M)))` -instead of the usual `C(Gⁿ, M)` to allow more general topological groups other than locally compact -ones. For this to work, we also work in `Action (TopModuleCat R) G`, where the `G` action on `M` -is only continuous on `M`, and not necessarily continuous in both variables, because the `G` action -on `C(G, M)` might not be continuous on both variables even if it is on `M`. - -For the differential map, instead of a finite sum we use the inductive definition -`d₋₁ : M → C(G, M) := const : m ↦ g ↦ m` and -`dₙ₊₁ : C(G, _) → C(G, C(G, _)) := const - C(G, dₙ) : f ↦ g ↦ f - dₙ (f (g))` -See `ContinuousCohomology.MultiInd.d`. - -## Main definition -- `ContinuousCohomology.homogeneousCochains`: - The functor taking an `R`-linear `G`-representation to the complex of homogeneous cochains. -- `continuousCohomology`: - The functor taking an `R`-linear `G`-representation to its `n`-th continuous cohomology. - -## TODO -- Show that it coincides with `groupCohomology` for discrete groups. -- Give the usual description of cochains in terms of `n`-ary functions for locally compact groups. -- Show that short exact sequences induce long exact sequences in certain scenarios. --/ - -set_option backward.defeqAttrib.useBackward true - -@[expose] public section - -open CategoryTheory Functor ContinuousMap - -variable (R G : Type*) [CommRing R] [Group G] [TopologicalSpace R] - -namespace ContinuousCohomology - -variable [TopologicalSpace G] [IsTopologicalGroup G] - -variable {R G} in -/-- The `G` representation `C(G, rep)` given a representation `rep`. -The `G` action is defined by `g • f := x ↦ g • f (g⁻¹ * x)`. -/ -abbrev Iobj (rep : Action (TopModuleCat R) G) : Action (TopModuleCat R) G where - V := .of R C(G, rep.V) - ρ := - { toFun g := TopModuleCat.ofHom - { toFun f := .comp (rep.ρ g).hom (f.comp (Homeomorph.mulLeft g⁻¹)) - map_add' _ _ := by ext; simp - map_smul' _ _ := by ext; simp } - map_one' := ConcreteCategory.ext (by ext; simp) - map_mul' _ _ := ConcreteCategory.ext (by ext; simp [mul_assoc]) } - -lemma Iobj_ρ_apply (rep : Action (TopModuleCat R) G) (g f x) : - ((Iobj rep).ρ g).hom f x = (rep.ρ g).hom (f (g⁻¹ * x)) := rfl - -/-- The functor taking a representation `rep` to the representation `C(G, rep)`. -/ -@[simps] -def I : Action (TopModuleCat R) G ⥤ Action (TopModuleCat R) G where - obj := Iobj - map {M N} φ := - { hom := TopModuleCat.ofHom (ContinuousLinearMap.compLeftContinuous _ _ φ.hom.hom) - comm g := by - ext f g' - change (M.ρ g ≫ φ.hom).hom (f (g⁻¹ * g')) = (φ.hom ≫ N.ρ g).hom (f (g⁻¹ * g')) - rw [φ.comm] } - map_id _ := rfl - map_comp _ _ := rfl - -instance : (I R G).Additive where -instance : (I R G).Linear R where - -/-- The constant function `rep ⟶ C(G, rep)` as a natural transformation. -/ -@[simps] -def const : 𝟭 _ ⟶ I R G where - app _ := { hom := TopModuleCat.ofHom (.const _ _), comm _ := rfl } - naturality _ _ _ := rfl - -namespace MultiInd - -set_option linter.style.whitespace false in -- manual alignment is not recognised -/-- The n-th functor taking `M` to `C(G, C(G,...,C(G, M)))` (with n `G`s). -These functors form a complex, see `MultiInd.complex`. -/ -def functor : ℕ → Action (TopModuleCat R) G ⥤ Action (TopModuleCat R) G - | 0 => 𝟭 _ - | n + 1 => functor n ⋙ I R G - -set_option linter.style.whitespace false in -- manual alignment is not recognised -/-- The differential map in `MultiInd.complex`. -/ -def d : ∀ n : ℕ, functor R G n ⟶ functor R G (n + 1) - | 0 => const R G - | n + 1 => whiskerLeft (functor R G (n + 1)) (const R G) - (by exact whiskerRight (d n) (I R G)) - -lemma d_zero : d R G 0 = const R G := rfl - -lemma d_succ (n : ℕ) : - d R G (n + 1) = whiskerLeft (functor R G (n + 1)) (const R G) - - (by exact whiskerRight (d R G n) (I R G)) := rfl - -set_option backward.isDefEq.respectTransparency false in -@[reassoc (attr := simp)] -lemma d_comp_d (n : ℕ) : - d R G n ≫ d R G (n + 1) = 0 := by - induction n with - | zero => - rw [d_succ, Preadditive.comp_sub, sub_eq_zero] - rfl - | succ n ih => - rw [d_succ R G (n + 1), Preadditive.comp_sub] - nth_rw 2 [d_succ] - rw [Preadditive.sub_comp, ← whiskerRight_comp, ih, - Functor.whiskerRight_zero, sub_zero, sub_eq_zero] - rfl - -/-- The complex of functors whose behaviour pointwise takes an `R`-linear `G`-representation `M` -to the complex `M → C(G, M) → ⋯ → C(G, C(G,...,C(G, M))) → ⋯` -The `G`-invariant submodules of it is the homogeneous cochains (shifted by one). -/ -def complex : CochainComplex (Action (TopModuleCat R) G ⥤ Action (TopModuleCat R) G) ℕ := - CochainComplex.of (functor R G) (d R G) (d_comp_d R G) - -end MultiInd - -/-- The functor taking an `R`-linear `G`-representation to its `G`-invariant submodule. -/ -def invariants : Action (TopModuleCat R) G ⥤ TopModuleCat R where - obj M := .of R - { carrier := { x | ∀ g : G, (M.ρ g).hom x = x } - add_mem' hx hy g := by simp [hx g, hy g] - zero_mem' := by simp - smul_mem' r x hx g := by simp [hx g] : Submodule R M.V } - map f := TopModuleCat.ofHom <| f.hom.hom.restrict fun x hx g ↦ - congr($(f.comm g) x).symm.trans congr(f.hom.hom $(hx g)) - -instance : (invariants R G).Linear R where -instance : (invariants R G).Additive where - -/-- `homogeneousCochains R G` is the functor taking -an `R`-linear `G`-representation to the complex of homogeneous cochains. -/ -def homogeneousCochains : Action (TopModuleCat R) G ⥤ CochainComplex (TopModuleCat R) ℕ := - (MultiInd.complex R G).asFunctor ⋙ (invariants R G).mapHomologicalComplex _ ⋙ - (ComplexShape.embeddingUp'Add 1 1).restrictionFunctor _ - -/-- `continuousCohomology R G n` is the functor taking -an `R`-linear `G`-representation to its `n`-th continuous cohomology. -/ -noncomputable -def _root_.continuousCohomology (n : ℕ) : Action (TopModuleCat R) G ⥤ TopModuleCat R := - homogeneousCochains R G ⋙ HomologicalComplex.homologyFunctor _ _ n - -set_option backward.isDefEq.respectTransparency false in -/-- The `0`-homogeneous cochains are isomorphic to `Xᴳ`. -/ -def kerHomogeneousCochainsZeroEquiv - (X : Action (TopModuleCat R) G) (n : ℕ) (hn : n = 1) : - (((homogeneousCochains R G).obj X).d 0 n).hom.ker ≃L[R] (invariants R G).obj X where - toFun x := - { val := DFunLike.coe (F := C(G, _)) x.1.1 1 - property g := by - subst hn - obtain ⟨⟨x : C(G, _), hx⟩, hx'⟩ := x - have : (X.ρ g).hom (x (g⁻¹ * 1)) = x 1 := congr(DFunLike.coe (F := C(G, _)) $(hx g) 1) - have hx' : x (g⁻¹ * 1) - x 1 = 0 := - congr(DFunLike.coe (F := C(G, _)) (DFunLike.coe (F := C(G, _)) ($hx').1 1) (g⁻¹ * 1)) - rw [sub_eq_zero] at hx' - exact congr((X.ρ g).hom $hx').symm.trans this } - map_add' _ _ := rfl - map_smul' _ _ := rfl - invFun x := by - refine ⟨⟨ContinuousLinearMap.const R _ x.1, fun g ↦ ContinuousMap.ext fun a ↦ - by subst hn; exact x.2 g⟩, ?_⟩ - subst hn - exact Subtype.ext (ContinuousMap.ext fun a ↦ - ContinuousMap.ext fun b ↦ show x.1 - x.1 = (0 : X.V) by simp) - left_inv x := by - subst hn - obtain ⟨⟨x : C(G, _), hx⟩, hx'⟩ := x - refine Subtype.ext (Subtype.ext <| ContinuousMap.ext fun a ↦ ?_) - have hx' : x 1 - x a = 0 := - congr(DFunLike.coe (F := C(G, _)) (DFunLike.coe (F := C(G, _)) ($hx').1 a) 1) - rwa [sub_eq_zero] at hx' - right_inv _ := rfl - continuous_toFun := continuous_induced_rng.mpr ((continuous_eval_const (F := C(G, _)) 1).comp - (continuous_subtype_val.comp continuous_subtype_val)) - continuous_invFun := continuous_induced_rng.mpr - (continuous_induced_rng.mpr ((ContinuousLinearMap.const R G).cont.comp continuous_subtype_val)) - -set_option backward.isDefEq.respectTransparency false in -open ShortComplex HomologyData in -/-- `H⁰_cont(G, X) ≅ Xᴳ`. -/ -noncomputable -def continuousCohomologyZeroIso : (continuousCohomology R G 0) ≅ invariants R G := - NatIso.ofComponents (fun X ↦ (ofIsLimitKernelFork _ (by simp) _ - (TopModuleCat.isLimitKer _)).left.homologyIso ≪≫ TopModuleCat.ofIso - (kerHomogeneousCochainsZeroEquiv R G X _ (by simp))) fun {X Y} f ↦ by - dsimp [continuousCohomology, HomologicalComplex.homologyMap] - rw [Category.assoc, ← Iso.inv_comp_eq] - rw [LeftHomologyData.leftHomologyIso_inv_naturality_assoc, Iso.inv_hom_id_assoc, - ← cancel_epi (LeftHomologyData.π _), leftHomologyπ_naturality'_assoc] - rfl - -end ContinuousCohomology diff --git a/Mathlib/RepresentationTheory/Continuous/Basic.lean b/Mathlib/RepresentationTheory/Continuous/Basic.lean index fc6080606d36fd..0dfb3a6fdb8dd3 100644 --- a/Mathlib/RepresentationTheory/Continuous/Basic.lean +++ b/Mathlib/RepresentationTheory/Continuous/Basic.lean @@ -415,6 +415,25 @@ def invariants (π : ContRepresentation R G V) : Submodule R V where lemma mem_invariants {π : ContRepresentation R G V} (v : V) : v ∈ π.invariants ↔ ∀ g, π g v = v := Iff.rfl +/-- The map induced on `G`-invariant elements by a continuous intertwining map. -/ +def _root_.ContIntertwiningMap.mapInvariants + {π : ContRepresentation R G V} {π' : ContRepresentation R G W} + (f : π →ⁱL π') : π.invariants →L[R] π'.invariants := + f.toContinuousLinearMap.restrict <| by + simp +contextual [f.toContinuousLinearMap_apply, ← f.isIntertwining] + +-- provided for rewrite +lemma _root_.ContIntertwiningMap.mapInvariants_apply + {π : ContRepresentation R G V} {π' : ContRepresentation R G W} + (f : π →ⁱL π') (v : π.invariants) : + f.mapInvariants v = f v := rfl + +@[simp] +lemma _root_.ContIntertwiningMap.mk_mapInvariants_apply + {π : ContRepresentation R G V} {π' : ContRepresentation R G W} + (f : π →ⁱL π') (v : V) (hv : v ∈ π.invariants) : + f.mapInvariants ⟨v, hv⟩ = f v := rfl + -- TODO : define `IsTopologicalMonoid` and then replace `Homeomorph.mulLeft g⁻¹` with the -- `ContinuousMap.mulRight g` to make `coind₁` work for monoids. variable {G H : Type*} [Group G] [TopologicalSpace G] [TopologicalSpace R] @@ -483,7 +502,7 @@ def coind₁Map (π₁ : ContRepresentation R G V) (π₂ : ContRepresentation R /-- The naturality of the transformation from `𝟭 ⟶ coind₁`. -/ @[simps] def coind₁ι (π : ContRepresentation R G V) : π →ⁱL coind₁ π where - toFun := .const G + toFun := ContinuousMap.const G map_add' _ _ := rfl map_smul' _ _ := rfl isIntertwining' := by aesop diff --git a/Mathlib/RepresentationTheory/Continuous/TopRep.lean b/Mathlib/RepresentationTheory/Continuous/TopRep.lean index c3fa7ff35657b2..a9367b8fb943e9 100644 --- a/Mathlib/RepresentationTheory/Continuous/TopRep.lean +++ b/Mathlib/RepresentationTheory/Continuous/TopRep.lean @@ -6,6 +6,7 @@ Authors: Edison Xie, Richard Hill module public import Mathlib.CategoryTheory.Action.Basic +public import Mathlib.CategoryTheory.Linear.LinearFunctor public import Mathlib.RepresentationTheory.Continuous.Basic /-! @@ -128,7 +129,9 @@ variable {A B} in lemma hom_comm_apply (f : A ⟶ B) (g : G) (a : A) : f.hom (A.ρ g a) = B.ρ g (f.hom a) := by simpa using! congr($(f.hom.2 g) a) -instance : AddCommGroup (A ⟶ B) := ConcreteCategory.homEquiv.addCommGroup +instance : AddCommGroup (A ⟶ B) := fast_instance% ConcreteCategory.homEquiv.addCommGroup + +@[simp] lemma hom_zero : (0 : A ⟶ B).hom = 0 := rfl lemma hom_add (f g : A ⟶ B) : (f + g).hom = f.hom + g.hom := rfl @@ -157,7 +160,7 @@ variable {k : Type u} {G : Type v} {X Y : Type w} [TopologicalSpace k] [CommRing [IsTopologicalAddGroup Y] [ContinuousSMul k Y] {ρ : ContRepresentation k G X} {σ : ContRepresentation k G Y} {A B C : TopRep k G} -instance : Module k (A ⟶ B) := ConcreteCategory.homEquiv.module k +instance : Module k (A ⟶ B) := fast_instance% ConcreteCategory.homEquiv.module k lemma hom_smul (r : k) (f : A ⟶ B) : (r • f).hom = r • f.hom := rfl @@ -219,4 +222,40 @@ instance : (fromActionTopModFunc (k := k) (G := G)).IsEquivalence := end equivAction +variable {G : Type v} [Group G] [TopologicalSpace G] [IsTopologicalGroup G] + +/-- The `G`-invariant topologicalsubmodule of a topological representation. -/ +abbrev invariants (X : TopRep k G) : TopModuleCat k := .of k X.ρ.invariants + +variable (k G) in +/-- The functor taking an `R`-linear `G`-representation to its `G`-invariant submodule. -/ +abbrev invariantsFunctor : TopRep k G ⥤ TopModuleCat k where + obj A := .of k A.ρ.invariants + map f := TopModuleCat.ofHom f.hom.mapInvariants + +instance : (invariantsFunctor k G).Additive where + +instance {k : Type u} [CommRing k] [TopologicalSpace k] [IsTopologicalRing k] : + (invariantsFunctor k G).Linear k where + +/-- The top rep induced by the coinduced representation. -/ +abbrev coind₁ (A : TopRep k G) : TopRep k G := of A.ρ.coind₁ + +variable (k G) in +/-- The functor taking a representation `rep` to the representation `C(G, rep)`. +The `G` action is defined by `g • f := x ↦ g • f (g⁻¹ * x)`. -/ +abbrev coind₁Functor : TopRep k G ⥤ TopRep k G where + obj := coind₁ + map φ := ofHom <| ContRepresentation.coind₁Map _ _ φ.hom + +instance : (TopRep.coind₁Functor k G).Additive where + +instance {k : Type u} [CommRing k] [TopologicalSpace k] [IsTopologicalRing k] : + (coind₁Functor k G).Linear k where + +/-- The constant function `rep ⟶ C(G, rep)` as a natural transformation. -/ +@[implicit_reducible, simps] +def coind₁ι : 𝟭 (TopRep k G) ⟶ coind₁Functor k G where + app rep := ofHom rep.ρ.coind₁ι + end TopRep diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean new file mode 100644 index 00000000000000..889894b5cc1f9d --- /dev/null +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean @@ -0,0 +1,139 @@ +/- +Copyright (c) 2026 Richard Hill. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Richard Hill, Andrew Yang, Edison Xie +-/ + +module + +public import Mathlib.Algebra.Homology.ShortComplex.HomologicalComplex +public import Mathlib.Algebra.Category.ModuleCat.Topology.Homology +public import Mathlib.RepresentationTheory.Continuous.TopRep + +/-! + +# Continuous cohomology + +We define continuous cohomology as the homology of the homogeneous cochain complex. + +## Implementation details + +We define homogeneous cochains as `g`-invariant continuous function in `C(G, C(G,...,C(G, M)))` +instead of the usual `C(Gⁿ, M)` to allow more general topological groups other than locally compact +ones. For this to work, we also work in `TopRep k G`, where the `G` action on `M` +is only continuous on `M`, and not necessarily continuous in both variables, because the `G` action +on `C(G, M)` might not be continuous on both variables even if it is on `M`. + +For the differential map, instead of a finite sum we use the inductive definition +`d₋₁ : M → C(G, M) := const : m ↦ g ↦ m` and +`dₙ₊₁ : C(G, _) → C(G, C(G, _)) := const - C(G, dₙ) : f ↦ g ↦ f - dₙ (f (g))` +See `TopRep.d`. + +## Main definition +- `TopRep.homogeneousCochains`: + The functor taking an `R`-linear `G`-representation to the complex of homogeneous cochains. +- `continuousCohomology`: + The functor taking an `R`-linear `G`-representation to its `n`-th continuous cohomology. + +## TODO +- Show that it coincides with `groupCohomology` for discrete groups. +- Give the usual description of cochains in terms of `n`-ary functions for locally compact groups. +- Show that short exact sequences induce long exact sequences in certain scenarios. +-/ + +@[expose] public section + +variable {k G : Type*} [Ring k] [Group G] [TopologicalSpace k] [IsTopologicalRing k] + [TopologicalSpace G] [IsTopologicalGroup G] + +open CategoryTheory ContRepresentation Limits + +namespace TopRep + +/-- The `n`-th term in the resolution of a topological representation induced by `TopRep.coind₁`. -/ +abbrev resolutionX (X : TopRep k G) : ℕ → TopRep k G + | 0 => X + | n + 1 => (resolutionX X n).coind₁ + +/-- The boundary map in the resolution of a topological representation induced +by `TopRep.coind₁Functor`. -/ +def d (X : TopRep k G) : (n : ℕ) → resolutionX X n ⟶ resolutionX X (n + 1) + | 0 => ofHom X.ρ.coind₁ι + | n + 1 => ofHom (resolutionX X (n + 1)).ρ.coind₁ι - (coind₁Functor k G).map (d X n) + +lemma d_zero (X : TopRep k G) : d X 0 = ofHom X.ρ.coind₁ι := rfl + +lemma d_succ (X : TopRep k G) (n : ℕ) : + d X (n + 1) = ofHom (resolutionX X (n + 1)).ρ.coind₁ι - (coind₁Functor k G).map (d X n) := + rfl + +lemma hom_d_succ (X : TopRep k G) (n : ℕ) : + (d X (n + 1)).hom = (resolutionX X (n + 1)).ρ.coind₁ι - + ContRepresentation.coind₁Map _ _ (d X n).hom := + rfl + +@[reassoc (attr := simp)] +lemma d_comp_d (X : TopRep k G) (n : ℕ) : d X n ≫ d X (n + 1) = 0 := by + induction n with + | zero => + ext + simp [d_succ, ContIntertwiningMap.toContinuousLinearMap_apply, d_zero, hom_sub] + | succ n ih => + rw [d_succ _ (n + 1), Preadditive.comp_sub] + nth_rw 2 [d_succ] + rw [Preadditive.sub_comp, ← Functor.map_comp, ih, Functor.map_zero, sub_zero, sub_eq_zero] + rfl + +/-- The complex of functors whose behaviour pointwise takes an `R`-linear `G`-representation `M` +to the complex `M → C(G, M) → ⋯ → C(G, C(G,...,C(G, M))) → ⋯` +The `G`-invariant submodules of it is the homogeneous cochains (shifted by one). -/ +abbrev resolution (X : TopRep k G) : CochainComplex (TopRep k G) ℕ := + CochainComplex.of (resolutionX X) (d X) (d_comp_d X) + +/-- The shifted boundary map of the resolution. -/ +def resolution'd (X : TopRep k G) (n : ℕ) : + resolutionX X (n + 1) ⟶ resolutionX X (n + 1 + 1) := d X (n + 1) + +lemma resolution'd₀_eq (X : TopRep k G) : resolution'd X 0 = d X 1 := rfl + +/-- The shifted resolution of a topological representation by `1` degree. -/ +abbrev resolution' (X : TopRep k G) : CochainComplex (TopRep k G) ℕ := + CochainComplex.of (fun i ↦ (resolution X).X (i + 1)) + (resolution'd X) (fun n ↦ d_comp_d X (n + 1)) + +set_option allowUnsafeReducibility true in +attribute [local reducible] CategoryTheory.Functor.mapHomologicalComplex + +/-- The homogeneous cochains of a topological representation. -/ +abbrev homogeneousCochains (X : TopRep k G) : + CochainComplex (TopModuleCat k) ℕ := + ((invariantsFunctor k G).mapHomologicalComplex _).obj (resolution' X) + +lemma homogeneousCochains.d₀₁_eq (X : TopRep k G) : + (homogeneousCochains X).d 0 1 = (invariantsFunctor k G).map (d X 1) := by + rw [← resolution'd₀_eq]; rfl + +lemma homogeneousCochains.d₀₁_apply (X : TopRep k G) (σ : (homogeneousCochains X).X 0) : + ((homogeneousCochains X).d 0 1).hom σ = (d X 1).hom σ := rfl + +/-- The continuous cohomology of a continuous representation defined +by `continuousCohomologyFunctor`. -/ +noncomputable abbrev _root_.continuousCohomology (n : ℕ) (A : TopRep k G) : + TopModuleCat k := (homogeneousCochains A).homology n + +end TopRep + +namespace ContinuousCohomology + +open TopRep + +/-- The `n`-cocycles `Zⁿ(G, A)` of a `k`-linear `G`-representation `A`, i.e. the kernel of the +`n`th differential in the complex of homogeneous cochains. -/ +noncomputable abbrev cocycles (A : TopRep k G) (n : ℕ) : + TopModuleCat k := (homogeneousCochains A).cycles n + +/-- The natural map from `n`-cocycles to `n`th continuous cohomology for a `k`-linear +`G`-representation `A`. -/ +noncomputable abbrev π (A : TopRep k G) (n : ℕ) := (homogeneousCochains A).homologyπ n + +end ContinuousCohomology diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean new file mode 100644 index 00000000000000..9bbafc6b5e7407 --- /dev/null +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean @@ -0,0 +1,89 @@ +/- +Copyright (c) 2026 Richard Hill. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Richard Hill, Andrew Yang, Edison Xie +-/ +module + +public import Mathlib.RepresentationTheory.Homological.ContCohomology.Basic + +/-! +## Low degree continuous cohomology + +In this file we show that the zeroth continuous cohomology is isomorphic to the +invariants of the representation. +-/ + +@[expose] public section + +namespace ContinuousCohomology + +open CategoryTheory Functor TopRep ContRepresentation + +variable {k G : Type*} [CommRing k] [Group G] [TopologicalSpace k] [IsTopologicalRing k] + [TopologicalSpace G] [IsTopologicalGroup G] + +set_option allowUnsafeReducibility true in +attribute [local reducible] CategoryTheory.Functor.mapHomologicalComplex + +variable (X : TopRep k G) + +lemma cocycles₀IsoAux (σ : (homogeneousCochains X).X 0) + (hσ : σ ∈ ((homogeneousCochains X).d 0 1).hom.ker) : σ.1 1 ∈ X.ρ.invariants := by + simp only [Nat.reduceAdd, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, + Subtype.ext_iff, homogeneousCochains.d₀₁_apply _] at hσ + simp only [Nat.reduceAdd, mem_invariants] + intro g + rw [d_succ, hom_sub, hom_ofHom, ContIntertwiningMap.sub_apply, d_zero, + ZeroMemClass.coe_zero, sub_eq_zero] at hσ + replace hσ := DFunLike.ext_iff.1 (DFunLike.ext_iff.1 hσ 1) g⁻¹ + simp only [Nat.reduceAdd, coind₁ι_toFun, ContinuousMap.const_apply, ConcreteCategory.hom_ofHom, + coind₁Map_toFun, ContinuousMap.comp_apply, ContinuousMap.coe_mk] at hσ + simpa [hσ] using DFunLike.ext_iff.1 (σ.2 g) 1 + +lemma mem_const_resol₀ (x : X) (hx : x ∈ X.ρ.invariants) : + ContinuousMap.const G x ∈ ((resolution' X).X 0).ρ.invariants := + ContRepresentation.mem_invariants _|>.1 fun _ ↦ ContinuousMap.ext fun _ ↦ hx _ + +lemma cocycles₀IsoAux' (x : X) (h : ContinuousMap.const G x ∈ ((resolution' X).X 0).ρ.invariants) : + ⟨ContinuousMap.const G x, h⟩ ∈ ((homogeneousCochains X).d 0 1).hom.ker := by + rw [LinearMap.mem_ker, Subtype.ext_iff, ContinuousLinearMap.coe_coe, + homogeneousCochains.d₀₁_apply] + simp [d_succ, hom_sub, ContIntertwiningMap.sub_apply, d_zero] + +/-- The isomorphism between the zeroth cocycles and the kernel of the zeroth differential. -/ +noncomputable abbrev cocycles₀Iso : cocycles X 0 ≅ + TopModuleCat.of k ((homogeneousCochains X).d 0 1).hom.ker := + Limits.KernelFork.mapIsoOfIsLimit ((homogeneousCochains X).cyclesIsKernel 0 1 (by simp)) + (TopModuleCat.isLimitKer _) (Iso.refl _) + +/-- The isomorphism between the kernel of the zeroth differential and +the invariants of a representation. -/ +def d₀kerIso : ((homogeneousCochains X).d 0 1).hom.ker ≃L[k] X.ρ.invariants where + toFun := fun ⟨σ, hσ⟩ ↦ ⟨σ.val 1, cocycles₀IsoAux X σ hσ⟩ + map_add' _ _ := rfl + map_smul' _ _ := rfl + invFun := fun ⟨x, hx⟩ ↦ ⟨⟨ContinuousMap.const G x, mem_const_resol₀ X x hx⟩, + cocycles₀IsoAux' X x (mem_const_resol₀ X x hx)⟩ + left_inv := fun ⟨⟨(x : C(G, X)), hx'⟩, hx⟩ ↦ by + ext g + rw [LinearMap.mem_ker, Subtype.ext_iff, ContinuousLinearMap.coe_coe, + homogeneousCochains.d₀₁_apply] at hx + simp only [Nat.reduceAdd, d_succ, d_zero, ConcreteCategory.hom_ofHom, hom_sub, + ContIntertwiningMap.sub_apply, coind₁ι_toFun, coind₁Map_toFun, ZeroMemClass.coe_zero, + sub_eq_zero, ContinuousMap.const_apply] at hx ⊢ + simpa using DFunLike.ext_iff.1 (DFunLike.ext_iff.1 hx g) 1 + right_inv _ := rfl + continuous_toFun := continuous_induced_rng.2 <| (continuous_eval_const 1).comp <| + (continuous_subtype_val.comp continuous_subtype_val) + continuous_invFun := continuous_induced_rng.2 <| continuous_induced_rng.2 <| + ContinuousMap.continuous_const'.comp continuous_subtype_val + +/-- The isomorphism between the zeroth continuous cohomology group and +the invariants of a representation. -/ +noncomputable def zeroIso (A : TopRep k G) : + continuousCohomology 0 A ≅ TopModuleCat.of k A.ρ.invariants := + (homogeneousCochains A).isoHomologyπ₀.symm ≪≫ cocycles₀Iso A ≪≫ + TopModuleCat.ofIso (d₀kerIso A) + +end ContinuousCohomology diff --git a/Mathlib/Tactic/Linter/DirectoryDependency.lean b/Mathlib/Tactic/Linter/DirectoryDependency.lean index 4fae86eecdf634..9e9bd3ca160442 100644 --- a/Mathlib/Tactic/Linter/DirectoryDependency.lean +++ b/Mathlib/Tactic/Linter/DirectoryDependency.lean @@ -617,6 +617,7 @@ def overrideAllowedImportDirs : NamePrefixRel := .ofArray #[ (`Mathlib.Analysis.Convex.SimplicialComplex.AffineIndependentUnion, `Mathlib.AlgebraicTopology), (`Mathlib.Probability.Kernel.Category, `Mathlib.CategoryTheory), -- For the category of s-finite/Markov kernels (`Mathlib.RepresentationTheory.Continuous, `Mathlib.Topology), -- For continuous representations + (`Mathlib.RepresentationTheory.Homological.ContCohomology, `Mathlib.Topology), -- For continuous cohomology -- TODO: think about the role of Analysis and Algebra, and perhaps further separation (`Mathlib.Algebra.Order.Archimedean.Real, `Mathlib.Analysis), (`Mathlib.Algebra.Star.CHSH, `Mathlib.Analysis), From 6179d6d9709faae428ba33f3c5b3ce4c95b591a9 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:54:24 +0000 Subject: [PATCH 0562/1300] feat(Category/Preadditive/FreydCategory/Homotopy): homotopies on the category of arrows (#41292) Define left and right homotopies between morphisms of `Arrow V`, where `V` is a preadditive category. TODO: Define the preadditive categories `LeftFreyd V` (resp. `RightFreyd V`) obtained by taking the quotient of `Arrow V` by the left (resp. right) homotopy relation. If `V` has binary biproducts, this will have all kernels (resp. cokernels) and will be the category obtained by freely adjoining kernels (resp. cokernels) to `V`. Co-authored-by: morel --- Mathlib.lean | 1 + Mathlib/CategoryTheory/Preadditive/Comma.lean | 6 + .../Preadditive/FreydCategory/Homotopy.lean | 228 ++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 Mathlib/CategoryTheory/Preadditive/FreydCategory/Homotopy.lean diff --git a/Mathlib.lean b/Mathlib.lean index b1e9ba98809ce5..0886516fa8ae28 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3242,6 +3242,7 @@ public import Mathlib.CategoryTheory.Preadditive.CommGrp_ public import Mathlib.CategoryTheory.Preadditive.Comma public import Mathlib.CategoryTheory.Preadditive.EilenbergMoore public import Mathlib.CategoryTheory.Preadditive.EndoFunctor +public import Mathlib.CategoryTheory.Preadditive.FreydCategory.Homotopy public import Mathlib.CategoryTheory.Preadditive.FunctorCategory public import Mathlib.CategoryTheory.Preadditive.HomOrthogonal public import Mathlib.CategoryTheory.Preadditive.Indization diff --git a/Mathlib/CategoryTheory/Preadditive/Comma.lean b/Mathlib/CategoryTheory/Preadditive/Comma.lean index 0b7ab15aba7870..dc477de5a32189 100644 --- a/Mathlib/CategoryTheory/Preadditive/Comma.lean +++ b/Mathlib/CategoryTheory/Preadditive/Comma.lean @@ -107,6 +107,12 @@ lemma Arrow.Hom.add_left (α β : u ⟶ v) : (α + β).left = α.left + β.left @[simp] lemma Arrow.Hom.add_right (α β : u ⟶ v) : (α + β).right = α.right + β.right := rfl +@[simp] +lemma Arrow.Hom.sub_left (α β : u ⟶ v) : (α - β).left = α.left - β.left := rfl + +@[simp] +lemma Arrow.Hom.sub_right (α β : u ⟶ v) : (α - β).right = α.right - β.right := rfl + @[simp] lemma Arrow.Hom.zero_left : (0 : u ⟶ v).left = 0 := rfl diff --git a/Mathlib/CategoryTheory/Preadditive/FreydCategory/Homotopy.lean b/Mathlib/CategoryTheory/Preadditive/FreydCategory/Homotopy.lean new file mode 100644 index 00000000000000..c62a21ae54c0ce --- /dev/null +++ b/Mathlib/CategoryTheory/Preadditive/FreydCategory/Homotopy.lean @@ -0,0 +1,228 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Quotient +public import Mathlib.CategoryTheory.Preadditive.Comma + +/-! +# Homotopies in the arrow category + +We define left and right homotopies between morphisms of `Arrow V`, where `V` is +a preadditive category. + +TODO: Define the preadditive categories `LeftFreyd V` (resp. `RightFreyd V`) obtained by +taking the quotient of `Arrow V` by the left (resp. right) homotopy relation. If `V` +has binary biproducts, this will have all kernels (resp. cokernels) and will be the +category obtained by freely adjoining kernels (resp. cokernels) to `V`. + +-/ + +@[expose] public section + +noncomputable section + +open CategoryTheory Category + +variable {V : Type*} [Category* V] [Preadditive V] + +namespace CategoryTheory.Arrow + +variable {u v w : Arrow V} (f g : u ⟶ v) + +/-- A left homotopy on morphisms in the category of arrows of a preadditive category. -/ +@[ext] +structure LeftHomotopy where +/-- A "diagonal" morphism from the right object of `u` to the left object of `v`. -/ + hom : u.right ⟶ v.left +/-- The difference of the left morphisms factors through `hom`. -/ + comm : f.left - g.left = u.hom ≫ hom := by cat_disch + +/-- A right homotopy on morphisms in the category of arrows of a preadditive category. -/ +@[ext] +structure RightHomotopy where + /-- A "diagonal" morphism from the right object of `u` to the left object of `v`. -/ + hom : u.right ⟶ v.left + /-- The difference of the right morphisms factors through `hom`. -/ + comm : f.right - g.right = hom ≫ v.hom := by cat_disch + +variable {f g} + +namespace LeftHomotopy + +/-- `f` is left homotopic to `g` iff `f - g` is left homotopic to `0`. -/ +def equivSubZero : LeftHomotopy f g ≃ LeftHomotopy (f - g) 0 where + toFun h := + { hom := h.hom + comm := by simp [← h.comm]} + invFun h := + { hom := h.hom + comm := by simp [← h.comm]} + left_inv := by cat_disch + right_inv := by cat_disch + +/-- Equal maps of arrows are left homotopic. -/ +@[simps] +def ofEq (h : f = g) : LeftHomotopy f g where + hom := 0 + +/-- Every map of arrows is left homotopic to itself. -/ +@[simps!, refl] +def refl (f : u ⟶ v) : LeftHomotopy f f := + ofEq (rfl : f = f) + +/-- `f` is left homotopic to `g` iff `g` is left homotopic to `f`. -/ +@[simps!, symm] +def symm {f g : u ⟶ v} (h : LeftHomotopy f g) : LeftHomotopy g f where + hom := -h.hom + comm := by simp [← h.comm] + +/-- Left homotopy is a transitive relation. -/ +@[simps!, trans] +def trans {e f g : u ⟶ v} (h : LeftHomotopy e f) (k : LeftHomotopy f g) : LeftHomotopy e g where + hom := h.hom + k.hom + comm := by simp [← h.comm, ← k.comm] + +/-- The sum of two left homotopies is a left homotopy between the sum of the respective +morphisms. -/ +@[simps!] +def add {f₁ g₁ f₂ g₂ : u ⟶ v} (h₁ : LeftHomotopy f₁ g₁) (h₂ : LeftHomotopy f₂ g₂) : + LeftHomotopy (f₁ + f₂) (g₁ + g₂) where + hom := h₁.hom + h₂.hom + comm := by simp [← h₁.comm, ← h₂.comm, add_sub_add_comm] + +/-- Left homotopy is closed under composition (on the right). -/ +@[simps] +def compRight {e f : u ⟶ v} (h : LeftHomotopy e f) (g : v ⟶ w) : + LeftHomotopy (e ≫ g) (f ≫ g) where + hom := h.hom ≫ g.left + comm := by simp [← reassoc_of% h.comm] + +/-- Left homotopy is closed under composition (on the left). -/ +@[simps] +def compLeft {f g : v ⟶ w} (h : LeftHomotopy f g) (e : u ⟶ v) : + LeftHomotopy (e ≫ f) (e ≫ g) where + hom := e.right ≫ h.hom + comm := by simp [← reassoc_of% e.w, ← h.comm] + +/-- Left homotopy is closed under composition. -/ +@[simps!] +def comp {f₁ g₁ : u ⟶ v} {f₂ g₂ : v ⟶ w} + (h₁ : LeftHomotopy f₁ g₁) (h₂ : LeftHomotopy f₂ g₂) : LeftHomotopy (f₁ ≫ f₂) (g₁ ≫ g₂) := + (h₁.compRight _).trans (h₂.compLeft _) + +/-- A variant of `LeftHomotopy.compRight` useful for dealing with homotopy equivalences. -/ +@[simps!] +def compRightId {f : u ⟶ u} (h : LeftHomotopy f (𝟙 u)) (g : u ⟶ v) : LeftHomotopy (f ≫ g) g := + (h.compRight g).trans (ofEq <| id_comp _) + +/-- A variant of `LeftHomotopy.compLeft` useful for dealing with homotopy equivalences. -/ +@[simps!] +def compLeftId {f : v ⟶ v} (h : LeftHomotopy f (𝟙 v)) (g : u ⟶ v) : LeftHomotopy (g ≫ f) g := + (h.compLeft g).trans (ofEq <| comp_id _) + +end LeftHomotopy + +namespace RightHomotopy + +/-- `f` is right homotopic to `g` iff `f - g` is righthomotopic to `0`. -/ +def equivSubZero : RightHomotopy f g ≃ RightHomotopy (f - g) 0 where + toFun h := + { hom := h.hom + comm := by simp [← h.comm]} + invFun h := + { hom := h.hom + comm := by simp [← h.comm]} + left_inv := by cat_disch + right_inv := by cat_disch + +/-- Equal maps of arrows are right homotopic. -/ +@[simps] +def ofEq (h : f = g) : RightHomotopy f g where + hom := 0 + +/-- Every map of arrows is right homotopic to itself. -/ +@[simps!, refl] +def refl (f : u ⟶ v) : RightHomotopy f f := + ofEq (rfl : f = f) + +/-- `f` is right homotopic to `g` iff `g` is right homotopic to `f`. -/ +@[simps!, symm] +def symm {f g : u ⟶ v} (h : RightHomotopy f g) : RightHomotopy g f where + hom := -h.hom + comm := by simp [← h.comm] + +/-- Right homotopy is a transitive relation. -/ +@[simps!, trans] +def trans {e f g : u ⟶ v} (h : RightHomotopy e f) (k : RightHomotopy f g) : RightHomotopy e g where + hom := h.hom + k.hom + comm := by simp [← h.comm, ← k.comm] + +/-- The sum of two right homotopies is a right homotopy between the sum of the respective +morphisms. -/ +@[simps!] +def add {f₁ g₁ f₂ g₂ : u ⟶ v} (h₁ : RightHomotopy f₁ g₁) (h₂ : RightHomotopy f₂ g₂) : + RightHomotopy (f₁ + f₂) (g₁ + g₂) where + hom := h₁.hom + h₂.hom + comm := by simp [← h₁.comm, ← h₂.comm, add_sub_add_comm] + +/-- Right homotopy is closed under composition (on the right). -/ +@[simps] +def compRight {e f : u ⟶ v} (h : RightHomotopy e f) (g : v ⟶ w) : + RightHomotopy (e ≫ g) (f ≫ g) where + hom := h.hom ≫ g.left + comm := by simp [← reassoc_of% h.comm] + +/-- Right homotopy is closed under composition (on the left). -/ +@[simps] +def compLeft {f g : v ⟶ w} (h : RightHomotopy f g) (e : u ⟶ v) : + RightHomotopy (e ≫ f) (e ≫ g) where + hom := e.right ≫ h.hom + comm := by simp [← h.comm] + +/-- Right homotopy is closed under composition. -/ +@[simps!] +def comp {f₁ g₁ : u ⟶ v} {f₂ g₂ : v ⟶ w} + (h₁ : RightHomotopy f₁ g₁) (h₂ : RightHomotopy f₂ g₂) : RightHomotopy (f₁ ≫ f₂) (g₁ ≫ g₂) := + (h₁.compRight _).trans (h₂.compLeft _) + +/-- A variant of `RightHomotopy.compRight` useful for dealing with homotopy equivalences. -/ +@[simps!] +def compRightId {f : u ⟶ u} (h : RightHomotopy f (𝟙 u)) (g : u ⟶ v) : RightHomotopy (f ≫ g) g := + (h.compRight g).trans (ofEq <| id_comp _) + +/-- A variant of `RightHomotopy.compLeft` useful for dealing with homotopy equivalences. -/ +@[simps!] +def compLeftId {f : v ⟶ v} (h : RightHomotopy f (𝟙 v)) (g : u ⟶ v) : RightHomotopy (g ≫ f) g := + (h.compLeft g).trans (ofEq <| comp_id _) + +end RightHomotopy + +variable (V) + +/-- The left homotopy relation on morphisms of `Arrow V`. -/ +def leftHomotopic : HomRel (Arrow V) := fun _ _ f g => Nonempty (LeftHomotopy f g) + +instance leftHomotopy_congruence : Congruence (leftHomotopic V) where + equivalence := + { refl := fun C => ⟨LeftHomotopy.refl C⟩ + symm := fun ⟨w⟩ => ⟨w.symm⟩ + trans := fun ⟨w₁⟩ ⟨w₂⟩ => ⟨w₁.trans w₂⟩ } + comp_left := fun _ _ _ ⟨i⟩ => ⟨i.compLeft _⟩ + comp_right := fun _ ⟨i⟩ => ⟨i.compRight _⟩ + +/-- The left homotopy relation on morphisms of `Arrow V`. -/ +def rightHomotopic : HomRel (Arrow V) := fun _ _ f g => Nonempty (RightHomotopy f g) + +instance rightHomotopy_congruence : Congruence (rightHomotopic V) where + equivalence := + { refl := fun C => ⟨RightHomotopy.refl C⟩ + symm := fun ⟨w⟩ => ⟨w.symm⟩ + trans := fun ⟨w₁⟩ ⟨w₂⟩ => ⟨w₁.trans w₂⟩ } + comp_left := fun _ _ _ ⟨i⟩ => ⟨i.compLeft _⟩ + comp_right := fun _ ⟨i⟩ => ⟨i.compRight _⟩ + +end CategoryTheory.Arrow From 2dd999421c4ce616b4d25267a204717d25fdab55 Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:14:59 +0000 Subject: [PATCH 0563/1300] feat: add normalization simproc for Bird's determinant algorithm (#41158) add `birdDet`, an implementation of a division-free determinant algorithm [1], and `norm_det` / `eval_det` frontend for normalizing expressions that use `birdDet`. The algorithm can be used for matrices with symbolic entries over a `CommRing` (see example below). The normalizer uses the ring tactic's normalisation infrastructure to produce a certificate chain between the `birdDet` expression and the computed determinant. I chose this particular algorithm because it is efficient enough to work with ~10x10 matrices, and is division-free and so can work with matrices with elements in a general commutative ring. For example: ```lean example {R: Type*} [CommRing R] (a b c d : R) : birdDet 2 #[a, b, c, d] = a * d - b * c := by simp only [norm_det] ring ``` [1]: https://doi.org/10.1016/j.ipl.2011.08.006 --- Mathlib.lean | 4 + .../Matrix/Determinant/Bird.lean | 131 ++++++ Mathlib/Tactic.lean | 3 + Mathlib/Tactic/Determinant/Bird.lean | 34 ++ Mathlib/Tactic/Determinant/Bird/Cert.lean | 412 ++++++++++++++++++ Mathlib/Tactic/Determinant/Bird/Meta.lean | 118 +++++ MathlibTest/matrix.lean | 64 +++ 7 files changed, 766 insertions(+) create mode 100644 Mathlib/LinearAlgebra/Matrix/Determinant/Bird.lean create mode 100644 Mathlib/Tactic/Determinant/Bird.lean create mode 100644 Mathlib/Tactic/Determinant/Bird/Cert.lean create mode 100644 Mathlib/Tactic/Determinant/Bird/Meta.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0886516fa8ae28..26e316b99e5460 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5095,6 +5095,7 @@ public import Mathlib.LinearAlgebra.Matrix.Circulant public import Mathlib.LinearAlgebra.Matrix.ConjTranspose public import Mathlib.LinearAlgebra.Matrix.Defs public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird public import Mathlib.LinearAlgebra.Matrix.Determinant.Misc public import Mathlib.LinearAlgebra.Matrix.Determinant.TotallyUnimodular public import Mathlib.LinearAlgebra.Matrix.Diagonal @@ -7277,6 +7278,9 @@ public import Mathlib.Tactic.DeriveCountable public import Mathlib.Tactic.DeriveEncodable public import Mathlib.Tactic.DeriveFintype public import Mathlib.Tactic.DeriveTraversable +public import Mathlib.Tactic.Determinant.Bird +public import Mathlib.Tactic.Determinant.Bird.Cert +public import Mathlib.Tactic.Determinant.Bird.Meta public import Mathlib.Tactic.ENatToNat public import Mathlib.Tactic.Eqns public import Mathlib.Tactic.ErwQuestion diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Bird.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird.lean new file mode 100644 index 00000000000000..f482861da89563 --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird.lean @@ -0,0 +1,131 @@ +/- +Copyright (c) 2026 Paul Cadman. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Paul Cadman +-/ +module + +public import Mathlib.Algebra.Ring.Defs + +/-! + +# A division-free determinant algorithm + +This file defines `birdDet`, an implementation of an division-free algorithm for +computing determinants. The algorithm runs in O(n^4) for an n-by-n matrix. + +This determinant algorithm comes from: + +Title: A simple division-free algorithm for computing determinants. +Author: Richard S. Bird +URL: https://doi.org/10.1016/j.ipl.2011.08.006 + +## Main definitions + +- `BirdDet.birdDet`: The entrypoint for the determinant calculation. +- `BirdDet.get`: matrix entry lookup. +- `BirdDet.sumFrom`: The sum `f lo + ... + f (n - 1)`. +- `BirdDet.iter`: The internal scalar recurrence for Bird's algorithm. + +## Main lemmas + +The lemmas in this file are unfolding equations. + +-/ + +public section + +namespace BirdDet + +variable {R : Type*} [CommRing R] + +/-- +`get n A i j` returns the (i, j)th entry of the `n × n` matrix whose entries are +stored in `A` in row-major order. + +The function does not check the matrix index bounds. +-/ +@[expose] protected def get (n : ℕ) (A : Array R) (i j : ℕ) : R := + A.getD (i * n + j) 0 + +/-- Sum `f lo + ... + f (n - 1)`. Returns zero when `n <= lo`. -/ +@[expose] protected def sumFrom (n lo : ℕ) (f : ℕ → R) : R := + if lo < n then f lo + BirdDet.sumFrom n (lo + 1) f else 0 + +/-- +# Scalar formula for one recurrence step. + +Bird's paper defines a matrix recursion for an `n × n` matrix `A`: + +``` +F_0 = A +F_{t+1} = μ(F_t) * A +``` + +where `μ(F_t)` is obtained from `F_t` by replacing each diagonal entry +`F_t k k` with the negative sum of the diagonal entries below it, setting the +entries in the lower triangular part to 0, and leaving all other entries +unchanged: + +``` +μ(F_t) = + 0 if i >= j + - ∑ k from i+1 to n-1, F_t k k if i = j + F_t i j if i < j +``` + +If we write out the entry-wise matrix multiplication `F_{t+1} i j = (μ(F_t) * A) i j` +we obtain: + +``` +F_{t+1} i j = + - (∑ k from i+1 to n-1, F_t k k) * (A i j) + + ∑ k from i+1 to n-1, (F_t i k) * (A k j) +``` +-/ +@[expose] protected def iter (n : ℕ) (A : Array R) (t : ℕ) (F : ℕ → ℕ → R) : ℕ → ℕ → R := + match t with + | 0 => F + | t + 1 => fun i j => + -(BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F k k) * BirdDet.get n A i j + + BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F i k * BirdDet.get n A k j + +/-- +`birdDet n A` computes the determinant of the `n × n` matrix whose entries are +stored in `A` in row-major order. +-/ +@[expose] def birdDet (n : ℕ) (A : Array R) : R := + match n with + | 0 => 1 + | k + 1 => (-1 : R) ^ k * BirdDet.iter n A k (BirdDet.get n A) 0 0 + +/- Unfolding lemmas -/ + +theorem sumFrom_step (n lo : ℕ) (f : ℕ → R) (h : lo < n) : + BirdDet.sumFrom n lo f = f lo + BirdDet.sumFrom n (lo + 1) f := by + rw [BirdDet.sumFrom] + simp [h] + +theorem sumFrom_stop (n lo : ℕ) (f : ℕ → R) (h : ¬ lo < n) : + BirdDet.sumFrom n lo f = 0 := by + rw [BirdDet.sumFrom] + simp [h] + +theorem iter_zero (n : ℕ) (A : Array R) (F : ℕ → ℕ → R) (i j : ℕ) : + BirdDet.iter n A 0 F i j = F i j := rfl + +theorem iter_succ (n : ℕ) (A : Array R) (t : ℕ) (F : ℕ → ℕ → R) (i j : ℕ) : + BirdDet.iter n A (t + 1) F i j = + -(BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F k k) * BirdDet.get n A i j + + BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F i k * BirdDet.get n A k j := rfl + +theorem birdDet_zero (A : Array R) : birdDet 0 A = 1 := rfl + +theorem birdDet_eq (n k : ℕ) (A : Array R) (hn : n = k + 1) : + birdDet n A = (-1 : R) ^ k * BirdDet.iter n A k (BirdDet.get n A) 0 0 := by + subst hn + rfl + +end BirdDet + +end diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index b09c506d6e6a86..40152d484fd5dd 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -99,6 +99,9 @@ public import Mathlib.Tactic.DeriveCountable public import Mathlib.Tactic.DeriveEncodable public import Mathlib.Tactic.DeriveFintype public import Mathlib.Tactic.DeriveTraversable +public import Mathlib.Tactic.Determinant.Bird +public import Mathlib.Tactic.Determinant.Bird.Cert +public import Mathlib.Tactic.Determinant.Bird.Meta public import Mathlib.Tactic.ENatToNat public import Mathlib.Tactic.Eqns public import Mathlib.Tactic.ErwQuestion diff --git a/Mathlib/Tactic/Determinant/Bird.lean b/Mathlib/Tactic/Determinant/Bird.lean new file mode 100644 index 00000000000000..05fdc2ae97903a --- /dev/null +++ b/Mathlib/Tactic/Determinant/Bird.lean @@ -0,0 +1,34 @@ +/- +Copyright (c) 2026 Paul Cadman. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Paul Cadman +-/ +module + +public import Mathlib.Tactic.Determinant.Bird.Cert + +/-! +# `norm_det` simproc and `eval_det` tactic + +A tactic for normalizing matrix determinants. +-/ + +public meta section + +open Lean Meta Elab Tactic Simp +open Mathlib.Tactic.Determinant + +/-- reify a `BirdDet` call and normalize it using the certificate-chain evaluator -/ +def normalizeBirdDet (e : Expr) : MetaM Simp.Result := do + let ⟨rα, ctx⟩ ← reifyBirdDet e + let detNorm ← certBirdDet (rα := rα) |>.run' {} |>.run ctx |>.run .reducible + Mathlib.Tactic.RingNF.cleanup {} {expr := detNorm.norm, proof? := some detNorm.proof} + +/-- Normalize a literal `birdDet` call using the certificate-chain evaluator. -/ +simproc_decl norm_det (BirdDet.birdDet _ _) := fun e => do + return .done (← normalizeBirdDet e) + +/-- Normalize `birdDet` calls in the target using the certificate-chain simproc. -/ +macro (name := evalDet) "eval_det" : tactic => `(tactic| simp only [norm_det]) + +end diff --git a/Mathlib/Tactic/Determinant/Bird/Cert.lean b/Mathlib/Tactic/Determinant/Bird/Cert.lean new file mode 100644 index 00000000000000..e92e0829b6d1ad --- /dev/null +++ b/Mathlib/Tactic/Determinant/Bird/Cert.lean @@ -0,0 +1,412 @@ +/- +Copyright (c) 2026 Paul Cadman. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Paul Cadman +-/ +module + +public meta import Mathlib.Tactic.Determinant.Bird.Meta +public meta import Mathlib.Tactic.Ring + +/-! + +# Certificate-chain evaluator for `BirdDet.birdDet` + +This file contains an evaulator that computes the ring tactic normal form of +`Mathlib.LinearAlgebra.Matrix.Determinant.Bird.birdDet` via iteratively +unfolding its definition, using the ring tactic for ring operations, and caching +intermediate certificates. + +The structure `Cert rα` carries the proof certificate and the evaluator builds +larger certificates as `birdDet` is unfolded. + +The entrypoint of the evaluator `certBirdDet` follows the two branches (n=0, +n=k+1) of the `birdDet` function: + +``` +certBirdDet (birdDet n A) + n = 0: + birdDet n A + = 1 -- via BirdDet.birdDet_zero + = ring normal form of 1 -- via certEval + n = k + 1: + birdDet n A + = (-1)^k * iter n A k (get n A) 0 0 -- via BirdDet.birdDet_eq + = ring normal form of the product -- certMul (certBirdSign k) (certIter k 0 0) +``` + +The `iter n A k (get n A) i j` function branches on k, (k=0, k=t+1) and +therefore the `certIter` function has two branches: + +``` +certIter k i j + k = 0: + iter n A 0 F i j = F i j -- via BirdDet.iter_zero + = ring normal form of A[i][j] -- via certEntry i j + k = t + 1: + iter n A (t + 1) F i j + = -(sumFrom n (i + 1) fun k => iter n A t F k k) * get n A i j + + sumFrom n (i + 1) fun k => iter n A t F i k * get n A k j + -- via BirdDet.iter_succ + = normal form of the first summand + normal form of the second summand + -- via certAdd + (certMul (certNeg (certDiag t (i + 1))) (certEntry i j)) + (certTail t i j (i + 1)) +``` + +Then the `certDiag` and `certTail` functions certify the two kinds of `sumFrom` +expressions. + +The evaulator also memoizes the `certIter`, `certDiag` and `certEntry` functions +to improve performance. + +## Main definitions + +- `certEntry` certifies `BirdDet.get`. +- `certSumFromStop` and `certSumFromStep` certifies `BirdDet.sumFrom_stop` and + `BirdDet.sumFrom_step`. +- `certIter` certifies `BirdDet.iter_zero` and `BirdDet.iter_succ`. +- `certBirdDet` certifies `BirdDet.birdDet_zero` and `BirdDet.birdDet_eq`. +-/ + +public meta section + +open Lean Meta Qq +open Mathlib.Tactic.Ring + +variable {u : Level} {α : Q(Type u)} {rα : Q(CommRing $α)} + +namespace Mathlib.Tactic.Determinant + +/-- The ring tactic normal-form value. -/ +abbrev CertVal {u : Level} {α : Q(Type u)} + (rα : Q(CommRing $α)) (e : Q($α)) := + Common.ExSum RatCoeff (commSemiringOfCommRing rα) e + +/-- The ring tactic result carried by a certificate. -/ +abbrev CertResult {u : Level} {α : Q(Type u)} + (rα : Q(CommRing $α)) (subject : Q($α)) := + Common.Result (CertVal rα) subject + +namespace Ctx + +/-- Return an expression for the partially applied function `iter n A t (get n A)` -/ +def iterP (ctx : Ctx rα) (t : ℕ) : Q(ℕ → ℕ → $α) := + let dim : Q(ℕ) := ctx.dimensionLit + let A : Q(Array $α) := ctx.arrayExpr + q(BirdDet.iter $dim $A $t (BirdDet.get $dim $A)) + +/-- Return an expression `sumFrom n lo f` -/ +def sumFrom (ctx : Ctx rα) (lo : ℕ) (f : Q(ℕ → $α)) : Q($α) := + let dim : Q(ℕ) := ctx.dimensionLit + q(BirdDet.sumFrom $dim $lo $f) + +end Ctx + +/-- A certificate that proves `subject = result.norm` via `result.proof` -/ +structure Cert {u : Level} {α : Q(Type u)} (rα : Q(CommRing $α)) where + /-- The expression being certified. -/ + {subject : Q($α)} + /-- The result of evaluating `subject` using the ring tactic. -/ + result : CertResult rα subject + /-- `true` when `norm` is zero, used as a hint to the evaluator. -/ + isZero : Bool + +namespace Cert + +variable + {u : Level} + {α : Q(Type u)} + {rα : Q(CommRing $α)} + +/-- The ring tactic normal form of `c.subject` -/ +def norm (c : Cert rα) : Q($α) := + c.result.expr + +/-- The internal ring tactic representation of `c.norm` -/ +def val (c : Cert rα) : CertVal rα c.norm := + c.result.val + +/-- The proof that `c.subject = c.norm` -/ +def proof (c : Cert rα) : Q($c.subject = $c.norm) := + c.result.proof + +/-- Prepend an equality to an existing normalized certificate. + +Given `c.proof : s.subject = c.norm` and `h : lhs = s.subject` return a +certificate with `proof : lhs = c.norm`. +-/ +def chainProof {lhs rhs : Q($α)} (c : Cert rα) (h : Q($lhs = $rhs)) : Cert rα := + have : $rhs =Q $c.subject := ⟨⟩ + let hProof : Q($lhs = $c.subject) := h + let proof : Q($lhs = $c.norm) := q(Eq.trans $hProof $c.proof) + { c with + subject := lhs + result.proof := proof + } + +end Cert + +/-- Cache certificates that are reused by the recursive Bird evaluator. -/ +structure CertCache {u : Level} {α : Q(Type u)} (rα : Q(CommRing $α)) where + /-- Cache for entry certificates, keyed by matrix indices. -/ + entryCache : Std.HashMap (ℕ × ℕ) (Cert rα) := {} + /-- Cache for `iter` certificates, keyed by recursion index and matrix indices. -/ + iterCache : Std.HashMap (ℕ × ℕ × ℕ) (Cert rα) := {} + /-- Cache for diagonal-tail certificates, keyed by recursion index and lower bound. -/ + diagCache : Std.HashMap (ℕ × ℕ) (Cert rα) := {} + +/-- The monad used by the certificate-chaining evaluator -/ +abbrev CertM {u : Level} {α : Q(Type u)} (rα : Q(CommRing $α)) := + StateT (CertCache rα) (ReaderT (Ctx rα) AtomM) + +/-- Checks if `val` is zero according to the ring tactic -/ +def isZeroVal {e : Q($α)} (val : CertVal rα e) : Bool := + match val with + | .zero => true + | .add .. => false + +/-- Construct a `Cert rα` from a ring tactic result -/ +def toCert {e : Q($α)} (res : Common.Result (CertVal rα) e) : Cert rα := + { result := res + isZero := isZeroVal res.val } + +/-- Build a zero certificate from a proof `lhs = 0`. -/ +def zeroCertOfProof {lhs : Q($α)} (h : Q($lhs = 0)) : Cert rα where + result.expr := q(0) + result.val := .zero + result.proof := h + isZero := true + +/-- If c.norm = 0, return a certificate with proof `x * c.subject = 0` without +recursively certifying `x`. -/ +def zeroProdCert (x : Q($α)) (c : Cert rα) : + MetaM (Cert rα) := do + let zero : Q($α) := q(0) + have : $c.norm =Q $zero := ⟨⟩ + let h : Q($x * $c.subject = $x * $zero) := + q(congrArg (fun y => $x * y) $c.proof) + return zeroCertOfProof q(Eq.trans $h (mul_zero $x)) + +/-- Certify `e = norm` by evaluating `e` with the `ring` normalizer. -/ +def certEval (e : Q($α)) : CertM rα (Cert rα) := do + let ctx ← read + let res ← Common.eval rcℕ ctx.rc ctx.cα e + return toCert res + +/-- Certify `a.subject + b.subject` from certificates for `a` and `b`. -/ +def certAdd (a b : Cert rα) : CertM rα (Cert rα) := do + let ctx ← read + let c ← toCert <$> Common.evalAdd ctx.rc rcℕ a.val b.val + let h : Q($a.subject + $b.subject = $a.norm + $b.norm) := + q(congr (congrArg (fun x y => x + y) $a.proof) $b.proof) + return c.chainProof h + +/-- Certify `a.subject * b.subject` from certificates for `a` and `b`. -/ +def certMul (a b : Cert rα) : CertM rα (Cert rα) := do + let ctx ← read + let c ← toCert <$> Common.evalMul ctx.rc rcℕ a.val b.val + let h : Q($a.subject * $b.subject = $a.norm * $b.norm) := + q(congr (congrArg (fun x y => x * y) $a.proof) $b.proof) + return c.chainProof h + +/-- Certify `-a.subject` from a certificate for `a`. -/ +def certNeg (a : Cert rα) : CertM rα (Cert rα) := do + let ctx ← read + let c ← toCert <$> Common.evalNeg ctx.rc rα a.val + let h : Q(-$a.subject = -$a.norm) := + q(congrArg (fun x => -x) $a.proof) + return c.chainProof h + +/-- Certify the sign factor `(-1)^k` from `BirdDet.birdDet_eq`. -/ +def certBirdSign (k : ℕ) : CertM rα (Cert rα) := do + certEval q((-1 : $α) ^ $k) + +/-- Certify one matrix entry lookup `BirdDet.get n A i j`. -/ +def certEntry (i j : ℕ) : CertM rα (Cert rα) := do + if let some c := (← get).entryCache[(i, j)]? then + return c + let ctx ← read + let {dimension := dim, dimensionLit := dimLit, arrayExpr := A, arrayEntries, ..} := ctx + let lhs : Q($α) := q(BirdDet.get $dimLit $A $i $j) + -- The index of the matrix entry (i, j) in arrayEntries + let idx := i * dim + j + let entry := arrayEntries.getD idx q(0) + let ce ← certEval entry + have : $lhs =Q $entry := ⟨⟩ + let h : Q($lhs = $entry) := q(rfl) + let cert := ce.chainProof h + modify fun s => {s with entryCache := s.entryCache.insert (i, j) cert} + return cert + +/-- Certify the stop branch of `BirdDet.sumFrom`. + +This corresponds to the `else 0` branch of: + +``` +sumFrom n lo f = if lo < n then f lo + sumFrom n (lo + 1) f else 0 +``` + +Throws a meta-level error if called with `lo` such that `lo < ctx.dimension`. +-/ +def certSumFromStop (lo : ℕ) (f : Q(ℕ → $α)) : CertM rα (Cert rα) := do + let ctx ← read + if lo < ctx.dimension then + throwError "certSumFromStop called with {lo} such that {lo} < {ctx.dimension}" + have dimLit : Q(ℕ) := ctx.dimensionLit + let hNot : Q(¬ $lo < $dimLit) ← mkDecideProofQ q(¬ $lo < $dimLit) + return zeroCertOfProof q(BirdDet.sumFrom_stop $dimLit $lo $f $hNot) + +/-- Certify the step branch of `BirdDet.sumFrom`. + +This corresponds to the `lo < n` branch of: + +``` +sumFrom n lo f = if lo < n then f lo + sumFrom n (lo + 1) f else 0 +``` + +Throws a meta-level error if called with `lo` such that `¬ lo < ctx.dimension`. +-/ +def certSumFromStep + (lo : ℕ) (f : Q(ℕ → $α)) + (headCert tailCert : CertM rα (Cert rα)) : CertM rα (Cert rα) := do + let ctx ← read + unless lo < ctx.dimension do + throwError "certSumFromStep called with {lo} such that ¬ {lo} < {ctx.dimension}" + have dim : Q(ℕ) := ctx.dimensionLit + let hLt : Q($lo < $dim) ← mkDecideProofQ q($lo < $dim) + let sumCert ← certAdd (← headCert) (← tailCert) + return sumCert.chainProof q(BirdDet.sumFrom_step $dim $lo $f $hLt) + +mutual + +/-- Certify a `BirdDet.iter` call. -/ +partial def certIter (t i j : ℕ) : CertM rα (Cert rα) := do + if let some c := (← get).iterCache[(t, i, j)]? then + return c + let ctx ← read + let {dimensionLit := dimLit, arrayExpr := A, ..} := ctx + let cert ← match t with + -- The t=0 branch of `BirdDet.iter`, unfold using `BirdDet.iter_zero` + | 0 => do + let ce ← certEntry i j + let h := q(BirdDet.iter_zero $dimLit $A (BirdDet.get $dimLit $A) $i $j) + pure (ce.chainProof h) + -- The t=t+1 branch of `BirdDet.iter`, unfold using `BirdDet.iter_succ` + | t' + 1 => do + -- First summand in `BirdDet.iter_succ`: + -- -(sumFrom n (i + 1) fun k => F_t k k) * get n A i j + let diagSummand := q(fun k => $(ctx.iterP t') k k) + let negDiagSum := q(-$(ctx.sumFrom (i + 1) diagSummand)) + let entryCert ← certEntry i j + let diagProdCert ← + -- If `get n A i j = 0` then we can skip computation of + -- `-(sumFrom n (i + 1) fun k => F_t k k)` + if entryCert.isZero then + zeroProdCert negDiagSum entryCert + else do + let diagSumCert ← certDiag t' (i + 1) + let negDiagSumCert ← certNeg diagSumCert + certMul negDiagSumCert entryCert + -- Second summand in `BirdDet.iter_succ`: + -- sumFrom n (i + 1) fun k => F_t i k * get n A k j + let tailSumCert ← certTail t' i j (i + 1) + let rhsCert ← certAdd diagProdCert tailSumCert + let h := q(BirdDet.iter_succ $dimLit $A $t' (BirdDet.get $dimLit $A) $i $j) + pure (rhsCert.chainProof h) + modify fun s => {s with iterCache := s.iterCache.insert (t, i, j) cert} + return cert + + +/-- Certify the diagonal tail sum from `BirdDet.iter_succ`: + +``` +sumFrom n (i + 1) fun k => iter n A t F k k) +``` +-/ +partial def certDiag (t lo : ℕ) : CertM rα (Cert rα) := do + if let some c := (← get).diagCache[(t, lo)]? then + return c + let ctx ← read + let diagonalSummand := q(fun k => $(ctx.iterP t) k k) + let cert ← + if lo < ctx.dimension + then do + let headCert := certIter t lo lo + let tailCert := certDiag t (lo + 1) + certSumFromStep + lo + diagonalSummand + headCert + tailCert + else + certSumFromStop lo diagonalSummand + modify fun s => {s with diagCache := s.diagCache.insert (t, lo) cert} + return cert + +/-- Certify the upper-tail sum from `BirdDet.iter_succ`: + +``` +sumFrom n (i + 1) fun k => iter n A t F i k * get n A k j +``` +-/ +partial def certTail (t i j lo : ℕ) : CertM rα (Cert rα) := do + let ctx ← read + let {dimensionLit := dimLit, arrayExpr := A, ..} := ctx + let tailSummand := + q(fun k => + $(ctx.iterP t) $i k * + BirdDet.get $dimLit $A k $j) + if lo < ctx.dimension + then do + -- headCert certifies `iter n A t F i lo * get n A lo j` + let headCert := do + let entryCert ← certEntry lo j + -- If `get n A lo j = 0` then we can skip computation of + -- `iter n A t F i lo` + if entryCert.isZero + then + zeroProdCert + q($(ctx.iterP t) $i $lo) + entryCert + else do + let iterCert ← certIter t i lo + certMul iterCert entryCert + let tailCert := certTail t i j (lo + 1) + certSumFromStep + lo + tailSummand + headCert + tailCert + else + certSumFromStop lo tailSummand + +end + +/-- Certify a `BirdDet.birdDet n A` call. -/ +def certBirdDet : CertM rα (Cert rα) := do + let ctx ← read + let {dimension := dim, dimensionLit := dimLit, arrayExpr, ..} := ctx + if dim == 0 + then + let ce ← certEval q(1 : $α) + have : $dimLit =Q 0 := ⟨⟩ + have A : Q(Array $α) := arrayExpr + let h := q(BirdDet.birdDet_zero $A) + return ce.chainProof h + else + -- The non-zero `BirdDet.birdDet_eq` branch matches `k + 1` + -- so we set k := `ctx.dimension - 1`. + let k := dim - 1 + let cs ← certBirdSign k + let ci ← certIter k 0 0 + let cm ← certMul cs ci + have kLit := mkNatLitQ k + have : $dimLit =Q $kLit + 1 := ⟨⟩ + let hn : Q($dimLit = $kLit + 1) := q(rfl) + let h := q(BirdDet.birdDet_eq $dimLit $kLit $arrayExpr $hn) + return cm.chainProof h + +end Mathlib.Tactic.Determinant + +end diff --git a/Mathlib/Tactic/Determinant/Bird/Meta.lean b/Mathlib/Tactic/Determinant/Bird/Meta.lean new file mode 100644 index 00000000000000..2b16374f8da6c0 --- /dev/null +++ b/Mathlib/Tactic/Determinant/Bird/Meta.lean @@ -0,0 +1,118 @@ +/- +Copyright (c) 2026 Paul Cadman. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Paul Cadman +-/ +module + +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird +public meta import Mathlib.Tactic.Ring +public meta import Mathlib.Util.Qq + +/-! +# Reification support for the determinant tactic + +This file contains the meta-level parser, `refiyBirdDet`, used by +`normalizeBirdDet` to turn `BirdDet.birdDet` calls into the context used by the +certificate-chain evaluator. + +## Main definitions + +- `reifyBirdDet`: Parse a call to `BirdDet.birdDet`. + +-/ + +public meta section + +open Lean Meta Qq +open Mathlib.Tactic.Ring + +namespace Mathlib.Tactic.Determinant + +/-- Construct a `CommSemiring` instance expression from a `CommRing` instance expression -/ +abbrev commSemiringOfCommRing {u : Level} {α : Q(Type u)} + (rα : Q(CommRing $α)) : Q(CommSemiring $α) := + q(CommRing.toCommSemiring (α := $α) (s := $rα)) + +/-- Parse an array literal into an array of element expressions. + +Compared to `getArrayLit?`, this also performs `whnf`. +-/ +def arrayLiteral? (e : Expr) : MetaM (Option (Array Expr)) := do + if let some elems ← getArrayLit? e then return some elems + let e ← whnf e + match_expr e with + | Array.mk _ xs => getListLit? xs + | _ => return none + +/-- The context for a certificate evaluation. -/ +structure Ctx {u : Level} {α : Q(Type u)} (rα : Q(CommRing $α)) where + /-- `Ring` evaluation cache for the scalar ring. -/ + cα : Common.Cache (commSemiringOfCommRing rα) + /-- Proof-producing ring arithmetic. -/ + rc : Common.RingCompute RatCoeff (commSemiringOfCommRing rα) + /-- The dimension of the reified matrix -/ + dimension : ℕ + /-- The quoted dimension expression from the reified determinant call. -/ + dimensionLit : Q(ℕ) + /-- The array of matrix entries as an Expr -/ + arrayExpr : Q(Array $α) + /-- An array of matrix entry `Expr`s` -/ + arrayEntries : Array Q($α) + +/-- The ring instance and evaluator context parsed by `reifyBirdDet`. -/ +structure ReifiedBirdDet where + /-- The universe level associated with the `birdDet` call -/ + {u : Level} + /-- The type of a matrix entry -/ + {α : Q(Type u)} + /-- The `CommRing` instance for matrix entries -/ + rα : Q(CommRing $α) + /-- The evaluator context for the parsed determinant expression. -/ + ctx : Ctx rα + +/-- Recognise a `birdDet` call and reify it into an evaluator context. -/ +def reifyBirdDet (e : Expr) : MetaM ReifiedBirdDet := do + let e ← instantiateMVars e + let ⟨_, α, _⟩ ← inferTypeQ' e + let_expr BirdDet.birdDet _ birdRingInst dimensionExpr arrayExpr := e + | throwError "expected an application of `birdDet, got {e}" + let some rα ← checkTypeQ birdRingInst q(CommRing $α) + | throwError "expected `birdDet` ring instance to have type {q(CommRing $α)}" + let dimensionExpr ← whnf dimensionExpr + let some dimensionLit ← checkTypeQ dimensionExpr q(ℕ) + | throwError "expected the dimension to have type `ℕ`, got {dimensionExpr}" + let some dimension ← getNatValue? dimensionLit + | throwError "expected the dimension to be a `ℕ` literal, got {dimensionLit}" + let some arrayExpr ← checkTypeQ arrayExpr q(Array $α) + | throwError "expected the array to have type {q(Array $α)}" + let some arrayEntries ← arrayLiteral? arrayExpr + | throwError "expected an array literal matrix, got {arrayExpr}" + unless arrayEntries.size == dimension * dimension do + throwError "matrix size mismatch: array has {arrayEntries.size} entries, \ + expected {dimension * dimension}" + let arrayEntries ← arrayEntries.mapM fun entry => do + let some entry ← checkTypeQ entry α + | throwError "expected array entry to have type {α}" + return entry + let sα := commSemiringOfCommRing rα + let cα : Common.Cache sα := { + rα := some rα + dsα := none + czα := none + } + return { + rα + ctx := { + cα + rc := ringCompute cα + dimension + dimensionLit + arrayExpr + arrayEntries + } + } + +end Mathlib.Tactic.Determinant + +end diff --git a/MathlibTest/matrix.lean b/MathlibTest/matrix.lean index 88ffc5b1fc731e..d97533ec18b060 100644 --- a/MathlibTest/matrix.lean +++ b/MathlibTest/matrix.lean @@ -4,7 +4,10 @@ https://github.com/leanprover-community/mathlib/blob/4f4a1c875d0baa92ab5d92f3fb1 -/ import Mathlib.GroupTheory.Perm.Fin import Mathlib.LinearAlgebra.Matrix.Determinant.Basic +import Mathlib.LinearAlgebra.Matrix.Determinant.Bird import Mathlib.LinearAlgebra.Matrix.Notation +import Mathlib.RingTheory.Polynomial.Basic +import Mathlib.Tactic.Determinant.Bird import Qq open Qq @@ -186,4 +189,65 @@ example (ι : Type*) [Inhabited ι] : Matrix.replicateCol ι (fun (_ : Fin 3) => simp_all rfl +section BirdDet + +open BirdDet + +variable + {R : Type*} + [CommRing R] + +example : birdDet 0 #[] = (1 : ℤ) := by + eval_det + +example : birdDet 1 #[-1] = -1 := by + eval_det + +example : birdDet 2 #[1, 2, 3, 4] = -2 := by + eval_det + +example : birdDet 2 (let A := #[1, 2, 3, 4]; A) = -2 := by + eval_det + +example (a b c d : R) : + birdDet 2 #[a, b, c, d] = a * d - b * c := by + eval_det + ring + +example (a b c d : R) : + birdDet 2 #[a, b, c, d] = a * d - b * c := by + simp only [norm_det] + ring + +example : birdDet 2 #[1, 2, 2, 4] + birdDet 2 #[2, 3, 4, 5] = -2 := by + simp only [norm_det] + norm_num + +example : birdDet 2 #[birdDet 2 #[2, 3, 4, 5], 2, 2, 4] = -12 := by + simp only [norm_det] + +example : + birdDet 8 + #[ 2, 0, -1, 0, 0, 0, 0, 0, + 0, 2, 0, -1, 0, 0, 0, 0, + -1, 0, 2, -1, 0, 0, 0, 0, + 0, -1, -1, 2, -1, 0, 0, 0, + 0, 0, 0, -1, 2, -1, 0, 0, + 0, 0, 0, 0, -1, 2, -1, 0, + 0, 0, 0, 0, 0, -1, 2, -1, + 0, 0, 0, 0, 0, 0, -1, 2] = 1 := by + simp only [norm_det] + +open MvPolynomial in +lemma test_case_11 : + birdDet (R := MvPolynomial (Fin 3) R) + 3 + #[1 , X 0, (X 0) ^ 2, + 1 , X 1, (X 1) ^ 2, + 1 , X 2, (X 2) ^ 2] = (X 0 - X 1) * (X 1 - X 2) * (X 2 - X 0) := by + simp only [norm_det] + ring + +end BirdDet + end Matrix From 103b83bc6b61adfed654fcbf04f64ef5a804168b Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 2 Jul 2026 20:05:06 +0000 Subject: [PATCH 0564/1300] chore: fix `Additive`/`Multiplicative` order instances (#41298) This PR fixes some `Additive`/`Multiplicative` instances using the new `inferInstanceAs`. --- .../Order/Monoid/Unbundled/TypeTags.lean | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean index eaca7d92a6fd20..373d81cb62a1e2 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean @@ -15,53 +15,53 @@ public section variable {α : Type*} -instance : ∀ [LE α], LE (Multiplicative α) := - fun {inst} => inst +instance [LE α] : LE (Multiplicative α) := + inferInstanceAs <| LE α -instance : ∀ [LE α], LE (Additive α) := - fun {inst} => inst +instance [LE α] : LE (Additive α) := + inferInstanceAs <| LE α -instance : ∀ [LT α], LT (Multiplicative α) := - fun {inst} => inst +instance [LT α] : LT (Multiplicative α) := + inferInstanceAs <| LT α -instance : ∀ [LT α], LT (Additive α) := - fun {inst} => inst +instance [LT α] : LT (Additive α) := + inferInstanceAs <| LT α -instance Multiplicative.preorder : ∀ [Preorder α], Preorder (Multiplicative α) := - fun {inst} => inst +instance Multiplicative.preorder [Preorder α] : Preorder (Multiplicative α) := + inferInstanceAs <| Preorder α -instance Additive.preorder : ∀ [Preorder α], Preorder (Additive α) := - fun {inst} => inst +instance Additive.preorder [Preorder α] : Preorder (Additive α) := + inferInstanceAs <| Preorder α -instance Multiplicative.partialOrder : ∀ [PartialOrder α], PartialOrder (Multiplicative α) := - fun {inst} => inst +instance Multiplicative.partialOrder [PartialOrder α] : PartialOrder (Multiplicative α) := + inferInstanceAs <| PartialOrder α -instance Additive.partialOrder : ∀ [PartialOrder α], PartialOrder (Additive α) := - fun {inst} => inst +instance Additive.partialOrder [PartialOrder α] : PartialOrder (Additive α) := + inferInstanceAs <| PartialOrder α -instance Multiplicative.linearOrder : ∀ [LinearOrder α], LinearOrder (Multiplicative α) := - fun {inst} => inst +instance Multiplicative.linearOrder [LinearOrder α] : LinearOrder (Multiplicative α) := + inferInstanceAs <| LinearOrder α -instance Additive.linearOrder : ∀ [LinearOrder α], LinearOrder (Additive α) := - fun {inst} => inst +instance Additive.linearOrder [LinearOrder α] : LinearOrder (Additive α) := + inferInstanceAs <| LinearOrder α -instance Multiplicative.orderBot [LE α] : ∀ [OrderBot α], OrderBot (Multiplicative α) := - fun {inst} => inst +instance Multiplicative.orderBot [LE α] [OrderBot α] : OrderBot (Multiplicative α) := + inferInstanceAs <| OrderBot α -instance Additive.orderBot [LE α] : ∀ [OrderBot α], OrderBot (Additive α) := - fun {inst} => inst +instance Additive.orderBot [LE α] [OrderBot α] : OrderBot (Additive α) := + inferInstanceAs <| OrderBot α -instance Multiplicative.orderTop [LE α] : ∀ [OrderTop α], OrderTop (Multiplicative α) := - fun {inst} => inst +instance Multiplicative.orderTop [LE α] [OrderTop α] : OrderTop (Multiplicative α) := + inferInstanceAs <| OrderTop α -instance Additive.orderTop [LE α] : ∀ [OrderTop α], OrderTop (Additive α) := - fun {inst} => inst +instance Additive.orderTop [LE α] [OrderTop α] : OrderTop (Additive α) := + inferInstanceAs <| OrderTop α -instance Multiplicative.boundedOrder [LE α] : ∀ [BoundedOrder α], BoundedOrder (Multiplicative α) := - fun {inst} => inst +instance Multiplicative.boundedOrder [LE α] [BoundedOrder α] : BoundedOrder (Multiplicative α) := + inferInstanceAs <| BoundedOrder α -instance Additive.boundedOrder [LE α] : ∀ [BoundedOrder α], BoundedOrder (Additive α) := - fun {inst} => inst +instance Additive.boundedOrder [LE α] [BoundedOrder α] : BoundedOrder (Additive α) := + inferInstanceAs <| BoundedOrder α instance Multiplicative.existsMulOfLe [Add α] [LE α] [ExistsAddOfLE α] : ExistsMulOfLE (Multiplicative α) := From 935eca8904b3b24da10f53f1fbffb415f1c26ec6 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 20:44:34 +0000 Subject: [PATCH 0565/1300] chore: update Mathlib dependencies 2026-07-02 (#41049) This PR updates the Mathlib dependencies. --- lake-manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 4291b508ab7539..25f55d0dc1c353 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e6518a674e62de322b8f79eebeda7bcae2a36bc3", + "rev": "e4952ae2afde0dd2868b313356d1ce00da677bd9", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "77d3cc514f987c1f42f2bbd8a8d56855012dc115", + "rev": "9c6e03c0a86237b199ebe6b1fbac18078a767ade", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 6b9551018720c9ce838138502c87cc2ee890a9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Fri, 3 Jul 2026 00:00:26 +0000 Subject: [PATCH 0566/1300] feat: more results on `Order.enum` (#39136) Most importantly, we prove that the enumerator function of a cofinal set is normal iff the set is closed (under non-empty suprema). --- Mathlib/Order/Cofinal.lean | 13 ++-- .../SetTheory/Cardinal/Cofinality/Club.lean | 16 +++- .../SetTheory/Cardinal/Cofinality/Enum.lean | 73 ++++++++++++++++++- Mathlib/SetTheory/Ordinal/Topology.lean | 2 + 4 files changed, 91 insertions(+), 13 deletions(-) diff --git a/Mathlib/Order/Cofinal.lean b/Mathlib/Order/Cofinal.lean index 0eddfbd7bccbca..1269f4bdf408f6 100644 --- a/Mathlib/Order/Cofinal.lean +++ b/Mathlib/Order/Cofinal.lean @@ -40,6 +40,10 @@ theorem isCofinal_empty_iff : IsCofinal (∅ : Set α) ↔ IsEmpty α := by refine ⟨fun h ↦ ⟨fun a ↦ ?_⟩, fun h ↦ .of_isEmpty⟩ simpa using h a +theorem IsCofinal.nonempty [Nonempty α] {s : Set α} (hs : IsCofinal s) : s.Nonempty := by + inhabit α + exact (hs default).imp fun _ ↦ And.left + @[simp] theorem isCofinal_singleton_iff {x : α} : IsCofinal {x} ↔ IsTop x := by simp [IsCofinal, IsTop] @@ -52,11 +56,6 @@ theorem IsCofinal.mono {s t : Set α} (h : s ⊆ t) (hs : IsCofinal s) : IsCofin obtain ⟨b, hb, hb'⟩ := hs a exact ⟨b, h hb, hb'⟩ -theorem IsCofinal.nonempty [Nonempty α] {s : Set α} (h : IsCofinal s) : s.Nonempty := by - inhabit α - obtain ⟨x, hx, _⟩ := h default - exact ⟨x, hx⟩ - end LE section Preorder @@ -174,4 +173,8 @@ theorem isCofinal_setOf_imp_lt (r : α → α → Prop) [h : IsWellFounded α r] by_contra! hc' exact hb' c (hb.trans hc') hc +theorem isCofinal_range_of_strictMono [WellFoundedLT α] {f : α → α} (hf : StrictMono f) : + IsCofinal (range f) := + fun x ↦ ⟨_, ⟨x, rfl⟩, hf.le_apply⟩ + end LinearOrder diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean index 852a93cbe709b4..1bedf6696be382 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Club.lean @@ -5,9 +5,7 @@ Authors: Violeta Hernández Palacios -/ module -public import Mathlib.Order.DirSupClosed -public import Mathlib.Order.IsNormal -public import Mathlib.SetTheory.Cardinal.Cofinality.Basic +public import Mathlib.SetTheory.Cardinal.Cofinality.Enum /-! # Club sets and stationary sets @@ -33,7 +31,8 @@ open Cardinal Order Set variable {α : Type v} {s t : Set α} {x : α} [LinearOrder α] -/-- A club set is closed under suprema and cofinal. -/ +/-- A club set is a set that is closed under suprema and that is cofinal. -/ +@[mk_iff] structure IsClub {α : Type*} [LinearOrder α] (s : Set α) where /-- Club sets are closed under suprema. If `α` is a well-order with the order topology, this condition is equivalent to `IsClosed s`. -/ @@ -160,6 +159,15 @@ theorem _root_.Order.IsNormal.isClub_fixedPoints {f : α → α} (hα : cof α ((aleph0_le_cof.lt_of_ne' hα).trans_le' ?_) simpa using mk_range_le_lift (f := fun n : ℕ ↦ f^[n] a) +/-- Club sets in regular cardinals correspond one to one with normal functions. -/ +theorem _root_.Order.isNormal_enum_iff_isClub [IsRegularCardinalOrder α] + {s : Set α} {hs : IsCofinal s} : IsNormal (Subtype.val ∘ enum s hs) ↔ IsClub s := by + simp_rw [isClub_iff, hs, and_true, isNormal_enum_iff_dirSupClosed] + +theorem isNormal_enum [IsRegularCardinalOrder α] {s : Set α} (hs : IsClub s) : + IsNormal (Subtype.val ∘ enum s hs.isCofinal) := + isNormal_enum_iff_isClub.2 hs + end WellFoundedLT end IsClub diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Enum.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Enum.lean index 2c4170c98d118d..1fc97fcc7ed543 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Enum.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Enum.lean @@ -21,6 +21,11 @@ If `s` is a cofinal subset of a regular cardinal order `α`, there exists a uniq `α ≃o s`, which we call `Order.enum`. When `α = Ordinal`, this is referred to as the enumerator function of the set. Note that if `α = ℕ`, then this definition matches `Nat.nth`. +## Main results + +- `Order.enum_eq_iff`: `Order.enum s _` is the unique strictly monotonic function with range `s`. +- `Order.isNormal_enum_iff_dirSupClosed`: club sets correspond one to one with normal functions. + ## TODO - Deprecate `Ordinal.enumOrd` in favor of `Order.enum`. @@ -93,14 +98,16 @@ theorem type_eq_of_isCofinal {s : Set α} (hs : IsCofinal s) : typeLT s = typeLT noncomputable def enum (s : Set α) (hs : IsCofinal s) : α ≃o s := .ofRelIsoLT (type_eq.1 (type_eq_of_isCofinal hs).symm).some -theorem enum_le_of_forall_lt {a o : α} {s : Set α} {hs : IsCofinal s} (ho : o ∈ s) - (H : ∀ b < a, enum s hs b < o) : enum s hs a ≤ o := by +variable {s : Set α} {hs : IsCofinal s} + +theorem enum_le_of_forall_lt {a o : α} (ho : o ∈ s) (H : ∀ b < a, enum s hs b < o) : + enum s hs a ≤ o := by rw [← Subtype.coe_mk o ho, Subtype.coe_le_coe, ← OrderIso.le_symm_apply] apply le_of_forall_lt simpa [OrderIso.lt_symm_apply] -theorem enum_succ_le_of_lt [SuccOrder α] {a o : α} {s : Set α} {hs : IsCofinal s} (ha : o ∈ s) - (H : enum s hs a < o) : enum s hs (succ a) ≤ o := by +theorem enum_succ_le_of_lt [SuccOrder α] {a o : α} (ha : o ∈ s) (H : enum s hs a < o) : + enum s hs (succ a) ≤ o := by refine enum_le_of_forall_lt ha fun b hb ↦ H.trans_le' ?_ simpa using le_of_lt_succ hb @@ -109,4 +116,62 @@ theorem enum_univ (x : α) : enum univ .univ x = ⟨x, mem_univ x⟩ := by rw [← Subsingleton.allEq OrderIso.Set.univ.symm (enum univ .univ)] rfl +theorem enum_anti {hs : IsCofinal s} {t : Set α} {x : α} (h : s ⊆ t) : + enum t (hs.mono h) x ≤ (enum s hs x).1 := by + induction x using WellFoundedLT.induction with | ind x IH + exact enum_le_of_forall_lt (h (Subtype.prop _)) fun y hy ↦ + (IH y hy).trans_lt ((enum s hs).strictMono hy) + +/-- A characterization of `Order.enum s _`: it is the unique strictly monotone function +with range `s`. -/ +theorem enum_eq_iff {f : α → α} : Subtype.val ∘ enum s hs = f ↔ StrictMono f ∧ range f = s := by + have H := (Subtype.strictMono_coe _).comp (enum s hs).strictMono + constructor + · rintro rfl + use (Subtype.strictMono_coe _).comp (enum s hs).strictMono + simp + · rintro ⟨hf, rfl⟩ + rw [← StrictMono.range_inj H hf] + simp + rfl + +theorem enum_range {f : α → α} (hf : StrictMono f) : + enum (range f) (isCofinal_range_of_strictMono hf) = hf.orderIso := by + ext x + apply congrFun (enum_eq_iff.2 ⟨?_, ?_⟩) + · exact (Subtype.strictMono_coe _).comp (OrderIso.strictMono _) + · simp + +theorem enum_bot {α : Type*} [ConditionallyCompleteLinearOrderBot α] [WellFoundedLT α] + [IsRegularCardinalOrder α] {s : Set α} {hs : IsCofinal s} : enum s hs ⊥ = sInf s := by + let : Bot s := ⟨⟨sInf s, csInf_mem hs.nonempty⟩⟩ + let : OrderBot s := .mk fun a ↦ csInf_le' a.2 + rw [OrderIso.map_bot] + rfl + +/-- Club sets in regular cardinals correspond one to one with normal functions. + +See also `Order.isNormal_enum_iff_isClub`. -/ +theorem isNormal_enum_iff_dirSupClosed : + IsNormal (Subtype.val ∘ enum s hs) ↔ DirSupClosed s := by + let H := (Subtype.strictMono_coe _).comp (enum s hs).strictMono + refine ⟨fun he ↦ by simpa using he.dirSupClosed_range, ?_⟩ + rw [isNormal_iff, dirSupClosed_iff_of_linearOrder] + refine fun hs' ↦ ⟨H, fun a ha b hb ↦ ?_⟩ + have bdd : BddAbove (Subtype.val ∘ enum s hs '' Iio a) := by + use enum s hs a + simpa [upperBounds] using fun x hx ↦ hx.le + have : Nonempty α := ⟨a⟩ + let := WellFoundedLT.toOrderBot α + let := WellFoundedLT.conditionallyCompleteLinearOrderBot α + trans sSup ((Subtype.val ∘ enum s hs) '' Iio a) + · refine enum_le_of_forall_lt (hs' ?_ ?_ (isLUB_csSup' bdd)) fun b hb ↦ ?_ + · grind + · simpa using ha.ne_bot + · obtain ⟨c, hca, hbc⟩ := ha.lt_iff_exists_lt.1 hb + refine (H hbc).trans_le <| le_csSup bdd ⟨c, ?_⟩ + simpa + · apply csSup_le' + simpa [upperBounds] + end Order diff --git a/Mathlib/SetTheory/Ordinal/Topology.lean b/Mathlib/SetTheory/Ordinal/Topology.lean index 298c9b4ea797c0..263dd7e58345c2 100644 --- a/Mathlib/SetTheory/Ordinal/Topology.lean +++ b/Mathlib/SetTheory/Ordinal/Topology.lean @@ -5,6 +5,7 @@ Authors: Violeta Hernández Palacios -/ module +public import Mathlib.SetTheory.Cardinal.Cofinality.Enum public import Mathlib.SetTheory.Ordinal.Enum public import Mathlib.Tactic.TFAE public import Mathlib.Topology.Order.IsNormal @@ -141,6 +142,7 @@ theorem isClosed_iff_bsup : theorem isSuccLimit_of_mem_frontier (ha : a ∈ frontier s) : IsSuccLimit a := SuccOrder.isSuccLimit_of_mem_frontier ha +@[deprecated isNormal_enum_iff_dirSupClosed (since := "2026-05-25")] theorem enumOrd_isNormal_iff_isClosed (hs : ¬ BddAbove s) : IsNormal (enumOrd s) ↔ IsClosed s := by have Hs := enumOrd_strictMono hs From a98f92c4fcb4fd3d59ebedb7d1efb9b5bb7a2695 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Fri, 3 Jul 2026 01:54:09 +0000 Subject: [PATCH 0567/1300] feat(Combinatorics/SimpleGraph/Paths): `Walk.map` preserves more properties (#38531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds some missing theorems about how `Walk.map` behaves with `IsTrail`/`IsPath`/`IsCircuit`/`IsCycle`. Summary of what we have now, with the 8 new theorems and 8 renames marked: ``` IsTrail.of_map : (p.map f).IsTrail → p.IsTrail -- new isTrail_map_iff_of_injective : f.Injective → (p.map f).IsTrail ↔ p.IsTrail -- renamed from map_isTrail_iff_of_injective IsTrail.map : f.Injective → p.IsTrail → (p.map f).IsTrail -- renamed from map_isTrail_of_injective IsPath.of_map : (p.map f).IsPath → p.IsPath isPath_map_iff_of_injective : f.Injective → (p.map f).IsPath ↔ p.IsPath -- renamed from map_isPath_iff_of_injective IsPath.map : f.Injective f → p.IsPath → (p.map f).IsPath -- renamed from map_isPath_of_injective IsCircuit.of_map : (p.map f).IsCircuit → p.IsCircuit -- new isCircuit_map_iff_of_injective : f.Injective → (p.map f).IsCircuit ↔ p.IsCircuit -- new IsCircuit.map : f.Injective → p.IsCircuit → (p.map f).IsCircuit -- new IsCycle.of_map : (p.map f).IsCycle → p.IsCycle -- new isCycle_map_iff_of_injective : f.Injective → (p.map f).IsCycle ↔ p.IsCycle -- renamed from map_isCycle_iff_of_injective IsCycle.map : f.Injective → p.IsCycle → (p.map f).IsCycle isTrail_mapLe : G ≤ G' → (p.mapLe h).IsTrail ↔ p.IsTrail -- renamed from mapLe_isTrail IsTrail.of_mapLe : G ≤ G' → (p.mapLe h).IsTrail → p.IsTrail IsTrail.mapLe : G ≤ G' → p.IsTrail → (p.mapLe h).IsTrail isPath_mapLe : G ≤ G' → (p.mapLe h).IsPath ↔ p.IsPath -- renamed from mapLe_isPath IsPath.of_mapLe : G ≤ G' → (p.mapLe h).IsPath → p.IsPath IsPath.mapLe : G ≤ G' → p.IsPath → (p.mapLe h).IsPath isCircuit_mapLe : G ≤ G' → (p.mapLe h).IsCircuit ↔ p.IsCircuit -- new IsCircuit.of_mapLe : G ≤ G' → (p.mapLe h).IsCircuit → p.IsCircuit -- new IsCircuit.mapLe : G ≤ G' → p.IsCircuit → (p.mapLe h).IsCircuit -- new isCycle_mapLe : G ≤ G' → (p.mapLe h).IsCycle ↔ p.IsCycle -- renamed from mapLe_isCycle IsCycle.of_mapLe : G ≤ G' → (p.mapLe h).IsCycle → p.IsCycle IsCycle.mapLe : G ≤ G' → p.IsCycle → (p.mapLe h).IsCycle ``` --- .../Combinatorics/SimpleGraph/Acyclic.lean | 2 +- .../Combinatorics/SimpleGraph/CycleGraph.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 118 +++++++++++------- 3 files changed, 77 insertions(+), 45 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index 18e6d521401d7b..d345f587840602 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -71,7 +71,7 @@ variable {G G'} /-- A graph that has an injective homomorphism to an acyclic graph is acyclic. -/ lemma IsAcyclic.comap (f : G →g G') (hinj : Function.Injective f) (h : G'.IsAcyclic) : G.IsAcyclic := - fun _ _ ↦ map_isCycle_iff_of_injective hinj |>.not.mp <| h _ + fun _ _ ↦ mt (.map hinj) (h _) lemma IsAcyclic.embedding (f : G ↪g G') (h : G'.IsAcyclic) : G.IsAcyclic := h.comap f f.injective diff --git a/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean b/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean index ffe1ab2347a633..547fde4d0fc65f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/CycleGraph.lean @@ -176,7 +176,7 @@ lemma cycleGraph_isContained_iff {n : ℕ} (hn : 2 < n) : · have : n = n - 3 + 3 := by lia rw [this] at h refine ⟨h.toHom ⟨0, by lia⟩, Walk.map h.toHom <| cycleGraph.cycle (n - 3), ?_, ?_⟩ - · exact (map_isCycle_iff_of_injective h.injective).mpr cycleGraph.isCycle_cycle + · exact (isCycle_map_iff_of_injective h.injective).mpr cycleGraph.isCycle_cycle · simp [cycleGraph.length_cycle, ← this] · obtain ⟨a, p, hp₁, hp₂⟩ := h' refine ⟨⟨⟨fun n ↦ p.support[n.succ]'(?_), ?_⟩, ?_⟩⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 085e35d3b587c2..6f69fbe25693eb 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -974,68 +974,100 @@ end Walk namespace Walk -variable {G G'} -variable (f : G →g G') {u v : V} (p : G.Walk u v) -variable {p f} - -theorem map_isPath_of_injective (hinj : Function.Injective f) (hp : p.IsPath) : - (p.map f).IsPath := by - induction p with - | nil => simp - | cons _ _ ih => - rw [Walk.cons_isPath_iff] at hp - simp only [map_cons, cons_isPath_iff, ih hp.1, support_map, List.mem_map, not_exists, not_and, - true_and] - intro x hx hf - cases hinj hf - exact hp.2 hx - -protected theorem IsPath.of_map {f : G →g G'} (hp : (p.map f).IsPath) : p.IsPath := by - induction p with - | nil => simp - | cons _ _ ih => grind [map_cons, Walk.cons_isPath_iff, support_map] +variable {G G'} {f : G →g G'} {u v : V} {p : G.Walk u v} -theorem map_isPath_iff_of_injective (hinj : Function.Injective f) : (p.map f).IsPath ↔ p.IsPath := - ⟨IsPath.of_map, map_isPath_of_injective hinj⟩ +protected theorem IsTrail.of_map (hp : (p.map f).IsTrail) : p.IsTrail := by + rw [isTrail_def] + rw [isTrail_def, edges_map] at hp + exact hp.of_map -theorem map_isTrail_iff_of_injective (hinj : Function.Injective f) : +theorem isTrail_map_iff_of_injective (hinj : Function.Injective f) : (p.map f).IsTrail ↔ p.IsTrail := by - induction p with - | nil => simp - | cons _ _ ih => - rw [map_cons, isTrail_cons, ih, isTrail_cons] - apply and_congr_right' - rw [← Sym2.map_mk, edges_map, ← List.mem_map_of_injective (Sym2.map.injective hinj)] + rw [isTrail_def, isTrail_def, edges_map, List.nodup_map_iff <| Sym2.map.injective hinj] + +@[deprecated (since := "2026-06-16")] +alias map_isTrail_iff_of_injective := isTrail_map_iff_of_injective + +alias ⟨_, IsTrail.map⟩ := isTrail_map_iff_of_injective + +@[deprecated (since := "2026-06-16")] alias isTrmap_ail_of_injective := IsTrail.map + +protected theorem IsPath.of_map (hp : (p.map f).IsPath) : p.IsPath := by + rw [isPath_def] + rw [isPath_def, support_map] at hp + exact hp.of_map -alias ⟨_, map_isTrail_of_injective⟩ := map_isTrail_iff_of_injective +theorem isPath_map_iff_of_injective (hinj : Function.Injective f) : + (p.map f).IsPath ↔ p.IsPath := by + rw [isPath_def, isPath_def, support_map, List.nodup_map_iff hinj] -theorem map_isCycle_iff_of_injective {p : G.Walk u u} (hinj : Function.Injective f) : +@[deprecated (since := "2026-06-16")] +alias map_isPath_iff_of_injective := isPath_map_iff_of_injective + +alias ⟨_, IsPath.map⟩ := isPath_map_iff_of_injective + +@[deprecated (since := "2026-06-16")] alias isPmap_ath_of_injective := IsPath.map + +protected theorem IsCircuit.of_map {p : G.Walk u u} (hp : (p.map f).IsCircuit) : p.IsCircuit := by + rw [isCircuit_def, ne_eq, eq_nil_iff_nil] + rw [isCircuit_def, ne_eq, eq_nil_iff_nil, nil_map_iff] at hp + exact hp.imp_left .of_map + +theorem isCircuit_map_iff_of_injective {p : G.Walk u u} (hinj : Function.Injective f) : + (p.map f).IsCircuit ↔ p.IsCircuit := by + rw [isCircuit_def, isCircuit_def, isTrail_map_iff_of_injective hinj, ne_eq, ne_eq, eq_nil_iff_nil, + eq_nil_iff_nil, nil_map_iff] + +alias ⟨_, IsCircuit.map⟩ := isCircuit_map_iff_of_injective + +protected theorem IsCycle.of_map {p : G.Walk u u} (hp : (p.map f).IsCycle) : p.IsCycle := by + rw [isCycle_def, ne_eq, eq_nil_iff_nil] + rw [isCycle_def, ne_eq, eq_nil_iff_nil, nil_map_iff, support_map, ← List.map_tail] at hp + exact hp.imp .of_map <| .imp_right <| .of_map f + +theorem isCycle_map_iff_of_injective {p : G.Walk u u} (hinj : Function.Injective f) : (p.map f).IsCycle ↔ p.IsCycle := by - rw [isCycle_def, isCycle_def, map_isTrail_iff_of_injective hinj, ne_eq, ne_eq, eq_nil_iff_nil, + rw [isCycle_def, isCycle_def, isTrail_map_iff_of_injective hinj, ne_eq, ne_eq, eq_nil_iff_nil, eq_nil_iff_nil, nil_map_iff, support_map, ← List.map_tail, List.nodup_map_iff hinj] -alias ⟨_, IsCycle.map⟩ := map_isCycle_iff_of_injective +@[deprecated (since := "2026-06-16")] +alias map_isCycle_iff_of_injective := isCycle_map_iff_of_injective + +alias ⟨_, IsCycle.map⟩ := isCycle_map_iff_of_injective @[simp] -theorem mapLe_isTrail {G G' : SimpleGraph V} (h : G ≤ G') {u v : V} {p : G.Walk u v} : +theorem isTrail_mapLe {G G' : SimpleGraph V} (h : G ≤ G') {u v : V} {p : G.Walk u v} : (p.mapLe h).IsTrail ↔ p.IsTrail := - map_isTrail_iff_of_injective Function.injective_id + isTrail_map_iff_of_injective Function.injective_id + +@[deprecated (since := "2026-06-16")] alias mapLe_isTrail := isTrail_mapLe -alias ⟨IsTrail.of_mapLe, IsTrail.mapLe⟩ := mapLe_isTrail +alias ⟨IsTrail.of_mapLe, IsTrail.mapLe⟩ := isTrail_mapLe @[simp] -theorem mapLe_isPath {G G' : SimpleGraph V} (h : G ≤ G') {u v : V} {p : G.Walk u v} : +theorem isPath_mapLe {G G' : SimpleGraph V} (h : G ≤ G') {u v : V} {p : G.Walk u v} : (p.mapLe h).IsPath ↔ p.IsPath := - map_isPath_iff_of_injective Function.injective_id + isPath_map_iff_of_injective Function.injective_id -alias ⟨IsPath.of_mapLe, IsPath.mapLe⟩ := mapLe_isPath +@[deprecated (since := "2026-06-16")] alias mapLe_isPath := isPath_mapLe + +alias ⟨IsPath.of_mapLe, IsPath.mapLe⟩ := isPath_mapLe @[simp] -theorem mapLe_isCycle {G G' : SimpleGraph V} (h : G ≤ G') {u : V} {p : G.Walk u u} : +theorem isCircuit_mapLe {G G' : SimpleGraph V} (h : G ≤ G') {u : V} {p : G.Walk u u} : + (p.mapLe h).IsCircuit ↔ p.IsCircuit := + isCircuit_map_iff_of_injective Function.injective_id + +alias ⟨IsCircuit.of_mapLe, IsCircuit.mapLe⟩ := isCircuit_mapLe + +@[simp] +theorem isCycle_mapLe {G G' : SimpleGraph V} (h : G ≤ G') {u : V} {p : G.Walk u u} : (p.mapLe h).IsCycle ↔ p.IsCycle := - map_isCycle_iff_of_injective Function.injective_id + isCycle_map_iff_of_injective Function.injective_id + +@[deprecated (since := "2026-06-16")] alias mapLe_isCycle := isCycle_mapLe -alias ⟨IsCycle.of_mapLe, IsCycle.mapLe⟩ := mapLe_isCycle +alias ⟨IsCycle.of_mapLe, IsCycle.mapLe⟩ := isCycle_mapLe end Walk @@ -1047,7 +1079,7 @@ variable {G G'} @[simps] protected def map (f : G →g G') (hinj : Function.Injective f) {u v : V} (p : G.Path u v) : G'.Path (f u) (f v) := - ⟨Walk.map f p, Walk.map_isPath_of_injective hinj p.2⟩ + ⟨Walk.map f p, p.isPath.map hinj⟩ theorem map_injective {f : G →g G'} (hinj : Function.Injective f) (u v : V) : Function.Injective (Path.map f hinj : G.Path u v → G'.Path (f u) (f v)) := by From 29fdc2c22d46a934031d8cf812a40fd6dab06a70 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:27:02 +0000 Subject: [PATCH 0568/1300] feat(Algebra): the Rees theorem for depth (#26212) In this PR we proved the Rees theorem for depth. Co-authored-by: Hu Yongle --- Mathlib.lean | 1 + Mathlib/RingTheory/Depth/Rees.lean | 184 +++++++++++++++++++++++++++++ docs/references.bib | 14 +++ 3 files changed, 199 insertions(+) create mode 100644 Mathlib/RingTheory/Depth/Rees.lean diff --git a/Mathlib.lean b/Mathlib.lean index 26e316b99e5460..83a282fa53c80c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6506,6 +6506,7 @@ public import Mathlib.RingTheory.DedekindDomain.LinearDisjoint public import Mathlib.RingTheory.DedekindDomain.PID public import Mathlib.RingTheory.DedekindDomain.SInteger public import Mathlib.RingTheory.DedekindDomain.SelmerGroup +public import Mathlib.RingTheory.Depth.Rees public import Mathlib.RingTheory.Derivation.Basic public import Mathlib.RingTheory.Derivation.DifferentialRing public import Mathlib.RingTheory.Derivation.Lie diff --git a/Mathlib/RingTheory/Depth/Rees.lean b/Mathlib/RingTheory/Depth/Rees.lean new file mode 100644 index 00000000000000..302d5394afc6e9 --- /dev/null +++ b/Mathlib/RingTheory/Depth/Rees.lean @@ -0,0 +1,184 @@ +/- +Copyright (c) 2025 Nailin Guan. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Nailin Guan +-/ +module + +public import Mathlib.Algebra.Category.Grp.Zero +public import Mathlib.Algebra.Category.ModuleCat.Ext.Basic +public import Mathlib.RingTheory.Regular.Category +public import Mathlib.RingTheory.Regular.LinearMap +public import Mathlib.RingTheory.Regular.RegularSequence +public import Mathlib.RingTheory.Spectrum.Prime.Topology + +/-! + +# The Rees theorem + +In this file we prove the Rees theorem for depth, which relates the vanishing of +certain `Ext` groups and the length of a maximal regular sequence in a certain ideal. + +## Main results + +* `ModuleCat.exists_isRegular_tfae` (Rees theorem) : For any `n : ℕ`, Noetherian ring `R`, + `I : Ideal R`, and finitely generated and nontrivial `R`-module `M` satisfying `IM < M`, + the following are equivalent: + · for any `N : ModuleCat R` finitely generated such that `Supp N ⊆ V(I)`, `∀ i < n, Ext N M i = 0` + · `∀ i < n, Ext (R ⧸ I) M i = 0` + · there exists a `N : ModuleCat R` finitely generated and nontrivial with `Supp N = V(I)` + such that `∀ i < n, Ext N M i = 0` + · there exists a `M`-regular sequence of length `n` with every element in `I` + +## References + +* [Commutative Algebra, Theorem 28][matsumuraCommAlg] + +-/ + +public section + +universe v u + +open LinearMap RingTheory.Sequence Ideal CategoryTheory Abelian Limits Pointwise IsSMulRegular + +variable {R : Type u} [CommRing R] + +private lemma smul_top_quotSMulTop_ne_top_of_smul_top_ne_top {M : Type*} [AddCommGroup M] + [Module R M] {I : Ideal R} {r : R} (hr : r ∈ I) + (hI : I • (⊤ : Submodule R M) ≠ ⊤) : + I • (⊤ : Submodule R (QuotSMulTop r M)) ≠ ⊤ := by + by_contra eq + absurd congrArg (Submodule.comap (Submodule.mkQ _)) eq + simpa [Submodule.comap_smul_top_of_surjective I _ (Submodule.mkQ_surjective _), + Submodule.smul_mono_left ((span_singleton_le_iff_mem I).mpr hr), + ← Submodule.ideal_span_singleton_smul] using hI + +namespace ModuleCat + +/-- The implication `(3) → (4)` of `exists_isRegular_tfae`: for `M N` finitely generated +module over Noetherian ring `R` and ideal `I` satisfying `IM < M` and `Supp N = V(I)`, +if `Ext N M i = 0` for all `i < n`, +then there exists an `M`-regular sequence of length `n` contained in `I`. -/ +lemma exists_isRegular_of_exists_subsingleton_ext [Small.{v} R] [IsNoetherianRing R] (I : Ideal R) + (n : ℕ) (M : ModuleCat.{v} R) [Module.Finite R M] (smul_lt : I • (⊤ : Submodule R M) < ⊤) + (N : ModuleCat.{v} R) [Module.Finite R N] + (h_supp : Module.support R N = PrimeSpectrum.zeroLocus I) + (h_ext : ∀ i < n, Subsingleton (Ext N M i)) : + ∃ rs : List R, rs.length = n ∧ (∀ r ∈ rs, r ∈ I) ∧ IsRegular M rs := by + induction n generalizing M with + | zero => + have : Nontrivial M := (Submodule.nontrivial_iff R).mp (nontrivial_of_lt _ _ smul_lt) + use [] + simp [isRegular_iff] + | succ n ih => + rw [Module.support_eq_zeroLocus, PrimeSpectrum.zeroLocus_eq_iff] at h_supp + -- use `Ext N M 0` vanish to obtain an `M`-regular element `x` in `Ann(N)` + have : Subsingleton (N ⟶ M) := Ext.addEquiv₀.subsingleton_congr.mp (h_ext 0 n.zero_lt_succ) + have : Subsingleton (N →ₗ[R] M) := ModuleCat.homAddEquiv.symm.subsingleton + obtain ⟨x, mem_ann, hx⟩ := subsingleton_linearMap_iff.mp this + -- take a power of it to make `xᵏ` fall into `I` + obtain ⟨k, hk⟩ := le_of_le_of_eq Ideal.le_radical h_supp mem_ann + -- verify that `N` indeed make `M ⧸ xᵏM` satisfy the induction hypothesis + have h_ext' : ∀ i < n, Subsingleton (Ext N (ModuleCat.of R (QuotSMulTop (x ^ k) M)) i) := by + intro i hi + -- the vanishing of `Ext` is obtained from the (covariant) long exact sequence given by + -- `M.smulShortComplex (x ^ k)` + have zero1 := AddCommGrpCat.isZero_of_iff_subsingleton.mpr (h_ext i (by omega)) + have zero2 := AddCommGrpCat.isZero_of_iff_subsingleton.mpr (h_ext (i + 1) (by omega)) + exact AddCommGrpCat.subsingleton_of_isZero <| ShortComplex.Exact.isZero_of_both_zeros + ((Ext.covariant_sequence_exact₃' N (hx.pow k).smulShortComplex_shortExact) i (i + 1) rfl) + (zero1.eq_zero_of_src _) (zero2.eq_zero_of_tgt _) + obtain ⟨rs, len, mem, reg⟩ := ih (ModuleCat.of R (QuotSMulTop (x ^ k) M)) + (smul_top_quotSMulTop_ne_top_of_smul_top_ne_top hk smul_lt.ne).lt_top h_ext' + use x ^ k :: rs + simpa [len, hk] using ⟨mem, hx.pow k, reg⟩ + +/-- The implication `(4) → (1)` of `exists_isRegular_tfae`: for `M N` finitely generated +module over Noetherian ring `R` and ideal `I` satisfying `IM < M` and `Supp N ⊆ V(I)`, +if there is an `M`-regular sequence `rs` contained in `I`, +then `Ext N M i = 0` for all `i < rs.length`. -/ +lemma subsingleton_ext_of_exists_isRegular [Small.{v} R] [IsNoetherianRing R] (I : Ideal R) + (N : ModuleCat.{v} R) [Nfin : Module.Finite R N] + (Nsupp : Module.support R N ⊆ PrimeSpectrum.zeroLocus I) + (M : ModuleCat.{v} R) [Module.Finite R M] (smul_lt : I • (⊤ : Submodule R M) < ⊤) + (rs : List R) (mem : ∀ r ∈ rs, r ∈ I) (reg : IsRegular M rs) : + ∀ i < rs.length, Subsingleton (Ext N M i) := by + generalize len : rs.length = n + induction n generalizing M rs with + | zero => simp + | succ n ih => + rintro i hi + have le_rad := Nsupp + rw [Module.support_eq_zeroLocus, PrimeSpectrum.zeroLocus_subset_zeroLocus_iff] at le_rad + match rs with + | [] => simp at len + | a :: rs' => + -- find a positive power of `a` lying in `Ann(N)` + obtain ⟨k, hk⟩ := le_rad (mem a List.mem_cons_self) + simp only [isRegular_cons_iff] at reg + simp only [List.mem_cons, forall_eq_or_imp] at mem + simp only [List.length_cons, Nat.add_left_inj] at len + -- prepare to apply induction hypothesis to `M/aM` + match i with + | 0 => -- vanishing of `Ext N M 0` follows from `aᵏ ∈ Ann(N)` + have : Subsingleton (N →ₗ[R] M) := subsingleton_linearMap_iff.mpr ⟨a ^ k, hk, reg.1.pow k⟩ + exact (Ext.addEquiv₀.trans ModuleCat.homAddEquiv).subsingleton + | i + 1 => + let g := (AddCommGrpCat.ofHom ((Ext.mk₀ (smulShortComplex M a).f).postcomp N + (add_zero (i + 1)))) + -- from the (covariant) long exact sequence given by `M.smulShortComplex a` + -- we obtain scalar multiple by `a` on `Ext N M i` is injective + have mono_g : Mono g := by + apply (Ext.covariant_sequence_exact₁' N reg.1.smulShortComplex_shortExact i (i + 1) + rfl).mono_g ((AddCommGrpCat.isZero_of_iff_subsingleton.mpr ?_).eq_zero_of_src _) + apply ih (ModuleCat.of R (QuotSMulTop a M)) _ rs' mem.2 reg.2 len i (by omega) + exact (smul_top_quotSMulTop_ne_top_of_smul_top_ne_top mem.1 smul_lt.ne).lt_top + let gk := AddCommGrpCat.ofHom ((Ext.mk₀ (M.smulShortComplex (a ^ k)).f).postcomp N + (add_zero (i + 1))) + have mono_gk : Mono gk := by + simp only [smulShortComplex_f_eq_smul_id, g, gk] at mono_g ⊢ + exact (Ext.postcomp_smul_id_mono_iff (a ^ k) (i + 1)).mpr <| + ((Ext.postcomp_smul_id_mono_iff a (i + 1)).mp mono_g).pow k + -- scalar multiple by `aᵏ` on `Ext N M i` is zero since `aᵏ ∈ Ann(N)`, so `Ext N M i` vanish + have zero_gk : gk = 0 := Ext.postcomp_smul_id_eq_zero_of_mem_annihilator hk (i + 1) + exact AddCommGrpCat.subsingleton_of_isZero (IsZero.of_mono_eq_zero _ zero_gk) + +/-- +**The Rees theorem** +For any `n : ℕ`, Noetherian ring `R`, `I : Ideal R`, and finitely generated and nontrivial +`R`-module `M` satisfying `IM < M`, the following are equivalent: +* for any `N : ModuleCat R` finitely generated and nontrivial with support contained in the + zero locus of `I`, `∀ i < n, Ext N M i = 0` +* `∀ i < n, Ext (R ⧸ I) M i = 0` +* there exists a `N : ModuleCat R` finitely generated and nontrivial with support equal to the + zero locus of `I`, `∀ i < n, Ext N M i = 0` +* there exists a `M`-regular sequence of length `n` with every element in `I` +-/ +lemma exists_isRegular_tfae [Small.{v} R] [IsNoetherianRing R] (I : Ideal R) (n : ℕ) + (M : ModuleCat.{v} R) [Module.Finite R M] (smul_lt : I • (⊤ : Submodule R M) < ⊤) : + [∀ N : ModuleCat.{v} R, Nontrivial N → Module.Finite R N → + Module.support R N ⊆ PrimeSpectrum.zeroLocus I → ∀ i < n, Subsingleton (Ext N M i), + ∀ i < n, Subsingleton (Ext (ModuleCat.of R (Shrink.{v} (R ⧸ I))) M i), + ∃ N : ModuleCat R, Nontrivial N ∧ Module.Finite R N ∧ + Module.support R N = PrimeSpectrum.zeroLocus I ∧ ∀ i < n, Subsingleton (Ext N M i), + ∃ rs : List R, rs.length = n ∧ (∀ r ∈ rs, r ∈ I) ∧ RingTheory.Sequence.IsRegular M rs + ].TFAE := by + -- two main implications `3 → 4` and `4 → 1` are separated out, the rest are trivial + have ntrQ : Nontrivial (R ⧸ I) := by + apply Submodule.Quotient.nontrivial_iff.mpr + by_contra eq + simp [eq] at smul_lt + have suppQ : Module.support R (Shrink.{v} (R ⧸ I)) = PrimeSpectrum.zeroLocus I := by + rw [(Shrink.linearEquiv R _).support_eq, Module.support_eq_zeroLocus, annihilator_quotient] + tfae_have 1 → 2 := fun h1 i hi ↦ h1 (ModuleCat.of R (Shrink.{v} (R ⧸ I))) + inferInstance inferInstance suppQ.subset i hi + tfae_have 2 → 3 := fun h2 ↦ ⟨(ModuleCat.of R (Shrink.{v} (R ⧸ I))), + inferInstance, Module.Finite.equiv (Shrink.linearEquiv R (R ⧸ I)).symm, suppQ, h2⟩ + tfae_have 3 → 4 := fun ⟨N, _, _, h_supp, h_ext⟩ ↦ + exists_isRegular_of_exists_subsingleton_ext I n M smul_lt N h_supp h_ext + tfae_have 4 → 1 := fun ⟨rs, len, mem, reg⟩ N Nntr Nfin Nsupp i hi ↦ + subsingleton_ext_of_exists_isRegular I N Nsupp M smul_lt rs mem reg i (hi.trans_eq len.symm) + tfae_finish + +end ModuleCat diff --git a/docs/references.bib b/docs/references.bib index 10a72574e5e57c..7f24a1fbf66c1a 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -3945,6 +3945,20 @@ @Book{ matsumura1987 doi = {https://doi.org/10.1017/CBO9781139171762} } +@Book{ matsumuraCommAlg, + author = {Matsumura, Hideyuki}, + title = {Commutative algebra. 2nd ed}, + fseries = {Mathematics Lecture Note Series}, + series = {Math. Lect. Note Ser.}, + volume = {56}, + year = {1980}, + publisher = {The Benjamin/Cummings Publishing Company, Reading, MA}, + language = {English}, + keywords = {13-02,13Cxx,13C11,13H10,13C15,13Axx}, + zbmath = {3687501}, + zbl = {0441.13001} +} + @Article{ matsuo1997, title = {On axioms for a vertex algebra and locality of quantum fields}, From 4d07630220eacaa8857b749374a7347b46e91cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:36:26 +0000 Subject: [PATCH 0569/1300] feat(CategoryTheory/Presentable): sharply smaller regular cardinals (#40937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this file, we introduce the predicate `Cardinal.SharplyLT`. Given two regular cardinals `κ₁ < κ₂`, this condition can be described in different ways (a TFAE lemma will appear in a future PR). Here, we define it by saying that the category `CardinalDirectedPoset κ₁` is `κ₂`-accessible, and we show one of the implications for the future TFAE lemma. (This PR also renames `CardinalFilteredPoset` as `CardinalDirectedPoset`.) --- Mathlib.lean | 1 + .../Presentable/CardinalDirectedPoset.lean | 161 ++++++++--- .../Presentable/SharplyLT/Basic.lean | 265 ++++++++++++++++++ Mathlib/SetTheory/Ordinal/Basic.lean | 4 + 4 files changed, 388 insertions(+), 43 deletions(-) create mode 100644 Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 83a282fa53c80c..95b9bbdadc99dc 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3283,6 +3283,7 @@ public import Mathlib.CategoryTheory.Presentable.LocallyPresentable public import Mathlib.CategoryTheory.Presentable.OrthogonalReflection public import Mathlib.CategoryTheory.Presentable.Presheaf public import Mathlib.CategoryTheory.Presentable.Retracts +public import Mathlib.CategoryTheory.Presentable.SharplyLT.Basic public import Mathlib.CategoryTheory.Presentable.StrongGenerator public import Mathlib.CategoryTheory.Presentable.Type public import Mathlib.CategoryTheory.Products.Associator diff --git a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean index 8217cf1f7859a6..b662c5e2dd2dd2 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean @@ -13,12 +13,16 @@ public import Mathlib.Order.Category.PartOrdEmb # The κ-accessible category of κ-directed posets Given a regular cardinal `κ : Cardinal.{u}`, we define the -category `CardinalFilteredPoset κ` of `κ`-directed partially ordered +category `CardinalDirectedPoset κ` of `κ`-directed partially ordered types (with order embeddings as morphisms), and we show that it is a `κ`-accessible category. +The notion of `κ`-directed partially ordered type is implemented +using the categorial notion `IsCardinalFiltered`: we may consider +"`κ`-directed" and "`κ`-filtered" as synonyms. + If `κ ≤ κ'` where `κ'` is also a regular cardinal, we characterize -the `κ'`-presentable objects of `CardinalFilteredPoset κ` as +the `κ'`-presentable objects of `CardinalDirectedPoset κ` as the objects `J` such that the underlying type `J.obj` has cardinality `< κ'`. @@ -38,7 +42,10 @@ namespace PartOrdEmb variable (κ : Cardinal.{u}) [Fact κ.IsRegular] /-- The property of objects in `PartOrdEmb` that are -satisfied by partially ordered types of cardinality `< κ`. -/ +satisfied by `κ`-directed partially ordered types. +(Note: for partially ordered types, "`κ`-directed" and +"`κ`-filtered" are synonyms. This is implemented using the +categorical notion `IsCardinalFiltered`.) -/ abbrev isCardinalFiltered : ObjectProperty PartOrdEmb.{u} := fun X ↦ IsCardinalFiltered X κ @@ -92,77 +99,77 @@ variable (κ : Cardinal.{u}) [Fact κ.IsRegular] /-- The category of `κ`-filtered partially ordered types, with morphisms given by order embeddings. -/ -abbrev CardinalFilteredPoset := +abbrev CardinalDirectedPoset := (PartOrdEmb.isCardinalFiltered κ).FullSubcategory variable {κ} -/-- The embedding of the category of `κ`-filtered +/-- The embedding of the category of `κ`-directed partially ordered types in the category of partially ordered types. -/ -abbrev CardinalFilteredPoset.ι : CardinalFilteredPoset κ ⥤ PartOrdEmb := +abbrev CardinalDirectedPoset.ι : CardinalDirectedPoset κ ⥤ PartOrdEmb := ObjectProperty.ι _ -namespace CardinalFilteredPoset +namespace CardinalDirectedPoset /-- Constructor for objects in `CardinalFilteredPoset κ`. -/ -abbrev of (J : PartOrdEmb.{u}) [IsCardinalFiltered J κ] : CardinalFilteredPoset κ where +abbrev of (J : PartOrdEmb.{u}) [IsCardinalFiltered J κ] : CardinalDirectedPoset κ where obj := J property := inferInstance -lemma Hom.injective {J₁ J₂ : CardinalFilteredPoset κ} (f : J₁ ⟶ J₂) : +lemma Hom.injective {J₁ J₂ : CardinalDirectedPoset κ} (f : J₁ ⟶ J₂) : Function.Injective f := f.hom.injective -lemma Hom.le_iff_le {J₁ J₂ : CardinalFilteredPoset κ} (f : J₁ ⟶ J₂) (x₁ x₂ : J₁.obj) : +lemma Hom.le_iff_le {J₁ J₂ : CardinalDirectedPoset κ} (f : J₁ ⟶ J₂) (x₁ x₂ : J₁.obj) : f x₁ ≤ f x₂ ↔ x₁ ≤ x₂ := f.hom.hom.le_iff_le -instance (J : CardinalFilteredPoset κ) : IsCardinalFiltered J.obj κ := J.property +instance (J : CardinalDirectedPoset κ) : IsCardinalFiltered J.obj κ := J.property -instance (J : CardinalFilteredPoset κ) : IsFiltered J.obj := +instance (J : CardinalDirectedPoset κ) : IsFiltered J.obj := isFiltered_of_isCardinalFiltered _ κ -instance (J : CardinalFilteredPoset κ) : Nonempty J.obj := IsFiltered.nonempty +instance (J : CardinalDirectedPoset κ) : Nonempty J.obj := IsFiltered.nonempty -instance : HasCardinalFilteredColimits (CardinalFilteredPoset κ) κ where +instance : HasCardinalFilteredColimits (CardinalDirectedPoset κ) κ where hasColimitsOfShape J _ _ := by have := isFiltered_of_isCardinalFiltered J κ infer_instance instance (A : Type u) [SmallCategory A] [IsCardinalFiltered A κ] : - PreservesColimitsOfShape A (forget (CardinalFilteredPoset κ)) := by + PreservesColimitsOfShape A (forget (CardinalDirectedPoset κ)) := by have := isFiltered_of_isCardinalFiltered A κ - change PreservesColimitsOfShape A (CardinalFilteredPoset.ι ⋙ forget _) + change PreservesColimitsOfShape A (CardinalDirectedPoset.ι ⋙ forget _) infer_instance -instance (J : CardinalFilteredPoset κ) (κ' : Cardinal.{u}) [Fact κ'.IsRegular] : +instance (J : CardinalDirectedPoset κ) (κ' : Cardinal.{u}) [Fact κ'.IsRegular] : IsCardinalFiltered (WithTop (J.obj)) κ' := isCardinalFiltered_of_hasTerminal _ _ -/-- The map `CardinalFilteredPoset κ → CardinalFilteredPoset κ` which sends +/-- The map `CardinalDirectedPoset κ → CardinalDirectedPoset κ` which sends a partially ordered `κ`-filtered type `J` to `WithTop J`. -/ -abbrev withTop (J : CardinalFilteredPoset κ) : CardinalFilteredPoset κ := +abbrev withTop (J : CardinalDirectedPoset κ) : CardinalDirectedPoset κ := .of (.of (WithTop J.obj)) section -variable {J : CardinalFilteredPoset κ} (P : Set J.obj → Prop) +variable {J : CardinalDirectedPoset κ} (P : Set J.obj → Prop) [IsDirectedOrder (Subtype P)] [Nonempty (Subtype P)] [∀ (S : Subtype P), IsCardinalFiltered S.val κ] set_option backward.defeqAttrib.useBackward true in /-- Given a predicate `P : Set J.obj → Prop` on the underlying type -of `J : CardinalFilteredPoset κ` such that all the subsets satisfying `P` -are `κ`-filtered, this is the functor `Subtype P ⥤ CardinalFilteredPoset κ` +of `J : CardinalDirectedPoset κ` such that all the subsets satisfying `P` +are `κ`-filtered, this is the functor `Subtype P ⥤ CardinalDirectedPoset κ` which sends a subset `S` of `J` satisfying `P` to the induced -partially ordered type `J`, as an object in `CardinalFilteredPoset κ`. -/ +partially ordered type `J`, as an object in `CardinalDirectedPoset κ`. -/ @[simps!] -def functorOfPredicateSet : Subtype P ⥤ CardinalFilteredPoset κ := +def functorOfPredicateSet : Subtype P ⥤ CardinalDirectedPoset κ := ObjectProperty.lift _ (PartOrdEmb.functorOfPredicateSet P) (fun S ↦ by dsimp; infer_instance) /-- Given a predicate `P : Set J.obj → Prop` on the underlying type -of `J : CardinalFilteredPoset κ` such that all the subsets satisfying `P` +of `J : CardinalDirectedPoset κ` such that all the subsets satisfying `P` are `κ`-filtered, this is the cocone with point `J` given by all the inclusions of the subsets satisfying `P`. -/ @[simps] @@ -170,22 +177,22 @@ def coconeOfPredicateSet : Cocone (functorOfPredicateSet P) where pt := J ι.app j := ObjectProperty.homMk ((PartOrdEmb.coconeOfPredicateSet P).ι.app j) -/-- Let `P` be a predicate on `Set J.obj` where `J : CardinalFilteredPoset κ`. +/-- Let `P` be a predicate on `Set J.obj` where `J : CardinalDirectedPoset κ`. We assume that `Subtype P` is directed and nonempty, and that any `a : J.obj` belongs to some `S : Set J.obj` satisfying `P`. Then, `J` is the colimit in the -category `CardinalFilteredPoset κ` of these subsets. -/ +category `CardinalDirectedPoset κ` of these subsets. -/ noncomputable def isColimitCoconeOfPredicateSet (hP : ∀ (a : J.obj), ∃ (S : Set J.obj), P S ∧ a ∈ S) : IsColimit (coconeOfPredicateSet P) := - isColimitOfReflects CardinalFilteredPoset.ι + isColimitOfReflects CardinalDirectedPoset.ι (PartOrdEmb.isColimitOfPredicateSet P hP) end variable (κ) in -/-- The property of posets in `CardinalFilteredPoset κ` that are +/-- The property of posets in `CardinalDirectedPoset κ` that are of cardinality `< κ` and have terminal object. -/ -def hasCardinalLTWithTerminal : ObjectProperty (CardinalFilteredPoset κ) := +def hasCardinalLTWithTerminal : ObjectProperty (CardinalDirectedPoset κ) := fun J ↦ HasCardinalLT J.obj κ ∧ HasTerminal J.obj instance : ObjectProperty.EssentiallySmall.{u} (hasCardinalLTWithTerminal κ) where @@ -194,7 +201,7 @@ instance : ObjectProperty.EssentiallySmall.{u} (hasCardinalLTWithTerminal κ) wh let α : Type u := Σ (S : Set X) (_ : PartialOrder S), ULift.{u} (PLift (IsCardinalFiltered S κ)) let (a : α) : PartialOrder a.1 := a.2.1 - let ι (a : α) : CardinalFilteredPoset κ := + let ι (a : α) : CardinalDirectedPoset κ := { obj := .of a.1 property := a.2.2.down.down } refine ⟨.ofObj ι, inferInstance, fun J ⟨hJ, _⟩ ↦ ?_⟩ @@ -205,11 +212,11 @@ instance : ObjectProperty.EssentiallySmall.{u} (hasCardinalLTWithTerminal κ) wh let e' : Set.range f ≃o J.obj := { toEquiv := e.symm, map_rel_iff' := by rfl } exact ⟨_, ⟨⟨Set.range f, inferInstance, ⟨⟨IsCardinalFiltered.of_equivalence κ e'.symm.equivalence⟩⟩⟩⟩, - ⟨CardinalFilteredPoset.ι.preimageIso (PartOrdEmb.Iso.mk (by exact e'.symm))⟩⟩ + ⟨CardinalDirectedPoset.ι.preimageIso (PartOrdEmb.Iso.mk (by exact e'.symm))⟩⟩ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in -lemma isCardinalPresentable_of_hasCardinalLT_of_le (J : CardinalFilteredPoset κ) +lemma isCardinalPresentable_of_hasCardinalLT_of_le (J : CardinalDirectedPoset κ) {κ' : Cardinal.{u}} [Fact κ'.IsRegular] (hJ : HasCardinalLT J.obj κ') (h : κ ≤ κ') : IsCardinalPresentable J κ' where preservesColimitOfShape A _ _ := ⟨fun {F} ↦ ⟨fun {c} hc ↦ ⟨by @@ -255,7 +262,7 @@ lemma isCardinalPresentable_of_hasCardinalLT_of_le (J : CardinalFilteredPoset κ section -variable (J : CardinalFilteredPoset κ) +variable (J : CardinalDirectedPoset κ) -- `@[nolint unusedArguments]` allows to setup some instances which uses -- the fact that `κ'` is regular. @@ -314,7 +321,7 @@ colimit of its subsets that are of cardinality `< κ'` and contain `⊤`. -/ abbrev coconeWithTop : Cocone (functorOfPredicateSet (J.PropSetWithTop κ')) := coconeOfPredicateSet (PropSetWithTop J κ') -/-- If `J : CardinalFilteredPoset κ` and `κ'` is any regular cardinal, +/-- If `J : CardinalDirectedPoset κ` and `κ'` is any regular cardinal, then `J.withTop` is the `κ'`-filtered colimit of its subsets that are of cardinality `< κ'` and contain `⊤`. -/ noncomputable def isColimitCoconeWithTop : IsColimit (coconeWithTop J κ') := @@ -341,15 +348,15 @@ protected lemma isCardinalPresentable_iff (h : κ ≤ κ') : end -protected lemma isCardinalPresentable_iff' (J : CardinalFilteredPoset κ) : +protected lemma isCardinalPresentable_iff' (J : CardinalDirectedPoset κ) : IsCardinalPresentable J κ ↔ HasCardinalLT J.obj κ := - CardinalFilteredPoset.isCardinalPresentable_iff _ (le_refl _) + CardinalDirectedPoset.isCardinalPresentable_iff _ (le_refl _) section -variable (J : CardinalFilteredPoset κ) +variable (J : CardinalDirectedPoset κ) -/-- Given `J : CardinalFilteredPoset κ`, this is the predicate +/-- Given `J : CardinalDirectedPoset κ`, this is the predicate on `Set J.obj` that is satisfied by subsets that are of cardinality `< κ` and have a terminal object. -/ def PropSet (S : Set J.obj) : Prop := @@ -397,15 +404,15 @@ instance : IsDirectedOrder (Subtype J.PropSet) := instance : Nonempty (Subtype J.PropSet) := IsFiltered.nonempty -/-- For any object `J : CardinalFilteredPoset κ`, this is a colimit +/-- For any object `J : CardinalDirectedPoset κ`, this is a colimit cocone exhibiting `J` as the colimit of its subsets that are of cardinality `< κ` and have a terminal object. -/ abbrev cocone : Cocone (functorOfPredicateSet J.PropSet) := coconeOfPredicateSet J.PropSet -/-- Any object `J : CardinalFilteredPoset κ` is a colimit +/-- Any object `J : CardinalDirectedPoset κ` is a colimit of its subsets that are of cardinality `< κ` and have a terminal object. -/ -noncomputable def isColimitCocone (J : CardinalFilteredPoset κ) : +noncomputable def isColimitCocone (J : CardinalDirectedPoset κ) : IsColimit (cocone J) := isColimitCoconeOfPredicateSet _ (fun a ↦ ⟨_, propSet_singleton a, by simp⟩) @@ -424,11 +431,79 @@ lemma isCardinalFilteredGenerator_hasCardinalLTWithTerminal : isColimit := isColimitCocone J prop_diag_obj j := j.prop }⟩⟩ -instance : IsCardinalAccessibleCategory (CardinalFilteredPoset κ) κ where +instance : IsCardinalAccessibleCategory (CardinalDirectedPoset κ) κ where exists_generator := ⟨hasCardinalLTWithTerminal κ, inferInstance, isCardinalFilteredGenerator_hasCardinalLTWithTerminal κ⟩ +variable (κ) (X : Type u) + +/-- Given a cardinal `κ` and a type `X`, this is the subtype of `Set X` +consisting of subsets of `X` of cardinality `< κ`. -/ +abbrev SetCardinalLT := Subtype (fun (S : Set X) ↦ HasCardinalLT S κ) + +variable {X} in +/-- Given a regular cardinal `κ` and `x : X`, this is the singleton `{x}`, +considered as a subset of `X` of cardinality `< κ`. -/ +abbrev SetCardinalLT.singleton (x : X) : SetCardinalLT κ X := + ⟨{x}, hasCardinalLT_of_finite _ _ (Cardinal.IsRegular.aleph0_le Fact.out)⟩ + +instance : IsCardinalFiltered (SetCardinalLT κ X) κ := + isCardinalFiltered_preorder _ _ + (fun K f hK ↦ + ⟨⟨⋃ (k : K), (f k).val, hasCardinalLT_iUnion _ + (by rwa [hasCardinalLT_iff_cardinal_mk_lt]) (fun k ↦ (f k).prop)⟩, + Set.subset_iUnion (fun k ↦ (f k).val)⟩) + +/-- Given a regular cardinal `κ` and a type `X`, this is the `κ`-filtered +partially ordered type of subsets of `X` of cardinality `< κ`, +as an object of the category `CardinalDirectedPoset κ`. -/ +abbrev setCardinalLT : CardinalDirectedPoset κ := + .of (PartOrdEmb.of (SetCardinalLT κ X)) + +end CardinalDirectedPoset + +@[deprecated (since := "2026-06-24")] alias CardinalFilteredPoset := + CardinalDirectedPoset + +namespace CardinalFilteredPoset + +@[deprecated (since := "2026-06-24")] alias ι := CardinalDirectedPoset.ι +@[deprecated (since := "2026-06-24")] alias of := CardinalDirectedPoset.of +@[deprecated (since := "2026-06-24")] alias Hom.injective := CardinalDirectedPoset.Hom.injective +@[deprecated (since := "2026-06-24")] alias Hom.le_iff_le := CardinalDirectedPoset.Hom.le_iff_le +@[deprecated (since := "2026-06-24")] alias withTop := CardinalDirectedPoset.withTop +@[deprecated (since := "2026-06-24")] +alias functorOfPredicateSet := CardinalDirectedPoset.functorOfPredicateSet +@[deprecated (since := "2026-06-24")] +alias coconeOfPredicateSet := CardinalDirectedPoset.coconeOfPredicateSet +@[deprecated (since := "2026-06-24")] +alias isColimitCoconeOfPredicateSet := CardinalDirectedPoset.isColimitCoconeOfPredicateSet +@[deprecated (since := "2026-06-24")] +alias hasCardinalLTWithTerminal := CardinalDirectedPoset.hasCardinalLTWithTerminal +@[deprecated (since := "2026-06-24")] +alias isCardinalPresentable_of_hasCardinalLT_of_le := + CardinalDirectedPoset.isCardinalPresentable_of_hasCardinalLT_of_le +@[deprecated (since := "2026-06-24")] +alias PropSetWithTop := CardinalDirectedPoset.PropSetWithTop +@[deprecated (since := "2026-06-24")] +alias propSetWithTop_pair := CardinalDirectedPoset.propSetWithTop_pair +@[deprecated (since := "2026-06-24")] +alias exists_mem_propSetWithTop := CardinalDirectedPoset.exists_mem_propSetWithTop +@[deprecated (since := "2026-06-24")] +alias coconeWithTop := CardinalDirectedPoset.coconeWithTop +@[deprecated (since := "2026-06-24")] +alias isColimitCoconeWithTop := CardinalDirectedPoset.isColimitCoconeWithTop +@[deprecated (since := "2026-06-24")] +alias isCardinalPresentable_iff := CardinalDirectedPoset.isCardinalPresentable_iff +@[deprecated (since := "2026-06-24")] +alias isCardinalPresentable_iff' := CardinalDirectedPoset.isCardinalPresentable_iff' +@[deprecated (since := "2026-06-24")] alias PropSet := CardinalDirectedPoset.PropSet +@[deprecated (since := "2026-06-24")] +alias propSet_singleton := CardinalDirectedPoset.propSet_singleton +@[deprecated (since := "2026-06-24")] alias cocone := CardinalDirectedPoset.cocone +@[deprecated (since := "2026-06-24")] alias isColimitCocone := CardinalDirectedPoset.isColimitCocone + end CardinalFilteredPoset end CategoryTheory diff --git a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean new file mode 100644 index 00000000000000..1fe915d41331d6 --- /dev/null +++ b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean @@ -0,0 +1,265 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.Presentable.CardinalDirectedPoset +public import Mathlib.CategoryTheory.Presentable.Dense +public import Mathlib.Order.TransfiniteIteration + +/-! +# Sharply smaller regular cardinals + +In this file, we introduce the predicate `Cardinal.SharplyLT`. Given two regular +cardinals `κ₁ < κ₂`, this condition can be described in different ways: +(i) the category `CardinalDirectedPoset κ₁` (of `κ₁`-directed partially ordered + types, with order embeddings as morphisms), is `κ₂`-accessible; +(ii) any `κ₁`-accessible category is `κ₂`-accessible. +(iii) for any type `X` of cardinality `< κ₂`, there exists a cofinal set of + cardinality `< κ₂` in the subtype of subsets of `X` of cardinality `< κ₁`; +(iv) for any `κ₁`-directed partially ordered type `X` and any subset `A` of `X` + of cardinality `< κ₂`, there exists a `κ₁`-directed subset `B` of `X` containing `A` + that is of cardinality `< κ₂`. +The equivalence of these conditions (i)-(iv) is Theorem 2.11 in the book by Adámek and Rosický +((i) → (iii) is `exists_cofinal_of_isCardinalAccessibleCategory_cardinalDirectedPoset`, +(iii) → (iv) is `exists_isCardinalFiltered_set_of_exists_cofinal`, (ii) → (i) is obvious; +the rest is TODO @joelriou). Here, we take (i) as the definition. + +## References +* [Adámek, J. and Rosický, J., *Locally presentable and accessible categories*][Adamek_Rosicky_1994] + +-/ + +universe w v u + +open CategoryTheory Limits + +namespace Cardinal + +variable {κ₁ κ₂ : Cardinal.{w}} [Fact κ₁.IsRegular] [Fact κ₂.IsRegular] + +variable (κ₁ κ₂) in +/-- If `κ₁ < κ₂` are two regular cardinals, we say that `κ₁` is sharply +smaller than `κ₂` if the category `CardinalDirectedPoset κ₁` +is `κ₂`-accessible. There are other characterizations (TODO @joelriou), +including the property that any `κ₁`-accessible category is +also `κ₂`-accessible. -/ +public structure SharplyLT : Prop where + lt : κ₁ < κ₂ + isCardinalAccessible_cardinalDirectedPoset : + IsCardinalAccessibleCategory (CardinalDirectedPoset κ₁) κ₂ + +namespace SharplyLT + +public lemma le (h : SharplyLT κ₁ κ₂) : κ₁ ≤ κ₂ := h.lt.le + +set_option backward.defeqAttrib.useBackward true in +open CardinalDirectedPoset in +/-- This is the implication (i) → (iii) in the characterizations +of `SharplyLT κ₁ κ₂` in the docstring of this file. -/ +public lemma exists_cofinal_of_isCardinalAccessibleCategory_cardinalDirectedPoset + (h : κ₁ ≤ κ₂) [IsCardinalAccessibleCategory (CardinalDirectedPoset κ₁) κ₂] + {X : Type w} (hX : HasCardinalLT X κ₂) : + ∃ (Y : Set (SetCardinalLT κ₁ X)), HasCardinalLT Y κ₂ ∧ IsCofinal Y := by + -- We write the partially ordered type `SetCardinalLT κ₁ X` of subsets + -- of `X` of cardinality `< κ₁` as a `κ₂`-filtered colimit (with index + -- category `J`) of `κ₂`-presentable objects (i.e. partially ordered + -- types of cardinality `< κ₂`.) + obtain ⟨J, _, _, ⟨p⟩⟩ := (isCardinalFilteredGenerator_isCardinalPresentable + (CardinalDirectedPoset κ₁) κ₂).exists_colimitsOfShape (setCardinalLT κ₁ X) + have : IsCardinalFiltered J κ₁ := .of_le _ h + have hp (j : J) : HasCardinalLT (p.diag.obj j).obj κ₂ := by + rw [← CardinalDirectedPoset.isCardinalPresentable_iff _ h] + exact p.prop_diag_obj j + -- For each `x : X`, we choose `j : J` in such a way that the singleton + -- `{x}` belongs to the image of `p.diag.obj j` in `SetCardinalLT κ₁ X`. + choose j y hy using fun x ↦ Types.jointly_surjective_of_isColimit + (isColimitOfPreserves (forget (CardinalDirectedPoset κ₁)) p.isColimit) + (SetCardinalLT.singleton κ₁ x) + dsimp at y hy + -- The expected cofinal set `A` will be the range of `p.ι.app j'` + -- where `j' : J` is such that for any `x : X`, there is a map `j x ⟶ j'` + let j' := IsCardinalFiltered.max j hX + let y' (x : X) : (p.diag.obj j').obj := + p.diag.map (IsCardinalFiltered.toMax j hX x) (y x) + have hy' (x : X) : p.ι.app j' (y' x) = SetCardinalLT.singleton κ₁ x := by + rw [← hy, ← p.w (IsCardinalFiltered.toMax j hX x)] + rfl + refine ⟨Set.range (p.ι.app j'), (hp j').of_surjective _ + (Set.rangeFactorization_surjective (f := p.ι.app j')), fun ⟨B, hB⟩ ↦ ?_⟩ + let j'' := IsCardinalFiltered.max (fun b ↦ y' b.val) hB + refine ⟨_, ⟨j'', rfl⟩, fun b hb ↦ ?_⟩ + have : y' b ≤ j'' := (leOfHom (IsCardinalFiltered.toMax (fun b ↦ y' b.val) hB ⟨b, hb⟩) :) + refine (p.ι.app j').hom.hom.monotone this ?_ + convert Set.mem_singleton b + exact Subtype.ext_iff.1 (hy' b) + +section + +open CardinalDirectedPoset + +namespace existsIsCardinalFilteredSetOfExistsCofinal + +/-! The definitions in this section are part of the proof of the +lemma `exists_isCardinalFiltered_set_of_exists_cofinal` below, +which is the implication (iii) → (iv) in the characterizations +of `SharplyLT κ₁ κ₂` which appear in the docstring of this file. -/ + +variable (h₀ : κ₁ < κ₂) + {X : Type w} [PartialOrder X] + -- The variables `Y`, `hY` and `hY'` below can be obtained by applying + -- the `choose` tactic to an assumption of the form + -- `∃ (Y : Set (SetCardinalLT κ₁ X)), HasCardinalLT Y κ₂ ∧ IsCofinal Y)` + -- e.g. when the condition (iii) in the docstring of this file is satisfied + (Y : ∀ (B : Set X) (_ : HasCardinalLT B κ₂), Set (SetCardinalLT κ₁ B)) + (hY : ∀ (B : Set X) (hB : HasCardinalLT B κ₂), HasCardinalLT (Y B hB) κ₂) + (hY' : ∀ (B : Set X) (hB : HasCardinalLT B κ₂), IsCofinal (Y B hB)) + -- In the proof of `exists_isCardinalFiltered_set_of_exists_cofinal` below, + -- we shall show that we can find such `m` and `hm`, i.e. + -- for any `B : Set X`, `hB : HasCardinalLT B κ₂`, `C : SetCardinalLT κ₁ B`, + -- if `C ∈ Y B hB`, then there exists `m : X` such that all the elements + -- of `C` are less than or equal to `m`. + (m : ∀ (B : Set X) (hB : HasCardinalLT B κ₂) (C : SetCardinalLT κ₁ B), + C ∈ Y B hB → X) + (hm : ∀ (B : Set X) (hB : HasCardinalLT B κ₂) (C : SetCardinalLT κ₁ B) + (hC : C ∈ Y B hB) (b : B), b ∈ C.val → b ≤ m B hB C hC) + (A : Set X) (hA : HasCardinalLT A κ₂) + +/-- The subset of `X` given by the union over all `C : Y B hB` of +`C` and `{m B hB C _}`. -/ +def φ₀ (B : Set X) (hB : HasCardinalLT B κ₂) : Set X := + ⋃ (C : Y B hB), Subtype.val '' C.val.val ∪ {m B hB C C.prop} + +omit [Fact κ₁.IsRegular] [Fact κ₂.IsRegular] in +include hY' hm in +lemma hφ₀ (B : Set X) (hB : HasCardinalLT B κ₂) {T : Type w} (f : T → B) + (hT : HasCardinalLT T κ₁) : + ∃ (a : φ₀ Y m B hB), ∀ (t : T), f t ≤ a.val := by + let C₀ : SetCardinalLT κ₁ B := + ⟨Set.range f, hT.of_surjective _ Set.rangeFactorization_surjective⟩ + obtain ⟨C, hC, hC'⟩ := hY' B hB C₀ + exact ⟨⟨m B hB C hC, Set.subset_iUnion _ ⟨C, hC⟩ (Or.inr (by simp))⟩, + fun t ↦ hm B hB C hC (f t) (hC' (by simp [C₀]))⟩ + +open Classical in +/-- This coincides with `φ₀` when `HasCardinalLT B κ₂` holds. -/ +def φ (B : Set X) : Set X := + if hB : HasCardinalLT B κ₂ then φ₀ Y m B hB else B + +omit [Fact κ₁.IsRegular] [Fact κ₂.IsRegular] [PartialOrder X] in +lemma φ_eq (B : Set X) (hB : HasCardinalLT B κ₂) : + φ Y m B = φ₀ Y m B hB := dif_pos hB + +include hY' in +omit [Fact κ₂.IsRegular] [PartialOrder X] in +lemma le_φ (B : Set X) : B ≤ φ Y m B := by + dsimp [φ] + split_ifs with hB + · intro b hb + obtain ⟨C, hC, hC'⟩ := hY' B hB ⟨{⟨b, hb⟩}, + hasCardinalLT_of_finite _ _ (IsRegular.aleph0_le Fact.out)⟩ + refine Set.subset_iUnion _ ⟨C, hC⟩ (Or.inl ?_) + simp only [Set.mem_image, Subtype.exists, exists_and_right, exists_eq_right] + exact ⟨hb, @hC' ⟨b, hb⟩ (by simp)⟩ + · simp + +include h₀ hA hY in +omit [PartialOrder X] in +/-- By iterating `φ` to the power `j : κ₁.ord.ToType` and evaluating +on `A`, we get a subset that is of cardinality `< κ₂`. -/ +lemma hasCardinalLT_transfiniteIterate_φ (j : κ₁.ord.ToType) : + HasCardinalLT (transfiniteIterate (φ Y m) j A :) κ₂ := by + induction j using SuccOrder.limitRecOn with + | isMin j hj => + have := Cardinal.nonempty_ord_toType (c := κ₁) (IsRegular.ne_zero Fact.out) + letI := WellFoundedLT.toOrderBot κ₁.ord.ToType + simpa [hj.eq_bot] + | succ j hj hj' => + have hκ₂ : κ₂.IsRegular := Fact.out + rw [transfiniteIterate_succ _ _ _ hj, φ_eq _ _ _ hj'] + refine hasCardinalLT_iUnion _ (hY _ _) + (fun ⟨C, hC⟩ ↦ hasCardinalLT_union hκ₂.aleph0_le ?_ + (hasCardinalLT_of_finite _ _ hκ₂.aleph0_le)) + refine (C.prop.of_le h₀.le).of_injective (fun ⟨c, hc⟩ ↦ ?_) + (fun c₁ c₂ hc ↦ ?_) + · simp only [Set.mem_image, Subtype.exists, exists_and_right, exists_eq_right] at hc + exact ⟨⟨c, hc.choose⟩, hc.choose_spec⟩ + · simpa only [Subtype.ext_iff] using hc + | isSuccLimit j hj hj' => + rw [transfiniteIterate_limit _ _ _ hj, Set.iSup_eq_iUnion] + refine hasCardinalLT_iUnion _ + (HasCardinalLT.of_injective ?_ _ Subtype.val_injective) (fun ⟨k, hk⟩ ↦ hj' _ hk) + simpa [hasCardinalLT_iff_cardinal_mk_lt] + +include hY' in +omit [Fact κ₂.IsRegular] [PartialOrder X] in +lemma monotone_transfiniteIterate_φ : + Monotone (fun (j : κ₁.ord.ToType) ↦ transfiniteIterate (φ Y m) j A) := + have := Cardinal.nonempty_ord_toType (c := κ₁) (IsRegular.ne_zero Fact.out) + letI := WellFoundedLT.toOrderBot κ₁.ord.ToType + monotone_transfiniteIterate _ _ (le_φ _ hY' _) + +omit [PartialOrder X] [Fact κ₂.IsRegular] in +lemma subset_iUnion : A ⊆ ⋃ (j : κ₁.ord.ToType), transfiniteIterate (φ Y m) j A := by + have := Cardinal.nonempty_ord_toType (c := κ₁) (IsRegular.ne_zero Fact.out) + letI := WellFoundedLT.toOrderBot κ₁.ord.ToType + exact subset_trans (by simp) (Set.subset_iUnion _ ⊥) + +include h₀ hY hY' hm hA in +lemma isCardinalFiltered_iUnion : + IsCardinalFiltered (⋃ (j : κ₁.ord.ToType), transfiniteIterate (φ Y m) j A) κ₁ := by + suffices ∀ ⦃K : Type w⦄ (j : κ₁.ord.ToType) (f : K → (transfiniteIterate (φ Y m) j A : Set _)) + (hK : HasCardinalLT K κ₁), + ∃ (x : (transfiniteIterate (φ Y m) (Order.succ j) A : Set _)), + ∀ (k : K), (f k).val ≤ x.val by + refine isCardinalFiltered_preorder _ _ (fun K f hK ↦ ?_) + rw [← hasCardinalLT_iff_cardinal_mk_lt] at hK + have (k : K) : ∃ (j : κ₁.ord.ToType), (f k).val ∈ transfiniteIterate (φ Y m) j A := by + simpa only [Set.mem_iUnion] using (f k).prop + choose a ha using this + obtain ⟨⟨z, hz⟩, hz'⟩ := this (IsCardinalFiltered.max a hK) (fun k ↦ + ⟨(f k).val, monotone_transfiniteIterate_φ Y hY' m A + (leOfHom (IsCardinalFiltered.toMax a hK k)) (ha k)⟩) hK + exact ⟨⟨z, Set.subset_iUnion _ _ hz⟩, hz'⟩ + intro K j f hK + obtain ⟨⟨x, hx⟩, hx'⟩ := hφ₀ Y hY' m hm _ + (hasCardinalLT_transfiniteIterate_φ h₀ Y hY m A hA _) f hK + refine ⟨⟨x, ?_⟩, hx'⟩ + have : NoMaxOrder κ₁.ord.ToType := noMaxOrder (IsRegular.aleph0_le Fact.out) + rwa [transfiniteIterate_succ _ _ _ (not_isMax j), + φ_eq _ _ _ (hasCardinalLT_transfiniteIterate_φ h₀ Y hY m A hA _)] + +end existsIsCardinalFilteredSetOfExistsCofinal + +open existsIsCardinalFilteredSetOfExistsCofinal in +/-- This is the implication (iii) → (iv) in the characterizations +of `SharplyLT κ₁ κ₂` in the docstring of this file. -/ +public lemma exists_isCardinalFiltered_set_of_exists_cofinal (h₀ : κ₁ < κ₂) + (h : ∀ (X : Type w) (_ : HasCardinalLT X κ₂), + ∃ (Y : Set (SetCardinalLT κ₁ X)), HasCardinalLT Y κ₂ ∧ IsCofinal Y) + {X : Type w} [PartialOrder X] [IsCardinalFiltered X κ₁] + (A : Set X) (hA : HasCardinalLT A κ₂) : + ∃ (B : Set X), A ⊆ B ∧ IsCardinalFiltered B κ₁ ∧ HasCardinalLT B κ₂ := by + choose Y hY hY' using fun (B : Set X) hB ↦ h B hB + have hY'' (B : Set X) (hB : HasCardinalLT B κ₂) + (C : SetCardinalLT κ₁ B) (hC : C ∈ Y B hB) : + ∃ (m : X), ∀ (b : B), b ∈ C.val → b ≤ m := + ⟨IsCardinalFiltered.max (fun (c : C.val) ↦ c.val.val) C.prop, + fun b hb ↦ leOfHom (IsCardinalFiltered.toMax + (fun (c : C.val) ↦ c.val.val) C.prop ⟨_, hb⟩)⟩ + choose m hm using hY'' + -- The expected subset `B` is obtained as the union over + -- all `j : κ₁.ord.ToType` of the transfinite iterations + -- of the map `φ` + exact ⟨⋃ j, transfiniteIterate (φ Y m) j A, subset_iUnion Y m A, + isCardinalFiltered_iUnion h₀ Y hY hY' m hm A hA, + hasCardinalLT_iUnion _ (by simpa [hasCardinalLT_iff_cardinal_mk_lt]) + (hasCardinalLT_transfiniteIterate_φ h₀ Y hY m A hA)⟩ + +end + +end SharplyLT + +end Cardinal diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index d5641068269f63..689ae9ee2f849c 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -1269,6 +1269,10 @@ def ord.orderEmbedding : Cardinal ↪o Ordinal := theorem ord.orderEmbedding_coe : (ord.orderEmbedding : Cardinal → Ordinal) = ord := rfl +lemma nonempty_ord_toType {c : Cardinal} (h : c ≠ 0) : + Nonempty c.ord.ToType := by + rwa [Ordinal.nonempty_toType_iff, ne_eq, ord_eq_zero] + end Cardinal namespace Ordinal From 5c10b4bf97cf4350d16d2ed8232279c4497bfc82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:07:03 +0000 Subject: [PATCH 0570/1300] feat(AlgebraicTopology): Reedy structures (#41141) In this PR, we introduce the definition of Reedy structures. From https://github.com/joelriou/reedy which was started at https://www.mittag-leffler.se/activities/formalizing-higher-categories/ Co-authored-by: Aras Ergus Co-authored-by: Nima Rasekh --- Mathlib.lean | 1 + Mathlib/AlgebraicTopology/Reedy/Basic.lean | 228 ++++++++++++++++++ .../MorphismProperty/Composition.lean | 27 ++- .../MorphismProperty/Factorization.lean | 19 ++ 4 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 Mathlib/AlgebraicTopology/Reedy/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 95b9bbdadc99dc..d12b8b7c5bed1c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1538,6 +1538,7 @@ public import Mathlib.AlgebraicTopology.Quasicategory.Nerve public import Mathlib.AlgebraicTopology.Quasicategory.StrictBicategory public import Mathlib.AlgebraicTopology.Quasicategory.StrictSegal public import Mathlib.AlgebraicTopology.Quasicategory.TwoTruncated +public import Mathlib.AlgebraicTopology.Reedy.Basic public import Mathlib.AlgebraicTopology.RelativeCellComplex.AttachCells public import Mathlib.AlgebraicTopology.RelativeCellComplex.Basic public import Mathlib.AlgebraicTopology.SimplexCategory.Augmented.Basic diff --git a/Mathlib/AlgebraicTopology/Reedy/Basic.lean b/Mathlib/AlgebraicTopology/Reedy/Basic.lean new file mode 100644 index 00000000000000..625b0026c3d70a --- /dev/null +++ b/Mathlib/AlgebraicTopology/Reedy/Basic.lean @@ -0,0 +1,228 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou, Nima Rasekh, Aras Ergus +-/ +module + +public import Mathlib.CategoryTheory.MorphismProperty.Composition +public import Mathlib.CategoryTheory.MorphismProperty.Factorization +public import Mathlib.CategoryTheory.Skeletal +public import Mathlib.Order.SuccPred.Basic + +/-! +# Reedy categories + +In this file, we introduce the definition of a Reedy structure +on a category `C` equipped with two classes of morphisms +`W₁` and `W₂` (these are sometimes denoted `C₋` and `C₊` in +the literature). + +## TODO +* Construct the Reedy model category structure on the category of +functors `C ⥤ D` when `C` is a Reedy category and `D` a model category +https://github.com/leanprover-community/project-intentions/issues/5 + +## References +* [Emily Riehl and Dominic Verity, *Elements of ∞-Category Theory*, C.4][RiehlVerity2022] + +-/ + +@[expose] public section + +universe u + +open CategoryTheory + +namespace HomotopicalAlgebra + +open MorphismProperty in +/-- A Reedy structure on a category `C` equipped with two multiplicative +classes of morphisms `W₁` and `W₂` consists of the data of a degree +map for objects `deg : C → α`, where `α` is a well ordered type. The first +two axioms `lt₁` and `lt₂` express the behaviour of the degree with +respect to morphisms in `W₁` (resp. `W₂`) that are not identities, and +the last axiom says that any morphism can be factored in a unique way +as a morphism in `W₁` followed by a morphism in `W₂`. -/ +structure ReedyStructure {C : Type*} [Category* C] (W₁ W₂ : MorphismProperty C) + [W₁.IsMultiplicative] [W₂.IsMultiplicative] + (α : Type*) [LinearOrder α] [OrderBot α] [SuccOrder α] [WellFoundedLT α] where + /-- the degree of an object -/ + deg : C → α + lt₁ {X Y : C} (f : X ⟶ Y) (hf : W₁ f) (hf' : ¬ identities C f) : deg Y < deg X + lt₂ {X Y : C} (f : X ⟶ Y) (hf : W₂ f) (hf' : ¬ identities C f) : deg X < deg Y + nonempty_unique {X Y : C} (f : X ⟶ Y) : + Nonempty (Unique (W₁.MapFactorizationData W₂ f)) + +namespace ReedyStructure + +variable {C : Type*} [Category* C] {W₁ W₂ : MorphismProperty C} + [W₁.IsMultiplicative] [W₂.IsMultiplicative] + {α : Type*} [LinearOrder α] [OrderBot α] [SuccOrder α] [WellFoundedLT α] + (r : ReedyStructure W₁ W₂ α) + +/-- The opposite of a Reedy structure. -/ +@[simps] +protected def op : ReedyStructure W₂.op W₁.op α where + deg := r.deg ∘ Opposite.unop + lt₁ f hf hf' := r.lt₂ f.unop hf (by + simpa [MorphismProperty.identities_op_iff] using hf') + lt₂ f hf hf' := r.lt₁ f.unop hf (by + simpa [MorphismProperty.identities_op_iff] using hf') + nonempty_unique f := + MorphismProperty.MapFactorizationData.opEquiv.uniqueCongr.nonempty_congr.1 + (r.nonempty_unique f.unop) + +lemma le₁ {X Y : C} (f : X ⟶ Y) (hf : W₁ f) : r.deg Y ≤ r.deg X := by + by_cases hf' : MorphismProperty.identities C f + · cases hf' + rfl + · exact (r.lt₁ f hf hf').le + +lemma le₂ {X Y : C} (f : X ⟶ Y) (hf : W₂ f) : r.deg X ≤ r.deg Y := by + by_cases hf' : MorphismProperty.identities C f + · cases hf' + rfl + · exact (r.lt₂ f hf hf').le + +lemma identities_of_prop₁_of_eq {X Y : C} {f : X ⟶ Y} (hf : W₁ f) (h : r.deg X = r.deg Y) : + MorphismProperty.identities _ f := by + by_contra + exact h.not_gt (r.lt₁ _ hf this) + +lemma identities_of_prop₂_of_eq {X Y : C} {f : X ⟶ Y} (hf : W₂ f) (h : r.deg X = r.deg Y) : + MorphismProperty.identities _ f := by + by_contra + exact h.not_lt (r.lt₂ _ hf this) + +include r in +lemma subsingleton_mapFactorizationData ⦃X Y : C⦄ (f : X ⟶ Y) : + Subsingleton (W₁.MapFactorizationData W₂ f) := by + have := (r.nonempty_unique f).some + infer_instance + +/-- The Reedy factorization of a morphism `f : X ⟶ Y` as a morphism in `W₁` +followed by a morphism in `W₂`. -/ +@[no_expose] +noncomputable def mapFactorizationData {X Y : C} (f : X ⟶ Y) : + W₁.MapFactorizationData W₂ f := by + letI := (r.nonempty_unique f).some + exact default + +include r in +lemma unique_obj {X Y : C} {f : X ⟶ Y} (fac fac' : W₁.MapFactorizationData W₂ f) : + fac.Z = fac'.Z := by + have := r.subsingleton_mapFactorizationData f + obtain rfl : fac = fac' := Subsingleton.elim _ _ + rfl + +include r in +lemma unique {X Y : C} {f : X ⟶ Y} (fac fac' : W₁.MapFactorizationData W₂ f) : + ∃ (h : fac.Z = fac'.Z), fac.i = fac'.i ≫ eqToHom h.symm ∧ fac.p = eqToHom h ≫ fac'.p := by + have := r.subsingleton_mapFactorizationData f + obtain rfl : fac = fac' := Subsingleton.elim _ _ + simp + +/-- The degree of a morphisms for a Reedy structure. It is defined as the degree of +the intermediate object in the Reedy factorization, but it is also the smallest +degree of an intermediate object in a factorization, see the lemma `degHom_le`. -/ +@[no_expose] +noncomputable def degHom {X Y : C} (f : X ⟶ Y) : α := r.deg (r.mapFactorizationData f).Z + +lemma degHom_eq {X Y : C} {f : X ⟶ Y} (h : W₁.MapFactorizationData W₂ f) : + r.degHom f = r.deg h.Z := by + have := r.subsingleton_mapFactorizationData + rw [← Subsingleton.elim (r.mapFactorizationData f) h] + rfl + +lemma exists_fac {X Y : C} (f : X ⟶ Y) : + ∃ (Z : C) (a : X ⟶ Z) (b : Z ⟶ Y), W₁ a ∧ W₂ b ∧ a ≫ b = f ∧ r.degHom f = r.deg Z := + ⟨_, _, _, (r.mapFactorizationData f).hi, (r.mapFactorizationData f).hp, + (r.mapFactorizationData f).fac, rfl⟩ + +lemma degHom_le {X Z Y : C} (f : X ⟶ Z) (g : Z ⟶ Y) : + r.degHom (f ≫ g) ≤ r.deg Z := by + obtain ⟨Zf, f₁, f₂, hf₁, hf₂, fac_f, eq_f⟩ := r.exists_fac f + obtain ⟨Zg, g₁, g₂, hg₁, hg₂, fac_g, eq_g⟩ := r.exists_fac g + obtain ⟨Zh, h₁, h₂, hh₁, hh₂, fac_h, eq_h⟩ := r.exists_fac (f₂ ≫ g₁) + let factfg := MorphismProperty.MapFactorizationData.mk (f := f ≫ g) Zh (f₁ ≫ h₁) (h₂ ≫ g₂) + (by simp [reassoc_of% fac_h, reassoc_of% fac_f, fac_g]) + (W₁.comp_mem _ _ hf₁ hh₁) (W₂.comp_mem _ _ hh₂ hg₂) + rw [r.degHom_eq factfg] + exact (r.le₁ _ hh₁).trans (r.le₂ _ hf₂) + +lemma degHom_le_deg_left {X Y : C} (f : X ⟶ Y) : + r.degHom f ≤ r.deg X := by + simpa using r.degHom_le (𝟙 X) f + +lemma degHom_le_deg_right {X Y : C} (f : X ⟶ Y) : + r.degHom f ≤ r.deg Y := by + simpa using r.degHom_le f (𝟙 Y) + +lemma degHom_comp_le_left {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : + r.degHom (f ≫ g) ≤ r.degHom f := by + have ⟨_, f₁, f₂, _, _, h_fac, h_deg⟩ := r.exists_fac f + rw [h_deg, ← h_fac, Category.assoc] + exact r.degHom_le f₁ (f₂ ≫ g) + +lemma degHom_comp_le_right {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : + r.degHom (f ≫ g) ≤ r.degHom g := by + have ⟨_, g₁, g₂, _, _, h_fac, h_deg⟩ := r.exists_fac g + rw [h_deg, ← h_fac, <- Category.assoc] + exact r.degHom_le (f ≫ g₁) g₂ + +lemma prop₂_of_degHom_eq_deg_left {X Y : C} {f : X ⟶ Y} (hf : r.degHom f = r.deg X) : + W₂ f := by + obtain ⟨Z, p, i, hp, hi, fac, h⟩ := r.exists_fac f + obtain ⟨_⟩ := r.identities_of_prop₁_of_eq hp (by aesop) + obtain rfl : i = f := by simpa using fac + exact hi + +lemma prop₁_of_degHom_eq_deg_right {X Y : C} {f : X ⟶ Y} (hf : r.degHom f = r.deg Y) : + W₁ f := by + obtain ⟨Z, p, i, hp, hi, fac, h⟩ := r.exists_fac f + obtain ⟨_⟩ := r.identities_of_prop₂_of_eq hi (by aesop) + obtain rfl : p = f := by simpa using fac + exact hp + +lemma degHom_lt_or_of_degHom_comp_lt + {X Z Y : C} (f : X ⟶ Z) (g : Z ⟶ Y) (hfg : r.degHom (f ≫ g) < r.deg Z) : + r.degHom f < r.deg Z ∨ r.degHom g < r.deg Z := by + contrapose! hfg + let φ := MorphismProperty.MapFactorizationData.mk Z f g rfl + (r.prop₁_of_degHom_eq_deg_right (le_antisymm (r.degHom_le_deg_right f) hfg.left)) + (r.prop₂_of_degHom_eq_deg_left (le_antisymm (r.degHom_le_deg_left g) hfg.right)) + rw [r.degHom_eq φ] + +@[simp] +lemma degHom_id (X : C) : r.degHom (𝟙 X) = r.deg X := + r.degHom_eq (MorphismProperty.MapFactorizationData.mk X (𝟙 X) (𝟙 X) (by simp) (W₁.id_mem _) + (W₂.id_mem _)) + +lemma deg_eq_of_iso {X Y : C} (e : X ≅ Y) : r.deg X = r.deg Y := by + have {X Y : C} (e : X ≅ Y) : r.deg X ≤ r.deg Y := by + rw [← r.degHom_id X, ← e.hom_inv_id] + apply r.degHom_le + exact le_antisymm (this e) (this e.symm) + +include r in +lemma prop₁_of_iso {X Y : C} (e : X ≅ Y) : W₁ e.hom := + r.prop₁_of_degHom_eq_deg_right (by + refine le_antisymm ?_ ?_ + · simpa using r.degHom_comp_le_right e.hom (𝟙 Y) + · simpa using r.degHom_comp_le_right e.inv e.hom) + +include r in +lemma prop₂_of_iso {X Y : C} (e : X ≅ Y) : W₂ e.hom := + (r.op.prop₁_of_iso e.op) + +include r in +lemma skeletal : Skeletal C := by + intro X Y ⟨e⟩ + exact (r.unique (f := e.hom) + (.mk X (𝟙 X) e.hom (by simp) (W₁.id_mem X) (r.prop₂_of_iso e)) + (.mk Y e.hom (𝟙 Y) (by simp) (r.prop₁_of_iso e) (W₂.id_mem Y))).choose + +end ReedyStructure + +end HomotopicalAlgebra diff --git a/Mathlib/CategoryTheory/MorphismProperty/Composition.lean b/Mathlib/CategoryTheory/MorphismProperty/Composition.lean index 37c150c2e5a9e8..69a532ca7dd9b7 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Composition.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Composition.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2022 Andrew Yang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Andrew Yang, Joël Riou +Authors: Andrew Yang, Joël Riou, Aras Ergus -/ module @@ -27,6 +27,18 @@ namespace MorphismProperty variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] +variable (C) in +/-- The property of morphisms that is satisfied by `𝟙 X` for any `X`. -/ +abbrev identities : MorphismProperty C := + .ofHoms fun X ↦ 𝟙 X + +lemma identities_op_iff {X Y : Cᵒᵖ} (f : X ⟶ Y) : + identities Cᵒᵖ f ↔ identities C f.unop := by + obtain ⟨X⟩ := X + obtain ⟨f⟩ := f + dsimp + exact ⟨fun ⟨_⟩ ↦ ⟨_⟩, fun ⟨_⟩ ↦ ⟨_⟩⟩ + /-- Typeclass expressing that a morphism property contains identities. -/ class ContainsIdentities (W : MorphismProperty C) : Prop where /-- for all `X : C`, the identity of `X` satisfies the morphism property -/ @@ -72,6 +84,13 @@ instance iInf {ι : Type*} {W : ι → MorphismProperty C} rw [← sInf_range] exact sInf (by simpa) +lemma iff_identities_le {W : MorphismProperty C} : + W.ContainsIdentities ↔ identities C ≤ W := + ⟨fun _ ↦ by intro _ _ _ ⟨_⟩; exact id_mem _, fun h ↦ ⟨fun _ ↦ h _ ⟨_⟩⟩⟩ + +instance : (identities C).ContainsIdentities := + iff_identities_le.2 (by rfl) + end ContainsIdentities instance Prod.containsIdentities {C₁ C₂ : Type*} [Category* C₁] [Category* C₂] @@ -220,6 +239,12 @@ instance : (epimorphisms C).IsMultiplicative where rw [epimorphisms.iff] at hf hg ⊢ apply epi_comp +instance : (identities C).IsMultiplicative where + comp_mem := by + rintro _ _ _ _ _ ⟨_⟩ ⟨_⟩ + simp only [Category.comp_id] + constructor + instance {P : MorphismProperty D} [P.IsMultiplicative] (F : C ⥤ D) : (P.inverseImage F).IsMultiplicative where diff --git a/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean b/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean index 616aca68551303..6c864a3443bd19 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean @@ -72,6 +72,25 @@ def op {X Y : C} {f : X ⟶ Y} (hf : MapFactorizationData W₁ W₂ f) : hi := hf.hp hp := hf.hi +/-- The factorization obtained from a factorization in the opposite category. -/ +@[simps] +protected def unop {W₁ W₂ : MorphismProperty Cᵒᵖ} {X Y : Cᵒᵖ} {f : X ⟶ Y} + (φ : MapFactorizationData W₁ W₂ f) : + MapFactorizationData W₂.unop W₁.unop f.unop where + Z := φ.Z.unop + i := φ.p.unop + p := φ.i.unop + hi := φ.hp + hp := φ.hi + fac := by simp [← unop_comp] + +/-- The bijection between factorizations in `C` and factorizations in `Cᵒᵖ`. -/ +@[simps] +def opEquiv {W₁ W₂ : MorphismProperty C} {X Y : C} {f : X ⟶ Y} : + MapFactorizationData W₁ W₂ f ≃ MapFactorizationData W₂.op W₁.op f.op where + toFun φ := φ.op + invFun φ := φ.unop + end MapFactorizationData /-- The data of a term in `MapFactorizationData W₁ W₂ f` for any morphism `f`. -/ From 50b02783d6bc4fb0062521148db7ad923145b150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 3 Jul 2026 09:07:05 +0000 Subject: [PATCH 0571/1300] =?UTF-8?q?feat(Analysis/Real):=20characterise?= =?UTF-8?q?=20when=20`=E2=88=9Ax=20=E2=89=A4=20x`=20and=20`x=20=E2=89=A4?= =?UTF-8?q?=20=E2=88=9Ax`=20(#41249)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From APAP --- Mathlib/Analysis/Real/Sqrt.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/Analysis/Real/Sqrt.lean b/Mathlib/Analysis/Real/Sqrt.lean index 3b8cd015df8f07..ebd06fcb895a4b 100644 --- a/Mathlib/Analysis/Real/Sqrt.lean +++ b/Mathlib/Analysis/Real/Sqrt.lean @@ -303,6 +303,18 @@ lemma sqrt_le_sqrt_iff' (hx : 0 < x) : √x ≤ √y ↔ x ≤ y := by @[simp] lemma isSquare_iff : IsSquare x ↔ 0 ≤ x := ⟨(·.nonneg), (⟨√x, mul_self_sqrt · |>.symm⟩)⟩ +@[simp] lemma sqrt_le_self_iff : √x ≤ x ↔ x = 0 ∨ 1 ≤ x := by + rw [sqrt_le_iff, ← sub_nonneg (a := x ^ 2), sq, ← mul_sub_one] + grind [mul_nonneg_iff] + +@[simp] lemma le_sqrt_self_iff : x ≤ √x ↔ x ≤ 1 := by + obtain hx | hx := le_or_gt x 0 + · simp [hx.trans] + · rw [le_sqrt' hx, sq, mul_le_iff_le_one_left hx] + +@[simp] lemma sqrt_lt_self_iff : √x < x ↔ 1 < x := by simp [← not_le] +@[simp] lemma lt_sqrt_self_iff : x < √x ↔ x ≠ 0 ∧ x < 1 := by simp [← not_le] + end Real namespace Mathlib.Meta.Positivity From 857acd3bbcc0c1f06b15b4ecd6ab7278ff0f77ca Mon Sep 17 00:00:00 2001 From: ymonbru <109665681+ymonbru@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:38:48 +0000 Subject: [PATCH 0572/1300] feat: add the set of compacts nhds of a compact and flavor of it towards the definition of K-sheaf (#40737) this file adds the definition of the set of compacts nhds of a compact, the open nhds of a compact, the open relatively compact nhds of a compact and the compacts inside an open subset. It also adds API related with these sets and the way they interact. In particular there is API related to the induced (as preorder) categories. I neede the dual version of Monotone.final_functor_iff, Joel Riou told me to duplicate the code for now (as the same tactic sequence can prove the dual version) until the automation can deal with that. All these definitions are prerequisite to the definition of K-Sheaves and their link with Sheaves, this will follow in an other PR Co-authored-by: Yannis Monbru --- Mathlib.lean | 1 + Mathlib/CategoryTheory/Filtered/Final.lean | 16 ++++ Mathlib/Topology/Sets/BaseChangeNhds.lean | 97 +++++++++++++++++++ Mathlib/Topology/Sets/Compacts.lean | 105 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Mathlib/Topology/Sets/BaseChangeNhds.lean diff --git a/Mathlib.lean b/Mathlib.lean index d12b8b7c5bed1c..022c89560e0dbd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -8119,6 +8119,7 @@ public import Mathlib.Topology.Separation.Profinite public import Mathlib.Topology.Separation.Regular public import Mathlib.Topology.Separation.SeparatedNhds public import Mathlib.Topology.Sequences +public import Mathlib.Topology.Sets.BaseChangeNhds public import Mathlib.Topology.Sets.Closeds public import Mathlib.Topology.Sets.CompactOpenCovered public import Mathlib.Topology.Sets.Compacts diff --git a/Mathlib/CategoryTheory/Filtered/Final.lean b/Mathlib/CategoryTheory/Filtered/Final.lean index 604403e69da7d9..3a35baf057910e 100644 --- a/Mathlib/CategoryTheory/Filtered/Final.lean +++ b/Mathlib/CategoryTheory/Filtered/Final.lean @@ -490,3 +490,19 @@ lemma Monotone.final_functor_iff {J₁ J₂ : Type*} [Preorder J₁] [Preorder J exact ⟨j₁, ⟨homOfLE h₁⟩⟩ · intro _ c _ _ exact ⟨c, 𝟙 _, rfl⟩ + +lemma Monotone.initial_functor_iff {J₁ J₂ : Type*} [Preorder J₁] [Preorder J₂] + [IsCodirectedOrder J₁] {f : J₁ → J₂} (hf : Monotone f) : + hf.functor.Initial ↔ ( ∀ j₁,∃ j₂, f j₂ ≤ j₁) := by + rw [Functor.initial_iff_of_isCofiltered] + constructor + · rintro ⟨h, _⟩ j₂ + obtain ⟨j₁, ⟨φ⟩⟩ := h j₂ + exact ⟨j₁,leOfHom φ⟩ + · intro h + constructor + · intro j₂ + obtain ⟨j₁, h₁⟩ := h j₂ + exact ⟨j₁, ⟨homOfLE h₁⟩⟩ + · intro _ c _ _ + exact ⟨ c, 𝟙 _, rfl⟩ diff --git a/Mathlib/Topology/Sets/BaseChangeNhds.lean b/Mathlib/Topology/Sets/BaseChangeNhds.lean new file mode 100644 index 00000000000000..83a8c9c091db3d --- /dev/null +++ b/Mathlib/Topology/Sets/BaseChangeNhds.lean @@ -0,0 +1,97 @@ +/- +Copyright (c) 2026 Yannis Monbru-Carcelero. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yannis Monbru Carcelero +-/ + +module + +public import Mathlib.CategoryTheory.Filtered.Final +public import Mathlib.Topology.Sets.Compacts + +/-! +# Base changes among different families of neighbourhoods + +This file builds base changes for `.compactsInside`, `openNhds`. + +It also contains the evidences that `openRcNhds_to_openNhds`and + `openRcNhds_to_compactNhds` are initials functors. + +-/ + +@[expose] public section + +namespace TopologicalSpace + +open Set CategoryTheory Limits + +variable {α : Type*} [TopologicalSpace α] + +namespace Opens + +/-- For `U` an open subset included in a open subset `V`, there is +a map sending compacts inside `U` to the ones inside `V` -/ +def baseChangeCompactsInside {U V : Opens α} (h : U ⟶ V) : U.compactsInside → V.compactsInside := + fun ⟨K, hK⟩ ↦ ⟨K, fun _ hx ↦ Set.mem_of_subset_of_mem (leOfHom h) (hK hx)⟩ + +lemma baseChangeCompactsInside_mono {U V : Opens α} (h : U ⟶ V) : + Monotone <| baseChangeCompactsInside h := + fun _ _ hKL _ hx ↦ SetLike.mem_coe.mpr (hKL hx) + +@[simp] +lemma baseChangeCompactsInside_comp {U V W : Opens α} (h : U ⟶ V) (k : V ⟶ W) + (K : U.compactsInside) : + baseChangeCompactsInside (h ≫ k) K = baseChangeCompactsInside k (baseChangeCompactsInside h K) + := by rfl + +@[simp] +lemma baseChangeOpenNhds_id {U : Opens α} (K : U.compactsInside) : + baseChangeCompactsInside (𝟙 U) K = K := by rfl + +end Opens + +namespace Compacts + +/-- For `K` a compact subset included in a compact subset `L`, there +is a map sending open neighbourhoods of `L` to the ones of `K` -/ +def baseChangeOpenNhds {K L : Compacts α} (h : K ⟶ L) : L.openNhds → K.openNhds := + fun ⟨U, hU⟩ ↦ ⟨U, fun _ hx ↦ Set.mem_of_subset_of_mem hU (leOfHom h hx)⟩ + +lemma baseChangeOpenNhds_mono {K L : Compacts α} (h : K ⟶ L) : Monotone <| baseChangeOpenNhds h := + fun _ _ hUV _ hx ↦ SetLike.mem_coe.mpr (hUV hx) + +@[simp] +lemma baseChangeOpenNhds_comp {K L M : Compacts α} (h : K ⟶ L) (k : L ⟶ M) (U : M.openNhds) : + baseChangeOpenNhds (h ≫ k) U = baseChangeOpenNhds h (baseChangeOpenNhds k U) := by rfl + +@[simp] +lemma baseChangeOpenNhds_id {K : Compacts α} (U : K.openNhds) : + baseChangeOpenNhds (𝟙 K) U = U := by rfl + +/-- The evidence that `⊥` is initial among the compact open neighbourhoods of `⊥` -/ +def isInitialBotOpensOpenNhdsBot : IsInitial (⊥ : (⊥ : Compacts α).openNhds) := .ofUniqueHom + (fun _ ↦ homOfLE <| by tauto) + (fun _ _ ↦ eq_of_comp_right_eq <| by tauto) + +instance {K : Compacts α} [T2Space α] [LocallyCompactSpace α] : + K.openRcNhdsToOpenNhds_mono.functor.Initial := by + rw [Monotone.initial_functor_iff] + intro U + obtain ⟨L, h1, h2, h3⟩ := exists_compact_between K.isCompact U.val.isOpen U.property + use ⟨⟨interior L, isOpen_interior⟩, + ⟨IsCompact.of_isClosed_subset h1 isClosed_closure + (closure_minimal interior_subset (IsCompact.isClosed h1)), + h2⟩⟩ + exact Subset.trans interior_subset h3 + +instance {K : Compacts α} [T2Space α] : K.openRcNhdsToCompactNhds_mono.functor.Initial := by + rw [Monotone.initial_functor_iff] + intro L + obtain ⟨U, h1, h2⟩ := exists_open_set_nhds_of_compactsNhds L + have h3 : closure (U : Set α) ⊆ L := (IsClosed.closure_subset_iff + (IsCompact.isClosed L.1.isCompact') ).2 h2 + exact ⟨⟨U, ⟨ IsCompact.of_isClosed_subset L.1.isCompact' isClosed_closure h3, h1⟩⟩, h3⟩ + +end Compacts + +end TopologicalSpace diff --git a/Mathlib/Topology/Sets/Compacts.lean b/Mathlib/Topology/Sets/Compacts.lean index 79a5b1cbe6bcea..358da018fa882e 100644 --- a/Mathlib/Topology/Sets/Compacts.lean +++ b/Mathlib/Topology/Sets/Compacts.lean @@ -273,8 +273,113 @@ theorem singleton_prod_singleton (x : α) (y : β) : -- todo: add `pi` +open Topology + +/-- The compacts neigbourhoods of a compact -/ +def compactNhds (K : Compacts α) : Set (Compacts α) := + {K' | ∀ (x : K), (K': Set α) ∈ 𝓝 x.val} + +lemma subset_of_mem_compactNhds {K K' : Compacts α} (h : K' ∈ K.compactNhds) : + (K : Set α) ⊆ K' := + fun x hx ↦ mem_of_mem_nhds (h ⟨x, hx⟩) + +lemma exists_open_set_nhds_of_compactsNhds {K : Compacts α} (L : K.compactNhds) : + ∃ U : Opens α, (K : Set α) ⊆ U ∧ (U : Set α) ⊆ L := by + obtain ⟨U, KsubU, openU, UsubL⟩ := exists_open_set_nhds (fun x hx ↦ L.2 ⟨x, hx⟩) + exact ⟨⟨U, openU⟩, KsubU, UsubL⟩ + +lemma exists_open_set_nhds_of_mem_compactsNhds {K K' : Compacts α} (h : K' ∈ K.compactNhds) : + ∃ U : Opens α, (K : Set α) ⊆ U ∧ (U : Set α) ⊆ K' := + exists_open_set_nhds_of_compactsNhds ⟨K', h⟩ + +/-- The compact neigbourhood induced by the existence of an open subset between two compacts -/ +def compactNhdsMkOfOpens {K : Compacts α} (L : Compacts α) (U : Opens α) + (h1 : (K : Set α) ⊆ U) (h2 : (U : Set α) ⊆ L) : + K.compactNhds := + ⟨L, fun _ ↦ Filter.mem_of_superset (IsOpen.mem_nhds U.is_open' (h1 (Subtype.coe_prop _))) h2⟩ + +instance [T2Space α] (K : Compacts α) : SemilatticeInf (K.compactNhds) where + inf L M := ⟨L.1 ⊓ M.1, fun x ↦ Filter.inter_mem_iff.2 ⟨L.2 x, M.2 x⟩⟩ + inf_le_right _ _ := Subtype.coe_le_coe.mp inf_le_right + inf_le_left _ _:= Subtype.coe_le_coe.mp inf_le_left + le_inf _ _ _ h k := + Subtype.coe_le_coe.mp (le_inf (Subtype.coe_le_coe.mpr h) (Subtype.coe_le_coe.mpr k)) + +/-- The set of opens neighbourhood of a compact subset -/ +def openNhds (K : Compacts α) : Set (Opens α) := {U | (K : Set α) ⊆ U} + +instance (K : Compacts α) : IsCodirectedOrder K.openNhds where + directed U1 U2 := ⟨⟨U1.val ⊓ U2.val, Set.subset_inter U1.property U2.property⟩, + ⟨Subtype.mk_le_mk.2 inf_le_left, Subtype.mk_le_mk.2 inf_le_right⟩⟩ + +instance (K : Compacts α) : Top K.openNhds := ⟨⊤, Set.subset_univ _⟩ +-- in particular `K.openNhds` is not empty and thus the induced catgory is cofiltered + +instance : Bot (⊥ : Compacts α).openNhds := ⟨⊥, fun _ h ↦ h⟩ + +/-- The opens neighbourhood of a compact subset that are relatively compact -/ +def openRcNhds (K : Compacts α) : Set (Opens α) := + {U | IsCompact (closure (U : Set α )) ∧ (K : Set α) ⊆ U} + +lemma subset_of_mem_openRcNhds {K : Compacts α} {U : Opens α} (h : U ∈ K.openRcNhds) : + (K : Set α) ⊆ U := + fun _ hx ↦ h.right hx + +lemma isCompact_closure_of_mem_openRcNhds {K : Compacts α} {U : Opens α} (h : U ∈ K.openRcNhds) : + IsCompact (closure (U : Set α)) := h.left + +lemma closure_mem_compactNhds_of_mem_openRcNhds {K : Compacts α} {U : Opens α} + (h : U ∈ K.openRcNhds) : + ⟨closure (U : Set α), isCompact_closure_of_mem_openRcNhds h⟩ ∈ K.compactNhds := by + intro x + have H : (U : Set α) ∈ 𝓝 (x : α) := + U.isOpen.mem_nhds <| Compacts.subset_of_mem_openRcNhds h (by simp) + exact Filter.mem_of_superset H subset_closure + +/-- The converting map from relatively compact opens +neighbourhood of a compact subset to its opens neighbourhoods -/ +def openRcNhdsToOpenNhds (K : Compacts α) : K.openRcNhds → K.openNhds := + fun U ↦ ⟨_, U.property.2⟩ + +lemma openRcNhdsToOpenNhds_mono (K : Compacts α) : + Monotone K.openRcNhdsToOpenNhds := fun _ _ h ↦ h + +/-- An open relatively compact neighbourhood of `K` induces a compact neighbourhood by taking +the closure +-/ +def openRcNhdsToCompactNhds (K : Compacts α) : K.openRcNhds → K.compactNhds := + fun U ↦ ⟨_, closure_mem_compactNhds_of_mem_openRcNhds (Subtype.coe_prop U)⟩ + +lemma openRcNhdsToCompactNhds_mono (K : Compacts α) : Monotone K.openRcNhdsToCompactNhds := + fun _ _ h ↦ closure_mono h + +instance [T2Space α] (K : Compacts α) : IsCodirectedOrder K.openRcNhds where + directed U1 U2 := ⟨⟨U1 ⊓ U2, (isCompact_closure_of_mem_openRcNhds (Subtype.coe_prop U1) |>.inter + <| isCompact_closure_of_mem_openRcNhds U2.coe_prop).of_isClosed_subset + isClosed_closure <| closure_inter_subset_inter_closure .., + le_inf (subset_of_mem_openRcNhds (Subtype.coe_prop U1)) + <| subset_of_mem_openRcNhds (Subtype.coe_prop U2)⟩, + Subtype.coe_le_coe.mp inf_le_left, + Subtype.coe_le_coe.mp inf_le_right⟩ + end Compacts +namespace Opens + +/-- The set of compacts inside an open subset -/ +def compactsInside (U : Opens α) : Set (Compacts α) := {K | (K : Set α) ⊆ U} + +/-- For `K` a compact subset insde an open subset `U`, `U` has a structure of open neighbourhood +of `K` -/ +def openNhdsOfCompactsInside {U : Opens α} (K : U.compactsInside) : (K.val).openNhds := + ⟨U, K.property⟩ + +end Opens + +/-- For `U` an open neighbourhood of `K`, `K` has a structure of compact insde `U` -/ +def Compacts.compactsInsideOfOpenNhds {K : Compacts α} (U : K.openNhds) : (U.val).compactsInside := + ⟨K, U.property⟩ + /-! ### Nonempty compact sets -/ /-- The type of nonempty compact sets of a topological space. -/ From 5286cbb15862dbd684b36a0bea3d04d68c429ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:38:51 +0000 Subject: [PATCH 0573/1300] refactor(CategoryTheory): more data in the PushoutObjObj structure (#40797) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given a bifunctor `F : C₁ ⥤ C₂ ⥤ C₃`, and morphisms `f₁ : X₁ ⟶ Y₁` in `C₁` and `f₂ : X₂ ⟶ Y₂` in `C₂`, one can form a commutative square in the category `C₃`, and the `PushoutObjObj` structure contains the data of a pushout of the top and left maps in this square. Then, `PushoutObjObj.ι` is the induced map from the pushout to the bottom-right object of the square. Until this PR, `PushoutObjObj.ι` was a definition. In this PR, we make it a field of the structure `PushoutObjObj` instead. This allows a better control on the definitional properties of `ι`. This already simplifies proofs in the file `Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PushoutProduct.lean` and I plan to take advantage of this in the formalization of the Reedy model category structure https://github.com/joelriou/reedy because in the study of similar structures for trifunctors obtained as compositions of bifunctors, these `ι` will appear as parameters of certain dependent types. --- .../Inner/PushoutProduct.lean | 30 ++--- .../AnodyneExtensions/PushoutProduct.lean | 30 ++--- .../SimplicialSet/PushoutProduct.lean | 15 +-- .../Shapes/Pullback/PullbackObjObj.lean | 104 ++++++------------ .../Monoidal/Braided/PushoutObjObj.lean | 5 - .../Monoidal/PushoutProduct.lean | 22 ++-- 6 files changed, 74 insertions(+), 132 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Inner/PushoutProduct.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Inner/PushoutProduct.lean index 4288b72d875f09..8816b313836957 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Inner/PushoutProduct.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Inner/PushoutProduct.lean @@ -110,44 +110,38 @@ lemma innerAnodyneExtensions_pushoutObjObjι' end -set_option backward.defeqAttrib.useBackward true in lemma innerAnodyneExtensions_unionProd_ι {X Y : SSet.{u}} (A : X.Subcomplex) (B : Y.Subcomplex) (hB : innerAnodyneExtensions B.ι) : - innerAnodyneExtensions (A.unionProd B).ι := by - simpa using innerAnodyneExtensions_pushoutObjObjι (Subcomplex.unionProd.pushoutObjObj A B) hB + innerAnodyneExtensions (A.unionProd B).ι := + innerAnodyneExtensions_pushoutObjObjι (Subcomplex.unionProd.pushoutObjObj A B) hB -set_option backward.defeqAttrib.useBackward true in lemma innerAnodyneExtensions_unionProd_ι' {X Y : SSet.{u}} (A : X.Subcomplex) (B : Y.Subcomplex) (hA : innerAnodyneExtensions A.ι) : - innerAnodyneExtensions (A.unionProd B).ι := by - simpa using innerAnodyneExtensions_pushoutObjObjι' (Subcomplex.unionProd.pushoutObjObj A B) hA + innerAnodyneExtensions (A.unionProd B).ι := + innerAnodyneExtensions_pushoutObjObjι' (Subcomplex.unionProd.pushoutObjObj A B) hA -set_option backward.defeqAttrib.useBackward true in lemma innerAnodyneExtensions.whiskerRight {X Y : SSet.{u}} {f : X ⟶ Y} (hf : innerAnodyneExtensions f) (Z : SSet.{u}) : - innerAnodyneExtensions (f ▷ Z) := by - simpa using innerAnodyneExtensions_pushoutObjObjι' + innerAnodyneExtensions (f ▷ Z) := + innerAnodyneExtensions_pushoutObjObjι' (.ofIsInitialRight (curriedTensor _) f (initial.to Z) initialIsInitial) hf -set_option backward.defeqAttrib.useBackward true in lemma innerAnodyneExtensions.whiskerLeft {X Y : SSet.{u}} {f : X ⟶ Y} (hf : innerAnodyneExtensions f) (Z : SSet.{u}) : - innerAnodyneExtensions (Z ◁ f) := by - simpa using innerAnodyneExtensions_pushoutObjObjι + innerAnodyneExtensions (Z ◁ f) := + innerAnodyneExtensions_pushoutObjObjι (.ofIsInitialLeft (curriedTensor _) (initial.to Z) f initialIsInitial) hf -set_option backward.defeqAttrib.useBackward true in instance {E B X : SSet.{u}} (p : E ⟶ B) [InnerFibration p] : - InnerFibration ((ihom X).map p) := by - simpa using innerFibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsInitial + InnerFibration ((ihom X).map p) := + innerFibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsInitial MonoidalClosed.internalHom (initial.to X) p initialIsInitial) -set_option backward.isDefEq.respectTransparency false in instance {A B : SSet.{u}} (i : A ⟶ B) [Mono i] (X : SSet.{u}) [Quasicategory X] : - InnerFibration ((MonoidalClosed.pre i).app X) := by - simpa using innerFibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsTerminal + InnerFibration ((MonoidalClosed.pre i).app X) := + innerFibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsTerminal MonoidalClosed.internalHom i (terminal.from X) terminalIsTerminal) instance (A : SSet.{u}) : Quasicategory ((ihom A).obj (⊤_ _)) := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PushoutProduct.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PushoutProduct.lean index 9155e285cd79c1..b043fc8c529dbc 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PushoutProduct.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PushoutProduct.lean @@ -112,44 +112,38 @@ lemma anodyneExtensions_pushoutObjObjι' end -set_option backward.defeqAttrib.useBackward true in lemma anodyneExtensions_unionProd_ι {X Y : SSet.{u}} (A : X.Subcomplex) (B : Y.Subcomplex) (hB : anodyneExtensions B.ι) : - anodyneExtensions (A.unionProd B).ι := by - simpa using anodyneExtensions_pushoutObjObjι (Subcomplex.unionProd.pushoutObjObj A B) hB + anodyneExtensions (A.unionProd B).ι := + anodyneExtensions_pushoutObjObjι (Subcomplex.unionProd.pushoutObjObj A B) hB -set_option backward.defeqAttrib.useBackward true in lemma anodyneExtensions_unionProd_ι' {X Y : SSet.{u}} (A : X.Subcomplex) (B : Y.Subcomplex) (hA : anodyneExtensions A.ι) : - anodyneExtensions (A.unionProd B).ι := by - simpa using anodyneExtensions_pushoutObjObjι' (Subcomplex.unionProd.pushoutObjObj A B) hA + anodyneExtensions (A.unionProd B).ι := + anodyneExtensions_pushoutObjObjι' (Subcomplex.unionProd.pushoutObjObj A B) hA -set_option backward.defeqAttrib.useBackward true in lemma anodyneExtensions.whiskerRight {X Y : SSet.{u}} {f : X ⟶ Y} (hf : anodyneExtensions f) (Z : SSet.{u}) : - anodyneExtensions (f ▷ Z) := by - simpa using anodyneExtensions_pushoutObjObjι' + anodyneExtensions (f ▷ Z) := + anodyneExtensions_pushoutObjObjι' (.ofIsInitialRight (curriedTensor _) f (initial.to Z) initialIsInitial) hf -set_option backward.defeqAttrib.useBackward true in lemma anodyneExtensions.whiskerLeft {X Y : SSet.{u}} {f : X ⟶ Y} (hf : anodyneExtensions f) (Z : SSet.{u}) : - anodyneExtensions (Z ◁ f) := by - simpa using anodyneExtensions_pushoutObjObjι + anodyneExtensions (Z ◁ f) := + anodyneExtensions_pushoutObjObjι (.ofIsInitialLeft (curriedTensor _) (initial.to Z) f initialIsInitial) hf -set_option backward.defeqAttrib.useBackward true in instance {E B X : SSet.{u}} (p : E ⟶ B) [Fibration p] : - Fibration ((ihom X).map p) := by - simpa using fibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsInitial + Fibration ((ihom X).map p) := + fibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsInitial MonoidalClosed.internalHom (initial.to X) p initialIsInitial) -set_option backward.isDefEq.respectTransparency false in instance {A B : SSet.{u}} (i : A ⟶ B) [Mono i] (X : SSet.{u}) [KanComplex X] : - Fibration ((MonoidalClosed.pre i).app X) := by - simpa using fibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsTerminal + Fibration ((MonoidalClosed.pre i).app X) := + fibration_pullbackObjObjπ (Functor.PullbackObjObj.ofIsTerminal MonoidalClosed.internalHom i (terminal.from X) terminalIsTerminal) instance (A : SSet.{u}) : KanComplex ((ihom A).obj (⊤_ _)) := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean b/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean index a37287f012af70..fa376a2784977d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean @@ -36,8 +36,9 @@ set_option backward.defeqAttrib.useBackward true in noncomputable def ιIso : Arrow.mk (S.unionProd T).ι ≅ S.ι □ T.ι := Arrow.isoMk' _ _ (isPushout S T).isoPushout (Iso.refl _) - (by apply (unionProd.isPushout S T).hom_ext <;> - simp [Functor.PushoutObjObj.ofHasPushout, Functor.PushoutObjObj.ι]) + (by + apply (unionProd.isPushout S T).hom_ext <;> + simp [Limits.pushout.inl_desc, Limits.pushout.inr_desc]) /-- Given subcomplexes `S` and `T` of simplicial sets, this if a `Functor.PushoutObjObj` structure for the chosen binary products on `SSet`, with point `S.unionProd T`. -/ @@ -47,15 +48,7 @@ noncomputable def pushoutObjObj : (curriedTensor _).PushoutObjObj S.ι T.ι wher inl := unionProd.ι₁ S T inr := unionProd.ι₂ S T isPushout := unionProd.isPushout S T - -set_option backward.defeqAttrib.useBackward true in -@[simp] -lemma pushoutObjObj_ι : (pushoutObjObj S T).ι = (S.unionProd T).ι := by - apply (pushoutObjObj S T).hom_ext - · rw [(pushoutObjObj S T).inl_ι] - simp - · rw [(pushoutObjObj S T).inr_ι] - simp + ι := (S.unionProd T).ι end unionProd diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean index 240a41e7591ce0..d6dffd0357608d 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean @@ -78,11 +78,17 @@ structure PushoutObjObj where /-- the second inclusion -/ inr : (F.obj X₁).obj Y₂ ⟶ pt isPushout : IsPushout ((F.map f₁).app X₂) ((F.obj X₁).map f₂) inl inr + /-- the Leibniz pushout -/ + ι : pt ⟶ (F.obj Y₁).obj Y₂ := isPushout.desc ((F.obj Y₁).map f₂) ((F.map f₁).app Y₂) (by simp) + inl_ι : inl ≫ ι = (F.obj Y₁).map f₂ := by cat_disch + inr_ι : inr ≫ ι = (F.map f₁).app Y₂ := by cat_disch namespace PushoutObjObj +attribute [reassoc (attr := simp)] inl_ι inr_ι + /-- The `PushoutObjObj` structure given by the pushout of the colimits API. -/ -@[simps -isSimp] +@[simps] noncomputable def ofHasPushout [HasPushout ((F.map f₁).app X₂) ((F.obj X₁).map f₂)] : F.PushoutObjObj f₁ f₂ where @@ -90,25 +96,18 @@ noncomputable def ofHasPushout inl := pushout.inl _ _ inr := pushout.inr _ _ isPushout := IsPushout.of_hasPushout _ _ + ι := pushout.desc ((F.obj Y₁).map f₂) ((F.map f₁).app Y₂) (by simp) + inl_ι := pushout.inl_desc .. + inr_ι := pushout.inr_desc .. variable {F f₁ f₂} (sq : F.PushoutObjObj f₁ f₂) -/-- The "inclusion" `sq.pt ⟶ (F.obj Y₁).obj Y₂` when -`sq : F.PushoutObjObj f₁ f₂`. -/ -noncomputable def ι : sq.pt ⟶ (F.obj Y₁).obj Y₂ := - sq.isPushout.desc ((F.obj Y₁).map f₂) ((F.map f₁).app Y₂) (by simp) - -@[reassoc (attr := simp)] -lemma inl_ι : sq.inl ≫ sq.ι = (F.obj Y₁).map f₂ := by simp [ι] - -@[reassoc (attr := simp)] -lemma inr_ι : sq.inr ≫ sq.ι = (F.map f₁).app Y₂ := by simp [ι] - @[ext] lemma hom_ext {X₃ : C₃} {f g : sq.pt ⟶ X₃} (hₗ : sq.inl ≫ f = sq.inl ≫ g) (hᵣ : sq.inr ≫ f = sq.inr ≫ g) : f = g := sq.isPushout.hom_ext hₗ hᵣ +set_option backward.defeqAttrib.useBackward true in /-- Given `sq : F.PushoutObjObj f₁ f₂`, flipping the pushout square gives `sq.flip : F.flip.PushoutObjObj f₂ f₁`. -/ @[simps] @@ -117,13 +116,9 @@ def flip : F.flip.PushoutObjObj f₂ f₁ where inl := sq.inr inr := sq.inl isPushout := sq.isPushout.flip + ι := sq.ι -set_option backward.isDefEq.respectTransparency false in -@[simp] -lemma ι_flip : sq.flip.ι = sq.ι := by - apply sq.flip.isPushout.hom_ext - · rw [inl_ι, flip_inl, inr_ι, flip_obj_map] - · rw [inr_ι, flip_inr, inl_ι, flip_map_app] +@[deprecated (since := "2026-06-19")] alias ι_flip := flip_ι section @@ -138,23 +133,10 @@ def ofNatIso : F'.PushoutObjObj f₁ f₂ where isPushout := sq.isPushout.of_iso ((e.app _).app _) ((e.app _).app _) ((e.app _).app _) (Iso.refl _) (by simp) (by simp) (by simp) (by simp) - -set_option backward.defeqAttrib.useBackward true in -@[simp, reassoc] -lemma ofNatIso_ι : - (sq.ofNatIso e).ι = sq.ι ≫ (e.hom.app _).app _ := by - apply sq.hom_ext - · simp [← (sq.ofNatIso e).inl_ι] - · simp [← (sq.ofNatIso e).inr_ι] + ι := sq.ι ≫ (e.hom.app _).app _ end -set_option backward.isDefEq.respectTransparency false in -lemma ofHasPushout_ι [HasPushout ((F.map f₁).app X₂) ((F.obj X₁).map f₂)] : - (ofHasPushout F f₁ f₂).ι = - pushout.desc ((F.obj Y₁).map f₂) ((F.map f₁).app Y₂) (by simp) := by - ext <;> simp [PushoutObjObj.ι, ofHasPushout_inl, ofHasPushout_inr] - section variable (F f₁ f₂) @@ -162,6 +144,7 @@ variable (F f₁ f₂) [PreservesColimitsOfShape (Discrete PEmpty.{1}) (F.flip.obj Y₂)] (h : IsInitial X₁) +set_option backward.defeqAttrib.useBackward true in /-- A `Functor.PushoutObjObj` structure for a functor `F : C₁ ⥤ C₂ ⥤ C₃` and morphisms `f₁ : X₁ ⟶ Y₁` and `f₂ : X₂ ⟶ Y₂` when `X₁` is initial and both `F.flip.obj X₂` and `F.flip.obj Y₂` preserve the initial object. -/ @@ -176,11 +159,8 @@ noncomputable def ofIsInitialLeft : F.PushoutObjObj f₁ f₂ where apply +allowSynthFailures IsPushout.of_vert_isIso · exact isIso_of_isInitial hX₂ hY₂ _ · exact ⟨hX₂.hom_ext _ _⟩ - -set_option backward.defeqAttrib.useBackward true in -@[simp] -lemma ofIsInitialLeft_ι : (ofIsInitialLeft F f₁ f₂ h).ι = (F.obj Y₁).map f₂ := by - simpa using (ofIsInitialLeft F f₁ f₂ h).inl_ι + ι := (F.obj Y₁).map f₂ + inr_ι := (IsInitial.isInitialObj (F.flip.obj Y₂) _ h).hom_ext .. end @@ -205,11 +185,8 @@ noncomputable def ofIsInitialRight : F.PushoutObjObj f₁ f₂ where apply +allowSynthFailures IsPushout.of_horiz_isIso · exact isIso_of_isInitial hX₁ hY₁ _ · exact ⟨hX₁.hom_ext _ _⟩ - -set_option backward.defeqAttrib.useBackward true in -@[simp] -lemma ofIsInitialRight_ι : (ofIsInitialRight F f₁ f₂ h).ι = (F.map f₁).app Y₂ := by - simpa using (ofIsInitialRight F f₁ f₂ h).inr_ι + ι := (F.map f₁).app Y₂ + inl_ι := (IsInitial.isInitialObj (F.obj Y₁) _ h).hom_ext .. end @@ -360,11 +337,19 @@ structure PullbackObjObj where snd : pt ⟶ (G.obj (op Y₁)).obj Y₃ isPullback : IsPullback fst snd ((G.obj (op X₁)).map f₃) ((G.map f₁.op).app Y₃) + /-- the Leibniz pullback -/ + π : (G.obj (op Y₁)).obj X₃ ⟶ pt := + isPullback.lift ((G.map f₁.op).app X₃) ((G.obj (op Y₁)).map f₃) (by simp) + π_fst : π ≫ fst = (G.map f₁.op).app X₃ := by cat_disch + π_snd : π ≫ snd = (G.obj (op Y₁)).map f₃ := by cat_disch namespace PullbackObjObj +attribute [reassoc (attr := simp)] π_fst π_snd + +set_option backward.isDefEq.respectTransparency false in /-- The `PullbackObjObj` structure given by the pullback of the limits API. -/ -@[simps -isSimp] +@[simps] noncomputable def ofHasPullback [HasPullback ((G.obj (op X₁)).map f₃) ((G.map f₁.op).app Y₃)] : G.PullbackObjObj f₁ f₃ where @@ -372,32 +357,15 @@ noncomputable def ofHasPullback fst := pullback.fst _ _ snd := pullback.snd _ _ isPullback := IsPullback.of_hasPullback _ _ + π := pullback.lift ((G.map f₁.op).app X₃) ((G.obj (op Y₁)).map f₃) (by simp) variable {G f₁ f₃} (sq : G.PullbackObjObj f₁ f₃) -/-- The projection `(G.obj (op Y₁)).obj X₃ ⟶ sq.pt` when -`sq : G.PullbackObjObj f₁ f₃`. -/ -noncomputable def π : (G.obj (op Y₁)).obj X₃ ⟶ sq.pt := - sq.isPullback.lift ((G.map f₁.op).app X₃) ((G.obj (op Y₁)).map f₃) (by simp) - -@[reassoc (attr := simp)] -lemma π_fst : sq.π ≫ sq.fst = (G.map f₁.op).app X₃ := by simp [π] - -@[reassoc (attr := simp)] -lemma π_snd : sq.π ≫ sq.snd = (G.obj (op Y₁)).map f₃ := by simp [π] - @[ext] lemma hom_ext {X₂ : C₂} {f g : X₂ ⟶ sq.pt} (h₁ : f ≫ sq.fst = g ≫ sq.fst) (h₂ : f ≫ sq.snd = g ≫ sq.snd) : f = g := sq.isPullback.hom_ext h₁ h₂ -set_option backward.isDefEq.respectTransparency false in -lemma ofHasPullback_π - [HasPullback ((G.obj (op X₁)).map f₃) ((G.map f₁.op).app Y₃)] : - (ofHasPullback G f₁ f₃).π = - pullback.lift ((G.map f₁.op).app X₃) ((G.obj (op Y₁)).map f₃) (by simp) := by - ext <;> simp [PullbackObjObj.π, ofHasPullback_fst, ofHasPullback_snd] - section variable (G f₁ f₃) @@ -419,11 +387,8 @@ noncomputable def ofIsInitial : G.PullbackObjObj f₁ f₃ where apply +allowSynthFailures IsPullback.of_vert_isIso · exact isIso_of_isTerminal hX₃ hY₃ _ · exact ⟨hY₃.hom_ext _ _⟩ - -set_option backward.defeqAttrib.useBackward true in -@[simp] -lemma ofIsInitial_π : (ofIsInitial G f₁ f₃ h).π = (G.obj (op Y₁)).map f₃ := by - simpa using (ofIsInitial G f₁ f₃ h).π_snd + π := (G.obj (op Y₁)).map f₃ + π_fst := (IsTerminal.isTerminalObj (G.flip.obj X₃) _ h.op).hom_ext _ _ end @@ -448,11 +413,8 @@ noncomputable def ofIsTerminal : G.PullbackObjObj f₁ f₃ where apply +allowSynthFailures IsPullback.of_horiz_isIso · exact isIso_of_isTerminal hY₁ hX₁ _ · exact ⟨hX₁.hom_ext _ _⟩ - -set_option backward.defeqAttrib.useBackward true in -@[simp] -lemma ofIsTerminal_π : (ofIsTerminal G f₁ f₃ h).π = (G.map f₁.op).app X₃ := by - simpa using (ofIsTerminal G f₁ f₃ h).π_fst + π := (G.map f₁.op).app X₃ + π_snd := (IsTerminal.isTerminalObj (G.obj (op Y₁)) _ h).hom_ext _ _ end diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/PushoutObjObj.lean b/Mathlib/CategoryTheory/Monoidal/Braided/PushoutObjObj.lean index e68cd152cf26cc..ec7d6b0b6cdef1 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/PushoutObjObj.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/PushoutObjObj.lean @@ -36,9 +36,4 @@ obtain a similar structure for `f₂` and `f₁`. -/ def flipTensor : (curriedTensor C).PushoutObjObj f₂ f₁ := sq.flip.ofNatIso (BraidedCategory.curriedBraidingNatIso _).symm -set_option backward.defeqAttrib.useBackward true in -@[simp] -lemma flipTensor_ι : dsimp% sq.flipTensor.ι = sq.ι ≫ (β_ _ _).inv := by - simp [flipTensor] - end CategoryTheory.Functor.PushoutObjObj diff --git a/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean b/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean index 15d96eeccc39c1..6ace1b822076ef 100644 --- a/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean +++ b/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean @@ -119,8 +119,8 @@ def whiskerLeftIso (associator_inv_naturality_middle W _ _).symm (associator_inv_naturality_right W _ _).symm)) (α_ W _ _).symm (((tensorLeft W).map_isPushout - (IsPushout.of_hasPushout (X₁.hom ▷ X₂.left) (X₁.left ◁ X₂.hom))).hom_ext (by - simp) (by simp)) + (IsPushout.of_hasPushout (X₁.hom ▷ X₂.left) (X₁.left ◁ X₂.hom))).hom_ext + (by simp [← whiskerLeft_comp_assoc]) (by simp [← whiskerLeft_comp_assoc])) set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @@ -138,7 +138,8 @@ def whiskerRightIso (associator_naturality_left _ _ W).symm (associator_naturality_middle _ _ W).symm)) (α_ _ _ W) (((tensorRight W).map_isPushout - (IsPushout.of_hasPushout (X₁.hom ▷ X₂.left) (X₁.left ◁ X₂.hom))).hom_ext (by simp) (by simp)) + (IsPushout.of_hasPushout (X₁.hom ▷ X₂.left) (X₁.left ◁ X₂.hom))).hom_ext + (by simp [← comp_whiskerRight_assoc]) (by simp [← comp_whiskerRight_assoc])) -- helper instance for `PushoutProduct.associator` local instance {F : C ⥤ C} @@ -165,16 +166,19 @@ def associator pushout.desc (_ ◁ pushout.inr _ _ ≫ pushout.inl _ _) (pushout.inr _ _) (by simp [Limits.pushout.associator_naturality_left_condition])) (((tensorRight _).map_isPushout (IsPushout.of_hasPushout _ _)).hom_ext - (by simp [Limits.pushout.whiskerLeft_condition_assoc, ← whisker_exchange_assoc]) - (by simp [← whisker_exchange_assoc, Limits.pushout.associator_naturality_left_condition])) + (by simp [Limits.pushout.whiskerLeft_condition_assoc, ← whisker_exchange_assoc, + ← comp_whiskerRight_assoc]) + (by simp [← whisker_exchange_assoc, Limits.pushout.associator_naturality_left_condition, + ← comp_whiskerRight_assoc])) · exact pushout.desc ((whiskerLeftIso _ _).hom.left ≫ pushout.desc (pushout.inl _ _) ((pushout.inl _ _ ▷ _) ≫ pushout.inr _ _) (by simp [Limits.pushout.associator_inv_naturality_right_condition])) ((α_ _ _ _).inv ≫ (pushout.inr _ _) ▷ _ ≫ pushout.inr _ _) (((tensorLeft _).map_isPushout (IsPushout.of_hasPushout _ _)).hom_ext (by simp [whisker_exchange_assoc, - Limits.pushout.associator_inv_naturality_right_condition]) - (by simp [whisker_exchange_assoc, Limits.pushout.condition_whiskerRight_assoc])) + Limits.pushout.associator_inv_naturality_right_condition, ← whiskerLeft_comp_assoc]) + (by simp [whisker_exchange_assoc, Limits.pushout.condition_whiskerRight_assoc, + ← whiskerLeft_comp_assoc])) · apply pushout.hom_ext (by simp) apply ((tensorRight _).map_isPushout (IsPushout.of_hasPushout _ _)).hom_ext <;> simp · refine pushout.hom_ext ?_ (by simp) @@ -214,7 +218,7 @@ def isInitialIso (X : Arrow C) {I : C} (i : IsInitial I) {W : C} : haveI : IsPushout (X.hom ▷ I) (_ ◁ i.to W) ((i.ofIso (zeroMul i).symm).to _) (𝟙 _) := .of_horiz_isIso (sq := ⟨(i.ofIso (zeroMul i).symm).hom_ext ..⟩) Arrow.isoMk' _ _ this.isoPushout.symm (Iso.refl _) - (pushout.hom_ext ((i.ofIso (zeroMul i).symm).hom_ext _ _) (by simp)) + (pushout.hom_ext ((i.ofIso (zeroMul i).symm).hom_ext ..) (by simp [pushout.inr_desc])) set_option backward.defeqAttrib.useBackward true in /-- The arrow isomorphism `(∅ ⟶ W) □ X ≅ W ◁ X` in a braided CCC with pushouts and @@ -227,7 +231,7 @@ def isInitialIso' [BraidedCategory C] (X : Arrow C) {I : C} (i : IsInitial I) {W haveI : IsPushout (i.to W ▷ _) (I ◁ X.hom) (𝟙 _) ((i.ofIso (mulZero i).symm).to _) := .of_vert_isIso (sq := ⟨(i.ofIso (mulZero i).symm).hom_ext ..⟩) Arrow.isoMk' _ _ this.isoPushout.symm (Iso.refl _) - (pushout.hom_ext (by simp) ((i.ofIso (mulZero i).symm).hom_ext _ _)) + (pushout.hom_ext (by simp [pushout.inl_desc]) ((i.ofIso (mulZero i).symm).hom_ext _ _)) /-- The arrow isomorphism `X □ (∅ ⟶ ⋆) ≅ X` in a CCC with pushouts, an initial object, and a terminal object. -/ From e62ffd551a0e87e98b36dc61a254446e220cf146 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:38:54 +0000 Subject: [PATCH 0574/1300] chore: fix bad indentation (#40853) Not exhaustive at all. Inspired by Zulip discussion in https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/linter.20requests/with/605217189 --- Counterexamples/NowhereDifferentiable.lean | 4 ++-- Mathlib/Algebra/Algebra/RestrictScalars.lean | 2 +- Mathlib/Algebra/EuclideanDomain/Basic.lean | 2 +- Mathlib/Algebra/Group/Submonoid/Units.lean | 2 +- Mathlib/Algebra/GroupWithZero/Units/Basic.lean | 2 +- .../Algebra/Homology/CochainComplexOpposite.lean | 2 +- .../Algebra/Homology/Factorizations/CM5a.lean | 3 +-- Mathlib/Algebra/Homology/HomologicalComplex.lean | 3 +-- ...mologicalComplexLimitsEventuallyConstant.lean | 2 +- .../HomotopyCategory/HomComplexInduction.lean | 2 +- Mathlib/Algebra/Homology/Precylinder.lean | 2 +- Mathlib/Algebra/Lie/Killing.lean | 6 +++--- Mathlib/Algebra/Lie/Prod.lean | 8 ++++---- .../Algebra/LieRinehartAlgebra/Subalgebra.lean | 2 +- .../Algebra/Order/GroupWithZero/Canonical.lean | 2 +- Mathlib/Algebra/Quaternion.lean | 2 +- Mathlib/Algebra/SkewMonoidAlgebra/Support.lean | 2 +- Mathlib/Algebra/SkewPolynomial/Basic.lean | 4 ++-- Mathlib/Algebra/Star/LinearMap.lean | 2 +- .../CStarAlgebra/GelfandNaimarkSegal.lean | 2 +- .../Distribution/ContDiffMapSupportedIn.lean | 4 ++-- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 2 +- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 2 +- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 3 +-- Mathlib/Analysis/ODE/Transform.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Sigmoid.lean | 2 +- .../Bicategory/Functor/StrictlyUnitary.lean | 2 +- Mathlib/CategoryTheory/Generator/Basic.lean | 2 +- .../CategoryTheory/GradedObject/Monoidal.lean | 2 +- .../GuitartExact/KanExtension.lean | 2 +- .../Limits/Shapes/Opposites/Equalizers.lean | 4 ++-- .../LocallyCartesianClosed/Over.lean | 6 +++--- Mathlib/CategoryTheory/Monoidal/Bimon_.lean | 4 ++-- .../Monoidal/DayConvolution/DayFunctor.lean | 4 ++-- .../CategoryTheory/Sites/Point/Skyscraper.lean | 2 +- Mathlib/Combinatorics/Graph/Subgraph.lean | 2 +- .../Combinatorics/SimpleGraph/FiveWheelLike.lean | 4 ++-- Mathlib/Combinatorics/SimpleGraph/Star.lean | 2 +- .../TuringMachine/StackTuringMachine.lean | 6 +++--- Mathlib/Data/Fin/Tuple/Basic.lean | 2 +- Mathlib/FieldTheory/Galois/Basic.lean | 2 +- .../IntermediateField/Adjoin/Defs.lean | 10 +++++----- .../FieldTheory/RatFunc/IntermediateField.lean | 2 +- Mathlib/FieldTheory/SeparableClosure.lean | 2 +- Mathlib/Geometry/Convex/ConvexSpace/Module.lean | 2 +- .../VectorBundle/CovariantDerivative/Metric.lean | 2 +- Mathlib/GroupTheory/FiniteAbelian/Duality.lean | 2 +- Mathlib/GroupTheory/RegularWreathProduct.lean | 6 +++--- .../Alternating/MaximalSubgroups.lean | 2 +- Mathlib/LinearAlgebra/Matrix/ZMatrix.lean | 4 ++-- Mathlib/LinearAlgebra/Reflection.lean | 4 ++-- Mathlib/LinearAlgebra/RootSystem/BaseExists.lean | 16 ++++++++-------- Mathlib/LinearAlgebra/Semisimple.lean | 4 ++-- .../Constructions/BorelSpace/Real.lean | 2 +- Mathlib/NumberTheory/SelbergSieve.lean | 4 ++-- Mathlib/Order/Types/Defs.lean | 8 ++++---- Mathlib/Order/UpperLower/CompleteLattice.lean | 2 +- .../Homological/Resolution.lean | 8 ++++---- Mathlib/RingTheory/FractionalIdeal/Basic.lean | 2 +- Mathlib/RingTheory/IsTensorProduct.lean | 14 +++++++------- .../RingTheory/OrderOfVanishing/Noetherian.lean | 2 +- .../RingTheory/Polynomial/Cyclotomic/Basic.lean | 2 +- Mathlib/Tactic/Algebra/Basic.lean | 2 +- Mathlib/Tactic/ComputeDegree.lean | 4 ++-- Mathlib/Tactic/FieldSimp.lean | 4 ++-- Mathlib/Tactic/FieldSimp/Attr.lean | 2 +- Mathlib/Tactic/Finiteness.lean | 4 ++-- Mathlib/Tactic/Translate/Core.lean | 2 +- Mathlib/Topology/Algebra/InfiniteSum/Field.lean | 2 +- .../Topology/Algebra/IsUniformGroup/Basic.lean | 4 ++-- Mathlib/Topology/EMetricSpace/Defs.lean | 2 +- Mathlib/Topology/IndicatorConstPointwise.lean | 6 +++--- Mathlib/Topology/Sion.lean | 2 +- MathlibTest/MkIffOfInductive.lean | 2 +- MathlibTest/Tactic/NormNum/Basic.lean | 2 +- 75 files changed, 126 insertions(+), 129 deletions(-) diff --git a/Counterexamples/NowhereDifferentiable.lean b/Counterexamples/NowhereDifferentiable.lean index 998caa01d49e12..2e1abcba12e4e7 100644 --- a/Counterexamples/NowhereDifferentiable.lean +++ b/Counterexamples/NowhereDifferentiable.lean @@ -76,8 +76,8 @@ theorem uniformContinuous_weierstrass {a : ℝ} (ha : a ∈ Set.Ioo 0 1) (b : To show that Weierstrass function $f(x)$ is not differentiable at any $x$, we choose a sequence $\{x_m\}$ such that, as $m\to\infty$ - - $\{x_m\}$ converges to $x$ - - The slope $(f(x_m) - f(x)) / (x_m - x)$ grows unbounded, +- $\{x_m\}$ converges to $x$ +- The slope $(f(x_m) - f(x)) / (x_m - x)$ grows unbounded, which means the derivative $f'(x)$ cannot exist. -/ diff --git a/Mathlib/Algebra/Algebra/RestrictScalars.lean b/Mathlib/Algebra/Algebra/RestrictScalars.lean index 3e2a3022589112..0fadc0e547779e 100644 --- a/Mathlib/Algebra/Algebra/RestrictScalars.lean +++ b/Mathlib/Algebra/Algebra/RestrictScalars.lean @@ -128,7 +128,7 @@ theorem IsScalarTower.restrictScalars [Module S M] : /-- This instance is only relevant when `RestrictScalars.moduleOrig` is available as an instance. -/ instance RestrictScalars.isScalarTower [Module S M] : IsScalarTower R S (RestrictScalars R S M) := - IsScalarTower.restrictScalars R S M + IsScalarTower.restrictScalars R S M end diff --git a/Mathlib/Algebra/EuclideanDomain/Basic.lean b/Mathlib/Algebra/EuclideanDomain/Basic.lean index 29d4260d10e80d..ca7cbc827090dc 100644 --- a/Mathlib/Algebra/EuclideanDomain/Basic.lean +++ b/Mathlib/Algebra/EuclideanDomain/Basic.lean @@ -419,7 +419,7 @@ section RingEquiv variable {R S : Type*} [EuclideanDomain R] [CommRing S] /-- If `S` is a nontrivial commutative ring isomorphic to a Euclidean domain - `R` then it is also a Euclidean domain. -/ +`R` then it is also a Euclidean domain. -/ protected abbrev RingEquiv.euclideanDomain (e : S ≃+* R) : EuclideanDomain S where toNontrivial := e.nontrivial quotient a b := e.symm (e a / e b) diff --git a/Mathlib/Algebra/Group/Submonoid/Units.lean b/Mathlib/Algebra/Group/Submonoid/Units.lean index bfd92d0a4dd51a..43f53ae8b81f86 100644 --- a/Mathlib/Algebra/Group/Submonoid/Units.lean +++ b/Mathlib/Algebra/Group/Submonoid/Units.lean @@ -189,7 +189,7 @@ S.unitsEquivUnitsType.trans unitsTypeEquivIsUnitSubmonoid end Units instance instSubsingletonUnits [Subsingleton Mˣ] {S : Submonoid M} : Subsingleton Sˣ := - .units_of_isUnit fun _a ha ↦ Subtype.ext (ha.map S.subtype).eq_one + .units_of_isUnit fun _a ha ↦ Subtype.ext (ha.map S.subtype).eq_one end Submonoid diff --git a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean index 9916a90765c529..eddd2a3619a1e3 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean @@ -170,7 +170,7 @@ theorem Ring.inverse_mul {a b : M₀} (h : IsUnit a ∨ IsUnit b) : (a * b)⁻¹ simp theorem Ring.isUnit_iff_inverse_ne_zero [Nontrivial M₀] {x : M₀} : IsUnit x ↔ x⁻¹ʳ ≠ 0 := - ⟨(IsUnit.ringInverse · |>.ne_zero), by simpa using mt <| Ring.inverse_non_unit (x := x)⟩ + ⟨(IsUnit.ringInverse · |>.ne_zero), by simpa using mt <| Ring.inverse_non_unit (x := x)⟩ grind_pattern Ring.isUnit_iff_inverse_ne_zero => IsUnit x, x⁻¹ʳ diff --git a/Mathlib/Algebra/Homology/CochainComplexOpposite.lean b/Mathlib/Algebra/Homology/CochainComplexOpposite.lean index 64b8dbc3f9a1d8..1fa7a1301583ec 100644 --- a/Mathlib/Algebra/Homology/CochainComplexOpposite.lean +++ b/Mathlib/Algebra/Homology/CochainComplexOpposite.lean @@ -199,7 +199,7 @@ lemma exactAt_op {K : CochainComplex C ℤ} {n : ℤ} (hK : K.ExactAt n) (by grind [next])] at hK lemma acyclic_op {K : CochainComplex C ℤ} (hK : K.Acyclic) : - ((opEquivalence C).functor.obj (op K)).Acyclic := + ((opEquivalence C).functor.obj (op K)).Acyclic := fun n ↦ exactAt_op (hK (-n)) n end CochainComplex diff --git a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean index 42fd1f3e186362..a8b90f9b7f277b 100644 --- a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean +++ b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean @@ -218,8 +218,7 @@ a factorisation of `f` as `ι f n ≫ π f n = f` where `ι f n : K ⟶ mid f n` is a monomorphism which is a quasi-isomorphism in degrees `≤ n`, `π f n` is a degreewise epimorphism with an injective kernel which also induces isomorphisms in degrees `≤ n`. - -/ - +-/ open HomComplex diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 99e9a323ad7da9..c98ed1fc1a863a 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -616,8 +616,7 @@ instance (f : C₁ ⟶ C₂) [IsSplitMono f] (j : ι) : IsSplitMono (f.f j) := inferInstanceAs (IsSplitMono ((eval _ _ j).map f)) @[push ←, simp] -lemma inv_f_apply (f : C₁ ⟶ C₂) [IsIso f] (j : ι) : - (inv f).f j = inv (f.f j) := by +lemma inv_f_apply (f : C₁ ⟶ C₂) [IsIso f] (j : ι) : (inv f).f j = inv (f.f j) := by apply IsIso.eq_inv_of_inv_hom_id simp [← comp_f] diff --git a/Mathlib/Algebra/Homology/HomologicalComplexLimitsEventuallyConstant.lean b/Mathlib/Algebra/Homology/HomologicalComplexLimitsEventuallyConstant.lean index c76e40fddbe9b2..c35a7343e85181 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplexLimitsEventuallyConstant.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplexLimitsEventuallyConstant.lean @@ -25,7 +25,7 @@ public section open CategoryTheory Category Limits variable {C J ι : Type*} [Category C] [Category J] - {c : ComplexShape ι} [IsCofiltered J] + {c : ComplexShape ι} [IsCofiltered J] namespace HomologicalComplex diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean index e852f802f684b3..b1c8cb3f37c129 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean @@ -40,7 +40,7 @@ def EqUpTo {n : ℤ} (α β : Cochain K L n) (p₀ : ℤ) : Prop := namespace InductionUp variable {d : ℤ} {X : ℕ → Set (Cochain K L d)} (φ : ∀ (n : ℕ), X n → X (n + 1)) - {p₀ : ℤ} (hφ : ∀ (n : ℕ) (x : X n), (φ n x).val.EqUpTo x.val (p₀ + n)) (x₀ : X 0) + {p₀ : ℤ} (hφ : ∀ (n : ℕ) (x : X n), (φ n x).val.EqUpTo x.val (p₀ + n)) (x₀ : X 0) /-- Assuming we have a sequence of subsets `X n : Set (Cochain K L d)` for all `n : ℕ`, a sequence of maps `φ n : X n → X (n + 1)` for `n : ℕ`, and an element `x₀ : X 0`, diff --git a/Mathlib/Algebra/Homology/Precylinder.lean b/Mathlib/Algebra/Homology/Precylinder.lean index d232a46034ba91..24b5e19930be59 100644 --- a/Mathlib/Algebra/Homology/Precylinder.lean +++ b/Mathlib/Algebra/Homology/Precylinder.lean @@ -38,7 +38,7 @@ noncomputable def precylinder [K.HasCylinder] : Precylinder K where π := cylinder.π _ /-- The pre-path object of a homological complex that is given by - `HomologicalComplex.pathObject`. -/ +`HomologicalComplex.pathObject`. -/ @[simps] noncomputable def prepathObject [K.HasPathObject] : PrepathObject K where P := K.pathObject diff --git a/Mathlib/Algebra/Lie/Killing.lean b/Mathlib/Algebra/Lie/Killing.lean index 6e24e0b900a1be..58a0a842e07fab 100644 --- a/Mathlib/Algebra/Lie/Killing.lean +++ b/Mathlib/Algebra/Lie/Killing.lean @@ -13,9 +13,9 @@ public import Mathlib.Algebra.Lie.TraceForm # Lie algebras with non-degenerate Killing forms. In characteristic zero, the following three conditions are equivalent: - 1. The solvable radical of a Lie algebra is trivial - 2. A Lie algebra is a direct sum of its simple ideals - 3. A Lie algebra has non-degenerate Killing form +1. The solvable radical of a Lie algebra is trivial +2. A Lie algebra is a direct sum of its simple ideals +3. A Lie algebra has non-degenerate Killing form In positive characteristic, it is still true that 3 implies 2, and that 2 implies 1, but there are counterexamples to the remaining implications. Thus condition 3 is the strongest assumption. diff --git a/Mathlib/Algebra/Lie/Prod.lean b/Mathlib/Algebra/Lie/Prod.lean index 48e9844cd6766e..ad29ba43b02a3e 100644 --- a/Mathlib/Algebra/Lie/Prod.lean +++ b/Mathlib/Algebra/Lie/Prod.lean @@ -25,8 +25,8 @@ This file defines the Lie algebra structure the Product of two Lie algebras - `LieHom.prodMap` the `Prod.map` of two Lie algebra homomorphisms is a Lie algebra homomorphism. ## Todo: Extend to further functionality from LinearMap.prod e.g. - - Lie Equivalences related to products - - Lie Submodule statements +- Lie Equivalences related to products +- Lie Submodule statements -/ @@ -132,7 +132,7 @@ variable (R L₁ L₂) theorem range_inl : range (inl R L₁ L₂) = ker (snd R L₁ L₂) := by rw [← LieSubalgebra.toSubmodule_inj, range_toSubmodule, LieIdeal.toLieSubalgebra_toSubmodule, - ker_toSubmodule] + ker_toSubmodule] exact LinearMap.range_inl R L₁ L₂ theorem ker_snd : ker (snd R L₁ L₂) = range (inl R L₁ L₂) := @@ -140,7 +140,7 @@ theorem ker_snd : ker (snd R L₁ L₂) = range (inl R L₁ L₂) := theorem range_inr : range (inr R L₁ L₂) = ker (fst R L₁ L₂) := by rw [← LieSubalgebra.toSubmodule_inj, range_toSubmodule, LieIdeal.toLieSubalgebra_toSubmodule, - ker_toSubmodule] + ker_toSubmodule] exact LinearMap.range_inr R L₁ L₂ theorem ker_fst : ker (fst R L₁ L₂) = range (inr R L₁ L₂) := diff --git a/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean b/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean index 56250b377b7ffd..3139fea5998468 100644 --- a/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean +++ b/Mathlib/Algebra/LieRinehartAlgebra/Subalgebra.lean @@ -207,7 +207,7 @@ section LieModule variable {M : Type*} [AddCommGroup M] [LieRingModule L M] [Module R M] /-- Given a Lie-Rinehart algebra `L` containing a LieRinehart subalgebra `L' ⊆ L`, together with a - Lie module `M` of `L`, we may regard `M` as a Lie module of `L'` by restriction. -/ +Lie module `M` of `L`, we may regard `M` as a Lie module of `L'` by restriction. -/ instance lieModule [LieModule R L M] : LieModule R L' M where smul_lie t x m := by rw [coe_bracket_of_module, Submodule.coe_smul_of_tower, smul_lie, coe_bracket_of_module] diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 44aff65f23f2b0..7c61a24d934051 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -58,7 +58,7 @@ instance (priority := 100) LinearOrderedCommMonoidWithZero.toMulPosStrictMono : -- See note [lower instance priority] instance (priority := 100) LinearOrderedCommMonoidWithZero.toIsOrderedMonoid : - IsOrderedMonoid α where + IsOrderedMonoid α where mul_le_mul_left a b hab c := by obtain rfl | hc := eq_or_ne c 0 · simp diff --git a/Mathlib/Algebra/Quaternion.lean b/Mathlib/Algebra/Quaternion.lean index 4c57a1cd268505..83aaf47e2793c9 100644 --- a/Mathlib/Algebra/Quaternion.lean +++ b/Mathlib/Algebra/Quaternion.lean @@ -471,7 +471,7 @@ theorem algebraMap_injective : (algebraMap R ℍ[R,c₁,c₂,c₃] : _ → _).In fun _ _ ↦ by simp [algebraMap_eq] instance : IsTorsionFree R ℍ[R,c₁,c₂,c₃] := - (addEquivProd ..).injective.moduleIsTorsionFree _ fun _ _ ↦ rfl + (addEquivProd ..).injective.moduleIsTorsionFree _ fun _ _ ↦ rfl section diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean index 1ea8d1e5037c62..7940905d09c8ed 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean @@ -110,7 +110,7 @@ theorem support_mul_single_eq_image {r : k} {x : G} (rx : IsRightRegular x) end DecidableEq theorem support_mul_single [IsRightCancelMul G] (r : k) (x : G) - (hrx : ∀ g : G, ∀ y, y * g • r = 0 ↔ y = 0) : + (hrx : ∀ g : G, ∀ y, y * g • r = 0 ↔ y = 0) : (f * single x r).support = f.support.map (mulRightEmbedding x) := by classical ext a diff --git a/Mathlib/Algebra/SkewPolynomial/Basic.lean b/Mathlib/Algebra/SkewPolynomial/Basic.lean index 0e1369bec1cfe0..926b3911497807 100644 --- a/Mathlib/Algebra/SkewPolynomial/Basic.lean +++ b/Mathlib/Algebra/SkewPolynomial/Basic.lean @@ -42,7 +42,7 @@ Furthermore, with this notation `φ^[n](a) = (ofAdd n) • a`, see `φ_iterate_a * `SkewPolynomial.monomial n a` is the skew polynomial `a X ^ n`. Note that `SkewPolynomial.monomial n` is defined as an `R`-linear map. * `SkewPolynomial.C a` is the constant skew polynomial `a`. Note that `C` is defined as an additive - homomorphism. + homomorphism. * `SkewPolynomial.CRingHom a` is the constant skew polynomial `a`, as a ring homomorphism. This requires to assume `[MulSemiringAction (Multiplicative ℕ) R]`. * `SkewPolynomial.X` is the skew polynomial `X`, i.e., `SkewPolynomial.monomial 1 1`. @@ -186,7 +186,7 @@ lemma smul_monomial {S} [Semiring S] [Module S R] (a : S) (b : R) : @[simp] lemma sum_monomial (f : SkewPolynomial R) : f.sum (fun (a : ℕ) ↦ monomial a) = f := - SkewMonoidAlgebra.sum_single _ + SkewMonoidAlgebra.sum_single _ @[simp] lemma sum_monomial_index {N} [AddCommMonoid N] {n : ℕ} {b : R} {h : ℕ → R → N} diff --git a/Mathlib/Algebra/Star/LinearMap.lean b/Mathlib/Algebra/Star/LinearMap.lean index db4ccb754ff7ef..0249b8488b7250 100644 --- a/Mathlib/Algebra/Star/LinearMap.lean +++ b/Mathlib/Algebra/Star/LinearMap.lean @@ -63,7 +63,7 @@ instance intrinsicStarAddMonoid : StarAddMonoid (WithConv (E →ₗ[R] F)) where theorem IntrinsicStar.isSelfAdjoint_iff_map_star (f : WithConv (E →ₗ[R] F)) : IsSelfAdjoint f ↔ ∀ x, f (star x) = star (f x) := by simp_rw [IsSelfAdjoint, WithConv.ext_iff, LinearMap.ext_iff, intrinsicStar_apply, - star_eq_iff_star_eq, eq_comm] + star_eq_iff_star_eq, eq_comm] @[deprecated (since := "2025-12-09")] alias isSelfAdjoint_iff_map_star := IntrinsicStar.isSelfAdjoint_iff_map_star diff --git a/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean b/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean index 9d39ae0363b9a5..3a577b00729dab 100644 --- a/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean +++ b/Mathlib/Analysis/CStarAlgebra/GelfandNaimarkSegal.lean @@ -135,7 +135,7 @@ consequence. -/ @[simp] private lemma completion_leftMulMapPreGNS_map_smul (m : ℂ) (x : A) : - (f.leftMulMapPreGNS (m • x)).completion = m • (f.leftMulMapPreGNS x).completion := by + (f.leftMulMapPreGNS (m • x)).completion = m • (f.leftMulMapPreGNS x).completion := by ext a induction a using induction_on with | hp => diff --git a/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean b/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean index d3a90374eea707..0ccb13f47c2c04 100644 --- a/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean +++ b/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean @@ -191,7 +191,7 @@ theorem copy_eq (f : 𝓓^{n}_{K}(E, F)) (f' : E → F) (h : f' = f) : f.copy f' @[simp] theorem coe_toBoundedContinuousFunction (f : 𝓓^{n}_{K}(E, F)) : - (f : BoundedContinuousFunction E F) = (f : E → F) := rfl + (f : BoundedContinuousFunction E F) = (f : E → F) := rfl section AddCommGroup @@ -234,7 +234,7 @@ instance : IsSubApply 𝓓^{n}_{K}(E, F) E F where @[deprecated (since := "2026-06-15")] alias coe_sub := FunLike.coe_sub instance instSMul {R} [Semiring R] [Module R F] [SMulCommClass ℝ R F] [ContinuousConstSMul R F] : - SMul R 𝓓^{n}_{K}(E, F) where + SMul R 𝓓^{n}_{K}(E, F) where smul c f := .mk (c • (f : E → F)) (f.contDiff.const_smul c) <| by rw [← smul_zero c] exact f.zero_on_compl.comp_left diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index a50a9e11c88999..297d9435e95b06 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -1335,7 +1335,7 @@ def orthonormalBasisSingleton : OrthonormalBasis ι 𝕜 E := @[simp] theorem orthonormalBasisSingleton_apply (i : ι) : - orthonormalBasisSingleton ι 𝕜 h v hv i = v := by + orthonormalBasisSingleton ι 𝕜 h v hv i = v := by simp [orthonormalBasisSingleton] @[simp] diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index eb2a4e773f4a14..152771a3d46fe5 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -20,7 +20,7 @@ public import Mathlib.Topology.Semicontinuity.Hemicontinuity This file contains the basic theory for the resolvent and spectrum of a Banach algebra. Theorems specific to *complex* Banach algebras, such as *Gelfand's formula* can be found in - `Mathlib/Analysis/Normed/Algebra/GelfandFormula.lean`. +`Mathlib/Analysis/Normed/Algebra/GelfandFormula.lean`. ## Main definitions diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index f5c101d5c96cc3..172f73b6945bf4 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -1243,8 +1243,7 @@ lemma toAddMonoidHom_linearMapOfLE (h : p ≤ q) : ext; rfl lemma linearMapOfLE_comp (hpq : p ≤ q) (hqr : q ≤ r) : - (linearMapOfLE 𝕜 E hqr).comp (linearMapOfLE 𝕜 E hpq) = - linearMapOfLE 𝕜 E (hpq.trans hqr) := by + (linearMapOfLE 𝕜 E hqr).comp (linearMapOfLE 𝕜 E hpq) = linearMapOfLE 𝕜 E (hpq.trans hqr) := by ext; rfl end OfLE diff --git a/Mathlib/Analysis/ODE/Transform.lean b/Mathlib/Analysis/ODE/Transform.lean index 1038e089811893..9f7120d18118ff 100644 --- a/Mathlib/Analysis/ODE/Transform.lean +++ b/Mathlib/Analysis/ODE/Transform.lean @@ -72,7 +72,7 @@ lemma IsIntegralCurveAt.comp_add (hγ : IsIntegralCurveAt γ v t₀) (dt : ℝ) isIntegralCurveAt_comp_add.mpr hγ lemma isIntegralCurveAt_comp_sub {dt : ℝ} : - IsIntegralCurveAt (γ ∘ (· - dt)) (v ∘ (· - dt)) (t₀ + dt) ↔ IsIntegralCurveAt γ v t₀ := by + IsIntegralCurveAt (γ ∘ (· - dt)) (v ∘ (· - dt)) (t₀ + dt) ↔ IsIntegralCurveAt γ v t₀ := by simpa using! isIntegralCurveAt_comp_add (dt := -dt) lemma IsIntegralCurveAt.comp_sub (hγ : IsIntegralCurveAt γ v t₀) (dt : ℝ) : diff --git a/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean b/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean index 2fb877b7f71693..81e3ca5316d90c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean +++ b/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean @@ -189,7 +189,7 @@ lemma ContDiff.sigmoid (hf : ContDiff ℝ ω f) : ContDiff ℝ ω (sigmoid ∘ f @[fun_prop] lemma differentiable_sigmoid : Differentiable ℝ sigmoid := - contDiff_sigmoid.of_le le_top |>.differentiable_one + contDiff_sigmoid.of_le le_top |>.differentiable_one @[fun_prop] lemma Differentiable.sigmoid (hf : Differentiable ℝ f) : Differentiable ℝ (sigmoid ∘ f) := diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/StrictlyUnitary.lean b/Mathlib/CategoryTheory/Bicategory/Functor/StrictlyUnitary.lean index 073d6dd9810ae8..9d80185dfd06a4 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/StrictlyUnitary.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/StrictlyUnitary.lean @@ -142,7 +142,7 @@ instance mapId_isIso (F : StrictlyUnitaryLaxFunctor B C) (x : B) : to an isomorphism when `F` is strictly unitary. -/ @[simps] def mapIdIso (F : StrictlyUnitaryLaxFunctor B C) (x : B) : - 𝟙 (F.obj x) ≅ F.map (𝟙 x) where + 𝟙 (F.obj x) ≅ F.map (𝟙 x) where hom := F.mapId x inv := eqToHom (F.map_id x) hom_inv_id := by simp [F.mapId_eq_eqToHom] diff --git a/Mathlib/CategoryTheory/Generator/Basic.lean b/Mathlib/CategoryTheory/Generator/Basic.lean index 29ee725fc88105..64fa142dd8cc16 100644 --- a/Mathlib/CategoryTheory/Generator/Basic.lean +++ b/Mathlib/CategoryTheory/Generator/Basic.lean @@ -550,7 +550,7 @@ theorem IsSeparator.of_equivalence {G : C} (h : IsSeparator G) (α : C ≌ D) : theorem IsCoseparator.of_equivalence {G : C} (h : IsCoseparator G) (α : C ≌ D) : IsCoseparator (α.functor.obj G) := by - simpa using! ObjectProperty.IsCoseparating.of_equivalence h α + simpa using! ObjectProperty.IsCoseparating.of_equivalence h α end Equivalence diff --git a/Mathlib/CategoryTheory/GradedObject/Monoidal.lean b/Mathlib/CategoryTheory/GradedObject/Monoidal.lean index 23473068c5b53a..a00bb81d325d9a 100644 --- a/Mathlib/CategoryTheory/GradedObject/Monoidal.lean +++ b/Mathlib/CategoryTheory/GradedObject/Monoidal.lean @@ -326,7 +326,7 @@ abbrev _root_.CategoryTheory.GradedObject.HasLeftTensor₃ObjExt (j : I) := Pres (Discrete.functor fun (i : { i : (I × I × I) | i.1 + i.2.1 + i.2.2 = j }) ↦ (((mapTrifunctor (bifunctorComp₂₃ (curriedTensor C) (curriedTensor C)) I I I).obj X₁).obj X₂).obj X₃ i) - ((curriedTensor C).obj Z) + ((curriedTensor C).obj Z) variable {X₁ X₂ X₃} variable [HasTensor X₂ X₃] [HasTensor X₁ (tensorObj X₂ X₃)] diff --git a/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean b/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean index 6c2f104be25efd..6237c66e5d64f0 100644 --- a/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean +++ b/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean @@ -118,7 +118,7 @@ end Functor.LeftExtension namespace TwoSquare variable {T : C₁ ⥤ C₂} {L : C₁ ⥤ C₃} {R : C₂ ⥤ C₄} {B : C₃ ⥤ C₄} - (w : TwoSquare T L R B) + (w : TwoSquare T L R B) include w diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean index dbd325de31bf8a..fee3e3f67f5143 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean @@ -108,8 +108,8 @@ namespace Cofork /-- The obvious map `Cofork f g → Fork f.unop g.unop` -/ def unop {X Y : Cᵒᵖ} {f g : X ⟶ Y} (c : Cofork f g) : Fork f.unop g.unop := - Cocone.unop ((Cocone.precompose (opParallelPairIso f.unop g.unop).hom).obj - (Cocone.whisker walkingParallelPairOpEquiv.inverse c)) + Cocone.unop ((Cocone.precompose (opParallelPairIso f.unop g.unop).hom).obj + (Cocone.whisker walkingParallelPairOpEquiv.inverse c)) set_option backward.defeqAttrib.useBackward true in lemma unop_π_app_one {X Y : Cᵒᵖ} {f g : X ⟶ Y} (c : Cofork f g) : diff --git a/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean b/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean index 7f3cc8cf2e0ec2..6f3bd6085f89cf 100644 --- a/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean +++ b/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean @@ -302,9 +302,9 @@ def forgetAdjToOver (X : C) : Over.forget X ⊣ toOver X where counit.app Z := fst Z X theorem forgetAdjToOver.homEquiv_symm {X : C} (Z : Over X) (A : C) (f : Z ⟶ (toOver X).obj A) : - ((forgetAdjToOver X).homEquiv Z A).symm f = f.left ≫ (fst _ _) := by - rw [Adjunction.homEquiv_counit, forgetAdjToOver_counit_app] - simp + ((forgetAdjToOver X).homEquiv Z A).symm f = f.left ≫ (fst _ _) := by + rw [Adjunction.homEquiv_counit, forgetAdjToOver_counit_app] + simp /-- The isomorphism of functors `toOver (𝟙_ C)` and `toOverUnit C`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean index e24b705f6e8de5..299305871404f6 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean @@ -172,7 +172,7 @@ set_option backward.isDefEq.respectTransparency false in @[simps!] def equivMonComonUnitIsoAppX (M : Bimon C) : M.X ≅ ((toMonComon C ⋙ ofMonComon C).obj M).X := - Mon.mkIso (equivMonComonUnitIsoAppXAux M) + Mon.mkIso (equivMonComonUnitIsoAppXAux M) set_option backward.isDefEq.respectTransparency false in instance (M : Bimon C) : IsComonHom (equivMonComonUnitIsoAppX M).hom where @@ -216,7 +216,7 @@ set_option backward.isDefEq.respectTransparency false in @[simps!] def equivMonComonCounitIsoApp (M : Mon (Comon C)) : (ofMonComon C ⋙ toMonComon C).obj M ≅ M := - Mon.mkIso <| (equivMonComonCounitIsoAppX M) + Mon.mkIso <| (equivMonComonCounitIsoAppX M) /-- The equivalence `Comon (Mon C) ≌ Mon (Comon C)` -/ def equivMonComon : Bimon C ≌ Mon (Comon C) where diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean index 248f5c4c941e9e..d921d186640088 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean @@ -158,13 +158,13 @@ def tensorDesc {F G H : C ⊛⥤ V} lemma η_comp_tensorDec {F G H : C ⊛⥤ V} (α : F.functor ⊠ G.functor ⟶ tensor C ⋙ H.functor) : - η F G ≫ Functor.whiskerLeft _ (tensorDesc α).natTrans = α := + η F G ≫ Functor.whiskerLeft _ (tensorDesc α).natTrans = α := Functor.descOfIsLeftKanExtension_fac _ _ _ _ @[reassoc (attr := simp)] lemma η_comp_tensorDesc_app {F G H : C ⊛⥤ V} (α : F.functor ⊠ G.functor ⟶ tensor C ⋙ H.functor) (x y : C) : - (η F G).app (x, y) ≫ (tensorDesc α).natTrans.app (x ⊗ y) = α.app (x, y) := + (η F G).app (x, y) ≫ (tensorDesc α).natTrans.app (x ⊗ y) = α.app (x, y) := Functor.descOfIsLeftKanExtension_fac_app _ _ _ _ _ open LawfulDayConvolutionMonoidalCategoryStruct diff --git a/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean b/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean index 54e9c9b6f39918..d6e557e769855b 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean @@ -109,7 +109,7 @@ lemma skyscraperPresheafHomEquiv_naturality_left Φ.skyscraperPresheafHomEquiv (Φ.presheafFiber.map f ≫ g) = f ≫ Φ.skyscraperPresheafHomEquiv g := Φ.skyscraperPresheafHomEquiv.symm.injective - (by simp [Φ.skyscraperPresheafHomEquiv_naturality_left_symm]) + (by simp [Φ.skyscraperPresheafHomEquiv_naturality_left_symm]) end diff --git a/Mathlib/Combinatorics/Graph/Subgraph.lean b/Mathlib/Combinatorics/Graph/Subgraph.lean index e95c7da66199bc..720b5263a920f6 100644 --- a/Mathlib/Combinatorics/Graph/Subgraph.lean +++ b/Mathlib/Combinatorics/Graph/Subgraph.lean @@ -46,7 +46,7 @@ graphs, subgraph, induced subgraph, spanning subgraph, closed subgraph public section variable {α β : Type*} {x y z u v w : α} {e f : β} {G G₁ G₂ H H₁ H₂ K : Graph α β} {F F₁ F₂ : Set β} - {X Y : Set α} + {X Y : Set α} open Set diff --git a/Mathlib/Combinatorics/SimpleGraph/FiveWheelLike.lean b/Mathlib/Combinatorics/SimpleGraph/FiveWheelLike.lean index 16d779a23d9d33..ec4282dafd2578 100644 --- a/Mathlib/Combinatorics/SimpleGraph/FiveWheelLike.lean +++ b/Mathlib/Combinatorics/SimpleGraph/FiveWheelLike.lean @@ -20,7 +20,7 @@ structures as well as graphs which avoid this structure. These have two key uses first appeared. We give this proof below, see `colorable_of_cliqueFree_lt_minDegree`. If `G` is maximally `Kᵣ₊₂`-free and `¬ G.Adj x y` (with `x ≠ y`) then there exists an `r`-set `s` - such that `s ∪ {x}` and `s ∪ {y}` are both `r + 1`-cliques. +such that `s ∪ {x}` and `s ∪ {y}` are both `r + 1`-cliques. If `¬ G.IsCompleteMultipartite` then it contains a `G.IsPathGraph3Compl v w₁ w₂` consisting of an edge `w₁w₂` and a vertex `v` such that `vw₁` and `vw₂` are non-edges. @@ -28,7 +28,7 @@ an edge `w₁w₂` and a vertex `v` such that `vw₁` and `vw₂` are non-edges. Hence any maximally `Kᵣ₊₂`-free graph that is not complete-multipartite must contain distinct vertices `v, w₁, w₂`, together with `r`-sets `s` and `t`, such that `{v, w₁, w₂}` induces the single edge `w₁w₂`, `s ∪ t` is disjoint from `{v, w₁, w₂}`, and `s ∪ {v}`, `t ∪ {v}`, `s ∪ {w₁}` and - `t ∪ {w₂}` are all `r + 1`-cliques. +`t ∪ {w₂}` are all `r + 1`-cliques. This leads to the definition of an `IsFiveWheelLike` structure which can be found in any maximally `Kᵣ₊₂`-free graph that is not complete-multipartite (see diff --git a/Mathlib/Combinatorics/SimpleGraph/Star.lean b/Mathlib/Combinatorics/SimpleGraph/Star.lean index 24d026a8c3b2de..f0a5ada3e89826 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Star.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Star.lean @@ -34,7 +34,7 @@ variable {V V' : Type*} (G : SimpleGraph V) (G' : SimpleGraph V') /-- The star graph on `V` centered at `r`: every non-center vertex is adjacent to `r`. -/ def starGraph (r : V) : SimpleGraph V := - .fromRel fun v _ ↦ v = r + .fromRel fun v _ ↦ v = r instance [DecidableEq V] (r : V) : DecidableRel (starGraph r).Adj := inferInstanceAs (DecidableRel fun x y ↦ x ≠ y ∧ (x = r ∨ y = r)) diff --git a/Mathlib/Computability/TuringMachine/StackTuringMachine.lean b/Mathlib/Computability/TuringMachine/StackTuringMachine.lean index 0e1a5b29264881..b1d70fe140e99a 100644 --- a/Mathlib/Computability/TuringMachine/StackTuringMachine.lean +++ b/Mathlib/Computability/TuringMachine/StackTuringMachine.lean @@ -300,9 +300,9 @@ stacks, but we have only one tape, so we must "multiplex" them all together. Pic 1 contains `[a, b]` and stack 2 contains `[c, d, e, f]` then the tape looks like this: ``` - bottom: ... | _ | T | _ | _ | _ | _ | ... - stack 1: ... | _ | b | a | _ | _ | _ | ... - stack 2: ... | _ | f | e | d | c | _ | ... +bottom: ... | _ | T | _ | _ | _ | _ | ... +stack 1: ... | _ | b | a | _ | _ | _ | ... +stack 2: ... | _ | f | e | d | c | _ | ... ``` where a tape element is a vertical slice through the diagram. Here the alphabet is diff --git a/Mathlib/Data/Fin/Tuple/Basic.lean b/Mathlib/Data/Fin/Tuple/Basic.lean index cc05c5f49d6741..4ec26a5bfc822b 100644 --- a/Mathlib/Data/Fin/Tuple/Basic.lean +++ b/Mathlib/Data/Fin/Tuple/Basic.lean @@ -1183,7 +1183,7 @@ lemma find_congr (hi : p i) (hpq : ∀ j ≤ i, p j ↔ q j) : /-- A weak version of `Fin.find_congr`, requiring `p = q` everywhere. -/ lemma find_congr' {hp : ∃ i, p i} {hq : ∃ i, q i} (hpq : ∀ {i}, p i ↔ q i) : - Fin.find p hp = Fin.find q hq := + Fin.find p hp = Fin.find q hq := let ⟨_, hp⟩ := hp; find_congr hp fun _ _ ↦ hpq lemma find_le (hi : p i) : Fin.find p ⟨i, hi⟩ ≤ i := diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index eb5609d304f505..1f888afb4d915f 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -288,7 +288,7 @@ A subgroup is isomorphic to the Galois group of its fixed field. -/ def subgroupEquivAlgEquiv [FiniteDimensional F E] (H : Subgroup Gal(E/F)) : H ≃* Gal(E/IntermediateField.fixedField H) := - (MulEquiv.subgroupCongr (fixingSubgroup_fixedField H).symm).trans (fixingSubgroupEquiv _) + (MulEquiv.subgroupCongr (fixingSubgroup_fixedField H).symm).trans (fixingSubgroupEquiv _) instance fixedField.smul : SMul K (fixedField (fixingSubgroup K)) where smul x y := ⟨x * y, fun ϕ => by diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean index 3f596fe43485df..99fe8c8f78d0dd 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean @@ -591,11 +591,11 @@ variable {A B C : Type*} [Field A] [Field B] [Field C] [Algebra A B] [Algebra B /-- Ring homomorphism between `A⟮b⟯` and `A⟮↑b⟯`. -/ def RingHom.adjoinAlgebraMap : A⟮b⟯ →+* A⟮((algebraMap B C) b)⟯ := RingHom.codRestrict (((Algebra.ofId B C).restrictScalars A).comp (IntermediateField.val A⟮b⟯)) _ - (fun x ↦ by - rw [show (algebraMap B C) b = (Algebra.ofId B C).restrictScalars A b by rfl, - ← Set.image_singleton, ← IntermediateField.adjoin_map A {b}] - use x - simp) + (fun x ↦ by + rw [show (algebraMap B C) b = (Algebra.ofId B C).restrictScalars A b by rfl, + ← Set.image_singleton, ← IntermediateField.adjoin_map A {b}] + use x + simp) instance : Algebra A⟮b⟯ A⟮(algebraMap B C) b⟯ := RingHom.toAlgebra (RingHom.adjoinAlgebraMap _) diff --git a/Mathlib/FieldTheory/RatFunc/IntermediateField.lean b/Mathlib/FieldTheory/RatFunc/IntermediateField.lean index c91f95b5d33eab..5fd7aeac0fe1f0 100644 --- a/Mathlib/FieldTheory/RatFunc/IntermediateField.lean +++ b/Mathlib/FieldTheory/RatFunc/IntermediateField.lean @@ -73,7 +73,7 @@ theorem minpolyX_eq_zero_iff : (f.minpolyX K⟮f⟯) = 0 ↔ ∃ c, f = C c := ⟨fun h ↦ f.eq_C_of_minpolyX_coeff_eq_zero (by simp [h]), by rintro ⟨c, rfl⟩; simp⟩ theorem isAlgebraic_adjoin_simple_X (hf : ¬∃ c, f = C c) : IsAlgebraic K⟮f⟯ (X : K⟮X⟯) := - ⟨f.minpolyX K⟮f⟯, fun H ↦ hf (f.minpolyX_eq_zero_iff.mp H), f.minpolyX_aeval_X⟩ + ⟨f.minpolyX K⟮f⟯, fun H ↦ hf (f.minpolyX_eq_zero_iff.mp H), f.minpolyX_aeval_X⟩ theorem isAlgebraic_adjoin_simple_X' (hf : ¬∃ c, f = C c) : Algebra.IsAlgebraic K⟮f⟯ K⟮X⟯ := by diff --git a/Mathlib/FieldTheory/SeparableClosure.lean b/Mathlib/FieldTheory/SeparableClosure.lean index cad4b2aad6bfbb..43518d5675b070 100644 --- a/Mathlib/FieldTheory/SeparableClosure.lean +++ b/Mathlib/FieldTheory/SeparableClosure.lean @@ -259,7 +259,7 @@ lemma separableClosure_le_separableClosure_iff [Algebra K E] [IsScalarTower F K E] {L : IntermediateField F E} : (separableClosure L E).restrictScalars F ≤ (separableClosure K E).restrictScalars F ↔ L ≤ (separableClosure K E).restrictScalars F := - (isClosed_restrictScalars_separableClosure F E K).closure_le_iff + (isClosed_restrictScalars_separableClosure F E K).closure_le_iff end separableClosure diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Module.lean b/Mathlib/Geometry/Convex/ConvexSpace/Module.lean index 155ef732f0bc2e..bfd6a3e1498226 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/Module.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/Module.lean @@ -83,7 +83,7 @@ lemma convexCombPair_eq_sum (a b : R) (ha hb hab) (x y : M) : classical simp [convexCombPair, sConvexComb_eq_sum, Finsupp.sum_add_index, add_smul] lemma IsAffineMap.map_sum_weights (hf : IsAffineMap R f) (w : StdSimplex R I) (g : I → M) : - f (w.weights.sum fun i r ↦ r • g i) = w.weights.sum fun i r ↦ r • f (g i) := by + f (w.weights.sum fun i r ↦ r • g i) = w.weights.sum fun i r ↦ r • f (g i) := by simpa using hf.map_iConvexComb w g lemma IsAffineMap.map_smul_add_smul (hf : IsAffineMap R f) (ha : 0 ≤ a) (hb : 0 ≤ b) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 740d390849c3eb..021464573225ca 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -33,7 +33,7 @@ metric `g` if and only if the differentiated metric tensor `∇ g` (defined by ## TODO * When Mathlib has a notion of parallel transport, prove the equivalence of - `CovariantDerivative.IsMetricCompatible` with the characterisation that parallel transport be an + `CovariantDerivative.IsMetricCompatible` with the characterisation that parallel transport be an isometry. * Given connections on bundles `V` and `W`, there is an induced connnection on the bundle diff --git a/Mathlib/GroupTheory/FiniteAbelian/Duality.lean b/Mathlib/GroupTheory/FiniteAbelian/Duality.lean index 567965b42e562e..cb0f5de5185b7b 100644 --- a/Mathlib/GroupTheory/FiniteAbelian/Duality.lean +++ b/Mathlib/GroupTheory/FiniteAbelian/Duality.lean @@ -70,7 +70,7 @@ theorem exists_apply_ne_one_of_hasEnoughRootsOfUnity {a : G} (ha : a ≠ 1) : variable {M} in @[simp] - theorem forall_apply_eq_apply_iff {g g' : G} : +theorem forall_apply_eq_apply_iff {g g' : G} : (∀ φ : G →* Mˣ, φ g = φ g') ↔ g = g' := by refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩ simpa [← not_forall, not_imp_not, mul_inv_eq_one, h] using diff --git a/Mathlib/GroupTheory/RegularWreathProduct.lean b/Mathlib/GroupTheory/RegularWreathProduct.lean index b82ac380fbfac4..593c7448dd641f 100644 --- a/Mathlib/GroupTheory/RegularWreathProduct.lean +++ b/Mathlib/GroupTheory/RegularWreathProduct.lean @@ -213,9 +213,9 @@ theorem IteratedWreathProduct.card [Finite G] : Nat.card (IteratedWreathProduct variable [Group G] instance : Group (IteratedWreathProduct G n) := by - induction n with - | zero => rw [IteratedWreathProduct_zero]; infer_instance - | succ n ih => rw [IteratedWreathProduct_succ]; infer_instance + induction n with + | zero => rw [IteratedWreathProduct_zero]; infer_instance + | succ n ih => rw [IteratedWreathProduct_succ]; infer_instance /-- The homomorphism from `IteratedWreathProduct G n` to `Perm (Fin n → G)`. -/ def iteratedWreathToPermHom (G : Type*) [Group G] : diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean index 06333463c6095b..f140de24f68cb0 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean @@ -260,7 +260,7 @@ theorem isCoatom_stabilizer_of_ncard_lt_ncard_compl {s : Set α} IsBlock.subsingleton_of_ssubset_compl_of_stabilizer_alternatingGroup_le h0 (hBsc.ssubset_of_ne (by aesop)) -- uses Step 1 hG.le hB - -- Step 3 : A block contained in `s` is a subsingleton + -- Step 3 : A block contained in `s` is a subsingleton have hB_not_le_s (B : Set α) (hB : IsBlock G B) (hBs : B ⊆ s) : B.Subsingleton := have : IsPreprimitive (stabilizer G s) s := diff --git a/Mathlib/LinearAlgebra/Matrix/ZMatrix.lean b/Mathlib/LinearAlgebra/Matrix/ZMatrix.lean index 6fa0a0046618da..ce22815bdb65b3 100644 --- a/Mathlib/LinearAlgebra/Matrix/ZMatrix.lean +++ b/Mathlib/LinearAlgebra/Matrix/ZMatrix.lean @@ -16,8 +16,8 @@ A matrix whose off-diagonal entries are all non-positive is known as a Z-matrix. are examples of Z-matrices. ## Main results: - * `Matrix.lt_two_mul_of_mul_diagonal_posDef_of_for_le_of_hasEigen`: a spectral bound result for - Z-matrices satisfying a positive-definiteness condition. +* `Matrix.lt_two_mul_of_mul_diagonal_posDef_of_for_le_of_hasEigen`: a spectral bound result for + Z-matrices satisfying a positive-definiteness condition. -/ diff --git a/Mathlib/LinearAlgebra/Reflection.lean b/Mathlib/LinearAlgebra/Reflection.lean index f79b24d5238189..e466bd0d0c813c 100644 --- a/Mathlib/LinearAlgebra/Reflection.lean +++ b/Mathlib/LinearAlgebra/Reflection.lean @@ -21,8 +21,8 @@ public import Mathlib.Tactic.Module Given an element `x` in a module `M` together with a linear form `f` on `M` such that `f x = 2`, the map `y ↦ y - (f y) • x` is an involutive endomorphism of `M`, such that: - 1. the kernel of `f` is fixed, - 2. the point `x` maps to `-x`. +1. the kernel of `f` is fixed, +2. the point `x` maps to `-x`. Such endomorphisms are often called reflections of the module `M`. When `M` carries an inner product for which `x` is perpendicular to the kernel of `f`, then (with mild assumptions) the endomorphism diff --git a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean index d367432da18e79..45bc346053560a 100644 --- a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean +++ b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean @@ -17,19 +17,19 @@ public import Mathlib.LinearAlgebra.RootSystem.Finite.Lemmas # Existence of bases for crystallographic root systems ## Main results: - * `RootPairing.Base.mk'`: an alternate constructor for `RootPairing.Base` which demands the axioms - for roots but not for coroots. - * `RootPairing.nonempty_base`: base existence proof for reduced crystallographic root systems. +* `RootPairing.Base.mk'`: an alternate constructor for `RootPairing.Base` which demands the axioms + for roots but not for coroots. +* `RootPairing.nonempty_base`: base existence proof for reduced crystallographic root systems. ## Implementation details The proof needs a set of ordered coefficients, even though the ultimate existence statement does not. There are at least two ways to deal with this: - (a) Using the fact that a crystallographic root system induces a `ℚ`-structure, pass to the root - system over `ℚ` defined by `RootPairing.restrictScalarsRat`, and develop a theory of base - change for root system bases. - (b) Introduce a second set of ordered coefficients (ultimately taken to be `ℚ`) and develop a - theory with two sets of coefficients simultaneously in play. +(a) Using the fact that a crystallographic root system induces a `ℚ`-structure, pass to the root + system over `ℚ` defined by `RootPairing.restrictScalarsRat`, and develop a theory of base + change for root system bases. +(b) Introduce a second set of ordered coefficients (ultimately taken to be `ℚ`) and develop a + theory with two sets of coefficients simultaneously in play. It is not really clear which is the better approach but here we opt for approach (b) as it seems to yield slightly more general results. diff --git a/Mathlib/LinearAlgebra/Semisimple.lean b/Mathlib/LinearAlgebra/Semisimple.lean index 6109d9ea4dda88..120bc5cbeda127 100644 --- a/Mathlib/LinearAlgebra/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Semisimple.lean @@ -17,8 +17,8 @@ public import Mathlib.RingTheory.SimpleModule.Basic Given an `R`-module `M` together with an `R`-linear endomorphism `f : M → M`, the following two conditions are equivalent: - 1. Every `f`-invariant submodule of `M` has an `f`-invariant complement. - 2. `M` is a semisimple `R[X]`-module, where the action of the polynomial ring is induced by `f`. +1. Every `f`-invariant submodule of `M` has an `f`-invariant complement. +2. `M` is a semisimple `R[X]`-module, where the action of the polynomial ring is induced by `f`. A linear endomorphism `f` satisfying these equivalent conditions is known as a *semisimple* endomorphism. We provide basic definitions and results about such endomorphisms in this file. diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean index f33dd9c3dc6795..ef30b4946bc384 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean @@ -374,7 +374,7 @@ theorem Measurable.nnreal_tsum {ι} [Countable ι] {f : ι → α → ℝ≥0} ( @[fun_prop, deprecated "Use `AEMeasurable.tsum` from `Mathlib.MeasureTheory.Constructions.Polish.Basic` instead" - (since := "2026-04-30")] + (since := "2026-04-30")] theorem AEMeasurable.ennreal_tsum {ι} [Countable ι] {f : ι → α → ℝ≥0∞} {μ : Measure α} (h : ∀ i, AEMeasurable (f i) μ) : AEMeasurable (fun x => ∑' i, f i x) μ := by simp_rw [ENNReal.tsum_eq_iSup_sum] diff --git a/Mathlib/NumberTheory/SelbergSieve.lean b/Mathlib/NumberTheory/SelbergSieve.lean index 316cf8e7ddb7c0..af6311cc74e0c1 100644 --- a/Mathlib/NumberTheory/SelbergSieve.lean +++ b/Mathlib/NumberTheory/SelbergSieve.lean @@ -23,8 +23,8 @@ minor notational difference is that we write $\nu(n)$ in place of $\frac{\omega( ## Results * `siftedSum_le_mainSum_errSum_of_UpperBoundSieve` - Every upper bound sieve gives an upper bound on the size of the sifted set in terms of `mainSum` and `errSum` - * `upperMoebius_of_lambda_sq` - Lambda squared weights produce upper bound sieves - * `lambdaSquared_mainSum_eq_diag_quad_form` - The main sum of a Λ² sieve has a nice diagonalisation +* `upperMoebius_of_lambda_sq` - Lambda squared weights produce upper bound sieves +* `lambdaSquared_mainSum_eq_diag_quad_form` - The main sum of a Λ² sieve has a nice diagonalisation ## References diff --git a/Mathlib/Order/Types/Defs.lean b/Mathlib/Order/Types/Defs.lean index 82c08e974b1ee4..f0e7316273439b 100644 --- a/Mathlib/Order/Types/Defs.lean +++ b/Mathlib/Order/Types/Defs.lean @@ -270,10 +270,10 @@ theorem lift_type_eq_iff : lift (type α) = lift (type β) ↔ Nonempty (α ≃o exact ⟨(ULift.orderIso.symm.trans h.some).trans ULift.orderIso⟩ theorem lift_type_le_iff : lift (type α) ≤ lift (type β) ↔ Nonempty (α ↪o β) := by - refine ⟨fun h ↦ ?_, fun ⟨h⟩ ↦ type_le_type <| (ULift.orderIso.toOrderEmbedding.trans h).trans - ULift.orderIso.symm.toOrderEmbedding⟩ - rw [← type_ulift, ← type_ulift, type_le_type_iff] at h - exact ⟨(ULift.orderIso.symm.toOrderEmbedding.trans h.some).trans ULift.orderIso.toOrderEmbedding⟩ + refine ⟨fun h ↦ ?_, fun ⟨h⟩ ↦ type_le_type <| (ULift.orderIso.toOrderEmbedding.trans h).trans + ULift.orderIso.symm.toOrderEmbedding⟩ + rw [← type_ulift, ← type_ulift, type_le_type_iff] at h + exact ⟨(ULift.orderIso.symm.toOrderEmbedding.trans h.some).trans ULift.orderIso.toOrderEmbedding⟩ /-- `ω` is the first infinite order type, defined as the order type of `ℕ`. -/ @[expose] diff --git a/Mathlib/Order/UpperLower/CompleteLattice.lean b/Mathlib/Order/UpperLower/CompleteLattice.lean index f24575b9fefe00..5d6cd1de5de14d 100644 --- a/Mathlib/Order/UpperLower/CompleteLattice.lean +++ b/Mathlib/Order/UpperLower/CompleteLattice.lean @@ -337,7 +337,7 @@ def map (f : α ≃o β) : UpperSet α ≃o UpperSet β where @[to_dual (attr := simp)] theorem symm_map (f : α ≃o β) : (map f).symm = map f.symm := by - ext; simp [map, OrderIso.symm_apply_eq] + ext; simp [map, OrderIso.symm_apply_eq] @[to_dual (attr := simp)] theorem mem_map : b ∈ map f s ↔ f.symm b ∈ s := by diff --git a/Mathlib/RepresentationTheory/Homological/Resolution.lean b/Mathlib/RepresentationTheory/Homological/Resolution.lean index e21a60eb83e1c0..ec47f3ab77cab3 100644 --- a/Mathlib/RepresentationTheory/Homological/Resolution.lean +++ b/Mathlib/RepresentationTheory/Homological/Resolution.lean @@ -54,10 +54,10 @@ computing group (co)homology. ## Main definitions - * `groupCohomology.resolution.ofMulActionBasis` - * `classifyingSpaceUniversalCover` - * `Rep.standardComplex.forget₂ToModuleCatHomotopyEquiv` - * `Rep.standardResolution` +* `groupCohomology.resolution.ofMulActionBasis` +* `classifyingSpaceUniversalCover` +* `Rep.standardComplex.forget₂ToModuleCatHomotopyEquiv` +* `Rep.standardResolution` TODO: There's bad DefEq abuses in `Action` and the way we do `Rep.standardComplex` should be unified with continuous cohomology, therefore we should remove the use of `Action` in `Rep` which diff --git a/Mathlib/RingTheory/FractionalIdeal/Basic.lean b/Mathlib/RingTheory/FractionalIdeal/Basic.lean index 6b00bb74fdf3a6..25256416bf34ef 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Basic.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Basic.lean @@ -184,7 +184,7 @@ theorem ext {I J : FractionalIdeal S P} : (∀ x, x ∈ I ↔ x ∈ J) → I = J SetLike.ext @[simp] - theorem equivNum_apply [IsDomain R] [Module.IsTorsionFree R P] [Nontrivial P] +theorem equivNum_apply [IsDomain R] [Module.IsTorsionFree R P] [Nontrivial P] {I : FractionalIdeal S P} (h_nz : (I.den : R) ≠ 0) (x : I) : algebraMap R P (equivNum h_nz x) = I.den • x := by change Algebra.linearMap R P _ = _ diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index 85f81da838dd3c..bd60b3fdb3bbeb 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -166,13 +166,13 @@ end map section variable {R S : Type*} [CommSemiring R] [CommSemiring S] [Algebra R S] - {M₁ M₂ M₃ M₁₂ M₂₃ : Type*} [AddCommMonoid M₁] [AddCommMonoid M₂] [AddCommMonoid M₃] - [AddCommMonoid M₁₂] [AddCommMonoid M₂₃] - [Module R M₁] - [Module R M₂] [Module S M₂] [IsScalarTower R S M₂] - [Module R M₃] [Module S M₃] [IsScalarTower R S M₃] - [Module R M₁₂] [Module S M₁₂] [IsScalarTower R S M₁₂] - [Module R M₂₃] [Module S M₂₃] [IsScalarTower R S M₂₃] + {M₁ M₂ M₃ M₁₂ M₂₃ : Type*} [AddCommMonoid M₁] [AddCommMonoid M₂] [AddCommMonoid M₃] + [AddCommMonoid M₁₂] [AddCommMonoid M₂₃] + [Module R M₁] + [Module R M₂] [Module S M₂] [IsScalarTower R S M₂] + [Module R M₃] [Module S M₃] [IsScalarTower R S M₃] + [Module R M₁₂] [Module S M₁₂] [IsScalarTower R S M₁₂] + [Module R M₂₃] [Module S M₂₃] [IsScalarTower R S M₂₃] set_option backward.defeqAttrib.useBackward true in /-- (Implementation): Use the more linear `IsTensorProduct.assoc`. -/ diff --git a/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean b/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean index f168d029b3da06..29fed9bd750345 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean @@ -18,7 +18,7 @@ public import Mathlib.RingTheory.Valuation.Discrete.IsDiscreteValuationRing # Order of vanishing in Noetherian rings. In this file we define various properties of the order of vanishing in Noetherian rings, including - some API for computing the order of vanishing in discrete valuation rings. +some API for computing the order of vanishing in discrete valuation rings. -/ @[expose] public section diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean index aa330d8e13e4ea..05e37ed8dd0363 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean @@ -656,7 +656,7 @@ theorem separable_cyclotomic (n : ℕ) (K : Type*) [Field K] [NeZero (n : K)] : theorem squarefree_cyclotomic (n : ℕ) (K : Type*) [Field K] [NeZero (n : K)] : Squarefree (cyclotomic n K) := - (separable_cyclotomic n K).squarefree + (separable_cyclotomic n K).squarefree end miscellaneous diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index 638cb205531b08..196a24afa6a3cd 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -432,7 +432,7 @@ and `S` that appear are comparable, in the sense that either `R` is an `S`-algeb * `algebra with R` uses the term `R` as the scalar ring, instead of attempting to infer it automatically. - -/ +-/ elab (name := algebra) "algebra":tactic => withMainContext do liftMetaTactic1 (transformAtTarget (fun e _ ↦ preprocess e) "algebra" .silent · default) diff --git a/Mathlib/Tactic/ComputeDegree.lean b/Mathlib/Tactic/ComputeDegree.lean index aad91fcb2100ef..ef76af3b313f88 100644 --- a/Mathlib/Tactic/ComputeDegree.lean +++ b/Mathlib/Tactic/ComputeDegree.lean @@ -530,7 +530,7 @@ end Tactic end Mathlib.Tactic.ComputeDegree /-! - We register `compute_degree` with the `hint` tactic. - -/ +We register `compute_degree` with the `hint` tactic. +-/ register_hint 1000 compute_degree register_try?_tactic (priority := 1000) compute_degree diff --git a/Mathlib/Tactic/FieldSimp.lean b/Mathlib/Tactic/FieldSimp.lean index 70cc8bae5385bb..9ca4f39b9d0c0a 100644 --- a/Mathlib/Tactic/FieldSimp.lean +++ b/Mathlib/Tactic/FieldSimp.lean @@ -799,7 +799,7 @@ simproc_decl fieldLt (LT.lt _ _) := FieldSimp.proc attribute [field, inherit_doc FieldSimp.proc] fieldEq fieldLe fieldLt /-! - We register `field_simp` with the `hint` tactic. - -/ +We register `field_simp` with the `hint` tactic. +-/ register_hint 1000 field_simp register_try?_tactic (priority := 1000) field_simp diff --git a/Mathlib/Tactic/FieldSimp/Attr.lean b/Mathlib/Tactic/FieldSimp/Attr.lean index b43d38f171c369..a8d460480067d9 100644 --- a/Mathlib/Tactic/FieldSimp/Attr.lean +++ b/Mathlib/Tactic/FieldSimp/Attr.lean @@ -15,5 +15,5 @@ open Lean Meta /-- Initialize the attribute `field` grouping the simprocs associated to the `field_simp` tactic. -/ initialize fieldSimpExt : Simp.SimprocExtension - ← Simp.registerSimprocAttr `field + ← Simp.registerSimprocAttr `field "Attribute grouping the simprocs associated to the field_simp tactic" none diff --git a/Mathlib/Tactic/Finiteness.lean b/Mathlib/Tactic/Finiteness.lean index 73551303bf70ec..40cc18f28f2c71 100644 --- a/Mathlib/Tactic/Finiteness.lean +++ b/Mathlib/Tactic/Finiteness.lean @@ -111,7 +111,7 @@ macro_rules `(tactic| · ($[have := $h];*); finiteness_nonterminal $c*) /-! - We register `finiteness` with the `hint` tactic. - -/ +We register `finiteness` with the `hint` tactic. +-/ register_hint 1000 finiteness register_try?_tactic (priority := 1000) finiteness diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 4ae75b243cbdca..2688f4e152a0d6 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -40,7 +40,7 @@ In the case of `to_additive`, we may want to apply it multiple times, (such as in `a ^ n` -> `n • a` -> `n +ᵥ a`). In this case, you should use the syntax `to_additive (attr := some_other_attr, to_additive)`, which will apply `some_other_attr` to all three generated declarations. - -/ +-/ syntax attrOption := &"attr" " := " Parser.Term.attrInstance,* syntax reorderOption := &"reorder" " := " translateReorder diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Field.lean b/Mathlib/Topology/Algebra/InfiniteSum/Field.lean index a053651031525a..67cf433b713286 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Field.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Field.lean @@ -22,7 +22,7 @@ public section section NormMulClass variable {α E : Type*} [SeminormedCommRing E] [NormMulClass E] [NormOneClass E] - {f : α → E} {x : E} + {f : α → E} {x : E} nonrec theorem HasProd.norm (hfx : HasProd f x) : HasProd (‖f ·‖) ‖x‖ := by simp only [HasProd, ← norm_prod] diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean index a00d7c6846f480..ac1b694b34f284 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean @@ -287,8 +287,8 @@ instance Subgroup.isClosed_of_discrete [T2Space G] {H : Subgroup G} [DiscreteTop @[to_additive] lemma Subgroup.tendsto_coe_cofinite_of_discrete [T2Space G] (H : Subgroup G) (hH : IsDiscrete (H : Set G)) : Tendsto ((↑) : H → G) cofinite (cocompact _) := - haveI : DiscreteTopology H := isDiscrete_iff_discreteTopology.mp hH - IsClosed.tendsto_coe_cofinite_of_isDiscrete isClosed_of_discrete hH + haveI : DiscreteTopology H := isDiscrete_iff_discreteTopology.mp hH + IsClosed.tendsto_coe_cofinite_of_isDiscrete isClosed_of_discrete hH @[to_additive] lemma MonoidHom.tendsto_coe_cofinite_of_discrete [T2Space G] {H : Type*} [Group H] {f : H →* G} diff --git a/Mathlib/Topology/EMetricSpace/Defs.lean b/Mathlib/Topology/EMetricSpace/Defs.lean index 44fa6e9c5e5d8f..b9dbd634ed6d89 100644 --- a/Mathlib/Topology/EMetricSpace/Defs.lean +++ b/Mathlib/Topology/EMetricSpace/Defs.lean @@ -181,7 +181,7 @@ theorem mem_uniformity_edist {s : Set (α × α)} : /-- Make a `PseudoEMetricSpace` from a metric. Warning: the uniformity and topology included herein are the ones generated by the metric. If the type has a pre-existing topology or uniformity, `PseudoEMetricSpace.ofEDistOfTopology` should be used instead. -/ - noncomputable abbrev PseudoEMetricSpace.ofEDist +noncomputable abbrev PseudoEMetricSpace.ofEDist {α : Type u} (edist : α → α → ℝ≥0∞) (edist_self : ∀ x : α, edist x x = 0) (edist_comm : ∀ x y : α, edist x y = edist y x) (edist_triangle : ∀ x y z : α, edist x z ≤ edist x y + edist y z) : PseudoEMetricSpace α where diff --git a/Mathlib/Topology/IndicatorConstPointwise.lean b/Mathlib/Topology/IndicatorConstPointwise.lean index df11b94be10a5e..cb3c518d5e5009 100644 --- a/Mathlib/Topology/IndicatorConstPointwise.lean +++ b/Mathlib/Topology/IndicatorConstPointwise.lean @@ -19,11 +19,11 @@ functions of sets converge pointwise. For `A` a set, `(Asᵢ)` an indexed collection of sets, under mild conditions, the following are equivalent: - (a) the indicator functions of `Asᵢ` tend to the indicator function of `A` pointwise; +(a) the indicator functions of `Asᵢ` tend to the indicator function of `A` pointwise; - (b) for every `x`, we eventually have that `x ∈ Asᵢ` holds iff `x ∈ A` holds; +(b) for every `x`, we eventually have that `x ∈ Asᵢ` holds iff `x ∈ A` holds; - (c) `Tendsto As _ <| Filter.pi (pure <| · ∈ A)`. +(c) `Tendsto As _ <| Filter.pi (pure <| · ∈ A)`. The results stating these in the case when the indicators take values in a Fréchet space are: * `tendsto_indicator_const_iff_forall_eventually` is the equivalence (a) ↔ (b); diff --git a/Mathlib/Topology/Sion.lean b/Mathlib/Topology/Sion.lean index 9344fd6db31c1a..4b16ccbc13a746 100644 --- a/Mathlib/Topology/Sion.lean +++ b/Mathlib/Topology/Sion.lean @@ -143,7 +143,7 @@ theorem sublevelLeft_subset_union [AddCommGroup F] [Module ℝ F] The hypotheses imply that `sublevelLeft X f b z` is connected, and that the two other are disjoint. -/ - theorem sublevelLeft_subset_or [TopologicalSpace E] [AddCommGroup E] +theorem sublevelLeft_subset_or [TopologicalSpace E] [AddCommGroup E] [IsTopologicalAddGroup E] [Module ℝ E] [ContinuousSMul ℝ E] [AddCommGroup F] [Module ℝ F] (hfx' : ∀ x ∈ X, QuasiconcaveOn ℝ Y fun y => f x y) diff --git a/MathlibTest/MkIffOfInductive.lean b/MathlibTest/MkIffOfInductive.lean index d0a602924fa8de..cd958cdc29656d 100644 --- a/MathlibTest/MkIffOfInductive.lean +++ b/MathlibTest/MkIffOfInductive.lean @@ -79,4 +79,4 @@ inductive ReflTransGen {α : Type _} (r : α → α → Prop) (a : α) : α → example {α : Type} (r : α → α → Prop) (a c : α) : ReflTransGen r a c ↔ c = a ∨ ∃ b : α, ReflTransGen r a b ∧ r b c := - reflTransGen_iff r a c + reflTransGen_iff r a c diff --git a/MathlibTest/Tactic/NormNum/Basic.lean b/MathlibTest/Tactic/NormNum/Basic.lean index 91681f9558d95f..f46bd5b3073eb4 100644 --- a/MathlibTest/Tactic/NormNum/Basic.lean +++ b/MathlibTest/Tactic/NormNum/Basic.lean @@ -710,7 +710,7 @@ example : - ((94 * 89) + (79 - (23 - (((- 1 / 55) + 95) * (28 - (54 / - - - 22)) example : (- 23 + 61) = (38 : α) := by norm_num1 example : - (93 / 69) = (-31/23 : α) := by norm_num1 example : (- - ((68 / (39 + (((45 * - (59 - (37 + 35))) / (53 - 75)) - - - (100 + - (50 / (- 30 - 59)))))) - (69 - (23 * 30))) / (57 + 17)) = (137496481/16368578 : α) := by + - (100 + - (50 / (- 30 - 59)))))) - (69 - (23 * 30))) / (57 + 17)) = (137496481/16368578 : α) := by norm_num1 example : (- 19 * - - (75 * - - 41)) = (-58425 : α) := by norm_num1 example : ((3 / ((- 28 * 45) * (19 + ((- (- 88 - (- (- 1 + 90) + 8)) + 87) * 48)))) + 1) = From ac8265fa30446510cd710fc7a6a9594ff049d1a9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:38:56 +0000 Subject: [PATCH 0575/1300] chore: add `.git-blame-ignore-revs` file (#41023) These revisions are ignored when doing git blame, providing more helpful output. We populate it with the commits corresponding to - #31786 (move to the module system), - #13166 and #13059 (replacing `refine'` by `refine`). This list is not exhaustive; further commits can be added later. --- .git-blame-ignore-revs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000000000..6275ba74ef0ab9 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,6 @@ +# 2024-05-20 replace `refine'` with one underscore by `refine` (#13059) +7493b5f81b4c031b87877c5c124bea1ddc4e567d +# 2024-05-24 replace many `refine'` with `refine` (#13166) +fc48848e4374f13c796a7399bfccd2e228f776df +# 2025-11-19 move Mathlib to the module system (#31786) +6a54a80825b060ab20dc31751ebdce78b3a3b518 From f7a05ed9e646c42461432e410222a9afcb35534c Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:38:58 +0000 Subject: [PATCH 0576/1300] feat(CategoryTheory/Preadditive/FreydCategory/RightFreyd): right Freyd category of a preadditive category (#41294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the right Freyd category of a preadditive category `V` as the quotient of `Arrow V` by the right homotopy relation, as well as a fully faithful additive functor `V ⥤ RightFreyd V` (when `V` has a zero object). TODO: If `V` has binary biproduct, then `RightFreyd V` has cokernels. Co-authored-by: morel --- Mathlib.lean | 1 + .../Preadditive/FreydCategory/RightFreyd.lean | 140 ++++++++++++++++++ docs/references.bib | 15 ++ 3 files changed, 156 insertions(+) create mode 100644 Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean diff --git a/Mathlib.lean b/Mathlib.lean index 022c89560e0dbd..b84b3d08209ed8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3244,6 +3244,7 @@ public import Mathlib.CategoryTheory.Preadditive.Comma public import Mathlib.CategoryTheory.Preadditive.EilenbergMoore public import Mathlib.CategoryTheory.Preadditive.EndoFunctor public import Mathlib.CategoryTheory.Preadditive.FreydCategory.Homotopy +public import Mathlib.CategoryTheory.Preadditive.FreydCategory.RightFreyd public import Mathlib.CategoryTheory.Preadditive.FunctorCategory public import Mathlib.CategoryTheory.Preadditive.HomOrthogonal public import Mathlib.CategoryTheory.Preadditive.Indization diff --git a/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean b/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean new file mode 100644 index 00000000000000..b26f77866360c1 --- /dev/null +++ b/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean @@ -0,0 +1,140 @@ +/- +Copyright (c) 2026 Sophie Morel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sophie Morel +-/ +module + +public import Mathlib.CategoryTheory.Preadditive.FreydCategory.Homotopy +public import Mathlib.CategoryTheory.Quotient.Preadditive + +/-! +# The right Freyd category + +Let `V` be a preadditive category. The right Freyd category of `V` is the quotient of +`Arrow V` by the right homotopy relation. (This is simply called "Freyd category" +in the reference.) + + +## References +* [Posur, S., *A constructive approach to Freyd categories*][posur2021Freyd] + +-/ + +@[expose] public section + +noncomputable section + +open CategoryTheory Category Limits Arrow + +variable (V : Type*) [Category* V] [Preadditive V] + +namespace CategoryTheory.Preadditive + +/-- If `V` is a preadditive category, then `RightFreyd V` is the category of arrows in `V`, +with morphisms identified when they are right homotopic. -/ +def RightFreyd := + CategoryTheory.Quotient (rightHomotopic V) + +instance : Category (RightFreyd V) := + inferInstanceAs <| Category (CategoryTheory.Quotient (rightHomotopic V)) + +/-- The category `RightFreyd V` is preadditive. -/ +instance : Preadditive (RightFreyd V) := + Quotient.preadditive _ (by + rintro _ _ _ _ _ _ ⟨h⟩ ⟨h'⟩ + exact ⟨RightHomotopy.add h h'⟩) + +namespace RightFreyd + +/-- The quotient functor from `Arrow V` to `RightFreyd V`. -/ +def quotient : Arrow V ⥤ RightFreyd V := + CategoryTheory.Quotient.functor _ + +instance : (quotient V).Full := Quotient.full_functor _ + +instance : (quotient V).EssSurj := Quotient.essSurj_functor _ + +instance : (quotient V).Additive where + +variable {V} + +/-- If two morphisms in `Arrow V` are right homotopic, then they become equal in the right +Freyd category. -/ +theorem eq_of_rightHomotopy {u v : Arrow V} (f g : u ⟶ v) (h : RightHomotopy f g) : + (quotient V).map f = (quotient V).map g := + CategoryTheory.Quotient.sound _ ⟨h⟩ + +/-- If two morphisms of `Arrow V` become equal in the right Freyd category, +then they are right homotopic. -/ +def homotopyOfEq {u v : Arrow V} (f g : u ⟶ v) + (w : (quotient V).map f = (quotient V).map g) : RightHomotopy f g := + ((Quotient.functor_map_eq_iff _ _ _).mp w).some + +variable {u v : Arrow V} (f g : u ⟶ v) + +/-- Two morphisms in `Arrow V` have the same image in `RightFreyd V` if and only if there +exists a right homotopy between them. -/ +lemma quotient_map_eq_iff : + (quotient V).map f = (quotient V).map g ↔ Nonempty (RightHomotopy f g) := + ⟨fun h ↦ ⟨homotopyOfEq _ _ (by simpa using h)⟩, + fun ⟨h⟩ ↦ by simpa using eq_of_rightHomotopy _ _ h⟩ + +/-- A morphism `f` in `Arrow V` is sent to `0` in `RightFreyd V` if and only if there +exists a right homotopy between `f` and `0`. -/ +lemma quotient_map_eq_zero_iff : (quotient V).map f = 0 ↔ Nonempty (RightHomotopy f 0) := + ⟨fun h ↦ ⟨homotopyOfEq _ _ (by simpa using h)⟩, + fun ⟨h⟩ ↦ by simpa using eq_of_rightHomotopy _ _ h⟩ + +/-- If `f` is a morphism of `Arrow V` such that `f.right` is an isomorphism, then the image of `f` +in the right Freyd category is an epimorphism. -/ +lemma epi_of_isIso_right [IsIso f.right] : Epi ((quotient V).map f) where + left_cancellation g₁ g₂ eq := by + obtain ⟨g₁, rfl⟩ := (quotient V).map_surjective g₁ + obtain ⟨g₂, rfl⟩ := (quotient V).map_surjective g₂ + set h : RightHomotopy (f ≫ g₁) (f ≫ g₂) := homotopyOfEq _ _ eq + exact eq_of_rightHomotopy _ _ ⟨inv f.right ≫ h.hom, by simp [dsimp% h.comm]⟩ + +section Functor + +variable [HasZeroObject V] + +variable (V) + +open ZeroObject in +set_option backward.defeqAttrib.useBackward true in +/-- If `V` has a zero object, this is the functor from `V` to `Arrow V` +that sends an object `X` to the arrow `0 ⟶ X`. -/ +@[simps] +def rightFunctor : V ⥤ Arrow V where + obj X := Arrow.mk (0 : 0 ⟶ X) + map f := Arrow.homMk 0 f + +set_option backward.defeqAttrib.useBackward true in +instance : (rightFunctor V).Additive where + map_add {_ _ _ _} := by cat_disch + +/-- The fully faithful additive functor from `V` to `RightFreyd V` sending an object `X` of `V` +to the class of the arrow `0 ⟶ X`. -/ +abbrev functor : V ⥤ RightFreyd V := rightFunctor V ⋙ quotient V + +instance : (functor V).Additive := by dsimp [functor]; infer_instance + +set_option backward.defeqAttrib.useBackward true in +instance : (functor V).Full where + map_surjective a := by + obtain ⟨u, rfl⟩ := (quotient V).map_surjective a + exact ⟨u.right, (quotient V).congr_map (by cat_disch)⟩ + +set_option backward.defeqAttrib.useBackward true in +instance : (functor V).Faithful where + map_injective {_ _} f g eq := by + dsimp at eq + rw [quotient_map_eq_iff] at eq + simpa [← sub_eq_zero] using! eq.some.comm + +end Functor + +end RightFreyd + +end CategoryTheory.Preadditive diff --git a/docs/references.bib b/docs/references.bib index 7f24a1fbf66c1a..9f5c0923881aa0 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -4790,6 +4790,21 @@ @Misc{ ponton2020chebyshev primaryclass = {math.NT} } +@Article{ posur2021Freyd, + author = {Posur, Sebastian}, + title = {A constructive approach to {Freyd} categories}, + fjournal = {Applied Categorical Structures}, + journal = {Appl. Categ. Struct.}, + issn = {0927-2852}, + volume = {29}, + number = {1}, + pages = {171--211}, + year = {2021}, + keywords = {18E10,18E05,18A25,16S99,18C35}, + zbmath = {7363561}, + zbl = {1478.18008} +} + @Article{ Prielipp1970, author = {Robert W. Prielipp}, title = {PERFECT NUMBERS, ABUNDANT NUMBERS, AND DEFICIENT NUMBERS}, From ec4870d29594705b9f29cf7197fb105fc2356788 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:39:01 +0000 Subject: [PATCH 0577/1300] chore: golf proofs with `grw` (#41307) This PR golfs some proofs with `grw`, by making use of strict rewriting. This is not exhaustive. I just picked some proofs that could be golfed, to show what can be done with `grw` now. --- Mathlib/Algebra/Order/CauSeq/Basic.lean | 19 +++++++------------ Mathlib/Algebra/Polynomial/Mirror.lean | 2 +- .../GeneratorsRelations/NormalForms.lean | 4 ++-- Mathlib/Analysis/Convolution.lean | 4 ++-- .../MeasureTheory/Covering/Besicovitch.lean | 6 +----- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 6 ++---- Mathlib/SetTheory/Ordinal/Exponential.lean | 3 +-- Mathlib/SetTheory/Ordinal/Notation.lean | 7 +++---- 8 files changed, 19 insertions(+), 32 deletions(-) diff --git a/Mathlib/Algebra/Order/CauSeq/Basic.lean b/Mathlib/Algebra/Order/CauSeq/Basic.lean index c3f8165c29f6db..21c801e49935a3 100644 --- a/Mathlib/Algebra/Order/CauSeq/Basic.lean +++ b/Mathlib/Algebra/Order/CauSeq/Basic.lean @@ -50,8 +50,7 @@ theorem rat_add_continuous_lemma {ε : α} (ε0 : 0 < ε) : ∃ δ > 0, ∀ {a₁ a₂ b₁ b₂ : β}, abv (a₁ - b₁) < δ → abv (a₂ - b₂) < δ → abv (a₁ + a₂ - (b₁ + b₂)) < ε := ⟨ε / 2, half_pos ε0, fun {a₁ a₂ b₁ b₂} h₁ h₂ => by - simpa [add_halves, sub_eq_add_neg, add_comm, add_left_comm, add_assoc] using - lt_of_le_of_lt (abv_add abv _ _) (add_lt_add h₁ h₂)⟩ + grw [add_sub_add_comm, abv_add abv, h₁, h₂, add_halves]⟩ theorem rat_mul_continuous_lemma {ε K₁ K₂ : α} (ε0 : 0 < ε) : ∃ δ > 0, ∀ {a₁ a₂ b₁ b₂ : β}, abv a₁ < K₁ → abv b₂ < K₂ → abv (a₁ - b₁) < δ → @@ -62,11 +61,10 @@ theorem rat_mul_continuous_lemma {ε K₁ K₂ : α} (ε0 : 0 < ε) : replace ha₁ := lt_of_lt_of_le ha₁ (le_trans (le_max_left _ K₂) (le_max_right 1 _)) replace hb₂ := lt_of_lt_of_le hb₂ (le_trans (le_max_right K₁ _) (le_max_right 1 _)) set M := max 1 (max K₁ K₂) - have : abv (a₁ - b₁) * abv b₂ + abv (a₂ - b₂) * abv a₁ < ε / 2 / M * M + ε / 2 / M * M := by - gcongr - rw [← abv_mul abv, mul_comm, div_mul_cancel₀ _ (ne_of_gt K0), ← abv_mul abv, add_halves] at this - simpa [sub_eq_add_neg, mul_add, add_mul, add_left_comm] using - lt_of_le_of_lt (abv_add abv _ _) this + suffices abv ((a₁ - b₁) * b₂ + a₁ * (a₂ - b₂)) < ε by + simpa [sub_eq_add_neg, mul_add, add_mul, add_left_comm] using this + grw [abv_add abv, abv_mul abv, abv_mul abv, h₁.le, h₂.le, ha₁, hb₂, mul_comm M, + div_mul_cancel₀ _ (ne_of_gt K0), add_halves] theorem rat_inv_continuous_lemma {β : Type*} [DivisionRing β] (abv : β → α) [IsAbsoluteValue abv] {ε K : α} (ε0 : 0 < ε) (K0 : 0 < K) : @@ -76,11 +74,8 @@ theorem rat_inv_continuous_lemma {β : Type*} [DivisionRing β] (abv : β → α have b0 := K0.trans_le hb rw [inv_sub_inv' ((abv_pos abv).1 a0) ((abv_pos abv).1 b0), abv_mul abv, abv_mul abv, abv_inv abv, abv_inv abv, abv_sub abv] - refine lt_of_mul_lt_mul_left (lt_of_mul_lt_mul_right ?_ b0.le) a0.le - rw [mul_assoc, inv_mul_cancel_right₀ b0.ne', ← mul_assoc, mul_inv_cancel₀ a0.ne', one_mul] - refine h.trans_le ?_ - gcongr - exact mul_nonneg a0.le ε0.le + grw [← ha, mul_assoc, ← hb, h] + simp [K0.ne'] end diff --git a/Mathlib/Algebra/Polynomial/Mirror.lean b/Mathlib/Algebra/Polynomial/Mirror.lean index 88991a34ceb232..26234c588f95d5 100644 --- a/Mathlib/Algebra/Polynomial/Mirror.lean +++ b/Mathlib/Algebra/Polynomial/Mirror.lean @@ -76,7 +76,7 @@ theorem coeff_mirror (n : ℕ) : · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])] by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree] - exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _) + grw [h2, add_tsub_cancel_left] · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2] rw [not_lt] at h2 rw [revAt_le (h2.trans (Nat.le_add_right _ _))] diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean b/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean index ca7e85ec11cc33..284959334420aa 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean @@ -124,8 +124,8 @@ lemma head_lt {m a L} (hL : IsAdmissible m (a :: L)) : ∀ a' ∈ L, a < a' := fun _ => L.rel_of_pairwise_cons hL.sortedLT.pairwise @[grind →] lemma getElem_lt {m L} (hL : IsAdmissible m L) - {k : ℕ} {hk : k < L.length} : L[k] < m + L.length := - (hL.le k hk).trans_lt (Nat.add_lt_add_left hk _) + {k : ℕ} {hk : k < L.length} : L[k] < m + L.length := by + grw [hL.le, hk] /-- An element of an `m`-admissible list, as an element of the appropriate `Fin` -/ @[simps] diff --git a/Mathlib/Analysis/Convolution.lean b/Mathlib/Analysis/Convolution.lean index 6b01e33224dd8d..2f7b10b145e3f6 100644 --- a/Mathlib/Analysis/Convolution.lean +++ b/Mathlib/Analysis/Convolution.lean @@ -807,8 +807,8 @@ theorem convolution_tendsto_right {ι} {g : ι → G → E'} {l : Filter ι} {x have hgi : dist (g i (k i)) z₀ < ε / 3 := hgδ hpi (hki.trans <| half_lt_self hδ) have h1 : ∀ x' ∈ ball (k i) (δ / 2), dist (g i x') (g i (k i)) ≤ ε / 3 + ε / 3 := by intro x' hx' - refine (dist_triangle_right _ _ _).trans (add_le_add (hgδ hpi ?_).le hgi.le) - exact ((dist_triangle _ _ _).trans_lt (add_lt_add hx'.out hki)).trans_eq (add_halves δ) + grw [dist_triangle_right, hgδ hpi ?_, hgi] + grw [dist_triangle, hx'.out, hki, add_halves] have := dist_convolution_le (add_pos h2ε h2ε).le hφi hnφi hiφi hmgi h1 refine ((dist_triangle _ _ _).trans_lt (add_lt_add_of_le_of_lt this hgi)).trans_eq ?_ ring diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index f91ca532768c13..efe2280ce46e21 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -590,11 +590,7 @@ theorem exist_finset_disjoint_balls_large_measure (μ : Measure α) [IsFiniteMea apply ENNReal.exists_le_of_sum_le _ S exact ⟨⟨0, bot_lt_iff_ne_bot.2 Npos⟩, Finset.mem_univ _⟩ replace hi : μ s / (N + 1) < μ (s ∩ v i) := by - apply lt_of_lt_of_le _ hi - apply (ENNReal.mul_lt_mul_iff_right hμs.ne' (by finiteness)).2 - rw [ENNReal.inv_lt_inv] - conv_lhs => rw [← add_zero (N : ℝ≥0∞)] - exact ENNReal.add_lt_add_left (by finiteness) zero_lt_one + grw [← hi, ← _root_.zero_lt_one, add_zero] <;> finiteness have B : μ (o ∩ v i) = ∑' x : u i, μ (o ∩ closedBall x (r x)) := by have : o ∩ v i = ⋃ (x : s) (_ : x ∈ u i), o ∩ closedBall x (r x) := by simp only [v, inter_iUnion] diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 30f55d840a5be4..6695747a689e33 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -768,8 +768,7 @@ theorem mul_add_div_mul {a c : Ordinal} (hc : c < a) (b d : Ordinal) : · have H := mul_ne_zero hc.ne_zero hd apply le_antisymm · rw [← lt_succ_iff, ← lt_mul_iff_div_lt H, mul_assoc] - · apply (add_lt_add_right hc _).trans_le - rw [← mul_succ] + · grw [hc, ← mul_succ] gcongr rw [succ_le_iff] exact lt_mul_succ_div b hd @@ -934,8 +933,7 @@ theorem lt_mul_iff {a b c : Ordinal} : a < b * c ↔ ∃ q < c, ∃ r < b, a = b obtain rfl | hb₀ := eq_or_ne b 0; · simp refine ⟨fun h ↦ ⟨_, (lt_mul_iff_div_lt hb₀).1 h, _, mod_lt a hb₀, (div_add_mod ..).symm⟩, ?_⟩ rintro ⟨q, hq, r, hr, rfl⟩ - apply add_lt_add_right hr _ |>.trans_le - grw [← mul_add_one, add_one_le_iff.2 hq] + grw [hr, ← mul_add_one, add_one_le_iff.2 hq] theorem forall_lt_mul {b c : Ordinal} {P : Ordinal → Prop} : (∀ a < b * c, P a) ↔ ∀ q < c, ∀ r < b, P (b * q + r) := by diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 0a5fc651c4b1c4..69ffde62389d92 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -432,8 +432,7 @@ theorem log_opow_mul_add {b u v w : Ordinal} (hb : 1 < b) (hv : v ≠ 0) (hw : w rw [log_eq_iff hb] · constructor · grw [opow_add, opow_log_le_self b hv, ← le_self_add] - · apply (add_lt_add_right hw _).trans_le - rw [← mul_add_one, add_assoc, opow_add] + · grw [hw, ← mul_add_one, add_assoc, opow_add] gcongr rw [add_one_le_iff] exact lt_opow_succ_log_self hb _ diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index 276eb23a77ca1a..5adbc6f5b49997 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -271,7 +271,7 @@ theorem oadd_lt_oadd_1 {e₁ n₁ o₁ e₂ n₂ o₂} (h₁ : NF (oadd e₁ n theorem oadd_lt_oadd_2 {e o₁ o₂ : ONote} {n₁ n₂ : ℕ+} (h₁ : NF (oadd e n₁ o₁)) (h : (n₁ : ℕ) < n₂) : oadd e n₁ o₁ < oadd e n₂ o₂ := by simp only [lt_def, repr] - refine (add_lt_add_right h₁.snd'.repr_lt _).trans_le (le_trans ?_ le_self_add) + grw [h₁.snd'.repr_lt, ← le_self_add] rwa [← mul_succ, mul_le_mul_iff_right₀ (opow_pos _ omega0_pos), succ_le_iff, Nat.cast_lt] theorem oadd_lt_oadd_3 {e n a₁ a₂} (h : a₁ < a₂) : oadd e n a₁ < oadd e n a₂ := by @@ -529,14 +529,13 @@ theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a have IH := oadd_mul_nfBelow h₁ h₂.snd by_cases e0 : e₂ = 0 <;> simp only [e0, oadd_mul, ↓reduceIte] · apply NFBelow.oadd h₁.fst h₁.snd - simpa using (add_lt_add_iff_left (repr e₁)).2 h₂.lt.pos + grw [← h₂.lt.pos, add_zero] · haveI := h₁.fst haveI := h₂.fst apply NFBelow.oadd · infer_instance · rwa [repr_add] - · rw [repr_add, add_lt_add_iff_left] - exact h₂.lt + · grw [repr_add, h₂.lt] instance mul_nf : ∀ (o₁ o₂) [NF o₁] [NF o₂], NF (o₁ * o₂) | 0, o, _, h₂ => by cases o <;> exact NF.zero From 88428689d58a29bc2d98dc1ce51ffc42f8c881d8 Mon Sep 17 00:00:00 2001 From: Patrick Massot <14060883+PatrickMassot@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:39:03 +0000 Subject: [PATCH 0578/1300] chore: fix differentiability of sums of sections lemmas (#41315) They were assuming unnecessarily strong hypotheses: weaken them to what was inteded. Co-authored-by: Michael Rothgang --- .../Manifold/VectorBundle/LocalFrame.lean | 4 ++-- .../Manifold/VectorBundle/MDifferentiable.lean | 17 +++++++++-------- .../Manifold/VectorBundle/Tensoriality.lean | 13 +++++++------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 48b563d3570b33..a051a620ddc6e5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -297,7 +297,7 @@ lemma mdifferentiableOn_of_coeff [FiniteDimensional 𝕜 F] have this (i) : MDiff[u] (T% ((LinearMap.piApply (hs.coeff i)) t • s i)) := (h i).smul_section ((hs.contMDiffOn i).mdifferentiableOn one_ne_zero) have almost : MDiff[u] (T% (fun x ↦ ∑ i, hs.coeff i x (t x) • s i x)) := - .sum_section (fun i _ hx ↦ this i _ hx) + .sum_section (fun i _ _ hx ↦ this i _ hx) apply almost.congr intro y hy simpa using congrArg (TotalSpace.mk' F y) (hs.coeff_sum_eq t hy) @@ -309,7 +309,7 @@ lemma mdifferentiableAt_of_coeff [FiniteDimensional 𝕜 F] MDiffAt (T% t) x := by have := fintypeOfFiniteDimensional hs (mem_of_mem_nhds hu) have almost : MDiffAt (T% (fun x ↦ ∑ i, hs.coeff i x (t x) • s i x)) x := - .sum_section (fun i ↦ (h i).smul_section <| + .sum_section (fun i _ ↦ (h i).smul_section <| ((hs.contMDiffOn i).mdifferentiableOn one_ne_zero).mdifferentiableAt hu) exact almost.congr_of_eventuallyEq <| (hs.eventually_eq_sum_coeff_smul t hu).mono (by simp) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 77f7642f8e1a13..417ace8c8b5fe6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -455,29 +455,30 @@ lemma mdifferentiable_smul_const_section fun x₀ ↦ (hs x₀).smul_const_section lemma MDifferentiableWithinAt.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} - (hs : ∀ i, MDiffAt[u] (T% (t i ·)) x₀) : + (hs : ∀ i ∈ s, MDiffAt[u] (T% (t i ·)) x₀) : MDiffAt[u] (T% (fun x ↦ ∑ i ∈ s, (t i x))) x₀ := by classical induction s using Finset.induction_on with | empty => simpa using! (contMDiffWithinAt_zeroSection 𝕜 E).mdifferentiableWithinAt one_ne_zero | insert i s hi h => - simpa [Finset.sum_insert hi] using! mdifferentiableWithinAt_add_section (hs i) h + simp only [Finset.mem_insert, forall_eq_or_imp] at hs + simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs.1) (h hs.2) lemma MDifferentiableAt.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} {x₀ : B} - (hs : ∀ i, MDiffAt (T% (t i ·)) x₀) : + (hs : ∀ i ∈ s, MDiffAt (T% (t i ·)) x₀) : MDiffAt (T% (fun x ↦ ∑ i ∈ s, (t i x))) x₀ := by simp_rw [← mdifferentiableWithinAt_univ] at hs ⊢ exact MDifferentiableWithinAt.sum_section hs lemma MDifferentiableOn.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} - (hs : ∀ i, MDiff[u] (T% (t i ·))) : + (hs : ∀ i ∈ s, MDiff[u] (T% (t i ·))) : MDiff[u] (T% (fun x ↦ ∑ i ∈ s, (t i x))) := - fun x₀ hx₀ ↦ .sum_section fun i ↦ hs i x₀ hx₀ + fun x₀ hx₀ ↦ .sum_section fun i hi ↦ hs i hi x₀ hx₀ lemma MDifferentiable.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} - (hs : ∀ i, MDiff (T% (t i ·))) : + (hs : ∀ i ∈ s, MDiff (T% (t i ·))) : MDiff (T% (fun x ↦ ∑ i ∈ s, (t i x))) := - fun x₀ ↦ .sum_section fun i ↦ (hs i) x₀ + fun x₀ ↦ .sum_section fun i hi ↦ (hs i) hi x₀ /-- The scalar product `ψ • s` of a differentiable function `ψ : M → 𝕜` and a section `s` of a vector bundle `V → M` is differentiable once `s` is differentiable on an open set containing @@ -510,7 +511,7 @@ lemma MDifferentiableWithinAt.sum_section_of_locallyFinite let s := {i | ((fun i ↦ {x | t i x ≠ 0}) i ∩ u').Nonempty} have := hfin.fintype have : MDiffAt[u ∩ u'] (T% (fun x ↦ ∑ i ∈ s, (t i x))) x₀ := - .sum_section fun i ↦ ((ht' i).mono inter_subset_left) + .sum_section fun i _ ↦ ((ht' i).mono inter_subset_left) apply (mdifferentiableWithinAt_inter hu').mp apply this.congr' (fun y hy ↦ ?_) inter_subset_right (mem_of_mem_nhds hu') rw [TotalSpace.mk_inj, tsum_eq_sum'] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index ea840a37f5c4d9..a4b1e190339b7c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -110,7 +110,7 @@ theorem zero (hΦ : TensorialAt I F Φ x) : Φ 0 = 0 := by /-- A tensorial operation on sections of a vector bundle respects sums (since it respects binary addition). -/ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι → Π x : M, V x) - (hσ : ∀ i, MDiffAt (T% (σ i)) x) : + (hσ : ∀ i ∈ s, MDiffAt (T% (σ i)) x) : Φ (fun x' ↦ ∑ i ∈ s, σ i x') = ∑ i ∈ s, Φ (σ i) := by classical induction s using Finset.induction_on with @@ -118,8 +118,9 @@ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι rw [Finset.sum_empty] exact hΦ.zero | insert a s ha h => - simp only [Finset.sum_insert ha, ← h] - exact hΦ.add (hσ a) (.sum_section hσ) + simp only [Finset.mem_insert, forall_eq_or_imp] at hσ + simp only [Finset.sum_insert ha, ← h hσ.2] + exact hΦ.add (hσ.1) (.sum_section hσ.2) variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 F'] [ContMDiffVectorBundle 1 F V I] [ContMDiffVectorBundle 1 F' V' I] @@ -147,7 +148,7 @@ lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} have hΦ_eq {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) : Φ σ = Φ (fun x' ↦ ∑ i, c i x' (σ x') • s i x') := hΦ.local hσ - (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) + (.sum_section fun i _ ↦ (hc hσ i).smul_section (hs i)) (t.eventually_eq_localFrame_sum_coeff_smul b x_mem) -- Now evaluate using the tensoriality properties. rw [hΦ_eq hσ, hΦ_eq hσ', hΦ.sum, hΦ.sum] @@ -157,8 +158,8 @@ lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} _ = c i x (σ' x) • Φ (s i) := by rw [hσσ'] _ = Φ ((LinearMap.piApply (c i) σ') • (s i)) := hΦ.smul (hc hσ' i) (hs i) |>.symm - · exact fun i ↦ (hc hσ' i).smul_section (hs i) - · exact fun i ↦ (hc hσ i).smul_section (hs i) + · exact fun i _ ↦ (hc hσ' i).smul_section (hs i) + · exact fun i _ ↦ (hc hσ i).smul_section (hs i) /-- If the operation `Φ` on sections of vector bundles `V` and `V'` is tensorial at `x` in each argument, then it depends only on the value of the sections at `x`. -/ From 94f630c506ae8b715b7d2683f10dd8fcd7055daf Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Fri, 3 Jul 2026 10:33:33 +0000 Subject: [PATCH 0579/1300] feat(Combinatorics/Enumerative/Bell): sum over partition shapes (#39693) Kill TODO in `Mathlib/Combinatorics/Enumerative/Bell.lean` which proves `Nat.bell` as a sum of `Multiset.bell` over partition shapes --- Mathlib/Combinatorics/Enumerative/Bell.lean | 142 +++++++++++++----- .../Enumerative/Partition/Basic.lean | 27 ++++ 2 files changed, 134 insertions(+), 35 deletions(-) diff --git a/Mathlib/Combinatorics/Enumerative/Bell.lean b/Mathlib/Combinatorics/Enumerative/Bell.lean index 00f5a2ddd4ba94..b4a6ea99c6b401 100644 --- a/Mathlib/Combinatorics/Enumerative/Bell.lean +++ b/Mathlib/Combinatorics/Enumerative/Bell.lean @@ -1,10 +1,12 @@ /- Copyright (c) 2024 Antoine Chambert-Loir & María-Inés de Frutos—Fernández. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Antoine Chambert-Loir, María-Inés de Frutos—Fernández, Yu Shao, Beibei Xiong, Weijie Jiang +Authors: Antoine Chambert-Loir, María-Inés de Frutos—Fernández, Yu Shao, Beibei Xiong, Weijie Jiang, +Yi Yuan -/ module +public import Mathlib.Combinatorics.Enumerative.Partition.Basic public import Mathlib.Data.Nat.Choose.Multinomial /-! # Bell numbers for multisets @@ -74,15 +76,12 @@ private theorem bell_mul_eq_lemma {x : ℕ} (hx : x ≠ 0) : ring_nf theorem bell_mul_eq (m : Multiset ℕ) : - m.bell * (m.map (fun j ↦ j !)).prod * ∏ j ∈ (m.toFinset.erase 0), (m.count j)! - = m.sum ! := by + m.bell * (m.map (fun j ↦ j !)).prod * ∏ j ∈ (m.toFinset.erase 0), (m.count j)! = m.sum ! := by unfold bell rw [← Nat.mul_right_inj (a := ∏ i ∈ m.toFinset, (i * count i m)!) (by positivity)] - simp only [← mul_assoc] - rw [Nat.multinomial_spec] - simp only [mul_assoc] - rw [mul_comm] - apply congr_arg₂ + simp only [← mul_assoc, Nat.multinomial_spec] + rw [mul_assoc, mul_assoc, mul_comm] + congr · rw [mul_comm, mul_assoc, ← Finset.prod_mul_distrib, Finset.prod_multiset_map_count] suffices this : _ by by_cases hm : 0 ∈ m.toFinset @@ -94,30 +93,50 @@ theorem bell_mul_eq (m : Multiset ℕ) : nth_rewrite 3 [← Finset.erase_eq_of_notMem hm] exact this rw [← Finset.prod_mul_distrib] - apply Finset.prod_congr rfl - intro x hx + congr! 1 with x hx rw [← mul_assoc, bell_mul_eq_lemma] simp only [Finset.mem_erase, ne_eq, mem_toFinset] at hx simp only [ne_eq, hx.1, not_false_eq_true] - · apply congr_arg - rw [Finset.sum_multiset_count] + · rw [Finset.sum_multiset_count] simp only [smul_eq_mul, mul_comm] theorem bell_eq (m : Multiset ℕ) : - m.bell = m.sum ! / ((m.map (fun j ↦ j !)).prod * - ∏ j ∈ (m.toFinset.erase 0), (m.count j)!) := by + m.bell = m.sum ! / ((m.map fun j ↦ j !).prod * ∏ j ∈ m.toFinset.erase 0, (m.count j)!) := by rw [← Nat.mul_left_inj, Nat.div_mul_cancel _] · rw [← mul_assoc] exact bell_mul_eq m · rw [← bell_mul_eq, mul_assoc] apply Nat.dvd_mul_left · rw [← Nat.pos_iff_ne_zero] - apply Nat.mul_pos - · simp only [CanonicallyOrderedAdd.multiset_prod_pos, mem_map, forall_exists_index, and_imp, - forall_apply_eq_imp_iff₂] - exact fun _ _ ↦ Nat.factorial_pos _ - · apply Finset.prod_pos - exact fun _ _ ↦ Nat.factorial_pos _ + exact Nat.mul_pos (by simp [Nat.factorial_pos]) (by positivity) + +private theorem bell_cons_mul_count (m : Multiset ℕ) {a : ℕ} (ha : a ≠ 0) : + (a ::ₘ m).bell * (a ::ₘ m).count a = (m.sum + a).choose a * m.bell := by + let rest := ∏ j ∈ (m.toFinset.erase 0).erase a, (m.count j)! + have hrest : rest = ∏ j ∈ ((a ::ₘ m).toFinset.erase 0).erase a, ((a ::ₘ m).count j)! := by + unfold rest + congr! 1 with j hj + · grind [Multiset.toFinset_cons] + · simp [Finset.mem_erase.mp hj] + let c := (m.map (· !)).prod * (m.count a)! * rest + have hm0 : m.bell * c = m.sum ! := by + have hsplit : (m.count a)! * rest = ∏ j ∈ m.toFinset.erase 0, (m.count j)! := by + by_cases hmem : a ∈ m.toFinset.erase 0 + · rw [← Finset.mul_prod_erase _ _ hmem] + · have hcount : m.count a = 0 := by grind [Multiset.count_eq_zero_of_notMem] + simp [rest, Finset.erase_eq_of_notMem hmem, hcount] + simpa [c, hsplit, mul_assoc] using Multiset.bell_mul_eq m + have hm : m.sum ! * a ! = m.bell * a ! * c := by grind + have hc : 0 < a ! * c := Nat.mul_pos (by positivity) <| + Nat.mul_pos (by simp [Nat.factorial_pos]) (by positivity) + apply Nat.eq_of_mul_eq_mul_right hc + calc + _ = (m.sum + a)! := by + have hq := Multiset.bell_mul_eq (a ::ₘ m) + rw [← Finset.mul_prod_erase _ _ (a := a) (by simp [*]), ← hrest] at hq + simpa [c, Nat.factorial_succ, add_comm, mul_assoc, mul_left_comm] using hq + _ = ((m.sum + a).choose a * m.bell) * (a ! * c) := by + simp [← Nat.add_choose_mul_factorial_mul_factorial, mul_assoc, hm] end Multiset @@ -128,7 +147,7 @@ of `n`-element subsets. -/ def uniformBell (m n : ℕ) : ℕ := bell (replicate m n) theorem uniformBell_eq (m n : ℕ) : m.uniformBell n = - ∏ p ∈ (Finset.range m), Nat.choose (p * n + n - 1) (n - 1) := by + ∏ p ∈ (Finset.range m), choose (p * n + n - 1) (n - 1) := by unfold uniformBell bell rw [toFinset_replicate] split_ifs with hm @@ -172,32 +191,26 @@ theorem uniformBell_eq_div (m : ℕ) {n : ℕ} (hn : n ≠ 0) : uniformBell m n = (m * n)! / (n ! ^ m * m !) := by rw [eq_comm] apply Nat.div_eq_of_eq_mul_left - · exact Nat.mul_pos (Nat.pow_pos (Nat.factorial_pos n)) m.factorial_pos + · exact Nat.mul_pos (Nat.pow_pos n.factorial_pos) m.factorial_pos · rw [← mul_assoc, ← uniformBell_mul_eq _ hn] /-- The `n`th standard Bell number, which counts the number of partitions of a set of cardinality `n`. - -## TODO - -Prove that `Nat.bell n` is equal to the sum of `Multiset.bell m` -over all multisets `m : Multiset ℕ` such that `m.sum = n`. -/ protected def bell : ℕ → ℕ | 0 => 1 - | n + 1 => ∑ i : Fin n.succ, choose n i * Nat.bell (n - i) + | n + 1 => ∑ i ≤ n, choose n i * (n - i).bell theorem bell_succ (n : ℕ) : - Nat.bell (n + 1) = ∑ i : Fin n.succ, Nat.choose n i * Nat.bell (n - i) := by + (n + 1).bell = ∑ i ≤ n, choose n i * (n - i).bell := by rw [Nat.bell] theorem bell_succ' (n : ℕ) : - Nat.bell (n + 1) = ∑ ij ∈ Finset.antidiagonal n, Nat.choose n ij.1 * Nat.bell ij.2 := by + (n + 1).bell = ∑ ij ∈ Finset.antidiagonal n, choose n ij.1 * ij.2.bell := by rw [Nat.bell_succ, - Finset.Nat.sum_antidiagonal_eq_sum_range_succ (fun x y => Nat.choose n x * Nat.bell y) n, - Finset.sum_range] - + ← Nat.range_succ_eq_Iic, + ← Finset.Nat.sum_antidiagonal_eq_sum_range_succ (fun x y ↦ choose n x * y.bell) n] @[simp] theorem bell_zero : Nat.bell 0 = 1 := by @@ -205,10 +218,69 @@ theorem bell_zero : Nat.bell 0 = 1 := by @[simp] theorem bell_one : Nat.bell 1 = 1 := by - simp [Nat.bell] + have : Finset.Iic 0 = {0} := Eq.symm (Finset.eq_of_veq rfl) + simp [Nat.bell, this] @[simp] theorem bell_two : Nat.bell 2 = 2 := by - simp [Nat.bell] + have : Finset.Iic 1 = {0, 1} := Finset.eq_of_veq rfl + simp [Nat.bell, this] + +theorem bell_eq_sum_erase {n : ℕ} (p : (n + 1).Partition) : + p.parts.bell = ∑ a ∈ p.parts.toFinset, n.choose (a - 1) * (p.parts.erase a).bell := by + apply Nat.eq_of_mul_eq_mul_left n.succ_pos + calc + _ = (∑ a ∈ p.parts.toFinset, p.parts.count a * a) * p.parts.bell := by + rw [succ_eq_add_one, mul_eq_mul_right_iff] + left + simpa [smul_eq_mul, p.parts_sum] using Finset.sum_multiset_count p.parts + _ = ∑ a ∈ p.parts.toFinset, a * (p.parts.count a * p.parts.bell) := by grind [Finset.sum_mul] + _ = ∑ a ∈ p.parts.toFinset, (n + 1) * (n.choose (a - 1) * (p.parts.erase a).bell) := by + congr! 1 with a ha + have ha0 : a ≠ 0 := by grind + have hsum : (p.parts.erase a).sum + a = n + 1 := by + simpa [p.parts_sum, add_comm] using congrArg Multiset.sum (cons_erase (mem_dedup.mp ha)) + grind [Nat.add_one_mul_choose_eq, cons_erase, bell_cons_mul_count] + _ = _ := by rw [Finset.mul_sum] + +private def sigmaPartitionWithPartEquiv (n : ℕ) : + (Σ i : Fin n.succ, {p : (n + 1).Partition // (i + 1 : ℕ) ∈ p.parts}) ≃ + Σ p : (n + 1).Partition, {a : ℕ // a ∈ p.parts.toFinset} where + toFun x := ⟨x.2.1, ⟨(x.1 + 1 : ℕ), by simpa using x.2.2⟩⟩ + invFun x := ⟨⟨x.2.1 - 1, by grind⟩, ⟨x.1, by grind⟩⟩ + left_inv x := by simp + right_inv x := by grind + +/-- `Nat.bell n` is equal to the sum of `Multiset.bell m` over all multisets `m : Multiset ℕ` such +that `m.sum = n`. -/ +theorem bell_eq_sum_partition (n : ℕ) : n.bell = ∑ p : n.Partition, p.parts.bell := by + refine Nat.strong_induction_on n ?_ + rintro (_ | n) ih + · simp + rw [Nat.bell_succ] + calc + _ = ∑ i ≤ n, ∑ q : (n - i).Partition, n.choose i * q.parts.bell := by + congr! with i + simp [ih (n - i) _, Finset.mul_sum] + _ = ∑ i ≤ n, ∑ p : {p : (n + 1).Partition // (i + 1 : ℕ) ∈ p.parts}, + choose n i * (p.1.parts.erase (i + 1)).bell := by + congr! with i hi + have : i ≤ n := Finset.mem_Iic.mp hi + have h1 : 1 ≤ (i + 1 : ℕ) := by lia + have h2 : (i + 1 : ℕ) ≤ n + 1 := by lia + have hsub : n + 1 - (i + 1 : ℕ) = n - i := by lia + exact hsub ▸ (Fintype.sum_equiv (Partition.partitionWithPartEquiv h1 h2) _ _ (fun _ ↦ rfl)).symm + _ = ∑ x : Σ p : (n + 1).Partition, p.parts.toFinset, + choose n (x.2.1 - 1) * (x.1.parts.erase x.2.1).bell := by + rw [← Nat.range_succ_eq_Iic, Finset.sum_range, ← Fintype.sum_sigma'] + refine Fintype.sum_equiv (sigmaPartitionWithPartEquiv n) _ _ ?_ + simp [sigmaPartitionWithPartEquiv] + _ = ∑ p : (n + 1).Partition, ∑ a : p.parts.toFinset, choose n (a - 1) * (p.parts.erase a).bell := + Fintype.sum_sigma' fun (p : (n + 1).Partition) (a : p.parts.toFinset) ↦ + choose n (a - 1) * (p.parts.erase a.1).bell + _ = _ := by + congr! with p + rw [bell_eq_sum_erase p] + exact p.parts.toFinset.sum_coe_sort (fun a ↦ choose n (a - 1) * (p.parts.erase a).bell) end Nat diff --git a/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean b/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean index 4bb7639e6fa7b9..935de73ea4c4a9 100644 --- a/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean +++ b/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean @@ -229,6 +229,33 @@ theorem countRestricted_two (n : ℕ) : countRestricted n 2 = distincts n := by def oddDistincts (n : ℕ) : Finset n.Partition := odds n ∩ distincts n +/-- If `1 ≤ a` and `a ≤ n`, partitions of `n` containing `a` as a part are equivalent to +partitions of `n - a`. The forward map removes one occurrence of `a`, and the inverse adds `a` as +a part. -/ +def partitionWithPartEquiv {n a : ℕ} (ha1 : 1 ≤ a) (ha : a ≤ n) : + {p : n.Partition // a ∈ p.parts} ≃ (n - a).Partition where + toFun p := by + refine ⟨p.1.parts.erase a, ?_, ?_⟩ + · intro _ hi + exact p.1.parts_pos (p.1.parts.erase_subset a hi) + · have hs : a + (p.1.parts.erase a).sum = n := by + simpa [p.1.parts_sum] using congrArg Multiset.sum (Multiset.cons_erase p.2) + lia + invFun q := ⟨⟨a ::ₘ q.parts, by grind, by simp [q.parts_sum, ha]⟩, by simp⟩ + left_inv p := Subtype.ext <| Partition.ext <| cons_erase p.property + right_inv q := Partition.ext <| erase_cons_head a q.parts + +@[simp] +theorem partitionWithPartEquiv_apply_parts {n a : ℕ} (ha1 : 1 ≤ a) (ha : a ≤ n) + (p : {p : n.Partition // a ∈ p.parts}) : + (partitionWithPartEquiv ha1 ha p).parts = p.1.parts.erase a := by + dsimp [partitionWithPartEquiv] + +@[simp] +theorem partitionWithPartEquiv_symm_apply_parts {n a : ℕ} (ha1 : 1 ≤ a) (ha : a ≤ n) + (p : (n - a).Partition) : ((partitionWithPartEquiv ha1 ha).symm p).1.parts = a ::ₘ p.parts := by + dsimp [partitionWithPartEquiv] + end Partition end Nat From daca28527e759c61e79118995d069fb5bedbff59 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:33:36 +0000 Subject: [PATCH 0580/1300] chore: further tweaks for the title checks around capitalisation (#40179) Also allow a few selected suffixes to abbreviations. And make the error messages about suffixes more detailed. --- Mathlib/Tactic/Linter/ValidatePRTitle.lean | 12 +++++++--- MathlibTest/ValidatePRTitle.lean | 27 ++++++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Mathlib/Tactic/Linter/ValidatePRTitle.lean b/Mathlib/Tactic/Linter/ValidatePRTitle.lean index 2c3bc34f5aabb4..1fb45d557e4a16 100644 --- a/Mathlib/Tactic/Linter/ValidatePRTitle.lean +++ b/Mathlib/Tactic/Linter/ValidatePRTitle.lean @@ -119,11 +119,17 @@ public def validateTitle (title : String) : Array String := Id.run do -- Future: we could check if `scope` describes a directory that actually exist. -- Should we allow special syntax such as `Data/*/Basic` or `{Set,Group}Theory`? - -- Titles should be lower-cased (but we allow abbreviations). + -- Titles should be lower-cased (but we allow abbreviations, or a `s` or `'ed` suffix). if subject.front.toLower != subject.front then let firstWord := subject.takeWhile (!·.isWhitespace) - if !isAbbreviation firstWord then - errors := errors.push "error: the PR subject should be lowercased" + let suffixes := ["'s", "s", "'ed"] + let mut withoutSuffix := firstWord + for suff in suffixes do + if firstWord.endsWith suff then + withoutSuffix := firstWord.dropSuffix suff + break + if !(isAbbreviation withoutSuffix) then + errors := errors.push s!"error: the PR subject `{subject}` should be lowercased" if subject.endsWith "." then errors := errors.push "error: the PR title should not end with a full stop" else if subject.endsWith " " then diff --git a/MathlibTest/ValidatePRTitle.lean b/MathlibTest/ValidatePRTitle.lean index b9b01432b3dbbf..d7b20b55b20290 100644 --- a/MathlibTest/ValidatePRTitle.lean +++ b/MathlibTest/ValidatePRTitle.lean @@ -114,16 +114,35 @@ section subject #guard_msgs in #check_title "feat: bad title." -/-- info: Message: 'error: the PR subject should be lowercased' -/ +/-- info: Message: 'error: the PR subject `My Bad Title` should be lowercased' -/ #guard_msgs in #check_title "feat: My Bad Title" -- Starting with an acronym is fine, however. #guard_msgs in #check_title "feat: RPC acronyms are fine" +#guard_msgs in #check_title "feat: `ℕ` is countable" +-- We also allow a `s`, `'s` or `'ed` suffix, as manual heuristic. +#guard_msgs in #check_title "feat: RPCs are yellow" +#guard_msgs in #check_title "chore: LLMs require adjusting our policies" +#guard_msgs in #check_title "chore: PR'ed lemmas" +#guard_msgs in #check_title "feat(CI): PR's to be deleted" +#guard_msgs in #check_title "chore: FCP'ed decisions should be listed separately" +-- We only remove at most one suffix. +/-- info: Message: 'error: the PR subject `PR'ed's lemmas` should be lowercased' -/ +#guard_msgs in #check_title "chore: PR'ed's lemmas" +/-- info: Message: 'error: the PR subject `PRs's something` should be lowercased' -/ +#guard_msgs in #check_title "chore: PRs's something" +-- This is not quite an abbreviation (and a grammar error). +/-- +info: Message: 'error: the PR subject `FCPed decisions should be listed separately` should be lowercased' +-/ +#guard_msgs in #check_title "chore: FCPed decisions should be listed separately" -- This PR title is arguably not very bad (Lindelöf is a proper name), -- a better fix is to start with a verb (which you should do anyway.) -/-- info: Message: 'error: the PR subject should be lowercased' -/ +/-- +info: Message: 'error: the PR subject `Lindelöf spaces something something` should be lowercased' +-/ #guard_msgs in #check_title "feat: Lindelöf spaces something something" @@ -196,13 +215,13 @@ info: Message: 'error: the PR title contains multiple consecutive spaces; please #guard_msgs in #check_title "feat(ModuleForm): 2e is less than 6" -/-- info: Message: 'error: the PR subject should be lowercased' -/ +/-- info: Message: 'error: the PR subject `W3c` should be lowercased' -/ #guard_msgs in #check_title "feat(ModuleForm): W3c" #guard_msgs in #check_title "feat(ModuleForm): W3C" -/-- info: Message: 'error: the PR subject should be lowercased' -/ +/-- info: Message: 'error: the PR subject `A new lemma` should be lowercased' -/ #guard_msgs in #check_title "feat(ModuleForm): A new lemma" From 4aaa9627924a83742fd7e230f5ae8f0cf7dcb8c7 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:33:38 +0000 Subject: [PATCH 0581/1300] fix(Translate): preserve binder names when reordering lambdas (#40946) To my surprise, `lambdaMetaTelescope` does not use the lambda binder names to give names to the introduced metavariables. As a result, `reorderLambda` would rename all lambda binder names to `x`. This is fixed by only using `forallMetaTelescope` to introduce the metavariables. --- Mathlib/Tactic/Translate/Reorder.lean | 8 +++----- MathlibTest/Attribute/ToDual.lean | 17 +++++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Mathlib/Tactic/Translate/Reorder.lean b/Mathlib/Tactic/Translate/Reorder.lean index 979689c87bedb4..6c5e03c1b0a4a8 100644 --- a/Mathlib/Tactic/Translate/Reorder.lean +++ b/Mathlib/Tactic/Translate/Reorder.lean @@ -213,15 +213,13 @@ partial def reorderForall (reorder : ArgReorder) (e : Expr) : MetaM Expr := do /-- Reorder the arguments of a function using the given `ArgReorder`. -/ partial def reorderLambda (reorder : ArgReorder) (e : Expr) : MetaM Expr := do - let (mvars, bis, e) ← lambdaMetaTelescope e reorder.range - let (mvars', bis', _) ← forallMetaBoundedTelescope (← inferType e) (reorder.range - mvars.size) - let mut mvars := mvars ++ mvars' + let (mvars, bis, _) ← forallMetaBoundedTelescope (← inferType e) reorder.range unless mvars.size = reorder.range do throwError "the permutation (reorder := {reorder}) is out of bounds, \ the function{indentExpr e}\nhas only {mvars.size} arguments" - let bis := reorder.permute! (bis ++ bis') |>.toList + let bis := reorder.permute! bis |>.toList -- Note that `mkLambdaFVars` also works with mvars. - fixBinderInfos bis <$> mkLambdaFVars (← reorderMVars mvars reorder) (mkAppN e mvars') + fixBinderInfos bis <$> mkLambdaFVars (← reorderMVars mvars reorder) (e.beta mvars) end diff --git a/MathlibTest/Attribute/ToDual.lean b/MathlibTest/Attribute/ToDual.lean index cc33c6b6d4b891..3eec586c7882c7 100644 --- a/MathlibTest/Attribute/ToDual.lean +++ b/MathlibTest/Attribute/ToDual.lean @@ -55,16 +55,17 @@ def SemilatticeSup.casesOn' {α} {motive : SemilatticeSup α → Sort*} (t : Sem t.casesOn mk /-- -info: SemilatticeInf.casesOn'.{u_1} {α : Type} {motive : SemilatticeInf α → Sort u_1} - (mk : - [inst : Min α] → - [inst_1 : PartialOrder α] → - (sup_le : ∀ (b a c : α), c ≤ a → c ≤ b → c ≤ a ⊓ b) → - motive { toPartialOrder := inst_1, toMin := inst, le_inf := ⋯ }) - (t : SemilatticeInf α) : motive t +info: @[expose] def SemilatticeInf.casesOn'.{u_1} : {α : Type} → + {motive : SemilatticeInf α → Sort u_1} → + ([inst : Min α] → + [inst_1 : PartialOrder α] → + (sup_le : ∀ (b a c : α), c ≤ a → c ≤ b → c ≤ a ⊓ b) → + motive { toPartialOrder := inst_1, toMin := inst, le_inf := ⋯ }) → + (t : SemilatticeInf α) → motive t := +fun {α} {motive} mk t => SemilatticeInf.casesOn t fun [PartialOrder α] [Min α] sup_le => mk ⋯ -/ #guard_msgs in -#check SemilatticeInf.casesOn' +#print SemilatticeInf.casesOn' class Semilattice (α : Type) extends SemilatticeInf α, SemilatticeSup α attribute [to_dual existing] Semilattice.toSemilatticeSup From 5f4b499c1f1f93d972f940b2d6a1b873a145d4dd Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 3 Jul 2026 11:57:57 +0000 Subject: [PATCH 0582/1300] =?UTF-8?q?fix(scripts/create=5Fdeprecated=5Fmod?= =?UTF-8?q?ules):=20produce=20deprecated=20modules=20ob=E2=80=A6=20(#40261?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …eying the module system --- scripts/create_deprecated_modules.lean | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/create_deprecated_modules.lean b/scripts/create_deprecated_modules.lean index 92138e86c56e5d..94f0be436a5645 100644 --- a/scripts/create_deprecated_modules.lean +++ b/scripts/create_deprecated_modules.lean @@ -50,13 +50,19 @@ It returns just the imports of `fileContent`, including trailing comments if `ke -/ def getHeader (fname fileContent : String) (keepTrailing : Bool) : IO String := do let (stx, _) ← Parser.parseHeader (Parser.mkInputContext fileContent fname) + -- The first argument is a module token (if any). + let isModule := !(stx.raw.getArg 0).getArgs.isEmpty let imports := stx.raw.getArg 2 -- extract just the imports list let imports := if keepTrailing then imports else imports.unsetTrailing -- Use `withLeading := false` to exclude leading comments (e.g. copyright header) that the -- parser now attaches to the first token (see leanprover/lean4#12662). let some substring := imports.getSubstring? (withLeading := false) | throw <| .userError "No substring: we have a problem!" - return substring.toString + -- This implementation is geared for to create a deprecated module: + -- since imports there are unused by definition, we need to tell shake to keep them. + -- For a general-purpose implementation, whether to add the `--keep-all` flag + -- should be made configurable. + return (if isModule then "module -- shake: keep-all\n\n" else "") ++ substring.toString /-- `getHeaderFromFileName fname keepTrailing` is similar to `getHeader`, except that it assumes that @@ -161,6 +167,8 @@ def mkRenamesDict (percent : Nat := 100) : IO (Std.HashMap String String) := do and a similarity percentage.\nFull git line: '{git}'" continue let some pctNat := (pct.drop 1).toNat? | continue + -- We skip renames of files in `MathlibTest`. + if oldName.startsWith "MathlibTest/" then continue -- This looks like a rename with a similarity index at least as big as our threshold: -- we add the rename to our dictionary. if percent ≤ pctNat then @@ -233,10 +241,11 @@ def deprecateFilePath (fname : String) (rename comment : Option String) : -- Retrieve the final version of the file, before it was deleted. let file ← runCmd s!"git show {modifiedHash}:{fname}" -- Generate a module deprecation for the file `fname`. + -- As mathlib uses the module system, it is fine to always generate a module. let fileHeader ← match rename with | some rename => do let modName := mkModName rename - pure s!"import {modName}" + pure s!"module -- shake: keep-all\n\npublic import {modName}" | none => getHeader fname file false let deprecatedFile := s!"{fileHeader.trimAsciiEnd}\n\n{deprecation.pretty.trimAsciiEnd}\n" msgs := msgs.push <| .trace {cls := `Deprecation} m!"{fname}" #[m!"\n{deprecatedFile}"] From 313e59a37c44c1a789c665fb79066fc222e48735 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 3 Jul 2026 12:43:06 +0000 Subject: [PATCH 0583/1300] refactor(RingTheory/RamificationInertia/Inertia): remove last occurances of `inertiaDeg_eq_inertiaDeg'` (#41320) This PR adds a bit more API for `RingTheory/RamificationInertia/Inertia` in order to remove the last occurances of `inertiaDeg_eq_inertiaDeg'`. Co-authored-by: tb65536 --- .../NumberField/Completion/Ramification.lean | 9 ++- .../NumberField/Ideal/KummerDedekind.lean | 2 +- .../RamificationInertia/HilbertTheory.lean | 4 +- .../RamificationInertia/Inertia.lean | 60 ++++++++++++++----- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean index d38f345250f80c..1e00c9583a5808 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean @@ -6,7 +6,7 @@ Authors: Salvatore Mercuri module public import Mathlib.NumberTheory.NumberField.Completion.LiesOverInstances -public import Mathlib.NumberTheory.RamificationInertia.Basic +public import Mathlib.RingTheory.RamificationInertia.Inertia /-! # Ramification theory of completions of number fields @@ -86,16 +86,15 @@ variable (w) open scoped Classical in /-- The inertia degree of `w` over `v`. -/ protected noncomputable def inertiaDeg : ℕ := - if _ : w.1.LiesOver v.1 then (⊥ : Ideal v.Completion).inertiaDeg (⊥ : Ideal w.Completion) else 0 + if _ : w.1.LiesOver v.1 then (⊥ : Ideal w.Completion).inertiaDeg' v.Completion else 0 theorem inertiaDeg_of_liesOver [w.1.LiesOver v.1] : - v.inertiaDeg w = (⊥ : Ideal v.Completion).inertiaDeg (⊥ : Ideal w.Completion) := by + v.inertiaDeg w = (⊥ : Ideal w.Completion).inertiaDeg' v.Completion := by simp only [InfinitePlace.inertiaDeg, dif_pos] theorem inertiaDeg_eq_finrank [w.1.LiesOver v.1] : v.inertiaDeg w = Module.finrank v.Completion w.Completion := by - simp only [inertiaDeg_of_liesOver, Ideal.inertiaDeg, Ideal.comap_bot_of_injective _ <| - FaithfulSMul.algebraMap_injective v.Completion w.Completion] + rw [inertiaDeg_of_liesOver, Ideal.inertiaDeg'_eq_of_isMaximal ⊥] exact Algebra.finrank_eq_of_equiv_equiv (RingEquiv.quotientBot v.Completion) (RingEquiv.quotientBot w.Completion) (by ext; simp [RingHom.algebraMap_toAlgebra]) diff --git a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean index bc6ad76777c640..d53e1be80c7114 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean @@ -218,7 +218,7 @@ theorem inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ apply Ideal.primesOver.isMaximal have := liesOver_primesOverSpanEquivMonicFactorsMod_symm hp hQ rw [primesOverSpanEquivMonicFactorsMod_symm_apply_eq_span, - ← inertiaDeg_eq_inertiaDeg' (span {(p : ℤ)}), inertiaDeg_algebraMap, + inertiaDeg'_eq_of_isMaximal (span {(p : ℤ)}), ← finrank_quotient_span_eq_natDegree] refine Algebra.finrank_eq_of_equiv_equiv (Int.quotientSpanNatEquivZMod p) ?_ (by ext; simp) exact (ZModXQuotSpanEquivQuotSpanPair hp hQ).symm diff --git a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean index cd3d07a89320a5..75ab4d182a9aad 100644 --- a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean +++ b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean @@ -283,7 +283,6 @@ private lemma instances (hp : p ≠ ⊥) : exact ⟨inst₁, inst₂, inst₃, inst₄, inst₅, Ideal.ne_bot_of_liesOver_of_ne_bot hp 𝓟D⟩ variable [FiniteDimensional K L] [Ring.HasFiniteQuotients A] [𝓟D.IsMaximal] [P.IsMaximal] - [p.IsMaximal] include K L D P in private lemma ramificationIdxIn_eq_and_inertiaDegIn_eq (hp : p ≠ ⊥) : @@ -297,8 +296,7 @@ private lemma ramificationIdxIn_eq_and_inertiaDegIn_eq (hp : p ≠ ⊥) : exact 𝓟D.ramificationIdx_above_le P · rw [inertiaDegIn_eq_inertiaDeg p P Gal(L/K), inertiaDegIn_eq_inertiaDeg _ P (stabilizer Gal(L/K) P)] - rw [← inertiaDeg_eq_inertiaDeg' p, ← inertiaDeg_eq_inertiaDeg' 𝓟D] - exact inertiaDeg_le_inertiaDeg p 𝓟D P + exact inertiaDeg'_above_le 𝓟D P · have := ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝓟D B (stabilizer Gal(L/K) P) rw [primesOver_eq_singleton K L P D 𝓞D, Set.ncard_singleton, one_mul] at this rw [this, IsGaloisGroup.card_eq_finrank (stabilizer Gal(L/K) P) D L, diff --git a/Mathlib/RingTheory/RamificationInertia/Inertia.lean b/Mathlib/RingTheory/RamificationInertia/Inertia.lean index 43dccb0c21f83a..f01fb0e111881b 100644 --- a/Mathlib/RingTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/RingTheory/RamificationInertia/Inertia.lean @@ -76,22 +76,36 @@ theorem inertiaDeg'_eq [q.LiesOver p] [q.IsPrime] [p.IsPrime] subst this exact inertiaDeg'_def q R -theorem inertiaDeg_eq_inertiaDeg' [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : - p.inertiaDeg q = q.inertiaDeg' R := by +theorem inertiaDeg'_eq_of_isFractionRing [q.LiesOver p] [p.IsPrime] [q.IsPrime] + (K L : Type*) [Field K] [Field L] + [Algebra (R ⧸ p) K] [IsFractionRing (R ⧸ p) K] + [Algebra (S ⧸ q) L] [IsFractionRing (S ⧸ q) L] + [Algebra R K] [IsScalarTower R (R ⧸ p) K] + [Algebra S L] [IsScalarTower S (S ⧸ q) L] + [Algebra R L] [IsScalarTower R S L] + [Algebra K L] [IsScalarTower R K L] : + q.inertiaDeg' R = Module.finrank K L := by + let := Localization.AtPrime.algebraOfLiesOver p q + rw [inertiaDeg'_eq p q] + apply Algebra.finrank_eq_of_equiv_equiv + (IsFractionRing.algEquivOfAlgEquiv (R := R) (A := R ⧸ p) (K := p.ResidueField) (L := K) .refl) + (IsFractionRing.algEquivOfAlgEquiv (R := S) (A := S ⧸ q) (K := q.ResidueField) (L := L) .refl) + apply IsFractionRing.ringHom_ext (A := R ⧸ p) + intro x + obtain ⟨x, rfl⟩ := Ideal.Quotient.mk_surjective x + simp [← IsScalarTower.algebraMap_apply R p.ResidueField q.ResidueField, + IsScalarTower.algebraMap_apply R S q.ResidueField, + ← IsScalarTower.algebraMap_apply R K L, ← IsScalarTower.algebraMap_apply R S L] + +theorem inertiaDeg'_eq_of_isMaximal [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : + q.inertiaDeg' R = Module.finrank (R ⧸ p) (S ⧸ q) := by let : Field (R ⧸ p) := Quotient.field p let : Field (S ⧸ q) := Quotient.field q - let := Localization.AtPrime.algebraOfLiesOver p q - rw [inertiaDeg'_eq p q, inertiaDeg_algebraMap] - let f := (algebraMap (S ⧸ q) q.ResidueField).comp (algebraMap (R ⧸ p) (S ⧸ q)) - let g := (algebraMap p.ResidueField q.ResidueField).comp (algebraMap (R ⧸ p) p.ResidueField) - have h : f = g := by ext; simp [f, g, ← IsScalarTower.algebraMap_apply] - let : Algebra (R ⧸ p) q.ResidueField := f.toAlgebra - have : IsScalarTower (R ⧸ p) (S ⧸ q) q.ResidueField := IsScalarTower.of_algebraMap_eq' rfl - have : IsScalarTower (R ⧸ p) p.ResidueField q.ResidueField := IsScalarTower.of_algebraMap_eq' h - rw [← mul_one (Module.finrank (R ⧸ p) (S ⧸ q)), - ← Module.finrank_of_bijective_algebraMap (bijective_algebraMap_quotient_residueField q), - Module.finrank_mul_finrank, ← Module.finrank_mul_finrank (R ⧸ p) p.ResidueField q.ResidueField, - Module.finrank_of_bijective_algebraMap (bijective_algebraMap_quotient_residueField p), one_mul] + exact inertiaDeg'_eq_of_isFractionRing p q (R ⧸ p) (S ⧸ q) + +theorem inertiaDeg_eq_inertiaDeg' [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : + p.inertiaDeg q = q.inertiaDeg' R := by + rw [inertiaDeg_algebraMap, inertiaDeg'_eq_of_isMaximal p q] theorem inertiaDeg'_tower [r.LiesOver q] : r.inertiaDeg' R = q.inertiaDeg' R * r.inertiaDeg' S := by @@ -105,6 +119,24 @@ theorem inertiaDeg'_tower [r.LiesOver q] : apply Module.finrank_mul_finrank · rw [inertiaDeg'_of_not_isPrime r R hr, inertiaDeg'_of_not_isPrime r S hr, mul_zero] +theorem inertiaDeg'_below_dvd [r.LiesOver q] : + q.inertiaDeg' R ∣ r.inertiaDeg' R := by + use r.inertiaDeg' S + rw [← inertiaDeg'_tower] + +theorem inertiaDeg'_above_dvd [r.LiesOver q] : + r.inertiaDeg' S ∣ r.inertiaDeg' R := by + use q.inertiaDeg' R + rw [mul_comm, ← inertiaDeg'_tower] + +theorem inertiaDeg'_below_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] : + q.inertiaDeg' R ≤ r.inertiaDeg' R := + Nat.le_of_dvd (r.inertiaDeg'_pos R) (q.inertiaDeg'_below_dvd r) + +theorem inertiaDeg'_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] : + r.inertiaDeg' S ≤ r.inertiaDeg' R := + Nat.le_of_dvd (r.inertiaDeg'_pos R) (q.inertiaDeg'_above_dvd r) + variable (R) in open Pointwise in @[simp] From 6fd5453dbccbeb09a0d5461e7d47735648d1f0ca Mon Sep 17 00:00:00 2001 From: Oliiiiver <114979686+Oliiiiver@users.noreply.github.com> Date: Fri, 3 Jul 2026 12:53:33 +0000 Subject: [PATCH 0584/1300] refactor: generalized weak approximation (#41157) refactor the existing proof of weak approximation to the generalized version applied to pairwise inequivalent absolute value --- .../Analysis/AbsoluteValue/Equivalence.lean | 47 +++++++++++++++++++ .../NumberField/InfinitePlace/Basic.lean | 38 ++------------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/Mathlib/Analysis/AbsoluteValue/Equivalence.lean b/Mathlib/Analysis/AbsoluteValue/Equivalence.lean index a74d5ea5364682..065f7dcf02d4f4 100644 --- a/Mathlib/Analysis/AbsoluteValue/Equivalence.lean +++ b/Mathlib/Analysis/AbsoluteValue/Equivalence.lean @@ -389,4 +389,51 @@ theorem isEquiv_iff_isHomeomorph (v w : AbsoluteValue F ℝ) : end Real +section WeakApproximation + +open Filter +open scoped Topology + +variable {F : Type*} [Field F] + +/-- +If `v : ι → AbsoluteValue F ℝ` is a finite family of nontrivial, pairwise inequivalent +real absolute values on a field `F`, then the diagonal embedding +`algebraMap F ((i : ι) → WithAbs (v i))` has dense range. + +This is the abstract weak approximation theorem; see +`NumberField.InfinitePlace.denseRange_algebraMap_pi` for the number-field special case. +-/ +theorem denseRange_algebraMap_pi {ι : Type*} [Finite ι] {v : ι → AbsoluteValue F ℝ} + (h : ∀ i, (v i).IsNontrivial) + (hv : Pairwise fun i j ↦ ¬(v i).IsEquiv (v j)) : + DenseRange <| algebraMap F ((i : ι) → WithAbs (v i)) := by + classical + have := Fintype.ofFinite ι + refine Metric.denseRange_iff.mpr fun z r hr ↦ ?_ + choose a hx using exists_one_lt_lt_one_pi_of_not_isEquiv h hv + let y := fun n : ℕ ↦ ∑ i, (1 / (1 + (a i)⁻¹ ^ n)) * WithAbs.equiv (v i) (z i) + have htend : atTop.Tendsto (fun n i ↦ (WithAbs.equiv (v i)).symm (y n)) (𝓝 z) := by + refine tendsto_pi_nhds.mpr fun u ↦ ?_ + simp_rw [← Fintype.sum_pi_single u z, y, map_sum, map_mul] + refine tendsto_finsetSum _ fun w _ ↦ ?_ + by_cases hw : u = w + · rw [← hw, Pi.single_eq_same] + have hlt : (v u) (a u)⁻¹ < 1 := by + simpa [← inv_pow, inv_lt_one_iff₀] using Or.inr (hx u).1 + simpa using (WithAbs.tendsto_one_div_one_add_pow_nhds_one hlt).mul_const (z u) + · rw [Pi.single_eq_of_ne (M := fun i ↦ WithAbs (v i)) hw (z w)] + have hgt : 1 < (v u) (a w)⁻¹ := by + rw [map_inv₀] + refine one_lt_inv_iff₀.mpr ⟨(v u).pos_iff.mpr fun ha ↦ ?_, (hx w).2 u hw⟩ + linarith [map_zero (v w) ▸ ha ▸ (hx w).1] + have := (v u).tendsto_div_one_add_pow_nhds_zero hgt + simp_rw [← WithAbs.norm_toAbs_eq] at this + simpa using (tendsto_zero_iff_norm_tendsto_zero.2 this).mul_const + ((WithAbs.equiv (v u)).symm _) + let ⟨N, hN⟩ := Metric.tendsto_atTop.1 htend r hr + exact ⟨y N, dist_comm z (algebraMap F _ (y N)) ▸ hN N le_rfl⟩ + +end WeakApproximation + end AbsoluteValue diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index 5f6e2279bcd393..5baa65ba634bb0 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -596,7 +596,6 @@ theorem isNontrivial : v.1.IsNontrivial := by variable {v} (K) -open Filter in /-- *Weak approximation for infinite places* The number field `K` is dense when embedded diagonally in the product @@ -604,39 +603,8 @@ The number field `K` is dense when embedded diagonally in the product topology coming from the infinite place `v`. -/ theorem denseRange_algebraMap_pi [NumberField K] : - DenseRange <| algebraMap K ((v : InfinitePlace K) → WithAbs v.1) := by - classical - -- We have to show that given `(zᵥ)ᵥ` with `zᵥ : WithAbs v.1`, there is a `y : K` that is - -- arbitrarily close to each `zᵥ` in `v`'s topology. - refine Metric.denseRange_iff.mpr fun z r hr ↦ ?_ - -- Given `v`, by previous results we can select a `aᵥ : K` for each infinite place `v` - -- such that `1 < v aᵥ` while `w aᵥ < 1` for all `w ≠ v`. - choose a hx using AbsoluteValue.exists_one_lt_lt_one_pi_of_not_isEquiv isNontrivial - fun _ _ hwv ↦ (eq_iff_isEquiv (K := K)).not.mp hwv - -- Define the sequence `yₙ = ∑ v, 1 / (1 + aᵥ⁻ⁿ) * zᵥ` in `K` - let y := fun n ↦ ∑ v, (1 / (1 + (a v)⁻¹ ^ n)) * WithAbs.equiv v.1 (z v) - -- We will show that this sequence converges to `z` in the product topology. - have : atTop.Tendsto - (fun n (v : InfinitePlace K) ↦ (WithAbs.equiv v.1).symm (y n)) (𝓝 z) := by - -- At a fixed place `u`, the limit of `y` with respect to `u`'s topology is `zᵤ`. - refine tendsto_pi_nhds.mpr fun u ↦ ?_ - simp_rw [← Fintype.sum_pi_single u z, y, map_sum, map_mul] - refine tendsto_finsetSum _ fun w _ ↦ ?_ - by_cases hw : u = w - · -- Because `1 / (1 + aᵤ⁻ⁿ) → 1` in `WithAbs u.1`. - rw [← hw, Pi.single_eq_same] - have : u (a u)⁻¹ < 1 := by simpa [← inv_pow, inv_lt_one_iff₀] using .inr (hx u).1 - simpa using (WithAbs.tendsto_one_div_one_add_pow_nhds_one this).mul_const (z u) - · -- And `1 / (1 + aᵤ⁻ⁿ) → 0` in `WithAbs w.1` when `w ≠ u`. - rw [Pi.single_eq_of_ne (M := fun v ↦ WithAbs v.1) hw (z w)] - have hu : 1 < u (a w)⁻¹ := by simpa [one_lt_inv_iff₀] using - ⟨u.pos_iff.2 fun ha ↦ by linarith [map_zero w ▸ ha ▸ (hx w).1], (hx w).2 u hw⟩ - have := u.1.tendsto_div_one_add_pow_nhds_zero hu - simp_rw [← WithAbs.norm_toAbs_eq] at this - simpa using (tendsto_zero_iff_norm_tendsto_zero.2 this).mul_const - ((WithAbs.equiv u.1).symm (WithAbs.equiv w.1 (z w))) - -- So taking a sufficiently large index of the sequence `yₙ` gives the desired term. - let ⟨N, h⟩ := Metric.tendsto_atTop.1 this r hr - exact ⟨y N, dist_comm z (algebraMap K _ (y N)) ▸ h N le_rfl⟩ + DenseRange <| algebraMap K ((v : InfinitePlace K) → WithAbs v.1) := + AbsoluteValue.denseRange_algebraMap_pi (fun v ↦ v.isNontrivial) + fun _ _ h ↦ (eq_iff_isEquiv (K := K)).not.mp h end NumberField.InfinitePlace From 9ff42dc6c7c6acf01138b7dda1381a08920d51ab Mon Sep 17 00:00:00 2001 From: Seewoo Lee <49933279+seewoo5@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:03:51 +0000 Subject: [PATCH 0585/1300] feat(ModularForm): the Eisenstein series E2 is bounded at ImInfty (#40765) --- Mathlib/Analysis/Complex/Periodic.lean | 3 +++ .../EisensteinSeries/E2/Summable.lean | 17 ++++++++++++++ .../EisensteinSeries/QExpansion.lean | 2 +- .../NumberTheory/ModularForms/QExpansion.lean | 22 +++++++++++++++++-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/Complex/Periodic.lean b/Mathlib/Analysis/Complex/Periodic.lean index 4cb853d1ba5833..ee74a523d80fab 100644 --- a/Mathlib/Analysis/Complex/Periodic.lean +++ b/Mathlib/Analysis/Complex/Periodic.lean @@ -74,6 +74,9 @@ theorem norm_qParam_lt_iff (hh : 0 < h) (A : ℝ) (z : ℂ) : rw [norm_qParam, Real.exp_lt_exp, div_lt_div_iff_of_pos_right hh, mul_lt_mul_left_of_neg] simpa using Real.pi_pos +theorem norm_qParam_lt_one (hh : 0 < h) {z : ℂ} (hz : 0 < im z) : ‖𝕢 h z‖ < 1 := by + simpa using (norm_qParam_lt_iff hh 0 z).mpr hz + lemma qParam_ne_zero (z : ℂ) : 𝕢 h z ≠ 0 := by simp [qParam, exp_ne_zero] diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Summable.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Summable.lean index 7272e6e7eae428..76fb2308303e97 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Summable.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Summable.lean @@ -103,6 +103,23 @@ lemma E2_eq_tsum_cexp : E2 z = 1 - 24 * ∑' n : ℕ+, σ 1 n * 𝕢 z ^ (n : simp [E2, G2_eq_tsum_cexp, riemannZeta_two] field +/-- The `q`-expansion of `E2` as a `HasSum` over `ℕ`. -/ +theorem hasSum_qExpansion_E2 : + HasSum (fun m : ℕ ↦ (if m = 0 then 1 else -24 * σ 1 m : ℂ) • 𝕢 z ^ m) (E2 z) := by + have hS : Summable fun n : ℕ ↦ σ 1 (n + 1) * 𝕢 z ^ (n + 1) := + (summable_nat_add_iff 1).mpr (summable_sigma_mul_cexp_pow (k := 2) (one_le_two) z) + rw [← hasSum_nat_add_iff' 1] + convert! (hS.mul_left (-24)).hasSum using 1 + · ext : 1 + simp [mul_assoc] + · rw [E2_eq_tsum_cexp, tsum_pnat_eq_tsum_succ (f := fun n ↦ σ 1 n * 𝕢 z ^ n), tsum_mul_left] + simp + +/-- `E2` is bounded at `i∞`. -/ +theorem isBoundedAtImInfty_E2 : IsBoundedAtImInfty E2 := + isBoundedAtImInfty_of_hasSum_qExpansion one_pos fun τ ↦ by + simpa only [Function.Periodic.qParam, ofReal_one, div_one] using hasSum_qExpansion_E2 (z := τ) + lemma tendsto_e2Summand_atTop_nhds_zero : Tendsto (e2Summand · z) atTop (𝓝 0) := (summable_e2Summand_symmetricIcc z).tendsto_zero_of_even_summable_symmetricIcc (e2Summand_even _) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 62fdc501c49be4..907535d57c87cc 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -308,7 +308,7 @@ open ModularFormClass local notation "𝕢" => Periodic.qParam /-- Summability of the divisor-sum q-expansion series `∑ σ_{k-1}(n) q^n`. -/ -private lemma summable_sigma_mul_cexp_pow {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +lemma EisensteinSeries.summable_sigma_mul_cexp_pow {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : Summable fun n : ℕ ↦ (σ (k - 1) n : ℂ) * cexp (2 * π * I * z) ^ n := by apply Summable.of_norm_bounded (summable_norm_pow_mul_geometric_of_norm_lt_one k (norm_exp_two_pi_I_lt_one z)) diff --git a/Mathlib/NumberTheory/ModularForms/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/QExpansion.lean index 8b0df914943f08..cddcd9165a1348 100644 --- a/Mathlib/NumberTheory/ModularForms/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/QExpansion.lean @@ -189,8 +189,7 @@ lemma hasSum_qExpansion_of_norm_lt {f : ℍ → ℂ} (hh : 0 < h) lemma hasSum_qExpansion {f : ℍ → ℂ} (hh : 0 < h) (hfper : Periodic (f ∘ ofComplex) h) (hfhol : MDiff f) (hfbdd : IsBoundedAtImInfty f) (τ : ℍ) : HasSum (fun m : ℕ ↦ (qExpansion h f).coeff m • 𝕢 h τ ^ m) (f τ) := by - have : 0 < 2 * π * τ.im / h := by positivity - have : ‖𝕢 h τ‖ < 1 := by simpa [Periodic.qParam, Complex.norm_exp, neg_div] + have : ‖𝕢 h τ‖ < 1 := Periodic.norm_qParam_lt_one hh τ.im_pos simpa [eq_cuspFunction τ hh.ne' hfper] using hasSum_qExpansion_of_norm_lt hh hfper hfhol hfbdd this @@ -258,6 +257,25 @@ private lemma hasFPowerSeriesOnBall_update {f : ℍ → ℂ} (hh : 0 < h) {c : · simpa [update_of_ne hy', mul_comm] using hasSum_cuspFunction_of_hasSum_punctured hh hf hy hy' +/-- A function on the upper half plane that is given everywhere by a convergent `q`-expansion with +non-negative exponents, `f τ = ∑' m, c m * 𝕢 h τ ^ m`, is bounded at `i∞`. This is a converse to +`hasSum_qExpansion`: there, boundedness is a hypothesis used to produce the `q`-expansion, while +here convergence of the `q`-expansion is enough to deduce boundedness. -/ +theorem isBoundedAtImInfty_of_hasSum_qExpansion {f : ℍ → ℂ} {c : ℕ → ℂ} (hh : 0 < h) + (hf : ∀ τ : ℍ, HasSum (fun m ↦ c m • 𝕢 h τ ^ m) (f τ)) : IsBoundedAtImInfty f := by + have hfeq : f = fun τ : ℍ ↦ update (cuspFunction h f) 0 (c 0) (𝕢 h τ) := by + funext τ + rw [update_of_ne (Periodic.qParam_ne_zero _)] + exact (hf τ).unique (hasSum_cuspFunction_of_hasSum_punctured hh hf + (Periodic.norm_qParam_lt_one hh τ.im_pos) (exp_ne_zero _)) + have htend : Tendsto f atImInfty (𝓝 (c 0)) := by + rw [hfeq] + simpa [update_self, Function.comp_def] using + (hasFPowerSeriesOnBall_update hh hf).hasFPowerSeriesAt.continuousAt.tendsto.comp + (qParam_tendsto_atImInfty hh) + -- `IsBoundedAtImInfty f = BoundedAtFilter atImInfty f = (f =O[atImInfty] 1)` by definition. + exact htend.isBigO_one ℝ + lemma hasFPowerSeriesOnBall_cuspFunction {f : ℍ → ℂ} {c : ℕ → ℂ} (hh : 0 < h) (hfanalytic : AnalyticAt ℂ (cuspFunction h f) 0) (hf : ∀ τ : ℍ, HasSum (fun m ↦ c m • 𝕢 h τ ^ m) (f τ)) : From cb2b8fd9a5aed099d511b720d025546487c8b0c0 Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:03:53 +0000 Subject: [PATCH 0586/1300] chore(CategoryTheory/Limits/Shapes/Kernels): remove duplicate definitions (#41316) Remove duplicate definitions `kernel.congr` (already defined in `kernelIsoOfEq`) and `cokernel.congr` (already defined in `cokernelIsoOfEq`). Co-authored-by: morel --- .../CategoryTheory/Limits/Shapes/Kernels.lean | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean index a22d7fc62767be..a76ecb17ce0a6b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean @@ -474,12 +474,7 @@ def kernelIsIsoComp {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] [HasKernel hom := kernel.lift _ (kernel.ι _ ≫ f) (by simp) inv := kernel.lift _ (kernel.ι _ ≫ inv f) (by simp) -set_option backward.defeqAttrib.useBackward true in -/-- Equal maps have isomorphic kernels. -/ -@[simps] def kernel.congr {X Y : C} (f g : X ⟶ Y) [HasKernel f] [HasKernel g] - (h : f = g) : kernel f ≅ kernel g where - hom := kernel.lift _ (kernel.ι f) (by simp [← h]) - inv := kernel.lift _ (kernel.ι g) (by simp [h]) +@[deprecated (since := "2026-07-03")] alias kernel.congr := kernelIsoOfEq lemma isZero_kernel_of_mono {X Y : C} (f : X ⟶ Y) [Mono f] [HasKernel f] : IsZero (kernel f) := @@ -1005,12 +1000,7 @@ def cokernelEpiComp {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [Epi f] [HasCokernel rw [← cancel_epi f, ← Category.assoc] simp) -set_option backward.defeqAttrib.useBackward true in -/-- Equal maps have isomorphic cokernels. -/ -@[simps] def cokernel.congr {X Y : C} (f g : X ⟶ Y) [HasCokernel f] [HasCokernel g] - (h : f = g) : cokernel f ≅ cokernel g where - hom := cokernel.desc _ (cokernel.π g) (by simp [h]) - inv := cokernel.desc _ (cokernel.π f) (by simp [← h]) +@[deprecated (since := "2026-07-03")] alias cokernel.congr := cokernelIsoOfEq lemma isZero_cokernel_of_epi {X Y : C} (f : X ⟶ Y) [Epi f] [HasCokernel f] : IsZero (cokernel f) := @@ -1098,7 +1088,7 @@ variable (f : X ⟶ Y) [HasKernel f] [HasImage f] [HasKernel (factorThruImage f) /-- The kernel of the morphism `X ⟶ image f` is just the kernel of `f`. -/ def kernelFactorThruImage : kernel (factorThruImage f) ≅ kernel f := - (kernelCompMono (factorThruImage f) (image.ι f)).symm ≪≫ (kernel.congr _ _ (by simp)) + (kernelCompMono (factorThruImage f) (image.ι f)).symm ≪≫ (kernelIsoOfEq (by simp)) @[reassoc (attr := simp)] theorem kernelFactorThruImage_hom_comp_ι : @@ -1324,4 +1314,5 @@ set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma coker.condition : Arrow.leftToRight ≫ π C = 0 := by cat_disch end HasCokernels + end CategoryTheory.Limits From ab4e75d4a94f9bb4c0f47bded965aa5504e39422 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:24:24 +0000 Subject: [PATCH 0587/1300] feat(RepresentationTheory/Homological/ContCohomology): add functoriality of continuous cohomology (#41309) --- Mathlib.lean | 1 + .../Continuous/Basic.lean | 160 +++++++++++++++-- .../Continuous/TopRep.lean | 62 +++++-- .../Homological/ContCohomology/Basic.lean | 34 ++-- .../ContCohomology/Functoriality.lean | 165 ++++++++++++++++++ .../Homological/ContCohomology/LowDegree.lean | 10 +- 6 files changed, 389 insertions(+), 43 deletions(-) create mode 100644 Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean diff --git a/Mathlib.lean b/Mathlib.lean index b84b3d08209ed8..7998353606a990 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6386,6 +6386,7 @@ public import Mathlib.RepresentationTheory.FDRep public import Mathlib.RepresentationTheory.FinGroupCharZero public import Mathlib.RepresentationTheory.FiniteIndex public import Mathlib.RepresentationTheory.Homological.ContCohomology.Basic +public import Mathlib.RepresentationTheory.Homological.ContCohomology.Functoriality public import Mathlib.RepresentationTheory.Homological.ContCohomology.LowDegree public import Mathlib.RepresentationTheory.Homological.FiniteCyclic public import Mathlib.RepresentationTheory.Homological.GroupCohomology.Basic diff --git a/Mathlib/RepresentationTheory/Continuous/Basic.lean b/Mathlib/RepresentationTheory/Continuous/Basic.lean index 0dfb3a6fdb8dd3..81d7d2a93610de 100644 --- a/Mathlib/RepresentationTheory/Continuous/Basic.lean +++ b/Mathlib/RepresentationTheory/Continuous/Basic.lean @@ -29,6 +29,14 @@ related basic results. * `ContRepresentation.coind₁ π` is the coinduced continuous representation on the space of continuous functions from `G` to `V` for a continuous representation `π`. +* `ContIntertwiningMap.mapInvariantsOfRes φ f` is the continuous linear map + `π.invariants →L[R] π'.invariants` induced by a monoid homomorphism `φ : H →* G` and a + continuous intertwining map `f : π.restrict φ →ⁱL π'`. + +* `ContRepresentation.coind₁ResMap φ f` is the continuous intertwining map + `π.coind₁.restrict φ →ⁱL π'.coind₁` induced by a continuous group homomorphism `φ : H →ₜ* G` + and a continuous intertwining map `f : π.restrict φ →ⁱL π'`, given by `F ↦ f ∘ F ∘ φ`. + ## Tags continuous representation, algebra -/ @@ -42,12 +50,26 @@ variable (R G V W U : Type*) [Monoid G] [Ring R] [AddCommGroup V] [TopologicalSp /-- A continuous representation of a group `G` on a `R`-module `V` which is a topological addgroup is a homomorphism `G →* V →L[R] V`. -/ -abbrev ContRepresentation := G →* V →L[R] V +structure ContRepresentation where + ofMonoidHom :: + /-- The underlying monoid homomorphism of a continuous representation. -/ + toMonoidHom : G →* V →L[R] V + +instance : FunLike (ContRepresentation R G V) G (V →L[R] V) where + coe π := π.toMonoidHom + coe_injective π₁ π₂ _ := by cases π₁; cases π₂; simp_all + +instance : MonoidHomClass (ContRepresentation R G V) G (V →L[R] V) where + map_one π := π.toMonoidHom.map_one + map_mul π := π.toMonoidHom.map_mul + +lemma ContRepresentation.toMonoidHom_apply (π : ContRepresentation R G V) (g : G) : + π.toMonoidHom g = π g := rfl /-- Every continuous representation "is" a representation. -/ abbrev ContRepresentation.toRepresentation (π : ContRepresentation R G V) : Representation R G V := - .comp ContinuousLinearMap.toLinearMapRingHom.toMonoidHom π + .comp ContinuousLinearMap.toLinearMapRingHom.toMonoidHom π.toMonoidHom variable {R G V W U} @@ -191,6 +213,14 @@ lemma toContinuousLinearMap_sub (f g : π₁ →ⁱL π₂) : lemma sub_apply (f g : π₁ →ⁱL π₂) (v : V) : (f - g) v = f v - g v := rfl +lemma sub_comp (f g : π₂ →ⁱL π₃) (h : π₁ →ⁱL π₂) : + (f - g).comp h = f.comp h - g.comp h := by + ext; simp + +lemma comp_sub (f : π₂ →ⁱL π₃) (g h : π₁ →ⁱL π₂) : + f.comp (g - h) = f.comp g - f.comp h := by + ext; simp + instance instSMul {S : Type*} [Monoid S] [DistribMulAction S W] [SMulCommClass R S W] [ContinuousConstSMul S W] [LinearMap.CompatibleSMul W W S R] : SMul S (π₁ →ⁱL π₂) where @@ -394,15 +424,42 @@ end Equiv variable (R G V) in /-- The trivial continuous representation of a group `G` on a `R`-module `V`. -/ -def trivial : ContRepresentation R G V := 1 +def trivial : ContRepresentation R G V := ofMonoidHom 1 @[simp] lemma trivial_apply (g : G) (v : V) : trivial R G V g v = v := rfl /-- The restriction of a continuous representation along a monoid homomorphism. -/ -@[simps!] +@[implicit_reducible] def restrict {H : Type*} [Monoid H] (π : ContRepresentation R G V) (φ : H →* G) : - ContRepresentation R H V := .comp π φ + ContRepresentation R H V := ofMonoidHom (π.toMonoidHom.comp φ) + +lemma restrict_apply {H : Type*} [Monoid H] (π : ContRepresentation R G V) (φ : H →* G) + (h : H) : π.restrict φ h = π (φ h) := rfl + +@[simp] +lemma restrict_apply_apply {H : Type*} [Monoid H] (π : ContRepresentation R G V) (φ : H →* G) + (h : H) (v : V) : π.restrict φ h v = π (φ h) v := rfl + +/-- The restriction of a continuous intertwining map along a monoid homomorphism. -/ +def _root_.ContIntertwiningMap.restrict {H : Type*} [Monoid H] {π : ContRepresentation R G V} + {π' : ContRepresentation R G W} (φ : H →* G) (f : π →ⁱL π') : + π.restrict φ →ⁱL π'.restrict φ where + __ := f.toContinuousLinearMap + isIntertwining' h := by + ext; simp [f.toContinuousLinearMap_apply, f.isIntertwining] + +lemma _root_.ContIntertwiningMap.restrict_toContinuousLinearMap {H : Type*} [Monoid H] + {π : ContRepresentation R G V} {π' : ContRepresentation R G W} (φ : H →* G) (f : π →ⁱL π') : + (f.restrict φ).toContinuousLinearMap = f.toContinuousLinearMap := rfl + +@[simp] lemma _root_.ContIntertwiningMap.restrict_apply {H : Type*} [Monoid H] + {π : ContRepresentation R G V} {π' : ContRepresentation R G W} (φ : H →* G) + (f : π →ⁱL π') (v : V) : f.restrict φ v = f v := rfl + +lemma _root_.ContIntertwiningMap.restrict_sub {H : Type*} [Monoid H] + {π : ContRepresentation R G V} {π' : ContRepresentation R G W} (φ : H →* G) + (f g : π →ⁱL π') : (f - g).restrict φ = f.restrict φ - g.restrict φ := rfl /-- The submodule of `G`-invariant elements of a continuous representation. -/ def invariants (π : ContRepresentation R G V) : Submodule R V where @@ -422,7 +479,8 @@ def _root_.ContIntertwiningMap.mapInvariants f.toContinuousLinearMap.restrict <| by simp +contextual [f.toContinuousLinearMap_apply, ← f.isIntertwining] --- provided for rewrite +-- provided for rewrite, this lemma should be used when `mapInvariants` is +-- applied to `(homogeneousCochains X).X 0` lemma _root_.ContIntertwiningMap.mapInvariants_apply {π : ContRepresentation R G V} {π' : ContRepresentation R G W} (f : π →ⁱL π') (v : π.invariants) : @@ -434,6 +492,32 @@ lemma _root_.ContIntertwiningMap.mk_mapInvariants_apply (f : π →ⁱL π') (v : V) (hv : v ∈ π.invariants) : f.mapInvariants ⟨v, hv⟩ = f v := rfl +variable {H : Type*} [Monoid H] + +lemma invariants_le_invariants_restrict (π : ContRepresentation R G V) (φ : H →* G) : + π.invariants ≤ (π.restrict φ).invariants := + fun _ hv h ↦ hv (φ h) + +variable {π : ContRepresentation R G V} {π' : ContRepresentation R H W} + +/-- Given a monoid homomorphism `φ : H →* G`, a `G`-representation `π` and an +`H`-representation `π'`, a continuous intertwining map `f : π.restrict φ →ⁱL π'` induces a +continuous linear map `π.invariants →L[R] π'.invariants` between the invariant submodules. -/ +def _root_.ContIntertwiningMap.mapInvariantsOfRes (φ : H →* G) + (f : π.restrict φ →ⁱL π') : π.invariants →L[R] π'.invariants := + f.toContinuousLinearMap.restrict <| by + simp +contextual [f.toContinuousLinearMap_apply, ← f.isIntertwining] + +-- provided for rewriting +lemma _root_.ContIntertwiningMap.mapInvariantsOfRes_apply (φ : H →* G) + (f : π.restrict φ →ⁱL π') (v : π.invariants) : + f.mapInvariantsOfRes φ v = f v := rfl + +@[simp] +lemma _root_.ContIntertwiningMap.mk_mapInvariantsOfRes_apply (φ : H →* G) + (f : π.restrict φ →ⁱL π') (v : V) (hv : v ∈ π.invariants) : + f.mapInvariantsOfRes φ ⟨v, hv⟩ = f v := rfl + -- TODO : define `IsTopologicalMonoid` and then replace `Homeomorph.mulLeft g⁻¹` with the -- `ContinuousMap.mulRight g` to make `coind₁` work for monoids. variable {G H : Type*} [Group G] [TopologicalSpace G] [TopologicalSpace R] @@ -454,20 +538,20 @@ lemma mem_coindV (f : C(H, V)) : f ∈ π.coindV φ ↔ ∀ g h, f (φ g * h) = instance : ContinuousSMul R (π.coindV φ) where continuous_smul := by continuity -variable [IsTopologicalRing R] [IsTopologicalGroup G] [IsTopologicalGroup H] +variable [IsTopologicalGroup G] [IsTopologicalGroup H] /-- The coinduced continuous representation where the action of `H` is defined by `h ↦ f ↦ f ∘ (· * h)`. -/ @[simps] def coind (π : ContRepresentation R G V) : ContRepresentation R H (π.coindV φ) where - toFun h := { + toMonoidHom.toFun h := { toFun | ⟨f, hf⟩ => ⟨f.comp (ContinuousMap.mulRight h), by simp [mul_assoc, hf _]⟩ map_add' _ _ := by simp map_smul' _ _ := by simp cont := continuous_induced_rng.2 <| by simpa using! (ContinuousMap.mulRight h).continuous_precomp.comp continuous_subtype_val} - map_one' := by ext; simp - map_mul' h1 h2 := by ext; simp [ContinuousMap.mulRight_mul] + toMonoidHom.map_one' := by ext; simp + toMonoidHom.map_mul' h1 h2 := by ext; simp [ContinuousMap.mulRight_mul] open ContinuousMap @@ -477,21 +561,24 @@ The action of an element `g : G` is defined by `f ↦ (x ↦ π g (f (g⁻¹ * x This new representation of `G` is isomorphic to the continuous coinduction of the trivial representation of the trivial subgroup of `G`, but the action has been twisted so that the map `const : V → C(G,V)` is an intertwining map. -/ -@[simps] def coind₁ (π : ContRepresentation R G V) : ContRepresentation R G C(G, V) where - toFun g := { + toMonoidHom.toFun g := { toFun f := .comp (π g) (f.comp (ContinuousMap.mulLeft g⁻¹)) map_add' _ _ := by ext; simp map_smul' _ _ := by ext; simp cont := (continuous_postcomp _).comp (continuous_precomp _) } - map_one' := by ext; simp - map_mul' _ _ := by ext; simp [mul_assoc] + toMonoidHom.map_one' := by ext; simp + toMonoidHom.map_mul' _ _ := by ext; simp [mul_assoc] + +@[simp] +lemma coind₁_apply_apply (π : ContRepresentation R G V) (g : G) (f : C(G, V)) (x : G) : + π.coind₁ g f x = π g (f (g⁻¹ * x)) := rfl /-- The functoriality of `coind₁`. -/ @[simps] -def coind₁Map (π₁ : ContRepresentation R G V) (π₂ : ContRepresentation R G W) (f : π₁ →ⁱL π₂) : +def coind₁Map {π₁ : ContRepresentation R G V} {π₂ : ContRepresentation R G W} (f : π₁ →ⁱL π₂) : coind₁ π₁ →ⁱL coind₁ π₂ where toFun := (f : ContinuousMap _ _).comp map_add' _ _ := by ext; simp @@ -515,4 +602,47 @@ def coind₁Equivcoind : (coind₁ (.trivial R (⊥ : Subgroup G) V)).Equiv ContinuousLinearEquiv.ofEq _ _ (by simp [SetLike.ext_iff])) <| fun g ↦ by simp [Subsingleton.elim g 1, ContinuousLinearMap.one_def] +section coind₁ResMap + +variable [ContinuousSMul R U] {π' : ContRepresentation R H W} {π} + +/-- Given a continuous group homomorphism `φ : H →ₜ* G`, precomposition with `φ` defines a +continuous intertwining map `π.coind₁.restrict φ →ⁱL (π.restrict φ).coind₁`. -/ +def coind₁Res (φ : H →ₜ* G) (π : ContRepresentation R G V) : + π.coind₁.restrict (φ : H →* G) →ⁱL (π.restrict (φ : H →* G)).coind₁ where + __ := ContinuousMap.compCLM R V φ.toContinuousMap + isIntertwining' h := by + ext F x + simp [map_mul, map_inv] + +@[simp] +lemma coind₁Res_apply (φ : H →ₜ* G) (π : ContRepresentation R G V) (F : C(G, V)) (x : H) : + coind₁Res φ π F x = F (φ x) := rfl + +/-- Given a continuous group homomorphism `φ : H →ₜ* G`, a continuous intertwining map +`f : π.restrict φ →ⁱL π'` induces a continuous intertwining map +`π.coind₁.restrict φ →ⁱL π'.coind₁`, sending `F : C(G, V)` to `f ∘ F ∘ φ : C(H, W)`. -/ +def coind₁ResMap (φ : H →ₜ* G) (f : π.restrict (φ : H →* G) →ⁱL π') : + π.coind₁.restrict (φ : H →* G) →ⁱL π'.coind₁ := + (coind₁Map f).comp (coind₁Res φ π) + +@[simp] +lemma coind₁ResMap_apply (φ : H →ₜ* G) (f : π.restrict (φ : H →* G) →ⁱL π') (F : C(G, V)) + (x : H) : coind₁ResMap φ f F x = f (F (φ x)) := rfl + +/-- The naturality of `coind₁ι` with respect to `coind₁ResMap`. -/ +lemma coind₁ResMap_comp_coind₁ι_restrict (φ : H →ₜ* G) (f : π.restrict (φ : H →* G) →ⁱL π') : + (coind₁ResMap φ f).comp (π.coind₁ι.restrict (φ : H →* G)) = π'.coind₁ι.comp f := rfl + +lemma coind₁Map_comp_coind₁ResMap (φ : H →ₜ* G) {σ : ContRepresentation R H U} + (f : π.restrict φ →ⁱL π') (g : π' →ⁱL σ) : + (coind₁Map g).comp (coind₁ResMap φ f) = coind₁ResMap φ (g.comp f) := rfl + +lemma coind₁ResMap_comp_coind₁Map_restrict (φ : H →ₜ* G) {ρ : ContRepresentation R G U} + (g : ρ →ⁱL π) (f : π.restrict (φ : H →* G) →ⁱL π') : + (coind₁ResMap φ f).comp ((coind₁Map g).restrict (φ : H →* G)) = + coind₁ResMap φ (f.comp (g.restrict (φ : H →* G))) := rfl + +end coind₁ResMap + end ContRepresentation diff --git a/Mathlib/RepresentationTheory/Continuous/TopRep.lean b/Mathlib/RepresentationTheory/Continuous/TopRep.lean index a9367b8fb943e9..54963a10aee64a 100644 --- a/Mathlib/RepresentationTheory/Continuous/TopRep.lean +++ b/Mathlib/RepresentationTheory/Continuous/TopRep.lean @@ -14,6 +14,11 @@ public import Mathlib.RepresentationTheory.Continuous.Basic This file defines the category `TopRep k G` of topological representations of a monoid `G` over a topological ring `k`, and shows that it is equivalent to the category `Action (TopModuleCat k) G`. + +For a topological group `G` we define the invariants functor `TopRep.invariantsFunctor`, the +coinduction functor `TopRep.coind₁Functor`, the restriction functor `TopRep.resFunctor` along a +group homomorphism `φ : H →* G`, and the morphism `TopRep.invariantsResMap φ f` between invariant +submodules induced by a morphism `f : res φ X ⟶ Y`. -/ @[expose] public section @@ -22,8 +27,7 @@ universe w u v /-- The category of topological representations of a monoid `G` over a topological ring `k`, and their morphisms. -/ -structure TopRep (k : Type u) (G : Type v) [TopologicalSpace k] [Ring k] - [IsTopologicalRing k] [Monoid G] where +structure TopRep (k : Type u) (G : Type v) [Ring k] [TopologicalSpace k] [Monoid G] where private mk :: /-- the underlying type of an object in `TopRep k G` -/ V : Type w @@ -38,7 +42,7 @@ structure TopRep (k : Type u) (G : Type v) [TopologicalSpace k] [Ring k] namespace TopRep variable {k : Type u} {G : Type v} {X Y : Type w} [TopologicalSpace k] [Ring k] - [IsTopologicalRing k] [Monoid G] [AddCommGroup X] [Module k X] [TopologicalSpace X] + [Monoid G] [AddCommGroup X] [Module k X] [TopologicalSpace X] [IsTopologicalAddGroup X] [ContinuousSMul k X] [AddCommGroup Y] [Module k Y] [TopologicalSpace Y] [IsTopologicalAddGroup Y] [ContinuousSMul k Y] {ρ : ContRepresentation k G X} {σ : ContRepresentation k G Y} @@ -155,7 +159,7 @@ instance : Preadditive (TopRep k G) where section Linear variable {k : Type u} {G : Type v} {X Y : Type w} [TopologicalSpace k] [CommRing k] - [IsTopologicalRing k] [Monoid G] [AddCommGroup X] [Module k X] [TopologicalSpace X] + [Monoid G] [AddCommGroup X] [Module k X] [TopologicalSpace X] [IsTopologicalAddGroup X] [ContinuousSMul k X] [AddCommGroup Y] [Module k Y] [TopologicalSpace Y] [IsTopologicalAddGroup Y] [ContinuousSMul k Y] {ρ : ContRepresentation k G X} {σ : ContRepresentation k G Y} {A B C : TopRep k G} @@ -192,8 +196,9 @@ def toActionTopModFunc : TopRep k G ⥤ Action (TopModuleCat k) G where /-- The functor sending an object in `Action (TopModuleCat k) G` to the corresponding topological representation. -/ def fromActionTopModFunc : Action (TopModuleCat.{w} k) G ⥤ TopRep k G where - obj X := .of <| (TopModuleCat.endRingEquiv X.V).toMonoidHom.comp X.ρ - map {X Y} f := ofHom ⟨f.hom.hom, fun g ↦ by simpa using congr(TopModuleCat.Hom.hom $(f.comm g))⟩ + obj X := .of <| .ofMonoidHom <| (TopModuleCat.endRingEquiv X.V).toMonoidHom.comp X.ρ + map {X Y} f := ofHom ⟨f.hom.hom, fun g ↦ by + simpa [← toMonoidHom_apply] using congr(TopModuleCat.Hom.hom $(f.comm g))⟩ /-- The unit isomorphism of the equivalence `TopRepIsoActionTop`. -/ def toActionFromAction (X : TopRep.{w} k G) : @@ -235,8 +240,7 @@ abbrev invariantsFunctor : TopRep k G ⥤ TopModuleCat k where instance : (invariantsFunctor k G).Additive where -instance {k : Type u} [CommRing k] [TopologicalSpace k] [IsTopologicalRing k] : - (invariantsFunctor k G).Linear k where +instance {k : Type u} [CommRing k] [TopologicalSpace k] : (invariantsFunctor k G).Linear k where /-- The top rep induced by the coinduced representation. -/ abbrev coind₁ (A : TopRep k G) : TopRep k G := of A.ρ.coind₁ @@ -246,16 +250,52 @@ variable (k G) in The `G` action is defined by `g • f := x ↦ g • f (g⁻¹ * x)`. -/ abbrev coind₁Functor : TopRep k G ⥤ TopRep k G where obj := coind₁ - map φ := ofHom <| ContRepresentation.coind₁Map _ _ φ.hom + map φ := ofHom <| ContRepresentation.coind₁Map φ.hom instance : (TopRep.coind₁Functor k G).Additive where -instance {k : Type u} [CommRing k] [TopologicalSpace k] [IsTopologicalRing k] : - (coind₁Functor k G).Linear k where +instance {k : Type u} [CommRing k] [TopologicalSpace k] : (coind₁Functor k G).Linear k where /-- The constant function `rep ⟶ C(G, rep)` as a natural transformation. -/ @[implicit_reducible, simps] def coind₁ι : 𝟭 (TopRep k G) ⟶ coind₁Functor k G where app rep := ofHom rep.ρ.coind₁ι +/-- The restriction of a topological representation along a monoid homomorphism. -/ +abbrev res {H : Type*} [Monoid H] (φ : H →* G) (A : TopRep k G) : TopRep k H := of (A.ρ.restrict φ) + +/-- The functor taking a topological `G`-representation to a topological `H`-representation +along a monoid homomorphism `φ : H →* G`. -/ +abbrev resFunctor {H : Type*} [Monoid H] (φ : H →* G) : + TopRep k G ⥤ TopRep k H where + obj := res φ + map f := ofHom <| f.hom.restrict φ + +section invariantsResMap + +variable {G H : Type*} [Group G] + +@[simp] +lemma resFunctor_map_hom [Monoid H] (φ : H →* G) {A B : TopRep k G} (f : A ⟶ B) : + ((resFunctor φ).map f).hom = f.hom.restrict φ := rfl + +variable [Group H] + +/-- The morphism between invariant submodules induced by a morphism `res φ X ⟶ Y` of +topological `H`-representations, where `φ : H →* G` is a group homomorphism. -/ +def invariantsResMap (φ : H →* G) {X : TopRep k G} {Y : TopRep k H} (f : res φ X ⟶ Y) : + X.invariants ⟶ Y.invariants := + TopModuleCat.ofHom (f.hom.mapInvariantsOfRes φ) + +lemma invariantsResMap_comp {X : TopRep k G} {Y Y' : TopRep k H} (φ : H →* G) + (f : res φ X ⟶ Y) (g : Y ⟶ Y') : + invariantsResMap φ (f ≫ g) = invariantsResMap φ f ≫ (invariantsFunctor k H).map g := rfl + +lemma invariantsResMap_map_comp {X X' : TopRep k G} {Y : TopRep k H} (φ : H →* G) + (f : X ⟶ X') (g : res φ X' ⟶ Y) : + invariantsResMap φ ((resFunctor φ).map f ≫ g) = + (invariantsFunctor k G).map f ≫ invariantsResMap φ g := rfl + +end invariantsResMap + end TopRep diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean index 889894b5cc1f9d..c7fdc66d39ca92 100644 --- a/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean @@ -43,7 +43,7 @@ See `TopRep.d`. @[expose] public section -variable {k G : Type*} [Ring k] [Group G] [TopologicalSpace k] [IsTopologicalRing k] +variable {k G : Type*} [Ring k] [Group G] [TopologicalSpace k] [TopologicalSpace G] [IsTopologicalGroup G] open CategoryTheory ContRepresentation Limits @@ -69,7 +69,7 @@ lemma d_succ (X : TopRep k G) (n : ℕ) : lemma hom_d_succ (X : TopRep k G) (n : ℕ) : (d X (n + 1)).hom = (resolutionX X (n + 1)).ρ.coind₁ι - - ContRepresentation.coind₁Map _ _ (d X n).hom := + ContRepresentation.coind₁Map (d X n).hom := rfl @[reassoc (attr := simp)] @@ -90,15 +90,20 @@ The `G`-invariant submodules of it is the homogeneous cochains (shifted by one). abbrev resolution (X : TopRep k G) : CochainComplex (TopRep k G) ℕ := CochainComplex.of (resolutionX X) (d X) (d_comp_d X) +/-- The shifted object in resolution by `1` degree. -/ +abbrev resolution'X (X : TopRep k G) (n : ℕ) : TopRep k G := resolutionX X (n + 1) + /-- The shifted boundary map of the resolution. -/ +@[implicit_reducible] def resolution'd (X : TopRep k G) (n : ℕ) : - resolutionX X (n + 1) ⟶ resolutionX X (n + 1 + 1) := d X (n + 1) + resolution'X X n ⟶ resolution'X X (n + 1) := d X (n + 1) -lemma resolution'd₀_eq (X : TopRep k G) : resolution'd X 0 = d X 1 := rfl +lemma resolution'd_eq (X : TopRep k G) (n : ℕ) : + resolution'd X n = d X (n + 1) := rfl /-- The shifted resolution of a topological representation by `1` degree. -/ abbrev resolution' (X : TopRep k G) : CochainComplex (TopRep k G) ℕ := - CochainComplex.of (fun i ↦ (resolution X).X (i + 1)) + CochainComplex.of (resolution'X X) (resolution'd X) (fun n ↦ d_comp_d X (n + 1)) set_option allowUnsafeReducibility true in @@ -109,15 +114,20 @@ abbrev homogeneousCochains (X : TopRep k G) : CochainComplex (TopModuleCat k) ℕ := ((invariantsFunctor k G).mapHomologicalComplex _).obj (resolution' X) -lemma homogeneousCochains.d₀₁_eq (X : TopRep k G) : - (homogeneousCochains X).d 0 1 = (invariantsFunctor k G).map (d X 1) := by - rw [← resolution'd₀_eq]; rfl +lemma homogeneousCochains.d_eq (X : TopRep k G) (i : ℕ) : + (homogeneousCochains X).d i (i + 1) = + (invariantsFunctor k G).map (d X (i + 1)) := by + dsimp only + rw [← resolution'd_eq, CochainComplex.of_d] -lemma homogeneousCochains.d₀₁_apply (X : TopRep k G) (σ : (homogeneousCochains X).X 0) : - ((homogeneousCochains X).d 0 1).hom σ = (d X 1).hom σ := rfl +lemma homogeneousCochains.d_apply (X : TopRep k G) (i : ℕ) + (σ : (homogeneousCochains X).X i) : + ((homogeneousCochains X).d i (i + 1)).hom σ = (d X (i + 1)).hom σ := by + rw [homogeneousCochains.d_eq] + dsimp [ContIntertwiningMap.mapInvariants_apply] -/-- The continuous cohomology of a continuous representation defined -by `continuousCohomologyFunctor`. -/ +/-- The continuous cohomology of a continuous representation defined by taking homology +of the homogeneous cochains. -/ noncomputable abbrev _root_.continuousCohomology (n : ℕ) (A : TopRep k G) : TopModuleCat k := (homogeneousCochains A).homology n diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean new file mode 100644 index 00000000000000..8e7e4e8a453839 --- /dev/null +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean @@ -0,0 +1,165 @@ +/- +Copyright (c) 2026 Yunzhou Xie. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Edison Xie, Richard Hill +-/ +module + +public import Mathlib.RepresentationTheory.Homological.ContCohomology.Basic + +/-! +# Functoriality of continuous cohomology + +Given topological groups `G` and `H`, a continuous group homomorphism `φ : H →ₜ* G`, a topological +representation `X` of `G`, a topological representation `Y` of `H`, and a morphism of topological +`H`-representations `f : res φ X ⟶ Y`, we construct a cochain map +`homogeneousCochains X ⟶ homogeneousCochains Y` and hence maps on continuous cohomology +`Hⁿ(G, X) ⟶ Hⁿ(H, Y)`. + +## Main definitions + +* `ContinuousCohomology.cochainsMap φ f` : the cochain map + `homogeneousCochains X ⟶ homogeneousCochains Y` induced by `φ : H →ₜ* G` and + `f : res φ X ⟶ Y`, sending an invariant function `σ : C(G, C(G, ⋯))` to `f ∘ σ ∘ φ`. +* `ContinuousCohomology.map φ f n` : the induced map `Hⁿ(G, X) ⟶ Hⁿ(H, Y)` on continuous + cohomology. +-/ + +@[expose] public section + +universe u v + +open CategoryTheory + +namespace ContinuousCohomology + +open TopRep ContRepresentation + +variable {k : Type u} {G H K : Type v} [Ring k] [TopologicalSpace k] + [Group G] [TopologicalSpace G] [IsTopologicalGroup G] + [Group H] [TopologicalSpace H] [IsTopologicalGroup H] + [Group K] [TopologicalSpace K] [IsTopologicalGroup K] + {X : TopRep k G} {Y : TopRep k H} {Z : TopRep k K} + +set_option allowUnsafeReducibility true in +attribute [local reducible] CategoryTheory.Functor.mapHomologicalComplex + +/-- The morphisms between the levels of the standard resolutions of `X` and `Y` induced by a +continuous group homomorphism `φ : H →ₜ* G` and a morphism `f : res φ X ⟶ Y`, given by +`F ↦ f ∘ F ∘ φ`. -/ +def resolutionMap (φ : H →ₜ* G) (f : res φ X ⟶ Y) : + (i : ℕ) → res φ (resolutionX X i) ⟶ resolutionX Y i + | 0 => f + | i + 1 => ofHom (coind₁ResMap φ (resolutionMap φ f i).hom) + +@[simp] +lemma resolutionMap_zero (φ : H →ₜ* G) (f : res φ X ⟶ Y) : + resolutionMap φ f 0 = f := rfl + +lemma resolutionMap_succ (φ : H →ₜ* G) (f : res φ X ⟶ Y) (i : ℕ) : + resolutionMap φ f (i + 1) = ofHom (coind₁ResMap φ (resolutionMap φ f i).hom) := rfl + +@[simp] +lemma resolutionMap_id (X : TopRep k G) (i : ℕ) : + resolutionMap (ContinuousMonoidHom.id G) (𝟙 X) i = 𝟙 (resolutionX X i) := by + induction i with + | zero => rfl + | succ i ih => + rw [resolutionMap_succ, ih] + ext F x + rfl + +lemma resolutionMap_comp (φ : H →ₜ* G) (ψ : K →ₜ* H) (f : res φ X ⟶ Y) (g : res ψ Y ⟶ Z) + (i : ℕ) : + resolutionMap (φ.comp ψ) (X := X) ((resFunctor (ψ : K →* H)).map f ≫ g) i = + (resFunctor (ψ : K →* H)).map (resolutionMap φ f i) ≫ resolutionMap ψ g i := by + induction i with + | zero => rfl + | succ i ih => + rw [resolutionMap_succ, resolutionMap_succ, resolutionMap_succ, ih] + ext F x + rfl + +/-- The maps `resolutionMap φ f` commute with the differentials of the resolutions. -/ +lemma resolutionMap_comp_d (φ : H →ₜ* G) (f : res φ X ⟶ Y) (i : ℕ) : + resolutionMap φ f i ≫ d Y i = + (resFunctor (φ : H →* G)).map (d X i) ≫ resolutionMap φ f (i + 1) := by + induction i with + | zero => rfl + | succ i ih => + ext : 1 + replace ih := congr($(ih).hom) + simp only [TopRep.hom_comp, resolutionMap_succ, TopRep.hom_ofHom, hom_d_succ, + ContIntertwiningMap.restrict_sub, ContIntertwiningMap.sub_comp, + ContIntertwiningMap.comp_sub, coind₁Map_comp_coind₁ResMap, + coind₁ResMap_comp_coind₁Map_restrict] at ih ⊢ + rw [ih, ← coind₁ResMap_comp_coind₁ι_restrict] + +/-- The cochain map `homogeneousCochains X ⟶ homogeneousCochains Y` induced by a continuous +group homomorphism `φ : H →ₜ* G` and a morphism of topological `H`-representations +`f : res φ X ⟶ Y`, sending an invariant function `σ : C(G, C(G, ⋯))` to `f ∘ σ ∘ φ`. -/ +@[simps! -isSimp f f_hom] +def cochainsMap (φ : H →ₜ* G) (f : res φ X ⟶ Y) : + homogeneousCochains X ⟶ homogeneousCochains Y where + f i := invariantsResMap φ (resolutionMap φ f (i + 1)) + comm' i j (hij : _ = _) := by + subst hij + rw [homogeneousCochains.d_eq, homogeneousCochains.d_eq, ← invariantsResMap_comp, + resolutionMap_comp_d, invariantsResMap_map_comp] + +@[simp] +lemma cochainsMap_id (X : TopRep k G) : + cochainsMap (ContinuousMonoidHom.id G) (𝟙 X) = 𝟙 (homogeneousCochains X) := by + ext i : 1 + rw [cochainsMap_f, resolutionMap_id] + ext v + rfl + +@[reassoc] +lemma cochainsMap_comp (φ : H →ₜ* G) (ψ : K →ₜ* H) (f : res φ X ⟶ Y) (g : res ψ Y ⟶ Z) : + cochainsMap (φ.comp ψ) (X := X) ((resFunctor (ψ : K →* H)).map f ≫ g) = + cochainsMap φ f ≫ cochainsMap ψ g := by + ext i v x + exact congr($(resolutionMap_comp φ ψ f g (i + 1)).hom v.1 x) + +/-- The map `Zⁿ(G, X) ⟶ Zⁿ(H, Y)` on cocycles induced by a continuous group homomorphism +`φ : H →ₜ* G` and a morphism of topological `H`-representations `f : res φ X ⟶ Y`. -/ +noncomputable abbrev cocyclesMap (φ : H →ₜ* G) (f : res φ X ⟶ Y) (n : ℕ) : + cocycles X n ⟶ cocycles Y n := + HomologicalComplex.cyclesMap (cochainsMap φ f) n + +@[simp] +lemma cocyclesMap_id (X : TopRep k G) (n : ℕ) : + cocyclesMap (ContinuousMonoidHom.id G) (𝟙 X) n = 𝟙 _ := by + simp [cocyclesMap] + +@[reassoc] +lemma cocyclesMap_comp (φ : H →ₜ* G) (ψ : K →ₜ* H) (f : res φ X ⟶ Y) (g : res ψ Y ⟶ Z) + (n : ℕ) : + cocyclesMap (φ.comp ψ) (X := X) ((resFunctor (ψ : K →* H)).map f ≫ g) n = + cocyclesMap φ f n ≫ cocyclesMap ψ g n := by + simp [cocyclesMap, ← HomologicalComplex.cyclesMap_comp, ← cochainsMap_comp] + +/-- The map `Hⁿ(G, X) ⟶ Hⁿ(H, Y)` on continuous cohomology induced by a continuous group +homomorphism `φ : H →ₜ* G` and a morphism of topological `H`-representations +`f : res φ X ⟶ Y`. -/ +noncomputable abbrev map (φ : H →ₜ* G) (f : res φ X ⟶ Y) (n : ℕ) : + continuousCohomology n X ⟶ continuousCohomology n Y := + HomologicalComplex.homologyMap (cochainsMap φ f) n + +@[reassoc] +theorem π_map (φ : H →ₜ* G) (f : res φ X ⟶ Y) (n : ℕ) : + π X n ≫ map φ f n = cocyclesMap φ f n ≫ π Y n := by + simp [map, cocyclesMap] + +@[simp] +lemma map_id (X : TopRep k G) (n : ℕ) : + map (ContinuousMonoidHom.id G) (𝟙 X) n = 𝟙 _ := by + simp [map] + +@[reassoc] +lemma map_comp (φ : H →ₜ* G) (ψ : K →ₜ* H) (f : res φ X ⟶ Y) (g : res ψ Y ⟶ Z) (n : ℕ) : + map (φ.comp ψ) (X := X) ((resFunctor (ψ : K →* H)).map f ≫ g) n = map φ f n ≫ map ψ g n := by + simp [map, ← HomologicalComplex.homologyMap_comp, ← cochainsMap_comp] + +end ContinuousCohomology diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean index 9bbafc6b5e7407..3b56514a64514b 100644 --- a/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean @@ -20,7 +20,7 @@ namespace ContinuousCohomology open CategoryTheory Functor TopRep ContRepresentation -variable {k G : Type*} [CommRing k] [Group G] [TopologicalSpace k] [IsTopologicalRing k] +variable {k G : Type*} [Ring k] [Group G] [TopologicalSpace k] [TopologicalSpace G] [IsTopologicalGroup G] set_option allowUnsafeReducibility true in @@ -31,8 +31,8 @@ variable (X : TopRep k G) lemma cocycles₀IsoAux (σ : (homogeneousCochains X).X 0) (hσ : σ ∈ ((homogeneousCochains X).d 0 1).hom.ker) : σ.1 1 ∈ X.ρ.invariants := by simp only [Nat.reduceAdd, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, - Subtype.ext_iff, homogeneousCochains.d₀₁_apply _] at hσ - simp only [Nat.reduceAdd, mem_invariants] + Subtype.ext_iff, homogeneousCochains.d_apply _] at hσ + simp only [mem_invariants] intro g rw [d_succ, hom_sub, hom_ofHom, ContIntertwiningMap.sub_apply, d_zero, ZeroMemClass.coe_zero, sub_eq_zero] at hσ @@ -48,7 +48,7 @@ lemma mem_const_resol₀ (x : X) (hx : x ∈ X.ρ.invariants) : lemma cocycles₀IsoAux' (x : X) (h : ContinuousMap.const G x ∈ ((resolution' X).X 0).ρ.invariants) : ⟨ContinuousMap.const G x, h⟩ ∈ ((homogeneousCochains X).d 0 1).hom.ker := by rw [LinearMap.mem_ker, Subtype.ext_iff, ContinuousLinearMap.coe_coe, - homogeneousCochains.d₀₁_apply] + homogeneousCochains.d_apply] simp [d_succ, hom_sub, ContIntertwiningMap.sub_apply, d_zero] /-- The isomorphism between the zeroth cocycles and the kernel of the zeroth differential. -/ @@ -68,7 +68,7 @@ def d₀kerIso : ((homogeneousCochains X).d 0 1).hom.ker ≃L[k] X.ρ.invariants left_inv := fun ⟨⟨(x : C(G, X)), hx'⟩, hx⟩ ↦ by ext g rw [LinearMap.mem_ker, Subtype.ext_iff, ContinuousLinearMap.coe_coe, - homogeneousCochains.d₀₁_apply] at hx + homogeneousCochains.d_apply] at hx simp only [Nat.reduceAdd, d_succ, d_zero, ConcreteCategory.hom_ofHom, hom_sub, ContIntertwiningMap.sub_apply, coind₁ι_toFun, coind₁Map_toFun, ZeroMemClass.coe_zero, sub_eq_zero, ContinuousMap.const_apply] at hx ⊢ From 5b558da63b4548357b5c6ec2168b39e887671d39 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:35:35 +0000 Subject: [PATCH 0588/1300] refactor(NumberTheory/NumberField/ExistsRamified): extract `Algebra.IsUnramifiedIn` version (#41323) This PR extracts an `Algebra.IsUnramifiedIn` version of the existence of ramified primes in number fields. Co-authored-by: tb65536 --- .../NumberField/ExistsRamified.lean | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean index 35f327d8b447ed..39c74954022c07 100644 --- a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean +++ b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean @@ -27,20 +27,25 @@ open scoped NumberField nonZeroDivisors variable {K 𝒪 : Type*} [Field K] [NumberField K] [CommRing 𝒪] [Algebra 𝒪 K] variable [IsIntegralClosure 𝒪 ℤ K] +/-- If `K` is a number field with positive rank, then some prime is ramified in `K`. -/ +lemma NumberField.exists_not_isUnramifiedIn (H : Module.finrank ℚ K ≠ 1) : + ∃ p : ℕ, p.Prime ∧ ¬ Algebra.IsUnramifiedIn 𝒪 (Ideal.span {(p : ℤ)}) := by + have : 0 < Module.finrank ℚ K := Module.finrank_pos + have : 2 < |discr K| := abs_discr_gt_two (by lia) + obtain ⟨p, hp1, hp2⟩ := (discr K).exists_prime_and_dvd (by linarith) + use p.natAbs, p.prime_iff_natAbs_prime.mp hp1 + simpa [← not_dvd_discr_iff_isUnramifiedIn K 𝒪 hp1] + /-- If `K` is a number field with positive rank, then there exists some maximal ideal of `𝓞 K` that is ramified over `ℤ`. -/ lemma NumberField.exists_not_isUnramifiedAt_int (H : Module.finrank ℚ K ≠ 1) : ∃ (P : Ideal 𝒪) (_ : P.IsMaximal), ¬ Algebra.IsUnramifiedAt ℤ P := by + obtain ⟨p, hp1, hp2⟩ := NumberField.exists_not_isUnramifiedIn (𝒪 := 𝒪) H have := (IsIntegralClosure.algebraMap_injective 𝒪 ℤ K).isDomain have := IsIntegralClosure.isDedekindDomain ℤ ℚ K 𝒪 - have := CharZero.of_module (R := 𝒪) K - have := Module.finrank_pos (R := ℚ) (M := K) - have := NumberField.abs_discr_gt_two (K := K) (by lia) - obtain ⟨q, hq, hqK⟩ := Int.exists_prime_and_dvd (n := discr K) (by zify; linarith) - have := (not_dvd_discr_iff_forall_mem K 𝒪 hq).not_right.mp hqK - push Not at this - obtain ⟨P, hP, h, H⟩ := this - exact ⟨P, hP.isMaximal (by aesop), H⟩ + have := IsIntegralClosure.isTorsionFree ℤ (A := 𝒪) K + have := IsIntegralClosure.isIntegral_algebra ℤ (A := 𝒪) K + grind [Algebra.isUnramifiedIn_iff_forall_of_isDedekindDomain] /-- Any number field that is unramified over `ℚ` has rank `1`. -/ lemma NumberField.finrank_eq_one_of_unramified [Algebra.Unramified ℤ 𝒪] : From 08fd0d06ca41cb1355b875e2ed691d532e82227b Mon Sep 17 00:00:00 2001 From: smorel394 <67864981+smorel394@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:54:09 +0000 Subject: [PATCH 0589/1300] feat(CategoryTheory/Preadditive/FreydCategory/RightFreyd): the right Freyd category has cokernels (#41295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If `V` is a preadditive category with binary biproducts, its right Freyd category (defined in #41294) has cokernels. - [x] depends on: #41292 - [x] depends on: #41294 Co-authored-by: morel Co-authored-by: Joël Riou <37772949+joelriou@users.noreply.github.com> --- .../Preadditive/FreydCategory/RightFreyd.lean | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean b/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean index b26f77866360c1..279b5749275e32 100644 --- a/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean +++ b/Mathlib/CategoryTheory/Preadditive/FreydCategory/RightFreyd.lean @@ -13,8 +13,16 @@ public import Mathlib.CategoryTheory.Quotient.Preadditive Let `V` be a preadditive category. The right Freyd category of `V` is the quotient of `Arrow V` by the right homotopy relation. (This is simply called "Freyd category" -in the reference.) +in the reference.) This is a preadditive category with a fully +faithful additive functor `RightFreyd.functor : V ⥤ RightFreyd V`. +We also show that, if `V` has binary biproducts, then `RightFreyd V` has cokernels. In fact +we construct, given a morphism `f : u ⟶ v` in `Arrow V`, a morphism +`Candidate.π f : v ⟶ Candidate.cokernel f` in `Arrow V` such that +`f ≫ Candidate.π f` is right homotopic to `0` (see `Candidate.condition`). +This allows us to define a cokernel cofork for `(quotient V).map f` (see +`Candidate.cokernelCofork`), and we show in `Candidate.isColimitCokernelCofork` that this is +a cokernel cofork. ## References * [Posur, S., *A constructive approach to Freyd categories*][posur2021Freyd] @@ -135,6 +143,71 @@ instance : (functor V).Faithful where end Functor +variable [HasBinaryBiproducts V] + +variable {u v : Arrow V} (f : u ⟶ v) + +namespace Candidate + +/-- If `f` is a morphism of `Arrow V`, this is a "candidate cokernel" of `f`, i.e. an object +in `Arrow V` whose image in `RightFreyd V` will be a cokernel of the image of `f`. -/ +abbrev cokernel := Arrow.mk (biprod.desc v.hom f.right) + +set_option backward.isDefEq.respectTransparency false in +/-- For `f : u ⟶ v` a morphism in `Arrow V`, this is the morphism `v ⟶ cokernel f` from `v` to +the "candidate cokernel" of `f`, whose image in `RightFreyd V` will be the projection to +the cokernel of the image of `f`. -/ +def π : v ⟶ cokernel f := Arrow.homMk biprod.inl (𝟙 v.right) + +set_option backward.isDefEq.respectTransparency false in +/-- The right homotopy expressing that `f ≫ π f` is sent to `0` in `RightFreyd V`. -/ +def condition : RightHomotopy (f ≫ π f) 0 where + hom := biprod.inr + comm := by simp [π] + +set_option backward.isDefEq.respectTransparency false in +instance : Epi ((quotient V).map (π f)) := + have : IsIso ((π f).right) := by simp only [π, homMk_right]; infer_instance + epi_of_isIso_right _ + +variable {w : Arrow V} (g : v ⟶ w) (h : RightHomotopy (f ≫ g) 0) + +set_option backward.isDefEq.respectTransparency false in +/-- If `f : u ⟶ v` and `g : v ⟶ w` are morphisms in `Arrow V` such that `f ≫ g` is right +homotopic to `0`, this is the morphism from the "candidate cokernel" of `f` to `w` defined +from the right homotopy. -/ +def desc : cokernel f ⟶ w := + Arrow.homMk (biprod.desc g.left h.hom) g.right (biprod.hom_ext' _ _ (by simp) + (by simp [← h.comm])) + +set_option backward.isDefEq.respectTransparency false in +@[reassoc (attr := simp)] +lemma π_desc : π f ≫ desc f g h = g := by ext <;> simp [π, desc] + +/-- For `f` a morphism in `Arrow V`, this is a cokernel cofork of `(quotient V).map f`. -/ +def cokernelCofork : CokernelCofork ((quotient V).map f) := + CokernelCofork.ofπ ((quotient V).map (Candidate.π f)) + (eq_of_rightHomotopy _ _ (Candidate.condition f)) + +set_option backward.isDefEq.respectTransparency false in +/-- For `f` a morphism in `Arrow V`, the cokernel cofork of `(quotient V).map f` constructed +in `cokernelCofork` is a colimit cofork. -/ +def isColimitCokernelCofork : IsColimit (cokernelCofork f) := + CokernelCofork.IsColimit.ofπ' _ + (eq_of_rightHomotopy _ _ (Candidate.condition f)) + (fun g hg ↦ Nonempty.some (by + obtain ⟨g, rfl⟩ := (quotient V).map_surjective g + exact ⟨(quotient V).map (desc f g (homotopyOfEq _ _ hg)), + by simp [← Functor.map_comp]⟩)) + +end Candidate + +/-- The category `RightFreyd V` has all cokernels if `V` has binary biproducts. -/ +instance : HasCokernels (RightFreyd V) where + has_colimit f := ⟨by + obtain ⟨f, rfl⟩ := (quotient V).map_surjective f + exact ⟨_, Candidate.isColimitCokernelCofork f⟩⟩ + end RightFreyd end CategoryTheory.Preadditive From 96ec947e9b66a5e6059131fc9c6d13a14cef756e Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Fri, 3 Jul 2026 15:04:32 +0000 Subject: [PATCH 0590/1300] feat(SimpleRing/DivisionRing): simple module is preserved by ModuleCat equivs (#41233) --- Mathlib.lean | 1 + Mathlib/Algebra/Category/ModuleCat/Basic.lean | 7 +++ .../Limits/Shapes/ZeroMorphisms.lean | 4 ++ Mathlib/CategoryTheory/Simple.lean | 20 +++++++ .../RingTheory/SimpleRing/DivisionRing.lean | 59 +++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 Mathlib/RingTheory/SimpleRing/DivisionRing.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7998353606a990..ae8a93fa6b2aba 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6992,6 +6992,7 @@ public import Mathlib.RingTheory.SimpleModule.WedderburnArtin public import Mathlib.RingTheory.SimpleRing.Basic public import Mathlib.RingTheory.SimpleRing.Congr public import Mathlib.RingTheory.SimpleRing.Defs +public import Mathlib.RingTheory.SimpleRing.DivisionRing public import Mathlib.RingTheory.SimpleRing.Field public import Mathlib.RingTheory.SimpleRing.Matrix public import Mathlib.RingTheory.SimpleRing.Principal diff --git a/Mathlib/Algebra/Category/ModuleCat/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Basic.lean index 8f8a97ee01b9ad..752a2035ff5200 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Basic.lean @@ -667,3 +667,10 @@ end Bilinear @[simp] theorem LinearMap.id_moduleCat_comp {R} [Ring R] {G : Type u} [AddCommGroup G] [Module R G] {H : ModuleCat.{u} R} (f : G →ₗ[R] H) : LinearMap.comp (𝟙 H : H ⟶ H).hom f = f := by simp + +instance {R S : Type*} [Ring R] [Ring S] (F : ModuleCat R ⥤ ModuleCat S) [F.Full] [F.Faithful] + (M : ModuleCat R) [h : Nontrivial M] : Nontrivial (F.obj M) := by + by_contra! + exact ((not_iff_not.2 ModuleCat.isZero_iff_subsingleton).2 <| + not_subsingleton_iff_nontrivial.2 h) <| IsZero.of_full_of_faithful_of_isZero F _ <| + ModuleCat.isZero_of_subsingleton <| F.obj M diff --git a/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean b/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean index be97296ed55f29..19cba70e5635d5 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean @@ -131,6 +131,10 @@ theorem zero_of_epi_comp {X Y Z : C} (f : X ⟶ Y) {g : Y ⟶ Z} [Epi f] (h : f rw [← comp_zero, cancel_epi] at h exact h +lemma comp_eq_zero_iff_of_epi {X Y Z : C} (f : X ⟶ Y) {g : Y ⟶ Z} [Epi f] : + f ≫ g = 0 ↔ g = 0 := + ⟨zero_of_epi_comp _, by simp +contextual⟩ + theorem eq_zero_of_image_eq_zero {X Y : C} {f : X ⟶ Y} [HasImage f] (w : image.ι f = 0) : f = 0 := by rw [← image.fac f, w, HasZeroMorphisms.comp_zero] diff --git a/Mathlib/CategoryTheory/Simple.lean b/Mathlib/CategoryTheory/Simple.lean index a832ffb3c19617..b433d6015c5c0f 100644 --- a/Mathlib/CategoryTheory/Simple.lean +++ b/Mathlib/CategoryTheory/Simple.lean @@ -58,6 +58,13 @@ class Simple (X : C) : Prop where theorem isIso_of_mono_of_nonzero {X Y : C} [Simple Y] {f : X ⟶ Y} [Mono f] (w : f ≠ 0) : IsIso f := (Simple.mono_isIso_iff_nonzero f).mpr w +theorem Functor.simple_of_simple_obj {D : Type*} [Category* D] [HasZeroMorphisms D] (F : C ⥤ D) + [F.PreservesMonomorphisms] [F.PreservesZeroMorphisms] [F.ReflectsIsomorphisms] [F.Faithful] + (X : C) [Simple (F.obj X)] : Simple X := + .mk fun {Y} g _ ↦ by + rw [← isIso_iff_of_reflects_iso g F, Simple.mono_isIso_iff_nonzero (F.map g), + ne_eq, ne_eq, not_iff_not, F.map_eq_zero_iff] + theorem Simple.of_iso {X Y : C} [Simple Y] (i : X ≅ Y) : Simple X := { mono_isIso_iff_nonzero := fun f m => by constructor @@ -78,6 +85,19 @@ theorem Simple.of_iso {X Y : C} [Simple Y] (i : X ≅ Y) : Simple X := theorem Simple.iff_of_iso {X Y : C} (i : X ≅ Y) : Simple X ↔ Simple Y := ⟨fun _ => Simple.of_iso i.symm, fun _ => Simple.of_iso i⟩ +theorem simple_obj {D : Type*} [Category* D] [HasZeroMorphisms D] (F : C ⥤ D) + [F.IsEquivalence] (X : C) [Simple X] : Simple (F.obj X) := by + rw [← F.asEquivalence_functor] + have := F.asEquivalence.counitIso.app (F.asEquivalence.functor.obj X) + rw [Functor.comp_obj, Functor.id_obj] at this + have := Simple.of_iso <| Functor.preimageIso _ this + exact Functor.simple_of_simple_obj F.asEquivalence.inverse _ + +theorem simple_obj_iff {D : Type*} [Category* D] [HasZeroMorphisms D] (F : C ⥤ D) + [F.IsEquivalence] (X : C) : + Simple (F.obj X) ↔ Simple X := + ⟨fun _ ↦ Functor.simple_of_simple_obj F X, fun _ ↦ simple_obj F X⟩ + theorem kernel_zero_of_nonzero_from_simple {X Y : C} [Simple X] {f : X ⟶ Y} [HasKernel f] (w : f ≠ 0) : kernel.ι f = 0 := by classical diff --git a/Mathlib/RingTheory/SimpleRing/DivisionRing.lean b/Mathlib/RingTheory/SimpleRing/DivisionRing.lean new file mode 100644 index 00000000000000..b7e68ae02cae77 --- /dev/null +++ b/Mathlib/RingTheory/SimpleRing/DivisionRing.lean @@ -0,0 +1,59 @@ +/- +Copyright (c) 2026 Yunzhou Xie. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Edison Xie +-/ +module + +public import Mathlib.Algebra.Category.ModuleCat.Simple +public import Mathlib.RingTheory.SimpleModule.Basic + +/-! + +## Simple modules over division rings +This file contains some results about simple modules over division rings. + +# Main results + +* `DivisionRing.nonempty_linearEquiv_of_isSimpleModule` : There is an unique simple module over + a division ring, up to isomorphism. +* `isSimpleModule_iff_eq_zero_or_injective` : A module is simple if and only if it is nontrivial + and every linear map from it is either zero or injective, this is the module analogue of + `RingHom.injective` +* `IsSimpleModule.obj_of_isEquivalence` : If `M` is a simple module over a ring `R`, and + `e : ModuleCat R ⥤ ModuleCat S` is an equivalence of categories, + then `e(M)` is a simple module over `S`. + +## Tags +Noncommutative algebra, simple module, division ring + +-/ + +@[expose] public section + +universe u v + +open CategoryTheory + +variable (R S : Type*) [DivisionRing R] [DivisionRing S] (e : ModuleCat R ≌ ModuleCat S) + +lemma DivisionRing.nonempty_linearEquiv_of_isSimpleModule (N : Type*) [AddCommGroup N] + [Module S N] [IsSimpleModule S N] : Nonempty (N ≃ₗ[S] S) := by + obtain ⟨I, hI, ⟨e⟩⟩ := isSimpleModule_iff_quot_maximal.mp ‹_› + exact ⟨e ≪≫ₗ I.quotEquivOfEqBot ((eq_bot_or_eq_top I).resolve_right hI.ne_top)⟩ + +lemma isSimpleModule_iff_eq_zero_or_injective (R : Type u) (M : Type v) [Ring R] [AddCommGroup M] + [Module R M] : IsSimpleModule R M ↔ (Nontrivial M ∧ ∀ (N : Type v) [AddCommGroup N] + [Module R N] (f : M →ₗ[R] N), f = 0 ∨ Function.Injective f) := + ⟨fun hM ↦ ⟨Submodule.nontrivial_iff _|>.1 hM.1.1, fun N _ _ f ↦ hM.1.2 (LinearMap.ker f)|>.elim + (fun h ↦ Or.inr <| by rwa [LinearMap.ker_eq_bot] at h) (fun h ↦ Or.inl <|by simp_all)⟩, + fun ⟨hM1, hM2⟩ ↦ isSimpleModule_iff R M|>.2 ⟨fun p ↦ (hM2 (M ⧸ p) p.mkQ).elim + (fun h ↦ Or.inr <| by simpa [Submodule.ext_iff, LinearMap.ext_iff] using h) + (fun h ↦ Or.inl <| eq_bot_iff.2 fun x hx ↦ h (by simp [hx]))⟩⟩ + +lemma IsSimpleModule.obj_of_isEquivalence + {R S : Type*} [Ring R] [Ring S] (e : ModuleCat R ⥤ ModuleCat S) + [e.IsEquivalence] (M : ModuleCat R) [IsSimpleModule R M] : + IsSimpleModule S (e.obj M) := by + rw [← simple_iff_isSimpleModule'] at * + exact simple_obj e M From a478520668bf632f3763c119ab513cc2667a866b Mon Sep 17 00:00:00 2001 From: Bolton Bailey Date: Fri, 3 Jul 2026 16:02:04 +0000 Subject: [PATCH 0591/1300] ci: add tech debt label (#40601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a step to the PR summary bot to make it add the "tech debt" label to PRs that decrease tech debt. This PR was made with the assistance of Claude code Thanks to Felix for this idea. Zulip discussion here [#mathlib4 > Technical Debt Counters @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Technical.20Debt.20Counters/near/601643776) --- .github/workflows/PR_summary.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index 4565d89484f7cd..c3350f3ed27589 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -233,6 +233,16 @@ jobs: echo "Compute technical debt changes" techDebtVar="$("${CI_SCRIPTS_DIR}/reporting/technical-debt-metrics.sh" pr_summary)" + # If the PR decreased technical debt, add the `tech debt` label. + # The metrics script emits a summary line "Decrease in tech debt:" for each + # level (strong/weak) that went down (and "Increase ..."/"No changes ..." otherwise), + # so matching either of those two lines means the PR reduced some tech debt. + if grep -qE "Decrease in (strong|weak) tech debt" <<< "${techDebtVar}" + then + printf $'Adding "tech debt" label to PR %s\n' "${PR}" + gh pr edit "${PR}" --add-label "tech debt" + fi + echo "Compute documentation reminder" workflowFilesChanged="$(grep '^\.github/workflows/' changed_files.txt || true)" if [ -n "${workflowFilesChanged}" ] From 8c60a81b4f0bd114cdcc6d465ee5b83a5df65f41 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:38:34 +0000 Subject: [PATCH 0592/1300] chore: update Mathlib dependencies 2026-07-03 (#41330) This PR updates the Mathlib dependencies. --- .github/actions/get-mathlib-ci/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 6b593d3115f957..2cb8b3a47631b1 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -10,7 +10,7 @@ inputs: # Default pinned commit used by workflows unless they explicitly override. # Update this ref as needed to pick up changes to mathlib-ci scripts # This is also updated automatically by .github/workflows/update_dependencies.yml - default: 5aee9d4ce5a39050c72b4aa46015a824b0c189ac + default: 0cd6cbc879d9241f3b4f6cb7e8291e34128c5654 path: description: Checkout destination path. required: false From 9e735227e77ebee3594a868a23d1ffd55b5bfd89 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:56:16 +0000 Subject: [PATCH 0593/1300] feat: import `#click_suggestions` in Mathlib.Tactic.Common (#40755) This PR adds the `#click_suggestions` command to `Mathlib.Tactic.Common`, so that it can be used in most mathlib files. To allow this, I reduced the theory imports, since `Mathlib.Tactic.Common` is not supposed to import much theory. The extra import will probably give a minor slowdown, but I think it is worth it. --- Mathlib/Tactic/ClickSuggestions/GRewrite.lean | 12 +++++++----- Mathlib/Tactic/Common.lean | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Mathlib/Tactic/ClickSuggestions/GRewrite.lean b/Mathlib/Tactic/ClickSuggestions/GRewrite.lean index a7d91b9ac2db4c..4bff790065b76a 100644 --- a/Mathlib/Tactic/ClickSuggestions/GRewrite.lean +++ b/Mathlib/Tactic/ClickSuggestions/GRewrite.lean @@ -6,7 +6,6 @@ Authors: Jovan Gerbscheid module public import Mathlib.Tactic.ClickSuggestions.SectionState -public import Mathlib.Order.Antisymmetrization public meta import Lean.Meta.ExprLens /-! @@ -43,10 +42,11 @@ private def gcongrBackward (relName : Name) (relation : Expr) (symm : Bool) : withLocalDeclD `a α fun a ↦ do withLocalDeclD `b α fun b ↦ do withNewMCtxDepth do + let mut result : Array GrwPos := #[] -- Any relation `r` can be proved from `AntisymmRel r`, so we add this as a possible relation - let antiSymm := mkApp2 (.const ``AntisymmRel [u]) α relation - let mut result : Array GrwPos := - #[{ relName := ``AntisymmRel, relation := antiSymm, symm? := none }] + if (← getEnv).contains `AntisymmRel then + let antiSymm := mkApp2 (.const `AntisymmRel [u]) α relation + result := result.push { relName := `AntisymmRel, relation := antiSymm, symm? := none } -- If `relName` is symmetric, then include the reverse as a possible relation (`symm? := none`) let symm? ← try let dummyVar ← mkFreshExprMVar (mkApp2 relation a b) @@ -61,7 +61,9 @@ private def gcongrBackward (relName : Name) (relation : Expr) (symm : Bool) : result := result.push { relName, relation, symm? } -- For `≤`, we add the relation `<`. if relName == ``LE.le then - let (mvars, _, le) ← forallMetaTelescope (← inferType (← mkConstWithFreshMVarLevels ``le_of_lt)) + if (← getEnv).contains `le_of_lt then + let (mvars, _, le) ← + forallMetaTelescope (← inferType (← mkConstWithFreshMVarLevels `le_of_lt)) if ← isDefEq le.appFn!.appFn! relation then let lt ← instantiateMVars (← inferType mvars.back!).appFn!.appFn! result := result.push { relName := ``LT.lt, relation := lt, symm? := symm } diff --git a/Mathlib/Tactic/Common.lean b/Mathlib/Tactic/Common.lean index e35e792b618078..01fa2cdc218664 100644 --- a/Mathlib/Tactic/Common.lean +++ b/Mathlib/Tactic/Common.lean @@ -42,6 +42,7 @@ public import Mathlib.Tactic.Choose public import Mathlib.Tactic.ClearExclamation public import Mathlib.Tactic.ClearExcept public import Mathlib.Tactic.Clear_ +public import Mathlib.Tactic.ClickSuggestions public import Mathlib.Tactic.Coe public import Mathlib.Tactic.CongrExclamation public import Mathlib.Tactic.CongrM From 5521c584f80bd9c2ab0aa8a43e95c9edbe37e8de Mon Sep 17 00:00:00 2001 From: Nicola Falciola Date: Fri, 3 Jul 2026 20:53:08 +0000 Subject: [PATCH 0594/1300] feat(Data/ZMod/QuotientRing): add an apply version for the single component of crt for zmod (#40972) The CRT for ZMod on the each components is equivalent to the usual `ZMod.castHom` given by the divisibility property. --- Mathlib/Data/ZMod/QuotientRing.lean | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mathlib/Data/ZMod/QuotientRing.lean b/Mathlib/Data/ZMod/QuotientRing.lean index b7161c061e2515..8ae25270c721aa 100644 --- a/Mathlib/Data/ZMod/QuotientRing.lean +++ b/Mathlib/Data/ZMod/QuotientRing.lean @@ -84,6 +84,14 @@ def ZMod.prodEquivPi {ι : Type*} [Fintype ι] (a : ι → ℕ) quotientInfRingEquivPiQuotient _ this |>.trans <| RingEquiv.piCongrRight fun i ↦ Int.quotientSpanNatEquivZMod (a i) +open Finset Function in +@[simp] +theorem ZMod.prodEquivPi_apply {ι : Type*} [Fintype ι] (a : ι → ℕ) + (coprime : Pairwise (Nat.Coprime on a)) (b : ZMod (∏ i, a i)) (i : ι) : + prodEquivPi a coprime b i = castHom (dvd_prod_of_mem a (mem_univ i)) _ b := + RingHom.congr_fun (Subsingleton.elim ((Pi.evalRingHom (fun _ ↦ ZMod _) i).comp + (prodEquivPi a coprime).toRingHom) _) b + /-- The **Chinese remainder theorem**, version for `ZMod n`. -/ def ZMod.equivPi (hn : n ≠ 0) : ZMod n ≃+* Π (p : n.primeFactors), ZMod (p ^ (n.factorization p)) := From 3850db6aa4cbbbc488ff39b408f7894076717019 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 3 Jul 2026 21:15:31 +0000 Subject: [PATCH 0595/1300] chore: fix some diamonds around `Lex`/`Colex` (#41035) This PR fixes some instance diamonds found by the instance diamond linter (#38781) --- Mathlib/Combinatorics/Colex.lean | 2 -- Mathlib/Data/DFinsupp/Lex.lean | 4 ++-- Mathlib/Order/PiLex.lean | 9 +++++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Mathlib/Combinatorics/Colex.lean b/Mathlib/Combinatorics/Colex.lean index 638979cbff807d..6daa6f3a5eb2f8 100644 --- a/Mathlib/Combinatorics/Colex.lean +++ b/Mathlib/Combinatorics/Colex.lean @@ -69,8 +69,6 @@ namespace Finset open Colex -instance : Inhabited (Colex (Finset α)) := ⟨toColex ∅⟩ - namespace Colex section PartialOrder variable [PartialOrder α] [PartialOrder β] {f : α → β} {𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)} diff --git a/Mathlib/Data/DFinsupp/Lex.lean b/Mathlib/Data/DFinsupp/Lex.lean index a701e03d918e5a..b2d249782a7be0 100644 --- a/Mathlib/Data/DFinsupp/Lex.lean +++ b/Mathlib/Data/DFinsupp/Lex.lean @@ -105,6 +105,7 @@ instance Colex.isStrictOrder [∀ i, PartialOrder (α i)] : See `DFinsupp.Lex.linearOrder` for a proof that this partial order is in fact linear. -/ instance Lex.partialOrder [∀ i, PartialOrder (α i)] : PartialOrder (Lex (Π₀ i, α i)) where le x y := ⇑(ofLex x) = ⇑(ofLex y) ∨ x < y + toLT := instLTLex __ := PartialOrder.lift (fun x : Lex (Π₀ i, α i) ↦ toLex (⇑(ofLex x))) (DFunLike.coe_injective (F := DFinsupp α)) @@ -112,6 +113,7 @@ instance Lex.partialOrder [∀ i, PartialOrder (α i)] : PartialOrder (Lex (Π See `DFinsupp.Colex.linearOrder` for a proof that this partial order is in fact linear. -/ instance Colex.partialOrder [∀ i, PartialOrder (α i)] : PartialOrder (Colex (Π₀ i, α i)) where le x y := ⇑(ofColex x) = ⇑(ofColex y) ∨ x < y + toLT := instLTColex __ := PartialOrder.lift (fun x : Colex (Π₀ i, α i) ↦ toColex (⇑(ofColex x))) (DFunLike.coe_injective (F := DFinsupp α)) @@ -175,14 +177,12 @@ instance Colex.decidableLT : DecidableLT (Colex (Π₀ i, α i)) := /-- The linear order on `DFinsupp`s obtained by the lexicographic ordering. -/ instance Lex.linearOrder : LinearOrder (Lex (Π₀ i, α i)) where - __ := Lex.partialOrder le_total := total_of _ toDecidableLT := decidableLT toDecidableLE := decidableLE /-- The linear order on `DFinsupp`s obtained by the colexicographic ordering. -/ instance Colex.linearOrder : LinearOrder (Colex (Π₀ i, α i)) where - __ := Colex.partialOrder le_total := total_of _ toDecidableLT := decidableLT toDecidableLE := decidableLE diff --git a/Mathlib/Order/PiLex.lean b/Mathlib/Order/PiLex.lean index 11683b0a6d28d9..c4300651ca5b6d 100644 --- a/Mathlib/Order/PiLex.lean +++ b/Mathlib/Order/PiLex.lean @@ -81,11 +81,16 @@ theorem trichotomous_lex [∀ i, Std.Trichotomous (α := β i) s] (wf : WellFoun @[deprecated (since := "2026-01-24")] alias isTrichotomous_lex := trichotomous_lex +/- +These instances are leaky, because they define the relation on `∀ i, β i` instead of +`Lex (∀ i, β i)`/`Colex (∀ i, β i)`. So, we would like to mark them `@[semireducible]`. +But the linter doesn't allow this, so we wrap them in `id` instead. +-/ instance [LT ι] [∀ a, LT (β a)] : LT (Lex (∀ i, β i)) := - ⟨Pi.Lex (· < ·) (· < ·)⟩ + id ⟨Pi.Lex (· < ·) (· < ·)⟩ instance [LT ι] [∀ a, LT (β a)] : LT (Colex (∀ i, β i)) := - ⟨Pi.Lex (· > ·) (· < ·)⟩ + id ⟨Pi.Lex (· > ·) (· < ·)⟩ -- If `Lex` and `Colex` are ever made into one-field structures, we need a `CoeFun` instance. -- This will make `x i` syntactically equal to `ofLex x i` for `x : Πₗ i, α i`, thus making From c093ecaf2255abd0cd9b076d33e86253a1e8ebb4 Mon Sep 17 00:00:00 2001 From: Johan Commelin Date: Sat, 4 Jul 2026 02:49:56 +0000 Subject: [PATCH 0596/1300] feat(scripts): export wikidata/stacks/kerodon cross-references as JSON (#40701) This PR adds `scripts/export_crossrefs.lean`, which exports every declaration tagged with `@[wikidata]`, `@[stacks]`, or `@[kerodon]` (name, file, line, ids) as JSON, and a CI workflow that runs it after each successful master build and publishes the result to https://github.com/leanprover-community/crossref-exports. The CI workflow can also be triggered manually using `workflow_dispatch`. The credentials are provided by a new GitHub app "crossref-exports-app" under the `leanprover-community` organization with secrets set up in the "crossref-exports" repo environment. Co-authored-by: Bryan Gin-ge Chen --- .github/workflows/build_template.yml | 3 + .github/workflows/export_crossrefs.yml | 161 +++++++++++++++++++++++++ .gitignore | 3 + Mathlib/Tactic/CrossRefAttribute.lean | 20 ++- docs/workflows.md | 1 + scripts/README.md | 11 ++ scripts/export_crossrefs.lean | 73 +++++++++++ 7 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/export_crossrefs.yml create mode 100644 scripts/export_crossrefs.lean diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index de0366348b2616..6e333b0394ffa4 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -801,6 +801,9 @@ jobs: run: | lake env lean scripts/create_deprecated_modules.lean lake env lean scripts/autolabel.lean + # Executing this also runs the export and writes a (gitignored) `crossrefs.json`, + # which doubles as a smoke test of the `export_crossrefs.yml` workflow. + lake env lean scripts/export_crossrefs.lean lake exe check_title_labels --labels "t-algebra" "feat: dummy PR for testing" - name: build everything diff --git a/.github/workflows/export_crossrefs.yml b/.github/workflows/export_crossrefs.yml new file mode 100644 index 00000000000000..fa12a8e457553d --- /dev/null +++ b/.github/workflows/export_crossrefs.yml @@ -0,0 +1,161 @@ +name: Export cross-reference data + +# Generates a JSON dictionary of every declaration tagged with `@[wikidata]`, +# `@[stacks]`, or `@[kerodon]` (name, file, line, and the referenced ids) and +# pushes it to a versioned repository (`CROSSREFS_REPO`), where it is publicly +# available at `https://raw.githubusercontent.com//master/crossrefs.json`. +# +# The data is read from the fully-imported `Mathlib` environment by +# `scripts/export_crossrefs.lean`, like the `#stacks_tags` command. + +on: + workflow_run: + workflows: ["continuous integration"] + branches: [master] + types: [completed] + workflow_dispatch: + inputs: + dry_run: + description: "Dry run: mint the app token and verify push permission, but don't push to the crossrefs repo" + type: boolean + default: true + +concurrency: + group: export-crossrefs + cancel-in-progress: true + +permissions: + contents: read + # Required for the token-minting action to request a GitHub OIDC token, + # which it exchanges (via Azure Key Vault) for a GitHub App installation token. + id-token: write + +env: + CROSSREFS_REPO: leanprover-community/crossref-exports + BUILT_SHA: ${{ github.event.workflow_run.head_sha || github.sha }} + +jobs: + export: + name: Export cross-reference JSON + runs-on: ubuntu-latest + environment: + name: crossref-exports + deployment: false + if: >- + github.repository == 'leanprover-community/mathlib4' && + (github.event_name == 'workflow_dispatch' + || github.event.workflow_run.conclusion == 'success') + steps: + - name: Checkout the built commit + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + # The exact commit CI validated; for manual runs, the dispatched ref. + ref: ${{ env.BUILT_SHA }} + + - name: Configure Lean and fetch the Mathlib cache + uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 + with: + auto-config: false + use-github-cache: false + use-mathlib-cache: true + reinstall-transient-toolchain: true + + - name: Generate crossrefs.json + env: + CROSSREFS_OUT: crossrefs.json + CROSSREFS_COMMIT: ${{ env.BUILT_SHA }} + run: lake env lean scripts/export_crossrefs.lean + + - name: Sanity-check the output + run: | + jq -e '.entries | length > 0' crossrefs.json > /dev/null + echo "Exported $(jq '.entries | length' crossrefs.json) entries." + + # Split `owner/repo` so the token can be scoped to the crossrefs repo. The + # app is installed on the crossrefs repo's owner, not on this repository, + # so the token-minting action must resolve the installation from there. + - name: Resolve crossrefs repository owner and name + id: repo + run: | + echo "owner=${CROSSREFS_REPO%%/*}" >> "$GITHUB_OUTPUT" + echo "name=${CROSSREFS_REPO#*/}" >> "$GITHUB_OUTPUT" + + # Mint a short-lived GitHub App installation token scoped to the crossrefs + # repo, instead of relying on a long-lived personal access token. + - name: Generate app token + id: app-token + uses: leanprover-community/mathlib-ci/.github/actions/azure-create-github-app-token@3bb576208589a435eeaeac9b144a1b7c3e948760 + with: + app-id: ${{ secrets.MATHLIB_CROSSREFS_APP_ID }} + key-vault-name: ${{ vars.MATHLIB_AZ_KEY_VAULT_NAME }} + key-name: crossref-exports-app-pk + azure-client-id: ${{ vars.GH_APP_AZURE_CLIENT_ID_CROSSREFS }} + azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} + owner: ${{ steps.repo.outputs.owner }} + repositories: ${{ steps.repo.outputs.name }} + + - name: Push to the crossrefs repository + env: + CROSSREFS_PUSH_TOKEN: ${{ steps.app-token.outputs.token }} + # On manual runs this defaults to true (see the workflow_dispatch + # inputs); on the automatic workflow_run trigger `inputs` is empty, so + # this is false and the push happens for real. + DRY_RUN: ${{ inputs.dry_run || false }} + run: | + git clone --depth 1 \ + "https://x-access-token:${CROSSREFS_PUSH_TOKEN}@github.com/${CROSSREFS_REPO}.git" \ + crossrefs-repo + cd crossrefs-repo + git config user.name "leanprover-community-bot" + git config user.email "leanprover-community-bot@users.noreply.github.com" + # Commit only when the entries themselves change. The `generated` + # timestamp and source `commit` change on every run, so comparing the + # whole file would produce a commit even when nothing of substance did. + # Consequence: the published `generated`/`commit` fields record when the + # entries last changed, not the latest commit the export ran against, so + # consumers should not read `generated` as a "data freshness" signal. + # Read each file fully into a string and compare; using `diff -q` on two + # `jq` process substitutions makes `diff` close the pipes at the first + # difference, which leaves the `jq` writers with a SIGPIPE ("broken pipe") + # and noisy spurious errors in the log. + if [ -f crossrefs.json ] && \ + [ "$(jq -Sc '.entries' crossrefs.json)" = "$(jq -Sc '.entries' ../crossrefs.json)" ]; then + echo "No change in entries." + changed=false + else + cp ../crossrefs.json crossrefs.json + git add crossrefs.json + git commit -m "Update crossrefs (mathlib4@${BUILT_SHA})" + changed=true + fi + + if [ "${DRY_RUN}" = "true" ]; then + # Verify the minted token can actually push, without mutating the + # remote: `git push --dry-run` performs the authenticated + # git-receive-pack handshake (which GitHub gates on write access) but + # never sends the update. If nothing changed, add a throwaway local + # commit so there is a ref update to negotiate. + if [ "${changed}" != "true" ]; then + git commit --allow-empty -m "Dry-run push permission check (never sent)" + fi + echo "Dry run: verifying push permission against ${CROSSREFS_REPO} without pushing." + git push --dry-run + elif [ "${changed}" = "true" ]; then + git push + else + echo "No change in entries; nothing to commit." + fi + + - name: Post failure message on Zulip + if: failure() + uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + with: + api-key: ${{ secrets.ZULIP_API_KEY }} + email: 'github-mathlib4-bot@leanprover.zulipchat.com' + organization-url: 'https://leanprover.zulipchat.com' + to: 'nightly-testing-mathlib' + type: 'stream' + topic: 'crossrefs export failure' + content: | + ❌ Cross-reference export [failed](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) on ${{ env.BUILT_SHA }} diff --git a/.gitignore b/.gitignore index ef8c9144af2e08..6973f6af86cc29 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ scripts/.rm_set_option_progress.jsonl # Artifacts from using the devcontainer setup .devcontainer/devcontainer-lock.json + +# Output of scripts/export_crossrefs.lean +/crossrefs.json diff --git a/Mathlib/Tactic/CrossRefAttribute.lean b/Mathlib/Tactic/CrossRefAttribute.lean index d99fb0748397f9..7697769c05dbcf 100644 --- a/Mathlib/Tactic/CrossRefAttribute.lean +++ b/Mathlib/Tactic/CrossRefAttribute.lean @@ -37,20 +37,30 @@ inductive Database where | kerodon | stacks | wikidata - deriving BEq, Hashable + deriving BEq, Hashable, Ord + +namespace Database /-- The base URL for an external database's tag pages. Always ends with `/`. -/ -def databaseURL : Database → String +def url : Database → String | .kerodon => "https://kerodon.net/tag/" | .stacks => "https://stacks.math.columbia.edu/tag/" | .wikidata => "https://www.wikidata.org/wiki/" /-- The display label used in docstring links and trace output. -/ -def databaseLabel : Database → String +def label : Database → String | .kerodon => "Kerodon Tag" | .stacks => "Stacks Tag" | .wikidata => "Wikidata" +/-- A lowercase short name for the given database. Useful when exporting to JSON. -/ +def shortName : Database → String + | .kerodon => "kerodon" + | .stacks => "stacks" + | .wikidata => "wikidata" + +end Database + /-- A cross-reference from a Mathlib declaration to an entry in an external database. -/ structure Tag where /-- The name of the declaration carrying the cross-reference. -/ @@ -82,7 +92,7 @@ This is the database-agnostic core of every cross-reference attribute's `add` ha def addCrossRefDoc (db : Database) (decl : Name) (idStr comment : String) : CoreM Unit := do let oldDoc := (← findDocString? (← getEnv) decl).getD "" let commentInDoc := if comment.isEmpty then "" else s!" ({comment})" - let link := s!"[{databaseLabel db} {idStr}]({databaseURL db}{idStr}){commentInDoc}" + let link := s!"[{db.label} {idStr}]({db.url}{idStr}){commentInDoc}" addDocStringCore decl <| "\n\n".intercalate ([oldDoc, link].filter (· != "")) addTagEntry decl db idStr comment @@ -281,7 +291,7 @@ def traceCrossRefs (db : Database) (verbose : Bool := false) : let (parL, parR) := if d.comment.isEmpty then ("", "") else (" (", ")") let cmt := parL ++ d.comment ++ parR msgs := msgs.push - m!"[{databaseLabel db} {d.tag}]({databaseURL db ++ d.tag}) \ + m!"[{db.label} {d.tag}]({db.url ++ d.tag}) \ corresponds to declaration '{.ofConstName d.declName}'.{cmt}" if verbose then let dType := ((env.find? d.declName).getD default).type diff --git a/docs/workflows.md b/docs/workflows.md index 60eef0312e97ee..45afc95ad2e788 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -105,3 +105,4 @@ Primary trigger for this section: completion of other workflows (`workflow_run`) | [`olean_report_wf_run.yaml`](../.github/workflows/olean_report_wf_run.yaml) | olean report (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/olean_report_wf_run.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/olean_report_wf_run.yaml) | Low | `workflow_run` | Privileged companion to `olean_report.yaml`. Downloads the bridge artifact and posts or updates the olean diff as a comment on the PR. | | [`decls-diff.yml`](../.github/workflows/decls-diff.yml) | Declarations diff (post-build)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/decls-diff.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/decls-diff.yml) | Low | `workflow_run` | Post-build companion to `ci` that diffs the `import-graph` artifact of a PR build against its master merge-base and patches the `### PR summary` comment's declarations-diff section with the Lean-aware result (or a cache-miss notice). | | [`export_telemetry.yaml`](../.github/workflows/export_telemetry.yaml) | Export workflow telemetry
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/export_telemetry.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/export_telemetry.yaml) | Low | `workflow_run` | Exports CI run telemetry to OTLP when selected CI workflows complete. | +| [`export_crossrefs.yml`](../.github/workflows/export_crossrefs.yml) | Export cross-reference data
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/export_crossrefs.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/export_crossrefs.yml) | Low | `workflow_run` | After a successful master `ci` build, regenerates the `@[wikidata]`/`@[stacks]`/`@[kerodon]` cross-reference JSON via `scripts/export_crossrefs.lean` and pushes it to the versioned crossrefs repository when the entries change. | diff --git a/scripts/README.md b/scripts/README.md index c8a19d945775d8..f41ad778e88a4e 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -236,6 +236,17 @@ to module `Foo.Bar` (no `srcDir` indirection). normalize the BibTeX file `docs/references.bib` using `bibtool`. - `yaml_check.py`, `check-yaml.lean` Sanity checks for `undergrad.yaml`, `overview.yaml`, `100.yaml` and `1000.yaml`. +- `export_crossrefs.lean` + Exports a JSON dictionary of every declaration tagged with `@[wikidata]`, `@[stacks]`, or + `@[kerodon]` (declaration name, source file, line number, and the cross-reference ids). + It runs as a Lean command over the fully-imported `Mathlib` environment (like `#stacks_tags`), + so it is invoked with `lake env lean scripts/export_crossrefs.lean` rather than `lake exe`. + The output path defaults to `crossrefs.json` (override with `CROSSREFS_OUT`); the embedded + mathlib commit SHA is read from `CROSSREFS_COMMIT`. The + [`export_crossrefs.yml`](../.github/workflows/export_crossrefs.yml) workflow runs this after every + successful master build and publishes the result to the + [`crossref-exports`](https://github.com/leanprover-community/crossref-exports) repository + (committing only when the entries actually change). - `autolabel.lean` is the Lean script in charge of automatically adding a `t-`label on eligible PRs. Autolabelling is inferred by which directories the current PR modifies. - `auto_commit.sh` runs a command and creates a commit with the result. The commit message format diff --git a/scripts/export_crossrefs.lean b/scripts/export_crossrefs.lean new file mode 100644 index 00000000000000..724face882f1b4 --- /dev/null +++ b/scripts/export_crossrefs.lean @@ -0,0 +1,73 @@ +/- +Copyright (c) 2026 Johan Commelin. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johan Commelin +-/ + +import Mathlib + +/-! +# Export cross-reference data as JSON + +Elaborating this file writes a JSON file listing every Mathlib declaration tagged with +`@[wikidata ...]`, `@[stacks ...]`, or `@[kerodon ...]`, together with its source file, line +number, and the referenced identifiers. + +The cross-references are read from the ambient environment (like the `#stacks_tags` command), so +the file must be run with the full `Mathlib` import elaborated: + + lake env lean scripts/export_crossrefs.lean + +The output path is taken from the `CROSSREFS_OUT` environment variable (default `crossrefs.json`) +and the recorded source commit from `CROSSREFS_COMMIT` (default `unknown`). +-/ + +open Lean Mathlib.CrossRef + +namespace ExportCrossRefs + +/-- The name of the module containing `decl`, and the 1-based line number where `decl` is +declared, if known. -/ +def declLocation (env : Environment) (decl : Name) : Option (String × Nat) := do + -- Inline `findDeclarationRangesCore?` since it's monadic. + let ranges ← declRangeExt.find? (level := .exported) env decl <|> + declRangeExt.find? (level := .server) env decl + let mod ← env.getModuleFor? decl + return (mod.toString, ranges.selectionRange.pos.line) + +/-- One JSON entry per declaration, sorted by declaration name. A declaration carrying several +cross-references (e.g. both a Stacks and a Wikidata tag) gets a single entry with multiple `refs`. -/ +def buildEntries (env : Environment) : Array Json := Id.run do + let mut byDecl : Std.HashMap Name (Array Tag) := {} + let (localTags, importedTags) := PersistentEnvExtension.getState tagExt env + for tags in importedTags do + for tag in tags do + byDecl := byDecl.alter tag.declName fun val? => val?.getD #[] |>.push tag + for tag in localTags do + byDecl := byDecl.alter tag.declName fun val? => val?.getD #[] |>.push tag + let sorted := byDecl.toArray.qsort fun a b => a.1.toString < b.1.toString + sorted.map fun (decl, tags) => + -- Canonical ref order (by database, then id) keeps the published file stable. + let tags := tags.qsort fun a b => + (compare a.database b.database).then (compare a.tag b.tag) |>.isLT + let refs : Array Json := tags.map fun t => + json% { db : $(t.database.shortName), id : $(t.tag), comment : $(t.comment) } + let (mod, line) := declLocation env decl |>.getD ("", 0) + json% { decl : $(decl.toString), module : $(mod), line : $(line), refs : $(refs) } + +end ExportCrossRefs + +open ExportCrossRefs in +-- TODO: consider moving to `importModules`, or managing with `lake` +-- (see also environment linter internals, which may eventually do the latter) +run_cmd do + let entries := buildEntries (← getEnv) + let now := (Std.Time.DateTime.ofTimestamp (← Std.Time.Timestamp.now) .UTC).toISO8601String + let json := json% { + generated : $(now.trimAscii.toString), + commit : $((← IO.getEnv "CROSSREFS_COMMIT").getD "unknown"), + entries : $(entries) + } + let path := (← IO.getEnv "CROSSREFS_OUT").getD "crossrefs.json" + IO.FS.writeFile path (json.pretty ++ "\n") + logInfo m!"Wrote {entries.size} cross-reference entries to {path}" From 613038575adbb25fe394846010a0507cfe643053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sat, 4 Jul 2026 08:56:05 +0000 Subject: [PATCH 0597/1300] refactor(Algebra): make `MonoidAlgebra` into a one-field structure (#38714) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace ``` def MonoidAlgebra (R M : Type*) [Semiring R] : Type _ := M →₀ R ``` by ``` structure MonoidAlgebra (R M : Type*) [Semiring R] where ofCoeff :: coeff : M →₀ R ``` and similarly for `AddMonoidAlgebra`. Since elements of `MonoidAlgebra R M` shouldn't be considered as finitely supported functions `M → R` anymore, I also remove the coercion to functions. This is a major change with many ramifications in mathlib. The foremost consequence is that it is now by design impossible to abuse defeqs by using `Finsupp` API on `MonoidAlgebra`. There are more consequences: 1. `coeff` is now used very widely. Many lemma names are renamed to contain `coeff` since their type signature changed. 2. For convenience, I copy more `Finsupp` API over to `MonoidAlgebra`. This includes induction principles (`induction`) and linear combinations (`supported`). 3. The existing API copied over from `Finsupp` has no reason to be so through `abbrev` (anymore?/ever), so I make them `def`s instead. 4. Many equalities in `MonoidAlgebra` that were previously obtained through direct applications of the relevant `Finsupp` lemmas are now replaced by `ext; simp`. 5. Many `set_option backward.isDefEq.respectTransparency false` are removed and a similar (but slightly smaller) number are added, essentially because we are pushing further the boundary of abuse. In many cases, the easiest solution to something breaking was to rid it of its own abuse. Therefore the following that changes that are a priori orthogonal to the titular change were made: 1. Make `PolynomialModule` a one-field structure, similarly to `MonoidAlgebra`. 2. Deduce the `MvPolynomial` base change results from the `AddMonoidAlgebra` ones. In particular, the `AddMonoidAlgebra` ones take the base ring on the left while the `MvPolynomial` ones took it on the right. Left is the correct side because of how heterogeneous base change is set up in mathlib. 3. Make the representation theory library use `MonoidAlgebra` more, whereas previously it was using `MonoidAlgebra` and `Finsupp` interchangeably. 4. Add `ModuleCat.monoidAlgebraFree` as an alternative to `ModuleCat.free` that uses `MonoidAlgebra` instead of `Finsupp`. This is useful to fix homological results that broke due to point 3. Some points that are left as future work: 1. `Polynomial R` is currently defined as a one-field structure around `AddMonoidAlgebra R ℕ`. Pending performance, it could become an `abbrev` instead. 3. `MonoidAlgebra` could become an `abbrev` of `SkewMonoidAlgebra` since it is a special case of it. In fact, `SkewMonoidAlgebra` could itself become a special case of `CrossProductAlgebra` from [BrauerGroup](https://github.com/Whysoserioushah/BrauerGroup). 5. `MvPowerSeries` and `PowerSeries` should follow the same treatment as `MonoidAlgebra`. 6. `Finsupp` should become an `abbrev` of (non-dependent) `DFinsupp`. This becomes easier after the current PR since the `Finsupp` API is used much less widely. Co-authored-by: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> --- .../ZeroDivisorsInAddMonoidAlgebras.lean | 20 +- .../Category/ModuleCat/Adjunctions.lean | 17 +- Mathlib/Algebra/FreeAlgebra/Cardinality.lean | 13 +- Mathlib/Algebra/Lie/Loop.lean | 1 + Mathlib/Algebra/MonoidAlgebra/Basic.lean | 139 ++-- Mathlib/Algebra/MonoidAlgebra/Cardinal.lean | 6 +- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 595 +++++++++++------- Mathlib/Algebra/MonoidAlgebra/Degree.lean | 172 ++--- Mathlib/Algebra/MonoidAlgebra/Division.lean | 99 ++- Mathlib/Algebra/MonoidAlgebra/Grading.lean | 68 +- Mathlib/Algebra/MonoidAlgebra/Ideal.lean | 46 +- Mathlib/Algebra/MonoidAlgebra/Lift.lean | 17 +- Mathlib/Algebra/MonoidAlgebra/MapDomain.lean | 149 +++-- Mathlib/Algebra/MonoidAlgebra/Module.lean | 225 ++++--- .../Algebra/MonoidAlgebra/NoZeroDivisors.lean | 41 +- Mathlib/Algebra/MonoidAlgebra/Opposite.lean | 35 +- .../Algebra/MonoidAlgebra/PointwiseSMul.lean | 26 +- Mathlib/Algebra/MonoidAlgebra/Support.lean | 135 ++-- .../Algebra/MonoidAlgebra/ToDirectSum.lean | 59 +- Mathlib/Algebra/MvPolynomial/Basic.lean | 96 ++- Mathlib/Algebra/MvPolynomial/Cardinal.lean | 4 +- Mathlib/Algebra/MvPolynomial/CommRing.lean | 4 +- Mathlib/Algebra/MvPolynomial/Degrees.lean | 14 +- Mathlib/Algebra/MvPolynomial/Derivation.lean | 6 +- Mathlib/Algebra/MvPolynomial/Division.lean | 12 +- Mathlib/Algebra/MvPolynomial/Equiv.lean | 218 ++++--- Mathlib/Algebra/MvPolynomial/Eval.lean | 5 +- Mathlib/Algebra/MvPolynomial/Funext.lean | 5 +- Mathlib/Algebra/MvPolynomial/Monad.lean | 6 +- Mathlib/Algebra/MvPolynomial/PDeriv.lean | 13 +- Mathlib/Algebra/MvPolynomial/Rename.lean | 54 +- Mathlib/Algebra/MvPolynomial/Supported.lean | 3 +- Mathlib/Algebra/Polynomial/Basic.lean | 97 ++- Mathlib/Algebra/Polynomial/Basis.lean | 4 +- Mathlib/Algebra/Polynomial/Cardinal.lean | 17 +- Mathlib/Algebra/Polynomial/Coeff.lean | 12 +- Mathlib/Algebra/Polynomial/Degree/Defs.lean | 6 +- Mathlib/Algebra/Polynomial/Derivative.lean | 9 +- Mathlib/Algebra/Polynomial/Eval/Coeff.lean | 4 +- Mathlib/Algebra/Polynomial/HasseDeriv.lean | 2 + Mathlib/Algebra/Polynomial/Homogenize.lean | 3 +- Mathlib/Algebra/Polynomial/Laurent.lean | 108 ++-- Mathlib/Algebra/Polynomial/Module/Basic.lean | 269 +++++--- Mathlib/Algebra/Polynomial/OfFn.lean | 3 +- Mathlib/Algebra/Polynomial/Reverse.lean | 17 +- Mathlib/Algebra/Polynomial/UnitTrinomial.lean | 18 +- .../Algebra/Ring/Subring/IntPolynomial.lean | 8 +- .../BoundedContinuousFunctionChar.lean | 36 +- Mathlib/Data/Finsupp/Basic.lean | 13 + Mathlib/FieldTheory/Finite/Polynomial.lean | 3 +- Mathlib/FieldTheory/SeparablyGenerated.lean | 12 +- .../LinearAlgebra/Finsupp/VectorSpace.lean | 4 +- Mathlib/LinearAlgebra/FreeAlgebra.lean | 3 +- .../LinearAlgebra/SymmetricAlgebra/Basis.lean | 2 + .../Measure/CharacteristicFunction/Basic.lean | 6 +- .../Measure/LevyConvergence.lean | 4 +- .../NumberTheory/BernoulliPolynomials.lean | 1 + Mathlib/NumberTheory/Height/MvPolynomial.lean | 23 +- Mathlib/RepresentationTheory/Action.lean | 101 ++- Mathlib/RepresentationTheory/Basic.lean | 143 ++--- Mathlib/RepresentationTheory/Coinduced.lean | 5 +- .../RepresentationTheory/Coinvariants.lean | 33 +- Mathlib/RepresentationTheory/Equiv.lean | 56 +- Mathlib/RepresentationTheory/FiniteIndex.lean | 7 +- .../Homological/FiniteCyclic.lean | 24 +- .../Homological/GroupHomology/Basic.lean | 1 - .../GroupHomology/FiniteCyclic.lean | 3 +- .../Homological/Resolution.lean | 122 ++-- Mathlib/RepresentationTheory/Induced.lean | 30 +- Mathlib/RepresentationTheory/Invariants.lean | 8 +- Mathlib/RepresentationTheory/Rep/Basic.lean | 25 +- Mathlib/RepresentationTheory/Rep/Iso.lean | 3 +- .../RingTheory/Coalgebra/MonoidAlgebra.lean | 18 +- Mathlib/RingTheory/Derivation/MapCoeffs.lean | 47 +- .../RingTheory/Extension/Cotangent/Basis.lean | 3 + Mathlib/RingTheory/Extension/Generators.lean | 23 +- .../Extension/Presentation/Basic.lean | 9 +- Mathlib/RingTheory/Filtration.lean | 16 +- Mathlib/RingTheory/FinitePresentation.lean | 2 +- Mathlib/RingTheory/FiniteType.lean | 49 +- Mathlib/RingTheory/Finiteness/Finsupp.lean | 4 +- .../RingTheory/HopfAlgebra/MonoidAlgebra.lean | 8 +- Mathlib/RingTheory/IsAdjoinRoot.lean | 10 +- Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 8 +- Mathlib/RingTheory/MvPolynomial/Basic.lean | 39 +- .../MvPolynomial/EulerIdentity.lean | 4 +- .../RingTheory/MvPolynomial/FreeCommRing.lean | 2 +- .../RingTheory/MvPolynomial/Homogeneous.lean | 26 +- Mathlib/RingTheory/MvPolynomial/Ideal.lean | 2 + .../MvPolynomial/IrreducibleQuadratic.lean | 6 +- .../MvPolynomial/Symmetric/Defs.lean | 6 +- .../MvPolynomial/WeightedHomogeneous.lean | 32 +- Mathlib/RingTheory/MvPowerSeries/Trunc.lean | 3 +- Mathlib/RingTheory/Polynomial/Basic.lean | 21 +- Mathlib/RingTheory/Polynomial/IsIntegral.lean | 2 +- Mathlib/RingTheory/Polynomial/Opposites.lean | 2 +- Mathlib/RingTheory/PowerBasis.lean | 10 +- .../RingTheory/RingHom/StandardSmooth.lean | 3 +- .../RingTheory/Smooth/IntegralClosure.lean | 18 +- .../RingTheory/Spectrum/Prime/Polynomial.lean | 13 +- .../TensorProduct/MonoidAlgebra.lean | 103 ++- .../TensorProduct/MvPolynomial.lean | 204 ++---- .../WittVector/StructurePolynomial.lean | 3 +- 103 files changed, 2196 insertions(+), 2048 deletions(-) diff --git a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean index 03e41b3f218856..08f0094e39a030 100644 --- a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean +++ b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean @@ -59,7 +59,7 @@ theorem zero_divisors_of_periodic {R A} [Nontrivial R] [Ring R] [AddMonoid A] {n (n2 : 2 ≤ n) (na : n • a = a) (na1 : (n - 1) • a ≠ 0) : ∃ f g : R[A], f ≠ 0 ∧ g ≠ 0 ∧ f * g = 0 := by refine ⟨single a 1, single ((n - 1) • a) 1 - single 0 1, by simp, ?_, ?_⟩ - · exact sub_ne_zero.mpr (by simpa [single, AddMonoidAlgebra, single_eq_single_iff]) + · simpa [sub_ne_zero, single_inj] · rw [mul_sub, AddMonoidAlgebra.single_mul_single, AddMonoidAlgebra.single_mul_single, sub_eq_zero, add_zero, ← succ_nsmul', Nat.sub_add_cancel (one_le_two.trans n2), na] @@ -81,22 +81,18 @@ theorem zero_divisors_of_torsion {R A} [Nontrivial R] [Ring R] [AddMonoid A] (a refine ⟨(Finset.range (addOrderOf a)).sum fun i : ℕ => single a 1 ^ i, single a 1 - single 0 1, ?_, ?_, ?_⟩ - · apply_fun fun x : R[A] => x 0 + · apply_fun fun x : R[A] => x.coeff 0 refine ne_of_eq_of_ne (?_ : (_ : R) = 1) one_ne_zero - rw [Finset.sum_apply'] + simp only [single_pow, one_pow, coeff_sum, coeff_single, Finset.sum_apply'] refine (Finset.sum_eq_single 0 ?_ ?_).trans ?_ · intro b hb b0 - rw [single_pow, one_pow, single_eq_of_ne'] + rw [Finsupp.single_eq_of_ne'] exact nsmul_ne_zero_of_lt_addOrderOf b0 (Finset.mem_range.mp hb) · grind - · rw [single_pow, one_pow, zero_smul, single_eq_same] - · apply_fun fun x : R[A] => x 0 - refine sub_ne_zero.mpr (ne_of_eq_of_ne (?_ : (_ : R) = 0) ?_) - · have a0 : a ≠ 0 := - ne_of_eq_of_ne (one_nsmul a).symm - (nsmul_ne_zero_of_lt_addOrderOf one_ne_zero (Nat.succ_le_iff.mp o2)) - simp only [a0, single_eq_of_ne', Ne, not_false_iff] - · simpa only [single_eq_same] using zero_ne_one + · simp + · apply_fun fun x : R[A] => x.coeff 0 + have a0 : a ≠ 0 := by rintro rfl; simp at o2 + simp [a0] · convert Commute.geom_sum₂_mul (R := AddMonoidAlgebra R A) _ (addOrderOf a) · rw [single_zero_one, one_pow, mul_one] · rw [single_pow, one_pow, addOrderOf_nsmul_eq_zero, single_zero_one, one_pow, sub_self] diff --git a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean index e1425d1a1ac8e2..7332a20631d816 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean @@ -6,9 +6,10 @@ Authors: Kim Morrison, Johan Commelin module public import Mathlib.Algebra.Category.ModuleCat.Monoidal.Basic +public import Mathlib.Algebra.MonoidAlgebra.Module +public import Mathlib.CategoryTheory.Linear.LinearFunctor public import Mathlib.CategoryTheory.Monoidal.Types.Basic public import Mathlib.LinearAlgebra.DirectSum.Finsupp -public import Mathlib.CategoryTheory.Linear.LinearFunctor /-! The functor of forming finitely supported functions on a type with values in a `[Ring R]` @@ -16,14 +17,12 @@ is the left adjoint of the forgetful functor from `R`-modules to types. -/ -@[expose] public section - +@[expose] public noncomputable section assert_not_exists Cardinal -noncomputable section - open CategoryTheory +open scoped MonoidAlgebra namespace ModuleCat @@ -42,6 +41,14 @@ def free : Type u ⥤ ModuleCat R where obj X := ModuleCat.of R (X →₀ R) map {_ _} f := ofHom <| Finsupp.lmapDomain _ _ (f : _ → _) +/-- The free functor `Type u ⥤ ModuleCat R` sending a type `X` to the +free `R`-module with generators `x : X`, implemented as the monoid algebra `R[X]`. +-/ +@[simps] +def monoidAlgebraFree : Type u ⥤ ModuleCat.{u} R where + obj X := .of R R[X] + map f := ofHom (MonoidAlgebra.mapDomainLinearMap R R f) + variable {R} /-- Constructor for elements in the module `(free R).obj X`. -/ diff --git a/Mathlib/Algebra/FreeAlgebra/Cardinality.lean b/Mathlib/Algebra/FreeAlgebra/Cardinality.lean index 1cc73f68cf28af..2eb4f5e46b36ce 100644 --- a/Mathlib/Algebra/FreeAlgebra/Cardinality.lean +++ b/Mathlib/Algebra/FreeAlgebra/Cardinality.lean @@ -8,6 +8,8 @@ module public import Mathlib.Algebra.FreeAlgebra public import Mathlib.SetTheory.Cardinal.Free +import Mathlib.Algebra.MonoidAlgebra.Cardinal + /-! # Cardinality of free algebras @@ -31,18 +33,17 @@ variable (X : Type v) theorem cardinalMk_eq_max_lift [Nonempty X] [Nontrivial R] : #(FreeAlgebra R X) = Cardinal.lift.{v} #R ⊔ Cardinal.lift.{u} #X ⊔ ℵ₀ := by have hX := mk_freeMonoid X - rw [equivMonoidAlgebraFreeMonoid.toEquiv.cardinal_eq, MonoidAlgebra, - mk_finsupp_lift_of_infinite, hX, lift_max, lift_aleph0, sup_comm, ← sup_assoc] + rw [equivMonoidAlgebraFreeMonoid.toEquiv.cardinal_eq, + MonoidAlgebra.cardinalMk_eq_max_lift_of_infinite, hX, lift_max, lift_aleph0, sup_assoc] @[simp] theorem cardinalMk_eq_lift [IsEmpty X] : #(FreeAlgebra R X) = Cardinal.lift.{v} #R := by - have := lift_mk_eq'.2 ⟨show (FreeMonoid X →₀ R) ≃ R from Finsupp.uniqueEquiv 1⟩ - rw [lift_id'.{u, v}, lift_umax] at this - rwa [equivMonoidAlgebraFreeMonoid.toEquiv.cardinal_eq, MonoidAlgebra] + simp [equivMonoidAlgebraFreeMonoid.toEquiv.cardinal_eq, + MonoidAlgebra.cardinalMk_eq_lift_of_fintype] @[nontriviality] theorem cardinalMk_eq_one [Subsingleton R] : #(FreeAlgebra R X) = 1 := by - rw [equivMonoidAlgebraFreeMonoid.toEquiv.cardinal_eq, MonoidAlgebra, mk_eq_one] + rw [equivMonoidAlgebraFreeMonoid.toEquiv.cardinal_eq, mk_eq_one] theorem cardinalMk_le_max_lift : #(FreeAlgebra R X) ≤ Cardinal.lift.{v} #R ⊔ Cardinal.lift.{u} #X ⊔ ℵ₀ := by diff --git a/Mathlib/Algebra/Lie/Loop.lean b/Mathlib/Algebra/Lie/Loop.lean index 071293eeccbd6a..3999d5c9248969 100644 --- a/Mathlib/Algebra/Lie/Loop.lean +++ b/Mathlib/Algebra/Lie/Loop.lean @@ -86,6 +86,7 @@ lemma toFinsupp_single_tmul (c : A) (z : L) : simp [← toFinsupp_symm_single] open Finsupp in +set_option backward.isDefEq.respectTransparency false in /-- The residue pairing on the loop algebra. When `A = ℤ` and the elements are viewed as Laurent polynomials with coefficients in `L`, the pairing is interpreted as `(f, g) ↦ Res f dg`. -/ @[simps] diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index 5a7c4928ebada5..6885b8460a0502 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -46,7 +46,7 @@ values on the monomials `single a 1`. -/] theorem nonUnitalAlgHom_ext [DistribMulAction R A] {φ₁ φ₂ : R[M] →ₙₐ[R] A} (h : ∀ x, φ₁ (single x 1) = φ₂ (single x 1)) : φ₁ = φ₂ := NonUnitalAlgHom.to_distribMulActionHom_injective <| - Finsupp.distribMulActionHom_ext' fun a => DistribMulActionHom.ext_ring (h a) + MonoidAlgebra.distribMulActionHom_ext' fun a => DistribMulActionHom.ext_ring (h a) /-- See note [partially-applied ext lemmas]. -/ @[ext high] @@ -60,28 +60,14 @@ non-associative algebras over `R` is adjoint to the forgetful functor in the oth @[simps apply_apply symm_apply] def liftMagma [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : (M →ₙ* A) ≃ (R[M] →ₙₐ[R] A) where - toFun f := - { liftAddHom fun x => (smulAddHom R A).flip (f x) with - toFun := fun a => a.sum fun m t => t • f m - map_smul' := fun t' a => by - rw [Finsupp.smul_sum, sum_smul_index'] - · simp_rw [smul_assoc, MonoidHom.id_apply] - · intro m - exact zero_smul R (f m) - map_mul' := fun a₁ a₂ => by - let g : M → R → A := fun m t => t • f m - have h₁ : ∀ m, g m 0 = 0 := by - intro m - exact zero_smul R (f m) - have h₂ : ∀ (m) (t₁ t₂ : R), g m (t₁ + t₂) = g m t₁ + g m t₂ := by - intros - rw [← add_smul] - -- Porting note: `reducible` cannot be `local` so proof gets long. - simp_rw [Finsupp.mul_sum, Finsupp.sum_mul, smul_mul_smul_comm, ← f.map_mul, mul_def, - sum_comm a₂ a₁] - rw [sum_sum_index h₁ h₂]; congr; ext - rw [sum_sum_index h₁ h₂]; congr; ext - rw [sum_single_index (h₁ _)] } + toFun f := { + toAddMonoidHom := + (liftAddHom fun x ↦ (smulAddHom R A).flip (f x)).comp coeffAddEquiv.toAddMonoidHom + map_smul' t' a := by simp [Finsupp.smul_sum, sum_smul_index', mul_smul] + map_mul' a₁ a₂ := by + simpa [mul_def, sum_sum_index, add_smul, Finsupp.mul_sum, Finsupp.sum_mul, + smul_mul_smul_comm] using Finsupp.sum_comm .. + } invFun F := F.toMulHom.comp (ofMagma R M) left_inv f := by ext; simp right_inv F := by ext; simp @@ -103,14 +89,8 @@ In particular this provides the instance `Algebra R R[M]`. -/ In particular this provides the instance `Algebra R R[M]`. -/] instance algebra : Algebra R A[M] where algebraMap := singleOneRingHom.comp (algebraMap R A) - smul_def' := fun r a => by - ext - dsimp - rw [single_one_mul_apply, Algebra.smul_def] - commutes' := fun r f => by - ext - dsimp - rw [single_one_mul_apply, mul_single_one_apply, Algebra.commutes] + smul_def' r a := by ext; simp [coeff_single_one_mul, Algebra.smul_def] + commutes' r f := by ext; simp [coeff_single_one_mul, coeff_mul_single_one, Algebra.commutes] /-- `MonoidAlgebra.single 1` as an `AlgHom` -/ @[to_additive (dont_translate := R A) (attr := simps! apply) @@ -141,9 +121,19 @@ variable (R M) in /-- The trivial monoid algebra is the base ring. -/ @[to_additive (dont_translate := R A) /-- The trivial monoid algebra is the base ring. -/] -def uniqueAlgEquiv [Unique M] : A[M] ≃ₐ[R] A where +def uniqueAlgEquiv [Subsingleton M] : A[M] ≃ₐ[R] A where toRingEquiv := uniqueRingEquiv _ - commutes' r := by simp [Unique.eq_default] + commutes' r := by simp + +variable (R M) in +@[to_additive (dont_translate := A) (attr := simp)] +lemma uniqueAlgEquiv_symm_apply [Subsingleton M] (a : A) : + (uniqueAlgEquiv R M).symm a = single 1 a := by classical ext; simp [uniqueAlgEquiv] + +-- We want this lemma to fire before `uniqueAlgEquiv_symm_apply`. +@[to_additive (dont_translate := A) (attr := simp↓ high)] +lemma coeff_uniqueAlgEquiv_symm [Subsingleton M] (a : A) (m : M) : + ((uniqueAlgEquiv R M).symm a).coeff m = a := by simp [Subsingleton.elim m 1] variable (R M) in @[to_additive (attr := simp)] @@ -166,8 +156,8 @@ def curryAlgEquiv : A[M × N] ≃ₐ[R] A[N][M] where toRingEquiv := curryRingEquiv commutes' r := by ext - simp [MonoidAlgebra, algebraMap, Algebra.algebraMap, singleOneRingHom, curryRingEquiv, - EquivLike.toEquiv, singleAddHom, curryAddEquiv] + simp [curryRingEquiv, curryAddEquiv, algebraMap, algebraMap, Algebra.algebraMap, + singleOneRingHom, singleAddHom, curryAddEquiv, ← ofCoeff_single] @[to_additive (attr := simp)] lemma curryAlgEquiv_single (m : M) (n : N) (a : A) : @@ -176,7 +166,7 @@ lemma curryAlgEquiv_single (m : M) (n : N) (a : A) : @[to_additive (attr := simp)] lemma curryAlgEquiv_symm_single (m : M) (n : N) (a : A) : (curryAlgEquiv R).symm (single m <| single n a) = (single (m, n) a) := by - classical exact Finsupp.uncurry_single .. + simp [curryAlgEquiv] end Algebra @@ -237,11 +227,11 @@ def lift : (M →* A) ≃ (R[M] →ₐ[R] A) where right_inv F := by ext; simp theorem lift_apply' (F : M →* A) (f : R[M]) : - lift R A M F f = f.sum fun a b => algebraMap R A b * F a := + lift R A M F f = f.coeff.sum fun a b => algebraMap R A b * F a := rfl theorem lift_apply (F : M →* A) (f : R[M]) : - lift R A M F f = f.sum fun a b => b • F a := by simp only [lift_apply', Algebra.smul_def] + lift R A M F f = f.coeff.sum fun a b => b • F a := by simp only [lift_apply', Algebra.smul_def] theorem lift_def (F : M →* A) : ⇑(lift R A M F) = liftNC (algebraMap R A) F := rfl @@ -260,21 +250,20 @@ theorem lift_unique' (F : R[M] →ₐ[R] A) : F = lift R A M ((F : R[M] →* A). /-- Decomposition of a `R`-algebra homomorphism from `R[M]` by its values on `F (single a 1)`. -/ theorem lift_unique (F : R[M] →ₐ[R] A) (f : R[M]) : - F f = f.sum fun a b => b • F (single a 1) := by + F f = f.coeff.sum fun a b => b • F (single a 1) := by conv_lhs => rw [lift_unique' F] simp [lift_apply] -set_option backward.isDefEq.respectTransparency false in theorem lift_mapRingHom_algebraMap [CommSemiring S] [Algebra S A] [Algebra R S] [IsScalarTower R S A] (f : M →* A) (x : R[M]) : lift _ _ _ f (mapRingHom _ (algebraMap R S) x) = lift _ _ _ f x := by - induction x using Finsupp.induction with + induction x using induction with | zero => simp | single_add a b f _ _ ih => simp [ih] -@[deprecated (since := "2026-03-20")] +@[deprecated (since := "2026-06-18")] alias lift_mapRangeRingHom_algebraMap := lift_mapRingHom_algebraMap variable (R A) in @@ -307,15 +296,17 @@ def domCongr (e : M ≃* N) : A[M] ≃ₐ[R] A[N] where commutes' _ := by ext; simp @[to_additive (attr := simp)] -lemma domCongr_apply (e : M ≃* N) (x : A[M]) (n : N) : domCongr R A e x n = x (e.symm n) := by - simp [domCongr] +lemma coeff_domCongr (e : M ≃* N) (f : A[M]) (n : N) : + (domCongr R A e f).coeff n = f.coeff (e.symm n) := by simp [domCongr] + +@[deprecated (since := "2026-06-18")] alias domCongr_apply := coeff_domCongr @[to_additive] theorem domCongr_toAlgHom (e : M ≃* N) : (domCongr R A e).toAlgHom = mapDomainAlgHom R A e := rfl @[to_additive (attr := simp)] -lemma domCongr_support (e : M ≃* N) (f : A[M]) : (domCongr R A e f).support = f.support.map e := by - ext; simp +lemma domCongr_support (e : M ≃* N) (x : A[M]) : + (domCongr R A e x).coeff.support = x.coeff.support.map e := by simp [domCongr, equivMapDomain] @[to_additive (attr := simp)] theorem domCongr_single (e : M ≃* N) (m : M) (a : A) : @@ -383,7 +374,7 @@ lemma mapDomainRingHom_comp_algebraMap (f : M →* N) : lemma mapRingHom_comp_algebraMap (f : R →+* S) : (mapRingHom (M := M) f).comp (algebraMap _ _) = (algebraMap _ _).comp f := by ext; simp -@[deprecated (since := "2026-03-20")] +@[deprecated (since := "2026-06-18")] alias mapRangeRingHom_comp_algebraMap := mapRingHom_comp_algebraMap variable (M) in @@ -395,20 +386,21 @@ noncomputable def mapAlgHom (f : A →ₐ[R] B) : A[M] →ₐ[R] B[M] where __ := mapRingHom M f commutes' := by simp -@[deprecated (since := "2026-03-20")] alias mapRangeAlgHom := mapAlgHom +@[deprecated (since := "2026-06-18")] alias mapRangeAlgHom := mapAlgHom variable (M) in @[to_additive (attr := simp)] lemma toRingHom_mapAlgHom (f : A →ₐ[R] B) : mapAlgHom M f = mapRingHom M f.toRingHom := rfl -@[deprecated (since := "2026-03-20")] alias toRingHom_mapRangeAlgHom := toRingHom_mapAlgHom +@[deprecated (since := "2026-06-18")] alias toRingHom_mapRangeAlgHom := toRingHom_mapAlgHom @[to_additive (attr := simp)] -lemma mapAlgHom_apply (f : A →ₐ[R] B) (x : A[M]) (m : M) : - mapAlgHom M f x m = f (x m) := mapRingHom_apply f.toRingHom x m +lemma coeff_mapAlgHom (f : A →ₐ[R] B) (x : A[M]) (m : M) : + (mapAlgHom M f x).coeff m = f (x.coeff m) := by simp [mapAlgHom] -@[deprecated (since := "2026-03-20")] alias mapRangeAlgHom_apply := mapAlgHom_apply +@[deprecated (since := "2026-06-18")] alias mapAlgHom_apply := coeff_mapAlgHom +@[deprecated (since := "2026-06-18")] alias mapRangeAlgHom_apply := coeff_mapAlgHom @[to_additive (attr := simp)] lemma mapAlgHom_single (f : A →ₐ[R] B) (m : M) (a : A) : @@ -426,7 +418,7 @@ lemma mapRangeAlgHom_comp {k R S T G} [CommSemiring k] [Semiring R] [Algebra k R mapAlgHom G (g.comp f) = (mapAlgHom G g).comp (mapAlgHom G f) := by ext; simp -@[deprecated (since := "2026-03-20")] alias mapRangeAlgHom_single := mapAlgHom_single +@[deprecated (since := "2026-06-18")] alias mapRangeAlgHom_single := mapAlgHom_single variable (R M) in /-- The algebra isomorphism of monoid algebras induced by an isomorphism of the base algebras. -/ @@ -439,12 +431,12 @@ noncomputable def mapAlgEquiv (e : A ≃ₐ[R] B) : A[M] ≃ₐ[R] B[M] where left_inv _ := by aesop right_inv _ := by aesop -@[deprecated (since := "2026-03-20")] alias mapRangeAlgEquiv := mapAlgEquiv +@[deprecated (since := "2026-06-18")] alias mapRangeAlgEquiv := mapAlgEquiv @[to_additive (attr := simp)] lemma symm_mapAlgEquiv (e : A ≃ₐ[R] B) : (mapAlgEquiv R M e).symm = mapAlgEquiv R M e.symm := rfl -@[deprecated (since := "2026-03-20")] alias symm_mapRangeAlgEquiv := symm_mapAlgEquiv +@[deprecated (since := "2026-06-18")] alias symm_mapRangeAlgEquiv := symm_mapAlgEquiv @[to_additive (attr := simp)] lemma mapAlgEquiv_trans (e₁ : A ≃ₐ[R] B) (e₂ : B ≃ₐ[R] C) : @@ -484,7 +476,6 @@ variable [Monoid M] [CommSemiring R] {V W : Type*} [AddCommMonoid V] [Module R V [Module R W] [Module R[M] W] [IsScalarTower R R[M] W] (f : V →ₗ[R] W) -set_option backward.isDefEq.respectTransparency false in /-- Build a `R[M]`-linear map from a `R`-linear map and evidence that it is `M`-equivariant. -/ def equivariantOfLinearOfComm (h : ∀ (g : M) (v : V), f (single g (1 : R) • v) = single g (1 : R) • f v) : @@ -492,7 +483,7 @@ def equivariantOfLinearOfComm toFun := f map_add' v v' := by simp map_smul' c v := by - refine Finsupp.induction c ?_ ?_ + refine induction c ?_ ?_ · simp · intro g r c' _nm _nz w dsimp at * @@ -553,17 +544,24 @@ theorem nonUnitalAlgHom_ext' [DistribMulAction R A] {φ₁ φ₂ : R[M] →ₙ (h : φ₁.toMulHom.comp (ofMagma R M) = φ₂.toMulHom.comp (ofMagma R M)) : φ₁ = φ₂ := nonUnitalAlgHom_ext R <| DFunLike.congr_fun h +set_option backward.isDefEq.respectTransparency false in /-- The functor `M ↦ R[M]`, from the category of magmas to the category of non-unital, non-associative algebras over `R` is adjoint to the forgetful functor in the other direction. -/ @[simps apply_apply symm_apply] def liftMagma [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : - (Multiplicative M →ₙ* A) ≃ (R[M] →ₙₐ[R] A) := - { (MonoidAlgebra.liftMagma R : (Multiplicative M →ₙ* A) ≃ (_ →ₙₐ[R] A)) with - toFun f := - { (MonoidAlgebra.liftMagma R f :) with - toFun := fun a => sum a fun m t => t • f (Multiplicative.ofAdd m) } - invFun f := f.toMulHom.comp (ofMagma R M) } + (Multiplicative M →ₙ* A) ≃ (R[M] →ₙₐ[R] A) where + toFun f := { + toAddMonoidHom := + (liftAddHom fun x ↦ (smulAddHom R A).flip (f <| .ofAdd x)).comp coeffAddEquiv.toAddMonoidHom + map_smul' t' a := by simp [Finsupp.smul_sum, sum_smul_index', mul_smul] + map_mul' a₁ a₂ := by + simpa [mul_def, sum_sum_index, add_smul, Finsupp.mul_sum, Finsupp.sum_mul, + smul_mul_smul_comm] using Finsupp.sum_comm .. + } + invFun F := F.toMulHom.comp (ofMagma R M) + left_inv f := by ext; simp + right_inv F := by ext; simp end NonUnitalNonAssocAlgebra @@ -599,11 +597,10 @@ def lift : (Multiplicative M →* A) ≃ (R[M] →ₐ[R] A) where right_inv F := by ext; simp theorem lift_apply' (F : Multiplicative M →* A) (f : R[M]) : - lift R A M F f = f.sum fun a b => algebraMap R A b * F (Multiplicative.ofAdd a) := - rfl + lift R A M F f = f.coeff.sum fun a b => algebraMap R A b * F (.ofAdd a) := rfl theorem lift_apply (F : Multiplicative M →* A) (f : R[M]) : - lift R A M F f = f.sum fun a b => b • F (Multiplicative.ofAdd a) := by + lift R A M F f = f.coeff.sum fun a b => b • F (.ofAdd a) := by simp only [lift_apply', Algebra.smul_def] theorem lift_def (F : Multiplicative M →* A) : @@ -634,21 +631,19 @@ theorem lift_unique' (F : R[M] →ₐ[R] A) : /-- Decomposition of a `R`-algebra homomorphism from `R[M]` by its values on `F (single a 1)`. -/ theorem lift_unique (F : R[M] →ₐ[R] A) (f : R[M]) : - F f = f.sum fun a b => b • F (single a 1) := by + F f = f.coeff.sum fun m r => r • F (single m 1) := by conv_lhs => rw [lift_unique' F] simp [lift_apply] -set_option backward.isDefEq.respectTransparency false in -theorem lift_mapRingHom_algebraMap [CommSemiring S] [Algebra S A] - [Algebra R S] [IsScalarTower R S A] +lemma lift_mapRingHom_algebraMap [CommSemiring S] [Algebra S A] [Algebra R S] [IsScalarTower R S A] (f : Multiplicative M →* A) (x : R[M]) : lift _ _ _ f (mapRingHom _ (algebraMap R S) x) = lift _ _ _ f x := by - induction x using Finsupp.induction with + induction x using induction with | zero => simp | single_add a b f _ _ ih => simp [ih] -@[deprecated (since := "2026-03-20")] +@[deprecated (since := "2026-06-18")] alias lift_mapRangeRingHom_algebraMap := lift_mapRingHom_algebraMap lemma algHom_ext_iff {φ₁ φ₂ : R[M] →ₐ[R] A} : (∀ x, φ₁ (single x 1) = φ₂ (single x 1)) ↔ φ₁ = φ₂ := diff --git a/Mathlib/Algebra/MonoidAlgebra/Cardinal.lean b/Mathlib/Algebra/MonoidAlgebra/Cardinal.lean index cf9a6f46b0a9d7..ba09854b2ad99a 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Cardinal.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Cardinal.lean @@ -25,7 +25,7 @@ namespace MonoidAlgebra @[to_additive (attr := simp)] lemma cardinalMk_eq_lift_of_fintype [Fintype M'] : #R[M'] = lift.{v} #R ^ card M' := by - simp [MonoidAlgebra] + simp [coeffEquiv.cardinal_eq] @[deprecated (since := "2026-03-26")] alias cardinalMk_lift_of_fintype := cardinalMk_eq_lift_of_fintype @@ -35,7 +35,7 @@ lemma cardinalMk_of_fintype [Fintype M] : #R[M] = #R ^ card M := by simp @[to_additive (attr := simp)] lemma cardinalMk_eq_max_lift_of_infinite [Infinite M'] [Nontrivial R] : - #R[M'] = max (lift.{v} #R) (lift.{u} #M') := by simp [MonoidAlgebra, max_comm] + #R[M'] = max (lift.{v} #R) (lift.{u} #M') := by simp [coeffEquiv.cardinal_eq, max_comm] @[deprecated (since := "2026-03-26")] alias cardinalMk_lift_of_infinite := cardinalMk_eq_max_lift_of_infinite @@ -45,7 +45,7 @@ lemma cardinalMk_of_infinite [Infinite M] [Nontrivial R] : #R[M] = max #R #M := @[to_additive (attr := simp)] lemma cardinalMk_eq_max_lift_of_infinite' [Nonempty M'] [Infinite R] : - #R[M'] = max (lift.{v} #R) (lift.{u} #M') := by simp [MonoidAlgebra, max_comm] + #R[M'] = max (lift.{v} #R) (lift.{u} #M') := by simp [coeffEquiv.cardinal_eq, max_comm] @[deprecated (since := "2026-03-26")] alias cardinalMk_lift_of_infinite' := cardinalMk_eq_max_lift_of_infinite' diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index 8dbf75acb2780e..7ec4e9de20d3aa 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -24,17 +24,14 @@ conditions at all. In this case the construction yields a not-necessarily-unital not-necessarily-associative algebra but it is still adjoint to the forgetful functor from such algebras to magmas, and we prove this as `MonoidAlgebra.liftMagma`. -In this file we define `MonoidAlgebra R M := M →₀ R`, and `AddMonoidAlgebra R M` -in the same way, and then define the convolution product on these. +In this file we define `MonoidAlgebra R M` and `AddMonoidAlgebra R M` as one-field structures around +`M →₀ R`, and then define the convolution product on these. When the domain is additive, this is used to define polynomials: ``` Polynomial R := AddMonoidAlgebra R ℕ MvPolynomial σ α := AddMonoidAlgebra R (σ →₀ ℕ) ``` -Note: `Polynomial R` is currently a wrapper around `AddMonoidAlgebra R ℕ` and not defeq to it. -There is ongoing work to make it defeq. -See https://github.com/leanprover-community/mathlib4/pull/25273 When the domain is multiplicative, e.g. a group, this will be used to define the group ring. @@ -51,29 +48,45 @@ https://github.com/leanprover-community/mathlib4/pull/36746 https://github.com/leanprover-community/mathlib4/pull/25273 -/ -@[expose] public section assert_not_exists NonUnitalAlgHom AlgEquiv -noncomputable section +@[expose] public noncomputable section open Finsupp hiding single variable {R S G M N O ι : Type*} -/-- The monoid algebra over a semiring `R` generated by the monoid `M`. +/-- The additive monoid algebra over a semiring `R` generated by the additive monoid `M`. It is the type of finite formal `R`-linear combinations of terms of `M`, endowed with the convolution product. -/ -@[to_additive (relevant_arg := M) -/-- The additive monoid algebra over a semiring `R` generated by the additive monoid `M`. +structure AddMonoidAlgebra (R M : Type*) [Semiring R] where + /-- Construct an element of the additive monoid algebra `R[M]` + from its coefficients `M →₀ R`. -/ + ofCoeff :: + /-- The coefficients `M →₀ R` of an element of the additive monoid algebra `R[M]`. -/ + coeff : M →₀ R + +/-- The monoid algebra over a semiring `R` generated by the monoid `M`. It is the type of finite formal `R`-linear combinations of terms of `M`, -endowed with the convolution product. -/, to_additive_dont_translate] -def MonoidAlgebra (R M : Type*) [Semiring R] : Type _ := M →₀ R +endowed with the convolution product. -/ +@[to_additive (relevant_arg := M), to_additive_dont_translate] +structure MonoidAlgebra (R M : Type*) [Semiring R] where + /-- Construct an element of the monoid algebra `R[M]` + from its coefficients `M →₀ R`. -/ + ofCoeff :: + /-- The coefficients `M →₀ R` of an element of the monoid algebra `R[M]`. -/ + coeff : M →₀ R + +initialize_simps_projections AddMonoidAlgebra (as_prefix coeff) +initialize_simps_projections MonoidAlgebra (as_prefix coeff) namespace AddMonoidAlgebra +open Lean.PrettyPrinter Delaborator + @[inherit_doc AddMonoidAlgebra] scoped syntax:max (priority := high) term noWs "[" term "]" : term @@ -81,13 +94,22 @@ macro_rules | `($R[$M]) => `(AddMonoidAlgebra $R $M) /-- Unexpander for `AddMonoidAlgebra`. -/ @[scoped app_unexpander AddMonoidAlgebra] -meta def unexpander : Lean.PrettyPrinter.Unexpander +meta def unexpander : Unexpander | `($_ $R $M) => `($R[$M]) | _ => throw () +/-- This prevents `ofCoeff x` being printed as `{ coeff := x }` by `delabStructureInstance`. -/ +@[app_delab ofCoeff] meta def delabOfCoeff : Delab := delabApp + end AddMonoidAlgebra namespace MonoidAlgebra +section Notation + +open Lean.PrettyPrinter Delaborator + +/-- This prevents `ofCoeff x` being printed as `{ coeff := x }` by `delabStructureInstance`. -/ +@[app_delab ofCoeff] meta def delabOfCoeff : Delab := delabApp @[inherit_doc MonoidAlgebra] scoped syntax:max (priority := high) term noWs "[" term "]" : term @@ -96,25 +118,17 @@ macro_rules | `($R[$M]) => `(MonoidAlgebra $R $M) /-- Unexpander for `MonoidAlgebra`. -/ @[scoped app_unexpander MonoidAlgebra] -meta def unexpander : Lean.PrettyPrinter.Unexpander +meta def unexpander : Unexpander | `($_ $R $M) => `($R[$M]) | _ => throw () -section Semiring -variable [Semiring R] {x y : R[M]} {r r₁ r₂ : R} {m m' m₁ m₂ : M} - -/-- Construct an element of the monoid algebra `R[M]` from its coefficients `M →₀ R`. -/ -@[to_additive -/-- Construct an element of the additive monoid algebra `R[M]` from its coefficients `M →₀ R`. -/] -def ofCoeff (x : M →₀ R) : R[M] := x +end Notation -/-- The coefficients `M →₀ R` of an element of the monoid algebra `R[M]`. -/ -@[to_additive -/-- The coefficients `M →₀ R` of an element of the additive monoid algebra `R[M]`. -/] -def coeff (x : R[M]) : M →₀ R := x +section Semiring +variable [Semiring R] {x y : R[M]} {r r₁ r₂ : R} {m m' m₁ m₂ m₁' m₂' : M} -@[to_additive (attr := simp)] lemma coeff_ofCoeff (x : M →₀ R) : coeff (ofCoeff x) = x := rfl -@[to_additive (attr := simp)] lemma ofCoeff_coeff (x : R[M]) : ofCoeff x.coeff = x := rfl +@[to_additive] lemma coeff_ofCoeff (x : M →₀ R) : (ofCoeff x).coeff = x := rfl +@[to_additive] lemma ofCoeff_coeff (x : R[M]) : ofCoeff x.coeff = x := rfl /-- `MonoidAlgebra.coeff` as an equiv. -/ @[to_additive (attr := simps apply symm_apply) @@ -135,7 +149,8 @@ def coeffEquiv : R[M] ≃ (M →₀ R) where lemma coeff_injective : (coeff : R[M] → M →₀ R).Injective := coeffEquiv.injective @[to_additive] -lemma ofCoeff_injective : (ofCoeff : (M →₀ R) → R[M]).Injective := coeffEquiv.symm.injective +lemma ofCoeff_injective : (ofCoeff : (M →₀ R) → R[M]).Injective := + coeffEquiv.symm.injective @[to_additive (attr := simp)] lemma coeff_inj : x.coeff = y.coeff ↔ x = y := coeff_injective.eq_iff @@ -143,39 +158,27 @@ lemma coeff_inj : x.coeff = y.coeff ↔ x = y := coeff_injective.eq_iff @[to_additive] lemma ofCoeff_inj {x y : M →₀ R} : ofCoeff x = ofCoeff y ↔ x = y := ofCoeff_injective.eq_iff -@[to_additive] instance inhabited : Inhabited R[M] := - inferInstanceAs <| Inhabited <| M →₀ R - -@[to_additive] instance nontrivial [Nontrivial R] [Nonempty M] : Nontrivial R[M] := - inferInstanceAs <| Nontrivial <| M →₀ R - -@[to_additive] instance unique [Subsingleton R] : Unique R[M] := - inferInstanceAs <| Unique <| M →₀ R +@[to_additive (attr := ext)] alias ⟨ext, _⟩ := coeff_inj -@[to_additive] instance instDecidableEq [DecidableEq R] [DecidableEq M] : DecidableEq R[M] := - inferInstanceAs <| DecidableEq <| M →₀ R +@[to_additive] +instance instInhabited : Inhabited R[M] := fast_instance% coeffEquiv.inhabited --- TODO: this instance abuses definitional equality with `Finsupp.mapRange` -@[to_additive (dont_translate := A)] -instance {A : Type*} [SMulZeroClass A R] : SMul A R[M] where - smul a x := x.mapRange (a • ·) (smul_zero _) +@[to_additive] +instance instNontrivial [Nontrivial R] [Nonempty M] : Nontrivial R[M] := coeffEquiv.nontrivial -@[to_additive] instance addCommMonoid : AddCommMonoid R[M] := - inferInstanceAs <| AddCommMonoid <| M →₀ R +@[to_additive] +instance instUnique [Subsingleton R] : Unique R[M] := fast_instance% coeffEquiv.unique -@[to_additive] instance instIsCancelAdd [IsCancelAdd R] : IsCancelAdd R[M] := - inferInstanceAs <| IsCancelAdd <| M →₀ R +@[to_additive] +instance instDecidableEq [DecidableEq R] [DecidableEq M] : DecidableEq R[M] := + coeffEquiv.decidableEq --- TODO: Replace this with `coeff`. See https://github.com/leanprover-community/mathlib4/pull/36746 -#adaptation_note /-- Since nightly-2026-03-22, -this is needed or we get errors in UniversalFactorizationRing.lean -/ -set_option backward.inferInstanceAs.wrap false in -@[to_additive] instance instCoeFun : CoeFun R[M] fun _ ↦ M → R := - inferInstanceAs <| CoeFun (M →₀ R) fun _ ↦ M → R +@[to_additive instAddCommMonoid] +instance instAddCommMonoid : AddCommMonoid R[M] := fast_instance% coeffEquiv.addCommMonoid -/-- A copy of `Finsupp.ext` for `MonoidAlgebra`. -/ -@[to_additive (attr := ext) /-- A copy of `Finsupp.ext` for `AddMonoidAlgebra`. -/] -lemma ext ⦃f g : R[M]⦄ (hfg : ∀ m, f m = g m) : f = g := Finsupp.ext hfg +@[to_additive] +instance instIsCancelAdd [IsCancelAdd R] : IsCancelAdd R[M] := + coeffEquiv.isCancelAdd /-- `MonoidAlgebra.coeff` as an `AddEquiv`. -/ @[to_additive (attr := simps! apply symm_apply) @@ -210,13 +213,43 @@ lemma coeff_finsuppSum [AddCommMonoid N] (f : ι →₀ N) (g : ι → N → R[M lemma ofCoeff_finsuppSum [AddCommMonoid N] (f : ι →₀ N) (g : ι → N → M →₀ R) : ofCoeff (f.sum g) = f.sum (fun i n ↦ ofCoeff (g i n)) := map_finsuppSum coeffAddEquiv.symm .. --- TODO: This definition is very leaky, and we later have frequent problems conflating the two --- versions of `single`. Perhaps someone wants to try making this a `def` rather than an `abbrev`? --- In Mathlib 3 this was locally reducible. /-- `MonoidAlgebra.single m r` for `m : M`, `r : R` is the element `rm : R[M]`. -/ @[to_additive /-- `AddMonoidAlgebra.single m r` for `m : M`, `r : R` is the element `rm : R[M]`. -/] -abbrev single (m : M) (r : R) : R[M] := Finsupp.single m r +def single (m : M) (r : R) : R[M] := .ofCoeff <| .single m r + +@[to_additive (attr := simp)] +lemma coeff_single (m : M) (r : R) : (single m r).coeff = .single m r := rfl + +@[to_additive (attr := simp)] +lemma ofCoeff_single (m : M) (r : R) : ofCoeff (.single m r) = single m r := rfl + +@[to_additive] +lemma single_inj : single m₁ r₁ = single m₂ r₂ ↔ m₁ = m₂ ∧ r₁ = r₂ ∨ r₁ = 0 ∧ r₂ = 0 := by + simp [← coeff_inj, Finsupp.single_eq_single_iff] + +@[to_additive] +lemma single_left_inj (hr : r ≠ 0) : single m₁ r = single m₂ r ↔ m₁ = m₂ := by simp [single_inj, hr] + +@[to_additive (attr := simp)] +lemma single_right_inj : single m r₁ = single m r₂ ↔ r₁ = r₂ := by simp +contextual [single_inj] + +/-- `MonoidAlgebra.single m r` is injective in `m` if `r ≠ 0`. For injectivity in `r`, see +`MonoidAlgebra.single_injective`. -/ +@[to_additive +/-- `AddMonoidAlgebra.single m r` is injective in `m` if `r ≠ 0`. For injectivity in `r`, see +`AddMonoidAlgebra.single_injective`.-/] +lemma single_left_injective (hr : r ≠ 0) : Function.Injective fun m : M ↦ single m r := + fun _ _ ↦ (single_left_inj hr).1 + +@[to_additive] +lemma single_right_injective : (single m : R → R[M]).Injective := fun _ _ ↦ single_right_inj.1 + +@[to_additive] +lemma single_add_single_inj (hr₁ : r₁ ≠ 0) (hr₂ : r₂ ≠ 0) : + single m₁ r₁ + single m₂ r₂ = single m₁' r₁ + single m₂' r₂ ↔ + m₁ = m₁' ∧ m₂ = m₂' ∨ r₁ = r₂ ∧ m₁ = m₂' ∧ m₂ = m₁' ∨ r₁ + r₂ = 0 ∧ m₁ = m₂ ∧ m₁' = m₂' := by + simp [← coeff_inj, single_add_single_eq_single_add_single, *] /-- Remove a term from an element of the monoid algebra. -/ @[to_additive /-- Remove a term from an element of the additive monoid algebra. -/] @@ -229,11 +262,10 @@ lemma coeff_erase (m : M) (x : R[M]) : (x.erase m).coeff = x.coeff.erase m := rf lemma ofCoeff_erase (m : M) (x : M →₀ R) : ofCoeff (x.erase m) = (ofCoeff x).erase m := rfl @[to_additive (attr := simp)] -lemma erase_zero (m : M) : erase m (0 : R[M]) = 0 := by simp [erase] +lemma erase_zero (m : M) : erase m (0 : R[M]) = 0 := by ext; simp @[to_additive (attr := simp)] -lemma erase_single (m : M) (r : R) : erase m (single m r) = 0 := by - simp [erase, ofCoeff, coeff]; rfl +lemma erase_single (m : M) (r : R) : erase m (single m r) = 0 := by ext; simp /-- Replace the `m`-th coefficient of an element `x` of the monoid algebra by a given value `r : R`. If `r = 0`, this is equal to `x.erase m`. -/ @@ -264,12 +296,11 @@ Further results on scalar multiplication can be found in variable {A : Type*} [SMulZeroClass A R] @[to_additive (dont_translate := A) smulZeroClass] -instance smulZeroClass : SMulZeroClass A R[M] := - inferInstanceAs <| SMulZeroClass A (M →₀ R) +instance smulZeroClass : SMulZeroClass A R[M] := fast_instance% coeffEquiv.smulZeroClass _ section -- Ensure that the different smul instances do not create a diamond. -example : (smulZeroClass (A := ℕ) (R := R) (M := M)).smul = addCommMonoid.nsmul := by +example : (smulZeroClass (A := ℕ) (R := R) (M := M)).smul = instAddCommMonoid.nsmul := by with_reducible_and_instances rfl -- Ensure that smul has good defeq properties @@ -279,53 +310,58 @@ example [Monoid A] (a : Units A) (x : R[M]) : with_reducible_and_instances rfl end -@[to_additive (dont_translate := A) (attr := simp) coeff_smul] +@[to_additive (attr := simp) (dont_translate := A) coeff_smul] lemma coeff_smul (a : A) (x : R[M]) : coeff (a • x) = a • coeff x := rfl -@[to_additive (dont_translate := A) (attr := simp) ofCoeff_smul] +@[to_additive (attr := simp) (dont_translate := A) ofCoeff_smul] lemma ofCoeff_smul (a : A) (x : M →₀ R) : ofCoeff (a • x) = a • ofCoeff x := rfl -@[to_additive (attr := simp) (dont_translate := A) smul_apply] -lemma smul_apply (a : A) (x : R[M]) (m : M) : (a • x) m = a • x m := rfl +@[to_additive (dont_translate := A) coeff_smul_apply] +lemma coeff_smul_apply (a : A) (x : R[M]) (m : M) : coeff (a • x) m = a • coeff x m := rfl + +@[deprecated (since := "2026-06-18")] alias smul_apply := coeff_smul_apply @[to_additive (attr := simp) (dont_translate := A) smul_single] -lemma smul_single (a : A) (m : M) (r : R) : a • single m r = single m (a • r) := by - ext - simp [single, ← Finsupp.smul_single] +lemma smul_single (a : A) (m : M) (r : R) : a • single m r = single m (a • r) := by ext; simp @[to_additive (dont_translate := R) smul_single'] lemma smul_single' (r' : R) (m : M) (r : R) : r' • single m r = single m (r' * r) := smul_single .. @[to_additive (dont_translate := N) distribSMul] instance distribSMul [DistribSMul N R] : DistribSMul N R[M] := - inferInstanceAs <| DistribSMul N (M →₀ R) + fast_instance% coeffEquiv.distribSMul _ @[to_additive (dont_translate := N) isScalarTower] instance isScalarTower [SMulZeroClass N R] [SMulZeroClass O R] [SMul N O] [IsScalarTower N O R] : - IsScalarTower N O R[M] := - inferInstanceAs <| IsScalarTower N O (M →₀ R) + IsScalarTower N O R[M] := coeffEquiv.isScalarTower .. @[to_additive (dont_translate := N) smulCommClass] instance smulCommClass [SMulZeroClass N R] [SMulZeroClass O R] [SMulCommClass N O R] : - SMulCommClass N O R[M] := - inferInstanceAs <| SMulCommClass N O (M →₀ R) + SMulCommClass N O R[M] := coeffEquiv.smulCommClass .. @[to_additive (dont_translate := N) isCentralScalar] instance isCentralScalar [SMulZeroClass N R] [SMulZeroClass Nᵐᵒᵖ R] [IsCentralScalar N R] : - IsCentralScalar N R[M] := - inferInstanceAs <| IsCentralScalar N (M →₀ R) + IsCentralScalar N R[M] := coeffEquiv.isCentralScalar _ end SMul -@[to_additive (attr := simp, norm_cast)] -lemma coe_add (f g : R[G]) : ⇑(f + g) = f + g := rfl +@[to_additive (attr := simp)] +lemma single_zero (m : M) : (single m 0 : R[M]) = 0 := by simp [single] -@[to_additive] -lemma single_zero (m : M) : (single m 0 : R[M]) = 0 := Finsupp.single_zero m +@[to_additive (attr := simp)] +lemma single_add (m : M) (r₁ r₂ : R) : single m (r₁ + r₂) = single m r₁ + single m r₂ := by + ext; simp -@[to_additive] -lemma single_add (m : M) (r₁ r₂ : R) : single m (r₁ + r₂) = single m r₁ + single m r₂ := - Finsupp.single_add m r₁ r₂ +@[to_additive (attr := deprecated coeff_add (since := "2026-06-18"))] +lemma coe_add (f g : R[M]) : ⇑(f + g).coeff = f.coeff + g.coeff := rfl + +@[to_additive (attr := simp)] +lemma single_add_erase (m : M) (x : R[M]) : single m (x.coeff m) + x.erase m = x := by + ext; simp [Finsupp.single_add_erase] + +@[to_additive (attr := simp)] + lemma erase_add_single (m : M) (x : R[M]) : x.erase m + single m (x.coeff m) = x := by + ext; simp [Finsupp.erase_add_single] /-- `MonoidAlgebra.single` as an `AddMonoidHom`. @@ -339,6 +375,17 @@ def singleAddHom (m : M) : R →+ R[M] where map_zero' := single_zero _ map_add' := single_add _ +/-- If two additive homomorphisms from `R[M]` are equal on each `single r m`, +then they are equal. -/ +@[to_additive AddMonoidAlgebra.addMonoidHom_ext +/-- If two additive homomorphisms from `R[M]` are equal on each `single r m`, +then they are equal. -/] +lemma addMonoidHom_ext [AddZeroClass N] ⦃f g : R[M] →+ N⦄ + (h : ∀ m r, f (single m r) = g (single m r)) : f = g := by + have : f.comp coeffAddEquiv.symm.toAddMonoidHom = g.comp coeffAddEquiv.symm.toAddMonoidHom := + Finsupp.addHom_ext h + convert congr(($this).comp coeffAddEquiv.toAddMonoidHom) <;> ext <;> simp + /-- If two additive homomorphisms from `R[M]` are equal on each `single r m`, then they are equal. @@ -357,31 +404,51 @@ verify `f (single a 1) = g (single a 1)`. TODO: Rename to `addMonoidHom_ext'`. -/] lemma addHom_ext' {N : Type*} [AddZeroClass N] ⦃f g : R[M] →+ N⦄ (hfg : ∀ m, f.comp (singleAddHom m) = g.comp (singleAddHom m)) : f = g := - Finsupp.addHom_ext' hfg + addMonoidHom_ext <| by simpa [DFunLike.ext_iff] using hfg -@[to_additive] +@[to_additive (attr := deprecated Finsupp.sum_single_index (since := "2026-06-18"))] lemma sum_single_index [AddCommMonoid N] {m : M} {r : R} {h : M → R → N} (h_zero : h m 0 = 0) : - (single m r).sum h = h m r := by + (single m r).coeff.sum h = h m r := by simp [h_zero] @[to_additive (attr := simp)] -lemma sum_single (x : R[M]) : x.sum single = x := Finsupp.sum_single _ +lemma sum_coeff_single (f : R[M]) : f.coeff.sum single = f := by ext; simp -@[to_additive] -theorem single_apply {a a' : M} {b : R} [Decidable (a = a')] : - single a b a' = if a = a' then b else 0 := +@[to_additive (attr := deprecated sum_coeff_single (since := "2026-06-18"))] +alias sum_single := sum_coeff_single + +@[to_additive (attr := deprecated Finsupp.single_apply (since := "2026-06-18"))] +theorem coeff_single_apply {a a' : M} {b : R} [Decidable (a = a')] : + (single a b).coeff a' = if a = a' then b else 0 := Finsupp.single_apply +@[deprecated (since := "2026-06-18")] protected alias single_apply := coeff_single_apply + @[to_additive (attr := simp)] -lemma single_eq_zero : single m r = 0 ↔ r = 0 := Finsupp.single_eq_zero +lemma single_eq_zero : single m r = 0 ↔ r = 0 := by simp [← coeff_inj] + +@[to_additive] lemma single_ne_zero : single m r ≠ 0 ↔ r ≠ 0 := single_eq_zero.not -@[to_additive] lemma single_ne_zero : single m r ≠ 0 ↔ r ≠ 0 := by simp [single] +@[to_additive (attr := elab_as_elim)] +lemma induction {motive : R[M] → Prop} (x : R[M]) + (zero : motive 0) + (single_add : ∀ m r x, m ∉ x.coeff.support → r ≠ 0 → motive x → motive (single m r + x)) : + motive x := + Finsupp.induction (motive := fun x ↦ motive <| ofCoeff x) x.coeff + (by simpa using zero) (fun m r x ↦ single_add m r (ofCoeff x)) @[to_additive (attr := elab_as_elim)] lemma induction_linear {p : R[M] → Prop} (x : R[M]) (zero : p 0) - (add : ∀ x y : R[M], p x → p y → p (x + y)) (single : ∀ m r, p (single m r)) : - p x := - Finsupp.induction_linear x zero (fun _ _ ↦ add _ _) (fun _ _ ↦ single _ _) + (add : ∀ x y : R[M], p x → p y → p (x + y)) + (single : ∀ m r, p (single m r)) : p x := + Finsupp.induction_linear (motive := (p <| ofCoeff ·)) x.coeff zero (fun _ _ ↦ add _ _) + (fun _ _ ↦ single _ _) + +@[to_additive (attr := simp) addSubmonoidClosure_single] +lemma addSubmonoidClosure_single : + AddSubmonoid.closure {x : R[M] | ∃ m r, x = single m r} = ⊤ := + top_unique fun x _hx => induction x (AddSubmonoid.zero_mem _) fun a b _f _ha _hb => + AddSubmonoid.add_mem _ <| AddSubmonoid.subset_closure <| ⟨a, b, rfl⟩ section One variable [One M] @@ -396,73 +463,79 @@ instance one : One R[M] where one := single 1 1 @[to_additive (dont_translate := R) one_def] lemma one_def : (1 : R[M]) = single 1 1 := rfl +@[to_additive (attr := simp) (dont_translate := R)] +lemma coeff_one_one : (1 : R[M]).coeff 1 = 1 := by simp [one_def] + end One section Mul variable [Mul M] -/-- The multiplication in a monoid algebra. +/-- The multiplication in an additive monoid algebra. We make it irreducible so that Lean doesn't unfold it when trying to unify two different things. -/ -@[irreducible] def mul' (x y : R[M]) : R[M] := - x.sum fun m₁ r₁ ↦ y.sum fun m₂ r₂ ↦ single (m₁ * m₂) (r₁ * r₂) +@[no_expose] +def _root_.AddMonoidAlgebra.mul' [Add M] (x y : AddMonoidAlgebra R M) : AddMonoidAlgebra R M := + x.coeff.sum fun m₁ r₁ ↦ y.coeff.sum fun m₂ r₂ ↦ .single (m₁ + m₂) (r₁ * r₂) +/-- The multiplication in a monoid algebra. -/-- The product of `f g : k[G]` is the finitely supported function -whose value at `a` is the sum of `f x * g y` over all pairs `x, y` -such that `x + y = a`. (Think of the product of multivariate -polynomials where `α` is the additive monoid of monomial exponents.) -/ -instance _root_.AddMonoidAlgebra.instMul [Add M] : Mul (AddMonoidAlgebra R M) where - mul f g := MonoidAlgebra.mul' (M := Multiplicative M) f g +We make it irreducible so that Lean doesn't unfold it when trying to unify two different things. -/ +@[to_additive existing mul', no_expose] +def mul' (x y : R[M]) : R[M] := + x.coeff.sum fun m₁ r₁ ↦ y.coeff.sum fun m₂ r₂ ↦ single (m₁ * m₂) (r₁ * r₂) /-- The product of `x y : R[M]` is the finitely supported function whose value at `m` -is the sum of `x m₁ * y m₂` over all pairs `m₁, m₂` such that `m₁ * m₂ = m`. - -(Think of the group ring of a group.) -/ -@[to_additive existing instMul] +is the sum of `x m₁ * y m₂` over all pairs `m₁, m₂` such that `m₁ * m₂ = m`. -/ +@[to_additive instMul +/-- The product of `x y : R[M]` is the finitely supported function whose value at `m` +is the sum of `x m₁ * y m₂` over all pairs `m₁, m₂` such that `m₁ + m₂ = m`. -/] instance instMul : Mul R[M] where mul := mul' @[to_additive (dont_translate := R) mul_def] lemma mul_def (x y : R[M]) : - x * y = x.sum fun m₁ r₁ ↦ y.sum fun m₂ r₂ ↦ single (m₁ * m₂) (r₁ * r₂) := by + x * y = x.coeff.sum fun m₁ r₁ ↦ y.coeff.sum fun m₂ r₂ ↦ single (m₁ * m₂) (r₁ * r₂) := by with_unfolding_all rfl -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance nonUnitalNonAssocSemiring : NonUnitalNonAssocSemiring R[M] where zero_mul := by simp [mul_def] mul_zero := by simp [mul_def] - left_distrib := by classical simp [mul_def]; simp [MonoidAlgebra, sum_add_index, mul_add] - right_distrib := by classical simp [mul_def]; simp [MonoidAlgebra, sum_add_index, add_mul] - -set_option backward.isDefEq.respectTransparency false in -@[to_additive (dont_translate := R) mul_apply] -lemma mul_apply [DecidableEq M] (x y : R[M]) (m : M) : - (x * y) m = x.sum fun m₁ r₁ ↦ y.sum fun m₂ r₂ ↦ if m₁ * m₂ = m then r₁ * r₂ else 0 := by - -- Porting note: `reducible` cannot be `local` so proof gets long. - rw [mul_def, Finsupp.sum_apply]; congr; ext - rw [Finsupp.sum_apply]; congr; ext - apply single_apply + left_distrib := by classical simp [mul_def, mul_add, sum_add, sum_add_index] + right_distrib := by classical simp [mul_def, add_mul, sum_add, sum_add_index] + +@[to_additive (dont_translate := R) coeff_mul] +lemma coeff_mul [DecidableEq M] (x y : R[M]) (m : M) : + (x * y).coeff m = + x.coeff.sum fun m₁ r₁ ↦ y.coeff.sum fun m₂ r₂ ↦ if m₁ * m₂ = m then r₁ * r₂ else 0 := by + simp [mul_def, Finsupp.single_apply] + +@[to_additive (attr := deprecated coeff_mul (since := "2026-06-18")) (dont_translate := R) + mul_apply] +alias mul_apply := coeff_mul open Finset in -@[to_additive (dont_translate := R) mul_apply_antidiagonal] -lemma mul_apply_antidiagonal (x y : R[M]) (m : M) (s : Finset (M × M)) - (hs : ∀ {p}, p ∈ s ↔ p.1 * p.2 = m) : (x * y) m = ∑ p ∈ s, x p.1 * y p.2 := by +@[to_additive (dont_translate := R) coeff_mul_antidiag] +lemma coeff_mul_antidiag (x y : R[M]) (m : M) (s : Finset (M × M)) + (hs : ∀ {p}, p ∈ s ↔ p.1 * p.2 = m) : (x * y).coeff m = ∑ p ∈ s, x.coeff p.1 * y.coeff p.2 := by classical - let F (p : M × M) : R := if p.1 * p.2 = m then x p.1 * y p.2 else 0 + let F (p : M × M) : R := if p.1 * p.2 = m then x.coeff p.1 * y.coeff p.2 else 0 calc - (x * y) m = ∑ m₁ ∈ x.support, ∑ m₂ ∈ y.support, F (m₁, m₂) := mul_apply .. - _ = ∑ p ∈ x.support ×ˢ y.support with p.1 * p.2 = m, x p.1 * y p.2 := by + (x * y).coeff m = ∑ m₁ ∈ x.coeff.support, ∑ m₂ ∈ y.coeff.support, F (m₁, m₂) := coeff_mul .. + _ = ∑ p ∈ x.coeff.support ×ˢ y.coeff.support with p.1 * p.2 = m, x.coeff p.1 * y.coeff p.2 := by rw [Finset.sum_filter, Finset.sum_product] - _ = ∑ p ∈ s with p.1 ∈ x.support ∧ p.2 ∈ y.support, x p.1 * y p.2 := by + _ = ∑ p ∈ s with p.1 ∈ x.coeff.support ∧ p.2 ∈ y.coeff.support, x.coeff p.1 * y.coeff p.2 := by congr! 1; ext; simp only [mem_filter, mem_product, hs, and_comm] - _ = ∑ p ∈ s, x p.1 * y p.2 := + _ = ∑ p ∈ s, x.coeff p.1 * y.coeff p.2 := sum_subset (filter_subset _ _) fun p hps hp => by simp only [mem_filter, mem_support_iff, not_and, Classical.not_not] at hp ⊢ - by_cases h1 : x p.1 = 0 + by_cases h1 : x.coeff p.1 = 0 · rw [h1, zero_mul] · rw [hp hps h1, mul_zero] -set_option backward.isDefEq.respectTransparency false in +@[to_additive (attr := deprecated coeff_mul_antidiag (since := "2026-06-18")) (dont_translate := R) + mul_apply_antidiagonal] +alias mul_apply_antidiagonal := coeff_mul_antidiag + @[to_additive (attr := simp) (dont_translate := R) single_mul_single] lemma single_mul_single (m₁ m₂ : M) (r₁ r₂ : R) : single m₁ r₁ * single m₂ r₂ = single (m₁ * m₂) (r₁ * r₂) := by simp [mul_def] @@ -478,59 +551,71 @@ lemma single_commute (hm : ∀ m', Commute m m') (hr : ∀ r', Commute r r') (x ext m' r' : 2; exact single_commute_single (hm m') (hr r') exact congr($this x) -@[to_additive (dont_translate := R) mul_single_apply_aux] -lemma mul_single_apply_aux (H : ∀ m' ∈ x.support, m' * m = m₁ ↔ m' = m₂) : - (x * single m r) m₁ = x m₂ * r := by +@[to_additive (dont_translate := R) coeff_mul_single_eq_coeff_mul] +lemma coeff_mul_single_eq_coeff_mul (m₂ : M) (H : ∀ m' ∈ x.coeff.support, m' * m = m₁ ↔ m' = m₂) : + (x * single m r).coeff m₁ = x.coeff m₂ * r := by classical calc - (x * single m r) m₁ - _ = x.sum fun m' r' ↦ if m' * m = m₁ then r' * r else 0 := by simp [mul_apply] - _ = x.sum fun m' r' ↦ if m' = m₂ then r' * r else 0 := by - dsimp [Finsupp.sum]; congr! 2; simp [*] - _ = x m₂ * r := by simp +contextual [Finsupp.sum_eq_single m₂] - -@[to_additive (dont_translate := R) single_mul_apply_aux] -lemma single_mul_apply_aux (H : ∀ m' ∈ x.support, m * m' = m₁ ↔ m' = m₂) : - (single m r * x) m₁ = r * x m₂ := by + (x * single m r).coeff m₁ + _ = x.coeff.sum fun m' r' ↦ if m' * m = m₁ then r' * r else 0 := by simp [coeff_mul] + _ = x.coeff.sum fun m' r' ↦ if m' = m₂ then r' * r else 0 := by gcongr; simp [*] + _ = x.coeff m₂ * r := by simp +contextual [Finsupp.sum_eq_single m₂] + +@[deprecated (since := "2026-06-18")] alias mul_single_apply_aux := coeff_mul_single_eq_coeff_mul + +@[to_additive (dont_translate := R) coeff_single_mul_eq_mul_coeff] +lemma coeff_single_mul_eq_mul_coeff (m₂ : M) (H : ∀ m' ∈ x.coeff.support, m * m' = m₁ ↔ m' = m₂) : + (single m r * x).coeff m₁ = r * x.coeff m₂ := by classical calc - (single m r * x) m₁ - _ = x.sum fun m' r' ↦ if m * m' = m₁ then r * r' else 0 := by simp [mul_apply] - _ = x.sum fun m' r' ↦ if m' = m₂ then r * r' else 0 := by - dsimp [Finsupp.sum]; congr! 2; simp [*] - _ = r * x m₂ := by simp +contextual [Finsupp.sum_eq_single m₂] + (single m r * x).coeff m₁ + _ = x.coeff.sum fun m' r' ↦ if m * m' = m₁ then r * r' else 0 := by simp [coeff_mul] + _ = x.coeff.sum fun m' r' ↦ if m' = m₂ then r * r' else 0 := by gcongr; simp [*] + _ = r * x.coeff m₂ := by simp +contextual [Finsupp.sum_eq_single m₂] + +@[deprecated (since := "2026-06-18")] alias single_mul_apply_aux := coeff_single_mul_eq_mul_coeff + +@[to_additive (attr := simp) (dont_translate := R) coeff_mul_single_of_forall_add_ne] +lemma coeff_mul_single_of_forall_mul_ne (r : R) (x : R[M]) (h : ∀ d, d * m ≠ m') : + (x * single m r).coeff m' = 0 := by classical simp [coeff_mul, h] -@[to_additive (attr := simp) (dont_translate := R) mul_single_apply_of_not_exists_add] -lemma mul_single_apply_of_not_exists_mul (r : R) (x : R[M]) (h : ¬ ∃ d, m' = d * m) : - (x * single m r) m' = 0 := by classical simp_all [mul_apply, eq_comm] +@[to_additive (attr := simp) (dont_translate := R) coeff_single_mul_of_forall_add_ne] +lemma coeff_single_mul_of_forall_mul_ne (r : R) (x : R[M]) (h : ∀ d, m * d ≠ m') : + (single m r * x).coeff m' = 0 := by classical simp [coeff_mul, h] -@[to_additive (attr := simp) (dont_translate := R) single_mul_apply_of_not_exists_add] -lemma single_mul_apply_of_not_exists_mul (r : R) (x : R[M]) (h : ¬ ∃ d, m' = m * d) : - (single m r * x) m' = 0 := by classical simp_all [mul_apply, eq_comm] +@[to_additive (attr := deprecated coeff_mul_single_of_forall_mul_ne (since := "2026-06-18")) + (dont_translate := R)] +lemma mul_single_apply_of_not_exists_mul (r : R) {g g' : M} (x : R[M]) + (h : ¬∃ d, g' = d * g) : (x * single g r).coeff g' = 0 := + coeff_mul_single_of_forall_mul_ne _ _ <| by simpa [eq_comm] using h + +@[to_additive (attr := deprecated coeff_single_mul_of_forall_mul_ne (since := "2026-06-18")) + (dont_translate := R)] +lemma single_mul_apply_of_not_exists_mul (r : R) {g g' : M} (x : R[M]) + (h : ¬∃ d, g' = g * d) : (single g r * x).coeff g' = 0 := + coeff_single_mul_of_forall_mul_ne _ _ <| by simpa [eq_comm] using h variable (R M : Type*) [Semiring R] [Mul M] in /-- The embedding of a magma into its magma algebra. -/ @[simps] def ofMagma : M →ₙ* R[M] where toFun a := single a 1 - map_mul' a b := by simp only [mul_def, mul_one, sum_single_index, single_eq_zero, mul_zero] + map_mul' a b := by ext; simp [mul_def, Finsupp.sum_single_index] end Mul section Semigroup variable [Semigroup M] -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance nonUnitalSemiring : NonUnitalSemiring R[M] where - mul_assoc := by simp [mul_def]; simp [MonoidAlgebra, sum_sum_index, mul_add, add_mul, mul_assoc] + mul_assoc := by simp [mul_def, sum_sum_index, mul_add, add_mul, mul_assoc] end Semigroup section MulOneClass variable [MulOneClass M] -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance nonAssocSemiring : NonAssocSemiring R[M] where natCast n := single 1 n @@ -540,26 +625,40 @@ instance nonAssocSemiring : NonAssocSemiring R[M] where mul_one := by simp [mul_def, one_def] @[to_additive (dont_translate := R)] -lemma natCast_def (n : ℕ) : (n : R[M]) = single (1 : M) (n : R) := rfl +lemma natCast_def (n : ℕ) : (n : R[M]) = single 1 (n : R) := rfl + +@[to_additive (dont_translate := R)] +lemma ofNat_def (n : ℕ) [n.AtLeastTwo] : (ofNat(n) : R[M]) = single 1 ofNat(n) := rfl -@[to_additive (dont_translate := R) mul_single_zero_apply] -lemma mul_single_one_apply (x : R[M]) (r : R) (m : M) : (x * single 1 r : R[M]) m = x m * r := - x.mul_single_apply_aux (by simp) +@[to_additive (dont_translate := R) (attr := simp)] +lemma coeff_natCast (n : ℕ) : (n : R[M]).coeff = .single 1 (n : R) := rfl + +@[to_additive (dont_translate := R) (attr := simp)] +lemma coeff_ofNat (n : ℕ) [n.AtLeastTwo] : (ofNat(n) : R[M]).coeff = .single 1 ofNat(n) := rfl + +@[to_additive (dont_translate := R) coeff_mul_single_zero] +lemma coeff_mul_single_one (x : R[M]) (r : R) (m : M) : + (x * single 1 r).coeff m = x.coeff m * r := + coeff_mul_single_eq_coeff_mul _ (by simp) -@[to_additive (dont_translate := R) single_zero_mul_apply] -lemma single_one_mul_apply (x : R[M]) (r : R) (m : M) : (single 1 r * x : R[M]) m = r * x m := - x.single_mul_apply_aux (by simp) +@[deprecated (since := "2026-06-18")] alias mul_single_one_apply := coeff_mul_single_one + +@[to_additive (dont_translate := R) coeff_single_zero_mul] +lemma coeff_single_one_mul (x : R[M]) (r : R) (m : M) : + (single 1 r * x).coeff m = r * x.coeff m := + x.coeff_single_mul_eq_mul_coeff _ (by simp) + +@[deprecated (since := "2026-06-18")] alias single_one_mul_apply := coeff_single_one_mul variable (R M : Type*) [Semiring R] [MulOneClass M] in /-- The embedding of a unital magma into its magma algebra. -/ -@[simps] +@[simps! apply] def of : M →* R[M] where __ := ofMagma R M - toFun m := single m 1 map_one' := rfl lemma of_injective [Nontrivial R] : Function.Injective (of R M) := fun a b h ↦ by - simpa using (single_eq_single_iff _ _ _ _).mp h + simpa [← coeff_inj, Finsupp.single_eq_single_iff] using h lemma of_commute (h : ∀ m', Commute m m') (f : R[M]) : Commute (of R M m) f := single_commute h .one_left f @@ -590,7 +689,7 @@ then they are equal. -/] lemma ringHom_ext [Semiring S] {f g : R[M] →+* S} (h₁ : ∀ r, f (single 1 r) = g (single 1 r)) (h_of : ∀ m, f (single m 1) = g (single m 1)) : f = g := - RingHom.coe_addMonoidHom_injective <| addHom_ext fun m r ↦ by + RingHom.coe_addMonoidHom_injective <| addMonoidHom_ext fun m r ↦ by simpa [← map_mul] using! congr($(h₁ r) * $(h_of m)) /-- If two ring homomorphisms from `R[M]` are equal on all `single m 1` @@ -620,90 +719,120 @@ lemma single_pow (m : M) (r : R) : ∀ n : ℕ, single m r ^ n = single (m ^ n) lemma induction_on {p : R[M] → Prop} (x : R[M]) (hM : ∀ m, p (of R M m)) (hadd : ∀ x y : R[M], p x → p y → p (x + y)) (hsmul : ∀ (r : R) (x), p x → p (r • x)) : p x := - Finsupp.induction_linear x (by simpa using hsmul 0 (of R M 1) (hM 1)) - (fun x y hf hg => hadd x y hf hg) fun m r ↦ by simpa using hsmul r (of R M m) (hM m) + Finsupp.induction_linear (motive := fun x ↦ p <| ofCoeff x) x.coeff + (by simpa using hsmul 0 (of R M 1) (hM 1)) + (fun x y hf hg ↦ hadd (ofCoeff x) (ofCoeff y) hf hg) + fun m r ↦ by simpa using hsmul r (of R M m) (hM m) @[to_additive (dont_translate := R)] instance isLocalHom_singleOneRingHom : IsLocalHom (singleOneRingHom (R := R) (M := M)) where map_nonunit := by simp_rw [isUnit_iff_exists] rintro a ⟨x, hax, hxa⟩ - refine ⟨x 1, ?_, ?_⟩ - · simpa [single_one_mul_apply, one_def] using congr($hax 1) - · simpa [mul_single_one_apply, one_def] using congr($hxa 1) + refine ⟨x.coeff 1, ?_, ?_⟩ + · simpa [coeff_single_one_mul] using congr(($hax).coeff 1) + · simpa [coeff_mul_single_one] using congr(($hxa).coeff 1) -set_option backward.isDefEq.respectTransparency false in variable (M) in /-- The trivial monoid algebra is the base ring. -/ @[to_additive (dont_translate := R) (attr := simps! apply) /-- The trivial additive monoid algebra is the base ring. -/] def uniqueRingEquiv [Subsingleton M] : R[M] ≃+* R where - toAddEquiv := Finsupp.uniqueAddEquiv 1 + toAddEquiv := coeffAddEquiv.trans <| Finsupp.uniqueAddEquiv 1 map_mul' x y := by - let : Unique M := ⟨⟨1⟩, fun _ ↦ Subsingleton.elim _ _⟩ - refine (mul_apply ..).trans ?_ - simp [Finsupp.sum_unique, Unique.eq_default, MonoidAlgebra] + let : Unique M := ⟨⟨1⟩, fun _ ↦ Subsingleton.elim ..⟩ + refine (coeff_mul ..).trans ?_ + simp [Finsupp.sum_unique, Unique.eq_default] variable (M) in @[to_additive (dont_translate := R) (attr := simp)] lemma uniqueRingEquiv_symm_apply [Subsingleton M] (r : R) : - (uniqueRingEquiv M).symm r = single 1 r := rfl + (uniqueRingEquiv M).symm r = single 1 r := by classical ext; simp [uniqueRingEquiv] -- We want this lemma to fire before `uniqueRingEquiv_symm_apply`. @[to_additive (dont_translate := R) (attr := simp↓ high)] -lemma uniqueRingEquiv_symm_apply_apply [Subsingleton M] (r : R) (m : M) : - (uniqueRingEquiv M).symm r m = r := by simp [Subsingleton.elim m 1] +lemma coeff_uniqueRingEquiv_symm [Subsingleton M] (r : R) (m : M) : + ((uniqueRingEquiv M).symm r).coeff m = r := by simp [Subsingleton.elim m 1] + +@[deprecated (since := "2026-06-18")] +alias uniqueRingEquiv_symm_apply_apply := coeff_uniqueRingEquiv_symm + +/-- A product monoid algebra is a nested monoid algebra. -/ +@[to_additive (dont_translate := R) +/-- An additive product monoid algebra is a nested additive monoid algebra. -/] +def curryAddEquiv : R[M × N] ≃+ R[N][M] := + coeffAddEquiv.trans <| .trans Finsupp.curryAddEquiv <| .trans + (Finsupp.mapRange.addEquiv coeffAddEquiv.symm) coeffAddEquiv.symm + +@[to_additive (attr := simp)] +lemma curryAddEquiv_single (m : M) (n : N) (r : R) : + curryAddEquiv (single (m, n) r) = single m (single n r) := by simp [curryAddEquiv] + +@[to_additive (attr := simp)] +lemma curryAddEquiv_symm_single (m : M) (n : N) (r : R) : + curryAddEquiv.symm (single m <| single n r) = (single (m, n) r) := by simp [curryAddEquiv] /-- A product monoid algebra is a nested monoid algebra. -/ @[to_additive (dont_translate := R) /-- An additive product monoid algebra is a nested additive monoid algebra. -/] def curryRingEquiv : R[M × N] ≃+* R[N][M] where toAddEquiv := curryAddEquiv - map_mul' := by - let f : R[M × N] →+ R[N][M] := curryAddEquiv.toAddMonoidHom - have {mn r} : f (single mn r) = single mn.1 (single mn.2 r) := Finsupp.curry_single _ _ - refine f.map_mul_iff.2 ?_ - ext ⟨m₁, n₁⟩ r₁ ⟨m₂, n₂⟩ r₂ - simp [this] + map_mul' := curryAddEquiv (M := M) (N := N).toAddMonoidHom.map_mul_iff.2 <| by + ext ⟨m₁, n₁⟩ r₁ ⟨m₂, n₂⟩ r₂; simp -@[to_additive (attr := simp)] +@[to_additive (dont_translate := R) (attr := simp)] lemma curryRingEquiv_single (m : M) (n : N) (r : R) : - curryRingEquiv (single (m, n) r) = single m (single n r) := by - classical exact Finsupp.curry_single .. + curryRingEquiv (single (m, n) r) = single m (single n r) := by simp [curryRingEquiv] @[to_additive (attr := simp)] lemma curryRingEquiv_symm_single (m : M) (n : N) (r : R) : curryRingEquiv.symm (single m <| single n r) = (single (m, n) r) := by - classical exact Finsupp.uncurry_single .. + simp [curryRingEquiv] + +variable [IsCancelMul M] + +@[to_additive (dont_translate := R) (attr := simp) coeff_mul_single_add] +lemma coeff_mul_single_mul (x : R[M]) (r : R) (m m' : M) : + (x * single m r).coeff (m' * m) = x.coeff m' * r := + coeff_mul_single_eq_coeff_mul _ (by simp) + +@[to_additive (dont_translate := R) (attr := simp) coeff_single_mul_add] +lemma coeff_single_mul_mul (x : R[M]) (r : R) (m m' : M) : + (single m r * x).coeff (m * m') = r * x.coeff m' := + x.coeff_single_mul_eq_mul_coeff _ (by simp) end Monoid section Group variable [Group G] -@[to_additive (attr := simp) (dont_translate := R) mul_single_apply] -lemma mul_single_apply (x : R[G]) (r : R) (g h : G) : (x * single g r) h = x (h * g⁻¹) * r := - mul_single_apply_aux <| by simp [eq_mul_inv_iff_mul_eq] +@[to_additive (attr := simp) (dont_translate := R) coeff_mul_single_apply] +lemma coeff_mul_single_apply (x : R[G]) (r : R) (g h : G) : + (x * single g r).coeff h = x.coeff (h * g⁻¹) * r := + coeff_mul_single_eq_coeff_mul _ <| by simp [eq_mul_inv_iff_mul_eq] -@[to_additive (attr := simp) (dont_translate := R) single_mul_apply] -lemma single_mul_apply (x : R[G]) (r : R) (g h : G) : (single g r * x) h = r * x (g⁻¹ * h) := - single_mul_apply_aux <| by simp [eq_inv_mul_iff_mul_eq] +@[deprecated (since := "2026-06-18")] alias mul_single_apply := coeff_mul_single_apply -@[to_additive (dont_translate := R) mul_apply_left] -lemma mul_apply_left (x y : R[G]) (g : G) : (x * y) g = x.sum fun h r ↦ r * y (h⁻¹ * g) := by - classical - rw [mul_apply] - dsimp [Finsupp.sum] - congr! 1 - simp +contextual [← eq_inv_mul_iff_mul_eq] +@[to_additive (attr := simp) (dont_translate := R) coeff_single_mul_apply] +lemma coeff_single_mul_apply (x : R[G]) (r : R) (g h : G) : + (single g r * x).coeff h = r * x.coeff (g⁻¹ * h) := + coeff_single_mul_eq_mul_coeff _ <| by simp [eq_inv_mul_iff_mul_eq] -@[to_additive (dont_translate := R) mul_apply_right] -lemma mul_apply_right (x y : R[G]) (g : G) : (x * y) g = y.sum fun h r ↦ x (g * h⁻¹) * r := by - classical - rw [mul_apply, Finsupp.sum_comm] - dsimp [Finsupp.sum] - congr! 1 - simp +contextual [← eq_mul_inv_iff_mul_eq] +@[deprecated (since := "2026-06-18")] alias single_mul_apply := coeff_single_mul_apply + +@[to_additive (dont_translate := R) coeff_mul_apply_left] +lemma coeff_mul_apply_left (x y : R[G]) (g : G) : + (x * y).coeff g = x.coeff.sum fun h r ↦ r * y.coeff (h⁻¹ * g) := by + classical rw [coeff_mul]; gcongr; simp +contextual [← eq_inv_mul_iff_mul_eq] + +@[deprecated (since := "2026-06-18")] alias mul_apply_left := coeff_mul_apply_left + +@[to_additive (dont_translate := R) coeff_mul_apply_right] +lemma coeff_mul_apply_right (x y : R[G]) (g : G) : + (x * y).coeff g = y.coeff.sum fun h r ↦ x.coeff (g * h⁻¹) * r := by + classical rw [coeff_mul, Finsupp.sum_comm]; gcongr; simp +contextual [← eq_mul_inv_iff_mul_eq] + +@[deprecated (since := "2026-06-18")] alias mul_apply_right := coeff_mul_apply_right end Group end Semiring @@ -713,7 +842,7 @@ variable [CommSemiring R] @[to_additive (dont_translate := R)] instance nonUnitalCommSemiring [CommSemigroup M] : NonUnitalCommSemiring R[M] where - mul_comm f g := by simp [mul_def, Finsupp.sum, mul_comm, f.support.sum_comm] + mul_comm f g := by simp [mul_def, Finsupp.sum, mul_comm, f.coeff.support.sum_comm] @[to_additive (dont_translate := R)] lemma single_one_comm [MulOneClass M] (r : R) (f : R[M]) : @@ -727,21 +856,25 @@ variable [CommMonoid M] instance commSemiring : CommSemiring R[M] where open Finset in -@[to_additive (dont_translate := R) prod_single] +@[to_additive (dont_translate := R) (attr := simp) prod_single] lemma prod_single (s : Finset ι) (m : ι → M) (r : ι → R) : ∏ i ∈ s, single (m i) (r i) = single (∏ i ∈ s, m i) (∏ i ∈ s, r i) := Finset.cons_induction_on s rfl fun i s hi ih ↦ by rw [prod_cons, ih, single_mul_single, prod_cons, prod_cons] +open Finset in +@[to_additive (dont_translate := R) (attr := simp) finsuppProd_single] +lemma finsuppProd_single [AddCommMonoid N] (f : ι →₀ N) (m : ι → N → M) (r : ι → N → R) : + f.prod (fun i n ↦ single (m i n) (r i n)) = single (f.prod m) (f.prod r) := prod_single .. + end CommMonoid end CommSemiring section Ring variable [Ring R] -@[to_additive (dont_translate := R)] -instance addCommGroup : AddCommGroup R[M] := - inferInstanceAs <| AddCommGroup <| M →₀ R +@[to_additive (dont_translate := R) addCommGroup] +instance addCommGroup : AddCommGroup R[M] := fast_instance% coeffEquiv.addCommGroup @[to_additive (attr := simp)] lemma coeff_neg (x : R[M]) : coeff (-x) = -coeff x := rfl @@ -756,10 +889,10 @@ lemma coeff_sub (x y : R[M]) : coeff (x - y) = coeff x - coeff y := rfl lemma ofCoeff_sub (x y : M →₀ R) : ofCoeff (x - y) = ofCoeff x - ofCoeff y := rfl @[to_additive (attr := simp) (dont_translate := R)] -lemma neg_apply (m : M) (x : R[M]) : (-x) m = -x m := rfl +lemma single_neg (m : M) (r : R) : single m (-r) = -single m r := by ext; simp -@[to_additive (dont_translate := R)] -lemma single_neg (m : M) (r : R) : single m (-r) = -single m r := Finsupp.single_neg m r +@[to_additive (attr := simp) (dont_translate := R)] +lemma single_sub (m : M) (r s : R) : single m (r - s) = single m r - single m s := by ext; simp @[to_additive (dont_translate := R)] instance nonUnitalNonAssocRing [Mul M] : NonUnitalNonAssocRing R[M] where @@ -767,7 +900,6 @@ instance nonUnitalNonAssocRing [Mul M] : NonUnitalNonAssocRing R[M] where @[to_additive (dont_translate := R)] instance nonUnitalRing [Semigroup M] : NonUnitalRing R[M] where -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance nonAssocRing [MulOneClass M] : NonAssocRing R[M] where intCast z := single 1 z @@ -780,6 +912,9 @@ lemma intCast_def [MulOneClass M] (z : ℤ) : (z : R[M]) = single 1 (z : R) := r @[to_additive (dont_translate := R)] instance ring [Monoid M] : Ring R[M] where +@[deprecated coeff_neg (since := "2026-06-18")] +lemma neg_apply (m : M) (x : R[M]) : (-x).coeff m = -x.coeff m := rfl + end Ring section CommRing @@ -807,7 +942,7 @@ variable (R M : Type*) [Semiring R] @[simps] def ofMagma [Add M] : Multiplicative M →ₙ* R[M] where toFun a := single a.toAdd 1 - map_mul' := by simp + map_mul' := by simp [mul_def] /-- Embedding of a magma with zero into its magma algebra. -/ def of [AddZeroClass M] : Multiplicative M →* R[M] where @@ -829,8 +964,8 @@ theorem of'_apply (a : M) : of' R M a = single a 1 := theorem of'_eq_of [AddZeroClass M] (a : M) : of' R M a = of R M (.ofAdd a) := rfl -theorem of_injective [Nontrivial R] [AddZeroClass M] : Function.Injective (of R M) := - MonoidAlgebra.of_injective +theorem of_injective [Nontrivial R] [AddZeroClass M] : Function.Injective (of R M) := fun a b h ↦ by + simpa [← coeff_inj, Finsupp.single_eq_single_iff] using h lemma of'_commute [AddZeroClass M] {a : M} (h : ∀ a', AddCommute a a') (f : AddMonoidAlgebra R M) : Commute (of' R M a) f := @@ -850,8 +985,10 @@ def singleHom [AddZeroClass M] : R × Multiplicative M →* R[M] where theorem induction_on [AddMonoid M] {p : R[M] → Prop} (x : R[M]) (hM : ∀ m, p (of R M <| .ofAdd m)) (hadd : ∀ x y : R[M], p x → p y → p (x + y)) (hsmul : ∀ (r : R) (x), p x → p (r • x)) : p x := - Finsupp.induction_linear x (by simpa using! hsmul 0 (of R M 1) (hM 0)) - (fun x y hf hg ↦ hadd x y hf hg) fun m r ↦ by simpa using! hsmul r (of R M m) (hM m) + Finsupp.induction_linear (motive := fun x ↦ p (ofCoeff x)) x.coeff + (by simpa using hsmul 0 (of R M 1) (hM 0)) + (fun x y hf hg ↦ hadd (ofCoeff x) (ofCoeff y) hf hg) + fun m r ↦ by simpa using! hsmul r (of R M m) (hM m) /-- If two ring homomorphisms from `R[M]` are equal on all `single m 1` and `single 0 r`, then they are equal. diff --git a/Mathlib/Algebra/MonoidAlgebra/Degree.lean b/Mathlib/Algebra/MonoidAlgebra/Degree.lean index 40d0c19acdf791..e8aab8b059d9e5 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Degree.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Degree.lean @@ -86,13 +86,18 @@ a type with *b*ot or *t*op respectively. variable (degb : A → B) (degt : A → T) (f g : R[A]) -theorem sup_support_add_le : - (f + g).support.sup degb ≤ f.support.sup degb ⊔ g.support.sup degb := by +theorem sup_support_coeff_add_le : + (f + g).coeff.support.sup degb ≤ f.coeff.support.sup degb ⊔ g.coeff.support.sup degb := by classical exact (Finset.sup_mono Finsupp.support_add).trans_eq Finset.sup_union -theorem le_inf_support_add : f.support.inf degt ⊓ g.support.inf degt ≤ (f + g).support.inf degt := - sup_support_add_le (fun a : A => OrderDual.toDual (degt a)) f g +@[deprecated (since := "2026-06-18")] alias sup_support_add_le := sup_support_coeff_add_le + +theorem le_inf_support_coeff_add : + f.coeff.support.inf degt ⊓ g.coeff.support.inf degt ≤ (f + g).coeff.support.inf degt := + sup_support_coeff_add_le (fun a : A => OrderDual.toDual (degt a)) f g + +@[deprecated (since := "2026-06-18")] alias le_inf_support_add := le_inf_support_coeff_add end ExplicitDegrees @@ -101,18 +106,22 @@ section AddOnly variable [Add A] [Add B] [Add T] [AddLeftMono B] [AddRightMono B] [AddLeftMono T] [AddRightMono T] -theorem sup_support_mul_le {degb : A → B} (degbm : ∀ a b, degb (a + b) ≤ degb a + degb b) +theorem sup_support_coeff_mul_le {degb : A → B} (degbm : ∀ a b, degb (a + b) ≤ degb a + degb b) (f g : R[A]) : - (f * g).support.sup degb ≤ f.support.sup degb + g.support.sup degb := by + (f * g).coeff.support.sup degb ≤ f.coeff.support.sup degb + g.coeff.support.sup degb := by classical - grw [support_mul, Finset.sup_add_le] + grw [support_coeff_mul_subset, Finset.sup_add_le] rintro _fd fds _gd gds grw [degbm, ← Finset.le_sup fds, ← Finset.le_sup gds] -theorem le_inf_support_mul {degt : A → T} (degtm : ∀ a b, degt a + degt b ≤ degt (a + b)) +@[deprecated (since := "2026-06-18")] alias sup_support_mul_le := sup_support_coeff_mul_le + +theorem le_inf_support_coeff_mul {degt : A → T} (degtm : ∀ a b, degt a + degt b ≤ degt (a + b)) (f g : R[A]) : - f.support.inf degt + g.support.inf degt ≤ (f * g).support.inf degt := - sup_support_mul_le (B := Tᵒᵈ) degtm f g + f.coeff.support.inf degt + g.coeff.support.inf degt ≤ (f * g).coeff.support.inf degt := + sup_support_coeff_mul_le (B := Tᵒᵈ) degtm f g + +@[deprecated (since := "2026-06-18")] alias le_inf_support_mul := le_inf_support_coeff_mul end AddOnly @@ -125,17 +134,17 @@ variable [AddMonoid A] [AddMonoid B] [AddLeftMono B] [AddRightMono B] theorem sup_support_list_prod_le (degb0 : degb 0 ≤ 0) (degbm : ∀ a b, degb (a + b) ≤ degb a + degb b) : ∀ l : List R[A], - l.prod.support.sup degb ≤ (l.map fun f : R[A] => f.support.sup degb).sum + l.prod.coeff.support.sup degb ≤ (l.map fun f : R[A] => f.coeff.support.sup degb).sum | [] => by rw [List.map_nil, Finset.sup_le_iff, List.prod_nil, List.sum_nil] exact fun a ha => by rwa [Finset.mem_singleton.mp (Finsupp.support_single_subset ha)] | f::fs => by rw [List.prod_cons, List.map_cons, List.sum_cons] - grw [sup_support_mul_le degbm, sup_support_list_prod_le degb0 degbm] + grw [sup_support_coeff_mul_le degbm, sup_support_list_prod_le degb0 degbm] theorem le_inf_support_list_prod (degt0 : 0 ≤ degt 0) (degtm : ∀ a b, degt a + degt b ≤ degt (a + b)) (l : List R[A]) : - (l.map fun f : R[A] => f.support.inf degt).sum ≤ l.prod.support.inf degt := by + (l.map fun f : R[A] => f.coeff.support.inf degt).sum ≤ l.prod.coeff.support.inf degt := by refine OrderDual.ofDual_le_ofDual.mpr ?_ refine sup_support_list_prod_le ?_ ?_ l · refine (OrderDual.ofDual_le_ofDual.mp ?_) @@ -144,13 +153,13 @@ theorem le_inf_support_list_prod (degt0 : 0 ≤ degt 0) exact degtm a b theorem sup_support_pow_le (degb0 : degb 0 ≤ 0) (degbm : ∀ a b, degb (a + b) ≤ degb a + degb b) - (n : ℕ) (f : R[A]) : (f ^ n).support.sup degb ≤ n • f.support.sup degb := by + (n : ℕ) (f : R[A]) : (f ^ n).coeff.support.sup degb ≤ n • f.coeff.support.sup degb := by rw [← List.prod_replicate, ← List.sum_replicate] refine (sup_support_list_prod_le degb0 degbm _).trans_eq ?_ rw [List.map_replicate] theorem le_inf_support_pow (degt0 : 0 ≤ degt 0) (degtm : ∀ a b, degt a + degt b ≤ degt (a + b)) - (n : ℕ) (f : R[A]) : n • f.support.inf degt ≤ (f ^ n).support.inf degt := by + (n : ℕ) (f : R[A]) : n • f.coeff.support.inf degt ≤ (f ^ n).coeff.support.inf degt := by refine OrderDual.ofDual_le_ofDual.mpr <| sup_support_pow_le (OrderDual.ofDual_le_ofDual.mp ?_) (fun a b => OrderDual.ofDual_le_ofDual.mp ?_) n f · exact degt0 @@ -166,35 +175,49 @@ variable [CommSemiring R] [AddCommMonoid A] [AddCommMonoid B] [AddLeftMono B] [A [AddCommMonoid T] [AddLeftMono T] [AddRightMono T] {degb : A → B} {degt : A → T} -theorem sup_support_multiset_prod_le (degb0 : degb 0 ≤ 0) +theorem sup_support_coeff_multisetProd_le (degb0 : degb 0 ≤ 0) (degbm : ∀ a b, degb (a + b) ≤ degb a + degb b) (m : Multiset R[A]) : - m.prod.support.sup degb ≤ (m.map fun f : R[A] => f.support.sup degb).sum := by + m.prod.coeff.support.sup degb ≤ (m.map fun f : R[A] => f.coeff.support.sup degb).sum := by induction m using Quot.inductionOn rw [Multiset.quot_mk_to_coe'', Multiset.map_coe, Multiset.sum_coe, Multiset.prod_coe] exact sup_support_list_prod_le degb0 degbm _ -theorem le_inf_support_multiset_prod (degt0 : 0 ≤ degt 0) +@[deprecated (since := "2026-06-18")] +alias sup_support_multiset_prod_le := sup_support_coeff_multisetProd_le + +theorem le_inf_support_coeff_multisetProd (degt0 : 0 ≤ degt 0) (degtm : ∀ a b, degt a + degt b ≤ degt (a + b)) (m : Multiset R[A]) : - (m.map fun f : R[A] => f.support.inf degt).sum ≤ m.prod.support.inf degt := by + (m.map fun f : R[A] => f.coeff.support.inf degt).sum ≤ m.prod.coeff.support.inf degt := by refine OrderDual.ofDual_le_ofDual.mpr <| - sup_support_multiset_prod_le (OrderDual.ofDual_le_ofDual.mp ?_) + sup_support_coeff_multisetProd_le (OrderDual.ofDual_le_ofDual.mp ?_) (fun a b => OrderDual.ofDual_le_ofDual.mp ?_) m · exact degt0 · exact degtm _ _ -theorem sup_support_finsetProd_le (degb0 : degb 0 ≤ 0) +@[deprecated (since := "2026-06-18")] +alias le_inf_support_multiset_prod := le_inf_support_coeff_multisetProd + +theorem sup_support_coeff_finsetProd_le (degb0 : degb 0 ≤ 0) (degbm : ∀ a b, degb (a + b) ≤ degb a + degb b) (s : Finset ι) (f : ι → R[A]) : - (∏ i ∈ s, f i).support.sup degb ≤ ∑ i ∈ s, (f i).support.sup degb := - (sup_support_multiset_prod_le degb0 degbm _).trans_eq <| congr_arg _ <| Multiset.map_map _ _ _ + (∏ i ∈ s, f i).coeff.support.sup degb ≤ ∑ i ∈ s, (f i).coeff.support.sup degb := + (sup_support_coeff_multisetProd_le degb0 degbm _).trans_eq <| congr_arg _ <| Multiset.map_map .. -@[deprecated (since := "2026-04-08")] alias sup_support_finset_prod_le := sup_support_finsetProd_le +@[deprecated (since := "2026-06-18")] +alias sup_support_finsetProd_le := sup_support_coeff_finsetProd_le -theorem le_inf_support_finsetProd (degt0 : 0 ≤ degt 0) +@[deprecated (since := "2026-04-08")] +alias sup_support_finset_prod_le := sup_support_coeff_finsetProd_le + +theorem le_inf_support_coeff_finsetProd (degt0 : 0 ≤ degt 0) (degtm : ∀ a b, degt a + degt b ≤ degt (a + b)) (s : Finset ι) (f : ι → R[A]) : - (∑ i ∈ s, (f i).support.inf degt) ≤ (∏ i ∈ s, f i).support.inf degt := - le_of_eq_of_le (by rw [Multiset.map_map]; rfl) (le_inf_support_multiset_prod degt0 degtm _) + (∑ i ∈ s, (f i).coeff.support.inf degt) ≤ (∏ i ∈ s, f i).coeff.support.inf degt := + le_of_eq_of_le (by rw [Multiset.map_map]; rfl) (le_inf_support_coeff_multisetProd degt0 degtm _) + +@[deprecated (since := "2026-06-18")] +alias le_inf_support_finsetProd := le_inf_support_coeff_finsetProd -@[deprecated (since := "2026-04-08")] alias le_inf_support_finset_prod := le_inf_support_finsetProd +@[deprecated (since := "2026-04-08")] +alias le_inf_support_finset_prod := le_inf_support_coeff_finsetProd end CommutativeLemmas @@ -229,19 +252,16 @@ type of (monic) monomials in `R[A]`, that respects addition). We make use of thi by taking `D := toLex`, and different monomial orders could be accessed via different type synonyms once they are added. -/ abbrev supDegree (f : R[A]) : B := - f.support.sup D + f.coeff.support.sup D variable {D} theorem supDegree_add_le {f g : R[A]} : (f + g).supDegree D ≤ (f.supDegree D) ⊔ (g.supDegree D) := - sup_support_add_le D f g + sup_support_coeff_add_le D f g -set_option backward.isDefEq.respectTransparency false in @[simp] -theorem supDegree_neg {f : R'[A]} : - (-f).supDegree D = f.supDegree D := by - rw [supDegree, supDegree, Finsupp.support_neg] +theorem supDegree_neg {f : R'[A]} : (-f).supDegree D = f.supDegree D := by simp [supDegree] theorem supDegree_sub_le {f g : R'[A]} : (f - g).supDegree D ≤ f.supDegree D ⊔ g.supDegree D := by @@ -250,34 +270,37 @@ theorem supDegree_sub_le {f g : R'[A]} : theorem supDegree_sum_le {ι} {s : Finset ι} {f : ι → R[A]} : (∑ i ∈ s, f i).supDegree D ≤ s.sup (fun i => (f i).supDegree D) := by classical - exact (Finset.sup_mono Finsupp.support_finsetSum).trans_eq (Finset.sup_biUnion _ _) + simp only [supDegree, coeff_sum] + grw [Finsupp.support_finsetSum, Finset.sup_biUnion] theorem supDegree_single_ne_zero (a : A) {r : R} (hr : r ≠ 0) : (single a r).supDegree D = D a := by - rw [supDegree, Finsupp.support_single a hr, Finset.sup_singleton] + simp [supDegree, hr] open Classical in theorem supDegree_single (a : A) (r : R) : (single a r).supDegree D = if r = 0 then ⊥ else D a := by split_ifs with hr <;> simp [supDegree_single_ne_zero, hr] -theorem apply_eq_zero_of_not_le_supDegree {p : R[A]} {a : A} (hlt : ¬ D a ≤ p.supDegree D) : - p a = 0 := by +theorem coeff_eq_zero_of_not_le_supDegree {p : R[A]} {a : A} (hlt : ¬ D a ≤ p.supDegree D) : + p.coeff a = 0 := by contrapose! hlt exact Finset.le_sup (Finsupp.mem_support_iff.2 hlt) -theorem supDegree_withBot_some_comp {s : AddMonoidAlgebra R A} (hs : s.support.Nonempty) : +@[deprecated (since := "2026-06-18")] +alias apply_eq_zero_of_not_le_supDegree := coeff_eq_zero_of_not_le_supDegree + +theorem supDegree_withBot_some_comp {s : AddMonoidAlgebra R A} (hs : s.coeff.support.Nonempty) : supDegree (WithBot.some ∘ D) s = supDegree D s := by unfold AddMonoidAlgebra.supDegree rw [← Finset.coe_sup' hs, Finset.sup'_eq_sup] -theorem supDegree_eq_of_isMaxOn {p : R[A]} {a : A} (hmem : a ∈ p.support) - (hmax : IsMaxOn D p.support a) : p.supDegree D = D a := +theorem supDegree_eq_of_isMaxOn {p : R[A]} {a : A} (hmem : a ∈ p.coeff.support) + (hmax : IsMaxOn D p.coeff.support a) : p.supDegree D = D a := sup_eq_of_isMaxOn hmem hmax variable {p q : R[A]} -set_option backward.isDefEq.respectTransparency false in @[simp] theorem supDegree_zero : (0 : R[A]).supDegree D = ⊥ := by simp [supDegree] @@ -288,8 +311,8 @@ theorem ne_zero_of_not_supDegree_le {b : B} (h : ¬ p.supDegree D ≤ b) : p ≠ variable [AddZeroClass A] -theorem supDegree_eq_of_max {b : B} (hb : b ∈ Set.range D) (hmem : D.invFun b ∈ p.support) - (hmax : ∀ a ∈ p.support, D a ≤ b) : p.supDegree D = b := +theorem supDegree_eq_of_max {b : B} (hb : b ∈ Set.range D) (hmem : D.invFun b ∈ p.coeff.support) + (hmax : ∀ a ∈ p.coeff.support, D a ≤ b) : p.supDegree D = b := sup_eq_of_max hb hmem hmax variable [Add B] @@ -297,7 +320,7 @@ variable [Add B] theorem supDegree_mul_le (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) [AddLeftMono B] [AddRightMono B] : (p * q).supDegree D ≤ p.supDegree D + q.supDegree D := - sup_support_mul_le (fun {_ _} => (hadd _ _).le) p q + sup_support_coeff_mul_le (fun {_ _} => (hadd _ _).le) p q theorem supDegree_prod_le {R A B : Type*} [CommSemiring R] [AddCommMonoid A] [AddCommMonoid B] [SemilatticeSup B] [OrderBot B] @@ -313,12 +336,12 @@ theorem supDegree_prod_le {R A B : Type*} [CommSemiring R] [AddCommMonoid A] [Ad rw [Finset.prod_insert his, Finset.sum_insert his] exact (supDegree_mul_le hadd).trans (by gcongr) -theorem apply_add_of_supDegree_le (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) +theorem coeff_add_of_supDegree_le (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) [AddLeftStrictMono B] [AddRightStrictMono B] (hD : D.Injective) {ap aq : A} (hp : p.supDegree D ≤ D ap) (hq : q.supDegree D ≤ D aq) : - (p * q) (ap + aq) = p ap * q aq := by + (p * q).coeff (ap + aq) = p.coeff ap * q.coeff aq := by classical - simp_rw [mul_apply, Finsupp.sum] + simp_rw [coeff_mul, Finsupp.sum] rw [Finset.sum_eq_single ap, Finset.sum_eq_single aq, if_pos rfl] · refine fun a ha hne => if_neg (fun he => ?_) apply_fun D at he; simp_rw [hadd] at he @@ -333,6 +356,8 @@ theorem apply_add_of_supDegree_le (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) · refine fun h => Finset.sum_eq_zero (fun a _ => ite_eq_right_iff.mpr <| fun _ => ?_) rw [Finsupp.notMem_support_iff.mp h, zero_mul] +@[deprecated (since := "2026-06-18")] alias apply_add_of_supDegree_le := coeff_add_of_supDegree_le + end SupDegree section LinearOrder @@ -342,8 +367,7 @@ variable [LinearOrder B] [OrderBot B] {p q : R[A]} (D : A → B) /-- If `D` is an injection into a linear order `B`, the leading coefficient of `f : R[A]` is the nonzero coefficient of highest degree according to `D`, or 0 if `f = 0`. In general, it is defined to be the coefficient at an inverse image of `supDegree f` (if such exists). -/ -noncomputable def leadingCoeff [Nonempty A] (f : R[A]) : R := - f (D.invFun <| f.supDegree D) +noncomputable def leadingCoeff [Nonempty A] (f : R[A]) : R := f.coeff <| D.invFun <| f.supDegree D /-- An element `f : R[A]` is monic if its leading coefficient is one. -/ @[reducible] def Monic [Nonempty A] (f : R[A]) : Prop := @@ -358,7 +382,8 @@ theorem leadingCoeff_single [Nonempty A] (hD : D.Injective) (a : A) (r : R) : rw [leadingCoeff, supDegree_single] split_ifs with hr · simp [hr] - · rw [Function.leftInverse_invFun hD, single_apply, if_pos rfl] + · rw [Function.leftInverse_invFun hD] + simp @[simp] theorem leadingCoeff_zero [Nonempty A] : (0 : R[A]).leadingCoeff D = 0 := rfl @@ -371,8 +396,8 @@ theorem monic_one [AddZeroClass A] (hD : D.Injective) : (1 : R[A]).Monic D := by rw [Monic, one_def, leadingCoeff_single hD] variable (D) in -lemma exists_supDegree_mem_support (hp : p ≠ 0) : ∃ a ∈ p.support, p.supDegree D = D a := - Finset.exists_mem_eq_sup _ (Finsupp.support_nonempty_iff.mpr hp) D +lemma exists_supDegree_mem_support (hp : p ≠ 0) : ∃ a ∈ p.coeff.support, p.supDegree D = D a := + Finset.exists_mem_eq_sup _ (by simpa [Finsupp.support_nonempty_iff]) D variable (D) in lemma supDegree_mem_range (hp : p ≠ 0) : p.supDegree D ∈ Set.range D := by @@ -387,7 +412,6 @@ lemma supDegree_sum_lt (hs : s.Nonempty) {b : B} variable [AddZeroClass A] -set_option backward.isDefEq.respectTransparency false in open Finsupp in lemma supDegree_add_eq_left (h : q.supDegree D < p.supDegree D) : (p + q).supDegree D = p.supDegree D := by @@ -395,19 +419,17 @@ lemma supDegree_add_eq_left (h : q.supDegree D < p.supDegree D) : obtain ⟨a, ha, he⟩ := exists_supDegree_mem_support D (ne_zero_of_not_supDegree_le h.not_ge) rw [he] at h ⊢ apply Finset.le_sup - rw [mem_support_iff, add_apply, apply_eq_zero_of_not_le_supDegree h.not_ge, add_zero] - exact mem_support_iff.mp ha + simpa [coeff_eq_zero_of_not_le_supDegree h.not_ge] using ha lemma supDegree_add_eq_right (h : p.supDegree D < q.supDegree D) : (p + q).supDegree D = q.supDegree D := by rw [add_comm, supDegree_add_eq_left h] -set_option backward.isDefEq.respectTransparency false in lemma leadingCoeff_add_eq_left (h : q.supDegree D < p.supDegree D) : (p + q).leadingCoeff D = p.leadingCoeff D := by obtain ⟨a, he⟩ := supDegree_mem_range D (ne_zero_of_not_supDegree_le h.not_ge) - rw [leadingCoeff, supDegree_add_eq_left h, Finsupp.add_apply, ← leadingCoeff, - apply_eq_zero_of_not_le_supDegree (D := D), add_zero] + rw [leadingCoeff, supDegree_add_eq_left h, coeff_add, Finsupp.add_apply, ← leadingCoeff, + coeff_eq_zero_of_not_le_supDegree (D := D), add_zero] rw [← he, Function.apply_invFun_apply (f := D), he]; exact h.not_ge lemma leadingCoeff_add_eq_right (h : p.supDegree D < q.supDegree D) : @@ -415,7 +437,7 @@ lemma leadingCoeff_add_eq_right (h : p.supDegree D < q.supDegree D) : rw [add_comm, leadingCoeff_add_eq_left h] lemma supDegree_mem_support (hD : D.Injective) (hp : p ≠ 0) : - D.invFun (p.supDegree D) ∈ p.support := by + D.invFun (p.supDegree D) ∈ p.coeff.support := by obtain ⟨a, ha, he⟩ := exists_supDegree_mem_support D hp rwa [he, Function.leftInverse_invFun hD] @@ -428,7 +450,6 @@ lemma leadingCoeff_eq_zero (hD : D.Injective) : p.leadingCoeff D = 0 ↔ p = 0 : lemma leadingCoeff_ne_zero (hD : D.Injective) : p.leadingCoeff D ≠ 0 ↔ p ≠ 0 := (leadingCoeff_eq_zero hD).ne -set_option backward.isDefEq.respectTransparency false in lemma supDegree_sub_lt_of_leadingCoeff_eq (hD : D.Injective) {R} [Ring R] {p q : R[A]} (hd : p.supDegree D = q.supDegree D) (hc : p.leadingCoeff D = q.leadingCoeff D) : (p - q).supDegree D < p.supDegree D ∨ p = q := by @@ -437,7 +458,7 @@ lemma supDegree_sub_lt_of_leadingCoeff_eq (hD : D.Injective) {R} [Ring R] {p q : · rw [hd, sup_idem] · rw [← sub_eq_zero, ← leadingCoeff_eq_zero hD, leadingCoeff] at he refine fun h => he ?_ - rwa [h, Finsupp.sub_apply, ← leadingCoeff, hd, ← leadingCoeff, sub_eq_zero] + rwa [h, coeff_sub, Finsupp.sub_apply, ← leadingCoeff, hd, ← leadingCoeff, sub_eq_zero] lemma supDegree_leadingCoeff_sum_eq (hi : i ∈ s) (hmax : ∀ j ∈ s, j ≠ i → (f j).supDegree D < (f i).supDegree D) : @@ -477,9 +498,9 @@ lemma sum_ne_zero_of_injOn_supDegree (hs : s.Nonempty) variable [Add B] variable [AddLeftStrictMono B] [AddRightStrictMono B] -set_option backward.isDefEq.respectTransparency false in -lemma apply_supDegree_add_supDegree (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) : - (p * q) (D.invFun (p.supDegree D + q.supDegree D)) = p.leadingCoeff D * q.leadingCoeff D := by +lemma coeff_supDegree_add_supDegree (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) : + (p * q).coeff (D.invFun (p.supDegree D + q.supDegree D)) = + p.leadingCoeff D * q.leadingCoeff D := by obtain rfl | hp := eq_or_ne p 0 · simp obtain rfl | hq := eq_or_ne q 0 @@ -487,7 +508,10 @@ lemma apply_supDegree_add_supDegree (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 obtain ⟨ap, -, hp⟩ := exists_supDegree_mem_support D hp obtain ⟨aq, -, hq⟩ := exists_supDegree_mem_support D hq simp_rw [leadingCoeff, hp, hq, ← hadd, Function.leftInverse_invFun hD _] - exact apply_add_of_supDegree_le hadd hD hp.le hq.le + exact coeff_add_of_supDegree_le hadd hD hp.le hq.le + +@[deprecated (since := "2026-06-18")] +alias apply_supDegree_add_supDegree := coeff_supDegree_add_supDegree lemma supDegree_mul (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) @@ -498,7 +522,7 @@ lemma supDegree_mul · rw [← AddSubsemigroup.coe_set_mk (Set.range D), ← AddHom.srange_mk _ hadd, SetLike.mem_coe] · exact add_mem (supDegree_mem_range D hp) (supDegree_mem_range D hq) · exact (AddHom.srange ⟨D, hadd⟩).add_mem - · simp_rw [Finsupp.mem_support_iff, apply_supDegree_add_supDegree hD hadd] + · simp_rw [Finsupp.mem_support_iff, coeff_supDegree_add_supDegree hD hadd] exact hpq · have := addLeftMono_of_addLeftStrictMono B have := addRightMono_of_addRightStrictMono B @@ -535,7 +559,7 @@ lemma leadingCoeff_mul [NoZeroDivisors R] · simp_rw [leadingCoeff_zero, zero_mul, leadingCoeff_zero] obtain rfl | hq := eq_or_ne q 0 · simp_rw [leadingCoeff_zero, mul_zero, leadingCoeff_zero] - rw [← apply_supDegree_add_supDegree hD hadd, ← supDegree_mul hD hadd ?_ hp hq, leadingCoeff] + rw [← coeff_supDegree_add_supDegree hD hadd, ← supDegree_mul hD hadd ?_ hp hq, leadingCoeff] apply mul_ne_zero <;> rwa [Ne, leadingCoeff_eq_zero hD] lemma Monic.leadingCoeff_mul_eq_left @@ -544,7 +568,7 @@ lemma Monic.leadingCoeff_mul_eq_left obtain rfl | hp := eq_or_ne p 0 · rw [zero_mul] rw [leadingCoeff, hq.supDegree_mul_of_ne_zero_left hD hadd hp, - apply_supDegree_add_supDegree hD hadd, hq, mul_one] + coeff_supDegree_add_supDegree hD hadd, hq, mul_one] lemma Monic.leadingCoeff_mul_eq_right (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) (hp : p.Monic D) : @@ -552,7 +576,7 @@ lemma Monic.leadingCoeff_mul_eq_right obtain rfl | hq := eq_or_ne q 0 · rw [mul_zero] rw [leadingCoeff, hp.supDegree_mul_of_ne_zero_right hD hadd hq, - apply_supDegree_add_supDegree hD hadd, hp, one_mul] + coeff_supDegree_add_supDegree hD hadd, hp, one_mul] lemma Monic.mul (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) @@ -597,14 +621,14 @@ Often, the Type `T` is `WithTop A`, If, further, `A` has a linear order, then this notion coincides with the usual one, using the minimum of the exponents. -/ abbrev infDegree (f : R[A]) : T := - f.support.inf D + f.coeff.support.inf D theorem le_infDegree_add (f g : R[A]) : (f.infDegree D) ⊓ (g.infDegree D) ≤ (f + g).infDegree D := - le_inf_support_add D f g + le_inf_support_coeff_add D f g variable {D} in -theorem infDegree_withTop_some_comp {s : AddMonoidAlgebra R A} (hs : s.support.Nonempty) : +theorem infDegree_withTop_some_comp {s : AddMonoidAlgebra R A} (hs : s.coeff.support.Nonempty) : infDegree (WithTop.some ∘ D) s = infDegree D s := by unfold AddMonoidAlgebra.infDegree rw [← Finset.coe_inf' hs, Finset.inf'_eq_inf] @@ -612,7 +636,7 @@ theorem infDegree_withTop_some_comp {s : AddMonoidAlgebra R A} (hs : s.support.N theorem le_infDegree_mul [AddZeroClass A] [Add T] [AddLeftMono T] [AddRightMono T] (D : AddHom A T) (f g : R[A]) : f.infDegree D + g.infDegree D ≤ (f * g).infDegree D := - le_inf_support_mul (fun {a b : A} => (map_add D a b).ge) _ _ + le_inf_support_coeff_mul (fun {a b : A} => (map_add D a b).ge) _ _ end InfDegree diff --git a/Mathlib/Algebra/MonoidAlgebra/Division.lean b/Mathlib/Algebra/MonoidAlgebra/Division.lean index 03685b4a954b45..bbab11c9339d0d 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Division.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Division.lean @@ -49,43 +49,38 @@ section variable [AddCommMonoid G] /-- Divide by `of' k G g`, discarding terms not divisible by this. -/ -noncomputable def divOf [IsCancelAdd G] (x : k[G]) (g : G) : k[G] := +noncomputable def divOf [IsCancelAdd G] (x : k[G]) (g : G) : k[G] where -- note: comapping by `+ g` has the effect of subtracting `g` from every element in -- the support, and discarding the elements of the support from which `g` can't be subtracted. -- If `G` is an additive group, such as `ℤ` when used for `LaurentPolynomial`, -- then no discarding occurs. - @Finsupp.comapDomain.addMonoidHom _ _ _ _ (g + ·) (add_right_injective g) x + coeff := x.coeff.comapDomain (g + ·) (add_right_injective g).injOn local infixl:70 " /ᵒᶠ " => divOf section divOf variable [IsCancelAdd G] -@[simp] -theorem divOf_apply (g : G) (x : k[G]) (g' : G) : (x /ᵒᶠ g) g' = x (g + g') := - rfl +@[simp] lemma coeff_divOf (g : G) (x : k[G]) (g' : G) : (x /ᵒᶠ g).coeff g' = x.coeff (g + g') := rfl + +@[deprecated (since := "2026-06-18")] alias divOf_apply := coeff_divOf @[simp] -theorem support_divOf (g : G) (x : k[G]) : - (x /ᵒᶠ g).support = - x.support.preimage (g + ·) (Function.Injective.injOn (add_right_injective g)) := +theorem support_coeff_divOf (g : G) (x : k[G]) : + (x /ᵒᶠ g).coeff.support = x.coeff.support.preimage (g + ·) (add_right_injective g).injOn := rfl +@[deprecated (since := "2026-06-18")] alias support_divOf := support_coeff_divOf + @[simp] -theorem zero_divOf (g : G) : (0 : k[G]) /ᵒᶠ g = 0 := - map_zero (Finsupp.comapDomain.addMonoidHom _) +theorem zero_divOf (g : G) : (0 : k[G]) /ᵒᶠ g = 0 := by ext; simp @[simp] -theorem divOf_zero (x : k[G]) : x /ᵒᶠ 0 = x := by - ext - simp only [AddMonoidAlgebra.divOf_apply, zero_add] +theorem divOf_zero (x : k[G]) : x /ᵒᶠ 0 = x := by ext; simp -theorem add_divOf (x y : k[G]) (g : G) : (x + y) /ᵒᶠ g = x /ᵒᶠ g + y /ᵒᶠ g := - map_add (Finsupp.comapDomain.addMonoidHom _) _ _ +theorem add_divOf (x y : k[G]) (g : G) : (x + y) /ᵒᶠ g = x /ᵒᶠ g + y /ᵒᶠ g := by ext; simp -theorem divOf_add (x : k[G]) (a b : G) : x /ᵒᶠ (a + b) = x /ᵒᶠ a /ᵒᶠ b := by - ext - simp only [AddMonoidAlgebra.divOf_apply, add_assoc] +theorem divOf_add (x : k[G]) (a b : G) : x /ᵒᶠ (a + b) = x /ᵒᶠ a /ᵒᶠ b := by ext; simp [add_assoc] /-- A bundled version of `AddMonoidAlgebra.divOf`. -/ @[simps] @@ -101,17 +96,10 @@ noncomputable def divOfHom : Multiplicative G →* AddMonoid.End k[G] where (divOf_add _ _ _) theorem of'_mul_divOf (a : G) (x : k[G]) : of' k G a * x /ᵒᶠ a = x := by - ext - rw [AddMonoidAlgebra.divOf_apply, of'_apply, single_mul_apply_aux, one_mul] - intro c hc - exact add_right_inj _ + ext; simp only [of'_apply, coeff_divOf, coeff_single_mul_add, one_mul] theorem mul_of'_divOf (x : k[G]) (a : G) : x * of' k G a /ᵒᶠ a = x := by - ext - rw [AddMonoidAlgebra.divOf_apply, of'_apply, mul_single_apply_aux, mul_one] - intro c hc - rw [add_comm] - exact add_right_inj _ + ext; simp only [of'_apply, coeff_divOf, add_comm a, coeff_mul_single_add, mul_one] theorem of'_divOf (a : G) : of' k G a /ᵒᶠ a = 1 := by simpa only [one_mul] using mul_of'_divOf (1 : k[G]) a @@ -121,60 +109,63 @@ end divOf /-- The remainder upon division by `of' k G g`. -/ noncomputable def modOf (x : k[G]) (g : G) : k[G] := letI := Classical.decPred fun g₁ => ∃ g₂, g₁ = g + g₂ - x.filter fun g₁ => ¬∃ g₂, g₁ = g + g₂ + .ofCoeff <| x.coeff.filter fun g₁ => ¬∃ g₂, g₁ = g + g₂ local infixl:70 " %ᵒᶠ " => modOf @[simp] -theorem modOf_apply_of_not_exists_add (x : k[G]) (g : G) (g' : G) - (h : ¬∃ d, g' = g + d) : (x %ᵒᶠ g) g' = x g' := by +theorem coeff_modOf_of_not_exists_add (x : k[G]) (g : G) (g' : G) (h : ¬∃ d, g' = g + d) : + (x %ᵒᶠ g).coeff g' = x.coeff g' := by classical exact Finsupp.filter_apply_pos _ _ h +@[deprecated (since := "2026-06-18")] +alias modOf_apply_of_not_exists_add := coeff_modOf_of_not_exists_add + @[simp] -theorem modOf_apply_of_exists_add (x : k[G]) (g : G) (g' : G) - (h : ∃ d, g' = g + d) : (x %ᵒᶠ g) g' = 0 := by +theorem coeff_modOf_of_exists_add (x : k[G]) (g : G) (g' : G) (h : ∃ d, g' = g + d) : + (x %ᵒᶠ g).coeff g' = 0 := by classical exact Finsupp.filter_apply_neg _ _ <| by rwa [Classical.not_not] +@[deprecated (since := "2026-06-18")] alias modOf_apply_of_exists_add := coeff_modOf_of_exists_add + @[simp] -theorem modOf_apply_add_self (x : k[G]) (g : G) (d : G) : (x %ᵒᶠ g) (d + g) = 0 := - modOf_apply_of_exists_add _ _ _ ⟨_, add_comm _ _⟩ +theorem coeff_modOf_add_self (x : k[G]) (g : G) (d : G) : (x %ᵒᶠ g).coeff (d + g) = 0 := + coeff_modOf_of_exists_add _ _ _ ⟨_, add_comm _ _⟩ + +@[deprecated (since := "2026-06-18")] alias modOf_apply_add_self := coeff_modOf_add_self + +theorem coeff_modOf_self_add (x : k[G]) (g : G) (d : G) : (x %ᵒᶠ g).coeff (g + d) = 0 := + coeff_modOf_of_exists_add _ _ _ ⟨_, rfl⟩ -theorem modOf_apply_self_add (x : k[G]) (g : G) (d : G) : (x %ᵒᶠ g) (g + d) = 0 := - modOf_apply_of_exists_add _ _ _ ⟨_, rfl⟩ +@[deprecated (since := "2026-06-18")] alias modOf_apply_self_add := coeff_modOf_self_add -set_option backward.isDefEq.respectTransparency false in theorem of'_mul_modOf (g : G) (x : k[G]) : of' k G g * x %ᵒᶠ g = 0 := by ext g' - rw [Finsupp.zero_apply] + simp only [of'_apply, coeff_zero, Finsupp.coe_zero, Pi.zero_apply] obtain ⟨d, rfl⟩ | h := em (∃ d, g' = g + d) - · rw [modOf_apply_self_add] - · rw [modOf_apply_of_not_exists_add _ _ _ h, of'_apply, single_mul_apply_of_not_exists_add _ _ h] + · rw [coeff_modOf_self_add] + · rw [coeff_modOf_of_not_exists_add _ _ _ h, coeff_single_mul_of_forall_add_ne] + simpa [eq_comm] using h -set_option backward.isDefEq.respectTransparency false in theorem mul_of'_modOf (x : k[G]) (g : G) : x * of' k G g %ᵒᶠ g = 0 := by ext g' - rw [Finsupp.zero_apply] + simp only [of'_apply, coeff_zero, Finsupp.zero_apply] obtain ⟨d, rfl⟩ | h := em (∃ d, g' = g + d) - · rw [modOf_apply_self_add] - · rw [modOf_apply_of_not_exists_add _ _ _ h, of'_apply, mul_single_apply_of_not_exists_add] - simpa only [add_comm] using h + · rw [coeff_modOf_self_add] + · rw [coeff_modOf_of_not_exists_add _ _ _ h, coeff_mul_single_of_forall_add_ne] + simpa [eq_comm, add_comm] using h theorem of'_modOf (g : G) : of' k G g %ᵒᶠ g = 0 := by simpa only [one_mul] using mul_of'_modOf (1 : k[G]) g -set_option backward.isDefEq.respectTransparency false in theorem divOf_add_modOf [IsCancelAdd G] (x : k[G]) (g : G) : of' k G g * (x /ᵒᶠ g) + x %ᵒᶠ g = x := by ext g' - rw [Finsupp.add_apply] + dsimp only [coeff_add, of'_apply, Finsupp.add_apply] obtain ⟨d, rfl⟩ | h := em (∃ d, g' = g + d) - swap - · rw [modOf_apply_of_not_exists_add x _ _ h, of'_apply, single_mul_apply_of_not_exists_add _ _ h, - zero_add] - · rw [modOf_apply_self_add, add_zero] - rw [of'_apply, single_mul_apply_aux, one_mul, divOf_apply] - intro a ha - exact add_right_inj _ + · rw [coeff_modOf_self_add, add_zero, coeff_single_mul_add, one_mul, coeff_divOf] + · rw [coeff_modOf_of_not_exists_add x _ _ h, coeff_single_mul_of_forall_add_ne, zero_add] + simpa [eq_comm] using h theorem modOf_add_divOf [IsCancelAdd G] (x : k[G]) (g : G) : x %ᵒᶠ g + of' k G g * (x /ᵒᶠ g) = x := by diff --git a/Mathlib/Algebra/MonoidAlgebra/Grading.lean b/Mathlib/Algebra/MonoidAlgebra/Grading.lean index 618855dacd15c4..79ae0eda9aea07 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Grading.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Grading.lean @@ -48,7 +48,7 @@ variable (R) [CommSemiring R] /-- The submodule corresponding to each grade given by the degree function `f`. -/ abbrev gradeBy (f : M → ι) (i : ι) : Submodule R R[M] where - carrier := { a | ∀ m, m ∈ a.support → f m = i } + carrier := { a | ∀ m, m ∈ a.coeff.support → f m = i } zero_mem' m h := by cases h add_mem' {a b} ha hb m h := by classical exact (Finset.mem_union.mp (Finsupp.support_add h)).elim (ha m) (hb m) @@ -61,22 +61,17 @@ abbrev grade (m : M) : Submodule R R[M] := theorem gradeBy_id : gradeBy R (id : M → M) = grade R := rfl theorem mem_gradeBy_iff (f : M → ι) (i : ι) (a : R[M]) : - a ∈ gradeBy R f i ↔ (a.support : Set M) ⊆ f ⁻¹' {i} := by rfl + a ∈ gradeBy R f i ↔ (a.coeff.support : Set M) ⊆ f ⁻¹' {i} := by rfl -theorem mem_grade_iff (m : M) (a : R[M]) : a ∈ grade R m ↔ a.support ⊆ {m} := by +theorem mem_grade_iff (m : M) (a : R[M]) : a ∈ grade R m ↔ a.coeff.support ⊆ {m} := by rw [← Finset.coe_subset, Finset.coe_singleton] rfl theorem mem_grade_iff' (m : M) (a : R[M]) : - a ∈ grade R m ↔ a ∈ (LinearMap.range (Finsupp.lsingle m : R →ₗ[R] M →₀ R) : - Submodule R R[M]) := by - rw [mem_grade_iff, Finsupp.support_subset_singleton'] - apply exists_congr - intro r - constructor <;> exact Eq.symm - -theorem grade_eq_lsingle_range (m : M) : - grade R m = LinearMap.range (Finsupp.lsingle m : R →ₗ[R] M →₀ R) := + a ∈ grade R m ↔ a ∈ LinearMap.range (lsingle (R := R) m) := by + rw [mem_grade_iff, Finsupp.support_subset_singleton']; simp [← coeff_inj, eq_comm] + +theorem grade_eq_lsingle_range (m : M) : grade R m = LinearMap.range (lsingle m) := Submodule.ext (mem_grade_iff' R m) theorem single_mem_gradeBy {R} [CommSemiring R] (f : M → ι) (m : M) (r : R) : @@ -100,8 +95,8 @@ instance gradeBy.gradedMonoid [AddMonoid M] [AddMonoid ι] [CommSemiring R] (f : apply map_zero mul_mem i j a b ha hb c hc := by classical - obtain ⟨ma, hma, mb, hmb, rfl⟩ : ∃ y ∈ a.support, ∃ z ∈ b.support, y + z = c := - Finset.mem_add.1 <| support_mul a b hc + obtain ⟨ma, hma, mb, hmb, rfl⟩ : ∃ y ∈ a.coeff.support, ∃ z ∈ b.coeff.support, y + z = c := + Finset.mem_add.1 <| support_coeff_mul_subset a b hc rw [map_add, ha ma hma, hb mb hmb] instance grade.gradedMonoid [AddMonoid M] [CommSemiring R] : @@ -114,26 +109,17 @@ set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition; the canonical grade decomposition, used to provide `DirectSum.decompose`. -/ def decomposeAux : R[M] →ₐ[R] ⨁ i : ι, gradeBy R f i := - AddMonoidAlgebra.lift R _ M - { toFun := fun m => - DirectSum.of (fun i : ι => gradeBy R f i) (f m.toAdd) - ⟨Finsupp.single m.toAdd 1, single_mem_gradeBy _ _ _⟩ - map_one' := - DirectSum.of_eq_of_gradedMonoid_eq - (by congr 2 <;> simp) - map_mul' := fun i j => by - symm - dsimp +instances only [toAdd_one, Eq.ndrec, Set.mem_setOf_eq, ne_eq, OneHom.toFun_eq_coe, - OneHom.coe_mk, toAdd_mul] - convert! DirectSum.of_mul_of (A := (fun i : ι => gradeBy R f i)) _ _ - repeat { rw [map_add] } - simp only [SetLike.coe_gMul] - exact Eq.trans (by rw [one_mul]) (single_mul_single ..).symm } + lift R _ M { + toFun m := .of (fun i ↦ gradeBy R f i) (f m.toAdd) ⟨single m.toAdd 1, single_mem_gradeBy _ _ _⟩ + map_one' := of_eq_of_gradedMonoid_eq (by congr 2 <;> simp) + map_mul' i j := by + simpa [toAdd_mul, of_mul_of, GradedMonoid.GMul.mul, single_mul_single, mul_one] using + DirectSum.of_eq_of_gradedMonoid_eq <| Sigma.subtype_ext (f.map_add _ _) rfl + } theorem decomposeAux_single (m : M) (r : R) : - decomposeAux f (Finsupp.single m r) = - DirectSum.of (fun i : ι => gradeBy R f i) (f m) - ⟨Finsupp.single m r, single_mem_gradeBy _ _ _⟩ := by + decomposeAux f (single m r) = + .of (fun i ↦ gradeBy R f i) (f m) ⟨single m r, single_mem_gradeBy _ _ _⟩ := by refine (lift_single _ _ _).trans ?_ refine (DirectSum.of_smul R _ _ _).symm.trans ?_ apply DirectSum.of_eq_of_gradedMonoid_eq @@ -142,21 +128,20 @@ theorem decomposeAux_single (m : M) (r : R) : rw [mul_one] rfl -set_option backward.isDefEq.respectTransparency false in theorem decomposeAux_coe {i : ι} (x : gradeBy R f i) : decomposeAux f ↑x = DirectSum.of (fun i => gradeBy R f i) i x := by classical obtain ⟨x, hx⟩ := x revert hx - refine Finsupp.induction x ?_ ?_ + refine induction x ?_ ?_ · intro hx symm exact map_zero _ · intro m b y hmy hb ih hmby - have : Disjoint (Finsupp.single m b).support y.support := by + have : Disjoint (Finsupp.single m b).support y.coeff.support := by simpa only [Finsupp.support_single _ hb, Finset.disjoint_singleton_left] - rw [mem_gradeBy_iff, Finsupp.support_add_eq this, Finset.coe_union, Set.union_subset_iff] - at hmby + rw [mem_gradeBy_iff, coeff_add, coeff_single, Finsupp.support_add_eq this, Finset.coe_union, + Set.union_subset_iff] at hmby obtain ⟨h1, h2⟩ := hmby have : f m = i := by rwa [Finsupp.support_single _ hb, Finset.coe_singleton, Set.singleton_subset_iff] @@ -184,17 +169,16 @@ theorem decomposeAux_eq_decompose : rfl theorem GradesBy.decompose_single (m : M) (r : R) : - DirectSum.decompose (gradeBy R f) (Finsupp.single m r : R[M]) = - DirectSum.of (fun i : ι => gradeBy R f i) (f m) - ⟨Finsupp.single m r, single_mem_gradeBy _ _ _⟩ := + DirectSum.decompose (gradeBy R f) (single m r : R[M]) = + .of (fun i ↦ gradeBy R f i) (f m) ⟨single m r, single_mem_gradeBy _ _ _⟩ := decomposeAux_single _ _ _ instance grade.gradedAlgebra : GradedAlgebra (grade R : ι → Submodule _ _) := inferInstanceAs <| GradedAlgebra (gradeBy R (AddMonoidHom.id ι)) theorem grade.decompose_single (i : ι) (r : R) : - DirectSum.decompose (grade R : ι → Submodule _ _) (Finsupp.single i r : AddMonoidAlgebra _ _) = - DirectSum.of (fun i : ι => grade R i) i ⟨Finsupp.single i r, single_mem_grade _ _⟩ := + DirectSum.decompose (grade R : ι → Submodule _ _) (single i r) = + .of (fun i ↦ grade R i) i ⟨single i r, single_mem_grade _ _⟩ := decomposeAux_single _ _ _ /-- `AddMonoidAlgebra.gradeBy` describe an internally graded algebra. -/ diff --git a/Mathlib/Algebra/MonoidAlgebra/Ideal.lean b/Mathlib/Algebra/MonoidAlgebra/Ideal.lean index 68bf3947b9cd74..75c694b5535431 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Ideal.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Ideal.lean @@ -18,7 +18,6 @@ public section variable {k A G : Type*} -set_option backward.isDefEq.respectTransparency false in /-- If `x` belongs to the ideal generated by generators in `s`, then every element of the support of `x` factors through an element of `s`. @@ -26,14 +25,15 @@ We could spell `∃ d, m = d * m` as `MulOpposite.op m' ∣ MulOpposite.op m` bu -/ theorem MonoidAlgebra.mem_ideal_span_of_image [Monoid G] [Semiring k] {s : Set G} {x : MonoidAlgebra k G} : - x ∈ Ideal.span (MonoidAlgebra.of k G '' s) ↔ ∀ m ∈ x.support, ∃ m' ∈ s, ∃ d, m = d * m' := by + x ∈ Ideal.span (MonoidAlgebra.of k G '' s) ↔ + ∀ m ∈ x.coeff.support, ∃ m' ∈ s, ∃ d, m = d * m' := by classical let RHS : Ideal (MonoidAlgebra k G) := - { carrier := { p | ∀ m : G, m ∈ p.support → ∃ m' ∈ s, ∃ d, m = d * m' } + { carrier := { p | ∀ m : G, m ∈ p.coeff.support → ∃ m' ∈ s, ∃ d, m = d * m' } add_mem' {x y} hx hy m hm := (Finset.mem_union.1 <| Finsupp.support_add hm).elim (hx m) (hy m) zero_mem' := by simp smul_mem' x y hy m hm := by - simp only [smul_eq_mul, mul_def] at hm + simp only [smul_eq_mul, mul_def, coeff_finsuppSum] at hm obtain ⟨xm, -, hm⟩ := Finset.mem_biUnion.mp (Finsupp.support_sum hm) obtain ⟨ym, hym, hm⟩ := Finset.mem_biUnion.mp (Finsupp.support_sum hm) obtain rfl := Finset.mem_singleton.mp (Finsupp.support_single_subset hm) @@ -48,10 +48,10 @@ theorem MonoidAlgebra.mem_ideal_span_of_image [Monoid G] [Semiring k] {s : Set G refine ⟨_, hi, 1, ?_⟩ simpa using Finsupp.support_single_subset hm · intro hx - rw [← Finsupp.sum_single x] + rw [← x.sum_coeff_single] apply Ideal.sum_mem _ fun i hi ↦ ?_ obtain ⟨d, hd, d2, rfl⟩ := hx _ hi - simpa using Ideal.mul_mem_left _ (.single d2 <| x (d2 * d)) (b := of k G d) + simpa using Ideal.mul_mem_left _ (.single d2 <| x.coeff (d2 * d)) (b := of k G d) (Ideal.subset_span <| Set.mem_image_of_mem _ hd) /-- If `x` belongs to the ideal generated by generators in `s`, then every element of the support of @@ -59,5 +59,35 @@ theorem MonoidAlgebra.mem_ideal_span_of_image [Monoid G] [Semiring k] {s : Set G -/ theorem AddMonoidAlgebra.mem_ideal_span_of'_image [AddMonoid A] [Semiring k] {s : Set A} {x : AddMonoidAlgebra k A} : - x ∈ Ideal.span (AddMonoidAlgebra.of' k A '' s) ↔ ∀ m ∈ x.support, ∃ m' ∈ s, ∃ d, m = d + m' := - @MonoidAlgebra.mem_ideal_span_of_image k (Multiplicative A) _ _ _ _ + x ∈ Ideal.span (AddMonoidAlgebra.of' k A '' s) ↔ + ∀ m ∈ x.coeff.support, ∃ m' ∈ s, ∃ d, m = d + m' := by + -- TODO: this proof is a direct copy of MonoidAlgebra.mem_ideal_span_of_image. + -- Alternatively, we could prove it via the equiv between `MonoidAlgebra` and `AddMonoidAlgebra`, + -- but that would require a lot more API. + classical + let RHS : Ideal (AddMonoidAlgebra k A) := { + carrier := { p | ∀ m : A, m ∈ p.coeff.support → ∃ m' ∈ s, ∃ d, m = d + m' } + add_mem' {x y} hx hy m hm := (Finset.mem_union.1 <| Finsupp.support_add hm).elim (hx m) (hy m) + zero_mem' := by simp + smul_mem' x y hy m hm := by + simp only [smul_eq_mul, mul_def, coeff_finsuppSum] at hm + obtain ⟨xm, -, hm⟩ := Finset.mem_biUnion.mp <| Finsupp.support_sum hm + obtain ⟨ym, hym, hm⟩ := Finset.mem_biUnion.mp <| Finsupp.support_sum hm + obtain rfl := Finset.mem_singleton.mp <| Finsupp.support_single_subset hm + refine (hy _ hym).imp fun sm ↦ .imp_right ?_ + rintro ⟨d, rfl⟩ + exact ⟨xm + d, (add_assoc ..).symm⟩ + } + change _ ↔ x ∈ RHS + constructor + · suffices Ideal.span (of' k A '' s) ≤ RHS from @this x + rw [Ideal.span_le] + rintro _ ⟨i, hi, rfl⟩ m hm + refine ⟨_, hi, 0, ?_⟩ + simpa using Finsupp.support_single_subset hm + · intro hx + rw [← x.sum_coeff_single] + apply Ideal.sum_mem _ fun i hi ↦ ?_ + obtain ⟨d, hd, d2, rfl⟩ := hx _ hi + simpa using Ideal.mul_mem_left _ (.single d2 <| x.coeff (d2 + d)) + (b := of' k A d) (Ideal.subset_span <| Set.mem_image_of_mem _ hd) diff --git a/Mathlib/Algebra/MonoidAlgebra/Lift.lean b/Mathlib/Algebra/MonoidAlgebra/Lift.lean index 56726221b2e651..e1e568811444da 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Lift.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Lift.lean @@ -47,7 +47,7 @@ and the range of either `f` or `g` is in center of `R`, then the result is a rin `R` is a `k`-algebra and `f = algebraMap k R`, then the result is an algebra homomorphism called `MonoidAlgebra.lift`. -/ def liftNC (f : k →+ R) (g : G → R) : k[G] →+ R := - liftAddHom fun x : G => (AddMonoidHom.mulRight (g x)).comp f + (liftAddHom fun x ↦ .comp (.mulRight (g x)) f).comp coeffAddEquiv.toAddMonoidHom @[simp] theorem liftNC_single (f : k →+ R) (g : G → R) (a : G) (b : k) : @@ -62,9 +62,9 @@ variable [Semiring k] [Mul G] [Semiring R] theorem liftNC_mul {g_hom : Type*} [FunLike g_hom G R] [MulHomClass g_hom G R] (f : k →+* R) (g : g_hom) (a b : k[G]) - (h_comm : ∀ {x y}, y ∈ a.support → Commute (f (b x)) (g y)) : + (h_comm : ∀ {x y}, y ∈ a.coeff.support → Commute (f (b.coeff x)) (g y)) : liftNC (f : k →+ R) g (a * b) = liftNC (f : k →+ R) g a * liftNC (f : k →+ R) g b := by - conv_rhs => rw [← sum_single a, ← sum_single b] + conv_rhs => rw [← sum_coeff_single a, ← sum_coeff_single b] simp_rw [mul_def, map_finsuppSum, liftNC_single, Finsupp.sum_mul, Finsupp.mul_sum] refine Finset.sum_congr rfl fun y hy => Finset.sum_congr rfl fun x _hx => ?_ simp [mul_assoc, (h_comm hy).left_comm] @@ -119,7 +119,7 @@ is a ring homomorphism and the range of either `f` or `g` is in center of `R`, t ring homomorphism. If `R` is a `k`-algebra and `f = algebraMap k R`, then the result is an algebra homomorphism called `AddMonoidAlgebra.lift`. -/ def liftNC (f : k →+ R) (g : Multiplicative G → R) : k[G] →+ R := - liftAddHom fun x : G => (AddMonoidHom.mulRight (g <| Multiplicative.ofAdd x)).comp f + (liftAddHom fun x ↦ .comp (.mulRight (g <| .ofAdd x)) f).comp coeffAddEquiv.toAddMonoidHom @[simp] theorem liftNC_single (f : k →+ R) (g : Multiplicative G → R) (a : G) (b : k) : @@ -135,9 +135,12 @@ variable [Semiring k] [Add G] [Semiring R] theorem liftNC_mul {g_hom : Type*} [FunLike g_hom (Multiplicative G) R] [MulHomClass g_hom (Multiplicative G) R] (f : k →+* R) (g : g_hom) (a b : k[G]) - (h_comm : ∀ {x y}, y ∈ a.support → Commute (f (b x)) (g <| Multiplicative.ofAdd y)) : - liftNC (f : k →+ R) g (a * b) = liftNC (f : k →+ R) g a * liftNC (f : k →+ R) g b := - MonoidAlgebra.liftNC_mul f g _ _ @h_comm + (h_comm : ∀ {x y}, y ∈ a.coeff.support → Commute (f (b.coeff x)) (g <| .ofAdd y)) : + liftNC (f : k →+ R) g (a * b) = liftNC (f : k →+ R) g a * liftNC (f : k →+ R) g b := by + conv_rhs => rw [← sum_coeff_single a, ← sum_coeff_single b] + simp_rw [mul_def, map_finsuppSum, liftNC_single, Finsupp.sum_mul, Finsupp.mul_sum] + refine Finset.sum_congr rfl fun y hy => Finset.sum_congr rfl fun x _hx => ?_ + simp [mul_assoc, (h_comm hy).left_comm] end Mul diff --git a/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean b/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean index 78ac51ec702b1a..4c26e9fb3c9cc1 100644 --- a/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean +++ b/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean @@ -28,37 +28,30 @@ variable [Semiring R] [Semiring S] [Semiring T] {f : M → N} {a : M} {r : R} /-- Given a function `f : M → N` between magmas, return the corresponding map `R[M] → R[N]` obtained by summing the coefficients along each fiber of `f`. -/ -@[to_additive /-- -Given a function `f : M → N` between magmas, return the corresponding map `R[M] → R[N]` obtained +@[to_additive (attr := simps) +/-- Given a function `f : M → N` between magmas, return the corresponding map `R[M] → R[N]` obtained by summing the coefficients along each fiber of `f`. -/] -abbrev mapDomain (f : M → N) (x : R[M]) : R[N] := Finsupp.mapDomain f x +def mapDomain (f : M → N) (x : R[M]) : R[N] := .ofCoeff <| Finsupp.mapDomain f x.coeff @[to_additive (attr := simp)] -lemma coeff_mapDomain (f : M → N) (x : R[M]) : - (mapDomain f x).coeff = x.coeff.mapDomain f := rfl - -/-- This isn't marked as simp to avoid looping with unfolding `coeff`. -/ -@[to_additive /-- This isn't marked as simp to avoid looping with unfolding `coeff`. -/] -lemma ofCoeff_mapDomain (f : M → N) (x : M →₀ R) : - ofCoeff (.mapDomain f x) = mapDomain f (ofCoeff x) := rfl - -@[to_additive] -lemma mapDomain_zero (f : M → N) : mapDomain f (0 : R[M]) = 0 := Finsupp.mapDomain_zero .. +lemma mapDomain_zero (f : M → N) : mapDomain f (0 : R[M]) = 0 := by ext; simp @[to_additive] lemma mapDomain_add (f : M → N) (x y : R[M]) : - mapDomain f (x + y) = mapDomain f x + mapDomain f y := Finsupp.mapDomain_add .. + mapDomain f (x + y) = mapDomain f x + mapDomain f y := by + ext; simp [Finsupp.mapDomain_add] @[to_additive] lemma mapDomain_sum (f : M → N) (x : S[M]) (v : M → S → R[M]) : - mapDomain f (x.sum v) = x.sum fun a b ↦ mapDomain f (v a b) := Finsupp.mapDomain_sum + mapDomain f (x.coeff.sum v) = x.coeff.sum fun a b ↦ mapDomain f (v a b) := by + ext; simp [Finsupp.mapDomain_sum] -@[to_additive] +@[to_additive (attr := simp)] lemma mapDomain_single : mapDomain f (single a r) = single (f a) r := by ext; simp @[to_additive] lemma mapDomain_injective (hf : Injective f) : Injective (mapDomain (R := R) f) := - Finsupp.mapDomain_injective hf + ofCoeff_injective.comp <| (Finsupp.mapDomain_injective hf).comp coeff_injective @[to_additive (dont_translate := R) (attr := simp) mapDomain_one] theorem mapDomain_one [One M] [One N] {F : Type*} [FunLike F M N] [OneHomClass F M N] (f : F) : @@ -67,7 +60,7 @@ theorem mapDomain_one [One M] [One N] {F : Type*} [FunLike F M N] [OneHomClass F /-- Given a map `f : R →+ S`, return the corresponding map `R[M] → S[M]` obtained by mapping each coefficient along `f`. -/ -@[to_additive (attr := simps!) +@[to_additive /-- Given a map `f : R →+ S`, return the corresponding map `R[M] → S[M]` obtained by mapping each coefficient along `f`. -/] def map (f : R →+ S) (x : R[M]) : S[M] := .ofCoeff <| x.coeff.mapRange f f.map_zero @@ -82,26 +75,25 @@ lemma ofCoeff_mapRange (f : R →+ S) (x : M →₀ R) : ofCoeff (.mapRange f f.map_zero x) = map f (ofCoeff x) := rfl @[to_additive (attr := simp)] -protected lemma map_zero (f : R →+ S) : map f (0 : R[M]) = 0 := mapRange_zero (hf := f.map_zero) +protected lemma map_zero (f : R →+ S) : map f (0 : R[M]) = 0 := by ext; simp @[to_additive] -protected lemma map_add (f : R →+ S) (x y : R[M]) : map f (x + y) = map f x + map f y := - mapRange_add (hf := f.map_zero) f.map_add .. +protected lemma map_add (f : R →+ S) (x y : R[M]) : map f (x + y) = map f x + map f y := by + ext; simp @[to_additive] protected lemma map_sum (f : R →+ S) (s : Finset ι) (x : ι → R[M]) : - map f (∑ i ∈ s, x i) = ∑ i ∈ s, map f (x i) := mapRange_finsetSum .. + map f (∑ i ∈ s, x i) = ∑ i ∈ s, map f (x i) := by ext; simp @[to_additive (attr := simp)] -lemma map_single (f : R →+ S) (r : R) (m : M) : map f (single m r) = single m (f r) := - mapRange_single (hf := f.map_zero) +lemma map_single (f : R →+ S) (r : R) (m : M) : map f (single m r) = single m (f r) := by ext; simp @[to_additive (attr := simp)] -lemma map_id (x : R[M]) : map (.id R) x = x := by simp [map, coeff, ofCoeff] +lemma map_id (x : R[M]) : map (.id R) x = x := by ext; simp @[to_additive (attr := simp)] -lemma map_map (f : S →+ T) (g : R →+ S) (x : R[M]) : - map f (map g x) = map (f.comp g) x := by simp [map, coeff, ofCoeff] +lemma map_map (f : S →+ T) (g : R →+ S) (x : R[M]) : map f (map g x) = map (f.comp g) x := by + ext; simp @[to_additive] lemma range_map (f : R →+ S) : Set.range (map (M := M) f) = {x | ∀ i, x.coeff i ∈ Set.range f} := @@ -140,16 +132,16 @@ lemma coeff_comapDomain (f : M → N) (hf) (x : R[N]) : (comapDomain f hf x).coeff = x.coeff.comapDomain f hf.injOn := by simp [comapDomain] @[to_additive (attr := simp)] -lemma comapDomain_zero (f : M → N) (hf) : comapDomain f hf (0 : R[N]) = 0 := by simp [comapDomain] +lemma comapDomain_zero (f : M → N) (hf) : comapDomain f hf (0 : R[N]) = 0 := by ext; simp @[to_additive (attr := simp)] lemma comapDomain_add (f : M → N) (hf) (x y : R[N]) : comapDomain f hf (x + y) = comapDomain f hf x + comapDomain f hf y := by - simp [comapDomain, comapDomain_add_of_injective hf] + ext; simp [comapDomain_add_of_injective hf] @[simp] lemma comapDomain_single_of_not_mem_range {r : R} {n : N} (hn : n ∉ Set.range f) (hf) : - comapDomain f hf (single n r) = 0 := by simp [comapDomain, coeff, single, *] + comapDomain f hf (single n r) = 0 := by ext; simp [*] /-- `comapDomain` as an `AddMonoidHom`. -/ @[to_additive (attr := simps) comapDomainAddMonoidHom /-- `comapDomain` as an `AddMonoidHom`. -/] @@ -160,16 +152,16 @@ def comapDomainAddMonoidHom (f : M → N) (hf : Injective f) : R[N] →+ R[M] wh @[to_additive (attr := simp)] lemma comapDomain_single_map (f : M → N) (hf) (m : M) (r : R) : - comapDomain f hf (single (f m) r) = single m r := by simp [comapDomain, single, coeff, ofCoeff] + comapDomain f hf (single (f m) r) = single m r := by ext; simp @[to_additive] lemma mapDomain_comapDomain {f : M → N} {x : R[N]} (hx : ↑x.coeff.support ⊆ Set.range f) (hf) : - mapDomain f (comapDomain f hf x) = x := Finsupp.mapDomain_comapDomain _ hf _ hx + mapDomain f (comapDomain f hf x) = x := by + ext : 1; exact Finsupp.mapDomain_comapDomain _ hf _ hx section Mul variable [Mul M] [Mul N] [Mul O] [FunLike F M N] [MulHomClass F M N] -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) mapDomain_mul] lemma mapDomain_mul (f : F) (x y : R[M]) : mapDomain f (x * y) = mapDomain f x * mapDomain f y := by simp [mul_def, mapDomain_sum, add_mul, mul_add, sum_mapDomain_index] @@ -211,8 +203,10 @@ def mapDomainAddEquiv (e : M ≃ N) : R[M] ≃+ R[N] where map_add' x y := by ext; simp @[to_additive (attr := simp)] -lemma mapDomainAddEquiv_apply (e : M ≃ N) (x : R[M]) (n : N) : - mapDomainAddEquiv R e x n = x (e.symm n) := by simp [mapDomainAddEquiv] +lemma coeff_mapDomainAddEquiv (e : M ≃ N) (x : R[M]) : + (mapDomainAddEquiv R e x).coeff = equivMapDomain e x.coeff := by ext; simp [mapDomainAddEquiv] + +@[deprecated (since := "2026-06-18")] alias mapDomainAddEquiv_apply := coeff_mapDomainAddEquiv @[to_additive (attr := simp)] lemma mapDomainAddEquiv_single (e : M ≃ N) (r : R) (m : M) : @@ -245,10 +239,12 @@ def mapAddEquiv (e : R ≃+ S) : R[M] ≃+ S[M] where @[deprecated (since := "2026-03-20")] alias mapRangeAddEquiv := mapAddEquiv @[to_additive (attr := simp)] -lemma mapAddEquiv_apply (e : R ≃+ S) (x : R[M]) (m : M) : - mapAddEquiv M e x m = e (x m) := by simp [mapAddEquiv, map, coeff, ofCoeff] +lemma coeff_mapAddEquiv (e : R ≃+ S) (x : R[M]) (m : M) : + (mapAddEquiv M e x).coeff m = e (x.coeff m) := by simp [mapAddEquiv] + +@[deprecated (since := "2026-06-18")] alias mapAddEquiv_apply := coeff_mapAddEquiv -@[deprecated (since := "2026-03-20")] alias mapRangeAddEquiv_apply := mapAddEquiv_apply +@[deprecated (since := "2026-03-20")] alias mapRangeAddEquiv_apply := coeff_mapAddEquiv @[to_additive (attr := simp)] lemma mapAddEquiv_single (e : R ≃+ S) (r : R) (m : M) : @@ -269,15 +265,12 @@ lemma mapAddEquiv_trans (e₁ : R ≃+ S) (e₂ : S ≃+ T) : @[deprecated (since := "2026-03-20")] alias mapRangeAddEquiv_trans := mapAddEquiv_trans -set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp) (dont_translate := R S) map_mul] protected lemma map_mul (f : R →+* S) (x y : R[M]) : map (f : R →+ S) (x * y) = map f x * map f y := by classical ext - simp [mul_def] - simp [MonoidAlgebra, sum_mapRange_index, map_finsuppSum, single_apply, apply_ite, map, - coeff, ofCoeff] + simp [mul_def, sum_mapRange_index, map_finsuppSum, single_apply, apply_ite] end Mul @@ -329,15 +322,16 @@ lemma coe_mapRingHom (f : R →+* S) : ⇑(mapRingHom M f) = map f := rfl @[deprecated (since := "2026-03-20")] alias coe_mapRangeRingHom := coe_mapRingHom @[to_additive (attr := simp)] -lemma mapRingHom_apply (f : R →+* S) (x : R[M]) (m : M) : - mapRingHom M f x m = f (x m) := by simp [mapRingHom, map, coeff, ofCoeff] +lemma coeff_mapRingHom (f : R →+* S) (x : R[M]) (m : M) : + (mapRingHom M f x).coeff m = f (x.coeff m) := by simp [mapRingHom] + +@[deprecated (since := "2026-06-18")] alias mapRingHom_apply := coeff_mapRingHom -@[deprecated (since := "2026-03-20")] alias mapRangeRingHom_apply := mapRingHom_apply +@[deprecated (since := "2026-03-20")] alias mapRangeRingHom_apply := coeff_mapRingHom @[to_additive (attr := simp)] lemma mapRingHom_single (f : R →+* S) (a : M) (b : R) : - mapRingHom M f (single a b) = single a (f b) := by - classical ext; simp [single_apply, apply_ite f] + mapRingHom M f (single a b) = single a (f b) := by simp [mapRingHom] @[deprecated (since := "2026-03-20")] alias mapRangeRingHom_single := mapRingHom_single @@ -370,8 +364,10 @@ def mapDomainRingEquiv (e : M ≃* N) : R[M] ≃+* R[N] := (by apply MonoidAlgebra.ringHom_ext <;> simp) (by apply MonoidAlgebra.ringHom_ext <;> simp) @[to_additive (attr := simp)] -lemma mapDomainRingEquiv_apply (e : M ≃* N) (x : R[M]) (n : N) : - mapDomainRingEquiv R e x n = x (e.symm n) := mapDomainAddEquiv_apply .. +lemma coeff_mapDomainRingEquiv (e : M ≃* N) (x : R[M]) : + (mapDomainRingEquiv R e x).coeff = equivMapDomain e x.coeff := coeff_mapDomainAddEquiv .. + +@[deprecated (since := "2026-06-18")] alias mapDomainRingEquiv_apply := coeff_mapDomainRingEquiv @[to_additive (attr := simp)] lemma mapDomainRingEquiv_single (e : M ≃* N) (r : R) (m : M) : @@ -401,10 +397,12 @@ def mapRingEquiv (e : R ≃+* S) : R[M] ≃+* S[M] := @[deprecated (since := "2026-03-20")] alias mapRangeRingEquiv := mapRingEquiv @[to_additive (attr := simp)] -lemma mapRingEquiv_apply (e : R ≃+* S) (x : R[M]) (m : M) : - mapRingEquiv M e x m = e (x m) := by simp [mapRingEquiv] +lemma coeff_mapRingEquiv (e : R ≃+* S) (x : R[M]) (m : M) : + (mapRingEquiv M e x).coeff m = e (x.coeff m) := by simp [mapRingEquiv] + +@[deprecated (since := "2026-06-18")] alias mapRingEquiv_apply := coeff_mapRingEquiv -@[deprecated (since := "2026-03-20")] alias mapRangeRingEquiv_apply := mapRingEquiv_apply +@[deprecated (since := "2026-03-20")] alias mapRangeRingEquiv_apply := coeff_mapRingEquiv @[to_additive (attr := simp)] lemma mapRingEquiv_single (e : R ≃+* S) (r : R) (m : M) : @@ -441,18 +439,15 @@ def commRingEquiv : R[M][N] ≃+* R[N][M] := @[to_additive (attr := simp)] lemma symm_commRingEquiv : (commRingEquiv : R[M][N] ≃+* R[N][M]).symm = commRingEquiv := rfl -set_option backward.isDefEq.respectTransparency false in -@[to_additive (dont_translate := R) (attr := simp)] +@[to_additive (attr := simp)] lemma commRingEquiv_single_single (m : M) (n : N) (r : R) : - commRingEquiv (single m <| single n r) = single n (single m r) := by - simp [commRingEquiv, MonoidAlgebra, curryRingEquiv, curryAddEquiv, mapDomainRingEquiv, - mapDomainRingHom, EquivLike.toEquiv] + commRingEquiv (single m <| single n r) = single n (single m r) := by simp [commRingEquiv] @[to_additive (dont_translate := R) (attr := simp)] lemma commRingEquiv_single_one (m : M) : commRingEquiv (single m (1 : R[N])) = single 1 (single m 1) := commRingEquiv_single_single .. --- We want this lemma to be tried before `commRingEquiv_single_single`. +-- We want this to have higher priority than `commRingEquiv_single_single` @[to_additive (dont_translate := R) (attr := simp high)] lemma commRingEquiv_single_one_single (m : M) : commRingEquiv (single 1 <| single m 1) = (single m (1 : R[N])) := commRingEquiv_single_single .. @@ -463,46 +458,48 @@ section Ring variable [Ring R] [Ring S] @[to_additive] -protected lemma map_neg (f : R →+ S) (x : R[M]) : map f (-x) = -map f x := - Finsupp.mapRange_neg (hf := f.map_zero) f.map_neg .. +protected lemma map_neg (f : R →+ S) (x : R[M]) : map f (-x) = -map f x := by ext; simp @[to_additive] -protected lemma map_sub (f : R →+ S) (x y : R[M]) : map f (x - y) = map f x - map f y := - Finsupp.mapRange_sub (hf := f.map_zero) f.map_sub .. +protected lemma map_sub (f : R →+ S) (x y : R[M]) : map f (x - y) = map f x - map f y := by + ext; simp end Ring end MonoidAlgebra /-! #### Conversions between `AddMonoidAlgebra` and `MonoidAlgebra` - -We have not defined `AddMonoidAlgebra k G = MonoidAlgebra k (Multiplicative G)` -because historically this caused problems; -since the changes that have made `nsmul` definitional, this would be possible, -but for now we just construct the ring isomorphisms using `RingEquiv.refl _`. -/ +set_option backward.isDefEq.respectTransparency false in variable (k G) in /-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of `Multiplicative` -/ protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] : AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) where - toFun x := x.mapDomain .ofAdd - invFun x := x.mapDomain Multiplicative.toAdd + toFun x := .ofCoeff <| x.coeff.mapDomain .ofAdd + invFun x := .ofCoeff <| x.coeff.mapDomain Multiplicative.toAdd left_inv x := by ext; simp right_inv x := by ext; simp - map_add' := mapDomain_add _ + map_add' x y := by simp [Finsupp.mapDomain_add] map_mul' x y := by - dsimp [Multiplicative.ofAdd] - exact MonoidAlgebra.mapDomain_mul (M := Multiplicative G) (MulHom.id (Multiplicative G)) x y + classical + ext + simp [MonoidAlgebra.coeff_mul, AddMonoidAlgebra.coeff_mul, Finsupp.sum_mapDomain_index, add_mul, + mul_add, ite_add_zero, Multiplicative.ext_iff] +set_option backward.isDefEq.respectTransparency false in variable (k G) in /-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/ protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] : MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) where - toFun x := x.mapDomain .ofMul - invFun x := x.mapDomain Additive.toMul + toFun x := .ofCoeff <| x.coeff.mapDomain .ofMul + invFun x := .ofCoeff <| x.coeff.mapDomain Additive.toMul left_inv x := by ext; simp right_inv x := by ext; simp - map_add' := mapDomain_add _ - map_mul' := MonoidAlgebra.mapDomain_mul (MulHom.id G) + map_add' x y := by simp [Finsupp.mapDomain_add] + map_mul' x y := by + classical + ext + simp [MonoidAlgebra.coeff_mul, AddMonoidAlgebra.coeff_mul, Finsupp.sum_mapDomain_index, add_mul, + mul_add, ite_add_zero, Additive.ext_iff] diff --git a/Mathlib/Algebra/MonoidAlgebra/Module.lean b/Mathlib/Algebra/MonoidAlgebra/Module.lean index 241638e85a37f6..8f8721f29c6dcf 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Module.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Module.lean @@ -6,9 +6,12 @@ Authors: Johannes Hölzl, Yury Kudryashov, Kim Morrison module public import Mathlib.Algebra.Module.BigOperators +public import Mathlib.Algebra.Module.Submodule.Map public import Mathlib.Algebra.Module.TransferInstance +public import Mathlib.Algebra.MonoidAlgebra.MapDomain public import Mathlib.Algebra.MonoidAlgebra.Lift public import Mathlib.LinearAlgebra.Basis.Defs +public import Mathlib.LinearAlgebra.Finsupp.Supported import Mathlib.LinearAlgebra.Span.Basic @@ -21,7 +24,7 @@ import Mathlib.LinearAlgebra.Span.Basic ## Implementation notes -We do not state the equivalent of `DistribMulAction G (MonoidAlgebra k G)` for `AddMonoidAlgebra` +We do not state the equivalent of `DistribMulAction M (MonoidAlgebra S M)` for `AddMonoidAlgebra` because mathlib does not have the notion of distributive actions of additive groups. -/ @@ -34,37 +37,102 @@ noncomputable section open Finsupp hiding single open Module -universe u₁ u₂ u₃ u₄ - -variable (k : Type u₁) (G : Type u₂) (H : Type*) {R S M : Type*} +variable {R S M N O G : Type*} /-! ### Multiplicative monoids -/ namespace MonoidAlgebra -variable {k G} - section SMul -variable {S : Type*} +section DistribMulAction +variable [Monoid S] [Semiring R] [DistribMulAction S R] + +@[to_additive (dont_translate := S) distribMulAction] +instance distribMulAction : DistribMulAction S R[M] := fast_instance% coeffEquiv.distribMulAction _ -@[to_additive (dont_translate := R) distribMulAction] -instance distribMulAction [Monoid R] [Semiring k] [DistribMulAction R k] : - DistribMulAction R k[G] := - inferInstanceAs <| DistribMulAction R (G →₀ k) +@[to_additive (dont_translate := S) (attr := simp)] +lemma mapDomain_smul (f : M → N) (s : S) (x : R[M]) : mapDomain f (s • x) = s • mapDomain f x := by + ext; simp [Finsupp.mapDomain_smul] + +end DistribMulAction section Module variable [Semiring R] [Semiring S] [Module R S] {s t : Set M} {x : S[M]} @[to_additive (dont_translate := R)] -instance module : Module R S[M] := inferInstanceAs <| Module R (M →₀ S) +instance : Module R S[M] := fast_instance% coeffEquiv.module _ + +@[to_additive] +instance instIsTorsionFree [IsTorsionFree R S] : IsTorsionFree R S[M] := + coeffEquiv.moduleIsTorsionFree _ variable (R) in /-- `MonoidAlgebra.coeff` as a linear equiv. -/ @[to_additive (attr := simps! apply symm_apply) /-- `MonoidAlgebra.coeff` as a linear equiv. -/] -def coeffLinearEquiv : S[M] ≃ₗ[R] M →₀ S := - coeffEquiv.linearEquiv _ +def coeffLinearEquiv : S[M] ≃ₗ[R] M →₀ S := coeffEquiv.linearEquiv _ + +variable (R S) in +/-- `MonoidAlgebra.mapDomain` as a linear map. -/ +@[to_additive /-- `AddMonoidAlgebra.mapDomain` as a linear map. -/] +def mapDomainLinearMap (f : M → N) : S[M] →ₗ[R] S[N] := + (coeffLinearEquiv _).symm.toLinearMap ∘ₗ Finsupp.lmapDomain _ _ f ∘ₗ + (coeffLinearEquiv _).toLinearMap + +@[to_additive (attr := simp)] +lemma coeff_mapDomainLinearMap (f : M → N) (x : S[M]) : + (mapDomainLinearMap R S f x).coeff = x.coeff.mapDomain f := rfl + +@[to_additive (attr := simp)] +lemma mapDomainLinearMap_single (f : M → N) (s : S) (m : M) : + mapDomainLinearMap R S f (single m s) = single (f m) s := by simp [mapDomainLinearMap] + +@[to_additive (attr := simp)] +lemma mapDomainLinearMap_comp (f : M → N) (g : N → O) : + mapDomainLinearMap R S (g ∘ f) = mapDomainLinearMap R S g ∘ₗ mapDomainLinearMap R S f := by + ext; simp [Finsupp.mapDomain_comp] + +variable (R S) in +/-- `MonoidAlgebra.mapDomain` as a linear equiv. -/ +@[to_additive /-- `AddMonoidAlgebra.mapDomain` as a linear equiv. -/] +def mapDomainLinearEquiv (e : M ≃ N) : S[M] ≃ₗ[R] S[N] := + (coeffLinearEquiv _).trans <| (Finsupp.domLCongr e).trans <| (coeffLinearEquiv _).symm + +@[to_additive (attr := simp)] +lemma coeff_mapDomainLinearEquiv (e : M ≃ N) (x : S[M]) : + (mapDomainLinearEquiv R S e x).coeff = equivMapDomain e x.coeff := rfl + +@[to_additive (attr := simp)] +lemma mapDomainLinearEquiv_single (e : M ≃ N) (s : S) (m : M) : + mapDomainLinearEquiv R S e (single m s) = single (e m) s := by simp [mapDomainLinearEquiv] + +@[to_additive (attr := simp)] +lemma symm_mapDomainLinearEquiv (e : M ≃ N) : + (mapDomainLinearEquiv R S e).symm = mapDomainLinearEquiv R S e.symm := rfl + +@[to_additive (attr := simp)] +lemma mapDomainLinearEquiv_trans (e₁ : M ≃ N) (e₂ : N ≃ O) : + mapDomainLinearEquiv R S (e₁.trans e₂) = + (mapDomainLinearEquiv R S e₁).trans (mapDomainLinearEquiv R S e₂) := by ext; simp + +variable (R M) in +/-- The trivial monoid algebra is the base ring. -/ +@[to_additive (dont_translate := R) +/-- The trivial monoid algebra is the base ring. -/] +def uniqueLinearEquiv [One M] [Subsingleton M] : S[M] ≃ₗ[R] S where + toAddEquiv := coeffAddEquiv.trans <| Finsupp.uniqueAddEquiv 1 + map_smul' r x := by simp + +variable (R) in +@[to_additive (attr := simp)] +lemma uniqueLinearEquiv_apply [One M] [Subsingleton M] (x : S[M]) : + uniqueLinearEquiv R M x = x.coeff 1 := rfl + +variable (R M) in +@[to_additive (attr := simp)] +lemma uniqueLinearEquiv_symm_apply [One M] [Subsingleton M] (s : S) : + (uniqueLinearEquiv R M).symm s = .single 1 s := rfl variable (R S s) in /-- The `R`-submodule of all elements of `S[M]` supported on a subset `s` of `M`. -/ @@ -88,7 +156,7 @@ variable (R S s) in @[to_additive (dont_translate := R)] lemma supported_eq_span_single : supported R R s = .span R ((fun m ↦ single m 1) '' s) := by simp [supported_eq_map, Finsupp.supported_eq_span_single R s, Submodule.map_span, - ← Set.image_comp, ofCoeff] + ← Set.image_comp] @[to_additive (attr := gcongr)] lemma supported_mono (hst : s ⊆ t) : supported R S s ≤ supported R S t := fun _ h ↦ h.trans hst @@ -109,80 +177,76 @@ def supportedEquivFinsupp (s : Set M) : supported R S s ≃ₗ[R] s →₀ S := end Module -@[to_additive (dont_translate := R)] -instance instIsTorsionFree [Semiring R] [Semiring k] [Module R k] [Module.IsTorsionFree R k] : - Module.IsTorsionFree R (MonoidAlgebra k G) := - inferInstanceAs <| IsTorsionFree R (G →₀ k) - @[to_additive (dont_translate := R) faithfulSMul] -instance faithfulSMul [Semiring k] [SMulZeroClass R k] [FaithfulSMul R k] [Nonempty G] : - FaithfulSMul R k[G] := - inferInstanceAs <| FaithfulSMul R (G →₀ k) +instance faithfulSMul [Semiring S] [SMulZeroClass R S] [FaithfulSMul R S] [Nonempty M] : + FaithfulSMul R S[M] := coeffEquiv.faithfulSMul _ /-- The standard basis for a monoid algebra. -/ @[to_additive /-- The standard basis for an additive monoid algebra. -/] def basis (R k) [Semiring k] : Module.Basis R k (MonoidAlgebra k R) where - repr := LinearEquiv.refl k (R →₀ k) + repr := coeffLinearEquiv _ @[to_additive (dont_translate := k) (attr := simp)] lemma basis_apply (k) [Semiring k] (r : R) : MonoidAlgebra.basis R k r = MonoidAlgebra.single r 1 := rfl -/-- This is not an instance as it conflicts with `MonoidAlgebra.distribMulAction` when `G = kˣ`. +/-- This is not an instance as it conflicts with `MonoidAlgebra.distribMulAction` when `M = kˣ`. -TODO: Change the type to `DistribMulAction Gᵈᵐᵃ k[G]` and then it can be an instance. +TODO: Change the type to `DistribMulAction Gᵈᵐᵃ S[M]` and then it can be an instance. TODO: Generalise to a group acting on another, instead of just the left multiplication action. -/ @[implicit_reducible] -def comapDistribMulActionSelf [Group G] [Semiring k] : DistribMulAction G k[G] := - fast_instance% Finsupp.comapDistribMulAction +def comapDistribMulActionSelf [Group G] [Semiring S] : DistribMulAction G S[G] := + have := Finsupp.comapDistribMulAction (G := G) (α := G) (M := S) + fast_instance% coeffEquiv.distribMulAction _ -end SMul +@[to_additive (dont_translate := R)] +lemma single_mem_span_single [Semiring R] [Nontrivial R] {m : M} {s : Set M} : + single m 1 ∈ Submodule.span R ((single · (1 : R)) '' s) ↔ m ∈ s := by + refine (Set.mem_image_equiv (f := (coeffLinearEquiv R).toEquiv)).symm.trans ?_ + change _ ∈ (Submodule.span R _).map (coeffLinearEquiv R).toLinearMap ↔ _ + simp [Submodule.map_span, ← Set.image_comp, Finsupp.single_mem_span_single] -/-! -#### Copies of `ext` lemmas and bundled `single`s from `Finsupp` +end SMul -As `MonoidAlgebra` is a type synonym, `ext` will not unfold it to find `ext` lemmas. -We need bundled version of `Finsupp.single` with the right types to state these lemmas. -It is good practice to have those, regardless of the `ext` issue. --/ +/-! #### Copies of `ext` lemmas and bundled `single`s from `Finsupp` -/ section ExtLemmas -variable [Semiring k] +variable [Semiring S] /-- `MonoidAlgebra.single` as a `DistribMulActionHom`. -/ @[to_additive (dont_translate := R) singleDistribMulActionHom /-- `AddMonoidAlgebra.single` as a `DistribMulActionHom`. -/] -def singleDistribMulActionHom [Monoid R] [DistribMulAction R k] (a : G) : k →+[R] k[G] where +def singleDistribMulActionHom [Monoid R] [DistribMulAction R S] (a : M) : S →+[R] S[M] where __ := singleAddHom a - map_smul' k m := by simp + map_smul' S m := by simp /-- A copy of `Finsupp.distribMulActionHom_ext'` for `MonoidAlgebra`. -/ @[to_additive (dont_translate := R) (attr := ext) distribMulActionHom_ext' /-- A copy of `Finsupp.distribMulActionHom_ext'` for `AddMonoidAlgebra`. -/] theorem distribMulActionHom_ext' {N : Type*} [Monoid R] [AddMonoid N] [DistribMulAction R N] - [DistribMulAction R k] {f g : k[G] →+[R] N} + [DistribMulAction R S] {f g : S[M] →+[R] N} (h : ∀ a, f.comp (singleDistribMulActionHom a) = g.comp (singleDistribMulActionHom a)) : f = g := - Finsupp.distribMulActionHom_ext' h + DistribMulActionHom.toAddMonoidHom_injective <| addMonoidHom_ext fun a x ↦ congr($(h a) x) /-- A copy of `Finsupp.lsingle` for `MonoidAlgebra`. -/ @[to_additive (dont_translate := R) /-- A copy of `Finsupp.lsingle` for `AddMonoidAlgebra`. -/] -abbrev lsingle [Semiring R] [Module R k] (a : G) : k →ₗ[R] k[G] := Finsupp.lsingle a +def lsingle [Semiring R] [Module R S] (a : M) : S →ₗ[R] S[M] := + (coeffLinearEquiv _).symm.toLinearMap.comp <| Finsupp.lsingle a @[to_additive (attr := simp)] -lemma lsingle_apply [Semiring R] [Module R k] (a : G) (b : k) : +lemma lsingle_apply [Semiring R] [Module R S] (a : M) (b : S) : lsingle (R := R) a b = single a b := rfl /-- A copy of `Finsupp.lhom_ext'` for `MonoidAlgebra`. -/ @[to_additive (attr := ext high)] -lemma lhom_ext' {N : Type*} [Semiring R] [AddCommMonoid N] [Module R N] [Module R k] - ⦃f g : k[G] →ₗ[R] N⦄ - (H : ∀ (x : G), LinearMap.comp f (lsingle x) = LinearMap.comp g (lsingle x)) : - f = g := - Finsupp.lhom_ext' H +lemma lhom_ext' {N : Type*} [Semiring R] [AddCommMonoid N] [Module R N] [Module R S] + ⦃f g : S[M] →ₗ[R] N⦄ + (H : ∀ (x : M), LinearMap.comp f (lsingle x) = LinearMap.comp g (lsingle x)) : f = g := + LinearMap.toAddMonoidHom_injective <| addMonoidHom_ext fun a x ↦ congr($(H a) x) end ExtLemmas @@ -194,7 +258,7 @@ lemma smul_of (m : M) (r : R) : r • of R M m = single m r := by simp /-- The image of an element `m : M` in `R[M]` belongs to the submodule generated by `s : Set M` if and only if `m ∈ s`. -/ lemma of_mem_span_of_iff [Nontrivial R] : of R M m ∈ Submodule.span R (of R M '' s) ↔ m ∈ s := - single_mem_span_single _ + single_mem_span_single /-- If the image of an element `m : M` in `R[M]` belongs to the submodule generated by the closure of some `s : Set M` then `m ∈ closure s`. -/ @@ -209,62 +273,49 @@ theorem liftNC_smul (f : S →+* R) (g : M →* R) (c : S) (φ : S[M]) : (AddMonoidHom.mulLeft (f c)).comp (liftNC (↑f) g) from DFunLike.congr_fun this φ ext - simp_rw [AddMonoidHom.comp_apply, singleAddHom_apply, smulAddHom_apply, - AddMonoidHom.coe_mulLeft, smul_single', liftNC_single, AddMonoidHom.coe_coe, map_mul, mul_assoc] + simp [mul_assoc] end MiscTheorems /-! #### Non-unital, non-associative algebra structure -/ section NonUnitalNonAssocAlgebra -variable (k) [Semiring k] [DistribSMul R k] [Mul G] +variable (S) [Semiring S] [DistribSMul R S] [Mul M] -set_option backward.isDefEq.respectTransparency false in -@[to_additive (dont_translate := R k) isScalarTower_self] -instance isScalarTower_self [IsScalarTower R k k] : IsScalarTower R k[G] k[G] where +@[to_additive (dont_translate := R S) isScalarTower_self] +instance isScalarTower_self [IsScalarTower R S S] : IsScalarTower R S[M] S[M] where smul_assoc t a b := by - classical ext; simp [mul_apply, sum_smul_index' (b := t), smul_sum, smul_mul_assoc] + classical ext; simp [coeff_mul, sum_smul_index', Finsupp.smul_sum, smul_mul_assoc] -set_option backward.isDefEq.respectTransparency false in -/-- Note that if `k` is a `CommSemiring` then we have `SMulCommClass k k k` and so we can take -`R = k` in the below. In other words, if the coefficients are commutative amongst themselves, they +/-- Note that if `S` is a `CommSemiring` then we have `SMulCommClass S S S` and so we can take +`R = S` in the below. In other words, if the coefficients are commutative amongst themselves, they also commute with the algebra multiplication. -/ -@[to_additive (dont_translate := R k) smulCommClass_self] -instance smulCommClass_self [SMulCommClass R k k] : SMulCommClass R k[G] k[G] where +@[to_additive (dont_translate := R S) smulCommClass_self] +instance smulCommClass_self [SMulCommClass R S S] : SMulCommClass R S[M] S[M] where smul_comm t a b := by - ext - -- Porting note: `refine` & `rw` are required because `simp` behaves differently. - classical - simp only [smul_eq_mul, mul_apply] - rw [coe_smul] - refine Eq.symm (Eq.trans (congr_arg (sum a) - (funext₂ fun a₁ b₁ => sum_smul_index' (g := b) (b := t) ?_)) ?_) <;> - simp only [mul_apply, Finsupp.sum, Finset.smul_sum, smul_ite, mul_smul_comm, - imp_true_iff, ite_eq_right_iff, Pi.smul_apply, mul_zero, smul_zero] - -@[to_additive (dont_translate := R k) smulCommClass_symm_self] -instance smulCommClass_symm_self [SMulCommClass k R k] : SMulCommClass k[G] R k[G] := - have := SMulCommClass.symm k R k; .symm .. + classical ext; simp [coeff_mul, sum_smul_index', Finsupp.smul_sum, mul_smul_comm] + +@[to_additive (dont_translate := R S) smulCommClass_symm_self] +instance smulCommClass_symm_self [SMulCommClass S R S] : SMulCommClass S[M] R S[M] := + have := SMulCommClass.symm S R S; .symm .. end NonUnitalNonAssocAlgebra section Submodule -variable [CommSemiring k] [Monoid G] +variable [CommSemiring S] [Monoid M] variable {V : Type*} [AddCommMonoid V] -variable [Module k V] [Module k[G] V] [IsScalarTower k k[G] V] +variable [Module S V] [Module S[M] V] [IsScalarTower S S[M] V] -set_option backward.isDefEq.respectTransparency false in -/-- A submodule over `k` which is stable under scalar multiplication by elements of `G` is a -submodule over `k[G]` -/ -def submoduleOfSMulMem (W : Submodule k V) (h : ∀ (g : G) (v : V), v ∈ W → of k G g • v ∈ W) : - Submodule k[G] V where +/-- A submodule over `S` which is stable under scalar multiplication by elements of `M` is a +submodule over `S[M]` -/ +def submoduleOfSMulMem (W : Submodule S V) (h : ∀ (g : M) (v : V), v ∈ W → of S M g • v ∈ W) : + Submodule S[M] V where carrier := W zero_mem' := W.zero_mem' add_mem' := W.add_mem' - smul_mem' := by - intro f v hv - rw [← Finsupp.sum_single f, Finsupp.sum, Finset.sum_smul] + smul_mem' f v hv := by + rw [← f.sum_coeff_single, Finsupp.sum, Finset.sum_smul] simp_rw [← smul_of, smul_assoc] exact Submodule.sum_smul_mem W _ fun g _ => h g v hv @@ -275,16 +326,13 @@ end MonoidAlgebra /-! ### Additive monoids -/ namespace AddMonoidAlgebra - -variable {k G} - section Semiring variable [Semiring R] [Semiring S] /-- The image of an element `m : M` in `R[M]` belongs the submodule generated by `s : Set M` if and only if `m ∈ s`. -/ lemma of'_mem_span [Nontrivial R] {m : M} {s : Set M} : - of' R M m ∈ Submodule.span R (of' R M '' s) ↔ m ∈ s := single_mem_span_single _ + of' R M m ∈ Submodule.span R (of' R M '' s) ↔ m ∈ s := single_mem_span_single set_option backward.isDefEq.respectTransparency false in /-- If the image of an element `m : M` in `R[M]` belongs the submodule generated by @@ -305,8 +353,7 @@ lemma liftNC_smul [AddZeroClass M] (f : S →+* R) (g : Multiplicative M →* R) suffices (liftNC (↑f) g).comp (smulAddHom S S[M] c) = (AddMonoidHom.mulLeft (f c)).comp (liftNC f g) from DFunLike.congr_fun this φ ext - simp_rw [AddMonoidHom.comp_apply, singleAddHom_apply, smulAddHom_apply, - AddMonoidHom.coe_mulLeft, smul_single', liftNC_single, AddMonoidHom.coe_coe, map_mul, mul_assoc] + simp [mul_assoc] end Semiring end AddMonoidAlgebra diff --git a/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean b/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean index 992b5313c14df6..bb6018557c6049 100644 --- a/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean +++ b/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean @@ -67,14 +67,14 @@ namespace MonoidAlgebra /-- The coefficient of a monomial in a product `f * g` that can be reached in at most one way as a product of monomials in the supports of `f` and `g` is a product. -/ -@[to_additive (dont_translate := R) mul_apply_add_eq_mul_of_uniqueAdd +@[to_additive (dont_translate := R) coeff_mul_add_of_uniqueAdd /-- The coefficient of a monomial in a product `f * g` that can be reached in at most one way as a product of monomials in the supports of `f` and `g` is a product. -/] -theorem mul_apply_mul_eq_mul_of_uniqueMul [Mul A] {f g : R[A]} {a0 b0 : A} - (h : UniqueMul f.support g.support a0 b0) : - (f * g) (a0 * b0) = f a0 * g b0 := by +theorem coeff_mul_mul_of_uniqueMul [Mul A] {f g : R[A]} {a0 b0 : A} + (h : UniqueMul f.coeff.support g.coeff.support a0 b0) : + (f * g).coeff (a0 * b0) = f.coeff a0 * g.coeff b0 := by classical - simp_rw [mul_apply, sum, ← Finset.sum_product'] + simp_rw [coeff_mul, sum, ← Finset.sum_product'] refine (Finset.sum_eq_single (a0, b0) ?_ ?_).trans (if_pos rfl) <;> simp_rw [Finset.mem_product] · refine fun ab hab hne ↦ if_neg (fun he ↦ hne <| Prod.ext ?_ ?_) exacts [(h hab.1 hab.2 he).1, (h hab.1 hab.2 he).2] @@ -83,36 +83,39 @@ theorem mul_apply_mul_eq_mul_of_uniqueMul [Mul A] {f g : R[A]} {a0 b0 : A} · rw [notMem_support_iff.mp af, zero_mul] · rw [notMem_support_iff.mp bg, mul_zero] +@[deprecated (since := "2026-06-18")] +alias mul_apply_mul_eq_mul_of_uniqueMul := coeff_mul_mul_of_uniqueMul + @[to_additive (dont_translate := R)] instance [NoZeroDivisors R] [Mul A] [UniqueProds A] : NoZeroDivisors R[A] where - eq_zero_or_eq_zero_of_mul_eq_zero {a b} ab := by - contrapose! ab - obtain ⟨da, a0, db, b0, h⟩ := UniqueProds.uniqueMul_of_nonempty - (support_nonempty_iff.mpr ab.1) (support_nonempty_iff.mpr ab.2) - refine support_nonempty_iff.mp ⟨da * db, ?_⟩ + eq_zero_or_eq_zero_of_mul_eq_zero {a b} hab := by + contrapose! hab + simp only [ne_eq, ← coeff_eq_zero, ← support_nonempty_iff] at hab ⊢ + obtain ⟨da, a0, db, b0, h⟩ := UniqueProds.uniqueMul_of_nonempty hab.1 hab.2 + refine ⟨da * db, ?_⟩ rw [mem_support_iff] at a0 b0 ⊢ - exact mul_apply_mul_eq_mul_of_uniqueMul h ▸ mul_ne_zero a0 b0 + exact coeff_mul_mul_of_uniqueMul h ▸ mul_ne_zero a0 b0 -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance [IsCancelAdd R] [IsLeftCancelMulZero R] [Mul A] [UniqueProds A] : IsLeftCancelMulZero R[A] where mul_left_cancel_of_ne_zero {f} hf {g₁ g₂} eq := by classical - induction hg : g₁.support ∪ g₂.support using Finset.eraseInduction generalizing g₁ g₂ with + induction hg : g₁.coeff.support ∪ g₂.coeff.support + using Finset.eraseInduction generalizing g₁ g₂ with | _ s ih => obtain h | h := s.eq_empty_or_nonempty <;> subst s - · simp_rw [Finset.union_eq_empty, support_eq_empty] at h; exact h.1.trans h.2.symm - obtain ⟨af, haf, ag, hag, uniq⟩ := - UniqueProds.uniqueMul_of_nonempty (support_nonempty_iff.2 hf) h - have h := mul_apply_mul_eq_mul_of_uniqueMul (uniq.mono subset_rfl Finset.subset_union_left) + · simp_all + simp only [ne_eq, ← coeff_eq_zero, ← support_nonempty_iff] at hf + obtain ⟨af, haf, ag, hag, uniq⟩ := UniqueProds.uniqueMul_of_nonempty hf h + have h := coeff_mul_mul_of_uniqueMul (uniq.mono subset_rfl Finset.subset_union_left) dsimp only at eq - rw [eq, mul_apply_mul_eq_mul_of_uniqueMul (uniq.mono subset_rfl Finset.subset_union_right)] at h + rw [eq, coeff_mul_mul_of_uniqueMul (uniq.mono subset_rfl Finset.subset_union_right)] at h have := mul_left_cancel₀ (mem_support_iff.mp haf) h rw [← g₁.erase_add_single ag, ← g₂.erase_add_single ag, this] at eq ⊢ simp_rw [mul_add, add_right_cancel_iff] at eq rw [ih ag hag eq] - simp_rw [support_erase, Finset.erase_union_distrib] + simp [Finset.erase_union_distrib] @[to_additive (dont_translate := R)] instance [IsCancelAdd R] [IsRightCancelMulZero R] [Mul A] [UniqueProds A] : diff --git a/Mathlib/Algebra/MonoidAlgebra/Opposite.lean b/Mathlib/Algebra/MonoidAlgebra/Opposite.lean index 5c826fc000da3c..fe4e061979df4d 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Opposite.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Opposite.lean @@ -5,7 +5,7 @@ Authors: Johannes Hölzl, Yury Kudryashov, Kim Morrison -/ module -public import Mathlib.Algebra.MonoidAlgebra.Defs +public import Mathlib.Algebra.MonoidAlgebra.MapDomain public import Mathlib.Algebra.Ring.Opposite public import Mathlib.Data.Finsupp.Basic @@ -23,40 +23,27 @@ variable {R M : Type*} [Semiring R] [Mul M] namespace MonoidAlgebra -set_option backward.isDefEq.respectTransparency false in /-- The opposite of a monoid algebra is equivalent as a ring to the opposite monoid algebra over the opposite ring. -/ @[to_additive (dont_translate := R) (attr := simps! +simpRhs apply symm_apply) /-- The opposite of a monoid algebra is equivalent as a ring to the opposite monoid algebra over the opposite ring. -/] protected noncomputable def opRingEquiv : R[M]ᵐᵒᵖ ≃+* Rᵐᵒᵖ[Mᵐᵒᵖ] where - __ := opAddEquiv.symm.trans <| - (Finsupp.mapRange.addEquiv (opAddEquiv : R ≃+ Rᵐᵒᵖ)).trans <| Finsupp.domCongr opEquiv + toAddEquiv := + opAddEquiv.symm.trans <| (mapDomainAddEquiv _ opEquiv).trans <| mapAddEquiv _ opAddEquiv map_mul' := by - -- This used to be `rw`, but we need `erw` after https://github.com/leanprover/lean4/pull/2644 - rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]; erw [AddEquiv.coe_toEquiv] - rw [← AddEquiv.coe_toAddMonoidHom] - refine (AddMonoidHom.map_mul_iff (R := R[M]ᵐᵒᵖ) (S := Rᵐᵒᵖ[Mᵐᵒᵖ]) _).mpr ?_ - ext - -- Porting note: `reducible` cannot be `local` so proof gets long. - simp only [AddMonoidHom.coe_comp, Function.comp_apply, singleAddHom_apply, - AddMonoidHom.compr₂_apply, AddMonoidHom.coe_mul, AddMonoidHom.coe_mulLeft, - AddMonoidHom.compl₂_apply, AddEquiv.toAddMonoidHom_eq_coe, - AddEquiv.coe_addMonoidHom_trans] - -- This used to be `rw`, but we need `erw` after https://github.com/leanprover/lean4/pull/2644 - erw [AddEquiv.trans_apply, AddEquiv.trans_apply, AddEquiv.trans_apply, - MulOpposite.opAddEquiv_symm_apply] - rw [MulOpposite.unop_mul (α := R[M])] - simp - -set_option backward.isDefEq.respectTransparency false in + classical + simp [coeff_mul, MonoidAlgebra.ext_iff, Finsupp.ext_iff, ← MulOpposite.unop_inj, + unop_finsuppSum, sum_mapRange_index, apply_ite unop, mapAddEquiv] + simpa using fun _ _ _ ↦ Finsupp.sum_comm .. + @[to_additive (dont_translate := R)] lemma opRingEquiv_single (r : R) (x : M) : - MonoidAlgebra.opRingEquiv (op (single x r)) = single (op x) (op r) := by simp + MonoidAlgebra.opRingEquiv (op (single x r)) = single (op x) (op r) := by ext; simp -set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] lemma opRingEquiv_symm_single (r : Rᵐᵒᵖ) (x : Mᵐᵒᵖ) : - MonoidAlgebra.opRingEquiv.symm (single x r) = op (single x.unop r.unop) := by simp + MonoidAlgebra.opRingEquiv.symm (single x r) = op (single x.unop r.unop) := by + apply MulOpposite.unop_injective; ext; simp end MonoidAlgebra diff --git a/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean b/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean index ca705f9ea50a82..a3c2846537cd6e 100644 --- a/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean +++ b/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean @@ -29,8 +29,8 @@ namespace MonoidAlgebra theorem mem_smulAntidiagonal_of_group [Group G] [MulAction G P] [Semiring R] [Zero V] (f : R[G]) (x : P → V) (p : P) (gh : G × P) : gh ∈ Finset.SMulAntidiagonal p - (Set.SMulAntidiagonal.finite_of_finite_fst f.support.finite_toSet x.support p) ↔ - f gh.1 ≠ 0 ∧ x gh.2 ≠ 0 ∧ gh.2 = gh.1⁻¹ • p := by + (Set.SMulAntidiagonal.finite_of_finite_fst f.coeff.support.finite_toSet x.support p) ↔ + f.coeff gh.1 ≠ 0 ∧ x gh.2 ≠ 0 ∧ gh.2 = gh.1⁻¹ • p := by rw [Finset.mem_smulAntidiagonal, eq_inv_smul_iff, Function.mem_support, Finset.mem_coe, Finsupp.mem_support_iff] @@ -42,29 +42,31 @@ scoped instance [SMul G P] [IsLeftCancelSMul G P] [Semiring R] [AddCommMonoid V] [SMulWithZero R V] : SMul (R[G]) (P → V) where smul f x p := ∑ gh ∈ Finset.SMulAntidiagonal p - (Set.SMulAntidiagonal.finite_of_finite_fst f.support.finite_toSet x.support p), f gh.1 • x gh.2 + (Set.SMulAntidiagonal.finite_of_finite_fst f.coeff.support.finite_toSet x.support p), + f.coeff gh.1 • x gh.2 @[to_additive (dont_translate := R) smul_eq] theorem smul_eq [SMul G P] [IsLeftCancelSMul G P] [Semiring R] [AddCommMonoid V] [SMulWithZero R V] (f : R[G]) (x : P → V) (p : P) - (hp : ((f.support : Set G).smulAntidiagonal (Function.support x) p).Finite := - Set.SMulAntidiagonal.finite_of_finite_fst f.support.finite_toSet x.support p) : - (f • x) p = ∑ gh ∈ Finset.SMulAntidiagonal p hp, f gh.1 • x gh.2 := + (hp : ((f.coeff.support : Set G).smulAntidiagonal (Function.support x) p).Finite := + Set.SMulAntidiagonal.finite_of_finite_fst f.coeff.support.finite_toSet x.support p) : + (f • x) p = ∑ gh ∈ Finset.SMulAntidiagonal p hp, f.coeff gh.1 • x gh.2 := rfl @[to_additive (dont_translate := R) smul_apply_addAction] theorem smul_apply_mulAction [Group G] [MulAction G P] [Semiring R] [AddCommMonoid V] [SMulWithZero R V] (f : MonoidAlgebra R G) (x : P → V) (p : P) : - (f • x) p = ∑ i ∈ f.support, (f i) • x (i⁻¹ • p) := by - have hp : ((f.support : Set G).smulAntidiagonal (Function.support x) p).Finite := - Set.SMulAntidiagonal.finite_of_finite_fst f.support.finite_toSet x.support p + (f • x) p = ∑ i ∈ f.coeff.support, (f.coeff i) • x (i⁻¹ • p) := by + have hp : ((f.coeff.support : Set G).smulAntidiagonal (Function.support x) p).Finite := + Set.SMulAntidiagonal.finite_of_finite_fst f.coeff.support.finite_toSet x.support p set s : Set (G × P) := ↑(Finset.SMulAntidiagonal p hp) have h₁ : s.InjOn Prod.fst := fun _ h₁ _ h₂ h ↦ by rw [Finset.mem_coe, mem_smulAntidiagonal_of_group] at h₁ h₂ aesop - have h₂ : s.MapsTo Prod.fst ↑f.support := fun g hg ↦ by aesop - have h₃ (g : G) (hg : g ∈ f.support) (hgn : g ∉ Prod.fst '' s) : f g • x (g⁻¹ • p) = 0 := by - obtain (h | h) : f g = 0 ∨ ∀ q, ¬ x q = 0 → ¬g • q = p := by aesop + have h₂ : s.MapsTo Prod.fst ↑f.coeff.support := fun g hg ↦ by aesop + have h₃ (g : G) (hg : g ∈ f.coeff.support) (hgn : g ∉ Prod.fst '' s) : + f.coeff g • x (g⁻¹ • p) = 0 := by + obtain (h | h) : f.coeff g = 0 ∨ ∀ q, ¬ x q = 0 → ¬g • q = p := by aesop · simp [h] · have := h (g⁻¹ • p) aesop diff --git a/Mathlib/Algebra/MonoidAlgebra/Support.lean b/Mathlib/Algebra/MonoidAlgebra/Support.lean index 5d4bd9aa4163d4..ed19081cfeeaec 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Support.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Support.lean @@ -10,6 +10,8 @@ public import Mathlib.Algebra.MonoidAlgebra.Module public import Mathlib.LinearAlgebra.Finsupp.Supported public import Mathlib.Algebra.Group.Pointwise.Finset.Basic +import Mathlib.LinearAlgebra.Span.Basic + /-! # Lemmas about the support of a finitely supported function -/ @@ -29,79 +31,89 @@ variable {k : Type u₁} {G : Type u₂} [Semiring k] section Mul variable [Mul G] -@[to_additive (dont_translate := k) support_mul] -theorem support_mul [DecidableEq G] (a b : k[G]) : (a * b).support ⊆ a.support * b.support := by - rw [MonoidAlgebra.mul_def] - exact support_sum.trans <| biUnion_subset.2 fun _x hx ↦ - support_sum.trans <| biUnion_subset.2 fun _y hy ↦ - support_single_subset.trans <| singleton_subset_iff.2 <| mem_image₂_of_mem hx hy - -@[to_additive (dont_translate := k) support_single_mul_subset] -lemma support_single_mul_subset [DecidableEq G] (f : k[G]) (r : k) (a : G) : - (single a r * f : k[G]).support ⊆ Finset.image (a * ·) f.support := - (support_mul _ _).trans <| (Finset.image₂_subset_right support_single_subset).trans <| by - rw [Finset.image₂_singleton_left] - -@[to_additive (dont_translate := k) support_mul_single_subset] -theorem support_mul_single_subset [DecidableEq G] (f : k[G]) (r : k) (a : G) : - (f * single a r).support ⊆ Finset.image (· * a) f.support := - (support_mul _ _).trans <| (Finset.image₂_subset_left support_single_subset).trans <| by - rw [Finset.image₂_singleton_right] - -@[to_additive (dont_translate := k) support_single_mul_eq_image] -theorem support_single_mul_eq_image [DecidableEq G] (f : k[G]) {r : k} +@[to_additive (dont_translate := k) support_coeff_mul_subset] +theorem support_coeff_mul_subset [DecidableEq G] (x y : k[G]) : + (x * y).coeff.support ⊆ x.coeff.support * y.coeff.support := by + simp only [MonoidAlgebra.mul_def, coeff_finsuppSum] + grw [Finsupp.support_sum, biUnion_subset] + rintro x hx + grw [Finsupp.support_sum, biUnion_subset] + exact fun y hy ↦ support_single_subset.trans <| singleton_subset_iff.2 <| mem_image₂_of_mem hx hy + +@[deprecated (since := "2026-06-18")] alias support_single_mul_eq_image := support_coeff_mul_subset + +@[to_additive (dont_translate := k) support_coeff_single_mul_subset] +lemma support_coeff_single_mul_subset [DecidableEq G] (x : k[G]) (r : k) (a : G) : + (single a r * x).coeff.support ⊆ x.coeff.support.image (a * ·) := by + grw [support_coeff_mul_subset, coeff_single, support_single_subset] + change image₂ _ _ _ ⊆ _ + rw [image₂_singleton_left] + +@[to_additive (dont_translate := k) support_coeff_mul_single_subset] +theorem support_coeff_mul_single_subset [DecidableEq G] (x : k[G]) (r : k) (a : G) : + (x * single a r).coeff.support ⊆ x.coeff.support.image (· * a) := by + grw [support_coeff_mul_subset, coeff_single, support_single_subset] + change image₂ _ _ _ ⊆ _ + rw [image₂_singleton_right] + +@[to_additive (dont_translate := k) support_coeff_single_mul_eq_image] +theorem support_coeff_single_mul_eq_image [DecidableEq G] (f : k[G]) {r : k} (hr : ∀ y, r * y = 0 ↔ y = 0) {x : G} (lx : IsLeftRegular x) : - (single x r * f : k[G]).support = Finset.image (x * ·) f.support := by - refine subset_antisymm (support_single_mul_subset f _ _) fun y hy => ?_ - obtain ⟨y, yf, rfl⟩ : ∃ a : G, a ∈ f.support ∧ x * a = y := by grind - simp [mul_apply, mem_support_iff.mp yf, hr, lx.eq_iff] + (single x r * f).coeff.support = f.coeff.support.image (x * ·) := by + refine subset_antisymm (support_coeff_single_mul_subset f _ _) fun y hy => ?_ + obtain ⟨y, yf, rfl⟩ : ∃ a ∈ f.coeff.support, x * a = y := by grind + simp [coeff_mul, mem_support_iff.mp yf, hr, lx.eq_iff] -@[to_additive (dont_translate := k) support_mul_single_eq_image] -theorem support_mul_single_eq_image [DecidableEq G] (f : k[G]) {r : k} +@[to_additive (dont_translate := k) support_coeff_mul_single_eq_image] +theorem support_coeff_mul_single_eq_image [DecidableEq G] (f : k[G]) {r : k} (hr : ∀ y, y * r = 0 ↔ y = 0) {x : G} (rx : IsRightRegular x) : - (f * single x r).support = Finset.image (· * x) f.support := by - refine subset_antisymm (support_mul_single_subset f _ _) fun y hy => ?_ - obtain ⟨y, yf, rfl⟩ : ∃ a : G, a ∈ f.support ∧ a * x = y := by grind - simp only [mul_apply, mem_support_iff.mp yf, hr, mem_support_iff, sum_single_index, - Finsupp.sum_ite_eq', Ne, not_false_iff, if_true, mul_zero, ite_self, rx.eq_iff] - -@[to_additive (dont_translate := k) support_mul_single] -theorem support_mul_single [IsRightCancelMul G] (f : k[G]) (r : k) + (f * single x r).coeff.support = Finset.image (· * x) f.coeff.support := by + refine subset_antisymm (support_coeff_mul_single_subset f _ _) fun y hy => ?_ + obtain ⟨y, yf, rfl⟩ : ∃ a : G, a ∈ f.coeff.support ∧ a * x = y := by grind + simp [coeff_mul, mem_support_iff.mp yf, hr, rx.eq_iff] + +@[deprecated (since := "2026-06-18")] +alias support_mul_single_eq_image := support_coeff_mul_single_eq_image + +@[to_additive (dont_translate := k) support_coeff_mul_single] +theorem support_coeff_mul_single [IsRightCancelMul G] (f : k[G]) (r : k) (hr : ∀ y, y * r = 0 ↔ y = 0) (x : G) : - (f * single x r).support = f.support.map (mulRightEmbedding x) := by - classical - ext - simp only [support_mul_single_eq_image f hr (IsRightRegular.all x), - mem_image, mem_map, mulRightEmbedding_apply] - -@[to_additive (dont_translate := k) support_single_mul] -theorem support_single_mul [IsLeftCancelMul G] (f : k[G]) (r : k) + (f * single x r).coeff.support = f.coeff.support.map (mulRightEmbedding x) := by + classical ext; simp [support_coeff_mul_single_eq_image f hr (.all x)] + +@[deprecated (since := "2026-06-18")] alias support_mul_single := support_coeff_mul_single + +@[to_additive (dont_translate := k) support_coeff_single_mul] +theorem support_coeff_single_mul [IsLeftCancelMul G] (f : k[G]) (r : k) (hr : ∀ y, r * y = 0 ↔ y = 0) (x : G) : - (single x r * f : k[G]).support = f.support.map (mulLeftEmbedding x) := by - classical - ext - simp only [support_single_mul_eq_image f hr (IsLeftRegular.all x), mem_image, - mem_map, mulLeftEmbedding_apply] + (single x r * f : k[G]).coeff.support = + f.coeff.support.map (mulLeftEmbedding x) := by + classical ext; simp [support_coeff_single_mul_eq_image f hr (.all x)] + +@[deprecated (since := "2026-06-18")] alias support_single_mul := support_coeff_single_mul end Mul -@[to_additive (dont_translate := k) support_one_subset] -lemma support_one_subset [One G] : (1 : k[G]).support ⊆ 1 := +@[to_additive (dont_translate := k) support_coeff_one_subset] +lemma support_coeff_one_subset [One G] : (1 : k[G]).coeff.support ⊆ 1 := Finsupp.support_single_subset -@[to_additive (dont_translate := k) (attr := simp) support_one] -lemma support_one [One G] [NeZero (1 : k)] : (1 : k[G]).support = 1 := +@[deprecated (since := "2026-06-18")] alias support_one_subset := support_coeff_one_subset + +@[to_additive (dont_translate := k) (attr := simp) support_coeff_one] +lemma support_coeff_one [One G] [NeZero (1 : k)] : (1 : k[G]).coeff.support = 1 := Finsupp.support_single _ one_ne_zero -section Span +@[deprecated (since := "2026-06-18")] alias support_one := support_coeff_one -variable [MulOneClass G] +section Span -set_option backward.isDefEq.respectTransparency false in /-- An element of `k[G]` is in the subalgebra generated by its support. -/ -theorem mem_span_support (f : k[G]) : f ∈ Submodule.span k (of k G '' (f.support : Set G)) := by - simp only [of, MonoidHom.coe_mk, OneHom.coe_mk] - rw [← Finsupp.supported_eq_span_single, Finsupp.mem_supported] +theorem mem_span_support_coeff [MulOneClass G] (f : k[G]) : + f ∈ Submodule.span k (of k G '' f.coeff.support) := by + simp [of, ← supported_eq_span_single, mem_supported] + +@[deprecated (since := "2026-06-18")] alias mem_span_support := mem_span_support_coeff end Span @@ -115,12 +127,11 @@ variable {k : Type u₁} {G : Type u₂} [Semiring k] section Span -set_option backward.isDefEq.respectTransparency false in /-- An element of `k[G]` is in the submodule generated by its support. -/ -theorem mem_span_support (f : k[G]) : f ∈ Submodule.span k (of' k G '' f.support) := by - simp only [of']; rw [← Finsupp.supported_eq_span_single, Finsupp.mem_supported] +theorem mem_span_support_coeff (f : k[G]) : f ∈ Submodule.span k (of' k G '' f.coeff.support) := by + simp [of', ← supported_eq_span_single, mem_supported] -@[deprecated (since := "2025-12-08")] alias mem_span_support' := mem_span_support +@[deprecated (since := "2026-06-18")] alias mem_span_support := mem_span_support_coeff end Span diff --git a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean index 08b5375879d562..252a0f83ce7af7 100644 --- a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean +++ b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean @@ -67,7 +67,7 @@ section Defs /-- Interpret an `AddMonoidAlgebra` as a homogeneous `DirectSum`. -/ def AddMonoidAlgebra.toDirectSum [Semiring M] (f : AddMonoidAlgebra M ι) : ⨁ _ : ι, M := - Finsupp.toDFinsupp f + f.coeff.toDFinsupp section @@ -80,18 +80,16 @@ lemma AddMonoidAlgebra.toDirectSum_single (i : ι) (m : M) : toDirectSum (single variable [∀ m : M, Decidable (m ≠ 0)] /-- Interpret a homogeneous `DirectSum` as an `AddMonoidAlgebra`. -/ -def DirectSum.toAddMonoidAlgebra (f : ⨁ _ : ι, M) : AddMonoidAlgebra M ι := - DFinsupp.toFinsupp f +def DirectSum.toAddMonoidAlgebra (f : ⨁ _ : ι, M) : AddMonoidAlgebra M ι := .ofCoeff f.toFinsupp @[simp] theorem DirectSum.toAddMonoidAlgebra_of (i : ι) (m : M) : - (DirectSum.of _ i m : ⨁ _ : ι, M).toAddMonoidAlgebra = .single i m := - DFinsupp.toFinsupp_single i m + (DirectSum.of _ i m : ⨁ _ : ι, M).toAddMonoidAlgebra = .single i m := by + ext : 1; exact DFinsupp.toFinsupp_single i m @[simp] theorem AddMonoidAlgebra.toDirectSum_toAddMonoidAlgebra (f : AddMonoidAlgebra M ι) : - f.toDirectSum.toAddMonoidAlgebra = f := - Finsupp.toDFinsupp_toFinsupp f + f.toDirectSum.toAddMonoidAlgebra = f := by ext : 1; exact Finsupp.toDFinsupp_toFinsupp _ @[simp] theorem DirectSum.toAddMonoidAlgebra_toDirectSum (f : ⨁ _ : ι, M) : @@ -167,46 +165,46 @@ namespace DirectSum variable [DecidableEq ι] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toAddMonoidAlgebra_zero [Semiring M] [∀ m : M, Decidable (m ≠ 0)] : - toAddMonoidAlgebra 0 = (0 : AddMonoidAlgebra M ι) := - DFinsupp.toFinsupp_zero + toAddMonoidAlgebra 0 = (0 : AddMonoidAlgebra M ι) := by simp [toAddMonoidAlgebra] @[simp] theorem toAddMonoidAlgebra_add [Semiring M] [∀ m : M, Decidable (m ≠ 0)] (f g : ⨁ _ : ι, M) : - (f + g).toAddMonoidAlgebra = toAddMonoidAlgebra f + toAddMonoidAlgebra g := - DFinsupp.toFinsupp_add _ _ + (f + g).toAddMonoidAlgebra = toAddMonoidAlgebra f + toAddMonoidAlgebra g := by + ext; simp [toAddMonoidAlgebra] @[simp] theorem toAddMonoidAlgebra_natCast [AddMonoid ι] [Semiring M] [∀ m : M, Decidable (m ≠ 0)] (n : ℕ) : - (n : ⨁ _ : ι, M).toAddMonoidAlgebra = n := - DFinsupp.toFinsupp_single _ _ + (n : ⨁ _ : ι, M).toAddMonoidAlgebra = n := by + ext : 1; exact DFinsupp.toFinsupp_single .. @[simp] theorem toAddMonoidAlgebra_ofNat [AddMonoid ι] [Semiring M] [∀ m : M, Decidable (m ≠ 0)] (n : ℕ) [n.AtLeastTwo] : (ofNat(n) : ⨁ _ : ι, M).toAddMonoidAlgebra = ofNat(n) := - DFinsupp.toFinsupp_single _ _ + toAddMonoidAlgebra_natCast _ @[simp] theorem toAddMonoidAlgebra_sub [Ring M] [∀ m : M, Decidable (m ≠ 0)] (f g : ⨁ _ : ι, M) : - (f - g).toAddMonoidAlgebra = toAddMonoidAlgebra f - toAddMonoidAlgebra g := - DFinsupp.toFinsupp_sub _ _ + (f - g).toAddMonoidAlgebra = toAddMonoidAlgebra f - toAddMonoidAlgebra g := by + ext : 1; exact DFinsupp.toFinsupp_sub .. @[simp] theorem toAddMonoidAlgebra_neg [Ring M] [∀ m : M, Decidable (m ≠ 0)] (f : ⨁ _ : ι, M) : - (-f).toAddMonoidAlgebra = - toAddMonoidAlgebra f := - DFinsupp.toFinsupp_neg _ + (-f).toAddMonoidAlgebra = -toAddMonoidAlgebra f := by + ext : 1; exact DFinsupp.toFinsupp_neg .. @[simp] theorem toAddMonoidAlgebra_intCast [AddMonoid ι] [Ring M] [∀ m : M, Decidable (m ≠ 0)] (z : ℤ) : - (z : ⨁ _ : ι, M).toAddMonoidAlgebra = z := - DFinsupp.toFinsupp_single _ _ + (z : ⨁ _ : ι, M).toAddMonoidAlgebra = z := by + ext : 1; exact DFinsupp.toFinsupp_single .. @[simp] theorem toAddMonoidAlgebra_one [Zero ι] [Semiring M] [∀ m : M, Decidable (m ≠ 0)] : - (1 : ⨁ _ : ι, M).toAddMonoidAlgebra = 1 := - DFinsupp.toFinsupp_single _ _ + (1 : ⨁ _ : ι, M).toAddMonoidAlgebra = 1 := by + ext : 1; exact DFinsupp.toFinsupp_single .. @[simp] theorem toAddMonoidAlgebra_mul [AddMonoid ι] [Semiring M] @@ -230,19 +228,16 @@ section Equivs equiv. -/ @[simps -fullyApplied] def addMonoidAlgebraEquivDirectSum [DecidableEq ι] [Semiring M] [∀ m : M, Decidable (m ≠ 0)] : - AddMonoidAlgebra M ι ≃ ⨁ _ : ι, M := - { finsuppEquivDFinsupp with - toFun := AddMonoidAlgebra.toDirectSum - invFun := DirectSum.toAddMonoidAlgebra } + AddMonoidAlgebra M ι ≃ ⨁ _ : ι, M where + toFun := AddMonoidAlgebra.toDirectSum + invFun := DirectSum.toAddMonoidAlgebra /-- The additive version of `AddMonoidAlgebra.addMonoidAlgebraEquivDirectSum`. -/ -@[simps -fullyApplied] +@[simps! -fullyApplied] def addMonoidAlgebraAddEquivDirectSum [DecidableEq ι] [Semiring M] [∀ m : M, Decidable (m ≠ 0)] : - AddMonoidAlgebra M ι ≃+ ⨁ _ : ι, M := - { addMonoidAlgebraEquivDirectSum with - toFun := AddMonoidAlgebra.toDirectSum - invFun := DirectSum.toAddMonoidAlgebra - map_add' := AddMonoidAlgebra.toDirectSum_add } + AddMonoidAlgebra M ι ≃+ ⨁ _ : ι, M where + toEquiv := addMonoidAlgebraEquivDirectSum + map_add' := AddMonoidAlgebra.toDirectSum_add /-- The ring version of `AddMonoidAlgebra.addMonoidAlgebraEquivDirectSum`. -/ @[simps -fullyApplied] diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 8c0bd485a58ea7..97279e5d9331ea 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -95,10 +95,10 @@ def monomial (s : σ →₀ ℕ) : R →ₗ[R] MvPolynomial σ R := theorem one_def : (1 : MvPolynomial σ R) = monomial 0 1 := rfl -theorem single_eq_monomial (s : σ →₀ ℕ) (a : R) : Finsupp.single s a = monomial s a := +theorem single_eq_monomial (s : σ →₀ ℕ) (a : R) : .single s a = monomial s a := rfl -theorem mul_def : p * q = p.sum fun m a => q.sum fun n b => monomial (m + n) (a * b) := +theorem mul_def : p * q = p.coeff.sum fun m a => q.coeff.sum fun n b => monomial (m + n) (a * b) := AddMonoidAlgebra.mul_def .. /-- `C a` is the constant polynomial with value `a` -/ @@ -128,12 +128,12 @@ def X (n : σ) : MvPolynomial σ R := theorem monomial_left_injective {r : R} (hr : r ≠ 0) : Function.Injective fun s : σ →₀ ℕ => monomial s r := - Finsupp.single_left_injective hr + single_left_injective hr @[simp] theorem monomial_left_inj {s t : σ →₀ ℕ} {r : R} (hr : r ≠ 0) : monomial s r = monomial t r ↔ s = t := - Finsupp.single_left_inj hr + single_left_inj hr theorem C_apply : (C a : MvPolynomial σ R) = monomial 0 a := rfl @@ -151,8 +151,7 @@ theorem C_mul_monomial : C a * monomial s a' = monomial s (a * a') := by exact this @[simp] -theorem C_add : (C (a + a') : MvPolynomial σ R) = C a + C a' := - Finsupp.single_add _ _ _ +theorem C_add : (C (a + a') : MvPolynomial σ R) = C a + C a' := by simp @[simp] theorem C_mul : (C (a * a') : MvPolynomial σ R) = C a * C a' := @@ -165,14 +164,12 @@ theorem C_pow (a : R) (n : ℕ) : (C (a ^ n) : MvPolynomial σ R) = C a ^ n := @[grind inj] theorem C_injective (σ : Type*) (R : Type*) [CommSemiring R] : Function.Injective (C : R → MvPolynomial σ R) := - Finsupp.single_injective _ + single_right_injective +set_option backward.isDefEq.respectTransparency false in theorem C_surjective {R : Type*} [CommSemiring R] (σ : Type*) [IsEmpty σ] : - Function.Surjective (C : R → MvPolynomial σ R) := by - refine fun p => ⟨p.toFun 0, Finsupp.ext fun a => ?_⟩ - simp only [C_apply, ← single_eq_monomial, (Finsupp.ext isEmptyElim (α := σ) : a = 0), - single_eq_same] - rfl + Function.Surjective (C : R → MvPolynomial σ R) := + fun p ↦ ⟨p.coeff 0, by apply AddMonoidAlgebra.ext; ext; simp [C_apply, ← single_eq_monomial]⟩ @[simp] theorem C_inj {σ : Type*} (R : Type*) [CommSemiring R] (r s : R) : @@ -219,8 +216,7 @@ theorem C_eq_smul_one : (C a : MvPolynomial σ R) = a • (1 : MvPolynomial σ R rw [← C_mul', mul_one] theorem smul_monomial {S₁ : Type*} [SMulZeroClass S₁ R] (r : S₁) : - r • monomial s a = monomial s (r • a) := - Finsupp.smul_single _ _ _ + r • monomial s a = monomial s (r • a) := smul_single _ _ _ theorem X_injective [Nontrivial R] : Function.Injective (X : σ → MvPolynomial σ R) := (monomial_left_injective one_ne_zero).comp (Finsupp.single_left_injective one_ne_zero) @@ -266,31 +262,30 @@ theorem C_mul_X_eq_monomial {s : σ} {a : R} : C a * X s = monomial (Finsupp.sin rw [← C_mul_X_pow_eq_monomial, pow_one] @[simp] -theorem monomial_zero {s : σ →₀ ℕ} : monomial s (0 : R) = 0 := - Finsupp.single_zero _ +theorem monomial_zero {s : σ →₀ ℕ} : monomial s (0 : R) = 0 := single_zero _ @[simp] theorem monomial_zero' : (monomial (0 : σ →₀ ℕ) : R → MvPolynomial σ R) = C := rfl @[simp] -theorem monomial_eq_zero {s : σ →₀ ℕ} {b : R} : monomial s b = 0 ↔ b = 0 := - Finsupp.single_eq_zero +theorem monomial_eq_zero {s : σ →₀ ℕ} {b : R} : monomial s b = 0 ↔ b = 0 := single_eq_zero @[simp] theorem sum_monomial_eq {A : Type*} [AddCommMonoid A] {u : σ →₀ ℕ} {r : R} {b : (σ →₀ ℕ) → R → A} - (w : b u 0 = 0) : sum (monomial u r) b = b u r := + (w : b u 0 = 0) : sum (monomial u r).coeff b = b u r := Finsupp.sum_single_index w @[simp] theorem sum_C {A : Type*} [AddCommMonoid A] {b : (σ →₀ ℕ) → R → A} (w : b 0 0 = 0) : - sum (C a) b = b 0 a := + sum (C a).coeff b = b 0 a := sum_monomial_eq w theorem monomial_sum_one {α : Type*} (s : Finset α) (f : α → σ →₀ ℕ) : (monomial (∑ i ∈ s, f i) 1 : MvPolynomial σ R) = ∏ i ∈ s, monomial (f i) 1 := map_prod (monomialOneHom R σ) (fun i => Multiplicative.ofAdd (f i)) s +set_option backward.isDefEq.respectTransparency false in theorem monomial_sum_index {α : Type*} (s : Finset α) (f : α → σ →₀ ℕ) (a : R) : monomial (∑ i ∈ s, f i) a = C a * ∏ i ∈ s, monomial (f i) 1 := by rw [← monomial_sum_one, C_mul', ← (monomial _).map_smul, smul_eq_mul, mul_one] @@ -304,8 +299,7 @@ theorem monomial_finsupp_sum_index {α β : Type*} [Zero β] (f : α →₀ β) monomial_sum_index _ _ _ theorem monomial_eq_monomial_iff {α : Type*} (a₁ a₂ : α →₀ ℕ) (b₁ b₂ : R) : - monomial a₁ b₁ = monomial a₂ b₂ ↔ a₁ = a₂ ∧ b₁ = b₂ ∨ b₁ = 0 ∧ b₂ = 0 := - Finsupp.single_eq_single_iff _ _ _ _ + monomial a₁ b₁ = monomial a₂ b₂ ↔ a₁ = a₂ ∧ b₁ = b₂ ∨ b₁ = 0 ∧ b₂ = 0 := single_inj theorem monomial_eq : monomial s a = C a * (s.prod fun n e => X n ^ e : MvPolynomial σ R) := by simp only [X_pow_eq_monomial, ← monomial_finsupp_sum_index, Finsupp.sum_single] @@ -346,7 +340,7 @@ and it holds for monomials. -/ theorem induction_on' {P : MvPolynomial σ R → Prop} (p : MvPolynomial σ R) (monomial : ∀ (u : σ →₀ ℕ) (a : R), P (monomial u a)) (add : ∀ p q : MvPolynomial σ R, P p → P q → P (p + q)) : P p := - Finsupp.induction p + induction p (suffices P (MvPolynomial.monomial 0 0) by rwa [monomial_zero] at this show P (MvPolynomial.monomial 0 0) from monomial 0 0) fun _ _ _ _ha _hb hPf => add _ _ (monomial _ _) hPf @@ -361,9 +355,9 @@ theorem monomial_add_induction_on {motive : MvPolynomial σ R → Prop} (p : MvP (C : ∀ a, motive (C a)) (monomial_add : ∀ (a : σ →₀ ℕ) (b : R) (f : MvPolynomial σ R), - a ∉ f.support → b ≠ 0 → motive f → motive ((monomial a b) + f)) : + a ∉ f.coeff.support → b ≠ 0 → motive f → motive (monomial a b + f)) : motive p := - Finsupp.induction p (C_0.rec <| C 0) monomial_add + induction p (C_0.rec <| C 0) monomial_add /-- Similar to `MvPolynomial.induction_on` but only a yet weaker form of `h_add` is required. @@ -375,7 +369,7 @@ theorem induction_on'' {motive : MvPolynomial σ R → Prop} (p : MvPolynomial (C : ∀ a, motive (C a)) (monomial_add : ∀ (a : σ →₀ ℕ) (b : R) (f : MvPolynomial σ R), - a ∉ f.support → b ≠ 0 → motive f → motive (monomial a b) → + a ∉ f.coeff.support → b ≠ 0 → motive f → motive (monomial a b) → motive ((monomial a b) + f)) (mul_X : ∀ (p : MvPolynomial σ R) (n : σ), motive p → motive (p * MvPolynomial.X n)) : motive p := @@ -460,15 +454,15 @@ theorem adjoin_range_X : Algebra.adjoin R (range (X : σ → MvPolynomial σ R)) @[ext] theorem linearMap_ext {M : Type*} [AddCommMonoid M] [Module R M] {f g : MvPolynomial σ R →ₗ[R] M} (h : ∀ s, f ∘ₗ monomial s = g ∘ₗ monomial s) : f = g := - Finsupp.lhom_ext' h + lhom_ext' h section Support /-- The finite set of all `m : σ →₀ ℕ` such that `X^m` has a non-zero coefficient. -/ def support (p : MvPolynomial σ R) : Finset (σ →₀ ℕ) := - Finsupp.support p + p.coeff.support -theorem finsupp_support_eq_support (p : MvPolynomial σ R) : Finsupp.support p = p.support := +theorem finsupp_support_eq_support (p : MvPolynomial σ R) : p.coeff.support = p.support := rfl theorem support_monomial [h : Decidable (a = 0)] : @@ -508,8 +502,8 @@ theorem support_smul {S₁ : Type*} [SMulZeroClass S₁ R] {a : S₁} {f : MvPol Finsupp.support_smul theorem support_sum {α : Type*} [DecidableEq σ] {s : Finset α} {f : α → MvPolynomial σ R} : - (∑ x ∈ s, f x).support ⊆ s.biUnion fun x => (f x).support := - Finsupp.support_finsetSum + (∑ x ∈ s, f x).support ⊆ s.biUnion fun x => (f x).support := by + simpa [support, coeff, MvPolynomial] using Finsupp.support_finsetSum end Support @@ -517,7 +511,7 @@ section Coeff /-- The coefficient of the monomial `m` in the multi-variable polynomial `p`. -/ def coeff (m : σ →₀ ℕ) (p : MvPolynomial σ R) : R := - @DFunLike.coe ((σ →₀ ℕ) →₀ R) _ _ _ p m + @DFunLike.coe ((σ →₀ ℕ) →₀ R) _ _ _ (AddMonoidAlgebra.coeff p) m @[simp, grind =] theorem mem_support_iff {p : MvPolynomial σ R} {m : σ →₀ ℕ} : m ∈ p.support ↔ p.coeff m ≠ 0 := by @@ -527,11 +521,12 @@ theorem notMem_support_iff {p : MvPolynomial σ R} {m : σ →₀ ℕ} : m ∉ p simp theorem sum_def {A} [AddCommMonoid A] {p : MvPolynomial σ R} {b : (σ →₀ ℕ) → R → A} : - p.sum b = ∑ m ∈ p.support, b m (p.coeff m) := by simp [support, Finsupp.sum, coeff] + (AddMonoidAlgebra.coeff p).sum b = ∑ m ∈ p.support, b m (p.coeff m) := by + simp [support, Finsupp.sum, coeff] theorem support_mul [DecidableEq σ] (p q : MvPolynomial σ R) : (p * q).support ⊆ p.support + q.support := - AddMonoidAlgebra.support_mul p q + AddMonoidAlgebra.support_coeff_mul_subset p q lemma disjoint_support_monomial {a : σ →₀ ℕ} {p : MvPolynomial σ R} {s : R} (ha : a ∉ p.support) (hs : s ≠ 0) : Disjoint (monomial a s).support p.support := by @@ -540,16 +535,17 @@ lemma disjoint_support_monomial {a : σ →₀ ℕ} {p : MvPolynomial σ R} {s : @[ext] theorem ext (p q : MvPolynomial σ R) : (∀ m, coeff m p = coeff m q) → p = q := - Finsupp.ext + fun h ↦ AddMonoidAlgebra.ext <| by ext; exact h _ +set_option backward.isDefEq.respectTransparency false in @[simp] -theorem coeff_add (m : σ →₀ ℕ) (p q : MvPolynomial σ R) : coeff m (p + q) = coeff m p + coeff m q := - add_apply p q m +theorem coeff_add (m : σ →₀ ℕ) (p q : MvPolynomial σ R) : + coeff m (p + q) = coeff m p + coeff m q := by simp [coeff, MvPolynomial] @[simp] theorem coeff_smul {S₁ : Type*} [SMulZeroClass S₁ R] (m : σ →₀ ℕ) (C : S₁) (p : MvPolynomial σ R) : coeff m (C • p) = C • coeff m p := - AddMonoidAlgebra.smul_apply C p m + AddMonoidAlgebra.coeff_smul_apply .. @[simp] theorem coeff_zero (m : σ →₀ ℕ) : coeff m (0 : MvPolynomial σ R) = 0 := @@ -651,17 +647,15 @@ theorem coeff_C_mul (m) (a : R) (p : MvPolynomial σ R) : coeff m (C a * p) = a theorem coeff_mul [DecidableEq σ] (p q : MvPolynomial σ R) (n : σ →₀ ℕ) : coeff n (p * q) = ∑ x ∈ Finset.antidiagonal n, coeff x.1 p * coeff x.2 q := - AddMonoidAlgebra.mul_apply_antidiagonal p q _ _ Finset.mem_antidiagonal + AddMonoidAlgebra.coeff_mul_antidiag p q _ _ Finset.mem_antidiagonal @[simp] theorem coeff_mul_monomial (m) (s : σ →₀ ℕ) (r : R) (p : MvPolynomial σ R) : - coeff (m + s) (p * monomial s r) = coeff m p * r := - AddMonoidAlgebra.mul_single_apply_aux fun _a _ => add_left_inj _ + coeff (m + s) (p * monomial s r) = coeff m p * r := coeff_mul_single_add .. @[simp] theorem coeff_monomial_mul (m) (s : σ →₀ ℕ) (r : R) (p : MvPolynomial σ R) : - coeff (s + m) (monomial s r * p) = r * coeff m p := - AddMonoidAlgebra.single_mul_apply_aux fun _a _ => add_right_inj _ + coeff (s + m) (monomial s r * p) = r * coeff m p := coeff_single_mul_add .. @[simp] theorem coeff_mul_X (m) (s : σ) (p : MvPolynomial σ R) : @@ -691,12 +685,12 @@ theorem coeff_prod_X_pow [DecidableEq σ] (d : σ →₀ ℕ) (x : σ → ℕ) ( @[simp] theorem support_mul_X (s : σ) (p : MvPolynomial σ R) : (p * X s).support = p.support.map (addRightEmbedding (Finsupp.single s 1)) := - AddMonoidAlgebra.support_mul_single p _ (by simp) _ + AddMonoidAlgebra.support_coeff_mul_single p _ (by simp) _ @[simp] theorem support_X_mul (s : σ) (p : MvPolynomial σ R) : (X s * p).support = p.support.map (addLeftEmbedding (Finsupp.single s 1)) := - AddMonoidAlgebra.support_single_mul p _ (by simp) _ + AddMonoidAlgebra.support_coeff_single_mul p _ (by simp) _ @[simp] theorem support_smul_eq {S : Type*} [Semiring S] [IsDomain S] [Module S R] @@ -766,9 +760,9 @@ theorem X_ne_zero [Nontrivial R] (s : σ) : use Finsupp.single s 1 simp only [coeff_X_same, ne_eq, one_ne_zero, not_false_eq_true] +set_option backward.isDefEq.respectTransparency false in @[simp] -theorem support_eq_empty {p : MvPolynomial σ R} : p.support = ∅ ↔ p = 0 := - Finsupp.support_eq_empty +theorem support_eq_empty {p : MvPolynomial σ R} : p.support = ∅ ↔ p = 0 := by simp [support] @[simp] lemma support_nonempty {p : MvPolynomial σ R} : p.support.Nonempty ↔ p ≠ 0 := by @@ -965,10 +959,11 @@ end ConstantCoeff section AsSum +set_option backward.isDefEq.respectTransparency false in @[simp] theorem support_sum_monomial_coeff (p : MvPolynomial σ R) : - (∑ v ∈ p.support, monomial v (coeff v p)) = p := - Finsupp.sum_single p + ∑ v ∈ p.support, monomial v (coeff v p) = p := by + apply AddMonoidAlgebra.ext; rw [AddMonoidAlgebra.coeff_sum]; exact Finsupp.sum_single _ theorem as_sum (p : MvPolynomial σ R) : p = ∑ v ∈ p.support, monomial v (coeff v p) := (support_sum_monomial_coeff p).symm @@ -989,7 +984,7 @@ def coeffsIn : Submodule R (MvPolynomial σ S) where carrier := {p | ∀ i, p.coeff i ∈ M} add_mem' := by simp +contextual [add_mem] zero_mem' := by simp - smul_mem' := by simp +contextual [Submodule.smul_mem] + smul_mem' r p hp i := Submodule.smul_mem _ _ (hp i) lemma mem_coeffsIn : p ∈ coeffsIn σ M ↔ ∀ i, p.coeff i ∈ M := .rfl @@ -1055,6 +1050,7 @@ end Module section Algebra variable [Algebra R S] {M : Submodule R S} +set_option backward.isDefEq.respectTransparency false in lemma coeffsIn_mul (M N : Submodule R S) : coeffsIn σ (M * N) = coeffsIn σ M * coeffsIn σ N := by classical refine le_antisymm (coeffsIn_le.2 ?_) ?_ diff --git a/Mathlib/Algebra/MvPolynomial/Cardinal.lean b/Mathlib/Algebra/MvPolynomial/Cardinal.lean index 3a2f04a095ce23..1e3367c7cc6967 100644 --- a/Mathlib/Algebra/MvPolynomial/Cardinal.lean +++ b/Mathlib/Algebra/MvPolynomial/Cardinal.lean @@ -8,7 +8,9 @@ module public import Mathlib.Algebra.MonoidAlgebra.Cardinal public import Mathlib.Algebra.MvPolynomial.Equiv public import Mathlib.Data.Finsupp.Fintype -public import Mathlib.SetTheory.Cardinal.Finsupp +public import Mathlib.SetTheory.Cardinal.Arithmetic + +import Mathlib.Algebra.MonoidAlgebra.Cardinal /-! # Cardinality of Multivariate Polynomial Ring diff --git a/Mathlib/Algebra/MvPolynomial/CommRing.lean b/Mathlib/Algebra/MvPolynomial/CommRing.lean index 03f3ab728abf50..3cee9c465cea2e 100644 --- a/Mathlib/Algebra/MvPolynomial/CommRing.lean +++ b/Mathlib/Algebra/MvPolynomial/CommRing.lean @@ -72,9 +72,7 @@ theorem coeff_neg (m : σ →₀ ℕ) (p : MvPolynomial σ R) : coeff m (-p) = - theorem coeff_sub (m : σ →₀ ℕ) (p q : MvPolynomial σ R) : coeff m (p - q) = coeff m p - coeff m q := Finsupp.sub_apply _ _ _ -@[simp] -theorem support_neg : (-p).support = p.support := - Finsupp.support_neg p +@[simp] lemma support_neg : (-p).support = p.support := by ext; simp theorem support_sub [DecidableEq σ] (p q : MvPolynomial σ R) : (p - q).support ⊆ p.support ∪ q.support := diff --git a/Mathlib/Algebra/MvPolynomial/Degrees.lean b/Mathlib/Algebra/MvPolynomial/Degrees.lean index 7b595c7d04643f..1069e18a3961dc 100644 --- a/Mathlib/Algebra/MvPolynomial/Degrees.lean +++ b/Mathlib/Algebra/MvPolynomial/Degrees.lean @@ -473,7 +473,7 @@ theorem totalDegree_X {R} [CommSemiring R] [Nontrivial R] (s : σ) : theorem totalDegree_add (a b : MvPolynomial σ R) : (a + b).totalDegree ≤ max a.totalDegree b.totalDegree := - sup_support_add_le _ _ _ + sup_support_coeff_add_le _ _ _ theorem totalDegree_add_eq_left_of_totalDegree_lt {p q : MvPolynomial σ R} (h : q.totalDegree < p.totalDegree) : (p + q).totalDegree = p.totalDegree := by @@ -484,8 +484,7 @@ theorem totalDegree_add_eq_left_of_totalDegree_lt {p q : MvPolynomial σ R} by_cases hp : p = 0 · simp [hp] obtain ⟨b, hb₁, hb₂⟩ := - p.support.exists_mem_eq_sup (Finsupp.support_nonempty_iff.mpr hp) fun m : σ →₀ ℕ => - Multiset.card (toMultiset m) + p.support.exists_mem_eq_sup (by simpa) fun m : σ →₀ ℕ => Multiset.card (toMultiset m) have hb : b ∉ q.support := by contrapose! h rw [totalDegree_eq p, hb₂, totalDegree_eq] @@ -503,7 +502,7 @@ theorem totalDegree_add_eq_right_of_totalDegree_lt {p q : MvPolynomial σ R} theorem totalDegree_mul (a b : MvPolynomial σ R) : (a * b).totalDegree ≤ a.totalDegree + b.totalDegree := - sup_support_mul_le (fun _ _ ↦ (Finsupp.sum_add_index' (fun _ => rfl) (fun _ _ _ => rfl)).le) _ _ + sup_support_coeff_mul_le (fun _ _ ↦ by simp [Finsupp.sum_add_index']) _ _ theorem totalDegree_smul_le [CommSemiring S] [DistribMulAction R S] (a : R) (f : MvPolynomial σ S) : (a • f).totalDegree ≤ f.totalDegree := @@ -598,10 +597,8 @@ theorem totalDegree_eq_zero_iff_eq_C {p : MvPolynomial σ R} : theorem totalDegree_rename_le (f : σ → τ) (p : MvPolynomial σ R) : (rename f p).totalDegree ≤ p.totalDegree := - Finset.sup_le fun b => by + Finset.sup_le fun b h => by classical - intro h - rw [rename_eq] at h have h' := Finsupp.mapDomain_support h rw [Finset.mem_image] at h' rcases h' with ⟨s, hs, rfl⟩ @@ -617,6 +614,7 @@ section degreesLE variable {s t : Multiset σ} variable (R σ s) in +set_option backward.isDefEq.respectTransparency false in /-- The submodule of multivariate polynomials of degrees bounded by a monomial `s`. -/ def degreesLE : Submodule R (MvPolynomial σ R) where carrier := {p | p.degrees ≤ s} @@ -631,6 +629,7 @@ def degreesLE : Submodule R (MvPolynomial σ R) where @[simp] lemma mem_degreesLE : p ∈ degreesLE R σ s ↔ p.degrees ≤ s := Iff.rfl variable (s t) in +set_option backward.isDefEq.respectTransparency false in lemma degreesLE_add : degreesLE R σ (s + t) = degreesLE R σ s * degreesLE R σ t := by classical rw [le_antisymm_iff, Submodule.mul_le] @@ -645,6 +644,7 @@ lemma degreesLE_add : degreesLE R σ (s + t) = degreesLE R σ s * degreesLE R σ rw [show monomial i (x.coeff i) = monomial a (x.coeff i) * monomial b 1 by simp [this]] exact Submodule.mul_mem_mul ((degrees_monomial _ _).trans ha) ((degrees_monomial _ _).trans hb) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma degreesLE_zero : degreesLE R σ 0 = 1 := by refine le_antisymm (fun x hx ↦ ?_) (by simp) simp only [mem_degreesLE, nonpos_iff_eq_zero] at hx diff --git a/Mathlib/Algebra/MvPolynomial/Derivation.lean b/Mathlib/Algebra/MvPolynomial/Derivation.lean index 28f0f5d4822d8c..09df9bff71ee13 100644 --- a/Mathlib/Algebra/MvPolynomial/Derivation.lean +++ b/Mathlib/Algebra/MvPolynomial/Derivation.lean @@ -34,9 +34,10 @@ variable (R) /-- The derivation on `MvPolynomial σ R` that takes value `f i` on `X i`, as a linear map. Use `MvPolynomial.mkDerivation` instead. -/ def mkDerivationₗ (f : σ → A) : MvPolynomial σ R →ₗ[R] A := - Finsupp.lsum R fun xs : σ →₀ ℕ => + Finsupp.lsum R (fun xs : σ →₀ ℕ => (LinearMap.ringLmapEquivSelf R R A).symm <| - xs.sum fun i k => monomial (xs - Finsupp.single i 1) (k : R) • f i + xs.sum fun i k => monomial (xs - Finsupp.single i 1) (k : R) • f i) + ∘ₗ (AddMonoidAlgebra.coeffLinearEquiv R).toLinearMap end @@ -83,6 +84,7 @@ theorem derivation_ext {D₁ D₂ : Derivation R (MvPolynomial σ R) A} (h : ∀ variable [IsScalarTower R (MvPolynomial σ R) A] +set_option backward.isDefEq.respectTransparency false in theorem leibniz_iff_X (D : MvPolynomial σ R →ₗ[R] A) (h₁ : D 1 = 0) : (∀ p q, D (p * q) = p • D q + q • D p) ↔ ∀ s i, D (monomial s 1 * X i) = (monomial s 1 : MvPolynomial σ R) • D (X i) + (X i : MvPolynomial σ R) • D (monomial s 1) := by diff --git a/Mathlib/Algebra/MvPolynomial/Division.lean b/Mathlib/Algebra/MvPolynomial/Division.lean index c47da3f0253cae..2ab005d010f324 100644 --- a/Mathlib/Algebra/MvPolynomial/Division.lean +++ b/Mathlib/Algebra/MvPolynomial/Division.lean @@ -66,9 +66,10 @@ theorem zero_divMonomial (s : σ →₀ ℕ) : (0 : MvPolynomial σ R) /ᵐᵒ theorem divMonomial_zero (x : MvPolynomial σ R) : x /ᵐᵒⁿᵒᵐⁱᵃˡ 0 = x := x.divOf_zero +set_option backward.isDefEq.respectTransparency false in theorem add_divMonomial (x y : MvPolynomial σ R) (s : σ →₀ ℕ) : - (x + y) /ᵐᵒⁿᵒᵐⁱᵃˡ s = x /ᵐᵒⁿᵒᵐⁱᵃˡ s + y /ᵐᵒⁿᵒᵐⁱᵃˡ s := - map_add (N := _ →₀ _) _ _ _ + (x + y) /ᵐᵒⁿᵒᵐⁱᵃˡ s = x /ᵐᵒⁿᵒᵐⁱᵃˡ s + y /ᵐᵒⁿᵒᵐⁱᵃˡ s := by + simp [divMonomial, MvPolynomial, AddMonoidAlgebra.add_divOf] theorem divMonomial_add (a b : σ →₀ ℕ) (x : MvPolynomial σ R) : x /ᵐᵒⁿᵒᵐⁱᵃˡ (a + b) = x /ᵐᵒⁿᵒᵐⁱᵃˡ a /ᵐᵒⁿᵒᵐⁱᵃˡ b := @@ -97,15 +98,12 @@ local infixl:70 " %ᵐᵒⁿᵒᵐⁱᵃˡ " => modMonomial @[simp] theorem coeff_modMonomial_of_not_le {s' s : σ →₀ ℕ} (x : MvPolynomial σ R) (h : ¬s ≤ s') : coeff s' (x %ᵐᵒⁿᵒᵐⁱᵃˡ s) = coeff s' x := - x.modOf_apply_of_not_exists_add s s' - (by - rintro ⟨d, rfl⟩ - exact h le_self_add) + x.coeff_modOf_of_not_exists_add s s' <| by rintro ⟨d, rfl⟩; exact h le_self_add @[simp] theorem coeff_modMonomial_of_le {s' s : σ →₀ ℕ} (x : MvPolynomial σ R) (h : s ≤ s') : coeff s' (x %ᵐᵒⁿᵒᵐⁱᵃˡ s) = 0 := - x.modOf_apply_of_exists_add _ _ <| exists_add_of_le h + x.coeff_modOf_of_exists_add _ _ <| exists_add_of_le h @[simp] theorem monomial_mul_modMonomial (s : σ →₀ ℕ) (x : MvPolynomial σ R) : diff --git a/Mathlib/Algebra/MvPolynomial/Equiv.lean b/Mathlib/Algebra/MvPolynomial/Equiv.lean index 3a90eea82c3a26..df04f114b1b633 100644 --- a/Mathlib/Algebra/MvPolynomial/Equiv.lean +++ b/Mathlib/Algebra/MvPolynomial/Equiv.lean @@ -256,48 +256,6 @@ section variable (S₁ S₂ S₃) -/-- The function from multivariable polynomials in a sum of two types, -to multivariable polynomials in one of the types, -with coefficients in multivariable polynomials in the other type. - -See `sumRingEquiv` for the ring isomorphism. --/ -def sumToIter : MvPolynomial (S₁ ⊕ S₂) R →+* MvPolynomial S₁ (MvPolynomial S₂ R) := - eval₂Hom (C.comp C) fun bc => Sum.recOn bc X (C ∘ X) - -@[simp] -theorem sumToIter_C (a : R) : sumToIter R S₁ S₂ (C a) = C (C a) := - eval₂_C _ _ a - -@[simp] -theorem sumToIter_Xl (b : S₁) : sumToIter R S₁ S₂ (X (Sum.inl b)) = X b := - eval₂_X _ _ (Sum.inl b) - -@[simp] -theorem sumToIter_Xr (c : S₂) : sumToIter R S₁ S₂ (X (Sum.inr c)) = C (X c) := - eval₂_X _ _ (Sum.inr c) - -/-- The function from multivariable polynomials in one type, -with coefficients in multivariable polynomials in another type, -to multivariable polynomials in the sum of the two types. - -See `sumRingEquiv` for the ring isomorphism. --/ -def iterToSum : MvPolynomial S₁ (MvPolynomial S₂ R) →+* MvPolynomial (S₁ ⊕ S₂) R := - eval₂Hom (eval₂Hom C (X ∘ Sum.inr)) (X ∘ Sum.inl) - -@[simp] -theorem iterToSum_C_C (a : R) : iterToSum R S₁ S₂ (C (C a)) = C a := - Eq.trans (eval₂_C _ _ (C a)) (eval₂_C _ _ _) - -@[simp] -theorem iterToSum_X (b : S₁) : iterToSum R S₁ S₂ (X b) = X (Sum.inl b) := - eval₂_X _ _ _ - -@[simp] -theorem iterToSum_C_X (c : S₂) : iterToSum R S₁ S₂ (C (X c)) = X (Sum.inr c) := - Eq.trans (eval₂_C _ _ (X c)) (eval₂_X _ _ _) - section isEmptyRingEquiv variable [IsEmpty σ] @@ -305,8 +263,7 @@ variable (σ) in /-- The algebra isomorphism between multivariable polynomials in no variables and the ground ring. -/ @[simps! apply] -def isEmptyAlgEquiv : MvPolynomial σ R ≃ₐ[R] R := - .ofAlgHom (aeval isEmptyElim) (Algebra.ofId _ _) (by ext) (by ext i m; exact isEmptyElim i) +def isEmptyAlgEquiv : MvPolynomial σ R ≃ₐ[R] R := AddMonoidAlgebra.uniqueAlgEquiv .. variable {R S₁} in @[simp] @@ -323,14 +280,22 @@ variable (σ) in /-- The ring isomorphism between multivariable polynomials in no variables and the ground ring. -/ @[simps! apply] -def isEmptyRingEquiv : MvPolynomial σ R ≃+* R := (isEmptyAlgEquiv R σ).toRingEquiv +def isEmptyRingEquiv : MvPolynomial σ R ≃+* R := AddMonoidAlgebra.uniqueRingEquiv _ -lemma isEmptyRingEquiv_symm_toRingHom : (isEmptyRingEquiv R σ).symm.toRingHom = C := rfl -@[simp] lemma isEmptyRingEquiv_symm_apply (r : R) : (isEmptyRingEquiv R σ).symm r = C r := rfl +variable (σ) in +@[simp] lemma isEmptyRingEquiv_symm_apply (r : R) : (isEmptyRingEquiv R σ).symm r = C r := + AddMonoidAlgebra.uniqueRingEquiv_symm_apply .. + +lemma isEmptyRingEquiv_symm_toRingHom : (isEmptyRingEquiv R σ).symm.toRingHom = C := by ext; simp + +lemma isEmptyRingEquiv_eq_coeff_zero {x : MvPolynomial σ R} : isEmptyRingEquiv R σ x = x.coeff 0 := + rfl -lemma isEmptyRingEquiv_eq_coeff_zero {σ R : Type*} [CommSemiring R] [IsEmpty σ] {x} : - isEmptyRingEquiv R σ x = x.coeff 0 := by - obtain ⟨x, rfl⟩ := (isEmptyRingEquiv R σ).symm.surjective x; simp +@[simp] lemma isEmptyAlgEquiv_symm_apply (r : R) : (isEmptyAlgEquiv R σ).symm r = C r := + isEmptyRingEquiv_symm_apply .. + +lemma isEmptyAlgEquiv_symm_toRingHom : (isEmptyAlgEquiv R σ).symm.toRingHom = C := + isEmptyRingEquiv_symm_toRingHom _ end isEmptyRingEquiv @@ -351,20 +316,79 @@ def mvPolynomialEquivMvPolynomial [CommSemiring S₃] (f : MvPolynomial S₁ R and multivariable polynomials in one of the types, with coefficients in multivariable polynomials in the other type. -/ -def sumRingEquiv : MvPolynomial (S₁ ⊕ S₂) R ≃+* MvPolynomial S₁ (MvPolynomial S₂ R) := by - apply mvPolynomialEquivMvPolynomial R (S₁ ⊕ S₂) _ _ (sumToIter R S₁ S₂) (iterToSum R S₁ S₂) - · refine RingHom.ext (hom_eq_hom _ _ ?hC ?hX) - case hC => ext1; simp only [RingHom.comp_apply, iterToSum_C_C, sumToIter_C] - case hX => intro; simp only [RingHom.comp_apply, iterToSum_C_X, sumToIter_Xr] - · simp [iterToSum_X, sumToIter_Xl] - · ext1; simp only [RingHom.comp_apply, sumToIter_C, iterToSum_C_C] - · rintro ⟨⟩ <;> simp only [sumToIter_Xl, iterToSum_X, sumToIter_Xr, iterToSum_C_X] +def sumRingEquiv : MvPolynomial (S₁ ⊕ S₂) R ≃+* MvPolynomial S₁ (MvPolynomial S₂ R) := + (mapDomainRingEquiv _ sumFinsuppAddEquivProdFinsupp).trans curryRingEquiv + +@[simp] +lemma sumRingEquiv_C (r : R) : sumRingEquiv R S₁ S₂ (C r) = C (C r) := by + unfold sumRingEquiv C MvPolynomial; simp [monomial] + +@[simp] +lemma sumRingEquiv_X_inl (s : S₁) : sumRingEquiv R S₁ S₂ (X <| .inl s) = X s := by + unfold sumRingEquiv X MvPolynomial; simp [monomial, AddMonoidAlgebra.one_def] + +@[simp] +lemma sumRingEquiv_X_inr (s : S₂) : sumRingEquiv R S₁ S₂ (X <| .inr s) = C (X s) := by + unfold sumRingEquiv C X MvPolynomial; simp [monomial] + +@[simp] +lemma sumRingEquiv_symm_C_C (r : R) : (sumRingEquiv R S₁ S₂).symm (C <| C r) = C r := by + simp [← sumRingEquiv_C] + +@[simp] +lemma sumRingEquiv_symm_X (s : S₁) : (sumRingEquiv R S₁ S₂).symm (X s) = X (.inl s) := by + simp [← sumRingEquiv_X_inl] + +@[simp] +lemma sumRingEquiv_symm_C_X (s : S₂) : (sumRingEquiv R S₁ S₂).symm (C <| X s) = X (.inr s) := by + simp [← sumRingEquiv_X_inr] + +/-- The function from multivariable polynomials in a sum of two types, +to multivariable polynomials in one of the types, +with coefficients in multivariable polynomials in the other type. + +See `sumRingEquiv` for the ring isomorphism. +-/ +@[deprecated sumRingEquiv (since := "2026-06-18")] +def sumToIter : MvPolynomial (S₁ ⊕ S₂) R →+* MvPolynomial S₁ (MvPolynomial S₂ R) := + eval₂Hom (C.comp C) fun bc => Sum.recOn bc X (C ∘ X) + +@[deprecated sumRingEquiv_C (since := "2026-06-18")] +theorem sumToIter_C (a : R) : sumToIter R S₁ S₂ (C a) = C (C a) := + eval₂_C _ _ a -@[simp] lemma iterToSum_sumToIter (p) : - iterToSum R S₁ S₂ (sumToIter R S₁ S₂ p) = p := (sumRingEquiv _ _ _).symm_apply_apply _ +@[deprecated sumRingEquiv_X_inl (since := "2026-06-18")] +theorem sumToIter_Xl (b : S₁) : sumToIter R S₁ S₂ (X (Sum.inl b)) = X b := + eval₂_X _ _ (Sum.inl b) + +@[deprecated sumRingEquiv_X_inr (since := "2026-06-18")] +theorem sumToIter_Xr (c : S₂) : sumToIter R S₁ S₂ (X (Sum.inr c)) = C (X c) := + eval₂_X _ _ (Sum.inr c) -@[simp] lemma sumToIter_iterToSum (p) : - sumToIter R S₁ S₂ (iterToSum R S₁ S₂ p) = p := (sumRingEquiv _ _ _).apply_symm_apply _ +/-- The function from multivariable polynomials in one type, +with coefficients in multivariable polynomials in another type, +to multivariable polynomials in the sum of the two types. + +See `sumRingEquiv` for the ring isomorphism. +-/ +@[deprecated sumRingEquiv (since := "2026-06-18")] +def iterToSum : MvPolynomial S₁ (MvPolynomial S₂ R) →+* MvPolynomial (S₁ ⊕ S₂) R := + eval₂Hom (eval₂Hom C (X ∘ Sum.inr)) (X ∘ Sum.inl) + +@[deprecated sumRingEquiv_symm_C_C (since := "2026-06-18")] +theorem iterToSum_C_C (a : R) : iterToSum R S₁ S₂ (C (C a)) = C a := + Eq.trans (eval₂_C _ _ (C a)) (eval₂_C _ _ _) + +@[deprecated sumRingEquiv_symm_X (since := "2026-06-18")] +theorem iterToSum_X (b : S₁) : iterToSum R S₁ S₂ (X b) = X (Sum.inl b) := + eval₂_X _ _ _ + +@[deprecated sumRingEquiv_symm_C_X (since := "2026-06-18")] +theorem iterToSum_C_X (c : S₂) : iterToSum R S₁ S₂ (C (X c)) = X (Sum.inr c) := + Eq.trans (eval₂_C _ _ (X c)) (eval₂_X _ _ _) + +@[deprecated (since := "2026-06-18")] alias iterToSum_sumToIter := RingEquiv.symm_apply_apply +@[deprecated (since := "2026-06-18")] alias sumToIter_iterToSum := RingEquiv.apply_symm_apply /-- The algebra isomorphism between multivariable polynomials in a sum of two types, and multivariable polynomials in one of the types, @@ -372,25 +396,41 @@ with coefficients in multivariable polynomials in the other type. -/ @[simps!] def sumAlgEquiv : MvPolynomial (S₁ ⊕ S₂) R ≃ₐ[R] MvPolynomial S₁ (MvPolynomial S₂ R) := - { sumRingEquiv R S₁ S₂ with - commutes' := by - intro r - have A : algebraMap R (MvPolynomial S₁ (MvPolynomial S₂ R)) r = (C (C r) :) := rfl - have B : algebraMap R (MvPolynomial (S₁ ⊕ S₂) R) r = C r := rfl - simp only [sumRingEquiv, mvPolynomialEquivMvPolynomial, Equiv.toFun_as_coe, - Equiv.coe_fn_mk, B, sumToIter_C, A] } + (domCongr _ _ sumFinsuppAddEquivProdFinsupp).trans (curryAlgEquiv _) + +@[simp] +lemma sumAlgEquiv_C_inl (r : R) : sumAlgEquiv R S₁ S₂ (C r) = C (C r) := by + ext; simp [sumAlgEquiv, C, monomial, coeff] + +@[simp] +lemma sumAlgEquiv_symm_C_C (r : R) : (sumAlgEquiv R S₁ S₂).symm (C <| C r) = C r := by + ext; simp [sumAlgEquiv, C, monomial, coeff] + +@[simp] +lemma sumAlgEquiv_X_inl (c : S₁) : sumAlgEquiv R S₁ S₂ (X <| .inl c) = X c := by + ext; simp [sumAlgEquiv, X, monomial, coeff, AddMonoidAlgebra.one_def] + +@[simp] +lemma sumAlgEquiv_symm_X (c : S₁) : (sumAlgEquiv R S₁ S₂).symm (X c) = (X <| .inl c) := by + ext; simp [sumAlgEquiv, X, monomial, coeff, AddMonoidAlgebra.one_def] + +@[simp] +lemma sumAlgEquiv_X_inr (c : S₂) : sumAlgEquiv R S₁ S₂ (X <| .inr c) = C (X c) := by + ext; simp [sumAlgEquiv, C, X, monomial, coeff] + +@[simp] +lemma sumAlgEquiv_symm_C_X (c : S₂) : (sumAlgEquiv R S₁ S₂).symm (C <| X c) = X (.inr c) := by + ext; simp [sumAlgEquiv, C, X, monomial, coeff] lemma sumAlgEquiv_comp_rename_inr : (sumAlgEquiv R S₁ S₂).toAlgHom.comp (rename Sum.inr) = IsScalarTower.toAlgHom R (MvPolynomial S₂ R) (MvPolynomial S₁ (MvPolynomial S₂ R)) := by - ext i - simp + ext; simp lemma sumAlgEquiv_comp_rename_inl : - (sumAlgEquiv R S₁ S₂).toAlgHom.comp (rename Sum.inl) = + (sumAlgEquiv R S₁ S₂).toAlgHom.comp (rename .inl) = MvPolynomial.mapAlgHom (Algebra.ofId _ _) := by - ext i - simp + ext; simp section commAlgEquiv variable {R S₁ S₂ : Type*} [CommSemiring R] @@ -401,18 +441,18 @@ polynomials in variables `S₂` and multivariable polynomials in variables `S₂ polynomials in variables `S₁`. -/ noncomputable def commAlgEquiv : MvPolynomial S₁ (MvPolynomial S₂ R) ≃ₐ[R] MvPolynomial S₂ (MvPolynomial S₁ R) := - (sumAlgEquiv R S₁ S₂).symm.trans <| (renameEquiv _ (.sumComm S₁ S₂)).trans (sumAlgEquiv R S₂ S₁) + AddMonoidAlgebra.commAlgEquiv _ @[simp] lemma commAlgEquiv_C (p) : commAlgEquiv R S₁ S₂ (.C p) = .map C p := by suffices (commAlgEquiv R S₁ S₂).toAlgHom.comp (IsScalarTower.toAlgHom R (MvPolynomial S₂ R) _) = mapAlgHom (Algebra.ofId _ _) by exact DFunLike.congr_fun this p - ext x : 1 - simp [commAlgEquiv] + ext; simp [commAlgEquiv, mapAlgHom, X, C, monomial, coeff, AddMonoidAlgebra.one_def] -lemma commAlgEquiv_C_X (i) : commAlgEquiv R S₁ S₂ (.C (.X i)) = .X i := by simp +lemma commAlgEquiv_C_X (i) : commAlgEquiv R S₁ S₂ (.C (.X i)) = .X i := by simp [map, X, monomial] -@[simp] lemma commAlgEquiv_X (i) : commAlgEquiv R S₁ S₂ (.X i) = .C (.X i) := by simp [commAlgEquiv] +@[simp] lemma commAlgEquiv_X (i) : commAlgEquiv R S₁ S₂ (.X i) = .C (.X i) := by + ext x y; simp [X, C, monomial, commAlgEquiv] end commAlgEquiv @@ -514,15 +554,13 @@ set_option backward.isDefEq.respectTransparency false in lemma support_optionEquivLeft (p : MvPolynomial (Option σ) R) : (optionEquivLeft R σ p).support = Finset.image (fun m => m none) p.support := by ext i - rw [Polynomial.mem_support_iff, Finset.mem_image, Finsupp.ne_iff] + simp only [Polynomial.mem_support_iff, ne_eq, MvPolynomial.ext_iff, coeff_zero, not_forall, + Finset.mem_image, mem_support_iff, ← optionEquivLeft_coeff_some_coeff_none] constructor · rintro ⟨m, hm⟩ - refine ⟨optionElim i m, ?_, optionElim_apply_none _ _⟩ - rw [← mem_support_coeff_optionEquivLeft] - simpa using! hm + exact ⟨optionElim i m, by simpa using! hm, optionElim_apply_none _ _⟩ · rintro ⟨m, h, rfl⟩ - refine ⟨some m, ?_⟩ - rwa [← coeff, zero_apply, ← mem_support_iff, mem_support_coeff_optionEquivLeft, optionElim_some] + exact ⟨some m, h⟩ theorem nonempty_support_optionEquivLeft {f : MvPolynomial (Option σ) R} (h : f ≠ 0) : (optionEquivLeft R σ f).support.Nonempty := by @@ -728,15 +766,13 @@ set_option backward.isDefEq.respectTransparency false in theorem support_finSuccEquiv (f : MvPolynomial (Fin (n + 1)) R) : (finSuccEquiv R n f).support = Finset.image (fun m : Fin (n + 1) →₀ ℕ => m 0) f.support := by ext i - rw [Polynomial.mem_support_iff, Finset.mem_image, Finsupp.ne_iff] + simp only [Polynomial.mem_support_iff, ne_eq, MvPolynomial.ext_iff, coeff_zero, not_forall, + Finset.mem_image, mem_support_iff, finSuccEquiv_coeff_coeff] constructor · rintro ⟨m, hm⟩ - refine ⟨cons i m, ?_, cons_zero _ _⟩ - rw [← mem_support_coeff_finSuccEquiv] - simpa using! hm + exact ⟨cons i m, hm, cons_zero _ _⟩ · rintro ⟨m, h, rfl⟩ - refine ⟨tail m, ?_⟩ - rwa [← coeff, zero_apply, ← mem_support_iff, mem_support_coeff_finSuccEquiv, cons_tail] + exact ⟨tail m, by simpa using h⟩ theorem mem_support_finSuccEquiv {f : MvPolynomial (Fin (n + 1)) R} {x} : x ∈ (finSuccEquiv R n f).support ↔ x ∈ (fun m : Fin (n + 1) →₀ _ ↦ m 0) '' f.support := by diff --git a/Mathlib/Algebra/MvPolynomial/Eval.lean b/Mathlib/Algebra/MvPolynomial/Eval.lean index 0e13948de38b25..b4cbd587a08874 100644 --- a/Mathlib/Algebra/MvPolynomial/Eval.lean +++ b/Mathlib/Algebra/MvPolynomial/Eval.lean @@ -474,7 +474,8 @@ theorem C_dvd_iff_map_hom_eq_zero (q : R →+* S₁) (r : R) (hr : ∀ r' : R, q simp only [coeff_map, coeff_zero, hr] theorem map_mapRange_eq_iff (f : R →+* S₁) (g : S₁ → R) (hg : g 0 = 0) (φ : MvPolynomial σ S₁) : - map f (Finsupp.mapRange g hg φ) = φ ↔ ∀ d, f (g (coeff d φ)) = coeff d φ := by + map f (.ofCoeff <| Finsupp.mapRange g hg <| AddMonoidAlgebra.coeff φ) = φ ↔ + ∀ d, f (g (coeff d φ)) = coeff d φ := by simp_rw [MvPolynomial.ext_iff, coeff_map]; rfl lemma coeffs_map (f : R →+* S₁) (p : MvPolynomial σ R) [DecidableEq S₁] : @@ -867,7 +868,7 @@ lemma algebraMap_def : rfl instance : IsScalarTower R (MvPolynomial σ R) (MvPolynomial σ S) := - IsScalarTower.of_algebraMap_eq' (by ext; simp) + IsScalarTower.of_algebraMap_eq' (by ext; simp [C, monomial, map]) instance [FaithfulSMul R S] : FaithfulSMul (MvPolynomial σ R) (MvPolynomial σ S) := (faithfulSMul_iff_algebraMap_injective ..).mpr diff --git a/Mathlib/Algebra/MvPolynomial/Funext.lean b/Mathlib/Algebra/MvPolynomial/Funext.lean index 571af32ac4a8d0..edac9370c37edf 100644 --- a/Mathlib/Algebra/MvPolynomial/Funext.lean +++ b/Mathlib/Algebra/MvPolynomial/Funext.lean @@ -36,8 +36,7 @@ private theorem funext_fin {n : ℕ} {p : MvPolynomial (Fin n) R} induction n with | zero => apply (MvPolynomial.isEmptyRingEquiv R (Fin 0)).injective - rw [map_zero] - convert! h _ finZeroElim + simpa [constantCoeff, coeff] using h 0 finZeroElim | succ n ih => apply (finSuccEquiv R n).injective rw [map_zero] @@ -46,7 +45,7 @@ private theorem funext_fin {n : ℕ} {p : MvPolynomial (Fin n) R} rintro _ ⟨r, hr, rfl⟩ refine ih (s ·.succ) (fun _ ↦ hs _) fun x hx ↦ ?_ rw [eval_polynomial_eval_finSuccEquiv] - exact h _ fun i _ ↦ i.cases (by simpa using hr) (by simpa using hx) + exact h _ fun i _ ↦ i.cases (by simpa [eval_C] using hr) (by simpa using hx) section diff --git a/Mathlib/Algebra/MvPolynomial/Monad.lean b/Mathlib/Algebra/MvPolynomial/Monad.lean index 1226d41875149d..3669cfe626dccc 100644 --- a/Mathlib/Algebra/MvPolynomial/Monad.lean +++ b/Mathlib/Algebra/MvPolynomial/Monad.lean @@ -341,14 +341,16 @@ instance lawfulFunctor : LawfulFunctor fun σ => MvPolynomial σ R where instance lawfulMonad : LawfulMonad fun σ => MvPolynomial σ R where pure_bind := by intros; simp [pure, bind] bind_assoc := by intros; simp [bind, ← bind₁_comp_bind₁] - seqLeft_eq := by intros; simp [SeqLeft.seqLeft, Seq.seq, (· <$> ·), bind₁_rename]; rfl + seqLeft_eq _ _ := by + simp [SeqLeft.seqLeft, Seq.seq, (· <$> ·), bind₁_rename]; simp [rename_eq_aeval]; rfl seqRight_eq := by intros; simp [SeqRight.seqRight, Seq.seq, (· <$> ·), bind₁_rename]; rfl pure_seq := by intros; simp [(· <$> ·), pure, Seq.seq] - bind_pure_comp := by aesop + bind_pure_comp _ _ := congr(⇑$((rename_eq_aeval ..).symm) _) bind_map := by aesop /- Possible TODO for the future: + Enable the following definitions, and write a lot of supporting lemmas. def bind (f : R →+* mv_polynomial τ S) (g : σ → mv_polynomial τ S) : diff --git a/Mathlib/Algebra/MvPolynomial/PDeriv.lean b/Mathlib/Algebra/MvPolynomial/PDeriv.lean index 929abd0a853464..9f76a70548e064 100644 --- a/Mathlib/Algebra/MvPolynomial/PDeriv.lean +++ b/Mathlib/Algebra/MvPolynomial/PDeriv.lean @@ -164,14 +164,23 @@ lemma aeval_sumElim_pderiv_inl {S τ : Type*} [CommRing S] [Algebra R S] simp only [Derivation.leibniz, pderiv_X, smul_eq_mul, map_add, map_mul, aeval_X, h] cases q <;> simp [Pi.single_apply] -lemma pderiv_sumToIter {σ ι} (p i) : - (sumToIter R σ ι p).pderiv i = sumToIter R σ ι (p.pderiv (.inl i)) := by +@[simp] +lemma pderiv_sumRingEquiv {σ ι} (p i) : + (sumRingEquiv R σ ι p).pderiv i = sumRingEquiv R σ ι (p.pderiv (.inl i)) := by classical induction p using MvPolynomial.induction_on with | C a => simp | add p q _ _ => simp_all | mul_X p n _ => cases n <;> simp_all [pderiv_X, Pi.single_apply, apply_ite] +@[deprecated (since := "2026-06-18")] alias pderiv_sumToIter := pderiv_sumRingEquiv + +@[simp] +lemma pderiv_sumAlgEquiv {R S₁ S₂ : Type*} [CommSemiring R] + (b : S₁) (p : MvPolynomial (S₁ ⊕ S₂) R) : + pderiv b (sumAlgEquiv R S₁ S₂ p) = sumAlgEquiv R S₁ S₂ (pderiv (Sum.inl b) p) := + pderiv_sumRingEquiv .. + end PDeriv end MvPolynomial diff --git a/Mathlib/Algebra/MvPolynomial/Rename.lean b/Mathlib/Algebra/MvPolynomial/Rename.lean index 9dfb980d984cfc..39bce9acf051f0 100644 --- a/Mathlib/Algebra/MvPolynomial/Rename.lean +++ b/Mathlib/Algebra/MvPolynomial/Rename.lean @@ -52,14 +52,14 @@ section Rename /-- Rename all the variables in a multivariable polynomial. -/ def rename (f : σ → τ) : MvPolynomial σ R →ₐ[R] MvPolynomial τ R := - aeval (X ∘ f) + AddMonoidAlgebra.mapDomainAlgHom _ _ (mapDomain.addMonoidHom f) -theorem rename_C (f : σ → τ) (r : R) : rename f (C r) = C r := - eval₂_C _ _ _ +theorem rename_C (f : σ → τ) (r : R) : rename f (C r) = C r := by + unfold rename C monomial MvPolynomial; simp @[simp] -theorem rename_X (f : σ → τ) (i : σ) : rename f (X i : MvPolynomial σ R) = X (f i) := - eval₂_X _ _ _ +theorem rename_X (f : σ → τ) (i : σ) : rename f (X i : MvPolynomial σ R) = X (f i) := by + simp [MvPolynomial, rename, X, monomial] @[simp] lemma rename_zero (f : σ → τ) : (0 : MvPolynomial σ R).rename f = 0 := rfl @@ -78,45 +78,29 @@ lemma map_comp_rename (f : R →+* S) (g : σ → τ) : @[simp] theorem rename_rename (f : σ → τ) (g : τ → α) (p : MvPolynomial σ R) : rename g (rename f p) = rename (g ∘ f) p := by - nth_rw 2 [rename] - simp_rw [aeval_def, algebraMap_eq, rename, aeval_eq_eval₂Hom] - rw [eval₂_comp_left (eval₂Hom (algebraMap R (MvPolynomial α R)) (X ∘ g)) C (X ∘ f) p] - simp only [comp_def, eval₂Hom_X'] - refine eval₂Hom_congr ?_ rfl rfl - ext1; simp only [comp_apply, RingHom.coe_comp, eval₂Hom_C] + simp [MvPolynomial, rename, mapDomain.addMonoidHom_comp] lemma rename_comp_rename (f : σ → τ) (g : τ → α) : (rename (R := R) g).comp (rename f) = rename (g ∘ f) := AlgHom.ext fun p ↦ rename_rename f g p @[simp] -theorem rename_id : rename id = AlgHom.id R (MvPolynomial σ R) := - AlgHom.ext fun p ↦ eval₂_eta p +theorem rename_id : rename id = AlgHom.id R (MvPolynomial σ R) := by simp [MvPolynomial, rename] lemma rename_id_apply (p : MvPolynomial σ R) : rename id p = p := by simp theorem rename_monomial (f : σ → τ) (d : σ →₀ ℕ) (r : R) : rename f (monomial d r) = monomial (d.mapDomain f) r := by - rw [rename, aeval_monomial, monomial_eq (s := Finsupp.mapDomain f d), - Finsupp.prod_mapDomain_index, algebraMap_eq] - · simp_rw [Function.comp_apply] - · exact fun n => pow_zero _ - · exact fun n i₁ i₂ => pow_add _ _ _ - -set_option backward.isDefEq.respectTransparency false in -theorem rename_eq (f : σ → τ) (p : MvPolynomial σ R) : - rename f p = Finsupp.mapDomain (Finsupp.mapDomain f) p := by - simp_rw [rename, aeval_def, eval₂, Finsupp.mapDomain, algebraMap_eq, comp_apply, - X_pow_eq_monomial, ← monomial_finsupp_sum_index, ← single_eq_monomial, AddMonoidAlgebra.coeff] + simp [MvPolynomial, rename, monomial] + +lemma rename_eq_aeval (f : σ → τ) : rename (R := R) f = aeval (X ∘ f) := by ext; simp + +@[deprecated (since := "2026-06-18")] alias rename_eq := rename_eq_aeval theorem rename_injective (f : σ → τ) (hf : Function.Injective f) : - Function.Injective (rename f : MvPolynomial σ R → MvPolynomial τ R) := by - have : - (rename f : MvPolynomial σ R → MvPolynomial τ R) = Finsupp.mapDomain (Finsupp.mapDomain f) := - funext (rename_eq f) - rw [this] - exact Finsupp.mapDomain_injective (Finsupp.mapDomain_injective hf) + Function.Injective (rename f : MvPolynomial σ R → MvPolynomial τ R) := + AddMonoidAlgebra.mapDomain_injective (Finsupp.mapDomain_injective hf) @[simp] lemma rename_eq_zero_iff_of_injective (p : MvPolynomial σ R) {f : σ → τ} @@ -152,8 +136,7 @@ theorem killCompl_C (r : R) : killCompl hf (C r) = C r := algHom_C _ _ theorem killCompl_comp_rename : (killCompl hf).comp (rename f) = AlgHom.id R _ := algHom_ext fun i => by dsimp - rw [rename, killCompl, aeval_X, comp_apply, aeval_X, dif_pos ⟨i, rfl⟩, - Equiv.ofInjective_symm_apply] + rw [rename_X, killCompl, aeval_X, dif_pos ⟨i, rfl⟩, Equiv.ofInjective_symm_apply] @[simp] theorem killCompl_rename_app (p : MvPolynomial σ R) : killCompl hf (rename f p) = p := @@ -365,7 +348,7 @@ theorem coeff_rename_embDomain (f : σ ↪ τ) (φ : MvPolynomial σ R) (d : σ theorem coeff_rename_eq_zero (f : σ → τ) (φ : MvPolynomial σ R) (d : τ →₀ ℕ) (h : ∀ u : σ →₀ ℕ, u.mapDomain f = d → φ.coeff u = 0) : (rename f φ).coeff d = 0 := by classical - rw [rename_eq, ← notMem_support_iff] + rw [← notMem_support_iff] intro H replace H := mapDomain_support H rw [Finset.mem_image] at H @@ -396,9 +379,8 @@ section Support theorem support_rename_of_injective {p : MvPolynomial σ R} {f : σ → τ} [DecidableEq τ] (h : Function.Injective f) : - (rename f p).support = Finset.image (Finsupp.mapDomain f) p.support := by - rw [rename_eq] - exact Finsupp.mapDomain_support_of_injective (Finsupp.mapDomain_injective h) _ + (rename f p).support = Finset.image (Finsupp.mapDomain f) p.support := + Finsupp.mapDomain_support_of_injective (Finsupp.mapDomain_injective h) _ lemma support_rename_killCompl_subset {p : MvPolynomial τ R} {f : σ → τ} (hf : f.Injective) : ((p.killCompl hf).rename f).support ⊆ p.support := by diff --git a/Mathlib/Algebra/MvPolynomial/Supported.lean b/Mathlib/Algebra/MvPolynomial/Supported.lean index 26f7cf1fac7e42..6b738196bfbd9e 100644 --- a/Mathlib/Algebra/MvPolynomial/Supported.lean +++ b/Mathlib/Algebra/MvPolynomial/Supported.lean @@ -42,8 +42,9 @@ noncomputable def supported (s : Set σ) : Subalgebra R (MvPolynomial σ R) := open Algebra +set_option backward.isDefEq.respectTransparency false in theorem supported_eq_range_rename (s : Set σ) : supported R s = (rename ((↑) : s → σ)).range := by - rw [supported, Set.image_eq_range, adjoin_range_eq_range_aeval, rename] + rw [supported, Set.image_eq_range, adjoin_range_eq_range_aeval, rename_eq_aeval] congr /-- The isomorphism between the subalgebra of polynomials supported by `s` and diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index bedc15cd7f6966..4f38dc96829bbb 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -16,6 +16,8 @@ public import Mathlib.Tactic.FastInstance public import Mathlib.LinearAlgebra.Finsupp.LSum public import Mathlib.Algebra.Order.Group.Nat +import Mathlib.Data.Finsupp.SMul + /-! # Theory of univariate polynomials @@ -221,7 +223,7 @@ theorem toFinsupp_pow (a : R[X]) (n : ℕ) : (a ^ n).toFinsupp = a.toFinsupp ^ n theorem _root_.IsSMulRegular.polynomial {S : Type*} [SMulZeroClass S R] {a : S} (ha : IsSMulRegular R a) : IsSMulRegular R[X] a - | ⟨_x⟩, ⟨_y⟩, h => congr_arg _ <| ha.finsupp (Polynomial.ofFinsupp.inj h) + | ⟨_x⟩, ⟨_y⟩, h => congr_arg _ <| coeff_injective <| ha.finsupp congr(($h).toFinsupp.coeff) theorem toFinsupp_injective : Function.Injective (toFinsupp : R[X] → AddMonoidAlgebra _ _) := fun ⟨_x⟩ ⟨_y⟩ ↦ congr_arg _ @@ -280,10 +282,7 @@ instance distribMulAction {S} [Monoid S] [DistribMulAction S R] : DistribMulActi ⟨⟨toFinsupp, toFinsupp_zero (R := R)⟩, toFinsupp_add⟩ toFinsupp_injective toFinsupp_smul instance faithfulSMul {S} [SMulZeroClass S R] [FaithfulSMul S R] : FaithfulSMul S R[X] where - eq_of_smul_eq_smul {_s₁ _s₂} h := by - apply eq_of_smul_eq_smul (α := ℕ →₀ R) - intro a - exact congr_arg toFinsupp (h ⟨a⟩) + eq_of_smul_eq_smul {_s₁ _s₂} h := eq_of_smul_eq_smul fun a : R[ℕ] ↦ congr(($(h ⟨a⟩)).toFinsupp) instance module {S} [Semiring S] [Module S R] : Module S R[X] := fast_instance% Function.Injective.module _ ⟨⟨toFinsupp, toFinsupp_zero⟩, toFinsupp_add⟩ @@ -335,8 +334,7 @@ def toFinsuppIso : R[X] ≃+* R[ℕ] where map_mul' := toFinsupp_mul map_add' := toFinsupp_add -instance [DecidableEq R] : DecidableEq R[X] := - @Equiv.decidableEq R[X] _ (toFinsuppIso R).toEquiv (Finsupp.instDecidableEq) +instance [DecidableEq R] : DecidableEq R[X] := (toFinsuppIso R).toEquiv.decidableEq /-- Linear isomorphism between `R[X]` and `R[ℕ]`. This is just an implementation detail, but it can be useful to transfer results from `Finsupp` to polynomials. -/ @@ -357,18 +355,17 @@ theorem toFinsupp_sum {ι : Type*} (s : Finset ι) (f : ι → R[X]) : /-- The set of all `n` such that `X^n` has a non-zero coefficient. -/ def support : R[X] → Finset ℕ - | ⟨p⟩ => p.support + | ⟨p⟩ => p.coeff.support @[simp] -theorem support_ofFinsupp (p) : support (⟨p⟩ : R[X]) = p.support := by rw [support] +theorem support_ofFinsupp (p) : support (⟨p⟩ : R[X]) = p.coeff.support := by rw [support] -theorem support_toFinsupp (p : R[X]) : p.toFinsupp.support = p.support := by rw [support] +theorem support_toFinsupp (p : R[X]) : p.toFinsupp.coeff.support = p.support := by rw [support] @[simp] theorem support_zero : (0 : R[X]).support = ∅ := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] theorem support_eq_empty : p.support = ∅ ↔ p = 0 := by rcases p with ⟨⟩ @@ -379,7 +376,6 @@ theorem support_eq_empty : p.support = ∅ ↔ p = 0 := by theorem card_support_eq_zero : #p.support = 0 ↔ p = 0 := by simp -set_option backward.isDefEq.respectTransparency false in /-- `monomial s a` is the monomial `a * X^s` -/ def monomial (n : ℕ) : R →ₗ[R] R[X] where toFun t := ⟨.single n t⟩ @@ -391,7 +387,8 @@ theorem toFinsupp_monomial (n : ℕ) (r : R) : (monomial n r).toFinsupp = .singl simp [monomial] @[simp] -theorem ofFinsupp_single (n : ℕ) (r : R) : ⟨.single n r⟩ = monomial n r := by simp [monomial] +theorem ofFinsupp_single (n : ℕ) (r : R) : (⟨.single n r⟩ : R[X]) = monomial n r := by + simp [monomial] @[simp] theorem monomial_zero_right (n : ℕ) : monomial n (0 : R) = 0 := @@ -417,16 +414,15 @@ theorem smul_monomial {S} [SMulZeroClass S R] (a : S) (n : ℕ) (b : R) : toFinsupp_injective <| AddMonoidAlgebra.smul_single _ _ _ theorem monomial_injective (n : ℕ) : Function.Injective (monomial n : R → R[X]) := - (toFinsuppIso R).symm.injective.comp (single_injective n) + (toFinsuppIso R).symm.injective.comp single_right_injective @[simp] theorem monomial_eq_zero_iff (t : R) (n : ℕ) : monomial n t = 0 ↔ t = 0 := LinearMap.map_eq_zero_iff _ (Polynomial.monomial_injective n) -set_option backward.isDefEq.respectTransparency false in theorem monomial_eq_monomial_iff {m n : ℕ} {a b : R} : monomial m a = monomial n b ↔ m = n ∧ a = b ∨ a = 0 ∧ b = 0 := by - rw [← toFinsupp_inj, toFinsupp_monomial, toFinsupp_monomial, Finsupp.single_eq_single_iff] + rw [← toFinsupp_inj, toFinsupp_monomial, toFinsupp_monomial, single_inj] theorem support_add : (p + q).support ⊆ p.support ∪ q.support := by simpa [support] using! Finsupp.support_add @@ -505,7 +501,7 @@ theorem X_mul : X * p = p * X := by rcases p with ⟨⟩ simp only [X, ← ofFinsupp_single, ← ofFinsupp_mul, ofFinsupp.injEq] ext - simp [AddMonoidAlgebra.mul_apply, add_comm] + simp [AddMonoidAlgebra.coeff_mul, add_comm] theorem X_pow_mul {n : ℕ} : X ^ n * p = p * X ^ n := by induction n with @@ -565,21 +561,18 @@ theorem X_pow_mul_monomial (k n : ℕ) (r : R) : X ^ k * monomial n r = monomial /-- `coeff p n` (often denoted `p.coeff n`) is the coefficient of `X^n` in `p`. -/ def coeff : R[X] → ℕ → R - | ⟨p⟩ => p + | ⟨p⟩ => p.coeff @[simp] -theorem coeff_ofFinsupp (p) : coeff (⟨p⟩ : R[X]) = p := by rw [coeff] +theorem coeff_ofFinsupp (p) : coeff (⟨p⟩ : R[X]) = p.coeff := by rw [coeff] -set_option backward.isDefEq.respectTransparency false in -theorem coeff_injective : Injective (coeff : R[X] → ℕ → R) := by - rintro ⟨p⟩ ⟨q⟩ - simp only [coeff, DFunLike.coe_fn_eq, imp_self, ofFinsupp.injEq] +theorem coeff_injective : Injective (coeff : R[X] → ℕ → R) := by rintro ⟨p⟩ ⟨q⟩; simp [coeff] @[simp] theorem coeff_inj : p.coeff = q.coeff ↔ p = q := coeff_injective.eq_iff -theorem toFinsupp_apply (f : R[X]) (i) : f.toFinsupp i = f.coeff i := by cases f; rfl +theorem toFinsupp_apply (f : R[X]) (i) : f.toFinsupp.coeff i = f.coeff i := by cases f; rfl theorem finite_range_coeff (f : R[X]) : (Set.range f.coeff).Finite := Finsupp.finite_range _ @@ -705,9 +698,9 @@ theorem forall_eq_iff_forall_eq : (∀ f g : R[X], f = g) ↔ ∀ a b : R, a = b simpa only [← subsingleton_iff] using subsingleton_iff_subsingleton theorem ext_iff {p q : R[X]} : p = q ↔ ∀ n, coeff p n = coeff q n := by - rcases p with ⟨f : ℕ →₀ R⟩ - rcases q with ⟨g : ℕ →₀ R⟩ - simpa [coeff] using! DFunLike.ext_iff (f := f) (g := g) + rcases p with ⟨f⟩ + rcases q with ⟨g⟩ + simpa [coeff] using! DFunLike.ext_iff (f := f.coeff) (g := g.coeff) @[ext] theorem ext {p q : R[X]} : (∀ n, coeff p n = coeff q n) → p = q := @@ -718,8 +711,8 @@ set_option backward.isDefEq.respectTransparency false in theorem addSubmonoid_closure_setOf_eq_monomial : AddSubmonoid.closure { p : R[X] | ∃ n a, p = monomial n a } = ⊤ := by apply top_unique - rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ← - Finsupp.add_closure_setOf_eq_single, AddMonoidHom.map_mclosure] + rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ← addSubmonoidClosure_single, + AddMonoidHom.map_mclosure] refine AddSubmonoid.closure_mono (Set.image_subset_iff.2 ?_) rintro _ ⟨n, a, rfl⟩ exact ⟨n, a, Polynomial.ofFinsupp_single _ _⟩ @@ -835,16 +828,14 @@ theorem support_X_empty (H : (1 : R) = 0) : (X : R[X]).support = ∅ := by theorem support_X [Nontrivial R] : (X : R[X]).support = singleton 1 := by rw [← pow_one X, support_X_pow 1] -set_option backward.isDefEq.respectTransparency false in theorem monomial_left_inj {a : R} (ha : a ≠ 0) {i j : ℕ} : monomial i a = monomial j a ↔ i = j := by - simp only [← ofFinsupp_single, ofFinsupp.injEq, Finsupp.single_left_inj ha] + simp [monomial_eq_monomial_iff, ha] theorem binomial_eq_binomial {k l m n : ℕ} {u v : R} (hu : u ≠ 0) (hv : v ≠ 0) : C u * X ^ k + C v * X ^ l = C u * X ^ m + C v * X ^ n ↔ k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u + v = 0 ∧ k = l ∧ m = n := by - simp_rw [C_mul_X_pow_eq_monomial, ← toFinsupp_inj, toFinsupp_add, toFinsupp_monomial] - exact Finsupp.single_add_single_eq_single_add_single hu hv + simp [C_mul_X_pow_eq_monomial, ← toFinsupp_inj, single_add_single_inj, *] theorem natCast_mul (n : ℕ) (p : R[X]) : (n : R[X]) * p = n • p := (nsmul_eq_mul _ _).symm @@ -922,7 +913,7 @@ protected theorem smul_sum {S T : Type*} [AddCommMonoid S] [DistribSMul T S] (p @[simp] theorem sum_monomial_eq : ∀ p : R[X], (p.sum fun n a ↦ monomial n a) = p - | ⟨_p⟩ => (ofFinsupp_sum _ _).symm.trans (congr_arg _ <| Finsupp.sum_single _) + | ⟨_p⟩ => (ofFinsupp_sum _ _).symm.trans (congr_arg _ <| sum_coeff_single _) theorem sum_C_mul_X_pow_eq (p : R[X]) : (p.sum fun n a ↦ C a * X ^ n) = p := by simp_rw [C_mul_X_pow_eq_monomial, sum_monomial_eq] @@ -972,14 +963,13 @@ theorem ofFinsupp_erase (p : R[ℕ]) (n : ℕ) : simp only [erase_def] @[simp] -theorem support_erase {p : R[X]} (n : ℕ) : support (p.erase n) = (support p).erase n := by - simp only [support, erase_def, Finsupp.support_erase, AddMonoidAlgebra.erase, ofCoeff, - AddMonoidAlgebra.coeff] +theorem support_erase (p : R[X]) (n : ℕ) : support (p.erase n) = (support p).erase n := by + simp [support] -theorem monomial_add_erase (p : R[X]) (n : ℕ) : monomial n (coeff p n) + p.erase n = p := - toFinsupp_injective <| by - rw [toFinsupp_add, toFinsupp_monomial, toFinsupp_erase, coeff] - exact Finsupp.single_add_erase _ _ +theorem monomial_add_erase (p : R[X]) (n : ℕ) : monomial n (coeff p n) + p.erase n = p := by + apply toFinsupp_injective + simp only [toFinsupp_add, toFinsupp_monomial, toFinsupp_erase] + exact AddMonoidAlgebra.single_add_erase .. theorem coeff_erase (p : R[X]) (n i : ℕ) : (p.erase n).coeff i = if i = n then 0 else p.coeff i := by @@ -1011,10 +1001,7 @@ def update (p : R[X]) (n : ℕ) (a : R) : R[X] := Polynomial.ofFinsupp (p.toFinsupp.update n a) theorem coeff_update (p : R[X]) (n : ℕ) (a : R) : - (p.update n a).coeff = Function.update p.coeff n a := by - ext - simp only [coeff, update, Function.update_apply, coe_update, AddMonoidAlgebra.update, ofCoeff, - AddMonoidAlgebra.coeff] + (p.update n a).coeff = Function.update p.coeff n a := by ext; simp [coeff, update] theorem coeff_update_apply (p : R[X]) (n : ℕ) (a : R) (i : ℕ) : (p.update n a).coeff i = if i = n then a else p.coeff i := by @@ -1034,10 +1021,7 @@ theorem update_zero_eq_erase (p : R[X]) (n : ℕ) : p.update n 0 = p.erase n := theorem support_update (p : R[X]) (n : ℕ) (a : R) [Decidable (a = 0)] : support (p.update n a) = if a = 0 then p.support.erase n else insert n p.support := by - classical - simp only [support, update, Finsupp.support_update, AddMonoidAlgebra.update, ofCoeff, - AddMonoidAlgebra.coeff] - congr + classical simp [support, update, Finsupp.support_update] theorem support_update_zero (p : R[X]) (n : ℕ) : support (p.update n 0) = p.support.erase n := by rw [update_zero_eq_erase, support_erase] @@ -1130,18 +1114,12 @@ instance ring : Ring R[X] := toFinsupp_mul toFinsupp_neg toFinsupp_sub (fun _ _ ↦ toFinsupp_nsmul _ _) (fun _ _ ↦ toFinsupp_zsmul _ _) toFinsupp_pow (fun _ ↦ rfl) fun _ ↦ rfl -set_option backward.isDefEq.respectTransparency false in @[simp] -theorem coeff_neg (p : R[X]) (n : ℕ) : coeff (-p) n = -coeff p n := by - rcases p with ⟨⟩ - rw [← ofFinsupp_neg, coeff, coeff, Finsupp.neg_apply] +theorem coeff_neg (p : R[X]) (n : ℕ) : coeff (-p) n = -coeff p n := by simp [coeff] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem coeff_sub (p q : R[X]) (n : ℕ) : coeff (p - q) n = coeff p n - coeff q n := by - rcases p with ⟨⟩ - rcases q with ⟨⟩ - rw [← ofFinsupp_sub, coeff, coeff, coeff, Finsupp.sub_apply] + simp [coeff, sub_eq_add_neg] @[simp] theorem monomial_neg (n : ℕ) (a : R) : monomial n (-a) = -monomial n a := by @@ -1150,11 +1128,8 @@ theorem monomial_neg (n : ℕ) (a : R) : monomial n (-a) = -monomial n a := by theorem monomial_sub (n : ℕ) : monomial n (a - b) = monomial n a - monomial n b := by rw [sub_eq_add_neg, map_add, monomial_neg, sub_eq_add_neg] -set_option backward.isDefEq.respectTransparency false in @[simp] -theorem support_neg {p : R[X]} : (-p).support = p.support := by - rcases p with ⟨⟩ - rw [← ofFinsupp_neg, support, support, Finsupp.support_neg] +theorem support_neg {p : R[X]} : (-p).support = p.support := by simp [support] theorem C_eq_intCast (n : ℤ) : C (n : R) = n := by simp diff --git a/Mathlib/Algebra/Polynomial/Basis.lean b/Mathlib/Algebra/Polynomial/Basis.lean index 0a51748fe1bb58..c0028424bcd382 100644 --- a/Mathlib/Algebra/Polynomial/Basis.lean +++ b/Mathlib/Algebra/Polynomial/Basis.lean @@ -14,7 +14,7 @@ public import Mathlib.LinearAlgebra.Basis.Defs -/ -@[expose] public section +@[expose] public noncomputable section open Module @@ -27,7 +27,7 @@ namespace Polynomial /-- The monomials form a basis on `R[X]`. To get the rank of a polynomial ring, use this and `Basis.mk_eq_rank`. -/ def basisMonomials : Basis ℕ R R[X] := - Basis.ofRepr (toFinsuppIsoLinear R) + .ofRepr <| (toFinsuppIsoLinear R).trans <| AddMonoidAlgebra.coeffLinearEquiv _ @[simp] theorem coe_basisMonomials : (basisMonomials R : ℕ → R[X]) = fun s => monomial s 1 := diff --git a/Mathlib/Algebra/Polynomial/Cardinal.lean b/Mathlib/Algebra/Polynomial/Cardinal.lean index e926c9dcdaf6cf..86d5b3634034a7 100644 --- a/Mathlib/Algebra/Polynomial/Cardinal.lean +++ b/Mathlib/Algebra/Polynomial/Cardinal.lean @@ -5,6 +5,7 @@ Authors: Chris Hughes, Junyan Xu -/ module +public import Mathlib.Algebra.MonoidAlgebra.Cardinal public import Mathlib.Algebra.Polynomial.Basic public import Mathlib.SetTheory.Cardinal.Finsupp @@ -17,22 +18,18 @@ of `#R` and `ℵ₀`. public section +open Cardinal Fintype -universe u - -open Cardinal Polynomial - -open Cardinal +universe u v +variable {R : Type u} {M : Type v} [Semiring R] namespace Polynomial @[simp] -theorem cardinalMk_eq_max {R : Type u} [Semiring R] [Nontrivial R] : #(R[X]) = max #R ℵ₀ := - (toFinsuppIso R).toEquiv.cardinal_eq.trans <| by - rw [AddMonoidAlgebra, mk_finsupp_lift_of_infinite, lift_uzero, max_comm] - rfl +lemma cardinalMk_eq_max {R : Type u} [Semiring R] [Nontrivial R] : #(R[X]) = max #R ℵ₀ := by + simp [(toFinsuppIso R).toEquiv.cardinal_eq] -theorem cardinalMk_le_max {R : Type u} [Semiring R] : #(R[X]) ≤ max #R ℵ₀ := by +lemma cardinalMk_le_max {R : Type u} [Semiring R] : #(R[X]) ≤ max #R ℵ₀ := by cases subsingleton_or_nontrivial R · exact (mk_eq_one _).trans_le (le_max_of_le_right one_le_aleph0) · exact cardinalMk_eq_max.le diff --git a/Mathlib/Algebra/Polynomial/Coeff.lean b/Mathlib/Algebra/Polynomial/Coeff.lean index fc6447e5112e30..b098d6d5f05c6d 100644 --- a/Mathlib/Algebra/Polynomial/Coeff.lean +++ b/Mathlib/Algebra/Polynomial/Coeff.lean @@ -59,9 +59,9 @@ theorem support_smul [SMulZeroClass S R] (r : S) (p : R[X]) : open scoped Pointwise in theorem card_support_mul_le : #(p * q).support ≤ #p.support * #q.support := by calc #(p * q).support - _ = #(p.toFinsupp * q.toFinsupp).support := by rw [← support_toFinsupp, toFinsupp_mul] - _ ≤ #(p.toFinsupp.support + q.toFinsupp.support) := - Finset.card_le_card (AddMonoidAlgebra.support_mul p.toFinsupp q.toFinsupp) + _ = #(p.toFinsupp * q.toFinsupp).coeff.support := by rw [← support_toFinsupp, toFinsupp_mul] + _ ≤ #(p.toFinsupp.coeff.support + q.toFinsupp.coeff.support) := by + grw [AddMonoidAlgebra.support_coeff_mul_subset] _ ≤ #p.support * #q.support := Finset.card_image₂_le .. /-- `Polynomial.sum` as a linear map. -/ @@ -112,7 +112,7 @@ theorem coeff_mul (p q : R[X]) (n : ℕ) : coeff (p * q) n = ∑ x ∈ antidiagonal n, coeff p x.1 * coeff q x.2 := by rcases p with ⟨p⟩; rcases q with ⟨q⟩ simp_rw [← ofFinsupp_mul, coeff] - exact AddMonoidAlgebra.mul_apply_antidiagonal p q n _ Finset.mem_antidiagonal + exact AddMonoidAlgebra.coeff_mul_antidiag p q n _ Finset.mem_antidiagonal @[simp] theorem mul_coeff_zero (p q : R[X]) : coeff (p * q) 0 = coeff p 0 * coeff q 0 := by simp [coeff_mul] @@ -154,7 +154,7 @@ theorem coeff_C_mul_X (x : R) (n : ℕ) : coeff (C x * X : R[X]) n = if n = 1 th theorem coeff_C_mul (p : R[X]) : coeff (C a * p) n = a * coeff p n := by rcases p with ⟨p⟩ simp_rw [← monomial_zero_left, ← ofFinsupp_single, ← ofFinsupp_mul, coeff] - exact AddMonoidAlgebra.single_zero_mul_apply p a n + exact p.coeff_single_zero_mul a n theorem C_mul' (a : R) (f : R[X]) : C a * f = a • f := by ext @@ -164,7 +164,7 @@ theorem C_mul' (a : R) (f : R[X]) : C a * f = a • f := by theorem coeff_mul_C (p : R[X]) (n : ℕ) (a : R) : coeff (p * C a) n = coeff p n * a := by rcases p with ⟨p⟩ simp_rw [← monomial_zero_left, ← ofFinsupp_single, ← ofFinsupp_mul, coeff] - exact AddMonoidAlgebra.mul_single_zero_apply p a n + exact p.coeff_mul_single_zero a n @[simp] lemma coeff_mul_natCast {a k : ℕ} : coeff (p * (a : R[X])) k = coeff p k * (↑a : R) := coeff_mul_C _ _ _ diff --git a/Mathlib/Algebra/Polynomial/Degree/Defs.lean b/Mathlib/Algebra/Polynomial/Degree/Defs.lean index 3119fcb7074168..6d775d7dbf5d86 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Defs.lean @@ -325,7 +325,7 @@ variable {p q : R[X]} {ι : Type*} theorem degree_add_le (p q : R[X]) : degree (p + q) ≤ max (degree p) (degree q) := by simpa only [degree, ← support_toFinsupp, toFinsupp_add] - using! AddMonoidAlgebra.sup_support_add_le _ _ _ + using! AddMonoidAlgebra.sup_support_coeff_add_le _ _ _ theorem degree_add_le_of_degree_le {p q : R[X]} {n : ℕ} (hp : degree p ≤ n) (hq : degree q ≤ n) : degree (p + q) ≤ n := @@ -366,8 +366,6 @@ theorem natDegree_C_mul_X_pow_le (a : R) (n : ℕ) : natDegree (C a * X ^ n) ≤ natDegree_le_iff_degree_le.2 <| degree_C_mul_X_pow_le _ _ theorem degree_erase_le (p : R[X]) (n : ℕ) : degree (p.erase n) ≤ degree p := by - simp only [erase_def, AddMonoidAlgebra.erase, AddMonoidAlgebra.coeff, AddMonoidAlgebra.ofCoeff, - degree, support] apply sup_mono simpa using Finset.erase_subset .. @@ -394,7 +392,7 @@ theorem degree_sum_le (s : Finset ι) (f : ι → R[X]) : _ ≤ _ := by rw [sup_cons]; exact max_le_max le_rfl ih theorem degree_mul_le (p q : R[X]) : degree (p * q) ≤ degree p + degree q := by - simpa [degree, ← support_toFinsupp] using! AddMonoidAlgebra.sup_support_mul_le (by simp) .. + simpa [degree, ← support_toFinsupp] using! AddMonoidAlgebra.sup_support_coeff_mul_le (by simp) .. theorem degree_mul_le_of_le {a b : WithBot ℕ} (hp : degree p ≤ a) (hq : degree q ≤ b) : degree (p * q) ≤ a + b := by grw [degree_mul_le, hp, hq] diff --git a/Mathlib/Algebra/Polynomial/Derivative.lean b/Mathlib/Algebra/Polynomial/Derivative.lean index ba8ca6254097ba..0005c6c05137f9 100644 --- a/Mathlib/Algebra/Polynomial/Derivative.lean +++ b/Mathlib/Algebra/Polynomial/Derivative.lean @@ -319,8 +319,9 @@ theorem iterate_derivative_mul {n} (p q : R[X]) : n.choose k • (derivative^[n - k + 1] p * derivative^[k] q)) + ∑ k ∈ range n.succ, n.choose k • (derivative^[n - k] p * derivative^[k + 1] q) := by - simp_rw [derivative_sum, derivative_smul, derivative_mul, Function.iterate_succ_apply', - smul_add, sum_add_distrib] + simp only [Nat.succ_eq_add_one, nsmul_eq_mul, derivative_mul, derivative_natCast, zero_mul, + derivative_sum, zero_add, Function.iterate_succ', Function.comp_apply] + simp_rw [mul_add, sum_add_distrib] _ = (∑ k ∈ range n.succ, n.choose k.succ • (derivative^[n - k] p * derivative^[k + 1] q)) + 1 • (derivative^[n + 1] p * derivative^[0] q) + @@ -538,9 +539,7 @@ theorem iterate_derivative_X_add_pow (n k : ℕ) (c : R) : induction k with | zero => simp | succ k IH => - rw [Nat.sub_succ', Function.iterate_succ_apply', IH, derivative_smul, - derivative_X_add_C_pow, map_natCast, Nat.descFactorial_succ, nsmul_eq_mul, nsmul_eq_mul, - Nat.cast_mul] + simp [Nat.sub_succ', Function.iterate_succ_apply', IH, derivative_X_add_C_pow] ring theorem iterate_derivative_mul_X_pow (n m : ℕ) (p : R[X]) : diff --git a/Mathlib/Algebra/Polynomial/Eval/Coeff.lean b/Mathlib/Algebra/Polynomial/Eval/Coeff.lean index 88bc89fb77245b..93083ce9d221a6 100644 --- a/Mathlib/Algebra/Polynomial/Eval/Coeff.lean +++ b/Mathlib/Algebra/Polynomial/Eval/Coeff.lean @@ -95,10 +95,10 @@ def piEquiv {ι} [Finite ι] (R : ι → Type*) [∀ i, Semiring (R i)] : (∀ i, R i)[X] ≃+* ∀ i, (R i)[X] := .ofBijective (RingHom.pi fun i ↦ mapRingHom (Pi.evalRingHom R i)) ⟨fun p q h ↦ by ext n i; simpa using congr_arg (fun p ↦ coeff (p i) n) h, - fun p ↦ ⟨.ofFinsupp (.ofSupportFinite (fun n i ↦ coeff (p i) n) <| + fun p ↦ ⟨.ofFinsupp <| .ofCoeff <| .ofSupportFinite (fun n i ↦ coeff (p i) n) <| (Set.finite_iUnion fun i ↦ (p i).support.finite_toSet).subset fun n hn ↦ by simp only [Set.mem_iUnion, Finset.mem_coe, mem_support_iff, Function.mem_support] at hn ⊢ - contrapose! hn; exact funext hn), by ext i n; exact coeff_map _ _⟩⟩ + contrapose! hn; exact funext hn, by ext i n; exact coeff_map _ _⟩⟩ theorem map_injective (hf : Function.Injective f) : Function.Injective (map f) := fun p q h => ext fun m => hf <| by rw [← coeff_map f, ← coeff_map f, h] diff --git a/Mathlib/Algebra/Polynomial/HasseDeriv.lean b/Mathlib/Algebra/Polynomial/HasseDeriv.lean index a364bbc159e581..ec054db563a362 100644 --- a/Mathlib/Algebra/Polynomial/HasseDeriv.lean +++ b/Mathlib/Algebra/Polynomial/HasseDeriv.lean @@ -124,6 +124,7 @@ theorem hasseDeriv_X (hk : 1 < k) : hasseDeriv k (X : R[X]) = 0 := by rw [← monomial_one_one_eq_X, hasseDeriv_monomial, Nat.choose_eq_zero_of_lt hk, Nat.cast_zero, zero_mul, monomial_zero_right] +set_option backward.isDefEq.respectTransparency false in theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by induction k with | zero => rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe] @@ -145,6 +146,7 @@ theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivativ congr rw [add_assoc, add_tsub_cancel_left] +set_option backward.isDefEq.respectTransparency false in theorem hasseDeriv_comp (k l : ℕ) : (@hasseDeriv R _ k).comp (hasseDeriv l) = (k + l).choose k • hasseDeriv (k + l) := by ext i : 2 diff --git a/Mathlib/Algebra/Polynomial/Homogenize.lean b/Mathlib/Algebra/Polynomial/Homogenize.lean index 5d2569c504ed10..82374567b2168e 100644 --- a/Mathlib/Algebra/Polynomial/Homogenize.lean +++ b/Mathlib/Algebra/Polynomial/Homogenize.lean @@ -282,7 +282,8 @@ lemma sum_eq_natDegree_of_mem_support_homogenize (p : R[X]) {s : Fin 2 →₀ /-- Summing a function over the coefficients of the homogenization of a polynomial `p` (of degree `p.natDegree`) gives the same result as summing over the coefficients of `p`. -/ lemma finsuppSum_homogenize_eq {M : Type*} [AddCommMonoid M] (p : R[X]) {f : R → M} : - (Finsupp.sum (p.homogenize p.natDegree) fun _ c ↦ f c) = p.sum fun _ c ↦ f c := by + (AddMonoidAlgebra.coeff <| p.homogenize p.natDegree).sum (fun _ c ↦ f c) = + p.sum fun _ c ↦ f c := by rw [MvPolynomial.sum_def, sum_def p] -- We set up a bijection between the sets indexing the terms on both sides -- and show that it maps the terms in the one sum to those in the other. diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index c0c049fb4ab09e..e7c7d9340ea465 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -90,8 +90,8 @@ scoped[LaurentPolynomial] notation:9000 R "[T;T⁻¹]" => LaurentPolynomial R open LaurentPolynomial @[ext] -theorem LaurentPolynomial.ext [Semiring R] {p q : R[T;T⁻¹]} (h : ∀ a, p a = q a) : p = q := - Finsupp.ext h +theorem LaurentPolynomial.ext [Semiring R] {p q : R[T;T⁻¹]} (h : ∀ a, p.coeff a = q.coeff a) : + p = q := by ext; exact h _ /-- The ring homomorphism, taking a polynomial with coefficients in `R` to a Laurent polynomial with coefficients in `R`. -/ @@ -122,8 +122,7 @@ section Semiring variable [Semiring R] -theorem single_zero_one_eq_one : (.single 0 1 : R[T;T⁻¹]) = (1 : R[T;T⁻¹]) := - rfl +theorem single_zero_one_eq_one : (.single 0 1 : R[T;T⁻¹]) = 1 := rfl /-! ### The functions `C` and `T`. -/ @@ -145,18 +144,17 @@ theorem C_eq_algebraMap {R : Type*} [CommSemiring R] (r : R) : C r = algebraMap theorem single_eq_C (r : R) : .single 0 r = C r := rfl -@[simp] lemma C_apply (t : R) (n : ℤ) : C t n = if n = 0 then t else 0 := by - rw [← single_eq_C, Finsupp.single_apply]; aesop +@[simp] lemma C_apply (t : R) (n : ℤ) : (C t).coeff n = if n = 0 then t else 0 := by + simp [← single_eq_C]; aesop /-- The function `n ↦ T ^ n`, implemented as a sequence `ℤ → R[T;T⁻¹]`. Using directly `T ^ n` does not work, since we want the exponents to be of Type `ℤ` and there is no `ℤ`-power defined on `R[T;T⁻¹]`. Using that `T` is a unit introduces extra coercions. For these reasons, the definition of `T` is as a sequence. -/ -def T (n : ℤ) : R[T;T⁻¹] := - .single n 1 +def T (n : ℤ) : R[T;T⁻¹] := .single n 1 -@[simp] lemma T_apply (m n : ℤ) : (T n : R[T;T⁻¹]) m = if n = m then 1 else 0 := +@[simp] lemma T_apply (m n : ℤ) : (T n : R[T;T⁻¹]).coeff m = if n = m then 1 else 0 := Finsupp.single_apply @[simp] @@ -230,7 +228,6 @@ theorem invOf_T (n : ℤ) : ⅟(T n : R[T;T⁻¹]) = T (-n) := theorem isUnit_T (n : ℤ) : IsUnit (T n : R[T;T⁻¹]) := isUnit_of_invertible _ -set_option backward.isDefEq.respectTransparency false in @[elab_as_elim] protected theorem induction_on {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹]) (h_C : ∀ a, M (C a)) (h_add : ∀ {p q}, M p → M q → M (p + q)) @@ -242,16 +239,17 @@ protected theorem induction_on {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹]) (h_C · simpa only [T_zero, mul_one] using h_C a · exact fun m => h_C_mul_T m a · exact fun m => h_C_mul_T_Z m a - have B : ∀ s : Finset ℤ, M (s.sum fun n : ℤ => C (p n) * T n) := by + have B : ∀ s : Finset ℤ, M (s.sum fun n : ℤ => C (p.coeff n) * T n) := by apply Finset.induction · convert! h_C 0 simp only [Finset.sum_empty, map_zero] · intro n s ns ih rw [Finset.sum_insert ns] exact h_add A ih - convert! B p.support + convert! B p.coeff.support ext a simp_rw [← single_eq_C_mul_T] + simp only [AddMonoidAlgebra.coeff_sum, coeff_single] rw [Finset.sum_apply', Finset.sum_eq_single a, single_eq_same] · intro b _ hb rw [single_eq_of_ne' hb] @@ -281,39 +279,33 @@ theorem commute_T (n : ℤ) (f : R[T;T⁻¹]) : Commute (T n) f := theorem T_mul (n : ℤ) (f : R[T;T⁻¹]) : T n * f = f * T n := (commute_T n f).eq -set_option backward.isDefEq.respectTransparency false in theorem smul_eq_C_mul (r : R) (f : R[T;T⁻¹]) : r • f = C r * f := by induction f using LaurentPolynomial.induction_on' with | add _ _ hp hq => rw [smul_add, mul_add, hp, hq] | C_mul_T n s => rw [← mul_assoc, ← smul_mul_assoc, mul_left_inj_of_invertible, ← map_mul, ← single_eq_C, - Finsupp.smul_single'] + AddMonoidAlgebra.smul_single'] rfl /-- `trunc : R[T;T⁻¹] →+ R[X]` maps a Laurent polynomial `f` to the polynomial whose terms of nonnegative degree coincide with the ones of `f`. The terms of negative degree of `f` "vanish". `trunc` is a left-inverse to `Polynomial.toLaurent`. -/ def trunc : R[T;T⁻¹] →+ R[X] := - (toFinsuppIso R).symm.toAddMonoidHom.comp <| comapDomain.addMonoidHom fun _ _ => Int.ofNat.inj + (toFinsuppIso R).symm.toAddMonoidHom.comp <| comapDomainAddMonoidHom (↑) Nat.cast_injective @[simp] theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by apply (toFinsuppIso R).injective simp only [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply, - RingHom.toAddMonoidHom_eq_coe, RingEquiv.toRingHom_eq_coe, Int.ofNat_eq_natCast, + RingHom.toAddMonoidHom_eq_coe, RingEquiv.toRingHom_eq_coe, AddMonoidHom.coe_coe, RingHom.coe_coe, RingEquiv.apply_symm_apply, toFinsuppIso_apply] - -- We need `erw` to see through the identification of `Finsupp` with `LaurentSeries`. - erw [comapDomain.addMonoidHom_apply Int.ofNat_injective] - split_ifs with n0 - · rw [toFinsupp_monomial] - lift n to ℕ using n0 - apply comapDomain_single - · rw [toFinsupp_inj] - ext a + split_ifs with hn + · lift n to ℕ using hn + simp [toFinsupp_monomial, -single_eq_C_mul_T] + · ext a have : a ≠ n := by lia - simp only [coeff_ofFinsupp, comapDomain_apply, Int.ofNat_eq_natCast, Polynomial.coeff_zero, - single_eq_of_ne this] + simp [-single_eq_C_mul_T, single_eq_of_ne this] @[simp] theorem leftInverse_trunc_toLaurent : @@ -379,39 +371,28 @@ theorem reduce_to_polynomial_of_mul_T (f : R[T;T⁻¹]) {Q : R[T;T⁻¹] → Pro section Support -set_option backward.isDefEq.respectTransparency false in -theorem support_C_mul_T (a : R) (n : ℤ) : Finsupp.support (C a * T n) ⊆ {n} := by +theorem support_C_mul_T (a : R) (n : ℤ) : (C a * T n).coeff.support ⊆ {n} := by rw [← single_eq_C_mul_T] exact support_single_subset -set_option backward.isDefEq.respectTransparency false in -theorem support_C_mul_T_of_ne_zero {a : R} (a0 : a ≠ 0) (n : ℤ) : - Finsupp.support (C a * T n) = {n} := by +theorem support_coeff_C_mul_T_of_ne_zero {a : R} (a0 : a ≠ 0) (n : ℤ) : + (C a * T n).coeff.support = {n} := by rw [← single_eq_C_mul_T] exact support_single _ a0 -set_option backward.isDefEq.respectTransparency false in +@[deprecated (since := "2026-06-18")] +alias support_C_mul_T_of_ne_zero := support_coeff_C_mul_T_of_ne_zero + +@[simp] lemma coeff_toLaurent (f : R[X]) : + f.toLaurent.coeff = f.toFinsupp.coeff.mapDomain Nat.castEmbedding := rfl + /-- The support of a polynomial `f` is a finset in `ℕ`. The lemma `toLaurent_support f` shows that the support of `f.toLaurent` is the same finset, but viewed in `ℤ` under the natural inclusion `ℕ ↪ ℤ`. -/ -theorem toLaurent_support (f : R[X]) : f.toLaurent.support = f.support.map Nat.castEmbedding := by - generalize hd : f.support = s - revert f - refine Finset.induction_on s ?_ ?_ <;> clear s - · intro f hf - rw [Finset.map_empty, Finsupp.support_eq_empty, toLaurent_eq_zero] - exact Polynomial.support_eq_empty.mp hf - · intro a s as hf f fs - have : (erase a f).toLaurent.support = s.map Nat.castEmbedding := by - refine hf (f.erase a) ?_ - simp only [fs, Finset.erase_eq_of_notMem as, Polynomial.support_erase, - Finset.erase_insert_eq_erase] - rw [← monomial_add_erase f a, Finset.map_insert, ← this, map_add, Polynomial.toLaurent_C_mul_T, - support_add_eq, Finset.insert_eq] - · congr - exact support_C_mul_T_of_ne_zero (Polynomial.mem_support_iff.mp (by simp [fs])) _ - · rw [this] - exact Disjoint.mono_left (support_C_mul_T _ _) (by simpa) +theorem support_coeff_toLaurent (f : R[X]) : + f.toLaurent.coeff.support = f.support.map Nat.castEmbedding := by simp [Polynomial.support] + +@[deprecated (since := "2026-06-18")] alias toLaurent_support := support_coeff_toLaurent end Support @@ -421,28 +402,26 @@ section Degrees If `f : R[T;T⁻¹]` is a Laurent polynomial, then `f.degree` is the maximum of its support of `f`, or `⊥`, if `f = 0`. -/ def degree (f : R[T;T⁻¹]) : WithBot ℤ := - f.support.max + f.coeff.support.max @[simp] theorem degree_zero : degree (0 : R[T;T⁻¹]) = ⊥ := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] theorem degree_eq_bot_iff {f : R[T;T⁻¹]} : f.degree = ⊥ ↔ f = 0 := by refine ⟨fun h => ?_, fun h => by rw [h, degree_zero]⟩ ext n - simp only [coe_zero, Pi.zero_apply] + simp only [AddMonoidAlgebra.coeff_zero, coe_zero, Pi.ofNat_apply] simp_rw [degree, Finset.max_eq_sup_withBot, Finset.sup_eq_bot_iff, Finsupp.mem_support_iff, Ne, WithBot.coe_ne_bot, imp_false, not_not] at h exact h n section ExactDegrees -set_option backward.isDefEq.respectTransparency false in @[simp] theorem degree_C_mul_T (n : ℤ) (a : R) (a0 : a ≠ 0) : degree (C a * T n) = n := by - rw [degree, support_C_mul_T_of_ne_zero a0 n] + rw [degree, support_coeff_C_mul_T_of_ne_zero a0 n] exact Finset.max_singleton theorem degree_C_mul_T_ite [DecidableEq R] (n : ℤ) (a : R) : @@ -600,7 +579,8 @@ def invert : R[T;T⁻¹] ≃ₐ[R] R[T;T⁻¹] := AddMonoidAlgebra.domCongr R R @[simp] lemma invert_T (n : ℤ) : invert (T n : R[T;T⁻¹]) = T (-n) := AddMonoidAlgebra.domCongr_single .. -@[simp] lemma invert_apply (f : R[T;T⁻¹]) (n : ℤ) : invert f n = f (-n) := by simp [invert] +@[simp] lemma invert_apply (f : R[T;T⁻¹]) (n : ℤ) : (invert f).coeff n = f.coeff (-n) := by + simp [invert] @[simp] lemma invert_comp_C : invert ∘ (@C R _) = C := by ext; simp @@ -627,20 +607,16 @@ section SMulWithZero variable [Semiring R] [AddCommMonoid S] [SMulWithZero R S] [Monoid S] (f g : R[T;T⁻¹]) (x y : Sˣ) /-- Evaluate a Laurent polynomial at a unit, using scalar multiplication. -/ -def smeval : S := Finsupp.sum f fun n r => r • (x ^ n).val +def smeval : S := f.coeff.sum fun n r => r • (x ^ n).val -theorem smeval_eq_sum : f.smeval x = Finsupp.sum f fun n r => r • (x ^ n).val := rfl +theorem smeval_eq_sum : f.smeval x = f.coeff.sum fun n r => r • (x ^ n).val := rfl theorem smeval_congr : f = g → x = y → f.smeval x = g.smeval y := by rintro rfl rfl; rfl -set_option backward.isDefEq.respectTransparency false in -@[simp] -theorem smeval_zero : (0 : R[T;T⁻¹]).smeval x = (0 : S) := by - simp only [smeval_eq_sum, Finsupp.sum_zero_index] +@[simp] lemma smeval_zero : (0 : R[T;T⁻¹]).smeval x = (0 : S) := by simp [smeval] theorem smeval_single (n : ℤ) (r : R) : smeval (.single n r) x = r • (x ^ n).val := by - simp only [smeval_eq_sum] - rw [Finsupp.sum_single_index (zero_smul R (x ^ n).val)] + simp [smeval, -single_eq_C_mul_T] @[simp] theorem smeval_C_mul_T_n (n : ℤ) (r : R) : (C r * T n).smeval x = r • (x ^ n).val := by @@ -671,11 +647,9 @@ section Module variable [Semiring R] [AddCommMonoid S] [Module R S] [Monoid S] (f g : R[T;T⁻¹]) (x y : Sˣ) -set_option backward.isDefEq.respectTransparency false in @[simp] theorem smeval_add : (f + g).smeval x = f.smeval x + g.smeval x := by - simp only [smeval_eq_sum] - rw [Finsupp.sum_add_index (fun n _ => zero_smul R (x ^ n).val) (fun n _ r r' => add_smul r r' _)] + simp [smeval, Finsupp.sum_add_index, add_smul] @[simp] theorem smeval_C_mul (r : R) : (C r * f).smeval x = r • (f.smeval x) := by diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index db3de74f1a1582..962263ec309547 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -39,71 +39,151 @@ See https://leanprover.zulipchat.com/#narrow/stream/144837-PR-reviews/topic/.231 for the full discussion. -/ @[nolint unusedArguments] -def PolynomialModule (R M : Type*) [CommRing R] [AddCommGroup M] [Module R M] := ℕ →₀ M -deriving Inhabited, FunLike, AddCommGroup +structure PolynomialModule (R M : Type*) [CommRing R] [AddCommGroup M] [Module R M] where + /-- Construct an element of the polynomial module `M[[]]` from its coefficients `ℕ →₀ M`. -/ + ofCoeff (R) :: + /-- The coefficients `ℕ →₀ M` of an element of the additive monoid algebra `M[X]`. -/ + coeff : ℕ →₀ M -variable (R : Type*) {M : Type*} [CommRing R] [AddCommGroup M] [Module R M] (I : Ideal R) +variable {ι R M N : Type*} [CommRing R] [AddCommGroup M] [Module R M] (I : Ideal R) variable {S : Type*} [CommSemiring S] [Algebra S R] [Module S M] [IsScalarTower S R M] namespace PolynomialModule +variable {x y : PolynomialModule R M} {r r₁ r₂ : R} {m m' m₁ m₂ m₁' m₂' : M} + +lemma coeff_ofCoeff (x : ℕ →₀ M) : (ofCoeff R x).coeff = x := rfl +lemma ofCoeff_coeff (x : PolynomialModule R M) : ofCoeff R x.coeff = x := rfl + +variable (R) in +/-- `PolynomialModule.coeff` as an equiv. -/ +@[simps! apply symm_apply] +def coeffEquiv : PolynomialModule R M ≃ (ℕ →₀ M) where + toFun := coeff + invFun := ofCoeff R + left_inv _ := rfl + right_inv _ := rfl + +lemma «forall» {P : PolynomialModule R M → Prop} : (∀ p, P p) ↔ ∀ q, P (ofCoeff R q) := + (coeffEquiv R).forall_congr_left + +lemma «exists» {P : PolynomialModule R M → Prop} : (∃ p, P p) ↔ ∃ q, P (ofCoeff R q) := + (coeffEquiv R).exists_congr_left + +lemma coeff_injective : (coeff : PolynomialModule R M → ℕ →₀ M).Injective := + (coeffEquiv R).injective + +lemma ofCoeff_injective : (ofCoeff R : (ℕ →₀ M) → PolynomialModule R M).Injective := + (coeffEquiv R).symm.injective -/-- Workaround to defeq problems: if we interpret a `PolynomialModule` as a `Finsupp`, also transfer -the `DFunLike` instance. -/ @[simp] -theorem funLike_eq (x : PolynomialModule R M) : - DFunLike.coe (self := Finsupp.instFunLike) x = x := rfl +lemma coeff_inj : x.coeff = y.coeff ↔ x = y := coeff_injective.eq_iff -/-- This is required to have the `IsScalarTower S R M` instance to avoid diamonds. -/ -instance : Module S (PolynomialModule R M) := - inferInstanceAs <| Module S (ℕ →₀ M) +lemma ofCoeff_inj {x y : ℕ →₀ M} : ofCoeff R x = ofCoeff R y ↔ x = y := ofCoeff_injective.eq_iff -theorem zero_apply (i : ℕ) : (0 : PolynomialModule R M) i = 0 := - Finsupp.zero_apply +@[ext] alias ⟨ext, _⟩ := coeff_inj -theorem add_apply (g₁ g₂ : PolynomialModule R M) (a : ℕ) : (g₁ + g₂) a = g₁ a + g₂ a := - Finsupp.add_apply g₁ g₂ a +instance instInhabited : Inhabited (PolynomialModule R M) := fast_instance% (coeffEquiv R).inhabited -/-- The monomial `m * x ^ i`. This is defeq to `Finsupp.singleAddHom`, and is redefined here -so that it has the desired type signature. -/ -def single (i : ℕ) : M →+ PolynomialModule R M := - Finsupp.singleAddHom i +instance instNontrivial [Nontrivial M] : Nontrivial (PolynomialModule R M) := + (coeffEquiv R).nontrivial -theorem single_apply (i : ℕ) (m : M) (n : ℕ) : single R i m n = ite (i = n) m 0 := - Finsupp.single_apply +instance instUnique [Subsingleton M] : Unique (PolynomialModule R M) := fast_instance% + (coeffEquiv R).unique + +instance instDecidableEq [DecidableEq M] : DecidableEq (PolynomialModule R M) := + (coeffEquiv R).decidableEq + +instance instAddCommGroup : AddCommGroup (PolynomialModule R M) := fast_instance% + (coeffEquiv R).addCommGroup + +/-- `PolynomialModule.coeff` as an `AddEquiv`. -/ +@[simps! apply symm_apply] +def coeffAddEquiv : PolynomialModule R M ≃+ (ℕ →₀ M) := (coeffEquiv R).addEquiv + +@[simp] lemma coeff_zero : coeff (0 : PolynomialModule R M) = 0 := rfl +@[simp] lemma ofCoeff_zero : (ofCoeff R 0 : PolynomialModule R M) = 0 := rfl +@[simp] lemma coeff_eq_zero : coeff x = 0 ↔ x = 0 := coeff_inj +@[simp] lemma ofCoeff_eq_zero {x : ℕ →₀ M} : ofCoeff R x = 0 ↔ x = 0 := + ofCoeff_inj + +@[simp] lemma coeff_add (x y : PolynomialModule R M) : coeff (x + y) = coeff x + coeff y := rfl +@[simp] lemma ofCoeff_add (x y : ℕ →₀ M) : ofCoeff R (x + y) = ofCoeff R x + ofCoeff R y := rfl + +@[simp] +lemma coeff_sum (s : Finset ι) (f : ι → PolynomialModule R M) : + coeff (∑ i ∈ s, f i) = ∑ i ∈ s, coeff (f i) := map_sum coeffAddEquiv .. + +@[simp] +lemma ofCoeff_sum (s : Finset ι) (f : ι → ℕ →₀ M) : + ofCoeff R (∑ i ∈ s, f i) = ∑ i ∈ s, ofCoeff R (f i) := map_sum coeffAddEquiv.symm .. + +@[simp] +lemma coeff_finsuppSum [AddCommMonoid N] (f : ι →₀ N) (g : ι → N → PolynomialModule R M) : + coeff (f.sum g) = f.sum (fun i n ↦ coeff (g i n)) := map_finsuppSum coeffAddEquiv .. + +@[simp] +lemma ofCoeff_finsuppSum [AddCommMonoid N] (f : ι →₀ N) (g : ι → N → ℕ →₀ M) : + ofCoeff R (f.sum g) = f.sum (fun i n ↦ ofCoeff R (g i n)) := + map_finsuppSum coeffAddEquiv.symm .. + +variable (R) in +/-- `MonoidAlgebra.single n m` for `m : M`, `r : R` is the element `rm : PolynomialModule R M`. -/ +def single (n : ℕ) (m : M) : PolynomialModule R M := .ofCoeff R <| .single n m + +@[simp] lemma coeff_single (n : ℕ) (m : M) : (single R n m).coeff = .single n m := rfl +@[simp] lemma ofCoeff_single (n : ℕ) (m : M) : ofCoeff R (.single n m) = single R n m := rfl + +@[deprecated (since := "2026-06-18")] alias single_apply := coeff_single + +@[simp] lemma single_zero (n : ℕ) : single R n (0 : M) = 0 := by simp [single] + +@[simp] +lemma single_add (n : ℕ) (m₁ m₂ : M) : + single R n (m₁ + m₂) = single R n m₁ + single R n m₂ := by ext; simp + +/-- This is required to have the `IsScalarTower S R M` instance to avoid diamonds. -/ +instance : Module S (PolynomialModule R M) := (coeffEquiv R).module _ + +instance (M : Type u) [AddCommGroup M] [Module R M] [Module S M] [IsScalarTower S R M] : + IsScalarTower S R (PolynomialModule R M) := (coeffEquiv R).isScalarTower _ _ + +variable (R S) in +/-- `PolynomialModule.coeff` as a linear equiv. -/ +@[simps! apply symm_apply] +def coeffLinearEquiv : PolynomialModule R M ≃ₗ[S] ℕ →₀ M := (coeffEquiv _).linearEquiv _ +variable (R) in /-- `PolynomialModule.single` as a linear map. -/ def lsingle (i : ℕ) : M →ₗ[R] PolynomialModule R M := - Finsupp.lsingle i + (coeffLinearEquiv R R).symm.comp <| Finsupp.lsingle i -theorem lsingle_apply (i : ℕ) (m : M) (n : ℕ) : lsingle R i m n = ite (i = n) m 0 := +theorem lsingle_apply (i : ℕ) (m : M) (n : ℕ) : (lsingle R i m).coeff n = ite (i = n) m 0 := Finsupp.single_apply theorem single_smul (i : ℕ) (r : R) (m : M) : single R i (r • m) = r • single R i m := (lsingle R i).map_smul r m -variable {R} - @[elab_as_elim] -theorem induction_linear {motive : PolynomialModule R M → Prop} (f : PolynomialModule R M) - (zero : motive 0) (add : ∀ f g, motive f → motive g → motive (f + g)) - (single : ∀ a b, motive (single R a b)) : motive f := - Finsupp.induction_linear f zero add single +lemma induction_linear {p : PolynomialModule R M → Prop} (x : PolynomialModule R M) (zero : p 0) + (add : ∀ x y : PolynomialModule R M, p x → p y → p (x + y)) + (single : ∀ n m, p (single R n m)) : p x := + Finsupp.induction_linear (motive := (p <| ofCoeff R ·)) x.coeff zero (fun _ _ ↦ add _ _) + (fun _ _ ↦ single _ _) instance polynomialModule : Module R[X] (PolynomialModule R M) := - inferInstanceAs <| Module R[X] (Module.AEval' (Finsupp.lmapDomain M R Nat.succ)) + inferInstanceAs <| Module R[X] <| Module.AEval' <| (coeffLinearEquiv R R).symm.comp <| + (Finsupp.lmapDomain M R Nat.succ).comp (coeffLinearEquiv R R).toLinearMap lemma smul_def (f : R[X]) (m : PolynomialModule R M) : - f • m = aeval (Finsupp.lmapDomain M R Nat.succ) f m := by + f • m = aeval ((coeffLinearEquiv R R).symm.comp <| + (Finsupp.lmapDomain M R Nat.succ).comp (coeffLinearEquiv R R).toLinearMap) f m := by rfl -instance (M : Type u) [AddCommGroup M] [Module R M] [Module S M] [IsScalarTower S R M] : - IsScalarTower S R (PolynomialModule R M) := - Finsupp.isScalarTower _ _ - instance isScalarTower' (M : Type u) [AddCommGroup M] [Module R M] [Module S M] [IsScalarTower S R M] : IsScalarTower S R[X] (PolynomialModule R M) := by haveI : IsScalarTower R R[X] (PolynomialModule R M) := - inferInstanceAs <| IsScalarTower R R[X] <| Module.AEval' <| Finsupp.lmapDomain M R Nat.succ + inferInstanceAs <| IsScalarTower R R[X] <| Module.AEval' <| (coeffLinearEquiv R R).symm.comp <| + (Finsupp.lmapDomain M R Nat.succ).comp (coeffLinearEquiv R R).toLinearMap constructor intro x y z rw [← @IsScalarTower.algebraMap_smul S R, ← @IsScalarTower.algebraMap_smul S R, smul_assoc] @@ -116,12 +196,12 @@ theorem monomial_smul_single (i : ℕ) (r : R) (j : ℕ) (m : M) : induction i generalizing r j m with | zero => rw [Function.iterate_zero, zero_add] - exact Finsupp.smul_single r j m + exact congr(ofCoeff R $(Finsupp.smul_single r j m)) | succ n hn => rw [Function.iterate_succ, Function.comp_apply, add_assoc, ← hn] congr 2 rw [Nat.one_add] - exact Finsupp.mapDomain_single + exact congr(ofCoeff R $(Finsupp.mapDomain_single)) @[simp] theorem monomial_smul_lsingle (i : ℕ) (r : R) (j : ℕ) (m : M) : @@ -130,79 +210,57 @@ theorem monomial_smul_lsingle (i : ℕ) (r : R) (j : ℕ) (m : M) : @[simp] theorem monomial_smul_apply (i : ℕ) (r : R) (g : PolynomialModule R M) (n : ℕ) : - (monomial i r • g) n = ite (i ≤ n) (r • g (n - i)) 0 := by + (monomial i r • g).coeff n = ite (i ≤ n) (r • g.coeff (n - i)) 0 := by induction g using PolynomialModule.induction_linear with - | zero => simp only [smul_zero, zero_apply, ite_self] - | add p q hp hq => - simp only [smul_add, add_apply, hp, hq] - split_ifs - exacts [rfl, zero_add 0] + | zero => simp + | add p q hp hq => simp [smul_add, hp, hq, ite_add_ite] | single => - rw [monomial_smul_single, single_apply, single_apply, smul_ite, smul_zero, ← ite_and] + simp [monomial_smul_single, Finsupp.single_apply] grind @[simp] theorem smul_single_apply (i : ℕ) (f : R[X]) (m : M) (n : ℕ) : - (f • single R i m) n = ite (i ≤ n) (f.coeff (n - i) • m) 0 := by + (f • single R i m).coeff n = ite (i ≤ n) (f.coeff (n - i) • m) 0 := by induction f using Polynomial.induction_on' with - | add p q hp hq => - rw [add_smul, add_apply, hp, hq, coeff_add, add_smul] - split_ifs - exacts [rfl, zero_add 0] - | monomial => grind [monomial_smul_single, single_apply, coeff_monomial, zero_smul] + | add p q hp hq => simp [add_smul, hp, hq, ite_add_ite] + | monomial => simp; grind [monomial_smul_single, coeff_monomial, zero_smul] theorem smul_apply (f : R[X]) (g : PolynomialModule R M) (n : ℕ) : - (f • g) n = ∑ x ∈ Finset.antidiagonal n, f.coeff x.1 • g x.2 := by + (f • g).coeff n = ∑ x ∈ Finset.antidiagonal n, f.coeff x.1 • g.coeff x.2 := by induction f using Polynomial.induction_on' with - | add p q hp hq => - rw [add_smul, add_apply, hp, hq, ← Finset.sum_add_distrib] - congr - ext - rw [coeff_add, add_smul] + | add p q hp hq => simp [add_smul, hp, hq, ← Finset.sum_add_distrib] | monomial f_n f_a => - rw [Finset.Nat.sum_antidiagonal_eq_sum_range_succ fun i j => (monomial f_n f_a).coeff i • g j, - monomial_smul_apply] - simp_rw [Polynomial.coeff_monomial, ← Finset.mem_range_succ_iff] - simp + rw [Finset.Nat.sum_antidiagonal_eq_sum_range_succ fun i j => + (monomial f_n f_a).coeff i • g.coeff j, monomial_smul_apply] + simp [Polynomial.coeff_monomial] set_option backward.isDefEq.respectTransparency false in /-- `PolynomialModule R R` is isomorphic to `R[X]` as an `R[X]` module. -/ -def equivPolynomialSelf : PolynomialModule R R ≃ₗ[R[X]] R[X] := - { (Polynomial.toFinsuppIso R).symm with - map_smul' := fun r x => by - dsimp only [RingEquiv.toEquiv_eq_coe, RingEquiv.coe_toEquiv_symm, Equiv.toFun_as_coe, - RingHom.id_apply, smul_eq_mul, RingEquiv.coe_coe_toEquiv_symm] - induction x using induction_linear with - | zero => rw [smul_zero, map_zero, mul_zero] - | add _ _ hp hq => rw [smul_add, map_add, map_add, mul_add, hp, hq] - | single n a => - ext i - simp_rw [toFinsuppIso_symm_apply, coeff_ofFinsupp, coeff_mul, funLike_eq, smul_single_apply, - smul_eq_mul, coeff_ofFinsupp, funLike_eq, single_apply, mul_ite, mul_zero] - split_ifs with hn - · rw [Finset.sum_eq_single (i - n, n)] - · simp only [ite_true] - · rintro ⟨p, q⟩ hpq1 hpq2 - rw [Finset.mem_antidiagonal] at hpq1 - split_ifs with H - · dsimp at H - exfalso - apply hpq2 - rw [← hpq1, H] - simp only [add_tsub_cancel_right] - · rfl - · intro H - exfalso - apply H - rw [Finset.mem_antidiagonal, tsub_add_cancel_of_le hn] - · symm - rw [Finset.sum_ite_of_false, Finset.sum_const_zero] - grind [Finset.mem_antidiagonal] } +def equivPolynomialSelf : PolynomialModule R R ≃ₗ[R[X]] R[X] where + toAddEquiv := coeffAddEquiv.trans <| AddMonoidAlgebra.coeffAddEquiv.symm.trans + (toFinsuppIso R).symm.toAddEquiv + map_smul' r x := by + dsimp + induction x using induction_linear with + | zero => simp + | add _ _ hp hq => simp_all [smul_add, mul_add] + | single n a => + ext i + simp only [coeffAddEquiv_apply, AddMonoidAlgebra.coeffAddEquiv_symm_apply, + toFinsuppIso_symm_apply, coeff_ofFinsupp, smul_single_apply, smul_eq_mul, coeff_single, + AddMonoidAlgebra.ofCoeff_single, ofFinsupp_single] + split_ifs with hn + · rw [show i = (i - n) + n by lia, Polynomial.coeff_mul_monomial] + simp + · rw [Polynomial.coeff_mul, Finset.sum_eq_zero] + simp [Polynomial.coeff_monomial] + lia /-- `PolynomialModule R S` is isomorphic to `S[X]` as an `R` module. -/ -def equivPolynomial {S : Type*} [CommRing S] [Algebra R S] : - PolynomialModule R S ≃ₗ[R] S[X] := - { (Polynomial.toFinsuppIso S).symm with map_smul' := fun _ _ => rfl } +def equivPolynomial {S : Type*} [CommRing S] [Algebra R S] : PolynomialModule R S ≃ₗ[R] S[X] where + toAddEquiv := coeffAddEquiv.trans <| AddMonoidAlgebra.coeffAddEquiv.symm.trans + (toFinsuppIso _).symm.toAddEquiv + map_smul' _ _ := rfl @[simp] lemma equivPolynomialSelf_apply_eq (p : PolynomialModule R R) : @@ -212,6 +270,14 @@ lemma equivPolynomialSelf_apply_eq (p : PolynomialModule R R) : lemma equivPolynomial_single {S : Type*} [CommRing S] [Algebra R S] (n : ℕ) (x : S) : equivPolynomial (single R n x) = monomial n x := rfl +@[simp] +lemma equivPolynomial_symm_monomial {S : Type*} [CommRing S] [Algebra R S] (n : ℕ) (x : S) : + equivPolynomial.symm (monomial n x) = single R n x := rfl + +@[simp] +lemma equivPolynomial_symm_one {S : Type*} [CommRing S] [Algebra R S] : + equivPolynomial.symm (1 : S[X]) = single R 0 1 := rfl + variable (R' : Type*) {M' : Type*} [CommRing R'] [AddCommGroup M'] [Module R' M'] variable [Module R M'] @@ -219,16 +285,19 @@ variable [Module R M'] after pre-composition with every `lsingle R a` are equal. -/ @[ext high] theorem hom_ext {f g : PolynomialModule R M →ₗ[R] M'} - (h : ∀ a, f ∘ₗ lsingle R a = g ∘ₗ lsingle R a) : f = g := - Finsupp.lhom_ext' h + (h : ∀ a, f ∘ₗ lsingle R a = g ∘ₗ lsingle R a) : f = g := by + simpa [← DFunLike.coe_fn_eq, funext_iff, PolynomialModule.forall] using Finsupp.lhom_ext' + (φ := f.comp (coeffLinearEquiv R R).symm.toLinearMap) + (ψ := g.comp (coeffLinearEquiv R R (M := M)).symm.toLinearMap) h /-- The image of a polynomial under a linear map. -/ def map (f : M →ₗ[R] M') : PolynomialModule R M →ₗ[R] PolynomialModule R' M' := - Finsupp.mapRange.linearMap f + (coeffLinearEquiv ..).symm.toLinearMap.comp <| (Finsupp.mapRange.linearMap f).comp <| + (coeffLinearEquiv ..).toLinearMap @[simp] -theorem map_single (f : M →ₗ[R] M') (i : ℕ) (m : M) : map R' f (single R i m) = single R' i (f m) := - Finsupp.mapRange_single (hf := f.map_zero) +theorem map_single (f : M →ₗ[R] M') (i : ℕ) (m : M) : + map R' f (single R i m) = single R' i (f m) := by simp [map] @[simp] theorem map_lsingle (f : M →ₗ[R] M') (i : ℕ) (m : M) : @@ -251,7 +320,7 @@ theorem map_smul (f : M →ₗ[R] M') (p : R[X]) (q : PolynomialModule R M) : /-- Evaluate a polynomial `p : PolynomialModule R M` at `r : R`. -/ @[simps! -isSimp] def eval (r : R) : PolynomialModule R M →ₗ[R] M where - toFun p := p.sum fun i m => r ^ i • m + toFun p := p.coeff.sum fun i m => r ^ i • m map_add' _ _ := Finsupp.sum_add_index' (fun _ => smul_zero _) fun _ _ _ => smul_add _ _ _ map_smul' s m := by refine (Finsupp.sum_smul_index' ?_).trans ?_ diff --git a/Mathlib/Algebra/Polynomial/OfFn.lean b/Mathlib/Algebra/Polynomial/OfFn.lean index db8f8fbcbea18f..67d1f8bc3c2ed4 100644 --- a/Mathlib/Algebra/Polynomial/OfFn.lean +++ b/Mathlib/Algebra/Polynomial/OfFn.lean @@ -42,7 +42,7 @@ variable {R : Type*} [Semiring R] [DecidableEq R] /-- `ofFn n v` is the polynomial whose coefficients are the entries of the vector `v`. -/ def ofFn (n : ℕ) : (Fin n → R) →ₗ[R] R[X] where - toFun v := ⟨(List.ofFn v).toFinsupp⟩ + toFun v := ⟨.ofCoeff (List.ofFn v).toFinsupp⟩ map_add' x y := by ext i by_cases h : i < n @@ -89,7 +89,6 @@ theorem ofFn_degree_lt {n : ℕ} (v : Fin n → R) : (ofFn n v).degree < n := by · exact (natDegree_lt_iff_degree_lt h).mp <| ofFn_natDegree_lt (Nat.one_le_iff_ne_zero.mpr <| ne_zero_of_ofFn_ne_zero h) _ -set_option backward.isDefEq.respectTransparency false in theorem ofFn_eq_sum_monomial {n : ℕ} (v : Fin n → R) : ofFn n v = ∑ i : Fin n, monomial i (v i) := by by_cases h : n = 0 diff --git a/Mathlib/Algebra/Polynomial/Reverse.lean b/Mathlib/Algebra/Polynomial/Reverse.lean index 4b1821d13d7268..57e12c9b888666 100644 --- a/Mathlib/Algebra/Polynomial/Reverse.lean +++ b/Mathlib/Algebra/Polynomial/Reverse.lean @@ -85,22 +85,19 @@ In practice, `reflect` is only used when `N` is at least as large as the degree Eventually, it will be used with `N` exactly equal to the degree of `f`. -/ noncomputable def reflect (N : ℕ) : R[X] → R[X] - | ⟨f⟩ => ⟨Finsupp.embDomain (revAt N) f⟩ + | ⟨f⟩ => ⟨.ofCoeff <| f.coeff.embDomain (revAt N)⟩ theorem reflect_support (N : ℕ) (f : R[X]) : - (reflect N f).support = Finset.image (revAt N) f.support := by - rcases f with ⟨⟩ - ext1 - simp only [reflect, support_ofFinsupp, support_embDomain, Finset.mem_map, Finset.mem_image] + (reflect N f).support = Finset.image (revAt N) f.support := by cases f; ext1; simp [reflect] @[simp, grind =] theorem coeff_reflect (N : ℕ) (f : R[X]) (i : ℕ) : coeff (reflect N f) i = f.coeff (revAt N i) := by rcases f with ⟨f⟩ simp only [reflect, coeff] calc - Finsupp.embDomain (revAt N) f i = Finsupp.embDomain (revAt N) f (revAt N (revAt N i)) := by - rw [revAt_invol] - _ = f (revAt N i) := Finsupp.embDomain_apply_self _ _ _ + f.coeff.embDomain (revAt N) i + = f.coeff.embDomain (revAt N) (revAt N (revAt N i)) := by rw [revAt_invol] + _ = f.coeff (revAt N i) := Finsupp.embDomain_apply_self _ _ _ @[simp] lemma reflect_reflect {N : ℕ} {p : R[X]} : (p.reflect N).reflect N = p := by ext; simp @@ -108,10 +105,8 @@ theorem coeff_reflect (N : ℕ) (f : R[X]) (i : ℕ) : coeff (reflect N f) i = f theorem reflect_zero {N : ℕ} : reflect N (0 : R[X]) = 0 := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] -theorem reflect_eq_zero_iff {N : ℕ} {f : R[X]} : reflect N (f : R[X]) = 0 ↔ f = 0 := by - rw [ofFinsupp_eq_zero, reflect, embDomain_eq_zero, ofFinsupp_eq_zero] +lemma reflect_eq_zero_iff {N : ℕ} {f : R[X]} : reflect N (f : R[X]) = 0 ↔ f = 0 := by simp [reflect] @[simp] theorem reflect_add (f g : R[X]) (N : ℕ) : reflect N (f + g) = reflect N f + reflect N g := by diff --git a/Mathlib/Algebra/Polynomial/UnitTrinomial.lean b/Mathlib/Algebra/Polynomial/UnitTrinomial.lean index db0c3f3704de77..0dd4ccbb155194 100644 --- a/Mathlib/Algebra/Polynomial/UnitTrinomial.lean +++ b/Mathlib/Algebra/Polynomial/UnitTrinomial.lean @@ -202,24 +202,22 @@ theorem isUnitTrinomial_iff'' (h : p * p.mirror = q * q.mirror) : namespace IsUnitTrinomial -set_option backward.isDefEq.respectTransparency false in theorem irreducible_aux1 {k m n : ℕ} (hkm : k < m) (hmn : m < n) (u v w : Units ℤ) (hp : p = trinomial k m n (u : ℤ) v w) : C (v : ℤ) * (C (u : ℤ) * X ^ (m + n) + C (w : ℤ) * X ^ (n - m + k + n)) = - ⟨Finsupp.filter (· ∈ Set.Ioo (k + n) (n + n)) (p * p.mirror).toFinsupp⟩ := by + ⟨.ofCoeff <| (p * p.mirror).toFinsupp.coeff.filter (· ∈ Set.Ioo (k + n) (n + n))⟩ := by have key : n - m + k < n := by rwa [← lt_tsub_iff_right, tsub_lt_tsub_iff_left_of_le hmn.le] rw [hp, trinomial_mirror hkm hmn u.ne_zero w.ne_zero] simp_rw [trinomial_def, C_mul_X_pow_eq_monomial, add_mul, mul_add, monomial_mul_monomial, - toFinsupp_add, toFinsupp_monomial, AddMonoidAlgebra, Finsupp.filter_add] + toFinsupp_add, toFinsupp_monomial, AddMonoidAlgebra.coeff_add, Finsupp.filter_add, + AddMonoidAlgebra.coeff_single] rw [Finsupp.filter_single_of_neg, Finsupp.filter_single_of_neg, Finsupp.filter_single_of_neg, Finsupp.filter_single_of_neg, Finsupp.filter_single_of_neg, Finsupp.filter_single_of_pos, Finsupp.filter_single_of_neg, Finsupp.filter_single_of_pos, Finsupp.filter_single_of_neg] - · simp only [add_zero, zero_add] - -- Porting note: the next `rw` is needed to see through the defeq `Finsupp = AddMonoidAlgebra` - rw [ofFinsupp_add] - simp only [ofFinsupp_single] - rw [C_mul_monomial, C_mul_monomial, mul_comm (v : ℤ) w, add_comm (n - m + k) n] - · exact fun h => h.2.ne rfl + · simp only [add_zero, zero_add, AddMonoidAlgebra.ofCoeff_add, ofFinsupp_add, + AddMonoidAlgebra.ofCoeff_single, ofFinsupp_single, C_mul_monomial, C_mul_monomial, + mul_comm (v : ℤ) w, add_comm (n - m + k) n] + · simp · refine ⟨?_, by gcongr⟩ rwa [add_comm, add_lt_add_iff_left, lt_add_iff_pos_left, tsub_pos_iff_lt] · exact fun h => h.1.ne (add_comm k n) @@ -234,7 +232,7 @@ theorem irreducible_aux1 {k m n : ℕ} (hkm : k < m) (hmn : m < n) (u v w : Unit theorem irreducible_aux2 {k m m' n : ℕ} (hkm : k < m) (hmn : m < n) (hkm' : k < m') (hmn' : m' < n) (u v w : Units ℤ) (hp : p = trinomial k m n (u : ℤ) v w) (hq : q = trinomial k m' n (u : ℤ) v w) (h : p * p.mirror = q * q.mirror) : q = p ∨ q = p.mirror := by - let f : ℤ[X] → ℤ[X] := fun p => ⟨Finsupp.filter (· ∈ Set.Ioo (k + n) (n + n)) p.toFinsupp⟩ + let f (p : ℤ[X]) : ℤ[X] := ⟨.ofCoeff <| .filter (· ∈ Set.Ioo (k + n) (n + n)) p.toFinsupp.coeff⟩ replace h := congr_arg f h replace h := (irreducible_aux1 hkm hmn u v w hp).trans h replace h := h.trans (irreducible_aux1 hkm' hmn' u v w hq).symm diff --git a/Mathlib/Algebra/Ring/Subring/IntPolynomial.lean b/Mathlib/Algebra/Ring/Subring/IntPolynomial.lean index 8ecf9812305533..6e8e09c43280be 100644 --- a/Mathlib/Algebra/Ring/Subring/IntPolynomial.lean +++ b/Mathlib/Algebra/Ring/Subring/IntPolynomial.lean @@ -29,11 +29,9 @@ open scoped Polynomial /-- Given a polynomial in `K[X]` such that all coefficients belong to the subring `R`, `Polynomial.int` is the corresponding polynomial in `R[X]`. -/ def Polynomial.int (P : K[X]) (hP : ∀ n : ℕ, P.coeff n ∈ R) : R[X] where - toFinsupp := - { support := P.support - toFun := fun n => ⟨P.coeff n, hP n⟩ - mem_support_toFun := fun n => by - rw [ne_eq, ← Subring.coe_eq_zero_iff, mem_support_iff] } + toFinsupp.coeff.toFun n := ⟨P.coeff n, hP n⟩ + toFinsupp.coeff.support := P.support + toFinsupp.coeff.mem_support_toFun n := by rw [ne_eq, ← Subring.coe_eq_zero_iff, mem_support_iff] namespace Polynomial diff --git a/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean b/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean index 7c636ca0124d61..4a05c33c3b103a 100644 --- a/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean +++ b/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean @@ -49,8 +49,7 @@ variable {V W : Type*} [AddCommGroup V] [Module ℝ V] [TopologicalSpace V] {he : Continuous e} {hL : Continuous fun p : V × W ↦ L p.1 p.2} /-- The bounded continuous mapping `fun v ↦ e (L v w)` from `V` to `ℂ`. -/ -noncomputable def char (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) - (w : W) : +noncomputable def char (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) (w : W) : V →ᵇ ℂ where toFun := fun v ↦ e (L v w) continuous_toFun := @@ -103,13 +102,13 @@ theorem ext_of_char_eq (he : Continuous e) (he' : e ≠ 1) /-- Monoid homomorphism mapping `w` to `fun v ↦ e (L v w)`. -/ noncomputable def charMonoidHom (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) : Multiplicative W →* (V →ᵇ ℂ) where - toFun w := char he hL w + toFun w := char he hL w.toAdd map_one' := char_zero_eq_one map_mul' := char_add_eq_mul (he := he) (hL := hL) @[simp] lemma charMonoidHom_apply (w : Multiplicative W) (v : V) : - charMonoidHom he hL w v = e (L v w) := by simp [charMonoidHom] + charMonoidHom he hL w v = e (L v w.toAdd) := by simp [charMonoidHom] /-- Algebra homomorphism mapping `w` to `fun v ↦ e (L v w)`. -/ noncomputable @@ -119,12 +118,9 @@ def charAlgHom (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2 @[simp] lemma charAlgHom_apply (w : AddMonoidAlgebra ℂ W) (v : V) : - charAlgHom he hL w v = ∑ a ∈ w.support, w a * (e (L v a) : ℂ) := by - simp only [charAlgHom, AddMonoidAlgebra.lift_apply] - rw [Finsupp.sum_of_support_subset w subset_rfl] - · simp only [coe_sum, coe_smul, charMonoidHom_apply, smul_eq_mul, Finset.sum_apply] - rfl - · simp + charAlgHom he hL w v = w.coeff.sum (fun a z ↦ z • (e (L v a) : ℂ)) := by + simp [charAlgHom, charMonoidHom, char, AddMonoidAlgebra.lift_apply] + simp [Finsupp.sum] /-- The family of `ℂ`-linear combinations of `char he hL w, w : W`, is closed under `star`. -/ lemma star_mem_range_charAlgHom (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) @@ -132,14 +128,11 @@ lemma star_mem_range_charAlgHom (he : Continuous e) (hL : Continuous fun p : V star x ∈ (charAlgHom he hL).range := by simp only [AlgHom.mem_range] at hx ⊢ obtain ⟨y, rfl⟩ := hx - let z := Finsupp.mapRange star (star_zero _) y + let z := y.map (starRingEnd _).toAddMonoidHom let f : W ↪ W := ⟨fun x ↦ -x, (fun _ _ ↦ neg_inj.mp)⟩ - refine ⟨z.embDomain f, ?_⟩ - ext1 u - simp only [charAlgHom_apply, Finsupp.support_embDomain, Finset.sum_map, - Finsupp.embDomain_apply_self, star_apply, star_sum, star_mul', Circle.star_addChar] - rw [Finsupp.support_mapRange_of_injective (star_zero _) y star_injective] - simp [z, f] + refine ⟨.ofCoeff <| z.coeff.embDomain f, ?_⟩ + ext + simp [charAlgHom_apply, Finsupp.sum_embDomain, z, Finsupp.sum_mapRange_index, f] /-- The star-subalgebra of polynomials. -/ noncomputable @@ -150,16 +143,11 @@ def charPoly (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) lemma mem_charPoly (f : V →ᵇ ℂ) : f ∈ charPoly he hL - ↔ ∃ w : AddMonoidAlgebra ℂ W, f = fun x ↦ ∑ a ∈ w.support, w a * (e (L x a) : ℂ) := by + ↔ ∃ w : AddMonoidAlgebra ℂ W, f = fun x ↦ w.coeff.sum (fun a z ↦ z * (e (L x a) : ℂ)) := by change f ∈ (charAlgHom he hL).range ↔ _ simp [BoundedContinuousFunction.ext_iff, funext_iff, eq_comm] -lemma char_mem_charPoly (w : W) : char he hL w ∈ charPoly he hL := by - rw [mem_charPoly] - refine ⟨AddMonoidAlgebra.single w 1, ?_⟩ - ext v - simp only [char_apply, AddMonoidAlgebra.single] - rw [Finset.sum_eq_single w] <;> simp +lemma char_mem_charPoly (w : W) : char he hL w ∈ charPoly he hL := ⟨.single w 1, by ext; simp⟩ /-- The family `charPoly he hL w, w : W` separates points in `V`. -/ lemma separatesPoints_charPoly (he : Continuous e) (he' : e ≠ 1) diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 682adeef183b67..ff4e89bf70c22e 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -285,6 +285,9 @@ theorem mapDomain_notin_range {f : α → β} (x : α →₀ M) (a : β) (h : a mapDomain f x a = 0 := mapDomain_of_not_mem_image_support <| by grw [Set.image_subset_range]; exact h +lemma mem_range_of_mapDomain_ne_zero {f : α → β} {x : α →₀ M} {b : β} (h : mapDomain f x b ≠ 0) : + b ∈ Set.range f := by contrapose! h; exact mapDomain_notin_range _ _ h + @[simp] theorem mapDomain_id : mapDomain id v = v := sum_single _ @@ -324,6 +327,16 @@ theorem mapDomain_equiv_apply {f : α ≃ β} (x : α →₀ M) (a : β) : conv_lhs => rw [← f.apply_symm_apply a] exact mapDomain_apply f.injective _ _ +@[simp] lemma support_mapDomain_embedding (f : α ↪ β) (x : α →₀ M) : + (mapDomain f x).support = x.support.map f := by + ext b + simp only [mem_support_iff, ne_eq, mem_map] + refine ⟨fun h ↦ ?_, ?_⟩ + · obtain ⟨a, rfl⟩ := mem_range_of_mapDomain_ne_zero h + exact ⟨a, by simpa [f.injective] using h⟩ + · rintro ⟨a, ha, rfl⟩ + simpa [f.injective] + /-- `Finsupp.mapDomain` is an `AddMonoidHom`. -/ @[simps] def mapDomain.addMonoidHom (f : α → β) : (α →₀ M) →+ β →₀ M where diff --git a/Mathlib/FieldTheory/Finite/Polynomial.lean b/Mathlib/FieldTheory/Finite/Polynomial.lean index f7e8534d758ea9..b1ba5973427013 100644 --- a/Mathlib/FieldTheory/Finite/Polynomial.lean +++ b/Mathlib/FieldTheory/Finite/Polynomial.lean @@ -116,6 +116,7 @@ section variable (K σ) +set_option backward.isDefEq.respectTransparency false in /-- `MvPolynomial.eval` as a `K`-linear map. -/ @[simps] def evalₗ [CommSemiring K] : MvPolynomial σ K →ₗ[K] (σ → K) → K where @@ -184,7 +185,7 @@ theorem rank_R [Fintype σ] : Module.rank K (R σ K) = Fintype.card (σ → K) : Module.rank K (R σ K) = Module.rank K (↥{ s : σ →₀ ℕ | ∀ n : σ, s n ≤ Fintype.card K - 1 } →₀ K) := LinearEquiv.rank_eq - (Finsupp.supportedEquivFinsupp { s : σ →₀ ℕ | ∀ n : σ, s n ≤ Fintype.card K - 1 }) + (AddMonoidAlgebra.supportedEquivFinsupp { s : σ →₀ ℕ | ∀ n : σ, s n ≤ Fintype.card K - 1 }) _ = #{ s : σ →₀ ℕ | ∀ n : σ, s n ≤ Fintype.card K - 1 } := by rw [rank_finsupp_self'] _ = #{ s : σ → ℕ | ∀ n : σ, s n < Fintype.card K } := by refine Quotient.sound ⟨Equiv.subtypeEquiv Finsupp.equivFunOnFinite fun f => ?_⟩ diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index 64e81115ac3599..862f674dbacdd6 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -159,13 +159,15 @@ theorem exists_mem_support_not_dvd_of_forall_totalDegree_le (hF0 : F ≠ 0) (hFa rw [F.support.sum_attach (fun i ↦ monomial i (F.coeff i)), support_sum_monomial_coeff, hFa]) simp only [LinearIndependent, injective_iff_map_eq_zero, not_forall] at this obtain ⟨F', hF', hF'0⟩ := this - let F'' : MvPolynomial ι k := F'.mapDomain fun s ↦ σ' s.1 - have hF''0 : F'' ≠ 0 := ne_of_ne_of_eq ((Finsupp.mapDomain_injective fun s t h ↦ Subtype.ext - (Finsupp.ext fun i ↦ by rw [hσ' _ s.2, hσ' _ t.2, h])).ne_iff.mpr hF'0) (by simp) + let F'' : MvPolynomial ι k := .ofCoeff <| F'.mapDomain fun s ↦ σ' s.1 + have hF''0 : F'' ≠ 0 := ne_of_ne_of_eq (AddMonoidAlgebra.ofCoeff_eq_zero.ne.2 <| + (Finsupp.mapDomain_injective fun s t h ↦ Subtype.ext + (Finsupp.ext fun i ↦ by rw [hσ' _ s.2, hσ' _ t.2, h])).ne hF'0) (by simp) have hF'' : aeval a F'' = 0 := by - have : (aeval a).toLinearMap ∘ₗ (Finsupp.lmapDomain k k fun s : F.support ↦ σ' s) = + have : (aeval a).toLinearMap ∘ₗ (AddMonoidAlgebra.coeffLinearEquiv _).symm.toLinearMap ∘ₗ + Finsupp.lmapDomain k k (fun s : F.support ↦ σ' s) = (Finsupp.linearCombination k fun s : F.support ↦ aeval a (monomial (σ' s) (1 : k))) := by - ext v; simp [AddMonoidAlgebra, monomial] + ext v; simp [monomial] simp only [← hF', F'', ← this]; rfl suffices hpm : p * F''.totalDegree ≤ F.totalDegree by have hF''0' : F''.totalDegree ≠ 0 := by diff --git a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean index 5193b3d60d253c..96ece9a77addc2 100644 --- a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean @@ -224,14 +224,14 @@ end FreeAbelianGroup namespace AddMonoidAlgebra variable {M R S : Type*} [Semiring R] [Semiring S] [Module R S] [Module.Free R S] -instance : Module.Free R S[M] := .finsupp .. +instance : Module.Free R S[M] := .of_equiv (coeffLinearEquiv _).symm end AddMonoidAlgebra namespace MonoidAlgebra variable {M R S : Type*} [Semiring R] [Semiring S] [Module R S] [Module.Free R S] -instance : Module.Free R S[M] := .finsupp .. +instance : Module.Free R S[M] := .of_equiv (coeffLinearEquiv _).symm end MonoidAlgebra diff --git a/Mathlib/LinearAlgebra/FreeAlgebra.lean b/Mathlib/LinearAlgebra/FreeAlgebra.lean index 568ad4444f01d9..9b71bce41d395e 100644 --- a/Mathlib/LinearAlgebra/FreeAlgebra.lean +++ b/Mathlib/LinearAlgebra/FreeAlgebra.lean @@ -37,7 +37,8 @@ variable [CommSemiring R] mapping `[x₁, x₂, ..., xₙ]` to the "monomial" `1 • x₁ * x₂ * ⋯ * xₙ` -/ -- @[simps] noncomputable def basisFreeMonoid : Basis (FreeMonoid X) R (FreeAlgebra R X) := - Finsupp.basisSingleOne.map equivMonoidAlgebraFreeMonoid.symm.toLinearEquiv + Finsupp.basisSingleOne.map + (equivMonoidAlgebraFreeMonoid.toLinearEquiv.trans <| MonoidAlgebra.coeffLinearEquiv _).symm instance : Module.Free R (FreeAlgebra R X) := .of_equiv equivMonoidAlgebraFreeMonoid.symm.toLinearEquiv diff --git a/Mathlib/LinearAlgebra/SymmetricAlgebra/Basis.lean b/Mathlib/LinearAlgebra/SymmetricAlgebra/Basis.lean index 948212500b1693..7e5a43c31856d5 100644 --- a/Mathlib/LinearAlgebra/SymmetricAlgebra/Basis.lean +++ b/Mathlib/LinearAlgebra/SymmetricAlgebra/Basis.lean @@ -42,6 +42,7 @@ variable {κ : Type uκ} {R : Type uR} {M : Type uM} section CommSemiring variable [CommSemiring R] [AddCommMonoid M] [Module R M] +set_option backward.isDefEq.respectTransparency false in /-- `SymmetricAlgebra.equivMvPolynomial` gives an algebra isomorphism between the symmetric algebra over a free module and multivariate polynomials over a basis. This is analogous to `TensorAlgebra.equivFreeAlgebra`. -/ @@ -63,6 +64,7 @@ lemma equivMvPolynomial_symm_X (b : Basis κ R M) (i : κ) : (equivMvPolynomial b).symm (MvPolynomial.X i) = ι R M (b i) := (equivMvPolynomial b).toEquiv.symm_apply_eq.mpr <| equivMvPolynomial_ι_apply b i |>.symm +set_option backward.isDefEq.respectTransparency false in theorem IsSymmetricAlgebra.mvPolynomial (I : Type*) (b : Basis I R M) : IsSymmetricAlgebra (Basis.constr b R (.X : I → MvPolynomial I R)) := (SymmetricAlgebra.equivMvPolynomial b).bijective diff --git a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean index abf7c13acae298..e4d87c9723190f 100644 --- a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean @@ -108,9 +108,9 @@ theorem ext_of_integral_char_eq (he : Continuous e) (he' : e ≠ 1) obtain ⟨w, hw⟩ := hg rw [hw] have hsum (P : Measure V) [IsFiniteMeasure P] : - ∫ v, ∑ a ∈ w.support, w a * e (L v a) ∂P = ∑ a ∈ w.support, ∫ v, w a * e (L v a) ∂P := - integral_finsetSum w.support - fun a ha => Integrable.const_mul (integrable P (char he hL a)) _ + ∫ v, w.coeff.sum (fun a z ↦ z * e (L v a)) ∂P = + w.coeff.sum (fun a z ↦ ∫ v, z * e (L v a) ∂P) := + integral_finsetSum _ fun a ha ↦ ((char he hL a).integrable P).const_mul _ rw [hsum P, hsum P'] apply Finset.sum_congr rfl fun i _ => ?_ simp only [MeasureTheory.integral_const_mul, mul_eq_mul_left_iff] diff --git a/Mathlib/MeasureTheory/Measure/LevyConvergence.lean b/Mathlib/MeasureTheory/Measure/LevyConvergence.lean index 9791f2a3a1e567..4294777be177cd 100644 --- a/Mathlib/MeasureTheory/Measure/LevyConvergence.lean +++ b/Mathlib/MeasureTheory/Measure/LevyConvergence.lean @@ -182,8 +182,8 @@ lemma ProbabilityMeasure.tendsto_charPoly_of_tendsto_charFun {μ : ι → Probab rw [mem_charPoly] at hg obtain ⟨w, hw⟩ := hg have h_eq (μ : Measure E) (hμ : IsProbabilityMeasure μ) : - ∫ x, g x ∂μ = ∑ a ∈ w.support, w a * ∫ x, (probChar (innerₗ E x a) : ℂ) ∂μ := by - simp_rw [hw] + ∫ x, g x ∂μ = w.coeff.sum (fun a z ↦ z * ∫ x, (probChar (innerₗ E x a) : ℂ) ∂μ) := by + simp_rw [hw, Finsupp.sum] rw [integral_finsetSum] · congr with y rw [integral_const_mul] diff --git a/Mathlib/NumberTheory/BernoulliPolynomials.lean b/Mathlib/NumberTheory/BernoulliPolynomials.lean index 51e293fd0ad465..f2b7edd25d0dfd 100644 --- a/Mathlib/NumberTheory/BernoulliPolynomials.lean +++ b/Mathlib/NumberTheory/BernoulliPolynomials.lean @@ -179,6 +179,7 @@ theorem bernoulli_succ_eval (n p : ℕ) : (bernoulli p.succ).eval (n : ℚ) = apply eq_add_of_sub_eq' rw [sum_range_pow_eq_bernoulli_sub] +set_option backward.isDefEq.respectTransparency false in theorem bernoulli_comp_one_add_X (n : ℕ) : (bernoulli n).comp (1 + X) = bernoulli n + n • X ^ (n - 1) := by refine Nat.strong_induction_on n fun d hd => ?_ diff --git a/Mathlib/NumberTheory/Height/MvPolynomial.lean b/Mathlib/NumberTheory/Height/MvPolynomial.lean index 0d65cd03474751..3d515c98aa5365 100644 --- a/Mathlib/NumberTheory/Height/MvPolynomial.lean +++ b/Mathlib/NumberTheory/Height/MvPolynomial.lean @@ -188,7 +188,7 @@ variable {K : Type*} [Field K] {ι : Type*} -- The "local" version of the height bound for (archimedean) absolute values. lemma AbsoluteValue.eval_mvPolynomial_le [Finite ι] (v : AbsoluteValue K ℝ) {p : MvPolynomial ι K} {N : ℕ} (hp : p.IsHomogeneous N) (x : ι → K) : - v (p.eval x) ≤ p.sum (fun _ c ↦ v c) * (⨆ i, v (x i)) ^ N := by + v (p.eval x) ≤ (AddMonoidAlgebra.coeff p).sum (fun _ c ↦ v c) * (⨆ i, v (x i)) ^ N := by rw [eval_eq, sum_def, Finset.sum_mul] grw [AbsoluteValue.sum_le] simp_rw [v.map_mul, v.map_prod, v.map_pow] @@ -228,12 +228,12 @@ open AdmissibleAbsValues /-- The constant in the (upper) height bound on values of `p`. -/ @[expose] noncomputable def mulHeightBound (p : ι' → MvPolynomial ι K) : ℝ := - (archAbsVal.map fun v ↦ ⨆ j, (p j).sum (fun _ c ↦ v c)).prod * + (archAbsVal.map fun v ↦ ⨆ j, (AddMonoidAlgebra.coeff <| p j).sum (fun _ c ↦ v c)).prod * ∏ᶠ v : nonarchAbsVal, ⨆ j, max (⨆ s : (p j).support, v.val (coeff s (p j))) 1 lemma mulHeightBound_eq (p : ι' → MvPolynomial ι K) : mulHeightBound p = - (archAbsVal.map fun v ↦ ⨆ j, (p j).sum (fun _ c ↦ v c)).prod * + (archAbsVal.map fun v ↦ ⨆ j, (AddMonoidAlgebra.coeff <| p j).sum (fun _ c ↦ v c)).prod * ∏ᶠ v : nonarchAbsVal, ⨆ j, max (⨆ s : (p j).support, v.val (coeff s (p j))) 1 := rfl @@ -241,10 +241,9 @@ variable (K ι ι') in lemma max_mulHeightBound_zero_one_eq_one : max (mulHeightBound (0 : ι' → MvPolynomial ι K)) 1 = 1 := by simp only [mulHeightBound_eq, Pi.zero_apply, support_zero, coeff_zero, AbsoluteValue.map_zero, - Real.iSup_of_isEmpty, zero_le_one, sup_of_le_right] - set_option backward.isDefEq.respectTransparency false in -- temporary measure - simp only [Finsupp.sum_zero_index] -- singling this out for needing the above - simp only [Real.iSup_const_zero, Multiset.map_const', Multiset.prod_replicate, zero_pow_eq] + Real.iSup_of_isEmpty, zero_le_one, sup_of_le_right, AddMonoidAlgebra.coeff_zero, + Finsupp.sum_zero_index, Real.iSup_const_zero, Multiset.map_const', Multiset.prod_replicate, + sup_eq_right, zero_pow_eq] rcases isEmpty_or_nonempty ι' · split_ifs · simpa using finprod_zero_le_one @@ -273,7 +272,8 @@ private lemma mulHeight_constantCoeff_le_mulHeightBound {p : ι' → MvPolynomia gcongr · exact finprod_nonneg fun v ↦ Real.iSup_nonneg_of_nonnegHomClass .. · exact prod_map_nonneg fun v _ ↦ iSup_nonneg fun _ ↦ sum_nonneg fun _ _ ↦ by positivity - · have H (v : AbsoluteValue K ℝ) (j : ι') : v (constantCoeff (p j)) ≤ sum (p j) fun _ c ↦ v c := + · have H (v : AbsoluteValue K ℝ) (j : ι') : + v (constantCoeff (p j)) ≤ (AddMonoidAlgebra.coeff <| p j).sum fun _ c ↦ v c := single_eval_le_sum _ v.map_zero (fun _ ↦ by positivity) _ exact prod_map_le_prod_map₀ _ _ (fun v _ ↦ Real.iSup_nonneg_of_nonnegHomClass ..) fun v _ ↦ Finite.ciSup_mono (H v) @@ -305,10 +305,11 @@ theorem mulHeight_eval_le {N : ℕ} {p : ι' → MvPolynomial ι K} (hp : ∀ i, rcases eq_or_ne (fun j ↦ eval x (p j)) 0 with h₀ | h₀ · grw [← le_max_right] simpa [h₀, mulHeight_zero] using one_le_pow₀ <| one_le_mulHeight x - have H₀ (v : AbsoluteValue K ℝ) : 0 ≤ ⨆ j, Finsupp.sum (p j) fun _ c ↦ v c := + have H₀ (v : AbsoluteValue K ℝ) : 0 ≤ ⨆ j, (AddMonoidAlgebra.coeff <| p j).sum fun _ c ↦ v c := iSup_nonneg (fun j ↦ sum_nonneg' <| fun s ↦ by positivity) -- The following four statements are used in the `gcongr`s below. - have H₁ : 0 ≤ (archAbsVal.map (fun v ↦ ⨆ j, Finsupp.sum (p j) fun _ c ↦ v c)).prod := + have H₁ : + 0 ≤ (archAbsVal.map (fun v ↦ ⨆ j, (AddMonoidAlgebra.coeff <| p j).sum fun _ c ↦ v c)).prod := prod_map_nonneg fun v _ ↦ H₀ v have H₂ : 0 ≤ (archAbsVal.map (fun v ↦ ⨆ i, v (x i))).prod := prod_map_nonneg fun _ _ ↦ Real.iSup_nonneg_of_nonnegHomClass .. @@ -331,7 +332,7 @@ theorem mulHeight_eval_le {N : ℕ} {p : ι' → MvPolynomial ι K} (hp : ∀ i, grw [v.eval_mvPolynomial_le (hp j) x] gcongr · exact HH₁ v - · exact HH₂ (fun j ↦ Finsupp.sum (p j) fun _ c ↦ v c) j + · exact HH₂ (fun j ↦ (AddMonoidAlgebra.coeff <| p j).sum fun _ c ↦ v c) j · -- nonarchimedean part: reduce to "local" statement `eval_mvPolynomial_le` have := (Function.ne_iff.mp h₀).nonempty have F := hasFiniteMulSupport_iSup_nonarchAbsVal hx diff --git a/Mathlib/RepresentationTheory/Action.lean b/Mathlib/RepresentationTheory/Action.lean index 91adc1496049d4..e756bfb73b9521 100644 --- a/Mathlib/RepresentationTheory/Action.lean +++ b/Mathlib/RepresentationTheory/Action.lean @@ -5,8 +5,9 @@ Authors: Yunzhou Xie -/ module -public import Mathlib.RepresentationTheory.Intertwining public import Mathlib.CategoryTheory.Action.Monoidal +public import Mathlib.RepresentationTheory.Intertwining +public import Mathlib.RingTheory.TensorProduct.MonoidAlgebra /-! @@ -25,6 +26,7 @@ universe w w' u u' v v' namespace Representation open Representation.IntertwiningMap Representation.TensorProduct +open scoped MonoidAlgebra noncomputable section @@ -38,29 +40,27 @@ variable (k G X) in /-- Every Set `X` that has a `G`-action on it can be made into a `G`-rep by using `X →₀ k` as the base module and `G`-action on it is induced by the `G`-action on `X`. -/ @[simps] -def linearize : Representation k G (X.V →₀ k) where - toFun g := Finsupp.lmapDomain k k (X.ρ g) +def linearize : Representation k G k[X.V] where + toFun g := MonoidAlgebra.mapDomainLinearMap k k (X.ρ g) map_one' := by ext; simp map_mul' _ _ := by ext; simp lemma linearize_single (g : G) (x : X.V) : - linearize k G X g (Finsupp.single x 1) = Finsupp.single (X.ρ g x) 1 := by + linearize k G X g (.single x 1) = .single (X.ρ g x) 1 := by simp /-- Every morphism between `G`-sets could be made into an intertwining map between `Representation`s by the linear map induced on the indexing sets. -/ +@[simps toLinearMap] def linearizeMap (f : X ⟶ Y) : IntertwiningMap (A := k) (linearize k G X) (linearize k G Y) where - __ := Finsupp.lmapDomain k k f.hom + toLinearMap := MonoidAlgebra.mapDomainLinearMap k k f.hom isIntertwining' g := by ext x y; simp [(congr($(f.comm g) x) : f.hom (X.ρ g x) = Y.ρ g (f.hom x))] @[simp] lemma linearizeMap_single (f : X ⟶ Y) (x : X.V) (r : k) : - (linearizeMap f) (Finsupp.single x r) = Finsupp.single (f.hom x) r := by + (linearizeMap f) (.single x r) = .single (f.hom x) r := by simp [linearizeMap] -lemma linearizeMap_toLinearMap (f : X ⟶ Y) : - (linearizeMap f).toLinearMap = Finsupp.lmapDomain k k f.hom := rfl - namespace LinearizeMonoidal open scoped MonoidalCategory @@ -81,10 +81,10 @@ variable (k G) in @[simps toLinearMap] def ε : (trivial k G k).IntertwiningMap (linearize k G (MonoidalCategoryStruct.tensorUnit (Action (Type w) G))) where - __ := Finsupp.uniqueLinearEquiv k k PUnit.unit |>.symm.toLinearMap + __ := MonoidAlgebra.uniqueLinearEquiv k PUnit |>.symm.toLinearMap isIntertwining' g := by ext1; simp [linearize_single _] -lemma ε_one : ε k G 1 = Finsupp.single PUnit.unit 1 := by +lemma ε_one : ε k G 1 = .single PUnit.unit 1 := by simp [← toLinearMap_apply, types_tensorUnit_def] open scoped MonoidalCategory @@ -93,10 +93,10 @@ variable (k G) in /-- The unit of the linearize functor. -/ @[simps toLinearMap] def η : (linearize k G (𝟙_ (Action (Type u) G))).IntertwiningMap (trivial k G k) where - __ := (Finsupp.uniqueLinearEquiv k k PUnit.unit).toLinearMap + toLinearMap := (MonoidAlgebra.uniqueLinearEquiv k PUnit).toLinearMap isIntertwining' g := by ext; simp [linearize_single _] -lemma η_single (x : PUnit) : η k G (Finsupp.single x 1) = 1 := by +lemma η_single (x : PUnit) : η k G (.single x 1) = 1 := by simp [← toLinearMap_apply, types_tensorUnit_def] variable (k G) in @@ -115,29 +115,28 @@ variable {k : Type u} [CommSemiring k] [Module k V] [Module k W] {σ : Represent variable (X Y) in /-- The tensor (multiplication) of the linearize functor. -/ @[simps toLinearMap] -def μ : ((linearize k G X).tprod (linearize k G Y)).IntertwiningMap - (linearize k G (X ⊗ Y)) where - __ := finsuppTensorFinsupp' k X.V Y.V +def μ : ((linearize k G X).tprod (linearize k G Y)).IntertwiningMap (linearize k G (X ⊗ Y)) where + toLinearMap := (MonoidAlgebra.tensorEquiv k).toLinearMap isIntertwining' g := by ext; simp [linearize_single _]; rfl lemma μ_apply_single_single (x : X.V) (y : Y.V) (r s : k) : - μ (k := k) X Y (Finsupp.single x r ⊗ₜ Finsupp.single y s) = Finsupp.single (x, y) (r * s) := by + μ (k := k) X Y (.single x r ⊗ₜ .single y s) = .single (x, y) (r * s) := by ext; simp [← toLinearMap_apply] open TensorProduct in -lemma μ_apply_apply (l1 : X.V →₀ k) (l2 : Y.V →₀ k) (xy : (X ⊗ Y).V) : - μ X Y (l1 ⊗ₜ l2) xy = l1 xy.1 * l2 xy.2 := by +lemma coeff_μ_tmul (l1 : k[X.V]) (l2 : k[Y.V]) (xy : (X ⊗ Y).V) : + (μ X Y (l1 ⊗ₜ l2)).coeff xy = l1.coeff xy.1 * l2.coeff xy.2 := by simp [← toLinearMap_apply, types_tensorObj_def, finsuppTensorFinsupp'_apply_apply _] lemma μ_comp_rTensor (f : X ⟶ Y) (Z : Action (Type w) G) : (μ Y Z).comp (rTensor (linearize k G Z) (linearizeMap f)) = (linearizeMap (f ▷ Z)).comp (μ X Z) := by - ext; simp [linearizeMap_single _] + ext; simp lemma μ_comp_lTensor (f : X ⟶ Y) (Z : Action (Type w) G) : (μ Z Y).comp ((linearizeMap f).lTensor (linearize k G Z)) = (linearizeMap (Z ◁ f)).comp (μ Z X) := by - ext : 6; simp [linearizeMap_single _] + ext; simp variable (X Y Z) in lemma μ_comp_assoc : ((linearizeMap (α_ X Y Z).hom).comp @@ -147,11 +146,10 @@ lemma μ_comp_assoc : ((linearizeMap (α_ X Y Z).hom).comp ext x y z : 9 -- experiment with monoidal structure of `Action` on `Type` simp only [Action.tensorObj_V, types_tensorObj_def, comp_toLinearMap, μ_toLinearMap, - toLinearMap_rTensor, LinearMap.coe_comp, Function.comp_apply, Finsupp.lsingle_apply, + toLinearMap_rTensor, LinearMap.coe_comp, Function.comp_apply, TensorProduct.AlgebraTensorModule.curry_apply, LinearMap.restrictScalars_self, - TensorProduct.curry_apply, LinearEquiv.coe_coe, LinearMap.rTensor_tmul, - finsuppTensorFinsupp'_single_tmul_single, mul_one, toLinearMap_lTensor, toLinearMap_assoc, - TensorProduct.assoc_tmul, LinearMap.lTensor_tmul, toLinearMap_apply] + TensorProduct.curry_apply, LinearEquiv.coe_coe, LinearMap.rTensor_tmul, toLinearMap_apply, + toLinearMap_lTensor, toLinearMap_assoc, TensorProduct.assoc_tmul, LinearMap.lTensor_tmul] -- after fixing the defeq problems in `Action` and in the monoidal category structure of `types` -- this line should close the goal so this is left as an indicator. convert dsimp% linearizeMap_single (α_ X Y Z).hom ((x, y), z) (1 : k) @@ -161,9 +159,7 @@ variable (X) in lemma μ_leftUnitor : (lid k (linearize k G X)).toIntertwiningMap = ((linearizeMap (λ_ X).hom).comp (μ (𝟙_ (Action (Type w) G)) X)).comp (rTensor (linearize k G X) (ε k G)) := by - ext x1 : 5 - simpa [types_tensorObj_def, types_tensorUnit_def] using - linearizeMap_single (k := k) (λ_ X).hom (PUnit.unit, x1) _ |>.symm + ext; simp variable (X) in lemma μ_rightUnitor : (rid k (linearize k G X)).toIntertwiningMap = @@ -176,28 +172,25 @@ variable (X Y) in /-- The comultiplication of the linearize functor. -/ def δ : (linearize k G (X ⊗ Y)).IntertwiningMap ((linearize k G X).tprod (linearize k G Y)) where - __ := (finsuppTensorFinsupp' k X.V Y.V).symm + toLinearMap := (MonoidAlgebra.tensorEquiv k).symm.toLinearMap isIntertwining' g := by - ext; simp [types_tensorObj_def, linearize_single _, - finsuppTensorFinsupp'_symm_single_eq_single_one_tmul k]; rfl + ext; simp [linearize_single _, MonoidAlgebra.tensorEquiv_symm_single_eq_single_one_tmul]; rfl lemma δ_apply_single (xy : (X ⊗ Y).V) : - (δ (k := k) X Y) (Finsupp.single xy 1) = Finsupp.single xy.1 1 ⊗ₜ - Finsupp.single xy.2 1 := by - simp [δ, finsuppTensorFinsupp'_symm_single_eq_single_one_tmul k] + (δ (k := k) X Y) (.single xy 1) = .single xy.1 1 ⊗ₜ .single xy.2 1 := by + simp [δ, MonoidAlgebra.tensorEquiv_symm_single_eq_single_one_tmul] variable (Z) in lemma rTensor_comp_δ (f : X ⟶ Y) : ((linearizeMap f).rTensor (linearize k G Z)).comp (δ X Z) = (δ Y Z).comp (linearizeMap (f ▷ Z)) := by - ext - simp [linearizeMap_single _, δ_apply_single _] + ext; simp [δ_apply_single _] variable (Z) in lemma lTensor_comp_δ (f : X ⟶ Y) : ((linearizeMap f).lTensor (linearize k G Z)).comp (δ Z X) = (δ Z Y).comp (linearizeMap (Z ◁ f)) := by - ext; simp [linearizeMap_single _, δ_apply_single _] + ext; simp [δ_apply_single _] variable (X Y Z) in lemma assoc_comp_δ : ((assoc (linearize k G X) (linearize k G Y) @@ -206,20 +199,20 @@ lemma assoc_comp_δ : ((assoc (linearize k G X) (linearize k G Y) (linearizeMap (α_ X Y Z).hom) := by ext -- TODO : try not to `simp` with `δ` and `linearizeMap` directly here - simp [linearizeMap, δ, finsuppTensorFinsupp'_symm_single_eq_single_one_tmul k] + simp [linearizeMap, δ, MonoidAlgebra.tensorEquiv_symm_single_eq_single_one_tmul] lemma leftUnitor_δ (X : Action (Type u) G) : (lid k (linearize k G X)).symm.toIntertwiningMap = (((η k G).rTensor (linearize k G X)).comp (δ (𝟙_ (Action (Type u) G)) X)).comp (linearizeMap (λ_ X).inv) := by ext -- TODO : try not to `simp` with `δ` and `linearizeMap` directly here - simp [linearizeMap, δ, finsuppTensorFinsupp'_symm_single_eq_single_one_tmul] + simp [linearizeMap, δ, MonoidAlgebra.tensorEquiv_symm_single_eq_single_one_tmul] unif_hint (X : Action (Type u) G) where ⊢ (X ⊗ 𝟙_ (Action (Type u) G)).V ≟ X.V × PUnit in lemma rightUnitor_δ (X : Action (Type u) G) : (rid k (linearize k G X)).symm.toIntertwiningMap = (((η k G).lTensor (linearize k G X)).comp (δ X (𝟙_ (Action (Type u) G)))).comp (linearizeMap (ρ_ X).inv) := by - ext; simp [linearizeMap_single _, δ_apply_single _] + ext; simp [δ_apply_single _] variable (X Y) in lemma μ_δ : (μ X Y).comp (δ (k := k) X Y) = .id _ := by @@ -236,42 +229,28 @@ end LinearizeMonoidal lemma linearizeTrivial_def (X : Type w) (g : G) : linearize k G (Action.trivial _ X) g = LinearMap.id := by ext (x : X) : 2 - rw [LinearMap.comp_apply, LinearMap.id_comp, Finsupp.lsingle_apply, linearize_single] + rw [LinearMap.comp_apply, LinearMap.id_comp, MonoidAlgebra.lsingle_apply, linearize_single] simp only [Action.trivial_ρ] rfl variable (k G) in /-- This a type-changing equivalence (which requires a non-trivial proof that `LinearEquiv.refl _ _` is `G`-equivariant) to avoid abusing defeq. -/ -def linearizeTrivialIso (X : Type w) : (linearize k G (Action.trivial _ X)).Equiv - (trivial k G (X →₀ k)) := - .mk (LinearEquiv.refl _ _) fun g ↦ by - simpa using! linearizeTrivial_def (k := k) X g +def linearizeTrivialIso (X : Type w) : (linearize k G (.trivial _ X)).Equiv (trivial k G k[X]) := + .mk (.refl ..) fun g ↦ by erw [linearizeTrivial_def, LinearMap.comp_id] open CategoryTheory -lemma linearizeTrivialIso_apply {X : Type w} (f : (Action.trivial _ X).V →₀ k) : - (linearizeTrivialIso k G X) f = f := rfl +lemma linearizeTrivialIso_apply {X : Type w} (f : k[(Action.trivial _ X).V]) : + linearizeTrivialIso k G X f = f := rfl -lemma linearizeTrivialIso_symm_apply {X : Type w} (f : X →₀ k) : +lemma linearizeTrivialIso_symm_apply {X : Type w} (f : k[X]) : (linearizeTrivialIso k G X).symm f = f := rfl variable (k G) in /-- This a type-changing equivalence to avoid abusing defeq. -/ def linearizeOfMulActionIso (H : Type w) [MulAction G H] : (linearize k G (Action.ofMulAction G H)).Equiv (ofMulAction k G H) := - .mk (LinearEquiv.refl _ _) fun g ↦ by rfl - --- the following two lemmas are bad but necessary to fix the broken proofs, but once --- we refactor `Action` away these should be removed -lemma linearizeOfMulActionIso_apply {H : Type w} [MulAction G H] (f : H →₀ k) : - @DFunLike.coe ((Representation.ofMulAction k G H).Equiv (Representation.linearize k G - (Action.ofMulAction G H))) (H →₀ k) (fun _ ↦ (Action.ofMulAction G H).V →₀ k) - EquivLike.toFunLike (Representation.linearizeOfMulActionIso k G H) f = f := rfl - -lemma linearizeOfMulActionIso_symm_apply {H : Type w} [MulAction G H] (f : H →₀ k) : - @DFunLike.coe ((Representation.ofMulAction k G H).Equiv (Representation.linearize k G - (Action.ofMulAction G H))) (H →₀ k) (fun _ ↦ (Action.ofMulAction G H).V →₀ k) - EquivLike.toFunLike (Representation.linearizeOfMulActionIso k G H).symm f = f := rfl + .mk (.refl ..) fun _ ↦ rfl variable (k G) in /-- This a type-changing equivalence to avoid abusing defeq. -/ diff --git a/Mathlib/RepresentationTheory/Basic.lean b/Mathlib/RepresentationTheory/Basic.lean index ffa02a90949dc8..4233958ae7607a 100644 --- a/Mathlib/RepresentationTheory/Basic.lean +++ b/Mathlib/RepresentationTheory/Basic.lean @@ -37,9 +37,8 @@ module can be accessed via `ρ.asModule`. Conversely, given a `k[G]`-module `M`, @[expose] public section -open MonoidAlgebra (lift of) +open MonoidAlgebra open LinearMap Module -open scoped MonoidAlgebra section @@ -396,14 +395,11 @@ section MulAction variable (k : Type*) [Semiring k] (G : Type*) [Monoid G] (H : Type*) [MulAction G H] /-- A `G`-action on `H` induces a representation `G →* End(k[H])` in the natural way. -/ -noncomputable def ofMulAction : Representation k G (H →₀ k) where - toFun g := Finsupp.lmapDomain k k (g • ·) - map_one' := by - ext x y - simp - map_mul' x y := by - ext z w - simp [mul_smul] +noncomputable def ofMulAction : Representation k G k[H] where + toFun g := (coeffLinearEquiv k).symm.toLinearMap ∘ₗ Finsupp.lmapDomain k k (g • ·) ∘ₗ + (coeffLinearEquiv k).toLinearMap + map_one' := by ext; simp + map_mul' x y := by ext; simp [mul_smul] /-- The natural `k`-linear `G`-representation on `k[G]` induced by left multiplication in `G`. -/ noncomputable abbrev leftRegular := ofMulAction k G G @@ -413,13 +409,13 @@ noncomputable abbrev diagonal (n : ℕ) := ofMulAction k G (Fin n → G) variable {k G H} -theorem ofMulAction_def (g : G) : ofMulAction k G H g = Finsupp.lmapDomain k k (g • ·) := - rfl +theorem ofMulAction_def (g : G) : + ofMulAction k G H g = (coeffLinearEquiv k).symm.toLinearMap ∘ₗ Finsupp.lmapDomain k k (g • ·) ∘ₗ + (coeffLinearEquiv k).toLinearMap := rfl @[simp] theorem ofMulAction_single (g : G) (x : H) (r : k) : - ofMulAction k G H g (Finsupp.single x r) = Finsupp.single (g • x) r := - Finsupp.mapDomain_single + ofMulAction k G H g (single x r) = single (g • x) r := by simp [ofMulAction_def] end MulAction section DistribMulAction @@ -475,44 +471,44 @@ section variable {k G V : Type*} [Semiring k] [Group G] [AddCommMonoid V] [Module k V] (ρ : Representation k G V) @[simp] -theorem ofMulAction_apply {H : Type*} [MulAction G H] (g : G) (f : H →₀ k) (h : H) : - ofMulAction k G H g f h = f (g⁻¹ • h) := by +theorem coeff_ofMulAction {H : Type*} [MulAction G H] (g : G) (f : k[H]) (h : H) : + (ofMulAction k G H g f).coeff h = f.coeff (g⁻¹ • h) := by conv_lhs => rw [← smul_inv_smul g h] - let h' := g⁻¹ • h - change ofMulAction k G H g f (g • h') = f h' + set h' := g⁻¹ • h have hg : Function.Injective (g • · : H → H) := by intro h₁ h₂ simp - simp only [ofMulAction_def, Finsupp.lmapDomain_apply, Finsupp.mapDomain_apply, hg] + simp [ofMulAction_def, Finsupp.mapDomain_apply, hg] + +@[deprecated (since := "2026-06-18")] alias ofMulAction_apply := coeff_ofMulAction -- Noncomputable since `MonoidAlgebra.instMul` is now noncomputable -noncomputable instance : - HMul k[G] (ofMulAction k G G).asModule k[G] := - inferInstanceAs <| HMul k[G] k[G] k[G] +noncomputable instance : HMul k[G] (ofMulAction k G G).asModule k[G] where + hMul x y := x * (ofMulAction k G G).asModuleEquiv y + end variable {k G V : Type*} [CommSemiring k] [Group G] [AddCommMonoid V] [Module k V] (ρ : Representation k G V) -set_option backward.isDefEq.respectTransparency false in -theorem ofMulAction_self_smul_eq_mul (x : k[G]) (y : (ofMulAction k G G).asModule) : - x • y = (x * y : k[G]) := by - induction x using MonoidAlgebra.induction_on with - | hM g => - change asAlgebraHom (ofMulAction k G G) _ _ = _ - ext - -- Porting note: single_mul_apply not firing in simp without parentheses, probably due to the - -- defeq abuse in `change` above. - simp [(MonoidAlgebra.single_mul_apply)] - | hadd x y hx hy => simp only [hx, hy, add_mul, add_smul] +@[simp] +lemma asAlgebraHom_ofMulAction_smul_eq_mul (x y : k[G]) : + (ofMulAction k G G).asAlgebraHom x y = x * y := by + induction x using induction_on with + | hM g => ext; simp [MonoidAlgebra.coeff_single_mul_apply] + | hadd x y hx hy => simp [hx, hy, add_mul] | hsmul r x hx => simp [← hx] +@[deprecated (since := "2026-06-18")] +alias ofMulAction_self_smul_eq_mul := asAlgebraHom_ofMulAction_smul_eq_mul + /-- If we equip `k[G]` with the `k`-linear `G`-representation induced by the left regular action of `G` on itself, the resulting object is isomorphic as a `k[G]`-module to `k[G]` with its natural `k[G]`-module structure. -/ @[simps] -noncomputable def ofMulActionSelfAsModuleEquiv : (ofMulAction k G G).asModule ≃ₗ[k[G]] k[G] := - { (asModuleEquiv _).toAddEquiv with map_smul' := ofMulAction_self_smul_eq_mul } +noncomputable def ofMulActionSelfAsModuleEquiv : (ofMulAction k G G).asModule ≃ₗ[k[G]] k[G] where + toAddEquiv := (asModuleEquiv _).toAddEquiv + map_smul' := by simp /-- When `G` is a group, a `k`-linear representation of `G` on `V` can be thought of as a group homomorphism from `G` into the invertible `k`-linear endomorphisms of `V`. @@ -532,43 +528,45 @@ open Finsupp lemma leftRegular_norm_apply : (leftRegular k G).norm = (LinearMap.lsmul k _).flip ((leftRegular k G).norm (single 1 1)) ∘ₗ - linearCombination _ (fun _ => 1) := by + linearCombination _ (fun _ => 1) ∘ₗ (coeffLinearEquiv _).toLinearMap := by ext i : 2 simpa [Representation.norm] using Finset.sum_bijective _ (Group.mulRight_bijective i) (by simp) (by simp) -lemma leftRegular_norm_eq_zero_iff (x : G →₀ k) : - (leftRegular k G).norm x = 0 ↔ x.linearCombination k (fun _ => (1 : k)) = 0 := by +lemma leftRegular_norm_eq_zero_iff (x : k[G]) : + (leftRegular k G).norm x = 0 ↔ x.coeff.linearCombination k (fun _ => (1 : k)) = 0 := by rw [leftRegular_norm_apply] constructor - · intro h - simpa [norm, Representation.norm] using Finsupp.ext_iff.1 h 1 + · rw [MonoidAlgebra.ext_iff, Finsupp.ext_iff] + intro h + simpa [norm, Representation.norm] using h 1 · intro h ext simp_all lemma ker_leftRegular_norm_eq : - LinearMap.ker (leftRegular k G).norm = - LinearMap.ker (linearCombination k (fun _ => (1 : k))) := by + LinearMap.ker (leftRegular k G).norm = LinearMap.ker + (linearCombination k (fun _ => (1 : k)) ∘ₗ (coeffLinearEquiv _).toLinearMap) := by ext exact leftRegular_norm_eq_zero_iff _ end Finite section Cyclic -lemma apply_eq_of_leftRegular_eq_of_generator (g : G) (hg : ∀ x, x ∈ Subgroup.zpowers g) - (x : G →₀ k) (hx : leftRegular k G g x = x) (γ : G) : - x γ = x g := by +lemma coeff_of_leftRegular_of_generator (g : G) (hg : ∀ x, x ∈ Subgroup.zpowers g) + (x : k[G]) (hx : leftRegular k G g x = x) (γ : G) : + x.coeff γ = x.coeff g := by + rw [MonoidAlgebra.ext_iff, Finsupp.ext_iff] at hx rcases hg γ with ⟨i, rfl⟩ induction i with - | zero => - simpa using (Finsupp.ext_iff.1 hx g) + | zero => simpa using hx g | succ n h => - simpa [← h, zpow_natCast, zpow_add_one, pow_mul_comm', pow_succ'] using - (Finsupp.ext_iff.1 hx (g ^ (n + 1))).symm + simpa [← h, zpow_natCast, zpow_add_one, pow_mul_comm', pow_succ'] using (hx (g ^ (n + 1))).symm | pred n h => - simpa [zpow_sub, ← h, ← mul_inv_rev, ← pow_mul_comm'] - using Finsupp.ext_iff.1 hx (g ^ (-n : ℤ)) + simpa [zpow_sub, ← h, ← mul_inv_rev, ← pow_mul_comm'] using hx (g ^ (-n : ℤ)) + +@[deprecated (since := "2026-06-18")] +alias apply_eq_of_leftRegular_eq_of_generator := coeff_of_leftRegular_of_generator end Cyclic end Group @@ -677,9 +675,7 @@ def dual : Representation k G (Module.Dual k V) where toFun g := { toFun := fun f => f ∘ₗ ρV g⁻¹ map_add' := fun f₁ f₂ => by simp only [add_comp] - map_smul' := fun r f => by - ext - simp only [coe_comp, Function.comp_apply, smul_apply, RingHom.id_apply] } + map_smul' r f := by ext; simp } map_one' := by ext; simp map_mul' g h := by ext; simp @@ -712,7 +708,7 @@ open Finsupp @[simps -isSimp] noncomputable def finsupp (α : Type*) : Representation k G (α →₀ A) where - toFun g := lsum k fun i => (lsingle i).comp (ρ g) + toFun g := lsum k fun i => (Finsupp.lsingle i).comp (ρ g) map_one' := lhom_ext (fun _ _ => by simp) map_mul' _ _ := lhom_ext (fun _ _ => by simp) @@ -723,34 +719,39 @@ lemma finsupp_single (g : G) (x : α) (a : A) : /-- The representation on `α →₀ k[G]` defined pointwise by the left regular representation. -/ noncomputable abbrev free (k G : Type*) [CommSemiring k] [Monoid G] (α : Type*) : - Representation k G (α →₀ G →₀ k) := + Representation k G (α →₀ k[G]) := finsupp (leftRegular k G) α noncomputable instance (k G : Type*) [CommRing k] [Monoid G] (α : Type*) : AddCommGroup (free k G α).asModule := - inferInstanceAs <| AddCommGroup (α →₀ G →₀ k) + inferInstanceAs <| AddCommGroup (α →₀ k[G]) lemma free_single_single (g h : G) (i : α) (r : k) : - free k G α g (single i (single h r)) = single i (single (g * h) r) := by + free k G α g (single i (single h r)) = .single i (single (g * h) r) := by simp variable (k G) (α : Type*) set_option backward.isDefEq.respectTransparency false in /-- The free `k[G]`-module on a type `α` is isomorphic to the representation `free k G α`. -/ -noncomputable def finsuppLEquivFreeAsModule : (α →₀ k[G]) ≃ₗ[k[G]] (free k G α).asModule := - { AddEquiv.refl _ with - map_smul' _ x := by - simp only [AddEquiv.toEquiv_eq_coe, Equiv.toFun_as_coe, EquivLike.coe_coe, - AddEquiv.refl_apply, RingHom.id_apply] - induction x using Finsupp.induction with - | zero => simp only [smul_zero] - | single_add _ _ _ _ _ h => - rw [smul_add, h] - change _ + asAlgebraHom _ _ _ = asAlgebraHom _ _ _ - simp only [map_add, smul_single, smul_eq_mul, MonoidAlgebra.mul_def, - asAlgebraHom_def, MonoidAlgebra.lift_apply] - simp [free, MonoidAlgebra, asModule, ofMulAction_def, mapDomain, smul_sum, single_sum] } +noncomputable def finsuppLEquivFreeAsModule : (α →₀ k[G]) ≃ₗ[k[G]] (free k G α).asModule where + toAddEquiv := (asModuleEquiv _).symm.toAddEquiv + map_smul' x y := by + simp only [AddHom.toFun_eq_coe, coe_toAddHom, LinearEquiv.coe_coe, RingHom.id_apply, + (free k G α).asModuleEquiv.symm_apply_eq, asModuleEquiv_map_smul, + LinearEquiv.apply_symm_apply] + induction x using MonoidAlgebra.induction_linear with + | zero => simp + | add => simp [*, add_smul] + | single g a => + induction y using Finsupp.induction_linear with + | zero => simp + | add => simp [*] + | single h y => + induction y using MonoidAlgebra.induction_linear with + | zero => simp + | add => simp [*] + | single i b => simp /-- `α` gives a `k[G]`-basis of the representation `free k G α`. -/ noncomputable def freeAsModuleBasis : Basis α k[G] (free k G α).asModule where diff --git a/Mathlib/RepresentationTheory/Coinduced.lean b/Mathlib/RepresentationTheory/Coinduced.lean index 51fb493a80f113..44a3d67e79da9e 100644 --- a/Mathlib/RepresentationTheory/Coinduced.lean +++ b/Mathlib/RepresentationTheory/Coinduced.lean @@ -164,7 +164,7 @@ noncomputable def _root_.Representation.coind' : Representation k H (res φ (leftRegular k H) ⟶ A) where toFun h := { toFun f := (resFunctor φ).map ((leftRegularHomEquiv (leftRegular k H)).symm.toLinearMap - (Finsupp.single h 1)) ≫ f + (.single h 1)) ≫ f map_add' _ _ := rfl map_smul' _ _ := rfl } map_one' := by @@ -211,7 +211,8 @@ to the `G`-representation morphisms `k[H] ⟶ A`. -/ @[simps] noncomputable def coindVEquiv : A.ρ.coindV φ ≃ₗ[k] (res φ (leftRegular k H) ⟶ A) where - toFun f := Rep.ofHom ⟨linearCombination _ f.1, fun g ↦ by dsimp; ext; simp [f.2 g]⟩ + toFun f := Rep.ofHom ⟨linearCombination _ f.1 ∘ₗ (MonoidAlgebra.coeffLinearEquiv _).toLinearMap, + fun g ↦ by dsimp; ext; simp [f.2 g]⟩ map_add' _ _ := coind'_ext φ <| by simp [Rep.add_hom] map_smul' _ _ := coind'_ext φ <| by simp [smul_hom] invFun f := ⟨fun h ↦ f.hom.toLinearMap (.single h 1), fun g h ↦ by diff --git a/Mathlib/RepresentationTheory/Coinvariants.lean b/Mathlib/RepresentationTheory/Coinvariants.lean index 7182029e0d4dc9..000afd91aa3a59 100644 --- a/Mathlib/RepresentationTheory/Coinvariants.lean +++ b/Mathlib/RepresentationTheory/Coinvariants.lean @@ -40,6 +40,8 @@ left adjoint to the functor equipping a module with the trivial representation. @[expose] public section +open scoped MonoidAlgebra + universe w w' u u' v v' namespace Representation @@ -267,12 +269,13 @@ lemma Coinvariants.mk_tmul_inv (x : V) (y : W) (g : G) : `⟦v ⊗ single g r⟧ ↦ r • ρ(g⁻¹)(v)`. -/ noncomputable def ofCoinvariantsTprodLeftRegular : Coinvariants (ρ.tprod (leftRegular k G)) →ₗ[k] V := - Coinvariants.lift _ (TensorProduct.lift (Finsupp.linearCombination _ fun g => ρ g⁻¹) ∘ₗ + Coinvariants.lift _ (TensorProduct.lift ((Finsupp.linearCombination _ fun g => ρ g⁻¹) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap) ∘ₗ (_root_.TensorProduct.comm _ _ _).toLinearMap) fun _ => by ext; simp @[simp] lemma ofCoinvariantsTprodLeftRegular_mk_tmul_single (x : V) (g : G) (r : k) : - ofCoinvariantsTprodLeftRegular ρ (Coinvariants.mk _ (x ⊗ₜ Finsupp.single g r)) = r • ρ g⁻¹ x := + ofCoinvariantsTprodLeftRegular ρ (Coinvariants.mk _ (x ⊗ₜ .single g r)) = r • ρ g⁻¹ x := congr($(Finsupp.linearCombination_single k (v := fun g => ρ g⁻¹) r g) x) /-- Given a `k`-linear `G`-representation `(V, ρ)`, this is the linear equivalence @@ -281,7 +284,7 @@ lemma ofCoinvariantsTprodLeftRegular_mk_tmul_single (x : V) (g : G) (r : k) : noncomputable def coinvariantsTprodLeftRegularLEquiv : Coinvariants (ρ.tprod (leftRegular k G)) ≃ₗ[k] V := LinearEquiv.ofLinear (ofCoinvariantsTprodLeftRegular ρ) - (Coinvariants.mk _ ∘ₗ (TensorProduct.mk k V (G →₀ k)).flip (single 1 1)) + (Coinvariants.mk _ ∘ₗ (TensorProduct.mk k V k[G]).flip (.single 1 1)) (by ext; simp) (by ext; simp) @[simp] @@ -451,22 +454,23 @@ section Finsupp open MonoidalCategory Finsupp -variable {k G : Type u} [CommRing k] [Group G] (A : Rep k G) (α : Type u) [DecidableEq α] +variable {k G : Type u} [CommRing k] [Group G] (A : Rep.{u} k G) (α : Type u) [DecidableEq α] + /-- Given a `k`-linear `G`-representation `(A, ρ)` and a type `α`, this is the map `(A ⊗ (α →₀ k[G]))_G →ₗ[k] (α →₀ A)` sending `⟦a ⊗ single x (single g r)⟧ ↦ single x (r • ρ(g⁻¹)(a)).` -/ noncomputable def coinvariantsTensorFreeToFinsupp : - (A ⊗ free k G α).ρ.Coinvariants →ₗ[k] (α →₀ A) := - (coinvariantsFinsuppLEquiv _ α ≪≫ₗ lcongr (Equiv.refl α) - (coinvariantsTprodLeftRegularLEquiv A.ρ)).toLinearMap ∘ₗ - ((coinvariantsFunctor k G).map (finsuppTensorRight k G A (leftRegular k G) α).hom).hom + (A ⊗ free.{u, u, u} k G α).ρ.Coinvariants.{u, u, u} →ₗ[k] (α →₀ A) := + (coinvariantsFinsuppLEquiv _ α ≪≫ₗ lcongr (Equiv.refl α) (coinvariantsTprodLeftRegularLEquiv + A.ρ)).toLinearMap ∘ₗ Coinvariants.map _ _ + (Representation.finsuppTensorRight _ _ _).toIntertwiningMap variable {α} @[simp] lemma coinvariantsTensorFreeToFinsupp_mk_tmul_single (x : A) (i : α) (g : G) (r : k) : DFunLike.coe (F := (A.ρ.tprod (Representation.free k G α)).Coinvariants →ₗ[k] α →₀ A.V) - (coinvariantsTensorFreeToFinsupp A α) (Coinvariants.mk _ (x ⊗ₜ single i (single g r))) = + (coinvariantsTensorFreeToFinsupp A α) (Coinvariants.mk _ (x ⊗ₜ single i (.single g r))) = single i (r • A.ρ g⁻¹ x) := by simp [coinvariantsTensorFreeToFinsupp, Representation.finsuppTensorRight] @@ -476,18 +480,17 @@ variable (α) `(α →₀ A) →ₗ[k] (A ⊗ (α →₀ k[G]))_G` sending `single x a ↦ ⟦a ⊗ₜ single x 1⟧.` -/ noncomputable def finsuppToCoinvariantsTensorFree : (α →₀ A) →ₗ[k] Coinvariants (A.ρ.tprod (free k G α).ρ) := - ((coinvariantsFunctor k G).map ((finsuppTensorRight k G A (leftRegular k G) α)).inv).hom ∘ₗ - (coinvariantsFinsuppLEquiv _ α ≪≫ₗ - lcongr (Equiv.refl α) (coinvariantsTprodLeftRegularLEquiv A.ρ)).symm.toLinearMap + Coinvariants.map _ _ (Representation.finsuppTensorRight _ _ _).symm.toIntertwiningMap ∘ₗ + (coinvariantsFinsuppLEquiv _ α ≪≫ₗ lcongr (Equiv.refl α) + (coinvariantsTprodLeftRegularLEquiv A.ρ)).symm.toLinearMap variable {A α} -set_option backward.defeqAttrib.useBackward true in @[simp] lemma finsuppToCoinvariantsTensorFree_single (i : α) (x : A) : DFunLike.coe (F := (α →₀ A.V) →ₗ[k] (A.ρ.tprod (Representation.free k G α)).Coinvariants) (finsuppToCoinvariantsTensorFree A α) (single i x) = - Coinvariants.mk _ (x ⊗ₜ single i (single (1 : G) (1 : k))) := by + Coinvariants.mk _ (x ⊗ₜ single i (.single (1 : G) (1 : k))) := by simp [finsuppToCoinvariantsTensorFree, Representation.finsuppTensorRight, Equiv.mk_symm] variable (A α) @@ -503,7 +506,7 @@ noncomputable abbrev coinvariantsTensorFreeLEquiv : simp [finsuppToCoinvariantsTensorFree_single, coinvariantsTensorFreeToFinsupp_mk_tmul_single]) <| Coinvariants.hom_ext <| TensorProduct.ext <| LinearMap.ext fun a => lhom_ext' fun i => - lhom_ext fun g r => by + MonoidAlgebra.lhom_ext' fun g => LinearMap.ext fun r => by simp [coinvariantsTensorFreeToFinsupp_mk_tmul_single _, finsuppToCoinvariantsTensorFree_single (A := A) i, TensorProduct.smul_tmul] diff --git a/Mathlib/RepresentationTheory/Equiv.lean b/Mathlib/RepresentationTheory/Equiv.lean index 16045234dbd2f6..e1ee9239802ab7 100644 --- a/Mathlib/RepresentationTheory/Equiv.lean +++ b/Mathlib/RepresentationTheory/Equiv.lean @@ -20,6 +20,8 @@ all the `Iso`s in `Rep` using the equivs in this file. @[expose] public section +open scoped MonoidAlgebra + universe u u' v v' w w' variable {k : Type u} [Semiring k] {G : Type v} [Monoid G] {V : Type v'} [AddCommMonoid V] @@ -34,33 +36,30 @@ variable (k G) in /-- If there exists `G`-action on a trivial monoid `H` then the induced representation on `k[H]` is equivalent to the trivial representation. -/ def ofMulActionSubsingletonEquivTrivial : (ofMulAction k G H).Equiv (trivial k G k) := - .mk (Finsupp.uniqueLinearEquiv _ _ 1) fun g ↦ by - ext a; simp [Subsingleton.elim (g • a) a] + .mk (MonoidAlgebra.uniqueLinearEquiv k H) fun g ↦ by ext a; simp [Subsingleton.elim (g • a) a] @[simp] -lemma ofMulActionSubsingletonEquivTrivial_apply (f : H →₀ k) : - (ofMulActionSubsingletonEquivTrivial k G H).toIntertwiningMap.toLinearMap f = f 1 := rfl +lemma ofMulActionSubsingletonEquivTrivial_apply (f : k[H]) : + (ofMulActionSubsingletonEquivTrivial k G H).toIntertwiningMap.toLinearMap f = f.coeff 1 := rfl @[simp] lemma ofMulActionSubsingletonEquivTrivial_symm_apply (r : k) : (ofMulActionSubsingletonEquivTrivial k G H).symm.toIntertwiningMap.toLinearMap r = - Finsupp.single 1 r := rfl + .single 1 r := rfl variable (k G) in /-- The equivalence of representations between `(Fin 1 → G) →₀ k` and `G →₀ k`. -/ def diagonalOneEquivLeftRegular : (diagonal k G 1).Equiv (leftRegular k G) := - .mk (Finsupp.domLCongr (Equiv.funUnique (Fin 1) G)) fun g ↦ by ext; simp + .mk (MonoidAlgebra.mapDomainLinearEquiv _ _ <| .funUnique _ _) fun g ↦ by ext; simp @[simp] lemma diagonalOneEquivLeftRegular_apply_single (f : Fin 1 → G) (r : k) : - (diagonalOneEquivLeftRegular k G) (Finsupp.single f r) = - Finsupp.single (f 0) r := by + (diagonalOneEquivLeftRegular k G) (.single f r) = .single (f 0) r := by simp [diagonalOneEquivLeftRegular] @[simp] lemma diagonalOneEquivLeftRegular_symm_apply_single (g : G) (r : k) : - (diagonalOneEquivLeftRegular k G).symm (Finsupp.single g r) = - Finsupp.single (uniqueElim g) r := by + (diagonalOneEquivLeftRegular k G).symm (.single g r) = .single (uniqueElim g) r := by simp [diagonalOneEquivLeftRegular] section comm @@ -72,16 +71,17 @@ section finsupp open Finsupp -/-- Every `f : α → V` can induce an intertwining map between `(α →₀ G →₀ k)` and `V`. -/ +/-- Every `f : α → V` can induce an intertwining map between `(α →₀ k[G])` and `V`. -/ @[simps! toLinearMap] def freeLift {α : Type w'} (f : α → V) : (free k G α).IntertwiningMap σ where - __ := linearCombination k (fun x => σ x.2 (f x.1)) ∘ₗ - (curryLinearEquiv k).symm.toLinearMap + toLinearMap := linearCombination k (fun x => σ x.2 (f x.1)) ∘ₗ + (curryLinearEquiv k).symm.toLinearMap ∘ₗ + Finsupp.mapRange.linearMap (MonoidAlgebra.coeffLinearEquiv _).toLinearMap isIntertwining' g := by ext; simp @[simp] lemma freeLift_single_single {α : Type w'} (i : α) (g : G) (r : k) (f : α → V) : - freeLift σ f (Finsupp.single i (Finsupp.single g r)) = r • σ g (f i) := by + freeLift σ f (Finsupp.single i (.single g r)) = r • σ g (f i) := by simp [freeLift] open IntertwiningMap @@ -89,7 +89,7 @@ open IntertwiningMap /-- Equiv between the intertwining map module `(α →₀ G →₀ k) → V` and the function space `α → V`. -/ @[simps] def freeLiftLEquiv (α : Type w') : ((free k G α).IntertwiningMap σ) ≃ₗ[k] (α → V) where - toFun f i := f (single i (single 1 1)) + toFun f i := f (single i (.single 1 1)) map_add' _ _ := rfl map_smul' _ _ := rfl invFun := freeLift σ @@ -141,36 +141,40 @@ lemma finsuppTensorRight_symm_apply_single {α : Type w'} [DecidableEq α] (i : /-- Equiv between representations induced by linear equiv between `(G →₀ k) ⊗[k] (α →₀ k)` and `α →₀ G →₀ k`. -/ def leftRegularTensorTrivialIsoFree (α : Type w') : - ((leftRegular k G).tprod (trivial k G (α →₀ k))).Equiv (free k G α) := - .mk (finsuppTensorFinsupp' k G α ≪≫ₗ Finsupp.domLCongr (Equiv.prodComm G α) ≪≫ₗ - curryLinearEquiv k) <| fun g ↦ by ext; simp + ((leftRegular k G).tprod (trivial k G k[α])).Equiv (free k G α) := + .mk (TensorProduct.congr (MonoidAlgebra.coeffLinearEquiv _) (MonoidAlgebra.coeffLinearEquiv _) ≪≫ₗ + finsuppTensorFinsupp' k G α ≪≫ₗ Finsupp.domLCongr (Equiv.prodComm G α) ≪≫ₗ curryLinearEquiv k + ≪≫ₗ Finsupp.mapRange.linearEquiv (MonoidAlgebra.coeffLinearEquiv _).symm) fun g ↦ by ext; simp @[simp] lemma leftRegularTensorTrivialIsoFree_apply_single_tmul_single {α : Type w'} (g : G) (i : α) - (r s : k) : leftRegularTensorTrivialIsoFree α (Finsupp.single g r ⊗ₜ Finsupp.single i s) = - Finsupp.single i (Finsupp.single g (r * s)) := by + (r s : k) : leftRegularTensorTrivialIsoFree α (.single g r ⊗ₜ .single i s) = + .single i (.single g (r * s)) := by simp [leftRegularTensorTrivialIsoFree] @[simp] lemma leftRegularTensorTrivialIsoFree_symm_apply_single_single {α : Type w'} (i : α) (g : G) - (r : k) : (leftRegularTensorTrivialIsoFree α).symm (Finsupp.single i (Finsupp.single g r)) = - Finsupp.single g 1 ⊗ₜ Finsupp.single i r := by + (r : k) : + (leftRegularTensorTrivialIsoFree α).symm (.single i (.single g r)) = + .single g 1 ⊗ₜ .single i r := by simp [leftRegularTensorTrivialIsoFree, finsuppTensorFinsupp'_symm_single_eq_single_one_tmul] end finsupp /-- The linear equiv between the hom module `k[G] ⟶ᵍ V` and `V` itself. -/ @[simps!] -def leftRegularMapEquiv : ((leftRegular k G).IntertwiningMap σ) ≃ₗ[k] V where - toFun f := (Finsupp.llift V k k G).symm f.toLinearMap (1 : G) +def leftRegularMapEquiv : (leftRegular k G).IntertwiningMap σ ≃ₗ[k] V where + toFun f := (Finsupp.llift V k k G).symm + (f.toLinearMap ∘ₗ (MonoidAlgebra.coeffLinearEquiv _).symm.toLinearMap) (1 : G) map_add' _ _ := rfl map_smul' _ _ := rfl - invFun v := ⟨Finsupp.llift _ _ k _ (fun g ↦ σ g v), fun g ↦ by ext g'; simp⟩ + invFun v := ⟨Finsupp.llift _ _ k _ (fun g ↦ σ g v) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv _).toLinearMap, fun g ↦ by ext g'; simp⟩ left_inv x := by ext; simp [← x.isIntertwining] right_inv v := by simp lemma leftRegularMapEquiv_symm_single (g : G) (v : V) : - ((leftRegularMapEquiv σ).symm v) (Finsupp.single g 1) = σ g v := by + ((leftRegularMapEquiv σ).symm v) (.single g 1) = σ g v := by simp end comm diff --git a/Mathlib/RepresentationTheory/FiniteIndex.lean b/Mathlib/RepresentationTheory/FiniteIndex.lean index 49c52f3cd7e9cd..89cf8b2082da03 100644 --- a/Mathlib/RepresentationTheory/FiniteIndex.lean +++ b/Mathlib/RepresentationTheory/FiniteIndex.lean @@ -104,8 +104,9 @@ variable (A) in `Ind_S^G(A) →ₗ[k] Coind_S^G(A)` sending `(⟦g ⊗ₜ[k] a⟧, sg) ↦ ρ(s)(a)`. -/ noncomputable abbrev indToCoind : ind S.subtype A →ₗ[k] coind S.subtype A := - Representation.Coinvariants.lift _ (TensorProduct.lift <| linearCombination _ fun g => - LinearMap.codRestrict _ (indToCoindAux A g) fun _ _ _ => by simp) fun _ => by ext; simp + Representation.Coinvariants.lift _ (TensorProduct.lift <| (linearCombination _ fun g => + LinearMap.codRestrict _ (indToCoindAux A g) fun _ _ _ => by simp) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap) fun _ => by ext; simp variable [S.FiniteIndex] @@ -120,7 +121,7 @@ noncomputable def coindToInd : coind S.subtype A →ₗ[k] ind S.subtype A where toFun f := ∑ g : Quotient (QuotientGroup.rightRel S), Quotient.liftOn g (fun g => IndV.mk S.subtype _ g (f.1 g)) fun g₁ g₂ ⟨s, (hs : _ * _ = _)⟩ => (Submodule.Quotient.eq _).2 <| Coinvariants.mem_ker_of_eq s - (single g₂ 1 ⊗ₜ[k] f.1 g₂) _ <| by have := f.2 s g₂; simp_all + (.single g₂ 1 ⊗ₜ[k] f.1 g₂) _ <| by have := f.2 s g₂; simp_all map_add' _ _ := by simpa [← Finset.sum_add_distrib, TensorProduct.tmul_add] using Finset.sum_congr rfl fun z _ => Quotient.inductionOn z fun _ => by simp map_smul' _ _ := by simpa [Finset.smul_sum] using Finset.sum_congr rfl fun z _ => diff --git a/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean b/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean index 8917b431d54b8b..7cb18640e27cf4 100644 --- a/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean +++ b/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean @@ -72,20 +72,21 @@ noncomputable def coinvariantsEquiv (hg : ∀ x, x ∈ Subgroup.zpowers g) : variable [Finite G] in lemma coinvariantsKer_leftRegular_eq_ker : Coinvariants.ker (Representation.leftRegular k G) = - LinearMap.ker (linearCombination k (fun _ => (1 : k))) := by + LinearMap.ker ((linearCombination k (fun _ => (1 : k))) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap) := by have := Fintype.ofFinite G refine le_antisymm (Submodule.span_le.2 ?_) fun x hx => ?_ · rintro x ⟨⟨g, y⟩, rfl⟩ simpa [linearCombination, sub_eq_zero, sum_fintype] using Finset.sum_bijective _ (Group.mulLeft_bijective g⁻¹) (by simp) (by lia) - · have : x = x.sum (fun g r => single g r - single 1 r) := by + · have : x = x.coeff.sum (fun g r => .single g r - .single 1 r) := by ext g by_cases hg : g = 1 - · simp_all [linearCombination, sum_apply'] - · simp_all [sum_apply'] + · simp_all [linearCombination, sum_apply', MonoidAlgebra.coeff_finsuppSum] + · simp_all [sum_apply', MonoidAlgebra.coeff_finsuppSum] rw [this] exact Submodule.finsuppSum_mem _ _ _ _ fun g _ => - Coinvariants.mem_ker_of_eq g (single 1 (x g)) _ (by simp) + Coinvariants.mem_ker_of_eq g (.single 1 (x.coeff g)) _ (by simp) end Representation.FiniteCyclicGroup @@ -101,16 +102,17 @@ lemma range_norm_eq_ker_applyAsHom_sub (hg : ∀ x, x ∈ Subgroup.zpowers g) : LinearMap.range (leftRegular k G).norm.hom.toLinearMap = LinearMap.ker (applyAsHom (leftRegular k G) g - 𝟙 _).hom.toLinearMap := le_antisymm (fun _ ⟨_, h⟩ => by simp [sub_hom, applyAsHom_apply _, ← h, norm]) - fun x hx => ⟨single 1 (x g), by - ext - have := apply_eq_of_leftRegular_eq_of_generator (k := k) g hg x - (by simpa [sub_hom, sub_eq_zero] using! hx) + fun x hx => ⟨.single 1 (x.coeff g), by + ext γ + have := coeff_of_leftRegular_of_generator (k := k) g hg x + (by simpa [sub_hom, sub_eq_zero] using! hx) γ simp [norm, Representation.norm, this]⟩ omit [Fintype G] in variable [Finite G] in lemma range_applyAsHom_sub_eq_ker_linearCombination (hg : ∀ x, x ∈ Subgroup.zpowers g) : LinearMap.range (applyAsHom (leftRegular k G) g - 𝟙 _).hom.toLinearMap = - LinearMap.ker (linearCombination k (fun _ => (1 : k))) := by + LinearMap.ker ((linearCombination k (fun _ => (1 : k))) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap) := by simp [sub_hom, applyAsHom, FiniteCyclicGroup.coinvariantsKer_eq_range (Representation.leftRegular k G) _ hg, ← FiniteCyclicGroup.coinvariantsKer_leftRegular_eq_ker] @@ -216,7 +218,7 @@ lemma resolution_quasiIso (g : G) (hg : ∀ x, x ∈ Subgroup.zpowers g) : leftRegular.range_applyAsHom_sub_eq_ker_linearCombination k g hg · rw [Rep.epi_iff_surjective] intro x - use single 1 x + use .single 1 x simp [ChainComplex.toSingle₀Equiv] | succ m _ => rw [quasiIsoAt_iff_exactAt' (hL := ChainComplex.exactAt_succ_single_obj ..), diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/Basic.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/Basic.lean index 6ac4d17b8f0721..23f095f27942ee 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/Basic.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/Basic.lean @@ -140,7 +140,6 @@ theorem d_single (n : ℕ) (g : Fin (n + 1) → G) (a : A) : open ModuleCat.MonoidalCategory set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem d_eq [DecidableEq G] : d A n = (coinvariantsTensorFreeLEquiv A (Fin (n + 1) → G)).toModuleIso.inv ≫ ((barComplex k G).coinvariantsTensorObj A).d (n + 1) n ≫ diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean index e37cbc3f4b6994..aba75e46af8252 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean @@ -58,7 +58,8 @@ noncomputable def coinvariantsTensorResolutionIso (hg : ∀ x, x ∈ Subgroup.zp moduleCatChainComplex A g := HomologicalComplex.Hom.isoOfComponents (fun _ => (coinvariantsTprodLeftRegularLEquiv A.ρ).toModuleIso) fun i j h => - coinvariantsTensor_hom_ext (LinearMap.ext fun a => lhom_ext' fun g => LinearMap.ext_ring (by + coinvariantsTensor_hom_ext (LinearMap.ext fun a => + MonoidAlgebra.lhom_ext' fun g => LinearMap.ext_ring (by subst h by_cases hj : Even (j + 1) · simpa [hj, coinvariantsTensorMk, ofCoinvariantsTprodLeftRegular, Rep.norm, diff --git a/Mathlib/RepresentationTheory/Homological/Resolution.lean b/Mathlib/RepresentationTheory/Homological/Resolution.lean index ec47f3ab77cab3..7708522c2163a4 100644 --- a/Mathlib/RepresentationTheory/Homological/Resolution.lean +++ b/Mathlib/RepresentationTheory/Homological/Resolution.lean @@ -150,7 +150,8 @@ def extraDegeneracyCompForgetAugmented : ExtraDegeneracy (compForgetAugmented G) space of `G` as a simplicial set, augmented by the map from `Fin 1 → G` to the terminal object in `Type u`. -/ def compForgetAugmented.toModule : SimplicialObject.Augmented (ModuleCat.{u} k) := - ((SimplicialObject.Augmented.whiskering _ _).obj (ModuleCat.free k)).obj (compForgetAugmented G) + ((SimplicialObject.Augmented.whiskering _ _).obj (ModuleCat.monoidAlgebraFree k)).obj + (compForgetAugmented G) /-- If we augment the universal cover of the classifying space of `G` as a simplicial set by the map from `Fin 1 → G` to the terminal object in `Type u`, then apply the free functor @@ -158,7 +159,7 @@ map from `Fin 1 → G` to the terminal object in `Type u`, then apply the free f degeneracy. -/ def extraDegeneracyCompForgetAugmentedToModule : ExtraDegeneracy (compForgetAugmented.toModule k G) := - ExtraDegeneracy.map (extraDegeneracyCompForgetAugmented G) (ModuleCat.free k) + .map (extraDegeneracyCompForgetAugmented G) (ModuleCat.monoidAlgebraFree k) end classifyingSpaceUniversalCover @@ -176,25 +177,23 @@ open classifyingSpaceUniversalCover AlgebraicTopology CategoryTheory.Limits /-- The `k`-linear map underlying the differential in the standard resolution of `k` as a trivial `k`-linear `G`-representation. It sends `(g₀, ..., gₙ) ↦ ∑ (-1)ⁱ • (g₀, ..., ĝᵢ, ..., gₙ)`. -/ -def d (G : Type u) (n : ℕ) : ((Fin (n + 1) → G) →₀ k) →ₗ[k] (Fin n → G) →₀ k := - Finsupp.lift ((Fin n → G) →₀ k) k (Fin (n + 1) → G) fun g => +def d (G : Type u) (n : ℕ) : k[Fin (n + 1) → G] →ₗ[k] k[Fin n → G] := + (Finsupp.lift k[Fin n → G] k (Fin (n + 1) → G) fun g => (@Finset.univ (Fin (n + 1)) _).sum fun p => - Finsupp.single (g ∘ p.succAbove) ((-1 : k) ^ (p : ℕ)) + .single (g ∘ p.succAbove) ((-1 : k) ^ (p : ℕ))) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap variable {k G} @[simp] theorem d_of {n : ℕ} (c : Fin (n + 1) → G) : - d k G n (Finsupp.single c 1) = - Finset.univ.sum fun p : Fin (n + 1) => - Finsupp.single (c ∘ p.succAbove) ((-1 : k) ^ (p : ℕ)) := by + d k G n (.single c 1) = ∑ p : Fin (n + 1), .single (c ∘ p.succAbove) ((-1 : k) ^ p.val) := by simp [d] lemma d_single {n : ℕ} (c : Fin (n + 1) → G) (r : k) : - d k G n (Finsupp.single c r) = - Finset.univ.sum fun p : Fin (n + 1) => - Finsupp.single (c ∘ p.succAbove) (r * (-1 : k) ^ (p : ℕ)) := by - rw [← mul_one r, ← smul_eq_mul, ← smul_single, map_smul, d_of] + d k G n (.single c r) = + ∑ p : Fin (n + 1), .single (c ∘ p.succAbove) (r * (-1 : k) ^ p.val) := by + rw [← mul_one r, ← smul_eq_mul, ← MonoidAlgebra.smul_single, map_smul, d_of] simp [Finset.smul_sum] variable (k G) [Monoid G] @@ -215,14 +214,14 @@ set_option backward.isDefEq.respectTransparency false in `G`-representation. It sends `(g₀, ..., gₙ₊₁) ↦ ∑ (-1)ⁱ • (g₀, ..., ĝᵢ, ..., gₙ₊₁)`. -/ theorem d_eq (n : ℕ) : ((standardComplex k G).d (n + 1) n).hom.toLinearMap = d k G (n + 1) := by - refine Finsupp.lhom_ext' fun (x : Fin (n + 2) → G) => LinearMap.ext_ring ?_ + refine MonoidAlgebra.lhom_ext' fun (x : Fin (n + 2) → G) => LinearMap.ext_ring ?_ simp [standardComplex, Action.ofMulAction_V, SimplicialObject.δ, SimplexCategory.δ, Fin.succAboveOrderEmb, ← Int.cast_smul_eq_zsmul k ((-1) ^ _ : ℤ), ← ofHom_smul, ← ofHom_sum, Representation.IntertwiningMap.coe_toLinearMap, Representation.IntertwiningMap.sum_apply, - Representation.IntertwiningMap.smul_apply, (Representation.linearizeMap_single), smul_single, + Representation.IntertwiningMap.smul_apply, (Representation.linearizeMap_single), smul_eq_mul, mul_one] -lemma d_apply {n : ℕ} (f : (Fin (n + 1 + 1) → G) →₀ k) : +lemma d_apply {n : ℕ} (f : k[Fin (n + 1 + 1) → G]) : ((standardComplex k G).d (n + 1) n).hom f = d k G (n + 1) f := by rw [← Representation.IntertwiningMap.toLinearMap_apply, d_eq]; rfl @@ -254,13 +253,14 @@ def forget₂ToModuleCatHomotopyEquiv : (extraDegeneracyCompForgetAugmentedToModule k G)).trans (HomotopyEquiv.ofIso <| (ChainComplex.single₀ (ModuleCat.{u} k)).mapIso - (@Finsupp.uniqueLinearEquiv k (⊤_ Type u) k _ _ _ _ - Types.terminalIso.toEquiv.unique.default).toModuleIso) + (letI : Unique (⊤_ Type u) := Types.terminalIso.toEquiv.unique + ((MonoidAlgebra.coeffLinearEquiv k (M := ⊤_ Type u)).trans + (Finsupp.uniqueLinearEquiv k k default)).toModuleIso)) /-- The hom of `k`-linear `G`-representations `k[G¹] → k` sending `∑ nᵢgᵢ ↦ ∑ nᵢ`. -/ def ε : Rep.ofMulAction k G (Fin 1 → G) ⟶ Rep.trivial k G k := ofHom - ⟨Finsupp.linearCombination _ fun _ ↦ (1 : k), fun _ ↦ Finsupp.lhom_ext' - fun _ => LinearMap.ext_ring <| by simp⟩ + ⟨(Finsupp.linearCombination _ fun _ ↦ (1 : k)) ∘ₗ (MonoidAlgebra.coeffLinearEquiv k).toLinearMap, + fun _ ↦ MonoidAlgebra.lhom_ext' fun _ => LinearMap.ext_ring <| by simp⟩ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @@ -269,12 +269,13 @@ a trivial `G`-representation, and the complex which is `k` at 0 and 0 everywhere `∑ nᵢgᵢ ↦ ∑ nᵢ : k[G¹] → k` at 0. -/ theorem forget₂ToModuleCatHomotopyEquiv_f_0_eq : (forget₂ToModuleCatHomotopyEquiv k G).1.f 0 = (forget₂ (Rep k G) _).map (ε k G) := by - refine ModuleCat.hom_ext <| Finsupp.lhom_ext fun (x : Fin 1 → G) r => ?_ - change mapDomain _ _ _ = Finsupp.linearCombination _ _ _ - simp only [HomotopyEquiv.ofIso, Iso.symm_hom, compForgetAugmented, compForgetAugmentedIso, - eqToIso.inv, HomologicalComplex.eqToHom_f] - change mapDomain _ (single x r) _ = _ - simp [Unique.eq_default (terminal.from _), single_apply, if_pos (Subsingleton.elim _ _)] + refine ModuleCat.hom_ext <| MonoidAlgebra.lhom_ext' fun (x : Fin 1 → G) => LinearMap.ext_ring ?_ + simp [forget₂ToModuleCatHomotopyEquiv, HomotopyEquiv.ofIso, HomotopyEquiv.trans, + SimplicialObject.Augmented.ExtraDegeneracy.homotopyEquiv, ChainComplex.single₀_map_f_zero, + AlgebraicTopology.AlternatingFaceMapComplex.ε_app_f_zero, compForgetAugmentedIso, eqToIso.inv, + HomologicalComplex.eqToHom_f, compForgetAugmented, compForgetAugmented.toModule, ε, + SimplicialObject.augment, Unique.eq_default (terminal.from _), MonoidAlgebra.coeff_single, + Finsupp.single_apply, if_pos (Subsingleton.elim _ _)] set_option backward.isDefEq.respectTransparency false in theorem d_comp_ε : (standardComplex k G).d 1 0 ≫ ε k G = 0 := by @@ -343,55 +344,54 @@ variable (n) `g₀·(g₁, ..., gₙ) + ∑ (-1)ʲ⁺¹·(g₀, ..., gⱼgⱼ₊₁, ..., gₙ) + (-1)ⁿ⁺¹·(g₀, ..., gₙ₋₁)` for `j = 0, ..., n - 1`. -/ def d : free k G Gⁿ⁺¹ ⟶ free k G Gⁿ := - freeLift k G _ fun g => single (fun i => g i.succ) (single (g 0) 1) + - Finset.univ.sum fun j : Fin (n + 1) => - single (Fin.contractNth j (· * ·) g) (single (1 : G) ((-1 : k) ^ ((j : ℕ) + 1))) + freeLift k G _ fun g => single (fun i => g i.succ) (.single (g 0) 1) + + ∑ j : Fin (n + 1), single (j.contractNth (· * ·) g) (.single (1 : G) ((-1 : k) ^ (j.val + 1))) variable {k G} in lemma d_single (x : Gⁿ⁺¹) : - (d k G n).hom (single x (single 1 1)) = single (fun i => x i.succ) (Finsupp.single (x 0) 1) + - Finset.univ.sum fun j : Fin (n + 1) => - single (Fin.contractNth j (· * ·) x) (single (1 : G) ((-1 : k) ^ ((j : ℕ) + 1))) := by + (d k G n).hom (single x (.single 1 1)) = single (fun i => x i.succ) (.single (x 0) 1) + + ∑ j : Fin (n + 1), + single (j.contractNth (· * ·) x) (.single (1 : G) ((-1 : k) ^ (j.val + 1))) := by simp [d, ← Representation.IntertwiningMap.toLinearMap_apply] --- the reason the following two horrible lemmas exist is again because `Action` has bad DefEq and --- we should be able to remove them as soon as we get rid of the use of `Action` in this file. -open scoped MonoidalCategory in -@[simp] -private lemma _root_.Representation.μ_apply_single_single_leftRegular (m : ℕ) (g : G) (r s : k) - (f : Fin m → G) : @DFunLike.coe _ (TensorProduct k ((Action.leftRegular G).V →₀ k) _) - (fun _ ↦ (Action.leftRegular G).V ⊗ (Fin m → G) →₀ k) _ - (Representation.LinearizeMonoidal.μ (Action.leftRegular G) (Action.trivial G (Fin m → G))) - (single g r ⊗ₜ[k] single f s) = single (g, f) (r * s) := - Representation.LinearizeMonoidal.μ_apply_single_single - (X := Action.leftRegular G) (Y := Action.trivial G (Fin m → G)) g f r s - -open scoped MonoidalCategory in -@[simp] -private lemma _root_.Representation.linearizeMap_single_diagonal (m : ℕ) (g : G) (f : Fin m → G) - (r : k) : @DFunLike.coe _ ((Action.leftRegular G).V ⊗ (Fin m → G) →₀ k) - (fun _ ↦ (Action.diagonal G (m + 1)).V →₀ k) _ - (Representation.linearizeMap (Action.diagonalSuccIsoTensorTrivial G m).inv) (single (g, f) r) - = single ((Action.diagonalSuccIsoTensorTrivial G m).inv.hom (g, f)) r := - Representation.linearizeMap_single (Action.diagonalSuccIsoTensorTrivial G m).inv (g, f) r - set_option backward.defeqAttrib.useBackward true in unif_hint (X : Type*) where ⊢ Action.V (Action.trivial G X) ≟ X in -unif_hint where ⊢ (HomologicalComplex.X (standardComplex k G) n).V ≟ ((Fin (n + 1) → G) →₀ k) in +unif_hint where ⊢ (HomologicalComplex.X (standardComplex k G) n).V ≟ k[Fin (n + 1) → G] in set_option backward.isDefEq.respectTransparency false in lemma d_comp_diagonalSuccIsoFree_inv_eq : d k G n ≫ (diagonalSuccIsoFree k G n).inv = (diagonalSuccIsoFree k G (n + 1)).inv ≫ (standardComplex k G).d (n + 1) n := free_ext k G _ _ _ fun i ↦ by - have eq3 : single (i 0 • Fin.partialProd fun i_1 ↦ i i_1.succ) (1 : k) = - single (Fin.partialProd i ∘ Fin.succ) 1 := by + have eq3 : MonoidAlgebra.single (i 0 • Fin.partialProd fun i_1 ↦ i i_1.succ) (1 : k) = + MonoidAlgebra.single (Fin.partialProd i ∘ Fin.succ) 1 := by congr; exact funext fun j ↦ Fin.partialProd_succ' i j |>.symm - simp [μ_hom, d_single (k := k), - Representation.linearizeOfMulActionIso_symm_apply, - Representation.linearizeTrivialIso_symm_apply _, d_apply (k := k), - Representation.μ_apply_single_single_leftRegular _, - Representation.linearizeMap_single_diagonal _] - simp [Fin.partialProd_contractNth, Fin.sum_univ_succ, Action.ofMulAction_V, eq3] + simp only [Rep.hom_comp, Representation.IntertwiningMap.comp_apply] + rw [d_single (k := k), map_add, map_sum] + -- in-context `have`: at `Action` carriers, only locally re-elaborated statements key-match + have H : ∀ (m : ℕ) (f : Fin m → G) (g : G) (r : k), + (diagonalSuccIsoFree k G m).inv.hom (single f (MonoidAlgebra.single g r)) = + MonoidAlgebra.single (g • Fin.partialProd f) r := by + intro m f g r + simp only [diagonalSuccIsoFree, diagonalSuccIsoTensorTrivial, Iso.trans_inv, Rep.hom_comp, + Representation.IntertwiningMap.comp_apply] + have step1 : (Hom.hom (leftRegularTensorTrivialIsoFree k G (Fin m → G)).inv) + (single f (.single g r)) = .single g 1 ⊗ₜ[k] .single f r := + Representation.leftRegularTensorTrivialIsoFree_symm_apply_single_single f g r + rw [step1] + simp only [mkIso_inv, Representation.linearizeOfMulActionIso, Representation.Equiv.mk_symm, + LinearEquiv.refl_symm, ConcreteCategory.hom_ofHom, Action.tensorObj_V, Action.trivial_V, + Functor.mapIso_inv, tensor_V, tensor_ρ, Iso.symm_inv, Functor.Monoidal.μIso_hom, μ_hom, + MonoidalCategory.tensorIso_inv, Representation.linearizeTrivialIso, hom_tensorHom, + Representation.IntertwiningMap.tensor_apply, Representation.Equiv.coe_toIntertwiningMap, + Representation.Equiv.mk_apply, LinearEquiv.refl_apply] + have key₁ := Representation.linearizeMap_single (k := k) + (Action.diagonalSuccIsoTensorTrivial G m).inv (g, f) ((1 : k) * r) + have key₂ := Representation.LinearizeMonoidal.μ_apply_single_single (k := k) + (X := Action.leftRegular G) (Y := Action.trivial G (Fin m → G)) g f 1 r + exact ((congrArg (fun z => (Representation.linearizeMap + (Action.diagonalSuccIsoTensorTrivial G m).inv) z) key₂).trans key₁).trans (by simp) + simp only [H, one_smul] + simp [d_apply (k := k), Fin.partialProd_contractNth, Fin.sum_univ_succ, eq3] end barComplex diff --git a/Mathlib/RepresentationTheory/Induced.lean b/Mathlib/RepresentationTheory/Induced.lean index c7bfc7fafff3a5..2dab755849aaad 100644 --- a/Mathlib/RepresentationTheory/Induced.lean +++ b/Mathlib/RepresentationTheory/Induced.lean @@ -43,6 +43,8 @@ is used to prove Shapiro's lemma in @[expose] public section +open scoped MonoidAlgebra + universe t w w' u u' v v' namespace Representation @@ -56,18 +58,18 @@ variable {k G H : Type*} [CommRing k] [Group G] [Group H] (φ : G →* H) {A B : /-- Given a group homomorphism `φ : G →* H` and a `G`-representation `(A, ρ)`, this is the `k`-module `(k[H] ⊗[k] A)_G` with the `G`-representation on `k[H]` defined by `φ`. See `Representation.ind` for the induced `H`-representation on `IndV φ ρ`. -/ -abbrev IndV := Coinvariants (V := TensorProduct k (H →₀ k) A) +abbrev IndV := Coinvariants (V := TensorProduct k k[H] A) (Representation.tprod ((leftRegular k H).comp φ) ρ) /-- Given a group homomorphism `φ : G →* H` and a `G`-representation `(A, ρ)`, this is the `H → A →ₗ[k] (k[H] ⊗[k] A)_G` sending `h, a` to `⟦h ⊗ₜ a⟧`. -/ noncomputable abbrev IndV.mk (h : H) : A →ₗ[k] IndV φ ρ := - Coinvariants.mk _ ∘ₗ TensorProduct.mk k _ _ (single h 1) + Coinvariants.mk _ ∘ₗ TensorProduct.mk k _ _ (.single h 1) @[ext] lemma IndV.hom_ext {f g : IndV φ ρ →ₗ[k] B} (hfg : ∀ h : H, f ∘ₗ IndV.mk φ ρ h = g ∘ₗ IndV.mk φ ρ h) : f = g := - Coinvariants.hom_ext <| TensorProduct.ext <| Finsupp.lhom_ext' fun h => + Coinvariants.hom_ext <| TensorProduct.ext <| MonoidAlgebra.lhom_ext' fun h => LinearMap.ext_ring <| hfg h /-- Given a group homomorphism `φ : G →* H` and a `G`-representation `A`, this is @@ -75,7 +77,8 @@ lemma IndV.hom_ext {f g : IndV φ ρ →ₗ[k] B} to `⟦h₁h⁻¹ ⊗ₜ a⟧`. -/ @[simps] noncomputable def ind : Representation k H (IndV φ ρ) where - toFun h := Coinvariants.map _ _ ⟨(lmapDomain k k fun x => x * h⁻¹).rTensor _, + toFun h := + Coinvariants.map _ _ ⟨(MonoidAlgebra.mapDomainLinearMap k k fun x => x * h⁻¹).rTensor _, fun _ => by ext; simp [mul_assoc]⟩ map_one' := by ext; simp map_mul' _ _ := by ext; simp [IndV, mul_assoc] @@ -137,16 +140,12 @@ noncomputable def indResHomEquiv (A : Rep.{max w v' u} k G) (B : Rep.{max w v' u map_add' _ _ := rfl map_smul' _ _ := rfl invFun f := Rep.ofHom ⟨Representation.Coinvariants.lift _ - (TensorProduct.lift <| lift _ _ _ fun h => B.ρ h⁻¹ ∘ₗ f.hom.toLinearMap) + (TensorProduct.lift <| (Finsupp.lift _ _ _ fun h => B.ρ h⁻¹ ∘ₗ f.hom.toLinearMap) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap) fun g ↦ by - simp only [res_obj_ρ, tprod_apply, MonoidHom.coe_comp, Function.comp_apply, - TensorProduct.lift_comp_map] - congr 1 - ext - simp only [LinearMap.coe_comp, Function.comp_apply, lsingle_apply, LinearMap.compl₂_apply, - ofMulAction_single, smul_eq_mul, lift_apply, mul_inv_rev, map_mul, zero_smul, - sum_single_index, one_smul, IntertwiningMap.toLinearMap_apply, Module.End.mul_apply] - rw [hom_comm_apply f g _]; simp, fun g ↦ by ext; simp⟩ + ext h x + simp only [LinearMap.coe_comp, Function.comp_apply, MonoidAlgebra.lsingle_apply] + simp [ofMulAction_single, mul_inv_rev, hom_comm_apply f g], fun g ↦ by ext; simp⟩ left_inv f := by ext h a simpa using (hom_comm_apply f h⁻¹ (IndV.mk φ A.ρ 1 a)).symm @@ -188,8 +187,9 @@ noncomputable def coinvariantsTensorIndHom : ((coinvariantsTensor k H).obj (ind φ A)).obj B ⟶ ((coinvariantsTensor k G).obj A).obj (res φ B) := ModuleCat.ofHom <| Coinvariants.lift _ (TensorProduct.lift <| Coinvariants.lift _ - (TensorProduct.lift <| Finsupp.lift _ _ _ <| fun g ↦ - (coinvariantsTensorMk A (res φ B)).compl₂ (B.ρ g)) + (TensorProduct.lift <| (Finsupp.lift _ _ _ <| fun g ↦ + (coinvariantsTensorMk A (res φ B)).compl₂ (B.ρ g)) ∘ₗ + (MonoidAlgebra.coeffLinearEquiv k).toLinearMap) fun g ↦ by ext; simpa [coinvariantsTensorMk, Coinvariants.mk_eq_iff] using! Coinvariants.sub_mem_ker _ _) fun _ ↦ by simp only [MonoidalCategory.curriedTensor_obj_obj, tensor_V, tensor_ρ, res_obj_ρ, diff --git a/Mathlib/RepresentationTheory/Invariants.lean b/Mathlib/RepresentationTheory/Invariants.lean index e78c870f3f9f46..a93460d67982c7 100644 --- a/Mathlib/RepresentationTheory/Invariants.lean +++ b/Mathlib/RepresentationTheory/Invariants.lean @@ -40,20 +40,20 @@ noncomputable def average : k[G] := ⅟(Fintype.card G : k) • ∑ g : G, of k /-- `average k G` is invariant under left multiplication by elements of `G`. -/ @[simp] -theorem mul_average_left (g : G) : ↑(Finsupp.single g 1) * average k G = average k G := by +theorem mul_average_left (g : G) : .single g 1 * average k G = average k G := by simp only [mul_one, Finset.mul_sum, Algebra.mul_smul_comm, average, MonoidAlgebra.of_apply, MonoidAlgebra.single_mul_single] - set f : G → k[G] := fun x => Finsupp.single x 1 + set f : G → k[G] := fun x => .single x 1 change ⅟(Fintype.card G : k) • ∑ x : G, f (g * x) = ⅟(Fintype.card G : k) • ∑ x : G, f x rw [Function.Bijective.sum_comp (Group.mulLeft_bijective g) _] /-- `average k G` is invariant under right multiplication by elements of `G`. -/ @[simp] -theorem mul_average_right (g : G) : average k G * ↑(Finsupp.single g 1) = average k G := by +theorem mul_average_right (g : G) : average k G * .single g 1 = average k G := by simp only [mul_one, Finset.sum_mul, Algebra.smul_mul_assoc, average, MonoidAlgebra.of_apply, MonoidAlgebra.single_mul_single] - set f : G → k[G] := fun x => Finsupp.single x 1 + set f : G → k[G] := fun x => .single x 1 change ⅟(Fintype.card G : k) • ∑ x : G, f (x * g) = ⅟(Fintype.card G : k) • ∑ x : G, f x rw [Function.Bijective.sum_comp (Group.mulRight_bijective g) _] diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index 4733606c6e9568..e1caf8bd04152e 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -24,6 +24,7 @@ module as `A.V` and the representation on it as `A.ρ`. universe w w' u u' v v' open CategoryTheory +open scoped MonoidAlgebra set_option backward.privateInPublic true in /-- The category of representations of monoid `G` and their morphisms. -/ @@ -404,7 +405,8 @@ variable {k G} /-- Given an element `x : A`, there is a natural morphism of representations `k[G] ⟶ A` sending `g ↦ A.ρ(g)(x).` -/ abbrev leftRegularHom (A : Rep k G) (x : A) : leftRegular k G ⟶ A := - Rep.ofHom ⟨Finsupp.lift A k G fun g ↦ A.ρ g x, fun g ↦ by ext; simp⟩ + Rep.ofHom ⟨Finsupp.lift A k G (fun g ↦ A.ρ g x) ∘ₗ (MonoidAlgebra.coeffLinearEquiv _).toLinearMap, + fun g ↦ by ext; simp⟩ theorem leftRegularHom_hom_single {A : Rep k G} (g : G) (x : A) (r : k) : (leftRegularHom A x).hom (.single g r) = r • A.ρ g x := by @@ -891,7 +893,7 @@ abbrev freeLiftLEquiv : homLinearEquiv _ _ ≪≫ₗ Representation.freeLiftLEquiv A.ρ α lemma free_ext (f g : free k G α ⟶ A) - (h : ∀ i : α, f.hom (single i (single 1 1)) = g.hom (single i (single 1 1))) : f = g := by + (h : ∀ i : α, f.hom (single i (.single 1 1)) = g.hom (single i (.single 1 1))) : f = g := by classical exact (freeLiftLEquiv k G α A).injective (funext_iff.2 h) variable {A} @@ -917,8 +919,7 @@ section variable (k G α : Type u) [DecidableEq α] [CommRing k] [Monoid G] /-- The natural isomorphism sending `single g r₁ ⊗ single a r₂ ↦ single a (single g r₁r₂)`. -/ -abbrev leftRegularTensorTrivialIsoFree : - leftRegular k G ⊗ trivial k G (α →₀ k) ≅ free k G α := +abbrev leftRegularTensorTrivialIsoFree : leftRegular k G ⊗ trivial k G k[α] ≅ free k G α := mkIso (Representation.leftRegularTensorTrivialIsoFree α) end @@ -928,12 +929,12 @@ end Finsupp /-- The monoidal functor sending a type `H` with a `G`-action to the induced `k`-linear `G`-representation on `k[H].` -/ @[simps] -abbrev linearization : (Action (Type w) G) ⥤ (Rep.{max w u} k G) where - obj X := Rep.of (X := X.V →₀ k) <| Representation.linearize k G X +abbrev linearization : Action (Type w) G ⥤ Rep.{max w u} k G where + obj X := .of <| .linearize k G X map f := Rep.ofHom <| Representation.linearizeMap f open MonoidalCategory Representation.LinearizeMonoidal in -instance : (linearization k G).Monoidal where +instance : (linearization k G).LaxMonoidal where ε := ofHom (ε k G) μ X Y := ofHom (μ X Y) μ_natural_left f Z := hom_ext <| μ_comp_rTensor f Z @@ -941,13 +942,19 @@ instance : (linearization k G).Monoidal where associativity X Y Z := by ext1; simp [μ_comp_assoc _] left_unitality X := hom_ext <| μ_leftUnitor X right_unitality X := hom_ext <| μ_rightUnitor X + +open MonoidalCategory Representation.LinearizeMonoidal in +instance : (linearization k G).OplaxMonoidal where η := ofHom (η k G) δ X Y := ofHom (δ X Y) δ_natural_left f Z := hom_ext <| rTensor_comp_δ Z f δ_natural_right Z f := hom_ext <| lTensor_comp_δ Z f - oplax_associativity X Y Z := hom_ext <| assoc_comp_δ X Y Z + oplax_associativity X Y Z := hom_ext <| by simpa using assoc_comp_δ X Y Z (k := k) oplax_left_unitality X := hom_ext <| leftUnitor_δ X oplax_right_unitality X := hom_ext <| rightUnitor_δ X + +open MonoidalCategory Representation.LinearizeMonoidal in +instance : (linearization k G).Monoidal where ε_η := hom_ext <| η_ε k G η_ε := hom_ext <| ε_η k G μ_δ X Y := hom_ext <| δ_μ (k := k) X Y @@ -989,7 +996,7 @@ variable (k G) in /-- The linearization of a type `X` on which `G` acts trivially is the trivial `G`-representation on `k[X]`. -/ abbrev linearizationTrivialIso (X : Type u) : - (linearization k G).obj (Action.trivial _ X) ≅ trivial k G (X →₀ k) := + (linearization k G).obj (Action.trivial _ X) ≅ trivial k G k[X] := Rep.mkIso (Representation.linearizeTrivialIso k G X) variable (k G) in diff --git a/Mathlib/RepresentationTheory/Rep/Iso.lean b/Mathlib/RepresentationTheory/Rep/Iso.lean index e9c9a47ceff40a..acb864891c279f 100644 --- a/Mathlib/RepresentationTheory/Rep/Iso.lean +++ b/Mathlib/RepresentationTheory/Rep/Iso.lean @@ -22,6 +22,7 @@ universe w w' u u' v v' namespace Rep open CategoryTheory +open scoped MonoidAlgebra suppress_compilation @@ -36,7 +37,7 @@ which `G` acts by `ρ(g₁)(g₂ ⊗ x) = (g₁ * g₂) ⊗ x`) sending `(g₀, `g₀ ⊗ (g₀⁻¹g₁, g₁⁻¹g₂, ..., gₙ₋₁⁻¹gₙ)`. The inverse sends `g₀ ⊗ (g₁, ..., gₙ)` to `(g₀, g₀g₁, ..., g₀g₁...gₙ)`. -/ abbrev diagonalSuccIsoTensorTrivial : - diagonal k G (n + 1) ≅ leftRegular k G ⊗ trivial k G ((Fin n → G) →₀ k) := + diagonal k G (n + 1) ≅ leftRegular k G ⊗ trivial k G k[Fin n → G] := linearizationOfMulActionIso k G (Fin (n + 1) → G) ≪≫ (linearization k G).mapIso (Action.diagonalSuccIsoTensorTrivial G n) ≪≫ (Functor.Monoidal.μIso (linearization k G) _ _).symm ≪≫ diff --git a/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean index db1f6536b6a4cd..a088eb39fe0904 100644 --- a/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean @@ -35,22 +35,28 @@ variable {R : Type*} [CommSemiring R] {A : Type*} [Semiring A] {X : Type*} [Module R A] [Coalgebra R A] variable (R A X) in -@[to_additive (dont_translate := R)] -instance instCoalgebra : Coalgebra R A[X] := inferInstanceAs <| Coalgebra R (X →₀ A) +@[to_additive] +instance instCoalgebra : Coalgebra R A[X] := coeffEquiv.coalgebra _ @[to_additive] -instance instIsCocomm [IsCocomm R A] : IsCocomm R A[X] := Finsupp.instIsCocomm R X A +instance instIsCocomm [IsCocomm R A] : IsCocomm R A[X] := coeffEquiv.coalgebraIsCocomm _ @[to_additive (attr := simp)] lemma counit_single (x : X) (a : A) : Coalgebra.counit (single x a) = Coalgebra.counit (R := R) a := Finsupp.counit_single _ _ _ _ _ -@[to_additive (attr := simp)] +@[to_additive] +lemma comul_def : + Coalgebra.comul (R := R) (A := A[X]) = + TensorProduct.map (coeffLinearEquiv R).symm.toLinearMap (coeffLinearEquiv R).symm.toLinearMap + ∘ₗ comul ∘ₗ (coeffLinearEquiv R).toLinearMap := rfl + +@[to_additive (dont_translate := R) (attr := simp)] lemma comul_single (x : X) (a : A) : Coalgebra.comul (R := R) (single x a) = - TensorProduct.map (lsingle x) (lsingle x) (Coalgebra.comul a) := - Finsupp.comul_single _ _ _ _ _ + TensorProduct.map (lsingle x) (lsingle x) (Coalgebra.comul a) := by + simp [comul_def, TensorProduct.map_map]; rfl end MonoidAlgebra diff --git a/Mathlib/RingTheory/Derivation/MapCoeffs.lean b/Mathlib/RingTheory/Derivation/MapCoeffs.lean index 22a21b6dbe2b30..6871bfa814a8ed 100644 --- a/Mathlib/RingTheory/Derivation/MapCoeffs.lean +++ b/Mathlib/RingTheory/Derivation/MapCoeffs.lean @@ -39,7 +39,7 @@ of the coefficients. def mapCoeffs : Derivation R A[X] (PolynomialModule A M) where __ := (PolynomialModule.map A d.toLinearMap).comp PolynomialModule.equivPolynomial.symm.toLinearMap - map_one_eq_zero' := show (Finsupp.single 0 1).mapRange (d : A → M) d.map_zero = 0 by simp + map_one_eq_zero' := by simp leibniz' p q := by dsimp induction p using Polynomial.induction_on' with @@ -47,34 +47,19 @@ def mapCoeffs : Derivation R A[X] (PolynomialModule A M) where | monomial n a => induction q using Polynomial.induction_on' with | add => simp only [mul_add, map_add, add_smul, smul_add, add_add_add_comm, *] - | monomial m b => - refine Finsupp.ext fun i ↦ ?_ - dsimp [PolynomialModule.equivPolynomial, PolynomialModule.map] - simp only [toFinsupp_mul, toFinsupp_monomial, AddMonoidAlgebra.single_mul_single] - change d _ = _ + _ - -- TODO: copy more `Finsupp` API to `PolynomialModule`. - -- We have to do a bit of work to go through the identification - -- `PolynomialModule A M = ℕ →₀ M`... - dsimp only [PolynomialModule, Finsupp.mapRange.linearMap_apply, coeFn_coe] - rw [Finsupp.mapRange_single, Finsupp.mapRange_single] - -- ... and here we go back through the identification. - change _ = (_ • PolynomialModule.single A _ _) _ + (_ • PolynomialModule.single A _ _) i - simp only [PolynomialModule.monomial_smul_single, AddMonoidAlgebra.single_apply, - apply_ite d, leibniz, map_zero, PolynomialModule.single_apply, ite_add_zero, - add_comm m n] + | monomial m b => ext; simp [Polynomial.monomial_mul_monomial, add_comm] @[simp] -lemma mapCoeffs_apply (p : A[X]) (i) : - d.mapCoeffs p i = d (coeff p i) := rfl +lemma mapCoeffs_apply (p : A[X]) (i) : (d.mapCoeffs p).coeff i = d (coeff p i) := rfl @[simp] lemma mapCoeffs_monomial (n : ℕ) (x : A) : - d.mapCoeffs (monomial n x) = .single A n (d x) := Finsupp.ext fun _ ↦ by - simp [coeff_monomial, apply_ite d, PolynomialModule.single_apply] + d.mapCoeffs (monomial n x) = .single A n (d x) := by + ext; simp [coeff_monomial, apply_ite d, Finsupp.single_apply] @[simp] -lemma mapCoeffs_X : - d.mapCoeffs (X : A[X]) = 0 := by simp [← monomial_one_one_eq_X] +lemma mapCoeffs_X : d.mapCoeffs (X : A[X]) = 0 := by + simp [← monomial_one_one_eq_X, PolynomialModule.single] @[simp] lemma mapCoeffs_C (x : A) : @@ -95,21 +80,17 @@ theorem apply_aeval_eq' (d' : Derivation R B M') (f : M →ₗ[A] M') _root_.map_natCast, h] rw [add_comm, ← smul_smul, ← smul_smul, Nat.cast_smul_eq_nsmul] - theorem apply_aeval_eq [IsScalarTower R A B] [IsScalarTower A B M'] (d : Derivation R B M') (x : B) (p : A[X]) : - d (aeval x p) = PolynomialModule.eval x ((d.compAlgebraMap A).mapCoeffs p) + - aeval x (derivative p) • d x := by - convert! apply_aeval_eq' (d.compAlgebraMap A) d LinearMap.id _ x p - · apply Finsupp.ext - intro x - rfl - · intro a - rfl + d (aeval x p) = + (((d.compAlgebraMap A).mapCoeffs p).map B .id).eval x + aeval x (derivative p) • d x := + apply_aeval_eq' (d.compAlgebraMap A) d LinearMap.id (fun _a ↦ rfl) x p theorem apply_eval_eq (x : A) (p : A[X]) : - d (eval x p) = PolynomialModule.eval x (d.mapCoeffs p) + eval x (derivative p) • d x := - apply_aeval_eq d x p + d (eval x p) = PolynomialModule.eval x (d.mapCoeffs p) + eval x (derivative p) • d x := by + convert! apply_aeval_eq d x p + ext + rfl end Derivation diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index 0d6ac75f554800..65073da77e4edd 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -260,6 +260,9 @@ lemma basis_apply [Nontrivial S] (r : Unit ⊕ σ) : · rw [basis_inr, cotangentEquivProd_symm_apply, cotangentCompLocalizationAwayEquiv_symm_inl, basisLeft, Module.Basis.map_apply, tensorCotangentEquiv_symm_apply, LinearMap.liftBaseChange_tmul, one_smul, Extension.Cotangent.map_mk] + simp only [Extension.Hom.toAlgHom_apply, Hom.toExtensionHom_toRingHom, AlgHom.toRingHom_eq_coe] + congr! 2 with x + simp [pres, Presentation.comp_relation_inr, kerGen, presLeft, Generators.toComp_toAlgHom] rfl end PresentationOfFreeCotangent.Aux diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index 8f0c380fec7e72..5c03910ea8864e 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -230,14 +230,14 @@ noncomputable def comp [Algebra S T] [IsScalarTower R S T] (Q : Generators S T ι') (P : Generators R S ι) : Generators R T (ι' ⊕ ι) where val := Sum.elim Q.val (algebraMap S T ∘ P.val) - σ' x := (Q.σ x).sum (fun n r ↦ rename Sum.inr (P.σ r) * monomial (n.mapDomain Sum.inl) 1) + σ' x := (AddMonoidAlgebra.coeff <| Q.σ x).sum fun n r ↦ + rename .inr (P.σ r) * monomial (n.mapDomain .inl) 1 aeval_val_σ' s := by have (x : P.Ring) : aeval (algebraMap S T ∘ P.val) x = algebraMap S T (aeval P.val x) := by rw [map_aeval, aeval_def, coe_eval₂Hom, ← IsScalarTower.algebraMap_eq, Function.comp_def] - conv_rhs => rw [← Q.aeval_val_σ s, ← (Q.σ s).sum_single] - simp only [map_finsuppSum, map_mul, aeval_rename, Sum.elim_comp_inr, this, aeval_val_σ, - aeval_monomial, map_one, Finsupp.prod_mapDomain_index_inj Sum.inl_injective, Sum.elim_inl, - one_mul, single_eq_monomial] + conv_rhs => rw [← Q.aeval_val_σ s, (Q.σ s).as_sum] + simp [aeval_rename, this, aeval_monomial, Finsupp.prod_mapDomain_index_inj Sum.inl_injective, + Finsupp.sum, MvPolynomial.finsupp_support_eq_support, MvPolynomial.coeff] variable (S) in /-- If `R → S → T` is a tower of algebras, a family of generators `R[X] → T` @@ -524,7 +524,7 @@ def toComp (Q : Generators S T ι') (P : Generators R S ι) : Hom P (Q.comp P) w aeval_val i := by simp lemma toComp_toAlgHom (Q : Generators S T ι') (P : Generators R S ι) : - (Q.toComp P).toAlgHom = rename Sum.inr := rfl + (Q.toComp P).toAlgHom = rename Sum.inr := by rw [rename_eq_aeval]; rfl /-- Given families of generators `X ⊆ T` over `S` and `Y ⊆ S` over `R`, there is a map of generators `R[X, Y] → S[X]`. -/ @@ -548,8 +548,11 @@ lemma toComp_toAlgHom_monomial (Q : Generators S T ι') (P : Generators R S ι) (Q.toComp P).toAlgHom (monomial j a) = monomial (Finsupp.sumElim 0 j) a := by convert! rename_monomial _ _ _ - ext f (i₁ | i₂) <;> - simp [Finsupp.mapDomain_notin_range, Finsupp.mapDomain_apply Sum.inr_injective] + · ext f (i₁ | i₂) + simp [rename_eq_aeval] + rfl + · ext f (i₁ | i₂) <;> + simp [Finsupp.mapDomain_notin_range, Finsupp.mapDomain_apply Sum.inr_injective] @[simp] lemma toAlgHom_ofComp_rename (Q : Generators S T ι') (P : Generators R S ι) (p : P.Ring) : @@ -731,7 +734,7 @@ to `ker(R[X][Y] → S[Y] → T)` constructed from `P.σ`. noncomputable def kerCompPreimage (Q : Generators S T ι') (P : Generators R S ι) (x : Q.ker) : (Q.comp P).ker := by - refine ⟨x.1.sum fun n r ↦ ?_, ?_⟩ + refine ⟨(AddMonoidAlgebra.coeff x.1).sum fun n r ↦ ?_, ?_⟩ · -- The use of `refine` is intentional to control the elaboration order -- so that the term has type `(Q.comp P).Ring` and not `MvPolynomial (Q.ι ⊕ P.ι) R` refine rename ?_ (P.σ r) * monomial ?_ 1 @@ -752,7 +755,7 @@ lemma ofComp_kerCompPreimage (Q : Generators S T ι') (P : Generators R S ι) (x refine Finset.sum_congr rfl fun j _ ↦ ?_ simp only [map_mul, Hom.toAlgHom_monomial] rw [one_smul, Finsupp.prod_mapDomain_index_inj Sum.inl_injective] - rw [rename, ← AlgHom.comp_apply, comp_aeval] + rw [rename_eq_aeval, ← AlgHom.comp_apply, comp_aeval] simp only [ofComp_val, Sum.elim_inr, Function.comp_apply, Sum.elim_inl, monomial_eq, Hom.toAlgHom_X] congr 1 diff --git a/Mathlib/RingTheory/Extension/Presentation/Basic.lean b/Mathlib/RingTheory/Extension/Presentation/Basic.lean index 075657d1a4168f..31e8ad3fdba6af 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Basic.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Basic.lean @@ -351,7 +351,7 @@ private noncomputable def aux (Q : Presentation S T ι' σ') (P : Presentation R /-- A choice of pre-image of `Q.relation r` under the canonical map `MvPolynomial (ι' ⊕ ι) R →ₐ[R] MvPolynomial ι' S` given by the evaluation of `P`. -/ noncomputable def compRelationAux (r : σ') : MvPolynomial (ι' ⊕ ι) R := - Finsupp.sum (Q.relation r) + (AddMonoidAlgebra.coeff <| Q.relation r).sum (fun x j ↦ (MvPolynomial.rename Sum.inr <| P.σ j) * monomial (x.mapDomain Sum.inl) 1) @[simp] @@ -363,10 +363,13 @@ private lemma compRelationAux_map (r : σ') : (Q.aux P) (Q.compRelationAux P r) = Q.relation r := by simp only [aux, compRelationAux, map_finsuppSum] simp only [map_mul, aeval_rename, aeval_monomial, Sum.elim_comp_inr] - conv_rhs => rw [← Finsupp.sum_single (Q.relation r)] + conv_rhs => rw [← (Q.relation r).ofCoeff_coeff, + ← Finsupp.sum_single (AddMonoidAlgebra.coeff <| Q.relation r)] + rw [AddMonoidAlgebra.ofCoeff_finsuppSum] congr ext u s m - simp only [MvPolynomial.single_eq_monomial, aeval, AlgHom.coe_mk, coe_eval₂Hom] + simp only [aeval, AlgHom.coe_mk, coe_eval₂Hom, map_one, one_mul, AddMonoidAlgebra.ofCoeff_single, + single_eq_monomial] rw [monomial_eq, IsScalarTower.algebraMap_eq R S, algebraMap_eq, ← eval₂_comp_left, ← aeval_def] simp [Finsupp.prod_mapDomain_index_inj (Sum.inl_injective)] diff --git a/Mathlib/RingTheory/Filtration.lean b/Mathlib/RingTheory/Filtration.lean index 2015d7408e6eb3..f909cc28ab729a 100644 --- a/Mathlib/RingTheory/Filtration.lean +++ b/Mathlib/RingTheory/Filtration.lean @@ -238,7 +238,7 @@ variable (F F') /-- The `R[IX]`-submodule of `M[X]` associated with an `I`-filtration. -/ protected noncomputable def submodule : Submodule (reesAlgebra I) (PolynomialModule R M) where - carrier := { f | ∀ i, f i ∈ F.N i } + carrier := { f | ∀ i, f.coeff i ∈ F.N i } add_mem' hf hg i := Submodule.add_mem _ (hf i) (hg i) zero_mem' _ := Submodule.zero_mem _ smul_mem' r f hf i := by @@ -250,7 +250,7 @@ protected noncomputable def submodule : Submodule (reesAlgebra I) (PolynomialMod exact F.pow_smul_le j k (Submodule.smul_mem_smul (r.2 j) (hf k)) @[simp] -theorem mem_submodule (f : PolynomialModule R M) : f ∈ F.submodule ↔ ∀ i, f i ∈ F.N i := +theorem mem_submodule (f : PolynomialModule R M) : f ∈ F.submodule ↔ ∀ i, f.coeff i ∈ F.N i := Iff.rfl theorem inf_submodule : (F ⊓ F').submodule = F.submodule ⊓ F'.submodule := by @@ -272,12 +272,12 @@ theorem submodule_closure_single : apply le_antisymm · rw [AddSubmonoid.closure_le, Set.iUnion_subset_iff] rintro i _ ⟨m, hm, rfl⟩ j - rw [single_apply] + rw [coeff_single, Finsupp.single_apply] split_ifs with h · rwa [← h] · exact (F.N j).zero_mem · intro f hf - rw [← f.sum_single] + rw [← f.ofCoeff_coeff, ← f.coeff.sum_single, ofCoeff_finsuppSum] apply AddSubmonoid.sum_mem _ _ rintro c - exact AddSubmonoid.subset_closure (Set.subset_iUnion _ c <| Set.mem_image_of_mem _ (hf c)) @@ -299,9 +299,9 @@ theorem submodule_eq_span_le_iff_stable_ge (n₀ : ℕ) : refine (F.smul_le n).antisymm ?_ intro x hx obtain ⟨l, hl⟩ := (Finsupp.mem_span_iff_linearCombination _ _ _).mp (H _ ⟨x, hx, rfl⟩) - replace hl := congr_arg (fun f : ℕ →₀ M => f (n + 1)) hl - rw [PolynomialModule.single_apply, if_pos rfl] at hl - rw [← hl, Finsupp.linearCombination_apply, Finsupp.sum_apply] + replace hl := congr_arg (fun f : PolynomialModule R M => f.coeff (n + 1)) hl + rw [PolynomialModule.coeff_single, Finsupp.single_apply, if_pos rfl] at hl + rw [← hl, Finsupp.linearCombination_apply, PolynomialModule.coeff_finsuppSum, Finsupp.sum_apply] apply Submodule.sum_mem _ _ rintro ⟨_, _, ⟨n', rfl⟩, _, ⟨hn', rfl⟩, m, hm, rfl⟩ - dsimp only [Subtype.coe_mk] @@ -328,7 +328,7 @@ theorem submodule_eq_span_le_iff_stable_ge (n₀ : ℕ) : · rw [add_comm, ← monomial_smul_single] exact F'.smul_mem ⟨_, reesAlgebra.monomial_mem.mpr (by rwa [pow_one])⟩ (hj <| Set.mem_image_of_mem _ hm') - · rw [map_add] + · rw [PolynomialModule.single_add] exact F'.add_mem hx hy /-- If the components of a filtration are finitely generated, then the filtration is stable iff diff --git a/Mathlib/RingTheory/FinitePresentation.lean b/Mathlib/RingTheory/FinitePresentation.lean index 8711421f53e1b1..cc8c128a3d64b0 100644 --- a/Mathlib/RingTheory/FinitePresentation.lean +++ b/Mathlib/RingTheory/FinitePresentation.lean @@ -489,7 +489,7 @@ lemma polynomial_induction refine fg_ker _ _ _ (hg.comp (MvPolynomial.C_surjective (Fin 0))) ?_ rw [← comap_ker] convert! hg'.map (MvPolynomial.isEmptyRingEquiv R (Fin 0)).toRingHom using 1 - simp only [RingEquiv.toRingHom_eq_coe] + simp only [RingEquiv.toRingHom_eq_coe, ← MvPolynomial.isEmptyRingEquiv_symm_toRingHom] exact Ideal.comap_symm (MvPolynomial.isEmptyRingEquiv R (Fin 0)) | succ n IH => let e : MvPolynomial (Fin (n + 1)) R ≃ₐ[R] MvPolynomial (Fin n) R[X] := diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index 68ec9e65447b48..c31975d59b8c2f 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -328,31 +328,26 @@ section Semiring variable [CommSemiring R] [AddMonoid M] /-- An element of `R[M]` is in the subalgebra generated by its support. -/ -theorem mem_adjoin_support (f : R[M]) : f ∈ adjoin R (of' R M '' f.support) := by - suffices span R (of' R M '' f.support) ≤ - Subalgebra.toSubmodule (adjoin R (of' R M '' f.support)) by - exact this (mem_span_support f) - rw [Submodule.span_le] - exact subset_adjoin +theorem mem_adjoin_support (f : R[M]) : f ∈ adjoin R (of' R M '' f.coeff.support) := + (adjoin R (of' R M '' f.coeff.support)).toSubmodule.span_le.2 subset_adjoin + (mem_span_support_coeff f) /-- If a set `S` generates, as algebra, `R[M]`, then the set of supports of elements of `S` generates `R[M]`. -/ theorem support_gen_of_gen {S : Set R[M]} (hS : Algebra.adjoin R S = ⊤) : - Algebra.adjoin R (⋃ f ∈ S, of' R M '' (f.support : Set M)) = ⊤ := by + Algebra.adjoin R (⋃ f ∈ S, of' R M '' (f.coeff.support : Set M)) = ⊤ := by refine le_antisymm le_top ?_ rw [← hS, adjoin_le_iff] intro f hf - have hincl : - of' R M '' f.support ⊆ ⋃ (g : R[M]) (_ : g ∈ S), of' R M '' g.support := by - intro s hs - exact Set.mem_iUnion₂.2 ⟨f, ⟨hf, hs⟩⟩ + have hincl : of' R M '' f.coeff.support ⊆ ⋃ g ∈ S, of' R M '' g.coeff.support := + fun s hs ↦ Set.mem_iUnion₂.2 ⟨f, hf, hs⟩ exact adjoin_mono hincl (mem_adjoin_support f) /-- If a set `S` generates, as algebra, `R[M]`, then the image of the union of the supports of elements of `S` generates `R[M]`. -/ theorem support_gen_of_gen' {S : Set R[M]} (hS : Algebra.adjoin R S = ⊤) : - Algebra.adjoin R (of' R M '' ⋃ f ∈ S, (f.support : Set M)) = ⊤ := by - suffices (of' R M '' ⋃ f ∈ S, (f.support : Set M)) = ⋃ f ∈ S, of' R M '' (f.support : Set M) by + Algebra.adjoin R (of' R M '' ⋃ f ∈ S, (f.coeff.support : Set M)) = ⊤ := by + suffices of' R M '' ⋃ f ∈ S, (f.coeff.support : Set M) = ⋃ f ∈ S, of' R M '' f.coeff.support by rw [this] exact support_gen_of_gen hS simp only [Set.image_iUnion] @@ -369,8 +364,8 @@ theorem exists_finset_adjoin_eq_top [h : FiniteType R R[M]] : ∃ G : Finset M, Algebra.adjoin R (of' R M '' G) = ⊤ := by obtain ⟨S, hS⟩ := h letI : DecidableEq M := Classical.decEq M - use Finset.biUnion S fun f => f.support - have : (Finset.biUnion S fun f => f.support : Set M) = ⋃ f ∈ S, (f.support : Set M) := by + use Finset.biUnion S fun f => f.coeff.support + have : S.biUnion (fun f => f.coeff.support) = ⋃ f ∈ S, (f.coeff.support : Set M) := by simp only [Finset.set_biUnion_coe, Finset.coe_biUnion] rw [this] exact support_gen_of_gen' hS @@ -482,30 +477,26 @@ section Semiring variable [CommSemiring R] [Monoid M] /-- An element of `R[M]` is in the subalgebra generated by its support. -/ -theorem mem_adjoin_support (f : R[M]) : f ∈ adjoin R (of R M '' f.support) := by - suffices span R (of R M '' f.support) ≤ Subalgebra.toSubmodule (adjoin R (of R M '' f.support)) by - exact this (mem_span_support f) - rw [Submodule.span_le] - exact subset_adjoin +theorem mem_adjoin_support (f : R[M]) : f ∈ adjoin R (of R M '' f.coeff.support) := + (adjoin R (of R M '' f.coeff.support)).toSubmodule.span_le.2 subset_adjoin + (mem_span_support_coeff f) /-- If a set `S` generates, as algebra, `R[M]`, then the set of supports of elements of `S` generates `R[M]`. -/ theorem support_gen_of_gen {S : Set R[M]} (hS : Algebra.adjoin R S = ⊤) : - Algebra.adjoin R (⋃ f ∈ S, of R M '' (f.support : Set M)) = ⊤ := by + Algebra.adjoin R (⋃ f ∈ S, of R M '' (f.coeff.support : Set M)) = ⊤ := by refine le_antisymm le_top ?_ rw [← hS, adjoin_le_iff] intro f hf - have hincl : (of R M '' f.support) ⊆ - ⋃ (g : R[M]) (H : g ∈ S), (of R M '' g.support) := by - intro s hs - exact Set.mem_iUnion₂.2 ⟨f, ⟨hf, hs⟩⟩ + have hincl : of R M '' f.coeff.support ⊆ ⋃ g ∈ S, of R M '' g.coeff.support := + fun s hs ↦ Set.mem_iUnion₂.2 ⟨f, hf, hs⟩ exact adjoin_mono hincl (mem_adjoin_support f) /-- If a set `S` generates, as algebra, `R[M]`, then the image of the union of the supports of elements of `S` generates `R[M]`. -/ theorem support_gen_of_gen' {S : Set R[M]} (hS : Algebra.adjoin R S = ⊤) : - Algebra.adjoin R (of R M '' ⋃ f ∈ S, (f.support : Set M)) = ⊤ := by - suffices (of R M '' ⋃ f ∈ S, (f.support : Set M)) = ⋃ f ∈ S, of R M '' (f.support : Set M) by + Algebra.adjoin R (of R M '' ⋃ f ∈ S, (f.coeff.support : Set M)) = ⊤ := by + suffices of R M '' ⋃ f ∈ S, f.coeff.support = ⋃ f ∈ S, of R M '' f.coeff.support by rw [this] exact support_gen_of_gen hS simp only [Set.image_iUnion] @@ -522,8 +513,8 @@ theorem exists_finset_adjoin_eq_top [h : FiniteType R R[M]] : ∃ G : Finset M, Algebra.adjoin R (of R M '' G) = ⊤ := by obtain ⟨S, hS⟩ := h letI : DecidableEq M := Classical.decEq M - use Finset.biUnion S fun f => f.support - have : (Finset.biUnion S fun f => f.support : Set M) = ⋃ f ∈ S, (f.support : Set M) := by + use Finset.biUnion S fun f => f.coeff.support + have : S.biUnion (fun f => f.coeff.support) = ⋃ f ∈ S, (f.coeff.support : Set M) := by simp only [Finset.set_biUnion_coe, Finset.coe_biUnion] rw [this] exact support_gen_of_gen' hS diff --git a/Mathlib/RingTheory/Finiteness/Finsupp.lean b/Mathlib/RingTheory/Finiteness/Finsupp.lean index 9bbb331d8f17f5..5a453d26a34539 100644 --- a/Mathlib/RingTheory/Finiteness/Finsupp.lean +++ b/Mathlib/RingTheory/Finiteness/Finsupp.lean @@ -146,14 +146,14 @@ end namespace AddMonoidAlgebra variable {M R S : Type*} [Finite M] [Semiring R] [Semiring S] [Module R S] [Module.Finite R S] -instance moduleFinite : Module.Finite R S[M] := .finsupp +instance moduleFinite : Module.Finite R S[M] := .equiv <| .symm <| coeffLinearEquiv _ end AddMonoidAlgebra namespace MonoidAlgebra variable {M R S : Type*} [Finite M] [Semiring R] [Semiring S] [Module R S] [Module.Finite R S] -instance moduleFinite : Module.Finite R S[M] := .finsupp +instance moduleFinite : Module.Finite R S[M] := .equiv <| .symm <| coeffLinearEquiv _ end MonoidAlgebra diff --git a/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean index ed41f7e89919a5..9610c02f01002e 100644 --- a/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean @@ -36,15 +36,15 @@ variable {R A : Type*} [CommSemiring R] [Semiring A] [HopfAlgebra R A] variable {G : Type*} [Group G] variable (R A G) in +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance instHopfAlgebraStruct : HopfAlgebraStruct R A[G] where - antipode := Finsupp.lsum R fun g => Finsupp.lsingle g⁻¹ ∘ₗ antipode R + antipode := Finsupp.lsum R (fun g ↦ lsingle g⁻¹ ∘ₗ antipode R) ∘ₗ (coeffLinearEquiv _).toLinearMap set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] -lemma antipode_single (g : G) (a : A) : - antipode R (single g a) = single g⁻¹ (antipode R a) := by - simp [MonoidAlgebra, antipode] +lemma antipode_single (g : G) (a : A) : antipode R (single g a) = single g⁻¹ (antipode R a) := by + simp [antipode] open Coalgebra in @[to_additive (dont_translate := R A)] diff --git a/Mathlib/RingTheory/IsAdjoinRoot.lean b/Mathlib/RingTheory/IsAdjoinRoot.lean index 07ee4861ca3196..9030176eeab859 100644 --- a/Mathlib/RingTheory/IsAdjoinRoot.lean +++ b/Mathlib/RingTheory/IsAdjoinRoot.lean @@ -418,7 +418,7 @@ def basis : Basis (Fin (natDegree f)) R S where repr.invFun g := h.map <| ofFinsupp <| .ofCoeff <| g.mapDomain Fin.val repr.left_inv x := by nontriviality R using Algebra.subsingleton R S - simp only [AddMonoidAlgebra.coeff, AddMonoidAlgebra.ofCoeff] + dsimp rw [Finsupp.mapDomain_comapDomain, Polynomial.eta, h.map_modByMonicHom x] · exact Fin.val_injective intro i hi @@ -432,8 +432,7 @@ def basis : Basis (Fin (natDegree f)) R S where repr.right_inv g := by nontriviality R ext i - simp only [AddMonoidAlgebra.coeff, AddMonoidAlgebra.ofCoeff, h.modByMonicHom_map, - Finsupp.comapDomain_apply, Polynomial.toFinsupp_apply] + simp only [h.modByMonicHom_map, Finsupp.comapDomain_apply, Polynomial.toFinsupp_apply] rw [(Polynomial.modByMonic_eq_self_iff h.monic).mpr, Polynomial.coeff] · rw [Finsupp.mapDomain_apply Fin.val_injective] rw [degree_eq_natDegree h.monic.ne_zero, degree_lt_iff_coeff_zero] @@ -448,8 +447,7 @@ def basis : Basis (Fin (natDegree f)) R S where @[simp] theorem basis_apply (i) : h.basis i = h.root ^ (i : ℕ) := - Basis.apply_eq_iff.mpr <| by - simp [AddMonoidAlgebra.coeff, AddMonoidAlgebra.ofCoeff, IsAdjoinRootMonic.basis] + Basis.apply_eq_iff.mpr <| by simp [IsAdjoinRootMonic.basis] include h in theorem deg_pos [Nontrivial S] : 0 < natDegree f := by @@ -470,7 +468,7 @@ def powerBasis : PowerBasis R S where @[simp] theorem basis_repr (x : S) (i : Fin (natDegree f)) : h.basis.repr x i = (h.modByMonicHom x).coeff (i : ℕ) := by - simp [IsAdjoinRootMonic.basis, AddMonoidAlgebra.coeff, AddMonoidAlgebra.ofCoeff, toFinsupp_apply] + simp [IsAdjoinRootMonic.basis, toFinsupp_apply] theorem basis_one (hdeg : 1 < natDegree f) : h.basis ⟨1, hdeg⟩ = h.root := by rw [h.basis_apply, Fin.val_mk, pow_one] diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index 3b95f71029bacd..b0793212737291 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -232,12 +232,12 @@ restriction to `ker(I/I² → ⊕ S dyᵢ)` is the connecting homomorphism in th noncomputable def δAux : Q.Ring →ₗ[R] T ⊗[S] Ω[S⁄R] := - Finsupp.lsum R (R := R) fun f ↦ - (TensorProduct.mk S T _ (f.prod (Q.val · ^ ·))).restrictScalars R ∘ₗ (D R S).toLinearMap + Finsupp.lsum R (R := R) (fun f ↦ + (TensorProduct.mk S T _ (f.prod (Q.val · ^ ·))).restrictScalars R ∘ₗ (D R S).toLinearMap) + ∘ₗ (AddMonoidAlgebra.coeffLinearEquiv _).toLinearMap lemma δAux_monomial (n r) : - δAux R Q (monomial n r) = (n.prod (Q.val · ^ ·)) ⊗ₜ D R S r := - Finsupp.lsum_single _ _ _ _ + δAux R Q (monomial n r) = (n.prod (Q.val · ^ ·)) ⊗ₜ D R S r := by simp [δAux] @[simp] lemma δAux_X (i) : diff --git a/Mathlib/RingTheory/MvPolynomial/Basic.lean b/Mathlib/RingTheory/MvPolynomial/Basic.lean index 8b110f625e4353..86708fc1d603ab 100644 --- a/Mathlib/RingTheory/MvPolynomial/Basic.lean +++ b/Mathlib/RingTheory/MvPolynomial/Basic.lean @@ -50,10 +50,8 @@ variable (σ : Type u) (R : Type v) [CommSemiring R] (p m : ℕ) namespace MvPolynomial -instance {σ : Type*} {R : Type*} [CommSemiring R] - [Small.{u} R] [Small.{u} σ] : - Small.{u} (MvPolynomial σ R) := - inferInstanceAs (Small.{u} ((σ →₀ ℕ) →₀ R)) +instance {σ R : Type*} [CommSemiring R] [Small.{u} R] [Small.{u} σ] : + Small.{u} (MvPolynomial σ R) := small_map AddMonoidAlgebra.coeffEquiv section CharP @@ -80,12 +78,10 @@ end ExpChar section Homomorphism -set_option backward.isDefEq.respectTransparency false in -theorem mapRange_eq_map {R S : Type*} [CommSemiring R] [CommSemiring S] (p : MvPolynomial σ R) - (f : R →+* S) : Finsupp.mapRange f f.map_zero p = map f p := by - rw [p.as_sum, Finsupp.mapRange_finsetSum, map_sum (map f)] - refine Finset.sum_congr rfl fun n _ => ?_ - rw [map_monomial, ← single_eq_monomial, Finsupp.mapRange_single, single_eq_monomial] +theorem map_eq_map {R S : Type*} [CommSemiring R] [CommSemiring S] (p : MvPolynomial σ R) + (f : R →+* S) : AddMonoidAlgebra.map f p = map f p := rfl + +@[deprecated (since := "2026-06-18")] alias mapRange_eq_map := map_eq_map end Homomorphism @@ -95,17 +91,18 @@ variable {σ} /-- The submodule of polynomials that are sum of monomials in the set `s`. -/ def restrictSupport (s : Set (σ →₀ ℕ)) : Submodule R (MvPolynomial σ R) := - Finsupp.supported _ _ s + AddMonoidAlgebra.supported R R s /-- `restrictSupport R s` has a canonical `R`-basis indexed by `s`. -/ def basisRestrictSupport (s : Set (σ →₀ ℕ)) : Basis s R (restrictSupport R s) where - repr := Finsupp.supportedEquivFinsupp s + repr := AddMonoidAlgebra.supportedEquivFinsupp s theorem restrictSupport_mono {s t : Set (σ →₀ ℕ)} (h : s ⊆ t) : - restrictSupport R s ≤ restrictSupport R t := Finsupp.supported_mono h + restrictSupport R s ≤ restrictSupport R t := AddMonoidAlgebra.supported_mono h lemma restrictSupport_eq_span (s : Set (σ →₀ ℕ)) : - restrictSupport R s = .span _ ((monomial · 1) '' s) := Finsupp.supported_eq_span_single .. + restrictSupport R s = .span _ ((monomial · 1) '' s) := + AddMonoidAlgebra.supported_eq_span_single .. lemma mem_restrictSupport_iff {s : Set (σ →₀ ℕ)} {r : MvPolynomial σ R} : r ∈ restrictSupport R s ↔ ↑r.support ⊆ s := .rfl @@ -133,9 +130,12 @@ open scoped Pointwise in classical apply le_antisymm · rw [restrictSupport_eq_span, Submodule.span_le, Set.image_subset_iff] - simpa using ⟨1, by simp⟩ + simp only [monomial, AddMonoidAlgebra.lsingle_apply, zero_subset, mem_preimage, + ← AddMonoidAlgebra.one_def, SetLike.mem_coe, Submodule.mem_one, algebraMap_eq] + exact ⟨1, by simp⟩ · rintro _ ⟨x, rfl⟩ - simp [mem_restrictSupport_iff, Set.subset_def, coeff_one] + simp [mem_restrictSupport_iff, subset_def, coeff, AddMonoidAlgebra.one_def, + Finsupp.single_apply] @[simp] lemma restrictSupport_univ : restrictSupport R (.univ : Set (σ →₀ ℕ)) = ⊤ := by @@ -156,6 +156,7 @@ def restrictSupportIdeal (s : Set (σ →₀ ℕ)) (hs : IsUpperSet s) : obtain ⟨⟨i, j⟩, hij, e⟩ := Finset.exists_ne_zero_of_sum_ne_zero hm refine hs (by simp_all [eq_comm]) (hy (show j ∈ y.support by aesop)) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma restrictScalars_restrictSupportIdeal (s : Set (σ →₀ ℕ)) (hs) : (restrictSupportIdeal (R := R) s hs).restrictScalars R = restrictSupport R s := @@ -182,7 +183,7 @@ theorem mem_restrictTotalDegree (p : MvPolynomial σ R) : set_option backward.isDefEq.respectTransparency false in theorem mem_restrictDegree (p : MvPolynomial σ R) (n : ℕ) : p ∈ restrictDegree σ R n ↔ ∀ s ∈ p.support, ∀ i, (s : σ →₀ ℕ) i ≤ n := by - rw [restrictDegree, restrictSupport, Finsupp.mem_supported] + rw [restrictDegree, restrictSupport, AddMonoidAlgebra.mem_supported] rfl theorem mem_restrictDegree_iff_sup [DecidableEq σ] (p : MvPolynomial σ R) (n : ℕ) : @@ -199,8 +200,8 @@ theorem restrictTotalDegree_le_restrictDegree (m : ℕ) : (degreeOf_le_totalDegree p i) s hs).trans ((mem_restrictTotalDegree _ _ _).mp hp) /-- The monomials form a basis on `MvPolynomial σ R`. -/ -def basisMonomials : Basis (σ →₀ ℕ) R (MvPolynomial σ R) := - Finsupp.basisSingleOne +def basisMonomials : Basis (σ →₀ ℕ) R (MvPolynomial σ R) where + repr := AddMonoidAlgebra.coeffLinearEquiv _ @[simp] theorem coe_basisMonomials : diff --git a/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean b/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean index 8bc83d1e7b65e8..4b8c64bb0560c9 100644 --- a/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean +++ b/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean @@ -33,7 +33,7 @@ protected lemma IsWeightedHomogeneous.pderiv [AddCancelCommMonoid M] {w : σ → (h : φ.IsWeightedHomogeneous w n) (h' : n' + w i = n) : (pderiv i φ).IsWeightedHomogeneous w n' := by rw [← mem_weightedHomogeneousSubmodule, weightedHomogeneousSubmodule_eq_finsupp_supported, - Finsupp.supported_eq_span_single] at h + AddMonoidAlgebra.supported_eq_span_single] at h refine Submodule.span_induction ?_ ?_ (fun p q _ _ hp hq ↦ ?_) (fun r p _ h ↦ ?_) h · rintro _ ⟨m, hm, rfl⟩ simp_rw [single_eq_monomial, pderiv_monomial, one_mul] @@ -60,7 +60,7 @@ open Finset in theorem IsWeightedHomogeneous.sum_weight_X_mul_pderiv {w : σ → ℕ} (h : φ.IsWeightedHomogeneous w n) : ∑ i : σ, w i • (X i * pderiv i φ) = n • φ := by rw [← mem_weightedHomogeneousSubmodule, weightedHomogeneousSubmodule_eq_finsupp_supported, - supported_eq_span_single] at h + AddMonoidAlgebra.supported_eq_span_single] at h refine Submodule.span_induction ?_ ?_ (fun p q _ _ hp hq ↦ ?_) (fun r p _ h ↦ ?_) h · rintro _ ⟨m, hm, rfl⟩ simp_rw [single_eq_monomial, X_mul_pderiv_monomial, smul_smul, ← sum_smul, mul_comm (w _)] diff --git a/Mathlib/RingTheory/MvPolynomial/FreeCommRing.lean b/Mathlib/RingTheory/MvPolynomial/FreeCommRing.lean index 836dd020d4d598..480af0ee207b81 100644 --- a/Mathlib/RingTheory/MvPolynomial/FreeCommRing.lean +++ b/Mathlib/RingTheory/MvPolynomial/FreeCommRing.lean @@ -55,7 +55,7 @@ noncomputable def mvPolynomialSupportLEEquiv { p : ι → MvPolynomial κ R // ∀ i, (p i).support ⊆ monoms i } ≃ ((Σ i, monoms i) → R) := { toFun := fun p i => (p.1 i.1).coeff i.2, - invFun := fun p => ⟨fun i => + invFun p := ⟨fun i => .ofCoeff { toFun := fun m => if hm : m ∈ monoms i then p ⟨i, ⟨m, hm⟩⟩ else 0 support := {m ∈ monoms i | ∃ hm : m ∈ monoms i, p ⟨i, ⟨m, hm⟩⟩ ≠ 0}, mem_support_toFun := by simp }, diff --git a/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean b/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean index 4a884d12016353..12c16d3463e782 100644 --- a/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean @@ -89,21 +89,7 @@ variable (σ R) /-- The submodule of homogeneous `MvPolynomial`s of degree `n`. -/ def homogeneousSubmodule (n : ℕ) : Submodule R (MvPolynomial σ R) where carrier := { x | x.IsHomogeneous n } - smul_mem' r a ha c hc := by - rw [coeff_smul] at hc - apply ha - intro h - apply hc - rw [h] - exact smul_zero r - zero_mem' _ hd := False.elim (hd <| coeff_zero _) - add_mem' {a b} ha hb c hc := by - rw [coeff_add] at hc - obtain h | h : coeff c a ≠ 0 ∨ coeff c b ≠ 0 := by - contrapose! hc - simp only [hc, add_zero] - · exact ha h - · exact hb h + __ := weightedHomogeneousSubmodule R 1 n @[simp] lemma weightedHomogeneousSubmodule_one (n : ℕ) : @@ -119,12 +105,13 @@ variable (σ R) /-- While equal, the former has a convenient definitional reduction. -/ theorem homogeneousSubmodule_eq_finsupp_supported (n : ℕ) : - homogeneousSubmodule σ R n = Finsupp.supported _ R { d | d.degree = n } := by + homogeneousSubmodule σ R n = AddMonoidAlgebra.supported _ R {d | d.degree = n} := by simp_rw [degree_eq_weight_one] exact weightedHomogeneousSubmodule_eq_finsupp_supported R 1 n variable {σ R} +set_option backward.isDefEq.respectTransparency false in theorem homogeneousSubmodule_mul (m n : ℕ) : homogeneousSubmodule σ R m * homogeneousSubmodule σ R n ≤ homogeneousSubmodule σ R (m + n) := weightedHomogeneousSubmodule_mul 1 m n @@ -132,9 +119,9 @@ theorem homogeneousSubmodule_mul (m n : ℕ) : set_option backward.isDefEq.respectTransparency false in lemma homogeneousSubmodule_one_eq_span_X : MvPolynomial.homogeneousSubmodule σ R 1 = .span R (.range X) := by - rw [MvPolynomial.homogeneousSubmodule_eq_finsupp_supported, Finsupp.supported_eq_span_single] - simp_rw [MvPolynomial.single_eq_monomial, ← Finsupp.range_single_one, ← Set.range_comp, - Function.comp_def, ← X_pow_eq_monomial, pow_one] + simp [MvPolynomial.homogeneousSubmodule_eq_finsupp_supported, + AddMonoidAlgebra.supported_eq_span_single, MvPolynomial.single_eq_monomial, + ← Finsupp.range_single_one, ← Set.range_comp, Function.comp_def, ← X_pow_eq_monomial] section @@ -234,6 +221,7 @@ theorem sum {ι : Type*} (s : Finset ι) (φ : ι → MvPolynomial σ R) (n : (h : ∀ i ∈ s, IsHomogeneous (φ i) n) : IsHomogeneous (∑ i ∈ s, φ i) n := (homogeneousSubmodule σ R n).sum_mem h +set_option backward.isDefEq.respectTransparency false in theorem mul (hφ : IsHomogeneous φ m) (hψ : IsHomogeneous ψ n) : IsHomogeneous (φ * ψ) (m + n) := homogeneousSubmodule_mul m n <| Submodule.mul_mem_mul hφ hψ diff --git a/Mathlib/RingTheory/MvPolynomial/Ideal.lean b/Mathlib/RingTheory/MvPolynomial/Ideal.lean index 48aec1bdae1c52..474013b7e2a648 100644 --- a/Mathlib/RingTheory/MvPolynomial/Ideal.lean +++ b/Mathlib/RingTheory/MvPolynomial/Ideal.lean @@ -71,6 +71,7 @@ variable (σ R) in lemma idealOfVars_fg [Finite σ] : (idealOfVars σ R).FG := Submodule.fg_span <| Set.finite_range _ +set_option backward.isDefEq.respectTransparency false in lemma idealOfVars_eq_restrictSupportIdeal : idealOfVars σ R = restrictSupportIdeal _ _ ((isUpperSet_Ici 1).preimage degree_mono) := by apply le_antisymm @@ -84,6 +85,7 @@ lemma idealOfVars_eq_restrictSupportIdeal : simpa [monomial_add_single] using Ideal.mul_mem_left _ _ (Ideal.subset_span (by simp)) open scoped Pointwise in +set_option backward.isDefEq.respectTransparency false in theorem pow_idealOfVars (n : ℕ) : idealOfVars σ R ^ n = restrictSupportIdeal _ _ ((isUpperSet_Ici n).preimage degree_mono) := by rw [idealOfVars_eq_restrictSupportIdeal] diff --git a/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean b/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean index f0617d25974419..5339bb38ce65d4 100644 --- a/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean +++ b/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean @@ -202,6 +202,7 @@ noncomputable def sumSMulXSMulY : variable (c : n →₀ R) +set_option backward.isDefEq.respectTransparency false in theorem irreducible_sumSMulXSMulY [IsDomain R] (hc : c.support.Nontrivial) (h_dvd : ∀ r, (∀ i, r ∣ c i) → IsUnit r) : @@ -210,8 +211,7 @@ theorem irreducible_sumSMulXSMulY [IsDomain R] let ι : n ↪ ((n ⊕ n) →₀ ℕ) := ⟨fun i ↦ .single (.inl i) 1 + .single (.inr i) 1, fun i j ↦ by simp +contextual [Finsupp.ext_iff, Finsupp.single_apply, ite_eq_iff']⟩ - -- unfortunate defeq abuse... we should have an `.embDomain`-like constructor for MvPolys - have aux : sumSMulXSMulY c = c.embDomain ι := by + have aux : sumSMulXSMulY c = .ofCoeff (c.embDomain ι) := by rw [← Finsupp.sum_single (Finsupp.embDomain _ _)] simp [Finsupp.sum_embDomain, sumSMulXSMulY, X, monomial_mul, Finsupp.linearCombination_apply, smul_monomial, ι] @@ -219,7 +219,7 @@ theorem irreducible_sumSMulXSMulY [IsDomain R] have hcoeff (i : n) : coeff (ι i) (sumSMulXSMulY c) = c i := by simp [aux, coeff, Finsupp.embDomain_apply] have hsupp : (sumSMulXSMulY c).support = c.support.map ι := by - rw [aux, support, Finsupp.support_embDomain] + simp [aux, support, Finsupp.support_embDomain] obtain ⟨a, ha⟩ := hc.nonempty apply irreducible_of_disjoint_support (d := ι a) (i := .inl a) · rwa [hsupp, Finset.map_nontrivial] diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean index c6997c31cdb15e..592ab3ac4e4d96 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean @@ -174,7 +174,7 @@ end CommRing end IsSymmetric /-- `MvPolynomial.rename` induces an isomorphism between the symmetric subalgebras. -/ -@[simps!] +@[simps! apply_coe symm_apply_coe] def renameSymmetricSubalgebra [CommSemiring R] (e : σ ≃ τ) : symmetricSubalgebra σ R ≃ₐ[R] symmetricSubalgebra τ R := AlgEquiv.ofAlgHom @@ -253,8 +253,8 @@ theorem support_esymm'' [DecidableEq σ] [Nontrivial R] (n : ℕ) : (Finsupp.single (∑ i ∈ t, Finsupp.single i 1) (1 : R)).support := by rw [esymm_eq_sum_monomial] simp only [← single_eq_monomial] - refine Finsupp.support_sum_eq_biUnion (powersetCard n (univ : Finset σ)) ?_ - intro s t hst + simp only [support, MvPolynomial, AddMonoidAlgebra.coeff_sum, AddMonoidAlgebra.coeff_single] + refine Finsupp.support_sum_eq_biUnion _ fun s t hst ↦ ?_ rw [disjoint_left, Finsupp.support_single _ one_ne_zero] rw [Finsupp.support_single _ one_ne_zero] simp only [mem_singleton] diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index 2be43ba2d95807..7ffe045f11fbd9 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -129,6 +129,7 @@ def IsWeightedHomogeneous (w : σ → M) (φ : MvPolynomial σ R) (m : M) : Prop variable (R) +set_option backward.isDefEq.respectTransparency false in /-- The submodule of homogeneous `MvPolynomial`s of degree `n`. -/ def weightedHomogeneousSubmodule (w : σ → M) (m : M) : Submodule R (MvPolynomial σ R) where carrier := { x | x.IsWeightedHomogeneous w m } @@ -155,14 +156,14 @@ set_option backward.isDefEq.respectTransparency false in `p.support ⊆ {d | weight w d = m}`. While equal, the former has a convenient definitional reduction. -/ theorem weightedHomogeneousSubmodule_eq_finsupp_supported (w : σ → M) (m : M) : - weightedHomogeneousSubmodule R w m = Finsupp.supported R R { d | weight w d = m } := by + weightedHomogeneousSubmodule R w m = AddMonoidAlgebra.supported R R {d | weight w d = m} := by ext x - rw [mem_supported, Set.subset_def] - simp only [Finsupp.mem_support_iff, mem_coe] - rfl + simp [IsWeightedHomogeneous] + simp [AddMonoidAlgebra.mem_supported, Set.subset_def, MvPolynomial, coeff] variable {R} +set_option backward.isDefEq.respectTransparency false in /-- The submodule generated by products `Pm * Pn` of weighted homogeneous polynomials of degrees `m` and `n` is contained in the submodule of weighted homogeneous polynomials of degree `m + n`. -/ theorem weightedHomogeneousSubmodule_mul (w : σ → M) (m n : M) : @@ -251,6 +252,7 @@ theorem sum {ι : Type*} (s : Finset ι) (φ : ι → MvPolynomial σ R) (n : M) (h : ∀ i ∈ s, IsWeightedHomogeneous w (φ i) n) : IsWeightedHomogeneous w (∑ i ∈ s, φ i) n := (weightedHomogeneousSubmodule R w n).sum_mem h +set_option backward.isDefEq.respectTransparency false in /-- The product of weighted homogeneous polynomials of weighted degrees `m` and `n` is weighted homogeneous of weighted degree `m + n`. -/ theorem mul {w : σ → M} (hφ : IsWeightedHomogeneous w φ m) (hψ : IsWeightedHomogeneous w ψ n) : @@ -316,13 +318,14 @@ lemma induction_on {w : σ → M} {m : M} simp_rw [Algebra.smul_def, algebraMap_eq, ← mul_assoc, ← map_mul] apply hx⟩ } rw [← mem_weightedHomogeneousSubmodule, weightedHomogeneousSubmodule_eq_finsupp_supported, - Finsupp.supported_eq_span_single] at hp + AddMonoidAlgebra.supported_eq_span_single] at hp refine (Submodule.span_le (p := A) |>.mpr ?_ hp).2 rw [Set.image_subset_iff] intro d hd - simp only [single_eq_monomial, Set.mem_preimage, SetLike.mem_coe] + simp only [MvPolynomial, Submodule.coe_set_mk, AddSubmonoid.coe_set_mk, + AddSubsemigroup.coe_set_mk, preimage_setOf_eq, mem_setOf_eq, A] refine ⟨isWeightedHomogeneous_monomial w d 1 hd, fun a ↦ ?_⟩ - simp [MvPolynomial.C_mul_monomial, monomial _ _ hd] + simpa only [single_eq_monomial, ← MvPolynomial.C_mul_monomial] using monomial _ (a * 1) hd end IsWeightedHomogeneous @@ -340,24 +343,25 @@ lemma WeightedHomogeneousSubmodule.gradedMonoid {w : σ → M} : of all its weighted homogeneous components. -/ def weightedHomogeneousComponent (w : σ → M) (n : M) : MvPolynomial σ R →ₗ[R] MvPolynomial σ R := letI := Classical.decEq M - (Submodule.subtype _).comp <| Finsupp.restrictDom _ _ { d | weight w d = n } + (coeffLinearEquiv _).symm.toLinearMap ∘ₗ Submodule.subtype _ ∘ₗ + Finsupp.restrictDom _ _ {d | weight w d = n} ∘ₗ (coeffLinearEquiv _).toLinearMap section WeightedHomogeneousComponent variable {w : σ → M} (n : M) (φ ψ : MvPolynomial σ R) +set_option backward.isDefEq.respectTransparency false in theorem coeff_weightedHomogeneousComponent [DecidableEq M] (d : σ →₀ ℕ) : coeff d (weightedHomogeneousComponent w n φ) = - if weight w d = n then coeff d φ else 0 := - letI := Classical.decEq M - Finsupp.filter_apply (fun d : σ →₀ ℕ => weight w d = n) φ d |>.trans <| by convert! rfl + if weight w d = n then coeff d φ else 0 := by + simp [weightedHomogeneousComponent, MvPolynomial, coeff, Finsupp.filter_apply] set_option backward.isDefEq.respectTransparency false in theorem weightedHomogeneousComponent_apply [DecidableEq M] : weightedHomogeneousComponent w n φ = - ∑ d ∈ φ.support with weight w d = n, monomial d (coeff d φ) := - letI := Classical.decEq M - Finsupp.filter_eq_sum (fun d : σ →₀ ℕ => weight w d = n) φ |>.trans <| by convert! rfl + ∑ d ∈ φ.support with weight w d = n, monomial d (coeff d φ) := by + simp [weightedHomogeneousComponent, MvPolynomial, coeff, Finsupp.filter_eq_sum, support, monomial] + congr /-- The `n` weighted homogeneous component of a polynomial is weighted homogeneous of weighted degree `n`. -/ diff --git a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean index 0f01f106605e17..6da78eab0af087 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean @@ -77,7 +77,8 @@ def truncFinset (R : Type*) [CommSemiring R] (s : Finset (σ →₀ ℕ)) : map_add' _ _ := by simp [sum_add_distrib] map_smul' _ _ := by classical - ext; simp [MvPolynomial.coeff_sum] + ext + simp [MvPolynomial.coeff, single, MvPolynomial.monomial] theorem truncFinset_apply (p : MvPowerSeries σ R) : truncFinset R s p = ∑ x ∈ s, MvPolynomial.monomial x (p.coeff x) := by rfl diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index 96e51ee43704b3..bc3e957ea17a99 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -726,7 +726,7 @@ private theorem prime_C_iff_of_fintype {R : Type u} (σ : Type v) {r : R} [CommR · congr! simp only [renameEquiv_apply, algHom_C, algebraMap_eq] · induction Fintype.card σ with - | zero => exact MulEquiv.prime_iff (isEmptyAlgEquiv R (Fin 0)).symm (p := r) + | zero => simpa using MulEquiv.prime_iff (isEmptyAlgEquiv R (Fin 0)).symm (p := r) | succ d hd => convert! MulEquiv.prime_iff (finSuccEquiv R d).symm (p := Polynomial.C (C r)) · simp [← finSuccEquiv_comp_C_eq_C] @@ -761,19 +761,18 @@ theorem prime_rename_iff (s : Set σ) {p : MvPolynomial s R} : let eqv := (sumAlgEquiv R (↥sᶜ) s).symm.trans (renameEquiv R <| (Equiv.sumComm (↥sᶜ) s).trans <| Equiv.Set.sumCompl s) - have : (rename (↑)).toRingHom = eqv.toAlgHom.toRingHom.comp C := by - apply ringHom_ext - · simp [eqv] - · simp [eqv] + have : rename Subtype.val = eqv.toAlgHom.comp (Algebra.algHom _ (MvPolynomial s R) _) := by + apply algHom_ext + simp [eqv, rename, X, monomial, Algebra.algHom, renameEquiv, Finsupp.mapDomain.addMonoidHom, + sumAlgEquiv, C] apply_fun (· p) at this - simp only [AlgHom.toRingHom_eq_coe, RingHom.coe_coe, AlgEquiv.toAlgHom_toRingHom, - RingHom.coe_comp, Function.comp_apply] at this - rw [this, MulEquiv.prime_iff, prime_C_iff] + simpa [this, MulEquiv.prime_iff, Algebra.algHom] using (prime_C_iff _).symm end MvPolynomial end Prime +set_option backward.isDefEq.respectTransparency false in /-- **Hilbert basis theorem**: a polynomial ring over a Noetherian ring is a Noetherian ring. -/ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNoetherianRing R[X] := isNoetherianRing_iff.2 @@ -854,10 +853,8 @@ namespace Polynomial theorem linearIndependent_powers_iff_aeval (f : M →ₗ[R] M) (v : M) : (LinearIndependent R fun n : ℕ => (f ^ n) v) ↔ ∀ p : R[X], aeval f p v = 0 → p = 0 := by - rw [linearIndependent_iff] - simp only [Finsupp.linearCombination_apply, aeval_endomorphism, forall_iff_forall_finsupp, - ofFinsupp_eq_zero] - exact Iff.rfl + simp [linearIndependent_iff, Finsupp.linearCombination_apply, aeval_endomorphism, Finsupp.sum, + forall_iff_forall_finsupp, AddMonoidAlgebra.coeffEquiv.forall_congr_left, Polynomial.sum] theorem disjoint_ker_aeval_of_isCoprime (f : M →ₗ[R] M) {p q : R[X]} (hpq : IsCoprime p q) : Disjoint (LinearMap.ker (aeval f p)) (LinearMap.ker (aeval f q)) := by diff --git a/Mathlib/RingTheory/Polynomial/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/IsIntegral.lean index 2c5d2a56db4dde..1bda775fc4645b 100644 --- a/Mathlib/RingTheory/Polynomial/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/IsIntegral.lean @@ -232,7 +232,7 @@ theorem MvPolynomial.isIntegral_iff_isIntegral_coeff.{w} {σ : Type w} {f : MvPo (isEmptyAlgEquiv _ PEmpty).symm.injective (.of_comp (f := (isEmptyAlgEquiv _ PEmpty).toRingHom) ?_) convert! H - · aesop (add simp MvPolynomial.isEmptyAlgEquiv) + · ext r m <;> simp [Subsingleton.elim m 0, C, X, monomial, coeff, map] · obtain rfl := Subsingleton.elim n 0 have : constantCoeff = (isEmptyAlgEquiv S PEmpty).toRingHom := by aesop simpa [-EmbeddingLike.apply_eq_iff_eq, -isEmptyAlgEquiv_apply] using! diff --git a/Mathlib/RingTheory/Polynomial/Opposites.lean b/Mathlib/RingTheory/Polynomial/Opposites.lean index 50970443dfb905..70b5c0f44591f3 100644 --- a/Mathlib/RingTheory/Polynomial/Opposites.lean +++ b/Mathlib/RingTheory/Polynomial/Opposites.lean @@ -42,7 +42,7 @@ set_option backward.isDefEq.respectTransparency false in @[simp] theorem opRingEquiv_op_monomial (n : ℕ) (r : R) : opRingEquiv R (op (monomial n r : R[X])) = monomial n (op r) := by - simp [opRingEquiv] + ext; simp [opRingEquiv, ← ofFinsupp_single] @[simp] theorem opRingEquiv_op_C (a : R) : opRingEquiv R (op (C a)) = C (op a) := diff --git a/Mathlib/RingTheory/PowerBasis.lean b/Mathlib/RingTheory/PowerBasis.lean index 4b16f4168d621b..0b0d5f716d58e2 100644 --- a/Mathlib/RingTheory/PowerBasis.lean +++ b/Mathlib/RingTheory/PowerBasis.lean @@ -99,13 +99,9 @@ theorem mem_span_pow' {x y : S} {d : ℕ} : ext n simp_rw [Set.mem_range, Set.mem_image, Finset.mem_coe, Finset.mem_range] exact ⟨fun ⟨⟨i, hi⟩, hy⟩ => ⟨i, hi, hy⟩, fun ⟨i, hi, hy⟩ => ⟨⟨i, hi⟩, hy⟩⟩ - simp only [this, mem_span_image_iff_linearCombination, degree_lt_iff_coeff_zero, - exists_iff_exists_finsupp, coeff, aeval_def, eval₂_eq_sum, Polynomial.sum, - mem_supported', linearCombination, Finsupp.sum, Algebra.smul_def, - LinearMap.id_coe, id, not_lt, Finsupp.coe_lsum, LinearMap.coe_smulRight, - Finset.mem_range, Finset.mem_coe] - simp_rw [@eq_comm _ y] - exact Iff.rfl + simp [this, mem_span_image_iff_linearCombination, degree_lt_iff_coeff_zero, eq_comm, + exists_iff_exists_finsupp, coeff, aeval_def, eval₂_eq_sum, Polynomial.sum, mem_supported', + Finsupp.sum, linearCombination, Algebra.smul_def, AddMonoidAlgebra.coeffEquiv.exists_congr_left] theorem mem_span_pow {x y : S} {d : ℕ} (hd : d ≠ 0) : y ∈ Submodule.span R (Set.range fun i : Fin d => x ^ (i : ℕ)) ↔ diff --git a/Mathlib/RingTheory/RingHom/StandardSmooth.lean b/Mathlib/RingTheory/RingHom/StandardSmooth.lean index 72713dee616133..5d6074b5714dea 100644 --- a/Mathlib/RingTheory/RingHom/StandardSmooth.lean +++ b/Mathlib/RingTheory/RingHom/StandardSmooth.lean @@ -244,8 +244,7 @@ theorem _root_.Algebra.IsStandardSmoothOfRelativeDimension.exists_etale_mvPolyno Algebra.Generators.ofSurjective] using congr($H _) suffices e ((e.symm (P.relation j)).pderiv i) = (P.relation j).pderiv (P.map i) by simp [Algebra.PreSubmersivePresentation.jacobiMatrix_apply, this] - simp [e, MvPolynomial.pderiv_sumToIter, ← MvPolynomial.pderiv_rename e₀.injective, - show e₀ (Sum.inl i) = P.map i from rfl] } + simp [e, ← MvPolynomial.pderiv_rename e₀.injective, show e₀ (Sum.inl i) = P.map i from rfl] } exact etale_algebraMap.mpr (Algebra.Etale.iff_isStandardSmoothOfRelativeDimension_zero.mpr ⟨_, _, _, inferInstance, P', by simp [Algebra.Presentation.dimension]⟩) diff --git a/Mathlib/RingTheory/Smooth/IntegralClosure.lean b/Mathlib/RingTheory/Smooth/IntegralClosure.lean index 614a4369212324..a16bc235247548 100644 --- a/Mathlib/RingTheory/Smooth/IntegralClosure.lean +++ b/Mathlib/RingTheory/Smooth/IntegralClosure.lean @@ -130,27 +130,29 @@ lemma TensorProduct.toIntegralClosure_mvPolynomial_bijective {σ : Type*} : refine ⟨toIntegralClosure_injective_of_flat, ?_⟩ rintro ⟨x, hx⟩ let e₀ : MvPolynomial σ R ⊗[R] B ≃ₐ[R] MvPolynomial σ B := - MvPolynomial.scalarRTensorAlgEquiv + (Algebra.TensorProduct.comm R _ _).trans + ((MvPolynomial.algebraTensorAlgEquiv R B).restrictScalars R) + let e₁ := (Algebra.TensorProduct.comm R (MvPolynomial σ R) (integralClosure R B)).trans + ((MvPolynomial.algebraTensorAlgEquiv R (integralClosure R B)).restrictScalars R) let e : MvPolynomial σ R ⊗[R] B ≃ₐ[MvPolynomial σ R] MvPolynomial σ B := { toRingEquiv := e₀.toRingEquiv, commutes' r := by change e₀.toRingHom.comp (algebraMap _ _) r = _ congr 1 - ext <;> simp [e₀, MvPolynomial.scalarRTensorAlgEquiv, MvPolynomial.coeff_map, - ← Algebra.algebraMap_eq_smul_one, apply_ite (algebraMap _ _), MvPolynomial.coeff_X] } + ext <;> simp [e₀, MvPolynomial.coeff_X] } have := MvPolynomial.isIntegral_iff_isIntegral_coeff.mp (hx.map e) obtain ⟨y, hy⟩ : e x ∈ RingHom.range (MvPolynomial.map (integralClosure R B).val.toRingHom) := by refine MvPolynomial.mem_range_map_iff_coeffs_subset.mpr ?_ simp [Set.subset_def, mem_integralClosure_iff, MvPolynomial.mem_coeffs_iff, @forall_comm B, this] - refine ⟨MvPolynomial.scalarRTensorAlgEquiv.symm y, Subtype.ext <| e.injective (.trans ?_ hy)⟩ - obtain ⟨y, rfl⟩ := (MvPolynomial.scalarRTensorAlgEquiv (R := R)).surjective y + refine ⟨e₁.symm y, Subtype.ext <| e.injective (.trans ?_ hy)⟩ + obtain ⟨y, rfl⟩ := e₁.surjective y dsimp [TensorProduct.toIntegralClosure, e] simp only [AlgEquiv.symm_apply_apply] have : e₀.toAlgHom.comp (Algebra.TensorProduct.map (AlgHom.id R (MvPolynomial σ R)) (integralClosure R B).val) = - (MvPolynomial.mapAlgHom (integralClosure R B).val).comp - MvPolynomial.scalarRTensorAlgEquiv.toAlgHom := by - ext <;> simp [e₀, MvPolynomial.coeff_map, MvPolynomial.scalarRTensorAlgEquiv] + (MvPolynomial.mapAlgHom (integralClosure R B).val).comp e₁.toAlgHom := by + ext <;> simp [e₀, e₁, MvPolynomial.coeff_map, MvPolynomial.coeff_one, + apply_ite ((↑) : (integralClosure R B) → B)] exact congr($this y) attribute [local instance] Algebra.TensorProduct.rightAlgebra in diff --git a/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean b/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean index 72051d51efadc5..d8ec4669009cfa 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean @@ -200,15 +200,16 @@ lemma mem_image_comap_C_basicOpen (f : MvPolynomial σ R) (x : PrimeSpectrum R) classical trans f.map (algebraMap R x.asIdeal.ResidueField) ≠ 0 · refine (mem_image_comap_basicOpen _ _).trans (not_iff_not.mpr ?_) - let e : MvPolynomial σ R ⊗[R] x.asIdeal.ResidueField ≃ₐ[R] + let e : x.asIdeal.ResidueField ⊗[R] MvPolynomial σ R ≃ₐ[x.asIdeal.ResidueField] MvPolynomial σ x.asIdeal.ResidueField := scalarRTensorAlgEquiv - rw [← IsNilpotent.map_iff e.injective, isNilpotent_iff_eq_zero] - change (e.toAlgHom.toRingHom).comp (algebraMap _ _) f = 0 ↔ MvPolynomial.map _ f = 0 + rw [← IsNilpotent.map_iff (Algebra.TensorProduct.comm ..).injective, + ← IsNilpotent.map_iff e.injective, isNilpotent_iff_eq_zero] + change (e.toAlgHom.toRingHom.comp (Algebra.TensorProduct.comm ..).toRingHom).comp + (algebraMap _ _) f = 0 ↔ MvPolynomial.map _ f = 0 congr! ext - · simp [scalarRTensorAlgEquiv, e, coeff_map, - Algebra.smul_def, apply_ite (f := algebraMap _ _)] - · simp [e, scalarRTensorAlgEquiv, coeff_map, coeff_X] + · simp [scalarRTensorAlgEquiv, e, Algebra.smul_def] + · simp [e, scalarRTensorAlgEquiv, coeff, map, X, monomial] · simp [MvPolynomial.ext_iff, coeff_map] lemma image_comap_C_basicOpen (f : MvPolynomial σ R) : diff --git a/Mathlib/RingTheory/TensorProduct/MonoidAlgebra.lean b/Mathlib/RingTheory/TensorProduct/MonoidAlgebra.lean index a709f392dc6b9f..5b6120229cfb2f 100644 --- a/Mathlib/RingTheory/TensorProduct/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/TensorProduct/MonoidAlgebra.lean @@ -6,16 +6,13 @@ Authors: Michał Mrugała module public import Mathlib.Algebra.MonoidAlgebra.Basic +public import Mathlib.LinearAlgebra.DirectSum.Finsupp public import Mathlib.RingTheory.IsTensorProduct /-! # Monoid algebras commute with base change In this file we show that monoid algebras are stable under pushout. - -## TODO - -Additivise -/ @[expose] public noncomputable section @@ -23,50 +20,50 @@ Additivise open Algebra TensorProduct namespace MonoidAlgebra -variable {R M S A B : Type*} [CommSemiring R] [CommSemiring S] [CommSemiring A] [CommSemiring B] -variable [Algebra R S] [Algebra R A] [Algebra R B] [CommMonoid M] +variable {R M N S A B : Type*} [CommSemiring R] [CommSemiring S] [CommSemiring A] [CommSemiring B] + [Algebra R S] [Algebra R A] [Algebra R B] [Algebra S A] [IsScalarTower R S A] + [CommMonoid M] [CommMonoid N] -- Note: Cannot be additivised automatically because of the use of `Multiplicative` -- in `AddMonoidAlgebra.liftNCAlgHom` and `of` /-- Implementation detail. -/ -noncomputable def _root_.AddMonoidAlgebra.tensorEquiv.invFun [AddCommMonoid M] : - AddMonoidAlgebra (A ⊗[R] B) M →ₐ[A] A ⊗[R] AddMonoidAlgebra B M := +noncomputable def _root_.AddMonoidAlgebra.rTensorEquivAlgEquiv.invFun [AddCommMonoid M] : + AddMonoidAlgebra (A ⊗[R] B) M →ₐ[S] A ⊗[R] AddMonoidAlgebra B M := AddMonoidAlgebra.liftNCAlgHom (Algebra.TensorProduct.map (.id _ _) AddMonoidAlgebra.singleZeroAlgHom) (Algebra.TensorProduct.includeRight.toMonoidHom.comp <| AddMonoidAlgebra.of B M) fun _ _ ↦ .all .. /-- Implementation detail. -/ -@[to_additive existing (dont_translate := R A B)] -def tensorEquiv.invFun : (A ⊗[R] B)[M] →ₐ[A] A ⊗[R] B[M] := +@[to_additive existing (dont_translate := R)] +def rTensorEquivAlgEquiv.invFun : (A ⊗[R] B)[M] →ₐ[S] A ⊗[R] B[M] := MonoidAlgebra.liftNCAlgHom (Algebra.TensorProduct.map (.id _ _) singleOneAlgHom) (Algebra.TensorProduct.includeRight.toMonoidHom.comp (of B M)) fun _ _ ↦ .all .. -set_option backward.isDefEq.respectTransparency false in omit [CommMonoid M] in variable (R A B) [AddCommMonoid M] in -lemma _root_.AddMonoidAlgebra.tensorEquiv.invFun_tmul (a : A) (m : M) (b : B) : - AddMonoidAlgebra.tensorEquiv.invFun (single m (a ⊗ₜ[R] b)) = a ⊗ₜ single m b := by - simp [AddMonoidAlgebra.tensorEquiv.invFun] +lemma _root_.AddMonoidAlgebra.rTensorEquivAlgEquiv.invFun_tmul (a : A) (m : M) (b : B) : + AddMonoidAlgebra.rTensorEquivAlgEquiv.invFun (S := S) (.single m (a ⊗ₜ[R] b)) = + a ⊗ₜ .single m b := by + simp [AddMonoidAlgebra.rTensorEquivAlgEquiv.invFun] -set_option backward.isDefEq.respectTransparency false in -@[to_additive existing (dont_translate := R A B) (attr := simp)] -lemma tensorEquiv.invFun_tmul (a : A) (m : M) (b : B) : - tensorEquiv.invFun (single m (a ⊗ₜ[R] b)) = a ⊗ₜ single m b := by - simp [tensorEquiv.invFun] +@[to_additive existing (dont_translate := R) (attr := simp)] +lemma rTensorEquivAlgEquiv.invFun_tmul (a : A) (m : M) (b : B) : + rTensorEquivAlgEquiv.invFun (S := S) (single m (a ⊗ₜ[R] b)) = a ⊗ₜ single m b := by + simp [rTensorEquivAlgEquiv.invFun] -variable (R A B) in +variable (R S A B) in /-- The base change of `B[M]` to an `R`-algebra `A` is isomorphic to `(A ⊗[R] B)[M]` as an `A`-algebra. -/ -@[to_additive (dont_translate := R A B) +@[to_additive (dont_translate := R S A B) /-- The base change of `B[M]` to an `R`-algebra `A` is isomorphic to `(A ⊗[R] B)[M]` as an `A`-algebra. -/] -noncomputable def tensorEquiv : A ⊗[R] B[M] ≃ₐ[A] (A ⊗[R] B)[M] := by - refine .ofAlgHom +noncomputable def rTensorEquivAlgEquiv : A ⊗[R] B[M] ≃ₐ[S] (A ⊗[R] B)[M] := by + refine .restrictScalars S <| .ofAlgHom (Algebra.TensorProduct.lift ((IsScalarTower.toAlgHom A (A ⊗[R] B) _).comp Algebra.TensorProduct.includeLeft) (mapAlgHom _ Algebra.TensorProduct.includeRight) fun p n ↦ .all ..) - tensorEquiv.invFun ?_ ?_ + rTensorEquivAlgEquiv.invFun ?_ ?_ · apply AlgHom.toLinearMap_injective ext simp @@ -75,21 +72,38 @@ noncomputable def tensorEquiv : A ⊗[R] B[M] ≃ₐ[A] (A ⊗[R] B)[M] := by ext simp -@[to_additive (dont_translate := A B) (attr := simp)] -lemma tensorEquiv_tmul (a : A) (p : B[M]) : - tensorEquiv R A B (a ⊗ₜ p) = a • mapAlgHom M Algebra.TensorProduct.includeRight p := by - simp [tensorEquiv, Algebra.smul_def] +@[to_additive (dont_translate := R A B) (attr := simp)] +lemma rTensorEquiv_tmulAlgEquiv (a : A) (p : B[M]) : + rTensorEquivAlgEquiv R S A B (a ⊗ₜ p) = + a • mapAlgHom M Algebra.TensorProduct.includeRight p := by + simp [rTensorEquivAlgEquiv, Algebra.smul_def] @[to_additive (dont_translate := R A B) (attr := simp)] -lemma tensorEquiv_symm_single (m : M) (a : A) (b : B) : - (tensorEquiv R A B).symm (single m (a ⊗ₜ b)) = a ⊗ₜ single m b := tensorEquiv.invFun_tmul .. +lemma rTensorEquiv_symm_singleAlgEquiv (m : M) (a : A) (b : B) : + (rTensorEquivAlgEquiv R S A B).symm (single m (a ⊗ₜ b)) = a ⊗ₜ single m b := + rTensorEquivAlgEquiv.invFun_tmul .. + +variable (R A B) in +/-- The base change of `B[M]` to an `R`-algebra `A` is isomorphic to `(A ⊗[R] B)[M]` +as an `A`-algebra. -/ +@[to_additive (dont_translate := R A B) +/-- The base change of `B[M]` to an `R`-algebra `A` is isomorphic to `(A ⊗[R] B)[M]` +as an `A`-algebra. -/] +noncomputable def lTensorAlgEquiv : A[M] ⊗[R] B ≃ₐ[R] (A ⊗[R] B)[M] := + (Algebra.TensorProduct.comm ..).trans <| (rTensorEquivAlgEquiv _ _ _ _).trans <| + mapAlgEquiv _ _ <| Algebra.TensorProduct.comm .. + +@[to_additive (dont_translate := R A B) (attr := simp)] +lemma lTensorAlgEquiv_symm_single (m : M) (a : A) (b : B) : + (lTensorAlgEquiv R A B).symm (single m (a ⊗ₜ b)) = single m a ⊗ₜ b := by + simp [lTensorAlgEquiv] variable (R A) in /-- The base change of `R[M]` to an `R`-algebra `A` is isomorphic to `A[M]` as an `A`-algebra. -/ @[to_additive (dont_translate := R A) /-- The base change of `R[M]` to an `R`-algebra `A` is isomorphic to `A[M]` as an `A`-algebra. -/] noncomputable def scalarTensorEquiv : A ⊗[R] R[M] ≃ₐ[A] A[M] := - (tensorEquiv ..).trans <| mapAlgEquiv A M <| Algebra.TensorProduct.rid R A A + (rTensorEquivAlgEquiv ..).trans <| mapAlgEquiv A M <| Algebra.TensorProduct.rid R A A @[to_additive (dont_translate := R A) (attr := simp)] lemma scalarTensorEquiv_tmul (a : A) (p : R[M]) : @@ -106,7 +120,7 @@ variable [Algebra S B] [Algebra A B] [IsScalarTower R A B] [IsScalarTower R S B] @[to_additive (dont_translate := R S B)] instance instIsPushout [IsPushout R S A B] : IsPushout R S A[M] B[M] where - out := .of_equiv ((tensorEquiv (M := M) R S A).trans <| + out := .of_equiv ((rTensorEquivAlgEquiv R S S A (M := M)).trans <| mapAlgEquiv S M <| IsPushout.equiv R S A B).toLinearEquiv fun x ↦ by induction x using induction_linear <;> simp_all [IsPushout.equiv_tmul] @@ -114,6 +128,31 @@ instance instIsPushout [IsPushout R S A B] : IsPushout R S A[M] B[M] where instance instIsPushout' [IsPushout R A S B] : IsPushout R A[M] S B[M] := have : IsPushout R S A B := .symm ‹_›; .symm inferInstance +omit [CommMonoid M] [CommMonoid N] + +-- TODO: Generalise to different base rings, strengthen to an `AlgEquiv` +variable (R) in +/-- The tensor product of two monoid algebras is the monoid algebra of their product. -/ +@[to_additive (dont_translate := R) (attr := simps! apply_coeff) +/-- The tensor product of two monoid algebras is the monoid algebra of their product. -/] +noncomputable def tensorEquiv : R[M] ⊗[R] R[N] ≃ₗ[R] R[M × N] := + TensorProduct.congr (coeffLinearEquiv _) (coeffLinearEquiv _) ≪≫ₗ + finsuppTensorFinsupp' .. ≪≫ₗ (coeffLinearEquiv _).symm + +@[to_additive (dont_translate := R) (attr := simp)] +lemma tensorEquiv_single_tmul_single (m : M) (r₁ : R) (n : N) (r₂ : R) : + tensorEquiv R (single m r₁ ⊗ₜ single n r₂) = single (m, n) (r₁ * r₂) := by ext; simp + +@[to_additive (dont_translate := R)] +lemma tensorEquiv_symm_single_eq_single_one_tmul (mn : M × N) (r : R) : + (tensorEquiv R).symm (single mn r) = single mn.1 1 ⊗ₜ single mn.2 r := by + simp [tensorEquiv, finsuppTensorFinsupp'_symm_single_eq_single_one_tmul] + +@[to_additive (dont_translate := R)] +lemma tensorEquiv_symm_single_eq_tmul_single_one (mn : M × N) (r : R) : + (tensorEquiv R).symm (single mn r) = single mn.1 r ⊗ₜ single mn.2 1 := by + simp [tensorEquiv, finsuppTensorFinsupp'_symm_single_eq_tmul_single_one] + end MonoidAlgebra end diff --git a/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean b/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean index 37fea569103ea5..cf25c5461a1c52 100644 --- a/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean +++ b/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean @@ -7,7 +7,7 @@ module public import Mathlib.LinearAlgebra.DirectSum.Finsupp public import Mathlib.Algebra.MvPolynomial.Eval -public import Mathlib.RingTheory.TensorProduct.Basic +public import Mathlib.RingTheory.TensorProduct.MonoidAlgebra public import Mathlib.Algebra.MvPolynomial.Equiv public import Mathlib.RingTheory.IsTensorProduct @@ -58,149 +58,36 @@ variable {σ ι : Type*} variable {S : Type*} [CommSemiring S] [Algebra R S] -section Module - -variable [DecidableEq σ] -variable [AddCommMonoid N] [Module R N] - -/-- The tensor product of a polynomial ring by a module is - linearly equivalent to a Finsupp of a tensor product -/ -noncomputable def rTensor : - MvPolynomial σ S ⊗[R] N ≃ₗ[S] (σ →₀ ℕ) →₀ (S ⊗[R] N) := - TensorProduct.finsuppLeft _ _ _ _ _ - -lemma rTensor_apply_tmul (p : MvPolynomial σ S) (n : N) : - rTensor (p ⊗ₜ[R] n) = p.sum (fun i m ↦ Finsupp.single i (m ⊗ₜ[R] n)) := - TensorProduct.finsuppLeft_apply_tmul p n - -lemma rTensor_apply_tmul_apply (p : MvPolynomial σ S) (n : N) (d : σ →₀ ℕ) : - rTensor (p ⊗ₜ[R] n) d = (coeff d p) ⊗ₜ[R] n := - TensorProduct.finsuppLeft_apply_tmul_apply p n d - -lemma rTensor_apply_monomial_tmul (e : σ →₀ ℕ) (s : S) (n : N) (d : σ →₀ ℕ) : - rTensor (monomial e s ⊗ₜ[R] n) d = if e = d then s ⊗ₜ[R] n else 0 := by - simp only [rTensor_apply_tmul_apply, coeff_monomial, ite_tmul] - -lemma rTensor_apply_X_tmul (s : σ) (n : N) (d : σ →₀ ℕ) : - rTensor (X s ⊗ₜ[R] n) d = if Finsupp.single s 1 = d then (1 : S) ⊗ₜ[R] n else 0 := by - rw [rTensor_apply_tmul_apply, coeff_X, ite_tmul] - -lemma rTensor_apply (t : MvPolynomial σ S ⊗[R] N) (d : σ →₀ ℕ) : - rTensor t d = ((lcoeff S d).restrictScalars R).rTensor N t := - TensorProduct.finsuppLeft_apply t d - -@[simp] -lemma rTensor_symm_apply_single (d : σ →₀ ℕ) (s : S) (n : N) : - rTensor.symm (Finsupp.single d (s ⊗ₜ n)) = - (monomial d s) ⊗ₜ[R] n := - TensorProduct.finsuppLeft_symm_apply_single (R := R) d s n - -/-- The tensor product of the polynomial algebra by a module - is linearly equivalent to a Finsupp of that module -/ -noncomputable def scalarRTensor : - MvPolynomial σ R ⊗[R] N ≃ₗ[R] (σ →₀ ℕ) →₀ N := - TensorProduct.finsuppScalarLeft _ _ _ - -lemma scalarRTensor_apply_tmul (p : MvPolynomial σ R) (n : N) : - scalarRTensor (p ⊗ₜ[R] n) = p.sum (fun i m ↦ Finsupp.single i (m • n)) := - TensorProduct.finsuppScalarLeft_apply_tmul p n - -lemma scalarRTensor_apply_tmul_apply (p : MvPolynomial σ R) (n : N) (d : σ →₀ ℕ) : - scalarRTensor (p ⊗ₜ[R] n) d = coeff d p • n := - TensorProduct.finsuppScalarLeft_apply_tmul_apply p n d - -lemma scalarRTensor_apply_monomial_tmul (e : σ →₀ ℕ) (r : R) (n : N) (d : σ →₀ ℕ) : - scalarRTensor (monomial e r ⊗ₜ[R] n) d = if e = d then r • n else 0 := by - rw [scalarRTensor_apply_tmul_apply, coeff_monomial, ite_smul, zero_smul] - -lemma scalarRTensor_apply_X_tmul_apply (s : σ) (n : N) (d : σ →₀ ℕ) : - scalarRTensor (X s ⊗ₜ[R] n) d = if Finsupp.single s 1 = d then n else 0 := by - rw [scalarRTensor_apply_tmul_apply, coeff_X, ite_smul, one_smul, zero_smul] - -lemma scalarRTensor_symm_apply_single (d : σ →₀ ℕ) (n : N) : - scalarRTensor.symm (Finsupp.single d n) = (monomial d 1) ⊗ₜ[R] n := - TensorProduct.finsuppScalarLeft_symm_apply_single d n - -end Module - section Algebra variable [CommSemiring N] [Algebra R N] /-- The algebra morphism from a tensor product of a polynomial algebra by an algebra to a polynomial algebra -/ -noncomputable def rTensorAlgHom : - (MvPolynomial σ S) ⊗[R] N →ₐ[S] MvPolynomial σ (S ⊗[R] N) := - Algebra.TensorProduct.lift - (mapAlgHom Algebra.TensorProduct.includeLeft) - ((IsScalarTower.toAlgHom R (S ⊗[R] N) _).comp Algebra.TensorProduct.includeRight) - (fun p n => by simp [commute_iff_eq, algebraMap_eq, mul_comm]) +noncomputable def rTensorAlgEquiv : S ⊗[R] MvPolynomial σ N ≃ₐ[S] MvPolynomial σ (S ⊗[R] N) := + AddMonoidAlgebra.rTensorEquivAlgEquiv R .. -@[simp] -lemma coeff_rTensorAlgHom_tmul - (p : MvPolynomial σ S) (n : N) (d : σ →₀ ℕ) : - coeff d (rTensorAlgHom (p ⊗ₜ[R] n)) = (coeff d p) ⊗ₜ[R] n := by - rw [rTensorAlgHom, Algebra.TensorProduct.lift_tmul] - rw [AlgHom.coe_comp, IsScalarTower.coe_toAlgHom', Function.comp_apply, - Algebra.TensorProduct.includeRight_apply] - rw [algebraMap_eq, mul_comm, coeff_C_mul] - simp [coeff_map] - -section DecidableEq -variable [DecidableEq σ] - -lemma coeff_rTensorAlgHom_monomial_tmul - (e : σ →₀ ℕ) (s : S) (n : N) (d : σ →₀ ℕ) : - coeff d (rTensorAlgHom (monomial e s ⊗ₜ[R] n)) = - if e = d then s ⊗ₜ[R] n else 0 := by - simp [ite_tmul] - -lemma rTensorAlgHom_toLinearMap : - (rTensorAlgHom : - MvPolynomial σ S ⊗[R] N →ₐ[S] MvPolynomial σ (S ⊗[R] N)).toLinearMap = - rTensor.toLinearMap := by - ext d n e - simp only [coe_comp, Function.comp_apply, AlgebraTensorModule.curry_apply, curry_apply, - LinearMap.coe_restrictScalars, AlgHom.toLinearMap_apply] - rw [coeff_rTensorAlgHom_tmul] - simp only [coeff] - exact (finsuppLeft_apply_tmul_apply _ _ _).symm - -lemma rTensorAlgHom_apply_eq (p : MvPolynomial σ S ⊗[R] N) : - rTensorAlgHom (S := S) p = rTensor p := by - rw [← AlgHom.toLinearMap_apply, rTensorAlgHom_toLinearMap] - rfl - -set_option backward.isDefEq.respectTransparency false in -/-- The tensor product of a polynomial algebra by an algebra - is algebraically equivalent to a polynomial algebra -/ -noncomputable def rTensorAlgEquiv : - (MvPolynomial σ S) ⊗[R] N ≃ₐ[S] MvPolynomial σ (S ⊗[R] N) := by - apply AlgEquiv.ofLinearEquiv rTensor - · simp only [Algebra.TensorProduct.one_def] - apply symm - rw [← LinearEquiv.symm_apply_eq] - exact finsuppLeft_symm_apply_single (R := R) (0 : σ →₀ ℕ) (1 : S) (1 : N) - · intro x y - erw [← rTensorAlgHom_apply_eq (S := S)] - simp only [map_mul, rTensorAlgHom_apply_eq] - rfl +@[deprecated (since := "2026-06-18")] alias rTensorAlgHom := rTensorAlgEquiv @[simp] -lemma rTensorAlgEquiv_apply (x : (MvPolynomial σ S) ⊗[R] N) : - rTensorAlgEquiv x = rTensorAlgHom x := by - rw [← AlgHom.coe_coe] - congr 1 - ext _ d <;> simpa [rTensorAlgEquiv] using! rTensor_apply_tmul_apply _ _ d +lemma coeff_rTensorAlgEquiv_tmul (s : S) (p : MvPolynomial σ N) (d : σ →₀ ℕ) : + coeff d (rTensorAlgEquiv (s ⊗ₜ[R] p)) = s ⊗ₜ[R] coeff d p := by + simp [rTensorAlgEquiv, coeff, MvPolynomial, ← tmul_eq_smul_one_tmul] + +lemma coeff_rTensorAlgEquiv_monomial_tmul [DecidableEq σ] (e : σ →₀ ℕ) (s : S) (n : N) + (d : σ →₀ ℕ) : + coeff d (rTensorAlgEquiv (s ⊗ₜ[R] monomial e n)) = if e = d then s ⊗ₜ[R] n else 0 := by + simp [tmul_ite] + +@[deprecated "Now a syntactic tautology" (since := "2026-06-18")] +lemma rTensorAlgEquiv_apply (x : N ⊗[R] MvPolynomial σ S) : + rTensorAlgEquiv x = rTensorAlgHom x := rfl /-- The tensor product of the polynomial algebra by an algebra is algebraically equivalent to a polynomial algebra with coefficients in that algebra -/ -noncomputable def scalarRTensorAlgEquiv : - MvPolynomial σ R ⊗[R] N ≃ₐ[R] MvPolynomial σ N := - rTensorAlgEquiv.trans (mapAlgEquiv σ (Algebra.TensorProduct.lid R N)) - -end DecidableEq +noncomputable def scalarRTensorAlgEquiv : N ⊗[R] MvPolynomial σ R ≃ₐ[N] MvPolynomial σ N := + AddMonoidAlgebra.scalarTensorEquiv R N variable (R) variable (A : Type*) [CommSemiring A] [Algebra R A] @@ -208,43 +95,30 @@ variable (A : Type*) [CommSemiring A] [Algebra R A] /-- Tensoring `MvPolynomial σ R` on the left by an `R`-algebra `A` is algebraically equivalent to `MvPolynomial σ A`. -/ noncomputable def algebraTensorAlgEquiv : - A ⊗[R] MvPolynomial σ R ≃ₐ[A] MvPolynomial σ A := AlgEquiv.ofAlgHom - (Algebra.TensorProduct.lift - (Algebra.ofId A (MvPolynomial σ A)) - (MvPolynomial.mapAlgHom <| Algebra.ofId R A) (fun _ _ ↦ Commute.all _ _)) - (aeval (fun s ↦ 1 ⊗ₜ X s)) - (by ext s; simp) - (by ext s; simp) + A ⊗[R] MvPolynomial σ R ≃ₐ[A] MvPolynomial σ A := + AddMonoidAlgebra.scalarTensorEquiv .. @[simp] lemma algebraTensorAlgEquiv_tmul (a : A) (p : MvPolynomial σ R) : - algebraTensorAlgEquiv R A (a ⊗ₜ p) = a • MvPolynomial.map (algebraMap R A) p := by - simp [algebraTensorAlgEquiv, Algebra.smul_def] + algebraTensorAlgEquiv R A (a ⊗ₜ p) = a • MvPolynomial.map (algebraMap R A) p := + AddMonoidAlgebra.scalarTensorEquiv_tmul .. @[simp] lemma algebraTensorAlgEquiv_symm_X (s : σ) : - (algebraTensorAlgEquiv R A).symm (X s) = 1 ⊗ₜ X s := by - simp [algebraTensorAlgEquiv] + (algebraTensorAlgEquiv R A).symm (X s) = 1 ⊗ₜ X s := + AddMonoidAlgebra.scalarTensorEquiv_symm_single .. @[simp] lemma algebraTensorAlgEquiv_symm_monomial (m : σ →₀ ℕ) (a : A) : - (algebraTensorAlgEquiv R A).symm (monomial m a) = a ⊗ₜ monomial m 1 := by - apply @Finsupp.induction σ ℕ _ _ m - · simp [algebraTensorAlgEquiv] - · intro i n f _ _ hfa - simp only [algebraTensorAlgEquiv, AlgEquiv.ofAlgHom_symm_apply] at hfa ⊢ - simp only [add_comm, monomial_add_single, map_mul, map_pow, aeval_X, - Algebra.TensorProduct.tmul_pow, one_pow, hfa] - nth_rw 2 [← mul_one a] - rw [Algebra.TensorProduct.tmul_mul_tmul] + (algebraTensorAlgEquiv R A).symm (monomial m a) = a ⊗ₜ monomial m 1 := + AddMonoidAlgebra.scalarTensorEquiv_symm_single .. @[simp] lemma algebraTensorAlgEquiv_symm_comp_aeval : ((algebraTensorAlgEquiv (σ := σ) R A).symm.toAlgHom.restrictScalars R).comp (MvPolynomial.mapAlgHom (R := R) (S₁ := R) (S₂ := A) (Algebra.ofId R A)) = Algebra.TensorProduct.includeRight := by - ext - simp + ext; simp [mapAlgHom, algebraTensorAlgEquiv, X, monomial] @[simp] lemma algebraTensorAlgEquiv_symm_map (x : MvPolynomial σ R) : @@ -272,29 +146,37 @@ variable {R} attribute [local simp] Algebra.smul_def @[simp] lemma tensorEquivSum_X_tmul_one (i) : - tensorEquivSum R σ ι S (.X i ⊗ₜ 1) = .X (.inl i) := by simp [tensorEquivSum] + tensorEquivSum R σ ι S (.X i ⊗ₜ 1) = .X (.inl i) := by + simp [tensorEquivSum, algebraTensorAlgEquiv, sumAlgEquiv, renameEquiv, rename, X, X, C, monomial] @[simp] lemma tensorEquivSum_C_tmul_one (r) : - tensorEquivSum R σ ι S (.C r ⊗ₜ 1) = .C r := by simp [tensorEquivSum] + tensorEquivSum R σ ι S (.C r ⊗ₜ 1) = .C r := by + simp [tensorEquivSum, algebraTensorAlgEquiv, sumAlgEquiv, renameEquiv, rename, C, monomial] @[simp] lemma tensorEquivSum_one_tmul_X (i) : - tensorEquivSum R σ ι S (1 ⊗ₜ .X i) = .X (.inr i) := by simp [tensorEquivSum] + tensorEquivSum R σ ι S (1 ⊗ₜ .X i) = .X (.inr i) := by + simp [tensorEquivSum, algebraTensorAlgEquiv, sumAlgEquiv, renameEquiv, rename, X, C, monomial] @[simp] lemma tensorEquivSum_one_tmul_C (r) : - tensorEquivSum R σ ι S (1 ⊗ₜ .C r) = .C (algebraMap R S r) := by simp [tensorEquivSum] + tensorEquivSum R σ ι S (1 ⊗ₜ .C r) = .C (algebraMap R S r) := by + simp [tensorEquivSum, algebraTensorAlgEquiv, sumAlgEquiv, renameEquiv, rename, C, monomial] @[simp] lemma tensorEquivSum_C_tmul_C (r : R) (s : S) : - tensorEquivSum R σ ι S (.C s ⊗ₜ .C r) = .C (r • s) := by simp [tensorEquivSum, mul_comm (C s)] + tensorEquivSum R σ ι S (.C s ⊗ₜ .C r) = .C (r • s) := by + simp [tensorEquivSum, algebraTensorAlgEquiv, sumAlgEquiv, renameEquiv, rename, C, monomial, + mul_comm] @[simp] lemma tensorEquivSum_X_tmul_X (i j) : - tensorEquivSum R σ ι S (.X i ⊗ₜ .X j) = .X (.inl i) * .X (.inr j) := by simp [tensorEquivSum] + tensorEquivSum R σ ι S (.X i ⊗ₜ .X j) = .X (.inl i) * .X (.inr j) := by + simp [tensorEquivSum, algebraTensorAlgEquiv, sumAlgEquiv, renameEquiv, rename, X, C, monomial, + Finsupp.mapDomain_add, add_comm] section Pushout attribute [local instance] algebraMvPolynomial -instance : Algebra.IsPushout R S (MvPolynomial σ R) (MvPolynomial σ S) where - out := .of_equiv (algebraTensorAlgEquiv R S).toLinearEquiv fun _ ↦ by simp +instance : Algebra.IsPushout R S (MvPolynomial σ R) (MvPolynomial σ S) := + AddMonoidAlgebra.instIsPushout instance : Algebra.IsPushout R (MvPolynomial σ R) S (MvPolynomial σ S) := .symm inferInstance diff --git a/Mathlib/RingTheory/WittVector/StructurePolynomial.lean b/Mathlib/RingTheory/WittVector/StructurePolynomial.lean index c75019e2c4122c..cc98c44df9f9a9 100644 --- a/Mathlib/RingTheory/WittVector/StructurePolynomial.lean +++ b/Mathlib/RingTheory/WittVector/StructurePolynomial.lean @@ -200,7 +200,8 @@ See `wittStructureInt_prop` for this property, and `wittStructureInt_existsUnique` for the fact that `wittStructureInt` gives the unique family of polynomials with this property. -/ noncomputable def wittStructureInt (Φ : MvPolynomial idx ℤ) (n : ℕ) : MvPolynomial (idx × ℕ) ℤ := - Finsupp.mapRange Rat.num (Rat.num_intCast 0) (wittStructureRat p (map (Int.castRingHom ℚ) Φ) n) + .ofCoeff <| .mapRange Rat.num (Rat.num_intCast 0) <| AddMonoidAlgebra.coeff <| + wittStructureRat p (map (Int.castRingHom ℚ) Φ) n variable {p} From 0873fec6bec676ebf3cb917d5009b2ad118fde43 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Sat, 4 Jul 2026 09:57:21 +0000 Subject: [PATCH 0598/1300] doc(CategoryTheory): qualify Pairwise in docstrings (#41333) This PR qualifies references to `CategoryTheory.Pairwise` in the docstrings of `Mathlib/CategoryTheory/Category/Pairwise`. This is needed because otherwise the hyperlink on the website will take you to https://leanprover-community.github.io/mathlib4_docs/Mathlib/Logic/Pairwise.html#Pairwise instead of to https://leanprover-community.github.io/mathlib4_docs/Mathlib/CategoryTheory/Category/Pairwise.html#CategoryTheory.Pairwise. Created with the help of codex. Co-authored-by: Yongxi Lin --- Mathlib/CategoryTheory/Category/Pairwise.lean | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Mathlib/CategoryTheory/Category/Pairwise.lean b/Mathlib/CategoryTheory/Category/Pairwise.lean index d1ca64670bd85a..1ab6028c79746b 100644 --- a/Mathlib/CategoryTheory/Category/Pairwise.lean +++ b/Mathlib/CategoryTheory/Category/Pairwise.lean @@ -16,7 +16,7 @@ public import Mathlib.Data.Fintype.Sum /-! # The category of "pairwise intersections". -Given `ι : Type v`, we build the diagram category `Pairwise ι` +Given `ι : Type v`, we build the diagram category `CategoryTheory.Pairwise ι` with objects `single i` and `pair i j`, for `i j : ι`, whose only non-identity morphisms are `left : pair i j ⟶ single i` and `right : pair i j ⟶ single j`. @@ -24,7 +24,7 @@ whose only non-identity morphisms are We use this later in describing (one formulation of) the sheaf condition. Given any function `U : ι → α`, where `α` is some complete lattice (e.g. `(Opens X)ᵒᵖ`), -we produce a functor `Pairwise ι ⥤ α` in the obvious way, +we produce a functor `CategoryTheory.Pairwise ι ⥤ α` in the obvious way, and show that `iSup U` provides a colimit cocone over this functor. -/ @@ -56,7 +56,7 @@ namespace Pairwise instance pairwiseInhabited [Inhabited ι] : Inhabited (Pairwise ι) := ⟨single default⟩ -/-- Morphisms in the category `Pairwise ι`. The only non-identity morphisms are +/-- Morphisms in the category `CategoryTheory.Pairwise ι`. The only non-identity morphisms are `left i j : single i ⟶ pair i j` and `right i j : single j ⟶ pair i j`. -/ inductive Hom : Pairwise ι → Pairwise ι → Type v @@ -74,13 +74,13 @@ open Hom instance homInhabited [Inhabited ι] : Inhabited (Hom (single (default : ι)) (single default)) := ⟨id_single default⟩ -/-- The identity morphism in `Pairwise ι`. +/-- The identity morphism in `CategoryTheory.Pairwise ι`. -/ def id : ∀ o : Pairwise ι, Hom o o | single i => id_single i | pair i j => id_pair i j -/-- Composition of morphisms in `Pairwise ι`. -/ +/-- Composition of morphisms in `CategoryTheory.Pairwise ι`. -/ def comp : ∀ {o₁ o₂ o₃ : Pairwise ι} (_ : Hom o₁ o₂) (_ : Hom o₂ o₃), Hom o₁ o₃ | _, _, _, id_single _, g => g | _, _, _, id_pair _ _, g => g @@ -95,7 +95,7 @@ instance : CategoryStruct (Pairwise ι) where section open Lean Elab Tactic in -/-- A helper tactic for `cat_disch` and `Pairwise`. -/ +/-- A helper tactic for `cat_disch` and `CategoryTheory.Pairwise`. -/ meta def pairwiseCases : TacticM Unit := do evalTactic (← `(tactic| casesm* (_ : Pairwise _) ⟶ (_ : Pairwise _))) @@ -138,7 +138,8 @@ def diagramMap : ∀ {o₁ o₂ : Pairwise ι} (_ : o₁ ⟶ o₂), diagramObj U | _, _, left _ _ => homOfLE inf_le_left | _, _, right _ _ => homOfLE inf_le_right -/-- Given a function `U : ι → α` for `[SemilatticeInf α]`, we obtain a functor `Pairwise ι ⥤ α`, +/-- Given a function `U : ι → α` for `[SemilatticeInf α]`, we obtain a functor +`CategoryTheory.Pairwise ι ⥤ α`, sending `single i` to `U i` and `pair i j` to `U i ⊓ U j`, and the morphisms to the obvious inequalities. -/ From eea4c07fc8d60fb25380451fdfa44f89a86c6ab4 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Sat, 4 Jul 2026 10:25:02 +0000 Subject: [PATCH 0599/1300] perf(Algebra/MonoidAlgebra/Defs): add `AddMonoid` shortcut instance (#41357) This PR adds an `AddMonoid` instance as the common ascestor of the `AddCommMonoid` and `AddCommGroup` instances on `MonoidAlgebra`. This reverts some of the slowdowns introduced by #38714. This is analogous to the performance improvement in #35555. --- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index 7ec4e9de20d3aa..ae0f0ecd99c765 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -173,6 +173,9 @@ instance instUnique [Subsingleton R] : Unique R[M] := fast_instance% coeffEquiv. instance instDecidableEq [DecidableEq R] [DecidableEq M] : DecidableEq R[M] := coeffEquiv.decidableEq +@[to_additive instAddMonoid] +instance instAddMonoid : AddMonoid R[M] := fast_instance% coeffEquiv.addMonoid + @[to_additive instAddCommMonoid] instance instAddCommMonoid : AddCommMonoid R[M] := fast_instance% coeffEquiv.addCommMonoid From faaff5e5590ad6b6878f66d30a33ded94cd97cf6 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Sat, 4 Jul 2026 11:51:29 +0000 Subject: [PATCH 0600/1300] refactor(RingTheory/RamificationInertia/Inertia): swap `inertiaDeg` and `inertiaDeg'` (#41325) This PR swaps `inertiaDeg` and `inertiaDeg'`. Co-authored-by: tb65536 --- .../NumberTheory/NumberField/ClassNumber.lean | 14 +- .../NumberField/Completion/Ramification.lean | 6 +- .../NumberField/Cyclotomic/Galois.lean | 2 +- .../NumberField/Cyclotomic/Ideal.lean | 14 +- .../NumberField/Discriminant/Different.lean | 4 +- .../NumberField/Ideal/KummerDedekind.lean | 6 +- .../RamificationInertia/Basic.lean | 18 +-- .../RamificationInertia/Galois.lean | 18 +-- .../RamificationInertia/HilbertTheory.lean | 6 +- .../RamificationInertia/Inertia.lean | 103 +++++++----- Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 14 +- .../Localization/AtPrime/Extension.lean | 8 +- .../RingTheory/RamificationInertia/Basic.lean | 8 +- .../RamificationInertia/Inertia.lean | 147 +++++++++++------- 14 files changed, 212 insertions(+), 156 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/ClassNumber.lean b/Mathlib/NumberTheory/NumberField/ClassNumber.lean index 1f63affdc3fca9..a289ec697a3450 100644 --- a/Mathlib/NumberTheory/NumberField/ClassNumber.lean +++ b/Mathlib/NumberTheory/NumberField/ClassNumber.lean @@ -143,7 +143,7 @@ The way this theorem should be used is to first compute `⌊(M K)⌋₊` and the to deal with the finite number of primes `p` in the interval. -/ theorem isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_Icc (h : ∀ p ∈ Finset.Icc 1 ⌊(M K)⌋₊, p.Prime → ∀ (P : Ideal (𝓞 K)), - P ∈ primesOver (span {(p : ℤ)}) (𝓞 K) → p ^ P.inertiaDeg' ℤ ≤ ⌊(M K)⌋₊ → + P ∈ primesOver (span {(p : ℤ)}) (𝓞 K) → p ^ P.inertiaDeg ℤ ≤ ⌊(M K)⌋₊ → Submodule.IsPrincipal P) : IsPrincipalIdealRing (𝓞 K) := by refine isPrincipalIdealRing_of_isPrincipal_of_norm_le_of_isPrime <| fun ⟨P, HP⟩ hP hPN ↦ ?_ @@ -157,18 +157,18 @@ theorem isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_I simpa [h, span_singleton_neg p, ← submodule_span_eq, ← hp] using over_under P have hspan : span {↑p.natAbs} = span {p} := by rcases abs_choice p with h | h <;> simp [h] - have hple : p.natAbs ^ P.inertiaDeg' ℤ ≤ ⌊(M K)⌋₊ := by + have hple : p.natAbs ^ P.inertiaDeg ℤ ≤ ⌊(M K)⌋₊ := by refine le_floor ?_ have : P.IsMaximal := hP.isMaximal (by simpa using HP.2) have : (span {p}).IsMaximal := (hpprime (.under ℤ P)).isMaximal_span_singleton - simpa only [hspan, ← cast_pow, ← natAbs_pow_inertiaDeg' p P] using hPN + simpa only [hspan, ← cast_pow, ← natAbs_pow_inertiaDeg p P] using hPN have hpabsprime := Int.prime_iff_natAbs_prime.mp (hpprime (hP.under _)) refine h _ ?_ hpabsprime _ ⟨hP, ?_⟩ hple - · suffices 0 < P.inertiaDeg' ℤ by + · suffices 0 < P.inertiaDeg ℤ by exact Finset.mem_Icc.mpr ⟨hpabsprime.one_le, le_trans (le_pow this) hple⟩ have := (isPrime_of_prime (prime_span_singleton_iff.mpr <| hpprime (hP.under _))).isMaximal <| by simp [((hpprime (hP.under _))).ne_zero] - exact inertiaDeg'_pos .. + exact inertiaDeg_pos .. · exact hspan ▸ hlies /-- Let `K` be a number field such that `K/ℚ` is Galois and let `M K` be the Minkowski bound of `K`. @@ -183,7 +183,7 @@ to deal with the finite number of primes `p` in the interval. -/ theorem isPrincipalIdealRing_of_isPrincipal_of_lt_or_isPrincipal_of_mem_primesOver_of_mem_Icc [IsGalois ℚ K] (h : ∀ p ∈ Finset.Icc 1 ⌊(M K)⌋₊, p.Prime → ∃ P ∈ primesOver (span {(p : ℤ)}) (𝓞 K), - ⌊(M K)⌋₊ < p ^ P.inertiaDeg' ℤ ∨ + ⌊(M K)⌋₊ < p ^ P.inertiaDeg ℤ ∨ Submodule.IsPrincipal P) : IsPrincipalIdealRing (𝓞 K) := by refine isPrincipalIdealRing_of_isPrincipal_of_pow_le_of_mem_primesOver_of_mem_Icc @@ -191,7 +191,7 @@ theorem isPrincipalIdealRing_of_isPrincipal_of_lt_or_isPrincipal_of_mem_primesOv obtain ⟨Q, ⟨hQ1, hQ2⟩, H⟩ := h p hpmem hp have := (isPrime_of_prime (prime_span_singleton_iff.mpr (prime_iff_prime_int.mp hp))).isMaximal (by simp [hp.ne_zero]) - by_cases h : ⌊(M K)⌋₊ < p ^ P.inertiaDeg' ℤ + by_cases h : ⌊(M K)⌋₊ < p ^ P.inertiaDeg ℤ · linarith rw [inertiaDeg_eq_of_isGaloisGroup (span {↑p}) Q P (K ≃ₐ[ℚ] K)] at H obtain ⟨σ, rfl⟩ := exists_smul_eq_of_isGaloisGroup (span ({↑p} : Set ℤ)) Q P (K ≃ₐ[ℚ] K) diff --git a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean index 1e00c9583a5808..e2b367b8760508 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean @@ -86,15 +86,15 @@ variable (w) open scoped Classical in /-- The inertia degree of `w` over `v`. -/ protected noncomputable def inertiaDeg : ℕ := - if _ : w.1.LiesOver v.1 then (⊥ : Ideal w.Completion).inertiaDeg' v.Completion else 0 + if _ : w.1.LiesOver v.1 then (⊥ : Ideal w.Completion).inertiaDeg v.Completion else 0 theorem inertiaDeg_of_liesOver [w.1.LiesOver v.1] : - v.inertiaDeg w = (⊥ : Ideal w.Completion).inertiaDeg' v.Completion := by + v.inertiaDeg w = (⊥ : Ideal w.Completion).inertiaDeg v.Completion := by simp only [InfinitePlace.inertiaDeg, dif_pos] theorem inertiaDeg_eq_finrank [w.1.LiesOver v.1] : v.inertiaDeg w = Module.finrank v.Completion w.Completion := by - rw [inertiaDeg_of_liesOver, Ideal.inertiaDeg'_eq_of_isMaximal ⊥] + rw [inertiaDeg_of_liesOver, Ideal.inertiaDeg_eq_of_isMaximal ⊥] exact Algebra.finrank_eq_of_equiv_equiv (RingEquiv.quotientBot v.Completion) (RingEquiv.quotientBot w.Completion) (by ext; simp [RingHom.algebraMap_toAlgebra]) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean index 6e5aec0b04a07a..233795e5acce92 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Galois.lean @@ -122,7 +122,7 @@ theorem mem_zpowers_galEquivZMod_of_mem_stabilizer {σ : Gal(K/ℚ)} (hσ : σ have h₀ : IsPrimitiveRoot (Ideal.Quotient.mk P hζ.toInteger) n := by refine hζ.toInteger_isPrimitiveRoot.idealQuotient_mk (by simpa using IsMaximal.ne_top inferInstance) ?_ - rw [← pow_inertiaDeg' p] + rw [← pow_inertiaDeg p] exact Nat.Coprime.pow_left _ hn have h₁ := IsFractionRing.stabilizerHom_apply_apply_mk Gal(K/ℚ) (Ideal.span {(p : ℤ)}) P (ℤ ⧸ span {(p : ℤ)}) (𝓞 K ⧸ P) ⟨σ, hσ⟩ hζ.toInteger diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 1858926305d56b..d0cfae01b281aa 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -97,9 +97,9 @@ instance liesOver_span_zeta_sub_one : (span {hζ.toInteger - 1}).LiesOver 𝒑 : rw [span_singleton_le_iff_mem, mem_comap, algebraMap_int_eq, map_natCast] exact p_mem_span_zeta_sub_one p k hζ -theorem inertiaDeg_span_zeta_sub_one : inertiaDeg' (span {hζ.toInteger - 1}) ℤ = 1 := by +theorem inertiaDeg_span_zeta_sub_one : inertiaDeg (span {hζ.toInteger - 1}) ℤ = 1 := by have : IsMaximal (span {hζ.toInteger - 1}) := .of_liesOver_isMaximal _ 𝒑 - rw [← Nat.pow_right_inj hp.out.one_lt, pow_one, pow_inertiaDeg', + rw [← Nat.pow_right_inj hp.out.one_lt, pow_one, pow_inertiaDeg, absNorm_span_zeta_sub_one] attribute [local instance] FractionRing.liftAlgebra in @@ -156,7 +156,7 @@ theorem eq_span_zeta_sub_one_of_liesOver (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime include hK in theorem inertiaDeg_eq_of_prime_pow (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - inertiaDeg' P ℤ = 1 := by + inertiaDeg P ℤ = 1 := by rw [eq_span_zeta_sub_one_of_liesOver p k K hK.zeta_spec P, inertiaDeg_span_zeta_sub_one] include hK in @@ -228,7 +228,7 @@ theorem isCoprime_of_not_zeta_sub_one_dvd {x : 𝓞 K} (hx : ¬ hζ.toInteger - (prime_span_singleton_iff.mpr hζ.zeta_sub_one_prime').irreducible.gcd_eq_one_iff, dvd_span_singleton, mem_span_singleton] -theorem inertiaDeg_span_zeta_sub_one' : inertiaDeg' (span {hζ.toInteger - 1}) ℤ = 1 := by +theorem inertiaDeg_span_zeta_sub_one' : inertiaDeg (span {hζ.toInteger - 1}) ℤ = 1 := by rw [← pow_one p] at hK hζ exact inertiaDeg_span_zeta_sub_one p 0 hζ @@ -259,7 +259,7 @@ theorem eq_span_zeta_sub_one_of_liesOver' (P : Ideal (𝓞 K)) [hP₁ : P.IsPrim include hK in theorem inertiaDeg_eq_of_prime (P : Ideal (𝓞 K)) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver 𝒑] : - inertiaDeg' P ℤ = 1 := by + inertiaDeg P ℤ = 1 := by rw [eq_span_zeta_sub_one_of_liesOver' p K hK.zeta_spec P, inertiaDeg_span_zeta_sub_one'] include hK in @@ -291,7 +291,7 @@ open NumberField.Ideal Polynomial variable {m} [NeZero m] [hK : IsCyclotomicExtension {m} ℚ K] theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : - inertiaDeg' P ℤ = orderOf (p : ZMod m) := by + inertiaDeg P ℤ = orderOf (p : ZMod m) := by replace hm : p.Coprime m := hp.out.coprime_iff_not_dvd.mpr hm let ζ := (zeta_spec m ℚ K).toInteger have h₁ : ¬ p ∣ exponent ζ := by @@ -427,7 +427,7 @@ theorem ramificationIdxIn_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : (inertiaDegIn_ramificationIdxIn_aux n K hn hm).2 theorem inertiaDeg_eq (hn : n = p ^ (k + 1) * m) (hm : ¬ p ∣ m) : - inertiaDeg' P ℤ = orderOf (p : ZMod m) := by + inertiaDeg P ℤ = orderOf (p : ZMod m) := by have : IsGalois ℚ K := isGalois {n} ℚ K rw [← inertiaDegIn_eq_inertiaDeg 𝒑 P Gal(K/ℚ), inertiaDegIn_eq n K hn hm] diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean index ba9f70b1c8c348..a587564c84f2c8 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean @@ -189,9 +189,9 @@ lemma not_dvd_discr_iff_forall_liesOver [IsIntegralClosure 𝒪 ℤ K] {p : ℤ} exact ⟨P, hP, ⟨h₁.symm⟩, h₂⟩ · rintro ⟨P, hP, hP', hP''⟩ have := Ideal.absNorm_dvd_absNorm_of_le (Ideal.dvd_iff_le.mp hP'') - rw [absNorm_differentIdeal K, ← Ideal.natAbs_pow_inertiaDeg' p, + rw [absNorm_differentIdeal K, ← Ideal.natAbs_pow_inertiaDeg p, ← Int.natAbs_pow, Int.natAbs_dvd_natAbs] at this - exact (dvd_pow_self _ (Ideal.inertiaDeg'_pos ..).ne').trans this + exact (dvd_pow_self _ (Ideal.inertiaDeg_pos ..).ne').trans this /-- A prime `p` does not divide `discr K` if and only if `p` (as the ideal `span {p}`) is unramified in the ring of integers `𝒪`. diff --git a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean index d53e1be80c7114..201f7b98bb32dc 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean @@ -209,7 +209,7 @@ The residual degree of the ideal corresponding to the class of `Q ∈ ℤ[X]` mo -/ theorem inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ exponent θ) {Q : ℤ[X]} (hQ : Q.map (Int.castRingHom (ZMod p)) ∈ monicFactorsMod θ p) : - inertiaDeg' ((primesOverSpanEquivMonicFactorsMod hp).symm + inertiaDeg ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q.map (Int.castRingHom (ZMod p)), hQ⟩ : Ideal (𝓞 K)) ℤ = natDegree (Q.map (Int.castRingHom (ZMod p))) := by -- This is needed for `inertiaDeg_algebraMap` below to work @@ -218,14 +218,14 @@ theorem inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ apply Ideal.primesOver.isMaximal have := liesOver_primesOverSpanEquivMonicFactorsMod_symm hp hQ rw [primesOverSpanEquivMonicFactorsMod_symm_apply_eq_span, - inertiaDeg'_eq_of_isMaximal (span {(p : ℤ)}), + inertiaDeg_eq_of_isMaximal (span {(p : ℤ)}), ← finrank_quotient_span_eq_natDegree] refine Algebra.finrank_eq_of_equiv_equiv (Int.quotientSpanNatEquivZMod p) ?_ (by ext; simp) exact (ZModXQuotSpanEquivQuotSpanPair hp hQ).symm theorem inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply' (hp : ¬ p ∣ exponent θ) {Q : (ZMod p)[X]} (hQ : Q ∈ monicFactorsMod θ p) : - inertiaDeg' + inertiaDeg ((primesOverSpanEquivMonicFactorsMod hp).symm ⟨Q, hQ⟩ : Ideal (𝓞 K)) ℤ = natDegree Q := by obtain ⟨S, rfl⟩ := (map_surjective _ (ZMod.ringHom_surjective (Int.castRingHom (ZMod p)))) Q rw [inertiaDeg_primesOverSpanEquivMonicFactorsMod_symm_apply] diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 3ff906756fa8ad..18009f800fe663 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -527,8 +527,8 @@ open scoped Classical in theorem Factors.finrank_pow_ramificationIdx [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : finrank (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) = - ramificationIdx' p P.1 * inertiaDeg p (P : Ideal S) := by - rw [finrank_prime_pow_ramificationIdx, inertiaDeg_algebraMap] + ramificationIdx' p P.1 * inertiaDeg' p (P : Ideal S) := by + rw [finrank_prime_pow_ramificationIdx, inertiaDeg'_algebraMap] exacts [Factors.ne_bot p P, NeZero.ne _] open scoped Classical in @@ -537,7 +537,7 @@ instance Factors.finiteDimensional_quotient_pow [Module.Finite R S] [p.IsMaximal FiniteDimensional (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) := by refine .of_finrank_pos ?_ rw [pos_iff_ne_zero, Factors.finrank_pow_ramificationIdx] - exact mul_ne_zero (Factors.ramificationIdx_ne_zero p P) (inertiaDeg_pos p P.1).ne' + exact mul_ne_zero (Factors.ramificationIdx_ne_zero p P) (inertiaDeg'_pos p P.1).ne' universe w @@ -595,10 +595,10 @@ here `S` is a finite `R`-module (and thus `Frac(S) : Frac(R)` is a finite extens is maximal. -/ theorem sum_ramification_inertia {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : ∑ P ∈ IsDedekindDomain.primesOverFinset p S, - ramificationIdx' p P * inertiaDeg p P = finrank K L := by + ramificationIdx' p P * inertiaDeg' p P = finrank K L := by set e := ramificationIdx' p (S := S) calc - ∑ P ∈ (factors (map (algebraMap R S) p)).toFinset, e P * inertiaDeg p P = + ∑ P ∈ (factors (map (algebraMap R S) p)).toFinset, e P * inertiaDeg' p P = ∑ P ∈ (factors (map (algebraMap R S) p)).toFinset.attach, finrank (R ⧸ p) (S ⧸ (P : Ideal S) ^ e P) := ?_ _ = finrank (R ⧸ p) @@ -616,7 +616,7 @@ theorem sum_ramification_inertia {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : theorem inertiaDeg_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (P : Ideal S) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver p] (hp0 : p ≠ ⊥) : - p.inertiaDeg P ≤ Module.finrank K L := by + p.inertiaDeg' P ≤ Module.finrank K L := by classical have hP : P ∈ IsDedekindDomain.primesOverFinset p S := (IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mpr ⟨hP₁, hP₂⟩ @@ -634,7 +634,7 @@ theorem ramificationIdx_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsM (IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mpr ⟨hP₁, hP₂⟩ rw [← sum_ramification_inertia S K L hp0, ← Finset.add_sum_erase _ _ hP] refine le_trans (Nat.le_mul_of_pos_right _ ?_) (Nat.le_add_right _ _) - exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg_ne_zero p P + exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg'_ne_zero p P theorem card_primesOverFinset_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : Finset.card (IsDedekindDomain.primesOverFinset p S) ≤ Module.finrank K L := by @@ -644,13 +644,13 @@ theorem card_primesOverFinset_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} have : P.LiesOver p := ((IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mp hP).2 refine Right.one_le_mul ?_ ?_ · exact Nat.pos_iff_ne_zero.mpr <| IsDedekindDomain.ramificationIdx'_ne_zero_of_liesOver _ hp0 - · exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg_ne_zero p P + · exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg'_ne_zero p P /-- `Ideal.sum_ramification_inertia`, in the local (DVR) case. -/ lemma ramificationIdx_mul_inertiaDeg_of_isLocalRing [IsLocalRing S] {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : ramificationIdx' p (IsLocalRing.maximalIdeal S) * - p.inertiaDeg (IsLocalRing.maximalIdeal S) = Module.finrank K L := by + p.inertiaDeg' (IsLocalRing.maximalIdeal S) = Module.finrank K L := by have := FaithfulSMul.of_field_isFractionRing R S K L simp_rw [← sum_ramification_inertia S K L hp0, IsLocalRing.primesOverFinset_eq S hp0, Finset.sum_singleton] diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index d4ce38c6669b64..61c426e3bcf99d 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -67,7 +67,7 @@ open scoped Classical in maximal ideal `p` of `A` are the same, which we define as `Ideal.inertiaDegIn`. -/ noncomputable def inertiaDegIn {A : Type*} [CommRing A] (p : Ideal A) (B : Type*) [CommRing B] [Algebra A B] : ℕ := - if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then h.choose.inertiaDeg' A else 0 + if h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p then h.choose.inertiaDeg A else 0 section MulAction @@ -145,9 +145,9 @@ theorem ramificationIdx_eq_of_isGaloisGroup : include p G in /-- All the `Ideal.inertiaDeg` over a fixed maximal ideal are the same. -/ theorem inertiaDeg_eq_of_isGaloisGroup : - P.inertiaDeg' A = Q.inertiaDeg' A := by + P.inertiaDeg A = Q.inertiaDeg A := by rcases exists_smul_eq_of_isGaloisGroup p P Q G with ⟨σ, rfl⟩ - rw [inertiaDeg'_smul] + rw [inertiaDeg_smul] include p G in /-- The `ramificationIdxIn` is equal to any ramification index over the same ideal. -/ @@ -168,7 +168,7 @@ theorem ramificationIdxIn_ne_zero [Module.Finite A B] [FaithfulSMul A B] {p : Id include G in /-- The `inertiaDegIn` is equal to any ramification index over the same ideal. -/ theorem inertiaDegIn_eq_inertiaDeg : - inertiaDegIn p B = P.inertiaDeg' A := by + inertiaDegIn p B = P.inertiaDeg A := by have h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p := ⟨P, hPp, hp⟩ obtain ⟨_, _⟩ := h.choose_spec rw [inertiaDegIn, dif_pos h] @@ -179,7 +179,7 @@ theorem inertiaDegIn_ne_zero [Module.Finite A B] [FaithfulSMul A B] {p : Ideal A inertiaDegIn p B ≠ 0 := by obtain ⟨P⟩ := (inferInstance : Nonempty (primesOver p B)) rw [inertiaDegIn_eq_inertiaDeg p P G] - exact (P.1.inertiaDeg'_pos A).ne' + exact (P.1.inertiaDeg_pos A).ne' section tower @@ -194,7 +194,7 @@ theorem inertiaDegIn_mul_inertiaDegIn : obtain ⟨⟨Q, _, _⟩⟩ := (inferInstance : Nonempty (primesOver P C)) have : Q.LiesOver p := LiesOver.trans Q P p rw [inertiaDegIn_eq_inertiaDeg p P G, inertiaDegIn_eq_inertiaDeg p Q GAC, - inertiaDegIn_eq_inertiaDeg P Q GBC, ← inertiaDeg'_tower P Q] + inertiaDegIn_eq_inertiaDeg P Q GBC, ← inertiaDeg_tower P Q] variable {p} in include G GAC GBC in @@ -286,7 +286,7 @@ open Algebra attribute [local instance] Ideal.Quotient.field in theorem card_stabilizer_eq_card_inertia_mul_finrank (p : Ideal R) [p.IsPrime] (P : Ideal S) [P.LiesOver p] [P.IsPrime] [PerfectField p.ResidueField] : - Nat.card (MulAction.stabilizer G P) = Nat.card (inertia G P) * P.inertiaDeg' R := by + Nat.card (MulAction.stabilizer G P) = Nat.card (inertia G P) * P.inertiaDeg R := by let := Localization.AtPrime.algebraOfLiesOver p P have heq : (algebraMap (S ⧸ P) P.ResidueField).comp (algebraMap (R ⧸ p) (S ⧸ P)) = (algebraMap p.ResidueField P.ResidueField).comp (algebraMap (R ⧸ p) p.ResidueField) := by @@ -301,14 +301,14 @@ theorem card_stabilizer_eq_card_inertia_mul_finrank (p : Ideal R) [p.IsPrime] Ideal.IsFractionRing.finite_of_isInvariant G p P p.ResidueField P.ResidueField have : Subgroup.index _ = _ := Nat.card_congr (IsFractionRing.stabilizerQuotientInertiaEquiv G p P p.ResidueField P.ResidueField).toEquiv - rw [inertiaDeg'_eq p P, ← IsGalois.card_aut_eq_finrank p.ResidueField P.ResidueField, ← this, + rw [inertiaDeg_eq p P, ← IsGalois.card_aut_eq_finrank p.ResidueField P.ResidueField, ← this, ← ((inertia G P).subgroupOf (MulAction.stabilizer G P)).card_mul_index, Nat.card_congr (Subgroup.subgroupOfEquivOfLe (inertia_le_stabilizer (M := G) P)).toEquiv, AddSubgroup.subgroupOf_inertia] lemma ncard_primesOver_mul_card_inertia_mul_finrank (p : Ideal R) [p.IsPrime] (P : Ideal S) [P.LiesOver p] [P.IsPrime] [PerfectField p.ResidueField] : - (p.primesOver S).ncard * Nat.card (P.inertia G) * P.inertiaDeg' R = Nat.card G := by + (p.primesOver S).ncard * Nat.card (P.inertia G) * P.inertiaDeg R = Nat.card G := by rw [mul_assoc, ← card_stabilizer_eq_card_inertia_mul_finrank p P, ← IsInvariant.orbit_eq_primesOver R S G p P] simpa using Nat.card_congr (MulAction.orbitProdStabilizerEquivGroup G P) diff --git a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean index 75ab4d182a9aad..b0714f550d861a 100644 --- a/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean +++ b/Mathlib/NumberTheory/RamificationInertia/HilbertTheory.lean @@ -296,7 +296,7 @@ private lemma ramificationIdxIn_eq_and_inertiaDegIn_eq (hp : p ≠ ⊥) : exact 𝓟D.ramificationIdx_above_le P · rw [inertiaDegIn_eq_inertiaDeg p P Gal(L/K), inertiaDegIn_eq_inertiaDeg _ P (stabilizer Gal(L/K) P)] - exact inertiaDeg'_above_le 𝓟D P + exact inertiaDeg_above_le 𝓟D P · have := ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn 𝓟D B (stabilizer Gal(L/K) P) rw [primesOver_eq_singleton K L P D 𝓞D, Set.ncard_singleton, one_mul] at this rw [this, IsGaloisGroup.card_eq_finrank (stabilizer Gal(L/K) P) D L, @@ -339,9 +339,9 @@ Let `D` be the decomposition field of `P` in `L/K`. Let `𝓟D` be a prime ideal then the inertia degree of `𝓟D` over `K` is equal to `1`. -/ theorem inertiaDeg_eq (hp : p ≠ ⊥) : - 𝓟D.inertiaDeg' A = 1 := by + 𝓟D.inertiaDeg A = 1 := by obtain ⟨_, _, _, _, _, _⟩ := instances A K L P D 𝓞D 𝓟D hp - have := inertiaDeg'_tower (R := A) 𝓟D P + have := inertiaDeg_tower (R := A) 𝓟D P rwa [← inertiaDegIn_eq_inertiaDeg p P Gal(L/K), ← inertiaDegIn_eq A K L P D 𝓞D 𝓟D hp, ← inertiaDegIn_eq_inertiaDeg 𝓟D P (stabilizer Gal(L/K) P), right_eq_mul₀ <| inertiaDegIn_ne_zero (stabilizer Gal(L/K) P)] at this diff --git a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean index e6224f22f1a457..f6ebed5b24e851 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean @@ -13,7 +13,7 @@ public import Mathlib.RingTheory.Ideal.Norm.AbsNorm Given `P : Ideal S` lying over `p : Ideal R` for the ring extension `f : R →+* S` (assuming `P` and `p` are prime or maximal where needed), -the **inertia degree** `Ideal.inertiaDeg p P` is the degree of the field extension +the **inertia degree** `Ideal.inertiaDeg' p P` is the degree of the field extension `(S / P) : (R / p)`. ## Implementation notes @@ -62,12 +62,12 @@ extension `(S / P) : (R / p)`. We do not assume `P` lies over `p` in the definition; we return `0` instead. -See `inertiaDeg_algebraMap` for the common case where `f = algebraMap R S` +See `inertiaDeg'_algebraMap` for the common case where `f = algebraMap R S` and there is an algebra structure `R / p → S / P`. -Note: This definition of inertia degree will eventually be replaced by `Ideal.inertiaDeg'`. +Note: This definition of inertia degree will eventually be replaced by `Ideal.inertiaDeg`. -/ -noncomputable def inertiaDeg : ℕ := +noncomputable def inertiaDeg' : ℕ := if hPp : comap f P = p then letI : Algebra (R ⧸ p) (S ⧸ P) := Quotient.algebraQuotientOfLEComap hPp.ge finrank (R ⧸ p) (S ⧸ P) @@ -75,91 +75,112 @@ noncomputable def inertiaDeg : ℕ := -- Useful for the `nontriviality` tactic using `comap_eq_of_scalar_tower_quotient`. @[simp] -theorem inertiaDeg_of_subsingleton [hp : p.IsMaximal] [hQ : Subsingleton (S ⧸ P)] : - inertiaDeg p P = 0 := by +theorem inertiaDeg'_of_subsingleton [hp : p.IsMaximal] [hQ : Subsingleton (S ⧸ P)] : + inertiaDeg' p P = 0 := by have := Ideal.Quotient.subsingleton_iff.mp hQ subst this exact dif_neg fun h => hp.ne_top <| h.symm.trans comap_top +@[deprecated (since := "2026-07-03")] alias inertiaDeg_of_subsingleton := + inertiaDeg'_of_subsingleton + @[simp] -theorem inertiaDeg_algebraMap [P.LiesOver p] : - inertiaDeg p P = finrank (R ⧸ p) (S ⧸ P) := by - rw [inertiaDeg, dif_pos (over_def P p).symm] +theorem inertiaDeg'_algebraMap [P.LiesOver p] : + inertiaDeg' p P = finrank (R ⧸ p) (S ⧸ P) := by + rw [inertiaDeg', dif_pos (over_def P p).symm] + +@[deprecated (since := "2026-07-03")] alias inertiaDeg_algebraMap := inertiaDeg'_algebraMap -theorem inertiaDeg_pos [p.IsMaximal] [Module.Finite R S] [P.LiesOver p] : 0 < inertiaDeg p P := +theorem inertiaDeg'_pos [p.IsMaximal] [Module.Finite R S] [P.LiesOver p] : 0 < inertiaDeg' p P := have : Nontrivial (S ⧸ P) := Quotient.nontrivial_of_liesOver_of_isPrime P p - finrank_pos.trans_eq (inertiaDeg_algebraMap p P).symm + finrank_pos.trans_eq (inertiaDeg'_algebraMap p P).symm /-- Variant with a weaker constraint, but on the prime upstairs instead. -/ -theorem inertiaDeg_pos' [P.IsPrime] [Module.Finite R S] [P.LiesOver p] : 0 < inertiaDeg p P := +theorem inertiaDeg'_pos' [P.IsPrime] [Module.Finite R S] [P.LiesOver p] : 0 < inertiaDeg' p P := have : p.IsPrime := Ideal.over_def P p ▸ inferInstance - Module.finrank_pos.trans_eq (inertiaDeg_algebraMap p P).symm + Module.finrank_pos.trans_eq (inertiaDeg'_algebraMap p P).symm + +@[deprecated (since := "2026-07-03")] alias inertiaDeg_pos' := inertiaDeg'_pos' -theorem inertiaDeg_ne_zero [p.IsMaximal] [Module.Finite R S] [P.LiesOver p] : inertiaDeg p P ≠ 0 := - (Nat.ne_of_lt (inertiaDeg_pos p P)).symm +theorem inertiaDeg'_ne_zero [p.IsMaximal] [Module.Finite R S] [P.LiesOver p] : + inertiaDeg' p P ≠ 0 := + (Nat.ne_of_lt (inertiaDeg'_pos p P)).symm -lemma inertiaDeg_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : - inertiaDeg p (P.comap e) = inertiaDeg p P := by +@[deprecated (since := "2026-07-03")] alias inertiaDeg_ne_zero := inertiaDeg'_ne_zero + +lemma inertiaDeg'_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : + inertiaDeg' p (P.comap e) = inertiaDeg' p P := by have he : (P.comap e).comap (algebraMap R S) = p ↔ P.comap (algebraMap R S₁) = p := by rw [← comap_coe e, comap_comap, ← e.toAlgHom_toRingHom, AlgHom.comp_algebraMap] by_cases h : P.LiesOver p - · rw [inertiaDeg_algebraMap, inertiaDeg_algebraMap] + · rw [inertiaDeg'_algebraMap, inertiaDeg'_algebraMap] exact (Quotient.algEquivOfEqComap p e rfl).toLinearEquiv.finrank_eq - · rw [inertiaDeg, dif_neg (fun eq => h ⟨(he.mp eq).symm⟩)] - rw [inertiaDeg, dif_neg (fun eq => h ⟨eq.symm⟩)] + · rw [inertiaDeg', dif_neg (fun eq => h ⟨(he.mp eq).symm⟩)] + rw [inertiaDeg', dif_neg (fun eq => h ⟨eq.symm⟩)] + +@[deprecated (since := "2026-07-03")] alias inertiaDeg_comap_eq := inertiaDeg'_comap_eq -lemma inertiaDeg_map_eq (P : Ideal S) +lemma inertiaDeg'_map_eq (P : Ideal S) {E : Type*} [EquivLike E S S₁] [AlgEquivClass E R S S₁] (e : E) : - inertiaDeg p (P.map e) = inertiaDeg p P := by + inertiaDeg' p (P.map e) = inertiaDeg' p P := by rw [show P.map e = _ from map_comap_of_equiv (RingEquivClass.toRingEquiv e : S ≃+* S₁)] - exact p.inertiaDeg_comap_eq (AlgEquivClass.toAlgEquiv e).symm P + exact p.inertiaDeg'_comap_eq (AlgEquivClass.toAlgEquiv e).symm P -theorem inertiaDeg_bot [Nontrivial R] [IsDomain S] [Algebra.IsIntegral R S] +@[deprecated (since := "2026-07-03")] alias inertiaDeg_map_eq := inertiaDeg'_map_eq + +theorem inertiaDeg'_bot [Nontrivial R] [IsDomain S] [Algebra.IsIntegral R S] [hP : P.LiesOver (⊥ : Ideal R)] : - (⊥ : Ideal R).inertiaDeg P = finrank R S := by - rw [inertiaDeg, dif_pos (over_def P (⊥ : Ideal R)).symm] + (⊥ : Ideal R).inertiaDeg' P = finrank R S := by + rw [inertiaDeg', dif_pos (over_def P (⊥ : Ideal R)).symm] replace hP : P = ⊥ := eq_bot_of_liesOver_bot R P rw [Algebra.finrank_eq_of_equiv_equiv (RingEquiv.quotientBot R).symm ((quotEquivOfEq hP).trans (RingEquiv.quotientBot S)).symm] rfl -theorem inertiaDeg_le_inertiaDeg {T : Type*} [CommRing T] [Algebra R T] [Algebra S T] +@[deprecated (since := "2026-07-03")] alias inertiaDeg_bot := inertiaDeg'_bot + +theorem inertiaDeg'_le_inertiaDeg' {T : Type*} [CommRing T] [Algebra R T] [Algebra S T] [IsScalarTower R S T] [Module.Finite R T] (Q : Ideal T) [P.LiesOver p] [Q.LiesOver P] - [p.IsPrime] : inertiaDeg P Q ≤ inertiaDeg p Q := by + [p.IsPrime] : inertiaDeg' P Q ≤ inertiaDeg' p Q := by have : Q.LiesOver p := LiesOver.trans Q P p - rw [inertiaDeg_algebraMap, inertiaDeg_algebraMap] + rw [inertiaDeg'_algebraMap, inertiaDeg'_algebraMap] have : IsScalarTower (R ⧸ p) (S ⧸ P) (T ⧸ Q) := IsScalarTower.of_algebraMap_eq <| by rintro ⟨x⟩ simp [Submodule.Quotient.quot_mk_eq_mk, IsScalarTower.algebraMap_apply R (S ⧸ P) (T ⧸ Q)] exact finrank_top_le_finrank_of_isScalarTower .. +@[deprecated (since := "2026-07-03")] alias inertiaDeg_le_inertiaDeg := inertiaDeg'_le_inertiaDeg' + end DecEq section absNorm -lemma absNorm_eq_pow_inertiaDeg_of_liesOver {S : Type*} [CommRing S] [IsDedekindDomain S] +lemma absNorm_eq_pow_inertiaDeg'_of_liesOver {S : Type*} [CommRing S] [IsDedekindDomain S] [Module.Free ℤ S] [IsDedekindDomain R] [Module.Free ℤ R] [Algebra S R] [Module.Finite S R] (P : Ideal R) (p : Ideal S) [P.LiesOver p] (hp : p.IsPrime) (hp_ne_bot : p ≠ ⊥) : - absNorm P = absNorm p ^ (p.inertiaDeg P) := by + absNorm P = absNorm p ^ (p.inertiaDeg' P) := by have : p.IsMaximal := hp.isMaximal hp_ne_bot let _ : Field (S ⧸ p) := Quotient.field p simpa [absNorm_apply, Submodule.cardQuot_apply] using Module.natCard_eq_pow_finrank (K := S ⧸ p) +@[deprecated (since := "2026-07-03")] alias absNorm_eq_pow_inertiaDeg_of_liesOver := + absNorm_eq_pow_inertiaDeg'_of_liesOver + /-- The absolute norm of an ideal `P` above a rational prime `p` is -`|p| ^ ((span {p}).inertiaDeg P)`. +`|p| ^ ((span {p}).inertiaDeg' P)`. See `absNorm_eq_pow_inertiaDeg'` for a version with `p` of type `ℕ`. -/ lemma absNorm_eq_pow_inertiaDeg [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] {p : ℤ} (P : Ideal R) [P.LiesOver (span {p})] (hp : Prime p) : - absNorm P = p.natAbs ^ ((span {p}).inertiaDeg P) := by - simpa using absNorm_eq_pow_inertiaDeg_of_liesOver P (span {p}) + absNorm P = p.natAbs ^ ((span {p}).inertiaDeg' P) := by + simpa using absNorm_eq_pow_inertiaDeg'_of_liesOver P (span {p}) (by rwa [span_singleton_prime hp.ne_zero]) (by simpa using hp.ne_zero) /-- The absolute norm of an ideal `P` above a rational (positive) prime `p` is -`p ^ ((span {p}).inertiaDeg P)`. +`p ^ ((span {p}).inertiaDeg' P)`. See `absNorm_eq_pow_inertiaDeg` for a version with `p` of type `ℤ`. -/ lemma absNorm_eq_pow_inertiaDeg' [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] {p : ℕ} (P : Ideal R) [P.LiesOver (span {(p : ℤ)})] (hp : p.Prime) : - absNorm P = p ^ ((span {(p : ℤ)}).inertiaDeg P) := + absNorm P = p ^ ((span {(p : ℤ)}).inertiaDeg' P) := absNorm_eq_pow_inertiaDeg P (Nat.prime_iff_prime_int.mp hp) end absNorm @@ -172,13 +193,13 @@ variable [Algebra R S] [Algebra S T] [Algebra R T] [IsScalarTower R S T] /-- Let `T / S / R` be a tower of algebras, `p, P, I` be ideals in `R, S, T`, respectively, and `p` and `P` are maximal. If `p = P ∩ S` and `P = I ∩ S`, then `f (I | p) = f (P | p) * f (I | P)`. -/ -theorem inertiaDeg_algebra_tower (p : Ideal R) (P : Ideal S) (I : Ideal T) [p.IsMaximal] - [P.IsMaximal] [P.LiesOver p] [I.LiesOver P] : inertiaDeg p I = - inertiaDeg p P * inertiaDeg P I := by +theorem inertiaDeg'_algebra_tower (p : Ideal R) (P : Ideal S) (I : Ideal T) [p.IsMaximal] + [P.IsMaximal] [P.LiesOver p] [I.LiesOver P] : inertiaDeg' p I = + inertiaDeg' p P * inertiaDeg' P I := by have h₁ := P.over_def p have h₂ := I.over_def P have h₃ := (LiesOver.trans I P p).over - simp only [inertiaDeg, dif_pos h₁.symm, dif_pos h₂.symm, dif_pos h₃.symm] + simp only [inertiaDeg', dif_pos h₁.symm, dif_pos h₂.symm, dif_pos h₃.symm] letI : Algebra (R ⧸ p) (S ⧸ P) := Ideal.Quotient.algebraQuotientOfLEComap h₁.le letI : Algebra (S ⧸ P) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₂.le letI : Algebra (R ⧸ p) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₃.le @@ -186,6 +207,8 @@ theorem inertiaDeg_algebra_tower (p : Ideal R) (P : Ideal S) (I : Ideal T) [p.Is rintro ⟨x⟩; exact congr_arg _ (IsScalarTower.algebraMap_apply R S T x) exact (finrank_mul_finrank (R ⧸ p) (S ⧸ P) (T ⧸ I)).symm +@[deprecated (since := "2026-07-03")] alias inertiaDeg_algebra_tower := inertiaDeg'_algebra_tower + end tower end Ideal diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index e55fb5aae24973..829c6ed62493a2 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -398,20 +398,20 @@ See `Ideal.relNorm_eq_pow_of_isMaximal` for a statement that does not require th be Galois. -/ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] - [IsGalois (FractionRing R) (FractionRing S)] : relNorm R P = p ^ P.inertiaDeg' R := by + [IsGalois (FractionRing R) (FractionRing S)] : relNorm R P = p ^ P.inertiaDeg R := by have : P.IsMaximal := IsMaximal.of_liesOver_isMaximal P p let G := Gal(FractionRing S/FractionRing R) let := IsIntegralClosure.MulSemiringAction R (FractionRing R) (FractionRing S) S have := IsGaloisGroup.of_isFractionRing G R S (FractionRing R) (FractionRing S) by_cases hp : p = ⊥ - · have h : P.inertiaDeg' R ≠ 0 := (inertiaDeg'_pos P R).ne' + · have h : P.inertiaDeg R ≠ 0 := (inertiaDeg_pos P R).ne' have hP : P = ⊥ := by rw [hp] at hPp exact eq_bot_of_liesOver_bot R P rw [hp, hP, relNorm_bot, bot_pow] rwa [hP] at h obtain ⟨s, hs⟩ := exists_relNorm_eq_pow_of_isPrime P p - suffices s = P.inertiaDeg' R by rwa [this] at hs + suffices s = P.inertiaDeg R by rwa [this] at hs have h₀ : ∀ Q ∈ (p.primesOver S).toFinset, relNorm R Q ^ Q.ramificationIdx R = p ^ ((p.ramificationIdxIn S) * s) := by intro Q hQ @@ -434,7 +434,7 @@ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] exact IsMaximal.ne_top inferInstance theorem relNorm_eq_pow_of_isMaximal [PerfectField (FractionRing R)] [P.IsMaximal] [p.IsMaximal] : - relNorm R P = p ^ P.inertiaDeg' R := by + relNorm R P = p ^ P.inertiaDeg R := by let T := Ring.NormalClosure R S obtain ⟨Q, hQ₁, hQ₂⟩ : ∃ Q : Ideal T, Q.IsMaximal ∧ Q.LiesOver P := exists_maximal_ideal_liesOver_of_isIntegral P @@ -443,7 +443,7 @@ theorem relNorm_eq_pow_of_isMaximal [PerfectField (FractionRing R)] [P.IsMaximal have : IsGalois (FractionRing S) (FractionRing T) := IsGalois.tower_top_of_isGalois (FractionRing R) (FractionRing S) (FractionRing T) rwa [← relNorm_relNorm R S, relNorm_eq_pow_of_isPrime_isGalois Q P, map_pow, - inertiaDeg'_tower (R := R) P Q, pow_mul, pow_left_inj (inertiaDeg'_pos Q S).ne'] at h + inertiaDeg_tower (R := R) P Q, pow_mul, pow_left_inj (inertiaDeg_pos Q S).ne'] at h end relNorm_prime @@ -469,8 +469,8 @@ theorem absNorm_relNorm [PerfectField (FractionRing R)] (I : Ideal S) : let P := under R Q let p := absNorm (under ℤ P) have : Q.LiesOver (span {(p : ℤ)}) := LiesOver.trans Q P _ - rw [relNorm_eq_pow_of_isMaximal Q P, map_pow, ← pow_inertiaDeg' p, ← pow_inertiaDeg' p, - ← pow_mul, ← inertiaDeg'_tower] + rw [relNorm_eq_pow_of_isMaximal Q P, map_pow, ← pow_inertiaDeg p, ← pow_inertiaDeg p, + ← pow_mul, ← inertiaDeg_tower] theorem relNorm_int (I : Ideal S) : relNorm ℤ I = Ideal.span {(absNorm I : ℤ)} := by diff --git a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean index 7a87b43cdb7204..8a0d964af4889c 100644 --- a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean +++ b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean @@ -168,8 +168,8 @@ theorem equivQuotientMapMaximalIdeal_apply_mk [p.IsMaximal] (x : S) : theorem inertiaDeg_map_eq_inertiaDeg [p.IsMaximal] [P.IsMaximal] [(Ideal.map (algebraMap S Sₚ) P).LiesOver (maximalIdeal Rₚ)] : - (maximalIdeal Rₚ).inertiaDeg (P.map (algebraMap S Sₚ)) = p.inertiaDeg P := by - rw [inertiaDeg_algebraMap, inertiaDeg_algebraMap] + (maximalIdeal Rₚ).inertiaDeg' (P.map (algebraMap S Sₚ)) = p.inertiaDeg' P := by + rw [inertiaDeg'_algebraMap, inertiaDeg'_algebraMap] refine Algebra.finrank_eq_of_equiv_equiv (equivQuotMaximalIdeal p Rₚ).symm (equivQuotientMapOfIsMaximal p Sₚ P).symm ?_ ext x @@ -238,8 +238,8 @@ theorem primesOverEquivPrimesOver_symm_apply (hp : p ≠ ⊥) (Q : (maximalIdeal ((primesOverEquivPrimesOver p Rₚ Sₚ hp).symm Q).1 = Ideal.comap (algebraMap S Sₚ) Q := rfl theorem primesOverEquivPrimesOver_inertiagDeg_eq [p.IsMaximal] (hp : p ≠ ⊥) (P : p.primesOver S) : - (maximalIdeal Rₚ).inertiaDeg (primesOverEquivPrimesOver p Rₚ Sₚ hp P : Ideal Sₚ) = - p.inertiaDeg P.val := by + (maximalIdeal Rₚ).inertiaDeg' (primesOverEquivPrimesOver p Rₚ Sₚ hp P : Ideal Sₚ) = + p.inertiaDeg' P.val := by have : NeZero p := ⟨hp⟩ have : P.val.IsMaximal := Ring.DimensionLEOne.maximalOfPrime (ne_bot_of_mem_primesOver (NeZero.ne _) P.prop) inferInstance diff --git a/Mathlib/RingTheory/RamificationInertia/Basic.lean b/Mathlib/RingTheory/RamificationInertia/Basic.lean index 1ff5e1a804766a..27525fcd1292ba 100644 --- a/Mathlib/RingTheory/RamificationInertia/Basic.lean +++ b/Mathlib/RingTheory/RamificationInertia/Basic.lean @@ -43,7 +43,7 @@ variable {R : Type*} [CommRing R] (p : Ideal R) [p.IsPrime] (S : Type*) [CommRin open IsLocalRing Module OrderIso PrimeSpectrum in theorem sum_ramification_inertia_eq_finrank_fiber [Algebra.QuasiFinite R S] [Fintype (p.primesOver S)] : - ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg' R = + ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg R = finrank p.ResidueField (p.Fiber S) := by let := Fintype.ofFinite (PrimeSpectrum (p.Fiber S)) rw [IsArtinianRing.finrank_eq_sum_primeSpectrum, ← (primesOverOrderIsoFiber R S p).symm.sum_comp] @@ -52,7 +52,7 @@ theorem sum_ramification_inertia_eq_finrank_fiber simp_rw [toEquiv_symm, coe_symm_toEquiv, coe_primesOverOrderIsoFiber_symm_apply] set r := q.1.comap Algebra.TensorProduct.includeRight let := Localization.AtPrime.algebraOfLiesOver p r - rw [ramificationIdx_eq p r, inertiaDeg'_eq p r] + rw [ramificationIdx_eq p r, inertiaDeg_eq p r] let Rp := Localization.AtPrime p let Sq := Localization.AtPrime q.1 let Sr := Localization.AtPrime r @@ -71,7 +71,7 @@ ideal of `R`. Then the sum over all prime ideals `q` of `S` lying over `p` of th index of `q` times the inertia degree of `q` equals the rank of `S` as an `R`-module. -/ theorem sum_ramification_inertia_eq_finrank [IsDomain R] [Module.Finite R S] [Module.Flat R S] [Fintype (p.primesOver S)] : - ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg' R = Module.finrank R S := by + ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg R = Module.finrank R S := by rw [sum_ramification_inertia_eq_finrank_fiber, finrank_fiber_eq_finrank] /-- Let `S/R` be a finite flat extension of integral domains, and let `p` be prime ideal of `R`. @@ -81,7 +81,7 @@ degree of `q` equals the cardinality of `G`. -/ theorem sum_ramification_inertia_eq_card [IsDomain R] [IsDomain S] [Module.Finite R S] [Module.Flat R S] [Fintype (p.primesOver S)] {G : Type*} [Group G] [MulSemiringAction G S] [IsGaloisGroup G R S] : - ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg' R = Nat.card G := by + ∑ q : p.primesOver S, q.1.ramificationIdx R * q.1.inertiaDeg R = Nat.card G := by let := IsGaloisGroup.finite G R S rw [sum_ramification_inertia_eq_finrank, IsGaloisGroup.card_eq_finrank' G R S] diff --git a/Mathlib/RingTheory/RamificationInertia/Inertia.lean b/Mathlib/RingTheory/RamificationInertia/Inertia.lean index f01fb0e111881b..ce251f7057cfe1 100644 --- a/Mathlib/RingTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/RingTheory/RamificationInertia/Inertia.lean @@ -16,13 +16,13 @@ to be the degree of the residue field of `q` over the residue field of its preim ## Main definitions -* `Ideal.inertiaDeg' q R`: The inertia degree of `q` over `R`. +* `Ideal.inertiaDeg q R`: The inertia degree of `q` over `R`. ## Main statements -* `inertiaDeg_eq_inertiaDeg'`: The inertia degree agrees with the usual definition in the case of +* `inertiaDeg'_eq_inertiaDeg`: The inertia degree agrees with the usual definition in the case of maximal ideals. -* `inertiaDeg'_tower`: Inertia degree is multiplicative in towers. +* `inertiaDeg_tower`: Inertia degree is multiplicative in towers. -/ @[expose] public section @@ -39,25 +39,30 @@ to be the degree of the residue field of `q` over the residue field of its preim When `q` is not prime, we use a junk value of `0`. -This will eventually replace the existing definition of `Ideal.inertiaDeg`. -/ -noncomputable def inertiaDeg' : ℕ := +This will eventually replace the existing definition of `Ideal.inertiaDeg'`. -/ +noncomputable def inertiaDeg : ℕ := if _ : q.IsPrime then letI := Localization.AtPrime.algebraOfLiesOver (q.under R) q Module.finrank (q.under R).ResidueField q.ResidueField else 0 -theorem inertiaDeg'_def [hq : q.IsPrime] +theorem inertiaDeg_def [hq : q.IsPrime] [Algebra (Localization.AtPrime (q.under R)) (Localization.AtPrime q)] [Localization.AtPrime.IsLiesOverAlgebra (q.under R) q] : - q.inertiaDeg' R = Module.finrank (q.under R).ResidueField q.ResidueField := by + q.inertiaDeg R = Module.finrank (q.under R).ResidueField q.ResidueField := by convert! dif_pos hq simp [Algebra.algebra_ext_iff, Localization.AtPrime.IsLiesOverAlgebra.algebraMap_eq] -theorem inertiaDeg'_of_not_isPrime (hq : ¬ q.IsPrime) : q.inertiaDeg' R = 0 := +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_def := inertiaDeg_def + +theorem inertiaDeg_of_not_isPrime (hq : ¬ q.IsPrime) : q.inertiaDeg R = 0 := dif_neg hq -theorem inertiaDeg'_pos [hq : q.IsPrime] [Module.Finite R S] : 0 < q.inertiaDeg' R := by +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_of_not_isPrime := + inertiaDeg_of_not_isPrime + +theorem inertiaDeg_pos [hq : q.IsPrime] [Module.Finite R S] : 0 < q.inertiaDeg R := by let := Localization.AtPrime.algebraOfLiesOver (q.under R) q - rw [inertiaDeg'_def] + rw [inertiaDeg_def] apply Module.finrank_pos end @@ -68,15 +73,17 @@ variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] [Algebra S T] [IsScalarTower R S T] (p : Ideal R) (q : Ideal S) (r : Ideal T) -theorem inertiaDeg'_eq [q.LiesOver p] [q.IsPrime] [p.IsPrime] +theorem inertiaDeg_eq [q.LiesOver p] [q.IsPrime] [p.IsPrime] [Algebra (Localization.AtPrime p) (Localization.AtPrime q)] [Localization.AtPrime.IsLiesOverAlgebra p q] : - q.inertiaDeg' R = Module.finrank p.ResidueField q.ResidueField := by + q.inertiaDeg R = Module.finrank p.ResidueField q.ResidueField := by have := Ideal.over_def q p subst this - exact inertiaDeg'_def q R + exact inertiaDeg_def q R -theorem inertiaDeg'_eq_of_isFractionRing [q.LiesOver p] [p.IsPrime] [q.IsPrime] +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_eq := inertiaDeg_eq + +theorem inertiaDeg_eq_of_isFractionRing [q.LiesOver p] [p.IsPrime] [q.IsPrime] (K L : Type*) [Field K] [Field L] [Algebra (R ⧸ p) K] [IsFractionRing (R ⧸ p) K] [Algebra (S ⧸ q) L] [IsFractionRing (S ⧸ q) L] @@ -84,9 +91,9 @@ theorem inertiaDeg'_eq_of_isFractionRing [q.LiesOver p] [p.IsPrime] [q.IsPrime] [Algebra S L] [IsScalarTower S (S ⧸ q) L] [Algebra R L] [IsScalarTower R S L] [Algebra K L] [IsScalarTower R K L] : - q.inertiaDeg' R = Module.finrank K L := by + q.inertiaDeg R = Module.finrank K L := by let := Localization.AtPrime.algebraOfLiesOver p q - rw [inertiaDeg'_eq p q] + rw [inertiaDeg_eq p q] apply Algebra.finrank_eq_of_equiv_equiv (IsFractionRing.algEquivOfAlgEquiv (R := R) (A := R ⧸ p) (K := p.ResidueField) (L := K) .refl) (IsFractionRing.algEquivOfAlgEquiv (R := S) (A := S ⧸ q) (K := q.ResidueField) (L := L) .refl) @@ -97,87 +104,113 @@ theorem inertiaDeg'_eq_of_isFractionRing [q.LiesOver p] [p.IsPrime] [q.IsPrime] IsScalarTower.algebraMap_apply R S q.ResidueField, ← IsScalarTower.algebraMap_apply R K L, ← IsScalarTower.algebraMap_apply R S L] -theorem inertiaDeg'_eq_of_isMaximal [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : - q.inertiaDeg' R = Module.finrank (R ⧸ p) (S ⧸ q) := by +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_eq_of_isFractionRing := +inertiaDeg_eq_of_isFractionRing + +theorem inertiaDeg_eq_of_isMaximal [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : + q.inertiaDeg R = Module.finrank (R ⧸ p) (S ⧸ q) := by let : Field (R ⧸ p) := Quotient.field p let : Field (S ⧸ q) := Quotient.field q - exact inertiaDeg'_eq_of_isFractionRing p q (R ⧸ p) (S ⧸ q) + exact inertiaDeg_eq_of_isFractionRing p q (R ⧸ p) (S ⧸ q) -theorem inertiaDeg_eq_inertiaDeg' [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : - p.inertiaDeg q = q.inertiaDeg' R := by - rw [inertiaDeg_algebraMap, inertiaDeg'_eq_of_isMaximal p q] +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_eq_of_isMaximal := + inertiaDeg_eq_of_isMaximal -theorem inertiaDeg'_tower [r.LiesOver q] : - r.inertiaDeg' R = q.inertiaDeg' R * r.inertiaDeg' S := by +theorem inertiaDeg'_eq_inertiaDeg [q.LiesOver p] [p.IsMaximal] [q.IsMaximal] : + p.inertiaDeg' q = q.inertiaDeg R := by + rw [inertiaDeg'_algebraMap, inertiaDeg_eq_of_isMaximal p q] + +@[deprecated (since := "2026-07-03")] alias inertiaDeg_eq_inertiaDeg' := inertiaDeg'_eq_inertiaDeg + +theorem inertiaDeg_tower [r.LiesOver q] : + r.inertiaDeg R = q.inertiaDeg R * r.inertiaDeg S := by by_cases hr : r.IsPrime · have : q.IsPrime := isPrime_of_liesOver r q have : q.LiesOver (r.under R) := LiesOver.tower_bot r q (r.under R) let := Localization.AtPrime.algebraOfLiesOver (r.under R) r let := Localization.AtPrime.algebraOfLiesOver (r.under R) q let := Localization.AtPrime.algebraOfLiesOver q r - rw [inertiaDeg'_def, inertiaDeg'_eq (r.under R), inertiaDeg'_eq q, eq_comm] + rw [inertiaDeg_def, inertiaDeg_eq (r.under R), inertiaDeg_eq q, eq_comm] apply Module.finrank_mul_finrank - · rw [inertiaDeg'_of_not_isPrime r R hr, inertiaDeg'_of_not_isPrime r S hr, mul_zero] + · rw [inertiaDeg_of_not_isPrime r R hr, inertiaDeg_of_not_isPrime r S hr, mul_zero] + +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_tower := inertiaDeg_tower + +theorem inertiaDeg_below_dvd [r.LiesOver q] : + q.inertiaDeg R ∣ r.inertiaDeg R := by + use r.inertiaDeg S + rw [← inertiaDeg_tower] -theorem inertiaDeg'_below_dvd [r.LiesOver q] : - q.inertiaDeg' R ∣ r.inertiaDeg' R := by - use r.inertiaDeg' S - rw [← inertiaDeg'_tower] +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_below_dvd := inertiaDeg_below_dvd -theorem inertiaDeg'_above_dvd [r.LiesOver q] : - r.inertiaDeg' S ∣ r.inertiaDeg' R := by - use q.inertiaDeg' R - rw [mul_comm, ← inertiaDeg'_tower] +theorem inertiaDeg_above_dvd [r.LiesOver q] : + r.inertiaDeg S ∣ r.inertiaDeg R := by + use q.inertiaDeg R + rw [mul_comm, ← inertiaDeg_tower] -theorem inertiaDeg'_below_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] : - q.inertiaDeg' R ≤ r.inertiaDeg' R := - Nat.le_of_dvd (r.inertiaDeg'_pos R) (q.inertiaDeg'_below_dvd r) +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_above_dvd := inertiaDeg_above_dvd -theorem inertiaDeg'_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] : - r.inertiaDeg' S ≤ r.inertiaDeg' R := - Nat.le_of_dvd (r.inertiaDeg'_pos R) (q.inertiaDeg'_above_dvd r) +theorem inertiaDeg_below_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] : + q.inertiaDeg R ≤ r.inertiaDeg R := + Nat.le_of_dvd (r.inertiaDeg_pos R) (q.inertiaDeg_below_dvd r) + +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_below_le := inertiaDeg_below_le + +theorem inertiaDeg_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] : + r.inertiaDeg S ≤ r.inertiaDeg R := + Nat.le_of_dvd (r.inertiaDeg_pos R) (q.inertiaDeg_above_dvd r) + +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_above_le := inertiaDeg_above_le variable (R) in open Pointwise in @[simp] -theorem inertiaDeg'_smul {G : Type*} [Group G] [MulSemiringAction G S] [SMulCommClass G R S] - (g : G) : (g • q).inertiaDeg' R = q.inertiaDeg' R := by +theorem inertiaDeg_smul {G : Type*} [Group G] [MulSemiringAction G S] [SMulCommClass G R S] + (g : G) : (g • q).inertiaDeg R = q.inertiaDeg R := by by_cases hq : q.IsPrime; swap - · rw [inertiaDeg'_of_not_isPrime, inertiaDeg'_of_not_isPrime] <;> simpa + · rw [inertiaDeg_of_not_isPrime, inertiaDeg_of_not_isPrime] <;> simpa · let p := q.under R let f₀ := MulSemiringAction.toAlgAut G R S g let := Localization.AtPrime.algebraOfLiesOver p q let := Localization.AtPrime.algebraOfLiesOver p (g • q) - rw [inertiaDeg'_eq p q, inertiaDeg'_eq p (g • q)] + rw [inertiaDeg_eq p q, inertiaDeg_eq p (g • q)] let e₂ := Ideal.residueFieldAlgEquiv' p (g • q) q f₀.symm (comap_symm f₀.toRingEquiv).symm exact e₂.toLinearEquiv.finrank_eq -theorem cardQuot_pow_inertiaDeg' [Module.Finite R S] [p.IsMaximal] [q.IsMaximal] [q.LiesOver p] : - p.cardQuot ^ q.inertiaDeg' R = q.cardQuot := by +@[deprecated (since := "2026-07-03")] alias inertiaDeg'_smul := inertiaDeg_smul + +theorem cardQuot_pow_inertiaDeg [Module.Finite R S] [p.IsMaximal] [q.IsMaximal] [q.LiesOver p] : + p.cardQuot ^ q.inertiaDeg R = q.cardQuot := by let _ : Field (R ⧸ p) := Quotient.field p - rw [← inertiaDeg_eq_inertiaDeg' p q, inertiaDeg_algebraMap p q] + rw [← inertiaDeg'_eq_inertiaDeg p q, inertiaDeg'_algebraMap p q] exact Module.natCard_eq_pow_finrank.symm -theorem absNorm_pow_inertiaDeg' [Module.Finite R S] [q.IsPrime] [q.LiesOver p] +@[deprecated (since := "2026-07-03")] alias cardQuot_pow_inertiaDeg' := cardQuot_pow_inertiaDeg + +theorem absNorm_pow_inertiaDeg [Module.Finite R S] [q.IsPrime] [q.LiesOver p] [IsDedekindDomain R] [IsDedekindDomain S] [Module.Free ℤ R] [Module.Free ℤ S] : - p.absNorm ^ q.inertiaDeg' R = q.absNorm := by + p.absNorm ^ q.inertiaDeg R = q.absNorm := by by_cases hp : p = ⊥ · subst hp - simpa [eq_bot_of_liesOver_bot R q] using (inertiaDeg'_pos q R).ne' + simpa [eq_bot_of_liesOver_bot R q] using (inertiaDeg_pos q R).ne' have := isPrime_of_liesOver q p have := isMaximal_of_isPrime_of_ne_bot p hp have := IsMaximal.of_liesOver_isMaximal q p - exact cardQuot_pow_inertiaDeg' p q + exact cardQuot_pow_inertiaDeg p q + +@[deprecated (since := "2026-07-03")] alias absNorm_pow_inertiaDeg' := absNorm_pow_inertiaDeg -theorem natAbs_pow_inertiaDeg' [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] (p : ℤ) +theorem natAbs_pow_inertiaDeg [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] (p : ℤ) (P : Ideal R) [P.IsPrime] [P.LiesOver (span {p})] : - p.natAbs ^ P.inertiaDeg' ℤ = absNorm P := by - simpa using absNorm_pow_inertiaDeg' (span {p}) P + p.natAbs ^ P.inertiaDeg ℤ = absNorm P := by + simpa using absNorm_pow_inertiaDeg (span {p}) P + +@[deprecated (since := "2026-07-03")] alias natAbs_pow_inertiaDeg' := natAbs_pow_inertiaDeg -theorem pow_inertiaDeg' [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] (p : ℕ) +theorem pow_inertiaDeg [IsDedekindDomain R] [Module.Free ℤ R] [Module.Finite ℤ R] (p : ℕ) (P : Ideal R) [P.IsPrime] [P.LiesOver (span {(p : ℤ)})] : - p ^ P.inertiaDeg' ℤ = absNorm P := - natAbs_pow_inertiaDeg' p P + p ^ P.inertiaDeg ℤ = absNorm P := + natAbs_pow_inertiaDeg p P end From bb577fa4a1e2a5314521209c86e6015303fd2e9a Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Sat, 4 Jul 2026 12:01:34 +0000 Subject: [PATCH 0601/1300] feat(RepresentationTheory/Rep): add instances and APIs (#41072) Co-authored-by: Riccardo Brasca --- .../RepresentationTheory/Intertwining.lean | 78 +++++++++++++++++++ Mathlib/RepresentationTheory/Rep/Basic.lean | 31 ++++++++ Mathlib/RepresentationTheory/Rep/Iso.lean | 19 ----- Mathlib/RepresentationTheory/Rep/Res.lean | 54 ++++++++++++- .../Subrepresentation.lean | 1 + 5 files changed, 162 insertions(+), 21 deletions(-) diff --git a/Mathlib/RepresentationTheory/Intertwining.lean b/Mathlib/RepresentationTheory/Intertwining.lean index ebcc0244e85ec0..5a7e62b4820e40 100644 --- a/Mathlib/RepresentationTheory/Intertwining.lean +++ b/Mathlib/RepresentationTheory/Intertwining.lean @@ -226,6 +226,84 @@ lemma comp_add (f₁ f₂ : IntertwiningMap σ τ) (g : IntertwiningMap ρ σ) : lemma add_comp (f : IntertwiningMap σ τ) (g₁ g₂ : IntertwiningMap ρ σ) : comp f (g₁ + g₂) = comp f g₁ + comp f g₂ := by ext1; simp [LinearMap.comp_add] +variable (A) in +/-- The projection of a product representation onto its first component is an intertwining map. -/ +def fst : IntertwiningMap (ρ.prod σ) ρ where + toLinearMap := LinearMap.fst A V W + isIntertwining' _ := LinearMap.ext <| by simp + +variable (A) in +/-- The projection of a product representation onto its second component is an intertwining map. -/ +def snd : IntertwiningMap (ρ.prod σ) σ where + toLinearMap := LinearMap.snd A V W + isIntertwining' _ := LinearMap.ext <| by simp + +@[simp] +lemma fst_apply (v : V × W) : fst A ρ σ v = v.1 := rfl + +@[simp] +lemma snd_apply (v : V × W) : snd A ρ σ v = v.2 := rfl + +@[simp, norm_cast] lemma coe_fst : ⇑(fst A ρ σ) = Prod.fst := rfl + +@[simp, norm_cast] lemma coe_snd : ⇑(snd A ρ σ) = Prod.snd := rfl + +lemma fst_surjective : Function.Surjective (fst A ρ σ) := LinearMap.fst_surjective + +lemma snd_surjective : Function.Surjective (snd A ρ σ) := LinearMap.snd_surjective + +section prod + +variable {ρ σ τ} +/-- The product of two intertwining maps is an intertwining map. -/ +def prod (f : IntertwiningMap ρ σ) (g : IntertwiningMap ρ τ) : IntertwiningMap ρ (σ.prod τ) where + toLinearMap := f.toLinearMap.prod g.toLinearMap + isIntertwining' _ := LinearMap.ext <| by simp [f.isIntertwining, g.isIntertwining] + +@[simp] +lemma fst_prod (f : IntertwiningMap ρ σ) (g : IntertwiningMap ρ τ) : + (fst A σ τ).comp (prod f g) = f := IntertwiningMap.ext <| LinearMap.fst_prod _ _ + +@[simp] +lemma snd_prod (f : IntertwiningMap ρ σ) (g : IntertwiningMap ρ τ) : + (snd A σ τ).comp (prod f g) = g := IntertwiningMap.ext <| LinearMap.snd_prod _ _ + +lemma prod_comp (X : Type*) [AddCommMonoid X] [Module A X] {π : Representation A G X} + (f : IntertwiningMap ρ σ) (g₁ : IntertwiningMap σ τ) (g₂ : IntertwiningMap σ π) : + (prod g₁ g₂).comp f = prod (g₁.comp f) (g₂.comp f) := + IntertwiningMap.ext <| LinearMap.prod_comp .. + +variable (A ρ σ) in +/-- The left inclusion of a product representation is an intertwining map. -/ +def inl : IntertwiningMap ρ (ρ.prod σ) := prod (id ρ) 0 + +variable (A ρ σ) in +/-- The right inclusion of a product representation is an intertwining map. -/ +def inr : IntertwiningMap σ (ρ.prod σ) := prod (0 : IntertwiningMap σ ρ) (id σ) + +lemma range_inl : (inl A ρ σ).range = (snd A ρ σ).ker := + Subrepresentation.ext <| LinearMap.range_inl .. + +lemma range_inr : (inr A ρ σ).range = (fst A ρ σ).ker := + Subrepresentation.ext <| LinearMap.range_inr .. + +@[simp] lemma fst_comp_inl : (fst A ρ σ).comp (inl A ρ σ) = id ρ := + IntertwiningMap.ext <| LinearMap.fst_comp_inl .. + +@[simp] lemma snd_comp_inl : (snd A ρ σ).comp (inl A ρ σ) = 0 := + IntertwiningMap.ext <| LinearMap.snd_comp_inl .. + +@[simp] lemma fst_comp_inr : (fst A ρ σ).comp (inr A ρ σ) = 0 := + IntertwiningMap.ext <| LinearMap.fst_comp_inr .. + +@[simp] lemma snd_comp_inr : (snd A ρ σ).comp (inr A ρ σ) = id σ := + IntertwiningMap.ext <| LinearMap.snd_comp_inr .. + +@[simp] lemma coprod_inl_inr : (inl A ρ σ).comp (fst A ρ σ) + (inr A ρ σ).comp (snd A ρ σ) = + .id _ := IntertwiningMap.ext <| LinearMap.coprod_inl_inr + +end prod + end IntertwiningMap /-- Equivalence between representations is a bijective intertwining map. -/ diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index e1caf8bd04152e..f825c0de10ee70 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -540,6 +540,37 @@ instance preservesColimits_forget : Limits.PreservesColimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCat k)) := Limits.preservesColimits_of_natIso (forgetNatIsoActionForget k G).symm +instance : Limits.HasBinaryBiproducts (Rep.{w} k G) where + has_binary_biproduct A B := Limits.hasBinaryBiproduct_of_total + ⟨Rep.of (X := A.V × B.V) (A.ρ.prod B.ρ), Rep.ofHom (.fst k A.ρ B.ρ), Rep.ofHom (.snd k A.ρ B.ρ), + Rep.ofHom (.inl k A.ρ B.ρ), Rep.ofHom (.inr k A.ρ B.ρ), by ext1; simp, + by ext1; simp [zero_hom], by ext1; simp [zero_hom], by ext1; simp⟩ <| by + ext1; simp [Rep.add_hom] + +instance : Limits.HasZeroObject (Rep.{w} k G) where + zero := ⟨Rep.trivial k G PUnit, { + unique_to X := Nonempty.intro ⟨⟨0⟩, fun f ↦ by + ext x; have : x = 0 := Subsingleton.elim _ _; subst this; simp⟩ + unique_from X := Nonempty.intro ⟨⟨0⟩, fun f ↦ by ext⟩ + }⟩ + +/-- An object of `Rep k G` is zero iff the underlying `k`-module is zero. -/ +lemma isZero_iff (M : Rep k G) : Limits.IsZero M ↔ Subsingleton M.V := by + simp [Limits.IsZero.iff_id_eq_zero, Rep.hom_ext_iff, Representation.IntertwiningMap.ext_iff, + ← ModuleCat.isZero_of_iff_subsingleton (R := k), ModuleCat.hom_ext_iff] + +instance : Limits.HasLimits (Rep.{w} k G) := + Adjunction.has_limits_of_equivalence (repIsoAction k G).functor + +instance : Limits.HasColimits (Rep.{w} k G) := + Adjunction.has_colimits_of_equivalence (repIsoAction k G).functor + +instance : Limits.ReflectsLimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCat k)) := + Limits.reflectsLimits_of_reflectsIsomorphisms + +instance : Limits.ReflectsColimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCat k)) := + Limits.reflectsColimits_of_reflectsIsomorphisms + variable {k G} in theorem epi_iff_surjective (f : A ⟶ B) : Epi f ↔ Function.Surjective f.hom := ⟨fun _ => (ModuleCat.epi_iff_surjective ((forget₂ _ _).map f)).1 inferInstance, diff --git a/Mathlib/RepresentationTheory/Rep/Iso.lean b/Mathlib/RepresentationTheory/Rep/Iso.lean index acb864891c279f..ae54a42dccd7fc 100644 --- a/Mathlib/RepresentationTheory/Rep/Iso.lean +++ b/Mathlib/RepresentationTheory/Rep/Iso.lean @@ -168,25 +168,6 @@ instance : (toModuleMonoidAlgebra.{w} (k := k) (G := G)).IsEquivalence := instance : (ofModuleMonoidAlgebra (k := k) (G := G)).IsEquivalence := (equivalenceModuleMonoidAlgebra (k := k) (G := G)).isEquivalence_inverse -open MonoidalCategory in -instance : Limits.HasBinaryBiproducts (Rep.{w} k G) where - has_binary_biproduct A B := Limits.hasBinaryBiproduct_of_total - ⟨Rep.of (X := A.V × B.V) (Representation.prod A.ρ B.ρ), Rep.ofHom ⟨LinearMap.fst k _ _, by - simp [LinearMap.ext_iff]⟩, Rep.ofHom ⟨LinearMap.snd k _ _, by simp [LinearMap.ext_iff]⟩, - Rep.ofHom ⟨LinearMap.inl _ _ _, by simp [LinearMap.ext_iff]⟩, Rep.ofHom ⟨LinearMap.inr _ _ _, - by simp [LinearMap.ext_iff]⟩, by ext : 2; simp, by ext : 2; simp [zero_hom], by - ext : 2; simp [zero_hom], by ext : 2; simp⟩ <| by - ext : 2; simp [← ofHom_comp, ← ofHom_add, LinearMap.ext_iff] - -instance : Limits.HasZeroObject (Rep.{w} k G) where - zero := ⟨Rep.trivial k G PUnit, { - unique_to X := Nonempty.intro ⟨⟨0⟩, fun f ↦ by - ext x; have : x = 0 := Subsingleton.elim _ _; subst this; simp⟩ - unique_from X := Nonempty.intro ⟨⟨0⟩, fun f ↦ by ext⟩ - }⟩ - -instance : Limits.HasFiniteProducts (Rep.{w} k G) := hasFiniteProducts_of_has_binary_and_terminal - instance : Abelian (Rep.{w} k G) := abelianOfEquivalence toModuleMonoidAlgebra -- TODO Verify that the equivalence with `ModuleCat k[G]` is a monoidal functor. diff --git a/Mathlib/RepresentationTheory/Rep/Res.lean b/Mathlib/RepresentationTheory/Rep/Res.lean index 284c9079d71112..008c53a80d3ba4 100644 --- a/Mathlib/RepresentationTheory/Rep/Res.lean +++ b/Mathlib/RepresentationTheory/Rep/Res.lean @@ -5,8 +5,8 @@ Authors: Edison Xie -/ module -public import Mathlib.RepresentationTheory.Rep.Basic - +public import Mathlib.Algebra.Homology.ShortComplex.ShortExact +public import Mathlib.RepresentationTheory.Rep.Iso /-! # Restriction of representations @@ -88,6 +88,56 @@ instance : (resFunctor (k := k) f).Additive where instance {k : Type u} [CommSemiring k] : (resFunctor (k := k) f).Linear k where map_smul {_ _} _ _ := by ext : 2; simp [smul_hom] +section ShortComplex + +open Limits + +variable {k : Type u} [Ring k] + +instance : PreservesLimits (resFunctor.{w} (k := k) f) := + have : PreservesLimitsOfSize.{w, w} (resFunctor f ⋙ forget₂ (Rep.{w} k H) (ModuleCat k)) := + inferInstanceAs (PreservesLimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCat k))) + preservesLimits_of_reflects_of_preserves _ (forget₂ (Rep.{w} k H) (ModuleCat k)) + +instance : Limits.PreservesColimits (resFunctor.{w} (k := k) f) := + have : PreservesColimitsOfSize.{w, w} (resFunctor (k := k) f ⋙ + forget₂ (Rep.{w} k H) (ModuleCat k)) := + inferInstanceAs (PreservesColimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCat k))) + preservesColimits_of_reflects_of_preserves _ (forget₂ (Rep.{w} k H) (ModuleCat k)) + +/-- An object of `Rep k G` is zero iff its restriction to `H` is zero. -/ +lemma isZero_res_iff (M : Rep k G) : + IsZero (res f M) ↔ IsZero M := by + rw [isZero_iff, isZero_iff, Rep.res_obj_V] + +/-- +The instances above show that the restriction functor `res φ : Rep R G ⥤ Rep R H` +preserves and reflects exactness. -/ +lemma res_map_exact {k : Type u} [CommRing k] + (S : ShortComplex (Rep.{w} k G)) : + (S.map (resFunctor f)).Exact ↔ S.Exact := by + rw [ShortComplex.exact_map_iff_of_faithful] + +lemma shortExact_res {k : Type u} [CommRing k] (φ : H →* G) {S : ShortComplex (Rep.{w} k G)} : + (S.map (resFunctor φ)).ShortExact ↔ S.ShortExact := by + constructor + · intro h + have h₁ := h.1 + have h₂ := h.2 + have h₃ := h.3 + rw [ShortComplex.exact_map_iff_of_faithful] at h₁ + simp only [ShortComplex.map_f, mono_iff_injective, ShortComplex.map_g, + epi_iff_surjective] at h₂ h₃ + exact {exact := h₁, mono_f := mono_iff_injective _|>.2 h₂, epi_g := epi_iff_surjective _|>.2 h₃} + · rintro @⟨_, mono_f, epi_g⟩ + exact { + exact := by rwa [ShortComplex.exact_map_iff_of_faithful] + mono_f := by simpa [mono_iff_injective] using! mono_f + epi_g := by simpa [epi_iff_surjective] using! epi_g + } + +end ShortComplex + noncomputable section variable {G : Type v} [Group G] (A : Rep k G) (S : Subgroup G) diff --git a/Mathlib/RepresentationTheory/Subrepresentation.lean b/Mathlib/RepresentationTheory/Subrepresentation.lean index ee58325924af84..f69a7d13d6d269 100644 --- a/Mathlib/RepresentationTheory/Subrepresentation.lean +++ b/Mathlib/RepresentationTheory/Subrepresentation.lean @@ -27,6 +27,7 @@ variable [Semiring A] [Monoid G] [AddCommMonoid W] [Module A W] /-- A subrepresentation of `G` of the `A`-module `W` is a submodule of `W` which is stable under the `G`-action. -/ +@[ext] structure Subrepresentation where /-- A subrepresentation is a submodule. -/ toSubmodule : Submodule A W From f3853dcbb5d9b2bceb63bb3b2b231474c9b714ef Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Sat, 4 Jul 2026 15:54:10 +0000 Subject: [PATCH 0602/1300] refactor(LSeries/AbstractFuncEq): `IsStrongFEPair` predicate (#41329) Weak and strong FE-pairs are constructs used in the proof of functional equations for certain L-functions. Mathematically a StrongFEPair is a WeakFEPair with an additional property (but the same data). Having them as separate structures, as at present, creates some annoying duplication. This gets rid of the StrongFEPair structure and replaces it with a _predicate_ `IsStrongFEPair` stating that a given WeakFEPair is actually strong. --- .../NumberTheory/LSeries/AbstractFuncEq.lean | 227 ++++++++++-------- .../NumberTheory/LSeries/HurwitzZetaOdd.lean | 22 +- 2 files changed, 138 insertions(+), 111 deletions(-) diff --git a/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean b/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean index d8bb638dfc19be..d01d85c505d2c5 100644 --- a/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean +++ b/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean @@ -41,11 +41,6 @@ The poles (and their residues) are explicitly given in terms of `f₀` and `g₀ See the sections *Main theorems on weak FE-pairs* and *Main theorems on strong FE-pairs* below. -* Strong FE pairs: - - `StrongFEPair.Λ` : function of `s : ℂ` - - `StrongFEPair.differentiable_Λ`: `Λ` is entire - - `StrongFEPair.hasMellin`: `Λ` is everywhere equal to the Mellin transform of `f` - - `StrongFEPair.functional_equation`: the functional equation for `Λ` * Weak FE pairs: - `WeakFEPair.Λ₀`: and `WeakFEPair.Λ`: functions of `s : ℂ` - `WeakFEPair.differentiable_Λ₀`: `Λ₀` is entire @@ -55,6 +50,10 @@ See the sections *Main theorems on weak FE-pairs* and - `WeakFEPair.functional_equation`: the functional equation for `Λ` - `WeakFEPair.Λ_residue_k`: computation of the residue at `k` - `WeakFEPair.Λ_residue_zero`: computation of the residue at `0`. + +* Strong FE pairs: + - `IsStrongFEPair.differentiable_Λ`: `Λ` is entire + - `IsStrongFEPair.hasMellin`: `Λ` is everywhere equal to the Mellin transform of `f` -/ @[expose] public section @@ -95,12 +94,13 @@ structure WeakFEPair where (hf_top (r : ℝ) : (f · - f₀) =O[atTop] (· ^ r)) (hg_top (r : ℝ) : (g · - g₀) =O[atTop] (· ^ r)) -/-- A structure designed to hold the hypotheses for the Mellin-functional-equation argument -(version without constant terms) -/ -structure StrongFEPair extends WeakFEPair E where (hf₀ : f₀ = 0) (hg₀ : g₀ = 0) - variable {E} +/-- A *strong FE-pair* is a weak FE-pair in which `f₀` and `g₀` are zero. -/ +structure IsStrongFEPair (P : WeakFEPair E) : Prop where + hf₀ : P.f₀ = 0 + hg₀ : P.g₀ = 0 + section symmetry /-- Reformulated functional equation with `f` and `g` interchanged. -/ @@ -111,8 +111,8 @@ lemma WeakFEPair.h_feq' (P : WeakFEPair E) (x : ℝ) (hx : 0 < x) : rw [one_div, inv_rpow hx.le, ofReal_inv] field [P.hε, (rpow_pos_of_pos hx _).ne'] -set_option linter.style.whitespace false in -- manual alignment is not recognised /-- The hypotheses are symmetric in `f` and `g`, with the constant `ε` replaced by `ε⁻¹`. -/ +@[simps] def WeakFEPair.symm (P : WeakFEPair E) : WeakFEPair E where f := P.g g := P.f @@ -128,22 +128,26 @@ def WeakFEPair.symm (P : WeakFEPair E) : WeakFEPair E where hk := P.hk h_feq := P.h_feq' -/-- The hypotheses are symmetric in `f` and `g`, with the constant `ε` replaced by `ε⁻¹`. -/ -def StrongFEPair.symm (P : StrongFEPair E) : StrongFEPair E where - toWeakFEPair := P.toWeakFEPair.symm - hf₀ := P.hg₀ - hg₀ := P.hf₀ +@[simp] lemma isStrongFEPair_symm {P : WeakFEPair E} : + IsStrongFEPair P.symm ↔ IsStrongFEPair P where + mp h := ⟨h.hg₀, h.hf₀⟩ + mpr h := ⟨h.hg₀, h.hf₀⟩ + +lemma IsStrongFEPair.symm {P : WeakFEPair E} (hP : IsStrongFEPair P) : + IsStrongFEPair P.symm := isStrongFEPair_symm.2 hP end symmetry namespace WeakFEPair +variable (P : WeakFEPair E) + /-! ## Auxiliary results I: lemmas on asymptotics -/ /-- As `x → 0`, we have `f x = x ^ (-P.k) • constant` up to a rapidly decaying error. -/ -lemma hf_zero (P : WeakFEPair E) (r : ℝ) : +lemma hf_zero (r : ℝ) : (fun x ↦ P.f x - (P.ε * ↑(x ^ (-P.k))) • P.g₀) =O[𝓝[>] 0] (· ^ r) := by have := (P.hg_top (-(r + P.k))).comp_tendsto tendsto_inv_nhdsGT_zero simp_rw [IsBigO, IsBigOWith, eventually_nhdsWithin_iff] at this ⊢ @@ -165,8 +169,7 @@ lemma hf_zero (P : WeakFEPair E) (r : ℝ) : field /-- Power asymptotic for `f - f₀` as `x → 0`. -/ -lemma hf_zero' (P : WeakFEPair E) : - (fun x : ℝ ↦ P.f x - P.f₀) =O[𝓝[>] 0] (· ^ (-P.k)) := by +lemma hf_zero' : (fun x : ℝ ↦ P.f x - P.f₀) =O[𝓝[>] 0] (· ^ (-P.k)) := by simp_rw [← fun x ↦ sub_add_sub_cancel (P.f x) ((P.ε * ↑(x ^ (-P.k))) • P.g₀) P.f₀] refine (P.hf_zero _).add (IsBigO.sub ?_ ?_) · rw [← isBigO_norm_norm] @@ -178,51 +181,8 @@ lemma hf_zero' (P : WeakFEPair E) : rw [norm_of_nonneg (rpow_pos_of_pos hx _).le, rpow_neg hx.le] exact (one_le_inv₀ (rpow_pos_of_pos hx _)).2 (rpow_le_one hx.le hx' P.hk.le) -end WeakFEPair - -namespace StrongFEPair - -variable (P : StrongFEPair E) - -/-- As `x → ∞`, `f x` decays faster than any power of `x`. -/ -lemma hf_top' (r : ℝ) : P.f =O[atTop] (· ^ r) := by - simpa [P.hf₀] using P.hf_top r - -/-- As `x → 0`, `f x` decays faster than any power of `x`. -/ -lemma hf_zero' (r : ℝ) : P.f =O[𝓝[>] 0] (· ^ r) := by - simpa using (P.hg₀ ▸ P.hf_zero r :) - -/-! -## Main theorems on strong FE-pairs --/ - -/-- The completed L-function. -/ -def Λ : ℂ → E := mellin P.f - -/-- The Mellin transform of `f` is well-defined and equal to `P.Λ s`, for all `s`. -/ -theorem hasMellin (s : ℂ) : HasMellin P.f s (P.Λ s) := - let ⟨_, ht⟩ := exists_gt s.re - let ⟨_, hu⟩ := exists_lt s.re - ⟨mellinConvergent_of_isBigO_rpow P.hf_int (P.hf_top' _) ht (P.hf_zero' _) hu, rfl⟩ - -lemma Λ_eq : P.Λ = mellin P.f := rfl - -lemma symm_Λ_eq : P.symm.Λ = mellin P.g := rfl - -/-- If `(f, g)` are a strong FE pair, then the Mellin transform of `f` is entire. -/ -theorem differentiable_Λ : Differentiable ℂ P.Λ := fun s ↦ - let ⟨_, ht⟩ := exists_gt s.re - let ⟨_, hu⟩ := exists_lt s.re - mellin_differentiableAt_of_isBigO_rpow P.hf_int (P.hf_top' _) ht (P.hf_zero' _) hu - -/-- Main theorem about strong FE pairs: if `(f, g)` are a strong FE pair, then the Mellin -transforms of `f` and `g` are related by `s ↦ k - s`. - -This is proved by making a substitution `t ↦ t⁻¹` in the Mellin transform integral. -/ -theorem functional_equation (s : ℂ) : - P.Λ (P.k - s) = P.ε • P.symm.Λ s := by - -- unfold definition: - rw [P.Λ_eq, P.symm_Λ_eq] +private theorem functional_equation_aux (s : ℂ) : + mellin P.f (P.k - s) = P.ε • mellin P.g s := by -- substitute `t ↦ t⁻¹` in `mellin P.g s` have step1 := mellin_comp_rpow P.g (-s) (-1) simp_rw [abs_neg, abs_one, inv_one, one_smul, ofReal_neg, ofReal_one, div_neg, div_one, neg_neg, @@ -242,7 +202,36 @@ theorem functional_equation (s : ℂ) : have : (t : ℂ) ^ (P.k : ℂ) ≠ 0 := by simpa [← ofReal_cpow ht.le] using (rpow_pos_of_pos ht _).ne' field_simp [P.hε] -end StrongFEPair +end WeakFEPair + +namespace IsStrongFEPair + +variable {P : WeakFEPair E} (hP : IsStrongFEPair P) +include hP + +/-- As `x → ∞`, `f x` decays faster than any power of `x`. -/ +lemma hf_top (r : ℝ) : P.f =O[atTop] (· ^ r) := by + simpa [hP.hf₀] using P.hf_top r + +/-- As `x → 0`, `f x` decays faster than any power of `x`. -/ +lemma hf_zero (r : ℝ) : P.f =O[𝓝[>] 0] (· ^ r) := by + simpa using (hP.hg₀ ▸ P.hf_zero r :) + +/-- The Mellin transform of `P.f` is globally convergent. Private since it is superseded by +`IsStrongFEPair.hasMellin` below, which also identifies its Mellin transform as `P.Λ`. -/ +private theorem mellinConvergent (s : ℂ) : MellinConvergent P.f s := + let ⟨_, ht⟩ := exists_gt s.re + let ⟨_, hu⟩ := exists_lt s.re + mellinConvergent_of_isBigO_rpow P.hf_int (hP.hf_top _) ht (hP.hf_zero _) hu + +/-- The Mellin transform of `P.f` is globally convergent. Private since it is superseded by +`IsStrongFEPair.differentiable_Λ` below. -/ +private theorem differentiable_mellin : Differentiable ℂ (mellin P.f) := fun s ↦ + let ⟨_, ht⟩ := exists_gt s.re + let ⟨_, hu⟩ := exists_lt s.re + mellin_differentiableAt_of_isBigO_rpow P.hf_int (hP.hf_top _) ht (hP.hf_zero _) hu + +end IsStrongFEPair namespace WeakFEPair @@ -297,14 +286,16 @@ lemma hf_modif_FE (x : ℝ) (hx : 0 < x) : lemma hf_modif_top (r : ℝ) : (fun x ↦ P.f_modif x - 0) =O[atTop] fun x ↦ x ^ r := by - refine (P.hf_top r).congr' ?_ (by rfl) + refine (P.hf_top r).congr' ?_ .rfl filter_upwards [eventually_gt_atTop 1] with x hx simp [f_modif, mem_Ioi.mpr hx, notMem_Ioo_of_ge hx.le] -set_option linter.style.whitespace false in -- manual alignment is not recognised /-- Given a weak FE-pair `(f, g)`, modify it into a strong FE-pair by subtracting suitable -correction terms from `f` and `g`. -/ -def toStrongFEPair : StrongFEPair E where +correction terms from `f` and `g`. + +(See `WeakFEPair.isStrongFEPair_toStrongFEPair` for the proof that this is actually a strong +FE-pair.) -/ +def toStrongFEPair : WeakFEPair E where f := P.f_modif g := P.symm.f_modif k := P.k @@ -316,11 +307,13 @@ def toStrongFEPair : StrongFEPair E where h_feq := P.hf_modif_FE hε := P.hε hk := P.hk - hf₀ := rfl - hg₀ := rfl hf_top := P.hf_modif_top hg_top := P.symm.hf_modif_top +lemma isStrongFEPair_toStrongFEPair : IsStrongFEPair P.toStrongFEPair where + hf₀ := rfl + hg₀ := rfl + /- Alternative form for the difference between `f - f₀` and its modified term. -/ lemma f_modif_aux1 : EqOn (fun x ↦ P.f_modif x - P.f x + P.f₀) ((Ioo 0 1).indicator (fun x : ℝ ↦ P.f₀ - (P.ε * ↑(x ^ (-P.k))) • P.g₀) @@ -328,13 +321,11 @@ lemma f_modif_aux1 : EqOn (fun x ↦ P.f_modif x - P.f x + P.f₀) intro x (hx : 0 < x) simp_rw [f_modif, Pi.add_apply] rcases lt_trichotomy x 1 with hx' | rfl | hx' - · simp_rw [indicator_of_notMem (notMem_Ioi.mpr hx'.le), - indicator_of_mem (mem_Ioo.mpr ⟨hx, hx'⟩), + · simp_rw [indicator_of_notMem (notMem_Ioi.mpr hx'.le), indicator_of_mem (mem_Ioo.mpr ⟨hx, hx'⟩), indicator_of_notMem (mem_singleton_iff.not.mpr hx'.ne)] abel · simp [add_comm, sub_eq_add_neg] - · simp_rw [indicator_of_mem (mem_Ioi.mpr hx'), - indicator_of_notMem (notMem_Ioo_of_ge hx'.le), + · simp_rw [indicator_of_mem (mem_Ioi.mpr hx'), indicator_of_notMem (notMem_Ioo_of_ge hx'.le), indicator_of_notMem (mem_singleton_iff.not.mpr hx'.ne')] abel @@ -370,12 +361,12 @@ lemma f_modif_aux2 [CompleteSpace E] {s : ℂ} (hs : P.k < re s) : · refine (Integrable.smul_const ?_ _).smul _ rw [← IntegrableOn, ← intervalIntegrable_iff_integrableOn_Ioc_of_le zero_le_one] exact intervalIntegral.intervalIntegrable_cpow' h_re2 - _ = _ := by simp_rw [← intervalIntegral.integral_of_le zero_le_one, - integral_cpow (Or.inl h_re1), integral_cpow (Or.inl h_re2), ofReal_zero, ofReal_one, - one_cpow, sub_add_cancel, zero_cpow fun h ↦ lt_irrefl _ (P.hk.le.trans_lt (zero_re ▸ h ▸ hs)), - zero_cpow (sub_ne_zero.mpr (fun h ↦ lt_irrefl _ ((ofReal_re _) ▸ h ▸ hs)) : s - P.k ≠ 0), - sub_zero, sub_eq_add_neg (_ • _), ← mul_smul, ← neg_smul, mul_one_div, ← div_neg, neg_sub] - + _ = _ := by + simp_rw [← intervalIntegral.integral_of_le zero_le_one] + match_scalars + · simp [integral_cpow (.inl h_re1), zero_cpow (show s ≠ 0 by grind [P.hk, zero_re])] + · simp [integral_cpow (.inl h_re2), zero_cpow (show s - P.k ≠ 0 by grind [P.hk, ofReal_re])] + grind /-! ## Main theorems on weak FE-pairs -/ @@ -393,24 +384,24 @@ lemma Λ₀_eq (s : ℂ) : P.Λ₀ s = P.Λ s + (1 / s) • P.f₀ + (P.ε / (P. lemma symm_Λ₀_eq (s : ℂ) : P.symm.Λ₀ s = P.symm.Λ s + (1 / s) • P.g₀ + (P.ε⁻¹ / (P.k - s)) • P.f₀ := by - rw [P.symm.Λ₀_eq] - rfl + simp [P.symm.Λ₀_eq] -theorem differentiable_Λ₀ : Differentiable ℂ P.Λ₀ := P.toStrongFEPair.differentiable_Λ +theorem differentiable_Λ₀ : Differentiable ℂ P.Λ₀ := + P.isStrongFEPair_toStrongFEPair.differentiable_mellin theorem differentiableAt_Λ {s : ℂ} (hs : s ≠ 0 ∨ P.f₀ = 0) (hs' : s ≠ P.k ∨ P.g₀ = 0) : DifferentiableAt ℂ P.Λ s := by refine ((P.differentiable_Λ₀ s).sub ?_).sub ?_ · rcases hs with hs | hs - · simpa using (differentiableAt_inv hs).smul_const _ + · fun_prop · simp [hs] · rcases hs' with hs' | hs' - · apply DifferentiableAt.smul_const - apply (differentiableAt_const _).div ((differentiableAt_const _).sub (differentiable_id _)) - simpa [sub_eq_zero, eq_comm] + · fun_prop (disch := grind) · simp [hs'] -/-- Relation between `Λ s` and the Mellin transform of `f - f₀`, where the latter is defined. -/ +/-- Relation between `Λ s` and the Mellin transform of `f - f₀`, where the latter is defined. +(Compare `IsStrongFEPair.hasMellin` for a version without assumptions on `s.re` assuming the +FE-pair is strong.) -/ theorem hasMellin [CompleteSpace E] {s : ℂ} (hs : P.k < s.re) : HasMellin (P.f · - P.f₀) s (P.Λ s) := by have hc1 : MellinConvergent (P.f · - P.f₀) s := @@ -418,51 +409,83 @@ theorem hasMellin [CompleteSpace E] mellinConvergent_of_isBigO_rpow (P.hf_int.sub (locallyIntegrableOn_const _)) (P.hf_top _) ht P.hf_zero' hs refine ⟨hc1, ?_⟩ - have hc2 : HasMellin P.f_modif s (P.Λ₀ s) := P.toStrongFEPair.hasMellin s + have hc2 : MellinConvergent P.f_modif s := + P.isStrongFEPair_toStrongFEPair.mellinConvergent s have hc3 : mellin (fun x ↦ f_modif P x - f P x + P.f₀) s = (1 / s) • P.f₀ + (P.ε / (↑P.k - s)) • P.g₀ := P.f_modif_aux2 hs - have := (hasMellin_sub hc2.1 hc1).2 - simp_rw [← sub_add, hc3, eq_sub_iff_add_eq, ← eq_sub_iff_add_eq', ← sub_sub] at this - exact this + have := (hasMellin_sub hc2 hc1).2 + simp only [Λ, Λ₀] at * + grind /-- Functional equation formulated for `Λ₀`. -/ theorem functional_equation₀ (s : ℂ) : P.Λ₀ (P.k - s) = P.ε • P.symm.Λ₀ s := - P.toStrongFEPair.functional_equation s + P.toStrongFEPair.functional_equation_aux s /-- Functional equation formulated for `Λ`. -/ theorem functional_equation (s : ℂ) : P.Λ (P.k - s) = P.ε • P.symm.Λ s := by linear_combination (norm := module) P.functional_equation₀ s - P.Λ₀_eq (P.k - s) - + congr(P.ε • $(P.symm_Λ₀_eq s)) + congr(($(mul_inv_cancel₀ P.hε) / ((P.k:ℂ) - s)) • P.f₀) + + congr(P.ε • $(P.symm_Λ₀_eq s)) + congr(($(mul_inv_cancel₀ P.hε) / (P.k - s)) • P.f₀) /-- The residue of `Λ` at `s = k` is equal to `ε • g₀`. -/ theorem Λ_residue_k : Tendsto (fun s : ℂ ↦ (s - P.k) • P.Λ s) (𝓝[≠] P.k) (𝓝 (P.ε • P.g₀)) := by simp_rw [Λ, smul_sub, (by simp : 𝓝 (P.ε • P.g₀) = 𝓝 (0 - 0 - -P.ε • P.g₀))] refine ((Tendsto.sub ?_ ?_).mono_left nhdsWithin_le_nhds).sub ?_ - · rw [(by rw [sub_self, zero_smul] : 𝓝 0 = 𝓝 ((P.k - P.k : ℂ) • P.Λ₀ P.k))] + · rw [(by simp : 𝓝 0 = 𝓝 ((P.k - P.k : ℂ) • P.Λ₀ P.k))] apply ((continuous_sub_right _).smul P.differentiable_Λ₀.continuous).tendsto - · rw [(by rw [sub_self, zero_smul] : 𝓝 0 = 𝓝 ((P.k - P.k : ℂ) • (1 / P.k : ℂ) • P.f₀))] + · rw [(by simp : 𝓝 0 = 𝓝 ((P.k - P.k : ℂ) • (1 / P.k : ℂ) • P.f₀))] refine (continuous_sub_right _).continuousAt.smul (ContinuousAt.smul ?_ continuousAt_const) have := ofReal_ne_zero.mpr P.hk.ne' fun_prop · refine (tendsto_const_nhds.mono_left nhdsWithin_le_nhds).congr' ?_ - refine eventually_nhdsWithin_of_forall (fun s (hs : s ≠ P.k) ↦ ?_) + filter_upwards [self_mem_nhdsWithin] with s (hs : s ≠ P.k) match_scalars - field [sub_ne_zero.mpr hs.symm] + grind /-- The residue of `Λ` at `s = 0` is equal to `-f₀`. -/ -theorem Λ_residue_zero : - Tendsto (fun s : ℂ ↦ s • P.Λ s) (𝓝[≠] 0) (𝓝 (-P.f₀)) := by +theorem Λ_residue_zero : Tendsto (fun s ↦ s • P.Λ s) (𝓝[≠] 0) (𝓝 (-P.f₀)) := by simp_rw [Λ, smul_sub, (by simp : 𝓝 (-P.f₀) = 𝓝 (((0 : ℂ) • P.Λ₀ 0) - P.f₀ - 0))] refine ((Tendsto.mono_left ?_ nhdsWithin_le_nhds).sub ?_).sub ?_ · exact (continuous_id.smul P.differentiable_Λ₀.continuous).tendsto _ · refine (tendsto_const_nhds.mono_left nhdsWithin_le_nhds).congr' ?_ - refine eventually_nhdsWithin_of_forall (fun s (hs : s ≠ 0) ↦ ?_) + filter_upwards [self_mem_nhdsWithin] with s (hs : s ≠ 0) match_scalars - field [sub_ne_zero.mpr hs.symm] + grind · rw [show 𝓝 0 = 𝓝 ((0 : ℂ) • (P.ε / (P.k - 0 : ℂ)) • P.g₀) by rw [zero_smul]] exact (continuousAt_id.smul ((continuousAt_const.div ((continuous_sub_left _).continuousAt) (by simpa using P.hk.ne')).smul continuousAt_const)).mono_left nhdsWithin_le_nhds end WeakFEPair + +namespace IsStrongFEPair +/-! +## Main theorems on strong FE-pairs +-/ + +open WeakFEPair + +variable {P : WeakFEPair E} (hP : IsStrongFEPair P) +include hP + +/-- For strong FE-pairs, `P.Λ` is everywhere equal to the Mellin transform of `P.f`. -/ +lemma Λ_eq : P.Λ = mellin P.f := by + ext s + simp only [mellin, Λ, Λ₀, f_modif, hP.hf₀, sub_zero, hP.hg₀, smul_zero] + refine integral_congr_ae <| (ae_restrict_iff' measurableSet_Ioi).mpr ?_ + filter_upwards [compl_mem_ae_iff.mpr (Subsingleton.measure_zero (s := {1}) (by simp) _)] + with t (ht₁ : t ≠ 1) (ht₀ : 0 < t) + by_cases ht : t < 1 <;> [rw [add_comm] ; skip] <;> + rw [Pi.add_apply, indicator_of_mem (by grind), indicator_of_notMem (by grind), add_zero] + +lemma symm_Λ_eq : P.symm.Λ = mellin P.g := hP.symm.Λ_eq + +/-- The Mellin transform of `f` is well-defined and equal to `P.Λ s`, for all `s`. -/ +theorem hasMellin (s : ℂ) : HasMellin P.f s (P.Λ s) := + ⟨hP.mellinConvergent s, congr_fun hP.Λ_eq.symm s⟩ + +/-- If `P` is a strong FE pair, then `P.Λ` is entire. -/ +theorem differentiable_Λ : Differentiable ℂ P.Λ := + hP.Λ_eq ▸ hP.differentiable_mellin + +end IsStrongFEPair diff --git a/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean b/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean index 7fccd95307415c..8a2e6b51e1118c 100644 --- a/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean +++ b/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean @@ -299,7 +299,7 @@ section FEPair /-- A `StrongFEPair` structure with `f = oddKernel a` and `g = sinKernel a`. -/ @[simps] -def hurwitzOddFEPair (a : UnitAddCircle) : StrongFEPair ℂ where +def hurwitzOddFEPair (a : UnitAddCircle) : WeakFEPair ℂ where f := ofReal ∘ oddKernel a g := ofReal ∘ sinKernel a hf_int := (continuous_ofReal.comp_continuousOn (continuousOn_oddKernel a)).locallyIntegrableOn @@ -311,9 +311,7 @@ def hurwitzOddFEPair (a : UnitAddCircle) : StrongFEPair ℂ where ε := 1 hε := one_ne_zero f₀ := 0 - hf₀ := rfl g₀ := 0 - hg₀ := rfl hf_top r := by let ⟨v, hv, hv'⟩ := isBigO_atTop_oddKernel a rw [← isBigO_norm_left] at hv' ⊢ @@ -324,6 +322,10 @@ def hurwitzOddFEPair (a : UnitAddCircle) : StrongFEPair ℂ where simpa using hv'.trans (isLittleO_exp_neg_mul_rpow_atTop hv _).isBigO h_feq x hx := by simp [← ofReal_mul, oddKernel_functional_equation a, inv_rpow (le_of_lt hx)] +lemma isStrong_hurwitzOddFEPair (a : UnitAddCircle) : IsStrongFEPair (hurwitzOddFEPair a) where + hf₀ := rfl + hg₀ := rfl + end FEPair /-! @@ -339,7 +341,7 @@ def completedHurwitzZetaOdd (a : UnitAddCircle) (s : ℂ) : ℂ := lemma differentiable_completedHurwitzZetaOdd (a : UnitAddCircle) : Differentiable ℂ (completedHurwitzZetaOdd a) := - ((hurwitzOddFEPair a).differentiable_Λ.comp + ((isStrong_hurwitzOddFEPair a).differentiable_Λ.comp ((differentiable_id.add_const 1).div_const 2)).div_const 2 /-- The entire function of `s` which agrees with @@ -351,7 +353,7 @@ def completedSinZeta (a : UnitAddCircle) (s : ℂ) : ℂ := lemma differentiable_completedSinZeta (a : UnitAddCircle) : Differentiable ℂ (completedSinZeta a) := - ((hurwitzOddFEPair a).symm.differentiable_Λ.comp + ((isStrong_hurwitzOddFEPair a).symm.differentiable_Λ.comp ((differentiable_id.add_const 1).div_const 2)).div_const 2 /-! @@ -360,13 +362,13 @@ lemma differentiable_completedSinZeta (a : UnitAddCircle) : lemma completedHurwitzZetaOdd_neg (a : UnitAddCircle) (s : ℂ) : completedHurwitzZetaOdd (-a) s = -completedHurwitzZetaOdd a s := by - simp [completedHurwitzZetaOdd, StrongFEPair.Λ, hurwitzOddFEPair, mellin, oddKernel_neg, - integral_neg, neg_div] + simp [completedHurwitzZetaOdd, (isStrong_hurwitzOddFEPair _).Λ_eq, mellin, + oddKernel_neg, integral_neg, neg_div] lemma completedSinZeta_neg (a : UnitAddCircle) (s : ℂ) : completedSinZeta (-a) s = -completedSinZeta a s := by - simp [completedSinZeta, StrongFEPair.Λ, mellin, StrongFEPair.symm, WeakFEPair.symm, - hurwitzOddFEPair, sinKernel_neg, integral_neg, neg_div] + simp [completedSinZeta, (isStrong_hurwitzOddFEPair _).symm_Λ_eq, mellin, sinKernel_neg, + integral_neg, neg_div] /-- Functional equation for the odd Hurwitz zeta function. -/ theorem completedHurwitzZetaOdd_one_sub (a : UnitAddCircle) (s : ℂ) : @@ -403,6 +405,7 @@ lemma hasSum_int_completedSinZeta (a : ℝ) {s : ℂ} (hs : 1 < re s) : apply Summable.div_const apply Summable.of_nat_of_neg <;> simpa + rw [completedSinZeta, (isStrong_hurwitzOddFEPair _).symm_Λ_eq] refine (mellin_div_const .. ▸ hasSum_mellin_pi_mul_sq' (zero_lt_one.trans hs) hF h_sum).congr_fun fun n ↦ ?_ simp [Int.sign_eq_sign, ← Int.cast_abs] -- non-terminal simp OK when `ring` follows @@ -441,6 +444,7 @@ lemma hasSum_int_completedHurwitzZetaOdd (a : ℝ) {s : ℂ} (hs : 1 < re s) : simp_rw [c, ← mul_one_div ‖_‖] apply Summable.mul_left rwa [summable_one_div_int_add_rpow] + rw [completedHurwitzZetaOdd, (isStrong_hurwitzOddFEPair _).Λ_eq] have := mellin_div_const .. ▸ hasSum_mellin_pi_mul_sq' (zero_lt_one.trans hs) hF h_sum refine this.congr_fun fun n ↦ ?_ simp only [r, c, mul_one_div, div_mul_eq_mul_div, div_right_comm] From 15d4269237f15864cbda050e185a8b811672eca5 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Sat, 4 Jul 2026 17:26:21 +0000 Subject: [PATCH 0603/1300] feat(NumberTheory/Chebyshev,NumberTheory/ArithmeticFunction/vonMangoldt): add positivity extensions (#41334) Adds `positivity` extensions for the von Mangoldt and Chebyshev functions. Co-authored-by: Terence Tao Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../ArithmeticFunction/VonMangoldt.lean | 16 ++++++++++++ Mathlib/NumberTheory/Chebyshev.lean | 26 +++++++++++++++++++ MathlibTest/positivity.lean | 5 ++++ 3 files changed, 47 insertions(+) diff --git a/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean b/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean index 354482b01aa3fe..4cc8c9d13c1e3b 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean @@ -156,3 +156,19 @@ theorem vonMangoldt_le_log : ∀ {n : ℕ}, Λ n ≤ Real.log (n : ℝ) (mem_divisors_self _ n.succ_ne_zero) end ArithmeticFunction + +namespace Mathlib.Meta.Positivity + +open Lean Meta Qq + +/-- Extension for the `positivity` tactic: the von Mangoldt function is nonnegative. -/ +@[positivity ArithmeticFunction.vonMangoldt _] +meta def evalVonMangoldt : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do + match u, α, e with + | 0, ~q(ℝ), ~q(@ArithmeticFunction.vonMangoldt $a) => + assertInstancesCommute + pure (.nonnegative q(ArithmeticFunction.vonMangoldt_nonneg)) + | _, _, _ => throwError "not von Mangoldt" + +end Mathlib.Meta.Positivity diff --git a/Mathlib/NumberTheory/Chebyshev.lean b/Mathlib/NumberTheory/Chebyshev.lean index 85cab1e97e9ab0..f5d4549c5106cb 100644 --- a/Mathlib/NumberTheory/Chebyshev.lean +++ b/Mathlib/NumberTheory/Chebyshev.lean @@ -853,3 +853,29 @@ theorem pi_le_log4_mul_div {x : ℝ} (hx : 1 < x) : π ⌊x⌋₊ ≤ log 4 * x end PrimeCounting end Chebyshev + +namespace Mathlib.Meta.Positivity + +open Lean Meta Qq + +/-- Extension for the `positivity` tactic: the first Chebyshev function is nonnegative. -/ +@[positivity Chebyshev.theta _] +meta def evalTheta : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do + match u, α, e with + | 0, ~q(ℝ), ~q(@Chebyshev.theta $a) => + assertInstancesCommute + pure (.nonnegative q(Chebyshev.theta_nonneg $a)) + | _, _, _ => throwError "not theta" + +/-- Extension for the `positivity` tactic: the second Chebyshev function is nonnegative. -/ +@[positivity Chebyshev.psi _] +meta def evalPsi : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => pure .none | some _ => do + match u, α, e with + | 0, ~q(ℝ), ~q(@Chebyshev.psi $a) => + assertInstancesCommute + pure (.nonnegative q(Chebyshev.psi_nonneg $a)) + | _, _, _ => throwError "not psi" + +end Mathlib.Meta.Positivity diff --git a/MathlibTest/positivity.lean b/MathlibTest/positivity.lean index a680ddf744befd..8c86757d4a6c9b 100644 --- a/MathlibTest/positivity.lean +++ b/MathlibTest/positivity.lean @@ -8,6 +8,7 @@ import Mathlib.Analysis.SpecialFunctions.Log.Basic import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan import Mathlib.MeasureTheory.Integral.Bochner.Basic import Mathlib.NumberTheory.ArithmeticFunction.Misc +import Mathlib.NumberTheory.Chebyshev import Mathlib.Topology.Algebra.InfiniteSum.Order /-! # Tests for the `positivity` tactic @@ -487,6 +488,10 @@ example {r : ℝ} (hr : 0 < r) : 0 < Real.sin (Real.arctan r) := by positivity example {r : ℝ} (hr : r ≠ 0) : Real.sin (Real.arctan r) ≠ 0 := by positivity example {r : ℝ} (hr : 0 ≤ r) : 0 ≤ Real.sin (Real.arctan r) := by positivity +example (n : ℕ) : 0 ≤ ArithmeticFunction.vonMangoldt n := by positivity +example (x : ℝ) : 0 ≤ Chebyshev.theta x := by positivity +example (x : ℝ) : 0 ≤ Chebyshev.psi x := by positivity + end SpecialFunctions /-! ### `sqrt` on `ℝ` and `ℝ≥0` -/ From d3716e6d2ea114ae7d9f994e5ebf3c064d80c8a7 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sat, 4 Jul 2026 19:01:14 +0000 Subject: [PATCH 0604/1300] feat(SimpleGraph/Acyclic): a graph is acyclic iff it is free of cycle graphs (#41363) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `G.IsAcyclic ↔ ∀ n ≥ 3, (cycleGraph n).Free G` - `G.IsAcyclic → 3 ≤ n → G.CliqueFree n` --- Mathlib/Combinatorics/SimpleGraph/Acyclic.lean | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index d345f587840602..297353a932b46e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Combinatorics.SimpleGraph.Bipartite public import Mathlib.Combinatorics.SimpleGraph.Connectivity.Subgraph public import Mathlib.Combinatorics.SimpleGraph.Connectivity.EdgeConnectivity +public import Mathlib.Combinatorics.SimpleGraph.CycleGraph public import Mathlib.Combinatorics.SimpleGraph.DegreeSum public import Mathlib.Combinatorics.SimpleGraph.Metric @@ -649,4 +650,14 @@ lemma isAcyclic_iff_pairwise_not_isEdgeReachable_two : rintro ⟨u, v⟩ huv exact (isBridge_iff_not_isEdgeReachable_two huv).mpr (h huv.ne) +theorem isAcyclic_iff_free_cycleGraph : G.IsAcyclic ↔ ∀ n ≥ 3, (cycleGraph n).Free G := by + refine ⟨fun h n hn hle ↦ ?_, fun h v p hcyc ↦ h p.length hcyc.three_le_length ?_⟩ + · have ⟨v, p, hcyc, hlen⟩ := cycleGraph_isContained_iff hn |>.mp hle + exact h p hcyc + · exact cycleGraph_isContained_iff hcyc.three_le_length |>.mpr ⟨v, p, hcyc, rfl⟩ + +theorem IsAcyclic.cliqueFree (h : G.IsAcyclic) {n : ℕ} (hn : 3 ≤ n) : G.CliqueFree n := by + refine not_cliqueFree_iff_top_isContained n |>.not_right.mpr fun hle ↦ ?_ + exact isAcyclic_iff_free_cycleGraph.mp h n hn <| hle.trans' <| .of_le le_top + end SimpleGraph From 20516762403e5d984c5f8956dcbad9c2e9fc84b4 Mon Sep 17 00:00:00 2001 From: Fernando Chu <17756312+FernandoChu@users.noreply.github.com> Date: Sun, 5 Jul 2026 16:12:27 +0000 Subject: [PATCH 0605/1300] feat(CategoryTheory): pseudofunctors preserve adjunctions (#40628) --- .../Bicategory/Adjunction/Basic.lean | 69 +++++++++++++++++-- .../Bicategory/Functor/Prelax.lean | 4 ++ 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean index aad59ce2fd31f2..b255d46edd7c89 100644 --- a/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean @@ -1,10 +1,12 @@ /- Copyright (c) 2023 Yuma Mizuno. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Yuma Mizuno +Authors: Yuma Mizuno, Fernando Chu -/ module +public import Mathlib.CategoryTheory.Bicategory.Functor.Pseudofunctor +public import Mathlib.CategoryTheory.Bicategory.Functor.StrictPseudofunctor public import Mathlib.Tactic.CategoryTheory.Bicategory.Basic public import Mathlib.Tactic.CategoryTheory.BicategoricalComp @@ -22,6 +24,9 @@ identities. The 2-morphism `η` is called the unit and `ε` is called the counit * `Bicategory.Equivalence.mkOfAdjointifyCounit`: construct an adjoint equivalence from 2-isomorphisms `η : 𝟙 a ≅ f ≫ g` and `ε : g ≫ f ≅ 𝟙 b`, by upgrading `ε` to a counit. +* `Pseudofunctor.mapAdjunction`: a pseudofunctor `F` carries an adjunction `f ⊣ g` + between 1-morphisms to an adjunction `F.map f ⊣ F.map g`. An analogous definition is given + for `StrictPseudofunctor`. ## TODO @@ -34,15 +39,14 @@ identities. The 2-morphism `η` is called the unit and `ε` is called the counit namespace CategoryTheory -namespace Bicategory - -open Category +open Category Bicategory -open scoped Bicategory +universe w₁ w₂ v₁ v₂ u₁ u₂ -universe w v u +variable {B : Type u₁} [Bicategory.{w₁, v₁} B] {C : Type u₂} [Bicategory.{w₂, v₂} C] + {a b c : B} {f : a ⟶ b} {g : b ⟶ a} -variable {B : Type u} [Bicategory.{w, v} B] {a b c : B} {f : a ⟶ b} {g : b ⟶ a} +namespace Bicategory /-- The 2-morphism defined by the following pasting diagram: ``` @@ -341,4 +345,55 @@ end end Bicategory +namespace Pseudofunctor + +variable (F : Pseudofunctor B C) (adj : f ⊣ g) + +lemma leftZigzag_map : + leftZigzag ((F.mapId a).inv ≫ F.map₂ adj.unit ≫ (F.mapComp f g).hom) + ((F.mapComp g f).inv ≫ F.map₂ adj.counit ≫ (F.mapId b).hom) = + (F.mapId a).inv ▷ F.map f ⊗≫ (F.mapComp (𝟙 a) f).inv ≫ + F.map₂ (leftZigzag adj.unit adj.counit) ≫ + (F.mapComp f (𝟙 b)).hom ⊗≫ F.map f ◁ (F.mapId b).hom := by + simp [leftZigzag, bicategoricalComp] + +lemma rightZigzag_map : + rightZigzag ((F.mapId a).inv ≫ F.map₂ adj.unit ≫ (F.mapComp f g).hom) + ((F.mapComp g f).inv ≫ F.map₂ adj.counit ≫ (F.mapId b).hom) = + F.map g ◁ (F.mapId a).inv ⊗≫ (F.mapComp g (𝟙 a)).inv ≫ + F.map₂ (rightZigzag adj.unit adj.counit) ≫ + (F.mapComp (𝟙 b) g).hom ⊗≫ (F.mapId b).hom ▷ F.map g := by + simp [rightZigzag, bicategoricalComp, F.map₂_iso_inv] + +/-- A pseudofunctor carries an adjunction `f ⊣ g` to an adjunction `F.map f ⊣ F.map g`. -/ +@[simps] +def mapAdjunction : F.map f ⊣ F.map g where + unit := (F.mapId a).inv ≫ F.map₂ adj.unit ≫ (F.mapComp f g).hom + counit := (F.mapComp g f).inv ≫ F.map₂ adj.counit ≫ (F.mapId b).hom + left_triangle := by simp [leftZigzag_map, bicategoricalComp, F.map₂_iso_inv] + right_triangle := by simp [rightZigzag_map, bicategoricalComp, F.map₂_iso_inv] + +end Pseudofunctor + +namespace StrictPseudofunctor + +variable (F : StrictPseudofunctor B C) (adj : f ⊣ g) + +/-- A strict pseudofunctor carries an adjunction `f ⊣ g` to an adjunction +`F.map f ⊣ F.map g`. -/ +@[simps!] +def mapAdjunction : F.map f ⊣ F.map g := F.toPseudofunctor.mapAdjunction adj + +lemma mapAdjunction_unit' : + (F.mapAdjunction adj).unit = + eqToHom (F.map_id a).symm ≫ F.map₂ adj.unit ≫ eqToHom (F.map_comp f g) := by + simp [F.mapId_eq_eqToIso, F.mapComp_eq_eqToIso] + +lemma mapAdjunction_counit' : + (F.mapAdjunction adj).counit = + eqToHom (F.map_comp g f).symm ≫ F.map₂ adj.counit ≫ eqToHom (F.map_id b) := by + simp [F.mapId_eq_eqToIso, F.mapComp_eq_eqToIso] + +end StrictPseudofunctor + end CategoryTheory diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean index a1d34e6a0f49bd..653a26fe111dae 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean @@ -175,6 +175,10 @@ lemma map₂_inv {f g : a ⟶ b} (η : f ⟶ g) [IsIso η] : F.map₂ (inv η) = apply IsIso.eq_inv_of_hom_inv_id simp [← F.map₂_comp η (inv η)] +lemma map₂_iso_inv {f g : a ⟶ b} (η : f ≅ g) : + F.map₂ η.inv = inv (F.map₂ η.hom) := by + rw [← F.map₂_inv, IsIso.Iso.inv_hom] + @[reassoc, simp] lemma map₂_hom_inv {f g : a ⟶ b} (η : f ≅ g) : F.map₂ η.hom ≫ F.map₂ η.inv = 𝟙 (F.map f) := by From f682f8f0e2edb6a764ffbd330c1b4ef5b2aa7d2e Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Sun, 5 Jul 2026 18:40:34 +0000 Subject: [PATCH 0606/1300] feat(Analysis/SpecialFunctions/Pow/Asymptotics): add Real.tendsto_rpow_atTop_of_base_gt_one (#41375) Mathlib contains `Real.tendsto_rpow_atTop_of_base_lt_one`, `Real.tendsto_rpow_atBot_of_base_lt_one`, and `Real.tendsto_rpow_atBot_of_base_gt_one`, but `Real.tendsto_rpow_atTop_of_base_gt_one` was mysteriously missing. (For comparison, `ENNReal` [has all four versions](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.html).) This PR fills in the gap by adding the fourth lemma (with a near-identical proof). Co-authored-by: Terence Tao --- Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean index 0f3593ac9b6bf2..40bde6d8539f88 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean @@ -81,6 +81,12 @@ lemma tendsto_rpow_atBot_of_base_lt_one (b : ℝ) (hb₀ : 0 < b) (hb₁ : b < 1 refine tendsto_exp_atTop.comp <| (tendsto_const_mul_atTop_iff_neg <| tendsto_id (α := ℝ)).mpr ?_ exact (log_neg_iff hb₀).mpr hb₁ +lemma tendsto_rpow_atTop_of_base_gt_one (b : ℝ) (hb : 1 < b) : + Tendsto (b ^ · : ℝ → ℝ) atTop atTop := by + simp_rw [Real.rpow_def_of_pos (by positivity : 0 < b)] + refine tendsto_exp_atTop.comp <| (tendsto_const_mul_atTop_iff_pos <| tendsto_id (α := ℝ)).mpr ?_ + exact log_pos hb + lemma tendsto_rpow_atBot_of_base_gt_one (b : ℝ) (hb : 1 < b) : Tendsto (b ^ · : ℝ → ℝ) atBot (𝓝 0) := by simp_rw [Real.rpow_def_of_pos (by positivity : 0 < b)] From e2361c1bebbe457b1b699a67f685f675801a6da0 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Sun, 5 Jul 2026 19:50:20 +0000 Subject: [PATCH 0607/1300] feat(RingTheory/MvPolynomial/Homogeneous): add homogeneous lemmas (#39472) Co-authored-by: NoahW314 --- Mathlib/Data/Finsupp/Weight.lean | 11 ++++++ .../RingTheory/MvPolynomial/Homogeneous.lean | 35 +++++++++++++++++++ .../MvPolynomial/WeightedHomogeneous.lean | 31 +++++++++++++++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/Mathlib/Data/Finsupp/Weight.lean b/Mathlib/Data/Finsupp/Weight.lean index 4c1fae64aabf15..e937d3e86043a7 100644 --- a/Mathlib/Data/Finsupp/Weight.lean +++ b/Mathlib/Data/Finsupp/Weight.lean @@ -200,6 +200,14 @@ theorem finite_of_nat_weight_le [Finite σ] (w : σ → ℕ) (hw : ∀ x, w x grw [← le_weight _ (hw x)] at hd simp [*] +theorem finite_of_nat_weight_lt [Finite σ] (w : σ → ℕ) (hw : ∀ x, w x ≠ 0) (n : ℕ) : + {d : σ →₀ ℕ | weight w d < n}.Finite := + Set.Finite.subset (finite_of_nat_weight_le w hw n) (by grind) + +theorem finite_of_nat_weight_eq [Finite σ] (w : σ → ℕ) (hw : ∀ x, w x ≠ 0) (n : ℕ) : + {d : σ →₀ ℕ | weight w d = n}.Finite := + Set.Finite.subset (finite_of_nat_weight_le w hw n) (by grind) + end CanonicallyOrderedAddCommMonoid variable {R : Type*} [AddCommMonoid R] @@ -257,6 +265,9 @@ theorem finite_of_degree_le [Finite σ] (n : ℕ) : lemma finite_of_degree_lt [Finite σ] (n : ℕ) : {f : σ →₀ ℕ | degree f < n}.Finite := Set.Finite.subset (finite_of_degree_le n) (by grind) +lemma finite_of_degree_eq [Finite σ] (n : ℕ) : {f : σ →₀ ℕ | f.degree = n}.Finite := + Set.Finite.subset (finite_of_degree_le n) (by grind) + lemma range_single_one : Set.range (fun a : σ ↦ Finsupp.single a 1) = { d | d.degree = 1 } := by refine subset_antisymm ?_ ?_ diff --git a/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean b/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean index 12c16d3463e782..c9490a77d509de 100644 --- a/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean @@ -109,6 +109,10 @@ theorem homogeneousSubmodule_eq_finsupp_supported (n : ℕ) : simp_rw [degree_eq_weight_one] exact weightedHomogeneousSubmodule_eq_finsupp_supported R 1 n +lemma homogeneousSubmodule_fg [Finite σ] (n : ℕ) : + (homogeneousSubmodule σ R n).FG := + weightedHomogeneousSubmodule_fg R (1 : σ → ℕ) (by simp) n + variable {σ R} set_option backward.isDefEq.respectTransparency false in @@ -165,6 +169,10 @@ theorem isHomogeneous_zero (n : ℕ) : IsHomogeneous (0 : MvPolynomial σ R) n : theorem isHomogeneous_one : IsHomogeneous (1 : MvPolynomial σ R) 0 := isHomogeneous_C _ _ +lemma isHomogeneous_of_isEmpty [IsEmpty σ] (f : MvPolynomial σ R) : f.IsHomogeneous 0 := by + rw [eq_C_of_isEmpty f] + exact isHomogeneous_C _ _ + variable {σ} theorem isHomogeneous_X (i : σ) : IsHomogeneous (X i : MvPolynomial σ R) 1 := by @@ -565,11 +573,26 @@ theorem homogeneousComponent_of_mem {m n : ℕ} {p : MvPolynomial σ R} homogeneousComponent m p = if m = n then p else 0 := weightedHomogeneousComponent_of_mem h +lemma homogeneousComponent_eq_self {n : ℕ} {p : MvPolynomial σ R} + (hp : p.IsHomogeneous n) : homogeneousComponent n p = p := by + simp [homogeneousComponent_of_mem hp] + lemma support_homogeneousComponent (n : ℕ) (p : MvPolynomial σ R) : (homogeneousComponent n p).support = {c ∈ p.support | c.degree = n} := by rw [degree_eq_weight_one] exact support_weightedHomogeneousComponent n p +lemma rename_homogeneousComponent {τ : Type*} {φ : σ → τ} (n : ℕ) (p : MvPolynomial σ R) : + rename φ (homogeneousComponent n p) = homogeneousComponent n (rename φ p) := by + induction p using MvPolynomial.induction_on' with + | monomial d c => + rw [rename_monomial, + homogeneousComponent_of_mem (isHomogeneous_monomial c rfl), + homogeneousComponent_of_mem (isHomogeneous_monomial c (Finsupp.degree_mapDomain φ d))] + split_ifs <;> simp [rename_monomial] + | add p q hp hq => simp [map_add, hp, hq] + + end HomogeneousComponent end @@ -607,6 +630,18 @@ theorem decomposition.decompose'_eq : rw [degree_eq_weight_one] rfl +attribute [local instance] MvPolynomial.gradedAlgebra + +lemma mem_iff_homogeneousComponent_mem {I : Ideal (MvPolynomial σ R)} + (h : I.IsHomogeneous (homogeneousSubmodule σ R)) (p : MvPolynomial σ R) : + p ∈ I ↔ ∀ n, (homogeneousComponent n p) ∈ I := + mem_iff_weightedHomogeneousComponent_mem R (1 : σ → ℕ) h p + +lemma homogeneousComponent_mem_of_mem {I : Ideal (MvPolynomial σ R)} + (h : I.IsHomogeneous (homogeneousSubmodule σ R)) {p : MvPolynomial σ R} (hp : p ∈ I) (n : ℕ) : + (homogeneousComponent n p) ∈ I := + weightedHomogeneousComponent_mem_of_mem R (1 : σ → ℕ) h hp n + end GradedAlgebra end MvPolynomial diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index 7ffe045f11fbd9..167c934b9e5fef 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -11,7 +11,8 @@ public import Mathlib.Algebra.GradedMonoid public import Mathlib.Algebra.MvPolynomial.Basic public import Mathlib.Algebra.Order.Monoid.Canonical.Defs public import Mathlib.Data.Finsupp.Weight -public import Mathlib.RingTheory.GradedAlgebra.Basic +public import Mathlib.RingTheory.GradedAlgebra.Homogeneous.Ideal +public import Mathlib.RingTheory.MvPolynomial.Basic public import Mathlib.Tactic.Order /-! @@ -161,6 +162,12 @@ theorem weightedHomogeneousSubmodule_eq_finsupp_supported (w : σ → M) (m : M) simp [IsWeightedHomogeneous] simp [AddMonoidAlgebra.mem_supported, Set.subset_def, MvPolynomial, coeff] +lemma weightedHomogeneousSubmodule_fg [Finite σ] (w : σ → ℕ) (hw : ∀ (x : σ), w x ≠ 0) (n : ℕ) : + (weightedHomogeneousSubmodule R w n).FG := by + rw [weightedHomogeneousSubmodule_eq_finsupp_supported, ← Module.Finite.iff_fg] + have := (Finsupp.finite_of_nat_weight_eq w hw n).to_subtype + exact Module.Finite.of_basis (basisRestrictSupport R {d | Finsupp.weight w d = n}) + variable {R} set_option backward.isDefEq.respectTransparency false in @@ -217,6 +224,11 @@ theorem isWeightedHomogeneous_zero (w : σ → M) (m : M) : theorem isWeightedHomogeneous_one (w : σ → M) : IsWeightedHomogeneous w (1 : MvPolynomial σ R) 0 := isWeightedHomogeneous_C _ _ +lemma isWeightedHomogeneous_of_isEmpty [IsEmpty σ] (w : σ → M) (f : MvPolynomial σ R) : + IsWeightedHomogeneous w f 0 := by + rw [eq_C_of_isEmpty f] + exact isWeightedHomogeneous_C _ _ + /-- An indeterminate `i : σ` is weighted homogeneous of degree `w i`. -/ theorem isWeightedHomogeneous_X (w : σ → M) (i : σ) : IsWeightedHomogeneous w (X i : MvPolynomial σ R) (w i) := by @@ -476,6 +488,10 @@ theorem weightedHomogeneousComponent_of_mem [DecidableEq M] {m n : M} · rfl · simp only [coeff_zero] +lemma weightedHomogeneousComponent_eq_self {n : M} {p : MvPolynomial σ R} + (hp : p.IsWeightedHomogeneous w n) : weightedHomogeneousComponent w n p = p := by + classical simp [weightedHomogeneousComponent_of_mem hp] + lemma support_weightedHomogeneousComponent [DecidableEq M] (n : M) (p : MvPolynomial σ R) : (weightedHomogeneousComponent w n p).support = {c ∈ p.support | (weight w) c = n} := by ext c @@ -676,6 +692,19 @@ theorem weightedDecomposition.decompose'_apply [DecidableEq M] weightedHomogeneousComponent w m φ := MvPolynomial.decompose'_apply R w φ m +attribute [local instance] MvPolynomial.weightedGradedAlgebra + +lemma mem_iff_weightedHomogeneousComponent_mem [DecidableEq M] {I : Ideal (MvPolynomial σ R)} + (h : I.IsHomogeneous (weightedHomogeneousSubmodule R w)) (p : MvPolynomial σ R) : + p ∈ I ↔ ∀ m : M, (weightedHomogeneousComponent w m p) ∈ I := by + simp_rw [← weightedDecomposition.decompose'_apply] + exact h.mem_iff + +lemma weightedHomogeneousComponent_mem_of_mem [DecidableEq M] {I : Ideal (MvPolynomial σ R)} + (h : I.IsHomogeneous (weightedHomogeneousSubmodule R w)) {p : MvPolynomial σ R} (hp : p ∈ I) + (m : M) : (weightedHomogeneousComponent w m p) ∈ I := + (mem_iff_weightedHomogeneousComponent_mem R w h p).mp hp m + end GradedAlgebra end MvPolynomial From aeb7a50549e317bdf76691a46678ecacb7764bce Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 6 Jul 2026 06:54:24 +0000 Subject: [PATCH 0608/1300] =?UTF-8?q?feat(Push):=20allow=20pushing=20`?= =?UTF-8?q?=E2=88=80`=20through=20`=E2=88=83`=20(#39411)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds `Classical.skolem` to the `push` set. This allows pusing a forall through an exists, which can sometimes be convenient. --- Mathlib/Tactic/Push.lean | 2 +- MathlibTest/Tactic/Push/Basic.lean | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mathlib/Tactic/Push.lean b/Mathlib/Tactic/Push.lean index bffb4f1db6b571..3ebc12e181ebcf 100644 --- a/Mathlib/Tactic/Push.lean +++ b/Mathlib/Tactic/Push.lean @@ -41,7 +41,7 @@ attribute [push ←] ne_eq -- TODO: lemmas involving `∃` should be tagged using `binderNameHint`, -- and lemmas involving `∀` would need manual rewriting to keep the binder name. attribute [push] - forall_const forall_and forall_or_left forall_or_right forall_eq forall_eq' forall_self_imp + forall_const forall_and forall_or_left forall_or_right forall_eq forall_eq' Classical.skolem exists_const exists_or exists_and_left exists_and_right exists_eq exists_eq' and_or_left and_or_right and_true true_and and_false false_and or_and_left or_and_right or_true true_or or_false false_or diff --git a/MathlibTest/Tactic/Push/Basic.lean b/MathlibTest/Tactic/Push/Basic.lean index ffcb6348d50aa1..06f4e419938657 100644 --- a/MathlibTest/Tactic/Push/Basic.lean +++ b/MathlibTest/Tactic/Push/Basic.lean @@ -35,6 +35,10 @@ example {r : ℕ → Prop} : ∀ n : ℕ, p ∨ r n ∧ q ∧ n = 1 := by guard_target =ₛ ∀ n : ℕ, p ∨ r n ∧ q ∧ n = 1 exact test_sorry +/-- info: ∃ f, (∀ (x : ℕ) (x_1 : x > 0), f x x_1 > 0) ∧ ∀ (x : ℕ) (x_1 : x > 0), x = f x x_1 -/ +#guard_msgs in +#push ∀ _, _ => ∀ ε > 0, ∃ δ > 0, ε = δ + example {r : ℕ → Prop} : ∃ n : ℕ, p ∨ r n ∨ q ∧ n = 1 := by push ∃ n, _ guard_target =ₛ p ∨ (∃ n, r n) ∨ q ∧ True From 85ce110e6bbb05f3e9e60f6cd3c0e58cdb90c1b1 Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Mon, 6 Jul 2026 07:46:33 +0000 Subject: [PATCH 0609/1300] feat(Geometry/Manifold): C^n smoothness of the inverse of a bundle trivialization (#41280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `Bundle.Trivialization.contMDiffAt_symmL`: For a trivialization `e` of a `C^n` vector bundle `E₁ → B` and a point `x ∈ e.baseSet` the section `m ↦ e.symmL 𝕜 m` defines a `C^n` section of the hom bundle `Hom(F₁, E₁)`. We also provide a `contMDiffOn` version. This PR was prepared with assistance from Claude. --- .../Geometry/Manifold/VectorBundle/Hom.lean | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index 661dd8ab0a85c0..1ff931d7d66655 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -131,6 +131,46 @@ instance ContMDiffVectorBundle.continuousLinearMap : end +section symmL + +variable {𝕜 B F₁ : Type*} [NontriviallyNormedField 𝕜] {n : WithTop ℕ∞} + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {HB : Type*} [TopologicalSpace HB] + {IB : ModelWithCorners 𝕜 EB HB} [TopologicalSpace B] [ChartedSpace HB B] + {E₁ : B → Type*} [∀ x, AddCommGroup (E₁ x)] [∀ x, Module 𝕜 (E₁ x)] + [NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] + [TopologicalSpace (TotalSpace F₁ E₁)] [∀ x, TopologicalSpace (E₁ x)] + [∀ x, IsTopologicalAddGroup (E₁ x)] [∀ x, ContinuousSMul 𝕜 (E₁ x)] + [FiberBundle F₁ E₁] [VectorBundle 𝕜 F₁ E₁] + +/-- Let `e` be a trivialization of a `C^n` vector bundle `E₁` over `B`. Then `m ↦ e.symmL 𝕜 m` +defines a section of the bundle of continuous linear maps `F₁ →L[𝕜] E₁` over `B`, and this section +is `C^n` at any point in `e.baseSet`. -/ +lemma Bundle.Trivialization.contMDiffAt_symmL [ContMDiffVectorBundle n F₁ E₁ IB] + (e : Trivialization F₁ (TotalSpace.proj : TotalSpace F₁ E₁ → B)) [MemTrivializationAtlas e] + {x : B} (hx : x ∈ e.baseSet) : + ContMDiffAt IB (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₁)) n + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₁) m (e.symmL 𝕜 m)) x := by + have hx' : x ∈ (trivializationAt F₁ E₁ x).baseSet := mem_baseSet_trivializationAt F₁ E₁ x + refine contMDiffAt_totalSpace.mpr ⟨contMDiffAt_id, ?_⟩ + apply (contMDiffAt_coordChangeL hx hx').congr_of_eventuallyEq + filter_upwards [e.open_baseSet.mem_nhds hx, + (trivializationAt F₁ E₁ x).open_baseSet.mem_nhds hx'] with b hb hb' + ext v + simp [hom_trivializationAt_apply, ContinuousLinearMap.inCoordinates, + coordChangeL_apply' e _ ⟨hb, hb'⟩, coe_linearMapAt_of_mem _ hb', + e.symmL_apply hb, e.mk_symm hb] + +/-- Let `e` be a trivialization of a `C^n` vector bundle `E₁` over `B`. Then `m ↦ e.symmL 𝕜 m` +defines a section of the bundle of continuous linear maps `F₁ →L[𝕜] E₁` over `B`, and this section +is `C^n` on `e.baseSet`. -/ +lemma Bundle.Trivialization.contMDiffOn_symmL [ContMDiffVectorBundle n F₁ E₁ IB] + (e : Trivialization F₁ (TotalSpace.proj : TotalSpace F₁ E₁ → B)) [MemTrivializationAtlas e] : + ContMDiffOn IB (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₁)) n + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₁) m (e.symmL 𝕜 m)) e.baseSet := + fun _ hx ↦ (e.contMDiffAt_symmL hx).contMDiffWithinAt + +end symmL + section /- Declare two manifolds `B₁` and `B₂` (with models `IB₁ : HB₁ → EB₁` and `IB₂ : HB₂ → EB₂`), From a3b50ce4ec76a7409b42c8fea5801d2f0b2a5d03 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 6 Jul 2026 09:01:00 +0000 Subject: [PATCH 0610/1300] chore: remove unused `linter.deprecated` exceptions (#41398) Turns out to be all of them (this is counted as weak tech debt, so probably nice to remove even though its all deprecations) Co-authored-by: Batixx --- .../CategoryTheory/Monoidal/OfHasFiniteProducts.lean | 2 -- Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean | 1 - Mathlib/Data/Array/Defs.lean | 2 -- Mathlib/Data/Tree/Basic.lean | 10 ---------- Mathlib/Data/Tree/Get.lean | 3 --- Mathlib/Lean/Expr/ReplaceRec.lean | 2 -- Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean | 5 ----- Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean | 6 ------ Mathlib/SetTheory/Ordinal/FundamentalSequence.lean | 1 - Mathlib/SetTheory/Ordinal/Topology.lean | 10 ---------- 10 files changed, 42 deletions(-) diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index db187334c5de14..e3b93682c62958 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -181,7 +181,6 @@ variable [PreservesLimit (Functor.empty.{0} C) F] [PreservesLimitsOfShape (Discrete WalkingPair) F] set_option backward.defeqAttrib.useBackward true in -set_option linter.deprecated false in @[deprecated inferInstance (since := "2025-10-19")] instance : have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal @@ -191,7 +190,6 @@ instance : IsIso (η F) := by dsimp [η_eq]; apply instIsIsoTerminalComparison set_option backward.defeqAttrib.useBackward true in -set_option linter.deprecated false in @[deprecated inferInstance (since := "2025-10-19")] instance (X Y : C) : have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal diff --git a/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean b/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean index 007aa07a4cbc53..2bdc3a2e175c21 100644 --- a/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean +++ b/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean @@ -45,7 +45,6 @@ def treesOfNumNodesEq : ℕ → Finset (BinaryTree Unit) · simp_wf; have := fst_le ijh.2; lia · simp_wf; have := snd_le ijh.2; lia -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.treesOfNumNodesEq`. -/ @[deprecated BinaryTree.treesOfNumNodesEq (since := "2026-06-07")] abbrev _root_.Tree.treesOfNumNodesEq : ℕ → Finset (Tree Unit) := diff --git a/Mathlib/Data/Array/Defs.lean b/Mathlib/Data/Array/Defs.lean index 3b0822b90fb351..3e28203de6db36 100644 --- a/Mathlib/Data/Array/Defs.lean +++ b/Mathlib/Data/Array/Defs.lean @@ -36,8 +36,6 @@ where cyclicPermuteAux : Array α → List Nat → α → Nat → Array α let (y, a) := a.swapAt! i x cyclicPermuteAux a is y i0 -set_option linter.deprecated false - /-- Permute the array using a list of cycles. -/ @[deprecated "This is now in `Mathlib.Tactic.Translate.Reorder.permute!`" (since := "2026-03-05")] def permute! [Inhabited α] (a : Array α) (ls : List (List Nat)) : Array α := diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 2a510b039f784b..cc791f1bc9436d 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -39,12 +39,10 @@ compile_inductive% BinaryTree @[deprecated (since := "2026-06-07"), reducible] alias Tree := BinaryTree -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.nil`. -/ @[deprecated BinaryTree.nil (since := "2026-06-07")] abbrev Tree.nil.{u} {α : Type u} : Tree α := BinaryTree.nil -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.node`. -/ @[deprecated BinaryTree.node (since := "2026-06-07")] abbrev Tree.node.{u} {α : Type u} @@ -71,7 +69,6 @@ def traverse | .nil => pure nil | .node a l r => .node <$> f a <*> traverse f l <*> traverse f r -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.traverse`. -/ @[deprecated BinaryTree.traverse (since := "2026-06-07")] abbrev _root_.Tree.traverse {m : Type* → Type*} [Applicative m] {α β} (f : α → m β) @@ -85,7 +82,6 @@ def map {β} (f : α → β) : BinaryTree α → BinaryTree β | nil => nil | node a l r => node (f a) (map f l) (map f r) -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.map`. -/ @[deprecated BinaryTree.map (since := "2026-06-07")] abbrev _root_.Tree.map {α β} (f : α → β) (t : Tree α) : Tree β := BinaryTree.map f t @@ -115,7 +111,6 @@ def numNodes : BinaryTree α → ℕ | nil => 0 | node _ a b => a.numNodes + b.numNodes + 1 -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.numNodes`. -/ @[deprecated BinaryTree.numNodes (since := "2026-06-07")] abbrev _root_.Tree.numNodes {α} (t : Tree α) : ℕ := BinaryTree.numNodes t @@ -126,7 +121,6 @@ def numLeaves : BinaryTree α → ℕ | nil => 1 | node _ a b => a.numLeaves + b.numLeaves -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.numLeaves`. -/ @[deprecated BinaryTree.numLeaves (since := "2026-06-07")] abbrev _root_.Tree.numLeaves {α} (t : Tree α) : ℕ := BinaryTree.numLeaves t @@ -137,7 +131,6 @@ def height : BinaryTree α → ℕ | nil => 0 | node _ a b => max a.height b.height + 1 -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.height`. -/ @[deprecated BinaryTree.height (since := "2026-06-07")] abbrev _root_.Tree.height {α} (t : Tree α) : ℕ := BinaryTree.height t @@ -161,7 +154,6 @@ def left : BinaryTree α → BinaryTree α | nil => nil | node _ l _r => l -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.left`. -/ @[deprecated BinaryTree.left (since := "2026-06-07")] abbrev _root_.Tree.left {α} (t : Tree α) : Tree α := BinaryTree.left t @@ -172,7 +164,6 @@ def right : BinaryTree α → BinaryTree α | nil => nil | node _ _l r => r -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.right`. -/ @[deprecated BinaryTree.right (since := "2026-06-07")] abbrev _root_.Tree.right {α} (t : Tree α) : Tree α := BinaryTree.right t @@ -186,7 +177,6 @@ def unitRecOn {motive : BinaryTree Unit → Sort*} (t : BinaryTree Unit) (base : (ind : ∀ x y, motive x → motive y → motive (x △ y)) : motive t := t.recOn base fun _u ↦ ind -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.unitRecOn`. -/ @[deprecated BinaryTree.unitRecOn (since := "2026-06-07")] abbrev _root_.Tree.unitRecOn {motive : Tree Unit → Sort*} (t : Tree Unit) (base : motive nil) diff --git a/Mathlib/Data/Tree/Get.lean b/Mathlib/Data/Tree/Get.lean index 9d4468c3c8c410..b2e753efb61658 100644 --- a/Mathlib/Data/Tree/Get.lean +++ b/Mathlib/Data/Tree/Get.lean @@ -38,7 +38,6 @@ def indexOf (lt : α → α → Prop) [DecidableRel lt] (x : α) : BinaryTree α | Ordering.eq => some PosNum.one | Ordering.gt => PosNum.bit1 <$> indexOf lt x t₂ -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.indexOf`. -/ @[deprecated BinaryTree.indexOf (since := "2026-06-07")] abbrev _root_.Tree.indexOf (lt : α → α → Prop) [DecidableRel lt] (x : α) : Tree α → Option PosNum := @@ -55,7 +54,6 @@ def get : PosNum → BinaryTree α → Option α | PosNum.bit0 n, node _a t₁ _t₂ => t₁.get n | PosNum.bit1 n, node _a _t₁ t₂ => t₂.get n -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.get`. -/ @[deprecated BinaryTree.get (since := "2026-06-07")] abbrev _root_.Tree.get (n : PosNum) (t : Tree α) : Option α := @@ -66,7 +64,6 @@ if the index is invalid. See `BinaryTree.get`. -/ def getOrElse (n : PosNum) (t : BinaryTree α) (v : α) : α := (t.get n).getD v -set_option linter.deprecated false in /-- **Alias** of `BinaryTree.getOrElse`. -/ @[deprecated BinaryTree.getOrElse (since := "2026-06-07")] abbrev _root_.Tree.getOrElse (n : PosNum) (t : Tree α) (v : α) : α := diff --git a/Mathlib/Lean/Expr/ReplaceRec.lean b/Mathlib/Lean/Expr/ReplaceRec.lean index 743a71f5da04dd..57242b27344049 100644 --- a/Mathlib/Lean/Expr/ReplaceRec.lean +++ b/Mathlib/Lean/Expr/ReplaceRec.lean @@ -18,8 +18,6 @@ replacing a subexpression. We completely mimic the implementation of `Expr.repla deprecated_module (since := "2026-01-26") -set_option linter.deprecated false - @[expose] public section namespace Lean.Expr diff --git a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean index d837239375be43..b345f010b225ac 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean @@ -55,16 +55,13 @@ of an indexed set of elements, use `BilinForm.iIsOrtho`. -/ def IsOrtho (B : BilinForm R M) (x y : M) : Prop := B x y = 0 -set_option linter.deprecated false in @[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_def {B : BilinForm R M} {x y : M} : B.IsOrtho x y ↔ B x y = 0 := Iff.rfl -set_option linter.deprecated false in @[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_left (x : M) : IsOrtho B (0 : M) x := LinearMap.isOrtho_zero_left B x -set_option linter.deprecated false in @[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_right (x : M) : IsOrtho B x (0 : M) := zero_right x @@ -104,7 +101,6 @@ section variable {R₄ M₄ : Type*} [CommRing R₄] [IsDomain R₄] variable [AddCommGroup M₄] [Module R₄ M₄] {G : BilinForm R₄ M₄} -set_option linter.deprecated false in @[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_smul_left {x y : M₄} {a : R₄} (ha : a ≠ 0) : IsOrtho G (a • x) y ↔ IsOrtho G x y := by @@ -113,7 +109,6 @@ theorem isOrtho_smul_left {x y : M₄} {a : R₄} (ha : a ≠ 0) : simp only [LinearMap.smul_apply, smul_eq_mul, mul_eq_zero, or_iff_right_iff_imp] exact fun a ↦ (ha a).elim -set_option linter.deprecated false in @[deprecated "`BilinMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_smul_right {x y : M₄} {a : R₄} (ha : a ≠ 0) : IsOrtho G x (a • y) ↔ IsOrtho G x y := by diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean index 2bdabb1c709851..ac8fa0c5f91077 100644 --- a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean @@ -59,23 +59,19 @@ variable [CommSemiring R] [CommSemiring R₁] [AddCommMonoid M₁] [Module R₁ def IsOrtho (B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M) (x : M₁) (y : M₂) : Prop := B x y = 0 -set_option linter.deprecated false in @[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_def {B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M} {x y} : B.IsOrtho x y ↔ B x y = 0 := Iff.rfl -set_option linter.deprecated false in @[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_left (B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M) (x) : IsOrtho B (0 : M₁) x := by dsimp only [IsOrtho] rw [map_zero B, zero_apply] -set_option linter.deprecated false in @[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_zero_right (B : M₁ →ₛₗ[I₁] M₂ →ₛₗ[I₂] M) (x) : IsOrtho B x (0 : M₂) := map_zero (B x) -set_option linter.deprecated false in @[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem isOrtho_flip {B : M₁ →ₛₗ[I₁] M₁ →ₛₗ[I₁'] M} {x y} : B.IsOrtho x y ↔ B.flip.IsOrtho y x := by simp_rw [isOrtho_def, flip_apply] @@ -103,7 +99,6 @@ variable [Field K] [AddCommGroup V] [Module K V] [Field K₁] [AddCommGroup V₁ [Field K₂] [AddCommGroup V₂] [Module K₂ V₂] {I₁ : K₁ →+* K} {I₂ : K₂ →+* K} {I₁' : K₁ →+* K} {J₁ : K →+* K} {J₂ : K →+* K} -set_option linter.deprecated false in @[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem ortho_smul_left {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} {a : K₁} (ha : a ≠ 0) : IsOrtho B x y ↔ IsOrtho B (a • x) y := by @@ -116,7 +111,6 @@ theorem ortho_smul_left {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} trivial · exact H -set_option linter.deprecated false in @[deprecated "`LinearMap.IsOrtho` has been deprecated" (since := "2026-03-30")] theorem ortho_smul_right {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} {a : K₂} {ha : a ≠ 0} : IsOrtho B x y ↔ IsOrtho B x (a • y) := by diff --git a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean index 82968c2439dced..d97e03ca2ebe51 100644 --- a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean +++ b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean @@ -227,7 +227,6 @@ theorem exists_fundamental_sequence (a : Ordinal.{u}) : exact (wo.wf.not_lt_min {j | r j i ∧ f i ≤ f j} ⟨IsTrans.trans _ _ _ hkj hji, H⟩) hkj · rwa [bfamilyOfFamily'_typein] -set_option linter.deprecated false in @[deprecated IsFundamentalSeq.comp_isNormal (since := "2026-03-23")] theorem IsFundamentalSequence.of_isNormal {f : Ordinal.{u} → Ordinal.{u}} (hf : IsNormal f) {a o} (ha : IsSuccLimit a) {g} (hg : IsFundamentalSequence a o g) : diff --git a/Mathlib/SetTheory/Ordinal/Topology.lean b/Mathlib/SetTheory/Ordinal/Topology.lean index 263dd7e58345c2..d08298527a1674 100644 --- a/Mathlib/SetTheory/Ordinal/Topology.lean +++ b/Mathlib/SetTheory/Ordinal/Topology.lean @@ -182,34 +182,28 @@ its accumulation points below the ordinal. -/ def IsClosedBelow (S : Set Ordinal) (o : Ordinal) : Prop := IsClosed (Iio o ↓∩ S) -set_option linter.deprecated false in @[deprecated SuccOrder.accPt_principal (since := "2026-05-24")] theorem isAcc_iff (o : Ordinal) (S : Set Ordinal) : o.IsAcc S ↔ o ≠ 0 ∧ ∀ p < o, (S ∩ Ioo p o).Nonempty := by apply SuccOrder.accPt_principal.trans simp -set_option linter.deprecated false in @[deprecated SuccOrder.accPt_principal (since := "2026-05-24")] theorem IsAcc.forall_lt {o : Ordinal} {S : Set Ordinal} (h : o.IsAcc S) : ∀ p < o, (S ∩ Ioo p o).Nonempty := ((isAcc_iff _ _).mp h).2 -set_option linter.deprecated false in @[deprecated AccPt.not_isMin (since := "2026-05-24")] theorem IsAcc.pos {o : Ordinal} {S : Set Ordinal} (h : o.IsAcc S) : 0 < o := pos_iff_ne_zero.mpr ((isAcc_iff _ _).mp h).1 -set_option linter.deprecated false in @[deprecated AccPt.isSuccLimit (since := "2026-05-24")] theorem IsAcc.isSuccLimit {o : Ordinal} {S : Set Ordinal} (h : o.IsAcc S) : IsSuccLimit o := AccPt.isSuccLimit h -set_option linter.deprecated false in @[deprecated AccPt.mono (since := "2026-05-24")] theorem IsAcc.mono {o : Ordinal} {S T : Set Ordinal} (h : S ⊆ T) (ho : o.IsAcc S) : o.IsAcc T := AccPt.mono ho (monotone_principal h) -set_option linter.deprecated false in @[deprecated SuccOrder.accPt_principal (since := "2026-05-24")] theorem IsAcc.inter_Ioo_nonempty {o : Ordinal} {S : Set Ordinal} (hS : o.IsAcc S) {p : Ordinal} (hp : p < o) : (S ∩ Ioo p o).Nonempty := hS.forall_lt p hp @@ -219,18 +213,15 @@ theorem accPt_subtype {p o : Ordinal} (S : Set Ordinal) (hpo : p < o) : AccPt p (𝓟 S) ↔ AccPt ⟨p, hpo⟩ (𝓟 (Iio o ↓∩ S)) := by rw [← comap_principal, isOpen_Iio.isOpenEmbedding_subtypeVal.accPt_comap_iff] -set_option linter.deprecated false in @[deprecated isClosed_iff_accPt (since := "2026-05-24")] theorem isClosedBelow_iff {S : Set Ordinal} {o : Ordinal} : IsClosedBelow S o ↔ ∀ p < o, IsAcc p S → p ∈ S := by simp [IsClosedBelow, IsAcc, isClosed_iff_accPt, ← comap_principal, isOpen_Iio.isOpenEmbedding_subtypeVal.accPt_comap_iff] -set_option linter.deprecated false in @[deprecated isClosed_iff_accPt (since := "2026-05-24")] alias ⟨IsClosedBelow.forall_lt, _⟩ := isClosedBelow_iff -set_option linter.deprecated false in @[deprecated isClosed_sInter (since := "2026-05-24")] theorem IsClosedBelow.sInter {o : Ordinal} {S : Set (Set Ordinal)} (h : ∀ C ∈ S, IsClosedBelow C o) : IsClosedBelow (⋂₀ S) o := by @@ -238,7 +229,6 @@ theorem IsClosedBelow.sInter {o : Ordinal} {S : Set (Set Ordinal)} exact fun p plto pAcc C CmemS ↦ (h C CmemS).forall_lt p plto <| AccPt.mono pAcc (monotone_principal (sInter_subset_of_mem CmemS)) -set_option linter.deprecated false in @[deprecated isClosed_iInter (since := "2026-05-24")] theorem IsClosedBelow.iInter {ι : Type u} {f : ι → Set Ordinal} {o : Ordinal} (h : ∀ i, IsClosedBelow (f i) o) : IsClosedBelow (⋂ i, f i) o := From 7bad0c47f9226828e409e03a208340404af88111 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Mon, 6 Jul 2026 10:11:19 +0000 Subject: [PATCH 0611/1300] feat(RingTheory/Polynomial): ideal span by monic polynomial (#41156) In this PR we added some lemmas for ideal span by monic polynomial. --- Mathlib.lean | 1 + Mathlib/RingTheory/Ideal/MonicSpan.lean | 54 ++++++++++++++++++++ Mathlib/RingTheory/PrincipalIdealDomain.lean | 7 +++ 3 files changed, 62 insertions(+) create mode 100644 Mathlib/RingTheory/Ideal/MonicSpan.lean diff --git a/Mathlib.lean b/Mathlib.lean index ae8a93fa6b2aba..82604c1674a2d6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6659,6 +6659,7 @@ public import Mathlib.RingTheory.Ideal.MinimalPrime.Basic public import Mathlib.RingTheory.Ideal.MinimalPrime.Colon public import Mathlib.RingTheory.Ideal.MinimalPrime.Localization public import Mathlib.RingTheory.Ideal.MinimalPrime.Noetherian +public import Mathlib.RingTheory.Ideal.MonicSpan public import Mathlib.RingTheory.Ideal.NatInt public import Mathlib.RingTheory.Ideal.Nonunits public import Mathlib.RingTheory.Ideal.Norm.AbsNorm diff --git a/Mathlib/RingTheory/Ideal/MonicSpan.lean b/Mathlib/RingTheory/Ideal/MonicSpan.lean new file mode 100644 index 00000000000000..2b5976da9537a5 --- /dev/null +++ b/Mathlib/RingTheory/Ideal/MonicSpan.lean @@ -0,0 +1,54 @@ +/- +Copyright (c) 2025 Nailin Guan. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Nailin Guan +-/ +module + +public import Mathlib.Algebra.Polynomial.FieldDivision +public import Mathlib.Algebra.Polynomial.Lifts +public import Mathlib.RingTheory.Ideal.Quotient.Operations +public import Mathlib.RingTheory.Polynomial.Basic + +/-! + +# Lemmas for ideal in polynomial span by monic polynomial + +-/ + +@[expose] public section + +variable (R : Type*) [CommRing R] + +open Ideal + +namespace Polynomial + +lemma exists_monic_span {k : Type*} [Field k] (I : Ideal k[X]) (ne : I ≠ ⊥) : + ∃ f, f.Monic ∧ I = Ideal.span {f} := by + classical + obtain ⟨x, h, spanx⟩ := Ideal.exists_normalized_span_of_isPrincipal I + refine ⟨x, (Polynomial.normalize_eq_self_iff_monic ?_).mp h, spanx⟩ + by_contra eq0 + simp [eq0, spanx] at ne + +lemma exists_monic_span_sup_map_eq (p : Ideal R[X]) + (ism : (p.comap C).IsMaximal) (ne : p ≠ (p.comap C).map C) : + ∃ f : R[X], f.Monic ∧ p = (p.comap C).map C ⊔ Ideal.span {f} := by + let q := p.comap C + let : Field (R ⧸ q) := Ideal.Quotient.field q + have ne' : Ideal.map (mapRingHom (Ideal.Quotient.mk q)) p ≠ ⊥ := by + simp only [ne_eq, map_eq_bot_iff_le_ker, Polynomial.ker_mapRingHom, q, mk_ker] + exact not_le_of_gt (lt_of_le_of_ne Ideal.map_comap_le ne.symm) + rcases Polynomial.exists_monic_span _ ne' with ⟨y, mony, hy⟩ + have : y ∈ lifts (Ideal.Quotient.mk q) := map_surjective _ Ideal.Quotient.mk_surjective _ + rcases Polynomial.lifts_and_natDegree_eq_and_monic this mony with ⟨f, hf, deg, monf⟩ + use f, monf + trans comap (mapRingHom (Ideal.Quotient.mk q)) ((span {f}).map (mapRingHom (Ideal.Quotient.mk q))) + · rw [Ideal.map_span, coe_mapRingHom, Set.image_singleton, hf, ← hy, + Ideal.comap_map_of_surjective' _ (map_surjective _ Ideal.Quotient.mk_surjective)] + simpa [Polynomial.ker_mapRingHom, q] using Ideal.map_comap_le + · rw [Ideal.comap_map_of_surjective' _ (map_surjective _ Ideal.Quotient.mk_surjective), + sup_comm, Polynomial.ker_mapRingHom, mk_ker] + +end Polynomial diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index f9191cf7a05d5e..b0e4c092c9bd35 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -552,3 +552,10 @@ lemma span_singleton_inf_span_singleton [EuclideanDomain R] [GCDMonoid R] (n m : rw [Ideal.mem_inf] simp only [Ideal.mem_span_singleton] exact lcm_dvd_iff.symm + +lemma Ideal.exists_normalized_span_of_isPrincipal {R : Type*} [CommSemiring R] + [NormalizationMonoid R] (I : Ideal R) [I.IsPrincipal] : + ∃ x, normalize x = x ∧ I = Ideal.span {x} := by + obtain ⟨x, rfl⟩ := ‹I.IsPrincipal› + refine ⟨normalize x, normalize_idem x, le_antisymm ?_ ?_⟩ <;> + simp [Ideal.mem_span_singleton] From db5c6a66675c39afae31ba65850058b68b37909f Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Mon, 6 Jul 2026 10:36:28 +0000 Subject: [PATCH 0612/1300] fix: remove [IsMinimal R W] from HasSplitMultiplicativeReduction (#41391) Currently we have ``` class HasMultiplicativeReduction (W : WeierstrassCurve K) : Prop extends IsMinimal R W where ... ``` and ``` class HasSplitMultiplicativeReduction (W : WeierstrassCurve K) [IsMinimal R W] : Prop extends W.HasMultiplicativeReduction R where ``` and in particular the second declaration asks for `IsMinimal` but also extends the first, which already has it. This PR removes `[IsMinimal R W]` from the second declaration. --- Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean index 5dcdab295b934a..0568284fa0dca0 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean @@ -319,7 +319,7 @@ the polynomial `c₄ T ^ 2 + a₁ c₄ T - (54 b₆ - 3 b₂ b₄ + a₂ c₄)` To see how this expression arises, note that the node `(x₀, y₀)` has second order Taylor expansion `(Y - y₀)^2 + a_1(X - x₀)(Y - y₀) - (3x₀ + a_2)(X - x₀)^2` where `x₀ = (18 b₆ - b₂ b₄) / c₄`. -/ @[mk_iff] -class HasSplitMultiplicativeReduction (W : WeierstrassCurve K) [IsMinimal R W] : Prop +class HasSplitMultiplicativeReduction (W : WeierstrassCurve K) : Prop extends W.HasMultiplicativeReduction R where splitMultiplicativeReduction : letI I := W.integralModel R Splits <| .map (algebraMap R (ResidueField R)) <| From d4fe71752a9fd59672d816143c9c97eae45dc9dc Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Mon, 6 Jul 2026 11:31:06 +0000 Subject: [PATCH 0613/1300] feat: lemma `enorm_toReal` (#41386) Co-authored-by: sgouezel --- Mathlib/Analysis/Normed/Group/Real.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Analysis/Normed/Group/Real.lean b/Mathlib/Analysis/Normed/Group/Real.lean index fb729daff80fc0..4080f0f631f66d 100644 --- a/Mathlib/Analysis/Normed/Group/Real.lean +++ b/Mathlib/Analysis/Normed/Group/Real.lean @@ -104,6 +104,9 @@ lemma enorm_ofReal_of_nonneg {a : ℝ} (ha : 0 ≤ a) : ‖ENNReal.ofReal a‖ theorem enorm_eq_ofReal (hr : 0 ≤ r) : ‖r‖ₑ = .ofReal r := by rw [← ofReal_norm, norm_of_nonneg hr] +@[simp] lemma enorm_toReal {a : ℝ≥0∞} (ha : a ≠ ∞) : ‖a.toReal‖ₑ = a := by + simp [enorm_eq_ofReal, ha] + theorem enorm_eq_ofReal_abs (r : ℝ) : ‖r‖ₑ = ENNReal.ofReal |r| := by rw [← enorm_eq_ofReal (abs_nonneg _), enorm_abs] From eb56e53fe59380b78617e2a94dc4d0a479d8b9d4 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 6 Jul 2026 12:01:56 +0000 Subject: [PATCH 0614/1300] chore: remove (all) redundant `backward.privateInPublic.warn` exceptions (#41382) Removes all `set_option backward.privateInPublic.warn false in` which arent actually needed, 52/384. Co-authored-by: Batixx --- Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean | 5 ----- Mathlib/CategoryTheory/Category/Cat/Adjunction.lean | 2 -- Mathlib/CategoryTheory/Galois/EssSurj.lean | 2 -- Mathlib/CategoryTheory/Join/Basic.lean | 4 ---- Mathlib/CategoryTheory/Monoidal/Functor.lean | 1 - Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean | 6 ------ Mathlib/CategoryTheory/WithTerminal/Basic.lean | 2 -- Mathlib/CategoryTheory/WithTerminal/Cone.lean | 4 ---- Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean | 2 -- Mathlib/Data/Fintype/EquivFin.lean | 2 -- Mathlib/Data/Sym/Sym2.lean | 1 - Mathlib/GroupTheory/OreLocalization/Basic.lean | 1 - Mathlib/LinearAlgebra/TensorProduct/Pi.lean | 4 ---- Mathlib/Logic/Equiv/Multiset.lean | 2 -- Mathlib/Logic/Godel/GodelBetaFunction.lean | 3 --- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 8 -------- Mathlib/Order/DirectedInverseSystem.lean | 4 ---- Mathlib/Order/Nucleus.lean | 3 --- Mathlib/RingTheory/WittVector/Basic.lean | 2 -- Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean | 2 -- Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean | 6 ------ 21 files changed, 66 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean index 4b83ce509510f0..808bbc3b83a4c1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean @@ -384,7 +384,6 @@ variable (φ : ∀ (x : V _⦋0⦌₂), F.obj (mk x) ⟶ G.obj (mk x)) F.map (homMk e) ≫ φ y = φ x ≫ G.map (homMk e) := by cat_disch) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Constructor for natural transformations between functors from `V.HomotopyCategory`. -/ def mkNatTrans : F ⟶ G where app _ := φ _ @@ -394,7 +393,6 @@ def mkNatTrans : F ⟶ G where exact this.symm.le f (by simp) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma mkNatTrans_app_mk (v : V _⦋0⦌₂) : (mkNatTrans φ hφ).app (mk v) = φ v := rfl @@ -408,19 +406,16 @@ variable (iso : ∀ (x : V _⦋0⦌₂), F.obj (mk x) ≅ G.obj (mk x)) (iso x).hom ≫ G.map (homMk e) := by cat_disch) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Constructor for natural isomorphisms between functors from `V.HomotopyCategory`. -/ def mkNatIso : F ≅ G := NatIso.ofComponents (fun _ ↦ iso _) (fun f ↦ (mkNatTrans _ hiso).naturality f) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma mkNatIso_hom_app_mk (v : V _⦋0⦌₂) : (mkNatIso iso hiso).hom.app (mk v) = (iso v).hom := rfl set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma mkNatIso_inv_app_mk (v : V _⦋0⦌₂) : (mkNatIso iso hiso).inv.app (mk v) = (iso v).inv := rfl diff --git a/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean b/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean index 1605de86087424..d7c20dd499c2c1 100644 --- a/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean +++ b/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean @@ -32,7 +32,6 @@ variable (X : Type u) (C : Cat) set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private def typeToCatObjectsAdjHomEquiv : (typeToCat.obj X ⟶ C) ≃ (X ⟶ Cat.objects.obj C) where toFun F := ↾fun x ↦ F.toFunctor.obj ⟨x⟩ invFun f := (Discrete.functor f).toCatHom @@ -41,7 +40,6 @@ private def typeToCatObjectsAdjHomEquiv : (typeToCat.obj X ⟶ C) ≃ (X ⟶ Cat simp) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private def typeToCatObjectsAdjCounitApp : (Cat.objects ⋙ typeToCat).obj C ⥤ C where obj := Discrete.as map := eqToHom ∘ Discrete.eq_of_hom diff --git a/Mathlib/CategoryTheory/Galois/EssSurj.lean b/Mathlib/CategoryTheory/Galois/EssSurj.lean index 3e47e452a8da4c..8ee8df169abd5d 100644 --- a/Mathlib/CategoryTheory/Galois/EssSurj.lean +++ b/Mathlib/CategoryTheory/Galois/EssSurj.lean @@ -67,8 +67,6 @@ private local instance fintypeQuotientStabilizer {X : Type*} [MulAction G X] Fintype (G ⧸ (MulAction.stabilizer (G) x)) := fintypeQuotient ⟨MulAction.stabilizer (G) x, stabilizer_isOpen (G) x⟩ -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- If `X` is a finite discrete `G`-set, it can be written as the finite disjoint union of quotients of the form `G ⧸ Uᵢ` for open subgroups `(Uᵢ)`. Note that this is simply the decomposition into orbits. -/ diff --git a/Mathlib/CategoryTheory/Join/Basic.lean b/Mathlib/CategoryTheory/Join/Basic.lean index a8999e2aa636d9..cdb00e70c5b904 100644 --- a/Mathlib/CategoryTheory/Join/Basic.lean +++ b/Mathlib/CategoryTheory/Join/Basic.lean @@ -308,22 +308,18 @@ variable {F : C ⋆ D ⥤ E} {F' : C ⋆ D ⥤ E} whiskerLeft (Prod.fst C D) αₗ ≫ whiskerRight (edgeTransform C D) F' := by cat_disch) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma mkNatTrans_app_left (c : C) : (mkNatTrans αₗ αᵣ h).app (left c) = αₗ.app c := rfl set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma mkNatTrans_app_right (d : D) : (mkNatTrans αₗ αᵣ h).app (right d) = αᵣ.app d := rfl set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma whiskerLeft_inclLeft_mkNatTrans : whiskerLeft (inclLeft C D) (mkNatTrans αₗ αᵣ h) = αₗ := rfl set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma whiskerLeft_inclRight_mkNatTrans : whiskerLeft (inclRight C D) (mkNatTrans αₗ αᵣ h) = αᵣ := rfl diff --git a/Mathlib/CategoryTheory/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Functor.lean index 875e6bb82a1c97..41ce57b77f91ea 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor.lean @@ -184,7 +184,6 @@ variable {F : C ⥤ D} cat_disch) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- A constructor for lax monoidal functors whose axioms are described by `tensorHom` instead of `whiskerLeft` and `whiskerRight`. diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean index 7a8ec10f7c0a7a..54e667a5967a55 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean @@ -64,8 +64,6 @@ corresponds to the shift by `-n` on `C`. -/ scoped instance : HasShift Cᵒᵖ ℤ := inferInstanceAs <| HasShift (OppositeShiftAux C) ℤ -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in instance [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] (n : ℤ) : (shiftFunctor Cᵒᵖ n).Additive := inferInstanceAs <| (shiftFunctor (OppositeShiftAux C) n).Additive @@ -74,8 +72,6 @@ end Opposite open Opposite -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- The shift functor on the opposite category identifies to the opposite functor of a shift functor on the original category. -/ def shiftFunctorOpIso (n m : ℤ) (hnm : n + m = 0) : @@ -85,8 +81,6 @@ def shiftFunctorOpIso (n m : ℤ) (hnm : n + m = 0) : variable {C} -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in lemma shiftFunctorZero_op_hom_app (X : Cᵒᵖ) : (shiftFunctorZero Cᵒᵖ ℤ).hom.app X = (shiftFunctorOpIso C 0 0 (zero_add 0)).hom.app X ≫ ((shiftFunctorZero C ℤ).inv.app X.unop).op := rfl diff --git a/Mathlib/CategoryTheory/WithTerminal/Basic.lean b/Mathlib/CategoryTheory/WithTerminal/Basic.lean index f53ba944c15c1d..f4986a2e85a677 100644 --- a/Mathlib/CategoryTheory/WithTerminal/Basic.lean +++ b/Mathlib/CategoryTheory/WithTerminal/Basic.lean @@ -427,7 +427,6 @@ instance subsingleton_hom {J : Type*} : Quiver.IsThin (WithTerminal (Discrete J) · rfl set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Implementation detail for `widePullbackShapeEquiv`. -/ @[simps apply] private def widePullbackShapeEquivObj {J : Type*} : @@ -442,7 +441,6 @@ private def widePullbackShapeEquivObj {J : Type*} : right_inv x := by cases x <;> simp set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Implementation detail for `widePullbackShapeEquiv`. -/ private def widePullbackShapeEquivMap {J : Type*} (x y : WidePullbackShape J) : (x ⟶ y) ≃ (widePullbackShapeEquivObj x ⟶ widePullbackShapeEquivObj y) where diff --git a/Mathlib/CategoryTheory/WithTerminal/Cone.lean b/Mathlib/CategoryTheory/WithTerminal/Cone.lean index fc3486ac2b7e43..f654502bc2cc63 100644 --- a/Mathlib/CategoryTheory/WithTerminal/Cone.lean +++ b/Mathlib/CategoryTheory/WithTerminal/Cone.lean @@ -63,7 +63,6 @@ def liftFromOverComp : liftFromOver.obj (K ⋙ Over.post F) ≅ liftFromOver.obj set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- A cone of a functor `K : J ⥤ Over X` consists of an object of `Over X`, together with morphisms. This same object is a cone of the extended functor `liftFromOver.obj K : WithTerminal J ⥤ C`. -/ @@ -87,7 +86,6 @@ private def coneLift : Cone K ⥤ Cone (liftFromOver.obj K) where } set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- This is the inverse of the previous construction: a cone of an extended functor `liftFromOver.obj K : WithTerminal J ⥤ C` consists of an object of `C`, together with morphisms. This same object is a cone of the original functor `K : J ⥤ Over X`. -/ @@ -177,7 +175,6 @@ def liftFromUnderComp : liftFromUnder.obj (K ⋙ Under.post F) ≅ liftFromUnder set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- A cocone of a functor `K : J ⥤ Under X` consists of an object of `Under X`, together with morphisms. This same object is a cocone of the extended functor `liftFromUnder.obj K : WithInitial J ⥤ C`. -/ @@ -201,7 +198,6 @@ private def coconeLift : Cocone K ⥤ Cocone (liftFromUnder.obj K) where } set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- This is the inverse of the previous construction: a cocone of an extended functor `liftFromUnder.obj K : WithInitial J ⥤ C` consists of an object of `C`, together with morphisms. This same object is a cocone of the original functor `K : J ⥤ Under X`. -/ diff --git a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean index 0522e1ad32621b..ecfe13df569322 100644 --- a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean +++ b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean @@ -377,8 +377,6 @@ def mu : IncidenceAlgebra 𝕜 α := variable {𝕜} {a b : α} -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in lemma mu_apply (a b : α) : mu 𝕜 a b = if a = b then 1 else -∑ x ∈ Ico a b, mu 𝕜 a x := by rw [mu, coe_mk, muFun_apply, sum_attach] diff --git a/Mathlib/Data/Fintype/EquivFin.lean b/Mathlib/Data/Fintype/EquivFin.lean index 9a81740a1fb9f1..5d004ad9f28f5f 100644 --- a/Mathlib/Data/Fintype/EquivFin.lean +++ b/Mathlib/Data/Fintype/EquivFin.lean @@ -523,7 +523,6 @@ instance [Infinite α] : Infinite (Equiv.Perm α) := by namespace Infinite set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private noncomputable def natEmbeddingAux (α : Type*) [Infinite α] : ℕ → α | n => letI := Classical.decEq α @@ -533,7 +532,6 @@ private noncomputable def natEmbeddingAux (α : Type*) [Infinite α] : ℕ → Multiset.mem_range.1).toFinset) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private theorem natEmbeddingAux_injective (α : Type*) [Infinite α] : Function.Injective (natEmbeddingAux α) := by rintro m n h diff --git a/Mathlib/Data/Sym/Sym2.lean b/Mathlib/Data/Sym/Sym2.lean index a70c5c2b5cff24..3e617857b0a269 100644 --- a/Mathlib/Data/Sym/Sym2.lean +++ b/Mathlib/Data/Sym/Sym2.lean @@ -849,7 +849,6 @@ section SymEquiv attribute [local instance] List.Vector.Perm.isSetoid set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private def fromVector : List.Vector α 2 → α × α | ⟨[a, b], _⟩ => (a, b) diff --git a/Mathlib/GroupTheory/OreLocalization/Basic.lean b/Mathlib/GroupTheory/OreLocalization/Basic.lean index 0eb66b6a45fb46..41d9c575b2b182 100644 --- a/Mathlib/GroupTheory/OreLocalization/Basic.lean +++ b/Mathlib/GroupTheory/OreLocalization/Basic.lean @@ -213,7 +213,6 @@ theorem lift₂Expand_of {C : Sort*} {P : X → S → X → S → C} rfl set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[to_additive] private abbrev smul' (r₁ : R) (s₁ : S) (r₂ : X) (s₂ : S) : X[S⁻¹] := oreNum r₁ s₂ • r₂ /ₒ (oreDenom r₁ s₂ * s₁) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean index e897dd3604541f..99efa2312c3080 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean @@ -131,15 +131,11 @@ def piScalarRightHomBil : N →ₗ[S] (ι → R) →ₗ[R] (ι → N) where rw [← IsScalarTower.smul_assoc, _root_.Algebra.smul_def, mul_comm, mul_smul] simp -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- For any `R`-module `N` and index type `ι`, there is a natural linear map `N ⊗[R] (ι → R) →ₗ (ι → N)`. This map is an isomorphism if `ι` is finite. -/ def piScalarRightHom : N ⊗[R] (ι → R) →ₗ[S] (ι → N) := AlgebraTensorModule.lift <| piScalarRightHomBil R S N ι -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[simp] lemma piScalarRightHom_tmul (x : N) (f : ι → R) : piScalarRightHom R S N ι (x ⊗ₜ f) = (fun j ↦ f j • x) := by diff --git a/Mathlib/Logic/Equiv/Multiset.lean b/Mathlib/Logic/Equiv/Multiset.lean index 8b6a18b68938b8..b8eba524c061a9 100644 --- a/Mathlib/Logic/Equiv/Multiset.lean +++ b/Mathlib/Logic/Equiv/Multiset.lean @@ -41,8 +41,6 @@ def encodeMultiset (s : Multiset α) : ℕ := def decodeMultiset (n : ℕ) : Option (Multiset α) := ((↑) : List α → Multiset α) <$> decode (α := List α) n -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- If `α` is encodable, then so is `Multiset α`. -/ instance _root_.Multiset.encodable : Encodable (Multiset α) := ⟨encodeMultiset, decodeMultiset, fun s => by simp [encodeMultiset, decodeMultiset, encodek]⟩ diff --git a/Mathlib/Logic/Godel/GodelBetaFunction.lean b/Mathlib/Logic/Godel/GodelBetaFunction.lean index 852e64c446e3c2..caa46d6f34c582 100644 --- a/Mathlib/Logic/Godel/GodelBetaFunction.lean +++ b/Mathlib/Logic/Godel/GodelBetaFunction.lean @@ -64,11 +64,9 @@ lemma coprime_mul_succ {n m a} (ha : m - n ∣ a) : Coprime (n * a + 1) (m * a + variable {m : ℕ} set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private def supOfSeq (a : Fin m → ℕ) : ℕ := max m (Finset.sup .univ a) + 1 set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private def coprimes (a : Fin m → ℕ) : Fin m → ℕ := fun i => (i + 1) * (supOfSeq a)! + 1 set_option backward.privateInPublic true in @@ -83,7 +81,6 @@ lemma coprimes_lt (a : Fin m → ℕ) (i) : a i < coprimes a i := by open scoped Function in -- required for scoped `on` notation set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private lemma pairwise_coprime_coprimes (a : Fin m → ℕ) : Pairwise (Coprime on coprimes a) := by intro i j hij wlog! ltij : i < j diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index 72ca1eecf4560c..1cdba1a8f7a375 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -260,8 +260,6 @@ theorem countable_leftLim_ne [OrderTopology R] (f : StieltjesFunction R) : /-! ### The outer measure associated to a Stieltjes function -/ -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in open scoped Classical in /-- Length of an interval. This is the largest monotone function which correctly measures all intervals. -/ @@ -272,8 +270,6 @@ def length (s : Set R) : ℝ≥0∞ := -- when measuring the size of a set (the set `{x}` will have measure `0` in our construction). else ⨅ (a) (b) (_ : s \ botSet ⊆ Ioc a b), ofReal (f b - f a) -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in lemma length_eq [Nonempty R] (s : Set R) : f.length s = ⨅ (a) (b) (_ : s \ botSet ⊆ Ioc a b), ofReal (f b - f a) := by simp [length] @@ -309,8 +305,6 @@ theorem length_mono {s₁ s₂ : Set R} (h : s₁ ⊆ s₂) : f.length s₁ ≤ simp only [length_eq] exact iInf_mono fun a => biInf_mono fun b h' => (sdiff_subset_sdiff_left h).trans h' -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in theorem length_sdiff_botSet {s : Set R} : f.length (s \ botSet) = f.length s := by rcases isEmpty_or_nonempty R with hR | hR · simp [length_eq_of_isEmpty] @@ -329,8 +323,6 @@ theorem outer_le_length (s : Set R) : f.outer s ≤ f.length s := variable [OrderTopology R] [CompactIccSpace R] -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- If a compact interval `[a, b]` is covered by a union of open interval `(c i, d i)`, then `f b - f a ≤ ∑ f (d i) - f (c i)`. This is an auxiliary technical statement to prove the same statement for half-open intervals, the point of the current statement being that one can use diff --git a/Mathlib/Order/DirectedInverseSystem.lean b/Mathlib/Order/DirectedInverseSystem.lean index 9e545d0689ec88..76c35452acdb11 100644 --- a/Mathlib/Order/DirectedInverseSystem.lean +++ b/Mathlib/Order/DirectedInverseSystem.lean @@ -206,7 +206,6 @@ variable {C : Sort*} (ih : ∀ i, F₁ i → F₂ i → C) (compat : ∀ i j h x y, ih i x y = ih j (f₁ i j h x) (f₂ i j h y)) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private noncomputable def lift₂Aux (z : Σ i, F₁ i) (w : Σ i, F₂ i) : {x : C // ∀ i (hzi : z.1 ≤ i) (hwi : w.1 ≤ i), x = ih i (f₁ _ _ hzi z.2) (f₂ _ _ hwi w.2)} := by choose j hzj hwj using exists_ge_ge z.1 w.1 @@ -227,7 +226,6 @@ protected noncomputable def lift₂ (z : DirectLimit F₁ f₁) (w : DirectLimit ← map_map' _ hx hji, jeq, ← map_map' _ hz hki, ← keq, map_map'] set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in theorem lift₂_def₂ (x : Σ i, F₁ i) (y : Σ i, F₂ i) (i) (hxi : x.1 ≤ i) (hyi : y.1 ≤ i) : DirectLimit.lift₂ f₁ f₂ ih compat ⟦x⟧ ⟦y⟧ = ih i (f₁ _ _ hxi x.2) (f₂ _ _ hyi y.2) := (lift₂Aux _ _ _ compat _ _).2 .. @@ -491,7 +489,6 @@ variable [WellFoundedLT ι] [SuccOrder ι] [InverseSystem f] (equivLim : ∀ i, IsSuccPrelimit i → {e : F i ≃ limit f i // ∀ x l, (e x).1 l = f l.2.le x}) set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private noncomputable def globalEquivAux (i : ι) : PEquivOn f (fun i hi ↦ (equivSucc i hi).1) (Iic i) := SuccOrder.prelimitRecOn i @@ -505,7 +502,6 @@ noncomputable def globalEquiv (i : ι) : F i ≃ piLT X i := (globalEquivAux equivSucc equivLim i).equiv ⟨i, le_rfl⟩ set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in theorem globalEquiv_naturality ⦃i j⦄ (h : i ≤ j) (x : F j) : letI e := globalEquiv equivSucc equivLim e i (f h x) = piLTProj h (e j x) := by diff --git a/Mathlib/Order/Nucleus.lean b/Mathlib/Order/Nucleus.lean index 4dd02640cf4b47..746286c2ba8b0a 100644 --- a/Mathlib/Order/Nucleus.lean +++ b/Mathlib/Order/Nucleus.lean @@ -239,7 +239,6 @@ lemma mem_range : x ∈ range n ↔ n x = x where mpr h := ⟨x, h⟩ set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- See `Nucleus.giRestrict` for the public-facing version. -/ private def giAux (n : Nucleus X) : GaloisInsertion (rangeFactorization n) Subtype.val where choice x hx := ⟨x, mem_range.2 <| hx.antisymm n.le_apply⟩ @@ -252,7 +251,6 @@ set_option backward.privateInPublic.warn false in instance : CompleteLattice (range n) := n.giAux.liftCompleteLattice set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in instance range.instFrameMinimalAxioms : Frame.MinimalAxioms (range n) where inf_sSup_le_iSup_inf a s := by simp_rw [← Subtype.coe_le_coe, iSup_subtype', iSup, sSup, n.giAux.gc.u_inf] @@ -264,7 +262,6 @@ instance range.instFrameMinimalAxioms : Frame.MinimalAxioms (range n) where instance : Frame (range n) := .ofMinimalAxioms range.instFrameMinimalAxioms set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Restrict a nucleus to its range. -/ @[simps] def restrict (n : Nucleus X) : FrameHom X (range n) where toFun := rangeFactorization n diff --git a/Mathlib/RingTheory/WittVector/Basic.lean b/Mathlib/RingTheory/WittVector/Basic.lean index 995bbfe8d97924..50fafa7aa18b02 100644 --- a/Mathlib/RingTheory/WittVector/Basic.lean +++ b/Mathlib/RingTheory/WittVector/Basic.lean @@ -240,8 +240,6 @@ private local instance comm_ring_aux₂ : CommRing (𝕎 (MvPolynomial R ℤ)) : (mapFun.zero _) (mapFun.one _) (mapFun.add _) (mapFun.mul _) (mapFun.neg _) (mapFun.sub _) (mapFun.nsmul _) (mapFun.zsmul _) (mapFun.pow _) (mapFun.natCast _) (mapFun.intCast _) -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- The commutative ring structure on `𝕎 R`. -/ instance : CommRing (𝕎 R) := (mapFun.surjective _ <| counit_surjective _).commRing (mapFun <| MvPolynomial.counit _) diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean index 4d7a993258824a..3f5841d4654d60 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean @@ -233,8 +233,6 @@ additive groups. -/] def ofFiniteGrpHom {G H : FiniteGrp.{u}} (f : G ⟶ H) : ofFiniteGrp G ⟶ ofFiniteGrp H := ConcreteCategory.ofHom ⟨f.hom.hom, by fun_prop⟩ -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in @[to_additive] instance : HasForget₂ FiniteGrp ProfiniteGrp where forget₂ := diff --git a/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean b/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean index 9d5128d1e3cc04..f30003724c53e3 100644 --- a/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean +++ b/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean @@ -131,29 +131,24 @@ private theorem candidates_refl (fA : f ∈ candidates X Y) : f (x, x) = 0 := fA.1.2 x set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private theorem candidates_nonneg (fA : f ∈ candidates X Y) : 0 ≤ f (x, y) := by grind [candidates_symm, candidates_triangle] set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private theorem candidates_dist_inl (fA : f ∈ candidates X Y) (x y : X) : f (inl x, inl y) = dist x y := fA.1.1.1.1.1 x y set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private theorem candidates_dist_inr (fA : f ∈ candidates X Y) (x y : Y) : f (inr x, inr y) = dist x y := fA.1.1.1.1.2 x y set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in private theorem candidates_le_maxVar (fA : f ∈ candidates X Y) : f (x, y) ≤ maxVar X Y := fA.2 x y set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- candidates are bounded by `maxVar X Y` -/ private theorem candidates_dist_bound (fA : f ∈ candidates X Y) : ∀ {x y : X ⊕ Y}, f (x, y) ≤ maxVar X Y * dist x y @@ -185,7 +180,6 @@ private theorem candidates_dist_bound (fA : f ∈ candidates X Y) : _ ≤ maxVar X Y * dist (inr x) (inr y) := by gcongr; exact one_le_maxVar X Y set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in /-- Technical lemma to prove that candidates are Lipschitz -/ private theorem candidates_lipschitz_aux (fA : f ∈ candidates X Y) : f (x, y) - f (z, t) ≤ 2 * maxVar X Y * dist (x, y) (z, t) := From 62aaa5c959a8c5cf491a22073ce59e97f7de5595 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 12:48:48 +0000 Subject: [PATCH 0615/1300] chore(CategoryTheory/ComposableArrows/Basic): localize use of the `backward.privateInPublic` option (#41407) Extracted from #41395 by `@felixpernegger`. Co-authored-by: felixpernegger <188575194+felixpernegger@users.noreply.github.com> --- .../ComposableArrows/Basic.lean | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index b2a4d03fec39b2..03e8c22e8eb212 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -44,8 +44,6 @@ set_option backward.defeqAttrib.useBackward true @[expose] public section -set_option backward.privateInPublic true - /-! New `simprocs` that run even in `dsimp` have caused breakages in this file. @@ -548,9 +546,11 @@ def homMkSucc (α : F.obj' 0 ⟶ G.obj' 0) (β : F.δ₀ ⟶ G.δ₀) variable (α : F.obj' 0 ⟶ G.obj' 0) (β : F.δ₀ ⟶ G.δ₀) (w : F.map' 0 1 ≫ app' β 0 = α ≫ G.map' 0 1 := by cat_disch) +set_option backward.privateInPublic true in @[simp] lemma homMkSucc_app_zero : (homMkSucc α β w).app 0 = α := rfl +set_option backward.privateInPublic true in @[simp] lemma homMkSucc_app_succ (i : ℕ) (hi : i + 1 < n + 1 + 1) : (homMkSucc α β w).app ⟨i + 1, hi⟩ = app' β i := rfl @@ -614,18 +614,23 @@ variable (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1 := by cat_disch) (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2 := by cat_disch) +set_option backward.privateInPublic true in /-- Constructor for morphisms in `ComposableArrows C 2`. -/ def homMk₂ : f ⟶ g := homMkSucc app₀ (homMk₁ app₁ app₂ w₁) w₀ +set_option backward.privateInPublic true in @[simp] lemma homMk₂_app_zero : (homMk₂ app₀ app₁ app₂ w₀ w₁).app 0 = app₀ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₂_app_one : (homMk₂ app₀ app₁ app₂ w₀ w₁).app 1 = app₁ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₂_app_two : (homMk₂ app₀ app₁ app₂ w₀ w₁).app 2 = app₂ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₂_app_two' : (homMk₂ app₀ app₁ app₂ w₀ w₁).app ⟨2, by valid⟩ = app₂ := rfl @@ -687,19 +692,24 @@ variable (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2 := by cat_disch) (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3 := by cat_disch) +set_option backward.privateInPublic true in /-- Constructor for morphisms in `ComposableArrows C 3`. -/ def homMk₃ : f ⟶ g := homMkSucc app₀ (homMk₂ app₁ app₂ app₃ w₁ w₂) w₀ +set_option backward.privateInPublic true in @[simp] lemma homMk₃_app_zero : (homMk₃ app₀ app₁ app₂ app₃ w₀ w₁ w₂).app 0 = app₀ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₃_app_one : (homMk₃ app₀ app₁ app₂ app₃ w₀ w₁ w₂).app 1 = app₁ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₃_app_two : (homMk₃ app₀ app₁ app₂ app₃ w₀ w₁ w₂).app ⟨2, by valid⟩ = app₂ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₃_app_three : (homMk₃ app₀ app₁ app₂ app₃ w₀ w₁ w₂).app ⟨3, by valid⟩ = app₃ := rfl @@ -754,23 +764,29 @@ variable (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3 := by cat_disch) (w₃ : f.map' 3 4 ≫ app₄ = app₃ ≫ g.map' 3 4 := by cat_disch) +set_option backward.privateInPublic true in /-- Constructor for morphisms in `ComposableArrows C 4`. -/ def homMk₄ : f ⟶ g := homMkSucc app₀ (homMk₃ app₁ app₂ app₃ app₄ w₁ w₂ w₃) w₀ +set_option backward.privateInPublic true in @[simp] lemma homMk₄_app_zero : (homMk₄ app₀ app₁ app₂ app₃ app₄ w₀ w₁ w₂ w₃).app 0 = app₀ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₄_app_one : (homMk₄ app₀ app₁ app₂ app₃ app₄ w₀ w₁ w₂ w₃).app 1 = app₁ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₄_app_two : (homMk₄ app₀ app₁ app₂ app₃ app₄ w₀ w₁ w₂ w₃).app ⟨2, by valid⟩ = app₂ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₄_app_three : (homMk₄ app₀ app₁ app₂ app₃ app₄ w₀ w₁ w₂ w₃).app ⟨3, by valid⟩ = app₃ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₄_app_four : (homMk₄ app₀ app₁ app₂ app₃ app₄ w₀ w₁ w₂ w₃).app ⟨4, by valid⟩ = app₄ := rfl @@ -835,27 +851,34 @@ variable (w₃ : f.map' 3 4 ≫ app₄ = app₃ ≫ g.map' 3 4 := by cat_disch) (w₄ : f.map' 4 5 ≫ app₅ = app₄ ≫ g.map' 4 5 := by cat_disch) +set_option backward.privateInPublic true in /-- Constructor for morphisms in `ComposableArrows C 5`. -/ def homMk₅ : f ⟶ g := homMkSucc app₀ (homMk₄ app₁ app₂ app₃ app₄ app₅ w₁ w₂ w₃ w₄) w₀ +set_option backward.privateInPublic true in @[simp] lemma homMk₅_app_zero : (homMk₅ app₀ app₁ app₂ app₃ app₄ app₅ w₀ w₁ w₂ w₃ w₄).app 0 = app₀ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₅_app_one : (homMk₅ app₀ app₁ app₂ app₃ app₄ app₅ w₀ w₁ w₂ w₃ w₄).app 1 = app₁ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₅_app_two : (homMk₅ app₀ app₁ app₂ app₃ app₄ app₅ w₀ w₁ w₂ w₃ w₄).app ⟨2, by valid⟩ = app₂ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₅_app_three : (homMk₅ app₀ app₁ app₂ app₃ app₄ app₅ w₀ w₁ w₂ w₃ w₄).app ⟨3, by valid⟩ = app₃ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₅_app_four : (homMk₅ app₀ app₁ app₂ app₃ app₄ app₅ w₀ w₁ w₂ w₃ w₄).app ⟨4, by valid⟩ = app₄ := rfl +set_option backward.privateInPublic true in @[simp] lemma homMk₅_app_five : (homMk₅ app₀ app₁ app₂ app₃ app₄ app₅ w₀ w₁ w₂ w₃ w₄).app ⟨5, by valid⟩ = app₅ := rfl From cef1e7de8e91a5dc9e89e484964f0735d048e3b4 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Mon, 6 Jul 2026 13:36:48 +0000 Subject: [PATCH 0616/1300] feat: lemmas about equality of `EqvGen` (#40792) I've named the lemmas about `Subrelation` with `_le_`, so that if/when #30526 lands, the names can be kept. --- Mathlib/Logic/Relation.lean | 88 ++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 953a9a444d0101..abd4bda0904338 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -56,6 +56,10 @@ open Function variable {α β γ δ ε ζ : Type*} +theorem Subrelation.antisymm {r r' : α → α → Prop} (h1 : Subrelation r r') (h2 : Subrelation r' r) : + r = r' := + funext₂ fun _ _ => propext ⟨h1, h2⟩ + section NeImp variable {r : α → α → Prop} @@ -380,7 +384,7 @@ instance stdSymm [Std.Symm r] : Std.Symm (ReflGen r) where @[deprecated (since := "2026-06-10")] alias symmetric := stdSymm -instance [IsTrans α r] : IsTrans α (ReflGen r) where +instance [IsTrans α r] : IsPreorder α (ReflGen r) where trans a b c h₁ h₂ := by obtain (rfl | h₂) := h₂ · exact h₁ @@ -583,7 +587,10 @@ instance stdSymm [Std.Symm r] : Std.Symm (TransGen r) where @[deprecated (since := "2026-06-10")] alias symmetric := stdSymm -instance [Std.Refl r] : Std.Refl (TransGen r) where +instance : IsTrans α (TransGen r) where + trans _ _ _ := TransGen.trans + +instance [Std.Refl r] : IsPreorder α (TransGen r) where refl x := .single (refl x) end TransGen @@ -622,9 +629,6 @@ end SymmGen section TransGen -instance : IsTrans α (TransGen r) := - ⟨@TransGen.trans α r⟩ - instance : Trans (TransGen r) r (TransGen r) := ⟨TransGen.tail⟩ @@ -727,15 +731,13 @@ instance : Trans r (ReflTransGen r) (ReflTransGen r) := instance : Trans (ReflTransGen r) r (ReflTransGen r) := ⟨tail⟩ -instance : Std.Refl (ReflTransGen r) := - ⟨@ReflTransGen.refl α r⟩ +instance : IsPreorder α (ReflTransGen r) where + refl := @ReflTransGen.refl α r + trans := @ReflTransGen.trans α r @[deprecated inferInstance (since := "2026-03-27")] theorem reflexive_reflTransGen : Std.Refl (ReflTransGen r) := inferInstance -instance : IsTrans α (ReflTransGen r) := - ⟨@ReflTransGen.trans α r⟩ - @[deprecated inferInstance (since := "2026-02-21")] theorem transitive_reflTransGen : IsTrans α (ReflTransGen r) := inferInstance @@ -796,6 +798,8 @@ variable (r) theorem is_equivalence : Equivalence (@EqvGen α r) := Equivalence.mk EqvGen.refl (EqvGen.symm _ _) (EqvGen.trans _ _ _) +instance : IsEquiv α (EqvGen r) := is_equivalence _ |>.isEquiv + /-- `EqvGen.setoid r` is the setoid generated by a relation `r`. The motivation for this definition is that `Quot r` behaves like `Quotient (EqvGen.setoid r)`, @@ -812,6 +816,68 @@ theorem mono {r p : α → α → Prop} (hrp : r ≤ p) : EqvGen r ≤ EqvGen p | symm a b _ ih => exact EqvGen.symm _ _ ih | trans a b c _ _ hab hbc => exact EqvGen.trans _ _ _ hab hbc +lemma eqvGen_le {r r' : α → α → Prop} [IsEquiv α r'] (h : Subrelation r r') : + Subrelation (EqvGen r) r' + | _, _, .refl _ => _root_.refl _ + | _, _, .symm _ _ hxy => _root_.symm (eqvGen_le h hxy :) + | _, _, .trans _ _ _ hxy hyz => _root_.trans (eqvGen_le h hxy :) (eqvGen_le h hyz :) + | _, _, .rel _ _ hab => h hab + +lemma eqvGen_mono {r r' : α → α → Prop} (h : Subrelation r r') : Subrelation (EqvGen r) (EqvGen r') + | _, _, .refl _ => .refl _ + | _, _, .symm _ _ hxy => .symm _ _ (eqvGen_mono h hxy) + | _, _, .trans _ _ _ hxy hyz => .trans _ _ _ (eqvGen_mono h hxy) (eqvGen_mono h hyz) + | _, _, .rel _ _ hab => .rel _ _ (h hab) + +lemma reflGen_le_eqvGen : Subrelation (ReflGen r) (EqvGen r) + | _, _, .refl => .refl _ + | _, _, .single h => .rel _ _ h + +lemma symmGen_le_eqvGen : Subrelation (SymmGen r) (EqvGen r) + | _, _, .inl h => .rel _ _ h + | _, _, .inr h => _root_.symm <| .rel _ _ h + +lemma transGen_le_eqvGen : Subrelation (TransGen r) (EqvGen r) := by + intro _ _ h + induction h using TransGen.trans_induction_on with + | trans _ _ h1 h2 => exact _root_.trans h1 h2 + | single h => exact .rel _ _ h + +lemma reflTransGen_le_eqvGen : Subrelation (ReflTransGen r) (EqvGen r) := by + intro _ _ h + induction h using ReflTransGen.trans_induction_on with + | refl => exact .refl _ + | trans _ _ h1 h2 => exact _root_.trans h1 h2 + | single h => exact .rel _ _ h + +@[simp, grind =] +lemma eqvGen_reflGen : EqvGen (ReflGen r) = EqvGen r := + Subrelation.antisymm + (eqvGen_le (reflGen_le_eqvGen _)) (eqvGen_mono (.single)) + +@[simp, grind =] +lemma eqvGen_transGen : EqvGen (TransGen r) = EqvGen r := + Subrelation.antisymm + (eqvGen_le (transGen_le_eqvGen _)) (eqvGen_mono .single) + +@[simp, grind =] +lemma eqvGen_symmGen : EqvGen (SymmGen r) = EqvGen r := + Subrelation.antisymm + (eqvGen_le (symmGen_le_eqvGen _)) (eqvGen_mono .inl) + +@[simp, grind =] +lemma eqvGen_reflTransGen : EqvGen (ReflTransGen r) = EqvGen r := + Subrelation.antisymm + (eqvGen_le (reflTransGen_le_eqvGen _)) (eqvGen_mono .single) + +@[grind =] +lemma eqvGen_eq_reflTransGen [Std.Symm r] : EqvGen r = ReflTransGen r := + have : IsEquiv α (ReflTransGen r) := ⟨⟩ + Subrelation.antisymm (eqvGen_le .single) (reflTransGen_le_eqvGen _) + +lemma reflTransGen_symmGen : ReflTransGen (SymmGen r) = EqvGen r := by + rw [← eqvGen_eq_reflTransGen, eqvGen_symmGen] + end EqvGen /-- The join of a relation on a single type is a new relation for which @@ -873,7 +939,7 @@ theorem isTrans_join [IsTrans α r] (h : ∀ a b c, r a b → r a c → Join r b @[deprecated (since := "2026-02-21")] alias transitive_join := isTrans_join -theorem equivalence_join [Std.Refl r] [IsTrans α r] (h : ∀ a b c, r a b → r a c → Join r b c) : +theorem equivalence_join [IsPreorder α r] (h : ∀ a b c, r a b → r a c → Join r b c) : Equivalence (Join r) := ⟨Join.refl.refl, Join.symm.symm _ _, isTrans_join h |>.trans _ _ _⟩ From 9ef14c7b82f8a45f8dfc03dace26d6bb25023bac Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 6 Jul 2026 15:50:26 +0000 Subject: [PATCH 0617/1300] feat: use `LE.le` for subset relation in `Set`, `Finset`, `PSet`, `ZFSet`, `Class` (#32983) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR uses `@[use_set_notation_for_order]` in `Set`, `Finset`, `PSet`, `ZFSet` and `Class`. So, for these types, we will write `⊆`, while the underlying constant is `LE.le`. Some notes: - The idea is to later extend this feature to other set notation constants, such as union/intersection. - Dot notation on the `HasSubset.Subset` namespace now doesn't work anymore, and the names need to be put in the `LE.le` namespace instead. - Various `simp` and `gcongr` tags needed to be removed/updated as a result of this change. See also https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/Any.20infimum.20based.20version.20of.20.60OmegaCompletePartialOrder.60.3F/near/579333629 --- .../Algebra/Algebra/Subalgebra/Lattice.lean | 2 +- Mathlib/Algebra/Group/Indicator.lean | 2 +- .../Algebra/Group/Pointwise/Finset/Basic.lean | 8 +- .../Algebra/Group/Pointwise/Set/Basic.lean | 4 +- .../Action/Pointwise/Finset.lean | 6 +- .../GroupWithZero/Action/Pointwise/Set.lean | 6 +- Mathlib/Algebra/MvPolynomial/Monad.lean | 2 +- .../Algebra/Order/Monoid/Unbundled/Pow.lean | 6 +- .../AlgebraicTopology/SimplicialSet/Horn.lean | 2 +- Mathlib/Analysis/LocallyConvex/WeakSpace.lean | 2 +- .../Analysis/Normed/Group/FunctionSeries.lean | 3 +- .../SpecialFunctions/Log/Summable.lean | 3 +- Mathlib/CategoryTheory/CofilteredSystem.lean | 2 +- .../Presentable/CardinalDirectedPoset.lean | 3 +- Mathlib/CategoryTheory/Topos/Sheaf.lean | 3 +- .../Enumerative/Partition/GenFun.lean | 4 +- Mathlib/Combinatorics/Hall/Basic.lean | 1 - Mathlib/Combinatorics/Matroid/Basic.lean | 2 +- .../Combinatorics/Matroid/Constructions.lean | 2 +- Mathlib/Combinatorics/Matroid/Dual.lean | 3 +- .../Combinatorics/Matroid/Rank/Cardinal.lean | 2 +- .../SetFamily/AhlswedeZhang.lean | 2 +- .../SetFamily/KruskalKatona.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 11 +- .../Combinatorics/SimpleGraph/Ends/Defs.lean | 4 +- Mathlib/Data/Finset/BooleanAlgebra.lean | 14 +- Mathlib/Data/Finset/Defs.lean | 39 +--- Mathlib/Data/Finset/Filter.lean | 2 +- Mathlib/Data/Finset/Image.lean | 1 - Mathlib/Data/Finset/Lattice/Basic.lean | 30 +-- Mathlib/Data/Finset/Option.lean | 2 +- Mathlib/Data/Finset/Powerset.lean | 8 +- Mathlib/Data/Finset/SDiff.lean | 8 +- Mathlib/Data/Finset/Sups.lean | 2 +- Mathlib/Data/Fintype/Card.lean | 3 +- Mathlib/Data/Multiset/ZeroCons.lean | 3 +- Mathlib/Data/Set/Basic.lean | 51 +---- Mathlib/Data/Set/Card.lean | 4 +- Mathlib/Data/Set/Defs.lean | 6 +- Mathlib/Data/Set/Disjoint.lean | 1 - Mathlib/Data/Set/Finite/Basic.lean | 2 +- Mathlib/Data/Set/FiniteExhaustion.lean | 2 +- Mathlib/Data/Set/Insert.lean | 5 +- Mathlib/Data/Set/Notation.lean | 2 +- Mathlib/Data/Set/Semiring.lean | 2 +- Mathlib/Data/Set/Sups.lean | 4 +- Mathlib/Data/SetLike/Basic.lean | 1 + Mathlib/Dynamics/Ergodic/Ergodic.lean | 2 +- Mathlib/Dynamics/FixedPoints/Prufer.lean | 2 +- .../VectorBundle/FiberwiseLinear.lean | 2 +- Mathlib/GroupTheory/CosetCover.lean | 2 +- Mathlib/GroupTheory/GroupAction/Blocks.lean | 6 +- Mathlib/Lean/Expr/ExtraRecognizers.lean | 3 +- .../AffineSpace/Simplex/Basic.lean | 2 +- Mathlib/Logic/Equiv/PartialEquiv.lean | 2 +- .../MeasureTheory/Covering/LiminfLimsup.lean | 8 +- .../Function/AEEqOfIntegral.lean | 2 +- .../Integral/DominatedConvergence.lean | 2 +- .../Integral/IntegralEqImproper.lean | 2 +- .../MeasurableSpace/CountablyGenerated.lean | 2 +- Mathlib/MeasureTheory/Measure/AEDisjoint.lean | 2 +- .../Measure/Decomposition/RadonNikodym.lean | 2 +- .../MeasureTheory/Measure/MeasureSpace.lean | 6 +- .../Measure/MeasureSpaceDef.lean | 2 +- Mathlib/MeasureTheory/Measure/Prokhorov.lean | 2 +- Mathlib/MeasureTheory/Measure/Regular.lean | 2 +- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 3 +- .../Measure/Typeclasses/Finite.lean | 2 +- .../Measure/Typeclasses/SFinite.lean | 2 +- Mathlib/MeasureTheory/SetSemiring.lean | 6 +- .../Variation/Semivariation.lean | 4 +- Mathlib/NumberTheory/WellApproximable.lean | 6 +- Mathlib/Order/Birkhoff.lean | 6 +- Mathlib/Order/BooleanAlgebra/Set.lean | 33 +-- Mathlib/Order/Bounds/Basic.lean | 9 +- Mathlib/Order/Defs/PartialOrder.lean | 3 + Mathlib/Order/Filter/AtTopBot/Finset.lean | 2 +- Mathlib/Order/Filter/Basic.lean | 6 +- Mathlib/Order/Filter/CountableInter.lean | 2 +- Mathlib/Order/Filter/Ker.lean | 2 +- Mathlib/Order/Heyting/Basic.lean | 2 +- Mathlib/Order/Interval/Finset/Defs.lean | 2 +- Mathlib/Order/LiminfLimsup.lean | 2 +- Mathlib/Order/PrimeSeparator.lean | 6 +- Mathlib/Order/RelClasses.lean | 209 +++++------------- Mathlib/Probability/Process/HittingTime.lean | 4 +- .../TranscendenceBasis.lean | 4 +- .../Polynomial/Cyclotomic/Eval.lean | 2 +- Mathlib/RingTheory/Spectrum/Prime/Module.lean | 2 +- Mathlib/SetTheory/ZFC/Basic.lean | 17 +- Mathlib/SetTheory/ZFC/Class.lean | 4 +- Mathlib/SetTheory/ZFC/Ordinal.lean | 2 +- Mathlib/SetTheory/ZFC/PSet.lean | 28 +-- Mathlib/Tactic/SetNotationForOrder.lean | 115 +++++++++- .../Algebra/InfiniteSum/Constructions.lean | 5 +- .../Algebra/InfiniteSum/SummationFilter.lean | 2 +- .../Nonarchimedean/TotallyDisconnected.lean | 2 +- .../Category/TopCat/Limits/Konig.lean | 2 +- .../Topology/Compactness/SigmaCompact.lean | 2 +- Mathlib/Topology/ExtremallyDisconnected.lean | 4 +- Mathlib/Topology/Instances/CantorSet.lean | 1 - Mathlib/Topology/MetricSpace/Ultra/Basic.lean | 6 +- Mathlib/Topology/Order/HullKernel.lean | 2 +- .../Semicontinuity/Hemicontinuity.lean | 4 +- .../Topology/Separation/PerfectlyNormal.lean | 2 +- Mathlib/Topology/Separation/Profinite.lean | 2 +- Mathlib/Topology/Sets/OpenCover.lean | 5 +- Mathlib/Topology/Sets/Opens.lean | 3 +- Mathlib/Topology/UniformSpace/Basic.lean | 3 +- Mathlib/Topology/UrysohnsLemma.lean | 4 +- MathlibTest/SetNotationForOrder.lean | 22 +- 111 files changed, 411 insertions(+), 477 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean b/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean index 6766d6e4b61206..0e4d16ce2a3182 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean @@ -882,7 +882,7 @@ theorem ext_of_adjoin_eq_top {s : Set A} (h : adjoin R s = ⊤) ⦃φ₁ φ₂ : theorem eqOn_adjoin_iff {φ ψ : A →ₐ[R] B} {s : Set A} : Set.EqOn φ ψ (adjoin R s) ↔ Set.EqOn φ ψ s := by have (S : Set A) : S ≤ equalizer φ ψ ↔ Set.EqOn φ ψ S := Iff.rfl - simp only [← this, Set.le_eq_subset, SetLike.coe_subset_coe, adjoin_le_iff] + simp only [← this, SetLike.coe_subset_coe, adjoin_le_iff] theorem adjoin_ext {s : Set A} ⦃φ₁ φ₂ : adjoin R s →ₐ[R] B⦄ (h : ∀ x hx, φ₁ ⟨x, subset_adjoin hx⟩ = φ₂ ⟨x, subset_adjoin hx⟩) : φ₁ = φ₂ := diff --git a/Mathlib/Algebra/Group/Indicator.lean b/Mathlib/Algebra/Group/Indicator.lean index 5ab0f2aa2210dd..9466e061e14c3a 100644 --- a/Mathlib/Algebra/Group/Indicator.lean +++ b/Mathlib/Algebra/Group/Indicator.lean @@ -209,7 +209,7 @@ lemma mulSupport_subset_subsingleton_of_disjoint_on_mulSupport [One β] {s : γ (fun d ↦ (s d).mulIndicator f i).mulSupport ⊆ {j} := by suffices ∀ j', j' ≠ j → {i} ⊆ s j → {i} ⊆ s j' → {i} ⊆ mulSupport f → False by by_contra; aesop intro j' h hj hj' hi - simp only [Pairwise, Disjoint, Set.le_eq_subset, Set.subset_inter_iff] at hs + simp only [Pairwise, Disjoint, Set.subset_inter_iff] at hs simpa using hs h ⟨hj', hi⟩ ⟨hj, hi⟩ end One diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index d2652c3e4c35e3..bd48fb945910d2 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean @@ -385,7 +385,7 @@ theorem Nonempty.of_mul_right : (s * t).Nonempty → t.Nonempty := theorem singleton_mul_singleton (a b : α) : ({a} : Finset α) * {b} = {a * b} := image₂_singleton -@[to_additive (attr := mono, gcongr)] +@[to_additive] theorem mul_subset_mul : s₁ ⊆ s₂ → t₁ ⊆ t₂ → s₁ * t₁ ⊆ s₂ * t₂ := image₂_subset @@ -822,8 +822,8 @@ scoped[Pointwise] attribute [instance] Finset.monoid Finset.addMonoid protected lemma pow_right_monotone (hs : 1 ∈ s) : Monotone (s ^ ·) := pow_right_monotone <| one_subset.2 hs -@[to_additive (attr := gcongr)] -lemma pow_subset_pow_left (hst : s ⊆ t) : s ^ n ⊆ t ^ n := subset_of_le (pow_left_mono n hst) +@[to_additive] +lemma pow_subset_pow_left (hst : s ⊆ t) : s ^ n ⊆ t ^ n := pow_left_mono n hst @[to_additive] lemma pow_subset_pow_right (hs : 1 ∈ s) (hmn : m ≤ n) : s ^ m ⊆ s ^ n := @@ -839,7 +839,7 @@ lemma subset_pow (hs : 1 ∈ s) (hn : n ≠ 0) : s ⊆ s ^ n := by @[to_additive] lemma pow_subset_pow_mul_of_sq_subset_mul (hst : s ^ 2 ⊆ t * s) (hn : n ≠ 0) : - s ^ n ⊆ t ^ (n - 1) * s := subset_of_le (pow_le_pow_mul_of_sq_le_mul hst hn) + s ^ n ⊆ t ^ (n - 1) * s := pow_le_pow_mul_of_sq_le_mul hst hn @[to_additive (attr := simp) nsmul_empty] lemma empty_pow (hn : n ≠ 0) : (∅ : Finset α) ^ n = ∅ := match n with | n + 1 => by simp [pow_succ] diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean index 8b833f8c4dbe32..2a809154e412cf 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean @@ -354,7 +354,7 @@ theorem singleton_mul : {a} * t = (a * ·) '' t := theorem singleton_mul_singleton : ({a} : Set α) * {b} = {a * b} := image2_singleton -@[to_additive (attr := mono, gcongr)] +@[to_additive] theorem mul_subset_mul : s₁ ⊆ t₁ → s₂ ⊆ t₂ → s₁ * s₂ ⊆ t₁ * t₂ := image2_subset @@ -642,7 +642,7 @@ scoped[Pointwise] attribute [instance] Set.monoid Set.addMonoid protected lemma pow_right_monotone (hs : 1 ∈ s) : Monotone (s ^ ·) := pow_right_monotone <| one_subset.2 hs -@[to_additive (attr := gcongr)] +@[to_additive] lemma pow_subset_pow_left (hst : s ⊆ t) : s ^ n ⊆ t ^ n := pow_left_mono _ hst @[to_additive] diff --git a/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Finset.lean b/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Finset.lean index 0e73dec4faf8b2..ca5bd298c3f3ef 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Finset.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Finset.lean @@ -110,7 +110,7 @@ lemma mem_inv_smul_finset_iff₀ (ha : a ≠ 0) : b ∈ a⁻¹ • s ↔ a • b @[simp] lemma smul_finset_subset_smul_finset_iff₀ (ha : a ≠ 0) : a • s ⊆ a • t ↔ s ⊆ t := - show Units.mk0 a ha • _ ⊆ _ ↔ _ from smul_finset_subset_smul_finset_iff + show Units.mk0 a ha • s ⊆ _ ↔ _ from smul_finset_subset_smul_finset_iff theorem pairwiseDisjoint_smul_iff₀ {s : Set α} {t : Finset β} (hs : ∀ a ∈ s, a ≠ 0) : s.PairwiseDisjoint (· • t) ↔ (s ×ˢ t : Set (α × β)).InjOn fun p => p.1 • p.2 := by @@ -118,10 +118,10 @@ theorem pairwiseDisjoint_smul_iff₀ {s : Set α} {t : Finset β} (hs : ∀ a exact Set.pairwiseDisjoint_image_right_iff (fun a ha => MulAction.injective₀ (hs a ha)) lemma smul_finset_subset_iff₀ (ha : a ≠ 0) : a • s ⊆ t ↔ s ⊆ a⁻¹ • t := - show Units.mk0 a ha • _ ⊆ _ ↔ _ from smul_finset_subset_iff + show Units.mk0 a ha • s ⊆ _ ↔ _ from smul_finset_subset_iff lemma subset_smul_finset_iff₀ (ha : a ≠ 0) : s ⊆ a • t ↔ a⁻¹ • s ⊆ t := - show _ ⊆ Units.mk0 a ha • _ ↔ _ from subset_smul_finset_iff + show _ ⊆ Units.mk0 a ha • t ↔ _ from subset_smul_finset_iff lemma smul_finset_inter₀ (ha : a ≠ 0) : a • (s ∩ t) = a • s ∩ a • t := image_inter _ _ <| MulAction.injective₀ ha diff --git a/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean b/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean index 24e1a716ec73cd..d38334edd8b231 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean @@ -142,13 +142,13 @@ lemma preimage_smul_inv₀ (ha : a ≠ 0) (t : Set β) : (fun x ↦ a⁻¹ • x @[simp] lemma smul_set_subset_smul_set_iff₀ (ha : a ≠ 0) {A B : Set β} : a • A ⊆ a • B ↔ A ⊆ B := - show Units.mk0 a ha • _ ⊆ _ ↔ _ from smul_set_subset_smul_set_iff + show Units.mk0 a ha • A ⊆ _ ↔ _ from smul_set_subset_smul_set_iff lemma smul_set_subset_iff₀ (ha : a ≠ 0) {A B : Set β} : a • A ⊆ B ↔ A ⊆ a⁻¹ • B := - show Units.mk0 a ha • _ ⊆ _ ↔ _ from smul_set_subset_iff_subset_inv_smul_set + show Units.mk0 a ha • A ⊆ _ ↔ _ from smul_set_subset_iff_subset_inv_smul_set lemma subset_smul_set_iff₀ (ha : a ≠ 0) {A B : Set β} : A ⊆ a • B ↔ a⁻¹ • A ⊆ B := - show _ ⊆ Units.mk0 a ha • _ ↔ _ from subset_smul_set_iff + show _ ⊆ Units.mk0 a ha • B ↔ _ from subset_smul_set_iff lemma smul_set_inter₀ (ha : a ≠ 0) : a • (s ∩ t) = a • s ∩ a • t := show Units.mk0 a ha • _ = _ from smul_set_inter diff --git a/Mathlib/Algebra/MvPolynomial/Monad.lean b/Mathlib/Algebra/MvPolynomial/Monad.lean index 3669cfe626dccc..7dc05a1dfde106 100644 --- a/Mathlib/Algebra/MvPolynomial/Monad.lean +++ b/Mathlib/Algebra/MvPolynomial/Monad.lean @@ -310,7 +310,7 @@ theorem vars_bind₁ [DecidableEq τ] (f : σ → MvPolynomial τ R) (φ : MvPol (C (coeff d φ)).vars ∪ (∏ i ∈ d.support, f i ^ d i).vars := vars_mul _ _ _ ≤ (∏ i ∈ d.support, f i ^ d i).vars := by - simp only [Finset.empty_union, vars_C, Finset.le_iff_subset, Finset.Subset.refl] + simp only [Finset.empty_union, vars_C, Finset.Subset.refl] _ ≤ d.support.biUnion fun i : σ => vars (f i ^ d i) := vars_prod _ _ ≤ d.support.biUnion fun i : σ => (f i).vars := ?_ apply Finset.biUnion_mono diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index a4dcd4ab0cb008..1206a324df55b2 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean @@ -62,7 +62,8 @@ variable [MulLeftMono M] {a : M} {n : ℕ} theorem pow_right_monotone (ha : 1 ≤ a) : Monotone fun n : ℕ ↦ a ^ n := monotone_nat_of_le_succ fun n ↦ by rw [pow_succ]; exact le_mul_of_one_le_right' ha -@[to_additive (attr := gcongr) nsmul_le_nsmul_left] +-- `gcongr low` so that we prefer `Set.pow_subset_pow` and `Finset.pow_subset_pow` +@[to_additive (attr := gcongr low) nsmul_le_nsmul_left] theorem pow_le_pow_right' {n m : ℕ} (ha : 1 ≤ a) (h : n ≤ m) : a ^ n ≤ a ^ m := pow_right_monotone ha h @@ -173,7 +174,8 @@ theorem Monotone.pow_const {f : β → M} (hf : Monotone f) : ∀ n : ℕ, Monot @[to_additive nsmul_right_mono] theorem pow_left_mono (n : ℕ) : Monotone fun a : M => a ^ n := monotone_id.pow_const _ -@[to_additive (attr := gcongr)] +-- `gcongr low` so that we prefer `Set.pow_subset_pow` and `Finset.pow_subset_pow` +@[to_additive (attr := gcongr low)] lemma pow_le_pow {a b : M} (hab : a ≤ b) (ht : 1 ≤ b) {m n : ℕ} (hmn : m ≤ n) : a ^ m ≤ b ^ n := (pow_le_pow_left' hab _).trans (pow_le_pow_right' ht hmn) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index f1a7b2397732c7..a828db88171e27 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -136,7 +136,7 @@ lemma subcomplex_le_horn_iff {n : ℕ} lemma face_le_horn_iff {n : ℕ} (S : Finset (Fin (n + 2))) (j : Fin (n + 2)) : stdSimplex.face.{u} S ≤ Λ[n + 1, j] ↔ S ≠ .univ ∧ S ≠ {j}ᶜ := by rw [subcomplex_le_horn_iff, stdSimplex.face_le_face_iff, ← not_iff_not] - simp only [Finset.le_eq_subset, Decidable.not_not, ne_eq, not_and_or] + simp only [Decidable.not_not, ne_eq, not_and_or] refine ⟨fun h ↦ ?_, by aesop⟩ rw [← Finset.compl_subset_compl, compl_compl, Finset.subset_singleton_iff, Finset.compl_eq_empty_iff] at h diff --git a/Mathlib/Analysis/LocallyConvex/WeakSpace.lean b/Mathlib/Analysis/LocallyConvex/WeakSpace.lean index b0dcd35f036b92..f9a6c9e251bbe5 100644 --- a/Mathlib/Analysis/LocallyConvex/WeakSpace.lean +++ b/Mathlib/Analysis/LocallyConvex/WeakSpace.lean @@ -90,7 +90,7 @@ theorem LinearEquiv.image_closure_of_convex {s : Set E} (hs : Convex ℝ s) (e : (he₂ : ∀ f : StrongDual 𝕜 E, Continuous (e.symm.dualMap f)) : e '' (closure s) = closure (e '' s) := by refine le_antisymm ((e : E →ₗ[𝕜] F).image_closure_of_convex hs he₁) ?_ - simp only [Set.le_eq_subset, ← Set.image_subset_image_iff e.symm.injective] + simp only [← Set.image_subset_image_iff e.symm.injective] simpa [Set.image_image] using (e.symm : F →ₗ[𝕜] E).image_closure_of_convex (hs.linear_image (e : E →ₗ[𝕜] F)) he₂ diff --git a/Mathlib/Analysis/Normed/Group/FunctionSeries.lean b/Mathlib/Analysis/Normed/Group/FunctionSeries.lean index 74303e41c4617a..4fcb532af051f8 100644 --- a/Mathlib/Analysis/Normed/Group/FunctionSeries.lean +++ b/Mathlib/Analysis/Normed/Group/FunctionSeries.lean @@ -59,8 +59,7 @@ theorem tendstoUniformlyOn_tsum_of_cofinite_eventually {ι : Type*} {f : ι → classical refine tendstoUniformlyOn_iff.2 fun ε εpos => ?_ have := (tendsto_order.1 (tendsto_tsum_compl_atTop_zero u)).2 _ εpos - simp only [gt_iff_lt, - eventually_atTop, Finset.le_eq_subset] at * + simp only [eventually_atTop] at * obtain ⟨t, ht⟩ := this rw [eventually_iff_exists_mem] at hfu obtain ⟨N, hN, HN⟩ := hfu diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean b/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean index 337abef1252e48..60d8611ab55778 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean @@ -173,8 +173,7 @@ lemma multipliable_one_add_of_summable [CompleteSpace R] obtain ⟨r₁, hr₁, s₁, hs₁⟩ := (multipliable_norm_one_add_of_summable_norm hf).eventually_bounded_finsetProd obtain ⟨s₂, hs₂⟩ := prod_vanishing_of_summable_norm hf (show 0 < ε / (2 * r₁) by positivity) - simp only [unconditional, Filter.mem_map, mem_atTop_sets, le_eq_subset, - Set.mem_preimage] + simp only [unconditional, Filter.mem_map, mem_atTop_sets, Set.mem_preimage] let s := s₁ ∪ s₂ -- The idea here is that if `s` is a large enough finset, then the product over `s` is bounded -- by some `r`, and the product over finsets disjoint from `s` is within `ε / (2 * r)` of 1. diff --git a/Mathlib/CategoryTheory/CofilteredSystem.lean b/Mathlib/CategoryTheory/CofilteredSystem.lean index e1efcaed5e6314..3d73003635fa6c 100644 --- a/Mathlib/CategoryTheory/CofilteredSystem.lean +++ b/Mathlib/CategoryTheory/CofilteredSystem.lean @@ -239,7 +239,7 @@ theorem isMittagLeffler_of_exists_finite_range rintro _ ⟨⟨k', g'⟩, rfl⟩ hl refine (eq_of_le_of_not_lt hl ?_).ge have := hmin _ ⟨k', g', (m.finite_toSet.subset <| hm.substr hl).coe_toFinset⟩ - rwa [Finset.lt_iff_ssubset, ← Finset.coe_ssubset, Set.Finite.coe_toFinset, hm] at this + rwa [← Finset.coe_ssubset, Set.Finite.coe_toFinset, hm] at this /-- The subfunctor of `F` obtained by restricting to the eventual range at each index. -/ @[simps obj map] diff --git a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean index b662c5e2dd2dd2..d4745dd6b9f4a7 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean @@ -292,7 +292,6 @@ instance : IsCardinalFiltered (Subtype (J.PropSetWithTop κ')) κ' := hasCardinalLT_union hκ' (hasCardinalLT_iUnion _ hK (fun k ↦ (α k).property.left)) (hasCardinalLT_of_finite _ _ hκ'), by simp⟩, fun k ↦ ?_⟩ rw [Subtype.mk_le_mk] - simp only [Set.le_eq_subset] exact subset_trans (Set.subset_iUnion (fun i ↦ (α i).1) k) Set.subset_union_left) instance : IsFiltered (Subtype (J.PropSetWithTop κ')) := @@ -393,7 +392,7 @@ instance : IsCardinalFiltered (Subtype J.PropSet) κ := · have hκ : Cardinal.aleph0 ≤ κ := Cardinal.IsRegular.aleph0_le Fact.out exact hasCardinalLT_union hκ (hasCardinalLT_iUnion _ hK (fun k ↦ (α k).2.1)) (hasCardinalLT_of_finite _ _ hκ) - · simp only [← Subtype.coe_le_coe, Set.le_eq_subset] + · simp only [← Subtype.coe_le_coe] exact subset_trans (Set.subset_iUnion_of_subset k (subset_refl _)) Set.subset_union_left ) instance : IsFiltered (Subtype J.PropSet) := isFiltered_of_isCardinalFiltered _ κ diff --git a/Mathlib/CategoryTheory/Topos/Sheaf.lean b/Mathlib/CategoryTheory/Topos/Sheaf.lean index 54c0cc73f139f5..3260f5e1bd332a 100644 --- a/Mathlib/CategoryTheory/Topos/Sheaf.lean +++ b/Mathlib/CategoryTheory/Topos/Sheaf.lean @@ -179,8 +179,7 @@ to the (closed) sieve on X where `f : Y → X` is in the sieve iff def χ (m : F ⟶ G) [Mono m] : G ⟶ Sheaf.Ω J where hom := (closedSieves J).lift (Presheaf.χ m.hom) (by intro X - simp only [Subfunctor.range_obj, closedSieves_obj, Set.le_iff_subset, - Set.range_subset_iff] + simp only [Subfunctor.range_obj, closedSieves_obj, Set.range_subset_iff] exact J.isClosed_χ_app_apply_of_isSheaf_of_isSeparated m.hom ((isSheaf_iff_isSheaf_of_type _ _).mp F.property) ((isSheaf_iff_isSheaf_of_type _ _).mp G.property).isSeparated _) diff --git a/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean b/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean index 15d1857dae5a36..1501e34ebc3410 100644 --- a/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean +++ b/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean @@ -182,9 +182,9 @@ theorem hasProd_genFun (f : ℕ → ℕ → R) : rw [coeff_genFun, coeff_prod] refine (sum_of_injOn toFinsuppAntidiag (toFinsuppAntidiag_injective d).injOn ?_ ?_ ?_).symm · intro p _ - exact mem_of_subset (finsuppAntidiag_mono hs.le _) p.toFinsuppAntidiag_mem_finsuppAntidiag + exact mem_of_subset (finsuppAntidiag_mono hs _) p.toFinsuppAntidiag_mem_finsuppAntidiag · exact fun g hg hg' ↦ aux_prod_coeff_eq_zero_of_notMem_range f (by simp) hg (by simpa using hg') - · exact fun p _ ↦ aux_prod_f_eq_prod_coeff f p hs.le (by simp) + · exact fun p _ ↦ aux_prod_f_eq_prod_coeff f p hs (by simp) theorem multipliable_genFun (f : ℕ → ℕ → R) : Multipliable fun i ↦ (1 : R⟦X⟧) + ∑' j, f (i + 1) (j + 1) • X ^ ((i + 1) * (j + 1)) := diff --git a/Mathlib/Combinatorics/Hall/Basic.lean b/Mathlib/Combinatorics/Hall/Basic.lean index 5d7cb118a5f2c8..7d0a04f1b1a91b 100644 --- a/Mathlib/Combinatorics/Hall/Basic.lean +++ b/Mathlib/Combinatorics/Hall/Basic.lean @@ -138,7 +138,6 @@ theorem Finset.all_card_le_biUnion_card_iff_exists_injective {ι : Type u} {α : intro i i' have subi : ({i} : Finset ι) ⊆ {i, i'} := by simp have subi' : ({i'} : Finset ι) ⊆ {i, i'} := by simp - rw [← Finset.le_iff_subset] at subi subi' simp only rw [← hu (CategoryTheory.homOfLE subi).op, ← hu (CategoryTheory.homOfLE subi').op] let uii' := u (Opposite.op ({i, i'} : Finset ι)) diff --git a/Mathlib/Combinatorics/Matroid/Basic.lean b/Mathlib/Combinatorics/Matroid/Basic.lean index cff431de2d345c..b0f254be394168 100644 --- a/Mathlib/Combinatorics/Matroid/Basic.lean +++ b/Mathlib/Combinatorics/Matroid/Basic.lean @@ -532,7 +532,7 @@ theorem indep_iff : M.Indep I ↔ ∃ B, M.IsBase B ∧ I ⊆ B := M.indep_iff' (I := I) theorem setOf_indep_eq (M : Matroid α) : {I | M.Indep I} = lowerClosure ({B | M.IsBase B}) := by - simp_rw [indep_iff, lowerClosure, LowerSet.coe_mk, mem_setOf, le_eq_subset] + simp_rw [indep_iff, lowerClosure, LowerSet.coe_mk, mem_setOf] theorem Indep.exists_isBase_superset (hI : M.Indep I) : ∃ B, M.IsBase B ∧ I ⊆ B := indep_iff.1 hI diff --git a/Mathlib/Combinatorics/Matroid/Constructions.lean b/Mathlib/Combinatorics/Matroid/Constructions.lean index 2005f3215fa937..acd87f98101488 100644 --- a/Mathlib/Combinatorics/Matroid/Constructions.lean +++ b/Mathlib/Combinatorics/Matroid/Constructions.lean @@ -122,7 +122,7 @@ theorem Finite.loopyOn_finite (hE : E.Finite) : Matroid.Finite (loopyOn E) := exact fun _ h _ ↦ h theorem empty_isBase_iff : M.IsBase ∅ ↔ M = loopyOn M.E := by - simp only [isBase_iff_maximal_indep, Maximal, empty_indep, le_eq_subset, empty_subset, + simp only [isBase_iff_maximal_indep, Maximal, empty_indep, empty_subset, subset_empty_iff, true_implies, true_and, ext_iff_indep, loopyOn_ground, loopyOn_indep_iff] exact ⟨fun h I _ ↦ ⟨@h _, fun hI ↦ by simp [hI]⟩, fun h I hI ↦ (h hI.subset_ground).1 hI⟩ diff --git a/Mathlib/Combinatorics/Matroid/Dual.lean b/Mathlib/Combinatorics/Matroid/Dual.lean index 07d0612b5c919b..00b03e6b085eda 100644 --- a/Mathlib/Combinatorics/Matroid/Dual.lean +++ b/Mathlib/Combinatorics/Matroid/Dual.lean @@ -229,7 +229,8 @@ theorem Indep.coindep (hI : M.Indep I) : M✶.Coindep I := dual_coindep_iff.2 hI theorem coindep_iff_exists' : M.Coindep X ↔ (∃ B, M.IsBase B ∧ B ⊆ M.E \ X) ∧ X ⊆ M.E := by - simp_rw [Coindep, dual_indep_iff_exists', and_comm (a := _ ⊆ _), and_congr_left_iff, subset_sdiff] + simp_rw [Coindep, dual_indep_iff_exists', and_comm (a := (_ : Set α) ⊆ _), and_congr_left_iff, + subset_sdiff] exact fun _ ↦ ⟨fun ⟨B, hB, hXB⟩ ↦ ⟨B, hB, hB.subset_ground, hXB.symm⟩, fun ⟨B, hB, _, hBX⟩ ↦ ⟨B, hB, hBX.symm⟩⟩ diff --git a/Mathlib/Combinatorics/Matroid/Rank/Cardinal.lean b/Mathlib/Combinatorics/Matroid/Rank/Cardinal.lean index a7b3dbadf85647..c50053c421f371 100644 --- a/Mathlib/Combinatorics/Matroid/Rank/Cardinal.lean +++ b/Mathlib/Combinatorics/Matroid/Rank/Cardinal.lean @@ -121,7 +121,7 @@ theorem cRk_le_cardinalMk (M : Matroid α) (X : Set α) : M.cRk X ≤ #X := @[simp] theorem cRank_restrict (M : Matroid α) (X : Set α) : (M ↾ X).cRank = M.cRk X := rfl theorem cRk_mono (M : Matroid α) : Monotone M.cRk := by - simp only [Monotone, le_eq_subset, cRk_le_iff] + simp only [Monotone, cRk_le_iff] intro X Y hXY I hIX obtain ⟨J, hJ, hIJ⟩ := hIX.indep.subset_isBasis'_of_subset (hIX.subset.trans hXY) exact (mk_le_mk_of_subset hIJ).trans hJ.cardinalMk_le_cRk diff --git a/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean b/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean index ac0a357e9bf3c3..e1010540aa8921 100644 --- a/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean +++ b/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean @@ -387,7 +387,7 @@ variable [Nonempty α] (card α - #(truncatedSup {s} t) : ℚ) / ((card α - #t) * (card α).choose #t) = if t ⊆ s then (card α - #s : ℚ) / ((card α - #t) * (card α).choose #t) else 0 := by rintro t - simp_rw [truncatedSup_singleton, le_iff_subset] + simp_rw [truncatedSup_singleton] split_ifs <;> simp simp_rw [← sub_eq_of_eq_add (Fintype.sum_div_mul_card_choose_card α), eq_sub_iff_add_eq, ← eq_sub_iff_add_eq', supSum, ← sum_sub_distrib, ← sub_div] diff --git a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean index 90c8e76eee6c17..080e8e056f9e95 100644 --- a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean +++ b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean @@ -109,7 +109,7 @@ protected lemma IsInitSeg.shadow [Finite α] (h₁ : IsInitSeg 𝒜 r) : IsInitS obtain rfl | hr := Nat.eq_zero_or_pos r · have : 𝒜 ⊆ {∅} := fun s hs ↦ by rw [mem_singleton, ← Finset.card_eq_zero]; exact h₁.1 hs have := shadow_monotone this - simp only [subset_empty, le_eq_subset, shadow_singleton_empty] at this + simp only [subset_empty, shadow_singleton_empty] at this simp [this] obtain rfl | h𝒜 := 𝒜.eq_empty_or_nonempty · simp diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 7f274aa1ba3bcc..10e5a526660762 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -484,13 +484,9 @@ alias _root_.Sym2.IsDiag.not_mem_edgeSet := not_mem_edgeSet_of_isDiag theorem edgeSet_inj : G₁.edgeSet = G₂.edgeSet ↔ G₁ = G₂ := (edgeSetEmbedding V).eq_iff_eq -@[simp] -theorem edgeSet_subset_edgeSet : edgeSet G₁ ⊆ edgeSet G₂ ↔ G₁ ≤ G₂ := - (edgeSetEmbedding V).le_iff_le +theorem edgeSet_subset_edgeSet : edgeSet G₁ ⊆ edgeSet G₂ ↔ G₁ ≤ G₂ := by simp -@[simp] -theorem edgeSet_ssubset_edgeSet : edgeSet G₁ ⊂ edgeSet G₂ ↔ G₁ < G₂ := - (edgeSetEmbedding V).lt_iff_lt +theorem edgeSet_ssubset_edgeSet : edgeSet G₁ ⊂ edgeSet G₂ ↔ G₁ < G₂ := by simp theorem edgeSet_injective : Injective (edgeSet : SimpleGraph V → Set (Sym2 V)) := (edgeSetEmbedding V).injective @@ -557,8 +553,7 @@ theorem edgeSet_sdiff : (G₁ \ G₂).edgeSet = G₁.edgeSet \ G₂.edgeSet := b variable {G G₁ G₂} @[simp] lemma disjoint_edgeSet : Disjoint G₁.edgeSet G₂.edgeSet ↔ Disjoint G₁ G₂ := by - rw [Set.disjoint_iff, disjoint_iff_inf_le, ← edgeSet_inf, ← edgeSet_bot, ← Set.le_iff_subset, - OrderEmbedding.le_iff_le] + rw [Set.disjoint_iff, disjoint_iff_inf_le, ← edgeSet_inf, ← edgeSet_bot, OrderEmbedding.le_iff_le] @[simp] lemma edgeSet_eq_empty : G.edgeSet = ∅ ↔ G = ⊥ := by rw [← edgeSet_bot, edgeSet_inj] diff --git a/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean b/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean index d50387eaa45c04..ea9dd77576bfa3 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean @@ -271,9 +271,9 @@ protected def «end» := theorem end_hom_mk_of_mk {s} (sec : s ∈ G.end) {K L : (Finset V)ᵒᵖ} (h : L ⟶ K) {v : V} (vnL : v ∉ L.unop) (hs : s L = G.componentComplMk vnL) : - s K = G.componentComplMk (Set.notMem_subset (le_of_op_hom h : _ ⊆ _) vnL) := by + s K = G.componentComplMk (Set.notMem_subset (le_of_op_hom h) vnL) := by rw [← sec h, hs] - apply ComponentCompl.hom_mk _ (le_of_op_hom h : _ ⊆ _) + apply ComponentCompl.hom_mk _ (le_of_op_hom h) theorem infinite_iff_in_eventualRange {K : (Finset V)ᵒᵖ} (C : G.componentComplFunctor.obj K) : C.supp.Infinite ↔ C ∈ G.componentComplFunctor.eventualRange K := by diff --git a/Mathlib/Data/Finset/BooleanAlgebra.lean b/Mathlib/Data/Finset/BooleanAlgebra.lean index 0d81242779450a..ae2576a09891db 100644 --- a/Mathlib/Data/Finset/BooleanAlgebra.lean +++ b/Mathlib/Data/Finset/BooleanAlgebra.lean @@ -89,11 +89,11 @@ theorem top_eq_univ : (⊤ : Finset α) = univ := rfl theorem ssubset_univ_iff {s : Finset α} : s ⊂ univ ↔ s ≠ univ := - @lt_top_iff_ne_top _ _ _ s + lt_top_iff_ne_top @[simp] theorem univ_subset_iff {s : Finset α} : univ ⊆ s ↔ s = univ := - @top_le_iff _ _ _ s + top_le_iff theorem codisjoint_left : Codisjoint s t ↔ ∀ ⦃a⦄, a ∉ s → a ∈ t := by classical simp [codisjoint_iff, eq_univ_iff_forall, or_iff_not_imp_left] @@ -132,16 +132,16 @@ protected theorem bihimp_def : s ⇔ t = (s ∪ tᶜ) ∩ (t ∪ sᶜ) := bihimp theorem coe_compl (s : Finset α) : ↑sᶜ = (↑s : Set α)ᶜ := Set.ext fun _ => mem_compl -@[simp] lemma compl_subset_compl : sᶜ ⊆ tᶜ ↔ t ⊆ s := @compl_le_compl_iff_le (Finset α) _ _ _ -@[simp] lemma compl_ssubset_compl : sᶜ ⊂ tᶜ ↔ t ⊂ s := @compl_lt_compl_iff_lt (Finset α) _ _ _ +lemma compl_subset_compl : sᶜ ⊆ tᶜ ↔ t ⊆ s := compl_le_compl_iff_le +lemma compl_ssubset_compl : sᶜ ⊂ tᶜ ↔ t ⊂ s := compl_lt_compl_iff_lt -lemma subset_compl_comm : s ⊆ tᶜ ↔ t ⊆ sᶜ := le_compl_iff_le_compl (α := Finset α) +lemma subset_compl_comm : s ⊆ tᶜ ↔ t ⊆ sᶜ := le_compl_iff_le_compl lemma subset_compl_iff_disjoint_right : s ⊆ tᶜ ↔ Disjoint s t := - le_compl_iff_disjoint_right (α := Finset α) + le_compl_iff_disjoint_right lemma subset_compl_iff_disjoint_left : s ⊆ tᶜ ↔ Disjoint t s := - le_compl_iff_disjoint_left (α := Finset α) + le_compl_iff_disjoint_left @[simp] lemma subset_compl_singleton : s ⊆ {a}ᶜ ↔ a ∉ s := by rw [subset_compl_comm, singleton_subset_iff, mem_compl] diff --git a/Mathlib/Data/Finset/Defs.lean b/Mathlib/Data/Finset/Defs.lean index ff4a11713536db..4421e55d0a0215 100644 --- a/Mathlib/Data/Finset/Defs.lean +++ b/Mathlib/Data/Finset/Defs.lean @@ -71,7 +71,7 @@ variable {α : Type*} {β : Type*} {γ : Type*} /-- `Finset α` is the type of finite sets of elements of `α`. It is implemented as a multiset (a list up to permutation) which has no duplicate elements. -/ -@[to_dual_dont_translate] +@[use_set_notation_for_order, to_dual_dont_translate] structure Finset (α : Type*) where /-- The underlying multiset -/ val : Multiset α @@ -185,37 +185,9 @@ section Subset variable {s t : Finset α} -instance : HasSubset (Finset α) := - ⟨fun s t => ∀ ⦃a⦄, a ∈ s → a ∈ t⟩ - -instance : HasSSubset (Finset α) := - ⟨fun s t => s ⊆ t ∧ ¬t ⊆ s⟩ - -instance partialOrder : PartialOrder (Finset α) := inferInstance - +@[deprecated "This is now a syntactic identity" (since := "2026-05-24")] theorem subset_of_le : s ≤ t → s ⊆ t := id -instance : @Std.Refl (Finset α) (· ⊆ ·) := - inferInstanceAs <| Std.Refl (· ≤ ·) - -instance : IsTrans (Finset α) (· ⊆ ·) := - inferInstanceAs <| IsTrans (Finset α) (· ≤ ·) - -instance : @Std.Antisymm (Finset α) (· ⊆ ·) := - inferInstanceAs <| Std.Antisymm (· ≤ ·) - -instance : @Std.Irrefl (Finset α) (· ⊂ ·) := - inferInstanceAs <| Std.Irrefl (· < ·) - -instance : IsTrans (Finset α) (· ⊂ ·) := - inferInstanceAs <| IsTrans (Finset α) (· < ·) - -instance : Std.Asymm (α := Finset α) (· ⊂ ·) := - inferInstanceAs <| Std.Asymm (· < ·) - -instance : IsNonstrictStrictOrder (Finset α) (· ⊆ ·) (· ⊂ ·) := - ⟨fun _ _ => Iff.rfl⟩ - theorem subset_def : s ⊆ t ↔ s.1 ⊆ t.1 := Iff.rfl @@ -237,7 +209,6 @@ theorem Subset.trans {s₁ s₂ s₃ : Finset α} : s₁ ⊆ s₂ → s₂ ⊆ s theorem Superset.trans {s₁ s₂ s₃ : Finset α} : s₁ ⊇ s₂ → s₂ ⊇ s₃ → s₁ ⊇ s₃ := fun h' h => Subset.trans h h' -@[gcongr] theorem mem_of_subset {s₁ s₂ : Finset α} {a : α} : s₁ ⊆ s₂ → a ∈ s₁ → a ∈ s₂ := Multiset.mem_of_subset @@ -269,17 +240,19 @@ theorem Subset.antisymm_iff {s₁ s₂ : Finset α} : s₁ = s₂ ↔ s₁ ⊆ s theorem not_subset : ¬s ⊆ t ↔ ∃ x ∈ s, x ∉ t := by simp only [← coe_subset, Set.not_subset, mem_coe] -@[simp] +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem le_eq_subset : ((· ≤ ·) : Finset α → Finset α → Prop) = (· ⊆ ·) := rfl -@[simp] +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem lt_eq_subset : ((· < ·) : Finset α → Finset α → Prop) = (· ⊂ ·) := rfl +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem le_iff_subset {s₁ s₂ : Finset α} : s₁ ≤ s₂ ↔ s₁ ⊆ s₂ := Iff.rfl +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem lt_iff_ssubset {s₁ s₂ : Finset α} : s₁ < s₂ ↔ s₁ ⊂ s₂ := Iff.rfl diff --git a/Mathlib/Data/Finset/Filter.lean b/Mathlib/Data/Finset/Filter.lean index 2efe5f0ac30a1b..084546dfff857a 100644 --- a/Mathlib/Data/Finset/Filter.lean +++ b/Mathlib/Data/Finset/Filter.lean @@ -214,7 +214,7 @@ lemma _root_.Set.pairwiseDisjoint_filter [DecidableEq β] (f : α → β) (s : S theorem disjoint_filter_and_not_filter : Disjoint (s.filter (fun x ↦ p x ∧ ¬q x)) (s.filter (fun x ↦ q x ∧ ¬p x)) := by intro _ htp htq - simp only [bot_eq_empty, le_eq_subset, subset_empty] + simp only [bot_eq_empty, subset_empty] by_contra! ⟨_, hx⟩ exact (mem_filter.mp (htq hx)).2.2 (mem_filter.mp (htp hx)).2.1 diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index f8ac0e819bf998..bb0fd4f4d7885c 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -440,7 +440,6 @@ theorem image_eq_image_iff_of_injOn {s₁ s₂ : Finset α} (ht : (s : Set α).I exact_mod_cast ht.image_eq_image_iff (mod_cast h₁) (mod_cast h₂) lemma image_ssubset_image {t : Finset α} (hf : Injective f) : s.image f ⊂ t.image f ↔ s ⊂ t := by - simp_rw [← lt_iff_ssubset] exact lt_iff_lt_of_le_iff_le' (image_subset_image_iff hf) (image_subset_image_iff hf) theorem coe_image_subset_range : ↑(s.image f) ⊆ Set.range f := diff --git a/Mathlib/Data/Finset/Lattice/Basic.lean b/Mathlib/Data/Finset/Lattice/Basic.lean index 9beacac1a22d74..7249c420ec26c7 100644 --- a/Mathlib/Data/Finset/Lattice/Basic.lean +++ b/Mathlib/Data/Finset/Lattice/Basic.lean @@ -64,16 +64,15 @@ instance : Union (Finset α) := instance : Inter (Finset α) := ⟨fun s t => ⟨_, s.2.ndinter t.1⟩⟩ -instance : Lattice (Finset α) := - { Finset.partialOrder with - sup := (· ∪ ·) - sup_le := fun _ _ _ hs ht _ ha => (mem_ndunion.1 ha).elim (fun h => hs h) fun h => ht h - le_sup_left := fun _ _ _ h => mem_ndunion.2 <| Or.inl h - le_sup_right := fun _ _ _ h => mem_ndunion.2 <| Or.inr h - inf := (· ∩ ·) - le_inf := fun _ _ _ ht hu _ h => mem_ndinter.2 ⟨ht h, hu h⟩ - inf_le_left := fun _ _ _ h => (mem_ndinter.1 h).1 - inf_le_right := fun _ _ _ h => (mem_ndinter.1 h).2 } +instance : Lattice (Finset α) where + sup := (· ∪ ·) + sup_le := fun _ _ _ hs ht _ ha => (mem_ndunion.1 ha).elim (fun h => hs h) fun h => ht h + le_sup_left := fun _ _ _ h => mem_ndunion.2 <| Or.inl h + le_sup_right := fun _ _ _ h => mem_ndunion.2 <| Or.inr h + inf := (· ∩ ·) + le_inf := fun _ _ _ ht hu _ h => mem_ndinter.2 ⟨ht h, hu h⟩ + inf_le_left := fun _ _ _ h => (mem_ndinter.1 h).1 + inf_le_right := fun _ _ _ h => (mem_ndinter.1 h).2 @[simp] theorem sup_eq_union' : (Max.max : Finset α → Finset α → Finset α) = Union.union := @@ -120,14 +119,14 @@ theorem coe_union (s₁ s₂ : Finset α) : ↑(s₁ ∪ s₂) = (s₁ ∪ s₂ Set.ext fun _ => mem_union theorem union_subset (hs : s ⊆ u) : t ⊆ u → s ∪ t ⊆ u := - sup_le <| le_iff_subset.2 hs + sup_le hs @[simp] lemma subset_union_left : s₁ ⊆ s₁ ∪ s₂ := fun _ ↦ mem_union_left _ @[simp] lemma subset_union_right : s₂ ⊆ s₁ ∪ s₂ := fun _ ↦ mem_union_right _ @[gcongr] theorem union_subset_union (hsu : s ⊆ u) (htv : t ⊆ v) : s ∪ t ⊆ u ∪ v := - sup_le_sup (le_iff_subset.2 hsu) htv + sup_le_sup hsu htv theorem union_subset_union_left (h : s₁ ⊆ s₂) : s₁ ∪ t ⊆ s₂ ∪ t := union_subset_union h Subset.rfl @@ -240,7 +239,8 @@ theorem inter_union_self (s t : Finset α) : s ∩ (t ∪ s) = s := by rw [inter_comm, union_inter_cancel_right] @[mono, gcongr] -theorem inter_subset_inter {x y s t : Finset α} (h : x ⊆ y) (h' : s ⊆ t) : x ∩ s ⊆ y ∩ t := by grind +theorem inter_subset_inter {x y s t : Finset α} (h : x ⊆ y) (h' : s ⊆ t) : x ∩ s ⊆ y ∩ t := + inf_le_inf h h' theorem inter_subset_inter_left (h : t ⊆ u) : s ∩ t ⊆ s ∩ u := inter_subset_inter Subset.rfl h @@ -249,12 +249,12 @@ theorem inter_subset_inter_right (h : s ⊆ t) : s ∩ u ⊆ t ∩ u := inter_subset_inter h Subset.rfl theorem inter_subset_union : s ∩ t ⊆ s ∪ t := - le_iff_subset.1 inf_le_sup + inf_le_sup instance : DistribLattice (Finset α) := { le_sup_inf := fun a b c => by simp +contextual only - [sup_eq_union, inf_eq_inter, le_eq_subset, subset_iff, mem_inter, mem_union, and_imp, + [sup_eq_union, inf_eq_inter, subset_iff, mem_inter, mem_union, and_imp, or_imp, true_or, imp_true_iff, true_and, or_true] } @[simp] diff --git a/Mathlib/Data/Finset/Option.lean b/Mathlib/Data/Finset/Option.lean index e87d0412a65937..52154bd8c0dd63 100644 --- a/Mathlib/Data/Finset/Option.lean +++ b/Mathlib/Data/Finset/Option.lean @@ -61,7 +61,7 @@ namespace Finset using `Option.some` and then insert `Option.none`. -/ def insertNone : Finset α ↪o Finset (Option α) := (OrderEmbedding.ofMapLEIff fun s => cons none (s.map Embedding.some) <| by simp) fun s t => by - rw [le_iff_subset, cons_subset_cons, map_subset_map, le_iff_subset] + rw [cons_subset_cons, map_subset_map] @[simp] theorem mem_insertNone {s : Finset α} : ∀ {o : Option α}, o ∈ insertNone s ↔ ∀ a ∈ o, a ∈ s diff --git a/Mathlib/Data/Finset/Powerset.lean b/Mathlib/Data/Finset/Powerset.lean index fdeaf3e445df8c..c5fd6473412e54 100644 --- a/Mathlib/Data/Finset/Powerset.lean +++ b/Mathlib/Data/Finset/Powerset.lean @@ -323,7 +323,7 @@ theorem powersetCard_sup [DecidableEq α] (u : Finset α) (n : ℕ) (hn : n < u. · simp_rw [Finset.sup_le_iff, mem_powersetCard] rintro x ⟨h, -⟩ exact h - · rw [sup_eq_biUnion, le_iff_subset, subset_iff] + · rw [sup_eq_biUnion, subset_iff] intro x hx simp only [mem_biUnion, id] obtain ⟨t, ht⟩ : ∃ t, t ∈ powersetCard n (u.erase x) := powersetCard_nonempty.2 @@ -355,9 +355,7 @@ lemma powersetCard_injOn {q r : ℕ} (hr₀ : r ≠ 0) (hrq : r ≤ q) : theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) : powersetCard n (s.map f) = (powersetCard n s).map (mapEmbedding f).toEmbedding := ext fun t => by - -- `le_eq_subset` is a dangerous lemma since it turns the type `↪o` into `(· ⊆ ·) ↪r (· ⊆ ·)`, - -- which makes `simp` have trouble working with `mapEmbedding_apply`. - simp only [mem_powersetCard, mem_map, RelEmbedding.coe_toEmbedding, mapEmbedding_apply] + simp only [mem_powersetCard, mem_map] constructor · classical intro h @@ -365,7 +363,7 @@ theorem powersetCard_map {β : Type*} (f : α ↪ β) (n : ℕ) (s : Finset α) refine ⟨_, ?_, this⟩ rw [← card_map f, this, h.2]; simp · rintro ⟨a, ⟨has, rfl⟩, rfl⟩ - simp only [map_subset_map, has, card_map, and_self] + simp [has] end powersetCard diff --git a/Mathlib/Data/Finset/SDiff.lean b/Mathlib/Data/Finset/SDiff.lean index ddfff9aec70612..5aa4996f9db80b 100644 --- a/Mathlib/Data/Finset/SDiff.lean +++ b/Mathlib/Data/Finset/SDiff.lean @@ -113,8 +113,8 @@ variable (u) in lemma sdiff_subset_sdiff_right (h : s ⊆ t) : u \ t ⊆ u \ s := by gcongr theorem sdiff_subset_sdiff_iff_subset {r : Finset α} (hs : s ⊆ r) (ht : t ⊆ r) : - r \ s ⊆ r \ t ↔ t ⊆ s := by - simpa only [← le_eq_subset] using sdiff_le_sdiff_iff_le hs ht + r \ s ⊆ r \ t ↔ t ⊆ s := + sdiff_le_sdiff_iff_le hs ht @[simp, grind =, norm_cast] theorem coe_sdiff (s₁ s₂ : Finset α) : ↑(s₁ \ s₂) = (s₁ \ s₂ : Set α) := @@ -157,7 +157,7 @@ theorem sdiff_idem (s t : Finset α) : (s \ t) \ t = s \ t := _root_.sdiff_idem theorem subset_sdiff : s ⊆ t \ u ↔ s ⊆ t ∧ Disjoint s u := - le_iff_subset.symm.trans le_sdiff + le_sdiff @[simp] theorem sdiff_eq_empty_iff_subset : s \ t = ∅ ↔ s ⊆ t := @@ -192,7 +192,7 @@ lemma cons_sdiff_cons (hab : a ≠ b) (ha hb) : s.cons a ha \ s.cons b hb = {a} theorem sdiff_insert_of_notMem {x : α} (h : x ∉ s) (t : Finset α) : s \ insert x t = s \ t := by grind -@[simp] theorem sdiff_subset {s t : Finset α} : s \ t ⊆ s := le_iff_subset.mp sdiff_le +theorem sdiff_subset {s t : Finset α} : s \ t ⊆ s := by simp theorem sdiff_ssubset (h : t ⊆ s) (ht : t.Nonempty) : s \ t ⊂ s := by grind diff --git a/Mathlib/Data/Finset/Sups.lean b/Mathlib/Data/Finset/Sups.lean index a95494ca558cfd..56cbfee29a21bb 100644 --- a/Mathlib/Data/Finset/Sups.lean +++ b/Mathlib/Data/Finset/Sups.lean @@ -484,7 +484,7 @@ variable [DistribLattice α] [OrderBot α] [DecidableRel (α := α) Disjoint] (s theorem disjSups_assoc : ∀ s t u : Finset α, s ○ t ○ u = s ○ (t ○ u) := by refine (associative_of_commutative_of_le inferInstance ?_).assoc - simp only [le_eq_subset, disjSups_subset_iff, mem_disjSups] + simp only [disjSups_subset_iff, mem_disjSups] rintro s t u _ ⟨a, ha, b, hb, hab, rfl⟩ c hc habc rw [disjoint_sup_left] at habc exact ⟨a, ha, _, ⟨b, hb, c, hc, habc.2, rfl⟩, hab.sup_right habc.1, (sup_assoc ..).symm⟩ diff --git a/Mathlib/Data/Fintype/Card.lean b/Mathlib/Data/Fintype/Card.lean index 3d37ede9458d79..953def12af2219 100644 --- a/Mathlib/Data/Fintype/Card.lean +++ b/Mathlib/Data/Fintype/Card.lean @@ -444,8 +444,7 @@ theorem wellFounded_of_trans_of_irrefl (r : α → α → Prop) [IsTrans α r] [ cases nonempty_fintype α have (x y) (hxy : r x y) : #{z | r z x} < #{z | r z y} := Finset.card_lt_card <| by - simp_rw [Finset.lt_iff_ssubset.symm, lt_iff_le_not_ge, Finset.le_iff_subset, - Finset.subset_iff, mem_filter_univ] + simp_rw [lt_iff_le_not_ge, Finset.subset_iff, mem_filter_univ] exact ⟨fun z hzx => _root_.trans hzx hxy, not_forall_of_exists_not ⟨x, Classical.not_imp.2 ⟨hxy, irrefl x⟩⟩⟩ diff --git a/Mathlib/Data/Multiset/ZeroCons.lean b/Mathlib/Data/Multiset/ZeroCons.lean index dbe5fa97bd6237..cf8fd0a7193fa7 100644 --- a/Mathlib/Data/Multiset/ZeroCons.lean +++ b/Mathlib/Data/Multiset/ZeroCons.lean @@ -308,7 +308,8 @@ theorem eq_zero_of_subset_zero {s : Multiset α} (h : s ⊆ 0) : s = 0 := @[simp] lemma subset_zero : s ⊆ 0 ↔ s = 0 := ⟨eq_zero_of_subset_zero, fun xeq => xeq.symm ▸ Subset.refl 0⟩ -@[simp] lemma zero_ssubset : 0 ⊂ s ↔ s ≠ 0 := by simp [ssubset_iff_subset_not_subset] +@[simp] lemma zero_ssubset : 0 ⊂ s ↔ s ≠ 0 := by + simp [(right_iff_left_not_left : 0 ⊂ s ↔ 0 ⊆ s ∧ ¬s ⊆ 0)] @[simp] lemma singleton_subset : {a} ⊆ s ↔ a ∈ s := by simp [subset_iff] diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index 33b1e76ca63b6a..f351d53127ac98 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -86,9 +86,6 @@ instance instBoundedOrder : BoundedOrder (Set α) where bot := ∅ top := univ -instance : HasSSubset (Set α) := - ⟨(· < ·)⟩ - @[simp] theorem top_eq_univ : (⊤ : Set α) = univ := rfl @@ -105,22 +102,26 @@ theorem sup_eq_union : ((· ⊔ ·) : Set α → Set α → Set α) = (· ∪ · theorem inf_eq_inter : ((· ⊓ ·) : Set α → Set α → Set α) = (· ∩ ·) := rfl -@[simp] +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem le_eq_subset : ((· ≤ ·) : Set α → Set α → Prop) = (· ⊆ ·) := rfl -@[simp] +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem lt_eq_ssubset : ((· < ·) : Set α → Set α → Prop) = (· ⊂ ·) := rfl +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem le_iff_subset : s ≤ t ↔ s ⊆ t := Iff.rfl +@[deprecated "This is now a syntactic equality" (since := "2026-05-24"), nolint synTaut] theorem lt_iff_ssubset : s < t ↔ s ⊂ t := Iff.rfl +@[deprecated "this is now a syntactic identity" (since := "2026-05-24")] alias ⟨_root_.LE.le.subset, _root_.HasSubset.Subset.le⟩ := le_iff_subset +@[deprecated "this is now a syntactic identity" (since := "2026-05-24")] alias ⟨_root_.LT.lt.ssubset, _root_.HasSSubset.SSubset.lt⟩ := lt_iff_ssubset instance PiSetCoe.canLift (ι : Type u) (α : ι → Type v) [∀ i, Nonempty (α i)] (s : Set ι) : @@ -218,40 +219,6 @@ theorem setOf_or {p q : α → Prop} : { a | p a ∨ q a } = { a | p a } ∪ { a /-! ### Subset and strict subset relations -/ - -instance : @Std.Refl (Set α) (· ⊆ ·) := - show Std.Refl (· ≤ ·) by infer_instance - -instance : IsTrans (Set α) (· ⊆ ·) := - show IsTrans (Set α) (· ≤ ·) by infer_instance - -instance : Trans ((· ⊆ ·) : Set α → Set α → Prop) (· ⊆ ·) (· ⊆ ·) := - show Trans (· ≤ ·) (· ≤ ·) (· ≤ ·) by infer_instance - -instance : @Std.Antisymm (Set α) (· ⊆ ·) := - show Std.Antisymm (· ≤ ·) by infer_instance - -instance : @Std.Irrefl (Set α) (· ⊂ ·) := - show Std.Irrefl (· < ·) by infer_instance - -instance : IsTrans (Set α) (· ⊂ ·) := - show IsTrans (Set α) (· < ·) by infer_instance - -instance : Trans ((· ⊂ ·) : Set α → Set α → Prop) (· ⊂ ·) (· ⊂ ·) := - show Trans (· < ·) (· < ·) (· < ·) by infer_instance - -instance : Trans ((· ⊂ ·) : Set α → Set α → Prop) (· ⊆ ·) (· ⊂ ·) := - show Trans (· < ·) (· ≤ ·) (· < ·) by infer_instance - -instance : Trans ((· ⊆ ·) : Set α → Set α → Prop) (· ⊂ ·) (· ⊂ ·) := - show Trans (· ≤ ·) (· < ·) (· < ·) by infer_instance - -instance : @Std.Asymm (Set α) (· ⊂ ·) := - show Std.Asymm (· < ·) by infer_instance - -instance : IsNonstrictStrictOrder (Set α) (· ⊆ ·) (· ⊂ ·) := - ⟨fun _ _ => Iff.rfl⟩ - -- TODO(Jeremy): write a tactic to unfold specific instances of generic notation? @[grind =] theorem subset_def : (s ⊆ t) = ∀ x, x ∈ s → x ∈ t := @@ -679,7 +646,8 @@ theorem union_subset_iff {s t u : Set α} : s ∪ t ⊆ u ↔ s ⊆ u ∧ t ⊆ @[gcongr] theorem union_subset_union {s₁ s₂ t₁ t₂ : Set α} (h₁ : s₁ ⊆ s₂) (h₂ : t₁ ⊆ t₂) : - s₁ ∪ t₁ ⊆ s₂ ∪ t₂ := fun _ => Or.imp (@h₁ _) (@h₂ _) + s₁ ∪ t₁ ⊆ s₂ ∪ t₂ := + sup_le_sup h₁ h₂ theorem union_subset_union_left {s₁ s₂ : Set α} (t) (h : s₁ ⊆ s₂) : s₁ ∪ t ⊆ s₂ ∪ t := union_subset_union h Subset.rfl @@ -819,7 +787,8 @@ theorem univ_inter (a : Set α) : univ ∩ a = a := top_inf_eq _ @[gcongr] theorem inter_subset_inter {s₁ s₂ t₁ t₂ : Set α} (h₁ : s₁ ⊆ t₁) (h₂ : s₂ ⊆ t₂) : - s₁ ∩ s₂ ⊆ t₁ ∩ t₂ := fun _ => And.imp (@h₁ _) (@h₂ _) + s₁ ∩ s₂ ⊆ t₁ ∩ t₂ := + inf_le_inf h₁ h₂ theorem inter_subset_inter_left {s t : Set α} (u : Set α) (H : s ⊆ t) : s ∩ u ⊆ t ∩ u := inter_subset_inter H Subset.rfl diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index 5e66b76ade76d6..f1661d587e2697 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -287,7 +287,7 @@ theorem encard_strictMono [Finite α] : StrictMono (encard : Set α → ℕ∞) fun _ _ h ↦ (toFinite _).encard_lt_encard h theorem Finite.encard_strictMonoOn : StrictMonoOn (α := Set α) encard (setOf Set.Finite) := - fun _ hs _ _ hlt ↦ hs.encard_lt_encard hlt.ssubset + fun _ hs _ _ hlt ↦ hs.encard_lt_encard hlt theorem Finite.encard_lt_card (hfin : s.Finite) (hne : s ≠ univ) : s.encard < ENat.card α := encard_univ α ▸ hfin.encard_lt_encard (ssubset_univ_iff.mpr hne) @@ -901,7 +901,7 @@ theorem ncard_strictMono [Finite α] : @StrictMono (Set α) _ _ _ ncard := fun _ _ h ↦ ncard_lt_ncard h theorem Finite.ncard_strictMonoOn : StrictMonoOn (α := Set α) ncard (setOf Set.Finite) := - fun _ _ _ ht hlt ↦ ncard_lt_ncard hlt.ssubset ht + fun _ _ _ ht hlt ↦ ncard_lt_ncard hlt ht theorem ncard_eq_of_bijective {n : ℕ} (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a) (hf' : ∀ (i) (h : i < n), f i h ∈ s) diff --git a/Mathlib/Data/Set/Defs.lean b/Mathlib/Data/Set/Defs.lean index cd1214aa75db2a..5f780c4092a23b 100644 --- a/Mathlib/Data/Set/Defs.lean +++ b/Mathlib/Data/Set/Defs.lean @@ -5,8 +5,8 @@ Authors: Leonardo de Moura -/ module -public import Mathlib.Init public import Batteries.Util.ExtendedBinder +public import Mathlib.Tactic.SetNotationForOrder import Mathlib.Tactic.ToDual @@ -46,6 +46,7 @@ Although `Set` is defined as `α → Prop`, this is an implementation detail whi relied on. Instead, `setOf` and membership of a set (`∈`) should be used to convert between sets and predicates. -/ +@[use_set_notation_for_order] def Set (α : Type u) := α → Prop /- @@ -88,9 +89,6 @@ to subset hypotheses. -/ instance : LE (Set α) := ⟨Set.Subset⟩ -instance : HasSubset (Set α) := - ⟨(· ≤ ·)⟩ - instance : EmptyCollection (Set α) := ⟨fun _ ↦ False⟩ diff --git a/Mathlib/Data/Set/Disjoint.lean b/Mathlib/Data/Set/Disjoint.lean index 19d162f3368440..2227bbb9d0af32 100644 --- a/Mathlib/Data/Set/Disjoint.lean +++ b/Mathlib/Data/Set/Disjoint.lean @@ -63,7 +63,6 @@ alias ⟨_root_.Disjoint.ne_of_mem, _⟩ := disjoint_iff_forall_ne lemma disjoint_of_subset_left (h : s ⊆ u) (d : Disjoint u t) : Disjoint s t := d.mono_left h lemma disjoint_of_subset_right (h : t ⊆ u) (d : Disjoint s u) : Disjoint s t := d.mono_right h -@[gcongr high] lemma disjoint_of_subset (hs : s₁ ⊆ s₂) (ht : t₁ ⊆ t₂) (h : Disjoint s₂ t₂) : Disjoint s₁ t₁ := h.mono hs ht diff --git a/Mathlib/Data/Set/Finite/Basic.lean b/Mathlib/Data/Set/Finite/Basic.lean index d25013acdc85cd..5c1a0dd85ed32e 100644 --- a/Mathlib/Data/Set/Finite/Basic.lean +++ b/Mathlib/Data/Set/Finite/Basic.lean @@ -656,7 +656,7 @@ theorem exists_finite_iff_finset {p : Set α → Prop} : theorem exists_subset_image_finite_and {f : α → β} {s : Set α} {p : Set β → Prop} : (∃ t ⊆ f '' s, t.Finite ∧ p t) ↔ ∃ t ⊆ s, t.Finite ∧ p (f '' t) := by classical - simp_rw [@and_comm (_ ⊆ _), and_assoc, exists_finite_iff_finset, @and_comm (p _), + simp_rw [@and_comm ((_ : Set _) ⊆ _), and_assoc, exists_finite_iff_finset, @and_comm (p _), Finset.subset_set_image_iff] aesop diff --git a/Mathlib/Data/Set/FiniteExhaustion.lean b/Mathlib/Data/Set/FiniteExhaustion.lean index 10b3a9449870e0..d12f24ce2b0583 100644 --- a/Mathlib/Data/Set/FiniteExhaustion.lean +++ b/Mathlib/Data/Set/FiniteExhaustion.lean @@ -38,7 +38,7 @@ instance {α : Type*} {s : Set α} : FunLike (FiniteExhaustion s) ℕ (Set α) w coe := toFun coe_injective | ⟨_, _, _, _⟩, ⟨_, _, _, _⟩, rfl => rfl -instance {α : Type*} {s : Set α} : RelHomClass (FiniteExhaustion s) LE.le HasSubset.Subset where +instance {α : Type*} {s : Set α} : OrderHomClass (FiniteExhaustion s) Nat (Set α) where map_rel K _ _ h := monotone_nat_of_le_succ (fun n ↦ K.subset_succ' n) h instance {α : Type*} {s : Set α} {K : FiniteExhaustion s} {n : ℕ} : Finite (K n) := diff --git a/Mathlib/Data/Set/Insert.lean b/Mathlib/Data/Set/Insert.lean index 4f1d5d94726f27..74410133de73aa 100644 --- a/Mathlib/Data/Set/Insert.lean +++ b/Mathlib/Data/Set/Insert.lean @@ -93,9 +93,12 @@ theorem subset_insert_iff_of_notMem (ha : a ∉ s) : s ⊆ insert a t ↔ s ⊆ theorem ssubset_iff_insert {s t : Set α} : s ⊂ t ↔ ∃ a ∉ s, insert a s ⊆ t := by grind -theorem _root_.HasSubset.Subset.ssubset_of_mem_notMem (hst : s ⊆ t) (hat : a ∈ t) (has : a ∉ s) : +theorem _root_.LE.le.ssubset_of_mem_notMem (hst : s ⊆ t) (hat : a ∈ t) (has : a ∉ s) : s ⊂ t := by grind +@[deprecated (since := "2026-06-05")] +alias _root_.HasSubset.Subset.ssubset_of_mem_notMem := LE.le.ssubset_of_mem_notMem + theorem ssubset_insert {s : Set α} {a : α} (h : a ∉ s) : s ⊂ insert a s := by grind theorem insert_comm (a b : α) (s : Set α) : insert a (insert b s) = insert b (insert a s) := by diff --git a/Mathlib/Data/Set/Notation.lean b/Mathlib/Data/Set/Notation.lean index a911c23c8b904c..0d650b45804127 100644 --- a/Mathlib/Data/Set/Notation.lean +++ b/Mathlib/Data/Set/Notation.lean @@ -25,7 +25,7 @@ They are defined here separately so that this file can be added as an exception and can thus be imported without a linting false positive when only the notation is desired. -/ -@[expose] public section +public section namespace Set.Notation /-- diff --git a/Mathlib/Data/Set/Semiring.lean b/Mathlib/Data/Set/Semiring.lean index b33f7a17ac5b7c..228d62fd9af895 100644 --- a/Mathlib/Data/Set/Semiring.lean +++ b/Mathlib/Data/Set/Semiring.lean @@ -54,7 +54,7 @@ protected theorem down_up (s : Set α) : s.up.down = s := protected theorem up_down (s : SetSemiring α) : s.down.up = s := rfl --- TODO: These lemmas are not tagged `simp` because `Set.le_eq_subset` simplifies the LHS +-- TODO: These lemmas should be tagged `simp` theorem up_le_up {s t : Set α} : s.up ≤ t.up ↔ s ⊆ t := Iff.rfl diff --git a/Mathlib/Data/Set/Sups.lean b/Mathlib/Data/Set/Sups.lean index ea363485f892ee..75ebdbd233ba45 100644 --- a/Mathlib/Data/Set/Sups.lean +++ b/Mathlib/Data/Set/Sups.lean @@ -155,7 +155,7 @@ lemma subset_sups_self : s ⊆ s ⊻ s := fun _a ha ↦ mem_sups.2 ⟨_, ha, _, lemma sups_subset_self : s ⊻ s ⊆ s ↔ SupClosed s := sups_subset_iff @[simp] lemma sups_eq_self : s ⊻ s = s ↔ SupClosed s := - subset_sups_self.le.ge_iff_eq'.symm.trans sups_subset_self + subset_sups_self.ge_iff_eq'.symm.trans sups_subset_self lemma sep_sups_le (s t : Set α) (a : α) : {b ∈ s ⊻ t | b ≤ a} = {b ∈ s | b ≤ a} ⊻ {b ∈ t | b ≤ a} := by ext; aesop @@ -285,7 +285,7 @@ lemma subset_infs_self : s ⊆ s ⊼ s := fun _a ha ↦ mem_infs.2 ⟨_, ha, _, lemma infs_self_subset : s ⊼ s ⊆ s ↔ InfClosed s := infs_subset_iff @[simp] lemma infs_self : s ⊼ s = s ↔ InfClosed s := - subset_infs_self.le.ge_iff_eq'.symm.trans infs_self_subset + subset_infs_self.ge_iff_eq'.symm.trans infs_self_subset lemma sep_infs_le (s t : Set α) (a : α) : {b ∈ s ⊼ t | a ≤ b} = {b ∈ s | a ≤ b} ⊼ {b ∈ t | a ≤ b} := by ext; aesop diff --git a/Mathlib/Data/SetLike/Basic.lean b/Mathlib/Data/SetLike/Basic.lean index b6c32ded8eaf23..f99140d7ea9d9a 100644 --- a/Mathlib/Data/SetLike/Basic.lean +++ b/Mathlib/Data/SetLike/Basic.lean @@ -233,6 +233,7 @@ of `IsConcreteLE`. -/ @[reducible] def PartialOrder.ofSetLike : PartialOrder A where __ := LE.ofSetLike A B + lt s t := letI := LE.ofSetLike A B; s ≤ t ∧ ¬t ≤ s __ := PartialOrder.lift (SetLike.coe : A → Set B) SetLike.coe_injective instance : letI := PartialOrder.ofSetLike A B; IsConcreteLE A B := diff --git a/Mathlib/Dynamics/Ergodic/Ergodic.lean b/Mathlib/Dynamics/Ergodic/Ergodic.lean index 23e83bebf0f598..d0d2eb3aebaedd 100644 --- a/Mathlib/Dynamics/Ergodic/Ergodic.lean +++ b/Mathlib/Dynamics/Ergodic/Ergodic.lean @@ -179,7 +179,7 @@ theorem ae_empty_or_univ_of_ae_le_preimage' (hf : Ergodic f μ) (hs : NullMeasur theorem ae_empty_or_univ_of_image_ae_le' (hf : Ergodic f μ) (hs : NullMeasurableSet s μ) (hs' : f '' s ≤ᵐ[μ] s) (h_fin : μ s ≠ ∞) : s =ᵐ[μ] (∅ : Set α) ∨ s =ᵐ[μ] univ := by replace hs' : s ≤ᵐ[μ] f ⁻¹' s := - (HasSubset.Subset.eventuallyLE (subset_preimage_image f s)).trans + (LE.le.eventuallyLE (subset_preimage_image f s)).trans (hf.quasiMeasurePreserving.preimage_mono_ae hs') exact ae_empty_or_univ_of_ae_le_preimage' hf hs hs' h_fin diff --git a/Mathlib/Dynamics/FixedPoints/Prufer.lean b/Mathlib/Dynamics/FixedPoints/Prufer.lean index a3ab70cf09b55d..061bb4e34693ca 100644 --- a/Mathlib/Dynamics/FixedPoints/Prufer.lean +++ b/Mathlib/Dynamics/FixedPoints/Prufer.lean @@ -35,7 +35,7 @@ theorem smul_eq_self_of_preimage_zpow_eq_self {G : Type*} [CommGroup G] {n : ℤ refine le_antisymm (this hg) ?_ conv_lhs => rw [← smul_inv_smul g s] replace hg : g⁻¹ ^ n ^ j = 1 := by rw [inv_zpow, hg, inv_one] - simpa only [le_eq_subset, smul_set_subset_smul_set_iff] using this hg + simp only [smul_set_subset_smul_set_iff, this hg] rw [(IsFixedPt.preimage_iterate hs j : (zpowGroupHom n)^[j] ⁻¹' s = s).symm] rintro g' hg' - ⟨y, hy, rfl⟩ change (zpowGroupHom n)^[j] (g' * y) ∈ s diff --git a/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean b/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean index d3ef5492fff333..5cdff3c88f91bc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean @@ -134,7 +134,7 @@ theorem ContMDiffFiberwiseLinear.locality_aux₁ rw [← hesu p] at this exact this.1 have he : e.source = (Prod.fst '' e.source) ×ˢ (univ : Set F) := by - apply HasSubset.Subset.antisymm + apply subset_antisymm · intro p hp exact ⟨⟨p, hp, rfl⟩, trivial⟩ · rintro ⟨x, v⟩ ⟨⟨p, hp, rfl : p.fst = x⟩, -⟩ diff --git a/Mathlib/GroupTheory/CosetCover.lean b/Mathlib/GroupTheory/CosetCover.lean index aecc3f4b584811..5dc34f40e03b57 100644 --- a/Mathlib/GroupTheory/CosetCover.lean +++ b/Mathlib/GroupTheory/CosetCover.lean @@ -299,7 +299,7 @@ theorem leftCoset_cover_filter_FiniteIndex_aux simpa [Set.mem_smul_set_iff_inv_smul_mem, smul_eq_mul, mul_assoc] using! hi' hx have ⟨k₁, hik₁, hk₁, hxk₁⟩ := hk' i hi hi' have ⟨k₂, hjk₂, hk₂, hxk₂⟩ := hk' j hj hj' - rw [← Set.singleton_subset_iff, ← Set.le_iff_subset] at hxk₁ hxk₂ ⊢ + rw [← Set.singleton_subset_iff] at hxk₁ hxk₂ ⊢ exact hdisjoint (Finset.mem_filter.mpr ⟨Finset.mem_univ k₁, hk₁⟩) (Finset.mem_filter.mpr ⟨Finset.mem_univ k₂, hk₂⟩) diff --git a/Mathlib/GroupTheory/GroupAction/Blocks.lean b/Mathlib/GroupTheory/GroupAction/Blocks.lean index acb6b45fc25ac4..d86983c27ca447 100644 --- a/Mathlib/GroupTheory/GroupAction/Blocks.lean +++ b/Mathlib/GroupTheory/GroupAction/Blocks.lean @@ -580,7 +580,7 @@ def block_stabilizerOrderIso [htGX : IsPretransitive G X] (a : X) : (id (propext Subtype.mk_eq_mk)).mpr (stabilizer_orbit_eq hH) map_rel_iff' := by rintro ⟨B, ha, hB⟩; rintro ⟨B', ha', hB'⟩ - simp only [Equiv.coe_fn_mk, Subtype.mk_le_mk, Set.le_eq_subset] + simp only [Equiv.coe_fn_mk, Subtype.mk_le_mk] constructor · rintro hBB' b hb obtain ⟨k, rfl⟩ := htGX.exists_smul_eq a b @@ -605,11 +605,11 @@ instance (a : X) : BoundedOrder (BlockMem G a) where top := ⟨Set.univ, Set.mem_univ a, .univ⟩ le_top := by rintro ⟨B, ha, hB⟩ - simp only [Subtype.mk_le_mk, le_eq_subset, subset_univ] + simp only [Subtype.mk_le_mk, subset_univ] bot := ⟨{a}, Set.mem_singleton a, IsBlock.singleton⟩ bot_le := by rintro ⟨B, ha, hB⟩ - simp only [Subtype.mk_le_mk, Set.le_eq_subset, Set.singleton_subset_iff] + simp only [Subtype.mk_le_mk, Set.singleton_subset_iff] exact ha @[to_additive (attr := simp, norm_cast)] diff --git a/Mathlib/Lean/Expr/ExtraRecognizers.lean b/Mathlib/Lean/Expr/ExtraRecognizers.lean index 5565303c78e36d..17a2adc57b4d50 100644 --- a/Mathlib/Lean/Expr/ExtraRecognizers.lean +++ b/Mathlib/Lean/Expr/ExtraRecognizers.lean @@ -6,13 +6,14 @@ Authors: Kyle Miller module public import Mathlib.Data.Set.CoeSort +import Lean.Expr /-! # Additional Expr recognizers needing theory imports -/ -@[expose] public section +public section namespace Lean.Expr diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean index 9137bd70e99de2..734b662a501c96 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean @@ -559,7 +559,7 @@ lemma affineCombination_mem_setInterior_face_iff_mem (I : Set k) {n : ℕ} (s : convert! Finset.univ.affineCombination_map (fs.orderEmbOfFin h).toEmbedding w s.points using 1 simp only [map_orderEmbOfFin_univ, Finset.affineCombination_indicator_subset _ _ fs.subset_univ] congr - grind [Set.indicator_eq_self, support_subset_iff] + grind [Set.indicator_eq_self, mem_support] lemma affineCombination_mem_interior_face_iff_mem_Ioo {n : ℕ} (s : Simplex k P n) {fs : Finset (Fin (n + 1))} {m : ℕ} (h : #fs = m + 1) {w : Fin (n + 1) → k} diff --git a/Mathlib/Logic/Equiv/PartialEquiv.lean b/Mathlib/Logic/Equiv/PartialEquiv.lean index 14605e6ca9458c..37cf911ee21e7c 100644 --- a/Mathlib/Logic/Equiv/PartialEquiv.lean +++ b/Mathlib/Logic/Equiv/PartialEquiv.lean @@ -94,7 +94,7 @@ elab (name := mfldSetTac) "mfld_set_tac" : tactic => withMainContext do · intro h_my_y try simp only [*, mfld_simps] at h_my_y try simp only [*, mfld_simps]))) - | (``Subset, #[_ty, _inst, _e₁, _e₂]) => + | (``LE.le, #[_ty, _inst, _e₁, _e₂]) => evalTactic (← `(tactic| ( intro my_y h_my_y try simp only [*, mfld_simps] at h_my_y diff --git a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean index ce5505fc9109fe..7fb8db25c9b16e 100644 --- a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean +++ b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean @@ -168,8 +168,7 @@ theorem blimsup_cthickening_ae_le_of_eventually_mul_le (p : ℕ → Prop) {s : exact max_le_max (le_refl 0) hi simp_rw [← cthickening_max_zero (r₁ _), ← cthickening_max_zero (r₂ _)] rcases le_or_gt 1 M with hM' | hM' - · apply HasSubset.Subset.eventuallyLE - change _ ≤ _ + · apply LE.le.eventuallyLE refine mono_blimsup' (hMr.mono fun i hi _ => cthickening_mono ?_ (s i)) exact (le_mul_of_one_le_left (hRp i) hM').trans hi · simp only [← @cthickening_closure _ _ _ (s _)] @@ -231,11 +230,10 @@ theorem blimsup_cthickening_ae_eq_blimsup_thickening {p : ℕ → Prop} {s : ℕ (hr : Tendsto r atTop (𝓝 0)) (hr' : ∀ᶠ i in atTop, p i → 0 < r i) : (blimsup (fun i => cthickening (r i) (s i)) atTop p : Set α) =ᵐ[μ] (blimsup (fun i => thickening (r i) (s i)) atTop p : Set α) := by - refine eventuallyLE_antisymm_iff.mpr ⟨?_, HasSubset.Subset.eventuallyLE (?_ : _ ≤ _)⟩ + refine eventuallyLE_antisymm_iff.mpr ⟨?_, LE.le.eventuallyLE ?_⟩ · rw [eventuallyLE_congr (blimsup_cthickening_mul_ae_eq μ p s (one_half_pos (α := ℝ)) r hr).symm EventuallyEq.rfl] - apply HasSubset.Subset.eventuallyLE - change _ ≤ _ + apply LE.le.eventuallyLE refine mono_blimsup' (hr'.mono fun i hi pi => cthickening_subset_thickening' (hi pi) ?_ (s i)) nlinarith [hi pi] · exact mono_blimsup fun i _ => thickening_subset_cthickening _ _ diff --git a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean index 002ba891b4f87f..78b0a17871d839 100644 --- a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean +++ b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean @@ -408,7 +408,7 @@ lemma ae_eq_zero_of_forall_setIntegral_isCompact_eq_zero · intro n exact (isClosed_closure.inter hs).measurableSet · intro m n hmn - simp only [t, Set.le_iff_subset] + simp only [t] gcongr · exact hf.integrableOn diff --git a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean index 9ddda1d5559bff..f9151af5679b35 100644 --- a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean +++ b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean @@ -150,7 +150,7 @@ theorem _root_.Antitone.tendsto_setIntegral (hsm : ∀ i, MeasurableSet (s i)) ( exact hfi.norm · simp_rw [norm_indicator_eq_indicator_norm] refine fun n => Eventually.of_forall fun x => ?_ - grw [(h_anti zero_le).subset] + grw [h_anti zero_le] · filter_upwards [] with a using le_trans (h_anti.tendsto_indicator _ _ _) (pure_le_nhds _) end TendstoMono diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index 52175f6b0a4e31..23db79f3ecf25c 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -371,7 +371,7 @@ private theorem lintegral_tendsto_of_monotone_of_nat {φ : ℕ → Set α} (hφ let F n := (φ n).indicator f have key₁ : ∀ n, AEMeasurable (F n) μ := fun n => hfm.indicator (hφ.measurableSet n) have key₂ : ∀ᵐ x : α ∂μ, Monotone fun n => F n x := ae_of_all _ fun x _i _j hij => by - dsimp [F]; grw [(hmono hij).subset] + dsimp [F]; grw [hmono hij] have key₃ : ∀ᵐ x : α ∂μ, Tendsto (fun n => F n x) atTop (𝓝 (f x)) := hφ.ae_tendsto_indicator f (lintegral_tendsto_of_tendsto_of_monotone key₁ key₂ key₃).congr fun n => lintegral_indicator (hφ.measurableSet n) _ diff --git a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean index 8a7725a4b038d6..c875214a5de081 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean @@ -156,7 +156,7 @@ lemma measurableSet_countablyGeneratedAtom (p : ℕ → Prop) : lemma disjoint_countablyGeneratedAtom : Pairwise (Function.onFun Disjoint (countablyGeneratedAtom α)) := by intro p q hpq s hsp hsq - simp only [le_eq_subset, bot_eq_empty, subset_empty_iff] at hsp hsq ⊢ + simp only [bot_eq_empty, subset_empty_iff] at hsp hsq ⊢ ext x simp only [mem_empty_iff_false, iff_false] intro hxs diff --git a/Mathlib/MeasureTheory/Measure/AEDisjoint.lean b/Mathlib/MeasureTheory/Measure/AEDisjoint.lean index b6698ca4bbddbd..564050c6820771 100644 --- a/Mathlib/MeasureTheory/Measure/AEDisjoint.lean +++ b/Mathlib/MeasureTheory/Measure/AEDisjoint.lean @@ -80,7 +80,7 @@ theorem mono_ae (h : AEDisjoint μ s t) (hu : u ≤ᵐ[μ] s) (hv : v ≤ᵐ[μ] measure_mono_null_ae (hu.inter hv) h protected theorem mono (h : AEDisjoint μ s t) (hu : u ⊆ s) (hv : v ⊆ t) : AEDisjoint μ u v := - mono_ae h (HasSubset.Subset.eventuallyLE hu) (HasSubset.Subset.eventuallyLE hv) + mono_ae h (LE.le.eventuallyLE hu) (LE.le.eventuallyLE hv) protected theorem congr (h : AEDisjoint μ s t) (hu : u =ᵐ[μ] s) (hv : v =ᵐ[μ] t) : AEDisjoint μ u v := diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/RadonNikodym.lean b/Mathlib/MeasureTheory/Measure/Decomposition/RadonNikodym.lean index d30b7a67ce9627..34a444691b9f2d 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/RadonNikodym.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/RadonNikodym.lean @@ -366,7 +366,7 @@ lemma setIntegral_toReal_rnDeriv_le [SigmaFinite μ] {s : Set α} (hμs : μ s have hμt : μ t ≠ ∞ := by rwa [ht, measure_toMeasurable s] calc ∫ x in s, (μ.rnDeriv ν x).toReal ∂ν ≤ ∫ x in t, (μ.rnDeriv ν x).toReal ∂ν := by - refine setIntegral_mono_set ?_ ?_ (HasSubset.Subset.eventuallyLE (subset_toMeasurable _ _)) + refine setIntegral_mono_set ?_ ?_ (LE.le.eventuallyLE (subset_toMeasurable _ _)) · exact integrableOn_toReal_rnDeriv hμt · exact ae_of_all _ (by simp) _ = (withDensity ν (rnDeriv μ ν)).real t := setIntegral_toReal_rnDeriv_eq_withDensity' ht_m diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 4f1e08faed2b5d..11af89700356d5 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -296,7 +296,7 @@ alias measure_diff_le_iff_le_add := measure_sdiff_le_iff_le_add theorem measure_eq_measure_of_null_sdiff {s t : Set α} (hst : s ⊆ t) (h_nullsdiff : μ (t \ s) = 0) : μ s = μ t := measure_congr <| - EventuallyLE.antisymm (HasSubset.Subset.eventuallyLE hst) (ae_le_set.mpr h_nullsdiff) + EventuallyLE.antisymm (LE.le.eventuallyLE hst) (ae_le_set.mpr h_nullsdiff) @[deprecated (since := "2026-06-03")] alias measure_eq_measure_of_null_diff := measure_eq_measure_of_null_sdiff @@ -351,7 +351,7 @@ theorem union_ae_eq_left_iff_ae_subset : (s ∪ t : Set α) =ᵐ[μ] s ↔ t ≤ ⟨fun h => by simpa only [union_sdiff_left] using (ae_eq_set.mp h).1, fun h => eventuallyLE_antisymm_iff.mpr ⟨by rwa [ae_le_set, union_sdiff_left], - HasSubset.Subset.eventuallyLE subset_union_left⟩⟩ + LE.le.eventuallyLE subset_union_left⟩⟩ @[simp] theorem union_ae_eq_right_iff_ae_subset : (s ∪ t : Set α) =ᵐ[μ] t ↔ s ≤ᵐ[μ] t := by @@ -367,7 +367,7 @@ theorem ae_eq_of_ae_subset_of_measure_ge (h₁ : s ≤ᵐ[μ] t) (h₂ : μ t /-- If `s ⊆ t`, `μ t ≤ μ s`, `μ t ≠ ∞`, and `s` is measurable, then `s =ᵐ[μ] t`. -/ theorem ae_eq_of_subset_of_measure_ge (h₁ : s ⊆ t) (h₂ : μ t ≤ μ s) (hsm : NullMeasurableSet s μ) (ht : μ t ≠ ∞) : s =ᵐ[μ] t := - ae_eq_of_ae_subset_of_measure_ge (HasSubset.Subset.eventuallyLE h₁) h₂ hsm ht + ae_eq_of_ae_subset_of_measure_ge h₁.eventuallyLE h₂ hsm ht theorem measure_iUnion_congr_of_subset {ι : Sort*} [Countable ι] {s : ι → Set α} {t : ι → Set α} (hsub : ∀ i, s i ⊆ t i) (h_le : ∀ i, μ (t i) ≤ μ (s i)) : μ (⋃ i, s i) = μ (⋃ i, t i) := by diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean b/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean index ed58424ad157ee..b92dd6562f24d7 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean @@ -334,7 +334,7 @@ theorem subset_toMeasurable (μ : Measure α) (s : Set α) : s ⊆ toMeasurable exacts [hs.choose_spec.1, h's.choose_spec.1, (exists_measurable_superset μ s).choose_spec.1] theorem ae_le_toMeasurable : s ≤ᵐ[μ] toMeasurable μ s := - HasSubset.Subset.eventuallyLE (subset_toMeasurable _ _) + LE.le.eventuallyLE (subset_toMeasurable _ _) @[simp] theorem measurableSet_toMeasurable (μ : Measure α) (s : Set α) : diff --git a/Mathlib/MeasureTheory/Measure/Prokhorov.lean b/Mathlib/MeasureTheory/Measure/Prokhorov.lean index e800614f79f4fc..f7b79b06bdbf1e 100644 --- a/Mathlib/MeasureTheory/Measure/Prokhorov.lean +++ b/Mathlib/MeasureTheory/Measure/Prokhorov.lean @@ -519,7 +519,7 @@ lemma isCompact_closure_of_isTightMeasureSet {S : Set (ProbabilityMeasure E)} apply isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le u_lim · exact fun n ↦ (finite_Iic n).isCompact_biUnion (fun i hi ↦ K_comp i) · right - simp only [Monotone, mem_Iic, le_eq_subset, iUnion_subset_iff, K'] + simp only [Monotone, mem_Iic, iUnion_subset_iff, K'] intro a b hab i hi apply subset_biUnion_of_mem exact hi.trans hab diff --git a/Mathlib/MeasureTheory/Measure/Regular.lean b/Mathlib/MeasureTheory/Measure/Regular.lean index 54fc6b4d334cd5..fb81fe7c2f5584 100644 --- a/Mathlib/MeasureTheory/Measure/Regular.lean +++ b/Mathlib/MeasureTheory/Measure/Regular.lean @@ -408,7 +408,7 @@ theorem comap' {mβ : MeasurableSpace β} [TopologicalSpace β] (μ : Measure β outerRegular A hA r hr := by rw [f_me.comap_apply] at hr obtain ⟨U, hUA, Uopen, hμU⟩ := OuterRegular.outerRegular (f_me.measurableSet_image' hA) r hr - refine ⟨f ⁻¹' U, by rwa [Superset, ← image_subset_iff], Uopen.preimage f_cont, ?_⟩ + refine ⟨f ⁻¹' U, by rwa [ge_iff_le, ← image_subset_iff], Uopen.preimage f_cont, ?_⟩ rw [f_me.comap_apply] exact (measure_mono (image_preimage_subset _ _)).trans_lt hμU diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index 1cdba1a8f7a375..5d666560eba459 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -479,8 +479,7 @@ theorem outer_trim [MeasurableSpace R] [BorelSpace R] [DenselyOrdered R] : show ∀ i, ∃ s, t i ⊆ s ∧ MeasurableSet s ∧ f.outer s ≤ f.length (t i) + ofReal (ε' i) by intro i rcases isEmpty_or_nonempty R with hR | hR - · refine ⟨∅, ?_, MeasurableSet.empty, by simp⟩ - simpa using eq_empty_of_isEmpty (t i) + · exact ⟨∅, by simp, MeasurableSet.empty, by simp⟩ have hl := ENNReal.lt_add_right ((ENNReal.le_tsum i).trans_lt h).ne (ENNReal.coe_pos.2 (ε'0 i)).ne' conv at hl => diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean index fdc5d2827d7b41..18fff318c3ff61 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean @@ -520,7 +520,7 @@ theorem exists_open_superset_measure_lt_top' (h : IsCompact s) (hμ : ∀ x ∈ s, μ.FiniteAtFilter (𝓝 x)) : ∃ U ⊇ s, IsOpen U ∧ μ U < ∞ := by refine IsCompact.induction_on h ?_ ?_ ?_ ?_ · use ∅ - simp [Superset] + simp · rintro s t hst ⟨U, htU, hUo, hU⟩ exact ⟨U, hst.trans htU, hUo, hU⟩ · rintro s t ⟨U, hsU, hUo, hU⟩ ⟨V, htV, hVo, hV⟩ diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean index b6c1889b88187b..2bcc77442bb711 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean @@ -361,7 +361,7 @@ lemma exists_ae_subset_biUnion_countable [SFinite μ] refine ⟨⋃ n, D n, by simp [DC], by simp [D_count], fun s hs ↦ ?_⟩ rw [← sum_sfiniteSeq μ] apply ae_sum_iff.2 (fun n ↦ (hD n s hs).trans ?_) - exact HasSubset.Subset.eventuallyLE (fun x hx ↦ by simp at hx ⊢; grind) + exact LE.le.eventuallyLE (fun x hx ↦ by simp at hx ⊢; grind) set_option backward.defeqAttrib.useBackward false in /-- If a measure `μ` is the sum of a countable family `mₙ`, and a set `t` has finite measure for diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 6c8c36d2502f7f..67d07b423025bf 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -190,7 +190,7 @@ lemma notMem_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) suffices t ⊆ s \ t by have h := @disjoint_sdiff_self_right _ t s _ specialize h le_rfl this - simp only [Set.bot_eq_empty, Set.le_eq_subset, subset_empty_iff] at h + simp only [Set.bot_eq_empty, subset_empty_iff] at h refine hC.empty_notMem_disjointOfDiff hs ht ?_ rwa [← h] rw [← hC.sUnion_disjointOfDiff hs ht] @@ -214,7 +214,6 @@ lemma pairwiseDisjoint_insert_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ refine PairwiseDisjoint.insert_of_notMem h (hC.notMem_disjointOfDiff hs ht) fun u hu ↦ ?_ simp_rw [id] refine Disjoint.mono_right ?_ (hC.disjoint_sUnion_disjointOfDiff hs ht) - simp only [Set.le_eq_subset] exact subset_sUnion_of_mem hu end disjointOfDiff @@ -363,7 +362,7 @@ lemma disjoint_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : have h_disj : u ≤ ⊥ := hC.disjoint_sUnion_disjointOfDiffUnion hs hI (subset_sUnion_of_mem huI) (subset_sUnion_of_mem hu_disjointOfDiffUnion) - simp only [Set.bot_eq_empty, Set.le_eq_subset, subset_empty_iff] at h_disj + simp only [Set.bot_eq_empty, subset_empty_iff] at h_disj refine hC.empty_notMem_disjointOfDiffUnion hs hI ?_ rwa [h_disj] at hu_disjointOfDiffUnion @@ -439,7 +438,6 @@ theorem disjointOfUnion_props (hC : IsSetSemiring C) (h1 : ↑J ⊆ C) : (hC.subset_of_diffUnion_disjointOfDiffUnion h1.1 h1.2) ?_ (@disjoint_sdiff_left _ (⋃₀ J) s) (Or.inl (hC.empty_notMem_disjointOfDiffUnion h1.1 h1.2)) - simp only [mem_coe, Set.le_eq_subset] apply sUnion_subset_iff.mp exact (hK3 i hi).trans (subset_sUnion_of_mem hi) have h8 : Function.onFun Disjoint K1 s i := by diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean index 93253fa2861639..e4f0a7166d533b 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean @@ -127,7 +127,7 @@ private lemma exists_one_le_enorm_apply_of_semivariation_eq_top exact enorm_sub_le rwa [ENNReal.add_le_add_iff_right (by simp)] at this · refine ⟨s \ t, hs.diff t_meas, sdiff_subset, hI, ?_⟩ - simp only [_root_.sdiff_sdiff_right_self, le_eq_subset, ts, inf_of_le_right] + simp only [_root_.sdiff_sdiff_right_self, ts, inf_of_le_right] exact le_trans (by simp) h't private lemma semivariation_univ_lt_top : μ.semivariation univ < ∞ := by @@ -155,7 +155,7 @@ private lemma semivariation_univ_lt_top : μ.semivariation univ < ∞ := by apply (pairwise_disjoint_on _).2 (fun m n hmn ↦ ?_) have : Disjoint (u m) (s (m + 1)) := by simp [u, disjoint_sdiff_left] apply this.mono_right - simp only [sdiff_le_iff, sup_eq_union, le_eq_subset, u] + simp only [sdiff_le_iff, sup_eq_union, u] exact Subset.trans (s_anti (by grind)) subset_union_right have : HasSum (fun i => μ (u i)) (μ (⋃ i, u i)) := hasSum_of_disjoint_iUnion (fun n ↦ (hs n).1.diff (hs (n + 1)).1) u_disj diff --git a/Mathlib/NumberTheory/WellApproximable.lean b/Mathlib/NumberTheory/WellApproximable.lean index 51f2d6e1ac8f88..730fc04d079d20 100644 --- a/Mathlib/NumberTheory/WellApproximable.lean +++ b/Mathlib/NumberTheory/WellApproximable.lean @@ -253,7 +253,7 @@ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto suffices f '' A p ⊆ blimsup (fun n => approxAddOrderOf 𝕊 n (p * δ n)) atTop fun n => 0 < n ∧ p∤n by apply (ergodic_nsmul hp.one_lt).ae_empty_or_univ_of_image_ae_le (hA₀ p).nullMeasurableSet - apply (HasSubset.Subset.eventuallyLE this).congr EventuallyEq.rfl + apply (LE.le.eventuallyLE this).congr EventuallyEq.rfl exact blimsup_thickening_mul_ae_eq μ (fun n => 0 < n ∧ p∤n) (fun n => {y | addOrderOf y = n}) (Nat.cast_pos.mpr hp.pos) _ hδ refine (sSupHom.setImage f).apply_blimsup_le.trans (mono_blimsup fun n hn => ?_) @@ -267,7 +267,7 @@ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto f '' B p ⊆ blimsup (fun n => approxAddOrderOf 𝕊 n (p * δ n)) atTop fun n => 0 < n ∧ p∣∣n by apply (ergodic_nsmul_add x hp.one_lt).ae_empty_or_univ_of_image_ae_le (hB₀ p).nullMeasurableSet - apply (HasSubset.Subset.eventuallyLE this).congr EventuallyEq.rfl + apply (LE.le.eventuallyLE this).congr EventuallyEq.rfl exact blimsup_thickening_mul_ae_eq μ (fun n => 0 < n ∧ p∣∣n) (fun n => {y | addOrderOf y = n}) (Nat.cast_pos.mpr hp.pos) _ hδ refine (sSupHom.setImage f).apply_blimsup_le.trans (mono_blimsup ?_) @@ -279,7 +279,7 @@ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto replace h_div : n / p * p = n := Nat.div_mul_cancel h_div have hf : f = (fun y => x + y) ∘ fun y => p • y := by ext; simp [f, add_comm x] - simp_rw [Function.comp_apply, le_eq_subset] + simp_rw [Function.comp_apply] rw [sSupHom.setImage_toFun, hf, image_comp] have := @monotone_image 𝕊 𝕊 fun y => x + y specialize this (approxAddOrderOf.image_nsmul_subset (δ n) (n / p) hp.pos) diff --git a/Mathlib/Order/Birkhoff.lean b/Mathlib/Order/Birkhoff.lean index 694621681cc97b..30a8b437d88295 100644 --- a/Mathlib/Order/Birkhoff.lean +++ b/Mathlib/Order/Birkhoff.lean @@ -243,15 +243,13 @@ variable [DecidableEq α] birkhoffFinset (a ⊔ b) = birkhoffFinset a ∪ birkhoffFinset b := by classical dsimp [OrderEmbedding.birkhoffFinset] - rw [birkhoffSet_sup, OrderIso.coe_toOrderEmbedding] - simp + simp [birkhoffSet_sup] @[simp] lemma birkhoffFinset_inf (a b : α) : birkhoffFinset (a ⊓ b) = birkhoffFinset a ∩ birkhoffFinset b := by classical dsimp [OrderEmbedding.birkhoffFinset] - rw [birkhoffSet_inf, OrderIso.coe_toOrderEmbedding] - simp + simp [birkhoffSet_inf] end OrderEmbedding diff --git a/Mathlib/Order/BooleanAlgebra/Set.lean b/Mathlib/Order/BooleanAlgebra/Set.lean index e26e68df0f27bc..6d0c6ec6ab3679 100644 --- a/Mathlib/Order/BooleanAlgebra/Set.lean +++ b/Mathlib/Order/BooleanAlgebra/Set.lean @@ -157,16 +157,15 @@ theorem union_compl_self (s : Set α) : s ∪ sᶜ = univ := theorem compl_union_self (s : Set α) : sᶜ ∪ s = univ := by rw [union_comm, union_compl_self] theorem compl_subset_comm : sᶜ ⊆ t ↔ tᶜ ⊆ s := - @compl_le_iff_compl_le _ s _ _ + compl_le_iff_compl_le theorem subset_compl_comm : s ⊆ tᶜ ↔ t ⊆ sᶜ := - @le_compl_iff_le_compl _ _ _ t + le_compl_iff_le_compl -@[simp] theorem compl_subset_compl : sᶜ ⊆ tᶜ ↔ t ⊆ s := - @compl_le_compl_iff_le (Set α) _ _ _ + compl_le_compl_iff_le -@[gcongr] theorem compl_subset_compl_of_subset (h : t ⊆ s) : sᶜ ⊆ tᶜ := compl_subset_compl.2 h +theorem compl_subset_compl_of_subset (h : t ⊆ s) : sᶜ ⊆ tᶜ := by gcongr theorem subset_union_compl_iff_inter_subset {s t u : Set α} : s ⊆ t ∪ uᶜ ↔ s ∩ u ⊆ t := (@isCompl_compl _ u _).le_sup_right_iff_inf_left_le @@ -187,7 +186,9 @@ lemma disjoint_compl_right_iff_subset : Disjoint s tᶜ ↔ s ⊆ t := disjoint_ alias ⟨_, _root_.Disjoint.subset_compl_right⟩ := subset_compl_iff_disjoint_right alias ⟨_, _root_.Disjoint.subset_compl_left⟩ := subset_compl_iff_disjoint_left +@[deprecated LE.le.disjoint_compl_left (since := "2026-06-05")] alias ⟨_, _root_.HasSubset.Subset.disjoint_compl_left⟩ := disjoint_compl_left_iff_subset +@[deprecated LE.le.disjoint_compl_right (since := "2026-06-05")] alias ⟨_, _root_.HasSubset.Subset.disjoint_compl_right⟩ := disjoint_compl_right_iff_subset @[simp] lemma nonempty_compl_of_nontrivial [Nontrivial α] (x : α) : Set.Nonempty {x}ᶜ := exists_ne x @@ -227,7 +228,7 @@ theorem sdiff_nonempty {s t : Set α} : (s \ t).Nonempty ↔ ¬s ⊆ t := @[deprecated (since := "2026-06-03")] alias diff_nonempty := sdiff_nonempty -theorem sdiff_subset {s t : Set α} : s \ t ⊆ s := show s \ t ≤ s from sdiff_le +theorem sdiff_subset {s t : Set α} : s \ t ⊆ s := sdiff_le @[deprecated (since := "2026-06-03")] alias diff_subset := sdiff_subset @@ -308,19 +309,18 @@ theorem union_inter_compl_left_subset (s t : Set α) : (s ∪ t) ∩ sᶜ ⊆ t theorem union_inter_compl_right_subset (s t : Set α) : (s ∪ t) ∩ tᶜ ⊆ s := by simp [union_inter_distrib_right] -@[gcongr] theorem sdiff_subset_sdiff {s₁ s₂ t₁ t₂ : Set α} : s₁ ⊆ s₂ → t₂ ⊆ t₁ → s₁ \ t₁ ⊆ s₂ \ t₂ := sdiff_le_sdiff @[deprecated (since := "2026-06-03")] alias diff_subset_diff := sdiff_subset_sdiff -theorem sdiff_subset_sdiff_left {s₁ s₂ t : Set α} (h : s₁ ⊆ s₂) : s₁ \ t ⊆ s₂ \ t := - sdiff_le_sdiff_right ‹s₁ ≤ s₂› +theorem sdiff_subset_sdiff_left {s₁ s₂ t : Set α} (h : s₁ ⊆ s₂) : s₁ \ t ⊆ s₂ \ t := by + gcongr @[deprecated (since := "2026-06-03")] alias diff_subset_diff_left := sdiff_subset_sdiff_left -theorem sdiff_subset_sdiff_right {s t u : Set α} (h : t ⊆ u) : s \ u ⊆ s \ t := - sdiff_le_sdiff_left ‹t ≤ u› +theorem sdiff_subset_sdiff_right {s t u : Set α} (h : t ⊆ u) : s \ u ⊆ s \ t := by + gcongr @[deprecated (since := "2026-06-03")] alias diff_subset_diff_right := sdiff_subset_sdiff_right @@ -387,7 +387,7 @@ theorem sdiff_union_of_subset {s t : Set α} (h : t ⊆ s) : s \ t ∪ t = s := @[deprecated (since := "2026-06-03")] alias diff_union_of_subset := sdiff_union_of_subset theorem sdiff_subset_comm {s t u : Set α} : s \ t ⊆ u ↔ s \ u ⊆ t := - show s \ t ≤ u ↔ s \ u ≤ t from sdiff_le_comm + sdiff_le_comm @[deprecated (since := "2026-06-03")] alias diff_subset_comm := sdiff_subset_comm @@ -483,7 +483,7 @@ lemma disjoint_sdiff_right : Disjoint s (t \ s) := disjoint_sdiff_self_right lemma disjoint_sdiff_inter : Disjoint (s \ t) (s ∩ t) := disjoint_of_subset_right inter_subset_right disjoint_sdiff_left -lemma subset_sdiff : s ⊆ t \ u ↔ s ⊆ t ∧ Disjoint s u := le_iff_subset.symm.trans le_sdiff +lemma subset_sdiff : s ⊆ t \ u ↔ s ⊆ t ∧ Disjoint s u := le_sdiff @[deprecated (since := "2026-06-03")] alias subset_diff := subset_sdiff @@ -496,13 +496,16 @@ lemma sdiff_ssubset_left_iff : s \ t ⊂ s ↔ (s ∩ t).Nonempty := @[deprecated (since := "2026-06-03")] alias diff_ssubset_left_iff := sdiff_ssubset_left_iff -lemma _root_.HasSubset.Subset.sdiff_ssubset_of_nonempty (hst : s ⊆ t) (hs : s.Nonempty) : +lemma _root_.LE.le.sdiff_ssubset_of_nonempty (hst : s ⊆ t) (hs : s.Nonempty) : t \ s ⊂ t := by simpa [inter_eq_self_of_subset_right hst] +@[deprecated (since := "2026-06-05")] +alias _root_.HasSubset.Subset.sdiff_ssubset_of_nonempty := LE.le.sdiff_ssubset_of_nonempty + @[deprecated (since := "2026-06-03")] alias _root_.HasSubset.Subset.diff_ssubset_of_nonempty := - _root_.HasSubset.Subset.sdiff_ssubset_of_nonempty + _root_.LE.le.sdiff_ssubset_of_nonempty lemma ssubset_iff_sdiff_singleton : s ⊂ t ↔ ∃ a ∈ t, s ⊆ t \ {a} := by grind diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index 8931a089fb9421..12fbb67bd29471 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -103,11 +103,14 @@ lemma IsCofinalFor.of_subset (hst : s ⊆ t) : IsCofinalFor s t := fun a ha ↦ ⟨a, hst ha, le_rfl⟩ @[to_dual] -alias HasSubset.Subset.isCofinalFor := IsCofinalFor.of_subset +alias LE.le.isCofinalFor := IsCofinalFor.of_subset -@[deprecated HasSubset.Subset.isCofinalFor (since := "2026-01-08")] +@[deprecated (since := "2026-03-23")] alias HasSubset.Subset.isCofinalFor := LE.le.isCofinalFor +@[deprecated (since := "2026-03-23")] alias HasSubset.Subset.isCoinitialFor := LE.le.isCoinitialFor + +@[deprecated LE.le.isCofinalFor (since := "2026-01-08")] alias HasSubset.Subset.iscofinalfor := IsCofinalFor.of_subset -@[deprecated HasSubset.Subset.isCoinitialFor (since := "2026-01-08")] +@[deprecated LE.le.isCoinitialFor (since := "2026-01-08")] alias HasSubset.Subset.iscoinitialfor := IsCoinitialFor.of_subset @[to_dual (attr := refl)] diff --git a/Mathlib/Order/Defs/PartialOrder.lean b/Mathlib/Order/Defs/PartialOrder.lean index 010158276785fa..01d0d4d600790b 100644 --- a/Mathlib/Order/Defs/PartialOrder.lean +++ b/Mathlib/Order/Defs/PartialOrder.lean @@ -201,6 +201,9 @@ lemma le_antisymm_iff : a = b ↔ a ≤ b ∧ b ≤ a := lemma lt_of_le_of_ne : a ≤ b → a ≠ b → a < b := fun h₁ h₂ => lt_of_le_not_ge h₁ <| mt (le_antisymm h₁) h₂ +@[to_dual lt_of_ne_of_le'] +lemma lt_of_ne_of_le : a ≠ b → a ≤ b → a < b := flip lt_of_le_of_ne + /-- Equality is decidable if `≤` is. -/ def decidableEqOfDecidableLE [DecidableLE α] : DecidableEq α | a, b => diff --git a/Mathlib/Order/Filter/AtTopBot/Finset.lean b/Mathlib/Order/Filter/AtTopBot/Finset.lean index 5391b68de4f9c2..a750c1afea43ba 100644 --- a/Mathlib/Order/Filter/AtTopBot/Finset.lean +++ b/Mathlib/Order/Filter/AtTopBot/Finset.lean @@ -31,7 +31,7 @@ theorem atTop_finset_eq_iInf : (atTop : Filter (Finset α)) = ⨅ x : α, 𝓟 ( refine le_iInf fun s => le_principal_iff.2 <| mem_iInf_of_iInter s.finite_toSet (fun i => mem_principal_self _) ?_ - simp only [subset_def, mem_iInter, SetCoe.forall, mem_Ici, Finset.le_iff_subset, + simp only [subset_def, mem_iInter, SetCoe.forall, mem_Ici, Finset.mem_singleton, Finset.subset_iff, forall_eq] exact fun t => id diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index bd75a96d04af39..c9c47c96d06c0e 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -368,7 +368,7 @@ theorem principal_mono {s t : Set α} : 𝓟 s ≤ 𝓟 t ↔ s ⊆ t := by theorem monotone_principal : Monotone (𝓟 : Set α → Filter α) := fun _ _ => principal_mono.2 @[simp] theorem principal_eq_iff_eq {s t : Set α} : 𝓟 s = 𝓟 t ↔ s = t := by - simp only [le_antisymm_iff, le_principal_iff, mem_principal]; rfl + simp only [le_antisymm_iff, le_principal_iff, mem_principal] @[simp] theorem join_principal_eq_sSup {s : Set (Filter α)} : join (𝓟 s) = sSup s := rfl @@ -1273,9 +1273,11 @@ theorem Set.EqOn.eventuallyEq_of_mem {α β} {s : Set α} {l : Filter α} {f g : (hl : s ∈ l) : f =ᶠ[l] g := h.eventuallyEq.filter_mono <| Filter.le_principal_iff.2 hl -theorem HasSubset.Subset.eventuallyLE {α} {l : Filter α} {s t : Set α} (h : s ⊆ t) : s ≤ᶠ[l] t := +theorem LE.le.eventuallyLE {α} {l : Filter α} {s t : Set α} (h : s ⊆ t) : s ≤ᶠ[l] t := Filter.Eventually.of_forall h +@[deprecated (since := "2026-03-16")] alias HasSubset.Subset.eventuallyLE := LE.le.eventuallyLE + variable {α β : Type*} {F : Filter α} {G : Filter β} namespace Filter diff --git a/Mathlib/Order/Filter/CountableInter.lean b/Mathlib/Order/Filter/CountableInter.lean index d8b3c95ba95775..157177640ee2e9 100644 --- a/Mathlib/Order/Filter/CountableInter.lean +++ b/Mathlib/Order/Filter/CountableInter.lean @@ -273,7 +273,7 @@ theorem mem_countableGenerate_iff {s : Set α} : s ∈ countableGenerate g ↔ ∃ S : Set (Set α), S ⊆ g ∧ S.Countable ∧ ⋂₀ S ⊆ s := by constructor <;> intro h · induction h with - | @basic s hs => exact ⟨{s}, by simp [hs, subset_refl]⟩ + | @basic s hs => exact ⟨{s}, by simp [hs]⟩ | univ => exact ⟨∅, by simp⟩ | superset _ _ ih => refine Exists.imp (fun S => ?_) ih; tauto | @sInter S Sct _ ih => diff --git a/Mathlib/Order/Filter/Ker.lean b/Mathlib/Order/Filter/Ker.lean index 2f33a646d2f0d0..9e397bb1f6d2e9 100644 --- a/Mathlib/Order/Filter/Ker.lean +++ b/Mathlib/Order/Filter/Ker.lean @@ -33,7 +33,7 @@ lemma ker_def (f : Filter α) : f.ker = ⋂ s ∈ f, s := sInter_eq_biInter /-- `Filter.principal` forms a Galois coinsertion with `Filter.ker`. -/ def gi_principal_ker : GaloisCoinsertion (𝓟 : Set α → Filter α) ker := GaloisConnection.toGaloisCoinsertion (fun s f ↦ by simp [principal_le_iff]) <| by - simp only [le_iff_subset, subset_def, mem_ker, mem_principal]; aesop + simp only [subset_def, mem_ker, mem_principal]; aesop lemma ker_mono : Monotone (ker : Filter α → Set α) := gi_principal_ker.gc.monotone_u lemma ker_surjective : Surjective (ker : Filter α → Set α) := gi_principal_ker.u_surjective diff --git a/Mathlib/Order/Heyting/Basic.lean b/Mathlib/Order/Heyting/Basic.lean index 606f033f833aa7..9cf8edd7dc9b3a 100644 --- a/Mathlib/Order/Heyting/Basic.lean +++ b/Mathlib/Order/Heyting/Basic.lean @@ -386,7 +386,7 @@ section GeneralizedCoheytingAlgebra variable [GeneralizedCoheytingAlgebra α] {a b c d : α} -@[simp] +@[simp low] -- low priority so that it doesn't overwrite user-provided simp lemmas theorem sdiff_le_iff : a \ b ≤ c ↔ a ≤ b ⊔ c := GeneralizedCoheytingAlgebra.sdiff_le_iff _ _ _ diff --git a/Mathlib/Order/Interval/Finset/Defs.lean b/Mathlib/Order/Interval/Finset/Defs.lean index a5bffe2d632411..6d15eb06998abd 100644 --- a/Mathlib/Order/Interval/Finset/Defs.lean +++ b/Mathlib/Order/Interval/Finset/Defs.lean @@ -810,7 +810,7 @@ using `WithBot.some` and then insert `⊥`. -/] def insertTop : Finset α ↪o Finset (WithTop α) := OrderEmbedding.ofMapLEIff (fun s => cons ⊤ (s.map Embedding.coeWithTop) <| by simp) - (fun s t => by rw [le_iff_subset, cons_subset_cons, map_subset_map, le_iff_subset]) + (fun s t => by rw [cons_subset_cons, map_subset_map]) @[to_dual (attr := simp)] theorem some_mem_insertTop {s : Finset α} {a : α} : ↑a ∈ insertTop s ↔ a ∈ s := by diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index da71eb7e9a05ce..d723c5a5569ee3 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -741,7 +741,7 @@ lemma mem_limsup_iff_frequently_mem : (a ∈ limsup s 𝓕) ↔ (∃ᶠ i in theorem cofinite.blimsup_set_eq : blimsup s cofinite p = { x | { n | p n ∧ x ∈ s n }.Infinite } := by - simp only [blimsup_eq, le_eq_subset, eventually_cofinite, not_forall, sInf_eq_sInter, exists_prop] + simp only [blimsup_eq, eventually_cofinite, not_forall, sInf_eq_sInter, exists_prop] ext x refine ⟨fun h => ?_, fun hx t h => ?_⟩ <;> contrapose h · simp only [mem_sInter, mem_setOf_eq, not_forall, exists_prop] diff --git a/Mathlib/Order/PrimeSeparator.lean b/Mathlib/Order/PrimeSeparator.lean index ab01162743bf4b..60d5cbfd67f8c5 100644 --- a/Mathlib/Order/PrimeSeparator.lean +++ b/Mathlib/Order/PrimeSeparator.lean @@ -53,7 +53,7 @@ theorem DistribLattice.prime_ideal_of_disjoint_filter_ideal [DistribLattice α] intro c hcS hcC hcNe use sUnion c refine ⟨?_, fun s hs ↦ le_sSup hs⟩ - simp only [le_eq_subset, mem_setOf_eq, disjoint_sUnion_right, S] + simp only [mem_setOf_eq, disjoint_sUnion_right, S] let ⟨J, hJ⟩ := hcNe refine ⟨Order.isIdeal_sUnion_of_isChain (fun _ hJ ↦ (hcS hJ).1) hcC hcNe, ⟨le_trans (hcS hJ).2.1 (le_sSup hJ), fun J hJ ↦ (hcS hJ).2.2⟩⟩ @@ -88,12 +88,12 @@ theorem DistribLattice.prime_ideal_of_disjoint_filter_ideal [DistribLattice α] have J₁F : ¬ (Disjoint (F : Set α) J₁) := by intro hdis apply J₁S - simp only [le_eq_subset, mem_setOf_eq, SetLike.coe_subset_coe, S] + simp only [mem_setOf_eq, SetLike.coe_subset_coe, S] exact ⟨J₁.isIdeal, le_trans IJ' le_sup_left, hdis⟩ have J₂F : ¬ (Disjoint (F : Set α) J₂) := by intro hdis apply J₂S - simp only [le_eq_subset, mem_setOf_eq, SetLike.coe_subset_coe, S] + simp only [mem_setOf_eq, SetLike.coe_subset_coe, S] exact ⟨J₂.isIdeal, le_trans IJ' le_sup_left, hdis⟩ -- Thus, pick cᵢ ∈ F ∩ Jᵢ. let ⟨c₁, ⟨c₁F, c₁J₁⟩⟩ := Set.not_disjoint_iff.1 J₁F diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index 93485384b10b30..09e339e37e4153 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -468,185 +468,96 @@ instance {s : α → α → Prop} [IsNonstrictStrictOrder α r s] : Std.Irrefl s /-! #### `⊆` and `⊂` -/ section Subset -variable [HasSubset α] {a b c : α} -lemma subset_of_eq_of_subset (hab : a = b) (hbc : b ⊆ c) : a ⊆ c := by rwa [hab] +attribute [to_set_notation] + le_of_eq_of_le le_of_le_of_eq le_refl le_rfl le_of_eq ge_of_eq ne_of_not_le ne_of_not_ge + le_trans le_antisymm ge_antisymm Eq.trans_le Eq.le Eq.ge le_antisymm_iff ge_antisymm_iff -lemma subset_of_subset_of_eq (hab : a ⊆ b) (hbc : b = c) : a ⊆ c := by rwa [← hbc] - -@[refl, simp] -lemma subset_refl [@Std.Refl α (· ⊆ ·)] (a : α) : a ⊆ a := refl _ - -lemma subset_rfl [@Std.Refl α (· ⊆ ·)] : a ⊆ a := refl _ - -lemma subset_of_eq [@Std.Refl α (· ⊆ ·)] : a = b → a ⊆ b := fun h => h ▸ subset_rfl - -lemma superset_of_eq [@Std.Refl α (· ⊆ ·)] : a = b → b ⊆ a := fun h => h ▸ subset_rfl - -lemma ne_of_not_subset [@Std.Refl α (· ⊆ ·)] : ¬a ⊆ b → a ≠ b := mt subset_of_eq - -lemma ne_of_not_superset [@Std.Refl α (· ⊆ ·)] : ¬a ⊆ b → b ≠ a := mt superset_of_eq - -@[trans] -lemma subset_trans [IsTrans α (· ⊆ ·)] {a b c : α} : a ⊆ b → b ⊆ c → a ⊆ c := _root_.trans - -lemma subset_antisymm [@Std.Antisymm α (· ⊆ ·)] : a ⊆ b → b ⊆ a → a = b := antisymm - -lemma superset_antisymm [@Std.Antisymm α (· ⊆ ·)] : a ⊆ b → b ⊆ a → b = a := antisymm' - -alias Eq.trans_subset := subset_of_eq_of_subset - -alias HasSubset.subset.trans_eq := subset_of_subset_of_eq - -alias Eq.subset := subset_of_eq +@[deprecated (since := "2026-05-24")] alias HasSubset.subset.trans_eq := LE.le.trans_eq @[deprecated (since := "2026-01-24")] alias Eq.subset' := Eq.subset -alias Eq.superset := superset_of_eq - +@[deprecated LE.le.trans (since := "2026-05-24")] alias HasSubset.Subset.trans := subset_trans +@[deprecated LE.le.antisymm (since := "2026-05-24")] alias HasSubset.Subset.antisymm := subset_antisymm +@[deprecated LE.le.antisymm' (since := "2026-05-24")] alias HasSubset.Subset.antisymm' := superset_antisymm -theorem subset_antisymm_iff [@Std.Refl α (· ⊆ ·)] [@Std.Antisymm α (· ⊆ ·)] : - a = b ↔ a ⊆ b ∧ b ⊆ a := - ⟨fun h => ⟨h.subset, h.superset⟩, fun h => h.1.antisymm h.2⟩ - -theorem superset_antisymm_iff [@Std.Refl α (· ⊆ ·)] [@Std.Antisymm α (· ⊆ ·)] : - a = b ↔ b ⊆ a ∧ a ⊆ b := - ⟨fun h => ⟨h.superset, h.subset⟩, fun h => h.1.antisymm' h.2⟩ - end Subset -section Ssubset -variable [HasSSubset α] {a b c : α} - -lemma ssubset_of_eq_of_ssubset (hab : a = b) (hbc : b ⊂ c) : a ⊂ c := by rwa [hab] - -lemma ssubset_of_ssubset_of_eq (hab : a ⊂ b) (hbc : b = c) : a ⊂ c := by rwa [← hbc] - -lemma ssubset_irrefl [@Std.Irrefl α (· ⊂ ·)] (a : α) : ¬a ⊂ a := irrefl _ - -lemma ssubset_irrfl [@Std.Irrefl α (· ⊂ ·)] {a : α} : ¬a ⊂ a := irrefl _ - -lemma ne_of_ssubset [@Std.Irrefl α (· ⊂ ·)] {a b : α} : a ⊂ b → a ≠ b := ne_of_irrefl - -lemma ne_of_ssuperset [@Std.Irrefl α (· ⊂ ·)] {a b : α} : a ⊂ b → b ≠ a := ne_of_irrefl' - -@[trans] -lemma ssubset_trans [IsTrans α (· ⊂ ·)] {a b c : α} : a ⊂ b → b ⊂ c → a ⊂ c := _root_.trans - -lemma ssubset_asymm [Std.Asymm (α := α) (· ⊂ ·)] {a b : α} : a ⊂ b → ¬b ⊂ a := asymm - -alias Eq.trans_ssubset := ssubset_of_eq_of_ssubset - -alias HasSSubset.SSubset.trans_eq := ssubset_of_ssubset_of_eq - -alias HasSSubset.SSubset.false := ssubset_irrfl - -alias HasSSubset.SSubset.ne := ne_of_ssubset - -alias HasSSubset.SSubset.ne' := ne_of_ssuperset - -alias HasSSubset.SSubset.trans := ssubset_trans - -alias HasSSubset.SSubset.asymm := ssubset_asymm - -end Ssubset - -section SubsetSsubset - -variable [HasSubset α] [HasSSubset α] [IsNonstrictStrictOrder α (· ⊆ ·) (· ⊂ ·)] {a b c : α} - -theorem ssubset_iff_subset_not_subset : a ⊂ b ↔ a ⊆ b ∧ ¬b ⊆ a := - right_iff_left_not_left - -theorem subset_of_ssubset (h : a ⊂ b) : a ⊆ b := - (ssubset_iff_subset_not_subset.1 h).1 - -theorem not_subset_of_ssubset (h : a ⊂ b) : ¬b ⊆ a := - (ssubset_iff_subset_not_subset.1 h).2 - -theorem not_ssubset_of_subset (h : a ⊆ b) : ¬b ⊂ a := fun h' => not_subset_of_ssubset h' h - -theorem ssubset_of_subset_not_subset (h₁ : a ⊆ b) (h₂ : ¬b ⊆ a) : a ⊂ b := - ssubset_iff_subset_not_subset.2 ⟨h₁, h₂⟩ - -alias HasSSubset.SSubset.subset := subset_of_ssubset - -alias HasSSubset.SSubset.not_subset := not_subset_of_ssubset - -alias HasSubset.Subset.not_ssubset := not_ssubset_of_subset - -alias HasSubset.Subset.ssubset_of_not_subset := ssubset_of_subset_not_subset - -theorem ssubset_of_subset_of_ssubset [IsTrans α (· ⊆ ·)] (h₁ : a ⊆ b) (h₂ : b ⊂ c) : a ⊂ c := - (h₁.trans h₂.subset).ssubset_of_not_subset fun h => h₂.not_subset <| h.trans h₁ - -theorem ssubset_of_ssubset_of_subset [IsTrans α (· ⊆ ·)] (h₁ : a ⊂ b) (h₂ : b ⊆ c) : a ⊂ c := - (h₁.subset.trans h₂).ssubset_of_not_subset fun h => h₁.not_subset <| h₂.trans h - -theorem ssubset_of_subset_of_ne [@Std.Antisymm α (· ⊆ ·)] (h₁ : a ⊆ b) (h₂ : a ≠ b) : a ⊂ b := - h₁.ssubset_of_not_subset <| mt h₁.antisymm h₂ - -theorem ssubset_of_ne_of_subset [@Std.Antisymm α (· ⊆ ·)] (h₁ : a ≠ b) (h₂ : a ⊆ b) : a ⊂ b := - ssubset_of_subset_of_ne h₂ h₁ - -theorem eq_or_ssubset_of_subset [@Std.Antisymm α (· ⊆ ·)] (h : a ⊆ b) : a = b ∨ a ⊂ b := - (em (b ⊆ a)).imp h.antisymm h.ssubset_of_not_subset - -theorem ssubset_or_eq_of_subset [@Std.Antisymm α (· ⊆ ·)] (h : a ⊆ b) : a ⊂ b ∨ a = b := - (eq_or_ssubset_of_subset h).symm - -lemma eq_of_subset_of_not_ssubset [@Std.Antisymm α (· ⊆ ·)] (hab : a ⊆ b) (hba : ¬ a ⊂ b) : a = b := - (eq_or_ssubset_of_subset hab).resolve_right hba +section SSubset -lemma eq_of_superset_of_not_ssuperset [@Std.Antisymm α (· ⊆ ·)] (hab : a ⊆ b) (hba : ¬ a ⊂ b) : - b = a := ((eq_or_ssubset_of_subset hab).resolve_right hba).symm +attribute [to_set_notation] + lt_of_eq_of_lt lt_of_lt_of_eq lt_irrefl ne_of_lt ne_of_gt lt_trans lt_asymm Eq.trans_lt -alias HasSubset.Subset.trans_ssubset := ssubset_of_subset_of_ssubset +@[deprecated (since := "2026-06-11")] alias ssubset_irrfl := ssubset_irrefl -alias HasSSubset.SSubset.trans_subset := ssubset_of_ssubset_of_subset +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.trans_eq := LT.lt.trans_eq -alias HasSubset.Subset.ssubset_of_ne := ssubset_of_subset_of_ne +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.false := LT.lt.false -alias Ne.ssubset_of_subset := ssubset_of_ne_of_subset +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.ne := LT.lt.ne -alias HasSubset.Subset.eq_or_ssubset := eq_or_ssubset_of_subset +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.ne' := LT.lt.ne' -alias HasSubset.Subset.ssubset_or_eq := ssubset_or_eq_of_subset +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.trans := LT.lt.trans -alias HasSubset.Subset.eq_of_not_ssubset := eq_of_subset_of_not_ssubset -alias HasSubset.Subset.eq_of_not_ssuperset := eq_of_superset_of_not_ssuperset +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.asymm := LT.lt.asymm -theorem ssubset_iff_subset_ne [@Std.Antisymm α (· ⊆ ·)] : a ⊂ b ↔ a ⊆ b ∧ a ≠ b := - ⟨fun h => ⟨h.subset, h.ne⟩, fun h => h.1.ssubset_of_ne h.2⟩ +end SSubset -theorem subset_iff_ssubset_or_eq [@Std.Refl α (· ⊆ ·)] [@Std.Antisymm α (· ⊆ ·)] : - a ⊆ b ↔ a ⊂ b ∨ a = b := - ⟨fun h => h.ssubset_or_eq, fun h => h.elim subset_of_ssubset subset_of_eq⟩ +section SubsetSSubset -namespace GCongr +attribute [to_set_notation] lt_iff_le_not_ge le_of_lt + not_le_of_gt not_lt_of_ge lt_of_le_not_ge + LT.lt.le LT.lt.not_ge LE.le.not_gt LE.le.lt_of_not_ge + lt_of_le_of_lt lt_of_lt_of_le lt_of_le_of_ne lt_of_ne_of_le eq_or_lt_of_le lt_or_eq_of_le + eq_of_le_of_not_lt eq_of_le_of_not_lt' + LE.le.trans_lt LT.lt.trans_le LE.le.lt_of_ne Ne.lt_of_le + LE.le.eq_or_lt LE.le.lt_or_eq + LE.le.eq_of_not_lt LE.le.eq_of_not_lt' + lt_iff_le_and_ne le_iff_lt_or_eq -variable [IsTrans α (· ⊆ ·)] {a b c d : α} +-- TODO: deprecate these aliases +alias ssubset_iff_subset_not_subset := ssubset_iff_subset_not_superset +alias not_subset_of_ssubset := not_subset_of_ssuperset +alias not_ssubset_of_subset := not_ssubset_of_superset +alias ssubset_of_subset_not_subset := ssubset_of_subset_not_superset +alias LT.lt.not_subset := LT.lt.not_superset +alias LE.le.not_ssubset := LE.le.not_ssuperset +alias LE.le.ssubset_of_not_subset := LE.le.ssubset_of_not_superset -@[gcongr] -theorem ssubset_imp_ssubset (h₁ : c ⊆ a) (h₂ : b ⊆ d) : a ⊂ b → c ⊂ d := - fun h => (h₁.trans_ssubset h).trans_subset h₂ +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.subset := LT.lt.subset +@[deprecated (since := "2026-05-24")] alias HasSSubset.SSubset.not_subset := LT.lt.not_superset +@[deprecated (since := "2026-05-24")] alias HasSubset.Subset.not_ssubset := LE.le.not_ssuperset +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.ssubset_of_not_subset := LE.le.ssubset_of_not_superset -@[gcongr] -theorem ssuperset_imp_ssuperset (h₁ : a ⊆ c) (h₂ : d ⊆ b) : a ⊃ b → c ⊃ d := - ssubset_imp_ssubset h₂ h₁ +alias eq_of_superset_of_not_ssuperset := eq_of_subset_of_not_ssubset' +alias LE.le.eq_of_not_ssuperset := LE.le.eq_of_not_ssubset' -/-- See if the term is `a ⊂ b` and the goal is `a ⊆ b`. -/ -@[gcongr_forward] meta def exactSubsetOfSSubset : Mathlib.Tactic.GCongr.ForwardExt where - eval h goal := do goal.assignIfDefEq (← Lean.Meta.mkAppM ``subset_of_ssubset #[h]) +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.trans_ssubset := LE.le.trans_ssubset +@[deprecated (since := "2026-05-24")] +alias HasSSubset.SSubset.trans_subset := LT.lt.trans_subset +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.ssubset_of_ne := LE.le.ssubset_of_ne +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.eq_or_ssubset := LE.le.eq_or_ssubset +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.ssubset_or_eq := LE.le.ssubset_or_eq +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.eq_of_not_ssubset := LE.le.eq_of_not_ssubset +@[deprecated (since := "2026-05-24")] +alias HasSubset.Subset.eq_of_not_ssuperset := LE.le.eq_of_not_ssuperset -end GCongr +-- TODO: deprecate +alias ssubset_iff_subset_ne := ssubset_iff_subset_and_ne -end SubsetSsubset +end SubsetSSubset /-! ### Conversion of bundled order typeclasses to unbundled relation typeclasses -/ diff --git a/Mathlib/Probability/Process/HittingTime.lean b/Mathlib/Probability/Process/HittingTime.lean index c84010217a9a73..6f0144b035b6b5 100644 --- a/Mathlib/Probability/Process/HittingTime.lean +++ b/Mathlib/Probability/Process/HittingTime.lean @@ -319,7 +319,7 @@ lemma hittingBtwn_anti (u : ι → Ω → β) (n m : ι) : Antitone (hittingBtwn simp only [hittingBtwn_def] split_ifs with hF hE hE · gcongr - exacts [⟨n, by simp [mem_lowerBounds]; grind⟩, hEF] + exact ⟨n, by simp [mem_lowerBounds]; grind⟩ · obtain ⟨t, ht⟩ := hF exact csInf_le_of_le ⟨n, by simp [mem_lowerBounds]; grind⟩ ht ht.1.2 · obtain ⟨t, ht⟩ := hE @@ -333,7 +333,7 @@ lemma hittingAfter_anti (u : ι → Ω → β) (n : ι) : Antitone (hittingAfter split_ifs with hF hE hE · norm_cast gcongr - exacts [⟨n, by simp only [mem_lowerBounds]; grind⟩, hEF] + exact ⟨n, by simp only [mem_lowerBounds]; grind⟩ · simp · obtain ⟨t, ht⟩ := hE exact absurd ⟨t, ht.1, hEF ht.2⟩ hF diff --git a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean index c50fad7f0f99e2..eb4677becdaabe 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean @@ -320,7 +320,7 @@ theorem matroid_isBasis_iff_of_subsingleton [Subsingleton A] {s t : Set A} : (matroid R A).IsBasis s t ↔ s = t := by have := (FaithfulSMul.algebraMap_injective R A).subsingleton simp_rw [Matroid.IsBasis, matroid_indep_iff, of_subsingleton, true_and, - matroid_e, subset_univ, and_true, ← le_iff_subset, maximal_le_iff] + matroid_e, subset_univ, and_true, maximal_le_iff] theorem isAlgebraic_adjoin_iff_of_matroid_isBasis [NoZeroDivisors A] {s t : Set A} {a : A} (h : (matroid R A).IsBasis s t) : IsAlgebraic (adjoin R s) a ↔ IsAlgebraic (adjoin R t) a := by @@ -404,7 +404,7 @@ theorem exists_isTranscendenceBasis_subset [NoZeroDivisors A] [FaithfulSMul R A] theorem isAlgebraic_iff_exists_isTranscendenceBasis_subset [IsDomain A] [FaithfulSMul R A] {s : Set A} : Algebra.IsAlgebraic (adjoin R s) A ↔ ∃ t, t ⊆ s ∧ IsTranscendenceBasis R ((↑) : t → A) := by - simp_rw [← matroid_spanning_iff, ← matroid_isBase_iff, and_comm (a := _ ⊆ _)] + simp_rw [← matroid_spanning_iff, ← matroid_isBase_iff, and_comm (a := _ ⊆ s)] exact Matroid.spanning_iff_exists_isBase_subset (subset_univ _) open Cardinal AlgebraicIndependent diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean index 9e7bea20b4441b..eb538bb3c80dae 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean @@ -152,7 +152,7 @@ theorem eval_one_cyclotomic_not_prime_pow {R : Type*} [Ring R] {n : ℕ} rw [eval_geom_sum, one_geom_sum, eval_prod, eq_comm, ← Finset.prod_sdiff <| @range_pow_padicValNat_subset_divisors' p _ _, Finset.prod_image] at this · simp_rw [eval_one_cyclotomic_prime_pow, Finset.prod_const, Finset.card_range, mul_comm] at this - rw [← Finset.prod_sdiff <| show {n} ⊆ _ from _] at this + rw [← Finset.prod_sdiff (s₁ := {n})] at this swap · simp only [singleton_subset_iff, mem_sdiff, mem_erase, Ne, mem_divisors, dvd_refl, true_and, mem_image, mem_range, not_exists, not_and] diff --git a/Mathlib/RingTheory/Spectrum/Prime/Module.lean b/Mathlib/RingTheory/Spectrum/Prime/Module.lean index 97da9964813383..830b1a4a766eb4 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Module.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Module.lean @@ -38,7 +38,7 @@ lemma LocalizedModule.subsingleton_iff_disjoint {f : R} : Subsingleton (LocalizedModule.Away f M) ↔ Disjoint ↑(PrimeSpectrum.basicOpen f) (Module.support R M) := by rw [subsingleton_iff_support_subset, PrimeSpectrum.basicOpen_eq_zeroLocus_compl, - disjoint_compl_left_iff, Set.le_iff_subset] + disjoint_compl_left_iff] lemma Module.stableUnderSpecialization_support : StableUnderSpecialization (Module.support R M) := fun x y e ↦ mem_support_mono <| (PrimeSpectrum.le_iff_specializes x y).mpr e diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index acf7312daad3e1..162994b751eef2 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -44,7 +44,7 @@ universe u /-- The ZFC universe of sets consists of the type of pre-sets, quotiented by extensional equivalence. -/ -@[pp_with_univ] +@[pp_with_univ, use_set_notation_for_order] def ZFSet : Type (u + 1) := Quotient PSet.setoid.{u} @@ -211,15 +211,10 @@ theorem nonempty_of_mem {x u : ZFSet} (h : x ∈ u) : u.Nonempty := @[simp, norm_cast] lemma nonempty_coe : (x : Set ZFSet.{u}).Nonempty ↔ x.Nonempty := .rfl -/-- `x ⊆ y` as ZFC sets means that all members of `x` are members of `y`. -/ -protected def Subset (x y : ZFSet.{u}) := - ∀ ⦃z⦄, z ∈ x → z ∈ y - -instance : HasSubset ZFSet := ⟨ZFSet.Subset⟩ -instance : HasSSubset ZFSet := ⟨(· < ·)⟩ - -@[simp] lemma le_def : x ≤ y ↔ x ⊆ y := .rfl -@[simp] lemma lt_def : x < y ↔ x ⊂ y := .rfl +@[deprecated "This is now a syntactic equality" (since := "2026-03-18"), nolint synTaut] +lemma le_def : x ≤ y ↔ x ⊆ y := .rfl +@[deprecated "This is now a syntactic equality" (since := "2026-03-18"), nolint synTaut] +lemma lt_def : x < y ↔ x ⊂ y := .rfl theorem subset_def {x y : ZFSet.{u}} : x ⊆ y ↔ ∀ ⦃z⦄, z ∈ x → z ∈ y := Iff.rfl @@ -238,7 +233,7 @@ theorem subset_iff : ∀ {x y : PSet}, mk x ⊆ mk y ↔ x ⊆ y let ⟨b, ab⟩ := h a ⟨b, za.trans ab⟩⟩ -lemma coe_subset_coe : (x : Set ZFSet.{u}) ⊆ y ↔ x ⊆ y := by simp +lemma coe_subset_coe : (x : Set ZFSet.{u}) ⊆ y ↔ x ⊆ y := SetLike.coe_subset_coe instance : @Std.Antisymm ZFSet (· ⊆ ·) := ⟨@le_antisymm ZFSet _⟩ diff --git a/Mathlib/SetTheory/ZFC/Class.lean b/Mathlib/SetTheory/ZFC/Class.lean index f7e5c204719ffe..5f0361f21f384d 100644 --- a/Mathlib/SetTheory/ZFC/Class.lean +++ b/Mathlib/SetTheory/ZFC/Class.lean @@ -31,9 +31,9 @@ universe u We define `Class` as `Set ZFSet`, as this allows us to get many instances automatically. However, in practice, we treat it as (the definitionally equal) `ZFSet → Prop`. This means, the preferred way to state that `x : ZFSet` belongs to `A : Class` is to write `A x`. -/ -@[pp_with_univ] +@[pp_with_univ, use_set_notation_for_order] def Class := - Set ZFSet deriving HasSubset, EmptyCollection, Nonempty, Union, Inter, Compl, SDiff + Set ZFSet deriving LE, EmptyCollection, Nonempty, Union, Inter, Compl, SDiff instance : Insert ZFSet Class := ⟨Set.insert⟩ diff --git a/Mathlib/SetTheory/ZFC/Ordinal.lean b/Mathlib/SetTheory/ZFC/Ordinal.lean index 33ea38e7fe01b0..4c6cc793d9b0a3 100644 --- a/Mathlib/SetTheory/ZFC/Ordinal.lean +++ b/Mathlib/SetTheory/ZFC/Ordinal.lean @@ -349,7 +349,7 @@ theorem toZFSet_subset_toZFSet_iff {a b : Ordinal} : a.toZFSet ⊆ b.toZFSet ↔ exact fun h ↦ not_subset_of_mem (toZFSet_mem_toZFSet_of_lt h) theorem toZFSet_strictMono : StrictMono toZFSet := - fun _ _ h ↦ by simpa [ssubset_iff_subset_not_subset] using ⟨h.le, h⟩ + fun _ _ h ↦ by rw [ssubset_iff_subset_not_subset]; simp [h, h.le] theorem toZFSet_injective : Function.Injective toZFSet := toZFSet_strictMono.injective diff --git a/Mathlib/SetTheory/ZFC/PSet.lean b/Mathlib/SetTheory/ZFC/PSet.lean index 1e6516a0bbdc19..7c20f1bef9f645 100644 --- a/Mathlib/SetTheory/ZFC/PSet.lean +++ b/Mathlib/SetTheory/ZFC/PSet.lean @@ -35,7 +35,7 @@ universe u v is a family of pre-sets indexed by a type in `Type u`. The ZFC universe is defined as a quotient of this to ensure extensionality. -/ -@[pp_with_univ] +@[pp_with_univ, use_set_notation_for_order] inductive PSet : Type (u + 1) | mk (α : Type u) (A : α → PSet) : PSet @@ -117,17 +117,15 @@ equivalent to some element of the second family. -/ protected def Subset (x y : PSet) : Prop := ∀ a, ∃ b, Equiv (x.Func a) (y.Func b) -instance : HasSubset PSet := +instance : LE PSet := ⟨PSet.Subset⟩ -instance : @Std.Refl PSet (· ⊆ ·) := - ⟨fun _ a => ⟨a, Equiv.refl _⟩⟩ - -instance : IsTrans PSet (· ⊆ ·) := - ⟨fun x y z hxy hyz a => by +instance : Preorder PSet where + le_refl _ a := ⟨a, Equiv.refl _⟩ + le_trans x y z hxy hyz a := by obtain ⟨b, hb⟩ := hxy a obtain ⟨c, hc⟩ := hyz b - exact ⟨c, hb.trans hc⟩⟩ + exact ⟨c, hb.trans hc⟩ theorem Equiv.ext : ∀ x y : PSet, Equiv x y ↔ x ⊆ y ∧ y ⊆ x | ⟨_, _⟩, ⟨_, _⟩ => @@ -162,24 +160,14 @@ theorem Subset.congr_right : ∀ {x y z : PSet}, Equiv x y → (z ⊆ x ↔ z let ⟨a, ab⟩ := βα b ⟨a, cb.trans (Equiv.symm ab)⟩⟩ -instance : Preorder PSet where - le := (· ⊆ ·) - le_refl := refl_of (· ⊆ ·) - le_trans _ _ _ := trans_of (· ⊆ ·) - -instance : HasSSubset PSet := ⟨(· < ·)⟩ - -@[simp] +@[deprecated "This is now a syntactic equality" (since := "2026-03-18"), nolint synTaut] theorem le_def (x y : PSet) : x ≤ y ↔ x ⊆ y := Iff.rfl -@[simp] +@[deprecated "This is now a syntactic equality" (since := "2026-03-18"), nolint synTaut] theorem lt_def (x y : PSet) : x < y ↔ x ⊂ y := Iff.rfl -instance : IsNonstrictStrictOrder PSet (· ⊆ ·) (· ⊂ ·) := - ⟨fun _ _ ↦ Iff.rfl⟩ - /-- `x ∈ y` as pre-sets if `x` is extensionally equivalent to a member of the family `y`. -/ protected def Mem (y x : PSet.{u}) : Prop := ∃ b, Equiv x (y.Func b) diff --git a/Mathlib/Tactic/SetNotationForOrder.lean b/Mathlib/Tactic/SetNotationForOrder.lean index e406431108dc5d..b8a5b03d200ae9 100644 --- a/Mathlib/Tactic/SetNotationForOrder.lean +++ b/Mathlib/Tactic/SetNotationForOrder.lean @@ -8,6 +8,8 @@ module public meta import Batteries.Lean.NameMapAttribute public meta import Lean.Elab.App public meta import Mathlib.Lean.PrettyPrinter.Delaborator +public import Mathlib.Tactic.Translate.GuessName +public import Mathlib.Util.AddRelatedDecl /-! # Set notation for order operations @@ -27,31 +29,44 @@ since they have both `≤` and `⊆` defined on them, with different meanings. TODO: Unify more order operations suh as `∪`/`⊔` and `∩`/`⊓`. -/ +/-- `UsesSetNotationForOrder` is used to track whether a type is tagged with +`@[use_set_notation_for_order]`. -/ +public class UsesSetNotationForOrder (α : Type*) + meta section namespace Mathlib.Meta.SetNotationForOrder -open Lean Meta Elab Term PrettyPrinter.Delaborator SubExpr +open Mathlib.Tactic Lean Meta Elab Term PrettyPrinter.Delaborator SubExpr + +/-- Add an instance of `UsesSetNotationForOrder` for `declName`. -/ +def mkUsesSetNotationForOrderInstance (declName : Name) (kind : AttributeKind) : CoreM Unit := + MetaM.run' do + let cinfo ← getConstInfo declName + forallTelescope cinfo.type fun xs _ ↦ do + let instName := .str declName "instUsesSetNotationForOrder" + let app := mkAppN (.const declName (cinfo.levelParams.map .param)) xs + addDecl <| Declaration.defnDecl { + name := instName + levelParams := cinfo.levelParams + type := ← mkForallFVars xs <| ← mkAppM ``UsesSetNotationForOrder #[app] + value := ← mkLambdaFVars xs <| ← mkAppOptM ``UsesSetNotationForOrder.mk #[app] + hints := .regular 0 + safety := .safe } + registerInstance instName kind (eval_prio default) /-- The `@[use_set_notation_for_order]` attribute marks that order operations on the given type should use set-style notation. For example, `⊆` for `≤` and `∪` for `⊔`. This affects both elaboration and delaboration. -/ -initialize setNotationExt : NameMapExtension Unit ← registerNameMapExtension _ - -@[inherit_doc setNotationExt] initialize registerBuiltinAttribute { name := `use_set_notation_for_order descr := "use set notation for order operations on this type" - add declName _stx kind := do - unless kind == .global do - throwAttrMustBeGlobal `use_set_notation_for_order kind - setNotationExt.add declName () } + add declName _stx kind := mkUsesSetNotationForOrderInstance declName kind } /-- Whether to use set notation for the given type or not. -/ def useSetNotationFor (type : Expr) : MetaM Bool := do - let .const n _ := (← whnfR type).getAppFn | return false - return (setNotationExt.find? (← getEnv) n).isSome + return (← trySynthInstance (← mkAppM ``UsesSetNotationForOrder #[type])) matches .some _ /-! ## Delaboration -/ @@ -120,8 +135,8 @@ def elabSubsetLike (x y : Term) (le leCls sub subCls : Name) (expectedType? : Op let_expr f@SubsetElabAux α x y := e | throwError "unexpected result {e} when elaborating {rel}" -- If the type cannot be determined yet, we postpone elaboration until it is known. -- This behaviour is inspired by `resolveLValLoop` from the file `Lean.Elab.App`. - tryPostponeIfMVar α if ← isMVarApp α then + tryPostpone synthesizeSyntheticMVarsUsingDefault if ← isMVarApp α then Linter.logLintIf linter.setNotationForOrder (← getRef) @@ -209,4 +224,82 @@ binder_predicate (priority := high) x " ⊇ " y:term => `($x ⊇ $y) `∃ x, x ⊃ y ∧ ...` -/ binder_predicate (priority := high) x " ⊃ " y:term => `($x ⊃ $y) +/-! ## Dot-notation namespace linter -/ + +/-- A temporary linter to help adapt to `@[set_notation_for_order]`. +It gives a warning when a lemma is in the wrong namespace for dot-notation. -/ +@[env_linter] +public def subsetDotNotationLinter : Batteries.Tactic.Lint.Linter where + noErrorsFound := "all names are correct" + errorsFound := "SOME DECLARATIONS USE THE WRONG NAMESPACE" + test declName := do + if Linter.isDeprecated (← getEnv) declName then return none + let n := declName.getNumParts + if n ≤ 2 then return none + let (nameStart, rest) := declName.splitAt (n - 2) + let otherStart ← match nameStart with + | ``Subset => pure ``LE.le + | ``SSubset => pure ``LT.lt + | _ => return none + let mut type := (← getConstInfo declName).type + while let .forallE _ d t _ := type do + type := t + if let .const c _ := d.getAppFn then + if c == otherStart then + return some m!"`{n}` should be named `{otherStart ++ rest}` in order to use dot-notation." + return none + +/-! ## Lemma translation -/ + +@[inherit_doc GuessName.GuessNameData.nameDict] +def nameDict : Std.HashMap String (List String) := .ofList [ + ("le", ["Subset"]), + ("ge", ["Superset"]), + ("lt", ["SSubset"]), + ("gt", ["SSuperset"]), + ("inf", ["Inter"]), + ("sup", ["Union"]), + ("sInf", ["SInter"]), + ("sSup", ["SUnion"]), + ("iInf", ["IInter"]), + ("iSup", ["IUnion"]), +] + +/-- Generate a variant of a theorem by restricting the order on the specified types to those +that are tagged `@[use_set_notation_for_order]`. + +Explicitly, `to_set_notation` inserts a `[UsesSetNotationForOrder α]` type class +assumption for each type `α`. +TODO: it would be nice to be able to restrict which types get the assumption. + +This is used to automatically generate theorems like `subset_trans` from `le_trans`. +The theorem name is automatically translated. +-/ +initialize + registerBuiltinAttribute { + name := `to_set_notation + descr := "generate the set notation version of an order theoretic lemma." + add src stx kind := do + unless kind == .global do + throwAttrMustBeGlobal `to_set_notation kind + let .str srcRoot srcStr := src | throwError "invalid name `{src}`" + let tgt := srcRoot.str <| GuessName.guessName { nameDict, abbreviationDict := {} } srcStr + MetaM.run' <| addRelatedDecl src tgt stx ⟨mkNullNode⟩ + (docstringPrefix? := s!"Set notation form of `{src}`") (hoverInfo := true) + fun value levels => do + forallTelescope (← inferType value) fun xs _ ↦ do + let mut value := mkAppN value xs + for x in xs.reverse do + if let .sort (.succ u) ← inferType x then + -- If `x` is a type, + -- create a constant lambda expression for the proof that now assumes `cls`. + let cls := .app (.const ``UsesSetNotationForOrder [u]) x + let ident ← withFreshMacroScope <| MonadQuotation.addMacroScope `inst + value := .lam ident cls value .instImplicit + value ← mkLambdaFVars #[x] value + return (value, levels) + liftCommandElabM <| Elab.Command.elabCommand (← `(command| + attribute [nolint unusedArguments] $(mkCIdent tgt))) + } + end Mathlib.Meta.SetNotationForOrder diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean b/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean index 7a881b5f577f7d..0c1829e9cc5741 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Constructions.lean @@ -118,7 +118,7 @@ theorem HasProd.sigma {γ : β → Type*} {f : (Σ b : β, γ b) → α} {g : β rcases mem_atTop_sets.mp (ha hs) with ⟨u, hu⟩ use u.image Sigma.fst, trivial intro bs hbs - simp only [Set.mem_preimage, Finset.le_iff_subset] at hu + simp only [Set.mem_preimage] at hu have : Tendsto (fun t : Finset (Σ b, γ b) ↦ ∏ p ∈ t with p.1 ∈ bs, f p) atTop (𝓝 <| ∏ b ∈ bs, g b) := by simp only [← sigma_preimage_mk, prod_sigma] @@ -194,8 +194,7 @@ theorem HasProd.of_sigma {γ : β → Type*} {f : (Σ b : β, γ b) → α} {g : HasProd f a := by classical apply le_nhds_of_cauchy_adhp h - simp only [← mapClusterPt_def, mapClusterPt_iff_frequently, frequently_atTop, - le_eq_subset] + simp only [← mapClusterPt_def, mapClusterPt_iff_frequently, frequently_atTop] intro u hu s rcases mem_nhds_iff.1 hu with ⟨v, vu, v_open, hv⟩ obtain ⟨t0, st0, ht0⟩ : ∃ t0, ∏ i ∈ t0, g i ∈ v ∧ s.image Sigma.fst ⊆ t0 := by diff --git a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean index 293cc2d1ff385e..4f65111db79aaf 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean @@ -182,7 +182,7 @@ instance [Countable β] : IsCountablyGenerated (unconditional β).filter := classical simp only [unconditional, comap] congr 1 with s - simp only [mem_map, mem_atTop_sets, Finset.le_eq_subset, mem_preimage] + simp only [mem_map, mem_atTop_sets, mem_preimage] constructor <;> rintro ⟨t, ht⟩ · refine ⟨t.preimage f (by simp), fun x hx ↦ ?_⟩ simpa [Finset.union_eq_right.mpr hx] using ht (t ∪ x.map f) t.subset_union_left diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean b/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean index b11a3174259953..7fc3ff54303007 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean @@ -43,7 +43,7 @@ lemma exists_openSubgroup_separating {a b : G} (h : a ≠ b) : obtain ⟨u, v, _, open_v, mem_u, mem_v, dis⟩ := t2_separation (h ∘ inv_mul_eq_one.mp) obtain ⟨V, hV⟩ := is_nonarchimedean v (open_v.mem_nhds mem_v) use V - simp only [Disjoint, Set.le_eq_subset, Set.bot_eq_empty, Set.subset_empty_iff] + simp only [Disjoint, Set.bot_eq_empty, Set.subset_empty_iff] intro x mem_aV mem_bV by_contra! ⟨s, hs⟩ have hsa : s ∈ a • (V : Set G) := mem_aV hs diff --git a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean index b70ea7635a9ffa..419cca5e85072f 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean @@ -84,7 +84,7 @@ theorem partialSections.nonempty [IsCofilteredOrEmpty J] [h : ∀ j : J, Nonempt set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in theorem partialSections.directed : - Directed Superset fun G : FiniteDiagram J => partialSections F G.2 := by + Directed GE.ge fun G : FiniteDiagram J => partialSections F G.2 := by classical intro A B let ιA : FiniteDiagramArrow A.1 → FiniteDiagramArrow (A.1 ⊔ B.1) := fun f => diff --git a/Mathlib/Topology/Compactness/SigmaCompact.lean b/Mathlib/Topology/Compactness/SigmaCompact.lean index 85e89a12d24f3f..37db621d2b0d1d 100644 --- a/Mathlib/Topology/Compactness/SigmaCompact.lean +++ b/Mathlib/Topology/Compactness/SigmaCompact.lean @@ -335,7 +335,7 @@ instance : FunLike (CompactExhaustion X) ℕ (Set X) where coe := toFun coe_injective | ⟨_, _, _, _⟩, ⟨_, _, _, _⟩, rfl => rfl -instance : RelHomClass (CompactExhaustion X) LE.le HasSubset.Subset where +instance : OrderHomClass (CompactExhaustion X) ℕ (Set X) where map_rel f _ _ h := monotone_nat_of_le_succ (fun n ↦ (f.subset_interior_succ' n).trans interior_subset) h diff --git a/Mathlib/Topology/ExtremallyDisconnected.lean b/Mathlib/Topology/ExtremallyDisconnected.lean index 5f1f8d8286f713..1916abbee2f674 100644 --- a/Mathlib/Topology/ExtremallyDisconnected.lean +++ b/Mathlib/Topology/ExtremallyDisconnected.lean @@ -167,8 +167,8 @@ lemma exists_compact_surjective_zorn_subset [T1Space A] [CompactSpace D] {X : D IsCompact.nonempty_iInter_of_directed_nonempty_isCompact_isClosed _ ?_ (fun c => ?_) (fun c => IsClosed.isCompact ?_) (fun c => ?_) · replace C_chain : IsChain (· ⊇ ·) C := C_chain.symm - have : ∀ s t : Set D, s ⊇ t → _ ⊇ _ := fun _ _ => inter_subset_inter_left <| X ⁻¹' {a} - exact (directedOn_iff_directed.mp C_chain.directedOn).mono_comp (· ⊇ ·) this + exact (directedOn_iff_directed.mp C_chain.directedOn).mono_comp (g := (· ∩ X ⁻¹' {a})) _ + fun _ _ => inter_subset_inter_left _ · rw [← image_inter_nonempty_iff, (C_sub c.mem).right, univ_inter] exact singleton_nonempty a all_goals exact (C_sub c.mem).left.inter <| (T1Space.t1 a).preimage X_cont diff --git a/Mathlib/Topology/Instances/CantorSet.lean b/Mathlib/Topology/Instances/CantorSet.lean index e25462d8d148d2..fbbd91931ac4b0 100644 --- a/Mathlib/Topology/Instances/CantorSet.lean +++ b/Mathlib/Topology/Instances/CantorSet.lean @@ -89,7 +89,6 @@ theorem zero_mem_cantorSet : 0 ∈ cantorSet := by simp [cantorSet, zero_mem_pre theorem preCantorSet_antitone : Antitone preCantorSet := by refine antitone_nat_of_succ_le fun m ↦ ?_ - simp only [Set.le_eq_subset] induction m with grind [preCantorSet_zero, preCantorSet_succ] lemma preCantorSet_subset_unitInterval {n : ℕ} : preCantorSet n ⊆ Set.Icc 0 1 := by diff --git a/Mathlib/Topology/MetricSpace/Ultra/Basic.lean b/Mathlib/Topology/MetricSpace/Ultra/Basic.lean index f551b24c8b65b8..6a6ba5751878f7 100644 --- a/Mathlib/Topology/MetricSpace/Ultra/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Ultra/Basic.lean @@ -79,7 +79,7 @@ lemma ball_eq_of_mem {x y : X} {r : ℝ} (h : y ∈ ball x r) : ball x r = ball lemma ball_subset_trichotomy : ball x r ⊆ ball y s ∨ ball y s ⊆ ball x r ∨ Disjoint (ball x r) (ball y s) := by wlog! hrs : r ≤ s generalizing x y r s - · rw [disjoint_comm, ← or_assoc, or_comm (b := _ ⊆ _), or_assoc] + · rw [disjoint_comm, ← or_assoc, or_comm (b := (_ : Set X) ⊆ _), or_assoc] exact this y x s r hrs.le · refine Set.disjoint_or_nonempty_inter (ball x r) (ball y s) |>.symm.imp (fun h ↦ ?_) (Or.inr ·) obtain ⟨hxz, hyz⟩ := (Set.mem_inter_iff _ _ _).mp h.some_mem @@ -104,7 +104,7 @@ lemma closedBall_subset_trichotomy : closedBall x r ⊆ closedBall y s ∨ closedBall y s ⊆ closedBall x r ∨ Disjoint (closedBall x r) (closedBall y s) := by wlog! hrs : r ≤ s generalizing x y r s - · rw [disjoint_comm, ← or_assoc, or_comm (b := _ ⊆ _), or_assoc] + · rw [disjoint_comm, ← or_assoc, or_comm (b := (_ : Set X) ⊆ _), or_assoc] exact this y x s r hrs.le · refine Set.disjoint_or_nonempty_inter (closedBall x r) (closedBall y s) |>.symm.imp (fun h ↦ ?_) (Or.inr ·) @@ -126,7 +126,7 @@ lemma isClosed_ball (x : X) (r : ℝ) : IsClosed (ball x r) := by simp [h.not_ge] at hy | inr hd => use r - simp [h, ← Set.le_iff_subset, le_compl_iff_disjoint_left, hd] + simp [h, le_compl_iff_disjoint_left, hd] lemma isClopen_ball : IsClopen (ball x r) := ⟨isClosed_ball x r, isOpen_ball⟩ diff --git a/Mathlib/Topology/Order/HullKernel.lean b/Mathlib/Topology/Order/HullKernel.lean index 70191c4186d32c..ba4af9ac21b64f 100644 --- a/Mathlib/Topology/Order/HullKernel.lean +++ b/Mathlib/Topology/Order/HullKernel.lean @@ -211,7 +211,7 @@ lemma closedsGC_closureOperator [TopologicalSpace α] [IsLower α] constructor · exact fun ⦃a⦄ a ↦ a (hull T (kernel S)) ⟨(isClosed_iff hT).mpr ⟨kernel S, rfl⟩, image_subset_iff.mp (fun _ hbS => sInf_le hbS)⟩ - · simp_rw [le_eq_subset, subset_sInter_iff] + · simp_rw [subset_sInter_iff] intro R hR rw [← (hull_kernel_of_isClosed hT hG hR.1), ← gc_closureOperator] exact ClosureOperator.monotone _ hR.2 diff --git a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean index 7e3e18d8a77616..a0b3a823bdedf4 100644 --- a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean +++ b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean @@ -68,7 +68,6 @@ lemma upperHemicontinuousWithinAt_iff_preimage_Iic : case h₂ => intro s t hst gcongr - exact hst case h₁ => intro s t hst gcongr @@ -96,8 +95,7 @@ lemma upperHemicontinuous_iff_isOpen_preimage_Iic : simp_rw [upperHemicontinuous_iff_preimage_Iic, isOpen_iff_mem_nhds (s := f ⁻¹' Iic _)] conv => enter [1, x] - rw [hasBasis_nhdsSet (f x) |>.forall_iff <| - fun s t hst ↦ by gcongr; exact hst] + rw [hasBasis_nhdsSet (f x) |>.forall_iff fun s t hst ↦ by gcongr] simp [forall_comm (α := α)] /-- A correspondence `f : α → Set β` is upper hemicontinuous if and only if its *lower inverse* diff --git a/Mathlib/Topology/Separation/PerfectlyNormal.lean b/Mathlib/Topology/Separation/PerfectlyNormal.lean index b860bf790d8de6..6e405d69ec8117 100644 --- a/Mathlib/Topology/Separation/PerfectlyNormal.lean +++ b/Mathlib/Topology/Separation/PerfectlyNormal.lean @@ -34,7 +34,7 @@ theorem perfectlyNormalSpace_iff_forall_isClosed_preimage_zero : -- write `s` as the intersection of a sequence of open sets `U n` obtain ⟨U, ho, hu⟩ := isGδ_iff_eq_iInter_nat.1 hs.isGδ have (n : ℕ) : Disjoint s (U n)ᶜ := by - apply HasSubset.Subset.disjoint_compl_right + apply LE.le.disjoint_compl_right grw [hu, iInter_subset] -- for each `n`, construct a continuous function `f n` that separates `s` from `(U n)ᶜ` choose f hfs hfu hfr using fun n => diff --git a/Mathlib/Topology/Separation/Profinite.lean b/Mathlib/Topology/Separation/Profinite.lean index 03010d586a2319..e39c13acfcdf7d 100644 --- a/Mathlib/Topology/Separation/Profinite.lean +++ b/Mathlib/Topology/Separation/Profinite.lean @@ -52,7 +52,7 @@ theorem nhds_basis_clopen (x : X) : (𝓝 x).HasBasis (fun s : Set X => x ∈ s · exact ⟨s, ⟨hs', hs⟩, hs''⟩ haveI : Nonempty N := ⟨⟨univ, isClopen_univ, mem_univ x⟩⟩ have hNcl : ∀ s : N, IsClosed s.val := fun s => s.property.1.1 - have hdir : Directed Superset fun s : N => s.val := by + have hdir : Directed GE.ge fun s : N => s.val := by rintro ⟨s, hs, hxs⟩ ⟨t, ht, hxt⟩ exact ⟨⟨s ∩ t, hs.inter ht, ⟨hxs, hxt⟩⟩, inter_subset_left, inter_subset_right⟩ have h_nhds : ∀ y ∈ ⋂ s : N, s.val, U ∈ 𝓝 y := fun y y_in => by diff --git a/Mathlib/Topology/Sets/OpenCover.lean b/Mathlib/Topology/Sets/OpenCover.lean index b6b104943bea7c..3095131b96e617 100644 --- a/Mathlib/Topology/Sets/OpenCover.lean +++ b/Mathlib/Topology/Sets/OpenCover.lean @@ -72,8 +72,9 @@ lemma exists_finite_of_compactSpace (hu : IsOpenCover u) [CompactSpace X] : end IsOpenCover lemma Opens.IsBasis.isOpenCover {S : Set (Opens X)} (hS : Opens.IsBasis S) : - IsOpenCover (fun U : S ↦ (U : Opens X)) := - top_le_iff.mp (subset_trans hS.2.superset (by simp)) + IsOpenCover (fun U : S ↦ (U : Opens X)) := by + ext1 + simp [← hS.2] /-- Given an open cover and a basis, the set of basis elements contained in any of the covers is still a cover. -/ diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index c6593fd745e47b..c9a12554fea78d 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -392,7 +392,8 @@ lemma IsBasis.exists_finite_of_isCompact {B : Set (Opens α)} (hB : IsBasis B) { obtain ⟨Us', hsub, hsup⟩ := isBasis_iff_cover.mp hB U obtain ⟨t, ht⟩ := hU.elim_finite_subcover (fun s : Us' ↦ s.1) (fun s ↦ s.1.2) (by simp [hsup]) refine ⟨Finset.image Subtype.val t, subset_trans (by simp) hsub, Finset.finite_toSet _, ?_⟩ - exact le_antisymm (subset_trans ht (by simp)) (le_trans (sSup_le_sSup (by simp)) hsup.ge) + exact le_antisymm (subset_trans (a := U.carrier) ht (by simp)) + (le_trans (sSup_le_sSup (by simp)) hsup.ge) lemma IsBasis.le_iff {α} {t₁ t₂ : TopologicalSpace α} {Us : Set (Opens α)} (hUs : @IsBasis α t₂ Us) : diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 391ad1a6a7787c..ae6a28fa2f9ae9 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -230,8 +230,7 @@ theorem closure_eq_inter_uniformity {t : SetRel α α} : closure t = ⋂ d ∈ calc closure t = ⋂ (V) (_ : V ∈ 𝓤 α ∧ SetRel.IsSymm V), V ○ t ○ V := closure_eq_uniformity t _ = ⋂ V ∈ 𝓤 α, V ○ t ○ V := - Eq.symm <| - UniformSpace.hasBasis_symmetric.biInter_mem fun _ _ hV => by dsimp at *; gcongr + Eq.symm <| UniformSpace.hasBasis_symmetric.biInter_mem fun _ _ hV => by gcongr _ = ⋂ V ∈ 𝓤 α, V ○ (t ○ V) := by simp [SetRel.comp_assoc] theorem uniformity_eq_uniformity_interior : 𝓤 α = (𝓤 α).lift' interior := diff --git a/Mathlib/Topology/UrysohnsLemma.lean b/Mathlib/Topology/UrysohnsLemma.lean index c93e3ecf19470f..aa2e075d08d5fc 100644 --- a/Mathlib/Topology/UrysohnsLemma.lean +++ b/Mathlib/Topology/UrysohnsLemma.lean @@ -485,7 +485,7 @@ lemma exists_tsupport_one_of_isOpen_isClosed [R1Space X] {s t : Set X} rw [← compl_compl s] at hscp obtain ⟨u, v, huIsOpen, hvIsOpen, hscompl_subset_u, ht_subset_v, hDisjointuv⟩ := SeparatedNhds.of_isClosed_isCompact_closure_compl_isClosed (isClosed_compl_iff.mpr hs) - hscp ht (HasSubset.Subset.disjoint_compl_left hst) + hscp ht (LE.le.disjoint_compl_left hst) rw [← subset_compl_iff_disjoint_right] at hDisjointuv have huvc : closure u ⊆ vᶜ := closure_minimal hDisjointuv hvIsOpen.isClosed_compl -- although `sᶜ` is not compact, `closure s` is compact and we can apply @@ -505,7 +505,7 @@ lemma exists_tsupport_one_of_isOpen_isClosed [R1Space X] {s t : Set X} obtain ⟨u1, hu1⟩ := SeparatedNhds.of_isClosed_isCompact_closure_compl_isClosed cIsClosed (IsCompact.of_isClosed_subset hscp isClosed_closure (closure_mono (compl_subset_compl.mpr Pc))) - (isClosed_compl_iff.mpr u0IsOpen) (HasSubset.Subset.disjoint_compl_right csubu0) + (isClosed_compl_iff.mpr u0IsOpen) (LE.le.disjoint_compl_right csubu0) simp_rw [← subset_compl_iff_disjoint_right, compl_subset_comm (s := u0)] at hu1 obtain ⟨v1, hu1, hv1, hcu1, hv1u, hu1v1⟩ := hu1 refine ⟨u1, hu1, hcu1, ?_, Pc, (Pc.trans hcu1).trans subset_closure⟩ diff --git a/MathlibTest/SetNotationForOrder.lean b/MathlibTest/SetNotationForOrder.lean index 97795fc1271e49..d442a3525681e3 100644 --- a/MathlibTest/SetNotationForOrder.lean +++ b/MathlibTest/SetNotationForOrder.lean @@ -3,10 +3,7 @@ module import Mathlib.Data.Set.Basic import Mathlib.Tactic.SetNotationForOrder -attribute [use_set_notation_for_order] Set - section Delab - -- `LE.le` is printed as `≤` or `⊆` depending on the type. /-- info: a ⊆ b : Prop -/ @@ -52,11 +49,10 @@ variable (a b : Nat) in end Delab section Elab +-- `⊆` is elaborated to `LE.le` or `Subset` depending on the type. set_option pp.notation false -- So we can see the difference between `LE.le` and `Subset`. --- `⊆` is elaborated to `LE.le` or `Subset` depending on the type. - /-- info: LE.le a b : Prop -/ #guard_msgs in variable (a b : Set Nat) in @@ -148,3 +144,19 @@ example (a b : List Nat) : True ∨ True ∨ a ⊆ b := by left; trivial end Elab + +section UsesSetNotationForOrder +-- Theorems like `subset_rfl` should only apply to things tagged with `use_set_notation_for_order` + +/-- +error: failed to synthesize instance of type class + UsesSetNotationForOrder ℕ + +Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command. +-/ +#guard_msgs in +example : 1 ≤ 1 := subset_rfl + +example : ({1} : Set Nat) ≤ {1} := subset_rfl + +end UsesSetNotationForOrder From ec622b3712e306780ce97a7c057494e2dcb8a46d Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 6 Jul 2026 20:31:19 +0000 Subject: [PATCH 0618/1300] doc(SetTheory): qualify `Cardinal.IsInaccessible.univ` in the doc (#41390) This fixes the broken link in the doc --- Mathlib/SetTheory/Ordinal/Univ.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/SetTheory/Ordinal/Univ.lean b/Mathlib/SetTheory/Ordinal/Univ.lean index 5b302b22694094..18efe4e0c84a55 100644 --- a/Mathlib/SetTheory/Ordinal/Univ.lean +++ b/Mathlib/SetTheory/Ordinal/Univ.lean @@ -15,7 +15,7 @@ order type of the ordinals. These are related via `Cardinal.univ.ord = Ordinal.u `Ordinal.univ.card = Cardinal.univ`. The cardinal `Cardinal.univ` is strongly inaccessible. This reflects the fact that in ZFC, the -cardinals form a proper class. See `IsInaccessible.univ` for a proof. +cardinals form a proper class. See `Cardinal.IsInaccessible.univ` for a proof. ## Implementation notes From 12b4b4adf73c3bf0917409bb4b9dd4c8b96f4e8f Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Mon, 6 Jul 2026 21:23:27 +0000 Subject: [PATCH 0619/1300] feat(RingTheory): add `Away.liftAlgHom` (#41321) Add `IsLocalization.Away.liftAlgHom`, the analog of `IsLocalization.liftAlgHom`. We use this to golf four proofs in ring theory, which used the pattern `IsLocalization.liftAlgHom (M := .powers ...)`. --- Mathlib/RingTheory/Etale/StandardEtale.lean | 12 +++-------- .../RingTheory/Localization/Away/Basic.lean | 20 +++++++++++++++++++ Mathlib/RingTheory/Localization/Basic.lean | 3 +-- .../UniversalFactorizationRing.lean | 9 +++------ Mathlib/RingTheory/QuasiFinite/Basic.lean | 7 ++----- Mathlib/RingTheory/ZariskisMainTheorem.lean | 5 ++--- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Mathlib/RingTheory/Etale/StandardEtale.lean b/Mathlib/RingTheory/Etale/StandardEtale.lean index f245cc4c4dc149..64f44f09d4c17b 100644 --- a/Mathlib/RingTheory/Etale/StandardEtale.lean +++ b/Mathlib/RingTheory/Etale/StandardEtale.lean @@ -200,13 +200,11 @@ def equivPolynomialQuotient : def equivAwayAdjoinRoot : P.Ring ≃ₐ[R] Localization.Away (AdjoinRoot.mk P.f P.g) := by refine .ofAlgHom (P.lift (algebraMap (AdjoinRoot P.f) _ (.root P.f)) ⟨?_, ?_⟩) - (IsLocalization.liftAlgHom (M := .powers <| AdjoinRoot.mk P.f P.g) - (f := AdjoinRoot.liftAlgHom _ _ P.X P.hasMap_X.1) <| Subtype.forall.mpr ?_) ?_ ?_ + (IsLocalization.Away.liftAlgHom (AdjoinRoot.mk P.f P.g) + (f := AdjoinRoot.liftAlgHom _ _ P.X P.hasMap_X.1) P.hasMap_X.2) ?_ ?_ · rw [aeval_algebraMap_apply, AdjoinRoot.aeval_eq, AdjoinRoot.mk_self, map_zero] · rw [aeval_algebraMap_apply, AdjoinRoot.aeval_eq] exact IsLocalization.Away.algebraMap_isUnit .. - · change Submonoid.powers _ ≤ (IsUnit.submonoid _).comap _ - simpa [Submonoid.powers_le, IsUnit.mem_submonoid_iff] using! P.hasMap_X.2 · ext; simp [Algebra.algHom] · ext; simp @@ -214,16 +212,12 @@ def equivAwayAdjoinRoot : def equivAwayQuotient : P.Ring ≃ₐ[R] Localization.Away P.g ⧸ Ideal.span {algebraMap _ (Localization.Away P.g) P.f} := by refine .ofAlgHom (P.lift (algebraMap R[X] _ .X) ⟨?_, ?_⟩) - (Ideal.Quotient.liftₐ _ (IsLocalization.liftAlgHom (M := .powers <| P.g) - (f := aeval P.X) <| Subtype.forall.mpr ?_) ?_) - ?_ ?_ + (Ideal.Quotient.liftₐ _ (IsLocalization.Away.liftAlgHom (P.g) P.hasMap_X.2) ?_) ?_ ?_ · rw [aeval_algebraMap_apply, IsScalarTower.algebraMap_apply _ (Localization.Away P.g) (_ ⧸ _), Ideal.Quotient.algebraMap_eq, aeval_X_left_apply, Ideal.Quotient.mk_singleton_self] · rw [aeval_algebraMap_apply, IsScalarTower.algebraMap_apply _ (Localization.Away P.g) (_ ⧸ _), aeval_X_left_apply] exact (IsLocalization.Away.algebraMap_isUnit ..).map _ - · change Submonoid.powers _ ≤ (IsUnit.submonoid _).comap _ - simpa [Submonoid.powers_le, IsUnit.mem_submonoid_iff] using P.hasMap_X.2 · change Ideal.span _ ≤ RingHom.ker _ simpa [Ideal.span_le] using P.hasMap_X.1 · apply Ideal.Quotient.algHom_ext diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index 2a0c932cff60c2..8f68522c0189c5 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -159,6 +159,26 @@ theorem lift_eq (hg : IsUnit (g x)) (a : R) : lift x hg (algebraMap R S a) = g a theorem lift_comp (hg : IsUnit (g x)) : (lift x hg).comp (algebraMap R S) = g := IsLocalization.lift_comp _ +section liftAlgHom + +variable {A : Type*} [CommSemiring A] [Algebra A R] [Algebra A S] [Algebra A P] + [IsScalarTower A R S] {f : R →ₐ[A] P} (hf : IsUnit (f x)) +include hf + +/-- `AlgHom` version of `IsLocalization.Away.lift`. -/ +noncomputable def liftAlgHom : S →ₐ[A] P where + __ := lift x hf + commutes' r := by simp [IsScalarTower.algebraMap_apply A R S] + +theorem liftAlgHom_toRingHom : (liftAlgHom x hf : S →ₐ[A] P).toRingHom = lift x hf := rfl + +@[simp] +theorem coe_liftAlgHom : ⇑(liftAlgHom x hf : S →ₐ[A] P) = lift x hf := rfl + +theorem liftAlgHom_apply (s : S) : liftAlgHom x hf s = lift x hf s := rfl + +end liftAlgHom + /-- Given `x y : R` and localizations `S`, `P` away from `x` and `y * x` respectively, the homomorphism induced from `S` to `P`. -/ noncomputable def awayToAwayLeft (y : R) [Algebra R P] [IsLocalization.Away (y * x) P] : S →+* P := diff --git a/Mathlib/RingTheory/Localization/Basic.lean b/Mathlib/RingTheory/Localization/Basic.lean index 9badde254b6b5b..c59a1127945cf0 100644 --- a/Mathlib/RingTheory/Localization/Basic.lean +++ b/Mathlib/RingTheory/Localization/Basic.lean @@ -201,8 +201,7 @@ include hf /-- `AlgHom` version of `IsLocalization.lift`. -/ noncomputable def liftAlgHom : S →ₐ[A] P where __ := lift hf - commutes' r := show lift hf (algebraMap A S r) = _ by - simp [IsScalarTower.algebraMap_apply A R S] + commutes' r := by simp [IsScalarTower.algebraMap_apply A R S] theorem liftAlgHom_toRingHom : (liftAlgHom hf : S →ₐ[A] P).toRingHom = lift hf := rfl diff --git a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean index 45e180fc490b56..cc868eaae619d9 100644 --- a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean +++ b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean @@ -593,12 +593,9 @@ def UniversalCoprimeFactorizationRing.homEquiv : AlgHom.comp_toRingHom, ← Polynomial.map_map] <;> rfl⟩ invFun q := by letI f := (UniversalFactorizationRing.homEquiv S m k hn p).symm ⟨q.1, q.2.1⟩ - refine IsLocalization.liftAlgHom (f := f) - (M := .powers (UniversalFactorizationRing.presentation m k hn p).jacobian) ?_ + apply IsLocalization.Away.liftAlgHom (f := f) + (UniversalFactorizationRing.presentation m k hn p).jacobian nontriviality S - rw [Subtype.forall] - change Submonoid.powers _ ≤ (IsUnit.submonoid _).comap f - simp only [Submonoid.powers_le, Submonoid.mem_comap, IsUnit.mem_submonoid_iff] rw [← AlgHom.coe_toRingHom, UniversalFactorizationRing.jacobian_resentation, map_mul, ← Polynomial.resultant_map_map, IsUnit.mul_iff] refine ⟨by cases n <;> simp, ?_⟩ @@ -612,7 +609,7 @@ def UniversalCoprimeFactorizationRing.homEquiv : left_inv f := by apply IsLocalization.algHom_ext (.powers (UniversalFactorizationRing.presentation m k hn p).jacobian) - ext; simp + ext; simp [Algebra.algHom] right_inv q := by apply Subtype.ext convert! congr($((UniversalFactorizationRing.homEquiv S m k hn p).apply_symm_apply diff --git a/Mathlib/RingTheory/QuasiFinite/Basic.lean b/Mathlib/RingTheory/QuasiFinite/Basic.lean index 08f45dedcf66ea..6e7c2e270be650 100644 --- a/Mathlib/RingTheory/QuasiFinite/Basic.lean +++ b/Mathlib/RingTheory/QuasiFinite/Basic.lean @@ -486,11 +486,8 @@ lemma QuasiFiniteAt.of_isOpen_singleton obtain ⟨e, he, H⟩ := PrimeSpectrum.isClopen_iff.mp H have hep : e ∉ p.asIdeal := H.le rfl let f : Localization.Away e →ₐ[S] Localization.AtPrime p.asIdeal := - IsLocalization.liftAlgHom (M := .powers e) (f := Algebra.ofId _ _) <| by - simp only [Subtype.forall] - refine Submonoid.powers_le (P := (IsUnit.submonoid _).comap _).mpr ?_ - simpa [IsUnit.mem_submonoid_iff] using IsLocalization.map_units - (M := p.asIdeal.primeCompl) _ ⟨e, hep⟩ + IsLocalization.Away.liftAlgHom e (f := Algebra.ofId _ _) + (IsLocalization.map_units (M := p.asIdeal.primeCompl) _ ⟨e, hep⟩) have h₁ := (PrimeSpectrum.localization_away_comap_range (Localization.Away e) e).trans H.symm have : Subsingleton (PrimeSpectrum (Localization.Away e)) := Function.Injective.subsingleton diff --git a/Mathlib/RingTheory/ZariskisMainTheorem.lean b/Mathlib/RingTheory/ZariskisMainTheorem.lean index 920e9ed36be5b7..1d7ad580fa7bd8 100644 --- a/Mathlib/RingTheory/ZariskisMainTheorem.lean +++ b/Mathlib/RingTheory/ZariskisMainTheorem.lean @@ -716,9 +716,8 @@ lemma ZariskisMainProperty.quasiFiniteAt have : Algebra.QuasiFinite R (Localization.Away r.1) := .of_surjective_algHom (Localization.awayMapₐ S'.val r) H.2 let f : Localization.Away r.1 →ₐ[S] Localization.AtPrime p := - IsLocalization.liftAlgHom (M := .powers r.1) (f := Algebra.ofId _ _) (by - simpa [Submonoid.mem_powers_iff] using - (IsLocalization.map_units (M := p.primeCompl) (Localization.AtPrime p) ⟨r, hrp⟩).pow) + IsLocalization.Away.liftAlgHom r.1 (f := Algebra.ofId _ _) <| + IsLocalization.map_units (M := p.primeCompl) (Localization.AtPrime p) ⟨r, hrp⟩ refine .of_forall_exists_mul_mem_range (f.restrictScalars R) fun x ↦ ?_ obtain ⟨x, ⟨s, hs⟩, rfl⟩ := IsLocalization.exists_mk'_eq p.primeCompl x exact ⟨algebraMap _ _ s, by simpa using IsLocalization.map_units _ ⟨s, hs⟩, From 19e592bcf5ad7e683e9d6e326b39c61e483190ed Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 7 Jul 2026 02:56:53 +0000 Subject: [PATCH 0620/1300] fix(Combinatorics/SimpleGraph/Paths): typos in two deprecations from #38531 (#41311) --- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 6f69fbe25693eb..ada1da35a5daf0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -990,7 +990,7 @@ alias map_isTrail_iff_of_injective := isTrail_map_iff_of_injective alias ⟨_, IsTrail.map⟩ := isTrail_map_iff_of_injective -@[deprecated (since := "2026-06-16")] alias isTrmap_ail_of_injective := IsTrail.map +@[deprecated (since := "2026-06-16")] alias map_isTrail_of_injective := IsTrail.map protected theorem IsPath.of_map (hp : (p.map f).IsPath) : p.IsPath := by rw [isPath_def] @@ -1006,7 +1006,7 @@ alias map_isPath_iff_of_injective := isPath_map_iff_of_injective alias ⟨_, IsPath.map⟩ := isPath_map_iff_of_injective -@[deprecated (since := "2026-06-16")] alias isPmap_ath_of_injective := IsPath.map +@[deprecated (since := "2026-06-16")] alias map_isPath_of_injective := IsPath.map protected theorem IsCircuit.of_map {p : G.Walk u u} (hp : (p.map f).IsCircuit) : p.IsCircuit := by rw [isCircuit_def, ne_eq, eq_nil_iff_nil] From ce0dcaa4265956ae72abd2dfa77214d838ddce24 Mon Sep 17 00:00:00 2001 From: Suzuka Yu <109365723+Yu-Misaka@users.noreply.github.com> Date: Tue, 7 Jul 2026 03:07:56 +0000 Subject: [PATCH 0621/1300] feat(LinearAlgebra/SymplecticGroup): symplectic matrices have determinant 1 (#40352) Greetings! This PR proposes a proof of `symplectic_matrix_det` mentioned at [lean-eval](https://lean-lang.org/eval/problems/symplectic_matrix_det/). The formalization of statement is due to @kim-em. The proof comes from Seed Prover (lean-eval) and was golfed by me. Co-authored-by: @GanjinZero --- Mathlib/LinearAlgebra/Matrix/Rank.lean | 53 +++++ .../LinearAlgebra/Matrix/Transvection.lean | 5 + Mathlib/LinearAlgebra/SymplecticGroup.lean | 198 +++++++++++++++++- 3 files changed, 253 insertions(+), 3 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Rank.lean b/Mathlib/LinearAlgebra/Matrix/Rank.lean index d2e68d01aad5b4..95b199b09ff306 100644 --- a/Mathlib/LinearAlgebra/Matrix/Rank.lean +++ b/Mathlib/LinearAlgebra/Matrix/Rank.lean @@ -12,6 +12,7 @@ public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas public import Mathlib.LinearAlgebra.Matrix.Diagonal public import Mathlib.LinearAlgebra.Matrix.DotProduct public import Mathlib.LinearAlgebra.Matrix.Dual +public import Mathlib.LinearAlgebra.Matrix.Transvection /-! # Rank of matrices @@ -25,6 +26,19 @@ This definition does not depend on the choice of basis, see `Matrix.rank_eq_finr * `Matrix.cRank`: the rank of a matrix as a cardinal * `Matrix.eRank`: the rank of a matrix as a term in `ℕ∞`. +## Main results + +* `Matrix.rank_eq_finrank_range_toLin`: the rank equals the dimension of the range of the +corresponding linear map, and is therefore independent of the choice of bases. +* `Matrix.rank_eq_finrank_span_cols`, `Matrix.rank_eq_finrank_span_row`: the rank equals the +dimension of the space spanned by the columns (resp. rows). +* `Matrix.rank_transpose`: transposing a matrix does not change its rank. +* `Matrix.rank_mul_le`: the rank of `A * B` is at most the rank of `A` and at most the rank of `B`. +* `Matrix.rank_mul_eq_left_of_isUnit_det`, `Matrix.rank_mul_eq_right_of_isUnit_det`: multiplying by +an invertible matrix does not change the rank. +* `Matrix.exists_rank_normal_form`: every square matrix over a field can be brought, by left and +right multiplication by invertible matrices, into the block form `fromBlocks 1 0 0 0`, where the +identity block has size equal to the rank of the matrix. -/ @[expose] public section @@ -278,6 +292,8 @@ theorem eRank_reindex {m₀ : Type um} {n : Type un} [Semiring R] (A : Matrix m (en : n ≃ n₀) : eRank (A.reindex em en) = eRank A := eRank_submatrix .. +/-- The rank of a matrix equals the dimension of the range of the corresponding linear map, +and is therefore independent of the choice of bases. -/ theorem rank_eq_finrank_range_toLin [Finite m] [DecidableEq n] {M₁ M₂ : Type*} [CommSemiring R] [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R M₁] [Module R M₂] (A : Matrix m n R) (v₁ : Basis m R M₁) (v₂ : Basis n R M₂) : @@ -328,6 +344,43 @@ theorem rank_diagonal [Fintype m] [DecidableEq m] [DecidableEq R] (w : m → R) rw [Matrix.rank, ← Matrix.toLin'_apply', Module.finrank, ← LinearMap.rank, LinearMap.rank_diagonal, Cardinal.toNat_natCast] +open TransvectionStruct in +/-- Every square matrix over a field can be brought, by left and right multiplication by +invertible matrices, into the block form `fromBlocks 1 0 0 0`, where the identity block has size +equal to the rank of the matrix. -/ +theorem exists_rank_normal_form [Fintype m] [DecidableEq m] (M : Matrix m m R) : + ∃ (V U : Matrix m m R) (e : m ≃ Fin M.rank ⊕ Fin (Fintype.card m - M.rank)), + IsUnit V ∧ IsUnit U ∧ + V * M * U = (fromBlocks 1 0 0 0).submatrix e e := by + classical + obtain ⟨L, L', D, hM0⟩ := Matrix.Pivot.exists_list_transvec_mul_diagonal_mul_list_transvec M + set E := fun i ↦ if D i = 0 then 1 else (D i)⁻¹ with E_def + set s : Finset m := .filter (fun i ↦ D i ≠ 0) .univ with s_def + set V := diagonal E * (L.reverse.map (toMatrix ∘ .inv)).prod with V_def + set U := (L'.reverse.map (toMatrix ∘ .inv)).prod with U_def + have hUdet : IsUnit U.det := (isUnit_iff_isUnit_det _).1 <| isUnit_prod_comp_inverse _ + have hVdet : IsUnit V.det := by + rw [V_def, det_mul, det_diagonal] + exact IsUnit.mk0 _ (Finset.prod_ne_zero_iff.2 (by grind)) |>.mul <| + (isUnit_iff_isUnit_det _).1 (isUnit_prod_comp_inverse _) + have hM : V * M * U = diagonal (fun i ↦ if i ∈ s then 1 else 0) := by + rw [V_def, U_def, hM0, mul_assoc, mul_assoc _ (L'.map _).prod, prod_mul_reverse_inv_prod, + mul_one, ← mul_assoc, mul_assoc _ (L.reverse.map _).prod, reverse_inv_prod_mul_prod, mul_one] + ext + simp only [E_def, mul_diagonal, diagonal_apply, ite_mul, one_mul, zero_mul, s_def, + Finset.mem_filter, Finset.mem_univ, true_and, ite_not] + split_ifs with h1 h2 <;> first | rw [← h1, h2] | rw [← h1, inv_mul_cancel₀ h2] | rfl + have hs : s.card = M.rank := by + simp [← rank_mul_eq_right_of_isUnit_det V M hVdet, ← rank_mul_eq_left_of_isUnit_det U (V * M) + hUdet, hM, rank_diagonal] + set e : m ≃ Fin M.rank ⊕ Fin (Fintype.card m - M.rank) := + (Equiv.sumCompl (· ∈ s)).symm.trans <| (Finset.equivFinOfCardEq hs).sumCongr <| + Fintype.equivFinOfCardEq <| by rw [Fintype.card_subtype_compl, Fintype.card_coe, hs] with he + refine ⟨V, U, e, (isUnit_iff_isUnit_det _).2 hVdet, isUnit_prod_comp_inverse _, ?_⟩ + rw [hM, ← diagonal_one, ← diagonal_zero, fromBlocks_diagonal, submatrix_diagonal_equiv] + refine congrArg _ (funext fun i ↦ ?_) + split_ifs with hi <;> simp [he, hi] + theorem cRank_diagonal [DecidableEq m] (w : m → R) : (diagonal w).cRank = lift.{uR} #{i // (w i) ≠ 0} := by classical diff --git a/Mathlib/LinearAlgebra/Matrix/Transvection.lean b/Mathlib/LinearAlgebra/Matrix/Transvection.lean index 8f6d4cd87b2498..776e9a631444d5 100644 --- a/Mathlib/LinearAlgebra/Matrix/Transvection.lean +++ b/Mathlib/LinearAlgebra/Matrix/Transvection.lean @@ -219,6 +219,11 @@ theorem prod_mul_reverse_inv_prod (L : List (TransvectionStruct n R)) : by simpa [Matrix.mul_assoc] simp_rw [IH, Matrix.mul_one, t.mul_inv] +theorem isUnit_prod_comp_inverse (L : List (TransvectionStruct n R)) : + IsUnit (L.map (toMatrix ∘ .inv)).prod := by + refine IsUnit.of_mul_eq_one (L.reverse.map toMatrix).prod ?_ + rw [← reverse_inv_prod_mul_prod L.reverse, L.reverse_reverse] + /-- `M` is a scalar matrix if it commutes with every nontrivial transvection (elementary matrix). -/ theorem _root_.Matrix.mem_range_scalar_of_commute_transvectionStruct {M : Matrix n n R} (hM : ∀ t : TransvectionStruct n R, Commute t.toMatrix M) : diff --git a/Mathlib/LinearAlgebra/SymplecticGroup.lean b/Mathlib/LinearAlgebra/SymplecticGroup.lean index c5ae74d50bf355..b90e068e0c7209 100644 --- a/Mathlib/LinearAlgebra/SymplecticGroup.lean +++ b/Mathlib/LinearAlgebra/SymplecticGroup.lean @@ -1,11 +1,15 @@ /- Copyright (c) 2022 Matej Penciak. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Matej Penciak, Moritz Doll, Fabien Clery +Authors: Matej Penciak, Moritz Doll, Fabien Clery, Seed Prover, Huanyu Zheng -/ module -public import Mathlib.LinearAlgebra.Matrix.NonsingularInverse +public import Mathlib.LinearAlgebra.Matrix.Action +public import Mathlib.LinearAlgebra.Matrix.SchurComplement +public import Mathlib.LinearAlgebra.Matrix.Rank +public import Mathlib.RingTheory.LocalProperties.Basic +public import Mathlib.RingTheory.LocalRing.ResidueField.Basic /-! # The Symplectic Group @@ -17,8 +21,23 @@ This file defines the symplectic group and proves elementary properties. * `Matrix.J`: the canonical `2n × 2n` skew-symmetric matrix * `symplecticGroup`: the group of symplectic matrices +## Implementation Notes + +* `SymplecticGroup.det_eq_one`: Symplectic matrices have determinant 1. The proof strategy +comes in two steps: + +1. Consider a symplectic matrix `M` over a local ring, we can construct a matrix of the +form `fromBlocks 1 X 0 1` s.t. the upper-left block of `(fromBlocks 1 X 0 1) * M` is invertible. +From this we can calculate the determinant. + +2. For a symplectic matrix `M` over general commutative ring `R`, we note that by step 1, +`M.det - 1 = 0` in any localization at a maximal ideal in `R`. Therefore `M.det = 1` in `R`. + +Developing the proof in two steps is helpful, since the local ring hypothesis allows us to +construct the desired `X` in step 1 at the residue field level, and lift back to the ring while +keeping the upper-left block invertible. + ## TODO -* Every symplectic matrix has determinant 1. * For `n = 1` the symplectic group coincides with the special linear group. -/ @@ -78,6 +97,7 @@ end JMatrixLemmas variable [Fintype l] /-- The group of symplectic matrices over a ring `R`. -/ +@[wikidata Q936434] def symplecticGroup : Submonoid (Matrix (l ⊕ l) (l ⊕ l) R) where carrier := { A | A * J l R * Aᵀ = J l R } mul_mem' {a b} ha hb := by @@ -197,4 +217,176 @@ instance : Group (symplecticGroup l R) := simp only [Submonoid.coe_one, Submonoid.coe_mul, Matrix.neg_mul, coe_inv] exact inv_left_mul_aux A.2 } +section Determinant + +variable {A B C D : Matrix l l R} + +theorem fromBlocks_mem_iff : + fromBlocks A B C D ∈ symplecticGroup l R ↔ + Aᵀ * C = Cᵀ * A ∧ + Bᵀ * D = Dᵀ * B ∧ + Aᵀ * D - Cᵀ * B = 1 := by + refine ⟨fun h ↦ ?_, fun h ↦ mem_iff'.2 ?_⟩ + · have h_final : fromBlocks (Cᵀ * A - Aᵀ * C) (Cᵀ * B - Aᵀ * D) + (Dᵀ * A - Bᵀ * C) (Dᵀ * B - Bᵀ * D) = J l R := by + simpa [mem_iff, fromBlocks_transpose, J, fromBlocks_multiply, + sub_eq_add_neg] using transpose_mem h + obtain ⟨h_eq1, h_eq2, _, h_eq3⟩ := fromBlocks_inj.1 h_final + exact ⟨(sub_eq_zero.1 h_eq1).symm, (sub_eq_zero.1 h_eq3).symm, by grind⟩ + · simp only [fromBlocks_transpose, J, fromBlocks_multiply, mul_zero, mul_one, zero_add, mul_neg, + add_zero, neg_mul, ← sub_eq_add_neg, fromBlocks_inj, sub_eq_zero] + exact ⟨h.1.symm, by grind, by simpa using congr(transpose $(h.2.2)), h.2.1.symm⟩ + +/-- The determinant of a symplectic matrix is 1 if its upper-left block is invertible. -/ +private lemma det_one_if_fromBlocks_invertible [Invertible A] + (hA : fromBlocks A B C D ∈ symplecticGroup l R) : + (fromBlocks A B C D).det = 1 := by + have h_block := fromBlocks_mem_iff.1 hA + rw [det_fromBlocks₁₁, invOf_eq_nonsing_inv, ← A.det_transpose, ← det_mul, + mul_sub, ← mul_assoc, ← mul_assoc, h_block.1, mul_assoc Cᵀ, + mul_inv_of_invertible, mul_one, h_block.2.2, det_one] + +/-- Given square matrices `A` and `C` over a field, if the only vector annihilated by both of +them is 0, and `Aᵀ * C = Cᵀ * A`, then one can construct a symmetric matrix `X` such that +`A + X * C` is invertible. + +This lemma, together with the one after, is used to turn the upper-left block into invertible +matrix in the main proof, so that we can use the previous lemma to calculate the determinant. -/ +private lemma exists_symmetric_X_invertible_add_mul_of_ker_inter_eq_bot {R : Type*} [Field R] + {A C : Matrix l l R} (hker : ∀ (x : l → R), (A • x = 0) → (C • x = 0) → x = 0) + (hsymm : Aᵀ * C = Cᵀ * A) : + ∃ (X : Matrix l l R), X.IsSymm ∧ IsUnit (A + X * C) := by + -- `C` is transformed into `P = fromBlocks 1 0 0 0` by invertible matrices `V` and `U`. + rcases exists_rank_normal_form C with ⟨V, U, s, hV, hU, heq⟩ + set P := V * C * U with P_def; set Q := Vᵀ⁻¹ * A * U with Q_def + set f := fun (x : Matrix l l R) ↦ x.submatrix s.symm s.symm + have hf (x) : f x = x.submatrix s.symm s.symm := rfl + have f_unit {x} : IsUnit x → IsUnit (f x) := (isUnit_submatrix_equiv ..).2 + have f_mul (x y) : f (x * y) = f x * f y := submatrix_mul _ _ _ _ _ s.symm.bijective + have _ : Invertible V := hV.invertible + have _ : Invertible U := hU.invertible + have _ : Invertible (f Vᵀ) := (f_unit (V.isUnit_transpose.2 hV)).invertible + -- The hypothesis that the only vector annihilated by both matrices is 0, holds for `P` and `Q`. + have con1 (x : Fin C.rank ⊕ Fin (Fintype.card l - C.rank) → R) + (heq1 : (f Q) • x = 0) (heq2 : (f P) • x = 0) : x = 0 := by + refine (f_unit hU).smul_left_cancel.1 ?_ + rw [f_mul, f_mul, mul_assoc, mul_smul, IsUnit.smul_eq_zero, mul_smul, hf, + smul_eq_mulVec, submatrix_mulVec_equiv, Equiv.symm_symm] at heq1 heq2 + · rw [Equiv.comp_symm_eq, Pi.zero_comp] at heq1 heq2 + exact s.surjective.injective_comp_right <| by simpa using hker _ heq1 heq2 + · exact f_unit hV + · exact f_unit <| isUnit_nonsing_inv_iff.2 <| V.isUnit_transpose.2 hV + -- The symmetry relation also holds for `P` and `Q`. + have con2 : Qᵀ * P = Pᵀ * Q := by + simp only [P_def, mul_assoc, transpose_mul, transpose_nonsing_inv, transpose_transpose, Q_def, + inv_mul_cancel_left_of_invertible, mul_inv_cancel_left_of_invertible] + rw [← mul_assoc Aᵀ, hsymm, mul_assoc] + replace con2 : (f Q).toBlocks₁₁ᵀ = (f Q).toBlocks₁₁ ∧ (f Q).toBlocks₁₂ = 0 := by + apply_fun reindex s s at con2 + rw [reindex_apply, reindex_apply, ← hf, ← hf, f_mul, f_mul Pᵀ, heq, hf, + ← transpose_submatrix, ← hf Q, ← (f Q).fromBlocks_toBlocks, hf (_)ᵀ, hf + ((fromBlocks 1 0 0 0).submatrix _ _)] at con2 + simp [fromBlocks_transpose, fromBlocks_multiply] at con2; tauto + -- The lower-right block of `Q` is invertible. + have con3 : IsUnit (f Q).toBlocks₂₂ := by + refine mulVec_injective_iff_isUnit.1 ?_ + rw [← coe_mulVecLin, ← LinearMap.ker_eq_bot] + refine ker_mulVecLin_eq_bot_iff.2 fun x hx ↦ Sum.elim_injective' <| + (con1 _ ?_ ?_).trans Sum.elim_zero_zero.symm + · rw [← (f Q).fromBlocks_toBlocks]; simp [hx, con2.2, fromBlocks_mulVec] + · simp [hf, heq, fromBlocks_mulVec] + set Y : Matrix (Fin C.rank ⊕ Fin (Fintype.card l - C.rank)) (Fin C.rank ⊕ + Fin (Fintype.card l - C.rank)) R := fromBlocks (1 - (f Q).toBlocks₁₁) 0 0 0 with Y_def + have hY_symm : Y.IsSymm := by + rw [Y_def, isSymm_fromBlocks_iff] + exact ⟨IsSymm.sub isSymm_one con2.1, by simp⟩ + -- We now take `X = Vᵀ * Y * V` and this gives the desired matrix `X.submatrix s s`. + set X := (f Vᵀ) * Y * (f V) with X_def + refine ⟨X.submatrix s s, IsSymm.submatrix ?_ s, (isUnit_submatrix_equiv s.symm s.symm).1 ?_⟩ + · simp_rw [X_def, Matrix.IsSymm, transpose_mul, hY_symm.eq, hf, transpose_submatrix, + transpose_transpose, mul_assoc] + · have heq' : f (A + X.submatrix s s * C) = (f Vᵀ) * (f Q + Y * (f P)) * f (U⁻¹) := by + simp_rw [hf, submatrix_add, Pi.add_apply, Q_def, P_def, ← hf, f_mul, hf, mul_add, ← mul_assoc, + ← inv_submatrix_equiv, add_mul, mul_assoc _ (U.submatrix _ _), mul_inv_of_invertible] + simp [X_def]; rfl + rw [← hf, heq', IsUnit.mul_iff, IsUnit.mul_iff] + refine ⟨⟨isUnit_of_invertible _, ?_⟩, ?_⟩ + · nth_rw 1 [Y_def, heq, ← (f Q).fromBlocks_toBlocks, con2.2] + simpa [hf, fromBlocks_multiply, fromBlocks_add] + · exact f_unit <| isUnit_nonsing_inv_iff.2 hU + +/-- For any symplectic matrix `fromBlocks A B C D` over a local ring `R`, we can construct +a symmetric `X` s.t. `A + X * C` is invertible. + +Introducing local ring hypothesis enables us to transport the construction of `X` +(from the previous lemma, which works only over fields) back to `R` while keeping +`A + X * C` invertible. -/ +private lemma exists_symmetric_X_isUnit_det_add_mul_of_symplectic [IsLocalRing R] + (hA : fromBlocks A B C D ∈ symplecticGroup l R) : + ∃ (X : Matrix l l R), X.IsSymm ∧ IsUnit (A + X * C).det := by + -- We utilize the previous result on field by mapping the symplectic matrix to residue field. + set k := IsLocalRing.ResidueField R; set f := IsLocalRing.residue R + set A' := f.mapMatrix A; set C' := f.mapMatrix C + set F' := fromBlocks A' (f.mapMatrix B) C' (f.mapMatrix D) with F'_def + have hF' : IsUnit F' := by + refine F'.isUnit_iff_isUnit_det.2 ?_ + convert (symplectic_det hA).map f + rw [RingHom.map_det, RingHom.mapMatrix_apply, Matrix.fromBlocks_map]; rfl + have hker (x : l → k) (hx1 : A' *ᵥ x = 0) (hx2 : C' *ᵥ x = 0) : x = 0 := by + have hv0 : F' *ᵥ (Sum.elim x 0) = F' *ᵥ (Sum.elim 0 0) := by + simp [fromBlocks_mulVec, hx1, hx2, F'_def] + exact (Sum.elim_eq_iff.1 (mulVec_injective_iff_isUnit.2 hF' hv0)).1 + -- Now we have a symmetric matrix `Y` over the residue field s.t. `A' + Y * C'` is invertible + -- where `A'` and `C'` are images of `A` and `C` under quotient map from `R` to its residue field. + obtain ⟨Y, hY_symm, hY_det⟩ := + exists_symmetric_X_invertible_add_mul_of_ker_inter_eq_bot hker <| by + change f.mapMatrix Aᵀ * f.mapMatrix C = f.mapMatrix Cᵀ * f.mapMatrix A + rw [← map_mul, (fromBlocks_mem_iff.1 hA).1, map_mul] + -- Lift `Y` back to the ring `R` and we have the `X` we need. + obtain ⟨X, hX_symm, hXY⟩ : ∃ X : Matrix l l R, X.IsSymm ∧ X.map f = Y := by + choose s hs using @IsLocalRing.residue_surjective R _ _ + exact ⟨Y.map s, hY_symm.map s, Matrix.ext fun i j ↦ hs (Y i j)⟩ + refine ⟨X, hX_symm, (IsLocalRing.residue_ne_zero_iff_isUnit _).1 ?_⟩ + -- Ensure `A + X * C` is still invertible in `R`. + rw [RingHom.map_det, map_add, map_mul, RingHom.mapMatrix_apply _ X, hXY] + exact ((isUnit_iff_isUnit_det _).1 hY_det).ne_zero + +/-- Symplectic matrices over a local ring have determinant 1. -/ +private lemma det_eq_one_of_isLocalRing [IsLocalRing R] {M : Matrix (l ⊕ l) (l ⊕ l) R} + (hM : M ∈ symplecticGroup l R) : M.det = 1 := by + set A := M.toBlocks₁₁; set B := M.toBlocks₁₂ + set C := M.toBlocks₂₁; set D := M.toBlocks₂₂ + obtain ⟨X, hX_symm, hA_isUnit⟩ := exists_symmetric_X_isUnit_det_add_mul_of_symplectic <| + M.fromBlocks_toBlocks ▸ hM + -- `fromBlocks 1 X 0 1` turns the upper-left block of `M` into an invertible matrix, here `X` + -- is obtained via previous result. + have Lx_mul : (fromBlocks 1 X 0 1) * M = fromBlocks (A + X * C) (B + X * D) C D := by + rw [← M.fromBlocks_toBlocks, fromBlocks_multiply] + simp only [one_mul, zero_mul, zero_add]; rfl + have h_fromBlocks_in : fromBlocks (A + X * C) (B + X * D) C D ∈ symplecticGroup l R := by + rw [← Lx_mul] + refine (symplecticGroup l R).mul_mem ?_ hM + simp [mem_iff, fromBlocks_transpose, hX_symm.eq, J, fromBlocks_multiply] + have _ : Invertible (A + X * C) := (A + X * C).invertibleOfIsUnitDet hA_isUnit + -- And we know that a symmetric matrix with invertible upper-left block has determinant 1. + have h_main : ((fromBlocks 1 X 0 1) * M).det = 1 := by + rw [Lx_mul, det_one_if_fromBlocks_invertible h_fromBlocks_in] + rwa [det_mul, det_fromBlocks_zero₂₁, det_one, one_mul, one_mul] at h_main + +/-- Symplectic matrices have determinant 1. + +The proof strategy comes in two steps: +1. Consider a symplectic matrix `M` over a local ring, we can construct a matrix of the +form `fromBlocks 1 X 0 1` s.t. the upper-left block of `(fromBlocks 1 X 0 1) * M` is invertible. +From this we can calculate the determinant. + +2. For a symplectic matrix `M` over general commutative ring `R`, we note that by step 1, +`M.det - 1 = 0` in any localization at a maximal ideal in `R`. Therefore `M.det = 1` in `R`. -/ +theorem det_eq_one {M : Matrix (l ⊕ l) (l ⊕ l) R} (hM : M ∈ symplecticGroup l R) : + M.det = 1 := by + refine sub_eq_zero.1 <| eq_zero_of_localization _ fun _ _ ↦ ?_ + simp [RingHom.map_det, RingHom.mapMatrix_apply, det_eq_one_of_isLocalRing <| map_mem hM _] + +end Determinant + end SymplecticGroup From f4e566ca02d995d16c590cdfe4dc051cc80f4624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 7 Jul 2026 03:37:26 +0000 Subject: [PATCH 0622/1300] feat(Algebra/MonoidAlgebra): more general `algHom_ext` (#41412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalise `algHom_ext` and `algHom_ext` from `R[M] →ₐ[R] A` to `A[M] →ₐ[R] B` by adding a second hypothesis that is automatically satisfied for `R[M] →ₐ[R] A` (see `AlgHom.ext_id`). Since the new extensionality lemma is more general, it applies in a bunch more places. Unfortunately, if it is stated using `MonoidAlgebra.of` then it isn't additivisable, meaning that a lot of previously additivised lemmas must now be written by hand. I therefore decided to drop the `of` spelling by unbundling the first hypothesis. This is justified by the fact that the users of the more bundled ext lemma are for `M := Nat`, `Int` or `Free(Abelian)Group`, none of which can be additivised. `algHom_ext` is now the partially bundled version, tagged with `ext`, and `algHom_ext'` the fully bundled version. From Toric --- Mathlib/Algebra/FreeAlgebra.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Basic.lean | 73 +++++++++++----------- Mathlib/Algebra/MonoidAlgebra/Grading.lean | 7 +-- Mathlib/Algebra/MvPolynomial/Basic.lean | 4 +- 4 files changed, 42 insertions(+), 44 deletions(-) diff --git a/Mathlib/Algebra/FreeAlgebra.lean b/Mathlib/Algebra/FreeAlgebra.lean index 2db44e9cca6e07..6658040586f4be 100644 --- a/Mathlib/Algebra/FreeAlgebra.lean +++ b/Mathlib/Algebra/FreeAlgebra.lean @@ -457,7 +457,7 @@ for example. noncomputable def equivMonoidAlgebraFreeMonoid : FreeAlgebra R X ≃ₐ[R] R[FreeMonoid X] := .ofAlgHom (lift R fun x ↦ .of R (FreeMonoid X) (.of x)) (MonoidAlgebra.lift R (FreeAlgebra R X) (FreeMonoid X) (FreeMonoid.lift (ι R))) - (by ext; simp) (by ext; simp) + (MonoidAlgebra.algHom_ext' (by ext; simp) (by ext)) (by ext; simp) /-- `FreeAlgebra R X` is nontrivial when `R` is. -/ instance [Nontrivial R] : Nontrivial (FreeAlgebra R X) := diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index 6885b8460a0502..e21a42366dbd79 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -203,20 +203,32 @@ def liftNCAlgHom (f : A →ₐ[R] B) (g : M →* B) (h_comm : ∀ x y, Commute ( @[simp] lemma coe_liftNCAlgHom (f : A →ₐ[R] B) (g : M →* B) (h_comm) : ⇑(liftNCAlgHom f g h_comm) = liftNC f g := rfl -/-- A `R`-algebra homomorphism from `R[M]` is uniquely defined by its -values on the functions `single a 1`. -/ -@[to_additive (dont_translate := R) /-- +-- The priority must be `high`. +/-- A `R`-algebra homomorphism from `A[M]` is uniquely defined by its +values on the functions `single m 1` and `single 1 a`. + +See note [partially-applied ext lemmas]. Note that the first assumption isn't written as an +equality of `MonoidHom`s because `of` doesn't additivise. -/ +@[to_additive (dont_translate := R A B) (attr := ext high) /-- A `R`-algebra homomorphism from `R[M]` is uniquely defined by its -values on the functions `single a 1`. -/] -theorem algHom_ext ⦃φ₁ φ₂ : R[M] →ₐ[R] A⦄ (h : ∀ x, φ₁ (single x 1) = φ₂ (single x 1)) : φ₁ = φ₂ := - AlgHom.toLinearMap_injective <| lhom_ext' fun a ↦ LinearMap.ext_ring (h a) +values on the functions `single m 1` and `single 1 a`. + +See note [partially-applied ext lemmas]. Note that the first assumption isn't written as an +equality of `AddMonoidHom`s because `of` doesn't multiplicativise. -/] +lemma algHom_ext ⦃φ₁ φ₂ : A[M] →ₐ[R] B⦄ (single_one_right : ∀ m, φ₁ (single m 1) = φ₂ (single m 1)) + (single_one_left : φ₁.comp singleOneAlgHom = φ₂.comp singleOneAlgHom) : + φ₁ = φ₂ := by + ext x + induction x using induction_linear with + | zero => simp + | add => simp_all + | single m a => simpa [← map_mul] using congr($(single_one_right m) * $single_one_left a) --- The priority must be `high`. -/-- See note [partially-applied ext lemmas]. -/ -@[ext high] -theorem algHom_ext' ⦃φ₁ φ₂ : R[M] →ₐ[R] A⦄ - (h : (φ₁ : R[M] →* A).comp (of R M) = (φ₂ : R[M] →* A).comp (of R M)) : φ₁ = φ₂ := - algHom_ext <| DFunLike.congr_fun h +/-- Version of `algHom_ext` where both assumptions are written as equalities of bundled homs. -/ +lemma algHom_ext' ⦃φ₁ φ₂ : A[M] →ₐ[R] B⦄ + (single_one_right : (φ₁ : A[M] →* B).comp (of A M) = (φ₂ : A[M] →* B).comp (of A M)) + (single_one_left : φ₁.comp singleOneAlgHom = φ₂.comp singleOneAlgHom) : φ₁ = φ₂ := + algHom_ext (congr($single_one_right ·)) single_one_left variable (R A M) in /-- Any monoid homomorphism `M →* A` can be lifted to an algebra homomorphism `R[M] →ₐ[R] A`. -/ @@ -276,14 +288,13 @@ def mapDomainAlgHom (f : M →* N) : A[M] →ₐ[R] A[N] where toRingHom := mapDomainRingHom A f commutes' := by simp -@[to_additive (attr := simp)] -lemma mapDomainAlgHom_id : mapDomainAlgHom R A (.id M) = .id R A[M] := by - ext; simp [MonoidHom.id, ← Function.id_def] +@[to_additive (dont_translate := A) (attr := simp)] +lemma mapDomainAlgHom_id : mapDomainAlgHom R A (.id M) = .id R A[M] := by ext <;> simp -@[to_additive (attr := simp)] +@[to_additive (dont_translate := A) (attr := simp)] lemma mapDomainAlgHom_comp (f : M →* N) (g : N →* O) : mapDomainAlgHom R A (g.comp f) = (mapDomainAlgHom R A g).comp (mapDomainAlgHom R A f) := by - ext; simp [mapDomain_comp] + ext <;> simp variable (R A) in /-- If `e : M ≃* N` is a multiplicative equivalence between two monoids, then @@ -407,16 +418,12 @@ lemma mapAlgHom_single (f : A →ₐ[R] B) (m : M) (a : A) : mapAlgHom M f (single m a) = single m (f a) := by classical ext; simp [single_apply, apply_ite f] -@[to_additive (attr := simp)] -lemma mapAlgHom_id {k R G} [CommSemiring k] [Semiring R] [Algebra k R] [Monoid G] : - mapAlgHom G (AlgHom.id k R) = AlgHom.id k (MonoidAlgebra R G) := by - ext; simp +@[to_additive (dont_translate := A) (attr := simp)] +lemma mapAlgHom_id : mapAlgHom M (.id R A) = .id R A[M] := by ext <;> simp -@[to_additive (attr := simp)] -lemma mapRangeAlgHom_comp {k R S T G} [CommSemiring k] [Semiring R] [Algebra k R] [Semiring S] - [Algebra k S] [Semiring T] [Algebra k T] [Monoid G] (f : R →ₐ[k] S) (g : S →ₐ[k] T) : - mapAlgHom G (g.comp f) = (mapAlgHom G g).comp (mapAlgHom G f) := by - ext; simp +@[to_additive (dont_translate := A B C) (attr := simp)] +lemma mapRangeAlgHom_comp (f : A →ₐ[R] B) (g : B →ₐ[R] C) : + mapAlgHom M (g.comp f) = (mapAlgHom M g).comp (mapAlgHom M f) := by ext <;> simp @[deprecated (since := "2026-06-18")] alias mapRangeAlgHom_single := mapAlgHom_single @@ -580,12 +587,11 @@ def liftNCAlgHom (f : A →ₐ[R] B) (g : Multiplicative M →* B) (h_comm : ∀ @[simp] lemma coe_liftNCAlgHom (f : A →ₐ[R] B) (g : Multiplicative M →* B) (h_comm) : ⇑(liftNCAlgHom f g h_comm) = liftNC f g := rfl -/-- See note [partially-applied ext lemmas]. -/ -@[ext high] -theorem algHom_ext' ⦃φ₁ φ₂ : R[M] →ₐ[R] A⦄ - (h : (φ₁ : R[M] →* A).comp (of R M) = (φ₂ : R[M] →* A).comp (of R M)) : - φ₁ = φ₂ := - algHom_ext <| DFunLike.congr_fun h +/-- Version of `algHom_ext` where both assumptions are written as equalities of bundled homs. -/ +lemma algHom_ext' ⦃φ₁ φ₂ : A[M] →ₐ[R] B⦄ + (single_one_right : (φ₁ : A[M] →* B).comp (of A M) = (φ₂ : A[M] →* B).comp (of A M)) + (single_one_left : φ₁.comp singleZeroAlgHom = φ₂.comp singleZeroAlgHom) : φ₁ = φ₂ := + algHom_ext (congr($single_one_right ·)) single_one_left variable (R M A) in /-- Any monoid homomorphism `M →* A` can be lifted to an algebra homomorphism @@ -646,9 +652,6 @@ lemma lift_mapRingHom_algebraMap [CommSemiring S] [Algebra S A] [Algebra R S] [I @[deprecated (since := "2026-06-18")] alias lift_mapRangeRingHom_algebraMap := lift_mapRingHom_algebraMap -lemma algHom_ext_iff {φ₁ φ₂ : R[M] →ₐ[R] A} : (∀ x, φ₁ (single x 1) = φ₂ (single x 1)) ↔ φ₁ = φ₂ := - ⟨fun h => algHom_ext h, by rintro rfl _; rfl⟩ - variable (R A) in /-- `AddMonoidAlgebra.domCongr` as an `AddMonoidHom` from `AddAut`. -/ @[simps] diff --git a/Mathlib/Algebra/MonoidAlgebra/Grading.lean b/Mathlib/Algebra/MonoidAlgebra/Grading.lean index 79ae0eda9aea07..ce985acf86dc7e 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Grading.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Grading.lean @@ -155,12 +155,7 @@ theorem decomposeAux_coe {i : ι} (x : gradeBy R f i) : congr 2 instance gradeBy.gradedAlgebra : GradedAlgebra (gradeBy R f) := - GradedAlgebra.ofAlgHom _ (decomposeAux f) - (by - ext : 4 - dsimp - rw [decomposeAux_single, DirectSum.coeAlgHom_of, Subtype.coe_mk]) - fun i x => by rw [decomposeAux_coe f x] + .ofAlgHom _ (decomposeAux f) (by ext; simp [decomposeAux_single]) <| by simp [decomposeAux_coe] @[simp] theorem decomposeAux_eq_decompose : diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 97279e5d9331ea..7afd4f5009d1e1 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -419,7 +419,7 @@ theorem is_id (f : MvPolynomial σ R →+* MvPolynomial σ R) (hC : f.comp C = C /-- See note [partially-applied ext lemmas]. -We set the priority higher than that of `AddMonoidAlgebra.algHom_ext'`. -/ +We set the priority higher than that of `AddMonoidAlgebra.algHom_ext`. -/ @[ext high + 1] theorem algHom_ext' {A B : Type*} [CommSemiring A] [CommSemiring B] [Algebra R A] [Algebra R B] {f g : MvPolynomial σ A →ₐ[R] B} @@ -435,7 +435,7 @@ We set the priority higher than that of `MvPolynomial.algHom_ext'`. -/ @[ext high + 2] theorem algHom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : MvPolynomial σ R →ₐ[R] A} (hf : ∀ i : σ, f (X i) = g (X i)) : f = g := - AddMonoidAlgebra.algHom_ext' (mulHom_ext' fun X : σ => MonoidHom.ext_mnat (hf X)) + AddMonoidAlgebra.algHom_ext' (mulHom_ext' fun X : σ => MonoidHom.ext_mnat (hf X)) (by ext) @[simp] theorem algHom_C {A : Type*} [Semiring A] [Algebra R A] (f : MvPolynomial σ R →ₐ[R] A) (r : R) : From 9854f6dd2143d4aeed97d33ac493531b6e1720f9 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Tue, 7 Jul 2026 05:44:09 +0000 Subject: [PATCH 0623/1300] chore(LinearAlgebra/AffineSpace/AffineSubspace/Defs): unsimp `coe_affineSpan` (#41404) Since `spanPoints` is an implementation detail that shouldn't be used outside the file, we unsimp `coe_affineSpan` which rewrites `(affineSpan _ _ : Set _)` as `spanPoints`. --- Mathlib/Analysis/Convex/Visible.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Convex/Visible.lean b/Mathlib/Analysis/Convex/Visible.lean index 4edf4e41f7bf90..cb55a8b199a1bb 100644 --- a/Mathlib/Analysis/Convex/Visible.lean +++ b/Mathlib/Analysis/Convex/Visible.lean @@ -207,7 +207,7 @@ lemma rank_le_card_isVisible (hs : IsClosed (convexHull ℝ s)) (hx : x ∉ conv span ℝ (-x +ᵥ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) by rw [AffineSubspace.coe_pointwise_vadd, h, span_span] simp [← AffineSubspace.coe_pointwise_vadd, AffineSubspace.pointwise_vadd_span, - vadd_set_insert, -coe_affineSpan, affineSpan_insert_zero] + vadd_set_insert, affineSpan_insert_zero] _ ≤ #(-x +ᵥ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) := rank_span_le _ _ = #{y ∈ s | IsVisible ℝ (convexHull ℝ s) x y} := by simp diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index bec793d3828b41..70a3eb716f4769 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -133,7 +133,7 @@ variable {k : Type*} {V : Type*} {P : Type*} [Ring k] [AddCommGroup V] [Module k variable (k V) {p₁ p₂ : P} /-- The affine span of a single point, coerced to a set, contains just that point. -/ -@[simp high] -- This needs to take priority over `coe_affineSpan` +@[simp] theorem coe_affineSpan_singleton (p : P) : (affineSpan k ({p} : Set P) : Set P) = {p} := by ext x rw [mem_coe, ← vsub_right_mem_direction_iff_mem (mem_affineSpan k (Set.mem_singleton p)) _, diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean index 485c4d8a1dc3fc..b4967c6f2f10ea 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Defs.lean @@ -470,7 +470,6 @@ def affineSpan (s : Set P) : AffineSubspace k P where (vsub_mem_vectorSpan_of_mem_spanPoints_of_mem_spanPoints k hp₁ hp₂)) /-- The affine span, converted to a set, is `spanPoints`. -/ -@[simp] theorem coe_affineSpan (s : Set P) : (affineSpan k s : Set P) = spanPoints k s := rfl @@ -501,7 +500,7 @@ theorem mem_affineSpan {p : P} {s : Set P} (hp : p ∈ s) : p ∈ affineSpan k s @[simp] lemma vectorSpan_add_self (s : Set V) : (vectorSpan k s : Set V) + s = affineSpan k s := by ext - simp [mem_add, spanPoints] + simp [mem_add, coe_affineSpan, spanPoints] grind variable {k} From 5c206a857e6422127e45b8823dd256e1b69918da Mon Sep 17 00:00:00 2001 From: Evgenia Karunus Date: Tue, 7 Jul 2026 06:06:27 +0000 Subject: [PATCH 0624/1300] feat(Analysis/RCLike/Basic): add norm_I (#41359) From the Carleson project. ___ **Upstreaming from Carleson: [/Carleson/ToMathlib/Analysis/RCLike/Basic.lean](https://github.com/fpvandoorn/carleson/blob/master/Carleson/ToMathlib/Analysis/RCLike/Basic.lean)** Changes from the Carleson version: 1. `norm_I` is refactored a bit [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Analysis/RCLike/Basic.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 1970d7eb45f5ad..1c6678f62c54ab 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -728,6 +728,9 @@ theorem norm_I_of_ne_zero (hI : (I : K) ≠ 0) : ‖(I : K)‖ = 1 := by rw [← mul_self_inj_of_nonneg (norm_nonneg I) zero_le_one, one_mul, ← norm_mul, I_mul_I_of_nonzero hI, norm_neg, norm_one] +theorem norm_I : ‖(I : K)‖ = if (I : K) ≠ 0 then 1 else 0 := by + grind [norm_I_of_ne_zero, norm_eq_zero] + theorem re_eq_norm_of_mul_conj (x : K) : re (x * conj x) = ‖x * conj x‖ := by rw [mul_conj, ← ofReal_pow]; simp [-map_pow] From cfa16a74cd62a6608814a340f9ae2651d16f9828 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 7 Jul 2026 08:33:12 +0000 Subject: [PATCH 0625/1300] chore: remove redundant `open Classical in` (#41387) Hopefully all of them. Also this PR moves the "open Classical in" to the proof ("classical" in tactic proofs) whenever possible. Co-authored-by: Batixx --- Mathlib/Algebra/BigOperators/Finprod.lean | 4 ++-- Mathlib/Algebra/BigOperators/Pi.lean | 2 +- .../Algebra/Homology/HomotopyCategory.lean | 1 - Mathlib/Algebra/Order/Archimedean/Class.lean | 1 - .../Calculus/ContDiff/FaaDiBruno.lean | 1 - Mathlib/Analysis/ODE/ExistUnique.lean | 4 ++-- .../SimpleGraph/CompleteMultipartite.lean | 2 +- .../SimpleGraph/Extremal/Basic.lean | 2 +- .../SimpleGraph/Extremal/TuranDensity.lean | 2 +- .../PurelyInseparable/Exponent.lean | 19 +++++++++---------- .../QuadraticForm/AlgClosed.lean | 1 - Mathlib/Logic/Nontrivial/Basic.lean | 2 +- Mathlib/Logic/Nontrivial/Defs.lean | 5 +++-- .../MeasureTheory/VectorMeasure/Integral.lean | 1 - Mathlib/NumberTheory/KummerDedekind.lean | 2 +- .../CanonicalEmbedding/FundamentalCone.lean | 1 - .../RamificationInertia/Inertia.lean | 1 - Mathlib/Order/CompleteLatticeIntervals.lean | 1 - Mathlib/Order/Preorder/Chain.lean | 4 ++-- .../Order/SuccPred/CompleteLinearOrder.lean | 1 - .../Moments/CovarianceBilinDual.lean | 1 - .../DedekindDomain/SelmerGroup.lean | 1 - .../DiscreteValuationRing/Basic.lean | 1 - Mathlib/RingTheory/HahnSeries/Basic.lean | 1 - .../UniqueFactorizationDomain/Basic.lean | 2 +- .../UniqueFactorizationDomain/FactorSet.lean | 2 +- Mathlib/SetTheory/Ordinal/Basic.lean | 2 +- Mathlib/Topology/ContinuousOn.lean | 2 +- .../Topology/MetricSpace/CoveringNumbers.lean | 1 - 29 files changed, 28 insertions(+), 42 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index 13ca6fe07da3e1..acb911dd7a79f0 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -1224,7 +1224,6 @@ theorem finsum_mem_mul' {R : Type*} [NonUnitalNonAssocSemiring R] {s : Set α} ( (hs : s.Finite) : (∑ᶠ a ∈ s, f a) * r = ∑ᶠ a ∈ s, f a * r := (AddMonoidHom.mulRight r).map_finsum_mem f hs -open Classical in /-- If `R` has no zero divisors, then multiplication commutes with finsums. See `mul_finsum'` for a statement assuming finiteness of support. @@ -1232,6 +1231,7 @@ statement assuming finiteness of support. theorem mul_finsum {R : Type*} [NonUnitalNonAssocSemiring R] [NoZeroDivisors R] (f : α → R) (r : R) : (r * ∑ᶠ a : α, f a) = ∑ᶠ a : α, r * f a := by + classical by_cases hr : r = 0 · simp_all by_cases h : f.support.Finite @@ -1250,7 +1250,6 @@ theorem mul_finsum_mem {R : Type*} [NonUnitalNonAssocSemiring R] [NoZeroDivisors ext a by_cases h : a ∈ s <;> simp_all -open Classical in /-- If `R` has no zero divisors, then multiplication commutes with finsums. See `finsum_mul'` for a statement assuming finiteness of support. @@ -1258,6 +1257,7 @@ statement assuming finiteness of support. theorem finsum_mul {R : Type*} [NonUnitalNonAssocSemiring R] [NoZeroDivisors R] (f : α → R) (r : R) : (∑ᶠ a : α, f a) * r = ∑ᶠ a : α, f a * r := by + classical by_cases hr : r = 0 · simp_all by_cases h : f.support.Finite diff --git a/Mathlib/Algebra/BigOperators/Pi.lean b/Mathlib/Algebra/BigOperators/Pi.lean index 9499e5811f2af0..738407dbbc3560 100644 --- a/Mathlib/Algebra/BigOperators/Pi.lean +++ b/Mathlib/Algebra/BigOperators/Pi.lean @@ -237,9 +237,9 @@ section FunLike variable {F α β ι : Type*} [FunLike F α β] [CommMonoid β] [CommMonoid F] [IsOneApply F α β] [IsMulApply F α β] -open Classical in @[to_additive (attr := simp, grind =)] theorem prod_apply (s : Finset ι) (f : ι → F) (x : α) : (∏ i ∈ s, f i) x = ∏ i ∈ s, f i x := by + classical induction s using Finset.induction_on with | empty => simp | insert i s his h => simp [his, h] diff --git a/Mathlib/Algebra/Homology/HomotopyCategory.lean b/Mathlib/Algebra/Homology/HomotopyCategory.lean index 398b611bbac818..8fafd08769e51a 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory.lean @@ -199,7 +199,6 @@ section variable [CategoryWithHomology V] -open Classical in /-- The `i`-th homology, as a functor from the homotopy category. -/ noncomputable def homologyFunctor (i : ι) : HomotopyCategory V c ⥤ V := CategoryTheory.Quotient.lift _ (HomologicalComplex.homologyFunctor V c i) (by diff --git a/Mathlib/Algebra/Order/Archimedean/Class.lean b/Mathlib/Algebra/Order/Archimedean/Class.lean index ed9bc3fca9dfa1..209a9bc111c513 100644 --- a/Mathlib/Algebra/Order/Archimedean/Class.lean +++ b/Mathlib/Algebra/Order/Archimedean/Class.lean @@ -605,7 +605,6 @@ s = ⊤ with a junk value ⊥. -/ s = ⊤ with a junk value ⊥. -/] noncomputable def subgroup (s : UpperSet (MulArchimedeanClass M)) : Subgroup M := - open Classical in if hs : s = ⊤ then ⊥ else { diff --git a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean index 5ae2154bdc47b5..1d5373d10243b0 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean @@ -631,7 +631,6 @@ def eraseMiddle (c : OrderedFinpartition (n + 1)) (hc : range (c.emb 0) ≠ {0}) exact ⟨i, Fin.cast A.symm j, by simp [hi, hij]⟩ set_option backward.isDefEq.respectTransparency false in -open Classical in /-- Extending the ordered partitions of `Fin n` bijects with the ordered partitions of `Fin (n+1)`. -/ @[simps apply] diff --git a/Mathlib/Analysis/ODE/ExistUnique.lean b/Mathlib/Analysis/ODE/ExistUnique.lean index e362863cf0c1e0..62609142eb50b4 100644 --- a/Mathlib/Analysis/ODE/ExistUnique.lean +++ b/Mathlib/Analysis/ODE/ExistUnique.lean @@ -74,7 +74,6 @@ theorem exists_eq_forall_mem_Icc_hasDerivWithinAt₀ ∀ t ∈ Icc tmin tmax, HasDerivWithinAt α (f t (α t)) (Icc tmin tmax) t := exists_eq_forall_mem_Icc_hasDerivWithinAt hf (mem_closedBall_self le_rfl) -open Classical in /-- **Picard-Lindelöf (Cauchy-Lipschitz) theorem**, differential form. This version shows the existence of a local flow and that it is Lipschitz continuous in the initial point. -/ theorem exists_forall_mem_closedBall_eq_hasDerivWithinAt_lipschitzOnWith @@ -82,6 +81,7 @@ theorem exists_forall_mem_closedBall_eq_hasDerivWithinAt_lipschitzOnWith ∃ α : E → ℝ → E, (∀ x ∈ closedBall x₀ r, α x t₀ = x ∧ ∀ t ∈ Icc tmin tmax, HasDerivWithinAt (α x) (f t (α x t)) (Icc tmin tmax) t) ∧ ∃ L' : ℝ≥0, ∀ t ∈ Icc tmin tmax, LipschitzOnWith L' (α · t) (closedBall x₀ r) := by + classical have (x) (hx : x ∈ closedBall x₀ r) := FunSpace.exists_isFixedPt_next hf hx choose α hα using this set α' := fun (x : E) ↦ if hx : x ∈ closedBall x₀ r then @@ -162,7 +162,6 @@ theorem exists_forall_mem_closedBall_exists_eq_forall_mem_Ioo_hasDerivAt₀ have ⟨α, hα1, hα2⟩ := H x₀ (mem_closedBall_self (le_of_lt hr)) ⟨α, hα1, ε, hε, hα2⟩ -open Classical in /-- If a vector field `f : E → E` is continuously differentiable at `x₀ : E`, then it admits a flow `α : E → ℝ → E` defined on an open domain, with initial condition `α x t₀ = x` for all `x` within the domain. -/ @@ -170,6 +169,7 @@ theorem exists_eventually_eq_hasDerivAt (hf : ContDiffAt ℝ 1 f x₀) (t₀ : ℝ) : ∃ α : E → ℝ → E, ∀ᶠ xt in 𝓝 x₀ ×ˢ 𝓝 t₀, α xt.1 t₀ = xt.1 ∧ HasDerivAt (α xt.1) (f (α xt.1 xt.2)) xt.2 := by + classical obtain ⟨r, hr, ε, hε, H⟩ := exists_forall_mem_closedBall_exists_eq_forall_mem_Ioo_hasDerivAt hf t₀ choose α hα using H refine ⟨fun (x : E) ↦ if hx : x ∈ closedBall x₀ r then α x hx else 0, ?_⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean b/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean index 2d912467e562b6..91d1e49c6cc7cd 100644 --- a/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean @@ -449,7 +449,6 @@ theorem completeEquipartiteGraph_isContained_iff : completeEquipartiteGraph r t ⊑ G ↔ Nonempty (G.CompleteEquipartiteSubgraph r t) := ⟨fun ⟨f⟩ ↦ ⟨CompleteEquipartiteSubgraph.ofCopy f⟩, fun ⟨K⟩ ↦ ⟨K.toCopy⟩⟩ -open Classical in /-- Simple graphs contain a copy of a `completeEquipartiteGraph (r + 1) t` iff there exists `s : Finset V` of size `#s = t` and `K : G.CompleteEquipartiteSubgraph r t` such that the vertices in `s` are adjacent to the vertices in `K`. -/ @@ -457,6 +456,7 @@ theorem completeEquipartiteGraph_succ_isContained_iff : completeEquipartiteGraph (r + 1) t ⊑ G ↔ ∃ᵉ (K : G.CompleteEquipartiteSubgraph r t) (s : Finset V), #s = t ∧ ∀ p ∈ K.parts, G.IsCompleteBetween p s := by + classical by_cases ht : t = 0 · have (r' : ℕ) : IsEmpty (Fin r' × Fin t) := by simp [ht, Fin.isEmpty] have h_bot (r' : ℕ) : completeEquipartiteGraph r' t = ⊥ := diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean index bd839dc27e9f29..b8c6c828860f3b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean @@ -43,10 +43,10 @@ def IsExtremal (G : SimpleGraph V) [DecidableRel G.Adj] (p : SimpleGraph V → P lemma IsExtremal.prop {p : SimpleGraph V → Prop} (h : G.IsExtremal p) : p G := h.1 -open Classical in /-- If one simple graph satisfies `p`, then there exists an extremal graph satisfying `p`. -/ theorem exists_isExtremal_iff_exists (p : SimpleGraph V → Prop) : (∃ G : SimpleGraph V, ∃ _ : DecidableRel G.Adj, G.IsExtremal p) ↔ ∃ G, p G := by + classical refine ⟨fun ⟨_, _, h⟩ ↦ ⟨_, h.1⟩, fun ⟨G, hp⟩ ↦ ?_⟩ obtain ⟨G', hp', h⟩ := by apply exists_max_image { G | p G } (#·.edgeFinset) diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean index ea465294ae58bb..234e7a12638587 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean @@ -154,13 +154,13 @@ noncomputable abbrev turanDensityConst (H : SimpleGraph W) (ε : ℝ) := Nat.find <| eventually_atTop.mp <| eventually_isContained_of_card_edgeFinset H h else 0 -open Classical in /-- Simple graphs on `card V` vertices having at least `(turanDensity H + o(1)) * (card V) ^ 2` edges contain `H`, for sufficiently large `card V`. -/ theorem isContained_of_card_edgeFinset (H : SimpleGraph W) {ε : ℝ} (hε_pos : 0 < ε) {V : Type*} [Fintype V] (h_verts : card V ≥ turanDensityConst H ε) (G : SimpleGraph V) [DecidableRel G.Adj] : #G.edgeFinset ≥ (turanDensity H + ε) * (card V).choose 2 → H ⊑ G := by + classical rw [(G.overFinIso rfl).card_edgeFinset_eq, isContained_congr Iso.refl (G.overFinIso rfl)] apply Nat.find_spec <| eventually_atTop.mp <| eventually_isContained_of_card_edgeFinset H hε_pos simpa only [turanDensityConst, hε_pos, ↓reduceDIte] using h_verts diff --git a/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean b/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean index fbbb0cf0539895..3b9af73fe70af5 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean @@ -67,10 +67,10 @@ noncomputable def exponent [HasExponent K L] : ℕ := variable {L} -open Classical in theorem exponent_def [HasExponent K L] (a : L) : - a ^ ringExpChar K ^ exponent K L ∈ (algebraMap K L).range := - Nat.find_spec ‹HasExponent K L›.has_exponent a + a ^ ringExpChar K ^ exponent K L ∈ (algebraMap K L).range := by + classical + exact Nat.find_spec ‹HasExponent K L›.has_exponent a /-- Version of `exponent_def` using `ExpChar`. -/ theorem exponent_def' [HasExponent K L] (p : ℕ) [ExpChar K p] (a : L) : @@ -79,10 +79,10 @@ theorem exponent_def' [HasExponent K L] (p : ℕ) [ExpChar K p] (a : L) : variable {K} -open Classical in theorem exponent_min [HasExponent K L] {e : ℕ} (h : e < exponent K L) : - ∃ a, a ^ ringExpChar K ^ e ∉ (algebraMap K L).range := - not_forall.mp <| Nat.find_min ‹HasExponent K L›.has_exponent h + ∃ a, a ^ ringExpChar K ^ e ∉ (algebraMap K L).range := by + classical + exact not_forall.mp <| Nat.find_min ‹HasExponent K L›.has_exponent h /-- Version of `exponent_min` using `ExpChar`. -/ theorem exponent_min' [HasExponent K L] (p : ℕ) [ExpChar K p] {e : ℕ} (h : e < exponent K L) : @@ -134,12 +134,11 @@ See `IsPurelyInseparable.algebraMap_elemReduct_eq`. -/ noncomputable def elemReduct (a : L) : K := Classical.choose <| Nat.find_spec <| minpoly_eq_X_pow_sub_C K (ringExpChar K) a -open Classical in theorem minpoly_eq (a : L) : - minpoly K a = X ^ ringExpChar K ^ elemExponent K a - C (elemReduct K a) := - Classical.choose_spec <| Nat.find_spec <| minpoly_eq_X_pow_sub_C K (ringExpChar K) a + minpoly K a = X ^ ringExpChar K ^ elemExponent K a - C (elemReduct K a) := by + classical + exact Classical.choose_spec <| Nat.find_spec <| minpoly_eq_X_pow_sub_C K (ringExpChar K) a -open Classical in /-- Version of `minpoly_eq` using `ExpChar`. -/ theorem minpoly_eq' (p : ℕ) [ExpChar K p] (a : L) : minpoly K a = X ^ p ^ elemExponent K a - C (elemReduct K a) := diff --git a/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean b/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean index 8c884280b839fd..fd03b5f799dd82 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean @@ -62,7 +62,6 @@ theorem equivalent_of_isAlgClosed [Invertible (2 : K)] {M : Type*} [AddCommGroup [FiniteDimensional K M] (Q₁ Q₂ : QuadraticForm K M) (hQ₁ : (associated Q₁).SeparatingLeft) (hQ₂ : (associated Q₂).SeparatingLeft) : Equivalent Q₁ Q₂ := - open Classical in (Q₁.equivalent_weightedSumSquares_of_isAlgClosed hQ₁).trans (Q₂.equivalent_weightedSumSquares_of_isAlgClosed hQ₂).symm diff --git a/Mathlib/Logic/Nontrivial/Basic.lean b/Mathlib/Logic/Nontrivial/Basic.lean index a846fe23a9037d..231dd8d624dbdd 100644 --- a/Mathlib/Logic/Nontrivial/Basic.lean +++ b/Mathlib/Logic/Nontrivial/Basic.lean @@ -64,10 +64,10 @@ namespace Pi variable {I : Type*} {f : I → Type*} -open Classical in /-- A pi type is nontrivial if it's nonempty everywhere and nontrivial somewhere. -/ theorem nontrivial_at (i' : I) [inst : ∀ i, Nonempty (f i)] [Nontrivial (f i')] : Nontrivial (∀ i : I, f i) := by + classical letI := Classical.decEq (∀ i : I, f i) exact (Function.update_injective (fun i ↦ Classical.choice (inst i)) i').nontrivial diff --git a/Mathlib/Logic/Nontrivial/Defs.lean b/Mathlib/Logic/Nontrivial/Defs.lean index 7d9d878ee2e03b..d912b4b4b429f8 100644 --- a/Mathlib/Logic/Nontrivial/Defs.lean +++ b/Mathlib/Logic/Nontrivial/Defs.lean @@ -58,8 +58,9 @@ protected theorem Decidable.exists_ne [Nontrivial α] [DecidableEq α] (x : α) exact ⟨y', h.symm⟩ · exact ⟨y, Ne.symm hx⟩ -open Classical in -theorem exists_ne [Nontrivial α] (x : α) : ∃ y, y ≠ x := Decidable.exists_ne x +theorem exists_ne [Nontrivial α] (x : α) : ∃ y, y ≠ x := + open scoped Classical in + Decidable.exists_ne x -- `x` and `y` are explicit here, as they are often needed to guide typechecking of `h`. theorem nontrivial_of_ne (x y : α) (h : x ≠ y) : Nontrivial α := diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index d82e901ee3ed54..421eca9f6d02ef 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -240,7 +240,6 @@ protected abbrev IntegrableOn (μ : VectorMeasure X F) (f : X → E) (s : Set X) : Prop := (μ.restrict s).Integrable f -open Classical in /-- The `G`-valued integral of `E`-valued function and the `F`-valued vector measure `μ` with linear paring `B : E →L[ℝ] F →L[ℝ] G` . This is set to be `0` if `G` is not complete or if `f` is not integrable with respect to `(μ.transpose B).variation`. Notation `∫ᵛ x, f x ∂[B; μ]`. diff --git a/Mathlib/NumberTheory/KummerDedekind.lean b/Mathlib/NumberTheory/KummerDedekind.lean index 047f50d41348f1..faaa85b2416425 100644 --- a/Mathlib/NumberTheory/KummerDedekind.lean +++ b/Mathlib/NumberTheory/KummerDedekind.lean @@ -115,7 +115,6 @@ noncomputable def normalizedFactorsMapEquivNormalizedFactorsMinPolyMk (hI : IsMa · refine (Ideal.normalizedFactorsEquivSpanNormalizedFactors ?_).symm exact Polynomial.map_monic_ne_zero (minpoly.monic hx') -open Classical in /-- The second half of the **Kummer-Dedekind Theorem**, stating that the bijection `FactorsEquiv'` defined in the first half preserves multiplicities. -/ theorem emultiplicity_factors_map_eq_emultiplicity @@ -125,6 +124,7 @@ theorem emultiplicity_factors_map_eq_emultiplicity emultiplicity J (I.map (algebraMap R S)) = emultiplicity (↑(normalizedFactorsMapEquivNormalizedFactorsMinPolyMk hI hI' hx hx' ⟨J, hJ⟩)) (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)) := by + classical rw [normalizedFactorsMapEquivNormalizedFactorsMinPolyMk, Equiv.coe_trans, Function.comp_apply, Ideal.emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_emultiplicity, IsDedekindDomain.normalizedFactorsEquivOfQuotEquiv_emultiplicity_eq_emultiplicity] diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean index 0d867ec9dcca5a..0c477d92a57d5e 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean @@ -93,7 +93,6 @@ open NumberField.Units NumberField.Units.dirichletUnitTheorem Module variable [NumberField K] {K} -open Classical in /-- The map from the mixed space to `logSpace K` defined in such way that: 1) it factors the map `logEmbedding`, see `logMap_eq_logEmbedding`; 2) it is constant on the sets `{c • x | c ∈ ℝ, c ≠ 0}` if `norm x ≠ 0`, see `logMap_real_smul`. -/ diff --git a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean index f6ebed5b24e851..bb1e0e04d4fba0 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean @@ -56,7 +56,6 @@ section DecEq variable {S₁ : Type*} [CommRing S₁] [Algebra R S₁] -open Classical in /-- The inertia degree of `P : Ideal S` lying over `p : Ideal R` is the degree of the extension `(S / P) : (R / p)`. diff --git a/Mathlib/Order/CompleteLatticeIntervals.lean b/Mathlib/Order/CompleteLatticeIntervals.lean index d55d8efcda1b5b..410bdf8aa0da86 100644 --- a/Mathlib/Order/CompleteLatticeIntervals.lean +++ b/Mathlib/Order/CompleteLatticeIntervals.lean @@ -168,7 +168,6 @@ end OrdConnected section Icc -open Classical in /-- Complete lattice structure on `Set.Icc` -/ noncomputable instance Set.Icc.completeLattice [ConditionallyCompleteLattice α] {a b : α} [Fact (a ≤ b)] : CompleteLattice (Set.Icc a b) where diff --git a/Mathlib/Order/Preorder/Chain.lean b/Mathlib/Order/Preorder/Chain.lean index ef314eaee043c2..570324303c31af 100644 --- a/Mathlib/Order/Preorder/Chain.lean +++ b/Mathlib/Order/Preorder/Chain.lean @@ -300,8 +300,8 @@ theorem succChain_spec (h : ∃ t, IsChain r s ∧ SuperChain r s t) : have : IsChain r s ∧ SuperChain r s h.choose := h.choose_spec simpa [SuccChain, dif_pos, exists_and_left.mp h] using this.2 -open Classical in theorem IsChain.succ (hs : IsChain r s) : IsChain r (SuccChain r s) := + open Classical in if h : ∃ t, IsChain r s ∧ SuperChain r s t then (succChain_spec h).1 else by rw [exists_and_left] at h @@ -313,8 +313,8 @@ theorem IsChain.superChain_succChain (hs₁ : IsChain r s) (hs₂ : ¬IsMaxChain obtain ⟨t, ht, hst⟩ := hs₂ hs₁ exact succChain_spec ⟨t, hs₁, ht, ssubset_iff_subset_ne.2 hst⟩ -open Classical in theorem subset_succChain : s ⊆ SuccChain r s := + open Classical in if h : ∃ t, IsChain r s ∧ SuperChain r s t then (succChain_spec h).2.1 else by simp [SuccChain, h] diff --git a/Mathlib/Order/SuccPred/CompleteLinearOrder.lean b/Mathlib/Order/SuccPred/CompleteLinearOrder.lean index 1f9d8f5fef5739..10c2c2e1f76a4b 100644 --- a/Mathlib/Order/SuccPred/CompleteLinearOrder.lean +++ b/Mathlib/Order/SuccPred/CompleteLinearOrder.lean @@ -79,7 +79,6 @@ lemma IsGLB.exists_of_nonempty_of_not_isPredPrelimit (hf : IsGLB (range f) x) (hx : ¬ IsPredPrelimit x) : ∃ i, f i = x := hf.exists_of_nonempty_of_not_isPredLimit <| mt IsPredLimit.isPredPrelimit hx -open Classical in /-- Every conditionally complete linear order with well-founded `<` is a successor order, by setting the successor of an element to be the infimum of all larger elements. -/ @[implicit_reducible, deprecated SuccOrder.ofLinearWellFoundedLT (since := "2026-04-12")] diff --git a/Mathlib/Probability/Moments/CovarianceBilinDual.lean b/Mathlib/Probability/Moments/CovarianceBilinDual.lean index b6270b417c8f6b..af82b04e46905b 100644 --- a/Mathlib/Probability/Moments/CovarianceBilinDual.lean +++ b/Mathlib/Probability/Moments/CovarianceBilinDual.lean @@ -224,7 +224,6 @@ section Covariance variable [NormedSpace ℝ E] [BorelSpace E] -open Classical in /-- Continuous bilinear form with value `∫ x, (L₁ x - μ[L₁]) * (L₂ x - μ[L₂]) ∂μ` on `(L₁, L₂)` if `MemLp id 2 μ`. If not, we set it to zero. -/ noncomputable diff --git a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean index 78804ef7d5efc4..2359cb8268f2c8 100644 --- a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean +++ b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean @@ -85,7 +85,6 @@ variable {R : Type u} [CommRing R] [IsDedekindDomain R] {K : Type v} [Field K] namespace HeightOneSpectrum -open Classical in /-- The multiplicative `v`-adic valuation on `Kˣ`. -/ def valuationOfNeZeroToFun (x : Kˣ) : Multiplicative ℤ := let hx := IsLocalization.sec R⁰ (x : K) diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index f93ac3d6bc2621..573b3b0fe62ad9 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -401,7 +401,6 @@ theorem unit_mul_pow_congr_unit {ϖ : R} (hirr : Irreducible ϖ) (u v : Rˣ) (m ## The additive valuation on a DVR -/ -open Classical in /-- The `ℕ∞`-valued additive valuation on a DVR. -/ noncomputable def addVal (R : Type u) [CommRing R] [IsDomain R] [IsDiscreteValuationRing R] : AddValuation R ℕ∞ := diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index b47610cfd797c3..8b0fe18166dad5 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -323,7 +323,6 @@ theorem coeff_eq_zero_of_lt_orderTop {x : R⟦Γ⟧} {i : Γ} (hi : i < x.orderT rw [orderTop_of_ne_zero hx, WithTop.coe_lt_coe] exact Set.IsWF.not_lt_min _ _ hi -open Classical in /-- A leading coefficient of a Hahn series is the coefficient of a lowest-order nonzero term, or zero if the series vanishes. -/ def leadingCoeff (x : R⟦Γ⟧) : R := x.orderTop.recTopCoe 0 x.coeff diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index 7b93b28eee7e7d..8dd5a1c99d6929 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -221,9 +221,9 @@ theorem factors_eq_singleton_of_irreducible {a : α} (ha : Irreducible a) : exact ⟨b, hab, .symm <| Multiset.eq_of_le_of_card_le (Multiset.singleton_le.mpr hbmem) (by rw [card_factors_of_irreducible ha, Multiset.card_singleton])⟩ -open Classical in theorem factors_mul {x y : α} (hx : x ≠ 0) (hy : y ≠ 0) : Rel Associated (factors (x * y)) (factors x + factors y) := by + classical refine factors_unique irreducible_of_factor (fun a ha => diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean index ee203370d34d5e..5a41a90bce1993 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean @@ -387,9 +387,9 @@ theorem mem_factors_iff_dvd {a p : α} (ha0 : a ≠ 0) (hp : Irreducible p) : apply dvd_of_mem_factors · apply mem_factors_of_dvd ha0 hp -open Classical in theorem exists_prime_dvd_of_not_inf_one {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) (h : Associates.mk a ⊓ Associates.mk b ≠ 1) : ∃ p : α, Prime p ∧ p ∣ a ∧ p ∣ b := by + classical have hz : factors (Associates.mk a) ⊓ factors (Associates.mk b) ≠ 0 := by contrapose h with hf change (factors (Associates.mk a) ⊓ factors (Associates.mk b)).prod = 1 diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 689ae9ee2f849c..8a0b3c5ed4a4d3 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -1074,10 +1074,10 @@ theorem exists_ord_eq (α) : ∃ (r : α → α → Prop) (_ : IsWellOrder α r) @[deprecated (since := "2026-03-29")] alias ord_eq := exists_ord_eq -open Classical in /-- There exists a well-order on `α` whose order type is exactly `ord #α`. -/ theorem exists_ord_eq_type_lt (α) : ∃ (_ : LinearOrder α) (_ : WellFoundedLT α), ord #α = typeLT α := + open scoped Classical in let ⟨r, _, hr⟩ := exists_ord_eq α let := linearOrderOfSTO r ⟨this, inferInstance, hr⟩ diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index 076d0884992796..b31ebedce237be 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -867,10 +867,10 @@ lemma ContinuousOn.union_continuousAt {f : α → β} (s_op : IsOpen s) (fun h => ContinuousWithinAt.continuousAt (continuousWithinAt hs h) <| IsOpen.mem_nhds s_op h) (ht _) -open Classical in /-- If a function is continuous on two closed sets, it is also continuous on their union. -/ theorem ContinuousOn.union_of_isClosed {f : α → β} (hfs : ContinuousOn f s) (hft : ContinuousOn f t) (hs : IsClosed s) (ht : IsClosed t) : ContinuousOn f (s ∪ t) := by + classical refine fun x hx ↦ .union ?_ ?_ · refine if hx : x ∈ s then hfs x hx else continuousWithinAt_of_notMem_closure ?_ rwa [hs.closure_eq] diff --git a/Mathlib/Topology/MetricSpace/CoveringNumbers.lean b/Mathlib/Topology/MetricSpace/CoveringNumbers.lean index 7239f25d474303..2aac260334ff10 100644 --- a/Mathlib/Topology/MetricSpace/CoveringNumbers.lean +++ b/Mathlib/Topology/MetricSpace/CoveringNumbers.lean @@ -246,7 +246,6 @@ lemma exists_set_encard_eq_coveringNumber (h : coveringNumber ε A ≠ ⊤) : simp_rw [iInf_subtype, iInf_and] rfl -open Classical in /-- A finite internal `ε`-cover of a set `A` by closed balls with minimal cardinality. It is defined as the empty set if no such finite cover exists. -/ noncomputable From a77377db42d36c734ebc20721fbe6e0150498757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hagb=20=28Junyu=20Guo=20=E9=83=AD=E4=BF=8A=E4=BD=99=29?= Date: Tue, 7 Jul 2026 09:24:46 +0000 Subject: [PATCH 0626/1300] chore(Data/Finsupp/MonomialOrder): rename fields of `MonomialOrder` to match naming conventions (#39494) Moves: - MonomialOrder.acm -> MonomialOrder.addCommMonoidSyn - MonomialOrder.lo -> MonomialOrder.linearOrderSyn - MonomialOrder.iocam -> MonomialOrder.isOrderedCancelAddMonoid_syn - MonomialOrder.wf -> MonomialOrder.wellFoundedLT_syn --- Mathlib/Data/Finsupp/MonomialOrder.lean | 19 ++++++++++++++----- Mathlib/RingTheory/MvPolynomial/Groebner.lean | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Mathlib/Data/Finsupp/MonomialOrder.lean b/Mathlib/Data/Finsupp/MonomialOrder.lean index 870cb641ffe02b..2c8b742bff7349 100644 --- a/Mathlib/Data/Finsupp/MonomialOrder.lean +++ b/Mathlib/Data/Finsupp/MonomialOrder.lean @@ -62,19 +62,28 @@ structure MonomialOrder (σ : Type*) where /-- The synonym type -/ syn : Type* /-- `syn` is an additive commutative monoid -/ - acm : AddCommMonoid syn := by infer_instance + addCommMonoidSyn : AddCommMonoid syn := by infer_instance /-- `syn` is linearly ordered -/ - lo : LinearOrder syn := by infer_instance + linearOrderSyn : LinearOrder syn := by infer_instance /-- `syn` is a linearly ordered cancellative additive commutative monoid -/ - iocam : IsOrderedCancelAddMonoid syn := by infer_instance + isOrderedCancelAddMonoid_syn : IsOrderedCancelAddMonoid syn := by infer_instance /-- the additive equivalence from `σ →₀ ℕ` to `syn` -/ toSyn : (σ →₀ ℕ) ≃+ syn /-- `toSyn` is monotone -/ toSyn_monotone : Monotone toSyn /-- `syn` is a well ordering -/ - wf : WellFoundedLT syn := by infer_instance + wellFoundedLT_syn : WellFoundedLT syn := by infer_instance -attribute [instance] MonomialOrder.acm MonomialOrder.lo MonomialOrder.iocam MonomialOrder.wf +attribute [instance] MonomialOrder.addCommMonoidSyn MonomialOrder.linearOrderSyn + MonomialOrder.isOrderedCancelAddMonoid_syn MonomialOrder.wellFoundedLT_syn + +@[deprecated (since := "2026-07-07")] alias acm := MonomialOrder.addCommMonoidSyn + +@[deprecated (since := "2026-07-07")] alias lo := MonomialOrder.linearOrderSyn + +@[deprecated (since := "2026-07-07")] alias iocam := MonomialOrder.isOrderedCancelAddMonoid_syn + +@[deprecated (since := "2026-07-07")] alias wf := MonomialOrder.wellFoundedLT_syn namespace MonomialOrder diff --git a/Mathlib/RingTheory/MvPolynomial/Groebner.lean b/Mathlib/RingTheory/MvPolynomial/Groebner.lean index a812383025b4d6..a6e9f9fd30e998 100644 --- a/Mathlib/RingTheory/MvPolynomial/Groebner.lean +++ b/Mathlib/RingTheory/MvPolynomial/Groebner.lean @@ -210,7 +210,7 @@ theorem div {ι : Type*} {b : ι → MvPolynomial σ R} exact bot_le · exact (div hb) (m.subLTerm f) termination_by WellFounded.wrap - ((isWellFounded_iff m.syn fun x x_1 ↦ x < x_1).mp m.wf) (m.toSyn (m.degree f)) + ((isWellFounded_iff m.syn fun x x_1 ↦ x < x_1).mp m.wellFoundedLT_syn) (m.toSyn (m.degree f)) decreasing_by · exact deg_reduce · apply degree_sub_LTerm_lt From 70f9aed325d8940844ad0e3246dc487f51bcb52a Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:24:48 +0000 Subject: [PATCH 0627/1300] chore(CategoryTheory/Limits/Types): change imports to avoid generating elementwise lemmas twice (#41425) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `@[elementwise]`-generated lemmas `limit.lift_π_apply`, `limit.w_apply`, `colimit.w_apply` and `colimit.ι_desc_apply` were generated twice: once in `CategoryTheory/ConcreteCategory/Elementwise.lean` and once in `CategoryTheory/Limits/Types/{Limits,Colimits}.lean`. This was harmless only because no module imported both generation sites; importing both makes `@[elementwise]` panic (cf. #40343 and previous iterations; this panic is fixed in #41422). This PR adds the import `Mathlib.CategoryTheory.ConcreteCategory.Elementwise` to the two `Types` files so they only generate the lemmas unique to them (`limMap_π_apply`, `colimit.ι_map_apply`). --- Mathlib/CategoryTheory/Limits/Types/Colimits.lean | 9 ++++++--- Mathlib/CategoryTheory/Limits/Types/Limits.lean | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Types/Colimits.lean b/Mathlib/CategoryTheory/Limits/Types/Colimits.lean index ae469221a059ea..bd32d232cc6df7 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Colimits.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Colimits.lean @@ -8,6 +8,7 @@ module public import Mathlib.Logic.UnivLE public import Mathlib.CategoryTheory.Limits.HasLimits public import Mathlib.CategoryTheory.Limits.Types.ColimitType +public import Mathlib.CategoryTheory.ConcreteCategory.Elementwise /-! # Colimits in the category of types @@ -175,9 +176,11 @@ theorem colimitEquivColimitType_apply (j : J) (x : F.obj j) : apply (colimitEquivColimitType F).symm.injective simp --- We don’t want to add `simp` to the original lemmas here -attribute [elementwise] colimit.w colimit.ι_desc colimit.ι_map -attribute [simp] colimit.w_apply colimit.ι_desc_apply colimit.ι_map_apply +-- We don’t want to add `simp` to the original lemmas here. +-- `colimit.w_apply` and `colimit.ι_desc_apply` are generated (and tagged `simp`) +-- in `Mathlib/CategoryTheory/ConcreteCategory/Elementwise.lean`. +attribute [elementwise] colimit.ι_map +attribute [simp] colimit.ι_map_apply variable {F} in @[deprecated colimit.w_apply (since := "2026-03-06")] diff --git a/Mathlib/CategoryTheory/Limits/Types/Limits.lean b/Mathlib/CategoryTheory/Limits/Types/Limits.lean index dec26a7ed19692..ebf1171a01a58c 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Limits.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Limits.lean @@ -7,6 +7,7 @@ module public import Mathlib.Logic.UnivLE public import Mathlib.CategoryTheory.Limits.HasLimits +public import Mathlib.CategoryTheory.ConcreteCategory.Elementwise /-! # Limits in the category of types. @@ -241,8 +242,10 @@ theorem limit_ext_iff' (F' : J ⥤ Type v) (x y : limit F') : x = y ↔ ∀ j, limit.π F' j x = limit.π F' j y := ⟨fun t _ => t ▸ rfl, limit_ext' _ _ _⟩ -attribute [elementwise] limit.lift_π limMap_π limit.w -attribute [simp] limit.lift_π_apply limMap_π_apply limit.w_apply +-- `limit.lift_π_apply` and `limit.w_apply` are generated (and tagged `simp`) +-- in `Mathlib/CategoryTheory/ConcreteCategory/Elementwise.lean`. +attribute [elementwise] limMap_π +attribute [simp] limMap_π_apply variable {F} in @[deprecated limit.w_apply (since := "2026-02-17")] From 80b457d52734bab76b8b75adfc69c6e7ed4120f0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:45:31 +0000 Subject: [PATCH 0628/1300] chore: properly deprecate the `linter.style.commandStart` option (#41408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - use the correct syntax for deprecating it: the previous one silently did nothing - as confirmed on Zulip: [#lean4 > No warning on use of deprecated options @ 💬](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/No.20warning.20on.20use.20of.20deprecated.20options/near/608661359) - remove the check for the `linter.style.commandStart` option in the `set_option` linter: it just duplicates the linter's check --- Mathlib/Tactic/Linter/Style.lean | 8 ++------ Mathlib/Tactic/Linter/Whitespace.lean | 2 +- MathlibTest/Linter/Whitespace.lean | 6 +++++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/Tactic/Linter/Style.lean b/Mathlib/Tactic/Linter/Style.lean index d949f89d541593..a3ed8ab4a86ac6 100644 --- a/Mathlib/Tactic/Linter/Style.lean +++ b/Mathlib/Tactic/Linter/Style.lean @@ -81,7 +81,7 @@ public def isSetOption : Syntax → Bool := /-- The `setOption` linter: this lints any `set_option` command, term or tactic which sets a `debug`, `pp`, `profiler` or `trace` option. This also warns if an option containing `maxHeartbeats` (typically, the `maxHeartbeats` or -`synthInstance.maxHeartbeats` option) or the `linter.flexible`, `linter.style.commandStart` or +`synthInstance.maxHeartbeats` option) or the `linter.flexible` or `backward.inferInstanceAs.wrap.reuseSubInstances ` option is set. **Why is this bad?** The `debug`, `pp`, `profiler` and `trace` options are good for debugging, @@ -92,8 +92,7 @@ explaining the need for them; another linter enforces this). The `linter.flexible` option should be scoped as `set_option opt in ...`. **How to fix this?** The `maxHeartbeats` and `linter.flexible` option changes can be scoped to -individual commands, if they are truly necessary. The `linter.style.commandStart` option is -deprecated and should be replaced by `linter.style.whitespace`. +individual commands, if they are truly necessary. New `backward.inferInstanceAs.wrap.reuseSubInstances` instances are technical debt, and should not be introduced. @@ -120,9 +119,6 @@ def setOptionLinter : Linter where run := withSetOptionIn fun stx => do Please scope this to individual declarations, as in\n```\nset_option {name} in\n\ -- comment explaining why this is necessary\n\ example : ... := ...\n```" - else if name == `linter.style.commandStart then - logWarningAt stx "The `linter.style.commandStart` option is deprecated, \ - use `linter.style.whitespace` instead." else if name == `backward.inferInstanceAs.wrap.reuseSubInstances then logWarningAt stx "The `backward.inferInstanceAs.wrap.reuseSubInstances` option \ marks the introduction of technical debt, so please don't use it." diff --git a/Mathlib/Tactic/Linter/Whitespace.lean b/Mathlib/Tactic/Linter/Whitespace.lean index 2c6a496e390461..0ba87d4e2b148f 100644 --- a/Mathlib/Tactic/Linter/Whitespace.lean +++ b/Mathlib/Tactic/Linter/Whitespace.lean @@ -43,10 +43,10 @@ public register_option linter.style.whitespace : Bool := { } /-- Deprecated in favour of `linter.style.whitespace` -/ -@[deprecated linter.style.whitespace (since := "2026-01-07")] public register_option linter.style.commandStart : Bool := { defValue := false descr := "deprecated: use the `linter.style.whitespace` option instead" + deprecation? := some { since := "2026-01-07", text? := "use the `linter.style.whitespace` option instead" } } /-- If the `linter.style.whitespace.verbose` option is `true`, the `whitespace` linter diff --git a/MathlibTest/Linter/Whitespace.lean b/MathlibTest/Linter/Whitespace.lean index fe8a85914821f4..b19b94f2b5db63 100644 --- a/MathlibTest/Linter/Whitespace.lean +++ b/MathlibTest/Linter/Whitespace.lean @@ -11,11 +11,15 @@ section set_option linter.style.setOption true /-- -warning: The `linter.style.commandStart` option is deprecated, use `linter.style.whitespace` instead. +warning: `linter.style.commandStart` has been deprecated: use the `linter.style.whitespace` option instead -/ #guard_msgs in set_option linter.style.commandStart true +/-- +warning: `linter.style.commandStart` has been deprecated: use the `linter.style.whitespace` option instead +-/ +#guard_msgs in set_option linter.style.commandStart true in example : Nat := 0 From 2e09891a520feeea2194c3f33d57477eb814d7a8 Mon Sep 17 00:00:00 2001 From: David Kurniadi Angdinata Date: Tue, 7 Jul 2026 10:41:25 +0000 Subject: [PATCH 0629/1300] feat(NumberTheory/EllipticDivisibilitySequence): add elliptic nets (#25989) This PR continues the work from #25030. Original PR: https://github.com/leanprover-community/mathlib4/pull/25030 Co-authored-by: tb65536 --- Mathlib/Data/Nat/DvdSequence.lean | 15 +- .../EllipticDivisibilitySequence.lean | 323 +++++++++++++++--- 2 files changed, 285 insertions(+), 53 deletions(-) diff --git a/Mathlib/Data/Nat/DvdSequence.lean b/Mathlib/Data/Nat/DvdSequence.lean index dcb4abb9a28910..37ea8e9e312645 100644 --- a/Mathlib/Data/Nat/DvdSequence.lean +++ b/Mathlib/Data/Nat/DvdSequence.lean @@ -40,6 +40,8 @@ lemma smul_dvd_smul [Monoid α] [Monoid β] [SMul α β] [IsScalarTower α β β def IsDvdSequence [Dvd α] [Dvd β] (f : α → β) : Prop := ∀ a b, a ∣ b → f a ∣ f b +@[deprecated (since := "2026-06-30")] alias IsDivSequence := IsDvdSequence + namespace IsDvdSequence variable (α) in @@ -55,17 +57,20 @@ protected theorem smul' [Dvd α] [Monoid β] [Monoid γ] {f : α → β} {g : α (hf : IsDvdSequence f) (hg : IsDvdSequence g) : IsDvdSequence (f • g) := fun a b hab ↦ smul_dvd_smul (hf a b hab) (hg a b hab) -protected theorem mul [Dvd α] [CommMonoid β] {f g : α → β} - (hf : IsDvdSequence f) (hg : IsDvdSequence g) : IsDvdSequence (f * g) := +protected theorem mul [Dvd α] [CommMonoid β] {f g : α → β} (hf : IsDvdSequence f) + (hg : IsDvdSequence g) : IsDvdSequence (f * g) := .smul' hf hg -protected theorem smul [Dvd α] [Monoid β] [Monoid γ] {f : α → γ} [SMul β γ] - [IsScalarTower β γ γ] [IsScalarTower β β γ] [SMulCommClass β γ γ] - (b : β) (hg : IsDvdSequence f) : IsDvdSequence (b • f) := +protected theorem smul [Dvd α] [Monoid β] [Monoid γ] {f : α → γ} [SMul β γ] [IsScalarTower β γ γ] + [IsScalarTower β β γ] [SMulCommClass β γ γ] (b : β) (hg : IsDvdSequence f) : + IsDvdSequence (b • f) := .smul' (.const α b) hg end IsDvdSequence +@[deprecated (since := "2026-06-30")] alias IsDivSequence.smul := IsDvdSequence.smul +@[deprecated (since := "2026-06-30")] alias isDivSequence_id := IsDvdSequence.id + namespace Nat /-- A function `f : ℕ → ℕ` is a strong divisibility sequence if `gcd (f a) (f b) = f (gcd a b)`. -/ diff --git a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean index 649c86acda9939..99cab97650e2f8 100644 --- a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean +++ b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean @@ -5,23 +5,45 @@ Authors: David Kurniadi Angdinata -/ module +public import Mathlib.Algebra.Group.EvenFunction public import Mathlib.Data.Nat.DvdSequence public import Mathlib.Data.Nat.EvenOddRec public import Mathlib.Tactic.Linarith public import Mathlib.Tactic.LinearCombination +public import Mathlib.Tactic.Ring import Mathlib.Algebra.Group.Int.Even +import Mathlib.Data.Int.ModEq /-! # Elliptic divisibility sequences -This file defines the type of an elliptic divisibility sequence (EDS) and a few examples. +This file defines the predicates for a sequence to be an elliptic net or an elliptic divisibility +sequence, as well as the canonical example of a normalised elliptic divisibility sequence. ## Mathematical background -Let `R` be a commutative ring. An elliptic sequence is a sequence `W : ℤ → R` satisfying -`W(m + n)W(m - n)W(r)² = W(m + r)W(m - r)W(n)² - W(n + r)W(n - r)W(m)²` for any `m, n, r ∈ ℤ`. -A divisibility sequence is a sequence `W : ℤ → R` satisfying `W(m) ∣ W(n)` for any `m, n ∈ ℤ` such -that `m ∣ n`. An elliptic divisibility sequence is simply a divisibility sequence that is elliptic. +Let `R` be a commutative ring, and let `W` be a sequence of elements in `R` indexed by `ℤ`. The +*elliptic relator* `ER(p, q, r, s) ∈ R` associated to `W` is given for all `p, q, r, s ∈ ℤ` by +`ER(p, q, r, s) := W(p+q+s)W(p-q)W(r+s)W(r) - W(p+r+s)W(p-r)W(q+s)W(q) + W(q+r+s)W(q-r)W(p+s)W(p)`. +Call `W` an *elliptic net* if it satisfies the *elliptic relation* `ER(p, q, r, s) = 0` for all +`p, q, r, s ∈ ℤ`. By a change of variables, `ER` is related to the symmetric relation `ERₐ` (see +`IsEllipticNet.rel_eq` and `IsEllipticNet.atomRel_eq`), where `ERₐ(a, b, c, d) ∈ R` is given for all +`a, b, c, d ∈ ℤ` by `ERₐ(a, b, c, d) := Wₐ(a, b)Wₐ(c, d) - Wₐ(a, c)Wₐ(b, d) + Wₐ(a, d)Wₐ(b, c)` +defined in terms of *elliptic atoms* `Wₐ(a, b) := W((a + b) / 2)W((a - b) / 2)`. + +As a special case, `W` is an *elliptic sequence* if it satisfies `ER(p, q, r, 0) = 0` for all +`p, q, r ∈ ℤ`. It is a *divisibility sequence* if it satisfies `W(k) ∣ W(n * k)` for all `k, n ∈ ℤ`, +and an *elliptic divisibility sequence* (EDS) if it is a divisibility sequence that is elliptic. If +`W` is an EDS, then `x • W` is also an EDS for any `x ∈ R`. It turns out that any EDS `W` can be +normalised such that `W(1) = 1`, in which case it can be characterised completely by + +* the *even relations* `ER(m + 1, m - 1, 1, 0) = 0` for all `m ∈ ℤ`, or in other words that + `W(2m)W(2) = W(m - 1)²W(m)W(m + 2) - W(m - 2)W(m)W(m + 1)²` for all `m ∈ ℤ`, and +* the *odd relations* `ER(m + 1, m, 1, 0) = 0` for all `m ∈ ℤ`, or in other words that + `W(2m + 1) = W(m + 2)W(m)³ - W(m - 1)W(m + 1)³` for all `m ∈ ℤ`, + +with initial values `W(0) = 0`, `W(1) = 1`, `W(2) = b`, `W(3) = c`, and `W(4) = d * b` for some +`b, c, d ∈ R`. This will be called the *canonical example of a normalised EDS* in this file. Some examples of EDSs include * the identity sequence, @@ -30,8 +52,12 @@ Some examples of EDSs include ## Main definitions -* `IsEllSequence`: a sequence indexed by integers is an elliptic sequence. -* `IsEllDivSequence`: a sequence indexed by integers is an EDS. +* `IsEllipticNet.atom`: the elliptic atom `Wₐ(a, b)` indexed by `ℤ`. +* `IsEllipticNet.atomRel`: the elliptic relator `ERₐ(a, b, c, d)` indexed by `ℤ`. +* `IsEllipticNet.rel`: the elliptic relator `ER(p, q, r, s)` indexed by `ℤ`. +* `IsEllipticNet`: a sequence indexed by `ℤ` is an elliptic net. +* `IsEllipticSequence`: a sequence indexed by `ℤ` is an elliptic sequence. +* `IsEllipticDvdSequence`: a sequence indexed by `ℤ` is an EDS. * `preNormEDS'`: the auxiliary sequence for a normalised EDS indexed by `ℕ`. * `preNormEDS`: the auxiliary sequence for a normalised EDS indexed by `ℤ`. * `complEDS₂`: the 2-complement sequence for a normalised EDS indexed by `ℕ`. @@ -41,11 +67,15 @@ Some examples of EDSs include ## Main statements -* TODO: prove that `normEDS` satisfies `IsEllDivSequence`. -* TODO: prove that a normalised sequence satisfying `IsEllDivSequence` can be given by `normEDS`. +* TODO: prove that `normEDS` satisfies `IsEllipticDvdSequence`. +* TODO: prove that a sequence satisfying `IsEllipticDvdSequence` can be normalised to a `normEDS`. ## Implementation notes +The elliptic relator is identical to the elliptic net recurrence defined by Stange, except that the +final term in the latter is negated. This unifies the definitions of Stange's elliptic nets and +Ward's elliptic sequences without requiring the sequence to be an odd function. + The normalised EDS `normEDS b c d n` is defined in terms of the auxiliary sequence `preNormEDS (b ^ 4) c d n`, which are equal when `n` is odd, and which differ by a factor of `b` when `n` is even. This coincides with the definition in the references since both agree for @@ -61,55 +91,254 @@ polynomials of elliptic curves, omitting a factor of the bivariate `2`-division ## References -M Ward, *Memoir on Elliptic Divisibility Sequences* +* K Stange, *Elliptic Nets and Elliptic Curves* +* M Ward, *Memoir on Elliptic Divisibility Sequences* ## Tags -elliptic, divisibility, sequence +elliptic net, elliptic divisibility sequence -/ @[expose] public section -universe u v +variable {R S : Type*} [CommRing R] [CommRing S] (W : ℤ → R) {F : Type*} [FunLike F R S] + [RingHomClass F R S] (f : F) + +namespace IsEllipticNet -variable {R : Type u} [CommRing R] +/-- The elliptic atom `Wₐ(a, b)` that defines an elliptic net. Note that this is defined in terms of +truncated integer division, and hence should only be used when `a` and `b` have the same parity. -/ +def atom (a b : ℤ) : R := + W ((a + b).tdiv 2) * W ((a - b).tdiv 2) -section IsEllDivSequence +@[simp] +lemma atom_same (a : ℤ) : atom W a a = W a * W 0 := by + rw [atom, ← two_mul, Int.mul_tdiv_cancel_left _ two_ne_zero, sub_self, Int.zero_tdiv] + +variable {W} in +@[simp] +lemma neg_atom (odd : W.Odd) (a b : ℤ) : -atom W a b = atom W b a := by + rw [atom, atom, add_comm, ← neg_sub a, Int.neg_tdiv, odd, mul_neg] -variable (W : ℤ → R) +variable {W} in +lemma atom_mul_atom (odd : W.Odd) (a b c d : ℤ) : + atom W a b * atom W c d = atom W b a * atom W d c := by + rw [← neg_atom odd a b, ← neg_atom odd c d, neg_mul_neg] -/-- The proposition that a sequence indexed by integers is an elliptic sequence. -/ -def IsEllSequence : Prop := - ∀ m n r : ℤ, W (m + n) * W (m - n) * W r ^ 2 = - W (m + r) * W (m - r) * W n ^ 2 - W (n + r) * W (n - r) * W m ^ 2 +variable {W} in +@[simp] +lemma atom_neg_left (odd : W.Odd) (a b : ℤ) : atom W (-a) b = atom W a b := by + rw [atom, atom, neg_add_eq_sub, ← neg_sub a, ← neg_add', Int.neg_tdiv, odd, Int.neg_tdiv, odd, + neg_mul_neg, mul_comm] -@[deprecated (since := "2026-06-30")] alias IsDivSequence := IsDvdSequence +@[simp] +lemma atom_neg_right (a b : ℤ) : atom W a (-b) = atom W a b := by + simp_rw [atom, ← sub_eq_add_neg, sub_neg_eq_add, mul_comm] -/-- The proposition that a sequence indexed by integers is an EDS. -/ -def IsEllDivSequence : Prop := - IsEllSequence W ∧ IsDvdSequence W +variable {W} in +@[simp] +lemma atom_abs_left (odd : W.Odd) (a b : ℤ) : atom W |a| b = atom W a b := by + rcases abs_choice a with h | h <;> simp only [h, atom_neg_left odd] -lemma isEllSequence_id : IsEllSequence id := - fun _ _ _ => by simp_rw [id_eq]; ring1 +@[simp] +lemma atom_abs_right (a b : ℤ) : atom W a |b| = atom W a b := by + rcases abs_choice b with h | h <;> simp only [h, atom_neg_right] -@[deprecated (since := "2026-06-30")] alias isDivSequence_id := IsDvdSequence.id +lemma atom_even (a b : ℤ) : atom W (2 * a) (2 * b) = W (a + b) * W (a - b) := by + simp_rw [atom, ← mul_add, ← mul_sub, Int.mul_tdiv_cancel_left _ two_ne_zero] -/-- The identity sequence is an EDS. -/ -theorem isEllDivSequence_id : IsEllDivSequence id := - ⟨isEllSequence_id, .id ℤ⟩ +lemma atom_odd (a b : ℤ) : atom W (2 * a + 1) (2 * b + 1) = W (a + b + 1) * W (a - b) := by + simp_rw [atom, add_add_add_comm _ (1 : ℤ), ← two_mul, ← mul_add, add_sub_add_comm, sub_self, + add_zero, ← mul_sub, Int.mul_tdiv_cancel_left _ two_ne_zero] + +lemma map_atom (a b : ℤ) : f (atom W a b) = atom (f ∘ W) a b := by + simp_rw [atom, map_mul, Function.comp] + +/-- The elliptic relator `ERₐ(a, b, c, d)` obtained by a change of variables in `ER(p, q, r, s)` +(see `IsEllipticNet.rel_eq` and `IsEllipticNet.atomRel_eq`). Note that this is defined in terms of +elliptic atoms, and hence should only be used when `a`, `b`, `c`, and `d` have the same parity. -/ +def atomRel (a b c d : ℤ) : R := + atom W a b * atom W c d - atom W a c * atom W b d + atom W a d * atom W b c + +@[simp] +lemma atomRel_same₁₂ (a b c : ℤ) : atomRel W a a b c = W a * W 0 * atom W b c := by + simp_rw [atomRel, atom_same, mul_comm <| atom W a b, sub_add_cancel] + +variable {W} in +@[simp] +lemma atomRel_same₁₃ (odd : W.Odd) (a b c : ℤ) : atomRel W a b a c = W a * W 0 * atom W c b := by + linear_combination (norm := (simp_rw [atomRel, atom_same]; ring1)) + W a * W 0 * neg_atom odd c b - atom W a c * neg_atom odd a b + +variable {W} in +@[simp] +lemma atomRel_same₁₄ (odd : W.Odd) (a b c : ℤ) : atomRel W a b c a = W a * W 0 * atom W b c := by + simp_rw [atomRel, atom_mul_atom odd a b, mul_comm <| atom W b a, sub_self, zero_add, atom_same] + +@[simp] +lemma atomRel_same₂₃ (a b c : ℤ) : atomRel W a b b c = W b * W 0 * atom W a c := by + simp_rw [atomRel, atom_same, sub_self, zero_add, mul_comm] + +variable {W} in +@[simp] +lemma atomRel_same₂₄ (odd : W.Odd) (a b c : ℤ) : atomRel W a b c b = W b * W 0 * atom W c a := by + linear_combination (norm := (simp_rw [atomRel, atom_same]; ring1)) + W b * W 0 * neg_atom odd a c - atom W a b * neg_atom odd b c + +@[simp] +lemma atomRel_same₃₄ (a b c : ℤ) : atomRel W a b c c = W c * W 0 * atom W a b := by + simp_rw [atomRel, atom_same, mul_comm, sub_add_cancel] + +variable {W} in +@[simp] +lemma atomRel_neg₁ (odd : W.Odd) (a b c d : ℤ) : atomRel W (-a) b c d = atomRel W a b c d := by + simp_rw [atomRel, atom_neg_left odd] + +variable {W} in +@[simp] +lemma atomRel_neg₂ (odd : W.Odd) (a b c d : ℤ) : atomRel W a (-b) c d = atomRel W a b c d := by + simp_rw [atomRel, atom_neg_left odd, atom_neg_right] + +variable {W} in +@[simp] +lemma atomRel_neg₃ (odd : W.Odd) (a b c d : ℤ) : atomRel W a b (-c) d = atomRel W a b c d := by + simp_rw [atomRel, atom_neg_left odd, atom_neg_right] + +@[simp] +lemma atomRel_neg₄ (a b c d : ℤ) : atomRel W a b c (-d) = atomRel W a b c d := by + simp_rw [atomRel, atom_neg_right] + +variable {W} in +@[simp] +lemma atomRel_abs₁ (odd : W.Odd) (a b c d : ℤ) : atomRel W |a| b c d = atomRel W a b c d := by + simp_rw [atomRel, atom_abs_left odd] + +variable {W} in +@[simp] +lemma atomRel_abs₂ (odd : W.Odd) (a b c d : ℤ) : atomRel W a |b| c d = atomRel W a b c d := by + simp_rw [atomRel, atom_abs_left odd, atom_abs_right] + +variable {W} in +@[simp] +lemma atomRel_abs₃ (odd : W.Odd) (a b c d : ℤ) : atomRel W a b |c| d = atomRel W a b c d := by + simp_rw [atomRel, atom_abs_left odd, atom_abs_right] + +@[simp] +lemma atomRel_abs₄ (a b c d : ℤ) : atomRel W a b c |d| = atomRel W a b c d := by + simp_rw [atomRel, atom_abs_right] + +lemma atomRel_avg_sub {a b c d : ℤ} (parity : d % 2 = a % 2 ∧ d % 2 = b % 2 ∧ d % 2 = c % 2) : + atomRel W ((a + b + c + d) / 2 - d) ((a + b + c + d) / 2 - c) ((a + b + c + d) / 2 - b) + ((a + b + c + d) / 2 - a) = atomRel W a b c d := by + simp_rw [add_assoc <| a + b, atomRel, atom, sub_add_sub_comm, ← two_mul] + repeat rw [Int.mul_ediv_cancel'] <;> grind + +lemma map_atomRel (a b c d : ℤ) : f (atomRel W a b c d) = atomRel (f ∘ W) a b c d := by + simp_rw [atomRel, map_add, map_sub, map_mul, map_atom] + +/-- The elliptic relator `ER(p, q, r, s)` that defines an elliptic net. -/ +def rel (p q r s : ℤ) : R := + W (p + q + s) * W (p - q) * W (r + s) * W r - W (p + r + s) * W (p - r) * W (q + s) * W q + + W (q + r + s) * W (q - r) * W (p + s) * W p + +lemma rel_eq (p q r s : ℤ) : rel W p q r s = atomRel W (2 * p + s) (2 * q + s) (2 * r + s) s := by + simp_rw [rel, atomRel, atom, add_add_add_comm _ s, add_assoc _ s, ← two_mul, ← mul_add, + add_sub_add_comm, add_sub_assoc, sub_self, add_zero, ← mul_sub, + Int.mul_tdiv_cancel_left _ two_ne_zero, mul_comm <| _ * W p, mul_assoc] + +lemma atomRel_two_mul (a b c d : ℤ) : + atomRel W (2 * a) (2 * b) (2 * c) (2 * d) = rel W (a - d) (b - d) (c - d) (2 * d) := by + simp_rw [rel_eq, mul_sub, sub_add_cancel] + +lemma atomRel_eq {a b c d : ℤ} (parity : d % 2 = a % 2 ∧ d % 2 = b % 2 ∧ d % 2 = c % 2) : + atomRel W a b c d = rel W ((a - d) / 2) ((b - d) / 2) ((c - d) / 2) d := by + simp only [rel_eq, Int.mul_ediv_cancel', Int.ModEq.dvd parity.1, Int.ModEq.dvd parity.2.1, + Int.ModEq.dvd parity.2.2, sub_add_cancel] + +variable {W} in +@[simp] +lemma rel_neg (odd : W.Odd) (p q r s : ℤ) : rel W (-p) (-q) (-r) (-s) = rel W p q r s := by + simp_rw [rel_eq, mul_neg, ← neg_add, atomRel_neg₁ odd, atomRel_neg₂ odd, atomRel_neg₃ odd, + atomRel_neg₄] + +/-- The even elliptic relator `ER(m + 1, m - 1, 1, 0)` for `m ∈ ℤ`. -/ +lemma rel_even (m : ℤ) : rel W (m + 1) (m - 1) 1 0 = W (2 * m) * W 2 * W 1 ^ 2 - + W (m - 1) ^ 2 * W m * W (m + 2) + W (m - 2) * W m * W (m + 1) ^ 2 := by + rw [rel] + ring_nf + +/-- The odd elliptic relator `ER(m + 1, m, 1, 0)` for `m ∈ ℤ`. -/ +lemma rel_odd (m : ℤ) : rel W (m + 1) m 1 0 = + W (2 * m + 1) * W 1 ^ 3 - W (m + 2) * W m ^ 3 + W (m - 1) * W (m + 1) ^ 3 := by + rw [rel] + ring_nf + +lemma map_rel (p q r s : ℤ) : f (rel W p q r s) = rel (f ∘ W) p q r s := by + simp_rw [rel, map_add, map_sub, map_mul, Function.comp] + +end IsEllipticNet + +/-- The proposition that a sequence indexed by `ℤ` is an elliptic net. -/ +def IsEllipticNet : Prop := + ∀ p q r s : ℤ, IsEllipticNet.rel W p q r s = 0 + +/-- The proposition that a sequence indexed by `ℤ` is an elliptic sequence. -/ +def IsEllipticSequence : Prop := + ∀ p q r : ℤ, IsEllipticNet.rel W p q r 0 = 0 + +@[deprecated (since := "2026-07-01")] alias IsEllSequence := IsEllipticSequence + +/-- The proposition that a sequence indexed by `ℤ` is an EDS. -/ +def IsEllipticDvdSequence : Prop := + IsEllipticSequence W ∧ IsDvdSequence W + +@[deprecated (since := "2026-06-30")] alias IsEllDivSequence := IsEllipticDvdSequence + +namespace IsEllipticNet + +variable {W} + +lemma isEllipticSequence (h : IsEllipticNet W) : IsEllipticSequence W := + (h · · · 0) + +protected lemma id : IsEllipticNet (id : ℤ → ℤ) := + fun _ _ _ _ ↦ by simp_rw [rel, id_eq]; ring1 + +protected lemma smul (h : IsEllipticNet W) (x : R) : IsEllipticNet <| x • W := fun p q r s ↦ by + linear_combination (norm := (simp_rw [rel, Pi.smul_apply, smul_eq_mul]; ring1)) x ^ 4 * h p q r s + +end IsEllipticNet + +namespace IsEllipticSequence variable {W} -lemma IsEllSequence.smul (h : IsEllSequence W) (x : R) : IsEllSequence (x • W) := - fun m n r => by - linear_combination (norm := (simp_rw [Pi.smul_apply, smul_eq_mul]; ring1)) x ^ 4 * h m n r +protected lemma id : IsEllipticSequence (id : ℤ → ℤ) := + IsEllipticNet.id.isEllipticSequence -@[deprecated (since := "2026-06-30")] alias IsDivSequence.smul := IsDvdSequence.smul +protected lemma smul (h : IsEllipticSequence W) (x : R) : IsEllipticSequence <| x • W := + fun p q r ↦ by linear_combination (norm := (simp [IsEllipticNet.rel]; ring1)) x ^ 4 * h p q r -lemma IsEllDivSequence.smul (h : IsEllDivSequence W) (x : R) : IsEllDivSequence (x • W) := +end IsEllipticSequence + +@[deprecated (since := "2026-07-01")] alias isEllSequence_id := IsEllipticSequence.id +@[deprecated (since := "2026-07-01")] alias IsEllSequence.smul := IsEllipticSequence.smul + +namespace IsEllipticDvdSequence + +variable {W} + +/-- The identity sequence is an EDS. -/ +protected theorem id : IsEllipticDvdSequence (id : ℤ → ℤ) := + ⟨IsEllipticSequence.id, .id ℤ⟩ + +protected lemma smul (h : IsEllipticDvdSequence W) (x : R) : IsEllipticDvdSequence <| x • W := ⟨h.left.smul x, h.right.smul x⟩ -end IsEllDivSequence +end IsEllipticDvdSequence + +@[deprecated (since := "2026-06-30")] alias isEllDivSequence_id := IsEllipticDvdSequence.id +@[deprecated (since := "2026-06-30")] alias IsEllDivSequence.smul := IsEllipticDvdSequence.smul variable (b c d : R) @@ -236,7 +465,7 @@ lemma preNormEDS_odd (m : ℤ) : preNormEDS b c d (2 * m + 1) = ring1 /-- The 2-complement sequence `Wᶜ₂ : ℤ → R` for a normalised EDS `W : ℤ → R` that witnesses -`W(k) ∣ W(2 * k)`. In other words, `W(k) * Wᶜ₂(k) = W(2 * k)` for any `k ∈ ℤ`. +`W(k) ∣ W(2 * k)`. In other words, `W(k) * Wᶜ₂(k) = W(2 * k)` for all `k ∈ ℤ`. This is defined in terms of `preNormEDS`. -/ def complEDS₂ (k : ℤ) : R := @@ -351,7 +580,7 @@ Strong recursion principle for a normalised EDS: if we have then we have `P n` for all `n : ℕ`. -/ @[elab_as_elim] -noncomputable def normEDSRec' {P : ℕ → Sort u} +noncomputable def normEDSRec' {P : ℕ → Sort*} (zero : P 0) (one : P 1) (two : P 2) (three : P 3) (four : P 4) (even : ∀ m : ℕ, (∀ k < 2 * (m + 3), P k) → P (2 * (m + 3))) (odd : ∀ m : ℕ, (∀ k < 2 * (m + 2) + 1, P k) → P (2 * (m + 2) + 1)) (n : ℕ) : P n := @@ -367,13 +596,13 @@ noncomputable def normEDSRec' {P : ℕ → Sort u} then we have `P n` for all `n : ℕ`. -/ @[elab_as_elim] -noncomputable def normEDSRec {P : ℕ → Sort u} +noncomputable def normEDSRec {P : ℕ → Sort*} (zero : P 0) (one : P 1) (two : P 2) (three : P 3) (four : P 4) (even : ∀ m : ℕ, P (m + 1) → P (m + 2) → P (m + 3) → P (m + 4) → P (m + 5) → P (2 * (m + 3))) (odd : ∀ m : ℕ, P (m + 1) → P (m + 2) → P (m + 3) → P (m + 4) → P (2 * (m + 2) + 1)) (n : ℕ) : P n := - normEDSRec' zero one two three four (fun _ ih => by apply even <;> exact ih _ <| by linarith only) - (fun _ ih => by apply odd <;> exact ih _ <| by linarith only) n + normEDSRec' zero one two three four (fun _ ih ↦ by apply even <;> exact ih _ <| by linarith only) + (fun _ ih ↦ by apply odd <;> exact ih _ <| by linarith only) n end NormEDS @@ -382,7 +611,7 @@ section ComplEDS variable (k : ℤ) /-- The complement sequence `Wᶜ : ℤ × ℕ → R` for a normalised EDS `W : ℤ → R` that witnesses -`W(k) ∣ W(n * k)`. In other words, `W(k) * Wᶜ(k, n) = W(n * k)` for any `k, n ∈ ℤ`. +`W(k) ∣ W(n * k)`. In other words, `W(k) * Wᶜ(k, n) = W(n * k)` for all `k, n ∈ ℤ`. This is defined in terms of `normEDS` and agrees with `complEDS₂` when `n = 2`. -/ def complEDS' : ℕ → R @@ -417,7 +646,7 @@ lemma complEDS'_odd (m : ℕ) : complEDS' b c d k (2 * (m + 1) + 1) = simp [Nat.mul_add_div two_pos, add_assoc] /-- The complement sequence `Wᶜ : ℤ × ℤ → R` for a normalised EDS `W : ℤ → R` that witnesses -`W(k) ∣ W(n * k)`. In other words, `W(k) * Wᶜ(k, n) = W(n * k)` for any `k, n ∈ ℤ`. +`W(k) ∣ W(n * k)`. In other words, `W(k) * Wᶜ(k, n) = W(n * k)` for all `k, n ∈ ℤ`. This extends `complEDS'` by defining its values at negative integers. -/ def complEDS (n : ℤ) : R := @@ -475,7 +704,7 @@ lemma complEDS_odd (m : ℤ) : complEDS b c d k (2 * m + 1) = then we have `P n` for all `n : ℕ`. -/ @[elab_as_elim] -noncomputable def complEDSRec' {P : ℕ → Sort u} (zero : P 0) (one : P 1) +noncomputable def complEDSRec' {P : ℕ → Sort*} (zero : P 0) (one : P 1) (even : ∀ m : ℕ, (∀ k < 2 * (m + 1), P k) → P (2 * (m + 1))) (odd : ∀ m : ℕ, (∀ k < 2 * (m + 1) + 1, P k) → P (2 * (m + 1) + 1)) (n : ℕ) : P n := n.evenOddStrongRec (by rintro (_ | _) h; exacts [zero, even _ h]) @@ -490,18 +719,16 @@ noncomputable def complEDSRec' {P : ℕ → Sort u} (zero : P 0) (one : P 1) then we have `P n` for all `n : ℕ`. -/ @[elab_as_elim] -noncomputable def complEDSRec {P : ℕ → Sort u} (zero : P 0) (one : P 1) +noncomputable def complEDSRec {P : ℕ → Sort*} (zero : P 0) (one : P 1) (even : ∀ m : ℕ, P (m + 1) → P (2 * (m + 1))) (odd : ∀ m : ℕ, P (m + 1) → P (m + 2) → P (2 * (m + 1) + 1)) (n : ℕ) : P n := - complEDSRec' zero one (fun _ ih => even _ <| ih _ <| by linarith only) - (fun _ ih => odd _ (ih _ <| by linarith only) <| ih _ <| by linarith only) n + complEDSRec' zero one (fun _ ih ↦ even _ <| ih _ <| by linarith only) + (fun _ ih ↦ odd _ (ih _ <| by linarith only) <| ih _ <| by linarith only) n end ComplEDS section Map -variable {S : Type v} [CommRing S] (f : R →+* S) - @[simp] lemma map_preNormEDS' (n : ℕ) : f (preNormEDS' b c d n) = preNormEDS' (f b) (f c) (f d) n := by induction n using normEDSRec' with From b5dc78b96f3e39ad8f07179b42085920ef8e9add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hagb=20=28Junyu=20Guo=20=E9=83=AD=E4=BF=8A=E4=BD=99=29?= Date: Tue, 7 Jul 2026 11:00:16 +0000 Subject: [PATCH 0630/1300] feat(Order/WellQuasiOrder): `WellQuasiOrdered` if onto homomorphous from a `WellQuasiOrdered` relation (#39787) It is used in #39788 for proof of well foundedness of `MonomialOrder` when the index type is finite. The hypotheses can be further weaken once #38557 is merged. --- Mathlib/Order/WellQuasiOrder.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/Order/WellQuasiOrder.lean b/Mathlib/Order/WellQuasiOrder.lean index 38967d32b4c397..0d34ea4abd0651 100644 --- a/Mathlib/Order/WellQuasiOrder.lean +++ b/Mathlib/Order/WellQuasiOrder.lean @@ -113,6 +113,13 @@ theorem RelIso.wellQuasiOrdered_iff {α β} {r : α → α → Prop} {s : β → congr! with g a b simp [f.map_rel_iff] +theorem WellQuasiOrdered.of_surjective {α β} {r : α → α → Prop} + {s : β → β → Prop} (h : WellQuasiOrdered r) (f : r →r s) (hf : Function.Surjective f) : + WellQuasiOrdered s := by + intro seq + have ⟨_, _, hle, hr⟩ := h (Function.surjInv hf ∘ seq) + exact ⟨_, _, hle, by simpa [Function.surjInv_eq] using f.map_rel hr⟩ + /-- A typeclass for an order with a well-quasi-ordered `≤` relation. Note that this is unlike `WellFoundedLT`, which instead takes a `<` relation. -/ @@ -178,6 +185,16 @@ theorem wellQuasiOrderedLE_iff : instance [WellQuasiOrderedLE α] [Preorder β] [WellQuasiOrderedLE β] : WellQuasiOrderedLE (α × β) := ⟨wellQuasiOrdered_le.prod wellQuasiOrdered_le⟩ +theorem Monotone.wellQuasiOrderedLE_of_wellQuasiOrderedLE_of_surjective [Preorder β] + [WellQuasiOrderedLE α] {f : α → β} (mono : Monotone f) (hf : Function.Surjective f) : + WellQuasiOrderedLE β := + ⟨wellQuasiOrdered_le.of_surjective ⟨_, (mono ·)⟩ hf⟩ + +theorem OrderHom.wellQuasiOrderedLE_of_wellQuasiOrderedLE_of_surjective [Preorder β] + [WellQuasiOrderedLE α] (f : α →o β) (hf : Function.Surjective f) : + WellQuasiOrderedLE β := + f.monotone.wellQuasiOrderedLE_of_wellQuasiOrderedLE_of_surjective hf + end Preorder section LinearOrder From ba682b5eeafffc3de11f10b5f85007d44b032ed2 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Tue, 7 Jul 2026 11:49:22 +0000 Subject: [PATCH 0631/1300] feat(Matrix/SemiringInverse): new lemmas about `detp` and `adjp` (#40875) Co-authored-by: Aristotle (Harmonic) [aristotle-harmonic@harmonic.fun](mailto:aristotle-harmonic@harmonic.fun) --- Mathlib/GroupTheory/Perm/Sign.lean | 8 ++ .../LinearAlgebra/Matrix/SemiringInverse.lean | 117 ++++++++++++++---- 2 files changed, 98 insertions(+), 27 deletions(-) diff --git a/Mathlib/GroupTheory/Perm/Sign.lean b/Mathlib/GroupTheory/Perm/Sign.lean index 97dd66422ff38b..b2c418962507f7 100644 --- a/Mathlib/GroupTheory/Perm/Sign.lean +++ b/Mathlib/GroupTheory/Perm/Sign.lean @@ -551,6 +551,14 @@ theorem sign_prodCongrLeft (σ : α → Perm β) : sign (prodCongrLeft σ) = ∏ theorem sign_permCongr (e : α ≃ β) (p : Perm α) : sign (e.permCongr p) = sign p := sign_eq_sign_of_equiv _ _ e.symm (by simp) +@[simp] theorem sign_trans_trans (f : β ≃ α) (p : Perm α) (g : α ≃ β) : + sign (f.trans (p.trans g)) = sign p * sign (f.trans g) := by + rw [← sign_permCongr g, ← sign_mul]; congr; ext; simp + +@[simp] theorem sign_equivCongr (f g : α ≃ β) (p : Perm α) : + sign (f.equivCongr g p) = sign p * sign (f.symm.trans g) := + sign_trans_trans .. + @[simp] theorem sign_sumCongr (σa : Perm α) (σb : Perm β) : sign (sumCongr σa σb) = sign σa * sign σb := by suffices sign (sumCongr σa (1 : Perm β)) = sign σa ∧ sign (sumCongr (1 : Perm α) σb) = sign σb diff --git a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean index 70a23cc12f3139..aeb9537a349ff2 100644 --- a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean @@ -10,6 +10,7 @@ public import Mathlib.Data.Matrix.Mul public import Mathlib.GroupTheory.Perm.Sign import Mathlib.Algebra.Module.End +import Mathlib.GroupTheory.Perm.Option /-! # Nonsingular inverses over semirings @@ -28,9 +29,13 @@ variable (s : ℤˣ) (A B : Matrix n n R) (i j : n) namespace Matrix -/-- The determinant, but only the terms of a given sign. -/ +/-- The determinant, but only the terms of a given sign. +`A.detp 1` is written `|A|⁺` in the literature and `A.detp (-1)` is written `|A|⁻`. -/ def detp : R := ∑ σ ∈ ofSign s, ∏ k, A k (σ k) +@[simp] lemma detp_transpose : A.transpose.detp s = A.detp s := + sum_equiv (.inv _) (by simp) fun σ _ ↦ prod_equiv σ (by simp) (by simp) + @[simp] lemma detp_one_diagonal (d : n → R) : detp 1 (diagonal d) = ∏ i, d i := by rw [detp, sum_eq_single_of_mem 1] @@ -59,6 +64,42 @@ lemma detp_neg_one_diagonal (d : n → R) : detp (-1) (diagonal d) = 0 := by lemma detp_neg_one_one : detp (-1) (1 : Matrix n n R) = 0 := by rw [← diagonal_one, detp_neg_one_diagonal] +@[simp] lemma detp_one_of_isEmpty [IsEmpty n] : A.detp 1 = 1 := by + rw [detp, sum_unique_nonempty _ _ ⟨1, _⟩] <;> simp + +@[simp] lemma detp_neg_one_of_isEmpty [IsEmpty n] : A.detp (-1) = 0 := by + rw [detp, ofSign, univ_unique] + convert sum_empty + simp +decide + +@[simp] lemma detp_submatrix_equiv_equiv (f g : m ≃ n) : + (A.submatrix f g).detp s = A.detp (s * sign (f.symm.trans g)) := + sum_equiv (equivCongr f g) (by simp) fun _ _ ↦ prod_equiv f (by simp) fun _ _ ↦ by simp + +lemma detp_submatrix_equiv_self (e : m ≃ n) : (A.submatrix e e).detp s = A.detp s := by + simp + +variable {A} + +lemma detp_eq_of_row_eq {p q : n} (hpq : p ≠ q) (hrow : A.row p = A.row q) + (s : ℤˣ := 1) (t : ℤˣ := -1) : A.detp s = A.detp t := by + have : A.detp 1 = A.detp (-1) := sum_equiv (.mulRight <| swap p q) (by simp [hpq]) + fun _ _ ↦ prod_equiv (swap p q) (by simp) (by aesop (add simp row)) + obtain rfl | rfl := Int.units_eq_one_or s <;> obtain rfl | rfl := Int.units_eq_one_or t <;> + first | rfl | rw [this] + +lemma detp_eq_of_col_eq {p q : n} (hpq : p ≠ q) (hcol : A.col p = A.col q) + (s : ℤˣ := 1) (t : ℤˣ := -1) : A.detp s = A.detp t := by + simpa using detp_eq_of_row_eq (A := Aᵀ) hpq hcol s t + +lemma detp_eq_of_row_eq_zero {p : n} (hrow : A.row p = 0) : A.detp s = 0 := + sum_eq_zero fun _ _ ↦ prod_eq_zero (mem_univ p) congr($hrow _) + +lemma detp_eq_of_col_eq_zero {p : n} (hcol : A.col p = 0) : A.detp s = 0 := by + simpa using detp_eq_of_row_eq_zero (A := Aᵀ) s hcol + +variable (A) + /-- The adjugate matrix, but only the terms of a given sign. -/ def adjp : Matrix n n R := of fun i j ↦ ∑ σ ∈ (ofSign s).filter (· j = i), ∏ k ∈ {j}ᶜ, A k (σ k) @@ -67,6 +108,34 @@ lemma adjp_apply (i j : n) : adjp s A i j = ∑ σ ∈ (ofSign s).filter (· j = i), ∏ k ∈ {j}ᶜ, A k (σ k) := rfl +lemma adjp_transpose : A.transpose.adjp s = (A.adjp s).transpose := + ext fun _ _ ↦ sum_equiv (.inv _) (by aesop) fun σ hσ ↦ prod_equiv σ (by aesop) (by simp) + +private lemma adjp_none_right (A : Matrix (Option n) (Option n) R) (i : Option n) : + A.adjp s i none = (A.submatrix some <| swap none i ∘ some).detp (sign (swap none i) * s) := by + rw [adjp, of_apply, detp] + convert sum_image (g := fun σ ↦ decomposeOption.symm (i, σ)) + ((Equiv.injective _).comp (Prod.mk_right_injective i)).injOn + · ext σ; simp only [mem_filter, mem_ofSign, mem_image] + exact ⟨fun _ ↦ ⟨σ.removeNone, by rw [← optionCongr_sign]; aesop⟩, by aesop⟩ + convert (prod_image (Option.some_injective n).injOn).symm + · rfl + · apply SetLike.coe_injective; simp [← Set.compl_range_some] + +lemma adjp_none_none (A : Matrix (Option n) (Option n) R) : + A.adjp s none none = (A.submatrix some some).detp s := by + simp [adjp_none_right] + +lemma adjp_some_none (A : Matrix (Option n) (Option n) R) : + A.adjp s (some i) none = (A.submatrix some (Function.update some i none)).detp (-s) := by + rw [adjp_none_right]; congr + · simp + · ext1; aesop + +lemma adjp_none_some (A : Matrix (Option n) (Option n) R) : + A.adjp s none (some i) = (A.submatrix (Function.update some i none) some).detp (-s) := by + rw [← detp_transpose]; simp [← A.transpose.adjp_some_none, adjp_transpose] + theorem detp_mul : detp 1 (A * B) + (detp 1 A * detp (-1) B + detp (-1) A * detp 1 B) = detp (-1) (A * B) + (detp 1 A * detp 1 B + detp (-1) A * detp (-1) B) := by @@ -115,32 +184,19 @@ theorem mul_adjp_apply_eq : (A * adjp s A) i i = detp s A := by rw [← prod_mul_prod_compl ({i} : Finset n), prod_singleton, (mem_filter.mp hσ).2] theorem mul_adjp_apply_ne (h : i ≠ j) : (A * adjp 1 A) i j = (A * adjp (-1) A) i j := by - simp_rw [mul_apply, adjp_apply, mul_sum, sum_sigma'] - let f : (Σ x : n, Perm n) → (Σ x : n, Perm n) := fun ⟨x, σ⟩ ↦ ⟨σ i, σ * swap i j⟩ - let t s : Finset (Σ x : n, Perm n) := univ.sigma fun x ↦ (ofSign s).filter fun σ ↦ σ j = x - have hf {s} : ∀ p ∈ t s, f (f p) = p := by - intro ⟨x, σ⟩ hp - rw [mem_sigma, mem_filter, mem_ofSign] at hp - simp_rw [f, Perm.mul_apply, swap_apply_left, hp.2.2, mul_swap_mul_self] - refine sum_bij' (fun p _ ↦ f p) (fun p _ ↦ f p) ?_ ?_ hf hf ?_ - · intro ⟨x, σ⟩ hp - rw [mem_sigma, mem_filter, mem_ofSign] at hp ⊢ - rw [Perm.mul_apply, sign_mul, hp.2.1, sign_swap h, swap_apply_right] - exact ⟨mem_univ (σ i), rfl, rfl⟩ - · intro ⟨x, σ⟩ hp - rw [mem_sigma, mem_filter, mem_ofSign] at hp ⊢ - rw [Perm.mul_apply, sign_mul, hp.2.1, sign_swap h, swap_apply_right] - exact ⟨mem_univ (σ i), rfl, rfl⟩ - · intro ⟨x, σ⟩ hp - rw [mem_sigma, mem_filter, mem_ofSign] at hp - have key : ({j}ᶜ : Finset n) = disjUnion ({i} : Finset n) ({i, j} : Finset n)ᶜ (by simp) := by - rw [singleton_disjUnion, cons_eq_insert, compl_insert, insert_erase] - rwa [mem_compl, mem_singleton] - simp_rw [key, prod_disjUnion, prod_singleton, f, Perm.mul_apply, swap_apply_left, ← mul_assoc] - rw [mul_comm (A i x) (A i (σ i)), hp.2.2] - refine congr_arg _ (prod_congr rfl fun x hx ↦ ?_) - rw [mem_compl, mem_insert, mem_singleton, not_or] at hx - rw [swap_apply_of_ne_of_ne hx.1 hx.2] + let A' : Matrix n n R := of <| Function.update A j (A i) + have h' s : (A * adjp s A) i j = (A' * adjp s A') j j := sum_congr rfl fun _ _ ↦ + congr_arg₂ (· * ·) (by simp [A']) <| sum_congr rfl fun σ hσ ↦ prod_congr rfl fun _ _ ↦ by aesop + simp_rw [h', mul_adjp_apply_eq] + apply detp_eq_of_row_eq h + simp [A', h] + +theorem adjp_mul_apply_eq : (adjp s A * A) i i = detp s A := by + rw [← detp_transpose, ← mul_adjp_apply_eq _ _ i, adjp_transpose, ← transpose_mul, transpose_apply] + +theorem adjp_mul_apply_ne (h : i ≠ j) : (adjp 1 A * A) i j = (adjp (-1) A * A) i j := by + simp_rw [← transpose_apply (_ * _) j i, transpose_mul, + ← adjp_transpose, mul_adjp_apply_ne _ _ _ h.symm] theorem mul_adjp_add_detp : A * adjp 1 A + detp (-1) A • 1 = A * adjp (-1) A + detp 1 A • 1 := by ext i j @@ -148,6 +204,13 @@ theorem mul_adjp_add_detp : A * adjp 1 A + detp (-1) A • 1 = A * adjp (-1) A + · simp_rw [mul_adjp_apply_eq, one_apply_eq, mul_one, add_comm] · simp_rw [mul_adjp_apply_ne A i j h, one_apply_ne h, mul_zero] +/-- Laplace expansion of `detp` along the `none` row of an `Option`-indexed matrix. -/ +lemma detp_option_expand_row_none (A : Matrix (Option n) (Option n) R) : + A.detp s = A none none * (A.submatrix some some).detp s + + ∑ k : n, A none (some k) * (A.submatrix some (Function.update some k none)).detp (-s) := by + simp_rw [← A.mul_adjp_apply_eq s none, mul_apply, + Fintype.sum_option, adjp_none_none, adjp_some_none] + variable {A B} theorem isAddUnit_mul {d : n → R} (hAB : A * B = diagonal d) (i j k : n) (hij : i ≠ j) : From f4acc68084bf13dc6845a15176feab667477113b Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2026 13:01:40 +0000 Subject: [PATCH 0632/1300] chore(GroupTheory/FreeGroup/Basic): automated extraction from #38114 (#41441) This PR was automatically created from PR #38114 by @javgomzar via a [review comment](https://github.com/leanprover-community/mathlib4/pull/38114#discussion_r3535970012) by @tb65536. Co-authored-by: javgomzar <51706873+javgomzar@users.noreply.github.com> --- Mathlib/GroupTheory/FreeGroup/Basic.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 4fdc5d6b3b1b88..1596a9dac2f92d 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -729,6 +729,11 @@ theorem closure_range_of (α) : rw [← range_lift_eq_closure, lift_of_eq_id] exact MonoidHom.range_eq_top.2 Function.surjective_id +@[to_additive] +theorem lift_surjective_of_surjective (hf : Function.Surjective f) : + Function.Surjective (lift f) := by + rw [← MonoidHom.range_eq_top, range_lift_eq_closure, hf.range_eq, Subgroup.closure_univ] + end lift section Map @@ -865,6 +870,10 @@ theorem prod.of {x : α} : prod (of x) = x := theorem prod.unique (g : FreeGroup α →* α) (hg : ∀ x, g (FreeGroup.of x) = x) {x} : g x = prod x := lift_unique g hg +@[to_additive] +theorem prod_surjective : Function.Surjective (prod : FreeGroup α →* α) := + FreeGroup.lift_surjective_of_surjective Function.surjective_id + end Prod @[to_additive] From f0630767e52e1d946d29404a58982ed74d6f04c5 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Tue, 7 Jul 2026 13:32:41 +0000 Subject: [PATCH 0633/1300] feat(CategoryTheory/EpiMono): add cube lemma (#41046) This is another upstreaming PR originated from the [CFT](https://github.com/kbuzzard/ClassFieldTheory) repo, it's a collaborative work from 2025 Clay Summer School on Formalizing Class Field Theory. --- Mathlib/CategoryTheory/EpiMono.lean | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Mathlib/CategoryTheory/EpiMono.lean b/Mathlib/CategoryTheory/EpiMono.lean index 9fcd9c470107df..57c915cda31949 100644 --- a/Mathlib/CategoryTheory/EpiMono.lean +++ b/Mathlib/CategoryTheory/EpiMono.lean @@ -6,6 +6,7 @@ Authors: Reid Barton, Kim Morrison module public import Mathlib.CategoryTheory.Groupoid +public import Mathlib.CategoryTheory.CommSq /-! # Facts about epimorphisms and monomorphisms. @@ -236,4 +237,44 @@ instance [IsSplitMono f] : IsSplitEpi f.op := end Opposite + +section cubeLemma + +variable {M000 M001 M010 M011 M100 M101 M110 M111 : C} + (f00x : M000 ⟶ M001) (f01x : M010 ⟶ M011) (f10x : M100 ⟶ M101) (f11x : M110 ⟶ M111) + (f0x0 : M000 ⟶ M010) (f0x1 : M001 ⟶ M011) (f1x0 : M100 ⟶ M110) (f1x1 : M101 ⟶ M111) + (fx00 : M000 ⟶ M100) (fx01 : M001 ⟶ M101) (fx10 : M010 ⟶ M110) (fx11 : M011 ⟶ M111) + +/-- This is a theorem saying if five faces of a cube commute and one edge is an epimorphism, + then the sixth face must also commute. -/ +theorem cube_lemma_of_epi (h0xx : f0x0 ≫ f01x = f00x ≫ f0x1) (h1xx : f1x0 ≫ f11x = f10x ≫ f1x1) + (hx0x : fx00 ≫ f10x = f00x ≫ fx01) (hx1x : fx10 ≫ f11x = f01x ≫ fx11) + (hxx0 : f0x0 ≫ fx10 = fx00 ≫ f1x0) [Epi f00x] : f0x1 ≫ fx11 = fx01 ≫ f1x1 := by + rw [← cancel_epi f00x] + grind + +/-- This is a theorem saying if five faces of a cube commute and one edge is a monomorphism, + then the sixth face must also commute. -/ +theorem cube_lemma_of_mono (h0xx : f0x0 ≫ f01x = f00x ≫ f0x1) (h1xx : f1x0 ≫ f11x = f10x ≫ f1x1) + (hx0x : fx00 ≫ f10x = f00x ≫ fx01) (hx1x : fx10 ≫ f11x = f01x ≫ fx11) + (hxx1 : f0x1 ≫ fx11 = fx01 ≫ f1x1) [Mono f11x] : f0x0 ≫ fx10 = fx00 ≫ f1x0 := by + rw [← cancel_mono f11x] + grind + +theorem CommSq.cube_lemma_of_epi (h0xx : CommSq f0x0 f00x f01x f0x1) + (h1xx : CommSq f1x0 f10x f11x f1x1) (hx0x : CommSq fx00 f00x f10x fx01) + (hx1x : CommSq fx10 f01x f11x fx11) (hxx0 : CommSq f0x0 fx00 fx10 f1x0) [Epi f00x] : + CommSq f0x1 fx01 fx11 f1x1 := + ⟨CategoryTheory.cube_lemma_of_epi f00x f01x f10x f11x + f0x0 f0x1 f1x0 f1x1 fx00 fx01 fx10 fx11 h0xx.w h1xx.w hx0x.w hx1x.w hxx0.w⟩ + +theorem CommSq.cube_lemma_of_mono (h0xx : CommSq f0x0 f00x f01x f0x1) + (h1xx : CommSq f1x0 f10x f11x f1x1) (hx0x : CommSq fx00 f00x f10x fx01) + (hx1x : CommSq fx10 f01x f11x fx11) (hxx1 : CommSq f0x1 fx01 fx11 f1x1) [Mono f11x] : + CommSq f0x0 fx00 fx10 f1x0 := + ⟨CategoryTheory.cube_lemma_of_mono f00x f01x f10x f11x + f0x0 f0x1 f1x0 f1x1 fx00 fx01 fx10 fx11 h0xx.w h1xx.w hx0x.w hx1x.w hxx1.w⟩ + +end cubeLemma + end CategoryTheory From 308db4b77766a1bf5aab4d678307978add6ab39a Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:13:07 +0000 Subject: [PATCH 0634/1300] chore: localise use of the `backward.privateInPublic` option more (#41410) Or comment on the existing unscoped usage. Similar to #41407, revealed by #41409. --- Mathlib/Combinatorics/Matroid/Basic.lean | 2 ++ Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean | 2 ++ Mathlib/NumberTheory/NumberField/House.lean | 7 ++++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Mathlib/Combinatorics/Matroid/Basic.lean b/Mathlib/Combinatorics/Matroid/Basic.lean index b0f254be394168..00acd4dc34c9d2 100644 --- a/Mathlib/Combinatorics/Matroid/Basic.lean +++ b/Mathlib/Combinatorics/Matroid/Basic.lean @@ -323,6 +323,8 @@ end exchange section aesop +-- This is necessary as `aesop` uses private lemmas for its proof terms: without this option, +-- the aesop proofs will not work, and any `aesop` auto-params will not fire. set_option backward.privateInPublic true /-- The `aesop_mat` tactic attempts to prove a set is contained in the ground set of a matroid. diff --git a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean index b466522103763e..501714b52998c2 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean @@ -497,6 +497,8 @@ section FastJacobi We follow the implementation as in `Mathlib/Tactic/NormNum/LegendreSymbol.lean`. -/ +-- `fastLegendreSym` is used for computing the Legendre symbol in a `norm_num` extension, +-- i.e. needs to be used publicly. set_option backward.privateInPublic true open NumberTheorySymbols jacobiSym diff --git a/Mathlib/NumberTheory/NumberField/House.lean b/Mathlib/NumberTheory/NumberField/House.lean index 7c54a42afb9a35..509517939b2428 100644 --- a/Mathlib/NumberTheory/NumberField/House.lean +++ b/Mathlib/NumberTheory/NumberField/House.lean @@ -176,9 +176,7 @@ variable {α : Type*} {β : Type*} (a : Matrix α β (𝓞 K)) private def a' : α → β → (K →+* ℂ) → (K →+* ℂ) → ℤ := fun k l r => (newBasis K).repr (a k l * (newBasis K) r) - -set_option backward.privateInPublic true - +set_option backward.privateInPublic true in /-- `asiegel K a` is the integer matrix of the coefficients of the product of matrix elements and basis vectors. -/ private def asiegel : Matrix (α × (K →+* ℂ)) (β × (K →+* ℂ)) ℤ := fun k l => a' K a k.1 l.1 l.2 k.2 @@ -210,6 +208,7 @@ variable {p q : ℕ} (h0p : 0 < p) (hpq : p < q) (x : β × (K →+* ℂ) → /-- `ξ` is the product of `x (l, r)` and the `r`-th basis element of the newBasis of `K`. -/ private def ξ : β → 𝓞 K := fun l => ∑ r : K →+* ℂ, x (l, r) * (newBasis K r) +set_option backward.privateInPublic true in include hxl in private theorem ξ_ne_0 : ξ K x ≠ 0 := by intro H @@ -224,6 +223,8 @@ private theorem lin_1 (l k r) : a k l * (newBasis K) r = ∑ u, (a' K a k l r u) * (newBasis K) u := by simp only [Basis.sum_repr (newBasis K) (a k l * (newBasis K) r), a', ← zsmul_eq_mul] +-- Variable declarations can only reference public items. +set_option backward.privateInPublic true variable [Fintype β] (cardβ : Fintype.card β = q) (hmulvec0 : asiegel K a *ᵥ x = 0) include hxl hmulvec0 in From 72e1caf8d87ba867b6cb87742c71832a9a298eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:28:18 +0000 Subject: [PATCH 0635/1300] fix(Tactic/FunProp): resolve names to be unfolded (#41370) This allows using `fun_prop [c]` when `c` is in an open namespace. Additionally, an error is now thrown when a given constant does not exist. --- Mathlib/Tactic/FunProp/Elab.lean | 8 +++++--- MathlibTest/FunPropMinimal.lean | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Tactic/FunProp/Elab.lean b/Mathlib/Tactic/FunProp/Elab.lean index e272838b828d24..c941602cd21102 100644 --- a/Mathlib/Tactic/FunProp/Elab.lean +++ b/Mathlib/Tactic/FunProp/Elab.lean @@ -8,6 +8,8 @@ module public meta import Lean.Elab.Tactic.Config public import Mathlib.Tactic.FunProp.Core +import Lean.Elab.InfoTree.Main + /-! ## `funProp` tactic syntax -/ @@ -93,10 +95,10 @@ def funPropTac : Tactic pure <| tacticToDischarge (← `(tactic| first | with_reducible assumption | ($tac))) | _ => pure assumptionDischarge - let namesToUnfold : Array Name := + let namesToUnfold ← show CoreM (Array Name) from match names with - | none => #[] - | some ns => ns.getElems.map (fun n => n.getId) + | none => pure #[] + | some ns => ns.getElems.mapM Elab.realizeGlobalConstNoOverloadWithInfo let namesToUnfold := namesToUnfold.append defaultNamesToUnfold diff --git a/MathlibTest/FunPropMinimal.lean b/MathlibTest/FunPropMinimal.lean index 2569a6cf13e07e..716799e4c4e3ba 100644 --- a/MathlibTest/FunPropMinimal.lean +++ b/MathlibTest/FunPropMinimal.lean @@ -375,8 +375,10 @@ def foo3 [Add α] (x : α) := x + x example [Add α] : Con (fun x : α => foo3 x) := by fun_prop [foo3] def myUncurry (f : α → β → γ) : α×β → γ := fun (x,y) => f x y -def diag (f : α → α → α) (x : α) := f x x +-- Namespaced to test that names are resolved +def MyNamespace.diag (f : α → α → α) (x : α) := f x x +open MyNamespace in theorem diag_Con (f : α → α → α) (hf : Con (myUncurry f)) : Con (fun x => diag f x) := by fun_prop [diag, myUncurry] From a92c9866e503f6f721307ff001939461cfba9ccd Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:28:20 +0000 Subject: [PATCH 0636/1300] =?UTF-8?q?feat(Order/SuccPred):=20`succ=20a=20?= =?UTF-8?q?=E2=89=A4=20b=20=E2=86=94=20a=20<=20b`=20when=20`b`=20is=20not?= =?UTF-8?q?=20maximal=20(#41371)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is `succ_le_iff_of_not_isMax'` (the unprimed version takes `IsMax a` instead). Also adds a `LinearOrder` version with the negated inequalities, versions for `SuccAddOrder`, and golfs the matching `ENat` theorems with those. --- Mathlib/Algebra/Order/SuccPred.lean | 6 ++++++ Mathlib/Data/ENat/Basic.lean | 17 +++++++---------- Mathlib/Order/SuccPred/Basic.lean | 22 +++++++++++++++++----- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Mathlib/Algebra/Order/SuccPred.lean b/Mathlib/Algebra/Order/SuccPred.lean index 7ea24dde4fa4e9..2bfe65cdd75e55 100644 --- a/Mathlib/Algebra/Order/SuccPred.lean +++ b/Mathlib/Algebra/Order/SuccPred.lean @@ -53,6 +53,9 @@ theorem add_one_le_of_lt (h : x < y) : x + 1 ≤ y := by theorem add_one_le_iff_of_not_isMax (hx : ¬ IsMax x) : x + 1 ≤ y ↔ x < y := by rw [← succ_eq_add_one, succ_le_iff_of_not_isMax hx] +theorem add_one_le_iff_of_not_isMax' (hy : ¬ IsMax y) : x + 1 ≤ y ↔ x < y := by + rw [← succ_eq_add_one, succ_le_iff_of_not_isMax' hy] + @[simp] theorem add_one_le_iff [NoMaxOrder α] : x + 1 ≤ y ↔ x < y := add_one_le_iff_of_not_isMax (not_isMax x) @@ -231,6 +234,9 @@ theorem le_of_lt_add_one (h : x < y + 1) : x ≤ y := by theorem lt_add_one_iff_of_not_isMax (hy : ¬ IsMax y) : x < y + 1 ↔ x ≤ y := by rw [← succ_eq_add_one, lt_succ_iff_of_not_isMax hy] +theorem lt_add_one_iff_of_not_isMax' (hx : ¬ IsMax x) : x < y + 1 ↔ x ≤ y := by + rw [← succ_eq_add_one, lt_succ_iff_of_not_isMax' hx] + @[simp] theorem lt_add_one_iff [NoMaxOrder α] : x < y + 1 ↔ x ≤ y := lt_add_one_iff_of_not_isMax (not_isMax y) diff --git a/Mathlib/Data/ENat/Basic.lean b/Mathlib/Data/ENat/Basic.lean index 8cd81bf0818142..79e7d1ee94dba5 100644 --- a/Mathlib/Data/ENat/Basic.lean +++ b/Mathlib/Data/ENat/Basic.lean @@ -282,10 +282,8 @@ theorem succ_def (m : ℕ∞) : Order.succ m = m + 1 := theorem add_one_le_iff (hm : m ≠ ⊤) : m + 1 ≤ n ↔ m < n := Order.add_one_le_iff_of_not_isMax (not_isMax_iff_ne_top.mpr hm) -theorem add_one_le_iff' (hn : n ≠ ⊤) : m + 1 ≤ n ↔ m < n := by - rcases eq_or_ne m ⊤ with rfl | hm - · simpa - · exact add_one_le_iff hm +theorem add_one_le_iff' (hn : n ≠ ⊤) : m + 1 ≤ n ↔ m < n := + Order.add_one_le_iff_of_not_isMax' (not_isMax_iff_ne_top.mpr hn) @[deprecated Order.one_le_iff_ne_zero (since := "2026-05-25")] protected theorem one_le_iff_ne_zero : 1 ≤ n ↔ n ≠ 0 := @@ -299,8 +297,11 @@ lemma lt_one_iff_eq_zero : n < 1 ↔ n = 0 := lemma le_one_iff_eq_zero_or_eq_one : n ≤ 1 ↔ n = 0 ∨ n = 1 := Order.le_one_iff -theorem lt_add_one_iff (hm : n ≠ ⊤) : m < n + 1 ↔ m ≤ n := - Order.lt_add_one_iff_of_not_isMax (not_isMax_iff_ne_top.mpr hm) +theorem lt_add_one_iff (hn : n ≠ ⊤) : m < n + 1 ↔ m ≤ n := + Order.lt_add_one_iff_of_not_isMax (not_isMax_iff_ne_top.mpr hn) + +theorem lt_add_one_iff' (hm : m ≠ ⊤) : m < n + 1 ↔ m ≤ n := + Order.lt_add_one_iff_of_not_isMax' (not_isMax_iff_ne_top.mpr hm) @[simp] theorem lt_two_iff : n < 2 ↔ n ≤ 1 := by @@ -314,10 +315,6 @@ theorem add_le_add_iff_right {m n k : ENat} (h : k ≠ ⊤) : n + k ≤ m + k ↔ n ≤ m := WithTop.add_le_add_iff_right h -theorem lt_add_one_iff' {m n : ENat} (hm : m ≠ ⊤) : - m < n + 1 ↔ m ≤ n := by - rw [← add_one_le_iff hm, add_le_add_iff_right one_ne_top] - theorem lt_coe_add_one_iff {m : ℕ∞} {n : ℕ} : m < n + 1 ↔ m ≤ n := lt_add_one_iff (coe_ne_top n) diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index b6947eeac6659e..22ecaf6f743fb5 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -186,6 +186,12 @@ theorem lt_succ_of_le_of_not_isMax (hab : b ≤ a) (ha : ¬IsMax a) : b < succ a theorem succ_le_iff_of_not_isMax (ha : ¬IsMax a) : succ a ≤ b ↔ a < b := ⟨(lt_succ_of_not_isMax ha).trans_le, succ_le_of_lt⟩ +@[to_dual le_pred_iff_of_not_isMin'] +theorem succ_le_iff_of_not_isMax' (hb : ¬IsMax b) : succ a ≤ b ↔ a < b := by + by_cases ha : IsMax a + · grind [le_succ, IsMax.mono] + · exact succ_le_iff_of_not_isMax ha + @[to_dual] lemma succ_lt_succ_of_not_isMax (h : a < b) (hb : ¬ IsMax b) : succ a < succ b := lt_succ_of_le_of_not_isMax (succ_le_of_lt h) hb @@ -417,13 +423,19 @@ variable [LinearOrder α] [SuccOrder α] {a b : α} @[to_dual] lemma succ_min (a b : α) : succ (min a b) = min (succ a) (succ b) := succ_mono.map_min @[to_dual le_of_pred_lt] -theorem le_of_lt_succ {a b : α} : a < succ b → a ≤ b := fun h ↦ by - by_contra! nh - exact (h.trans_le (succ_le_of_lt nh)).false +theorem le_of_lt_succ {a b : α} : a < succ b → a ≤ b := by + contrapose! + exact succ_le_of_lt @[to_dual pred_lt_iff_of_not_isMin] -theorem lt_succ_iff_of_not_isMax (ha : ¬IsMax a) : b < succ a ↔ b ≤ a := - ⟨le_of_lt_succ, fun h => h.trans_lt <| lt_succ_of_not_isMax ha⟩ +theorem lt_succ_iff_of_not_isMax (ha : ¬IsMax a) : b < succ a ↔ b ≤ a := by + contrapose! + exact succ_le_iff_of_not_isMax ha + +@[to_dual pred_lt_iff_of_not_isMin'] +theorem lt_succ_iff_of_not_isMax' (hb : ¬IsMax b) : b < succ a ↔ b ≤ a := by + contrapose! + exact succ_le_iff_of_not_isMax' hb @[to_dual (reorder := ha hb)] theorem succ_lt_succ_iff_of_not_isMax (ha : ¬IsMax a) (hb : ¬IsMax b) : From 6f604786851f312da512a988fd54eee4ca35dcf9 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:28:22 +0000 Subject: [PATCH 0637/1300] =?UTF-8?q?feat(Data/ENat/Basic):=20coe=20versio?= =?UTF-8?q?ns=20of=20`m=20+=201=20=E2=89=A4=20n=20=E2=86=94=20m=20<=20n`?= =?UTF-8?q?=20(#41372)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Nat.cast` specializations of `add_one_le_iff`/`add_one_le_iff'`/`lt_add_one_iff'` (the `lt_add_one_iff` version already exists). These are helpful with `simp`-like tactics which don't like the `≠ ⊤` side condition. --- Mathlib/Data/ENat/Basic.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Data/ENat/Basic.lean b/Mathlib/Data/ENat/Basic.lean index 79e7d1ee94dba5..ba7945bc7626cd 100644 --- a/Mathlib/Data/ENat/Basic.lean +++ b/Mathlib/Data/ENat/Basic.lean @@ -285,6 +285,12 @@ theorem add_one_le_iff (hm : m ≠ ⊤) : m + 1 ≤ n ↔ m < n := theorem add_one_le_iff' (hn : n ≠ ⊤) : m + 1 ≤ n ↔ m < n := Order.add_one_le_iff_of_not_isMax' (not_isMax_iff_ne_top.mpr hn) +theorem coe_add_one_le_iff {m : ℕ} {n : ℕ∞} : m + 1 ≤ n ↔ m < n := + add_one_le_iff <| coe_ne_top m + +theorem add_one_le_coe_iff {m : ℕ∞} {n : ℕ} : m + 1 ≤ n ↔ m < n := + add_one_le_iff' <| coe_ne_top n + @[deprecated Order.one_le_iff_ne_zero (since := "2026-05-25")] protected theorem one_le_iff_ne_zero : 1 ≤ n ↔ n ≠ 0 := Order.one_le_iff_ne_zero @@ -318,6 +324,9 @@ theorem add_le_add_iff_right {m n k : ENat} (h : k ≠ ⊤) : theorem lt_coe_add_one_iff {m : ℕ∞} {n : ℕ} : m < n + 1 ↔ m ≤ n := lt_add_one_iff (coe_ne_top n) +theorem coe_lt_add_one_iff {m : ℕ} {n : ℕ∞} : m < n + 1 ↔ m ≤ n := + lt_add_one_iff' (coe_ne_top m) + theorem le_coe_iff {n : ℕ∞} {k : ℕ} : n ≤ ↑k ↔ ∃ (n₀ : ℕ), n = n₀ ∧ n₀ ≤ k := WithTop.le_coe_iff From d8d7c66091ed5798d562a2ad011746e013b190be Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 7 Jul 2026 15:21:38 +0000 Subject: [PATCH 0638/1300] chore: prefer `open scoped Classical` over `open Classical` (#41414) As suggested [here](https://github.com/leanprover-community/mathlib4/pull/41387#issuecomment-4892479952). Replace `open Classical` with `open scoped Classical` whenever possible (only like `open Classical` 5 remain), excluding MathlibTest. 6 more `open Classical` were found to be entirely redundant. The next PR in this series will try to remove redundant `open scoped Classical`. (I would also do `classical` but my computer is a bit too slow for that...) Co-authored-by: Batixx Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Archive/Imo/Imo2001Q3.lean | 4 +-- Archive/Sensitivity.lean | 9 ++--- .../AscendingDescendingSequences.lean | 4 +-- .../SumOfPrimeReciprocalsDiverges.lean | 2 +- Counterexamples/AharoniKorman.lean | 4 +-- Mathlib/Algebra/BigOperators/Finprod.lean | 4 +-- .../BigOperators/Group/Multiset/Basic.lean | 2 +- .../Algebra/Category/Ring/Under/Limits.lean | 2 +- Mathlib/Algebra/Colimit/Ring.lean | 2 +- Mathlib/Algebra/Field/IsField.lean | 2 +- .../Algebra/GroupWithZero/Units/Basic.lean | 4 +-- Mathlib/Algebra/Homology/ComplexShape.lean | 2 +- .../Algebra/Homology/DifferentialObject.lean | 2 +- Mathlib/Algebra/Homology/Double.lean | 6 ++-- Mathlib/Algebra/Homology/Embedding/Basic.lean | 2 +- .../Algebra/Homology/Embedding/HomEquiv.lean | 2 +- .../Algebra/Homology/Embedding/TruncGE.lean | 8 ++--- Mathlib/Algebra/Homology/Homotopy.lean | 4 +-- .../SpectralObject/SpectralSequence.lean | 2 +- Mathlib/Algebra/Lie/Loop.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Degree.lean | 2 +- Mathlib/Algebra/MvPolynomial/Rename.lean | 2 +- Mathlib/Algebra/Order/Archimedean/Class.lean | 2 +- Mathlib/Algebra/Order/CauSeq/Completion.lean | 2 +- Mathlib/Algebra/Order/Floor/Defs.lean | 2 +- .../Algebra/Order/Module/HahnEmbedding.lean | 2 +- Mathlib/Algebra/Polynomial/OfFn.lean | 2 +- .../EllipticCurve/Reduction.lean | 2 +- Mathlib/Analysis/BoxIntegral/Basic.lean | 4 +-- .../BoxIntegral/Box/SubboxInduction.lean | 2 +- .../Analysis/BoxIntegral/UnitPartition.lean | 2 +- .../NonUnital.lean | 2 +- Mathlib/Analysis/Calculus/DSlope.lean | 2 +- .../Distribution/SchwartzSpace/Basic.lean | 2 +- .../Distribution/TemperateGrowth.lean | 2 +- .../Analysis/InnerProductSpace/l2Space.lean | 2 +- Mathlib/Analysis/Meromorphic/Divisor.lean | 4 +-- .../Meromorphic/FactorizedRational.lean | 8 ++--- Mathlib/Analysis/Normed/Group/Seminorm.lean | 4 +-- Mathlib/Analysis/Normed/Module/Bases.lean | 2 +- .../Normed/Module/Multilinear/Basic.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 2 +- .../ExpLog/Order.lean | 2 +- .../EnoughInjectives.lean | 2 +- .../Limits/Preserves/SigmaConst.lean | 2 +- .../Limits/Shapes/MultiequalizerPullback.lean | 2 +- .../Presentable/SharplyLT/Basic.lean | 2 +- .../Sites/Precoverage/Subsheaf.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Clique.lean | 2 +- .../SimpleGraph/CompleteMultipartite.lean | 2 +- .../SimpleGraph/Extremal/Basic.lean | 6 ++-- .../SimpleGraph/Extremal/TuranDensity.lean | 2 +- Mathlib/Control/Fix.lean | 2 +- Mathlib/Data/Finsupp/Defs.lean | 2 +- Mathlib/Data/Seq/Defs.lean | 2 +- Mathlib/Data/Set/MemPartition.lean | 2 +- Mathlib/FieldTheory/CardinalEmb.lean | 2 +- Mathlib/FieldTheory/Finite/Polynomial.lean | 6 ++-- .../IsAlgClosed/AlgebraicClosure.lean | 2 +- .../PurelyInseparable/Exponent.lean | 6 ++-- Mathlib/FieldTheory/RatFunc/Luroth.lean | 8 ++--- Mathlib/FieldTheory/SeparableDegree.lean | 2 +- .../SplittingField/Construction.lean | 2 +- .../SplittingField/IsSplittingField.lean | 2 +- Mathlib/Geometry/Manifold/MFDeriv/Defs.lean | 4 +-- .../Geometry/Manifold/PartitionOfUnity.lean | 4 +-- .../KullbackLeibler/Basic.lean | 6 ++-- .../AffineSpace/AffineSubspace/Shift.lean | 2 +- .../FiniteDimensional/Lemmas.lean | 2 +- Mathlib/LinearAlgebra/Multilinear/Basic.lean | 2 +- .../LinearAlgebra/PiTensorProduct/Basis.lean | 2 +- .../LinearAlgebra/PiTensorProduct/Dual.lean | 4 +-- .../QuadraticForm/AlgClosed.lean | 2 +- .../QuadraticForm/Signature.lean | 2 +- Mathlib/LinearAlgebra/SpecialLinearGroup.lean | 2 +- Mathlib/LinearAlgebra/TensorProduct/Free.lean | 4 +-- Mathlib/LinearAlgebra/Trace.lean | 4 +-- Mathlib/Logic/Equiv/Fintype.lean | 2 +- Mathlib/Logic/Nontrivial/Basic.lean | 2 +- Mathlib/Logic/Nontrivial/Defs.lean | 6 ++-- .../ProjectiveFamilyContent.lean | 2 +- .../Function/AEMeasurableSequence.lean | 2 +- .../Function/ConditionalLExpectation.lean | 2 +- .../Function/LpSeminorm/Defs.lean | 2 +- .../Group/FundamentalDomain.lean | 2 +- .../MeasureTheory/Integral/Bochner/Basic.lean | 2 +- Mathlib/MeasureTheory/Integral/SetToL1.lean | 2 +- .../MeasurableSpace/CountablyGenerated.lean | 6 ++-- .../MeasureTheory/MeasurableSpace/Defs.lean | 2 +- .../MeasurableSpace/Embedding.lean | 4 +-- Mathlib/MeasureTheory/Measure/Comap.lean | 4 +-- .../Measure/Decomposition/Exhaustion.lean | 2 +- .../Measure/Decomposition/Lebesgue.lean | 4 +-- Mathlib/MeasureTheory/Measure/Map.lean | 4 +-- .../Measure/MeasureSpaceDef.lean | 2 +- .../MeasureTheory/Measure/PreVariation.lean | 2 +- .../MeasureTheory/VectorMeasure/Basic.lean | 6 ++-- .../VectorMeasure/WithDensity.lean | 2 +- Mathlib/NumberTheory/ClassNumber/Finite.lean | 2 +- Mathlib/NumberTheory/KummerDedekind.lean | 4 +-- Mathlib/NumberTheory/LSeries/PrimesInAP.lean | 2 +- Mathlib/NumberTheory/ModularForms/Cusps.lean | 2 +- .../NumberField/CanonicalEmbedding/Basic.lean | 36 +++++++++---------- .../CanonicalEmbedding/FundamentalCone.lean | 2 +- .../NumberField/Ideal/Asymptotics.lean | 2 +- Mathlib/NumberTheory/Padics/PadicNumbers.lean | 8 ++--- Mathlib/Order/Atoms.lean | 4 +-- Mathlib/Order/Birkhoff.lean | 4 +-- Mathlib/Order/CompleteLatticeIntervals.lean | 8 ++--- .../ConditionallyCompleteLattice/Basic.lean | 6 ++-- Mathlib/Order/Filter/FilterProduct.lean | 2 +- Mathlib/Order/InitialSeg.lean | 2 +- Mathlib/Order/Interval/Basic.lean | 2 +- Mathlib/Order/LiminfLimsup.lean | 6 ++-- Mathlib/Order/NonemptyFiniteChains.lean | 2 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 2 +- Mathlib/Order/Preorder/Chain.lean | 18 +++++----- Mathlib/Order/RelClasses.lean | 2 +- Mathlib/Order/SuccPred/Basic.lean | 2 +- Mathlib/Order/SuccPred/Limit.lean | 8 ++--- .../Kernel/Composition/MapComap.lean | 2 +- .../Kernel/Composition/ParallelComp.lean | 2 +- Mathlib/Probability/Kernel/Condexp.lean | 2 +- .../Kernel/Disintegration/StandardBorel.lean | 4 +-- Mathlib/Probability/Kernel/RadonNikodym.lean | 2 +- .../Moments/CovarianceBilinDual.lean | 2 +- .../DiscreteValuationRing/Basic.lean | 4 +-- Mathlib/RingTheory/DividedPowers/Basic.lean | 2 +- Mathlib/RingTheory/DividedPowers/Padic.lean | 6 ++-- .../RingTheory/Extension/Cotangent/Basis.lean | 2 +- .../Extension/Presentation/Submersive.lean | 2 +- .../FractionalIdeal/Operations.lean | 2 +- Mathlib/RingTheory/HahnSeries/Basic.lean | 10 +++--- .../RingTheory/HahnSeries/Multiplication.lean | 2 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 4 +-- Mathlib/RingTheory/Ideal/Quotient/Basic.lean | 2 +- .../IntegralClosure/IsIntegral/Basic.lean | 2 +- .../RingTheory/OrderOfVanishing/Basic.lean | 2 +- .../OreLocalization/NonZeroDivisors.lean | 4 +-- .../RamificationInertia/Inertia.lean | 2 +- .../RamificationInertia/Ramification.lean | 2 +- .../UniqueFactorizationDomain/Defs.lean | 2 +- .../UniqueFactorizationDomain/FactorSet.lean | 8 ++--- .../UniqueFactorizationDomain/Moebius.lean | 2 +- .../RingTheory/Valuation/ValuationRing.lean | 2 +- Mathlib/SetTheory/Ordinal/Basic.lean | 10 +++--- Mathlib/Tactic/FieldSimp/Lemmas.lean | 2 +- .../Topology/Algebra/InfiniteSum/ENNReal.lean | 4 +-- Mathlib/Topology/Algebra/Module/Equiv.lean | 2 +- .../Topology/Algebra/Module/LinearPMap.lean | 2 +- Mathlib/Topology/Algebra/UniformField.lean | 2 +- .../CWComplex/Classical/Subcomplex.lean | 2 +- .../Category/Profinite/CofilteredLimit.lean | 2 +- .../Topology/Compactness/SigmaCompact.lean | 2 +- Mathlib/Topology/Connected/Basic.lean | 2 +- Mathlib/Topology/DiscreteQuotient.lean | 2 +- .../Topology/FiberBundle/Trivialization.lean | 6 ++-- Mathlib/Topology/IsClosedRestrict.lean | 2 +- Mathlib/Topology/LocallyConstant/Basic.lean | 2 +- Mathlib/Topology/LocallyFinsupp.lean | 2 +- Mathlib/Topology/MetricSpace/Dilation.lean | 2 +- Mathlib/Topology/MetricSpace/Gluing.lean | 2 +- Mathlib/Topology/MetricSpace/PiNat.lean | 6 ++-- Mathlib/Topology/PartitionOfUnity.lean | 12 +++---- Mathlib/Topology/ShrinkingLemma.lean | 4 +-- Mathlib/Topology/UniformSpace/Completion.lean | 2 +- Mathlib/Topology/UniformSpace/Separation.lean | 2 +- Mathlib/Topology/VectorBundle/Basic.lean | 14 ++++---- 168 files changed, 288 insertions(+), 291 deletions(-) diff --git a/Archive/Imo/Imo2001Q3.lean b/Archive/Imo/Imo2001Q3.lean index 812ec2bfe83d12..c271b89aca619f 100644 --- a/Archive/Imo/Imo2001Q3.lean +++ b/Archive/Imo/Imo2001Q3.lean @@ -53,7 +53,7 @@ def Easy (F : Fin 21 → Finset ℕ) (p : ℕ) : Prop := 3 ≤ #{i | p ∈ F i} variable {G B : Fin 21 → Finset ℕ} -open Classical in +open scoped Classical in /-- Every contestant solved at most five problems that were not easy for the other cohort. -/ lemma card_not_easy_le_five {i : Fin 21} (hG : #(G i) ≤ 6) (hB : ∀ j, ¬Disjoint (G i) (B j)) : #{p ∈ G i | ¬Easy B p} ≤ 5 := by @@ -68,7 +68,7 @@ lemma card_not_easy_le_five {i : Fin 21} (hG : #(G i) ≤ 6) (hB : ∀ j, ¬Disj _ ≤ ∑ p ∈ G i, 2 := sum_le_sum fun p mp ↦ Nat.le_of_lt_succ (h p mp) _ ≤ _ := by rw [sum_const, smul_eq_mul]; lia -open Classical in +open scoped Classical in /-- There are at most 210 girl-boy pairs who solved some problem in common that was not easy for a fixed cohort. -/ lemma card_not_easy_le_210 (hG : ∀ i, #(G i) ≤ 6) (hB : ∀ i j, ¬Disjoint (G i) (B j)) : diff --git a/Archive/Sensitivity.lean b/Archive/Sensitivity.lean index a766a59f8c18fd..e16a8c042c5fba 100644 --- a/Archive/Sensitivity.lean +++ b/Archive/Sensitivity.lean @@ -195,7 +195,6 @@ noncomputable def ε : ∀ {n : ℕ}, Q n → V n →ₗ[ℝ] ℝ variable {n : ℕ} set_option backward.isDefEq.respectTransparency false in -open Classical in theorem duality (p q : Q n) : ε p (e q) = if p = q then 1 else 0 := by induction n with | zero => simp [Subsingleton.elim (α := Q 0) p q, ε, e] @@ -225,7 +224,6 @@ theorem epsilon_total {v : V n} (h : ∀ p : Q n, (ε p) v = 0) : v = 0 := by open Module -open Classical in /-- `e` and `ε` are dual families of vectors. It implies that `e` is indeed a basis and `ε` computes coefficients of decompositions of vectors on that basis. -/ theorem dualBases_e_ε (n : ℕ) : DualBases (@e n) (@ε n) where @@ -244,7 +242,6 @@ theorem dim_V : Module.rank ℝ (V n) = 2 ^ n := by rw [rank_eq_card_basis (dualBases_e_ε _).basis, Q.card] assumption_mod_cast -open Classical in instance : FiniteDimensional ℝ (V n) := (dualBases_e_ε _).basis.finiteDimensional_of_finite @@ -293,7 +290,7 @@ theorem f_squared (v : V n) : (f n) (f n v) = (n : ℝ) • v := by `q` the column index). -/ set_option backward.isDefEq.respectTransparency false in -open Classical in +open scoped Classical in theorem f_matrix (p q : Q n) : |ε q (f n (e p))| = if p ∈ q.adjacent then 1 else 0 := by induction n with | zero => @@ -372,7 +369,7 @@ local notation "Card " X:70 => #(Set.toFinset X) equipped with their subspace structures. The notations come from the general theory of lattices, with inf and sup (also known as meet and join). -/ -open Classical in +open scoped Classical in /-- If a subset `H` of `Q (m+1)` has cardinal at least `2^m + 1` then the subspace of `V (m+1)` spanned by the corresponding basis vectors non-trivially intersects the range of `g m`. -/ @@ -407,7 +404,7 @@ theorem exists_eigenvalue (H : Set (Q m.succ)) (hH : Card H ≥ 2 ^ m + 1) : rw [Set.toFinset_card] at hH linarith -open Classical in +open scoped Classical in /-- **Huang sensitivity theorem** also known as the **Huang degree theorem** -/ theorem huang_degree_theorem (H : Set (Q m.succ)) (hH : Card H ≥ 2 ^ m + 1) : ∃ q, q ∈ H ∧ √(m + 1) ≤ Card H ∩ q.adjacent := by diff --git a/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean b/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean index b9480c2046155a..a51e40209af26a 100644 --- a/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean +++ b/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean @@ -33,12 +33,12 @@ variable {α β : Type*} [Fintype α] [LinearOrder α] [LinearOrder β] {f : α /-- The possible lengths of an increasing sequence which ends at `i`. -/ private noncomputable def incSequencesTo (f : α → β) (i : α) : Finset ℕ := - open Classical in + open scoped Classical in image card {t : Finset α | IsGreatest t i ∧ StrictMonoOn f t} /-- The possible lengths of a decreasing sequence which ends at `i`. -/ private noncomputable def decSequencesTo (f : α → β) (i : α) : Finset ℕ := - open Classical in + open scoped Classical in image card {t : Finset α | IsGreatest t i ∧ StrictAntiOn f t} /-- The singleton sequence is increasing, so 1 is a possible length. -/ diff --git a/Archive/Wiedijk100Theorems/SumOfPrimeReciprocalsDiverges.lean b/Archive/Wiedijk100Theorems/SumOfPrimeReciprocalsDiverges.lean index a9436620c12432..47e07840fbcb94 100644 --- a/Archive/Wiedijk100Theorems/SumOfPrimeReciprocalsDiverges.lean +++ b/Archive/Wiedijk100Theorems/SumOfPrimeReciprocalsDiverges.lean @@ -52,7 +52,7 @@ of `p`, i.e., those `e < x` for which there is a prime `p ∈ (k, x]` that divid -/ def U (x k : ℕ) : Finset ℕ := (P x k).biUnion fun p ↦ {e ∈ range x | p ∣ e + 1} -open Classical in +open scoped Classical in /-- Those `e < x` for which `e + 1` is a product of powers of primes smaller than or equal to `k`. -/ noncomputable def M (x k : ℕ) : Finset ℕ := {e ∈ range x | ∀ p : ℕ, p.Prime ∧ p ∣ e + 1 → p ≤ k} diff --git a/Counterexamples/AharoniKorman.lean b/Counterexamples/AharoniKorman.lean index e42447f5bc5d59..ffc861009c76ce 100644 --- a/Counterexamples/AharoniKorman.lean +++ b/Counterexamples/AharoniKorman.lean @@ -870,7 +870,7 @@ lemma not_R_hits_same {x : Hollom} (hx : x ∈ R n C) (hx' : x ∉ C ∩ level n apply f.incomp_apply _ (hx.2 _ hfx).symm exact ne_of_mem_of_not_mem hfx hx' -open Classical in +open scoped Classical in /-- Given a subset `C` of the Hollom partial order, and an index `n`, find the smallest element of `C ∩ level (n + 1)`, expressed as `(x₀, y₀, n + 1)`. @@ -912,7 +912,7 @@ lemma x0_y0_mem (h : (C ∩ level (n + 1)).Nonempty) : h(x0 n C, y0 n C, n + 1) lemma x0_y0_min (hC : IsChain (· ≤ ·) C) {a b : ℕ} (h : h(a, b, n + 1) ∈ C) : h(x0 n C, y0 n C, n + 1) ≤ h(a, b, n + 1) := x0y0_min (a, b) hC h -open Classical in +open scoped Classical in /-- Construction of the set `S`, which has the following key properties: * It is a subset of `R`. diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index acb911dd7a79f0..b2aab9788f5d16 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -97,13 +97,13 @@ section /- Note: we use classical logic only for these definitions, to ensure that we do not write lemmas with `Classical.dec` in their statement. -/ -open Classical in +open scoped Classical in /-- Sum of `f x` as `x` ranges over the elements of the support of `f`, if it's finite. Zero otherwise. -/ noncomputable irreducible_def finsum (lemma := finsum_def') [AddCommMonoid M] (f : α → M) : M := if h : HasFiniteSupport (f ∘ PLift.down) then ∑ i ∈ h.toFinset, f i.down else 0 -open Classical in +open scoped Classical in /-- Product of `f x` as `x` ranges over the elements of the multiplicative support of `f`, if it's finite. One otherwise. -/ @[to_additive existing] diff --git a/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean index a4f7d95f92c9c3..04badc18840eb4 100644 --- a/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean @@ -232,7 +232,7 @@ theorem sum_map_tsub [AddCommMonoid M] [PartialOrder M] [ExistsAddOfLE M] end OrderedSub instance {M : Type*} : IsAddTorsionFree (Multiset M) := - ⟨fun n hn x y h ↦ open Classical in Multiset.ext' fun _ ↦ + ⟨fun n hn x y h ↦ open scoped Classical in Multiset.ext' fun _ ↦ (Nat.mul_right_inj hn).mp <| by simp only [← Multiset.count_nsmul, h]⟩ end Multiset diff --git a/Mathlib/Algebra/Category/Ring/Under/Limits.lean b/Mathlib/Algebra/Category/Ring/Under/Limits.lean index b0139dcbc8f5bd..7b05204b482d33 100644 --- a/Mathlib/Algebra/Category/Ring/Under/Limits.lean +++ b/Mathlib/Algebra/Category/Ring/Under/Limits.lean @@ -80,7 +80,7 @@ def tensorProductFanIso [Fintype ι] [DecidableEq ι] : Algebra.TensorProduct.piRight_tmul] · simp_all -open Classical in +open scoped Classical in /-- The fan on `i ↦ S ⊗[R] P i` given by `S ⊗[R] ∀ i, P i` is limiting if `ι` is finite. -/ def tensorProductFanIsLimit [Finite ι] : IsLimit (tensorProductFan S P) := letI : Fintype ι := Fintype.ofFinite ι diff --git a/Mathlib/Algebra/Colimit/Ring.lean b/Mathlib/Algebra/Colimit/Ring.lean index ed479e03486171..1091157c329aac 100644 --- a/Mathlib/Algebra/Colimit/Ring.lean +++ b/Mathlib/Algebra/Colimit/Ring.lean @@ -321,7 +321,7 @@ theorem exists_inv {p : Ring.DirectLimit G f} : p ≠ 0 → ∃ y, p * y = 1 := section -open Classical in +open scoped Classical in /-- Noncomputable multiplicative inverse in a direct limit of fields. -/ noncomputable def inv (p : Ring.DirectLimit G f) : Ring.DirectLimit G f := if H : p = 0 then 0 else Classical.choose (DirectLimit.exists_inv G f H) diff --git a/Mathlib/Algebra/Field/IsField.lean b/Mathlib/Algebra/Field/IsField.lean index 69710a3312cc6f..ba5c64299d332c 100644 --- a/Mathlib/Algebra/Field/IsField.lean +++ b/Mathlib/Algebra/Field/IsField.lean @@ -69,7 +69,7 @@ theorem not_isField_of_subsingleton (R : Type u) [Semiring R] [Subsingleton R] : let ⟨_, _, h⟩ := h.exists_pair_ne h (Subsingleton.elim _ _) -open Classical in +open scoped Classical in /-- Transferring from `IsField` to `Semifield`. -/ @[implicit_reducible] noncomputable def IsField.toSemifield {R : Type u} [Semiring R] (h : IsField R) : Semifield R where diff --git a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean index eddd2a3619a1e3..7b11b6be6663f4 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean @@ -74,7 +74,7 @@ theorem not_isUnit_zero [Nontrivial M₀] : ¬IsUnit (0 : M₀) := namespace Ring -open Classical in +open scoped Classical in /-- Introduce a function `inverse` on a monoid with zero `M₀`, which sends `x` to `x⁻¹` if `x` is invertible and to `0` otherwise. This definition is somewhat ad hoc, but one needs a fully (rather than partially) defined inverse function for some purposes, including for calculus. @@ -508,7 +508,7 @@ section NoncomputableDefs variable {M : Type*} [Nontrivial M] -open Classical in +open scoped Classical in /-- Constructs a `GroupWithZero` structure on a `MonoidWithZero` consisting only of units and 0. -/ @[implicit_reducible] diff --git a/Mathlib/Algebra/Homology/ComplexShape.lean b/Mathlib/Algebra/Homology/ComplexShape.lean index ce57848afdc0bd..f26391859d369c 100644 --- a/Mathlib/Algebra/Homology/ComplexShape.lean +++ b/Mathlib/Algebra/Homology/ComplexShape.lean @@ -133,7 +133,7 @@ instance subsingleton_next (c : ComplexShape ι) (i : ι) : Subsingleton { j // congr exact c.next_eq rij rik -open Classical in +open scoped Classical in /-- An arbitrary choice of index `j` such that `Rel i j`, if such exists. Returns `i` otherwise. -/ diff --git a/Mathlib/Algebra/Homology/DifferentialObject.lean b/Mathlib/Algebra/Homology/DifferentialObject.lean index 36387a8a9e3d93..0f1a6025bc82b2 100644 --- a/Mathlib/Algebra/Homology/DifferentialObject.lean +++ b/Mathlib/Algebra/Homology/DifferentialObject.lean @@ -76,7 +76,7 @@ theorem d_eqToHom (X : HomologicalComplex V (ComplexShape.up' b)) {x y z : β} ( set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in -open Classical in +open scoped Classical in /-- The functor from differential graded objects to homological complexes. -/ @[simps] diff --git a/Mathlib/Algebra/Homology/Double.lean b/Mathlib/Algebra/Homology/Double.lean index ae5903dcbf3b21..c4ecd3ea3d8416 100644 --- a/Mathlib/Algebra/Homology/Double.lean +++ b/Mathlib/Algebra/Homology/Double.lean @@ -32,7 +32,7 @@ section variable {X₀ X₁ : C} (f : X₀ ⟶ X₁) {ι : Type*} {c : ComplexShape ι} {i₀ i₁ : ι} (hi₀₁ : c.Rel i₀ i₁) -open Classical in +open scoped Classical in /-- Given a complex shape `c`, two indices `i₀` and `i₁` such that `c.Rel i₀ i₁`, and `f : X₀ ⟶ X₁`, this is the homological complex which, if `i₀ ≠ i₁`, only consists of the map `f` in degrees `i₀` and `i₁`, and zero everywhere else. -/ @@ -112,7 +112,7 @@ variable {f} (h : i₀ ≠ i₁) {K : HomologicalComplex C c} (φ₀ : X₀ ⟶ (comm : φ₀ ≫ K.d i₀ i₁ = f ≫ φ₁) (hφ : ∀ (k : ι), c.Rel i₁ k → φ₁ ≫ K.d i₁ k = 0) -open Classical in +open scoped Classical in /-- Constructor for morphisms from a homological complex `double f hi₀₁`. -/ noncomputable def mkHomFromDouble : double f hi₀₁ ⟶ K where f k := @@ -189,7 +189,7 @@ noncomputable def evalCompCoyonedaCorepresentableBySingle (i : ι) [DecidableEq variable [c.HasNoLoop] -open Classical in +open scoped Classical in /-- Given a complex shape `c : ComplexShape ι` (with no loop), `X : C` and `j : ι`, this is a quite explicit choice of corepresentative of the functor which sends `K : HomologicalComplex C c` to `X ⟶ K.X j`. -/ diff --git a/Mathlib/Algebra/Homology/Embedding/Basic.lean b/Mathlib/Algebra/Homology/Embedding/Basic.lean index f4aa921fcc8fe4..17bd456cd318e9 100644 --- a/Mathlib/Algebra/Homology/Embedding/Basic.lean +++ b/Mathlib/Algebra/Homology/Embedding/Basic.lean @@ -137,7 +137,7 @@ instance [e.IsTruncGE] : e.op.IsTruncLE where instance [e.IsTruncLE] : e.op.IsTruncGE where mem_next h := e.mem_prev h -open Classical in +open scoped Classical in /-- The map `ι' → Option ι` which sends `e.f i` to `some i` and the other elements to `none`. -/ noncomputable def r (i' : ι') : Option ι := if h : ∃ (i : ι), e.f i = i' diff --git a/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean b/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean index 3042ee1136e7ba..9387307deb8881 100644 --- a/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean +++ b/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean @@ -54,7 +54,7 @@ variable (φ : K.restriction e ⟶ L) variable {e} -open Classical in +open scoped Classical in /-- Auxiliary definition for `liftExtend`. -/ noncomputable def f (i' : ι') : K.X i' ⟶ (L.extend e).X i' := if hi' : ∃ i, e.f i = i' then diff --git a/Mathlib/Algebra/Homology/Embedding/TruncGE.lean b/Mathlib/Algebra/Homology/Embedding/TruncGE.lean index 8117514386c784..d8798f8abc86a3 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncGE.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncGE.lean @@ -56,7 +56,7 @@ variable (K L M : HomologicalComplex C c') (φ : K ⟶ L) (φ' : L ⟶ M) namespace truncGE' -open Classical in +open scoped Classical in /-- The `X` field of `truncGE'`. -/ noncomputable def X (i : ι) : C := if e.BoundaryGE i @@ -73,7 +73,7 @@ noncomputable def XIso {i : ι} (hi : ¬ e.BoundaryGE i) : X K e i ≅ K.X (e.f i) := eqToIso (if_neg hi) -open Classical in +open scoped Classical in /-- The `d` field of `truncGE'`. -/ noncomputable def d (i j : ι) : X K e i ⟶ X K e j := if hij : c.Rel i j @@ -160,7 +160,7 @@ section variable {K L M} -open Classical in +open scoped Classical in /-- The morphism `K.truncGE' e ⟶ L.truncGE' e` induced by a morphism `K ⟶ L`. -/ noncomputable def truncGE'Map : K.truncGE' e ⟶ L.truncGE' e where f i := @@ -226,7 +226,7 @@ end namespace restrictionToTruncGE' -open Classical in +open scoped Classical in /-- Auxiliary definition for `HomologicalComplex.restrictionToTruncGE'`. -/ noncomputable def f (i : ι) : (K.restriction e).X i ⟶ (K.truncGE' e).X i := if hi : e.BoundaryGE i then diff --git a/Mathlib/Algebra/Homology/Homotopy.lean b/Mathlib/Algebra/Homology/Homotopy.lean index b921e0e5a06f8d..a931b79b3bbc97 100644 --- a/Mathlib/Algebra/Homology/Homotopy.lean +++ b/Mathlib/Algebra/Homology/Homotopy.lean @@ -248,7 +248,7 @@ def nullHomotopicMap (hom : ∀ i j, C.X i ⟶ D.X j) : C ⟶ D where rw [dNext_eq hom hij, prevD_eq hom hij, Preadditive.comp_add, Preadditive.add_comp, eq1, eq2, add_zero, zero_add, assoc] -open Classical in +open scoped Classical in /-- Variant of `nullHomotopicMap` where the input consists only of the relevant maps `C_i ⟶ D_j` such that `c.Rel j i`. -/ def nullHomotopicMap' (h : ∀ i j, c.Rel j i → (C.X i ⟶ D.X j)) : C ⟶ D := @@ -330,7 +330,7 @@ def nullHomotopy (hom : ∀ i j, C.X i ⟶ D.X j) (zero : ∀ i j, ¬c.Rel j i rw [HomologicalComplex.zero_f_apply, add_zero] rfl } -open Classical in +open scoped Classical in /-- Homotopy to zero for maps constructed with `nullHomotopicMap'` -/ @[simps!] def nullHomotopy' (h : ∀ i j, c.Rel j i → (C.X i ⟶ D.X j)) : Homotopy (nullHomotopicMap' h) 0 := by diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index debb0e05f49302..a0b5f70d184daf 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -115,7 +115,7 @@ noncomputable def pageXIso (r : ℤ) (hr : r₀ ≤ r) (pq : κ) subst h hn₂ h₀ h₁ h₂ h₃ rfl) -open Classical in +open scoped Classical in /-- The differential on the `r`th page of the spectral sequence. -/ noncomputable def pageD (r : ℤ) (pq pq' : κ) (hr : r₀ ≤ r := by lia) : pageX X data r pq hr ⟶ pageX X data r pq' hr := diff --git a/Mathlib/Algebra/Lie/Loop.lean b/Mathlib/Algebra/Lie/Loop.lean index 3999d5c9248969..52d448747dc5b4 100644 --- a/Mathlib/Algebra/Lie/Loop.lean +++ b/Mathlib/Algebra/Lie/Loop.lean @@ -70,7 +70,7 @@ def loopAlgebraEquivLaurent : namespace LoopAlgebra -open Classical in +open scoped Classical in /-- A linear isomorphism to finitely supported functions. -/ def toFinsupp : loopAlgebra R A L ≃ₗ[R] A →₀ L := TensorProduct.equivFinsuppOfBasisLeft (AddMonoidAlgebra.basis A R) diff --git a/Mathlib/Algebra/MonoidAlgebra/Degree.lean b/Mathlib/Algebra/MonoidAlgebra/Degree.lean index e8aab8b059d9e5..259226a19b845f 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Degree.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Degree.lean @@ -277,7 +277,7 @@ theorem supDegree_single_ne_zero (a : A) {r : R} (hr : r ≠ 0) : (single a r).supDegree D = D a := by simp [supDegree, hr] -open Classical in +open scoped Classical in theorem supDegree_single (a : A) (r : R) : (single a r).supDegree D = if r = 0 then ⊥ else D a := by split_ifs with hr <;> simp [supDegree_single_ne_zero, hr] diff --git a/Mathlib/Algebra/MvPolynomial/Rename.lean b/Mathlib/Algebra/MvPolynomial/Rename.lean index 39bce9acf051f0..159560456c0fc9 100644 --- a/Mathlib/Algebra/MvPolynomial/Rename.lean +++ b/Mathlib/Algebra/MvPolynomial/Rename.lean @@ -124,7 +124,7 @@ section variable {f : σ → τ} (hf : Function.Injective f) {p q : MvPolynomial τ R} -open Classical in +open scoped Classical in /-- Given a function between sets of variables `f : σ → τ` that is injective with proof `hf`, `MvPolynomial.killCompl hf` is the `AlgHom` from `R[τ]` to `R[σ]` that is left inverse to `rename f : R[σ] → R[τ]` and sends the variables in the complement of the range of `f` to `0`. -/ diff --git a/Mathlib/Algebra/Order/Archimedean/Class.lean b/Mathlib/Algebra/Order/Archimedean/Class.lean index 209a9bc111c513..23ab632c89c4d9 100644 --- a/Mathlib/Algebra/Order/Archimedean/Class.lean +++ b/Mathlib/Algebra/Order/Archimedean/Class.lean @@ -262,7 +262,7 @@ instance [Subsingleton M] : Subsingleton (MulArchimedeanClass M) := @[to_additive] noncomputable instance : LinearOrder (MulArchimedeanClass M) := - open Classical in + open scoped Classical in -- TODO: why does `inferInstanceAs` not work here? fast_instance% (inferInstance : LinearOrder (Antisymmetrization (MulArchimedeanOrder M) (· ≤ ·))) diff --git a/Mathlib/Algebra/Order/CauSeq/Completion.lean b/Mathlib/Algebra/Order/CauSeq/Completion.lean index 9d8794438abc3f..7bc0005e95c2aa 100644 --- a/Mathlib/Algebra/Order/CauSeq/Completion.lean +++ b/Mathlib/Algebra/Order/CauSeq/Completion.lean @@ -188,7 +188,7 @@ instance instRatCast : RatCast (Cauchy abv) where ratCast q := ofRat q @[simp, norm_cast] lemma ofRat_nnratCast (q : ℚ≥0) : ofRat (q : β) = (q : Cauchy abv) := rfl @[simp, norm_cast] lemma ofRat_ratCast (q : ℚ) : ofRat (q : β) = (q : Cauchy abv) := rfl -open Classical in +open scoped Classical in noncomputable instance : Inv (Cauchy abv) := ⟨fun x => (Quotient.liftOn x fun f => mk <| if h : LimZero f then 0 else inv f h) fun f g fg => by diff --git a/Mathlib/Algebra/Order/Floor/Defs.lean b/Mathlib/Algebra/Order/Floor/Defs.lean index 64f301a1f3b181..8e1e7c083be6a1 100644 --- a/Mathlib/Algebra/Order/Floor/Defs.lean +++ b/Mathlib/Algebra/Order/Floor/Defs.lean @@ -207,7 +207,7 @@ def FloorRing.ofCeil (α) [Ring α] [LinearOrder α] [IsOrderedRing α] (ceil : gc_coe_floor := fun a z => by rw [le_neg, gc_ceil_coe, Int.cast_neg, neg_le_neg_iff] gc_ceil_coe } -open Classical in +open scoped Classical in private noncomputable def floorAux {α} [Ring α] [PartialOrder α] [IsOrderedRing α] [Nontrivial α] {x : α} (below : ∃ n : ℤ, n ≤ x) (above : ∃ n : ℤ, x ≤ n) : diff --git a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean index e9101fdda6f68b..8a775ef6df973c 100644 --- a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean +++ b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean @@ -515,7 +515,7 @@ extension isn't necessarily linear. -/ noncomputable def evalCoeff (x : M) (c : FiniteArchimedeanClass M) : R := - open Classical in + open scoped Classical in if h : ∃ y : f.val.domain, y.val - x ∈ ball K c then (ofLex (f.val h.choose)).coeff c else diff --git a/Mathlib/Algebra/Polynomial/OfFn.lean b/Mathlib/Algebra/Polynomial/OfFn.lean index 67d1f8bc3c2ed4..2d8521f1f06382 100644 --- a/Mathlib/Algebra/Polynomial/OfFn.lean +++ b/Mathlib/Algebra/Polynomial/OfFn.lean @@ -105,7 +105,7 @@ theorem injective_ofFn (n : ℕ) : Function.Injective (ofFn (R := R) n) := omit [DecidableEq R] in theorem surjective_toFn (n : ℕ) : Function.Surjective (toFn (R := R) n) := - open Classical in + open scoped Classical in Function.RightInverse.surjective <| toFn_comp_ofFn_eq_id n theorem ofFn_comp_toFn_eq_id_of_natDegree_lt {n : ℕ} {p : R[X]} (h_deg : p.natDegree < n) : diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean index 0568284fa0dca0..7887753b457cbf 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Reduction.lean @@ -209,7 +209,7 @@ variable {K : Type*} [Field K] [Algebra R K] [IsFractionRing R K] open WithZero Multiplicative open IsDiscreteValuationRing IsDedekindDomain.HeightOneSpectrum -open Classical in +open scoped Classical in /-- The valuation of the discriminant of a Weierstrass curve `W`, which is at most 1 if `W` is integral. Zero otherwise. -/ noncomputable def valuation_Δ_aux (W : WeierstrassCurve K) : diff --git a/Mathlib/Analysis/BoxIntegral/Basic.lean b/Mathlib/Analysis/BoxIntegral/Basic.lean index 607a6bc99eda13..049d9d385a074c 100644 --- a/Mathlib/Analysis/BoxIntegral/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Basic.lean @@ -105,7 +105,7 @@ theorem integralSum_inf_partition (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ integralSum f vol (π.infPrepartition π') = integralSum f vol π := integralSum_biUnion_partition f vol π _ fun _J hJ => h.restrict (Prepartition.le_of_mem _ hJ) -open Classical in +open scoped Classical in theorem integralSum_fiberwise {α} (g : Box ι → α) (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : TaggedPrepartition I) : (∑ y ∈ π.boxes.image g, integralSum f vol (π.filter (g · = y))) = integralSum f vol π := @@ -164,7 +164,7 @@ predicate. -/ def Integrable (I : Box ι) (l : IntegrationParams) (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) := ∃ y, HasIntegral I l f vol y -open Classical in +open scoped Classical in /-- The integral of a function `f` over a box `I` along a filter `l` w.r.t. a volume `vol`. Returns zero on non-integrable functions. -/ def integral (I : Box ι) (l : IntegrationParams) (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) := diff --git a/Mathlib/Analysis/BoxIntegral/Box/SubboxInduction.lean b/Mathlib/Analysis/BoxIntegral/Box/SubboxInduction.lean index 56282b2cd361a1..94bfac326ca29b 100644 --- a/Mathlib/Analysis/BoxIntegral/Box/SubboxInduction.lean +++ b/Mathlib/Analysis/BoxIntegral/Box/SubboxInduction.lean @@ -40,7 +40,7 @@ namespace Box variable {ι : Type*} {I J : Box ι} -open Classical in +open scoped Classical in /-- For a box `I`, the hyperplanes passing through its center split `I` into `2 ^ card ι` boxes. `BoxIntegral.Box.splitCenterBox I s` is one of these boxes. See also `BoxIntegral.Partition.splitCenter` for the corresponding `BoxIntegral.Partition`. -/ diff --git a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean index b8f218c8f6b7d6..2caace409304a7 100644 --- a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean +++ b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean @@ -222,7 +222,7 @@ theorem mem_admissibleIndex_iff {B : Box ι} {ν : ι → ℤ} : ν ∈ admissibleIndex n B ↔ box n ν ≤ B := by rw [admissibleIndex, Set.Finite.mem_toFinset, Set.mem_setOf_eq, Box.coe_subset_coe] -open Classical in +open scoped Classical in /-- For `B : BoxIntegral.Box`, the `TaggedPrepartition` formed by the set of all `unitPartition.box` whose index is `B`-admissible. -/ def prepartition (B : Box ι) : TaggedPrepartition B where diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index 303415eb28ff4d..31c5d13ffeeb7c 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -201,7 +201,7 @@ end cfcₙL section CFCn -open Classical in +open scoped Classical in /-- This is the *continuous functional calculus* of an element `a : A` in a non-unital algebra applied to bare functions. When either `a` does not satisfy the predicate `p` (i.e., `a` is not `IsStarNormal`, `IsSelfAdjoint`, or `0 ≤ a` when `R` is `ℂ`, `ℝ`, or `ℝ≥0`, respectively), or when diff --git a/Mathlib/Analysis/Calculus/DSlope.lean b/Mathlib/Analysis/Calculus/DSlope.lean index ba32188c80a643..235f8b43b375d5 100644 --- a/Mathlib/Analysis/Calculus/DSlope.lean +++ b/Mathlib/Analysis/Calculus/DSlope.lean @@ -29,7 +29,7 @@ open Function Set Filter variable {𝕜 E : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] [NormedSpace 𝕜 E] -open Classical in +open scoped Classical in /-- `dslope f a b` is defined as `slope f a b = (b - a)⁻¹ • (f b - f a)` for `a ≠ b` and `deriv f a` for `a = b`. -/ noncomputable def dslope (f : 𝕜 → E) (a : 𝕜) : 𝕜 → E := diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean index 6246742ddac1b8..240e9dcf911178 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean @@ -732,7 +732,7 @@ end bilin section smul variable (F) in -open Classical in +open scoped Classical in /-- The map `f ↦ (x ↦ g x • f x)` as a continuous `𝕜`-linear map on Schwartz space, where `g` is a function of temperate growth. -/ def smulLeftCLM (g : E → 𝕜) : 𝓢(E, F) →L[𝕜] 𝓢(E, F) := diff --git a/Mathlib/Analysis/Distribution/TemperateGrowth.lean b/Mathlib/Analysis/Distribution/TemperateGrowth.lean index 0232517372254d..baf2162ae7318e 100644 --- a/Mathlib/Analysis/Distribution/TemperateGrowth.lean +++ b/Mathlib/Analysis/Distribution/TemperateGrowth.lean @@ -424,7 +424,7 @@ open scoped ENNReal class HasTemperateGrowth (μ : Measure E) : Prop where exists_integrable : ∃ (n : ℕ), Integrable (fun x ↦ (1 + ‖x‖) ^ (- (n : ℝ))) μ -open Classical in +open scoped Classical in /-- An integer exponent `l` such that `(1 + ‖x‖) ^ (-l)` is integrable if `μ` has temperate growth. -/ def integrablePower (μ : Measure E) : ℕ := diff --git a/Mathlib/Analysis/InnerProductSpace/l2Space.lean b/Mathlib/Analysis/InnerProductSpace/l2Space.lean index 42ce8b9d7ccd1d..a4d66041103696 100644 --- a/Mathlib/Analysis/InnerProductSpace/l2Space.lean +++ b/Mathlib/Analysis/InnerProductSpace/l2Space.lean @@ -380,7 +380,7 @@ namespace HilbertBasis instance {ι : Type*} : Inhabited (HilbertBasis ι 𝕜 ℓ²(ι, 𝕜)) := ⟨ofRepr (LinearIsometryEquiv.refl 𝕜 _)⟩ -open Classical in +open scoped Classical in /-- `b i` is the `i`th basis vector. -/ instance instFunLike : FunLike (HilbertBasis ι 𝕜 E) ι E where coe b i := b.repr.symm (lp.single 2 i (1 : 𝕜)) diff --git a/Mathlib/Analysis/Meromorphic/Divisor.lean b/Mathlib/Analysis/Meromorphic/Divisor.lean index 67b64ce7dee5b7..9605d5ffb3dda6 100644 --- a/Mathlib/Analysis/Meromorphic/Divisor.lean +++ b/Mathlib/Analysis/Meromorphic/Divisor.lean @@ -31,7 +31,7 @@ namespace MeromorphicOn ## Definition of the Divisor -/ -open Classical in +open scoped Classical in /-- The divisor of a meromorphic function `f`, mapping a point `z` to the order of `f` at `z`, and to zero if the order is infinite. @@ -54,7 +54,7 @@ noncomputable def divisor (f : 𝕜 → E) (U : Set 𝕜) : tauto · simp [hf, Pi.zero_def] -open Classical in +open scoped Classical in /-- Definition of the divisor -/ theorem divisor_def (f : 𝕜 → E) (U : Set 𝕜) : divisor f U z = if MeromorphicOn f U ∧ z ∈ U then (meromorphicOrderAt f z).untop₀ else 0 := diff --git a/Mathlib/Analysis/Meromorphic/FactorizedRational.lean b/Mathlib/Analysis/Meromorphic/FactorizedRational.lean index 78c48e562fd40f..941471adbf470c 100644 --- a/Mathlib/Analysis/Meromorphic/FactorizedRational.lean +++ b/Mathlib/Analysis/Meromorphic/FactorizedRational.lean @@ -100,7 +100,7 @@ theorem ne_zero {d : 𝕜 → ℤ} {x : 𝕜} (h : d x = 0) : by_cases h₂ : x = z <;> simp_all [zpow_ne_zero, sub_ne_zero] · simp [finprod_of_infinite_mulSupport h₁] -open Classical in +open scoped Classical in /-- Helper Lemma for Computations: Extract one factor out of a factorized rational function. -/ @@ -179,7 +179,7 @@ theorem divisor {U : Set 𝕜} {D : locallyFinsuppWithin U ℤ} (hD : D.support. by_cases hz : z ∈ U <;> simp [(meromorphicNFOn D U).meromorphicOn, hz, meromorphicOrderAt_eq D hD] -open Classical in +open scoped Classical in private lemma mulSupport_update {d : 𝕜 → ℤ} {x : 𝕜} (h : d.support.Finite) : (fun u ↦ (x - u) ^ Function.update d x 0 u).mulSupport ⊆ h.toFinset := by @@ -191,7 +191,7 @@ private lemma mulSupport_update {d : 𝕜 → ℤ} {x : 𝕜} simp · simp_all -open Classical in +open scoped Classical in /-- Compute the trailing coefficient of the factorized rational function associated with `d : 𝕜 → ℤ`. -/ @@ -374,7 +374,7 @@ theorem MeromorphicOn.extract_zeros_poles_log {f g : 𝕜 → E} {D : Function.l rw [log_mul (Finset.prod_ne_zero_iff.2 this) (by simp [hg ⟨z, h₃z⟩]), log_prod this] simp [log_zpow] -open Classical in +open scoped Classical in /-- In the setting of `MeromorphicOn.extract_zeros_poles`, compute the trailing coefficient of `f` in terms of `divisor f U` and `g x`. diff --git a/Mathlib/Analysis/Normed/Group/Seminorm.lean b/Mathlib/Analysis/Normed/Group/Seminorm.lean index e5c3f97f277ce7..0b0c1322132f2a 100644 --- a/Mathlib/Analysis/Normed/Group/Seminorm.lean +++ b/Mathlib/Analysis/Normed/Group/Seminorm.lean @@ -254,7 +254,7 @@ theorem coe_add : ⇑(p + q) = p + q := theorem add_apply (x : E) : (p + q) x = p x + q x := rfl -open Classical in +open scoped Classical in @[to_additive] noncomputable instance : SupSet (GroupSeminorm E) where sSup s := @@ -530,7 +530,7 @@ theorem zero_apply (x : E) : (0 : NonarchAddGroupSeminorm E) x = 0 := instance : Inhabited (NonarchAddGroupSeminorm E) := ⟨0⟩ -open Classical in +open scoped Classical in noncomputable instance : SupSet (NonarchAddGroupSeminorm E) where sSup s := if h : BddAbove s then diff --git a/Mathlib/Analysis/Normed/Module/Bases.lean b/Mathlib/Analysis/Normed/Module/Bases.lean index 04f6571614bc88..8a0fb89ad36437 100644 --- a/Mathlib/Analysis/Normed/Module/Bases.lean +++ b/Mathlib/Analysis/Normed/Module/Bases.lean @@ -181,7 +181,7 @@ theorem range_proj_eq_span (A : Finset β) : use b i rw [ContinuousLinearMap.coe_coe, proj_apply_basis_mem, if_pos (Finset.mem_coe.mp hi)] -open Classical in +open scoped Classical in /-- Composition of projections: `proj A (proj B x) = proj (A ∩ B) x`. -/ theorem proj_comp (A B : Finset β) (x : X) : b.proj A (b.proj B x) = b.proj (A ∩ B) x := by simp only [proj_apply, map_sum, map_smul, b.ortho, Pi.single_apply, ite_smul, one_smul, zero_smul, diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean index aba6bf12d57fad..d179029f25fa13 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean @@ -1195,7 +1195,7 @@ lemma norm_iteratedFDerivComponent_le {α : Type*} [Fintype α] _ = ‖f‖ * ‖x‖ ^ (Fintype.card {a : ι // a ∉ s}) := by rw [prod_const, card_univ] _ = ‖f‖ * ‖x‖ ^ (Fintype.card ι - Fintype.card α) := by simp [Fintype.card_congr e] -open Classical in +open scoped Classical in /-- The `k`-th iterated derivative of a continuous multilinear map `f` at the point `x`. It is a continuous multilinear map of `k` vectors `v₁, ..., vₖ` (with the same type as `x`), mapping them to `∑ f (x₁, (v_{i₁})₂, x₃, ...)`, where at each index `j` one uses either `xⱼ` or one diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index 7e79c81ce21402..0a455fc7dc5380 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -471,7 +471,7 @@ theorem smul_inf [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] (r section Classical -open Classical in +open scoped Classical in /-- We define the supremum of an arbitrary subset of `Seminorm 𝕜 E` as follows: * if `s` is `BddAbove` *as a set of functions `E → ℝ`* (that is, if `s` is pointwise bounded above), we take the pointwise supremum of all elements of `s`, and we prove that it is indeed a diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean index 5886de2d98cf4f..b8dda31c967e0f 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean @@ -60,7 +60,7 @@ lemma CFC.tendsto_ite_cfc_rpow_sub_one_ite_log : · simpa [ha] using CFC.tendsto_cfc_rpow_sub_one_log ha · simp_all -open Classical in +open scoped Classical in private lemma CFC.cfc_rpow_sub_one_eqOn {p : ℝ} : {a : A | IsStrictlyPositive a}.EqOn (fun a => if a ∈ {b : A | IsStrictlyPositive b} diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean index e906c11c7cf233..74d39579f9e6ac 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean @@ -151,7 +151,7 @@ lemma exists_larger_subobject {X : C} (A : Subobject X) (hA : A ≠ ⊤) : variable {X : C} -open Classical in +open scoped Classical in /-- Assuming `G : C` is a generator, `X : C`, and `A : Subobject X`, this is a subobject of `X` which is `⊤` if `A = ⊤`, and otherwise it is a larger subobject given by the lemma `exists_larger_subobject`. diff --git a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean index 288d0e0d270b25..43d27f6f02903d 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean @@ -64,7 +64,7 @@ variable {α β : Type*} (f : α → β) [HasCoproduct (fun (_ : α) ↦ R)] [HasCoproduct (fun (_ : β) ↦ R)] [HasCoproduct (fun (_ : ((Set.range f)ᶜ : Set _)) ↦ R)] -open Classical in +open scoped Classical in /-- A colimit cokernel cofork for the map `∐ fun (_ : α) ↦ R ⟶ ∐ fun (_ : β) ↦ R` induced by a map `f : α → β`. -/ @[simps! pt] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean index 3a3a473b4a72bd..71bf6910d015d9 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean @@ -29,7 +29,7 @@ namespace isPushout variable (s : PushoutCocone (I.fst default) (I.snd default)) -open Classical in +open scoped Classical in /-- Given a multispan shape `J` which is essentially `.ofLinearOrder ι` (where `ι` has exactly two elements), this is the multicofork deduced from a pushout cocone. -/ diff --git a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean index 1fe915d41331d6..5a9df97b791eff 100644 --- a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean +++ b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean @@ -143,7 +143,7 @@ lemma hφ₀ (B : Set X) (hB : HasCardinalLT B κ₂) {T : Type w} (f : T → B) exact ⟨⟨m B hB C hC, Set.subset_iUnion _ ⟨C, hC⟩ (Or.inr (by simp))⟩, fun t ↦ hm B hB C hC (f t) (hC' (by simp [C₀]))⟩ -open Classical in +open scoped Classical in /-- This coincides with `φ₀` when `HasCardinalLT B κ₂` holds. -/ def φ (B : Set X) : Set X := if hB : HasCardinalLT B κ₂ then φ₀ Y m B hB else B diff --git a/Mathlib/CategoryTheory/Sites/Precoverage/Subsheaf.lean b/Mathlib/CategoryTheory/Sites/Precoverage/Subsheaf.lean index a3e4894680d5dc..2598225e342f7f 100644 --- a/Mathlib/CategoryTheory/Sites/Precoverage/Subsheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Precoverage/Subsheaf.lean @@ -101,7 +101,7 @@ def Witness.eval (hF : ∀ ⦃X : C⦄ (R : Presieve X), R ∈ K X → Presieve. | _, .base X i => t _ i | _, .restrict f i => do F.map f.op (← eval hF _ t i) | _, .amalgamate (R := R) hR h => - open Classical in + open scoped Classical in let vals := fun W (r : W ⟶ _) (hr : R r) ↦ eval hF _ t (h r hr) /- If all elements of the family are evaluatable and the resulting family is compatible, take the glued section. Otherwise, return `none`. -/ diff --git a/Mathlib/Combinatorics/SimpleGraph/Clique.lean b/Mathlib/Combinatorics/SimpleGraph/Clique.lean index 811642e1f0599d..91c10f7adc191f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Clique.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Clique.lean @@ -546,7 +546,7 @@ lemma CliqueFree.mem_of_sup_edge_isNClique {x y : α} {t : Finset α} {n : ℕ} have ht : (t : Set α) \ {x} = t := sdiff_eq_left.mpr <| Set.disjoint_singleton_right.mpr hf exact h t ⟨ht ▸ hc.1.sdiff_of_sup_edge, hc.2⟩ -open Classical in +open scoped Classical in /-- Adding an edge increases the clique number by at most one. -/ protected theorem CliqueFree.sup_edge (h : G.CliqueFree n) (v w : α) : (G ⊔ edge v w).CliqueFree (n + 1) := diff --git a/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean b/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean index 91d1e49c6cc7cd..57c4eb22faeac3 100644 --- a/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean @@ -372,7 +372,7 @@ theorem disjoint : (K.parts : Set (Finset V)).Pairwise Disjoint := /-- The finset of vertices in a complete equipartite subgraph. -/ def verts : Finset V := K.parts.disjiUnion id K.disjoint -open Classical in +open scoped Classical in /-- The finset of vertices in a complete equipartite subgraph as a `biUnion`. -/ lemma verts_eq_biUnion : K.verts = K.parts.biUnion id := by rw [verts, disjiUnion_eq_biUnion] diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean index b8c6c828860f3b..9d0be5b2353ffc 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/Basic.lean @@ -59,7 +59,7 @@ theorem exists_isExtremal_free {W : Type*} {H : SimpleGraph W} (h : H ≠ ⊥) : ∃ G : SimpleGraph V, ∃ _ : DecidableRel G.Adj, G.IsExtremal H.Free := (exists_isExtremal_iff_exists H.Free).mpr ⟨⊥, free_bot h⟩ -open Classical in +open scoped Classical in theorem IsExtremal.le_iff_eq {p : SimpleGraph V → Prop} (hG : G.IsExtremal p) {H : SimpleGraph V} (hH : p H) : G ≤ H ↔ G = H := @@ -70,7 +70,7 @@ end IsExtremal section ExtremalNumber -open Classical in +open scoped Classical in /-- The extremal number of a natural number `n` and a simple graph `H` is the maximum number of edges in a `H`-free simple graph on `n` vertices. @@ -80,7 +80,7 @@ noncomputable def extremalNumber (n : ℕ) {W : Type*} (H : SimpleGraph W) : ℕ variable {n : ℕ} {V W : Type*} {G : SimpleGraph V} {H : SimpleGraph W} -open Classical in +open scoped Classical in theorem extremalNumber_of_fintypeCard_eq [Fintype V] (hc : card V = n) : extremalNumber n H = sup { G : SimpleGraph V | H.Free G } (#·.edgeFinset) := by let e := Fintype.equivFinOfCardEq hc diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean index 234e7a12638587..68c018b1ab8528 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/TuranDensity.lean @@ -140,7 +140,7 @@ theorem eventually_isContained_of_card_edgeFinset (H : SimpleGraph W) {ε : ℝ} exact hcard_edges.trans (mod_cast card_edgeFinset_le_extremalNumber h_free) · exact antitoneOn_extremalNumber_div_choose_two H hm (hm.trans hn) hn -open Classical in +open scoped Classical in /-- The edge density of `H`-free simple graphs on `turanDensityConst H ε` vertices is at most `turanDensity H + ε`. diff --git a/Mathlib/Control/Fix.lean b/Mathlib/Control/Fix.lean index f6d331ffb64602..4553cd46f208ff 100644 --- a/Mathlib/Control/Fix.lean +++ b/Mathlib/Control/Fix.lean @@ -67,7 +67,7 @@ protected def fix (x : α) : Part (β x) := (Part.assert (∃ i, (Fix.approx f i x).Dom)) fun h => WellFounded.fix.{1} (Nat.Upto.wf h) (fixAux f) Nat.Upto.zero x -open Classical in +open scoped Classical in protected theorem fix_def {x : α} (h' : ∃ i, (Fix.approx f i x).Dom) : Part.fix f x = Fix.approx f (Nat.succ (Nat.find h')) x := by let p := fun i : ℕ => (Fix.approx f i x).Dom diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 2b2ed3a0d43935..67dea8abf8c631 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -432,7 +432,7 @@ theorem support_embDomain (f : α ↪ β) (v : α →₀ M) : (embDomain f v).su theorem embDomain_zero (f : α ↪ β) : (embDomain f 0 : β →₀ M) = 0 := rfl -open Classical in +open scoped Classical in @[grind =] theorem embDomain_apply (f : α ↪ β) (v : α →₀ M) (b : β) : embDomain f v b = if h : ∃ a, f a = b then v h.choose else 0 := by diff --git a/Mathlib/Data/Seq/Defs.lean b/Mathlib/Data/Seq/Defs.lean index ccf969fb98ccdb..a7eae2d1ba2b8f 100644 --- a/Mathlib/Data/Seq/Defs.lean +++ b/Mathlib/Data/Seq/Defs.lean @@ -457,7 +457,7 @@ def Terminates (s : Seq α) : Prop := def length (s : Seq α) (h : s.Terminates) : ℕ := Nat.find h -open Classical in +open scoped Classical in /-- The `ENat`-valued length of a sequence. For non-terminating sequences, it is `⊤`. -/ noncomputable def length' (s : Seq α) : ℕ∞ := if h : s.Terminates then s.length h else ⊤ diff --git a/Mathlib/Data/Set/MemPartition.lean b/Mathlib/Data/Set/MemPartition.lean index 137a587b573bb3..55bef6ac416f99 100644 --- a/Mathlib/Data/Set/MemPartition.lean +++ b/Mathlib/Data/Set/MemPartition.lean @@ -108,7 +108,7 @@ noncomputable instance instFintype_memPartition (f : ℕ → Set α) (n : ℕ) : Fintype (memPartition f n) := (finite_memPartition f n).fintype -open Classical in +open scoped Classical in /-- The set in `memPartition f n` to which `a : α` belongs. -/ def memPartitionSet (f : ℕ → Set α) : ℕ → α → Set α | 0 => fun _ ↦ univ diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index 55b85ffa1f09af..7530ef2bb6bb7d 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -281,7 +281,7 @@ lemma eq_bot_of_not_nonempty (hi : ¬ Nonempty (Iio i)) : filtration i = ⊥ := rw [← range_coe] at hi; exact (hi inferInstance).elim · exact bot_unique <| adjoin_le_iff.mpr fun _ ⟨j, hj, _⟩ ↦ (hi ⟨j, coe_lt_coe.mpr hj⟩).elim -open Classical in +open scoped Classical in /-- If `i` is a limit, the type of embeddings of `E⟮ f n x }ᶜ)ᶜ -open Classical in +open scoped Classical in /-- A sequence of measurable functions that are equal to `f` and verify property `p` on the measurable set `aeSeqSet hf p`. -/ noncomputable def aeSeq (hf : ∀ i, AEMeasurable (f i) μ) (p : α → (ι → β) → Prop) : ι → α → β := diff --git a/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean b/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean index 4e7c80eed2058a..094252c2730d14 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean @@ -60,7 +60,7 @@ namespace MeasureTheory variable {Ω : Type*} {mΩ₀ mΩ : MeasurableSpace Ω} {P : Measure[mΩ₀] Ω} {X Y : Ω → ℝ≥0∞} -open Classical in +open scoped Classical in /-- Conditional (Lebesgue) expectation of a function, with notation `P⁻[X|mΩ]`. It is defined as `0` if either `¬ mΩ ≤ mΩ₀` or `hm : mΩ ≤ mΩ₀` but `¬ SigmaFinite (P.trim hm)`. diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean index 1bf1d4daa46fff..74d96d2baebf72 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Defs.lean @@ -143,7 +143,7 @@ and to `essSup ‖f‖ μ` for `p = ∞`. This is well-defined only if `MemLp f p μ`. Otherwise, it equals `0`. -/ noncomputable def lpNorm (f : α → E) (p : ℝ≥0∞) (μ : Measure α) : ℝ := - open Classical in if AEStronglyMeasurable f μ then (eLpNorm f p μ).toReal else 0 + open scoped Classical in if AEStronglyMeasurable f μ then (eLpNorm f p μ).toReal else 0 end Lp diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index 237ae6b34da3f9..02badc202cc9f3 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -672,7 +672,7 @@ class HasFundamentalDomain (G : Type*) (α : Type*) [One G] [SMul G α] [Measura attribute [to_additive existing] MeasureTheory.HasFundamentalDomain -open Classical in +open scoped Classical in /-- The `covolume` of an action of `G` on `α` the volume of some fundamental domain, or `0` if none exists. -/ @[to_additive addCovolume /-- The `addCovolume` of an action of `G` on `α` is the volume of some diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index fab92ef18f6c86..64877fbe3b945b 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -151,7 +151,7 @@ variable [NormedAddCommGroup E] [NormedDivisionRing 𝕜] [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] {G : Type*} [NormedAddCommGroup G] [NormedSpace ℝ G] -open Classical in +open scoped Classical in /-- The Bochner integral -/ irreducible_def integral {_ : MeasurableSpace α} (μ : Measure α) (f : α → G) : G := if _ : CompleteSpace G then diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index bd8c0a097c415a..4dd785826d3770 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -624,7 +624,7 @@ section Function variable {T T' T'' : Set α → E →L[ℝ] F} {C C' C'' : ℝ} {f g : α → E} variable (μ T) -open Classical in +open scoped Classical in /-- Extend `T : Set α → E →L[ℝ] F` to `(α → E) → F` (for integrable functions `α → E`). We set it to 0 if the function is not integrable or if the target space is not complete. -/ def setToFun (hT : DominatedFinMeasAdditive μ T C) (f : α → E) : F := diff --git a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean index c875214a5de081..cdb6f9017c6a3c 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean @@ -138,7 +138,7 @@ section CountablyGeneratedAtom variable {mα : MeasurableSpace α} [CountablyGenerated α] -open Classical in +open scoped Classical in /-- The atoms in a countably generated measurable space. Some of those sets may be empty, but the nonempty ones are the atoms of the measurable space. @@ -175,7 +175,7 @@ lemma mem_countablyGeneratedAtom_natGeneratingSequence (x : α) : x ∈ countablyGeneratedAtom α (x ∈ natGeneratingSequence α ·) := by simp [countablyGeneratedAtom]; grind -open Classical in +open scoped Classical in /-- Any measurable set in a countably generated measurable space can be expressed as a union of atoms. -/ lemma exists_eq_iUnion_countablyGeneratedAtom {s : Set α} (hs : MeasurableSet s) : @@ -391,7 +391,7 @@ theorem exists_countablyGenerated_le_of_countablySeparated [m : MeasurableSpace open Function -open Classical in +open scoped Classical in /-- A map from a measurable space to the Cantor space `ℕ → Bool` induced by a countable sequence of sets generating the measurable space. -/ noncomputable diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index 33747c548193a4..ab6c6ea9a1084a 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -194,7 +194,7 @@ protected theorem MeasurableSet.ite {t s₁ s₂ : Set α} (ht : MeasurableSet t (h₁ : MeasurableSet s₁) (h₂ : MeasurableSet s₂) : MeasurableSet (t.ite s₁ s₂) := (h₁.inter ht).union (h₂.diff ht) -open Classical in +open scoped Classical in theorem MeasurableSet.ite' {s t : Set α} {p : Prop} (hs : p → MeasurableSet s) (ht : ¬p → MeasurableSet t) : MeasurableSet (ite p s t) := by split_ifs with h diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 7d72ab51e1f10c..15d886f920a57e 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -762,13 +762,13 @@ lemma equivRange_symm_apply_mk (hf : MeasurableEmbedding f) (x : α) : /-- The left-inverse of a `MeasurableEmbedding` -/ protected noncomputable def invFun [Nonempty α] (hf : MeasurableEmbedding f) (x : β) : α := - open Classical in + open scoped Classical in if hx : x ∈ range f then hf.equivRange.symm ⟨x, hx⟩ else (Nonempty.some inferInstance) @[fun_prop] lemma measurable_invFun [Nonempty α] (hf : MeasurableEmbedding f) : Measurable (hf.invFun : β → α) := - open Classical in + open scoped Classical in Measurable.dite (by fun_prop) measurable_const hf.measurableSet_range lemma leftInverse_invFun [Nonempty α] (hf : MeasurableEmbedding f) : hf.invFun.LeftInverse f := by diff --git a/Mathlib/MeasureTheory/Measure/Comap.lean b/Mathlib/MeasureTheory/Measure/Comap.lean index a139a84385390e..be9da9dd21bcf1 100644 --- a/Mathlib/MeasureTheory/Measure/Comap.lean +++ b/Mathlib/MeasureTheory/Measure/Comap.lean @@ -32,7 +32,7 @@ namespace Measure variable {α β γ : Type*} {s : Set α} -open Classical in +open scoped Classical in /-- Pullback of a `Measure` as a linear map. If `f` sends each measurable set to a measurable set, then for each measurable set `s` we have `comapₗ f μ s = μ (f '' s)`. @@ -54,7 +54,7 @@ theorem comapₗ_apply {_ : MeasurableSpace α} {_ : MeasurableSpace β} (f : α rw [comapₗ, dif_pos, liftLinear_apply _ hs, OuterMeasure.comap_apply, coe_toOuterMeasure] exact ⟨hfi, hf⟩ -open Classical in +open scoped Classical in /-- Pullback of a `Measure`. If `f` sends each measurable set to a null-measurable set, then for each measurable set `s` we have `comap f μ s = μ (f '' s)`. diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean index f9b70dc62f28a3..0bc097a039a1c1 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean @@ -59,7 +59,7 @@ namespace MeasureTheory variable {α : Type*} {mα : MeasurableSpace α} {μ ν : Measure α} {s t : Set α} -open Classical in +open scoped Classical in /-- A measurable set such that `μ.restrict (μ.sigmaFiniteSetWRT ν)` is sigma-finite and for all measurable sets `t ⊆ sᶜ`, either `ν t = 0` or `μ t = ∞`. -/ def Measure.sigmaFiniteSetWRT (μ ν : Measure α) : Set α := diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean index bc7219a36a8c60..810ec64d0ba490 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean @@ -66,14 +66,14 @@ class HaveLebesgueDecomposition (μ ν : Measure α) : Prop where lebesgue_decomposition : ∃ p : Measure α × (α → ℝ≥0∞), Measurable p.2 ∧ p.1 ⟂ₘ ν ∧ μ = p.1 + ν.withDensity p.2 -open Classical in +open scoped Classical in /-- If a pair of measures `HaveLebesgueDecomposition`, then `singularPart` chooses the measure from `HaveLebesgueDecomposition`, otherwise it returns the zero measure. For sigma-finite measures, `μ = μ.singularPart ν + ν.withDensity (μ.rnDeriv ν)`. -/ noncomputable irreducible_def singularPart (μ ν : Measure α) : Measure α := if h : HaveLebesgueDecomposition μ ν then (Classical.choose h.lebesgue_decomposition).1 else 0 -open Classical in +open scoped Classical in /-- If a pair of measures `HaveLebesgueDecomposition`, then `rnDeriv` chooses the measurable function from `HaveLebesgueDecomposition`, otherwise it returns the zero function. For sigma-finite measures, `μ = μ.singularPart ν + ν.withDensity (μ.rnDeriv ν)`. -/ diff --git a/Mathlib/MeasureTheory/Measure/Map.lean b/Mathlib/MeasureTheory/Measure/Map.lean index fa9fb8055d9343..33fbe530cb5c90 100644 --- a/Mathlib/MeasureTheory/Measure/Map.lean +++ b/Mathlib/MeasureTheory/Measure/Map.lean @@ -67,7 +67,7 @@ theorem le_liftLinear_apply {f : OuterMeasure α →ₗ[ℝ≥0∞] OuterMeasure f μ.toOuterMeasure s ≤ liftLinear f hf μ s := le_toMeasure_apply _ (hf μ) s -open Classical in +open scoped Classical in /-- The pushforward of a measure as a linear map. It is defined to be `0` if `f` is not a measurable function. -/ noncomputable @@ -83,7 +83,7 @@ theorem mapₗ_congr {f g : α → β} (hf : Measurable f) (hg : Measurable g) ( simpa only [mapₗ, hf, hg, hs, dif_pos, liftLinear_apply, OuterMeasure.map_apply] using! measure_congr (h.preimage s) -open Classical in +open scoped Classical in /-- The pushforward of a measure. It is defined to be `0` if `f` is not an almost everywhere measurable function. -/ noncomputable diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean b/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean index b92dd6562f24d7..6218e85fbdea7e 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean @@ -315,7 +315,7 @@ theorem _root_.MeasurableSpace.ae_induction_on_inter end ae -open Classical in +open scoped Classical in /-- A measurable set `t ⊇ s` such that `μ t = μ s`. It even satisfies `μ (t ∩ u) = μ (s ∩ u)` for any measurable set `u` if `μ s ≠ ∞`, see `measure_toMeasurable_inter`. This property holds without the assumption `μ s ≠ ∞` when the space is s-finite (for example diff --git a/Mathlib/MeasureTheory/Measure/PreVariation.lean b/Mathlib/MeasureTheory/Measure/PreVariation.lean index b407ad6c372e07..8a158efc2fcd36 100644 --- a/Mathlib/MeasureTheory/Measure/PreVariation.lean +++ b/Mathlib/MeasureTheory/Measure/PreVariation.lean @@ -47,7 +47,7 @@ section variable (f : Set X → ℝ≥0∞) -open Classical in +open scoped Classical in /-- If `s` is measurable then `preVariationFun f s` is the supremum over partitions `P` of `s` of the quantity `∑ p ∈ P.parts, f p`. If `s` is not measurable then it is set to `0`. -/ noncomputable def preVariationFun (s : Set X) : ℝ≥0∞ := diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index ace2e7cfc59cc5..462e1339e6b361 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -583,7 +583,7 @@ variable {mα : MeasurableSpace α} [MeasurableSpace β] variable {M : Type*} [AddCommMonoid M] [TopologicalSpace M] variable (v : VectorMeasure α M) -open Classical in +open scoped Classical in /-- The pushforward of a vector measure along a function. -/ def map (v : VectorMeasure α M) (f : α → β) : VectorMeasure β M := if hf : Measurable f then @@ -688,7 +688,7 @@ end Module end -open Classical in +open scoped Classical in /-- The restriction of a vector measure on some set. -/ @[no_expose] def restrict (v : VectorMeasure α M) (i : Set α) : VectorMeasure α M := if hi : MeasurableSet i then @@ -1294,7 +1294,7 @@ end MutuallySingular section Trim -open Classical in +open scoped Classical in /-- Restriction of a vector measure onto a sub-σ-algebra. -/ @[simps] def trim {m n : MeasurableSpace α} (v : VectorMeasure α M) (hle : m ≤ n) : diff --git a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean index a6fa2b886b0531..1bbde10a8da904 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean @@ -39,7 +39,7 @@ open TopologicalSpace variable {μ : Measure α} variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] -open Classical in +open scoped Classical in /-- Given a measure `μ` and an integrable function `f`, `μ.withDensityᵥ f` is the vector measure which maps the set `s` to `∫ₛ f ∂μ`. -/ def Measure.withDensityᵥ {m : MeasurableSpace α} (μ : Measure α) (f : α → E) : VectorMeasure α E := diff --git a/Mathlib/NumberTheory/ClassNumber/Finite.lean b/Mathlib/NumberTheory/ClassNumber/Finite.lean index 2c77f086215cd8..c1baf8148b4a8f 100644 --- a/Mathlib/NumberTheory/ClassNumber/Finite.lean +++ b/Mathlib/NumberTheory/ClassNumber/Finite.lean @@ -319,7 +319,7 @@ theorem mkMMem_surjective [IsDedekindDomain S] [Algebra.IsAlgebraic R S] : obtain ⟨J, mk0_eq_mk0, J_dvd⟩ := exists_mk0_eq_mk0 bS adm ⟨I, hI⟩ exact ⟨⟨J, J_dvd⟩, mk0_eq_mk0.symm⟩ -open Classical in +open scoped Classical in /-- The **class number theorem**: the class group of an integral closure `S` of `R` in an algebraic extension `L` is finite if there is an admissible absolute value. diff --git a/Mathlib/NumberTheory/KummerDedekind.lean b/Mathlib/NumberTheory/KummerDedekind.lean index faaa85b2416425..4099b722cfa7a6 100644 --- a/Mathlib/NumberTheory/KummerDedekind.lean +++ b/Mathlib/NumberTheory/KummerDedekind.lean @@ -97,7 +97,7 @@ lemma quotMapEquivQuotQuotMap_symm_apply (hx : (conductor R x).comap (algebraMap simp only [RingEquiv.apply_symm_apply, adjoin.powerBasis'_gen, quotAdjoinEquivQuotMap_apply_mk, coe_aeval_mk_apply] -open Classical in +open scoped Classical in /-- The first half of the **Kummer-Dedekind Theorem**, stating that the prime factors of `I*S` are in bijection with those of the minimal polynomial of the generator of `S` over `R`, taken `mod I`. -/ @@ -130,7 +130,7 @@ theorem emultiplicity_factors_map_eq_emultiplicity IsDedekindDomain.normalizedFactorsEquivOfQuotEquiv_emultiplicity_eq_emultiplicity] set_option backward.isDefEq.respectTransparency false in -open Classical in +open scoped Classical in /-- The **Kummer-Dedekind Theorem**. -/ theorem normalizedFactors_ideal_map_eq_normalizedFactors_min_poly_mk_map (hI : IsMaximal I) (hI' : I ≠ ⊥) (hx : (conductor R x).comap (algebraMap R S) ⊔ I = ⊤) (hx' : IsIntegral R x) : diff --git a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean index cc2bb503cc5b83..c9b77f4253ba06 100644 --- a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean +++ b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean @@ -294,7 +294,7 @@ lemma LSeries_residueClass_eq (ha : IsUnit a) {s : ℂ} (hs : 1 < s.re) : variable (a) -open Classical in +open scoped Classical in /-- The auxiliary function used, e.g., with the Wiener-Ikehara Theorem to prove Dirichlet's Theorem. On `re s > 1`, it agrees with the L-series of the von Mangoldt function restricted to the residue class `a : ZMod q` minus the principal part diff --git a/Mathlib/NumberTheory/ModularForms/Cusps.lean b/Mathlib/NumberTheory/ModularForms/Cusps.lean index 102372815d0acd..3e572abd435718 100644 --- a/Mathlib/NumberTheory/ModularForms/Cusps.lean +++ b/Mathlib/NumberTheory/ModularForms/Cusps.lean @@ -314,7 +314,7 @@ section Real variable (𝒢 : Subgroup (GL (Fin 2) ℝ)) -open Classical in +open scoped Classical in /-- The strict width of the cusp `∞`, i.e. the `x` such that `𝒢.strictPeriods = zmultiples x`, or 0 if no such `x` exists. -/ noncomputable def strictWidthInfty : ℝ := diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index 928a5fbe2c5dfc..e53507c24b94d7 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -226,11 +226,11 @@ open MeasureTheory.Measure MeasureTheory variable [NumberField K] -open Classical in +open scoped Classical in instance : IsAddHaarMeasure (volume : Measure (mixedSpace K)) := prod.instIsAddHaarMeasure volume volume -open Classical in +open scoped Classical in instance : NullSingletonClass (volume : Measure (mixedSpace K)) := by obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K)) by_cases hw : IsReal w @@ -242,7 +242,7 @@ instance : NullSingletonClass (volume : Measure (mixedSpace K)) := by exact prod.instNullSingletonClass_snd variable {K} in -open Classical in +open scoped Classical in /-- The set of points in the mixedSpace that are equal to `0` at a fixed (real) place has volume zero. -/ theorem volume_eq_zero (w : {w // IsReal w}) : @@ -675,12 +675,12 @@ instance : DiscreteTopology (mixedEmbedding.integerLattice K) := by rw [← span_latticeBasis] infer_instance -open Classical in +open scoped Classical in instance : IsZLattice ℝ (mixedEmbedding.integerLattice K) := by simp_rw [← span_latticeBasis] infer_instance -open Classical in +open scoped Classical in theorem fundamentalDomain_integerLattice : MeasureTheory.IsAddFundamentalDomain (mixedEmbedding.integerLattice K) (ZSpan.fundamentalDomain (latticeBasis K)) := by @@ -788,12 +788,12 @@ instance : DiscreteTopology (mixedEmbedding.idealLattice K I) := by rw [← span_idealLatticeBasis] infer_instance -open Classical in +open scoped Classical in instance : IsZLattice ℝ (mixedEmbedding.idealLattice K I) := by simp_rw [← span_idealLatticeBasis] infer_instance -open Classical in +open scoped Classical in theorem fundamentalDomain_idealLattice : MeasureTheory.IsAddFundamentalDomain (mixedEmbedding.idealLattice K I) (ZSpan.fundamentalDomain (fractionalIdealLatticeBasis K I)) := by @@ -820,7 +820,7 @@ instance : Ring (euclidean.mixedSpace K) := variable [NumberField K] -open Classical in +open scoped Classical in /-- The continuous linear equivalence between the Euclidean mixed space and the mixed space. -/ def toMixed : (euclidean.mixedSpace K) ≃L[ℝ] (mixedSpace K) := (WithLp.linearEquiv _ _ _).trans @@ -832,19 +832,19 @@ protected theorem finrank : finrank ℝ (euclidean.mixedSpace K) = finrank ℚ K := by rw [LinearEquiv.finrank_eq (toMixed K).toLinearEquiv, mixedEmbedding.finrank] -open Classical in +open scoped Classical in /-- An orthonormal basis of the Euclidean mixed space. -/ def stdOrthonormalBasis : OrthonormalBasis (index K) ℝ (euclidean.mixedSpace K) := OrthonormalBasis.prod (EuclideanSpace.basisFun _ ℝ) ((Pi.orthonormalBasis fun _ ↦ Complex.orthonormalBasisOneI).reindex (Equiv.sigmaEquivProd _ _)) -open Classical in +open scoped Classical in theorem stdOrthonormalBasis_map_eq : (euclidean.stdOrthonormalBasis K).toBasis.map (toMixed K).toLinearEquiv = mixedEmbedding.stdBasis K := by ext <;> rfl -open Classical in +open scoped Classical in theorem volumePreserving_toMixed : MeasurePreserving (toMixed K) where measurable := (toMixed K).continuous.measurable @@ -854,13 +854,13 @@ theorem volumePreserving_toMixed : ← measure_congr (ZSpan.fundamentalDomain_ae_parallelepiped (stdBasis K) volume), volume_fundamentalDomain_stdBasis K] -open Classical in +open scoped Classical in theorem volumePreserving_toMixed_symm : MeasurePreserving (toMixed K).symm := by have : MeasurePreserving (toMixed K).toHomeomorph.toMeasurableEquiv := volumePreserving_toMixed K exact this.symm -open Classical in +open scoped Classical in /-- The image of ring of integers `𝓞 K` in the Euclidean mixed space. -/ protected def integerLattice : Submodule ℤ (euclidean.mixedSpace K) := ZLattice.comap ℝ (mixedEmbedding.integerLattice K) (toMixed K).toLinearMap @@ -870,7 +870,7 @@ instance : DiscreteTopology (euclidean.integerLattice K) := by rw [euclidean.integerLattice] infer_instance -open Classical in +open scoped Classical in instance : IsZLattice ℝ (euclidean.integerLattice K) := by simp_rw [euclidean.integerLattice] infer_instance @@ -885,7 +885,7 @@ open ContinuousLinearEquiv variable {K} (s : Set {w : InfinitePlace K // IsReal w}) -open Classical in +open scoped Classical in /-- Let `s` be a set of real places, define the continuous linear equiv of the mixed space that swaps sign at places in `s` and leaves the rest unchanged. -/ def negAt : @@ -1049,7 +1049,7 @@ open MeasureTheory variable [NumberField K] include hA in -open Classical in +open scoped Classical in theorem iUnion_negAt_plusPart_ae : ⋃ s, negAt s '' (plusPart A) =ᵐ[volume] A := by nth_rewrite 2 [← iUnion_negAt_plusPart_union A hA] @@ -1072,7 +1072,7 @@ theorem measurableSet_negAt_plusPart (hm : MeasurableSet A) : variable {A} -open Classical in +open scoped Classical in /-- The image of the `plusPart` of `A` by `negAt` have all the same volume as `plusPart A`. -/ theorem volume_negAt_plusPart (hm : MeasurableSet A) : volume (negAt s '' (plusPart A)) = volume (plusPart A) := by @@ -1080,7 +1080,7 @@ theorem volume_negAt_plusPart (hm : MeasurableSet A) : volume_preserving_negAt.measure_preimage (measurableSet_plusPart hm).nullMeasurableSet] include hA in -open Classical in +open scoped Classical in /-- If a subset `A` of the `mixedSpace` is symmetric at real places, then its volume is `2^ nrRealPlaces K` times the volume of its `plusPart`. -/ theorem volume_eq_two_pow_mul_volume_plusPart (hm : MeasurableSet A) : diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean index 0c477d92a57d5e..9958e44ebcd81e 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean @@ -172,7 +172,7 @@ open NumberField.Units NumberField.Units.dirichletUnitTheorem variable [NumberField K] -open Classical in +open scoped Classical in /-- The fundamental cone is a cone in the mixed space, i.e. a subset fixed by multiplication by a nonzero real number, see `smul_mem_of_mem`, that is also a fundamental domain for the action of `(𝓞 K)ˣ` modulo torsion, see `exists_unit_smul_mem` and `torsion_smul_mem_of_mem`. -/ diff --git a/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean b/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean index f5c1ec7899c81e..e149e1a95598ba 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean @@ -52,7 +52,7 @@ private theorem tendsto_norm_le_and_mk_eq_div_atTop_aux₁ (hJ : ClassGroup.mk0 exact fun _ ↦ (mul_le_mul_iff_of_pos_left (Nat.cast_pos.mpr (absNorm_pos_of_nonZeroDivisors J))).symm -open Classical in +open scoped Classical in private def tendsto_norm_le_and_mk_eq_div_atTop_aux₂ : ↑({x | x ∈ (toMixed K) ⁻¹' fundamentalCone K ∧ mixedEmbedding.norm ((toMixed K) x) ≤ s} ∩ (ZLattice.comap ℝ (idealLattice K ((FractionalIdeal.mk0 K) J)) (toMixed K).toLinearMap)) diff --git a/Mathlib/NumberTheory/Padics/PadicNumbers.lean b/Mathlib/NumberTheory/Padics/PadicNumbers.lean index a01f31fae82778..0308dc88ff0d0c 100644 --- a/Mathlib/NumberTheory/Padics/PadicNumbers.lean +++ b/Mathlib/NumberTheory/Padics/PadicNumbers.lean @@ -204,7 +204,7 @@ theorem stationaryPoint_spec {f : PadicSeq p} (hf : ¬f ≈ 0) : stationaryPoint hf ≤ m → stationaryPoint hf ≤ n → padicNorm p (f n) = padicNorm p (f m) := @(Classical.choose_spec <| stationary hf) -open Classical in +open scoped Classical in /-- Since the norm of the entries of a Cauchy sequence is eventually stationary, we can lift the norm to sequences. -/ def norm (f : PadicSeq p) : ℚ := @@ -295,7 +295,7 @@ variable {p : ℕ} [Fact p.Prime] /-! ### Valuation on `PadicSeq` -/ -open Classical in +open scoped Classical in /-- The `p`-adic valuation on `ℚ` lifts to `PadicSeq p`. `Valuation f` is defined to be the valuation of the (`ℚ`-valued) stationary point of `f`. -/ def valuation (f : PadicSeq p) : ℤ := @@ -1135,7 +1135,7 @@ lemma valuation_zpow (x : ℚ_[p]) : ∀ n : ℤ, (x ^ n).valuation = n * x.valu | (n : ℕ) => by simp | .negSucc n => by simp [← neg_mul]; simp [Int.negSucc_eq] -open Classical in +open scoped Classical in /-- The additive `p`-adic valuation on `ℚ_[p]`, with values in `WithTop ℤ`. -/ def addValuationDef : ℚ_[p] → WithTop ℤ := fun x ↦ if x = 0 then ⊤ else x.valuation @@ -1175,7 +1175,7 @@ theorem AddValuation.map_add (x y : ℚ_[p]) : open WithZero -open Classical in +open scoped Classical in /-- The `p`-adic valuation on `ℚ_[p]`, as a `Valuation`, bundled `Padic.valuation`. -/ @[simps] noncomputable def mulValuation : Valuation ℚ_[p] ℤᵐ⁰ where diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index b91cbff332c5ee..626c404ca544a2 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -898,7 +898,7 @@ end DecidableEq variable [Lattice α] [BoundedOrder α] [IsSimpleOrder α] -open Classical in +open scoped Classical in /-- A simple `BoundedOrder` is also complete. -/ @[implicit_reducible] protected noncomputable def completeLattice : CompleteLattice α := @@ -927,7 +927,7 @@ protected noncomputable def completeLattice : CompleteLattice α := intro con exact top_ne_bot (eq_bot_iff.2 (h con)) } -open Classical in +open scoped Classical in /-- A simple `BoundedOrder` is also a `CompleteBooleanAlgebra`. -/ @[implicit_reducible] protected noncomputable def completeBooleanAlgebra : CompleteBooleanAlgebra α := diff --git a/Mathlib/Order/Birkhoff.lean b/Mathlib/Order/Birkhoff.lean index 30a8b437d88295..695f6178b8b6b3 100644 --- a/Mathlib/Order/Birkhoff.lean +++ b/Mathlib/Order/Birkhoff.lean @@ -184,7 +184,7 @@ end OrderIso section DistribLattice variable [DistribLattice α] [Fintype α] [@DecidablePred α SupIrred] -open Classical in +open scoped Classical in /-- **Birkhoff Representation for finite distributive lattices**. Any nonempty finite distributive lattice is isomorphic to the lattice of lower sets of its sup-irreducible elements. -/ noncomputable def OrderIso.lowerSetSupIrred [OrderBot α] : α ≃o LowerSet {a : α // SupIrred a} := @@ -262,7 +262,7 @@ noncomputable def birkhoffSet : LatticeHom α (Set {a : α // SupIrred a}) where map_sup' := OrderEmbedding.birkhoffSet_sup map_inf' := OrderEmbedding.birkhoffSet_inf -open Classical in +open scoped Classical in /-- **Birkhoff's Representation Theorem**. Any finite distributive lattice can be embedded in a powerset lattice. -/ noncomputable def birkhoffFinset : LatticeHom α (Finset {a : α // SupIrred a}) where diff --git a/Mathlib/Order/CompleteLatticeIntervals.lean b/Mathlib/Order/CompleteLatticeIntervals.lean index 410bdf8aa0da86..916a55e0b0d96a 100644 --- a/Mathlib/Order/CompleteLatticeIntervals.lean +++ b/Mathlib/Order/CompleteLatticeIntervals.lean @@ -34,7 +34,7 @@ section SupSet variable [Preorder α] [SupSet α] -open Classical in +open scoped Classical in /-- `SupSet` structure on a nonempty subset `s` of a preorder with `SupSet`. This definition is non-canonical (it uses `default s`); it should be used only as here, as an auxiliary instance in the construction of the `ConditionallyCompleteLinearOrder` structure. -/ @@ -47,7 +47,7 @@ noncomputable def subsetSupSet [Inhabited s] : SupSet s where attribute [local instance] subsetSupSet -open Classical in +open scoped Classical in @[simp] theorem subset_sSup_def [Inhabited s] : @sSup s _ = fun t => @@ -74,7 +74,7 @@ section InfSet variable [Preorder α] [InfSet α] -open Classical in +open scoped Classical in /-- `InfSet` structure on a nonempty subset `s` of a preorder with `InfSet`. This definition is non-canonical (it uses `default s`); it should be used only as here, as an auxiliary instance in the construction of the `ConditionallyCompleteLinearOrder` structure. -/ @@ -87,7 +87,7 @@ noncomputable def subsetInfSet [Inhabited s] : InfSet s where attribute [local instance] subsetInfSet -open Classical in +open scoped Classical in @[simp] theorem subset_sInf_def [Inhabited s] : @sInf s _ = fun t => diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index 70cd9673351c01..fc72050567fcc3 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -45,7 +45,7 @@ Extension of `sSup` and `sInf` from a preorder `α` to `WithTop α` and `WithBot variable [LE α] -open Classical in +open scoped Classical in @[to_dual] noncomputable instance WithTop.instSupSet [SupSet α] : SupSet (WithTop α) := @@ -53,7 +53,7 @@ noncomputable instance WithTop.instSupSet [SupSet α] : if ⊤ ∈ S then ⊤ else if BddAbove ((fun (a : α) ↦ ↑a) ⁻¹' S : Set α) then ↑(sSup ((fun (a : α) ↦ (a : WithTop α)) ⁻¹' S : Set α)) else ⊤⟩ -open Classical in +open scoped Classical in @[to_dual] noncomputable instance WithTop.instInfSet [InfSet α] : InfSet (WithTop α) := ⟨fun S => if S ⊆ {⊤} ∨ ¬BddBelow S then ⊤ else ↑(sInf ((fun (a : α) ↦ ↑a) ⁻¹' S : Set α))⟩ @@ -954,7 +954,7 @@ noncomputable instance [ConditionallyCompleteLinearOrder α] : csInf_of_not_bddBelow s := absurd <| OrderBot.bddBelow s csSup_empty := WithBot.sSup_empty -open Classical in +open scoped Classical in noncomputable instance WithTop.WithBot.completeLattice {α : Type*} [ConditionallyCompleteLattice α] : CompleteLattice (WithTop (WithBot α)) where isLUB_sSup S := ⟨fun a haS ↦ (WithTop.isLUB_sSup' ⟨a, haS⟩).1 haS, fun a ha ↦ by diff --git a/Mathlib/Order/Filter/FilterProduct.lean b/Mathlib/Order/Filter/FilterProduct.lean index e77219d949f83f..cb45944cb31856 100644 --- a/Mathlib/Order/Filter/FilterProduct.lean +++ b/Mathlib/Order/Filter/FilterProduct.lean @@ -87,7 +87,7 @@ instance total [LE β] [@Std.Total β (· ≤ ·)] : @Std.Total β* (· ≤ ·) ⟨fun f g => inductionOn₂ f g fun _f _g => eventually_or.1 <| Eventually.of_forall fun _x => total_of _ _ _⟩ -open Classical in +open scoped Classical in /-- If `φ` is an ultrafilter then the ultraproduct is a linear order. -/ noncomputable instance instLinearOrder [LinearOrder β] : LinearOrder β* := Lattice.toLinearOrder _ diff --git a/Mathlib/Order/InitialSeg.lean b/Mathlib/Order/InitialSeg.lean index 8566d4824c3c84..cdceff71584bf1 100644 --- a/Mathlib/Order/InitialSeg.lean +++ b/Mathlib/Order/InitialSeg.lean @@ -473,7 +473,7 @@ theorem wellFounded_iff_principalSeg {β : Type u} {s : β → β → Prop} [IsT namespace InitialSeg -open Classical in +open scoped Classical in /-- Every initial segment embedding into a well order can be turned into an isomorphism if surjective, or into a principal segment embedding if not. -/ noncomputable def principalSumRelIso [IsWellOrder β s] (f : r ≼i s) : (r ≺i s) ⊕ (r ≃r s) := diff --git a/Mathlib/Order/Interval/Basic.lean b/Mathlib/Order/Interval/Basic.lean index eba4f95c6109a1..e2dcf378650041 100644 --- a/Mathlib/Order/Interval/Basic.lean +++ b/Mathlib/Order/Interval/Basic.lean @@ -601,7 +601,7 @@ section CompleteLattice variable [CompleteLattice α] -open Classical in +open scoped Classical in noncomputable instance completeLattice [DecidableLE α] : CompleteLattice (Interval α) where sSup := fun S => if h : S ⊆ {⊥} then ⊥ diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index d723c5a5569ee3..cdae22417057be 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -971,7 +971,7 @@ theorem gt_mem_sets_of_limsInf_gt : f.IsBounded (· ≥ ·) → b < f.limsInf section Classical -open Classical in +open scoped Classical in /-- Given an indexed family of sets `s j` over `j : Subtype p` and a function `f`, then `liminf_reparam j` is equal to `j` if `f` is bounded below on `s j`, and otherwise to some index `k` such that `f` is bounded below on `s k` (if there exists one). @@ -1031,7 +1031,7 @@ theorem HasBasis.liminf_eq_ciSup_ciInf {v : Filter ι} · exact (hZ j0 hj0).elim simp_rw [hv.liminf_eq_sSup_iUnion_iInter, A, B, sSup_iUnion_Iic] -open Classical in +open scoped Classical in /-- Writing a liminf as a supremum of infimum, in a (possibly non-complete) conditionally complete linear order. A reparametrization trick is needed to avoid taking the infimum of sets which are not bounded below. -/ @@ -1077,7 +1077,7 @@ theorem HasBasis.limsup_eq_ciInf_ciSup {v : Filter ι} limsup f v = ⨅ (j : Subtype p), ⨆ (i : s (limsup_reparam f s p j)), f i := HasBasis.liminf_eq_ciSup_ciInf (α := αᵒᵈ) hv hs H -open Classical in +open scoped Classical in /-- Writing a limsup as an infimum of supremum, in a (possibly non-complete) conditionally complete linear order. A reparametrization trick is needed to avoid taking the supremum of sets which are not bounded below. -/ diff --git a/Mathlib/Order/NonemptyFiniteChains.lean b/Mathlib/Order/NonemptyFiniteChains.lean index 2ed532433c3c8a..9e1a91832dba42 100644 --- a/Mathlib/Order/NonemptyFiniteChains.lean +++ b/Mathlib/Order/NonemptyFiniteChains.lean @@ -51,7 +51,7 @@ lemma le_iff (A B : NonemptyFiniteChains X) : A ≤ B ↔ A.finset ≤ B.finset @[simp] lemma lt_iff (A B : NonemptyFiniteChains X) : A < B ↔ A.finset < B.finset := Iff.rfl -open Classical in +open scoped Classical in /-- The image of a nonempty finite chain by a monotone map. -/ noncomputable def map (s : NonemptyFiniteChains X) (f : X →o Y) : NonemptyFiniteChains Y where diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 00e009dec771ec..d5913f103a73f3 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -332,7 +332,7 @@ theorem eq_of_chain {c : Chain (Part α)} {a b : α} (ha : some a ∈ c) (hb : s · have := c.monotone hij _ ha; apply mem_unique this hb · have := c.monotone hji _ hb; apply Eq.symm; apply mem_unique this ha -open Classical in +open scoped Classical in /-- The (noncomputable) `ωSup` definition for the `ω`-CPO structure on `Part α`. -/ protected noncomputable def ωSup (c : Chain (Part α)) : Part α := if h : ∃ a, some a ∈ c then some (Classical.choose h) else none diff --git a/Mathlib/Order/Preorder/Chain.lean b/Mathlib/Order/Preorder/Chain.lean index 570324303c31af..ac24fba1fc51b0 100644 --- a/Mathlib/Order/Preorder/Chain.lean +++ b/Mathlib/Order/Preorder/Chain.lean @@ -289,7 +289,7 @@ protected theorem IsMaxChain.nonempty_iff (h : IsMaxChain r s) : Nonempty α ↔ theorem IsMaxChain.symm (h : IsMaxChain r s) : IsMaxChain (flip r) s := ⟨h.isChain.symm, fun _ ht₁ ht₂ ↦ h.2 ht₁.symm ht₂⟩ -open Classical in +open scoped Classical in /-- Given a set `s`, if there exists a chain `t` strictly including `s`, then `SuccChain s` is one of these chains. Otherwise it is `s`. -/ def SuccChain (r : α → α → Prop) (s : Set α) : Set α := @@ -300,10 +300,10 @@ theorem succChain_spec (h : ∃ t, IsChain r s ∧ SuperChain r s t) : have : IsChain r s ∧ SuperChain r s h.choose := h.choose_spec simpa [SuccChain, dif_pos, exists_and_left.mp h] using this.2 -theorem IsChain.succ (hs : IsChain r s) : IsChain r (SuccChain r s) := - open Classical in - if h : ∃ t, IsChain r s ∧ SuperChain r s t then (succChain_spec h).1 - else by +theorem IsChain.succ (hs : IsChain r s) : IsChain r (SuccChain r s) := by + classical + if h : ∃ t, IsChain r s ∧ SuperChain r s t then exact (succChain_spec h).1 + else rw [exists_and_left] at h simpa [SuccChain, dif_neg, h] using hs @@ -313,10 +313,10 @@ theorem IsChain.superChain_succChain (hs₁ : IsChain r s) (hs₂ : ¬IsMaxChain obtain ⟨t, ht, hst⟩ := hs₂ hs₁ exact succChain_spec ⟨t, hs₁, ht, ssubset_iff_subset_ne.2 hst⟩ -theorem subset_succChain : s ⊆ SuccChain r s := - open Classical in - if h : ∃ t, IsChain r s ∧ SuperChain r s t then (succChain_spec h).2.1 - else by +theorem subset_succChain : s ⊆ SuccChain r s := by + classical + if h : ∃ t, IsChain r s ∧ SuperChain r s t then exact (succChain_spec h).2.1 + else simp [SuccChain, h] end Chain diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index 09e339e37e4153..6df98882f1c222 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -319,7 +319,7 @@ def toWellFoundedRelation : WellFoundedRelation α := end WellFoundedLT -open Classical in +open scoped Classical in /-- Construct a decidable linear order from a well-founded linear order. -/ @[implicit_reducible] noncomputable def IsWellOrder.linearOrder (r : α → α → Prop) [IsWellOrder α r] : LinearOrder α := diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 22ecaf6f743fb5..916cc1ecc3d6f6 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -110,7 +110,7 @@ def SuccOrder.ofCore (succ : α → α) (hn : ∀ {a}, ¬IsMax a → ∀ b, a < variable (α) -open Classical in +open scoped Classical in /-- A well-order is a `SuccOrder`. -/ @[to_dual (attr := implicit_reducible) /-- A linear order with well-founded greater-than relation is a `PredOrder`. -/] diff --git a/Mathlib/Order/SuccPred/Limit.lean b/Mathlib/Order/SuccPred/Limit.lean index fc659e09113f72..3a2a4e7fefc3c9 100644 --- a/Mathlib/Order/SuccPred/Limit.lean +++ b/Mathlib/Order/SuccPred/Limit.lean @@ -560,7 +560,7 @@ variable [PartialOrder α] [SuccOrder α] (succ : ∀ a, ¬IsMax a → motive (succ a)) (isSuccPrelimit : ∀ a, IsSuccPrelimit a → motive a) variable (b) in -open Classical in +open scoped Classical in /-- A value can be built by building it on successors and successor pre-limits. -/ @[to_dual (attr := elab_as_elim) /-- A value can be built by building it on predecessors and predecessor pre-limits. -/] @@ -608,7 +608,7 @@ variable [PartialOrder α] [SuccOrder α] (isSuccLimit : ∀ a, IsSuccLimit a → motive a) variable (b) in -open Classical in +open scoped Classical in /-- A value can be built by building it on minimal elements, successors, and successor limits. -/ @[to_dual (attr := elab_as_elim) @@ -666,7 +666,7 @@ variable [PartialOrder α] [SuccOrder α] [WellFoundedLT α] (isSuccPrelimit : ∀ a, IsSuccPrelimit a → (∀ b < a, motive b) → motive a) variable (b) in -open Classical in +open scoped Classical in /-- Recursion principle on a well-founded partial `SuccOrder`. -/ @[to_dual (attr := elab_as_elim) /-- Recursion principle on a well-founded partial `PredOrder`. -/] @@ -721,7 +721,7 @@ variable [PartialOrder α] [SuccOrder α] [WellFoundedLT α] (isMin : ∀ a, IsM (isSuccLimit : ∀ a, IsSuccLimit a → (∀ b < a, motive b) → motive a) variable (b) in -open Classical in +open scoped Classical in /-- Recursion principle on a well-founded partial `SuccOrder`, separating out the case of a minimal element. -/ @[to_dual (attr := elab_as_elim) diff --git a/Mathlib/Probability/Kernel/Composition/MapComap.lean b/Mathlib/Probability/Kernel/Composition/MapComap.lean index d639924e23fab4..7606bd9421d80c 100644 --- a/Mathlib/Probability/Kernel/Composition/MapComap.lean +++ b/Mathlib/Probability/Kernel/Composition/MapComap.lean @@ -55,7 +55,7 @@ noncomputable def mapOfMeasurable (κ : Kernel α β) (f : β → γ) (hf : Meas toFun a := (κ a).map f measurable' := by fun_prop -open Classical in +open scoped Classical in /-- The pushforward of a kernel along a function. If the function is not measurable, we use zero instead. This choice of junk value ensures that typeclass inference can infer that the `map` of a kernel diff --git a/Mathlib/Probability/Kernel/Composition/ParallelComp.lean b/Mathlib/Probability/Kernel/Composition/ParallelComp.lean index 401a797032a819..37945ad527781c 100644 --- a/Mathlib/Probability/Kernel/Composition/ParallelComp.lean +++ b/Mathlib/Probability/Kernel/Composition/ParallelComp.lean @@ -40,7 +40,7 @@ variable {α β γ δ : Type*} {mα : MeasurableSpace α} {mβ : MeasurableSpace {mγ : MeasurableSpace γ} {mδ : MeasurableSpace δ} {κ : Kernel α β} {η : Kernel γ δ} {x : α × γ} -open Classical in +open scoped Classical in /-- Parallel product of two kernels. -/ noncomputable irreducible_def parallelComp (κ : Kernel α β) (η : Kernel γ δ) : Kernel (α × γ) (β × δ) := diff --git a/Mathlib/Probability/Kernel/Condexp.lean b/Mathlib/Probability/Kernel/Condexp.lean index b78cd01bb370b5..264ccaece12745 100644 --- a/Mathlib/Probability/Kernel/Condexp.lean +++ b/Mathlib/Probability/Kernel/Condexp.lean @@ -61,7 +61,7 @@ end AuxLemmas variable {Ω F : Type*} {m : MeasurableSpace Ω} [mΩ : MeasurableSpace Ω] [StandardBorelSpace Ω] {μ : Measure Ω} [IsFiniteMeasure μ] -open Classical in +open scoped Classical in /-- Kernel associated with the conditional expectation with respect to a σ-algebra. It satisfies `μ[f | m] =ᵐ[μ] fun ω => ∫ y, f y ∂(condExpKernel μ m ω)`. It is defined as the conditional distribution of the identity given the identity, where the second diff --git a/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean b/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean index 3e1dc035eb1258..95537e43dcba81 100644 --- a/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean @@ -173,7 +173,7 @@ section BorelSnd Since every standard Borel space embeds measurably into `ℝ`, we can generalize a disintegration property on `ℝ` to all these spaces. -/ -open Classical in +open scoped Classical in /-- Auxiliary definition for `ProbabilityTheory.Kernel.condKernel`. A Borel space `Ω` embeds measurably into `ℝ` (with embedding `e`), hence we can get a `Kernel α Ω` from a `Kernel α ℝ` by taking the comap by `e`. @@ -396,7 +396,7 @@ end Measure section CountableOrCountablyGenerated variable [h : CountableOrCountablyGenerated α β] (κ : Kernel α (β × Ω)) [IsFiniteKernel κ] -open Classical in +open scoped Classical in /-- Conditional kernel of a kernel `κ : Kernel α (β × Ω)`: a Markov kernel such that `fst κ ⊗ₖ condKernel κ = κ` (see `MeasureTheory.Measure.compProd_fst_condKernel`). It exists whenever `Ω` is standard Borel and either `α` is countable diff --git a/Mathlib/Probability/Kernel/RadonNikodym.lean b/Mathlib/Probability/Kernel/RadonNikodym.lean index 4f4fe581f4b154..37e2a38b4c4336 100644 --- a/Mathlib/Probability/Kernel/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/RadonNikodym.lean @@ -81,7 +81,7 @@ namespace ProbabilityTheory.Kernel variable {α γ : Type*} {mα : MeasurableSpace α} {mγ : MeasurableSpace γ} {κ η : Kernel α γ} [hαγ : MeasurableSpace.CountableOrCountablyGenerated α γ] -open Classical in +open scoped Classical in /-- Auxiliary function used to define `ProbabilityTheory.Kernel.rnDeriv` and `ProbabilityTheory.Kernel.singularPart`. diff --git a/Mathlib/Probability/Moments/CovarianceBilinDual.lean b/Mathlib/Probability/Moments/CovarianceBilinDual.lean index af82b04e46905b..e3ffb10125ba32 100644 --- a/Mathlib/Probability/Moments/CovarianceBilinDual.lean +++ b/Mathlib/Probability/Moments/CovarianceBilinDual.lean @@ -53,7 +53,7 @@ section LinearMap variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 E] -open Classical in +open scoped Classical in /-- Linear map from the dual to `Lp` equal to `MemLp.toLp` if `MemLp id p μ` and to 0 otherwise. -/ noncomputable def toLpₗ (μ : Measure E) (p : ℝ≥0∞) : diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index 573b3b0fe62ad9..f4b52ff1919234 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -574,13 +574,13 @@ variable {R : Type*} [CommRing R] [IsDomain R] [IsDiscreteValuationRing R] two steps to terminate. Given `GCD(x,y)`, if `x ∣ y` then `y%x = 0` so we're done in one step; otherwise `y%x = y` and then `GCD(x,y) = GCD(y,x)` which brings us back to the first case. -/ def quotient (x y : R) : R := - open Classical in if y = 0 then 0 else if h : y ∣ x then h.choose else 0 + open scoped Classical in if y = 0 then 0 else if h : y ∣ x then h.choose else 0 /-- A noncomputable remainder to define the Euclidean domain structure. The GCD algorithm only takes two steps to terminate. Given `GCD(x,y)`, if `x ∣ y` then `y%x = 0` so we're done in one step; otherwise `y%x = y` and then `GCD(x,y) = GCD(y,x)` which brings us back to the first case. -/ def remainder (x y : R) : R := - open Classical in if y ∣ x then 0 else x + open scoped Classical in if y ∣ x then 0 else x /-- A modification of the valuation, sending `0` to `⊥` instead of `⊤`. -/ def toWithBotNat (x : R) : WithBot ℕ := diff --git a/Mathlib/RingTheory/DividedPowers/Basic.lean b/Mathlib/RingTheory/DividedPowers/Basic.lean index 056b259b042d3d..ed93b1f1f92b75 100644 --- a/Mathlib/RingTheory/DividedPowers/Basic.lean +++ b/Mathlib/RingTheory/DividedPowers/Basic.lean @@ -94,7 +94,7 @@ structure DividedPowers where variable (A) in /-- The canonical `DividedPowers` structure on the zero ideal -/ noncomputable def dividedPowersBot : DividedPowers (⊥ : Ideal A) where - dpow n a := open Classical in ite (a = 0 ∧ n = 0) 1 0 + dpow n a := open scoped Classical in ite (a = 0 ∧ n = 0) 1 0 dpow_null {n a} ha := by simp only [mem_bot] at ha rw [if_neg] diff --git a/Mathlib/RingTheory/DividedPowers/Padic.lean b/Mathlib/RingTheory/DividedPowers/Padic.lean index bc8abcc6e1c6b7..3c5c3bd9f30b60 100644 --- a/Mathlib/RingTheory/DividedPowers/Padic.lean +++ b/Mathlib/RingTheory/DividedPowers/Padic.lean @@ -41,7 +41,7 @@ noncomputable def DividedPowers.ofInjective (f : A →+* B) (hf : Injective f) (hJ : DividedPowers J) (hIJ : I.map f = J) (hmem : ∀ (n : ℕ) {x : A} (_ : x ∈ I), ∃ (y : A) (_ : n ≠ 0 → y ∈ I), f y = hJ.dpow n (f x)) : DividedPowers I where - dpow n x := open Classical in if hx : x ∈ I then Exists.choose (hmem n hx) else 0 + dpow n x := open scoped Classical in if hx : x ∈ I then Exists.choose (hmem n hx) else 0 dpow_null hx := by simp [dif_neg hx] dpow_zero {x} hx := by simp only [dif_pos hx, ← hf.eq_iff, (Exists.choose_spec (hmem 0 hx)).2, map_one] @@ -153,7 +153,7 @@ noncomputable def dividedPowers : DividedPowers (Ideal.span {(p : ℤ_[p])}) := open Function private lemma dividedPowers_eq (n : ℕ) (x : ℤ_[p]) : - (dividedPowers p).dpow n x = open Classical in + (dividedPowers p).dpow n x = open scoped Classical in if hx : x ∈ Ideal.span {(p : ℤ_[p])} then ⟨dpow' p n x, dpow'_int p n hx⟩ else 0 := by simp only [dividedPowers, ofInjective] split_ifs with hx @@ -167,7 +167,7 @@ private lemma dividedPowers_eq (n : ℕ) (x : ℤ_[p]) : · rfl lemma coe_dpow_eq (n : ℕ) (x : ℤ_[p]) : - ((dividedPowers p).dpow n x : ℚ_[p]) = open Classical in + ((dividedPowers p).dpow n x : ℚ_[p]) = open scoped Classical in if _ : x ∈ Ideal.span {(p : ℤ_[p])} then inverse (n ! : ℚ_[p]) * x ^ n else 0 := by simp only [dividedPowers_eq, dpow', inverse_eq_inv', dite_eq_ite] split_ifs <;> simp diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index 65073da77e4edd..9bb832bfc24773 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -97,7 +97,7 @@ instance : IsLocalization.Away D.gbar S := by rw [← map_one (algebraMap P.Ring S), ← sub_eq_zero, ← map_sub, ← RingHom.mem_ker] exact D.hgmem -open Classical in +open scoped Classical in /-- The "naive" presentation of `T = R[X₁, ..., Xₙ] / (b₁, ..., bᵣ)` over `R`. We make sure the section `T → R[X₁, ..., Xₙ]` maps `-1` to `-1` and `0` to `0`. -/ def presLeft : Presentation R D.T ι σ := diff --git a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean index 956fcb7d611e89..8ade816775c620 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean @@ -597,7 +597,7 @@ end Constructions variable {R S ι σ} -open Classical in +open scoped Classical in /-- If `P` is submersive, `PreSubmersivePresentation.aevalDifferential` is an isomorphism. -/ noncomputable def aevalDifferentialEquiv (P : SubmersivePresentation R S ι σ) : (σ → S) ≃ₗ[S] (σ → S) := diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index 236098adb9e8d8..40978b008c9367 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -390,7 +390,7 @@ theorem isFractional_div_of_ne_zero {I J : FractionalIdeal R₁⁰ K} (h : J ≠ I.isFractional.div_of_nonzero J.isFractional fun H => h <| coeToSubmodule_injective <| H.trans coe_zero.symm -open Classical in +open scoped Classical in noncomputable instance : Div (FractionalIdeal R₁⁰ K) := ⟨fun I J => if h : J = 0 then 0 else ⟨I / J, isFractional_div_of_ne_zero h⟩⟩ diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index 8b0fe18166dad5..c4b2a64e471f73 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -188,7 +188,7 @@ def iterateEquiv [PartialOrder Γ'] : R⟦Γ'⟧⟦Γ⟧ ≃ R⟦Γ ×ₗ Γ'⟧ left_inv := congrFun rfl right_inv := congrFun rfl -open Classical in +open scoped Classical in /-- `single a r` is the Hahn series which has coefficient `r` at `a` and zero otherwise. -/ def single (a : Γ) : ZeroHom R R⟦Γ⟧ where toFun r := @@ -206,7 +206,7 @@ theorem coeff_single_same (a : Γ) (r : R) : (single a r).coeff a = r := by theorem coeff_single_of_ne (h : b ≠ a) : (single a r).coeff b = 0 := by classical exact Pi.single_eq_of_ne (M := fun _ => R) h r -open Classical in +open scoped Classical in theorem coeff_single : (single a r).coeff b = if b = a then r else 0 := by split_ifs with h <;> simp [h] @@ -248,7 +248,7 @@ instance [Nonempty Γ] [Nontrivial R] : Nontrivial R⟦Γ⟧ := section Order variable {x : R⟦Γ⟧} -open Classical in +open scoped Classical in /-- The orderTop of a Hahn series `x` is a minimal element of `WithTop Γ` where `x` has a nonzero coefficient if `x ≠ 0`, and is `⊤` when `x = 0`. -/ def orderTop (x : R⟦Γ⟧) : WithTop Γ := @@ -352,7 +352,7 @@ theorem coeff_untop_eq_leadingCoeff {x : R⟦Γ⟧} (hx) : variable [Zero Γ] -open Classical in +open scoped Classical in /-- The order of a nonzero Hahn series `x` is a minimal element of `Γ` where `x` has a nonzero coefficient, the order of 0 is 0. -/ def order (x : R⟦Γ⟧) : Γ := @@ -435,7 +435,7 @@ section Domain variable [PartialOrder Γ'] -open Classical in +open scoped Classical in /-- Extends the domain of a `HahnSeries` by an `OrderEmbedding`. -/ def embDomain (f : Γ ↪o Γ') : R⟦Γ⟧ → R⟦Γ'⟧ := fun x => { coeff := fun b : Γ' => if h : b ∈ f '' x.support then x.coeff (Classical.choose h) else 0 diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index fe2d366daab26a..035bbf98a04d5b 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -68,7 +68,7 @@ instance [Zero R] [IntCast R] : IntCast R⟦Γ⟧ where intCast z := single 0 z instance [Zero R] [NNRatCast R] : NNRatCast R⟦Γ⟧ where nnratCast q := single 0 q instance [Zero R] [RatCast R] : RatCast R⟦Γ⟧ where ratCast q := single 0 q -open Classical in +open scoped Classical in @[simp] theorem coeff_one [Zero R] [One R] {a : Γ} : (1 : R⟦Γ⟧).coeff a = if a = 0 then 1 else 0 := coeff_single diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 1816db6f432fe3..f33baf323acfe1 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -609,7 +609,7 @@ section EmbDomain variable [PartialOrder Γ] [AddCommMonoid R] -open Classical in +open scoped Classical in /-- A summable family can be reindexed by an embedding without changing its sum. -/ def embDomain (s : SummableFamily Γ R α) (f : α ↪ β) : SummableFamily Γ R β where toFun b := if h : b ∈ Set.range f then s (Classical.choose h) else 0 @@ -630,7 +630,7 @@ def embDomain (s : SummableFamily Γ R α) (f : α ↪ β) : SummableFamily Γ R variable (s : SummableFamily Γ R α) (f : α ↪ β) {a : α} {b : β} -open Classical in +open scoped Classical in theorem embDomain_apply : s.embDomain f b = if h : b ∈ Set.range f then s (Classical.choose h) else 0 := rfl diff --git a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean index ab3b8fc6869fd3..cd2056327ea71e 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean @@ -111,7 +111,7 @@ theorem exists_inv [hI : I.IsMaximal] : rw [← eq_sub_iff_add_eq'] at abc rwa [abc, ← neg_mem_iff (G := R) (H := I), neg_sub] at hc -open Classical in +open scoped Classical in /-- The quotient by a maximal ideal is a group with zero. This is a `def` rather than `instance`, since users will have computable inverses in some applications. diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean index d384913c18d8ae..19edd42a3f3ac5 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean @@ -82,7 +82,7 @@ theorem isIntegral_algHom_iff (f : A →ₐ[R] B) (hf : Function.Injective f) {x end -open Classical in +open scoped Classical in theorem Submodule.span_range_natDegree_eq_adjoin {R A} [CommRing R] [Semiring A] [Algebra R A] {x : A} {f : R[X]} (hf : f.Monic) (hfx : aeval x f = 0) : span R (Finset.image (x ^ ·) (Finset.range (natDegree f))) = diff --git a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean index a05056c4d42b0b..bf20bae55d0e2e 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean @@ -225,7 +225,7 @@ end IsPrincipalIdealRing variable (R) -open Classical in +open scoped Classical in /-- Zero-preserving monoid homomorphism from a nontrivial commutative ring `R` to `ℤᵐ⁰`. diff --git a/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean b/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean index 22374c758ebf25..90d0018f86091d 100644 --- a/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean +++ b/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean @@ -41,7 +41,7 @@ instance nontrivial : Nontrivial R[R⁰⁻¹] := variable [NoZeroDivisors R] -open Classical in +open scoped Classical in /-- The inversion of Ore fractions for a ring without zero divisors, satisfying `0⁻¹ = 0` and `(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/ @[irreducible] @@ -64,7 +64,7 @@ protected noncomputable def inv : R[R⁰⁻¹] → R[R⁰⁻¹] := noncomputable instance inv' : Inv R[R⁰⁻¹] := ⟨OreLocalization.inv⟩ -open Classical in +open scoped Classical in protected theorem inv_def {r : R} {s : R⁰} : (r /ₒ s)⁻¹ = if hr : r = (0 : R) then (0 : R[R⁰⁻¹]) diff --git a/Mathlib/RingTheory/RamificationInertia/Inertia.lean b/Mathlib/RingTheory/RamificationInertia/Inertia.lean index ce251f7057cfe1..23179a415b8879 100644 --- a/Mathlib/RingTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/RingTheory/RamificationInertia/Inertia.lean @@ -33,7 +33,7 @@ section variable {S : Type*} [CommRing S] (q : Ideal S) (R : Type*) [CommRing R] [Algebra R S] -open Classical in +open scoped Classical in /-- Given a prime ideal `q` of an `R`-algebra `S`, the inertia degree of `q` over `R` is defined to be the degree of the residue field of `q` over the residue field of its preimage `p` in `R`. diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index ffd80a1f9d4b0a..651541f695bd63 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -39,7 +39,7 @@ section variable {S : Type*} [CommRing S] (q : Ideal S) (R : Type*) [CommRing R] [Algebra R S] -open Classical in +open scoped Classical in /-- Let `S/R` be an extension of rings, and let `q` be a prime ideal of `S` lying over a prime ideal `p` of `R`. Let `Sq` be the localization of `S` and `q`, and let `pSq` be the image of `p` in `Sq`. Then the ramification index of `q` over `R` is defined to be the length of the quotient `Sq/pSq` as diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean index 68c3a1a67d99de..38d0e574bfe275 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean @@ -184,7 +184,7 @@ theorem of_subsingleton [Subsingleton α] : UniqueFactorizationMonoid α where variable [UniqueFactorizationMonoid α] -open Classical in +open scoped Classical in /-- Noncomputably determines the multiset of prime factors. -/ noncomputable def factors (a : α) : Multiset α := if h : a = 0 then 0 else Classical.choose (UniqueFactorizationMonoid.exists_prime_factors a h) diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean index 5a41a90bce1993..2ec546c11e0d2b 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean @@ -313,15 +313,15 @@ theorem prod_le [Nontrivial α] {a b : FactorSet α} : a.prod ≤ b.prod ↔ a have : a.prod.factors ≤ b.prod.factors := factors_mono h rwa [prod_factors, prod_factors] at this -open Classical in +open scoped Classical in noncomputable instance : Max (Associates α) := ⟨fun a b => (a.factors ⊔ b.factors).prod⟩ -open Classical in +open scoped Classical in noncomputable instance : Min (Associates α) := ⟨fun a b => (a.factors ⊓ b.factors).prod⟩ -open Classical in +open scoped Classical in noncomputable instance : Lattice (Associates α) := { Associates.instPartialOrder with sup := (· ⊔ ·) @@ -336,7 +336,7 @@ noncomputable instance : Lattice (Associates α) := inf_le_left := fun a _ => le_trans (prod_mono inf_le_left) (le_of_eq (factors_prod a)) inf_le_right := fun _ b => le_trans (prod_mono inf_le_right) (le_of_eq (factors_prod b)) } -open Classical in +open scoped Classical in theorem sup_mul_inf (a b : Associates α) : (a ⊔ b) * (a ⊓ b) = a * b := show (a.factors ⊔ b.factors).prod * (a.factors ⊓ b.factors).prod = a * b by nontriviality α diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean index c9cb2ffba573b2..52e7d74170489a 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean @@ -32,7 +32,7 @@ variable {α : Type*} [CommMonoidWithZero α] [UniqueFactorizationMonoid α] {a /-- The Moebius function on a unique factorization monoid, defined to be `((-1) ^ (factors a).card)` if `a` is squarefree and `0` otherwise. -/ noncomputable def moebius (a : α) : ℤ := - open Classical in + open scoped Classical in if Squarefree a then ((-1) ^ (factors a).card) else 0 -- Todo: prove `Int.moebius_eq` as well. diff --git a/Mathlib/RingTheory/Valuation/ValuationRing.lean b/Mathlib/RingTheory/Valuation/ValuationRing.lean index 7cfc53ea0295a6..e82a9b454cd51f 100644 --- a/Mathlib/RingTheory/Valuation/ValuationRing.lean +++ b/Mathlib/RingTheory/Valuation/ValuationRing.lean @@ -286,7 +286,7 @@ instance le_total_ideal : @Std.Total (Ideal A) (· ≤ ·) := by · exfalso; apply h₂; rw [← h] apply Ideal.mul_mem_right _ _ hb -open Classical in +open scoped Classical in /- Todo: get rid of the `DecidableLE` argument. Currently, this argument causes this instance to not be called often, which hides a loop in simp-lemmas. See diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 8a0b3c5ed4a4d3..fa5a7b2d04f2ad 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -266,14 +266,14 @@ theorem inductionOn₃ {motive : Ordinal → Ordinal → Ordinal → Prop} (o₁ motive (type r) (type s) (type t)) : motive o₁ o₂ o₃ := Quotient.inductionOn₃ o₁ o₂ o₃ fun ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ↦ type α r β s γ t -open Classical in +open scoped Classical in /-- To prove a result on ordinals, it suffices to prove it for order types of well-orders. -/ @[elab_as_elim] theorem inductionOnWellOrder {motive : Ordinal → Prop} (o : Ordinal) (type : ∀ (α) [LinearOrder α] [WellFoundedLT α], motive (typeLT α)) : motive o := inductionOn o fun α r wo ↦ @type α (linearOrderOfSTO r) wo.toIsWellFounded -open Classical in +open scoped Classical in /-- To define a function on ordinals, it suffices to define them on order types of well-orders. Since `LinearOrder` is data-carrying, `liftOnWellOrder_type` is not a definitional equality, unlike @@ -1076,11 +1076,11 @@ theorem exists_ord_eq (α) : ∃ (r : α → α → Prop) (_ : IsWellOrder α r) /-- There exists a well-order on `α` whose order type is exactly `ord #α`. -/ theorem exists_ord_eq_type_lt (α) : - ∃ (_ : LinearOrder α) (_ : WellFoundedLT α), ord #α = typeLT α := - open scoped Classical in + ∃ (_ : LinearOrder α) (_ : WellFoundedLT α), ord #α = typeLT α := by + classical let ⟨r, _, hr⟩ := exists_ord_eq α let := linearOrderOfSTO r - ⟨this, inferInstance, hr⟩ + exact ⟨this, inferInstance, hr⟩ theorem ord_le_type (r : α → α → Prop) [h : IsWellOrder α r] : ord #α ≤ type r := ciInf_le' _ (Subtype.mk r h) diff --git a/Mathlib/Tactic/FieldSimp/Lemmas.lean b/Mathlib/Tactic/FieldSimp/Lemmas.lean index 177257c99d0d68..e08407c14b8dfa 100644 --- a/Mathlib/Tactic/FieldSimp/Lemmas.lean +++ b/Mathlib/Tactic/FieldSimp/Lemmas.lean @@ -29,7 +29,7 @@ variable {α : Type*} section variable [GroupWithZero α] -open Classical in +open scoped Classical in /-- This is a variant of integer exponentiation, defined for internal use in the `field_simp` tactic implementation. It differs from the usual integer exponentiation in that `0 ^ 0` is `0`, not `1`. With this choice, the function `n ↦ a ^ n` is always a homomorphism (`a ^ (n + m) = a ^ n * a ^ m`), diff --git a/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean b/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean index 1f7b28ee787536..4ec7ec8c950bd5 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean @@ -286,7 +286,7 @@ theorem tsum_union_le (f : α → ℝ≥0∞) (s t : Set α) : calc ∑' x : ↑(s ∪ t), f x = ∑' x : ⋃ b, cond b s t, f x := tsum_congr_set_coe _ union_eq_iUnion _ ≤ _ := by simpa using tsum_iUnion_le f (cond · s t) -open Classical in +open scoped Classical in theorem tsum_eq_add_tsum_ite {f : β → ℝ≥0∞} (b : β) : ∑' x, f x = f b + ∑' x, ite (x = b) 0 (f x) := ENNReal.summable.tsum_eq_add_tsum_ite' b @@ -470,7 +470,7 @@ theorem tsum_strict_mono {f g : α → ℝ≥0} (hg : Summable g) (h : f < g) : theorem tsum_pos {g : α → ℝ≥0} (hg : Summable g) (i : α) (hi : 0 < g i) : 0 < ∑' b, g b := by simpa using tsum_lt_tsum (fun a => zero_le) hi hg -open Classical in +open scoped Classical in theorem tsum_eq_add_tsum_ite {f : α → ℝ≥0} (hf : Summable f) (i : α) : ∑' x, f x = f i + ∑' x, ite (x = i) 0 (f x) := by refine (NNReal.summable_of_le (fun i' => ?_) hf).tsum_eq_add_tsum_ite' i diff --git a/Mathlib/Topology/Algebra/Module/Equiv.lean b/Mathlib/Topology/Algebra/Module/Equiv.lean index b3ade728418b0f..4e644e96118994 100644 --- a/Mathlib/Topology/Algebra/Module/Equiv.lean +++ b/Mathlib/Topology/Algebra/Module/Equiv.lean @@ -1061,7 +1061,7 @@ equivalence. -/ def IsInvertible (f : M →L[R] M₂) : Prop := ∃ (A : M ≃L[R] M₂), A = f -open Classical in +open scoped Classical in /-- Introduce a function `inverse` from `M →L[R] M₂` to `M₂ →L[R] M`, which sends `f` to `f.symm` if `f` is a continuous linear equivalence and to `0` otherwise. This definition is somewhat ad hoc, but one needs a fully (rather than partially) defined inverse function for some purposes, including diff --git a/Mathlib/Topology/Algebra/Module/LinearPMap.lean b/Mathlib/Topology/Algebra/Module/LinearPMap.lean index 158081fc2866f2..a7d9549f25f4d5 100644 --- a/Mathlib/Topology/Algebra/Module/LinearPMap.lean +++ b/Mathlib/Topology/Algebra/Module/LinearPMap.lean @@ -91,7 +91,7 @@ theorem IsClosable.existsUnique {f : E →ₗ.[R] F} (hf : f.IsClosable) : refine existsUnique_of_exists_of_unique hf fun _ _ hy₁ hy₂ => eq_of_eq_graph ?_ rw [← hy₁, ← hy₂] -open Classical in +open scoped Classical in /-- If `f` is closable, then `f.closure` is the closure. Otherwise it is defined as `f.closure = f`. -/ noncomputable def closure (f : E →ₗ.[R] F) : E →ₗ.[R] F := diff --git a/Mathlib/Topology/Algebra/UniformField.lean b/Mathlib/Topology/Algebra/UniformField.lean index 9d1cd8e0bccf46..b983eddb5bd019 100644 --- a/Mathlib/Topology/Algebra/UniformField.lean +++ b/Mathlib/Topology/Algebra/UniformField.lean @@ -92,7 +92,7 @@ theorem continuous_hatInv [CompletableTopField K] {x : hat K} (h : x ≠ 0) : rw [eq_bot] exact comap_bot -open Classical in +open scoped Classical in /-- The value of `hat_inv` at zero is not really specified, although it's probably zero. Here we explicitly enforce the `inv_zero` axiom. diff --git a/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean b/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean index 3c8c3994156c1d..60887ff11ec8dd 100644 --- a/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean +++ b/Mathlib/Topology/CWComplex/Classical/Subcomplex.lean @@ -75,7 +75,7 @@ lemma RelCWComplex.Subcomplex.disjoint_openCell_subcomplex_of_not_mem [RelCWComp simp_rw [← union, disjoint_union_right, disjoint_iUnion_right] exact ⟨disjointBase n i , fun _ _ ↦ disjoint_openCell_of_ne (by lia)⟩ -open Classical in +open scoped Classical in /-- A subcomplex is again a CW complex. -/ @[simps] instance RelCWComplex.Subcomplex.instRelCWComplex [T2Space X] [RelCWComplex C D] diff --git a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean index 32b8b296ff0364..dfa0f583b04854 100644 --- a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean +++ b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean @@ -120,7 +120,7 @@ theorem exists_locallyConstant_fin_two (hC : IsLimit C) (f : LocallyConstant C.p set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in -open Classical in +open scoped Classical in theorem exists_locallyConstant_finite_aux {α : Type*} [Finite α] (hC : IsLimit C) (f : LocallyConstant C.pt α) : ∃ (j : J) (g : LocallyConstant (F.obj j) (α → Fin 2)), (f.map fun a b => if a = b then (0 : Fin 2) else 1) = g.comap (C.π.app _).hom.hom := by diff --git a/Mathlib/Topology/Compactness/SigmaCompact.lean b/Mathlib/Topology/Compactness/SigmaCompact.lean index 37db621d2b0d1d..7d412e5a0dc409 100644 --- a/Mathlib/Topology/Compactness/SigmaCompact.lean +++ b/Mathlib/Topology/Compactness/SigmaCompact.lean @@ -378,7 +378,7 @@ theorem exists_superset_of_isCompact {s : Set X} (hs : IsCompact s) : ∃ n, s exact mem_iUnion.2 ⟨k + 1, K.subset_interior_succ _ hk⟩ · exact Monotone.directed_le fun _ _ h ↦ interior_mono <| K.subset h -open Classical in +open scoped Classical in /-- The minimal `n` such that `x ∈ K n`. -/ protected noncomputable def find (x : X) : ℕ := Nat.find (K.exists_mem x) diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 6d2c298d792167..905b1b9ea09162 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -495,7 +495,7 @@ that contains this point. -/ def connectedComponent (x : α) : Set α := ⋃₀ { s : Set α | IsPreconnected s ∧ x ∈ s } -open Classical in +open scoped Classical in /-- Given a set `F` in a topological space `α` and a point `x : α`, the connected component of `x` in `F` is the connected component of `x` in the subtype `F` seen as a set in `α`. This definition does not make sense if `x` is not in `F` so we return the diff --git a/Mathlib/Topology/DiscreteQuotient.lean b/Mathlib/Topology/DiscreteQuotient.lean index 9022c5a122c7bc..b5045bc4dc69c2 100644 --- a/Mathlib/Topology/DiscreteQuotient.lean +++ b/Mathlib/Topology/DiscreteQuotient.lean @@ -351,7 +351,7 @@ instance [CompactSpace X] : Finite S := by variable (X) -open Classical in +open scoped Classical in /-- If `X` is a compact space, then we associate to any discrete quotient on `X` a finite set of clopen subsets of `X`, given by the fibers of `proj`. diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index 2177900ac23584..11e93196721c24 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -227,7 +227,7 @@ section Nonempty variable [∀ x, Nonempty (E x)] -open Classical in +open scoped Classical in /-- A fiberwise inverse to `e`. This is the function `F → E b` that induces a local inverse `B × F → TotalSpace F E` of `e` on `e.baseSet`. Outside of `e.baseSet` it takes on arbitrarily chosen junk values. -/ @@ -880,7 +880,7 @@ theorem frontier_preimage (e : Trivialization F proj) (s : Set B) : rw [← (e.isImage_preimage_prod s).frontier.preimage_eq, frontier_prod_univ_eq, (e.isImage_preimage_prod _).preimage_eq, e.source_eq, preimage_inter] -open Classical in +open scoped Classical in /-- Given two bundle trivializations `e`, `e'` of `proj : Z → B` and a set `s : Set B` such that the base sets of `e` and `e'` intersect `frontier s` on the same set and `e p = e' p` whenever `proj p ∈ e.baseSet ∩ frontier s`, `e.piecewise e' s Hs Heq` is the bundle trivialization over @@ -928,7 +928,7 @@ noncomputable def piecewiseLe [LinearOrder B] [OrderTopology B] (e e' : Triviali · simp [*] · simp [*] -open Classical in +open scoped Classical in /-- Given two bundle trivializations `e`, `e'` over disjoint sets, `e.disjoint_union e' H` is the bundle trivialization over the union of the base sets that agrees with `e` and `e'` over their base sets. -/ diff --git a/Mathlib/Topology/IsClosedRestrict.lean b/Mathlib/Topology/IsClosedRestrict.lean index 8d0962c2c569c1..bb2bae721d6989 100644 --- a/Mathlib/Topology/IsClosedRestrict.lean +++ b/Mathlib/Topology/IsClosedRestrict.lean @@ -30,7 +30,7 @@ variable {ι : Type*} {α : ι → Type*} {s : Set (Π i, α i)} {i : ι} {S : S namespace Topology -open Classical in +open scoped Classical in /-- Given a set in a product space `s : Set (Π j, α j)` and a set of coordinates `S : Set ι`, `Sᶜ.restrict '' s × (Π i : S, α i)` is the set of functions that coincide with an element of `s` on `Sᶜ` and are arbitrary on `S`. diff --git a/Mathlib/Topology/LocallyConstant/Basic.lean b/Mathlib/Topology/LocallyConstant/Basic.lean index d2c7ae07e86ea3..aa3f28e9167a39 100644 --- a/Mathlib/Topology/LocallyConstant/Basic.lean +++ b/Mathlib/Topology/LocallyConstant/Basic.lean @@ -451,7 +451,7 @@ noncomputable def mulIndicator (hU : IsClopen U) : LocallyConstant X R where variable (a : X) -open Classical in +open scoped Classical in @[to_additive] theorem mulIndicator_apply_eq_if (hU : IsClopen U) : mulIndicator f hU a = if a ∈ U then f a else 1 := diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index cab3d2bf990d59..5affd647d7c928 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -598,7 +598,7 @@ noncomputable def restrict [Zero Y] {V : Set X} (D : locallyFinsuppWithin U Y) ( intro _ _ simp_all -open Classical in +open scoped Classical in lemma restrict_apply [Zero Y] {V : Set X} (D : locallyFinsuppWithin U Y) (h : V ⊆ U) (z : X) : (D.restrict h) z = if z ∈ V then D z else 0 := rfl diff --git a/Mathlib/Topology/MetricSpace/Dilation.lean b/Mathlib/Topology/MetricSpace/Dilation.lean index 91ef2dd25879de..2158ba0b0054f0 100644 --- a/Mathlib/Topology/MetricSpace/Dilation.lean +++ b/Mathlib/Topology/MetricSpace/Dilation.lean @@ -128,7 +128,7 @@ theorem copy_eq_self (f : α →ᵈ β) {f' : α → β} (h : f' = f) : f.copy f variable [FunLike F α β] -open Classical in +open scoped Classical in /-- The ratio of a dilation `f`. If the ratio is undefined (i.e., the distance between any two points in `α` is either zero or infinity), then we choose one as the ratio. -/ def ratio [DilationClass F α β] (f : F) : ℝ≥0 := diff --git a/Mathlib/Topology/MetricSpace/Gluing.lean b/Mathlib/Topology/MetricSpace/Gluing.lean index b9ba57063d8c42..b75a6b56bdba80 100644 --- a/Mathlib/Topology/MetricSpace/Gluing.lean +++ b/Mathlib/Topology/MetricSpace/Gluing.lean @@ -308,7 +308,7 @@ namespace Sigma of two spaces. I.e., work with sigma types instead of sum types. -/ variable {ι : Type*} {E : ι → Type*} [∀ i, MetricSpace (E i)] -open Classical in +open scoped Classical in /-- Distance on a disjoint union. There are many (noncanonical) ways to put a distance compatible with each factor. We choose a construction that works for unbounded spaces, but requires basepoints, diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index 61b1c66783476d..a503e533a8f72a 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -71,7 +71,7 @@ namespace PiNat /-! ### The firstDiff function -/ -open Classical in +open scoped Classical in /-- In a product space `Π n, E n`, then `firstDiff x y` is the first index at which `x` and `y` differ. If `x = y`, then by convention we set `firstDiff x x = 0`. -/ irreducible_def firstDiff (x y : ∀ n, E n) : ℕ := @@ -249,7 +249,7 @@ a `MetricSpace` instance, as other distances may be used on these spaces, but we local instances in this section. -/ -open Classical in +open scoped Classical in /-- The distance function on a product space `Π n, E n`, given by `dist x y = (1/2)^n` where `n` is the first index at which `x` and `y` differ. -/ @[instance_reducible] @@ -482,7 +482,7 @@ theorem exists_disjoint_cylinder {s : Set (∀ n, E n)} (hs : IsClosed s) {x : exact mem_cylinder_iff_dist_le.1 hy _ < infDist x s := hn -open Classical in +open scoped Classical in /-- Given a point `x` in a product space `Π (n : ℕ), E n`, and `s` a subset of this space, then `shortestPrefixDiff x s` if the smallest `n` for which there is no element of `s` having the same prefix of length `n` as `x`. If there is no such `n`, then use `0` by convention. -/ diff --git a/Mathlib/Topology/PartitionOfUnity.lean b/Mathlib/Topology/PartitionOfUnity.lean index d1f019e7cafe54..4f168a7c767a55 100644 --- a/Mathlib/Topology/PartitionOfUnity.lean +++ b/Mathlib/Topology/PartitionOfUnity.lean @@ -335,7 +335,7 @@ theorem nonneg (i : ι) (x : X) : 0 ≤ f i x := theorem le_one (i : ι) (x : X) : f i x ≤ 1 := f.le_one' i x -open Classical in +open scoped Classical in /-- A `BumpCovering` that consists of a single function, uniformly equal to one, defined as an example for `Inhabited` instance. -/ protected def single (i : ι) (s : Set X) : BumpCovering ι X s where @@ -350,7 +350,7 @@ protected def single (i : ι) (s : Set X) : BumpCovering ι X s where le_one' := update_le_iff.2 ⟨le_rfl, fun _ _ _ => zero_le_one⟩ eventuallyEq_one' x _ := ⟨i, by rw [Pi.single_eq_same, ContinuousMap.coe_one]⟩ -open Classical in +open scoped Classical in @[simp] theorem coe_single (i : ι) (s : Set X) : ⇑(BumpCovering.single i s) = Pi.single i 1 := by rfl @@ -503,7 +503,7 @@ theorem toPOUFun_zero_of_zero {i : ι} {x : X} (h : f i x = 0) : f.toPOUFun i x theorem support_toPOUFun_subset (i : ι) : support (f.toPOUFun i) ⊆ support (f i) := fun _ => mt <| f.toPOUFun_zero_of_zero -open Classical in +open scoped Classical in theorem toPOUFun_eq_mul_prod (i : ι) (x : X) (t : Finset ι) (ht : ∀ j, WellOrderingRel j i → f j x ≠ 0 → j ∈ t) : f.toPOUFun i x = f i x * ∏ j ∈ t with WellOrderingRel j i, (1 - f j x) := by @@ -529,7 +529,7 @@ theorem sum_toPOUFun_eq (x : X) : ∑ᶠ i, f.toPOUFun i x = 1 - ∏ᶠ i, (1 - convert! f.toPOUFun_eq_mul_prod _ _ _ fun j _ hj => _ rwa [Finite.mem_toFinset] -open Classical in +open scoped Classical in theorem exists_finset_toPOUFun_eventuallyEq (i : ι) (x : X) : ∃ t : Finset ι, f.toPOUFun i =ᶠ[𝓝 x] f i * ∏ j ∈ t with WellOrderingRel j i, (1 - f j) := by rcases f.locallyFinite x with ⟨U, hU, hf⟩ @@ -571,13 +571,13 @@ def toPartitionOfUnity : PartitionOfUnity ι X s where theorem toPartitionOfUnity_apply (i : ι) (x : X) : f.toPartitionOfUnity i x = f i x * ∏ᶠ (j) (_ : WellOrderingRel j i), (1 - f j x) := rfl -open Classical in +open scoped Classical in theorem toPartitionOfUnity_eq_mul_prod (i : ι) (x : X) (t : Finset ι) (ht : ∀ j, WellOrderingRel j i → f j x ≠ 0 → j ∈ t) : f.toPartitionOfUnity i x = f i x * ∏ j ∈ t with WellOrderingRel j i, (1 - f j x) := f.toPOUFun_eq_mul_prod i x t ht -open Classical in +open scoped Classical in theorem exists_finset_toPartitionOfUnity_eventuallyEq (i : ι) (x : X) : ∃ t : Finset ι, f.toPartitionOfUnity i =ᶠ[𝓝 x] f i * ∏ j ∈ t with WellOrderingRel j i, (1 - f j) := f.exists_finset_toPOUFun_eventuallyEq i x diff --git a/Mathlib/Topology/ShrinkingLemma.lean b/Mathlib/Topology/ShrinkingLemma.lean index 58cbfd0c7ec0ab..770cac4e18c0b6 100644 --- a/Mathlib/Topology/ShrinkingLemma.lean +++ b/Mathlib/Topology/ShrinkingLemma.lean @@ -76,7 +76,7 @@ protected theorem subset (v : PartialRefinement u s p) (i : ι) : v i ⊆ u i := classical exact if h : i ∈ v.carrier then subset_closure.trans (v.closure_subset h) else (v.apply_eq h).le -open Classical in +open scoped Classical in instance : PartialOrder (PartialRefinement u s p) where le v₁ v₂ := v₁.carrier ⊆ v₂.carrier ∧ ∀ i ∈ v₁.carrier, v₁ i = v₂ i le_refl _ := ⟨Subset.refl _, fun _ _ => rfl⟩ @@ -102,7 +102,7 @@ their carriers. -/ def chainSupCarrier (c : Set (PartialRefinement u s p)) : Set ι := ⋃ v ∈ c, carrier v -open Classical in +open scoped Classical in /-- Choice of an element of a nonempty chain of partial refinements. If `i` belongs to one of `carrier v`, `v ∈ c`, then `find c ne i` is one of these partial refinements. -/ def find (c : Set (PartialRefinement u s p)) (ne : c.Nonempty) (i : ι) : PartialRefinement u s p := diff --git a/Mathlib/Topology/UniformSpace/Completion.lean b/Mathlib/Topology/UniformSpace/Completion.lean index 5d8af417a0802f..7705375efdd1e8 100644 --- a/Mathlib/Topology/UniformSpace/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Completion.lean @@ -218,7 +218,7 @@ instance [h : Nonempty α] : Nonempty (CauchyFilter α) := section Extend -open Classical in +open scoped Classical in /-- Extend a uniformly continuous function `α → β` to a function `CauchyFilter α → β`. Outputs junk when `f` is not uniformly continuous. -/ def extend (f : α → β) : CauchyFilter α → β := diff --git a/Mathlib/Topology/UniformSpace/Separation.lean b/Mathlib/Topology/UniformSpace/Separation.lean index 5055fdd348f7e4..86c7a03066396c 100644 --- a/Mathlib/Topology/UniformSpace/Separation.lean +++ b/Mathlib/Topology/UniformSpace/Separation.lean @@ -288,7 +288,7 @@ theorem uniformContinuous_uncurry_lift₂ {f : α → β → γ} theorem comap_mk_uniformity : (𝓤 (SeparationQuotient α)).comap (Prod.map mk mk) = 𝓤 α := comap_map_mk_uniformity -open Classical in +open scoped Classical in /-- Factoring functions to a separated space through the separation quotient. TODO: unify with `SeparationQuotient.lift`. -/ diff --git a/Mathlib/Topology/VectorBundle/Basic.lean b/Mathlib/Topology/VectorBundle/Basic.lean index ada696545834d0..a2f4df1e3a9076 100644 --- a/Mathlib/Topology/VectorBundle/Basic.lean +++ b/Mathlib/Topology/VectorBundle/Basic.lean @@ -86,7 +86,7 @@ theorem linear [AddCommMonoid F] [Module R F] [∀ x, AddCommMonoid (E x)] [∀ variable [AddCommMonoid F] [Module R F] [∀ x, AddCommMonoid (E x)] [∀ x, Module R (E x)] -open Classical in +open scoped Classical in /-- A fiberwise linear inverse to `e`. -/ protected def symmₗ (e : Pretrivialization F (π F E)) [e.IsLinear R] (b : B) : F →ₗ[R] E b := by refine if hb : b ∈ e.baseSet then IsLinearMap.mk' (e.symm b) ?_ else 0 @@ -115,14 +115,14 @@ def linearEquivAt (e : Pretrivialization F (π F E)) [e.IsLinear R] (b : B) (hb map_add' v w := (e.linear R hb).map_add v w map_smul' c v := (e.linear R hb).map_smul c v -open Classical in +open scoped Classical in /-- A fiberwise linear map equal to `e` on `e.baseSet`. -/ protected def linearMapAt (e : Pretrivialization F (π F E)) [e.IsLinear R] (b : B) : E b →ₗ[R] F := if hb : b ∈ e.baseSet then e.linearEquivAt R b hb else 0 variable {R} -open Classical in +open scoped Classical in theorem coe_linearMapAt (e : Pretrivialization F (π F E)) [e.IsLinear R] (b : B) : ⇑(e.linearMapAt R b) = fun y => if b ∈ e.baseSet then (e ⟨b, y⟩).2 else 0 := by rw [Pretrivialization.linearMapAt] @@ -133,7 +133,7 @@ theorem coe_linearMapAt_of_mem (e : Pretrivialization F (π F E)) [e.IsLinear R] (hb : b ∈ e.baseSet) : ⇑(e.linearMapAt R b) = fun y => (e ⟨b, y⟩).2 := by simp_rw [coe_linearMapAt, if_pos hb] -open Classical in +open scoped Classical in theorem linearMapAt_apply (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (y : E b) : e.linearMapAt R b y = if b ∈ e.baseSet then (e ⟨b, y⟩).2 else 0 := by rw [coe_linearMapAt] @@ -223,7 +223,7 @@ variable (R) in protected def linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] (b : B) : E b →ₗ[R] F := e.toPretrivialization.linearMapAt R b -open Classical in +open scoped Classical in theorem coe_linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] (b : B) : ⇑(e.linearMapAt R b) = fun y => if b ∈ e.baseSet then (e ⟨b, y⟩).2 else 0 := e.toPretrivialization.coe_linearMapAt b @@ -233,7 +233,7 @@ theorem coe_linearMapAt_of_mem (e : Trivialization F (π F E)) [e.IsLinear R] {b (hb : b ∈ e.baseSet) : ⇑(e.linearMapAt R b) = fun y => (e ⟨b, y⟩).2 := by simp_rw [coe_linearMapAt, if_pos hb] -open Classical in +open scoped Classical in theorem linearMapAt_apply (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (y : E b) : e.linearMapAt R b y = if b ∈ e.baseSet then (e ⟨b, y⟩).2 else 0 := by rw [coe_linearMapAt] @@ -264,7 +264,7 @@ theorem linearMapAt_symmₗ (e : Trivialization F (π F E)) [e.IsLinear R] {b : e.toPretrivialization.linearMapAt_symmₗ hb y variable (R) in -open Classical in +open scoped Classical in /-- A coordinate change function between two trivializations, as a continuous linear equivalence. Defined to be the identity when `b` does not lie in the base set of both trivializations. -/ def coordChangeL (e e' : Trivialization F (π F E)) [e.IsLinear R] [e'.IsLinear R] (b : B) : From 7a95be0bf4367954a79a36fd72bb27ef054c0576 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 7 Jul 2026 18:14:00 +0000 Subject: [PATCH 0639/1300] feat(Translate): copy `alias` and `deprecated` attributes (#40503) This PR implements two related features for `to_dual`/`to_additive`: 1. When tagging a declaration that was created as an `alias` of `foo`, we mark the new declaration as an `alias` of the translation of `foo`, and we add the docstring that is automatically added for aliases, saying that it is an alias, unless a docstring is manually specified. To make this work, we add the manually specified docstring *before* running `copyMetaData`, so that the alias docstring is not added. 2. When using `(attr := deprecated ...)`, we ensure that the target for deprecation is set correctly. This solves the problem of adding deprecations for `to_additive`/`to_dual` declarations. This works when explicitly writing the target, and when applying this to an `alias`. closes #19424 --- Mathlib/Algebra/Group/Pi/Lemmas.lean | 37 ++++------ Mathlib/Data/Finset/Lattice/Fold.lean | 12 +--- Mathlib/GroupTheory/Index.lean | 7 +- .../GroupTheory/SpecificGroups/Cyclic.lean | 7 +- Mathlib/Order/Disjoint.lean | 3 +- Mathlib/Order/SupClosed.lean | 10 +-- Mathlib/Tactic/Translate/Core.lean | 42 +++++++++-- MathlibTest/Attribute/ToAdditive/Basic.lean | 69 ++++++++++++++++++- 8 files changed, 125 insertions(+), 62 deletions(-) diff --git a/Mathlib/Algebra/Group/Pi/Lemmas.lean b/Mathlib/Algebra/Group/Pi/Lemmas.lean index d28636953c7627..190be2eb25d05e 100644 --- a/Mathlib/Algebra/Group/Pi/Lemmas.lean +++ b/Mathlib/Algebra/Group/Pi/Lemmas.lean @@ -77,13 +77,9 @@ def MulHom.pi {γ : Type w} [Mul γ] (g : ∀ i, γ →ₙ* f i) : γ →ₙ* toFun x i := g i x map_mul' x y := funext fun i => (g i).map_mul x y -@[deprecated (since := "2026-05-29")] alias Pi.addHom := AddHom.pi -@[to_additive existing (attr := deprecated MulHom.pi (since := "2026-05-29"))] alias - Pi.mulHom := MulHom.pi +@[to_additive (attr := deprecated (since := "2026-05-29"))] alias Pi.mulHom := MulHom.pi -@[deprecated (since := "2026-05-29")] alias Pi.addHom_apply := AddHom.pi_apply -@[to_additive existing (attr := deprecated MulHom.pi_apply (since := "2026-05-29"))] alias - Pi.mulHom_apply := MulHom.pi_apply +@[to_additive (attr := deprecated (since := "2026-05-29"))] alias Pi.mulHom_apply := MulHom.pi_apply @[to_additive] theorem MulHom.pi_injective {γ : Type w} [Nonempty I] [Mul γ] (g : ∀ i, γ →ₙ* f i) @@ -91,13 +87,11 @@ theorem MulHom.pi_injective {γ : Type w} [Nonempty I] [Mul γ] (g : ∀ i, γ let ⟨i⟩ := ‹Nonempty I› hg i ((funext_iff.mp h :) i) -@[deprecated (since := "2026-05-29")] alias AddHom.injective_pi := AddHom.pi_injective -@[to_additive existing (attr := deprecated MulHom.pi_injective (since := "2026-05-29"))] alias - MulHom.injective_pi := MulHom.pi_injective +@[to_additive (attr := deprecated (since := "2026-05-29"))] +alias MulHom.injective_pi := MulHom.pi_injective -@[deprecated (since := "2026-05-29")] alias Pi.addHom_injective := AddHom.injective_pi -@[to_additive existing (attr := deprecated MulHom.pi_injective (since := "2026-05-29"))] alias - Pi.mulHom_injective := MulHom.pi_injective +@[to_additive (attr := deprecated (since := "2026-05-29"))] +alias Pi.mulHom_injective := MulHom.pi_injective variable (f) @@ -166,13 +160,10 @@ def MonoidHom.pi {γ : Type w} [MulOneClass γ] (g : ∀ i, γ →* f i) : toFun := fun x i => g i x map_one' := funext fun i => (g i).map_one } -@[deprecated (since := "2026-05-29")] alias Pi.addMonoidHom := AddMonoidHom.pi -@[to_additive existing (attr := deprecated MonoidHom.pi (since := "2026-05-29"))] alias - Pi.monoidHom := MonoidHom.pi +@[to_additive (attr := deprecated (since := "2026-05-29"))] alias Pi.monoidHom := MonoidHom.pi -@[deprecated (since := "2026-05-29")] alias Pi.addMonoidHom_apply := AddMonoidHom.pi_apply -@[to_additive existing (attr := deprecated MonoidHom.pi_apply (since := "2026-05-29"))] alias - Pi.monoidHom_apply := MonoidHom.pi_apply +@[to_additive (attr := deprecated (since := "2026-05-29"))] +alias Pi.monoidHom_apply := MonoidHom.pi_apply @[to_additive] theorem MonoidHom.pi_injective {γ : Type w} [Nonempty I] [MulOneClass γ] @@ -180,13 +171,11 @@ theorem MonoidHom.pi_injective {γ : Type w} [Nonempty I] [MulOneClass γ] Function.Injective (MonoidHom.pi g) := MulHom.pi_injective (fun i => (g i).toMulHom) hg -@[deprecated (since := "2026-05-29")] alias AddMonoidHom.injective_pi := AddMonoidHom.pi_injective -@[to_additive existing (attr := deprecated MonoidHom.pi_injective (since := "2026-05-29"))] alias - MonoidHom.injective_pi := MonoidHom.pi_injective +@[to_additive (attr := deprecated (since := "2026-05-29"))] +alias MonoidHom.injective_pi := MonoidHom.pi_injective -@[deprecated (since := "2026-05-29")] alias Pi.addMonoidHom_injective := AddMonoidHom.pi_injective -@[to_additive existing (attr := deprecated MonoidHom.pi_injective (since := "2026-05-29"))] alias - Pi.monoidHom_injective := MonoidHom.pi_injective +@[to_additive (attr := deprecated (since := "2026-05-29"))] +alias Pi.monoidHom_injective := MonoidHom.pi_injective variable (f) diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index 0f82aa39ee7c54..6b25b519cddedc 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -102,11 +102,7 @@ protected theorem sup_le_iff {a : α} : s.sup f ≤ a ↔ ∀ b ∈ s, f b ≤ a simp only [Multiset.mem_map, and_imp, exists_imp] exact ⟨fun k b hb => k _ _ hb rfl, fun k a' b hb h => h ▸ k _ hb⟩ --- TODO: `@[to_dual]` should translate the docstring generated by `alias` -protected alias ⟨_, sup_le⟩ := Finset.sup_le_iff - -@[to_dual existing sup_le] -protected alias ⟨_, le_inf⟩ := Finset.le_inf_iff +@[to_dual le_inf] protected alias ⟨_, sup_le⟩ := Finset.sup_le_iff @[to_dual le_inf_const] theorem sup_const_le : (s.sup fun _ => a) ≤ a := @@ -545,11 +541,7 @@ theorem sup'_singleton {b : β} : ({b} : Finset β).sup' (singleton_nonempty _) theorem sup'_le_iff {a : α} : s.sup' H f ≤ a ↔ ∀ b ∈ s, f b ≤ a := by simp_rw [← @WithBot.coe_le_coe α, coe_sup', Finset.sup_le_iff]; rfl --- TODO: `@[to_dual]` should translate the docstring generated by `alias` -alias ⟨_, sup'_le⟩ := sup'_le_iff - -@[to_dual existing sup'_le] -alias ⟨_, le_inf'⟩ := le_inf'_iff +@[to_dual le_inf'] alias ⟨_, sup'_le⟩ := sup'_le_iff @[to_dual inf'_le] theorem le_sup' {b : β} (h : b ∈ s) : f b ≤ s.sup' ⟨b, h⟩ f := diff --git a/Mathlib/GroupTheory/Index.lean b/Mathlib/GroupTheory/Index.lean index 266f5f1af2c273..b3c6fd0d028d22 100644 --- a/Mathlib/GroupTheory/Index.lean +++ b/Mathlib/GroupTheory/Index.lean @@ -520,12 +520,7 @@ lemma disjoint_of_coprime_natCard (h : Nat.card H |>.Coprime <| Nat.card K) : Di disjoint_iff.mpr <| card_eq_one.mp <| Nat.eq_one_of_dvd_coprimes h (card_dvd_of_le inf_le_left) (card_dvd_of_le inf_le_right) -@[deprecated AddSubgroup.disjoint_of_coprime_natCard (since := "2026-05-28")] -lemma _root_.AddSubgroup.inf_eq_bot_of_coprime {G : Type*} [AddGroup G] {H K : AddSubgroup G} - (h : Nat.Coprime (Nat.card H) (Nat.card K)) : H ⊓ K = ⊥ := - disjoint_iff.mp <| AddSubgroup.disjoint_of_coprime_natCard h - -@[to_additive existing (attr := deprecated disjoint_of_coprime_natCard (since := "2026-05-28"))] +@[to_additive (attr := deprecated disjoint_of_coprime_natCard (since := "2026-05-28"))] lemma inf_eq_bot_of_coprime (h : Nat.Coprime (Nat.card H) (Nat.card K)) : H ⊓ K = ⊥ := disjoint_iff.mp <| disjoint_of_coprime_natCard h diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean index 673b7378410d62..a5247cb57e02cb 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean @@ -197,12 +197,7 @@ theorem MonoidHom.isMulCommutative_of_isCyclic_of_ker_le_center [IsCyclic G'] (f _ = y ^ m * y ^ n * y ^ (-m) * (y ^ (-n) * b * a) := by rw [mem_center_iff.1 hb] _ = b * a := by group -@[deprecated AddMonoidHom.isAddCommutative_of_isAddCyclic_of_ker_le_center (since := "2026-05-26")] -theorem commutative_of_addCyclic_center_quotient {G G' : Type*} [AddGroup G] [AddGroup G'] - [IsAddCyclic G'] (f : G →+ G') (hf : f.ker ≤ .center G) (a b : G) : a + b = b + a := - f.isAddCommutative_of_isAddCyclic_of_ker_le_center hf |>.is_comm.comm a b - -@[to_additive existing (attr := deprecated MonoidHom.isMulCommutative_of_isCyclic_of_ker_le_center +@[to_additive (attr := deprecated MonoidHom.isMulCommutative_of_isCyclic_of_ker_le_center (since := "2026-05-26"))] theorem commutative_of_cyclic_center_quotient [IsCyclic G'] (f : G →* G') (hf : f.ker ≤ center G) (a b : G) : a * b = b * a := diff --git a/Mathlib/Order/Disjoint.lean b/Mathlib/Order/Disjoint.lean index 1d3c8bcacd75ee..844d5aa07f29c4 100644 --- a/Mathlib/Order/Disjoint.lean +++ b/Mathlib/Order/Disjoint.lean @@ -64,8 +64,7 @@ theorem Disjoint.symm ⦃a b : α⦄ : Disjoint a b → Disjoint b a := instance symm_disjoint : Std.Symm (Disjoint : α → α → Prop) where symm := Disjoint.symm -@[deprecated (since := "2026-06-10")] alias symmetric_codisjoint := symm_codisjoint -@[to_dual existing, deprecated (since := "2026-06-10")] alias symmetric_disjoint := symm_disjoint +@[to_dual (attr := deprecated (since := "2026-06-10"))] alias symmetric_disjoint := symm_disjoint @[to_dual (attr := simp, grind ←)] theorem disjoint_bot_left : Disjoint ⊥ a := fun _ hbot _ ↦ hbot diff --git a/Mathlib/Order/SupClosed.lean b/Mathlib/Order/SupClosed.lean index 78d08d819371d4..2502a90f5c994e 100644 --- a/Mathlib/Order/SupClosed.lean +++ b/Mathlib/Order/SupClosed.lean @@ -191,10 +191,7 @@ lemma isSublattice_pi {ι : Type*} {α : ι → Type*} [∀ i, Lattice (α i)] { @[simp] lemma isSublattice_preimage_ofDual : IsSublattice (ofDual ⁻¹' s) ↔ IsSublattice s := ⟨fun h ↦ ⟨h.2, h.1⟩, fun h ↦ ⟨h.2, h.1⟩⟩ --- TODO: `@[to_dual]` should translate the docstring generated by `alias` -alias ⟨_, InfClosed.dual⟩ := supClosed_preimage_ofDual -@[to_dual existing] -alias ⟨_, SupClosed.dual⟩ := infClosed_preimage_ofDual +@[to_dual] alias ⟨_, InfClosed.dual⟩ := supClosed_preimage_ofDual alias ⟨_, IsSublattice.dual⟩ := isSublattice_preimage_ofDual alias ⟨_, IsSublattice.of_dual⟩ := isSublattice_preimage_toDual @@ -243,10 +240,7 @@ lemma supClosure_mono : Monotone (supClosure : Set α → Set α) := supClosure. @[to_dual (attr := simp)] lemma supClosure_eq_self : supClosure s = s ↔ SupClosed s := supClosure.isClosed_iff.symm --- TODO: `@[to_dual]` should translate the docstring generated by `alias` -alias ⟨_, SupClosed.supClosure_eq⟩ := supClosure_eq_self -@[to_dual existing] -alias ⟨_, InfClosed.infClosure_eq⟩ := infClosure_eq_self +@[to_dual] alias ⟨_, SupClosed.supClosure_eq⟩ := supClosure_eq_self @[to_dual] lemma supClosure_idem (s : Set α) : supClosure (supClosure s) = supClosure s := diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 2688f4e152a0d6..393fbba8d4b92f 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -14,6 +14,7 @@ public meta import Lean.Meta.Tactic.Symm public meta import Lean.Meta.CoeAttr public meta import Mathlib.Lean.Meta.Simp public import Batteries.Lean.NameMapAttribute +public import Batteries.Tactic.Alias public import Batteries.Tactic.Trans public import Mathlib.Tactic.Eqns public import Mathlib.Tactic.Translate.Attributes @@ -865,6 +866,20 @@ def copyInstanceAttribute (src tgt : Name) : CoreM Unit := do trace[translate_detail] "Making {tgt} an instance with priority {prio}." addInstance tgt attr_kind prio |>.run' +open Batteries.Tactic.Alias in +/-- If `src` was declared with `alias`, then record `tgt` as an alias, +and give it an alias-style docstring if it doesn't have a doc-string already -/ +def copyAliasAttribute (t : TranslateData) (src tgt : Name) : CoreM Unit := do + if let some srcInfo ← getAliasInfo? src then + let env ← getEnv + let tgtInfo? := match srcInfo with + | .plain n => .plain <$> findTranslationName? env t n + | .forward n => .forward <$> findTranslationName? env t n + | .reverse n => .reverse <$> findTranslationName? env t n + if let some tgtInfo := tgtInfo? then + setAliasInfo tgtInfo tgt + addAliasDocstring tgt tgtInfo + /-- Warn the user when the declaration has an attribute. -/ def warnAttrCore (stx : Syntax) (f : Environment → Name → Bool) (thisAttr attrName src tgt : Name) : CoreM Unit := do @@ -1151,8 +1166,10 @@ mutual /-- Apply attributes to the original and translated declarations. -/ partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) (reorder : Reorder) (relevantArg : RelevantArg) : TermElabM (Array Name) := do - -- we only copy the `instance` attribute, since it is nice to directly tag `instance` declarations - copyInstanceAttribute src tgt + if !cfg.existing && !cfg.none then + -- Copy the `instance` attribute, since it is nice to directly tag `instance` declarations. + copyInstanceAttribute src tgt + copyAliasAttribute t src tgt -- Warn users if the original declaration has an attribute if !cfg.existing && !cfg.none && linter.existingAttributeWarning.get (← getOptions) then let appliedAttrs ← getAllSimpAttrs src @@ -1193,7 +1210,22 @@ partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) translateLemmas t allDecls reorder relevantArg "simps lemmas" cfg.ref (impl · attr.stx attr.kind) else - for decl in allDecls do + let mut attr := attr + -- Set the target of `(attr := deprecated)` when applied to an `alias`. + if attr.name == `deprecated then + if let some info ← Batteries.Tactic.Alias.getAliasInfo? src then + if let `(attr| deprecated%$tk $[$desc:str]? $[(since := $since)]?) := attr.stx then + attr := { attr with stx := ← `(attr| + deprecated%$tk $(mkCIdent info.name) $[$desc:str]? $[(since := $since)]?) } + for decl in allDecls, i in 0...* do + if i != 0 then + -- Translate the target of `(attr := deprecated)` if possible. + if attr.name == `deprecated then + if let `(attr| deprecated%$tk $name $[$desc]? $[(since := $since)]?) := attr.stx then + let name ← realizeGlobalConstNoOverload name + if let some name := findTranslationName? (← getEnv) t name then + attr := { attr with stx := ← `(attr| + deprecated%$tk $(mkCIdent name) $[$desc]? $[(since := $since)]?) } Term.applyAttributes decl #[attr] return nestedDecls @@ -1249,13 +1281,13 @@ partial def addTranslationAttr (t : TranslateData) (src : Name) (cfg : Config) let reorder := cfg.reorder?.getD {} -- tgt doesn't exist, so let's make it transformDeclRec t cfg src tgt src reorder cfg.rename + if let some doc := cfg.doc then + addDocStringCore tgt doc let nestedNames ← copyMetaData t cfg src -- add pop-up information when mousing over the given translated name -- (the information will be over the attribute if no translated name is given) Term.addTermInfo' cfg.ref (← mkConstWithLevelParams tgt) (isBinder := !alreadyExists) |>.run' |>.run' - if let some doc := cfg.doc then - addDocStringCore tgt doc return nestedNames.push tgt end diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index 4e815db07b96e8..57b6ece3f9ffb6 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -689,7 +689,7 @@ theorem mulTrivial : True := trivial /-- info: (via `docComment` syntax) I am an additive docstring! -/ #guard_msgs in run_cmd - let some doc ← findDocString? (← getEnv) ``addTrivial + let some doc ← findDocString? (← getEnv) ``addTrivial | throwError "no `docComment` docstring found" logInfo doc @@ -959,3 +959,70 @@ attribute [to_additive existing] MulClass MulClass.mk.congr_simp #guard_msgs in @[to_additive] axiom MulAxiom {α} : Mul α + +/-! Docstring on `alias` -/ + +@[to_additive] alias HMulAlias := HMul + +/-- +info: **Alias** of `HAdd`. + +--- + +The notation typeclass for heterogeneous addition. +This enables the notation `a + b : γ` where `a : α`, `b : β`. +-/ +#guard_msgs in +run_cmd + let some doc ← findDocString? (← getEnv) ``HAddAlias + | throwError "no `docComment` docstring found" + logInfo doc + +@[to_additive /-- Overriding docstring -/] alias HMulAlias' := HMul + +/-- info: Overriding docstring -/ +#guard_msgs in +run_cmd + let some doc ← findDocString? (← getEnv) ``HAddAlias' + | throwError "no `docComment` docstring found" + logInfo doc + +/-! Deprecated attribute -/ + +@[to_additive (attr := deprecated mul_comm (since := "today"))] +theorem old_mul_comm {α} [CommMagma α] (a b : α) : a * b = b * a := mul_comm a b + +/-- +warning: `old_mul_comm` has been deprecated: Use `mul_comm` instead +--- +info: @old_mul_comm : ∀ {α : Type u_1} [inst : CommMagma α] (a b : α), a * b = b * a +-/ +#guard_msgs in +#check @old_mul_comm + +/-- +warning: `old_add_comm` has been deprecated: Use `add_comm` instead +--- +info: @old_add_comm : ∀ {α : Type u_1} [inst : AddCommMagma α] (a b : α), a + b = b + a +-/ +#guard_msgs in +#check @old_add_comm + +@[to_additive (attr := deprecated (since := "today"))] +alias mul_comm_alias := mul_comm + +/-- +warning: `mul_comm_alias` has been deprecated: Use `mul_comm` instead +--- +info: @mul_comm_alias : ∀ {G : Type u_1} [inst : CommMagma G] (a b : G), a * b = b * a +-/ +#guard_msgs in +#check @mul_comm_alias + +/-- +warning: `add_comm_alias` has been deprecated: Use `add_comm` instead +--- +info: @add_comm_alias : ∀ {G : Type u_1} [inst : AddCommMagma G] (a b : G), a + b = b + a +-/ +#guard_msgs in +#check @add_comm_alias From b405e28f36359816c36e5c4c2284bf072620af3e Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Tue, 7 Jul 2026 19:13:10 +0000 Subject: [PATCH 0640/1300] feat(Topology): Show existence of a neighbourhood around p which avoids all points in the support of a locally finsupp function except those which specialize to p (#39353) In this PR we show a simple lemma proving the existence of a neighbourhood around any point p which avoids every point in the support of a locally finsupp function except those which specialize to p. AI disclosure: The statements and a sketch with sorries were provided by me, but I had claude fill in the sorries. Co-authored-by: Raph-DG --- Mathlib/Topology/DiscreteSubset.lean | 24 ++++++++++++++++++++++++ Mathlib/Topology/LocallyFinsupp.lean | 14 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index b949ac0ba8702a..6a9e500b734003 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -365,6 +365,30 @@ lemma mem_codiscrete {S : Set X} : S ∈ codiscrete X ↔ ∀ x, Disjoint (𝓝[≠] x) (𝓟 Sᶜ) := by simp [codiscrete, mem_codiscreteWithin, compl_eq_univ_sdiff] +lemma Disjoint.eventualy_nhdsWithin_specializes + {p : X} {s : Set X} (hs : Disjoint (𝓝[s] p) cofinite) : + ∀ᶠ x in 𝓝[s] p, x ⤳ p := by + obtain ⟨t, h₁t, h₂t⟩ := disjoint_cofinite_right.mp hs + set S := {y ∈ t ∩ s | ¬(y ⤳ p)} + have hS_nhds (y) (hy : y ∈ S) : (closure ({y} : Set X))ᶜ ∈ 𝓝 p := + isClosed_closure.isOpen_compl.mem_nhds <| by + simpa [specializes_iff_mem_closure] using hy.2 + filter_upwards [h₁t, nhdsWithin_le_nhds ((biInter_mem <| h₂t.subset (by grind)).mpr hS_nhds), + self_mem_nhdsWithin] with x hxt hxS + contrapose + refine fun hxp hxf ↦ mem_iInter₂.mp hxS x ⟨⟨hxt, hxf⟩, hxp⟩ ?_ + grind [subset_closure] + +lemma Disjoint.nhdsWithin_eq_of_cofinite + {p : X} {s : Set X} (hs : Disjoint (𝓝[s] p) cofinite) : + 𝓝[s] p = 𝓟 ({x | x ⤳ p} ∩ s) := by + apply le_antisymm + · simpa using ⟨hs.eventualy_nhdsWithin_specializes, self_mem_nhdsWithin⟩ + · rw [← inf_principal, nhdsWithin] + gcongr + rw [Filter.principal_le_iff] + exact fun s hs x hx ↦ mem_of_mem_nhds (hx hs) + lemma mem_codiscrete_accPt {S : Set X} : S ∈ codiscrete X ↔ ∀ x, ¬AccPt x (𝓟 Sᶜ) := by simp only [mem_codiscrete, disjoint_iff, AccPt, not_neBot] diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 5affd647d7c928..69e86e21c6d843 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -692,4 +692,18 @@ lemma restrict_negPart {V : Set X} (D : locallyFinsuppWithin U ℤ) (h : V ⊆ U simp only [locallyFinsuppWithin.restrict_apply, locallyFinsuppWithin.negPart_apply] aesop +lemma disjoint_nhdsWithin_cofinite_of_mem [Zero Y] + (f : locallyFinsuppWithin U Y) (p : X) (hp : p ∈ U) : + Disjoint (𝓝[f.support] p) cofinite := by + rw [disjoint_cofinite_right] + obtain ⟨t, h₁t, h₂t⟩ := f.supportLocallyFiniteWithinDomain p hp + refine ⟨t ∩ f.support, ?_, h₂t⟩ + rw [mem_nhdsWithin_iff_exists_mem_nhds_inter] + grind + +lemma _root_.Function.locallyFinsupp.disjoint_nhdsWithin_cofinite + [Zero Y] (f : locallyFinsupp X Y) (p : X) : + Disjoint (𝓝[f.support] p) cofinite := + disjoint_nhdsWithin_cofinite_of_mem f p (mem_univ _) + end Function.locallyFinsuppWithin From 8b63cc61a148833a9b6766052ccad269dbdf5091 Mon Sep 17 00:00:00 2001 From: David Gross Date: Tue, 7 Jul 2026 19:52:09 +0000 Subject: [PATCH 0641/1300] chore(PiTensorProduct/ProjectiveNorm): cleaner reducible defeqs (#40573) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR replaces `projectiveSeminorm x` by `‖x‖` in the definitions of `toDualContinuousMultilinearMap`, `toDualContinuousMultilinearMap_le_projectiveSeminorm`, and `projectiveSeminorm_tprod_le`. The two terms are defeq, but not at reducible transparency. The new definition allows us to get rid of a `convert!` and a `using!`, and is more consistent with the rest of the module. --- .../Module/PiTensorProduct/InjectiveSeminorm.lean | 15 +++++++-------- .../PiTensorProduct/ProjectiveSeminorm.lean | 11 ++++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean index 4a18420fc5ec71..6c07e93e422bf7 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean @@ -52,21 +52,20 @@ variable (F) in /-- The linear map from `⨂[𝕜] i, Eᵢ` to `ContinuousMultilinearMap 𝕜 E F →L[𝕜] F` sending `x` in `⨂[𝕜] i, Eᵢ` to the map `f ↦ f.lift x`. -/ @[simps!] -noncomputable def toDualContinuousMultilinearMap : (⨂[𝕜] i, E i) →ₗ[𝕜] - ContinuousMultilinearMap 𝕜 E F →L[𝕜] F where +noncomputable def toDualContinuousMultilinearMap : + (⨂[𝕜] i, E i) →ₗ[𝕜] ContinuousMultilinearMap 𝕜 E F →L[𝕜] F where toFun x := LinearMap.mkContinuous - (lift.toLinearMap.flip x ∘ₗ ContinuousMultilinearMap.toMultilinearMapLinear) - (projectiveSeminorm x) - (fun _ ↦ by simpa [mul_comm] using! norm_eval_le_projectiveSeminorm ..) + (lift.toLinearMap.flip x ∘ₗ ContinuousMultilinearMap.toMultilinearMapLinear) ‖x‖ + (fun f ↦ by simpa [mul_comm] using norm_eval_le_projectiveSeminorm f x) map_add' x y := by ext; simp map_smul' a x := by ext; simp theorem toDualContinuousMultilinearMap_le_projectiveSeminorm (x : ⨂[𝕜] i, E i) : - ‖toDualContinuousMultilinearMap F x‖ ≤ projectiveSeminorm x := by + ‖toDualContinuousMultilinearMap F x‖ ≤ ‖x‖ := by simp only [toDualContinuousMultilinearMap, LinearMap.coe_mk, AddHom.coe_mk] - apply LinearMap.mkContinuous_norm_le _ (apply_nonneg _ _) + apply LinearMap.mkContinuous_norm_le _ (by positivity) /-- The injective seminorm on `⨂[𝕜] i, Eᵢ`. Morally, it sends `x` in `⨂[𝕜] i, Eᵢ` to the `sup` of the operator norms of the `PiTensorProduct.toDualContinuousMultilinearMap F x`, for all @@ -89,7 +88,7 @@ lemma dualSeminorms_bounded : BddAbove {p | ∃ (G : Type (max uι u𝕜 uE)) use projectiveSeminorm simp only [mem_upperBounds, Set.mem_setOf_eq, forall_exists_index] intro p G _ _ hp x - simpa [hp] using toDualContinuousMultilinearMap_le_projectiveSeminorm _ + simpa [hp] using! toDualContinuousMultilinearMap_le_projectiveSeminorm _ @[deprecated "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean index 432bc808ff1f78..4e81a007e0a788 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/ProjectiveSeminorm.lean @@ -120,7 +120,7 @@ theorem projectiveSeminorm_smul_le (a : 𝕜) (x : ⨂[𝕜] i, E i) : ‖a • infimum over all expressions of `x` as `∑ j, ⨂ₜ[𝕜] mⱼ i` (with the `mⱼ` ∈ `Π i, Eᵢ`) of `∑ j, Π i, ‖mⱼ i‖`. -/ noncomputable def projectiveSeminorm : Seminorm 𝕜 (⨂[𝕜] i, E i) := .ofSMulLE - _ projectiveSeminorm_zero projectiveSeminorm_add_le projectiveSeminorm_smul_le + norm projectiveSeminorm_zero projectiveSeminorm_add_le projectiveSeminorm_smul_le noncomputable instance : SeminormedAddCommGroup (⨂[𝕜] i, E i) := fast_instance% AddGroupSeminorm.toSeminormedAddCommGroup projectiveSeminorm.toAddGroupSeminorm @@ -132,10 +132,11 @@ theorem projectiveSeminorm_apply (x : ⨂[𝕜] i, E i) : projectiveSeminorm x = iInf (fun (p : lifts x) ↦ projectiveSeminormAux p.1) := rfl theorem projectiveSeminorm_tprod_le (m : Π i, E i) : - projectiveSeminorm (⨂ₜ[𝕜] i, m i) ≤ ∏ i, ‖m i‖ := by - convert! ciInf_le (bddBelow_projectiveSemiNormAux _) ⟨FreeAddMonoid.of ((1 : 𝕜), m), ?_⟩ - · simp [projectiveSeminormAux] - · simp [mem_lifts_iff] + ‖(⨂ₜ[𝕜] i, m i)‖ ≤ ∏ i, ‖m i‖ := by + have hle := ciInf_le (bddBelow_projectiveSemiNormAux (⨂ₜ[𝕜] i, m i)) + ⟨FreeAddMonoid.of (1, m), by simp [mem_lifts_iff]⟩ + grw [norm_def, hle] + simp [projectiveSeminormAux] end NormedField From f9ce623fd400be68ab070bf41dd26f2aabffdc58 Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Tue, 7 Jul 2026 20:01:46 +0000 Subject: [PATCH 0642/1300] feat: abstract theory of measures (#37984) General foundations of non-archimedean measure theory (intended for applications to Iwasawa algebras) --- Mathlib.lean | 2 + .../NumberTheory/Padics/Measure/Basic.lean | 244 ++++++++++++++++++ .../NumberTheory/Padics/Measure/Topology.lean | 52 ++++ Mathlib/Topology/ContinuousMap/Algebra.lean | 43 +++ 4 files changed, 341 insertions(+) create mode 100644 Mathlib/NumberTheory/Padics/Measure/Basic.lean create mode 100644 Mathlib/NumberTheory/Padics/Measure/Topology.lean diff --git a/Mathlib.lean b/Mathlib.lean index 82604c1674a2d6..6ef83cb76ea317 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5877,6 +5877,8 @@ public import Mathlib.NumberTheory.Padics.Complex public import Mathlib.NumberTheory.Padics.HeightOneSpectrum public import Mathlib.NumberTheory.Padics.Hensel public import Mathlib.NumberTheory.Padics.MahlerBasis +public import Mathlib.NumberTheory.Padics.Measure.Basic +public import Mathlib.NumberTheory.Padics.Measure.Topology public import Mathlib.NumberTheory.Padics.PadicIntegers public import Mathlib.NumberTheory.Padics.PadicNorm public import Mathlib.NumberTheory.Padics.PadicNumbers diff --git a/Mathlib/NumberTheory/Padics/Measure/Basic.lean b/Mathlib/NumberTheory/Padics/Measure/Basic.lean new file mode 100644 index 00000000000000..f8a2f46b20c7a1 --- /dev/null +++ b/Mathlib/NumberTheory/Padics/Measure/Basic.lean @@ -0,0 +1,244 @@ +/- +Copyright (c) 2024 David Loeffler. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: David Loeffler +-/ +module + +public import Mathlib.Topology.UniformSpace.ProdApproximation + +/-! +# Abstract measures on topological spaces + +We define an "abstract measure" on `X`, with values in a normed ring `R`, to be an `R`-linear +functional on continuous maps `X → R`. This is an important construction in p-adic analysis (where +the Iwasawa algebra is defined as the space of abstract measures on `ℤ_[p]` with values in `ℚ_[p]`). +-/ + +public section + +open ContinuousMap + +variable {X Y R E : Type*} [TopologicalSpace X] [TopologicalSpace Y] + [AddCommGroup E] [TopologicalSpace E] [IsTopologicalAddGroup E] + [CommRing R] [TopologicalSpace R] [IsTopologicalRing R] [Module R E] --[ContinuousSMul R E] + +section Defs + +/-! +### Basic definitions +-/ + +variable (X R E) in +/-- +The space of `E`-valued measures on `X`, i.e. continuous linear maps `C(X, R) → E`. (The case +`R = E` is the most important case.) + +This is the same space `C(X, R) →L[R] E`, but we do not want it to inherit the default +(norm) topology, so we make a type synonym. +-/ +@[expose] def AbstractMeasure := C(X, R) →L[R] E + +@[inherit_doc] +scoped [AbstractMeasure] notation "D(" X ", " R ")" => AbstractMeasure X R R + +end Defs + +namespace AbstractMeasure + +section NoContinuousSMul + +/-- Inherit `FunLike` structure from `C(X, R) →L[R] E`. -/ +instance : FunLike (AbstractMeasure X R E) C(X, R) E := + inferInstanceAs (FunLike (C(X, R) →L[R] E) C(X, R) E) + +/-- Inherit `ContinuousLinearMapClass` structure from `C(X, R) →L[R] E`. -/ +instance : ContinuousLinearMapClass (AbstractMeasure X R E) R C(X, R) E := + inferInstanceAs (ContinuousLinearMapClass (C(X, R) →L[R] E) R C(X, R) E) + +/-- Inherit `AddCommGroup` structure from `C(X, R) →L[R] E`. -/ +instance : AddCommGroup (AbstractMeasure X R E) := + inferInstanceAs (AddCommGroup (C(X, R) →L[R] E)) + +instance isAddApply : IsAddApply (AbstractMeasure X R E) C(X, R) E where + add_apply _ _ _ := rfl + +end NoContinuousSMul + +section ContinuousSMul + +variable [ContinuousSMul R E] + +/-- Inherit `R`-module structure from `C(X, R) →L[R] E`. -/ +instance : Module R (AbstractMeasure X R E) := + inferInstanceAs (Module R (C(X, R) →L[R] E)) + +instance isSMulApply : IsSMulApply R (AbstractMeasure X R E) C(X, R) E where + smul_apply _ _ _ := rfl + +/-- The defining equivalence between measures and continuous linear maps on continuous functions. -/ +def toCLMEquiv : AbstractMeasure X R E ≃ₗ[R] C(X, R) →L[R] E := + LinearEquiv.refl _ _ + +@[simp] lemma coe_toCLMEquiv (μ : AbstractMeasure X R E) (f : C(X, R)) : + toCLMEquiv μ f = μ f := + (rfl) + +@[simp] lemma coe_symm_toCLMEquiv (L : C(X, R) →L[R] E) (f : C(X, R)) : + toCLMEquiv.symm L f = L f := + (rfl) + +variable (R) in +/-- The Dirac measure, "evaluation at `x`". -/ +def dirac (x : X) : D(X, R) := + toCLMEquiv.symm (ContinuousMap.evalCLM R x) + +@[simp] lemma dirac_apply (x : X) (f : C(X, R)) : dirac R x f = f x := (rfl) + +section Map + +/-- Measures can be pushed forward (`R`-linearly) along continuous maps. -/ +def map (f : C(X, Y)) : AbstractMeasure X R E →ₗ[R] AbstractMeasure Y R E where + toFun μ := μ ∘L f.compCLM R R + map_add' _ _ := rfl + map_smul' _ _ := rfl + +@[simp] lemma map_apply (f : C(X, Y)) (μ : AbstractMeasure X R E) (g : C(Y, R)) : + map f μ g = μ (g.comp f) := + (rfl) + +@[simp] lemma map_map {Z : Type*} [TopologicalSpace Z] + (f : C(X, Y)) (g : C(Y, Z)) (μ : AbstractMeasure X R E) : + map g (map f μ) = map (g.comp f) μ := + (rfl) + +@[simp] +lemma map_id (μ : AbstractMeasure X R E) : + map (.id X) μ = μ := + (rfl) + +@[simp] lemma map_dirac (f : C(X, Y)) (x : X) : + map f (dirac R x) = dirac R (f x) := + (rfl) + +end Map + +section Prod + +/-! +### Product structure +-/ + +-- note we define `contractSnd` first, because `f.curry` only works one way round + +/-- Send a measure `ν` on `Y` and a function `f` on `X × Y` to the function on `X` given by +`x ↦ ν (f (x, ·))`, or more suggestively, `x ↦ ∫ f(x, y) dμ(y)`. -/ +def contractSnd : D(Y, R) →ₗ[R] C(X × Y, R) →ₗ[R] C(X, R) := + LinearMap.mk₂ R (fun ν f ↦ comp ν f.curry) ?_ ?_ ?_ ?_ where finally + all_goals intros; ext; simp + +/-- Send a measure `μ` on `X` and a function `f` on `X × Y` to the function on `Y` given by +`y ↦ μ (f (·, y))`, or more suggestively, `y ↦ ∫ f(x, y) dμ(x)`. -/ +def contractFst : D(X, R) →ₗ[R] C(X × Y, R) →ₗ[R] C(Y, R) := + ((prodSwap.compCLM R R).toLinearMap.lcomp R _).comp contractSnd + +variable (μ : D(X, R)) (ν : D(Y, R)) + +@[simp] lemma contractFst_apply (f : C(X × Y, R)) (y : Y) : + contractFst μ f y = μ ⟨fun x ↦ f (x, y), by continuity⟩ := + (rfl) + +@[simp] lemma contractSnd_apply (f : C(X × Y, R)) (x : X) : + contractSnd ν f x = ν ⟨fun y ↦ f (x, y), by continuity⟩ := + (rfl) + +lemma contractFst_dirac (x : X) (y : Y) (f : C(X × Y, R)) : + contractFst (dirac R x) f y = f (x, y) := + (rfl) + +lemma contractSnd_dirac (x : X) (y : Y) (f : C(X × Y, R)) : + contractSnd (dirac R y) f x = f (x, y) := + (rfl) + +section LocallyCompact + +variable [LocallyCompactSpace X] [LocallyCompactSpace Y] + +/-- `AbstractMeasure.contractSnd` bundled with continuity in the function argument. -/ +def contractSndCLM : D(Y, R) →ₗ[R] C(X × Y, R) →L[R] C(X, R) where + toFun ν := ⟨contractSnd ν, by + refine continuous_of_continuous_uncurry _ (ν.continuous.comp ?_) + apply continuous_of_continuous_uncurry + rw [← (Homeomorph.prodAssoc C(X × Y, R) X Y).symm.comp_continuous_iff'] + exact ContinuousEval.continuous_eval⟩ + map_add' _ _ := ContinuousLinearMap.coe_injective.eq_iff.mp <| contractSnd.map_add _ _ + map_smul' _ _ := ContinuousLinearMap.coe_injective.eq_iff.mp <| contractSnd.map_smul _ _ + +/-- `AbstractMeasure.contractFst` bundled with continuity in the function argument. -/ +def contractFstCLM : D(X, R) →ₗ[R] C(X × Y, R) →L[R] C(Y, R) := + ((ContinuousMap.prodSwap.compCLM R R).lcomp _).comp contractSndCLM + +/-- "Left-handed" version of the natural product map on measures (acting on functions +as first integrating along `X`, and then integrating the result along `Y`). -/ +def prodMk : D(X, R) →ₗ[R] D(Y, R) →ₗ[R] D(X × Y, R) := + (ContinuousLinearMap.llcomp _ _ _ R).comp contractFstCLM + +@[simp] lemma prodMk_apply (f : C(X × Y, R)) : + prodMk μ ν f = ν (μ.contractFst f) := (rfl) + +/-- On functions of the form `(x, y) ↦ f x * g y`, the measure `prodMk μ ν` agrees with the +algebraic tensor product of `μ` and `ν`. -/ +lemma prodMk_prod_apply (f : C(X, R)) (g : C(Y, R)) : + prodMk μ ν ((f.comp .fst) * (g.comp .snd)) = μ f * ν g := by + simp only [← smul_eq_mul, prodMk_apply, ← map_smul] + congr 1 with y + simp_rw [contractFst_apply, ContinuousMap.smul_apply, smul_eq_mul, mul_comm (μ f) (g y), + ← smul_eq_mul, ← map_smul] + congr 1 with x + simp_rw [ContinuousMap.smul_apply, smul_eq_mul, mul_comm (g y) (f x)] + rfl + +/-- "Right-handed" version of the natural product map on measures (acting on functions +as first integrating along `Y`, and then integrating the result along `X`). -/ +def prodMk' : D(X, R) →ₗ[R] D(Y, R) →ₗ[R] D(X × Y, R) := + ((ContinuousLinearMap.llcomp R _ _ R).comp contractSndCLM).flip + +@[simp] +lemma prodMk'_apply (f : C(X × Y, R)) : (μ.prodMk' ν) f = μ (ν.contractSnd f) := (rfl) + +lemma prodMk'_flip (f : C(X × Y, R)) : + (μ.prodMk' ν) f = (ν.prodMk μ) (f.comp ContinuousMap.prodSwap) := (rfl) + +lemma prodMk'_prod_apply (f : C(X, R)) (g : C(Y, R)) : + prodMk' μ ν ((f.comp .fst) * (g.comp .snd)) = μ f * ν g := by + simp only [prodMk'_apply, mul_comm (μ f) (ν g), ← smul_eq_mul, ← map_smul] + congr 1 with x + simp_rw [ContinuousMap.smul_apply, smul_eq_mul, mul_comm (ν g) (f x), contractSnd_apply, + ← smul_eq_mul, ← map_smul] + rfl + +end LocallyCompact + +section Profinite + +variable [CompactSpace X] [CompactSpace Y] [T2Space X] [T2Space Y] [TotallyDisconnectedSpace X] + [T0Space R] + +/-- For profinite spaces, the two product structures on measures agree. -/ +lemma prodMk_eq_prodMk' : prodMk μ ν = prodMk' μ ν := by + apply DFunLike.coe_injective + apply denseRange_tensorHom.equalizer (by fun_prop) (by fun_prop) (funext fun h ↦ ?_) + induction h with + | zero => simp + | add => grind + | tmul f g => simp [prodMul_def, prodMk_prod_apply μ, prodMk'_prod_apply μ] + +end Profinite + +end Prod + +end ContinuousSMul + +end AbstractMeasure + +end diff --git a/Mathlib/NumberTheory/Padics/Measure/Topology.lean b/Mathlib/NumberTheory/Padics/Measure/Topology.lean new file mode 100644 index 00000000000000..9a7cf8e4d6901d --- /dev/null +++ b/Mathlib/NumberTheory/Padics/Measure/Topology.lean @@ -0,0 +1,52 @@ +/- +Copyright (c) 2024 David Loeffler. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: David Loeffler +-/ +module + +public import Mathlib.NumberTheory.Padics.Measure.Basic +public import Mathlib.Topology.ContinuousMap.Compact + +/-! +# Topologies on spaces of measures + +We define the weak and strong topologies on `D(X, E)`. These are deliberately not declared as +instances in order to avoid favouring one topology over the other. +-/ + +@[expose] public section + +open ContinuousMap Topology + +variable {X R E : Type*} [TopologicalSpace X] + +namespace AbstractMeasure + +section Topology + +section Weak + +variable [NormedAddCommGroup E] [CommRing R] [Module R E] [TopologicalSpace R] + [IsTopologicalRing R] [ContinuousSMul R E] + +/-- +The weak topology on `AbstractMeasure G R E` (the weakest topology such that `μ ↦ μ f` is +continuous for all `f`). +-/ +@[reducible] def WeakTopology : TopologicalSpace (AbstractMeasure X R E) := + .induced (fun μ f ↦ μ f) inferInstance + +end Weak + +variable [CompactSpace X] [NontriviallyNormedField R] [NormedAddCommGroup E] [NormedSpace R E] + +/-- The strong topology on `AbstractMeasure G R E` (the topology induced by the norm). -/ +@[reducible] def StrongTopology : TopologicalSpace (AbstractMeasure X R E) := + inferInstanceAs (TopologicalSpace (C(X, R) →L[R] E)) + +end Topology + +end AbstractMeasure + +end diff --git a/Mathlib/Topology/ContinuousMap/Algebra.lean b/Mathlib/Topology/ContinuousMap/Algebra.lean index 926994ae9b3157..4857f9538804c2 100644 --- a/Mathlib/Topology/ContinuousMap/Algebra.lean +++ b/Mathlib/Topology/ContinuousMap/Algebra.lean @@ -850,3 +850,46 @@ def ContinuousMap.evalAlgHom (x : X) : C(X, R) →ₐ[S] R where map_add' _ _ := rfl map_mul' _ _ := rfl commutes' _ := rfl + +section curry + +namespace ContinuousMap + +variable {Y Z : Type*} [TopologicalSpace Y] [TopologicalSpace Z] + +@[to_additive (attr := simp)] +lemma curry_mul_apply [Mul Z] [ContinuousMul Z] (f g : C(X × Y, Z)) (x : X) : + (f * g).curry x = f.curry x * g.curry x := + rfl + +@[to_additive (attr := simp)] +lemma curry_div_apply [Div Z] [ContinuousDiv Z] (f g : C(X × Y, Z)) (x : X) : + (f / g).curry x = f.curry x / g.curry x := + rfl + +@[to_additive (attr := simp)] +lemma curry_smul_apply {R : Type*} [SMul R Z] [ContinuousConstSMul R Z] + (f : C(X × Y, Z)) (r : R) (x : X) : + (r • f).curry x = r • f.curry x := + rfl + +@[to_additive (attr := simp)] +lemma curry_inv_apply [Inv Z] [ContinuousInv Z] (f : C(X × Y, Z)) (x : X) : + (f⁻¹).curry x = (f.curry x)⁻¹ := + rfl + +@[to_additive (attr := simp)] +lemma curry_pow_apply [Monoid Z] [ContinuousMul Z] + (f : C(X × Y, Z)) (n : ℕ) (x : X) : + (f ^ n).curry x = (f.curry x) ^ n := + rfl + +@[to_additive (attr := simp)] +lemma curry_zpow_apply [Group Z] [IsTopologicalGroup Z] + (f : C(X × Y, Z)) (n : ℤ) (x : X) : + (f ^ n).curry x = (f.curry x) ^ n := + rfl + +end ContinuousMap + +end curry From 87a6eccfb8c6cd5dfe4ebb2fc8178b697ac18cd0 Mon Sep 17 00:00:00 2001 From: ajirving <29164966+ajirving@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:01:49 +0000 Subject: [PATCH 0643/1300] feat(Analysis): integral test for infinite sums (#40588) Extends the results in SumIntegralComparisons.lean to infinite sums. If a function is nonnegative, antitone and integrable on $(0, \infty)$ then we prove that its restriction to $\N$ is summable and we bound its sum by the integral. This upstreams some results I recently added to the PrimeNumberTheoremAnd project in Mertens.lean. Co-authored-by: Jireh Loreaux Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: David Loeffler --- Mathlib/Analysis/SumIntegralComparisons.lean | 148 ++++++++++++++++++- docs/undergrad.yaml | 2 +- 2 files changed, 142 insertions(+), 8 deletions(-) diff --git a/Mathlib/Analysis/SumIntegralComparisons.lean b/Mathlib/Analysis/SumIntegralComparisons.lean index d333e36c258610..16026e45f2abf3 100644 --- a/Mathlib/Analysis/SumIntegralComparisons.lean +++ b/Mathlib/Analysis/SumIntegralComparisons.lean @@ -1,26 +1,26 @@ /- Copyright (c) 2022 Kevin H. Wilson. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kevin H. Wilson +Authors: Kevin H. Wilson, Alastair Irving -/ module public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic public import Mathlib.Data.Set.Function +import Mathlib.MeasureTheory.Integral.IntegralEqImproper + /-! # Comparing sums and integrals ## Summary It is often the case that error terms in analysis can be computed by comparing -an infinite sum to the improper integral of an antitone function. This file will eventually enable -that. +an infinite sum to the improper integral of an antitone function. -At the moment it contains several lemmas in this direction, for antitone or monotone functions +It contains several lemmas in this direction, for antitone or monotone functions (or products of antitone and monotone functions), formulated for sums on `range i` or `Ico a b`. - -`TODO`: Add more lemmas to the API to directly address limiting issues +These are used to prove a version of the integral test for antitone functions. ## Main Results @@ -36,7 +36,12 @@ At the moment it contains several lemmas in this direction, for antitone or mono by the integral of `f x * g (x - 1)` if `f` is monotone and `g` is antitone. * `integral_le_sum_mul_Ico_of_antitone_monotone`: the sum of `f i * g i` on an interval is bounded below by the integral of `f x * g (x - 1)` if `f` is antitone and `g` is monotone. - +* `AntitoneOn.summable_of_integrableOn_Ioi_zero` and `AntitoneOn.tsum_le_integral`, the + integral test for antitone functions. +* `AntitoneOn.abs_tsum_sub_sum_range_le_integral`: an error estimate for the difference + between a sum and its partial sums in terms of an integral. +* `AntitoneOn.integrableOn_Ioi_zero_of_summable` and `AntitoneOn.integral_le_tsum`, the converse to + the integral test. ## Tags analysis, comparison, asymptotics @@ -173,3 +178,132 @@ lemma integral_le_sum_mul_Ico_of_antitone_monotone apply MonotoneOn.memLp_isCompact isCompact_Icc intro _ _ _ _ _ apply hg <;> grind + +/-! ## Comparison of infinite sums and integrals -/ + +/-- The partial sums of a nonnegative antitone function are bounded +by the integral over `(a, ∞)`. -/ +lemma AntitoneOn.sum_Ico_le_integral {a b : ℕ} (anti : AntitoneOn f (Icc a b)) + (integrable : IntegrableOn f (Ioi a)) (nonneg : ∀ t ∈ Ioi (a : ℝ), 0 ≤ f t) : + ∑ n ∈ .Ico a b, f ↑(n + 1) ≤ ∫ x in Ioi (a : ℝ), f x := by + by_cases! hab : b < a + · simpa [Finset.Ico_eq_empty_of_le hab.le] using setIntegral_nonneg measurableSet_Ioi nonneg + grw [anti.sum_le_integral_Ico hab, integral_of_le (mod_cast hab)] + apply setIntegral_mono_set integrable _ (Ioc_subset_Ioi_self.eventuallyLE) + exact ae_restrict_of_forall_mem measurableSet_Ioi nonneg + +/-- The partial sums of a nonnegative function are bounded by the integral over `(0, ∞)`. -/ +lemma AntitoneOn.sum_range_le_integral {N : ℕ} (anti : AntitoneOn f (Icc 0 (N : ℝ))) + (integrable : IntegrableOn f (Ioi 0)) (nonneg : ∀ t ∈ Ioi 0, 0 ≤ f t) : + ∑ n ∈ Finset.range N, f ((n + 1 : ℕ)) ≤ ∫ x in Ioi 0, f x := by + rw [Finset.range_eq_Ico] + exact_mod_cast AntitoneOn.sum_Ico_le_integral (a := 0) (mod_cast anti) + (mod_cast integrable) (mod_cast nonneg) + +/-- **Integral test**: A function which is nonnegative, integrable and antitone +for sufficiently large `n` is summable. -/ +theorem AntitoneOn.summable_of_integrableOn_Ioi {N : ℕ} (anti : AntitoneOn f (Ici (N : ℝ))) + (integrable : IntegrableOn f (Ioi (N : ℝ))) (nonneg : ∀ t ∈ Ioi (N : ℝ), 0 ≤ f t) : + Summable (fun (n : ℕ) ↦ f n) := by + rw [← summable_nat_add_iff (N + 1)] + refine summable_of_sum_range_le (c := ∫ t in Ioi (N : ℝ), f t) (by grind) fun M ↦ ?_ + calc + _ = ∑ n ∈ Finset.Ico N (N + M), f (n + 1 : ℕ) := by rw [Finset.sum_Ico_eq_sum_range]; grind + _ ≤ _ := (anti.mono Icc_subset_Ici_self).sum_Ico_le_integral integrable nonneg + +/-- **Integral test**: a nonnegative antitone function is summable if it is integrable. -/ +theorem AntitoneOn.summable_of_integrableOn_Ioi_zero (anti : AntitoneOn f (Ici 0)) + (integrable : IntegrableOn f (Ioi 0)) (nonneg : ∀ t ∈ Ioi 0, 0 ≤ f t) : + Summable (fun (n : ℕ) ↦ f n) := + summable_of_integrableOn_Ioi (N := 0) (mod_cast anti) (mod_cast integrable) (mod_cast nonneg) + +open Filter Finset in +theorem AntitoneOn.tsum_comp_add_le_integral (N : ℕ) (anti : AntitoneOn f (Ici (N : ℝ))) + (integrable : IntegrableOn f (Ioi (N : ℝ))) (nonneg : ∀ t ∈ Ioi (N : ℝ), 0 ≤ f t) : + ∑' (n : ℕ), f (n + N + 1 : ℕ) ≤ ∫ x in Ioi (N : ℝ), f x := by + refine tsum_le_of_sum_le' (integral_nonneg_of_ae ?_) fun s ↦ ?_ + · filter_upwards [ae_restrict_mem measurableSet_Ioi] using nonneg + · obtain ⟨t, ht⟩ := tendsto_finset_range.eventually (Ici_mem_atTop s) |>.exists + calc + ∑ i ∈ s, f ↑(i + N + 1) ≤ ∑ i ∈ range t, f ↑(i + N + 1) := + sum_le_sum_of_subset_of_nonneg ht <| by grind + _ = ∑ i ∈ Ico N (N + t), f ↑(i + 1) := by rw [Finset.sum_Ico_eq_sum_range]; grind + _ ≤ ∫ (x : ℝ) in Set.Ioi (N : ℝ), f x := + (anti.mono <| by grind).sum_Ico_le_integral integrable nonneg + +/-- **Integral test**: bounds the sum from 1 by an integral. -/ +theorem AntitoneOn.tsum_add_one_le_integral (anti : AntitoneOn f (Ici 0)) + (integrable : IntegrableOn f (Ioi 0)) (nonneg : ∀ t ∈ Ioi 0, 0 ≤ f t) : + ∑' (n : ℕ), f (n + 1 : ℕ) ≤ ∫ x in Ioi 0, f x := by + exact_mod_cast AntitoneOn.tsum_comp_add_le_integral 0 (mod_cast anti) (mod_cast integrable) + (mod_cast nonneg) + +/-- **Integral test**: bounds the sum of a nonnegative antitone function by an integral. -/ +theorem AntitoneOn.tsum_le_integral (anti : AntitoneOn f (Ici 0)) + (integrable : IntegrableOn f (Ioi 0)) (nonneg : ∀ t ∈ Ioi 0, 0 ≤ f t) : + ∑' (n : ℕ), f n ≤ f 0 + ∫ x in Ioi 0, f x := by + grind [(anti.summable_of_integrableOn_Ioi_zero integrable nonneg).tsum_eq_zero_add, + anti.tsum_add_one_le_integral integrable nonneg] + +/-- Bounds the difference between a sum and its partial sums by an integral. -/ +theorem AntitoneOn.abs_tsum_sub_sum_range_le_integral {N : ℕ} (hN : 1 ≤ N) + (anti : AntitoneOn f (Ici (N - 1 : ℝ))) + (integrable : IntegrableOn f (Ioi (N - 1 : ℝ))) (nonneg : ∀ t ∈ Ioi (N - 1 : ℝ), 0 ≤ f t) : + |(∑' (n : ℕ), f n) - ∑ n ∈ Finset.range N, f n| ≤ ∫ x in Ioi (N - 1 : ℝ), f x := by + rw [← (AntitoneOn.summable_of_integrableOn_Ioi (mod_cast anti) (mod_cast integrable) + (mod_cast nonneg)).sum_add_tsum_nat_add N, add_sub_cancel_left, + abs_of_nonneg (tsum_nonneg <| by grind)] + convert! AntitoneOn.tsum_comp_add_le_integral (N - 1) (mod_cast anti) (mod_cast integrable) + (mod_cast nonneg) using 1 + · congr; ext; congr 2; grind + · norm_cast + +open Filter in +/-- Converse to the integral test: a nonnegative, integrable, summable function is integrable. -/ +theorem AntitoneOn.integrableOn_Ioi_of_summable_comp_add {N : ℕ} (anti : AntitoneOn f (Ici (N : ℝ))) + (summable : Summable (fun n ↦ f (n + N : ℕ))) (nonneg : ∀ t ∈ Ioi (N : ℝ), 0 ≤ f t) : + IntegrableOn f (Ioi (N : ℝ)) := by + refine integrableOn_Ioi_of_intervalIntegral_norm_bounded (∑' (n : ℕ), f (n + N : ℕ)) _ ?_ + (tendsto_atTop_add_const_right atTop (N : ℝ) tendsto_natCast_atTop_atTop) ?_ + · intro n + rw [← intervalIntegrable_iff_integrableOn_Ioc_of_le (by grind)] + exact (anti.mono <| by grind [uIcc_of_le]).intervalIntegrable + · filter_upwards [eventually_gt_atTop 0] with M hM + calc + _ = ∫ x in N..M+N, f x := by + refine intervalIntegral.integral_congr_uIoo fun x ↦ ?_ + grind [Real.norm_of_nonneg, uIoo_of_le] + _ ≤ ∑ n ∈ Finset.range M, f (n + N : ℕ) := by + convert! AntitoneOn.integral_le_sum (anti.mono _) using 2 <;> grind + _ ≤ _ := by grind [summable.sum_le_tsum, Nat.cast_pos] + +/-- Converse to the integral test: a nonnegative, integrable, summable function is integrable. -/ +theorem AntitoneOn.integrableOn_Ioi_zero_of_summable (anti : AntitoneOn f (Ici 0)) + (summable : Summable (fun (n : ℕ) ↦ f n)) (nonneg : ∀ t ∈ Ioi 0, 0 ≤ f t) : + IntegrableOn f (Ioi 0) := + mod_cast AntitoneOn.integrableOn_Ioi_of_summable_comp_add (N := 0) (mod_cast anti) summable + (mod_cast nonneg) + +open Filter in +/-- The sum of a nonnegative, antitone function is bounded below by its integral. -/ +theorem AntitoneOn.integral_le_tsum_comp_add (N : ℕ) (anti : AntitoneOn f (Ici (N : ℝ))) + (summable : Summable (fun (n : ℕ) ↦ f n)) (nonneg : ∀ t ∈ Ioi (N : ℝ), 0 ≤ f t) : + ∫ x in Ioi (N : ℝ), f x ≤ ∑' (n : ℕ), f (n + N : ℕ) := by + rw [← summable_nat_add_iff N] at summable + have lim := summable.tendsto_sum_tsum_nat + have := tendsto_atTop_add_const_right atTop (N : ℝ) tendsto_natCast_atTop_atTop + have integrable := anti.integrableOn_Ioi_of_summable_comp_add summable nonneg + refine le_of_tendsto_of_tendsto (intervalIntegral_tendsto_integral_Ioi N integrable this) lim ?_ + filter_upwards with M + calc + _ ≤ ∑ n ∈ Finset.Ico N (N + M), f n := by + convert! AntitoneOn.integral_le_sum_Ico _ _ using 2 <;> grind [anti.mono] + _ = _ := by + rw [Finset.sum_Ico_eq_sum_range] + grind + +/-- The sum of a nonnegative, antitone function is bounded below by its integral. -/ +theorem AntitoneOn.integral_le_tsum (anti : AntitoneOn f (Ici 0)) + (summable : Summable (fun (n : ℕ) ↦ f n)) (nonneg : ∀ t ∈ Ioi 0, 0 ≤ f t) : + ∫ x in Ioi 0, f x ≤ ∑' (n : ℕ), f n := + mod_cast AntitoneOn.integral_le_tsum_comp_add 0 (mod_cast anti) summable (mod_cast nonneg) diff --git a/docs/undergrad.yaml b/docs/undergrad.yaml index 9c97063d8ff3cb..e5f5202fbfc094 100644 --- a/docs/undergrad.yaml +++ b/docs/undergrad.yaml @@ -298,7 +298,7 @@ Single Variable Real Analysis: Geometric series: 'tsum_geometric_of_norm_lt_one' convergence of $p$-series for $p>1$: 'Real.summable_one_div_nat_rpow' summation of comparison relations: 'http://braise.univ-rennes1.fr/donnees/ParamHTML/S%E9ries%20num%E9riques/Con/Sommation%20des%20relations%20de%20comparaison/cst.ps' - comparison of a series and an integral: 'https://en.wikipedia.org/wiki/Integral_test_for_convergence' + comparison of a series and an integral: 'AntitoneOn.tsum_le_integral' error estimation: 'https://en.wikipedia.org/wiki/Series_(mathematics)#Evaluation_of_truncation_errors' absolute convergence: 'https://en.wikipedia.org/wiki/Absolute_convergence' products of series: 'https://en.wikipedia.org/wiki/Cauchy_product' From d3555a86c61d1749dac1d4edc91d33c4659f11ae Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:32:41 +0000 Subject: [PATCH 0644/1300] feat: analytic extension of meromorphic functions (#40545) Add two simple theorems on analytic extension of meromorphic functions. Includes code donated by @unaoya Naoya Umezaki, modified by Claude Code. --- Mathlib/Analysis/Meromorphic/Order.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index dd421392c0de3e..08900fe127cc49 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -292,6 +292,19 @@ theorem AnalyticAt.meromorphicOrderAt_nonneg (hf : AnalyticAt 𝕜 f x) : 0 ≤ meromorphicOrderAt f x := by simp [hf.meromorphicOrderAt_eq] +/-- A meromorphic function has non-negative order iff there exists an analytic extension. -/ +theorem MeromorphicAt.meromorphicOrderAt_nonneg_iff + (hf : MeromorphicAt f x) : + 0 ≤ meromorphicOrderAt f x ↔ ∃ g : 𝕜 → E, AnalyticAt 𝕜 g x ∧ f =ᶠ[𝓝[≠] x] g := by + refine ⟨fun nneg ↦ ?_, fun ⟨g, hg₁, hg₂⟩ ↦ ?_⟩ + · cases h₀ : meromorphicOrderAt f x with + | top => exact ⟨0, analyticAt_const, meromorphicOrderAt_eq_top_iff.mp h₀⟩ + | coe n => + obtain ⟨g, hg, -, hfg⟩ := (meromorphicOrderAt_eq_int_iff hf).mp h₀ + refine ⟨fun z ↦ (z - x) ^ n • g z, ?_, hfg⟩ + exact (AnalyticAt.zpow_nonneg (by fun_prop) (by simpa [h₀] using nneg)).smul hg + · simp [meromorphicOrderAt_congr hg₂, hg₁.meromorphicOrderAt_nonneg] + /-- If a function is both meromorphic and continuous at a point, then it is analytic there. -/ protected theorem MeromorphicAt.analyticAt {f : 𝕜 → E} {x : 𝕜} (h : MeromorphicAt f x) (h' : ContinuousAt f x) : From 0893f079d7b8cba3b36ab06a1b45c36a30a5f07e Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:32:43 +0000 Subject: [PATCH 0645/1300] feat(Analysis/Complex/ExponentialBounds): add log 4 and log 10 lemmas (#40721) Co-authored-by: Terence Tao --- Mathlib/Analysis/Complex/ExponentialBounds.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Analysis/Complex/ExponentialBounds.lean b/Mathlib/Analysis/Complex/ExponentialBounds.lean index 190f489b95125a..74707109144088 100644 --- a/Mathlib/Analysis/Complex/ExponentialBounds.lean +++ b/Mathlib/Analysis/Complex/ExponentialBounds.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Complex.Exponential public import Mathlib.Analysis.SpecialFunctions.Log.Deriv +public import Mathlib.Analysis.SpecialFunctions.Pow.Real /-! # Bounds on specific values of the exponential @@ -103,6 +104,8 @@ theorem log_three_gt_d9 : 1.0986122885 < log 3 := theorem log_three_lt_d9 : log 3 < 1.0986122888 := lt_of_le_of_lt (sub_le_iff_le_add.1 (abs_sub_le_iff.1 log_three_near_10).1) (by norm_num) +theorem log_four_eq : log 4 = 2 * log 2 := by norm_num [← log_rpow] + theorem log_five_near_10 : |log 5 - 160943791243 / 100000000000| ≤ 1 / 10 ^ 10 := by suffices |log 5 - 160943791243 / 100000000000| ≤ (4 / 5) ^ 131 / 5⁻¹ + (1 / 10 ^ 10 - (4 / 5) ^ 131 / 5⁻¹) by @@ -121,4 +124,6 @@ theorem log_five_gt_d9 : 1.6094379123 < log 5 := theorem log_five_lt_d9 : log 5 < 1.6094379126 := lt_of_le_of_lt (sub_le_iff_le_add.1 (abs_sub_le_iff.1 log_five_near_10).1) (by norm_num) +theorem log_ten_eq : log 10 = log 2 + log 5 := by norm_num [← log_mul] + end Real From d630e71963eae2ec2771b31d00b0afb1af2d25f1 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:32:45 +0000 Subject: [PATCH 0646/1300] feat(Analysis/SpecialFunctions): images of Ioi/Ici/Icc/Ico/Ioc/Ioo/uIcc under exp and log (#41118) Add `image_exp_Ioi`, `image_exp_Ici`, `image_log_Ioi`, `image_log_Ici` as `simp` lemmas to compute the image of `Set.Ici a` and `Set.Ioi a` under `Real.exp` and `Real.log`. Also added similar lemmas for bounded intervals. Co-authored-by: Terence Tao --- Mathlib/Analysis/SpecialFunctions/Exp.lean | 40 +++++++++++++++++ .../Analysis/SpecialFunctions/Log/Basic.lean | 44 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/Mathlib/Analysis/SpecialFunctions/Exp.lean b/Mathlib/Analysis/SpecialFunctions/Exp.lean index 26a805eee4d867..f56bc3f95d4d05 100644 --- a/Mathlib/Analysis/SpecialFunctions/Exp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Exp.lean @@ -319,6 +319,46 @@ theorem coe_comp_expOrderIso : (↑) ∘ expOrderIso = exp := theorem range_exp : range exp = Set.Ioi 0 := by rw [← coe_comp_expOrderIso, range_comp, expOrderIso.range_eq, image_univ, Subtype.range_coe] +@[simp] +theorem image_exp_Ioi (a : ℝ) : exp '' Ioi a = Ioi (exp a) := + continuous_exp.continuousOn.image_Ioi_of_strictMonoOn (exp_strictMono.strictMonoOn _) + tendsto_exp_atTop + +@[simp] +theorem image_exp_Ici (a : ℝ) : exp '' Ici a = Ici (exp a) := + continuous_exp.continuousOn.image_Ici_of_monotoneOn (exp_strictMono.monotone.monotoneOn _) + tendsto_exp_atTop + +@[simp] +theorem image_exp_Icc (a b : ℝ) : exp '' Icc a b = Icc (exp a) (exp b) := + continuous_exp.image_Icc_of_strictMono exp_strictMono + +@[simp] +theorem image_exp_Ico (a b : ℝ) : exp '' Ico a b = Ico (exp a) (exp b) := + continuous_exp.image_Ico_of_strictMono exp_strictMono + +@[simp] +theorem image_exp_Ioc (a b : ℝ) : exp '' Ioc a b = Ioc (exp a) (exp b) := + continuous_exp.image_Ioc_of_strictMono exp_strictMono + +@[simp] +theorem image_exp_Ioo (a b : ℝ) : exp '' Ioo a b = Ioo (exp a) (exp b) := + continuous_exp.image_Ioo_of_strictMono exp_strictMono + +@[simp] +theorem image_exp_uIcc (a b : ℝ) : exp '' uIcc a b = uIcc (exp a) (exp b) := + continuous_exp.continuousOn.image_uIcc_of_monotoneOn (exp_strictMono.monotone.monotoneOn _) + +@[simp] +theorem image_exp_Iio (a : ℝ) : exp '' Iio a = Ioo 0 (exp a) := by + rw [← coe_comp_expOrderIso, image_comp, expOrderIso.image_Iio, image_subtype_val_Ioi_Iio, + Function.comp_apply] + +@[simp] +theorem image_exp_Iic (a : ℝ) : exp '' Iic a = Ioc 0 (exp a) := by + rw [← coe_comp_expOrderIso, image_comp, expOrderIso.image_Iic, image_subtype_val_Ioi_Iic, + Function.comp_apply] + @[simp] theorem map_exp_atTop : map exp atTop = atTop := by rw [← coe_comp_expOrderIso, ← Filter.map_map, OrderIso.map_atTop, map_val_Ioi_atTop] diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index cc7333c231aa1b..fe745c1c5d5d34 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -470,6 +470,50 @@ theorem isLittleO_const_log_atTop {c : ℝ} : (fun _ => c) =o[atTop] log := by continuousOn_toFun := continuousOn_exp continuousOn_invFun x hx := (continuousAt_log (ne_of_gt hx)).continuousWithinAt +@[simp] +theorem image_log_Ioi {a : ℝ} (ha : 0 < a) : log '' Ioi a = Ioi (log a) := + (continuousOn_log.mono fun _ hx ↦ (ha.trans_le hx).ne').image_Ioi_of_strictMonoOn + (strictMonoOn_log.mono fun _ hx ↦ ha.trans_le hx) tendsto_log_atTop + +@[simp] +theorem image_log_Ici {a : ℝ} (ha : 0 < a) : log '' Ici a = Ici (log a) := + (continuousOn_log.mono fun _ hx ↦ (ha.trans_le hx).ne').image_Ici_of_monotoneOn + (strictMonoOn_log.monotoneOn.mono fun _ hx ↦ ha.trans_le hx) tendsto_log_atTop + +@[simp] +theorem image_log_Icc {a b : ℝ} (ha : 0 < a) (hab : a ≤ b) : log '' Icc a b = Icc (log a) (log b) := + (continuousOn_log.mono fun _ hx ↦ (ha.trans_le hx.1).ne').image_Icc_of_monotoneOn hab + (strictMonoOn_log.monotoneOn.mono fun _ hx ↦ ha.trans_le hx.1) + +@[simp] +theorem image_log_Ico {a b : ℝ} (ha : 0 < a) (hab : a ≤ b) : log '' Ico a b = Ico (log a) (log b) := + (continuousOn_log.mono fun _ hx ↦ (ha.trans_le hx.1).ne').image_Ico_of_strictMonoOn hab + (strictMonoOn_log.mono fun _ hx ↦ ha.trans_le hx.1) + +@[simp] +theorem image_log_Ioc {a b : ℝ} (ha : 0 < a) (hab : a ≤ b) : log '' Ioc a b = Ioc (log a) (log b) := + (continuousOn_log.mono fun _ hx ↦ (ha.trans_le hx.1).ne').image_Ioc_of_strictMonoOn hab + (strictMonoOn_log.mono fun _ hx ↦ ha.trans_le hx.1) + +@[simp] +theorem image_log_Ioo {a b : ℝ} (ha : 0 < a) (hab : a ≤ b) : log '' Ioo a b = Ioo (log a) (log b) := + (continuousOn_log.mono fun _ hx ↦ (ha.trans_le hx.1).ne').image_Ioo_of_strictMonoOn hab + (strictMonoOn_log.mono fun _ hx ↦ ha.trans_le hx.1) + +@[simp] +theorem image_log_uIcc {a b : ℝ} (ha : 0 < a) (hb : 0 < b) : + log '' uIcc a b = uIcc (log a) (log b) := + (continuousOn_log.mono fun _ hx ↦ ((lt_min ha hb).trans_le hx.1).ne').image_uIcc_of_monotoneOn + (strictMonoOn_log.monotoneOn.mono fun _ hx ↦ (lt_min ha hb).trans_le hx.1) + +@[simp] +theorem image_log_Ioo_zero {a : ℝ} (ha : 0 < a) : log '' Ioo 0 a = Iio (log a) := by + nth_rw 1 [← exp_log ha, ← image_exp_Iio, ← image_comp, log_comp_exp, image_id] + +@[simp] +theorem image_log_Ioc_zero {a : ℝ} (ha : 0 < a) : log '' Ioc 0 a = Iic (log a) := by + nth_rw 1 [← exp_log ha, ← image_exp_Iic, ← image_comp, log_comp_exp, image_id] + end Real namespace Nat.Prime From 6fba560ee038f8effc5f40905103aeff6f468d72 Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Tue, 7 Jul 2026 20:32:47 +0000 Subject: [PATCH 0647/1300] doc(NumberTheory/ModularForms): remove a TODO which is done (#41281) --- Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean b/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean index 04d471e6120948..64cece13f17d6a 100644 --- a/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean @@ -15,8 +15,8 @@ public import Mathlib.NumberTheory.ModularForms.QExpansion This file contains results specific to modular forms of level one, i.e. modular forms for `SL(2, ℤ)`. -TODO: Add finite-dimensionality of these spaces of modular forms. - +Finite-dimensionality of these spaces is proved in a later file +(`Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean`). -/ public section From 10d7078a15f0d57f9bf9250d5e3425c562f4b939 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:32:49 +0000 Subject: [PATCH 0648/1300] doc(NumberTheory): fix Bernoulli polynomial theorem link (#41335) This fully qualifies the module-doc reference to `Polynomial.sum_bernoulli` so the generated docs link to the Bernoulli polynomial theorem in this file, rather than the root `sum_bernoulli` theorem for Bernoulli numbers. Co-authored-by: Yongxi Lin --- Mathlib/NumberTheory/BernoulliPolynomials.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/BernoulliPolynomials.lean b/Mathlib/NumberTheory/BernoulliPolynomials.lean index f2b7edd25d0dfd..21a770d7a26655 100644 --- a/Mathlib/NumberTheory/BernoulliPolynomials.lean +++ b/Mathlib/NumberTheory/BernoulliPolynomials.lean @@ -29,7 +29,7 @@ Bernoulli polynomials are defined using `bernoulli`, the Bernoulli numbers. ## Main theorems -- `sum_bernoulli`: The sum of the $k^\mathrm{th}$ Bernoulli polynomial with binomial +- `Polynomial.sum_bernoulli`: The sum of the $k^\mathrm{th}$ Bernoulli polynomial with binomial coefficients up to `n` is `(n + 1) * X^n`. - `Polynomial.bernoulli_generating_function`: The Bernoulli polynomials act as generating functions for the exponential. From 23b2504460d6e616ea7a7da3bdbcef9daa683e0c Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:32:51 +0000 Subject: [PATCH 0649/1300] chore: split `BoundedVariation` (#41421) Extract the part on `variationOnFromTo`. Otherwise, the file will get over the limit in a subsequent PR. This is a pure split, no material added or removed. Co-authored-by: sgouezel --- Mathlib.lean | 1 + Mathlib/Analysis/BoundedVariation.lean | 2 +- Mathlib/Analysis/ConstantSpeed.lean | 2 +- .../VectorMeasure/BoundedVariation.lean | 2 +- .../EMetricSpace/BoundedVariation.lean | 296 ---------------- .../EMetricSpace/VariationOnFromTo.lean | 320 ++++++++++++++++++ 6 files changed, 324 insertions(+), 299 deletions(-) create mode 100644 Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean diff --git a/Mathlib.lean b/Mathlib.lean index 6ef83cb76ea317..8493722be7dc63 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7895,6 +7895,7 @@ public import Mathlib.Topology.EMetricSpace.Lipschitz public import Mathlib.Topology.EMetricSpace.PairReduction public import Mathlib.Topology.EMetricSpace.Paracompact public import Mathlib.Topology.EMetricSpace.Pi +public import Mathlib.Topology.EMetricSpace.VariationOnFromTo public import Mathlib.Topology.EMetricSpace.Weak public import Mathlib.Topology.ExtendFrom public import Mathlib.Topology.ExtremallyDisconnected diff --git a/Mathlib/Analysis/BoundedVariation.lean b/Mathlib/Analysis/BoundedVariation.lean index 983845d98394a1..a7d9407eecf000 100644 --- a/Mathlib/Analysis/BoundedVariation.lean +++ b/Mathlib/Analysis/BoundedVariation.lean @@ -8,7 +8,7 @@ module public import Mathlib.Analysis.Calculus.FDeriv.Equiv public import Mathlib.Analysis.Calculus.FDeriv.Prod public import Mathlib.Analysis.Calculus.Monotone -public import Mathlib.Topology.EMetricSpace.BoundedVariation +public import Mathlib.Topology.EMetricSpace.VariationOnFromTo /-! # Almost everywhere differentiability of functions with locally bounded variation diff --git a/Mathlib/Analysis/ConstantSpeed.lean b/Mathlib/Analysis/ConstantSpeed.lean index 2af9ce0d7bf53b..7eef2a7b6988ce 100644 --- a/Mathlib/Analysis/ConstantSpeed.lean +++ b/Mathlib/Analysis/ConstantSpeed.lean @@ -7,7 +7,7 @@ module public import Mathlib.Data.Set.Function public import Mathlib.Analysis.RCLike.Basic -public import Mathlib.Topology.EMetricSpace.BoundedVariation +public import Mathlib.Topology.EMetricSpace.VariationOnFromTo /-! # Constant speed diff --git a/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean b/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean index c053ad9ee7f9c9..505009ea9beeb5 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean @@ -8,7 +8,7 @@ module public import Mathlib.Analysis.Normed.Group.Defs public import Mathlib.MeasureTheory.Measure.Stieltjes public import Mathlib.MeasureTheory.VectorMeasure.Basic -public import Mathlib.Topology.EMetricSpace.BoundedVariation +public import Mathlib.Topology.EMetricSpace.VariationOnFromTo import Mathlib.MeasureTheory.VectorMeasure.AddContent diff --git a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean index ad2563a2b56bfb..20e89be5466d28 100644 --- a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean +++ b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean @@ -48,7 +48,6 @@ that the sets one uses are nonempty and bounded above as these are only conditio @[expose] public section - open scoped NNReal ENNReal Topology UniformConvergence open Set Filter OrderDual @@ -1129,301 +1128,6 @@ theorem MonotoneOn.boundedVariationOn grw [hf.eVariationOn_le as bs] exact ENNReal.ofReal_mono (by grind) -/-- The **signed** variation of `f` on the interval `Icc a b` intersected with the set `s`, -squashed to a real (therefore only really meaningful if the variation is finite) --/ -noncomputable def variationOnFromTo (f : α → E) (s : Set α) (a b : α) : ℝ := - if a ≤ b then (eVariationOn f (s ∩ Icc a b)).toReal else -(eVariationOn f (s ∩ Icc b a)).toReal - -namespace variationOnFromTo - -variable (f : α → E) (s : Set α) - -protected theorem self (a : α) : variationOnFromTo f s a a = 0 := by - dsimp only [variationOnFromTo] - rw [if_pos le_rfl, Icc_self, eVariationOn.subsingleton, ENNReal.toReal_zero] - exact fun x hx y hy => hx.2.trans hy.2.symm - -protected theorem nonneg_of_le {a b : α} (h : a ≤ b) : 0 ≤ variationOnFromTo f s a b := by - simp only [variationOnFromTo, if_pos h, ENNReal.toReal_nonneg] - -protected theorem eq_neg_swap (a b : α) : - variationOnFromTo f s a b = -variationOnFromTo f s b a := by - rcases lt_trichotomy a b with (ab | rfl | ba) - · simp only [variationOnFromTo, if_pos ab.le, if_neg ab.not_ge, neg_neg] - · simp only [variationOnFromTo.self, neg_zero] - · simp only [variationOnFromTo, if_pos ba.le, if_neg ba.not_ge] - -protected theorem nonpos_of_ge {a b : α} (h : b ≤ a) : variationOnFromTo f s a b ≤ 0 := by - rw [variationOnFromTo.eq_neg_swap] - exact neg_nonpos_of_nonneg (variationOnFromTo.nonneg_of_le f s h) - -variable {f s} in -theorem abs_le_eVariationOn (hf : BoundedVariationOn f s) {a b : α} : - |variationOnFromTo f s a b| ≤ (eVariationOn f s).toReal := by - by_cases hab : a ≤ b - · simp only [variationOnFromTo, hab, ↓reduceIte, ENNReal.abs_toReal] - exact ENNReal.toReal_mono hf (eVariationOn.mono _ inter_subset_left) - · simp only [variationOnFromTo, hab, ↓reduceIte, abs_neg, ENNReal.abs_toReal] - exact ENNReal.toReal_mono hf (eVariationOn.mono _ inter_subset_left) - -protected theorem eq_of_le {a b : α} (h : a ≤ b) : - variationOnFromTo f s a b = (eVariationOn f (s ∩ Icc a b)).toReal := - if_pos h - -protected theorem eq_of_ge {a b : α} (h : b ≤ a) : - variationOnFromTo f s a b = -(eVariationOn f (s ∩ Icc b a)).toReal := by - rw [variationOnFromTo.eq_neg_swap, neg_inj, variationOnFromTo.eq_of_le f s h] - -protected theorem add {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} - (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : - variationOnFromTo f s a b + variationOnFromTo f s b c = variationOnFromTo f s a c := by - symm - refine additive_of_total (· ≤ · : α → α → Prop) (variationOnFromTo f s) (· ∈ s) ?_ ?_ ha hb hc - · rintro x y _xs _ys - simp only [variationOnFromTo.eq_neg_swap f s y x, add_neg_cancel] - · rintro x y z xy yz xs ys zs - rw [variationOnFromTo.eq_of_le f s xy, variationOnFromTo.eq_of_le f s yz, - variationOnFromTo.eq_of_le f s (xy.trans yz), - ← ENNReal.toReal_add (hf x y xs ys) (hf y z ys zs), eVariationOn.Icc_add_Icc f xy yz ys] - -protected theorem sub_right {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} - (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : - variationOnFromTo f s a b - variationOnFromTo f s a c = variationOnFromTo f s c b := by - rw [← variationOnFromTo.add hf ha hc hb, add_sub_cancel_left] - -protected theorem sub_left {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} - (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : - variationOnFromTo f s a b - variationOnFromTo f s c b = variationOnFromTo f s a c := by - rw [← variationOnFromTo.add hf ha hc hb, add_sub_cancel_right] - -variable {f s} in -protected theorem edist_zero_of_eq_zero (hf : LocallyBoundedVariationOn f s) - {a b : α} (ha : a ∈ s) (hb : b ∈ s) (h : variationOnFromTo f s a b = 0) : - edist (f a) (f b) = 0 := by - wlog h' : a ≤ b - · rw [edist_comm] - apply this hf hb ha _ (le_of_not_ge h') - rw [variationOnFromTo.eq_neg_swap, h, neg_zero] - · rw [← nonpos_iff_eq_zero, ← ENNReal.ofReal_zero, ← h, variationOnFromTo.eq_of_le f s h', - ENNReal.ofReal_toReal (hf a b ha hb)] - apply eVariationOn.edist_le - exacts [⟨ha, ⟨le_rfl, h'⟩⟩, ⟨hb, ⟨h', le_rfl⟩⟩] - -protected theorem eq_left_iff {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) - {a b c : α} (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : - variationOnFromTo f s a b = variationOnFromTo f s a c ↔ variationOnFromTo f s b c = 0 := by - simp only [← variationOnFromTo.add hf ha hb hc, left_eq_add] - -protected theorem eq_zero_iff_of_le {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) - {a b : α} (ha : a ∈ s) (hb : b ∈ s) (ab : a ≤ b) : - variationOnFromTo f s a b = 0 ↔ - ∀ ⦃x⦄ (_hx : x ∈ s ∩ Icc a b) ⦃y⦄ (_hy : y ∈ s ∩ Icc a b), edist (f x) (f y) = 0 := by - rw [variationOnFromTo.eq_of_le _ _ ab, ENNReal.toReal_eq_zero_iff, or_iff_left (hf a b ha hb), - eVariationOn.eq_zero_iff] - -protected theorem eq_zero_iff_of_ge {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) - {a b : α} (ha : a ∈ s) (hb : b ∈ s) (ba : b ≤ a) : - variationOnFromTo f s a b = 0 ↔ - ∀ ⦃x⦄ (_hx : x ∈ s ∩ Icc b a) ⦃y⦄ (_hy : y ∈ s ∩ Icc b a), edist (f x) (f y) = 0 := by - rw [variationOnFromTo.eq_of_ge _ _ ba, neg_eq_zero, ENNReal.toReal_eq_zero_iff, - or_iff_left (hf b a hb ha), eVariationOn.eq_zero_iff] - -protected theorem eq_zero_iff {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b : α} - (ha : a ∈ s) (hb : b ∈ s) : - variationOnFromTo f s a b = 0 ↔ - ∀ ⦃x⦄ (_hx : x ∈ s ∩ uIcc a b) ⦃y⦄ (_hy : y ∈ s ∩ uIcc a b), edist (f x) (f y) = 0 := by - rcases le_total a b with (ab | ba) - · rw [uIcc_of_le ab] - exact variationOnFromTo.eq_zero_iff_of_le hf ha hb ab - · rw [uIcc_of_ge ba] - exact variationOnFromTo.eq_zero_iff_of_ge hf ha hb ba - -variable {f} {s} - -protected theorem monotoneOn (hf : LocallyBoundedVariationOn f s) {a : α} (as : a ∈ s) : - MonotoneOn (variationOnFromTo f s a) s := by - rintro b bs c cs bc - rw [← variationOnFromTo.add hf as bs cs] - exact le_add_of_nonneg_right (variationOnFromTo.nonneg_of_le f s bc) - -protected theorem antitoneOn (hf : LocallyBoundedVariationOn f s) {b : α} (bs : b ∈ s) : - AntitoneOn (fun a => variationOnFromTo f s a b) s := by - rintro a as c cs ac - dsimp only - rw [← variationOnFromTo.add hf as cs bs] - exact le_add_of_nonneg_left (variationOnFromTo.nonneg_of_le f s ac) - -lemma abs_sub_le_sub_of_le {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s) - {a b c : α} (as : a ∈ s) (bs : b ∈ s) (cs : c ∈ s) (bc : b ≤ c) : - |f c - f b| ≤ variationOnFromTo f s a c - variationOnFromTo f s a b := calc - _ = dist (f b) (f c) := by rw [dist_comm, Real.dist_eq] - _ ≤ variationOnFromTo f s b c := by - rw [variationOnFromTo.eq_of_le f s bc, dist_edist] - apply ENNReal.toReal_mono (hf b c bs cs) - apply eVariationOn.edist_le f - exacts [⟨bs, le_rfl, bc⟩, ⟨cs, bc, le_rfl⟩] - _ = variationOnFromTo f s a c - variationOnFromTo f s a b := by - rw [← variationOnFromTo.add hf as bs cs, add_sub_cancel_left] - -protected theorem add_self_monotoneOn {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s) - {a : α} (as : a ∈ s) : MonotoneOn (variationOnFromTo f s a + f) s := by - rintro b bs c cs bc - suffices f b - f c ≤ variationOnFromTo f s a c - variationOnFromTo f s a b by simp; linarith - calc - f b - f c ≤ |f c - f b| := by grw [le_abs_self (f b - f c), abs_sub_comm (f b) (f c)] - _ ≤ variationOnFromTo f s a c - variationOnFromTo f s a b := abs_sub_le_sub_of_le hf as bs cs bc - -protected theorem sub_self_monotoneOn {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s) - {a : α} (as : a ∈ s) : MonotoneOn (variationOnFromTo f s a - f) s := by - rintro b bs c cs bc - rw [Pi.sub_apply, Pi.sub_apply, le_sub_iff_add_le, add_comm_sub, ← le_sub_iff_add_le'] - calc - f c - f b ≤ |f c - f b| := le_abs_self _ - _ ≤ variationOnFromTo f s a c - variationOnFromTo f s a b := abs_sub_le_sub_of_le hf as bs cs bc - -protected theorem comp_eq_of_monotoneOn {β : Type*} [LinearOrder β] (f : α → E) {t : Set β} - (φ : β → α) (hφ : MonotoneOn φ t) {x y : β} (hx : x ∈ t) (hy : y ∈ t) : - variationOnFromTo (f ∘ φ) t x y = variationOnFromTo f (φ '' t) (φ x) (φ y) := by - rcases le_total x y with (h | h) - · rw [variationOnFromTo.eq_of_le _ _ h, variationOnFromTo.eq_of_le _ _ (hφ hx hy h), - eVariationOn.comp_inter_Icc_eq_of_monotoneOn f φ hφ hx hy] - · rw [variationOnFromTo.eq_of_ge _ _ h, variationOnFromTo.eq_of_ge _ _ (hφ hy hx h), - eVariationOn.comp_inter_Icc_eq_of_monotoneOn f φ hφ hy hx] - -/-- The jump of `variationOnFromTo` on the left of a point is given by the distance between the -left limit and the value of the function. -/ -theorem tendsto_left {E : Type*} [PseudoMetricSpace E] [TopologicalSpace α] [OrderTopology α] - {f : α → E} {l : E} {a b : α} (ha : a ∈ s) (hb : b ∈ s) - (hf : LocallyBoundedVariationOn f s) (h'f : Tendsto f (𝓝[s ∩ Iio b] b) (𝓝 l)) : - Tendsto (variationOnFromTo f s a) (𝓝[s ∩ Iio b] b) - (𝓝 (variationOnFromTo f s a b - dist (f b) l)) := by - suffices H : Tendsto (fun x ↦ variationOnFromTo f s a b - variationOnFromTo f s x b) - (𝓝[s ∩ Iio b] b) (𝓝 (variationOnFromTo f s a b - dist (f b) l)) by - apply Tendsto.congr' _ H - filter_upwards [self_mem_nhdsWithin] with x hx - rw [variationOnFromTo.sub_left hf ha hb hx.1] - apply Tendsto.const_sub - suffices H : Tendsto (fun x ↦ (eVariationOn f (s ∩ Icc x b)).toReal) (𝓝[s ∩ Iio b] b) - (𝓝 (dist (f b) l)) by - apply Tendsto.congr' _ H - filter_upwards [self_mem_nhdsWithin] with x hx using by simp [variationOnFromTo, hx.2.le] - rw [dist_edist] - exact (ENNReal.tendsto_toReal (by simp)).comp (hf.tendsto_eVariationOn_Icc_left h'f hb) - -/-- The jump of `variationOnFromTo` on the right of a point is given by the distance between the -right limit and the value of the function. -/ -theorem tendsto_right {E : Type*} [PseudoMetricSpace E] [TopologicalSpace α] [OrderTopology α] - {f : α → E} {l : E} {a b : α} (ha : a ∈ s) (hb : b ∈ s) - (hf : LocallyBoundedVariationOn f s) (h'f : Tendsto f (𝓝[s ∩ Ioi b] b) (𝓝 l)) : - Tendsto (variationOnFromTo f s a) (𝓝[s ∩ Ioi b] b) - (𝓝 (variationOnFromTo f s a b + dist (f b) l)) := by - suffices H : Tendsto (fun x ↦ variationOnFromTo f s a b + variationOnFromTo f s b x) - (𝓝[s ∩ Ioi b] b) (𝓝 (variationOnFromTo f s a b + dist (f b) l)) by - apply Tendsto.congr' _ H - filter_upwards [self_mem_nhdsWithin] with x hx - rw [variationOnFromTo.add hf ha hb hx.1] - apply Tendsto.const_add - suffices H : Tendsto (fun x ↦ (eVariationOn f (s ∩ Icc b x)).toReal) (𝓝[s ∩ Ioi b] b) - (𝓝 (dist (f b) l)) by - apply Tendsto.congr' _ H - filter_upwards [self_mem_nhdsWithin] with x hx using by simp [variationOnFromTo, hx.2.le] - rw [dist_edist] - exact (ENNReal.tendsto_toReal (by simp)).comp (hf.tendsto_eVariationOn_Icc_right h'f hb) - -/-- The jump of `variationOnFromTo` on the left of a point is given by the distance between the -left limit and the value of the function. -/ -theorem leftLim_eq {E : Type*} [PseudoMetricSpace E] [CompleteSpace E] - {f : α → E} {a b : α} (hf : BoundedVariationOn f univ) : - (variationOnFromTo f univ a).leftLim b = - variationOnFromTo f univ a b - dist (f b) (f.leftLim b) := by - let : TopologicalSpace α := Preorder.topology α - have : OrderTopology α := ⟨rfl⟩ - rcases eq_or_neBot (𝓝[<] b) with hb | hb - · simp [leftLim_eq_of_eq_bot _ hb] - apply leftLim_eq_of_tendsto - have := variationOnFromTo.tendsto_left (f := f) (l := f.leftLim b) (mem_univ a) (mem_univ b) - hf.locallyBoundedVariationOn - simp only [univ_inter] at this - exact this (hf.tendsto_leftLim _) - -/-- The jump of `variationOnFromTo` on the right of a point is given by the distance between the -right limit and the value of the function. -/ -theorem rightLim_eq {E : Type*} [PseudoMetricSpace E] [CompleteSpace E] - {f : α → E} {a b : α} (hf : BoundedVariationOn f univ) : - (variationOnFromTo f univ a).rightLim b = - variationOnFromTo f univ a b + dist (f b) (f.rightLim b) := by - let : TopologicalSpace α := Preorder.topology α - have : OrderTopology α := ⟨rfl⟩ - rcases eq_or_neBot (𝓝[>] b) with hb | hb - · simp [rightLim_eq_of_eq_bot _ hb] - apply rightLim_eq_of_tendsto - have := variationOnFromTo.tendsto_right (f := f) (l := f.rightLim b) (mem_univ a) (mem_univ b) - hf.locallyBoundedVariationOn - simp only [univ_inter] at this - exact this (hf.tendsto_rightLim _) - -theorem _root_.BoundedVariationOn.continuousWithinAt_variationOnFromTo_Ici - [TopologicalSpace α] [OrderTopology α] (hf : BoundedVariationOn f univ) {a x : α} - (hx : ContinuousWithinAt f (Ici x) x) : - ContinuousWithinAt (variationOnFromTo f univ a) (Ici x) x := by - have : variationOnFromTo f univ a = - fun y ↦ variationOnFromTo f univ a x + variationOnFromTo f univ x y := by - ext y - rw [variationOnFromTo.add hf.locallyBoundedVariationOn (mem_univ _) (mem_univ _) (mem_univ _)] - rw [this] - apply continuousWithinAt_const.add - suffices H : ContinuousWithinAt (fun y ↦ (eVariationOn f (univ ∩ Icc x y)).toReal) (Ici x) x from - H.congr_of_mem (fun y hy ↦ by grind [variationOnFromTo]) self_mem_Iic - simp only [ContinuousWithinAt, Icc_self] - rw [eVariationOn.subsingleton _ (by grind [Set.Subsingleton])] - apply (ENNReal.tendsto_toReal ENNReal.zero_ne_top).comp - apply Tendsto.mono_left _ (nhdsWithin_mono _ (subset_univ _)) - exact hf.tendsto_eVariationOn_Icc_zero_right _ (by simpa using hx) - -theorem _root_.BoundedVariationOn.continuousWithinAt_variationOnFromTo_rightLim_Ici - [TopologicalSpace α] [OrderTopology α] [T3Space E] [CompleteSpace E] - (hf : BoundedVariationOn f univ) {a x : α} : - ContinuousWithinAt (variationOnFromTo f.rightLim univ a) (Ici x) x := - hf.rightLim.continuousWithinAt_variationOnFromTo_Ici hf.continuousWithinAt_rightLim - -end variationOnFromTo - -/-- If a real-valued function has bounded variation on a set, then it is a difference of monotone -functions there. Moreover, one can make sure that the two monotone functions add up to the -variation of `f`. -/ -theorem LocallyBoundedVariationOn.exists_monotoneOn_sub_monotoneOn' {f : α → ℝ} {s : Set α} - (h : LocallyBoundedVariationOn f s) : - ∃ p q : α → ℝ, MonotoneOn p s ∧ MonotoneOn q s ∧ f = p - q ∧ - ∀ x ∈ s, ∀ y ∈ s, (p y - p x) + (q y - q x) = variationOnFromTo f s x y := by - rcases eq_empty_or_nonempty s with (rfl | ⟨c, cs⟩) - · refine ⟨f, 0, subsingleton_empty.monotoneOn _, subsingleton_empty.monotoneOn _, - (sub_zero f).symm, fun x hx y hy ↦ by simp at hx⟩ - refine ⟨fun x ↦ (variationOnFromTo f s c x + f x) / 2, - fun x ↦ (variationOnFromTo f s c x - f x) / 2, ?_, ?_, ?_, ?_⟩ - · intro x hx y hy hxy - dsimp - gcongr 1 - simpa using variationOnFromTo.add_self_monotoneOn h cs hx hy hxy - · intro x hx y hy hxy - dsimp - gcongr 1 - simpa using variationOnFromTo.sub_self_monotoneOn h cs hx hy hxy - · ext - simp - ring - · intro x hx y hy - rw [← variationOnFromTo.add h hx cs hy, variationOnFromTo.eq_neg_swap] - ring - -/-- If a real-valued function has bounded variation on a set, then it is a difference of monotone -functions there. -/ -theorem LocallyBoundedVariationOn.exists_monotoneOn_sub_monotoneOn {f : α → ℝ} {s : Set α} - (h : LocallyBoundedVariationOn f s) : - ∃ p q : α → ℝ, MonotoneOn p s ∧ MonotoneOn q s ∧ f = p - q := by - rcases h.exists_monotoneOn_sub_monotoneOn' with ⟨p, q, hp, hq, h'f, -⟩ - exact ⟨p, q, hp, hq, h'f⟩ - /-! ### Lipschitz functions and bounded variation -/ section LipschitzOnWith diff --git a/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean b/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean new file mode 100644 index 00000000000000..02ef52c23a7f0e --- /dev/null +++ b/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean @@ -0,0 +1,320 @@ +/- +Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.Analysis.Normed.Group.Real +public import Mathlib.Topology.EMetricSpace.BoundedVariation + +/-! +# Signed variation + +We define `variationOnFromTo f s a b : ℝ` as the signed variation of `f` between `a` and `b`, i.e., +its variation if `a ≤ b`, and its opposite otherwise. We establish basic properties of this notion, +and use it to show that a bounded variation real function is the difference of two monotone +functions. + -/ + +@[expose] public section + +open scoped ENNReal Topology +open Set Filter + +variable {α : Type*} [LinearOrder α] {E : Type*} [PseudoEMetricSpace E] + +/-- The **signed** variation of `f` on the interval `Icc a b` intersected with the set `s`, +squashed to a real (therefore only really meaningful if the variation is finite) +-/ +noncomputable def variationOnFromTo (f : α → E) (s : Set α) (a b : α) : ℝ := + if a ≤ b then (eVariationOn f (s ∩ Icc a b)).toReal else -(eVariationOn f (s ∩ Icc b a)).toReal + +namespace variationOnFromTo + +variable (f : α → E) (s : Set α) + +protected theorem self (a : α) : variationOnFromTo f s a a = 0 := by + dsimp only [variationOnFromTo] + rw [if_pos le_rfl, Icc_self, eVariationOn.subsingleton, ENNReal.toReal_zero] + exact fun x hx y hy => hx.2.trans hy.2.symm + +protected theorem nonneg_of_le {a b : α} (h : a ≤ b) : 0 ≤ variationOnFromTo f s a b := by + simp only [variationOnFromTo, if_pos h, ENNReal.toReal_nonneg] + +protected theorem eq_neg_swap (a b : α) : + variationOnFromTo f s a b = -variationOnFromTo f s b a := by + rcases lt_trichotomy a b with (ab | rfl | ba) + · simp only [variationOnFromTo, if_pos ab.le, if_neg ab.not_ge, neg_neg] + · simp only [variationOnFromTo.self, neg_zero] + · simp only [variationOnFromTo, if_pos ba.le, if_neg ba.not_ge] + +protected theorem nonpos_of_ge {a b : α} (h : b ≤ a) : variationOnFromTo f s a b ≤ 0 := by + rw [variationOnFromTo.eq_neg_swap] + exact neg_nonpos_of_nonneg (variationOnFromTo.nonneg_of_le f s h) + +variable {f s} in +theorem abs_le_eVariationOn (hf : BoundedVariationOn f s) {a b : α} : + |variationOnFromTo f s a b| ≤ (eVariationOn f s).toReal := by + by_cases hab : a ≤ b + · simp only [variationOnFromTo, hab, ↓reduceIte, ENNReal.abs_toReal] + exact ENNReal.toReal_mono hf (eVariationOn.mono _ inter_subset_left) + · simp only [variationOnFromTo, hab, ↓reduceIte, abs_neg, ENNReal.abs_toReal] + exact ENNReal.toReal_mono hf (eVariationOn.mono _ inter_subset_left) + +protected theorem eq_of_le {a b : α} (h : a ≤ b) : + variationOnFromTo f s a b = (eVariationOn f (s ∩ Icc a b)).toReal := + if_pos h + +protected theorem eq_of_ge {a b : α} (h : b ≤ a) : + variationOnFromTo f s a b = -(eVariationOn f (s ∩ Icc b a)).toReal := by + rw [variationOnFromTo.eq_neg_swap, neg_inj, variationOnFromTo.eq_of_le f s h] + +protected theorem add {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} + (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : + variationOnFromTo f s a b + variationOnFromTo f s b c = variationOnFromTo f s a c := by + symm + refine additive_of_total (· ≤ · : α → α → Prop) (variationOnFromTo f s) (· ∈ s) ?_ ?_ ha hb hc + · rintro x y _xs _ys + simp only [variationOnFromTo.eq_neg_swap f s y x, add_neg_cancel] + · rintro x y z xy yz xs ys zs + rw [variationOnFromTo.eq_of_le f s xy, variationOnFromTo.eq_of_le f s yz, + variationOnFromTo.eq_of_le f s (xy.trans yz), + ← ENNReal.toReal_add (hf x y xs ys) (hf y z ys zs), eVariationOn.Icc_add_Icc f xy yz ys] + +protected theorem sub_right {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} + (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : + variationOnFromTo f s a b - variationOnFromTo f s a c = variationOnFromTo f s c b := by + rw [← variationOnFromTo.add hf ha hc hb, add_sub_cancel_left] + +protected theorem sub_left {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b c : α} + (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : + variationOnFromTo f s a b - variationOnFromTo f s c b = variationOnFromTo f s a c := by + rw [← variationOnFromTo.add hf ha hc hb, add_sub_cancel_right] + +variable {f s} in +protected theorem edist_zero_of_eq_zero (hf : LocallyBoundedVariationOn f s) + {a b : α} (ha : a ∈ s) (hb : b ∈ s) (h : variationOnFromTo f s a b = 0) : + edist (f a) (f b) = 0 := by + wlog h' : a ≤ b + · rw [edist_comm] + apply this hf hb ha _ (le_of_not_ge h') + rw [variationOnFromTo.eq_neg_swap, h, neg_zero] + · rw [← nonpos_iff_eq_zero, ← ENNReal.ofReal_zero, ← h, variationOnFromTo.eq_of_le f s h', + ENNReal.ofReal_toReal (hf a b ha hb)] + apply eVariationOn.edist_le + exacts [⟨ha, ⟨le_rfl, h'⟩⟩, ⟨hb, ⟨h', le_rfl⟩⟩] + +protected theorem eq_left_iff {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) + {a b c : α} (ha : a ∈ s) (hb : b ∈ s) (hc : c ∈ s) : + variationOnFromTo f s a b = variationOnFromTo f s a c ↔ variationOnFromTo f s b c = 0 := by + simp only [← variationOnFromTo.add hf ha hb hc, left_eq_add] + +protected theorem eq_zero_iff_of_le {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) + {a b : α} (ha : a ∈ s) (hb : b ∈ s) (ab : a ≤ b) : + variationOnFromTo f s a b = 0 ↔ + ∀ ⦃x⦄ (_hx : x ∈ s ∩ Icc a b) ⦃y⦄ (_hy : y ∈ s ∩ Icc a b), edist (f x) (f y) = 0 := by + rw [variationOnFromTo.eq_of_le _ _ ab, ENNReal.toReal_eq_zero_iff, or_iff_left (hf a b ha hb), + eVariationOn.eq_zero_iff] + +protected theorem eq_zero_iff_of_ge {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) + {a b : α} (ha : a ∈ s) (hb : b ∈ s) (ba : b ≤ a) : + variationOnFromTo f s a b = 0 ↔ + ∀ ⦃x⦄ (_hx : x ∈ s ∩ Icc b a) ⦃y⦄ (_hy : y ∈ s ∩ Icc b a), edist (f x) (f y) = 0 := by + rw [variationOnFromTo.eq_of_ge _ _ ba, neg_eq_zero, ENNReal.toReal_eq_zero_iff, + or_iff_left (hf b a hb ha), eVariationOn.eq_zero_iff] + +protected theorem eq_zero_iff {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a b : α} + (ha : a ∈ s) (hb : b ∈ s) : + variationOnFromTo f s a b = 0 ↔ + ∀ ⦃x⦄ (_hx : x ∈ s ∩ uIcc a b) ⦃y⦄ (_hy : y ∈ s ∩ uIcc a b), edist (f x) (f y) = 0 := by + rcases le_total a b with (ab | ba) + · rw [uIcc_of_le ab] + exact variationOnFromTo.eq_zero_iff_of_le hf ha hb ab + · rw [uIcc_of_ge ba] + exact variationOnFromTo.eq_zero_iff_of_ge hf ha hb ba + +variable {f} {s} + +protected theorem monotoneOn (hf : LocallyBoundedVariationOn f s) {a : α} (as : a ∈ s) : + MonotoneOn (variationOnFromTo f s a) s := by + rintro b bs c cs bc + rw [← variationOnFromTo.add hf as bs cs] + exact le_add_of_nonneg_right (variationOnFromTo.nonneg_of_le f s bc) + +protected theorem antitoneOn (hf : LocallyBoundedVariationOn f s) {b : α} (bs : b ∈ s) : + AntitoneOn (fun a => variationOnFromTo f s a b) s := by + rintro a as c cs ac + dsimp only + rw [← variationOnFromTo.add hf as cs bs] + exact le_add_of_nonneg_left (variationOnFromTo.nonneg_of_le f s ac) + +lemma abs_sub_le_sub_of_le {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s) + {a b c : α} (as : a ∈ s) (bs : b ∈ s) (cs : c ∈ s) (bc : b ≤ c) : + |f c - f b| ≤ variationOnFromTo f s a c - variationOnFromTo f s a b := calc + _ = dist (f b) (f c) := by rw [dist_comm, Real.dist_eq] + _ ≤ variationOnFromTo f s b c := by + rw [variationOnFromTo.eq_of_le f s bc, dist_edist] + apply ENNReal.toReal_mono (hf b c bs cs) + apply eVariationOn.edist_le f + exacts [⟨bs, le_rfl, bc⟩, ⟨cs, bc, le_rfl⟩] + _ = variationOnFromTo f s a c - variationOnFromTo f s a b := by + rw [← variationOnFromTo.add hf as bs cs, add_sub_cancel_left] + +protected theorem add_self_monotoneOn {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s) + {a : α} (as : a ∈ s) : MonotoneOn (variationOnFromTo f s a + f) s := by + rintro b bs c cs bc + suffices f b - f c ≤ variationOnFromTo f s a c - variationOnFromTo f s a b by simp; linarith + calc + f b - f c ≤ |f c - f b| := by grw [le_abs_self (f b - f c), abs_sub_comm (f b) (f c)] + _ ≤ variationOnFromTo f s a c - variationOnFromTo f s a b := abs_sub_le_sub_of_le hf as bs cs bc + +protected theorem sub_self_monotoneOn {f : α → ℝ} {s : Set α} (hf : LocallyBoundedVariationOn f s) + {a : α} (as : a ∈ s) : MonotoneOn (variationOnFromTo f s a - f) s := by + rintro b bs c cs bc + rw [Pi.sub_apply, Pi.sub_apply, le_sub_iff_add_le, add_comm_sub, ← le_sub_iff_add_le'] + calc + f c - f b ≤ |f c - f b| := le_abs_self _ + _ ≤ variationOnFromTo f s a c - variationOnFromTo f s a b := abs_sub_le_sub_of_le hf as bs cs bc + +protected theorem comp_eq_of_monotoneOn {β : Type*} [LinearOrder β] (f : α → E) {t : Set β} + (φ : β → α) (hφ : MonotoneOn φ t) {x y : β} (hx : x ∈ t) (hy : y ∈ t) : + variationOnFromTo (f ∘ φ) t x y = variationOnFromTo f (φ '' t) (φ x) (φ y) := by + rcases le_total x y with (h | h) + · rw [variationOnFromTo.eq_of_le _ _ h, variationOnFromTo.eq_of_le _ _ (hφ hx hy h), + eVariationOn.comp_inter_Icc_eq_of_monotoneOn f φ hφ hx hy] + · rw [variationOnFromTo.eq_of_ge _ _ h, variationOnFromTo.eq_of_ge _ _ (hφ hy hx h), + eVariationOn.comp_inter_Icc_eq_of_monotoneOn f φ hφ hy hx] + +/-- The jump of `variationOnFromTo` on the left of a point is given by the distance between the +left limit and the value of the function. -/ +theorem tendsto_left {E : Type*} [PseudoMetricSpace E] [TopologicalSpace α] [OrderTopology α] + {f : α → E} {l : E} {a b : α} (ha : a ∈ s) (hb : b ∈ s) + (hf : LocallyBoundedVariationOn f s) (h'f : Tendsto f (𝓝[s ∩ Iio b] b) (𝓝 l)) : + Tendsto (variationOnFromTo f s a) (𝓝[s ∩ Iio b] b) + (𝓝 (variationOnFromTo f s a b - dist (f b) l)) := by + suffices H : Tendsto (fun x ↦ variationOnFromTo f s a b - variationOnFromTo f s x b) + (𝓝[s ∩ Iio b] b) (𝓝 (variationOnFromTo f s a b - dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx + rw [variationOnFromTo.sub_left hf ha hb hx.1] + apply Tendsto.const_sub + suffices H : Tendsto (fun x ↦ (eVariationOn f (s ∩ Icc x b)).toReal) (𝓝[s ∩ Iio b] b) + (𝓝 (dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx using by simp [variationOnFromTo, hx.2.le] + rw [dist_edist] + exact (ENNReal.tendsto_toReal (by simp)).comp (hf.tendsto_eVariationOn_Icc_left h'f hb) + +/-- The jump of `variationOnFromTo` on the right of a point is given by the distance between the +right limit and the value of the function. -/ +theorem tendsto_right {E : Type*} [PseudoMetricSpace E] [TopologicalSpace α] [OrderTopology α] + {f : α → E} {l : E} {a b : α} (ha : a ∈ s) (hb : b ∈ s) + (hf : LocallyBoundedVariationOn f s) (h'f : Tendsto f (𝓝[s ∩ Ioi b] b) (𝓝 l)) : + Tendsto (variationOnFromTo f s a) (𝓝[s ∩ Ioi b] b) + (𝓝 (variationOnFromTo f s a b + dist (f b) l)) := by + suffices H : Tendsto (fun x ↦ variationOnFromTo f s a b + variationOnFromTo f s b x) + (𝓝[s ∩ Ioi b] b) (𝓝 (variationOnFromTo f s a b + dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx + rw [variationOnFromTo.add hf ha hb hx.1] + apply Tendsto.const_add + suffices H : Tendsto (fun x ↦ (eVariationOn f (s ∩ Icc b x)).toReal) (𝓝[s ∩ Ioi b] b) + (𝓝 (dist (f b) l)) by + apply Tendsto.congr' _ H + filter_upwards [self_mem_nhdsWithin] with x hx using by simp [variationOnFromTo, hx.2.le] + rw [dist_edist] + exact (ENNReal.tendsto_toReal (by simp)).comp (hf.tendsto_eVariationOn_Icc_right h'f hb) + +/-- The jump of `variationOnFromTo` on the left of a point is given by the distance between the +left limit and the value of the function. -/ +theorem leftLim_eq {E : Type*} [PseudoMetricSpace E] [CompleteSpace E] + {f : α → E} {a b : α} (hf : BoundedVariationOn f univ) : + (variationOnFromTo f univ a).leftLim b = + variationOnFromTo f univ a b - dist (f b) (f.leftLim b) := by + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ + rcases eq_or_neBot (𝓝[<] b) with hb | hb + · simp [leftLim_eq_of_eq_bot _ hb] + apply leftLim_eq_of_tendsto + have := variationOnFromTo.tendsto_left (f := f) (l := f.leftLim b) (mem_univ a) (mem_univ b) + hf.locallyBoundedVariationOn + simp only [univ_inter] at this + exact this (hf.tendsto_leftLim _) + +/-- The jump of `variationOnFromTo` on the right of a point is given by the distance between the +right limit and the value of the function. -/ +theorem rightLim_eq {E : Type*} [PseudoMetricSpace E] [CompleteSpace E] + {f : α → E} {a b : α} (hf : BoundedVariationOn f univ) : + (variationOnFromTo f univ a).rightLim b = + variationOnFromTo f univ a b + dist (f b) (f.rightLim b) := by + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ + rcases eq_or_neBot (𝓝[>] b) with hb | hb + · simp [rightLim_eq_of_eq_bot _ hb] + apply rightLim_eq_of_tendsto + have := variationOnFromTo.tendsto_right (f := f) (l := f.rightLim b) (mem_univ a) (mem_univ b) + hf.locallyBoundedVariationOn + simp only [univ_inter] at this + exact this (hf.tendsto_rightLim _) + +theorem _root_.BoundedVariationOn.continuousWithinAt_variationOnFromTo_Ici + [TopologicalSpace α] [OrderTopology α] (hf : BoundedVariationOn f univ) {a x : α} + (hx : ContinuousWithinAt f (Ici x) x) : + ContinuousWithinAt (variationOnFromTo f univ a) (Ici x) x := by + have : variationOnFromTo f univ a = + fun y ↦ variationOnFromTo f univ a x + variationOnFromTo f univ x y := by + ext y + rw [variationOnFromTo.add hf.locallyBoundedVariationOn (mem_univ _) (mem_univ _) (mem_univ _)] + rw [this] + apply continuousWithinAt_const.add + suffices H : ContinuousWithinAt (fun y ↦ (eVariationOn f (univ ∩ Icc x y)).toReal) (Ici x) x from + H.congr_of_mem (fun y hy ↦ by grind [variationOnFromTo]) self_mem_Iic + simp only [ContinuousWithinAt, Icc_self] + rw [eVariationOn.subsingleton _ (by grind [Set.Subsingleton])] + apply (ENNReal.tendsto_toReal ENNReal.zero_ne_top).comp + apply Tendsto.mono_left _ (nhdsWithin_mono _ (subset_univ _)) + exact hf.tendsto_eVariationOn_Icc_zero_right _ (by simpa using hx) + +theorem _root_.BoundedVariationOn.continuousWithinAt_variationOnFromTo_rightLim_Ici + [TopologicalSpace α] [OrderTopology α] [T3Space E] [CompleteSpace E] + (hf : BoundedVariationOn f univ) {a x : α} : + ContinuousWithinAt (variationOnFromTo f.rightLim univ a) (Ici x) x := + hf.rightLim.continuousWithinAt_variationOnFromTo_Ici hf.continuousWithinAt_rightLim + +end variationOnFromTo + +/-- If a real-valued function has bounded variation on a set, then it is a difference of monotone +functions there. Moreover, one can make sure that the two monotone functions add up to the +variation of `f`. -/ +theorem LocallyBoundedVariationOn.exists_monotoneOn_sub_monotoneOn' {f : α → ℝ} {s : Set α} + (h : LocallyBoundedVariationOn f s) : + ∃ p q : α → ℝ, MonotoneOn p s ∧ MonotoneOn q s ∧ f = p - q ∧ + ∀ x ∈ s, ∀ y ∈ s, (p y - p x) + (q y - q x) = variationOnFromTo f s x y := by + rcases eq_empty_or_nonempty s with (rfl | ⟨c, cs⟩) + · refine ⟨f, 0, subsingleton_empty.monotoneOn _, subsingleton_empty.monotoneOn _, + (sub_zero f).symm, fun x hx y hy ↦ by simp at hx⟩ + refine ⟨fun x ↦ (variationOnFromTo f s c x + f x) / 2, + fun x ↦ (variationOnFromTo f s c x - f x) / 2, ?_, ?_, ?_, ?_⟩ + · intro x hx y hy hxy + dsimp + gcongr 1 + simpa using variationOnFromTo.add_self_monotoneOn h cs hx hy hxy + · intro x hx y hy hxy + dsimp + gcongr 1 + simpa using variationOnFromTo.sub_self_monotoneOn h cs hx hy hxy + · ext + simp + ring + · intro x hx y hy + rw [← variationOnFromTo.add h hx cs hy, variationOnFromTo.eq_neg_swap] + ring + +/-- If a real-valued function has bounded variation on a set, then it is a difference of monotone +functions there. -/ +theorem LocallyBoundedVariationOn.exists_monotoneOn_sub_monotoneOn {f : α → ℝ} {s : Set α} + (h : LocallyBoundedVariationOn f s) : + ∃ p q : α → ℝ, MonotoneOn p s ∧ MonotoneOn q s ∧ f = p - q := by + rcases h.exists_monotoneOn_sub_monotoneOn' with ⟨p, q, hp, hq, h'f, -⟩ + exact ⟨p, q, hp, hq, h'f⟩ From 3b5afa97c31c95c69273cc3724eb50c78399405c Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:32:54 +0000 Subject: [PATCH 0650/1300] doc(LinearAlgebra/Matrix/ToLin): fix typos (#41448) Co-authored-by: SnirBroshi <26556598+SnirBroshi@users.noreply.github.com> --- Mathlib/LinearAlgebra/Matrix/ToLin.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/ToLin.lean b/Mathlib/LinearAlgebra/Matrix/ToLin.lean index cf711039ba3e98..bbd8ec8bd71fcd 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLin.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLin.lean @@ -125,7 +125,7 @@ example {A} [Semiring A] [Fintype n] := (mulVecBilin A Aᵐᵒᵖ : Matrix m n A /-- `vecMulVec` as a bilinear map. -When `A` is noncommutative, `R` and `S` can be instantiated as `vecMulVecLinear A Aᵐᵒᵖ`. -/ +When `A` is noncommutative, `R` and `S` can be instantiated as `vecMulVecBilin A Aᵐᵒᵖ`. -/ @[simps] def vecMulVecBilin : (m → A) →ₗ[R] (n → A) →ₗ[S] Matrix m n A where toFun x := @@ -137,9 +137,9 @@ def vecMulVecBilin : (m → A) →ₗ[R] (n → A) →ₗ[S] Matrix m n A where example {A} [Semiring A] := (vecMulVecBilin A Aᵐᵒᵖ : (m → A) →ₗ[_] (n → A) →ₗ[_] _) -/-- `vecMulVec` as a bilinear map. +/-- `dotProduct` as a bilinear map. -When `A` is noncommutative, `R` and `S` can be instantiated as `vecMulVecLinear A Aᵐᵒᵖ`. -/ +When `A` is noncommutative, `R` and `S` can be instantiated as `dotProductBilin A Aᵐᵒᵖ`. -/ @[simps] def dotProductBilin [Fintype m] : (m → A) →ₗ[R] (m → A) →ₗ[S] A where toFun x := From d1f304c611eb2e7507ea2393df3d155563609d8e Mon Sep 17 00:00:00 2001 From: Elias Judin Date: Tue, 7 Jul 2026 21:04:17 +0000 Subject: [PATCH 0651/1300] feat(Algebra): add eval API parity lemmas (#39865) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `MvPolynomial.hom_eval₂`, parallel to `Polynomial.hom_eval₂`. Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Algebra/MvPolynomial/Eval.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Algebra/MvPolynomial/Eval.lean b/Mathlib/Algebra/MvPolynomial/Eval.lean index b4cbd587a08874..46547815cf52ca 100644 --- a/Mathlib/Algebra/MvPolynomial/Eval.lean +++ b/Mathlib/Algebra/MvPolynomial/Eval.lean @@ -195,6 +195,11 @@ theorem map_eval₂Hom [CommSemiring S₂] (f : R →+* S₁) (g : σ → S₁) rw [← comp_eval₂Hom] rfl +theorem hom_eval₂ [CommSemiring S₂] (p : MvPolynomial σ R) (f : R →+* S₁) + (φ : S₁ →+* S₂) (g : σ → S₁) : + φ (p.eval₂ f g) = p.eval₂ (φ.comp f) (fun i => φ (g i)) := + map_eval₂Hom f g φ p + theorem eval₂Hom_monomial (f : R →+* S₁) (g : σ → S₁) (d : σ →₀ ℕ) (r : R) : eval₂Hom f g (monomial d r) = f r * d.prod fun i k => g i ^ k := by simp only [coe_eval₂Hom, eval₂_monomial] From fc2bf99a233c8e9f673170f1966f001be8ec30f4 Mon Sep 17 00:00:00 2001 From: Owen Kent <20529132+owenpkent@users.noreply.github.com> Date: Tue, 7 Jul 2026 21:04:20 +0000 Subject: [PATCH 0652/1300] feat(NumberTheory/Harmonic/ZetaAsymp): conjugation symmetry of riemannZeta (#41133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds the reflection (conjugation) symmetry of the Riemann zeta function to `Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean`: - `riemannZeta_conj` :`riemannZeta (conj s) = conj (riemannZeta s)`; - `riemannZeta_conj_eq_zero_iff` : `riemannZeta (conj s) = 0 ↔ riemannZeta s = 0` (the zeros are symmetric under complex conjugation). This is the natural companion to the functional equation already in Mathlib (`riemannZeta_one_sub`). Together the two symmetries `s ↦ 1 - s` and `s ↦ conj s` generate the quadruple symmetry `{ρ, 1 - ρ, conj ρ, 1 - conj ρ}` of the nontrivial zeros, and the reflection symmetry alone is a basic, frequently-used fact (it is why the zeros come in conjugate pairs). Mathematical content: `ζ` has real Dirichlet coefficients, so on `1 < re s` the identity `conj (ζ (conj s)) = ζ s` holds termwise from `zeta_eq_tsum_one_div_nat_cpow` and `Complex.conj_cpow`. The identity principle for analytic functions then propagates it across the connected domain `ℂ ∖ {1}` (`AnalyticOnNhd.eqOn_of_preconnected_of_eventuallyEq`); analyticity of `conj ∘ ζ ∘ conj` is the anti-holomorphic composition `HasDerivAt.conj_conj`. The PR adds two imports (`Mathlib.Analysis.Calculus.Deriv.Star`, `Mathlib.Analysis.Normed.Module.Connected`), both confirmed required. --- Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean | 39 +++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean b/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean index 3220e94f093a8a..6846dc699ecd29 100644 --- a/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean +++ b/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean @@ -9,6 +9,9 @@ public import Mathlib.NumberTheory.LSeries.Dirichlet public import Mathlib.NumberTheory.Harmonic.GammaDeriv public import Mathlib.Analysis.Asymptotics.Lemmas +import Mathlib.Analysis.Calculus.Deriv.Star +import Mathlib.Analysis.Normed.Module.Connected + /-! # Asymptotics of `ζ s` as `s → 1` or `s → 0` @@ -25,6 +28,8 @@ The goal of this file is to evaluate the limit of `ζ s - 1 / (s - 1)` as `s → for certain entire functions `riemannZeta₀` and `riemannZeta₁`. * Asymptotics for `deriv riemannZeta s`, `log (riemannZeta s)`, `(deriv riemannZeta s) / (riemannZeta s)` and `(riemannZeta s)⁻¹` as `s → 1`. +* `riemannZeta_conj`: the conjugation symmetry `ζ (conj s) = conj (ζ s)` (valid for all `s`, + since the junk value `ζ 1` is real). ### Outline of arguments @@ -406,7 +411,7 @@ end val_at_one end ZetaAsymptotics open scoped Real -open Complex +open Complex ComplexConjugate /-- Formula for `ζ 1`. Note that mathematically `ζ 1` is undefined, but our construction ascribes this particular value to it. -/ @@ -444,6 +449,38 @@ lemma riemannZeta_one_ne_zero : riemannZeta 1 ≠ 0 := by exact (lt_trans Real.exp_one_lt_d9 (by norm_num)).trans_le <| mul_le_mul_of_nonneg_left Real.two_le_pi (by simp) +/-- **Conjugation symmetry of the Riemann zeta function**: `ζ (conj s) = conj (ζ s)`. + +Since `ζ` has real Dirichlet coefficients, `conj (ζ (conj z)) = ζ z` holds termwise for +`1 < re z`, and the identity principle propagates this to all `s ≠ 1`; the junk value `ζ 1` is +real, so the identity also holds at `s = 1`. -/ +@[simp] +theorem riemannZeta_conj (s : ℂ) : riemannZeta (conj s) = conj (riemannZeta s) := by + rcases eq_or_ne s 1 with rfl | hs + · have h : riemannZeta 1 = ((γ - Real.log (4 * π)) / 2 : ℝ) := by + rw [riemannZeta_one, ofReal_div, ofReal_sub, ofReal_log (by positivity : (0 : ℝ) ≤ 4 * π)] + norm_cast + rw [map_one, h, conj_ofReal] + · -- `conj ∘ ζ ∘ conj` is analytic on `{1}ᶜ` and agrees with `ζ` termwise on `1 < re z`, so + -- the identity principle propagates the equality to the connected set `{1}ᶜ`. + have hg_an : AnalyticOnNhd ℂ (fun z ↦ conj (riemannZeta (conj z))) {1}ᶜ := + DifferentiableOn.analyticOnNhd + (fun z hz ↦ (differentiableAt_conj_conj_iff.mpr <| differentiableAt_riemannZeta <| + (map_ne_one_iff _ (starRingEnd ℂ).injective).mpr hz).differentiableWithinAt) + isOpen_compl_singleton + have hgz (z : ℂ) (hz : 1 < z.re) : conj (riemannZeta (conj z)) = riemannZeta z := by + rw [zeta_eq_tsum_one_div_nat_cpow (by rwa [conj_re]), conj_tsum, + zeta_eq_tsum_one_div_nat_cpow hz] + exact tsum_congr fun n ↦ by + rw [map_div₀, map_one, ← conj_cpow _ _ (by rw [natCast_arg]; positivity), conj_natCast] + have heq : EqOn (fun z ↦ conj (riemannZeta (conj z))) riemannZeta {1}ᶜ := + hg_an.eqOn_of_preconnected_of_eventuallyEq analyticOn_riemannZeta + (isConnected_compl_singleton_of_one_lt_rank (by simp) 1).isPreconnected + (by norm_num : (2 : ℂ) ∈ _) + (eventuallyEq_of_mem + ((isOpen_lt continuous_const continuous_re).mem_nhds (by norm_num)) hgz) + simpa using congrArg (starRingEnd ℂ) (heq hs) + lemma riemannZeta_eventually_ne_zero_nhds_one : ∀ᶠ s in 𝓝 1, riemannZeta s ≠ 0 := by filter_upwards [eventually_nhdsWithin_iff.1 <| riemannZeta_residue_one.eventually_ne one_ne_zero] grind [riemannZeta_one_ne_zero] From 46946047569cabb61c7e87bba28cf89c3bb3077f Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 7 Jul 2026 22:28:35 +0000 Subject: [PATCH 0653/1300] =?UTF-8?q?refactor(Analysis/Meromorphic):=20gen?= =?UTF-8?q?eralize=20=F0=9D=95=9C=20=E2=86=92=20=F0=9D=95=9C=20to=20?= =?UTF-8?q?=F0=9D=95=9C=20=E2=86=92=20=F0=9D=95=9C'=20for=20order=20lemma?= =?UTF-8?q?=20when=20possible=20(#39904)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These lemma previously requires domain and codomain to be the same. This doesn't have to be the case. To support the generalization, I also generalized `Meromorphic{At/On}.smul` and `meromprhicOrderAt_smul` to allow a different scalar from the domain field. This is similar to `AnalyticAt.smul`. --- Mathlib/Analysis/Meromorphic/Basic.lean | 29 ++++++++-------- Mathlib/Analysis/Meromorphic/Order.lean | 46 +++++++++++++------------ 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index af4ae3fc44673f..8986659627ce08 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -29,7 +29,7 @@ open scoped Topology variable {𝕜 𝕜' : Type*} [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {R : Type*} [NormedRing R] [Module R E] [IsBoundedSMul R E] [SMulCommClass 𝕜 R E] +variable {R : Type*} [NormedRing R] [Module R E] [IsBoundedSMul R E] /-- Meromorphy of `f` at `x` (more precisely, on a punctured neighbourhood of `x`; the value at `x` itself is irrelevant). -/ @@ -86,17 +86,17 @@ lemma add {f g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : (((analyticAt_id.sub analyticAt_const).pow _).smul hg) @[to_fun (attr := fun_prop)] -lemma smul {f : 𝕜 → 𝕜} {g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : +lemma smul [NormedAlgebra 𝕜 R] [IsScalarTower 𝕜 R E] + {f : 𝕜 → R} {g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : MeromorphicAt (f • g) x := by rcases hf with ⟨m, hf⟩ rcases hg with ⟨n, hg⟩ refine ⟨m + n, ?_⟩ convert hf.smul hg with z - simp - module + rw [Pi.smul_apply', Pi.smul_apply', smul_smul_smul_comm, smul_eq_mul, pow_add] @[to_fun (attr := fun_prop)] -lemma const_smul {x : 𝕜} {f : 𝕜 → E} (hf : MeromorphicAt f x) (c : R) : +lemma const_smul [SMulCommClass 𝕜 R E] {x : 𝕜} {f : 𝕜 → E} (hf : MeromorphicAt f x) (c : R) : MeromorphicAt (c • f) x := by rcases hf with ⟨m, hf⟩ exact ⟨m, by simpa [smul_comm _ c _] using hf.fun_const_smul⟩ @@ -104,12 +104,7 @@ lemma const_smul {x : 𝕜} {f : 𝕜 → E} (hf : MeromorphicAt f x) (c : R) : @[to_fun (attr := fun_prop)] lemma mul {f g : 𝕜 → 𝕜'} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : MeromorphicAt (f * g) x := by - rcases hf with ⟨m, hf⟩ - rcases hg with ⟨n, hg⟩ - refine ⟨m + n, ?_⟩ - convert hf.mul hg with z - simp - module + simpa using hf.smul hg /-- Finite products of meromorphic functions are meromorphic. -/ @[fun_prop] -- TODO: to_fun generates an unreadable statement, see #32866 @@ -553,12 +548,15 @@ include hf in @[simp] lemma neg_iff : MeromorphicOn (-f) U ↔ MeromorphicOn f U := ⟨fun h ↦ by simpa only [neg_neg] using h.neg, neg⟩ -@[to_fun] lemma smul {s : 𝕜 → 𝕜} (hs : MeromorphicOn s U) {f : 𝕜 → E} (hf : MeromorphicOn f U) : +@[to_fun] +lemma smul [NormedAlgebra 𝕜 R] [IsScalarTower 𝕜 R E] {s : 𝕜 → R} (hs : MeromorphicOn s U) + {f : 𝕜 → E} (hf : MeromorphicOn f U) : MeromorphicOn (s • f) U := fun x hx ↦ (hs x hx).smul (hf x hx) include hf in -@[to_fun] lemma const_smul (c : R) : MeromorphicOn (c • f) U := fun x hx ↦ (hf x hx).const_smul c +@[to_fun] lemma const_smul [SMulCommClass 𝕜 R E] (c : R) : MeromorphicOn (c • f) U := + fun x hx ↦ (hf x hx).const_smul c include hs ht in @[to_fun] lemma mul : MeromorphicOn (s * t) U := fun x hx ↦ (hs x hx).mul (ht x hx) @@ -702,11 +700,12 @@ lemma sub (hf : Meromorphic f) (hg : Meromorphic g) : Meromorphic (f - g) := fun x ↦ (hf x).sub (hg x) @[to_fun (attr := fun_prop)] -lemma smul {f : 𝕜 → 𝕜} (hf : Meromorphic f) (hg : Meromorphic g) : +lemma smul [NormedAlgebra 𝕜 R] [IsScalarTower 𝕜 R E] {f : 𝕜 → R} (hf : Meromorphic f) + (hg : Meromorphic g) : Meromorphic (f • g) := fun x ↦ (hf x).smul (hg x) @[to_fun (attr := fun_prop)] -lemma const_smul (hf : Meromorphic f) (c : R) : +lemma const_smul [SMulCommClass 𝕜 R E] (hf : Meromorphic f) (c : R) : Meromorphic (c • f) := fun x ↦ (hf x).const_smul c @[to_fun (attr := fun_prop)] diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index 08900fe127cc49..49bca14ba54e70 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -29,6 +29,9 @@ open scoped Topology variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {R : Type*} [NormedRing R] [NoZeroDivisors R] + [Module R E] [IsBoundedSMul R E] [Module.IsTorsionFree R E] + {𝕜' : Type*} [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] {f f₁ f₂ : 𝕜 → E} {x : 𝕜} /-! @@ -355,24 +358,24 @@ lemma meromorphicOrderAt_id : meromorphicOrderAt (𝕜 := 𝕜) id 0 = 1 := by /-- The order of a constant function is `⊤` if the constant is zero and `0` otherwise. -/ -theorem meromorphicOrderAt_const_intCast (z₀ : 𝕜) (n : ℤ) [Decidable ((n : 𝕜) = 0)] : - meromorphicOrderAt (n : 𝕜 → 𝕜) z₀ = if (n : 𝕜) = 0 then ⊤ else (0 : WithTop ℤ) := - meromorphicOrderAt_const z₀ (n : 𝕜) +theorem meromorphicOrderAt_const_intCast (z₀ : 𝕜) (n : ℤ) [Decidable ((n : 𝕜') = 0)] : + meromorphicOrderAt (n : 𝕜 → 𝕜') z₀ = if (n : 𝕜') = 0 then ⊤ else (0 : WithTop ℤ) := + meromorphicOrderAt_const z₀ (n : 𝕜') /-- The order of a constant function is `⊤` if the constant is zero and `0` otherwise. -/ -theorem meromorphicOrderAt_const_natCast (z₀ : 𝕜) (n : ℕ) [Decidable ((n : 𝕜) = 0)] : - meromorphicOrderAt (n : 𝕜 → 𝕜) z₀ = if (n : 𝕜) = 0 then ⊤ else (0 : WithTop ℤ) := - meromorphicOrderAt_const z₀ (n : 𝕜) +theorem meromorphicOrderAt_const_natCast (z₀ : 𝕜) (n : ℕ) [Decidable ((n : 𝕜') = 0)] : + meromorphicOrderAt (n : 𝕜 → 𝕜') z₀ = if (n : 𝕜') = 0 then ⊤ else (0 : WithTop ℤ) := + meromorphicOrderAt_const z₀ (n : 𝕜') /-- The order of a constant function is `⊤` if the constant is zero and `0` otherwise. -/ -@[simp] theorem meromorphicOrderAt_const_ofNat (z₀ : 𝕜) (n : ℕ) [Decidable ((n : 𝕜) = 0)] : - meromorphicOrderAt (ofNat(n) : 𝕜 → 𝕜) z₀ = if (n : 𝕜) = 0 then ⊤ else (0 : WithTop ℤ) := by - convert! meromorphicOrderAt_const z₀ (n : 𝕜) - simp [Semiring.toGrindSemiring_ofNat 𝕜 n] +@[simp] theorem meromorphicOrderAt_const_ofNat (z₀ : 𝕜) (n : ℕ) [Decidable ((n : 𝕜') = 0)] : + meromorphicOrderAt (ofNat(n) : 𝕜 → 𝕜') z₀ = if (n : 𝕜') = 0 then ⊤ else (0 : WithTop ℤ) := by + convert! meromorphicOrderAt_const z₀ (n : 𝕜') + simp [Semiring.toGrindSemiring_ofNat 𝕜' n] /-- The order of `(· - x) ^ n` at `x` is `n`. -/ @[simp, to_fun] theorem meromorphicOrderAt_zpow_id_sub_const {n : ℤ} : @@ -417,8 +420,8 @@ theorem meromorphicOrderAt_fun_neg {f : 𝕜 → E} : meromorphicOrderAt f x = meromorphicOrderAt (fun z ↦ -f z) x := meromorphicOrderAt_neg /-- The order is additive when multiplying scalar-valued and vector-valued meromorphic functions. -/ -@[to_fun] theorem meromorphicOrderAt_smul {f : 𝕜 → 𝕜} {g : 𝕜 → E} - (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : +@[to_fun] theorem meromorphicOrderAt_smul [NormedAlgebra 𝕜 R] [IsScalarTower 𝕜 R E] + {f : 𝕜 → R} {g : 𝕜 → E} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : meromorphicOrderAt (f • g) x = meromorphicOrderAt f x + meromorphicOrderAt g x := by -- Trivial cases: one of the functions vanishes around z₀ cases h₂f : meromorphicOrderAt f x with @@ -439,7 +442,7 @@ theorem meromorphicOrderAt_fun_neg {f : 𝕜 → E} : simp [hfa, hga, smul_comm (F a), zpow_add₀ (sub_ne_zero.mpr ha), mul_smul] /-- The order is additive when multiplying meromorphic functions. -/ -@[to_fun] theorem meromorphicOrderAt_mul {f g : 𝕜 → 𝕜} (hf : MeromorphicAt f x) +@[to_fun] theorem meromorphicOrderAt_mul {f g : 𝕜 → 𝕜'} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : meromorphicOrderAt (f * g) x = meromorphicOrderAt f x + meromorphicOrderAt g x := meromorphicOrderAt_smul hf hg @@ -447,7 +450,7 @@ theorem meromorphicOrderAt_fun_neg {f : 𝕜 → E} : /-- The order is additive in products of meromorphic functions. -/ -theorem meromorphicOrderAt_prod {x : 𝕜} {ι : Type*} {s : Finset ι} {f : ι → 𝕜 → 𝕜} +theorem meromorphicOrderAt_prod {x : 𝕜} {ι : Type*} {s : Finset ι} {f : ι → 𝕜 → 𝕜'} (hf : ∀ i ∈ s, MeromorphicAt (f i) x) : meromorphicOrderAt (∏ i ∈ s, f i) x = ∑ i ∈ s, meromorphicOrderAt (f i) x := by classical @@ -466,7 +469,7 @@ theorem meromorphicOrderAt_prod {x : 𝕜} {ι : Type*} {s : Finset ι} {f : ι /-- The order is additive in products of meromorphic functions. -/ -theorem meromorphicOrderAt_fun_prod {x : 𝕜} {ι : Type*} {s : Finset ι} {f : ι → 𝕜 → 𝕜} +theorem meromorphicOrderAt_fun_prod {x : 𝕜} {ι : Type*} {s : Finset ι} {f : ι → 𝕜 → 𝕜'} (hf : ∀ i ∈ s, MeromorphicAt (f i) x) : meromorphicOrderAt (fun a ↦ ∏ i ∈ s, f i a) x = ∑ i ∈ s, meromorphicOrderAt (f i) x := by convert! meromorphicOrderAt_prod hf @@ -484,7 +487,7 @@ lemma meromorphicOrderAt_finprod_ne_top {x : 𝕜} {ι : Type*} {F : ι → 𝕜 simp [finprod_of_not_hasFiniteMulSupport hF] /-- The order multiplies by `n` when taking a meromorphic function to its `n`th power. -/ -@[to_fun] theorem meromorphicOrderAt_pow {f : 𝕜 → 𝕜} {x : 𝕜} (hf : MeromorphicAt f x) {n : ℕ} : +@[to_fun] theorem meromorphicOrderAt_pow {f : 𝕜 → 𝕜'} {x : 𝕜} (hf : MeromorphicAt f x) {n : ℕ} : meromorphicOrderAt (f ^ n) x = n * meromorphicOrderAt f x := by induction n case zero => @@ -502,7 +505,7 @@ lemma meromorphicOrderAt_finprod_ne_top {x : 𝕜} {ι : Type*} {F : ι → 𝕜 ring /-- The order multiplies by `n` when taking a meromorphic function to its `n`th power. -/ -@[to_fun] theorem meromorphicOrderAt_zpow {f : 𝕜 → 𝕜} {x : 𝕜} (hf : MeromorphicAt f x) {n : ℤ} : +@[to_fun] theorem meromorphicOrderAt_zpow {f : 𝕜 → 𝕜'} {x : 𝕜} (hf : MeromorphicAt f x) {n : ℤ} : meromorphicOrderAt (f ^ n) x = n * meromorphicOrderAt f x := by -- Trivial case: n = 0 by_cases hn : n = 0 @@ -526,12 +529,12 @@ lemma meromorphicOrderAt_finprod_ne_top {x : 𝕜} {ι : Type*} {F : ι → 𝕜 · simp_all [zpow_eq_zero_iff hn] · filter_upwards [h₃g] intro y hy - rw [Pi.pow_apply, hy, smul_eq_mul, mul_zpow] + rw [Pi.pow_apply, hy, Algebra.smul_def, Algebra.smul_def, mul_zpow, ← map_zpow₀] congr 1 rw [mul_comm, zpow_mul] /-- The order of the inverse is the negative of the order. -/ -@[to_fun] theorem meromorphicOrderAt_inv {f : 𝕜 → 𝕜} : +@[to_fun] theorem meromorphicOrderAt_inv {f : 𝕜 → 𝕜'} : meromorphicOrderAt (f⁻¹) x = -meromorphicOrderAt f x := by by_cases hf : MeromorphicAt f x; swap · have : ¬ MeromorphicAt (f⁻¹) x := by @@ -550,13 +553,12 @@ lemma meromorphicOrderAt_finprod_ne_top {x : 𝕜} {ι : Type*} {F : ι → 𝕜 rw [eventually_nhdsWithin_iff] at * filter_upwards [h₃g] intro _ h₁a h₂a - simp only [Pi.inv_apply, h₁a h₂a, smul_eq_mul, mul_inv_rev, zpow_neg] - ring + simp [h₁a h₂a, Algebra.smul_def, mul_comm] /-- The order of a quotient is the difference of the orders. -/ -@[to_fun] theorem meromorphicOrderAt_div {f g : 𝕜 → 𝕜} (hf : MeromorphicAt f x) +@[to_fun] theorem meromorphicOrderAt_div {f g : 𝕜 → 𝕜'} (hf : MeromorphicAt f x) (hg : MeromorphicAt g x) : meromorphicOrderAt (f / g) x = meromorphicOrderAt f x - meromorphicOrderAt g x := by rw [div_eq_mul_inv, meromorphicOrderAt_mul hf hg.inv, meromorphicOrderAt_inv, sub_eq_add_neg] From 267e163da5b36e4da56822bab36bfcc09ad1a86f Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 7 Jul 2026 23:14:14 +0000 Subject: [PATCH 0654/1300] feat(Analysis): lemma for fderiv of FormalMultilinearSeries.sum (#41018) These are useful for rewriting in expressions that uses `FormalMultilinearSeries.sum` --- Mathlib/Analysis/Calculus/FDeriv/Analytic.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean index fef5366e1c2606..d20869f14aab26 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean @@ -221,6 +221,19 @@ protected theorem HasFPowerSeriesOnBall.fderiv [CompleteSpace F] rw [← h.fderiv_eq, add_sub_cancel] simpa only [edist_eq_enorm_sub, Metric.mem_eball] using! hz +protected theorem FormalMultilinearSeries.fderiv_sum [CompleteSpace F] (h : ‖x‖ₑ < p.radius) : + fderiv 𝕜 p.sum x = p.derivSeries.sum x := by + have h := p.hasFPowerSeriesOnBall (zero_le.trans_lt h) |>.fderiv.hasSum + (show x ∈ Metric.eball 0 p.radius by simpa using h) |>.tsum_eq + rw [zero_add] at h + rw [← h, FormalMultilinearSeries.sum] + +protected theorem FormalMultilinearSeries.hasFDerivAt_sum [CompleteSpace F] (h : ‖x‖ₑ < p.radius) : + HasFDerivAt p.sum (p.derivSeries.sum x) x := by + rw [← FormalMultilinearSeries.fderiv_sum h] + exact p.hasFPowerSeriesOnBall (zero_le.trans_lt h) + |>.analyticAt_of_mem (by simpa using h) |>.differentiableAt.hasFDerivAt + /-- If a function has a power series within a set on a ball, then so does its derivative. -/ protected theorem HasFPowerSeriesWithinOnBall.fderivWithin [CompleteSpace F] (h : HasFPowerSeriesWithinOnBall f p s x r) (hu : UniqueDiffOn 𝕜 (insert x s)) : From 1082fe00c1d9aef84df818af79102460ba04ff85 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Tue, 7 Jul 2026 23:35:25 +0000 Subject: [PATCH 0655/1300] feat(Analysis): strengthen bounds for sin (#41094) This PR strengthens various bounds for `Real.sin` in mathlib. The statement `Complex.sin_bound` now has a quintic right hand side with a smaller constant. This bound is always better in the range where the theorem applies. The same is true for `Real.sin_bound`. Since these changes broke the proof of `sin_pos_of_pos_of_le_one`, I fixed and golfed this proof. Next `sin_gt_sub_cube` is given a tight constant, and its range of validity is extended, and the proof is the same length. A version for weak inequality, and a version with absolute value is also added. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Analysis/Complex/Trigonometric.lean | 35 +++++----------- Mathlib/Analysis/Real/Pi/Bounds.lean | 10 ++--- .../Trigonometric/Bounds.lean | 42 ++++++++++++------- 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/Mathlib/Analysis/Complex/Trigonometric.lean b/Mathlib/Analysis/Complex/Trigonometric.lean index 554e4153002295..3d37f9aa071a00 100644 --- a/Mathlib/Analysis/Complex/Trigonometric.lean +++ b/Mathlib/Analysis/Complex/Trigonometric.lean @@ -558,21 +558,21 @@ theorem cos_bound {x : ℂ} (hx : ‖x‖ ≤ 1) : ‖cos x - (1 - x ^ 2 / 2)‖ grw [exp_bound (by simpa) (by simp), exp_bound (by simpa) (by simp)] _ ≤ ‖x‖ ^ 4 * (5 / 96) := by norm_num -theorem sin_bound {x : ℂ} (hx : ‖x‖ ≤ 1) : ‖sin x - (x - x ^ 3 / 6)‖ ≤ ‖x‖ ^ 4 * (5 / 96) := +theorem sin_bound {x : ℂ} (hx : ‖x‖ ≤ 1) : ‖sin x - (x - x ^ 3 / 6)‖ ≤ ‖x‖ ^ 5 / 100 := calc ‖sin x - (x - x ^ 3 / 6)‖ = - ‖(exp (-x * I) - ∑ m ∈ range 4, (-x * I) ^ m / m.factorial) * I / 2 - - (exp (x * I) - ∑ m ∈ range 4, (x * I) ^ m / m.factorial) * I / 2‖ := by + ‖(exp (-x * I) - ∑ m ∈ range 5, (-x * I) ^ m / m.factorial) * I / 2 - + (exp (x * I) - ∑ m ∈ range 5, (x * I) ^ m / m.factorial) * I / 2‖ := by simp [sin, field, Finset.sum_range_succ, Nat.factorial] grind [I_sq, two_ne_zero] - _ ≤ ‖exp (-x * I) - ∑ m ∈ range 4, (-x * I) ^ m / m.factorial‖ / 2 + - ‖exp (x * I) - ∑ m ∈ range 4, (x * I) ^ m / m.factorial‖ / 2 := by + _ ≤ ‖exp (-x * I) - ∑ m ∈ range 5, (-x * I) ^ m / m.factorial‖ / 2 + + ‖exp (x * I) - ∑ m ∈ range 5, (x * I) ^ m / m.factorial‖ / 2 := by grw [norm_sub_le] simp - _ ≤ ‖-x * I‖ ^ 4 * (Nat.succ 4 * (Nat.factorial 4 * (4 : ℕ) : ℝ)⁻¹) / 2 + - ‖x * I‖ ^ 4 * (Nat.succ 4 * (Nat.factorial 4 * (4 : ℕ) : ℝ)⁻¹) / 2 := by + _ ≤ ‖-x * I‖ ^ 5 * (Nat.succ 5 * (Nat.factorial 5 * (5 : ℕ) : ℝ)⁻¹) / 2 + + ‖x * I‖ ^ 5 * (Nat.succ 5 * (Nat.factorial 5 * (5 : ℕ) : ℝ)⁻¹) / 2 := by grw [exp_bound (by simpa) (by simp), exp_bound (by simpa) (by simp)] - _ ≤ ‖x‖ ^ 4 * (5 / 96) := by norm_num + _ = ‖x‖ ^ 5 / 100 := by norm_num [mul_one_div] end Complex @@ -873,7 +873,7 @@ open Complex theorem cos_bound {x : ℝ} (hx : |x| ≤ 1) : |cos x - (1 - x ^ 2 / 2)| ≤ |x| ^ 4 * (5 / 96) := by simpa [← ofReal_cos, ← norm_eq_abs, ← norm_real] using Complex.cos_bound (x := x) (by simpa) -theorem sin_bound {x : ℝ} (hx : |x| ≤ 1) : |sin x - (x - x ^ 3 / 6)| ≤ |x| ^ 4 * (5 / 96) := by +theorem sin_bound {x : ℝ} (hx : |x| ≤ 1) : |sin x - (x - x ^ 3 / 6)| ≤ |x| ^ 5 / 100 := by simpa [← ofReal_sin, ← norm_eq_abs, ← norm_real] using Complex.sin_bound (x := x) (by simpa) theorem cos_pos_of_le_one {x : ℝ} (hx : |x| ≤ 1) : 0 < cos x := @@ -889,21 +889,8 @@ theorem cos_pos_of_le_one {x : ℝ} (hx : |x| ≤ 1) : 0 < cos x := _ < 1 := by norm_num) _ ≤ cos x := sub_le_comm.1 (abs_sub_le_iff.1 (cos_bound hx)).2 -theorem sin_pos_of_pos_of_le_one {x : ℝ} (hx0 : 0 < x) (hx : x ≤ 1) : 0 < sin x := - calc 0 < x - x ^ 3 / 6 - |x| ^ 4 * (5 / 96) := - sub_pos.2 <| lt_sub_iff_add_lt.2 - (calc - |x| ^ 4 * (5 / 96) + x ^ 3 / 6 ≤ x * (5 / 96) + x / 6 := by - gcongr - · calc - |x| ^ 4 ≤ |x| ^ 1 := - pow_le_pow_of_le_one (abs_nonneg _) - (by rwa [abs_of_nonneg (le_of_lt hx0)]) (by decide) - _ = x := by simp [abs_of_nonneg (le_of_lt hx0)] - · calc - x ^ 3 ≤ x ^ 1 := pow_le_pow_of_le_one (le_of_lt hx0) hx (by decide) - _ = x := pow_one _ - _ < x := by linarith) +theorem sin_pos_of_pos_of_le_one {x : ℝ} (hx0 : 0 < x) (hx : x ≤ 1) : 0 < sin x := by + calc 0 < x - x ^ 3 / 6 - |x| ^ 5 / 100 := by grind [pow_le_of_le_one] _ ≤ sin x := sub_le_comm.1 (abs_sub_le_iff.1 (sin_bound (by rwa [abs_of_nonneg (le_of_lt hx0)]))).2 diff --git a/Mathlib/Analysis/Real/Pi/Bounds.lean b/Mathlib/Analysis/Real/Pi/Bounds.lean index e5c12920db666f..86147be4daf2ed 100644 --- a/Mathlib/Analysis/Real/Pi/Bounds.lean +++ b/Mathlib/Analysis/Real/Pi/Bounds.lean @@ -40,14 +40,10 @@ theorem pi_lt_sqrtTwoAddSeries (n : ℕ) : have : π < (√(2 - sqrtTwoAddSeries 0 n) / 2 + 1 / (2 ^ n) ^ 3 / 4) * (2 : ℝ) ^ (n + 2) := by rw [← div_lt_iff₀ (by simp), ← sin_pi_over_two_pow_succ, ← sub_lt_iff_lt_add'] calc - π / 2 ^ (n + 2) - sin (π / 2 ^ (n + 2)) < (π / 2 ^ (n + 2)) ^ 3 / 4 := - sub_lt_comm.1 <| sin_gt_sub_cube (by positivity) <| div_le_one_of_le₀ ?_ (by positivity) - _ ≤ (4 / 2 ^ (n + 2)) ^ 3 / 4 := by gcongr; exact pi_le_four + π / 2 ^ (n + 2) - sin (π / 2 ^ (n + 2)) < (π / 2 ^ (n + 2)) ^ 3 / 6 := + sub_lt_comm.1 <| sin_gt_sub_cube (by positivity) + _ ≤ (4 / 2 ^ (n + 2)) ^ 3 / 4 := by gcongr; exacts [pi_le_four, by norm_num] _ = 1 / (2 ^ n) ^ 3 / 4 := by simp [add_comm n, pow_add, div_mul_eq_div_div]; norm_num - calc - π ≤ 4 := pi_le_four - _ = 2 ^ (0 + 2) := by norm_num - _ ≤ 2 ^ (n + 2) := by gcongr <;> norm_num refine lt_of_lt_of_le this (le_of_eq ?_); rw [add_mul]; congr 1 · ring simp only [show (4 : ℝ) = 2 ^ 2 by norm_num, ← pow_mul, div_div, ← pow_add] diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean index 4330534fa420d7..561dc570aa772d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean @@ -20,7 +20,7 @@ the ranges of these functions, and their monotonicity in suitable intervals. Here we prove the following: * `sin_lt`: for `x > 0` we have `sin x < x`. -* `sin_gt_sub_cube`: For `0 < x ≤ 1` we have `x - x ^ 3 / 4 < sin x`. +* `sin_gt_sub_cube`: For `0 < x` we have `x - x ^ 3 / 6 < sin x`. * `lt_tan`: for `0 < x < π/2` we have `x < tan x`. * `cos_le_one_div_sqrt_sq_add_one` and `cos_lt_one_div_sqrt_sq_add_one`: for `-3 * π / 2 ≤ x ≤ 3 * π / 2`, we have `cos x ≤ 1 / sqrt (x ^ 2 + 1)`, with strict inequality if @@ -143,21 +143,33 @@ lemma cos_le_one_sub_mul_cos_sq (hx : |x| ≤ π) : cos x ≤ 1 - 2 / π ^ 2 * x ring_nf at this ⊢ linarith -/-- For 0 < x ≤ 1 we have x - x ^ 3 / 4 < sin x. +/-- For 0 < x we have x - x ^ 3 / 6 < sin x. -This is also true for x > 1, but it's nontrivial for x just above 1. This inequality is not -tight; the tighter inequality is sin x > x - x ^ 3 / 6 for all x > 0, but this inequality has -a simpler proof. -/ -theorem sin_gt_sub_cube {x : ℝ} (h : 0 < x) (h' : x ≤ 1) : x - x ^ 3 / 4 < sin x := by - have hx : |x| = x := abs_of_nonneg h.le - have := neg_le_of_abs_le (sin_bound <| show |x| ≤ 1 by rwa [hx]) - rw [le_sub_iff_add_le, hx] at this - refine lt_of_lt_of_le ?_ this - have : x ^ 3 / ↑4 - x ^ 3 / ↑6 = x ^ 3 * 12⁻¹ := by norm_num [div_eq_mul_inv, ← mul_sub] - rw [add_comm, sub_add, sub_neg_eq_add, sub_lt_sub_iff_left, ← lt_sub_iff_add_lt', this] - refine mul_lt_mul' ?_ (by norm_num) (by norm_num) (pow_pos h 3) - apply pow_le_pow_of_le_one h.le h' - simp +This inequality is tight, in that the constant 6 is best possible. -/ +theorem sin_gt_sub_cube {x : ℝ} (hx : 0 < x) : x - x ^ 3 / 6 < Real.sin x := by + let f (t : ℝ) : ℝ := Real.sin t - (t - t ^ 3 / 6) + have hderiv (t : ℝ) : deriv f t = cos t - 1 + t ^ 2 / 2 := by + simp (disch := fun_prop) [f] + ring + have hmono : StrictMonoOn f (Set.Ici 0) := by + apply strictMonoOn_of_deriv_pos (convex_Ici 0) (by fun_prop) + grind [one_sub_sq_div_two_lt_cos, interior_Ici] + have h0 : f 0 < f x := hmono (by simp) hx.le hx + grind [Real.sin_zero] + +/-- For 0 ≤ x we have x - x ^ 3 / 6 ≤ sin x. + +This inequality is tight, in that the constant 6 is best possible. -/ +theorem sin_ge_sub_cube {x : ℝ} (hx : 0 ≤ x) : x - x ^ 3 / 6 ≤ Real.sin x := by + obtain rfl | hx := hx.eq_or_lt + · simp + exact (sin_gt_sub_cube hx).le + +/-- `|x - sin x| ≤ |x|³ / 6` for every real `x`. -/ +theorem abs_sub_sin_le (x : ℝ) : |x - Real.sin x| ≤ |x| ^ 3 / 6 := by + wlog hx : 0 ≤ x + · grind [sin_neg] + · grind [Real.sin_le, abs_of_nonneg, sin_ge_sub_cube] /-- The derivative of `tan x - x` is `1/(cos x)^2 - 1` away from the zeroes of cos. -/ theorem deriv_tan_sub_id (x : ℝ) (h : cos x ≠ 0) : From b2b48591384d6b5af43b9e605df6b3f59722f47d Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Wed, 8 Jul 2026 00:16:50 +0000 Subject: [PATCH 0656/1300] chore(Topology): fix instances for CLM (#41172) --- .../Module/ContinuousLinearMap/Basic.lean | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean index b05b66b66b0ea6..19850c87fc323c 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean @@ -437,25 +437,7 @@ theorem toContinuousAddMonoidHom_add (f g : M₁ →SL[σ₁₂] M₂) : ↑(f + g) = (f + g : ContinuousAddMonoidHom M₁ M₂) := rfl -- The `AddMonoid` instance exists to help speedup unification -instance : AddMonoid (M₁ →SL[σ₁₂] M₂) where - zero_add := by - intros - ext - apply_rules [zero_add, add_assoc, add_zero, neg_add_cancel, add_comm] - add_zero := by - intros - ext - apply_rules [zero_add, add_assoc, add_zero, neg_add_cancel, add_comm] - add_assoc := by - intros - ext - apply_rules [zero_add, add_assoc, add_zero, neg_add_cancel, add_comm] - nsmul_zero f := by - ext - simp - nsmul_succ n f := by - ext - simp [add_smul] +instance : AddMonoid (M₁ →SL[σ₁₂] M₂) := fast_instance% FunLike.addMonoid instance addCommMonoid : AddCommMonoid (M₁ →SL[σ₁₂] M₂) := fast_instance% FunLike.addCommMonoid @@ -879,13 +861,7 @@ instance sub : Sub (M →SL[σ₁₂] M₂) := instance : IsSubApply (M →SL[σ₁₂] M₂) M M₂ where sub_apply _ _ _ := rfl --- Todo: figure out how to use `FunLike.addCommGroup` here -instance addCommGroup : AddCommGroup (M →SL[σ₁₂] M₂) where - sub_eq_add_neg _ _ := by ext; apply sub_eq_add_neg - zsmul_zero' f := by ext; simp - zsmul_succ' n f := by ext; simp [add_smul, add_comm] - zsmul_neg' n f := by ext; simp [add_smul] - neg_add_cancel _ := by ext; apply neg_add_cancel +instance addCommGroup : AddCommGroup (M →SL[σ₁₂] M₂) := fast_instance% FunLike.addCommGroup @[simp, norm_cast] theorem toLinearMap_sub (f g : M →SL[σ₁₂] M₂) : (↑(f - g) : M →ₛₗ[σ₁₂] M₂) = f - g := From d1cc9a6c17ee1d25b1468a06b04d8ff59eac63ae Mon Sep 17 00:00:00 2001 From: Sabrina Jewson <58880148+SabrinaJewson@users.noreply.github.com> Date: Wed, 8 Jul 2026 01:01:07 +0000 Subject: [PATCH 0657/1300] feat(Topology/Order): provide lemmas linking topological continuity to order continuity (#37684) All the hard work is already done, but this just fills in a couple convenient missing pieces. Co-authored-by: SabrinaJewson --- Mathlib/Topology/Order/Basic.lean | 7 +++++++ Mathlib/Topology/Order/IsLUB.lean | 1 + Mathlib/Topology/Order/Monotone.lean | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index bee708fa11f2b7..477b11d1e552ac 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -807,4 +807,11 @@ the function is between conditionally complete linear orders with order topologi lemma RightOrdContinuous.continuousWithinAt_Ici (hf : RightOrdContinuous f) : ContinuousWithinAt f (Ici x) x := hf.dual.continuousWithinAt_Iic +/-- A function that is order-theoretically both left- and right-continuous is continuous, assuming +the function is between conditionally complete linear orders with order topologies. -/ +lemma Continuous.of_ordContinuous (hl : LeftOrdContinuous f) (hr : RightOrdContinuous f) : + Continuous f := + continuous_iff_continuousAt.mpr fun _ ↦ continuousAt_iff_continuous_left_right.mpr + ⟨hl.continuousWithinAt_Iic, hr.continuousWithinAt_Ici⟩ + end ConditionallyCompleteLinearOrder diff --git a/Mathlib/Topology/Order/IsLUB.lean b/Mathlib/Topology/Order/IsLUB.lean index f36797e4ef2d73..b764d8851c42fb 100644 --- a/Mathlib/Topology/Order/IsLUB.lean +++ b/Mathlib/Topology/Order/IsLUB.lean @@ -110,6 +110,7 @@ theorem IsGLB.mem_lowerBounds_of_tendsto [Preorder γ] [TopologicalSpace γ] [Or -- For a version of this theorem in which the convergence considered on the domain `α` is as -- `x : α` tends to negative infinity, rather than tending to a point `x` in `α`, see -- `isGLB_of_tendsto_atBot` +@[to_dual existing] theorem IsGLB.isGLB_of_tendsto [Preorder γ] [TopologicalSpace γ] [OrderClosedTopology γ] {f : α → γ} {s : Set α} {a : α} {b : γ} (hf : MonotoneOn f s) : IsGLB s a → s.Nonempty → Tendsto f (𝓝[s] a) (𝓝 b) → IsGLB (f '' s) b := diff --git a/Mathlib/Topology/Order/Monotone.lean b/Mathlib/Topology/Order/Monotone.lean index 74f143f2542819..667414ec596d7e 100644 --- a/Mathlib/Topology/Order/Monotone.lean +++ b/Mathlib/Topology/Order/Monotone.lean @@ -168,6 +168,28 @@ theorem Antitone.countable_not_continuousAt (hf : Antitone f) : end Continuity +section OrdContinuous + +variable [TopologicalSpace β] [OrderTopology β] + +/-- A monotone left-continuous function is left-continuous in the order-theoretic sense. -/ +@[to_dual +/-- A monotone right-continuous function is right-continuous in the order-theoretic sense. -/ +] +theorem Monotone.leftOrdContinuous (hf : Monotone f) + (cont : ∀ x, ContinuousWithinAt f (Iic x) x) : LeftOrdContinuous f := + fun s x hs hx ↦ IsLUB.isLUB_of_tendsto (hf.monotoneOn s) hx hs ((cont x).mono hx.1) + +/-- A monotone continuous function is left-continuous in the order-theoretic sense. -/ +@[to_dual +/-- A monotone continuous function is right-continuous in the order-theoretic sense. -/ +] +theorem Continuous.leftOrdContinuous (cont : Continuous f) (hf : Monotone f) : + LeftOrdContinuous f := + hf.leftOrdContinuous fun _ ↦ cont.continuousWithinAt + +end OrdContinuous + end LinearOrder section ConditionallyCompleteLinearOrder From 6ea8e17f4adf46912bae545b8bee4373e0323e7c Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Wed, 8 Jul 2026 01:27:09 +0000 Subject: [PATCH 0658/1300] feat(InfiniteSum): zero function has product zero (#39855) Prove that in a comm monoid with zero, the product of the zero function is zero. --- Mathlib/Topology/Algebra/InfiniteSum/Basic.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index e9a8e8710bfd7c..c2f23ff8472ca4 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -779,11 +779,24 @@ lemma hasProd_zero_of_exists_eq_zero (hf : ∃ b, f b = 0) [L.LeAtTop] : HasProd filter_upwards [(eventually_ge_atTop {b}).filter_mono L.le_atTop] with s hs exact (Finset.prod_eq_zero (Finset.singleton_subset_iff.mp hs) hb).symm +lemma hasProd_zero_zero [Nonempty β] [L.LeAtTop] : HasProd (fun _ ↦ 0 : β → α) 0 L := by + obtain ⟨b⟩ := ‹Nonempty β› + exact hasProd_zero_of_exists_eq_zero ⟨b, by simp⟩ + lemma multipliable_of_exists_eq_zero (hf : ∃ b, f b = 0) [L.LeAtTop] : Multipliable f L := ⟨0, hasProd_zero_of_exists_eq_zero hf⟩ +lemma multipliable_zero [L.LeAtTop] : Multipliable (fun _ ↦ 0 : β → α) L := by + obtain hβ | hβ := isEmpty_or_nonempty β + · simp + · exact ⟨0, hasProd_zero_zero⟩ + lemma tprod_of_exists_eq_zero [T2Space α] [L.NeBot] [L.LeAtTop] (hf : ∃ b, f b = 0) : ∏'[L] b, f b = 0 := (hasProd_zero_of_exists_eq_zero hf).tprod_eq +@[simp] lemma tprod_zero [T2Space α] [Nonempty β] [L.NeBot] [L.LeAtTop] : + ∏'[L] _, (0 : α) = 0 := + hasProd_zero_zero.tprod_eq + end CommMonoidWithZero From a814cbd177cfc634b6a62f26b8762f5268917c42 Mon Sep 17 00:00:00 2001 From: Jiedong Jiang <107380768+jjdishere@users.noreply.github.com> Date: Wed, 8 Jul 2026 01:27:11 +0000 Subject: [PATCH 0659/1300] chore(Topology/Algebra/UniformMulAction): fix name style (#40445) In this PR, we rename some instances that does not follow the Mathlib naming convention. --- Mathlib/Topology/Algebra/UniformMulAction.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/Algebra/UniformMulAction.lean b/Mathlib/Topology/Algebra/UniformMulAction.lean index a5969d94f8b291..8252be5fe6518b 100644 --- a/Mathlib/Topology/Algebra/UniformMulAction.lean +++ b/Mathlib/Topology/Algebra/UniformMulAction.lean @@ -60,7 +60,7 @@ instance AddGroup.uniformContinuousConstSMul_int [AddGroup X] [IsUniformAddGroup /-- A `DistribSMul` that is continuous on a uniform group is uniformly continuous. This can't be an instance due to it forming a loop with -`UniformContinuousConstSMul.to_continuousConstSMul` -/ +`UniformContinuousConstSMul.instContinuousConstSMul` -/ theorem uniformContinuousConstSMul_of_continuousConstSMul [AddGroup M] [DistribSMul R M] [UniformSpace M] [IsUniformAddGroup M] [ContinuousConstSMul R M] : UniformContinuousConstSMul R M := @@ -83,7 +83,7 @@ section SMul variable [SMul M X] @[to_additive] -instance (priority := 100) UniformContinuousConstSMul.to_continuousConstSMul +instance (priority := 100) UniformContinuousConstSMul.instContinuousConstSMul [UniformContinuousConstSMul M X] : ContinuousConstSMul M X := ⟨fun c => (uniformContinuous_const_smul c).continuous⟩ @@ -119,7 +119,7 @@ instance MulOpposite.uniformContinuousConstSMul [UniformContinuousConstSMul M X] end SMul @[to_additive] -instance IsUniformGroup.to_uniformContinuousConstSMul {G : Type u} [Group G] [UniformSpace G] +instance IsUniformGroup.instUniformContinuousConstSMul {G : Type u} [Group G] [UniformSpace G] [IsUniformGroup G] : UniformContinuousConstSMul G G := ⟨fun _ => uniformContinuous_const.mul uniformContinuous_id⟩ From 324df5f3a1be99ebeb84d5ba542352f75ca2d719 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Wed, 8 Jul 2026 01:27:13 +0000 Subject: [PATCH 0660/1300] chore(Topology/Order/OrderClosed): add label to hypothesis `[NeBot _]` (#41385) This is so we can conveniently use it in `grw`, `refine`, `exact`, etc, by adding `(hx := proof)` without needing to declare `have := proof` or needing to do `convert` to use it. --- Mathlib/Topology/Order/OrderClosed.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/Order/OrderClosed.lean b/Mathlib/Topology/Order/OrderClosed.lean index 6388ad265d4940..be6dcbf83ed2f9 100644 --- a/Mathlib/Topology/Order/OrderClosed.lean +++ b/Mathlib/Topology/Order/OrderClosed.lean @@ -130,12 +130,12 @@ theorem le_of_tendsto_of_frequently {x : Filter β} (lim : Tendsto f x (𝓝 a)) isClosed_Iic.mem_of_frequently_of_tendsto h lim @[to_dual ge_of_tendsto] -theorem le_of_tendsto {x : Filter β} [NeBot x] (lim : Tendsto f x (𝓝 a)) +theorem le_of_tendsto {x : Filter β} [hx : NeBot x] (lim : Tendsto f x (𝓝 a)) (h : ∀ᶠ c in x, f c ≤ b) : a ≤ b := isClosed_Iic.mem_of_tendsto lim h @[to_dual ge_of_tendsto'] -theorem le_of_tendsto' {x : Filter β} [NeBot x] (lim : Tendsto f x (𝓝 a)) +theorem le_of_tendsto' {x : Filter β} [hx : NeBot x] (lim : Tendsto f x (𝓝 a)) (h : ∀ c, f c ≤ b) : a ≤ b := le_of_tendsto lim (Eventually.of_forall h) @@ -468,7 +468,7 @@ theorem le_of_tendsto_of_tendsto_of_frequently {f g : β → α} {b : Filter β} t.isClosed_le'.mem_of_frequently_of_tendsto h (hf.prodMk_nhds hg) @[to_dual self (reorder := f g, a₁ a₂, hf hg)] -theorem le_of_tendsto_of_tendsto {f g : β → α} {b : Filter β} {a₁ a₂ : α} [NeBot b] +theorem le_of_tendsto_of_tendsto {f g : β → α} {b : Filter β} {a₁ a₂ : α} [hb : NeBot b] (hf : Tendsto f b (𝓝 a₁)) (hg : Tendsto g b (𝓝 a₂)) (h : f ≤ᶠ[b] g) : a₁ ≤ a₂ := le_of_tendsto_of_tendsto_of_frequently hf hg <| Eventually.frequently h @@ -476,7 +476,7 @@ theorem le_of_tendsto_of_tendsto {f g : β → α} {b : Filter β} {a₁ a₂ : alias tendsto_le_of_eventuallyLE := le_of_tendsto_of_tendsto @[to_dual self (reorder := f g, a₁ a₂, hf hg)] -theorem le_of_tendsto_of_tendsto' {f g : β → α} {b : Filter β} {a₁ a₂ : α} [NeBot b] +theorem le_of_tendsto_of_tendsto' {f g : β → α} {b : Filter β} {a₁ a₂ : α} [hb : NeBot b] (hf : Tendsto f b (𝓝 a₁)) (hg : Tendsto g b (𝓝 a₂)) (h : ∀ x, f x ≤ g x) : a₁ ≤ a₂ := le_of_tendsto_of_tendsto hf hg (Eventually.of_forall h) From cb7e76b058574272af01cf4ae850cf5f27f8d88f Mon Sep 17 00:00:00 2001 From: Li Jiale <185082061+Scarlett-le@users.noreply.github.com> Date: Wed, 8 Jul 2026 01:56:41 +0000 Subject: [PATCH 0661/1300] feat: add orthogonality lemmas for 2-dimensional inner product spaces (#35956) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a two-dimensional inner product space over `𝕜`, if `u` is orthogonal to `v` and `v` is orthogonal to `w` (with `v ≠ 0` and `w ≠ 0`), then `u ∈ 𝕜 ∙ w`. Co-authored-by: Scarlett-le <735979178@qq.com> Co-authored-by: Jireh Loreaux --- .../Projection/FiniteDimensional.lean | 12 ++++++++++++ Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean b/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean index 59ddfb10a05528..f1542dd9fe6327 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean @@ -130,6 +130,18 @@ theorem finrank_orthogonal_span_singleton {n : ℕ} [_i : Fact (finrank 𝕜 E = exact finrank_add_finrank_orthogonal' <| by simp [finrank_span_singleton hv, _i.elim, add_comm] +/-- If a nonzero vector `w` and a vector `u` are both orthogonal to the same nonzero vector `v` +in a two-dimensional inner product space, then `u` lies in the span of `w`. -/ +theorem mem_span_singleton_of_inner_eq_zero_of_inner_eq_zero + [Fact (finrank 𝕜 E = 2)] {u v w : E} (hv : v ≠ 0) (hw : w ≠ 0) + (huv : ⟪v, u⟫_𝕜 = 0) (hwv : ⟪v, w⟫_𝕜 = 0) : + u ∈ 𝕜 ∙ w := by + haveI : FiniteDimensional 𝕜 E := .of_fact_finrank_eq_succ 1 + suffices heq : (𝕜 ∙ v)ᗮ = 𝕜 ∙ w by rwa [← heq, mem_orthogonal_singleton_iff_inner_right] + exact eq_span_singleton_of_mem_of_finrank_eq_one + (finrank_orthogonal_span_singleton (n := 1) hv) + (mem_orthogonal_singleton_iff_inner_right.mpr hwv) hw + end Submodule open Module Submodule diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index b948b99d513e9d..83c1c3b59a1cf9 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -582,6 +582,14 @@ lemma exists_smul_eq_of_finrank_eq_one have : y ∈ Submodule.span K {x} := by rw [this]; exact mem_top exact mem_span_singleton.1 this +/-- A submodule of finrank 1 is spanned by any of its nonzero elements. -/ +theorem eq_span_singleton_of_mem_of_finrank_eq_one {S : Submodule K V} {w : V} + (hS : finrank K S = 1) (hw : w ∈ S) (hw0 : w ≠ 0) : + S = K ∙ w := by + haveI : FiniteDimensional K S := Module.finite_of_finrank_pos (by lia) + exact Eq.symm <| eq_of_le_of_finrank_le (by simpa) + (by rw [hS, finrank_span_singleton hw0]) + theorem Set.finrank_mono [FiniteDimensional K V] {s t : Set V} (h : s ⊆ t) : s.finrank K ≤ t.finrank K := Submodule.finrank_mono (span_mono h) From 476ab284693e554a6b48c5f5210cb4fb5ae51252 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:42:12 +0000 Subject: [PATCH 0662/1300] doc(Algebra/GroupWithZero): replace `Nonzero M` with `Nontrivial M` (#41455) Co-authored-by: NoahW314 --- Mathlib/Algebra/GroupWithZero/Units/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean index 7b11b6be6663f4..873e7ab2b6ddf8 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean @@ -37,7 +37,7 @@ theorem ne_zero [Nontrivial M₀] (u : M₀ˣ) : (u : M₀) ≠ 0 := left_ne_zero_of_mul_eq_one u.mul_inv -- We can't use `mul_eq_zero` + `Units.ne_zero` in the next two lemmas because we don't assume --- `Nonzero M₀`. +-- `Nontrivial M₀`. @[simp] theorem mul_left_eq_zero (u : M₀ˣ) {a : M₀} : a * u = 0 ↔ a = 0 := ⟨fun h => by simpa using mul_eq_zero_of_left h ↑u⁻¹, fun h => mul_eq_zero_of_left h u⟩ From 323e515aa8839759bd2b1f375ec5358ec06fb0ab Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:27:13 +0000 Subject: [PATCH 0663/1300] chore(MeasureTheory/Measure/Lebesgue/EqHaar): remove an `erw` (#40408) Extracted from #40348 Co-authored-by: Batixx --- Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean index 70624b7e155506..0f79b4b9d11fa6 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean @@ -94,8 +94,10 @@ theorem map_addHaar {ι E F : Type*} [Fintype ι] [NormedAddCommGroup E] [Normed (b : Basis ι ℝ E) (f : E ≃L[ℝ] F) : map f b.addHaar = (b.map f.toLinearEquiv).addHaar := by rw [eq_comm, Basis.addHaar_eq_iff, Measure.map_apply f.continuous.measurable - (PositiveCompacts.isCompact _).measurableSet, Basis.coe_parallelepiped, Basis.coe_map] - erw [← image_parallelepiped, f.toEquiv.preimage_image, addHaar_self] + (PositiveCompacts.isCompact _).measurableSet, Basis.coe_parallelepiped, Basis.coe_map, + ← addHaar_self b, ← f.toEquiv.preimage_image (_root_.parallelepiped ⇑b)] + have := image_parallelepiped f.toLinearMap (⇑b : ι → E) + simp_all end Module.Basis From d9ea05095f397fd5a2d9f23cb2c005409150434a Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:27:16 +0000 Subject: [PATCH 0664/1300] feat(Data/Nat/Factorial/Basic): add `ascFactorial_le` (#40816) Co-authored-by: NoahW314 --- Mathlib/Data/Nat/Factorial/Basic.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Data/Nat/Factorial/Basic.lean b/Mathlib/Data/Nat/Factorial/Basic.lean index 4a434c8b88ebfa..092a314777028b 100644 --- a/Mathlib/Data/Nat/Factorial/Basic.lean +++ b/Mathlib/Data/Nat/Factorial/Basic.lean @@ -267,6 +267,12 @@ theorem ascFactorial_of_sub {n k : ℕ} : (n - k) * (n - k + 1).ascFactorial k = (n - k).ascFactorial (k + 1) := by rw [succ_ascFactorial, ascFactorial_succ] +theorem ascFactorial_le (k : ℕ) {n m : ℕ} (h : n ≤ m) : + n.ascFactorial k ≤ m.ascFactorial k := by + induction k with + | zero => rfl + | succ k ih => exact Nat.mul_le_mul (by lia) ih + theorem pow_succ_le_ascFactorial (n : ℕ) : ∀ k : ℕ, n ^ k ≤ n.ascFactorial k | 0 => by rw [ascFactorial_zero, Nat.pow_zero] | k + 1 => by From 6420e6d6623db25a408290cf5881643d02336ea7 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:27:18 +0000 Subject: [PATCH 0665/1300] feat(Analysis/SpecialFunctions/Log/InvLog): add more API for inv_log and log_log (#40847) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a `simp` lemma form `Real.deriv_inv_log'` of `Real.deriv_inv_log`, in analogy with `Real.deriv_inv` and `Real.deriv_inv'`, or `Real.deriv_log'` and `Real.deriv_log`. There were two downstream applications of `Real.deriv_inv_log` that received minor golfs as a consequence. Also added some helper lemmas for the associated `DifferentiableAt` and `HasDeriv` versions, as well as variants for the double logarithm. As applications, definite integrals of `t⁻¹ / log t` and `t⁻¹ / (log t)^2` were added to `Analysis.SpecialFunctions.Integrals.Basic`, and improper integrals of `t⁻¹ / (log t)^2` were added to `Analysis.SpecialFunctions.ImproperIntegrals`. Also added two asymptotic lemmas, asserting that `(fun x ↦ 1 / log x) =o[atTop] (fun _ ↦ (1:ℝ))` and `(fun _ ↦ (1:ℝ)) =o[atTop] (fun x ↦ log (log x))`, which will be needed to establish Mertens' second theorem. Co-authored-by: Terence Tao Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../SpecialFunctions/ImproperIntegrals.lean | 23 +++ .../SpecialFunctions/Integrals/Basic.lean | 25 ++++ .../Analysis/SpecialFunctions/Log/InvLog.lean | 138 +++++++++++++----- .../Computability/AkraBazzi/SumTransform.lean | 3 +- Mathlib/NumberTheory/Chebyshev.lean | 7 +- 5 files changed, 158 insertions(+), 38 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean b/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean index a678fe671d81af..5c5996c9bbff38 100644 --- a/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean +++ b/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean @@ -288,3 +288,26 @@ theorem integral_univ_inv_one_add_sq : ∫ (x : ℝ), (1 + x ^ 2)⁻¹ = π := (by ring : π = (π / 2) - (-(π / 2))) ▸ integral_of_hasDerivAt_of_tendsto hasDerivAt_arctan' integrable_inv_one_add_sq (tendsto_nhds_of_tendsto_nhdsWithin tendsto_arctan_atBot) (tendsto_nhds_of_tendsto_nhdsWithin tendsto_arctan_atTop) + +@[simp] +theorem integrableOn_inv_div_log_sq_Ioi {c : ℝ} (hc : 1 < c) : + IntegrableOn (fun t ↦ t⁻¹ / (log t) ^ 2) (.Ioi c) volume := by + apply integrableOn_Ioi_deriv_of_nonneg' _ _ tendsto_log_atTop.inv_tendsto_atTop.neg + · intro t _ + convert! (hasDerivAt_inv_log (by grind : t ≠ 0) (by grind) (by grind)).neg using 1 + field + · intro t _ + have : 0 < t := by grind + positivity + +@[simp] +theorem integral_inv_divlog_sq_Ioi {c : ℝ} (hc : 1 < c) : + ∫ (t : ℝ) in .Ioi c, t⁻¹ / (log t) ^ 2 = (log c)⁻¹ := by + convert! integral_Ioi_of_hasDerivAt_of_tendsto' (m := 0) (f := fun t ↦ -(log t)⁻¹) ?_ + (integrableOn_inv_div_log_sq_Ioi hc) ?_ using 1 + · simp + · intro t _ + convert! (hasDerivAt_inv_log (by grind : t ≠ 0) (by grind) (by grind)).neg using 1 + field + convert! tendsto_log_atTop.inv_tendsto_atTop.neg using 1 + simp diff --git a/Mathlib/Analysis/SpecialFunctions/Integrals/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Integrals/Basic.lean index ff569021f2a334..335df785f4a6b9 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrals/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrals/Basic.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.SpecialFunctions.NonIntegrable public import Mathlib.Analysis.SpecialFunctions.Pow.Deriv public import Mathlib.Analysis.SpecialFunctions.Integrability.Basic public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Sinc +public import Mathlib.Analysis.SpecialFunctions.Log.InvLog public import Mathlib.MeasureTheory.Integral.IntervalIntegral.IntegrationByParts /-! @@ -366,6 +367,30 @@ theorem integral_div_sq_add_sq {c : ℝ} : · rw [integral_const_mul, integral_inv_sq_add_sq hc] field_simp +/-- The integrand is chosen to match the conclusion of `Real.deriv_log_log`. -/ +@[simp] +theorem integral_inv_div_log (ha : 1 < a) (hb : 1 < b) : + ∫ t in a..b, t⁻¹ / log t = log (log b) - log (log a) := by + rw [← intervalIntegral.integral_congr (fun _ _ ↦ deriv_log_log_apply)] + refine integral_deriv_eq_sub (fun _ _ ↦ ?_) ?_ + · exact differentiableOn_log_log.differentiableAt (Ioi_mem_nhds (by grind [Set.uIcc])) + refine (?_ : ContinuousOn _ _).congr (fun _ _ ↦ deriv_log_log_apply) |>.intervalIntegrable + fun_prop (disch := grind [log_pos, Set.uIcc]) + +/-- The integrand is chosen to match the conclusion of `Real.deriv_inv_log`. -/ +@[simp] +theorem integral_inv_div_log_sq (ha : 1 < a) (hb : 1 < b) : + ∫ t in a..b, t⁻¹ / log t ^ 2 = (log a)⁻¹ - (log b)⁻¹ := by + suffices ∫ t in a..b, deriv (fun t ↦ (log t)⁻¹) t = (log b)⁻¹ - (log a)⁻¹ by + simp_rw [deriv_inv_log, neg_div, intervalIntegral.integral_neg] at this + linarith + refine integral_deriv_eq_sub (fun _ _ ↦ ?_) (ContinuousOn.intervalIntegrable ?_) + · exact differentiableOn_inv_log.differentiableAt (Ioi_mem_nhds (by grind [Set.uIcc])) + suffices ContinuousOn (fun x ↦ (-x⁻¹) * ((log x)⁻¹) ^ 2) (.uIcc a b) by + convert this using 2 with x + simp [field] + fun_prop (disch := grind [log_pos, Set.uIcc]) + section RpowCpow open Complex diff --git a/Mathlib/Analysis/SpecialFunctions/Log/InvLog.lean b/Mathlib/Analysis/SpecialFunctions/Log/InvLog.lean index 5d3d4f4f7f63d6..dab4599433b67f 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/InvLog.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/InvLog.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Alastair Irving. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Alastair Irving, Michael Stoll +Authors: Alastair Irving, Michael Stoll, Terence Tao -/ module @@ -10,53 +10,125 @@ public import Mathlib.Analysis.SpecialFunctions.Log.Deriv public import Mathlib.Analysis.SpecialFunctions.Pow.Asymptotics /-! -# Multiplicative inverse of real logarithm +# Multiplicative inverse and iteration of real logarithm -We prove properties of the function `x ↦ (log x)⁻¹`. +We prove properties of the functions `x ↦ (log x)⁻¹` and `x ↦ log (log x)`. ## Main results -- `deriv_inv_log` gives a formula for the derivative which holds for all values. +- `deriv_inv_log` gives a formula for the derivative of `x ↦ (log x)⁻¹` which holds for all values. +- `deriv_log_log` gives a formula for the derivative of `x ↦ log (log x)` which holds for all + values. -/ public section namespace Real -open Filter +open Filter Asymptotics Bornology Metric IsOrderBornology DifferentiableAt + +/- ## Derivative of the inverse logarithm -/ lemma not_differentiableAt_inv_log_zero : ¬ DifferentiableAt ℝ (fun x ↦ (log x)⁻¹) 0 := by simp only [← hasDerivAt_deriv_iff, hasDerivAt_iff_tendsto_slope_zero, zero_add, log_zero, inv_zero, sub_zero, smul_eq_mul, ← mul_inv, mul_comm _ (log _)] - have H' : Tendsto (fun x ↦ log x * x) (nhdsWithin 0 (Set.Iio 0)) (nhdsWithin 0 (Set.Ioi 0)) := by - refine tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _ - tendsto_log_mul_self_nhdsLT_zero ?_ - simp only [← nhdsWithin_Ioo_eq_nhdsLT neg_one_lt_zero, Set.mem_Ioi] - refine eventually_nhdsWithin_of_forall fun x ⟨hx₁, hx₂⟩ ↦ mul_pos_of_neg_of_neg ?_ hx₂ - refine log_neg_eq_log x ▸ log_neg ?_ ?_ <;> grind - exact fun H ↦ (tendsto_nhdsWithin_mono_left (show Set.Iio (0 : ℝ) ⊆ _ by grind) H).not_tendsto - (by simp) (tendsto_inv_nhdsGT_zero.comp H') + refine fun H ↦ (tendsto_nhdsWithin_mono_left (by grind : Set.Iio (0 : ℝ) ⊆ _) H).not_tendsto + (by simp) (tendsto_inv_nhdsGT_zero.comp ?_) + refine tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _ + tendsto_log_mul_self_nhdsLT_zero ?_ + simp only [← nhdsWithin_Ioo_eq_nhdsLT neg_one_lt_zero, Set.mem_Ioi] + refine eventually_nhdsWithin_of_forall fun x ⟨hx₁, hx₂⟩ ↦ mul_pos_of_neg_of_neg ?_ hx₂ + apply log_neg_eq_log x ▸ log_neg <;> grind lemma not_continuousAt_inv_log_one : ¬ ContinuousAt (fun x ↦ (log x)⁻¹) 1 := by - suffices Tendsto (fun x ↦ (log x)⁻¹) (nhdsWithin 1 {1}ᶜ) (Bornology.cobounded ℝ) from - not_continuousAt_of_tendsto this nhdsWithin_le_nhds (Metric.disjoint_nhds_cobounded _) - have H := HasDerivAt.tendsto_nhdsNE (by simpa using hasDerivAt_log one_ne_zero) one_ne_zero - exact tendsto_inv₀_nhdsNE_zero.comp <| log_one ▸ H - -lemma not_continuousAt_inv_log_neg_one : ¬ ContinuousAt (fun x ↦ (log x)⁻¹) (-1) := by - refine fun H ↦ not_continuousAt_inv_log_one ?_ - simpa only [log_neg_eq_log] using ContinuousAt.comp' H continuousAt_neg - -theorem deriv_inv_log {x : ℝ} : - deriv (fun x ↦ (log x)⁻¹) x = -x⁻¹ / (log x ^ 2) := by - rcases eq_or_ne x 0 with rfl | h0 - · simpa using deriv_zero_of_not_differentiableAt not_differentiableAt_inv_log_zero - rcases eq_or_ne x 1 with rfl | h1 - · simpa using deriv_zero_of_not_differentiableAt <| - mt DifferentiableAt.continuousAt not_continuousAt_inv_log_one - rcases eq_or_ne x (-1) with rfl | h2 - · simpa using deriv_zero_of_not_differentiableAt <| - mt DifferentiableAt.continuousAt not_continuousAt_inv_log_neg_one - simp_all + suffices Tendsto (fun x ↦ (log x)⁻¹) (nhdsWithin 1 {1}ᶜ) (cobounded ℝ) from + not_continuousAt_of_tendsto this nhdsWithin_le_nhds (disjoint_nhds_cobounded _) + exact tendsto_inv₀_nhdsNE_zero.comp <| log_one ▸ + HasDerivAt.tendsto_nhdsNE (by simpa using hasDerivAt_log one_ne_zero) one_ne_zero + +lemma not_continuousAt_inv_log_neg_one : ¬ ContinuousAt (fun x ↦ (log x)⁻¹) (-1) := + fun H ↦ not_continuousAt_inv_log_one + (by simpa only [log_neg_eq_log] using H.comp' continuousAt_neg) + +theorem deriv_inv_log_apply {x : ℝ} : deriv (fun x ↦ (log x)⁻¹) x = -x⁻¹ / log x ^ 2 := by + have := mt (continuousAt (𝕜 := ℝ)) not_continuousAt_inv_log_neg_one + have := mt (continuousAt (𝕜 := ℝ)) not_continuousAt_inv_log_one + have := not_differentiableAt_inv_log_zero + obtain (⟨_, _, _⟩ | rfl | rfl | rfl) : + (x ≠ -1 ∧ x ≠ 0 ∧ x ≠ 1) ∨ x = -1 ∨ x = 0 ∨ x = 1 := by tauto + · simp_all + all_goals rw [deriv_zero_of_not_differentiableAt ‹_›]; simp + +@[simp] +theorem deriv_inv_log : deriv (fun x ↦ (log x)⁻¹) = fun x ↦ -x⁻¹ / log x ^ 2 := + funext fun _ ↦ deriv_inv_log_apply + +theorem differentiableAt_inv_log {x : ℝ} (hx₀ : x ≠ 0) (hx₁ : x ≠ 1) (hx₂ : x ≠ -1) : + DifferentiableAt ℝ (fun x ↦ (log x)⁻¹) x := by + fun_prop (disch := grind [log_ne_zero]) + +theorem hasDerivAt_inv_log {x : ℝ} (hx₀ : x ≠ 0) (hx₁ : x ≠ 1) (hx₂ : x ≠ -1) : + HasDerivAt (fun x ↦ (log x)⁻¹) (-x⁻¹ / (log x ^ 2)) x := by + simpa using (differentiableAt_inv_log hx₀ hx₁ hx₂).hasDerivAt + +theorem differentiableOn_inv_log' : DifferentiableOn ℝ (fun x ↦ (log x)⁻¹) {-1,0,1}ᶜ := + (differentiableOn_log.mono (by grind)).inv (by simp; tauto) + +theorem differentiableOn_inv_log : DifferentiableOn ℝ (fun x ↦ (log x)⁻¹) (.Ioi 1) := + differentiableOn_inv_log'.mono (by grind) + +theorem inv_log_isLittleO_one : (fun x ↦ (log x)⁻¹) =o[atTop] fun _ ↦ (1 : ℝ) := by + rw [isLittleO_one_iff] + convert tendsto_log_atTop.inv_tendsto_atTop; simp + +/- ## Derivative of the iterated logarithm -/ + +lemma not_continuousAt_log_log_zero : ¬ ContinuousAt (fun x ↦ log (log x)) 0 := by + suffices Tendsto (fun x ↦ log (log x)) (nhdsWithin 0 {0}ᶜ) (cobounded ℝ) from + not_continuousAt_of_tendsto this nhdsWithin_le_nhds (disjoint_nhds_cobounded _) + have : Tendsto log atBot atTop := by + convert tendsto_log_atTop.comp tendsto_neg_atBot_atTop; ext; simp + exact (this.mono_right atTop_le_cobounded).comp tendsto_log_nhdsNE_zero + +lemma not_continuousAt_log_log_one : ¬ ContinuousAt (fun x ↦ log (log x)) 1 := by + suffices Tendsto (fun x ↦ log (log x)) (nhdsWithin 1 {1}ᶜ) (cobounded ℝ) from + not_continuousAt_of_tendsto this nhdsWithin_le_nhds (disjoint_nhds_cobounded _) + exact (tendsto_log_nhdsNE_zero.mono_right atBot_le_cobounded).comp <| log_one ▸ + HasDerivAt.tendsto_nhdsNE (by simpa using hasDerivAt_log one_ne_zero) one_ne_zero + +lemma not_continuousAt_log_log_neg_one : ¬ ContinuousAt (fun x ↦ log (log x)) (-1) := + fun H ↦ not_continuousAt_log_log_one + (by simpa only [log_neg_eq_log] using H.comp' continuousAt_neg) + +theorem deriv_log_log_apply {x : ℝ} : deriv (fun x ↦ log (log x)) x = x⁻¹ / log x := by + have := not_continuousAt_log_log_neg_one + have := not_continuousAt_log_log_zero + have := not_continuousAt_log_log_one + obtain (⟨_, _, _⟩ | rfl | rfl | rfl) : + (x ≠ -1 ∧ x ≠ 0 ∧ x ≠ 1) ∨ x = -1 ∨ x = 0 ∨ x = 1 := by tauto + · simp_all + all_goals rw [deriv_zero_of_not_differentiableAt (mt continuousAt ‹_›)]; simp + +@[simp] +theorem deriv_log_log : deriv (fun x ↦ log (log x)) = fun x ↦ x⁻¹ / log x := + funext fun _ ↦ deriv_log_log_apply + +theorem differentiableAt_log_log {x : ℝ} (hx₀ : x ≠ 0) (hx₁ : x ≠ 1) (hx₂ : x ≠ -1) : + DifferentiableAt ℝ (fun x ↦ log (log x)) x := + (differentiableAt_log (by grind)).log (by simp; grind) + +theorem hasDerivAt_log_log {x : ℝ} (hx₀ : x ≠ 0) (hx₁ : x ≠ 1) (hx₂ : x ≠ -1) : + HasDerivAt (fun x ↦ log (log x)) (x⁻¹ / log x) x := by + simpa using (differentiableAt_log_log hx₀ hx₁ hx₂).hasDerivAt + +theorem differentiableOn_log_log' : DifferentiableOn ℝ (fun x ↦ log (log x)) {-1,0,1}ᶜ := + (differentiableOn_log.mono (by grind)).log (by simp; tauto) + +theorem differentiableOn_log_log : DifferentiableOn ℝ (fun x ↦ log (log x)) (.Ioi 1) := + differentiableOn_log_log'.mono (by grind) + +theorem one_isLittleO_log_log : (fun _ ↦ (1 : ℝ)) =o[atTop] fun x ↦ log (log x) := by + simp only [isLittleO_one_left_iff, norm_eq_abs] + exact tendsto_abs_atTop_atTop.comp (tendsto_log_atTop.comp tendsto_log_atTop) end Real diff --git a/Mathlib/Computability/AkraBazzi/SumTransform.lean b/Mathlib/Computability/AkraBazzi/SumTransform.lean index db27473bb71623..227670ace0f31f 100644 --- a/Mathlib/Computability/AkraBazzi/SumTransform.lean +++ b/Mathlib/Computability/AkraBazzi/SumTransform.lean @@ -357,8 +357,7 @@ lemma differentiableOn_one_add_smoothingFn : DifferentiableOn ℝ (fun z => 1 + lemma deriv_smoothingFn {x : ℝ} : deriv ε x = -x⁻¹ / (log x ^ 2) := by unfold smoothingFn - simp_rw [one_div] - apply deriv_inv_log + simp lemma isLittleO_deriv_smoothingFn : deriv ε =o[atTop] fun x => x⁻¹ := calc deriv ε diff --git a/Mathlib/NumberTheory/Chebyshev.lean b/Mathlib/NumberTheory/Chebyshev.lean index f5d4549c5106cb..f11b8f7ec00db4 100644 --- a/Mathlib/NumberTheory/Chebyshev.lean +++ b/Mathlib/NumberTheory/Chebyshev.lean @@ -652,8 +652,9 @@ theorem primeCounting_eq_theta_div_log_add_integral {x : ℝ} (hx : 2 ≤ x) : have int_deriv (f : ℝ → ℝ) : ∫ u in 2..x, deriv (fun x ↦ (log x)⁻¹) u * f u = ∫ u in 2..x, f u * -(u * log u ^ 2)⁻¹ := - intervalIntegral.integral_congr fun u _ ↦ by simp [deriv_inv_log, field] - simp [int_deriv, a, Set.indicator_apply, sum_filter, theta_eq_sum_Icc] + intervalIntegral.integral_congr fun u _ ↦ by simp [field] + rw [int_deriv] + simp [a, Set.indicator_apply, sum_filter, theta_eq_sum_Icc] grind · -- Differentiability intro z ⟨_, _⟩ @@ -662,7 +663,7 @@ theorem primeCounting_eq_theta_div_log_add_integral {x : ℝ} (hx : 2 ≤ x) : fun_prop · -- Integrability of the derivative refine ContinuousOn.integrableOn_Icc fun z ⟨_, _⟩ ↦ ContinuousWithinAt.congr ?_ - (fun _ _ ↦ deriv_inv_log) deriv_inv_log + (fun _ _ ↦ deriv_inv_log_apply) deriv_inv_log_apply have : z ≠ 0 := by linarith have : log z ^ 2 ≠ 0 := by refine pow_ne_zero 2 <| log_ne_zero_of_pos_of_ne_one ?_ ?_ <;> linarith From fa1dc79258f485f4273372b736879769d764fbd3 Mon Sep 17 00:00:00 2001 From: Francesco Chotuck <101644758+FrankieNC@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:27:21 +0000 Subject: [PATCH 0666/1300] feat(Algebra/Order/Module): monotonicity of scalar multiplication (#41060) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Summary Add the `const_smul`/`smul_const` family of monotonicity lemmas in `Algebra/Order/Module/Defs`: left/right scalar multiplication by a nonnegative (resp. positive) element preserves (anti/strict)tonicity. * `Monotone.const_smul`, `Antitone.const_smul`, `StrictMono.const_smul`, `StrictAnti.const_smul` (`a • f x`, `PosSMulMono`/`PosSMulStrictMono`) * `Monotone.smul_const`, `Antitone.smul_const`, `StrictMono.smul_const`, `StrictAnti.smul_const` (`f x • b`, `SMulPosMono`/`SMulPosStrictMono`) These are the `smul` analogues of the existing `Monotone.const_mul`/ `mul_const` family, proved by composing with `monotone_smul_left_of_nonneg`/ `monotone_smul_right_of_nonneg` (and their strict counterparts). --- Mathlib/Algebra/Order/Module/Defs.lean | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Mathlib/Algebra/Order/Module/Defs.lean b/Mathlib/Algebra/Order/Module/Defs.lean index 77bc2b291d884b..88019b5c7d3466 100644 --- a/Mathlib/Algebra/Order/Module/Defs.lean +++ b/Mathlib/Algebra/Order/Module/Defs.lean @@ -327,6 +327,26 @@ lemma strictMono_smul_left_of_pos [PosSMulStrictMono α β] (ha : 0 < a) : @[gcongr] lemma smul_lt_smul_of_pos_left [PosSMulStrictMono α β] (hb : b₁ < b₂) (ha : 0 < a) : a • b₁ < a • b₂ := strictMono_smul_left_of_pos ha hb +/-- Scalar multiplication on the left by a nonnegative element preserves monotonicity. -/ +lemma Monotone.const_smul [PosSMulMono α β] {γ : Type*} [Preorder γ] {f : γ → β} + (hf : Monotone f) (ha : 0 ≤ a) : Monotone fun x ↦ a • f x := + (monotone_smul_left_of_nonneg ha).comp hf + +/-- Scalar multiplication on the left by a nonnegative element preserves antitonicity. -/ +lemma Antitone.const_smul [PosSMulMono α β] {γ : Type*} [Preorder γ] {f : γ → β} + (hf : Antitone f) (ha : 0 ≤ a) : Antitone fun x ↦ a • f x := + (monotone_smul_left_of_nonneg ha).comp_antitone hf + +/-- Scalar multiplication on the left by a positive element preserves strict monotonicity. -/ +lemma StrictMono.const_smul [PosSMulStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → β} + (hf : StrictMono f) (ha : 0 < a) : StrictMono fun x ↦ a • f x := + (strictMono_smul_left_of_pos ha).comp hf + +/-- Scalar multiplication on the left by a positive element preserves strict antitonicity. -/ +lemma StrictAnti.const_smul [PosSMulStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → β} + (hf : StrictAnti f) (ha : 0 < a) : StrictAnti fun x ↦ a • f x := + (strictMono_smul_left_of_pos ha).comp_strictAnti hf + lemma lt_of_smul_lt_smul_left [PosSMulReflectLT α β] (h : a • b₁ < a • b₂) (ha : 0 ≤ a) : b₁ < b₂ := PosSMulReflectLT.lt_of_smul_lt_smul_left ha h @@ -357,6 +377,26 @@ lemma monotone_smul_right_of_nonneg [SMulPosMono α β] (hb : 0 ≤ b) : Monoton lemma strictMono_smul_right_of_pos [SMulPosStrictMono α β] (hb : 0 < b) : StrictMono ((· • b) : α → β) := SMulPosStrictMono.smul_lt_smul_of_pos_right hb +/-- Scalar multiplication on the right by a nonnegative element preserves monotonicity. -/ +lemma Monotone.smul_const [SMulPosMono α β] {γ : Type*} [Preorder γ] {f : γ → α} + (hf : Monotone f) (hb : 0 ≤ b) : Monotone fun x ↦ f x • b := + (monotone_smul_right_of_nonneg hb).comp hf + +/-- Scalar multiplication on the right by a nonnegative element preserves antitonicity. -/ +lemma Antitone.smul_const [SMulPosMono α β] {γ : Type*} [Preorder γ] {f : γ → α} + (hf : Antitone f) (hb : 0 ≤ b) : Antitone fun x ↦ f x • b := + (monotone_smul_right_of_nonneg hb).comp_antitone hf + +/-- Scalar multiplication on the right by a positive element preserves strict monotonicity. -/ +lemma StrictMono.smul_const [SMulPosStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → α} + (hf : StrictMono f) (hb : 0 < b) : StrictMono fun x ↦ f x • b := + (strictMono_smul_right_of_pos hb).comp hf + +/-- Scalar multiplication on the right by a positive element preserves strict antitonicity. -/ +lemma StrictAnti.smul_const [SMulPosStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → α} + (hf : StrictAnti f) (hb : 0 < b) : StrictAnti fun x ↦ f x • b := + (strictMono_smul_right_of_pos hb).comp_strictAnti hf + @[gcongr] lemma smul_le_smul_of_nonneg_right [SMulPosMono α β] (ha : a₁ ≤ a₂) (hb : 0 ≤ b) : a₁ • b ≤ a₂ • b := monotone_smul_right_of_nonneg hb ha From 9a0c9f31d4bc20b7fa363c2dfb0f678b7a9e2ecb Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:27:23 +0000 Subject: [PATCH 0667/1300] chore(Util): remove a global `privateInPublic` exception (#41431) Co-authored-by: Batixx --- Mathlib/Util/CompileInductive.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Util/CompileInductive.lean b/Mathlib/Util/CompileInductive.lean index 14ad1ecefb6004..780897eb602329 100644 --- a/Mathlib/Util/CompileInductive.lean +++ b/Mathlib/Util/CompileInductive.lean @@ -258,9 +258,6 @@ compile_inductive% Option compile_def% False.recOn compile_def% Empty.recOn -set_option backward.privateInPublic true -set_option backward.privateInPublic.warn false - -- In addition to the manual implementation below, we also have to override the `Float.val` and -- `Float.mk` functions because these also have no implementation in core lean. -- Because `floatSpec.float` is an opaque type, the identity function is as good an implementation @@ -269,7 +266,13 @@ private unsafe def Float.valUnsafe : Float → floatSpec.float := unsafeCast private unsafe def Float.mkUnsafe : floatSpec.float → Float := unsafeCast @[implemented_by Float.valUnsafe] private def Float.valImpl (x : Float) : floatSpec.float := x.1 @[implemented_by Float.mkUnsafe] private def Float.mkImpl (x : floatSpec.float) : Float := ⟨x⟩ + +set_option backward.privateInPublic true in +set_option backward.privateInPublic.warn false in @[csimp] private theorem Float.val_eq : @Float.val = Float.valImpl := rfl + +set_option backward.privateInPublic true in +set_option backward.privateInPublic.warn false in @[csimp] private theorem Float.mk_eq : @Float.mk = Float.mkImpl := rfl -- These types need manual implementations because the default implementation in `compileStruct` From 364057064c26a1f04d0d01c7dfb7f0cf173a7feb Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 8 Jul 2026 04:20:22 +0000 Subject: [PATCH 0668/1300] feat(Algebra/Group/Subgroup/ZPowers/Lemmas): `zmultiples` sup/inf over the integers (#41261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For `a b : ℤ`: - `zmultiples a ⊔ zmultiples b = zmultiples (a.gcd b)` - `zmultiples a ⊓ zmultiples b = zmultiples (a.lcm b)` Co-authored-by: Jireh Loreaux --- Mathlib/Algebra/Group/Subgroup/ZPowers/Lemmas.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/ZPowers/Lemmas.lean b/Mathlib/Algebra/Group/Subgroup/ZPowers/Lemmas.lean index 59c009c076593f..fc96785132915a 100644 --- a/Mathlib/Algebra/Group/Subgroup/ZPowers/Lemmas.lean +++ b/Mathlib/Algebra/Group/Subgroup/ZPowers/Lemmas.lean @@ -75,4 +75,11 @@ theorem closure_eq_zmultiples (a b : ℤ) : closure {a, b} = zmultiples (a.gcd b · grind [closure_le, mem_zmultiples_iff, SetLike.mem_coe, gcd_dvd_left, gcd_dvd_right] · simp [zmultiples_le, mem_closure_pair, gcd_eq_gcd_ab, mul_comm] +theorem zmultiples_sup (a b : ℤ) : zmultiples a ⊔ zmultiples b = zmultiples (a.gcd b : ℤ) := by + simp_rw [← closure_eq_zmultiples, zmultiples_eq_closure, ← closure_union, Set.singleton_union] + +theorem zmultiples_inf (a b : ℤ) : zmultiples a ⊓ zmultiples b = zmultiples (a.lcm b : ℤ) := by + ext + simp [mem_zmultiples_iff, coe_lcm_dvd_iff] + end Int From feca3f1f0a59995ce24b35e3fd99fd4fd56df74e Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 8 Jul 2026 05:25:06 +0000 Subject: [PATCH 0669/1300] feat: extended canonical decomposition (#40191) Establish the Extended Canonical Decomposition of meromorphic functions, where a complex-meromorphic function `f` on a closed disk is written, up to modification over a discrete set, as a product of a non-vanishing analytic function, canonical factors and meromorphic functions of the form `(x - const) ^ n` where `const` is on the circumference of the disk. This extended decomposition is key in the proof of the classic Poisson-Jensen formula. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Algebra/BigOperators/Finprod.lean | 8 + .../Complex/CanonicalDecomposition.lean | 144 +++++++++++++++++- Mathlib/Topology/DiscreteSubset.lean | 10 ++ 3 files changed, 154 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index b2aab9788f5d16..c930a7b8c6efdf 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -445,6 +445,14 @@ theorem finprod_ne_zero {M₀ : Type*} [CommMonoidWithZero M₀] [Nontrivial M · grind [finprod_eq_prod f h₂, Finset.prod_ne_zero_iff] · simp [finprod_of_infinite_mulSupport h₂] +theorem finprod_apply_ne_zero {ι : Type*} {N₀ M₀ : Type*} [CommMonoidWithZero M₀] [Nontrivial M₀] + [NoZeroDivisors M₀] {n : N₀} {f : ι → N₀ → M₀} (h : ∀ i, f i n ≠ 0) : + (∏ᶠ i, f i) n ≠ 0 := by + by_cases h₂ : f.mulSupport.Finite + · rw [finprod_eq_prod f h₂] + grind [Finset.prod_apply, Finset.prod_ne_zero_iff] + · simp [finprod_of_infinite_mulSupport h₂] + @[to_additive] theorem map_finsetProd {α F : Type*} [Fintype α] [EquivLike F M N] [MulEquivClass F M N] (f : F) (g : α → M) : f (∏ i : α, g i) = ∏ i : α, f (g i) := by diff --git a/Mathlib/Analysis/Complex/CanonicalDecomposition.lean b/Mathlib/Analysis/Complex/CanonicalDecomposition.lean index 0137bf9a8e6cd6..c12b3682f64313 100644 --- a/Mathlib/Analysis/Complex/CanonicalDecomposition.lean +++ b/Mathlib/Analysis/Complex/CanonicalDecomposition.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Meromorphic.FactorizedRational public import Mathlib.Analysis.Meromorphic.RCLike +public import Mathlib.Analysis.Normed.Module.Connected /-! # Canonical Decomposition @@ -19,18 +20,18 @@ as `(∏ᶠ u, (· - u) ^ divisor f U u) • g`, where `g` is analytic without z values of norm one on the boundary of the disk. This file introduces the canonical factors and provides API for the canonical decomposition. +This file also formulates an extended version of the canonical decomposition that takes zeros on +poles on the boundary of the ball into account. + See Page 160f of [Lang, *Introduction to Complex Hyperbolic Spaces*][MR886677] for a detailed discussion. - -TODO: Formulate a refined version of the canonical decomposition that takes zeros on poles on the -boundary of the ball into account. -/ @[expose] public section namespace Complex -open ComplexConjugate Filter Function MeromorphicOn Metric Real Set +open ComplexConjugate Filter Function MeromorphicOn Metric Real Set Topology variable {R : ℝ} {w : ℂ} @@ -219,7 +220,7 @@ the conclusions of the decomposition theorem. variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] {R : ℝ} {c w : ℂ} - {f : ℂ → E} + {f g : ℂ → E} /-- Given functions `f`, `g` and a real number `R`, the following convenience structure packs the @@ -229,13 +230,10 @@ is formulated by saying that `g` is meromorphic in normal form and `g ≠ 0`. structure CanonicalDecomp (f g : ℂ → E) (R : ℝ) : Prop where /-- A proof that `f` is meromorphic on `closedBall 0 R`. -/ meromorphicOn : MeromorphicOn f (closedBall 0 R) - /-- A proof that `g` is meromorphic in normal form on `closedBall 0 R`. -/ meromorphicNFOn : MeromorphicNFOn g (closedBall 0 R) - /-- A proof that `g` does not vanish in the interior of the ball. -/ ne_zero : ∀ u ∈ (ball 0 R), g u ≠ 0 - /-- A proof that `f` is equal, up to modification over a discrete set, to a product of `g` and canonical factors prescribed by the divisor of `f`. @@ -385,4 +383,134 @@ theorem _root_.MeromorphicOn.exists_canonicalDecomp filter_upwards [toMeromorphicNFOn_eqOn_codiscrete hφ] using by simp_all [g] } +/-- +Given a canonical decomposition `CanonicalDecomp f g R`, the function associated with the divisor of +`g` equals the function associated with the divisor of `f`, seen as a meromorphic function on the +sphere. +-/ +theorem CanonicalDecomp.divisor_eq_divisor {x : ℂ} (D : CanonicalDecomp f g R) (hR : 0 < R) : + divisor g (closedBall (0 : ℂ) R) x = divisor f (sphere 0 R) x := by + rcases lt_trichotomy ‖x‖ R with h|h|h + · -- The case where `x` is contained in `ball 0 R`. There, the divisor of `g` vanishes because `g` + -- does not have zeros or poles. The divisor of `f` vanishes because `x` is not contained in the + -- sphere. + have : x ∉ sphere (0 : ℂ) R := by aesop + have := (D.meromorphicNFOn (mem_closedBall_zero_iff.mpr h.le)).meromorphicOrderAt_eq_zero_iff.2 + (D.ne_zero x (by aesop)) + rw [divisor_apply D.meromorphicNFOn.meromorphicOn (mem_closedBall_zero_iff.mpr h.le)] + simp_all + · -- The case where `x` is contained in `sphere 0 R`. There, the orders of `f` and `g` agree + -- because the canonical factors are analytic and do not vanish. + have η₁ : AnalyticAt ℂ (∏ᶠ u, canonicalFactor R u ^ (-(divisor f (ball 0 R)) u)) x := by + refine analyticAt_finprod fun a ↦ ?_ + by_cases ha : a ∈ ball 0 R + · exact (analyticOnNhd_canonicalFactor _ _ _ (by aesop)).zpow + (canonicalFactor_ne_zero ha (by aesop) (by aesop)) + · simp_all only [mem_ball, dist_zero_right, not_lt, + locallyFinsuppWithin.apply_eq_zero_of_notMem, neg_zero, zpow_zero] + exact analyticAt_const + have η₀ : f =ᶠ[𝓝[≠] x] (∏ᶠ u, canonicalFactor R u ^ (-(divisor f (ball 0 R)) u)) • g := by + refine MeromorphicAt.eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin_preperfect + (U := closedBall 0 R) (D.meromorphicOn x (by aesop)) + (η₁.meromorphicAt.smul (D.meromorphicNFOn.meromorphicOn x (by aesop))) (by aesop) ?_ + D.eventuallyEq + rw [← closure_ball 0 hR.ne'] + exact isOpen_ball.perfect_closure.2 + have : meromorphicOrderAt (∏ᶠ u, canonicalFactor R u ^ (-(divisor f (ball 0 R)) u)) x = 0 := by + refine η₁.meromorphicNFAt.meromorphicOrderAt_eq_zero_iff.2 (finprod_apply_ne_zero fun a ↦ ?_) + by_cases ha : a ∈ ball 0 R + · exact zpow_ne_zero _ (canonicalFactor_ne_zero ha (by aesop) (by aesop)) + · simp_all + rw [divisor_apply (D.meromorphicOn.mono_set sphere_subset_closedBall) (by aesop), + divisor_apply D.meromorphicNFOn.meromorphicOn (by aesop), meromorphicOrderAt_congr η₀, + meromorphicOrderAt_smul η₁.meromorphicAt (D.meromorphicNFOn (by aesop)).meromorphicAt] + simp_all + · -- Trivial case: `x` is outside `closedBall 0 R`, so both divisors evaluate to zero. + have : x ∉ sphere (0 : ℂ) R := by aesop + simp_all + +/-! +## Extended Canonical Decomposition + +The extended canonical decomposition theorem shows that a meromorphic function `f` on a closed disk +is equal, up to modification over a discrete set, to a product of a non-vanishing analytic function, +canonical factors and meromorphic functions of the form `(x - const) ^ n` where `const` is on the +circumference of the disk. + +To simplify notation and avoid repetition, we introduce a structure, `ECanonicalDecomp`, that +bundles the conclusions of the extended canonical decomposition theorem. +-/ + +/-- +Given functions `f`, `g` and a real number `R`, the following convenience structure packs the +information relevant in the extended canonical decomposition. +-/ +structure ECanonicalDecomp (f g : ℂ → E) (R : ℝ) where + /-- A proof that `f` is meromorphic on `closedBall 0 R`. -/ + meromorphicOn : MeromorphicOn f (closedBall 0 R) + /-- A proof that `g` is analytic in a neighborhood of `closedBall 0 R`. -/ + analyticOnNhd : AnalyticOnNhd ℂ g (closedBall 0 R) + /-- A proof that `g` does not vanish on the closed ball. -/ + ne_zero : ∀ u ∈ (closedBall 0 R), g u ≠ 0 + /-- + A proof that `f` is equal, up to modification over a discrete set, to a product of `g`, canonical + factors prescribed by the divisor of `f`, and a factorized rational function with poles and zeros + only on the boundary of the ball. + -/ + eventuallyEq : f =ᶠ[codiscreteWithin (closedBall 0 R)] + ((∏ᶠ u, (canonicalFactor R u) ^ (-divisor f (ball 0 R) u)) + * (∏ᶠ v, (· - v) ^ (divisor f (sphere 0 R)) v)) • g + +/-- +**Extended canonical decomposition:** A meromorphic function on a closed disk is equal, up to +modification over a discrete set, to a product of a non-vanishing analytic function, canonical +factors and meromorphic functions of the form `(x - const) ^ n` where `const` is on the +circumference of the disk. +-/ +theorem _root_.MeromorphicOn.exists_ecanonicalDecomp (h₁f : MeromorphicOn f (closedBall 0 R)) + (h₂f : ∀ u : (closedBall (0 : ℂ) R), meromorphicOrderAt f u ≠ ⊤) : + ∃ h, ECanonicalDecomp f h R := by + rcases gt_trichotomy 0 R with hR | hR | hR + · use fun _ ↦ f 0 + exact { + meromorphicOn := by simp_all + analyticOnNhd := by simp_all + ne_zero := by simp_all + eventuallyEq := by + simp_all only [closedBall_of_neg] + filter_upwards [Filter.self_mem_codiscreteWithin ∅] with a ha + tauto + } + · use fun _ ↦ meromorphicTrailingCoeffAt f 0 + exact { + meromorphicOn := by simp_all + analyticOnNhd _ _ := by fun_prop + ne_zero := by + simp only [hR.symm, closedBall_zero, mem_singleton_iff, ne_eq, forall_eq] + apply MeromorphicAt.meromorphicTrailingCoeffAt_ne_zero (h₁f 0 _) _ + <;> simp_all + eventuallyEq := by + simp only [hR.symm, closedBall_zero] + apply subsingleton_singleton.mem_codiscreteWithin + } + obtain ⟨g, D⟩ := h₁f.exists_canonicalDecomp h₂f + have h₄g : ∀ (u : closedBall (0 : ℂ) R), meromorphicOrderAt g u ≠ ⊤ := by + rw [← D.meromorphicNFOn.meromorphicOn.exists_meromorphicOrderAt_ne_top_iff_forall + (Metric.isConnected_closedBall hR.le)] + have s₁ : (0 : ℂ) ∈ closedBall 0 R := by simp [hR.le] + use ⟨0, s₁⟩ + simp [(D.meromorphicNFOn s₁).meromorphicOrderAt_eq_zero_iff.2 (D.ne_zero 0 (by simp [hR]))] + obtain ⟨h, h₁h, h₂h, h₃h⟩ := D.meromorphicNFOn.meromorphicOn.extract_zeros_poles h₄g <| + (divisor g (closedBall 0 R)).finiteSupport <| isCompact_closedBall 0 R + use h + exact { + meromorphicOn := h₁f + analyticOnNhd := h₁h + ne_zero := (h₂h ⟨·, ·⟩) + eventuallyEq := by + filter_upwards [D.eventuallyEq, h₃h] with a h₁a h₂a + simp_rw [← D.divisor_eq_divisor hR] + simp_all [← smul_assoc] + } + end Complex diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 6a9e500b734003..6b7212902f7641 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -331,6 +331,16 @@ theorem codiscreteWithin_iff_locallyFiniteComplementWithin [T1Space X] {s U : Se use t \ (t ∩ (U \ s)), nhdsNE_of_nhdsNE_sdiff_finite (mem_nhdsWithin_of_mem_nhds h₁t) h₂t simp +/-- +In a `T1Space`, every set is codiscrete within a subsingleton set. +-/ +@[simp] theorem Set.Subsingleton.mem_codiscreteWithin [T1Space X] {s t : Set X} + (h : Set.Subsingleton t) : + s ∈ codiscreteWithin t := by + rw [codiscreteWithin_iff_locallyEmptyComplementWithin] + intro z hz + use univ \ t, nhdsNE_of_nhdsNE_sdiff_finite univ_mem h.finite, by aesop + /-- In a `T1Space`, complements of singleton sets are codiscrete within any set. -/ From ec463ea53bf8401dbfc1d9716f96fc2e0b39afa5 Mon Sep 17 00:00:00 2001 From: Suzuka Yu <109365723+Yu-Misaka@users.noreply.github.com> Date: Wed, 8 Jul 2026 06:04:10 +0000 Subject: [PATCH 0670/1300] feat(RepresentationTheory/Intertwining): a central element of the MonoidAlgebra acts on a representation as self-intertwining map (#41400) --- Mathlib/RepresentationTheory/Intertwining.lean | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Mathlib/RepresentationTheory/Intertwining.lean b/Mathlib/RepresentationTheory/Intertwining.lean index 5a7e62b4820e40..94b70397a40b47 100644 --- a/Mathlib/RepresentationTheory/Intertwining.lean +++ b/Mathlib/RepresentationTheory/Intertwining.lean @@ -592,6 +592,24 @@ def centralMul (g : G) (hg : g ∈ Submonoid.center G) : IntertwiningMap ρ ρ w toLinearMap := ρ g isIntertwining' x := LinearMap.ext <| (isIntertwiningMap_of_mem_center ρ g hg).isIntertwining x +/-- If `z` is a central element of the monoid algebra `A[G]`, then this is the action of `z`, + considered as an intertwining map from any representation of `G` to itself. -/ +noncomputable def centralAlgebraMul {z : A[G]} (hz : z ∈ Submonoid.center A[G]) : + ρ.IntertwiningMap ρ where + toLinearMap := ρ.asAlgebraHom z + isIntertwining' _ := by simp_rw [← ρ.asAlgebraHom_of, ← Module.End.mul_eq_comp, + ← map_mul, Submonoid.mem_center_iff.1 hz] + +@[simp] lemma centralAlgebraMul_apply {z : A[G]} (hz : z ∈ Submonoid.center A[G]) (v : V) : + centralAlgebraMul ρ hz v = ρ.asAlgebraHom z v := rfl + +/-- `centralAlgebraMul` as monoid homomorphism from the center of `A[G]` to intertwining map + from any representation of `G` to itself. -/ +@[simps] noncomputable def centralAlgebraMulHom : Submonoid.center A[G] →* ρ.IntertwiningMap ρ where + toFun z := centralAlgebraMul _ z.2 + map_one' := by ext; simp + map_mul' _ _ := by ext; simp + /-- `IntertwiningMap.toLinearMap` as a linear map. -/ @[simps] def toLinearMapl : IntertwiningMap ρ σ →ₗ[A] V →ₗ[A] W where toFun := toLinearMap From 812b9b69676b63b4d58aed90d400e56fa3a0b99d Mon Sep 17 00:00:00 2001 From: Yifan Bai <110049727+TTony2019@users.noreply.github.com> Date: Wed, 8 Jul 2026 06:21:37 +0000 Subject: [PATCH 0671/1300] feat(Analysis/Convex/Intrinsic): add product theorems for affine spans and intrinsic interiors (#38551) Add API for products of affine subspaces and proves product theorems for affine spans and intrinsic interiors. Co-authored-by: Zichen Wang --- .../Algebra/Group/Pointwise/Set/Basic.lean | 4 + Mathlib/Algebra/Torsor/Basic.lean | 20 +++++ Mathlib/Analysis/Convex/Intrinsic.lean | 10 +++ .../AffineSpace/AffineSubspace/Basic.lean | 73 ++++++++++++++++++- Mathlib/LinearAlgebra/Prod.lean | 7 ++ 5 files changed, 112 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean index 2a809154e412cf..28e4c96416321f 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean @@ -536,6 +536,10 @@ theorem inter_div_union_subset_union : s₁ ∩ s₂ / (t₁ ∪ t₂) ⊆ s₁ theorem union_div_inter_subset_union : (s₁ ∪ s₂) / (t₁ ∩ t₂) ⊆ s₁ / t₁ ∪ s₂ / t₂ := image2_union_inter_subset_union +@[to_additive (attr := simp) prod_sub_prod_comm] +lemma prod_div_prod_comm [Div β] (s₁ s₂ : Set α) (t₁ t₂ : Set β) : + (s₁ ×ˢ t₁) / (s₂ ×ˢ t₂) = (s₁ / s₂) ×ˢ (t₁ / t₂) := by aesop (add simp mem_div) + end Div -- TODO: rename `NPow` to `npow` and `ZPow` to `zpow`. diff --git a/Mathlib/Algebra/Torsor/Basic.lean b/Mathlib/Algebra/Torsor/Basic.lean index 87f77a9f44c433..4ae0002cd683e7 100644 --- a/Mathlib/Algebra/Torsor/Basic.lean +++ b/Mathlib/Algebra/Torsor/Basic.lean @@ -33,6 +33,15 @@ namespace Set theorem singleton_sdiv_self (p : P) : ({p} : Set P) /ₛ {p} = {(1 : G)} := by rw [Set.singleton_sdiv_singleton, sdiv_self] +@[to_additive (attr := simp)] +theorem one_mem_sdiv_iff {s t : Set P} : (1 : G) ∈ s /ₛ t ↔ ¬Disjoint s t := by + simp [not_disjoint_iff_nonempty_inter, mem_sdiv, Set.Nonempty] + +@[to_additive] +theorem Nonempty.one_mem_sdiv_self {s : Set P} (h : s.Nonempty) : (1 : G) ∈ s /ₛ s := + let ⟨p, hp⟩ := h + ⟨p, hp, p, hp, sdiv_self _⟩ + end Set /-- If dividing two points by the same point produces equal results, those points are equal. -/ @[to_additive /-- If the same point subtracted from two points produces equal @@ -160,6 +169,17 @@ theorem mk_sdiv_mk (p₁ p₂ : P) (p₁' p₂' : P') : end Prod +namespace Set + +variable {G G' P P' : Type*} [Group G] [Group G'] [Torsor G P] [Torsor G' P'] + +@[to_additive prod_vsub_prod_comm] +theorem prod_sdiv_prod_comm (s₁ s₂ : Set P) (t₁ t₂ : Set P') : + (s₁ ×ˢ t₁) /ₛ (s₂ ×ˢ t₂) = (s₁ /ₛ s₂) ×ˢ (t₁ /ₛ t₂) := by + aesop (add norm simp [mem_sdiv, mem_prod]) + +end Set + namespace Pi universe u v w diff --git a/Mathlib/Analysis/Convex/Intrinsic.lean b/Mathlib/Analysis/Convex/Intrinsic.lean index 9479339d6c71c4..6c1f2aabafd068 100644 --- a/Mathlib/Analysis/Convex/Intrinsic.lean +++ b/Mathlib/Analysis/Convex/Intrinsic.lean @@ -217,6 +217,16 @@ theorem intrinsicClosure_eq_closure_inter_affineSpan (s : Set P) : rw [Subtype.range_coe] apply subset_affineSpan +theorem intrinsicInterior_prod_eq [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace Q] + [AddTorsor W Q] (s : Set P) (t : Set Q) : + intrinsicInterior 𝕜 (s ×ˢ t) = intrinsicInterior 𝕜 s ×ˢ intrinsicInterior 𝕜 t := by + let e : affineSpan 𝕜 (s ×ˢ t) ≃ₜ affineSpan 𝕜 s × affineSpan 𝕜 t := + (Homeomorph.setCongr (by simp [affineSpan_prod_eq])).trans (Homeomorph.Set.prod _ _) + have : Subtype.val ∘ e.symm = fun p ↦ (p.1, p.2) := rfl + have h : ((↑) ⁻¹' (s ×ˢ t) : Set _) = e ⁻¹' (((↑) ⁻¹' s) ×ˢ ((↑) ⁻¹' t)) := rfl + simp_rw [intrinsicInterior, h, ← e.preimage_interior, interior_prod_eq, ← e.image_symm, + ← image_comp, prod_image_image_eq, this] + section ImageOfHomeomorphAffineSpan variable [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace Q] [AddTorsor W Q] diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index 70a3eb716f4769..9dd892ef26e3a1 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -815,8 +815,77 @@ namespace AffineSubspace open AffineEquiv -variable {k : Type*} {V : Type*} {P : Type*} [Ring k] [AddCommGroup V] [Module k V] -variable [AffineSpace V P] +variable {k V W P Q : Type*} [Ring k] [AddCommGroup V] [Module k V] [AffineSpace V P] + [AddCommGroup W] [Module k W] [AffineSpace W Q] + +/-- The product of two affine subspaces as an affine subspace. -/ +def prod (s : AffineSubspace k P) (t : AffineSubspace k Q) : AffineSubspace k (P × Q) where + carrier := (s : Set P) ×ˢ (t : Set Q) + smul_vsub_vadd_mem' c _ _ _ hp₁ hp₂ hp₃ := + ⟨s.smul_vsub_vadd_mem' c hp₁.1 hp₂.1 hp₃.1, t.smul_vsub_vadd_mem' c hp₁.2 hp₂.2 hp₃.2⟩ + +@[simp] +theorem coe_prod (s : AffineSubspace k P) (t : AffineSubspace k Q) : + (s.prod t : Set (P × Q)) = (s : Set P) ×ˢ (t : Set Q) := + rfl + +@[simp] +theorem mem_prod (s : AffineSubspace k P) (t : AffineSubspace k Q) (x : P × Q) : + x ∈ s.prod t ↔ x.1 ∈ s ∧ x.2 ∈ t := + Set.mem_prod + +@[gcongr] +theorem prod_mono {s₁ s₂ : AffineSubspace k P} {t₁ t₂ : AffineSubspace k Q} + (hs : s₁ ≤ s₂) (ht : t₁ ≤ t₂) : s₁.prod t₁ ≤ s₂.prod t₂ := + Set.prod_mono hs ht + +@[simp] +theorem prod_top_top : (⊤ : AffineSubspace k P).prod (⊤ : AffineSubspace k Q) = ⊤ := by + ext; simp + +@[simp] +theorem prod_bot_right (s : AffineSubspace k P) : s.prod (⊥ : AffineSubspace k Q) = ⊥ := by + simp [AffineSubspace.ext_iff] + +@[simp] +theorem prod_bot_left (t : AffineSubspace k P) : (⊥ : AffineSubspace k Q).prod t = ⊥ := by + simp [AffineSubspace.ext_iff] + +theorem prod_inf_prod (s₁ s₂ : AffineSubspace k P) (t₁ t₂ : AffineSubspace k Q) : + s₁.prod t₁ ⊓ s₂.prod t₂ = (s₁ ⊓ s₂).prod (t₁ ⊓ t₂) := + SetLike.coe_injective Set.prod_inter_prod + +theorem _root_.vectorSpan_prod_le (s : Set P) (t : Set Q) : + vectorSpan k (s ×ˢ t) ≤ (vectorSpan k s).prod (vectorSpan k t) := by + simpa [vectorSpan_def, Set.prod_vsub_prod_comm] using Submodule.span_prod_le (s -ᵥ s) (t -ᵥ t) + +theorem direction_prod_le (s : AffineSubspace k P) (t : AffineSubspace k Q) : + (s.prod t).direction ≤ s.direction.prod t.direction := by + simpa [direction_eq_vectorSpan, coe_prod] using vectorSpan_prod_le (s : Set P) (t : Set Q) + +theorem _root_.vectorSpan_prod_eq {s : Set P} {t : Set Q} (hs : s.Nonempty) (ht : t.Nonempty) : + vectorSpan k (s ×ˢ t) = (vectorSpan k s).prod (vectorSpan k t) := by + rw [vectorSpan_def, Set.prod_vsub_prod_comm] + exact Submodule.span_prod_eq k hs.zero_mem_vsub_self ht.zero_mem_vsub_self + +theorem direction_prod_eq {s : AffineSubspace k P} {t : AffineSubspace k Q} + (hs : s ≠ ⊥) (ht : t ≠ ⊥) : + (s.prod t).direction = s.direction.prod t.direction := by + simp [direction_eq_vectorSpan, vectorSpan_prod_eq, nonempty_iff_ne_bot, ht, hs] + +theorem _root_.affineSpan_prod_eq (s : Set P) (t : Set Q) : + affineSpan k (s ×ˢ t) = (affineSpan k s).prod (affineSpan k t) := by + rcases s.eq_empty_or_nonempty with rfl | hs + · simp + rcases t.eq_empty_or_nonempty with rfl | ht + · simp + apply AffineSubspace.ext_of_direction_eq + · simp [direction_prod_eq, Set.nonempty_iff_ne_empty.mp, hs, ht, direction_affineSpan, + vectorSpan_prod_eq] + · obtain ⟨x, hx⟩ := hs + obtain ⟨y, hy⟩ := ht + use ⟨x, y⟩ + simp [mem_affineSpan, hx, hy] /-- Two affine subspaces are parallel if one is related to the other by adding the same vector to all points. -/ diff --git a/Mathlib/LinearAlgebra/Prod.lean b/Mathlib/LinearAlgebra/Prod.lean index 67074813e619c5..d00e8164ac8be6 100644 --- a/Mathlib/LinearAlgebra/Prod.lean +++ b/Mathlib/LinearAlgebra/Prod.lean @@ -640,6 +640,13 @@ theorem prod_eq_top_iff {p₁ : Submodule R M} {p₂ : Submodule R M₂} : p₁.prod p₂ = ⊤ ↔ p₁ = ⊤ ∧ p₂ = ⊤ := by simp only [eq_top_iff, le_prod_iff, map_top, range_fst, range_snd] +variable {M M₂} in +theorem span_prod_eq {s : Set M} {t : Set M₂} (hs : 0 ∈ s) (ht : 0 ∈ t) : + span R (s ×ˢ t) = (span R s).prod (span R t) := by + refine le_antisymm (span_prod_le s t) ?_ + simp [Submodule.prod_le_iff, map_span] + grind [span_mono] + end Submodule namespace LinearEquiv From ae588ec23e9aa3650b8681914bc3e88754b3eaa1 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 8 Jul 2026 07:01:35 +0000 Subject: [PATCH 0672/1300] feat(Analysis/InnerProductSpace): generalized determinant of a rectangle matrix / linear map (#37295) This is the volume factor of a linear map --- Mathlib.lean | 1 + .../Analysis/InnerProductSpace/NormDet.lean | 441 ++++++++++++++++++ docs/references.bib | 34 ++ 3 files changed, 476 insertions(+) create mode 100644 Mathlib/Analysis/InnerProductSpace/NormDet.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8493722be7dc63..59670b0f0bd814 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2050,6 +2050,7 @@ public import Mathlib.Analysis.InnerProductSpace.LinearMap public import Mathlib.Analysis.InnerProductSpace.LinearPMap public import Mathlib.Analysis.InnerProductSpace.MeanErgodic public import Mathlib.Analysis.InnerProductSpace.MulOpposite +public import Mathlib.Analysis.InnerProductSpace.NormDet public import Mathlib.Analysis.InnerProductSpace.NormPow public import Mathlib.Analysis.InnerProductSpace.OfNorm public import Mathlib.Analysis.InnerProductSpace.Orientation diff --git a/Mathlib/Analysis/InnerProductSpace/NormDet.lean b/Mathlib/Analysis/InnerProductSpace/NormDet.lean new file mode 100644 index 00000000000000..4647f2e6431309 --- /dev/null +++ b/Mathlib/Analysis/InnerProductSpace/NormDet.lean @@ -0,0 +1,441 @@ +/- +Copyright (c) 2026 Weiyi Wang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Weiyi Wang +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.Adjoint +public import Mathlib.Analysis.InnerProductSpace.GramMatrix +public import Mathlib.Analysis.InnerProductSpace.SingularValues +public import Mathlib.Geometry.Euclidean.Volume.Measure + +import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar +import Mathlib.Topology.MetricSpace.HausdorffDimension + +/-! +# Norm determinant of a linear map + +Given a rectangular matrix $T$, it is common to talk about $\sqrt{det(T^{H}T)}$, where $T^{H}$ is +the conjugate transpose of $T$, as a generalization to the determinant of a square matrix. It is the +$m$-dimensional volume factor for linear maps $\mathbb{R}^m \to \mathbb{R}^n$. It is given various +names in the literature: +* "Jacobian" (definition 3.4 of [lawrenceronald2025]), in the context of volume factor + for a non-linear map. However, we choose to reserve this name for the matrix consisting of + derivatives. +* "Gram determinant", which is already used by `Matrix.gram`, and it is often referring to + $det(T^{H}T)$ without the square root. +* "Nonnegative determinant" (definition 1 of [haruoyoshiohidetoki2006]). + +Without a standardized name, we give a descriptive name `LinearMap.normDet` to reflect its +definition and show that it is a generalization of `‖(f : LinearMap 𝕜 U U).det‖` +(See `LinearMap.normDet_eq_norm_det`). We also construct this on linear maps between inner product +spaces instead of matrices, and allow the codomain to have infinite dimension. + +## Main definition +* `LinearMap.normDet` : the norm determinant of a linear map. + +## Main result +* `ContinuousLinearMap.normDet_sq` and `LinearMap.normDet_sq`: The square of `f.normDet` + equals to the determinant of `f.adjoint ∘ₗ f`. +* `LinearMap.normDet_sq_eq_det_gram`: The square of `LinearMap.normDet` equals to the determinant of + the Gram matrix formed by vectors mapped from an orthonormal basis. +* `LinearMap.normDet_eq_prod_singularValues`: `LinearMap.normDet` equals to the product of singular + values. +* `LinearMap.hausdorffMeasure_image`: `LinearMap.normDet` is the volume factor for Hausdorff + measure. + +-/ + +public section + +open Module + +namespace LinearMap + +variable {𝕜 U V W : Type*} [RCLike 𝕜] [NormedAddCommGroup U] [InnerProductSpace 𝕜 U] + [FiniteDimensional 𝕜 U] [NormedAddCommGroup V] [InnerProductSpace 𝕜 V] [NormedAddCommGroup W] + [InnerProductSpace 𝕜 W] + +open Classical in +/-- +The norm determinant of a linear map `f : U →ₗ[𝕜] V` is defined as the norm of the determinant of +the square matrix representing the linear map `U →ₗ[𝕜] f.range` over a pair of orthonormal basis of +equal dimensions. +(See `LinearMap.normDet_eq_norm_det_toMatrix_rangeRestrict` for using arbitrary orthonormal basis) + +If such basis doesn't exist (e.g. the map is not injective), the norm determinant is zero. +(See `LinearMap.normDet_eq_zero_iff_ker_ne_bot`) +-/ +noncomputable def normDet (f : U →ₗ[𝕜] V) : ℝ := + if h : Nonempty (OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 f.range) then + ‖(f.rangeRestrict.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis h.some.toBasis).det‖ + else + 0 + +theorem normDet_nonneg (f : U →ₗ[𝕜] V) : 0 ≤ f.normDet := by + unfold normDet + split <;> simp + +/-- +`LinearMap.normDet` is well-defined under any pair of orthonormal basis. +-/ +theorem normDet_eq_norm_det_toMatrix_rangeRestrict {ι : Type*} [Fintype ι] [DecidableEq ι] + (f : U →ₗ[𝕜] V) (bu : OrthonormalBasis ι 𝕜 U) (bv : OrthonormalBasis ι 𝕜 f.range) : + f.normDet = ‖(f.rangeRestrict.toMatrix bu.toBasis bv.toBasis).det‖ := by + have hrank : finrank 𝕜 U = finrank 𝕜 f.range := by + rw [finrank_eq_nat_card_basis bu.toBasis, finrank_eq_nat_card_basis bv.toBasis] + have h : Nonempty (OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 f.range) := by + rw [hrank] + exact ⟨stdOrthonormalBasis 𝕜 f.range⟩ + simp only [normDet, h, ↓reduceDIte] + rw [← basis_toMatrix_mul_linearMap_toMatrix_mul_basis_toMatrix (stdOrthonormalBasis 𝕜 U).toBasis + bu.toBasis h.some.toBasis bv.toBasis] + have h1 : bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis * + (stdOrthonormalBasis 𝕜 U).toBasis.toMatrix bu.toBasis = 1 := + Basis.toMatrix_mul_toMatrix_flip _ _ + have h2 : (stdOrthonormalBasis 𝕜 U).toBasis.toMatrix bu.toBasis * + bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis = 1 := + Basis.toMatrix_mul_toMatrix_flip _ _ + rw [← Matrix.det_comm' h1 h2, ← Matrix.mul_assoc, Matrix.det_mul, norm_mul] + suffices ‖(bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis * + h.some.toBasis.toMatrix ⇑bv.toBasis).det‖ = 1 by + rw [this, one_mul] + refine CStarRing.norm_of_mem_unitary <| Matrix.det_of_mem_unitary ?_ + rw [Matrix.mem_unitaryGroup_iff, Matrix.star_eq_conjTranspose, Matrix.conjTranspose_mul, + ← Matrix.mul_assoc, Matrix.mul_assoc (bu.toBasis.toMatrix (stdOrthonormalBasis 𝕜 U).toBasis)] + simp + +/-- +`LinearMap.normDet` vanishes iff the map is not injective. +-/ +theorem normDet_eq_zero_iff_ker_ne_bot {f : U →ₗ[𝕜] V} : + f.normDet = 0 ↔ f.ker ≠ ⊥ where + mp h := by + contrapose h + let g : U ≃ₗ[𝕜] f.range := LinearEquiv.ofBijective f.rangeRestrict + ⟨by simpa using ker_eq_bot.mp h, f.surjective_rangeRestrict⟩ + let bu := stdOrthonormalBasis 𝕜 U + let bv := g.finrank_eq.symm ▸ stdOrthonormalBasis 𝕜 f.range + rw [f.normDet_eq_norm_det_toMatrix_rangeRestrict bu bv, norm_eq_zero.not] + suffices (f.rangeRestrict.adjoint.toMatrix bv.toBasis bu.toBasis).det * + (f.rangeRestrict.toMatrix bu.toBasis bv.toBasis).det ≠ 0 by + simpa [toMatrix_adjoint, Matrix.det_conjTranspose] using this + simpa [← Matrix.det_mul, ← LinearMap.toMatrix_comp, det_eq_zero_iff_ker_ne_bot, + LinearMap.ker_adjoint_comp_self] using h + mpr h := by + suffices ¬ Nonempty (OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 f.range) by + simp [normDet, this] + contrapose h + obtain ⟨b⟩ := h + have hrank : finrank 𝕜 f.range = finrank 𝕜 U := by + simpa using finrank_eq_card_basis b.toBasis + simpa [hrank] using f.finrank_range_add_finrank_ker + +theorem normDet_eq_zero_iff_rank_range_ne {f : U →ₗ[𝕜] V} : + f.normDet = 0 ↔ finrank 𝕜 f.range ≠ finrank 𝕜 U := by + simp [normDet_eq_zero_iff_ker_ne_bot, ← f.finrank_range_add_finrank_ker] + +theorem normDet_ne_zero_tfae (f : U →ₗ[𝕜] V) : + List.TFAE [f.normDet ≠ 0, + f.ker = ⊥, + finrank 𝕜 f.range = finrank 𝕜 U, + Nonempty (OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 f.range), + Function.Injective f] := by + tfae_have 1 ↔ 2 := f.normDet_eq_zero_iff_ker_ne_bot.not_left + tfae_have 1 ↔ 3 := f.normDet_eq_zero_iff_rank_range_ne.not_left + tfae_have 3 → 4 := by + intro h + rw [← h] + exact ⟨stdOrthonormalBasis 𝕜 f.range⟩ + tfae_have 4 → 3 := by + rintro ⟨b⟩ + simpa using Module.finrank_eq_card_basis b.toBasis + tfae_have 2 ↔ 5 := ker_eq_bot + tfae_finish + +private noncomputable def orthonormalBasis_range {ι : Type*} [Fintype ι] {f : U →ₗ[𝕜] V} + (hf : f.ker = ⊥) (b : OrthonormalBasis ι 𝕜 U) : OrthonormalBasis ι 𝕜 f.range := + let h : Nonempty (OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 f.range) := + (f.normDet_ne_zero_tfae.out 1 3).mp hf + h.some.reindex (Fintype.equivFinOfCardEq <| (Module.finrank_eq_card_basis b.toBasis).symm).symm + +theorem normDet_eq_zero_tfae (f : U →ₗ[𝕜] V) : + List.TFAE [f.normDet = 0, + f.ker ≠ ⊥, + finrank 𝕜 f.range ≠ finrank 𝕜 U, + finrank 𝕜 f.range < finrank 𝕜 U, + IsEmpty (OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 f.range), + ¬Function.Injective f] := by + tfae_have 1 ↔ 2 := f.normDet_eq_zero_iff_ker_ne_bot + tfae_have 1 ↔ 3 := f.normDet_eq_zero_iff_rank_range_ne + tfae_have 3 ↔ 4 := by simpa using finrank_range_le f + tfae_have 3 ↔ 5 := by + have h := (f.normDet_ne_zero_tfae.out 2 3).not + simpa using h + tfae_have 2 ↔ 6 := ker_eq_bot.not + tfae_finish + +/-- +`LinearMap.normDet` can be calculated with any pair of orthonormal basis if the domain and the +codomain have equal dimension. +-/ +theorem normDet_eq_norm_det_toMatrix {ι : Type*} [Fintype ι] [DecidableEq ι] (f : U →ₗ[𝕜] V) + (bu : OrthonormalBasis ι 𝕜 U) (bv : OrthonormalBasis ι 𝕜 V) : + f.normDet = ‖(f.toMatrix bu.toBasis bv.toBasis).det‖ := by + have : FiniteDimensional 𝕜 V := bv.toBasis.finiteDimensional_of_finite + by_cases! hrank : finrank 𝕜 U = finrank 𝕜 f.range + · have h : f.range = ⊤ := by + apply Submodule.eq_of_le_of_finrank_le le_top + simp [finrank_eq_card_basis bv.toBasis, ← hrank, finrank_eq_card_basis bu.toBasis] + let bv' : OrthonormalBasis ι 𝕜 f.range := bv.map (LinearIsometryEquiv.ofTop _ _ h).symm + rw [f.normDet_eq_norm_det_toMatrix_rangeRestrict bu bv'] + rfl + · symm + rw [normDet_eq_zero_iff_rank_range_ne.mpr hrank.symm] + contrapose hrank with hdet + have h : IsUnit ((f.toMatrix bu.toBasis bv.toBasis).det) := by + simpa using hdet + let f' := LinearEquiv.ofIsUnitDet h + have hf : f.range = ⊤ := f'.range + rw [hf] + simpa using f'.finrank_eq + +/-- +`LinearMap.normDet` equals the norm of `LinearMap.det` for an endomorphism. +-/ +theorem normDet_eq_norm_det (f : U →ₗ[𝕜] U) : f.normDet = ‖f.det‖ := by + simp [f.normDet_eq_norm_det_toMatrix (stdOrthonormalBasis 𝕜 U) (stdOrthonormalBasis 𝕜 U)] + +/-- +`LinearMap.normDet` of a linear isometry is 1. +-/ +@[simp] +theorem _root_.LinearIsometry.normDet_eq_one (f : U →ₗᵢ[𝕜] V) : f.toLinearMap.normDet = 1 := by + obtain ⟨b⟩ := (f.normDet_ne_zero_tfae.out 4 3).mp f.injective + rw [normDet_eq_norm_det_toMatrix_rangeRestrict _ (stdOrthonormalBasis 𝕜 U) b] + apply CStarRing.norm_of_mem_unitary + exact Matrix.det_of_mem_unitary <| (f.equivRange).toMatrix_mem_unitaryGroup _ _ + +@[simp] +theorem normDet_id : (id : U →ₗ[𝕜] U).normDet = 1 := + LinearIsometry.id.normDet_eq_one + +@[simp] +theorem normDet_subtype (p : Submodule 𝕜 U) : p.subtype.normDet = 1 := + p.subtypeₗᵢ.normDet_eq_one + +@[simp] +theorem normDet_of_subsingleton [Subsingleton U] (f : U →ₗ[𝕜] V) : f.normDet = 1 := by + have h : f.ker = ⊥ := Submodule.eq_bot_of_subsingleton + have hrank : finrank 𝕜 U = 0 := finrank_zero_iff.mpr ‹_› + let bu : OrthonormalBasis (Fin 0) 𝕜 U := (stdOrthonormalBasis 𝕜 U).reindex (by rw [hrank]) + let bv := orthonormalBasis_range h bu + simp [normDet_eq_norm_det_toMatrix_rangeRestrict f bu bv] + +@[simp] +theorem normDet_zero : (0 : U →ₗ[𝕜] V).normDet = 0 ^ finrank 𝕜 U := by + nontriviality U + simp [zero_pow finrank_pos.ne.symm, normDet_eq_zero_iff_ker_ne_bot] + +@[simp] +theorem normDet_smul (f : U →ₗ[𝕜] V) (c : 𝕜) : + (c • f).normDet = ‖c‖ ^ finrank 𝕜 U * f.normDet := by + by_cases hc : c = 0 + · nontriviality U + simp [hc, zero_pow finrank_pos.ne.symm] + by_cases h : f.ker = ⊥ + · obtain ⟨bv⟩ := (f.normDet_ne_zero_tfae.out 1 3).mp h + let bu : OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 U := stdOrthonormalBasis 𝕜 U + let bv' : OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 (c • f).range := bv.map + (LinearIsometryEquiv.ofEq _ _ (LinearMap.range_smul _ _ hc).symm) + rw [f.normDet_eq_norm_det_toMatrix_rangeRestrict bu bv, + (c • f).normDet_eq_norm_det_toMatrix_rangeRestrict bu bv', ← norm_pow, ← norm_mul] + have : finrank 𝕜 U = Fintype.card (Fin (finrank 𝕜 U)) := by simp + conv in c ^ finrank 𝕜 U => rw [this] + rw [← Matrix.det_smul, ← map_smul] + rfl + · have h' : (c • f).ker ≠ ⊥ := by simpa [f.ker_smul _ hc] using h + simp [normDet_eq_zero_iff_ker_ne_bot.mpr h, normDet_eq_zero_iff_ker_ne_bot.mpr h'] + +@[simp] +theorem normDet_neg (f : U →ₗ[𝕜] V) : (-f).normDet = f.normDet := by + simpa using f.normDet_smul (-1) + +/-- +The square of `f.normDet` equals the determinant of `f.adjoint ∘L f`. +-/ +theorem _root_.ContinuousLinearMap.normDet_sq [CompleteSpace V] (f : U →L[𝕜] V) : + haveI : CompleteSpace U := FiniteDimensional.complete 𝕜 U + ↑(f.normDet ^ 2) = (f.adjoint ∘L f).det := by + have : CompleteSpace U := FiniteDimensional.complete 𝕜 U + have : CompleteSpace f.range := FiniteDimensional.complete 𝕜 f.range + let bu := stdOrthonormalBasis 𝕜 U + by_cases h : f.ker = ⊥ + · obtain ⟨b⟩ := (f.normDet_ne_zero_tfae.out 1 3).mp h + have hf : f = f.range.subtypeₗᵢ.toContinuousLinearMap ∘L f.rangeRestrict := rfl + conv_rhs => rw [hf] + rw [ContinuousLinearMap.adjoint_comp, ← ContinuousLinearMap.comp_assoc, + ContinuousLinearMap.comp_assoc (ContinuousLinearMap.adjoint _), + f.range.subtypeₗᵢ.adjoint_comp_self, ContinuousLinearMap.one_def, ContinuousLinearMap.comp_id, + ContinuousLinearMap.det, ContinuousLinearMap.toLinearMap_comp, ← det_toMatrix bu.toBasis, + toMatrix_comp bu.toBasis b.toBasis bu.toBasis, ← ContinuousLinearMap.adjoint_toLinearMap, + toMatrix_adjoint, f.toLinearMap.normDet_eq_norm_det_toMatrix_rangeRestrict bu b] + simp [RCLike.conj_mul] + · trans 0 + · simp [show f.normDet = 0 from (f.normDet_eq_zero_tfae.out 1 0).mp h] + symm + rw [det_eq_zero_iff_ker_ne_bot, ContinuousLinearMap.ker_adjoint_comp_self] + exact h + +/-- +The square of `f.normDet` equals the determinant of `f.adjoint ∘ₗ f` when the codomain is finite +dimensional. +-/ +theorem normDet_sq [FiniteDimensional 𝕜 V] (f : U →ₗ[𝕜] V) : + ↑(f.normDet ^ 2) = (f.adjoint ∘ₗ f).det := by + have : CompleteSpace V := FiniteDimensional.complete 𝕜 V + exact f.toContinuousLinearMap.normDet_sq + +/-- +The square of `f.normDet` equals the determinant of the Gram matrix formed by vectors mapped from +an orthonormal basis. +-/ +theorem normDet_sq_eq_det_gram {ι : Type*} [Fintype ι] [DecidableEq ι] (f : U →ₗ[𝕜] V) + (b : OrthonormalBasis ι 𝕜 U) : + ↑(f.normDet ^ 2) = (Matrix.gram 𝕜 (f <| b ·)).det := by + suffices ↑(f.normDet ^ 2) = (Matrix.gram 𝕜 (f.rangeRestrict <| b ·)).det by + simpa + by_cases h : f.ker = ⊥ + · let bv := orthonormalBasis_range h b + rw [Matrix.gram_eq_conjTranspose_mul bv, Matrix.det_mul, Matrix.det_conjTranspose] + rw [RCLike.star_def, RCLike.conj_mul, f.normDet_eq_norm_det_toMatrix_rangeRestrict b bv] + simp only [map_pow] + congr + ext i j + simp [LinearMap.toMatrix_apply] + · trans 0 + · simp [show f.normDet = 0 from (f.normDet_eq_zero_tfae.out 1 0).mp h] + have hrank := (f.normDet_eq_zero_tfae.out 1 3).mp h + symm + contrapose! hrank with h0 + rw [finrank_eq_card_basis b.toBasis] + exact (Matrix.linearIndependent_of_det_gram_ne_zero h0).fintype_card_le_finrank + +theorem normDet_comp (f : U →ₗ[𝕜] V) (g : V →ₗ[𝕜] W) : + (g ∘ₗ f).normDet = (g.domRestrict f.range).normDet * f.normDet := by + by_cases hf : f.ker = ⊥ + · let bu : OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 U := stdOrthonormalBasis 𝕜 U + obtain ⟨bv⟩ := (f.normDet_ne_zero_tfae.out 1 3).mp hf + by_cases hgf : (g ∘ₗ f).ker = ⊥ + · obtain ⟨bw⟩ := ((g ∘ₗ f).normDet_ne_zero_tfae.out 1 3).mp hgf + let bw' : OrthonormalBasis (Fin (finrank 𝕜 U)) 𝕜 (g.domRestrict f.range).range := + bw.map (LinearIsometryEquiv.ofEq _ _ (by simp [LinearMap.range_comp])) + rw [(g ∘ₗ f).normDet_eq_norm_det_toMatrix_rangeRestrict bu bw, + f.normDet_eq_norm_det_toMatrix_rangeRestrict bu bv, + (g.domRestrict f.range).normDet_eq_norm_det_toMatrix_rangeRestrict bv bw'] + rw [← norm_mul, ← Matrix.det_mul, ← LinearMap.toMatrix_comp] + rfl + · have hg : (g.domRestrict f.range).ker ≠ ⊥ := by + contrapose hf with hgf' + rw [← LinearMap.ker_rangeRestrict, ← LinearMap.ker_comp_of_ker_eq_bot _ hgf'] + exact hgf + simp [normDet_eq_zero_iff_ker_ne_bot.mpr hgf, normDet_eq_zero_iff_ker_ne_bot.mpr hg] + · have hgf : (g ∘ₗ f).ker ≠ ⊥ := by + contrapose hf with hbot + simpa [hbot] using ker_le_ker_comp f g + simp [normDet_eq_zero_iff_ker_ne_bot.mpr hf, normDet_eq_zero_iff_ker_ne_bot.mpr hgf] + +theorem normDet_comp_of_finrank_eq [FiniteDimensional 𝕜 V] (f : U →ₗ[𝕜] V) (g : V →ₗ[𝕜] W) + (h : finrank 𝕜 U = finrank 𝕜 V) : + (g ∘ₗ f).normDet = g.normDet * f.normDet := by + by_cases htop : f.range = ⊤ + · rw [normDet_comp] + congrm ?_ * _ + suffices (g.domRestrict f.range).normDet * (id : V →ₗ[𝕜] V).normDet = g.normDet by simpa + have : f.range = id.range := by simp [htop] + convert! (normDet_comp LinearMap.id g).symm + · have hker : f.ker ≠ ⊥ := by + simpa [ker_eq_bot_iff_range_eq_top_of_finrank_eq_finrank h] using htop + have hker' : (g ∘ₗ f).ker ≠ ⊥ := by + contrapose hker with hbot + simpa [hbot] using ker_le_ker_comp f g + simp [normDet_eq_zero_iff_ker_ne_bot.mpr hker, normDet_eq_zero_iff_ker_ne_bot.mpr hker'] + +@[simp] +theorem normDet_codRestrict {p : Submodule 𝕜 V} {f : U →ₗ[𝕜] V} (h : ∀ c, f c ∈ p) : + (f.codRestrict p h).normDet = f.normDet := by + have : f = p.subtype ∘ₗ f.codRestrict p h := rfl + conv_rhs => rw [this] + rw [normDet_comp] + have : (p.subtype.domRestrict (codRestrict p f h).range).normDet = 1 := + (p.subtypeₗᵢ.comp (codRestrict p f h).range.subtypeₗᵢ).normDet_eq_one + simp [this] + +theorem normDet_eq_prod_singularValues [FiniteDimensional 𝕜 V] (f : U →ₗ[𝕜] V) : + f.normDet = ∏ i ∈ Finset.range (finrank 𝕜 U), f.singularValues i := by + rw [← sq_eq_sq₀ f.normDet_nonneg (Finset.prod_nonneg fun i _ ↦ f.singularValues_nonneg i), + ← RCLike.ofReal_inj (K := 𝕜), ← Finset.prod_pow, ← Fin.prod_univ_eq_prod_range, normDet_sq] + simp_rw [sq_singularValues_fin] + push_cast + rw [← LinearMap.IsSymmetric.det_eq_prod_eigenvalues] + +section Real + +open MeasureTheory Measure + +variable {U V : Type*} [NormedAddCommGroup U] [InnerProductSpace ℝ U] [FiniteDimensional ℝ U] + [NormedAddCommGroup V] [InnerProductSpace ℝ V] + +theorem normDet_eq_abs_det (f : U →ₗ[ℝ] U) : f.normDet = |f.det| := by + simpa using f.normDet_eq_norm_det + +/-- +Using Hausdorff measure with the domain dimension, the volume of the image is scaled by +`LinearMap.normDet`. +-/ +theorem hausdorffMeasure_image [MeasurableSpace U] [BorelSpace U] [MeasurableSpace V] [BorelSpace V] + (f : U →ₗ[ℝ] V) (s : Set U) : + μH[finrank ℝ U] (f '' s) = ENNReal.ofReal f.normDet * μH[finrank ℝ U] s := by + by_cases h : f.ker = ⊥ + · have hrank : finrank ℝ ↥f.range = finrank ℝ U := (f.normDet_ne_zero_tfae.out 1 2).mp h + obtain ⟨bv⟩ := (f.normDet_ne_zero_tfae.out 1 3).mp h + let g : U ≃ₗᵢ[ℝ] f.range := (stdOrthonormalBasis ℝ U).equiv bv (Equiv.refl _) + suffices μH[finrank ℝ U] ((f.range.subtypeₗᵢ.comp g.toLinearIsometry) '' + ((g.symm.toLinearIsometry.toLinearMap ∘ₗ f.rangeRestrict) '' s)) = + ENNReal.ofReal f.normDet * μH[finrank ℝ U] s by + simpa [Set.image_image] + rw [(LinearIsometry.isometry _).hausdorffMeasure_image (by simp), + addHaar_image_linearMap μH[finrank ℝ U], ← normDet_eq_abs_det, + normDet_comp_of_finrank_eq _ _ hrank.symm, g.symm.toLinearIsometry.normDet_eq_one] + simp + · suffices μH[finrank ℝ U] (f.range.subtypeₗᵢ '' (f.rangeRestrict '' s)) = 0 by + simpa [(f.normDet_eq_zero_tfae.out 1 0).mp h, Set.image_image] + rw [(LinearIsometry.isometry _).hausdorffMeasure_image (by simp)] + have h : (finrank ℝ f.range : ℝ) < finrank ℝ U := by + exact_mod_cast (f.normDet_eq_zero_tfae.out 1 3).mp h + simp [Real.hausdorffMeasure_of_finrank_lt h] + +/-- +Using Euclidean Hausdorff measure with the domain dimension, the volume of the image is scaled by +`LinearMap.normDet`. +-/ +theorem euclideanHausdorffMeasure_image [MeasurableSpace U] [BorelSpace U] [MeasurableSpace V] + [BorelSpace V] (f : U →ₗ[ℝ] V) (s : Set U) : + μHE[finrank ℝ U] (f '' s) = ENNReal.ofReal f.normDet * μHE[finrank ℝ U] s := by + simp_rw [euclideanHausdorffMeasure_def, Measure.smul_apply, nnreal_smul_coe_apply, + hausdorffMeasure_image] + exact mul_left_comm _ _ _ + +/-- +The volume of the image measured by Euclidean Hausdorff measure is equal to the Lebesgue measure +scaled by `LinearMap.normDet`. +-/ +theorem euclideanHausdorffMeasure_image_eq_normDet_mul_volume [MeasurableSpace U] [BorelSpace U] + [MeasurableSpace V] [BorelSpace V] (f : U →ₗ[ℝ] V) (s : Set U) : + μHE[finrank ℝ U] (f '' s) = ENNReal.ofReal f.normDet * volume s := by + rw [f.euclideanHausdorffMeasure_image, InnerProductSpace.euclideanHausdorffMeasure_eq_volume] + +end Real + +end LinearMap diff --git a/docs/references.bib b/docs/references.bib index 9f5c0923881aa0..9597e32be3847f 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -2870,6 +2870,24 @@ @Book{ hartshorne61 mrreviewer = {F. Oort} } +@Article{ haruoyoshiohidetoki2006, + author = {Yanai, Haruo and Takane, Yoshio and Ishii, Hidetoki}, + title = {Nonnegative determinant of a rectangular matrix: {Its} + definition and applications to multivariate analysis}, + fjournal = {Linear Algebra and its Applications}, + journal = {Linear Algebra Appl.}, + issn = {0024-3795}, + volume = {417}, + number = {1}, + pages = {259--274}, + year = {2006}, + language = {English}, + doi = {10.1016/j.laa.2005.10.022}, + keywords = {15A15,62H20}, + zbmath = {5044090}, + zbl = {1105.15008} +} + @Book{ hatcher02, author = {Hatcher, Allen}, title = {Algebraic topology}, @@ -3738,6 +3756,22 @@ @Book{ laumon-morel-bailly-2000 mrnumber = {1771927} } +@Book{ lawrenceronald2025, + author = {Evans, Lawrence Craig and Gariepy, Ronald F.}, + title = {Measure theory and fine properties of functions}, + edition = {2nd edition}, + fseries = {Textbooks in Mathematics}, + series = {Textb. Math.}, + isbn = {978-1-032-94644-3; 978-1-003-58300-4}, + year = {2025}, + publisher = {Boca Raton, FL: CRC Press}, + language = {English}, + doi = {10.1201/9781003583004}, + keywords = {28-01,28A75,28A78,26B15,26B20,26B25}, + zbmath = {8010281}, + zbl = {1569.28001} +} + @Article{ lazarus1973, author = {Michel Lazarus}, title = {Les familles libres maximales d'un module ont-elles le From 7de2be8d1aa3d23b804c5932abc98ce2c700962e Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:03:31 +0000 Subject: [PATCH 0673/1300] chore: remove some unused instance arguments (#41470) Removes some unused instance arguments in private declarations. Found by leanprover-community/batteries#1831. Also uses `_` for intentionally unused arguments instead of setting the linter option, as this is respected by the `unusedArguments` linter as well. --- Mathlib/Analysis/Convex/Birkhoff.lean | 2 +- Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean | 3 +-- Mathlib/Combinatorics/Nullstellensatz.lean | 2 +- Mathlib/Data/W/Basic.lean | 3 +-- Mathlib/GroupTheory/FiniteAbelian/Duality.lean | 3 +-- Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean | 4 +--- Mathlib/InformationTheory/Coding/KraftMcMillan.lean | 3 +-- Mathlib/RingTheory/Etale/QuasiFinite.lean | 6 +++--- Mathlib/RingTheory/Extension/Presentation/Basic.lean | 3 +-- Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean | 3 +-- Mathlib/Tactic/Ring/Common.lean | 3 +-- 11 files changed, 13 insertions(+), 22 deletions(-) diff --git a/Mathlib/Analysis/Convex/Birkhoff.lean b/Mathlib/Analysis/Convex/Birkhoff.lean index 52c52d26adf950..50306eb9c6a471 100644 --- a/Mathlib/Analysis/Convex/Birkhoff.lean +++ b/Mathlib/Analysis/Convex/Birkhoff.lean @@ -48,7 +48,7 @@ variable [Semifield R] [LinearOrder R] [IsStrictOrderedRing R] {M : Matrix n n R If M is a positive scalar multiple of a doubly stochastic matrix, then there is a permutation matrix whose support is contained in the support of M. -/ -private lemma exists_perm_eq_zero_implies_eq_zero [Nonempty n] {s : R} (hs : 0 < s) +private lemma exists_perm_eq_zero_implies_eq_zero {s : R} (hs : 0 < s) (hM : ∃ M' ∈ doublyStochastic R n, M = s • M') : ∃ σ : Equiv.Perm n, ∀ i j, M i j = 0 → σ.permMatrix R i j = 0 := by rw [exists_mem_doublyStochastic_eq_smul_iff hs.le] at hM diff --git a/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean b/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean index ebbad741095003..0015ed2a201246 100644 --- a/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean +++ b/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean @@ -31,9 +31,8 @@ variable {ι : Type*} section prime variable {p : ℕ} [Fact p.Prime] {s : Finset ι} -set_option linter.unusedVariables false in /-- The first multivariate polynomial used in the proof of Erdős–Ginzburg–Ziv. -/ -private noncomputable def f₁ (s : Finset ι) (a : ι → ZMod p) : MvPolynomial s (ZMod p) := +private noncomputable def f₁ (s : Finset ι) (_a : ι → ZMod p) : MvPolynomial s (ZMod p) := ∑ i, X i ^ (p - 1) /-- The second multivariate polynomial used in the proof of Erdős–Ginzburg–Ziv. -/ diff --git a/Mathlib/Combinatorics/Nullstellensatz.lean b/Mathlib/Combinatorics/Nullstellensatz.lean index ab6494d1647864..22bb48f127226e 100644 --- a/Mathlib/Combinatorics/Nullstellensatz.lean +++ b/Mathlib/Combinatorics/Nullstellensatz.lean @@ -164,7 +164,7 @@ private theorem Alon.degree_P [Nontrivial R] (m : MonomialOrder σ) (S : Finset exact isRegular_one /-- The leading coefficient of `Alon.P S i` is `1`. -/ -private theorem Alon.monic_P [Nontrivial R] (m : MonomialOrder σ) (S : Finset R) (i : σ) : +private theorem Alon.monic_P (m : MonomialOrder σ) (S : Finset R) (i : σ) : m.Monic (P S i) := Monic.prod (fun r _ ↦ m.monic_X_sub_C i r) diff --git a/Mathlib/Data/W/Basic.lean b/Mathlib/Data/W/Basic.lean index 81c5d481441c4d..b55386b033176f 100644 --- a/Mathlib/Data/W/Basic.lean +++ b/Mathlib/Data/W/Basic.lean @@ -129,8 +129,7 @@ We define an auxiliary type `WType' β n` of trees of depth at most `n`, and the induction on `n` that these are all encodable. These auxiliary constructions are not interesting in and of themselves, so we mark them as `private`. -/ -private abbrev WType' {α : Type*} (β : α → Type*) [∀ a : α, Fintype (β a)] - [∀ a : α, Encodable (β a)] (n : ℕ) := +private abbrev WType' {α : Type*} (β : α → Type*) [∀ a : α, Fintype (β a)] (n : ℕ) := { t : WType β // t.depth ≤ n } variable [∀ a : α, Encodable (β a)] diff --git a/Mathlib/GroupTheory/FiniteAbelian/Duality.lean b/Mathlib/GroupTheory/FiniteAbelian/Duality.lean index cb0f5de5185b7b..901095e361002c 100644 --- a/Mathlib/GroupTheory/FiniteAbelian/Duality.lean +++ b/Mathlib/GroupTheory/FiniteAbelian/Duality.lean @@ -29,8 +29,7 @@ namespace CommGroup open MonoidHom -private -lemma dvd_exponent {ι G : Type*} [Finite ι] [Monoid G] {n : ι → ℕ} +private lemma dvd_exponent {ι G : Type*} [Monoid G] {n : ι → ℕ} (e : G ≃* ((i : ι) → Multiplicative (ZMod (n i)))) (i : ι) : n i ∣ Monoid.exponent G := by classical -- to get `DecidableEq ι` diff --git a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean index cdd0050b96e0d8..7f97a7643abb32 100644 --- a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean +++ b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean @@ -268,9 +268,7 @@ end SpanningTree set_option backward.privateInPublic true in /-- Another name for the identity function `G → G`, to help type checking. -/ -private def symgen {G : Type u} [Groupoid.{v} G] [IsFreeGroupoid G] : - G → Symmetrify (Generators G) := - id +private def symgen {G : Type u} [Groupoid.{v} G] : G → Symmetrify (Generators G) := id set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in diff --git a/Mathlib/InformationTheory/Coding/KraftMcMillan.lean b/Mathlib/InformationTheory/Coding/KraftMcMillan.lean index 895f3520fb1ad9..e960a8b2de9898 100644 --- a/Mathlib/InformationTheory/Coding/KraftMcMillan.lean +++ b/Mathlib/InformationTheory/Coding/KraftMcMillan.lean @@ -65,8 +65,7 @@ private lemma concatFn_injective_of_uniquelyDecodable {S : Finset (List α)} have := List.ofFn_injective (h _ _ (by simp) (by simp) hflat) exact Subtype.ext (congrArg (fun f => f i) this) -private lemma sum_pow_length_filter_eq_le_card_mul [Fintype α] [Nonempty α] - {T : Finset (List α)} {s : ℕ} : +private lemma sum_pow_length_filter_eq_le_card_mul [Fintype α] {T : Finset (List α)} {s : ℕ} : (∑ x ∈ T.filter (fun x => x.length = s), (1 / (Fintype.card α : ℝ)) ^ x.length) ≤ ((Fintype.card α) ^ s) * (1 / Fintype.card α) ^ s := by calc diff --git a/Mathlib/RingTheory/Etale/QuasiFinite.lean b/Mathlib/RingTheory/Etale/QuasiFinite.lean index 58240404b83dde..cfeb0d8b82fcf4 100644 --- a/Mathlib/RingTheory/Etale/QuasiFinite.lean +++ b/Mathlib/RingTheory/Etale/QuasiFinite.lean @@ -447,9 +447,9 @@ attribute [local instance] Localization.AtPrime.algebraOfLiesOver /-- A key induction step of `exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq`. -/ private theorem Algebra.exists_etale_completeOrthogonalIdempotents_forall_liesOver_eq_aux - {R : Type u} {S : Type (max u v)} [CommRing R] [CommRing S] [Algebra R S] [Module.Finite R S] - (p : Ideal R) [p.IsPrime] (q : Ideal S) [q.IsPrime] - [q.LiesOver p] (R' : Type u) [CommRing R'] [Algebra R R'] [Algebra.Etale R R'] (P : Ideal R') + {R : Type u} {S : Type (max u v)} [CommRing R] [CommRing S] [Algebra R S] + (p : Ideal R) [p.IsPrime] (q : Ideal S) + (R' : Type u) [CommRing R'] [Algebra R R'] [Algebra.Etale R R'] (P : Ideal R') [P.IsPrime] [P.LiesOver p] (e : R' ⊗[R] S) (P' : Ideal (R' ⊗[R] S)) [P'.IsPrime] [P'.LiesOver P] (hP'q : Ideal.comap Algebra.TensorProduct.includeRight.toRingHom P' = q) diff --git a/Mathlib/RingTheory/Extension/Presentation/Basic.lean b/Mathlib/RingTheory/Extension/Presentation/Basic.lean index 31e8ad3fdba6af..5dc88a6f3a2fbf 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Basic.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Basic.lean @@ -341,10 +341,9 @@ assumption this span is the kernel of the evaluation map of `P`. For this, we us variable {ι' σ' T : Type*} [CommRing T] [Algebra S T] variable (Q : Presentation S T ι' σ') (P : Presentation R S ι σ) -set_option linter.unusedVariables false in /-- The evaluation map `MvPolynomial (ι' ⊕ ι) →ₐ[R] T` factors via this map. For more details, see the module docstring at the beginning of the section. -/ -private noncomputable def aux (Q : Presentation S T ι' σ') (P : Presentation R S ι σ) : +private noncomputable def aux (_Q : Presentation S T ι' σ') (P : Presentation R S ι σ) : MvPolynomial (ι' ⊕ ι) R →ₐ[R] MvPolynomial ι' S := aeval (Sum.elim X (MvPolynomial.C ∘ P.val)) diff --git a/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean b/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean index 5edcaaf1e0b975..758b10169ca3d5 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean @@ -158,8 +158,7 @@ set_option backward.privateInPublic true in variable (R₀ R n e) in /-- The statement we induct on in the `C : R → R[X]` case of Chevalley's theorem with complexity bound. -/ -private def Statement [Algebra ℤ R] : Prop := - ∀ f : R[X], ∃ T : ConstructibleSetData R, +private def Statement : Prop := ∀ f : R[X], ∃ T : ConstructibleSetData R, comap Polynomial.C '' (zeroLocus (Set.range e) \ zeroLocus {f}) = T.toSet ∧ ∀ C ∈ T, C.n ≤ e.degBound ∧ ∀ i, C.g i ∈ e.coeffSubmodule R₀ ^ e.powBound diff --git a/Mathlib/Tactic/Ring/Common.lean b/Mathlib/Tactic/Ring/Common.lean index 868611fdfd5cc9..996a6a91af732a 100644 --- a/Mathlib/Tactic/Ring/Common.lean +++ b/Mathlib/Tactic/Ring/Common.lean @@ -900,8 +900,7 @@ theorem mul_pow_mul {ea₁ b c₁ : ℕ} {xa₁ c₃ d : R} (_ : ea₁ * b = c subst_vars; simp [_root_.mul_pow, pow_mul, Nat.rawCast] -- needed to lift from `OptionT CoreM` to `OptionT MetaM` -private local instance {m m'} [Monad m] [Monad m'] [MonadLiftT m m'] : - MonadLiftT (OptionT m) (OptionT m') where +private local instance {m m'} [MonadLiftT m m'] : MonadLiftT (OptionT m) (OptionT m') where monadLift x := OptionT.mk x.run /-- There are several special cases when exponentiating monomials: From 18c9c7d81bf3472541c9fb27656ae6a10461e6da Mon Sep 17 00:00:00 2001 From: Brian Nugent Date: Wed, 8 Jul 2026 08:44:16 +0000 Subject: [PATCH 0674/1300] chore(Topology): refactor TopologicalSpace.Opens.map to use OrderHom.toFunctor (#39991) Co-authored-by: Brian-Nugent --- .../Geometry/RingedSpace/OpenImmersion.lean | 20 +++++++++---------- .../RingedSpace/PresheafedSpace/Gluing.lean | 2 +- Mathlib/Topology/Category/TopCat/Opens.lean | 17 +++++++++++++--- Mathlib/Topology/Sheaves/Presheaf.lean | 4 ++-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 15acb42928814d..0d6bdc89118317 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -122,7 +122,7 @@ noncomputable def isoRestrict : X ≅ Y.restrict H.base_open := refine asIso (f.c.app (op (opensFunctor f |>.obj (unop U)))) ≪≫ X.presheaf.mapIso (eqToIso ?_) induction U with | op U => ?_ cases U - dsimp only [IsOpenMap.functor, Functor.op, Opens.map] + dsimp only [IsOpenMap.functor, Functor.op, Opens.map_def] congr 2 erw [Set.preimage_image_eq _ H.base_open.injective] rfl @@ -178,8 +178,8 @@ set_option backward.isDefEq.respectTransparency false in /-- For an open immersion `f : X ⟶ Y` and an open set `U ⊆ X`, we have the map `X(U) ⟶ Y(U)`. -/ noncomputable def invApp (U : Opens X) : X.presheaf.obj (op U) ⟶ Y.presheaf.obj (op (opensFunctor f |>.obj U)) := - X.presheaf.map (eqToHom (by simp [Opens.map, Set.preimage_image_eq _ H.base_open.injective])) ≫ - inv (f.c.app (op (opensFunctor f |>.obj U))) + X.presheaf.map (eqToHom (by simp [Opens.map_def, Set.preimage_image_eq _ H.base_open.injective])) + ≫ inv (f.c.app (op (opensFunctor f |>.obj U))) set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @@ -201,7 +201,7 @@ theorem inv_invApp (U : Opens X) : inv (H.invApp _ U) = f.c.app (op (opensFunctor f |>.obj U)) ≫ X.presheaf.map - (eqToHom (by simp [Opens.map, Set.preimage_image_eq _ H.base_open.injective])) := by + (eqToHom (by simp [Opens.map_def, Set.preimage_image_eq _ H.base_open.injective])) := by rw [← cancel_epi (H.invApp _ U), IsIso.hom_inv_id] delta invApp simp [← Functor.map_comp] @@ -210,7 +210,7 @@ set_option backward.isDefEq.respectTransparency false in @[simp, reassoc, elementwise] theorem invApp_app (U : Opens X) : invApp f U ≫ f.c.app (op (opensFunctor f |>.obj U)) = X.presheaf.map - (eqToHom (by simp [Opens.map, Set.preimage_image_eq _ H.base_open.injective])) := by + (eqToHom (by simp [Opens.map_def, Set.preimage_image_eq _ H.base_open.injective])) := by rw [invApp, Category.assoc, IsIso.inv_hom_id, Category.comp_id] set_option backward.isDefEq.respectTransparency false in @@ -380,7 +380,7 @@ def pullbackConeOfLeftLift : s.pt ⟶ (pullbackConeOfLeft f g).pt where s.pt.presheaf.map (eqToHom (by - dsimp only [Opens.map, IsOpenMap.functor, Functor.op] + dsimp only [Opens.map_def, IsOpenMap.functor, Functor.op] congr 2 let s' : PullbackCone f.base g.base := PullbackCone.mk s.fst.base s.snd.base (congr_arg Hom.base s.condition) @@ -822,13 +822,13 @@ instance (U : Opens X) : IsIso (H.invApp _ U) := by delta invApp; infer_instance theorem inv_invApp (U : Opens X) : inv (H.invApp _ U) = f.hom.c.app (op (opensFunctor f |>.obj U)) ≫ X.presheaf.map - (eqToHom (by simp [Opens.map, Set.preimage_image_eq _ H.base_open.injective])) := + (eqToHom (by simp [Opens.map_def, Set.preimage_image_eq _ H.base_open.injective])) := PresheafedSpace.IsOpenImmersion.inv_invApp f.hom U @[reassoc (attr := simp)] theorem invApp_app (U : Opens X) : H.invApp _ U ≫ f.hom.c.app (op (opensFunctor f |>.obj U)) = X.presheaf.map - (eqToHom (by simp [Opens.map, Set.preimage_image_eq _ H.base_open.injective])) := + (eqToHom (by simp [Opens.map_def, Set.preimage_image_eq _ H.base_open.injective])) := PresheafedSpace.IsOpenImmersion.invApp_app f.hom U attribute [elementwise] invApp_app @@ -1242,7 +1242,7 @@ theorem inv_invApp (U : Opens X) : (eqToHom (by have := Set.preimage_image_eq U.1 H.base_open.injective dsimp at this - simp [Opens.map, this])) := + simp [Opens.map_def, this])) := PresheafedSpace.IsOpenImmersion.inv_invApp f.1 U set_option backward.defeqAttrib.useBackward true in @@ -1253,7 +1253,7 @@ theorem invApp_app (U : Opens X) : (eqToHom (by have := Set.preimage_image_eq U.1 H.base_open.injective dsimp at this - simp [Opens.map, this])) := + simp [Opens.map_def, this])) := PresheafedSpace.IsOpenImmersion.invApp_app f.1 U attribute [elementwise nosimp] invApp_app diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean index 9f8d7b72bc12d0..5a2d28638f84f4 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean @@ -180,7 +180,7 @@ theorem snd_invApp_t_app' (i j k : D.J) (U : Opens (pullback (D.f i j) (D.f i k) fconstructor -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq` · delta IsOpenImmersion.opensFunctor IsOpenEmbedding.functor - dsimp only [Functor.op, Opens.map, IsOpenMap.functor, unop_op, Opens.coe_mk] + dsimp only [Functor.op, Opens.map_def, IsOpenMap.functor, unop_op, Opens.coe_mk] congr 2 have := (𝖣.t_fac k i j).symm rw [← IsIso.inv_comp_eq] at this diff --git a/Mathlib/Topology/Category/TopCat/Opens.lean b/Mathlib/Topology/Category/TopCat/Opens.lean index 96f6645978055a..903bdd670ef086 100644 --- a/Mathlib/Topology/Category/TopCat/Opens.lean +++ b/Mathlib/Topology/Category/TopCat/Opens.lean @@ -146,11 +146,22 @@ def inclusionTopIso (X : TopCat.{u}) : (toTopCat X).obj ⊤ ≅ X where hom := inclusion' ⊤ inv := TopCat.ofHom ⟨fun x => ⟨x, trivial⟩, continuous_def.2 fun _ ⟨_, hS, hSU⟩ => hSU ▸ hS⟩ +/-- The FrameHom sending an open in `Y` to its preimage in `X` -/ +@[simps] +def _root_.TopCat.Hom.frameHom (f : X ⟶ Y) : FrameHom (Opens Y) (Opens X) where + toFun U := ⟨f ⁻¹' (U : Set Y), U.isOpen.preimage f.hom.continuous⟩ + map_inf' _ _ := rfl + map_top' := rfl + map_sSup' _ := by ext; simp + /-- `Opens.map f` gives the functor from open sets in Y to open set in X, given by taking preimages under f. -/ -def map (f : X ⟶ Y) : Opens Y ⥤ Opens X where - obj U := ⟨f ⁻¹' (U : Set Y), U.isOpen.preimage f.hom.continuous⟩ - map i := ⟨⟨fun _ h => i.le h⟩⟩ +def map (f : X ⟶ Y) : Opens Y ⥤ Opens X := + (OrderHomClass.toOrderHom f.frameHom).toFunctor + +lemma map_def (f : X ⟶ Y) : map f = + { obj U := ⟨f ⁻¹' (U : Set Y), U.isOpen.preimage f.hom.continuous⟩ + map i := ⟨⟨fun _ h => i.le h⟩⟩ } := rfl @[simp] theorem map_coe (f : X ⟶ Y) (U : Opens Y) : ((map f).obj U : Set X) = f ⁻¹' (U : Set Y) := diff --git a/Mathlib/Topology/Sheaves/Presheaf.lean b/Mathlib/Topology/Sheaves/Presheaf.lean index 9d0ac759394de3..c86168c5c462b1 100644 --- a/Mathlib/Topology/Sheaves/Presheaf.lean +++ b/Mathlib/Topology/Sheaves/Presheaf.lean @@ -246,7 +246,7 @@ set_option backward.defeqAttrib.useBackward true in theorem toPushforwardOfIso_app {X Y : TopCat.{w}} (H₁ : X ≅ Y) {ℱ : X.Presheaf C} {𝒢 : Y.Presheaf C} (H₂ : H₁.hom _* ℱ ⟶ 𝒢) (U : (Opens X)ᵒᵖ) : (toPushforwardOfIso H₁ H₂).app U = - ℱ.map (eqToHom (by simp [Opens.map, Set.preimage_preimage])) ≫ + ℱ.map (eqToHom (by simp [Opens.map_def, Set.preimage_preimage])) ≫ H₂.app (op ((Opens.map H₁.inv).obj (unop U))) := by simp [toPushforwardOfIso, Adjunction.homEquiv_unit] @@ -263,7 +263,7 @@ theorem pushforwardToOfIso_app {X Y : TopCat.{w}} (H₁ : X ≅ Y) {ℱ : Y.Pres (H₂ : ℱ ⟶ H₁.hom _* 𝒢) (U : (Opens X)ᵒᵖ) : (pushforwardToOfIso H₁ H₂).app U = H₂.app (op ((Opens.map H₁.inv).obj (unop U))) ≫ - 𝒢.map (eqToHom (by simp [Opens.map, Set.preimage_preimage])) := by + 𝒢.map (eqToHom (by simp [Opens.map_def, Set.preimage_preimage])) := by simp [pushforwardToOfIso, Equivalence.toAdjunction, Adjunction.homEquiv_counit] end Iso From ff4ee7173b661481dbafaf34494d0fae4877aa55 Mon Sep 17 00:00:00 2001 From: Michael Stoll <99838730+MichaelStollBayreuth@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:44:18 +0000 Subject: [PATCH 0675/1300] feat(GroupTheory/Descent): add versions showing finiteness of torsion (#41439) This adds results showing that the torsion subgroup of an (additive) commutative group is finite when it admits a height function with certain properties (weaker than needed to show finite generation). Once the approximate parallelogram law on elliptic curves is in, this will give a proof that the torsion subgroup of the group of `K`-rational points on an elliptic curve over a number field `K` is finite. --- Mathlib/GroupTheory/Descent.lean | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/Mathlib/GroupTheory/Descent.lean b/Mathlib/GroupTheory/Descent.lean index 340f0f360c29c2..6e7e89947fc24d 100644 --- a/Mathlib/GroupTheory/Descent.lean +++ b/Mathlib/GroupTheory/Descent.lean @@ -8,8 +8,11 @@ module public import Mathlib.Data.Real.Basic public import Mathlib.GroupTheory.Finiteness public import Mathlib.GroupTheory.Index +public import Mathlib.GroupTheory.Torsion public import Mathlib.Order.Northcott +import Mathlib.Algebra.Order.Archimedean.Real.Basic +import Mathlib.Data.Fintype.Order import Mathlib.Data.Set.Finite.Lemmas import Mathlib.Tactic.FieldSimp import Mathlib.Tactic.Linarith @@ -43,6 +46,8 @@ This last version is one of the main ingredients of the standard proof of the **Mordell-Weil Theorem**. It allows to reduce the statement to showing that `G / 2 • G` is finite (where `G` is the Mordell-Weil group). +We also provide versions that prove that the torsion subgroup is finite under weaker assumptions. + ### Implementation note Replacing `ℝ` by an ordered field (`{R : Type*} [LinearOrder R] [Field R] [IsOrderedRing R]`) @@ -150,4 +155,65 @@ theorem CommGroup.fg_of_descent' {G : Type*} [CommGroup G] {h : G → ℝ} {C : have H₂' g x : h x ≤ 2 * h (g * x) + (2 * h g⁻¹ + C) := by grind [mul_inv_cancel_comm] exact fg_of_descent (b := 4) (by norm_num) (by norm_num) H₁ H₂' H₃' +/-- +If `M` is a monoid and `n : ℕ`, `h : M → ℝ` satisfy +* for all `M : G`, `h (x ^ n) ≥ b * h x - c₀`, +* for all `B : ℝ`, there are only finitely many `x : M` such that `h x ≤ B`, + +where `1 < b` and `c₀` are real numbers, then the set of elements of finite order in `M` is finite. +-/ +@[to_additive /-- If `M` is an additive monoid and `n : ℕ`, `h : M → ℝ` satisfy +* for all `x : M`, `h (n • x) ≥ b * h x - c₀`, +* for all `B : ℝ`, there are only finitely many `x : M` such that `h x ≤ B`, + +where `1 < b` and `c₀` are real numbers, then the set of elements of finite order in `M` +is finite. -/] +theorem Monoid.finite_set_isOfFiniteOrder_of_descent {M : Type*} [Monoid M] {n : ℕ} {h : M → ℝ} + {b c₀ : ℝ} (hb : 1 < b) (H : ∀ x, b * h x - c₀ ≤ h (x ^ n)) [Northcott h] : + Finite { x : M | IsOfFinOrder x } := by + refine (Northcott.finite_le (h := h) (c₀ / (b - 1))).subset fun t ht ↦ ?_ + have : Finite ↥(Submonoid.powers t) := ht.finite_powers + let C : ℝ := ⨆ g : Submonoid.powers t, h g + have hC : ∀ g ∈ Submonoid.powers t, h g ≤ C := + fun g hg ↦ Finite.le_ciSup (fun g : Submonoid.powers t ↦ h g) ⟨g, hg⟩ + refine (hC t (Submonoid.mem_powers t)).trans ?_ + obtain ⟨t₀, ht₀⟩ : ∃ g : Submonoid.powers t, h g = C := exists_eq_ciSup_of_finite + rw [le_div_iff₀' (by grind)] + grind [Submonoid.pow_mem] + +/-- +If `G` is a commutative group and `n : ℕ`, `h : G → ℝ` satisfy +* for all `x : G`, `h (x ^ n) ≥ b * h x - c₀`, +* for all `B : ℝ`, there are only finitely many `x : G` such that `h x ≤ B`, + +where `1 < b` and `c₀` are real numbers, then the torsion subgroup of `G` is finite. +-/ +@[to_additive /-- If `G` is a commutative additive group and `n : ℕ`, `h : G → ℝ` satisfy +* for all `x : G`, `h (n • x) ≥ b * h x - c₀`, +* for all `B : ℝ`, there are only finitely many `x : G` such that `h x ≤ B`, + +where `1 < b` and `c₀` are real numbers, then the torsion subgroup of `G` is finite. -/] +theorem CommGroup.finite_torsion_of_descent {G : Type*} [CommGroup G] {n : ℕ} {h : G → ℝ} + {b c₀ : ℝ} (hb : 1 < b) (H : ∀ x, b * h x - c₀ ≤ h (x ^ n)) [Northcott h] : + Finite (torsion G) := + Monoid.finite_set_isOfFiniteOrder_of_descent hb H + +/-- +If `G` is a commutative group and `n : ℕ`, `h : G → ℝ` satisfy +* there is `C : ℝ` such that for all `x y : G`, `|h (x * y) + h(x / y) - 2 * (h x + h y)| ≤ C`, +* for all `B : ℝ`, there are only finitely many `x : G` such that `h x ≤ B`, + +then the torsion subgroup of `G` is finite. +-/ +@[to_additive /-- If `G` is a commutative additive group and `n : ℕ`, `h : G → ℝ` satisfy +* there is `C : ℝ` such that for all `x y : G`, `|h (x + y) + h(x - y) - 2 * (h x + h y)| ≤ C`, +* for all `B : ℝ`, there are only finitely many `x : G` such that `h x ≤ B`, + +then the torsion subgroup of `G` is finite. -/] +theorem CommGroup.finite_torsion_of_descent' {G : Type*} [CommGroup G] {h : G → ℝ} {C : ℝ} + (H : ∀ x y, |h (x * y) + h (x / y) - 2 * (h x + h y)| ≤ C) [Northcott h] : + Finite (torsion G) := by + have H' x : 4 * h x - (h 1 + C) ≤ h (x ^ 2) := by grind [pow_two, div_self'] + exact finite_torsion_of_descent (b := 4) (by norm_num) H' + end From 569217d9aaaeb38898b192dd754a9222fcd1fc23 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:44:20 +0000 Subject: [PATCH 0676/1300] feat(Analysis/SpecialFunctions/ImproperIntegrals): fix typo (#41480) An underscore was left out of the name of a recently merged theorem by mistake; this PR restores that underscore. Co-authored-by: Terence Tao --- Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean b/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean index 5c5996c9bbff38..e3900fef798c67 100644 --- a/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean +++ b/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean @@ -301,7 +301,7 @@ theorem integrableOn_inv_div_log_sq_Ioi {c : ℝ} (hc : 1 < c) : positivity @[simp] -theorem integral_inv_divlog_sq_Ioi {c : ℝ} (hc : 1 < c) : +theorem integral_inv_div_log_sq_Ioi {c : ℝ} (hc : 1 < c) : ∫ (t : ℝ) in .Ioi c, t⁻¹ / (log t) ^ 2 = (log c)⁻¹ := by convert! integral_Ioi_of_hasDerivAt_of_tendsto' (m := 0) (f := fun t ↦ -(log t)⁻¹) ?_ (integrableOn_inv_div_log_sq_Ioi hc) ?_ using 1 From 92cc40faf55f1aaf6fa170c53972416d367fdaf5 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:44:22 +0000 Subject: [PATCH 0677/1300] chore(Condensed/Discrete/Module): specify free universe variable explicitly (#41483) This is beneficial for the same reasons as #40964. This particular change matters for #41462; extracted from that PR. Co-authored-by: felixpernegger <188575194+felixpernegger@users.noreply.github.com> --- Mathlib/Condensed/Discrete/Module.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Condensed/Discrete/Module.lean b/Mathlib/Condensed/Discrete/Module.lean index f6766356f6d83c..b3ba358aa6b01b 100644 --- a/Mathlib/Condensed/Discrete/Module.lean +++ b/Mathlib/Condensed/Discrete/Module.lean @@ -154,13 +154,13 @@ instance : (functor R).Full := (fullyFaithfulFunctor R).full instance : (discrete (ModuleCat R)).Faithful := Functor.Faithful.of_iso (functorIsoDiscrete R) -instance : (constantSheaf (coherentTopology CompHaus) (ModuleCat R)).Faithful := +instance : (constantSheaf (coherentTopology CompHaus) (ModuleCat.{u + 1} R)).Faithful := inferInstanceAs (discrete (ModuleCat R)).Faithful instance : (discrete (ModuleCat R)).Full := Functor.Full.of_iso (functorIsoDiscrete R) -instance : (constantSheaf (coherentTopology CompHaus) (ModuleCat R)).Full := +instance : (constantSheaf (coherentTopology CompHaus) (ModuleCat.{u + 1} R)).Full := inferInstanceAs (discrete (ModuleCat R)).Full instance : (constantSheaf (coherentTopology CompHaus) (Type (u + 1))).Faithful := From 27c42f4d5c7ffd17db2878eb1b996aedb05df766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 8 Jul 2026 08:56:47 +0000 Subject: [PATCH 0678/1300] chore(Algebra/SkewMonoidAlgebra): rename the conversion functions to `coeff`/`ofCoeff` (#41365) --- Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean | 334 ++++++++++-------- Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean | 19 +- Mathlib/Algebra/SkewMonoidAlgebra/Single.lean | 40 +-- .../Algebra/SkewMonoidAlgebra/Support.lean | 4 +- Mathlib/Algebra/SkewPolynomial/Basic.lean | 28 +- 5 files changed, 220 insertions(+), 205 deletions(-) diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean index ca290e8eb3c320..55c81676972ae1 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean @@ -38,21 +38,26 @@ noncomputable section combinations of terms of `G`, endowed with a skewed convolution product. -/ structure SkewMonoidAlgebra (k : Type*) (G : Type*) [Zero k] where /-- The natural map from `G →₀ k` to `SkewMonoidAlgebra k G`. -/ - ofFinsupp :: + ofCoeff :: /-- The natural map from `SkewMonoidAlgebra k G` to `G →₀ k`. -/ - toFinsupp : G →₀ k + coeff : G →₀ k open Function namespace SkewMonoidAlgebra +initialize_simps_projections SkewMonoidAlgebra (as_prefix coeff) + +@[deprecated (since := "2026-07-06"), reducible] alias ofFinsupp := ofCoeff +@[deprecated (since := "2026-07-06"), reducible] alias toFinsupp := coeff + variable {k G : Type*} section AddMonoid variable [AddMonoid k] -@[simp] -theorem eta (f : SkewMonoidAlgebra k G) : ofFinsupp f.toFinsupp = f := rfl +@[simp] lemma eta (f : SkewMonoidAlgebra k G) : ofCoeff f.coeff = f := rfl +@[simp] lemma coeff_ofCoeff (f : G →₀ k) : coeff (ofCoeff f) = f := rfl set_option backward.privateInPublic true in @[irreducible] @@ -76,94 +81,122 @@ set_option backward.privateInPublic.warn false in instance {S : Type*} [SMulZeroClass S k] : SMulZeroClass S (SkewMonoidAlgebra k G) where smul s f := smul s f - smul_zero a := by exact congr_arg ofFinsupp (smul_zero a) + smul_zero a := by exact congr_arg ofCoeff (smul_zero a) @[simp] -theorem ofFinsupp_zero : (⟨0⟩ : SkewMonoidAlgebra k G) = 0 := rfl +theorem ofCoeff_zero : (⟨0⟩ : SkewMonoidAlgebra k G) = 0 := rfl + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_zero := ofCoeff_zero @[simp] -theorem ofFinsupp_add {a b} : (⟨a + b⟩ : SkewMonoidAlgebra k G) = ⟨a⟩ + ⟨b⟩ := +theorem ofCoeff_add {a b} : (⟨a + b⟩ : SkewMonoidAlgebra k G) = ⟨a⟩ + ⟨b⟩ := show _ = add _ _ by rw [add] +@[deprecated (since := "2026-07-04")] alias ofFinsupp_add := ofCoeff_add + @[simp] -theorem ofFinsupp_smul {S : Type*} [SMulZeroClass S k] (a : S) (b : G →₀ k) : +theorem ofCoeff_smul {S : Type*} [SMulZeroClass S k] (a : S) (b : G →₀ k) : (⟨a • b⟩ : SkewMonoidAlgebra k G) = (a • ⟨b⟩ : SkewMonoidAlgebra k G) := show _ = smul _ _ by rw [smul] +@[deprecated (since := "2026-07-04")] alias ofFinsupp_smul := ofCoeff_smul + @[simp] -theorem toFinsupp_zero : (0 : SkewMonoidAlgebra k G).toFinsupp = 0 := rfl +theorem coeff_zero : (0 : SkewMonoidAlgebra k G).coeff = 0 := rfl + +@[deprecated (since := "2026-07-04")] alias toFinsupp_zero := coeff_zero @[simp] -theorem toFinsupp_add (a b : SkewMonoidAlgebra k G) : - (a + b).toFinsupp = a.toFinsupp + b.toFinsupp := by - rw [← ofFinsupp_add] +theorem coeff_add (a b : SkewMonoidAlgebra k G) : + (a + b).coeff = a.coeff + b.coeff := by + rw [← ofCoeff_add] + +@[deprecated (since := "2026-07-04")] alias toFinsupp_add := coeff_add @[simp] -theorem toFinsupp_smul {S : Type*} [SMulZeroClass S k] (a : S) (b : SkewMonoidAlgebra k G) : - (a • b).toFinsupp = a • b.toFinsupp := by - rw [← ofFinsupp_smul] +theorem coeff_smul {S : Type*} [SMulZeroClass S k] (a : S) (b : SkewMonoidAlgebra k G) : + (a • b).coeff = a • b.coeff := by + rw [← ofCoeff_smul] + +@[deprecated (since := "2026-07-04")] alias toFinsupp_smul := coeff_smul theorem _root_.IsSMulRegular.skewMonoidAlgebra {S : Type*} [Monoid S] [DistribMulAction S k] {a : S} (ha : IsSMulRegular k a) : IsSMulRegular (SkewMonoidAlgebra k G) a | ⟨_⟩, ⟨_⟩, h => by - exact congr_arg _ <| ha.finsupp (ofFinsupp.inj h) + exact congr_arg _ <| ha.finsupp (ofCoeff.inj h) -theorem toFinsupp_injective : - Function.Injective (toFinsupp : SkewMonoidAlgebra k G → Finsupp _ _) := +theorem coeff_injective : + Function.Injective (coeff : SkewMonoidAlgebra k G → Finsupp _ _) := fun ⟨_⟩ _ ↦ congr_arg _ +@[deprecated (since := "2026-07-04")] alias toFinsupp_injective := coeff_injective + @[simp] -theorem toFinsupp_inj {a b : SkewMonoidAlgebra k G} : a.toFinsupp = b.toFinsupp ↔ a = b := - toFinsupp_injective.eq_iff +theorem coeff_inj {a b : SkewMonoidAlgebra k G} : a.coeff = b.coeff ↔ a = b := + coeff_injective.eq_iff + +@[deprecated (since := "2026-07-04")] alias toFinsupp_inj := coeff_inj + +theorem ofCoeff_injective : + Function.Injective (ofCoeff : Finsupp _ _ → SkewMonoidAlgebra k G) := + fun _ _ ↦ congr_arg coeff -theorem ofFinsupp_injective : - Function.Injective (ofFinsupp : Finsupp _ _ → SkewMonoidAlgebra k G) := - fun _ _ ↦ congr_arg toFinsupp +@[deprecated (since := "2026-07-04")] alias ofFinsupp_injective := ofCoeff_injective -/-- A variant of `SkewMonoidAlgebra.ofFinsupp_injective` in terms of `Iff`. -/ -theorem ofFinsupp_inj {a b} : (⟨a⟩ : SkewMonoidAlgebra k G) = ⟨b⟩ ↔ a = b := - ofFinsupp_injective.eq_iff +/-- A variant of `SkewMonoidAlgebra.ofCoeff_injective` in terms of `Iff`. -/ +theorem ofCoeff_inj {a b} : (⟨a⟩ : SkewMonoidAlgebra k G) = ⟨b⟩ ↔ a = b := + ofCoeff_injective.eq_iff + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_inj := ofCoeff_inj @[simp] -theorem toFinsupp_eq_zero {a : SkewMonoidAlgebra k G} : a.toFinsupp = 0 ↔ a = 0 := - toFinsupp_inj +theorem coeff_eq_zero {a : SkewMonoidAlgebra k G} : a.coeff = 0 ↔ a = 0 := + coeff_inj + +@[deprecated (since := "2026-07-04")] alias toFinsupp_eq_zero := coeff_eq_zero @[simp] -theorem ofFinsupp_eq_zero {a} : (⟨a⟩ : SkewMonoidAlgebra k G) = 0 ↔ a = 0 := - ofFinsupp_inj +theorem ofCoeff_eq_zero {a} : (⟨a⟩ : SkewMonoidAlgebra k G) = 0 ↔ a = 0 := + ofCoeff_inj + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_eq_zero := ofCoeff_eq_zero instance : Inhabited (SkewMonoidAlgebra k G) := ⟨0⟩ instance [Nontrivial k] [Nonempty G] : - Nontrivial (SkewMonoidAlgebra k G) := Function.Injective.nontrivial ofFinsupp_injective + Nontrivial (SkewMonoidAlgebra k G) := Function.Injective.nontrivial ofCoeff_injective instance [Subsingleton k] : Unique (SkewMonoidAlgebra k G) := - Function.Injective.unique toFinsupp_injective + Function.Injective.unique coeff_injective instance : AddMonoid (SkewMonoidAlgebra k G) where - __ := toFinsupp_injective.addMonoid _ toFinsupp_zero toFinsupp_add - (fun _ _ ↦ toFinsupp_smul _ _) + __ := coeff_injective.addMonoid _ coeff_zero coeff_add + (fun _ _ ↦ coeff_smul _ _) section Support /-- For `f : SkewMonoidAlgebra k G`, `f.support` is the set of all `a ∈ G` such that `f.coeff a ≠ 0`. -/ -def support (p : SkewMonoidAlgebra k G) : Finset G := p.toFinsupp.support +def support (p : SkewMonoidAlgebra k G) : Finset G := p.coeff.support @[simp] -theorem support_ofFinsupp (p) : support (⟨p⟩ : SkewMonoidAlgebra k G) = p.support := by +theorem support_ofCoeff (p) : support (⟨p⟩ : SkewMonoidAlgebra k G) = p.support := by rw [support] -theorem support_toFinsupp (p : SkewMonoidAlgebra k G) : p.toFinsupp.support = p.support := by +@[deprecated (since := "2026-07-04")] alias support_ofFinsupp := support_ofCoeff + +theorem support_coeff (p : SkewMonoidAlgebra k G) : p.coeff.support = p.support := by rw [support] +@[deprecated (since := "2026-07-04")] alias support_toFinsupp := support_coeff + @[simp] theorem support_zero : (0 : SkewMonoidAlgebra k G).support = ∅ := rfl @[simp] theorem support_eq_empty {p} : p.support = ∅ ↔ (p : SkewMonoidAlgebra k G) = 0 := by rcases p - simp only [support, Finsupp.support_eq_empty, ofFinsupp_eq_zero] + simp only [support, Finsupp.support_eq_empty, ofCoeff_eq_zero] lemma support_add [DecidableEq G] {p q : SkewMonoidAlgebra k G} : (p + q).support ⊆ p.support ∪ q.support := by @@ -173,31 +206,15 @@ end Support section Coeff -/-- `coeff f a` (often denoted `f.coeff a`) is the coefficient of `a` in `f`. -/ -def coeff : SkewMonoidAlgebra k G → G → k - | ⟨p⟩ => p - -@[simp] -theorem coeff_ofFinsupp (p) : coeff (⟨p⟩ : SkewMonoidAlgebra k G) = p := rfl +@[deprecated (since := "2026-07-06")] alias coeff_ofFinsupp := coeff_ofCoeff -theorem coeff_injective : Injective (coeff : SkewMonoidAlgebra k G → G → k) := by - rintro ⟨p⟩ ⟨q⟩ - simp only [coeff, DFunLike.coe_fn_eq, imp_self, ofFinsupp.injEq] - -@[simp] -theorem coeff_inj (p q : SkewMonoidAlgebra k G) : p.coeff = q.coeff ↔ p = q := - coeff_injective.eq_iff - -@[simp] -theorem toFinsupp_apply (f : SkewMonoidAlgebra k G) (g) : f.toFinsupp g = f.coeff g := rfl - -@[simp] -theorem coeff_zero (g : G) : coeff (0 : SkewMonoidAlgebra k G) g = 0 := rfl +@[deprecated "Now a syntactic tautology" (since := "2026-07-04"), nolint synTaut] +theorem toFinsupp_apply (f : SkewMonoidAlgebra k G) (g) : f.coeff g = f.coeff g := rfl @[simp] theorem mem_support_iff {f : SkewMonoidAlgebra k G} {a : G} : a ∈ f.support ↔ f.coeff a ≠ 0 := by rcases f with ⟨⟩ - simp only [coeff, support_ofFinsupp, Finsupp.mem_support_iff, ne_eq] + simp only [support_ofCoeff, Finsupp.mem_support_iff, ne_eq] theorem notMem_support_iff {f : SkewMonoidAlgebra k G} {a : G} : a ∉ f.support ↔ f.coeff a = 0 := by @@ -211,19 +228,6 @@ theorem ext_iff {p q : SkewMonoidAlgebra k G} : p = q ↔ ∀ n, coeff p n = coe @[ext] theorem ext {p q : SkewMonoidAlgebra k G} : (∀ a, coeff p a = coeff q a) → p = q := ext_iff.2 -@[simp] -theorem coeff_add (p q : SkewMonoidAlgebra k G) (a : G) : - coeff (p + q) a = coeff p a + coeff q a := by - rcases p - rcases q - simp_rw [← ofFinsupp_add, coeff] - exact Finsupp.add_apply _ _ _ - -@[simp] -theorem coeff_smul {S} [SMulZeroClass S k] (r : S) (p : SkewMonoidAlgebra k G) (a : G) : - coeff (r • p) a = r • coeff p a := by - rfl - end Coeff section Single @@ -232,50 +236,55 @@ section Single def single (a : G) (b : k) : SkewMonoidAlgebra k G := ⟨Finsupp.single a b⟩ @[simp] -theorem toFinsupp_single (a : G) (b : k) : (single a b).toFinsupp = Finsupp.single a b := rfl +theorem coeff_single (a : G) (b : k) : (single a b).coeff = Finsupp.single a b := rfl + +@[deprecated (since := "2026-07-04")] alias toFinsupp_single := coeff_single @[simp] -theorem ofFinsupp_single (a : G) (b : k) : ⟨Finsupp.single a b⟩ = single a b := rfl +theorem ofCoeff_single (a : G) (b : k) : ⟨Finsupp.single a b⟩ = single a b := rfl -theorem coeff_single (a : G) (b : k) [DecidableEq G] : - coeff (single a b) = Pi.single a b := by - simp [coeff, Finsupp.single_eq_pi_single] +@[deprecated (since := "2026-07-06")] alias ofFinsupp_single := ofCoeff_single theorem coeff_single_apply {a a' : G} {b : k} [Decidable (a = a')] : coeff (single a b) a' = if a = a' then b else 0 := by - simp [coeff, Finsupp.single_apply] + simp [Finsupp.single_apply] theorem single_zero_right (a : G) : single a (0 : k) = 0 := by - simp [← toFinsupp_inj] + simp [← coeff_inj] @[simp] theorem single_add (a : G) (b₁ b₂ : k) : single a (b₁ + b₂) = single a b₁ + single a b₂ := by - simp [← toFinsupp_inj] + simp [← coeff_inj] @[simp] theorem single_zero (a : G) : (single a 0 : SkewMonoidAlgebra k G) = 0 := by - simp [← toFinsupp_inj] + simp [← coeff_inj] theorem single_eq_zero {a : G} {b : k} : single a b = 0 ↔ b = 0 := by - simp [← toFinsupp_inj] + simp [← coeff_inj] set_option linter.style.whitespace false in -- manual alignment is not recognised /-- Group isomorphism between `SkewMonoidAlgebra k G` and `G →₀ k`. -/ @[simps apply symm_apply] -def toFinsuppAddEquiv : SkewMonoidAlgebra k G ≃+ (G →₀ k) where - toFun := toFinsupp - invFun := ofFinsupp - map_add' := toFinsupp_add +def coeffAddEquiv : SkewMonoidAlgebra k G ≃+ (G →₀ k) where + toFun := coeff + invFun := ofCoeff + map_add' := coeff_add + +@[deprecated (since := "2026-07-04")] alias toFinsuppAddEquiv := coeffAddEquiv +@[deprecated (since := "2026-07-04")] alias toFinsuppAddEquiv_apply := coeffAddEquiv_apply +@[deprecated (since := "2026-07-04")] +alias toFinsuppAddEquiv_symm_apply := coeffAddEquiv_symm_apply theorem smul_single {S} [SMulZeroClass S k] (s : S) (a : G) (b : k) : s • single a b = single a (s • b) := - toFinsupp_injective <| by simp; + coeff_injective <| by simp; theorem single_injective (a : G) : Function.Injective (single a : k → SkewMonoidAlgebra k G) := - toFinsuppAddEquiv.symm.injective.comp (Finsupp.single_injective a) + coeffAddEquiv.symm.injective.comp (Finsupp.single_injective a) theorem single_left_inj {a a' : G} {b : k} (h : b ≠ 0) : single a b = single a' b ↔ a = a' := by - rw [← toFinsupp_inj] + rw [← coeff_inj] exact Finsupp.single_left_inj h theorem _root_.IsSMulRegular.skewMonoidAlgebra_iff {S : Type*} [Monoid S] [DistribMulAction S k] @@ -302,34 +311,37 @@ instance : One (SkewMonoidAlgebra k G) where instance : AddMonoidWithOne (SkewMonoidAlgebra k G) where -theorem ofFinsupp_one : (⟨Finsupp.single 1 1⟩ : SkewMonoidAlgebra k G) = 1 := rfl +theorem ofCoeff_one : (⟨Finsupp.single 1 1⟩ : SkewMonoidAlgebra k G) = 1 := rfl + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_one := ofCoeff_one @[simp] -theorem toFinsupp_one : (1 : SkewMonoidAlgebra k G).toFinsupp = Finsupp.single 1 1 := rfl +theorem coeff_one : (1 : SkewMonoidAlgebra k G).coeff = Finsupp.single 1 1 := rfl + +@[deprecated (since := "2026-07-04")] alias toFinsupp_one := coeff_one @[simp] -theorem toFinsupp_eq_single_one_one_iff {a : SkewMonoidAlgebra k G} : - a.toFinsupp = Finsupp.single 1 1 ↔ a = 1 := by - simp [← toFinsupp_inj] +theorem coeff_eq_single_one_one_iff {a : SkewMonoidAlgebra k G} : + a.coeff = Finsupp.single 1 1 ↔ a = 1 := by + simp [← coeff_inj] + +@[deprecated (since := "2026-07-04")] +alias toFinsupp_eq_single_one_one_iff := coeff_eq_single_one_one_iff @[simp] -theorem ofFinsupp_eq_one {a} : +theorem ofCoeff_eq_one {a} : (⟨a⟩ : SkewMonoidAlgebra k G) = 1 ↔ a = Finsupp.single 1 1 := by - simp [← toFinsupp_inj] + simp [← coeff_inj] + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_eq_one := ofCoeff_eq_one @[simp] theorem single_one_one : single (1 : G) (1 : k) = 1 := rfl theorem one_def : (1 : SkewMonoidAlgebra k G) = single 1 1 := rfl -@[simp] -theorem coeff_one_one : coeff (1 : SkewMonoidAlgebra k G) 1 = 1 := by - simp only [coeff, toFinsupp_single, Finsupp.single_eq_same] - -theorem coeff_one {a : G} [Decidable (a = 1)] : - (1 : SkewMonoidAlgebra k G).coeff a = if a = 1 then 1 else 0 := by - classical - simpa [eq_comm (a := a)] using! coeff_single_apply +@[deprecated coeff_one (since := "2026-07-04")] +theorem coeff_one_one : coeff (1 : SkewMonoidAlgebra k G) 1 = 1 := by simp theorem natCast_def (n : ℕ) : (n : SkewMonoidAlgebra k G) = single (1 : G) (n : k) := by induction n <;> simp_all @@ -346,20 +358,20 @@ section AddCommMonoid variable [AddCommMonoid k] instance : AddCommMonoid (SkewMonoidAlgebra k G) where - __ := toFinsupp_injective.addCommMonoid _ toFinsupp_zero toFinsupp_add - (fun _ _ ↦ toFinsupp_smul _ _) + __ := coeff_injective.addCommMonoid _ coeff_zero coeff_add + (fun _ _ ↦ coeff_smul _ _) section sum instance [DecidableEq G] [DecidableEq k] : DecidableEq (SkewMonoidAlgebra k G) := - Equiv.decidableEq toFinsuppAddEquiv.toEquiv + Equiv.decidableEq coeffAddEquiv.toEquiv /-- `sum f g` is the sum of `g a (f.coeff a)` over the support of `f`. -/ def sum {N : Type*} [AddCommMonoid N] (f : SkewMonoidAlgebra k G) (g : G → k → N) : N := - f.toFinsupp.sum g + f.coeff.sum g theorem sum_def {N : Type*} [AddCommMonoid N] (f : SkewMonoidAlgebra k G) (g : G → k → N) : - sum f g = f.toFinsupp.sum g := rfl + sum f g = f.coeff.sum g := rfl /-- Unfolded version of `sum_def` in terms of `Finset.sum`. -/ theorem sum_def' {N : Type*} [AddCommMonoid N] (f : SkewMonoidAlgebra k G) (g : G → k → N) : @@ -376,25 +388,29 @@ theorem map_sum {N P : Type*} [AddCommMonoid N] [AddCommMonoid P] {H : Type*} [F _root_.map_sum h _ _ /-- Variant where the image of `g` is a `SkewMonoidAlgebra`. -/ -theorem toFinsupp_sum' {k' G' : Type*} [AddCommMonoid k'] (f : SkewMonoidAlgebra k G) +theorem coeff_sum' {k' G' : Type*} [AddCommMonoid k'] (f : SkewMonoidAlgebra k G) (g : G → k → SkewMonoidAlgebra k' G') : - (sum f g).toFinsupp = Finsupp.sum f.toFinsupp (toFinsupp <| g · ·) := - _root_.map_sum toFinsuppAddEquiv (fun a ↦ g a (f.coeff a)) f.toFinsupp.support + (sum f g).coeff = Finsupp.sum f.coeff (coeff <| g · ·) := + _root_.map_sum coeffAddEquiv (fun a ↦ g a (f.coeff a)) f.coeff.support -theorem ofFinsupp_sum {k' G' : Type*} [AddCommMonoid k'] (f : G →₀ k) +@[deprecated (since := "2026-07-04")] alias toFinsupp_sum' := coeff_sum' + +theorem ofCoeff_sum {k' G' : Type*} [AddCommMonoid k'] (f : G →₀ k) (g : G → k → G' →₀ k') : (⟨Finsupp.sum f g⟩ : SkewMonoidAlgebra k' G') = sum ⟨f⟩ (⟨g · ·⟩) := by - apply toFinsupp_injective; simp only [toFinsupp_sum'] + apply coeff_injective; simp only [coeff_sum'] + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_sum := ofCoeff_sum theorem sum_single (f : SkewMonoidAlgebra k G) : f.sum single = f := by - apply toFinsupp_injective; simp only [toFinsupp_sum', toFinsupp_single, Finsupp.sum_single] + apply coeff_injective; simp only [coeff_sum', coeff_single, Finsupp.sum_single] /-- Taking the `sum` under `h` is an additive homomorphism, if `h` is an additive homomorphism. This is a more specific version of `SkewMonoidAlgebra.sum_add_index` with simpler hypotheses. -/ theorem sum_add_index' {S : Type*} [AddCommMonoid S] {f g : SkewMonoidAlgebra k G} {h : G → k → S} (hf : ∀ i, h i 0 = 0) (h_add : ∀ a b₁ b₂, h a (b₁ + b₂) = h a b₁ + h a b₂) : (f + g).sum h = f.sum h + g.sum h := by - rw [show f + g = ⟨f.toFinsupp + g.toFinsupp⟩ by rw [ofFinsupp_add, eta]] + rw [show f + g = ⟨f.coeff + g.coeff⟩ by rw [ofCoeff_add, eta]] exact Finsupp.sum_add_index' hf h_add /-- Taking the `sum` under `h` is an additive homomorphism, if `h` is an additive homomorphism. @@ -404,7 +420,7 @@ theorem sum_add_index {S : Type*} [DecidableEq G] [AddCommMonoid S] {f g : SkewMonoidAlgebra k G} {h : G → k → S} (h_zero : ∀ a ∈ f.support ∪ g.support, h a 0 = 0) (h_add : ∀ a ∈ f.support ∪ g.support, ∀ b₁ b₂, h a (b₁ + b₂) = h a b₁ + h a b₂) : (f + g).sum h = f.sum h + g.sum h := by - rw [show f + g = ⟨f.toFinsupp + g.toFinsupp⟩ by rw [ofFinsupp_add, eta]] + rw [show f + g = ⟨f.coeff + g.coeff⟩ by rw [ofCoeff_add, eta]] exact Finsupp.sum_add_index h_zero h_add @[simp] @@ -424,13 +440,13 @@ theorem sum_sum_index {α β M N P : Type*} [AddCommMonoid M] [AddCommMonoid N] (h_zero : ∀ (a : β), h a 0 = 0) (h_add : ∀ (a : β) (b₁ b₂ : N), h a (b₁ + b₂) = h a b₁ + h a b₂) : sum (sum f g) h = sum f fun a b ↦ sum (g a b) h := by - rw [sum_def, toFinsupp_sum' f g, Finsupp.sum_sum_index h_zero h_add]; simp [sum_def] + rw [sum_def, coeff_sum' f g, Finsupp.sum_sum_index h_zero h_add]; simp [sum_def] @[simp] theorem coeff_sum {k' G' : Type*} [AddCommMonoid k'] {f : SkewMonoidAlgebra k G} {g : G → k → SkewMonoidAlgebra k' G'} {a₂ : G'} : (f.sum g).coeff a₂ = f.sum fun a₁ b ↦ (g a₁ b).coeff a₂ := by - simp_rw [coeff, toFinsupp_sum', sum_def, Finsupp.sum_apply] + simp_rw [coeff_sum', sum_def, Finsupp.sum_apply] theorem sum_mul {S : Type*} [NonUnitalNonAssocSemiring S] (b : S) (s : SkewMonoidAlgebra k G) {f : G → k → S} : s.sum f * b = s.sum fun a c ↦ f a c * b := by @@ -446,7 +462,7 @@ set_option backward.isDefEq.respectTransparency false in theorem sum_ite_eq' {N : Type*} [AddCommMonoid N] [DecidableEq G] (f : SkewMonoidAlgebra k G) (a : G) (b : G → k → N) : (f.sum fun (x : G) (v : k) ↦ if x = a then b x v else 0) = if a ∈ f.support then b a (f.coeff a) else 0 := by - simp only [sum_def', f.toFinsupp.support.sum_ite_eq', support] + simp only [sum_def', f.coeff.support.sum_ite_eq', support] theorem smul_sum {M : Type*} {R : Type*} [AddCommMonoid M] [DistribSMul R M] {v : SkewMonoidAlgebra k G} {c : R} {h : G → k → M} : @@ -496,9 +512,11 @@ def mapDomain : map_zero' := sum_zero_index map_add' _ _ := sum_add_index' (fun _ ↦ single_zero _) fun _ ↦ single_add _ -lemma toFinsupp_mapDomain : - (mapDomain f v).toFinsupp = Finsupp.mapDomain f v.toFinsupp := by - simp_rw [mapDomain_apply, Finsupp.mapDomain, toFinsupp_sum', single] +lemma coeff_mapDomain : + (mapDomain f v).coeff = Finsupp.mapDomain f v.coeff := by + simp_rw [mapDomain_apply, Finsupp.mapDomain, coeff_sum', single] + +@[deprecated (since := "2026-07-04")] alias toFinsupp_mapDomain := coeff_mapDomain variable {f v} @@ -519,7 +537,7 @@ theorem mapDomain_single {a : G} {b : k} : mapDomain f (single a b) = single (f theorem mapDomain_smul {R : Type*} [Monoid R] [DistribMulAction R k] {b : R} : mapDomain f (b • v) = b • mapDomain f v := by - simp_rw [← toFinsupp_inj, toFinsupp_smul, toFinsupp_mapDomain] + simp_rw [← coeff_inj, coeff_smul, coeff_mapDomain] simp [Finsupp.mapDomain_smul] /-- A non-commutative version of `SkewMonoidAlgebra.lift`: given an additive homomorphism @@ -535,7 +553,7 @@ If `R` is a `k`-algebra and `f = algebraMap k R`, then the result is an algebra def liftNC {R : Type*} [NonUnitalNonAssocSemiring R] (f : k →+ R) (g : G → R) : SkewMonoidAlgebra k G →+ R := (Finsupp.liftAddHom fun x ↦ (AddMonoidHom.mulRight (g x)).comp f).comp - (AddEquiv.toAddMonoidHom toFinsuppAddEquiv) + (AddEquiv.toAddMonoidHom coeffAddEquiv) @[simp] theorem liftNC_single {R : Type*} [NonUnitalNonAssocSemiring R] (f : k →+ R) (g : G → R) (a : G) (b : k) : liftNC f g (single a b) = f b * g a := @@ -557,29 +575,37 @@ variable [AddGroup k] ⟨fun ⟨a⟩ ↦ ⟨-a⟩⟩ @[simp] -theorem ofFinsupp_neg {a} : (⟨-a⟩ : SkewMonoidAlgebra k G) = -⟨a⟩ := +theorem ofCoeff_neg {a} : (⟨-a⟩ : SkewMonoidAlgebra k G) = -⟨a⟩ := (rfl) +@[deprecated (since := "2026-07-04")] alias ofFinsupp_neg := ofCoeff_neg + instance : AddGroup (SkewMonoidAlgebra k G) where zsmul := zsmulRec - neg_add_cancel a := by cases a; simp [← ofFinsupp_neg, ← ofFinsupp_add] + neg_add_cancel a := by cases a; simp [← ofCoeff_neg, ← ofCoeff_add] @[simp] -theorem toFinsupp_neg (a : SkewMonoidAlgebra k G) : (-a).toFinsupp = -a.toFinsupp := - toFinsuppAddEquiv.map_neg a +theorem coeff_neg (a : SkewMonoidAlgebra k G) : (-a).coeff = -a.coeff := + coeffAddEquiv.map_neg a + +@[deprecated (since := "2026-07-04")] alias toFinsupp_neg := coeff_neg @[simp] -theorem ofFinsupp_sub {a b} : (⟨a - b⟩ : SkewMonoidAlgebra k G) = ⟨a⟩ - ⟨b⟩ := - toFinsuppAddEquiv.symm.map_sub a b +theorem ofCoeff_sub {a b} : (⟨a - b⟩ : SkewMonoidAlgebra k G) = ⟨a⟩ - ⟨b⟩ := + coeffAddEquiv.symm.map_sub a b + +@[deprecated (since := "2026-07-04")] alias ofFinsupp_sub := ofCoeff_sub @[simp] -theorem toFinsupp_sub (a b : SkewMonoidAlgebra k G) : - (a - b).toFinsupp = a.toFinsupp - b.toFinsupp := - toFinsuppAddEquiv.map_sub a b +theorem coeff_sub (a b : SkewMonoidAlgebra k G) : + (a - b).coeff = a.coeff - b.coeff := + coeffAddEquiv.map_sub a b + +@[deprecated (since := "2026-07-04")] alias toFinsupp_sub := coeff_sub @[simp] theorem single_neg (a : G) (b : k) : single a (-b) = -single a b := by - simp [← ofFinsupp_single] + simp [← ofCoeff_single] end AddGroup @@ -617,7 +643,7 @@ theorem sum_smul_index' {N R : Type*} [AddCommMonoid k] [DistribSMul R k] [AddCommMonoid N] {g : SkewMonoidAlgebra k G} {b : R} {h : G → k → N} (h0 : ∀ i, h i 0 = 0) : (b • g).sum h = g.sum (h · <| b • ·) := by - simp only [sum_def, toFinsupp_smul, Finsupp.sum_smul_index' h0] + simp only [sum_def, coeff_smul, Finsupp.sum_smul_index' h0] @[simp] theorem liftNC_one {g_hom R : Type*} [NonAssocSemiring k] [One G] [Semiring R] [FunLike g_hom G R] @@ -750,7 +776,7 @@ instance instCommSemiring [CommSemiring k] [CommMonoid G] [MulSemiringAction G k simp only [mul_def, hgk, sum_def] rw [Finsupp.sum_comm] exact Finsupp.sum_congr (fun x _ ↦ Finsupp.sum_congr - (fun y _ ↦ by rw [mul_comm, mul_comm (a.toFinsupp y) _])) + (fun y _ ↦ by rw [mul_comm, mul_comm (a.coeff y) _])) instance instRing [Ring k] [Monoid G] [MulSemiringAction G k] : Ring (SkewMonoidAlgebra k G) where __ := instNonAssocRing @@ -760,48 +786,50 @@ variable {S S₁ S₂ : Type*} instance [AddMonoid k] [DistribSMul S k] : DistribSMul S (SkewMonoidAlgebra k G) where - __ := toFinsupp_injective.distribSMul ⟨⟨toFinsupp, toFinsupp_zero⟩, toFinsupp_add⟩ - toFinsupp_smul + __ := coeff_injective.distribSMul ⟨⟨coeff, coeff_zero⟩, coeff_add⟩ + coeff_smul instance [Monoid S] [AddMonoid k] [DistribMulAction S k] : DistribMulAction S (SkewMonoidAlgebra k G) where - __ := toFinsupp_injective.distribMulAction ⟨⟨toFinsupp, toFinsupp_zero (k := k)⟩, toFinsupp_add⟩ - toFinsupp_smul + __ := coeff_injective.distribMulAction ⟨⟨coeff, coeff_zero (k := k)⟩, coeff_add⟩ + coeff_smul instance [Semiring S] [AddCommMonoid k] [Module S k] : Module S (SkewMonoidAlgebra k G) where - __ := toFinsupp_injective.module _ ⟨⟨toFinsupp, toFinsupp_zero⟩, toFinsupp_add⟩ toFinsupp_smul + __ := coeff_injective.module _ ⟨⟨coeff, coeff_zero⟩, coeff_add⟩ coeff_smul instance instFaithfulSMul [AddMonoid k] [SMulZeroClass S k] [FaithfulSMul S k] [Nonempty G] : FaithfulSMul S (SkewMonoidAlgebra k G) where eq_of_smul_eq_smul {_s₁ _s₂} h := by - apply eq_of_smul_eq_smul fun a : G →₀ k ↦ congr_arg toFinsupp _ + apply eq_of_smul_eq_smul fun a : G →₀ k ↦ congr_arg coeff _ intro a - simp_rw [ofFinsupp_smul, h] + simp_rw [ofCoeff_smul, h] instance [AddMonoid k] [SMul S₁ S₂] [SMulZeroClass S₁ k] [SMulZeroClass S₂ k] [IsScalarTower S₁ S₂ k] : IsScalarTower S₁ S₂ (SkewMonoidAlgebra k G) := - ⟨fun _ _ ⟨_⟩ ↦ by simp_rw [← ofFinsupp_smul, smul_assoc]⟩ + ⟨fun _ _ ⟨_⟩ ↦ by simp_rw [← ofCoeff_smul, smul_assoc]⟩ instance [AddMonoid k] [SMulZeroClass S₁ k] [SMulZeroClass S₂ k] [SMulCommClass S₁ S₂ k] : SMulCommClass S₁ S₂ (SkewMonoidAlgebra k G) := - ⟨fun _ _ ⟨_⟩ ↦ by simp_rw [← ofFinsupp_smul, smul_comm _ _ _]⟩ + ⟨fun _ _ ⟨_⟩ ↦ by simp_rw [← ofCoeff_smul, smul_comm _ _ _]⟩ instance [AddMonoid k] [SMulZeroClass S k] [SMulZeroClass Sᵐᵒᵖ k] [IsCentralScalar S k] : IsCentralScalar S (SkewMonoidAlgebra k G) := - ⟨fun _ ⟨_⟩ ↦ by simp_rw [← ofFinsupp_smul, op_smul_eq_smul]⟩ + ⟨fun _ ⟨_⟩ ↦ by simp_rw [← ofCoeff_smul, op_smul_eq_smul]⟩ section Module.Free variable [Semiring S] /-- Linear equivalence between `SkewMonoidAlgebra k G` and `G →₀ k`. -/ -def toFinsuppLinearEquiv [AddCommMonoid k] [Module S k] : SkewMonoidAlgebra k G ≃ₗ[S] (G →₀ k) := - AddEquiv.toLinearEquiv toFinsuppAddEquiv (by simp) +def coeffLinearEquiv [AddCommMonoid k] [Module S k] : SkewMonoidAlgebra k G ≃ₗ[S] (G →₀ k) := + AddEquiv.toLinearEquiv coeffAddEquiv (by simp) + +@[deprecated (since := "2026-07-04")] alias toFinsuppLinearEquiv := coeffLinearEquiv /-- The basis on `SkewMonoidAlgebra k G` with basis vectors `fun i ↦ single i 1` -/ def basisSingleOne [Semiring k] : Module.Basis G k (SkewMonoidAlgebra k G) where - repr := toFinsuppLinearEquiv + repr := coeffLinearEquiv instance [Semiring k] : Module.Free k (SkewMonoidAlgebra k G) := Module.Free.of_basis basisSingleOne @@ -1115,7 +1143,7 @@ theorem smul_of (g : G) (r : k) : r • of k G g = single g r := by theorem of_injective [Nontrivial k] : Function.Injective (of k G) := fun a b h ↦ by - simp_rw [of_apply, ← toFinsupp_inj] at h + simp_rw [of_apply, ← coeff_inj] at h simpa using (Finsupp.single_eq_single_iff _ _ _ _).mp h /-- If two ring homomorphisms from `SkewMonoidAlgebra k G` are equal on all `single a 1` @@ -1236,11 +1264,7 @@ variable {A : Type*} [Semiring A] [Algebra k A] instance [MulSemiringAction G A] [SMulCommClass G k A] : Algebra k (SkewMonoidAlgebra A G) where algebraMap := singleOneRingHom.comp (algebraMap k A) - smul_def' r a := by - ext - simp only [RingHom.coe_comp, comp_apply, coeff_smul, Algebra.smul_def, singleOneRingHom, - singleAddHom, ZeroHom.toFun_eq_coe, ZeroHom.coe_mk, RingHom.coe_mk, MonoidHom.coe_mk, - OneHom.coe_mk, coeff_single_one_mul] + smul_def' r a := by ext; simp [Algebra.smul_def, singleOneRingHom, coeff_single_one_mul] commutes' r f := by ext simp only [singleOneRingHom, singleAddHom, ZeroHom.toFun_eq_coe, ZeroHom.coe_mk, RingHom.coe_mk, diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean index f0ac9769eca069..65049171679131 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean @@ -108,22 +108,17 @@ variable [AddCommMonoid k] /-- Given `f : G ≃ H`, we can map `l : SkewMonoidAlgebra k G` to `equivMapDomain f l : SkewMonoidAlgebra k H` (computably) by mapping the support forwards and the function backwards. -/ +@[simps] def equivMapDomain (f : G ≃ H) (l : SkewMonoidAlgebra k G) : SkewMonoidAlgebra k H where - toFinsupp := ⟨l.support.map f.toEmbedding, fun a ↦ l.coeff (f.symm a), by simp⟩ + coeff := l.coeff.equivMapDomain f -@[simp] -theorem coeff_equivMapDomain (f : G ≃ H) (l : SkewMonoidAlgebra k G) (b : H) : - (equivMapDomain f l).coeff b = l.coeff (f.symm b) := - rfl - -lemma toFinsupp_equivMapDomain (f : G ≃ H) (l : SkewMonoidAlgebra k G) : - (equivMapDomain f l).toFinsupp = Finsupp.equivMapDomain f l.toFinsupp := rfl +@[deprecated (since := "2026-07-06")] alias toFinsupp_equivMapDomain := coeff_equivMapDomain theorem equivMapDomain_eq_mapDomain (f : G ≃ H) (l : SkewMonoidAlgebra k G) : equivMapDomain f l = mapDomain f l := by - apply toFinsupp_injective + apply coeff_injective ext x - simp_rw [toFinsupp_equivMapDomain, Finsupp.equivMapDomain_apply, toFinsupp_mapDomain, + simp_rw [coeff_equivMapDomain, Finsupp.equivMapDomain_apply, coeff_mapDomain, Finsupp.mapDomain_equiv_apply] theorem equivMapDomain_trans {G' G'' : Type*} (f : G ≃ G') (g : G' ≃ G'') @@ -139,8 +134,8 @@ theorem equivMapDomain_refl (l : SkewMonoidAlgebra k G) : equivMapDomain (Equiv. theorem equivMapDomain_single (f : G ≃ H) (a : G) (b : k) : equivMapDomain f (single a b) = single (f a) b := by classical - apply toFinsupp_injective - simp_rw [toFinsupp_equivMapDomain, single, Finsupp.equivMapDomain_single] + apply coeff_injective + simp_rw [coeff_equivMapDomain, single, Finsupp.equivMapDomain_single] end equivMapDomain diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean index e1c074f5c1c9b7..7f4a52f2127137 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean @@ -30,20 +30,22 @@ Given an element `f` of a skew monoid algebra, `erase a f` is an element with th as `f` except at `a` where the coefficient is `0`. If `a` is not in the support of `f` then `erase a f = f`. -/ @[simps] def erase : SkewMonoidAlgebra M α →+ SkewMonoidAlgebra M α where - toFun f := ⟨f.toFinsupp.erase a⟩ + toFun f := ⟨f.coeff.erase a⟩ map_zero' := by simp map_add' := by simp +@[deprecated (since := "2026-07-04")] alias erase_apply_toFinsupp := coeff_erase_apply + @[simp] theorem support_erase [DecidableEq α] : (f.erase a).support = f.support.erase a := by ext; simp [erase] -@[simp] +@[deprecated Finsupp.erase_same (since := "2026-07-04")] theorem coeff_erase_same : (f.erase a).coeff a = 0 := by simp [erase] variable {a a'} in -@[simp] +@[deprecated Finsupp.erase_ne (since := "2026-07-04")] theorem coeff_erase_ne (h : a' ≠ a) : (f.erase a).coeff a' = f.coeff a' := by simp [erase, h] @@ -51,15 +53,9 @@ theorem coeff_erase_ne (h : a' ≠ a) : (f.erase a).coeff a' = f.coeff a' := by theorem erase_single : erase a (single a b) = 0 := by simp [erase] -theorem coeff_erase_apply [DecidableEq α] : - (f.erase a).coeff a' = if a' = a then 0 else f.coeff a' := - ite_congr rfl (fun _ ↦ rfl) (fun _ ↦ rfl) - theorem single_add_erase (a : α) (f : SkewMonoidAlgebra M α) : single a (f.coeff a) + f.erase a = f := by - apply toFinsupp_injective - rw [single, ← toFinsupp_apply, toFinsupp_add, erase_apply_toFinsupp, - Finsupp.single_add_erase] + ext; simp [ coeff_add, Finsupp.single_add_erase] @[elab_as_elim] theorem induction {p : SkewMonoidAlgebra M α → Prop} (f : SkewMonoidAlgebra M α) (h0 : p 0) @@ -87,14 +83,13 @@ variable {M α : Type*} [AddCommMonoid M] (f : SkewMonoidAlgebra M α) (a a' : a given value `b : M`. If `b = 0`, this amounts to removing `a` from the support of `f`. Otherwise, if `a` was not in the `support` of `f`, it is added to it. -/ -@[simps] def update : SkewMonoidAlgebra M α := - ⟨f.toFinsupp.update a b⟩ +@[simps coeff] def update : SkewMonoidAlgebra M α := + ⟨f.coeff.update a b⟩ + +@[deprecated (since := "2026-07-04")] alias update_toFinsupp := coeff_update @[simp] -theorem update_self : f.update a (f.coeff a) = f := by - rcases f with ⟨f⟩ - apply toFinsupp_injective - simp +theorem update_self : f.update a (f.coeff a) = f := by ext; simp @[simp] theorem zero_update : update 0 a b = single a b := by @@ -104,21 +99,18 @@ theorem support_update [DecidableEq α] [DecidableEq M] : support (f.update a b) = if b = 0 then f.support.erase a else insert a f.support := by aesop (add norm [update, Finsupp.support_update_ne_zero]) -theorem coeff_update [DecidableEq α] : (f.update a b).coeff = Function.update f.coeff a b := by - simp only [coeff, update, Finsupp.update, Finsupp.coe_mk] - congr! - +@[deprecated Finsupp.update_apply (since := "2026-07-04")] theorem coeff_update_apply [DecidableEq α] : (f.update a b).coeff a' = if a' = a then b else f.coeff a' := by - rw [coeff_update, Function.update_apply] + simp [coeff_update, Function.update_apply] -@[simp] +@[deprecated Finsupp.update_apply (since := "2026-07-04")] theorem coeff_update_same : (f.update a b).coeff a = b := by classical rw [f.coeff_update_apply, if_pos rfl] variable {a a'} in -@[simp] +@[deprecated Finsupp.update_apply (since := "2026-07-04")] theorem coeff_update_ne (h : a' ≠ a) : (f.update a b).coeff a' = f.coeff a' := by classical rw [f.coeff_update_apply, if_neg h] @@ -128,7 +120,7 @@ theorem update_eq_erase_add_single : f.update a b = f.erase a + single a b := by @[simp] theorem update_zero_eq_erase : f.update a 0 = f.erase a := by - classical ext; simp [coeff_update_apply, coeff_erase_apply] + classical ext; simp [coeff_erase_apply, Finsupp.erase_apply, Function.update_apply] end update diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean index 7940905d09c8ed..95f17ff8576225 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Support.lean @@ -38,7 +38,7 @@ theorem support_single_subset : (single a b).support ⊆ {a} := Finsupp.support_ theorem support_sum {k' G' : Type*} [DecidableEq G'] [AddCommMonoid k'] {f : SkewMonoidAlgebra k G} {g : G → k → SkewMonoidAlgebra k' G'} : (f.sum g).support ⊆ f.support.biUnion fun a ↦ (g a (f.coeff a)).support := by - simp_rw [support, toFinsupp_sum'] + simp_rw [support, coeff_sum'] apply Finsupp.support_sum end AddCommMonoid @@ -48,7 +48,7 @@ section AddCommGroup variable [AddCommGroup k] theorem support_neg (p : SkewMonoidAlgebra k G) : (-p).support = p.support := by - rw [support, toFinsupp_neg, Finsupp.support_neg, support_toFinsupp] + rw [support, coeff_neg, Finsupp.support_neg, support_coeff] end AddCommGroup diff --git a/Mathlib/Algebra/SkewPolynomial/Basic.lean b/Mathlib/Algebra/SkewPolynomial/Basic.lean index 926b3911497807..43773e49ace59e 100644 --- a/Mathlib/Algebra/SkewPolynomial/Basic.lean +++ b/Mathlib/Algebra/SkewPolynomial/Basic.lean @@ -147,7 +147,7 @@ lemma sum_def' {S : Type*} [AddCommMonoid S] (p : SkewPolynomial R) (f : ℕ → lemma sum_def {S : Type*} [AddCommMonoid S] (p : SkewPolynomial R) (f : ℕ → R → S) : p.sum f = ∑ n ∈ p.support, f n (p.coeff n) := by - simp only [sum_def', SkewMonoidAlgebra.sum_def, Finsupp.sum, toFinsupp_apply] + simp only [sum_def', SkewMonoidAlgebra.sum_def, Finsupp.sum] apply Finset.sum_of_injOn (toAdd) (Injective.injOn fun ⦃a₁ a₂⦄ a ↦ a) (fun _ ↦ ?_) <;> simp +contextual [coeff] @@ -203,8 +203,8 @@ lemma monomial_eq_zero_iff (t : R) : monomial n t = 0 ↔ t = 0 := lemma monomial_eq_monomial_iff {m n : ℕ} {a b : R} : monomial m a = monomial n b ↔ m = n ∧ a = b ∨ a = 0 ∧ b = 0 := by rw [← Finsupp.single_eq_single_iff m n a b] - simp only [monomial_def, ← toFinsupp_single, toFinsupp_inj] - simp only [← ofFinsupp_single, SkewMonoidAlgebra.ofFinsupp_inj, Finsupp.single_eq_single_iff, + simp only [monomial_def, ← coeff_single, coeff_inj] + simp only [← ofCoeff_single, SkewMonoidAlgebra.ofCoeff_inj, Finsupp.single_eq_single_iff, EmbeddingLike.apply_eq_iff_eq] lemma induction {motive : SkewPolynomial R → Prop} (p : SkewPolynomial R) (h0 : motive 0) @@ -240,7 +240,8 @@ lemma monomial_mul_monomial [MulSemiringAction (Multiplicative ℕ) R] (n m : lemma mul_def {f g : SkewPolynomial R} [MulSemiringAction (Multiplicative ℕ) R] : f * g = f.sum fun (a₁ : ℕ) b₁ ↦ g.sum fun (a₂ : ℕ) b₂ ↦ monomial (a₁ + a₂) (b₁ * φ^[a₁] b₂) := by ext - simp [φ_iterate_apply, sum_def', coeff_mul, monomial, lsingle_apply, coeff_single_apply] + simp [φ_iterate_apply, sum_def', coeff_mul, monomial, lsingle_apply, SkewMonoidAlgebra.coeff_sum'] + simp [SkewMonoidAlgebra.sum, Finsupp.single_apply] section Constant @@ -586,7 +587,7 @@ end Sum @[simp] lemma coeff_add (p q : SkewPolynomial R) (n : ℕ) : coeff (p + q) n = coeff p n + coeff q n := - SkewMonoidAlgebra.coeff_add p q n + by simp [coeff] end Semiring @@ -660,6 +661,7 @@ lemma monomial_add_erase (p : SkewPolynomial R) (n : ℕ) : monomial n (coeff p n) + p.erase n = p := by simp [coeff, monomial_def, erase, SkewMonoidAlgebra.single_add_erase] +@[simp] lemma coeff_erase (p : SkewPolynomial R) (n i : ℕ) : (p.erase n).coeff i = if i = n then 0 else p.coeff i := by exact ite_congr rfl (fun _ ↦ rfl) (fun _ ↦ rfl) @@ -672,11 +674,11 @@ lemma erase_zero (n : ℕ) : (0 : SkewPolynomial R).erase n = 0 := by lemma erase_monomial {n : ℕ} {a : R} : erase n (monomial n a) = 0 := by simp [erase, monomial_def, zero_def] -@[simp] +@[deprecated coeff_erase (since := "2026-07-06")] lemma erase_same (p : SkewPolynomial R) (n : ℕ) : coeff (p.erase n) n = 0 := by simp [coeff_erase] -@[simp] +@[deprecated coeff_erase (since := "2026-07-06")] lemma erase_ne (p : SkewPolynomial R) {n i : ℕ} (h : i ≠ n) : coeff (p.erase n) i = coeff p i := by simp [coeff_erase, h] @@ -696,25 +698,27 @@ def update (p : SkewPolynomial R) (n : ℕ) (a : R) : SkewPolynomial R := lemma update_def (p : SkewPolynomial R) (n : ℕ) (a : R) : p.update n a = SkewMonoidAlgebra.update p (ofAdd n) a := rfl +@[simp] lemma coeff_update (p : SkewPolynomial R) (n : ℕ) (a : R) : - (p.update n a).coeff = Function.update p.coeff n a := - SkewMonoidAlgebra.coeff_update _ _ _ + (p.update n a).coeff = Function.update p.coeff n a := by + ext; simp [coeff, update]; rfl +@[deprecated coeff_update (since := "2026-07-06")] lemma coeff_update_apply (p : SkewPolynomial R) (n : ℕ) (a : R) (i : ℕ) : (p.update n a).coeff i = if i = n then a else p.coeff i := SkewMonoidAlgebra.coeff_update_apply _ _ _ _ -@[simp] +@[deprecated coeff_update (since := "2026-07-06")] lemma coeff_update_same (p : SkewPolynomial R) (n : ℕ) (a : R) : (p.update n a).coeff n = a := by rw [p.coeff_update_apply, if_pos rfl] +@[deprecated coeff_update (since := "2026-07-06")] lemma coeff_update_ne (p : SkewPolynomial R) {n i : ℕ} (a : R) (h : i ≠ n) : (p.update n a).coeff i = p.coeff i := by rw [p.coeff_update_apply, if_neg h] @[simp] lemma update_zero_eq_erase (p : SkewPolynomial R) (n : ℕ) : p.update n 0 = p.erase n := by - ext - rw [coeff_update_apply, coeff_erase] + ext; simp [Function.update_apply] lemma support_update (p : SkewPolynomial R) (n : ℕ) (a : R) [DecidableEq R] : support (p.update n a) = if a = 0 then p.support.erase n else insert n p.support := by From ed0d70fdcde71d335acd1613d5fa86e9db419963 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:06:14 +0000 Subject: [PATCH 0679/1300] chore: remove redundant `open scoped Classical` (#41423) This PR removes all redundant/unused `open scoped Classical in`. Furthermore, if the `open scoped Classical` is only needed for the proof of a declaration, it moves it there (and convert it to `classical` when in tactic mode). Excludes MathlibTest. This was done with a script bruteforcing everything, made by Claude code. Only thing remaining would be to check if all `classical` are really needed, but there are quite a lot of them (>3k). Co-authored-by: Batixx --- Archive/Imo/Imo1998Q2.lean | 1 - Mathlib/Analysis/Normed/Lp/ProdLp.lean | 3 -- .../Extremal/RuzsaSzemeredi.lean | 5 +-- Mathlib/Combinatorics/SimpleGraph/Clique.lean | 5 +-- Mathlib/FieldTheory/Perfect.lean | 1 - .../PurelyInseparable/Exponent.lean | 1 + Mathlib/Geometry/Manifold/ChartedSpace.lean | 1 - Mathlib/GroupTheory/Coxeter/Length.lean | 6 ++-- Mathlib/GroupTheory/FreeAbelianGroup.lean | 6 ++-- Mathlib/GroupTheory/Perm/ViaEmbedding.lean | 18 +++++----- Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 1 - .../Function/L1Space/Integrable.lean | 6 ++-- .../MeasureTheory/Function/SimpleFunc.lean | 35 ++++++++++--------- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 1 - .../Measure/Typeclasses/SFinite.lean | 12 +++---- Mathlib/MeasureTheory/SetSemiring.lean | 2 -- .../RamificationInertia/Basic.lean | 11 ------ .../DedekindDomain/AdicValuation.lean | 1 - .../DedekindDomain/Factorization.lean | 13 +------ .../DedekindDomain/Ideal/Lemmas.lean | 2 -- .../Spectrum/Maximal/Localization.lean | 6 ++-- .../Profinite/Nobeling/Induction.lean | 2 +- .../Category/Profinite/Nobeling/Span.lean | 1 - .../Profinite/Nobeling/Successor.lean | 2 +- 24 files changed, 55 insertions(+), 87 deletions(-) diff --git a/Archive/Imo/Imo1998Q2.lean b/Archive/Imo/Imo1998Q2.lean index 2badc27f504822..8767c5419d519e 100644 --- a/Archive/Imo/Imo1998Q2.lean +++ b/Archive/Imo/Imo1998Q2.lean @@ -98,7 +98,6 @@ def A : Finset (AgreedTriple C J) := Finset.univ.filter @fun (a : AgreedTriple C J) => (a.judgePair.Agree r a.contestant ∧ a.judgePair.Distinct) -open scoped Classical in theorem A_maps_to_offDiag_judgePair (a : AgreedTriple C J) : a ∈ A r → a.judgePair ∈ Finset.offDiag (@Finset.univ J _) := by simp [A, Finset.mem_offDiag] diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 46c7a52ff50c8a..7f3db78937ac48 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -162,7 +162,6 @@ section EDist variable [EDist α] [EDist β] -open scoped Classical in /-- Endowing the space `WithLp p (α × β)` with the `L^p` edistance. We register this instance separate from `WithLp.instProdPseudoEMetric` since the latter requires the type class hypothesis `[Fact (1 ≤ p)]` in order to prove the triangle inequality. @@ -231,7 +230,6 @@ section Dist variable [Dist α] [Dist β] -open scoped Classical in /-- Endowing the space `WithLp p (α × β)` with the `L^p` distance. We register this instance separate from `WithLp.instProdPseudoMetricSpace` since the latter requires the type class hypothesis `[Fact (1 ≤ p)]` in order to prove the triangle inequality. @@ -268,7 +266,6 @@ section Norm variable [Norm α] [Norm β] -open scoped Classical in /-- Endowing the space `WithLp p (α × β)` with the `L^p` norm. We register this instance separate from `WithLp.instProdSeminormedAddCommGroup` since the latter requires the type class hypothesis `[Fact (1 ≤ p)]` in order to prove the triangle inequality. diff --git a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean index 295e9e0dbaa35e..3d79d4e756596a 100644 --- a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean +++ b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean @@ -52,8 +52,9 @@ noncomputable def ruzsaSzemerediNumber : ℕ := by exact Nat.findGreatest (fun m ↦ ∃ (G : SimpleGraph α) (_ : DecidableRel G.Adj), #(G.cliqueFinset 3) = m ∧ G.LocallyLinear) ((card α).choose 3) -open scoped Classical in -lemma ruzsaSzemerediNumber_le : ruzsaSzemerediNumber α ≤ (card α).choose 3 := Nat.findGreatest_le _ +lemma ruzsaSzemerediNumber_le : ruzsaSzemerediNumber α ≤ (card α).choose 3 := by + classical + exact Nat.findGreatest_le _ lemma ruzsaSzemerediNumber_spec : ∃ (G : SimpleGraph α) (_ : DecidableRel G.Adj), diff --git a/Mathlib/Combinatorics/SimpleGraph/Clique.lean b/Mathlib/Combinatorics/SimpleGraph/Clique.lean index 91c10f7adc191f..e8dd715e3ea3be 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Clique.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Clique.lean @@ -549,8 +549,9 @@ lemma CliqueFree.mem_of_sup_edge_isNClique {x y : α} {t : Finset α} {n : ℕ} open scoped Classical in /-- Adding an edge increases the clique number by at most one. -/ protected theorem CliqueFree.sup_edge (h : G.CliqueFree n) (v w : α) : - (G ⊔ edge v w).CliqueFree (n + 1) := - fun _ hs ↦ (hs.erase_of_sup_edge_of_mem <| + (G ⊔ edge v w).CliqueFree (n + 1) := by + classical + exact fun _ hs ↦ (hs.erase_of_sup_edge_of_mem <| (h.mono n.le_succ).mem_of_sup_edge_isNClique hs).not_cliqueFree h lemma IsNClique.exists_not_adj_of_cliqueFree_succ (hc : G.IsNClique n s) diff --git a/Mathlib/FieldTheory/Perfect.lean b/Mathlib/FieldTheory/Perfect.lean index d657ea8da75180..b3987a9aa0062b 100644 --- a/Mathlib/FieldTheory/Perfect.lean +++ b/Mathlib/FieldTheory/Perfect.lean @@ -455,7 +455,6 @@ noncomputable def rootsExpandToRoots : (expand R p f).roots.toFinset ↪ f.roots @[simp] theorem rootsExpandToRoots_apply (x) : (rootsExpandToRoots p f x : R) = x ^ p := rfl -open scoped Classical in /-- If `f` is a polynomial over an integral domain `R` of characteristic `p`, then there is a map from the set of roots of `Polynomial.expand R (p ^ n) f` to the set of roots of `f`. It's given by `x ↦ x ^ (p ^ n)`, see `rootsExpandPowToRoots_apply`. -/ diff --git a/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean b/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean index 8f35c2e4719f84..cee815e014b520 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean @@ -118,6 +118,7 @@ open scoped Classical in variable {K} in theorem elemExponent_eq_zero_of_mem_range {a : L} (h : a ∈ (algebraMap K L).range) : elemExponent K a = 0 := by + classical apply (Nat.find_eq_zero _).mpr rw [pow_zero, pow_one] obtain ⟨y, hy⟩ := h diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 778649d7c467bc..b74ab6fd4af0cc 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -523,7 +523,6 @@ def ChartedSpace.sum_of_nonempty [Nonempty H] : ChartedSpace H (M ⊕ M') where right use ChartedSpace.chartAt x, cm'.chart_mem_atlas x -open scoped Classical in instance ChartedSpace.sum : ChartedSpace H (M ⊕ M') := by by_cases! h : Nonempty H · exact ChartedSpace.sum_of_nonempty diff --git a/Mathlib/GroupTheory/Coxeter/Length.lean b/Mathlib/GroupTheory/Coxeter/Length.lean index 899c36600fabc9..2ddaecacc15999 100644 --- a/Mathlib/GroupTheory/Coxeter/Length.lean +++ b/Mathlib/GroupTheory/Coxeter/Length.lean @@ -90,9 +90,9 @@ theorem exists_isReduced (w : W) : ∃ ω : List B, cs.IsReduced ω ∧ w = π @[deprecated (since := "2026-03-25")] alias exists_reduced_word := exists_isReduced @[deprecated (since := "2026-03-25")] alias exists_reduced_word' := exists_isReduced -open scoped Classical in -theorem length_wordProd_le (ω : List B) : ℓ (π ω) ≤ ω.length := - Nat.find_min' (cs.exists_word_with_prod (π ω)) ⟨ω, rfl, rfl⟩ +theorem length_wordProd_le (ω : List B) : ℓ (π ω) ≤ ω.length := by + classical + exact Nat.find_min' (cs.exists_word_with_prod (π ω)) ⟨ω, rfl, rfl⟩ @[simp] theorem length_one : ℓ (1 : W) = 0 := Nat.eq_zero_of_le_zero (cs.length_wordProd_le []) diff --git a/Mathlib/GroupTheory/FreeAbelianGroup.lean b/Mathlib/GroupTheory/FreeAbelianGroup.lean index 428433cd3c1388..cabbd53143f759 100644 --- a/Mathlib/GroupTheory/FreeAbelianGroup.lean +++ b/Mathlib/GroupTheory/FreeAbelianGroup.lean @@ -146,9 +146,9 @@ end lift section -open scoped Classical in -theorem of_injective : Function.Injective (of : α → FreeAbelianGroup α) := - fun x y hoxy ↦ Classical.by_contradiction fun hxy : x ≠ y ↦ +theorem of_injective : Function.Injective (of : α → FreeAbelianGroup α) := by + classical + exact fun x y hoxy ↦ Classical.by_contradiction fun hxy : x ≠ y ↦ let f : FreeAbelianGroup α →+ ℤ := lift fun z ↦ if x = z then (1 : ℤ) else 0 have hfx1 : f (of x) = 1 := (lift_apply_of _ _).trans <| if_pos rfl have hfy1 : f (of y) = 1 := hoxy ▸ hfx1 diff --git a/Mathlib/GroupTheory/Perm/ViaEmbedding.lean b/Mathlib/GroupTheory/Perm/ViaEmbedding.lean index 45a830398c0625..a4426f18a48311 100644 --- a/Mathlib/GroupTheory/Perm/ViaEmbedding.lean +++ b/Mathlib/GroupTheory/Perm/ViaEmbedding.lean @@ -29,13 +29,13 @@ open scoped Classical in noncomputable def viaEmbedding : Perm β := extendDomain e (ofInjective ι.1 ι.2) -open scoped Classical in -theorem viaEmbedding_apply (x : α) : e.viaEmbedding ι (ι x) = ι (e x) := - extendDomain_apply_image e (ofInjective ι.1 ι.2) x +theorem viaEmbedding_apply (x : α) : e.viaEmbedding ι (ι x) = ι (e x) := by + classical + exact extendDomain_apply_image e (ofInjective ι.1 ι.2) x -open scoped Classical in -theorem viaEmbedding_apply_of_notMem (x : β) (hx : x ∉ Set.range ι) : e.viaEmbedding ι x = x := - extendDomain_apply_not_subtype e (ofInjective ι.1 ι.2) hx +theorem viaEmbedding_apply_of_notMem (x : β) (hx : x ∉ Set.range ι) : e.viaEmbedding ι x = x := by + classical + exact extendDomain_apply_not_subtype e (ofInjective ι.1 ι.2) hx open scoped Classical in /-- `viaEmbedding` as a group homomorphism -/ @@ -45,9 +45,9 @@ noncomputable def viaEmbeddingHom : Perm α →* Perm β := theorem viaEmbeddingHom_apply : viaEmbeddingHom ι e = viaEmbedding e ι := rfl -open scoped Classical in -theorem viaEmbeddingHom_injective : Function.Injective (viaEmbeddingHom ι) := - extendDomainHom_injective (ofInjective ι.1 ι.2) +theorem viaEmbeddingHom_injective : Function.Injective (viaEmbeddingHom ι) := by + classical + exact extendDomainHom_injective (ofInjective ι.1 ι.2) end Perm diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index ecba99c0e53472..8926b75a69fe96 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -257,7 +257,6 @@ theorem LinearMap.exists_leftInverse_of_injective (f : V →ₗ[K] V') (hf_inj : rw [Basis.ofVectorSpace_apply_self, fb_eq, hC.constr_basis] exact leftInverse_invFun (LinearMap.ker_eq_bot.1 hf_inj) _ -open scoped Classical in /-- The left inverse of `f : E →ₗ[𝕜] F`. If `f` is not injective, then we use the junk value `0`. -/ diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 24c15da88228dd..cc312fd5c05404 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -339,10 +339,10 @@ theorem Integrable.to_average {f : α → ε} (h : Integrable f μ) : Integrable · apply h.smul_measure simpa -open scoped Classical in theorem integrable_average [IsFiniteMeasure μ] {f : α → ε} : - Integrable f ((μ univ)⁻¹ • μ) ↔ Integrable f μ := - (eq_or_ne μ 0).by_cases (fun h => by simp [h]) fun h => + Integrable f ((μ univ)⁻¹ • μ) ↔ Integrable f μ := by + classical + exact (eq_or_ne μ 0).by_cases (fun h => by simp [h]) fun h => integrable_smul_measure (ENNReal.inv_ne_zero.2 <| by finiteness) (ENNReal.inv_ne_top.2 <| mt Measure.measure_univ_eq_zero.1 h) diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index 310be420f857eb..e672003be67e07 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -215,11 +215,11 @@ theorem piecewise_univ (f g : α →ₛ β) : piecewise univ MeasurableSet.univ theorem piecewise_empty (f g : α →ₛ β) : piecewise ∅ MeasurableSet.empty f g = g := coe_injective <| by simp -open scoped Classical in @[simp] theorem piecewise_same (f : α →ₛ β) {s : Set α} (hs : MeasurableSet s) : - piecewise s hs f f = f := - coe_injective <| Set.piecewise_same _ _ + piecewise s hs f f = f := by + classical + exact coe_injective <| Set.piecewise_same _ _ theorem support_indicator [Zero β] {s : Set α} (hs : MeasurableSet s) (f : α →ₛ β) : Function.support (f.piecewise s hs (SimpleFunc.const α 0)) = s ∩ Function.support f := @@ -674,10 +674,11 @@ lemma mk_le_mk {f g : α → β} {hf hg hf' hg'} : mk f hf hf' ≤ mk g hg hg' @[simp, gcongr] lemma mk_lt_mk {f g : α → β} {hf hg hf' hg'} : mk f hf hf' < mk g hg hg' ↔ f < g := Iff.rfl -open scoped Classical in @[gcongr only] lemma piecewise_mono (hf : ∀ a ∈ s, f₁ a ≤ f₂ a) (hg : ∀ a ∉ s, g₁ a ≤ g₂ a) : - piecewise s hs f₁ g₁ ≤ piecewise s hs f₂ g₂ := Set.piecewise_mono hf hg + piecewise s hs f₁ g₁ ≤ piecewise s hs f₂ g₂ := by + classical + exact Set.piecewise_mono hf hg end Preorder @@ -751,10 +752,10 @@ theorem restrict_univ (f : α →ₛ β) : restrict f univ = f := by simp [restr @[simp] theorem restrict_empty (f : α →ₛ β) : restrict f ∅ = 0 := by simp [restrict] -open scoped Classical in theorem map_restrict_of_zero [Zero γ] {g : β → γ} (hg : g 0 = 0) (f : α →ₛ β) (s : Set α) : - (f.restrict s).map g = (f.map g).restrict s := - ext fun x => + (f.restrict s).map g = (f.map g).restrict s := by + classical + exact ext fun x => if hs : MeasurableSet s then by simp [hs, Set.indicator_comp_of_zero hg] else by simp [restrict_of_not_measurable hs, hg] @@ -781,19 +782,19 @@ theorem mem_restrict_range {r : β} {s : Set α} {f : α →ₛ β} (hs : Measur r ∈ (restrict f s).range ↔ r = 0 ∧ s ≠ univ ∨ r ∈ f '' s := by rw [← Finset.mem_coe, coe_range, coe_restrict _ hs, mem_range_indicator] -open scoped Classical in theorem mem_image_of_mem_range_restrict {r : β} {s : Set α} {f : α →ₛ β} - (hr : r ∈ (restrict f s).range) (h0 : r ≠ 0) : r ∈ f '' s := - if hs : MeasurableSet s then by simpa [mem_restrict_range hs, h0, -mem_range] using hr + (hr : r ∈ (restrict f s).range) (h0 : r ≠ 0) : r ∈ f '' s := by + classical + exact if hs : MeasurableSet s then by simpa [mem_restrict_range hs, h0, -mem_range] using hr else by rw [restrict_of_not_measurable hs] at hr exact (h0 <| eq_zero_of_mem_range_zero hr).elim -open scoped Classical in @[gcongr, mono] theorem restrict_mono [Preorder β] (s : Set α) {f g : α →ₛ β} (H : f ≤ g) : - f.restrict s ≤ g.restrict s := - if hs : MeasurableSet s then fun x => by + f.restrict s ≤ g.restrict s := by + classical + exact if hs : MeasurableSet s then fun x => by simp only [coe_restrict _ hs, indicator_le_indicator (H x)] else by simp only [restrict_of_not_measurable hs, le_refl] @@ -1030,10 +1031,10 @@ theorem lintegral_sum {m : MeasurableSpace α} {ι} (f : α →ₛ ℝ≥0∞) ( ENNReal.tsum_mul_left] apply ENNReal.tsum_comm -open scoped Classical in theorem restrict_lintegral (f : α →ₛ ℝ≥0∞) {s : Set α} (hs : MeasurableSet s) : - (restrict f s).lintegral μ = ∑ r ∈ f.range, r * μ (f ⁻¹' {r} ∩ s) := - calc + (restrict f s).lintegral μ = ∑ r ∈ f.range, r * μ (f ⁻¹' {r} ∩ s) := by + classical + exact calc (restrict f s).lintegral μ = ∑ r ∈ f.range, r * μ (restrict f s ⁻¹' {r}) := lintegral_eq_of_subset _ fun x hx => if hxs : x ∈ s then fun _ => by diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index 5d666560eba459..abbd8b02fc8ddc 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -76,7 +76,6 @@ lemma isOpen_Iotop [TopologicalSpace R] [OrderTopology R] (a b : R) : IsOpen (Io simp [this, isOpen_Ioi] · simp [isOpen_Ioo] -open scoped Classical in /-- `botSet` is the set of all bottom elements. -/ def botSet : Set R := {x | IsBot x} diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean index 2bcc77442bb711..4be87e7cb30e9e 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean @@ -148,15 +148,15 @@ open scoped Classical in noncomputable def spanningSetsIndex (μ : Measure α) [SigmaFinite μ] (x : α) : ℕ := Nat.find <| iUnion_eq_univ_iff.1 (iUnion_spanningSets μ) x -open scoped Classical in theorem measurableSet_spanningSetsIndex (μ : Measure α) [SigmaFinite μ] : - Measurable (spanningSetsIndex μ) := - measurable_find _ <| measurableSet_spanningSets μ + Measurable (spanningSetsIndex μ) := by + classical + exact measurable_find _ <| measurableSet_spanningSets μ -open scoped Classical in theorem preimage_spanningSetsIndex_singleton (μ : Measure α) [SigmaFinite μ] (n : ℕ) : - spanningSetsIndex μ ⁻¹' {n} = disjointed (spanningSets μ) n := - preimage_find_eq_disjointed _ _ _ + spanningSetsIndex μ ⁻¹' {n} = disjointed (spanningSets μ) n := by + classical + exact preimage_find_eq_disjointed _ _ _ theorem spanningSetsIndex_eq_iff (μ : Measure α) [SigmaFinite μ] {x : α} {n : ℕ} : spanningSetsIndex μ x = n ↔ x ∈ disjointed (spanningSets μ) n := by diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 67d07b423025bf..74d5c72231956c 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -148,7 +148,6 @@ theorem isSetRing_supClosure (hC : IsSetSemiring C) : IsSetRing (supClosure C) w section disjointOfDiff -open scoped Classical in /-- In a semi-ring of sets `C`, for all sets `s, t ∈ C`, `s \ t` is equal to a disjoint union of finitely many sets in `C`. The finite set of sets in the union is not unique, but this definition gives an arbitrary `Finset (Set α)` that satisfies the equality. @@ -291,7 +290,6 @@ lemma exists_disjoint_finset_sdiff_eq (hC : IsSetSemiring C) (hs : s ∈ C) (hI @[deprecated (since := "2026-06-03")] alias exists_disjoint_finset_diff_eq := exists_disjoint_finset_sdiff_eq -open scoped Classical in /-- In a semiring of sets `C`, for all set `s ∈ C` and finite set of sets `I ⊆ C`, `disjointOfDiffUnion` is a finite set of sets in `C` such that `s \ ⋃₀ I = ⋃₀ (hC.disjointOfDiffUnion hs I hI)`. diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 18009f800fe663..95df6e14862ac7 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -491,39 +491,32 @@ section FactorsMap variable [IsDedekindDomain S] -open scoped Classical in theorem Factors.ne_bot (P : (factors (map (algebraMap R S) p)).toFinset) : (P : Ideal S) ≠ ⊥ := (prime_of_factor _ (Multiset.mem_toFinset.mp P.2)).ne_zero -open scoped Classical in instance Factors.isPrime (P : (factors (map (algebraMap R S) p)).toFinset) : IsPrime (P : Ideal S) := Ideal.isPrime_of_prime (prime_of_factor _ (Multiset.mem_toFinset.mp P.2)) -open scoped Classical in theorem Factors.ramificationIdx_ne_zero (P : (factors (map (algebraMap R S) p)).toFinset) : ramificationIdx' p P.1 ≠ 0 := IsDedekindDomain.ramificationIdx'_ne_zero (ne_zero_of_mem_factors (Multiset.mem_toFinset.mp P.2)) (Factors.isPrime p P) (Ideal.le_of_dvd (dvd_of_mem_factors (Multiset.mem_toFinset.mp P.2))) -open scoped Classical in instance Factors.fact_ramificationIdx_neZero (P : (factors (map (algebraMap R S) p)).toFinset) : NeZero (ramificationIdx' p P.1) := ⟨Factors.ramificationIdx_ne_zero p P⟩ attribute [local instance] Quotient.algebraQuotientOfRamificationIdxNeZero -open scoped Classical in instance Factors.isScalarTower (P : (factors (map (algebraMap R S) p)).toFinset) : IsScalarTower R (R ⧸ p) (S ⧸ (P : Ideal S)) := IsScalarTower.of_algebraMap_eq' rfl -open scoped Classical in instance Factors.liesOver [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : P.1.LiesOver p := ⟨(comap_eq_of_scalar_tower_quotient (algebraMap (R ⧸ p) (S ⧸ P.1)).injective).symm⟩ -open scoped Classical in theorem Factors.finrank_pow_ramificationIdx [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : finrank (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) = @@ -531,7 +524,6 @@ theorem Factors.finrank_pow_ramificationIdx [p.IsMaximal] rw [finrank_prime_pow_ramificationIdx, inertiaDeg'_algebraMap] exacts [Factors.ne_bot p P, NeZero.ne _] -open scoped Classical in instance Factors.finiteDimensional_quotient_pow [Module.Finite R S] [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : FiniteDimensional (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) := by @@ -541,7 +533,6 @@ instance Factors.finiteDimensional_quotient_pow [Module.Finite R S] [p.IsMaximal universe w -open scoped Classical in /-- **Chinese remainder theorem** for a ring of integers: if the prime ideal `p : Ideal R` factors in `S` as `∏ i, P i ^ e i`, then `S ⧸ I` factors as `Π i, R ⧸ (P i ^ e i)`. -/ noncomputable def Factors.piQuotientEquiv (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) : @@ -568,7 +559,6 @@ theorem Factors.piQuotientEquiv_map (p : Ideal R) (hp : map (algebraMap R S) p variable (S) -open scoped Classical in /-- **Chinese remainder theorem** for a ring of integers: if the prime ideal `p : Ideal R` factors in `S` as `∏ i, P i ^ e i`, then `S ⧸ I` factors `R ⧸ I`-linearly as `Π i, R ⧸ (P i ^ e i)`. -/ @@ -588,7 +578,6 @@ variable (K L : Type*) [Field K] [Field L] [IsDedekindDomain R] [Algebra R K] [I [Algebra S L] [IsFractionRing S L] [Algebra K L] [Algebra R L] [IsScalarTower R S L] [IsScalarTower R K L] [Module.Finite R S] -open scoped Classical in /-- The **fundamental identity** of ramification index `e` and inertia degree `f`: for `P` ranging over the primes lying over `p`, `∑ P, e P * f P = [Frac(S) : Frac(R)]`; here `S` is a finite `R`-module (and thus `Frac(S) : Frac(R)` is a finite extension) and `p` diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index f3cb0b5d1c25ae..f7949de0bbed4a 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -91,7 +91,6 @@ theorem intValuationDef_if_pos {r : R} (hr : r = 0) : v.intValuationDef r = 0 := theorem intValuationDef_zero : v.intValuationDef 0 = 0 := if_pos rfl -open scoped Classical in theorem intValuationDef_if_neg {r : R} (hr : r ≠ 0) : v.intValuationDef r = exp (-(Associates.mk v.asIdeal).count (Associates.mk (Ideal.span {r} : Ideal R)).factors : ℤ) := diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 3481ab85dc8195..c25fa26cb9ebc7 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -66,7 +66,6 @@ variable {R : Type*} [CommRing R] {K : Type*} [Field K] [Algebra R K] [IsFractio variable [IsDedekindDomain R] (v : HeightOneSpectrum R) -open scoped Classical in /-- Given a maximal ideal `v` and an ideal `I` of `R`, `maxPowDividing` returns the maximal power of `v` dividing `I`. -/ def IsDedekindDomain.HeightOneSpectrum.maxPowDividing (I : Ideal R) : Ideal R := @@ -92,7 +91,6 @@ theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) : intro v w hvw exact Subtype.coe_injective (HeightOneSpectrum.ext (by simpa using hvw)) -open scoped Classical in /-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/ theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) : @@ -108,7 +106,6 @@ theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) : namespace Ideal -open scoped Classical in /-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that `v^(val_v(I))` is not the unit ideal. -/ @[fun_prop] @@ -126,7 +123,6 @@ theorem hasFiniteMulSupport {I : Ideal R} (hI : I ≠ 0) : @[deprecated (since := "2026-03-03")] alias finite_mulSupport := hasFiniteMulSupport -open scoped Classical in /-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that `v^(val_v(I))`, regarded as a fractional ideal, is not `(1)`. -/ @[fun_prop] @@ -139,7 +135,6 @@ theorem hasFiniteMulSupport_coe {I : Ideal R} (hI : I ≠ 0) : @[deprecated (since := "2026-03-03")] alias finite_mulSupport_coe := hasFiniteMulSupport_coe -open scoped Classical in /-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that `v^-(val_v(I))` is not the unit ideal. -/ @[fun_prop] @@ -152,11 +147,11 @@ theorem hasFiniteMulSupport_inv {I : Ideal R} (hI : I ≠ 0) : @[deprecated (since := "2026-03-03")] alias finite_mulSupport_inv := hasFiniteMulSupport_inv -open scoped Classical in /-- For every nonzero ideal `I` of `v`, `v^(val_v(I) + 1)` does not divide `∏_v v^(val_v(I))`. -/ theorem finprod_not_dvd (I : Ideal R) (hI : I ≠ 0) : ¬v.asIdeal ^ ((Associates.mk v.asIdeal).count (Associates.mk I).factors + 1) ∣ ∏ᶠ v : HeightOneSpectrum R, v.maxPowDividing I := by + classical have hf := hasFiniteMulSupport hI have h_ne_zero : v.maxPowDividing I ≠ 0 := pow_ne_zero _ v.ne_bot rw [← mul_finprod_cond_ne v hf, pow_add, pow_one, finprod_cond_ne _ _ hf] @@ -183,7 +178,6 @@ theorem Associates.finprod_ne_zero (I : Ideal R) : namespace Ideal -open scoped Classical in /-- The multiplicity of `v` in `∏_v v^(val_v(I))` equals `val_v(I)`. -/ theorem finprod_count (I : Ideal R) (hI : I ≠ 0) : (Associates.mk v.asIdeal).count (Associates.mk (∏ᶠ v : HeightOneSpectrum R, v.maxPowDividing I)).factors = @@ -231,7 +225,6 @@ theorem iInf_maxPowDividing_eq {I : Ideal R} (h0 : I ≠ 0) : variable (K) -open scoped Classical in /-- The ideal `I` equals the finprod `∏_v v^(val_v(I))`, when both sides are regarded as fractional ideals of `R`. -/ theorem finprod_heightOneSpectrum_factorization_coe {I : Ideal R} (hI : I ≠ 0) : @@ -251,7 +244,6 @@ namespace FractionalIdeal open Int IsLocalization open Ideal in -open scoped Classical in /-- If `I` is a nonzero fractional ideal, `a ∈ R`, and `J` is an ideal of `R` such that `I = a⁻¹J`, then `I` is equal to the product `∏_v v^(val_v(J) - val_v(a))`. -/ theorem finprod_heightOneSpectrum_factorization {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) {a : R} @@ -271,7 +263,6 @@ theorem finprod_heightOneSpectrum_factorization {I : FractionalIdeal R⁰ K} (hI intro v rw [← zpow_add₀ ((@coeIdeal_ne_zero R _ K _ _ _ _).mpr v.ne_bot), sub_eq_add_neg] -open scoped Classical in /-- For a nonzero `k = r/s ∈ K`, the fractional ideal `(k)` is equal to the product `∏_v v^(val_v(r) - val_v(s))`. -/ theorem finprod_heightOneSpectrum_factorization_principal_fraction {n : R} (hn : n ≠ 0) (d : ↥R⁰) : @@ -541,7 +532,6 @@ theorem count_finprod (exps : HeightOneSpectrum R → ℤ) rw [mem_mulSupport, h, zpow_zero] at hv exact hv (Eq.refl 1) -open scoped Classical in theorem count_coe {J : Ideal R} (hJ : J ≠ 0) : count K v J = (Associates.mk v.asIdeal).count (Associates.mk J).factors := by rw [count_well_defined K (J := J) (a := 1), Ideal.span_singleton_one, sub_eq_self, @@ -577,7 +567,6 @@ theorem finprod_heightOneSpectrum_factorization' {I : FractionalIdeal R⁰ K} (h variable {K} -open scoped Classical in /-- If `I ≠ 0`, then `val_v(I) = 0` for all but finitely many maximal ideals of `R`. -/ theorem finite_factors' {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) {a : R} {J : Ideal R} (haJ : I = spanSingleton R⁰ ((algebraMap R K) a)⁻¹ * ↑J) : diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index 9ee3f36a59bbc5..e5054d4f776d69 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -923,7 +923,6 @@ def quotientEquivPiOfProdEq {ι : Type*} [Fintype ι] (I : Ideal R) (P : ι → HeightOneSpectrum.quotientEquivPiOfProdEq I (fun i ↦ ⟨P i, (isPrime_of_prime (prime i)), (prime i).ne_zero⟩) e (by grind) prod_eq -open scoped Classical in /-- **Chinese remainder theorem** for a Dedekind domain: `R ⧸ I` factors as `Π i, R ⧸ (P i ^ e i)`, where `P i` ranges over the prime factors of `I` and `e i` over the multiplicities. -/ def quotientEquivPiFactors {I : Ideal R} (hI : I ≠ ⊥) : @@ -1162,7 +1161,6 @@ variable {A : Type*} [CommRing A] {p : Ideal A} (hpb : p ≠ ⊥) [hpm : p.IsMax namespace IsDedekindDomain -open scoped Classical in variable (p) in /-- The finite set of all prime factors of the pushforward of `p`. -/ noncomputable abbrev primesOverFinset : Finset (Ideal B) := diff --git a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean index 70e090dc94f605..040355ebc361fc 100644 --- a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean +++ b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean @@ -176,9 +176,9 @@ localizations at maximal ideals. -/ def piLocalizationToMaximal : PiLocalization R →ₐ[R] MaximalSpectrum.PiLocalization R := AlgHom.pi fun I ↦ Pi.evalAlgHom _ _ I.toPrimeSpectrum -open scoped Classical in -theorem piLocalizationToMaximal_surjective : Function.Surjective (piLocalizationToMaximal R) := - fun r ↦ ⟨fun I ↦ if h : I.1.IsMaximal then r ⟨_, h⟩ else 0, funext fun _ ↦ dif_pos _⟩ +theorem piLocalizationToMaximal_surjective : Function.Surjective (piLocalizationToMaximal R) := by + classical + exact fun r ↦ ⟨fun I ↦ if h : I.1.IsMaximal then r ⟨_, h⟩ else 0, funext fun _ ↦ dif_pos _⟩ variable {R} diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Induction.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Induction.lean index 4289fc17787723..2989eac53e537e 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Induction.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Induction.lean @@ -119,9 +119,9 @@ open scoped Classical in noncomputable def Nobeling.ι : S → ({C : Set S // IsClopen C} → Bool) := fun s C => decide (s ∈ C.1) -open scoped Classical in /-- The map `Nobeling.ι` is a closed embedding. -/ theorem Nobeling.isClosedEmbedding : IsClosedEmbedding (Nobeling.ι S) := by + classical apply Continuous.isClosedEmbedding · dsimp +unfoldPartialApp [ι] refine continuous_pi ?_ diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean index e558f4c0b1caf6..85b6d679dd112a 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean @@ -74,7 +74,6 @@ def spanFinBasis (x : π C (· ∈ s)) : LocallyConstant (π C (· ∈ s)) ℤ w haveI : DiscreteTopology (π C (· ∈ s)) := Finite.instDiscreteTopology IsLocallyConstant.of_discrete _ -open scoped Classical in theorem spanFinBasis.span : ⊤ ≤ Submodule.span ℤ (Set.range (spanFinBasis C s)) := by intro f _ rw [Finsupp.mem_span_range_iff_exists_finsupp] diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean index 20805f5b1e1c11..4b2e9628bc9211 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean @@ -234,9 +234,9 @@ theorem C1_projOrd {x : I → Bool} (hx : x ∈ C1 C ho) : SwapTrue o (Proj (ord exact (hsC h').symm include hC in -open scoped Classical in theorem CC_exact {f : LocallyConstant C ℤ} (hf : Linear_CC' C hsC ho f = 0) : ∃ y, πs C o y = f := by + classical dsimp [Linear_CC', Linear_CC'₀, Linear_CC'₁] at hf simp only [sub_eq_zero, ← LocallyConstant.coe_inj] at hf let C₀C : C0 C ho → C := fun x ↦ ⟨x.val, x.prop.1⟩ From 5d0719050a6ad4156562303be03e533913dc0591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 8 Jul 2026 10:17:12 +0000 Subject: [PATCH 0680/1300] feat(Topology/UniformSpace): tag `UniformContinuous` with `@[fun_prop]` (#41019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and tag all the relevant lemmas (found via Loogle). Do the same for the other function properties. The precise list of tagged function properties is `UniformContinuous`, `UniformContinuousOn`, `IsUniformInducing`, `IsUniformEmbedding`, `UniformContinuous₂`. From MeanFourier --- Mathlib/Analysis/Complex/Basic.lean | 3 +++ Mathlib/Analysis/Normed/Group/AddTorsor.lean | 2 ++ Mathlib/Analysis/Normed/Group/Uniform.lean | 4 +-- Mathlib/Analysis/Normed/Lp/PiLp.lean | 2 ++ Mathlib/Analysis/Normed/Lp/ProdLp.lean | 3 +++ .../Function/SimpleFuncDenseLp.lean | 1 + .../Topology/Algebra/IsUniformGroup/Defs.lean | 10 +++---- .../Algebra/Module/Multilinear/Topology.lean | 5 ++++ .../Algebra/SeparationQuotient/Section.lean | 3 +++ .../Topology/Algebra/UniformMulAction.lean | 5 +++- .../Topology/ContinuousMap/Bounded/Basic.lean | 2 ++ .../UniformSpace/AbstractCompletion.lean | 9 +++++++ Mathlib/Topology/UniformSpace/Basic.lean | 27 ++++++++++++++++--- Mathlib/Topology/UniformSpace/Completion.lean | 8 ++++++ Mathlib/Topology/UniformSpace/Defs.lean | 10 +++++-- Mathlib/Topology/UniformSpace/Separation.lean | 4 +++ 16 files changed, 84 insertions(+), 14 deletions(-) diff --git a/Mathlib/Analysis/Complex/Basic.lean b/Mathlib/Analysis/Complex/Basic.lean index be3b9d791a5c2b..ded2fe18b25a89 100644 --- a/Mathlib/Analysis/Complex/Basic.lean +++ b/Mathlib/Analysis/Complex/Basic.lean @@ -118,6 +118,7 @@ theorem antilipschitz_equivRealProd : AntilipschitzWith (NNReal.sqrt 2) equivRea AddMonoidHomClass.antilipschitz_of_bound equivRealProdLm fun z ↦ by simpa only [Real.coe_sqrt, NNReal.coe_ofNat] using! norm_le_sqrt_two_mul_max z +@[fun_prop] theorem isUniformEmbedding_equivRealProd : IsUniformEmbedding equivRealProd := antilipschitz_equivRealProd.isUniformEmbedding lipschitz_equivRealProd.uniformContinuous @@ -153,6 +154,7 @@ def reCLM : ℂ →L[ℝ] ℝ := theorem continuous_re : Continuous re := reCLM.continuous +@[fun_prop] lemma uniformContinuous_re : UniformContinuous re := reCLM.uniformContinuous @@ -175,6 +177,7 @@ def imCLM : ℂ →L[ℝ] ℝ := theorem continuous_im : Continuous im := imCLM.continuous +@[fun_prop] lemma uniformContinuous_im : UniformContinuous im := imCLM.uniformContinuous diff --git a/Mathlib/Analysis/Normed/Group/AddTorsor.lean b/Mathlib/Analysis/Normed/Group/AddTorsor.lean index 1a55a304a7024c..4d5acfaea1fa28 100644 --- a/Mathlib/Analysis/Normed/Group/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Group/AddTorsor.lean @@ -222,9 +222,11 @@ theorem LipschitzWith.vsub [PseudoEMetricSpace α] {f g : α → P} {Kf Kg : ℝ _ ≤ Kf * edist x y + Kg * edist x y := add_le_add (hf x y) (hg x y) _ = (Kf + Kg) * edist x y := (add_mul _ _ _).symm +@[fun_prop] theorem uniformContinuous_vadd : UniformContinuous fun x : V × P => x.1 +ᵥ x.2 := (LipschitzWith.prod_fst.vadd LipschitzWith.prod_snd).uniformContinuous +@[fun_prop] theorem uniformContinuous_vsub : UniformContinuous fun x : P × P => x.1 -ᵥ x.2 := (LipschitzWith.prod_fst.vsub LipschitzWith.prod_snd).uniformContinuous diff --git a/Mathlib/Analysis/Normed/Group/Uniform.lean b/Mathlib/Analysis/Normed/Group/Uniform.lean index 63e5d0871fab00..f3b432ea05b8e2 100644 --- a/Mathlib/Analysis/Normed/Group/Uniform.lean +++ b/Mathlib/Analysis/Normed/Group/Uniform.lean @@ -185,11 +185,11 @@ theorem lipschitzWith_one_norm' : LipschitzWith 1 (norm : E → ℝ) := by theorem lipschitzWith_one_nnnorm' : LipschitzWith 1 (NNNorm.nnnorm : E → ℝ≥0) := lipschitzWith_one_norm' -@[to_additive uniformContinuous_norm] +@[to_additive (attr := fun_prop) uniformContinuous_norm] theorem uniformContinuous_norm' : UniformContinuous (norm : E → ℝ) := lipschitzWith_one_norm'.uniformContinuous -@[to_additive uniformContinuous_nnnorm] +@[to_additive (attr := fun_prop) uniformContinuous_nnnorm] theorem uniformContinuous_nnnorm' : UniformContinuous fun a : E => ‖a‖₊ := uniformContinuous_norm'.subtype_mk _ diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index c82470b0c99e0b..29f923f2419acb 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -566,10 +566,12 @@ instance secondCountableTopology [Countable ι] [∀ i, TopologicalSpace (β i)] instance uniformSpace [∀ i, UniformSpace (β i)] : UniformSpace (PiLp p β) := (Pi.uniformSpace β).comap ofLp +@[fun_prop] lemma uniformContinuous_ofLp [∀ i, UniformSpace (β i)] : UniformContinuous (@ofLp p (∀ i, β i)) := uniformContinuous_comap +@[fun_prop] lemma uniformContinuous_toLp [∀ i, UniformSpace (β i)] : UniformContinuous (@toLp p (∀ i, β i)) := uniformContinuous_comap' uniformContinuous_id diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 7f3db78937ac48..739a0034d95587 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -515,9 +515,11 @@ variable [UniformSpace α] [UniformSpace β] instance instProdUniformSpace : UniformSpace (WithLp p (α × β)) := instUniformSpaceProd.comap ofLp +@[fun_prop] lemma prod_uniformContinuous_toLp : UniformContinuous (@toLp p (α × β)) := uniformContinuous_comap' uniformContinuous_id +@[fun_prop] lemma prod_uniformContinuous_ofLp : UniformContinuous (@ofLp p (α × β)) := uniformContinuous_comap @@ -679,6 +681,7 @@ instance instProdSeminormedAddCommGroup [SeminormedAddCommGroup α] [SeminormedA prod_norm_eq_add (zero_lt_one.trans_le h), dist_eq_norm, ← norm_neg_add] rfl +@[fun_prop] lemma isUniformInducing_toLp [PseudoEMetricSpace α] [PseudoEMetricSpace β] : IsUniformInducing (@toLp p (α × β)) := (prod_antilipschitzWith_toLp p α β).isUniformInducing diff --git a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean index 96eff255ca78e7..26cd321dd22ecd 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean @@ -635,6 +635,7 @@ section CoeToLp variable [Fact (1 ≤ p)] +@[fun_prop] protected theorem uniformContinuous : UniformContinuous ((↑) : Lp.simpleFunc E p μ → Lp E p μ) := uniformContinuous_comap diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean index 84a576206c5621..7a8ba9da15ddd5 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean @@ -202,12 +202,12 @@ variable [UniformSpace α] [Group α] [IsUniformGroup α] theorem uniformContinuous_div : UniformContinuous fun p : α × α => p.1 / p.2 := IsUniformGroup.uniformContinuous_div -@[to_additive] +@[to_additive (attr := fun_prop)] theorem UniformContinuous.div [UniformSpace β] {f : β → α} {g : β → α} (hf : UniformContinuous f) (hg : UniformContinuous g) : UniformContinuous fun x => f x / g x := uniformContinuous_div.comp (hf.prodMk hg) -@[to_additive] +@[to_additive (attr := fun_prop)] theorem UniformContinuous.inv [UniformSpace β] {f : β → α} (hf : UniformContinuous f) : UniformContinuous fun x => (f x)⁻¹ := by have : UniformContinuous fun x => 1 / f x := uniformContinuous_const.div hf @@ -217,7 +217,7 @@ theorem UniformContinuous.inv [UniformSpace β] {f : β → α} (hf : UniformCon theorem uniformContinuous_inv : UniformContinuous fun x : α => x⁻¹ := uniformContinuous_id.inv -@[to_additive] +@[to_additive (attr := fun_prop)] theorem UniformContinuous.mul [UniformSpace β] {f : β → α} {g : β → α} (hf : UniformContinuous f) (hg : UniformContinuous g) : UniformContinuous fun x => f x * g x := by have : UniformContinuous fun x => f x / (g x)⁻¹ := hf.div hg.inv @@ -314,7 +314,7 @@ theorem Filter.Tendsto.uniformity_mul_iff_left {ι : Type*} {f g : ι → α × Tendsto (f * g) l (𝓤 α) ↔ Tendsto f l (𝓤 α) := ⟨fun hfg ↦ by simpa using hfg.uniformity_mul hg.uniformity_inv, fun hf ↦ hf.uniformity_mul hg⟩ -@[to_additive UniformContinuous.const_nsmul] +@[to_additive (attr := fun_prop) UniformContinuous.const_nsmul] theorem UniformContinuous.pow_const [UniformSpace β] {f : β → α} (hf : UniformContinuous f) : ∀ n : ℕ, UniformContinuous fun x => f x ^ n | 0 => by @@ -328,7 +328,7 @@ theorem UniformContinuous.pow_const [UniformSpace β] {f : β → α} (hf : Unif theorem uniformContinuous_pow_const (n : ℕ) : UniformContinuous fun x : α => x ^ n := uniformContinuous_id.pow_const n -@[to_additive UniformContinuous.const_zsmul] +@[to_additive (attr := fun_prop) UniformContinuous.const_zsmul] theorem UniformContinuous.zpow_const [UniformSpace β] {f : β → α} (hf : UniformContinuous f) : ∀ n : ℤ, UniformContinuous fun x => f x ^ n | (n : ℕ) => by diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean index 114712b3724e5e..047fedc1e464bc 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean @@ -87,11 +87,13 @@ lemma isEmbedding_toUniformOnFun : ((Π i, E i) →ᵤ[{s | IsVonNBounded 𝕜 s}] F)) := isUniformEmbedding_toUniformOnFun.isEmbedding +@[fun_prop] theorem uniformContinuous_coe_fun [∀ i, ContinuousSMul 𝕜 (E i)] : UniformContinuous (DFunLike.coe : ContinuousMultilinearMap 𝕜 E F → (Π i, E i) → F) := (UniformOnFun.uniformContinuous_toFun sUnion_isVonNBounded_eq_univ).comp isUniformEmbedding_toUniformOnFun.uniformContinuous +@[fun_prop] theorem uniformContinuous_eval_const [∀ i, ContinuousSMul 𝕜 (E i)] (x : Π i, E i) : UniformContinuous fun f : ContinuousMultilinearMap 𝕜 E F ↦ f x := uniformContinuous_pi.1 uniformContinuous_coe_fun x @@ -107,6 +109,7 @@ instance instUniformContinuousConstSMul {M : Type*} haveI := uniformContinuousConstSMul_of_continuousConstSMul M F isUniformEmbedding_toUniformOnFun.uniformContinuousConstSMul fun _ _ ↦ rfl +@[fun_prop] theorem isUniformInducing_postcomp {G : Type*} [AddCommGroup G] [UniformSpace G] [IsUniformAddGroup G] [Module 𝕜 G] (g : F →L[𝕜] G) (hg : IsUniformInducing g) : @@ -155,6 +158,7 @@ variable (𝕜' : Type*) [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜' [∀ i, ContinuousSMul 𝕜 (E i)] set_option backward.isDefEq.respectTransparency false in +@[fun_prop] theorem isUniformEmbedding_restrictScalars : IsUniformEmbedding (restrictScalars 𝕜' : ContinuousMultilinearMap 𝕜 E F → ContinuousMultilinearMap 𝕜' E F) := by @@ -164,6 +168,7 @@ theorem isUniformEmbedding_restrictScalars : convert! isUniformEmbedding_toUniformOnFun using 4 with s exact ⟨fun h ↦ h.extend_scalars _, fun h ↦ h.restrict_scalars _⟩ +@[fun_prop] theorem uniformContinuous_restrictScalars : UniformContinuous (restrictScalars 𝕜' : ContinuousMultilinearMap 𝕜 E F → ContinuousMultilinearMap 𝕜' E F) := diff --git a/Mathlib/Topology/Algebra/SeparationQuotient/Section.lean b/Mathlib/Topology/Algebra/SeparationQuotient/Section.lean index f7b3a297855f13..90f662cd96a6f4 100644 --- a/Mathlib/Topology/Algebra/SeparationQuotient/Section.lean +++ b/Mathlib/Topology/Algebra/SeparationQuotient/Section.lean @@ -78,14 +78,17 @@ section VectorSpaceUniform variable (K E : Type*) [DivisionRing K] [AddCommGroup E] [Module K E] [UniformSpace E] [IsUniformAddGroup E] [ContinuousConstSMul K E] +@[fun_prop] theorem outCLM_isUniformInducing : IsUniformInducing (outCLM K E) := by rw [← isUniformInducing_mk.of_comp_iff, mk_comp_outCLM] exact .id +@[fun_prop] theorem outCLM_isUniformEmbedding : IsUniformEmbedding (outCLM K E) where injective := outCLM_injective K E toIsUniformInducing := outCLM_isUniformInducing K E +@[fun_prop] theorem outCLM_uniformContinuous : UniformContinuous (outCLM K E) := (outCLM_isUniformInducing K E).uniformContinuous diff --git a/Mathlib/Topology/Algebra/UniformMulAction.lean b/Mathlib/Topology/Algebra/UniformMulAction.lean index 8252be5fe6518b..88ca68e321b869 100644 --- a/Mathlib/Topology/Algebra/UniformMulAction.lean +++ b/Mathlib/Topology/Algebra/UniformMulAction.lean @@ -89,7 +89,7 @@ instance (priority := 100) UniformContinuousConstSMul.instContinuousConstSMul variable {M X Y} -@[to_additive] +@[to_additive (attr := fun_prop)] theorem UniformContinuous.const_smul [UniformContinuousConstSMul M X] {f : Y → X} (hf : UniformContinuous f) (c : M) : UniformContinuous (c • f) := (uniformContinuous_const_smul c).comp hf @@ -127,10 +127,12 @@ section Ring variable {R β : Type*} [Ring R] [UniformSpace R] [UniformSpace β] +@[fun_prop] theorem UniformContinuous.const_mul' [UniformContinuousConstSMul R R] {f : β → R} (hf : UniformContinuous f) (a : R) : UniformContinuous fun x ↦ a * f x := hf.const_smul a +@[fun_prop] theorem UniformContinuous.mul_const' [UniformContinuousConstSMul Rᵐᵒᵖ R] {f : β → R} (hf : UniformContinuous f) (a : R) : UniformContinuous fun x ↦ f x * a := hf.const_smul (MulOpposite.op a) @@ -143,6 +145,7 @@ theorem uniformContinuous_mul_right' [UniformContinuousConstSMul Rᵐᵒᵖ R] ( UniformContinuous fun b : R => b * a := uniformContinuous_id.mul_const' _ +@[fun_prop] theorem UniformContinuous.div_const' {R β : Type*} [DivisionRing R] [UniformSpace R] [UniformContinuousConstSMul Rᵐᵒᵖ R] [UniformSpace β] {f : β → R} (hf : UniformContinuous f) (a : R) : diff --git a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean index cd64c8f0b0c001..8ee7a7818b0865 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean @@ -280,6 +280,7 @@ theorem lipschitz_eval_const (x : α) : LipschitzWith 1 fun f : α →ᵇ β => @[deprecated (since := "2025-11-29")] alias lipschitz_evalx := lipschitz_eval_const +@[fun_prop] theorem uniformContinuous_coe : @UniformContinuous (α →ᵇ β) (α → β) _ _ (⇑) := uniformContinuous_pi.2 fun x => (lipschitz_eval_const x).uniformContinuous @@ -392,6 +393,7 @@ theorem lipschitz_comp {G : β → γ} {C : ℝ≥0} (H : LipschitzWith C G) : _ ≤ C * dist f g := by gcongr; apply dist_coe_le_dist /-- The composition operator (in the target) with a Lipschitz map is uniformly continuous. -/ +@[fun_prop] theorem uniformContinuous_comp {G : β → γ} {C : ℝ≥0} (H : LipschitzWith C G) : UniformContinuous (comp G H : (α →ᵇ β) → α →ᵇ γ) := (lipschitz_comp H).uniformContinuous diff --git a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean index a17498f30017f0..53ef3368713f79 100644 --- a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean +++ b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean @@ -94,6 +94,7 @@ theorem closure_range : closure (range ι) = univ := theorem isDenseInducing : IsDenseInducing ι := ⟨pkg.isUniformInducing.isInducing, pkg.dense⟩ +@[fun_prop] theorem uniformContinuous_coe : UniformContinuous ι := IsUniformInducing.uniformContinuous pkg.isUniformInducing @@ -136,6 +137,7 @@ theorem extend_coe [T2Space β] (hf : UniformContinuous f) (a : α) : (pkg.exten variable [CompleteSpace β] +@[fun_prop] theorem uniformContinuous_extend : UniformContinuous (pkg.extend f) := by by_cases hf : UniformContinuous f · rw [pkg.extend_def hf] @@ -147,6 +149,7 @@ theorem uniformContinuous_extend : UniformContinuous (pkg.extend f) := by theorem continuous_extend : Continuous (pkg.extend f) := pkg.uniformContinuous_extend.continuous +@[fun_prop] lemma isUniformInducing_extend (h : IsUniformInducing f) : IsUniformInducing (pkg.extend f) := by rw [extend_def _ h.uniformContinuous] @@ -183,6 +186,7 @@ local notation "map" => pkg.map pkg' variable (f : α → β) +@[fun_prop] theorem uniformContinuous_map : UniformContinuous (map f) := pkg.uniformContinuous_extend @@ -254,6 +258,7 @@ variable (pkg' : AbstractCompletion.{vα'} α) def compare : pkg.space → pkg'.space := pkg.extend pkg'.coe +@[fun_prop] theorem uniformContinuous_compare : UniformContinuous (pkg.compare pkg') := pkg.uniformContinuous_extend @@ -277,9 +282,11 @@ def compareEquiv : pkg.space ≃ᵤ pkg'.space where uniformContinuous_toFun := uniformContinuous_compare _ _ uniformContinuous_invFun := uniformContinuous_compare _ _ +@[fun_prop] theorem uniformContinuous_compareEquiv : UniformContinuous (pkg.compareEquiv pkg') := pkg.uniformContinuous_compare pkg' +@[fun_prop] theorem uniformContinuous_compareEquiv_symm : UniformContinuous (pkg.compareEquiv pkg').symm := pkg'.uniformContinuous_compare pkg @@ -373,6 +380,7 @@ end T0Space variable {f : α → β → γ} variable [CompleteSpace γ] (f) +@[fun_prop] theorem uniformContinuous_extension₂ : UniformContinuous₂ (pkg.extend₂ pkg' f) := by rw [uniformContinuous₂_def, AbstractCompletion.extend₂, uncurry_curry] apply uniformContinuous_extend @@ -399,6 +407,7 @@ local notation f " ∘₂ " g => bicompr f g protected def map₂ (f : α → β → γ) : hatα → hatβ → hatγ := pkg.extend₂ pkg' (pkg''.coe ∘₂ f) +@[fun_prop] theorem uniformContinuous_map₂ (f : α → β → γ) : UniformContinuous₂ (pkg.map₂ pkg' pkg'' f) := AbstractCompletion.uniformContinuous_extension₂ pkg pkg' _ diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index ae6a28fa2f9ae9..17bb184e5be4b0 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -520,10 +520,12 @@ section variable [UniformSpace α] [UniformSpace β] [UniformSpace γ] {f : α → β} {s t : Set α} +@[fun_prop] theorem UniformContinuous.continuous (hf : UniformContinuous f) : Continuous f := continuous_iff_le_induced.mpr <| UniformSpace.toTopologicalSpace_mono <| uniformContinuous_iff_le_comap.1 hf +@[fun_prop] lemma UniformContinuous.uniformContinuousOn (hf : UniformContinuous f) : UniformContinuousOn f s := tendsto_inf_left hf @@ -539,6 +541,7 @@ lemma UniformContinuousOn.congr {f g : α → β} {s : Set α} apply EventuallyEq.filter_mono _ inf_le_right filter_upwards [mem_principal_self _] with ⟨a, b⟩ ⟨ha, hb⟩ using by simp [h ha, h hb] +@[fun_prop] lemma UniformContinuousOn.comp {g : β → γ} {t : Set β} (hg : UniformContinuousOn g t) (hf : UniformContinuousOn f s) (hst : MapsTo f s t) : UniformContinuousOn (g ∘ f) s := by change Tendsto ((fun x ↦ (g x.1, g x.2)) ∘ (fun x ↦ (f x.1, f x.2))) (𝓤 α ⊓ 𝓟 (s ×ˢ s)) (𝓤 γ) @@ -547,6 +550,7 @@ lemma UniformContinuousOn.comp {g : β → γ} {t : Set β} (hg : UniformContinu simp only [tendsto_principal, mem_prod, eventually_principal, and_imp, Prod.forall] exact fun a b ha hb ↦ ⟨hst ha, hst hb⟩ +@[fun_prop] lemma UniformContinuous.comp_uniformContinuousOn {g : β → γ} (hg : UniformContinuous g) (hf : UniformContinuousOn f s) : UniformContinuousOn (g ∘ f) s := (hg.uniformContinuousOn (s := univ)).comp hf (mapsTo_univ _ _) @@ -622,15 +626,19 @@ open Additive Multiplicative instance : UniformSpace (Additive α) := ‹UniformSpace α› instance : UniformSpace (Multiplicative α) := ‹UniformSpace α› +@[fun_prop] theorem uniformContinuous_ofMul : UniformContinuous (ofMul : α → Additive α) := uniformContinuous_id +@[fun_prop] theorem uniformContinuous_toMul : UniformContinuous (toMul : Additive α → α) := uniformContinuous_id +@[fun_prop] theorem uniformContinuous_ofAdd : UniformContinuous (ofAdd : α → Multiplicative α) := uniformContinuous_id +@[fun_prop] theorem uniformContinuous_toAdd : UniformContinuous (toAdd : Multiplicative α → α) := uniformContinuous_id @@ -655,10 +663,12 @@ theorem map_uniformity_set_coe {s : Set α} [UniformSpace α] : map (Prod.map (↑) (↑)) (𝓤 s) = 𝓤 α ⊓ 𝓟 (s ×ˢ s) := by rw [uniformity_setCoe, map_comap, range_prodMap, Subtype.range_val] +@[fun_prop] theorem uniformContinuous_subtype_val {p : α → Prop} [UniformSpace α] : UniformContinuous (Subtype.val : { a : α // p a } → α) := uniformContinuous_comap +@[fun_prop] theorem UniformContinuous.subtype_mk {p : α → Prop} [UniformSpace α] [UniformSpace β] {f : β → α} (hf : UniformContinuous f) (h : ∀ x, p (f x)) : UniformContinuous (fun x => ⟨f x, h x⟩ : β → Subtype p) := @@ -683,6 +693,7 @@ theorem tendsto_of_uniformContinuous_subtype [UniformSpace α] [UniformSpace β] rw [(@map_nhds_subtype_coe_eq_nhds α _ (· ∈ s) a (mem_of_mem_nhds ha) ha).symm] exact tendsto_map' hf.continuous.continuousAt +@[fun_prop] theorem UniformContinuousOn.continuousOn [UniformSpace α] [UniformSpace β] {f : α → β} {s : Set α} (h : UniformContinuousOn f s) : ContinuousOn f s := by rw [uniformContinuousOn_iff_restrict] at h @@ -708,11 +719,11 @@ theorem comap_uniformity_mulOpposite [UniformSpace α] : namespace MulOpposite -@[to_additive] +@[to_additive (attr := fun_prop)] theorem uniformContinuous_unop [UniformSpace α] : UniformContinuous (unop : αᵐᵒᵖ → α) := uniformContinuous_comap -@[to_additive] +@[to_additive (attr := fun_prop)] theorem uniformContinuous_op [UniformSpace α] : UniformContinuous (op : α → αᵐᵒᵖ) := uniformContinuous_comap' uniformContinuous_id @@ -818,16 +829,19 @@ theorem tendsto_prod_uniformity_snd [UniformSpace α] [UniformSpace β] : Tendsto (fun p : (α × β) × α × β => (p.1.2, p.2.2)) (𝓤 (α × β)) (𝓤 β) := le_trans (map_mono inf_le_right) map_comap_le +@[fun_prop] theorem uniformContinuous_fst [UniformSpace α] [UniformSpace β] : UniformContinuous fun p : α × β => p.1 := tendsto_prod_uniformity_fst +@[fun_prop] theorem uniformContinuous_snd [UniformSpace α] [UniformSpace β] : UniformContinuous fun p : α × β => p.2 := tendsto_prod_uniformity_snd variable [UniformSpace α] [UniformSpace β] [UniformSpace γ] +@[fun_prop] theorem UniformContinuous.prodMk {f₁ : α → β} {f₂ : α → γ} (h₁ : UniformContinuous f₁) (h₂ : UniformContinuous f₂) : UniformContinuous fun a => (f₁ a, f₂ a) := by rw [UniformContinuous, uniformity_prod] @@ -841,10 +855,12 @@ theorem UniformContinuous.prodMk_right {f : α × β → γ} (h : UniformContinu UniformContinuous fun b => f (a, b) := h.comp (uniformContinuous_const.prodMk uniformContinuous_id) +@[fun_prop] theorem UniformContinuous.prodMap [UniformSpace δ] {f : α → γ} {g : β → δ} (hf : UniformContinuous f) (hg : UniformContinuous g) : UniformContinuous (Prod.map f g) := (hf.comp uniformContinuous_fst).prodMk (hg.comp uniformContinuous_snd) +@[fun_prop] lemma uniformContinuous_swap : UniformContinuous (Prod.swap : α × β → β × α) := uniformContinuous_snd.prodMk uniformContinuous_fst @@ -904,6 +920,7 @@ variable {δ' : Type*} [UniformSpace α] [UniformSpace β] [UniformSpace γ] [Un local notation f " ∘₂ " g => Function.bicompr f g /-- Uniform continuity for functions of two variables. -/ +@[fun_prop] def UniformContinuous₂ (f : α → β → γ) := UniformContinuous (uncurry f) @@ -919,10 +936,12 @@ theorem uniformContinuous₂_curry (f : α × β → γ) : UniformContinuous₂ (Function.curry f) ↔ UniformContinuous f := by rw [UniformContinuous₂, uncurry_curry] +@[fun_prop] theorem UniformContinuous₂.comp {f : α → β → γ} {g : γ → δ} (hg : UniformContinuous g) (hf : UniformContinuous₂ f) : UniformContinuous₂ (g ∘₂ f) := hg.comp hf +@[fun_prop] theorem UniformContinuous₂.bicompl {f : α → β → γ} {ga : δ → α} {gb : δ' → β} (hf : UniformContinuous₂ f) (hga : UniformContinuous ga) (hgb : UniformContinuous gb) : UniformContinuous₂ (bicompl f ga gb) := @@ -970,8 +989,8 @@ theorem union_mem_uniformity_sum {a : SetRel α α} (ha : a ∈ 𝓤 α) {b : Se theorem Sum.uniformity : 𝓤 (α ⊕ β) = map (Prod.map inl inl) (𝓤 α) ⊔ map (Prod.map inr inr) (𝓤 β) := rfl -lemma uniformContinuous_inl : UniformContinuous (Sum.inl : α → α ⊕ β) := le_sup_left -lemma uniformContinuous_inr : UniformContinuous (Sum.inr : β → α ⊕ β) := le_sup_right +@[fun_prop] lemma uniformContinuous_inl : UniformContinuous (Sum.inl : α → α ⊕ β) := le_sup_left +@[fun_prop] lemma uniformContinuous_inr : UniformContinuous (Sum.inr : β → α ⊕ β) := le_sup_right instance [IsCountablyGenerated (𝓤 α)] [IsCountablyGenerated (𝓤 β)] : IsCountablyGenerated (𝓤 (α ⊕ β)) := by diff --git a/Mathlib/Topology/UniformSpace/Completion.lean b/Mathlib/Topology/UniformSpace/Completion.lean index 7705375efdd1e8..de432525d28e07 100644 --- a/Mathlib/Topology/UniformSpace/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Completion.lean @@ -238,6 +238,7 @@ end T0Space variable [CompleteSpace β] +@[fun_prop] theorem uniformContinuous_extend {f : α → β} : UniformContinuous (extend f) := by by_cases hf : UniformContinuous f · rw [extend, if_pos hf] @@ -344,6 +345,7 @@ attribute [local instance] theorem nonempty_completion_iff : Nonempty (Completion α) ↔ Nonempty α := cPkg.dense.nonempty_iff.symm +@[fun_prop] theorem uniformContinuous_coe : UniformContinuous ((↑) : α → Completion α) := cPkg.uniformContinuous_coe @@ -431,6 +433,7 @@ section CompleteSpace variable [CompleteSpace β] +@[fun_prop] theorem uniformContinuous_extension : UniformContinuous (Completion.extension f) := cPkg.uniformContinuous_extend @@ -474,6 +477,7 @@ variable {f : α → β} protected def map (f : α → β) : Completion α → Completion β := cPkg.map cPkg f +@[fun_prop] theorem uniformContinuous_map : UniformContinuous (Completion.map f) := cPkg.uniformContinuous_map cPkg f @@ -535,10 +539,12 @@ def completionSeparationQuotientEquiv (α : Type u) [UniformSpace α] : rw [map_coe uniformContinuous_mk, extension_coe (uniformContinuous_lift' _), lift'_mk (uniformContinuous_coe _)] +@[fun_prop] theorem uniformContinuous_completionSeparationQuotientEquiv : UniformContinuous (completionSeparationQuotientEquiv α) := uniformContinuous_extension +@[fun_prop] theorem uniformContinuous_completionSeparationQuotientEquiv_symm : UniformContinuous (completionSeparationQuotientEquiv α).symm := uniformContinuous_map @@ -567,6 +573,7 @@ end T0Space variable [CompleteSpace γ] +@[fun_prop] theorem uniformContinuous_extension₂ : UniformContinuous₂ (Completion.extension₂ f) := cPkg.uniformContinuous_extension₂ cPkg f @@ -580,6 +587,7 @@ open Function protected def map₂ (f : α → β → γ) : Completion α → Completion β → Completion γ := cPkg.map₂ cPkg cPkg f +@[fun_prop] theorem uniformContinuous_map₂ (f : α → β → γ) : UniformContinuous₂ (Completion.map₂ f) := cPkg.uniformContinuous_map₂ cPkg cPkg f diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index b2078d7073c3d9..17cc02dd2e4d84 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -627,6 +627,7 @@ variable [UniformSpace β] /-- A function `f : α → β` is *uniformly continuous* if `(f x, f y)` tends to the diagonal as `(x, y)` tends to the diagonal. In other words, if `x` is sufficiently close to `y`, then `f x` is close to `f y` no matter where `x` and `y` are located in `α`. -/ +@[fun_prop] def UniformContinuous (f : α → β) := Tendsto (fun x : α × α => (f x.1, f x.2)) (𝓤 α) (𝓤 β) @@ -637,6 +638,7 @@ scoped[Uniformity] notation "UniformContinuous[" u₁ ", " u₂ "]" => @UniformC the diagonal as `(x, y)` tends to the diagonal while remaining in `s ×ˢ s`. In other words, if `x` is sufficiently close to `y`, then `f x` is close to `f y` no matter where `x` and `y` are located in `s`. -/ +@[fun_prop] def UniformContinuousOn (f : α → β) (s : Set α) : Prop := Tendsto (fun x : α × α => (f x.1, f x.2)) (𝓤 α ⊓ 𝓟 (s ×ˢ s)) (𝓤 β) @@ -658,17 +660,21 @@ theorem uniformContinuous_of_const {c : α → β} (h : ∀ a b, c a = c b) : eq_univ_iff_forall.2 fun ⟨a, b⟩ => h a b le_trans (map_le_iff_le_comap.2 <| by simp [comap_principal, this]) refl_le_uniformity +@[fun_prop] theorem uniformContinuous_id : UniformContinuous (@id α) := tendsto_id +@[fun_prop] theorem uniformContinuous_const {b : β} : UniformContinuous fun _ : α => b := uniformContinuous_of_const fun _ _ => rfl +@[fun_prop] nonrec theorem UniformContinuous.comp [UniformSpace γ] {g : β → γ} {f : α → β} (hg : UniformContinuous g) (hf : UniformContinuous f) : UniformContinuous (g ∘ f) := hg.comp hf /-- If a function `T` is uniformly continuous in a uniform space `β`, then its `n`-th iterate `T^[n]` is also uniformly continuous. -/ +@[fun_prop] theorem UniformContinuous.iterate (T : β → β) (n : ℕ) (h : UniformContinuous T) : UniformContinuous T^[n] := by induction n with @@ -692,7 +698,7 @@ theorem Filter.HasBasis.uniformContinuousOn_iff {ι'} {p : ι → Prop} /-- A map `f : α → β` between uniform spaces is called *uniform inducing* if the uniformity filter on `α` is the pullback of the uniformity filter on `β` under `Prod.map f f`. If `α` is a separated space, then this implies that `f` is injective, hence it is a `IsUniformEmbedding`. -/ -@[mk_iff] +@[mk_iff, fun_prop] structure IsUniformInducing (f : α → β) : Prop where /-- The uniformity filter on the domain is the pullback of the uniformity filter on the codomain under `Prod.map f f`. -/ @@ -700,7 +706,7 @@ structure IsUniformInducing (f : α → β) : Prop where /-- A map `f : α → β` between uniform spaces is a *uniform embedding* if it is uniform inducing and injective. If `α` is a separated space, then the latter assumption follows from the former. -/ -@[mk_iff] +@[mk_iff, fun_prop] structure IsUniformEmbedding (f : α → β) : Prop extends IsUniformInducing f where /-- A uniform embedding is injective. -/ injective : Function.Injective f diff --git a/Mathlib/Topology/UniformSpace/Separation.lean b/Mathlib/Topology/UniformSpace/Separation.lean index 86c7a03066396c..39c7b86a9c707a 100644 --- a/Mathlib/Topology/UniformSpace/Separation.lean +++ b/Mathlib/Topology/UniformSpace/Separation.lean @@ -263,6 +263,7 @@ instance instUniformSpace : UniformSpace (SeparationQuotient α) where theorem uniformity_eq : 𝓤 (SeparationQuotient α) = (𝓤 α).map (Prod.map mk mk) := rfl +@[fun_prop] theorem uniformContinuous_mk : UniformContinuous (mk : α → SeparationQuotient α) := le_rfl @@ -299,6 +300,7 @@ def lift' [T0Space β] (f : α → β) : SeparationQuotient α → β := theorem lift'_mk [T0Space β] {f : α → β} (h : UniformContinuous f) (a : α) : lift' f (mk a) = f a := by rw [lift', dif_pos h, lift_mk] +@[fun_prop] theorem uniformContinuous_lift' [T0Space β] (f : α → β) : UniformContinuous (lift' f) := by by_cases hf : UniformContinuous f · rwa [lift', dif_pos hf, uniformContinuous_lift] @@ -311,6 +313,7 @@ def map (f : α → β) : SeparationQuotient α → SeparationQuotient β := lif theorem map_mk {f : α → β} (h : UniformContinuous f) (a : α) : map f (mk a) = mk (f a) := by rw [map, lift'_mk (uniformContinuous_mk.comp h)]; rfl +@[fun_prop] theorem uniformContinuous_map (f : α → β) : UniformContinuous (map f) := uniformContinuous_lift' _ @@ -349,6 +352,7 @@ lemma eq_top_iff_indiscrete : u = ⊤ ↔ IndiscreteTopology α := ⟨fun h ↦ IndiscreteTopology.mk <| h ▸ UniformSpace.toTopologicalSpace_top (α := α), fun _ ↦ eq_top_uniformSpace⟩ +@[fun_prop] lemma uniformContinuous [IndiscreteTopology β] {f : α → β} : UniformContinuous f := by rw [UniformContinuous, eq_top_uniformSpace (α := β), top_uniformity] exact Filter.tendsto_top From f057047df5cbf77131531a0d341964828b869042 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Wed, 8 Jul 2026 11:32:06 +0000 Subject: [PATCH 0681/1300] chore(Data/Set/Encard): fix all `backward.isDefEq.respectTransparency` (#41468) All but one stem from abusing the defeq between `ENat` and `WithTop Nat`, use the ENat API instead. --- Mathlib/Data/Set/Card.lean | 51 ++++++++++++++------------------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index f1661d587e2697..b3bbdde0aaf5aa 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -118,9 +118,8 @@ protected alias ⟨_, Nonempty.encard_pos⟩ := encard_pos theorem encard_ne_zero_of_mem {a : α} (h : a ∈ s) : s.encard ≠ 0 := (encard_pos.mpr ⟨a, h⟩).ne.symm -set_option backward.isDefEq.respectTransparency false in @[simp] theorem encard_singleton (e : α) : ({e} : Set α).encard = 1 := by - rw [encard, ENat.card_eq_coe_fintype_card, Fintype.card_ofSubsingleton, Nat.cast_one] + rw [encard, ENat.card_eq_coe_fintype_card, card_singleton, Nat.cast_eq_one] theorem encard_union_eq (h : Disjoint s t) : (s ∪ t).encard = s.encard + t.encard := by classical @@ -225,31 +224,28 @@ theorem encard_union_add_encard_inter (s t : Set α) : rw [← sdiff_union_self, encard_union_eq disjoint_sdiff_left, add_right_comm, encard_sdiff_add_encard_inter] -set_option backward.isDefEq.respectTransparency false in theorem encard_eq_encard_iff_encard_sdiff_eq_encard_sdiff (h : (s ∩ t).Finite) : s.encard = t.encard ↔ (s \ t).encard = (t \ s).encard := by rw [← encard_sdiff_add_encard_inter s t, ← encard_sdiff_add_encard_inter t s, inter_comm t s, - WithTop.add_right_inj h.encard_lt_top.ne] + (ENat.addLECancellable_of_lt_top h.encard_lt_top).inj_left] @[deprecated (since := "2026-06-03")] alias encard_eq_encard_iff_encard_diff_eq_encard_diff := encard_eq_encard_iff_encard_sdiff_eq_encard_sdiff -set_option backward.isDefEq.respectTransparency false in theorem encard_le_encard_iff_encard_sdiff_le_encard_sdiff (h : (s ∩ t).Finite) : s.encard ≤ t.encard ↔ (s \ t).encard ≤ (t \ s).encard := by rw [← encard_sdiff_add_encard_inter s t, ← encard_sdiff_add_encard_inter t s, inter_comm t s, - WithTop.add_le_add_iff_right h.encard_lt_top.ne] + ENat.add_le_add_iff_right h.encard_lt_top.ne] @[deprecated (since := "2026-06-03")] alias encard_le_encard_iff_encard_diff_le_encard_diff := encard_le_encard_iff_encard_sdiff_le_encard_sdiff -set_option backward.isDefEq.respectTransparency false in theorem encard_lt_encard_iff_encard_sdiff_lt_encard_sdiff (h : (s ∩ t).Finite) : s.encard < t.encard ↔ (s \ t).encard < (t \ s).encard := by rw [← encard_sdiff_add_encard_inter s t, ← encard_sdiff_add_encard_inter t s, inter_comm t s, - WithTop.add_lt_add_iff_right h.encard_lt_top.ne] + ENat.add_lt_add_iff_right h.encard_lt_top.ne] @[deprecated (since := "2026-06-03")] alias encard_lt_encard_iff_encard_diff_lt_encard_diff := @@ -268,11 +264,11 @@ theorem Finite.finite_of_encard_le {s : Set α} {t : Set β} (hs : s.Finite) (h : t.encard ≤ s.encard) : t.Finite := encard_lt_top_iff.1 (h.trans_lt hs.encard_lt_top) -set_option backward.isDefEq.respectTransparency false in lemma Finite.eq_of_subset_of_encard_le' (ht : t.Finite) (hst : s ⊆ t) (hts : t.encard ≤ s.encard) : s = t := by rw [← zero_add (a := encard s), ← encard_sdiff_add_encard_of_subset hst] at hts - have hdiff := WithTop.le_of_add_le_add_right (ht.subset hst).encard_lt_top.ne hts + have hdiff := + (ENat.addLECancellable_of_lt_top (ht.subset hst).encard_lt_top).add_le_add_iff_right.mp hts rw [nonpos_iff_eq_zero, encard_eq_zero, sdiff_eq_empty] at hdiff exact hst.antisymm hdiff @@ -334,11 +330,10 @@ theorem encard_sdiff_singleton_add_one (h : a ∈ s) : @[deprecated (since := "2026-06-03")] alias encard_diff_singleton_add_one := encard_sdiff_singleton_add_one -set_option backward.isDefEq.respectTransparency false in theorem encard_sdiff_singleton_of_mem (h : a ∈ s) : (s \ {a}).encard = s.encard - 1 := by - rw [← encard_sdiff_singleton_add_one h, ← WithTop.add_right_inj WithTop.one_ne_top, - tsub_add_cancel_of_le (self_le_add_left _ _)] + rw [← encard_sdiff_singleton_add_one h, + (ENat.addLECancellable_of_ne_top ENat.one_ne_top).add_tsub_cancel_right] @[deprecated (since := "2026-06-03")] alias encard_diff_singleton_of_mem := encard_sdiff_singleton_of_mem @@ -357,18 +352,16 @@ theorem encard_exchange (ha : a ∉ s) (hb : b ∈ s) : (insert a (s \ {b})).enc theorem encard_exchange' (ha : a ∉ s) (hb : b ∈ s) : (insert a s \ {b}).encard = s.encard := by rw [← insert_sdiff_singleton_comm (by rintro rfl; exact ha hb), encard_exchange ha hb] -set_option backward.isDefEq.respectTransparency false in theorem encard_eq_add_one_iff {k : ℕ∞} : s.encard = k + 1 ↔ (∃ a t, a ∉ t ∧ insert a t = s ∧ t.encard = k) := by refine ⟨fun h ↦ ?_, ?_⟩ · obtain ⟨a, ha⟩ := nonempty_of_encard_ne_zero (s := s) (by simp [h]) refine ⟨a, s \ {a}, fun h ↦ h.2 rfl, by rwa [insert_sdiff_singleton, insert_eq_of_mem], ?_⟩ - rw [← WithTop.add_right_inj WithTop.one_ne_top, ← h, - encard_sdiff_singleton_add_one ha] + rw [encard_sdiff_singleton_of_mem ha, h, + (ENat.addLECancellable_of_ne_top ENat.one_ne_top).add_tsub_cancel_right] rintro ⟨a, t, h, rfl, rfl⟩ rw [encard_insert_of_notMem h] -set_option backward.isDefEq.respectTransparency false in /-- Every set is either empty, infinite, or can have its `encard` reduced by a removal. Intended for well-founded induction on the value of `encard`. -/ theorem eq_empty_or_encard_eq_top_or_encard_sdiff_singleton_lt (s : Set α) : @@ -376,7 +369,7 @@ theorem eq_empty_or_encard_eq_top_or_encard_sdiff_singleton_lt (s : Set α) : refine s.eq_empty_or_nonempty.elim Or.inl (Or.inr ∘ fun ⟨a,ha⟩ ↦ (s.finite_or_infinite.elim (fun hfin ↦ Or.inr ⟨a, ha, ?_⟩) (Or.inl ∘ Infinite.encard_eq))) rw [← encard_sdiff_singleton_add_one ha]; nth_rw 1 [← add_zero (encard _)] - exact WithTop.add_lt_add_left hfin.sdiff.encard_lt_top.ne zero_lt_one + exact ENat.add_lt_add_of_le_of_lt hfin.sdiff.encard_lt_top.ne le_rfl zero_lt_one @[deprecated (since := "2026-06-03")] alias eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt := @@ -386,10 +379,8 @@ end InsertErase section SmallSets -set_option backward.isDefEq.respectTransparency false in theorem encard_pair {x y : α} (hne : x ≠ y) : ({x, y} : Set α).encard = 2 := by - rw [encard_insert_of_notMem (by simpa), ← one_add_one_eq_two, - WithTop.add_right_inj WithTop.one_ne_top, encard_singleton] + rw [encard_insert_of_notMem (by simpa), ← one_add_one_eq_two, encard_singleton] theorem encard_eq_one : s.encard = 1 ↔ ∃ x, s = {x} := by refine ⟨fun h ↦ ?_, fun ⟨x, hx⟩ ↦ by rw [hx, encard_singleton]⟩ @@ -423,24 +414,23 @@ theorem exists_ne_of_one_lt_encard (h : 1 < s.encard) (a : α) : ∃ b ∈ s, b apply hne rw [h' b hb, h' b' hb'] -set_option backward.isDefEq.respectTransparency false in theorem encard_eq_two : s.encard = 2 ↔ ∃ x y, x ≠ y ∧ s = {x, y} := by refine ⟨fun h ↦ ?_, fun ⟨x, y, hne, hs⟩ ↦ by rw [hs, encard_pair hne]⟩ obtain ⟨x, hx⟩ := nonempty_of_encard_ne_zero (s := s) (by rw [h]; simp) rw [← insert_eq_of_mem hx, ← insert_sdiff_singleton, encard_insert_of_notMem (fun h ↦ h.2 rfl), - ← one_add_one_eq_two, WithTop.add_right_inj (WithTop.one_ne_top), encard_eq_one] at h + ← one_add_one_eq_two, (ENat.addLECancellable_of_ne_top ENat.one_ne_top).inj_left, + encard_eq_one] at h obtain ⟨y, h⟩ := h refine ⟨x, y, by rintro rfl; exact (h.symm.subset rfl).2 rfl, ?_⟩ rw [← h, insert_sdiff_singleton, insert_eq_of_mem hx] -set_option backward.isDefEq.respectTransparency false in theorem encard_eq_three {α : Type u_1} {s : Set α} : encard s = 3 ↔ ∃ x y z, x ≠ y ∧ x ≠ z ∧ y ≠ z ∧ s = {x, y, z} := by refine ⟨fun h ↦ ?_, fun ⟨x, y, z, hxy, hyz, hxz, hs⟩ ↦ ?_⟩ · obtain ⟨x, hx⟩ := nonempty_of_encard_ne_zero (s := s) (by rw [h]; simp) rw [← insert_eq_of_mem hx, ← insert_sdiff_singleton, encard_insert_of_notMem (fun h ↦ h.2 rfl), (by exact rfl : (3 : ℕ∞) = 2 + 1), - WithTop.add_right_inj WithTop.one_ne_top, encard_eq_two] at h + (ENat.addLECancellable_of_ne_top ENat.one_ne_top).inj_left, encard_eq_two] at h obtain ⟨y, z, hne, hs⟩ := h refine ⟨x, y, z, ?_, ?_, hne, ?_⟩ · rintro rfl; exact (hs.symm.subset (Or.inl rfl)).2 rfl @@ -448,14 +438,13 @@ theorem encard_eq_three {α : Type u_1} {s : Set α} : rw [← hs, insert_sdiff_singleton, insert_eq_of_mem hx] rw [hs, encard_insert_of_notMem, encard_insert_of_notMem, encard_singleton] <;> aesop -set_option backward.isDefEq.respectTransparency false in theorem encard_eq_four {α : Type u_1} {s : Set α} : encard s = 4 ↔ ∃ x y z w, x ≠ y ∧ x ≠ z ∧ x ≠ w ∧ y ≠ z ∧ y ≠ w ∧ z ≠ w ∧ s = {x, y, z, w} := by refine ⟨fun h ↦ ?_, fun ⟨x, y, z, w, hxy, hxz, hxw, hyz, hyw, hzw, hs⟩ ↦ ?_⟩ · obtain ⟨x, hx⟩ := nonempty_of_encard_ne_zero (s := s) (by rw [h]; simp) rw [← insert_eq_of_mem hx, ← insert_sdiff_singleton, encard_insert_of_notMem (fun h ↦ h.2 rfl), (by exact rfl : (4 : ℕ∞) = 3 + 1), - WithTop.add_right_inj WithTop.one_ne_top, encard_eq_three] at h + (ENat.addLECancellable_of_ne_top ENat.one_ne_top).inj_left, encard_eq_three] at h obtain ⟨y, z, w, hyz, hyw, hzw, hs⟩ := h refine ⟨x, y, z, w, ?_, ?_, ?_, hyz, hyw, hzw, ?_⟩ · rintro rfl; exact (hs.symm.subset (Or.inl rfl)).2 rfl @@ -472,11 +461,10 @@ theorem Nat.encard_range (k : ℕ) : {i | i < k}.encard = k := by end SmallSets -set_option backward.isDefEq.respectTransparency false in theorem Finite.eq_insert_of_subset_of_encard_eq_succ (hs : s.Finite) (h : s ⊆ t) (hst : t.encard = s.encard + 1) : ∃ a, t = insert a s := by - rw [← encard_sdiff_add_encard_of_subset h, add_comm, WithTop.add_left_inj hs.encard_lt_top.ne, - encard_eq_one] at hst + rw [← encard_sdiff_add_encard_of_subset h, add_comm _ 1, + (ENat.addLECancellable_of_lt_top hs.encard_lt_top).inj_left, encard_eq_one] at hst obtain ⟨x, hx⟩ := hst; use x; rw [← sdiff_union_of_subset h, hx, singleton_union] theorem exists_subset_encard_eq {k : ℕ∞} (hk : k ≤ s.encard) : ∃ t, t ⊆ s ∧ t.encard = k := by @@ -558,7 +546,6 @@ lemma encard_preimage_val_le_encard_right (P Q : Set α) : (P ↓∩ Q).encard Function.Embedding.encard_le ⟨fun ⟨⟨x, _⟩, hx⟩ ↦ ⟨x, hx⟩, fun _ _ h ↦ by simpa [Subtype.coe_inj] using h⟩ -set_option backward.isDefEq.respectTransparency false in theorem Finite.exists_injOn_of_encard_le [Nonempty β] {s : Set α} {t : Set β} (hs : s.Finite) (hle : s.encard ≤ t.encard) : ∃ (f : α → β), s ⊆ f ⁻¹' t ∧ InjOn f s := by classical @@ -567,7 +554,7 @@ theorem Finite.exists_injOn_of_encard_le [Nonempty β] {s : Set α} {t : Set β} · exact (encard_ne_top_iff.mpr hs h).elim obtain ⟨b, hbt⟩ := encard_pos.1 ((encard_pos.2 ⟨_, has⟩).trans_le hle) have hle' : (s \ {a}).encard ≤ (t \ {b}).encard := by - rwa [← WithTop.add_le_add_iff_right WithTop.one_ne_top, + rwa [← ENat.add_le_add_iff_right ENat.one_ne_top, encard_sdiff_singleton_add_one has, encard_sdiff_singleton_add_one hbt] obtain ⟨f₀, hf₀s, hinj⟩ := exists_injOn_of_encard_le hs.sdiff hle' simp only [preimage_sdiff, subset_def, mem_sdiff, mem_singleton_iff, mem_preimage, and_imp] From 63eca8847e5a868552b1e60ad7bfcd465bc31baa Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:04:14 +0000 Subject: [PATCH 0682/1300] feat(Algebra/RingTheory): polynomial over regular ring (#29701) In this PR, we prove that the ring of polynomials over a regular ring is regular. --- Mathlib.lean | 1 + .../RegularLocalRing/Polynomial.lean | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 Mathlib/RingTheory/RegularLocalRing/Polynomial.lean diff --git a/Mathlib.lean b/Mathlib.lean index 59670b0f0bd814..25322c6b37cb10 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6958,6 +6958,7 @@ public import Mathlib.RingTheory.Regular.LinearMap public import Mathlib.RingTheory.Regular.ProjectiveDimension public import Mathlib.RingTheory.Regular.RegularSequence public import Mathlib.RingTheory.RegularLocalRing.Defs +public import Mathlib.RingTheory.RegularLocalRing.Polynomial public import Mathlib.RingTheory.RingHom.Bijective public import Mathlib.RingTheory.RingHom.EssFiniteType public import Mathlib.RingTheory.RingHom.Etale diff --git a/Mathlib/RingTheory/RegularLocalRing/Polynomial.lean b/Mathlib/RingTheory/RegularLocalRing/Polynomial.lean new file mode 100644 index 00000000000000..796207f43b6298 --- /dev/null +++ b/Mathlib/RingTheory/RegularLocalRing/Polynomial.lean @@ -0,0 +1,114 @@ +/- +Copyright (c) 2025 Nailin Guan. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Nailin Guan +-/ +module + +public import Mathlib.Algebra.Polynomial.FieldDivision +public import Mathlib.RingTheory.Ideal.MonicSpan +public import Mathlib.RingTheory.KrullDimension.Polynomial +public import Mathlib.RingTheory.RegularLocalRing.Defs + +/-! + +# Polynomial over Regular Ring + +In this file we prove that the polynomial ring over a regular ring is regular. + +## Main results + +* `Polynomial.isRegularRing_of_isRegularRing` : the polynomial ring over a regular ring is + a regular ring. + +* `MvPolynomial.isRegularRing_of_isRegularRing` : the multivariate polynomial ring with finite + variates over a regular ring is a regular ring. + +-/ + +@[expose] public section + +variable (R : Type*) [CommRing R] + +open IsLocalRing Polynomial Ideal + +lemma Polynomial.isRegularLocalRing_localization_atPrime_of_comap_eq_maximalIdeal + [IsRegularLocalRing R] (p : Ideal R[X]) [p.IsPrime] (max : p.comap C = maximalIdeal R) : + IsRegularLocalRing (Localization.AtPrime p) := by + apply IsRegularLocalRing.of_spanFinrank_maximalIdeal_le + let q := (maximalIdeal R).map C + have qle : q ≤ p := by simpa [q, ← max] using map_comap_le + have reg := (isRegularLocalRing_iff R).mp ‹_› + have fg' := (maximalIdeal R).fg_of_isNoetherianRing + have fg := Submodule.FG.finite_generators fg' + have ht : (maximalIdeal R).height ≤ q.height := le_of_eq (height_map_C (maximalIdeal R)).symm + by_cases eq : p = q + · have ht1 : (maximalIdeal R).height ≤ p.height := by simpa [eq] + have : Ideal.span ((algebraMap R (Localization.AtPrime p)) '' (maximalIdeal R).generators) = + maximalIdeal (Localization.AtPrime p) := by + rw [IsScalarTower.algebraMap_eq R R[X] (Localization.AtPrime p), RingHom.coe_comp, + Set.image_comp, ← Ideal.map_span, ← Ideal.map_span] + simp only [Ideal.span, (maximalIdeal R).span_generators, algebraMap_eq, q, ← eq, + Localization.AtPrime.map_eq_maximalIdeal] + simp only [← maximalIdeal_height_eq_ringKrullDim, ← IsLocalization.height_under p.primeCompl, + IsLocalization.AtPrime.under_maximalIdeal _ p, ge_iff_le] + apply le_trans _ (WithBot.coe_le_coe.mpr ht1) + simp only [maximalIdeal_height_eq_ringKrullDim, ← reg, Nat.cast_le, ← this, + ← Submodule.FG.generators_ncard fg'] + exact (Submodule.spanFinrank_span_le_ncard_of_finite (fg.image _)).trans (Set.ncard_image_le fg) + · have lt : q < p := lt_of_le_of_ne qle (Ne.symm eq) + have : (comap C p).IsMaximal := by simpa [max] using maximalIdeal.isMaximal R + obtain ⟨y, _, hy⟩ := Polynomial.exists_monic_span_sup_map_eq R p this (by simpa [max]) + have peq : p = Ideal.span (((algebraMap R R[X]) '' (maximalIdeal R).generators) ∪ {y}) := by + simp only [Set.union_comm, Ideal.span_union, ← Ideal.map_span, algebraMap_eq, sup_comm] + nth_rw 1 [hy, max, ← (maximalIdeal R).span_generators] + simp only [← Localization.AtPrime.map_eq_maximalIdeal, peq, Ideal.map_span] + rw [← maximalIdeal_height_eq_ringKrullDim, ← IsLocalization.height_under p.primeCompl, + IsLocalization.AtPrime.under_maximalIdeal _ p] + apply le_trans _ (WithBot.coe_le_coe.mpr (Ideal.height_add_one_le_of_lt_of_isPrime lt)) + apply le_trans _ (WithBot.coe_le_coe.mpr (add_le_add_left ht 1)) + rw [WithBot.coe_add, maximalIdeal_height_eq_ringKrullDim, WithBot.coe_one, ← reg, + ← Nat.cast_one, ← Nat.cast_add, Nat.cast_le] + have fin := (fg.image (algebraMap R R[X])).union (Set.finite_singleton y) + apply le_trans (Submodule.spanFinrank_span_le_ncard_of_finite (fin.image _)) + apply le_trans (Set.ncard_image_le fin) (le_trans (Set.ncard_union_le _ _) _) + rw [Set.ncard_singleton, add_le_add_iff_right, ← Submodule.FG.generators_ncard fg'] + exact Set.ncard_image_le fg + +instance Polynomial.isRegularRing_of_isRegularRing [IsRegularRing R] : IsRegularRing R[X] := by + apply isRegularRing_iff.mpr (fun p hp ↦ ?_) + let q := p.comap C + let S := (Localization.AtPrime q)[X] + let pc := Submonoid.map Polynomial.C.toMonoidHom q.primeCompl + let : Algebra R[X] S := algebra R (Localization.AtPrime q) + have : IsLocalization pc S := Polynomial.isLocalization _ _ + let pS := p.map (algebraMap R[X] S) + have disj : Disjoint (pc : Set R[X]) (p : Set R[X]) := by + simpa [pc, q] using! Set.disjoint_image_left.mpr + (Set.disjoint_compl_left_iff_subset.mpr (fun _ a ↦ a)) + have : pS.IsPrime := IsLocalization.isPrime_of_isPrime_disjoint pc _ _ ‹_› disj + have : IsLocalization.AtPrime (Localization.AtPrime pS) p := by + convert IsLocalization.isLocalization_isLocalization_atPrime_isLocalization pc + (Localization.AtPrime pS) pS + exact (IsLocalization.under_map_of_isPrime_disjoint pc _ ‹_› disj).symm + have := isRegularRing_iff.mp ‹_› q + have eq : comap C pS = maximalIdeal (Localization.AtPrime q) := by + rw [← IsLocalization.map_under q.primeCompl _ (comap C pS), + ← IsLocalization.map_under q.primeCompl _ (maximalIdeal (Localization.AtPrime q))] + simp only [comap_comap, S, pS] + rw [← Polynomial.algebraMap_eq (R := Localization.AtPrime q), + ← IsScalarTower.algebraMap_eq R (Localization.AtPrime q) (Localization.AtPrime q)[X], + IsScalarTower.algebraMap_eq R R[X] (Localization.AtPrime q)[X], ← comap_comap, + ← Ideal.under_def R[X], IsLocalization.under_map_of_isPrime_disjoint pc _ ‹_› disj] + simp [q, IsLocalization.AtPrime.under_maximalIdeal (Localization.AtPrime q) q] + have := isRegularLocalRing_localization_atPrime_of_comap_eq_maximalIdeal _ pS eq + exact IsRegularLocalRing.of_ringEquiv (IsLocalization.algEquiv p.primeCompl + (Localization.AtPrime pS) (Localization.AtPrime p)).toRingEquiv + +instance MvPolynomial.isRegularRing_of_isRegularRing [IsRegularRing R] {ι : Type*} [Finite ι] : + IsRegularRing (MvPolynomial ι R) := by + induction ι using Finite.induction_empty_option with + | of_equiv e H => exact IsRegularRing.of_ringEquiv (renameEquiv _ e).toRingEquiv + | h_empty => exact IsRegularRing.of_ringEquiv (isEmptyRingEquiv R _).symm + | h_option IH => + exact IsRegularRing.of_ringEquiv (MvPolynomial.optionEquivLeft _ _).toRingEquiv.symm From 60cccde06da8b41156aaaee9cb21281f311bf0cf Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:04:17 +0000 Subject: [PATCH 0683/1300] chore: remove some casts from `Nat` to `Fin n` (#41128) The other ones are much harder to avoid or needed (since they make statements about the coercion) Co-authored-by: Batixx --- Mathlib/Combinatorics/Additive/AP/Three/Defs.lean | 14 ++++++-------- Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean | 4 ++-- Mathlib/Data/ZMod/Defs.lean | 4 ++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Mathlib/Combinatorics/Additive/AP/Three/Defs.lean b/Mathlib/Combinatorics/Additive/AP/Three/Defs.lean index e5334e9eb941ab..f6eab8832c46d7 100644 --- a/Mathlib/Combinatorics/Additive/AP/Three/Defs.lean +++ b/Mathlib/Combinatorics/Additive/AP/Three/Defs.lean @@ -443,20 +443,18 @@ theorem addRothNumber_Ico (a b : ℕ) : addRothNumber (Ico a b) = rothNumberNat convert! (image_add_left_Ico 0 (b - a) _).symm exact (add_tsub_cancel_of_le h).symm -open Fin.NatCast in -- TODO: should this be refactored to avoid needing the coercion? -lemma Fin.addRothNumber_eq_rothNumberNat (hkn : 2 * k ≤ n) : +lemma Fin.addRothNumber_eq_rothNumberNat {k : Fin (n + 1)} (hkn : 2 * k ≤ n) : addRothNumber (Iio k : Finset (Fin n.succ)) = rothNumberNat k := IsAddFreimanIso.addRothNumber_congr <| mod_cast isAddFreimanIso_Iio two_ne_zero hkn -open Fin.CommRing in -- TODO: should this be refactored to avoid needing the coercion? -lemma Fin.addRothNumber_le_rothNumberNat (k n : ℕ) (hkn : k ≤ n) : +lemma Fin.addRothNumber_le_rothNumberNat {n : ℕ} (k : Fin (n + 1)) : addRothNumber (Iio k : Finset (Fin n.succ)) ≤ rothNumberNat k := by + open Fin.CommRing in -- TODO: should this be refactored to avoid needing the coercion? suffices h : Set.BijOn (Nat.cast : ℕ → Fin n.succ) (range k) (Iio k : Finset (Fin n.succ)) by exact (AddHomClass.isAddFreimanHom (Nat.castRingHom _) h.mapsTo).addRothNumber_mono h - refine ⟨?_, (CharP.natCast_injOn_Iio _ n.succ).mono (by simp; lia), ?_⟩ - · simpa using! fun x ↦ natCast_strictMono hkn - simp only [Set.SurjOn, coe_Iio, Set.subset_def, Set.mem_Iio, Set.mem_image, lt_def, - val_cast_of_lt, Nat.lt_succ_iff.2 hkn, coe_range] + refine ⟨?_, (CharP.natCast_injOn_Iio _ n.succ).mono (by simp), ?_⟩ + · simpa using! fun x ↦ natCast_strictMono (is_le k) + simp only [Set.SurjOn, coe_Iio, Set.subset_def, Set.mem_Iio, Set.mem_image, lt_def, coe_range] exact fun x hx ↦ ⟨x, hx, by simp⟩ end rothNumberNat diff --git a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean index 3d79d4e756596a..364d1fc78694b8 100644 --- a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean +++ b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean @@ -189,8 +189,8 @@ lemma rothNumberNat_le_ruzsaSzemerediNumberNat (n : ℕ) : open scoped Fin.CommRing in calc (2 * n + 1) * rothNumberNat n - _ = Fintype.card α * addRothNumber (Iio (n : α)) := by - rw [Fin.addRothNumber_eq_rothNumberNat le_rfl, Fintype.card_fin] + _ = Fintype.card α * addRothNumber (Iio (⟨n, by lia⟩ : α)) := by + rw [Fin.addRothNumber_eq_rothNumberNat (by simp), Fintype.card_fin] _ ≤ Fintype.card α * addRothNumber (univ : Finset α) := by gcongr; exact subset_univ _ _ ≤ ruzsaSzemerediNumber (Sum α (Sum α α)) := addRothNumber_le_ruzsaSzemerediNumber _ diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index e6b35cc6f970f0..00e5d929d5bce7 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -132,8 +132,8 @@ attribute [scoped instance] Fin.instCommRing end CommRing -instance (n : ℕ) [NeZero n] : NeZero (1 : Fin (n + 1)) := - open Fin.CommRing in inferInstance +instance (n : ℕ) [NeZero n] : NeZero (1 : Fin (n + 1)) where + out := by simp end Fin From 13871ecd63277c7e535f3d0fe986eb46fbbe1c8d Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:04:20 +0000 Subject: [PATCH 0684/1300] chore(Analysis/Meromorphic/Order): fix defeq abuse (#41392) Remove defeq abuse via `Option.ne_none_iff_exists'`. --- Mathlib/Analysis/Meromorphic/Order.lean | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index 49bca14ba54e70..1579cfa70c8f60 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -268,15 +268,16 @@ theorem meromorphicOrderAt_congr (hf₁₂ : f₁ =ᶠ[𝓝[≠] x] f₂) : contrapose hf₁ exact hf₁.congr hf₁₂.symm simp [hf₁, this] - by_cases h₁f₁ : meromorphicOrderAt f₁ x = ⊤ - · rw [h₁f₁, eq_comm] + rw [eq_comm] + cases h₁f₁ : meromorphicOrderAt f₁ x with + | top => rw [meromorphicOrderAt_eq_top_iff] at h₁f₁ ⊢ - exact EventuallyEq.rw h₁f₁ (fun x => Eq (f₂ x)) hf₁₂.symm - · obtain ⟨n, hn : meromorphicOrderAt f₁ x = n⟩ := Option.ne_none_iff_exists'.mp h₁f₁ - obtain ⟨g, h₁g, h₂g, h₃g⟩ := (meromorphicOrderAt_eq_int_iff hf₁).1 hn - rw [hn, eq_comm, meromorphicOrderAt_eq_int_iff (hf₁.congr hf₁₂)] + filter_upwards [hf₁₂, h₁f₁] using by grind + | coe n => + obtain ⟨g, h₁g, h₂g, h₃g⟩ := (meromorphicOrderAt_eq_int_iff hf₁).1 h₁f₁ + rw [meromorphicOrderAt_eq_int_iff (hf₁.congr hf₁₂)] use g, h₁g, h₂g - exact EventuallyEq.rw h₃g (fun x => Eq (f₂ x)) hf₁₂.symm + filter_upwards [hf₁₂, h₃g] using by grind /-- Compatibility of notions of `order` for analytic and meromorphic functions. -/ lemma AnalyticAt.meromorphicOrderAt_eq (hf : AnalyticAt 𝕜 f x) : From 55f9b919a41067ab1417f48e1d99c5981a201807 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Wed, 8 Jul 2026 12:04:22 +0000 Subject: [PATCH 0685/1300] chore: fix some ENat-related instances of `backward.isDefEq.respectTransparency` (#41456) Fixed defeq abuses between `ENat` and `WithTop Nat` by just using the ENat API. --- .../Polynomial/Degree/TrailingDegree.lean | 17 ++++++----------- .../SimpleGraph/Coloring/Vertex.lean | 3 +-- Mathlib/Data/ENat/Pow.lean | 3 +-- Mathlib/Data/Nat/Multiplicity.lean | 4 +--- .../TopologicalEntropy/CoverEntropy.lean | 9 ++++----- .../Dynamics/TopologicalEntropy/NetEntropy.lean | 15 +++++++-------- Mathlib/MeasureTheory/Function/SimpleFunc.lean | 3 +-- Mathlib/NumberTheory/Padics/PadicVal/Basic.lean | 4 +--- Mathlib/Order/Height.lean | 7 +++---- Mathlib/Order/KrullDimension.lean | 6 ++---- Mathlib/Probability/Process/Stopping.lean | 6 ++---- Mathlib/RingTheory/Ideal/Height.lean | 8 +++----- Mathlib/RingTheory/Multiplicity.lean | 8 +++----- Mathlib/RingTheory/MvPowerSeries/LexOrder.lean | 4 +--- 14 files changed, 36 insertions(+), 61 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean index 90137d1ae13896..cb762e933de609 100644 --- a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean @@ -259,10 +259,10 @@ theorem natTrailingDegree_mem_support_of_nonzero : p ≠ 0 → natTrailingDegree theorem natTrailingDegree_le_of_mem_supp (a : ℕ) : a ∈ p.support → natTrailingDegree p ≤ a := natTrailingDegree_le_of_ne_zero ∘ mem_support_iff.mp -set_option backward.isDefEq.respectTransparency false in theorem natTrailingDegree_eq_support_min' (h : p ≠ 0) : natTrailingDegree p = p.support.min' (nonempty_support_iff.mpr h) := by - rw [natTrailingDegree, trailingDegree, ← Finset.coe_min', ENat.some_eq_coe, ENat.toNat_coe] + rw [natTrailingDegree, trailingDegree, ← Finset.coe_min' (support_nonempty.mpr h)] + norm_cast theorem le_natTrailingDegree (hp : p ≠ 0) (hn : ∀ m < n, p.coeff m = 0) : n ≤ p.natTrailingDegree := by @@ -296,15 +296,12 @@ theorem le_trailingDegree_mul : p.trailingDegree + q.trailingDegree ≤ (p * q). (min_le (mem_support_iff.mpr (right_ne_zero_of_mul hpq)))).trans_eq ?_ rwa [← WithTop.coe_add, WithTop.coe_eq_coe, ← mem_antidiagonal] -set_option backward.isDefEq.respectTransparency false in theorem le_natTrailingDegree_mul (h : p * q ≠ 0) : p.natTrailingDegree + q.natTrailingDegree ≤ (p * q).natTrailingDegree := by have hp : p ≠ 0 := fun hp => h (by rw [hp, zero_mul]) have hq : q ≠ 0 := fun hq => h (by rw [hq, mul_zero]) - rw [← WithTop.coe_le_coe, WithTop.coe_add, ← Nat.cast_withTop (natTrailingDegree p), - ← Nat.cast_withTop (natTrailingDegree q), ← Nat.cast_withTop (natTrailingDegree (p * q)), - ← trailingDegree_eq_natTrailingDegree hp, ← trailingDegree_eq_natTrailingDegree hq, - ← trailingDegree_eq_natTrailingDegree h] + rw [← ENat.coe_le_coe, ENat.coe_add, ← trailingDegree_eq_natTrailingDegree hp, + ← trailingDegree_eq_natTrailingDegree hq, ← trailingDegree_eq_natTrailingDegree h] exact le_trailingDegree_mul theorem coeff_mul_natTrailingDegree_add_natTrailingDegree : (p * q).coeff @@ -332,15 +329,13 @@ theorem trailingDegree_mul' (h : p.trailingCoeff * q.trailingCoeff ≠ 0) : apply trailingDegree_le_of_ne_zero rwa [coeff_mul_natTrailingDegree_add_natTrailingDegree] -set_option backward.isDefEq.respectTransparency false in theorem natTrailingDegree_mul' (h : p.trailingCoeff * q.trailingCoeff ≠ 0) : (p * q).natTrailingDegree = p.natTrailingDegree + q.natTrailingDegree := by have hp : p ≠ 0 := fun hp => h (by rw [hp, trailingCoeff_zero, zero_mul]) have hq : q ≠ 0 := fun hq => h (by rw [hq, trailingCoeff_zero, mul_zero]) apply natTrailingDegree_eq_of_trailingDegree_eq_some - rw [trailingDegree_mul' h, Nat.cast_withTop (natTrailingDegree p + natTrailingDegree q), - WithTop.coe_add, ← Nat.cast_withTop, ← Nat.cast_withTop, - ← trailingDegree_eq_natTrailingDegree hp, ← trailingDegree_eq_natTrailingDegree hq] + rw [trailingDegree_mul' h, ENat.coe_add, ← trailingDegree_eq_natTrailingDegree hp, + ← trailingDegree_eq_natTrailingDegree hq] theorem natTrailingDegree_mul [NoZeroDivisors R] (hp : p ≠ 0) (hq : q ≠ 0) : (p * q).natTrailingDegree = p.natTrailingDegree + q.natTrailingDegree := diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean index f8091d4860295c..02d84e2d92cf0f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean @@ -336,10 +336,9 @@ theorem chromaticNumber_ne_top_iff_exists : G.chromaticNumber ≠ ⊤ ↔ ∃ n, rw [chromaticNumber] simp -set_option backward.isDefEq.respectTransparency false in theorem chromaticNumber_le_iff_colorable {n : ℕ} : G.chromaticNumber ≤ n ↔ G.Colorable n := by refine ⟨fun h ↦ ?_, Colorable.chromaticNumber_le⟩ - have : G.chromaticNumber ≠ ⊤ := (trans h (WithTop.coe_lt_top n)).ne + have : G.chromaticNumber ≠ ⊤ := (trans h (ENat.coe_lt_top n)).ne rw [chromaticNumber_ne_top_iff_exists] at this obtain ⟨m, hm⟩ := this rw [hm.chromaticNumber_eq_sInf, Nat.cast_le] at h diff --git a/Mathlib/Data/ENat/Pow.lean b/Mathlib/Data/ENat/Pow.lean index 71e651332f409f..e83311d992c684 100644 --- a/Mathlib/Data/ENat/Pow.lean +++ b/Mathlib/Data/ENat/Pow.lean @@ -136,7 +136,6 @@ lemma epow_add : x ^ (y + z) = x ^ y * x ^ z := by exact (epow_pos x_2.ne_zero).ne' simp only [← Nat.cast_add, epow_natCast, pow_add x] -set_option backward.isDefEq.respectTransparency false in lemma mul_epow : (x * y) ^ z = x ^ z * y ^ z := by induction z · rcases lt_trichotomy x 1 with x_0 | rfl | x_2 @@ -145,7 +144,7 @@ lemma mul_epow : (x * y) ^ z = x ^ z * y ^ z := by · rcases lt_trichotomy y 1 with y_0 | rfl | y_2 · simp only [Order.lt_one_iff.1 y_0, mul_zero, zero_epow_top] · simp - · rw [epow_top x_2, epow_top y_2, WithTop.top_mul_top] + · rw [epow_top x_2, epow_top y_2, mul_top top_ne_zero] exact epow_top (one_lt_mul x_2.le y_2) · simp only [epow_natCast, mul_pow x y] diff --git a/Mathlib/Data/Nat/Multiplicity.lean b/Mathlib/Data/Nat/Multiplicity.lean index 70d8c8d5671efc..88faa7909725f9 100644 --- a/Mathlib/Data/Nat/Multiplicity.lean +++ b/Mathlib/Data/Nat/Multiplicity.lean @@ -172,13 +172,11 @@ theorem multiplicity_factorial_pow {n p : ℕ} (hp : p.Prime) : | succ n h => rw [pow_succ', hp.emultiplicity_factorial_mul, h, Finset.sum_range_succ, ENat.coe_add] -set_option backward.isDefEq.respectTransparency false in /-- A prime power divides `n!` iff it is at most the sum of the quotients `n / p ^ i`. This sum is expressed over the set `Ico 1 b` where `b` is any bound greater than `log p n` -/ theorem pow_dvd_factorial_iff {p : ℕ} {n r b : ℕ} (hp : p.Prime) (hbn : log p n < b) : p ^ r ∣ n ! ↔ r ≤ ∑ i ∈ Ico 1 b, n / p ^ i := by - rw [← WithTop.coe_le_coe, ENat.some_eq_coe, ← hp.emultiplicity_factorial hbn, - pow_dvd_iff_le_emultiplicity] + rw [← ENat.coe_le_coe, ← hp.emultiplicity_factorial hbn, pow_dvd_iff_le_emultiplicity] theorem emultiplicity_factorial_le_div_pred {p : ℕ} (hp : p.Prime) (n : ℕ) : emultiplicity p n ! ≤ (n / (p - 1) : ℕ) := by diff --git a/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean index 346c6c706000b4..6df21185d76b11 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean @@ -218,25 +218,24 @@ lemma coverMincard_antitone (T : X → X) (F : Set X) (n : ℕ) : Antitone fun U : SetRel X X ↦ coverMincard T F U n := fun _ _ U_V ↦ biInf_mono fun _ h ↦ h.of_entourage_subset U_V -set_option backward.isDefEq.respectTransparency false in lemma coverMincard_finite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : ℕ) : coverMincard T F U n < ⊤ ↔ ∃ s : Finset X, IsDynCoverOf T F U n s ∧ s.card = coverMincard T F U n := by refine ⟨fun h_fin ↦ ?_, fun ⟨s, _, s_coverMincard⟩ ↦ s_coverMincard ▸ WithTop.coe_lt_top s.card⟩ - obtain ⟨k, k_min⟩ := WithTop.ne_top_iff_exists.1 h_fin.ne + obtain ⟨k, k_min⟩ := ENat.ne_top_iff_exists.mp h_fin.ne rw [← k_min] - simp only [ENat.some_eq_coe, Nat.cast_inj] + simp only [Nat.cast_inj] have : Nonempty {s : Finset X // IsDynCoverOf T F U n s} := by by_contra h apply ENat.coe_ne_top k - rw [← ENat.some_eq_coe, k_min, coverMincard, iInf₂_eq_top] + rw [k_min, coverMincard, iInf₂_eq_top] simp only [ENat.coe_ne_top, imp_false] rw [nonempty_subtype, not_exists] at h exact h have key := ciInf_mem fun s : {s : Finset X // IsDynCoverOf T F U n s} ↦ (s.val.card : ℕ∞) rw [coverMincard, iInf_subtype'] at k_min rw [← k_min, mem_range, Subtype.exists] at key - simp only [ENat.some_eq_coe, Nat.cast_inj, exists_prop] at key + simp only [Nat.cast_inj, exists_prop] at key exact key @[simp] diff --git a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean index 853778648ef964..1f341c7e4489b8 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean @@ -113,36 +113,35 @@ lemma netMaxcard_antitone (T : X → X) (F : Set X) (n : ℕ) : Antitone fun U : SetRel X X ↦ netMaxcard T F U n := fun _ _ U_V ↦ biSup_mono fun _ h ↦ h.of_entourage_subset U_V -set_option backward.isDefEq.respectTransparency false in lemma netMaxcard_finite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : ℕ) : netMaxcard T F U n < ⊤ ↔ ∃ s : Finset X, IsDynNetIn T F U n s ∧ (s.card : ℕ∞) = netMaxcard T F U n := by apply Iff.intro <;> intro h - · obtain ⟨k, k_max⟩ := WithTop.ne_top_iff_exists.1 h.ne + · obtain ⟨k, k_max⟩ := ENat.ne_top_iff_exists.mp h.ne rw [← k_max] - simp only [ENat.some_eq_coe, Nat.cast_inj] + simp only [Nat.cast_inj] -- The criterion we want to use is `Nat.sSup_mem`. We rewrite `netMaxcard` with an `sSup`, -- then check its `BddAbove` and `Nonempty` hypotheses. have : netMaxcard T F U n = sSup (WithTop.some '' Finset.card '' {s : Finset X | IsDynNetIn T F U n s}) := by rw [netMaxcard, ← image_comp, sSup_image] simp only [mem_setOf_eq, ENat.some_eq_coe, Function.comp_apply] + exact biSup_congr (fun _ _ ↦ rfl) rw [this] at k_max have h_bdda : BddAbove (Finset.card '' {s : Finset X | IsDynNetIn T F U n s}) := by refine ⟨k, mem_upperBounds.2 ?_⟩ simp only [mem_image, mem_setOf_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] intro s h - rw [← WithTop.coe_le_coe, k_max] + rw [← ENat.coe_le_coe, k_max] apply le_sSup - simp only [ENat.some_eq_coe, mem_image, mem_setOf_eq, Nat.cast_inj, exists_eq_right] - exact Filter.frequently_principal.mp fun a ↦ a h rfl + exact Filter.frequently_principal.mp fun a ↦ a (by simpa using ⟨_, h, rfl⟩) rfl have h_nemp : (Finset.card '' {s : Finset X | IsDynNetIn T F U n s}).Nonempty := by refine ⟨0, ?_⟩ simp only [mem_image, mem_setOf_eq, Finset.card_eq_zero, exists_eq_right, Finset.coe_empty] exact isDynNetIn_empty - rw [← WithTop.coe_sSup' h_bdda, ENat.some_eq_coe, Nat.cast_inj] at k_max + rw [← WithTop.coe_sSup' h_bdda] at k_max have key := Nat.sSup_mem h_nemp h_bdda - rw [← k_max, mem_image] at key + rw [← Nat.cast_inj.mp k_max, mem_image] at key simp only [mem_setOf_eq] at key exact key · obtain ⟨s, _, s_card⟩ := h diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index e672003be67e07..133f5f46b0638a 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -867,10 +867,9 @@ theorem ennrealRatEmbed_encode (q : ℚ) : def eapprox : (α → ℝ≥0∞) → ℕ → α →ₛ ℝ≥0∞ := approx ennrealRatEmbed -set_option backward.isDefEq.respectTransparency false in theorem eapprox_lt_top (f : α → ℝ≥0∞) (n : ℕ) (a : α) : eapprox f n a < ∞ := by simp only [eapprox, approx, finset_sup_apply, restrict] - rw [Finset.sup_lt_iff (α := ℝ≥0∞) WithTop.top_pos] + rw [Finset.sup_lt_iff (α := ℝ≥0∞) bot_lt_top] intro b _ split_ifs · simp only [coe_zero, coe_piecewise, piecewise_eq_indicator, coe_const] diff --git a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean index 80b6ae2ff73f00..28a3121252e60b 100644 --- a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean +++ b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean @@ -184,11 +184,9 @@ theorem padicValNat_self [Fact p.Prime] : padicValNat p p = 1 := by rw [padicValNat_def (@Fact.out p.Prime).ne_zero] simp -set_option backward.isDefEq.respectTransparency false in theorem one_le_padicValNat_of_dvd {n : ℕ} [hp : Fact p.Prime] (hn : n ≠ 0) (div : p ∣ n) : 1 ≤ padicValNat p n := by - rwa [← WithTop.coe_le_coe, ENat.some_eq_coe, padicValNat_eq_emultiplicity hn, - ← pow_dvd_iff_le_emultiplicity, pow_one] + rwa [← ENat.coe_le_coe, padicValNat_eq_emultiplicity hn, ← pow_dvd_iff_le_emultiplicity, pow_one] theorem dvd_iff_padicValNat_ne_zero {p n : ℕ} [Fact p.Prime] (hn0 : n ≠ 0) : p ∣ n ↔ padicValNat p n ≠ 0 := diff --git a/Mathlib/Order/Height.lean b/Mathlib/Order/Height.lean index 0436ec08dcce35..a3730fbc6acb25 100644 --- a/Mathlib/Order/Height.lean +++ b/Mathlib/Order/Height.lean @@ -92,15 +92,14 @@ theorem not_isChain_of_chainHeight_lt_encard (s t : Set α) (ht : t ⊆ s) grw [encard_le_chainHeight_of_isChain _ _ ht hh] at he exact (lt_self_iff_false _).mp he -set_option backward.isDefEq.respectTransparency false in theorem chainHeight_eq_top_iff : s.chainHeight r = ⊤ ↔ ∀ n : ℕ, ∃ t ⊆ s, t.encard = n ∧ IsChain r t := by refine ⟨fun h _ ↦ exists_isChain_of_le_chainHeight _ (le_top.trans_eq h.symm), fun h ↦ ?_⟩ contrapose! h - obtain ⟨n, hn⟩ := WithTop.ne_top_iff_exists.1 h + obtain ⟨n, hn⟩ := ENat.ne_top_iff_exists.mp h refine ⟨n + 1, fun l hl he ↦ not_isChain_of_chainHeight_lt_encard r s l hl ?_⟩ - rw [← hn, some_eq_coe, he, Nat.cast_lt] - exact lt_add_one _ + rw [← hn, he] + exact_mod_cast lt_add_one _ @[simp] theorem chainHeight_eq_zero_iff : s.chainHeight r = 0 ↔ s = ∅ := by diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index 7053dd35d3f121..05c8a6d13cb88a 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -705,7 +705,6 @@ lemma krullDim_eq_length_of_finiteDimensionalOrder [FiniteDimensionalOrder α] : RelSeries.length_le_length_longestOf _ _) <| le_iSup (fun (i : LTSeries _) ↦ (i.length : WithBot (WithTop ℕ))) <| LTSeries.longestOf _ -set_option backward.isDefEq.respectTransparency false in lemma krullDim_eq_top [InfiniteDimensionalOrder α] : krullDim α = ⊤ := le_antisymm le_top <| le_iSup_iff.mpr <| fun m hm ↦ match m, hm with @@ -715,9 +714,8 @@ lemma krullDim_eq_top [InfiniteDimensionalOrder α] : | some ⊤, _ => le_refl _ | some (some m), hm => by refine (not_lt_of_ge (hm (LTSeries.withLength _ (m + 1))) ?_).elim - rw [WithBot.some_eq_coe, ← WithBot.coe_natCast, WithBot.coe_lt_coe, - WithTop.some_eq_coe, ← WithTop.coe_natCast, WithTop.coe_lt_coe] - simp + simp [ENat.WithBot.lt_add_one_iff] + norm_cast lemma krullDim_eq_top_iff : krullDim α = ⊤ ↔ InfiniteDimensionalOrder α := by refine ⟨fun h ↦ ?_, fun _ ↦ krullDim_eq_top⟩ diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index ec2d4646868779..1f84841c8797e3 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -1311,7 +1311,6 @@ section AddCommMonoid variable [AddCommMonoid β] -set_option backward.isDefEq.respectTransparency false in theorem stoppedValue_eq {N : ℕ} (hbdd : ∀ ω, τ ω ≤ N) : stoppedValue u τ = fun x => (∑ i ∈ Finset.range (N + 1), Set.indicator {ω | τ ω = i} (u i)) x := by refine stoppedValue_eq_of_mem_finset fun ω ↦ ?_ @@ -1319,9 +1318,8 @@ theorem stoppedValue_eq {N : ℕ} (hbdd : ∀ ω, τ ω ≤ N) : stoppedValue u have h_top : τ ω ≠ ⊤ := fun h_contra ↦ by simp [h_contra] at hbdd lift τ ω to ℕ using h_top with t ht simp only [Nat.cast_le] at hbdd - simp only [ENat.some_eq_coe, Finset.coe_range, Set.mem_image, Set.mem_Iio, Nat.cast_inj, - exists_eq_right, gt_iff_lt] - grind + simp only [ENat.some_eq_coe, Finset.coe_range, Set.mem_image, Set.mem_Iio] + exact ⟨t, by simpa, Nat.cast_inj.mpr rfl⟩ theorem stoppedProcess_eq (n : ℕ) : stoppedProcess u τ n = Set.indicator {a | n ≤ τ a} (u n) + ∑ i ∈ Finset.range n, Set.indicator {ω | τ ω = i} (u i) := by diff --git a/Mathlib/RingTheory/Ideal/Height.lean b/Mathlib/RingTheory/Ideal/Height.lean index 6fc30fe2b79b4e..c5a46cc9620e2d 100644 --- a/Mathlib/RingTheory/Ideal/Height.lean +++ b/Mathlib/RingTheory/Ideal/Height.lean @@ -93,15 +93,13 @@ private lemma Ideal.primeHeight_lt_top (I : Ideal R) [I.FiniteHeight] [I.IsPrime rw [← I.height_eq_primeHeight] exact Ideal.height_lt_top ‹I.IsPrime›.ne_top -set_option backward.isDefEq.respectTransparency false in lemma Ideal.exists_ltSeries_length_eq_height (p : Ideal R) [p.IsPrime] [p.FiniteHeight] : ∃ (l : LTSeries (PrimeSpectrum R)), RelSeries.last l = ⟨p, inferInstance⟩ ∧ l.length = p.height := by - obtain ⟨n, hn⟩ := Option.ne_none_iff_exists'.mp (p.height_ne_top (IsPrime.ne_top ‹_›)) + obtain ⟨n, hn⟩ := ENat.ne_top_iff_exists.mp (p.height_ne_top (IsPrime.ne_top ‹_›)) rw [Ideal.height_eq_primeHeight, Ideal.primeHeight] at hn ⊢ - obtain ⟨l, last, len⟩ := Order.exists_series_of_height_eq_coe (⟨p, ‹_›⟩ : PrimeSpectrum R) hn - rw [hn] - exact ⟨l, last, by rw [len, WithTop.some_eq_coe, ENat.some_eq_coe]⟩ + obtain ⟨l, last, len⟩ := Order.exists_series_of_height_eq_coe (⟨p, ‹_›⟩ : PrimeSpectrum R) hn.symm + exact ⟨l, last, len ▸ hn⟩ private lemma Ideal.height_mono_of_isPrime {I J : Ideal R} [I.IsPrime] [J.IsPrime] (h : I ≤ J) : I.height ≤ J.height := by diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index 3b8b29f7968916..3ae9ebb2cb3780 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -100,11 +100,11 @@ theorem emultiplicity_eq_zero_iff_multiplicity_eq_zero : emultiplicity a b = 0 ↔ multiplicity a b = 0 := emultiplicity_eq_iff_multiplicity_eq_of_ne_one zero_ne_one -set_option backward.isDefEq.respectTransparency false in @[simp] theorem multiplicity_eq_one_of_not_finiteMultiplicity (h : ¬FiniteMultiplicity a b) : multiplicity a b = 1 := by - simp [multiplicity, emultiplicity_eq_top.2 h] + rw [multiplicity, emultiplicity_eq_top.mpr h] + decide @[simp] theorem multiplicity_le_emultiplicity : @@ -357,12 +357,10 @@ theorem emultiplicity_le_emultiplicity_iff {c d : β} : simp_all only [not_exists, Decidable.not_not, not_true_eq_false, top_le_iff, dite_eq_right_iff, ENat.coe_ne_top, imp_false, not_false_eq_true, implies_true] -set_option backward.isDefEq.respectTransparency false in theorem FiniteMultiplicity.multiplicity_le_multiplicity_iff {c d : β} (hab : FiniteMultiplicity a b) (hcd : FiniteMultiplicity c d) : multiplicity a b ≤ multiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b → c ^ n ∣ d := by - rw [← WithTop.coe_le_coe, ENat.some_eq_coe, ← hab.emultiplicity_eq_multiplicity, - ← hcd.emultiplicity_eq_multiplicity] + rw [← ENat.coe_le_coe, ← hab.emultiplicity_eq_multiplicity, ← hcd.emultiplicity_eq_multiplicity] apply emultiplicity_le_emultiplicity_iff theorem emultiplicity_eq_emultiplicity_iff {c d : β} : diff --git a/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean b/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean index 98896a9b9f6ff1..ea86ba38fc3528 100644 --- a/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean +++ b/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean @@ -29,13 +29,11 @@ section LexOrder open Finsupp variable [LinearOrder σ] [WellFoundedGT σ] -set_option backward.isDefEq.respectTransparency false in /-- The lex order on multivariate power series. -/ noncomputable def lexOrder (φ : MvPowerSeries σ R) : (WithTop (Lex (σ →₀ ℕ))) := by classical exact if h : φ = 0 then ⊤ else by - have ne : Set.Nonempty (toLex '' φ.support) := by - simp only [Set.image_nonempty, Function.support_nonempty_iff, ne_eq, h, not_false_eq_true] + have ne : Set.Nonempty (toLex '' φ.support) := by simpa apply WithTop.some apply WellFounded.min _ (toLex '' φ.support) ne · exact Finsupp.instLTLex.lt From 1c3e8f34a897e543dae130ad26f2a91aa23ee2cb Mon Sep 17 00:00:00 2001 From: Paul Lezeau <72892199+Paul-Lez@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:55:23 +0000 Subject: [PATCH 0686/1300] feat: implement LMFDB attribute (#41290) Implement LMFDB attribute. This allows users to link Mathlib declarations to LMFDB knowls. The implementation here copies the implementation of the other cross-referencing attributes. --- Mathlib/Tactic/CrossRefAttribute.lean | 82 +++++++++++++++++++++++++++ MathlibTest/CrossRefAttribute.lean | 35 ++++++++++++ 2 files changed, 117 insertions(+) diff --git a/Mathlib/Tactic/CrossRefAttribute.lean b/Mathlib/Tactic/CrossRefAttribute.lean index 7697769c05dbcf..699b1acad9a119 100644 --- a/Mathlib/Tactic/CrossRefAttribute.lean +++ b/Mathlib/Tactic/CrossRefAttribute.lean @@ -17,6 +17,7 @@ to entries in external mathematical databases: * `@[stacks TAG]` — [Stacks Project](https://stacks.math.columbia.edu/tags) * `@[kerodon TAG]` — [Kerodon](https://kerodon.net/tag/) * `@[wikidata QID]` — [Wikidata](https://www.wikidata.org) +* `@[lmfdb ID]` — [LMFDB](https://www.lmfdb.org) Each attribute records the cross-reference in an environment extension and appends a link to the declaration's docstring. @@ -35,6 +36,7 @@ namespace Mathlib.CrossRef /-- The supported external databases -/ inductive Database where | kerodon + | lmfdb | stacks | wikidata deriving BEq, Hashable, Ord @@ -44,18 +46,21 @@ namespace Database /-- The base URL for an external database's tag pages. Always ends with `/`. -/ def url : Database → String | .kerodon => "https://kerodon.net/tag/" + | .lmfdb => "https://www.lmfdb.org/knowledge/show/" | .stacks => "https://stacks.math.columbia.edu/tag/" | .wikidata => "https://www.wikidata.org/wiki/" /-- The display label used in docstring links and trace output. -/ def label : Database → String | .kerodon => "Kerodon Tag" + | .lmfdb => "LMFDB" | .stacks => "Stacks Tag" | .wikidata => "Wikidata" /-- A lowercase short name for the given database. Useful when exporting to JSON. -/ def shortName : Database → String | .kerodon => "kerodon" + | .lmfdb => "lmfdb" | .stacks => "stacks" | .wikidata => "wikidata" @@ -169,6 +174,39 @@ def wikidataIdNoAntiquot : Parser := { def wikidataIdParser : Parser := withAntiquot (mkAntiquot "wikidataId" wikidataIdKind) wikidataIdNoAntiquot +/-! # LMFDB parser -/ + +/-- `lmfdbId` is the node kind of LMFDB identifiers: lower case words with `.` in between. +The words can also contain underscores and digits. -/ +abbrev lmfdbIdKind : SyntaxNodeKind := `lmfdbId + +/-- The main parser for LMFDB identifiers: it accepts lower case words with `.` in between. +The words can also contain underscores and digits. -/ +def lmfdbIdFn : ParserFn := fun c s => + let i := s.pos + let s := takeWhileFn (fun c => c.isAlphanum || c == '.' || c == '_') c s + if s.hasError then + s + else if s.pos == i then + ParserState.mkError s "lmfdb id" + else + if !(c.extract i s.pos).toList.all + (fun c => c.isLower || c.isDigit || c == '.' || c == '_') then + ParserState.mkUnexpectedError s + "LMFDB ids must consist only of lowercase letters, digits, periods, and underscores." + else + mkNodeToken lmfdbIdKind i true c s + +@[inherit_doc lmfdbIdFn] +def lmfdbIdNoAntiquot : Parser := { + fn := lmfdbIdFn + info := mkAtomicInfo "lmfdbId" +} + +@[inherit_doc lmfdbIdFn] +def lmfdbIdParser : Parser := + withAntiquot (mkAntiquot "lmfdbId" lmfdbIdKind) lmfdbIdNoAntiquot + end Mathlib.CrossRef open Mathlib.CrossRef @@ -183,6 +221,11 @@ def Lean.TSyntax.getWikidataId (stx : TSyntax wikidataIdKind) : CoreM String := let some val := Syntax.isLit? wikidataIdKind stx | throwError "Malformed Wikidata id" return val +/-- Extract the underlying identifier as a string from a `lmfdbId` node. -/ +def Lean.TSyntax.getLmfdbId (stx : TSyntax lmfdbIdKind) : CoreM String := do + let some val := Syntax.isLit? lmfdbIdKind stx | throwError "Malformed LMFDB id" + return val + namespace Lean.PrettyPrinter namespace Formatter @@ -195,6 +238,10 @@ namespace Formatter @[combinator_formatter wikidataIdNoAntiquot] def wikidataIdNoAntiquot.formatter := visitAtom wikidataIdKind +/-- The formatter for LMFDB identifier syntax. -/ +@[combinator_formatter lmfdbIdNoAntiquot] def lmfdbIdNoAntiquot.formatter := + visitAtom lmfdbIdKind + end Formatter namespace Parenthesizer @@ -205,6 +252,9 @@ namespace Parenthesizer /-- The parenthesizer for Wikidata identifier syntax. -/ @[combinator_parenthesizer wikidataIdNoAntiquot] def wikidataIdAntiquot.parenthesizer := visitToken +/-- The parenthesizer for LMFDB identifier syntax. -/ +@[combinator_parenthesizer lmfdbIdNoAntiquot] def lmfdbIdAntiquot.parenthesizer := visitToken + end Lean.PrettyPrinter.Parenthesizer namespace Mathlib.CrossRef @@ -265,6 +315,26 @@ initialize Lean.registerBuiltinAttribute { applicationTime := .beforeElaboration } +/-! ### LMFDB attribute -/ + +/-- The `lmfdb` attribute. +Use it as `@[lmfdb foo.bar "Optional comment"]` to associate a Mathlib declaration with +the corresponding [LMFDB](https://www.lmfdb.org) item. +-/ +syntax (name := lmfdbTag) "lmfdb" lmfdbIdParser (ppSpace str)? : attr + +initialize Lean.registerBuiltinAttribute { + name := `lmfdbTag + descr := "Apply an LMFDB identifier to a declaration." + add := fun decl stx _attrKind => do + let (id, comment) ← match stx with + | `(attr| lmfdb $id $[$comment]?) => pure (id, comment) + | _ => throwUnsupportedSyntax + addCrossRefDoc .lmfdb decl (← id.getLmfdbId) ((comment.map (·.getString)).getD "") + -- docstrings are immutable once an asynchronous elaboration task has been started + applicationTime := .beforeElaboration +} + end Mathlib.CrossRef /-- Returns the array of `Tag`s in the environment, sorted alphabetically by tag. -/ @@ -336,4 +406,16 @@ or declaration type (for definitions, structures, instances, etc.) after each su elab (name := wikidataTags) "#wikidata_tags" tk:("!")? : command => traceCrossRefs .wikidata (tk.isSome) +/-- The `#lmfdb_tags` command retrieves all declarations that have the `lmfdb` attribute. + +For each found declaration, it prints a line +``` +'declaration_name' corresponds to tag 'declaration_tag'. +``` +The variant `#lmfdb_tags!` also adds the theorem statement (for theorems) +or declaration type (for definitions, structures, instances, etc.) after each summary line. +-/ +elab (name := lmfdbTags) "#lmfdb_tags" tk:("!")? : command => + traceCrossRefs .lmfdb (tk.isSome) + end Mathlib.CrossRef diff --git a/MathlibTest/CrossRefAttribute.lean b/MathlibTest/CrossRefAttribute.lean index f9f683f33e13ba..43b8d766667efc 100644 --- a/MathlibTest/CrossRefAttribute.lean +++ b/MathlibTest/CrossRefAttribute.lean @@ -97,6 +97,41 @@ info: /-- info: Q42 -/ #guard_msgs in #parse Mathlib.CrossRef.wikidataIdFn => "Q42" +namespace LMFDB + +@[lmfdb group.abelian "A vacuous comment"] +theorem IsAbelian : 1 + 1 = 2 := by + rfl + +/-- +info: some ([LMFDB group.abelian](https://www.lmfdb.org/knowledge/show/group.abelian) (A vacuous comment)) +-/ +#guard_msgs in +run_cmd + Lean.logInfo m!"{← Lean.findDocString? (← Lean.getEnv) `LMFDB.IsAbelian}" + +/-- +error: :1:9: LMFDB ids must consist only of lowercase letters, digits, periods, and underscores. +-/ +#guard_msgs in #parse Mathlib.CrossRef.lmfdbIdFn => "LMFDB.tag" + +/-- info: lmfdb.tag_99 -/ +#guard_msgs in #parse Mathlib.CrossRef.lmfdbIdFn => "lmfdb.tag_99" + +/-- +error: :1:5: LMFDB ids must consist only of lowercase letters, digits, periods, and underscores. +-/ +#guard_msgs in #parse Mathlib.CrossRef.lmfdbIdFn => "LMFDB&tag" + +/-- +info: +[LMFDB group.abelian](https://www.lmfdb.org/knowledge/show/group.abelian) corresponds to declaration 'IsAbelian'. (A vacuous comment) +-/ +#guard_msgs in +#lmfdb_tags + +end LMFDB + section errors open Lean Parser Mathlib.CrossRef From 32ea179db3ac19f99d36de6a7c73c6b8b6d2acfd Mon Sep 17 00:00:00 2001 From: Chris Birkbeck <56166236+CBirkbeck@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:17:21 +0000 Subject: [PATCH 0687/1300] feat(NumberTheory): the abstract Hecke ring of a Hecke pair (#41251) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The definitions underlying abstract Hecke rings: - `IsHeckeTriple Δ H₁ H₂`: compatibility conditions on a submonoid `Δ` and two subgroups. - `HeckeCoset Δ H₁ H₂`: the double cosets `H₁\Δ/H₂`. - `HeckeCosetModule Δ H₁ H₂ Z`: their finitely-supported `Z`-linear combinations; `𝕋 Δ H Z` is the diagonal Hecke ring. The convolution product and ring structure come in later PRs. Co-Authored-By: Claude Opus 4.8 --- Mathlib.lean | 1 + Mathlib/NumberTheory/HeckeRing/Defs.lean | 227 +++++++++++++++++++++++ docs/references.bib | 29 +++ 3 files changed, 257 insertions(+) create mode 100644 Mathlib/NumberTheory/HeckeRing/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index 25322c6b37cb10..be5b9583eb2447 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5743,6 +5743,7 @@ public import Mathlib.NumberTheory.Harmonic.EulerMascheroni public import Mathlib.NumberTheory.Harmonic.GammaDeriv public import Mathlib.NumberTheory.Harmonic.Int public import Mathlib.NumberTheory.Harmonic.ZetaAsymp +public import Mathlib.NumberTheory.HeckeRing.Defs public import Mathlib.NumberTheory.Height.Basic public import Mathlib.NumberTheory.Height.EllipticCurve public import Mathlib.NumberTheory.Height.MvPolynomial diff --git a/Mathlib/NumberTheory/HeckeRing/Defs.lean b/Mathlib/NumberTheory/HeckeRing/Defs.lean new file mode 100644 index 00000000000000..ffe480b78f3397 --- /dev/null +++ b/Mathlib/NumberTheory/HeckeRing/Defs.lean @@ -0,0 +1,227 @@ +/- +Copyright (c) 2026 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ +module + +public import Mathlib.Algebra.Group.Finsupp +public import Mathlib.GroupTheory.Commensurable +public import Mathlib.GroupTheory.DoubleCoset + +/-! +# Hecke rings: definitions + +This file introduces the abstract Hecke ring of a *Hecke pair* `(H, Δ)` and, more generally, the +Hecke coset modules attached to a triple `(H₁, Δ, H₂)`, following [Shimura][shimura1971], +Chapter 3, and [Krieg][krieg1990], Chapter I. It sets up the underlying types: the compatibility +conditions `IsHeckeTriple Δ H₁ H₂` on a submonoid `Δ` of a group `G` and a pair of subgroups +of `G`, the double-coset quotient `HeckeCoset Δ H₁ H₂` of `Δ` by `H₁gH₂ = H₁hH₂`, and the Hecke +coset module `HeckeCosetModule Δ H₁ H₂ Z` of formal finitely-supported linear combinations of +double cosets. +The convolution product `HeckeCosetModule Δ H₁ H₂ Z × HeckeCosetModule Δ H₂ H₃ Z → +HeckeCosetModule Δ H₁ H₃ Z` and the ring structure on the diagonal Hecke ring `𝕋 Δ H Z` are +developed in later files. + +The relevance of the submonoid `Δ` may not be immediately obvious; a natural example is +`H = GL₂(ℤ)` inside `G = GL₂(ℚ)` with `Δ` the submonoid of integral matrices with nonzero +determinant, which is the Hecke pair underlying the classical Hecke operators `T_n`. Mixed +subgroups `H₁ ≠ H₂` arise for Hecke operators between different levels, e.g. `H₁ = Γ₀(N)` and +`H₂ = Γ₀(M)` inside the same `Δ`. + +## Main definitions + +* `IsHeckeTriple Δ H₁ H₂`: `(H₁, Δ, H₂)` is a Hecke triple, i.e. `H₁ ≤ Δ`, `H₂ ≤ Δ`, + `Commensurable H₁ H₂` and `Δ ≤ commensurator H₂`, making the double cosets `H₁\Δ/H₂` finite + unions of left cosets. The classical Hecke pair `(H, Δ)` is the diagonal case + `IsHeckeTriple Δ H H`. +* `HeckeCoset Δ H₁ H₂`: the quotient of `Δ` by the relation `H₁gH₂ = H₁hH₂`, i.e. the double + cosets `H₁\Δ/H₂` forming the basis of the Hecke coset module. +* `HeckeCosetModule Δ H₁ H₂ Z`: the Hecke coset module with coefficients in `Z`, the + finitely-supported `Z`-linear combinations of double cosets. +* `HeckeRing Δ H Z`, notation `𝕋 Δ H Z`: the Hecke ring, the diagonal case + `HeckeCosetModule Δ H H Z` of the Hecke coset module. + +## Implementation notes + +The data `(Δ, H₁, H₂)` enters unbundled, with the compatibility conditions collected in the +Prop-valued class `IsHeckeTriple`: the types `HeckeCoset Δ H₁ H₂` and `HeckeCosetModule Δ H₁ H₂ Z` +are built from the data alone and depend on no proofs, and a single ambient `Δ` shared by all +levels +(as in [Shimura][shimura1971]) means products of double cosets over different subgroups, +`H₁g₁H₂ * H₂g₂H₃ ⊆ Δ`, need no compatibility hypotheses. The conditions are only needed for the +finiteness of the coset decompositions, which enters through the `Fintype` instance on +`DoubleCoset.DecompQuotient` in later files. Requiring `Δ` to be a submonoid rather than a +subsemigroup loses no generality, since `H₁ ≤ Δ` already forces `1 ∈ Δ`. + +## References + +* [G. Shimura, *Introduction to the arithmetic theory of automorphic functions*][shimura1971] +* [A. Krieg, *Hecke algebras*][krieg1990] +-/ + +@[expose] public section + +open Subgroup Subgroup.Commensurable +open scoped Pointwise + +variable {G : Type*} [Group G] + +/-- A *Hecke triple* `(H₁, Δ, H₂)`: the compatibility conditions on a submonoid `Δ` and a pair +of subgroups `H₁, H₂` of `G` making the double cosets `H₁\Δ/H₂` finite unions of left cosets: +both subgroups are contained in `Δ`, they are commensurable, and `Δ` commensurates them. The +classical Hecke pair `(H, Δ)` of [Shimura][shimura1971], Chapter 3, is the diagonal case +`IsHeckeTriple Δ H H`. -/ +class IsHeckeTriple (Δ : Submonoid G) (H₁ H₂ : Subgroup G) : Prop where + /-- The left subgroup is contained in `Δ`. -/ + left_le : H₁.toSubmonoid ≤ Δ + /-- The right subgroup is contained in `Δ`. -/ + right_le : H₂.toSubmonoid ≤ Δ + /-- The two subgroups are commensurable. -/ + commensurable : Commensurable H₁ H₂ + /-- The submonoid `Δ` lies in the commensurator of the right subgroup (hence, the subgroups + being commensurable, also in that of the left one; see `le_commensurator_left`). -/ + le_commensurator_right : Δ ≤ (commensurator H₂).toSubmonoid + +namespace IsHeckeTriple + +variable {Δ : Submonoid G} {H₁ H₂ H₃ : Subgroup G} + +/-- The Hecke triple `(H, Δ, H)` coming from a pair `(H, Δ)` with `H ≤ Δ ≤ commensurator H`. -/ +theorem of_diagonal {H : Subgroup G} (h : H.toSubmonoid ≤ Δ) + (hc : Δ ≤ (commensurator H).toSubmonoid) : IsHeckeTriple Δ H H := + ⟨h, h, .refl H, hc⟩ + +/-- Elements of the left subgroup lie in `Δ`. -/ +theorem mem_of_mem_left (H₂ : Subgroup G) [IsHeckeTriple Δ H₁ H₂] {x : G} (hx : x ∈ H₁) : x ∈ Δ := + left_le H₂ hx + +/-- Elements of the right subgroup lie in `Δ`. -/ +theorem mem_of_mem_right (H₁ : Subgroup G) [IsHeckeTriple Δ H₁ H₂] {x : G} (hx : x ∈ H₂) : x ∈ Δ := + right_le H₁ hx + +/-- The submonoid `Δ` lies in the commensurator of the left subgroup. -/ +theorem le_commensurator_left (H₂ : Subgroup G) [h : IsHeckeTriple Δ H₁ H₂] : + Δ ≤ (commensurator H₁).toSubmonoid := by + rw [h.commensurable.eq] + exact h.le_commensurator_right + +/-- Elements of `Δ` lie in the commensurator of the right subgroup. -/ +theorem mem_commensurator_right (H₁ : Subgroup G) [IsHeckeTriple Δ H₁ H₂] (g : Δ) : + (g : G) ∈ commensurator H₂ := + le_commensurator_right H₁ g.2 + +/-- Elements of `Δ` lie in the commensurator of the left subgroup. -/ +theorem mem_commensurator_left (H₂ : Subgroup G) [IsHeckeTriple Δ H₁ H₂] (g : Δ) : + (g : G) ∈ commensurator H₁ := + le_commensurator_left H₂ g.2 + +/-- Conjugating the right subgroup of a Hecke triple `(H₁, Δ, H₂)` by an element of `Δ` gives a +subgroup commensurable with the left one. -/ +theorem commensurable_conjAct_right [IsHeckeTriple Δ H₁ H₂] (g : Δ) : + Commensurable (ConjAct.toConjAct (g : G) • H₂) H₁ := by + have hg : Commensurable (ConjAct.toConjAct (g : G) • H₂) H₂ := mem_commensurator_right H₁ g + exact hg.trans (commensurable (Δ := Δ)).symm + +/-- Hecke coset module data compose. Not an instance, since the middle subgroup cannot be +inferred from the goal. -/ +theorem trans [IsHeckeTriple Δ H₁ H₂] [IsHeckeTriple Δ H₂ H₃] : + IsHeckeTriple Δ H₁ H₃ := + ⟨left_le H₂, right_le H₂, + (commensurable (Δ := Δ) (H₁ := H₁) (H₂ := H₂)).trans + (commensurable (Δ := Δ) (H₁ := H₂) (H₂ := H₃)), + le_commensurator_right H₂⟩ + +/-- The left diagonal datum `(H₁, Δ, H₁)`. Not an instance, since `H₂` cannot be inferred. -/ +theorem diag_left [IsHeckeTriple Δ H₁ H₂] : IsHeckeTriple Δ H₁ H₁ := + ⟨left_le H₂, left_le H₂, .refl H₁, le_commensurator_left H₂⟩ + +/-- The right diagonal datum `(H₂, Δ, H₂)`. Not an instance, since `H₁` cannot be inferred. -/ +theorem diag_right [IsHeckeTriple Δ H₁ H₂] : IsHeckeTriple Δ H₂ H₂ := + ⟨right_le H₁, right_le H₁, .refl H₂, le_commensurator_right H₁⟩ + +end IsHeckeTriple + +/-- The setoid on `Δ` identifying elements with the same double coset `H₁gH₂ = H₁hH₂`, pulled +back from `DoubleCoset.setoid` along the inclusion `Δ ↪ G`. + +This is an `abbrev` rather than a global instance: the subgroups `H₁, H₂` cannot be inferred +from the submonoid `Δ`, so this cannot participate in instance search (and a global instance +would also create a `Setoid` diamond on `↥Δ` with the left-coset setoid). The quotient map is +`HeckeCoset.mk`. -/ +abbrev HeckeCoset.setoid (Δ : Submonoid G) (H₁ H₂ : Subgroup G) : Setoid Δ := + (DoubleCoset.setoid (H₁ : Set G) H₂).comap Subtype.val + +/-- A Hecke double coset: an equivalence class of `Δ`-elements under `H₁gH₂ = H₁hH₂`. This is +the basis type for the `HeckeCosetModule`. -/ +def HeckeCoset (Δ : Submonoid G) (H₁ H₂ : Subgroup G) := Quotient (HeckeCoset.setoid Δ H₁ H₂) + +namespace HeckeCoset + +variable {Δ : Submonoid G} + +/-- The double coset `H₁gH₂` of an element `g : Δ`. -/ +def mk (H₁ H₂ : Subgroup G) (g : Δ) : HeckeCoset Δ H₁ H₂ := + Quotient.mk (setoid Δ H₁ H₂) g + +variable (Δ) in +instance (H₁ H₂ : Subgroup G) : Inhabited (HeckeCoset Δ H₁ H₂) := ⟨mk H₁ H₂ ⟨1, Δ.one_mem⟩⟩ + +variable (Δ) in +/-- The identity double coset `H1H = H` of the diagonal (Hecke pair) case. -/ +instance (H : Subgroup G) : One (HeckeCoset Δ H H) := ⟨mk H H ⟨1, Δ.one_mem⟩⟩ + +lemma one_def (H : Subgroup G) : (1 : HeckeCoset Δ H H) = mk H H ⟨1, Δ.one_mem⟩ := rfl + +end HeckeCoset + +/-- The Hecke coset module with coefficients in `Z`: the finitely-supported `Z`-linear +combinations of double cosets `H₁\Δ/H₂`. For `H₁ = H₂` this is the underlying module of the +Hecke ring `𝕋 Δ H Z` (see `HeckeRing`). The coefficients `Z` need only carry a `Zero` for the +type to make sense; algebraic structure is added by the instances below at the weakest level each +requires. -/ +def HeckeCosetModule (Δ : Submonoid G) (H₁ H₂ : Subgroup G) (Z : Type*) [Zero Z] := + HeckeCoset Δ H₁ H₂ →₀ Z + +/-- The Hecke ring `𝕋 Δ H Z` with coefficients in `Z`: the diagonal Hecke coset module +`HeckeCosetModule Δ H H Z`, the finitely-supported `Z`-linear combinations of double cosets +`H\Δ/H`. The convolution product making it a ring is developed in later files. -/ +abbrev HeckeRing (Δ : Submonoid G) (H : Subgroup G) (Z : Type*) [Zero Z] := + HeckeCosetModule Δ H H Z + +@[inherit_doc] +scoped[HeckeCosetModule] notation "𝕋" => HeckeRing + +namespace HeckeCosetModule + +variable (Δ : Submonoid G) (H₁ H₂ : Subgroup G) (Z : Type*) + +/-- Elements of `HeckeCosetModule Δ H₁ H₂ Z` are functions `HeckeCoset Δ H₁ H₂ → Z` (finitely +supported). -/ +instance [Zero Z] : FunLike (HeckeCosetModule Δ H₁ H₂ Z) (HeckeCoset Δ H₁ H₂) Z := + inferInstanceAs (FunLike (HeckeCoset Δ H₁ H₂ →₀ Z) (HeckeCoset Δ H₁ H₂) Z) + +noncomputable instance [AddCommMonoid Z] : AddCommMonoid (HeckeCosetModule Δ H₁ H₂ Z) := + inferInstanceAs (AddCommMonoid (HeckeCoset Δ H₁ H₂ →₀ Z)) + +noncomputable instance [AddCommGroup Z] : AddCommGroup (HeckeCosetModule Δ H₁ H₂ Z) := + inferInstanceAs (AddCommGroup (HeckeCoset Δ H₁ H₂ →₀ Z)) + +/-- The sanctioned constructor of `HeckeCosetModule Δ H₁ H₂ Z` from a finitely-supported function +on double cosets. Build elements through `of` rather than relying on the definitional unfolding +`HeckeCosetModule Δ H₁ H₂ Z = (HeckeCoset Δ H₁ H₂ →₀ Z)`. -/ +def of {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {Z : Type*} [Zero Z] : + (HeckeCoset Δ H₁ H₂ →₀ Z) ≃ HeckeCosetModule Δ H₁ H₂ Z := + Equiv.refl _ + +@[simp] +lemma of_apply {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {Z : Type*} [Zero Z] + (f : HeckeCoset Δ H₁ H₂ →₀ Z) (D : HeckeCoset Δ H₁ H₂) : of f D = f D := + rfl + +@[ext] +lemma ext {Δ : Submonoid G} {H₁ H₂ : Subgroup G} {Z : Type*} [Zero Z] + {f g : HeckeCosetModule Δ H₁ H₂ Z} (h : ∀ D, f D = g D) : f = g := + Finsupp.ext h + +end HeckeCosetModule diff --git a/docs/references.bib b/docs/references.bib index 9597e32be3847f..e77de3dee27a70 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -3679,6 +3679,21 @@ @PhDThesis{ kremsater1972sequential school = {University of British Columbia} } +@Book{ krieg1990, + author = {Krieg, Aloys}, + title = {Hecke algebras}, + series = {Memoirs of the American Mathematical Society}, + volume = {87}, + number = {435}, + publisher = {American Mathematical Society, Providence, RI}, + year = {1990}, + pages = {x+158}, + issn = {0065-9266}, + mrnumber = {1027069}, + doi = {10.1090/memo/0435}, + url = {https://doi.org/10.1090/memo/0435} +} + @Book{ kung_rota_yan2009, author = {Kung, Joseph P. S. and Rota, Gian-Carlo and Yan, Catherine H.}, @@ -5448,6 +5463,20 @@ @Book{ sga-4-tome-1 zbl = {0234.00007} } +@Book{ shimura1971, + author = {Shimura, Goro}, + title = {Introduction to the arithmetic theory of automorphic + functions}, + series = {Publications of the Mathematical Society of Japan}, + volume = {11}, + note = {Kan\^{o} Memorial Lectures, No. 1}, + publisher = {Iwanami Shoten Publishers, Tokyo; Princeton University + Press, Princeton, NJ}, + year = {1971}, + pages = {xiv+267}, + mrnumber = {0314766} +} + @Book{ sierpinski1958, author = {Wacław Sierpiński}, title = {Cardinal and Ordinal Numbers}, From 8df0e1b604d1668165ad022c4bc8be3fe03e6efd Mon Sep 17 00:00:00 2001 From: Salvatore Mercuri <47568553+smmercuri@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:55:51 +0000 Subject: [PATCH 0688/1300] perf: make valuation unexposed (#41492) --- Mathlib/RingTheory/DedekindDomain/AdicValuation.lean | 4 ++-- Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index f7949de0bbed4a..1d7727d67a78a9 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -324,6 +324,7 @@ theorem intValuation_eq_one_iff {v : HeightOneSpectrum R} {x : R} : variable (K) in /-- The `v`-adic valuation of `x : K` is the valuation of `r` divided by the valuation of `s`, where `r` and `s` are chosen so that `x = r/s`. -/ +@[no_expose] def valuation (v : HeightOneSpectrum R) : Valuation K ℤᵐ⁰ := v.intValuation.extendToLocalization (fun r hr => Set.mem_compl <| v.intValuation_ne_zero' ⟨r, hr⟩) K @@ -331,8 +332,7 @@ def valuation (v : HeightOneSpectrum R) : Valuation K ℤᵐ⁰ := theorem valuation_def (x : K) : v.valuation K x = v.intValuation.extendToLocalization - (fun r hr => Set.mem_compl (v.intValuation_ne_zero' ⟨r, hr⟩)) K x := - rfl + (fun r hr => Set.mem_compl (v.intValuation_ne_zero' ⟨r, hr⟩)) K x := by rw [valuation] /-- The `v`-adic valuation of `r / s : K` is the valuation of `r` divided by the valuation of `s`. -/ diff --git a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean index 2359cb8268f2c8..d577397592f4f6 100644 --- a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean +++ b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean @@ -96,7 +96,7 @@ def valuationOfNeZeroToFun (x : Kˣ) : Multiplicative ℤ := theorem valuationOfNeZeroToFun_eq (x : Kˣ) : (v.valuationOfNeZeroToFun x : ℤᵐ⁰) = v.valuation K x := by classical - rw [show v.valuation K x = _ * _ by rfl] + rw [show v.valuation K x = _ * _ by rw [valuation_def]; rfl] rw [Units.val_inv_eq_inv_val] change _ = ite _ _ _ * (ite _ _ _)⁻¹ simp_rw [IsLocalization.toLocalizationMap_sec, SubmonoidClass.coe_subtype, From 2f35248703f4824acffd6dce07cc4d44105bc56f Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Wed, 8 Jul 2026 15:11:45 +0000 Subject: [PATCH 0689/1300] refactor(Algebra): weaken NormalizationMonoid (#34179) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR replaces the two fields ``` normUnit_mul : ∀ {a b}, a ≠ 0 → b ≠ 0 → normUnit (a * b) = normUnit a * normUnit b normUnit_coe_units : ∀ u : αˣ, normUnit u = u⁻¹ ``` in the definition of NormalizationMonoid by ``` normUnit_one : normUnit 1 = 1 normUnit_mul_units {a : α} (u : αˣ) : a ≠ 0 → normUnit (a * u) = u⁻¹ * normUnit a ``` and rename the old version to StrongNormalizationMonoid. The vast majority of API continue to hold under this weakened notion of NormalizationMonoid; only a handful requires the original notion. Every cancellative monoid with zero admits a weakened NormalizationMonoid structure, and every GCDMonoid admits a weakened NormalizedGCDMonoid structure. This allows us to generalize [Polynomial.normalizedGcdMonoid](https://leanprover-community.github.io/mathlib4_docs/Mathlib/RingTheory/Polynomial/Content.html#Polynomial.normalizedGcdMonoid) to all GCDMonoids. --- Mathlib/Algebra/GCDMonoid/Basic.lean | 476 ++++++++++-------- Mathlib/Algebra/GCDMonoid/Finset.lean | 35 +- .../Algebra/GCDMonoid/IntegrallyClosed.lean | 2 +- Mathlib/Algebra/GCDMonoid/Multiset.lean | 21 +- Mathlib/Algebra/GCDMonoid/Nat.lean | 19 +- Mathlib/Algebra/GCDMonoid/PUnit.lean | 4 +- Mathlib/Algebra/GroupWithZero/Associated.lean | 7 + Mathlib/Algebra/Polynomial/FieldDivision.lean | 35 +- Mathlib/NumberTheory/FLT/Basic.lean | 9 +- Mathlib/RingTheory/ChainOfDivisors.lean | 2 +- .../DedekindDomain/Ideal/Basic.lean | 6 +- .../DedekindDomain/Ideal/Lemmas.lean | 4 +- Mathlib/RingTheory/PicardGroup.lean | 2 +- Mathlib/RingTheory/Polynomial/Content.lean | 104 ++-- .../Polynomial/Cyclotomic/Expand.lean | 3 +- Mathlib/RingTheory/Polynomial/GaussLemma.lean | 74 +-- Mathlib/RingTheory/PowerSeries/Inverse.lean | 8 +- Mathlib/RingTheory/PrincipalIdealDomain.lean | 4 +- Mathlib/RingTheory/RootsOfUnity/Minpoly.lean | 3 +- .../UniqueFactorizationDomain/ClassGroup.lean | 33 +- .../UniqueFactorizationDomain/Finite.lean | 2 +- .../UniqueFactorizationDomain/GCDMonoid.lean | 18 +- .../Multiplicative.lean | 4 +- .../Multiplicity.lean | 2 +- .../NormalizedFactors.lean | 21 +- 25 files changed, 518 insertions(+), 380 deletions(-) diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index 2bafbe6eb818b4..7b7826686220ea 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -15,8 +15,11 @@ This file defines extra structures on `CommMonoidWithZero`s. ## Main Definitions * `NormalizationMonoid` +* `StrongNormalizationMonoid` * `GCDMonoid` +* `IsGCDMonoid` * `NormalizedGCDMonoid` +* `StrongNormalizedGCDMonoid` * `gcdMonoidOfGCD`, `gcdMonoidOfExistsGCD`, `normalizedGCDMonoidOfGCD`, `normalizedGCDMonoidOfExistsGCD` * `gcdMonoidOfLCM`, `gcdMonoidOfExistsLCM`, `normalizedGCDMonoidOfLCM`, @@ -27,16 +30,22 @@ For the `NormalizedGCDMonoid` instances on `ℕ` and `ℤ`, see `Mathlib/Algebra ## Implementation Notes * `NormalizationMonoid` is defined by assigning to each element a `normUnit` such that multiplying - by that unit normalizes the monoid, and `normalize` is an idempotent monoid homomorphism. This + by that unit normalizes the monoid, and `normalize` is an idempotent function. This definition as currently implemented does casework on `0`. +* `StrongNormalizationMonoid` further requires `normalize` to be a monoid homomorphism. + * `GCDMonoid` contains the definitions of `gcd` and `lcm` with the usual properties. They are both determined up to a unit. +* `IsGCDMonoid` is the predicate for the existence of a `GCDMonoid` structure. + * `NormalizedGCDMonoid` extends `NormalizationMonoid`, so the `gcd` and `lcm` are always normalized. This makes `gcd`s of polynomials easier to work with, but excludes Euclidean domains, and monoids without zero. +* `StrongNormalizedGCDMonoid` similarly extends `StrongNormalizationMonoid`. + * `gcdMonoidOfGCD` and `normalizedGCDMonoidOfGCD` noncomputably construct a `GCDMonoid` (resp. `NormalizedGCDMonoid`) structure just from the `gcd` and its properties. @@ -68,39 +77,64 @@ variable {α : Type*} /-- Normalization monoid: multiplying with `normUnit` gives a normal form for associated elements. -/ -class NormalizationMonoid (α : Type*) [CommMonoidWithZero α] where +class NormalizationMonoid (α : Type*) [MonoidWithZero α] where /-- `normUnit` assigns to each element of the monoid a unit of the monoid. -/ normUnit : α → αˣ - /-- The proposition that `normUnit` maps `0` to the identity. -/ normUnit_zero : normUnit 0 = 1 + normUnit_one : normUnit 1 = 1 + /-- The condition that ensures associated elements are normalized to the same element. -/ + normUnit_mul_units {a : α} (u : αˣ) : a ≠ 0 → normUnit (a * u) = u⁻¹ * normUnit a + +/-- Construct a `NormalizationMonoid` from a right inverse of `Associates.mk`. -/ +noncomputable abbrev NormalizationMonoid.ofRightInverse {α : Type*} [MonoidWithZero α] + [IsLeftCancelMulZero α] (out : Associates α → α) + (mk_out : ∀ a, Associates.mk (out a) = a) (out_one : out 1 = 1) : + NormalizationMonoid α := + have assoc a := (Associates.mk_eq_mk_iff_associated.mp <| mk_out (.mk a)).symm + let := Classical.dec + { normUnit a := if a = 0 then 1 else (assoc a).choose + normUnit_zero := if_pos rfl + normUnit_one := by + nontriviality α; rw [← Units.val_inj]; convert ← (assoc 1).choose_spec <;> simp [out_one] + normUnit_mul_units {a} u ha := by + simp_rw [Units.mul_left_eq_zero, if_neg ha, eq_inv_mul_iff_mul_eq, ← Units.val_inj] + rw [Units.val_mul, ← (IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha).eq_iff, + (assoc a).choose_spec, ← mul_assoc, (assoc _).choose_spec, + Associates.mk_eq_mk_iff_associated.mpr (associated_mul_unit_right a u u.isUnit)] } + +/-- A cancellative monoid with zero always admits a `NormalizationMonoid` structure. -/ +instance (α) [MonoidWithZero α] [IsLeftCancelMulZero α] : + Nonempty (NormalizationMonoid α) := .intro <| by + classical + exact .ofRightInverse + (fun a ↦ by classical exact if a = 1 then 1 else a.out) + (fun _ ↦ by split_ifs with h <;> simp [h]) (by simp) + +/-- Strong normalization monoid: multiplying with `normUnit` gives a normal form for associated +elements. It is stronger in that it ensures the normalization map is a monoid homomorphism. -/ +class StrongNormalizationMonoid (α) [CommMonoidWithZero α] extends NormalizationMonoid α where /-- The proposition that `normUnit` respects multiplication of non-zero elements. -/ normUnit_mul : ∀ {a b}, a ≠ 0 → b ≠ 0 → normUnit (a * b) = normUnit a * normUnit b /-- The proposition that `normUnit` maps units to their inverses. -/ normUnit_coe_units : ∀ u : αˣ, normUnit u = u⁻¹ + normUnit_one := normUnit_coe_units 1 + normUnit_mul_units {a} u ha := + (by nontriviality α; simp [normUnit_mul, ha, normUnit_coe_units, mul_comm]) -export NormalizationMonoid (normUnit normUnit_zero normUnit_mul normUnit_coe_units) +export NormalizationMonoid (normUnit normUnit_zero normUnit_one normUnit_mul_units) +export StrongNormalizationMonoid (normUnit_mul) -attribute [simp] normUnit_coe_units normUnit_zero normUnit_mul +attribute [simp] normUnit_zero normUnit_mul normUnit_one section NormalizationMonoid -variable [CommMonoidWithZero α] [NormalizationMonoid α] +variable [MonoidWithZero α] [NormalizationMonoid α] -@[simp] -theorem normUnit_one : normUnit (1 : α) = 1 := - normUnit_coe_units 1 +@[simp] theorem normUnit_coe_units (u : αˣ) : normUnit u.1 = u⁻¹ := by + nontriviality α; convert normUnit_mul_units u one_ne_zero using 1 <;> simp /-- Chooses an element of each associate class, by multiplying by `normUnit` -/ -def normalize : α →*₀ α where - toFun x := x * normUnit x - map_zero' := by - simp only [normUnit_zero] - exact mul_one (0 : α) - map_one' := by rw [normUnit_one, one_mul]; rfl - map_mul' x y := - (by_cases fun hx : x = 0 => by rw [hx, zero_mul, zero_mul, zero_mul]) fun hx => - (by_cases fun hy : y = 0 => by rw [hy, mul_zero, zero_mul, mul_zero]) fun hy => by - simp only [normUnit_mul hx hy, Units.val_mul]; simp only [mul_assoc, mul_left_comm y] +def normalize (x : α) : α := x * normUnit x theorem associated_normalize (x : α) : Associated x (normalize x) := ⟨_, rfl⟩ @@ -120,61 +154,44 @@ theorem Associates.mk_normalize (x : α) : Associates.mk (normalize x) = Associa theorem normalize_apply (x : α) : normalize x = x * normUnit x := rfl -theorem normalize_zero : normalize (0 : α) = 0 := - normalize.map_zero +@[simp] theorem normalize_zero : normalize (0 : α) = 0 := by simp [normalize] -theorem normalize_one : normalize (1 : α) = 1 := - normalize.map_one +@[simp] theorem normalize_one : normalize (1 : α) = 1 := by simp [normalize] -theorem normalize_coe_units (u : αˣ) : normalize (u : α) = 1 := by simp [normalize_apply] +theorem normalize_coe_units (u : αˣ) : normalize (u : α) = 1 := by simp [normalize] @[simp] theorem normalize_eq_zero {x : α} : normalize x = 0 ↔ x = 0 := ⟨fun hx => (associated_zero_iff_eq_zero x).1 <| hx ▸ associated_normalize _, by rintro rfl; exact normalize_zero⟩ -theorem normalize_eq_one {x : α} : normalize x = 1 ↔ IsUnit x := - ⟨fun hx => isUnit_iff_exists_inv.2 ⟨_, hx⟩, fun ⟨u, hu⟩ => hu ▸ normalize_coe_units u⟩ +theorem normalize_eq_one {x : α} : normalize x = 1 ↔ IsUnit x where + mp hx := Units.eq_inv_of_mul_eq_one_right hx ▸ Units.isUnit _ + mpr := fun ⟨u, hu⟩ ↦ hu ▸ normalize_coe_units u @[simp] theorem normUnit_mul_normUnit (a : α) : normUnit (a * normUnit a) = 1 := by nontriviality α using Subsingleton.elim a 0 obtain rfl | h := eq_or_ne a 0 · rw [normUnit_zero, zero_mul, normUnit_zero] - · rw [normUnit_mul h (Units.ne_zero _), normUnit_coe_units, mul_inv_eq_one] + · simp [normUnit_mul_units _ h] @[simp] theorem normalize_idem (x : α) : normalize (normalize x) = normalize x := by simp [normalize_apply] -theorem normalize_eq_normalize [IsCancelMulZero α] {a b : α} (hab : a ∣ b) (hba : b ∣ a) : - normalize a = normalize b := by - nontriviality α - rcases associated_of_dvd_dvd hab hba with ⟨u, rfl⟩ - refine by_cases (by rintro rfl; simp) fun ha : a ≠ 0 => ?_ - suffices a * ↑(normUnit a) = a * ↑u * ↑(normUnit a) * ↑u⁻¹ by - simpa only [normalize_apply, mul_assoc, normUnit_mul ha u.ne_zero, normUnit_coe_units] - calc - a * ↑(normUnit a) = a * ↑(normUnit a) * ↑u * ↑u⁻¹ := (Units.mul_inv_cancel_right _ _).symm - _ = a * ↑u * ↑(normUnit a) * ↑u⁻¹ := by rw [mul_right_comm a] - -theorem normalize_eq_normalize_iff [IsCancelMulZero α] {x y : α} : - normalize x = normalize y ↔ x ∣ y ∧ y ∣ x := - ⟨fun h => ⟨Units.dvd_mul_right.1 ⟨_, h.symm⟩, Units.dvd_mul_right.1 ⟨_, h⟩⟩, fun ⟨hxy, hyx⟩ => - normalize_eq_normalize hxy hyx⟩ - -theorem normalize_eq_normalize_iff_associated [IsCancelMulZero α] {x y : α} : - normalize x = normalize y ↔ Associated x y := by - rw [normalize_eq_normalize_iff, dvd_dvd_iff_associated] - -theorem dvd_antisymm_of_normalize_eq [IsCancelMulZero α] {a b : α} - (ha : normalize a = a) (hb : normalize b = b) - (hab : a ∣ b) (hba : b ∣ a) : a = b := - ha ▸ hb ▸ normalize_eq_normalize hab hba +theorem normalize_eq_normalize_iff_associated {a b : α} : + normalize a = normalize b ↔ Associated a b where + mp h := (associated_normalize a).trans <| .trans (.of_eq h) (associated_normalize b).symm + mpr := by + rintro ⟨u, rfl⟩ + nontriviality α + refine by_cases (by rintro rfl; simp only [zero_mul]) fun ha : a ≠ 0 ↦ ?_ + simp [normalize, normUnit_mul_units _ ha, mul_assoc] -theorem Associated.eq_of_normalized [IsCancelMulZero α] +theorem Associated.eq_of_normalized {a b : α} (h : Associated a b) (ha : normalize a = a) (hb : normalize b = b) : - a = b := - dvd_antisymm_of_normalize_eq ha hb h.dvd h.dvd' + a = b := by + rw [← ha, normalize_eq_normalize_iff_associated.mpr h, hb] @[simp] theorem dvd_normalize_iff {a b : α} : a ∣ normalize b ↔ a ∣ b := @@ -184,16 +201,33 @@ theorem dvd_normalize_iff {a b : α} : a ∣ normalize b ↔ a ∣ b := theorem normalize_dvd_iff {a b : α} : normalize a ∣ b ↔ a ∣ b := Units.mul_right_dvd +section + +variable [IsLeftCancelMulZero α] + +theorem normalize_eq_normalize {a b : α} (hab : a ∣ b) (hba : b ∣ a) : + normalize a = normalize b := + normalize_eq_normalize_iff_associated.mpr (associated_of_dvd_dvd hab hba) + +theorem normalize_eq_normalize_iff {x y : α} : normalize x = normalize y ↔ x ∣ y ∧ y ∣ x := by + rw [normalize_eq_normalize_iff_associated, dvd_dvd_iff_associated] + +theorem dvd_antisymm_of_normalize_eq {a b : α} (ha : normalize a = a) (hb : normalize b = b) + (hab : a ∣ b) (hba : b ∣ a) : a = b := + ha ▸ hb ▸ normalize_eq_normalize hab hba + +end + end NormalizationMonoid namespace Associates -variable [CommMonoidWithZero α] [IsCancelMulZero α] [NormalizationMonoid α] +variable [MonoidWithZero α] [NormalizationMonoid α] /-- Maps an element of `Associates` back to the normalized element of its associate class -/ protected def out : Associates α → α := - (Quotient.lift (normalize : α → α)) fun a _ ⟨_, hu⟩ => - hu ▸ normalize_eq_normalize ⟨_, rfl⟩ (Units.mul_right_dvd.2 <| dvd_refl a) + (Quotient.lift (normalize : α → α)) fun _ _ ⟨_, hu⟩ => + hu ▸ normalize_eq_normalize_iff_associated.mpr ⟨_, rfl⟩ @[simp] theorem out_mk (a : α) : (Associates.mk a).out = normalize a := @@ -203,18 +237,6 @@ theorem out_mk (a : α) : (Associates.mk a).out = normalize a := theorem out_one : (1 : Associates α).out = 1 := normalize_one -theorem out_mul (a b : Associates α) : (a * b).out = a.out * b.out := - Quotient.inductionOn₂ a b fun _ _ => by - simp only [Associates.quotient_mk_eq_mk, out_mk, mk_mul_mk, normalize.map_mul] - -theorem dvd_out_iff (a : α) (b : Associates α) : a ∣ b.out ↔ Associates.mk a ≤ b := - Quotient.inductionOn b <| by - simp [Associates.out_mk, Associates.quotient_mk_eq_mk, mk_le_mk_iff_dvd] - -theorem out_dvd_iff (a : α) (b : Associates α) : b.out ∣ a ↔ b ≤ Associates.mk a := - Quotient.inductionOn b <| by - simp [Associates.out_mk, Associates.quotient_mk_eq_mk, mk_le_mk_iff_dvd] - @[simp] theorem out_top : (⊤ : Associates α).out = 0 := normalize_zero @@ -237,8 +259,48 @@ theorem out_eq_zero_iff {a : Associates α} : a.out = 0 ↔ a = 0 := theorem out_zero : (0 : Associates α).out = 0 := by simp +variable {α : Type*} [CommMonoidWithZero α] [NormalizationMonoid α] + +theorem out_mul' (a b : Associates α) : Associated (a * b).out (a.out * b.out) := + Quotient.inductionOn₂ a b fun _ _ ↦ normalize_associated_iff.mpr <| + .mul_mul (associated_normalize _) (associated_normalize _) + +theorem dvd_out_iff (a : α) (b : Associates α) : a ∣ b.out ↔ Associates.mk a ≤ b := + Quotient.inductionOn b <| by + simp [Associates.out_mk, Associates.quotient_mk_eq_mk, mk_le_mk_iff_dvd] + +theorem out_dvd_iff (a : α) (b : Associates α) : b.out ∣ a ↔ b ≤ Associates.mk a := + Quotient.inductionOn b <| by + simp [Associates.out_mk, Associates.quotient_mk_eq_mk, mk_le_mk_iff_dvd] + end Associates +section StrongNormalizationMonoid + +variable [CommMonoidWithZero α] [StrongNormalizationMonoid α] + +@[simp] theorem normalize_mul (x y : α) : normalize (x * y) = normalize x * normalize y := by + obtain rfl | hx := eq_or_ne x 0; · simp + obtain rfl | hy := eq_or_ne y 0; · simp + simp_rw [normalize, normUnit_mul hx hy] + ac_rfl + +/-- `normalize` in a `StrongNormalizationMonoid` as a `MonoidWithZeroHom`. -/ +def normalizeHom : α →*₀ α where + toFun := normalize + map_zero' := normalize_zero + map_one' := normalize_one + map_mul' := normalize_mul + +theorem coe_normalizeHom : normalizeHom (α := α) = normalize (α := α) := + rfl + +theorem Associates.out_mul (a b : Associates α) : (a * b).out = a.out * b.out := + Quotient.inductionOn₂ a b fun _ _ => by + simp only [Associates.quotient_mk_eq_mk, out_mk, mk_mul_mk, normalize_mul] + +end StrongNormalizationMonoid + /-- GCD monoid: a cancellative `CommMonoidWithZero` with `gcd` (greatest common divisor) and `lcm` (least common multiple) operations, determined up to a unit. The type class focuses on `gcd` and we derive the corresponding `lcm` facts from `gcd`. @@ -261,14 +323,17 @@ class GCDMonoid (α : Type*) [CommMonoidWithZero α] extends IsCancelMulZero α /-- `0` is right-absorbing. -/ lcm_zero_right : ∀ a, lcm a 0 = 0 +/-- Existence of a `GCDMonoid` structure on a `CommMonoidWithZero`. -/ +class inductive IsGCDMonoid (α : Type*) [CommMonoidWithZero α] : Prop + | intro : GCDMonoid α → IsGCDMonoid α + attribute [instance 100] GCDMonoid.toIsCancelMulZero /-- Normalized GCD monoid: a cancellative `CommMonoidWithZero` with normalization and `gcd` (greatest common divisor) and `lcm` (least common multiple) operations. In this setting `gcd` and `lcm` form a bounded lattice on the associated elements where `gcd` is the infimum, `lcm` is the supremum, `1` is bottom, and `0` is top. The type class focuses on `gcd` and we derive the -corresponding `lcm` facts from `gcd`. --/ +corresponding `lcm` facts from `gcd`. -/ class NormalizedGCDMonoid (α : Type*) [CommMonoidWithZero α] extends NormalizationMonoid α, GCDMonoid α where /-- The GCD is normalized to itself. -/ @@ -276,21 +341,37 @@ class NormalizedGCDMonoid (α : Type*) [CommMonoidWithZero α] extends Normaliza /-- The LCM is normalized to itself. -/ normalize_lcm : ∀ a b, normalize (lcm a b) = lcm a b -export GCDMonoid (gcd lcm gcd_dvd_left gcd_dvd_right dvd_gcd lcm_zero_left lcm_zero_right) +/-- Strong normalized GCD monoid: a `NormalizedGCDMonoid` whose `normalize` function is a +monoid homomorphism. -/ +class StrongNormalizedGCDMonoid (α : Type*) [CommMonoidWithZero α] extends + StrongNormalizationMonoid α, GCDMonoid α where + /-- The GCD is normalized to itself. -/ + normalize_gcd : ∀ a b, normalize (gcd a b) = gcd a b + /-- The LCM is normalized to itself. -/ + normalize_lcm : ∀ a b, normalize (lcm a b) = lcm a b + +export GCDMonoid (gcd lcm gcd_dvd_left gcd_dvd_right dvd_gcd + gcd_mul_lcm lcm_zero_left lcm_zero_right) attribute [simp] lcm_zero_left lcm_zero_right +instance (α) [CommMonoidWithZero α] [StrongNormalizedGCDMonoid α] : NormalizedGCDMonoid α where + normalize_gcd := StrongNormalizedGCDMonoid.normalize_gcd + normalize_lcm := StrongNormalizedGCDMonoid.normalize_lcm + section GCDMonoid variable [CommMonoidWithZero α] instance [NormalizationMonoid α] : Nonempty (NormalizationMonoid α) := ⟨‹_›⟩ -instance [GCDMonoid α] : Nonempty (GCDMonoid α) := ⟨‹_›⟩ -instance [NormalizedGCDMonoid α] : Nonempty (NormalizedGCDMonoid α) := ⟨‹_›⟩ -instance [h : Nonempty (NormalizedGCDMonoid α)] : Nonempty (NormalizationMonoid α) := - h.elim fun _ ↦ inferInstance -instance [h : Nonempty (NormalizedGCDMonoid α)] : Nonempty (GCDMonoid α) := - h.elim fun _ ↦ inferInstance +instance [StrongNormalizationMonoid α] : Nonempty (StrongNormalizationMonoid α) := ⟨‹_›⟩ + +instance (priority := 100) [GCDMonoid α] : IsGCDMonoid α := ⟨‹_›⟩ + +variable (α) in +-- This is not an instance due to performance reasons. +theorem IsGCDMonoid.isCancelMulZero [h : IsGCDMonoid α] : IsCancelMulZero α := + h.rec fun _ ↦ inferInstance theorem gcd_isUnit_iff_isRelPrime [GCDMonoid α] {a b : α} : IsUnit (gcd a b) ↔ IsRelPrime a b := @@ -300,9 +381,6 @@ theorem gcd_isUnit_iff_isRelPrime [GCDMonoid α] {a b : α} : theorem normalize_gcd [NormalizedGCDMonoid α] : ∀ a b : α, normalize (gcd a b) = gcd a b := NormalizedGCDMonoid.normalize_gcd -theorem gcd_mul_lcm [GCDMonoid α] : ∀ a b : α, Associated (gcd a b * lcm a b) (a * b) := - GCDMonoid.gcd_mul_lcm - section GCD theorem dvd_gcd_iff [GCDMonoid α] (a b c : α) : a ∣ gcd b c ↔ a ∣ b ∧ a ∣ c := @@ -410,7 +488,7 @@ theorem gcd_same [NormalizedGCDMonoid α] (a : α) : gcd a a = normalize a := gcd_eq_normalize (gcd_dvd_left _ _) (dvd_gcd (dvd_refl a) (dvd_refl a)) @[simp] -theorem gcd_mul_left [NormalizedGCDMonoid α] (a b c : α) : +theorem gcd_mul_left [StrongNormalizedGCDMonoid α] (a b c : α) : gcd (a * b) (a * c) = normalize a * gcd b c := (by_cases (by rintro rfl; simp)) fun ha : a ≠ 0 => @@ -437,7 +515,7 @@ theorem gcd_mul_left' [GCDMonoid α] (a b c : α) : · exact dvd_gcd (mul_dvd_mul_left a <| gcd_dvd_left _ _) (mul_dvd_mul_left a <| gcd_dvd_right _ _) @[simp] -theorem gcd_mul_right [NormalizedGCDMonoid α] (a b c : α) : +theorem gcd_mul_right [StrongNormalizedGCDMonoid α] (a b c : α) : gcd (b * a) (c * a) = gcd b c * normalize a := by simp only [mul_comm, gcd_mul_left] @[simp] @@ -493,7 +571,7 @@ theorem dvd_mul_gcd_iff_dvd_mul [GCDMonoid α] {m n k : α} : k ∣ m * gcd k n Note: In general, this representation is highly non-unique. See `Nat.dvdProdDvdOfDvdProd` for a constructive version on `ℕ`. -/ -instance [h : Nonempty (GCDMonoid α)] : DecompositionMonoid α where +instance [h : IsGCDMonoid α] : DecompositionMonoid α where primal k m n H := by cases h by_cases h0 : gcd k m = 0 @@ -609,14 +687,14 @@ theorem exists_eq_pow_of_mul_eq_pow [GCDMonoid α] [Subsingleton αˣ] theorem gcd_greatest {α : Type*} [CommMonoidWithZero α] [NormalizedGCDMonoid α] {a b d : α} (hda : d ∣ a) (hdb : d ∣ b) (hd : ∀ e : α, e ∣ a → e ∣ b → e ∣ d) : - GCDMonoid.gcd a b = normalize d := - haveI h := hd _ (GCDMonoid.gcd_dvd_left a b) (GCDMonoid.gcd_dvd_right a b) + gcd a b = normalize d := + haveI h := hd _ (gcd_dvd_left a b) (gcd_dvd_right a b) gcd_eq_normalize h (GCDMonoid.dvd_gcd hda hdb) theorem gcd_greatest_associated {α : Type*} [CommMonoidWithZero α] [GCDMonoid α] {a b d : α} (hda : d ∣ a) (hdb : d ∣ b) (hd : ∀ e : α, e ∣ a → e ∣ b → e ∣ d) : - Associated d (GCDMonoid.gcd a b) := - haveI h := hd _ (GCDMonoid.gcd_dvd_left a b) (GCDMonoid.gcd_dvd_right a b) + Associated d (gcd a b) := + haveI h := hd _ (gcd_dvd_left a b) (gcd_dvd_right a b) associated_of_dvd_dvd (GCDMonoid.dvd_gcd hda hdb) h theorem isUnit_gcd_of_eq_mul_gcd {α : Type*} [CommMonoidWithZero α] [GCDMonoid α] @@ -703,6 +781,9 @@ theorem lcm_eq_zero_iff [GCDMonoid α] (a b : α) : lcm a b = 0 ↔ a = 0 ∨ b rwa [← mul_eq_zero, ← associated_zero_iff_eq_zero]) (by rintro (rfl | rfl) <;> [apply lcm_zero_left; apply lcm_zero_right]) +theorem lcm_ne_zero_iff [GCDMonoid α] {a b : α} : lcm a b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 := by + simp + @[simp] theorem normalize_lcm [NormalizedGCDMonoid α] (a b : α) : normalize (lcm a b) = lcm a b := NormalizedGCDMonoid.normalize_lcm a b @@ -775,7 +856,7 @@ theorem lcm_eq_one_iff [NormalizedGCDMonoid α] (a b : α) : lcm a b = 1 ↔ a rw [lcm_units_coe_left, normalize_coe_units] @[simp] -theorem lcm_mul_left [NormalizedGCDMonoid α] (a b c : α) : +theorem lcm_mul_left [StrongNormalizedGCDMonoid α] (a b c : α) : lcm (a * b) (a * c) = normalize a * lcm b c := (by_cases (by rintro rfl; simp)) fun ha : a ≠ 0 => @@ -790,7 +871,7 @@ theorem lcm_mul_left [NormalizedGCDMonoid α] (a b c : α) : ((mul_dvd_mul_iff_left ha).1 <| eq ▸ dvd_lcm_right _ _))) @[simp] -theorem lcm_mul_right [NormalizedGCDMonoid α] (a b c : α) : +theorem lcm_mul_right [StrongNormalizedGCDMonoid α] (a b c : α) : lcm (b * a) (c * a) = lcm b c * normalize a := by simp only [mul_comm, lcm_mul_left] theorem lcm_eq_left_iff [NormalizedGCDMonoid α] (a b : α) (h : normalize a = a) : @@ -874,15 +955,22 @@ section UniqueUnit variable [CommMonoidWithZero α] [Subsingleton αˣ] -- see Note [lower instance priority] -instance (priority := 100) NormalizationMonoid.ofUniqueUnits : NormalizationMonoid α where +instance (priority := 100) : StrongNormalizationMonoid α where normUnit _ := 1 normUnit_zero := rfl normUnit_mul _ _ := (mul_one 1).symm normUnit_coe_units _ := Subsingleton.elim _ _ -instance uniqueNormalizationMonoidOfUniqueUnits : Unique (NormalizationMonoid α) where - default := .ofUniqueUnits - uniq := fun ⟨u, _, _, _⟩ => by congr; simp [eq_iff_true_of_subsingleton] +@[deprecated (since := "2026-07-08")] +alias NormalizationMonoid.ofUniqueUnits := instStrongNormalizationMonoid + +instance : Unique (NormalizationMonoid α) where + default := inferInstance + uniq := by rintro ⟨⟩; congr; apply Subsingleton.elim + +instance : Unique (StrongNormalizationMonoid α) where + default := inferInstance + uniq := by rintro ⟨⟩; congr; apply Subsingleton.elim instance subsingleton_gcdMonoid_of_unique_units : Subsingleton (GCDMonoid α) := ⟨fun g₁ g₂ => by @@ -901,15 +989,18 @@ instance subsingleton_gcdMonoid_of_unique_units : Subsingleton (GCDMonoid α) := instance subsingleton_normalizedGCDMonoid_of_unique_units : Subsingleton (NormalizedGCDMonoid α) := ⟨by - intro a b - cases a; rename_i a_norm a_gcd _ _ - cases b; rename_i b_norm b_gcd _ _ - have := Subsingleton.elim a_gcd b_gcd - subst this - have := Subsingleton.elim a_norm b_norm - subst this + rintro @⟨a_norm, a_gcd, _⟩ @⟨b_norm, b_gcd, _⟩ + cases Subsingleton.elim a_gcd b_gcd + cases Subsingleton.elim a_norm b_norm rfl⟩ +instance : Subsingleton (StrongNormalizedGCDMonoid α) where + allEq := by + rintro @⟨a_norm, a_gcd, _⟩ @⟨b_norm, b_gcd, _⟩ + cases Subsingleton.elim a_gcd b_gcd + cases Subsingleton.elim a_norm b_norm + rfl + @[simp] theorem normUnit_eq_one (x : α) : normUnit x = 1 := rfl @@ -920,7 +1011,7 @@ theorem normalize_eq (x : α) : normalize x = x := /-- If a monoid's only unit is `1`, then it is isomorphic to its associates. -/ @[simps] -def associatesEquivOfUniqueUnits [IsCancelMulZero α] : Associates α ≃* α where +def associatesEquivOfUniqueUnits : Associates α ≃* α where toFun := Associates.out invFun := Associates.mk left_inv := Associates.mk_out @@ -968,9 +1059,9 @@ variable [IsCancelMulZero α] /-- Define `NormalizationMonoid` on a structure from a `MonoidHom` inverse to `Associates.mk`. -/ @[implicit_reducible] -def normalizationMonoidOfMonoidHomRightInverse [DecidableEq α] (f : Associates α →* α) +def strongNormalizationMonoidOfMonoidHomRightInverse [DecidableEq α] (f : Associates α →* α) (hinv : Function.RightInverse f Associates.mk) : - NormalizationMonoid α where + StrongNormalizationMonoid α where normUnit a := if a = 0 then 1 else Classical.choose (Associates.mk_eq_mk_iff_associated.1 (hinv (Associates.mk a)).symm) @@ -992,6 +1083,10 @@ def normalizationMonoidOfMonoidHomRightInverse [DecidableEq α] (f : Associates Associates.mk_eq_mk_iff_associated.2 (associated_one_iff_isUnit.2 ⟨u, rfl⟩), Associates.mk_one, map_one] +@[deprecated (since := "2026-07-08")] +noncomputable alias normalizationMonoidOfMonoidHomRightInverse := + strongNormalizationMonoidOfMonoidHomRightInverse + /-- Define `GCDMonoid` on a structure just from the `gcd` and its properties. -/ @[implicit_reducible] noncomputable def gcdMonoidOfGCD [DecidableEq α] (gcd : α → α → α) @@ -1030,50 +1125,24 @@ noncomputable def normalizedGCDMonoidOfGCD [NormalizationMonoid α] [DecidableEq gcd gcd_dvd_left gcd_dvd_right - dvd_gcd := fun {_ _ _} => dvd_gcd + dvd_gcd normalize_gcd - lcm := fun a b => + lcm a b := if a = 0 then 0 - else Classical.choose (dvd_normalize_iff.2 ((gcd_dvd_left a b).trans (Dvd.intro b rfl))) - normalize_lcm := fun a b => by - dsimp [normalize] - split_ifs with a0 - · exact @normalize_zero α _ _ - · have := (Classical.choose_spec - (dvd_normalize_iff.2 ((gcd_dvd_left a b).trans (Dvd.intro b rfl)))).symm - set l := Classical.choose (dvd_normalize_iff.2 ((gcd_dvd_left a b).trans (Dvd.intro b rfl))) - obtain rfl | hb := eq_or_ne b 0 - · rw [mul_zero a, normalize_zero, mul_eq_zero] at this - obtain ha | hl := this - · apply (a0 _).elim - rw [← zero_dvd_iff, ← ha] - exact gcd_dvd_left _ _ - · rw [hl, zero_mul] - have h1 : gcd a b ≠ 0 := by - have hab : a * b ≠ 0 := mul_ne_zero a0 hb - contrapose hab - rw [← normalize_eq_zero, ← this, hab, zero_mul] - have h2 : normalize (gcd a b * l) = gcd a b * l := by rw [this, normalize_idem] - rw [← normalize_gcd] at this - rwa [normalize.map_mul, normalize_gcd, mul_right_inj' h1] at h2 - gcd_mul_lcm := fun a b => by + else normalize (Classical.choose ((gcd_dvd_left a b).trans (Dvd.intro b rfl))) + normalize_lcm a b := by split_ifs <;> simp + gcd_mul_lcm a b := by split_ifs with a0 · rw [mul_zero, a0, zero_mul] - · rw [← Classical.choose_spec (dvd_normalize_iff.2 ((gcd_dvd_left a b).trans (.intro b rfl)))] - exact normalize_associated (a * b) - lcm_zero_left := fun _ => if_pos rfl - lcm_zero_right := fun a => by + · exact .trans ((normalize_associated _).mul_left _) + (.of_eq (Classical.choose_spec (_ : _ ∣ a * b)).symm) + lcm_zero_left _ := if_pos rfl + lcm_zero_right a := by split_ifs with a0 · rfl - rw [← normalize_eq_zero] at a0 - have h := - (Classical.choose_spec (dvd_normalize_iff.2 ((gcd_dvd_left a 0).trans (.intro 0 rfl)))).symm - have gcd0 : gcd a 0 = normalize a := by - rw [← normalize_gcd] - exact normalize_eq_normalize (gcd_dvd_left _ _) (dvd_gcd (dvd_refl a) (dvd_zero a)) - rw [← gcd0] at a0 - apply Or.resolve_left (mul_eq_zero.1 _) a0 - rw [h, mul_zero, normalize_zero] } + let := gcdMonoidOfGCD gcd gcd_dvd_left gcd_dvd_right dvd_gcd + simpa [gcd_ne_zero_of_left a0] using show GCDMonoid.gcd .. * _ = _ + from (Classical.choose_spec ((gcd_dvd_left a 0).trans (.intro 0 rfl))).symm } /-- Define `GCDMonoid` on a structure just from the `lcm` and its properties. -/ @[implicit_reducible] @@ -1147,84 +1216,48 @@ noncomputable def normalizedGCDMonoidOfLCM [NormalizationMonoid α] [DecidableEq (dvd_lcm_left : ∀ a b, a ∣ lcm a b) (dvd_lcm_right : ∀ a b, b ∣ lcm a b) (lcm_dvd : ∀ {a b c}, c ∣ a → b ∣ a → lcm c b ∣ a) (normalize_lcm : ∀ a b, normalize (lcm a b) = lcm a b) : NormalizedGCDMonoid α := - let exists_gcd a b := dvd_normalize_iff.2 (lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left a rfl)) + let exists_gcd a b := lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left a rfl) + let := gcdMonoidOfLCM lcm dvd_lcm_left dvd_lcm_right lcm_dvd { (inferInstance : NormalizationMonoid α) with lcm - gcd := fun a b => - if a = 0 then normalize b - else if b = 0 then normalize a else Classical.choose (exists_gcd a b) - gcd_mul_lcm := fun a b => by + gcd a b := normalize <| + if a = 0 then b + else if b = 0 then a else Classical.choose (exists_gcd a b) + gcd_mul_lcm a b := by split_ifs with h h_1 · rw [h, eq_zero_of_zero_dvd (dvd_lcm_left _ _), mul_zero, zero_mul] · rw [h_1, eq_zero_of_zero_dvd (dvd_lcm_right _ _), mul_zero, mul_zero] - rw [mul_comm, ← Classical.choose_spec (exists_gcd a b)] - exact normalize_associated (a * b) + rw [mul_comm] + exact ((normalize_associated _).mul_left _).trans + (.of_eq (Classical.choose_spec (exists_gcd a b)).symm) normalize_lcm - normalize_gcd := fun a b => by - dsimp [normalize] - split_ifs with h h_1 - · apply normalize_idem - · apply normalize_idem - have h0 : lcm a b ≠ 0 := by - intro con - have h := lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left a rfl) - rw [con, zero_dvd_iff, mul_eq_zero] at h - cases h - · exact absurd ‹a = 0› h - · exact absurd ‹b = 0› h_1 - apply mul_left_cancel₀ h0 - refine _root_.trans ?_ (Classical.choose_spec (exists_gcd a b)) - conv_lhs => - congr - rw [← normalize_lcm a b] - rw [← normalize_apply, ← normalize.map_mul, - ← Classical.choose_spec (exists_gcd a b), normalize_idem] - lcm_zero_left := fun _ => eq_zero_of_zero_dvd (dvd_lcm_left _ _) - lcm_zero_right := fun _ => eq_zero_of_zero_dvd (dvd_lcm_right _ _) - gcd_dvd_left := fun a b => by + normalize_gcd a b := normalize_idem _ + lcm_zero_left _ := eq_zero_of_zero_dvd (dvd_lcm_left _ _) + lcm_zero_right _ := eq_zero_of_zero_dvd (dvd_lcm_right _ _) + gcd_dvd_left a b := by split_ifs with h h_1 · rw [h] apply dvd_zero · exact (normalize_associated _).dvd - have h0 : lcm a b ≠ 0 := by - intro con - have h := lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left a rfl) - rw [con, zero_dvd_iff, mul_eq_zero] at h - cases h - · exact absurd ‹a = 0› h - · exact absurd ‹b = 0› h_1 - rw [← mul_dvd_mul_iff_left h0, ← Classical.choose_spec (exists_gcd a b), normalize_dvd_iff, + have h0 : lcm a b ≠ 0 := lcm_ne_zero_iff.mpr ⟨h, h_1⟩ + rw [normalize_dvd_iff, ← mul_dvd_mul_iff_left h0, ← Classical.choose_spec (exists_gcd a b), mul_comm, mul_dvd_mul_iff_right h] apply dvd_lcm_right - gcd_dvd_right := fun a b => by + gcd_dvd_right a b := by split_ifs with h h_1 · exact (normalize_associated _).dvd · rw [h_1] apply dvd_zero - have h0 : lcm a b ≠ 0 := by - intro con - have h := lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left a rfl) - rw [con, zero_dvd_iff, mul_eq_zero] at h - cases h - · exact absurd ‹a = 0› h - · exact absurd ‹b = 0› h_1 - rw [← mul_dvd_mul_iff_left h0, ← Classical.choose_spec (exists_gcd a b), normalize_dvd_iff, + have h0 : lcm a b ≠ 0 := lcm_ne_zero_iff.mpr ⟨h, h_1⟩ + rw [normalize_dvd_iff, ← mul_dvd_mul_iff_left h0, ← Classical.choose_spec (exists_gcd a b), mul_dvd_mul_iff_right h_1] apply dvd_lcm_left - dvd_gcd := fun {a b c} ac ab => by + dvd_gcd {a b c} ac ab := by split_ifs with h h_1 · apply dvd_normalize_iff.2 ab · apply dvd_normalize_iff.2 ac - have h0 : lcm c b ≠ 0 := by - intro con - have h := lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left c rfl) - rw [con, zero_dvd_iff, mul_eq_zero] at h - cases h - · exact absurd ‹c = 0› h - · exact absurd ‹b = 0› h_1 - rw [← mul_dvd_mul_iff_left h0, ← Classical.choose_spec - (dvd_normalize_iff.2 (lcm_dvd (Dvd.intro b rfl) (Dvd.intro_left c rfl))), - dvd_normalize_iff] + have h0 : lcm c b ≠ 0 := lcm_ne_zero_iff.mpr ⟨h, h_1⟩ + rw [dvd_normalize_iff, ← mul_dvd_mul_iff_left h0, ← Classical.choose_spec (exists_gcd c b)] rcases ab with ⟨d, rfl⟩ rw [mul_eq_zero] at h_1 push Not at h_1 @@ -1254,6 +1287,29 @@ noncomputable def normalizedGCDMonoidOfExistsGCD [NormalizationMonoid α] [Decid (fun {a b c} ac ab => dvd_normalize_iff.2 ((Classical.choose_spec (h c b) a).1 ⟨ac, ab⟩)) fun _ _ => normalize_idem _ +/-- Define a `StrongNormalizedGCDMonoid` structure on a monoid just from +the existence of a `gcd`. -/ +abbrev strongNormalizedGCDMonoidOfExistsGCD [StrongNormalizationMonoid α] [DecidableEq α] + (h : ∀ a b : α, ∃ c : α, ∀ d : α, d ∣ a ∧ d ∣ b ↔ d ∣ c) : StrongNormalizedGCDMonoid α where + __ := normalizedGCDMonoidOfExistsGCD h + __ := ‹StrongNormalizationMonoid α› + +theorem nonempty_normalizedGCDMonoid_iff_isGCDMonoid {α} [CommMonoidWithZero α] : + Nonempty (NormalizedGCDMonoid α) ↔ IsGCDMonoid α where + mp := fun ⟨_⟩ ↦ inferInstance + mpr := fun ⟨_⟩ ↦ by + have := Classical.arbitrary (NormalizationMonoid α) + classical exact ⟨normalizedGCDMonoidOfExistsGCD fun _ _ ↦ ⟨_, fun _ ↦ (dvd_gcd_iff ..).symm⟩⟩ + +instance (α) [CommMonoidWithZero α] [IsGCDMonoid α] : Nonempty (NormalizedGCDMonoid α) := + nonempty_normalizedGCDMonoid_iff_isGCDMonoid.mpr ‹_› + +theorem nonempty_strongNormalizedGCDMonoid_iff {α} [CommMonoidWithZero α] : + Nonempty (StrongNormalizedGCDMonoid α) ↔ + IsGCDMonoid α ∧ Nonempty (StrongNormalizationMonoid α) := + ⟨fun ⟨_⟩ ↦ ⟨inferInstance, inferInstance⟩, fun ⟨⟨_⟩, ⟨_⟩⟩ ↦ by classical exact + ⟨strongNormalizedGCDMonoidOfExistsGCD fun _ _ ↦ ⟨_, fun _ ↦ (dvd_gcd_iff ..).symm⟩⟩⟩ + /-- Define a `GCDMonoid` structure on a monoid just from the existence of an `lcm`. -/ @[implicit_reducible] noncomputable def gcdMonoidOfExistsLCM [DecidableEq α] @@ -1275,6 +1331,23 @@ noncomputable def normalizedGCDMonoidOfExistsLCM [NormalizationMonoid α] [Decid (fun {a b c} ac ab => normalize_dvd_iff.2 ((Classical.choose_spec (h c b) a).1 ⟨ac, ab⟩)) fun _ _ => normalize_idem _ +/-- Define a `StrongNormalizedGCDMonoid` structure on a monoid just from +the existence of a `lcm`. -/ +abbrev strongNormalizedGCDMonoidOfExistsLCM [StrongNormalizationMonoid α] [DecidableEq α] + (h : ∀ a b : α, ∃ c : α, ∀ d : α, a ∣ d ∧ b ∣ d ↔ c ∣ d) : StrongNormalizedGCDMonoid α where + __ := normalizedGCDMonoidOfExistsLCM h + __ := ‹StrongNormalizationMonoid α› + +theorem isGCDMonoid_iff_exists_gcd {α} [CommMonoidWithZero α] : + IsGCDMonoid α ↔ IsCancelMulZero α ∧ ∀ a b : α, ∃ c : α, ∀ d : α, d ∣ a ∧ d ∣ b ↔ d ∣ c where + mp := fun ⟨_⟩ ↦ ⟨inferInstance, fun _ _ ↦ ⟨_, fun _ ↦ (dvd_gcd_iff ..).symm⟩⟩ + mpr := fun ⟨_, h⟩ ↦ by classical exact ⟨gcdMonoidOfExistsGCD h⟩ + +theorem isGCDMonoid_iff_exists_lcm {α} [CommMonoidWithZero α] : + IsGCDMonoid α ↔ IsCancelMulZero α ∧ ∀ a b : α, ∃ c : α, ∀ d : α, a ∣ d ∧ b ∣ d ↔ c ∣ d where + mp := fun ⟨_⟩ ↦ ⟨inferInstance, fun _ _ ↦ ⟨_, fun _ ↦ (lcm_dvd_iff ..).symm⟩⟩ + mpr := fun ⟨_, h⟩ ↦ by classical exact ⟨gcdMonoidOfExistsLCM h⟩ + end Constructors namespace CommGroupWithZero @@ -1282,7 +1355,7 @@ namespace CommGroupWithZero variable (G₀ : Type*) [CommGroupWithZero G₀] [DecidableEq G₀] -- see Note [lower instance priority] -instance (priority := 100) : NormalizedGCDMonoid G₀ where +instance (priority := 100) : StrongNormalizedGCDMonoid G₀ where normUnit x := if h : x = 0 then 1 else (Units.mk0 x h)⁻¹ normUnit_zero := dif_pos rfl normUnit_mul {x y} x0 y0 := Units.ext <| by simp [x0, y0, mul_comm] @@ -1301,7 +1374,8 @@ instance (priority := 100) : NormalizedGCDMonoid G₀ where normalize_lcm a b := if h : a = 0 ∨ b = 0 then by simp [if_pos h] else by simp [if_neg h] @[simp] -theorem coe_normUnit {a : G₀} (h0 : a ≠ 0) : (↑(normUnit a) : G₀) = a⁻¹ := by simp [normUnit, h0] +theorem coe_normUnit {a : G₀} (h0 : a ≠ 0) : (↑(normUnit a) : G₀) = a⁻¹ := by + simp [normUnit, h0] theorem normalize_eq_one {a : G₀} (h0 : a ≠ 0) : normalize a = 1 := by simp [normalize_apply, h0] diff --git a/Mathlib/Algebra/GCDMonoid/Finset.lean b/Mathlib/Algebra/GCDMonoid/Finset.lean index 077df9a89421a3..2307eea5f10e07 100644 --- a/Mathlib/Algebra/GCDMonoid/Finset.lean +++ b/Mathlib/Algebra/GCDMonoid/Finset.lean @@ -208,7 +208,9 @@ theorem gcd_eq_gcd_filter_ne_zero [DecidablePred fun x : β ↦ f x = 0] : split_ifs with h1 <;> simp [h, h1] simp only [gcd_zero_left, normalize_gcd] -nonrec theorem gcd_mul_left {a : α} : (s.gcd fun x ↦ a * f x) = normalize a * s.gcd f := by +nonrec theorem gcd_mul_left {α} [CommMonoidWithZero α] [StrongNormalizedGCDMonoid α] + {s : Finset β} {f : β → α} {a : α} : + (s.gcd fun x ↦ a * f x) = normalize a * s.gcd f := by classical refine s.induction_on ?_ ?_ · simp @@ -216,20 +218,27 @@ nonrec theorem gcd_mul_left {a : α} : (s.gcd fun x ↦ a * f x) = normalize a * rw [gcd_insert, gcd_insert, h, ← gcd_mul_left] apply ((normalize_associated a).mul_right _).gcd_eq_right -nonrec theorem gcd_mul_right {a : α} : (s.gcd fun x ↦ f x * a) = s.gcd f * normalize a := by - classical - refine s.induction_on ?_ ?_ - · simp - · intro b t _ h - rw [gcd_insert, gcd_insert, h, ← gcd_mul_right] - apply ((normalize_associated a).mul_left _).gcd_eq_right +nonrec theorem gcd_mul_right {α} [CommMonoidWithZero α] [StrongNormalizedGCDMonoid α] + {s : Finset β} {f : β → α} {a : α} : + (s.gcd fun x ↦ f x * a) = s.gcd f * normalize a := by + simp_rw [mul_comm]; exact gcd_mul_left + +variable (s f) in +nonrec theorem gcd_mul_left' (a : α) : Associated (s.gcd fun x ↦ a * f x) (a * s.gcd f) := by + classical exact s.induction_on (by simp) fun b s hbs h ↦ by + simpa using .trans (.gcd .rfl h) (gcd_mul_left' ..) + +variable (s f) in +nonrec theorem gcd_mul_right' (a : α) : Associated (s.gcd fun x ↦ f x * a) (s.gcd f * a) := by + simp_rw [mul_comm]; apply gcd_mul_left' theorem extract_gcd' (f g : β → α) (hs : ∃ x, x ∈ s ∧ f x ≠ 0) - (hg : ∀ b ∈ s, f b = s.gcd f * g b) : s.gcd g = 1 := - ((mul_right_eq_self₀ (a := s.gcd f)).1 <| by - conv_lhs => rw [← normalize_gcd, ← gcd_mul_left, ← gcd_congr rfl hg]).resolve_right <| by - contrapose! hs - exact gcd_eq_zero_iff.1 hs + (hg : ∀ b ∈ s, f b = s.gcd f * g b) : s.gcd g = 1 := by + rw [← normalize_gcd, normalize_eq_one, ← associated_one_iff_isUnit] + refine .of_mul_left (.symm <| .trans ?_ (gcd_mul_left' ..)) .rfl (a := s.gcd f) ?_ + · simp [← gcd_congr rfl hg] + contrapose! hs + exact s.gcd_eq_zero_iff.1 hs theorem extract_gcd (f : β → α) (hs : s.Nonempty) : ∃ g : β → α, (∀ b ∈ s, f b = s.gcd f * g b) ∧ s.gcd g = 1 := by diff --git a/Mathlib/Algebra/GCDMonoid/IntegrallyClosed.lean b/Mathlib/Algebra/GCDMonoid/IntegrallyClosed.lean index ecd0c87bd2578b..d22d057cea4e58 100644 --- a/Mathlib/Algebra/GCDMonoid/IntegrallyClosed.lean +++ b/Mathlib/Algebra/GCDMonoid/IntegrallyClosed.lean @@ -32,7 +32,7 @@ theorem IsLocalization.surj_of_gcd_domain [GCDMonoid R] (M : Submonoid R) [IsLoc grind instance (priority := 100) GCDMonoid.toIsIntegrallyClosed - [h : Nonempty (GCDMonoid R)] : IsIntegrallyClosed R := + [h : IsGCDMonoid R] : IsIntegrallyClosed R := (isIntegrallyClosed_iff (FractionRing R)).mpr fun {X} ⟨p, hp₁, hp₂⟩ => by cases h obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X diff --git a/Mathlib/Algebra/GCDMonoid/Multiset.lean b/Mathlib/Algebra/GCDMonoid/Multiset.lean index 26a7a18d6643d0..621d46f837be2c 100644 --- a/Mathlib/Algebra/GCDMonoid/Multiset.lean +++ b/Mathlib/Algebra/GCDMonoid/Multiset.lean @@ -162,13 +162,21 @@ theorem gcd_eq_zero_iff (s : Multiset α) : s.gcd = 0 ↔ ∀ x ∈ s, x = 0 := theorem gcd_ne_zero_iff (s : Multiset α) : s.gcd ≠ 0 ↔ ∃ x ∈ s, x ≠ 0 := by simp [gcd_eq_zero_iff] -theorem gcd_map_mul (a : α) (s : Multiset α) : (s.map (a * ·)).gcd = normalize a * s.gcd := by +theorem gcd_map_mul {α} [CommMonoidWithZero α] [StrongNormalizedGCDMonoid α] + (a : α) (s : Multiset α) : (s.map (a * ·)).gcd = normalize a * s.gcd := by refine s.induction_on ?_ fun b s ih ↦ ?_ · simp_rw [map_zero, gcd_zero, mul_zero] · simp_rw [map_cons, gcd_cons, ← gcd_mul_left] rw [ih] apply ((normalize_associated a).mul_right _).gcd_eq_right +theorem associated_gcd_map_mul (a : α) (s : Multiset α) : + Associated (s.map (a * ·)).gcd (a * s.gcd) := by + refine s.induction_on ?_ fun b s ih ↦ ?_ + · simp_rw [map_zero, gcd_zero, mul_zero, Associated.of_eq] + · simp_rw [map_cons, gcd_cons] + exact .trans (.gcd .rfl ih) (gcd_mul_left' ..) + section variable [DecidableEq α] @@ -200,11 +208,12 @@ theorem gcd_ndinsert (a : α) (s : Multiset α) : (ndinsert a s).gcd = GCDMonoid end theorem extract_gcd' (s t : Multiset α) (hs : ∃ x, x ∈ s ∧ x ≠ (0 : α)) - (ht : s = t.map (s.gcd * ·)) : t.gcd = 1 := - ((mul_right_eq_self₀ (a := s.gcd)).1 <| by - conv_lhs => rw [← normalize_gcd, ← gcd_map_mul, ← ht]).resolve_right <| by - contrapose! hs - exact s.gcd_eq_zero_iff.1 hs + (ht : s = t.map (s.gcd * ·)) : t.gcd = 1 := by + rw [← normalize_gcd, normalize_eq_one, ← associated_one_iff_isUnit] + refine .of_mul_left (.symm ?_) .rfl (a := s.gcd) ?_ + · simpa using (Associated.of_eq <| congr(gcd $ht)).trans (associated_gcd_map_mul ..) + contrapose! hs + exact s.gcd_eq_zero_iff.1 hs theorem extract_gcd (s : Multiset α) (hs : s ≠ 0) : ∃ t : Multiset α, s = t.map (s.gcd * ·) ∧ t.gcd = 1 := by diff --git a/Mathlib/Algebra/GCDMonoid/Nat.lean b/Mathlib/Algebra/GCDMonoid/Nat.lean index 04a18661b75b49..5ab65cf0b87e5f 100644 --- a/Mathlib/Algebra/GCDMonoid/Nat.lean +++ b/Mathlib/Algebra/GCDMonoid/Nat.lean @@ -16,10 +16,10 @@ public import Mathlib.Algebra.GroupWithZero.Nat ## Main statements * ℕ is a `GCDMonoid` -* ℕ is a `NormalizedGCDMonoid` -* ℤ is a `NormalizationMonoid` +* ℕ is a `StrongNormalizedGCDMonoid` +* ℤ is a `StrongNormalizationMonoid` * ℤ is a `GCDMonoid` -* ℤ is a `NormalizedGCDMonoid` +* ℤ is a `StrongNormalizedGCDMonoid` ## Tags natural numbers, integers, normalization monoid, gcd monoid, greatest common divisor @@ -46,9 +46,9 @@ theorem gcd_eq_nat_gcd (m n : ℕ) : gcd m n = Nat.gcd m n := theorem lcm_eq_nat_lcm (m n : ℕ) : lcm m n = Nat.lcm m n := rfl -instance : NormalizedGCDMonoid ℕ := +instance : StrongNormalizedGCDMonoid ℕ := { (inferInstance : GCDMonoid ℕ), - (inferInstance : NormalizationMonoid ℕ) with + (inferInstance : StrongNormalizationMonoid ℕ) with normalize_gcd := fun _ _ => normalize_eq _ normalize_lcm := fun _ _ => normalize_eq _ } @@ -56,7 +56,7 @@ namespace Int section NormalizationMonoid -instance normalizationMonoid : NormalizationMonoid ℤ where +instance strongNormalizationMonoid : StrongNormalizationMonoid ℤ where normUnit a := if 0 ≤ a then 1 else -1 normUnit_zero := if_pos le_rfl normUnit_mul {a b} hna hnb := by @@ -66,6 +66,9 @@ instance normalizationMonoid : NormalizationMonoid ℤ where (units_eq_one_or u).elim (fun eq => eq.symm ▸ if_pos Int.one_nonneg) fun eq => eq.symm ▸ if_neg (not_le_of_gt <| show (-1 : ℤ) < 0 by decide) +@[deprecated (since := "2026-07-08")] +alias normalizationMonoid := strongNormalizationMonoid + theorem normUnit_eq (z : ℤ) : normUnit z = if 0 ≤ z then 1 else -1 := rfl theorem normalize_of_nonneg {z : ℤ} (h : 0 ≤ z) : normalize z = z := by @@ -113,8 +116,8 @@ instance : GCDMonoid ℤ where lcm_zero_left _ := natCast_eq_zero.2 <| Nat.lcm_zero_left _ lcm_zero_right _ := natCast_eq_zero.2 <| Nat.lcm_zero_right _ -instance : NormalizedGCDMonoid ℤ := - { Int.normalizationMonoid, +instance : StrongNormalizedGCDMonoid ℤ := + { Int.strongNormalizationMonoid, (inferInstance : GCDMonoid ℤ) with normalize_gcd := fun _ _ => normalize_coe_nat _ normalize_lcm := fun _ _ => normalize_coe_nat _ } diff --git a/Mathlib/Algebra/GCDMonoid/PUnit.lean b/Mathlib/Algebra/GCDMonoid/PUnit.lean index 62a0b717685523..c8990dd76189f9 100644 --- a/Mathlib/Algebra/GCDMonoid/PUnit.lean +++ b/Mathlib/Algebra/GCDMonoid/PUnit.lean @@ -20,7 +20,7 @@ public section namespace PUnit -- This is too high-powered and should be split off also -instance normalizedGCDMonoid : NormalizedGCDMonoid PUnit where +instance : StrongNormalizedGCDMonoid PUnit where gcd _ _ := unit lcm _ _ := unit normUnit _ := 1 @@ -36,6 +36,8 @@ instance normalizedGCDMonoid : NormalizedGCDMonoid PUnit where normalize_gcd := by subsingleton normalize_lcm := by subsingleton +instance normalizedGCDMonoid : NormalizedGCDMonoid PUnit := inferInstance + @[simp] theorem gcd_eq {x y : PUnit} : gcd x y = unit := rfl diff --git a/Mathlib/Algebra/GroupWithZero/Associated.lean b/Mathlib/Algebra/GroupWithZero/Associated.lean index ed2f121e36380d..b37d8f469c09af 100644 --- a/Mathlib/Algebra/GroupWithZero/Associated.lean +++ b/Mathlib/Algebra/GroupWithZero/Associated.lean @@ -82,6 +82,9 @@ attribute [local instance] Associated.setoid theorem Associated.of_eq [Monoid M] {a b : M} (h : a = b) : a ~ᵤ b := ⟨1, by rwa [Units.val_one, mul_one]⟩ +@[nontriviality] theorem Associated.of_subsingleton [Subsingleton M] [Monoid M] (a b : M) : + Associated a b := .of_eq (Subsingleton.elim ..) + theorem unit_associated_one [Monoid M] {u : Mˣ} : (u : M) ~ᵤ 1 := ⟨u⁻¹, Units.mul_inv u⟩ @@ -162,15 +165,19 @@ theorem associated_unit_mul_right_iff {N : Type*} [CommMonoid N] {a b : N} {u : Associated a (↑u * b) ↔ Associated a b := associated_isUnit_mul_right_iff u.isUnit +@[gcongr] theorem Associated.mul_left [Monoid M] (a : M) {b c : M} (h : b ~ᵤ c) : a * b ~ᵤ a * c := by obtain ⟨d, rfl⟩ := h; exact ⟨d, mul_assoc _ _ _⟩ +@[gcongr] theorem Associated.mul_right [CommMonoid M] {a b : M} (h : a ~ᵤ b) (c : M) : a * c ~ᵤ b * c := by obtain ⟨d, rfl⟩ := h; exact ⟨d, mul_right_comm _ _ _⟩ +@[gcongr] theorem Associated.mul_mul [CommMonoid M] {a₁ a₂ b₁ b₂ : M} (h₁ : a₁ ~ᵤ b₁) (h₂ : a₂ ~ᵤ b₂) : a₁ * a₂ ~ᵤ b₁ * b₂ := (h₁.mul_right _).trans (h₂.mul_left _) +@[gcongr] theorem Associated.pow_pow [CommMonoid M] {a b : M} {n : ℕ} (h : a ~ᵤ b) : a ^ n ~ᵤ b ^ n := by induction n with | zero => simp [Associated.refl] diff --git a/Mathlib/Algebra/Polynomial/FieldDivision.lean b/Mathlib/Algebra/Polynomial/FieldDivision.lean index 2f27e0a29d944a..94f81cb00c56c3 100644 --- a/Mathlib/Algebra/Polynomial/FieldDivision.lean +++ b/Mathlib/Algebra/Polynomial/FieldDivision.lean @@ -197,29 +197,32 @@ theorem isRoot_of_isRoot_of_dvd_derivative_mul [CharZero R] {f g : R[X]} (hf0 : Nat.sub_eq_iff_eq_add (Nat.succ_le_iff.2 ((rootMultiplicity_pos hf0).2 haf))] at hr' lia -section NormalizationMonoid - -variable [NormalizationMonoid R] -instance instNormalizationMonoid : NormalizationMonoid R[X] where +instance instNormalizationMonoid [NormalizationMonoid R] : NormalizationMonoid R[X] where normUnit p := ⟨C ↑(normUnit p.leadingCoeff), C ↑(normUnit p.leadingCoeff)⁻¹, by rw [← map_mul, Units.mul_inv, C_1], by rw [← map_mul, Units.inv_mul, C_1]⟩ normUnit_zero := Units.ext (by simp) + normUnit_one := Units.ext (by simp) + normUnit_mul_units u h := Units.ext <| by + dsimp only [Units.val_mul] + obtain ⟨_, ⟨w, rfl⟩, h2⟩ := isUnit_iff.1 ⟨u, rfl⟩ + rw [leadingCoeff_mul, ← h2, leadingCoeff_C, normUnit_mul_units _ (leadingCoeff_ne_zero.2 h), + Units.eq_inv_mul_iff_mul_eq, Units.val_mul, C_mul, ← mul_assoc, ← h2, ← C_mul] + simp + +instance [StrongNormalizationMonoid R] : StrongNormalizationMonoid R[X] where normUnit_mul hp0 hq0 := Units.ext (by dsimp rw [Ne, ← leadingCoeff_eq_zero] at * - rw [leadingCoeff_mul, normUnit_mul hp0 hq0, Units.val_mul, C_mul]) - normUnit_coe_units u := - Units.ext - (by - dsimp - rw [← mul_one u⁻¹, Units.val_mul, Units.eq_inv_mul_iff_mul_eq] - rcases Polynomial.isUnit_iff.1 ⟨u, rfl⟩ with ⟨_, ⟨w, rfl⟩, h2⟩ - rw [← h2, leadingCoeff_C, normUnit_coe_units, ← C_mul, Units.mul_inv, C_1] - rfl) + simp_rw [normUnit, leadingCoeff_mul, normUnit_mul hp0 hq0, Units.val_mul, C_mul]) + normUnit_coe_units := normUnit_coe_units + +section NormalizationMonoid + +variable [NormalizationMonoid R] @[simp] theorem coe_normUnit {p : R[X]} : (normUnit p : R[X]) = C ↑(normUnit p.leadingCoeff) := by @@ -237,11 +240,11 @@ theorem roots_normalize {R} [CommRing R] [IsDomain R] [NormalizationMonoid R] {p (normalize p).roots = p.roots := by rw [normalize_apply, mul_comm, coe_normUnit, roots_C_mul _ (normUnit (leadingCoeff p)).ne_zero] -theorem normUnit_X : normUnit (X : Polynomial R) = 1 := by +theorem normUnit_X : normUnit (X : R[X]) = 1 := by have := coe_normUnit (R := R) (p := X) rwa [leadingCoeff_X, normUnit_one, Units.val_one, map_one, Units.val_eq_one] at this -theorem X_eq_normalize : (X : Polynomial R) = normalize X := by +theorem X_eq_normalize : X = normalize (X : R[X]) := by simp only [normalize_apply, normUnit_X, Units.val_one, mul_one] end NormalizationMonoid @@ -548,7 +551,7 @@ theorem monic_normalize [DecidableEq R] (hp0 : p ≠ 0) : Monic (normalize p) := rw [Monic, leadingCoeff_normalize, normalize_eq_one] apply hp0 -theorem normalize_eq_self_iff_monic [DecidableEq R] {p : Polynomial R} (hp : p ≠ 0) : +theorem normalize_eq_self_iff_monic [DecidableEq R] {p : R[X]} (hp : p ≠ 0) : normalize p = p ↔ p.Monic := ⟨fun h ↦ h ▸ monic_normalize hp, fun h ↦ Monic.normalize_eq_self h⟩ diff --git a/Mathlib/NumberTheory/FLT/Basic.lean b/Mathlib/NumberTheory/FLT/Basic.lean index 5202059f5afca0..c21f4b48f7231a 100644 --- a/Mathlib/NumberTheory/FLT/Basic.lean +++ b/Mathlib/NumberTheory/FLT/Basic.lean @@ -229,10 +229,9 @@ lemma fermatLastTheoremWith_of_fermatLastTheoremWith_coprime {n : ℕ} {R : Type rw [← mul_add, mul_right_inj' (pow_ne_zero n ha.1)] at habc refine hn A B C ha.2 hb.2 hc.2 ?_ habc rw [← Finset.normalize_gcd, normalize_eq_one] - obtain ⟨u, hu⟩ := normalize_associated d - refine ⟨u, mul_left_cancel₀ (mt normalize_eq_zero.mp ha.1) (hu.symm ▸ ?_)⟩ - rw [← Finset.gcd_mul_left, gcd_eq_gcd_image, image_insert, image_insert, image_singleton, - id_eq, id_eq, id_eq, ← hA, ← hB, ← hC] + refine isUnit_of_associated_mul ?_ ha.1 + grw [← Finset.gcd_mul_left', gcd_eq_gcd_image] + refine .of_eq ?_; congr; simp [s, hA, hB, hC] lemma dvd_c_of_prime_of_dvd_a_of_dvd_b_of_FLT {n : ℕ} {p : ℤ} (hp : Prime p) {a b c : ℤ} (hpa : p ∣ a) (hpb : p ∣ b) (HF : a ^ n + b ^ n + c ^ n = 0) : p ∣ c := by @@ -251,7 +250,7 @@ lemma isCoprime_of_gcd_eq_one_of_FLT {n : ℕ} {a b c : ℤ} (Hgcd : Finset.gcd simp only [ne_eq, hn, not_false_eq_true, zero_pow, add_zero, zero_add, pow_eq_zero_iff] at HF simp only [HF, Finset.mem_singleton, Finset.insert_eq_of_mem, Finset.gcd_singleton, id_eq, - map_zero, zero_ne_one] at Hgcd + normalize_zero, zero_ne_one] at Hgcd · rw [← Hgcd] refine Finset.dvd_gcd_iff.mpr fun x hx ↦ ?_ simp only [Finset.mem_insert, Finset.mem_singleton] at hx diff --git a/Mathlib/RingTheory/ChainOfDivisors.lean b/Mathlib/RingTheory/ChainOfDivisors.lean index 9a0b005f8e0073..e9e83174dbeb93 100644 --- a/Mathlib/RingTheory/ChainOfDivisors.lean +++ b/Mathlib/RingTheory/ChainOfDivisors.lean @@ -345,7 +345,7 @@ variable [Subsingleton Mˣ] [Subsingleton Nˣ] /-- The order isomorphism between the factors of `mk m` and the factors of `mk n` induced by a bijection between the factors of `m` and the factors of `n` that preserves `∣`. -/ @[simps] -def mkFactorOrderIsoOfFactorDvdEquiv [IsCancelMulZero N] +def mkFactorOrderIsoOfFactorDvdEquiv {m : M} {n : N} {d : { l : M // l ∣ m } ≃ { l : N // l ∣ n }} (hd : ∀ l l', (d l : N) ∣ d l' ↔ (l : M) ∣ (l' : M)) : Set.Iic (Associates.mk m) ≃o Set.Iic (Associates.mk n) where diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean index 497e84753a0c09..e328c4ba9d3ad6 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean @@ -445,6 +445,10 @@ instance Ideal.uniqueFactorizationMonoid : UniqueFactorizationMonoid (Ideal A) : ⟨x * y, Ideal.mul_mem_mul x_mem y_mem, mt this.isPrime.mem_or_mem (not_or_intro x_notMem y_notMem)⟩⟩, Prime.irreducible⟩ } -noncomputable instance Ideal.normalizationMonoid : NormalizationMonoid (Ideal A) := .ofUniqueUnits +noncomputable instance Ideal.strongNormalizationMonoid : StrongNormalizationMonoid (Ideal A) := + inferInstance + +@[deprecated (since := "2026-07-08")] +alias Ideal.normalizationMonoid := Ideal.strongNormalizationMonoid end IsDedekindDomain diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index e5054d4f776d69..7a1360a71b601b 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -323,8 +323,8 @@ theorem sup_mul_inf (I J : Ideal A) : (I ⊔ J) * (I ⊓ J) = I * J := by /-- Ideals in a Dedekind domain have gcd and lcm operators that (trivially) are compatible with the normalization operator. -/ -noncomputable instance : NormalizedGCDMonoid (Ideal A) := - { normalizationMonoid with +noncomputable instance : StrongNormalizedGCDMonoid (Ideal A) := + { strongNormalizationMonoid with gcd := (· ⊔ ·) gcd_dvd_left := fun _ _ => by simpa only [dvd_iff_le] using le_sup_left gcd_dvd_right := fun _ _ => by simpa only [dvd_iff_le] using le_sup_right diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index fa191bb3509d09..680783fa988a5f 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -854,7 +854,7 @@ the group of the invertible `R`-submodules in `A` modulo the principal submodule /-- The Picard group of a domain with normalizable gcd is trivial. This includes unique factorization domains. -/ @[stacks 0BCH] -instance (R) [CommRing R] [IsDomain R] [Nonempty (NormalizedGCDMonoid R)] : Subsingleton (Pic R) := +instance (R) [CommRing R] [IsDomain R] [IsGCDMonoid R] : Subsingleton (Pic R) := Equiv.subsingleton (ClassGroup.equivPic R).toEquiv.symm end PicardGroup diff --git a/Mathlib/RingTheory/Polynomial/Content.lean b/Mathlib/RingTheory/Polynomial/Content.lean index d2bc3c3cc753fa..2c8933de7c5e76 100644 --- a/Mathlib/RingTheory/Polynomial/Content.lean +++ b/Mathlib/RingTheory/Polynomial/Content.lean @@ -138,14 +138,27 @@ theorem content_X_pow {k : ℕ} : content ((X : R[X]) ^ k) = 1 := by @[simp] theorem content_X : content (X : R[X]) = 1 := by rw [← mul_one X, content_X_mul, content_one] -theorem content_C_mul (r : R) (p : R[X]) : (C r * p).content = normalize r * p.content := by +theorem content_C_mul {R} [CommRing R] [StrongNormalizedGCDMonoid R] (r : R) (p : R[X]) : + (C r * p).content = normalize r * p.content := by by_cases h0 : r = 0; · simp [h0] - rw [content]; rw [content]; rw [← Finset.gcd_mul_left] + rw [content, content, ← Finset.gcd_mul_left] refine congr (congr rfl ?_) ?_ <;> ext <;> simp [h0, mem_support_iff] +theorem associated_content_C_mul (r : R) (p : R[X]) : + Associated (C r * p).content (r * p.content) := by + by_cases h0 : r = 0; · simp [h0] + refine .trans (.of_eq ?_) (Finset.gcd_mul_left' _ _ _) + rw [content]; refine congr (congr rfl ?_) ?_ <;> ext <;> simp [h0, mem_support_iff] + +-- `simp`-normal form is `normUnit_content` +theorem normalize_content {p : R[X]} : normalize p.content = p.content := + Finset.normalize_gcd + @[simp] theorem content_monomial {r : R} {k : ℕ} : content (monomial k r) = normalize r := by - rw [← C_mul_X_pow_eq_monomial, content_C_mul, content_X_pow, mul_one] + rw [← C_mul_X_pow_eq_monomial, ← normalize_content, normalize_eq_normalize_iff_associated] + grw [associated_content_C_mul, content_X_pow, mul_one] + exact Associated.rfl theorem content_eq_zero_iff {p : R[X]} : content p = 0 ↔ p = 0 := by rw [content, Finset.gcd_eq_zero_iff] @@ -155,10 +168,6 @@ theorem content_eq_zero_iff {p : R[X]} : content p = 0 ↔ p = 0 := by · intro x simp [h] --- `simp`-normal form is `normUnit_content` -theorem normalize_content {p : R[X]} : normalize p.content = p.content := - Finset.normalize_gcd - @[simp] theorem normUnit_content {p : R[X]} : normUnit (content p) = 1 := by by_cases hp0 : p.content = 0 @@ -180,7 +189,7 @@ theorem content_eq_gcd_range_succ (p : R[X]) : content_eq_gcd_range_of_lt _ _ (Nat.lt_succ_self _) theorem content_eq_gcd_leadingCoeff_content_eraseLead (p : R[X]) : - p.content = GCDMonoid.gcd p.leadingCoeff (eraseLead p).content := by + p.content = gcd p.leadingCoeff (eraseLead p).content := by by_cases h : p = 0 · simp [h] rw [← leadingCoeff_eq_zero, leadingCoeff, ← Ne, ← mem_support_iff] at h @@ -230,9 +239,10 @@ theorem primPart_zero : primPart (0 : R[X]) = 1 := theorem isPrimitive_primPart (p : R[X]) : p.primPart.IsPrimitive := by by_cases h : p = 0; · simp [h] rw [← content_eq_zero_iff] at h - rw [isPrimitive_iff_content_eq_one] - apply mul_left_cancel₀ h - conv_rhs => rw [p.eq_C_content_mul_primPart, mul_one, content_C_mul, normalize_content] + rw [isPrimitive_iff_content_eq_one, ← normalize_content, normalize_eq_one] + refine isUnit_of_associated_mul (.symm ?_) h + conv_lhs => rw [p.eq_C_content_mul_primPart] + apply associated_content_C_mul theorem content_primPart (p : R[X]) : p.primPart.content = 1 := p.isPrimitive_primPart.content_eq_one @@ -288,7 +298,7 @@ theorem eval₂_primPart_eq_zero {S : Type*} [CommSemiring S] [IsDomain S] {f : end PrimPart theorem gcd_content_eq_of_dvd_sub {a : R} {p q : R[X]} (h : C a ∣ p - q) : - GCDMonoid.gcd a p.content = GCDMonoid.gcd a q.content := by + gcd a p.content = gcd a q.content := by rw [content_eq_gcd_range_of_lt p (max p.natDegree q.natDegree).succ (lt_of_le_of_lt (le_max_left _ _) (Nat.lt_succ_self _))] rw [content_eq_gcd_range_of_lt q (max p.natDegree q.natDegree).succ @@ -300,20 +310,20 @@ theorem gcd_content_eq_of_dvd_sub {a : R} {p q : R[X]} (h : C a ∣ p - q) : rw [← coeff_sub, hw, coeff_C_mul] theorem content_mul_aux {p q : R[X]} : - GCDMonoid.gcd (p * q).eraseLead.content p.leadingCoeff = - GCDMonoid.gcd (p.eraseLead * q).content p.leadingCoeff := by + gcd (p * q).eraseLead.content p.leadingCoeff = + gcd (p.eraseLead * q).content p.leadingCoeff := by rw [gcd_comm (content _) _, gcd_comm (content _) _] apply gcd_content_eq_of_dvd_sub rw [← self_sub_C_mul_X_pow, ← self_sub_C_mul_X_pow, sub_mul, sub_sub, add_comm, sub_add, sub_sub_cancel, leadingCoeff_mul, map_mul, mul_assoc, mul_assoc] apply dvd_sub (Dvd.intro _ rfl) (Dvd.intro _ rfl) -@[simp] -theorem content_mul {p q : R[X]} : (p * q).content = p.content * q.content := by +theorem associated_content_mul (p q : R[X]) : + Associated ((p * q).content) (p.content * q.content) := by nontriviality R classical - suffices h : - ∀ (n : ℕ) (p q : R[X]), (p * q).degree < n → (p * q).content = p.content * q.content by + suffices h : ∀ (n : ℕ) (p q : R[X]), + (p * q).degree < n → Associated ((p * q).content) (p.content * q.content) by apply h apply lt_of_le_of_lt degree_le_natDegree (WithBot.coe_lt_coe.2 (Nat.lt_succ_self _)) intro n p q hpq @@ -336,15 +346,16 @@ theorem content_mul {p q : R[X]} : (p * q).content = p.content * q.content := by ← degree_eq_natDegree q.primPart_ne_zero] at heq rw [p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart] suffices h : (q.primPart * p.primPart).content = 1 by - rw [mul_assoc, content_C_mul, content_C_mul, mul_comm p.primPart, mul_assoc, content_C_mul, - content_C_mul, h, mul_one, content_primPart, content_primPart, mul_one, mul_one] + grw [mul_assoc, associated_content_C_mul, associated_content_C_mul, mul_comm p.primPart, + mul_assoc, associated_content_C_mul, associated_content_C_mul, h, mul_one, + content_primPart, content_primPart, mul_one, mul_one] rw [← normalize_content, normalize_eq_one, isUnit_iff_dvd_one, content_eq_gcd_leadingCoeff_content_eraseLead, leadingCoeff_mul, gcd_comm] apply (gcd_mul_dvd_mul_gcd _ _ _).trans - rw [content_mul_aux, ih, content_primPart, mul_one, gcd_comm, ← + rw [content_mul_aux, (ih ..).gcd_eq_left, content_primPart, mul_one, gcd_comm, ← content_eq_gcd_leadingCoeff_content_eraseLead, content_primPart, one_mul, - mul_comm q.primPart, content_mul_aux, ih, content_primPart, mul_one, gcd_comm, ← - content_eq_gcd_leadingCoeff_content_eraseLead, content_primPart] + mul_comm q.primPart, content_mul_aux, (ih ..).gcd_eq_left, content_primPart, mul_one, + gcd_comm, ← content_eq_gcd_leadingCoeff_content_eraseLead, content_primPart] · rw [← heq, degree_mul, WithBot.add_lt_add_iff_right] · apply degree_erase_lt p.primPart_ne_zero · rw [Ne, degree_eq_bot] @@ -354,12 +365,28 @@ theorem content_mul {p q : R[X]} : (p * q).content = p.content * q.content := by · rw [Ne, degree_eq_bot] apply p.primPart_ne_zero +@[simp] +theorem content_mul {R} [CommRing R] [StrongNormalizedGCDMonoid R] {p q : R[X]} : + (p * q).content = p.content * q.content := + (associated_content_mul ..).eq_of_normalized normalize_content <| by simp [normalize_content] + theorem IsPrimitive.mul {p q : R[X]} (hp : p.IsPrimitive) (hq : q.IsPrimitive) : (p * q).IsPrimitive := by - rw [isPrimitive_iff_content_eq_one, content_mul, hp.content_eq_one, hq.content_eq_one, mul_one] + rw [isPrimitive_iff_content_eq_one, ← normalize_content, normalize_eq_one] + refine (associated_content_mul p q).symm.isUnit ?_ + simp_rw [hp.content_eq_one, hq.content_eq_one, mul_one, isUnit_one] + +theorem associated_primPart_mul {p q : R[X]} (h0 : p * q ≠ 0) : + Associated (p * q).primPart (p.primPart * q.primPart) := by + rw [Ne, ← content_eq_zero_iff, ← C_eq_zero] at h0 + refine .of_mul_left ?_ .rfl h0 + conv_lhs => rw [← (p * q).eq_C_content_mul_primPart, + p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart, mul_mul_mul_comm, ← C_mul] + gcongr + exact (associated_content_mul ..).symm.map _ @[simp] -theorem primPart_mul {p q : R[X]} (h0 : p * q ≠ 0) : +theorem primPart_mul {R} [CommRing R] [StrongNormalizedGCDMonoid R] {p q : R[X]} (h0 : p * q ≠ 0) : (p * q).primPart = p.primPart * q.primPart := by rw [Ne, ← content_eq_zero_iff, ← C_eq_zero] at h0 apply mul_left_cancel₀ h0 @@ -373,8 +400,7 @@ theorem IsPrimitive.dvd_primPart_iff_dvd {p q : R[X]} (hp : p.IsPrimitive) (hq : p ∣ q.primPart ↔ p ∣ q := by refine ⟨fun h => h.trans (Dvd.intro_left _ q.eq_C_content_mul_primPart.symm), fun h => ?_⟩ rcases h with ⟨r, rfl⟩ - apply Dvd.intro _ - rw [primPart_mul hq, hp.primPart_eq] + exact .trans (by simp [hp.primPart_eq]) (associated_primPart_mul hq).symm.dvd theorem exists_primitive_lcm_of_isPrimitive {p q : R[X]} (hp : p.IsPrimitive) (hq : q.IsPrimitive) : ∃ r : R[X], r.IsPrimitive ∧ ∀ s : R[X], p ∣ s ∧ q ∣ s ↔ r ∣ s := by @@ -415,21 +441,22 @@ theorem exists_primitive_lcm_of_isPrimitive {p q : R[X]} (hp : p.IsPrimitive) (h have hC0 := rprim.ne_zero rw [Ne, ← leadingCoeff_eq_zero, ← C_eq_zero] at hC0 rw [sub_add_cancel, ← rprim.dvd_primPart_iff_dvd (mul_ne_zero hC0 s0)] at h - rcases isUnit_primPart_C r.leadingCoeff with ⟨u, hu⟩ - apply h.trans (Associated.symm ⟨u, _⟩).dvd - rw [primPart_mul (mul_ne_zero hC0 s0), hu, mul_comm] + refine h.trans (Associated.dvd ?_) + grw [associated_primPart_mul (mul_ne_zero hC0 s0)] + exact associated_unit_mul_left _ _ (isUnit_primPart_C _) theorem dvd_iff_content_dvd_content_and_primPart_dvd_primPart {p q : R[X]} (hq : q ≠ 0) : p ∣ q ↔ p.content ∣ q.content ∧ p.primPart ∣ q.primPart := by constructor · rintro ⟨r, rfl⟩ - rw [content_mul, p.isPrimitive_primPart.dvd_primPart_iff_dvd hq] + rw [(associated_content_mul ..).dvd_iff_dvd_right, + p.isPrimitive_primPart.dvd_primPart_iff_dvd hq] exact ⟨dvd_mul_right .., dvd_mul_of_dvd_left p.primPart_dvd _⟩ · rintro ⟨h₁, h₂⟩ rw [p.eq_C_content_mul_primPart, q.eq_C_content_mul_primPart] gcongr -noncomputable instance (priority := 100) normalizedGcdMonoid : NormalizedGCDMonoid R[X] := +noncomputable instance normalizedGcdMonoid : NormalizedGCDMonoid R[X] := letI := Classical.decEq R normalizedGCDMonoidOfExistsLCM fun p q => by rcases exists_primitive_lcm_of_isPrimitive p.isPrimitive_primPart @@ -443,8 +470,9 @@ noncomputable instance (priority := 100) normalizedGcdMonoid : NormalizedGCDMono rcases hpq with (hpq | hpq) <;> simp [hpq, hs] iterate 3 rw [dvd_iff_content_dvd_content_and_primPart_dvd_primPart hs] nontriviality R - rw [content_mul, rprim.content_eq_one, mul_one, content_C, normalize_lcm, lcm_dvd_iff, - primPart_mul (mul_ne_zero hpq rprim.ne_zero), rprim.primPart_eq, + rw [(associated_content_mul ..).dvd_iff_dvd_left, rprim.content_eq_one, mul_one, content_C, + (associated_primPart_mul (mul_ne_zero hpq rprim.ne_zero)).dvd_iff_dvd_left, rprim.primPart_eq, + normalize_lcm, lcm_dvd_iff, (isUnit_primPart_C (lcm p.content q.content)).mul_left_dvd, ← hr s.primPart] tauto @@ -458,4 +486,12 @@ theorem degree_gcd_le_right (p) {q : R[X]} (hq : q ≠ 0) : (gcd p q).degree ≤ end NormalizedGCDMonoid +noncomputable instance [StrongNormalizedGCDMonoid R] : StrongNormalizedGCDMonoid R[X] where + __ : NormalizedGCDMonoid R[X] := inferInstance + __ : StrongNormalizationMonoid R[X] := inferInstance + +-- We do not add a `GCDMonoid R[X]` instance due to diamond +instance [IsGCDMonoid R] : IsGCDMonoid R[X] := + have := Classical.arbitrary (NormalizedGCDMonoid R); inferInstance + end Polynomial diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean index 01a6f5ec86d5b5..22a9397b02b9b3 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean @@ -47,8 +47,7 @@ theorem cyclotomic_expand_eq_cyclotomic_mul {p n : ℕ} (hp : Nat.Prime p) (hdiv refine eq_of_monic_of_dvd_of_natDegree_le ((cyclotomic.monic _ ℤ).mul (cyclotomic.monic _ ℤ)) ((cyclotomic.monic n ℤ).expand hp.pos) ?_ ?_ · refine (IsPrimitive.Int.dvd_iff_map_cast_dvd_map_cast _ _ - (IsPrimitive.mul (cyclotomic.isPrimitive (n * p) ℤ) (cyclotomic.isPrimitive n ℤ)) - ((cyclotomic.monic n ℤ).expand hp.pos).isPrimitive).2 ?_ + ((cyclotomic.isPrimitive (n * p) ℤ).mul (cyclotomic.isPrimitive n ℤ))).2 ?_ rw [Polynomial.map_mul, map_cyclotomic_int, map_cyclotomic_int, map_expand, map_cyclotomic_int] refine IsCoprime.mul_dvd (cyclotomic.isCoprime_rat fun h => ?_) ?_ ?_ · replace h : n * p = n * 1 := by simp [h] diff --git a/Mathlib/RingTheory/Polynomial/GaussLemma.lean b/Mathlib/RingTheory/Polynomial/GaussLemma.lean index 39af4196f09f96..584ae38d88571c 100644 --- a/Mathlib/RingTheory/Polynomial/GaussLemma.lean +++ b/Mathlib/RingTheory/Polynomial/GaussLemma.lean @@ -213,7 +213,7 @@ end IsIntegrallyClosed open IsLocalization -section NormalizedGCDMonoid +section GCDMonoid variable [IsDomain R] @@ -233,27 +233,23 @@ theorem isUnit_or_eq_zero_of_isUnit_integerNormalization_primPart [NormalizedGCD · apply h0 con · apply Units.ne_zero _ con -variable [Nonempty (NormalizedGCDMonoid R)] +variable [IsGCDMonoid R] lemma IsPrimitive.mul_map_mem_lifts_iff {f : R[X]} (hf : IsPrimitive f) {g : K[X]} : g * f.map (algebraMap R K) ∈ lifts (algebraMap R K) ↔ g ∈ lifts (algebraMap R K) := by let : NormalizedGCDMonoid R := Nonempty.some inferInstance - refine ⟨?_, fun h ↦ Subsemiring.mul_mem _ h ⟨_, rfl⟩⟩ - intro ⟨k, (hk : Polynomial.map _ _ = _)⟩ - let g' := integerNormalization (nonZeroDivisors R) g - obtain ⟨b, hb₁, (hb₂ : Polynomial.map _ g' = _)⟩ := - integerNormalization_spec (nonZeroDivisors R) g + refine ⟨fun ⟨k, (hk : k.map _ = _)⟩ ↦ ?_, fun h ↦ mul_mem h ⟨_, rfl⟩⟩ + let g' := integerNormalization R⁰ g + obtain ⟨b, hb₁, (hb₂ : g'.map _ = _)⟩ := integerNormalization_spec R⁰ g have g'_mul_f : g' * f = b • k := by - apply Polynomial.map_injective (algebraMap R K) (FaithfulSMul.algebraMap_injective R K) + apply map_injective (algebraMap R K) (FaithfulSMul.algebraMap_injective R K) rw [Polynomial.map_smul, algebraMap_smul, hk, ← smul_mul_assoc, ← hb₂, Polynomial.map_mul] - use C (normUnit b : R) * C k.content * g'.primPart - have := congr($(g'_mul_f).content) - simp only [content_mul, hf.content_eq_one, mul_one, smul_eq_C_mul, content_C, - normalize_apply] at this - rw [← smul_right_inj (nonZeroDivisors.ne_zero hb₁), ← hb₂] - rw (occs := [2]) [eq_C_content_mul_primPart g'] - simp [this, Polynomial.map_mul, map_C, Algebra.smul_def, algebraMap_apply, - mul_assoc] + apply_fun content at g'_mul_f + have h := Associated.of_eq g'_mul_f + grw [← C_mul', associated_content_mul, associated_content_C_mul, hf.content_eq_one, mul_one] at h + obtain ⟨g'', hg⟩ : C b ∣ g' := dvd_content_iff_C_dvd.mp <| (dvd_mul_right ..).trans h.dvd' + use g'' + simp [← smul_right_inj (nonZeroDivisors.ne_zero hb₁), ← hb₂, hg, C_mul'] lemma IsPrimitive.map_mul_mem_lifts_iff {f : R[X]} (hf : IsPrimitive f) {g : K[X]} : f.map (algebraMap R K) * g ∈ lifts (algebraMap R K) ↔ g ∈ lifts (algebraMap R K) := by @@ -280,10 +276,9 @@ theorem IsPrimitive.irreducible_iff_irreducible_map_fraction_map {p : R[X]} (hp obtain ⟨u, hu⟩ : Associated (c * d) (content (integerNormalization R⁰ a) * content (integerNormalization R⁰ b)) := by - rw [← dvd_dvd_iff_associated, ← normalize_eq_normalize_iff, normalize.map_mul, - normalize.map_mul, normalize_content, normalize_content, ← - mul_one (normalize c * normalize d), ← hp.content_eq_one, ← content_C, ← content_C, ← - content_mul, ← content_mul, ← content_mul, h1] + grw [← associated_content_mul, ← h1, associated_content_mul, ← C_mul, content_C, + hp.content_eq_one, mul_one] + apply associated_normalize rw [← map_mul, eq_comm, (integerNormalization R⁰ a).eq_C_content_mul_primPart, (integerNormalization R⁰ b).eq_C_content_mul_primPart, mul_assoc, mul_comm _ (C _ * _), ← mul_assoc, ← mul_assoc, ← map_mul, ← hu, map_mul, mul_assoc, mul_assoc, ← @@ -303,36 +298,21 @@ theorem IsPrimitive.irreducible_iff_irreducible_map_fraction_map {p : R[X]} (hp apply isUnit_or_eq_zero_of_isUnit_integerNormalization_primPart h0.1 h theorem IsPrimitive.dvd_of_fraction_map_dvd_fraction_map {p q : R[X]} (hp : p.IsPrimitive) - (hq : q.IsPrimitive) (h_dvd : p.map (algebraMap R K) ∣ q.map (algebraMap R K)) : p ∣ q := by + (h_dvd : p.map (algebraMap R K) ∣ q.map (algebraMap R K)) : p ∣ q := by rcases h_dvd with ⟨r, hr⟩ - obtain ⟨s, s0, hs⟩ := integerNormalization_spec R⁰ r - rw [Algebra.smul_def, algebraMap_apply] at hs - have h : p ∣ q * C s := by - use integerNormalization R⁰ r - apply map_injective (algebraMap R K) (IsFractionRing.injective _ _) - rw [Polynomial.map_mul, Polynomial.map_mul, hs, hr, mul_assoc, mul_comm r] - simp - have := Classical.arbitrary (NormalizedGCDMonoid R) - rw [← hp.dvd_primPart_iff_dvd, primPart_mul, hq.primPart_eq, Associated.dvd_iff_dvd_right] at h - · exact h - · symm - rcases isUnit_primPart_C s with ⟨u, hu⟩ - use u - rw [hu] - iterate 2 - apply mul_ne_zero hq.ne_zero - rw [Ne, C_eq_zero] - contrapose s0 - simp [s0, mem_nonZeroDivisors_iff_ne_zero] + obtain ⟨r, rfl⟩ := (mul_map_mem_lifts_iff hp).mp ⟨q, mul_comm _ r ▸ hr⟩ + use r + simpa [← Polynomial.map_mul, (map_injective _ (FaithfulSMul.algebraMap_injective R K)).eq_iff] + using hr variable (K) -theorem IsPrimitive.dvd_iff_fraction_map_dvd_fraction_map {p q : R[X]} (hp : p.IsPrimitive) - (hq : q.IsPrimitive) : p ∣ q ↔ p.map (algebraMap R K) ∣ q.map (algebraMap R K) := +theorem IsPrimitive.dvd_iff_fraction_map_dvd_fraction_map {p q : R[X]} (hp : p.IsPrimitive) : + p ∣ q ↔ p.map (algebraMap R K) ∣ q.map (algebraMap R K) := ⟨fun ⟨a, b⟩ => ⟨a.map (algebraMap R K), b.symm ▸ Polynomial.map_mul (algebraMap R K)⟩, fun h => - hp.dvd_of_fraction_map_dvd_fraction_map hq h⟩ + hp.dvd_of_fraction_map_dvd_fraction_map h⟩ -end NormalizedGCDMonoid +end GCDMonoid end FractionMap @@ -342,8 +322,8 @@ theorem IsPrimitive.Int.irreducible_iff_irreducible_map_cast {p : ℤ[X]} (hp : Irreducible p ↔ Irreducible (p.map (Int.castRingHom ℚ)) := hp.irreducible_iff_irreducible_map_fraction_map -theorem IsPrimitive.Int.dvd_iff_map_cast_dvd_map_cast (p q : ℤ[X]) (hp : p.IsPrimitive) - (hq : q.IsPrimitive) : p ∣ q ↔ p.map (Int.castRingHom ℚ) ∣ q.map (Int.castRingHom ℚ) := - hp.dvd_iff_fraction_map_dvd_fraction_map ℚ hq +theorem IsPrimitive.Int.dvd_iff_map_cast_dvd_map_cast (p q : ℤ[X]) (hp : p.IsPrimitive) : + p ∣ q ↔ p.map (Int.castRingHom ℚ) ∣ q.map (Int.castRingHom ℚ) := + hp.dvd_iff_fraction_map_dvd_fraction_map ℚ end Polynomial diff --git a/Mathlib/RingTheory/PowerSeries/Inverse.lean b/Mathlib/RingTheory/PowerSeries/Inverse.lean index 4186b5caaba40a..01c77db9d93550 100644 --- a/Mathlib/RingTheory/PowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/PowerSeries/Inverse.lean @@ -311,17 +311,15 @@ theorem maximalIdeal_eq_span_X : IsLocalRing.maximalIdeal (k⟦X⟧) = Ideal.spa apply Ideal.eq_top_of_isUnit_mem I hfI0 (IsUnit.map C (Ne.isUnit hfX)) rw [IsLocalRing.eq_maximalIdeal hX] -set_option linter.style.whitespace false in -- manual alignment is not recognised -instance : NormalizationMonoid k⟦X⟧ where +instance : StrongNormalizationMonoid k⟦X⟧ where normUnit f := (Unit_of_divided_by_X_pow_order f)⁻¹ normUnit_zero := by simp only [Unit_of_divided_by_X_pow_order_zero, inv_one] - normUnit_mul := fun hf hg ↦ by + normUnit_mul hf hg := by simp only [← mul_inv, inv_inj] simp only [Unit_of_divided_by_X_pow_order_nonzero (mul_ne_zero hf hg), Unit_of_divided_by_X_pow_order_nonzero hf, Unit_of_divided_by_X_pow_order_nonzero hg, Units.ext_iff, Units.val_mul, ← divXPowOrder_mul] - normUnit_coe_units := by - intro u + normUnit_coe_units u := by set u₀ := u.1 with hu have h₀ : IsUnit u₀ := ⟨u, hu.symm⟩ rw [inv_inj, Units.ext_iff, ← hu, Unit_of_divided_by_X_pow_order_nonzero h₀.ne_zero] diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index b0e4c092c9bd35..a06cd2ff1b50bb 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -218,10 +218,10 @@ variable (R) /-- Any Bézout domain is a GCD domain. This is not an instance since `GCDMonoid` contains data, and this might not be how we would like to construct it. -/ @[implicit_reducible] -noncomputable def toGCDDomain [IsBezout R] [IsDomain R] [DecidableEq R] : GCDMonoid R := +noncomputable def toGCDDomain [IsBezout R] [IsCancelMulZero R] [DecidableEq R] : GCDMonoid R := gcdMonoidOfGCD (gcd · ·) (gcd_dvd_left · ·) (gcd_dvd_right · ·) dvd_gcd -instance nonemptyGCDMonoid [IsBezout R] [IsDomain R] : Nonempty (GCDMonoid R) := by +instance [IsBezout R] [IsCancelMulZero R] : IsGCDMonoid R := by classical exact ⟨toGCDDomain R⟩ theorem associated_gcd_gcd [GCDMonoid R] : Associated (IsBezout.gcd x y) (GCDMonoid.gcd x y) := diff --git a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean index cee6484f6fc28b..ea33f168a34ee2 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean @@ -122,8 +122,7 @@ theorem minpoly_eq_pow {p : ℕ} [hprime : Fact p.Prime] (hdiv : ¬p ∣ n) : have Qirr : Irreducible Q := minpoly.irreducible ((h.pow_of_prime hprime.1 hdiv).isIntegral hpos) have PQprim : IsPrimitive (P * Q) := Pmonic.isPrimitive.mul Qmonic.isPrimitive have prod : P * Q ∣ X ^ n - 1 := by - rw [IsPrimitive.Int.dvd_iff_map_cast_dvd_map_cast (P * Q) (X ^ n - 1) PQprim - (monic_X_pow_sub_C (1 : ℤ) (ne_of_gt hpos)).isPrimitive, + rw [IsPrimitive.Int.dvd_iff_map_cast_dvd_map_cast (P * Q) (X ^ n - 1) PQprim, Polynomial.map_mul] refine IsCoprime.mul_dvd ?_ ?_ ?_ · have aux := IsPrimitive.Int.irreducible_iff_irreducible_map_cast Pmonic.isPrimitive diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean index d71c4fdea1e966..22f9f66073f64f 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean @@ -10,13 +10,13 @@ public import Mathlib.RingTheory.ClassGroup.Basic /-! # The class group of a Unique Factorization Domain is trivial -This file proves that the ideal class group of a Normalized GCD Domain is trivial. +This file proves that the ideal class group of a GCD Domain is trivial. The main application is to Unique Factorization Domains, -which are known to be Normalized GCD Domains. +which are known to be GCD Domains. ## Main result -- `NormalizedGCDMonoid.subsingleton_classGroup` : the class group of a domain with - normalizable gcd is trivial. This includes unique factorization domains. +- `IsGCDMonoid.subsingleton_classGroup` : the class group of a GCD domain is trivial. + This includes unique factorization domains. ## References @@ -29,14 +29,13 @@ open FractionalIdeal Ideal public section -variable {R : Type*} [CommRing R] [IsDomain R] [Nonempty (NormalizedGCDMonoid R)] -namespace NormalizedGCDMonoid +variable {R : Type*} [CommRing R] [IsDomain R] [IsGCDMonoid R] +namespace IsGCDMonoid lemma isPrincipal_of_exists_mul_ne_zero_isPrincipal {J : Ideal R} (hJ : ∃ K : Ideal R, J * K ≠ 0 ∧ (J * K).IsPrincipal) : J.IsPrincipal := by - letI : NormalizedGCDMonoid R := - Classical.choice (inferInstance : Nonempty (NormalizedGCDMonoid R)) + letI : NormalizedGCDMonoid R := Classical.arbitrary _ obtain ⟨K, hJK0, hK⟩ := hJ rcases hK.principal with ⟨x, hJK⟩ have hxmemJK : x ∈ J * K := by simp [hJK] @@ -74,13 +73,12 @@ lemma isPrincipal_of_exists_mul_ne_zero_isPrincipal apply dvd_mul_of_dvd_left suffices x ∣ normalize b * g from this.trans ((associated_normalize b).mul_right g).dvd' -- Show `x ∣ b * g` by proving `x ∣ b * c` for all `b ∈ J` and `c ∈ T`. - rw [← Finset.gcd_mul_left, Finset.dvd_gcd_iff] + rw [← (Finset.gcd_mul_left' ..).dvd_iff_dvd_right, Finset.dvd_gcd_iff] intro c hc - rw [← mem_span_singleton, span, ← hJK] - exact mul_mem_mul hb (hTK hc) + rw [← mem_span_singleton, span, ← hJK, normalize_apply] + exact mul_mem_mul (J.mul_mem_right _ hb) (hTK hc) -/-- In a normalized GCD domain, an integral ideal that is invertible as a fractional ideal -is principal. +/-- In a GCD domain, an integral ideal that is invertible as a fractional ideal is principal. Public API note: see `ClassGroup.isPrincipal_of_isUnit_coeIdeal`. -/ private theorem isPrincipal_of_isUnit_fractionalIdeal (I : Ideal R) @@ -105,7 +103,7 @@ private theorem isPrincipal_of_isUnit_fractionalIdeal (I : Ideal R) · simp [hIK, ha0] · simpa [hIK] using (inferInstance : (Ideal.span {a}).IsPrincipal) -/-- In a normalized GCD domain, every invertible fractional ideal is principal. +/-- In a GCD domain, every invertible fractional ideal is principal. Public API note: see `ClassGroup.isPrincipal_coeSubmodule_of_isUnit`. -/ private theorem isPrincipal_fractionalIdeal_of_isUnit @@ -118,7 +116,7 @@ private theorem isPrincipal_fractionalIdeal_of_isUnit exact isPrincipal_of_isPrincipal_num (I : FractionalIdeal R⁰ (FractionRing R)) hJprin -/-- The ideal class group of a domain with normalizable gcd is trivial. +/-- The ideal class group of a GCD domain is trivial. This includes unique factorization domains. -/ instance subsingleton_classGroup : Subsingleton (ClassGroup R) := by refine subsingleton_of_forall_eq 1 ?_ @@ -128,5 +126,8 @@ instance subsingleton_classGroup : Subsingleton (ClassGroup R) := by exact ClassGroup.mk_eq_one_iff.mpr (isPrincipal_fractionalIdeal_of_isUnit I) +end IsGCDMonoid -end NormalizedGCDMonoid +@[deprecated (since := "2026-07-08")] +alias NormalizedGCDMonoid.isPrincipal_of_exists_mul_ne_zero_isPrincipal := + IsGCDMonoid.isPrincipal_of_exists_mul_ne_zero_isPrincipal diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean index 6d041adb86a88a..84f8f56aef002b 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean @@ -31,7 +31,7 @@ many units (e.g. `ℤ`, `Ideal (ring_of_integers K)`), it has finitely many divi noncomputable def fintypeSubtypeDvd {M : Type*} [CommMonoidWithZero M] [UniqueFactorizationMonoid M] [Fintype Mˣ] (y : M) (hy : y ≠ 0) : Fintype { x // x ∣ y } := by haveI : Nontrivial M := ⟨⟨y, 0, hy⟩⟩ - haveI : NormalizationMonoid M := UniqueFactorizationMonoid.normalizationMonoid + haveI : StrongNormalizationMonoid M := UniqueFactorizationMonoid.strongNormalizationMonoid haveI := Classical.decEq M haveI := Classical.decEq (Associates M) -- We'll show `fun (u : Mˣ) (f ⊆ factors y) ↦ u * Π f` is injective diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean index abb5e77d5c3859..b94e85ead641c8 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean @@ -47,6 +47,9 @@ noncomputable def UniqueFactorizationMonoid.toGCDMonoid (α : Type*) [CommMonoid rw [← mk_eq_mk_iff_associated, ← Associates.mk_mul_mk, ← associated_iff_eq, Associates.quot_out, Associates.quot_out, mul_comm, sup_mul_inf, Associates.mk_mul_mk] +instance (priority := 100) (α) [CommMonoidWithZero α] [UniqueFactorizationMonoid α] : + IsGCDMonoid α := ⟨toGCDMonoid α⟩ + /-- `toNormalizedGCDMonoid` constructs a GCD monoid out of a normalization on a unique factorization domain. -/ @[implicit_reducible] @@ -65,15 +68,18 @@ noncomputable def UniqueFactorizationMonoid.toNormalizedGCDMonoid (α : Type*) exact ⟨hac, hab⟩ lcm_zero_left := fun a => show (⊤ ⊔ Associates.mk a).out = 0 by simp lcm_zero_right := fun a => show (Associates.mk a ⊔ ⊤).out = 0 by simp - gcd_mul_lcm := fun a b => by - rw [← out_mul, mul_comm, sup_mul_inf, mk_mul_mk, out_mk] + gcd_mul_lcm := fun a b => (out_mul' ..).symm.trans <| by + rw [mul_comm, sup_mul_inf, mk_mul_mk, out_mk] exact normalize_associated (a * b) normalize_gcd := fun a b => by apply normalize_out _ normalize_lcm := fun a b => by apply normalize_out _ } -instance (α) [CommMonoidWithZero α] [UniqueFactorizationMonoid α] : - Nonempty (NormalizedGCDMonoid α) := by - letI := UniqueFactorizationMonoid.normalizationMonoid (α := α) - classical exact ⟨UniqueFactorizationMonoid.toNormalizedGCDMonoid α⟩ +/-- `toStrongNormalizedGCDMonoid` constructs a GCD monoid out of a strong normalization on a + unique factorization domain. -/ +noncomputable abbrev UniqueFactorizationMonoid.toStrongNormalizedGCDMonoid (α : Type*) + [CommMonoidWithZero α] [UniqueFactorizationMonoid α] [StrongNormalizationMonoid α] : + StrongNormalizedGCDMonoid α where + __ := toNormalizedGCDMonoid α + __ := ‹StrongNormalizationMonoid α› end diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean index 19dca9ea9ba773..27aef704ca559f 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean @@ -83,7 +83,7 @@ theorem induction_on_coprime {P : α → Prop} (a : α) (h0 : P 0) (h1 : ∀ {x} by_cases ha0 : a = 0 · rwa [ha0] haveI : Nontrivial α := ⟨⟨_, _, ha0⟩⟩ - letI : NormalizationMonoid α := UniqueFactorizationMonoid.normalizationMonoid + letI : StrongNormalizationMonoid α := UniqueFactorizationMonoid.strongNormalizationMonoid refine P_of_associated (prod_normalizedFactors ha0) ?_ rw [← (normalizedFactors a).map_id, Finset.prod_multiset_map_count] refine induction_on_prime_power _ _ ?_ ?_ @h1 @hpr @hcp <;> simp only [Multiset.mem_toFinset] @@ -130,7 +130,7 @@ theorem multiplicative_of_coprime (f : α → β) (a b : α) (h0 : f 0 = 0) _ = f a * f (b * 1) := by simp only [h1 isUnit_one, hf1, mul_zero] _ = f a * f b := by rw [mul_one] haveI : Nontrivial α := ⟨⟨_, _, ha0⟩⟩ - letI : NormalizationMonoid α := UniqueFactorizationMonoid.normalizationMonoid + letI : StrongNormalizationMonoid α := UniqueFactorizationMonoid.strongNormalizationMonoid suffices f (∏ p ∈ (normalizedFactors a).toFinset ∪ (normalizedFactors b).toFinset, p ^ ((normalizedFactors a).count p + (normalizedFactors b).count p)) = diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean index e0f095c0f440fe..ec20b2835b46b2 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean @@ -157,7 +157,7 @@ lemma dvd_iff_emultiplicity_le {a b : R} (ha : a ≠ 0) : refine ⟨fun h _ _ ↦ emultiplicity_le_emultiplicity_of_dvd_right h, fun h ↦ ?_⟩ by_cases hb : b = 0 · simp_all - letI : NormalizationMonoid R := UniqueFactorizationMonoid.normalizationMonoid + letI : StrongNormalizationMonoid R := UniqueFactorizationMonoid.strongNormalizationMonoid rw [dvd_iff_normalizedFactors_le_normalizedFactors ha hb, Multiset.le_iff_count] intro q by_cases hq : q ∈ normalizedFactors a diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean index 3db98f8f11a8b3..4c515f6c69eb24 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean @@ -54,10 +54,12 @@ theorem prod_normalizedFactors {a : α} (ane0 : a ≠ 0) : ext rw [Function.comp_apply, Associates.mk_normalize] -theorem prod_normalizedFactors_eq {a : α} (ane0 : a ≠ 0) : +theorem prod_normalizedFactors_eq {α} [CommMonoidWithZero α] [StrongNormalizationMonoid α] + [UniqueFactorizationMonoid α] {a : α} (ane0 : a ≠ 0) : (normalizedFactors a).prod = normalize a := by trans normalize (normalizedFactors a).prod - · rw [normalizedFactors, ← map_multiset_prod, normalize_idem] + · rw [normalizedFactors, ← coe_normalizeHom, ← map_multiset_prod, coe_normalizeHom, + normalize_idem] · exact normalize_eq_normalize_iff.mpr (dvd_dvd_iff_associated.mpr (prod_normalizedFactors ane0)) theorem prime_of_normalized_factor {a : α} : ∀ x : α, x ∈ normalizedFactors a → Prime x := by @@ -201,7 +203,7 @@ theorem dvd_iff_normalizedFactors_le_normalizedFactors {x y : α} (hx : x ≠ 0) theorem _root_.Associated.normalizedFactors_eq {a b : α} (h : Associated a b) : normalizedFactors a = normalizedFactors b := by unfold normalizedFactors - have h' : ⇑(normalize (α := α)) = Associates.out ∘ Associates.mk := funext Associates.out_mk + have h' : normalize (α := α) = Associates.out ∘ Associates.mk := funext Associates.out_mk rw [h', ← Multiset.map_map, ← Multiset.map_map, Associates.rel_associated_iff_map_eq_map.mp (factors_rel_of_associated h)] @@ -371,10 +373,11 @@ open Multiset Associates variable [CommMonoidWithZero α] [UniqueFactorizationMonoid α] open scoped Classical in -/-- Noncomputably defines a `normalizationMonoid` structure on a `UniqueFactorizationMonoid`. -/ +/-- Noncomputably defines a `StrongNormalizationMonoid` structure on a `UniqueFactorizationMonoid`. +-/ @[implicit_reducible] -protected noncomputable def normalizationMonoid : NormalizationMonoid α := - normalizationMonoidOfMonoidHomRightInverse +protected noncomputable def strongNormalizationMonoid : StrongNormalizationMonoid α := + strongNormalizationMonoidOfMonoidHomRightInverse { toFun := fun a : Associates α => if a = 0 then 0 else @@ -402,6 +405,12 @@ protected noncomputable def normalizationMonoid : NormalizationMonoid α := associated_iff_eq] apply prod_normalizedFactors hx) +@[deprecated (since := "2026-07-08")] +protected alias normalizationMonoid := UniqueFactorizationMonoid.strongNormalizationMonoid + +instance (priority := 100) : Nonempty (StrongNormalizationMonoid α) := + ⟨UniqueFactorizationMonoid.strongNormalizationMonoid⟩ + end UniqueFactorizationMonoid namespace UniqueFactorizationMonoid From b9a56a66c2378a50b39ada1f5a8fe63b9bb1eeff Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Wed, 8 Jul 2026 15:51:28 +0000 Subject: [PATCH 0690/1300] chore: fix ENat-related `backward.isDefEq.respectTransparency` (#41482) Add a `WithBot ENat` lemma matching one for `ENat` and use it directly to avoid abusing the defeq between `ENat`/`WithTop Nat` in two places. --- Mathlib/Data/ENat/Basic.lean | 3 +++ Mathlib/Order/KrullDimension.lean | 10 +++++----- Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean | 6 ++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Mathlib/Data/ENat/Basic.lean b/Mathlib/Data/ENat/Basic.lean index ba7945bc7626cd..6ef55d1250976f 100644 --- a/Mathlib/Data/ENat/Basic.lean +++ b/Mathlib/Data/ENat/Basic.lean @@ -633,6 +633,9 @@ namespace ENat.WithBot @[simp] lemma coe_eq_natCast (n : ℕ) : (n : ℕ∞) = (n : WithBot ℕ∞) := rfl +lemma eq_top_iff_forall_ge {n : WithBot ℕ∞} : n = ⊤ ↔ ∀ m : ℕ, m ≤ n := + _root_.WithBot.eq_top_iff_forall_ge + lemma lt_add_one_iff {n : WithBot ℕ∞} {m : ℕ} : n < m + 1 ↔ n ≤ m := by rw [← WithBot.coe_one, ← ENat.coe_one, WithBot.coe_natCast, ← Nat.cast_add, ← WithBot.coe_natCast] cases n diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index 05c8a6d13cb88a..b40d78664694ba 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -711,11 +711,11 @@ lemma krullDim_eq_top [InfiniteDimensionalOrder α] : | ⊥, hm => False.elim <| by haveI : Inhabited α := ⟨LTSeries.withLength _ 0 0⟩ exact not_le_of_gt (WithBot.bot_lt_coe _ : ⊥ < (0 : WithBot (WithTop ℕ))) <| hm default - | some ⊤, _ => le_refl _ - | some (some m), hm => by - refine (not_lt_of_ge (hm (LTSeries.withLength _ (m + 1))) ?_).elim - simp [ENat.WithBot.lt_add_one_iff] - norm_cast + | ⊤, _ => le_refl _ + | m, hm => by + rw [top_le_iff, ENat.WithBot.eq_top_iff_forall_ge] + intro n + simpa using hm (LTSeries.withLength _ n) lemma krullDim_eq_top_iff : krullDim α = ⊤ ↔ InfiniteDimensionalOrder α := by refine ⟨fun h ↦ ?_, fun _ ↦ krullDim_eq_top⟩ diff --git a/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean b/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean index f9485349cf4bc1..02ba2e127fcead 100644 --- a/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean +++ b/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean @@ -91,7 +91,6 @@ lemma ringKrullDim_add_natCard_le_ringKrullDim_mvPolynomial (σ : Type*) [Finite grw [IH, ringKrullDim_succ_le_ringKrullDim_polynomial] exact (ringKrullDim_eq_of_ringEquiv (MvPolynomial.optionEquivLeft _ _).toRingEquiv).ge -set_option backward.isDefEq.respectTransparency false in open MvPolynomial in lemma ringKrullDim_add_enatCard_le_ringKrullDim_mvPolynomial (σ : Type*) : ringKrullDim R + ENat.card σ ≤ ringKrullDim (MvPolynomial σ R) := by @@ -102,15 +101,14 @@ lemma ringKrullDim_add_enatCard_le_ringKrullDim_mvPolynomial (σ : Type*) : exact ringKrullDim_add_natCard_le_ringKrullDim_mvPolynomial _ · simp only [ENat.card_eq_top_of_infinite, WithBot.coe_top] suffices ringKrullDim (MvPolynomial σ R) = ⊤ by simp_all - rw [WithBot.eq_top_iff_forall_ge] + rw [ENat.WithBot.eq_top_iff_forall_ge] intro n let ι := Infinite.natEmbedding σ ∘ Fin.val (n := n + 1) have := Function.invFun_surjective (f := ι) ((Infinite.natEmbedding σ).2.comp Fin.val_injective) refine le_trans ?_ (ringKrullDim_le_of_surjective (rename (R := R) _).toRingHom (rename_surjective _ this)) refine le_trans ?_ (ringKrullDim_add_natCard_le_ringKrullDim_mvPolynomial _) - simp only [ENat.some_eq_coe, Nat.card_eq_fintype_card, Fintype.card_fin, Nat.cast_add, - Nat.cast_one] + simp only [Nat.card_eq_fintype_card, Fintype.card_fin, Nat.cast_add, Nat.cast_one] trans n + 1 · norm_cast simp From 463839dbb4ba1f666390dffb830ed42e7605e088 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 8 Jul 2026 18:17:36 +0000 Subject: [PATCH 0691/1300] feat(Translate): validate all translations (#40365) Make `to_dual`/`to_additive` validate all translations that are added. In particular, translations between fields of structures, and between lemmas generated by `simps`, are now validated. This will help catch translation problems. In the file `Limits.Cones`, the same issue with `simps` keeps arising due to how `CategoryTheory.Iso` interacts with `to_dual`. Ideally this could be fixed at the meta level to avoid these awkward workarounds. This PR also removes a heuristic in the name guessing algorithm for re-tagging declarations that were already tagged. After this PR, there won't be any reason anymore to re-tag declarations, so this heuristic can be removed. Additionally, the `translateOverwrite` linter is strengthened so that it always warns when overwriting an existing translation. Due to #40493, which added a universe metavariable unification, we now need to call `processPostponed` to ensure all universe metavariables will be assigned. --- Mathlib/Algebra/Category/MonCat/Basic.lean | 1 + Mathlib/Algebra/Notation/Defs.lean | 1 + Mathlib/CategoryTheory/Adjunction/Basic.lean | 8 +- Mathlib/CategoryTheory/CommSq.lean | 5 +- Mathlib/CategoryTheory/Comma/Basic.lean | 37 ++++-- Mathlib/CategoryTheory/EpiMono.lean | 2 - Mathlib/CategoryTheory/Iso.lean | 2 +- .../LiftingProperties/Basic.lean | 1 + Mathlib/CategoryTheory/Limits/Cones.lean | 70 +++++++++- Mathlib/CategoryTheory/Limits/IsLimit.lean | 22 ++-- .../Limits/Shapes/Grothendieck.lean | 3 +- .../Limits/Shapes/StrongEpi.lean | 4 - Mathlib/CategoryTheory/Limits/VanKampen.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Grp.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Mod.lean | 3 +- Mathlib/CategoryTheory/Monoidal/Mon.lean | 4 +- Mathlib/CategoryTheory/NatIso.lean | 3 +- Mathlib/CategoryTheory/NatTrans.lean | 3 +- Mathlib/CategoryTheory/Retract.lean | 3 + Mathlib/GroupTheory/FreeGroup/Basic.lean | 1 + .../GroupTheory/MonoidLocalization/Basic.lean | 1 + Mathlib/Order/CompleteBooleanAlgebra.lean | 1 + Mathlib/Order/Heyting/Basic.lean | 2 + Mathlib/Order/Hom/Basic.lean | 8 +- Mathlib/Order/Hom/CompleteLattice.lean | 12 +- Mathlib/Order/Hom/WithTopBot.lean | 18 ++- Mathlib/Order/Lattice.lean | 2 +- Mathlib/Order/SuccPred/Archimedean.lean | 2 - Mathlib/Order/SuccPred/Basic.lean | 2 - Mathlib/Order/SuccPred/Limit.lean | 3 +- Mathlib/Order/UpperLower/CompleteLattice.lean | 8 +- Mathlib/Tactic/ToAdditive.lean | 4 +- Mathlib/Tactic/ToDual.lean | 2 +- Mathlib/Tactic/Translate/Core.lean | 123 ++++++++++-------- MathlibTest/Attribute/ToAdditive/Basic.lean | 30 ++++- MathlibTest/Attribute/ToDual.lean | 30 +++-- 36 files changed, 279 insertions(+), 146 deletions(-) diff --git a/Mathlib/Algebra/Category/MonCat/Basic.lean b/Mathlib/Algebra/Category/MonCat/Basic.lean index 70cc261223147a..42a3b43d3ad6c8 100644 --- a/Mathlib/Algebra/Category/MonCat/Basic.lean +++ b/Mathlib/Algebra/Category/MonCat/Basic.lean @@ -106,6 +106,7 @@ abbrev ofHom {X Y : Type u} [Monoid X] [Monoid Y] (f : X →* Y) : of X ⟶ of Y ConcreteCategory.ofHom (C := MonCat) f /-- Use the `ConcreteCategory.hom` projection for `@[simps]` lemmas. -/ +@[to_additive /-- Use the `ConcreteCategory.hom` projection for `@[simps]` lemmas. -/] def Hom.Simps.hom (X Y : MonCat.{u}) (f : Hom X Y) := f.hom diff --git a/Mathlib/Algebra/Notation/Defs.lean b/Mathlib/Algebra/Notation/Defs.lean index 5aed3f1ceec315..281afb2937ae4c 100644 --- a/Mathlib/Algebra/Notation/Defs.lean +++ b/Mathlib/Algebra/Notation/Defs.lean @@ -50,6 +50,7 @@ class HVAdd (α : Type u) (β : Type v) (γ : outParam (Type w)) where attribute [notation_class smul Simps.copySecond] HSMul attribute [notation_class nsmul Simps.nsmulArgs] HSMul attribute [notation_class zsmul Simps.zsmulArgs] HSMul +attribute [notation_class vadd Simps.copySecond] HVAdd /-- Type class for the `+ᵥ` notation. -/ class VAdd (G : Type u) (P : Type v) where diff --git a/Mathlib/CategoryTheory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Adjunction/Basic.lean index 4ad3606f6184e9..f48f325c75ef09 100644 --- a/Mathlib/CategoryTheory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Adjunction/Basic.lean @@ -92,6 +92,7 @@ universe w v₁ v₂ v₃ u₁ u₂ u₃ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] +set_option linter.translate.warnInvalid false in /-- `F ⊣ G` represents the data of an adjunction between two functors `F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint. @@ -119,11 +120,8 @@ structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where dsimp% unit.app (G.obj Y) ≫ G.map (counit.app Y) = 𝟙 (G.obj Y) := by cat_disch to_dual_name_hint Left Right -set_option linter.translateOverwrite false -set_option linter.translateGenerateName false -attribute [to_dual existing counit] Adjunction.unit -attribute [to_dual existing right_triangle_components] Adjunction.left_triangle_components +attribute [to_dual existing] Adjunction.unit Adjunction.left_triangle_components attribute [to_dual self (reorder := C D, 2 4, F G, unit counit, left_triangle_components right_triangle_components)] Adjunction.mk attribute [to_dual self (reorder := C D, 2 4, F G, @@ -593,7 +591,7 @@ lemma comp_unit_app (X : C) : dsimp% (adj₁.comp adj₂).unit.app X = adj₁.unit.app X ≫ G.map (adj₂.unit.app (F.obj X)) := by simp [Adjunction.comp] -@[to_dual existing (attr := simp, reassoc) comp_unit_app] +@[to_dual existing (attr := simp, reassoc)] lemma comp_counit_app (X : E) : dsimp% (adj₁.comp adj₂).counit.app X = H.map (adj₁.counit.app (I.obj X)) ≫ adj₂.counit.app X := by simp [Adjunction.comp] diff --git a/Mathlib/CategoryTheory/CommSq.lean b/Mathlib/CategoryTheory/CommSq.lean index 4fbb955280fb35..2aab35db91b8ca 100644 --- a/Mathlib/CategoryTheory/CommSq.lean +++ b/Mathlib/CategoryTheory/CommSq.lean @@ -32,6 +32,7 @@ namespace CategoryTheory variable {C : Type*} [Category* C] +set_option linter.translate.warnInvalid false in /-- The proposition that a square ``` W ---f---> X @@ -55,11 +56,9 @@ namespace CommSq variable {W X Y Z : C} {f : W ⟶ X} {g : W ⟶ Y} {h : X ⟶ Z} {i : Y ⟶ Z} -set_option linter.translateOverwrite false in @[to_dual existing w] lemma w' (self : CommSq f g h i) : g ≫ i = f ≫ h := self.w.symm -set_option linter.translateOverwrite false in /-- `CommSq.mk'` is the dual of `CommSq.mk`, which we need for `to_dual`. Please avoid using this directly. -/ @[to_dual existing mk] @@ -171,6 +170,7 @@ namespace CommSq variable {A B X Y : C} {f : A ⟶ X} {i : A ⟶ B} {p : X ⟶ Y} {g : B ⟶ Y} +set_option linter.translate.warnInvalid false in /-- Now we consider a square: ``` A ---f---> X @@ -193,7 +193,6 @@ structure LiftStruct (sq : CommSq f i p g) where fac_right : l ≫ p = g := by cat_disch attribute [to_dual self] LiftStruct.ext -set_option linter.translateOverwrite false in attribute [to_dual existing fac_left] LiftStruct.fac_right attribute [to_dual self (reorder := A Y, B X, f g, i p, fac_left fac_right)] LiftStruct.mk diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index 84918905be1fe7..91525e9f3baeb6 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -62,6 +62,9 @@ variable {A' : Type u₄} [Category.{v₄} A'] variable {B' : Type u₅} [Category.{v₅} B'] variable {T' : Type u₆} [Category.{v₆} T'] +to_dual_name_hint Left Right, Fst Snd, L R, L₁ R₁, L₂ R₂, A B, F₁ F₂ + +set_option linter.translate.warnInvalid false in /-- The objects of the comma category are triples of an object `left : A`, an object `right : B` and a morphism `hom : L.obj left ⟶ R.obj right`. -/ @[to_dual self (reorder := A B, 2 4, L R), wikidata Q1780005] @@ -73,10 +76,8 @@ structure Comma (L : A ⥤ T) (R : B ⥤ T) : Type max u₁ u₂ v₃ where /-- A morphism from `L.obj left` to `R.obj right` -/ hom : L.obj left ⟶ R.obj right -set_option linter.translateOverwrite false - -attribute [to_dual existing right] Comma.left -attribute [to_dual self] Comma.mk +attribute [to_dual existing] Comma.left +attribute [to_dual self] Comma.hom Comma.mk -- Satisfying the inhabited linter instance Comma.inhabited [Inhabited T] : Inhabited (Comma (𝟭 T) (𝟭 T)) where @@ -87,6 +88,7 @@ instance Comma.inhabited [Inhabited T] : Inhabited (Comma (𝟭 T) (𝟭 T)) whe variable {L : A ⥤ T} {R : B ⥤ T} +set_option linter.translate.warnInvalid false in /-- A morphism between two objects in the comma category is a commutative square connecting the morphisms coming from the two objects using morphisms in the image of the functors `L` and `R`. -/ @@ -98,9 +100,7 @@ structure CommaMorphism (X Y : Comma L R) where right : X.right ⟶ Y.right w : L.map left ≫ Y.hom = X.hom ≫ R.map right := by cat_disch -attribute [to_dual existing right] CommaMorphism.left - -to_dual_name_hint Left Right, Fst Snd, L R, L₁ R₁, L₂ R₂, A B, F₁ F₂ +attribute [to_dual existing] CommaMorphism.left @[to_dual existing w] theorem CommaMorphism.w' {X Y : Comma R L} (self : CommaMorphism Y X) : @@ -155,6 +155,7 @@ end variable (L) (R) +set_option linter.translate.warnInvalid false in /-- The functor sending an object `X` in the comma category to `X.left`. -/ @[to_dual (reorder := L R) (attr := simps) /-- The functor sending an object `X` in the comma category to `X.right`. -/] @@ -162,7 +163,6 @@ def fst : Comma L R ⥤ A where obj X := X.left map f := f.left -set_option linter.existingAttributeWarning false in attribute [to_dual existing] fst_map set_option backward.defeqAttrib.useBackward true in @@ -208,11 +208,15 @@ section variable {L₁ L₂ L₃ : A ⥤ T} {R₁ R₂ R₃ : B ⥤ T} +set_option linter.translate.warnInvalid false in /-- Extract the isomorphism between the left objects from an isomorphism in the comma category. -/ @[to_dual (attr := simps!) /-- Extract the isomorphism between the right objects from an isomorphism in the comma category. -/] def leftIso {X Y : Comma L₁ R₁} (α : X ≅ Y) : X.left ≅ Y.left := (fst L₁ R₁).mapIso α +attribute [to_dual existing rightIso_inv] leftIso_hom +attribute [to_dual existing rightIso_hom] leftIso_inv + /-- Construct an isomorphism in the comma category given isomorphisms of the objects whose forward directions give a commutative square. -/ @@ -257,8 +261,9 @@ def map : Comma L R ⥤ Comma L' R' where dsimp rw [← F.map_comp_assoc, ← F.map_comp_assoc, φ.w] } -set_option linter.existingAttributeWarning false in attribute [to_dual existing] map_obj_left +attribute [to_dual existing (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, X Y)] + map_map_left set_option backward.isDefEq.respectTransparency false in @[to_dual existing (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β) map_obj_hom] @@ -317,6 +322,7 @@ where `β : R ⋙ F ⟶ F₂ ⋙ R'`. -/] theorem map_fst : map α β ⋙ fst L' R' = fst L R ⋙ F₁ := rfl +set_option linter.translate.warnInvalid false in /-- The isomorphism between `map α β ⋙ fst L' R'` and `fst L R ⋙ F₁`, where `α : F₁ ⋙ L' ⟶ L ⋙ F`. -/ @[to_dual (attr := simps!) (reorder := α β) @@ -327,6 +333,7 @@ def mapFst : map α β ⋙ fst L' R' ≅ fst L R ⋙ F₁ := end +set_option linter.translate.warnInvalid false in /-- A natural transformation `L₁ ⟶ L₂` induces a functor `Comma L₂ R ⥤ Comma L₁ R`. -/ @[to_dual (attr := simps) /-- A natural transformation `R₁ ⟶ R₂` induces a functor `Comma L R₁ ⥤ Comma L R₂`. -/] @@ -339,12 +346,11 @@ def mapLeft (l : L₁ ⟶ L₂) : Comma L₂ R ⥤ Comma L₁ R where { left := f.left right := f.right } -set_option linter.existingAttributeWarning false -set_option linter.translateGenerateName false -attribute [to_dual existing mapRight_map_right] mapLeft_map_left -attribute [to_dual existing mapRight_map_left] mapLeft_map_right +attribute [to_dual existing] mapLeft_map_left +attribute [to_dual existing] mapLeft_map_right set_option backward.defeqAttrib.useBackward true in +set_option linter.translate.warnInvalid false in /-- The functor `Comma L R ⥤ Comma L R` induced by the identity natural transformation on `L` is naturally isomorphic to the identity functor. -/ @[to_dual (attr := simps!) @@ -354,6 +360,7 @@ def mapLeftId : mapLeft R (𝟙 L) ≅ 𝟭 _ := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) set_option backward.defeqAttrib.useBackward true in +set_option linter.translate.warnInvalid false in /-- The functor `Comma L₁ R ⥤ Comma L₃ R` induced by the composition of two natural transformations `l : L₁ ⟶ L₂` and `l' : L₂ ⟶ L₃` is naturally isomorphic to the composition of the two functors induced by these natural transformations. -/ @@ -365,6 +372,7 @@ def mapLeftComp (l : L₁ ⟶ L₂) (l' : L₂ ⟶ L₃) : mapLeft R (l ≫ l') ≅ mapLeft R l' ⋙ mapLeft R l := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option linter.translate.warnInvalid false in /-- Two equal natural transformations `L₁ ⟶ L₂` yield naturally isomorphic functors `Comma L₁ R ⥤ Comma L₂ R`. -/ @[to_dual (attr := simps!) @@ -374,6 +382,7 @@ def mapLeftEq (l l' : L₁ ⟶ L₂) (h : l = l') : mapLeft R l ≅ mapLeft R l' NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) set_option backward.defeqAttrib.useBackward true in +set_option linter.translate.warnInvalid false in /-- A natural isomorphism `L₁ ≅ L₂` induces an equivalence of categories `Comma L₁ R ≌ Comma L₂ R`. -/ @[to_dual (attr := simps!) @@ -391,6 +400,7 @@ section variable {C : Type u₄} [Category.{v₄} C] +set_option linter.translate.warnInvalid false in /-- The functor `(F ⋙ L, R) ⥤ (L, R)` -/ @[to_dual (attr := simps) (reorder := F L R) /-- The functor `(L, F ⋙ R) ⥤ (L, R)` -/] def preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : Comma (F ⋙ L) R ⥤ Comma L R where @@ -443,7 +453,6 @@ def post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : Comma L R ⥤ Comma (L ⋙ right := f.right w := by simp only [Functor.comp_map, ← F.map_comp, f.w] } -set_option linter.existingAttributeWarning false in attribute [to_dual existing] post_obj_left attribute [to_dual self] post_obj_hom diff --git a/Mathlib/CategoryTheory/EpiMono.lean b/Mathlib/CategoryTheory/EpiMono.lean index 57c915cda31949..91afde3592136e 100644 --- a/Mathlib/CategoryTheory/EpiMono.lean +++ b/Mathlib/CategoryTheory/EpiMono.lean @@ -174,8 +174,6 @@ class SplitEpiCategory : Prop where /-- All epis are split -/ isSplitEpi_of_epi : ∀ {X Y : C} (f : X ⟶ Y) [Epi f], IsSplitEpi f -attribute [to_dual existing] SplitEpiCategory.isSplitEpi_of_epi SplitEpiCategory.mk - end /-- In a category in which every epimorphism is split, every epimorphism splits. This is not an diff --git a/Mathlib/CategoryTheory/Iso.lean b/Mathlib/CategoryTheory/Iso.lean index e2018dc0a520f5..24aca085030435 100644 --- a/Mathlib/CategoryTheory/Iso.lean +++ b/Mathlib/CategoryTheory/Iso.lean @@ -229,6 +229,7 @@ def homToEquiv (α : X ≅ Y) {Z : C} : (Z ⟶ X) ≃ (Z ⟶ Y) where end Iso +set_option linter.translate.warnInvalid false in /-- The `IsIso` typeclass expresses that a morphism is invertible. Given a morphism `f` with `IsIso f`, one can view `f` as an isomorphism via `asIso f` and get @@ -238,7 +239,6 @@ class IsIso (f : X ⟶ Y) : Prop where /-- The existence of an inverse morphism. -/ out : ∃ inv : Y ⟶ X, f ≫ inv = 𝟙 X ∧ inv ≫ f = 𝟙 Y -set_option linter.translateOverwrite false in /-- `IsIso.mk'` is the dual of `IsIso.mk`, which we need for `to_dual`. Please avoid using this directly. -/ @[to_dual existing mk] diff --git a/Mathlib/CategoryTheory/LiftingProperties/Basic.lean b/Mathlib/CategoryTheory/LiftingProperties/Basic.lean index 185a3dd028503c..e89bf38bd4f1a2 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/Basic.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/Basic.lean @@ -38,6 +38,7 @@ variable {C : Type*} [Category* C] {A B B' X Y Y' : C} (i : A ⟶ B) (i' : B ⟶ to_dual_name_hint Left Right, A Y, B X, I P +set_option linter.translate.warnInvalid false in /-- `HasLiftingProperty i p` means that `i` has the left lifting property with respect to `p`, or equivalently that `p` has the right lifting property with respect to `i`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 0d406a66ca30b3..106186e51c2118 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -289,9 +289,10 @@ lemma ConeMorphism.map_w {c c' : Cone F} (f : c ⟶ c') (G : C ⥤ D) (j : J) : namespace Cone +set_option linter.translate.warnInvalid false in /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ -@[to_dual (attr := simps) ext_inv +@[to_dual (attr := simps) extInv /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/] def ext {c c' : Cone F} (φ : c.pt ≅ c'.pt) @@ -301,22 +302,33 @@ def ext {c c' : Cone F} (φ : c.pt ≅ c'.pt) { hom := φ.inv w := fun j => φ.inv_comp_eq.mpr (w j) } +attribute [to_dual existing extInv_inv_hom] ext_hom_hom +attribute [to_dual existing extInv_hom_hom] ext_inv_hom + +set_option linter.translate.warnInvalid false in /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ @[to_dual (attr := simps!) ext /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/] -def ext_inv {c c' : Cone F} (φ : c.pt ≅ c'.pt) +def extInv {c c' : Cone F} (φ : c.pt ≅ c'.pt) (w : ∀ j, φ.inv ≫ c.π.app j = c'.π.app j := by cat_disch) : c ≅ c' := ext φ fun j ↦ (Iso.inv_comp_eq φ).mp (w j) +attribute [to_dual existing ext_hom_hom] extInv_inv_hom +attribute [to_dual existing ext_inv_hom] extInv_hom_hom + attribute [aesop apply safe (rule_sets := [CategoryTheory])] Limits.Cone.ext Limits.Cocone.ext +set_option linter.translate.warnInvalid false in /-- Eta rule for cones. -/ @[to_dual (attr := simps!) /-- Eta rule for cocones. -/] def eta (c : Cone F) : c ≅ ⟨c.pt, c.π⟩ := ext (Iso.refl _) +attribute [to_dual existing eta_hom_hom] eta_inv_hom +attribute [to_dual existing eta_inv_hom] eta_hom_hom + /-- Given a cone morphism whose object part is an isomorphism, produce an isomorphism of cones. -/ @@ -333,11 +345,16 @@ theorem cone_iso_of_hom_iso {K : J ⥤ C} {c d : Cone K} (f : c ⟶ d) [i : IsIs def extendHom (s : Cone F) {X : C} (f : X ⟶ s.pt) : s.extend f ⟶ s where hom := f +set_option linter.translate.warnInvalid false in /-- Extending a cone by the identity does nothing. -/ @[to_dual (attr := simps!) /-- Extending a cocone by the identity does nothing. -/] def extendId (s : Cone F) : s.extend (𝟙 s.pt) ≅ s := ext (Iso.refl _) +attribute [to_dual existing extendId_inv_hom] extendId_hom_hom +attribute [to_dual existing extendId_hom_hom] extendId_inv_hom + +set_option linter.translate.warnInvalid false in /-- Extending a cone by a composition is the same as extending the cone twice. -/ @[to_dual (attr := simps!) (reorder := f g) /-- Extending a cocone by a composition is the same as extending the cone twice. -/] @@ -345,6 +362,10 @@ def extendComp (s : Cone F) {X Y : C} (f : X ⟶ Y) (g : Y ⟶ s.pt) : s.extend (f ≫ g) ≅ (s.extend g).extend f := ext (Iso.refl _) +attribute [to_dual existing extendComp_inv_hom] extendComp_hom_hom +attribute [to_dual existing extendComp_hom_hom] extendComp_inv_hom + +set_option linter.translate.warnInvalid false in /-- A cone extended by an isomorphism is isomorphic to the original cone. -/ @[to_dual (attr := simps) /-- A cocone extended by an isomorphism is isomorphic to the original cone. -/] @@ -352,6 +373,9 @@ def extendIso (s : Cone F) {X : C} (f : s.pt ≅ X) : s ≅ s.extend f.inv where hom := { hom := f.hom } inv := { hom := f.inv } +attribute [to_dual existing extendIso_inv_hom] extendIso_hom_hom +attribute [to_dual existing extendIso_hom_hom] extendIso_inv_hom + @[to_dual] instance {s : Cone F} {X : C} (f : X ⟶ s.pt) [IsIso f] : IsIso (s.extendHom f) := ⟨(extendIso s (asIso' f)).hom, by cat_disch⟩ @@ -368,6 +392,7 @@ def postcompose {G : J ⥤ C} (α : F ⟶ G) : Cone F ⥤ Cone G where π := c.π ≫ α } map f := { hom := f.hom } +set_option linter.translate.warnInvalid false in /-- Postcomposing a cone by the composite natural transformation `α ≫ β` is the same as postcomposing by `α` and then by `β`. -/ @[to_dual (attr := simps!) (reorder := α β) @@ -377,12 +402,19 @@ def postcomposeComp {G H : J ⥤ C} (α : F ⟶ G) (β : G ⟶ H) : postcompose (α ≫ β) ≅ postcompose α ⋙ postcompose β := NatIso.ofComponents fun s => ext (Iso.refl _) +attribute [to_dual existing precomposeComp_inv_app_hom] postcomposeComp_hom_app_hom +attribute [to_dual existing precomposeComp_hom_app_hom] postcomposeComp_inv_app_hom + +set_option linter.translate.warnInvalid false in /-- Postcomposing by the identity does not change the cone up to isomorphism. -/ @[to_dual (attr := simps!) /-- Precomposing by the identity does not change the cocone up to isomorphism. -/] def postcomposeId : postcompose (𝟙 F) ≅ 𝟭 (Cone F) := NatIso.ofComponents fun s => ext (Iso.refl _) +attribute [to_dual existing precomposeId_inv_app_hom] postcomposeId_hom_app_hom +attribute [to_dual existing precomposeId_hom_app_hom] postcomposeId_inv_app_hom + /-- If `F` and `G` are naturally isomorphic functors, then they have equivalent categories of cones. -/ @@ -582,12 +614,16 @@ open CategoryTheory.Limits def mapCone (c : Cone F) : Cone (F ⋙ H) := (Cone.functoriality F H).obj c +set_option linter.translate.warnInvalid false in /-- The construction `mapCone` respects functor composition. -/ @[to_dual (attr := simps!) /-- The construction `mapCocone` respects functor composition. -/] noncomputable def mapConeMapCone {F : J ⥤ C} {H : C ⥤ D} {H' : D ⥤ E} (c : Cone F) : H'.mapCone (H.mapCone c) ≅ (H ⋙ H').mapCone c := Cone.ext (Iso.refl _) +attribute [to_dual existing mapCoconeMapCocone_inv_hom] mapConeMapCone_hom_hom +attribute [to_dual existing mapCoconeMapCocone_hom_hom] mapConeMapCone_inv_hom + /-- Given a cone morphism `c ⟶ c'`, construct a cone morphism on the mapped cones functorially. -/ @[to_dual /-- Given a cocone morphism `c ⟶ c'`, construct a cocone morphism on the mapped cocones @@ -616,6 +652,7 @@ noncomputable def mapConeInvMapCone {F : J ⥤ D} (H : D ⥤ C) [IsEquivalence H mapConeInv H (mapCone H c) ≅ c := (Limits.Cone.functorialityEquivalence F (asEquivalence H)).unitIso.symm.app c +set_option linter.translate.warnInvalid false in /-- `functoriality F _ ⋙ postcompose (whisker_left F _)` simplifies to `functoriality F _`. -/ @[to_dual (attr := simps!) /-- `functoriality F _ ⋙ precompose (whiskerLeft F _)` simplifies to `functoriality F _`. -/] @@ -623,6 +660,12 @@ def functorialityCompPostcompose {H H' : C ⥤ D} (α : H ≅ H') : Cone.functoriality F H ⋙ Cone.postcompose (whiskerLeft F α.hom) ≅ Cone.functoriality F H' := NatIso.ofComponents fun c => Cone.ext (α.app _) +attribute [to_dual existing functorialityCompPrecompose_inv_app_hom] + functorialityCompPostcompose_hom_app_hom +attribute [to_dual existing functorialityCompPrecompose_hom_app_hom] + functorialityCompPostcompose_inv_app_hom + +set_option linter.translate.warnInvalid false in /-- For `F : J ⥤ C`, given a cone `c : Cone F`, and a natural isomorphism `α : H ≅ H'` for functors `H H' : C ⥤ D`, the postcomposition of the cone `H.mapCone` using the isomorphism `α` is isomorphic to the cone `H'.mapCone`. @@ -637,6 +680,12 @@ def postcomposeWhiskerLeftMapCone {H H' : C ⥤ D} (α : H ≅ H') (c : Cone F) (Cone.postcompose (whiskerLeft F α.hom :)).obj (mapCone H c) ≅ mapCone H' c := (functorialityCompPostcompose α).app c +attribute [to_dual existing precomposeWhiskerLeftMapCocone_inv_hom] + postcomposeWhiskerLeftMapCone_hom_hom +attribute [to_dual existing precomposeWhiskerLeftMapCocone_hom_hom] + postcomposeWhiskerLeftMapCone_inv_hom + +set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `postcompose`. In particular, for `F : J ⥤ C`, given a cone `c : Cone F`, a natural transformation `α : F ⟶ G` and a functor `H : C ⥤ D`, we have two obvious ways of producing @@ -652,6 +701,10 @@ def mapConePostcompose {α : F ⟶ G} {c} : (Cone.postcompose (whiskerRight α H :)).obj (mapCone H c) := Cone.ext (Iso.refl _) +attribute [to_dual existing mapCoconePrecompose_inv_hom] mapConePostcompose_hom_hom +attribute [to_dual existing mapCoconePrecompose_hom_hom] mapConePostcompose_inv_hom + +set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `postcomposeEquivalence` -/ @[to_dual (attr := simps!) /-- `mapCocone` commutes with `precomposeEquivalence` -/] def mapConePostcomposeEquivalenceFunctor {α : F ≅ G} {c} : @@ -659,11 +712,20 @@ def mapConePostcomposeEquivalenceFunctor {α : F ≅ G} {c} : (Cone.postcomposeEquivalence (isoWhiskerRight α H :)).functor.obj (mapCone H c) := Cone.ext (Iso.refl _) +attribute [to_dual existing mapCoconePrecomposeEquivalenceFunctor_inv_hom] + mapConePostcomposeEquivalenceFunctor_hom_hom +attribute [to_dual existing mapCoconePrecomposeEquivalenceFunctor_hom_hom] + mapConePostcomposeEquivalenceFunctor_inv_hom + +set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `whisker` -/ @[to_dual (attr := simps!) /-- `mapCocone` commutes with `whisker` -/] def mapConeWhisker {E : K ⥤ J} {c : Cone F} : mapCone H (c.whisker E) ≅ (mapCone H c).whisker E := Cone.ext (Iso.refl _) +attribute [to_dual existing mapCoconeWhisker_inv_hom] mapConeWhisker_hom_hom +attribute [to_dual existing mapCoconeWhisker_hom_hom] mapConeWhisker_inv_hom + end Functor namespace Limits @@ -829,10 +891,14 @@ open CategoryTheory.Limits variable {F : J ⥤ C} (G : C ⥤ D) +set_option linter.translate.warnInvalid false in /-- The opposite cocone of the image of a cone is the image of the opposite cocone. -/ @[to_dual (attr := simps!) /-- The opposite cone of the image of a cocone is the image of the opposite cone. -/] def mapConeOp (t : Cone F) : (mapCone G t).op ≅ mapCocone G.op t.op := Cocone.ext (Iso.refl _) +attribute [to_dual existing mapCoconeOp_inv_hom] mapConeOp_hom_hom +attribute [to_dual existing mapCoconeOp_hom_hom] mapConeOp_inv_hom + end CategoryTheory.Functor diff --git a/Mathlib/CategoryTheory/Limits/IsLimit.lean b/Mathlib/CategoryTheory/Limits/IsLimit.lean index 57c4bedb521de0..fb192345963e50 100644 --- a/Mathlib/CategoryTheory/Limits/IsLimit.lean +++ b/Mathlib/CategoryTheory/Limits/IsLimit.lean @@ -71,7 +71,7 @@ structure IsColimit (t : Cocone F) where /-- The map `desc` makes the diagram with the natural transformations commute -/ fac : ∀ (s : Cocone F) (j : J), dsimp% t.ι.app j ≫ desc s = s.ι.app j := by cat_disch /-- `desc` is the unique such map -/ - uniq : + uniq : dsimp% ∀ (s : Cocone F) (m : t.pt ⟶ s.pt) (_ : ∀ j : J, t.ι.app j ≫ m = s.ι.app j), m = desc s := by cat_disch @@ -145,6 +145,7 @@ def mkConeMorphism {t : Cone F} (lift : ∀ s : Cone F, s ⟶ t) have : ConeMorphism.mk m w = lift s := by apply uniq congrArg ConeMorphism.hom this +set_option linter.translate.warnInvalid false in /-- Limit cones on `F` are unique up to isomorphism. -/ @[to_dual (attr := simps) /-- Colimit cocones on `F` are unique up to isomorphism. -/] def uniqueUpToIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : s ≅ t where @@ -153,6 +154,9 @@ def uniqueUpToIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : s ≅ t where hom_inv_id := P.uniq_cone_morphism inv_hom_id := Q.uniq_cone_morphism +attribute [to_dual existing uniqueUpToIso_inv] uniqueUpToIso_hom +attribute [to_dual existing uniqueUpToIso_hom] uniqueUpToIso_inv + /-- Any cone morphism between limit cones is an isomorphism. -/ @[to_dual (reorder := P Q) /-- Any cocone morphism between colimit cocones is an isomorphism. -/] theorem hom_isIso {s t : Cone F} (P : IsLimit s) (Q : IsLimit t) (f : s ⟶ t) : IsIso f := @@ -338,6 +342,7 @@ def equivOfNatIsoOfIso {F G : J ⥤ C} (α : F ≅ G) (c : Cone F) (d : Cone G) (postcomposeHomEquiv α _).symm.trans (equivIsoLimit w) set_option backward.defeqAttrib.useBackward true in +set_option linter.translate.warnInvalid false in /-- The cone points of two limit cones for naturally isomorphic functors are themselves isomorphic. -/ @@ -352,10 +357,8 @@ def conePointsIsoOfNatIso {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit hom_inv_id := P.hom_ext (by simp) inv_hom_id := Q.hom_ext (by simp) -set_option linter.translateOverwrite false in -attribute [to_dual existing IsColimit.coconePointsIsoOfNatIso_inv] conePointsIsoOfNatIso_hom -set_option linter.translateOverwrite false in -attribute [to_dual existing IsColimit.coconePointsIsoOfNatIso_hom] conePointsIsoOfNatIso_inv +attribute [to_dual existing coconePointsIsoOfNatIso_inv] conePointsIsoOfNatIso_hom +attribute [to_dual existing coconePointsIsoOfNatIso_hom] conePointsIsoOfNatIso_inv @[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_inv] theorem conePointsIsoOfNatIso_hom_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) @@ -433,6 +436,7 @@ def extendIsoEquiv {s : Cone F} {X : C} (i : X ⟶ s.pt) [IsIso i] : set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option linter.translate.warnInvalid false in /-- We can prove two cone points `(s : Cone F).pt` and `(t : Cone G).pt` are isomorphic if * both cones are limit cones * their indexing categories are equivalent via some `e : J ≌ K`, @@ -468,12 +472,8 @@ def conePointsIsoOfEquivalence {F : J ⥤ C} {s : Cone F} {G : K ⥤ C} {t : Con apply hom_ext Q cat_disch } -set_option linter.translateOverwrite false in -attribute [to_dual existing IsColimit.coconePointsIsoOfEquivalence_inv] - conePointsIsoOfEquivalence_hom -set_option linter.translateOverwrite false in -attribute [to_dual existing IsColimit.coconePointsIsoOfEquivalence_hom] - conePointsIsoOfEquivalence_inv +attribute [to_dual existing coconePointsIsoOfEquivalence_inv] conePointsIsoOfEquivalence_hom +attribute [to_dual existing coconePointsIsoOfEquivalence_hom] conePointsIsoOfEquivalence_inv end Equivalence diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean b/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean index 55a57cc5349fce..aca1b0a3a32c72 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean @@ -143,8 +143,7 @@ def isColimitCoconeFiberwiseColimitOfCocone {c : Cocone G} (hc : IsColimit c) : simp only [Functor.const_obj_obj, IsColimit.fac, NatTrans.comp_app, Functor.comp_obj, Grothendieck.forget_obj, natTransIntoForgetCompFiberwiseColimit_app, whiskerLeft_app] - simp only [coconeFiberwiseColimitOfCocone_pt, Functor.const_obj_obj, - coconeFiberwiseColimitOfCocone_ι_app] at this + simp only [coconeFiberwiseColimitOfCocone_pt, coconeFiberwiseColimitOfCocone_ι_app] at this simp [← this] lemma hasColimit_fiberwiseColimit [HasColimit G] : HasColimit (fiberwiseColimit G) where diff --git a/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean b/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean index e10bb4da61c91f..68d2320f57e874 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean @@ -64,8 +64,6 @@ class StrongMono (f : P ⟶ Q) : Prop where /-- The right lifting property with respect to all epimorphisms -/ rlp : ∀ ⦃X Y : C⦄ (z : X ⟶ Y) [Epi z], HasLiftingProperty z f -attribute [to_dual existing] StrongEpi.llp StrongEpi.mk - @[to_dual (reorder := hf (X Y, u v))] theorem StrongEpi.mk' {f : P ⟶ Q} [Epi f] (hf : ∀ (X Y : C) (z : X ⟶ Y) (_ : Mono z) (u : P ⟶ X) @@ -146,8 +144,6 @@ class StrongMonoCategory : Prop where /-- A strong mono category is a category in which every monomorphism is strong. -/ strongMono_of_mono : ∀ {X Y : C} (f : X ⟶ Y) [Mono f], StrongMono f -attribute [to_dual existing] StrongEpiCategory.strongEpi_of_epi StrongEpiCategory.mk - end @[to_dual] diff --git a/Mathlib/CategoryTheory/Limits/VanKampen.lean b/Mathlib/CategoryTheory/Limits/VanKampen.lean index 4b7e5be79c6a66..15d6a166144b66 100644 --- a/Mathlib/CategoryTheory/Limits/VanKampen.lean +++ b/Mathlib/CategoryTheory/Limits/VanKampen.lean @@ -660,7 +660,7 @@ theorem isVanKampenColimit_extendCofan {n : ℕ} (f : Fin (n + 1) → C) refine Hc.uniq (Cofan.mk T (Fin.cases f₁ (fun i ↦ Sigma.ι (fun (j : Fin n) ↦ (Discrete.functor F').obj ⟨j.succ⟩) _ ≫ f₂))) _ ?_ intro ⟨j⟩ - simp only [Discrete.functor_obj, Cofan.mk_pt, Functor.const_obj_obj, Cofan.mk_ι_app] + simp only [Discrete.functor_obj, Cofan.mk_pt, Cofan.mk_ι_app] induction j using Fin.inductionOn · simp only [Fin.cases_zero, m₁] · simp only [← m₂, colimit.ι_desc_assoc, Discrete.functor_obj, diff --git a/Mathlib/CategoryTheory/Monoidal/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Grp.lean index c515ce6f7c0a53..1219d99e346b1c 100644 --- a/Mathlib/CategoryTheory/Monoidal/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Grp.lean @@ -57,7 +57,7 @@ namespace GrpObj attribute [reassoc (attr := simp)] left_inv right_inv attribute [reassoc (attr := simp)] AddGrpObj.left_neg AddGrpObj.right_neg -attribute [to_additive existing] left_inv left_inv_assoc right_inv right_inv_assoc +attribute [to_additive existing] left_inv_assoc right_inv_assoc @[to_additive] instance instTensorUnit : GrpObj (𝟙_ C) where diff --git a/Mathlib/CategoryTheory/Monoidal/Mod.lean b/Mathlib/CategoryTheory/Monoidal/Mod.lean index c46da70fe15944..70c46cbe43f302 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mod.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mod.lean @@ -64,6 +64,7 @@ class ModObj (X : D) where /-- The action map is compatible with multiplication. -/ mul_smul (X) : μ ⊵ₗ X ≫ smul = (αₗ M M X).hom ≫ M ⊴ₗ smul ≫ smul := by cat_disch +set_option linter.translateOverwrite false in attribute [to_additive existing (attr := reassoc (attr := simp))] ModObj.mul_smul ModObj.one_smul @@ -191,6 +192,7 @@ alias IsMod_Hom := IsModHom @[deprecated (since := "2026-04-21")] alias IsMod_Hom.smul_hom := IsModHom.smul_hom +set_option linter.translateOverwrite false in attribute [to_additive existing (attr := reassoc (attr := simp))] IsModHom.smul_hom variable {M N O : D} [ModObj A M] [ModObj A N] [ModObj A O] @@ -264,7 +266,6 @@ structure Hom (M N : Mod D A) where [isModHom : IsModHom A hom] attribute [instance] Hom.isModHom -attribute [to_additive existing (attr := instance)] Hom.isModHom /-- An alternative constructor for `Hom`, taking a morphism without a `[IsModHom]` instance, as well as the relevant diff --git a/Mathlib/CategoryTheory/Monoidal/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Mon.lean index 511a06c6329210..a23acdc24df1d3 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon.lean @@ -102,6 +102,7 @@ variable {M X Y : C} [MonObj M] @[inherit_doc] scoped notation "η" => MonObj.one @[inherit_doc] scoped notation "η[" M "]" => MonObj.one (X := M) +set_option linter.translateOverwrite false in attribute [to_additive existing (attr := reassoc (attr := simp))] one_mul mul_one mul_assoc /-- Transfer `MonObj` along an isomorphism. -/ @@ -213,6 +214,7 @@ class IsMonHom (f : M ⟶ N) : Prop where one_hom (f) : η ≫ f = η := by cat_disch mul_hom (f) : μ ≫ f = (f ⊗ₘ f) ≫ μ := by cat_disch +set_option linter.translateOverwrite false in attribute [to_additive existing (attr := reassoc (attr := simp))] IsMonHom.one_hom IsMonHom.mul_hom @[to_additive] @@ -521,7 +523,7 @@ structure Hom (M N : Mon C) where hom : M.X ⟶ N.X [isMonHom_hom : IsMonHom hom] -attribute [to_additive existing (attr := instance)] Hom.isMonHom_hom +attribute [instance] Hom.isMonHom_hom /-- Construct a morphism `M ⟶ N` of `Mon C` from a map `f : M ⟶ N` and compatibilities with the unit and the multiplication. -/ diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index dac61bd6dd46be..f5393261e2531f 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -172,6 +172,7 @@ theorem isIso_inv_app (α : F ⟶ G) [IsIso α] (X) : (inv α).app X = inv (α.a theorem inv_map_inv_app (F : C ⥤ D ⥤ E) {X Y : C} (e : X ≅ Y) (Z : D) : inv ((F.map e.inv).app Z) = (F.map e.hom).app Z := by cat_disch +set_option linter.translate.warnInvalid false in /-- Construct a natural isomorphism between functors by giving object level isomorphisms, and checking naturality only in the forward direction. -/ @@ -189,10 +190,8 @@ def ofComponents (app : ∀ X : C, F.obj X ≅ G.obj X) simp only [Iso.inv_hom_id_assoc, Iso.hom_inv_id, assoc, comp_id] at h exact h } -set_option linter.translateOverwrite false in attribute [to_dual existing ofComponents'_inv_app] ofComponents_hom_app -set_option linter.translateOverwrite false in attribute [to_dual existing ofComponents'_hom_app] ofComponents_inv_app @[to_dual (attr := simp)] diff --git a/Mathlib/CategoryTheory/NatTrans.lean b/Mathlib/CategoryTheory/NatTrans.lean index 0427d0dd616b3d..d5cd9410c7cb75 100644 --- a/Mathlib/CategoryTheory/NatTrans.lean +++ b/Mathlib/CategoryTheory/NatTrans.lean @@ -42,6 +42,7 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] +set_option linter.translate.warnInvalid false in /-- `NatTrans F G` represents a natural transformation between functors `F` and `G`. The field `app` provides the components of the natural transformation. @@ -55,12 +56,10 @@ structure NatTrans (F G : C ⥤ D) : Type max u₁ v₂ where /-- The naturality square for a given morphism. -/ naturality ⦃X Y : C⦄ (f : X ⟶ Y) : F.map f ≫ app Y = app X ≫ G.map f := by cat_disch -set_option linter.translateOverwrite false in @[to_dual existing naturality] lemma NatTrans.naturality' {F G : C ⥤ D} (self : NatTrans G F) ⦃X Y : C⦄ (f : Y ⟶ X) : self.app Y ≫ F.map f = G.map f ≫ self.app X := (self.naturality f).symm -set_option linter.translateOverwrite false in /-- `NatTrans.mk'` is the dual of `NatTrans.mk`, which we need for `to_dual`. Please avoid using this directly. -/ @[to_dual existing mk] diff --git a/Mathlib/CategoryTheory/Retract.lean b/Mathlib/CategoryTheory/Retract.lean index c0986d2ae21ec4..d3cba593ccdf19 100644 --- a/Mathlib/CategoryTheory/Retract.lean +++ b/Mathlib/CategoryTheory/Retract.lean @@ -121,11 +121,14 @@ lemma i_w : h.i.left ≫ g = f ≫ h.i.right := h.i.w @[to_dual none, reassoc] lemma r_w : h.r.left ≫ f = g ≫ h.r.right := h.r.w +set_option linter.translate.warnInvalid false in /-- The top of a retract diagram of morphisms determines a retract of objects. -/ @[to_dual (attr := simps!) /-- The bottom of a retract diagram of morphisms determines a retract of objects. -/] def left : Retract X Z := h.map Arrow.leftFunc +attribute [to_dual existing] left_i left_r + @[to_dual (attr := reassoc (attr := simp))] lemma retract_left : h.i.left ≫ h.r.left = 𝟙 X := h.left.retract diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 1596a9dac2f92d..614f4742809c6c 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -438,6 +438,7 @@ theorem IsReduced.infix (h : IsReduced L₂) (h' : L₁ <:+: L₂) : IsReduced L end IsReduced end FreeGroup +set_option linter.translateOverwrite false in /-- If `α` is a type, then `FreeGroup α` is the free group generated by `α`. This is a group equipped with a function `FreeGroup.of : α → FreeGroup α` which has diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index 6b2cb8e36d0c07..08a7a2e46461ca 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -203,6 +203,7 @@ theorem r_iff_oreEqv_r {x y : M × S} : r S x y ↔ (OreLocalization.oreEqv S M) end Localization +set_option linter.translateOverwrite false in /-- The localization of a `CommMonoid` at one of its submonoids (as a quotient type). -/ @[to_additive AddLocalization /-- The localization of an `AddCommMonoid` at one of its submonoids (as a quotient type). -/] diff --git a/Mathlib/Order/CompleteBooleanAlgebra.lean b/Mathlib/Order/CompleteBooleanAlgebra.lean index 9617a6f5bfbbce..686e989f975c90 100644 --- a/Mathlib/Order/CompleteBooleanAlgebra.lean +++ b/Mathlib/Order/CompleteBooleanAlgebra.lean @@ -82,6 +82,7 @@ theorem inf_sSup_eq {α : Type*} [Order.Frame α] {s : Set α} {a : α} : a ⊓ sSup s = ⨆ b ∈ s, a ⊓ b := gc_inf_himp.l_sSup +set_option linter.translate.warnInvalid false in /-- A coframe, aka complete Brouwer algebra or complete co-Heyting algebra, is a complete lattice whose `⊔` distributes over `⨅`. -/ @[to_dual] diff --git a/Mathlib/Order/Heyting/Basic.lean b/Mathlib/Order/Heyting/Basic.lean index 9cf8edd7dc9b3a..dcacfa7ccb0a1e 100644 --- a/Mathlib/Order/Heyting/Basic.lean +++ b/Mathlib/Order/Heyting/Basic.lean @@ -140,6 +140,7 @@ class GeneralizedHeytingAlgebra (α : Type*) extends Lattice α, OrderTop α, HI /-- `(a ⇨ ·)` is right adjoint to `(a ⊓ ·)` -/ le_himp_iff (a b c : α) : a ≤ b ⇨ c ↔ a ⊓ b ≤ c +set_option linter.translate.warnInvalid false in /-- A generalized co-Heyting algebra is a lattice with an additional binary difference operation `\` such that `(· \ a)` is left adjoint to `(· ⊔ a)`. @@ -155,6 +156,7 @@ class HeytingAlgebra (α : Type*) extends GeneralizedHeytingAlgebra α, OrderBot /-- `aᶜ` is defined as `a ⇨ ⊥` -/ himp_bot (a : α) : a ⇨ ⊥ = aᶜ +set_option linter.translate.warnInvalid false in /-- A co-Heyting algebra is a bounded lattice with an additional binary difference operation `\` such that `(· \ a)` is left adjoint to `(· ⊔ a)`. -/ @[to_dual] diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 22ef5cfb8f190a..351b640014edbf 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -94,8 +94,8 @@ abbrev OrderEmbedding (α β : Type*) [LE α] [LE β] := @RelEmbedding α β (· ≤ ·) (· ≤ ·) to_dual_insert_cast_fun OrderEmbedding := - fun ⟨iso, h⟩ ↦ ⟨iso, by rwa [forall_comm]⟩, - fun ⟨iso, h⟩ ↦ ⟨iso, by rwa [forall_comm]⟩ + fun i ↦ ⟨i.1, by rw [forall_comm]; exact @i.2⟩, + fun i ↦ ⟨i.1, by rw [forall_comm]; exact @i.2⟩ /-- Notation for an `OrderEmbedding`. -/ infixl:25 " ↪o " => OrderEmbedding @@ -106,8 +106,8 @@ abbrev OrderIso (α β : Type*) [LE α] [LE β] := @RelIso α β (· ≤ ·) (· ≤ ·) to_dual_insert_cast_fun OrderIso := - fun ⟨iso, h⟩ ↦ ⟨iso, by rwa [forall_comm]⟩, - fun ⟨iso, h⟩ ↦ ⟨iso, by rwa [forall_comm]⟩ + fun i ↦ ⟨i.1, by rw [forall_comm]; exact @i.2⟩, + fun i ↦ ⟨i.1, by rw [forall_comm]; exact @i.2⟩ /-- Notation for an `OrderIso`. -/ infixl:25 " ≃o " => OrderIso diff --git a/Mathlib/Order/Hom/CompleteLattice.lean b/Mathlib/Order/Hom/CompleteLattice.lean index ce3ed8eefe07db..985d41c9809745 100644 --- a/Mathlib/Order/Hom/CompleteLattice.lean +++ b/Mathlib/Order/Hom/CompleteLattice.lean @@ -183,13 +183,6 @@ end Equiv variable [FunLike F α β] -/-- Reinterpret an order isomorphism as a morphism of complete lattices. -/ -@[simps] def OrderIso.toCompleteLatticeHom [CompleteLattice α] [CompleteLattice β] - (f : OrderIso α β) : CompleteLatticeHom α β where - toFun := f - map_sInf' := sInfHomClass.map_sInf f - map_sSup' := sSupHomClass.map_sSup f - @[to_dual] instance [SupSet α] [SupSet β] [sSupHomClass F α β] : CoeTC F (sSupHom α β) := ⟨fun f => ⟨f, map_sSup f⟩⟩ @@ -454,6 +447,11 @@ instance : CompleteLatticeHomClass (CompleteLatticeHom α β) α β where map_sSup f := f.map_sSup' map_sInf f := f.map_sInf' +/-- Reinterpret an order isomorphism as a morphism of complete lattices. -/ +@[simps] def OrderIso.toCompleteLatticeHom (f : OrderIso α β) : CompleteLatticeHom α β where + toFun := f + map_sInf' := sInfHomClass.map_sInf f + map_sSup' := sSupHomClass.map_sSup f /-- Reinterpret a `CompleteLatticeHom` as a `BoundedLatticeHom`. -/ def toBoundedLatticeHom (f : CompleteLatticeHom α β) : BoundedLatticeHom α β := diff --git a/Mathlib/Order/Hom/WithTopBot.lean b/Mathlib/Order/Hom/WithTopBot.lean index bc0dccca59233c..9b4cda0089d4f0 100644 --- a/Mathlib/Order/Hom/WithTopBot.lean +++ b/Mathlib/Order/Hom/WithTopBot.lean @@ -68,13 +68,17 @@ def _root_.Function.Embedding.coeWithTop : α ↪ WithTop α where inj' := WithTop.coe_injective /-- The coercion `α → WithTop α` bundled as monotone map. -/ -@[to_dual (attr := simps -fullyApplied) +@[to_dual /-- The coercion `α → WithBot α` bundled as monotone map. -/] def coeOrderHom {α : Type*} [Preorder α] : α ↪o WithTop α where toFun := (↑) inj' := WithTop.coe_injective map_rel_iff' := WithTop.coe_le_coe +-- `simps` could generate this theorem, but `to_dual` is not happy with that version. +@[to_dual (attr := simp)] +theorem coeOrderHom_apply {α : Type*} [Preorder α] : (coeOrderHom : α → WithTop α) = some := rfl + /-- Any `OrderTop` is equivalent to `WithTop` of the subtype excluding `⊤`. See also `Equiv.optionSubtypeNe`. -/ @@ -126,12 +130,16 @@ namespace OrderEmbedding variable [Preorder α] [Preorder β] /-- A version of `WithBot.map` for order embeddings. -/ -@[to_dual (attr := simps -fullyApplied) /-- A version of `WithTop.map` for order embeddings. -/] +@[to_dual /-- A version of `WithTop.map` for order embeddings. -/] protected def withBotMap (f : α ↪o β) : WithBot α ↪o WithBot β where toFun := WithBot.map f inj' := WithBot.map_injective f.injective map_rel_iff' := WithBot.map_le_iff f f.map_rel_iff +-- `simps` could generate this theorem, but `to_dual` is not happy with that version. +@[to_dual (attr := simp)] +theorem withBotMap_apply (f : α ↪o β) : ⇑f.withBotMap = WithBot.map f := rfl + end OrderEmbedding namespace OrderIso @@ -139,12 +147,16 @@ namespace OrderIso variable [PartialOrder α] [PartialOrder β] [PartialOrder γ] /-- A version of `Equiv.optionCongr` for `WithTop`. -/ -@[to_dual (attr := simps -fullyApplied) /-- A version of `Equiv.optionCongr` for `WithBot`. -/] +@[to_dual /-- A version of `Equiv.optionCongr` for `WithBot`. -/] def withTopCongr (e : α ≃o β) : WithTop α ≃o WithTop β where toFun := WithTop.map e __ := e.toOrderEmbedding.withTopMap __ := e.toEquiv.withTopCongr +-- `simps` could generate this theorem, but `to_dual` is not happy with that version. +@[to_dual (attr := simp)] +theorem withTopCongr_apply (e : α ≃o β) : ⇑e.withTopCongr = WithTop.map e := rfl + @[simp] theorem withTopCongr_refl : (OrderIso.refl α).withTopCongr = OrderIso.refl _ := RelIso.toEquiv_injective Equiv.withTopCongr_refl diff --git a/Mathlib/Order/Lattice.lean b/Mathlib/Order/Lattice.lean index 638d9fdc787be5..c2254941159d90 100644 --- a/Mathlib/Order/Lattice.lean +++ b/Mathlib/Order/Lattice.lean @@ -88,7 +88,7 @@ class SemilatticeInf (α : Type u) extends PartialOrder α where /-- The infimum is the *greatest* lower bound -/ protected le_inf : ∀ a b c : α, a ≤ b → a ≤ c → a ≤ inf b c -attribute [to_dual existing] SemilatticeSup.sup_le SemilatticeSup.mk SemilatticeSup.casesOn +attribute [to_dual existing] SemilatticeSup.casesOn @[to_dual] instance SemilatticeSup.toMax [SemilatticeSup α] : Max α where max a b := SemilatticeSup.sup a b diff --git a/Mathlib/Order/SuccPred/Archimedean.lean b/Mathlib/Order/SuccPred/Archimedean.lean index 95d958922bd1f4..22890a86d2dd18 100644 --- a/Mathlib/Order/SuccPred/Archimedean.lean +++ b/Mathlib/Order/SuccPred/Archimedean.lean @@ -38,8 +38,6 @@ class IsPredArchimedean (α : Type*) [Preorder α] [PredOrder α] : Prop where export IsSuccArchimedean (exists_succ_iterate_of_le) export IsPredArchimedean (exists_pred_iterate_of_le) -attribute [to_dual existing] exists_succ_iterate_of_le - section Preorder variable [Preorder α] diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 916cc1ecc3d6f6..8318ad5a29c0ab 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -69,8 +69,6 @@ class PredOrder (α : Type*) [Preorder α] where /-- Proof that `pred b` is the greatest element less than `b` -/ le_pred_of_lt {a b} : a < b → a ≤ pred b -attribute [to_dual existing] PredOrder.mk PredOrder.le_pred_of_lt - @[to_dual] instance [Preorder α] [SuccOrder α] : PredOrder αᵒᵈ where pred := toDual ∘ SuccOrder.succ ∘ ofDual diff --git a/Mathlib/Order/SuccPred/Limit.lean b/Mathlib/Order/SuccPred/Limit.lean index 3a2a4e7fefc3c9..e7269ec2a418fa 100644 --- a/Mathlib/Order/SuccPred/Limit.lean +++ b/Mathlib/Order/SuccPred/Limit.lean @@ -106,8 +106,7 @@ structure IsPredLimit (a : α) : Prop where /-- Predecessor limits aren't covered by any other elements. -/ protected isPredPrelimit : IsPredPrelimit a -attribute [to_dual existing] - IsSuccLimit.mk IsSuccLimit.not_isMin IsSuccLimit.isSuccPrelimit isSuccLimit_iff +attribute [to_dual existing] isSuccLimit_iff attribute [simp] IsSuccLimit.isSuccPrelimit IsPredLimit.isPredPrelimit @[to_dual (attr := simp)] diff --git a/Mathlib/Order/UpperLower/CompleteLattice.lean b/Mathlib/Order/UpperLower/CompleteLattice.lean index 5d6cd1de5de14d..d5cd26deb4789c 100644 --- a/Mathlib/Order/UpperLower/CompleteLattice.lean +++ b/Mathlib/Order/UpperLower/CompleteLattice.lean @@ -326,7 +326,7 @@ variable [Preorder α] [Preorder β] [Preorder γ] variable {f : α ≃o β} {s t : UpperSet α} {a : α} {b : β} /-- An order isomorphism of Preorders induces an order isomorphism of their upper sets. -/ -@[to_dual (attr := simps) +@[to_dual /-- An order isomorphism of Preorders induces an order isomorphism of their lower sets. -/] def map (f : α ≃o β) : UpperSet α ≃o UpperSet β where toFun s := ⟨f '' s, s.upper.image f⟩ @@ -335,6 +335,12 @@ def map (f : α ≃o β) : UpperSet α ≃o UpperSet β where right_inv _ := ext <| f.image_preimage _ map_rel_iff' := image_subset_image_iff f.injective +-- `simps` could generate these theorems, but `to_dual` is not happy with those versions. +@[to_dual (attr := simp)] +theorem coe_map_apply (f : α ≃o β) (s : UpperSet α) : map f s = f '' s := rfl +@[to_dual (attr := simp)] +theorem coe_map_symm_apply (f : α ≃o β) (s : UpperSet β) : (map f).symm s = f ⁻¹' s := rfl + @[to_dual (attr := simp)] theorem symm_map (f : α ≃o β) : (map f).symm = map f.symm := by ext; simp [map, OrderIso.symm_apply_eq] diff --git a/Mathlib/Tactic/ToAdditive.lean b/Mathlib/Tactic/ToAdditive.lean index 3a1956837e99e2..db9f0f5cae5945 100644 --- a/Mathlib/Tactic/ToAdditive.lean +++ b/Mathlib/Tactic/ToAdditive.lean @@ -24,10 +24,12 @@ attribute [to_additive existing Zero.ofOfNat0] One.ofOfNat1 attribute [to_additive existing] Inv Mul HMul instHMul Div HDiv instHDiv +set_option linter.translate.warnInvalid false in attribute [to_additive (reorder := α β) SMul] Pow attribute [to_additive existing (reorder := α β, 4 5) smul] Pow.pow attribute [to_additive existing (reorder := α β, pow (1 2))] Pow.mk +set_option linter.translate.warnInvalid false in attribute [to_additive (reorder := α β)] HPow -attribute [to_additive existing (reorder := α β, 5 6)] HPow.hPow +attribute [to_additive existing (reorder := α β, 5 6) hSMul] HPow.hPow attribute [to_additive existing (reorder := α β, hPow (1 2))] HPow.mk attribute [to_additive existing] instHPow diff --git a/Mathlib/Tactic/ToDual.lean b/Mathlib/Tactic/ToDual.lean index b0b0650974b835..525c314bac9394 100644 --- a/Mathlib/Tactic/ToDual.lean +++ b/Mathlib/Tactic/ToDual.lean @@ -33,7 +33,7 @@ attribute [to_dual lt_of_lt_of_eq''] lt_of_lt_of_eq attribute [to_dual] Max -attribute [to_dual existing] Std.LawfulOrderSup Std.LawfulOrderSup.mk Std.LawfulOrderSup.max_le_iff +attribute [to_dual existing] Std.LawfulOrderSup -- We need to tag the lemmas used by `grind` in order to translate `grind` proofs. namespace Lean.Grind.Order diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 393fbba8d4b92f..e68ca740cfa9cd 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -164,6 +164,13 @@ register_option linter.translateRedundant : Bool := { defValue := true descr := "Linter used by translate attributes that checks if the attribute is redundant" } +/-- Linter used by translate attributes that warns when a translation was not added +because of being invalid. -/ +register_option linter.translate.warnInvalid : Bool := { + defValue := true + descr := "Linter used by translate attributes that warns when a translation was not added + because of being invalid." } + /-- `RelevantArg` represents an optional argument that should be checked to determine whether or not to translate the given constant. -/ inductive RelevantArg where @@ -295,12 +302,9 @@ where /-- Insert only one direction of a translation. -/ insertTranslationAux (src : Name) (t : TranslateData) (info : TranslationInfo) : CoreM Unit := do if let some info' := findTranslation? (← getEnv) t src then - -- After `insert_to_additive_translation`, we may end up adding same translation again. - -- So in that case, don't log a warning. - if info.translation != info'.translation then - Linter.logLintIf linter.translateOverwrite ref m!"`{src}` was already translated to \ - `{info'.translation}` instead of `{info.translation}`.\n\ - Unless the original translation was wrong, please remove this `{t.attrName}` attribute." + Linter.logLintIf linter.translateOverwrite ref m!"`{src}` was already translated to \ + `{info'.translation}` instead of `{info.translation}`.\n\ + Unless the original translation was wrong, please remove this `{t.attrName}` attribute." modifyEnv (t.translations.addEntry · (src, info)) trace[translate] "Added translation {src} ↦ {tgt}\ {if info.reorder.reorder.isEmpty then "" else s!" (reorder := {info.reorder.reorder})"} \ @@ -732,14 +736,14 @@ def findAuxDecls (decl : ConstantInfo) (pre : Name) : CoreM (Array Name) := do /-- Return the `relevant_arg` option based on the computed `relevantArg?` and the given `cfg.relevantArg?`. -/ def getRelevantArg (t : TranslateData) (cfg : Config) (relevantArg? : Option RelevantArg) - (src : Name) : CoreM RelevantArg := do + (src : Name) (lint : Bool := true) : CoreM RelevantArg := do let relevantArg := relevantArg?.getD (.arg 0) if let some relevantArg' := cfg.relevantArg? then - if relevantArg == relevantArg' then + if lint && relevantArg == relevantArg' then Linter.logLintIf linter.translateRelevantArg cfg.ref m!"\ `{t.attrName}` correctly autogenerated `(relevant_arg := {relevantArg'})` for \ `{.ofConstName src}`.\nYou may remove the option." - else if relevantArg?.isSome then + else if lint && relevantArg?.isSome then Linter.logLintIf linter.translateRelevantArg cfg.ref m!"\ `{t.attrName}` determined that `(relevant_arg := {relevantArg})` \ is the right option for `{.ofConstName src}`, \ @@ -904,24 +908,6 @@ def warnParametricAttr {β : Type} [Inhabited β] (stx : Syntax) (attr : Paramet (thisAttr attrName src tgt : Name) : CoreM Unit := warnAttrCore stx (attr.getParam? · · |>.isSome) thisAttr attrName src tgt -/-- `translateLemmas names argInfo desc t` runs `t` on all elements of `names` -and adds translations between the generated lemmas (the output of `t`). -`names` must be non-empty. -/ -def translateLemmas - (t : TranslateData) (names : Array Name) (reorder : Reorder) (relevantArg : RelevantArg) - (desc : String) (ref : Syntax) (runAttr : Name → CoreM (Array Name)) : CoreM Unit := do - let auxLemmas ← names.mapM runAttr - let nLemmas := auxLemmas[0]!.size - for nm in names, lemmas in auxLemmas do - unless lemmas.size == nLemmas do - throwError "{names[0]!} and {nm} do not generate the same number of {desc}." - for srcLemmas in auxLemmas, tgtLemmas in auxLemmas.eraseIdx! 0 do - for srcLemma in srcLemmas, tgtLemma in tgtLemmas do - -- Only add a translation if one doesn't already exist. - -- This happens if `srcLemma` is the `_assoc` lemma from `to_dual (attr := reassoc)`. - if (findTranslation? (← getEnv) t srcLemma).isNone then - insertTranslation t srcLemma tgtLemma reorder relevantArg ref - /-- Return the provided target name or autogenerate one if one was not provided. -/ def targetName (t : TranslateData) (cfg : Config) (src : Name) : CoreM Name := do if cfg.self then @@ -933,11 +919,6 @@ def targetName (t : TranslateData) (cfg : Config) (src : Name) : CoreM Name := d logWarning m!"`{t.attrName} none` ignores the provided name {cfg.target}" return ← withDeclNameForAuxNaming src do mkAuxDeclName <| .mkSimple ("_" ++ t.attrName.toString) - -- When re-tagging an existing translation, simply return that existing translation. - if cfg.existing then - if cfg.target == .anonymous then - if let some tgt := findTranslationName? (← getEnv) t src then - return tgt let .str pre s := src | throwError "{t.attrName}: can't transport {src}" trace[translate_detail] "The name {s} splits as {open GuessName in s.splitCase}" -- Auto-generated name of the resulting declaration, without prior namespace components. @@ -972,8 +953,8 @@ where n' /-- Verify that the type of `srcDecl` translates to that of `tgtDecl`. -Also try to autogenerate the `reorder` option for this translation. -/ -partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config) : +Also try to autogenerate the `reorder` and `relevant_arg` options for this translation. -/ +partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config) (lint := true) : MetaM (Reorder × RelevantArg) := withoutExporting do let srcDecl ← getConstInfo src let tgtDecl ← getConstInfo tgt @@ -990,14 +971,16 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config trace[translate_detail] "The guessed reorder is {reorder'}" let reorder ← if let some reorder := cfg.reorder? then - if reorder == reorder' then + if reorder.range > srcType.getForallArity then + throwError "The given (reorder := {reorder}) is out of bounds for `{.ofConstName src}`" + if lint && reorder == reorder' then Linter.logLintIf linter.translateReorder cfg.ref m!"\ `{t.attrName}` correctly autogenerated `(reorder := {reorder'})` for {src}.\n\ You may remove the `(reorder := {reorder})` argument." pure reorder else pure reorder' - if cfg.self && reorder.isEmpty then + if lint && cfg.self && reorder.isEmpty then Linter.logLintIf linter.translateRedundant cfg.ref m!"\ `{t.attrName} self` is redundant when none of the arguments are reordered.\n\ Please remove the attribute, or provide an explicit `(reorder := ...)` argument.\n\ @@ -1013,32 +996,63 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config unless ← withReducible <| isDefEq srcType tgtType do throwError "`{t.attrName}` validation failed: expected{indentExpr srcType}\nbut '{tgt}' has \ type{indentExpr tgtType}" + -- Process any remaining universe contraints, to assign all universe metavariables. + discard <| processPostponed (mayPostpone := false) (exceptionOnFailure := true) let params ← levels.mapM fun level ↦ do match ← instantiateLevelMVars level with | .param u => return u | _ => throwError "inferred universe `{level}` in `{srcType}` is not a parameter." let some univReorder := getPermutation params.toArray tgtDecl.levelParams.toArray | throwError "inferred universe parameters {params} \ are not a reordering of {srcDecl.levelParams}." - return ({ univReorder, reorder }, ← getRelevantArg t cfg relevantArg? src) + return ({ univReorder, reorder }, ← getRelevantArg t cfg relevantArg? src lint) + +/-- A version of `insertTranslation` that checks whether the translation is valid, and only +inserts the translation if it is valid. -/ +def insertTranslationChecked (t : TranslateData) (src tgt : Name) (cfg : Config) : CoreM Unit := do + let (reorder, relevantArg) ← + try + checkExistingType t src tgt cfg (lint := false) |>.run' + catch ex => + Linter.logLintIf linter.translate.warnInvalid cfg.ref m!"\ + @[{t.attrName}] failed to add a translation from `{.ofConstName src}` to \ + `{.ofConstName tgt}`.\nPlease silence this warning and add a translation manually. \ + Error:\n\n{ex.toMessageData}" + return + insertTranslation t src tgt reorder relevantArg cfg.ref + +/-- `translateLemmas` runs `runAttr` on all elements of `names` and adds translations between +the generated lemmas (the output of `t`). `names` must be non-empty. -/ +def translateLemmas (t : TranslateData) (names : Array Name) + (desc : String) (cfg : Config) (runAttr : Name → CoreM (Array Name)) : CoreM Unit := do + let auxLemmas ← names.mapM runAttr + let nLemmas := auxLemmas[0]!.size + for nm in names, lemmas in auxLemmas do + unless lemmas.size == nLemmas do + throwError "{names[0]!} and {nm} do not generate the same number of {desc}." + for srcLemmas in auxLemmas, tgtLemmas in auxLemmas.eraseIdx! 0 do + for srcLemma in srcLemmas, tgtLemma in tgtLemmas do + -- Only add a translation if one doesn't already exist. + -- This happens if `srcLemma` is the `_assoc` lemma from `to_dual (attr := reassoc)`. + if (findTranslation? (← getEnv) t srcLemma).isNone then + insertTranslationChecked t srcLemma tgtLemma cfg /-- if `f src = #[a_1, ..., a_n]` and `f tgt = #[b_1, ... b_n]` then `proceedFieldsAux src tgt f` will insert translations from `a_i` to `b_i`. -/ -def proceedFieldsAux (t : TranslateData) (src tgt : Name) (reorder : Reorder) - (relevantArg : RelevantArg) (ref : Syntax) (f : Name → Array Name) : CoreM Unit := do +def proceedFieldsAux (t : TranslateData) (src tgt : Name) (cfg : Config) + (f : Name → Array Name) : CoreM Unit := do let srcFields := f src let tgtFields := f tgt if srcFields.size != tgtFields.size then throwError "Failed to map fields of {src}, {tgt} with {srcFields} ↦ {tgtFields}.\n \ Lengths do not match." for srcField in srcFields, tgtField in tgtFields do - insertTranslation t srcField tgtField reorder relevantArg ref + insertTranslationChecked t srcField tgtField cfg /-- Add the structure fields of `src` to the translations dictionary so that they will be translated correctly. -/ -def proceedFields (t : TranslateData) (src tgt : Name) (reorder : Reorder) - (relevantArg : RelevantArg) (ref : Syntax) : CoreM Unit := do +def proceedFields (t : TranslateData) (src tgt : Name) (cfg : Config) : CoreM Unit := do let env ← getEnv - let aux := proceedFieldsAux t src tgt reorder relevantArg ref + let aux := proceedFieldsAux t src tgt cfg -- add translations for the structure fields aux fun declName ↦ if isStructure env declName then @@ -1164,8 +1178,8 @@ def elabTranslationAttr (declName : Name) (stx : Syntax) : CoreM Config := do mutual /-- Apply attributes to the original and translated declarations. -/ -partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) (reorder : Reorder) - (relevantArg : RelevantArg) : TermElabM (Array Name) := do +partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) : + TermElabM (Array Name) := do if !cfg.existing && !cfg.none then -- Copy the `instance` attribute, since it is nice to directly tag `instance` declarations. copyInstanceAttribute src tgt @@ -1207,7 +1221,7 @@ partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) for attr in attrs do if let some impl := (← generatingAttrs.get).find? attr.name then withRef attr.stx do withLogging do - translateLemmas t allDecls reorder relevantArg "simps lemmas" cfg.ref + translateLemmas t allDecls "simps lemmas" cfg (impl · attr.stx attr.kind) else let mut attr := attr @@ -1229,12 +1243,9 @@ partial def applyAttributes (t : TranslateData) (cfg : Config) (src tgt : Name) Term.applyAttributes decl #[attr] return nestedDecls -/-- -Copies equation lemmas and attributes from `src` to `tgt` --/ -partial def copyMetaData (t : TranslateData) (cfg : Config) (src : Name) : CoreM (Array Name) := do - let some { reorder, relevantArg, translation := tgt } := findTranslation? (← getEnv) t src | - throwError "internal `{t.attrName}` error: {src} was not translated." +/-- Copies equation lemmas and attributes from `src` to `tgt`. -/ +partial def copyMetaData (t : TranslateData) (cfg : Config) (src tgt : Name) : + CoreM (Array Name) := do -- The equation lemmas can only be related if the value of `tgt` is the translated value of `src`. unless cfg.existing do if let some eqns := eqnsAttribute.find? (← getEnv) src then @@ -1246,9 +1257,9 @@ partial def copyMetaData (t : TranslateData) (cfg : Config) (src : Name) : CoreM /- We need to generate all equation lemmas for `src` and `tgt`, even for non-recursive definitions. If we don't do that, the equation lemma for `src` might be generated later when doing a `rw`, but it won't be generated for `tgt`. -/ - translateLemmas t #[src, tgt] reorder relevantArg "equation lemmas" cfg.ref fun nm ↦ + translateLemmas t #[src, tgt] "equation lemmas" cfg fun nm ↦ (·.getD #[]) <$> MetaM.run' (getEqnsFor? nm) - applyAttributes t cfg src tgt reorder relevantArg |>.run'.run' + applyAttributes t cfg src tgt |>.run'.run' /-- `addTranslationAttr src cfg` adds a translation attribute to `src` with configuration `cfg`. See the attribute implementation for more details. @@ -1274,7 +1285,7 @@ partial def addTranslationAttr (t : TranslateData) (src : Name) (cfg : Config) -- since `tgt` already exists, we just need to -- add translations `src.x ↦ tgt.x'` for any subfields. trace[translate_detail] "declaration {tgt} already exists." - proceedFields t src tgt reorder relevantArg cfg.ref + proceedFields t src tgt cfg else unless (← withoutExporting do getConstInfo src).hasValue (allowOpaque := true) do throwError "`{t.attrName}` cannot translate `{.ofConstName src}` because it has no value." @@ -1283,7 +1294,7 @@ partial def addTranslationAttr (t : TranslateData) (src : Name) (cfg : Config) transformDeclRec t cfg src tgt src reorder cfg.rename if let some doc := cfg.doc then addDocStringCore tgt doc - let nestedNames ← copyMetaData t cfg src + let nestedNames ← copyMetaData t cfg src tgt -- add pop-up information when mousing over the given translated name -- (the information will be over the attribute if no translated name is given) Term.addTermInfo' cfg.ref (← mkConstWithLevelParams tgt) (isBinder := !alreadyExists) diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index 57b6ece3f9ffb6..36768fc9e78cfc 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -95,6 +95,8 @@ class my_has_scalar (M : Type u) (α : Type v) where smul : M → α → α instance : my_has_scalar Nat Nat := ⟨fun a b => a * b⟩ + +set_option linter.translate.warnInvalid false in attribute [to_additive (reorder := α β) my_has_scalar] my_has_pow set_option pp.mvars.anonymous false in /-- @@ -104,7 +106,7 @@ but 'Test.my_has_scalar.smul' has type {M : Type u} → {α : Type v} → [self : my_has_scalar M α] → M → α → α -/ #guard_msgs in -attribute [to_additive existing] my_has_pow.pow +attribute [to_additive existing smul] my_has_pow.pow set_option pp.mvars.anonymous false in /-- error: `to_additive` validation failed: expected @@ -113,8 +115,8 @@ but 'Test.my_has_scalar.smul' has type {M : Type u} → {α : Type v} → [self : my_has_scalar M α] → M → α → α -/ #guard_msgs in -attribute [to_additive existing (reorder := α β)] my_has_pow.pow -attribute [to_additive existing (reorder := α β, 4 5)] my_has_pow.pow +attribute [to_additive existing (reorder := α β) smul] my_has_pow.pow +attribute [to_additive existing (reorder := α β, 4 5) smul] my_has_pow.pow @[to_additive bar1] def foo1 {α : Type u} [my_has_pow α ℕ] (x : α) (n : ℕ) : α := @my_has_pow.pow α ℕ _ x n @@ -132,12 +134,14 @@ def foo2 {α} [my_has_pow α ℕ] (x : α) (n : ℕ) (m : PLift ℤ) : α := x ^ theorem foo2_works : foo2 2 3 (PLift.up 2) = Nat.pow 2 5 := by decide theorem bar2_works : bar2 2 3 (PLift.up 2) = 2 * 5 := by decide +set_option linter.translate.warnInvalid false in @[to_additive bar3] def foo3 {α} [my_has_pow α ℕ] (x : α) : ℕ → α := @my_has_pow.pow α ℕ _ x theorem foo3_works : foo3 2 3 = Nat.pow 2 3 := by decide theorem bar3_works : bar3 2 3 = 2 * 3 := by decide +set_option linter.translate.warnInvalid false in @[to_additive bar4] def foo4 {α : Type u} : Type v → Type (max u v) := @my_has_pow α @@ -148,6 +152,7 @@ set_option linter.defProp false in @[to_additive bar5] def foo5 {α} [my_has_pow α ℕ] [my_has_pow ℕ ℤ] : True := True.intro +set_option linter.translate.warnInvalid false in @[to_additive bar6] def foo6 {α} [my_has_pow α ℕ] : α → ℕ → α := @my_has_pow.pow α ℕ _ @@ -253,9 +258,9 @@ run_cmd do /- Test on inductive types -/ inductive AddInd : ℕ → Prop where | basic : AddInd 2 - | zero : AddInd 0 + | zero : AddInd 1 -@[to_additive] +@[to_additive (relevant_arg := _)] inductive MulInd : ℕ → Prop where | basic : MulInd 2 | one : MulInd 1 @@ -391,12 +396,15 @@ def reorderMulThree {α : Type _} [Mul α] (x y z : α) : α := x * y * z def reorderMulThree' {α : Type _} [Mul α] (x y z : α) : α := x * y * z /-! Test `(reorder := ...)` when the proof needs to be eta-expanded. -/ +set_option linter.translate.warnInvalid false in @[to_additive (reorder := 3 4 5)] alias reorderMulThree_alias := reorderMulThree +set_option linter.translate.warnInvalid false in @[to_additive (reorder := 3 4 2)] alias reorderMulThree_alias' := reorderMulThree +set_option linter.translate.warnInvalid false in @[to_additive (reorder := 3 4 5)] def reorderMulThree_alias'' {α : Type _} [Mul α] (x y : α) : α → α := reorderMulThree x y @@ -533,6 +541,7 @@ end Test insert_to_additive_translation localize add_localize @[to_additive] def localize.r := Nat +set_option linter.translateOverwrite false in @[to_additive add_localize] def localize := Nat @[to_additive] def localize.s := Nat @@ -601,6 +610,7 @@ elab "unfold%" e:term : term => do let e ← Elab.Term.elabTerm e none Meta.unfoldDefinition e +set_option linter.translate.warnInvalid false in @[to_additive] def myPow {α β : Type} [i : Pow α β] (a : α) := unfold% i.1 a @@ -908,6 +918,16 @@ warning: `to_additive` determined that `(relevant_arg := 2)` is the right option You may remove the option. Note: This linter can be disabled with `set_option linter.translateRelevantArg false` +--- +warning: @[to_additive] failed to add a translation from `monoidAlgebraFoo₂.eq_1` to `addMonoidAlgebraFoo₂.eq_1`. +Please silence this warning and add a translation manually. Error: + +`to_additive` validation failed: expected + ∀ {k G : Type} [inst : Inhabited k], monoidAlgebraFoo₂ = ({ x := fun x => default }, 2) +but 'addMonoidAlgebraFoo₂.eq_1' has type + ∀ {k G : Type} [inst : Inhabited k], addMonoidAlgebraFoo₂ = ({ x := fun x => default }, 2) + +Note: This linter can be disabled with `set_option linter.translate.warnInvalid false` -/ #guard_msgs in @[to_additive (dont_translate := k) (relevant_arg := k)] diff --git a/MathlibTest/Attribute/ToDual.lean b/MathlibTest/Attribute/ToDual.lean index 3eec586c7882c7..539ba3e99d00b5 100644 --- a/MathlibTest/Attribute/ToDual.lean +++ b/MathlibTest/Attribute/ToDual.lean @@ -12,13 +12,11 @@ variable {α : Type} [PartialOrder α] (a b c : α) class SemilatticeInf (α : Type) extends PartialOrder α, Min α where le_inf : ∀ a b c : α, a ≤ b → a ≤ c → a ≤ b ⊓ c +-- The `reorder` arguments are automatically inferred here: +@[to_dual] class SemilatticeSup (α : Type) extends PartialOrder α, Max α where protected sup_le : ∀ a b c : α, a ≤ c → b ≤ c → a ⊔ b ≤ c -attribute [to_dual] SemilatticeInf --- The `reorder` argument is automatically inferred here: -attribute [to_dual existing] SemilatticeSup.sup_le SemilatticeInf.mk - @[to_dual] lemma SemilatticeInf.le_inf' {α : Type} [SemilatticeInf α] (a b c : α) : a ≤ b → a ≤ c → a ≤ b ⊓ c := SemilatticeInf.le_inf a b c @@ -209,13 +207,12 @@ def lt_sum_eq_of_le [DecidableLE α] {a b : α} (hab : a ≤ b) : a < b ⊕' a = b := if hba : b ≤ a then PSum.inr (le_antisymm hab hba) else PSum.inl (lt_of_le_not_ge hab hba) -set_option warn.classDefReducibility false in +set_option linter.translate.warnInvalid false in @[to_dual DecidableLE1_dual] -def DecidableLE1 (h : ∀ a b : α, Decidable (a ≤ b)) : DecidableLE α := fun a b ↦ h a b +abbrev DecidableLE1 (h : ∀ a b : α, Decidable (a ≤ b)) : DecidableLE α := fun a b ↦ h a b -set_option warn.classDefReducibility false in @[to_dual DecidableLE2_dual] -def DecidableLE2 (h : ∀ a b : α, Decidable (a ≤ b)) : DecidableLE α := id h +abbrev DecidableLE2 (h : ∀ a b : α, Decidable (a ≤ b)) : DecidableLE α := id h -- Not yet supported because it probably won't show up in practice -- (though it wouldn't be too hard to fix `unfoldConsts` to support this) @@ -339,12 +336,13 @@ inductive WithBot.LE : WithBot α → WithBot α → Prop where | bot_le (x : WithBot α) : WithBot.LE .bot x | coe_le_coe {a b : α} : a ≤ b → WithBot.LE (.coe a) (.coe b) +set_option linter.translate.warnInvalid false in @[to_dual existing (reorder := 3 4)] inductive WithTop.LE : WithTop α → WithTop α → Prop where | le_top (x : WithTop α) : WithTop.LE x .top | coe_le_coe {a b : α} : a ≤ b → WithTop.LE (.coe a) (.coe b) -attribute [to_dual existing] WithTop.LE.le_top +attribute [to_dual existing bot_le] WithTop.LE.le_top @[to_dual] instance WithBot.instLE : _root_.LE (WithBot α) := ⟨WithBot.LE⟩ @@ -397,6 +395,20 @@ theorem le_of_lt_and_le_of_lt {β} [Preorder β] (a b : α) (c d : β) : (a < b def universeTest1.{u,v,w} (α : Type u) (β : Type v) (γ : Type w) := α × β × γ @[to_dual existing (reorder := α β γ) universeTest1] def universeTest1'.{v,w,u} (α : Type u) (β : Type v) (γ : Type w) := α × β × γ + +-- Due to the reordering of arguments, the equation theorem of the dual has a different shape, +-- so we get this warning. +/-- +warning: @[to_dual] failed to add a translation from `universeTest1''.eq_1` to `universeTest1''._to_dual_1.eq_1`. Please silence this warning and add a translation manually. Error: + +`to_dual` validation failed: expected + universeTest1''._to_dual_1 = fun α β γ => universeTest1' β γ α +but 'universeTest1''._to_dual_1.eq_1' has type + ∀ (α : Type u) (β : Type v) (γ : Type w), universeTest1''._to_dual_1 α β γ = universeTest1' β γ α + +Note: This linter can be disabled with `set_option linter.translate.warnInvalid false` +-/ +#guard_msgs in @[to_dual none] alias universeTest1'' := universeTest1 @[to_dual (reorder := u₁ u₂) universeTest2'] From 357bb374e627d1078832a9079718788c43966d43 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 8 Jul 2026 19:11:26 +0000 Subject: [PATCH 0692/1300] feat: tool for finding duplicate declarations (#33640) This PR defines a tool for finding duplicate declarations automatically. This can be used to help fix this technical debt. --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + Mathlib/Tactic/DuplicateDecls.lean | 198 ++++++++++++++++++++++ MathlibTest/Tactic/DuplicateDecls.lean | 40 +++++ MathlibTest/Tactic/DuplicateDeclsAux.lean | 36 ++++ 5 files changed, 276 insertions(+) create mode 100644 Mathlib/Tactic/DuplicateDecls.lean create mode 100644 MathlibTest/Tactic/DuplicateDecls.lean create mode 100644 MathlibTest/Tactic/DuplicateDeclsAux.lean diff --git a/Mathlib.lean b/Mathlib.lean index be5b9583eb2447..74826bc9621c0c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7293,6 +7293,7 @@ public import Mathlib.Tactic.DeriveTraversable public import Mathlib.Tactic.Determinant.Bird public import Mathlib.Tactic.Determinant.Bird.Cert public import Mathlib.Tactic.Determinant.Bird.Meta +public import Mathlib.Tactic.DuplicateDecls public import Mathlib.Tactic.ENatToNat public import Mathlib.Tactic.Eqns public import Mathlib.Tactic.ErwQuestion diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 40152d484fd5dd..6e239fb555cc45 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -102,6 +102,7 @@ public import Mathlib.Tactic.DeriveTraversable public import Mathlib.Tactic.Determinant.Bird public import Mathlib.Tactic.Determinant.Bird.Cert public import Mathlib.Tactic.Determinant.Bird.Meta +public import Mathlib.Tactic.DuplicateDecls public import Mathlib.Tactic.ENatToNat public import Mathlib.Tactic.Eqns public import Mathlib.Tactic.ErwQuestion diff --git a/Mathlib/Tactic/DuplicateDecls.lean b/Mathlib/Tactic/DuplicateDecls.lean new file mode 100644 index 00000000000000..cce91a0ef9278f --- /dev/null +++ b/Mathlib/Tactic/DuplicateDecls.lean @@ -0,0 +1,198 @@ +/- +Copyright (c) 2026 Jovan Gerbscheid. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jovan Gerbscheid +-/ +module + +public import Mathlib.Init +public import ImportGraph.Lean.Environment + +/-! +# A tool for finding duplicate declarations + +It is easy to accidentally create multiple instances of the same theorem or instance. +This file defines a tool to automatically detect such cases. +The order of hypotheses, and their binder info and binder names are ignored. +Universe parameters are also ignored. + +For theorems, it is completely redundant to have multiple of the same type. +For instances, we typically also don't want to have multiple of the same type. + +To use it, simply run the following command in a file that does not use the module system: +``` +open Lean Mathlib.Tactic.DuplicateDecls +run_meta do logInfo m!"{← lintDuplicateDeclarations .theorems}" +run_meta do logInfo m!"{← lintDuplicateDeclarations .instances}" +run_meta do logInfo m!"{← lintDuplicateDeclarations .defs}" +``` + +## How does it work + +The function `sortBinders` reorders the forall binders of a declaration type into a canonical form, +which lets us detect duplication even when the arguments are in a different order. +We also erase the binder kinds (e.g. implicit/explicit) in the type, +and we erase all universe levels, both of which help to find more duplicates. + +To avoid flagging aliases as duplicate (which are most likely intentionally duplicated), +we filter out declarations that are defined as another declaration (see `isAlias`). + +The results are sorted by module name. +-/ + +meta section + +namespace Mathlib.Tactic.DuplicateDecls +open Lean Meta + +/-- Clear all universe levels from an expression, so that they are ignored. -/ +-- Note: I tried using a cache in the implementation, but that seemed to only slow things down. +partial def eraseUnivs (e : Expr) : Expr := + match e with + | .sort _ => .sort 0 + | .const declName _ => .const declName [] + | .app fn arg => e.updateApp! (eraseUnivs fn) (eraseUnivs arg) + | .lam _ t b _ => e.updateLambdaE! (eraseUnivs t) (eraseUnivs b) + | .forallE _ t b _ => e.updateForallE! (eraseUnivs t) (eraseUnivs b) + | .letE _ t v b _ => e.updateLetE! (eraseUnivs t) (eraseUnivs v) (eraseUnivs b) + | .mdata _ expr => e.updateMData! (eraseUnivs expr) + | .proj _ _ s => e.updateProj! (eraseUnivs s) + | e => e + +/-- Sort the hypotheses in `e` into a normalized order by sorting their types. +Also replace universe levels with a default value. + +TODO: When there are multiple variables of the same type, their order will not be changed. +This is a limitation of the current approach. -/ +def sortBinders (e : Expr) : MetaM Expr := do + (if e.isLambda then lambdaTelescope else forallTelescope) e fun fvars e ↦ do + let n := fvars.size + let fvars : Vector Expr n := fvars.toVector + let mut remainingTypes ← fvars.mapM (return some <| eraseUnivs <| ← inferType ·) + let mut e := eraseUnivs e + let mut sortedTypes := #[] + for _ in *...n do + let mut minType? : Option (Fin n × Expr) := none + for h : i in 0...n do + if let some type := remainingTypes[i] then + if !type.hasFVar then + if let some (minIdx, minType) := minType? then + if type.quickLt minType then + continue + minType? := some (⟨i, by get_elem_tactic⟩, type) + let some (minIdx, minType) := minType? | + panic! s!"All types have fvars: {remainingTypes.toArray}" + sortedTypes := sortedTypes.push minType + remainingTypes := remainingTypes.set minIdx none + let abstractFVar (e : Expr) := (e.liftLooseBVars 0 1).abstract #[fvars[minIdx]] + remainingTypes := remainingTypes.map (·.map abstractFVar) + e := abstractFVar e + return sortedTypes.foldr (init := e) fun type e ↦ .forallE `_ type e .default + +/-- Return `true` if `cinfo` is defined as another constant. +If so, we assume that the declaration is intentionally duplicated. +This only works for exposed definitions. -/ +def isAlias (cinfo : ConstantInfo) : Bool := + (cinfo.value? (allowOpaque := true)).any isConstBVarApp +where + isConstBVarApp : Expr → Bool + | .const .. => true + | .app f (.bvar _) => isConstBVarApp f + | .lam _ _ b _ => isConstBVarApp b + | _ => false + +/-- An inductive type for the kind of duplicate declarations to search for. -/ +public inductive Target where + /-- Search for duplicate theorems. -/ + | theorems + /-- Search for duplicate instances that aren't theorems. -/ + | instances + /-- Search for duplicate definitions that aren't instances or theorems, + Also indexes on the value, not just the type. -/ + | defs + +/-- Compute an array of duplicate declarations in the current environment. -/ +def duplicateDeclarations (cfg : Target) : CoreM (Array (Array Name)) := MetaM.run' do + let env ← getEnv + let mut visited : Std.HashMap Expr Name := {} + let mut dups : Std.HashMap Expr (Array Name) := {} + for (name, cinfo) in env.constants.map₁ do + if name.isInternalDetail + || name.isMetaprogramming + || !allowCompletion env name + || Linter.isDeprecated env name + || isAlias cinfo then continue + if ← isProp cinfo.type then + unless cfg matches .theorems do continue + else + match cfg with + | .theorems => continue + | .instances => if (← isClass? cinfo.type).isNone then continue + | .defs => + if (← isClass? cinfo.type).isNone then + if let some value := cinfo.value? then + let normValue ← sortBinders value + let normType ← sortBinders cinfo.type + let key := .app normValue normType + if let some name' := visited[key]? then + dups := dups.alter key (·.getD #[name'] |>.push name) + else + visited := visited.insert key name + continue + let normType ← sortBinders cinfo.type + if let some name' := visited[normType]? then + dups := dups.alter normType (·.getD #[name'] |>.push name) + else + visited := visited.insert normType name + return dups.valuesArray + +/-- Given a module name, return a number that can be used for sorting. -/ +def libraryNumber (module : Name) : Nat := + #[`Init, `Std, `Lean, `Batteries, `Mathlib].idxOf module.getRoot + +/-- Structure used for sorting imported modules: +1. The number given by `libraryNumber`. +2. The name of the module as a string. +-/ +def ModuleKey := Nat × String + deriving Inhabited + +instance : Ord ModuleKey := ⟨fun a b ↦ (compare a.1 b.1).then (compare a.2 b.2)⟩ +instance : LT ModuleKey := ltOfOrd +instance : LE ModuleKey := leOfOrd +instance : Max ModuleKey := maxOfLe + +/-- Return the object by which to sort the module that `name` is from. +That is, the `libraryNumber` followed by the module as a string. -/ +def mkModuleKey! (name : Name) (env : Environment) : ModuleKey := + let mod := (env.getModuleFor? name).get! + (libraryNumber mod, mod.toString) + +/-- Return the list of duplicate declarations, grouped by the name of the module +with the biggest `ModuleKey`. -/ +def sortedDuplicateDeclarations (cfg : Target) : + CoreM (Array (String × Array (Array Name))) := do + let env ← getEnv + let dups ← duplicateDeclarations cfg + let mut result : Std.TreeMap ModuleKey (Array (Array Name)) := {} + for names in dups do + let moduleKey := names.map (mkModuleKey! · env) |>.max?.get! + result := result.alter moduleKey (·.getD #[] |>.push (names.qsort Name.lt)) + return result.toArray.map fun (a, dups) ↦ (a.2, dups) + +/-- The duplicate declarations linter. It tells you which duplicate declarations there are +in the current environment. -/ +public def lintDuplicateDeclarations (tgt : Target) : CoreM MessageData := do + if (← getEnv).header.isModule then + throwError "In order to detect aliases, this function should be run in a non-module" + let dups ← sortedDuplicateDeclarations tgt + let mut msg := m!"Number of duplicates: {dups.foldl (init := 0) (· + ·.2.size)}" + for (module, dups) in dups do + msg := msg ++ s!"\n\n-- {module}" + for names in dups do + msg := msg ++ "\n" + for name in names do + msg := msg ++ m!"\n{.ofConstName name} : {(← getConstInfo name).type}" + return msg + +end Mathlib.Tactic.DuplicateDecls diff --git a/MathlibTest/Tactic/DuplicateDecls.lean b/MathlibTest/Tactic/DuplicateDecls.lean new file mode 100644 index 00000000000000..74e8241335f3d5 --- /dev/null +++ b/MathlibTest/Tactic/DuplicateDecls.lean @@ -0,0 +1,40 @@ +import MathlibTest.Tactic.DuplicateDeclsAux + +open Lean Mathlib.Tactic.DuplicateDecls + +/-- +-- MathlibTest.Tactic.DuplicateDeclsAux + +int_nat_add_comm : ∀ (m : Int) (n : Nat), ↑n + m = m + ↑n +nat_int_add_comm : ∀ (n : Nat) (m : Int), ↑n + m = m + ↑n + +Eq.trans : ∀ {α : Sort u} {a b c : α}, a = b → b = c → a = c +Eq.trans_Type : ∀ {α : Type u} {a b c : α}, a = b → b = c → a = c + +of_one_add_one_of_two_add_two : 1 + 1 = 2 → 2 + 2 = 4 → True +of_two_add_two_of_one_add_one : 2 + 2 = 4 → 1 + 1 = 2 → True + +one_add_one : 1 + 1 = 2 +one_add_one' : 1 + 1 = 2 +-/ +#guard_msgs (substring := true) in +run_meta do logInfo m!"{← lintDuplicateDeclarations .theorems}" + +/-- +-- MathlibTest.Tactic.DuplicateDeclsAux + +instAddNat : Add Nat +instAddNat' : Add Nat +instAddNat'' : Add Nat +-/ +#guard_msgs (substring := true) in +run_meta do logInfo m!"{← lintDuplicateDeclarations .instances}" + +/-- +-- MathlibTest.Tactic.DuplicateDeclsAux + +addTen : Nat → Nat +addTen' : Nat → Nat +-/ +#guard_msgs (substring := true) in +run_meta do logInfo m!"{← lintDuplicateDeclarations .defs}" diff --git a/MathlibTest/Tactic/DuplicateDeclsAux.lean b/MathlibTest/Tactic/DuplicateDeclsAux.lean new file mode 100644 index 00000000000000..9cb9fd8b3a7c6e --- /dev/null +++ b/MathlibTest/Tactic/DuplicateDeclsAux.lean @@ -0,0 +1,36 @@ +import Mathlib.Tactic.DuplicateDecls + +/-! Theorems-/ + +theorem one_add_one : 1 + 1 = 2 := rfl +theorem one_add_one' : 1 + 1 = 2 := rfl +theorem one_add_one_alias : 1 + 1 = 2 := one_add_one -- this is an alias, so it won't be flagged + +theorem of_one_add_one_of_two_add_two : 1 + 1 = 2 → 2 + 2 = 4 → True := by simp +theorem of_two_add_two_of_one_add_one : 2 + 2 = 4 → 1 + 1 = 2 → True := by simp + +theorem nat_int_add_comm (n : Nat) (m : Int) : n + m = m + n := by rw [Int.add_comm] +theorem int_nat_add_comm (m : Int) (n : Nat) : n + m = m + n := by rw [Int.add_comm] + +theorem Eq.trans_Type {α : Type u} {a b c : α} (h₁ : Eq a b) (h₂ : Eq b c) : Eq a c := + h₂ ▸ h₁ + +-- The following duplicates are not detected because of variables with the same type +theorem nat_add_comm (n m : Nat) : n + m = m + n := Nat.add_comm n m +theorem nat_add_comm' (m n : Nat) : n + m = m + n := by grind + +theorem nat_le_trans (a b c : Nat) : a ≤ b → b ≤ c → a ≤ c := Nat.le_trans +theorem nat_ge_trans (a b c : Nat) : b ≤ a → c ≤ b → c ≤ a := by lia + +/-! Instances -/ +-- The value is not looked at, because instances are meant to be canonical. +-- We check whether a definition is an instance based on its type. We might want to change this. +@[implicit_reducible] def instAddNat' : Add Nat := ⟨Nat.sub⟩ +@[implicit_reducible] def instAddNat'' : Add Nat := ⟨Nat.mul⟩ + +/-! Definitions -/ + +-- For definitions that are not instances, we look at both the type and the value. +def addTen (n : Nat) := n + 10 +def addTen' (n : Nat) := n + 10 +def addTwenty (n : Nat) := n + 20 From 69b866d83ad1b8b66cedabff77dec8d9d20e1c03 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 8 Jul 2026 19:11:32 +0000 Subject: [PATCH 0693/1300] perf: make `Equiv` transfer instances more reduced (#41002) This pr speeds up the instances that are tranferred through `Equiv`s by using the projections `.toFun` and `.invFun` directly in the data. I think that we should eventually deprecate these instances, and instead have a metaprogram that creates these instances for us in each use case. --- Mathlib/Algebra/Algebra/TransferInstance.lean | 3 ++- Mathlib/Algebra/Category/MonCat/Limits.lean | 3 +-- Mathlib/Algebra/Field/TransferInstance.lean | 5 ++-- Mathlib/Algebra/Group/TransferInstance.lean | 23 +++++++++++++++---- Mathlib/Algebra/Ring/TransferInstance.lean | 7 +++--- Mathlib/Algebra/Star/TransferInstance.lean | 3 ++- Mathlib/RingTheory/PicardGroup.lean | 4 ++-- .../Algebra/Module/TransferInstance.lean | 2 +- .../Topology/Homeomorph/TransferInstance.lean | 6 +++-- .../MetricSpace/TransferInstance.lean | 7 +++--- 10 files changed, 41 insertions(+), 22 deletions(-) diff --git a/Mathlib/Algebra/Algebra/TransferInstance.lean b/Mathlib/Algebra/Algebra/TransferInstance.lean index adf5cbca9a0082..a8cac28844af75 100644 --- a/Mathlib/Algebra/Algebra/TransferInstance.lean +++ b/Mathlib/Algebra/Algebra/TransferInstance.lean @@ -22,6 +22,7 @@ variable {R α β : Type*} [CommSemiring R] namespace Equiv variable (e : α ≃ β) +-- See note [instance transfer via equivalence] variable (R) in /-- Transfer `Algebra` across an `Equiv` -/ protected abbrev algebra (e : α ≃ β) [Semiring β] : @@ -30,7 +31,7 @@ protected abbrev algebra (e : α ≃ β) [Semiring β] : letI := Equiv.semiring e letI := e.smul R { algebraMap := - { toFun r := e.symm (algebraMap R β r) + { toFun r := e.invFun (algebraMap R β r) __ := e.ringEquiv.symm.toRingHom.comp (algebraMap R β) } commutes' r x := show e.symm ((e (e.symm (algebraMap R β r)) * e x)) = diff --git a/Mathlib/Algebra/Category/MonCat/Limits.lean b/Mathlib/Algebra/Category/MonCat/Limits.lean index df7a30769f7586..a567874386d21b 100644 --- a/Mathlib/Algebra/Category/MonCat/Limits.lean +++ b/Mathlib/Algebra/Category/MonCat/Limits.lean @@ -180,8 +180,7 @@ noncomputable instance forget_createsLimit : simp only [Types.Small.limitCone_pt, Functor.comp_obj, Functor.mapCone_pt, Types.Small.limitConeIsLimit_lift, Functor.const_obj_obj, Functor.mapCone_π_app, ConcreteCategory.hom_ofHom, TypeCat.Fun.coe_mk, map_mul] - congr - simp only [Functor.comp_obj, Equiv.symm_apply_apply] + rw [← equivShrink_mul] rfl · exact fun _ ↦ rfl diff --git a/Mathlib/Algebra/Field/TransferInstance.lean b/Mathlib/Algebra/Field/TransferInstance.lean index 37f6c86000b5af..9c6cabd24aae40 100644 --- a/Mathlib/Algebra/Field/TransferInstance.lean +++ b/Mathlib/Algebra/Field/TransferInstance.lean @@ -21,11 +21,12 @@ assert_not_exists Module namespace Equiv variable {α β : Type*} (e : α ≃ β) +-- See note [instance transfer via equivalence] /-- Transfer `NNRatCast` across an `Equiv` -/ -protected abbrev nnratCast [NNRatCast β] : NNRatCast α where nnratCast q := e.symm q +protected abbrev nnratCast [NNRatCast β] : NNRatCast α where nnratCast q := e.invFun q /-- Transfer `RatCast` across an `Equiv` -/ -protected abbrev ratCast [RatCast β] : RatCast α where ratCast n := e.symm n +protected abbrev ratCast [RatCast β] : RatCast α where ratCast n := e.invFun n /-- Transfer `DivisionRing` across an `Equiv` -/ protected abbrev divisionRing [DivisionRing β] : DivisionRing α := by diff --git a/Mathlib/Algebra/Group/TransferInstance.lean b/Mathlib/Algebra/Group/TransferInstance.lean index 41a945e1b28f44..023e3826f2583a 100644 --- a/Mathlib/Algebra/Group/TransferInstance.lean +++ b/Mathlib/Algebra/Group/TransferInstance.lean @@ -25,12 +25,25 @@ When adding new definitions that transfer type-classes across an equivalence, pl assert_not_exists MonoidWithZero MulAction +library_note «instance transfer via equivalence» /-- +For many type classes, we have a definition that lets us transfer instances from one type to another +using an equivalence, such as `Equiv.mul` for `Mul`. +Constructing data instances in this way is discouraged because the resulting data is inefficient +to unfold. To somewhat mitigate this problem, in these definitions we don't write the +projections on `Equiv` in the usual way using `Equiv.symm` and `DFunLike.coe`, and instead use +`Equiv.toFun` and `Equiv.invFun` directly. As a result, unification has to do less unfolding. + +Note also that when constructing data instances in this way, it usually helps to use +`fast_instance%` to get a faster instance. +-/ + namespace Equiv variable {M α β : Type*} (e : α ≃ β) +-- See note [instance transfer via equivalence] /-- Transfer `One` across an `Equiv` -/ @[to_additive /-- Transfer `Zero` across an `Equiv` -/] -protected abbrev one [One β] : One α where one := e.symm 1 +protected abbrev one [One β] : One α where one := e.invFun 1 @[to_additive] lemma one_def [One β] : @@ -39,7 +52,7 @@ lemma one_def [One β] : /-- Transfer `Mul` across an `Equiv` -/ @[to_additive /-- Transfer `Add` across an `Equiv` -/] -protected abbrev mul [Mul β] : Mul α where mul x y := e.symm (e x * e y) +protected abbrev mul [Mul β] : Mul α where mul x y := e.invFun (e.toFun x * e.toFun y) @[to_additive] lemma mul_def [Mul β] (x y : α) : @@ -49,7 +62,7 @@ lemma mul_def [Mul β] (x y : α) : /-- Transfer `Div` across an `Equiv` -/ @[to_additive /-- Transfer `Sub` across an `Equiv` -/] protected abbrev div [Div β] : Div α := - ⟨fun x y => e.symm (e x / e y)⟩ + ⟨fun x y => e.invFun (e.toFun x / e.toFun y)⟩ @[to_additive] lemma div_def [Div β] (x y : α) : @@ -60,7 +73,7 @@ lemma div_def [Div β] (x y : α) : -- but we already have an `Equiv.inv` (which perhaps should move to `Perm.inv`?) /-- Transfer `Inv` across an `Equiv` -/ @[to_additive /-- Transfer `Neg` across an `Equiv` -/] -protected abbrev Inv [Inv β] : Inv α where inv x := e.symm (e x)⁻¹ +protected abbrev Inv [Inv β] : Inv α where inv x := e.invFun (e.toFun x)⁻¹ @[to_additive] lemma inv_def [Inv β] (x : α) : @@ -71,7 +84,7 @@ variable (M) in /-- Transfer `Pow` across an `Equiv` -/ @[to_additive (attr := to_additive /-- Transfer `VAdd` across an `Equiv` -/) smul /-- Transfer `SMul` across an `Equiv` -/] -protected abbrev pow [Pow β M] : Pow α M where pow x n := e.symm (e x ^ n) +protected abbrev pow [Pow β M] : Pow α M where pow x n := e.invFun (e.toFun x ^ n) @[to_additive (attr := to_additive) smul_def] lemma pow_def [Pow β M] (n : M) (x : α) : diff --git a/Mathlib/Algebra/Ring/TransferInstance.lean b/Mathlib/Algebra/Ring/TransferInstance.lean index dd9da001db04e6..3d5e4988fd0d73 100644 --- a/Mathlib/Algebra/Ring/TransferInstance.lean +++ b/Mathlib/Algebra/Ring/TransferInstance.lean @@ -64,10 +64,11 @@ protected abbrev nonUnitalSemiring [NonUnitalSemiring β] : NonUnitalSemiring α let nsmul := e.smul ℕ apply e.injective.nonUnitalSemiring _ <;> intros <;> exact e.apply_symm_apply _ +-- See note [instance transfer via equivalence] /-- Transfer `AddMonoidWithOne` across an `Equiv` -/ protected abbrev addMonoidWithOne [AddMonoidWithOne β] : AddMonoidWithOne α := { e.addMonoid, e.one with - natCast := fun n => e.symm n + natCast := fun n => e.invFun n natCast_zero := e.injective (by simp [zero_def]) natCast_succ := fun n => e.injective (by simp [add_def, one_def]) } @@ -75,10 +76,10 @@ protected abbrev addMonoidWithOne [AddMonoidWithOne β] : AddMonoidWithOne α := protected abbrev addGroupWithOne [AddGroupWithOne β] : AddGroupWithOne α := { e.addMonoidWithOne, e.addGroup with - intCast := fun n => e.symm n + intCast := fun n => e.invFun n intCast_ofNat := fun n => by simp only [Int.cast_natCast]; rfl intCast_negSucc := fun _ => - congr_arg e.symm <| (Int.cast_negSucc _).trans <| congr_arg _ (e.apply_symm_apply _).symm } + congr_arg e.invFun <| (Int.cast_negSucc _).trans <| congr_arg _ (e.apply_symm_apply _).symm } /-- Transfer `NonAssocSemiring` across an `Equiv` -/ protected abbrev nonAssocSemiring [NonAssocSemiring β] : NonAssocSemiring α := by diff --git a/Mathlib/Algebra/Star/TransferInstance.lean b/Mathlib/Algebra/Star/TransferInstance.lean index 0d7ca79277f689..594774ad56dc8b 100644 --- a/Mathlib/Algebra/Star/TransferInstance.lean +++ b/Mathlib/Algebra/Star/TransferInstance.lean @@ -21,11 +21,12 @@ namespace Equiv variable (e : R ≃ S) +-- See note [instance transfer via equivalence] /-- Transfer `Star` across an `Equiv`. See note [reducible non-instances]. For `star : R → R` bundled as an `Equiv`, see `Equiv.Perm.star`. -/ protected abbrev star [Star S] : Star R where - star r := e.symm (star (e r)) + star r := e.invFun (star (e.toFun r)) /-- Transfer `InvolutiveStar` across an `Equiv`. See note [reducible non-instances]. -/ protected abbrev involutiveStar [InvolutiveStar S] : InvolutiveStar R := diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 680783fa988a5f..9c22008a85eba4 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -472,14 +472,14 @@ instance : Free R (1 : Pic R) := mk_eq_one_iff_free.mp mk_eq_self theorem mk_tensor : Pic.mk R (M ⊗[R] N) = Pic.mk R M * Pic.mk R N := congr_arg (equivShrink _) <| Units.ext <| by - simp_rw [Pic.mk, Equiv.symm_apply_apply] + simp_rw [Pic.mk, Equiv.toFun_as_coe, Equiv.symm_apply_apply] refine (Quotient.sound ?_).trans (Skeleton.toSkeleton_tensorObj ..) exact ⟨(Finite.reprEquivₛ R _ ≪≫ₗ TensorProduct.congr (Finite.reprEquivₛ R M).symm (Finite.reprEquivₛ R N).symm).toModuleIsoₛ⟩ theorem mk_dual : Pic.mk R (Dual R M) = (Pic.mk R M)⁻¹ := congr_arg (equivShrink _) <| Units.ext <| by - rw [Pic.mk, Equiv.symm_apply_apply] + rw [Pic.mk, Equiv.toFun_as_coe, Equiv.symm_apply_apply] exact Quotient.sound ⟨(Finite.reprEquivₛ R _ ≪≫ₗ (Finite.reprEquivₛ R _).dualMap).toModuleIsoₛ⟩ theorem inv_eq_dual (M : Pic R) : M⁻¹ = Pic.mk R (Dual R M) := by diff --git a/Mathlib/Topology/Algebra/Module/TransferInstance.lean b/Mathlib/Topology/Algebra/Module/TransferInstance.lean index 619bc36a6f0531..4e1f9e606f6404 100644 --- a/Mathlib/Topology/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Topology/Algebra/Module/TransferInstance.lean @@ -50,7 +50,7 @@ def continuousLinearEquiv (e : α ≃ β) : { toLinearEquiv := e.linearEquiv _ continuous_toFun := continuous_induced_dom continuous_invFun := by - simp +instances only [Equiv.topologicalSpace, ← @coinduced_symm] + simp +instances only [Equiv.topologicalSpace, toFun_as_coe, ← coinduced_symm] exact continuous_coinduced_rng } @[simp] diff --git a/Mathlib/Topology/Homeomorph/TransferInstance.lean b/Mathlib/Topology/Homeomorph/TransferInstance.lean index 565e9c1044c042..f1aef1efc4aa1d 100644 --- a/Mathlib/Topology/Homeomorph/TransferInstance.lean +++ b/Mathlib/Topology/Homeomorph/TransferInstance.lean @@ -21,10 +21,11 @@ variable {R α β : Type*} namespace Equiv +-- See note [instance transfer via equivalence] /-- Transfer a `TopologicalSpace` across an `Equiv` -/ protected abbrev topologicalSpace [TopologicalSpace β] (e : α ≃ β) : TopologicalSpace α := - .induced e ‹_› + .induced e.toFun ‹_› /-- An equivalence `e : α ≃ β` gives a homeomorphism `α ≃ₜ β` where the topological space structure on `α` is the one obtained by transporting the topological space structure on `β` back along `e`. -/ @@ -37,6 +38,7 @@ def homeomorph [TopologicalSpace β] (e : α ≃ β) : continuous_invFun := by simp only [Equiv.invFun_as_coe] convert! continuous_coinduced_rng - rw [e.coinduced_symm] } + rw [e.coinduced_symm] + rfl } end Equiv diff --git a/Mathlib/Topology/MetricSpace/TransferInstance.lean b/Mathlib/Topology/MetricSpace/TransferInstance.lean index 5e363372b2c829..9058726a3784a2 100644 --- a/Mathlib/Topology/MetricSpace/TransferInstance.lean +++ b/Mathlib/Topology/MetricSpace/TransferInstance.lean @@ -22,15 +22,16 @@ namespace Equiv variable (e : α ≃ β) +-- See note [instance transfer via equivalence] /-- Transfer a `Dist` across an `Equiv` -/ -protected abbrev dist (e : α ≃ β) [Dist β] : Dist α := ⟨fun x y ↦ dist (e x) (e y)⟩ +protected abbrev dist (e : α ≃ β) [Dist β] : Dist α := ⟨fun x y ↦ dist (e.toFun x) (e.toFun y)⟩ /-- Transfer a `PseudoMetricSpace` across an `Equiv` -/ protected abbrev pseudometricSpace [PseudoMetricSpace β] (e : α ≃ β) : PseudoMetricSpace α := - .induced e ‹_› + .induced e.toFun ‹_› /-- Transfer a `MetricSpace` across an `Equiv` -/ protected abbrev metricSpace [MetricSpace β] (e : α ≃ β) : MetricSpace α := - .induced e e.injective ‹_› + .induced e.toFun e.injective ‹_› end Equiv From 80ffd59621338133f22d4d6403537540e78aa68b Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 8 Jul 2026 23:38:00 +0000 Subject: [PATCH 0694/1300] perf(Translate): use cache in `guessReorder` (#41516) This PR fixes a performance issue in `to_additive`/`to_dual`. The `guessReorder` function did not use a cache, meaning that it would visit the same expressions multiple times unnecessarily. --- Mathlib/Tactic/Translate/Core.lean | 6 +++- Mathlib/Tactic/Translate/Reorder.lean | 52 ++++++++++++++------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index e68ca740cfa9cd..01dc430c3cb060 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -956,6 +956,8 @@ where Also try to autogenerate the `reorder` and `relevant_arg` options for this translation. -/ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config) (lint := true) : MetaM (Reorder × RelevantArg) := withoutExporting do + withTraceNode `translate_detail (fun _ => + return m!"checking translation `{.ofConstName src}` → `{.ofConstName tgt}`") do let srcDecl ← getConstInfo src let tgtDecl ← getConstInfo tgt unless srcDecl.numLevelParams == tgtDecl.numLevelParams do @@ -967,7 +969,9 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config srcType ← b.insertBoundaries srcType t.attrName let (srcType', relevantArg?) ← applyReplacementForall t cfg.dontTranslate srcType srcType := srcType' - let reorder' ← guessReorder srcType tgtDecl.type + let reorder' ← withTraceNode `translate_detail (fun _ => + return m!"guessing the reorder between `{srcType}` and `{tgtDecl.type}`") do + guessReorder srcType tgtDecl.type trace[translate_detail] "The guessed reorder is {reorder'}" let reorder ← if let some reorder := cfg.reorder? then diff --git a/Mathlib/Tactic/Translate/Reorder.lean b/Mathlib/Tactic/Translate/Reorder.lean index 6c5e03c1b0a4a8..185afe8d94720a 100644 --- a/Mathlib/Tactic/Translate/Reorder.lean +++ b/Mathlib/Tactic/Translate/Reorder.lean @@ -274,7 +274,8 @@ partial def guessReorder (src tgt : Expr) : MetaM ArgReorder := withReducible do forallBoundedTelescope tgt depth fun tgtVars tgt ↦ do let srcMap : Std.HashMap FVarId Nat := .ofArray <| srcVars.mapIdx fun i x => (x.fvarId!, i) let tgtMap : Std.HashMap FVarId Nat := .ofArray <| tgtVars.mapIdx fun i x => (x.fvarId!, i) - let perm := (visit src tgt (.replicate depth none) (srcMap, tgtMap)).elim [] decomposePerm + let perm := (← visit src tgt (.replicate depth none) |>.run (srcMap, tgtMap) |>.run' {} |>.run) + |>.elim [] decomposePerm -- Recursively guess the reorder in the hypotheses let mut argReorders := #[] for i in *...depth do @@ -296,30 +297,33 @@ where /-- Determine for each `i : Fin n` to what `j : Fin n` it should get translated. -/ visit (src tgt : Expr) {n : Nat} (map : Vector (Option (Fin n)) n) : ReaderT (Std.HashMap FVarId Nat × Std.HashMap FVarId Nat) - Option (Vector (Option (Fin n)) n) := do - match src, tgt with - | .forallE _ d₁ b₁ _, .forallE _ d₂ b₂ _ => visit d₁ d₂ map >>= visit b₁ b₂ - | .lam _ d₁ b₁ _ , .lam _ d₂ b₂ _ => visit d₁ d₂ map >>= visit b₁ b₂ - | .mdata _ e₁ , .mdata _ e₂ => visit e₁ e₂ map - | .letE _ t₁ v₁ b₁ _, .letE _ t₂ v₂ b₂ _ => visit t₁ t₂ map >>= visit v₁ v₂ >>= visit b₁ b₂ - | .app f₁ a₁ , .app f₂ a₂ => visit f₁ f₂ map >>= visit a₁ a₂ - | .proj _ _ e₁ , .proj _ _ e₂ => visit e₁ e₂ map - | .fvar fvarId₁ , .fvar fvarId₂ => - let some i₁ := (← read).1[fvarId₁]? | some map - let some i₂ := (← read).2[fvarId₂]? | some map - if h : i₂ < n then - if let some i₂' := map[i₁]! then - guard (i₂ == i₂') -- If `i₂ ≠ i₂'`, it's not clear what `i₁` should be translated to. - some map + StateRefT (Std.HashSet (Expr × Expr)) (OptionT BaseIO) (Vector (Option (Fin n)) n) := do + if (← get).contains (src, tgt) then return map + let map ← match src, tgt with + | .forallE _ d₁ b₁ _, .forallE _ d₂ b₂ _ => visit d₁ d₂ map >>= visit b₁ b₂ + | .lam _ d₁ b₁ _ , .lam _ d₂ b₂ _ => visit d₁ d₂ map >>= visit b₁ b₂ + | .mdata _ e₁ , .mdata _ e₂ => visit e₁ e₂ map + | .letE _ t₁ v₁ b₁ _, .letE _ t₂ v₂ b₂ _ => visit t₁ t₂ map >>= visit v₁ v₂ >>= visit b₁ b₂ + | .app f₁ a₁ , .app f₂ a₂ => visit f₁ f₂ map >>= visit a₁ a₂ + | .proj _ _ e₁ , .proj _ _ e₂ => visit e₁ e₂ map + | .fvar fvarId₁ , .fvar fvarId₂ => + let some i₁ := (← read).1[fvarId₁]? | pure map + let some i₂ := (← read).2[fvarId₂]? | pure map + if h : i₂ < n then + if let some i₂' := map[i₁]! then + guard (i₂ == i₂') -- If `i₂ ≠ i₂'`, it's not clear what `i₁` should be translated to. + pure map + else + pure <| map.set! i₁ (some ⟨i₂, h⟩) else - some <| map.set! i₁ (some ⟨i₂, h⟩) - else - panic! s!"index {i₂} is out of bounds ({n})" - /- To avoid false positives, we do a sanity check to make sure that the two expressions are - indeed of the same shape. Note that we cannot check for `e₁ == e₁`, because the universes - in `e₁` and `e₂` might be different (because we decide only later whether to swap them). -/ - | .lit _, .lit _ | .bvar _, .bvar _ | .sort _, .sort _ | .const .., .const .. => some map - | _, _ => none + panic! s!"index {i₂} is out of bounds ({n})" + /- To avoid false positives, we do a sanity check to make sure that the two expressions are + indeed of the same shape. Note that we cannot check for `e₁ == e₁`, because the universes + in `e₁` and `e₂` might be different (because we decide only later whether to swap them). -/ + | .lit _, .lit _ | .bvar _, .bvar _ | .sort _, .sort _ | .const .., .const .. => pure map + | _, _ => failure + modify (·.insert (src, tgt)) + return map /-! ### Syntax for specifying a reorder -/ From fc5bfc7b00c1d18429a2dfa00148de8b67f97dbf Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Thu, 9 Jul 2026 03:55:44 +0000 Subject: [PATCH 0695/1300] chore(Geometry/Manifold/Submersion): reword 'project intentions' phrase (#41500) As suggested privately by `kim-em`; the current phrasing reads nicer and conveys what the original phrasing meant to say. --- Mathlib/Geometry/Manifold/Submersion.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Submersion.lean b/Mathlib/Geometry/Manifold/Submersion.lean index 95d305ffd1405f..6a821bd6ad7f7b 100644 --- a/Mathlib/Geometry/Manifold/Submersion.lean +++ b/Mathlib/Geometry/Manifold/Submersion.lean @@ -83,8 +83,8 @@ The implementation strategy is identical to the one for immersions. See the impl [schmeding2023] * Note that Margelef-Roig and Dominguez have a slightly different definition of submersions. -**Please do not work** on this file without prior discussion with Michael Rothgang. -This will be the topic of Samantha Naranjo's master's thesis, and it's nice to coordinate. +**Please talk** to Michael Rothgang before working on this file, to avoid duplicate work. +The above TODOs are the topic of Samantha Naranjo's master's thesis; it's nicer to coordinate. -/ From ae861491c1fcc958a370f204124d522a3f7b0de9 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Thu, 9 Jul 2026 05:55:31 +0000 Subject: [PATCH 0696/1300] feat(Analysis): use `Is*Apply` for `Seminorm` (#40880) --- .../SeminormLatticeNotDistrib.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 75 ++++++++----------- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/Counterexamples/SeminormLatticeNotDistrib.lean b/Counterexamples/SeminormLatticeNotDistrib.lean index 74412734856351..536a6c30ea007a 100644 --- a/Counterexamples/SeminormLatticeNotDistrib.lean +++ b/Counterexamples/SeminormLatticeNotDistrib.lean @@ -41,7 +41,7 @@ noncomputable def q2 : Seminorm ℝ (ℝ × ℝ) := theorem eq_one : (p ⊔ q1 ⊓ q2) (1, 1) = 1 := by suffices ⨅ x : ℝ × ℝ, q1 x + q2 (1 - x) ≤ 1 by simpa apply ciInf_le_of_le bddBelow_range_add ((0, 1) : ℝ × ℝ); dsimp [q1, q2] - simp only [abs_zero, smul_zero, sub_self, add_zero, zero_le_one] + simp /-- This is a counterexample to the distributivity of the lattice `Seminorm ℝ (ℝ × ℝ)`. -/ theorem not_distrib : ¬(p ⊔ q1) ⊓ (p ⊔ q2) ≤ p ⊔ q1 ⊓ q2 := by diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index 0a455fc7dc5380..d306b69cbbf6ce 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -133,13 +133,12 @@ instance instZero : Zero (Seminorm 𝕜 E) := ⟨{ AddGroupSeminorm.instZeroAddGroupSeminorm.zero with smul' := fun _ _ => (mul_zero _).symm }⟩ -@[simp] -theorem coe_zero : ⇑(0 : Seminorm 𝕜 E) = 0 := - rfl +instance : IsZeroApply (Seminorm 𝕜 E) E ℝ where + zero_apply _ := rfl -@[simp] -theorem zero_apply (x : E) : (0 : Seminorm 𝕜 E) x = 0 := - rfl +@[deprecated (since := "2026-06-22")] alias coe_zero := FunLike.coe_zero + +@[deprecated (since := "2026-06-22")] protected alias zero_apply := zero_apply instance : Inhabited (Seminorm 𝕜 E) := ⟨0⟩ @@ -155,19 +154,16 @@ instance instSMul [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] : simp only [← smul_one_smul ℝ≥0 r (_ : ℝ), NNReal.smul_def, smul_eq_mul] rw [map_smul_eq_mul, mul_left_comm] } +instance [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] : IsSMulApply R (Seminorm 𝕜 E) E ℝ where + smul_apply _ _ _ := rfl + instance [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] [SMul R' ℝ] [SMul R' ℝ≥0] [IsScalarTower R' ℝ≥0 ℝ] [SMul R R'] [IsScalarTower R R' ℝ] : - IsScalarTower R R' (Seminorm 𝕜 E) where - smul_assoc r a p := ext fun x => smul_assoc r a (p x) + IsScalarTower R R' (Seminorm 𝕜 E) := FunLike.isScalarTower -theorem coe_smul [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] (r : R) (p : Seminorm 𝕜 E) : - ⇑(r • p) = r • ⇑p := - rfl +@[deprecated (since := "2026-06-22")] alias coe_smul := FunLike.coe_smul -@[simp] -theorem smul_apply [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] (r : R) (p : Seminorm 𝕜 E) - (x : E) : (r • p) x = r • p x := - rfl +@[deprecated (since := "2026-06-22")] protected alias smul_apply := smul_apply instance instAdd : Add (Seminorm 𝕜 E) where add p q := @@ -175,50 +171,43 @@ instance instAdd : Add (Seminorm 𝕜 E) where toFun := fun x => p x + q x smul' := fun a x => by simp only [map_smul_eq_mul, map_smul_eq_mul, mul_add] } -theorem coe_add (p q : Seminorm 𝕜 E) : ⇑(p + q) = p + q := - rfl +instance : IsAddApply (Seminorm 𝕜 E) E ℝ where + add_apply _ _ _ := rfl -@[simp] -theorem add_apply (p q : Seminorm 𝕜 E) (x : E) : (p + q) x = p x + q x := - rfl +@[deprecated (since := "2026-06-22")] alias coe_add := FunLike.coe_add -instance instAddMonoid : AddMonoid (Seminorm 𝕜 E) := - DFunLike.coe_injective.addMonoid _ rfl coe_add fun _ _ => by rfl +@[deprecated (since := "2026-06-22")] protected alias add_apply := add_apply -instance instAddCommMonoid : AddCommMonoid (Seminorm 𝕜 E) := - DFunLike.coe_injective.addCommMonoid _ rfl coe_add fun _ _ => by rfl +instance instAddMonoid : AddMonoid (Seminorm 𝕜 E) := fast_instance% FunLike.addMonoid + +instance instAddCommMonoid : AddCommMonoid (Seminorm 𝕜 E) := fast_instance% FunLike.addCommMonoid instance instPartialOrder : PartialOrder (Seminorm 𝕜 E) := PartialOrder.lift _ DFunLike.coe_injective instance instIsOrderedCancelAddMonoid : IsOrderedCancelAddMonoid (Seminorm 𝕜 E) := - Function.Injective.isOrderedCancelAddMonoid DFunLike.coe coe_add .rfl + Function.Injective.isOrderedCancelAddMonoid DFunLike.coe FunLike.coe_add .rfl instance instMulAction [Monoid R] [MulAction R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] : - MulAction R (Seminorm 𝕜 E) := - DFunLike.coe_injective.mulAction _ (by intros; rfl) + MulAction R (Seminorm 𝕜 E) := fast_instance% FunLike.mulAction variable (𝕜 E) -/-- `coeFn` as an `AddMonoidHom`. Helper definition for showing that `Seminorm 𝕜 E` is a module. -/ -@[simps] -def coeFnAddMonoidHom : AddMonoidHom (Seminorm 𝕜 E) (E → ℝ) where - toFun := (↑) - map_zero' := coe_zero - map_add' := coe_add +@[deprecated (since := "2026-06-22")] alias coeFnAddMonoidHom := FunLike.coeAddMonoidHom + +@[deprecated (since := "2026-06-22")] alias coeFnAddMonoidHom_apply := FunLike.coeAddMonoidHom_apply -theorem coeFnAddMonoidHom_injective : Function.Injective (coeFnAddMonoidHom 𝕜 E) := - show @Function.Injective (Seminorm 𝕜 E) (E → ℝ) (↑) from DFunLike.coe_injective +@[deprecated (since := "2026-06-22")] alias coeFnAddMonoidHom_injective := + FunLike.coeAddMonoidHom_injective variable {𝕜 E} instance instDistribMulAction [Monoid R] [DistribMulAction R ℝ] [SMul R ℝ≥0] - [IsScalarTower R ℝ≥0 ℝ] : DistribMulAction R (Seminorm 𝕜 E) := - (coeFnAddMonoidHom_injective 𝕜 E).distribMulAction _ (by intros; rfl) + [IsScalarTower R ℝ≥0 ℝ] : DistribMulAction R (Seminorm 𝕜 E) := fast_instance% + FunLike.distribMulAction instance instModule [Semiring R] [Module R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] : - Module R (Seminorm 𝕜 E) := - (coeFnAddMonoidHom_injective 𝕜 E).module R _ (by intros; rfl) + Module R (Seminorm 𝕜 E) := fast_instance% FunLike.module instance instSup : Max (Seminorm 𝕜 E) where max p q := @@ -407,10 +396,8 @@ variable {σ₁₂ : 𝕜 →+* 𝕜₂} [RingHomIsometric σ₁₂] variable [AddCommGroup E] [AddCommGroup E₂] [Module 𝕜 E] [Module 𝕜₂ E₂] theorem comp_smul (p : Seminorm 𝕜₂ E₂) (f : E →ₛₗ[σ₁₂] E₂) (c : 𝕜₂) : - p.comp (c • f) = ‖c‖₊ • p.comp f := - ext fun _ => by - rw [comp_apply, smul_apply, LinearMap.smul_apply, map_smul_eq_mul, NNReal.smul_def, coe_nnnorm, - smul_eq_mul, comp_apply] + p.comp (c • f) = ‖c‖₊ • p.comp f := by + ext; simp [NNReal.smul_def, map_smul_eq_mul] theorem comp_smul_apply (p : Seminorm 𝕜₂ E₂) (f : E →ₛₗ[σ₁₂] E₂) (c : 𝕜₂) (x : E) : p.comp (c • f) x = ‖c‖ * p (f x) := @@ -1178,7 +1165,7 @@ theorem continuous_of_le [TopologicalSpace E] [IsTopologicalAddGroup E] theorem continuous_finsetSum [TopologicalSpace E] {p : ι → Seminorm 𝕝 E} {s : Finset ι} (hp : ∀ i ∈ s, Continuous (p i)) : Continuous ((∑ i ∈ s, p i : Seminorm 𝕝 E) : E → ℝ) := by - change Continuous (fun x ↦ coeFnAddMonoidHom _ _ (∑ i ∈ s, p i) x) + change Continuous (fun x ↦ FunLike.coeAddMonoidHom _ _ _ (∑ i ∈ s, p i) x) simp_rw [map_sum, Finset.sum_apply] exact _root_.continuous_finsetSum s hp From 5a0753dc725610d074b177e4677000ee96165b8e Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:09:28 +0000 Subject: [PATCH 0697/1300] feat: a function which is continuous outside of a countable set is strongly measurable (#41418) Co-authored-by: sgouezel --- .../Constructions/BorelSpace/Basic.lean | 15 ++++++++ .../MeasureTheory/Function/SimpleFunc.lean | 10 ++++++ .../Function/StronglyMeasurable/Basic.lean | 36 +++++++++++++++++++ .../MeasurableSpace/Constructions.lean | 5 +++ 4 files changed, 66 insertions(+) diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index 966522788b9a5e..6e103889210543 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -498,6 +498,21 @@ is ae-measurable. -/ theorem Continuous.aemeasurable {f : α → γ} (h : Continuous f) {μ : Measure α} : AEMeasurable f μ := h.measurable.aemeasurable +/-- If a function is continuous outside of a countable set, it is measurable. -/ +theorem ContinuousOn.measurable_of_countable_compl [MeasurableSingletonClass α] + {f : α → γ} {s : Set α} (hf : ContinuousOn f s) (hs : (sᶜ).Countable) : Measurable f := by + apply measurable_of_measurable_on_compl_countable _ hs + rw [compl_compl] + exact (continuousOn_iff_continuous_restrict.1 hf).measurable + +/-- If a function is continuous outside of a countable set, then it is measurable. -/ +theorem measurable_of_countable_not_continuousAt [MeasurableSingletonClass α] + {f : α → γ} (hf : Set.Countable {x | ¬ ContinuousAt f x}) : Measurable f := by + have : ContinuousOn f {x | ContinuousAt f x} := fun x hx ↦ hx.continuousWithinAt + apply this.measurable_of_countable_compl + convert hf + grind + theorem Topology.IsClosedEmbedding.measurable {f : α → γ} (hf : IsClosedEmbedding f) : Measurable f := hf.continuous.measurable diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index 133f5f46b0638a..3778440c72a4c4 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -221,6 +221,16 @@ theorem piecewise_same (f : α →ₛ β) {s : Set α} (hs : MeasurableSet s) : classical exact coe_injective <| Set.piecewise_same _ _ +/-- Dependent If-then-else as a `SimpleFunc`. -/ +@[simps] +def dite (s : Set α) (hs : MeasurableSet s) (f : s →ₛ β) (g : (sᶜ : Set α) →ₛ β) : α →ₛ β where + toFun x := open scoped Classical in if hx : x ∈ s then f ⟨x, hx⟩ else g ⟨x, hx⟩ + measurableSet_fiber' x := by + classical + letI : MeasurableSpace β := ⊤ + exact Measurable.dite f.measurable g.measurable hs trivial + finite_range' := (f.finite_range.union g.finite_range).subset (by grind) + theorem support_indicator [Zero β] {s : Set α} (hs : MeasurableSet s) (f : α →ₛ β) : Function.support (f.piecewise s hs (SimpleFunc.const α 0)) = s ∩ Function.support f := Set.support_indicator diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 6f81c159bb59af..c47967b096d8d8 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -817,6 +817,42 @@ protected theorem ite {_ : MeasurableSpace α} [TopologicalSpace β] {p : α → (hg : StronglyMeasurable g) : StronglyMeasurable fun x => ite (p x) (f x) (g x) := StronglyMeasurable.piecewise hp hf hg +protected theorem dite {s : Set α} {m : MeasurableSpace α} [TopologicalSpace β] + [(x : α) → Decidable (x ∈ s)] {f : ↑s → β} (hf : StronglyMeasurable f) + {g : ↑sᶜ → β} (hg : StronglyMeasurable g) (hs : MeasurableSet s) : + StronglyMeasurable fun x ↦ if hx : x ∈ s then f ⟨x, hx⟩ else g ⟨x, hx⟩ := by + refine ⟨fun n ↦ SimpleFunc.dite s hs (hf.approx n) (hg.approx n), fun x ↦ ?_⟩ + by_cases hx : x ∈ s + · simpa [hx] using hf.tendsto_approx ⟨x, hx⟩ + · simpa [hx] using hg.tendsto_approx ⟨x, hx⟩ + +/-- If a function is continuous outside of a countable set, then it is strongly measurable. -/ +theorem _root_.ContinuousOn.stronglyMeasurable_of_countable_compl [MeasurableSpace α] + [TopologicalSpace α] [OpensMeasurableSpace α] [MeasurableSingletonClass α] + [TopologicalSpace β] [PseudoMetrizableSpace β] + [h : SecondCountableTopologyEither α β] {f : α → β} {s : Set α} (hf : ContinuousOn f s) + (hs : (sᶜ).Countable) : StronglyMeasurable f := by + classical + have h's : MeasurableSet s := by simpa using hs.measurableSet.compl + have : f = fun x ↦ if hx : x ∈ s then f (⟨x, hx⟩ : s) else f (⟨x, hx⟩ : (sᶜ : Set α)) := by simp + rw [this] + apply StronglyMeasurable.dite (f := fun x ↦ f x) (g := fun x ↦ f x) ?_ ?_ h's + · have : SecondCountableTopologyEither s β := by cases h.out <;> infer_instance + exact (continuousOn_iff_continuous_restrict.1 hf).stronglyMeasurable + · have := hs.to_subtype + exact MeasureTheory.StronglyMeasurable.of_discrete + +/-- If a function is continuous outside of a countable set, then it is strongly measurable. -/ +theorem of_countable_not_continuousAt [MeasurableSpace α] [TopologicalSpace α] + [OpensMeasurableSpace α] [MeasurableSingletonClass α] + [TopologicalSpace β] [PseudoMetrizableSpace β] + [h : SecondCountableTopologyEither α β] {f : α → β} + (hf : Set.Countable {x | ¬ ContinuousAt f x}) : StronglyMeasurable f := by + have : ContinuousOn f {x | ContinuousAt f x} := fun x hx ↦ hx.continuousWithinAt + apply this.stronglyMeasurable_of_countable_compl + convert hf + grind + @[fun_prop] theorem _root_.MeasurableEmbedding.stronglyMeasurable_extend {f : α → β} {g : α → γ} {g' : γ → β} {mα : MeasurableSpace α} {mγ : MeasurableSpace γ} [TopologicalSpace β] diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index 05898d572f1af7..9b3c601b13e101 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -279,6 +279,11 @@ theorem measurable_of_measurable_on_compl_finite [MeasurableSingletonClass α] { have := hs.to_subtype measurable_of_restrict_of_restrict_compl hs.measurableSet (measurable_of_finite _) hf +theorem measurable_of_measurable_on_compl_countable [MeasurableSingletonClass α] {f : α → β} + (s : Set α) (hs : s.Countable) (hf : Measurable (sᶜ.restrict f)) : Measurable f := + have := hs.to_subtype + measurable_of_restrict_of_restrict_compl hs.measurableSet (measurable_of_countable _) hf + theorem measurable_of_measurable_on_compl_singleton [MeasurableSingletonClass α] {f : α → β} (a : α) (hf : Measurable ({ x | x ≠ a }.restrict f)) : Measurable f := measurable_of_measurable_on_compl_finite {a} (finite_singleton a) hf From acad6f4eb47959c7f9044081268d43aae88dec63 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Thu, 9 Jul 2026 09:22:05 +0000 Subject: [PATCH 0698/1300] =?UTF-8?q?feat(GroupAction):=20`(M=20=E2=86=92[?= =?UTF-8?q?M]=20M)=20=E2=89=83*=20M=E1=B5=90=E1=B5=92=E1=B5=96`=20(#33112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This comes up in #33108 in the form that permutations of a group commuting with the left multiplications are the right multiplications. The Semiring versions are already in mathlib. --- Mathlib/GroupTheory/GroupAction/Hom.lean | 44 ++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/Mathlib/GroupTheory/GroupAction/Hom.lean b/Mathlib/GroupTheory/GroupAction/Hom.lean index 4ba57e5936c038..d841820eabda11 100644 --- a/Mathlib/GroupTheory/GroupAction/Hom.lean +++ b/Mathlib/GroupTheory/GroupAction/Hom.lean @@ -413,8 +413,6 @@ end MulActionHom namespace MulActionHom -section - variable {R M N X Y : Type*} {σ : M → N} attribute [local simp] map_smulₛₗ smul_sub @@ -535,7 +533,47 @@ instance [SMul M X] [Monoid N] [Ring Y] [MulSemiringAction N Y] : instance [SMul M X] [Monoid N] [CommRing Y] [MulSemiringAction N Y] : CommRing (X →ₑ[σ] Y) where -end +namespace End + +/-- For a monoid `M` acting on a type `X`, the `M`-equivariant functions from `X` to itself +form a monoid under composition. -/ +@[to_additive /-- For an additive monoid `M` acting on a type `X`, the `M`-equivariant functions +from `X` to itself form an additive monoid under composition. -/] +local instance [SMul M X] : Monoid (X →[M] X) where + mul f g := f.comp g + mul_assoc _ _ _ := rfl + one := .id _ + one_mul _ := rfl + mul_one _ := rfl + +@[to_additive (attr := simp)] theorem mul_def [SMul M X] {f g : X →[M] X} : f * g = f.comp g := rfl + +/-- The `M`-equivariant functions from a monoid `M` to itself are exactly +right multiplications by elements of `M`. See also `RingEquiv.moduleEndSelf`. -/ +@[to_additive (attr := simps) +/-- The `M`-equivariant functions from an additive monoid `M` to itself are exactly +right additions by elements of `M`. -/] +def equivMulOpposite [Monoid M] : (M →[M] M) ≃* Mᵐᵒᵖ where + toFun f := .op (f 1) + invFun m := .mk (· * m.unop) fun _ _ ↦ mul_assoc .. + left_inv f := by ext m; change m • f 1 = _; rw [← map_smul, smul_eq_mul, mul_one] + right_inv := mul_one + map_mul' f g := congr_arg MulOpposite.op <| by + dsimp [← smul_eq_mul]; simp_rw [← map_smul, smul_eq_mul, mul_one]; rfl + +/-- The functions from a monoid `M` to itself equivariant with respect to the right `M`-action +are exactly left multiplications by elements of `M`. See also `RingEquiv.moduleEndSelfOp`. -/ +@[to_additive (attr := simps) +/-- The functions from an additive monoid `M` to itself equivariant with respect to +the right `M`-action are exactly left additions by elements of `M`. -/] +def mulOppositeEquiv [Monoid M] : (M →[Mᵐᵒᵖ] M) ≃* M where + toFun f := f 1 + invFun m := .mk (m * ·) fun _ _ ↦ (mul_assoc ..).symm + left_inv f := by ext m; change MulOpposite.op m • f 1 = _; simp [← map_smul] + right_inv := mul_one + map_mul' f g := show _ = MulOpposite.op (g 1) • f 1 by simp [← map_smul] + +end End end MulActionHom From d0a0b14db0469466a1a0e8cd942d0b4264b5d807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 9 Jul 2026 10:03:00 +0000 Subject: [PATCH 0699/1300] feat(CategoryTheory): presheaves of types which preserve a limit (#32725) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let `F : J ⥤ Cᵒᵖ` be a functor. We show that a presheaf `P : Cᵒᵖ ⥤ Type w` preserves the limit of `F` iff `P` is a local object with respect to a suitable family of morphisms in `Cᵒᵖ ⥤ Type w` (this family contains `1` or `0` morphism depending on whether the limit of `F` exists or not). --- Mathlib.lean | 1 + .../Limits/Types/PreservesLimit.lean | 149 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 Mathlib/CategoryTheory/Limits/Types/PreservesLimit.lean diff --git a/Mathlib.lean b/Mathlib.lean index 74826bc9621c0c..bf4256c6cb96b2 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2990,6 +2990,7 @@ public import Mathlib.CategoryTheory.Limits.Types.Images public import Mathlib.CategoryTheory.Limits.Types.Limits public import Mathlib.CategoryTheory.Limits.Types.Multicoequalizer public import Mathlib.CategoryTheory.Limits.Types.Multiequalizer +public import Mathlib.CategoryTheory.Limits.Types.PreservesLimit public import Mathlib.CategoryTheory.Limits.Types.Products public import Mathlib.CategoryTheory.Limits.Types.Pullbacks public import Mathlib.CategoryTheory.Limits.Types.Pushouts diff --git a/Mathlib/CategoryTheory/Limits/Types/PreservesLimit.lean b/Mathlib/CategoryTheory/Limits/Types/PreservesLimit.lean new file mode 100644 index 00000000000000..4c983adb421703 --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/Types/PreservesLimit.lean @@ -0,0 +1,149 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.ObjectProperty.FunctorCategory.PreservesLimits +public import Mathlib.CategoryTheory.ObjectProperty.Local + +/-! +# Presheaves of types which preserves a limit + +Let `F : J ⥤ Cᵒᵖ` be a functor. We show that a presheaf `P : Cᵒᵖ ⥤ Type w` +preserves the limit of `F` iff `P` is a local object with respect to a suitable +family of morphisms in `Cᵒᵖ ⥤ Type w` (this family contains `1` or `0` morphism +depending on whether the limit of `F` exists or not). + +-/ + +@[expose] public section + +universe w v v' u u' + +namespace CategoryTheory + +open Limits Opposite + +namespace Presheaf + +section + +variable {C : Type u} [Category.{v} C] + {J : Type u'} [Category.{v'} J] [LocallySmall.{w} C] + {F : J ⥤ Cᵒᵖ} (c : Cone F) {c' : Cocone (F.leftOp ⋙ shrinkYoneda.{w})} + (hc : IsLimit c) (hc' : IsColimit c') (P : Cᵒᵖ ⥤ Type w) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +variable {P} in +/-- Let `F : J ⥤ Cᵒᵖ` be a functor, `c'` a colimit cocone for `F.leftOp ⋙ shrinkYoneda.{w}`. +For any `P : Cᵒᵖ ⥤ Type w`, this is the bijection between `c'.pt ⟶ P` and the type +of sections of `F ⋙ P`. -/ +@[simps -isSimp symm_apply apply_coe] +noncomputable def coconeCompShrinkYonedaHomEquiv : + (c'.pt ⟶ P) ≃ (F ⋙ P).sections where + toFun f := + { val j := shrinkYonedaEquiv (c'.ι.app (op j) ≫ f) + property {X X'} g := by + dsimp + rw [← dsimp% c'.w g.op, Category.assoc] + conv_rhs => rw [shrinkYonedaEquiv_comp] + rw [shrinkYonedaEquiv_shrinkYoneda_map] + apply map_shrinkYonedaEquiv } + invFun s := hc'.desc (Cocone.mk _ + { app j := shrinkYonedaEquiv.symm (s.val j.unop) + naturality j₁ j₂ f := by + rw [← s.property f.unop] + dsimp + rw [shrinkYonedaEquiv_symm_map, Category.comp_id] }) + left_inv f := hc'.hom_ext (by simp) + right_inv u := by cat_disch + +/-- Let `F : J ⥤ Cᵒᵖ` be a functor, `c'` a colimit cocone for `F.leftOp ⋙ shrinkYoneda.{w}`. +For any cone `c` for `F`, this is the canonical natural transformation +`c'.pt ⟶ shrinkYoneda.{w}.obj c.pt.unop`. -/ +noncomputable def coconePtToShrinkYoneda : + c'.pt ⟶ shrinkYoneda.{w}.obj c.pt.unop := + hc'.desc (shrinkYoneda.{w}.mapCocone (coconeLeftOpOfCone c)) + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +variable {P} in +@[reassoc] +lemma coconePtToShrinkYoneda_comp (x : P.obj c.pt) : + coconePtToShrinkYoneda c hc' ≫ shrinkYonedaEquiv.symm x = + (coconeCompShrinkYonedaHomEquiv hc').symm + (Types.sectionOfCone (P.mapCone c) x) := by + refine hc'.hom_ext (fun _ ↦ ?_) + dsimp [coconePtToShrinkYoneda, coconeCompShrinkYonedaHomEquiv_symm_apply] + rw [hc'.fac_assoc, hc'.fac] + exact (shrinkYonedaEquiv_symm_map _ _).symm + +set_option backward.isDefEq.respectTransparency false in +lemma nonempty_isLimit_mapCone_iff : + Nonempty (IsLimit (P.mapCone c)) ↔ + (MorphismProperty.single (coconePtToShrinkYoneda c hc')).isLocal P := by + rw [Types.isLimit_iff_bijective_sectionOfCone, + MorphismProperty.isLocal_single_iff_bijective, + ← Function.Bijective.of_comp_iff' (coconeCompShrinkYonedaHomEquiv hc').symm.bijective, + ← Function.Bijective.of_comp_iff _ shrinkYonedaEquiv.bijective] + convert Iff.rfl using 2 + ext : 1 + simp [← coconePtToShrinkYoneda_comp] + +variable {c} + +include hc in +lemma preservesLimit_eq_isLocal_single : + ObjectProperty.preservesLimit F = + (MorphismProperty.single (coconePtToShrinkYoneda c hc')).isLocal := by + ext P + rw [← nonempty_isLimit_mapCone_iff c hc' P] + exact ⟨fun _ ↦ ⟨isLimitOfPreserves P hc⟩, + fun ⟨h⟩ ↦ preservesLimit_of_preserves_limit_cone hc h⟩ + +variable (F) [Small.{w} J] + +/-- Auxiliary definition for `Presheaf.preservesLimitHomFamily`. -/ +noncomputable abbrev preservesLimitHomFamilySrc := + colimit (F.leftOp ⋙ shrinkYoneda) + +/-- Auxiliary definition for `Presheaf.preservesLimitHomFamily`. -/ +noncomputable abbrev preservesLimitHomFamilyTgt (h : PLift (HasLimit F)) := + letI := h.down + shrinkYoneda.obj (limit F).unop + +/-- Let `F : J ⥤ Cᵒᵖ` be a functor. This is the family of morphisms +which consists of the single morphism +`colimit (F.leftOp ⋙ shrinkYoneda) ⟶ shrinkYoneda.obj (limit F).unop` +if `F` has a limit, or is the empty family otherwise. -/ +noncomputable abbrev preservesLimitHomFamily (h : PLift (HasLimit F)) : + preservesLimitHomFamilySrc F ⟶ preservesLimitHomFamilyTgt F h := + letI := h.down + coconePtToShrinkYoneda (limit.cone F) (colimit.isColimit _) + +lemma preservesLimit_eq_isLocal : + ObjectProperty.preservesLimit F = + (MorphismProperty.ofHoms (preservesLimitHomFamily F)).isLocal := by + ext + by_cases hF : HasLimit F + · rw [preservesLimit_eq_isLocal_single (limit.isLimit F) (colimit.isColimit _)] + convert Iff.rfl + ext + exact ⟨fun ⟨_⟩ ↦ ⟨⟨⟩⟩, fun ⟨_⟩ ↦ ⟨⟨hF⟩⟩⟩ + · exact ⟨fun _ _ _ _ ⟨h⟩ ↦ (hF h.down).elim, + fun _ ↦ ⟨fun hc ↦ (hF ⟨_, hc⟩).elim⟩⟩ + +lemma preservesLimitsOfShape_eq_isLocal : + ObjectProperty.preservesLimitsOfShape J = + (⨆ (F : J ⥤ Cᵒᵖ), MorphismProperty.ofHoms (preservesLimitHomFamily F)).isLocal := by + simp only [ObjectProperty.preservesLimitsOfShape_eq_iSup, + MorphismProperty.isLocal_iSup, preservesLimit_eq_isLocal] + +end + +end Presheaf + +end CategoryTheory From e67386483d858937af820ab80b7425298666f302 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 9 Jul 2026 10:03:03 +0000 Subject: [PATCH 0700/1300] chore(Topology/Algebra/Valued/WithVal): clean up instances (#41302) This PR cleans up some instance diamonds around `WithVal`. --- Mathlib/Topology/Algebra/Valued/WithVal.lean | 25 ++++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index 52af5959ca41f2..0f0f940695bd2b 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -267,9 +267,8 @@ instance {P : Type*} [Ring S] [SMul P R] [SMul S R] [SMul P S] smul_assoc := by simp [smul_right_def, smul_left_def, -toVal_smul] instance [AddCommMonoid S] [Module R S] : Module (WithVal v) S := - .compHom S (equiv v).toRingHom + fast_instance% .compHom S (equiv v).toRingHom -set_option backward.isDefEq.respectTransparency false in instance [AddCommMonoid S] [Module R S] [Module.Finite R S] : Module.Finite (WithVal v) S := .of_restrictScalars_finite R (WithVal v) S @@ -300,7 +299,7 @@ section left variable [CommRing R] (v : Valuation R Γ₀) [Semiring S] [Algebra R S] instance : Algebra (WithVal v) S := fast_instance% { - __ := (inferInstance : Module (WithVal v) S) + algebraMap.toFun r := algebraMap R S (ofVal r) __ := Algebra.compHom S (equiv v).toRingHom } theorem algebraMap_left_apply (s : WithVal v) : @@ -318,7 +317,9 @@ section right variable [CommSemiring R] [Ring S] [Algebra R S] (v : Valuation S Γ₀) -instance : Algebra R (WithVal v) := fast_instance% (equiv v).algebra R +instance : Algebra R (WithVal v) := fast_instance% { + (equiv v).algebra R with + algebraMap.toFun r := toVal v (algebraMap R S r) } theorem algebraMap_right_apply (r : R) : algebraMap R (WithVal v) r = toVal v (algebraMap R S r) := rfl @@ -344,12 +345,9 @@ instance {S : Type*} [CommRing S] [Algebra R S] (M : Submonoid R) [IsLocalizatio end Algebra -section Field - -instance [DivisionRing R] (v : Valuation R Γ₀) : DivisionRing (WithVal v) := fast_instance% - (equiv v).divisionRing +section DivisionRing -variable [Field R] (v : Valuation R Γ₀) +variable [DivisionRing R] (v : Valuation R Γ₀) instance : Div (WithVal v) where div x y := toVal _ (x.ofVal / y.ofVal) instance : Inv (WithVal v) where inv x := toVal _ x.ofVal⁻¹ @@ -377,6 +375,14 @@ instance : RatCast (WithVal v) where ratCast q := toVal _ q @[simp] lemma ofVal_ratCast (q : ℚ) : ofVal (q : WithVal v) = q := rfl +instance : DivisionRing (WithVal v) := fast_instance% (equiv v).divisionRing + +end DivisionRing + +section Field + +variable [Field R] (v : Valuation R Γ₀) + instance : Field (WithVal v) := fast_instance% ofVal_injective v |>.field _ (ofVal_zero _) (ofVal_one _) (ofVal_add _) (ofVal_mul _) (ofVal_neg _) (ofVal_sub _) (ofVal_inv _) (ofVal_div _) @@ -673,7 +679,6 @@ instance : CoeHead (𝓞 (WithVal v)) (WithVal v) where instance (R : Type*) [CommRing R] [Algebra R K] [IsIntegralClosure R ℤ K] : IsIntegralClosure R ℤ (WithVal v) := .of_algEquiv _ (WithVal.algEquiv ℤ v).symm (fun _ ↦ rfl) -set_option backward.isDefEq.respectTransparency false in /-- The ring equivalence between `𝓞 (WithVal v)` and an integral closure of `ℤ` in `K`. -/ @[simps!] From 46b70232ffd8466db2c3a6748836b3ca100a4ea6 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 10:03:05 +0000 Subject: [PATCH 0701/1300] chore: update Mathlib dependencies 2026-07-09 (#41405) This PR updates the Mathlib dependencies. Co-authored-by: Bryan Gin-ge Chen --- MathlibTest/Tactic/AesopCat.lean | 2 +- lake-manifest.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MathlibTest/Tactic/AesopCat.lean b/MathlibTest/Tactic/AesopCat.lean index b878fbf387ec39..b3b429e8b9177c 100644 --- a/MathlibTest/Tactic/AesopCat.lean +++ b/MathlibTest/Tactic/AesopCat.lean @@ -12,7 +12,7 @@ example : Foo where /-- error: could not synthesize default value for field 'w' of 'Foo' using tactics --- -error: tactic 'aesop' failed, failed to prove the goal after exhaustive search. +error: Tactic `aesop` failed, failed to prove the goal after exhaustive search. Initial goal: ⊢ 35 = 37 Remaining goals after safe rules: diff --git a/lake-manifest.json b/lake-manifest.json index 25f55d0dc1c353..8c018e595b3ff1 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b5b9e2bb45ce91e4bc44eaa738c3a8910404ab82", + "rev": "24fa6b3599743c23e6debd53d5fd09ebfa587d29", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9c6e03c0a86237b199ebe6b1fbac18078a767ade", + "rev": "232c5be1450cb3e59fd3486ab87393af0a98986e", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From e469acc1a6f48bf1ea649154ddba3830fd9e4afc Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Thu, 9 Jul 2026 10:58:20 +0000 Subject: [PATCH 0702/1300] feat(CategoryTheory/Sites/Over): add `Presieve.overEquiv` (#41510) This PR adds `Presieve.overEquiv`, the presieve version of the existing `Sieve.overEquiv`. I also upgraded these equivs to order isomorphisms, and fixed some defeq abuse at the same time. Partial help from Claude on a couple of the proofs, all code was ultimately written and golfed by me. Co-authored-by: tb65536 --- Mathlib/AlgebraicGeometry/Sites/Small.lean | 2 +- .../Sites/Descent/DescentData.lean | 2 +- .../Sites/Descent/Precoverage.lean | 6 +- Mathlib/CategoryTheory/Sites/Over.lean | 118 +++++++++--------- Mathlib/CategoryTheory/Sites/Point/Over.lean | 4 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 10 +- 6 files changed, 76 insertions(+), 66 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Sites/Small.lean b/Mathlib/AlgebraicGeometry/Sites/Small.lean index 65525c1c014f1d..eb2ee33aaa6afc 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Small.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Small.lean @@ -72,7 +72,7 @@ lemma Cover.toPresieveOver_le_arrows_iff {X : Over S} (R : Sieve X) (𝒰 : Cover.{u} (precoverage P) X.left) [𝒰.Over S] : 𝒰.toPresieveOver ≤ R.arrows ↔ Presieve.ofArrows 𝒰.X 𝒰.f ≤ (Sieve.overEquiv X R).arrows := by - simp_rw [← Sieve.giGenerate.gc.le_iff_le, ← Sieve.overEquiv_le_overEquiv_iff] + simp_rw [← Sieve.giGenerate.gc.le_iff_le, ← (Sieve.overEquiv X).map_rel_iff] rw [overEquiv_generate_toPresieveOver_eq_ofArrows] variable [P.IsMultiplicative] [P.RespectsIso] diff --git a/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean b/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean index 0330de4a5c5ae8..25a9d3550f1cc0 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean @@ -616,7 +616,7 @@ noncomputable def fullyFaithfulToDescentData [F.IsPrestack J] (hf : Sieve.ofArro intro M N refine ((isSheaf_iff_isSheaf_of_type _ _).1 (IsPrestack.isSheaf J M N)).isSheafFor _ ?_ - rwa [GrothendieckTopology.mem_over_iff, Sieve.generate_sieve, Equiv.apply_symm_apply]) + rwa [GrothendieckTopology.mem_over_iff, Sieve.generate_sieve, OrderIso.apply_symm_apply]) lemma isPrestackFor [F.IsPrestack J] {S : C} (R : Presieve S) (hR : Sieve.generate R ∈ J S) : F.IsPrestackFor R := by diff --git a/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean b/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean index fd2a5da5fe7d2a..cfb85be4edb1c8 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean @@ -64,7 +64,7 @@ public lemma faithful_pullFunctor : refine F.presheafHomObjHomEquiv.injective ?_i have : (Sieve.overEquiv (Over.mk (𝟙 (X i)))).symm (Sieve.pullback (f i) (Sieve.ofArrows X' f')) ∈ J.over (X i) _ := by - simpa only [J.mem_over_iff, Equiv.apply_symm_apply] using! J.pullback_stable (f i) hf' + simpa only [J.mem_over_iff, OrderIso.apply_symm_apply] using! J.pullback_stable (f i) hf' refine (((isSheaf_iff_isSheaf_of_type _ _).1 (IsPrestack.isSheaf _ _ _)).isSeparated _ this).ext ?_ rintro Z g ⟨Y, p, c, ⟨j⟩, hp⟩ @@ -104,7 +104,7 @@ abbrev sieve (i : ι) : Sieve (Over.mk (𝟙 (X i))) := include hf' in variable (f) in lemma sieve_mem (i : ι) : sieve f f' i ∈ J.over _ _ := by - simpa only [J.mem_over_iff, Equiv.apply_symm_apply] using! J.pullback_stable (f i) hf' + simpa only [J.mem_over_iff, OrderIso.apply_symm_apply] using! J.pullback_stable (f i) hf' set_option backward.defeqAttrib.useBackward true in lemma mem_sieve {i : ι} {Z : C} (q : Z ⟶ X i) ⦃j : ι'⦄ (a : Z ⟶ X' j) @@ -275,7 +275,7 @@ lemma comm ⦃W : C⦄ (q : W ⟶ S) ⦃i₁ i₂ : ι⦄ Category.assoc, DescentData.hom_comp, D₂.hom_self _ _ hf₁, Category.comp_id] have H : (Sieve.overEquiv (Over.mk f₁)).symm (Sieve.pullback q (Sieve.ofArrows X' f')) ∈ J.over _ _ := by - rw [J.mem_over_iff, Equiv.apply_symm_apply] + rw [J.mem_over_iff, OrderIso.apply_symm_apply] exact J.pullback_stable _ hf' refine ((isSheaf_iff_isSheaf_of_type _ _).1 (IsPrestack.isSheaf J (D₁.obj i₁) (D₂.obj i₁)) _ H).isSeparatedFor.ext ?_ diff --git a/Mathlib/CategoryTheory/Sites/Over.lean b/Mathlib/CategoryTheory/Sites/Over.lean index b008c77f36e1fb..3a512a92661ab2 100644 --- a/Mathlib/CategoryTheory/Sites/Over.lean +++ b/Mathlib/CategoryTheory/Sites/Over.lean @@ -33,70 +33,74 @@ open Category variable {C : Type u} [Category.{v} C] +namespace Presieve + @[simp] -lemma Presieve.map_functorPullback_overForget {X : C} {Y : Over X} (R : Presieve Y.left) : - Presieve.map (Over.forget X) (.functorPullback (Over.forget X) R) = R := by - refine le_antisymm (map_functorPullback _) fun Z g hg ↦ ?_ - let g' : Over.mk (g ≫ Y.hom) ⟶ Y := Over.homMk g - exact Presieve.map.of (u := g') hg +lemma functorPullback_map_overForget {X : C} {Y : Over X} (S : Presieve Y) : + (S.map (Over.forget X)).functorPullback (Over.forget X) = S := by + let R : Presieve Y.left := fun Z g ↦ S (Over.homMk g : Over.mk (g ≫ Y.hom) ⟶ Y) + suffices hR : (R.functorPullback (Over.forget X)) = S by + rw [← hR, functorPullback_map_functorPullback] + funext Z f + obtain ⟨Z, fZ, rfl⟩ := Z.mk_surjective + obtain ⟨g : Z ⟶ Y.left, rfl : g ≫ Y.hom = fZ, rfl⟩ := Over.homMk_surjective f + rfl -namespace Sieve +@[simp] +lemma map_functorPullback_overForget {X : C} {Y : Over X} (R : Presieve Y.left) : + (R.functorPullback (Over.forget X)).map (Over.forget X) = R := + le_antisymm (map_functorPullback _) fun Z g hg ↦ + map.of (u := (Over.homMk g : Over.mk (g ≫ Y.hom) ⟶ Y)) hg -set_option backward.defeqAttrib.useBackward true in -/-- The equivalence `Sieve Y ≃ Sieve Y.left` for all `Y : Over X`. -/ -def overEquiv {X : C} (Y : Over X) : - Sieve Y ≃ Sieve Y.left where - toFun S := Sieve.functorPushforward (Over.forget X) S - invFun S' := Sieve.functorPullback (Over.forget X) S' - left_inv S := by - ext Z g - dsimp [Presieve.functorPullback, Presieve.functorPushforward] - constructor - · rintro ⟨W, a, b, h, w⟩ - let c : Z ⟶ W := Over.homMk b - (by rw [← Over.w g, w, assoc, Over.w a]) - rw [show g = c ≫ a by ext; exact w] - exact S.downward_closed h _ - · intro h - exact ⟨Z, g, 𝟙 _, h, by simp⟩ - right_inv S := by - ext Z g - dsimp [Presieve.functorPullback, Presieve.functorPushforward] - constructor - · rintro ⟨W, a, b, h, rfl⟩ - exact S.downward_closed h _ - · intro h - exact ⟨Over.mk ((g ≫ Y.hom)), Over.homMk g, 𝟙 _, h, by simp⟩ +/-- The equivalence `Presieve Y ≃ Presieve Y.left` for all `Y : Over X`. -/ +@[simps] +def overEquiv {X : C} (Y : Over X) : Presieve Y ≃o Presieve Y.left where + toFun S := map (Over.forget X) S + invFun S' := functorPullback (Over.forget X) S' + left_inv := functorPullback_map_overForget + right_inv := map_functorPullback_overForget + map_rel_iff' := ⟨fun h ↦ by simpa using functorPullback_monotone h, fun h ↦ map_monotone h⟩ -@[simp] -lemma overEquiv_top {X : C} (Y : Over X) : - overEquiv Y ⊤ = ⊤ := by - ext Z g - simp only [top_apply, iff_true] - dsimp [overEquiv, Presieve.functorPushforward] - exact ⟨Y, 𝟙 Y, g, by simp, by simp⟩ +end Presieve + +namespace Sieve @[simp] -lemma overEquiv_symm_top {X : C} (Y : Over X) : - (overEquiv Y).symm ⊤ = ⊤ := - (overEquiv Y).injective (by simp) +lemma functorPushforward_overForget_arrows {X : C} {Y : Over X} (S : Sieve Y) : + S.arrows.functorPushforward (Over.forget X) = S.arrows.map (Over.forget X) := by + refine le_antisymm ?_ (S.arrows.map_le_functorPushforward (Over.forget X)) + rintro Z - ⟨W, fW, fZ, h, rfl⟩ + exact Presieve.map_map (S.downward_closed h (Over.homMk fZ : Over.mk (fZ ≫ W.hom) ⟶ W)) -set_option backward.isDefEq.respectTransparency false in @[simp] -lemma overEquiv_bot {X : C} (Y : Over X) : overEquiv Y ⊥ = ⊥ := by - simp [overEquiv] +lemma functorPullback_functorPushforward_overForget {X : C} {Y : Over X} (S : Sieve Y) : + (S.functorPushforward (Over.forget X)).functorPullback (Over.forget X) = S := by + apply arrows_ext + simp -set_option backward.isDefEq.respectTransparency false in @[simp] -lemma overEquiv_symm_bot {X : C} (Y : Over X) : (overEquiv Y).symm ⊥ = ⊥ := by - rw [overEquiv, Equiv.coe_fn_symm_mk, functorPullback_bot] +lemma functorPushforward_functorPullback_overForget {X : C} {Y : Over X} (S : Sieve Y.left) : + (S.functorPullback (Over.forget X)).functorPushforward (Over.forget X) = S := by + apply arrows_ext + simp [← arrows_generate_map_eq_functorPushforward] -lemma overEquiv_le_overEquiv_iff {X : C} {Y : Over X} (R₁ R₂ : Sieve Y) : - R₁.overEquiv Y ≤ R₂.overEquiv Y ↔ R₁ ≤ R₂ := by - refine ⟨fun h ↦ ?_, fun h ↦ Sieve.functorPushforward_monotone _ _ h⟩ - replace h : (overEquiv Y).symm (R₁.overEquiv Y) ≤ (overEquiv Y).symm (R₂.overEquiv Y) := - Sieve.functorPullback_monotone _ _ h - simpa using h +/-- The equivalence `Sieve Y ≃ Sieve Y.left` for all `Y : Over X`. -/ +@[simps -isSimp] -- working with `overEquiv` is useful enough that we don't want `simp` unfolding it +def overEquiv {X : C} (Y : Over X) : Sieve Y ≃o Sieve Y.left where + toFun := functorPushforward (Over.forget X) + invFun := functorPullback (Over.forget X) + left_inv := functorPullback_functorPushforward_overForget + right_inv := functorPushforward_functorPullback_overForget + map_rel_iff' := by + rw [Equiv.coe_fn_mk] + exact ⟨fun h ↦ by simpa using functorPullback_monotone _ _ h, + fun h ↦ functorPushforward_monotone _ _ h⟩ + +@[deprecated (since := "2026-07-08")] alias overEquiv_top := map_top +@[deprecated (since := "2026-07-08")] alias overEquiv_symm_top := map_top +@[deprecated (since := "2026-07-08")] alias overEquiv_bot := map_bot +@[deprecated (since := "2026-07-08")] alias overEquiv_symm_bot := map_bot +@[deprecated (since := "2026-07-08")] alias overEquiv_le_overEquiv_iff := RelIso.map_rel_iff set_option backward.defeqAttrib.useBackward true in lemma overEquiv_pullback {X : C} {Y₁ Y₂ : Over X} (f : Y₁ ⟶ Y₂) (S : Sieve Y₂) : @@ -245,7 +249,7 @@ lemma mem_over_iff {X : C} {Y : Over X} (S : Sieve Y) : lemma overEquiv_symm_mem_over {X : C} (Y : Over X) (S : Sieve Y.left) (hS : S ∈ J Y.left) : (Sieve.overEquiv Y).symm S ∈ (J.over X) Y := by - simpa only [mem_over_iff, Equiv.apply_symm_apply] using hS + simpa only [mem_over_iff, OrderIso.apply_symm_apply] using hS lemma over_forget_coverPreserving (X : C) : CoverPreserving (J.over X) J (Over.forget X) where @@ -528,7 +532,7 @@ lemma over_toGrothendieck_eq_toGrothendieck_comap_forget (X : C) : refine le_antisymm ?_ ?_ · intro ⟨Y, right, (s : Y ⟶ X)⟩ R hR obtain ⟨(R : Sieve Y), rfl⟩ := (Sieve.overEquiv _).symm.surjective R - simp +instances only [GrothendieckTopology.mem_over_iff, Equiv.apply_symm_apply, + simp +instances only [GrothendieckTopology.mem_over_iff, OrderIso.apply_symm_apply, ← Precoverage.toGrothendieck_toCoverage, Coverage.mem_toGrothendieck, Over.left] at hR induction hR with @@ -536,7 +540,6 @@ lemma over_toGrothendieck_eq_toGrothendieck_comap_forget (X : C) : rw [Sieve.overEquiv_symm_generate] exact .of _ _ (by simpa) | top => - rw [Sieve.overEquiv_symm_top] simp | transitive Y R S hR H ih ih' => refine GrothendieckTopology.transitive _ (ih s) _ fun Z g hg ↦ ?_ @@ -547,7 +550,8 @@ lemma over_toGrothendieck_eq_toGrothendieck_comap_forget (X : C) : intro Y R hR rw [Precoverage.mem_comap_iff] at hR rw [GrothendieckTopology.mem_toPrecoverage_iff, GrothendieckTopology.mem_over_iff, - Sieve.overEquiv, Equiv.coe_fn_mk, ← Sieve.generate_map_eq_functorPushforward] + Sieve.overEquiv, RelIso.coe_fn_mk, Equiv.coe_fn_mk, + ← Sieve.generate_map_eq_functorPushforward] exact Precoverage.Saturate.of _ _ hR end diff --git a/Mathlib/CategoryTheory/Sites/Point/Over.lean b/Mathlib/CategoryTheory/Sites/Point/Over.lean index a64e4cbffcf603..38514ec9ad53fb 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Over.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Over.lean @@ -50,7 +50,7 @@ def over : Point.{w} (J.over X) where jointly_surjective := by rintro U R hR ⟨u, hu⟩ obtain ⟨R, rfl⟩ := (Sieve.overEquiv _).symm.surjective R - simp only [mem_over_iff, Equiv.apply_symm_apply] at hR + simp only [mem_over_iff, OrderIso.apply_symm_apply] at hR obtain ⟨Y, f, hf, v, rfl⟩ := Φ.jointly_surjective R hR u refine ⟨Over.mk (f ≫ U.hom), Over.homMk f, hf, ⟨v, ?_⟩, rfl⟩ rw [FunctorToTypes.mem_fromOverSubfunctor_iff] at hu ⊢ @@ -71,7 +71,7 @@ lemma IsConservativeFamilyOfPoints.over mk' (fun Y S hS ↦ by obtain ⟨Y, f, rfl⟩ := Over.mk_surjective Y obtain ⟨S, rfl⟩ := (Sieve.overEquiv _).symm.surjective S - rw [mem_over_iff, Equiv.apply_symm_apply] + rw [mem_over_iff, OrderIso.apply_symm_apply] obtain ⟨ι, Z, g, rfl⟩ := S.exists_eq_ofArrows rw [hP.jointly_reflect_ofArrows_mem_of_small] intro Φ y diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 45cd429c4147d0..81bf60530d4028 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -757,8 +757,11 @@ theorem le_generate (R : Presieve X) : R ≤ generate R := theorem generate_sieve (S : Sieve X) : generate S = S := giGenerate.l_u_eq S -lemma generate_mono : Monotone (generate : Presieve X → _) := - (giGenerate (X := X)).gc.monotone_l +@[gcongr] +theorem generate_mono : Monotone (generate : Presieve X → Sieve X) := giGenerate.gc.monotone_l + +@[gcongr] +theorem arrows_mono : Monotone (arrows : Sieve X → Presieve X) := giGenerate.gc.monotone_u /-- If the identity arrow is in a sieve, the sieve is maximal. -/ theorem id_mem_iff_eq_top : S (𝟙 X) ↔ S = ⊤ := @@ -1469,6 +1472,9 @@ lemma Presieve.functorPullback_arrows {X : C} (S : Sieve (F.obj X)) : Presieve.functorPullback F S.arrows = Sieve.functorPullback F S := rfl +theorem Presieve.map_le_functorPushforward (S : Presieve X) : S.map F ≤ S.functorPushforward F := by + grw [← Sieve.arrows_generate_map_eq_functorPushforward, ← Sieve.le_generate] + lemma Presieve.bind_ofArrows_le_bindOfArrows {ι : Type*} {X : C} (Z : ι → C) (f : ∀ i, Z i ⟶ X) (R : ∀ i, Presieve (Z i)) : Sieve.bind (Sieve.ofArrows Z f) From 2a52b15f892ee5fb4192435a0b6849207f6dbd4f Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 9 Jul 2026 11:11:35 +0000 Subject: [PATCH 0703/1300] chore: remove some redundant `classical` (#41497) Remove `classical` (in two cases `open scoped Classical in`) when we already did `open (scoped) Classical in` Found by @vlad902 [here](https://github.com/leanprover-community/mathlib4/pull/41423#discussion_r3543871353) Co-authored-by: Batixx --- Mathlib/Combinatorics/SimpleGraph/Clique.lean | 1 - Mathlib/FieldTheory/PurelyInseparable/Exponent.lean | 1 - .../NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean | 1 - Mathlib/RingTheory/DedekindDomain/Different.lean | 3 +-- Mathlib/RingTheory/Extension/Presentation/Submersive.lean | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Clique.lean b/Mathlib/Combinatorics/SimpleGraph/Clique.lean index e8dd715e3ea3be..b3863017dc3f63 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Clique.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Clique.lean @@ -546,7 +546,6 @@ lemma CliqueFree.mem_of_sup_edge_isNClique {x y : α} {t : Finset α} {n : ℕ} have ht : (t : Set α) \ {x} = t := sdiff_eq_left.mpr <| Set.disjoint_singleton_right.mpr hf exact h t ⟨ht ▸ hc.1.sdiff_of_sup_edge, hc.2⟩ -open scoped Classical in /-- Adding an edge increases the clique number by at most one. -/ protected theorem CliqueFree.sup_edge (h : G.CliqueFree n) (v w : α) : (G ⊔ edge v w).CliqueFree (n + 1) := by diff --git a/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean b/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean index cee815e014b520..3243f8425492a4 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Exponent.lean @@ -114,7 +114,6 @@ is the smallest natural number `e` such that `a ^ ringExpChar K ^ e ∈ K`. -/ noncomputable def elemExponent (a : L) : ℕ := Nat.find <| minpoly_eq_X_pow_sub_C K (ringExpChar K) a -open scoped Classical in variable {K} in theorem elemExponent_eq_zero_of_mem_range {a : L} (h : a ∈ (algebraMap K L).range) : elemExponent K a = 0 := by diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean index 7da4f53aa81781..dcf939ca237774 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean @@ -533,7 +533,6 @@ theorem logMap_expMapBasis (x : realSpace K) : logMap (mixedSpaceOfRealSpace (expMapBasis x)) ∈ ZSpan.fundamentalDomain ((basisUnitLattice K).ofZLatticeBasis ℝ (unitLattice K)) ↔ ∀ w, w ≠ w₀ → x w ∈ Set.Ico 0 1 := by - classical simp_rw [ZSpan.mem_fundamentalDomain, equivFinRank.forall_congr_left, Subtype.forall] refine forall₂_congr fun w hw ↦ ?_ rw [expMapBasis_apply'', map_smul, logMap_real_smul (norm_expMapBasis_ne_zero _) diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index 88a9307503810b..8637e97f1922c2 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -112,7 +112,6 @@ open scoped Classical in lemma traceDual_top' : (⊤ : Submodule B L)ᵛ = if ((LinearMap.range (Algebra.trace K L)).restrictScalars A ≤ 1) then ⊤ else ⊥ := by - classical split_ifs with h · rw [_root_.eq_top_iff] exact fun _ _ _ _ ↦ h ⟨_, rfl⟩ @@ -224,11 +223,11 @@ variable [IsDomain A] [IsFractionRing B L] [Nontrivial B] [NoZeroDivisors B] namespace FractionalIdeal -open scoped Classical in /-- The dual of a non-zero fractional ideal is the dual of the submodule under the trace form. -/ noncomputable def dual (I : FractionalIdeal B⁰ L) : FractionalIdeal B⁰ L := + open scoped Classical in if hI : I = 0 then 0 else ⟨Iᵛ, by classical diff --git a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean index 8ade816775c620..60e65585343dde 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean @@ -297,7 +297,6 @@ variable [Fintype σ] [Fintype σ'] open scoped Classical in private lemma jacobiMatrix_comp_inl_inr (i : σ') (j : σ) : (Q.comp P).jacobiMatrix (Sum.inl i) (Sum.inr j) = 0 := by - classical rw [jacobiMatrix_apply] refine MvPolynomial.pderiv_eq_zero_of_notMem_vars (fun hmem ↦ ?_) apply MvPolynomial.vars_rename at hmem From 2d00c9242abecf5af452fe84bf7ce95d299313be Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Thu, 9 Jul 2026 11:11:37 +0000 Subject: [PATCH 0704/1300] chore: fix some ENat-related instances of `backward.isDefEq.respectTransparency` (#41515) --- Mathlib/Algebra/Polynomial/Div.lean | 3 +-- Mathlib/Data/ENat/Basic.lean | 1 + Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean | 5 ++--- Mathlib/RingTheory/DiscreteValuationRing/Basic.lean | 3 +-- Mathlib/RingTheory/Multiplicity.lean | 3 +-- Mathlib/RingTheory/OrderOfVanishing/Basic.lean | 4 +--- Mathlib/Topology/Instances/ENat.lean | 4 ++-- 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index 7ee00bdddb3f4f..dd34b114930c06 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -525,7 +525,6 @@ theorem rootMultiplicity_eq_natFind_of_ne_zero {p : R[X]} (p0 : p ≠ 0) {a : R} @[deprecated (since := "2026-02-12")] alias rootMultiplicity_eq_nat_find_of_nonzero := rootMultiplicity_eq_natFind_of_ne_zero -set_option backward.isDefEq.respectTransparency false in theorem rootMultiplicity_eq_multiplicity [DecidableEq R] (p : R[X]) (a : R) : rootMultiplicity a p = @@ -535,7 +534,7 @@ theorem rootMultiplicity_eq_multiplicity [DecidableEq R] · rfl rename_i h simp only [finiteMultiplicity_X_sub_C a h, ↓reduceDIte] - rw [← ENat.some_eq_coe, WithTop.untopD_coe] + rw [untopD_coe_enat] congr @[simp] diff --git a/Mathlib/Data/ENat/Basic.lean b/Mathlib/Data/ENat/Basic.lean index 6ef55d1250976f..b6bc86c0d471fb 100644 --- a/Mathlib/Data/ENat/Basic.lean +++ b/Mathlib/Data/ENat/Basic.lean @@ -118,6 +118,7 @@ def lift (x : ℕ∞) (h : x < ⊤) : ℕ := WithTop.untop x (WithTop.lt_top_iff lift ofNat(n) (WithTop.coe_lt_top n) = OfNat.ofNat n := rfl @[simp] theorem add_lt_top {a b : ℕ∞} : a + b < ⊤ ↔ a < ⊤ ∧ b < ⊤ := WithTop.add_lt_top +@[simp] theorem add_eq_top {a b : ℕ∞} : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := WithTop.add_eq_top @[simp] theorem lift_add (a b : ℕ∞) (h : a + b < ⊤) : lift (a + b) h = lift a (add_lt_top.1 h).1 + lift b (add_lt_top.1 h).2 := by diff --git a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean index 1f341c7e4489b8..fd3269e6bc03fa 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean @@ -188,7 +188,6 @@ lemma netMaxcard_univ (T : X → X) (h : F.Nonempty) (n : ℕ) : netMaxcard T F refine Finset.card_le_one.2 fun x x_s y y_s ↦ ?_ exact PairwiseDisjoint.elim_set s_net x_s y_s x (mem_univ x) (mem_univ x) -set_option backward.isDefEq.respectTransparency false in lemma netMaxcard_infinite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : ℕ) : netMaxcard T F U n = ⊤ ↔ ∀ k : ℕ, ∃ s : Finset X, IsDynNetIn T F U n s ∧ k ≤ s.card := by apply Iff.intro <;> intro h @@ -198,11 +197,11 @@ lemma netMaxcard_infinite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : simp only [Nat.cast_lt, Subtype.exists, exists_prop] at h obtain ⟨s, s_net, s_k⟩ := h exact ⟨s, s_net, s_k.le⟩ - · refine WithTop.eq_top_iff_forall_gt.2 fun k ↦ ?_ + · refine ENat.eq_top_iff_forall_gt.mpr fun k ↦ ?_ specialize h (k + 1) obtain ⟨s, s_net, s_card⟩ := h apply s_net.card_le_netMaxcard.trans_lt' - rw [ENat.some_eq_coe, Nat.cast_lt] + rw [ENat.coe_lt_coe] exact (lt_add_one k).trans_le s_card lemma netMaxcard_le_coverMincard (T : X → X) (F : Set X) (n : ℕ) : diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index f4b52ff1919234..cf440202db633a 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -558,14 +558,13 @@ theorem length_quotient_pow_maximalIdeal (n : ℕ) : end -set_option backward.isDefEq.respectTransparency false in instance (R : Type*) [CommRing R] [IsDomain R] [IsDiscreteValuationRing R] : IsHausdorff (maximalIdeal R) R where haus' x hx := by obtain ⟨ϖ, hϖ⟩ := exists_irreducible R simp only [← Ideal.one_eq_top, smul_eq_mul, mul_one, SModEq.zero, hϖ.maximalIdeal_eq, Ideal.span_singleton_pow, Ideal.mem_span_singleton, ← addVal_le_iff_dvd, hϖ.addVal_pow] at hx - rwa [← addVal_eq_top_iff, WithTop.eq_top_iff_forall_ge] + rwa [← addVal_eq_top_iff, ENat.eq_top_iff_forall_ge] noncomputable section toEuclideanDomain variable {R : Type*} [CommRing R] [IsDomain R] [IsDiscreteValuationRing R] diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index 3ae9ebb2cb3780..a601027c1f34ef 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -689,7 +689,6 @@ theorem multiplicity_mul {p a b : α} (hp : Prime p) (hfin : FiniteMultiplicity rw [hfin.multiplicity_eq_iff] exact ⟨hdiv, hsucc⟩ -set_option backward.isDefEq.respectTransparency false in theorem emultiplicity_mul {p a b : α} (hp : Prime p) : emultiplicity p (a * b) = emultiplicity p a + emultiplicity p b := by by_cases hfin : FiniteMultiplicity p (a * b) @@ -697,7 +696,7 @@ theorem emultiplicity_mul {p a b : α} (hp : Prime p) : hfin.mul_right.emultiplicity_eq_multiplicity] norm_cast exact multiplicity_mul hp hfin - · rw [emultiplicity_eq_top.2 hfin, eq_comm, WithTop.add_eq_top, emultiplicity_eq_top, + · rw [emultiplicity_eq_top.mpr hfin, eq_comm, ENat.add_eq_top, emultiplicity_eq_top, emultiplicity_eq_top] simpa only [FiniteMultiplicity.mul_iff hp, not_and_or] using hfin diff --git a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean index bf20bae55d0e2e..fb8aabcebe768f 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean @@ -284,7 +284,6 @@ If `x` is not a non zero divisor, `ordMonoidWithZeroHom` is equal to `0`. theorem ordMonoidWithZeroHom_eq_zero [Nontrivial R] {x : R} (h : x ∉ nonZeroDivisors R) : ordMonoidWithZeroHom R x = 0 := dif_neg h -set_option backward.isDefEq.respectTransparency false in /-- The quotient of a Noetherian ring of krull dimension less than or equal to `1` by a principal ideal is of finite length. @@ -297,8 +296,7 @@ theorem _root_.isFiniteLength_quotient_span_singleton [IsNoetherianRing R] ⟨isNoetherian_quotient (Ideal.span {x}), isArtinian_of_surjective_algebraMap (Ideal.Quotient.mk_surjective (I := .span {x}))⟩ rw [isArtinianRing_iff_krullDimLE_zero, Ring.KrullDimLE, Order.krullDimLE_iff, - ← WithBot.add_le_add_iff_right' (c := 1) (by simp) (WithBot.coe_eq_coe.not.mpr (by simp)), - Nat.cast_zero, zero_add] + ← ENat.WithBot.add_le_add_one_right_iff, Nat.cast_zero, zero_add] exact (ringKrullDim_quotient_succ_le_of_nonZeroDivisor hx).trans (Order.KrullDimLE.krullDim_le) variable [IsNoetherianRing R] [Ring.KrullDimLE 1 R] diff --git a/Mathlib/Topology/Instances/ENat.lean b/Mathlib/Topology/Instances/ENat.lean index 7a04848b12d4fd..e60bfbe1582e96 100644 --- a/Mathlib/Topology/Instances/ENat.lean +++ b/Mathlib/Topology/Instances/ENat.lean @@ -69,11 +69,11 @@ theorem tendsto_natCast_nhds_top : Tendsto Nat.cast atTop (𝓝 (⊤ : ℕ∞)) filter_upwards [eventually_ge_atTop (n + 1)] with a ha using by simpa instance : ContinuousAdd ℕ∞ := by - refine ⟨continuous_iff_continuousAt.2 fun (a, b) ↦ ?_⟩ + refine ⟨continuous_iff_continuousAt.mpr fun (a, b) ↦ ?_⟩ match a, b with | ⊤, _ => exact tendsto_nhds_top_mono' continuousAt_fst fun p ↦ le_add_right le_rfl | (a : ℕ), ⊤ => exact tendsto_nhds_top_mono' continuousAt_snd fun p ↦ le_add_left le_rfl - | (a : ℕ), (b : ℕ) => simp [ContinuousAt, nhds_prod_eq, tendsto_pure_nhds] + | (a : ℕ), (b : ℕ) => simp [ContinuousAt, nhds_prod_eq] instance : ContinuousMul ℕ∞ where continuous_mul := From 8bba4200986270d3b30be2bb2f8840af47a7854f Mon Sep 17 00:00:00 2001 From: Salvatore Mercuri <47568553+smmercuri@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:13:21 +0000 Subject: [PATCH 0705/1300] refactor(NumberTheory): make `adicCompletion` a one-field structure (#41526) `adicCompletion` as an `abbrev` is causing slowdown in FLT. --- .../NumberField/Completion/FinitePlace.lean | 3 +- .../Padics/HeightOneSpectrum.lean | 20 +- .../DedekindDomain/AdicValuation.lean | 261 ++++++++++++++++-- .../DedekindDomain/FiniteAdeleRing.lean | 10 +- Mathlib/RingTheory/LaurentSeries.lean | 84 +++--- 5 files changed, 301 insertions(+), 77 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean index 4241695e4ee78e..2d4baf22f6d9b5 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean @@ -93,7 +93,8 @@ variable {K : Type*} [Field K] {R : Type*} [CommRing R] [Algebra R K] [IsDedekin /-- The embedding of a field inside its `adicCompletion` with respect to `v`. -/ noncomputable def FinitePlace.embedding : K →+* adicCompletion K v := - UniformSpace.Completion.coeRingHom.comp (WithVal.equiv (v.valuation K)).symm + (adicCompletion.equiv K v).symm.toRingHom.comp + (UniformSpace.Completion.coeRingHom.comp (WithVal.equiv (v.valuation K)).symm) theorem FinitePlace.embedding_apply (x : K) : embedding v x = ↑x := rfl diff --git a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean index 3423a432f69de3..ecb2fe4fb4f2a0 100644 --- a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean +++ b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean @@ -145,22 +145,30 @@ noncomputable def withValEquiv (v : HeightOneSpectrum R) : /-- The continuous `ℚ`-algebra isomorphism between `v.adicCompletion ℚ` and `ℚ_[primesEquiv v]`. -/ noncomputable def adicCompletion.padicEquiv (v : HeightOneSpectrum R) : v.adicCompletion ℚ ≃A[ℚ] ℚ_[primesEquiv v] where - __ := (mapRingEquiv _ (withValEquiv v).continuous + __ := (IsDedekindDomain.HeightOneSpectrum.adicCompletion.equiv ℚ v).trans <| + (mapRingEquiv _ (withValEquiv v).continuous (withValEquiv v).symm.continuous).trans Padic.withValRingEquiv - __ := ((mapEquiv (withValEquiv v)).trans Padic.withValUniformEquiv).toHomeomorph + __ := ((IsDedekindDomain.HeightOneSpectrum.adicCompletion.uniformEquiv ℚ v).trans <| + (mapEquiv (withValEquiv v)).trans Padic.withValUniformEquiv).toHomeomorph commutes' := by simp /-- The continuous `ℤ`-algebra isomorphism between `v.adicCompletionIntegers ℚ` and `ℤ_[primesEquiv v]`. -/ noncomputable def adicCompletionIntegers.padicIntEquiv (v : HeightOneSpectrum R) : v.adicCompletionIntegers ℚ ≃A[ℤ] ℤ_[primesEquiv v] where - __ := let e := (mapRingEquiv _ (withValEquiv v).continuous + __ := let e0 := (IsDedekindDomain.HeightOneSpectrum.adicCompletion.equiv ℚ v).restrict + (v.adicCompletionIntegers ℚ) + (Valued.v (R := (v.valuation ℚ).Completion)).valuationSubring + fun _ ↦ by rw [HeightOneSpectrum.mem_adicCompletionIntegers]; rfl + let e := (mapRingEquiv _ (withValEquiv v).continuous (withValEquiv v).symm.continuous).restrict _ _ fun _ ↦ by simpa using! (valuation_equiv_padicValuation v).valuedCompletion_le_one_iff - e.trans withValIntegersRingEquiv - __ := let e := (mapEquiv (withValEquiv v)).subtype fun _ ↦ by + (e0.trans e).trans withValIntegersRingEquiv + __ := let e0 := (IsDedekindDomain.HeightOneSpectrum.adicCompletion.uniformEquiv ℚ v).subtype + fun _ ↦ by rw [HeightOneSpectrum.mem_adicCompletionIntegers]; rfl + let e := (mapEquiv (withValEquiv v)).subtype fun _ ↦ by simpa using! (valuation_equiv_padicValuation v).valuedCompletion_le_one_iff - (e.trans withValIntegersUniformEquiv).toHomeomorph + ((e0.trans e).trans withValIntegersUniformEquiv).toHomeomorph commutes' := by simp /-- The diagram diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index 1d7727d67a78a9..d692d814ba6e86 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -600,26 +600,210 @@ theorem adicValued_apply' (x : WithVal (v.valuation K)) : variable (K) -/-- The completion of `K` with respect to its `v`-adic valuation. -/ -abbrev adicCompletion := (v.valuation K).Completion +/-- The completion of `K` with respect to its `v`-adic valuation, defined as a one-field structure +wrapping the uniform-space completion `(v.valuation K).Completion`. -/ +structure adicCompletion where + /-- Wrap an element of the underlying completion `(v.valuation K).Completion` into + `adicCompletion`. -/ + ofCompletion :: + /-- The underlying element of the completion `(v.valuation K).Completion`. -/ + toCompletion : (v.valuation K).Completion + +namespace adicCompletion + +open UniformSpace MonoidWithZeroHom MonoidWithZeroHom.ValueGroup₀ Filter Topology Valuation + +/-- `adicCompletion.toCompletion` and `adicCompletion.ofCompletion` as an equivalence. -/ +@[simps] +def equivCompletion : adicCompletion K v ≃ (v.valuation K).Completion where + toFun := toCompletion + invFun := ofCompletion + left_inv _ := rfl + right_inv _ := rfl + +noncomputable instance : Field (adicCompletion K v) := fast_instance% (equivCompletion K v).field + +/-- `adicCompletion.toCompletion` as a ring isomorphism onto the underlying completion. -/ +@[simps! apply] +def equiv : adicCompletion K v ≃+* (v.valuation K).Completion where + toEquiv := equivCompletion K v + map_mul' _ _ := rfl + map_add' _ _ := rfl + +@[simp] lemma toCompletion_ofCompletion (x : (v.valuation K).Completion) : + toCompletion (ofCompletion x : adicCompletion K v) = x := rfl +@[simp] lemma ofCompletion_toCompletion (x : adicCompletion K v) : + ofCompletion x.toCompletion = x := rfl + +@[simp] lemma toCompletion_zero : (0 : adicCompletion K v).toCompletion = 0 := rfl +@[simp] lemma toCompletion_one : (1 : adicCompletion K v).toCompletion = 1 := rfl +@[simp] lemma toCompletion_add (x y : adicCompletion K v) : + (x + y).toCompletion = x.toCompletion + y.toCompletion := rfl +@[simp] lemma toCompletion_mul (x y : adicCompletion K v) : + (x * y).toCompletion = x.toCompletion * y.toCompletion := rfl + +theorem toCompletion_surjective : Function.Surjective (toCompletion (K := K) (v := v)) := + (equivCompletion K v).surjective + +theorem ofCompletion_surjective : Function.Surjective (ofCompletion (K := K) (v := v)) := + (equivCompletion K v).symm.surjective + +noncomputable instance : UniformSpace (adicCompletion K v) := .comap toCompletion inferInstance + +theorem isUniformInducing_toCompletion : + IsUniformInducing (toCompletion (K := K) (v := v)) := ⟨rfl⟩ + +instance : IsUniformAddGroup (adicCompletion K v) := + IsUniformInducing.isUniformAddGroup (equiv K v).toRingHom (isUniformInducing_toCompletion K v) + +/-- The `v`-adic valuation on `adicCompletion K v`, transported from the completion along `equiv`. +-/ +noncomputable def valuation : Valuation (adicCompletion K v) ℤᵐ⁰ := + Valued.v.comap (equiv K v).toRingHom + +theorem valueGroup_eq : + valueGroup (.ofClass (valuation K v)) = + valueGroup (.ofClass (Valued.v : Valuation (v.valuation K).Completion ℤᵐ⁰)) := by + simp [valuation, valueGroup, valueMonoid, ← (toCompletion_surjective K v).range_comp]; rfl + +/-- The multiplicative equivalence between the value group of the completion's valuation, pulled +back along `equiv`, and that of the completion. -/ +def valueGroupEquiv : + valueGroup (.ofClass (valuation K v)) ≃* + valueGroup (.ofClass (Valued.v : Valuation (v.valuation K).Completion ℤᵐ⁰)) where + __ := Equiv.setCongr (by rw [valueGroup_eq K v]) + map_mul' _ _ := rfl + +@[simp] theorem coe_valueGroupEquiv (a : valueGroup (.ofClass (valuation K v))) : + ((valueGroupEquiv K v a : _) : ℤᵐ⁰ˣ) = a := rfl + +/-- The order-preserving multiplicative equivalence between the `ValueGroup₀` of the completion's +valuation, pulled back along `equiv`, and that of the completion. -/ +noncomputable def valueGroupOrderIso : + ValueGroup₀ (.ofClass (valuation K v)) ≃*o + ValueGroup₀ (.ofClass (Valued.v : Valuation (v.valuation K).Completion ℤᵐ⁰)) where + toFun := WithZero.map' (valueGroupEquiv K v) + invFun := WithZero.map' (valueGroupEquiv K v).symm + left_inv x := by match x with | 0 => simp | .coe a => simp + right_inv y := by match y with | 0 => simp | .coe b => simp + map_mul' := by simp + map_le_map_iff' {a b} := by + match a, b with + | 0, 0 => simp + | 0, .coe _ => simp + | .coe _, 0 => simp + | .coe a, .coe b => simp [← Subtype.coe_le_coe] + +@[simp] theorem coe_valueGroupOrderIso_coe (a : valueGroup (.ofClass (valuation K v))) : + valueGroupOrderIso K v (a : ValueGroup₀ _) = (valueGroupEquiv K v a : ValueGroup₀ _) := by + simp [valueGroupOrderIso] + +theorem embedding_valueGroupOrderIso (g : ValueGroup₀ (.ofClass (valuation K v))) : + embedding (valueGroupOrderIso K v g) = embedding g := by + match g with + | 0 => simp [valueGroupOrderIso] + | .coe a => simp [coe_valueGroupOrderIso_coe, embedding_apply, coe_valueGroupEquiv] + +theorem valueGroupOrderIso_restrict (x : adicCompletion K v) : + valueGroupOrderIso K v ((valuation K v).restrict x) = + Valued.v.restrict (toCompletion x) := by + apply embedding_strictMono.injective + rw [embedding_valueGroupOrderIso, embedding_restrict, embedding_restrict]; rfl + +noncomputable instance : Valued (adicCompletion K v) ℤᵐ⁰ where + v := valuation K v + is_topological_valuation s := by + rw [(isUniformInducing_toCompletion K v).isInducing.nhds_eq_comap 0, toCompletion_zero, + Filter.mem_comap] + refine ⟨fun ⟨t, ht, hts⟩ ↦ ?_, fun ⟨γ, hγ⟩ ↦ ?_⟩ + · obtain ⟨δ, hδ⟩ := Valued.mem_nhds_zero.1 ht + refine ⟨Units.mapEquiv (valueGroupOrderIso K v).symm.toMulEquiv δ, fun x hx ↦ hts (hδ ?_)⟩ + rw [Set.mem_setOf_eq] at hx ⊢ + simpa [← map_lt_map_iff (valueGroupOrderIso K v), valueGroupOrderIso_restrict] using hx + · refine ⟨{y | Valued.v.restrict y < ↑(Units.mapEquiv (valueGroupOrderIso K v).toMulEquiv γ)}, + ?_, fun x hx ↦ hγ ?_⟩ + · rw [Valued.mem_nhds_zero] + exact ⟨Units.mapEquiv (valueGroupOrderIso K v).toMulEquiv γ, subset_rfl⟩ + · rw [Set.mem_setOf_eq, ← map_lt_map_iff (valueGroupOrderIso K v), + valueGroupOrderIso_restrict] + simpa using hx + +noncomputable instance : CompleteSpace (adicCompletion K v) := + ((isUniformInducing_toCompletion K v).completeSpace_congr (toCompletion_surjective K v)).mpr + inferInstance + +/-- Coercion of an element of `WithVal (v.valuation K)` into the adic completion. -/ +instance : Coe (WithVal (v.valuation K)) (adicCompletion K v) where + coe x := ofCompletion (x : (v.valuation K).Completion) + +/-- Coercion of an element of `K` into the adic completion. -/ +instance (priority := 99) : Coe K (adicCompletion K v) where + coe k := ofCompletion (k : (v.valuation K).Completion) + +@[simp] lemma coe_toCompletion (k : K) : + (↑k : adicCompletion K v).toCompletion = (k : (v.valuation K).Completion) := rfl + +theorem valuedAdicCompletion_def {x : adicCompletion K v} : + Valued.v x = Valued.extensionValuation x.toCompletion := rfl + +@[simp] theorem valued_toCompletion (x : adicCompletion K v) : + Valued.v x.toCompletion = Valued.v x := rfl + +@[simp] theorem valued_ofCompletion (y : (v.valuation K).Completion) : + Valued.v (ofCompletion y : adicCompletion K v) = Valued.v y := rfl + +theorem valued_coe (k : K) : + Valued.v (↑k : adicCompletion K v) = v.valuation K k := by + simp + +@[ext] theorem ext {x y : adicCompletion K v} (h : x.toCompletion = y.toCompletion) : x = y := by + cases x; cases y; exact congrArg ofCompletion h + +@[norm_cast] lemma coe_zero : ((0 : K) : adicCompletion K v) = 0 := by + apply adicCompletion.ext; simp +@[norm_cast] lemma coe_one : ((1 : K) : adicCompletion K v) = 1 := by + apply adicCompletion.ext; simp +@[norm_cast] lemma coe_add (x y : K) : + ((x + y : K) : adicCompletion K v) = ↑x + ↑y := by + apply adicCompletion.ext; simp [UniformSpace.Completion.coe_add] +@[norm_cast] lemma coe_mul (x y : K) : + ((x * y : K) : adicCompletion K v) = ↑x * ↑y := by + apply adicCompletion.ext; simp [UniformSpace.Completion.coe_mul] + +/-- `toCompletion` as a uniform-space isomorphism onto the underlying completion. -/ +def uniformEquiv : adicCompletion K v ≃ᵤ (v.valuation K).Completion where + toEquiv := equivCompletion K v + uniformContinuous_toFun := uniformContinuous_comap + uniformContinuous_invFun := + (isUniformInducing_toCompletion K v).uniformContinuous_iff.mpr uniformContinuous_id + +theorem continuous_toCompletion : Continuous (toCompletion (K := K) (v := v)) := + (uniformEquiv K v).continuous -theorem valuedAdicCompletion_def {x : v.adicCompletion K} : - Valued.v x = Valued.extensionValuation x := rfl +theorem continuous_ofCompletion : Continuous (ofCompletion (K := K) (v := v)) := + (uniformEquiv K v).symm.continuous + +instance : T0Space (adicCompletion K v) := + (uniformEquiv K v).toHomeomorph.isEmbedding.t0Space + +end adicCompletion lemma valuedAdicCompletion_surjective : - Function.Surjective (Valued.v : (v.adicCompletion K) → ℤᵐ⁰) := - Valued.valuedCompletion_surjective_iff.mpr <| .of_comp (v.valuation_surjective K) + Function.Surjective (Valued.v : (v.adicCompletion K) → ℤᵐ⁰) := by + have h : Function.Surjective (Valued.v : (v.valuation K).Completion → ℤᵐ⁰) := + Valued.valuedCompletion_surjective_iff.mpr <| .of_comp (v.valuation_surjective K) + exact h.comp (adicCompletion.toCompletion_surjective K v) lemma adicCompletion_valueGroup_eq : MonoidWithZeroHom.valueGroup (.ofClass (Valued.v (R := adicCompletion K v))) = MonoidWithZeroHom.valueGroup (.ofClass (valuation K v)) := by ext n - simp only [MonoidWithZeroHom.mem_valueGroup_iff_of_comm, ne_eq, map_eq_zero] - refine ⟨fun ⟨a, ha0, x, hx⟩ ↦ ?_, fun ⟨a, ha0, x, hx⟩ ↦ ⟨a, by simp [ha0], x, by simpa using hx⟩⟩ + simp only [MonoidWithZeroHom.mem_valueGroup_iff_of_comm, ne_eq, MonoidWithZeroHom.coe_ofClass] + refine ⟨fun ⟨a, ha0, x, hx⟩ ↦ ?_, fun ⟨a, ha0, x, hx⟩ ↦ + ⟨↑a, by simpa using ha0, ↑x, by simpa using hx⟩⟩ obtain ⟨b, hb⟩ := valuation_surjective K v (Valued.v a) obtain ⟨y, hy⟩ := valuation_surjective K v (Valued.v x) - refine ⟨b, ?_, y, by simpa [hb, hy] using hx⟩ - rwa [← ne_eq, ← (valuation K v).ne_zero_iff, hb, Valuation.ne_zero_iff] + exact ⟨b, by rw [hb]; exact ha0, y, by rw [hb, hy]; exact hx⟩ /-- The ring of integers of `adicCompletion`. -/ def adicCompletionIntegers : ValuationSubring (v.adicCompletion K) := @@ -655,9 +839,10 @@ instance adicValued.uniformContinuousConstSMul : exact (Ring.uniformContinuousConstSMul (WithVal <| v.valuation K)).uniformContinuous_const_smul _ open UniformSpace in -instance : Algebra S (v.adicCompletion K) where +/-- The `S`-algebra structure on the underlying completion. -/ +noncomputable instance instAlgebraCompletion : Algebra S ((v.valuation K).Completion) where toSMul := Completion.instSMul _ _ - algebraMap := Completion.coeRingHom.comp (algebraMap _ _) + algebraMap := Completion.coeRingHom.comp (algebraMap S (WithVal (v.valuation K))) commutes' r x := by induction x using Completion.induction_on with | hp => @@ -671,22 +856,48 @@ instance : Algebra S (v.adicCompletion K) where simp [Algebra.smul_def, Completion.algebraMap_def, WithVal.algebraMap_right_apply, Completion.coeRingHom] +noncomputable instance : Algebra S (v.adicCompletion K) := + fast_instance% (adicCompletion.equivCompletion K v).algebra S + +theorem algebraMap_adicCompletion_toCompletion (r : S) : + (algebraMap S (v.adicCompletion K) r).toCompletion = + algebraMap S ((v.valuation K).Completion) r := rfl + +instance {S₀ : Type*} [CommSemiring S₀] [Algebra S₀ S] [Algebra S₀ K] [IsScalarTower S₀ S K] : + IsScalarTower S₀ S ((v.valuation K).Completion) := + .of_algebraMap_eq fun x ↦ by + exact congrArg (UniformSpace.Completion.coeRingHom (α := WithVal (v.valuation K))) + (IsScalarTower.algebraMap_apply S₀ S (WithVal (v.valuation K)) x) + +instance {S₀ : Type*} [CommSemiring S₀] [Algebra S₀ S] [Algebra S₀ K] [IsScalarTower S₀ S K] : + IsScalarTower S₀ S (v.adicCompletion K) := + .of_algebraMap_eq fun x ↦ by + apply adicCompletion.ext + rw [algebraMap_adicCompletion_toCompletion, algebraMap_adicCompletion_toCompletion, + IsScalarTower.algebraMap_apply S₀ S ((v.valuation K).Completion)] + theorem coe_smul_adicCompletion (r : S) (x : WithVal (v.valuation K)) : - (↑(r • x) : v.adicCompletion K) = r • (↑x : v.adicCompletion K) := - UniformSpace.Completion.coe_smul r x + (↑(r • x) : v.adicCompletion K) = r • (↑x : v.adicCompletion K) := by + apply adicCompletion.ext + exact UniformSpace.Completion.coe_smul r x theorem algebraMap_adicCompletion : ⇑(algebraMap S <| v.adicCompletion K) = (↑) ∘ algebraMap S K := rfl variable {R} in -theorem denseRange_algebraMap : DenseRange (algebraMap K (v.adicCompletion K)) := - UniformSpace.Completion.denseRange_coe.comp (WithVal.equiv _).symm.surjective.denseRange - (UniformSpace.Completion.continuous_coe _) +theorem denseRange_algebraMap : DenseRange (algebraMap K (v.adicCompletion K)) := by + rw [algebraMap_adicCompletion] + exact (adicCompletion.ofCompletion_surjective K v).denseRange.comp + (UniformSpace.Completion.denseRange_coe.comp (WithVal.equiv _).symm.surjective.denseRange + (UniformSpace.Completion.continuous_coe _)) + (adicCompletion.continuous_ofCompletion K v) end Algebra theorem coe_algebraMap_mem (r : R) : ↑((algebraMap R K) r) ∈ adicCompletionIntegers K v := by - rw [mem_adicCompletionIntegers, Valued.valuedCompletion_apply] + rw [mem_adicCompletionIntegers] + change Valued.v (↑((algebraMap R K) r) : adicCompletion K v).toCompletion ≤ 1 + rw [Valued.valuedCompletion_apply] simpa using v.valuation_le_one _ instance : Algebra R (v.adicCompletionIntegers K) where @@ -702,11 +913,11 @@ instance : Algebra R (v.adicCompletionIntegers K) where map_one' := by ext; simp map_mul' x y := by ext - simp only [map_mul, UniformSpace.Completion.coe_mul, MulMemClass.mk_mul_mk] + simp [map_mul, UniformSpace.Completion.coe_mul] map_zero' := by ext; simp map_add' x y := by ext - simp only [map_add, UniformSpace.Completion.coe_add, AddMemClass.mk_add_mk] } + simp [map_add, UniformSpace.Completion.coe_add] } commutes' r x := by rw [mul_comm] smul_def' r x := by @@ -730,14 +941,16 @@ open scoped algebraMap in -- to make the coercions from `R` fire /-- The valuation on the completion agrees with the global valuation on elements of the integer ring. -/ theorem valuedAdicCompletion_eq_valuation (r : R) : - Valued.v (r : v.adicCompletion K) = v.valuation K r := - Valued.valuedCompletion_apply _ + Valued.v (r : v.adicCompletion K) = v.valuation K r := by + rw [← adicCompletion.valued_toCompletion] + exact Valued.valuedCompletion_apply _ variable {R K} in /-- The valuation on the completion agrees with the global valuation on elements of the field. -/ theorem valuedAdicCompletion_eq_valuation' (k : K) : - Valued.v (k : v.adicCompletion K) = v.valuation K k := - Valued.valuedCompletion_apply _ + Valued.v (k : v.adicCompletion K) = v.valuation K k := by + rw [← adicCompletion.valued_toCompletion] + exact Valued.valuedCompletion_apply _ variable {R K} in open scoped algebraMap in -- to make the coercion from `R` fire diff --git a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean index 7f5ce30facd4e0..ff857b8f025943 100644 --- a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean +++ b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean @@ -115,12 +115,12 @@ all but finitely many places, which is `IsDedekindDomain.HeightOneSpectrum.Suppo protected def algebraMap : K →+* FiniteAdeleRing R K where toFun k := ⟨fun i ↦ k, by simp only [Filter.eventually_cofinite, SetLike.mem_coe, mem_adicCompletionIntegers R K, - adicCompletion, Valued.valuedCompletion_apply, not_le] + valuedAdicCompletion_eq_valuation', not_le] exact HeightOneSpectrum.Support.finite R k⟩ - map_one' := rfl - map_mul' x y := Subtype.ext <| funext fun _ ↦ UniformSpace.Completion.coe_mul _ _ - map_zero' := rfl - map_add' x y := Subtype.ext <| funext fun _ ↦ UniformSpace.Completion.coe_add _ _ + map_one' := Subtype.ext <| funext fun _ ↦ adicCompletion.coe_one .. + map_mul' x y := Subtype.ext <| funext fun _ ↦ adicCompletion.coe_mul .. + map_zero' := Subtype.ext <| funext fun _ ↦ adicCompletion.coe_zero .. + map_add' x y := Subtype.ext <| funext fun _ ↦ adicCompletion.coe_add .. instance : Algebra K (FiniteAdeleRing R K) := (FiniteAdeleRing.algebraMap R K).toAlgebra diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index 2de61dbc423458..86c866fe9a00d5 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -954,10 +954,20 @@ theorem uniformContinuous_withVal_equiv : theorem continuous_coe : Continuous ((↑) : K⟮X⟯ → K⸨X⸩) := (isUniformInducing_iff'.1 (inducing_coe)).1.continuous +variable (K) in +/-- An abbreviation for the `X`-adic completion of `K⟮X⟯` -/ +abbrev RatFuncAdicCompl := adicCompletion K⟮X⟯ (idealX K) + /-- The `X`-adic completion as an abstract completion of `K⟮X⟯` -/ abbrev ratfuncAdicComplPkg : AbstractCompletion (WithVal (polynomialValuationX K)) := UniformSpace.Completion.cPkg +instance : Field (ratfuncAdicComplPkg (K := K).space) := + inferInstanceAs (Field ((polynomialValuationX K).Completion)) + +instance : Valued (ratfuncAdicComplPkg (K := K).space) (WithZero (Multiplicative ℤ)) := + inferInstanceAs (Valued ((polynomialValuationX K).Completion) (WithZero (Multiplicative ℤ))) + variable (K) /-- Having established that the `K⸨X⸩` is complete and contains `K⟮X⟯` as a dense subspace, it gives rise to an abstract completion of `K⟮X⟯`. -/ @@ -990,41 +1000,29 @@ abbrev extensionAsRingHom := UniformSpace.Completion.extensionHom <| (algebraMap K⟮X⟯ K⸨X⸩).comp (WithVal.equiv (polynomialValuationX K)).toRingHom -/-- An abbreviation for the `X`-adic completion of `K⟮X⟯` -/ -abbrev RatFuncAdicCompl := adicCompletion K⟮X⟯ (idealX K) - -instance : Field (ratfuncAdicComplPkg (K := K).space) := - inferInstanceAs <| Field (RatFuncAdicCompl K) - --- help typeclass inference along -instance : Valued (ratfuncAdicComplPkg (K := K).space) (WithZero (Multiplicative ℤ)) := - inferInstanceAs <| Valued (RatFuncAdicCompl K) (WithZero (Multiplicative ℤ)) - /-! The two instances below make `comparePkg` and `comparePkg_eq_extension` slightly faster. -/ instance : UniformSpace (RatFuncAdicCompl K) := inferInstance instance : UniformSpace K⸨X⸩ := inferInstance /-- The uniform space isomorphism between two abstract completions of `ratfunc K` -/ abbrev comparePkg : RatFuncAdicCompl K ≃ᵤ K⸨X⸩ := - compareEquiv ratfuncAdicComplPkg (LaurentSeriesPkg K) + (adicCompletion.uniformEquiv _ _).trans <| compareEquiv ratfuncAdicComplPkg (LaurentSeriesPkg K) lemma comparePkg_eq_extension (x : RatFuncAdicCompl K) : - (comparePkg K) x = (extensionAsRingHom K (continuous_coe' _)) x := rfl + (comparePkg K) x = + (extensionAsRingHom K (continuous_coe' _)) (adicCompletion.toCompletion x) := rfl -/-- The uniform space equivalence between two abstract completions of `ratfunc K` as a ring -equivalence: this will be the *inverse* of the fundamental one. -/ +/-- The ring equivalence between `RatFuncAdicCompl K` and `K⸨X⸩`. -/ abbrev ratfuncAdicComplRingEquiv : RatFuncAdicCompl K ≃+* K⸨X⸩ := { comparePkg K with - map_mul' := by - intro x y - rw [Equiv.toFun_as_coe, UniformEquiv.coe_toEquiv, comparePkg_eq_extension, - (extensionAsRingHom K (continuous_coe' _)).map_mul] - simp [← comparePkg_eq_extension] - map_add' := by - intro x y - rw [Equiv.toFun_as_coe, UniformEquiv.coe_toEquiv, comparePkg_eq_extension, - (extensionAsRingHom K (continuous_coe' _)).map_add] - simp [← comparePkg_eq_extension] } + map_mul' x y := + (comparePkg_eq_extension K (x * y)).trans <| + (map_mul _ x.toCompletion y.toCompletion).trans <| + (congrArg₂ (· * ·) (comparePkg_eq_extension K x) (comparePkg_eq_extension K y)).symm + map_add' x y := + (comparePkg_eq_extension K (x + y)).trans <| + (map_add _ x.toCompletion y.toCompletion).trans <| + (congrArg₂ (· + ·) (comparePkg_eq_extension K x) (comparePkg_eq_extension K y)).symm } /-- The uniform space equivalence between two abstract completions of `ratfunc K` as a ring equivalence: it goes from `K⸨X⸩` to `RatFuncAdicCompl K` -/ @@ -1032,17 +1030,20 @@ abbrev LaurentSeriesRingEquiv : K⸨X⸩ ≃+* RatFuncAdicCompl K := (ratfuncAdicComplRingEquiv K).symm lemma LaurentSeriesRingEquiv_def (f : K⟦X⟧) : - (LaurentSeriesRingEquiv K) f = (LaurentSeriesPkg K).compare ratfuncAdicComplPkg (f : K⸨X⸩) := + (LaurentSeriesRingEquiv K) f = adicCompletion.ofCompletion + ((LaurentSeriesPkg K).compare ratfuncAdicComplPkg (f : K⸨X⸩)) := rfl @[simp] theorem ratfuncAdicComplRingEquiv_apply (x : RatFuncAdicCompl K) : - ratfuncAdicComplRingEquiv K x = ratfuncAdicComplPkg.compare (LaurentSeriesPkg K) x := rfl + ratfuncAdicComplRingEquiv K x = + ratfuncAdicComplPkg.compare (LaurentSeriesPkg K) (adicCompletion.toCompletion x) := rfl theorem coe_X_compare : (ratfuncAdicComplRingEquiv K) ((RatFunc.X : K⟮X⟯) : RatFuncAdicCompl K) = ((PowerSeries.X : K⟦X⟧) : K⸨X⸩) := by - rw [PowerSeries.coe_X, ← RatFunc.coe_X, ← LaurentSeries_coe, ← compare_coe] + rw [ratfuncAdicComplRingEquiv_apply, PowerSeries.coe_X, ← RatFunc.coe_X, ← LaurentSeries_coe, + ← compare_coe] rfl theorem algebraMap_apply (a : K) : algebraMap K K⸨X⸩ a = HahnSeries.C a := by @@ -1100,21 +1101,22 @@ theorem tendsto_valuation (a : (idealX K).adicCompletion K⟮X⟯) : /-- The extension of the `X`-adic valuation from `K⟮X⟯` up to its abstract completion coincides, modulo the isomorphism with `K⸨X⸩`, with the `X`-adic valuation on `K⸨X⸩`. -/ theorem valuation_compare (f : K⸨X⸩) : - (Valued.v : (RatFuncAdicCompl K) → ℤᵐ⁰) - (AbstractCompletion.compare (LaurentSeriesPkg K) ratfuncAdicComplPkg f) = - Valued.v f := by + Valued.v (LaurentSeriesRingEquiv K f) = Valued.v f := by + change Valued.v (adicCompletion.ofCompletion + ((LaurentSeriesPkg K).compare ratfuncAdicComplPkg f)) = Valued.v f + rw [adicCompletion.valued_ofCompletion] letI : UniformSpace (ratfuncAdicComplPkg (K := K).space) := ratfuncAdicComplPkg.uniformStruct + have raw_surj : Function.Surjective (Valued.v : (polynomialValuationX K).Completion → ℤᵐ⁰) := + Valued.valuedCompletion_surjective_iff.mpr <| .of_comp ((idealX K).valuation_surjective K⟮X⟯) rw [← valuation_LaurentSeries_equal_extension, ← compare_comp_eq_compare ratfuncAdicComplPkg _] · exact congr_fun (ratfuncAdicComplPkg.isDenseInducing.extend_unique - Valued.valuedCompletion_apply (Valued.continuous_valuation_of_surjective - (valuedAdicCompletion_surjective _ _))).symm _ + Valued.valuedCompletion_apply (Valued.continuous_valuation_of_surjective raw_surj)).symm _ · refine Valued.continuous_valuation_of_surjective (fun x ↦ ?_) obtain ⟨y, rfl⟩ := RatFunc.valuation_surjective K x exact ⟨.toVal _ y, rfl⟩ · intro x - have h_cont := Valued.continuous_valuation_of_surjective - (valuedAdicCompletion_surjective K⟮X⟯ (idealX K)) + have h_cont := Valued.continuous_valuation_of_surjective raw_surj rw [ratfuncAdicComplPkg.isDenseInducing.extend_unique Valued.valuedCompletion_apply h_cont] exact (h_cont.continuousAt.tendsto.comp tendsto_comap).congr @@ -1145,8 +1147,7 @@ lemma powerSeriesEquivSubring_coe_apply (f : K⟦X⟧) : completion of `K⟮X⟯`. -/ theorem mem_integers_of_powerSeries (F : K⟦X⟧) : (LaurentSeriesRingEquiv K) F ∈ (idealX K).adicCompletionIntegers K⟮X⟯ := by - simp only [mem_adicCompletionIntegers, LaurentSeriesRingEquiv_def, - valuation_compare, val_le_one_iff_eq_coe] + rw [mem_adicCompletionIntegers, valuation_compare, val_le_one_iff_eq_coe] exact ⟨F, rfl⟩ /-- Conversely, all elements in the unit ball inside the completion of `K⟮X⟯` come from a power @@ -1155,10 +1156,11 @@ theorem exists_powerSeries_of_memIntegers {x : RatFuncAdicCompl K} (hx : x ∈ (idealX K).adicCompletionIntegers K⟮X⟯) : ∃ F : K⟦X⟧, (LaurentSeriesRingEquiv K) F = x := by set f := (ratfuncAdicComplRingEquiv K) x with hf - have H_x : (LaurentSeriesPkg K).compare ratfuncAdicComplPkg ((ratfuncAdicComplRingEquiv K) x) = - x := congr_fun (inverse_compare (LaurentSeriesPkg K) ratfuncAdicComplPkg) x - rw [mem_adicCompletionIntegers, ← H_x] at hx - obtain ⟨F, hF⟩ := (val_le_one_iff_eq_coe K f).mp (valuation_compare _ f ▸ hx) + have hval : Valued.v f ≤ 1 := by + rw [← valuation_compare (K := K) f, hf, RingEquiv.symm_apply_apply, + ← mem_adicCompletionIntegers] + exact hx + obtain ⟨F, hF⟩ := (val_le_one_iff_eq_coe K f).mp hval exact ⟨F, by rw [hF, hf, RingEquiv.symm_apply_apply]⟩ theorem powerSeries_ext_subring : @@ -1185,7 +1187,7 @@ lemma powerSeriesRingEquiv_coe_apply (f : K⟦X⟧) : lemma LaurentSeriesRingEquiv_mem_valuationSubring (f : K⟦X⟧) : LaurentSeriesRingEquiv K f ∈ Valued.v.valuationSubring := by simp only [Valuation.mem_valuationSubring_iff] - rw [LaurentSeriesRingEquiv_def, valuation_compare, val_le_one_iff_eq_coe] + rw [valuation_compare, val_le_one_iff_eq_coe] use f lemma algebraMap_C_mem_adicCompletionIntegers (x : K) : From 6972320261af03f26653613660363d5a1997fa06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 9 Jul 2026 14:40:15 +0000 Subject: [PATCH 0706/1300] feat(MeasureTheory): mass of `count.real` (#40367) From MeanFourier --- Mathlib.lean | 1 + Mathlib/Data/Real/ENatENNReal.lean | 2 ++ Mathlib/MeasureTheory/Measure/Count.lean | 7 +++++++ Mathlib/RingTheory/Length.lean | 4 +--- Mathlib/SetTheory/Cardinal/ENNReal.lean | 22 ++++++++++++++++++++++ Mathlib/SetTheory/Cardinal/Finite.lean | 5 +++-- 6 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 Mathlib/SetTheory/Cardinal/ENNReal.lean diff --git a/Mathlib.lean b/Mathlib.lean index bf4256c6cb96b2..3396763a6940e6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7148,6 +7148,7 @@ public import Mathlib.SetTheory.Cardinal.Continuum public import Mathlib.SetTheory.Cardinal.CountableCover public import Mathlib.SetTheory.Cardinal.Defs public import Mathlib.SetTheory.Cardinal.Divisibility +public import Mathlib.SetTheory.Cardinal.ENNReal public import Mathlib.SetTheory.Cardinal.ENat public import Mathlib.SetTheory.Cardinal.Embedding public import Mathlib.SetTheory.Cardinal.EventuallyConst diff --git a/Mathlib/Data/Real/ENatENNReal.lean b/Mathlib/Data/Real/ENatENNReal.lean index b72d5b91573df8..9883f52e698c25 100644 --- a/Mathlib/Data/Real/ENatENNReal.lean +++ b/Mathlib/Data/Real/ENatENNReal.lean @@ -87,6 +87,8 @@ theorem toENNReal_strictMono : StrictMono ((↑) : ℕ∞ → ℝ≥0∞) := theorem toENNReal_zero : ((0 : ℕ∞) : ℝ≥0∞) = 0 := map_zero toENNRealRingHom +@[simp] lemma toENNReal_eq_zero : toENNReal n = 0 ↔ n = 0 := by rw [← toENNReal_zero, toENNReal_inj] + @[simp, norm_cast] theorem toENNReal_add (m n : ℕ∞) : ↑(m + n) = (m + n : ℝ≥0∞) := map_add toENNRealRingHom m n diff --git a/Mathlib/MeasureTheory/Measure/Count.lean b/Mathlib/MeasureTheory/Measure/Count.lean index da9b3412674521..ab77e21937e97d 100644 --- a/Mathlib/MeasureTheory/Measure/Count.lean +++ b/Mathlib/MeasureTheory/Measure/Count.lean @@ -7,6 +7,8 @@ module public import Mathlib.MeasureTheory.Measure.Dirac +import Mathlib.SetTheory.Cardinal.ENNReal + /-! # Counting measure @@ -162,6 +164,11 @@ instance count.isFiniteMeasure [Finite α] : @[simp] lemma count_univ : count (univ : Set α) = ENat.card α := by simp [count_apply .univ, encard_univ] +@[simp] lemma count_real_univ : count.real (.univ : Set α) = Nat.card α := by simp [Measure.real] + +instance neZero_count [Nonempty α] : NeZero (count : Measure α) where + out := by rintro h; simpa using congr($h .univ) + lemma _root_.Subsingleton.count_eq_dirac [Subsingleton α] (i : α) : count = dirac i := by calc count diff --git a/Mathlib/RingTheory/Length.lean b/Mathlib/RingTheory/Length.lean index f62d99504fc47d..002d65e28c0f45 100644 --- a/Mathlib/RingTheory/Length.lean +++ b/Mathlib/RingTheory/Length.lean @@ -264,9 +264,7 @@ lemma Module.length_of_free [Module.Free R M] : nontriviality R nontriviality M by_cases H : Module.length R R = ⊤ - · rw [b.repr.length_eq, Module.length_finsupp, H, ENat.mul_top', ENat.mul_top'] - congr 1 - simp [ENat.card_eq_zero_iff_empty, rank_pos_of_free.ne'] + · simp [b.repr.length_eq, H, rank_pos_of_free.ne'] rw [← ne_eq, Module.length_ne_top_iff, isFiniteLength_iff_isNoetherian_isArtinian] at H cases H let b := Module.Free.chooseBasis R M diff --git a/Mathlib/SetTheory/Cardinal/ENNReal.lean b/Mathlib/SetTheory/Cardinal/ENNReal.lean new file mode 100644 index 00000000000000..677a97fa4318ef --- /dev/null +++ b/Mathlib/SetTheory/Cardinal/ENNReal.lean @@ -0,0 +1,22 @@ +/- +Copyright (c) 2026 Yaël Dillies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies +-/ +module + +public import Mathlib.Data.Real.ENatENNReal +public import Mathlib.SetTheory.Cardinal.NatCard + +/-! +# Lemmas about `Nat.card` and `ENNReal` +-/ + +public section + +namespace ENNReal + +@[simp] lemma toReal_enatCard (α : Type*) : ENNReal.toReal (ENat.card α) = Nat.card α := by + cases finite_or_infinite α <;> simp [ENat.card_eq_coe_natCard] + +end ENNReal diff --git a/Mathlib/SetTheory/Cardinal/Finite.lean b/Mathlib/SetTheory/Cardinal/Finite.lean index e765a8b236bf85..4e24ecade762c3 100644 --- a/Mathlib/SetTheory/Cardinal/Finite.lean +++ b/Mathlib/SetTheory/Cardinal/Finite.lean @@ -352,14 +352,15 @@ theorem card_eq_zero_iff_empty (α : Type*) : card α = 0 ↔ IsEmpty α := by theorem card_ne_zero_iff_nonempty (α : Type*) : card α ≠ 0 ↔ Nonempty α := by simp [card_eq_zero_iff_empty] +@[simp] lemma card_ne_zero [Nonempty α] : card α ≠ 0 := (card_ne_zero_iff_nonempty _).2 ‹_› + theorem card_pos_iff_nonempty (α : Type*) : 0 < card α ↔ Nonempty α := by rw [pos_iff_ne_zero, card_ne_zero_iff_nonempty] theorem one_le_card_iff_nonempty (α : Type*) : 1 ≤ card α ↔ Nonempty α := by simp [Order.one_le_iff_ne_zero, card_eq_zero_iff_empty] -@[simp] lemma card_pos [Nonempty α] : 0 < card α := by - simpa [pos_iff_ne_zero, card_ne_zero_iff_nonempty] +@[simp] lemma card_pos [Nonempty α] : 0 < card α := by simp [pos_iff_ne_zero] theorem card_le_one_iff_subsingleton (α : Type*) : card α ≤ 1 ↔ Subsingleton α := by rw [← le_one_iff_subsingleton] From 89a18ed210e8f7a9f13f607f3492c40426d0fe56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 9 Jul 2026 14:40:17 +0000 Subject: [PATCH 0707/1300] chore: move `dualDistribEquiv` (#41535) This is in prevision of #41479 redefining it in terms of `homTensorHomEquiv`. Extracted by Claude Opus from #41479 Assisted-by: Claude Opus 4.8 --- .../BilinearForm/TensorProduct.lean | 1 + Mathlib/LinearAlgebra/Contraction.lean | 77 +++++++++++++++++++ Mathlib/LinearAlgebra/Dual/Lemmas.lean | 66 ---------------- 3 files changed, 78 insertions(+), 66 deletions(-) diff --git a/Mathlib/LinearAlgebra/BilinearForm/TensorProduct.lean b/Mathlib/LinearAlgebra/BilinearForm/TensorProduct.lean index 488f15bdb0aad4..0620d08694a4bc 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/TensorProduct.lean @@ -6,6 +6,7 @@ Authors: Eric Wieser module public import Mathlib.LinearAlgebra.BilinearForm.Hom +public import Mathlib.LinearAlgebra.Contraction public import Mathlib.LinearAlgebra.Dual.Lemmas public import Mathlib.LinearAlgebra.TensorProduct.Tower public import Mathlib.RingTheory.TensorProduct.Finite diff --git a/Mathlib/LinearAlgebra/Contraction.lean b/Mathlib/LinearAlgebra/Contraction.lean index 8f247cdbdc15bc..228d8e3ba8c286 100644 --- a/Mathlib/LinearAlgebra/Contraction.lean +++ b/Mathlib/LinearAlgebra/Contraction.lean @@ -274,3 +274,80 @@ theorem homTensorHomEquiv_apply (x : (M →ₗ[R] P) ⊗[R] (N →ₗ[R] Q)) : end CommSemiring end HomTensorHom + +namespace TensorProduct + +open LinearMap Module + +variable {R M N : Type*} {ι κ : Type*} +variable [DecidableEq ι] [DecidableEq κ] +variable [Fintype ι] [Fintype κ] + +attribute [local ext] TensorProduct.ext + +variable [CommSemiring R] [AddCommMonoid M] [AddCommMonoid N] +variable [Module R M] [Module R N] + +/-- An inverse to `TensorProduct.dualDistrib` given bases. +-/ +noncomputable def dualDistribInvOfBasis (b : Basis ι R M) (c : Basis κ R N) : + Dual R (M ⊗[R] N) →ₗ[R] Dual R M ⊗[R] Dual R N := + ∑ i, ∑ j, + (ringLmapEquivSelf R ℕ _).symm (b.dualBasis i ⊗ₜ c.dualBasis j) ∘ₗ + applyₗ (c j) ∘ₗ applyₗ (b i) ∘ₗ lcurry (.id R) M N R + +@[simp] +theorem dualDistribInvOfBasis_apply (b : Basis ι R M) (c : Basis κ R N) (f : Dual R (M ⊗[R] N)) : + dualDistribInvOfBasis b c f = ∑ i, ∑ j, f (b i ⊗ₜ c j) • b.dualBasis i ⊗ₜ c.dualBasis j := by + simp [dualDistribInvOfBasis] + +theorem dualDistrib_dualDistribInvOfBasis_left_inverse (b : Basis ι R M) (c : Basis κ R N) : + comp (dualDistrib R M N) (dualDistribInvOfBasis b c) = LinearMap.id := by + apply (b.tensorProduct c).dualBasis.ext + rintro ⟨i, j⟩ + apply (b.tensorProduct c).ext + rintro ⟨i', j'⟩ + simp only [dualDistrib, Basis.coe_dualBasis, coe_comp, Function.comp_apply, + dualDistribInvOfBasis_apply, Basis.coord_apply, Basis.tensorProduct_repr_tmul_apply, + Basis.repr_self, _root_.map_sum, map_smul, homTensorHomMap_apply, compRight_apply, + Basis.tensorProduct_apply, LinearMap.coe_sum, Finset.sum_apply, smul_apply, LinearEquiv.coe_coe, + map_tmul, lid_tmul, smul_eq_mul, id_coe, id_eq] + rw [Finset.sum_eq_single i, Finset.sum_eq_single j] + · simpa using mul_comm _ _ + all_goals { intros; simp [*] at * } + +theorem dualDistrib_dualDistribInvOfBasis_right_inverse (b : Basis ι R M) (c : Basis κ R N) : + comp (dualDistribInvOfBasis b c) (dualDistrib R M N) = LinearMap.id := by + apply (b.dualBasis.tensorProduct c.dualBasis).ext + rintro ⟨i, j⟩ + simp only [Basis.tensorProduct_apply, Basis.coe_dualBasis, coe_comp, Function.comp_apply, + dualDistribInvOfBasis_apply, dualDistrib_apply, Basis.coord_apply, Basis.repr_self, + id_coe, id_eq] + rw [Finset.sum_eq_single i, Finset.sum_eq_single j] + · simp + all_goals { intros; simp [*] at * } + +/-- A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` given bases for `M` and `N`. +It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural +isomorphism `R ⊗ R ≃ R`. +-/ +@[simps!] +noncomputable def dualDistribEquivOfBasis (b : Basis ι R M) (c : Basis κ R N) : + Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) := by + refine LinearEquiv.ofLinear (dualDistrib R M N) (dualDistribInvOfBasis b c) ?_ ?_ + · exact dualDistrib_dualDistribInvOfBasis_left_inverse _ _ + · exact dualDistrib_dualDistribInvOfBasis_right_inverse _ _ + +variable (R M N) +variable [Module.Finite R M] [Module.Finite R N] [Module.Free R M] [Module.Free R N] + +/-- +A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` when `M` and `N` are finite free +modules. It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural +isomorphism `R ⊗ R ≃ R`. +-/ +@[simp] +noncomputable def dualDistribEquiv : Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) := + dualDistribEquivOfBasis (Module.Free.chooseBasis R M) (Module.Free.chooseBasis R N) + +end TensorProduct diff --git a/Mathlib/LinearAlgebra/Dual/Lemmas.lean b/Mathlib/LinearAlgebra/Dual/Lemmas.lean index 5e885ee7021604..c2415b5462af86 100644 --- a/Mathlib/LinearAlgebra/Dual/Lemmas.lean +++ b/Mathlib/LinearAlgebra/Dual/Lemmas.lean @@ -1126,70 +1126,4 @@ theorem dualDistrib_apply (f : Dual A M) (g : Dual R N) (m : M) (n : N) : end AlgebraTensorModule -variable {R M N} -variable [CommSemiring R] [AddCommMonoid M] [AddCommMonoid N] -variable [Module R M] [Module R N] - -/-- An inverse to `TensorProduct.dualDistrib` given bases. --/ -noncomputable def dualDistribInvOfBasis (b : Basis ι R M) (c : Basis κ R N) : - Dual R (M ⊗[R] N) →ₗ[R] Dual R M ⊗[R] Dual R N := - ∑ i, ∑ j, - (ringLmapEquivSelf R ℕ _).symm (b.dualBasis i ⊗ₜ c.dualBasis j) ∘ₗ - applyₗ (c j) ∘ₗ applyₗ (b i) ∘ₗ lcurry (.id R) M N R - -@[simp] -theorem dualDistribInvOfBasis_apply (b : Basis ι R M) (c : Basis κ R N) (f : Dual R (M ⊗[R] N)) : - dualDistribInvOfBasis b c f = ∑ i, ∑ j, f (b i ⊗ₜ c j) • b.dualBasis i ⊗ₜ c.dualBasis j := by - simp [dualDistribInvOfBasis] - -theorem dualDistrib_dualDistribInvOfBasis_left_inverse (b : Basis ι R M) (c : Basis κ R N) : - comp (dualDistrib R M N) (dualDistribInvOfBasis b c) = LinearMap.id := by - apply (b.tensorProduct c).dualBasis.ext - rintro ⟨i, j⟩ - apply (b.tensorProduct c).ext - rintro ⟨i', j'⟩ - simp only [dualDistrib, Basis.coe_dualBasis, coe_comp, Function.comp_apply, - dualDistribInvOfBasis_apply, Basis.coord_apply, Basis.tensorProduct_repr_tmul_apply, - Basis.repr_self, _root_.map_sum, map_smul, homTensorHomMap_apply, compRight_apply, - Basis.tensorProduct_apply, LinearMap.coe_sum, Finset.sum_apply, smul_apply, LinearEquiv.coe_coe, - map_tmul, lid_tmul, smul_eq_mul, id_coe, id_eq] - rw [Finset.sum_eq_single i, Finset.sum_eq_single j] - · simpa using mul_comm _ _ - all_goals { intros; simp [*] at * } - -theorem dualDistrib_dualDistribInvOfBasis_right_inverse (b : Basis ι R M) (c : Basis κ R N) : - comp (dualDistribInvOfBasis b c) (dualDistrib R M N) = LinearMap.id := by - apply (b.dualBasis.tensorProduct c.dualBasis).ext - rintro ⟨i, j⟩ - simp only [Basis.tensorProduct_apply, Basis.coe_dualBasis, coe_comp, Function.comp_apply, - dualDistribInvOfBasis_apply, dualDistrib_apply, Basis.coord_apply, Basis.repr_self, - id_coe, id_eq] - rw [Finset.sum_eq_single i, Finset.sum_eq_single j] - · simp - all_goals { intros; simp [*] at * } - -/-- A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` given bases for `M` and `N`. -It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural -isomorphism `R ⊗ R ≃ R`. --/ -@[simps!] -noncomputable def dualDistribEquivOfBasis (b : Basis ι R M) (c : Basis κ R N) : - Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) := by - refine LinearEquiv.ofLinear (dualDistrib R M N) (dualDistribInvOfBasis b c) ?_ ?_ - · exact dualDistrib_dualDistribInvOfBasis_left_inverse _ _ - · exact dualDistrib_dualDistribInvOfBasis_right_inverse _ _ - -variable (R M N) -variable [Module.Finite R M] [Module.Finite R N] [Module.Free R M] [Module.Free R N] - -/-- -A linear equivalence between `Dual M ⊗ Dual N` and `Dual (M ⊗ N)` when `M` and `N` are finite free -modules. It sends `f ⊗ g` to the composition of `TensorProduct.map f g` with the natural -isomorphism `R ⊗ R ≃ R`. --/ -@[simp] -noncomputable def dualDistribEquiv : Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) := - dualDistribEquivOfBasis (Module.Free.chooseBasis R M) (Module.Free.chooseBasis R N) - end TensorProduct From 8f56b705808633e8e50b8d63c3616e985e42bfe2 Mon Sep 17 00:00:00 2001 From: Arnoud van der Leer <6382058+arnoudvanderleer@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:29:26 +0000 Subject: [PATCH 0708/1300] feat(AlgebraicTopology/SimplicialSet): define isomorphisms in simplicial sets, and the coherent isomorphism simplicial set (#35287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit show that any edge in a simplicial set, that is the image of the forward edge of the coherent isomorphism under a simplicial set morphism, is an isomorphism. Co-authored-by: Dagur Asgeirsson Co-authored-by: Joël Riou <37772949+joelriou@users.noreply.github.com> --- Mathlib.lean | 2 + .../SimplicialSet/CoherentIso.lean | 197 ++++++++++++++++++ .../SimplicialSet/CompStruct.lean | 92 +++++++- .../SimplicialSet/NerveCodiscrete.lean | 42 ++++ .../CategoryTheory/CodiscreteCategory.lean | 21 ++ 5 files changed, 352 insertions(+), 2 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/NerveCodiscrete.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3396763a6940e6..b51d41f92d98c8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1581,6 +1581,7 @@ public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.UnionPro public import Mathlib.AlgebraicTopology.SimplicialSet.Basic public import Mathlib.AlgebraicTopology.SimplicialSet.Boundary public import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations +public import Mathlib.AlgebraicTopology.SimplicialSet.CoherentIso public import Mathlib.AlgebraicTopology.SimplicialSet.CompStruct public import Mathlib.AlgebraicTopology.SimplicialSet.CompStructTruncated public import Mathlib.AlgebraicTopology.SimplicialSet.Coskeletal @@ -1604,6 +1605,7 @@ public import Mathlib.AlgebraicTopology.SimplicialSet.Monoidal public import Mathlib.AlgebraicTopology.SimplicialSet.Monomorphisms public import Mathlib.AlgebraicTopology.SimplicialSet.Nerve public import Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction +public import Mathlib.AlgebraicTopology.SimplicialSet.NerveCodiscrete public import Mathlib.AlgebraicTopology.SimplicialSet.NerveNondegenerate public import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplices public import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplicesColimit diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean b/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean new file mode 100644 index 00000000000000..506e6a780ce410 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean @@ -0,0 +1,197 @@ +/- +Copyright (c) 2026 Johns Hopkins Category Theory Seminar. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johns Hopkins Category Theory Seminar, Arnoud van der Leer +-/ +module + +public import Mathlib.AlgebraicTopology.SimplicialSet.CompStruct +public import Mathlib.AlgebraicTopology.SimplicialSet.NerveCodiscrete +public import Mathlib.AlgebraicTopology.SimplicialSet.StrictSegal +public import Mathlib.CategoryTheory.CodiscreteCategory + +/-! +# The Coherent Isomorphism + +We define the free walking isomorphism `WalkingIso`; the category with objects `zero` and +`one` and unique morphisms `zero ⟶ one` and `one ⟶ zero`. We construct an equivalence +`WalkingIso.equiv` between the type of functors from `WalkingIso` into any category `C` and the type +`Σ (X : C) (Y : C), (X ≅ Y)` of isomorphisms in that category. + +The simplicial set `SSet.coherentIso` is defined as the nerve of `WalkingIso`, with +`coherentIso.x₀` and `coherentIso.x₁` the `0`-simplices corresponding to `WalkingIso.zero` +and `WalkingIso.one` respectively, and `coherentIso.hom : Edge x₀ x₁` and +`coherentIso.inv : Edge x₁ x₀` forward and backward edges corresponding to the morphisms in +`WalkingIso`. Given any simplicial set `X`, with a morphism `g : coherentIso ⟶ X`, `0`-simplices +`x₀ x₁: X _⦋0⦌` and an edge between them `f : Edge x₀ x₁`, such that `g` sends `coherentIso.hom` to +`f`, then `f` has an inverse (in the sense of `Edge.InvStruct`), see `invStructOfEqMapHom`. + +-/ + +@[expose] public section + +universe w u v + +open CategoryTheory + +namespace CategoryTheory + +/-- This is the free-living isomorphism as the codiscrete category on `Bool`. -/ +abbrev WalkingIso : Type w := Codiscrete (ULift Bool) + +namespace WalkingIso + +/-- The underlying type of `WalkingIso` is equivalent to `Bool`, since they both have 2 elements. -/ +def equivBool : WalkingIso.{w} ≃ Bool := codiscreteEquiv.trans Equiv.ulift + +section + +variable {C : Type u} [Category.{v} C] + +/-- The domain of the isomorphism -/ +def zero : WalkingIso.{w} := .mk (.up false) + +/-- The codomain of the isomorphism -/ +def one : WalkingIso.{w} := .mk (.up true) + +/-- The isomorphism between `zero` and `one` in `WalkingIso`. -/ +def iso : zero.{w} ≅ one := Codiscrete.iso zero one + +lemma eq_iso_hom (f : zero.{w} ⟶ one) : f = iso.{w}.hom := Codiscrete.eq_iso_hom f + +lemma eq_iso_inv (f : one.{w} ⟶ zero) : f = iso.{w}.inv := Codiscrete.eq_iso_inv f + +/-- Functors out of `WalkingIso` define isomorphisms in the target category. -/ +@[simps!] +def toIso (F : WalkingIso.{w} ⥤ C) : F.obj zero ≅ F.obj one := F.mapIso iso + +section induction + +variable {motive : WalkingIso.{u} → Sort*} (zero : motive zero) (one : motive one) + +/-- The recursor for WalkingIso, which constructs a term of `∏ (x : WalkingIso), A x` from +a term of `A zero` and a term of `A one`. -/ +@[elab_as_elim, induction_eliminator] +protected def rec : ∀ a, motive a + | .mk (.up false) => zero + | .mk (.up true) => one + +@[simp] lemma rec_zero : WalkingIso.rec zero one .zero = zero := rfl +@[simp] lemma rec_one : WalkingIso.rec zero one .one = one := rfl + +end induction + +/-- From an isomorphism in a category, we can build a functor out of `WalkingIso` to +that category. -/ +def fromIso {X Y : C} (e : X ≅ Y) : WalkingIso.{w} ⥤ C where + obj x := by induction x; exacts [X, Y] + map {x y} _ := by induction x <;> induction y; exacts [𝟙 X, e.hom, e.inv, 𝟙 Y] + map_comp {x y z} _ _ := by induction x <;> induction y <;> induction z <;> simp + map_id {x} := by induction x <;> rfl + +section + +variable {X Y : C} (e : X ≅ Y) + +@[simp] +lemma fromIso_zero : (fromIso.{w} e).obj .zero = X := rfl + +@[simp] +lemma fromIso_one : (fromIso.{w} e).obj .one = Y := rfl + +@[simp] +lemma fromIso_map_zero_zero (f : zero ⟶ zero) : (fromIso.{w} e).map f = 𝟙 X := rfl + +@[simp] +lemma fromIso_hom (f : zero ⟶ one) : (fromIso.{w} e).map f = e.hom := rfl + +@[simp] +lemma fromIso_inv (f : one ⟶ zero) : (fromIso.{w} e).map f = e.inv := rfl + +@[simp] +lemma fromIso_map_one_one (f : one ⟶ one) : (fromIso.{w} e).map f = 𝟙 Y := rfl + +end + +/-- An equivalence between the type of `WalkingIso`s in `C` and the type of isomorphisms in `C`. -/ +@[simps] +def equiv : (WalkingIso.{w} ⥤ C) ≃ Σ (X : C) (Y : C), (X ≅ Y) where + toFun F := ⟨F.obj zero, F.obj one, toIso F⟩ + invFun p := fromIso p.2.2 + right_inv := fun ⟨X, Y, e⟩ ↦ rfl + left_inv F := Functor.ext (by rintro (_ | _) <;> rfl) <| by + intro X Y f + induction X <;> + induction Y <;> + simp [Codiscrete.eq_id] <;> + rfl + +end + +end WalkingIso + +end CategoryTheory + +namespace SSet + +open Simplicial Edge + +/-- The simplicial set that encodes a single isomorphism. +Its n-simplices are formal compositions of arrows in WalkingIso. -/ +abbrev coherentIso : SSet := nerve WalkingIso.{u} + +namespace coherentIso + +/-- The source vertex of `coherentIso`. -/ +def x₀ : coherentIso.{u} _⦋0⦌ := + ComposableArrows.mk₀ WalkingIso.zero + +/-- The target vertex of `coherentIso`. -/ +def x₁ : coherentIso.{u} _⦋0⦌ := + ComposableArrows.mk₀ WalkingIso.one + +/-- The forwards edge of `coherentIso`. -/ +def hom : Edge.{u} x₀ x₁ where + edge := ComposableArrows.mk₁ WalkingIso.iso.hom + src_eq := ComposableArrows.ext₀ rfl + tgt_eq := ComposableArrows.ext₀ rfl + +/-- The backwards edge of `coherentIso`. -/ +def inv : Edge.{u} x₁ x₀ where + edge := ComposableArrows.mk₁ WalkingIso.iso.inv + src_eq := ComposableArrows.ext₀ rfl + tgt_eq := ComposableArrows.ext₀ rfl + +/-- The forwards and backwards edge of `coherentIso` compose to the identity. -/ +def homInvId : Edge.CompStruct.{u} hom inv (Edge.id x₀) where + simplex := ComposableArrows.mk₂ WalkingIso.iso.hom WalkingIso.iso.inv + d₂ := ComposableArrows.ext₁ rfl rfl rfl + d₀ := ComposableArrows.ext₁ rfl rfl rfl + d₁ := ComposableArrows.ext₁ rfl rfl rfl + +/-- The backwards and forwards edge of `coherentIso` compose to the identity. -/ +def invHomId : Edge.CompStruct.{u} inv hom (Edge.id x₁) where + simplex := ComposableArrows.mk₂ WalkingIso.iso.inv WalkingIso.iso.hom + d₂ := ComposableArrows.ext₁ rfl rfl rfl + d₀ := ComposableArrows.ext₁ rfl rfl rfl + d₁ := ComposableArrows.ext₁ rfl rfl rfl + +/-- The forwards edge of `coherentIso` has an inverse. -/ +@[simps] +def invStructHom : Edge.InvStruct.{u} coherentIso.hom where + inv := inv + homInvId := homInvId + invHomId := invHomId + +/-- For a simplicial set `X`, if an edge in `X` is equal to the image of `hom` +under a morphism of simplicial sets, this edge has an inverse. -/ +abbrev invStructOfEqMapHom {X : SSet.{u}} {x₀ x₁ : X _⦋0⦌} + {f : Edge x₀ x₁} + {g : coherentIso ⟶ X} + (hfg : f.edge = g.app _ hom.edge) : + f.InvStruct := + (invStructHom.map g).ofEq hfg.symm + +end coherentIso + +end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/CompStruct.lean b/Mathlib/AlgebraicTopology/SimplicialSet/CompStruct.lean index b4fd516c69be05..1ca3c81c40fb0c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/CompStruct.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/CompStruct.lean @@ -1,14 +1,14 @@ /- Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Joël Riou +Authors: Joël Riou, Arnoud van der Leer -/ module public import Mathlib.AlgebraicTopology.SimplicialSet.CompStructTruncated /-! -# Edges and "triangles" in simplicial sets +# Edges, "triangles" and isos in simplicial sets Given a simplicial set `X`, we introduce two types: * Given `0`-simplices `x₀` and `x₁`, we define `Edge x₀ x₁` @@ -22,6 +22,10 @@ Given a simplicial set `X`, we introduce two types: The definitions in this file are definitionally equal to their `2`-truncated counterparts.) +Given `0`-simplices `x₀` and `x₁`, and an edge `hom : Edge x₀ x₁`, `InvStruct hom` records the data +of an edge `inv : Edge x₁ x₀` and simplices `homInvId : CompStruct hom inv (id x₀)` and +`invHomId : CompStruct inv hom (id x₁)`, witnessing that `inv` is an inverse to `hom`. + -/ @[expose] public section @@ -127,6 +131,15 @@ lemma exists_of_simplex (s : X _⦋1⦌) : ∃ (x₀ x₁ : X _⦋0⦌) (e : Edge x₀ x₁), e.edge = s := ⟨_, _, mk' s, rfl⟩ +/-- Transports an edge between `x₀` and `x₁` to an edge between `y₀` and `y₁`, given `x₀ = y₀` +and `x₁ = y₁`. -/ +@[simps] +def ofEq {y₀ y₁ : X _⦋0⦌} (e : Edge x₀ x₁) (h₀ : x₀ = y₀) (h₁ : x₁ = y₁) : + Edge y₀ y₁ where + edge := e.edge + src_eq := e.src_eq.trans h₀ + tgt_eq := e.tgt_eq.trans h₁ + /-- Let `x₀`, `x₁`, `x₂` be `0`-simplices of a simplicial set `X`, `e₀₁` an edge from `x₀` to `x₁`, `e₁₂` an edge from `x₁` to `x₂`, `e₀₂` an edge from `x₀` to `x₂`. This is the data of a `2`-simplex whose @@ -212,6 +225,14 @@ def compId (e : Edge x₀ x₁) : CompStruct e (.id x₁) e := @[simp] lemma compId_simplex (e : Edge x₀ x₁) : (compId e).simplex = X.σ 1 e.edge := rfl +/-- The identity edge on a point, composed with itself, gives the identity. -/ +def idCompId (x : X _⦋0⦌) : CompStruct (id x) (id x) (id x) := + ofTruncated (.idCompId _) + +@[simp] +lemma idCompId_simplex (x : X _⦋0⦌) : (idCompId x).simplex = X.σ 0 (X.σ 0 x) := + Truncated.Edge.CompStruct.idCompId_simplex _ + /-- The image of a `Edge.CompStruct` by a morphism of simplicial sets. -/ def map (h : CompStruct e₀₁ e₁₂ e₀₂) (f : X ⟶ Y) : CompStruct (e₀₁.map f) (e₁₂.map f) (e₀₂.map f) := @@ -221,8 +242,75 @@ def map (h : CompStruct e₀₁ e₁₂ e₀₂) (f : X ⟶ Y) : lemma map_simplex (h : CompStruct e₀₁ e₁₂ e₀₂) (f : X ⟶ Y) : (h.map f).simplex = f.app _ h.simplex := rfl +/-- Transports a `CompStruct` between edges `e₀₁`, `e₁₂` and `e₀₂` to a `CompStruct` between edges +`f₀₁`, `f₁₂` and `f₀₂` along equalities of 1-simplices `eᵢⱼ.edge = fᵢⱼ.edge`. -/ +@[simps] +def ofEq {y₀ y₁ y₂ : X _⦋0⦌} + {e₀₁ : Edge x₀ x₁} {f₀₁ : Edge y₀ y₁} + {e₁₂ : Edge x₁ x₂} {f₁₂ : Edge y₁ y₂} + {e₀₂ : Edge x₀ x₂} {f₀₂ : Edge y₀ y₂} + (c : CompStruct e₀₁ e₁₂ e₀₂) + (h₀₁ : e₀₁.edge = f₀₁.edge) + (h₁₂ : e₁₂.edge = f₁₂.edge) + (h₀₂ : e₀₂.edge = f₀₂.edge) : + CompStruct f₀₁ f₁₂ f₀₂ where + simplex := c.simplex + d₂ := c.d₂.trans h₀₁ + d₀ := c.d₀.trans h₁₂ + d₁ := c.d₁.trans h₀₂ + end CompStruct +/-- For an edge `hom`, `InvStruct hom` encodes the data of a backward edge `inv`, and +2-simplices witnessing that `hom` and `inv` compose to the identity on their endpoints. +This implies that `hom` becomes an isomorphism in the homotopy category. -/ +@[ext] +structure InvStruct (hom : Edge x₀ x₁) where + /-- The backwards edge -/ + inv : Edge x₁ x₀ + /-- The simplex witnessing that `hom` and `inv` compose to the identity -/ + homInvId : CompStruct hom inv (id x₀) + /-- The simplex witnessing that `inv` and `hom` compose to the identity -/ + invHomId : CompStruct inv hom (id x₁) + +namespace InvStruct + +/-- The identity edge has an inverse. -/ +@[simps] +def invStructId (x : X _⦋0⦌) : InvStruct (id x) where + inv := id x + homInvId := CompStruct.idCompId x + invHomId := CompStruct.idCompId x + +/-- The inverse has an inverse. -/ +@[simps] +def invStructInv {hom : Edge x₀ x₁} (I : InvStruct hom) : InvStruct I.inv where + inv := hom + homInvId := I.invHomId + invHomId := I.homInvId + +/-- Maps an inverse along an morphism of simplicial sets. -/ +@[simps] +def map {hom : Edge x₀ x₁} (I : InvStruct hom) (f : X ⟶ Y) : InvStruct (hom.map f) where + inv := I.inv.map f + homInvId := (I.homInvId.map f).ofEq rfl rfl (Edge.ext_iff.mp (map_id _ _)) + invHomId := (I.invHomId.map f).ofEq rfl rfl (Edge.ext_iff.mp (map_id _ _)) + +/-- Transports an inverse for `hom` along an equality of 1-simplices `hom = hom'`. + I.e. constructs an inverse for `hom'` from an inverse for `hom`. -/ +@[simps] +def ofEq {y₀ y₁ : X _⦋0⦌} {hom : Edge x₀ x₁} {hom' : Edge y₀ y₁} + (I : InvStruct hom) + (hhom : hom.edge = hom'.edge) : + InvStruct hom' where + inv := I.inv.ofEq + (by rw [← hom.tgt_eq, hhom, hom'.tgt_eq]) + (by rw [← hom.src_eq, hhom, hom'.src_eq]) + homInvId := I.homInvId.ofEq hhom rfl (by rw [← hom.src_eq, hhom, hom'.src_eq]) + invHomId := I.invHomId.ofEq rfl hhom (by rw [← hom.tgt_eq, hhom, hom'.tgt_eq]) + +end InvStruct + end Edge end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NerveCodiscrete.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NerveCodiscrete.lean new file mode 100644 index 00000000000000..1ae7ceffa04bef --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NerveCodiscrete.lean @@ -0,0 +1,42 @@ +/- +Copyright (c) 2026 Arnoud van der Leer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Arnoud van der Leer +-/ +module + +public import Mathlib.CategoryTheory.CodiscreteCategory +public import Mathlib.AlgebraicTopology.SimplicialSet.Nerve + +/-! +# The Nerve of a Codiscrete Category + +In the codiscrete category on a type `X`, every hom-type is given by `Unit`. +When we take the nerve of such a category, the `n`-simplices become equivalent to +`X`-vectors of length `n + 1`. +Therefore, if `X` has decidable equality, so does the type of `n`-simplices in this nerve. +-/ + +@[expose] public section + +universe u + +namespace CategoryTheory.Codiscrete + +open Simplicial + +variable {X : Type u} {n : ℕ} + +/-- Since the morphisms in a codiscrete category do not carry information, an n-simplex of +coherentIso is equivalent to an X-vector of length (n + 1). -/ +@[simps! +dsimpLhs] +def equivFun : nerve (Codiscrete X) _⦋n⦌ ≃ (Fin (n + 1) → X) where + toFun f k := (f.obj k).as + invFun f := .mk (fun k ↦ .mk (f k)) (fun _ ↦ iso _ _|>.hom) (fun _ ↦ rfl) (fun _ _ ↦ rfl) + +/-- If a type `X` has decidable equality, the nerve of the codiscrete category on `X` +has decidable equality as well. -/ +instance [DecidableEq X] : DecidableEq (nerve (Codiscrete X) _⦋n⦌) := + fun _ _ ↦ decidable_of_iff _ (Equiv.apply_eq_iff_eq equivFun) + +end CategoryTheory.Codiscrete diff --git a/Mathlib/CategoryTheory/CodiscreteCategory.lean b/Mathlib/CategoryTheory/CodiscreteCategory.lean index 659f10d267e21a..005d4955c70548 100644 --- a/Mathlib/CategoryTheory/CodiscreteCategory.lean +++ b/Mathlib/CategoryTheory/CodiscreteCategory.lean @@ -66,6 +66,27 @@ instance (A : Type*) : Category (Codiscrete A) where id _ := ⟨⟩ comp _ _ := ⟨⟩ +/-- Any two objects in a codiscrete category are isomorphic. -/ +def iso {A : Type u} (x y : Codiscrete A) : x ≅ y where + hom := () + inv := () + +lemma eq_id {A : Type u} {x : Codiscrete A} (f : x ⟶ x) : f = 𝟙 _ := rfl + +lemma eq_iso_hom {A : Type u} {x y : Codiscrete A} (f : x ⟶ y) : f = (iso x y).hom := rfl + +lemma eq_iso_inv {A : Type u} {x y : Codiscrete A} (f : x ⟶ y) : f = (iso y x).inv := rfl + +@[simps] +instance uniqueHom {A : Type u} (x y : Codiscrete A) : Unique (x ⟶ y) where + default := (iso x y).hom + uniq _ := rfl + +@[simps] +instance uniqueIso {A : Type u} (x y : Codiscrete A) : Unique (x ≅ y) where + default := iso x y + uniq _ := rfl + section variable {C : Type u} [Category.{v} C] {A : Type w} From e3b73828b03c9961c9b33aa95f1d2dc0dca82028 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:29:31 +0000 Subject: [PATCH 0709/1300] fix(RingTheory/TwoSidedIdeal/Basic): remove instance with bad outParam (#40718) There are two different instances for `SMulMemClass (TwoSidedIdeal R) _ R`, which violates the fact the fact that the second argument in the class is an `outParam` . So, this PR turns one of the instances into just a theorem. --- Mathlib/RingTheory/TwoSidedIdeal/Basic.lean | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean index d9de6ad31362b3..d639148dbd2e69 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean @@ -192,7 +192,10 @@ lemma coe_mk' (carrier : Set R) (zero_mem add_mem neg_mem mul_mem_left mul_mem_r instance : SMulMemClass (TwoSidedIdeal R) R R where smul_mem _ _ h := TwoSidedIdeal.mul_mem_left _ _ _ h -instance : SMulMemClass (TwoSidedIdeal R) Rᵐᵒᵖ R where +-- This is not an instance, because together with the instance above, +-- it violates the `outParam` of `SMulMemClass`. +-- See: https://github.com/leanprover-community/mathlib4/pull/40718 +theorem instSMulMemClassMulOpposite : SMulMemClass (TwoSidedIdeal R) Rᵐᵒᵖ R where smul_mem _ _ h := TwoSidedIdeal.mul_mem_right _ _ _ h instance : Add I where add x y := ⟨x.1 + y.1, I.add_mem x.2 y.2⟩ From d45663d02f179c449d17bb065acc845b8051ec1a Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Fri, 10 Jul 2026 02:16:48 +0000 Subject: [PATCH 0710/1300] feat(AlgebraicGeometry/Birational): composition of rational maps (#39445) Define composition of partial and rational maps. - [x] depends on: #39442 - [x] depends on: #39443 - [x] depends on: #39317 - [x] depends on: #40189 --- Mathlib.lean | 1 + .../Birational/Composition.lean | 219 ++++++++++++++++++ .../Birational/Dominant.lean | 2 +- .../Birational/RationalMap.lean | 75 ++++-- Mathlib/AlgebraicGeometry/OpenImmersion.lean | 3 + 5 files changed, 286 insertions(+), 14 deletions(-) create mode 100644 Mathlib/AlgebraicGeometry/Birational/Composition.lean diff --git a/Mathlib.lean b/Mathlib.lean index b51d41f92d98c8..3fe5766f3bb2fd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1350,6 +1350,7 @@ public import Mathlib.AlgebraicGeometry.AlgClosed.Basic public import Mathlib.AlgebraicGeometry.AlgebraicCycle.Basic public import Mathlib.AlgebraicGeometry.Artinian public import Mathlib.AlgebraicGeometry.Birational.Birational +public import Mathlib.AlgebraicGeometry.Birational.Composition public import Mathlib.AlgebraicGeometry.Birational.Dominant public import Mathlib.AlgebraicGeometry.Birational.RationalMap public import Mathlib.AlgebraicGeometry.ColimitsOver diff --git a/Mathlib/AlgebraicGeometry/Birational/Composition.lean b/Mathlib/AlgebraicGeometry/Birational/Composition.lean new file mode 100644 index 00000000000000..852abbeadf6a90 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/Birational/Composition.lean @@ -0,0 +1,219 @@ +/- +Copyright (c) 2026 Justus Springer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Justus Springer +-/ +module + +public import Mathlib.AlgebraicGeometry.Birational.Dominant + +/-! +# Composition of rational maps + +This file defines composition for partial maps and rational maps between schemes. + +## Main definitions + +- `Scheme.PartialMap.comp`: given a dominant partial map `f : X.PartialMap Y` and any partial map + `g : Y.PartialMap Z`, their composition `f.comp g : X.PartialMap Z` is defined on the preimage + of `g`'s domain under `f`. +- `Scheme.RationalMap.comp`: composition of rational maps, defined via a dominant representative. + +## Main statements + +- `Scheme.PartialMap.comp_equiv_of_equiv`: Composition respects equivalence of partial maps. +- `Scheme.PartialMap.comp_assoc`: Composition of partial maps is associative. +- `Scheme.RationalMap.comp_assoc`: Composition of rational maps is associative. + +-/ + +@[expose] public section + +universe u + +open CategoryTheory + +namespace AlgebraicGeometry.Scheme + +variable {X Y Z : Scheme.{u}} + +section PreirreducibleSpace + +variable [PreirreducibleSpace X] [Nonempty Y] + +namespace PartialMap + +/-- Composition of partial maps. The domain of `f.comp g` is the preimage of `g.domain` under `f`, +viewed as an open subscheme of `X`. Requires `f.hom` to be dominant so that the domain is dense. -/ +@[simps] +noncomputable def comp (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) : + X.PartialMap Z where + domain := f.domain.ι ''ᵁ f.hom ⁻¹ᵁ g.domain + dense_domain := (f.domain.ι ''ᵁ f.hom ⁻¹ᵁ g.domain).2.dense <| by + simpa [← Set.nonempty_preimage_iff] using + f.hom.denseRange.inter_open_nonempty _ g.domain.2 g.dense_domain.nonempty + hom := (f.domain.ι.isoImage _).inv ≫ f.hom ∣_ g.domain ≫ g.hom + +set_option backward.defeqAttrib.useBackward true in +lemma comp_restrict_left (f : X.PartialMap Y) [IsDominant f.hom] (U : X.Opens) + (hU : Dense (U : Set X)) (hU' : U ≤ f.domain) (g : Y.PartialMap Z) : + (f.restrict U hU hU').comp g = (f.comp g).restrict (f.domain.ι ''ᵁ f.hom ⁻¹ᵁ g.domain ⊓ U) + ((f.comp g).dense_domain.inter_of_isOpen_right hU U.2) inf_le_left := by + ext + · simp [ι_image_homOfLE_eq_ι_image_inf] + · simp [morphismRestrict_comp, isoImage_ι_inv_morphismRestrict_homOfLE_assoc, isoOfEq_hom] + +set_option backward.defeqAttrib.useBackward true in +lemma comp_restrict_right (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) + (V : Y.Opens) (hV : Dense (V : Set Y)) (hV' : V ≤ g.domain) : + f.comp (g.restrict V hV hV') = (f.comp g).restrict + (f.domain.ι ''ᵁ (f.hom ⁻¹ᵁ V)) ((f.domain.ι ''ᵁ f.hom ⁻¹ᵁ V).2.dense <| by + simpa [← Set.nonempty_preimage_iff] using + f.hom.denseRange.inter_open_nonempty _ V.2 hV.nonempty) + (f.domain.ι.image_mono (f.hom.preimage_mono hV')) := by + ext + · simp + · simp [← f.domain.ι.isoImage_inv_homOfLE_assoc _ _ (f.hom.preimage_mono hV'), + ← morphismRestrict_homOfLE_assoc f.hom _ _ hV'] + +set_option backward.defeqAttrib.useBackward true in +/-- Composition respects equivalence of partial maps on the left. -/ +lemma comp_equiv_of_equiv_left {f₁ f₂ : X.PartialMap Y} [IsDominant f₁.hom] [IsDominant f₂.hom] + (h : f₁.equiv f₂) (g : Y.PartialMap Z) : + (f₁.comp g).equiv (f₂.comp g) := by + obtain ⟨W, hW, hW₁, hW₂, e⟩ := h + replace e : f₁.restrict W hW hW₁ = f₂.restrict W hW hW₂ := + PartialMap.ext _ _ rfl (by simpa using e) + replace e := congr($(e).comp g) + rw [comp_restrict_left, comp_restrict_left] at e + exact equiv_of_restrict_eq _ _ e + +set_option backward.defeqAttrib.useBackward true in +/-- Composition respects equivalence of partial maps on the right. -/ +lemma comp_equiv_of_equiv_right (f : X.PartialMap Y) [IsDominant f.hom] {g₁ g₂ : Y.PartialMap Z} + (h : g₁.equiv g₂) : (f.comp g₁).equiv (f.comp g₂) := by + obtain ⟨W, hW, hW₁, hW₂, e⟩ := h + replace e : g₁.restrict W hW hW₁ = g₂.restrict W hW hW₂ := + PartialMap.ext _ _ rfl (by simpa using e) + replace e := congr(f.comp $e) + rw [comp_restrict_right, comp_restrict_right] at e + exact equiv_of_restrict_eq _ _ e + +/-- Composition respects equivalence of partial maps in both arguments. -/ +lemma comp_equiv_of_equiv (f₁ f₂ : X.PartialMap Y) [IsDominant f₁.hom] [IsDominant f₂.hom] + (hf : f₁.equiv f₂) (g₁ g₂ : Y.PartialMap Z) (hg : g₁.equiv g₂) : + (f₁.comp g₁).equiv (f₂.comp g₂) := + equivalence_rel.trans (comp_equiv_of_equiv_left hf _) (comp_equiv_of_equiv_right _ hg) + +set_option backward.defeqAttrib.useBackward true in +instance isDominant_comp_hom (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) + [IsDominant g.hom] : IsDominant (f.comp g).hom := by + dsimp only [comp_domain, comp_hom] + have := IsZariskiLocalAtTarget.restrict ‹IsDominant f.hom› g.domain + infer_instance + +set_option backward.defeqAttrib.useBackward true in +@[simp] +lemma comp_assoc {X₁ X₂ X₃ Y : Scheme.{u}} [PreirreducibleSpace X₁] [IrreducibleSpace X₂] + [Nonempty X₃] (f : X₁.PartialMap X₂) [IsDominant f.hom] (g : X₂.PartialMap X₃) + [IsDominant g.hom] (h : X₃.PartialMap Y) : + (f.comp g).comp h = f.comp (g.comp h) := by + ext + · simp_rw [comp_domain, comp_hom, ← Category.assoc, Hom.comp_preimage, Hom.inv_preimage, + ← Hom.comp_image, Hom.isoImage_hom_ι, Hom.comp_image, image_morphismRestrict_preimage] + · dsimp + simp_rw [morphismRestrict_comp, morphismRestrict_ι_image_ι_isoImage_inv_assoc, + Hom.comp_preimage, Category.assoc] + conv_lhs => rw [← Category.assoc] + conv_rhs => rw [← Category.assoc, ← Category.assoc, ← Category.assoc] + congr 1 + simp [← cancel_mono (Opens.ι _)] + +set_option backward.defeqAttrib.useBackward true in +@[simp] +lemma comp_toPartialMap (f : X.PartialMap Y) [IsDominant f.hom] (g : Y ⟶ Z) : + f.comp g.toPartialMap = f.compHom g := by + ext1 + · simp + · simp_rw [comp_hom, Hom.toPartialMap_domain, Hom.toPartialMap_hom, compHom_hom, topIso_hom, + morphismRestrict_ι_assoc, f.domain.isoImage_ι_inv_ι_assoc, isoOfEq_hom] + rfl + +set_option backward.defeqAttrib.useBackward true in +lemma comp_id (f : X.PartialMap Y) [IsDominant f.hom] : f.comp (PartialMap.id Y) = f := by simp + +end PartialMap + +namespace RationalMap + +-- If better def-eqs are required, consider refactoring this by using `Quotient.liftOn₂` +-- and a bundled structure `DominantPartialMap`. +/-- Composition of rational maps. Requires `f` to be dominant, so that we may choose +a dominant representative. -/ +noncomputable def comp (f : X ⤏ Y) [f.IsDominant] (g : Y ⤏ Z) : X ⤏ Z := + Quotient.liftOn g (PartialMap.toRationalMap ∘ f.representative.comp) <| fun _ _ h ↦ by + rw [Function.comp_apply, Function.comp_apply, PartialMap.toRationalMap_eq_iff] + exact PartialMap.comp_equiv_of_equiv_right _ h + +lemma comp_def (f : X ⤏ Y) [f.IsDominant] (g : Y.PartialMap Z) : + f.comp g.toRationalMap = (f.representative.comp g).toRationalMap := + rfl + +lemma toRationalMap_comp (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) : + f.toRationalMap.comp g.toRationalMap = (f.comp g).toRationalMap := by + rw [RationalMap.comp_def, PartialMap.toRationalMap_eq_iff] + exact PartialMap.comp_equiv_of_equiv_left f.representative_toRationalMap_equiv _ + +@[simp] +lemma comp_id (f : X ⤏ Y) [f.IsDominant] : f.comp (RationalMap.id Y) = f := by + simp [RationalMap.comp_def] + +instance (f : X ⤏ Y) [f.IsDominant] (g : Y ⤏ Z) [g.IsDominant] : (f.comp g).IsDominant := by + rw [← g.toRationalMap_representative, RationalMap.comp_def] + infer_instance + +lemma comp_toRationalMap (f : X ⤏ Y) [f.IsDominant] (h : Y ⟶ Z) : + f.comp h.toRationalMap = f.compHom h := by + simp [comp_def, PartialMap.comp_toPartialMap] + +@[grind _=_] +lemma comp_assoc {X₁ X₂ X₃ Y : Scheme.{u}} [PreirreducibleSpace X₁] [IrreducibleSpace X₂] + [Nonempty X₃] (f₁ : X₁ ⤏ X₂) [f₁.IsDominant] (f₂ : X₂ ⤏ X₃) [f₂.IsDominant] (f₃ : X₃ ⤏ Y) : + (f₁.comp f₂).comp f₃ = f₁.comp (f₂.comp f₃) := by + rw [← f₃.toRationalMap_representative] + simp_rw [comp_def, ← PartialMap.comp_assoc, PartialMap.toRationalMap_eq_iff] + apply PartialMap.comp_equiv_of_equiv_left + rw [← f₂.toRationalMap_representative, comp_def] + apply (f₁.representative.comp f₂.representative).representative_toRationalMap_equiv.trans + apply PartialMap.comp_equiv_of_equiv_right + rw [toRationalMap_representative] + +instance isOver_comp {S : Scheme.{u}} [IrreducibleSpace Y] [Nonempty Z] [X.Over S] [Y.Over S] + [Z.Over S] (f : X ⤏ Y) [f.IsDominant] [f.IsOver S] (g : Y ⤏ Z) [g.IsDominant] [g.IsOver S] : + (f.comp g).IsOver S := by + rw [isOver_iff, ← comp_toRationalMap, comp_assoc, comp_toRationalMap, + isOver_iff.mp ‹g.IsOver S›, comp_toRationalMap, RationalMap.isOver_iff.mp ‹f.IsOver S›] + +end RationalMap + +end PreirreducibleSpace + +set_option backward.defeqAttrib.useBackward true in +@[simp] +lemma PartialMap.id_comp {X Y : Scheme.{u}} [IrreducibleSpace X] (f : X.PartialMap Y) : + (PartialMap.id X).comp f = f := by + ext1 + · simp_rw [comp_domain, Hom.toPartialMap_domain, Hom.toPartialMap_hom, Category.comp_id, + ← X.topIso_hom, ← Hom.inv_image, ← Hom.comp_image, Iso.inv_hom_id, Hom.id_image] + · simp_rw [comp_hom, Hom.toPartialMap_hom, Hom.toPartialMap_domain, morphismRestrict_comp, + morphismRestrict_id, ← X.topIso_hom, Hom.comp_preimage, Hom.id_preimage, + Category.comp_id, ← X.topIso.hom.isoImage_preimage_hom_homOfLE, Category.assoc, + Iso.inv_hom_id_assoc] + rfl + +@[simp, grind =] +lemma RationalMap.id_comp {X Y : Scheme.{u}} [IrreducibleSpace X] (f : X ⤏ Y) : + (RationalMap.id X).comp f = f := by + rw [← f.toRationalMap_representative, toRationalMap_comp, PartialMap.id_comp] + +end AlgebraicGeometry.Scheme diff --git a/Mathlib/AlgebraicGeometry/Birational/Dominant.lean b/Mathlib/AlgebraicGeometry/Birational/Dominant.lean index f41ec7096c0df6..1e51460f22d7a8 100644 --- a/Mathlib/AlgebraicGeometry/Birational/Dominant.lean +++ b/Mathlib/AlgebraicGeometry/Birational/Dominant.lean @@ -36,7 +36,7 @@ namespace PartialMap set_option backward.defeqAttrib.useBackward true in /-- Restricting a dominant partial map to a dense open yields a dominant partial map. -/ -lemma isDominant_restrict_hom (f : X.PartialMap Y) [IsDominant f.hom] (U : X.Opens) +instance isDominant_restrict_hom (f : X.PartialMap Y) [IsDominant f.hom] (U : X.Opens) (hU : Dense (U : Set X)) (hU' : U ≤ f.domain) : IsDominant (f.restrict U hU hU').hom := by dsimp only [restrict_domain, restrict_hom] have : IsDominant (X.homOfLE hU') := Opens.isDominant_homOfLE hU hU' diff --git a/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean b/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean index 9f67f767fa06f7..4a0717389ddacb 100644 --- a/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean +++ b/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean @@ -120,15 +120,38 @@ def compHom (f : X.PartialMap Y) (g : Y ⟶ Z) : X.PartialMap Z where dense_domain := f.dense_domain hom := f.hom ≫ g +set_option backward.defeqAttrib.useBackward true in +@[simp] +lemma compHom_id (f : X.PartialMap Y) : f.compHom (𝟙 Y) = f := by + ext <;> simp + set_option backward.defeqAttrib.useBackward true in instance [X.Over S] [Y.Over S] [Z.Over S] (f : X.PartialMap Y) (g : Y ⟶ Z) [f.IsOver S] [g.IsOver S] : (f.compHom g).IsOver S where /-- A scheme morphism as a partial map. -/ @[simps] -def _root_.AlgebraicGeometry.Scheme.Hom.toPartialMap (f : X.Hom Y) : +def _root_.AlgebraicGeometry.Scheme.Hom.toPartialMap (f : X ⟶ Y) : X.PartialMap Y := ⟨⊤, dense_univ, X.topIso.hom ≫ f⟩ +set_option backward.defeqAttrib.useBackward true in +instance (f : X ⟶ Y) [IsDominant f] : IsDominant f.toPartialMap.hom := by + dsimp + have := Opens.isDominant_ι (X := X) (U := ⊤) dense_univ + infer_instance + +lemma _root_.AlgebraicGeometry.Scheme.Hom.toPartialMap_compHom (f : X ⟶ Y) (g : Y ⟶ Z) : + f.toPartialMap.compHom g = (f ≫ g).toPartialMap := rfl + +variable (X) in +/-- The identity partial map. -/ +protected abbrev id : X.PartialMap X := (𝟙 X : X ⟶ X).toPartialMap + +@[simp] +lemma id_compHom (f : X ⟶ Y) : (PartialMap.id X).compHom f = f.toPartialMap := by + apply PartialMap.ext _ _ rfl + simp + set_option backward.defeqAttrib.useBackward true in instance [X.Over S] [Y.Over S] (f : X ⟶ Y) [f.IsOver S] : f.toPartialMap.IsOver S where @@ -226,20 +249,37 @@ def equiv (f g : X.PartialMap Y) : Prop := ∃ (W : X.Opens) (hW : Dense (W : Set X)) (hWl : W ≤ f.domain) (hWr : W ≤ g.domain), (f.restrict W hW hWl).hom = (g.restrict W hW hWr).hom +lemma equiv_of_restrict_eq (f g : X.PartialMap Y) {W₁ W₂ : X.Opens} {hW₁ : Dense (W₁ : Set X)} + {hW₂ : Dense (W₂ : Set X)} {hW₁' : W₁ ≤ f.domain} {hW₂' : W₂ ≤ g.domain} + (H : f.restrict W₁ hW₁ hW₁' = g.restrict W₂ hW₂ hW₂') : f.equiv g := by + have e : W₁ = W₂ := congr($(H).domain) + subst e + exact ⟨W₁, hW₁, hW₁', hW₂', congr($(H).hom)⟩ + +@[refl] +lemma equiv.refl (f : X.PartialMap Y) : f.equiv f := + ⟨f.domain, f.dense_domain, by simp⟩ + +@[symm] +lemma equiv.symm {f g : X.PartialMap Y} : f.equiv g → g.equiv f := by + intro ⟨W, hW, hWl, hWr, e⟩ + exact ⟨W, hW, hWr, hWl, e.symm⟩ + set_option backward.defeqAttrib.useBackward true in +@[trans] +lemma equiv.trans {f g h : X.PartialMap Y} : f.equiv g → g.equiv h → f.equiv h := by + intro ⟨W₁, hW₁, hW₁l, hW₁r, e₁⟩ ⟨W₂, hW₂, hW₂l, hW₂r, e₂⟩ + refine ⟨W₁ ⊓ W₂, hW₁.inter_of_isOpen_left hW₂ W₁.2, inf_le_left.trans hW₁l, + inf_le_right.trans hW₂r, ?_⟩ + dsimp at e₁ e₂ + simp only [restrict_domain, restrict_hom, ← X.homOfLE_homOfLE (U := W₁ ⊓ W₂) inf_le_left hW₁l, + Category.assoc, e₁, ← X.homOfLE_homOfLE (U := W₁ ⊓ W₂) inf_le_right hW₂r, ← e₂] + simp only [homOfLE_homOfLE_assoc] + lemma equivalence_rel : Equivalence (@Scheme.PartialMap.equiv X Y) where - refl f := ⟨f.domain, f.dense_domain, by simp⟩ - symm {f g} := by - intro ⟨W, hW, hWl, hWr, e⟩ - exact ⟨W, hW, hWr, hWl, e.symm⟩ - trans {f g h} := by - intro ⟨W₁, hW₁, hW₁l, hW₁r, e₁⟩ ⟨W₂, hW₂, hW₂l, hW₂r, e₂⟩ - refine ⟨W₁ ⊓ W₂, hW₁.inter_of_isOpen_left hW₂ W₁.2, inf_le_left.trans hW₁l, - inf_le_right.trans hW₂r, ?_⟩ - dsimp at e₁ e₂ - simp only [restrict_domain, restrict_hom, ← X.homOfLE_homOfLE (U := W₁ ⊓ W₂) inf_le_left hW₁l, - Category.assoc, e₁, ← X.homOfLE_homOfLE (U := W₁ ⊓ W₂) inf_le_right hW₂r, ← e₂] - simp only [homOfLE_homOfLE_assoc] + refl := equiv.refl + symm := equiv.symm + trans := equiv.trans instance : Setoid (X.PartialMap Y) := ⟨@PartialMap.equiv X Y, equivalence_rel⟩ @@ -334,6 +374,10 @@ def PartialMap.toRationalMap (f : X.PartialMap Y) : X ⤏ Y := Quotient.mk _ f /-- A scheme morphism as a rational map. -/ abbrev Hom.toRationalMap (f : X.Hom Y) : X ⤏ Y := f.toPartialMap.toRationalMap +variable (X) in +/-- The identity rational map. -/ +abbrev RationalMap.id : X ⤏ X := (PartialMap.id X).toRationalMap + variable (S) in /-- A rational map is an `S`-map if some partial map in the equivalence class is an `S`-map. -/ class RationalMap.IsOver [X.Over S] [Y.Over S] (f : X ⤏ Y) : Prop where @@ -391,6 +435,11 @@ def RationalMap.compHom (f : X ⤏ Y) (g : Y ⟶ Z) : X ⤏ Z := by lemma RationalMap.compHom_toRationalMap (f : X.PartialMap Y) (g : Y ⟶ Z) : (f.compHom g).toRationalMap = f.toRationalMap.compHom g := rfl +@[simp] +lemma RationalMap.id_compHom (f : X ⟶ Y) : + (RationalMap.id X).compHom f = f.toRationalMap := by + rw [RationalMap.id, ← compHom_toRationalMap, PartialMap.id_compHom] + instance [X.Over S] [Y.Over S] [Z.Over S] (f : X ⤏ Y) (g : Y ⟶ Z) [f.IsOver S] [g.IsOver S] : (f.compHom g).IsOver S where exists_partialMap_over := by diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index a8b61e1491ec98..1f2c719581f96d 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -201,6 +201,9 @@ lemma id_image {X : Scheme} (U : X.Opens) : 𝟙 X ''ᵁ U = U := lemma inv_image {X Y : Scheme} (e : X ≅ Y) (U : Y.Opens) : e.inv ''ᵁ U = e.hom ⁻¹ᵁ U := TopologicalSpace.Opens.ext <| (Scheme.homeoOfIso e.symm).toEquiv.image_eq_preimage_symm _ +lemma inv_preimage {X Y : Scheme} (e : X ≅ Y) (U : X.Opens) : e.inv ⁻¹ᵁ U = e.hom ''ᵁ U := + (inv_image e.symm U).symm + @[simp] lemma apply_mem_image_iff {X Y : Scheme} (f : X ⟶ Y) [IsOpenImmersion f] {U : X.Opens} {x : X} : f x ∈ f ''ᵁ U ↔ x ∈ U := From 1a783458e32009352666447834e2eebf0ebe6e31 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 10 Jul 2026 02:42:26 +0000 Subject: [PATCH 0711/1300] feat(Algebra/Algebra/Tower): add `restrictScalarsHom` (#41417) This PR adds `AlgEquiv.restrictScalarsHom`, analogous to the existing `AlgEquiv.extendScalarsHomOfSurjective`. This PR also renames `coe_restrictScalars -> toRingEquiv_restrictScalars` without a deprecation to make way for `coe_restrictScalars' -> coe_restrictScalars`. Co-authored-by: tb65536 --- Mathlib/Algebra/Algebra/Tower.lean | 42 +++++++++++++++---- .../RingTheory/Smooth/IntegralClosure.lean | 2 +- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Tower.lean b/Mathlib/Algebra/Algebra/Tower.lean index 464f3228d15a2c..ae551c438c7583 100644 --- a/Mathlib/Algebra/Algebra/Tower.lean +++ b/Mathlib/Algebra/Algebra/Tower.lean @@ -247,25 +247,48 @@ theorem restrictScalars_apply (f : A ≃ₐ[S] B) (x : A) : f.restrictScalars R (f.restrictScalars R).toLinearEquiv = f.toLinearEquiv.restrictScalars R := rfl @[simp] -theorem coe_restrictScalars (f : A ≃ₐ[S] B) : (f.restrictScalars R : A ≃+* B) = f := rfl +theorem toRingEquiv_restrictScalars (f : A ≃ₐ[S] B) : (f.restrictScalars R : A ≃+* B) = f := rfl @[simp] -theorem coe_restrictScalars' (f : A ≃ₐ[S] B) : (restrictScalars R f : A → B) = f := rfl +theorem coe_restrictScalars (f : A ≃ₐ[S] B) : (restrictScalars R f : A → B) = f := rfl + +@[deprecated (since := "2026-07-06")] alias coe_restrictScalars' := coe_restrictScalars theorem restrictScalars_injective : Function.Injective (restrictScalars R : (A ≃ₐ[S] B) → A ≃ₐ[R] B) := fun _ _ h => AlgEquiv.ext (AlgEquiv.congr_fun h :) +@[simp] +lemma symm_restrictScalars (f : A ≃ₐ[S] B) : + (f.restrictScalars R).symm = f.symm.restrictScalars R := + rfl + +@[deprecated "Use `symm_restrictScalars` instead." (since := "2026-07-06")] lemma restrictScalars_symm_apply (f : A ≃ₐ[S] B) (x : B) : - (f.restrictScalars R).symm x = f.symm x := rfl + (f.restrictScalars R).symm x = f.symm x := by + simp -@[simp] +@[deprecated "Use `symm_restrictScalars` instead." (since := "2026-07-06")] lemma coe_restrictScalars_symm (f : A ≃ₐ[S] B) : - ((f.restrictScalars R).symm : B ≃+* A) = f.symm := rfl + ((f.restrictScalars R).symm : B ≃+* A) = f.symm := by + simp -@[simp] +@[deprecated "Use `symm_restrictScalars` instead." (since := "2026-07-06")] lemma coe_restrictScalars_symm' (f : A ≃ₐ[S] B) : - ((restrictScalars R f).symm : B → A) = f.symm := rfl + ((restrictScalars R f).symm : B → A) = f.symm := by + simp + +/-- `AlgEquiv.restrictScalars` as a homomorphism. -/ +def restrictScalarsHom : (A ≃ₐ[S] A) →* (A ≃ₐ[R] A) := + MulSemiringAction.toAlgAut (A ≃ₐ[S] A) R A + +@[simp] +theorem restrictScalarsHom_apply (f : A ≃ₐ[S] A) : f.restrictScalarsHom R = f.restrictScalars R := + rfl + +theorem restrictScalarsHom_injective : + Function.Injective (restrictScalarsHom R : (A ≃ₐ[S] A) →* (A ≃ₐ[R] A)) := + restrictScalars_injective R section @@ -300,6 +323,11 @@ def extendScalarsHomOfSurjective (h : Function.Surjective ⇑(algebraMap R S)) : __ := extendScalarsOfSurjective h map_mul' _ _ := rfl +@[simp] +lemma toMonoidHom_symm_extendScalarsHomOfSurjective (h : Function.Surjective (algebraMap R S)) : + (extendScalarsHomOfSurjective h (A := A).symm : (A ≃ₐ[S] A) →* _) = restrictScalarsHom R := + rfl + end end AlgEquiv diff --git a/Mathlib/RingTheory/Smooth/IntegralClosure.lean b/Mathlib/RingTheory/Smooth/IntegralClosure.lean index a16bc235247548..b98a96dc4c56e1 100644 --- a/Mathlib/RingTheory/Smooth/IntegralClosure.lean +++ b/Mathlib/RingTheory/Smooth/IntegralClosure.lean @@ -177,7 +177,7 @@ lemma TensorProduct.toIntegralClosure_bijective_of_isLocalization convert! (IsLocalization.algEquiv (Algebra.algebraMapSubmonoid (integralClosure R B) M) (S ⊗[R] integralClosure R B) (integralClosure S (S ⊗[R] B))).bijective - rw [← AlgHom.coe_restrictScalars' R, ← AlgEquiv.coe_restrictScalars' R, ← AlgEquiv.coe_toAlgHom] + rw [← AlgHom.coe_restrictScalars' R, ← AlgEquiv.coe_restrictScalars R, ← AlgEquiv.coe_toAlgHom] congr 1 ext1 · apply IsLocalization.algHom_ext M; ext From a0f8570f7130187f9f437adefd9afe15a47db4a9 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Fri, 10 Jul 2026 03:16:52 +0000 Subject: [PATCH 0712/1300] feat(GroupTheory): a characteristic subgroup of a characteristic subgroup is characteristic (#34908) The main theorem proved in this PR is `characteristic_of_characteristic_of_characteristic`. If says that if `K` is a characteristic subgroup of a characteristic subgroup `H` of `G`, then `K` is a characteristic subgroup of `G`. Created with the help of Codex. --- Mathlib/Algebra/Group/Subgroup/Basic.lean | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 0799e6710ca3cd..812e977e3439de 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -316,6 +316,31 @@ instance botCharacteristic : Characteristic (⊥ : Subgroup G) := instance topCharacteristic : Characteristic (⊤ : Subgroup G) := characteristic_iff_map_le.mpr fun _ϕ => le_top +/-- If `H` is a characteristic subgroup of `G`, then every automorphism of `G` induces an +automorphism of `H`. -/ +@[to_additive (attr := simps!) + /-- If `H` is a characteristic additive subgroup of `G`, then every automorphism of `G` induces an + automorphism of `H`. -/] +def _root_.MulAut.characteristic (H : Subgroup G) [H.Characteristic] : MulAut G →* MulAut H where + toFun φ := + { toFun := fun h => ⟨φ h, characteristic_iff_le_comap.mp inferInstance φ h.2⟩ + invFun := fun h => ⟨φ.symm h, characteristic_iff_le_comap.mp inferInstance φ.symm h.2⟩ + left_inv h := Subtype.ext (φ.symm_apply_apply h) + right_inv h := Subtype.ext (φ.apply_symm_apply h) + map_mul' h k := Subtype.ext (map_mul φ (h : G) (k : G)) } + map_one' := rfl + map_mul' _ _ := rfl + +/-- If `H` is a characteristic subgroup of `G` and `K` is a characteristic subgroup of `H`, then +`K` is a characteristic subgroup of `G`. -/ +@[to_additive + /-- If `H` is a characteristic additive subgroup of `G` and `K` is a characteristic additive + subgroup of `H`, then `K` is a characteristic additive subgroup of `G`. -/] +instance characteristic_of_characteristic_of_characteristic [H.Characteristic] + {K : Subgroup H} [hK : K.Characteristic] : (K.map H.subtype).Characteristic := by + refine characteristic_iff_map_eq.2 fun φ ↦ ?_ + have := congr_arg (map H.subtype) <| characteristic_iff_map_eq.1 hK (MulAut.characteristic H φ) + simpa [Subgroup.map_map, MulAut.characteristic] variable (H) From a33a5ccd631025f4a7e4221935c87daafe7d53a0 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 05:12:45 +0000 Subject: [PATCH 0713/1300] feat(Topology/Algebra/ValuativeTopology): checking `IsValuativeTopology` using any compatible valuation (#41527) Add two intro methods of `IsValuativeTopology`. This PR was automatically created from PR #36769 by @jjdishere via a [review comment](https://github.com/leanprover-community/mathlib4/pull/36769#discussion_r3549974641) by @jjdishere. Co-authored-by: @faenuccio Co-authored-by: jjdishere <107380768+jjdishere@users.noreply.github.com> Co-authored-by: Filippo A. E. Nuccio Co-authored-by: Jiedong Jiang --- .../ValuativeRel/ValuativeTopology.lean | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean index b565a57c266789..06703c0c4427b3 100644 --- a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean +++ b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean @@ -92,10 +92,35 @@ variable {K : Type*} [DivisionRing K] [ValuativeRel K] {Γ₀ : Type*} section TopologicalSpace -variable [TopologicalSpace R] [IsValuativeTopology R] (v : Valuation R Γ₀) [v.Compatible] - +variable [TopologicalSpace R] (v : Valuation R Γ₀) [v.Compatible] namespace IsValuativeTopology +/-- If the neighborhoods of every point for a given topology are defined by a valuation `v` +compatible with the valuative relation, then the topology is a valuative topology. -/ +theorem of_mem_nhds_iff_vle (H : ∀ {s : Set R} {x : R}, s ∈ 𝓝 x ↔ + ∃ (γ : (ValueGroup₀ (.ofClass v))ˣ), {z : R | v.restrict (z - x) < γ} ⊆ s) : + IsValuativeTopology R := by + constructor + refine fun {s x} ↦ ⟨fun h_mem ↦ ?_, fun ⟨γ, hγ⟩ ↦ + H.mpr ⟨.mk0 ((orderMonoidIso v) γ) (by simp), subset_trans (by simp [neg_add_eq_sub]) hγ⟩⟩ + obtain ⟨γ, hγ⟩ := H.mp h_mem + exact ⟨.mk0 ((orderMonoidIso v).symm γ) (by simp), subset_trans (by simp [neg_add_eq_sub]) hγ⟩ + +open scoped Pointwise in +/-- In a topological group, if the neighborhoods of zero are defined by a valuation `v` compatible +with the valuative relation, then the underlying topology is valuative. -/ +theorem of_mem_nhds_zero_iff_vle [IsTopologicalAddGroup R] + (H : ∀ {s : Set R}, s ∈ 𝓝 0 ↔ ∃ (γ : (ValueGroup₀ (.ofClass v))ˣ), + {z : R | v.restrict z < γ} ⊆ s) : IsValuativeTopology R := by + apply of_mem_nhds_iff_vle v (fun {s x} ↦ ?_) + rw [← vadd_mem_nhds_vadd_iff (g := -x)] + simp only [vadd_eq_add, neg_add_cancel, H, subset_vadd_set_iff, neg_neg] + suffices ∀ (γ : (ValueGroup₀ (.ofClass v))ˣ), (x +ᵥ {z | v.restrict z < ↑γ}) = + {a | v.restrict (-x + a) < ↑γ} by simp_all [neg_add_eq_sub] + simp [Set.ext_iff, mem_vadd_set_iff_neg_vadd_mem] + +variable [IsValuativeTopology R] + /-- A variant of `IsValuativeTopology.mem_nhds_iff` using subtraction. -/ lemma mem_nhds_iff' {s : Set R} {x : R} : s ∈ 𝓝 x ↔ ∃ γ : (ValueGroupWithZero R)ˣ, { z | valuation R (z - x) < γ } ⊆ s := by @@ -135,6 +160,8 @@ end IsValuativeTopology open IsValuativeTopology +variable [IsValuativeTopology R] + namespace Valuation lemma mem_nhds_iff {s : Set R} {x : R} : s ∈ 𝓝 x ↔ From 0098dd94d810711e831b250902687d3edab9969b Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Fri, 10 Jul 2026 09:48:02 +0000 Subject: [PATCH 0714/1300] feat(RingTheory/Flat): a finite flat `R`-module `M` is locally free if `rankAtStalk M` is constant (#39412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let `M` be a finite flat `R`-module, `p` be a prime ideal of `R`. We show that if `rankAtStalk M` is constant, then there exists `a ∉ p` such that the `M` is free after localization away from `a`. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 1 + .../Algebra/Module/FinitePresentation.lean | 17 +++++ .../Module/LocalizedModule/Submodule.lean | 9 +++ Mathlib/RingTheory/Flat/LocallyFree.lean | 64 +++++++++++++++++++ .../RingTheory/Localization/BaseChange.lean | 8 ++- .../RingTheory/Spectrum/Prime/FreeLocus.lean | 21 ++++++ Mathlib/RingTheory/Support.lean | 6 ++ 7 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 Mathlib/RingTheory/Flat/LocallyFree.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3fe5766f3bb2fd..42345a6fdb224f 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6594,6 +6594,7 @@ public import Mathlib.RingTheory.Flat.FaithfullyFlat.Basic public import Mathlib.RingTheory.Flat.FaithfullyFlat.Descent public import Mathlib.RingTheory.Flat.IsBaseChange public import Mathlib.RingTheory.Flat.Localization +public import Mathlib.RingTheory.Flat.LocallyFree public import Mathlib.RingTheory.Flat.Rank public import Mathlib.RingTheory.Flat.Stability public import Mathlib.RingTheory.Flat.Tensor diff --git a/Mathlib/Algebra/Module/FinitePresentation.lean b/Mathlib/Algebra/Module/FinitePresentation.lean index 71029470069912..de0440401bcbe2 100644 --- a/Mathlib/Algebra/Module/FinitePresentation.lean +++ b/Mathlib/Algebra/Module/FinitePresentation.lean @@ -405,6 +405,23 @@ lemma Module.FinitePresentation.exists_lift_of_isLocalizedModule ← LinearMap.comp_smul, LinearMap.comp_assoc, LinearMap.comp_assoc] simp +/-- Let `M` be a finitely presented `R`-module, `N` be an `R`-module, `S` be a submonoid of `R`, +`Mₚ` be the localization of `M` at `S`, `Nₚ` be the localization of `N` at `S`. Then any surjective +linear map `ϕ : Mₚ →ₗ[R] Nₚ` lifts to a linear map `φ : M →ₗ[R] N` that is surjective after +localization at `S`. -/ +lemma Module.exists_localizedMap_surjective_of_surjective [Module.FinitePresentation R M] + (S : Submonoid R) {Mₚ : Type*} [AddCommGroup Mₚ] [Module R Mₚ] + (f : M →ₗ[R] Mₚ) [IsLocalizedModule S f] {Nₚ : Type*} [AddCommGroup Nₚ] [Module R Nₚ] + (g : N →ₗ[R] Nₚ) [IsLocalizedModule S g] {ϕ : Mₚ →ₗ[R] Nₚ} (hϕ : Function.Surjective ϕ) : + ∃ (φ : M →ₗ[R] N) (s : S) (_ : IsLocalizedModule.map S f g φ = s • ϕ), + Function.Surjective (IsLocalizedModule.map S f g φ) := by + obtain ⟨φ, s, hφ⟩ := FinitePresentation.exists_lift_of_isLocalizedModule S g (ϕ ∘ₗ f) + have hmap : IsLocalizedModule.map S f g φ = s • ϕ := by + apply IsLocalizedModule.linearMap_ext S f g + simp [IsLocalizedModule.map_comp, hφ, LinearMap.smul_comp] + refine ⟨φ, s, hmap, ?_⟩ + simpa only [hmap] using! ((End.isUnit_iff _).mp (IsLocalizedModule.map_units g s)).2.comp hϕ + lemma Module.Finite.exists_smul_of_comp_eq_of_isLocalizedModule [hM : Module.Finite R M] (g₁ g₂ : M →ₗ[R] N) (h : f.comp g₁ = f.comp g₂) : ∃ (s : S), s • g₁ = s • g₂ := by diff --git a/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean b/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean index 5f9397f0e4d59c..a237aa5d75fa28 100644 --- a/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean +++ b/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean @@ -373,4 +373,13 @@ lemma localized'_range_eq_range_localizedMap (g : M →ₗ[R] P) : (range g).localized' S p f' = range ((map p f f' g).extendScalarsOfIsLocalization p S) := SetLike.ext (by apply SetLike.ext_iff.mp (f.range_localizedMap_eq_localized₀_range p f' g).symm) +lemma localizedMap_surjective_iff_subsingleton_localized_coker {R M N : Type*} [CommRing R] + [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N] (S : Submonoid R) (φ : M →ₗ[R] N) : + Function.Surjective (LocalizedModule.map S φ) ↔ + Subsingleton (LocalizedModule S (N ⧸ φ.range)) := by + simp [(localizedQuotientEquiv S φ.range).symm.subsingleton_congr, + LinearMap.localized'_range_eq_range_localizedMap (Localization S) S + (LocalizedModule.mkLinearMap S M) (LocalizedModule.mkLinearMap S N), + LinearMap.range_eq_top, LocalizedModule.map, mapExtendScalars] + end LinearMap diff --git a/Mathlib/RingTheory/Flat/LocallyFree.lean b/Mathlib/RingTheory/Flat/LocallyFree.lean new file mode 100644 index 00000000000000..9d3e9b59022823 --- /dev/null +++ b/Mathlib/RingTheory/Flat/LocallyFree.lean @@ -0,0 +1,64 @@ +/- +Copyright (c) 2026 Yongle Hu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yongle Hu +-/ +module + +public import Mathlib.RingTheory.Spectrum.Prime.FreeLocus + +/-! +# A finite flat module `M` is locally free if `rankAtStalk M` is constant +-/ + +public section + +namespace Module + +variable {R : Type*} [CommRing R] {M N : Type*} [AddCommGroup M] [Module R M] [Module.Finite R M] + [Module.Flat R M] [AddCommGroup N] [Module R N] [Module.Finite R N] [Module.Flat R N] + +open LocalizedModule + +attribute [local instance] Module.free_of_flat_of_isLocalRing + +lemma bijective_of_surjective_of_rankAtStalk_eq {φ : M →ₗ[R] N} (hs : Function.Surjective φ) + (h : ∀ (m : Ideal R) [m.IsMaximal], + rankAtStalk M ⟨m, inferInstance⟩ = rankAtStalk N ⟨m, inferInstance⟩) : + Function.Bijective φ := + bijective_of_localized_maximal φ fun m _ ↦ + OrzechProperty.bijective_of_surjective_of_finrank_le (map m.primeCompl φ) + (map_surjective m.primeCompl φ hs) (h m).le + +variable (M) in +/-- Let `M` be a finite flat `R`-module, `p` be a prime ideal of `R`. If `rankAtStalk M` is +constant, then there exists `a ∉ p` such that `M` is free after localization away from `a`. -/ +theorem Free.away_of_finite_of_flat_of_rankAtStalk_constant (p : Ideal R) [p.IsPrime] + (h : ∀ (m : Ideal R) [m.IsMaximal], + rankAtStalk M ⟨m, inferInstance⟩ = rankAtStalk M ⟨p, inferInstance⟩) : + ∃ a ∉ p, Module.Free (Localization.Away a) (LocalizedModule.Away a M) := by + rcases subsingleton_or_nontrivial R with _ | _ + · use 1, Ideal.IsPrime.one_notMem ‹_› + exact Module.Free.of_subsingleton' (Localization.Away 1) (LocalizedModule.Away 1 M) + · let Rₚ := Localization.AtPrime p + let n := rankAtStalk M ⟨p, inferInstance⟩ + let f : (Fin n →₀ R) →ₗ[R] Fin n →₀ Rₚ := Finsupp.mapRange.linearMap (Algebra.linearMap R Rₚ) + let g : M →ₗ[R] LocalizedModule.AtPrime p M := LocalizedModule.mkLinearMap p.primeCompl M + obtain ⟨φ, -, -, hφps⟩ := exists_localizedMap_surjective_of_surjective p.primeCompl f g + ((finBasis Rₚ (LocalizedModule.AtPrime p M)).repr.restrictScalars R).symm.surjective + obtain ⟨a, hap, hφas⟩ := by + refine exists_localizedMap_away_surjective_of_localizedMap_atPrime_surjective p φ ?_ + simpa [LocalizedModule.coe_map_eq f g] + have : Module.Free (Localization.Away a) (LocalizedModule.Away a (Fin n →₀ R)) := + free_of_isLocalizedModule (Submonoid.powers a) (mkLinearMap (Submonoid.powers a) (Fin n →₀ R)) + let φₐ : LocalizedModule.Away a (Fin n →₀ R) →ₗ[Localization.Away a] LocalizedModule.Away a M := + LocalizedModule.map (Submonoid.powers a) φ + refine ⟨a, hap, Module.Free.of_equiv <| LinearEquiv.ofBijective φₐ <| + bijective_of_surjective_of_rankAtStalk_eq hφas <| fun m _ ↦ ?_⟩ + obtain ⟨𝔪, _, hm𝔪⟩ : ∃ 𝔪 : Ideal R, 𝔪.IsMaximal ∧ PrimeSpectrum.comap + (algebraMap R (Localization (Submonoid.powers a))) ⟨m, inferInstance⟩ ≤ 𝔪 := + (m.comap (algebraMap R (Localization.Away a))).exists_le_maximal Ideal.IsPrime.ne_top' + simp [rankAtStalk_isBaseChange (LocalizedModule.isBaseChange (Submonoid.powers a) _), + rankAtStalk_eq_of_le_of_finite_of_flat' M hm𝔪, h 𝔪, n] + +end Module diff --git a/Mathlib/RingTheory/Localization/BaseChange.lean b/Mathlib/RingTheory/Localization/BaseChange.lean index 1ee7a99f5f08af..5be2d5aa24a705 100644 --- a/Mathlib/RingTheory/Localization/BaseChange.lean +++ b/Mathlib/RingTheory/Localization/BaseChange.lean @@ -38,6 +38,11 @@ theorem IsLocalizedModule.isBaseChange [IsLocalizedModule S f] : IsBaseChange A refine ⟨ℓ.extendScalarsOfIsLocalization S A, by simp, fun g'' h ↦ ?_⟩ cases h₂ (LinearMap.restrictScalars R g'') h; rfl +variable (M) in +lemma LocalizedModule.isBaseChange : + IsBaseChange (Localization S) (LocalizedModule.mkLinearMap S M) := + IsLocalizedModule.isBaseChange S (Localization S) (LocalizedModule.mkLinearMap S M) + /-- The map `(f : M →ₗ[R] M')` is a localization of modules iff the map `(Localization S) × M → N, (s, m) ↦ s • f m` is the tensor product (insomuch as it is the universal bilinear map). @@ -62,8 +67,7 @@ variable (M) in an `S⁻¹R`-module. -/ noncomputable def LocalizedModule.equivTensorProduct : LocalizedModule S M ≃ₗ[Localization S] Localization S ⊗[R] M := - IsLocalizedModule.isBaseChange S (Localization S) - (LocalizedModule.mkLinearMap S M) |>.equiv.symm + (LocalizedModule.isBaseChange S M).equiv.symm @[simp] lemma LocalizedModule.equivTensorProduct_symm_apply_tmul (x : M) (r : R) (s : S) : diff --git a/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean b/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean index 50ad1fe06dcaa0..0bd9b1d81f856c 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean @@ -334,6 +334,27 @@ lemma rankAtStalk_baseChange {S : Type*} [CommRing S] [Algebra R S] (p : PrimeSp rw [rankAtStalk, e.finrank_eq] apply Module.finrank_baseChange +lemma rankAtStalk_isBaseChange {S Mₛ : Type*} [CommRing S] [Algebra R S] [AddCommGroup Mₛ] + [Module R Mₛ] [Module S Mₛ] [IsScalarTower R S Mₛ] {f : M →ₗ[R] Mₛ} (hf : IsBaseChange S f) + (p : PrimeSpectrum S) : rankAtStalk Mₛ p = rankAtStalk M (p.comap (algebraMap R S)) := by + simp [rankAtStalk_eq_of_equiv hf.equiv.symm, rankAtStalk_baseChange] + +variable (M) in +lemma rankAtStalk_eq_of_le_of_finite_of_flat {p q : PrimeSpectrum R} (hpq : p ≤ q) : + rankAtStalk M p = rankAtStalk M q := by + let S := Localization.AtPrime q.asIdeal + obtain ⟨P, rfl⟩ : p ∈ Set.range (PrimeSpectrum.comap (algebraMap R S)) := by + rw [PrimeSpectrum.localization_comap_range S q.asIdeal.primeCompl] + exact disjoint_compl_left_iff.mpr hpq + rw [← rankAtStalk_isBaseChange (LocalizedModule.isBaseChange q.asIdeal.primeCompl M), + rankAtStalk_eq_finrank_of_free] + simp [rankAtStalk] + +variable (M) in +lemma rankAtStalk_eq_of_le_of_finite_of_flat' {p q : Ideal R} [hp : p.IsPrime] [hq : q.IsPrime] + (hpq : p ≤ q) : rankAtStalk M ⟨p, hp⟩ = rankAtStalk M ⟨q, hq⟩ := + rankAtStalk_eq_of_le_of_finite_of_flat M hpq + /-- See `rankAtStalk_tensorProduct_of_isScalarTower` for a hetero-basic version. -/ lemma rankAtStalk_tensorProduct (N : Type*) [AddCommGroup N] [Module R N] [Module.Finite R N] [Module.Flat R N] : rankAtStalk (M ⊗[R] N) = rankAtStalk M * rankAtStalk (R := R) N := by diff --git a/Mathlib/RingTheory/Support.lean b/Mathlib/RingTheory/Support.lean index f6dfd259672600..b5e49ab6706dab 100644 --- a/Mathlib/RingTheory/Support.lean +++ b/Mathlib/RingTheory/Support.lean @@ -238,6 +238,12 @@ lemma IsLocalizedModule.exists_subsingleton_away {M' : Type*} [AddCommMonoid M'] have : Subsingleton (LocalizedModule p.primeCompl M) := e.subsingleton exact LocalizedModule.exists_subsingleton_away p +lemma Module.exists_localizedMap_away_surjective_of_localizedMap_atPrime_surjective (p : Ideal R) + [p.IsPrime] (φ : N →ₗ[R] M) (hφ : Function.Surjective (LocalizedModule.map p.primeCompl φ)) : + ∃ a ∉ p, Function.Surjective (LocalizedModule.map (Submonoid.powers a) φ) := by + simp_rw [φ.localizedMap_surjective_iff_subsingleton_localized_coker] at hφ ⊢ + exact LocalizedModule.exists_subsingleton_away p + /-- `Supp(M/IM) = Supp(M) ∩ Z(I)`. -/ @[stacks 00L3 "(1)"] theorem Module.support_quotient (I : Ideal R) : From b587a4efdcc639b6fccfefbfd55d2ce2dc6d27dd Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 11:59:19 +0000 Subject: [PATCH 0715/1300] chore: update Mathlib dependencies 2026-07-10 (#41563) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 8c018e595b3ff1..a7a14490b470cf 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "232c5be1450cb3e59fd3486ab87393af0a98986e", + "rev": "e68e6d1b0defc3f2df735986824b96ae29a7bd46", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From dc3d68789729f0b8ddd60f7b597643d0943fcfbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20G=C3=B3mez=20Zaragoza?= <51706873+javgomzar@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:54:32 +0000 Subject: [PATCH 0716/1300] feat(FinitelyPresentedGroup): add finite groups instance (#38114) Add `IsFinitelyPresented` instance for finite groups. Co-authored-by: Hang Lu Su , Thomas Browning Co-authored-by: Javier Gomez Zaragoza Co-authored-by: Hang Lu Su --- .../GroupTheory/FinitelyPresentedGroup.lean | 63 ++++++++++++------- Mathlib/GroupTheory/Schreier.lean | 14 ++++- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean index c72f4d89cfe415..449ec578624bd0 100644 --- a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean +++ b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean @@ -2,11 +2,12 @@ Copyright (c) 2025 Hang Lu Su. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Riccardo Brasca, Fabrizio Barroero, Stefano Francaviglia, - Francesco Milizia, Valerio Proietti, Hang Lu Su, Lawrence Wu + Francesco Milizia, Valerio Proietti, Hang Lu Su, Lawrence Wu, Javier Gómez Zaragoza -/ module public import Mathlib.Algebra.Group.Subgroup.Basic +public import Mathlib.GroupTheory.Schreier public import Mathlib.Data.Set.Finite.Basic public import Mathlib.Data.Finite.Sum public import Mathlib.GroupTheory.FreeGroup.Basic @@ -21,13 +22,13 @@ public import Mathlib.Logic.Equiv.Fin.Basic This file defines finitely presented groups. ## Main definitions -* `Subgroup.IsNormalClosureFG N`: says that the subgroup `N` is the normal closure of a - finitely generated subgroup. +* `Subgroup.IsFinitelyNormallyGenerated N`: says that the subgroup `N` is the normal closure of a + finite set. * `IsFinitelyPresented`: defines when a group is finitely presented. ## Main results -* `Subgroup.IsNormalClosureFG.map`: Being the normal closure of a finite set is preserved under - surjective homomorphism. +* `Subgroup.IsFinitelyNormallyGenerated.map`: Being the normal closure of a finite set is preserved +under surjective homomorphism. * `IsFinitelyPresented.equiv`: finitely presented groups are closed under isomorphism. ## Tags @@ -38,32 +39,40 @@ finitely presented group, finitely generated normal closure variable {G H α β : Type*} [Group G] [Group H] -/-- `N.IsNormalClosureFG` says that the subgroup `N` is the normal closure of a finitely-generated -subgroup. -/ -@[to_additive /-- `N.IsNormalClosureFG` says that the additive subgroup `N` is the normal closure -of an additive finitely-generated subgroup. -/] -def Subgroup.IsNormalClosureFG (N : Subgroup G) : Prop := +/-- `N.IsFinitelyNormallyGenerated` says that the subgroup `N` is the normal closure + of a finite set. -/ +@[to_additive /-- `N.IsFinitelyNormallyGenerated` says that the additive subgroup `N` +is the normal closure of a finite set. -/] +def Subgroup.IsFinitelyNormallyGenerated (N : Subgroup G) : Prop := ∃ S : Set G, S.Finite ∧ Subgroup.normalClosure S = N -namespace Subgroup.IsNormalClosureFG +@[deprecated (since := "2026-06-25")] +alias Subgroup.IsNormalClosureFG := Subgroup.IsFinitelyNormallyGenerated + +namespace Subgroup.IsFinitelyNormallyGenerated /-- Being the normal closure of a finite set is invariant under surjective homomorphism. -/ @[to_additive /-- Being the additive normal closure of a finite set is invariant under surjective homomorphism. -/] -protected theorem map {N : Subgroup G} (hN : N.IsNormalClosureFG) - {f : G →* H} (hf : Function.Surjective f) : (N.map f).IsNormalClosureFG := by +protected theorem map {N : Subgroup G} (hN : N.IsFinitelyNormallyGenerated) + {f : G →* H} (hf : Function.Surjective f) : (N.map f).IsFinitelyNormallyGenerated := by obtain ⟨S, hSfinite, hSclosure⟩ := hN refine ⟨f '' S, hSfinite.image _, ?_⟩ rw [← hSclosure, Subgroup.map_normalClosure _ _ hf] +@[to_additive] +theorem of_FG (N : Subgroup G) [N.Normal] [h : Group.FG N] : N.IsFinitelyNormallyGenerated := by + obtain ⟨S, rfl, hS⟩ := N.fg_iff.mp ((Group.fg_iff_subgroup_fg N).mp h) + exact ⟨S, hS, le_antisymm (normalClosure_le_normal subset_closure) closure_le_normalClosure⟩ + open Function Set Subgroup in /-- The preimage of a finitely generated normal subgroup by a surjective homomorphism with a finitely generated kernel is finitely generated. -/ @[to_additive /-- The preimage of a finitely generated normal subgroup by a surjective additive homomorphism with a finitely generated kernel is finitely generated. -/] -protected theorem comap {N : Subgroup H} (hN : N.IsNormalClosureFG) - {f : G →* H} (hf : Surjective f) (hf' : f.ker.IsNormalClosureFG) : - (N.comap f).IsNormalClosureFG := by +protected theorem comap {N : Subgroup H} (hN : N.IsFinitelyNormallyGenerated) + {f : G →* H} (hf : Surjective f) (hf' : f.ker.IsFinitelyNormallyGenerated) : + (N.comap f).IsFinitelyNormallyGenerated := by obtain ⟨S, hS_fin, hS⟩ := hN obtain ⟨T, hT_fin, hT⟩ := hf' have : ∃ S', S'.Finite ∧ f '' S' = S := @@ -75,23 +84,24 @@ protected theorem comap {N : Subgroup H} (hN : N.IsNormalClosureFG) /-- The trivial group is the normal closure of a finite set of relations. -/ @[to_additive /-- The trivial additive group is the normal closure of a finite set of relations. -/] -protected theorem bot : (⊥ : Subgroup G).IsNormalClosureFG := - ⟨∅, Finite.of_subsingleton, normalClosure_empty⟩ +protected theorem bot : (⊥ : Subgroup G).IsFinitelyNormallyGenerated := of_FG _ -end Subgroup.IsNormalClosureFG +end Subgroup.IsFinitelyNormallyGenerated /-- An additive group is finitely presented if it has a finite generating set such that the kernel of the induced map from the free additive group on that set is the normal closure of finitely many relations. -/ class AddGroup.IsFinitelyPresented (G : Type*) [AddGroup G] : Prop where - out : ∃ (n : ℕ) (φ : FreeAddGroup (Fin n) →+ G), Function.Surjective φ ∧ φ.ker.IsNormalClosureFG + out : ∃ (n : ℕ) (φ : FreeAddGroup (Fin n) →+ G), + Function.Surjective φ ∧ φ.ker.IsFinitelyNormallyGenerated /-- A group is finitely presented if it has a finite generating set such that the kernel of the induced map from the free group on that set is the normal closure of finitely many relations. -/ @[mk_iff, to_additive existing] class Group.IsFinitelyPresented (G : Type*) [Group G] : Prop where - out : ∃ (n : ℕ) (φ : FreeGroup (Fin n) →* G), Function.Surjective φ ∧ φ.ker.IsNormalClosureFG + out : ∃ (n : ℕ) (φ : FreeGroup (Fin n) →* G), + Function.Surjective φ ∧ φ.ker.IsFinitelyNormallyGenerated namespace Group.IsFinitelyPresented @@ -108,7 +118,7 @@ finitely generated as a normal subgroup is finitely presented. -/ @[to_additive /-- The image of a finitely presented additive group under a surjective additive homomorphism whose kernel is finitely generated as a normal subgroup is finitely presented. -/] theorem of_surjective [hG : IsFinitelyPresented G] (f : G →* H) - (hf_surj : Function.Surjective f) (hf_ker : f.ker.IsNormalClosureFG) : + (hf_surj : Function.Surjective f) (hf_ker : f.ker.IsFinitelyNormallyGenerated) : IsFinitelyPresented H := by obtain ⟨n, φ, hφ_surj, hφ_ker⟩ := hG.out refine ⟨n, f.comp φ, hf_surj.comp hφ_surj, ?_⟩ @@ -120,7 +130,7 @@ which is finitely generated as a normal subgroup is finitely presented. -/ @[to_additive /-- The quotient of a finitely presented additive group by an additive subgroup which is finitely generated as a normal subgroup is finitely presented. -/] theorem quotient [hG : IsFinitelyPresented G] (N : Subgroup G) [N.Normal] - (hN : N.IsNormalClosureFG) : IsFinitelyPresented (G ⧸ N) := + (hN : N.IsFinitelyNormallyGenerated) : IsFinitelyPresented (G ⧸ N) := of_surjective (QuotientGroup.mk' N) (QuotientGroup.mk'_surjective N) ((QuotientGroup.ker_mk' N).symm ▸ hN) @@ -159,4 +169,11 @@ instance [IsFinitelyPresented G] [IsFinitelyPresented H] : obtain ⟨_, sH, ⟨_ : Finite sH, ⟨φH⟩⟩⟩ := exists_mulEquiv_presentedGroup (G := H) exact equiv ((PresentedGroup.coprodPresentations sG sH).trans (MulEquiv.coprodCongr φG φH).symm) +variable (G) + +/-- Any finite group is finitely presented. -/ +@[to_additive] +instance [Finite G] : IsFinitelyPresented G := + of_surjective FreeGroup.prod FreeGroup.prod_surjective (.of_FG FreeGroup.prod.ker) + end Group.IsFinitelyPresented diff --git a/Mathlib/GroupTheory/Schreier.lean b/Mathlib/GroupTheory/Schreier.lean index 1133fbe3ba7e88..301f28f1521dc7 100644 --- a/Mathlib/GroupTheory/Schreier.lean +++ b/Mathlib/GroupTheory/Schreier.lean @@ -64,6 +64,7 @@ namespace Subgroup variable {G : Type*} [Group G] {H : Subgroup G} {R S : Set G} +@[to_additive] theorem closure_mul_image_mul_eq_top (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) (hS : closure S = ⊤) : (closure ((R * S).image fun g => g * (hR.toRightFun g : G)⁻¹)) * R = ⊤ := by @@ -90,7 +91,9 @@ theorem closure_mul_image_mul_eq_top /-- **Schreier's Lemma**: If `R : Set G` and `H : Subgroup G` are complements with `1 ∈ R`, and if `G` is generated by `S : Set G`, then `H` is generated by the `Set` `(R * S).image (fun g ↦ g * (hR.toRightFun g)⁻¹)`. -/ -@[wikidata Q3229345] +@[wikidata Q3229345, to_additive /-- **Schreier's Lemma**: If `R : Set G` and `H : AddSubgroup G` +are complements with `0 ∈ R`, and if `G` is generated by `S : Set G`, +then `H` is generated by the `Set` `(R + S).image (fun g ↦ g - (hR.toRightFun g))`. -/] theorem closure_mul_image_eq (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) (hS : closure S = ⊤) : closure ((R * S).image fun g => g * (hR.toRightFun g : G)⁻¹) = H := by have hU : closure ((R * S).image fun g => g * (hR.toRightFun g : G)⁻¹) ≤ H := by @@ -111,6 +114,9 @@ theorem closure_mul_image_eq (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) /-- **Schreier's Lemma**: If `R : Set G` and `H : Subgroup G` are complements with `1 ∈ R`, and if `G` is generated by `S : Set G`, then `H` is generated by the `Set` `(R * S).image (fun g ↦ g * (hR.toRightFun g)⁻¹)`. -/ +@[to_additive /-- **Schreier's Lemma**: If `R : Set G` and `H : AddSubgroup G` are complements with +`0 ∈ R`, and if `G` is generated by `S : Set G`, then `H` is generated by the `Set` + `(R + S).image (fun g ↦ g - (hR.toRightFun g))`. -/] theorem closure_mul_image_eq_top (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) (hS : closure S = ⊤) : closure ((R * S).image fun g => ⟨g * (hR.toRightFun g : G)⁻¹, hR.mul_inv_toRightFun_mem g⟩ : Set H) = ⊤ := by @@ -120,6 +126,9 @@ theorem closure_mul_image_eq_top (hR : IsComplement H R) (hR1 : (1 : G) ∈ R) /-- **Schreier's Lemma**: If `R : Finset G` and `H : Subgroup G` are complements with `1 ∈ R`, and if `G` is generated by `S : Finset G`, then `H` is generated by the `Finset` `(R * S).image (fun g ↦ g * (hR.toRightFun g)⁻¹)`. -/ +@[to_additive /-- **Schreier's Lemma**: If `R : Finset G` and `H : AddSubgroup G` are complements +with `0 ∈ R`, and if `G` is generated by `S : Finset G`, then `H` is generated by the `Finset` + `(R + S).image (fun g ↦ g - (hR.toRightFun g))`. -/] theorem closure_mul_image_eq_top' [DecidableEq G] {R S : Finset G} (hR : IsComplement (H : Set G) R) (hR1 : (1 : G) ∈ R) (hS : closure (S : Set G) = ⊤) : @@ -129,6 +138,7 @@ theorem closure_mul_image_eq_top' [DecidableEq G] {R S : Finset G} variable (H) +@[to_additive] theorem exists_finset_card_le_mul [FiniteIndex H] {S : Finset G} (hS : closure (S : Set G) = ⊤) : ∃ T : Finset H, #T ≤ H.index * #S ∧ closure (T : Set H) = ⊤ := by letI := H.fintypeQuotientOfFiniteIndex @@ -151,6 +161,8 @@ theorem exists_finset_card_le_mul [FiniteIndex H] {S : Finset G} (hS : closure ( /-- **Schreier's Lemma**: A finite index subgroup of a finitely generated group is finitely generated. -/ +@[to_additive /-- **Schreier's Lemma**: A finite index additive subgroup of a finitely generated + additive group is finitely generated. -/] instance fg_of_index_ne_zero [hG : Group.FG G] [FiniteIndex H] : Group.FG H := by obtain ⟨S, hS⟩ := hG.1 obtain ⟨T, -, hT⟩ := exists_finset_card_le_mul H hS From 2028213c0d615301c14937e52dcc899ee04481c4 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Fri, 10 Jul 2026 12:54:34 +0000 Subject: [PATCH 0717/1300] feat(RingTheory/PicardGroup): invertible modules over semirings are locally free (#41528) Theorem 10.7 in *Facets of module theory over semirings* (Borger & Jun, https://arxiv.org/abs/2405.18645, Adv Math). Aristotle [discovered](https://aristotle.harmonic.fun/dashboard/requests/3e3dc70f-a9aa-4b84-a6fd-a812851c3bfb) a simpler proof using `Invertible.bijective_of_surjective` available in Mathlib. (The task started at 01:37 AM and Aristotle found the proof at 01:46 AM.) Also generalizes lemmas and adds a new def about local semirings. Co-authored-by: Aristotle (Harmonic) [aristotle-harmonic@harmonic.fun](mailto:aristotle-harmonic@harmonic.fun) --- Mathlib/RingTheory/LocalRing/Basic.lean | 31 +++++++---- .../LocalRing/MaximalIdeal/Defs.lean | 4 +- Mathlib/RingTheory/PicardGroup.lean | 52 ++++++++++++++----- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/Mathlib/RingTheory/LocalRing/Basic.lean b/Mathlib/RingTheory/LocalRing/Basic.lean index a190f2b83505d5..63430eac95cd99 100644 --- a/Mathlib/RingTheory/LocalRing/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/Basic.lean @@ -36,6 +36,27 @@ theorem of_nonunits_add [Nontrivial R] isUnit_or_isUnit_of_add_one {a b} hab := or_iff_not_and_not.2 fun H => h a b H.1 H.2 <| hab.symm ▸ isUnit_one +variable [IsLocalRing R] + +theorem isUnit_or_isUnit_of_isUnit_add {a b : R} (h : IsUnit (a + b)) : IsUnit a ∨ IsUnit b := by + rcases h with ⟨u, hu⟩ + rw [← Units.inv_mul_eq_one, mul_add] at hu + apply Or.imp _ _ (isUnit_or_isUnit_of_add_one hu) <;> exact (u⁻¹.isUnit_units_mul _).mp + +theorem nonunits_add {a b : R} (ha : a ∈ nonunits R) (hb : b ∈ nonunits R) : a + b ∈ nonunits R := + fun H ↦ not_or_intro ha hb (isUnit_or_isUnit_of_isUnit_add H) + +variable (R) in +/-- The nonunits of a local semiring form an additive submonoid. -/ +@[expose] def nonunitsAddSubmonoid : AddSubmonoid R where + carrier := nonunits R + zero_mem' := by simp + add_mem' := nonunits_add + +theorem exists_of_isUnit_sum {ι : Type*} {s : Finset ι} {f : ι → R} + (h : IsUnit (∑ i ∈ s, f i)) : ∃ i ∈ s, IsUnit (f i) := by + contrapose! h; exact (nonunitsAddSubmonoid R).sum_mem h + end Semiring section CommSemiring @@ -66,16 +87,6 @@ theorem of_unique_nonzero_prime (h : ∃! P : Ideal R, P ≠ ⊥ ∧ Ideal.IsPri · rintro rfl exact hPnot_top (hM.1.2 P (bot_lt_iff_ne_bot.2 hPnonzero))) -variable [IsLocalRing R] - -theorem isUnit_or_isUnit_of_isUnit_add {a b : R} (h : IsUnit (a + b)) : IsUnit a ∨ IsUnit b := by - rcases h with ⟨u, hu⟩ - rw [← Units.inv_mul_eq_one, mul_add] at hu - apply Or.imp _ _ (isUnit_or_isUnit_of_add_one hu) <;> exact isUnit_of_mul_isUnit_right - -theorem nonunits_add {a b : R} (ha : a ∈ nonunits R) (hb : b ∈ nonunits R) : a + b ∈ nonunits R := - fun H => not_or_intro ha hb (isUnit_or_isUnit_of_isUnit_add H) - end CommSemiring section Ring diff --git a/Mathlib/RingTheory/LocalRing/MaximalIdeal/Defs.lean b/Mathlib/RingTheory/LocalRing/MaximalIdeal/Defs.lean index 02c3f6eadec3d6..43f39672d83532 100644 --- a/Mathlib/RingTheory/LocalRing/MaximalIdeal/Defs.lean +++ b/Mathlib/RingTheory/LocalRing/MaximalIdeal/Defs.lean @@ -28,9 +28,7 @@ variable (R : Type*) [CommSemiring R] [IsLocalRing R] /-- The ideal of elements that are not units. -/ def maximalIdeal : Ideal R where - carrier := nonunits R - zero_mem' := zero_mem_nonunits.2 <| zero_ne_one - add_mem' {_ _} hx hy := nonunits_add hx hy + __ := nonunitsAddSubmonoid R smul_mem' _ _ := mul_mem_nonunits_right end IsLocalRing diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 9c22008a85eba4..12bfc620754045 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -367,6 +367,35 @@ instance (L) [AddCommMonoid L] [Module R L] [Module A L] [IsScalarTower R A L] [Module.Invertible A L] : Module.Invertible A (L ⊗[R] M) := .congr (AlgebraTensorModule.cancelBaseChange R A A L M) +/-- An invertible module over a commutative semiring is Zariski-locally free of rank 1. +Theorem 10.7 in [BorgerJun2024]. + +More precisely, there is a finite set of elements of `R` that generate the unit ideal, +and localizing `M` at any one of them yields a free module. + +Finite projective modules over a local commutative semiring may not be free, +see Remark 7.10, Example 9.6 and 9.8. -/ +theorem exists_finset_free_localization : + ∃ s : Finset R, Ideal.span (s : Set R) = ⊤ ∧ + ∀ r ∈ s, Free (Localization.Away r) (LocalizedModule.Away r M) := by + classical + -- write 1 = ∑ᵢ fᵢ(mᵢ) with `mᵢ : M` and `fᵢ : Dual R M` + obtain ⟨S, hS⟩ := ((linearEquiv R M).symm 1).exists_finset + refine ⟨S.image fun i ↦ i.1 i.2, ?_, fun r hr ↦ ?_⟩ + -- Part 1: The evaluations fᵢ(mᵢ) generate the unit ideal + · simpa [Ideal.eq_top_iff_one, (LinearEquiv.symm_apply_eq _).mp hS, linearEquiv] + using Ideal.sum_mem _ fun i hi ↦ Ideal.subset_span (Finset.mem_image_of_mem _ hi) + -- Part 2: After localizing at any f(m), the module becomes free + obtain ⟨⟨f, m⟩, _, rfl⟩ := Finset.mem_image.mp hr + -- Extend f to a R_{f(m)}-linear functional f' on the localized module + let f' : Dual (Localization.Away (f m)) (LocalizedModule.Away (f m) M) := + .extendScalarsOfIsLocalization (.powers (f m)) _ <| IsLocalizedModule.map + (.powers (f m)) (LocalizedModule.mkLinearMap _ M) (Algebra.linearMap R _) f + -- f'(m/1) = f(m)/1 is a unit in R_{f(m)}, so f' is surjective and therefore bijective + have surj : Function.Surjective f' := LinearMap.range_eq_top.mp <| Ideal.eq_top_of_isUnit_mem + _ ⟨_, IsLocalizedModule.map_apply ..⟩ (IsLocalization.Away.algebraMap_isUnit (f m)) + exact .of_equiv <| .symm <| .ofBijective f' (bijective_of_surjective surj) + end CommSemiring end Algebra @@ -404,8 +433,7 @@ open CommRing (Pic) noncomputable instance : CommGroup (Pic R) := fast_instance% (equivShrink _).symm.commGroup -variable (M N : Type*) [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] - [Module.Invertible R M] [Module.Invertible R N] +variable [Module.Invertible R M] [Module.Invertible R N] instance : Module.Invertible R (Finite.reprₛ R M) := .congr (Finite.reprEquivₛ R M).symm @@ -503,11 +531,14 @@ instance [Subsingleton (Pic R)] : Free R M := have := subsingleton_iffₛ.mp ‹_› (Finite.reprₛ R M) inferInstance .of_equiv (Finite.reprEquivₛ R M) -/- TODO: it's still true that the Picard group of a (commutative) local semiring is trivial; -in fact invertible modules over a semiring are Zariski-locally free (but projective module may -not be). See Remark 7.10, Example 9.6 and 9.8, and Theorem 11.7 in [BorgerJun2024]. -/ -instance (R) [CommRing R] [IsLocalRing R] : Subsingleton (Pic R) := - subsingleton_iff.mpr fun _ _ _ _ ↦ free_of_flat_of_isLocalRing +/-- The Picard group of a local semiring is trivial. -/ +instance [IsLocalRing R] : Subsingleton (Pic R) := subsingleton_iffₛ.mpr fun M _ _ _ ↦ by + obtain ⟨S, hS⟩ := ((Invertible.linearEquiv R M).symm 1).exists_finset + replace hS : 1 = ∑ i ∈ S, i.1 i.2 := by + simpa [LinearEquiv.symm_apply_eq, Invertible.linearEquiv] using hS + obtain ⟨⟨f, m⟩, mem, hfm⟩ := IsLocalRing.exists_of_isUnit_sum (hS ▸ isUnit_one) + exact .of_equiv <| .symm <| .ofBijective f (Invertible.bijective_of_surjective <| + LinearMap.range_eq_top.mp <| Ideal.eq_top_of_isUnit_mem _ ⟨m, rfl⟩ hfm) /-- The Picard group of a semilocal ring is trivial. -/ instance (R) [CommRing R] [Finite (MaximalSpectrum R)] : Subsingleton (Pic R) := @@ -592,18 +623,15 @@ end PicardGroup namespace Module.Invertible -variable (R M : Type*) [CommRing R] [AddCommGroup M] [Module R M] [Module.Invertible R M] +variable [Module.Invertible R M] -set_option backward.defeqAttrib.useBackward true in --- TODO: generalize to CommSemiring by generalizing `CommRing.Pic.instSubsingletonOfIsLocalRing` theorem tensorProductComm_eq_refl : TensorProduct.comm R M M = .refl .. := by let f (P : Ideal R) [P.IsMaximal] := LocalizedModule.mkLinearMap P.primeCompl M let ff (P : Ideal R) [P.IsMaximal] := TensorProduct.map (f P) (f P) refine LinearEquiv.toLinearMap_injective <| LinearMap.eq_of_localization_maximal _ ff _ ff _ _ fun P _ ↦ .trans (b := (TensorProduct.comm ..).toLinearMap) ?_ ?_ · apply IsLocalizedModule.linearMap_ext P.primeCompl (ff P) (ff P) - ext; dsimp - apply IsLocalizedModule.map_apply + ext; exact IsLocalizedModule.map_apply _ (ff P) .. let Rp := Localization P.primeCompl have ⟨e⟩ := free_iff_linearEquiv.mp (inferInstance : Free Rp (LocalizedModule P.primeCompl M)) have e := e.restrictScalars R From 286a924d324fcb0280beb30182341d0f0d52ef01 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:08:18 +0000 Subject: [PATCH 0718/1300] chore: measure longest (re-)build path instructions (#41331) This mirrors the setup added in leanprover/lean4#14261. Co-authored-by: Joscha --- scripts/bench/build/README.md | 5 ++ scripts/bench/build/lakeprof_measurements.py | 84 ++++++++++++++++++++ scripts/bench/build/run | 3 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100755 scripts/bench/build/lakeprof_measurements.py diff --git a/scripts/bench/build/README.md b/scripts/bench/build/README.md index eab2e8e62d9be6..7b328289b777b2 100644 --- a/scripts/bench/build/README.md +++ b/scripts/bench/build/README.md @@ -18,6 +18,11 @@ The following metrics are collected from `lakeprof report`: - `build/lakeprof/longest build path//wall-clock` - `build/lakeprof/longest rebuild path//wall-clock` +The following metrics are collected from a combination of `lakeprof report` and the per-module instructions: + +- `build/lakeprof/longest build path//instructions` +- `build/lakeprof/longest rebuild path//instructions` + The following metrics are collected individually for each module: - `build/module///lines` diff --git a/scripts/bench/build/lakeprof_measurements.py b/scripts/bench/build/lakeprof_measurements.py new file mode 100755 index 00000000000000..db97dcb3bd1f1a --- /dev/null +++ b/scripts/bench/build/lakeprof_measurements.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 + +# Derives the `build/lakeprof/*` measurements from `lakeprof report` and the +# existing contents of the measurements file. The results are appended back onto +# the measurements file. +# +# Must be run from the src dir so that lakeprof can collect the metadata it +# needs. + +import argparse +import json +import re +import subprocess +import sys +from dataclasses import dataclass +from pathlib import Path + + +def save_measurement( + output: Path, metric: str, value: float, unit: str | None = None +) -> None: + data = {"metric": metric, "value": value} + if unit is not None: + data["unit"] = unit + with open(output, "a") as f: + f.write(f"{json.dumps(data)}\n") + + +def load_instructions_per_module(output: Path) -> dict[str, float]: + pattern = re.compile(r"build/module/(.*)//instructions") + instructions: dict[str, float] = {} + with open(output) as f: + for line in f: + data = json.loads(line) + if match := pattern.fullmatch(data["metric"]): + instructions[match.group(1)] = data["value"] + return instructions + + +@dataclass +class Row: + time: float + time_frac: float + cum_time: float + cum_time_frac: float + module: str + + +def lakeprof_report(*args: str) -> list[Row]: + result = subprocess.run( + ["lakeprof", "report", *args, "-j"], capture_output=True, encoding="utf-8" + ) + if result.returncode != 0: + print(result.stdout, end="", file=sys.stdout) + print(result.stderr, end="", file=sys.stderr) + sys.exit(result.returncode) + return [Row(*row) for row in json.loads(result.stdout)] + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("out", type=Path) + args = parser.parse_args() + out: Path = args.out + + instructions = load_instructions_per_module(out) + + for flag, name in [("-p", "longest build path"), ("-r", "longest rebuild path")]: + rows = lakeprof_report(flag) + + # Total wall-clock time, as reported by lakeprof + save_measurement( + out, f"build/lakeprof/{name}//wall-clock", rows[-1].cum_time, "s" + ) + + # Total instructions, computed from lakeprof's modules and our own measurements + total_instructions = sum(instructions.get(row.module, 0) for row in rows) + save_measurement( + out, f"build/lakeprof/{name}//instructions", total_instructions + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/bench/build/run b/scripts/bench/build/run index 3affbc9fa47546..b7eeea535f9b60 100755 --- a/scripts/bench/build/run +++ b/scripts/bench/build/run @@ -13,8 +13,7 @@ LAKE_OVERRIDE_LEAN=true LEAN=$(realpath "$BENCH/build/fake-root/bin/lean") \ lakeprof record lake build --no-cache # Analyze lakeprof data -lakeprof report -pj | jq -c '{metric: "build/lakeprof/longest build path//wall-clock", value: .[-1][2], unit: "s"}' >> measurements.jsonl -lakeprof report -rj | jq -c '{metric: "build/lakeprof/longest rebuild path//wall-clock", value: .[-1][2], unit: "s"}' >> measurements.jsonl +"$BENCH/build/lakeprof_measurements.py" measurements.jsonl # Upload lakeprof report # Guarded to prevent accidental uploads (which wouldn't work anyways) during local runs. From 6f6d267d6dab648062ec50502204cf512cd7274f Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Fri, 10 Jul 2026 14:30:27 +0000 Subject: [PATCH 0719/1300] ci: run lake cache shadow pipeline with patched lake version with latest features (#41547) Use a variable to override the lean toolchain, so we can point to a custom lean toolchain to experiment / ingest some changes that are still unreleased Note this pipeline is experimental and non-sensitive, so it's fine to be loose here. --- .github/workflows/lake_cache_shadow.yml | 120 ++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 8 deletions(-) diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 68a7710e79bc1c..489b364a216ef3 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -19,18 +19,38 @@ name: Lake cache shadow (master) # # host than the S3 API endpoint; e.g. an R2 public r2.dev/custom domain). # LAKE_CACHE_ARTIFACT_ENDPOINT_PUBLIC — e.g. https://pub-.r2.dev//artifacts # LAKE_CACHE_REVISION_ENDPOINT_PUBLIC — e.g. https://pub-.r2.dev//revisions +# # Optional. Default toolchain override for every run, including +# # scheduled ones; the dispatch input takes precedence. Unset to run +# # on the repo pin. +# LAKE_SHADOW_TOOLCHAIN_OVERRIDE — e.g. leanprover/lean4-pr-releases:pr-release-14301 # # Jobs: # build_and_stage Build mathlib + deps with Lake's artifact cache # enabled, then stage the resulting .ltar files. # upload Push staged artifacts to the cache bucket via # `lake cache put-staged`, then record a per-run manifest -# under cache/analysis/ and report carryover vs the prior run. +# under cache/analysis// and report +# carryover vs the prior run on the same toolchain. # consume Fresh checkout, fetch from the cache bucket via # `lake cache get`, run `lake build` against the # rehydrated cache, then verify with `--rehash`. # report Post a per-run summary to the `CI admins` Zulip # stream (topic `Lake cache shadow`). +# +# Toolchain override: +# The `toolchain_override` input, or else the LAKE_SHADOW_TOOLCHAIN_OVERRIDE +# variable, swaps the toolchain the whole pipeline runs on: build_and_stage +# resolves it into its `toolchain` output, and the downstream jobs stamp +# that output into their checkouts, so every job runs the same lake. Its +# lean must be behaviorally compatible with the repo pin, e.g. a Lake change +# cherry-picked onto the pinned release's lineage as a lean4 pr-release. +# Input hashes incorporate the toolchain, so all runs safely share one +# artifact scope. The analysis chain (warm-start pointer + carryover +# manifests) is keyed per toolchain under analysis//, so pinned and +# override runs each warm-start from and diff against their own lineage. +# A toolchain's first run — or a pr-release tag republished under the same +# name — misses the legacy cache and all prior artifacts, costing one +# full-turnover source build. on: schedule: @@ -54,6 +74,15 @@ on: # Mathlib.Topology.Basic Mathlib.Combinatorics.SimpleGraph.Basic Mathlib.RingTheory.Ideal.Basic # or add `Archive Counterexamples` to also shadow those libraries. default: Mathlib + toolchain_override: + description: >- + optional Lean toolchain to run the pipeline on instead of the repo + pin; see the "Toolchain override" note at the top of this file. + Empty falls back to the LAKE_SHADOW_TOOLCHAIN_OVERRIDE repository + variable; the pipeline runs on the repo pin when both are empty. + required: false + type: string + default: '' permissions: contents: read @@ -67,6 +96,9 @@ defaults: shell: bash -euo pipefail {0} env: + # Effective toolchain override: dispatch input, else repository variable, + # else the repo pin. + TOOLCHAIN_OVERRIDE: ${{ inputs.toolchain_override || vars.LAKE_SHADOW_TOOLCHAIN_OVERRIDE || '' }} # Scope prefix for all puts and gets in this workflow. Namespaces the # workflow's artifacts within the cache bucket. SHADOW_SCOPE: mathlib4-master-shadow @@ -78,7 +110,8 @@ jobs: name: Build + stage if: ${{ github.repository == 'leanprover-community/mathlib4' }} runs-on: pr - timeout-minutes: 90 + # 240 covers the full source build of a toolchain generation's first run. + timeout-minutes: ${{ (inputs.toolchain_override || vars.LAKE_SHADOW_TOOLCHAIN_OVERRIDE) && 240 || 90 }} outputs: sha: ${{ steps.resolve.outputs.sha }} toolchain: ${{ steps.resolve.outputs.toolchain }} @@ -110,6 +143,15 @@ jobs: fetch-depth: 2 path: pr-branch + # Before the resolve step, so the run's recorded toolchain is the one + # actually used. + - name: Apply toolchain override + if: ${{ env.TOOLCHAIN_OVERRIDE != '' }} + shell: bash -euo pipefail {0} + run: | + printf '%s\n' "$TOOLCHAIN_OVERRIDE" > pr-branch/lean-toolchain + echo "::notice::toolchain override: $TOOLCHAIN_OVERRIDE" + - name: Resolve sha & toolchain id: resolve shell: bash -euo pipefail {0} @@ -124,7 +166,10 @@ jobs: shell: bash -euo pipefail {0} run: | mkdir -p pr-branch/.lake/ - mkdir -p .cache/mathlib/ + # The landrun ruleset mounts $HOME/.cache/mathlib read-only and + # errors out if the path is missing. Runs that skip legacy hydration + # reach the first landrun step with it absent. + mkdir -p "$HOME/.cache/mathlib/" mkdir -p _work - name: install elan @@ -135,6 +180,17 @@ jobs: ./elan-init.sh -y --default-toolchain none echo "$HOME/.elan/bin" >> "${GITHUB_PATH}" + # `elan which` below does not auto-install non-pinned toolchains. The + # uninstall forces a fresh download: pr-release tags are republished in + # place, and elan skips toolchains it already has, so a persistent + # runner would otherwise keep running a stale binary under that name. + - name: Install override toolchain + if: ${{ env.TOOLCHAIN_OVERRIDE != '' }} + shell: bash -euo pipefail {0} + run: | + elan toolchain uninstall "$TOOLCHAIN_OVERRIDE" || true + elan toolchain install "$TOOLCHAIN_OVERRIDE" + - name: set toolchain directory shell: bash -euo pipefail {0} run: | @@ -168,7 +224,10 @@ jobs: cd pr-branch lake env + # The legacy cache is keyed to the repo's pinned toolchain — cold for an + # override toolchain, where the warm-start step below takes its place. - name: Hydrate .lake/build via legacy cache + if: ${{ env.TOOLCHAIN_OVERRIDE == '' }} shell: bash -euo pipefail {0} run: | cd pr-branch @@ -199,6 +258,28 @@ jobs: awk '/^package mathlib where/,/^$/' lakefile.lean echo "::endgroup::" + # Seed Lake's artifact cache from the previous run on the same + # toolchain, whose rev comes from that toolchain's analysis chain + # (`analysis//_latest.txt`). Only content the cache can't serve + # is packed or built; a toolchain's first run has no chain yet and + # proceeds from source. + - name: Warm start from shadow scope + shell: bash -euo pipefail {0} + env: + LAKE_CACHE_ARTIFACT_ENDPOINT: ${{ vars.LAKE_CACHE_ARTIFACT_ENDPOINT_PUBLIC }} + LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT_PUBLIC }} + run: | + # Must mirror the slug in the upload job's carryover step. + slug="$(printf %s "$(cat pr-branch/lean-toolchain)" | tr -c 'A-Za-z0-9._-' '-')" + prev="$(curl -fsS "${LAKE_CACHE_ARTIFACT_ENDPOINT%/artifacts}/analysis/$slug/_latest.txt" 2>/dev/null || true)" + if [ -z "$prev" ]; then + echo "::notice::no prior run recorded for chain $slug; proceeding without a warm start" + exit 0 + fi + cd pr-branch + lake cache get --scope="$SHADOW_SCOPE" --rev="$prev" \ + || echo "::warning::warm start from rev ${prev:0:12} failed; proceeding without it" + # Incremental build: with the legacy cache having hydrated .lake/build/ # and the lakefile patched, Lake's pipeline runs to pack/cache any # modules whose .ltar+mapping aren't yet in Lake's cache. Module @@ -277,13 +358,21 @@ jobs: LAKE_CACHE_ARTIFACT_ENDPOINT: ${{ vars.LAKE_CACHE_ARTIFACT_ENDPOINT }} LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT }} steps: - - name: Checkout mathlib (for lean-toolchain pin) + - name: Checkout mathlib (workspace for put-staged) uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch fetch-depth: 1 + # Stamp the effective toolchain from build_and_stage's resolve step, so + # put-staged runs the same lake that produced the staging; the elan + # proxy auto-installs it on first use. + - name: Pin effective toolchain + env: + EFFECTIVE_TOOLCHAIN: ${{ needs.build_and_stage.outputs.toolchain }} + run: printf '%s\n' "$EFFECTIVE_TOOLCHAIN" > pr-branch/lean-toolchain + - name: install elan + matching lake run: | curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh @@ -318,7 +407,8 @@ jobs: --toolchain="${{ needs.build_and_stage.outputs.toolchain }}" 2>&1 | tee /tmp/put.log # Cache carryover analysis: diff this run's uploaded artifact set against - # the previous run's, using a tiny per-run manifest kept in the bucket. + # the previous run's on the same toolchain, via tiny per-run manifests + # kept in the bucket under the toolchain's analysis// prefix. # Here: # carryover = artifacts also present last run; # new = this run's churn (≈ how much Mathlib changed since the last build). @@ -331,8 +421,11 @@ jobs: AUTH: ${{ vars.LAKE_CACHE_ARTIFACT_ENDPOINT }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.repository }} + EFFECTIVE_TOOLCHAIN: ${{ needs.build_and_stage.outputs.toolchain }} run: | - base="${AUTH%/artifacts}/analysis" + # Must mirror the slug in build_and_stage's warm-start step. + slug="$(printf %s "$EFFECTIVE_TOOLCHAIN" | tr -c 'A-Za-z0-9._-' '-')" + base="${AUTH%/artifacts}/analysis/$slug" sha="${{ needs.build_and_stage.outputs.sha }}" sig=(--aws-sigv4 aws:amz:auto:s3 --user "$LAKE_CACHE_KEY") # grep exits 1 on no match (handled by the total==0 branch); tolerate it under pipefail. @@ -379,7 +472,7 @@ jobs: new_content="$(numfmt --to=iec-i --suffix=B "$new_bytes") across ${new} new artifact(s) vs rev ${prev:0:12}${distnote}" pct=$(awk "BEGIN{printf \"%.1f\", ($total>0)?100*$carry/$total:0}") note="" - [ "$total" -gt 0 ] && [ "$new" -eq "$total" ] && note=" — full turnover, likely a toolchain/generation change, not source churn" + [ "$total" -gt 0 ] && [ "$new" -eq "$total" ] && note=" — full turnover, likely a republished toolchain binary, not source churn" summary="${carry}/${total} (${pct}%) carried over, ${new} new vs rev ${prev:0:12}${note}" fi echo "::notice::cache carryover: ${summary}" @@ -396,7 +489,7 @@ jobs: needs: [build_and_stage, upload] if: ${{ github.repository == 'leanprover-community/mathlib4' }} runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 90 outputs: cache_health: ${{ steps.cachehealth.outputs.health }} env: @@ -416,6 +509,14 @@ jobs: path: pr-branch fetch-depth: 1 + # Stamp the effective toolchain from build_and_stage's resolve step, so + # the replay runs the same lake that built the artifacts; the elan + # proxy auto-installs it on first use. + - name: Pin effective toolchain + env: + EFFECTIVE_TOOLCHAIN: ${{ needs.build_and_stage.outputs.toolchain }} + run: printf '%s\n' "$EFFECTIVE_TOOLCHAIN" > pr-branch/lean-toolchain + - name: install elan run: | curl -o elan-init.sh -sSfL https://elan.lean-lang.org/elan-init.sh @@ -533,6 +634,9 @@ jobs: { echo "msg< Date: Fri, 10 Jul 2026 14:48:05 +0000 Subject: [PATCH 0720/1300] chore: update Mathlib dependencies 2026-07-10 (#41586) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index a7a14490b470cf..c81997e983eaca 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e68e6d1b0defc3f2df735986824b96ae29a7bd46", + "rev": "9647daaa8c0bc688fcfcb04252c864b859b51f57", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From a08ff0d0f4a09dfc02656595d681eb3d84202fa9 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:48:08 +0000 Subject: [PATCH 0721/1300] chore: refactor bench suite (#41587) Over time, this bench suite drifted away from the lean4 one. This PR tries to align them again, re-using scripts from lean4 unchanged where possible, and only slightly modified otherwise. Co-authored-by: Joscha --- scripts/bench/README.md | 17 ++- scripts/bench/build/fake-root/bin/lean | 32 +++-- scripts/bench/build/lakeprof_report_upload.py | 44 +++--- scripts/bench/build/run | 18 +-- scripts/bench/combine.py | 83 ++++++++--- scripts/bench/lint/run | 4 +- scripts/bench/measure.py | 6 +- scripts/bench/open-mathlib/run | 6 +- scripts/bench/repeatedly.py | 132 +++++++++++++----- scripts/bench/run | 12 +- scripts/bench/size/run | 3 +- 11 files changed, 238 insertions(+), 119 deletions(-) diff --git a/scripts/bench/README.md b/scripts/bench/README.md index 4a2ccbdf4dbc68..a707b979dd52d2 100644 --- a/scripts/bench/README.md +++ b/scripts/bench/README.md @@ -5,13 +5,13 @@ It is built around [radar](https://github.com/leanprover/radar) and benchmark results can be viewed on the [Lean FRO radar instance](https://radar.lean-lang.org/repos/mathlib4). -To execute the entire suite, run `scripts/bench/run` in the repo root. -To execute an individual benchmark, run `scripts/bench//run` in the repo root. -All scripts output their measurements into the file `measurements.jsonl`. +To execute the benchmark suite, run `scripts/bench/run` from the repo root. +All measurements will be placed into `measurements.jsonl` in the repo root. Radar sums any duplicated measurements with matching metrics. -To post-process the `measurements.jsonl` file this way in-place, -run `scripts/bench/combine.py` in the repo root after executing the benchmark suite. +To post-process the `measurements.jsonl` file this way, +run `scripts/bench/combine.py measurements.jsonl -o measurements_combined.jsonl` +in the repo root after executing the benchmark suite. The `*.py` symlinks exist only so the python files are a bit nicer to edit in text editors that rely on the file ending. @@ -24,6 +24,13 @@ To add a benchmark to the suite, follow these steps: as well as any other files required for the benchmark. 2. Edit `scripts/bench/run` to call the `run` script of your new benchmark. +The following environment variables are available to an individual benchmark's `run` script: + +- `ROOT_DIR`: absolute path to the root of the repo +- `BENCH_DIR`: absolute path to this directory (`scripts/bench`). +- `OUTPUT_FILE`: absolute path to the `measurements.jsonl` file + that benchmarks should append their measurements to + ## How radar executes the benchmark suite Radar requires a _bench repo_ to be configured for each repo. diff --git a/scripts/bench/build/fake-root/bin/lean b/scripts/bench/build/fake-root/bin/lean index 5dbe6a8c9551ba..2ce14c08b2c7ba 100755 --- a/scripts/bench/build/fake-root/bin/lean +++ b/scripts/bench/build/fake-root/bin/lean @@ -2,25 +2,29 @@ import argparse import json +import os import re import subprocess import sys from pathlib import Path -NAME = "build" -REPO = Path() -BENCH = REPO / "scripts" / "bench" -OUTFILE = REPO / "measurements.jsonl" +# Global paths +BENCH_DIR = Path(os.environ["BENCH_DIR"]) +WRAPPER_OUT = Path(os.environ["WRAPPER_OUT"]) +WRAPPER_PREFIX = Path(os.environ["WRAPPER_PREFIX"]) -sys.path.append(str(BENCH)) +# Other config +BENCHMARK = "build" + +sys.path.append(str(BENCH_DIR)) import measure # noqa: E402 -def save_result(metric: str, value: float, unit: str | None = None) -> None: +def save_measurement(metric: str, value: float, unit: str | None = None) -> None: data = {"metric": metric, "value": value} if unit is not None: data["unit"] = unit - with open(OUTFILE, "a+") as f: + with open(WRAPPER_OUT, "a") as f: f.write(f"{json.dumps(data)}\n") @@ -38,33 +42,33 @@ def get_module(setup: Path) -> str: def count_lines(module: str, path: Path) -> None: with open(path) as f: lines = sum(1 for _ in f) - save_result(f"{NAME}/module/{module}//lines", lines) + save_measurement(f"{BENCHMARK}/module/{module}//lines", lines) def run_lean(module: str) -> None: _, stderr = measure.main( cmd=["lean", "--profile", "-Dprofiler.threshold=9999999", *sys.argv[1:]], - output=OUTFILE, - topics=[f"{NAME}/module/{module}"], + output=WRAPPER_OUT, + topics=[f"{BENCHMARK}/module/{module}"], metrics={"instructions"}, append=True, capture=True, ) + # Output of `lean --profile` + # See timeit.cpp for the time format for line in stderr.splitlines(): - # Output of `lean --profile` - # See timeit.cpp for the time format if match := re.fullmatch(r"\t(.*) ([\d.]+)(m?s)", line): name = match.group(1) seconds = float(match.group(2)) if match.group(3) == "ms": seconds = seconds / 1000 - save_result(f"{NAME}/profile/{name}//wall-clock", seconds, "s") + save_measurement(f"{BENCHMARK}/profile/{name}//wall-clock", seconds, "s") def main() -> None: if sys.argv[1:] == ["--print-prefix"]: - print(Path(__file__).resolve().parent.parent) + print(WRAPPER_PREFIX) return if sys.argv[1:] == ["--githash"]: diff --git a/scripts/bench/build/lakeprof_report_upload.py b/scripts/bench/build/lakeprof_report_upload.py index ceaad103cae060..c779115a4c3462 100644 --- a/scripts/bench/build/lakeprof_report_upload.py +++ b/scripts/bench/build/lakeprof_report_upload.py @@ -1,16 +1,24 @@ #!/usr/bin/env python3 import json +import os import subprocess import sys from pathlib import Path +upload_url = os.environ.get("LAKEPROF_UPLOAD_URL") +if not upload_url: + sys.exit(0) +if upload_url.endswith("/"): + upload_url = upload_url[:-1] -def run(*args: str) -> None: - subprocess.run(args, check=True) +# Determine paths relative to the current file. +script_file = Path(__file__) +template_file = script_file.parent / "lakeprof_report_template.html" +root_dir = script_file.parent.parent.parent.parent -def run_stdout(*command: str, cwd: str | None = None) -> str: +def run_stdout(*command: str, cwd: Path | None = None) -> str: result = subprocess.run(command, capture_output=True, encoding="utf-8", cwd=cwd) if result.returncode != 0: print(result.stdout, end="", file=sys.stdout) @@ -19,26 +27,20 @@ def run_stdout(*command: str, cwd: str | None = None) -> str: return result.stdout -def main() -> None: - script_file = Path(__file__) - template_file = script_file.parent / "lakeprof_report_template.html" +sha = run_stdout("git", "rev-parse", "@", cwd=root_dir).strip() +base_url = f"{upload_url}/{sha}" +report = run_stdout("lakeprof", "report", "-prc", cwd=root_dir) - sha = run_stdout("git", "rev-parse", "@").strip() - base_url = f"https://speed.lean-lang.org/mathlib4-out/{sha}" - report = run_stdout("lakeprof", "report", "-prc") - with open(template_file) as f: - template = f.read() +template = template_file.read_text() +template = template.replace("__BASE_URL__", json.dumps(base_url)) +template = template.replace("__LAKEPROF_REPORT__", report) +(root_dir / "index.html").write_text(template) - template = template.replace("__BASE_URL__", json.dumps(base_url)) - template = template.replace("__LAKEPROF_REPORT__", report) - with open("index.html", "w") as f: - f.write(template) +def upload(file: Path) -> None: + subprocess.run(["curl", "-fT", file, f"{base_url}/{file.name}"], check=True) - run("curl", "-T", "index.html", f"{base_url}/index.html") - run("curl", "-T", "lakeprof.log", f"{base_url}/lakeprof.log") - run("curl", "-T", "lakeprof.trace_event", f"{base_url}/lakeprof.trace_event") - -if __name__ == "__main__": - main() +upload(root_dir / "index.html") +upload(root_dir / "lakeprof.log") +upload(root_dir / "lakeprof.trace_event") diff --git a/scripts/bench/build/run b/scripts/bench/build/run index b7eeea535f9b60..a4cb089046d432 100755 --- a/scripts/bench/build/run +++ b/scripts/bench/build/run @@ -1,22 +1,18 @@ #!/usr/bin/env bash set -euxo pipefail -BENCH="scripts/bench" - # Prepare build lake clean rm -f .lake/packages/batteries/.lake/build/bin/runLinter # Run build -LAKE_OVERRIDE_LEAN=true LEAN=$(realpath "$BENCH/build/fake-root/bin/lean") \ - "$BENCH/measure.py" --append -t build -d -- \ +LAKE_OVERRIDE_LEAN=true \ + LEAN="$BENCH_DIR/build/fake-root/bin/lean" \ + WRAPPER_OUT="$OUTPUT_FILE" \ + WRAPPER_PREFIX="$BENCH_DIR/build/fake-root" \ + "$BENCH_DIR/measure.py" -t build -d -a -o "$OUTPUT_FILE" -- \ lakeprof record lake build --no-cache # Analyze lakeprof data -"$BENCH/build/lakeprof_measurements.py" measurements.jsonl - -# Upload lakeprof report -# Guarded to prevent accidental uploads (which wouldn't work anyways) during local runs. -if [ -f build_upload_lakeprof_report ]; then - python3 "$BENCH/build/lakeprof_report_upload.py" -fi +"$BENCH_DIR/build/lakeprof_measurements.py" measurements.jsonl +python3 "$BENCH_DIR/build/lakeprof_report_upload.py" diff --git a/scripts/bench/combine.py b/scripts/bench/combine.py index 2a71f31b968aaf..bf5e3b6dcefbbf 100755 --- a/scripts/bench/combine.py +++ b/scripts/bench/combine.py @@ -2,30 +2,79 @@ import argparse import json +import sys from pathlib import Path +from typing import Any -OUTFILE = Path() / "measurements.jsonl" -if __name__ == "__main__": +def add_measurement( + values: dict[str, float], + units: dict[str, str | None], + data: dict[str, Any], +) -> None: + metric = data["metric"] + values[metric] = values.get(metric, 0) + data["value"] + units[metric] = data.get("unit") + + +def format_measurement( + values: dict[str, float], + units: dict[str, str | None], + name: str, +) -> dict[str, Any]: + value = values[name] + unit = units.get(name) + + data: dict[str, Any] = {"metric": name, "value": value} + if unit is not None: + data["unit"] = unit + + return data + + +def main() -> None: parser = argparse.ArgumentParser( - description=f"Combine duplicated measurements in {OUTFILE.name} the way radar does, by summing their values." + description="Combine measurement files in the JSON Lines format, summing duplicated measurements like radar does.", + ) + parser.add_argument( + "input", + nargs="*", + default=[], + help="input files to read measurements from. If none are specified, measurements are read from stdin.", + ) + parser.add_argument( + "-o", + "--output", + type=Path, + help="output file to write measurements to. If not specified, the result is printed to stdout.", ) args = parser.parse_args() + inputs: list[Path] = args.input + output: Path | None = args.output + values: dict[str, float] = {} units: dict[str, str | None] = {} - with open(OUTFILE, "r") as f: - for line in f: - data = json.loads(line) - metric = data["metric"] - values[metric] = values.get(metric, 0) + data["value"] - units[metric] = data.get("unit") - - with open(OUTFILE, "w") as f: - for metric, value in values.items(): - unit = units.get(metric) - data = {"metric": metric, "value": value} - if unit is not None: - data["unit"] = unit - f.write(f"{json.dumps(data)}\n") + # Read measurements + if inputs: + for input in inputs: + with open(input, "r") as f: + for line in f: + add_measurement(values, units, json.loads(line)) + else: + for line in sys.stdin: + add_measurement(values, units, json.loads(line)) + + # Write measurements + if output: + with open(output, "w") as f: + for metric in sorted(values): + f.write(f"{json.dumps(format_measurement(values, units, metric))}\n") + else: + for metric in sorted(values): + print(json.dumps(format_measurement(values, units, metric))) + + +if __name__ == "__main__": + main() diff --git a/scripts/bench/lint/run b/scripts/bench/lint/run index f9b487052707cf..301d282dff12ab 100755 --- a/scripts/bench/lint/run +++ b/scripts/bench/lint/run @@ -1,8 +1,6 @@ #!/usr/bin/env bash set -euxo pipefail -BENCH="scripts/bench" - lake build runLinter -LEAN_ABORT_ON_PANIC=1 "$BENCH/measure.py" --append -t lint -d -- \ +LEAN_ABORT_ON_PANIC=1 "$BENCH_DIR/measure.py" -t lint -d -a -o "$OUTPUT_FILE" -- \ lake exe runLinter Mathlib diff --git a/scripts/bench/measure.py b/scripts/bench/measure.py index c01a8a1267543b..c52b6e90285e45 100755 --- a/scripts/bench/measure.py +++ b/scripts/bench/measure.py @@ -7,7 +7,6 @@ import subprocess import sys import tempfile -from argparse import Namespace from dataclasses import dataclass from pathlib import Path from typing import Tuple @@ -184,8 +183,7 @@ def main( return measured.stdout, measured.stderr -@dataclass -class Args(Namespace): +class Args: topic: list[str] metric: list[str] default_metrics: bool @@ -243,7 +241,7 @@ class Args(Namespace): default=[], help="arguments to pass to the command", ) - args = parser.parse_args(namespace=Args) + args = parser.parse_args(namespace=Args()) metrics = set(args.metric) if args.default_metrics: diff --git a/scripts/bench/open-mathlib/run b/scripts/bench/open-mathlib/run index e48cb2c693ab35..eaad0043a53aa2 100755 --- a/scripts/bench/open-mathlib/run +++ b/scripts/bench/open-mathlib/run @@ -1,8 +1,6 @@ #!/usr/bin/env bash set -euxo pipefail -BENCH="scripts/bench" - -"$BENCH/repeatedly.py" -n 5 -- \ - "$BENCH/measure.py" --append -t open-mathlib -d -- \ +"$BENCH_DIR/repeatedly.py" -n 5 -o "$OUTPUT_FILE" -- \ + "$BENCH_DIR/measure.py" -t open-mathlib -d -a -o "$OUTPUT_FILE" -- \ lake lean Mathlib.lean diff --git a/scripts/bench/repeatedly.py b/scripts/bench/repeatedly.py index 7dbf7a1c70d169..fae258cf0247b5 100755 --- a/scripts/bench/repeatedly.py +++ b/scripts/bench/repeatedly.py @@ -8,10 +8,6 @@ from dataclasses import dataclass from pathlib import Path -REPO = Path() -OUTFILE = REPO / "measurements.jsonl" -OUTFILE_TMP = REPO / "measurements_repeated_tmp.jsonl" - @dataclass class Measurement: @@ -33,59 +29,98 @@ def to_json_str(self) -> str: @contextmanager -def temporarily_move_outfile(): - if OUTFILE_TMP.exists(): - raise Exception(f"{OUTFILE_TMP} already exists") +def temporarily_move_outfile(outfile: Path): + outfile_tmp = outfile.with_name(outfile.name + ".repeatedly_tmp") + if outfile_tmp.exists(): + raise Exception(f"{outfile_tmp} already exists") - OUTFILE.touch() - OUTFILE.rename(OUTFILE_TMP) + outfile.touch() + outfile.rename(outfile_tmp) try: yield finally: - OUTFILE_TMP.rename(OUTFILE) + outfile_tmp.rename(outfile) -def read_measurements_from_outfile() -> list[Measurement]: +def read_measurements_from_outfile(outfile: Path) -> list[Measurement]: measurements = [] - with open(OUTFILE, "r") as f: + with open(outfile, "r") as f: for line in f: measurements.append(Measurement.from_json_str(line)) return measurements -def write_measurements_to_outfile(measurements: list[Measurement]) -> None: - with open(OUTFILE, "a") as f: +def write_measurements_to_outfile( + outfile: Path, measurements: list[Measurement] +) -> None: + with open(outfile, "a") as f: for measurement in measurements: f.write(f"{measurement.to_json_str()}\n") -def run_once(cmd: list[str]) -> list[Measurement]: - with temporarily_move_outfile(): +def run_once(cmd: list[str], outfile: Path) -> list[Measurement]: + with temporarily_move_outfile(outfile): proc = subprocess.run(cmd) if proc.returncode != 0: sys.exit(proc.returncode) - return read_measurements_from_outfile() + return read_measurements_from_outfile(outfile) -def repeatedly(cmd: list[str], iterations: int) -> list[Measurement]: +def sum_by_metric(measurements: list[Measurement]) -> dict[str, Measurement]: totals: dict[str, Measurement] = {} + for measurement in measurements: + if existing := totals.get(measurement.metric): + measurement.value += existing.value + totals[measurement.metric] = measurement + return totals + + +def repeatedly( + cmd: list[str], + iterations: int, + outfile: Path, + drop_highest: int = 0, + drop_lowest: int = 0, +) -> list[Measurement]: + by_metric: dict[str, list[Measurement]] = {} for i in range(iterations): - for measurement in run_once(cmd): - if existing := totals.get(measurement.metric): - measurement.value += existing.value - totals[measurement.metric] = measurement + for metric, measurement in sum_by_metric(run_once(cmd, outfile)).items(): + by_metric.setdefault(metric, []).append(measurement) + + if drop_highest + drop_lowest >= iterations: + raise ValueError( + f"drop_highest ({drop_highest}) + drop_lowest ({drop_lowest}) must be " + f"less than the number of iterations ({iterations})" + ) + + results = [] + for metric, measurements in by_metric.items(): + if drop_highest or drop_lowest: + measurements.sort(key=lambda m: m.value) + measurements = measurements[drop_lowest : len(measurements) - drop_highest] + if not measurements: + continue + unit = measurements[0].unit + value = sum(m.value for m in measurements) / len(measurements) + results.append(Measurement(metric, value, unit)) + + return results - for measurement in totals.values(): - measurement.value /= iterations - return list(totals.values()) +class Args: + iterations: int + drop_highest: int + drop_lowest: int + outfile: Path + cmd: str + args: list[str] if __name__ == "__main__": parser = argparse.ArgumentParser( - description=f"Repeatedly run a command, averaging the resulting measurements in {OUTFILE.name}.", + description="Repeatedly run a command, averaging the measurements it writes.", ) parser.add_argument( "-n", @@ -94,15 +129,44 @@ def repeatedly(cmd: list[str], iterations: int) -> list[Measurement]: default=5, help="number of iterations", ) + parser.add_argument( + "-H", + "--drop-highest", + type=int, + default=0, + help="drop the n highest values of each metric before averaging", + ) + parser.add_argument( + "-L", + "--drop-lowest", + type=int, + default=0, + help="drop the n lowest values of each metric before averaging", + ) + parser.add_argument( + "-o", + "--outfile", + type=Path, + default=Path("measurements.jsonl"), + help="measurements file the command under test writes to", + ) parser.add_argument( "cmd", - nargs="*", help="command to repeatedly run", ) - args = parser.parse_args() - - iterations: int = args.iterations - cmd: list[str] = args.cmd - - measurements = repeatedly(cmd, iterations) - write_measurements_to_outfile(measurements) + parser.add_argument( + "args", + nargs="*", + default=[], + help="arguments to pass to the command", + ) + args = parser.parse_args(namespace=Args()) + + measurements = repeatedly( + [args.cmd] + args.args, + args.iterations, + args.outfile, + args.drop_highest, + args.drop_lowest, + ) + write_measurements_to_outfile(args.outfile, measurements) diff --git a/scripts/bench/run b/scripts/bench/run index c3e270c6a3f94c..d8e253c2c8caee 100755 --- a/scripts/bench/run +++ b/scripts/bench/run @@ -1,16 +1,18 @@ #!/usr/bin/env bash set -euo pipefail -BENCH="scripts/bench" +export ROOT_DIR="$(realpath .)" +export BENCH_DIR="$ROOT_DIR/scripts/bench" +export OUTPUT_FILE="$ROOT_DIR/measurements.jsonl" echo "Running benchmark: build" -"$BENCH/build/run" +"$BENCH_DIR/build/run" echo "Running benchmark: lint" -"$BENCH/lint/run" +"$BENCH_DIR/lint/run" echo "Running benchmark: open-mathlib" -"$BENCH/open-mathlib/run" +"$BENCH_DIR/open-mathlib/run" echo "Running benchmark: size" -"$BENCH/size/run" +"$BENCH_DIR/size/run" diff --git a/scripts/bench/size/run b/scripts/bench/size/run index 3acb2ebdf3c89f..c4b51eba6f45d0 100755 --- a/scripts/bench/size/run +++ b/scripts/bench/size/run @@ -1,9 +1,10 @@ #!/usr/bin/env python3 import json +import os from pathlib import Path -OUTFILE = Path() / "measurements.jsonl" +OUTFILE = Path(os.environ["OUTPUT_FILE"]) def output_result( From bd20b9c6e573b21deac71b31d2c7b755a53b2f8f Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:16:44 +0000 Subject: [PATCH 0722/1300] fix(GRewrite): preserve binder names in the goal (#40323) This PR fixes the new `grw` implementation to preserve binder names in the goal. Preservation of binder names was already implemented, but it wouldn't work when the used `gcongr` lemma contained eta expanded variables, because the binder name from the eta expansion would persist. So, the fix is to eta reduce these terms before using them. --- Mathlib/Tactic/GCongr/Core.lean | 18 ++++++++++++++++-- Mathlib/Tactic/GRewrite/Core.lean | 3 +++ Mathlib/Topology/List.lean | 4 ++-- MathlibTest/Tactic/GRewrite.lean | 6 +++--- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Mathlib/Tactic/GCongr/Core.lean b/Mathlib/Tactic/GCongr/Core.lean index 82658fddf1dd60..d3cea22abb7fe8 100644 --- a/Mathlib/Tactic/GCongr/Core.lean +++ b/Mathlib/Tactic/GCongr/Core.lean @@ -676,14 +676,19 @@ For each main subgoal, also return whether the sides of the relation are swapped This function is used by both the `gcongr` and `grw` tactic. In the case of `grw`, one of the two sides of the goal is a metavariable that is filled in -by this function. -/ +by this function. + +In the main subgoals, the forall binders are introduced. They are named using the `with` clause of +`gcongr`, or otherwise using binder names in the goal. `grw` relies on these names to ensure that +binder names are preserved in the goal. +-/ def applyGCongrLemma (g : MVarId) (lem : GCongr.GCongrLemma) : GCongrM (Array (MVarId × Bool) × Array MVarId) := do let const ← mkConstWithFreshMVarLevels lem.declName let type ← inferType const -- Use `withDefault` so that we can unfold `Monotone`. let (mvars, bis, type) ← withDefault <| forallMetaTelescopeReducing type lem.numHyps - guard <| ← approxDefEq <| isDefEq (← g.getType) type + guard <| ← approxDefEq <| isDefEq (← g.getType) (← preprocess type) g.assign (mkAppN const mvars) let mut sideGoals := #[] for mvar in mvars, i in 0...* do @@ -720,6 +725,15 @@ where match e with | .lam n _ b _ => lambdaBinderNames b (acc.push n) | _ => acc + /-- Remove any redundant eta expansions in the arguments on either side of the relation `e`. + As a result, the corresponding binder names are removed, so they cannot end up in the expression + produced by `grw`. -/ + preprocess (e : Expr) : MetaM Expr := do + let normArgs (x : Expr) := x.headBeta.withApp (mkAppN · <| ·.map Expr.eta) + match ← whnf e with + | .forallE _ lhs rhs _ => return e.updateForallE! (normArgs lhs) (normArgs rhs) + | mkApp2 rel lhs rhs => return mkApp2 rel (normArgs lhs) (normArgs rhs) + | _ => throwError "internal `gcongr` error: expected `{e}` to be a relation" /-- The core of the `gcongr` tactic. Parse a goal into the form `(f _ ... _) ∼ (f _ ... _)`, look up any relevant `@[gcongr]` lemmas, try to apply them, recursively run the tactic itself on diff --git a/Mathlib/Tactic/GRewrite/Core.lean b/Mathlib/Tactic/GRewrite/Core.lean index 1b5311dcc33df0..db0ff04ad806a9 100644 --- a/Mathlib/Tactic/GRewrite/Core.lean +++ b/Mathlib/Tactic/GRewrite/Core.lean @@ -205,6 +205,9 @@ partial def processGCongrHypothesisAux (goal : MVarId) (forward : Bool) (config let (target, mvarApp) := if forward then (lhs, rhs) else (rhs, lhs) if let some (result, proof) ← grewriteCore relName rel? target forward config then mvarApp.withApp fun mvar xs ↦ do + /- Note: the names of the free variables `xs` end up in the new goal as lambda binders. + `applyGCongrLemma` ensures that these are the binder names that appear in the original goal. + As a result, when rewriting inside of `{x | p x}`, the binder name `x` is preserved. -/ mvar.mvarId!.assign (← mkLambdaFVars xs result) goal.assign proof return true diff --git a/Mathlib/Topology/List.lean b/Mathlib/Topology/List.lean index 8c1cd3d3370549..706123c7bd2038 100644 --- a/Mathlib/Topology/List.lean +++ b/Mathlib/Topology/List.lean @@ -53,9 +53,9 @@ theorem nhds_list (as : List α) : 𝓝 as = traverse 𝓝 as := by ⟨u::v, List.Forall₂.cons hu hv, Subset.trans (Set.seq_mono (Set.image_mono hut) hvss) hus⟩ rcases this with ⟨v, hv, hvs⟩ - have : sequence v ∈ traverse 𝓝 l := + have : ∀ᶠ y in traverse 𝓝 l, sequence v y := mem_traverse _ _ <| hv.imp fun a s ⟨hs, ha⟩ => IsOpen.mem_nhds hs ha - refine mem_of_superset this fun u hu ↦ ?_ + refine Eventually.mono this fun u hu ↦ ?_ have hu := (List.mem_traverse _ _).1 hu have : List.Forall₂ (fun a s => IsOpen s ∧ a ∈ s) u v := by refine List.Forall₂.flip ?_ diff --git a/MathlibTest/Tactic/GRewrite.lean b/MathlibTest/Tactic/GRewrite.lean index 62a69dee5f6a3f..972184032da8e4 100644 --- a/MathlibTest/Tactic/GRewrite.lean +++ b/MathlibTest/Tactic/GRewrite.lean @@ -112,7 +112,7 @@ example (h₁ : W ⊂ Y) (h₂ : X ⊂ (W ∪ Z)) : X ⊂ (Y ∪ Z) := by guard_target =ₛ X ⊂ (W ∪ Z) exact h₂ --- binder names are not preserved: +-- Binder names are preserved: /-- trace: α : Type ?u.3 X Y Z W : Set α @@ -120,11 +120,11 @@ a b : ℕ h : a < b f : ℕ → ℕ hf : ∀ (i : ℕ), 0 ≤ f i -⊢ ∑ i ∈ {a | a < b}.toFinset, f i ≤ ∑ i ∈ {x | x < b}.toFinset, f i +⊢ ∑ j ∈ {z | z < b}.toFinset, f j ≤ ∑ i ∈ {x | x < b}.toFinset, f i -/ #guard_msgs in example {a b : Nat} (h : a < b) (f : Nat → Nat) (hf : ∀ i, 0 ≤ f i) : - ∑ j ∈ ({z | z ≤ a} : Set Nat), f j ≤ ∑ i ∈ ({x | x < b} : Set Nat), f i := by + ∑ j ∈ ({z | z ≤ a} : Set Nat), f j ≤ ∑ i ∈ ({x | x < b} : Set Nat), f i := by grewrite [h] trace_state rfl From 1857d442a8dbc42cdc29a97e9a684ceea15c7a90 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 10 Jul 2026 19:00:22 +0000 Subject: [PATCH 0723/1300] chore: use `Sort*` in the definition of `Equiv` (#41588) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change `(β : Sort _)` to `(β : Sort*)` in the definition of `Equiv`. --- Mathlib/Logic/Equiv/Defs.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Logic/Equiv/Defs.lean b/Mathlib/Logic/Equiv/Defs.lean index 0926a54045947a..532d1b9b997f17 100644 --- a/Mathlib/Logic/Equiv/Defs.lean +++ b/Mathlib/Logic/Equiv/Defs.lean @@ -66,7 +66,7 @@ universe u v w z variable {α : Sort u} {β : Sort v} {γ : Sort w} /-- `α ≃ β` is the type of functions from `α → β` with a two-sided inverse. -/ -structure Equiv (α : Sort*) (β : Sort _) where +structure Equiv (α β : Sort*) where /-- The forward map of an equivalence. Do NOT use directly. Use the coercion instead. -/ From 19e77d298b5e3a9df932543a36d10b9874b4145b Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 10 Jul 2026 19:53:01 +0000 Subject: [PATCH 0724/1300] chore(CategoryTheory/Sites/Descent/Precoverage): deprecate duplicate theorem (#41553) `Presieve.functorPushforward_overForget` is a duplicate of `Sieve.arrows_generate_map_eq_functorPushforward` (this was basically already noticed in #35189, but no deprecation was made then). Co-authored-by: tb65536 --- Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean | 2 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean b/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean index cfb85be4edb1c8..79b9cb7a7cedaf 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean @@ -397,7 +397,7 @@ lemma IsPrestack.of_precoverage obtain ⟨R', hR'⟩ := (Sieve.overEquiv _).symm.surjective (Sieve.generate R) rw [Presieve.isSheafFor_iff_generate] apply IsPrestackFor.isSheafFor' - simpa [Sieve.overEquiv_generate, Presieve.functorPushforward_overForget] + simpa [Sieve.overEquiv_generate, ← Sieve.arrows_generate_map_eq_functorPushforward] using hF _ _ hR /-- If a precoverage satisfies `HasIsos`, `IsStableUnderBaseChange` and diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 81bf60530d4028..3af74da41626a2 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -1485,6 +1485,7 @@ lemma Presieve.bind_ofArrows_le_bindOfArrows {ι : Type*} {X : C} (Z : ι → C) rw [← Sieve.ofArrows.fac hv', ← reassoc_of% hu] exact ⟨S, u, u' ≫ f _, ⟨_, _, h⟩, rfl⟩ +@[deprecated "Use Sieve.arrows_generate_map_eq_functorPushforward instead." (since := "2026-07-09")] lemma Presieve.functorPushforward_overForget {S : C} {X : Over S} (R : Presieve X) : Presieve.functorPushforward (Over.forget S) R = From e0394640a9b58504a907066ad37cafea3a8b75f7 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Fri, 10 Jul 2026 20:06:16 +0000 Subject: [PATCH 0725/1300] feat: more API specific to strict group homs (#41238) * Move the section of `Topology.Maps.Strict.Basic` about group homs to a new file `Topology.Maps.Strict.Group` * add more criterions for strictness of group homs * the first isomorphism theorem holds for strict group homs, yielding a [ContinuousMulEquiv](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Topology/Algebra/ContinuousMonoidHom.html#ContinuousMulEquiv) * various tweaks to namespaces and variables throughout the two files. --- Mathlib.lean | 1 + Mathlib/Topology/Maps/Strict/Basic.lean | 80 ++++++------------ Mathlib/Topology/Maps/Strict/Group.lean | 104 ++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 54 deletions(-) create mode 100644 Mathlib/Topology/Maps/Strict/Group.lean diff --git a/Mathlib.lean b/Mathlib.lean index 42345a6fdb224f..5fac66204eba26 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7986,6 +7986,7 @@ public import Mathlib.Topology.Maps.Proper.Basic public import Mathlib.Topology.Maps.Proper.CompactlyGenerated public import Mathlib.Topology.Maps.Proper.UniversallyClosed public import Mathlib.Topology.Maps.Strict.Basic +public import Mathlib.Topology.Maps.Strict.Group public import Mathlib.Topology.MetricSpace.Algebra public import Mathlib.Topology.MetricSpace.Antilipschitz public import Mathlib.Topology.MetricSpace.Basic diff --git a/Mathlib/Topology/Maps/Strict/Basic.lean b/Mathlib/Topology/Maps/Strict/Basic.lean index df5a1e96472a03..8489dffef5bae0 100644 --- a/Mathlib/Topology/Maps/Strict/Basic.lean +++ b/Mathlib/Topology/Maps/Strict/Basic.lean @@ -9,7 +9,6 @@ public import Mathlib.Topology.Maps.Basic public import Mathlib.Topology.Homeomorph.Quotient public import Mathlib.Topology.Constructions public import Mathlib.Data.Setoid.Basic -public import Mathlib.Topology.Algebra.Group.Quotient /-! # Bourbaki Strict Maps @@ -35,18 +34,6 @@ We provide several equivalent ways to characterize a strict map `f`: the canonical bijection `Quotient (Setoid.ker f) ≃ Set.range f` is a homeomorphism. * `Topology.isStrictMap_iff_isEmbedding_kerLift`: `f` is strict if and only if the canonical injection `Quotient (Setoid.ker f) → Y` (`Setoid.kerLift f`) is an embedding. - -### Group homomorphisms - -In general, the product (in the sense of `Prod.map`) of two strict maps need not be strict. -But thanks to `MonoidHom.isOpenQuotientMap_of_isQuotientMap`, we can replace `IsQuotientMap` -by `IsOpenQuotientMap` in the setting of group homomorphisms. Therefore we provide several -important properties of strict group homomorphisms : - -* `isStrictMap_iff_isOpenQuotientMap_rangeRestrict`: `f` is a strict group homomorphism if - and only if the `rangeRestrict` of `f` is an open quotient map. -* `isStrictMap_prodMap`: The product (in the sense of Prod.map) of strict group homomorphisms - is strict. -/ @[expose] public section @@ -56,8 +43,9 @@ open Function Set Topology Setoid namespace Topology variable {X Y Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z] - (f : X → Y) {g : Y → Z} + {f : X → Y} {g : Y → Z} +variable (f) in /-- A map is a strict map in the sense of Bourbaki if the natural map to its image is a quotient map. -/ def IsStrictMap : Prop := @@ -67,8 +55,6 @@ lemma isStrictMap_iff_isQuotientMap_rangeFactorization : IsStrictMap f ↔ IsQuotientMap (Set.rangeFactorization f) := Iff.rfl -variable {f} - /-- A map is a strict map if and only if the canonical bijection `Quotient (Setoid.ker f) ≃ Set.range f` is a homeomorphism. -/ theorem isStrictMap_iff_isHomeomorph_quotientKerEquivRange : @@ -80,10 +66,13 @@ theorem isStrictMap_iff_isHomeomorph_quotientKerEquivRange : /-- The homeomorphism `Quotient (Setoid.ker f) ≃ₜ Set.range f` given by a strict map `f`. This is the homeomorphism obtained from the first isomorphism theorem. -/ -noncomputable def Homeomorph.quotientKerEquivRange (hf : IsStrictMap f) : +noncomputable def _root_.Homeomorph.quotientKerEquivRange (hf : IsStrictMap f) : Quotient (Setoid.ker f) ≃ₜ Set.range f := (isStrictMap_iff_isHomeomorph_quotientKerEquivRange.mp hf).homeomorph +@[deprecated (since := "2026-07-10")] protected alias Homeomorph.quotientKerEquivRange := + Homeomorph.quotientKerEquivRange + /-- A map is a strict map if and only if the canonical injection `Quotient (Setoid.ker f) → Y` (`Setoid.kerLift f`) is an embedding. -/ theorem isStrictMap_iff_isEmbedding_kerLift : @@ -98,24 +87,33 @@ lemma IsStrictMap.continuous {f : X → Y} (hf : IsStrictMap f) : Continuous f : exact continuous_rangeFactorization_iff.mp hf.continuous /-- A open continuous map is a strict map. -/ -lemma IsOpenMap.isStrictMap (ho : IsOpenMap f) (h_cont : Continuous f) : +lemma _root_.IsOpenMap.isStrictMap (ho : IsOpenMap f) (h_cont : Continuous f) : IsStrictMap f := by rw [isStrictMap_iff_isQuotientMap_rangeFactorization] exact (ho.subtype_mk fun x => ⟨x, rfl⟩).isQuotientMap h_cont.rangeFactorization Set.rangeFactorization_surjective +@[deprecated (since := "2026-07-10")] protected alias IsOpenMap.isStrictMap := + IsOpenMap.isStrictMap + /-- A closed continuous map is a strict map. -/ -lemma IsClosedMap.isStrictMap (hc : IsClosedMap f) (h_cont : Continuous f) : +lemma _root_.IsClosedMap.isStrictMap (hc : IsClosedMap f) (h_cont : Continuous f) : IsStrictMap f := by rw [isStrictMap_iff_isQuotientMap_rangeFactorization] exact (hc.subtype_mk fun x => ⟨x, rfl⟩).isQuotientMap h_cont.rangeFactorization Set.rangeFactorization_surjective +@[deprecated (since := "2026-07-10")] protected alias IsClosedMap.isStrictMap := + IsClosedMap.isStrictMap + /-- A homeomorphism is a strict map. -/ -lemma IsHomeomorph.isStrictMap (f_homeo : IsHomeomorph f) : +lemma _root_.IsHomeomorph.isStrictMap (f_homeo : IsHomeomorph f) : IsStrictMap f := f_homeo.isOpenMap.isStrictMap f_homeo.continuous +@[deprecated (since := "2026-07-10")] protected alias IsHomeomorph.isStrictMap := + IsHomeomorph.isStrictMap + /-- The identity is a strict map. -/ lemma IsStrictMap.id : IsStrictMap (id : X → X) := IsHomeomorph.id.isStrictMap @@ -174,45 +172,19 @@ lemma isHomeomorph_iff_isStrictMap_bijective : and_assoc] /-- Strict maps are preserved when precomposing with a homeomorphism. -/ -lemma Homeomorph.isStrictMap_comp_iff (e : X ≃ₜ Y) {f : Y → Z} : +lemma _root_.Homeomorph.isStrictMap_comp_iff (e : X ≃ₜ Y) {f : Y → Z} : IsStrictMap (f ∘ e) ↔ IsStrictMap f := e.isQuotientMap.isStrictMap_iff.symm +@[deprecated (since := "2026-07-10")] protected alias Homeomorph.isStrictMap_comp_iff := + Homeomorph.isStrictMap_comp_iff + /-- Strict maps are preserved when postcomposing with a homeomorphism. -/ -lemma Homeomorph.comp_isStrictMap_iff (e : Y ≃ₜ Z) {f : X → Y} : +lemma _root_.Homeomorph.comp_isStrictMap_iff (e : Y ≃ₜ Z) {f : X → Y} : IsStrictMap (e ∘ f) ↔ IsStrictMap f := e.isEmbedding.isStrictMap_iff.symm -end Topology - -namespace MonoidHom - -variable {G H G' H' : Type*} [Group G'] [Group H'] [Group G] [Group H] (f : G →* H) (g : G' →* H') - [TopologicalSpace G] [IsTopologicalGroup G] [TopologicalSpace H] - -/-- A group homomorphism is strict if and only if its `rangeRestrict` is an open quotient map. -/ -@[to_additive] lemma isStrictMap_iff_isOpenQuotientMap_rangeRestrict : - IsStrictMap f ↔ IsOpenQuotientMap f.rangeRestrict := by - rw [isOpenQuotientMap_iff_isQuotientMap] - rfl - -variable {f g} [TopologicalSpace G'] [IsTopologicalGroup G'] [TopologicalSpace H'] +@[deprecated (since := "2026-07-10")] protected alias Homeomorph.comp_isStrictMap_iff := + Homeomorph.comp_isStrictMap_iff -/-- The product (in the sense of `Prod.map`) of group homomorphisms is strict if and only if each -of the morphisms is strict. -/ -@[to_additive isStrictMap_prodMap_iff] lemma isStrictMap_prodMap_iff : - IsStrictMap (f.prodMap g) ↔ IsStrictMap f ∧ IsStrictMap g := by - simp_rw [isStrictMap_iff_isOpenQuotientMap_rangeRestrict] - let Φ : (f.prodMap g).range ≃ₜ f.range × g.range := - (Homeomorph.setCongr (by simp [Subgroup.coe_prod])).trans (Homeomorph.Set.prod _ _) - have eq : Φ ∘ (f.prodMap g).rangeRestrict = f.rangeRestrict.prodMap g.rangeRestrict := rfl - rw [← Φ.comp_isOpenQuotientMap_iff, eq, MonoidHom.coe_prodMap, isOpenQuotientMap_prodMap_iff] - -/-- The product (in the sense of `Prod.map`) of strict group homomorphisms is strict -/ -@[to_additive isStrictMap_prodMap] lemma isStrictMap_prodMap (hf : IsStrictMap f) - (hg : IsStrictMap g) : IsStrictMap (f.prodMap g) := - isStrictMap_prodMap_iff.mpr ⟨hf, hg⟩ - --- TODO Add the lemma `isStrictMap_piMap` once `MonoidHom.piMap` has been defined. - -end MonoidHom +end Topology diff --git a/Mathlib/Topology/Maps/Strict/Group.lean b/Mathlib/Topology/Maps/Strict/Group.lean new file mode 100644 index 00000000000000..f199f927ff1b1e --- /dev/null +++ b/Mathlib/Topology/Maps/Strict/Group.lean @@ -0,0 +1,104 @@ +/- +Copyright (c) 2026 Ziyan Wei. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Ziyan Wei, Anatole Dedecker +-/ +module + +public import Mathlib.GroupTheory.QuotientGroup.Basic +public import Mathlib.Topology.Algebra.ContinuousMonoidHom +public import Mathlib.Topology.Algebra.Group.Quotient +public import Mathlib.Topology.Maps.Strict.Basic + +/-! +# Strict Group Homomorphisms + +In this file, we study homomorphisms of topological groups which are *strict* in the sense +of `Topology.IsStrictMap`. + +We provide specialized variations of general facts about `IsStrictMap` for convenience. +But we also show that strict group homomorphisms enjoy some extra properties compared to general +strict maps. Namely, we provide: +* `isStrictMap_iff_isOpenQuotientMap_rangeRestrict`: `f` is a strict group homomorphism if + and only if the `rangeRestrict` of `f` is an *open* quotient map. This ultimately relies + on `MonoidHom.isOpenQuotientMap_of_isQuotientMap`. +* `isStrictMap_prodMap`: The product (in the sense of `MonoidHom.prodMap`) of strict group + homomorphisms is strict. Note that this result is false for general maps; what makes things work + in our context is that, unlike `IsQuotientMap`, `IsOpenQuotientMap` is stable under product. +-/ + +@[expose] public section + +open Function Set Topology QuotientGroup + +namespace MonoidHom + +variable {G H G' H' : Type*} [Group G'] [Group H'] [Group G] [Group H] {f : G →* H} {g : G' →* H'} + [TopologicalSpace G] [TopologicalSpace H] + +/-- A group homomorphism is strict if and only if its `QuotientGroup.kerLift` is an embedding. -/ +@[to_additive /-- An additive group homomorphism is strict if and only if its +`QuotientAddGroup.kerLift` is an embedding. -/] +protected lemma isStrictMap_iff_isEmbedding_kerLift : + IsStrictMap f ↔ IsEmbedding (kerLift f) := by + -- Note: `G ⧸ MonoidHom.ker f` and `G ⧸ Setoid.ker f` are not definitionally equal, so + -- using `Topology.isStrictMap_iff_isEmbedding_kerLift` is too painful here. + simp_rw [isEmbedding_iff_isStrictMap_injective, kerLift_injective, and_true, + (isQuotientMap_mk _).isStrictMap_iff] + rfl + +/-- A group homomorphism is strict if and only if the canonical isomorphism +`G ⧸ f.ker ≃ f.range` is a homeomorphism. -/ +@[to_additive /-- An additive group homomorphism is strict if and only if the canonical isomorphism +`G ⧸ f.ker ≃ f.range` is a homeomorphism. -/] +protected lemma isStrictMap_iff_isHomeomorph_quotientKerEquivRange : + IsStrictMap f ↔ IsHomeomorph (quotientKerEquivRange f) := by + -- Note: `G ⧸ MonoidHom.ker f` and `G ⧸ Setoid.ker f` are not definitionally equal, so + -- using `Topology.isStrictMap_iff_isHomeomorph_quotientKerEquivRange` is too painful here. + simp_rw [isHomeomorph_iff_isStrictMap_bijective, EquivLike.bijective, and_true, + (isQuotientMap_mk _).isStrictMap_iff, IsEmbedding.subtypeVal.isStrictMap_iff] + rfl + +/-- The isomorphism of topological groups `G ⧸ f.ker ≃ f.range` given by a strict group +homomorphism `f`. This is an avatar of the first isomorphism theorem. -/ +@[to_additive /-- The isomorphism of topological additive groups `G ⧸ f.ker ≃ f.range` given by a +strict additive group homomorphism `f`. This is an avatar of the first isomorphism theorem. -/] +noncomputable def _root_.ContinuousMulEquiv.quotientKerEquivRange + (hf : IsStrictMap f) : G ⧸ f.ker ≃ₜ* f.range where + toMulEquiv := QuotientGroup.quotientKerEquivRange f + __ := (f.isStrictMap_iff_isHomeomorph_quotientKerEquivRange.mp hf).homeomorph + +variable [IsTopologicalGroup G] + +/-- A group homomorphism is strict if and only if its `rangeRestrict` is an open quotient map. -/ +@[to_additive /-- An additive group homomorphism is strict if and only if its `rangeRestrict` is an +open quotient map. -/] +protected lemma isStrictMap_iff_isOpenQuotientMap_rangeRestrict : + IsStrictMap f ↔ IsOpenQuotientMap f.rangeRestrict := by + rw [isOpenQuotientMap_iff_isQuotientMap] + rfl + +variable [TopologicalSpace G'] [IsTopologicalGroup G'] [TopologicalSpace H'] + +/-- The product (in the sense of `Prod.map`) of group homomorphisms is strict if and only if each +of the homomorphisms is strict. -/ +@[to_additive isStrictMap_prodMap_iff /-- The product (in the sense of `Prod.map`) of additive group +homomorphisms is strict if and only if each of the homomorphisms is strict. -/] +protected lemma isStrictMap_prodMap_iff : + IsStrictMap (f.prodMap g) ↔ IsStrictMap f ∧ IsStrictMap g := by + simp_rw [MonoidHom.isStrictMap_iff_isOpenQuotientMap_rangeRestrict] + let Φ : (f.prodMap g).range ≃ₜ f.range × g.range := + (Homeomorph.setCongr (by simp [Subgroup.coe_prod])).trans (Homeomorph.Set.prod _ _) + have eq : Φ ∘ (f.prodMap g).rangeRestrict = f.rangeRestrict.prodMap g.rangeRestrict := rfl + rw [← Φ.comp_isOpenQuotientMap_iff, eq, MonoidHom.coe_prodMap, isOpenQuotientMap_prodMap_iff] + +/-- The product (in the sense of `Prod.map`) of strict group homomorphisms is strict. -/ +@[to_additive isStrictMap_prodMap /-- The product (in the sense of `Prod.map`) of strict additive +group homomorphisms is strict. -/] +protected lemma isStrictMap_prodMap (hf : IsStrictMap f) + (hg : IsStrictMap g) : IsStrictMap (f.prodMap g) := + MonoidHom.isStrictMap_prodMap_iff.mpr ⟨hf, hg⟩ + +-- TODO: Add the lemma `isStrictMap_piMap` once `MonoidHom.piMap` has been defined. + +end MonoidHom From 0c00cfd56dfe7f24b1dcea7dfe4cb28ca11412fe Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Fri, 10 Jul 2026 20:22:05 +0000 Subject: [PATCH 0726/1300] feat: variations of Submodule.disjoint_map with weaker hypotheses (#41511) --- Mathlib/Algebra/Module/Submodule/Map.lean | 3 +-- Mathlib/LinearAlgebra/Span/Basic.lean | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 2e2f7d8ae98dc0..8ee3ab95cc8422 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -452,8 +452,7 @@ end OrderIso --TODO(Mario): is there a way to prove this from order properties? theorem map_inf_eq_map_inf_comap [RingHomSurjective σ₁₂] {f : M →ₛₗ[σ₁₂] M₂} {p : Submodule R M} {p' : Submodule R₂ M₂} : map f p ⊓ p' = map f (p ⊓ comap f p') := - le_antisymm (by rintro _ ⟨⟨x, h₁, rfl⟩, h₂⟩; exact ⟨_, ⟨h₁, h₂⟩, rfl⟩) - (le_inf (map_mono inf_le_left) (map_le_iff_le_comap.2 inf_le_right)) + .symm <| SetLike.coe_injective <| image_inter_preimage _ _ _ @[simp] theorem map_comap_subtype : map p.subtype (comap p.subtype p') = p ⊓ p' := diff --git a/Mathlib/LinearAlgebra/Span/Basic.lean b/Mathlib/LinearAlgebra/Span/Basic.lean index 2f16a8eb65657b..cd957fe7a6343d 100644 --- a/Mathlib/LinearAlgebra/Span/Basic.lean +++ b/Mathlib/LinearAlgebra/Span/Basic.lean @@ -561,6 +561,16 @@ theorem comap_map_sup_of_comap_le {f : M →ₛₗ[τ₁₂] M₂} {p : Submodul rw [add_comm, ← eq_sub_iff_add_eq, ← map_sub] at eq; subst eq simpa using p.add_mem (le hz) hy +lemma disjoint_map_of_ker_le_right {f : M →ₛₗ[τ₁₂] M₂} {p q : Submodule R M} + (hpq : Disjoint p q) (hker : f.ker ≤ q) : Disjoint (p.map f) (q.map f) := by + rw [disjoint_iff, map_inf_eq_map_inf_comap, comap_map_eq, eq_bot_iff, map_le_iff_le_comap, + comap_bot, sup_eq_left.mpr hker, hpq.eq_bot] + exact bot_le + +lemma disjoint_map_of_ker_le_left {f : M →ₛₗ[τ₁₂] M₂} {p q : Submodule R M} + (hpq : Disjoint p q) (hker : f.ker ≤ p) : Disjoint (p.map f) (q.map f) := + disjoint_map_of_ker_le_right hpq.symm hker |>.symm + theorem isCoatom_comap_or_eq_top (f : M →ₛₗ[τ₁₂] M₂) {p : Submodule R₂ M₂} (hp : IsCoatom p) : IsCoatom (comap f p) ∨ comap f p = ⊤ := or_iff_not_imp_right.mpr fun h ↦ ⟨h, fun q lt ↦ by From 61df950f3fe77af24ce23af50ac2ba83d290a12f Mon Sep 17 00:00:00 2001 From: Alex Korbonits <5281694+korbonits@users.noreply.github.com> Date: Fri, 10 Jul 2026 21:42:09 +0000 Subject: [PATCH 0727/1300] feat(Topology/Connected): path-connectedness of products and pi types (#40092) Add path-connectedness of binary products and dependent products (pi types): The analogous `LocPathConnectedSpace` / `LocallyConnectedSpace` product and pi instances (and further `connectedComponent` / `pathComponent` product lemmas) are left for follow-up PRs. --- Mathlib/Topology/Connected/PathConnected.lean | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index d2302fd0ec8004..b29d16279be30e 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -183,6 +183,7 @@ theorem JoinedIn.target_mem (h : JoinedIn F x y) : y ∈ F := def JoinedIn.somePath (h : JoinedIn F x y) : Path x y := Classical.choose h +@[simp] theorem JoinedIn.somePath_mem (h : JoinedIn F x y) (t : I) : h.somePath t ∈ F := Classical.choose_spec h t @@ -600,6 +601,55 @@ instance Real.instPathConnectedSpace : PathConnectedSpace ℝ where joined x y := ⟨⟨⟨fun (t : I) ↦ (1 - t) * x + t * y, by fun_prop⟩, by simp, by simp⟩⟩ nonempty := inferInstance +/-! ### Products and pi types -/ + +section Prod + +variable {s : Set X} {t : Set Y} + +/-- If `x₁` is joined to `x₂` within `s` and `y₁` to `y₂` within `t`, then `(x₁, y₁)` is joined +to `(x₂, y₂)` within `s ×ˢ t`. -/ +theorem JoinedIn.prod {x₁ x₂ : X} {y₁ y₂ : Y} (hx : JoinedIn s x₁ x₂) (hy : JoinedIn t y₁ y₂) : + JoinedIn (s ×ˢ t) (x₁, y₁) (x₂, y₂) := + ⟨hx.somePath.prod hy.somePath, by simp⟩ + +/-- The product of two path-connected sets is path-connected. -/ +theorem IsPathConnected.prod (hs : IsPathConnected s) (ht : IsPathConnected t) : + IsPathConnected (s ×ˢ t) := by + rw [isPathConnected_iff] + refine ⟨hs.nonempty.prod ht.nonempty, fun (x₁, y₁) ⟨hx₁, hy₁⟩ (x₂, y₂) ⟨hx₂, hy₂⟩ ↦ ?_⟩ + exact hs.joinedIn x₁ hx₁ x₂ hx₂ |>.prod <| ht.joinedIn y₁ hy₁ y₂ hy₂ + +instance Prod.instPathConnectedSpace [PathConnectedSpace X] [PathConnectedSpace Y] : + PathConnectedSpace (X × Y) := by + rw [pathConnectedSpace_iff_univ, ← Set.univ_prod_univ] + exact isPathConnected_univ.prod isPathConnected_univ + +end Prod + +section Pi + +variable {Z : ι → Type*} [∀ i, TopologicalSpace (Z i)] + +/-- If for each `i`, `x i` is joined to `y i` within `s i`, then `x` is joined to `y` within the +product set `Set.univ.pi s`. -/ +theorem JoinedIn.pi {s : ∀ i, Set (Z i)} {x y : ∀ i, Z i} + (h : ∀ i, JoinedIn (s i) (x i) (y i)) : JoinedIn (Set.univ.pi s) x y := + ⟨.pi (fun i ↦ (h i).somePath), by simp⟩ + +/-- The product of a family of path-connected sets is path-connected. -/ +theorem IsPathConnected.pi {s : ∀ i, Set (Z i)} (h : ∀ i, IsPathConnected (s i)) : + IsPathConnected (Set.univ.pi s) := by + choose x hx hjoin using h + exact ⟨x, by simpa, fun y hy ↦ .pi fun i ↦ hjoin i (by grind)⟩ + +instance Pi.instPathConnectedSpace [∀ i, PathConnectedSpace (Z i)] : + PathConnectedSpace (∀ i, Z i) := by + rw [pathConnectedSpace_iff_univ, ← Set.pi_univ] + exact .pi fun _ ↦ isPathConnected_univ + +end Pi + theorem pathConnectedSpace_iff_eq : PathConnectedSpace X ↔ ∃ x : X, pathComponent x = univ := by simp [pathConnectedSpace_iff_univ, isPathConnected_iff_eq] From 4de1b93c2153bdf5cdd365ef57af14905150446a Mon Sep 17 00:00:00 2001 From: Francesco Vercellesi <109623632+franv314@users.noreply.github.com> Date: Fri, 10 Jul 2026 22:03:58 +0000 Subject: [PATCH 0728/1300] feat(Topology/Order/IntermediateValue): add fixed point theorem (#41360) If a function is continuous and surjective from a closed interval to itself, then is has a fixed point. --- Mathlib/Topology/Order/IntermediateValue.lean | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Mathlib/Topology/Order/IntermediateValue.lean b/Mathlib/Topology/Order/IntermediateValue.lean index 3bcb0694485bac..843b1fb9c18b9b 100644 --- a/Mathlib/Topology/Order/IntermediateValue.lean +++ b/Mathlib/Topology/Order/IntermediateValue.lean @@ -587,6 +587,25 @@ theorem exists_mem_Icc_isFixedPt_of_mapsTo {a b : α} {f : α → α} (hf : Cont (hle : a ≤ b) (hmaps : MapsTo f (Icc a b) (Icc a b)) : ∃ c ∈ Icc a b, IsFixedPt f c := exists_mem_Icc_isFixedPt hf hle (hmaps <| left_mem_Icc.2 hle).1 (hmaps <| right_mem_Icc.2 hle).2 +/-- Version of `exists_mem_Icc_isFixedPt_of_mapsTo` using `Set.uIcc` -/ +theorem exists_mem_uIcc_isFixedPt_of_mapsTo {a b : α} {f : α → α} (hf : ContinuousOn f (uIcc a b)) + (hmaps : MapsTo f (uIcc a b) (uIcc a b)) : ∃ c ∈ uIcc a b, IsFixedPt f c := + exists_mem_Icc_isFixedPt_of_mapsTo hf inf_left_le_sup_left hmaps + +/-- If a closed interval is contained in its own image under a continuous map `f : α → α`, +then this map has a fixed point on this interval. -/ +theorem exists_mem_Icc_isFixedPt_of_surjOn {a b : α} {f : α → α} (hf : ContinuousOn f (Icc a b)) + (hle : a ≤ b) (h_surj : SurjOn f (Icc a b) (Icc a b)) : ∃ c ∈ Icc a b, IsFixedPt f c := + have ⟨x₀, hx₀⟩ := h_surj (left_mem_Icc.mpr hle) + have ⟨x₁, hx₁⟩ := h_surj (right_mem_Icc.mpr hle) + isPreconnected_Icc.intermediate_value₂ + hx₀.1 hx₁.1 hf continuousOn_id (by grind) (by grind) + +/-- Version of `exists_mem_Icc_isFixedPt_of_surjOn` using `Set.uIcc` -/ +theorem exists_mem_uIcc_isFixedPt_of_surjOn {a b : α} {f : α → α} (hf : ContinuousOn f (uIcc a b)) + (h_surj : SurjOn f (uIcc a b) (uIcc a b)) : ∃ c ∈ uIcc a b, IsFixedPt f c := + exists_mem_Icc_isFixedPt_of_surjOn hf inf_left_le_sup_left h_surj + theorem intermediate_value_Ico {a b : α} (hab : a ≤ b) {f : α → δ} (hf : ContinuousOn f (Icc a b)) : Ico (f a) (f b) ⊆ f '' Ico a b := Or.elim (eq_or_lt_of_le hab) (fun he _ h => absurd h.2 (not_lt_of_ge (he ▸ h.1))) fun hlt => From 6e91c0d7bea2ad0475ec17fa32e8b6cf0a608ab2 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Fri, 10 Jul 2026 22:27:46 +0000 Subject: [PATCH 0729/1300] doc: fix docstring of orthogonalProjectionOnto (#41568) This PR fixes the docstring of `Submodule.orthogonalProjectionOnto`, which said "complete subspace" (a leftover from the removed `orthogonalProjectionFn` docstring), even though the hypothesis `[K.HasOrthogonalProjection]` is strictly weaker than completeness. Restore the pre-existing wording "The orthogonal projection onto a subspace.", matching the deprecated `orthogonalProjection` abbrev just below. --- Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean index 09797f0b3d9bc8..fa9b6e01850880 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean @@ -109,7 +109,7 @@ section orthogonalProjection variable [K.HasOrthogonalProjection] -/-- The orthogonal projection onto a complete subspace. -/ +/-- The orthogonal projection onto a subspace. -/ def orthogonalProjectionOnto : E →L[𝕜] K := K.projectionOntoL Kᗮ K.isTopCompl_orthogonal /-- The orthogonal projection onto a subspace. -/ From c368140668f5fa16a1bd977448c1f665d48c3df4 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Fri, 10 Jul 2026 22:27:48 +0000 Subject: [PATCH 0730/1300] chore(Topology/DiscreteSubset): fix typo eventualy -> eventually in lemma name (#41569) This PR renames `Disjoint.eventualy_nhdsWithin_specializes` to `Disjoint.eventually_nhdsWithin_specializes`, fixing the misspelling "eventualy", and update its single (internal) use site. The lemma was merged three days ago and has not been in any release, so no deprecated alias is added. --- Mathlib/Topology/DiscreteSubset.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 6b7212902f7641..2cff2fe9277615 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -375,7 +375,7 @@ lemma mem_codiscrete {S : Set X} : S ∈ codiscrete X ↔ ∀ x, Disjoint (𝓝[≠] x) (𝓟 Sᶜ) := by simp [codiscrete, mem_codiscreteWithin, compl_eq_univ_sdiff] -lemma Disjoint.eventualy_nhdsWithin_specializes +lemma Disjoint.eventually_nhdsWithin_specializes {p : X} {s : Set X} (hs : Disjoint (𝓝[s] p) cofinite) : ∀ᶠ x in 𝓝[s] p, x ⤳ p := by obtain ⟨t, h₁t, h₂t⟩ := disjoint_cofinite_right.mp hs @@ -393,7 +393,7 @@ lemma Disjoint.nhdsWithin_eq_of_cofinite {p : X} {s : Set X} (hs : Disjoint (𝓝[s] p) cofinite) : 𝓝[s] p = 𝓟 ({x | x ⤳ p} ∩ s) := by apply le_antisymm - · simpa using ⟨hs.eventualy_nhdsWithin_specializes, self_mem_nhdsWithin⟩ + · simpa using ⟨hs.eventually_nhdsWithin_specializes, self_mem_nhdsWithin⟩ · rw [← inf_principal, nhdsWithin] gcongr rw [Filter.principal_le_iff] From 052559c5c957052541d779c79f6c57f78379de8b Mon Sep 17 00:00:00 2001 From: Evgenia Karunus Date: Sat, 11 Jul 2026 09:24:57 +0000 Subject: [PATCH 0731/1300] feat(MeasureTheory/Function/EssSup): add iSup_le_essSup, add essSup_le_iSup (#40453) From the Carleson project. --- Mathlib/MeasureTheory/Function/EssSup.lean | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Mathlib/MeasureTheory/Function/EssSup.lean b/Mathlib/MeasureTheory/Function/EssSup.lean index 62d7b80de3e784..daae5e3c3a3c57 100644 --- a/Mathlib/MeasureTheory/Function/EssSup.lean +++ b/Mathlib/MeasureTheory/Function/EssSup.lean @@ -302,6 +302,9 @@ theorem essInf_const_top : essInf (fun _ : α => (⊤ : β)) μ = (⊤ : β) := lemma essSup_eq_iSup (hμ : ∀ a, μ {a} ≠ 0) (f : α → β) : essSup f μ = ⨆ i, f i := by rw [essSup, ae_eq_top.2 hμ, limsup_top_eq_iSup] +lemma essSup_le_iSup {f : α → β} : essSup f μ ≤ ⨆ i, f i := + essSup_le_of_ae_le _ (ae_of_all _ (le_iSup f)) + lemma essInf_eq_iInf (hμ : ∀ a, μ {a} ≠ 0) (f : α → β) : essInf f μ = ⨅ i, f i := by rw [essInf, ae_eq_top.2 hμ, liminf_top_eq_iInf] @@ -313,6 +316,21 @@ lemma essInf_eq_iInf (hμ : ∀ a, μ {a} ≠ 0) (f : α → β) : essInf f μ = end CompleteLattice +section CompleteLinearOrder + +variable [CompleteLinearOrder β] + +lemma iSup_eq_essSup {f : α → β} (h : ∀ ⦃x a⦄, a < f x → μ {y | a < f y} ≠ 0) : + ⨆ x, f x = essSup f μ := by + apply le_antisymm (iSup_le _) essSup_le_iSup + intro i + rw [essSup_eq_sInf] + apply le_sInf + intro b hb + exact not_lt.mp fun a ↦ h a hb + +end CompleteLinearOrder + namespace ENNReal variable {f : α → ℝ≥0∞} From 5e1cacbae25bf77b65215f70f89fe2124bebdd60 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sat, 11 Jul 2026 11:20:34 +0000 Subject: [PATCH 0732/1300] feat: a map is smooth iff its post-composition with an immersion is (#28865) A future PR will use this to golf the results in `Icc/Instances.lean`; we will also use this to study bordism theory. --- Mathlib/Analysis/Calculus/ContDiff/Defs.lean | 7 ++ Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 9 ++ Mathlib/Geometry/Manifold/Immersion.lean | 94 ++++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Calculus/ContDiff/Defs.lean b/Mathlib/Analysis/Calculus/ContDiff/Defs.lean index 31a39178b239c9..aac7759c6a9585 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Defs.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Defs.lean @@ -254,6 +254,13 @@ theorem ContDiffWithinAt.congr (h : ContDiffWithinAt 𝕜 n f s x) (h₁ : ∀ y (hx : f₁ x = f x) : ContDiffWithinAt 𝕜 n f₁ s x := h.congr_of_eventuallyEq (Filter.eventuallyEq_of_mem self_mem_nhdsWithin h₁) hx +/-- Version of `ContDiffWithinAt.congr` where `x` need not be contained in `s`, +but `f` and `f₁` are equal on a set containing both. -/ +theorem ContDiffWithinAt.congr' (h : ContDiffWithinAt 𝕜 n f s x) (h₁ : ∀ y ∈ t, f₁ y = f y) + (hst : s ⊆ t) (hxt : x ∈ t) : + ContDiffWithinAt 𝕜 n f₁ s x := + h.congr (fun _y hy ↦ h₁ _ (hst hy)) (h₁ x hxt) + theorem contDiffWithinAt_congr (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : f₁ x = f x) : ContDiffWithinAt 𝕜 n f₁ s x ↔ ContDiffWithinAt 𝕜 n f s x := ⟨fun h' ↦ h'.congr (fun x hx ↦ (h₁ x hx).symm) hx.symm, fun h' ↦ h'.congr h₁ hx⟩ diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index c4a9815c985c17..3e578df2a2dcbe 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -423,6 +423,15 @@ theorem contMDiffWithinAt_iff_image refine fun _ => contDiffWithinAt_congr_set ?_ simp_rw [e.extend_symm_preimage_inter_range_eventuallyEq hs hx] +theorem contMDiffAt_iff_of_mem_maximalAtlas {x : M} (he : e ∈ maximalAtlas I n M) + (he' : e' ∈ maximalAtlas I' n M') (hx : x ∈ e.source) (hy : f x ∈ e'.source) : + ContMDiffAt I I' n f x ↔ + ContinuousAt f x ∧ + ContDiffWithinAt 𝕜 n (e'.extend I' ∘ f ∘ (e.extend I).symm) (range I) (e.extend I x) := by + rw [← contMDiffWithinAt_univ, + contMDiffWithinAt_iff_of_mem_maximalAtlas he he' hx hy, + continuousWithinAt_univ, preimage_univ, univ_inter] + /-- One can reformulate being `C^n` within a set at a point as continuity within this set at this point, and being `C^n` in any chart containing that point. -/ theorem contMDiffWithinAt_iff_of_mem_source [IsManifold I n M] [IsManifold I' n M'] diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index 8d81f03d5e84e4..545786bc5c650f 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -60,6 +60,9 @@ This shortens the overall argument, as the definition of submersions has the sam * `IsImmersionAt.contMDiffAt`: if f is an immersion at `x`, it is `C^n` at `x`. * `IsImmersion.contMDiff`: if f is a `C^n` immersion, it is automatically `C^n` in the sense of `ContMDiff`. +* `ContMDiffAt.iff_comp_isImmersionAt` and `ContMDiff.iff_comp_isImmersion`: a function `f : M → N` + is `C^n` (at `x`) if and only if it is continuous (at `x`) and its composition `φ ∘ f` with a + `C^n` immersion `φ : N → P` (at `f x`) is `C^n`. ## Implementation notes @@ -434,6 +437,70 @@ theorem contMDiffOn (h : IsImmersionAtOfComplement F I J n f x) : theorem contMDiffAt (h : IsImmersionAtOfComplement F I J n f x) : CMDiffAt n f x := h.contMDiffOn.contMDiffAt (h.domChart.open_source.mem_nhds (mem_domChart_source h)) +/-- Let `f : M → N` be a function, and suppose `φ : N → N'` is a `C^n` immersion at `f x`, such +that `φ ∘ f` is `C^n` at `x`. Let `x ∈ t ⊆ M` be contained in the slice chart at `f x`. +Then `f` seen in the slice chart at `φ (f x)` and the preferred chart at `x` +is `C^n` at (the image of) `x` within (the image of) `t`. -/ +private lemma aux {f : M → N} {φ : N → N'} + (h : IsImmersionAtOfComplement F J J' n φ (f x)) (h' : CMDiffAt n (φ ∘ f) x) + {t : Set M} (ht : t ⊆ f ⁻¹' h.domChart.source) (hxt : x ∈ t) : + ContDiffWithinAt 𝕜 n ((h.domChart.extend J) ∘ f ∘ (extChartAt I x).symm) + ((extChartAt I x).symm ⁻¹' t ∩ range I) ((extChartAt I x) x) := by + -- Consider the local expressions of `f`, `φ`, `x` and `s'` in the charts we're considering. + set f' := (h.domChart.extend J) ∘ f ∘ (extChartAt I x).symm + set φ' := (h.codChart.extend J') ∘ φ ∘ (h.domChart.extend J).symm + set x' := (extChartAt I x) x + set s := (extChartAt I x).symm ⁻¹' t ∩ range I + have hx' : extChartAt I x x ∈ s := ⟨by simp [mem_chart_source H x, hxt], mem_range_self _⟩ + have h'loc : ContDiffWithinAt 𝕜 n ((h.codChart.extend J') ∘ (φ ∘ f) ∘ (extChartAt I x).symm) + ((extChartAt I x).symm ⁻¹' t ∩ range I) (extChartAt I x x) := by + replace h' : CMDiffAt[t] n (φ ∘ f) x := h'.contMDiffWithinAt + rw [contMDiffWithinAt_iff_of_mem_maximalAtlas' h.codChart_mem_maximalAtlas] at h' + exacts [h'.2, h.mem_codChart_source] + -- By hypothesis, `φ ∘ f` (read in our charts) is `C^n` at `x'` within `s`. + have h'' : ContDiffWithinAt 𝕜 n (φ' ∘ f') s x' := by + apply h'loc.congr_of_mem (fun y hy ↦ ?_) hx' + simp only [mfld_simps, φ', f'] + rw [h.domChart.left_inv] + apply ht hy.1 + -- On the other hand, composing `f'` with the inclusion `u ↦ (u, 0)` is also `C^n` + -- (as a composition of `C^n` functions); this locally equals `φ ∘ f` in coordinates + -- (since `f` is an immersion). + set f'' := (h.equiv ∘ fun x ↦ (x, 0)) ∘ f' + have h''' : ContDiffWithinAt 𝕜 n f'' s x' := by + refine h''.congr_of_mem (fun y hy ↦ ?_) hx' + simp only [f'', φ', f'] + nth_rw 2 [comp_apply] + rw [Function.comp_apply, h.writtenInCharts] + rw [h.domChart.extend_target_eq_image_source] + exact ⟨(f ∘ (extChartAt I x).symm) y, ht hy.1, by simp⟩ + -- Composing with a suitable projection to cancel the inclusion, we deduce that `f` is `C^n`. + have h'''' : ContDiffWithinAt 𝕜 n ((Prod.fst ∘ h.equiv.symm) ∘ f'') s x' := by + refine ContDiffWithinAt.comp x' ?_ h''' (mapsTo_univ _ _) + rw [contDiffWithinAt_univ] + exact contDiffAt_fst.comp _ h.equiv.symm.contDiff.contDiffAt + exact h''''.congr_of_mem (fun y hy ↦ by simp [f'']) hx' + +/-- A function `f : M → N` between `C^n` manifolds is `C^n` at `x` if and only if it is continuous +at `x` and its composition `φ ∘ f` with a `C^n` immersion `φ : N → N'` at `f x` is `C^n` at `x`. -/ +lemma _root_.ContMDiffAt.iff_comp_isImmersionAtOfComplement + {f : M → N} {φ : N → N'} (hφ : IsImmersionAtOfComplement F J J' n φ (f x)) : + -- Note: `φ` need not be inducing, so continuity of `φ ∘ f` at `x` + -- generally does not imply continuity of `f` + CMDiffAt n f x ↔ ContinuousAt f x ∧ CMDiffAt n (φ ∘ f) x := by + refine ⟨fun hf ↦ ⟨hf.continuousAt, hφ.contMDiffAt.comp x hf⟩, fun ⟨hf, h'⟩ ↦ ?_⟩ + -- Since `f` is continuous at `x`, some neighbourhood `t` of `x` is mapped + -- into `hφ.domChart.source` under `f`. By restriction, we may assume `t` is open, + -- so it suffices to test smoothness on `t`. + have : hφ.domChart.source ∈ 𝓝 (f x) := hφ.domChart.open_source.mem_nhds hφ.mem_domChart_source + obtain ⟨t, ht, htopen, hxt⟩ := mem_nhds_iff.mp (hf this) + suffices CMDiffAt[t] n f x from this.contMDiffAt <| htopen.mem_nhds hxt + -- We test smoothness of `f` on `t` in the preferred chart at `x` and `hφ.codChart`. + rw [contMDiffWithinAt_iff_of_mem_maximalAtlas' + hφ.domChart_mem_maximalAtlas hφ.mem_domChart_source] + refine ⟨hf.continuousWithinAt, ?_⟩ + exact aux hφ h' ht hxt + end IsImmersionAtOfComplement namespace IsImmersionAt @@ -620,6 +687,15 @@ theorem contMDiffOn (h : IsImmersionAt I J n f x) : CMDiff[h.domChart.source] n theorem contMDiffAt (h : IsImmersionAt I J n f x) : CMDiffAt n f x := h.isImmersionAtOfComplement_complement.contMDiffAt +/-- A function `f : M → N` between `C^n` manifolds is `C^n` at `x` if and only if it is continuous +at `x` and its composition `φ ∘ f` with a `C^n` immersion `φ : N → N'` at `f x` is `C^n` at `x`. -/ +lemma _root_.ContMDiffAt.iff_comp_isImmersionAt {f : M → N} {φ : N → N'} + (hφ : IsImmersionAt J J' n φ (f x)) : + -- Note: `φ` need not be inducing, so continuity of `φ ∘ f` at `x` + -- generally does not imply continuity of `f` + CMDiffAt n f x ↔ ContinuousAt f x ∧ CMDiffAt n (φ ∘ f) x := by + rw [← ContMDiffAt.iff_comp_isImmersionAtOfComplement hφ.isImmersionAtOfComplement_complement] + end IsImmersionAt variable (F I J n) in @@ -748,10 +824,18 @@ lemma sumInr {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] [IsManifold @[deprecated (since := "2025-12-16")] alias ofOpen := of_opens /-- A `C^n` immersion is `C^n`. -/ -theorem contMDiff - (h : IsImmersionOfComplement F I J n f) : CMDiff n f := +theorem contMDiff (h : IsImmersionOfComplement F I J n f) : CMDiff n f := fun x ↦ (h x).contMDiffAt +/-- A function `f : M → N` between `C^n` manifolds is `C^n` if and only if it is continuous +and its composition `φ ∘ f` with a `C^n` immersion `φ : N → N'` is `C^n`. -/ +lemma _root_.ContMDiff.iff_comp_isImmersionOfComplement {f : M → N} {φ : N → N'} + (hφ : IsImmersionOfComplement F J J' n φ) : + CMDiff n f ↔ Continuous f ∧ CMDiff n (φ ∘ f) := by + refine ⟨fun h ↦ ⟨h.continuous, hφ.contMDiff.comp h⟩, fun ⟨h, h'⟩ x ↦ ?_⟩ + rw [ContMDiffAt.iff_comp_isImmersionAtOfComplement (hφ (f x))] + exact ⟨h.continuousAt, h' x⟩ + end IsImmersionOfComplement namespace IsImmersion @@ -825,6 +909,12 @@ theorem contMDiff (h : IsImmersion I J n f) : CMDiff n f := h.isImmersionOfComplement_complement.contMDiff +/-- A function `f : M → N` between `C^n` manifolds is `C^n` if and only if it is continuous +and its composition `φ ∘ f` with a `C^n` immersion `φ : N → N'` is `C^n`. -/ +lemma _root_.ContMDiff.iff_comp_isImmersion {f : M → N} {φ : N → N'} (hφ : IsImmersion J J' n φ) : + CMDiff n f ↔ Continuous f ∧ CMDiff n (φ ∘ f) := by + rw [ContMDiff.iff_comp_isImmersionOfComplement hφ.isImmersionOfComplement_complement] + end IsImmersion end Manifold From 4efb186f102ebfd2eea1545c151d6fbcfdff0e43 Mon Sep 17 00:00:00 2001 From: Pepa Montero Jimena Date: Sat, 11 Jul 2026 12:12:25 +0000 Subject: [PATCH 0733/1300] =?UTF-8?q?feat(Topology/Algebra/InfiniteSum/Nat?= =?UTF-8?q?Int):=20hasProd=20versions=20of=20=E2=84=95+/=E2=84=95=20transf?= =?UTF-8?q?er=20lemmas=20(#41502)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `PNat` section of `Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean` provides `Multipliable` and `tprod` lemmas for transferring infinite products between `ℕ+` and `ℕ`, but not `HasProd` lemmas. This PR completes this gap with: * `hasProd_pnat_iff_hasProd_succ`: `HasProd (fun n : ℕ+ ↦ f n) m ↔ HasProd (fun n : ℕ ↦ f (n + 1)) m`, the `HasProd` counterpart of the existing `multipliable_pnat_iff_multipliable_succ` * `hasProd_pnat_iff`: in a topological group, `HasProd (fun n : ℕ+ ↦ f n) g ↔ HasProd f (g * f 0)`, the counterpart of `multipliable_pnat_iff_multipliable_nat` * `tprod_pnat_eq_tprod_of_eq_one`: if `f 0 = 1`, then `∏' n : ℕ+, f n = ∏' n, f n`. Unlike `tprod_zero_pnat_eq_tprod_nat`, this requires no multipliability hypothesis (and no group structure or `T2Space`) **Motivation**: the additive versions (`hasSum_pnat_iff`, `tsum_pnat_eq_tsum_of_eq_zero`, ...) replace three private lemmas in the [FLT project](https://github.com/ImperialCollegeLondon/FLT) (`hasSum_nat_of_pnat_add`, `hasSum_pnat_of_nat`, `tsum_pnat_of_zero`), each of which becomes a one-line application, stated there for `ℂ` only. **AI Disclosure**: original code in FLT was written by William Coram and Samuel Yin with the assistance of Claude. It was later cleaned up using Codex. Co-authored-by: William Coram Co-authored-by: Samuel Yin --- .../Topology/Algebra/InfiniteSum/NatInt.lean | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean index e0dbc3df77b3fe..8da2192c993191 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean @@ -541,10 +541,28 @@ lemma multipliable_pnat_iff_multipliable_nat [TopologicalSpace G] [IsTopological {f : ℕ → G} : Multipliable (fun n : ℕ+ ↦ f n) ↔ Multipliable f := by rw [multipliable_pnat_iff_multipliable_succ, multipliable_nat_add_iff] +@[to_additive] +theorem hasProd_pnat_iff_hasProd_succ {f : ℕ → M} : + HasProd (fun x : ℕ+ ↦ f x) m ↔ HasProd (fun x : ℕ ↦ f (x + 1)) m := + Equiv.pnatEquivNat.symm.hasProd_iff.symm + +@[to_additive] +theorem hasProd_pnat_iff [TopologicalSpace G] [IsTopologicalGroup G] {f : ℕ → G} {a : G} : + HasProd (fun x : ℕ+ ↦ f x) a ↔ HasProd f (a * f 0) := by + simp [hasProd_pnat_iff_hasProd_succ, hasProd_nat_add_iff] + @[to_additive] theorem tprod_pnat_eq_tprod_succ {f : ℕ → M} : ∏' n : ℕ+, f n = ∏' n, f (n + 1) := (Equiv.pnatEquivNat.symm.tprod_eq _).symm +@[to_additive] +theorem tprod_pnat_eq_tprod_of_eq_one {f : ℕ → M} (hf : f 0 = 1) : + ∏' n : ℕ+, f n = ∏' n : ℕ, f n := + PNat.coe_injective.tprod_eq fun n hn ↦ by + rcases Nat.eq_zero_or_pos n with rfl | h + · exact absurd hf hn + · exact ⟨⟨n, h⟩, rfl⟩ + @[to_additive] lemma tprod_zero_pnat_eq_tprod_nat [TopologicalSpace G] [IsTopologicalGroup G] [T2Space G] {f : ℕ → G} (hf : Multipliable f) : From 79aee35d9696d759b73eed71d7dde666750bc35e Mon Sep 17 00:00:00 2001 From: "mathlib-nolints[bot]" <258989889+mathlib-nolints[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 00:39:24 +0000 Subject: [PATCH 0734/1300] chore(scripts): update nolints.json (#41627) I am happy to remove some nolints for you! --- scripts/nolints.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/nolints.json b/scripts/nolints.json index c2e26b90be252a..26d79efc46e85a 100644 --- a/scripts/nolints.json +++ b/scripts/nolints.json @@ -483,8 +483,6 @@ "CategoryTheory.IsCardinalFiltered.exists_cardinal_directed.instPartialOrderDiagramWithUniqueTerminal"], ["defsWithUnderscore", "CategoryTheory.Limits.BinaryBicone.retract_left"], ["defsWithUnderscore", "CategoryTheory.Limits.BinaryBicone.retract_right"], - ["defsWithUnderscore", "CategoryTheory.Limits.Cocone.ext_inv"], - ["defsWithUnderscore", "CategoryTheory.Limits.Cone.ext_inv"], ["defsWithUnderscore", "CategoryTheory.Limits.IsCofiltered.sequentialFunctor_obj"], ["defsWithUnderscore", From b95982f413bf08801f23ed434feeb52dad009330 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 10:17:32 +0000 Subject: [PATCH 0735/1300] chore(Geometry/Manifold/ContMDiff/Atlas): generalise `mem_maximalAtlas_of_contMDiffOn` and friends (#40720) These lemmas were only stated about maps on the underlying topological space `H`. They should be generalised to include charts of the manifold `M`. This comes up when proving that diffeomorphisms are immersions (by hand) and also when defining quotient manifolds. Follow-up to #40632. Co-authored-by: grunweg <10105016+grunweg@users.noreply.github.com> Co-authored-by: Michael Rothgang --- .../Geometry/Manifold/ContMDiff/Atlas.lean | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean index 811c6456c64ac7..ae089b85638df8 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean @@ -157,21 +157,28 @@ theorem contMDiffOn_of_mem_contDiffGroupoid {e' : OpenPartialHomeomorph H H} (h : e' ∈ contDiffGroupoid n I) : ContMDiffOn I I n e' e'.source := (contDiffWithinAt_localInvariantProp n).liftPropOn_of_mem_groupoid contDiffWithinAtProp_id h -lemma OpenPartialHomeomorph.mem_maximalAtlas_of_contMDiffOn (φ : OpenPartialHomeomorph H H) - (hφ : ContMDiffOn I I n φ φ.source) (hφ' : ContMDiffOn I I n φ.symm φ.target) : - φ ∈ maximalAtlas I n H := by - simp only [mfld_simps, IsManifold.mem_maximalAtlas_iff, StructureGroupoid.maximalAtlas, forall_eq, +lemma OpenPartialHomeomorph.mem_maximalAtlas_of_contMDiffOn [IsManifold I n M] + (φ : OpenPartialHomeomorph M H) (hφ : ContMDiffOn I I n φ φ.source) + (hφ' : ContMDiffOn I I n φ.symm φ.target) : + φ ∈ maximalAtlas I n M := by + simp only [mfld_simps, IsManifold.mem_maximalAtlas_iff, StructureGroupoid.maximalAtlas, contDiffGroupoid, mem_groupoid_of_pregroupoid, contDiffPregroupoid, ← contMDiffOn_iff_contDiffOn] + intro e he + have he' := contMDiffOn_of_mem_maximalAtlas (I := I) (n := n) + (StructureGroupoid.subset_maximalAtlas _ he) + have he'' := contMDiffOn_symm_of_mem_maximalAtlas (I := I) (n := n) + (StructureGroupoid.subset_maximalAtlas _ he) refine ⟨⟨?_, ?_⟩, ?_, ?_⟩ all_goals apply I.contMDiff.comp_contMDiffOn - · exact hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) - · exact hφ.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) - · exact hφ.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) - · exact hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by simp) - -lemma IsManifold.mem_maximalAtlas_iff_contMDiffOn (φ : OpenPartialHomeomorph H H) : - φ ∈ maximalAtlas I n H ↔ ContMDiffOn I I n φ φ.source ∧ ContMDiffOn I I n φ.symm φ.target := + · apply he'.comp (hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by grind)) (by grind) + · apply hφ.comp (he''.comp (I.contMDiffOn_symm.mono (by simp)) (by grind)) (by grind) + · exact hφ.comp (he''.comp (I.contMDiffOn_symm.mono (by simp)) (by grind)) (by grind) + · exact he'.comp (hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by grind)) (by grind) + +lemma IsManifold.mem_maximalAtlas_iff_contMDiffOn [IsManifold I n M] + (φ : OpenPartialHomeomorph M H) : + φ ∈ maximalAtlas I n M ↔ ContMDiffOn I I n φ φ.source ∧ ContMDiffOn I I n φ.symm φ.target := ⟨fun h ↦ ⟨contMDiffOn_of_mem_maximalAtlas h, contMDiffOn_symm_of_mem_maximalAtlas h⟩, fun ⟨hφ, hφ'⟩ ↦ φ.mem_maximalAtlas_of_contMDiffOn hφ hφ'⟩ From 7c59a0a6cbff267024f1c701907f704c690782fb Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Sun, 12 Jul 2026 11:01:26 +0000 Subject: [PATCH 0736/1300] feat(RingTheory/Ideal): prime avoidance for maximal ideal (#40814) In this PR, we added prime avoidance for maximal ideal. --- Mathlib/RingTheory/Ideal/Operations.lean | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 7017583d9e6b72..52f18f9b67028c 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -1224,6 +1224,16 @@ lemma subset_union_prime_finite {R ι : Type*} [CommRing R] {s : Set ι} rw [hmem_union, Ideal.subset_union_prime a b (fun i hin ↦ hp i ((ht i).mp hin))] exact exists_congr (fun i ↦ and_congr_left fun _ ↦ ht i) +lemma subset_iUnion_iff_mem_of_isMaximal_of_finite + {R : Type*} [CommRing R] {M : Ideal R} [M.IsMaximal] {S : Set (Ideal R)} + (hs : S.Finite) (a b : Ideal R) (hp : ∀ I ∈ S, I ≠ a → I ≠ b → I.IsPrime) + (ha : a ≠ ⊤) (hb : b ≠ ⊤) : ((M : Set R) ⊆ ⋃ I ∈ S, I) ↔ M ∈ S := by + refine (subset_union_prime_finite hs a b hp).trans ⟨fun ⟨I, mem, le⟩ ↦ ?_, (⟨M, ·, le_rfl⟩)⟩ + rwa [‹M.IsMaximal›.eq_of_le _ le] + simp_rw [← or_iff_not_imp_left] at hp + obtain rfl | rfl | hp := hp I mem + exacts [ha, hb, hp.ne_top] + /-- Generalize `Ideal.IsMaximal.exists_inv` to power of maximal ideals. -/ theorem IsMaximal.exists_inv_pow (I : Ideal R) [I.IsMaximal] {x : R} (hx : x ∉ I) (n : ℕ) : ∃ (y : R), ∃ i ∈ I ^ n, y * x + i = 1 := by From 9de183cf4048aa3d2198571106af8d53ac8ff4fd Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Sun, 12 Jul 2026 11:31:05 +0000 Subject: [PATCH 0737/1300] chore: fix nsmul and zsmul non-reducible diamond in SplittingField (#40708) Co-authored-by: sgouezel --- Mathlib/FieldTheory/SplittingField/Construction.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/FieldTheory/SplittingField/Construction.lean b/Mathlib/FieldTheory/SplittingField/Construction.lean index 0de98488d220dd..4afc0022f93020 100644 --- a/Mathlib/FieldTheory/SplittingField/Construction.lean +++ b/Mathlib/FieldTheory/SplittingField/Construction.lean @@ -214,7 +214,7 @@ end SplittingFieldAux def SplittingField (f : K[X]) := MvPolynomial (SplittingFieldAux f.natDegree f) K ⧸ RingHom.ker (MvPolynomial.aeval (R := K) id).toRingHom -deriving Inhabited, CommRing +deriving Inhabited namespace SplittingField @@ -223,6 +223,8 @@ variable (f : K[X]) variable {S : Type*} [DistribSMul S K] [IsScalarTower S K K] in deriving instance SMul S for SplittingField f +instance : CommRing (SplittingField f) := inferInstanceAs <| CommRing (_ ⧸ _) + variable {R : Type*} [CommSemiring R] [Algebra R K] in deriving instance Algebra R, IsScalarTower R K for SplittingField f From 6ee55367d7ab04d9a9d24751d6b493b7e023e27d Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Sun, 12 Jul 2026 11:31:07 +0000 Subject: [PATCH 0738/1300] feat(Algebra/GroupWithZero): prove that `Is{Left,Right}CancelMulZero` is Dedekind-finite (#41453) Co-authored-by: NoahW314 --- Mathlib/Algebra/GroupWithZero/Basic.lean | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Mathlib/Algebra/GroupWithZero/Basic.lean b/Mathlib/Algebra/GroupWithZero/Basic.lean index a6ce83d77a3f5c..cd2d00c15c8442 100644 --- a/Mathlib/Algebra/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Basic.lean @@ -325,6 +325,22 @@ theorem eq_zero_of_mul_eq_self_left [IsRightCancelMulZero M₀] (h₁ : b ≠ 1) a = 0 := Classical.byContradiction fun ha => h₁ <| mul_right_cancel₀ ha <| h₂.symm ▸ (one_mul a).symm +variable {M₀ : Type*} [MonoidWithZero M₀] + +instance (priority := 100) [IsLeftCancelMulZero M₀] : IsDedekindFiniteMonoid M₀ where + mul_eq_one_symm h := by + cases subsingleton_or_nontrivial M₀ + · exact Subsingleton.elim _ _ + exact (IsLeftCancelMulZero.mul_left_cancel_of_ne_zero + (left_ne_zero_of_mul_eq_one h)).mul_eq_one_symm h + +instance (priority := 100) [IsRightCancelMulZero M₀] : IsDedekindFiniteMonoid M₀ where + mul_eq_one_symm h := by + cases subsingleton_or_nontrivial M₀ + · exact Subsingleton.elim _ _ + exact (IsRightCancelMulZero.mul_right_cancel_of_ne_zero + (right_ne_zero_of_mul_eq_one h)).mul_eq_one_symm h + end CancelMonoidWithZero section GroupWithZero From c0cbc05a6f61999c6e6e8afdcbbe0b3daff95a27 Mon Sep 17 00:00:00 2001 From: Scott Carnahan <128885296+ScottCarnahan@users.noreply.github.com> Date: Sun, 12 Jul 2026 11:31:09 +0000 Subject: [PATCH 0739/1300] chore(LinearAlgebra/TensorProduct/Map): add symm_lTensor and symm_rTensor (#41550) This PR adds 2 simp lemmas about pulling an equivalence through a tensor product of modules, and deprecates 4 simp lemmas that become solvable by simp. --- Mathlib/LinearAlgebra/TensorProduct/Map.lean | 16 ++++++++++++---- Mathlib/RingTheory/Coalgebra/CoassocSimps.lean | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Map.lean b/Mathlib/LinearAlgebra/TensorProduct/Map.lean index c2f23fa7984d96..ac9e7ae0a5aafc 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Map.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Map.lean @@ -595,21 +595,29 @@ def rTensor (f : N ≃ₗ[R] P) : N ⊗[R] M ≃ₗ[R] P ⊗[R] M := TensorProdu variable (g : P ≃ₗ[R] Q) (f : N ≃ₗ[R] P) (m : M) (n : N) (p : P) (x : M ⊗[R] N) (y : N ⊗[R] M) +@[simp] theorem symm_lTensor : (f.lTensor M).symm = f.symm.lTensor M := rfl + +@[simp] theorem symm_rTensor : (f.rTensor M).symm = f.symm.rTensor M := rfl + @[simp] theorem coe_lTensor : lTensor M f = (f : N →ₗ[R] P).lTensor M := rfl -@[simp] theorem coe_lTensor_symm : (lTensor M f).symm = (f.symm : P →ₗ[R] N).lTensor M := rfl +@[deprecated "use symm_lTensor and coe_lTensor" (since := "2026-07-04")] +theorem coe_lTensor_symm : (lTensor M f).symm = (f.symm : P →ₗ[R] N).lTensor M := rfl @[simp] theorem coe_rTensor : rTensor M f = (f : N →ₗ[R] P).rTensor M := rfl -@[simp] theorem coe_rTensor_symm : (rTensor M f).symm = (f.symm : P →ₗ[R] N).rTensor M := rfl +@[deprecated "use symm_rTensor and coe_rTensor" (since := "2026-07-04")] +theorem coe_rTensor_symm : (rTensor M f).symm = (f.symm : P →ₗ[R] N).rTensor M := rfl @[simp] theorem lTensor_tmul : f.lTensor M (m ⊗ₜ n) = m ⊗ₜ f n := rfl -@[simp] theorem lTensor_symm_tmul : (f.lTensor M).symm (m ⊗ₜ p) = m ⊗ₜ f.symm p := rfl +@[deprecated "use symm_lTensor and lTensor_tmul" (since := "2026-07-04")] +theorem lTensor_symm_tmul : (f.lTensor M).symm (m ⊗ₜ p) = m ⊗ₜ f.symm p := rfl @[simp] theorem rTensor_tmul : f.rTensor M (n ⊗ₜ m) = f n ⊗ₜ m := rfl -@[simp] theorem rTensor_symm_tmul : (f.rTensor M).symm (p ⊗ₜ m) = f.symm p ⊗ₜ m := rfl +@[deprecated "use symm_rTensor and rTensor_tmul" (since := "2026-07-04")] +theorem rTensor_symm_tmul : (f.rTensor M).symm (p ⊗ₜ m) = f.symm p ⊗ₜ m := rfl lemma comm_trans_rTensor_trans_comm_eq (g : N ≃ₗ[R] P) : TensorProduct.comm R Q N ≪≫ₗ rTensor Q g ≪≫ₗ TensorProduct.comm R P Q = lTensor Q g := diff --git a/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean b/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean index 433e94131ac863..5b185e6f6f3b53 100644 --- a/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean +++ b/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean @@ -73,8 +73,8 @@ attribute [coassoc_simps] LinearMap.comp_id LinearMap.id_comp TensorProduct.map_ LinearEquiv.coe_trans LinearEquiv.trans_symm LinearEquiv.refl_toLinearMap TensorProduct.toLinearMap_congr LinearEquiv.comp_symm LinearEquiv.symm_comp LinearEquiv.symm_symm - LinearEquiv.coe_lTensor LinearEquiv.coe_lTensor_symm - LinearEquiv.coe_rTensor LinearEquiv.coe_rTensor_symm + LinearEquiv.coe_lTensor LinearEquiv.symm_lTensor + LinearEquiv.coe_rTensor LinearEquiv.symm_rTensor IsCocomm.comm_comp_comul TensorProduct.AlgebraTensorModule.map_eq TensorProduct.AlgebraTensorModule.assoc_eq TensorProduct.AlgebraTensorModule.rightComm_eq TensorProduct.tensorTensorTensorComm TensorProduct.AlgebraTensorModule.tensorTensorTensorComm From 2800ac2bd3c2653f48647df6cb15b22c6e6e5039 Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Sun, 12 Jul 2026 11:31:11 +0000 Subject: [PATCH 0740/1300] chore(RingTheory/Polynomial/Basic): remove unused `haveI` and defeq abuse (#41608) --- Mathlib/RingTheory/Polynomial/Basic.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index bc3e957ea17a99..ac7a2baaabd417 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -772,7 +772,6 @@ end MvPolynomial end Prime -set_option backward.isDefEq.respectTransparency false in /-- **Hilbert basis theorem**: a polynomial ring over a Noetherian ring is a Noetherian ring. -/ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNoetherianRing R[X] := isNoetherianRing_iff.2 @@ -784,7 +783,6 @@ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNo have hm2 : ∀ k, I.leadingCoeffNth k ≤ M := fun k => Or.casesOn (le_or_gt k N) (fun h => HN ▸ I.leadingCoeffNth_mono h) fun h _ hx => Classical.by_contradiction fun hxm => - haveI : IsNoetherian R R := inst have : ¬M < I.leadingCoeffNth k := by refine WellFounded.not_lt_min inst.wf _ ?_; exact ⟨k, rfl⟩ this ⟨HN ▸ I.leadingCoeffNth_mono (le_of_lt h), fun H => hxm (H hx)⟩ From bd2f30dcd35b91fe8cf67d333de797947f6173e2 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:24:34 +0000 Subject: [PATCH 0741/1300] chore: update Mathlib dependencies 2026-07-12 (#41650) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index c81997e983eaca..e2a6b55352e02d 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9647daaa8c0bc688fcfcb04252c864b859b51f57", + "rev": "dfb6d7e9949d1bb0706f651e330176bc66fc6f3d", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 30ff0d59c48647f4d2f88c55fe92696464019c50 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Sun, 12 Jul 2026 16:04:28 +0000 Subject: [PATCH 0742/1300] fix(Util/AddRelatedDecl): error instead of panicking when the target declaration already exists (#41422) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If `addRelatedDecl` is asked to create a declaration that already exists in an imported module, the `addDeclarationRangesFromSyntax` call panics with `cannot insert ... into Lean.declRangeExt, it is not defined in the current module` (aborting the build with no usable diagnostic); a duplicate in the current module only failed later at `addDecl`. Check up front and throw a clear error naming the module that already declares the target. This was hit when `shake --fix` added `import Mathlib.CategoryTheory.ConcreteCategory.Elementwise` to `Mathlib/CategoryTheory/Limits/Types/{Limits,Colimits}.lean` in #40343 (and previous iterations). Zulip: [#mathlib4 > shake --fix causes elementwise to panic](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/shake.20--fix.20causes.20elementwise.20to.20panic/with/601797502) --- Mathlib/Util/AddRelatedDecl.lean | 6 ++++++ MathlibTest/CategoryTheory/Elementwise.lean | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Mathlib/Util/AddRelatedDecl.lean b/Mathlib/Util/AddRelatedDecl.lean index 83e3108d0cdc62..456f300be06a66 100644 --- a/Mathlib/Util/AddRelatedDecl.lean +++ b/Mathlib/Util/AddRelatedDecl.lean @@ -34,6 +34,8 @@ and has been factored out to avoid code duplication. Feel free to add features as needed for other applications. This helper: +* throws an error if a declaration named `tgt` already exists + (in the current module or in an imported one), * calls `addDeclarationRangesFromSyntax`, so jump-to-definition works, * copies the `protected` status of the existing declaration, and * supports copying attributes. @@ -64,6 +66,10 @@ def addRelatedDecl (src tgt : Name) (ref : Syntax) (docstringPrefix? : Option String := none) (hoverInfo : Bool := false) : MetaM Unit := do + -- If `tgt` already exists in an imported module, the `addDeclarationRangesFromSyntax` call + -- below panics (and if it exists in the current module, `addDecl` would fail with a less + -- helpful message), so we check for a pre-existing declaration up front. + checkNotAlreadyDeclared tgt addDeclarationRangesFromSyntax tgt (← getRef) ref let info ← withoutExporting <| getConstInfo src let value := .const src (info.levelParams.map mkLevelParam) diff --git a/MathlibTest/CategoryTheory/Elementwise.lean b/MathlibTest/CategoryTheory/Elementwise.lean index e9eb6a83ec50d1..0547e9afae5e4f 100644 --- a/MathlibTest/CategoryTheory/Elementwise.lean +++ b/MathlibTest/CategoryTheory/Elementwise.lean @@ -1,5 +1,6 @@ import Mathlib.Tactic.CategoryTheory.Elementwise import Mathlib.Algebra.Category.MonCat.Basic +import Mathlib.CategoryTheory.ConcreteCategory.Elementwise set_option autoImplicit true @@ -232,4 +233,19 @@ example {α β : Type} (f g : α ⟶ β) (w : f ≫ 𝟙 β = g) (a : α) : f a end ConcreteCategory +section AlreadyDeclared + +open CategoryTheory.Limits + +-- Regression test: regenerating an `_apply` lemma that was already generated in an imported +-- module (here `Mathlib.CategoryTheory.ConcreteCategory.Elementwise`) must error via +-- `checkNotAlreadyDeclared` instead of panicking in `addDeclarationRangesFromSyntax`. +/-- +error: `CategoryTheory.Limits.limit.w_apply` has already been declared +-/ +#guard_msgs in +attribute [elementwise] limit.w + +end AlreadyDeclared + end ElementwiseTest From eb3af393c9d32e9d57fef7aeff7bd266e5ed1d7c Mon Sep 17 00:00:00 2001 From: damiano Date: Sun, 12 Jul 2026 19:09:47 +0000 Subject: [PATCH 0743/1300] chore: add missing `to_additive` docstrings in MeasureTheory.Measure (#41638) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing additive doc-strings (multiplicative side has a hand-written doc-string, additive side did not) across 6 file(s) in **MeasureTheory.Measure**. The additive doc-strings are simple-minded translations of the multiplicative ones, with referenced lemma names replaced by their `to_additive` counterparts. These gaps were found by an environment linter that pairs each declaration with its `to_additive` counterpart and checks that both or neither is documented. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- .../Constructions/Polish/Basic.lean | 7 ++- .../Function/StronglyMeasurable/Basic.lean | 5 ++- .../MeasureTheory/Measure/EverywherePos.lean | 11 ++++- Mathlib/MeasureTheory/Measure/Haar/Basic.lean | 3 +- .../MeasureTheory/Measure/Haar/Quotient.lean | 7 ++- .../MeasureTheory/Measure/Haar/Unique.lean | 44 ++++++++++++++----- 6 files changed, 59 insertions(+), 18 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index c1c595f7b275db..d571c9ee50a733 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -633,7 +633,12 @@ to `QuotientGroup` (the next `instance`). TODO: typeclass inference should normally find this, but currently doesn't. E.g., `MeasurableSMul G (G ⧸ Γ)` fails to synthesize, even though `G ⧸ Γ` is the quotient of `G` by the action of `Γ`; it seems unable to pick up the `BorelSpace` instance. -/ -@[to_additive AddCosetSpace.borelSpace] +@[to_additive AddCosetSpace.borelSpace + /-- When the additive subgroup `N < G` is not necessarily `Normal`, we have an `AddCosetSpace` as +opposed to `QuotientAddGroup` (the next `instance`). +TODO: typeclass inference should normally find this, but currently doesn't. +E.g., `MeasurableVAdd G (G ⧸ Γ)` fails to synthesize, even though `G ⧸ Γ` is the quotient +of `G` by the action of `Γ`; it seems unable to pick up the `BorelSpace` instance. -/] instance CosetSpace.borelSpace {G : Type*} [TopologicalSpace G] [PolishSpace G] [Group G] [MeasurableSpace G] [BorelSpace G] {N : Subgroup G} [T2Space (G ⧸ N)] [SecondCountableTopology (G ⧸ N)] : BorelSpace (G ⧸ N) := Quotient.borelSpace diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index c47967b096d8d8..3258e70d0b2e8f 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -726,7 +726,8 @@ theorem _root_.Continuous.stronglyMeasurable [MeasurableSpace α] [TopologicalSp · exact hf.measurable.stronglyMeasurable /-- A continuous function whose support is contained in a compact set is strongly measurable. -/ -@[to_additive] +@[to_additive /-- A continuous function whose support is contained in a compact set is strongly +measurable. -/] theorem _root_.Continuous.stronglyMeasurable_of_mulSupport_subset_isCompact [MeasurableSpace α] [TopologicalSpace α] [OpensMeasurableSpace α] [TopologicalSpace β] [PseudoMetrizableSpace β] [One β] {f : α → β} (hf : Continuous f) {k : Set α} @@ -737,7 +738,7 @@ theorem _root_.Continuous.stronglyMeasurable_of_mulSupport_subset_isCompact exact ⟨hf.measurable, (isCompact_range_of_mulSupport_subset_isCompact hf hk h'f).isSeparable⟩ /-- A continuous function with compact support is strongly measurable. -/ -@[to_additive] +@[to_additive /-- A continuous function with compact support is strongly measurable. -/] theorem _root_.Continuous.stronglyMeasurable_of_hasCompactMulSupport [MeasurableSpace α] [TopologicalSpace α] [OpensMeasurableSpace α] [TopologicalSpace β] [PseudoMetrizableSpace β] [One β] {f : α → β} (hf : Continuous f) diff --git a/Mathlib/MeasureTheory/Measure/EverywherePos.lean b/Mathlib/MeasureTheory/Measure/EverywherePos.lean index b3083c19e3a419..e0c8061995c45e 100644 --- a/Mathlib/MeasureTheory/Measure/EverywherePos.lean +++ b/Mathlib/MeasureTheory/Measure/EverywherePos.lean @@ -216,7 +216,11 @@ open scoped Pointwise topological group, then it is a Gδ set. This is nontrivial, as there is no second-countability or metrizability assumption in the statement, so a general compact closed set has no reason to be a countable intersection of open sets. -/ -@[to_additive] +@[to_additive +/-- If a compact closed set is everywhere positive with respect to a left-invariant measure on a +topological additive group, then it is a Gδ set. This is nontrivial, as there is no +second-countability or metrizability assumption in the statement, so a general compact closed set +has no reason to be a countable intersection of open sets. -/] lemma IsEverywherePos.IsGdelta_of_isMulLeftInvariant {k : Set G} (h : μ.IsEverywherePos k) (hk : IsCompact k) (h'k : IsClosed k) : IsGδ k := by @@ -275,7 +279,10 @@ lemma IsEverywherePos.IsGdelta_of_isMulLeftInvariant /-- **Halmos' theorem: Haar measure is completion regular.** More precisely, any finite measure set can be approximated from inside by a level set of a continuous function with compact support. -/ -@[to_additive innerRegularWRT_preimage_one_hasCompactSupport_measure_ne_top_of_addGroup] +@[to_additive innerRegularWRT_preimage_one_hasCompactSupport_measure_ne_top_of_addGroup +/-- **Halmos' theorem: Haar measure is completion regular.** More precisely, any finite measure +set can be approximated from inside by a level set of a continuous function with compact +support. -/] theorem innerRegularWRT_preimage_one_hasCompactSupport_measure_ne_top_of_group : InnerRegularWRT μ (fun s ↦ ∃ (f : G → ℝ), Continuous f ∧ HasCompactSupport f ∧ s = f ⁻¹' {1}) (fun s ↦ MeasurableSet s ∧ μ s ≠ ∞) := by diff --git a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean index 0d5daf17221d2e..43a481127a239a 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean @@ -673,7 +673,8 @@ theorem haarMeasure_unique (μ : Measure G) [SigmaFinite μ] [IsMulLeftInvariant /-- Let `μ` be a σ-finite left invariant measure on `G`. Then `μ` is equal to the Haar measure defined by `K₀` iff `μ K₀ = 1`. -/ -@[to_additive] +@[to_additive /-- Let `μ` be a σ-finite left invariant measure on `G`. Then `μ` is equal to the +additive Haar measure defined by `K₀` iff `μ K₀ = 1`. -/] theorem haarMeasure_eq_iff (K₀ : PositiveCompacts G) (μ : Measure G) [SigmaFinite μ] [IsMulLeftInvariant μ] : haarMeasure K₀ = μ ↔ μ K₀ = 1 := diff --git a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean index 568e8541bf3d58..02bd9b10e08766 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean @@ -69,7 +69,9 @@ variable {G : Type*} [Group G] [MeasurableSpace G] (ν : Measure G) {Γ : Subgro /-- Given a subgroup `Γ` of a topological group `G` with measure `ν`, and a measure 'μ' on the quotient `G ⧸ Γ` satisfying `QuotientMeasureEqMeasurePreimage`, the restriction of `ν` to a fundamental domain is measure-preserving with respect to `μ`. -/ -@[to_additive] +@[to_additive /-- Given a subgroup `Γ` of a topological additive group `G` with measure `ν`, and a + measure 'μ' on the quotient `G ⧸ Γ` satisfying `AddQuotientMeasureEqMeasurePreimage`, the + restriction of `ν` to a fundamental domain is measure-preserving with respect to `μ`. -/] theorem measurePreserving_quotientGroup_mk_of_QuotientMeasureEqMeasurePreimage {𝓕 : Set G} (h𝓕 : IsFundamentalDomain Γ.op 𝓕 ν) (μ : Measure (G ⧸ Γ)) [QuotientMeasureEqMeasurePreimage ν μ] : @@ -83,7 +85,8 @@ variable [TopologicalSpace G] [IsTopologicalGroup G] [BorelSpace G] [PolishSpace /-- If `μ` satisfies `QuotientMeasureEqMeasurePreimage` relative to a both left- and right- invariant measure `ν` on `G`, then it is a `G` invariant measure on `G ⧸ Γ`. -/ -@[to_additive] +@[to_additive /-- If `μ` satisfies `AddQuotientMeasureEqMeasurePreimage` relative to a both left- + and right-invariant measure `ν` on `G`, then it is a `G` invariant measure on `G ⧸ Γ`. -/] lemma MeasureTheory.QuotientMeasureEqMeasurePreimage.smulInvariantMeasure_quotient [IsMulLeftInvariant ν] [hasFun : HasFundamentalDomain Γ.op G ν] : SMulInvariantMeasure G (G ⧸ Γ) μ where diff --git a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean index dd3a0f69aaeb57..870fefd7dbc122 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean @@ -74,7 +74,9 @@ namespace MeasureTheory /-- The parameterized integral `x ↦ ∫ y, g (y⁻¹ * x) ∂μ` depends continuously on `y` when `g` is a compactly supported continuous function on a topological group `G`, and `μ` is finite on compact sets. -/ -@[to_additive] +@[to_additive /-- The parameterized integral `x ↦ ∫ y, g (-y + x) ∂μ` depends continuously on `y` +when `g` is a compactly supported continuous function on a topological additive group `G`, and `μ` +is finite on compact sets. -/] lemma continuous_integral_apply_inv_mul {G : Type*} [TopologicalSpace G] [LocallyCompactSpace G] [Group G] [IsTopologicalGroup G] [MeasurableSpace G] [BorelSpace G] @@ -120,7 +122,10 @@ measures will give the same integral, up to some fixed scalar. integrals with respect to `μ` as integrals with respect to `ν` up to a constant scaling factor (given in the statement as `∫ x, g x ∂μ` where `g` is a fixed reference function) and an explicit density `y ↦ 1/∫ z, g (z⁻¹ * y) ∂ν`. -/ -@[to_additive] +@[to_additive /-- In an additive group with a left invariant measure `μ` and a right invariant +measure `ν`, one can express integrals with respect to `μ` as integrals with respect to `ν` up to a +constant scaling factor (given in the statement as `∫ x, g x ∂μ` where `g` is a fixed reference +function) and an explicit density `y ↦ 1/∫ z, g (-z + y) ∂ν`. -/] lemma integral_isMulLeftInvariant_isMulRightInvariant_combo {μ ν : Measure G} [IsFiniteMeasureOnCompacts μ] [IsFiniteMeasureOnCompacts ν] [IsMulLeftInvariant μ] [IsMulRightInvariant ν] [IsOpenPosMeasure ν] @@ -214,7 +219,10 @@ lemma integral_isMulLeftInvariant_isMulRightInvariant_combo /-- Given two left-invariant measures which are finite on compacts, they coincide in the following sense: they give the same value to the integral of continuous compactly supported functions, up to a multiplicative constant. -/ -@[to_additive exists_integral_isAddLeftInvariant_eq_smul_of_hasCompactSupport] +@[to_additive exists_integral_isAddLeftInvariant_eq_smul_of_hasCompactSupport +/-- Given two left-invariant measures which are finite on +compacts, they coincide in the following sense: they give the same value to the integral of +continuous compactly supported functions, up to a multiplicative constant. -/] lemma exists_integral_isMulLeftInvariant_eq_smul_of_hasCompactSupport (μ' μ : Measure G) [IsHaarMeasure μ] [IsFiniteMeasureOnCompacts μ'] [IsMulLeftInvariant μ'] : ∃ (c : ℝ≥0), ∀ (f : G → ℝ), Continuous f → HasCompactSupport f → @@ -409,7 +417,8 @@ lemma haarScalarFactor_map (μ' μ : Measure G) [IsHaarMeasure μ] [IsHaarMeasur /-- The scalar factor between two left-invariant measures is non-zero when both measures are positive on open sets. -/ -@[to_additive] +@[to_additive /-- The scalar factor between two left-invariant measures is non-zero when both +measures are positive on open sets. -/] lemma haarScalarFactor_pos_of_isHaarMeasure (μ' μ : Measure G) [IsHaarMeasure μ] [IsHaarMeasure μ'] : 0 < haarScalarFactor μ' μ := pos_iff_ne_zero.2 (fun H ↦ by simpa [H] using haarScalarFactor_eq_mul μ' μ μ') @@ -661,7 +670,9 @@ theorem measure_isMulInvariant_eq_smul_of_isCompact_closure [LocallyCompactSpace /-- **Uniqueness of Haar measures**: Two Haar measures on a compact group coincide up to a multiplicative factor. -/ -@[to_additive isAddInvariant_eq_smul_of_compactSpace] +@[to_additive isAddInvariant_eq_smul_of_compactSpace +/-- **Uniqueness of additive Haar measures**: +Two additive Haar measures on a compact additive group coincide up to a multiplicative factor. -/] lemma isMulInvariant_eq_smul_of_compactSpace [CompactSpace G] (μ' μ : Measure G) [IsHaarMeasure μ] [IsMulLeftInvariant μ'] [IsFiniteMeasureOnCompacts μ'] : μ' = haarScalarFactor μ' μ • μ := by @@ -684,7 +695,8 @@ instance (priority := 100) instRegularOfIsHaarMeasureOfCompactSpace /-- **Uniqueness of Haar measures**: Two Haar measures which are probability measures coincide. -/ -@[to_additive] +@[to_additive /-- **Uniqueness of additive Haar measures**: +Two additive Haar measures which are probability measures coincide. -/] lemma isHaarMeasure_eq_of_isProbabilityMeasure [LocallyCompactSpace G] (μ' μ : Measure G) [IsProbabilityMeasure μ] [IsProbabilityMeasure μ'] [IsHaarMeasure μ] [IsHaarMeasure μ'] : μ' = μ := by @@ -828,7 +840,11 @@ Given two left-invariant measures which are finite on compacts and inner regular for finite measure sets with respect to compact sets, they coincide in the following sense: they give the same value to finite measure sets, up to a multiplicative constant. -/ -@[to_additive] +@[to_additive /-- **Uniqueness of left-invariant measures**: +Given two left-invariant measures which are finite on +compacts and inner regular for finite measure sets with respect to compact sets, +they coincide in the following sense: they give the same value to finite measure sets, +up to a multiplicative constant. -/] lemma measure_isMulLeftInvariant_eq_smul_of_ne_top [LocallyCompactSpace G] (μ' μ : Measure G) [IsHaarMeasure μ] [IsFiniteMeasureOnCompacts μ'] [IsMulLeftInvariant μ'] [InnerRegularCompactLTTop μ] [InnerRegularCompactLTTop μ'] {s : Set G} @@ -866,7 +882,10 @@ lemma measure_isMulLeftInvariant_eq_smul_of_ne_top [LocallyCompactSpace G] /-- **Uniqueness of left-invariant measures**: Given two left-invariant measures which are finite on compacts and inner regular, they coincide up to a multiplicative constant. -/ -@[to_additive isAddLeftInvariant_eq_smul_of_innerRegular] +@[to_additive isAddLeftInvariant_eq_smul_of_innerRegular +/-- **Uniqueness of left-invariant measures**: +Given two left-invariant measures which are finite +on compacts and inner regular, they coincide up to a multiplicative constant. -/] lemma isMulLeftInvariant_eq_smul_of_innerRegular [LocallyCompactSpace G] (μ' μ : Measure G) [IsHaarMeasure μ] [IsFiniteMeasureOnCompacts μ'] [IsMulLeftInvariant μ'] [InnerRegular μ] [InnerRegular μ'] : @@ -880,7 +899,10 @@ lemma isMulLeftInvariant_eq_smul_of_innerRegular [LocallyCompactSpace G] /-- **Uniqueness of left-invariant measures**: Given two left-invariant measures which are finite on compacts and regular, they coincide up to a multiplicative constant. -/ -@[to_additive isAddLeftInvariant_eq_smul_of_regular] +@[to_additive isAddLeftInvariant_eq_smul_of_regular +/-- **Uniqueness of left-invariant measures**: +Given two left-invariant measures which are finite +on compacts and regular, they coincide up to a multiplicative constant. -/] lemma isMulLeftInvariant_eq_smul_of_regular [LocallyCompactSpace G] (μ' μ : Measure G) [IsHaarMeasure μ] [IsMulLeftInvariant μ'] [Regular μ] [Regular μ'] : μ' = haarScalarFactor μ' μ • μ := by @@ -894,7 +916,9 @@ lemma isMulLeftInvariant_eq_smul_of_regular [LocallyCompactSpace G] /-- **Uniqueness of left-invariant measures**: Two Haar measures coincide up to a multiplicative constant in a second countable group. -/ -@[to_additive isAddLeftInvariant_eq_smul] +@[to_additive isAddLeftInvariant_eq_smul +/-- **Uniqueness of left-invariant measures**: +Two additive Haar measures coincide up to a multiplicative constant in a second countable group. -/] lemma isMulLeftInvariant_eq_smul [LocallyCompactSpace G] [SecondCountableTopology G] (μ' μ : Measure G) [IsHaarMeasure μ] [IsFiniteMeasureOnCompacts μ'] [IsMulLeftInvariant μ'] : μ' = haarScalarFactor μ' μ • μ := From f34e762642b3470574f0117a100a8fc4eaeae651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Sun, 12 Jul 2026 20:38:57 +0000 Subject: [PATCH 0744/1300] feat(Topology/Sets): disjoint `Compacts` form an open set (#40053) --- Mathlib/Topology/Sets/Compacts.lean | 9 +++++++++ Mathlib/Topology/Sets/VietorisTopology.lean | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Mathlib/Topology/Sets/Compacts.lean b/Mathlib/Topology/Sets/Compacts.lean index 358da018fa882e..eacdaf95b8ae77 100644 --- a/Mathlib/Topology/Sets/Compacts.lean +++ b/Mathlib/Topology/Sets/Compacts.lean @@ -166,6 +166,15 @@ theorem singleton_injective : Function.Injective ({·} : α → Compacts α) := theorem singleton_inj {x y : α} : ({x} : Compacts α) = {y} ↔ x = y := singleton_injective.eq_iff +theorem disjoint_coe_iff (K L : Compacts α) : Disjoint (K : Set α) L ↔ Disjoint K L where + mp h := .of_orderEmbedding (.ofMapLEIff SetLike.coe (fun _ _ => SetLike.coe_subset_coe)) h + mpr h := by + rw [Set.disjoint_iff] + intro x ⟨hxK, hxL⟩ + specialize @h {x} + simp_rw [← SetLike.coe_subset_coe, coe_singleton, singleton_subset_iff] at h + exact h hxK hxL + instance [Nonempty α] : Nontrivial (Compacts α) := by constructor obtain ⟨x⟩ := ‹Nonempty α› diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index 812e1615152237..b2feab21cf604d 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -369,6 +369,19 @@ theorem isClopen_singleton_bot : IsClopen {(⊥ : Compacts α)} := by convert! vietoris.isClopen_singleton_empty.preimage continuous_coe rw [← coe_bot, ← image_singleton (f := SetLike.coe), SetLike.coe_injective.preimage_image] +theorem isOpen_setOf_disjoint_coe [T2Space α] : + IsOpen {p : Compacts α × Compacts α | Disjoint (p.1 : Set α) p.2} := by + rw [isOpen_iff_forall_mem_open] + intro ⟨K, L⟩ hKL + obtain ⟨U, V, hU, hV, hKU, hLV, hUV⟩ := + SeparatedNhds.of_isCompact_isCompact K.isCompact L.isCompact hKL + exact ⟨{K' : Compacts α | ↑K' ⊆ U} ×ˢ {L' : Compacts α | ↑L' ⊆ V}, by grind, + (isOpen_subsets_of_isOpen hU).prod (isOpen_subsets_of_isOpen hV), hKU, hLV⟩ + +theorem isOpen_setOf_disjoint [T2Space α] : + IsOpen {p : Compacts α × Compacts α | Disjoint p.1 p.2} := by + simpa only [disjoint_coe_iff] using isOpen_setOf_disjoint_coe + theorem closure_finite_subsets (s : Set α) : closure {K : Compacts α | (K : Set α).Finite ∧ ↑K ⊆ s} = {K : Compacts α | ↑K ⊆ closure s} := by change closure (SetLike.coe ⁻¹' {K : Set α | K.Finite ∧ K ⊆ s}) = @@ -702,6 +715,10 @@ theorem isClosed_inter_nonempty_of_isClosed {F : Set α} (h : IsClosed F) : IsClosed {K : NonemptyCompacts α | (↑K ∩ F).Nonempty} := (vietoris.isClosed_inter_nonempty_of_isClosed h).preimage continuous_coe +theorem isOpen_setOf_disjoint_coe [T2Space α] : + IsOpen {p : NonemptyCompacts α × NonemptyCompacts α | Disjoint (p.1 : Set α) p.2} := + Compacts.isOpen_setOf_disjoint_coe.preimage <| continuous_toCompacts.prodMap continuous_toCompacts + theorem closure_finite_subsets (s : Set α) : closure {K : NonemptyCompacts α | (K : Set α).Finite ∧ ↑K ⊆ s} = {K : NonemptyCompacts α | ↑K ⊆ closure s} := by From 46931f419bdd637d3b9db8c6232646f21fb519c4 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Mon, 13 Jul 2026 01:22:45 +0000 Subject: [PATCH 0745/1300] feat: function composition preserves boundedness (#33126) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds the following theorem: if the range of a function `g` is bounded above, then `g ∘ f` is bounded above for all functions `f`. Co-authored-by: Yongxi Lin --- Mathlib/Algebra/Order/Group/Pointwise/Bounds.lean | 4 ++-- Mathlib/Algebra/Order/GroupWithZero/Bounds.lean | 4 ++-- Mathlib/Order/Bounds/Basic.lean | 8 ++++++++ Mathlib/Order/Bounds/Image.lean | 8 +++++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Order/Group/Pointwise/Bounds.lean b/Mathlib/Algebra/Order/Group/Pointwise/Bounds.lean index d9d653c008cd2a..a465892cbc546c 100644 --- a/Mathlib/Algebra/Order/Group/Pointwise/Bounds.lean +++ b/Mathlib/Algebra/Order/Group/Pointwise/Bounds.lean @@ -58,7 +58,7 @@ lemma BddBelow.mul (hs : BddBelow s) (ht : BddBelow t) : BddBelow (s * t) := @[to_additive] lemma BddAbove.range_mul (hf : BddAbove (range f)) (hg : BddAbove (range g)) : BddAbove (range fun i ↦ f i * g i) := - .range_comp (f := fun i ↦ (f i, g i)) (bddAbove_range_prod.2 ⟨hf, hg⟩) + .range_comp_left (f := fun i ↦ (f i, g i)) (bddAbove_range_prod.2 ⟨hf, hg⟩) (monotone_fst.mul' monotone_snd) @[to_additive] @@ -114,7 +114,7 @@ theorem IsLUB.inv (h : IsLUB s a) : IsGLB s⁻¹ a⁻¹ := @[to_additive] lemma BddBelow.range_inv {α : Type*} {f : α → G} (hf : BddBelow (range f)) : BddAbove (range (fun x => (f x)⁻¹)) := - hf.range_comp (OrderIso.inv G).monotone + hf.range_comp_left (OrderIso.inv G).monotone @[to_additive] lemma BddAbove.range_inv {α : Type*} {f : α → G} (hf : BddAbove (range f)) : diff --git a/Mathlib/Algebra/Order/GroupWithZero/Bounds.lean b/Mathlib/Algebra/Order/GroupWithZero/Bounds.lean index 332d14f56f258c..262c46180e14e3 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Bounds.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Bounds.lean @@ -17,8 +17,8 @@ public section open Set -/-- A variant of `BddAbove.range_comp` that assumes that `f` is nonnegative and `g` is monotone on - nonnegative values. -/ +/-- A variant of `BddAbove.range_comp_left` that assumes that `f` is nonnegative and `g` is monotone +on nonnegative values. -/ lemma BddAbove.range_comp_of_nonneg {α β γ : Type*} [Nonempty α] [Preorder β] [Zero β] [Preorder γ] {f : α → β} {g : β → γ} (hf : BddAbove (range f)) (hf0 : 0 ≤ f) (hg : MonotoneOn g {x : β | 0 ≤ x}) : BddAbove (range (fun x => g (f x))) := by diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index 12fbb67bd29471..c50f1b1e109a3b 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -225,6 +225,14 @@ theorem upperBounds_mono ⦃s t : Set α⦄ (hst : s ⊆ t) ⦃a b⦄ (hab : a theorem BddAbove.mono ⦃s t : Set α⦄ (h : s ⊆ t) : BddAbove t → BddAbove s := Nonempty.mono <| upperBounds_mono_set h +/-- If the range of a function `g` is bounded above, then `g ∘ f` is bounded above for all functions +`f`. -/ +@[to_dual /-- If the range of a function `g` is bounded below, then `g ∘ f` is bounded below for all +functions `f`. -/] +theorem BddAbove.range_comp_right (f : γ → β) {g : β → α} + (hg : BddAbove (Set.range g)) : BddAbove (Set.range (g ∘ f)) := + hg.mono (range_comp_subset_range f g) + /-- If `a` is a least upper bound for sets `s` and `p`, then it is a least upper bound for any set `t`, `s ⊆ t ⊆ p`. -/ @[to_dual /-- If `a` is a greatest lower bound for sets `s` and `p`, then it is a greater lower diff --git a/Mathlib/Order/Bounds/Image.lean b/Mathlib/Order/Bounds/Image.lean index d019ab9910b1a5..85a84b61bdf40d 100644 --- a/Mathlib/Order/Bounds/Image.lean +++ b/Mathlib/Order/Bounds/Image.lean @@ -430,7 +430,13 @@ lemma BddAbove.range_mono [Preorder β] {f : α → β} (g : α → β) (h : ∀ exact (h x).trans (hC <| mem_range_self x) @[to_dual] -lemma BddAbove.range_comp {γ : Type*} [Preorder β] [Preorder γ] {f : α → β} {g : β → γ} +lemma BddAbove.range_comp_left {γ : Type*} [Preorder β] [Preorder γ] {f : α → β} {g : β → γ} (hf : BddAbove (range f)) (hg : Monotone g) : BddAbove (range (fun x => g (f x))) := by change BddAbove (range (g ∘ f)) simpa only [Set.range_comp] using hg.map_bddAbove hf + +@[deprecated BddAbove.range_comp_left (since := "2026-06-07")] +alias BddAbove.range_comp := BddAbove.range_comp_left + +@[deprecated BddBelow.range_comp_left (since := "2026-06-07")] +alias BddBelow.range_comp := BddBelow.range_comp_left From 9637cdc63e1714c89e44dbeb8573b755996809ac Mon Sep 17 00:00:00 2001 From: damiano Date: Mon, 13 Jul 2026 06:50:21 +0000 Subject: [PATCH 0746/1300] chore: add missing `to_additive` docstrings in category theory files (#41643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing additive doc-strings (multiplicative side has a hand-written doc-string, additive side did not) across 9 file(s) in **category theory files**. The additive doc-strings are simple-minded translations of the multiplicative ones, with referenced lemma names replaced by their `to_additive` counterparts. These gaps were found by an environment linter that pairs each declaration with its `to_additive` counterpart and checks that both or neither is documented. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Mathlib/Algebra/Category/Grp/Ulift.lean | 4 ++-- Mathlib/Algebra/Category/MonCat/Basic.lean | 3 ++- Mathlib/Algebra/Category/Semigrp/Basic.lean | 3 ++- Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean | 12 ++++++++---- Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean | 4 +++- .../CategoryTheory/Monoidal/Cartesian/Normal.lean | 3 ++- Mathlib/CategoryTheory/Monoidal/Grp.lean | 6 +++++- Mathlib/CategoryTheory/Monoidal/Mod.lean | 3 ++- Mathlib/CategoryTheory/Monoidal/Mon.lean | 5 +++-- 9 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Mathlib/Algebra/Category/Grp/Ulift.lean b/Mathlib/Algebra/Category/Grp/Ulift.lean index c9a99aa76b8d20..b43a1d826553ae 100644 --- a/Mathlib/Algebra/Category/Grp/Ulift.lean +++ b/Mathlib/Algebra/Category/Grp/Ulift.lean @@ -140,12 +140,12 @@ def uliftFunctorFullyFaithful : uliftFunctor.{u, v}.FullyFaithful where map_preimage _ := rfl preimage_map _ := rfl --- The universe lift functor for commutative groups is faithful. -/ +/-- The universe lift functor for commutative groups is faithful. -/ @[to_additive /-- The universe lift functor for commutative additive groups is faithful. -/] instance : uliftFunctor.{u, v}.Faithful := uliftFunctorFullyFaithful.faithful --- The universe lift functor for commutative groups is full. -/ +/-- The universe lift functor for commutative groups is full. -/ @[to_additive /-- The universe lift functor for commutative additive groups is full. -/] instance : uliftFunctor.{u, v}.Full := uliftFunctorFullyFaithful.full diff --git a/Mathlib/Algebra/Category/MonCat/Basic.lean b/Mathlib/Algebra/Category/MonCat/Basic.lean index 42a3b43d3ad6c8..de0d5588f909d1 100644 --- a/Mathlib/Algebra/Category/MonCat/Basic.lean +++ b/Mathlib/Algebra/Category/MonCat/Basic.lean @@ -504,7 +504,8 @@ instance CommMonCat.forget_reflects_isos : (forget CommMonCat.{u}).ReflectsIsomo exact e.toCommMonCatIso.isIso_hom /-- Ensure that `forget₂ CommMonCat MonCat` automatically reflects isomorphisms. -/ -@[to_additive] +@[to_additive + /-- Ensure that `forget₂ AddCommMonCat AddMonCat` automatically reflects isomorphisms. -/] instance CommMonCat.forget₂_full : (forget₂ CommMonCat MonCat).Full where map_surjective f := ⟨ofHom f.hom, rfl⟩ diff --git a/Mathlib/Algebra/Category/Semigrp/Basic.lean b/Mathlib/Algebra/Category/Semigrp/Basic.lean index 6e146186a8c4a1..741701259c9483 100644 --- a/Mathlib/Algebra/Category/Semigrp/Basic.lean +++ b/Mathlib/Algebra/Category/Semigrp/Basic.lean @@ -447,7 +447,8 @@ instance Semigrp.forgetReflectsIsos : (forget Semigrp.{u}).ReflectsIsomorphisms exact e.toSemigrpIso.isIso_hom /-- Ensure that `forget₂ CommMonCat MonCat` automatically reflects isomorphisms. -/ -@[to_additive] +@[to_additive /-- Ensure that `forget₂ AddCommMonCat AddMonCat` automatically reflects +isomorphisms. -/] instance Semigrp.forget₂_full : (forget₂ Semigrp MagmaCat).Full where map_surjective f := ⟨ofHom f.hom, rfl⟩ diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean index 0ebc7b3a240160..369d70592156be 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean @@ -187,7 +187,8 @@ lemma GrpObj.one_inv : η[G] ≫ ι = η := by simp [GrpObj.inv_eq_inv, GrpObj.c open scoped _root_.CategoryTheory.Obj in /-- If `G` is a group object and `F` is monoidal, then `Hom(X, G) → Hom(F X, F G)` preserves inverses. -/ -@[to_additive (attr := simp)] +@[to_additive (attr := simp) /-- If `G` is an additive group object and `F` is monoidal, +then `Hom(X, G) → Hom(F X, F G)` preserves negation. -/] lemma Functor.map_inv' {D : Type*} [Category* D] [CartesianMonoidalCategory D] (F : C ⥤ D) [F.Monoidal] {X G : C} (f : X ⟶ G) [GrpObj G] : F.map (f⁻¹) = (F.map f)⁻¹ := by @@ -270,7 +271,8 @@ lemma hom_pow (f : G ⟶ H) (n : ℕ) : (f ^ n).hom = f.hom ^ n := by end Hom /-- A commutative group object is a group object in the category of group objects. -/ -@[to_additive] +@[to_additive /-- A commutative additive group object is an additive group object in the category of +additive group objects. -/] instance : GrpObj H where inv := Grp.homMk' { hom := ι[H.X] } namespace Hom @@ -291,7 +293,8 @@ end Hom attribute [local simp] mul_eq_mul comp_mul mul_comm mul_div_mul_comm in /-- A commutative group object is a commutative group object in the category of group objects. -/ -@[to_additive] +@[to_additive /-- A commutative additive group object is a commutative additive group object in the +category of additive group objects. -/] instance : IsCommMonObj H where @[to_additive] @@ -317,7 +320,8 @@ lemma GrpObj.conj_eq_snd_of_isCommMonObj [IsCommMonObj G] : conj G = snd G G := open scoped IsMulCommutative in /-- `G` is a commutative group object if and only if the commutator map `(x, y) ↦ x * y * x⁻¹ * y⁻¹` is constant. -/ -@[to_additive] +@[to_additive /-- `G` is a commutative additive group object if and only if the commutator map +`(x, y) ↦ x + y + (-x) + (-y)` is constant. -/] lemma isCommMonObj_iff_commutator_eq_toUnit_η : IsCommMonObj G ↔ GrpObj.commutator G = toUnit _ ≫ η := by rw [isCommMonObj_iff_isMulCommutative] diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean index aebc3e41b449ac..d006a8456885bd 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean @@ -468,7 +468,9 @@ end Hom open scoped IsMulCommutative in /-- A monoid object `M` is commutative if and only if `X ⟶ M` is commutative for all `X`. -/ -@[to_additive] +@[to_additive +/-- An additive monoid object `M` is commutative if and only if `X ⟶ M` is commutative for all +`X`. -/] lemma isCommMonObj_iff_isMulCommutative (M : C) [MonObj M] [BraidedCategory C] : IsCommMonObj M ↔ ∀ (X : C), IsMulCommutative (X ⟶ M) := by exact ⟨fun h X ↦ ⟨⟨by simp [mul_comm]⟩⟩, fun h ↦ ⟨by simp [mul_eq_mul, comp_mul, mul_comm]⟩⟩ diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Normal.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Normal.lean index 7a9ce3ff7dc6f5..899e877936fe9f 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Normal.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Normal.lean @@ -78,7 +78,8 @@ lemma isNormalHom_iff [IsMonHom φ] [Mono φ] : Normal φ ↔ ∃ ψ : G ⊗ H /-- If `φ` is mono, it is a normal group homomorphism if and only if for all `X` the image of `H(X)` in `G(X)` is a normal subgroup. -/ -@[to_additive] +@[to_additive /-- If `φ` is mono, it is a normal additive group homomorphism if and only if for all +`X` the image of `H(X)` in `G(X)` is a normal additive subgroup. -/] theorem normal_iff_normal_monoidHom [IsMonHom φ] [Mono φ] : Normal φ ↔ ∀ (X : C), (monoidHom φ X).range.Normal := by rw [isNormalHom_iff] diff --git a/Mathlib/CategoryTheory/Monoidal/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Grp.lean index 1219d99e346b1c..5e32e6fbaad479 100644 --- a/Mathlib/CategoryTheory/Monoidal/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Grp.lean @@ -286,7 +286,11 @@ lemma mulRight_one (A : C) [GrpObj A] : mulRight η[A] = Iso.refl A := by In fact, any monoid object whose associativity diagram is Cartesian can be made into a group object (we do not prove this in this file), so we should expect that many properties of group objects follow from this result. -/ -@[to_additive] +@[to_additive /-- The associativity diagram of an additive group object is Cartesian. + +In fact, any additive monoid object whose associativity diagram is Cartesian can be made into an +additive group object (we do not prove this in this file), so we should expect that many properties +of additive group objects follow from this result. -/] theorem isPullback (A : C) [GrpObj A] : IsPullback (μ ▷ A) ((α_ A A A).hom ≫ (A ◁ μ)) μ μ where w := by simp diff --git a/Mathlib/CategoryTheory/Monoidal/Mod.lean b/Mathlib/CategoryTheory/Monoidal/Mod.lean index 70c46cbe43f302..730450bcc5b85f 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mod.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mod.lean @@ -108,7 +108,8 @@ lemma smul_eq_mul (M : C) [MonObj M] : γ[M,M] = μ[M] := rfl /-- If `C` acts monoidally on `D`, then every object of `D` is canonically a module over the trivial monoid. -/ -@[to_additive (attr := simps)] +@[to_additive (attr := simps) /-- If `C` acts monoidally on `D`, then every object of `D` is +canonically an additive module over the trivial additive monoid. -/] instance (X : D) : ModObj (𝟙_ C) X where smul := (λₗ _).hom diff --git a/Mathlib/CategoryTheory/Monoidal/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Mon.lean index a23acdc24df1d3..aa681901e8873f 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon.lean @@ -606,7 +606,8 @@ instance {A B : Mon C} (f : A ⟶ B) [e : IsIso ((forget C).map f)] : IsIso f.ho e /-- The forgetful functor from monoid objects to the ambient category reflects isomorphisms. -/ -@[to_additive] +@[to_additive /-- The forgetful functor from additive monoid objects to the ambient category +reflects isomorphisms. -/] instance : (forget C).ReflectsIsomorphisms where reflects f e := ⟨⟨.mk' (inv f.hom), by cat_disch⟩⟩ @@ -726,7 +727,7 @@ variable (C) set_option backward.defeqAttrib.useBackward true in /-- The forgetful functor from `Mon C` to `C` is monoidal when `C` is monoidal. -/ -@[to_additive] +@[to_additive /-- The forgetful functor from `AddMon C` to `C` is monoidal when `C` is monoidal. -/] instance : (forget C).Monoidal := Functor.CoreMonoidal.toMonoidal { εIso := Iso.refl _ From d6b248061c64ee3aff51e28de440294ac185a6dc Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Mon, 13 Jul 2026 07:09:01 +0000 Subject: [PATCH 0747/1300] feat(Algebra/Module): lemma for `spanFinrank` eq one (#40813) In this PR we added equivalent characterization of `spanFinrank` equal to one. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Algebra/Module/SpanRank.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Module/SpanRank.lean b/Mathlib/Algebra/Module/SpanRank.lean index b987823c938eba..036b6d4af6e496 100644 --- a/Mathlib/Algebra/Module/SpanRank.lean +++ b/Mathlib/Algebra/Module/SpanRank.lean @@ -284,6 +284,13 @@ lemma spanFinrank_singleton {m : M} (hm : m ≠ 0) : (span R {m}).spanFinrank = · by_contra! simp [Submodule.spanFinrank_eq_zero_iff_eq_bot (fg_span_singleton m), hm] at this +lemma spanFinrank_eq_one_iff (p : Submodule R M) : p.spanFinrank = 1 ↔ p.IsPrincipal ∧ p ≠ ⊥ := by + refine ⟨fun h ↦ ⟨?_, (by grind [spanFinrank_bot])⟩, + fun ⟨⟨a, ha⟩, _⟩ ↦ ha ▸ spanFinrank_singleton (by simp_all)⟩ + have fg : p.FG := spanRank_finite_iff_fg.1 (by simp_all [spanFinrank]) + obtain ⟨a, ha⟩ : ∃ a, p.generators = {a} := by simpa [← fg.generators_ncard] using h + exact ⟨a, ha ▸ (p.span_generators).symm⟩ + end Defs end Submodule From b118b5f12c2e678fada5704d29a60351692365b1 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Mon, 13 Jul 2026 07:49:37 +0000 Subject: [PATCH 0748/1300] fix(scripts/runSkimmer): only `lake update skimmer` (#41662) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, `runSkimmer.sh` would run `lake update`, thus potentially erroneously updating packages from mathlib in its own `.lake/packages`. By using `lake update skimmer` we ensure that only skimmer itself (which depends on nothing) is updated, and we match the mathlib dependencies to whatever mathlib already has. This ensures that we're able to use the mathlib cache. Note: this still clones every package into `scripts/SideSkimmer/.lake/packages/`—but by cloning the right version, we can use the cache. --- scripts/runSkimmer.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/runSkimmer.sh b/scripts/runSkimmer.sh index ae8e794998cb9d..5b014dd81da44a 100755 --- a/scripts/runSkimmer.sh +++ b/scripts/runSkimmer.sh @@ -49,11 +49,11 @@ usage() { Usage: runSkimmer.sh [[--no-update] [--on [tgts...]] | --lake-update | --init | -h | --help] Options: - [no arguments] Run \`lake update\` in \`SideSkimmer\`, then run \`lake build :applyCurrentTryThis\` on targets configured in \`runSkimmer.sh\`. (When refactoring mathlib, does not get mathlib's cache.) - --on [tgts...] Run \`lake update\` in \`SideSkimmer\`, then run \`lake build :applyCurrentTryThis\` for \`tgt\` in the supplied \`tgts\`. Each `tgt` may be lake target syntax for the current package or a library or module therein. (When refactoring mathlib, does not get mathlib's cache.) - --no-update Only run \`lake build :applyCurrentTryThis\`, without first running \`lake update\` in \`SideSkimmer\`. Applies both the default targets and those supplied with \`--on\`. + [no arguments] Run \`lake update skimmer\` in \`SideSkimmer\`, then run \`lake build :applyCurrentTryThis\` on targets configured in \`runSkimmer.sh\`. (When refactoring mathlib, does not get mathlib's cache.) + --on [tgts...] Run \`lake update skimmer\` in \`SideSkimmer\`, then run \`lake build :applyCurrentTryThis\` for \`tgt\` in the supplied \`tgts\`. Each `tgt` may be lake target syntax for the current package or a library or module therein. (When refactoring mathlib, does not get mathlib's cache.) + --no-update Only run \`lake build :applyCurrentTryThis\`, without first running \`lake update skimmer\` in \`SideSkimmer\`. Applies both the default targets and those supplied with \`--on\`. --init Set up the \`SideSkimmer\` side package. This only needs to be done when first introducing \`runSkimmer.sh\` to a new repo. - --lake-update Only run \`lake update -v\` in \`SideSkimmer\`, and if refactoring mathlib, do not get mathlib's cache while doing so. + --lake-update Only run \`lake update skimmer -v\` in \`SideSkimmer\`, and if refactoring mathlib, do not get mathlib's cache while doing so. EOF } @@ -117,18 +117,18 @@ EOF /lean-toolchain EOF # Creates toolchain, manifest, etc. - (cd "${pkg}" && lake update) + (cd "${pkg}" && lake update skimmer) else if [[ -f "${pkg}/lakefile.lean" && -f "${pkg}/.gitignore" ]]; then if [[ "${lakeUpdate}" ]]; then - echo "Only running \`lake update -v\` in \`SideSkimmer\`; skipping run." - (cd "${pkg}" && lake update -v) + echo "Only running \`lake update skimmer -v\` in \`SideSkimmer\`; skipping run." + (cd "${pkg}" && lake update skimmer -v) exit 0 fi - # Only run `lake update` if `--no-update` is not present. + # Only run `lake update skimmer` if `--no-update` is not present. if [[ ! "${noUpdate}" ]]; then - echo "Running \`lake update\` in \`SideSkimmer\`. Use \`runSkimmer.sh --no-update\` to skip this step." - (cd "${pkg}" && lake update) + echo "Running \`lake update skimmer\` in \`SideSkimmer\`. Use \`runSkimmer.sh --no-update\` to skip this step." + (cd "${pkg}" && lake update skimmer) elif [[ ! -f "${pkg}/lake-manifest.json" ]]; then echo "Expected manifest at \`${pkg}/lake-manifest.json\`." echo "Please exclude the \`--no-update\` flag to create one." From a3364faec42918fcd84a03a255b50570129f9ead Mon Sep 17 00:00:00 2001 From: Salvatore Mercuri <47568553+smmercuri@users.noreply.github.com> Date: Mon, 13 Jul 2026 08:45:00 +0000 Subject: [PATCH 0749/1300] refactor(NumberTheory): make `InfinitePlace.Completion` a one-field structure (#41543) Makes FLT a lot faster. `InfinitePlace` analogue of #41526. --- .../NumberField/Completion/InfinitePlace.lean | 189 +++++++++++++++--- .../Completion/LiesOverInstances.lean | 30 ++- .../NumberField/InfiniteAdeleRing.lean | 5 +- 3 files changed, 183 insertions(+), 41 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean index 53e7e944072535..c1298e0915b3cb 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean @@ -73,19 +73,134 @@ theorem isometry_embedding_of_isReal (hv : v.IsReal) : AddMonoidHomClass.isometry_of_norm _ fun x ↦ by simpa using! v.norm_embedding_of_isReal hv (WithAbs.equiv v.1 x) -/-- The completion of a number field at an infinite place. -/ -abbrev Completion := v.1.Completion +instance : CompletableTopField (WithAbs v.1) := + v.isometry_embedding.isUniformInducing.completableTopField + +/-- The completion of a number field at an infinite place, as a one-field structure wrapping the +completion `v.1.Completion` of `K` at the underlying absolute value. -/ +structure Completion where + /-- Wrap an element of `v.1.Completion` into `v.Completion`. -/ + ofCompletion :: + /-- The underlying element of `v.1.Completion`. -/ + toCompletion : v.1.Completion namespace Completion +/-- `Completion.toCompletion` and `Completion.ofCompletion` as an equivalence. -/ +@[simps] +def equivCompletion : v.Completion ≃ v.1.Completion where + toFun := toCompletion + invFun := ofCompletion + left_inv _ := rfl + right_inv _ := rfl + +instance : NormedField v.Completion := fast_instance% (equivCompletion v).normedField + +/-- `Completion.toCompletion` as a ring isomorphism onto the underlying completion. -/ +@[simps! apply] +def equiv : v.Completion ≃+* v.1.Completion where + toEquiv := equivCompletion v + map_mul' _ _ := rfl + map_add' _ _ := rfl + +@[simp] lemma toCompletion_ofCompletion (x : v.1.Completion) : + toCompletion (ofCompletion x : v.Completion) = x := rfl +@[simp] lemma ofCompletion_toCompletion (x : v.Completion) : + ofCompletion x.toCompletion = x := rfl + +@[simp] lemma toCompletion_zero : (0 : v.Completion).toCompletion = 0 := rfl +@[simp] lemma toCompletion_one : (1 : v.Completion).toCompletion = 1 := rfl +@[simp] lemma toCompletion_add (x y : v.Completion) : + (x + y).toCompletion = x.toCompletion + y.toCompletion := rfl +@[simp] lemma toCompletion_mul (x y : v.Completion) : + (x * y).toCompletion = x.toCompletion * y.toCompletion := rfl + +@[ext] theorem ext {v : InfinitePlace K} {x y : v.Completion} + (h : x.toCompletion = y.toCompletion) : x = y := by + cases x; cases y; exact congrArg ofCompletion h + +theorem toCompletion_surjective : Function.Surjective (toCompletion (v := v)) := + (equivCompletion v).surjective + +theorem ofCompletion_surjective : Function.Surjective (ofCompletion (v := v)) := + (equivCompletion v).symm.surjective + +@[simp] lemma norm_toCompletion (x : v.Completion) : ‖x.toCompletion‖ = ‖x‖ := rfl + +@[simp] lemma norm_ofCompletion (x : v.1.Completion) : + ‖(ofCompletion x : v.Completion)‖ = ‖x‖ := rfl + +theorem isometry_toCompletion : Isometry (toCompletion (v := v)) := + Isometry.of_dist_eq fun _ _ ↦ rfl + +/-- `Completion.toCompletion` as an isometry equivalence onto the underlying completion. -/ +def isometryEquivCompletion : v.Completion ≃ᵢ v.1.Completion where + toEquiv := equivCompletion v + isometry_toFun := isometry_toCompletion v + +theorem continuous_toCompletion : Continuous (toCompletion (v := v)) := + (isometry_toCompletion v).continuous + +theorem continuous_ofCompletion : Continuous (ofCompletion (v := v)) := + (isometryEquivCompletion v).symm.continuous + +instance : CompleteSpace v.Completion := + ((isometry_toCompletion v).isUniformInducing.completeSpace_congr + (toCompletion_surjective v)).mpr inferInstance + +instance : Inhabited v.Completion := ⟨0⟩ + +/-- Coercion of an element of `WithAbs v.1` into the completion. -/ +instance : Coe (WithAbs v.1) v.Completion where + coe x := ofCompletion (x : v.1.Completion) + +/-- Coercion of an element of `K` into the completion. -/ +instance : Coe K v.Completion where + coe k := ofCompletion (k : v.1.Completion) + +@[simp] lemma coe_toCompletion (x : WithAbs v.1) : + (x : v.Completion).toCompletion = (x : v.1.Completion) := rfl + +@[norm_cast] lemma coe_zero : ((0 : K) : v.Completion) = 0 := by ext; simp +@[norm_cast] lemma coe_one : ((1 : K) : v.Completion) = 1 := by ext; simp +@[norm_cast] lemma coe_add (x y : K) : ((x + y : K) : v.Completion) = ↑x + ↑y := by + ext; simp [UniformSpace.Completion.coe_add] +@[norm_cast] lemma coe_mul (x y : K) : ((x * y : K) : v.Completion) = ↑x * ↑y := by + ext; simp [UniformSpace.Completion.coe_mul] + +theorem continuous_coe : Continuous ((↑) : WithAbs v.1 → v.Completion) := + (continuous_ofCompletion v).comp (UniformSpace.Completion.continuous_coe _) + +theorem denseRange_coe : DenseRange ((↑) : WithAbs v.1 → v.Completion) := + (ofCompletion_surjective v).denseRange.comp UniformSpace.Completion.denseRange_coe + (continuous_ofCompletion v) + +/-- Induction on the completion of a number field at an infinite place: a closed property that +holds on the image of `K` holds everywhere. -/ +@[elab_as_elim] +theorem induction_on {p : v.Completion → Prop} (x : v.Completion) (hp : IsClosed {x | p x}) + (ih : ∀ a : WithAbs v.1, p a) : p x := + UniformSpace.Completion.induction_on (p := fun y ↦ p (ofCompletion y)) x.toCompletion + (hp.preimage (continuous_ofCompletion v)) ih + +section Algebra + +variable (R : Type*) [CommSemiring R] [Algebra R (WithAbs v.1)] + [UniformContinuousConstSMul R (WithAbs v.1)] + +instance : Algebra R v.Completion := fast_instance% (equivCompletion v).algebra R + +theorem algebraMap_toCompletion (r : R) : + (algebraMap R v.Completion r).toCompletion = algebraMap R v.1.Completion r := rfl + +end Algebra + +@[simp] theorem algebraMap_apply (k : K) : algebraMap K v.Completion k = (k : v.Completion) := rfl lemma norm_coe (x : WithAbs v.1) : ‖(x : v.Completion)‖ = v (WithAbs.equiv v.1 x) := UniformSpace.Completion.norm_coe x -instance : CompletableTopField (WithAbs v.1) := - v.isometry_embedding.isUniformInducing.completableTopField - example : NormedField v.Completion := inferInstance example : Algebra K v.Completion := inferInstance example : IsTopologicalRing v.Completion := inferInstance @@ -93,8 +208,8 @@ example : IsTopologicalRing v.Completion := inferInstance /-- The coercion from the rationals to its completion along an infinite place is `Rat.cast`. -/ lemma WithAbs.ratCast_equiv (v : InfinitePlace ℚ) (x : WithAbs v.1) : Rat.cast (WithAbs.equiv _ x) = (x : v.Completion) := - (eq_ratCast (UniformSpace.Completion.coeRingHom.comp - (WithAbs.equiv v.1).symm.toRingHom) _).symm + (eq_ratCast ((equiv v).symm.toRingHom.comp (UniformSpace.Completion.coeRingHom.comp + (WithAbs.equiv v.1).symm.toRingHom)) _).symm lemma Rat.norm_infinitePlace_completion (v : InfinitePlace ℚ) (x : ℚ) : ‖(x : v.Completion)‖ = |x| := by @@ -104,14 +219,16 @@ lemma Rat.norm_infinitePlace_completion (v : InfinitePlace ℚ) (x : ℚ) : /-- The completion of a number field at an infinite place is locally compact. -/ instance locallyCompactSpace : LocallyCompactSpace (v.Completion) := - AbsoluteValue.Completion.locallyCompactSpace v.isometry_embedding + letI := AbsoluteValue.Completion.locallyCompactSpace v.isometry_embedding + (isometryEquivCompletion v).toHomeomorph.isClosedEmbedding.locallyCompactSpace /-- The embedding associated to an infinite place extended to an embedding `v.Completion →+* ℂ`. -/ -def extensionEmbedding : v.Completion →+* ℂ := v.isometry_embedding.extensionHom +def extensionEmbedding : v.Completion →+* ℂ := + v.isometry_embedding.extensionHom.comp (equiv v).toRingHom /-- The embedding `K →+* ℝ` associated to a real infinite place extended to `v.Completion →+* ℝ`. -/ def extensionEmbeddingOfIsReal {v : InfinitePlace K} (hv : IsReal v) : v.Completion →+* ℝ := - (v.isometry_embedding_of_isReal hv).extensionHom + (v.isometry_embedding_of_isReal hv).extensionHom.comp (equiv v).toRingHom @[simp] theorem extensionEmbedding_coe (x : WithAbs v.1) : @@ -123,31 +240,34 @@ theorem extensionEmbeddingOfIsReal_coe {v : InfinitePlace K} (hv : IsReal v) (x extensionEmbeddingOfIsReal hv x = embedding_of_isReal hv (WithAbs.equiv v.1 x) := (v.isometry_embedding_of_isReal hv).extensionHom_coe _ -open UniformSpace.Completion in -@[simp] -theorem extensionEmbeddingOfIsReal_apply {v : InfinitePlace K} (hv : IsReal v) (x : v.Completion) : - (extensionEmbeddingOfIsReal hv x : ℂ) = extensionEmbedding v x := by - refine UniformSpace.Completion.induction_on x ?_ (by simp) - exact isClosed_eq (Continuous.comp' (by fun_prop) continuous_extension) continuous_extension - /-- The embedding `v.Completion →+* ℂ` is an isometry. -/ theorem isometry_extensionEmbedding : Isometry (extensionEmbedding v) := - v.isometry_embedding.completion_extension + v.isometry_embedding.completion_extension.comp (isometry_toCompletion v) /-- The embedding `v.Completion →+* ℝ` at a real infinite place is an isometry. -/ theorem isometry_extensionEmbeddingOfIsReal {v : InfinitePlace K} (hv : IsReal v) : Isometry (extensionEmbeddingOfIsReal hv) := - (v.isometry_embedding_of_isReal hv).completion_extension + (v.isometry_embedding_of_isReal hv).completion_extension.comp (isometry_toCompletion v) + +@[simp] +theorem extensionEmbeddingOfIsReal_apply {v : InfinitePlace K} (hv : IsReal v) (x : v.Completion) : + (extensionEmbeddingOfIsReal hv x : ℂ) = extensionEmbedding v x := by + induction x using induction_on with + | hp => + exact isClosed_eq + (Complex.continuous_ofReal.comp (isometry_extensionEmbeddingOfIsReal hv).continuous) + (isometry_extensionEmbedding v).continuous + | ih a => simp /-- The embedding `v.Completion →+* ℂ` has closed image inside `ℂ`. -/ theorem isClosed_image_extensionEmbedding : IsClosed (Set.range (extensionEmbedding v)) := - v.isometry_embedding.completion_extension.isClosedEmbedding.isClosed_range + (isometry_extensionEmbedding v).isClosedEmbedding.isClosed_range /-- The embedding `v.Completion →+* ℝ` associated to a real infinite place has closed image inside `ℝ`. -/ theorem isClosed_image_extensionEmbeddingOfIsReal {v : InfinitePlace K} (hv : IsReal v) : IsClosed (Set.range (extensionEmbeddingOfIsReal hv)) := - (v.isometry_embedding_of_isReal hv).completion_extension.isClosedEmbedding.isClosed_range + (isometry_extensionEmbeddingOfIsReal hv).isClosedEmbedding.isClosed_range theorem subfield_ne_real_of_isComplex {v : InfinitePlace K} (hv : IsComplex v) : (extensionEmbedding v).fieldRange ≠ Complex.ofRealHom.fieldRange := by @@ -209,15 +329,20 @@ def isometryEquivRealOfIsReal {v : InfinitePlace K} (hv : IsReal v) : v.Completi isometry_toFun := isometry_extensionEmbeddingOfIsReal hv variable {L : Type*} [Field L] [Algebra K L] (w : InfinitePlace L) {v} - [Algebra v.Completion w.Completion] [IsScalarTower K v.Completion w.Completion] -set_option backward.isDefEq.respectTransparency false in +theorem algebraMap_eq_coe (x : WithAbs v.1) : + algebraMap (WithAbs v.1) w.Completion x = (algebraMap (WithAbs v.1) (WithAbs w.1) x) := by + apply ext + rw [algebraMap_toCompletion] + exact UniformSpace.Completion.algebraMap_def (WithAbs w.1) (WithAbs v.1) x + +variable [Algebra v.Completion w.Completion] [IsScalarTower K v.Completion w.Completion] + @[simp] theorem algebraMap_coe (x : WithAbs v.1) : - algebraMap v.Completion w.Completion x = algebraMap (WithAbs v.1) (WithAbs w.1) x := by - have := IsScalarTower.algebraMap_apply (WithAbs v.1) v.Completion w.Completion x - rw [algebraMap_def] at this - simp [this, algebraMap_def, Algebra.algebraMap_self] + algebraMap v.Completion w.Completion x = algebraMap (WithAbs v.1) (WithAbs w.1) x := + (IsScalarTower.algebraMap_apply (WithAbs v.1) v.Completion w.Completion x).symm.trans + (algebraMap_eq_coe w x) end Completion @@ -240,8 +365,9 @@ theorem liesOver_extensionEmbedding [ContinuousSMul v.Completion w.Completion] ext x induction x using induction_on · exact isClosed_eq - (continuous_extension.comp (continuous_algebraMap v.Completion w.Completion)) - continuous_extension + ((isometry_extensionEmbedding w).continuous.comp + (continuous_algebraMap v.Completion w.Completion)) + (isometry_extensionEmbedding v).continuous · simp [WithAbs.algebraMap_left_apply, WithAbs.algebraMap_right_apply, ← ComplexEmbedding.LiesOver.over w.embedding v.embedding] @@ -252,8 +378,9 @@ theorem liesOver_conjugate_extensionEmbedding [ContinuousSMul v.Completion w.Com ext x induction x using induction_on · simpa using! isClosed_eq (.comp (by fun_prop) - (continuous_extension.comp <| continuous_algebraMap v.Completion w.Completion)) - continuous_extension + ((isometry_extensionEmbedding w).continuous.comp <| + continuous_algebraMap v.Completion w.Completion)) + (isometry_extensionEmbedding v).continuous · simp [WithAbs.algebraMap_left_apply, WithAbs.algebraMap_right_apply, ← ComplexEmbedding.LiesOver.over (conjugate w.embedding) v.embedding] diff --git a/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean b/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean index 505f6f53fb1e66..61bd2a56112998 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean @@ -21,23 +21,39 @@ public section namespace NumberField.LiesOver -open UniformSpace.Completion InfinitePlace +open InfinitePlace InfinitePlace.Completion variable {K L : Type*} [Field K] [Field L] [Algebra K L] {v : InfinitePlace K} {w : InfinitePlace L} variable [w.1.LiesOver v.1] +/-- The ring homomorphism `v.Completion →+* w.Completion` induced by `algebraMap K L`, when `w` +lies over `v`. -/ +noncomputable def completionMap : v.Completion →+* w.Completion := + ((Completion.equiv w).symm.toRingHom.comp + (LiesOver.isometry_algebraMap w v).mapRingHom).comp (Completion.equiv v).toRingHom + +theorem continuous_completionMap : Continuous (completionMap (v := v) (w := w)) := + (continuous_ofCompletion w).comp <| + UniformSpace.Completion.continuous_map.comp (continuous_toCompletion v) + +theorem completionMap_coe (x : WithAbs v.1) : + completionMap (x : v.Completion) = ((algebraMap (WithAbs v.1) (WithAbs w.1) x : WithAbs w.1) : + w.Completion) := + Completion.ext <| (LiesOver.isometry_algebraMap w v).mapRingHom_coe x + /-- If `w` lies over `v`, then `w.Completion` is a `v.Completion`-algebra. -/ -noncomputable scoped instance : Algebra v.Completion w.Completion := - (LiesOver.isometry_algebraMap w v).mapRingHom.toAlgebra +noncomputable scoped instance : Algebra v.Completion w.Completion := completionMap.toAlgebra scoped instance : IsScalarTower K v.Completion w.Completion := .of_algebraMap_eq fun x ↦ by - simp_rw [RingHom.algebraMap_toAlgebra, UniformSpace.Completion.algebraMap_def, - Isometry.mapRingHom_coe] + have h : algebraMap K v.Completion x = ((WithAbs.toAbs v.1 x : WithAbs v.1) : v.Completion) := + rfl + rw [RingHom.algebraMap_toAlgebra, h, completionMap_coe] + apply Completion.ext + rw [Completion.algebraMap_toCompletion, UniformSpace.Completion.algebraMap_def] simp [WithAbs.algebraMap_left_apply, WithAbs.algebraMap_right_apply] scoped instance : ContinuousSMul v.Completion w.Completion where - continuous_smul := (UniformSpace.Completion.continuous_map.comp continuous_fst).mul - (Continuous.comp continuous_id continuous_snd) + continuous_smul := (continuous_completionMap.comp continuous_fst).mul continuous_snd end NumberField.LiesOver diff --git a/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean b/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean index 1813f5a678c2f4..a1cd977f3b3738 100644 --- a/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean +++ b/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean @@ -102,9 +102,8 @@ theorem mixedEmbedding_eq_algebraMap_comp {x : K} : The number field $K$ is dense in the infinite adele ring $\prod_v K_v$. -/ theorem denseRange_algebraMap [NumberField K] : DenseRange <| algebraMap K (InfiniteAdeleRing K) := - (DenseRange.piMap fun _ => UniformSpace.Completion.denseRange_coe).comp - (InfinitePlace.denseRange_algebraMap_pi K) - (.piMap fun _ => UniformSpace.Completion.continuous_coe _) + (DenseRange.piMap fun v => Completion.denseRange_coe v).comp + (InfinitePlace.denseRange_algebraMap_pi K) (.piMap fun v => Completion.continuous_coe v) /-- The norm on the infinite adele ring is given by the product of the normalized norms across infinite places. The normalized norm is the real norm at real places and the From 11c7f27fb4ff943700fc58bb89b3ad8789e250b3 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Mon, 13 Jul 2026 09:07:13 +0000 Subject: [PATCH 0750/1300] feat(Analysis/BoxIntegral): minor API additions to BoxIntegral and BoxIntegral.BoxAdditiveMap (#41592) Thjs PR records some minor API additions to `Analysis.BoxIntegral` and `Analysis.BoxIntegral.BoxAdditiveMap` that arose as part of the ICERM Riemann-Stieltjes integration project, but are of general utility beyond that project. Co-authored-by: Terence Tao --- Mathlib/Analysis/BoxIntegral/Basic.lean | 21 ++++++-- .../BoxIntegral/Partition/Additive.lean | 50 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/BoxIntegral/Basic.lean b/Mathlib/Analysis/BoxIntegral/Basic.lean index 049d9d385a074c..90d0a9b09bc2e2 100644 --- a/Mathlib/Analysis/BoxIntegral/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Basic.lean @@ -76,12 +76,20 @@ local notation "ℝⁿ" => ι → ℝ ### Integral sum and its basic properties -/ - /-- The integral sum of `f : ℝⁿ → E` over a tagged prepartition `π` w.r.t. box-additive volume `vol` with codomain `E →L[ℝ] F` is the sum of `vol J (f (π.tag J))` over all boxes of `π`. -/ def integralSum (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : TaggedPrepartition I) : F := ∑ J ∈ π.boxes, vol J (f (π.tag J)) +theorem integralSum_congr {f₁ f₂ : ℝⁿ → E} {vol₁ vol₂ : ι →ᵇᵃ E →L[ℝ] F} + (hf : EqOn f₁ f₂ I.Icc) (hvol : EqOn vol₁ vol₂ π.boxes) : + integralSum f₁ vol₁ π = integralSum f₂ vol₂ π := by + unfold integralSum + refine Finset.sum_congr rfl (fun J hJ ↦ ?_) + congr 1 + · exact hvol hJ + exact hf (π.tag_mem_Icc J) + theorem integralSum_biUnionTagged (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : Prepartition I) (πi : ∀ J, TaggedPrepartition J) : integralSum f vol (π.biUnionTagged πi) = ∑ J ∈ π.boxes, integralSum f vol (πi J) := by @@ -151,7 +159,6 @@ variable [Fintype ι] ### Basic integrability theory -/ - /-- The predicate `HasIntegral I l f vol y` says that `y` is the integral of `f` over `I` along `l` w.r.t. volume `vol`. This means that integral sums of `f` tend to `𝓝 y` along `BoxIntegral.IntegrationParams.toFilteriUnion I ⊤`. -/ @@ -170,6 +177,15 @@ Returns zero on non-integrable functions. -/ def integral (I : Box ι) (l : IntegrationParams) (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) := if h : Integrable I l f vol then h.choose else 0 +theorem hasIntegral_congr (I : Box ι) (l : IntegrationParams) {f₁ f₂ : ℝⁿ → E} + {vol₁ vol₂ : ι →ᵇᵃ E →L[ℝ] F} + (hf : EqOn f₁ f₂ I.Icc) (hvol : EqOn vol₁ vol₂ (Set.Iic I)) (y : F) : + HasIntegral I l f₁ vol₁ y ↔ HasIntegral I l f₂ vol₂ y := by + unfold HasIntegral + refine Filter.tendsto_congr (fun π ↦ integralSum_congr hf (hvol.mono ?_)) + intro J hJ + simp [π.le_of_mem' J hJ] + -- Porting note: using the above notation ℝⁿ here causes the theorem below to be silently ignored -- see https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Lean.204.20doesn't.20add.20lemma.20to.20the.20environment/near/363764522 -- and https://github.com/leanprover/lean4/issues/2257 @@ -389,7 +405,6 @@ The proof is mostly based on [Russel A. Gordon, *The integrals of Lebesgue, Denjoy, Perron, and Henstock*][Gordon55]. -/ - namespace Integrable /-- If `ε > 0`, then `BoxIntegral.Integrable.convergenceR` is a function `r : ℝ≥0 → ℝⁿ → (0, ∞)` diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean b/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean index 70c31e161287d2..c120b1ea1104b1 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean @@ -63,6 +63,8 @@ open Box Prepartition Finset variable {N : Type*} [AddCommMonoid M] [AddCommMonoid N] {I₀ : WithTop (Box ι)} {I : Box ι} {i : ι} +/-! ### Coercion, extensionality, and the defining property -/ + instance : FunLike (ι →ᵇᵃ[I₀] M) (Box ι) M where coe := toFun coe_injective f g h := by cases f; cases g; congr @@ -77,10 +79,16 @@ theorem coe_injective : Injective fun (f : ι →ᵇᵃ[I₀] M) x => f x := theorem coe_inj {f g : ι →ᵇᵃ[I₀] M} : (f : Box ι → M) = g ↔ f = g := DFunLike.coe_fn_eq +@[ext] +theorem ext {f g : ι →ᵇᵃ[I₀] M} (h : ∀ J, f J = g J) : f = g := + DFunLike.ext _ _ h + theorem sum_partition_boxes (f : ι →ᵇᵃ[I₀] M) (hI : ↑I ≤ I₀) {π : Prepartition I} (h : π.IsPartition) : ∑ J ∈ π.boxes, f J = f I := f.sum_partition_boxes' I hI π h +/-! ### Additive monoid structure -/ + @[simps -fullyApplied] instance : Zero (ι →ᵇᵃ[I₀] M) := ⟨⟨0, fun _ _ _ _ => sum_const_zero⟩⟩ @@ -101,6 +109,15 @@ instance {R} [Monoid R] [DistribMulAction R M] : SMul R (ι →ᵇᵃ[I₀] M) : instance : AddCommMonoid (ι →ᵇᵃ[I₀] M) := Function.Injective.addCommMonoid _ coe_injective rfl (fun _ _ => rfl) fun _ _ => rfl +@[simp] +lemma add_apply (f g : ι →ᵇᵃ[I₀] M) (J : Box ι) : (f + g) J = f J + g J := rfl + +@[simp] +lemma smul_apply {R : Type*} [Monoid R] [DistribMulAction R M] + (c : R) (f : ι →ᵇᵃ[I₀] M) (J : Box ι) : (c • f) J = c • (f J) := rfl + +/-! ### Constructions and combinators -/ + @[simp] theorem map_split_add (f : ι →ᵇᵃ[I₀] M) (hI : ↑I ≤ I₀) (i : ι) (x : ℝ) : (I.splitLower i x).elim' 0 f + (I.splitUpper i x).elim' 0 f = f I := by @@ -163,8 +180,39 @@ theorem sum_boxes_congr [Finite ι] (f : ι →ᵇᵃ[I₀] M) (hI : ↑I ≤ I exacts [(WithTop.coe_le_coe.2 <| π₁.le_of_mem hJ).trans hI, (WithTop.coe_le_coe.2 <| π₂.le_of_mem hJ).trans hI] +section AddCommGroup + +/-! ### Additive group structure -/ + +variable {M : Type*} [AddCommGroup M] + +instance : Neg (ι →ᵇᵃ[I₀] M) := + ⟨fun f ↦ + ⟨-(f : Box ι → M), fun I hI π hπ ↦ by + simp only [Pi.neg_apply, Finset.sum_neg_distrib, sum_partition_boxes _ hI hπ]⟩⟩ + +instance : Sub (ι →ᵇᵃ[I₀] M) := + ⟨fun f g ↦ + ⟨(f : Box ι → M) - g, fun I hI π hπ ↦ by + simp only [Pi.sub_apply, Finset.sum_sub_distrib, sum_partition_boxes _ hI hπ]⟩⟩ + +instance : AddCommGroup (ι →ᵇᵃ[I₀] M) := + Function.Injective.addCommGroup _ DFunLike.coe_injective + rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + +@[simp] +lemma neg_apply (f : ι →ᵇᵃ[I₀] M) (J : Box ι) : (-f) J = -(f J) := rfl + +@[simp] +lemma sub_apply (f g : ι →ᵇᵃ[I₀] M) (J : Box ι) : (f - g) J = f J - g J := rfl + +end AddCommGroup + section ToSMul +/-! ### Scalar multiplication on a normed space -/ + variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] /-- If `f` is a box-additive map, then so is the map sending `I` to the scalar multiplication @@ -177,6 +225,8 @@ theorem toSMul_apply (f : ι →ᵇᵃ[I₀] ℝ) (I : Box ι) (x : E) : f.toSMu end ToSMul +/-! ### Difference along an axis: `upper − lower` over faces -/ + /-- Given a box `I₀` in `ℝⁿ⁺¹`, `f x : Box (Fin n) → G` is a family of functions indexed by a real `x` and for `x ∈ [I₀.lower i, I₀.upper i]`, `f x` is box-additive on subboxes of the `i`-th face of `I₀`, then `fun J ↦ f (J.upper i) (J.face i) - f (J.lower i) (J.face i)` is box-additive on subboxes From 22e2625af6b5248de5323d0026f58b5771833042 Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Mon, 13 Jul 2026 09:29:50 +0000 Subject: [PATCH 0751/1300] chore: simplify `show _ from by _` to `show _ by _` (#41493) `show X from t` proves `X` using the term `t`; `show X by tac` proves `X` using the tactic `tac`. `show X from by tac` is thus a redundant lengthening of `show X by tac`. This replaces all 21 occurrences of `show _ from by _` in the library with `show _ by _`. --- Mathlib/Algebra/Lie/Weights/Cartan.lean | 2 +- Mathlib/Analysis/Convex/Approximation.lean | 2 +- Mathlib/Analysis/MeanInequalitiesPow.lean | 2 +- Mathlib/Analysis/Polynomial/MahlerMeasure.lean | 2 +- .../CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean | 6 +++--- Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean | 2 +- .../Combinatorics/SimpleGraph/Connectivity/Subgraph.lean | 6 +++--- Mathlib/Combinatorics/SimpleGraph/Matching.lean | 6 +++--- Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean | 2 +- Mathlib/LinearAlgebra/JordanChevalley.lean | 2 +- Mathlib/LinearAlgebra/Projectivization/Action.lean | 4 ++-- Mathlib/RingTheory/HopfAlgebra/Convolution.lean | 2 +- Mathlib/Topology/Algebra/Monoid.lean | 4 ++-- Mathlib/Topology/Compactification/OnePoint/Basic.lean | 2 +- 14 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Mathlib/Algebra/Lie/Weights/Cartan.lean b/Mathlib/Algebra/Lie/Weights/Cartan.lean index ac6795709a85ac..e6da1b44287b17 100644 --- a/Mathlib/Algebra/Lie/Weights/Cartan.lean +++ b/Mathlib/Algebra/Lie/Weights/Cartan.lean @@ -330,7 +330,7 @@ lemma lieIdeal_eq_inf_cartan_sup_biSup_inf_rootSpace (I : LieIdeal K L) : conv_lhs => rw [lieIdeal_eq_iSup_inf_genWeightSpace] exact iSup_le fun α ↦ by by_cases hα : α.IsZero - · rw [show genWeightSpace L (α : H → K) = H.toLieSubmodule from by ext; simp [hα.eq]] + · rw [show genWeightSpace L (α : H → K) = H.toLieSubmodule by ext; simp [hα.eq]] exact le_sup_left · exact le_sup_of_le_right (le_iSup₂_of_le α hα le_rfl) diff --git a/Mathlib/Analysis/Convex/Approximation.lean b/Mathlib/Analysis/Convex/Approximation.lean index cd2fd270b26db8..1e2ae788358a8d 100644 --- a/Mathlib/Analysis/Convex/Approximation.lean +++ b/Mathlib/Analysis/Convex/Approximation.lean @@ -115,7 +115,7 @@ theorem sSup_affine_eq (hsc : IsClosed s) ext x rw [sSup_apply] refine csSup_eq_of_forall_le_of_forall_lt_exists_gt ?_ (fun r ⟨f, hf⟩ => ?_) (fun r hr => ?_) - · obtain ⟨l, c, hlc⟩ := exists_affine_le_of_lt (𝕜 := 𝕜) x.2 (show φ x - 1 < φ x from by grind) + · obtain ⟨l, c, hlc⟩ := exists_affine_le_of_lt (𝕜 := 𝕜) x.2 (show φ x - 1 < φ x by grind) hsc hφc hφcv exact ⟨φ x - 1, hlc.2 ▸ ⟨⟨s.restrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩, rfl⟩⟩ · exact hf ▸ f.2.1 x diff --git a/Mathlib/Analysis/MeanInequalitiesPow.lean b/Mathlib/Analysis/MeanInequalitiesPow.lean index d157730b07294d..18b89c5d8dbae4 100644 --- a/Mathlib/Analysis/MeanInequalitiesPow.lean +++ b/Mathlib/Analysis/MeanInequalitiesPow.lean @@ -351,7 +351,7 @@ theorem rpow_add_le_mul_rpow_add_rpow' (z₁ z₂ : ℝ≥0∞) {p : ℝ} (hp : · simp · rwa [ENNReal.inv_lt_one, one_lt_ofReal] rw [show LpAddConst (ENNReal.ofReal p)⁻¹ = - (2 : ℝ≥0∞) ^ (1 / ((ENNReal.ofReal p)⁻¹).toReal - 1) from by + (2 : ℝ≥0∞) ^ (1 / ((ENNReal.ofReal p)⁻¹).toReal - 1) by rw [LpAddConst, if_pos hmem]] simp only [ENNReal.toReal_inv, div_inv_eq_mul, one_mul] rw [ENNReal.toReal_ofReal hp] diff --git a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean index 71d466e6a1089c..d5261c5c7fdc98 100644 --- a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean +++ b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean @@ -352,7 +352,7 @@ root of its degree plus one. -/ theorem mahlerMeasure_le_sqrt_natDegree_add_one_mul_supNorm (p : Polynomial ℂ) : p.mahlerMeasure ≤ √(p.natDegree + 1) * p.supNorm := (p.mahlerMeasure_le_sqrt_sum_sq_norm_coeff).trans <| by - rw [show √(↑(p.natDegree) + 1) * p.supNorm = √((p.natDegree + 1) * p.supNorm ^ 2) from by + rw [show √(↑(p.natDegree) + 1) * p.supNorm = √((p.natDegree + 1) * p.supNorm ^ 2) by rw [Real.sqrt_mul (by positivity), Real.sqrt_sq p.supNorm_nonneg]] gcongr refine (p.support.sum_le_card_nsmul _ (p.supNorm ^ 2) fun i _ ↦ ?_).trans ?_ diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean index 917b893f1dbf0f..db670cce839bd2 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean @@ -89,7 +89,7 @@ def isLimitPullbackConeMapOfIsLimit [PreservesLimit (cospan f g) G] /-- The property of reflecting pullbacks expressed in terms of binary fans. -/ def isLimitOfIsLimitPullbackConeMap [ReflectsLimit (cospan f g) G] (l : IsLimit (PullbackCone.mk (G.map h) (G.map k) (show G.map h ≫ G.map f = G.map k ≫ G.map g - from by simp only [← G.map_comp, comm]))) : IsLimit (PullbackCone.mk h k comm) := + by simp only [← G.map_comp, comm]))) : IsLimit (PullbackCone.mk h k comm) := isLimitOfReflects G ((PullbackCone.isLimitMapConeEquiv (PullbackCone.mk _ _ comm) G).2 l) @@ -222,7 +222,7 @@ def isColimitPushoutCoconeMapOfIsColimit [PreservesColimit (span f g) G] /-- The property of reflecting pushouts expressed in terms of binary cofans. -/ def isColimitOfIsColimitPushoutCoconeMap [ReflectsColimit (span f g) G] (l : IsColimit (PushoutCocone.mk (G.map h) (G.map k) (show G.map f ≫ G.map h = - G.map g ≫ G.map k from by simp only [← G.map_comp, comm]))) : + G.map g ≫ G.map k by simp only [← G.map_comp, comm]))) : IsColimit (PushoutCocone.mk h k comm) := isColimitOfReflects G ((isColimitMapCoconePushoutCoconeEquiv G comm).symm l) @@ -232,7 +232,7 @@ variable (f g) [PreservesColimit (span f g) G] morphisms of the pushout cocone is a colimit. -/ def isColimitOfHasPushoutOfPreservesColimit [i : HasPushout f g] : IsColimit (PushoutCocone.mk (G.map (pushout.inl _ _)) (G.map (@pushout.inr _ _ _ _ _ f g i)) - (show G.map f ≫ G.map (pushout.inl _ _) = G.map g ≫ G.map (pushout.inr _ _) from by + (show G.map f ≫ G.map (pushout.inl _ _) = G.map g ≫ G.map (pushout.inr _ _) by simp only [← G.map_comp, pushout.condition])) := isColimitPushoutCoconeMapOfIsColimit G _ (pushoutIsPushout f g) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean index 705894aae5d3af..31af169e54f790 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean @@ -323,7 +323,7 @@ instance epi_coprod_to_pushout {C : Type*} [Category* C] {X Y Z : C} (f : X ⟶ /-- The pushout of `f, g` is also the pullback of `h ≫ f, h ≫ g` for any epi `h`. -/ noncomputable def pushoutIsPushoutOfEpiComp (f : X ⟶ Y) (g : X ⟶ Z) (h : W ⟶ X) [Epi h] [HasPushout f g] : IsColimit (PushoutCocone.mk (pushout.inl f g) (pushout.inr f g) - (show (h ≫ f) ≫ pushout.inl f g = (h ≫ g) ≫ pushout.inr f g from by + (show (h ≫ f) ≫ pushout.inl f g = (h ≫ g) ≫ pushout.inr f g by simp only [Category.assoc]; rw [cancel_epi]; exact pushout.condition)) := PushoutCocone.isColimitOfEpiComp f g h _ (colimit.isColimit (span f g)) diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean index aac973d31a57db..5d25f8c3a90171 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean @@ -278,7 +278,7 @@ theorem toSubgraph_adj_snd {u v} (w : G.Walk u v) (h : ¬ w.Nil) : w.toSubgraph. theorem toSubgraph_adj_penultimate {u v} (w : G.Walk u v) (h : ¬ w.Nil) : w.toSubgraph.Adj w.penultimate v := by rw [not_nil_iff_lt_length] at h - simpa [show w.length - 1 + 1 = w.length from by lia] + simpa [show w.length - 1 + 1 = w.length by lia] using w.toSubgraph_adj_getVert (by lia : w.length - 1 < w.length) theorem toSubgraph_adj_iff {u v u' v'} (w : G.Walk u v) : @@ -391,7 +391,7 @@ lemma neighborSet_toSubgraph_endpoint {u v} {p : G.Walk u v} lemma neighborSet_toSubgraph_internal {u} {i : ℕ} {p : G.Walk u v} (hp : p.IsPath) (h : i ≠ 0) (h' : i < p.length) : p.toSubgraph.neighborSet (p.getVert i) = {p.getVert (i - 1), p.getVert (i + 1)} := by - have hadj1 := ((show i - 1 + 1 = i from by lia) ▸ + have hadj1 := ((show i - 1 + 1 = i by lia) ▸ p.toSubgraph_adj_getVert (by lia : (i - 1) < p.length)).symm ext v simp_all only [ne_eq, Subgraph.mem_neighborSet, Set.mem_insert_iff, Set.mem_singleton_iff, @@ -441,7 +441,7 @@ lemma neighborSet_toSubgraph_endpoint {u} {p : G.Walk u u} (hpc : p.IsCycle) : lemma neighborSet_toSubgraph_internal {u} {i : ℕ} {p : G.Walk u u} (hpc : p.IsCycle) (h : i ≠ 0) (h' : i < p.length) : p.toSubgraph.neighborSet (p.getVert i) = {p.getVert (i - 1), p.getVert (i + 1)} := by - have hadj1 := ((show i - 1 + 1 = i from by lia) ▸ + have hadj1 := ((show i - 1 + 1 = i by lia) ▸ p.toSubgraph_adj_getVert (by lia : (i - 1) < p.length)).symm ext v simp_all only [ne_eq, Subgraph.mem_neighborSet, Set.mem_insert_iff, Set.mem_singleton_iff, diff --git a/Mathlib/Combinatorics/SimpleGraph/Matching.lean b/Mathlib/Combinatorics/SimpleGraph/Matching.lean index 376f0441c1051e..87b8654c30b185 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Matching.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Matching.lean @@ -519,7 +519,7 @@ lemma IsCycles.reachable_deleteEdges [Finite V] (hadj : G.Adj v w) simp only [Walk.toSubgraph, singletonSubgraph_le_iff, subgraphOfAdj_verts, Set.mem_insert_iff, Set.mem_singleton_iff, or_true, sup_of_le_left] exact (Subgraph.spanningCoe_subgraphOfAdj hadj).symm - rw [show G.deleteEdges {s(v, w)} = G \ fromEdgeSet {s(v, w)} from by rfl] + rw [show G.deleteEdges {s(v, w)} = G \ fromEdgeSet {s(v, w)} by rfl] exact this ▸ (hcyc.reachable_sdiff_toSubgraph_spanningCoe hadj.toWalk (Walk.IsPath.of_adj hadj)).symm @@ -613,14 +613,14 @@ lemma Subgraph.IsPerfectMatching.symmDiff_of_isAlternating (hM : M.IsPerfectMatc · grind · obtain ⟨w'', hw''⟩ := hG'cyc.other_adj_of_adj hr.1 by_contra! hc - simp_all [show M.Adj v y ↔ ¬M.Adj v w' from by simpa using hG' hc hr.1 hw'.2] + simp_all [show M.Adj v y ↔ ¬M.Adj v w' by simpa using hG' hc hr.1 hw'.2] · use w simp only [Subgraph.top_adj, SimpleGraph.sup_adj, sdiff_adj, Subgraph.spanningCoe_adj, hw.1, h, not_false_eq_true, and_self, not_true_eq_false, or_false, true_and] rintro y (hl | hr) · exact hw.2 _ hl.1 · have ⟨w', hw'⟩ := hG'cyc.other_adj_of_adj hr.1 - simp_all [show M.Adj v y ↔ ¬M.Adj v w' from by simpa using hG' hw'.1 hr.1 hw'.2] + simp_all [show M.Adj v y ↔ ¬M.Adj v w' by simpa using hG' hw'.1 hr.1 hw'.2] lemma Subgraph.IsPerfectMatching.isAlternating_symmDiff_left {M' : Subgraph G'} (hM : M.IsPerfectMatching) (hM' : M'.IsPerfectMatching) : diff --git a/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean b/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean index 28ff818b96ad57..d80e862c7214c6 100644 --- a/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean +++ b/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean @@ -200,7 +200,7 @@ theorem isMultiplyPreprimitive_succ_iff_ofStabilizer simp only rw [← Nat.cast_one, ← Nat.cast_add, ← hs] apply congr_arg₂ _ _ rfl - rw [show s = g⁻¹ • s' from by simp [hs'], + rw [show s = g⁻¹ • s' by simp [hs'], ← Set.image_smul, (MulAction.injective g⁻¹).encard_image, hst] rw [Set.encard_insert_of_notMem, Subtype.coe_injective.encard_image, ENat.coe_one] exact notMem_val_image M t diff --git a/Mathlib/LinearAlgebra/JordanChevalley.lean b/Mathlib/LinearAlgebra/JordanChevalley.lean index 49f61b5a236dbe..cfea752c5ae0eb 100644 --- a/Mathlib/LinearAlgebra/JordanChevalley.lean +++ b/Mathlib/LinearAlgebra/JordanChevalley.lean @@ -94,7 +94,7 @@ theorem isNilpotent_isSemisimple_unique [PerfectField K] have hsf : Commute s (n₁ + s₁) := heq ▸ hc.symm.add_right (Commute.refl s) have hnf : Commute n (n₁ + s₁) := heq ▸ (Commute.refl n).add_right hc have hnil : IsNilpotent (s - s₀) := by - rw [show s - s₀ = n₀ - n from by grind] + rw [show s - s₀ = n₀ - n by grind] exact (commute_of_mem_adjoin_singleton_of_commute hn₀ hnf).symm.isNilpotent_sub hn₀_nil hn have hss : (s - s₀).IsSemisimple := hs.sub_of_commute (commute_of_mem_adjoin_singleton_of_commute hs₀ hsf) hs₀_ss diff --git a/Mathlib/LinearAlgebra/Projectivization/Action.lean b/Mathlib/LinearAlgebra/Projectivization/Action.lean index 7ff05dfca850b4..4b1cbe2b8ea2a1 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Action.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Action.lean @@ -146,7 +146,7 @@ instance specialLinearGroup_is_two_pretransitive : suffices (b.repr D.rep) ⟨D.rep, hD_mem⟩ = 1 by rw [this, Module.Basis.extend_apply_self, Units.smul_def] module - nth_rewrite 1 [show D.rep = (⟨D.rep, hD_mem⟩ : s) from by rfl] + nth_rewrite 1 [show D.rep = (⟨D.rep, hD_mem⟩ : s) by rfl] rw [← Module.Basis.extend_apply_self, Module.Basis.repr_self] simp · rw [smul_mk, mk_eq_mk_iff, LinearEquiv.smul_def] @@ -156,7 +156,7 @@ instance specialLinearGroup_is_two_pretransitive : suffices (b.repr D'.rep) ⟨D.rep, hD_mem⟩ = 0 by rw [Module.Basis.extend_apply_self] simp [this] - nth_rewrite 1 [show D'.rep = (⟨D'.rep, hD'_mem⟩ : s) from by rfl] + nth_rewrite 1 [show D'.rep = (⟨D'.rep, hD'_mem⟩ : s) by rfl] rw [← Module.Basis.extend_apply_self, Module.Basis.repr_self] apply Finsupp.single_eq_of_ne simp only [ne_eq, ← Subtype.coe_inj] diff --git a/Mathlib/RingTheory/HopfAlgebra/Convolution.lean b/Mathlib/RingTheory/HopfAlgebra/Convolution.lean index ef72940b1e6023..aae1f434c68830 100644 --- a/Mathlib/RingTheory/HopfAlgebra/Convolution.lean +++ b/Mathlib/RingTheory/HopfAlgebra/Convolution.lean @@ -115,7 +115,7 @@ lemma comul_right_inv : toConv δ * toConv 𝑭 = 1 := by _ = δ ∘ₗ (toConv id * toConv 𝑺).ofConv := by simp [LinearMap.convMul_def] _ = δ ∘ₗ (1 : WithConv (C →ₗ[R] C)).ofConv := by rw [id_mul_antipode] _ = η ∘ₗ ε := by - simp [LinearMap.convOne_def, show (δ ∘ₗ η : R →ₗ[R] C ⊗[R] C) = η from by ext; simp; rfl, + simp [LinearMap.convOne_def, show (δ ∘ₗ η : R →ₗ[R] C ⊗[R] C) = η by ext; simp; rfl, ← comp_assoc] end LinearMap diff --git a/Mathlib/Topology/Algebra/Monoid.lean b/Mathlib/Topology/Algebra/Monoid.lean index b175611ea822d6..fc1387005e15c0 100644 --- a/Mathlib/Topology/Algebra/Monoid.lean +++ b/Mathlib/Topology/Algebra/Monoid.lean @@ -90,8 +90,8 @@ instance ContinuousMul.to_continuousSMul : ContinuousSMul M M := @[to_additive] instance ContinuousMul.to_continuousSMul_op : ContinuousSMul Mᵐᵒᵖ M := - ⟨show Continuous ((fun p : M × M => p.1 * p.2) ∘ Prod.swap ∘ Prod.map MulOpposite.unop id) from - by fun_prop⟩ + ⟨show Continuous ((fun p : M × M => p.1 * p.2) ∘ Prod.swap ∘ Prod.map MulOpposite.unop id) by + fun_prop⟩ @[to_additive] theorem ContinuousMul.induced {α : Type*} {β : Type*} {F : Type*} [FunLike F α β] [Mul α] diff --git a/Mathlib/Topology/Compactification/OnePoint/Basic.lean b/Mathlib/Topology/Compactification/OnePoint/Basic.lean index 2640e0361b0fa5..ed57d3affd569b 100644 --- a/Mathlib/Topology/Compactification/OnePoint/Basic.lean +++ b/Mathlib/Topology/Compactification/OnePoint/Basic.lean @@ -589,7 +589,7 @@ noncomputable def equivOfIsEmbeddingOfRangeEq : exact (isClosed_compl_iff.mpr hU₂).isCompact let e : OnePoint X ≃ Y := { toFun := fun p ↦ p.elim y f - invFun := fun q ↦ if hq : q = y then ∞ else ↑(show q ∈ range f from by simpa [hy]).choose + invFun := fun q ↦ if hq : q = y then ∞ else ↑(show q ∈ range f by simpa [hy]).choose left_inv := fun p ↦ by induction p using OnePoint.rec with | infty => simp From 5715d56e4663ff3c48097b3c24d10a5c5bab7ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hagb=20=28Junyu=20Guo=20=E9=83=AD=E4=BF=8A=E4=BD=99=29?= Date: Mon, 13 Jul 2026 10:03:54 +0000 Subject: [PATCH 0752/1300] feat(Data/Finsupp/MonomialOrder): weaken `IsOrderedCancelAddMonoid` to `IsOrderedAddMonoid` (#32829) `IsOrderedCancelAddMonoid syn` (`.iocam`) can be obtained from `IsOrderedAddMonoid syn` and other fields. --- Mathlib/Data/Finsupp/MonomialOrder.lean | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/Finsupp/MonomialOrder.lean b/Mathlib/Data/Finsupp/MonomialOrder.lean index 2c8b742bff7349..859628c5d6b8a9 100644 --- a/Mathlib/Data/Finsupp/MonomialOrder.lean +++ b/Mathlib/Data/Finsupp/MonomialOrder.lean @@ -66,7 +66,7 @@ structure MonomialOrder (σ : Type*) where /-- `syn` is linearly ordered -/ linearOrderSyn : LinearOrder syn := by infer_instance /-- `syn` is a linearly ordered cancellative additive commutative monoid -/ - isOrderedCancelAddMonoid_syn : IsOrderedCancelAddMonoid syn := by infer_instance + isOrderedAddMonoid_syn : IsOrderedAddMonoid syn := by infer_instance /-- the additive equivalence from `σ →₀ ℕ` to `syn` -/ toSyn : (σ →₀ ℕ) ≃+ syn /-- `toSyn` is monotone -/ @@ -75,20 +75,26 @@ structure MonomialOrder (σ : Type*) where wellFoundedLT_syn : WellFoundedLT syn := by infer_instance attribute [instance] MonomialOrder.addCommMonoidSyn MonomialOrder.linearOrderSyn - MonomialOrder.isOrderedCancelAddMonoid_syn MonomialOrder.wellFoundedLT_syn + MonomialOrder.isOrderedAddMonoid_syn MonomialOrder.wellFoundedLT_syn @[deprecated (since := "2026-07-07")] alias acm := MonomialOrder.addCommMonoidSyn @[deprecated (since := "2026-07-07")] alias lo := MonomialOrder.linearOrderSyn -@[deprecated (since := "2026-07-07")] alias iocam := MonomialOrder.isOrderedCancelAddMonoid_syn - @[deprecated (since := "2026-07-07")] alias wf := MonomialOrder.wellFoundedLT_syn namespace MonomialOrder variable {σ : Type*} (m : MonomialOrder σ) +instance : AddCancelCommMonoid m.syn where + add_left_cancel := m.toSyn.symm.injective.isLeftCancelAdd _ (map_add _) |>.add_left_cancel + +instance isOrderedCancelAddMonoid_syn : IsOrderedCancelAddMonoid m.syn := + IsOrderedAddMonoid.toIsOrderedCancelAddMonoid' + +@[deprecated (since := "2026-07-07")] alias iocam := MonomialOrder.isOrderedCancelAddMonoid_syn + lemma le_add_right (a b : σ →₀ ℕ) : m.toSyn a ≤ m.toSyn a + m.toSyn b := by rw [← map_add] From b883e5758cefe396784b08a8444fbdc322737b5f Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Mon, 13 Jul 2026 10:03:56 +0000 Subject: [PATCH 0753/1300] feat(Data/Multiset): add the Multiset version of `List.find?` (#40326) This is often more convenient (and computationally more efficient) than using `Multiset.choose`, since it avoids us having to do a preliminary pass over the set to determine if any elements satisfy the predicate. While it doesn't make any difference since `Finsupp` is (currently) noncomputable, we use this to implement `Finsupp.embDomain` more simply. The motivation for this def is to efficiently define `DFinsupp.embDomain`. --- Mathlib.lean | 2 + Mathlib/Data/Finsupp/Basic.lean | 2 +- Mathlib/Data/Finsupp/Defs.lean | 31 +++----- Mathlib/Data/List/Find.lean | 39 +++++++++++ Mathlib/Data/Multiset/Find.lean | 109 +++++++++++++++++++++++++++++ Mathlib/Data/Set/Subsingleton.lean | 4 ++ 6 files changed, 164 insertions(+), 23 deletions(-) create mode 100644 Mathlib/Data/List/Find.lean create mode 100644 Mathlib/Data/Multiset/Find.lean diff --git a/Mathlib.lean b/Mathlib.lean index 5fac66204eba26..2ef8861921c2af 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4064,6 +4064,7 @@ public import Mathlib.Data.List.DropRight public import Mathlib.Data.List.Duplicate public import Mathlib.Data.List.Enum public import Mathlib.Data.List.FinRange +public import Mathlib.Data.List.Find public import Mathlib.Data.List.Flatten public import Mathlib.Data.List.Fold public import Mathlib.Data.List.Forall2 @@ -4140,6 +4141,7 @@ public import Mathlib.Data.Multiset.Dedup public import Mathlib.Data.Multiset.Defs public import Mathlib.Data.Multiset.DershowitzManna public import Mathlib.Data.Multiset.Filter +public import Mathlib.Data.Multiset.Find public import Mathlib.Data.Multiset.FinsetOps public import Mathlib.Data.Multiset.Fintype public import Mathlib.Data.Multiset.Fold diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index ff4e89bf70c22e..063fcb3498d22a 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -1224,7 +1224,7 @@ theorem extendDomain_eq_embDomain_subtype (f : Subtype P →₀ M) : by_cases h : P a · refine Eq.trans ?_ (embDomain_apply_self (.subtype P) f (Subtype.mk a h)).symm simp [h] - · simp [embDomain, h] + · rw [embDomain_notin_range] <;> simp [*] theorem support_extendDomain_subset (f : Subtype P →₀ M) : ↑(f.extendDomain).support ⊆ {x | P x} := by diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 67dea8abf8c631..7e9bf12623e815 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -6,6 +6,7 @@ Authors: Johannes Hölzl, Kim Morrison module public import Mathlib.Algebra.FiniteSupport.Defs +public import Mathlib.Data.Multiset.Find /-! # Type of functions with finite support @@ -407,22 +408,12 @@ is the finitely supported function whose value at `f a : β` is `v a`. For a `b : β` outside the range of `f`, it is zero. -/ def embDomain (f : α ↪ β) (v : α →₀ M) : β →₀ M where support := v.support.map f - toFun a₂ := + toFun b := haveI := Classical.decEq β - if h : a₂ ∈ v.support.map f then - v - (v.support.choose (fun a₁ => f a₁ = a₂) - (by - rcases Finset.mem_map.1 h with ⟨a, ha, rfl⟩ - exact ExistsUnique.intro a ⟨ha, rfl⟩ fun b ⟨_, hb⟩ => f.injective hb)) - else 0 - mem_support_toFun a₂ := by - dsimp - split_ifs with h - · simp only [h, true_iff] - rw [← notMem_support_iff, not_not] - classical apply Finset.choose_mem - · simp only [h, not_true_eq_false] + match v.support.1.find? (fun a => f a = b) (by intro x; grind) with + | some a => v a + | none => 0 + mem_support_toFun a₂ := by grind @[simp] theorem support_embDomain (f : α ↪ β) (v : α →₀ M) : (embDomain f v).support = v.support.map f := @@ -436,18 +427,14 @@ open scoped Classical in @[grind =] theorem embDomain_apply (f : α ↪ β) (v : α →₀ M) (b : β) : embDomain f v b = if h : ∃ a, f a = b then v h.choose else 0 := by - simp only [embDomain, mem_map, mem_support_iff, coe_mk] + simp only [embDomain, coe_mk] -- TODO: investigate why `grind` needs `split_ifs` first; this should never happen. split_ifs <;> grind @[simp, grind =] theorem embDomain_apply_self (f : α ↪ β) (v : α →₀ M) (a : α) : embDomain f v (f a) = v a := by - classical - simp_rw [embDomain, coe_mk, mem_map'] - split_ifs with h - · refine congr_arg (v : α → M) (f.inj' ?_) - exact Finset.choose_property (fun a₁ => f a₁ = f a) _ _ - · exact (notMem_support_iff.1 h).symm + simp_rw [embDomain, coe_mk] + grind @[grind =>] theorem embDomain_notin_range (f : α ↪ β) (v : α →₀ M) (a : β) (h : a ∉ Set.range f) : diff --git a/Mathlib/Data/List/Find.lean b/Mathlib/Data/List/Find.lean new file mode 100644 index 00000000000000..524c0314edca33 --- /dev/null +++ b/Mathlib/Data/List/Find.lean @@ -0,0 +1,39 @@ +/- +Copyright (c) 2026 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ +module + +public import Mathlib.Data.Set.Subsingleton + +/-! +# Lemmas about `List.find?` +-/ + +public section + +namespace List +variable {α : Type*} + +/-- If there is at most one element satisfying `p`, then `find?` agrees on permuted lists. -/ +theorem find?_eq_find?_of_perm {p : α → Bool} {l₁ l₂ : List α} + (h : l₁.Perm l₂) (hp : {x ∈ l₁ | p x}.Subsingleton) : + l₁.find? p = l₂.find? p := by + induction h with + | nil => rfl + | cons x _ ih => + grind + | swap x y l => + dsimp [Set.Subsingleton] at hp + by_cases p x <;> by_cases p y <;> grind + | trans _ _ ih1 ih2 => + refine (ih1 ?_).trans (ih2 ?_) <;> grind + +/-- If two predicates agree on all the elements, so does `find?`. -/ +@[congr] +theorem find?_congr {p₁ p₂ : α → Bool} {l : List α} (h : ∀ x ∈ l, p₁ x = p₂ x) : + l.find? p₁ = l.find? p₂ := by + induction l with grind + +end List diff --git a/Mathlib/Data/Multiset/Find.lean b/Mathlib/Data/Multiset/Find.lean new file mode 100644 index 00000000000000..298c7d93e52245 --- /dev/null +++ b/Mathlib/Data/Multiset/Find.lean @@ -0,0 +1,109 @@ +/- +Copyright (c) 2026 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ +module +public import Mathlib.Data.List.Find +public import Mathlib.Data.Multiset.AddSub +public import Mathlib.Data.Multiset.Basic +public import Mathlib.Data.Set.Subsingleton + +/-! +# Finding subsingleton elements within multisets + +This module provides `Multiset.find? s p ⋯`, which lifts `List.find?` to multisets. +-/ + +public section + +namespace Multiset +variable {α : Type*} (p : α → Prop) [DecidablePred p] + +/-- `s.find? p ⋯` finds the subsingleton element of `s` satisfying the condition `p`, if one exists. + +This is the multiset version of `List.find?`, +and is like `Multiset.choose`, but `Option`-valued. -/ +@[expose] def find? (s : Multiset α) : {x ∈ s | p x}.Subsingleton → Option α := + Quotient.recOn s (fun l _ => l.find? p) fun l₁ l₂ h => by + unfold Eq.ndrec + rw [eqRec_eq_cast, cast_eq_iff_heq] + refine Function.hfunext ?_ (fun hp₁ hp₂ _ ↦ heq_of_eq ?_) + · congr! + exact Quotient.sound h + refine List.find?_eq_find?_of_perm h ?_ + simpa using hp₁ + +@[simp, grind =] +theorem find?_coe (l : List α) (hp) : + (l : Multiset α).find? p hp = l.find? (fun a => p a) := rfl + +theorem find?_some {a : α} {s : Multiset α} {hp} : + s.find? p hp = some a → p a := by + induction s using Quotient.inductionOn with | _ l + simp only [quot_mk_to_coe, find?_coe _ _ hp] + simpa using l.find?_some (p := (p ·)) + +@[simp] +theorem find?_zero : (0 : Multiset α).find? p (by simp) = none := rfl + +@[simp] +theorem find?_cons (a : α) (s : Multiset α) (hp) : + (cons a s).find? p hp = if h : p a then some a else s.find? p (by grind) := by + induction s using Quotient.inductionOn + simp only [quot_mk_to_coe, cons_coe] + grind + +@[simp] +theorem find?_singleton (a : α) (hp) : + ({a} : Multiset α).find? p hp = if p a then some a else none := + find?_cons _ _ _ _ + +@[simp] +theorem find?_add (s t : Multiset α) (hp) : + (s + t).find? p hp = + (s.find? p (hp.anti <| by grind)).or (t.find? p (hp.anti <| by grind)) := by + induction s, t using Quotient.inductionOn₂ + exact List.find?_append + +variable {p} in +@[simp, grind =] +theorem find?_eq_some_iff {a : α} {s : Multiset α} (hp) : + s.find? p hp = some a ↔ a ∈ s ∧ p a := by + induction s using Multiset.induction_on with + | empty => simp + | cons x s ih => + rw [find?_cons] + split + · dsimp [Set.Subsingleton] at hp + specialize hp ⟨mem_cons_self _ _, ‹p x›⟩ + grind + · simp_rw [ih] + grind + +variable {p} in +@[simp, grind =] +theorem find?_eq_none_iff {s : Multiset α} (hp) : + s.find? p hp = none ↔ ∀ a ∈ s, ¬ p a := by + induction s using Multiset.induction_on with + | empty => simp + | cons x s ih => + rw [find?_cons] + dsimp [Set.Subsingleton] at hp + grind + +/-- If two predicates agree on all the elements, so does `find?`. -/ +@[congr] +theorem find?_congr {p₁ p₂ : α → Prop} [DecidablePred p₁] [DecidablePred p₂] {s : Multiset α} + (hp₁ : {x ∈ s | p₁ x}.Subsingleton) (h : ∀ x ∈ s, p₁ x ↔ p₂ x) : + s.find? p₁ hp₁ = s.find? p₂ + (by simp_rw +contextual [← exists_prop, ← h, exists_prop, hp₁]) := by + induction s using Quotient.ind with simp +contextual [h] + +theorem find?_eq_choose {s : Multiset α} (hp : ∃! x, x ∈ s ∧ p x) : + s.find? p hp.setSubsingleton = some (s.choose p hp) := by + ext a + refine find?_eq_some_iff _ |>.trans ?_ + simp only [Option.some.injEq, choose_eq_iff] + +end Multiset diff --git a/Mathlib/Data/Set/Subsingleton.lean b/Mathlib/Data/Set/Subsingleton.lean index 948c01f09b8c53..3af37eac7e4c0b 100644 --- a/Mathlib/Data/Set/Subsingleton.lean +++ b/Mathlib/Data/Set/Subsingleton.lean @@ -139,6 +139,10 @@ lemma Subsingleton.denselyOrdered {s : Set α} [LT α] (hs : s.Subsingleton) : have := (subsingleton_coe _).mpr hs ⟨fun _ _ h ↦ ⟨_, h.trans_eq (Subsingleton.elim _ _), h⟩⟩ +theorem _root_.ExistsUnique.setSubsingleton {α : Type*} {p : α → Prop} (h : ExistsUnique p) : + {x | p x}.Subsingleton := + fun _ hx _ hy => h.unique hx hy + end Subsingleton /-! ### Nontrivial -/ From a7a0864217d023035b6915bf6fcd07cc9e3161d0 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Mon, 13 Jul 2026 10:57:21 +0000 Subject: [PATCH 0754/1300] feat(Algebra): localization preserves unique factorization (#33832) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 2 + .../BigOperators/Group/Finset/Basic.lean | 7 ++ Mathlib/Algebra/GroupWithZero/Associated.lean | 33 +++++++- .../GroupTheory/MonoidLocalization/Basic.lean | 11 +++ .../MonoidLocalization/Divisibility.lean | 40 +++++++++ .../UniqueFactorization.lean | 84 +++++++++++++++++++ Mathlib/RingTheory/Ideal/UFD.lean | 3 +- Mathlib/RingTheory/Localization/Defs.lean | 12 +-- .../Localization.lean | 49 +---------- 9 files changed, 180 insertions(+), 61 deletions(-) create mode 100644 Mathlib/GroupTheory/MonoidLocalization/Divisibility.lean create mode 100644 Mathlib/GroupTheory/MonoidLocalization/UniqueFactorization.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2ef8861921c2af..d1e53da0a2518c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4810,12 +4810,14 @@ public import Mathlib.GroupTheory.MonoidLocalization.Away public import Mathlib.GroupTheory.MonoidLocalization.Basic public import Mathlib.GroupTheory.MonoidLocalization.Cardinality public import Mathlib.GroupTheory.MonoidLocalization.DivPairs +public import Mathlib.GroupTheory.MonoidLocalization.Divisibility public import Mathlib.GroupTheory.MonoidLocalization.Finite public import Mathlib.GroupTheory.MonoidLocalization.GrothendieckGroup public import Mathlib.GroupTheory.MonoidLocalization.Lemmas public import Mathlib.GroupTheory.MonoidLocalization.Maps public import Mathlib.GroupTheory.MonoidLocalization.MonoidWithZero public import Mathlib.GroupTheory.MonoidLocalization.Order +public import Mathlib.GroupTheory.MonoidLocalization.UniqueFactorization public import Mathlib.GroupTheory.Nilpotent public import Mathlib.GroupTheory.NoncommCoprod public import Mathlib.GroupTheory.NoncommPiCoprod diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index 2d6a839ae18056..a829d75b1e7635 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -1108,6 +1108,13 @@ theorem prod_sum {ι : Type*} [CommMonoid M] (f : ι → Multiset M) (s : Finset end Multiset +@[to_additive (attr := simp)] +lemma IsUnit.multisetProd_iff [CommMonoid M] {s : Multiset M} : + IsUnit s.prod ↔ ∀ a ∈ s, IsUnit a := by + induction s using Multiset.induction with + | empty => simp + | cons a s ih => simpa using fun _ ↦ ih + @[to_additive (attr := simp)] lemma IsUnit.prod_iff [CommMonoid M] {f : ι → M} : IsUnit (∏ a ∈ s, f a) ↔ ∀ a ∈ s, IsUnit (f a) := by diff --git a/Mathlib/Algebra/GroupWithZero/Associated.lean b/Mathlib/Algebra/GroupWithZero/Associated.lean index b37d8f469c09af..585655daa2f27b 100644 --- a/Mathlib/Algebra/GroupWithZero/Associated.lean +++ b/Mathlib/Algebra/GroupWithZero/Associated.lean @@ -730,12 +730,37 @@ end Associates section CommMonoidWithZero -theorem dvdNotUnit_of_dvdNotUnit_associated [CommMonoidWithZero M] [Nontrivial M] {p q r : M} +variable [CommMonoidWithZero M] {p q r : M} + +theorem dvdNotUnit_of_dvdNotUnit_associated (h : DvdNotUnit p q) (h' : Associated q r) : DvdNotUnit p r := by - obtain ⟨u, rfl⟩ := Associated.symm h' + obtain ⟨u, rfl⟩ := h' + obtain ⟨hp, x, hx⟩ := h + refine ⟨hp, x * u, mt isUnit_of_mul_isUnit_left hx.1, ?_⟩ + rw [← mul_assoc, ← hx.right] + +alias Associated.dvdNotUnit_right := dvdNotUnit_of_dvdNotUnit_associated + +theorem Associated.dvdNotUnit_left (h : DvdNotUnit p r) (h' : Associated p q) : + DvdNotUnit q r := by + obtain ⟨u, rfl⟩ := h'.symm obtain ⟨hp, x, hx⟩ := h - refine ⟨hp, x * ↑u⁻¹, DvdNotUnit.not_unit ⟨u⁻¹.ne_zero, x, hx.left, mul_comm _ _⟩, ?_⟩ - rw [← mul_assoc, ← hx.right, mul_assoc, Units.mul_inv, mul_one] + have hq : q ≠ 0 := by simp_all + refine ⟨hq, x * u, mt isUnit_of_mul_isUnit_left hx.1, ?_⟩ + rw [mul_comm x, ← mul_assoc, ← hx.2] + +theorem Associated.dvdNotUnit_left_iff (h : Associated p q) : DvdNotUnit p r ↔ DvdNotUnit q r where + mp := (h.dvdNotUnit_left ·) + mpr := (h.symm.dvdNotUnit_left ·) + +theorem Associated.dvdNotUnit_right_iff (h : Associated q r) : DvdNotUnit p q ↔ DvdNotUnit p r where + mp := (h.dvdNotUnit_right ·) + mpr := (h.symm.dvdNotUnit_right ·) + +theorem Associated.acc_dvdNotUnit_iff (h : Associated p q) : + Acc DvdNotUnit p ↔ Acc DvdNotUnit q where + mp acc := .intro _ fun _r hr ↦ acc.inv (h.dvdNotUnit_right_iff.mpr hr) + mpr acc := .intro _ fun _r hr ↦ acc.inv (h.dvdNotUnit_right_iff.mp hr) end CommMonoidWithZero diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index 08a7a2e46461ca..3a7477ea43e9ef 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -885,6 +885,17 @@ variable {M N : Type*} [CommMonoid M] {S : Submonoid M} [CommMonoid N] @[to_additive] instance [IsCancelMul M] [Nontrivial M] : Nontrivial (Localization S) := (injective_iff <| Localization.monoidOf S).mpr (fun _ _ ↦ .all _) |>.nontrivial +/-- Any localization of a cancellative commutative monoid is cancellative. -/ +@[to_additive +/-- Any localization of a cancellative commutative additive monoid is cancellative. -/] +abbrev cancelCommMonoid {M N} [CancelCommMonoid M] {S : Submonoid M} + [CommMonoid N] (f : S.LocalizationMap N) : CancelCommMonoid N where + mul_left_cancel := f.isCancelMul.mul_left_cancel + +@[to_additive] instance {M} [CancelCommMonoid M] (S : Submonoid M) : + CancelCommMonoid (Localization S) := + (Localization.monoidOf S).cancelCommMonoid + @[to_additive] theorem subsingleton_of_subsingleton (f : LocalizationMap S N) [Subsingleton M] : Subsingleton N where allEq x y := by diff --git a/Mathlib/GroupTheory/MonoidLocalization/Divisibility.lean b/Mathlib/GroupTheory/MonoidLocalization/Divisibility.lean new file mode 100644 index 00000000000000..90ba9d85dfcff1 --- /dev/null +++ b/Mathlib/GroupTheory/MonoidLocalization/Divisibility.lean @@ -0,0 +1,40 @@ +/- +Copyright (c) 2026 Junyan Xu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Junyan Xu +-/ +module + +public import Mathlib.GroupTheory.MonoidLocalization.Basic + +import Mathlib.Algebra.Divisibility.Hom +import Mathlib.Algebra.Divisibility.Units + +/-! +# Divisibility in localizations of commutative monoids +-/ + +namespace Submonoid.LocalizationMap + +variable {M N : Type*} [CommMonoid M] {S : Submonoid M} [CommMonoid N] (f : LocalizationMap S N) + +public theorem map_isUnit_iff {m : M} : IsUnit (f m) ↔ ∃ s ∈ S, m ∣ s := by + refine ⟨fun h ↦ ?_, fun ⟨m, hm, dvd⟩ ↦ isUnit_of_dvd_unit (map_dvd _ dvd) (f.map_units ⟨m, hm⟩)⟩ + have ⟨s, hxs⟩ := isUnit_iff_dvd_one.mp h + have ⟨⟨r, s⟩, hrs⟩ := f.surj s + replace hrs := congr(f m * $hrs) + rw [← mul_assoc, ← hxs, one_mul, ← map_mul] at hrs + have ⟨s', eq⟩ := f.eq_iff_exists.mp hrs + exact ⟨s' * s, mul_mem s'.2 s.2, _, mul_left_comm _ m _ ▸ eq⟩ + +public theorem map_dvd_map {m₁ m₂ : M} : f m₁ ∣ f m₂ ↔ ∃ s ∈ S, m₁ ∣ s * m₂ where + mp := fun ⟨n, eq⟩ ↦ by + have ⟨⟨m, s⟩, hn⟩ := f.surj n + replace hn := congr(f m₁ * $hn) + rw [← mul_assoc, ← eq, ← map_mul, ← map_mul] at hn + have ⟨s', hs'⟩ := f.eq_iff_exists.mp hn + refine ⟨_, mul_mem s'.2 s.2, s' * m, ?_⟩ + rwa [mul_left_comm, mul_assoc, mul_comm s.1] + mpr := fun ⟨s, hs, dvd⟩ ↦ (f.map_units ⟨s, hs⟩).dvd_mul_left.mp (map_mul f .. ▸ map_dvd f dvd) + +end Submonoid.LocalizationMap diff --git a/Mathlib/GroupTheory/MonoidLocalization/UniqueFactorization.lean b/Mathlib/GroupTheory/MonoidLocalization/UniqueFactorization.lean new file mode 100644 index 00000000000000..4a65bc9e8b2ecb --- /dev/null +++ b/Mathlib/GroupTheory/MonoidLocalization/UniqueFactorization.lean @@ -0,0 +1,84 @@ +/- +Copyright (c) 2026 Junyan Xu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yongle Hu, Junyan Xu +-/ +module + +public import Mathlib.RingTheory.Localization.Defs +public import Mathlib.RingTheory.UniqueFactorizationDomain.Basic + +/-! # Localization preserves unique factorization + +## Main results + +* `UniqueFactorizationMonoid.of_isLocalization`: a localization of a unique factorization monoid + is still a unique factorization monoid. In particular, a localization of a UFD is a UFD provided + it is nontrivial. +-/ + +@[expose] public section + +variable {M N : Type*} + +namespace Submonoid.LocalizationMap + +variable [CommMonoidWithZero M] [CommMonoidWithZero N] {S : Submonoid M} + +theorem map_prime (f : S.LocalizationMap N) {m : M} (prime : Prime m) + (n0 : f m ≠ 0) (nu : ¬ IsUnit (f m)) : Prime (f m) := by + refine ⟨n0, nu, fun n₁ n₂ dvd ↦ ?_⟩ + have ⟨⟨m₁, s₁⟩, eq₁⟩ := f.surj n₁ + have ⟨⟨m₂, s₂⟩, eq₂⟩ := f.surj n₂ + have := (f.map_units (s₁ * s₂)).dvd_mul_right.mpr dvd + rw [Submonoid.mul_def, map_mul, mul_mul_mul_comm, eq₁, eq₂, ← map_mul, f.map_dvd_map] at this + have ⟨s, hs, dvd⟩ := this + rw [← mul_assoc] at dvd + obtain dvd | dvd := prime.dvd_or_dvd dvd + all_goals have := map_dvd f dvd + · rw [map_mul, (f.map_units ⟨s, hs⟩).dvd_mul_left, ← eq₁, (f.map_units s₁).dvd_mul_right] at this + exact .inl this + · rw [← eq₂, (f.map_units s₂).dvd_mul_right] at this; exact .inr this + +theorem eq_isUnit_map_mul_irreducible_of_irreducible_map [WfDvdMonoid M] (f : S.LocalizationMap N) + {m : M} (hm : Irreducible (f m)) : ∃ u m' : M, IsUnit (f u) ∧ Irreducible m' ∧ m = u * m' := by + induction m using WfDvdMonoid.induction_on_irreducible with + | zero => exact (hm.ne_zero f.map_zero).elim + | unit u hu => exact (hm.not_isUnit (hu.map f)).elim + | mul a i ha0 hi ha => + rw [map_mul, irreducible_mul_iff] at hm + obtain hia | hai := hm + · exact ⟨a, i, hia.2, hi, mul_comm ..⟩ + · obtain ⟨u, m', hu, hm', rfl⟩ := ha hai.1 + exact ⟨u * i, m', by simpa using hu.mul hai.2, hm', by ac_rfl⟩ + +open UniqueFactorizationMonoid in +theorem uniqueFactorizationMonoid (f : S.LocalizationMap N) + [UniqueFactorizationMonoid M] : UniqueFactorizationMonoid N := + have := f.isCancelMulZero + .of_exists_prime_factors fun n hn ↦ by + classical + have ⟨⟨m, s⟩, eq⟩ := f.surj n + use ((factors m).map f).filter (¬ IsUnit ·) + rw [Ne, ← (f.map_units s).mul_left_eq_zero, eq] at hn + refine ⟨fun x hx ↦ ?_, .trans (eq ▸ ?_) ((associated_mul_unit_left _ _ (f.map_units s)))⟩ + · rw [Multiset.mem_filter, Multiset.mem_map] at hx + obtain ⟨p, hp, rfl⟩ := hx.1 + exact f.map_prime (prime_of_factor _ hp) + (mt (fun h ↦ eq_zero_of_zero_dvd <| h ▸ map_dvd f (dvd_of_mem_factors hp)) hn) hx.2 + · exact .trans (.trans (associated_unit_mul_right _ _ <| + IsUnit.multisetProd_iff.mpr fun x hx ↦ (Multiset.mem_filter.mp hx).2) <| .of_eq <| + (Multiset.prod_filter_mul_prod_filter_not _).trans (f.toMonoidHom.map_multiset_prod _).symm) + ((factors_prod (mt (by simp [·]) hn)).map f) + +end Submonoid.LocalizationMap + +variable [CommSemiring M] (S : Submonoid M) + +/-- A localization of a unique factorization monoid is still a unique factorization monoid. -/ +theorem UniqueFactorizationMonoid.of_isLocalization (N : Type*) [CommSemiring N] [Algebra M N] + [IsLocalization S N] [UniqueFactorizationMonoid M] : UniqueFactorizationMonoid N := + (IsLocalization.toLocalizationMap S N).uniqueFactorizationMonoid + +instance [UniqueFactorizationMonoid M] : UniqueFactorizationMonoid (Localization S) := + (Localization.monoidOf S).uniqueFactorizationMonoid diff --git a/Mathlib/RingTheory/Ideal/UFD.lean b/Mathlib/RingTheory/Ideal/UFD.lean index 5581830415eec3..87d8bc8ebec921 100644 --- a/Mathlib/RingTheory/Ideal/UFD.lean +++ b/Mathlib/RingTheory/Ideal/UFD.lean @@ -5,9 +5,10 @@ Authors: Yongle Hu -/ module +public import Mathlib.GroupTheory.MonoidLocalization.UniqueFactorization public import Mathlib.RingTheory.Ideal.KrullsHeightTheorem public import Mathlib.RingTheory.Localization.Away.Lemmas -public import Mathlib.RingTheory.UniqueFactorizationDomain.Localization +public import Mathlib.RingTheory.UniqueFactorizationDomain.Kaplansky /-! # UFD criteria via height `1` prime ideals and localization diff --git a/Mathlib/RingTheory/Localization/Defs.lean b/Mathlib/RingTheory/Localization/Defs.lean index 3c0cedffbbf9aa..2a6edce839a986 100644 --- a/Mathlib/RingTheory/Localization/Defs.lean +++ b/Mathlib/RingTheory/Localization/Defs.lean @@ -9,9 +9,9 @@ public import Mathlib.Algebra.BigOperators.Group.Finset.Defs public import Mathlib.Algebra.Regular.Basic public import Mathlib.Algebra.Ring.NonZeroDivisors public import Mathlib.Data.Fintype.Prod +public import Mathlib.GroupTheory.MonoidLocalization.Divisibility public import Mathlib.GroupTheory.MonoidLocalization.MonoidWithZero public import Mathlib.RingTheory.OreLocalization.Ring -public import Mathlib.Tactic.ApplyFun public import Mathlib.Tactic.Ring /-! @@ -186,14 +186,8 @@ theorem of_le_of_exists_dvd (N : Submonoid R) (h₁ : M ≤ N) (h₂ : ∀ n ∈ of_le M N h₁ fun n hn ↦ have ⟨m, hm, dvd⟩ := h₂ n hn isUnit_of_dvd_unit (map_dvd _ dvd) (map_units S ⟨m, hm⟩) -theorem algebraMap_isUnit_iff {x : R} : IsUnit (algebraMap R S x) ↔ ∃ m ∈ M, x ∣ m := by - refine ⟨fun h ↦ ?_, fun ⟨m, hm, dvd⟩ ↦ isUnit_of_dvd_unit (map_dvd _ dvd) (map_units S ⟨m, hm⟩)⟩ - have ⟨s, hxs⟩ := isUnit_iff_dvd_one.mp h - have ⟨⟨r, m⟩, hrm⟩ := surj M s - apply_fun (algebraMap R S x * ·) at hrm - rw [← mul_assoc, ← hxs, one_mul, ← map_mul] at hrm - have ⟨m', eq⟩ := (eq_iff_exists M S).mp hrm - exact ⟨m' * m, mul_mem m'.2 m.2, _, mul_left_comm _ x _ ▸ eq⟩ +theorem algebraMap_isUnit_iff {x : R} : IsUnit (algebraMap R S x) ↔ ∃ m ∈ M, x ∣ m := + (toLocalizationMap M S).map_isUnit_iff end diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean index 1c4b0fae487db3..768ea3322b1ac8 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Localization.lean @@ -1,50 +1,5 @@ -/- -Copyright (c) 2026 Yongle Hu. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Yongle Hu --/ module -public import Mathlib.RingTheory.Localization.Ideal -public import Mathlib.RingTheory.UniqueFactorizationDomain.Kaplansky +public import Mathlib.GroupTheory.MonoidLocalization.UniqueFactorization -/-! -# Localization of a UFD - -## Main results -* `UniqueFactorizationMonoid.localization` : The localization of a UFD is still a UFD. --/ - -public section - -namespace UniqueFactorizationMonoid - -variable {R : Type*} [CommRing R] [UniqueFactorizationMonoid R] [IsDomain R] - -/-- If `S` is the localization of a UFD `R`, then `S` is also a UFD. -/ -theorem of_isLocalization (M : Submonoid R) - (S : Type*) [CommRing S] [Algebra R S] [IsLocalization M S] : UniqueFactorizationMonoid S := by - by_cases h0 : 0 ∈ M - · have : Subsingleton S := IsLocalization.subsingleton h0 - exact of_subsingleton S - have hM : M ≤ nonZeroDivisors R := le_nonZeroDivisors_of_noZeroDivisors h0 - have : IsDomain S := IsLocalization.isDomain_of_le_nonZeroDivisors S hM - rw [UniqueFactorizationMonoid.iff_exists_prime_mem_of_isPrime] - intro p hpb _ - obtain ⟨x, hxp, hpx⟩ := Ideal.IsPrime.exists_mem_prime_of_ne_bot - inferInstance (IsLocalization.bot_lt_under_prime M S hM p hpb).ne' - use algebraMap R S x, hxp - rw [← Ideal.span_singleton_prime] - · rw [← Set.image_singleton, ← Ideal.map_span] - refine IsLocalization.isPrime_of_isPrime_disjoint M S _ - (Ideal.isPrime_span_singleton_of_prime hpx) ?_ - rw [← IsLocalization.map_algebraMap_ne_top_iff_disjoint M S] - intro h - exact Ideal.IsPrime.ne_top' (top_unique (h.symm.trans_le (by simpa [Ideal.map_span] using hxp))) - · simp [map_ne_zero_iff _ (IsLocalization.injective S hM), hpx.ne_zero] - -/-- The localization of a UFD is still a UFD. -/ -instance localization (M : Submonoid R) : UniqueFactorizationMonoid (Localization M) := - of_isLocalization M (Localization M) - -end UniqueFactorizationMonoid +deprecated_module (since := "2026-07-12") From f65b4ad3395cc684112fd1d1c633681822fec13c Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Mon, 13 Jul 2026 13:28:47 +0000 Subject: [PATCH 0755/1300] feat: convenience API for strict linear maps (#41250) Everything here follows from the AddGroup case, but it's convenient to have a more adapted bundling. --- Mathlib.lean | 1 + Mathlib/LinearAlgebra/Isomorphisms.lean | 2 + Mathlib/Topology/Maps/Strict/Group.lean | 16 ++--- Mathlib/Topology/Maps/Strict/Module.lean | 77 ++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 Mathlib/Topology/Maps/Strict/Module.lean diff --git a/Mathlib.lean b/Mathlib.lean index d1e53da0a2518c..6b50cfeeca50fe 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7991,6 +7991,7 @@ public import Mathlib.Topology.Maps.Proper.CompactlyGenerated public import Mathlib.Topology.Maps.Proper.UniversallyClosed public import Mathlib.Topology.Maps.Strict.Basic public import Mathlib.Topology.Maps.Strict.Group +public import Mathlib.Topology.Maps.Strict.Module public import Mathlib.Topology.MetricSpace.Algebra public import Mathlib.Topology.MetricSpace.Antilipschitz public import Mathlib.Topology.MetricSpace.Basic diff --git a/Mathlib/LinearAlgebra/Isomorphisms.lean b/Mathlib/LinearAlgebra/Isomorphisms.lean index 0d9eb915251ce8..1433a483660ca4 100644 --- a/Mathlib/LinearAlgebra/Isomorphisms.lean +++ b/Mathlib/LinearAlgebra/Isomorphisms.lean @@ -37,6 +37,8 @@ section IsomorphismLaws /-- The **first isomorphism law for modules**. The quotient of `M` by the kernel of `f` is linearly equivalent to the range of `f`. -/ noncomputable def quotKerEquivRange : (M ⧸ LinearMap.ker f) ≃ₗ[R] LinearMap.range f := + -- TODO: We should fix this definition so that `fₗ.quotKerEquivRange.toAddEquiv` is definitionally + -- equal to `QuotientAddGroup.quotientKerEquivRange f.toAddMonoidHom`. (LinearEquiv.ofInjective ((LinearMap.ker f).liftQ f <| le_rfl) <| ker_eq_bot.mp <| Submodule.ker_liftQ_eq_bot _ _ _ (le_refl (LinearMap.ker f))).trans (LinearEquiv.ofEq _ _ <| Submodule.range_liftQ _ _ _) diff --git a/Mathlib/Topology/Maps/Strict/Group.lean b/Mathlib/Topology/Maps/Strict/Group.lean index f199f927ff1b1e..e6ff0a60adfc03 100644 --- a/Mathlib/Topology/Maps/Strict/Group.lean +++ b/Mathlib/Topology/Maps/Strict/Group.lean @@ -29,7 +29,7 @@ strict maps. Namely, we provide: @[expose] public section -open Function Set Topology QuotientGroup +open Topology QuotientGroup namespace MonoidHom @@ -80,10 +80,10 @@ protected lemma isStrictMap_iff_isOpenQuotientMap_rangeRestrict : variable [TopologicalSpace G'] [IsTopologicalGroup G'] [TopologicalSpace H'] -/-- The product (in the sense of `Prod.map`) of group homomorphisms is strict if and only if each -of the homomorphisms is strict. -/ -@[to_additive isStrictMap_prodMap_iff /-- The product (in the sense of `Prod.map`) of additive group -homomorphisms is strict if and only if each of the homomorphisms is strict. -/] +/-- The product (in the sense of `MonoidHom.prodMap`) of group homomorphisms is strict if and only +if both homomorphisms are strict. -/ +@[to_additive isStrictMap_prodMap_iff /-- The product (in the sense of `AddMonoidHom.prodMap`) of +additive group homomorphisms is strict if and only if both homomorphisms are strict. -/] protected lemma isStrictMap_prodMap_iff : IsStrictMap (f.prodMap g) ↔ IsStrictMap f ∧ IsStrictMap g := by simp_rw [MonoidHom.isStrictMap_iff_isOpenQuotientMap_rangeRestrict] @@ -92,9 +92,9 @@ protected lemma isStrictMap_prodMap_iff : have eq : Φ ∘ (f.prodMap g).rangeRestrict = f.rangeRestrict.prodMap g.rangeRestrict := rfl rw [← Φ.comp_isOpenQuotientMap_iff, eq, MonoidHom.coe_prodMap, isOpenQuotientMap_prodMap_iff] -/-- The product (in the sense of `Prod.map`) of strict group homomorphisms is strict. -/ -@[to_additive isStrictMap_prodMap /-- The product (in the sense of `Prod.map`) of strict additive -group homomorphisms is strict. -/] +/-- The product (in the sense of `MonoidHom.prodMap`) of strict group homomorphisms is strict. -/ +@[to_additive isStrictMap_prodMap /-- The product (in the sense of `AddMonoidHom.prodMap`) of strict +additive group homomorphisms is strict. -/] protected lemma isStrictMap_prodMap (hf : IsStrictMap f) (hg : IsStrictMap g) : IsStrictMap (f.prodMap g) := MonoidHom.isStrictMap_prodMap_iff.mpr ⟨hf, hg⟩ diff --git a/Mathlib/Topology/Maps/Strict/Module.lean b/Mathlib/Topology/Maps/Strict/Module.lean new file mode 100644 index 00000000000000..d09323659f7103 --- /dev/null +++ b/Mathlib/Topology/Maps/Strict/Module.lean @@ -0,0 +1,77 @@ +/- +Copyright (c) 2026 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anatole Dedecker +-/ +module + +public import Mathlib.LinearAlgebra.Isomorphisms +public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Quotient +public import Mathlib.Topology.Algebra.Module.Equiv +public import Mathlib.Topology.Maps.Strict.Group + +/-! +# Strict linear maps + +In this file, we study continuous linear maps which are *strict* in the sense of +`Topology.IsStrictMap`. So far, all the results in this file are direct +adaptations from the theory of strict homomorphisms of topological additive groups. +-/ + +@[expose] public section + +open Topology + +namespace LinearMap + +variable {R S M N Nₗ M' Nₗ' : Type*} [Ring R] [Ring S] {σ : R →+* S} + [AddCommGroup M] [AddCommGroup N] [AddCommGroup Nₗ] [AddCommGroup M'] [AddCommGroup Nₗ'] + [Module R M] [Module S N] [Module R Nₗ] [Module R M'] [Module R Nₗ'] + {f : M →ₛₗ[σ] N} {fₗ : M →ₗ[R] Nₗ} {gₗ : M' →ₗ[R] Nₗ'} + [TopologicalSpace M] [TopologicalSpace N] [TopologicalSpace Nₗ] + +/-- A linear map `f : M → N` is strict if and only if the induced map `M ⧸ f.ker → N` is an +embedding. -/ +protected lemma isStrictMap_iff_isEmbedding_liftQ_ker : + IsStrictMap f ↔ IsEmbedding (f.ker.liftQ f le_rfl) := + f.toAddMonoidHom.isStrictMap_iff_isEmbedding_kerLift + +/-- A linear map `f : M → N` is strict if and only if the canonical isomorphism +`M ⧸ f.ker ≃ f.range` is a homeomorphism. -/ +protected lemma isStrictMap_iff_isHomeomorph_quotKerEquivRange : + IsStrictMap fₗ ↔ IsHomeomorph fₗ.quotKerEquivRange := by + -- Note: right now, this cannot easily be deduced from the `AddMonoidHom` statement, because + -- `fₗ.quotKerEquivRange.toAddEquiv` is not def-eq to + -- `QuotientAddGroup.quotientKerEquivRange fₗ.toAddMonoidHom`. This would require + -- fixing the definition of `LinearMap.quotKerEquivRange`. + simp_rw [isHomeomorph_iff_isStrictMap_bijective, EquivLike.bijective, and_true, + fₗ.ker.isQuotientMap_mkQ.isStrictMap_iff, IsEmbedding.subtypeVal.isStrictMap_iff] + rfl + +/-- The isomorphism of topological modules `M ⧸ f.ker ≃ f.range` given by a strict linear +map `f : M → N`. This is an avatar of the first isomorphism theorem. -/ +noncomputable def _root_.ContinuousLinearEquiv.quotKerEquivRange + (hf : IsStrictMap fₗ) : (M ⧸ fₗ.ker) ≃L[R] fₗ.range := + .ofIsHomeomorph fₗ.quotKerEquivRange (fₗ.isStrictMap_iff_isHomeomorph_quotKerEquivRange.mp hf) + +variable [IsTopologicalAddGroup M] + +/-- A linear map is strict if and only if its `rangeRestrict` is an open quotient map. -/ +protected lemma isStrictMap_iff_isOpenQuotientMap_rangeRestrict [RingHomSurjective σ] : + IsStrictMap f ↔ IsOpenQuotientMap f.rangeRestrict := + f.toAddMonoidHom.isStrictMap_iff_isOpenQuotientMap_rangeRestrict + +variable [TopologicalSpace M'] [IsTopologicalAddGroup M'] [TopologicalSpace Nₗ'] + +/-- The product (in the sense of `LinearMap.prodMap`) of linear maps is strict if and only if both +maps are strict. -/ +protected lemma isStrictMap_prodMap_iff : + IsStrictMap (fₗ.prodMap gₗ) ↔ IsStrictMap fₗ ∧ IsStrictMap gₗ := + AddMonoidHom.isStrictMap_prodMap_iff (f := fₗ.toAddMonoidHom) (g := gₗ.toAddMonoidHom) + +/-- The product (in the sense of `LinearMap.prodMap`) of strict linear maps is strict. -/ +protected lemma isStrictMap_prodMap (hf : IsStrictMap fₗ) + (hg : IsStrictMap gₗ) : IsStrictMap (fₗ.prodMap gₗ) := + LinearMap.isStrictMap_prodMap_iff.mpr ⟨hf, hg⟩ + +end LinearMap From 3977924c63176de352502cfd7f029dcb54efbc0a Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Mon, 13 Jul 2026 14:10:55 +0000 Subject: [PATCH 0756/1300] chore(Data/{W}Seq): cleanup flexible linter exceptions (#41672) This is mostly just restructuring combinators/case splits so that it's convenient to squeeze simps where appropriate. I've tried to clean-up and modernize the style a bit as well where possible. --- Mathlib/Data/Seq/Basic.lean | 136 +++++++++++++++-------------------- Mathlib/Data/WSeq/Basic.lean | 111 ++++++++++++++-------------- 2 files changed, 111 insertions(+), 136 deletions(-) diff --git a/Mathlib/Data/Seq/Basic.lean b/Mathlib/Data/Seq/Basic.lean index 64dcab304b8fa6..b45364cc18b8b7 100644 --- a/Mathlib/Data/Seq/Basic.lean +++ b/Mathlib/Data/Seq/Basic.lean @@ -37,9 +37,8 @@ theorem length'_of_not_terminates {s : Seq α} (h : ¬ s.Terminates) : s.length' = ⊤ := by simp [length', h] -set_option linter.flexible false in -- simp followed by exact rfl @[simp] -theorem length_nil : length (nil : Seq α) terminates_nil = 0 := by simp [length]; exact rfl +theorem length_nil : length (nil : Seq α) terminates_nil = 0 := by simp [length, terminatedAt_nil] @[simp] theorem length'_nil : length' (nil : Seq α) = 0 := by @@ -287,25 +286,21 @@ theorem append_nil (s : Seq α) : append s nil = s := by dsimp exact ⟨rfl, _, rfl, rfl⟩ -set_option linter.flexible false in -- TODO: fix non-terminal simp @[simp] theorem append_assoc (s t u : Seq α) : append (append s t) u = append s (append t u) := by apply eq_of_bisim fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u) - · intro s1 s2 h - exact - match s1, s2, h with - | _, _, ⟨s, t, u, rfl, rfl⟩ => by - cases s <;> simp - case nil => - cases t <;> simp - case nil => - cases u <;> simp - case cons _ u => refine ⟨nil, nil, u, ?_, ?_⟩ <;> simp - case cons _ t => refine ⟨nil, t, u, ?_, ?_⟩ <;> simp - case cons _ s => exact ⟨s, t, u, rfl, rfl⟩ + · rintro _ _ ⟨s, t, u, rfl, rfl⟩ + cases s with + | nil => + cases t with + | nil => + cases u with + | nil => simp + | cons _ u => simpa using ⟨nil, nil, u, by simp, by simp⟩ + | cons _ t => simpa using ⟨nil, t, u, by simp, by simp⟩ + | cons _ s => simpa using ⟨s, t, u, rfl, rfl⟩ · exact ⟨s, t, u, rfl, rfl⟩ -set_option backward.isDefEq.respectTransparency false in theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ := by have := h; revert this generalize e : append s₁ s₂ = ss; intro h; revert s₁ @@ -322,7 +317,7 @@ theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) rcases show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' | m · rw [e'] exact Or.inl (mem_cons _ _) - · obtain ⟨i1, i2⟩ := show c = b ∧ append t₁ s₂ = s' by simpa + · obtain ⟨i1, i2⟩ := show c = b ∧ append t₁ s₂ = s' by simpa using e rcases o with e' | IH · simp [i1, e'] · exact Or.imp_left (mem_cons_of_mem _) (IH m i2) @@ -407,21 +402,17 @@ theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ · injection oe · injection oe with h'; exact ⟨a, om, h'⟩ -set_option linter.flexible false in -- TODO: fix non-terminal simp @[simp] theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := by - apply - eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _ - ⟨s, t, rfl, rfl⟩ - intro s1 s2 h - exact - match s1, s2, h with - | _, _, ⟨s, t, rfl, rfl⟩ => by - cases s <;> simp - case nil => - cases t <;> simp - case cons _ t => refine ⟨nil, t, ?_, ?_⟩ <;> simp - case cons _ s => exact ⟨s, t, rfl, rfl⟩ + refine eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) + ?_ ⟨s, t, rfl, rfl⟩ + rintro s1 s2 ⟨s, t, rfl, rfl⟩ + cases s with + | nil => + cases t with + | nil => simp + | cons _ t => simpa using ⟨nil, t, by simp, by simp⟩ + | cons _ s => simpa using ⟨s, t, rfl, rfl⟩ end Map @@ -460,30 +451,26 @@ theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join · simpa only [BisimO, join_cons_cons, destruct_cons, cons_append, true_and] using Or.inr ⟨_, _, S, rfl, rfl⟩ -set_option linter.flexible false in -- TODO: fix non-terminal simp @[simp] theorem join_append (S T : Seq (Seq1 α)) : join (append S T) = append (join S) (join T) := by apply eq_of_bisim fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)) - · intro s1 s2 h - exact - match s1, s2, h with - | _, _, ⟨s, S, T, rfl, rfl⟩ => by - cases s <;> simp - case nil => - cases S <;> simp - case nil => - cases T with - | nil => simp - | cons s T => - obtain ⟨a, s⟩ := s; simp only [join_cons, destruct_cons, true_and] - refine ⟨s, nil, T, ?_, ?_⟩ <;> simp - case cons s S => - obtain ⟨a, s⟩ := s - simpa using ⟨s, S, T, rfl, rfl⟩ - case cons _ s => exact ⟨s, S, T, rfl, rfl⟩ - · refine ⟨nil, S, T, ?_, ?_⟩ <;> simp + · rintro s1 s2 ⟨s, S, T, rfl, rfl⟩ + cases s with + | nil => + cases S with + | nil => + cases T with + | nil => simp + | cons s T => + obtain ⟨a, s⟩ := s + simpa using ⟨s, nil, T, by simp, by simp⟩ + | cons s S => + obtain ⟨a, s⟩ := s + simpa using ⟨s, S, T, rfl, rfl⟩ + | cons _ s => simpa using ⟨s, S, T, rfl, rfl⟩ + · exact ⟨nil, S, T, by simp, by simp⟩ end Join @@ -1018,31 +1005,27 @@ theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by obtain ⟨a, s⟩ := f a cases s <;> simp -set_option linter.flexible false in -- TODO: fix non-terminal simp @[simp] theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by apply Seq.eq_of_bisim fun s1 s2 => ∃ s S, s1 = Seq.append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S)) - · intro s1 s2 h - exact - match s1, s2, h with - | _, _, ⟨s, S, rfl, rfl⟩ => by - cases s <;> simp - case nil => - cases S <;> simp - case cons x S => - obtain ⟨a, s⟩ := x - simpa [map] using ⟨_, _, rfl, rfl⟩ - case cons _ s => exact ⟨s, S, rfl, rfl⟩ - · refine ⟨nil, S, ?_, ?_⟩ <;> simp + · rintro s1 s2 ⟨s, S, rfl, rfl⟩ + cases s with + | nil => + cases S with + | nil => simp + | cons x S => + obtain ⟨a, s⟩ := x + simpa [map] using ⟨_, _, rfl, rfl⟩ + | cons _ s => simpa using ⟨s, S, rfl, rfl⟩ + · simpa using ⟨nil, S, by simp, by simp⟩ @[simp] theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S) | ((a, s), S) => by cases s <;> simp [map] -set_option linter.flexible false in -- TODO: fix non-terminal simp @[simp] theorem join_join (SS : Seq (Seq1 (Seq1 α))) : Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) := by @@ -1050,21 +1033,18 @@ theorem join_join (SS : Seq (Seq1 (Seq1 α))) : Seq.eq_of_bisim fun s1 s2 => ∃ s SS, s1 = Seq.append s (Seq.join (Seq.join SS)) ∧ s2 = Seq.append s (Seq.join (Seq.map join SS)) - · intro s1 s2 h - exact - match s1, s2, h with - | _, _, ⟨s, SS, rfl, rfl⟩ => by - cases s <;> simp - case nil => - cases SS <;> simp - case cons S SS => - obtain ⟨s, S⟩ := S; obtain ⟨x, s⟩ := s - simp only [Seq.join_cons, join_append, destruct_cons] - cases s <;> simp - case nil => exact ⟨_, _, rfl, rfl⟩ - case cons x s => refine ⟨Seq.cons x (append s (Seq.join S)), SS, ?_, ?_⟩ <;> simp - case cons _ s => exact ⟨s, SS, rfl, rfl⟩ - · refine ⟨nil, SS, ?_, ?_⟩ <;> simp + · rintro s1 s2 ⟨s, SS, rfl, rfl⟩ + cases s with + | nil => + cases SS with + | nil => simp + | cons S SS => + obtain ⟨⟨x, s⟩, S⟩ := S + cases s with + | nil => simpa using ⟨_, _, rfl, rfl⟩ + | cons x s => simpa using ⟨Seq.cons x (append s (Seq.join S)), SS, by simp, by simp⟩ + | cons _ s => simpa using ⟨s, SS, rfl, rfl⟩ + · simpa using ⟨nil, SS, by simp, by simp⟩ @[simp] theorem bind_assoc (s : Seq1 α) (f : α → Seq1 β) (g : β → Seq1 γ) : diff --git a/Mathlib/Data/WSeq/Basic.lean b/Mathlib/Data/WSeq/Basic.lean index fa9bb6729bd42c..d3fe87d6ca7e15 100644 --- a/Mathlib/Data/WSeq/Basic.lean +++ b/Mathlib/Data/WSeq/Basic.lean @@ -421,27 +421,29 @@ theorem mem_think (s : WSeq α) (a) : a ∈ think s ↔ a ∈ s := by injections · apply Stream'.mem_cons_of_mem _ h -set_option linter.flexible false in -- TODO: fix non-terminal simp theorem eq_or_mem_iff_mem {s : WSeq α} {a a' s'} : some (a', s') ∈ destruct s → (a ∈ s ↔ a = a' ∨ a ∈ s') := by - generalize e : destruct s = c; intro h + generalize e : destruct s = c + intro h revert s - apply Computation.memRecOn h <;> [skip; intro c IH] <;> intro s <;> + apply Computation.memRecOn h <;> [skip; intro c IH] <;> intro s m <;> induction s using WSeq.recOn <;> - intro m <;> - have := congr_arg Computation.destruct m <;> - simp at this - · obtain ⟨i1, i2⟩ := this + have := congr_arg Computation.destruct m + case h1.nil | h1.think | h2.nil | h2.cons => simp at this + case h2.think => simp at this; simp [IH this] + case h1.cons => + simp only [destruct_cons, destruct_pure, Sum.inl.injEq, Option.some.injEq, + Prod.mk.injEq] at this + obtain ⟨i1, i2⟩ := this rw [i1, i2] dsimp only [cons, Membership.mem, WSeq.Mem, Seq.Mem, Seq.cons] have h_a_eq_a' : a = a' ↔ some (some a) = some (some a') := by simp rw [h_a_eq_a'] refine ⟨Stream'.eq_or_mem_of_mem_cons, fun o => ?_⟩ - · rcases o with e | m - · rw [e] - apply Stream'.mem_cons - · exact Stream'.mem_cons_of_mem _ m - · simp [IH this] + rcases o with e | m + · rw [e] + apply Stream'.mem_cons + · exact Stream'.mem_cons_of_mem _ m @[simp] theorem mem_cons_iff (s : WSeq α) (b) {a} : a ∈ cons b s ↔ a = b ∨ a ∈ s := @@ -453,14 +455,15 @@ theorem mem_cons_of_mem {s : WSeq α} (b) {a} (h : a ∈ s) : a ∈ cons b s := theorem mem_cons (s : WSeq α) (a) : a ∈ cons a s := (mem_cons_iff _ _).2 (Or.inl rfl) -set_option linter.flexible false in -- TODO: fix non-terminal simp -theorem mem_of_mem_tail {s : WSeq α} {a} : a ∈ tail s → a ∈ s := by - intro h; have := h; obtain ⟨n, e⟩ := h; revert s; simp only [Stream'.get] - induction n <;> intro s <;> induction s using WSeq.recOn <;> - simp <;> intro m e <;> injections - · exact Or.inr m - · exact Or.inr m +theorem mem_of_mem_tail {s : WSeq α} {a} (h : a ∈ tail s) : a ∈ s := by + have ⟨n, e⟩ := h + revert s + induction n <;> intro s m e <;> induction s using WSeq.recOn + case zero.nil | succ.nil => simpa using m + case zero.cons | succ.cons => exact WSeq.mem_cons_iff .. |>.mpr <| Or.inr (by simpa using m) + case zero.think => injections case succ.think n IH s => + simp only [tail_think, mem_think] at m e ⊢ apply IH m rw [e] cases tail s @@ -688,41 +691,36 @@ theorem mem_map (f : α → β) {a : α} {s : WSeq α} : a ∈ s → f a ∈ map Seq.mem_map (Option.map f) set_option backward.isDefEq.respectTransparency false in -set_option linter.flexible false in -- TODO: fix non-terminal simp -- The converse is not true without additional assumptions theorem exists_of_mem_join {a : α} : ∀ {S : WSeq (WSeq α)}, a ∈ join S → ∃ s, s ∈ S ∧ a ∈ s := by suffices ∀ ss : WSeq α, a ∈ ss → ∀ s S, append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s from fun S h => (this _ h nil S (by simp) (by simp [h])).resolve_left (notMem_nil _) - intro ss h; apply mem_rec_on h <;> [intro b ss o; intro ss IH] <;> intro s S - · induction s using WSeq.recOn <;> + intro ss h + apply mem_rec_on h + · intro b ss o s S ej m + induction s using WSeq.recOn <;> [induction S using WSeq.recOn; skip; skip] <;> - intro ej m <;> simp at ej <;> have := congr_arg Seq.destruct ej <;> - simp at this; cases this - case cons.intro b' s => - subst b' ss - simp? at m ⊢ says simp only [cons_append, mem_cons_iff] at m ⊢ - rcases o with e | IH - · simp [e] - rcases m with e | m - · simp [e] - exact Or.imp_left Or.inr (IH _ _ rfl m) - · induction s using WSeq.recOn <;> + have := congr_arg Seq.destruct ej + case nil.nil | nil.cons | nil.think | think => simp at this + case cons => + simp only [cons_append, seq_destruct_cons, Option.some.injEq, Prod.mk.injEq] at this + cases this with + | intro b' s => + subst b' ss + simp? at m ⊢ says simp only [cons_append, mem_cons_iff] at m ⊢ + rcases o with e | IH + · simp [e] + rcases m with e | m + · simp [e] + exact Or.imp_left Or.inr (IH _ _ rfl m) + · intro ss IH s S ej m + induction s using WSeq.recOn <;> [induction S using WSeq.recOn; skip; skip] <;> - intro ej m <;> simp at ej <;> have := congr_arg Seq.destruct ej <;> simp at this <;> - subst ss - case cons s S => - apply Or.inr - simp only [join_cons, nil_append, mem_think, mem_cons_iff, exists_eq_or_imp] at m ⊢ - exact IH s S rfl m - case think S => - apply Or.inr - replace m : a ∈ S.join := by simpa using m - rcases (IH nil S (by simp) (by simp [m])).resolve_left (notMem_nil _) with ⟨s, sS, as⟩ - exact ⟨s, by simp [sS], as⟩ - · simp only [think_append, mem_think] at m IH ⊢ - apply IH _ _ rfl m + have := congr_arg Seq.destruct ej + case nil.cons | nil.think | think => simp at this; simp_all + case nil.nil | cons => simp at this theorem exists_of_mem_bind {s : WSeq α} {f : α → WSeq β} {b} (h : b ∈ bind s f) : ∃ a ∈ s, b ∈ f a := @@ -789,23 +787,20 @@ theorem destruct_join (S : WSeq (WSeq α)) : case nil | cons => simp case think S => exact Or.inr ⟨S, by simp⟩ -set_option linter.flexible false in -- TODO: fix non-terminal simp @[simp] theorem map_join (f : α → β) (S) : map f (join S) = join (map (map f) S) := by apply Seq.eq_of_bisim fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S)) - · intro s1 s2 h - exact - match s1, s2, h with - | _, _, ⟨s, S, rfl, rfl⟩ => by - induction s using WSeq.recOn <;> simp - · induction S using WSeq.recOn <;> simp - case cons s S => exact ⟨map f s, S, rfl, rfl⟩ - case think S => refine ⟨nil, S, ?_, ?_⟩ <;> simp - · exact ⟨_, _, rfl, rfl⟩ - · exact ⟨_, _, rfl, rfl⟩ - · refine ⟨nil, S, ?_, ?_⟩ <;> simp + · rintro s1 s2 ⟨s, S, rfl, rfl⟩ + induction s using WSeq.recOn + · induction S using WSeq.recOn with + | nil => simp + | cons s S => simpa using ⟨map f s, S, rfl, rfl⟩ + | think S => simpa using ⟨nil, S, by simp, by simp⟩ + · simpa using ⟨_, _, rfl, rfl⟩ + · simpa using ⟨_, _, rfl, rfl⟩ + · exact ⟨nil, S, by simp, by simp⟩ end WSeq From 4a7edd35ec64de7117995da659e9d4d80e6cca19 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:51:20 +0000 Subject: [PATCH 0757/1300] chore: update Mathlib dependencies 2026-07-13 (#41687) This PR updates the Mathlib dependencies. --- lake-manifest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index e2a6b55352e02d..bf9044d64622a2 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f3c7bd5061bd81b4480295c524d4f245c8b7e4e2", + "rev": "e12c1910fe855cbfc38803cd4e55543906d5fa62", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e4952ae2afde0dd2868b313356d1ce00da677bd9", + "rev": "6e311e2a844da9b2cc3971187df2fe0066947b93", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "7a62bd13860cd39ac98da16ffc8c24d601353f69", + "rev": "38d591e778f100aec9762bb582f9c7f55f50e9dc", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", From 81a5d257c8e410db227a6665ed08f64fea08e997 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Mon, 13 Jul 2026 15:46:04 +0000 Subject: [PATCH 0758/1300] chore: bump toolchain to v4.32.0 (#41690) Co-authored-by: Joscha --- lake-manifest.json | 10 +++++----- lean-toolchain | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index bf9044d64622a2..cbd060afa9cc86 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "41f407a8e85b0fdc00910633a8f14754139b63f4", + "rev": "7e9612bf0b9ee66db3cb5b9988a35afc706f5a12", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "24fa6b3599743c23e6debd53d5fd09ebfa587d29", + "rev": "a7dbf0c63b694e47f425f3dcddbc0e178bb432d3", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "dfb6d7e9949d1bb0706f651e330176bc66fc6f3d", + "rev": "023ce7d62a0531e22a5331e20b587817a80d49ff", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "406ebb8c8e2f7e852a1b47764b42494022ce652c", + "rev": "88679d088c9720c27ebdf2ba4dafe17341747f94", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.32.0-rc1", + "inputRev": "v4.32.0", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lean-toolchain b/lean-toolchain index 2694eb767c1d5d..94b9f495baff80 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.32.0-rc1 +leanprover/lean4:v4.32.0 From b86f7b9ebe47ff9bc2db86b38a6b7f3fac59febb Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Mon, 13 Jul 2026 16:49:27 +0000 Subject: [PATCH 0759/1300] chore: tweak bench suite (#41692) This PR applies a few tweaks to bring the bench suite in-line with the other repos using a similar setup. The only change that affects functionality is how `.lean` LoC are computed. Instead of looking only in `Mathlib`, now it searches the entire repo for `.lean` files. Follow-up to #41587. Co-authored-by: Joscha --- scripts/bench/build/README.md | 6 +++--- scripts/bench/build/lakeprof_report_upload.py | 7 +++---- scripts/bench/build/run | 2 +- scripts/bench/size/run | 13 ++++++++++++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/scripts/bench/build/README.md b/scripts/bench/build/README.md index 7b328289b777b2..7a37466b5df050 100644 --- a/scripts/bench/build/README.md +++ b/scripts/bench/build/README.md @@ -1,6 +1,6 @@ # The `build` benchmark -This benchmark executes a complete build of mathlib4 and collects global and per-module metrics. +This benchmark executes a complete build and collects global and per-module metrics. The following metrics are collected by a wrapper around the entire build process: @@ -28,5 +28,5 @@ The following metrics are collected individually for each module: - `build/module///lines` - `build/module///instructions` -If the file `build_upload_lakeprof_report` is present in the repo root, -the lakeprof report will be uploaded once the benchmark run concludes. +If the `LAKEPROF_UPLOAD_URL` environment variable is set, +the lakeprof report will be uploaded to that URL prefix once the benchmark run concludes. diff --git a/scripts/bench/build/lakeprof_report_upload.py b/scripts/bench/build/lakeprof_report_upload.py index c779115a4c3462..450887df8d28de 100644 --- a/scripts/bench/build/lakeprof_report_upload.py +++ b/scripts/bench/build/lakeprof_report_upload.py @@ -12,10 +12,9 @@ if upload_url.endswith("/"): upload_url = upload_url[:-1] -# Determine paths relative to the current file. -script_file = Path(__file__) -template_file = script_file.parent / "lakeprof_report_template.html" -root_dir = script_file.parent.parent.parent.parent +# Determine paths +template_file = Path(__file__).with_name("lakeprof_report_template.html") +root_dir = Path(os.environ["ROOT_DIR"]) def run_stdout(*command: str, cwd: Path | None = None) -> str: diff --git a/scripts/bench/build/run b/scripts/bench/build/run index a4cb089046d432..ea60febaa75ce1 100755 --- a/scripts/bench/build/run +++ b/scripts/bench/build/run @@ -14,5 +14,5 @@ LAKE_OVERRIDE_LEAN=true \ lakeprof record lake build --no-cache # Analyze lakeprof data -"$BENCH_DIR/build/lakeprof_measurements.py" measurements.jsonl +"$BENCH_DIR/build/lakeprof_measurements.py" "$OUTPUT_FILE" python3 "$BENCH_DIR/build/lakeprof_report_upload.py" diff --git a/scripts/bench/size/run b/scripts/bench/size/run index c4b51eba6f45d0..38bea958139cfd 100755 --- a/scripts/bench/size/run +++ b/scripts/bench/size/run @@ -3,6 +3,7 @@ import json import os from pathlib import Path +from typing import Generator OUTFILE = Path(os.environ["OUTPUT_FILE"]) @@ -20,6 +21,16 @@ def output_result( f.write(f"{json.dumps(data)}\n") +def find_lean_files() -> Generator[Path, None, None]: + for p in Path().iterdir(): + if p.name.startswith("."): + continue + elif p.is_dir(): + yield from p.glob("**/*.lean") + elif p.name.endswith(".lean"): + yield p + + def measure_lines(topic: str, *paths: Path) -> None: for path in paths: if path.is_file(): @@ -37,7 +48,7 @@ def measure_bytes(topic: str, *paths: Path) -> None: if __name__ == "__main__": - measure_lines("size/.lean", *Path().glob("Mathlib/**/*.lean")) + measure_lines("size/.lean", *find_lean_files()) measure_bytes("size/.olean", *Path().glob(".lake/build/**/*.olean")) measure_bytes("size/.olean.server", *Path().glob(".lake/build/**/*.olean.server")) measure_bytes("size/.olean.private", *Path().glob(".lake/build/**/*.olean.private")) From 07c971f2d3e93d5ad2c37913b6a3158865115128 Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Mon, 13 Jul 2026 17:10:27 +0000 Subject: [PATCH 0760/1300] feat(Order/OrderIsoNat+Data/Finset/Sort): add finiteness and identity theorems for linear orders (#41679) Add theorems to prove that finite, strictly monotone self-maps are the identity. In order to show that we do not lose generality by using the `Finite` constraint instead of `WellFoundedGT` + `WellFoundedLT` add a theorem to prove that a linear order that is well-founded in both directions is finite. To prove the latter also add a theorem to prove that every infinite linear order contains either a strictly increasing or a strictly descreasing sequence. The theorems in `Data/Finset/Sort` are required for https://github.com/leanprover-community/mathlib4/pull/41160. Co-authored-by: Oliver Nash --- .../SimplicialSet/ProdStdSimplex.lean | 1 + .../SimplicialSet/StdSimplex.lean | 1 + Mathlib/Data/Finset/Sort.lean | 38 -------------- Mathlib/Order/OrderIsoNat.lean | 26 ++++++++++ Mathlib/Order/Preorder/Finite.lean | 52 +++++++++++++++++++ 5 files changed, 80 insertions(+), 38 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean index a7d96f4f6af594..5d4e6ee08bba79 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean @@ -7,6 +7,7 @@ module public import Mathlib.AlgebraicTopology.SimplicialSet.Monoidal public import Mathlib.AlgebraicTopology.SimplicialSet.NerveNondegenerate +import Mathlib.Order.Preorder.Finite /-! # Binary product of standard simplices diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 2e06c56fee1cb4..ba21e62be40308 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -13,6 +13,7 @@ public import Mathlib.Logic.Equiv.Fin.Basic public import Mathlib.Order.Fin.Finset public import Mathlib.Order.Fin.SuccAboveOrderIso public import Mathlib.CategoryTheory.Limits.Shapes.FiniteProducts +import Mathlib.Order.Preorder.Finite /-! # The standard simplex diff --git a/Mathlib/Data/Finset/Sort.lean b/Mathlib/Data/Finset/Sort.lean index 90932d88a4603e..42d098fba84e1b 100644 --- a/Mathlib/Data/Finset/Sort.lean +++ b/Mathlib/Data/Finset/Sort.lean @@ -353,41 +353,3 @@ lemma nonempty_orderEmbedding_of_finite_infinite haveI := Fintype.ofFinite α obtain ⟨s, hs⟩ := Infinite.exists_subset_card_eq β (Fintype.card α) exact ⟨((Fintype.orderIsoFinOfCardEq α rfl).symm.toOrderEmbedding).trans (s.orderEmbOfFin hs)⟩ - -@[elab_as_elim, deprecated "Use `WellFoundedLT.induction _ h` instead." (since := "2026-04-10")] -lemma LinearOrder.strong_induction_of_finite - {α : Type*} [LinearOrder α] [Finite α] {motive : α → Prop} - (h : ∀ (j : α) (_ : ∀ (k : α), k < j → motive k), motive j) (i : α) : - motive i := WellFoundedLT.induction _ h - -lemma OrderEmbedding.range_eq_iff - {α β : Type*} [LinearOrder α] [PartialOrder β] [Finite α] - {f g : α ↪o β} : - Set.range f = Set.range g ↔ f = g := by - refine ⟨fun h ↦ ?_, by rintro rfl; rfl⟩ - let ef := (f.strictMono.strictMonoOn .univ).orderIso - let eg := (g.strictMono.strictMonoOn .univ).orderIso - let i : f '' .univ ≃o g '' .univ := - { __ := Equiv.setCongr (by simpa using! h) - map_rel_iff' := by rfl } - have : (ef.trans i).trans eg.symm = .refl _ := by - exact Subsingleton.elim _ _ - ext x - simpa only [OrderIso.trans_apply, OrderIso.apply_symm_apply, OrderIso.refl_apply, Subtype.ext_iff] - using! congr(eg ($this ⟨x, Set.mem_univ x⟩)) - -lemma OrderHom.range_eq_iff {α β : Type*} [LinearOrder α] [PartialOrder β] - [Finite α] {f g : α →o β} - (hf : Function.Injective f) (hg : Function.Injective g) : - Set.range f = Set.range g ↔ f = g := by - refine ⟨fun h ↦ ?_, by rintro rfl; rfl⟩ - ext : 2 - exact DFunLike.congr_fun ((OrderEmbedding.range_eq_iff - (f := .ofStrictMono f (f.monotone.strictMono_of_injective hf)) - (g := .ofStrictMono g (g.monotone.strictMono_of_injective hg))).1 (by simpa)) _ - -lemma OrderHom.eq_id_of_injective {α : Type*} [LinearOrder α] [Finite α] (f : α →o α) - (hf : Function.Injective f) : - f = .id := - (range_eq_iff hf Function.injective_id).1 (by - simpa [Set.range_eq_univ] using Finite.surjective_of_injective hf) diff --git a/Mathlib/Order/OrderIsoNat.lean b/Mathlib/Order/OrderIsoNat.lean index 23b8963a657b94..3c1aefd5c22cd3 100644 --- a/Mathlib/Order/OrderIsoNat.lean +++ b/Mathlib/Order/OrderIsoNat.lean @@ -21,6 +21,10 @@ defines the limit value of an eventually-constant sequence. * `natLT`/`natGT`: Make an order embedding `Nat ↪ α` from an increasing/decreasing function `Nat → α`. +* `Infinite.exists_strictMono_or_strictAnti`: Every infinite linear order contains a strictly + increasing or strictly decreasing sequence indexed by `ℕ`. +* `Finite.of_wellFoundedLT_wellFoundedGT`: A linear order that is well-founded in both directions + is finite. * `monotonicSequenceLimit`: The limit of an eventually-constant monotone sequence `Nat →o α`. * `monotonicSequenceLimitIndex`: The index of the first occurrence of `monotonicSequenceLimit` in the sequence. @@ -189,6 +193,28 @@ theorem exists_increasing_or_nonincreasing_subseq (r : α → α → Prop) [IsTr exact ih (lt_of_lt_of_le m.lt_succ_self (Nat.le_add_right _ _)) · exact ⟨g, Or.intro_right _ hnr⟩ +/-- Every infinite linear order contains either a strictly increasing or a strictly decreasing +sequence indexed by `ℕ`. -/ +theorem Infinite.exists_strictMono_or_strictAnti (α : Type*) [LinearOrder α] [Infinite α] : + ∃ f : ℕ → α, StrictMono f ∨ StrictAnti f := by + let f := Infinite.natEmbedding α + obtain ⟨g, hg⟩ := exists_increasing_or_nonincreasing_subseq (· < ·) f + refine ⟨f ∘ g, ?_⟩ + rcases hg with hIncreasing | hNonincreasing + · exact Or.inl hIncreasing + · refine Or.inr <| fun m n hmn ↦ lt_of_le_of_ne ?_ ((f.injective.comp g.injective).ne ?_) + · grind + · grind + +/-- A linear order that is well-founded in both directions is finite. -/ +theorem Finite.of_wellFoundedLT_wellFoundedGT (α : Type*) [LinearOrder α] + [WellFoundedLT α] [WellFoundedGT α] : Finite α := by + apply Finite.of_not_infinite + intro + obtain ⟨f, hStrictMono | hStrictAnti⟩ := Infinite.exists_strictMono_or_strictAnti α + · exact not_strictMono_of_wellFoundedGT f hStrictMono + · exact not_strictAnti_of_wellFoundedLT f hStrictAnti + /-- The **monotone chain condition**: a preorder is co-well-founded iff every increasing sequence contains two non-increasing indices. diff --git a/Mathlib/Order/Preorder/Finite.lean b/Mathlib/Order/Preorder/Finite.lean index c64ac316b4bd62..345db2b340ac76 100644 --- a/Mathlib/Order/Preorder/Finite.lean +++ b/Mathlib/Order/Preorder/Finite.lean @@ -6,6 +6,7 @@ Authors: Yaël Dillies module public import Mathlib.Data.Set.Finite.Basic +public import Mathlib.Order.Hom.Set public import Mathlib.Order.Minimal /-! @@ -13,6 +14,9 @@ public import Mathlib.Order.Minimal This file shows that non-empty finite sets in a preorder have minimal/maximal elements, and contrapositively that non-empty sets without minimal or maximal elements are infinite. + +It also provides uniqueness results for order embeddings and order homomorphisms on finite linear +orders. -/ public section @@ -145,3 +149,51 @@ lemma Finite.exists_le_maximal (h : p a) : ∃ b, a ≤ b ∧ Maximal p b := {x | p x}.toFinite.exists_le_maximal h end Preorder + +@[elab_as_elim, deprecated "Use `WellFoundedLT.induction _ h` instead." (since := "2026-04-10")] +lemma LinearOrder.strong_induction_of_finite + {α : Type*} [LinearOrder α] [Finite α] {motive : α → Prop} + (h : ∀ (j : α) (_ : ∀ (k : α), k < j → motive k), motive j) (i : α) : + motive i := WellFoundedLT.induction _ h + +lemma OrderEmbedding.range_eq_iff + {α β : Type*} [LinearOrder α] [PartialOrder β] [Finite α] + {f g : α ↪o β} : + Set.range f = Set.range g ↔ f = g := by + refine ⟨fun h ↦ ?_, by rintro rfl; rfl⟩ + let ef := (f.strictMono.strictMonoOn .univ).orderIso + let eg := (g.strictMono.strictMonoOn .univ).orderIso + let i : f '' .univ ≃o g '' .univ := + { __ := Equiv.setCongr (by simpa using! h) + map_rel_iff' := by rfl } + have : (ef.trans i).trans eg.symm = .refl _ := by + exact Subsingleton.elim _ _ + ext x + simpa only [OrderIso.trans_apply, OrderIso.apply_symm_apply, OrderIso.refl_apply, Subtype.ext_iff] + using! congr(eg ($this ⟨x, Set.mem_univ x⟩)) + +lemma OrderHom.range_eq_iff {α β : Type*} [LinearOrder α] [PartialOrder β] + [Finite α] {f g : α →o β} + (hf : Function.Injective f) (hg : Function.Injective g) : + Set.range f = Set.range g ↔ f = g := by + refine ⟨fun h ↦ ?_, by rintro rfl; rfl⟩ + ext : 2 + exact DFunLike.congr_fun ((OrderEmbedding.range_eq_iff + (f := .ofStrictMono f (f.monotone.strictMono_of_injective hf)) + (g := .ofStrictMono g (g.monotone.strictMono_of_injective hg))).1 (by simpa)) _ + +lemma OrderHom.eq_id_of_injective {α : Type*} [LinearOrder α] [Finite α] (f : α →o α) + (hf : Function.Injective f) : + f = .id := + (range_eq_iff hf Function.injective_id).1 (by + simpa [Set.range_eq_univ] using Finite.surjective_of_injective hf) + +/-- A strictly monotone self-map of a finite linear order is the identity. -/ +theorem StrictMono.eq_id {α : Type*} [LinearOrder α] [Finite α] {f : α → α} + (hf : StrictMono f) : f = id := + le_antisymm hf.le_id hf.id_le + +/-- A strictly monotone self-map of a finite linear order fixes every point. -/ +theorem StrictMono.apply_eq {α : Type*} [LinearOrder α] [Finite α] {f : α → α} + {x : α} (hf : StrictMono f) : f x = x := + congrFun hf.eq_id x From 8ccb214159da909d84c32960cf5ce590b71ccf3e Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 13 Jul 2026 18:36:40 +0000 Subject: [PATCH 0761/1300] chore: use `to_additive` in more places (#29145) This PR addresses some comments about `to_additive` not working, by making it work more. --- .../Combinatorics/Additive/DoublingConst.lean | 29 ++++--------------- .../Topology/Algebra/InfiniteSum/Module.lean | 23 ++------------- 2 files changed, 9 insertions(+), 43 deletions(-) diff --git a/Mathlib/Combinatorics/Additive/DoublingConst.lean b/Mathlib/Combinatorics/Additive/DoublingConst.lean index e10a6b1d546b1e..3b9234ae49676d 100644 --- a/Mathlib/Combinatorics/Additive/DoublingConst.lean +++ b/Mathlib/Combinatorics/Additive/DoublingConst.lean @@ -155,42 +155,25 @@ end Fintype variable {𝕜 : Type*} [Semifield 𝕜] [CharZero 𝕜] --- we can't use `to_additive`, because it tries to translate `/` to `-` -lemma cast_addConst (A B : Finset G') : (σ[A, B] : 𝕜) = #(A + B) / #A := by - simp [addConst] - -lemma cast_subConst (A B : Finset G') : (δ[A, B] : 𝕜) = #(A - B) / #A := by - simp [subConst] - +@[to_additive (dont_translate := 𝕜)] lemma cast_mulConst (A B : Finset G) : (σₘ[A, B] : 𝕜) = #(A * B) / #A := by simp [mulConst] +@[to_additive (dont_translate := 𝕜)] lemma cast_divConst (A B : Finset G) : (δₘ[A, B] : 𝕜) = #(A / B) / #A := by simp [divConst] -lemma cast_addConst_mul_card (A B : Finset G') : (σ[A, B] * #A : 𝕜) = #(A + B) := by - norm_cast; exact addConst_mul_card _ _ - -lemma cast_subConst_mul_card (A B : Finset G') : (δ[A, B] * #A : 𝕜) = #(A - B) := by - norm_cast; exact subConst_mul_card _ _ - -lemma card_mul_cast_addConst (A B : Finset G') : (#A * σ[A, B] : 𝕜) = #(A + B) := by - norm_cast; exact card_mul_addConst _ _ - -lemma card_mul_cast_subConst (A B : Finset G') : (#A * δ[A, B] : 𝕜) = #(A - B) := by - norm_cast; exact card_mul_subConst _ _ - -@[simp] +@[to_additive (dont_translate := 𝕜) (attr := simp) cast_addConst_mul_card] lemma cast_mulConst_mul_card (A B : Finset G) : (σₘ[A, B] * #A : 𝕜) = #(A * B) := by norm_cast; exact mulConst_mul_card _ _ -@[simp] +@[to_additive (dont_translate := 𝕜) (attr := simp) cast_subConst_mul_card] lemma cast_divConst_mul_card (A B : Finset G) : (δₘ[A, B] * #A : 𝕜) = #(A / B) := by norm_cast; exact divConst_mul_card _ _ -@[simp] +@[to_additive (dont_translate := 𝕜) (attr := simp) card_mul_cast_addConst] lemma card_mul_cast_mulConst (A B : Finset G) : (#A * σₘ[A, B] : 𝕜) = #(A * B) := by norm_cast; exact card_mul_mulConst _ _ -@[simp] +@[to_additive (dont_translate := 𝕜) (attr := simp) card_mul_cast_subConst] lemma card_mul_cast_divConst (A B : Finset G) : (#A * δₘ[A, B] : 𝕜) = #(A / B) := by norm_cast; exact card_mul_divConst _ _ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Module.lean b/Mathlib/Topology/Algebra/InfiniteSum/Module.lean index e0a9d387be8520..a7e054ae230e34 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Module.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Module.lean @@ -198,10 +198,11 @@ noncomputable def MulAction.automorphize [Group α] [MulAction α β] (f : β congr 1 simp only [mul_smul] --- we can't use `to_additive`, because it tries to translate `•` into `+ᵥ` - /-- Automorphization of a function into an `R`-`Module` distributes, that is, commutes with the `R`-scalar multiplication. -/ +@[to_additive (dont_translate := R) automorphize_smul_left /-- +Automorphization of a function into an `R`-`Module` distributes, that is, commutes with the +`R`-scalar multiplication. -/] lemma MulAction.automorphize_smul_left [Group α] [MulAction α β] (f : β → M) (g : Quotient (MulAction.orbitRel α β) → R) : MulAction.automorphize ((g ∘ (@Quotient.mk' _ (_))) • f) @@ -218,24 +219,6 @@ lemma MulAction.automorphize_smul_left [Group α] [MulAction α β] (f : β → simp_rw [H₁] exact tsum_const_smul'' _ -/-- Automorphization of a function into an `R`-`Module` distributes, that is, commutes with the -`R`-scalar multiplication. -/ -lemma AddAction.automorphize_smul_left [AddGroup α] [AddAction α β] (f : β → M) - (g : Quotient (AddAction.orbitRel α β) → R) : - AddAction.automorphize ((g ∘ (@Quotient.mk' _ (_))) • f) - = g • (AddAction.automorphize f : Quotient (AddAction.orbitRel α β) → M) := by - ext x - induction x using Quotient.inductionOn with | _ b - simp only [automorphize, Pi.smul_apply', comp_apply] - set π : β → Quotient (AddAction.orbitRel α β) := Quotient.mk (AddAction.orbitRel α β) - have H₁ : ∀ a : α, π (a +ᵥ b) = π b := by - intro a - apply (@Quotient.eq _ (AddAction.orbitRel α β) (a +ᵥ b) b).mpr - use a - change ∑' a : α, g (π (a +ᵥ b)) • f (a +ᵥ b) = g (π b) • ∑' a : α, f (a +ᵥ b) - simp_rw [H₁] - exact tsum_const_smul'' _ - section variable {G : Type*} [Group G] {Γ : Subgroup G} From c318994e21432386d26071e8741fa6b9ab607a24 Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Mon, 13 Jul 2026 19:01:30 +0000 Subject: [PATCH 0762/1300] feat: delaborators for inequalities in big operators (#39027) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `∏ i < n, f i` was already accepted as valid syntax, but this PR now also prints appropriate sums/products using this notation. --- .../BigOperators/Group/Finset/Defs.lean | 114 ++++++++++-------- MathlibTest/BigOps.lean | 63 ++++++++++ 2 files changed, 130 insertions(+), 47 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Defs.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Defs.lean index 694588e215ae6d..0acacafe6e597b 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Defs.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Defs.lean @@ -163,6 +163,9 @@ meta def bigOpBindersProd (processed : Array (Term × Term)) : MacroM Term := do processed.foldrM (fun s p => `(SProd.sprod $(s.2) $p)) processed.back.2 (start := processed.size - 1) +/-- A `with`-clause in a big operator. Example usage: `∑ i < 100 with Even i, f i`. -/ +syntax BigOpWith := " with " atomic(binderIdent " : ")? term + /-- - `∑ x, f x` is notation for `Finset.sum Finset.univ f`. It is the sum of `f x`, where `x` ranges over the finite domain of `f`. @@ -175,8 +178,7 @@ meta def bigOpBindersProd (processed : Array (Term × Term)) : MacroM Term := do These support destructuring, for example `∑ ⟨x, y⟩ ∈ s ×ˢ t, f x y`. Notation: `"∑" bigOpBinders* (" with" (ident ":")? term)? "," term` -/ -syntax (name := bigsum) - "∑ " bigOpBinders (" with " atomic(binderIdent " : ")? term)? ", " term:67 : term +syntax (name := bigsum) "∑ " bigOpBinders BigOpWith ? ", " term:67 : term /-- - `∏ x, f x` is notation for `Finset.prod Finset.univ f`. It is the product of `f x`, @@ -191,8 +193,7 @@ syntax (name := bigsum) These support destructuring, for example `∏ ⟨x, y⟩ ∈ s ×ˢ t, f x y`. Notation: `"∏" bigOpBinders* ("with" (ident ":")? term)? "," term` -/ -syntax (name := bigprod) - "∏ " bigOpBinders (" with " atomic(binderIdent " : ")? term)? ", " term:67 : term +syntax (name := bigprod) "∏ " bigOpBinders BigOpWith ? ", " term:67 : term macro_rules (kind := bigsum) | `(∑ $bs:bigOpBinders $[with $[$hx??:binderIdent :]? $p?:term]?, $v) => do @@ -226,23 +227,51 @@ open scoped Batteries.ExtendedBinder /-- The possibilities we distinguish to delaborate the finset indexing a big operator: * `finset s` corresponds to `∑ x ∈ s, f x` * `univ` corresponds to `∑ x, f x` -* `filter s p` corresponds to `∑ x ∈ s with p x, f x` -* `filterUniv p` corresponds to `∑ x with p x, f x` +* `Iio n`/`Iic n`/`Ioi n`/`Ici n` corresponds to the intervals that are elaborated by sums. -/ private inductive FinsetResult where | finset (s : Term) | univ - | filter (s : Term) (p : Term) - | filterUniv (p : Term) + | Iio (n : Term) + | Iic (n : Term) + | Ioi (n : Term) + | Ici (n : Term) + +/-- The possibilities we distinguish to delaborate the finset indexing a big operator, including +filters. +* `{finset := s, filter = none}` represents `∑ x ∈ s, f x`; +* `{finset := s, filter = some p}` represents `∑ x ∈ s with p, f x`. +-/ +private structure FinsetFilterResult where + finset : FinsetResult + filter : Option Term -/-- Delaborates a finset indexing a big operator. In case it is a `Finset.filter`, `i` is used for -the binder name. -/ -private meta def delabFinsetArg (i : Ident) : DelabM FinsetResult := do +/-- Delaborates a finset indexing a big operator. -/ +private meta def delabFinsetResult : DelabM FinsetResult := do let s ← getExpr if s.isAppOfArity ``Finset.univ 2 then return .univ - else if s.isAppOfArity ``Finset.filter 4 then - let #[_, _, _, t] := s.getAppArgs | failure + else if s.isAppOfArity `Finset.Iio 4 then + let ss ← withNaryArg 3 delab + return .Iio ss + else if s.isAppOfArity `Finset.Iic 4 then + let ss ← withNaryArg 3 delab + return .Iic ss + else if s.isAppOfArity `Finset.Ioi 4 then + let ss ← withNaryArg 3 delab + return .Ioi ss + else if s.isAppOfArity `Finset.Ici 4 then + let ss ← withNaryArg 3 delab + return .Ici ss + else + let ss ← delab + return .finset ss + +/-- Delaborates a finset indexing a big operator. In case the finset involves a filter, +`i` is used for the binder name. -/ +private meta def delabFinsetArg (i : Ident) : DelabM FinsetFilterResult := do + let s ← getExpr + if s.isAppOfArity ``Finset.filter 4 then let p ← withNaryArg 1 do if (← getExpr).isLambda then @@ -250,14 +279,11 @@ private meta def delabFinsetArg (i : Ident) : DelabM FinsetResult := do else let p ← delab return (← `($p $i)) - if t.isAppOfArity ``Finset.univ 2 then - return .filterUniv p - else - let ss ← withNaryArg 3 delab - return .filter ss p + let r ← withNaryArg 3 delabFinsetResult + return ⟨r, some p⟩ else - let ss ← delab - return .finset ss + let r ← delabFinsetResult + return ⟨r, none⟩ /-- Delaborator for `Finset.prod`. The `pp.funBinderTypes` option controls whether to show the domain type when the product is over `Finset.univ`. -/ @@ -267,28 +293,25 @@ to show the domain type when the product is over `Finset.univ`. -/ guard f.isLambda let ppDomain ← withAppArg <| getPPOption getPPFunBinderTypes let (i, body) ← withAppArg <| withBindingBodyUnusedName fun i => do - return (⟨i⟩, ← delab) - let res ← withNaryArg 3 <| delabFinsetArg i + return ((⟨i⟩ : Ident), ← delab) + let ⟨res, p⟩ ← withNaryArg 3 <| delabFinsetArg i + let withClause? : Option (TSyntax `BigOperators.BigOpWith) ← (match p with + | .some pp => return some (← `(BigOpWith|with $pp:term)) + | .none => return none) match res with - | .finset ss => `(∏ $i:ident ∈ $ss, $body) + | .finset ss => `(∏ $i:ident ∈ $ss $[$withClause?]?, $body) | .univ => - let binder ← - if ppDomain then - let ty ← withNaryArg 0 delab - `(bigOpBinder| $i:ident : $ty) - else - `(bigOpBinder| $i:ident) - `(∏ $binder:bigOpBinder, $body) - | .filter ss p => - `(∏ $i:ident ∈ $ss with $p, $body) - | .filterUniv p => let binder ← if ppDomain then let ty ← withNaryArg 0 delab `(bigOpBinder| $i:ident : $ty) else `(bigOpBinder| $i:ident) - `(∏ $binder:bigOpBinder with $p, $body) + `(∏ $binder:bigOpBinder $[$withClause?]?, $body) + | .Iio ss => `(∏ $i:ident < $ss $[$withClause?]?, $body) + | .Iic ss => `(∏ $i:ident ≤ $ss $[$withClause?]?, $body) + | .Ioi ss => `(∏ $i:ident > $ss $[$withClause?]?, $body) + | .Ici ss => `(∏ $i:ident ≥ $ss $[$withClause?]?, $body) /-- Delaborator for `Finset.sum`. The `pp.funBinderTypes` option controls whether to show the domain type when the sum is over `Finset.univ`. -/ @@ -299,9 +322,12 @@ to show the domain type when the sum is over `Finset.univ`. -/ let ppDomain ← withAppArg <| getPPOption getPPFunBinderTypes let (i, body) ← withAppArg <| withBindingBodyUnusedName fun i => do return ((⟨i⟩ : Ident), ← delab) - let res ← withNaryArg 3 <| delabFinsetArg i + let ⟨res, p⟩ ← withNaryArg 3 <| delabFinsetArg i + let withClause? : Option (TSyntax `BigOperators.BigOpWith) ← (match p with + | .some pp => return some (← `(BigOpWith|with $pp:term)) + | .none => return none) match res with - | .finset ss => `(∑ $i:ident ∈ $ss, $body) + | .finset ss => `(∑ $i:ident ∈ $ss $[$withClause?]?, $body) | .univ => let binder ← if ppDomain then @@ -309,17 +335,11 @@ to show the domain type when the sum is over `Finset.univ`. -/ `(bigOpBinder| $i:ident : $ty) else `(bigOpBinder| $i:ident) - `(∑ $binder:bigOpBinder, $body) - | .filter ss p => - `(∑ $i:ident ∈ $ss with $p, $body) - | .filterUniv p => - let binder ← - if ppDomain then - let ty ← withNaryArg 0 delab - `(bigOpBinder| $i:ident : $ty) - else - `(bigOpBinder| $i:ident) - `(∑ $binder:bigOpBinder with $p, $body) + `(∑ $binder:bigOpBinder $[$withClause?]?, $body) + | .Iio ss => `(∑ $i:ident < $ss $[$withClause?]?, $body) + | .Iic ss => `(∑ $i:ident ≤ $ss $[$withClause?]?, $body) + | .Ioi ss => `(∑ $i:ident > $ss $[$withClause?]?, $body) + | .Ici ss => `(∑ $i:ident ≥ $ss $[$withClause?]?, $body) end BigOperators diff --git a/MathlibTest/BigOps.lean b/MathlibTest/BigOps.lean index 1649dfea98f168..7330a11ae0445a 100644 --- a/MathlibTest/BigOps.lean +++ b/MathlibTest/BigOps.lean @@ -1,4 +1,5 @@ import Mathlib.Algebra.BigOperators.Group.Finset.Basic +import Mathlib.Order.Interval.Finset.Nat import Mathlib.Data.Fintype.Basic section @@ -123,4 +124,66 @@ set_option pp.analyze true in set_option pp.analyze true in #check Finset.prod {j | p j} fun i ↦ f i +/-! ### Big operators over ordered sets -/ + +variable {g : ℕ → M} {q q' : ℕ → Prop} [DecidablePred q] [DecidablePred q'] {n : ℕ} {i₀ : ι} + +/-- info: ∏ i < n, g i : M -/ +#guard_msgs in +#check Finset.prod (Finset.Iio n) fun i ↦ g i + +/-- info: ∏ i ≤ n, g i : M -/ +#guard_msgs in +#check Finset.prod (Finset.Iic n) fun i ↦ g i + +/-- info: ∏ i < n with q i, g i : M -/ +#guard_msgs in +#check Finset.prod ((Finset.Iio n).filter q) fun i ↦ g i + +/-- info: ∏ i ≤ n with q i ∧ q' i, g i : M -/ +#guard_msgs in +#check Finset.prod ((Finset.Iic n).filter fun j ↦ q j ∧ q' j) fun i ↦ g i + +section Bot +variable [Preorder ι] [LocallyFiniteOrderBot ι] + +/-- info: ∏ i < i₀, f i : M -/ +#guard_msgs in +#check Finset.prod (Finset.Iio i₀) fun i ↦ f i + +/-- info: ∏ i ≤ i₀, f i : M -/ +#guard_msgs in +#check Finset.prod (Finset.Iic i₀) fun i ↦ f i + +/-- info: ∏ i < i₀ with p i, f i : M -/ +#guard_msgs in +#check Finset.prod ((Finset.Iio i₀).filter p) fun i ↦ f i + +/-- info: ∏ i ≤ i₀ with p i, f i : M -/ +#guard_msgs in +#check Finset.prod ((Finset.Iic i₀).filter p) fun i ↦ f i + +end Bot + +section Top +variable [Preorder ι] [LocallyFiniteOrderTop ι] + +/-- info: ∏ i > i₀, f i : M -/ +#guard_msgs in +#check Finset.prod (Finset.Ioi i₀) fun i ↦ f i + +/-- info: ∏ i ≥ i₀, f i : M -/ +#guard_msgs in +#check Finset.prod (Finset.Ici i₀) fun i ↦ f i + +/-- info: ∏ i > i₀ with p i, f i : M -/ +#guard_msgs in +#check Finset.prod ((Finset.Ioi i₀).filter p) fun i ↦ f i + +/-- info: ∏ i ≥ i₀ with p i, f i : M -/ +#guard_msgs in +#check Finset.prod ((Finset.Ici i₀).filter p) fun i ↦ f i + +end Top + end From 26068cbf4c9d6b64e4997e57d30e58f127e956df Mon Sep 17 00:00:00 2001 From: Devon Tuma <23745784+dtumad@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:01:33 +0000 Subject: [PATCH 0763/1300] chore: Add `seqLeft` and `seqRight` unfolding to monad_norm simp set (#39436) This PR adds `seqLeft_eq_bind` and `seqRight_eq_bind` to `monad_norm`, so that `<*` and `*>` get unfolded in the same way as `<*>` already does when using the `simp` set. --- Mathlib/Tactic/Attr/Core.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Tactic/Attr/Core.lean b/Mathlib/Tactic/Attr/Core.lean index 38d8f72816dd5e..215b4e419a86f2 100644 --- a/Mathlib/Tactic/Attr/Core.lean +++ b/Mathlib/Tactic/Attr/Core.lean @@ -18,7 +18,7 @@ from the core library and the `Batteries` library with these attributes in this public meta section attribute [functor_norm, monad_norm] seq_assoc pure_seq pure_bind bind_assoc bind_pure map_pure -attribute [monad_norm] seq_eq_bind_map +attribute [monad_norm] seq_eq_bind_map seqLeft_eq_bind seqRight_eq_bind attribute [mfld_simps] id and_true true_and Function.comp_apply and_self eq_self not_false true_or or_true heq_eq_eq forall_const and_imp From 5ea82b358e0cfb15a4d7a50d66105e6396714730 Mon Sep 17 00:00:00 2001 From: Vasilii Nesterov <118051017+vasnesterov@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:01:35 +0000 Subject: [PATCH 0764/1300] feat(Tactic/ComputeAsymptotics/Multiseries): corecursion for multiseries (#40249) Translate API for general corecursion for `Seq` to `Multiseries`. --- .../ComputeAsymptotics/Multiseries/Defs.lean | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean index 2264a94ec0a599..1e332c14282d37 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.Seq.Basic public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized +public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion /-! @@ -131,6 +132,25 @@ def corec {β : Type*} {basis_hd} {basis_tl} Multiseries basis_hd basis_tl := Seq.corec (fun a => (f a).map (fun (exp, coef, next) => ((exp, coef), next))) b +/-- An operation on multiseries called a "friend" if any `n`-prefix of its output depends only on +the `n`-prefix of the input. Such operations can be used in the tail of (non-primitive) corecursive +definitions. -/ +def FriendlyOperation {basis_hd basis_tl} + (op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) : Prop := + Seq.FriendlyOperation op + +/-- A family of friendly operations on multiseries indexed by a type `γ`. -/ +class FriendlyOperationClass {basis_hd basis_tl} {γ : Type*} + (op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) : Prop + extends Seq.FriendlyOperationClass op + +theorem FriendlyOperationClass.mk' {basis_hd basis_tl} {γ : Type*} + {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (h : ∀ c, FriendlyOperation (op c)) : + FriendlyOperationClass op := by + suffices Seq.FriendlyOperationClass op by constructor + exact ⟨h⟩ + private lemma destruct_eq_destruct_map {basis_hd basis_tl} (s : Stream'.Seq (ℝ × MultiseriesExpansion basis_tl)) : s.destruct = (Multiseries.destruct (basis_hd := basis_hd) s).map @@ -138,6 +158,50 @@ private lemma destruct_eq_destruct_map {basis_hd basis_tl} simp only [destruct, Option.map_map] exact Option.map_id_apply.symm +theorem FriendlyOperation.coind_comp_friend_left {basis_hd basis_tl} + {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (motive : (Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) → Prop) + (h_base : motive op) + (h_step : ∀ op, motive op → ∃ T : Option (ℝ × MultiseriesExpansion basis_tl) → + Option (ℝ × MultiseriesExpansion basis_tl × Subtype FriendlyOperation × Subtype motive), + ∀ s, (op s).destruct = + (T s.head).map (fun (exp, coef, opf, op') => (exp, coef, opf.val <| op'.val (s.tail)))) : + FriendlyOperation op := by + refine Seq.FriendlyOperation.coind_comp_friend_left motive h_base (fun op h_op ↦ ?_) + obtain ⟨T, hT⟩ := h_step op h_op + use fun hd? ↦ (T hd?).map (fun (exp, coef, opf, op') => ((exp, coef), opf, op')) + intro s + rw [destruct_eq_destruct_map, hT s] + simp + rfl + +theorem FriendlyOperation.coind_comp_friend_right {basis_hd basis_tl} + {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (motive : (Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) → Prop) + (h_base : motive op) + (h_step : ∀ op, motive op → ∃ T : Option (ℝ × MultiseriesExpansion basis_tl) → + Option (ℝ × MultiseriesExpansion basis_tl × Subtype FriendlyOperation × Subtype motive), + ∀ s, (op s).destruct = + (T s.head).map (fun (exp, coef, opf, op') => (exp, coef, op'.val <| opf.val (s.tail)))) : + FriendlyOperation op := by + refine Seq.FriendlyOperation.coind_comp_friend_right motive h_base (fun op h_op ↦ ?_) + obtain ⟨T, hT⟩ := h_step op h_op + use fun hd? ↦ (T hd?).map (fun (exp, coef, opf, op') => ((exp, coef), opf, op')) + intro s + rw [destruct_eq_destruct_map, hT s] + simp + rfl + +/-- Non-primitive corecursor for `Multiseries basis_hd basis_tl` allowing to use a friendly +operation in the tail of the corecursive definition. -/ +noncomputable def gcorec {β γ : Type*} {basis_hd} {basis_tl} + (F : β → Option (ℝ × MultiseriesExpansion basis_tl × γ × β)) + (op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) + [FriendlyOperationClass op] + (b : β) : + Multiseries basis_hd basis_tl := + Seq.gcorec (fun a => (F a).map (fun (exp, coef, c, next) => ((exp, coef), c, next))) op b + instance (basis_hd basis_tl) : Inhabited (Multiseries basis_hd basis_tl) where default := (default : Seq (ℝ × MultiseriesExpansion basis_tl)) @@ -162,6 +226,97 @@ theorem eq_of_bisim_strong {basis_hd : ℝ → ℝ} {basis_tl : Basis} x = cons exp coef x' ∧ y = cons exp coef y' ∧ motive x' y') : x = y := Seq.eq_of_bisim_strong motive base (by grind [nil, cons]) +theorem FriendlyOperationClass.FriendlyOperation {basis_hd basis_tl} {γ : Type*} + {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + [h : FriendlyOperationClass op] + (c : γ) : + FriendlyOperation (op c) := + h.friend c + +/-- Decomposes a friendly operation by the head of the input sequence. Returns `none` if the output +is `nil`, or `some (exp, coef, op')` where `(exp, coef)` is the head of the output and +`op'` is a friendly operation mapping the tail of the input to the tail of the output. See +`destruct_apply_eq_unfold` for the correctness statement. -/ +def FriendlyOperation.unfold {basis_hd basis_tl} + {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (h : FriendlyOperation op) (hd? : Option (ℝ × MultiseriesExpansion basis_tl)) : + Option (ℝ × MultiseriesExpansion basis_tl × Subtype ( + @Multiseries.FriendlyOperation basis_hd basis_tl)) := + Seq.FriendlyOperation.unfold h hd? |>.map (fun ((exp, coef), op') ↦ (exp, coef, op')) + +theorem FriendlyOperation.destruct_apply_eq_unfold {basis_hd basis_tl} + {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (h : FriendlyOperation op) (ms : Multiseries basis_hd basis_tl) : + destruct (op ms) = (h.unfold ms.head).map + (fun (exp, coef, op') ↦ (exp, coef, op'.val ms.tail)) := by + unfold Multiseries.destruct + simp [Seq.FriendlyOperation.destruct_apply_eq_unfold h, FriendlyOperation.unfold, head] + cases Seq.FriendlyOperation.unfold h (Seq.head ms) <;> rfl + +theorem FriendlyOperation.head_eq_head {basis_hd basis_tl} + {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (h : FriendlyOperation op) {x y : Multiseries basis_hd basis_tl} + (h_head : x.head = y.head) : (op x).head = (op y).head := + Seq.FriendlyOperation.op_head_eq h h_head + +theorem FriendlyOperation.id {basis_hd basis_tl} : + FriendlyOperation (id : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) := + Seq.FriendlyOperation.id + +theorem FriendlyOperation.comp {basis_hd basis_tl} + {op₁ op₂ : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (h₁ : FriendlyOperation op₁) (h₂ : FriendlyOperation op₂) : + FriendlyOperation (op₁ ∘ op₂) := + Seq.FriendlyOperation.comp h₁ h₂ + +theorem FriendlyOperation.const {basis_hd basis_tl} {s : Multiseries basis_hd basis_tl} : + FriendlyOperation (fun _ ↦ s) := + Seq.FriendlyOperation.const + +theorem FriendlyOperation.ite {basis_hd basis_tl} + {op₁ op₂ : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + (h₁ : FriendlyOperation op₁) (h₂ : FriendlyOperation op₂) + {P : Option (ℝ × MultiseriesExpansion basis_tl) → Prop} [DecidablePred P] : + FriendlyOperation (fun ms ↦ if P ms.head then op₁ ms else op₂ ms) := + Seq.FriendlyOperation.ite h₁ h₂ + +theorem FriendlyOperation.cons {basis_hd basis_tl} (exp : ℝ) + (coef : MultiseriesExpansion basis_tl) : + FriendlyOperation (cons (basis_hd := basis_hd) exp coef) := + Seq.FriendlyOperation.cons _ + +theorem FriendlyOperation.cons_tail {basis_hd basis_tl} + {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + {exp : ℝ} {coef : MultiseriesExpansion basis_tl} + (h : FriendlyOperation op) : + FriendlyOperation (fun ms ↦ (op (.cons exp coef ms)).tail) := + Seq.FriendlyOperation.cons_tail h + +theorem FriendlyOperationClass.comp {basis_hd basis_tl} {γ γ' : Type*} + {g : γ' → γ} + {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + [h : FriendlyOperationClass op] : FriendlyOperationClass (fun c ↦ op (g c)) := by + have : Seq.FriendlyOperationClass (fun c ↦ op (g c)) := Seq.FriendlyOperationClass.comp _ _ + constructor + +theorem eq_of_bisim_friend {γ : Type*} {basis_hd : ℝ → ℝ} {basis_tl : Basis} + {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + [FriendlyOperationClass op] + {x y : Multiseries basis_hd basis_tl} + (motive : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl → Prop) + (base : motive x y) + (step : ∀ x y, motive x y → (x = y) ∨ ∃ exp coef, + ∃ (c : γ) (x' y' : Multiseries basis_hd basis_tl), + x = cons exp coef (op c x') ∧ y = cons exp coef (op c y') ∧ motive x' y') : + x = y := by + apply Seq.FriendlyOperationClass.eq_of_bisim (op := op) motive base + peel step with x y ih h + obtain h | ⟨exp, coef, c, x', y', rfl, rfl, h_next⟩ := h + · simp [h] + right + use (exp, coef), x', y', c + simpa [cons] + section simp @[simp] @@ -203,6 +358,30 @@ theorem corec_cons {β : Type*} {basis_hd} {basis_tl} {exp : ℝ} rw [Seq.corec_cons] simpa +theorem gcorec_nil {β γ : Type*} {basis_hd} {basis_tl} + {F : β → Option (ℝ × MultiseriesExpansion basis_tl × γ × β)} + {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + [FriendlyOperationClass op] {b : β} + (h : F b = none) : + gcorec F op b = nil := by + unfold gcorec + rw [Seq.gcorec_nil] + · simp [nil] + · simpa + +theorem gcorec_some {β γ : Type*} {basis_hd} {basis_tl} + {F : β → Option (ℝ × MultiseriesExpansion basis_tl × γ × β)} + {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} + [FriendlyOperationClass op] {b : β} + {exp : ℝ} {coef : MultiseriesExpansion basis_tl} {c : γ} {next : β} + (h : F b = some (exp, coef, c, next)) : + gcorec F op b = cons exp coef (op c (gcorec F op next)) := by + unfold gcorec + rw [Seq.gcorec_some] + · simp [cons] + rfl + · simpa + @[simp] theorem destruct_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} : destruct (nil : Multiseries basis_hd basis_tl) = none := by @@ -376,6 +555,12 @@ theorem ext_iff {basis_hd basis_tl} rw [eq_mk ms₁, eq_mk ms₂] simp [h] +@[simp] +theorem ofReal_toReal (x : ℝ) : (ofReal x).toReal = x := rfl + +@[simp] +theorem toReal_ofReal (ms : MultiseriesExpansion []) : ofReal ms.toReal = ms := rfl + @[simp] theorem const_toFun (ms : MultiseriesExpansion []) : ms.toFun = fun _ ↦ ms.toReal := rfl From addfd30bdc9b408fbec336cddcbca3535be24f3a Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:01:37 +0000 Subject: [PATCH 0765/1300] feat(GRewrite): support universe changing rewrites (#40338) This PR allows `grw` to deal with relations that are heterogenous (the two sides don't have the same type). I'm slightly surprised that this works :). I added a basic test showing that the polymorphic relations on cardinals can be used in `grw`, as proposed in https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Universe-heterogeneous.20ordinal.20and.20cardinal.20relations/with/495593531 --- Mathlib/Tactic/GRewrite/Core.lean | 19 ++++++++++---- MathlibTest/Tactic/GRewrite.lean | 42 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Mathlib/Tactic/GRewrite/Core.lean b/Mathlib/Tactic/GRewrite/Core.lean index db0ff04ad806a9..90d03a868f031d 100644 --- a/Mathlib/Tactic/GRewrite/Core.lean +++ b/Mathlib/Tactic/GRewrite/Core.lean @@ -176,11 +176,20 @@ def GRewriteLemma.apply (lem : GRewriteLemma) (goal : MVarId) (symm : Bool) /-- Create the `gcongr` goal corresponding to rewriting `e` by relation `rel?`, so that we can apply `gcongr` lemmas to it. -/ def makeGCongrGoal (rel? : Option Expr) (e : Expr) (forward : Bool) : MetaM (Expr × Expr) := do - let mkRel := if let some rel := rel? then mkApp2 rel else (.forallE `_a · · .default) - -- Assume that the two arguments of `rel` have the same type. - let mvar ← mkFreshExprMVar (← inferType e) - let target := if forward then mkRel e mvar else mkRel mvar e - return (mvar, ← mkFreshExprMVar target) + if let some rel := rel? then + let .forallE _ d₁ (.forallE _ d₂ _ _) _ ← whnf (← inferType rel) | throwFunctionExpected rel + -- note that `@[gcongr]`'s checks should prevent this happening + if d₂.hasLooseBVars then throwError "grw: {rel} is a dependent relation" + if forward then + let mvar ← mkFreshExprMVar d₂ + return (mvar, ← mkFreshExprMVar <| mkApp2 rel e mvar) + else + let mvar ← mkFreshExprMVar d₁ + return (mvar, ← mkFreshExprMVar <| mkApp2 rel mvar e) + else + let mvar ← mkFreshTypeMVar + let target := if forward then .forallE `_a e mvar .default else .forallE `_a mvar e .default + return (mvar, ← mkFreshExprMVar (some target)) /-- Version of `getRel` that also returns the expression of the relation. -/ def getRel' (e : Expr) : Option (Name × Option Expr × Expr × Expr) := diff --git a/MathlibTest/Tactic/GRewrite.lean b/MathlibTest/Tactic/GRewrite.lean index 972184032da8e4..434c5cb6e98a16 100644 --- a/MathlibTest/Tactic/GRewrite.lean +++ b/MathlibTest/Tactic/GRewrite.lean @@ -500,3 +500,45 @@ example (h₁ : a < b) : Set.Ici b ⊆ Set.Ioi a := by grw [h₁] end strict + +section universePolymorphic + +universe u v w w' + +axiom Cardinal : Type u + +axiom liftEq : Cardinal.{u} → Cardinal.{v} → Prop +axiom liftLE : Cardinal.{u} → Cardinal.{v} → Prop + +variable {a : Cardinal.{u}} {b : Cardinal.{v}} {c : Cardinal.{w}} {d : Cardinal.{w'}} + +@[gcongr] +axiom liftLE_imp_liftLE_of_liftLE_of_liftLE (h₁ : liftLE a b) (h₂ : liftLE c d) : + liftLE b c → liftLE a d + +@[refl] +axiom liftEq_rfl : liftEq a a + +@[symm] +axiom liftEq.comm (h : liftEq a b) : liftEq b a + +axiom liftLE_of_liftEq (h : liftEq a b) : liftLE a b + +@[refl] +theorem liftLE_rfl : liftLE a a := liftLE_of_liftEq liftEq_rfl +namespace Mathlib.Tactic.GCongr + +/-- See if the term is `AntisymmRel r a b` and the goal is `r a b`. -/ +@[gcongr_forward] +public meta def exactLiftLEOfLiftEq : ForwardExt where + eval h goal := do goal.assignIfDefEq (← Lean.Meta.mkAppM ``liftLE_of_liftEq #[h]) + +end Mathlib.Tactic.GCongr + +example (h : liftEq a b) (h' : liftLE b c) : liftLE a c := by + grw [h, h'] + +example (h : liftEq b a) (h' : liftLE b c) : liftLE a c := by + grw [← h, ← h'] + +end universePolymorphic From c61a931152efc366f5f0792d5858bae10fb97116 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:01:39 +0000 Subject: [PATCH 0766/1300] fix(GRewrite): preserve binder names in a forall (#41620) This PR is a follow-up to #40323, and ensures that `grw` preserves binder names and binder info in universal quantifiers. This special-case support is needed because foralls are not represented with a lambda, like all other binders. --- Mathlib/Tactic/GRewrite/Core.lean | 5 ++++- MathlibTest/Tactic/GRewrite.lean | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Mathlib/Tactic/GRewrite/Core.lean b/Mathlib/Tactic/GRewrite/Core.lean index 90d03a868f031d..58140aabfff4c8 100644 --- a/Mathlib/Tactic/GRewrite/Core.lean +++ b/Mathlib/Tactic/GRewrite/Core.lean @@ -332,7 +332,10 @@ partial def grewriteCore (relName : Name) (rel? : Option Expr) (e : Expr) (forwa for gcongrLem in lemmas do if gcongrLem.forGrw then if ← processGCongrLemma goal.mvarId! gcongrLem forward config then - return (← instantiateMVars mvar, goal) + -- Preserve the binder name/info in a forall. + match e, ← instantiateMVars mvar with + | .forallE n _ _ bi, .forallE _ d b _ => return some (.forallE n d b bi, goal) + | _, result => return some (result, goal) setMCtx mctx -- Cache the fact that there was nothing to rewrite. modify fun s ↦ { s with cache := s.cache.insert cacheKey } diff --git a/MathlibTest/Tactic/GRewrite.lean b/MathlibTest/Tactic/GRewrite.lean index 434c5cb6e98a16..cb7404bd831eea 100644 --- a/MathlibTest/Tactic/GRewrite.lean +++ b/MathlibTest/Tactic/GRewrite.lean @@ -129,6 +129,17 @@ example {a b : Nat} (h : a < b) (f : Nat → Nat) (hf : ∀ i, 0 ≤ f i) : trace_state rfl +/-- +trace: α : Type ?u.3 +X Y Z W : Set α +⊢ ∀ {α : Type u_1} [inst : LinearOrder α] (a b : α), max a b ≤ max a b +-/ +#guard_msgs in +example : ∀ {α : Type*} [LinearOrder α] (a b : α), min a b ≤ max a b := by + grw [@inf_le_sup] + trace_state + intros; rfl + end subsets section rationals From 1f165a51dee3b8cf9dbd45716c0b7fe05fa6bf00 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 13 Jul 2026 19:52:05 +0000 Subject: [PATCH 0767/1300] fix(Tactic/DepRewrite): `rw!` produces type incorrect terms (#41594) Fix bug where `rw!` can produce type-incorrect terms when the motive is dependent but the rewritten term is definitionally equal to the original term. See [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/conv-mode.20rw.21.20can.20produce.20type-incorrect.20term/near/609501125). --- Mathlib/Tactic/DepRewrite.lean | 30 +++++++++++-------- MathlibTest/depRewrite.lean | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/Mathlib/Tactic/DepRewrite.lean b/Mathlib/Tactic/DepRewrite.lean index 9fa28c318f8d2f..d098c43be9bb4f 100644 --- a/Mathlib/Tactic/DepRewrite.lean +++ b/Mathlib/Tactic/DepRewrite.lean @@ -23,9 +23,12 @@ theorem dcongrArg.{u, v} {α : Sort u} {a a' : α} {β : (a' : α) → a = a' f a rfl = Eq.rec (motive := fun x h' ↦ β x (h.trans h')) (f a' h) h.symm := by cases h; rfl -theorem nddcongrArg.{u, v} {α : Sort u} {a a' : α} {β : Sort v} - (h : a = a') (f : (a' : α) → (h : a = a') → β) : - f a rfl = f a' h := by +theorem hdcongrArg.{u, v} {α : Sort u} {a a' : α} {β : (a' : α) → a = a' → Sort v} + (h : a = a') (f : (a' : α) → (h : a = a') → β a' h) : + f a rfl ≍ f a' h := by + cases h; rfl + +theorem eq_of_heq.{u} {α : Sort u} {a a' : α} (h : a ≍ a') : a = a' := by cases h; rfl theorem heqL.{u} {α β : Sort u} {a : α} {b : β} (h : HEq a b) : @@ -467,20 +470,21 @@ def _root_.Lean.MVarId.depRewrite (mvarId : MVarId) (e : Expr) (heq : Expr) -- `eqPrf : eAbst lhs rfl = eNew` -- `eAbst lhs rfl ≡ e` let (eNew, eqPrf) ← do - if isDep then - lambdaBoundedTelescope eAbst 2 fun xs eBody => do - let #[x, h] := xs | throwError - "internal error: expected 2 arguments in{indentExpr eAbst}" - let eBodyTp ← inferType eBody - checkCastAllowed eBody eBodyTp config.castMode - let some eBody ← castBack? eBody eBodyTp x h ∅ ∅ | throwError + lambdaBoundedTelescope eAbst 2 fun xs eBody => do + let #[x, h] := xs | throwError + "internal error: expected 2 arguments in{indentExpr eAbst}" + let eBodyTyp ← inferType eBody + let motive ← mkLambdaFVars xs eBodyTyp + if isDep then + checkCastAllowed eBody eBodyTyp config.castMode + let some eBody ← castBack? eBody eBodyTyp x h ∅ ∅ | throwError "internal error: body{indentExpr eBody}\nshould mention '{x}' or '{h}'" - let motive ← mkLambdaFVars xs eBodyTp pure ( eBody.replaceFVars #[x, h] #[rhs, heq], mkApp6 (.const ``dcongrArg [u1, u2]) α lhs rhs motive heq eAbst) - else - pure (eNew, mkApp6 (.const ``nddcongrArg [u1, u2]) α lhs rhs eType heq eAbst) + else + let heqPrf := mkApp6 (.const ``hdcongrArg [u1, u2]) α lhs rhs motive heq eAbst + pure (eNew, mkApp4 (.const ``eq_of_heq [u2]) eType e eNew heqPrf) postprocessAppMVars `depRewrite mvarId newMVars binderInfos (synthAssignedInstances := !tactic.skipAssignedInstances.get (← getOptions)) let newMVarIds ← newMVars.map Expr.mvarId! |>.filterM fun mvarId => diff --git a/MathlibTest/depRewrite.lean b/MathlibTest/depRewrite.lean index 01bc4d43b09a81..d8beb297c52e06 100644 --- a/MathlibTest/depRewrite.lean +++ b/MathlibTest/depRewrite.lean @@ -493,3 +493,57 @@ example (f : Nat → ∀ c, Fin (c + n)) : P (f (f (f m n) (f n m)) n).1 := by rw! (castMode := .all) [eq, ← eq] guard_target =ₛ P ((f (f (f n n) (f n n))) n).1 exact test_sorry + +-- https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/conv-mode.20rw.21.20can.20produce.20type-incorrect.20term/near/609501125 +/-- +trace: n m : Nat +eq : n = m +B : Nat → Type +ι : Type u_1 +X : ι → Sort u_2 +f : (i : ι) → X i +i : ι +y : X i +h : (i, 1).fst = i +| f i +--- +trace: n m : Nat +eq : n = m +B : Nat → Type +ι : Type u_1 +X : ι → Sort u_2 +f : (i : ι) → X i +i : ι +y : X i +h : (i, 1).fst = i +⊢ f i = y +-/ +#guard_msgs in +example {ι : Type*} {X : ι → Sort*} (f : ∀ i, X i) (i : ι) (y : X i) : + f (i, 1).1 = y := by + have h : (i, 1).1 = i := rfl + conv => lhs; rw! [h]; trace_state + trace_state + exact test_sorry + +def PropOrBool (x : Bool) : Type := + bif x then Prop else Bool + +def boolToPropOrBool (x y : Bool) : PropOrBool x := + match x with + | true => y = true + | false => y + +example : let t := true; boolToPropOrBool t t := by + intro t + have h : t = true := rfl + rw! [h] + guard_target =ₛ boolToPropOrBool true true + rfl + +example : let t := true; boolToPropOrBool (t || true) t := by + intro t + have h : t = false := test_sorry + rw! [h] + guard_target =ₛ boolToPropOrBool (false || true) false + contradiction From 8ccbd332c6cc6a43e9a583c60d359f246a7a303c Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 02:27:14 +0000 Subject: [PATCH 0768/1300] chore: update Mathlib dependencies 2026-07-14 (#41715) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index cbd060afa9cc86..99b699c4b2f237 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "6e311e2a844da9b2cc3971187df2fe0066947b93", + "rev": "d662197a9ca6f411c5738c45ec0192c786462f5d", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", From 88c7c14ac20579201b60afdf22dc6dc032da0444 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 03:21:51 +0000 Subject: [PATCH 0769/1300] feat(Data/Finset/Image): `Finset.image` as an `Equiv` (#41683) This PR adds the bijection between a finset `s` and `s.image f`. Co-authored-by: tb65536 --- Mathlib/Data/Finset/Image.lean | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index bb0fd4f4d7885c..c6c5fb2cf921cb 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -253,6 +253,14 @@ theorem map_nontrivial : (s.map f).Nontrivial ↔ s.Nontrivial := theorem attach_map_val {s : Finset α} : s.attach.map (Embedding.subtype _) = s := eq_of_veq <| by rw [map_val, attach_val]; exact Multiset.attach_map_val _ +variable (f s) in +/-- A `Finset` is in bijection with its image under an `Embedding`. -/ +@[simps!] +noncomputable def equivMap : s ≃ s.map f := + .ofBijective (fun x ↦ ⟨f x, s.mem_map_of_mem f x.2⟩) (⟨fun x y ↦ by simp, fun ⟨x, hx⟩ ↦ by + obtain ⟨x, hxs, rfl⟩ := mem_map.mp hx + exact ⟨⟨x, hxs⟩, rfl⟩⟩) + end Map theorem range_add_one' (n : ℕ) : From 14c4b77b0c8c8fe5e0fbc8753e3d7e43f66678d3 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 05:10:54 +0000 Subject: [PATCH 0770/1300] feat(SetTheory/Cardinal/ToNat): `Cardinal.toNat` version of `eq_of_forall_le_iff` (#41691) This PR adds a `Cardinal.toNat` version of `eq_of_forall_le_iff`. This is useful for proving equality of `Module.finrank`. Co-authored-by: tb65536 --- Mathlib/SetTheory/Cardinal/ToNat.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/SetTheory/Cardinal/ToNat.lean b/Mathlib/SetTheory/Cardinal/ToNat.lean index f96e394d2a5a73..d34858d1a18b28 100644 --- a/Mathlib/SetTheory/Cardinal/ToNat.lean +++ b/Mathlib/SetTheory/Cardinal/ToNat.lean @@ -170,4 +170,16 @@ lemma toNat_eq_iff_of_lt_aleph0 {a : Cardinal.{u}} (n : ℕ) (lt : a < Cardinal. nth_rw 2 [← Cardinal.cast_toNat_of_lt_aleph0 lt] exact Nat.cast_inj.symm +/-- A `Cardinal.toNat` version of `eq_of_forall_le_iff`. +This is useful for proving equality of `Module.finrank`. -/ +theorem toNat_eq_of_forall_le_iff {c : Cardinal.{u}} {d : Cardinal.{v}} + (h : ∀ n : ℕ, n ≤ c ↔ n ≤ d) : c.toNat = d.toNat := by + have h' := forall_congr' h + rw [← Cardinal.aleph0_le, ← Cardinal.aleph0_le] at h' + rcases iff_iff_and_or_not_and_not.mp h' with ⟨hc, hd⟩ | ⟨hc, hd⟩ + · simp [Cardinal.toNat_apply_of_aleph0_le, hc, hd] + · apply eq_of_forall_le_iff + rw [← cast_toNat_of_lt_aleph0 (not_le.mp hc), ← cast_toNat_of_lt_aleph0 (not_le.mp hd)] at h + simpa using h + end Cardinal From 677b8c0a9c4e501bdcc92348b7a14d7d35b068a9 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 14 Jul 2026 08:46:19 +0000 Subject: [PATCH 0771/1300] chore: replace `have this` with `have` (#41712) This PR remove all `have this` and `let this` in favour of `have` and `let` directly, which is a minor (and easy) style improvement. Note there are a few exceptions when we cant do the replacement, i.e. when having a statement of the form `have this (n) : ...` Co-authored-by: Batixx --- Archive/Imo/Imo2006Q3.lean | 2 +- Mathlib/Algebra/Homology/ModelCategory/Lifting.lean | 2 +- Mathlib/Algebra/Star/NonUnitalSubalgebra.lean | 2 +- Mathlib/Algebra/Star/Subalgebra.lean | 4 ++-- Mathlib/Analysis/Calculus/FDeriv/Norm.lean | 2 +- Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean | 2 +- Mathlib/Analysis/Normed/Operator/Compact/Basic.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 2 +- Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean | 6 +++--- Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean | 6 +++--- .../Constructions/FiniteProductsOfBinaryProducts.lean | 4 ++-- .../CategoryTheory/Limits/Preserves/FunctorCategory.lean | 2 +- Mathlib/CategoryTheory/Limits/Presheaf.lean | 2 +- Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean | 8 ++++---- Mathlib/CategoryTheory/Preadditive/Biproducts.lean | 2 +- Mathlib/CategoryTheory/Shift/Basic.lean | 2 +- .../SmallObject/IsCardinalForSmallObjectArgument.lean | 2 +- Mathlib/Combinatorics/Configuration.lean | 6 +++--- Mathlib/Data/List/Basic.lean | 2 +- Mathlib/Data/Nat/Init.lean | 2 +- Mathlib/Data/Seq/Basic.lean | 2 +- Mathlib/GroupTheory/Perm/Centralizer.lean | 2 +- Mathlib/GroupTheory/QuotientGroup/Basic.lean | 2 +- .../SpecificGroups/Alternating/Centralizer.lean | 2 +- Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean | 2 +- Mathlib/LinearAlgebra/Reflection.lean | 2 +- Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean | 2 +- Mathlib/MeasureTheory/Integral/Prod.lean | 2 +- Mathlib/Order/RelSeries.lean | 4 ++-- Mathlib/Probability/CentralLimitTheorem.lean | 2 +- Mathlib/Probability/Distributions/Uniform.lean | 2 +- .../Probability/Kernel/Composition/IntegralCompProd.lean | 2 +- Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean | 2 +- Mathlib/RingTheory/FractionalIdeal/Operations.lean | 2 +- Mathlib/RingTheory/Polynomial/ScaleRoots.lean | 2 +- Mathlib/RingTheory/Smooth/Basic.lean | 4 ++-- Mathlib/SetTheory/ZFC/Basic.lean | 2 +- Mathlib/Tactic/NormNum/Ordinal.lean | 8 ++++---- Mathlib/Topology/Algebra/InfiniteSum/Module.lean | 2 +- Mathlib/Topology/Algebra/InfiniteSum/Ring.lean | 2 +- Mathlib/Topology/Algebra/Module/ModuleTopology.lean | 2 +- Mathlib/Topology/Connected/TotallyDisconnected.lean | 2 +- Mathlib/Topology/Order/OrderClosed.lean | 2 +- Mathlib/Topology/Sion.lean | 2 +- MathlibTest/Clean.lean | 2 +- 45 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Archive/Imo/Imo2006Q3.lean b/Archive/Imo/Imo2006Q3.lean index 9a60dba50d1b0b..17c5d90b00c595 100644 --- a/Archive/Imo/Imo2006Q3.lean +++ b/Archive/Imo/Imo2006Q3.lean @@ -55,7 +55,7 @@ theorem zero_lt_32 : (0 : ℝ) < 32 := by simp theorem subst_wlog {x y z s : ℝ} (hxy : 0 ≤ x * y) (hxyz : x + y + z = 0) : 32 * |x * y * z * s| ≤ sqrt 2 * (x ^ 2 + y ^ 2 + z ^ 2 + s ^ 2) ^ 2 := by have hz : (x + y) ^ 2 = z ^ 2 := by linear_combination (x + y - z) * hxyz - have this := + have := calc 2 * s ^ 2 * (16 * x ^ 2 * y ^ 2 * (x + y) ^ 2) ≤ _ * _ ^ 3 := by gcongr; exact lhs_ineq hxy diff --git a/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean b/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean index 45271328faa704..4a8d77e9b58f8b 100644 --- a/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean +++ b/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean @@ -106,7 +106,7 @@ noncomputable def cocycle₁ : Cocycle Q K 1 := have : Epi π := Cofork.IsColimit.epi hQ have : Mono ι := Fork.IsLimit.mono hK ext n _ rfl - have this := Cochain.congr_v ((cocycle₁' sq hsq).δ_eq_zero 2) n _ rfl + have := Cochain.congr_v ((cocycle₁' sq hsq).δ_eq_zero 2) n _ rfl rw [Cochain.zero_v, δ_v _ _ (by simp) _ _ _ _ (n + 1) _ (by lia) rfl, Int.negOnePow_even 2 ⟨1, by simp⟩, one_smul] at this ⊢ rwa [← cancel_mono (ι.f (n + 2)), ← cancel_epi (π.f n), diff --git a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean index 4ff88552ac4834..80934eec23f179 100644 --- a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean @@ -598,7 +598,7 @@ variable [IsScalarTower R A A] [SMulCommClass R A A] /-- The star operation on `NonUnitalSubalgebra` commutes with `NonUnitalAlgebra.adjoin`. -/ theorem star_adjoin_comm (s : Set A) : star (NonUnitalAlgebra.adjoin R s) = NonUnitalAlgebra.adjoin R (star s) := - have this : + have : ∀ t : Set A, NonUnitalAlgebra.adjoin R (star t) ≤ star (NonUnitalAlgebra.adjoin R t) := fun _ => NonUnitalAlgebra.adjoin_le fun _ hx => NonUnitalAlgebra.subset_adjoin R hx le_antisymm (by simpa only [star_star] using NonUnitalSubalgebra.star_mono (this (star s))) diff --git a/Mathlib/Algebra/Star/Subalgebra.lean b/Mathlib/Algebra/Star/Subalgebra.lean index d729e0d61d2a4f..c9039e2bbcc875 100644 --- a/Mathlib/Algebra/Star/Subalgebra.lean +++ b/Mathlib/Algebra/Star/Subalgebra.lean @@ -282,7 +282,7 @@ theorem comap_injective {f : A →⋆ₐ[R] B} (hf : Function.Surjective f) : Function.Injective (comap f) := fun _S₁ _S₂ h => ext fun b => let ⟨x, hx⟩ := hf b - let this := SetLike.ext_iff.1 h x + let := SetLike.ext_iff.1 h x hx ▸ this @[simp] @@ -381,7 +381,7 @@ theorem star_mono : Monotone (star : Subalgebra R A → Subalgebra R A) := fun _ variable (R) in /-- The star operation on `Subalgebra` commutes with `Algebra.adjoin`. -/ theorem star_adjoin_comm (s : Set A) : star (Algebra.adjoin R s) = Algebra.adjoin R (star s) := - have this : ∀ t : Set A, Algebra.adjoin R (star t) ≤ star (Algebra.adjoin R t) := fun _ => + have : ∀ t : Set A, Algebra.adjoin R (star t) ≤ star (Algebra.adjoin R t) := fun _ => Algebra.adjoin_le fun _ hx => Algebra.subset_adjoin hx le_antisymm (by simpa only [star_star] using Subalgebra.star_mono (this (star s))) (this s) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Norm.lean b/Mathlib/Analysis/Calculus/FDeriv/Norm.lean index f768fd12622ee4..3e4551ac46d5fe 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Norm.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Norm.lean @@ -154,7 +154,7 @@ theorem DifferentiableAt.differentiableAt_norm_of_smul (h : DifferentiableAt ℝ theorem DifferentiableAt.fderiv_norm_self {x : E} (h : DifferentiableAt ℝ (‖·‖) x) : fderiv ℝ (‖·‖) x x = ‖x‖ := by rw [← h.lineDeriv_eq_fderiv, lineDeriv] - have this (t : ℝ) : ‖x + t • x‖ = |1 + t| * ‖x‖ := by + have (t : ℝ) : ‖x + t • x‖ = |1 + t| * ‖x‖ := by rw [← norm_eq_abs, ← norm_smul, add_smul, one_smul] simp_rw [this] rw [deriv_mul_const] diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean index 2af2a8e852a39a..08d6de288e36bb 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean @@ -107,7 +107,7 @@ instance hasLimit_parallelPair {V W : SemiNormedGrp.{u}} (f g : V ⟶ W) : Nonempty.intro { cone := fork f g isLimit := - have this := fun (c : Fork f g) => + have := fun (c : Fork f g) => show NormedAddGroupHom.compHom (f - g).hom c.ι.hom = 0 by rw [hom_sub, map_sub, AddMonoidHom.sub_apply, sub_eq_zero] exact congr_arg Hom.hom c.condition diff --git a/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean b/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean index 9a8ca0e373bacc..4b0f7c8bd1186c 100644 --- a/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean @@ -125,7 +125,7 @@ theorem IsCompactOperator.image_subset_compact_of_isVonNBounded {f : M₁ →ₛ let ⟨K, hK, hKf⟩ := hf let ⟨r, hr, hrS⟩ := (hS hKf).exists_pos let ⟨c, hc⟩ := NormedField.exists_lt_norm 𝕜₁ r - let this := ne_zero_of_norm_ne_zero (hr.trans hc).ne.symm + let := ne_zero_of_norm_ne_zero (hr.trans hc).ne.symm ⟨σ₁₂ c • K, hK.image <| continuous_id.const_smul (σ₁₂ c), by rw [image_subset_iff, this.isUnit.preimage_smul_setₛₗ σ₁₂]; exact hrS c hc.le⟩ diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index d306b69cbbf6ce..6285f64161f237 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -1177,7 +1177,7 @@ theorem continuous_finsetSup [TopologicalSpace E] [IsTopologicalAddGroup E] lemma ball_mem_nhds [TopologicalSpace E] {p : Seminorm 𝕝 E} (hp : Continuous p) {r : ℝ} (hr : 0 < r) : p.ball 0 r ∈ (𝓝 0 : Filter E) := by - have this : Tendsto p (𝓝 0) (𝓝 0) := map_zero p ▸ hp.tendsto 0 + have : Tendsto p (𝓝 0) (𝓝 0) := map_zero p ▸ hp.tendsto 0 simpa only [p.ball_zero_eq] using! this (Iio_mem_nhds hr) lemma uniformSpace_eq_of_hasBasis diff --git a/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean b/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean index c6eb21b424287d..10369154600ecf 100644 --- a/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean +++ b/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean @@ -202,15 +202,15 @@ lemma isRightAdjoint_triangle_lift_monadic (U : B ⥤ C) [MonadicRightAdjoint U] [HasReflexiveCoequalizers A] [(R ⋙ U).IsRightAdjoint] : R.IsRightAdjoint := by let R' : A ⥤ _ := R ⋙ Monad.comparison (monadicAdjunction U) rsuffices : R'.IsRightAdjoint - · let this : (R' ⋙ (Monad.comparison (monadicAdjunction U)).inv).IsRightAdjoint := by + · let : (R' ⋙ (Monad.comparison (monadicAdjunction U)).inv).IsRightAdjoint := by infer_instance refine ((Adjunction.ofIsRightAdjoint (R' ⋙ (Monad.comparison (monadicAdjunction U)).inv)).ofNatIsoRight ?_).isRightAdjoint exact Functor.isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm ≪≫ R.rightUnitor - let this : (R' ⋙ Monad.forget (monadicAdjunction U).toMonad).IsRightAdjoint := by + let : (R' ⋙ Monad.forget (monadicAdjunction U).toMonad).IsRightAdjoint := by refine ((Adjunction.ofIsRightAdjoint (R ⋙ U)).ofNatIsoRight ?_).isRightAdjoint exact Functor.isoWhiskerLeft R (Monad.comparisonForget (monadicAdjunction U)).symm - let this : ∀ X, RegularEpi ((Monad.adj (monadicAdjunction U).toMonad).counit.app X) := by + let : ∀ X, RegularEpi ((Monad.adj (monadicAdjunction U).toMonad).counit.app X) := by intro X simp only [Monad.adj_counit] exact ⟨_, _, _, _, Monad.beckAlgebraCoequalizer X⟩ diff --git a/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean b/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean index 1648118141e187..162175cb9d23c4 100644 --- a/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean +++ b/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean @@ -194,15 +194,15 @@ lemma isLeftAdjoint_triangle_lift_comonadic (F : B ⥤ A) [ComonadicLeftAdjoint [HasCoreflexiveEqualizers C] [(L ⋙ F).IsLeftAdjoint] : L.IsLeftAdjoint := by let L' : _ ⥤ _ := L ⋙ Comonad.comparison (comonadicAdjunction F) rsuffices : L'.IsLeftAdjoint - · let this : (L' ⋙ (Comonad.comparison (comonadicAdjunction F)).inv).IsLeftAdjoint := by + · let : (L' ⋙ (Comonad.comparison (comonadicAdjunction F)).inv).IsLeftAdjoint := by infer_instance refine ((Adjunction.ofIsLeftAdjoint (L' ⋙ (Comonad.comparison (comonadicAdjunction F)).inv)).ofNatIsoLeft ?_).isLeftAdjoint exact Functor.isoWhiskerLeft L (Comonad.comparison _).asEquivalence.unitIso.symm ≪≫ L.leftUnitor - let this : (L' ⋙ Comonad.forget (comonadicAdjunction F).toComonad).IsLeftAdjoint := by + let : (L' ⋙ Comonad.forget (comonadicAdjunction F).toComonad).IsLeftAdjoint := by refine ((Adjunction.ofIsLeftAdjoint (L ⋙ F)).ofNatIsoLeft ?_).isLeftAdjoint exact Functor.isoWhiskerLeft L (Comonad.comparisonForget (comonadicAdjunction F)).symm - let this : ∀ X, RegularMono ((Comonad.adj (comonadicAdjunction F).toComonad).unit.app X) := by + let : ∀ X, RegularMono ((Comonad.adj (comonadicAdjunction F).toComonad).unit.app X) := by intro X simp only [Comonad.adj_unit] exact ⟨_, _, _, _, Comonad.beckCoalgebraEqualizer X⟩ diff --git a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean index cb582d90a1552c..16c1a911232acc 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean @@ -136,7 +136,7 @@ lemma preservesFinOfPreservesBinaryAndTerminal : preservesLimit_of_preserves_limit_cone (extendFanIsLimit f (limit.isLimit _) (limit.isLimit _)) _ apply (isLimitMapConeFanMkEquiv _ _ _).symm _ - let this := + let := extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F _) (isLimitOfHasBinaryProductOfPreservesLimit F _ _) refine IsLimit.ofIsoLimit this ?_ @@ -261,7 +261,7 @@ lemma preserves_fin_of_preserves_binary_and_initial : preservesColimit_of_preserves_colimit_cocone (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _ apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _ - let this := + let := extendCofanIsColimit (fun i => F.obj (f i)) (isColimitOfHasCoproductOfPreservesColimit F _) (isColimitOfHasBinaryCoproductOfPreservesColimit F _ _) diff --git a/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean b/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean index 1445294592acbc..359e764250e1af 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean @@ -67,7 +67,7 @@ lemma FunctorCategory.prod_preservesColimits [HasBinaryProducts D] [HasColimits preserves := fun {c : Cocone K} (t : IsColimit c) => ⟨by apply evaluationJointlyReflectsColimits _ fun {k} => ?_ change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c) - let this := + let := isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t apply IsColimit.mapCoconeEquiv _ this apply (NatIso.ofComponents _ _).symm diff --git a/Mathlib/CategoryTheory/Limits/Presheaf.lean b/Mathlib/CategoryTheory/Limits/Presheaf.lean index 59fe1e8925575b..f833f6546eea73 100644 --- a/Mathlib/CategoryTheory/Limits/Presheaf.lean +++ b/Mathlib/CategoryTheory/Limits/Presheaf.lean @@ -85,7 +85,7 @@ lemma map_comp_uliftYonedaEquiv_down (E : ℰ) {X Y : C} (f : X ⟶ Y) (g : uliftYoneda.{max w v₂}.obj Y ⟶ (restrictedULiftYoneda.{max w v₁} A).obj E) : A.map f ≫ (uliftYonedaEquiv g).down = (uliftYonedaEquiv (uliftYoneda.map f ≫ g)).down := by - have this := (g.naturality_apply f.op) (ULift.up (𝟙 Y)) + have := (g.naturality_apply f.op) (ULift.up (𝟙 Y)) dsimp [uliftYonedaEquiv, uliftYoneda] at this ⊢ cat_disch diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 168fcf4e55e9dc..8ede7661f528eb 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -296,11 +296,11 @@ def whiskerToCocone {f : J → C} (c : Bicone f) (g : K ≃ J) : noncomputable def whiskerIsBilimitIff {f : J → C} (c : Bicone f) (g : K ≃ J) : (c.whisker g).IsBilimit ≃ c.IsBilimit := by refine equivOfSubsingletonOfSubsingleton (fun hc => ⟨?_, ?_⟩) fun hc => ⟨?_, ?_⟩ - · let this := IsLimit.ofIsoLimit hc.isLimit (Bicone.whiskerToCone c g) - let this := (IsLimit.postcomposeHomEquiv (Discrete.functorComp f g).symm _) this + · let := IsLimit.ofIsoLimit hc.isLimit (Bicone.whiskerToCone c g) + let := (IsLimit.postcomposeHomEquiv (Discrete.functorComp f g).symm _) this exact IsLimit.ofWhiskerEquivalence (Discrete.equivalence g) this - · let this := IsColimit.ofIsoColimit hc.isColimit (Bicone.whiskerToCocone c g) - let this := (IsColimit.precomposeHomEquiv (Discrete.functorComp f g) _) this + · let := IsColimit.ofIsoColimit hc.isColimit (Bicone.whiskerToCocone c g) + let := (IsColimit.precomposeHomEquiv (Discrete.functorComp f g) _) this exact IsColimit.ofWhiskerEquivalence (Discrete.equivalence g) this · apply IsLimit.ofIsoLimit _ (Bicone.whiskerToCone c g).symm apply (IsLimit.postcomposeHomEquiv (Discrete.functorComp f g).symm _).symm _ diff --git a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean index 003a6a2ae4b31b..f21956f433342a 100644 --- a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean +++ b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean @@ -778,7 +778,7 @@ via Gaussian elimination. def Biprod.gaussian (f : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂) [IsIso (biprod.inl ≫ f ≫ biprod.fst)] : Σ' (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) (g₂₂ : X₂ ⟶ Y₂), L.hom ≫ f ≫ R.hom = biprod.map (biprod.inl ≫ f ≫ biprod.fst) g₂₂ := by - let this := + let := Biprod.gaussian' (biprod.inl ≫ f ≫ biprod.fst) (biprod.inl ≫ f ≫ biprod.snd) (biprod.inr ≫ f ≫ biprod.fst) (biprod.inr ≫ f ≫ biprod.snd) rwa [Biprod.ofComponents_eq] at this diff --git a/Mathlib/CategoryTheory/Shift/Basic.lean b/Mathlib/CategoryTheory/Shift/Basic.lean index 512b3a71c90453..9b80634563f384 100644 --- a/Mathlib/CategoryTheory/Shift/Basic.lean +++ b/Mathlib/CategoryTheory/Shift/Basic.lean @@ -809,7 +809,7 @@ def hasShift : dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)] simp [shiftFunctorAdd', eqToHom_map]) zero_add_hom_app := fun n X => hF.map_injective (by - have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n) + have := dcongr_arg (fun a => (i a).hom.app X) (zero_add n) rw [← cancel_mono ((i n).hom.app ((s 0).obj X))] simp only [comp_obj, map_add_hom_app, this, shiftFunctorAdd_zero_add_hom_app, id_obj, Category.assoc, eqToHom_trans_assoc, eqToHom_refl, Category.id_comp, Iso.inv_hom_id_app, diff --git a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean index eaeabf4d62d737..2e73c9c13525a5 100644 --- a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean +++ b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean @@ -261,7 +261,7 @@ noncomputable def iterationFunctorMapSuccAppArrowIso (f : Arrow C) (j : κ.ord.T Arrow.isoMk (Iso.refl _) (((evaluation _ _).obj f).mapIso ((succStruct I κ).iterationFunctorObjSuccIso j (not_isMax j))) (by - have this := NatTrans.congr_app ((succStruct I κ).iterationFunctor_map_succ j (not_isMax j)) f + have := NatTrans.congr_app ((succStruct I κ).iterationFunctor_map_succ j (not_isMax j)) f dsimp at this dsimp [iterationFunctor] rw [id_comp, this, assoc, Iso.inv_hom_id_app, comp_id] diff --git a/Mathlib/Combinatorics/Configuration.lean b/Mathlib/Combinatorics/Configuration.lean index 051a7cb6b3de49..a24fbf50717b85 100644 --- a/Mathlib/Combinatorics/Configuration.lean +++ b/Mathlib/Combinatorics/Configuration.lean @@ -230,7 +230,7 @@ theorem HasLines.card_le [HasLines P L] [Fintype P] [Fintype L] : · rw [lineCount, Nat.card_eq_fintype_card, Fintype.card_pos_iff] obtain ⟨l, _⟩ := @exists_line P L _ _ p exact - let this := not_exists.mp hp l + let := not_exists.mp hp l ⟨⟨mkLine this, (mkLine_ax this).2⟩⟩ exact lt_irrefl _ this @@ -286,7 +286,7 @@ theorem HasPoints.lineCount_eq_pointCount [HasPoints P L] [Fintype P] [Fintype L @[implicit_reducible] noncomputable def HasLines.hasPoints [HasLines P L] [Fintype P] [Fintype L] (h : Fintype.card P = Fintype.card L) : HasPoints P L := - let this : ∀ l₁ l₂ : L, l₁ ≠ l₂ → ∃ p : P, p ∈ l₁ ∧ p ∈ l₂ := fun l₁ l₂ hl => by + let : ∀ l₁ l₂ : L, l₁ ≠ l₂ → ∃ p : P, p ∈ l₁ ∧ p ∈ l₂ := fun l₁ l₂ hl => by classical obtain ⟨f, _, hf2⟩ := HasLines.exists_bijective_of_card_eq h haveI : Nontrivial L := ⟨⟨l₁, l₂, hl⟩⟩ @@ -321,7 +321,7 @@ noncomputable def HasLines.hasPoints [HasLines P L] [Fintype P] [Fintype L] @[implicit_reducible] noncomputable def HasPoints.hasLines [HasPoints P L] [Fintype P] [Fintype L] (h : Fintype.card P = Fintype.card L) : HasLines P L := - let this := @HasLines.hasPoints (Dual L) (Dual P) _ _ _ _ h.symm + let := @HasLines.hasPoints (Dual L) (Dual P) _ _ _ _ h.symm { ‹HasPoints P L› with mkLine := @fun _ _ => this.mkPoint mkLine_ax := @fun _ _ => this.mkPoint_ax } diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 7934ab8744cd87..3e8b01e90c6e3b 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -1007,7 +1007,7 @@ theorem length_erase_add_one {a : α} {l : List α} (h : a ∈ l) : theorem map_erase [BEq β] [LawfulBEq β] {f : α → β} (finj : Injective f) {a : α} (l : List α) : map f (l.erase a) = (map f l).erase (f a) := by - have this : (a == ·) = (f a == f ·) := by ext b; simp [finj.eq_iff] + have : (a == ·) = (f a == f ·) := by ext b; simp [finj.eq_iff] rw [erase_eq_eraseP, erase_eq_eraseP, eraseP_map, this]; rfl theorem map_foldl_erase [BEq β] [LawfulBEq β] {f : α → β} (finj : Injective f) {l₁ l₂ : List α} : diff --git a/Mathlib/Data/Nat/Init.lean b/Mathlib/Data/Nat/Init.lean index cb4e7df684123e..1593364ec90cad 100644 --- a/Mathlib/Data/Nat/Init.lean +++ b/Mathlib/Data/Nat/Init.lean @@ -358,7 +358,7 @@ theorem diag_induction (P : ℕ → ℕ → Prop) (ha : ∀ a, P (a + 1) (a + 1) | 0, _ + 1, _ => hb _ | a + 1, b + 1, h => by apply hd _ _ (Nat.add_lt_add_iff_right.1 h) - · have this : a + 1 = b ∨ a + 1 < b := by lia + · have : a + 1 = b ∨ a + 1 < b := by lia rcases this with (rfl | h) · exact ha _ apply diag_induction P ha hb hd (a + 1) b h diff --git a/Mathlib/Data/Seq/Basic.lean b/Mathlib/Data/Seq/Basic.lean index b45364cc18b8b7..7be37bed43fb01 100644 --- a/Mathlib/Data/Seq/Basic.lean +++ b/Mathlib/Data/Seq/Basic.lean @@ -313,7 +313,7 @@ theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) simpa using m | cons c t₁ => intro m e - have this := congr_arg destruct e + have := congr_arg destruct e rcases show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' | m · rw [e'] exact Or.inl (mem_cons _ _) diff --git a/Mathlib/GroupTheory/Perm/Centralizer.lean b/Mathlib/GroupTheory/Perm/Centralizer.lean index 919c6f7deb3157..920a838ccbb773 100644 --- a/Mathlib/GroupTheory/Perm/Centralizer.lean +++ b/Mathlib/GroupTheory/Perm/Centralizer.lean @@ -120,7 +120,7 @@ lemma Subgroup.Centralizer.toConjAct_smul_mem_cycleFactorsFinset {k c : Perm α} (ConjAct.toConjAct k) • g.cycleFactorsFinset by rw [← Finset.mem_coe, this] simp only [Set.smul_mem_smul_set_iff, Finset.mem_coe, c_mem] - have this := cycleFactorsFinset_conj_eq (ConjAct.toConjAct (k : Perm α)) g + have := cycleFactorsFinset_conj_eq (ConjAct.toConjAct (k : Perm α)) g rw [ConjAct.toConjAct_smul, mem_centralizer_singleton_iff.mp k_mem, mul_assoc] at this simp only [mul_inv_cancel, mul_one] at this conv_lhs => rw [this] diff --git a/Mathlib/GroupTheory/QuotientGroup/Basic.lean b/Mathlib/GroupTheory/QuotientGroup/Basic.lean index 43921ef5032ee4..8e12e066332e75 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Basic.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Basic.lean @@ -390,7 +390,7 @@ theorem subsingleton_quotient_top : Subsingleton (G ⧸ (⊤ : Subgroup G)) := b subgroup is the whole additive group. -/] theorem subgroup_eq_top_of_subsingleton (H : Subgroup G) (h : Subsingleton (G ⧸ H)) : H = ⊤ := top_unique fun x _ => by - have this : 1⁻¹ * x ∈ H := QuotientGroup.eq.1 (Subsingleton.elim _ _) + have : 1⁻¹ * x ∈ H := QuotientGroup.eq.1 (Subsingleton.elim _ _) rwa [inv_one, one_mul] at this end trivial diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean index 0814180e5da1c6..671e2bf4d34ddc 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean @@ -185,7 +185,7 @@ theorem count_le_one_of_centralizer_le_alternating even_two, Even.mul_left, Even.neg_pow, one_pow, one_mul] apply Odd.neg_one_pow apply odd_of_centralizer_le_alternatingGroup h - have this : (k : Perm α).cycleType.card * 2 = (k : Perm α).support.card := by + have : (k : Perm α).cycleType.card * 2 = (k : Perm α).support.card := by rw [← sum_cycleType, hk_cT] simp have that : Multiset.card (k : Perm α).cycleType = (c : Perm α).support.card := by diff --git a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean index 909bb28e8236b7..62909b38c9dc33 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean @@ -192,7 +192,7 @@ theorem inf_iSup_genEigenspace [FiniteDimensional K V] (h : ∀ x ∈ p, f x ∈ f.mapsTo_genEigenspace_of_comm hfg μ k have hg₃ : InjOn g ↑(f.genEigenspace μ k) := by apply LinearMap.injOn_of_disjoint_ker subset_rfl - have this := f.independent_genEigenspace k + have := f.independent_genEigenspace k have aux (μ') (_hμ' : μ' ∈ m.support.erase μ) : (f.genEigenspace μ') ↑l₀ ≤ (f.genEigenspace μ') k := by apply (f.genEigenspace μ').mono diff --git a/Mathlib/LinearAlgebra/Reflection.lean b/Mathlib/LinearAlgebra/Reflection.lean index e466bd0d0c813c..fc9dd092b2a985 100644 --- a/Mathlib/LinearAlgebra/Reflection.lean +++ b/Mathlib/LinearAlgebra/Reflection.lean @@ -388,7 +388,7 @@ lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [IsDomain R] [IsTorsionFree rw [range_inclusion] simp let x' : span R Φ := ⟨x, hx⟩ - have this : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ → + have : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ → MapsTo (preReflection x' ((span R Φ).subtype.dualMap F)) Φ' Φ' := by intro F hF ⟨y, hy⟩ hy' simp only [Φ'] at hy' ⊢ diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean index e557a7f8d6b6e1..edce6dcdfeb79f 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean @@ -581,7 +581,7 @@ include P in lemma card_index_eq_twelve : Nat.card ι = 12 := by classical - have this : Nat.card (allRoots P).toFinset = 12 := by + have : Nat.card (allRoots P).toFinset = 12 := by rw [Nat.card_eq_fintype_card, Fintype.card_coe, toFinset_card_of_nodup (allRoots_nodup P)] simp rw [← this] diff --git a/Mathlib/MeasureTheory/Integral/Prod.lean b/Mathlib/MeasureTheory/Integral/Prod.lean index db1b5939973c22..a0757cf3a92874 100644 --- a/Mathlib/MeasureTheory/Integral/Prod.lean +++ b/Mathlib/MeasureTheory/Integral/Prod.lean @@ -428,7 +428,7 @@ theorem continuous_integral_integral : apply tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds _ (fun i => zero_le) _ · exact fun i => ∫⁻ x, ∫⁻ y, ‖i (x, y) - g (x, y)‖ₑ ∂ν ∂μ swap; · exact fun i => lintegral_mono fun x => enorm_integral_le_lintegral_enorm _ - have this (i : α × β →₁[μ.prod ν] E) : Measurable fun z => ‖i z - g z‖ₑ := + have (i : α × β →₁[μ.prod ν] E) : Measurable fun z => ‖i z - g z‖ₑ := ((Lp.stronglyMeasurable i).sub (Lp.stronglyMeasurable g)).enorm simp_rw [← lintegral_prod _ (this _).aemeasurable, ← L1.ofReal_norm_sub_eq_lintegral, ← ofReal_zero] diff --git a/Mathlib/Order/RelSeries.lean b/Mathlib/Order/RelSeries.lean index de64ff43f100f3..e47695bfec369b 100644 --- a/Mathlib/Order/RelSeries.lean +++ b/Mathlib/Order/RelSeries.lean @@ -614,7 +614,7 @@ def inductionOn (motive : RelSeries r → Sort*) (cons : (p : RelSeries r) → (x : α) → (hx : x ~[r] p.head) → (hp : motive p) → motive (p.cons x hx)) (p : RelSeries r) : motive p := by - let this {n : ℕ} (heq : p.length = n) : motive p := by + let {n : ℕ} (heq : p.length = n) : motive p := by induction n generalizing p with | zero => convert! singleton p.head @@ -679,7 +679,7 @@ def inductionOn' (motive : RelSeries r → Sort*) (snoc : (p : RelSeries r) → (x : α) → (hx : p.last ~[r] x) → (hp : motive p) → motive (p.snoc x hx)) (p : RelSeries r) : motive p := by - let this {n : ℕ} (heq : p.length = n) : motive p := by + let {n : ℕ} (heq : p.length = n) : motive p := by induction n generalizing p with | zero => convert! singleton p.head diff --git a/Mathlib/Probability/CentralLimitTheorem.lean b/Mathlib/Probability/CentralLimitTheorem.lean index 1e1676806ae8f7..245a5c81bd45f0 100644 --- a/Mathlib/Probability/CentralLimitTheorem.lean +++ b/Mathlib/Probability/CentralLimitTheorem.lean @@ -103,7 +103,7 @@ private theorem tendstoInDistribution_inv_sqrt_mul_var_mul_sum_sub have mX0 := (hident 0).aemeasurable_fst have intX0 : Integrable (X 0) P := memLp_one_iff_integrable.1 <| (memLp_two_of_variance_ne_zero mX0.aestronglyMeasurable hX).mono_exponent (by simp) - have this (n : ℕ) ω : (√(n * Var[X 0; P]))⁻¹ * (∑ k ∈ Finset.range n, X k ω - n * P[X 0]) = + have (n : ℕ) ω : (√(n * Var[X 0; P]))⁻¹ * (∑ k ∈ Finset.range n, X k ω - n * P[X 0]) = (√n)⁻¹ * ∑ k ∈ Finset.range n, (X k ω - P[X 0]) / √Var[X 0; P] := by rw [← Finset.sum_div, Finset.sum_sub_distrib] simp [field] diff --git a/Mathlib/Probability/Distributions/Uniform.lean b/Mathlib/Probability/Distributions/Uniform.lean index ccf3e23c43c6fe..9afe5ff77bc9fc 100644 --- a/Mathlib/Probability/Distributions/Uniform.lean +++ b/Mathlib/Probability/Distributions/Uniform.lean @@ -263,7 +263,7 @@ theorem toOuterMeasure_uniformOfFinset_apply : tsum_eq_sum fun _ hx => if_neg fun h => hx (Finset.mem_filter.2 h) _ = ∑ x ∈ s with x ∈ t, (#s : ℝ≥0∞)⁻¹ := Finset.sum_congr rfl fun x hx => by - have this : x ∈ s ∧ x ∈ t := by simpa using hx + have : x ∈ s ∧ x ∈ t := by simpa using hx simp only [this, and_self_iff, if_true] _ = #{x ∈ s | x ∈ t} / #s := by simp only [div_eq_mul_inv, Finset.sum_const, nsmul_eq_mul] diff --git a/Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean b/Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean index fcf1bdcd3fcbaa..9f3f6be36a298a 100644 --- a/Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/IntegralCompProd.lean @@ -222,7 +222,7 @@ theorem Kernel.continuous_integral_integral : apply tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds _ (fun i => zero_le) _ · exact fun i => ∫⁻ x, ∫⁻ y, ‖i (x, y) - g (x, y)‖ₑ ∂η (a, x) ∂κ a swap; · exact fun i => lintegral_mono fun x => enorm_integral_le_lintegral_enorm _ - have this (i : Lp (α := β × γ) E 1 (((κ ⊗ₖ η) a) : Measure (β × γ))) : + have (i : Lp (α := β × γ) E 1 (((κ ⊗ₖ η) a) : Measure (β × γ))) : Measurable fun z => ‖i z - g z‖ₑ := ((Lp.stronglyMeasurable i).sub (Lp.stronglyMeasurable g)).enorm simp_rw [← lintegral_compProd _ _ _ (this _), ← L1.ofReal_norm_sub_eq_lintegral, ← ofReal_zero] diff --git a/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean b/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean index 18941666d8d90e..15d96abefdd774 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean @@ -74,7 +74,7 @@ lemma tensorCotangentSpace_tmul_tmul (t : T) (s : S) (x : Ω[P.Ring⁄R]) : ← mk_apply s x, IsTensorProduct.assocOfMapSMul_symm_tmul] simp only [mk_apply, AlgebraTensorModule.cancelBaseChange_symm_tmul, AlgebraTensorModule.congr_tmul, LinearEquiv.refl_apply] - have this : x ∈ Submodule.span P.Ring (Set.range (KaehlerDifferential.D R P.Ring)) := by + have : x ∈ Submodule.span P.Ring (Set.range (KaehlerDifferential.D R P.Ring)) := by rw [KaehlerDifferential.span_range_derivation] trivial induction this using Submodule.span_induction with diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index 40978b008c9367..9f82c47edd5264 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -350,7 +350,7 @@ variable [Algebra R₁ K] instance : Nontrivial (FractionalIdeal R₁⁰ K) := ⟨⟨0, 1, fun h => - have this : (1 : K) ∈ (0 : FractionalIdeal R₁⁰ K) := by + have : (1 : K) ∈ (0 : FractionalIdeal R₁⁰ K) := by rw [← (algebraMap R₁ K).map_one] simpa only [h] using coe_mem_one R₁⁰ 1 one_ne_zero ((mem_zero_iff _).mp this)⟩⟩ diff --git a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean index 1ba2255c027ed2..b6407237a13e81 100644 --- a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean +++ b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean @@ -136,7 +136,7 @@ theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s simp [eval₂_eq_sum, sum_def] _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i := (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by - let this : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi' + let : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi' simp [this]) _ = p.support.sum fun i : ℕ => f (p.coeff i) * f s ^ (p.natDegree - i + i) * a ^ i := (Finset.sum_congr rfl fun i _hi => by diff --git a/Mathlib/RingTheory/Smooth/Basic.lean b/Mathlib/RingTheory/Smooth/Basic.lean index 54640dfe993ab0..ed53c3ad419b47 100644 --- a/Mathlib/RingTheory/Smooth/Basic.lean +++ b/Mathlib/RingTheory/Smooth/Basic.lean @@ -135,7 +135,7 @@ theorem exists_lift apply Ideal.IsNilpotent.induction_on (S := B) I hI · intro B _ I hI _; exact FormallySmooth.comp_surjective R A I hI · intro B _ I J hIJ h₁ h₂ _ g - let this : ((B ⧸ I) ⧸ J.map (Ideal.Quotient.mk I)) ≃ₐ[R] B ⧸ J := + let : ((B ⧸ I) ⧸ J.map (Ideal.Quotient.mk I)) ≃ₐ[R] B ⧸ J := { (DoubleQuot.quotQuotEquivQuotSup I J).trans (Ideal.quotEquivOfEq (sup_eq_right.mpr hIJ)) with commutes' := fun x => rfl } @@ -488,7 +488,7 @@ theorem of_isLocalization : FormallySmooth R Rₘ := by apply (IsNilpotent.isUnit_quotient_mk_iff ⟨2, e⟩).mp convert! (IsLocalization.map_units Rₘ x).map f simp only [Ideal.Quotient.mk_algebraMap, AlgHom.commutes] - let this : Rₘ →ₐ[R] Q := + let : Rₘ →ₐ[R] Q := { IsLocalization.lift this with commutes' := IsLocalization.lift_eq this } use this apply AlgHom.coe_ringHom_injective diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index 162994b751eef2..289dbb07ff7f4e 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -509,7 +509,7 @@ lemma coe_sInter (h : x.Nonempty) : (⋂₀ x : Set ZFSet) = ⋂₀ (SetLike.coe simp [mem_sInter h] theorem singleton_injective : Function.Injective (@singleton ZFSet ZFSet _) := fun x y H => by - let this := congr_arg sUnion H + let := congr_arg sUnion H rwa [sUnion_singleton, sUnion_singleton] at this @[simp] diff --git a/Mathlib/Tactic/NormNum/Ordinal.lean b/Mathlib/Tactic/NormNum/Ordinal.lean index 5f6186be9354d2..8fe0b6c395f7ca 100644 --- a/Mathlib/Tactic/NormNum/Ordinal.lean +++ b/Mathlib/Tactic/NormNum/Ordinal.lean @@ -85,10 +85,10 @@ def evalOrdinalLE : NormNumExt where let ⟨an, pa⟩ ← deriveNat a i let ⟨bn, pb⟩ ← deriveNat b i if an.natLit! ≤ bn.natLit! then - have this : decide ($an ≤ $bn) =Q true := ⟨⟩ + have : decide ($an ≤ $bn) =Q true := ⟨⟩ pure (.isTrue q(isNat_ordinalLE_true $pa $pb $this)) else - have this : decide ($an ≤ $bn) =Q false := ⟨⟩ + have : decide ($an ≤ $bn) =Q false := ⟨⟩ pure (.isFalse q(isNat_ordinalLE_false $pa $pb $this)) | _, _ => throwError "not inequality on ordinals" @@ -103,10 +103,10 @@ def evalOrdinalLT : NormNumExt where let ⟨an, pa⟩ ← deriveNat a i let ⟨bn, pb⟩ ← deriveNat b i if an.natLit! < bn.natLit! then - have this : decide ($an < $bn) =Q true := ⟨⟩ + have : decide ($an < $bn) =Q true := ⟨⟩ pure (.isTrue q(isNat_ordinalLT_true $pa $pb $this)) else - have this : decide ($an < $bn) =Q false := ⟨⟩ + have : decide ($an < $bn) =Q false := ⟨⟩ pure (.isFalse q(isNat_ordinalLT_false $pa $pb $this)) | _, _ => throwError "not strict inequality on ordinals" diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Module.lean b/Mathlib/Topology/Algebra/InfiniteSum/Module.lean index a7e054ae230e34..fd734dde59a7fc 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Module.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Module.lean @@ -92,7 +92,7 @@ variable {f : ι → R} {g : κ → M} {s : R} {t u : M} theorem HasSum.smul_eq (hf : HasSum f s) (hg : HasSum g t) (hfg : HasSum (fun x : ι × κ ↦ f x.1 • g x.2) u) : s • t = u := have key₁ : HasSum (fun i ↦ f i • t) (s • t) := hf.smul_const t - have this : ∀ i : ι, HasSum (fun c : κ ↦ f i • g c) (f i • t) := fun i ↦ hg.const_smul (f i) + have : ∀ i : ι, HasSum (fun c : κ ↦ f i • g c) (f i • t) := fun i ↦ hg.const_smul (f i) have key₂ : HasSum (fun i ↦ f i • t) u := HasSum.prod_fiberwise hfg this key₁.unique key₂ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean b/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean index e925b80f9c5ff0..e35bbff9e5feaa 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Ring.lean @@ -171,7 +171,7 @@ variable [TopologicalSpace α] [T3Space α] [NonUnitalNonAssocSemiring α] [IsTo theorem HasSum.mul_eq (hf : HasSum f s) (hg : HasSum g t) (hfg : HasSum (fun x : ι × κ ↦ f x.1 * g x.2) u) : s * t = u := have key₁ : HasSum (fun i ↦ f i * t) (s * t) := hf.mul_right t - have this : ∀ i : ι, HasSum (fun c : κ ↦ f i * g c) (f i * t) := fun i ↦ hg.mul_left (f i) + have : ∀ i : ι, HasSum (fun c : κ ↦ f i * g c) (f i * t) := fun i ↦ hg.mul_left (f i) have key₂ : HasSum (fun i ↦ f i * t) u := HasSum.prod_fiberwise hfg this key₁.unique key₂ diff --git a/Mathlib/Topology/Algebra/Module/ModuleTopology.lean b/Mathlib/Topology/Algebra/Module/ModuleTopology.lean index a38676b41761ee..f67007d2e83bc8 100644 --- a/Mathlib/Topology/Algebra/Module/ModuleTopology.lean +++ b/Mathlib/Topology/Algebra/Module/ModuleTopology.lean @@ -390,7 +390,7 @@ theorem isQuotientMap_of_surjectiveₛₗ [τB : TopologicalSpace B'] [IsModuleT haveI := IsModuleTopology.toContinuousAdd R A haveI := IsModuleTopology.toContinuousAdd S B' -- Because φ is linear, it's continuous for the module topologies (by a previous result). - have this : Continuous φ := continuous_of_linearMapₛₗ hσ.continuous φ + have : Continuous φ := continuous_of_linearMapₛₗ hσ.continuous φ -- So the coinduced topology is finer than the module topology on B. rw [continuous_iff_coinduced_le] at this -- So STP the module topology on B is ≤ the topology coinduced from A diff --git a/Mathlib/Topology/Connected/TotallyDisconnected.lean b/Mathlib/Topology/Connected/TotallyDisconnected.lean index 93ba84db981906..8fa3ab59abb2ee 100644 --- a/Mathlib/Topology/Connected/TotallyDisconnected.lean +++ b/Mathlib/Topology/Connected/TotallyDisconnected.lean @@ -61,7 +61,7 @@ instance Pi.totallyDisconnectedSpace {α : Type*} {β : α → Type*} [∀ a, TopologicalSpace (β a)] [∀ a, TotallyDisconnectedSpace (β a)] : TotallyDisconnectedSpace (∀ a : α, β a) := ⟨fun t _ h2 => - have this : ∀ a, IsPreconnected ((fun x : ∀ a, β a => x a) '' t) := fun a => + have : ∀ a, IsPreconnected ((fun x : ∀ a, β a => x a) '' t) := fun a => h2.image (fun x => x a) (continuous_apply a).continuousOn fun x x_in y y_in => funext fun a => (this a).subsingleton ⟨x, x_in, rfl⟩ ⟨y, y_in, rfl⟩⟩ diff --git a/Mathlib/Topology/Order/OrderClosed.lean b/Mathlib/Topology/Order/OrderClosed.lean index be6dcbf83ed2f9..55e9bcb6d130e9 100644 --- a/Mathlib/Topology/Order/OrderClosed.lean +++ b/Mathlib/Topology/Order/OrderClosed.lean @@ -427,7 +427,7 @@ namespace Subtype -- todo: add `OrderEmbedding.orderClosedTopology` instance {p : α → Prop} : OrderClosedTopology (Subtype p) := - have this : Continuous fun p : Subtype p × Subtype p => ((p.fst : α), (p.snd : α)) := + have : Continuous fun p : Subtype p × Subtype p => ((p.fst : α), (p.snd : α)) := continuous_subtype_val.prodMap continuous_subtype_val OrderClosedTopology.mk (t.isClosed_le'.preimage this) diff --git a/Mathlib/Topology/Sion.lean b/Mathlib/Topology/Sion.lean index 4b16ccbc13a746..91e3dceffe7134 100644 --- a/Mathlib/Topology/Sion.lean +++ b/Mathlib/Topology/Sion.lean @@ -265,7 +265,7 @@ public theorem exists_lt_iInf_of_lt_iInf_of_sup (fun h1 ↦ ?_) (fun h2 ↦ ?_) · grw [mem_J1_iff, (monotone_sublevelLeft ⟨(z : F), h_mem_Y z⟩ htt'.le), h1] · grw [mem_J2_iff, (monotone_sublevelLeft ⟨(z : F), h_mem_Y z⟩ htt'.le), h2] - have this : IsPreconnected (Set.univ : Set (segment ℝ (y1 : F) y2)) := by + have : IsPreconnected (Set.univ : Set (segment ℝ (y1 : F) y2)) := by simpa [← Topology.IsInducing.subtypeVal.isPreconnected_image] using (convex_segment (y1 : F) y2).isPreconnected have hJ1 : IsClosed J1 := isClosed_setOf_sublevelLeft_subset ne_X kX hfy hfy' diff --git a/MathlibTest/Clean.lean b/MathlibTest/Clean.lean index 1f2b6f1a0ec244..23feae3602f036 100644 --- a/MathlibTest/Clean.lean +++ b/MathlibTest/Clean.lean @@ -42,7 +42,7 @@ example : True := by guard_hyp x' :ₛ id Nat := (1 : Nat) let y := show Nat from 1 - guard_hyp y :ₛ Nat := have this := 1; this + guard_hyp y :ₛ Nat := have := 1; this let y' := clean% show Nat from 1 guard_hyp y' :ₛ Nat := 1 From a05a5203b5f61372fbffbc36f7eabdcf2acb34c5 Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Tue, 14 Jul 2026 09:39:07 +0000 Subject: [PATCH 0772/1300] refactor(LinearAlgebra.Matrix.Determinant.Bird): move Bird determinant definitions into a submodule (#41673) Move the Bird algorithm definitions into Bird/Defs.lean in preparation for a subsequent PR (https://github.com/leanprover-community/mathlib4/pull/41160) that adds `LinearAlgebra/Matrix/Determinant/Bird/Correctness.lean` as a sibling. --- Mathlib.lean | 2 +- .../Matrix/Determinant/{Bird.lean => Bird/Defs.lean} | 0 Mathlib/Tactic/Determinant/Bird/Cert.lean | 2 +- Mathlib/Tactic/Determinant/Bird/Meta.lean | 2 +- MathlibTest/matrix.lean | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename Mathlib/LinearAlgebra/Matrix/Determinant/{Bird.lean => Bird/Defs.lean} (100%) diff --git a/Mathlib.lean b/Mathlib.lean index 6b50cfeeca50fe..f152a16c49fc9c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5107,7 +5107,7 @@ public import Mathlib.LinearAlgebra.Matrix.Circulant public import Mathlib.LinearAlgebra.Matrix.ConjTranspose public import Mathlib.LinearAlgebra.Matrix.Defs public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic -public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs public import Mathlib.LinearAlgebra.Matrix.Determinant.Misc public import Mathlib.LinearAlgebra.Matrix.Determinant.TotallyUnimodular public import Mathlib.LinearAlgebra.Matrix.Diagonal diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Bird.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Defs.lean similarity index 100% rename from Mathlib/LinearAlgebra/Matrix/Determinant/Bird.lean rename to Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Defs.lean diff --git a/Mathlib/Tactic/Determinant/Bird/Cert.lean b/Mathlib/Tactic/Determinant/Bird/Cert.lean index e92e0829b6d1ad..8d3e14344d2e52 100644 --- a/Mathlib/Tactic/Determinant/Bird/Cert.lean +++ b/Mathlib/Tactic/Determinant/Bird/Cert.lean @@ -13,7 +13,7 @@ public meta import Mathlib.Tactic.Ring # Certificate-chain evaluator for `BirdDet.birdDet` This file contains an evaulator that computes the ring tactic normal form of -`Mathlib.LinearAlgebra.Matrix.Determinant.Bird.birdDet` via iteratively +`Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs.birdDet` via iteratively unfolding its definition, using the ring tactic for ring operations, and caching intermediate certificates. diff --git a/Mathlib/Tactic/Determinant/Bird/Meta.lean b/Mathlib/Tactic/Determinant/Bird/Meta.lean index 2b16374f8da6c0..f2cb99e80a70e5 100644 --- a/Mathlib/Tactic/Determinant/Bird/Meta.lean +++ b/Mathlib/Tactic/Determinant/Bird/Meta.lean @@ -5,7 +5,7 @@ Authors: Paul Cadman -/ module -public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs public meta import Mathlib.Tactic.Ring public meta import Mathlib.Util.Qq diff --git a/MathlibTest/matrix.lean b/MathlibTest/matrix.lean index d97533ec18b060..536de7198fde2c 100644 --- a/MathlibTest/matrix.lean +++ b/MathlibTest/matrix.lean @@ -4,7 +4,7 @@ https://github.com/leanprover-community/mathlib/blob/4f4a1c875d0baa92ab5d92f3fb1 -/ import Mathlib.GroupTheory.Perm.Fin import Mathlib.LinearAlgebra.Matrix.Determinant.Basic -import Mathlib.LinearAlgebra.Matrix.Determinant.Bird +import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs import Mathlib.LinearAlgebra.Matrix.Notation import Mathlib.RingTheory.Polynomial.Basic import Mathlib.Tactic.Determinant.Bird From 67158084fed415ed1f6dfa9b6929c19c83297807 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 14 Jul 2026 09:39:09 +0000 Subject: [PATCH 0773/1300] chore: remove all unused `let` (#41716) This PR removes all unused/redundant `let`. Co-authored-by: Batixx --- Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean | 2 -- Mathlib/CategoryTheory/Sites/Coherent/LocallySurjective.lean | 2 -- Mathlib/Data/Fin/VecNotation.lean | 1 - Mathlib/FieldTheory/CardinalEmb.lean | 1 - Mathlib/FieldTheory/PurelyInseparable/Basic.lean | 1 - Mathlib/FieldTheory/Relrank.lean | 1 - Mathlib/LinearAlgebra/RootSystem/BaseExists.lean | 1 - Mathlib/MeasureTheory/Group/FundamentalDomain.lean | 1 - Mathlib/NumberTheory/RamificationInertia/Inertia.lean | 1 - Mathlib/RingTheory/Ideal/GoingUp.lean | 1 - Mathlib/RingTheory/LittleWedderburn.lean | 1 - Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean | 1 - Mathlib/Topology/Category/Profinite/Extend.lean | 1 - Mathlib/Topology/Sheaves/Alexandrov.lean | 1 - Mathlib/Topology/UniformSpace/AbstractCompletion.lean | 2 -- Mathlib/Topology/UniformSpace/Basic.lean | 1 - 16 files changed, 19 deletions(-) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean index f6490c818ee8c8..7c50f225daf795 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean @@ -464,8 +464,6 @@ theorem second_derivative_symmetric_of_eventually [IsRCLikeNormedField 𝕜] let _ := IsRCLikeNormedField.rclike 𝕜 let _ : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 E let _ : NormedSpace ℝ F := NormedSpace.restrictScalars ℝ 𝕜 F - let _ : LinearMap.CompatibleSMul E F ℝ 𝕜 := LinearMap.IsScalarTower.compatibleSMul - let _ : LinearMap.CompatibleSMul E (E →L[𝕜] F) ℝ 𝕜 := LinearMap.IsScalarTower.compatibleSMul let f'R : E → E →L[ℝ] F := fun x ↦ (f' x).restrictScalars ℝ let f''R : E →L[ℝ] E →L[ℝ] F := f''.bilinearRestrictScalars ℝ have hfR : ∀ᶠ y in 𝓝 x, HasFDerivAt f (f'R y) y := by diff --git a/Mathlib/CategoryTheory/Sites/Coherent/LocallySurjective.lean b/Mathlib/CategoryTheory/Sites/Coherent/LocallySurjective.lean index 146e646f8df096..ee936188375697 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/LocallySurjective.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/LocallySurjective.lean @@ -68,7 +68,6 @@ lemma extensiveTopology.surjective_of_isLocallySurjective_sheaf_of_types [Finita rw [mem_sieves_iff_contains_colimit_cofan] at h obtain ⟨α, _, Y, π, h, h'⟩ := h let y : (a : α) → (F.obj ⟨Y a⟩) := fun a ↦ (h' a).choose - let _ : Fintype α := Fintype.ofFinite _ let ht := (Types.productLimitCone (fun a ↦ F.obj ⟨Y a⟩)).isLimit let ht' := (Functor.Initial.isLimitWhiskerEquiv (Discrete.opposite α).inverse (Cocone.op (Cofan.mk X π))).symm h.some.op @@ -116,7 +115,6 @@ lemma regularTopology.isLocallySurjective_sheaf_of_types [Preregular C] [Finitar obtain ⟨α, _, Z, π, h, h'⟩ := h rw [mem_sieves_iff_hasEffectiveEpi] let x : (a : α) → (F.obj ⟨Z a⟩) := fun a ↦ (h' a).choose - let _ : Fintype α := Fintype.ofFinite _ let i' : ((a : α) → (F.obj ⟨Z a⟩)) ≅ (F.obj ⟨∐ Z⟩) := (Types.productIso _).symm ≪≫ (PreservesProduct.iso F _).symm ≪≫ F.mapIso (opCoproductIsoProduct _).symm refine ⟨∐ Z, Sigma.desc π, inferInstance, i'.hom x, ?_⟩ diff --git a/Mathlib/Data/Fin/VecNotation.lean b/Mathlib/Data/Fin/VecNotation.lean index 11479cbb45ed13..eb4325f5b30e99 100644 --- a/Mathlib/Data/Fin/VecNotation.lean +++ b/Mathlib/Data/Fin/VecNotation.lean @@ -259,7 +259,6 @@ theorem vecCons_const (a : α) : (vecCons a fun _ : Fin n => a) = fun _ => a := funext <| Fin.forall_iff_succ.2 ⟨rfl, cons_val_succ _ _⟩ theorem vec_single_eq_const (a : α) : ![a] = fun _ => a := - let _ : Unique (Fin 1) := inferInstance funext <| Unique.forall_iff.2 rfl /-- `![a, b, ...] 1` is equal to `b`. diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index 7530ef2bb6bb7d..51a8083ba22a60 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -128,7 +128,6 @@ def leastExt : ι → ι := rw [adjoin_basis_eq_top, ← eq_top_iff] at this apply_fun Module.rank F at this refine ne_of_lt ?_ this - let _ : AddCommMonoid (⊤ : IntermediateField F E) := inferInstance conv_rhs => rw [topEquiv.toLinearEquiv.rank_eq] have := mk_Iio_lt i (by simp) rw [mk_toType, card_ord] at this diff --git a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean index e737a97e815e7d..71681f5634f0ed 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean @@ -612,7 +612,6 @@ lemma adjoin_eq_of_isAlgebraic_of_isSeparable [Algebra.IsAlgebraic F E] have := Algebra.isSeparable_tower_top_of_isSeparable E L K let i : S →+* L := Subsemiring.inclusion fun x hx ↦ subset_adjoin E (S : Set K) hx let _ : Algebra S L := i.toAlgebra - let _ : SMul S L := Algebra.toSMul have : IsScalarTower S L K := IsScalarTower.of_algebraMap_eq (congrFun rfl) have := Algebra.IsAlgebraic.trans F E K have : IsPurelyInseparable S K := separableClosure.isPurelyInseparable F K diff --git a/Mathlib/FieldTheory/Relrank.lean b/Mathlib/FieldTheory/Relrank.lean index 0c5de1459a4ff3..28f775aedb62d4 100644 --- a/Mathlib/FieldTheory/Relrank.lean +++ b/Mathlib/FieldTheory/Relrank.lean @@ -124,7 +124,6 @@ theorem relfinrank_top_left : relfinrank ⊤ A = 1 := relfinrank_eq_one_of_le le @[simp] theorem relrank_top_right : relrank A ⊤ = Module.rank A E := by - let _ : AddCommMonoid (⊤ : IntermediateField A E) := inferInstance rw [relrank_eq_rank_of_le (show A ≤ ⊤ from le_top), extendScalars_top, IntermediateField.topEquiv.toLinearEquiv.rank_eq] diff --git a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean index 45bc346053560a..527c373656cc7b 100644 --- a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean +++ b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean @@ -320,7 +320,6 @@ noncomputable def Base.mk' (s : Set ι) lemma nonempty_base : Nonempty P.Base := by let _i : Module ℚ M := Module.compHom M (algebraMap ℚ R) - let _i : Module ℚ N := Module.compHom N (algebraMap ℚ R) obtain ⟨f, hf⟩ : ∃ f : Dual ℚ M, ∀ i, f (P.root i) ≠ 0 := exists_dual_forall_apply_ne_zero P.root <| by simp [P.ne_zero] letI := P.indexNeg diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index 02badc202cc9f3..2b2f9959e7d482 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -832,7 +832,6 @@ lemma QuotientMeasureEqMeasurePreimage.sigmaFiniteQuotient · obtain ⟨s, fund_dom_s⟩ := i' have : π ⁻¹' π '' (A n) = _ := MulAction.quotient_preimage_image_eq_union_mul (A n) (G := G) have measπAn : MeasurableSet (π '' A n) := by - let _ : Setoid α := α_mod_G rw [measurableSet_quotient, Quotient.mk''_eq_mk, this] apply MeasurableSet.iUnion exact fun g ↦ MeasurableSet.const_smul (hA_meas n) g diff --git a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean index bb1e0e04d4fba0..e5931a31ab8a51 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean @@ -159,7 +159,6 @@ lemma absNorm_eq_pow_inertiaDeg'_of_liesOver {S : Type*} [CommRing S] [IsDedekin (P : Ideal R) (p : Ideal S) [P.LiesOver p] (hp : p.IsPrime) (hp_ne_bot : p ≠ ⊥) : absNorm P = absNorm p ^ (p.inertiaDeg' P) := by have : p.IsMaximal := hp.isMaximal hp_ne_bot - let _ : Field (S ⧸ p) := Quotient.field p simpa [absNorm_apply, Submodule.cardQuot_apply] using Module.natCard_eq_pow_finrank (K := S ⧸ p) @[deprecated (since := "2026-07-03")] alias absNorm_eq_pow_inertiaDeg_of_liesOver := diff --git a/Mathlib/RingTheory/Ideal/GoingUp.lean b/Mathlib/RingTheory/Ideal/GoingUp.lean index 3c9b3441e4d7fe..43581c4e048d63 100644 --- a/Mathlib/RingTheory/Ideal/GoingUp.lean +++ b/Mathlib/RingTheory/Ideal/GoingUp.lean @@ -289,7 +289,6 @@ theorem exists_ideal_over_prime_of_isIntegral_of_isDomain [Algebra.IsIntegral R letI : IsDomain (Localization (Algebra.algebraMapSubmonoid S P.primeCompl)) := IsLocalization.isDomain_localization (le_nonZeroDivisors_of_noZeroDivisors hP0) obtain ⟨Qₚ : Ideal Sₚ, Qₚ_maximal⟩ := exists_maximal Sₚ - let _ : Algebra Rₚ Sₚ := localizationAlgebra P.primeCompl S have : Algebra.IsIntegral Rₚ Sₚ := ⟨isIntegral_localization⟩ have Qₚ_max : IsMaximal (comap _ Qₚ) := isMaximal_comap_of_isIntegral_of_isMaximal (R := Rₚ) (S := Sₚ) Qₚ diff --git a/Mathlib/RingTheory/LittleWedderburn.lean b/Mathlib/RingTheory/LittleWedderburn.lean index 20425e0914f877..d45ab2d60d826a 100644 --- a/Mathlib/RingTheory/LittleWedderburn.lean +++ b/Mathlib/RingTheory/LittleWedderburn.lean @@ -173,5 +173,4 @@ theorem Finite.isDomain_to_isField (D : Type*) [Finite D] [Ring D] [IsDomain D] classical cases nonempty_fintype D let _ := Fintype.divisionRingOfIsDomain D - let _ := littleWedderburn D exact Field.toIsField D diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean index c8a0f9e6b53d1f..f6c30922e9e39f 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean @@ -236,7 +236,6 @@ theorem mem_adjoin_of_smul_prime_smul_of_minpoly_isEisensteinAt {B : PowerBasis set P := minpoly R B.gen with hP obtain ⟨n, hn⟩ := Nat.exists_eq_succ_of_ne_zero B.dim_pos.ne' have : Module.IsTorsionFree R L := .trans_faithfulSMul R K L - let _ := P.map (algebraMap R L) -- There is a polynomial `Q` such that `p • z = aeval B.gen Q`. We can assume that -- `Q.degree < P.degree` and `Q ≠ 0`. rw [adjoin_singleton_eq_range_aeval] at hz diff --git a/Mathlib/Topology/Category/Profinite/Extend.lean b/Mathlib/Topology/Category/Profinite/Extend.lean index 335172a81fb214..0e4c53af2d91cb 100644 --- a/Mathlib/Topology/Category/Profinite/Extend.lean +++ b/Mathlib/Topology/Category/Profinite/Extend.lean @@ -42,7 +42,6 @@ the profinite set when written as a cofiltered limit of finite sets. -/ lemma exists_hom (hc : IsLimit c) {X : FintypeCat} (f : c.pt ⟶ toProfinite.obj X) : ∃ (i : I) (g : F.obj i ⟶ X), f = c.π.app i ≫ toProfinite.map g := by - let _ : TopologicalSpace X := ⊥ have : DiscreteTopology (toProfinite.obj X) := ⟨rfl⟩ let f' : LocallyConstant c.pt (toProfinite.obj X) := ⟨f, (IsLocallyConstant.iff_continuous _).mpr f.hom.hom.continuous⟩ diff --git a/Mathlib/Topology/Sheaves/Alexandrov.lean b/Mathlib/Topology/Sheaves/Alexandrov.lean index 128a90ea4a520a..058bebb985779a 100644 --- a/Mathlib/Topology/Sheaves/Alexandrov.lean +++ b/Mathlib/Topology/Sheaves/Alexandrov.lean @@ -198,6 +198,5 @@ theorem Topology.IsUpperSet.isSheaf_of_isRightKanExtension @rightKanExtensionUnique _ _ _ _ _ _ _ _ _ _ (by assumption) _ _ (by assumption) change TopCat.Presheaf.IsSheaf (X := TopCat.of X) P rw [isSheaf_iso_iff this] - let _ : Preorder (TopCat.of X) := inferInstanceAs <| Preorder X have _ : Topology.IsUpperSet (TopCat.of X) := inferInstanceAs <| Topology.IsUpperSet X exact isSheaf_principalsKanExtension (X := TopCat.of X) F diff --git a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean index 53ef3368713f79..7b95754309a634 100644 --- a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean +++ b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean @@ -318,8 +318,6 @@ theorem compare_comp_eq_compare (γ : Type uγ) [TopologicalSpace γ] (∀ a : pkg.space, Filter.Tendsto f (Filter.comap pkg.coe (𝓝 a)) (𝓝 ((pkg.isDenseInducing.extend f) a))) → pkg.isDenseInducing.extend f ∘ pkg'.compare pkg = pkg'.isDenseInducing.extend f := by - let _ := pkg'.uniformStruct - let _ := pkg.uniformStruct intro h have (x : α) : (pkg.isDenseInducing.extend f ∘ pkg'.compare pkg) (pkg'.coe x) = f x := by simp only [Function.comp_apply, compare_coe, IsDenseInducing.extend_eq _ cont_f] diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 17bb184e5be4b0..45ae3163670cf2 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -903,7 +903,6 @@ theorem uniformContinuous_sInf_dom₂ {α β γ} {f : α → β → γ} {uas : S haveI := sInf uas; haveI := sInf ubs exact @UniformContinuous _ _ _ uc fun p : α × β => f p.1 p.2 := by -- proof essentially copied from `continuous_sInf_dom` - let _ : UniformSpace (α × β) := instUniformSpaceProd have ha := uniformContinuous_sInf_dom ha uniformContinuous_id have hb := uniformContinuous_sInf_dom hb uniformContinuous_id have h_unif_cont_id := @UniformContinuous.prodMap _ _ _ _ (sInf uas) (sInf ubs) ua ub _ _ ha hb From 58283e06495f009f96f53df0e0ed73d7add4c649 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 14 Jul 2026 11:01:34 +0000 Subject: [PATCH 0774/1300] chore(SimpleGraph/Acyclic): clean up "acyclic iff at most one path" API (#41219) Followup to [this comment](https://github.com/leanprover-community/mathlib4/pull/40818#issuecomment-4845714600) on #40818 --- .../Combinatorics/SimpleGraph/Acyclic.lean | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index 297353a932b46e..c89e7cc9a208a4 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -185,32 +185,32 @@ lemma isAcyclic_iff_forall_adj_isBridge : @[deprecated (since := "2026-06-04")] alias isAcyclic_iff_forall_edge_isBridge := isAcyclic_iff_forall_isBridge +theorem isAcyclic_iff_subsingleton_path : G.IsAcyclic ↔ ∀ u v, Subsingleton (G.Path u v) := by + refine ⟨fun h u v ↦ ⟨fun p q ↦ ?_⟩, fun h v c hc ↦ ?_⟩ + · have := p.isPath.exists_isCycle_of_ne q.isPath + grind [IsAcyclic, Subtype.coe_inj] + · have := h _ v |>.elim ⟨_, hc.isPath_tail⟩ ⟨_, .of_adj <| c.adj_snd hc.not_nil |>.symm⟩ + grind [length_cons, length_nil, hc.three_le_length, c.length_tail_add_one hc.not_nil] + +alias ⟨IsAcyclic.subsingleton_path, _⟩ := isAcyclic_iff_subsingleton_path + +@[deprecated IsAcyclic.subsingleton_path (since := "2026-06-30")] theorem IsAcyclic.path_unique {G : SimpleGraph V} (h : G.IsAcyclic) {v w : V} (p q : G.Path v w) : - p = q := by - have := p.isPath.exists_isCycle_of_ne q.isPath - grind [IsAcyclic, Subtype.coe_inj] - -theorem isAcyclic_of_path_unique (h : ∀ (v w : V) (p q : G.Path v w), p = q) : G.IsAcyclic := by - intro v c hc - simp only [Walk.isCycle_def, Ne] at hc - cases c with - | nil => cases hc.2.1 rfl - | cons ha c' => - simp only [Walk.isTrail_cons, Walk.support_cons, List.tail_cons] at hc - specialize h _ _ ⟨c', by simp only [Walk.isPath_def, hc.2]⟩ (Path.singleton ha.symm) - rw [Path.singleton, Subtype.mk.injEq] at h - simp [h] at hc + p = q := + h.subsingleton_path v w |>.elim p q -theorem isAcyclic_iff_path_unique : G.IsAcyclic ↔ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q := - ⟨IsAcyclic.path_unique, isAcyclic_of_path_unique⟩ +@[deprecated isAcyclic_iff_subsingleton_path (since := "2026-06-30")] +theorem isAcyclic_of_path_unique (h : ∀ (v w : V) (p q : G.Path v w), p = q) : G.IsAcyclic := + isAcyclic_iff_subsingleton_path.mpr (⟨h · ·⟩) -theorem isAcyclic_iff_subsingleton_path : G.IsAcyclic ↔ ∀ ⦃u v⦄, Subsingleton (G.Path u v) := by - simp [isAcyclic_iff_path_unique, subsingleton_iff] +@[deprecated isAcyclic_iff_subsingleton_path (since := "2026-06-30")] +theorem isAcyclic_iff_path_unique : G.IsAcyclic ↔ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q := + isAcyclic_iff_subsingleton_path.trans <| forall₂_congr fun _ _ ↦ subsingleton_iff theorem IsAcyclic.eq_snd_of_adj_start (h : G.IsAcyclic) {u v w : V} {p : G.Walk u v} (hp : p.IsPath) (hadj : G.Adj u w) (hsupp : w ∈ p.support) : w = p.snd := by classical - have := isAcyclic_iff_path_unique.mp h ⟨_, hp.takeUntil hsupp⟩ <| .singleton hadj + have := h.subsingleton_path u w |>.elim ⟨_, hp.takeUntil hsupp⟩ <| .singleton hadj grind [p.getVert_length_takeUntil hsupp, Path.singleton_coe, length] theorem IsAcyclic.eq_penultimate_of_adj_end (h : G.IsAcyclic) {u v w : V} {p : G.Walk u v} @@ -222,14 +222,14 @@ theorem IsAcyclic.eq_penultimate_of_adj_end (h : G.IsAcyclic) {u v w : V} {p : G lemma IsAcyclic.mem_support_of_ne_mem_support_of_adj_of_isPath (hG : G.IsAcyclic) {u v w : V} {p : G.Walk u v} {q : G.Walk u w} (hp : p.IsPath) (hq : q.IsPath) (hadj : G.Adj v w) (hv : v ∉ q.support) : w ∈ p.support := by - rw [Subtype.mk.inj <| isAcyclic_iff_path_unique.mp hG ⟨p, hp⟩ ⟨_, hq.concat hv hadj.symm⟩] + rw [Subtype.mk.inj <| hG.subsingleton_path u v |>.elim ⟨p, hp⟩ ⟨_, hq.concat hv hadj.symm⟩] exact q.support_subset_support_concat _ q.end_mem_support lemma IsAcyclic.ne_mem_support_of_support_of_adj_of_isPath (hG : G.IsAcyclic) {u v w : V} {p : G.Walk u v} {q : G.Walk u w} (hp : p.IsPath) (hq : q.IsPath) (hadj : G.Adj v w) (hw : w ∈ p.support) : v ∉ q.support := by obtain ⟨p₀, p₁, hp₀, hp₁, happend⟩ := hp.mem_support_iff_exists_append.mp hw - rw [← Subtype.mk.inj <| hG.path_unique ⟨p₀, hp₀⟩ ⟨q, hq⟩] + rw [← Subtype.mk.inj <| hG.subsingleton_path u w |>.elim ⟨p₀, hp₀⟩ ⟨q, hq⟩] exact fun hxp => (happend ▸ hp).ne_of_mem_support_of_append hadj.symm.ne' hxp (p₁.end_mem_support) rfl @@ -237,12 +237,12 @@ lemma IsAcyclic.path_concat (hG : G.IsAcyclic) {u v w : V} {p : G.Walk u v} {q : (hp : p.IsPath) (hq : q.IsPath) (hadj : G.Adj v w) (hv : v ∈ q.support) : q = p.concat hadj := by have hw : w ∉ p.support := hG.ne_mem_support_of_support_of_adj_of_isPath hq hp hadj.symm hv - exact Subtype.mk.inj <| isAcyclic_iff_path_unique.mp hG ⟨q, hq⟩ ⟨_, hp.concat hw hadj⟩ + exact Subtype.mk.inj <| hG.subsingleton_path u w |>.elim ⟨q, hq⟩ ⟨_, hp.concat hw hadj⟩ theorem isTree_iff_existsUnique_path : G.IsTree ↔ Nonempty V ∧ ∀ v w : V, ∃! p : G.Walk v w, p.IsPath := by classical - rw [isTree_iff, isAcyclic_iff_path_unique] + simp_rw [isTree_iff, isAcyclic_iff_subsingleton_path, subsingleton_iff] constructor · rintro ⟨hc, hu⟩ refine ⟨hc.nonempty, ?_⟩ @@ -251,7 +251,7 @@ theorem isTree_iff_existsUnique_path : use q simp only [true_and, Path.isPath] intro p hp - specialize hu ⟨p, hp⟩ q + specialize hu v w ⟨p, hp⟩ q exact Subtype.ext_iff.mp hu · rintro ⟨hV, h⟩ refine ⟨Connected.mk ?_, ?_⟩ @@ -355,7 +355,7 @@ lemma isTree_iff_minimal_connected : IsTree G ↔ Minimal Connected G := by refine ⟨fun htree ↦ ⟨htree.connected, fun G' h' hle u v hadj ↦ ?_⟩, isTree_of_minimal_connected⟩ have ⟨p, hp⟩ := h'.exists_isPath u v have := congrArg Walk.edges <| congrArg Subtype.val <| - htree.isAcyclic.path_unique ⟨p.mapLe hle, hp.mapLe hle⟩ <| Path.singleton hadj + htree.isAcyclic.subsingleton_path u v |>.elim ⟨p.mapLe hle, hp.mapLe hle⟩ <| Path.singleton hadj simp only [edges_map, Hom.coe_ofLE, Sym2.map_id, List.map_id_fun, id_eq] at this simp [this, p.adj_of_mem_edges] From 7fff4171d6fb4b9eba9808b254f73c29b1f76d03 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 14 Jul 2026 11:01:36 +0000 Subject: [PATCH 0775/1300] feat(Topology/Algebra/Group/Basic,Algebra/Group/Pointwise/Set/Basic): add Filter.map_{sub,div}{Left,Right}_nhds{,LT,GT,NE} (#41376) The file `Topology/Algebra/Group/Basic` contains various variants of `Filter.map_mulLeft_nhds` and `Filter.map_mulRight_nhds`. The PR adds the analogous lemmas for division, with very similar proofs (which requires adding some helper lemmas to `Algebra/Group/Pointwise/Set/Basic`). Using `to_additive', one also obtains lemmas for subtraction for free, Co-authored-by: Terence Tao Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- .../Algebra/Group/Pointwise/Set/Basic.lean | 12 ++++ Mathlib/Topology/Algebra/Group/Basic.lean | 67 +++++++++++++++++-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean index 28e4c96416321f..1b733efbea028f 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean @@ -915,6 +915,14 @@ theorem image_mul_left' : (a⁻¹ * ·) '' t = (a * ·) ⁻¹' t := by simp @[to_additive] theorem image_mul_right' : (· * b⁻¹) '' t = (· * b) ⁻¹' t := by simp +@[to_additive] +theorem image_div_left : (a / ·) '' t = (·⁻¹ * a) ⁻¹' t := by + rw [image_eq_preimage_of_inverse] <;> intro c <;> simp + +@[to_additive] +theorem image_div_right : (· / b) '' t = (· * b) ⁻¹' t := by + rw [image_eq_preimage_of_inverse] <;> intro c <;> simp + @[to_additive (attr := simp)] theorem preimage_mul_left_singleton : (a * ·) ⁻¹' {b} = {a⁻¹ * b} := by rw [← image_mul_left', image_singleton] @@ -923,6 +931,10 @@ theorem preimage_mul_left_singleton : (a * ·) ⁻¹' {b} = {a⁻¹ * b} := by theorem preimage_mul_right_singleton : (· * a) ⁻¹' {b} = {b * a⁻¹} := by rw [← image_mul_right', image_singleton] +@[to_additive (attr := simp)] +theorem preimage_inv_mul_right_singleton : (·⁻¹ * a) ⁻¹' {b} = {a / b} := by + rw [← image_div_left, image_singleton] + @[to_additive (attr := simp)] theorem preimage_mul_left_one : (a * ·) ⁻¹' 1 = {a⁻¹} := by rw [← image_mul_left', image_one, mul_one] diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 7d82c9db6f5b06..597a465ef34eb1 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -373,7 +373,7 @@ lemma continuousOn_inv_iff : ContinuousOn f⁻¹ s ↔ ContinuousOn f s := @[to_additive] alias ⟨ContinuousOn.of_inv, _⟩ := continuousOn_inv_iff @[to_additive (attr := simp)] -theorem Filter.inv_nhdsNE {a : G} : (𝓝[≠] a)⁻¹ = (𝓝[≠] (a⁻¹)) := by +theorem Filter.inv_nhdsNE {a : G} : (𝓝[≠] a)⁻¹ = 𝓝[≠] (a⁻¹) := by convert! (Homeomorph.inv G).isEmbedding.map_nhdsWithin_eq .. using 2 simp @@ -517,22 +517,22 @@ section mul variable [ContinuousMul H] @[to_additive (attr := simp)] -theorem Filter.map_mul_left_nhdsGT {c a : H} : map (c * ·) (𝓝[>] a) = (𝓝[>] (c * a)) := by +theorem Filter.map_mul_left_nhdsGT {c a : H} : map (c * ·) (𝓝[>] a) = 𝓝[>] (c * a) := by convert! (Homeomorph.mulLeft c).isEmbedding.map_nhdsWithin_eq .. using 2 simp [mul_comm] @[to_additive (attr := simp)] -theorem Filter.map_mul_left_nhdsLT {c a : H} : map (c * ·) (𝓝[<] a) = (𝓝[<] (c * a)) := by +theorem Filter.map_mul_left_nhdsLT {c a : H} : map (c * ·) (𝓝[<] a) = 𝓝[<] (c * a) := by convert! (Homeomorph.mulLeft c).isEmbedding.map_nhdsWithin_eq .. using 2 simp [mul_comm] @[to_additive (attr := simp)] -theorem Filter.map_mul_right_nhdsGT {c a : H} : map (· * c) (𝓝[>] a) = (𝓝[>] (a * c)) := by +theorem Filter.map_mul_right_nhdsGT {c a : H} : map (· * c) (𝓝[>] a) = 𝓝[>] (a * c) := by convert! (Homeomorph.mulRight c).isEmbedding.map_nhdsWithin_eq .. using 2 simp @[to_additive (attr := simp)] -theorem Filter.map_mul_right_nhdsLT {c a : H} : map (· * c) (𝓝[<] a) = (𝓝[<] (a * c)) := by +theorem Filter.map_mul_right_nhdsLT {c a : H} : map (· * c) (𝓝[<] a) = 𝓝[<] (a * c) := by convert! (Homeomorph.mulRight c).isEmbedding.map_nhdsWithin_eq .. using 2 simp @@ -543,12 +543,12 @@ section inv variable [ContinuousInv H] @[to_additive (attr := simp)] -theorem Filter.inv_nhdsGT {a : H} : (𝓝[>] a)⁻¹ = (𝓝[<] (a⁻¹)) := by +theorem Filter.inv_nhdsGT {a : H} : (𝓝[>] a)⁻¹ = 𝓝[<] (a⁻¹) := by convert! (Homeomorph.inv H).isEmbedding.map_nhdsWithin_eq .. using 2 simp @[to_additive (attr := simp)] -theorem Filter.inv_nhdsLT {a : H} : (𝓝[<] a)⁻¹ = (𝓝[>] (a⁻¹)) := by +theorem Filter.inv_nhdsLT {a : H} : (𝓝[<] a)⁻¹ = 𝓝[>] (a⁻¹) := by convert! (Homeomorph.inv H).isEmbedding.map_nhdsWithin_eq .. using 2 simp @@ -1064,6 +1064,10 @@ alias Filter.tendsto_const_div_iff := Filter.tendsto_const_div_iff' def Homeomorph.divLeft (x : G) : G ≃ₜ G := { Equiv.divLeft x with } +@[to_additive (attr := simp)] +theorem Homeomorph.coe_divLeft (a : G) : ⇑(Homeomorph.divLeft a) = (a / ·) := + rfl + @[to_additive] theorem isOpenMap_div_left (a : G) : IsOpenMap (a / ·) := (Homeomorph.divLeft _).isOpenMap @@ -1078,6 +1082,10 @@ theorem isClosedMap_div_left (a : G) : IsClosedMap (a / ·) := def Homeomorph.divRight (x : G) : G ≃ₜ G := { Equiv.divRight x with } +@[to_additive (attr := simp)] +theorem Homeomorph.coe_divRight (a : G) : ⇑(Homeomorph.divRight a) = (· / a) := + rfl + @[to_additive] lemma isOpenMap_div_right (a : G) : IsOpenMap (· / a) := (Homeomorph.divRight a).isOpenMap @@ -1094,6 +1102,51 @@ theorem tendsto_div_nhds_one_iff {α : Type*} {l : Filter α} {x : G} {u : α theorem nhds_translation_div (x : G) : comap (· / x) (𝓝 1) = 𝓝 x := by simpa only [div_eq_mul_inv] using nhds_translation_mul_inv x +variable [TopologicalSpace H] [CommGroup H] [IsTopologicalGroup H] + [PartialOrder H] [IsOrderedMonoid H] + +@[to_additive (attr := simp)] +theorem Filter.map_divRight_nhdsGT {c a : H} : map (· / c) (𝓝[>] a) = 𝓝[>] (a / c) := by + convert! (Homeomorph.divRight c).isEmbedding.map_nhdsWithin_eq .. using 2 + simp + +@[to_additive (attr := simp)] +theorem Filter.map_divRight_nhdsLT {c a : H} : map (· / c) (𝓝[<] a) = 𝓝[<] (a / c) := by + convert! (Homeomorph.divRight c).isEmbedding.map_nhdsWithin_eq .. using 2 + simp + +@[to_additive (attr := simp)] +theorem Filter.map_divRight_nhdsNE {c a : G} : + map (· / c) (𝓝[≠] a) = 𝓝[≠] (a / c) := by + convert! (Homeomorph.divRight c).isEmbedding.map_nhdsWithin_eq .. using 2 + simp [div_eq_mul_inv] + +@[to_additive (attr := simp)] +theorem Filter.map_divRight_nhds {c a : G} : + map (· / c) (𝓝 a) = 𝓝 (a / c) := by + convert! (Homeomorph.divRight c).map_nhds_eq .. using 2 + +@[to_additive (attr := simp)] +theorem Filter.map_divLeft_nhdsGT {c a : H} : map (c / ·) (𝓝[>] a) = 𝓝[<] (c / a) := by + convert! (Homeomorph.divLeft c).isEmbedding.map_nhdsWithin_eq .. using 2 + simp + +@[to_additive (attr := simp)] +theorem Filter.map_divLeft_nhdsLT {c a : H} : map (c / ·) (𝓝[<] a) = 𝓝[>] (c / a) := by + convert! (Homeomorph.divLeft c).isEmbedding.map_nhdsWithin_eq .. using 2 + simp + +@[to_additive (attr := simp)] +theorem Filter.map_divLeft_nhdsNE {c a : G} : + map (c / ·) (𝓝[≠] a) = 𝓝[≠] (c / a) := by + convert! (Homeomorph.divLeft c).isEmbedding.map_nhdsWithin_eq .. using 2 + simp [image_div_left] + +@[to_additive (attr := simp)] +theorem Filter.map_divLeft_nhds {c a : G} : + map (c / ·) (𝓝 a) = 𝓝 (c / a) := by + convert! (Homeomorph.divLeft c).map_nhds_eq .. using 2 + end DivInvTopologicalGroup section FilterMul From daa89cd356faf84149d57396da106505635af41a Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 14 Jul 2026 11:41:21 +0000 Subject: [PATCH 0776/1300] feat(LinearAlgebra): characterize triangularizable semisimple endomorphisms (#41590) --- Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean | 12 ++++++++++++ Mathlib/LinearAlgebra/Semisimple.lean | 5 ----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean b/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean index 64142e4c03f3db..7f0c89b928c95f 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean @@ -19,6 +19,8 @@ endomorphisms. * `Module.End.IsFinitelySemisimple.genEigenspace_eq_eigenspace`: for a semisimple endomorphism, a generalized eigenspace is an eigenspace. +* `Module.End.IsSemisimple.iSup_maxGenEigenspace_eq_top_iff`: a semisimple endomorphism is + triangularizable if and only if it is diagonalizable. * `Module.End.IsSemisimple.iSup_eigenspace_eq_top`: over an algebraically closed field, the eigenspaces of a semisimple endomorphism span the whole space. * `Module.End.IsSemisimple.eq_zero_iff_forall_eigenvalue`: a semisimple endomorphism over @@ -71,6 +73,16 @@ lemma IsFinitelySemisimple.maxGenEigenspace_eq_eigenspace f.maxGenEigenspace μ = f.eigenspace μ := hf.genEigenspace_eq_eigenspace μ ENat.top_pos +/-- A finitely-semisimple endomorphism is triangularizable if and only if it is diagonalizable. -/ +lemma IsFinitelySemisimple.iSup_maxGenEigenspace_eq_top_iff (hf : f.IsFinitelySemisimple) : + (⨆ μ : R, f.maxGenEigenspace μ) = ⊤ ↔ (⨆ μ : R, f.eigenspace μ) = ⊤ := by + simp [hf.maxGenEigenspace_eq_eigenspace] + +/-- A semisimple endomorphism is triangularizable if and only if it is diagonalizable. -/ +lemma IsSemisimple.iSup_maxGenEigenspace_eq_top_iff (hf : f.IsSemisimple) : + (⨆ μ : R, f.maxGenEigenspace μ) = ⊤ ↔ (⨆ μ : R, f.eigenspace μ) = ⊤ := + hf.isFinitelySemisimple.iSup_maxGenEigenspace_eq_top_iff + section AlgClosed variable {K V : Type*} [Field K] [IsAlgClosed K] [AddCommGroup V] [Module K V] diff --git a/Mathlib/LinearAlgebra/Semisimple.lean b/Mathlib/LinearAlgebra/Semisimple.lean index 120bc5cbeda127..099bf504ffefdf 100644 --- a/Mathlib/LinearAlgebra/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Semisimple.lean @@ -36,11 +36,6 @@ endomorphism. We provide basic definitions and results about such endomorphisms * `IsSemisimple.of_mem_adjoin_pair`: every endomorphism in the subalgebra generated by two commuting semisimple endomorphisms is semisimple, if the base field is perfect. -## TODO - -In finite dimensions over a field: -* Triangularizable iff diagonalisable for semisimple endomorphisms - -/ @[expose] public section From ee04c5cbaa01ea37630885a08e667025542957ce Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 11:41:24 +0000 Subject: [PATCH 0777/1300] chore(Algebra/Module/Submodule/EqLocus): automated extraction from #39100 (#41726) This PR was automatically created from PR #39100 by @ADedecker via a [review comment](https://github.com/leanprover-community/mathlib4/pull/39100#discussion_r3578217569) by @ocfnash. Co-authored-by: ADedecker <48656793+ADedecker@users.noreply.github.com> --- Mathlib/Algebra/Module/Submodule/EqLocus.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Algebra/Module/Submodule/EqLocus.lean b/Mathlib/Algebra/Module/Submodule/EqLocus.lean index 9a6626da9d7b56..0691c6e537e6bb 100644 --- a/Mathlib/Algebra/Module/Submodule/EqLocus.lean +++ b/Mathlib/Algebra/Module/Submodule/EqLocus.lean @@ -68,6 +68,10 @@ theorem le_eqLocus {f g : M →ₛₗ[τ₁₂] M₂} {S : Submodule R M} : S ≤ eqLocus f g ↔ Set.EqOn f g S := Iff.rfl +theorem eqOn_eqLocus {f g : M →ₛₗ[τ₁₂] M₂} : + Set.EqOn f g (eqLocus f g) := + fun _ h ↦ h + variable {F : Type*} [FunLike F M M₂] [SemilinearMapClass F τ₁₂ M M₂] include τ₁₂ in From 39568fbb654ee838444c610979c312acc1b40caf Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 14 Jul 2026 12:28:10 +0000 Subject: [PATCH 0778/1300] chore: replace (d)simp +instances with (d)simp whenever possible (#40650) Co-authored-by: Batixx --- Mathlib/Algebra/Category/CoalgCat/ComonEquivalence.lean | 2 -- Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean | 3 +-- Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean | 3 +-- Mathlib/CategoryTheory/Galois/Topology.lean | 2 +- Mathlib/CategoryTheory/Localization/Trifunctor.lean | 2 +- Mathlib/CategoryTheory/Sites/Over.lean | 2 +- Mathlib/GroupTheory/IsSubnormal.lean | 3 +-- 7 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Mathlib/Algebra/Category/CoalgCat/ComonEquivalence.lean b/Mathlib/Algebra/Category/CoalgCat/ComonEquivalence.lean index 2f0c1d2516ed1b..d7da06bd1af254 100644 --- a/Mathlib/Algebra/Category/CoalgCat/ComonEquivalence.lean +++ b/Mathlib/Algebra/Category/CoalgCat/ComonEquivalence.lean @@ -187,8 +187,6 @@ theorem comul_tensorObj_tensorObj_left : (A := ((CoalgCat.of R M ⊗ CoalgCat.of R N) ⊗ CoalgCat.of R P : CoalgCat R)) = Coalgebra.comul (A := M ⊗[R] N ⊗[R] P) := by rw [ofComonObjCoalgebraStruct_comul] - dsimp +instances - simp +instances only [toComonObj] simp [tensorμ_eq_tensorTensorTensorComm, TensorProduct.comul_def, AlgebraTensorModule.tensorTensorTensorComm_eq] rfl diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean index abdf63e2098e0f..34a404e16be455 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean @@ -75,8 +75,7 @@ lemma pushforwardSections_unitHomEquiv (unitToPushforwardObjUnit φ ≫ (pushforward φ).map f) := by ext X have := unitToPushforwardObjUnit_val_app_apply φ (X := X) 1 - dsimp at this ⊢ - simp +instances [this, map_one] + simp [this, map_one] rfl variable [(pushforward.{u} φ).IsRightAdjoint] diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean index c03fc7a53b0c76..bee106c6039743 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean @@ -256,8 +256,7 @@ lemma le_of_iSup_eq_top {I J : X.IdealSheafData} {ι : Type*} refine Submodule.le_of_isLocalized_span _ this (fun i ↦ Γ(X, X.basicOpen i.1)) (fun i ↦ Algebra.linearMap Γ(X, V.1) Γ(X, X.basicOpen i.1)) ?_ rintro ⟨_, j, rfl⟩ - dsimp - simp +instances only [← Submodule.restrictScalars_localized' Γ(X, X.basicOpen (r j)), + simp only [← Submodule.restrictScalars_localized' Γ(X, X.basicOpen (r j)), Ideal.localized'_eq_map, RingHom.algebraMap_toAlgebra] erw [I.map_ideal (U := ⟨_, V.2.basicOpen _⟩) (X.basicOpen_le (r j)), J.map_ideal (U := ⟨_, V.2.basicOpen _⟩) (X.basicOpen_le (r j))] diff --git a/Mathlib/CategoryTheory/Galois/Topology.lean b/Mathlib/CategoryTheory/Galois/Topology.lean index b3075869aaa53e..08d22dfd2817d5 100644 --- a/Mathlib/CategoryTheory/Galois/Topology.lean +++ b/Mathlib/CategoryTheory/Galois/Topology.lean @@ -92,7 +92,7 @@ lemma autEmbedding_range : Set.range (autEmbedding F) = ⋂ (f : Arrow C), { a | F.map f.hom ≫ (a f.right).hom = (a f.left).hom ≫ F.map f.hom } := by ext a - simp +instances only [Set.mem_range, Set.mem_iInter, Set.mem_setOf_eq] + simp only [Set.mem_range, Set.mem_iInter, Set.mem_setOf_eq] refine ⟨fun ⟨σ, h⟩ i ↦ by cat_disch, fun h ↦ ?_⟩ exact ⟨NatIso.ofComponents a (fun {X Y} f ↦ by ext; simpa using ConcreteCategory.congr_hom (h ⟨X, Y, f⟩) _), rfl⟩ diff --git a/Mathlib/CategoryTheory/Localization/Trifunctor.lean b/Mathlib/CategoryTheory/Localization/Trifunctor.lean index 0a82e9dd1e54aa..a06b4cdf7efff0 100644 --- a/Mathlib/CategoryTheory/Localization/Trifunctor.lean +++ b/Mathlib/CategoryTheory/Localization/Trifunctor.lean @@ -221,7 +221,7 @@ lemma associator_hom_app_app_app (X₁ : C₁) (X₂ : C₂) (X₃ : C₃) : (G₂₃ ⋙ (whiskeringRight _ _ _).obj L₂₃) G₂₃').inv.app X₂).app X₃) := by dsimp [associator] rw [lift₃NatTrans_app_app_app] - dsimp +instances [Lifting₃.iso, Lifting₃.bifunctorComp₁₂, Lifting₃.bifunctorComp₂₃] + dsimp [Lifting₃.iso, Lifting₃.bifunctorComp₁₂, Lifting₃.bifunctorComp₂₃] simp only [Category.assoc] end diff --git a/Mathlib/CategoryTheory/Sites/Over.lean b/Mathlib/CategoryTheory/Sites/Over.lean index 3a512a92661ab2..19c03ba87acf1c 100644 --- a/Mathlib/CategoryTheory/Sites/Over.lean +++ b/Mathlib/CategoryTheory/Sites/Over.lean @@ -532,7 +532,7 @@ lemma over_toGrothendieck_eq_toGrothendieck_comap_forget (X : C) : refine le_antisymm ?_ ?_ · intro ⟨Y, right, (s : Y ⟶ X)⟩ R hR obtain ⟨(R : Sieve Y), rfl⟩ := (Sieve.overEquiv _).symm.surjective R - simp +instances only [GrothendieckTopology.mem_over_iff, OrderIso.apply_symm_apply, + simp only [GrothendieckTopology.mem_over_iff, OrderIso.apply_symm_apply, ← Precoverage.toGrothendieck_toCoverage, Coverage.mem_toGrothendieck, Over.left] at hR induction hR with diff --git a/Mathlib/GroupTheory/IsSubnormal.lean b/Mathlib/GroupTheory/IsSubnormal.lean index 2ee36f6407a99c..ee416209372056 100644 --- a/Mathlib/GroupTheory/IsSubnormal.lean +++ b/Mathlib/GroupTheory/IsSubnormal.lean @@ -189,8 +189,7 @@ lemma isSubnormal_iff : H.IsSubnormal ↔ · grind · refine monotone_nat_of_le_succ ?_ grind only [monotone_iff_forall_lt] - · simp +instances only - grind + · grind mpr := by rintro ⟨n, hyps⟩ revert H From 2d8c533bd0a0515caa32f18c0ab4485bd6229378 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 12:28:12 +0000 Subject: [PATCH 0779/1300] feat(LinearAlgebra/Dimension/Localization): `Module.rank` is preserved by `IsFractionRing` (#41698) This PR proves that replacing a ring by its fraction ring does not change `rank` or `finrank`. I have named these `rank_right_eq` and `finrank_right_eq` in anticipation of further variants landing in #41694. Co-authored-by: tb65536 --- .../LinearAlgebra/Dimension/Localization.lean | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Mathlib/LinearAlgebra/Dimension/Localization.lean b/Mathlib/LinearAlgebra/Dimension/Localization.lean index 570105f08262ee..9cefb23f6802de 100644 --- a/Mathlib/LinearAlgebra/Dimension/Localization.lean +++ b/Mathlib/LinearAlgebra/Dimension/Localization.lean @@ -72,6 +72,29 @@ lemma IsLocalization.rank_eq : Module.rank S N = Module.rank R N := by · have := inj.nontrivial exact (hs.localization S p).cardinal_le_rank +theorem IsLocalization.finrank_eq : finrank S N = finrank R N := by + simp_rw [finrank, rank_eq S p hp] + +end + +section + +variable (R N) [IsFractionRing R S] + +/-- Given `IsScalarTower R S N`, if `S` is the fraction ring of `R`, then the rank `rank S N` +of the right part of the tower equals the rank `rank R N` of the whole tower. + +See `IsFractionRing.finrank_right_eq` for the finrank version. -/ +theorem IsFractionRing.rank_right_eq : Module.rank S N = Module.rank R N := + IsLocalization.rank_eq S R⁰ le_rfl + +/-- Given `IsScalarTower R S N`, if `S` is the fraction ring of `R`, then the finrank `finrank S N` +of the right part of the tower equals the finrank `finrank R N` of the whole tower. + +See `IsFractionRing.rank_right_eq` for the rank version. -/ +theorem IsFractionRing.finrank_right_eq : finrank S N = finrank R N := + IsLocalization.finrank_eq S R⁰ le_rfl + end variable (R M) in From 4a73a604a632a0ccbfede27ec82c817aca9b043d Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 13:20:49 +0000 Subject: [PATCH 0780/1300] feat(LinearAlgebra/Dimension/Finite): add `rank_eq_zero_of_not_faithfulSMul` (#41697) If the action of `R` on `M` is not faithful, then the rank is zero. Co-authored-by: tb65536 --- Mathlib/LinearAlgebra/Dimension/Basic.lean | 5 +++++ Mathlib/LinearAlgebra/Dimension/Finite.lean | 3 +++ 2 files changed, 8 insertions(+) diff --git a/Mathlib/LinearAlgebra/Dimension/Basic.lean b/Mathlib/LinearAlgebra/Dimension/Basic.lean index 824dc4f9b01d3a..be686d7a739311 100644 --- a/Mathlib/LinearAlgebra/Dimension/Basic.lean +++ b/Mathlib/LinearAlgebra/Dimension/Basic.lean @@ -176,6 +176,11 @@ theorem Module.one_le_rank_iff : 1 ≤ Module.rank R M ↔ ∃ f : R →ₗ[R] M · exact ⟨f ∘ₗ _, by apply hf.comp (LinearEquiv.piUnique R ..).symm.injective⟩ · exact ⟨f ∘ₗ _, hf.comp (LinearEquiv.piUnique R ..).injective⟩ +theorem Module.rank_eq_zero_of_not_faithfulSMul (h : ¬ FaithfulSMul R M) : Module.rank R M = 0 := by + contrapose! h + obtain ⟨f, hf⟩ := by rwa [← Cardinal.one_le_iff_ne_zero, one_le_rank_iff] at h + exact ⟨fun {x y} hxy ↦ hf (by simpa [← map_smul] using hxy (f 1))⟩ + section variable [AddCommMonoid M'] [Module R' M'] diff --git a/Mathlib/LinearAlgebra/Dimension/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Finite.lean index d08c8e0cf7ff44..954e193f16af00 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finite.lean @@ -424,6 +424,9 @@ theorem Module.finrank_eq_zero_of_rank_eq_zero (h : Module.rank R M = 0) : delta finrank rw [h, zero_toNat] +theorem Module.finrank_eq_zero_of_not_faithfulSMul (h : ¬ FaithfulSMul R M) : finrank R M = 0 := + finrank_eq_zero_of_rank_eq_zero (rank_eq_zero_of_not_faithfulSMul h) + section variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M] [IsDomain R] [IsTorsionFree R M] From 249c48c2c2b5d7ebf8e765c30ce13b680e99cf04 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:52:52 +0000 Subject: [PATCH 0781/1300] feat(FieldTheory/IntermediateField/Adjoin/Defs): prove `adjoin F (adjoin K S) = adjoin F S` (#41416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds `adjoin_adjoin_right`, which states that `adjoin F (adjoin K S) = adjoin F S` (compare with `adjoin_adjoin_left` which states that `(adjoin (adjoin F S) T).restrictScalars _ = adjoin F (S ∪ T)`). This can be used to golf the proof of `adjoin_insert_adjoin`. I had to move `adjoin_union` earlier in the file (I moved to be with `adjoin_empty` and `adjoin_univ`). Upstreamed from FLT. Co-authored-by: tb65536 --- .../IntermediateField/Adjoin/Defs.lean | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean index 99fe8c8f78d0dd..5e784b6a68cede 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Defs.lean @@ -360,6 +360,9 @@ theorem adjoin_univ (F E : Type*) [Field F] [Field E] [Algebra F E] : adjoin F (Set.univ : Set E) = ⊤ := eq_top_iff.mpr <| subset_adjoin _ _ +theorem adjoin_union {S T : Set E} : adjoin F (S ∪ T) = adjoin F S ⊔ adjoin F T := + gc.l_sup + /-- If `K` is a field with `F ⊆ K` and `S ⊆ K` then `adjoin F S ≤ K`. -/ theorem adjoin_le_subfield {K : Subfield E} (HF : Set.range (algebraMap F E) ⊆ K) (HS : S ⊆ K) : (adjoin F S).toSubfield ≤ K := by @@ -385,15 +388,18 @@ theorem adjoin_adjoin_left (T : Set E) : (fun x hx ↦ Subfield.subset_closure <| .inl ⟨⟨x, Subfield.subset_closure (.inr hx)⟩, rfl⟩) (fun x hx ↦ Subfield.subset_closure <| .inr hx) +/-- Adjoining is idempotent: adjoining an adjoin is the same as a single adjoin. -/ +@[simp] +lemma adjoin_adjoin_right {K : Type*} [Field K] [Algebra K F] [Algebra K E] [IsScalarTower K F E] : + adjoin F (adjoin K S) = adjoin F S := by + refine le_antisymm ?_ (adjoin.mono F S (adjoin K S) (subset_adjoin K S)) + rw [adjoin_le_iff, ← (adjoin F S).coe_restrictScalars K, SetLike.coe_subset_coe] + simp + @[simp] theorem adjoin_insert_adjoin (x : E) : - adjoin F (insert x (adjoin F S : Set E)) = adjoin F (insert x S) := - le_antisymm - (adjoin_le_iff.mpr - (Set.insert_subset_iff.mpr - ⟨subset_adjoin _ _ (Set.mem_insert _ _), - adjoin_le_iff.mpr (subset_adjoin_of_subset_right _ _ (Set.subset_insert _ _))⟩)) - (by grw [← subset_adjoin]) + adjoin F (insert x (adjoin F S : Set E)) = adjoin F (insert x S) := by + simp_rw [← Set.singleton_union, adjoin_union, adjoin_adjoin_right] /-- `F[S][T] = F[T][S]` -/ theorem adjoin_adjoin_comm (T : Set E) : @@ -446,9 +452,6 @@ theorem extendScalars_adjoin {K : IntermediateField F E} {S : Set E} (h : K ≤ exact le_antisymm (adjoin.mono F S _ Set.subset_union_right) <| adjoin_le_iff.2 <| Set.union_subset h (subset_adjoin F S) -theorem adjoin_union {S T : Set E} : adjoin F (S ∪ T) = adjoin F S ⊔ adjoin F T := - gc.l_sup - theorem restrictScalars_adjoin_eq_sup (K : IntermediateField F E) (S : Set E) : restrictScalars F (adjoin K S) = K ⊔ adjoin F S := by rw [restrictScalars_adjoin, adjoin_union, adjoin_self] From 783ccda4ee524f13cc5636237be0a1942bc04824 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:10:08 +0000 Subject: [PATCH 0782/1300] chore(Topology/Algebra/Module/FiniteDimension): automated extraction from #39100 (#41738) This PR was automatically created from PR #39100 by @ADedecker via a [review comment](https://github.com/leanprover-community/mathlib4/pull/39100#discussion_r3579997910) by @ocfnash. Co-authored-by: ADedecker <48656793+ADedecker@users.noreply.github.com> --- Mathlib/Topology/Algebra/Module/FiniteDimension.lean | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean index 9e16cef2540d80..60e8aeb7c50f87 100644 --- a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean +++ b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean @@ -553,6 +553,17 @@ theorem Submodule.isClosed_sup_finiteDimensional rw [← comap_map_mkQ] exact (map s.mkQ t).closed_of_finiteDimensional.preimage continuous_quot_mk +/-- A sufficient condition for a linear map taking values in a TVS to have closed range is that +there exists a finite-codimension subspace of the domain whose image is closed. -/ +theorem LinearMap.isClosed_range_of_isClosed_map_of_finiteDimensional_quotient + {E : Type*} [AddCommGroup E] [Module 𝕜 E] {f : E →ₗ[𝕜] F} {s : Submodule 𝕜 E} + [s.CoFG] (h : IsClosed (s.map f : Set F)) : + IsClosed (f.range : Set F) := by + obtain ⟨t, s_compl_t⟩ := Submodule.exists_isCompl s + have : FiniteDimensional 𝕜 t := .of_fg <| Submodule.CoFG.fg_of_isCompl s_compl_t inferInstance + rw [← Submodule.map_top, ← s_compl_t.sup_eq_top, Submodule.map_sup] + exact Submodule.isClosed_sup_finiteDimensional _ _ h + /-- An injective linear map with finite-dimensional domain is a closed embedding. -/ theorem LinearMap.isClosedEmbedding_of_injective [T2Space E] [FiniteDimensional 𝕜 E] [T2Space F] {f : E →ₗ[𝕜] F} (hf : LinearMap.ker f = ⊥) : IsClosedEmbedding f := From aae61ae084c21995ee248964a81e3750ad0db2db Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:30:49 +0000 Subject: [PATCH 0783/1300] refactor(Order/JordanHolder): remove `Iso` from `JordanHolderLattice` (#41445) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently `JordanHolderLattice` requires a choice of `Iso`. Different choices of `Iso` will lead to different strength versions of the Jordan-Holder theorem. For example, picking `Iso` to be "quotients have the same cardinality" will prove that any two composition series can be rearranged so that corresponding quotients have the same cardinality. But there is actually a strongest possible choice for `Iso`, namely the equivalence relation generated by the relations `Iso (x, x ⊔ y) (x ⊓ y, y)` for `IsMaximal x (x ⊔ y)`. These are exactly the moves that are strung together to prove the Jordan-Holder theorem. Fixing `Iso` to be this strongest possible choice leads to the strongest possible Jordan-Holder theorem. This allows us to remove `Iso` from definition of `JordanHolderLattice`. The proof obligation `IsMaximal x (x ⊔ y) → (x, x ⊔ y) ~ (x ⊓ y, y)` moves from a field of `JordanHolderLattice` to something that the user must later prove to deduce that `Iso` implies the desired equivalence relation (usually "quotients are isomorphic"). This also allows us to add an instance stating that every modular lattice is a Jordan-Holder lattice, resolving a longstanding todo in the file. So we can also remove the instance stating that submodules form a Jordan-Holder lattice. Co-authored-by: tb65536 --- Mathlib/Order/JordanHolder.lean | 98 +++++++++++++--------- Mathlib/Order/ModularLattice.lean | 18 +++- Mathlib/RingTheory/SimpleModule/Basic.lean | 28 +++---- 3 files changed, 84 insertions(+), 60 deletions(-) diff --git a/Mathlib/Order/JordanHolder.lean b/Mathlib/Order/JordanHolder.lean index fc6a98ca3a949d..58f8d818e5fcda 100644 --- a/Mathlib/Order/JordanHolder.lean +++ b/Mathlib/Order/JordanHolder.lean @@ -6,6 +6,7 @@ Authors: Chris Hughes module public import Mathlib.Order.Lattice +public import Mathlib.Order.ModularLattice public import Mathlib.Data.List.Sort public import Mathlib.Logic.Equiv.Fin.Basic public import Mathlib.Logic.Equiv.Functor @@ -25,11 +26,8 @@ The main definitions in this file are `JordanHolderLattice` and `CompositionSeri and the relation `Equivalent` on `CompositionSeries` A `JordanHolderLattice` is the class for which the Jordan Hölder theorem is proved. A -Jordan Hölder lattice is a lattice equipped with a notion of maximality, `IsMaximal`, and a notion -of isomorphism of pairs `Iso`. In the example of subgroups of a group, `IsMaximal H K` means that -`H` is a maximal normal subgroup of `K`, and `Iso (H₁, K₁) (H₂, K₂)` means that the quotient -`H₁ / K₁` is isomorphic to the quotient `H₂ / K₂`. `Iso` must be symmetric and transitive and must -satisfy the second isomorphism theorem `Iso (H, H ⊔ K) (H ⊓ K, K)`. +Jordan Hölder lattice is a lattice equipped with a notion of maximality, `IsMaximal`. In the +example of subgroups of a group, `IsMaximal H K` means that `H` is a maximal normal subgroup of `K`. A `CompositionSeries X` is a finite nonempty series of elements of the lattice `X` such that each element is maximal inside the next. The length of a `CompositionSeries X` is @@ -38,6 +36,11 @@ that a series start from the bottom of the lattice and finish at the top. For a composition series `s`, `s.last` is the largest element of the series, and `s.head` is the least element. +We define an equivalence relation `JordanHolderLattice.Iso` on intervals generated by the relations +`Iso (x, x ⊔ y) (x ⊓ y, y)` for `IsMaximal x (x ⊔ y)`. This is the strongest possible equivalence +relation for which we can prove the Jordan Hölder theorem. For any specific `JordanHolderLattice`, +one must verify that `Iso` implies the desired weaker notion (e.g., isomorphism of quotients). + Two `CompositionSeries X`, `s₁` and `s₂` are equivalent if there is a bijection `e : Fin s₁.length ≃ Fin s₂.length` such that for any `i`, `Iso (s₁ i, s₁ i.succ) (s₂ (e i), s₂ (e i.succ))` @@ -50,24 +53,7 @@ then they are `Equivalent`. ## TODO -Provide instances of `JordanHolderLattice` for subgroups, and potentially for modular lattices. - -It is not entirely clear how this should be done. Possibly there should be no global instances -of `JordanHolderLattice`, and the instances should only be defined locally in order to prove -the Jordan-Hölder theorem for modules/groups and the API should be transferred because many of the -theorems in this file will have stronger versions for modules. There will also need to be an API for -mapping composition series across homomorphisms. It is also probably possible to -provide an instance of `JordanHolderLattice` for any `ModularLattice`, and in this case the -Jordan-Hölder theorem will say that there is a well-defined notion of length of a modular lattice. -However an instance of `JordanHolderLattice` for a modular lattice will not be able to contain -the correct notion of isomorphism for modules, so a separate instance for modules will still be -required and this will clash with the instance for modular lattices, and so at least one of these -instances should not be a global instance. - -> [!NOTE] -> The previous paragraph indicates that the instance of `JordanHolderLattice` for submodules should -> be obtained via `ModularLattice`. This is not the case in `mathlib4`. -> See `JordanHolderModule.instJordanHolderLattice`. +Provide instances of `JordanHolderLattice` for subgroups. -/ @[expose] public section @@ -78,28 +64,62 @@ universe u open Set RelSeries /-- A `JordanHolderLattice` is the class for which the Jordan Hölder theorem is proved. A -Jordan Hölder lattice is a lattice equipped with a notion of maximality, `IsMaximal`, and a notion -of isomorphism of pairs `Iso`. In the example of subgroups of a group, `IsMaximal H K` means that -`H` is a maximal normal subgroup of `K`, and `Iso (H₁, K₁) (H₂, K₂)` means that the quotient -`H₁ / K₁` is isomorphic to the quotient `H₂ / K₂`. `Iso` must be symmetric and transitive and must -satisfy the second isomorphism theorem `Iso (H, H ⊔ K) (H ⊓ K, K)`. +Jordan Hölder lattice is a lattice equipped with a notion of maximality, `IsMaximal`. + Examples include `Subgroup G` if `G` is a group, and `Submodule R M` if `M` is an `R`-module. --/ + +In the example of subgroups, `IsMaximal H K` means that `H` is a maximal normal subgroup of `K`. +In the example of submodules, `IsMaximal M N` means that `M` is a maximal submodule of `N`. -/ class JordanHolderLattice (X : Type u) [Lattice X] where IsMaximal : X → X → Prop lt_of_isMaximal : ∀ {x y}, IsMaximal x y → x < y sup_eq_of_isMaximal : ∀ {x y z}, IsMaximal x z → IsMaximal y z → x ≠ y → x ⊔ y = z isMaximal_inf_left_of_isMaximal_sup : ∀ {x y}, IsMaximal x (x ⊔ y) → IsMaximal y (x ⊔ y) → IsMaximal (x ⊓ y) x - Iso : X × X → X × X → Prop - iso_symm : ∀ {x y}, Iso x y → Iso y x - iso_trans : ∀ {x y z}, Iso x y → Iso y z → Iso x z - second_iso : ∀ {x y}, IsMaximal x (x ⊔ y) → Iso (x, x ⊔ y) (x ⊓ y, y) namespace JordanHolderLattice +/-- Every modular lattice is a Jordan Hölder lattice. -/ +instance (X : Type u) [Lattice X] [IsModularLattice X] : JordanHolderLattice X where + IsMaximal := (· ⋖ ·) + lt_of_isMaximal := CovBy.lt + sup_eq_of_isMaximal hxz hyz := hxz.wcovBy.sup_eq hyz.wcovBy + isMaximal_inf_left_of_isMaximal_sup := inf_covBy_of_covBy_sup_of_covBy_sup_left + variable {X : Type u} [Lattice X] [JordanHolderLattice X] +/-- The equivalence relation on intervals generated by the relations `Iso (x, x ⊔ y) (x ⊓ y, y)` for +`IsMaximal x (x ⊔ y)`. This is the strongest possibly equivalence relation for which we can prove +the Jordan Hölder theorem. For any specific `JordanHolderLattice`, use `Iso.rel` to verify that +`Iso` implies the desired weaker notion (e.g., isomorphism of quotients). -/ +def Iso : X × X → X × X → Prop := + Relation.EqvGen fun (x, xsy) (xiy, y) ↦ IsMaximal x xsy ∧ xsy = x ⊔ y ∧ xiy = x ⊓ y + +theorem iso_refl {x : X × X} : Iso x x := + Relation.EqvGen.refl x + +theorem iso_symm {x y : X × X} (h : Iso x y) : Iso y x := + Relation.EqvGen.symm x y h + +theorem iso_trans {x y z : X × X} (hxy : Iso x y) (hyz : Iso y z) : Iso x z := + Relation.EqvGen.trans x y z hxy hyz + +theorem second_iso {x y : X} (h : IsMaximal x (x ⊔ y)) : Iso (x, x ⊔ y) (x ⊓ y, y) := + Relation.EqvGen.rel (x, x ⊔ y) (x ⊓ y, y) ⟨h, rfl, rfl⟩ + +/-- The equivalence relation on intervals implies any other notions of isomorphism. -/ +theorem Iso.rel + (e : X × X → X × X → Prop) + (h_refl : ∀ {x}, e x x) + (h_symm : ∀ {x y}, e x y → e y x) + (h_trans : ∀ {x y z}, e x y → e y z → e x z) + (h_rel : ∀ {x y}, IsMaximal x (x ⊔ y) → e (x, x ⊔ y) (x ⊓ y, y)) + {x y : X × X} (h_iso : Iso x y) : e x y := by + have : IsEquiv (X × X) e := { refl _ := h_refl, symm _ _ := h_symm, trans _ _ _ := h_trans } + refine Relation.EqvGen.eqvGen_le ?_ h_iso + rintro ⟨a, b⟩ ⟨c, d⟩ ⟨h, rfl : b = a ⊔ d, rfl : c = a ⊓ d⟩ + exact h_rel h + theorem isMaximal_inf_right_of_isMaximal_sup {x y : X} (hxz : IsMaximal x (x ⊔ y)) (hyz : IsMaximal y (x ⊔ y)) : IsMaximal (x ⊓ y) y := by rw [inf_comm] @@ -115,9 +135,7 @@ theorem isMaximal_of_eq_inf (x b : X) {a y : X} (ha : x ⊓ y = a) (hxy : x ≠ theorem second_iso_of_eq {x y a b : X} (hm : IsMaximal x a) (ha : x ⊔ y = a) (hb : x ⊓ y = b) : Iso (x, a) (b, y) := by subst a b; exact second_iso hm -theorem IsMaximal.iso_refl {x y : X} (h : IsMaximal x y) : Iso (x, y) (x, y) := - second_iso_of_eq h (sup_eq_right.2 (le_of_lt (lt_of_isMaximal h))) - (inf_eq_left.2 (le_of_lt (lt_of_isMaximal h))) +@[deprecated (since := "2026-07-11")] alias IsMaximal.iso_refl := iso_refl end JordanHolderLattice @@ -253,7 +271,7 @@ namespace Equivalent @[refl] theorem refl (s : CompositionSeries X) : Equivalent s s := - ⟨Equiv.refl _, fun _ => (s.step _).iso_refl⟩ + ⟨Equiv.refl _, fun _ => iso_refl⟩ @[symm] theorem symm {s₁ s₂ : CompositionSeries X} (h : Equivalent s₁ s₂) : Equivalent s₂ s₁ := @@ -360,7 +378,7 @@ theorem snoc_snoc_swap {s : CompositionSeries X} {x₁ x₂ y₁ y₂ : X} {hsat · erw [Equiv.swap_apply_of_ne_of_ne h2 h1, snoc_castSucc, snoc_castSucc, snoc_castSucc, snoc_castSucc, Fin.succ_castSucc, snoc_castSucc, Fin.succ_castSucc, snoc_castSucc, snoc_castSucc, snoc_castSucc] - exact (s.step i).iso_refl⟩ + exact iso_refl⟩ end Equivalent @@ -423,7 +441,7 @@ theorem exists_last_eq_snoc_equivalent (s : CompositionSeries X) (x : X) (hm : I htt.symm ▸ imxs).snoc s.last (by simpa using isMaximal_eraseLast_last h0s)) := by conv_lhs => rw [eq_snoc_eraseLast h0s] - exact Equivalent.snoc hteqv (by simpa using (isMaximal_eraseLast_last h0s).iso_refl) + exact Equivalent.snoc hteqv (by simpa using iso_refl) refine this.trans <| Equivalent.snoc_snoc_swap (iso_symm (second_iso_of_eq hm @@ -449,6 +467,6 @@ theorem jordan_holder (s₁ s₂ : CompositionSeries X) refine hteq.trans ?_ conv_rhs => rw [eq_snoc_eraseLast h0s₂] simp only [ht] - exact Equivalent.snoc this (by simpa [htt] using (isMaximal_eraseLast_last h0s₂).iso_refl) + exact Equivalent.snoc this (by simpa [htt] using iso_refl) end CompositionSeries diff --git a/Mathlib/Order/ModularLattice.lean b/Mathlib/Order/ModularLattice.lean index 4702db1d0bd2d3..1173bc3a3f8e7e 100644 --- a/Mathlib/Order/ModularLattice.lean +++ b/Mathlib/Order/ModularLattice.lean @@ -220,9 +220,9 @@ theorem wellFounded_gt_exact_sequence {β γ : Type*} [Preorder β] [Preorder γ wellFounded_lt_exact_sequence (α := αᵒᵈ) (β := γᵒᵈ) (γ := βᵒᵈ) K g₁ g₂ f₁ f₂ gi.dual gci.dual hg hf -/-- The diamond isomorphism between the intervals `[a ⊓ b, a]` and `[b, a ⊔ b]` -/ +/-- The diamond isomorphism between the closed intervals `[a ⊓ b, a]` and `[b, a ⊔ b]` -/ @[simps] -def infIccOrderIsoIccSup (a b : α) : Set.Icc (a ⊓ b) a ≃o Set.Icc b (a ⊔ b) where +def infIccOrderIsoIccSup (a b : α) : Icc (a ⊓ b) a ≃o Icc b (a ⊔ b) where toFun x := ⟨x ⊔ b, ⟨le_sup_right, sup_le_sup_right x.prop.2 b⟩⟩ invFun x := ⟨a ⊓ x, ⟨inf_le_inf_left a x.prop.1, inf_le_left⟩⟩ left_inv x := @@ -243,13 +243,19 @@ def infIccOrderIsoIccSup (a b : α) : Set.Icc (a ⊓ b) a ≃o Set.Icc b (a ⊔ sup_eq_right.2 y.prop.1, inf_sup_assoc_of_le _ y.prop.2, sup_comm b] exact inf_le_inf_left _ h +/-- The diamond isomorphism between the closed intervals `[a ⊓ b, b]` and `[a, a ⊔ b]` -/ +@[simps!] +def infIccOrderIsoIccSup' (a b : α) : Icc (a ⊓ b) b ≃o Icc a (a ⊔ b) := + (OrderIso.setCongr _ _ (by rw [inf_comm])).trans <| (infIccOrderIsoIccSup b a).trans <| + OrderIso.setCongr _ _ (by rw [sup_comm]) + theorem inf_strictMonoOn_Icc_sup {a b : α} : StrictMonoOn (fun c => a ⊓ c) (Icc b (a ⊔ b)) := StrictMono.of_restrict (infIccOrderIsoIccSup a b).symm.strictMono theorem sup_strictMonoOn_Icc_inf {a b : α} : StrictMonoOn (fun c => c ⊔ b) (Icc (a ⊓ b) a) := StrictMono.of_restrict (infIccOrderIsoIccSup a b).strictMono -/-- The diamond isomorphism between the intervals `]a ⊓ b, a[` and `}b, a ⊔ b[`. -/ +/-- The diamond isomorphism between the open intervals `(a ⊓ b, a)` and `(b, a ⊔ b)`. -/ @[simps] def infIooOrderIsoIooSup (a b : α) : Ioo (a ⊓ b) a ≃o Ioo b (a ⊔ b) where toFun c := @@ -274,6 +280,12 @@ def infIooOrderIsoIooSup (a b : α) : Ioo (a ⊓ b) a ≃o Ioo b (a ⊔ b) where @OrderIso.le_iff_le _ _ _ _ (infIccOrderIsoIccSup _ _) ⟨c.1, Ioo_subset_Icc_self c.2⟩ ⟨d.1, Ioo_subset_Icc_self d.2⟩ +/-- The diamond isomorphism between the open intervals `(a ⊓ b, b)` and `(a, a ⊔ b)`. -/ +@[simps!] +def infIooOrderIsoIooSup' (a b : α) : Ioo (a ⊓ b) b ≃o Ioo a (a ⊔ b) := + (OrderIso.setCongr _ _ (by rw [inf_comm])).trans <| (infIooOrderIsoIooSup b a).trans <| + OrderIso.setCongr _ _ (by rw [sup_comm]) + -- See note [lower instance priority] instance (priority := 100) IsModularLattice.to_isLowerModularLattice : IsLowerModularLattice α := ⟨fun {a b} => by diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index cf045c20aa2d96..7b19346c53fe5f 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -547,23 +547,17 @@ instance (R) [DivisionRing R] [Module R M] [Nontrivial M] : IsSimpleModule (Modu end LinearMap -namespace JordanHolderModule - -instance instJordanHolderLattice : JordanHolderLattice (Submodule R M) where - IsMaximal := (· ⋖ ·) - lt_of_isMaximal := CovBy.lt - sup_eq_of_isMaximal hxz hyz := WCovBy.sup_eq hxz.wcovBy hyz.wcovBy - isMaximal_inf_left_of_isMaximal_sup := inf_covBy_of_covBy_sup_of_covBy_sup_left - Iso X Y := Nonempty <| (X.2 ⧸ X.1.comap X.2.subtype) ≃ₗ[R] Y.2 ⧸ Y.1.comap Y.2.subtype - iso_symm := fun ⟨f⟩ => ⟨f.symm⟩ - iso_trans := fun ⟨f⟩ ⟨g⟩ => ⟨f.trans g⟩ - second_iso {X} {Y} _ := by - constructor - rw [sup_comm, inf_comm] - dsimp - exact (LinearMap.quotientInfEquivSupQuotient Y X).symm - -end JordanHolderModule +namespace JordanHolderLattice + +/-- The isomorphism relation for composition series of modules implies isomorphism of quotients. -/ +noncomputable def Iso.linearEquiv {X Y : Submodule R M × Submodule R M} (h : Iso X Y) : + (X.2 ⧸ X.1.comap X.2.subtype) ≃ₗ[R] Y.2 ⧸ Y.1.comap Y.2.subtype := + letI e : Submodule R M × Submodule R M → Submodule R M × Submodule R M → Prop := + fun X Y ↦ Nonempty <| (X.2 ⧸ X.1.comap X.2.subtype) ≃ₗ[R] Y.2 ⧸ Y.1.comap Y.2.subtype + Nonempty.some <| h.rel e ⟨.refl R _⟩ (fun ⟨f⟩ ↦ ⟨f.symm⟩) (fun ⟨f⟩ ⟨g⟩ ↦ ⟨f.trans g⟩) + fun h ↦ by rw [sup_comm, inf_comm]; exact ⟨(LinearMap.quotientInfEquivSupQuotient ..).symm⟩ + +end JordanHolderLattice section jacobson_density From 827142c3f60cc75c16f6acd229c2aa2d502bd19e Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:11:21 +0000 Subject: [PATCH 0784/1300] chore: fix non-reducible diamond in C^* algebras (#40431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following fails before the PR, succeeds after it ``` example : ((instCStarAlgebraSubtypeMemStarSubalgebraComplexElemental x).toAlgebra : Algebra ℂ ↥(StarAlgebra.elemental ℂ x)) = (StarAlgebra.elemental ℂ x).algebra := by with_reducible_and_instances rfl ``` Co-authored-by: sgouezel --- Mathlib/Algebra/Ring/Subsemiring/Basic.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean index 0a393c2b0c391b..5bdf2171feb8e8 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean @@ -721,6 +721,7 @@ variable [SetLike σR R] [SetLike σS S] [SubsemiringClass σR R] [SubsemiringCl open Subsemiring /-- Restriction of a ring homomorphism to a subsemiring of the codomain. -/ +@[implicit_reducible] def codRestrict (f : R →+* S) (s : σS) (h : ∀ x, f x ∈ s) : R →+* s := { (f : R →* S).codRestrict s h, (f : R →+ S).codRestrict s h with toFun := fun n => ⟨f n, h n⟩ } From 5134085bde65e2a257d3556c7038cb2bbee2f380 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:11:24 +0000 Subject: [PATCH 0785/1300] feat: weaken assumptions to construct vector measures (#41153) Co-authored-by: sgouezel --- .../VectorMeasure/AddContent.lean | 89 +++++++++++++++++-- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean b/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean index 8394925e8a56f3..3fbf1b815c89e3 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean @@ -5,10 +5,12 @@ Authors: Sébastien Gouëzel -/ module +public import Mathlib.MeasureTheory.Function.ConditionalExpectation.LebesgueBochner public import Mathlib.Analysis.Normed.Group.InfiniteSum public import Mathlib.MeasureTheory.Measure.AddContent public import Mathlib.MeasureTheory.Measure.MeasuredSets -public import Mathlib.MeasureTheory.VectorMeasure.Basic +public import Mathlib.MeasureTheory.Measure.Trim +public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral /-! # Constructing a vector measure from an additive content @@ -16,7 +18,7 @@ public import Mathlib.MeasureTheory.VectorMeasure.Basic Consider a content defined on a semiring of sets. We investigate in this file whether it is possible to extend it to a (countably additive) vector measure on the whole sigma-algebra. We show that this is possible when the content is dominated by a finite -measure, see `exists_extension_of_isSetSemiring_of_le_measure_of_generateFrom`. +measure, see `exists_extension_of_isSetSemiring_of_le_measure`. -/ @[expose] public section @@ -291,10 +293,6 @@ private lemma exists_extension_of_isSetSemiring_of_le_measure_of_generateFrom_of /-- Consider an additive content `m ` on a semi-ring of sets `C`, which is dominated by a finite measure `μ`. Assume that `C` generates the sigma-algebra. Then `m` extends to a countably additive vector measure which is dominated by `μ`. -/ -/- TODO: weaken the assumption that `C` generates the sigma-algebra to measurability of all -elements of `C`, once integrals wrt vector measures is available (by composing the integral wrt `m'` -on the generated sigma-algebra, with conditional expectation of the indicator function to project -on the generated sigma-algebra). -/ theorem exists_extension_of_isSetSemiring_of_le_measure_of_generateFrom [IsFiniteMeasure μ] {C : Set (Set α)} {m : AddContent E C} (hC : IsSetSemiring C) (hm : ∀ s ∈ C, ‖m s‖ₑ ≤ μ s) (h'C : hα = generateFrom C) : @@ -315,4 +313,83 @@ theorem exists_extension_of_isSetSemiring_of_le_measure_of_generateFrom exact ae_le_set_inter Filter.EventuallyLE.rfl (hD s hs) exact ⟨m', h, fun s ↦ (h' s).trans (Measure.restrict_apply_le (⋃₀ D) s)⟩ +/-- Consider an additive content `m` on a semi-ring of measurable sets `C`, which is dominated +by a finite measure `μ`. +Then `m` extends to a countably additive vector measure which is dominated by `μ`. -/ +theorem exists_extension_of_isSetSemiring_of_le_measure [NormedSpace ℝ E] + [IsFiniteMeasure μ] {C : Set (Set α)} {m : AddContent E C} (hC : IsSetSemiring C) + (hm : ∀ s ∈ C, ‖m s‖ₑ ≤ μ s) (h'C : ∀ s ∈ C, MeasurableSet s) : + ∃ m' : VectorMeasure α E, (∀ s ∈ C, m' s = m s) ∧ ∀ s, ‖m' s‖ₑ ≤ μ s := by + /- On the sigma-algebra `M` generated by `C`, the desired vector measure is provided by + `exists_extension_of_isSetSemiring_of_le_measure_of_generateFrom`. We extend it to the whole + sigma-algebra of measurable sets by integrating the conditional expectation with respect to `M`. + This extension satisfies all the desired properties. -/ + classical + let M : MeasurableSpace α := generateFrom C + have Mle : M ≤ hα := generateFrom_le h'C + set μ' := μ.trim Mle with hμ' + obtain ⟨m', m'C, hm'⟩ : + ∃ m' : @VectorMeasure α M E _ _, (∀ s ∈ C, m' s = m s) ∧ ∀ s, ‖m' s‖ₑ ≤ μ' s := by + apply exists_extension_of_isSetSemiring_of_le_measure_of_generateFrom hC (fun s hs ↦ ?_) rfl + apply (hm s hs).trans_eq + exact (MeasureTheory.trim_measurableSet_eq Mle (measurableSet_generateFrom hs)).symm + have m'_le : m'.variation ≤ μ' := by + exact variation_le_of_forall_enorm_le (fun s hs ↦ hm' _) + -- next line is to make sure that the default instance is picked below when defininig `m''`. + let : MeasurableSpace α := hα + let m'' : VectorMeasure α E := + { measureOf' s := if MeasurableSet s then ∫ᵛ x, μ[s.indicator 1 | M] x ∂• m' else 0 + empty' := by simp + not_measurable' s hs := by simp [hs] + m_iUnion' f f_meas hf := by + have : ∫ᵛ (x : α), μ[fun x ↦ ∑' (d : ℕ), (f d).indicator 1 x | M] x ∂•m' + = ∫ᵛ (x : α), ∑' d, μ[(f d).indicator 1 | M] x ∂•m' := by + apply VectorMeasure.integral_congr_ae + apply ae_mono m'_le + apply ae_eq_trim_of_measurable _ (by fun_prop) (by fun_prop) + apply condExp_tsum (fun i ↦ ?_) + · simp only [enorm_indicator_eq_indicator_enorm, Pi.one_apply, enorm_one, f_meas, + lintegral_indicator, lintegral_const, MeasurableSet.univ, Measure.restrict_apply, + Set.univ_inter, one_mul, ne_eq, ← measure_iUnion hf f_meas, measure_ne_top, + not_false_eq_true] + · exact AEStronglyMeasurable.indicator (by fun_prop) (f_meas i) + simp only [f_meas, ↓reduceIte, implies_true, MeasurableSet.iUnion, + indicator_iUnion_of_pairwise_disjoint _ hf, this] + have I : ∑' (i : ℕ), ∫⁻ (a : α), ‖μ[(f i).indicator (1 : α → ℝ) | M] a‖ₑ ∂μ < ∞ := by + have A i : ∫⁻ a, ‖μ[(f i).indicator (1 : α → ℝ) | M] a‖ₑ ∂μ = μ (f i) := + lintegral_enorm_condExp_indicator Mle (f_meas i) + simp_rw [A, ← measure_iUnion hf f_meas] + exact measure_lt_top _ _ + rw [integral_tsum (by fun_prop)]; swap + · apply ne_of_lt + grw [m'_le, hμ'] + have A i : Measurable[M] (fun x ↦ ‖μ[(f i).indicator (1 : α → ℝ) | M] x‖ₑ) := by fun_prop + simp_rw [lintegral_trim Mle (A _)] + exact I + refine Summable.hasSum (Summable.of_enorm ?_) + apply ne_of_lt (lt_of_le_of_lt ?_ I) + gcongr with i + grw [enorm_integral_le_lintegral_enorm, ContinuousLinearMap.opENorm_lsmul_le, one_mul, + lintegral_mono' m'_le le_rfl, hμ', lintegral_trim _ (by fun_prop)] } + refine ⟨m'', fun s hs ↦ ?_, fun s ↦ ?_⟩ + · simp only [coe_mk, h'C s hs, ↓reduceIte, m''] + have : ∫ᵛ (x : α), μ[s.indicator 1 | M] x ∂•m' = ∫ᵛ (x : α), s.indicator 1 x ∂•m' := by + apply integral_congr_ae + filter_upwards with x + rw [condExp_of_stronglyMeasurable Mle] + · exact StronglyMeasurable.indicator stronglyMeasurable_const + (measurableSet_generateFrom hs) + · exact (integrable_const 1).indicator (h'C s hs) + rw [this, integral_indicator (measurableSet_generateFrom hs)] + have : IsFiniteMeasure m'.variation := + isFiniteMeasure_of_le _ m'_le + simp only [Pi.one_apply, setIntegral_const] + simp [m'C s hs] + · by_cases hs : MeasurableSet s; swap + · simp [not_measurable _ hs] + simp only [coe_mk, hs, ↓reduceIte, m''] + grw [enorm_integral_le_lintegral_enorm, ContinuousLinearMap.opENorm_lsmul_le, one_mul, + lintegral_mono' m'_le le_rfl, hμ', lintegral_trim _ (by fun_prop), + lintegral_enorm_condExp_indicator Mle hs] + end MeasureTheory.VectorMeasure From c866e9d5f66fe471af7d6e8ba8e8d5704a577a6b Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:11:26 +0000 Subject: [PATCH 0786/1300] feat: the product of bounded variation functions has bounded variation (#41195) Co-authored-by: sgouezel Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib/Analysis/BoundedVariation.lean | 112 +++++++++++++++++- .../EMetricSpace/BoundedVariation.lean | 5 + 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/BoundedVariation.lean b/Mathlib/Analysis/BoundedVariation.lean index a7d9407eecf000..ea1036c6ec2b8f 100644 --- a/Mathlib/Analysis/BoundedVariation.lean +++ b/Mathlib/Analysis/BoundedVariation.lean @@ -33,11 +33,121 @@ We also give several variations around these results. public section -open scoped NNReal Topology +open scoped NNReal Topology ENNReal open Set MeasureTheory Filter variable {V : Type*} [NormedAddCommGroup V] [NormedSpace ℝ V] [FiniteDimensional ℝ V] +section + +open Finset + +variable {α : Type*} [LinearOrder α] {E F G : Type*} + [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + [NormedAddCommGroup G] [NormedSpace ℝ G] + {s : Set α} {f : α → E} {g : α → F} {C D : ℝ≥0∞} {B : E →L[ℝ] F →L[ℝ] G} + +lemma eVariationOn_bilinear_comp_le (hf : ∀ x ∈ s, ‖f x‖ₑ ≤ C) (hg : ∀ x ∈ s, ‖g x‖ₑ ≤ D) + (B : E →L[ℝ] F →L[ℝ] G) : + eVariationOn (fun x ↦ B (f x) (g x) : α → G) s ≤ + ‖B‖ₑ * (C * eVariationOn g s + D * eVariationOn f s) := by + apply iSup_le + rintro ⟨n, ⟨u, u_mono, u_mem⟩⟩ + calc ∑ i ∈ range n, edist (B (f (u (i + 1))) (g (u (i + 1)))) (B (f (u i)) (g (u i))) + _ ≤ ∑ i ∈ range n, edist (B (f (u (i + 1))) (g (u (i + 1)))) (B (f (u i)) (g (u (i + 1)))) + + ∑ i ∈ range n, edist (B (f (u i)) (g (u (i + 1)))) (B (f (u i)) (g (u i))) := by + rw [← Finset.sum_add_distrib] + gcongr with i hi + apply edist_triangle + _ = ∑ i ∈ range n, ‖B (f (u (i + 1)) - f (u i)) (g (u (i + 1)))‖ₑ + + ∑ i ∈ range n, ‖B (f (u i)) (g (u (i + 1)) - g (u i))‖ₑ := by simp [edist_eq_enorm_sub] + _ ≤ ∑ i ∈ range n, ‖B‖ₑ * ‖f (u (i + 1)) - f (u i)‖ₑ * ‖g (u (i + 1))‖ₑ + + ∑ i ∈ range n, ‖B‖ₑ * ‖f (u i)‖ₑ * ‖g (u (i + 1)) - g (u i)‖ₑ := by + gcongr with i hi i hi + · apply ContinuousLinearMap.le_opENorm₂ + · apply ContinuousLinearMap.le_opENorm₂ + _ ≤ ∑ i ∈ range n, ‖B‖ₑ * ‖f (u (i + 1)) - f (u i)‖ₑ * D + + ∑ i ∈ range n, ‖B‖ₑ * C * ‖g (u (i + 1)) - g (u i)‖ₑ := by + gcongr with i hi i hi + · apply hg _ (u_mem _) + · apply hf _ (u_mem _) + _ = ‖B‖ₑ * D * ∑ i ∈ range n, ‖f (u (i + 1)) - f (u i)‖ₑ + + ‖B‖ₑ * C * ∑ i ∈ range n, ‖g (u (i + 1)) - g (u i)‖ₑ := by + simp only [← sum_mul, ← mul_sum] + ring + _ ≤ ‖B‖ₑ * D * eVariationOn f s + ‖B‖ₑ * C * eVariationOn g s := by + simp only [← edist_eq_enorm_sub] + gcongr + · exact eVariationOn.sum_le_of_monotoneOn_Iic (u_mono.monotoneOn _) (fun i hi ↦ u_mem i) + · exact eVariationOn.sum_le_of_monotoneOn_Iic (u_mono.monotoneOn _) (fun i hi ↦ u_mem i) + _ = ‖B‖ₑ * (C * eVariationOn g s + D * eVariationOn f s) := by ring + +@[to_fun eVariationOn_fun_smul_le] +lemma eVariationOn_smul_le {𝕜 : Type*} {f : α → 𝕜} {g : α → F} + [NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] + [NormSMulClass 𝕜 F] [IsScalarTower ℝ 𝕜 F] + {C D : ℝ≥0∞} {s : Set α} (hf : ∀ x ∈ s, ‖f x‖ₑ ≤ C) (hg : ∀ x ∈ s, ‖g x‖ₑ ≤ D) : + eVariationOn (f • g) s ≤ C * eVariationOn g s + D * eVariationOn f s := by + apply (eVariationOn_bilinear_comp_le hf hg (B := ContinuousLinearMap.lsmul ℝ 𝕜)).trans + grw [ContinuousLinearMap.opENorm_lsmul_le, one_mul] + +@[to_fun eVariationOn_fun_mul_le] +lemma eVariation_mul_le {f g : α → ℝ} + {C D : ℝ≥0∞} {s : Set α} (hf : ∀ x ∈ s, ‖f x‖ₑ ≤ C) (hg : ∀ x ∈ s, ‖g x‖ₑ ≤ D) : + eVariationOn (f * g) s ≤ C * eVariationOn g s + D * eVariationOn f s := by + simpa using eVariationOn_smul_le hf hg + +lemma BoundedVariationOn.bilinear_comp + (hf : BoundedVariationOn f s) (hg : BoundedVariationOn g s) (B : E →L[ℝ] F →L[ℝ] G) : + BoundedVariationOn (fun x ↦ B (f x) (g x)) s := by + rcases s.eq_empty_or_nonempty with rfl | ⟨⟨x, hx⟩⟩ + · simp + suffices eVariationOn (fun x ↦ (B (f x)) (g x)) s < ∞ from ne_of_lt this + have A (y) (hy : y ∈ s) : ‖f y‖ₑ ≤ ‖f x‖ₑ + eVariationOn f s := by + grw [show f y = f x + (f y - f x) by abel, enorm_add_le, ← edist_eq_enorm_sub, + eVariationOn.edist_le _ hy hx] + have A' (y) (hy : y ∈ s) : ‖g y‖ₑ ≤ ‖g x‖ₑ + eVariationOn g s := by + grw [show g y = g x + (g y - g x) by abel, enorm_add_le, ← edist_eq_enorm_sub, + eVariationOn.edist_le _ hy hx] + grw [eVariationOn_bilinear_comp_le A A'] + simp [mul_add, ENNReal.mul_lt_top_iff, hf.lt_top, hg.lt_top] + +@[to_fun] +lemma BoundedVariationOn.smul {𝕜 : Type*} {f : α → 𝕜} {g : α → F} + [NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] + [NormSMulClass 𝕜 F] [IsScalarTower ℝ 𝕜 F] + {s : Set α} (hf : BoundedVariationOn f s) (hg : BoundedVariationOn g s) : + BoundedVariationOn (f • g) s := + hf.bilinear_comp hg (B := ContinuousLinearMap.lsmul ℝ 𝕜) + +@[to_fun] +lemma BoundedVariationOn.mul {f g : α → ℝ} {s : Set α} + (hf : BoundedVariationOn f s) (hg : BoundedVariationOn g s) : + BoundedVariationOn (f * g) s := + hf.bilinear_comp hg (B := ContinuousLinearMap.lsmul ℝ ℝ) + +lemma LocallyBoundedVariationOn.bilinear_comp (hf : LocallyBoundedVariationOn f s) + (hg : LocallyBoundedVariationOn g s) (B : E →L[ℝ] F →L[ℝ] G) : + LocallyBoundedVariationOn (fun x ↦ B (f x) (g x)) s := + fun a b ha hb ↦ (hf a b ha hb).bilinear_comp (hg a b ha hb) B + +@[to_fun] +lemma LocallyBoundedVariationOn.smul {𝕜 : Type*} {f : α → 𝕜} {g : α → F} + [NormedRing 𝕜] [NormedAlgebra ℝ 𝕜] [Module 𝕜 F] + [NormSMulClass 𝕜 F] [IsScalarTower ℝ 𝕜 F] + {s : Set α} (hf : LocallyBoundedVariationOn f s) (hg : LocallyBoundedVariationOn g s) : + LocallyBoundedVariationOn (f • g) s := + hf.bilinear_comp hg (B := ContinuousLinearMap.lsmul ℝ 𝕜) + +@[to_fun] +lemma LocallyBoundedVariationOn.mul {f g : α → ℝ} {s : Set α} + (hf : LocallyBoundedVariationOn f s) (hg : LocallyBoundedVariationOn g s) : + LocallyBoundedVariationOn (f * g) s := + hf.bilinear_comp hg (B := ContinuousLinearMap.lsmul ℝ ℝ) + +end + namespace LocallyBoundedVariationOn /-- A bounded variation function into `ℝ` is differentiable almost everywhere. Superseded by diff --git a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean index 20e89be5466d28..6bb4b5c2385ba4 100644 --- a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean +++ b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean @@ -219,6 +219,11 @@ protected theorem subsingleton (f : α → E) {s : Set α} (hs : s.Subsingleton) eVariationOn f s = 0 := constant_on (hs.image f) +@[simp] +theorem _root_.BoundedVariationOn.of_subsingleton {f : α → E} {s : Set α} (hs : s.Subsingleton) : + BoundedVariationOn f s := by + simp [BoundedVariationOn, hs] + theorem lowerSemicontinuous_aux {ι : Type*} {F : ι → α → E} {p : Filter ι} {f : α → E} {s : Set α} (Ffs : ∀ x ∈ s, Tendsto (fun i => F i x) p (𝓝 (f x))) {v : ℝ≥0∞} (hv : v < eVariationOn f s) : ∀ᶠ n : ι in p, v < eVariationOn (F n) s := by From 383070160f86da967c9c899ca1bdf97f2938d618 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:49:56 +0000 Subject: [PATCH 0787/1300] feat(NumberTheory/NumberField/Completion/Ramification): add `InfinitePlace.mult_mul_finrank` (#41600) This PR proves that if `w` lies over `v`, then `v.mult * Module.finrank v.Completion w.Completion = w.mult`. Co-authored-by: tb65536 --- .../NumberField/Completion/Ramification.lean | 24 ++++++++++++++----- .../NumberField/InfinitePlace/Basic.lean | 14 +++++++---- .../InfinitePlace/Ramification.lean | 3 +++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean index e2b367b8760508..7a7a1aa8817508 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean @@ -42,10 +42,10 @@ open scoped NumberField.LiesOver variable {K L : Type*} [Field K] [Field L] [Algebra K L] (v : InfinitePlace K) {w : InfinitePlace L} -namespace Completion +open Completion /-- If `w` is a ramified place over `v` then `w.Completion` has `v.Completion` dimension two. -/ -theorem finrank_eq_two_of_isRamified [w.1.LiesOver v.1] (h : w.IsRamified K) : +theorem IsRamified.finrank_eq_two [w.1.LiesOver v.1] (h : w.IsRamified K) : Module.finrank v.Completion w.Completion = 2 := by have H := NumberField.InfinitePlace.isRamified_iff.mp h rw [NumberField.InfinitePlace.LiesOver.comap_eq w v] at H @@ -55,7 +55,7 @@ theorem finrank_eq_two_of_isRamified [w.1.LiesOver v.1] (h : w.IsRamified K) : Complex.finrank_real_complex] /-- If `w` is an unramified place over `v` then `w.Completion` has `v.Completion` dimension one. -/ -theorem finrank_eq_one_of_isUnramified [w.1.LiesOver v.1] (h : w.IsUnramified K) : +theorem IsUnramified.finrank_eq_one [w.1.LiesOver v.1] (h : w.IsUnramified K) : Module.finrank v.Completion w.Completion = 1 := by rcases v.isReal_or_isComplex with (hv | hv) · have := LiesOver.extensionEmbedding_liesOver_of_isReal w hv @@ -77,7 +77,19 @@ theorem finrank_eq_one_of_isUnramified [w.1.LiesOver v.1] (h : w.IsUnramified K) (starRingAut (R := ℂ))) (by ext; simp [← conjugate_coe_eq]), Module.finrank_self] -end Completion +@[deprecated (since := "2026-07-10")] alias Completion.finrank_eq_two_of_isRamified := + IsRamified.finrank_eq_two + +@[deprecated (since := "2026-07-10")] alias Completion.finrank_eq_one_of_isUnramified := + IsUnramified.finrank_eq_one + +variable (w) in +theorem mult_mul_finrank [w.1.LiesOver v.1] : + v.mult * Module.finrank v.Completion w.Completion = w.mult := by + have hv : v = w.comap (algebraMap K L) := Subtype.ext ‹w.1.LiesOver v.1›.comp_eq.symm + rcases w.isUnramified_or_isRamified K with h | h + · rw [h.finrank_eq_one v, hv, h.eq, mul_one] + · rw [h.finrank_eq_two v, hv, h.isReal.mult_eq_one, h.isComplex.mult_eq_two, one_mul] open Completion @@ -100,11 +112,11 @@ theorem inertiaDeg_eq_finrank [w.1.LiesOver v.1] : variable {v w} in theorem inertiaDeg_eq_one (hw : w ∈ unramifiedPlacesOver L v) : v.inertiaDeg w = 1 := - have := (Set.mem_setOf.1 hw).1; finrank_eq_one_of_isUnramified v hw.2 ▸ inertiaDeg_eq_finrank v w + have := (Set.mem_setOf.1 hw).1; hw.2.finrank_eq_one v ▸ inertiaDeg_eq_finrank v w variable {v w} in theorem inertiaDeg_eq_two (hw : w ∈ ramifiedPlacesOver L v) : v.inertiaDeg w = 2 := - have := (Set.mem_setOf.1 hw).1; finrank_eq_two_of_isRamified v hw.2 ▸ inertiaDeg_eq_finrank v w + have := (Set.mem_setOf.1 hw).1; hw.2.finrank_eq_two v ▸ inertiaDeg_eq_finrank v w variable (K L) in open scoped Classical in diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index 5baa65ba634bb0..c4b3e62bd0113d 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -267,15 +267,21 @@ open scoped Classical in define it, see `card_filter_mk_eq`. -/ noncomputable def mult (w : InfinitePlace K) : ℕ := if (IsReal w) then 1 else 2 +theorem IsReal.mult_eq_one {w : InfinitePlace K} (hw : IsReal w) : mult w = 1 := + if_pos hw + +theorem IsComplex.mult_eq_two {w : InfinitePlace K} (hw : IsComplex w) : mult w = 2 := + if_neg (not_isReal_iff_isComplex.mpr hw) + @[simp] theorem mult_isReal (w : {w : InfinitePlace K // IsReal w}) : - mult w.1 = 1 := by - rw [mult, if_pos w.prop] + mult w.1 = 1 := + w.2.mult_eq_one @[simp] theorem mult_isComplex (w : {w : InfinitePlace K // IsComplex w}) : - mult w.1 = 2 := by - rw [mult, if_neg (not_isReal_iff_isComplex.mpr w.prop)] + mult w.1 = 2 := + w.2.mult_eq_two theorem mult_pos {w : InfinitePlace K} : 0 < mult w := by rw [mult] diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean index 521e28ad4eb9e7..5574e2aef5f7e5 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean @@ -188,6 +188,9 @@ An infinite place is ramified in a field extension if it is not unramified. -/ abbrev IsRamified : Prop := ¬w.IsUnramified k +lemma isUnramified_or_isRamified : w.IsUnramified k ∨ w.IsRamified k := + or_not + variable {k} lemma isUnramified_self : IsUnramified K w := rfl From 85b471ce5a26910a597e61505014715aed7cde1e Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Tue, 14 Jul 2026 18:00:21 +0000 Subject: [PATCH 0788/1300] chore: replace `haveI`/`letI` with `have`/`let` in tactics when the goal is a prop (#41708) Using `haveI`/`letI` for instances in proofs is a holdover from Lean 3, and is unnecessary in Lean 4. As explained by @Vierkantor on Zulip [here](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/letI.2FhaveI.20linter/near/609781158): > Historical note: a lot of the `haveI`/`letI` usage is a remnant of Lean 3 times, where the `I` stood for Instances: the old versions of the `have`/`let` tactics would not add the new variable to the list of available instances, and you'd need `haveI`/`letI` to force an update to the instance cache and make them visible. In our modern Lean 4 age, basic `have`/`let` already make the instance available and `I` instead only stands for Inline. But the old `haveI` got ported to the new `haveI` and so there is a bit of a superstition that we have to keep using `haveI` and `letI` for instances. (Note that inlining can change IR for compiled defs, so we don't change those.) Try-this statements produced by #41657; applied mechanically by running `scripts/runSkimmer.sh`. Then, Mathlib.CategoryTheory.Galois.Basic was fixed up manually: it turned out that the `haveI`'s triggering the linter were completely unnecessary, which might be why universe issues came about when the linter suggested turning them into `have`s. Cleaning up term-mode `haveI`/`letI` is left for another PR. Co-authored-by: @JovanGerb --- Mathlib/Algebra/Algebra/Operations.lean | 2 +- .../Algebra/Subalgebra/IsSimpleOrder.lean | 4 +- Mathlib/Algebra/Algebra/Subalgebra/Rank.lean | 8 +-- Mathlib/Algebra/AlgebraicCard.lean | 2 +- Mathlib/Algebra/BigOperators/Associated.lean | 2 +- Mathlib/Algebra/BigOperators/Finprod.lean | 6 +- .../BigOperators/Group/Finset/Basic.lean | 4 +- Mathlib/Algebra/Category/Grp/Images.lean | 4 +- .../Category/ModuleCat/ChangeOfRings.lean | 14 ++--- .../ModuleCat/Differentials/Basic.lean | 4 +- Mathlib/Algebra/Category/ModuleCat/Free.lean | 2 +- .../Algebra/Category/ModuleCat/Kernels.lean | 2 +- .../ModuleCat/Monoidal/Adjunction.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/Stalk.lean | 2 +- Mathlib/Algebra/Category/Ring/Epi.lean | 2 +- .../Category/Ring/FinitePresentation.lean | 2 +- .../Algebra/Category/Ring/LinearAlgebra.lean | 2 +- Mathlib/Algebra/Central/Basic.lean | 2 +- Mathlib/Algebra/CharP/Algebra.lean | 8 +-- Mathlib/Algebra/CharP/Defs.lean | 4 +- Mathlib/Algebra/CharP/Invertible.lean | 2 +- Mathlib/Algebra/CharP/Lemmas.lean | 2 +- Mathlib/Algebra/CharP/LocalRing.lean | 8 +-- Mathlib/Algebra/CharP/MixedCharZero.lean | 4 +- Mathlib/Algebra/CharP/Quotient.lean | 2 +- Mathlib/Algebra/DirectSum/Decomposition.lean | 2 +- Mathlib/Algebra/DualNumber.lean | 2 +- Mathlib/Algebra/EuclideanDomain/Basic.lean | 2 +- Mathlib/Algebra/Exact/Basic.lean | 2 +- Mathlib/Algebra/Exact/Sequence.lean | 8 +-- Mathlib/Algebra/Field/Subfield/Basic.lean | 2 +- Mathlib/Algebra/Group/Subgroup/Finite.lean | 2 +- Mathlib/Algebra/Group/Subgroup/Lattice.lean | 2 +- .../Algebra/Group/Submonoid/Membership.lean | 2 +- Mathlib/Algebra/Group/TransferInstance.lean | 8 +-- Mathlib/Algebra/Homology/Additive.lean | 4 +- .../Homology/DerivedCategory/Ext/Basic.lean | 32 +++++------ .../DerivedCategory/Ext/EnoughInjectives.lean | 4 +- .../Ext/EnoughProjectives.lean | 4 +- .../DerivedCategory/Ext/ExactSequences.lean | 12 ++-- .../DerivedCategory/Ext/ExtClass.lean | 6 +- .../DerivedCategory/Ext/TStructure.lean | 2 +- .../Homology/DerivedCategory/KInjective.lean | 2 +- .../Homology/DerivedCategory/KProjective.lean | 2 +- .../DerivedCategory/SmallShiftedHom.lean | 2 +- Mathlib/Algebra/Homology/HomotopyCofiber.lean | 10 ++-- Mathlib/Algebra/Homology/ImageToKernel.lean | 2 +- .../Algebra/Homology/ShortComplex/Exact.lean | 18 +++--- .../Homology/ShortComplex/Homology.lean | 2 +- .../Homology/ShortComplex/LeftHomology.lean | 2 +- .../Homology/ShortComplex/QuasiIso.lean | 4 +- .../Homology/ShortComplex/RightHomology.lean | 4 +- Mathlib/Algebra/Lie/Engel.lean | 8 +-- Mathlib/Algebra/Lie/Extension.lean | 2 +- Mathlib/Algebra/Lie/Loop.lean | 2 +- Mathlib/Algebra/Module/PID.lean | 4 +- Mathlib/Algebra/Module/SnakeLemma.lean | 6 +- Mathlib/Algebra/Module/SpanRank.lean | 2 +- Mathlib/Algebra/Module/Submodule/Lattice.lean | 2 +- Mathlib/Algebra/Module/Torsion/Basic.lean | 2 +- Mathlib/Algebra/Module/TransferInstance.lean | 2 +- Mathlib/Algebra/Module/ZLattice/Basic.lean | 2 +- Mathlib/Algebra/Notation/Indicator.lean | 2 +- .../Algebra/Order/Group/Unbundled/Abs.lean | 2 +- .../Algebra/Order/Monoid/Unbundled/Basic.lean | 8 +-- .../Algebra/Polynomial/Degree/Operations.lean | 2 +- Mathlib/Algebra/Polynomial/Div.lean | 20 +++---- Mathlib/Algebra/Polynomial/Expand.lean | 2 +- Mathlib/Algebra/Polynomial/Inductions.lean | 2 +- Mathlib/Algebra/Polynomial/Module/Basic.lean | 2 +- Mathlib/Algebra/Ring/Subring/Basic.lean | 2 +- Mathlib/Algebra/Ring/Subsemiring/Basic.lean | 2 +- Mathlib/Algebra/Squarefree/Basic.lean | 2 +- Mathlib/Algebra/TrivSqZeroExt/Basic.lean | 6 +- Mathlib/AlgebraicGeometry/AffineScheme.lean | 18 +++--- .../AffineTransitionLimit.lean | 6 +- Mathlib/AlgebraicGeometry/ColimitsOver.lean | 2 +- .../EllipticCurve/IsomOfJ.lean | 18 +++--- .../EllipticCurve/NormalForms.lean | 14 ++--- Mathlib/AlgebraicGeometry/FunctionField.lean | 2 +- .../AlgebraicGeometry/IdealSheaf/Basic.lean | 2 +- .../IdealSheaf/Subscheme.lean | 8 +-- Mathlib/AlgebraicGeometry/Limits.lean | 8 +-- Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 10 ++-- .../AlgebraicGeometry/Morphisms/Affine.lean | 6 +- .../Morphisms/AffineAnd.lean | 6 +- .../AlgebraicGeometry/Morphisms/Basic.lean | 16 +++--- .../Morphisms/ClosedImmersion.lean | 4 +- .../Morphisms/Constructors.lean | 12 ++-- .../AlgebraicGeometry/Morphisms/Finite.lean | 4 +- .../Morphisms/FormallyUnramified.lean | 2 +- .../Morphisms/OpenImmersion.lean | 2 +- .../AlgebraicGeometry/Morphisms/Proper.lean | 4 +- .../Morphisms/QuasiCompact.lean | 6 +- .../Morphisms/QuasiSeparated.lean | 4 +- .../Morphisms/RingHomProperties.lean | 20 +++---- .../Morphisms/Separated.lean | 2 +- .../AlgebraicGeometry/Morphisms/Smooth.lean | 4 +- Mathlib/AlgebraicGeometry/Normalization.lean | 10 ++-- .../ProjectiveSpectrum/Basic.lean | 4 +- .../ProjectiveSpectrum/Proper.lean | 2 +- .../ProjectiveSpectrum/Scheme.lean | 8 +-- Mathlib/AlgebraicGeometry/Properties.lean | 14 ++--- Mathlib/AlgebraicGeometry/Pullbacks.lean | 2 +- Mathlib/AlgebraicGeometry/Sites/Etale.lean | 2 +- .../Sites/MorphismProperty.lean | 2 +- Mathlib/AlgebraicGeometry/Sites/Small.lean | 6 +- Mathlib/AlgebraicGeometry/SpreadingOut.lean | 8 +-- Mathlib/AlgebraicGeometry/Stalk.lean | 2 +- Mathlib/AlgebraicGeometry/StructureSheaf.lean | 12 ++-- .../AlgebraicGeometry/ValuativeCriterion.lean | 6 +- .../DoldKan/NReflectsIso.lean | 2 +- .../SimplexCategory/Basic.lean | 12 ++-- .../SimplicialSet/HomotopyCat.lean | 2 +- .../Analysis/BoxIntegral/Integrability.lean | 6 +- .../Instances.lean | 2 +- .../Calculus/ContDiff/Convolution.lean | 2 +- .../ApproximatesLinearOn.lean | 2 +- .../FiniteDimensional.lean | 2 +- .../Calculus/LagrangeMultipliers.lean | 2 +- Mathlib/Analysis/Calculus/LogDeriv.lean | 2 +- Mathlib/Analysis/Calculus/MeanValue.lean | 14 ++--- .../Analysis/Calculus/ParametricIntegral.lean | 2 +- Mathlib/Analysis/Calculus/SmoothSeries.lean | 6 +- .../Analysis/Calculus/UniformLimitsDeriv.lean | 10 ++-- .../Analysis/Complex/Polynomial/Basic.lean | 2 +- .../Complex/UpperHalfPlane/Metric.lean | 4 +- Mathlib/Analysis/ConstantSpeed.lean | 2 +- .../Analysis/Convex/Cone/TensorProduct.lean | 2 +- Mathlib/Analysis/Convex/EGauge.lean | 2 +- Mathlib/Analysis/Convex/Extreme.lean | 2 +- Mathlib/Analysis/Convex/Integral.lean | 6 +- Mathlib/Analysis/Convex/Intrinsic.lean | 8 +-- Mathlib/Analysis/Convex/KreinMilman.lean | 2 +- Mathlib/Analysis/Convex/MetricSpace.lean | 2 +- Mathlib/Analysis/Convex/Side.lean | 8 +-- Mathlib/Analysis/Convex/StdSimplex.lean | 2 +- .../Distribution/AEEqOfIntegralContDiff.lean | 2 +- .../Distribution/TemperedDistribution.lean | 2 +- Mathlib/Analysis/Fourier/AddCircle.lean | 6 +- Mathlib/Analysis/Hofer.lean | 2 +- .../Analysis/InnerProductSpace/Adjoint.lean | 16 +++--- Mathlib/Analysis/InnerProductSpace/Basic.lean | 6 +- Mathlib/Analysis/InnerProductSpace/Defs.lean | 4 +- .../InnerProductSpace/LaxMilgram.lean | 2 +- .../InnerProductSpace/Orientation.lean | 8 +-- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 4 +- .../InnerProductSpace/Projection/Basic.lean | 2 +- .../Projection/FiniteDimensional.lean | 12 ++-- .../InnerProductSpace/Projection/Minimal.lean | 8 +-- .../Analysis/InnerProductSpace/Rayleigh.lean | 6 +- .../Analysis/InnerProductSpace/Spectrum.lean | 2 +- .../Analysis/InnerProductSpace/l2Space.lean | 2 +- Mathlib/Analysis/LocallyConvex/Bounded.lean | 4 +- .../Analysis/LocallyConvex/HahnBanach.lean | 8 +-- Mathlib/Analysis/LocallyConvex/WeakDual.lean | 8 +-- Mathlib/Analysis/Matrix/LDL.lean | 4 +- .../Normed/Affine/AddTorsorBases.lean | 4 +- Mathlib/Analysis/Normed/Affine/MazurUlam.lean | 2 +- .../Analysis/Normed/Algebra/Exponential.lean | 2 +- .../Normed/Algebra/QuaternionExponential.lean | 2 +- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 2 +- Mathlib/Analysis/Normed/Field/Dense.lean | 4 +- Mathlib/Analysis/Normed/Group/Uniform.lean | 2 +- Mathlib/Analysis/Normed/Lp/PiLp.lean | 6 +- Mathlib/Analysis/Normed/Lp/ProdLp.lean | 4 +- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 8 +-- Mathlib/Analysis/Normed/Module/Basic.lean | 10 ++-- .../Analysis/Normed/Module/Complemented.lean | 2 +- Mathlib/Analysis/Normed/Module/Dual.lean | 2 +- .../Normed/Module/FiniteDimension.lean | 6 +- .../Normed/Module/Multilinear/Basic.lean | 2 +- .../Module/MultipliableUniformlyOn.lean | 4 +- .../PiTensorProduct/InjectiveSeminorm.lean | 4 +- Mathlib/Analysis/Normed/Operator/Banach.lean | 4 +- .../Analysis/Normed/Operator/NormedSpace.lean | 2 +- Mathlib/Analysis/Normed/Order/UpperLower.lean | 2 +- .../Normed/Unbundled/FiniteExtension.lean | 4 +- .../Normed/Unbundled/SpectralNorm.lean | 14 ++--- Mathlib/Analysis/RCLike/TangentCone.lean | 4 +- Mathlib/Analysis/Seminorm.lean | 12 ++-- .../Analysis/SpecialFunctions/Bernstein.lean | 2 +- .../Gaussian/FourierTransform.lean | 2 +- .../SpecialFunctions/Pow/Integral.lean | 2 +- .../Trigonometric/Complex.lean | 2 +- Mathlib/Analysis/SpecificLimits/Basic.lean | 2 +- Mathlib/CategoryTheory/Abelian/Basic.lean | 8 +-- .../Abelian/GrothendieckAxioms/Basic.lean | 12 ++-- .../GrothendieckCategory/Subobject.lean | 2 +- .../Abelian/Injective/Basic.lean | 2 +- .../Abelian/Injective/Dimension.lean | 22 ++++---- .../Abelian/NonPreadditive.lean | 12 ++-- .../Abelian/Projective/Basic.lean | 2 +- .../Abelian/Projective/Dimension.lean | 22 ++++---- .../Abelian/Pseudoelements.lean | 4 +- .../Abelian/SerreClass/Localization.lean | 10 ++-- Mathlib/CategoryTheory/Abelian/Transfer.lean | 4 +- Mathlib/CategoryTheory/Adhesive/Basic.lean | 4 +- .../CategoryTheory/Adjunction/Reflective.lean | 8 +-- .../CategoryTheory/Category/Cat/Limit.lean | 4 +- Mathlib/CategoryTheory/CofilteredSystem.lean | 18 +++--- Mathlib/CategoryTheory/Comma/Final.lean | 4 +- .../ConcreteCategory/ReflectsIso.lean | 4 +- Mathlib/CategoryTheory/Extensive.lean | 4 +- .../FiberedCategory/Cartesian.lean | 2 +- .../Filtered/CostructuredArrow.lean | 4 +- Mathlib/CategoryTheory/Filtered/Final.lean | 8 +-- Mathlib/CategoryTheory/Functor/Flat.lean | 8 +-- .../Functor/KanExtension/Basic.lean | 4 +- .../Functor/ReflectsIso/Balanced.lean | 4 +- .../Functor/ReflectsIso/Basic.lean | 2 +- Mathlib/CategoryTheory/Galois/Basic.lean | 20 +++---- .../CategoryTheory/Galois/Equivalence.lean | 2 +- Mathlib/CategoryTheory/Galois/EssSurj.lean | 8 +-- Mathlib/CategoryTheory/Galois/Examples.lean | 6 +- .../Galois/Prorepresentability.lean | 2 +- Mathlib/CategoryTheory/Galois/Topology.lean | 4 +- Mathlib/CategoryTheory/Generator/Abelian.lean | 4 +- Mathlib/CategoryTheory/Generator/Basic.lean | 12 ++-- Mathlib/CategoryTheory/Groupoid/Basic.lean | 2 +- .../GuitartExact/VerticalComposition.lean | 4 +- Mathlib/CategoryTheory/Idempotents/Basic.lean | 6 +- .../Idempotents/FunctorCategories.lean | 2 +- Mathlib/CategoryTheory/Limits/Comma.lean | 16 +++--- Mathlib/CategoryTheory/Limits/Cones.lean | 4 +- .../FiniteProductsOfBinaryProducts.lean | 12 ++-- .../LimitsOfProductsAndEqualizers.lean | 6 +- .../Limits/Constructions/WeaklyInitial.lean | 4 +- Mathlib/CategoryTheory/Limits/Final.lean | 10 ++-- Mathlib/CategoryTheory/Limits/HasLimits.lean | 16 +++--- .../CategoryTheory/Limits/IsConnected.lean | 4 +- Mathlib/CategoryTheory/Limits/Lattice.lean | 4 +- Mathlib/CategoryTheory/Limits/MonoCoprod.lean | 4 +- .../Limits/MorphismProperty.lean | 4 +- .../Limits/Preserves/Bifunctor.lean | 4 +- .../Limits/Preserves/Filtered.lean | 8 +-- .../Limits/Preserves/Finite.lean | 14 ++--- .../Limits/Preserves/Grothendieck.lean | 2 +- .../Limits/Preserves/Shapes/Biproducts.lean | 2 +- .../Limits/Preserves/Shapes/Equalizers.lean | 2 +- .../Limits/Preserves/Shapes/Terminal.lean | 4 +- .../Limits/Shapes/Biproducts.lean | 2 +- .../Limits/Shapes/Equalizers.lean | 4 +- .../Limits/Shapes/FiniteLimits.lean | 8 +-- .../Limits/Shapes/FiniteProducts.lean | 4 +- .../CategoryTheory/Limits/Shapes/Images.lean | 4 +- .../Limits/Shapes/IsTerminal.lean | 4 +- .../Limits/Shapes/NormalMono/Basic.lean | 4 +- .../Limits/Shapes/Opposites/Products.lean | 2 +- .../Limits/Shapes/Opposites/Pullbacks.lean | 4 +- .../Limits/Shapes/Reflexive.lean | 4 +- .../Limits/Shapes/RegularMono.lean | 4 +- .../Limits/Shapes/StrictInitial.lean | 10 ++-- Mathlib/CategoryTheory/Limits/Sifted.lean | 4 +- Mathlib/CategoryTheory/Limits/VanKampen.lean | 12 ++-- .../Localization/Adjunction.lean | 4 +- .../Localization/CalculusOfFractions.lean | 12 ++-- .../Localization/Construction.lean | 2 +- .../OfLocalizedEquivalences.lean | 4 +- .../Localization/Equivalence.lean | 2 +- .../CategoryTheory/Localization/HomEquiv.lean | 2 +- .../CategoryTheory/Localization/Linear.lean | 2 +- .../Localization/LocalizerMorphism.lean | 8 +-- .../Localization/Monoidal/Functor.lean | 2 +- Mathlib/CategoryTheory/Localization/Pi.lean | 6 +- .../Localization/Predicate.lean | 4 +- Mathlib/CategoryTheory/Localization/Prod.lean | 6 +- .../Localization/Resolution.lean | 8 +-- .../CategoryTheory/Localization/SmallHom.lean | 4 +- .../CategoryTheory/Monad/Comonadicity.lean | 2 +- Mathlib/CategoryTheory/Monad/Limits.lean | 16 +++--- Mathlib/CategoryTheory/Monad/Monadicity.lean | 2 +- .../Monoidal/Action/Opposites.lean | 8 +-- .../Monoidal/Cartesian/Basic.lean | 4 +- .../Monoidal/Cartesian/CommMon_.lean | 2 +- .../Monoidal/Cartesian/FunctorCategory.lean | 2 +- .../Monoidal/Cartesian/Grp.lean | 2 +- .../Monoidal/Cartesian/Mon.lean | 2 +- .../Monoidal/Closed/Cartesian.lean | 8 +-- .../CategoryTheory/Monoidal/Closed/Ideal.lean | 4 +- .../Monoidal/DayConvolution.lean | 14 ++--- .../Monoidal/DayConvolution/Braided.lean | 4 +- .../ExternalProduct/KanExtension.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Functor.lean | 6 +- Mathlib/CategoryTheory/Monoidal/Mon.lean | 2 +- .../Monoidal/NaturalTransformation.lean | 2 +- .../MorphismProperty/IsInvertedBy.lean | 10 ++-- .../MorphismProperty/Limits.lean | 4 +- .../TransfiniteComposition.lean | 2 +- .../ObjectProperty/FiniteProducts.lean | 4 +- .../ObjectProperty/Kernels.lean | 4 +- Mathlib/CategoryTheory/PUnit.lean | 2 +- .../Preadditive/Biproducts.lean | 26 ++++----- .../Preadditive/Injective/Basic.lean | 4 +- .../CategoryTheory/Preadditive/LeftExact.lean | 20 +++---- .../Preadditive/Projective/Basic.lean | 2 +- Mathlib/CategoryTheory/Preadditive/Schur.lean | 4 +- .../Presentable/CardinalDirectedPoset.lean | 4 +- .../Presentable/SharplyLT/Basic.lean | 4 +- Mathlib/CategoryTheory/Quotient/Linear.lean | 2 +- Mathlib/CategoryTheory/Shift/Adjunction.lean | 8 +-- Mathlib/CategoryTheory/Shift/CommShift.lean | 6 +- .../CategoryTheory/Shift/Localization.lean | 4 +- Mathlib/CategoryTheory/Simple.lean | 6 +- .../Sites/ConcreteSheafification.lean | 2 +- .../Sites/EqualizerSheafCondition.lean | 2 +- Mathlib/CategoryTheory/Sites/Equivalence.lean | 2 +- Mathlib/CategoryTheory/Sites/IsSheafFor.lean | 4 +- Mathlib/CategoryTheory/Sites/LeftExact.lean | 4 +- Mathlib/CategoryTheory/Sites/Point/Basic.lean | 2 +- Mathlib/CategoryTheory/Sites/Sheaf.lean | 2 +- .../IsCardinalForSmallObjectArgument.lean | 20 +++---- .../CategoryTheory/Subobject/MonoOver.lean | 2 +- .../Triangulated/LocalizingSubcategory.lean | 6 +- .../Additive/ErdosGinzburgZiv.lean | 4 +- .../Combinatorics/Additive/RuzsaCovering.lean | 2 +- Mathlib/Combinatorics/Configuration.lean | 6 +- .../Enumerative/IncidenceAlgebra.lean | 4 +- .../Extremal/RuzsaSzemeredi.lean | 6 +- Mathlib/Combinatorics/Hall/Basic.lean | 6 +- Mathlib/Combinatorics/Hall/Finite.lean | 10 ++-- Mathlib/Combinatorics/Nullstellensatz.lean | 4 +- .../Combinatorics/SimpleGraph/DegreeSum.lean | 4 +- .../SimpleGraph/Finsubgraph.lean | 4 +- .../Combinatorics/SimpleGraph/Matching.lean | 6 +- .../Combinatorics/SimpleGraph/Operations.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Prod.lean | 14 ++--- .../SimpleGraph/StronglyRegular.lean | 2 +- .../SimpleGraph/UniversalVerts.lean | 2 +- Mathlib/Computability/Primrec/Basic.lean | 8 +-- Mathlib/Computability/Primrec/List.lean | 4 +- .../TuringMachine/PostTuringMachine.lean | 2 +- .../Condensed/Discrete/Characterization.lean | 8 +-- .../Condensed/Discrete/LocallyConstant.lean | 2 +- Mathlib/Data/Analysis/Topology.lean | 2 +- Mathlib/Data/DFinsupp/Defs.lean | 2 +- Mathlib/Data/DFinsupp/FiniteInfinite.lean | 2 +- Mathlib/Data/DFinsupp/WellFounded.lean | 8 +-- Mathlib/Data/ENNReal/Operations.lean | 2 +- Mathlib/Data/ENat/Lattice.lean | 2 +- .../Data/Fin/Tuple/BubbleSortInduction.lean | 2 +- Mathlib/Data/Finite/Prod.lean | 10 ++-- Mathlib/Data/Finite/Sigma.lean | 4 +- Mathlib/Data/Finite/Sum.lean | 4 +- Mathlib/Data/Finite/Vector.lean | 4 +- Mathlib/Data/Finset/Fold.lean | 2 +- Mathlib/Data/Finset/Image.lean | 2 +- Mathlib/Data/Finset/Lattice/Fold.lean | 6 +- Mathlib/Data/Finset/Preimage.lean | 2 +- Mathlib/Data/Finset/Slice.lean | 2 +- Mathlib/Data/Finset/Sort.lean | 2 +- Mathlib/Data/Fintype/CardEmbedding.lean | 2 +- Mathlib/Data/Fintype/EquivFin.lean | 2 +- Mathlib/Data/Fintype/Pi.lean | 2 +- Mathlib/Data/Fintype/Prod.lean | 2 +- Mathlib/Data/Holor.lean | 2 +- Mathlib/Data/Int/ModEq.lean | 2 +- Mathlib/Data/List/AList.lean | 2 +- Mathlib/Data/List/OffDiag.lean | 4 +- Mathlib/Data/Multiset/Powerset.lean | 4 +- Mathlib/Data/Multiset/ZeroCons.lean | 2 +- Mathlib/Data/Nat/Cast/Defs.lean | 2 +- Mathlib/Data/Nat/Choose/Lucas.lean | 4 +- Mathlib/Data/Nat/Choose/Multinomial.lean | 2 +- Mathlib/Data/Nat/Nth.lean | 2 +- Mathlib/Data/Nat/Totient.lean | 12 ++-- Mathlib/Data/PFunctor/Univariate/M.lean | 2 +- Mathlib/Data/Prod/Basic.lean | 4 +- Mathlib/Data/Seq/Computation.lean | 4 +- Mathlib/Data/Seq/Parallel.lean | 4 +- Mathlib/Data/Set/Card.lean | 4 +- Mathlib/Data/Set/Countable.lean | 2 +- Mathlib/Data/Set/Finite/Basic.lean | 4 +- Mathlib/Data/Set/Finite/Lattice.lean | 12 ++-- Mathlib/Data/Set/Finite/Range.lean | 2 +- Mathlib/Data/Set/Function.lean | 2 +- Mathlib/Data/Set/Lattice.lean | 2 +- Mathlib/Data/Set/Lattice/Image.lean | 2 +- Mathlib/Data/Sym/NatCard.lean | 6 +- Mathlib/Data/ZMod/Basic.lean | 10 ++-- Mathlib/Data/ZMod/QuotientGroup.lean | 2 +- Mathlib/Data/ZMod/Units.lean | 2 +- Mathlib/Dynamics/Ergodic/Function.lean | 2 +- Mathlib/FieldTheory/AbelRuffini.lean | 6 +- Mathlib/FieldTheory/AxGrothendieck.lean | 6 +- Mathlib/FieldTheory/CardinalEmb.lean | 2 +- Mathlib/FieldTheory/Cardinality.lean | 4 +- Mathlib/FieldTheory/ChevalleyWarning.lean | 4 +- Mathlib/FieldTheory/Differential/Basic.lean | 6 +- .../FieldTheory/Differential/Liouville.lean | 2 +- Mathlib/FieldTheory/Extension.lean | 6 +- Mathlib/FieldTheory/Finite/Basic.lean | 12 ++-- Mathlib/FieldTheory/Finite/Extension.lean | 4 +- Mathlib/FieldTheory/Finite/GaloisField.lean | 14 ++--- Mathlib/FieldTheory/Finite/Trace.lean | 2 +- Mathlib/FieldTheory/Galois/Basic.lean | 2 +- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 10 ++-- Mathlib/FieldTheory/Galois/Profinite.lean | 4 +- .../IntermediateField/Adjoin/Basic.lean | 10 ++-- .../IntermediateField/Algebraic.lean | 2 +- .../FieldTheory/IntermediateField/Basic.lean | 2 +- Mathlib/FieldTheory/IsAlgClosed/Basic.lean | 4 +- .../IsAlgClosed/Classification.lean | 12 ++-- Mathlib/FieldTheory/KrullTopology.lean | 2 +- Mathlib/FieldTheory/KummerExtension.lean | 14 ++--- Mathlib/FieldTheory/LinearDisjoint.lean | 10 ++-- Mathlib/FieldTheory/Minpoly/Basic.lean | 4 +- Mathlib/FieldTheory/Normal/Basic.lean | 6 +- Mathlib/FieldTheory/Normal/Closure.lean | 2 +- Mathlib/FieldTheory/Perfect.lean | 2 +- .../FieldTheory/PolynomialGaloisGroup.lean | 10 ++-- Mathlib/FieldTheory/PrimitiveElement.lean | 10 ++-- .../FieldTheory/PurelyInseparable/Basic.lean | 22 ++++---- .../PurelyInseparable/PerfectClosure.lean | 22 ++++---- .../FieldTheory/PurelyInseparable/Tower.lean | 16 +++--- Mathlib/FieldTheory/RatFunc/Basic.lean | 2 +- .../RatFunc/IntermediateField.lean | 2 +- Mathlib/FieldTheory/Relrank.lean | 14 ++--- Mathlib/FieldTheory/Separable.lean | 8 +-- Mathlib/FieldTheory/SeparableClosure.lean | 8 +-- Mathlib/FieldTheory/SeparableDegree.lean | 24 ++++---- Mathlib/Geometry/Euclidean/Altitude.lean | 4 +- .../Geometry/Euclidean/Angle/Bisector.lean | 10 ++-- .../Euclidean/Angle/Oriented/Projection.lean | 2 +- .../Euclidean/Angle/Oriented/Rotation.lean | 4 +- Mathlib/Geometry/Euclidean/Angle/Sphere.lean | 2 +- .../Angle/Unoriented/Projection.lean | 2 +- Mathlib/Geometry/Euclidean/Circumcenter.lean | 6 +- Mathlib/Geometry/Euclidean/Incenter.lean | 6 +- Mathlib/Geometry/Euclidean/MongePoint.lean | 2 +- .../Geometry/Euclidean/NinePointCircle.lean | 2 +- Mathlib/Geometry/Euclidean/Projection.lean | 2 +- Mathlib/Geometry/Euclidean/Sphere/Basic.lean | 2 +- Mathlib/Geometry/Euclidean/Sphere/Power.lean | 2 +- Mathlib/Geometry/Manifold/ChartedSpace.lean | 12 ++-- .../Geometry/Manifold/ContMDiff/Basic.lean | 4 +- Mathlib/Geometry/Manifold/Diffeomorph.lean | 6 +- .../Geometry/Manifold/IsManifold/Basic.lean | 28 +++++----- .../Manifold/IsManifold/ExtChartAt.lean | 4 +- Mathlib/Geometry/Manifold/Metrizable.lean | 6 +- .../Geometry/Manifold/PartitionOfUnity.lean | 8 +-- .../Geometry/Manifold/Riemannian/Basic.lean | 2 +- .../Geometry/Manifold/VectorBundle/Basic.lean | 4 +- .../Geometry/Manifold/WhitneyEmbedding.lean | 6 +- .../LocallyRingedSpace/HasColimits.lean | 4 +- .../Geometry/RingedSpace/OpenImmersion.lean | 6 +- .../Geometry/RingedSpace/PresheafedSpace.lean | 4 +- Mathlib/GroupTheory/CommutingProbability.lean | 2 +- Mathlib/GroupTheory/Exponent.lean | 2 +- Mathlib/GroupTheory/FiniteAbelian/Basic.lean | 8 +-- Mathlib/GroupTheory/Finiteness.lean | 4 +- Mathlib/GroupTheory/GroupAction/Defs.lean | 4 +- .../GroupTheory/GroupAction/DomAct/Basic.lean | 2 +- .../GroupAction/MultipleTransitivity.lean | 4 +- .../GroupTheory/GroupAction/Primitive.lean | 2 +- Mathlib/GroupTheory/Nilpotent.lean | 4 +- Mathlib/GroupTheory/NoncommPiCoprod.lean | 6 +- Mathlib/GroupTheory/Order/Min.lean | 2 +- Mathlib/GroupTheory/OrderOfElement.lean | 2 +- Mathlib/GroupTheory/PGroup.lean | 10 ++-- Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 6 +- Mathlib/GroupTheory/Perm/Cycle/Factors.lean | 2 +- Mathlib/GroupTheory/Perm/Cycle/Type.lean | 2 +- Mathlib/GroupTheory/PushoutI.lean | 4 +- Mathlib/GroupTheory/Rank.lean | 2 +- Mathlib/GroupTheory/Schreier.lean | 12 ++-- Mathlib/GroupTheory/SchurZassenhaus.lean | 16 +++--- Mathlib/GroupTheory/Solvable.lean | 2 +- .../SpecificGroups/Quaternion.lean | 4 +- Mathlib/GroupTheory/Sylow.lean | 14 ++--- Mathlib/GroupTheory/Transfer.lean | 8 +-- Mathlib/LinearAlgebra/AffineSpace/Basis.lean | 2 +- .../AffineSpace/FiniteDimensional.lean | 6 +- .../AffineSpace/Independent.lean | 2 +- .../AffineSpace/Simplex/Basic.lean | 4 +- .../AffineSpace/Simplex/Centroid.lean | 6 +- Mathlib/LinearAlgebra/Alternating/Basic.lean | 2 +- Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 2 +- .../BilinearForm/DualLattice.lean | 6 +- Mathlib/LinearAlgebra/Charpoly/Basic.lean | 2 +- .../CliffordAlgebra/BaseChange.lean | 4 +- .../CliffordAlgebra/Inversion.lean | 6 +- .../CliffordAlgebra/SpinGroup.lean | 28 +++++----- Mathlib/LinearAlgebra/Coevaluation.lean | 4 +- Mathlib/LinearAlgebra/DFinsupp.lean | 2 +- Mathlib/LinearAlgebra/Determinant.lean | 6 +- .../Dimension/ErdosKaplansky.lean | 6 +- Mathlib/LinearAlgebra/Dimension/Finite.lean | 4 +- Mathlib/LinearAlgebra/Dimension/Free.lean | 2 +- .../Dimension/FreeAndStrongRankCondition.lean | 32 +++++------ .../LinearAlgebra/Dimension/RankNullity.lean | 4 +- .../Dimension/StrongRankCondition.lean | 28 +++++----- Mathlib/LinearAlgebra/Dual/Basis.lean | 2 +- Mathlib/LinearAlgebra/Dual/Lemmas.lean | 4 +- .../Eigenspace/Triangularizable.lean | 2 +- .../LinearAlgebra/ExteriorAlgebra/Basic.lean | 12 ++-- .../LinearAlgebra/ExteriorPower/Basis.lean | 2 +- .../FiniteDimensional/Basic.lean | 4 +- .../FiniteDimensional/Lemmas.lean | 10 ++-- .../Finsupp/LinearCombination.lean | 2 +- Mathlib/LinearAlgebra/Finsupp/Supported.lean | 4 +- .../LinearAlgebra/FreeModule/Determinant.lean | 2 +- Mathlib/LinearAlgebra/FreeModule/Norm.lean | 2 +- Mathlib/LinearAlgebra/FreeModule/PID.lean | 2 +- Mathlib/LinearAlgebra/LinearDisjoint.lean | 4 +- .../LinearIndependent/Basic.lean | 4 +- .../LinearAlgebra/LinearIndependent/Defs.lean | 4 +- .../LinearIndependent/Lemmas.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Adjugate.lean | 4 +- Mathlib/LinearAlgebra/Matrix/Basis.lean | 8 +-- Mathlib/LinearAlgebra/Matrix/Block.lean | 8 +-- .../Matrix/Charpoly/FiniteField.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Invertible.lean | 6 +- .../Matrix/Irreducible/Defs.lean | 10 ++-- .../Matrix/NonsingularInverse.lean | 20 +++---- .../LinearAlgebra/Matrix/SchurComplement.lean | 16 +++--- Mathlib/LinearAlgebra/Matrix/ToLin.lean | 4 +- .../LinearAlgebra/Matrix/ToLinearEquiv.lean | 2 +- Mathlib/LinearAlgebra/Multilinear/Basic.lean | 16 +++--- Mathlib/LinearAlgebra/Multilinear/Curry.lean | 16 +++--- .../LinearAlgebra/Multilinear/DirectSum.lean | 4 +- .../Multilinear/FiniteDimensional.lean | 2 +- .../Multilinear/TensorProduct.lean | 8 +-- Mathlib/LinearAlgebra/Orientation.lean | 6 +- .../LinearAlgebra/PiTensorProduct/Basis.lean | 2 +- .../LinearAlgebra/PiTensorProduct/Dual.lean | 8 +-- .../Projectivization/Cardinality.lean | 6 +- .../Projectivization/PSL/PSL2.lean | 2 +- .../LinearAlgebra/QuadraticForm/Basic.lean | 2 +- .../LinearAlgebra/QuadraticForm/Basis.lean | 2 +- .../QuadraticForm/TensorProduct.lean | 2 +- Mathlib/LinearAlgebra/RootSystem/Base.lean | 12 ++-- .../LinearAlgebra/RootSystem/BaseExists.lean | 14 ++--- Mathlib/LinearAlgebra/RootSystem/Chain.lean | 14 ++--- .../LinearAlgebra/RootSystem/Finite/G2.lean | 2 +- .../RootSystem/GeckConstruction/Basic.lean | 4 +- .../RootSystem/GeckConstruction/Lemmas.lean | 6 +- .../GeckConstruction/Relations.lean | 10 ++-- .../GeckConstruction/Semisimple.lean | 8 +-- Mathlib/LinearAlgebra/RootSystem/Hom.lean | 2 +- Mathlib/LinearAlgebra/Semisimple.lean | 2 +- .../LinearAlgebra/TensorAlgebra/Basic.lean | 4 +- Mathlib/LinearAlgebra/Trace.lean | 8 +-- Mathlib/Logic/Denumerable.lean | 2 +- Mathlib/Logic/Equiv/Fin/Rotate.lean | 4 +- Mathlib/Logic/Equiv/List.lean | 2 +- Mathlib/Logic/Nontrivial/Basic.lean | 2 +- .../Constructions/BorelSpace/Metric.lean | 2 +- .../Constructions/BorelSpace/Metrizable.lean | 2 +- .../Constructions/BorelSpace/Order.lean | 10 ++-- Mathlib/MeasureTheory/Constructions/Pi.lean | 8 +-- .../Constructions/Polish/Basic.lean | 44 +++++++-------- .../Polish/StronglyMeasurable.lean | 2 +- .../Constructions/Projective.lean | 2 +- .../MeasureTheory/Covering/Besicovitch.lean | 4 +- .../Covering/Differentiation.lean | 4 +- Mathlib/MeasureTheory/Covering/Vitali.lean | 2 +- .../Function/AEEqOfIntegral.lean | 8 +-- .../Function/AEMeasurableOrder.lean | 4 +- .../ConditionalExpectation/AEMeasurable.lean | 2 +- .../ConditionalExpectation/CondexpL2.lean | 2 +- .../ConditionalExpectation/Indicator.lean | 4 +- .../Function/FactorsThrough.lean | 2 +- Mathlib/MeasureTheory/Function/Jacobian.lean | 4 +- .../Function/L1Space/Integrable.lean | 4 +- .../Function/LocallyIntegrable.lean | 2 +- .../Function/LpSeminorm/Count.lean | 2 +- .../LpSeminorm/TriangleInequality.lean | 2 +- .../MeasureTheory/Function/SimpleFunc.lean | 4 +- .../Function/SimpleFuncDense.lean | 6 +- .../Function/SimpleFuncDenseLp.lean | 2 +- .../AEStronglyMeasurable.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 12 ++-- .../Function/StronglyMeasurable/Lp.lean | 2 +- Mathlib/MeasureTheory/Group/AddCircle.lean | 4 +- .../Group/FundamentalDomain.lean | 4 +- .../MeasureTheory/Integral/Asymptotics.lean | 2 +- Mathlib/MeasureTheory/Integral/Average.lean | 6 +- .../MeasureTheory/Integral/Bochner/Basic.lean | 4 +- .../MeasureTheory/Integral/Bochner/Set.lean | 4 +- .../Integral/CurveIntegral/Basic.lean | 12 ++-- .../Integral/CurveIntegral/Poincare.lean | 2 +- .../Integral/FinMeasAdditive.lean | 2 +- .../MeasureTheory/Integral/IntegrableOn.lean | 4 +- .../IntervalIntegral/FundThmCalculus.lean | 2 +- .../IntervalIntegral/IntegrationByParts.lean | 2 +- .../Integral/IntervalIntegral/Periodic.lean | 2 +- .../Integral/Lebesgue/Basic.lean | 2 +- Mathlib/MeasureTheory/Integral/SetToL1.lean | 2 +- .../MeasurableSpace/CountablyGenerated.lean | 4 +- .../MeasurableSpace/MeasurablyGenerated.lean | 4 +- .../MeasureTheory/Measure/AEMeasurable.lean | 4 +- Mathlib/MeasureTheory/Measure/Content.lean | 4 +- .../Measure/FiniteMeasureExt.lean | 2 +- .../Measure/FiniteMeasurePi.lean | 2 +- .../Measure/FiniteMeasureProd.lean | 4 +- Mathlib/MeasureTheory/Measure/Haar/Basic.lean | 6 +- .../Measure/Haar/InnerProductSpace.lean | 2 +- .../MeasureTheory/Measure/Haar/Quotient.lean | 6 +- .../Measure/HasOuterApproxClosed.lean | 2 +- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 12 ++-- .../MeasureTheory/Measure/Lebesgue/Basic.lean | 2 +- .../Measure/Lebesgue/EqHaar.lean | 8 +-- .../Measure/Lebesgue/VolumeOfBalls.lean | 20 +++---- .../Measure/LevyConvergence.lean | 2 +- .../Measure/LevyProkhorovMetric.lean | 2 +- .../MeasureTheory/Measure/MeasureSpace.lean | 6 +- .../MeasureTheory/Measure/Portmanteau.lean | 2 +- Mathlib/MeasureTheory/Measure/Prod.lean | 2 +- Mathlib/MeasureTheory/Measure/Regular.lean | 16 +++--- .../Measure/RegularityCompacts.lean | 2 +- Mathlib/MeasureTheory/Measure/Restrict.lean | 4 +- .../Measure/Typeclasses/Finite.lean | 2 +- .../Typeclasses/NullSingletonClass.lean | 2 +- .../Measure/Typeclasses/SFinite.lean | 2 +- .../OuterMeasure/OfFunction.lean | 8 +-- .../VectorMeasure/Decomposition/Lebesgue.lean | 8 +-- .../VectorMeasure/SetIntegral.lean | 2 +- .../VectorMeasure/WithDensity.lean | 6 +- .../Algebra/Ring/Definability.lean | 4 +- .../Arithmetic/Presburger/Definability.lean | 2 +- .../Presburger/Semilinear/Basic.lean | 14 ++--- Mathlib/ModelTheory/Definability.lean | 4 +- Mathlib/ModelTheory/Fraisse.lean | 2 +- Mathlib/ModelTheory/Graph.lean | 2 +- Mathlib/ModelTheory/LanguageMap.lean | 6 +- Mathlib/ModelTheory/Order.lean | 20 +++---- Mathlib/ModelTheory/Satisfiability.lean | 26 ++++----- Mathlib/ModelTheory/Substructures.lean | 6 +- .../ClassNumber/AdmissibleAbsoluteValue.lean | 2 +- Mathlib/NumberTheory/Cyclotomic/Basic.lean | 16 +++--- .../Cyclotomic/CyclotomicCharacter.lean | 6 +- .../NumberTheory/Cyclotomic/Discriminant.lean | 8 +-- Mathlib/NumberTheory/Cyclotomic/Gal.lean | 2 +- .../Cyclotomic/PrimitiveRoots.lean | 16 +++--- .../NumberTheory/LSeries/HurwitzZetaEven.lean | 2 +- .../NumberTheory/LegendreSymbol/Basic.lean | 2 +- .../LegendreSymbol/GaussEisensteinLemmas.lean | 2 +- .../LegendreSymbol/JacobiSymbol.lean | 2 +- Mathlib/NumberTheory/LocalField/Basic.lean | 12 ++-- Mathlib/NumberTheory/LucasLehmer.lean | 2 +- Mathlib/NumberTheory/Modular.lean | 4 +- .../ModularForms/CongruenceSubgroups.lean | 4 +- .../NumberTheory/ModularForms/QExpansion.lean | 2 +- .../NumberField/Cyclotomic/Basic.lean | 10 ++-- .../NumberField/Discriminant/Basic.lean | 6 +- .../NumberField/InfinitePlace/Embeddings.lean | 6 +- .../InfinitePlace/Ramification.lean | 4 +- Mathlib/NumberTheory/NumberField/Norm.lean | 6 +- Mathlib/NumberTheory/Padics/Complex.lean | 4 +- Mathlib/NumberTheory/Padics/RingHoms.lean | 2 +- Mathlib/NumberTheory/Pell.lean | 2 +- Mathlib/NumberTheory/PrimesCongruentOne.lean | 4 +- .../RamificationInertia/Basic.lean | 8 +-- .../RamificationInertia/Inertia.lean | 8 +-- .../RamificationInertia/Ramification.lean | 2 +- Mathlib/NumberTheory/WellApproximable.lean | 2 +- Mathlib/NumberTheory/Wilson.lean | 2 +- Mathlib/NumberTheory/Zsqrtd/Basic.lean | 2 +- Mathlib/Order/Category/NonemptyFinLinOrd.lean | 6 +- Mathlib/Order/CompleteLattice/Basic.lean | 4 +- .../ConditionallyCompleteLattice/Indexed.lean | 2 +- .../Indexed.lean | 4 +- Mathlib/Order/CountableDenseLinearOrder.lean | 2 +- Mathlib/Order/Disjoint.lean | 4 +- Mathlib/Order/Extension/Linear.lean | 12 ++-- .../Order/Filter/AtTopBot/BigOperators.lean | 2 +- Mathlib/Order/Filter/Basic.lean | 4 +- Mathlib/Order/Filter/CountableInter.lean | 6 +- Mathlib/Order/Filter/Finite.lean | 4 +- Mathlib/Order/Filter/IsBounded.lean | 2 +- Mathlib/Order/Filter/Map.lean | 2 +- Mathlib/Order/Filter/Pi.lean | 2 +- Mathlib/Order/Filter/Prod.lean | 2 +- Mathlib/Order/Filter/Ultrafilter/Defs.lean | 6 +- Mathlib/Order/KrullDimension.lean | 2 +- Mathlib/Order/Monotone/MonovaryOrder.lean | 2 +- Mathlib/Order/Partition/Equipartition.lean | 2 +- Mathlib/Order/WellFoundedSet.lean | 4 +- Mathlib/Order/WellQuasiOrder.lean | 4 +- Mathlib/Probability/CDF.lean | 2 +- Mathlib/Probability/Independence/ZeroOne.lean | 2 +- Mathlib/Probability/Kernel/Defs.lean | 2 +- .../Kernel/MeasurableIntegral.lean | 2 +- .../Probability/Martingale/Convergence.lean | 2 +- Mathlib/Probability/Process/Filtration.lean | 12 ++-- Mathlib/Probability/Process/Predictable.lean | 16 +++--- Mathlib/Probability/Process/Stopping.lean | 2 +- Mathlib/Probability/StrongLaw.lean | 2 +- Mathlib/Probability/UniformOn.lean | 2 +- Mathlib/RepresentationTheory/Coinduced.lean | 2 +- Mathlib/RepresentationTheory/Maschke.lean | 4 +- .../Subrepresentation.lean | 2 +- Mathlib/RingTheory/Adjoin/Field.lean | 6 +- Mathlib/RingTheory/Adjoin/PowerBasis.lean | 2 +- Mathlib/RingTheory/AdjoinRoot.lean | 2 +- Mathlib/RingTheory/Algebraic/Basic.lean | 6 +- .../AlgebraicIndependent/Basic.lean | 2 +- .../RankAndCardinality.lean | 14 ++--- .../TranscendenceBasis.lean | 12 ++-- Mathlib/RingTheory/ChainOfDivisors.lean | 14 ++--- Mathlib/RingTheory/Coprime/Ideal.lean | 2 +- .../RingTheory/DedekindDomain/Different.lean | 18 +++--- Mathlib/RingTheory/DedekindDomain/Dvr.lean | 12 ++-- .../DedekindDomain/Factorization.lean | 2 +- .../DedekindDomain/Ideal/Lemmas.lean | 4 +- .../DedekindDomain/IntegralClosure.lean | 20 +++---- Mathlib/RingTheory/DedekindDomain/PID.lean | 10 ++-- .../DiscreteValuationRing/Basic.lean | 10 ++-- .../DiscreteValuationRing/TFAE.lean | 2 +- Mathlib/RingTheory/Discriminant.lean | 2 +- Mathlib/RingTheory/EssentialFiniteness.lean | 2 +- Mathlib/RingTheory/Etale/Basic.lean | 4 +- Mathlib/RingTheory/Etale/Kaehler.lean | 18 +++--- Mathlib/RingTheory/Etale/StandardEtale.lean | 2 +- Mathlib/RingTheory/Extension/Basic.lean | 2 +- .../RingTheory/Extension/Cotangent/Basic.lean | 2 +- Mathlib/RingTheory/Extension/Generators.lean | 2 +- Mathlib/RingTheory/FinitePresentation.lean | 12 ++-- Mathlib/RingTheory/FiniteType.lean | 16 +++--- Mathlib/RingTheory/Finiteness/Basic.lean | 8 +-- .../Finiteness/FiniteTypeLocal.lean | 2 +- Mathlib/RingTheory/Finiteness/Finsupp.lean | 8 +-- Mathlib/RingTheory/Finiteness/Ideal.lean | 8 +-- .../Finiteness/ModuleFinitePresentation.lean | 2 +- Mathlib/RingTheory/Flat/Basic.lean | 6 +- .../RingTheory/Flat/EquationalCriterion.lean | 2 +- .../RingTheory/Flat/FaithfullyFlat/Basic.lean | 6 +- Mathlib/RingTheory/FormalGroup/Basic.lean | 4 +- Mathlib/RingTheory/FreeCommRing.lean | 2 +- .../HomogeneousLocalization.lean | 2 +- .../RingTheory/HahnSeries/Multiplication.lean | 4 +- Mathlib/RingTheory/Henselian.lean | 2 +- .../Ideal/AssociatedPrime/Basic.lean | 2 +- Mathlib/RingTheory/Ideal/GoingUp.lean | 4 +- Mathlib/RingTheory/Ideal/Maps.lean | 4 +- Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean | 4 +- Mathlib/RingTheory/Ideal/Operations.lean | 2 +- Mathlib/RingTheory/Ideal/Prod.lean | 2 +- Mathlib/RingTheory/Ideal/Quotient/Basic.lean | 4 +- .../RingTheory/Ideal/Quotient/Nilpotent.lean | 2 +- .../RingTheory/Ideal/Quotient/Operations.lean | 2 +- .../IntegralClosure/Algebra/Basic.lean | 4 +- .../IntegralClosure/Algebra/Ideal.lean | 2 +- .../IntegralClosure/IntegralRestrict.lean | 56 +++++++++---------- .../IntegralClosure/IntegrallyClosed.lean | 2 +- .../IntegralClosure/IsIntegral/Basic.lean | 8 +-- .../IsIntegralClosure/Basic.lean | 4 +- Mathlib/RingTheory/IntegralDomain.lean | 2 +- Mathlib/RingTheory/Invariant/Basic.lean | 4 +- Mathlib/RingTheory/Invariant/Galois.lean | 2 +- Mathlib/RingTheory/IsTensorProduct.lean | 12 ++-- Mathlib/RingTheory/Jacobson/Ideal.lean | 4 +- Mathlib/RingTheory/Jacobson/Polynomial.lean | 2 +- Mathlib/RingTheory/Jacobson/Ring.lean | 4 +- Mathlib/RingTheory/Kaehler/Basic.lean | 2 +- Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 6 +- Mathlib/RingTheory/KrullDimension/Basic.lean | 2 +- Mathlib/RingTheory/LaurentSeries.lean | 2 +- Mathlib/RingTheory/LinearDisjoint.lean | 24 ++++---- Mathlib/RingTheory/LittleWedderburn.lean | 8 +-- Mathlib/RingTheory/LocalProperties/Basic.lean | 16 +++--- .../RingTheory/LocalProperties/Exactness.lean | 8 +-- Mathlib/RingTheory/LocalRing/Module.lean | 8 +-- .../LocalRing/ResidueField/Instances.lean | 8 +-- .../LocalRing/ResidueField/Polynomial.lean | 2 +- Mathlib/RingTheory/LocalRing/Subring.lean | 2 +- .../RingTheory/Localization/Away/Basic.lean | 2 +- .../RingTheory/Localization/Away/Lemmas.lean | 2 +- .../RingTheory/Localization/BaseChange.lean | 12 ++-- Mathlib/RingTheory/Localization/Basic.lean | 2 +- Mathlib/RingTheory/Localization/Defs.lean | 4 +- .../RingTheory/Localization/FractionRing.lean | 4 +- Mathlib/RingTheory/Localization/Ideal.lean | 2 +- Mathlib/RingTheory/Localization/Integer.lean | 2 +- Mathlib/RingTheory/Localization/Integral.lean | 16 +++--- .../LocalizationLocalization.lean | 4 +- .../RingTheory/Localization/NormTrace.lean | 8 +-- Mathlib/RingTheory/Morita/Matrix.lean | 4 +- Mathlib/RingTheory/MvPowerSeries/Expand.lean | 2 +- .../MvPowerSeries/Substitution.lean | 32 +++++------ Mathlib/RingTheory/Noetherian/Orzech.lean | 2 +- .../RingTheory/NonUnitalSubring/Basic.lean | 2 +- .../NonUnitalSubsemiring/Basic.lean | 2 +- Mathlib/RingTheory/Norm/Basic.lean | 22 ++++---- Mathlib/RingTheory/Norm/Defs.lean | 2 +- Mathlib/RingTheory/Norm/Transitivity.lean | 2 +- Mathlib/RingTheory/NormTrace.lean | 2 +- .../RingTheory/OrderOfVanishing/Basic.lean | 2 +- Mathlib/RingTheory/OreLocalization/Ring.lean | 4 +- Mathlib/RingTheory/OrzechProperty.lean | 8 +-- Mathlib/RingTheory/Perfection.lean | 4 +- Mathlib/RingTheory/PiTensorProduct.lean | 4 +- Mathlib/RingTheory/Polynomial/Basic.lean | 2 +- .../Polynomial/Cyclotomic/Basic.lean | 2 +- .../Polynomial/Cyclotomic/Eval.lean | 4 +- .../Polynomial/Cyclotomic/Expand.lean | 8 +-- .../Polynomial/Cyclotomic/Roots.lean | 10 ++-- Mathlib/RingTheory/Polynomial/Dickson.lean | 2 +- .../Polynomial/Eisenstein/IsIntegral.lean | 2 +- .../RingTheory/Polynomial/RationalRoot.lean | 2 +- .../Polynomial/Resultant/Basic.lean | 10 ++-- Mathlib/RingTheory/Polynomial/ScaleRoots.lean | 2 +- .../Polynomial/SeparableDegree.lean | 2 +- .../Polynomial/UniqueFactorization.lean | 2 +- .../UniversalFactorizationRing.lean | 28 +++++----- .../RingTheory/PowerSeries/Substitution.lean | 8 +-- Mathlib/RingTheory/PrincipalIdealDomain.lean | 2 +- Mathlib/RingTheory/RingHom/Finite.lean | 12 ++-- Mathlib/RingTheory/RingHom/Integral.lean | 6 +- Mathlib/RingTheory/RingHom/Locally.lean | 26 ++++----- Mathlib/RingTheory/RingHom/Surjective.lean | 2 +- Mathlib/RingTheory/RingHom/Unramified.lean | 2 +- Mathlib/RingTheory/RingHomProperties.lean | 4 +- Mathlib/RingTheory/RootsOfUnity/Minpoly.lean | 4 +- .../RootsOfUnity/PrimitiveRoots.lean | 2 +- Mathlib/RingTheory/SimpleModule/Basic.lean | 10 ++-- Mathlib/RingTheory/Smooth/Basic.lean | 16 +++--- Mathlib/RingTheory/Smooth/Kaehler.lean | 8 +-- .../Smooth/StandardSmoothCotangent.lean | 2 +- .../RingTheory/Spectrum/Prime/FreeLocus.lean | 10 ++-- .../RingTheory/Spectrum/Prime/Topology.lean | 4 +- Mathlib/RingTheory/SurjectiveOnStalks.lean | 2 +- Mathlib/RingTheory/TensorProduct/Finite.lean | 2 +- .../TensorProduct/IsBaseChangePi.lean | 6 +- Mathlib/RingTheory/TensorProduct/Maps.lean | 4 +- .../RingTheory/TensorProduct/Nontrivial.lean | 4 +- Mathlib/RingTheory/Trace/Basic.lean | 26 ++++----- Mathlib/RingTheory/Trace/Defs.lean | 6 +- Mathlib/RingTheory/Trace/Quotient.lean | 16 +++--- .../UniqueFactorizationDomain/Basic.lean | 4 +- .../UniqueFactorizationDomain/ClassGroup.lean | 2 +- .../UniqueFactorizationDomain/FactorSet.lean | 2 +- .../Multiplicative.lean | 16 +++--- .../Multiplicity.lean | 2 +- .../NormalizedFactors.lean | 2 +- Mathlib/RingTheory/Unramified/Basic.lean | 18 +++--- Mathlib/RingTheory/Unramified/Field.lean | 4 +- Mathlib/RingTheory/Unramified/LocalRing.lean | 2 +- .../RingTheory/Valuation/ValuationRing.lean | 2 +- Mathlib/RingTheory/WittVector/Compare.lean | 2 +- Mathlib/RingTheory/WittVector/Frobenius.lean | 2 +- Mathlib/RingTheory/WittVector/InitTail.lean | 2 +- Mathlib/RingTheory/WittVector/Isocrystal.lean | 2 +- Mathlib/RingTheory/ZariskisMainTheorem.lean | 16 +++--- Mathlib/SetTheory/Cardinal/Arithmetic.lean | 4 +- Mathlib/SetTheory/Cardinal/Basic.lean | 4 +- .../Cardinal/Cofinality/Ordinal.lean | 4 +- Mathlib/SetTheory/Cardinal/Finite.lean | 14 ++--- Mathlib/SetTheory/Cardinal/NatCard.lean | 26 ++++----- Mathlib/SetTheory/Cardinal/Order.lean | 2 +- Mathlib/SetTheory/Ordinal/Family.lean | 2 +- .../Ordinal/FundamentalSequence.lean | 2 +- Mathlib/SetTheory/Ordinal/Notation.lean | 34 +++++------ Mathlib/SetTheory/Ordinal/Rank.lean | 2 +- Mathlib/Tactic/NormNum/LegendreSymbol.lean | 2 +- Mathlib/Topology/Algebra/ConstMulAction.lean | 2 +- .../Topology/Algebra/ContinuousAffineMap.lean | 4 +- Mathlib/Topology/Algebra/FilterBasis.lean | 6 +- .../Topology/Algebra/Group/GroupTopology.lean | 10 ++-- .../Topology/Algebra/InfiniteSum/Defs.lean | 2 +- .../Topology/Algebra/InfiniteSum/Group.lean | 6 +- .../Algebra/InfiniteSum/SummationFilter.lean | 2 +- .../Algebra/IsUniformGroup/Basic.lean | 6 +- .../IsUniformGroup/DiscreteSubgroup.lean | 2 +- .../Algebra/Module/FiniteDimension.lean | 10 ++-- .../Algebra/Module/LocallyConvex.lean | 8 +-- .../Algebra/Module/ModuleTopology.lean | 12 ++-- .../Algebra/Module/Multilinear/Topology.lean | 10 ++-- .../Module/Spaces/UniformConvergenceCLM.lean | 42 +++++++------- .../Algebra/Module/TopDualPairing.lean | 4 +- .../Algebra/Module/UniformConvergence.lean | 2 +- Mathlib/Topology/Algebra/Monoid.lean | 8 +-- .../Algebra/Nonarchimedean/AdicTopology.lean | 6 +- .../Algebra/Nonarchimedean/Bases.lean | 8 +-- .../RestrictedProduct/TopologicalSpace.lean | 6 +- Mathlib/Topology/Algebra/Semigroup.lean | 6 +- Mathlib/Topology/Algebra/UniformField.lean | 6 +- .../Topology/Algebra/UniformFilterBasis.lean | 4 +- .../ValuativeRel/ValuativeTopology.lean | 4 +- .../Topology/Algebra/Valued/NormedValued.lean | 4 +- .../Algebra/Valued/ValuationTopology.lean | 2 +- Mathlib/Topology/Baire/Lemmas.lean | 4 +- Mathlib/Topology/Bases.lean | 10 ++-- .../Topology/CWComplex/Classical/Basic.lean | 2 +- Mathlib/Topology/Category/CompHaus/Basic.lean | 4 +- .../Category/Profinite/CofilteredLimit.lean | 6 +- Mathlib/Topology/Category/Stonean/Basic.lean | 6 +- .../Category/TopCat/Limits/Konig.lean | 2 +- .../Category/TopCat/Limits/Products.lean | 4 +- Mathlib/Topology/CompactOpen.lean | 4 +- .../Topology/Compactification/StoneCech.lean | 4 +- Mathlib/Topology/Compactness/Compact.lean | 6 +- Mathlib/Topology/Compactness/Lindelof.lean | 2 +- Mathlib/Topology/Connected/Basic.lean | 2 +- .../Connected/LocallyPathConnected.lean | 2 +- Mathlib/Topology/Connected/PathConnected.lean | 2 +- Mathlib/Topology/Constructions.lean | 4 +- Mathlib/Topology/ContinuousMap/Algebra.lean | 4 +- .../ContinuousMap/Bounded/ArzelaAscoli.lean | 2 +- Mathlib/Topology/Covering/Quotient.lean | 6 +- Mathlib/Topology/DenseEmbedding.lean | 2 +- Mathlib/Topology/DiscreteSubset.lean | 2 +- Mathlib/Topology/ExtendFrom.lean | 2 +- Mathlib/Topology/ExtremallyDisconnected.lean | 2 +- Mathlib/Topology/FiberBundle/Basic.lean | 12 ++-- Mathlib/Topology/GDelta/Basic.lean | 2 +- .../Homotopy/LocallyContractible.lean | 4 +- .../Homotopy/TopCat/ZerothHomotopy.lean | 2 +- Mathlib/Topology/Instances/Complex.lean | 6 +- Mathlib/Topology/IsLocalHomeomorph.lean | 2 +- Mathlib/Topology/LocallyConstant/Basic.lean | 8 +-- Mathlib/Topology/Maps/Basic.lean | 2 +- Mathlib/Topology/MetricSpace/Contracting.lean | 2 +- .../MetricSpace/HausdorffDimension.lean | 2 +- Mathlib/Topology/MetricSpace/HolderNorm.lean | 4 +- Mathlib/Topology/MetricSpace/Kuratowski.lean | 2 +- Mathlib/Topology/MetricSpace/Perfect.lean | 2 +- Mathlib/Topology/MetricSpace/PiNat.lean | 4 +- Mathlib/Topology/MetricSpace/Polish.lean | 18 +++--- .../Topology/MetricSpace/Pseudo/Basic.lean | 4 +- Mathlib/Topology/MetricSpace/Pseudo/Pi.lean | 2 +- .../Metrizable/CompletelyMetrizable.lean | 18 +++--- Mathlib/Topology/Metrizable/Uniformity.lean | 4 +- Mathlib/Topology/Metrizable/Urysohn.lean | 6 +- Mathlib/Topology/NhdsWithin.lean | 2 +- .../OpenPartialHomeomorph/Constructions.lean | 8 +-- Mathlib/Topology/Order.lean | 8 +-- Mathlib/Topology/Order/Compact.lean | 4 +- Mathlib/Topology/Order/IntermediateValue.lean | 2 +- Mathlib/Topology/Order/IsLUB.lean | 2 +- Mathlib/Topology/Order/LawsonTopology.lean | 4 +- Mathlib/Topology/Order/LeftRightLim.lean | 12 ++-- Mathlib/Topology/Order/LeftRightNhds.lean | 2 +- .../Topology/Order/LowerUpperTopology.lean | 2 +- Mathlib/Topology/Order/ScottTopology.lean | 4 +- .../Topology/Order/UpperLowerSetTopology.lean | 4 +- Mathlib/Topology/PartitionOfUnity.lean | 2 +- .../Separation/CompletelyRegular.lean | 2 +- Mathlib/Topology/Separation/Connected.lean | 2 +- Mathlib/Topology/Separation/Profinite.lean | 4 +- Mathlib/Topology/Sequences.lean | 4 +- .../SheafCondition/PairwiseIntersections.lean | 2 +- .../Sheaves/SheafCondition/Sites.lean | 2 +- Mathlib/Topology/Sheaves/Stalks.lean | 2 +- Mathlib/Topology/ShrinkingLemma.lean | 6 +- Mathlib/Topology/UniformSpace/Cauchy.lean | 8 +-- .../LocallyUniformConvergence.lean | 2 +- .../Topology/UniformSpace/OfCompactT2.lean | 2 +- .../UniformSpace/Ultra/Constructions.lean | 8 +-- .../UniformConvergenceTopology.lean | 2 +- Mathlib/Topology/VectorBundle/Basic.lean | 4 +- Mathlib/Topology/VectorBundle/Riemannian.lean | 2 +- 953 files changed, 2607 insertions(+), 2613 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Operations.lean b/Mathlib/Algebra/Algebra/Operations.lean index d31f10ca1de085..ac958fba49be6a 100644 --- a/Mathlib/Algebra/Algebra/Operations.lean +++ b/Mathlib/Algebra/Algebra/Operations.lean @@ -806,7 +806,7 @@ instance : IdemCommSemiring (Submodule R A) := theorem prod_span {ι : Type*} (s : Finset ι) (M : ι → Set A) : (∏ i ∈ s, Submodule.span R (M i)) = Submodule.span R (∏ i ∈ s, M i) := by - letI := Classical.decEq ι + let := Classical.decEq ι refine Finset.induction_on s ?_ ?_ · simp [one_eq_span, Set.singleton_one] · intro _ _ H ih diff --git a/Mathlib/Algebra/Algebra/Subalgebra/IsSimpleOrder.lean b/Mathlib/Algebra/Algebra/Subalgebra/IsSimpleOrder.lean index 176d9f6b6125ee..29926876684415 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/IsSimpleOrder.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/IsSimpleOrder.lean @@ -24,8 +24,8 @@ theorem Subalgebra.isSimpleOrder_of_finrank_prime (F A) [Field F] [Ring A] [IsDo ⟨⟨⊥, ⊤, fun he => Nat.not_prime_one ((Subalgebra.bot_eq_top_iff_finrank_eq_one.1 he).subst hp)⟩⟩ eq_bot_or_eq_top := fun K => by - haveI : FiniteDimensional _ _ := .of_finrank_pos hp.pos - letI := divisionRingOfFiniteDimensional F K + have : FiniteDimensional _ _ := .of_finrank_pos hp.pos + let := divisionRingOfFiniteDimensional F K refine (hp.eq_one_or_self_of_dvd _ ⟨_, (finrank_mul_finrank F K A).symm⟩).imp ?_ fun h => ?_ · exact fun h' => Subalgebra.eq_bot_of_finrank_one h' · exact diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Rank.lean b/Mathlib/Algebra/Algebra/Subalgebra/Rank.lean index ae303f1a4a8955..3c630fa255c73c 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Rank.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Rank.lean @@ -35,11 +35,11 @@ variable [Module.Free R A] [Module.Free A (Algebra.adjoin A (B : Set S))] theorem rank_sup_eq_rank_left_mul_rank_of_free : Module.rank R ↥(A ⊔ B) = Module.rank R A * Module.rank A (Algebra.adjoin A (B : Set S)) := by rcases subsingleton_or_nontrivial R with _ | _ - · haveI := Module.subsingleton R S; simp + · have := Module.subsingleton R S; simp nontriviality S using rank_subsingleton' - letI : Algebra A (Algebra.adjoin A (B : Set S)) := Subalgebra.algebra _ - letI : SMul A (Algebra.adjoin A (B : Set S)) := Algebra.toSMul - haveI : IsScalarTower R A (Algebra.adjoin A (B : Set S)) := + let : Algebra A (Algebra.adjoin A (B : Set S)) := Subalgebra.algebra _ + let : SMul A (Algebra.adjoin A (B : Set S)) := Algebra.toSMul + have : IsScalarTower R A (Algebra.adjoin A (B : Set S)) := IsScalarTower.of_algebraMap_eq (congrFun rfl) rw [rank_mul_rank R A (Algebra.adjoin A (B : Set S))] change _ = Module.rank R ((Algebra.adjoin A (B : Set S)).restrictScalars R) diff --git a/Mathlib/Algebra/AlgebraicCard.lean b/Mathlib/Algebra/AlgebraicCard.lean index af9f9351e40e20..d5ef0674d10f08 100644 --- a/Mathlib/Algebra/AlgebraicCard.lean +++ b/Mathlib/Algebra/AlgebraicCard.lean @@ -31,7 +31,7 @@ namespace Algebraic theorem infinite_of_charZero (R A : Type*) [CommRing R] [Ring A] [Algebra R A] [CharZero A] : { x : A | IsAlgebraic R x }.Infinite := by - letI := MulActionWithZero.nontrivial R A + let := MulActionWithZero.nontrivial R A exact infinite_of_injective_forall_mem Nat.cast_injective isAlgebraic_nat theorem aleph0_le_cardinalMk_of_charZero (R A : Type*) [CommRing R] [Ring A] diff --git a/Mathlib/Algebra/BigOperators/Associated.lean b/Mathlib/Algebra/BigOperators/Associated.lean index 897989824e09f6..a5fb4e8c160e0b 100644 --- a/Mathlib/Algebra/BigOperators/Associated.lean +++ b/Mathlib/Algebra/BigOperators/Associated.lean @@ -178,7 +178,7 @@ theorem prod_eq_one_iff {p : Multiset (Associates M)} : (by simp +contextual [mul_eq_one, or_imp, forall_and]) theorem prod_le_prod {p q : Multiset (Associates M)} (h : p ≤ q) : p.prod ≤ q.prod := by - haveI := Classical.decEq (Associates M) + have := Classical.decEq (Associates M) suffices p.prod ≤ (p + (q - p)).prod by rwa [add_tsub_cancel_of_le h] at this suffices p.prod * 1 ≤ p.prod * (q - p).prod by simpa exact mul_mono (le_refl p.prod) one_le diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index c930a7b8c6efdf..63ce51e2fa6fe3 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -226,9 +226,9 @@ theorem finprod_true (f : True → M) : ∏ᶠ i, f i = f trivial := theorem finprod_eq_dif {p : Prop} [Decidable p] (f : p → M) : ∏ᶠ i, f i = if h : p then f h else 1 := by split_ifs with h - · haveI : Unique p := ⟨⟨h⟩, fun _ => rfl⟩ + · have : Unique p := ⟨⟨h⟩, fun _ => rfl⟩ exact finprod_unique f - · haveI : IsEmpty p := ⟨h⟩ + · have : IsEmpty p := ⟨h⟩ exact finprod_of_isEmpty f @[to_additive] @@ -1065,7 +1065,7 @@ over `a ∈ ⋃ i ∈ I, t i` is equal to the product over `i ∈ I` of the prod over `a ∈ t i`. -/] theorem finprod_mem_biUnion {I : Set ι} {t : ι → Set α} (h : I.PairwiseDisjoint t) (hI : I.Finite) (ht : ∀ i ∈ I, (t i).Finite) : ∏ᶠ a ∈ ⋃ x ∈ I, t x, f a = ∏ᶠ i ∈ I, ∏ᶠ j ∈ t i, f j := by - haveI := hI.fintype + have := hI.fintype rw [biUnion_eq_iUnion, finprod_mem_iUnion, ← finprod_set_coe_eq_finprod_mem] exacts [fun x y hxy => h x.2 y.2 (Subtype.coe_injective.ne hxy), fun b => ht b b.2] diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index a829d75b1e7635..dc1fd7e60a6421 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -393,7 +393,7 @@ lemma prod_congr_of_eq_on_inter {ι M : Type*} {s₁ s₂ : Finset ι} {f g : ι @[to_additive] theorem prod_eq_mul_of_mem {s : Finset ι} {f : ι → M} (a b : ι) (ha : a ∈ s) (hb : b ∈ s) (hn : a ≠ b) (h₀ : ∀ c ∈ s, c ≠ a ∧ c ≠ b → f c = 1) : ∏ x ∈ s, f x = f a * f b := by - haveI := Classical.decEq ι; let s' := ({a, b} : Finset ι) + have := Classical.decEq ι; let s' := ({a, b} : Finset ι) have hu : s' ⊆ s := by grind have hf : ∀ c ∈ s, c ∉ s' → f c = 1 := by grind rw [← Finset.prod_subset hu hf] @@ -403,7 +403,7 @@ theorem prod_eq_mul_of_mem {s : Finset ι} {f : ι → M} (a b : ι) (ha : a ∈ theorem prod_eq_mul {s : Finset ι} {f : ι → M} (a b : ι) (hn : a ≠ b) (h₀ : ∀ c ∈ s, c ≠ a ∧ c ≠ b → f c = 1) (ha : a ∉ s → f a = 1) (hb : b ∉ s → f b = 1) : ∏ x ∈ s, f x = f a * f b := by - haveI := Classical.decEq ι; by_cases h₁ : a ∈ s <;> by_cases h₂ : b ∈ s + have := Classical.decEq ι; by_cases h₁ : a ∈ s <;> by_cases h₂ : b ∈ s · exact prod_eq_mul_of_mem a b h₁ h₂ hn h₀ · rw [hb h₂, mul_one] apply prod_eq_single_of_mem a h₁ diff --git a/Mathlib/Algebra/Category/Grp/Images.lean b/Mathlib/Algebra/Category/Grp/Images.lean index af3773c9aa8ccf..3d103f20cbe859 100644 --- a/Mathlib/Algebra/Category/Grp/Images.lean +++ b/Mathlib/Algebra/Category/Grp/Images.lean @@ -60,14 +60,14 @@ noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I := ofHom { toFun := (fun x => F'.e (Classical.indefiniteDescription _ x.2).1 : image f → F'.I) map_zero' := by - haveI := F'.m_mono + have := F'.m_mono apply injective_of_mono F'.m change (F'.e ≫ F'.m) _ = _ rw [F'.fac, map_zero] exact (Classical.indefiniteDescription (fun y => f y = 0) _).2 map_add' := by intro x y - haveI := F'.m_mono + have := F'.m_mono apply injective_of_mono F'.m rw [map_add] change (F'.e ≫ F'.m) _ = (F'.e ≫ F'.m) _ + (F'.e ≫ F'.m) _ diff --git a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean index b162815dd0a236..bdafae24b18577 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean @@ -427,7 +427,7 @@ lemma hom_ext {M : ModuleCat R} {N : ModuleCat S} {α β : (extendScalars f).obj M ⟶ N} (h : ∀ (m : M), α ((1 : S) ⊗ₜ m) = β ((1 : S) ⊗ₜ m)) : α = β := by apply (restrictScalars f).map_injective - letI := f.toAlgebra + let := f.toAlgebra ext : 1 apply TensorProduct.ext' intro (s : S) m @@ -765,7 +765,7 @@ def homEquiv {X : ModuleCat R} {Y : ModuleCat S} : toFun := HomEquiv.toRestrictScalars.{u₁, u₂, v} f invFun := HomEquiv.fromExtendScalars.{u₁, u₂, v} f left_inv g := by - letI m1 : Module R S := Module.compHom S f; letI m2 : Module R Y := Module.compHom Y f + let m1 : Module R S := Module.compHom S f; let m2 : Module R Y := Module.compHom Y f apply hom_ext apply LinearMap.ext; intro z induction z using TensorProduct.induction_on with @@ -779,7 +779,7 @@ def homEquiv {X : ModuleCat R} {Y : ModuleCat S} : rfl | add _ _ ih1 ih2 => rw [map_add, map_add, ih1, ih2] right_inv g := by - letI m1 : Module R S := Module.compHom S f; letI m2 : Module R Y := Module.compHom Y f + let m1 : Module R S := Module.compHom S f; let m2 : Module R Y := Module.compHom Y f ext x rw [HomEquiv.toRestrictScalars_hom_apply] -- This needs to be `erw` because of some unfolding in `fromExtendScalars` @@ -801,7 +801,7 @@ def Unit.map {X : ModuleCat R} : X ⟶ (extendScalars f ⋙ restrictScalars f).o { toFun := fun x => (1 : S) ⊗ₜ[R,f] x map_add' := fun x x' => by dsimp; rw [TensorProduct.tmul_add] map_smul' := fun r x => by - letI m1 : Module R S := Module.compHom S f + let m1 : Module R S := Module.compHom S f dsimp; rw [← TensorProduct.smul_tmul, TensorProduct.smul_tmul'] } /-- @@ -860,9 +860,9 @@ def counit : restrictScalars.{max v u₂, u₁, u₂} f ⋙ extendScalars f ⟶ app _ := Counit.map.{u₁, u₂, v} f naturality Y Y' g := by -- Porting note: this is very annoying; fix instances in concrete categories - letI m1 : Module R S := Module.compHom S f - letI m2 : Module R Y := Module.compHom Y f - letI m2 : Module R Y' := Module.compHom Y' f + let m1 : Module R S := Module.compHom S f + let m2 : Module R Y := Module.compHom Y f + let m2 : Module R Y' := Module.compHom Y' f ext z induction z using TensorProduct.induction_on with | zero => rw [map_zero, map_zero] diff --git a/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean index 6457b8aeb1a7ae..af3967d4d00478 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean @@ -175,8 +175,8 @@ noncomputable def desc : CommRingCat.KaehlerDifferential f ⟶ M := set_option backward.isDefEq.respectTransparency false in @[simp] lemma desc_d (b : B) : D.desc (CommRingCat.KaehlerDifferential.d b) = D.d b := by - letI := f.hom.toAlgebra - letI := Module.compHom M f.hom + let := f.hom.toAlgebra + let := Module.compHom M f.hom apply D.liftKaehlerDifferential_comp_D end ModuleCat.Derivation diff --git a/Mathlib/Algebra/Category/ModuleCat/Free.lean b/Mathlib/Algebra/Category/ModuleCat/Free.lean index 7b4c01add2785e..e5317f64219849 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Free.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Free.lean @@ -172,7 +172,7 @@ theorem free_shortExact [Module.Free R S.X₁] [Module.Free R S.X₃] : theorem free_shortExact_rank_add [Module.Free R S.X₁] [Module.Free R S.X₃] [StrongRankCondition R] : Module.rank R S.X₂ = Module.rank R S.X₁ + Module.rank R S.X₃ := by - haveI := free_shortExact hS' + have := free_shortExact hS' rw [Module.Free.rank_eq_card_chooseBasisIndex, Module.Free.rank_eq_card_chooseBasisIndex R S.X₁, Module.Free.rank_eq_card_chooseBasisIndex R S.X₃, Cardinal.add_def, Cardinal.eq] exact ⟨Basis.indexEquiv (Module.Free.chooseBasis R S.X₂) (Basis.ofShortExact hS' diff --git a/Mathlib/Algebra/Category/ModuleCat/Kernels.lean b/Mathlib/Algebra/Category/ModuleCat/Kernels.lean index 9561c889cadc06..dae26944b28243 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Kernels.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Kernels.lean @@ -64,7 +64,7 @@ def cokernelIsColimit : IsColimit (cokernelCocone f) := (fun s => ofHom <| (LinearMap.range f.hom).liftQ (Cofork.π s).hom <| LinearMap.range_le_ker_iff.2 <| ModuleCat.hom_ext_iff.mp <| CokernelCofork.condition s) (fun s => hom_ext <| (LinearMap.range f.hom).liftQ_mkQ (Cofork.π s).hom _) fun s m h => by - haveI : Epi (ofHom f.hom.range.mkQ) := + have : Epi (ofHom f.hom.range.mkQ) := (epi_iff_range_eq_top _).mpr (Submodule.range_mkQ _) apply (cancel_epi (ofHom f.hom.range.mkQ)).1 exact h diff --git a/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean b/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean index 2f8ad3328e1090..61d9e40861ab29 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean @@ -111,7 +111,7 @@ noncomputable instance : (restrictScalars f).LaxMonoidal := @[simp] lemma restrictScalars_η (r : R) : ε (restrictScalars f) r = f r := by - letI := f.toAlgebra + let := f.toAlgebra dsimp [Adjunction.rightAdjointLaxMonoidal_ε] rw [extendRestrictScalarsAdj_homEquiv_apply, extendScalars_η] erw [AlgebraTensorModule.rid_tmul] diff --git a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean index 96073610f7a15f..e1dc19ba163ba2 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean @@ -136,7 +136,7 @@ lemma IsColimit.ι_smul {cR : Cocone R} (hcR : IsColimit cR) {cM : Cocone M} letI := IsColimit.module R M H hcR hcM cM.ι.app i (r • m) = HSMul.hSMul (α := cR.pt) (β := cM.pt) (cR.ι.app i r) (cM.ι.app i m) := by - letI := filteredColimitsModule R M H + let := filteredColimitsModule R M H let α := IsColimit.coconePointUniqueUpToIso hcM (AddCommGrpCat.FilteredColimits.colimitCoconeIsColimit M) let β := IsColimit.coconePointUniqueUpToIso hcR diff --git a/Mathlib/Algebra/Category/Ring/Epi.lean b/Mathlib/Algebra/Category/Ring/Epi.lean index eb1928f837b191..fbd4bf461dadf5 100644 --- a/Mathlib/Algebra/Category/Ring/Epi.lean +++ b/Mathlib/Algebra/Category/Ring/Epi.lean @@ -34,7 +34,7 @@ lemma CommRingCat.epi_iff_epi {R S : Type u} [CommRing R] [CommRing S] [Algebra simp only [Algebra.algebraMap_eq_smul_one, smul_tmul]) exact RingHom.congr_fun (congrArg Hom.hom this) · refine fun H ↦ ⟨fun {T} f g e ↦ ?_⟩ - letI : Algebra R T := (ofHom (algebraMap R S) ≫ g).hom.toAlgebra + let : Algebra R T := (ofHom (algebraMap R S) ≫ g).hom.toAlgebra let f' : S →ₐ[R] T := ⟨f.hom, RingHom.congr_fun (congrArg Hom.hom e)⟩ let g' : S →ₐ[R] T := ⟨g.hom, fun _ ↦ rfl⟩ ext s diff --git a/Mathlib/Algebra/Category/Ring/FinitePresentation.lean b/Mathlib/Algebra/Category/Ring/FinitePresentation.lean index a6af210fb9b3b5..4094799bcb8e31 100644 --- a/Mathlib/Algebra/Category/Ring/FinitePresentation.lean +++ b/Mathlib/Algebra/Category/Ring/FinitePresentation.lean @@ -83,7 +83,7 @@ lemma RingHom.EssFiniteType.exists_eq_comp_ι_app_of_isColimit (hf : f.hom.Finit ∃ (i : J) (g' : S ⟶ F.obj i), f ≫ g' = α.app i ∧ g = g' ≫ c.ι.app i := by classical have hc' := isColimitOfPreserves (forget _) hc - letI := f.hom.toAlgebra + let := f.hom.toAlgebra obtain ⟨n, hn⟩ := hf let P := CommRingCat.of (MvPolynomial (Fin n) R) let iP : R ⟶ P := CommRingCat.ofHom MvPolynomial.C diff --git a/Mathlib/Algebra/Category/Ring/LinearAlgebra.lean b/Mathlib/Algebra/Category/Ring/LinearAlgebra.lean index d75dbaba623be5..6ac8b2885b8974 100644 --- a/Mathlib/Algebra/Category/Ring/LinearAlgebra.lean +++ b/Mathlib/Algebra/Category/Ring/LinearAlgebra.lean @@ -31,7 +31,7 @@ lemma nontrivial_of_isPushout_of_isField {A B C D : CommRingCat.{u}} (hA : IsField A) {f : A ⟶ B} {g : A ⟶ C} {inl : B ⟶ D} {inr : C ⟶ D} [Nontrivial B] [Nontrivial C] (h : IsPushout f g inl inr) : Nontrivial D := by - letI : Field A := hA.toField + let : Field A := hA.toField algebraize [f.hom, g.hom] let e : D ≅ .of (B ⊗[A] C) := IsColimit.coconePointUniqueUpToIso h.isColimit (CommRingCat.pushoutCoconeIsColimit A B C) diff --git a/Mathlib/Algebra/Central/Basic.lean b/Mathlib/Algebra/Central/Basic.lean index 3f810abca4111e..932b5ef110a970 100644 --- a/Mathlib/Algebra/Central/Basic.lean +++ b/Mathlib/Algebra/Central/Basic.lean @@ -47,7 +47,7 @@ lemma baseField_essentially_unique [Algebra k K] [Algebra K D] [Algebra k D] [IsScalarTower k K D] [IsCentral k D] : Function.Bijective (algebraMap k K) := by - haveI : IsCentral K D := + have : IsCentral K D := { out := fun x ↦ show x ∈ Subalgebra.center k D → _ by simp only [center_eq_bot, mem_bot, Set.mem_range, forall_exists_index] rintro x rfl diff --git a/Mathlib/Algebra/CharP/Algebra.lean b/Mathlib/Algebra/CharP/Algebra.lean index c3fdd42442d0d7..3141dd3a9d40d4 100644 --- a/Mathlib/Algebra/CharP/Algebra.lean +++ b/Mathlib/Algebra/CharP/Algebra.lean @@ -97,16 +97,16 @@ lemma expChar_of_injective_ringHom [NonAssocSemiring R] [NonAssocSemiring A] {f : R →+* A} (h : Function.Injective f) (q : ℕ) [hR : ExpChar R q] : ExpChar A q := by rcases hR with _ | hprime - · haveI := charZero_of_injective_ringHom h; exact .zero - haveI := charP_of_injective_ringHom h q; exact .prime hprime + · have := charZero_of_injective_ringHom h; exact .zero + have := charP_of_injective_ringHom h q; exact .prime hprime /-- If `R →+* A` is injective, and `A` is of exponential characteristic `p`, then `R` is also of exponential characteristic `p`. Similar to `RingHom.charZero`. -/ lemma RingHom.expChar [NonAssocSemiring R] [NonAssocSemiring A] (f : R →+* A) (H : Function.Injective f) (p : ℕ) [ExpChar A p] : ExpChar R p := by cases ‹ExpChar A p› with - | zero => haveI := f.charZero; exact .zero - | prime hp => haveI := f.charP H p; exact .prime hp + | zero => have := f.charZero; exact .zero + | prime hp => have := f.charP H p; exact .prime hp /-- If `R →+* A` is injective, then `R` is of exponential characteristic `p` if and only if `A` is also of exponential characteristic `p`. Similar to `RingHom.charZero_iff`. -/ diff --git a/Mathlib/Algebra/CharP/Defs.lean b/Mathlib/Algebra/CharP/Defs.lean index f875bbc401e213..4e0b15fedbe75f 100644 --- a/Mathlib/Algebra/CharP/Defs.lean +++ b/Mathlib/Algebra/CharP/Defs.lean @@ -156,7 +156,7 @@ namespace ringChar variable [NonAssocSemiring R] lemma spec : ∀ x : ℕ, (x : R) = 0 ↔ ringChar R ∣ x := by - letI : CharP R (ringChar R) := (Classical.choose_spec (CharP.existsUnique R)).1 + let : CharP R (ringChar R) := (Classical.choose_spec (CharP.existsUnique R)).1 exact CharP.cast_eq_zero_iff R (ringChar R) lemma eq (p : ℕ) [C : CharP R p] : ringChar R = p := @@ -388,7 +388,7 @@ noncomputable def ringExpChar : ℕ := max (ringChar R) 1 lemma ringExpChar.eq (q : ℕ) [h : ExpChar R q] : ringExpChar R = q := by rcases h with _ | h - · haveI := CharP.ofCharZero R + · have := CharP.ofCharZero R rw [ringExpChar, ringChar.eq R 0]; rfl rw [ringExpChar, ringChar.eq R q] exact Nat.max_eq_left h.one_lt.le diff --git a/Mathlib/Algebra/CharP/Invertible.lean b/Mathlib/Algebra/CharP/Invertible.lean index 7b36b94527fc62..2f2598a2400b9d 100644 --- a/Mathlib/Algebra/CharP/Invertible.lean +++ b/Mathlib/Algebra/CharP/Invertible.lean @@ -65,7 +65,7 @@ def invertibleOfCoprime {n : ℕ} (h : n.Coprime p) : theorem invOf_eq_of_coprime {n : ℕ} [Invertible (n : R)] (h : n.Coprime p) : ⅟(n : R) = n.gcdA p := by - letI : Invertible (n : R) := invertibleOfCoprime h + let : Invertible (n : R) := invertibleOfCoprime h convert! (rfl : ⅟(n : R) = _) theorem CharP.isUnit_natCast_iff {n : ℕ} (hp : p.Prime) : IsUnit (n : R) ↔ ¬p ∣ n where diff --git a/Mathlib/Algebra/CharP/Lemmas.lean b/Mathlib/Algebra/CharP/Lemmas.lean index c5f7ad678800e2..a824b4a0dc2a5d 100644 --- a/Mathlib/Algebra/CharP/Lemmas.lean +++ b/Mathlib/Algebra/CharP/Lemmas.lean @@ -285,7 +285,7 @@ variable (R) [NonAssocRing R] /-- The characteristic of a finite ring cannot be zero. -/ theorem char_ne_zero_of_finite (p : ℕ) [CharP R p] [Finite R] : p ≠ 0 := by rintro rfl - haveI : CharZero R := charP_to_charZero R + have : CharZero R := charP_to_charZero R exact absurd Nat.cast_injective (not_injective_infinite_finite ((↑) : ℕ → R)) theorem ringChar_ne_zero_of_finite [Finite R] : ringChar R ≠ 0 := diff --git a/Mathlib/Algebra/CharP/LocalRing.lean b/Mathlib/Algebra/CharP/LocalRing.lean index e741303f7b6b22..d9a382728f54a8 100644 --- a/Mathlib/Algebra/CharP/LocalRing.lean +++ b/Mathlib/Algebra/CharP/LocalRing.lean @@ -30,7 +30,7 @@ theorem charP_zero_or_prime_power (R : Type*) [CommRing R] [IsLocalRing R] (q : apply or_iff_not_imp_left.2 intro q_pos let K := IsLocalRing.ResidueField R - haveI RM_char := ringChar.charP K + have RM_char := ringChar.charP K let r := ringChar K let n := q.factorization r -- `r := char(R/m)` is either prime or zero: @@ -58,9 +58,9 @@ theorem charP_zero_or_prime_power (R : Type*) [CommRing R] [IsLocalRing R] (q : absurd (by simpa [n_zero] using q_eq_rn) (CharP.char_ne_one R q) -- Definition of prime power: `∃ r n, Prime r ∧ 0 < n ∧ r ^ n = q`. exact ⟨r, ⟨n, ⟨r_prime.prime, ⟨pos_iff_ne_zero.mpr n_pos, q_eq_rn.symm⟩⟩⟩⟩ - · haveI K_char_p_0 := ringChar.of_eq r_zero - haveI K_char_zero : CharZero K := CharP.charP_to_charZero K - haveI R_char_zero := RingHom.charZero (IsLocalRing.residue R) + · have K_char_p_0 := ringChar.of_eq r_zero + have K_char_zero : CharZero K := CharP.charP_to_charZero K + have R_char_zero := RingHom.charZero (IsLocalRing.residue R) -- Finally, `r = 0` would lead to a contradiction: have q_zero := CharP.eq R char_R_q (CharP.ofCharZero R) exact absurd q_zero q_pos diff --git a/Mathlib/Algebra/CharP/MixedCharZero.lean b/Mathlib/Algebra/CharP/MixedCharZero.lean index 6d184970dc9fdb..25e505bb05cced 100644 --- a/Mathlib/Algebra/CharP/MixedCharZero.lean +++ b/Mathlib/Algebra/CharP/MixedCharZero.lean @@ -278,7 +278,7 @@ theorem nonempty_algebraRat_iff : Nonempty (Algebra ℚ R) ↔ ∀ I : Ideal R, I ≠ ⊤ → CharZero (R ⧸ I) := by constructor · intro h_alg - haveI h_alg' : Algebra ℚ R := h_alg.some + have h_alg' : Algebra ℚ R := h_alg.some apply of_algebraRat · intro h apply Nonempty.intro @@ -333,7 +333,7 @@ theorem split_by_characteristic (h_pos : ∀ p : ℕ, p ≠ 0 → CharP R p → | intro p p_charP => by_cases h : p = 0 · rw [h] at p_charP - haveI h0 : CharZero R := CharP.charP_to_charZero R + have h0 : CharZero R := CharP.charP_to_charZero R exact split_equalCharZero_mixedCharZero R h_equal h_mixed · exact h_pos p h p_charP diff --git a/Mathlib/Algebra/CharP/Quotient.lean b/Mathlib/Algebra/CharP/Quotient.lean index 8372e3c8a1599e..e2ab5e0b296440 100644 --- a/Mathlib/Algebra/CharP/Quotient.lean +++ b/Mathlib/Algebra/CharP/Quotient.lean @@ -72,5 +72,5 @@ theorem Ideal.Quotient.index_eq_zero (I : Ideal R) : (↑I.toAddSubgroup.index : rw [AddSubgroup.index, Nat.card_eq] split_ifs with hq; swap · simp - letI : Fintype (R ⧸ I) := @Fintype.ofFinite _ hq + let : Fintype (R ⧸ I) := @Fintype.ofFinite _ hq exact Nat.cast_card_eq_zero (R ⧸ I) diff --git a/Mathlib/Algebra/DirectSum/Decomposition.lean b/Mathlib/Algebra/DirectSum/Decomposition.lean index 32e9581ec7509f..ab7887ab66ded5 100644 --- a/Mathlib/Algebra/DirectSum/Decomposition.lean +++ b/Mathlib/Algebra/DirectSum/Decomposition.lean @@ -108,7 +108,7 @@ protected theorem Decomposition.inductionOn {motive : M → Prop} (zero : motive (add : ∀ m m' : M, motive m → motive m' → motive (m + m')) : ∀ m, motive m := by let ℳ' : ι → AddSubmonoid M := fun i ↦ (⟨⟨ℳ i, fun x y ↦ AddMemClass.add_mem x y⟩, (ZeroMemClass.zero_mem _)⟩ : AddSubmonoid M) - haveI t : DirectSum.Decomposition ℳ' := + have t : DirectSum.Decomposition ℳ' := { decompose' := DirectSum.decompose ℳ left_inv := fun _ ↦ (decompose ℳ).left_inv _ right_inv := fun _ ↦ (decompose ℳ).right_inv _ } diff --git a/Mathlib/Algebra/DualNumber.lean b/Mathlib/Algebra/DualNumber.lean index 561d689b864acd..b45c31f70b77dd 100644 --- a/Mathlib/Algebra/DualNumber.lean +++ b/Mathlib/Algebra/DualNumber.lean @@ -127,7 +127,7 @@ on `R` and its value on `ε`. -/ lemma ringHom_ext {R' : Type*} [CommSemiring R'] {f g : R[ε] →+* R'} (h₀ : f.comp (algebraMap R R[ε]) = g.comp (algebraMap R R[ε])) (hε : f ε = g ε) : f = g := by - letI : Algebra R R' := by + let : Algebra R R' := by letI := f.toAlgebra exact Algebra.compHom _ (algebraMap R R[ε]) let f' : R[ε] →ₐ[R] R' := diff --git a/Mathlib/Algebra/EuclideanDomain/Basic.lean b/Mathlib/Algebra/EuclideanDomain/Basic.lean index ca7cbc827090dc..1af3e541f14667 100644 --- a/Mathlib/Algebra/EuclideanDomain/Basic.lean +++ b/Mathlib/Algebra/EuclideanDomain/Basic.lean @@ -55,7 +55,7 @@ theorem mod_eq_zero {a b : R} : a % b = 0 ↔ b ∣ a := rw [← div_add_mod a b, h, add_zero] exact dvd_mul_right _ _, fun ⟨c, e⟩ => by rw [e, ← add_left_cancel_iff, div_add_mod, add_zero] - haveI := Classical.dec + have := Classical.dec by_cases b0 : b = 0 · simp only [b0, zero_mul] · rw [mul_div_cancel_left₀ _ b0]⟩ diff --git a/Mathlib/Algebra/Exact/Basic.lean b/Mathlib/Algebra/Exact/Basic.lean index c06babd2e4c995..5aae5f12791023 100644 --- a/Mathlib/Algebra/Exact/Basic.lean +++ b/Mathlib/Algebra/Exact/Basic.lean @@ -90,7 +90,7 @@ may not apply if the zero of `Set.range g` is not definitionally equal to `⟨0, lemma iff_rangeFactorization [One P] (hg : 1 ∈ Set.range g) : letI : One (Set.range g) := ⟨⟨1, hg⟩⟩ MulExact f g ↔ MulExact ((↑) : Set.range f → N) (Set.rangeFactorization g) := by - letI : One (Set.range g) := ⟨⟨1, hg⟩⟩ + let : One (Set.range g) := ⟨⟨1, hg⟩⟩ have : ((1 : Set.range g) : P) = 1 := rfl simp [MulExact, Subtype.ext_iff, this] diff --git a/Mathlib/Algebra/Exact/Sequence.lean b/Mathlib/Algebra/Exact/Sequence.lean index 5cc990339f1579..2987f4d772de49 100644 --- a/Mathlib/Algebra/Exact/Sequence.lean +++ b/Mathlib/Algebra/Exact/Sequence.lean @@ -84,14 +84,14 @@ private lemma sum_neg_one_pow_finrank_eq_zero_of_exact_six_aux {V₀ V₁ V₂ V (surj : Surjective f₄) : (finrank k V₀ : ℤ) - finrank k V₁ + finrank k V₂ - finrank k V₃ + finrank k V₄ - finrank k V₅ = 0 := by - letI Vs := ![V₀, V₁, V₂, V₃, V₄, V₅] - letI (i : Fin 6) : AddCommGroup (Vs i) := match i with + let Vs := ![V₀, V₁, V₂, V₃, V₄, V₅] + let (i : Fin 6) : AddCommGroup (Vs i) := match i with | 0 => ‹_› | 1 => ‹_› | 2 => ‹_› | 3 => ‹_› | 4 => ‹_› | 5 => ‹_› - letI (i : Fin 6) : Module k (Vs i) := match i with + let (i : Fin 6) : Module k (Vs i) := match i with | 0 => ‹_› | 1 => ‹_› | 2 => ‹_› | 3 => ‹_› | 4 => ‹_› | 5 => ‹_› have (i : Fin 6) : FiniteDimensional k (Vs i) := match i with | 0 => ‹_› | 1 => ‹_› | 2 => ‹_› | 3 => ‹_› | 4 => ‹_› | 5 => ‹_› - letI fs (i : Fin 5) : Vs i.castSucc →ₗ[k] Vs i.succ := match i with + let fs (i : Fin 5) : Vs i.castSucc →ₗ[k] Vs i.succ := match i with | 0 => f₀ | 1 => f₁ | 2 => f₂ | 3 => f₃ | 4 => f₄ simpa [Fin.sum_univ_six] using! Module.sum_neg_one_pow_finrank_eq_zero_of_exact Vs fs inj (fun i ↦ by fin_cases i; exacts [exact₁, exact₂, exact₃, exact₄]) surj diff --git a/Mathlib/Algebra/Field/Subfield/Basic.lean b/Mathlib/Algebra/Field/Subfield/Basic.lean index a2b1f72211ab4f..4c2d2f09e3d340 100644 --- a/Mathlib/Algebra/Field/Subfield/Basic.lean +++ b/Mathlib/Algebra/Field/Subfield/Basic.lean @@ -424,7 +424,7 @@ theorem coe_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Subfield K} (h theorem mem_sSup_of_directedOn {S : Set (Subfield K)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : K} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, Subtype.exists, exists_prop] theorem coe_sSup_of_directedOn {S : Set (Subfield K)} (Sne : S.Nonempty) diff --git a/Mathlib/Algebra/Group/Subgroup/Finite.lean b/Mathlib/Algebra/Group/Subgroup/Finite.lean index caee3abfd81122..8e1697265de47d 100644 --- a/Mathlib/Algebra/Group/Subgroup/Finite.lean +++ b/Mathlib/Algebra/Group/Subgroup/Finite.lean @@ -217,7 +217,7 @@ section Normalizer theorem mem_normalizer_fintype {S : Set G} [Finite S] {x : G} (h : ∀ n, n ∈ S → x * n * x⁻¹ ∈ S) : x ∈ Subgroup.normalizer S := by - haveI := Classical.propDecidable; cases nonempty_fintype S + have := Classical.propDecidable; cases nonempty_fintype S exact fun n => ⟨h n, fun h₁ => have heq : (fun n => x * n * x⁻¹) '' S = S := diff --git a/Mathlib/Algebra/Group/Subgroup/Lattice.lean b/Mathlib/Algebra/Group/Subgroup/Lattice.lean index 04aeb1ddde5112..0101300c46195a 100644 --- a/Mathlib/Algebra/Group/Subgroup/Lattice.lean +++ b/Mathlib/Algebra/Group/Subgroup/Lattice.lean @@ -579,7 +579,7 @@ theorem coe_iSup_of_directed {ι} [Nonempty ι] {S : ι → Subgroup G} (hS : Di @[to_additive] theorem mem_sSup_of_directedOn {K : Set (Subgroup G)} (Kne : K.Nonempty) (hK : DirectedOn (· ≤ ·) K) {x : G} : x ∈ sSup K ↔ ∃ s ∈ K, x ∈ s := by - haveI : Nonempty K := Kne.to_subtype + have : Nonempty K := Kne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hK.directed_val, SetCoe.exists, exists_prop] @[to_additive] diff --git a/Mathlib/Algebra/Group/Submonoid/Membership.lean b/Mathlib/Algebra/Group/Submonoid/Membership.lean index 0e5c544e78d9ea..e9e109c8842c1a 100644 --- a/Mathlib/Algebra/Group/Submonoid/Membership.lean +++ b/Mathlib/Algebra/Group/Submonoid/Membership.lean @@ -88,7 +88,7 @@ theorem coe_iSup_of_directed {ι} [Nonempty ι] {S : ι → Submonoid M} (hS : D @[to_additive] theorem mem_sSup_of_directedOn {S : Set (Submonoid M)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : M} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val] @[to_additive] diff --git a/Mathlib/Algebra/Group/TransferInstance.lean b/Mathlib/Algebra/Group/TransferInstance.lean index 023e3826f2583a..918e34d382f4df 100644 --- a/Mathlib/Algebra/Group/TransferInstance.lean +++ b/Mathlib/Algebra/Group/TransferInstance.lean @@ -131,21 +131,21 @@ protected abbrev commSemigroup [CommSemigroup β] : CommSemigroup α := by protected lemma isLeftCancelMul [Mul β] [IsLeftCancelMul β] : letI := e.mul IsLeftCancelMul α := by - letI := e.mul; exact e.injective.isLeftCancelMul _ fun _ _ ↦ e.apply_symm_apply _ + let := e.mul; exact e.injective.isLeftCancelMul _ fun _ _ ↦ e.apply_symm_apply _ /-- Transfer `IsRightCancelMul` across an `Equiv` -/ @[to_additive /-- Transfer `IsRightCancelAdd` across an `Equiv` -/] protected lemma isRightCancelMul [Mul β] [IsRightCancelMul β] : letI := e.mul IsRightCancelMul α := by - letI := e.mul; exact e.injective.isRightCancelMul _ fun _ _ ↦ e.apply_symm_apply _ + let := e.mul; exact e.injective.isRightCancelMul _ fun _ _ ↦ e.apply_symm_apply _ /-- Transfer `IsCancelMul` across an `Equiv` -/ @[to_additive /-- Transfer `IsCancelAdd` across an `Equiv` -/] protected lemma isCancelMul [Mul β] [IsCancelMul β] : letI := e.mul IsCancelMul α := by - letI := e.mul; exact e.injective.isCancelMul _ fun _ _ ↦ e.apply_symm_apply _ + let := e.mul; exact e.injective.isCancelMul _ fun _ _ ↦ e.apply_symm_apply _ /-- Transfer `MulOneClass` across an `Equiv` -/ @[to_additive /-- Transfer `AddZeroClass` across an `Equiv` -/] @@ -204,7 +204,7 @@ lemma exists_type_univ_nonempty_mulEquiv.{u, v} (G : Type u) [Group G] [Finite G obtain ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin G let f : Fin n ≃ ULift (Fin n) := Equiv.ulift.symm let e : G ≃ ULift (Fin n) := e.trans f - letI groupH : Group (ULift (Fin n)) := e.symm.group + let groupH : Group (ULift (Fin n)) := e.symm.group exact ⟨ULift (Fin n), groupH, inferInstance, ⟨MulEquiv.symm <| e.symm.mulEquiv⟩⟩ end Finite diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 56b8a7c83daa15..6b9c84d330b1bd 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -135,10 +135,10 @@ instance Functor.mapHomologicalComplex_reflects_iso (F : W₁ ⥤ W₂) [F.Prese ReflectsIsomorphisms (F.mapHomologicalComplex c) := ⟨fun f => by intro - haveI : ∀ n : ι, IsIso (F.map (f.f n)) := fun n => + have : ∀ n : ι, IsIso (F.map (f.f n)) := fun n => ((HomologicalComplex.eval W₂ c n).mapIso (asIso ((F.mapHomologicalComplex c).map f))).isIso_hom - haveI := fun n => isIso_of_reflects_iso (f.f n) F + have := fun n => isIso_of_reflects_iso (f.f n) F exact HomologicalComplex.Hom.isIso_of_components f⟩ instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] : diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean index ff26fc2ef8b227..f63799346ef521 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean @@ -91,7 +91,7 @@ lemma hasExt_of_hasDerivedCategory [HasDerivedCategory.{w} C] : HasExt.{w} C := infer_instance lemma HasExt.standard : HasExt.{max u v} C := by - letI := HasDerivedCategory.standard + let := HasDerivedCategory.standard exact hasExt_of_hasDerivedCategory _ set_option backward.isDefEq.respectTransparency false in @@ -192,7 +192,7 @@ lemma mk₀_hom [HasDerivedCategory.{w'} C] (f : X ⟶ Y) : @[simp] lemma mk₀_comp_mk₀ (f : X ⟶ Y) (g : Y ⟶ Z) : (mk₀ f).comp (mk₀ g) (zero_add 0) = mk₀ (f ≫ g) := by - letI := HasDerivedCategory.standard C; ext; simp + let := HasDerivedCategory.standard C; ext; simp @[simp] lemma mk₀_comp_mk₀_assoc (f : X ⟶ Y) (g : Y ⟶ Z) {n : ℕ} (α : Ext Z T n) : @@ -204,7 +204,7 @@ lemma mk₀_comp_mk₀_assoc (f : X ⟶ Y) (g : Y ⟶ Z) {n : ℕ} (α : Ext Z T variable (X Y) in lemma mk₀_bijective : Function.Bijective (mk₀ (X := X) (Y := Y)) := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have h : (singleFunctor C 0).FullyFaithful := Functor.FullyFaithful.ofFullyFaithful _ let e : (X ⟶ Y) ≃ Ext X Y 0 := (h.homEquiv.trans (ShiftedHom.homEquiv _ (by simp))).trans homEquiv.symm @@ -268,51 +268,51 @@ private lemma zero_hom' : (0 : Ext X Y n).hom' = 0 := @[simp] lemma add_comp (α₁ α₂ : Ext X Y n) {m : ℕ} (β : Ext Y Z m) {p : ℕ} (h : n + m = p) : (α₁ + α₂).comp β h = α₁.comp β h + α₂.comp β h := by - letI := HasDerivedCategory.standard C; ext; simp [this, add_hom'] + let := HasDerivedCategory.standard C; ext; simp [this, add_hom'] @[simp] lemma comp_add (α : Ext X Y n) {m : ℕ} (β₁ β₂ : Ext Y Z m) {p : ℕ} (h : n + m = p) : α.comp (β₁ + β₂) h = α.comp β₁ h + α.comp β₂ h := by - letI := HasDerivedCategory.standard C; ext; simp [this, add_hom'] + let := HasDerivedCategory.standard C; ext; simp [this, add_hom'] @[simp] lemma neg_comp (α : Ext X Y n) {m : ℕ} (β : Ext Y Z m) {p : ℕ} (h : n + m = p) : (-α).comp β h = -α.comp β h := by - letI := HasDerivedCategory.standard C; ext; simp [this, neg_hom'] + let := HasDerivedCategory.standard C; ext; simp [this, neg_hom'] @[simp] lemma comp_neg (α : Ext X Y n) {m : ℕ} (β : Ext Y Z m) {p : ℕ} (h : n + m = p) : α.comp (-β) h = -α.comp β h := by - letI := HasDerivedCategory.standard C; ext; simp [this, neg_hom'] + let := HasDerivedCategory.standard C; ext; simp [this, neg_hom'] variable (X n) in @[simp] lemma zero_comp {m : ℕ} (β : Ext Y Z m) (p : ℕ) (h : n + m = p) : (0 : Ext X Y n).comp β h = 0 := by - letI := HasDerivedCategory.standard C; ext; simp [this, zero_hom'] + let := HasDerivedCategory.standard C; ext; simp [this, zero_hom'] @[simp] lemma comp_zero (α : Ext X Y n) (Z : C) (m : ℕ) (p : ℕ) (h : n + m = p) : α.comp (0 : Ext Y Z m) h = 0 := by - letI := HasDerivedCategory.standard C; ext; simp [this, zero_hom'] + let := HasDerivedCategory.standard C; ext; simp [this, zero_hom'] @[simp] lemma mk₀_id_comp (α : Ext X Y n) : (mk₀ (𝟙 X)).comp α (zero_add n) = α := by - letI := HasDerivedCategory.standard C; ext; simp + let := HasDerivedCategory.standard C; ext; simp @[simp] lemma comp_mk₀_id (α : Ext X Y n) : α.comp (mk₀ (𝟙 Y)) (add_zero n) = α := by - letI := HasDerivedCategory.standard C; ext; simp + let := HasDerivedCategory.standard C; ext; simp variable (X Y) in @[simp] lemma mk₀_zero : mk₀ (0 : X ⟶ Y) = 0 := by - letI := HasDerivedCategory.standard C; ext; simp [zero_hom'] + let := HasDerivedCategory.standard C; ext; simp [zero_hom'] lemma mk₀_add (f g : X ⟶ Y) : mk₀ (f + g) = mk₀ f + mk₀ g := by - letI := HasDerivedCategory.standard C; ext; simp [add_hom', ShiftedHom.mk₀] + let := HasDerivedCategory.standard C; ext; simp [add_hom', ShiftedHom.mk₀] /-- The additive bijection `Ext X Y 0 ≃+ (X ⟶ Y)`. -/ @[simps! symm_apply] @@ -333,7 +333,7 @@ lemma mk₀_eq_zero_iff {M N : C} (f : M ⟶ N) : @[simp] lemma mk₀_neg (f : X ⟶ Y) : mk₀ (-f) = -mk₀ f := by - letI := HasDerivedCategory.standard C; ext; simp [neg_hom'] + let := HasDerivedCategory.standard C; ext; simp [neg_hom'] section @@ -342,7 +342,7 @@ lemma biprod_ext {X₁ X₂ : C} {α β : Ext (X₁ ⊞ X₂) Y n} (h₁ : (mk₀ biprod.inl).comp α (zero_add n) = (mk₀ biprod.inl).comp β (zero_add n)) (h₂ : (mk₀ biprod.inr).comp α (zero_add n) = (mk₀ biprod.inr).comp β (zero_add n)) : α = β := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C rw [Ext.ext_iff] at h₁ h₂ ⊢ simp only [comp_hom, mk₀_hom, ShiftedHom.mk₀_comp] at h₁ h₂ apply BinaryCofan.IsColimit.hom_ext @@ -557,7 +557,7 @@ open Abelian variable (C) in lemma hasExt_iff_small_ext : HasExt.{w'} C ↔ ∀ (X Y : C) (n : ℕ), Small.{w'} (Ext.{w} X Y n) := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C simp only [hasExt_iff, small_congr Ext.homEquiv] constructor · intro h X Y n diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughInjectives.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughInjectives.lean index 4de85b619e0a04..d7b9f8c1a97059 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughInjectives.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughInjectives.lean @@ -101,7 +101,7 @@ lemma eq_zero_of_injective [HasExt.{w} C] {X I : C} {n : ℕ} [Injective I] (e : Ext X I (n + 1)) : e = 0 := by let K := (CochainComplex.singleFunctor C 0).obj X have := K.isStrictlyGE_of_ge (-n) 0 (by lia) - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C apply homEquiv.injective simp only [← cancel_mono (((singleFunctors C).shiftIso (n + 1) (-(n + 1)) 0 (by lia)).hom.app _), zero_hom, Limits.zero_comp] @@ -125,7 +125,7 @@ instances, we would have to specify the universe explicitly almost everywhere, which would be an inconvenience. Then, we must be very selective regarding `HasExt` instances. -/ lemma hasExt_of_enoughInjectives [LocallySmall.{w} C] [EnoughInjectives C] : HasExt.{w} C := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := hasExt_of_hasDerivedCategory C rw [hasExt_iff_small_ext.{w}] intro X Y n diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughProjectives.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughProjectives.lean index ee9256913f59a8..2dc52050bd2d7d 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughProjectives.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/EnoughProjectives.lean @@ -99,7 +99,7 @@ open DerivedCategory set_option backward.isDefEq.respectTransparency false in lemma eq_zero_of_projective [HasExt.{w} C] {P Y : C} {n : ℕ} [Projective P] (e : Ext P Y (n + 1)) : e = 0 := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C apply homEquiv.injective simp only [← cancel_mono (((singleFunctors C).shiftIso (n + 1) (-(n + 1)) 0 (by lia)).hom.app _), zero_hom, Limits.zero_comp] @@ -124,7 +124,7 @@ instances, we would have to specify the universe explicitly almost everywhere, which would be an inconvenience. Then, we must be very selective regarding `HasExt` instances. -/ lemma hasExt_of_enoughProjectives [LocallySmall.{w} C] [EnoughProjectives C] : HasExt.{w} C := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := hasExt_of_hasDerivedCategory C rw [hasExt_iff_small_ext.{w}] intro X Y n diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean index 2f6cac77be8ef4..565031ebfe26c7 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean @@ -67,7 +67,7 @@ lemma covariant_sequence_exact₂' (n : ℕ) : dsimp simp only [comp_assoc_of_third_deg_zero, mk₀_comp_mk₀, ShortComplex.zero, mk₀_zero, comp_zero])).Exact := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := (preadditiveCoyoneda.obj (op ((singleFunctor C 0).obj X))).homologySequence_exact₂ _ (hS.singleTriangle_distinguished) n rw [ShortComplex.ab_exact_iff_function_exact] at this ⊢ @@ -88,7 +88,7 @@ lemma covariant_sequence_exact₃' : dsimp simp only [comp_assoc_of_second_deg_zero, ShortComplex.ShortExact.comp_extClass, comp_zero])).Exact := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := (preadditiveCoyoneda.obj (op ((singleFunctor C 0).obj X))).homologySequence_exact₃ _ (hS.singleTriangle_distinguished) n₀ n₁ (by lia) rw [ShortComplex.ab_exact_iff_function_exact] at this ⊢ @@ -108,7 +108,7 @@ lemma covariant_sequence_exact₁' : dsimp simp only [comp_assoc_of_third_deg_zero, ShortComplex.ShortExact.extClass_comp, comp_zero])).Exact := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := (preadditiveCoyoneda.obj (op ((singleFunctor C 0).obj X))).homologySequence_exact₁ _ (hS.singleTriangle_distinguished) n₀ n₁ (by lia) rw [ShortComplex.ab_exact_iff_function_exact] at this ⊢ @@ -204,7 +204,7 @@ lemma contravariant_sequence_exact₂' (n : ℕ) : ext dsimp simp only [mk₀_comp_mk₀_assoc, ShortComplex.zero, mk₀_zero, zero_comp])).Exact := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := (preadditiveYoneda.obj ((singleFunctor C 0).obj Y)).homologySequence_exact₂ _ (op_distinguished _ hS.singleTriangle_distinguished) n rw [ShortComplex.ab_exact_iff_function_exact] at this ⊢ @@ -224,7 +224,7 @@ lemma contravariant_sequence_exact₁' : ext dsimp simp only [ShortComplex.ShortExact.extClass_comp_assoc])).Exact := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := (preadditiveYoneda.obj ((singleFunctor C 0).obj Y)).homologySequence_exact₃ _ (op_distinguished _ hS.singleTriangle_distinguished) n₀ n₁ (by lia) rw [ShortComplex.ab_exact_iff_function_exact] at this ⊢ @@ -241,7 +241,7 @@ lemma contravariant_sequence_exact₃' : ext dsimp simp only [ShortComplex.ShortExact.comp_extClass_assoc])).Exact := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C have := (preadditiveYoneda.obj ((singleFunctor C 0).obj Y)).homologySequence_exact₁ _ (op_distinguished _ hS.singleTriangle_distinguished) n₀ n₁ (by lia) rw [ShortComplex.ab_exact_iff_function_exact] at this ⊢ diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExtClass.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExtClass.lean index 4e34a0c256f55b..8a82a5f8467b09 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExtClass.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExtClass.lean @@ -102,7 +102,7 @@ end @[simp] lemma comp_extClass : (Ext.mk₀ S.g).comp hS.extClass (zero_add 1) = 0 := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C ext simp only [Ext.comp_hom, Ext.mk₀_hom, extClass_hom, Ext.zero_hom, ShiftedHom.mk₀_comp] @@ -116,7 +116,7 @@ lemma comp_extClass_assoc {Y : C} {n : ℕ} (γ : Ext S.X₁ Y n) {n' : ℕ} (h @[simp] lemma extClass_comp : hS.extClass.comp (Ext.mk₀ S.f) (add_zero 1) = 0 := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C ext simp only [Ext.comp_hom, Ext.mk₀_hom, extClass_hom, Ext.zero_hom, ShiftedHom.comp_mk₀] @@ -132,7 +132,7 @@ lemma extClass_naturality {S₁ S₂ : ShortComplex C} (h₁ : S₁.ShortExact) (h₂ : S₂.ShortExact) (f : S₁ ⟶ S₂) : h₁.extClass.comp (Ext.mk₀ f.τ₁) (add_zero 1) = (Ext.mk₀ f.τ₃).comp h₂.extClass (zero_add 1) := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C ext simpa [ShiftedHom.comp_mk₀, ShiftedHom.mk₀_comp] using! (singleTriangle.map h₁ h₂ f).comm₃ diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean index 73889aef11cd9a..27705d8ad2371a 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -44,7 +44,7 @@ lemma hasSmallLocalizedShiftedHom_of_isLE_of_isGE (a b : ℤ) [K.IsGE a] [K.IsLE a] [L.IsGE b] [L.IsLE b] : HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := by - letI := HasDerivedCategory.standard + let := HasDerivedCategory.standard obtain ⟨X, ⟨eX⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj K) a obtain ⟨Y, ⟨eY⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj L) b simp only [hasSmallLocalizedShiftedHom_iff _ _ Q] diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index e9e9457c504b1d..221f901691d12c 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -69,7 +69,7 @@ variable (K L : CochainComplex C ℤ) (n : ℤ) set_option backward.isDefEq.respectTransparency false in lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C rw [← Function.Bijective.of_comp_iff' (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean index a97dc2065d1291..62bc40a28b8297 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean @@ -70,7 +70,7 @@ variable (K L : CochainComplex C ℤ) (n : ℤ) set_option backward.isDefEq.respectTransparency false in lemma bijective_toSmallShiftedHom_of_isKProjective [K.IsKProjective] : Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C rw [← Function.Bijective.of_comp_iff' (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean b/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean index 8c977e12d1cf47..b56ffa0b408a35 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean @@ -40,7 +40,7 @@ to the `x`. -/ noncomputable def toSmallShiftedHom (x : CohomologyClass K L n) : SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := Quotient.lift (fun y ↦ SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm y)) (by - letI := HasDerivedCategory.standard C + let := HasDerivedCategory.standard C intro y₁ y₂ h refine (SmallShiftedHom.equiv _ DerivedCategory.Q).injective ?_ simp only [SmallShiftedHom.equiv_mk, ShiftedHom.map] diff --git a/Mathlib/Algebra/Homology/HomotopyCofiber.lean b/Mathlib/Algebra/Homology/HomotopyCofiber.lean index 96920cb78c75bc..36be79f5f5c90a 100644 --- a/Mathlib/Algebra/Homology/HomotopyCofiber.lean +++ b/Mathlib/Algebra/Homology/HomotopyCofiber.lean @@ -83,7 +83,7 @@ lemma isZero_X (i : ι) (hG : IsZero (G.X i)) (hF : ∀ (j : ι), c.Rel i j → IsZero (F.X j)) : IsZero (X φ i) := by by_cases h : c.Rel i (c.next i) - · haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ h + · have := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ h refine IsZero.of_iso ?_ (XIsoBiprod φ _ _ h) simp only [biprod_isZero_iff] exact ⟨hF _ h, hG⟩ @@ -149,7 +149,7 @@ lemma inrX_fstX (i j : ι) (hij : c.Rel i j) : lemma inlX_XIsoBiprod_hom (i j : ι) (hij : c.Rel j i) : haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij inlX φ i j hij ≫ (XIsoBiprod φ j i hij).hom = biprod.inl := by - haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + have := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij simp [inlX] @[reassoc (attr := simp)] @@ -163,7 +163,7 @@ lemma inrX_XIsoBiprod_hom (i j : ι) (hij : c.Rel j i) : haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij inrX φ j ≫ (XIsoBiprod φ j i hij).hom = biprod.inr := by obtain rfl := c.next_eq' hij - haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + have := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij simp [inrX, XIsoBiprod, dif_pos hij] @[reassoc (attr := simp)] @@ -184,7 +184,7 @@ noncomputable def d (i j : ι) : X φ i ⟶ X φ j := lemma ext_to_X (i j : ι) (hij : c.Rel i j) {A : C} {f g : A ⟶ X φ i} (h₁ : f ≫ fstX φ i j hij = g ≫ fstX φ i j hij) (h₂ : f ≫ sndX φ i = g ≫ sndX φ i) : f = g := by - haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + have := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij rw [← cancel_mono (XIsoBiprod φ i j hij).hom] apply biprod.hom_ext · simpa using! h₁ @@ -199,7 +199,7 @@ lemma ext_to_X' (i : ι) (hi : ¬ c.Rel i (c.next i)) {A : C} {f g : A ⟶ X φ lemma ext_from_X (i j : ι) (hij : c.Rel j i) {A : C} {f g : X φ j ⟶ A} (h₁ : inlX φ i j hij ≫ f = inlX φ i j hij ≫ g) (h₂ : inrX φ j ≫ f = inrX φ j ≫ g) : f = g := by - haveI := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij + have := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij rw [← cancel_epi (XIsoBiprod φ j i hij).inv] apply biprod.hom_ext' · simpa diff --git a/Mathlib/Algebra/Homology/ImageToKernel.lean b/Mathlib/Algebra/Homology/ImageToKernel.lean index 47916e78e08c29..000ea09d602d06 100644 --- a/Mathlib/Algebra/Homology/ImageToKernel.lean +++ b/Mathlib/Algebra/Homology/ImageToKernel.lean @@ -137,7 +137,7 @@ instance imageToKernel_epi_of_zero_of_mono [HasKernels V] [HasZeroObject V] [Mon instance imageToKernel_epi_of_epi_of_zero [HasImages V] [Epi f] : Epi (imageToKernel f (0 : B ⟶ C) (by simp)) := by simp only [imageToKernel_zero_right] - haveI := epi_image_of_epi f + have := epi_image_of_epi f rw [← imageSubobject_arrow] infer_instance diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index fee0ba6b919258..9916143396dc42 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -92,12 +92,12 @@ variable {S} lemma HomologyData.exact_iff (h : S.HomologyData) : S.Exact ↔ IsZero h.left.H := by - haveI := HasHomology.mk' h + have := HasHomology.mk' h exact LeftHomologyData.exact_iff h.left lemma HomologyData.exact_iff' (h : S.HomologyData) : S.Exact ↔ IsZero h.right.H := by - haveI := HasHomology.mk' h + have := HasHomology.mk' h exact RightHomologyData.exact_iff h.right variable (S) @@ -148,7 +148,7 @@ variable {S} lemma HomologyData.exact_iff_i_p_zero (h : S.HomologyData) : S.Exact ↔ h.left.i ≫ h.right.p = 0 := by - haveI := HasHomology.mk' h + have := HasHomology.mk' h rw [h.left.exact_iff, ← h.comm] constructor · intro z @@ -171,8 +171,8 @@ lemma exact_iff_iCycles_pOpcycles_zero [S.HasHomology] : lemma exact_iff_kernel_ι_comp_cokernel_π_zero [S.HasHomology] [HasKernel S.g] [HasCokernel S.f] : S.Exact ↔ kernel.ι S.g ≫ cokernel.π S.f = 0 := by - haveI := HasLeftHomology.hasCokernel S - haveI := HasRightHomology.hasKernel S + have := HasLeftHomology.hasCokernel S + have := HasRightHomology.hasKernel S exact S.exact_iff_i_p_zero (LeftHomologyData.ofHasKernelOfHasCokernel S) (RightHomologyData.ofHasCokernelOfHasKernel S) @@ -295,8 +295,8 @@ lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) : · intro h have := h.hasHomology simp only [exact_iff_isZero_homology] at h - haveI := S.isIso_iCycles hg - haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h + have := S.isIso_iCycles hg + have : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h rw [← S.toCycles_i] apply epi_comp · intro @@ -310,14 +310,14 @@ variable {S} set_option backward.defeqAttrib.useBackward true in lemma Exact.epi_f' (hS : S.Exact) (h : LeftHomologyData S) : Epi h.f' := epi_of_isZero_cokernel' _ h.hπ (by - haveI := hS.hasHomology + have := hS.hasHomology dsimp simpa only [← h.exact_iff] using hS) set_option backward.defeqAttrib.useBackward true in lemma Exact.mono_g' (hS : S.Exact) (h : RightHomologyData S) : Mono h.g' := mono_of_isZero_kernel' _ h.hι (by - haveI := hS.hasHomology + have := hS.hasHomology dsimp simpa only [← h.exact_iff] using hS) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Homology.lean b/Mathlib/Algebra/Homology/ShortComplex/Homology.lean index 123c6e89fc7520..b68c0c098a0417 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Homology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Homology.lean @@ -727,7 +727,7 @@ lemma hasHomology_of_isIso_leftRightHomologyComparison' lemma hasHomology_of_isIsoLeftRightHomologyComparison [S.HasLeftHomology] [S.HasRightHomology] [h : IsIso S.leftRightHomologyComparison] : S.HasHomology := by - haveI : IsIso (leftRightHomologyComparison' S.leftHomologyData S.rightHomologyData) := h + have : IsIso (leftRightHomologyComparison' S.leftHomologyData S.rightHomologyData) := h exact hasHomology_of_isIso_leftRightHomologyComparison' S.leftHomologyData S.rightHomologyData section diff --git a/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean b/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean index 56c1b1fb4575e4..866f7a60ff3579 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean @@ -1085,7 +1085,7 @@ set_option backward.isDefEq.respectTransparency false in lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] : HasCokernel (kernel.lift S.g S.f S.zero) := by let h := S.leftHomologyData - haveI : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩ + have : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩ let e : parallelPair (kernel.lift S.g S.f S.zero) 0 ≅ parallelPair h.f' 0 := parallelPair.ext (Iso.refl _) (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi) (by cat_disch) (by simp) diff --git a/Mathlib/Algebra/Homology/ShortComplex/QuasiIso.lean b/Mathlib/Algebra/Homology/ShortComplex/QuasiIso.lean index 725a4d870788b3..03660942f87188 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/QuasiIso.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/QuasiIso.lean @@ -104,7 +104,7 @@ lemma LeftHomologyMapData.quasiIso_iff {φ : S₁ ⟶ S₂} {h₁ : S₁.LeftHom rw [ShortComplex.quasiIso_iff, γ.homologyMap_eq] constructor · intro h - haveI : IsIso (γ.φH ≫ (LeftHomologyData.homologyIso h₂).inv) := + have : IsIso (γ.φH ≫ (LeftHomologyData.homologyIso h₂).inv) := IsIso.of_isIso_comp_left (LeftHomologyData.homologyIso h₁).hom _ exact IsIso.of_isIso_comp_right _ (LeftHomologyData.homologyIso h₂).inv · intro h @@ -116,7 +116,7 @@ lemma RightHomologyMapData.quasiIso_iff {φ : S₁ ⟶ S₂} {h₁ : S₁.RightH rw [ShortComplex.quasiIso_iff, γ.homologyMap_eq] constructor · intro h - haveI : IsIso (γ.φH ≫ (RightHomologyData.homologyIso h₂).inv) := + have : IsIso (γ.φH ≫ (RightHomologyData.homologyIso h₂).inv) := IsIso.of_isIso_comp_left (RightHomologyData.homologyIso h₁).hom _ exact IsIso.of_isIso_comp_right _ (RightHomologyData.homologyIso h₂).inv · intro h diff --git a/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean b/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean index d3ee48beba9abc..8d67f596bcdfee 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean @@ -1240,7 +1240,7 @@ instance (φ : S₁ ⟶ S₂) (h₁ : S₁.RightHomologyData) (h₂ : S₂.Right [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] : IsIso (rightHomologyMap' φ h₁ h₂) := by let h₂' := RightHomologyData.ofEpiOfIsIsoOfMono φ h₁ - haveI : IsIso (rightHomologyMap' φ h₁ h₂') := by + have : IsIso (rightHomologyMap' φ h₁ h₂') := by rw [(RightHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).rightHomologyMap'_eq] dsimp infer_instance @@ -1386,7 +1386,7 @@ set_option backward.isDefEq.respectTransparency false in lemma hasKernel [S.HasRightHomology] [HasCokernel S.f] : HasKernel (cokernel.desc S.f S.g S.zero) := by let h := S.rightHomologyData - haveI : HasLimit (parallelPair h.g' 0) := ⟨⟨⟨_, h.hι'⟩⟩⟩ + have : HasLimit (parallelPair h.g' 0) := ⟨⟨⟨_, h.hι'⟩⟩⟩ let e : parallelPair (cokernel.desc S.f S.g S.zero) 0 ≅ parallelPair h.g' 0 := parallelPair.ext (IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) h.hp) (Iso.refl _) (coequalizer.hom_ext (by simp)) (by simp) diff --git a/Mathlib/Algebra/Lie/Engel.lean b/Mathlib/Algebra/Lie/Engel.lean index 3214cfa5c41c7b..881677545bfc3c 100644 --- a/Mathlib/Algebra/Lie/Engel.lean +++ b/Mathlib/Algebra/Lie/Engel.lean @@ -171,11 +171,11 @@ theorem LieAlgebra.isEngelian_of_subsingleton [Subsingleton L] : LieAlgebra.IsEn theorem Function.Surjective.isEngelian {f : L →ₗ⁅R⁆ L₂} (hf : Function.Surjective f) (h : LieAlgebra.IsEngelian.{u₁, u₂, u₄} R L) : LieAlgebra.IsEngelian.{u₁, u₃, u₄} R L₂ := by intro M _i1 _i2 _i3 _i4 h' - letI : LieRingModule L M := LieRingModule.compLieHom M f - letI : LieModule R L M := compLieHom M f + let : LieRingModule L M := LieRingModule.compLieHom M f + let : LieModule R L M := compLieHom M f have hnp : ∀ x, IsNilpotent (toEnd R L M x) := fun x => h' (f x) have surj_id : Function.Surjective (LinearMap.id : M →ₗ[R] M) := Function.surjective_id - haveI : LieModule.IsNilpotent L M := h M hnp + have : LieModule.IsNilpotent L M := h M hnp apply hf.lieModuleIsNilpotent _ surj_id aesop @@ -250,7 +250,7 @@ theorem LieAlgebra.isEngelian_of_isNoetherian [IsNoetherian R L] : LieAlgebra.Is LieSubalgebra.mem_toSubmodule] exact LieSubalgebra.lie_mem K x.prop HX exact nontrivial_max_triv_of_isNilpotent R K (L' ⧸ K.toLieSubmodule) - haveI _i5 : IsNoetherian R L' := by + have _i5 : IsNoetherian R L' := by refine isNoetherian_of_surjective (LieHom.rangeRestrict (toEnd R L M)).toLinearMap ?_ simp only [LinearMap.range_eq_top] exact LieHom.surjective_rangeRestrict (toEnd R L M) diff --git a/Mathlib/Algebra/Lie/Extension.lean b/Mathlib/Algebra/Lie/Extension.lean index 54f1fa462d7f6a..a8476d586df5d1 100644 --- a/Mathlib/Algebra/Lie/Extension.lean +++ b/Mathlib/Algebra/Lie/Extension.lean @@ -355,7 +355,7 @@ one extension. -/ lemma lieModuleOf [IsLieAbelian M] (E : Extension R M L) : letI := E.ringModuleOf LieModule R L M := by - letI := E.ringModuleOf + let := E.ringModuleOf set h := E.proj_surjective.hasRightInverse exact { smul_lie r x m := by diff --git a/Mathlib/Algebra/Lie/Loop.lean b/Mathlib/Algebra/Lie/Loop.lean index 52d448747dc5b4..2b9b690e70e189 100644 --- a/Mathlib/Algebra/Lie/Loop.lean +++ b/Mathlib/Algebra/Lie/Loop.lean @@ -122,7 +122,7 @@ def twoCochainOfBilinear [CommRing A] [IsAddTorsionFree R] [Algebra A R] val := (residuePairing R A L Φ).compr₂ (TrivialLieModule.equiv R (loopAlgebra R A L) R).symm property := by refine Cohomology.mem_twoCochain_iff.mpr fun f ↦ ?_ - letI F := toFinsupp R A L + let F := toFinsupp R A L suffices ((F f).sum fun a v ↦ a • Φ (F f (-a)) v) = 0 by simpa classical set s := (F f).support ∪ (F f).support.image (Equiv.neg A) with hs diff --git a/Mathlib/Algebra/Module/PID.lean b/Mathlib/Algebra/Module/PID.lean index afc20225a1d2ba..499a385da36705 100644 --- a/Mathlib/Algebra/Module/PID.lean +++ b/Mathlib/Algebra/Module/PID.lean @@ -95,7 +95,7 @@ theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R · exact Finset.fintypeCoeSort _ · rintro ⟨p, hp⟩ have hP := prime_of_factor p (Multiset.mem_toFinset.mp hp) - haveI := Ideal.isPrime_of_prime hP + have := Ideal.isPrime_of_prime hP exact (IsPrincipal.prime_generator_of_isPrime p hP.ne_zero).irreducible namespace Module @@ -177,7 +177,7 @@ theorem torsion_by_prime_power_decomposition (hM : Module.IsTorsion' M (Submonoi | zero => use finZeroElim rw [Set.range_eq_empty, Submodule.span_empty] at hs - haveI : Unique M := + have : Unique M := ⟨⟨0⟩, fun x => by dsimp; rw [← Submodule.mem_bot R, hs]; exact Submodule.mem_top⟩ exact ⟨0⟩ | succ d IH => diff --git a/Mathlib/Algebra/Module/SnakeLemma.lean b/Mathlib/Algebra/Module/SnakeLemma.lean index 7c694eb66871e1..bb7a8776f1f85d 100644 --- a/Mathlib/Algebra/Module/SnakeLemma.lean +++ b/Mathlib/Algebra/Module/SnakeLemma.lean @@ -151,8 +151,8 @@ such that `f₂` is surjective with a (set-theoretic) section `σ`, `g₁` is in lemma SnakeLemma.exact_δ_right (F : K₂ →ₗ[R] K₃) (hF : f₂.comp ι₂ = ι₃.comp F) (h : Injective ι₃) : Exact F (δ i₁ i₂ i₃ f₁ f₂ hf g₁ g₂ hg h₁ h₂ σ hσ ρ hρ ι₃ hι₃ π₁ hπ₁) := by - haveI H₁ : ∀ x, f₂ (σ x) = x := congr_fun hσ - haveI H₂ := δ_aux i₂ i₃ f₂ g₁ g₂ hg h₂ σ hσ ρ hρ ι₃ hι₃ + have H₁ : ∀ x, f₂ (σ x) = x := congr_fun hσ + have H₂ := δ_aux i₂ i₃ f₂ g₁ g₂ hg h₂ σ hσ ρ hρ ι₃ hι₃ intro x constructor · intro H @@ -189,7 +189,7 @@ such that `f₂` is surjective with a (set-theoretic) section `σ`, `g₁` is in -/ lemma SnakeLemma.exact_δ_left (G : C₁ →ₗ[R] C₂) (hF : G.comp π₁ = π₂.comp g₁) (h : Surjective π₁) : Exact (δ i₁ i₂ i₃ f₁ f₂ hf g₁ g₂ hg h₁ h₂ σ hσ ρ hρ ι₃ hι₃ π₁ hπ₁) G := by - haveI H₂ := δ_aux i₂ i₃ f₂ g₁ g₂ hg h₂ σ hσ ρ hρ ι₃ hι₃ + have H₂ := δ_aux i₂ i₃ f₂ g₁ g₂ hg h₂ σ hσ ρ hρ ι₃ hι₃ intro x constructor · intro H diff --git a/Mathlib/Algebra/Module/SpanRank.lean b/Mathlib/Algebra/Module/SpanRank.lean index 036b6d4af6e496..559adf4c06ed9e 100644 --- a/Mathlib/Algebra/Module/SpanRank.lean +++ b/Mathlib/Algebra/Module/SpanRank.lean @@ -440,7 +440,7 @@ lemma Module.Basis.mk_eq_spanRank [RankCondition R] {ι : Type*} (v : Basis ι R theorem Submodule.rank_eq_spanRank_of_free [Module.Free R M] [StrongRankCondition R] : Module.rank R M = (⊤ : Submodule R M).spanRank := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R obtain ⟨I, B⟩ := ‹Module.Free R M› rw [← Basis.mk_eq_rank'' B, ← Basis.mk_eq_spanRank B, ← Cardinal.lift_id #(Set.range B), Cardinal.mk_range_eq_of_injective B.injective, Cardinal.lift_id _] diff --git a/Mathlib/Algebra/Module/Submodule/Lattice.lean b/Mathlib/Algebra/Module/Submodule/Lattice.lean index 8f2375d8309044..1b5678a24211e4 100644 --- a/Mathlib/Algebra/Module/Submodule/Lattice.lean +++ b/Mathlib/Algebra/Module/Submodule/Lattice.lean @@ -222,7 +222,7 @@ theorem coe_sInf (P : Set (Submodule R M)) : (↑(sInf P) : Set M) = ⋂ p ∈ P @[simp] theorem coe_finsetInf {ι} (s : Finset ι) (p : ι → Submodule R M) : (↑(s.inf p) : Set M) = ⋂ i ∈ s, ↑(p i) := by - letI := Classical.decEq ι + let := Classical.decEq ι refine s.induction_on ?_ fun i s _ ih ↦ ?_ · simp · rw [Finset.inf_insert, coe_inf, ih] diff --git a/Mathlib/Algebra/Module/Torsion/Basic.lean b/Mathlib/Algebra/Module/Torsion/Basic.lean index 6719c23989257c..5ec9aad55261ff 100644 --- a/Mathlib/Algebra/Module/Torsion/Basic.lean +++ b/Mathlib/Algebra/Module/Torsion/Basic.lean @@ -808,7 +808,7 @@ theorem _root_.Submodule.annihilator_top_inter_nonZeroDivisors [Module.Finite R refine ⟨_, ?_, (∏ x ∈ S, (@hM x).choose : R⁰).prop⟩ rw [Submonoid.coe_finsetProd, SetLike.mem_coe, ← hS, mem_annihilator_span] intro n - letI := Classical.decEq M + let := Classical.decEq M rw [← Finset.prod_erase_mul _ _ n.prop, mul_smul, ← Submonoid.smul_def, (@hM n).choose_spec, smul_zero] diff --git a/Mathlib/Algebra/Module/TransferInstance.lean b/Mathlib/Algebra/Module/TransferInstance.lean index 9913582e578408..f3e43ed03f1560 100644 --- a/Mathlib/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Algebra/Module/TransferInstance.lean @@ -94,7 +94,7 @@ lemma LinearEquiv.isScalarTower [Module R α] [Module R β] [IsScalarTower R A (e : α ≃ₗ[R] β) : letI := e.toAddEquiv.module A IsScalarTower R A α := by - letI := e.toAddEquiv.module A + let := e.toAddEquiv.module A constructor intro x y z simp only [Equiv.smul_def, smul_assoc] diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index a7546316ed9cbe..cac18e0e8dd386 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -339,7 +339,7 @@ theorem setFinite_inter [ProperSpace E] [Finite ι] {s : Set E} (hs : Bornology. theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpace E] [Finite ι] : MeasurableSet (fundamentalDomain b) := by cases nonempty_fintype ι - haveI : FiniteDimensional ℝ E := b.finiteDimensional_of_finite + have : FiniteDimensional ℝ E := b.finiteDimensional_of_finite let D : Set (ι → ℝ) := Set.pi Set.univ fun _ : ι => Set.Ico (0 : ℝ) 1 rw [(_ : fundamentalDomain b = b.equivFun.toLinearMap ⁻¹' D)] · refine measurableSet_preimage (LinearMap.continuous_of_finiteDimensional _).measurable ?_ diff --git a/Mathlib/Algebra/Notation/Indicator.lean b/Mathlib/Algebra/Notation/Indicator.lean index 9b4f555409ac5d..ba7178798403bd 100644 --- a/Mathlib/Algebra/Notation/Indicator.lean +++ b/Mathlib/Algebra/Notation/Indicator.lean @@ -203,7 +203,7 @@ lemma mulIndicator_inter_mulSupport (s : Set α) (f : α → M) : @[to_additive] lemma comp_mulIndicator (h : M → β) (f : α → M) {s : Set α} {x : α} [DecidablePred (· ∈ s)] : h (s.mulIndicator f x) = s.piecewise (h ∘ f) (const α (h 1)) x := by - letI := Classical.decPred (· ∈ s) + let := Classical.decPred (· ∈ s) convert! s.apply_piecewise f (const α 1) (fun _ => h) (x := x) using 2 @[to_additive] diff --git a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean index b8bef6562b9299..e45ec70e41eee1 100644 --- a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean +++ b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean @@ -159,7 +159,7 @@ lemma inf_sq_eq_mul_div_mabs_div (a b : α) : (a ⊓ b) ^ 2 = a * b / |b / a|ₘ @[to_additive] lemma mabs_div_sup_mul_mabs_div_inf (a b c : α) : |(a ⊔ c) / (b ⊔ c)|ₘ * |(a ⊓ c) / (b ⊓ c)|ₘ = |a / b|ₘ := by - letI : DistribLattice α := CommGroup.toDistribLattice α + let : DistribLattice α := CommGroup.toDistribLattice α calc |(a ⊔ c) / (b ⊔ c)|ₘ * |(a ⊓ c) / (b ⊓ c)|ₘ = (b ⊔ c ⊔ (a ⊔ c)) / ((b ⊔ c) ⊓ (a ⊔ c)) * |(a ⊓ c) / (b ⊓ c)|ₘ := by diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean index 7b4f64e055890f..ebf96411e49c3a 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean @@ -292,8 +292,8 @@ alias mul_right_cancel'' := mul_right_cancel @[to_additive] lemma mul_le_mul_iff_of_ge [MulLeftStrictMono α] [MulRightStrictMono α] {a₁ a₂ b₁ b₂ : α} (ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂) : a₂ * b₂ ≤ a₁ * b₁ ↔ a₁ = a₂ ∧ b₁ = b₂ := by - haveI := mulLeftMono_of_mulLeftStrictMono α - haveI := mulRightMono_of_mulRightStrictMono α + have := mulLeftMono_of_mulLeftStrictMono α + have := mulRightMono_of_mulRightStrictMono α refine ⟨fun h ↦ ?_, by rintro ⟨rfl, rfl⟩; rfl⟩ simp only [eq_iff_le_not_lt, ha, hb, true_and] refine ⟨fun ha ↦ h.not_gt ?_, fun hb ↦ h.not_gt ?_⟩ @@ -302,8 +302,8 @@ alias mul_right_cancel'' := mul_right_cancel @[to_additive] theorem mul_eq_mul_iff_eq_and_eq [MulLeftStrictMono α] [MulRightStrictMono α] {a b c d : α} (hac : a ≤ c) (hbd : b ≤ d) : a * b = c * d ↔ a = c ∧ b = d := by - haveI := mulLeftMono_of_mulLeftStrictMono α - haveI := mulRightMono_of_mulRightStrictMono α + have := mulLeftMono_of_mulLeftStrictMono α + have := mulRightMono_of_mulRightStrictMono α rw [le_antisymm_iff, eq_true (mul_le_mul' hac hbd), true_and, mul_le_mul_iff_of_ge hac hbd] @[to_additive] diff --git a/Mathlib/Algebra/Polynomial/Degree/Operations.lean b/Mathlib/Algebra/Polynomial/Degree/Operations.lean index 47254f2cbeae4d..470a8b06b11dbe 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Operations.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Operations.lean @@ -470,7 +470,7 @@ theorem degree_smul_of_isRightRegular_leadingCoeff (ha : a ≠ 0) exact hp.mul_right_eq_zero_iff.ne.mpr ha theorem degree_lt_degree_mul_X (hp : p ≠ 0) : p.degree < (p * X).degree := by - haveI := Nontrivial.of_polynomial_ne hp + have := Nontrivial.of_polynomial_ne hp have : leadingCoeff p * leadingCoeff X ≠ 0 := by simpa rw [degree_mul' this, degree_eq_natDegree hp, degree_X, ← Nat.cast_one, ← Nat.cast_add] norm_cast diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index dd34b114930c06..03b97312bdc07d 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -174,7 +174,7 @@ theorem natDegree_modByMonic_lt (p : R[X]) {q : R[X]} (hmq : Monic q) (hq : q · rw [hpq, natDegree_zero, Nat.pos_iff_ne_zero] contrapose hq exact eq_one_of_monic_natDegree_zero hmq hq - · haveI := Nontrivial.of_polynomial_ne hpq + · have := Nontrivial.of_polynomial_ne hpq exact natDegree_lt_natDegree hpq (degree_modByMonic_lt p hmq) @[simp] @@ -189,7 +189,7 @@ theorem zero_divByMonic (p : R[X]) : 0 /ₘ p = 0 := by theorem modByMonic_zero (p : R[X]) : p %ₘ 0 = p := letI := Classical.decEq R if h : Monic (0 : R[X]) then by - haveI := monic_zero_iff_subsingleton.mp h + have := monic_zero_iff_subsingleton.mp h simp [eq_iff_true_of_subsingleton] else by unfold modByMonic divModByMonicAux; rw [dif_neg h] @@ -197,7 +197,7 @@ theorem modByMonic_zero (p : R[X]) : p %ₘ 0 = p := theorem divByMonic_zero (p : R[X]) : p /ₘ 0 = 0 := letI := Classical.decEq R if h : Monic (0 : R[X]) then by - haveI := monic_zero_iff_subsingleton.mp h + have := monic_zero_iff_subsingleton.mp h simp [eq_iff_true_of_subsingleton] else by unfold divByMonic divModByMonicAux; rw [dif_neg h] @@ -301,7 +301,7 @@ theorem degree_divByMonic_le (p q : R[X]) : degree (p /ₘ q) ≤ degree p := else if hq : Monic q then if h : degree q ≤ degree p then by - haveI := Nontrivial.of_polynomial_ne hp0 + have := Nontrivial.of_polynomial_ne hp0 rw [← degree_add_divByMonic hq h, degree_eq_natDegree hq.ne_zero, degree_eq_natDegree (mt (divByMonic_eq_zero_iff hq).1 (not_lt.2 h))] exact WithBot.coe_le_coe.2 (Nat.le_add_left _ _) @@ -315,11 +315,11 @@ theorem degree_divByMonic_lt (p q : R[X]) (hp0 : p ≠ 0) letI := Classical.decEq R if hq : q.Monic then if hpq : degree p < degree q then by - haveI := Nontrivial.of_polynomial_ne hp0 + have := Nontrivial.of_polynomial_ne hp0 rw [(divByMonic_eq_zero_iff hq).2 hpq, degree_eq_natDegree hp0] exact WithBot.bot_lt_coe _ else by - haveI := Nontrivial.of_polynomial_ne hp0 + have := Nontrivial.of_polynomial_ne hp0 rw [← degree_add_divByMonic hq (not_lt.1 hpq), degree_eq_natDegree hq.ne_zero, degree_eq_natDegree (mt (divByMonic_eq_zero_iff hq).1 hpq)] exact @@ -375,7 +375,7 @@ theorem div_modByMonic_unique {f g} (q r : R[X]) (hg : Monic g) theorem map_mod_divByMonic [Ring S] (f : R →+* S) (hq : Monic q) : (p /ₘ q).map f = p.map f /ₘ q.map f ∧ (p %ₘ q).map f = p.map f %ₘ q.map f := by nontriviality S - haveI : Nontrivial R := f.domain_nontrivial + have : Nontrivial R := f.domain_nontrivial have : map f p /ₘ map f q = map f (p /ₘ q) ∧ map f p %ₘ map f q = map f (p %ₘ q) := div_modByMonic_unique ((p /ₘ q).map f) _ (hq.map f) ⟨Eq.symm <| by rw [← Polynomial.map_mul, ← Polynomial.map_add, modByMonic_add_div], @@ -487,7 +487,7 @@ variable (R) in theorem not_isField : ¬IsField R[X] := by nontriviality R intro h - letI := h.toField + let := h.toField simpa using congr_arg natDegree (monic_X.eq_one_of_isUnit <| monic_X (R := R).ne_zero.isUnit) section multiplicity @@ -500,7 +500,7 @@ def decidableDvdMonic [DecidableEq R] (p : R[X]) (hq : Monic q) : Decidable (q decidable_of_iff (p %ₘ q = 0) (modByMonic_eq_zero_iff_dvd hq) theorem finiteMultiplicity_X_sub_C (a : R) (h0 : p ≠ 0) : FiniteMultiplicity (X - C a) p := by - haveI := Nontrivial.of_polynomial_ne h0 + have := Nontrivial.of_polynomial_ne h0 refine finiteMultiplicity_of_degree_pos_of_monic ?_ (monic_X_sub_C _) h0 rw [degree_X_sub_C] decide @@ -651,7 +651,7 @@ theorem rootMultiplicity_pos {p : R[X]} (hp : p ≠ 0) {x : R} : theorem eval_divByMonic_pow_rootMultiplicity_ne_zero {p : R[X]} (a : R) (hp : p ≠ 0) : eval a (p /ₘ (X - C a) ^ rootMultiplicity a p) ≠ 0 := by classical - haveI : Nontrivial R := Nontrivial.of_polynomial_ne hp + have : Nontrivial R := Nontrivial.of_polynomial_ne hp rw [Ne, ← IsRoot, ← dvd_iff_isRoot] rintro ⟨q, hq⟩ have := pow_mul_divByMonic_rootMultiplicity_eq p a diff --git a/Mathlib/Algebra/Polynomial/Expand.lean b/Mathlib/Algebra/Polynomial/Expand.lean index 8f46371e485833..cfc9f72596a0da 100644 --- a/Mathlib/Algebra/Polynomial/Expand.lean +++ b/Mathlib/Algebra/Polynomial/Expand.lean @@ -257,7 +257,7 @@ theorem expand_contract' [NoZeroDivisors R] {f : R[X]} (hf : Polynomial.derivati expand R p (contract p f) = f := by obtain _ | @⟨_, hprime, hchar⟩ := ‹ExpChar R p› · rw [expand_one, contract_one] - · haveI := Fact.mk hchar; exact expand_contract p hf hprime.ne_zero + · have := Fact.mk hchar; exact expand_contract p hf hprime.ne_zero theorem map_frobenius_expand (f : R[X]) : map (frobenius R p) (expand R p f) = f ^ p := by refine f.induction_on' (fun a b ha hb => ?_) fun n a => ?_ diff --git a/Mathlib/Algebra/Polynomial/Inductions.lean b/Mathlib/Algebra/Polynomial/Inductions.lean index 4b7167ad718b36..897336644d5b5d 100644 --- a/Mathlib/Algebra/Polynomial/Inductions.lean +++ b/Mathlib/Algebra/Polynomial/Inductions.lean @@ -106,7 +106,7 @@ theorem divX_C_mul_X_pow : divX (C a * X ^ n) = if n = 0 then 0 else C a * X ^ ( simp only [divX_C_mul, divX_X_pow, mul_ite, mul_zero] theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by - haveI := Nontrivial.of_polynomial_ne hp0 + have := Nontrivial.of_polynomial_ne hp0 calc degree (divX p) < (divX p * X + C (p.coeff 0)).degree := if h : degree p ≤ 0 then by diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index 962263ec309547..aa72d371907c63 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -181,7 +181,7 @@ lemma smul_def (f : R[X]) (m : PolynomialModule R M) : instance isScalarTower' (M : Type u) [AddCommGroup M] [Module R M] [Module S M] [IsScalarTower S R M] : IsScalarTower S R[X] (PolynomialModule R M) := by - haveI : IsScalarTower R R[X] (PolynomialModule R M) := + have : IsScalarTower R R[X] (PolynomialModule R M) := inferInstanceAs <| IsScalarTower R R[X] <| Module.AEval' <| (coeffLinearEquiv R R).symm.comp <| (Finsupp.lmapDomain M R Nat.succ).comp (coeffLinearEquiv R R).toLinearMap constructor diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index 26fdd10daf025d..7e59b08ac1fbca 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -774,7 +774,7 @@ theorem coe_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Subring R} (hS theorem mem_sSup_of_directedOn {S : Set (Subring R)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, exists_prop] theorem coe_sSup_of_directedOn {S : Set (Subring R)} (Sne : S.Nonempty) diff --git a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean index 5bdf2171feb8e8..0d670dff45982d 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean @@ -692,7 +692,7 @@ theorem coe_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Subsemiring R} theorem mem_sSup_of_directedOn {S : Set (Subsemiring R)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, exists_prop] theorem coe_sSup_of_directedOn {S : Set (Subsemiring R)} (Sne : S.Nonempty) diff --git a/Mathlib/Algebra/Squarefree/Basic.lean b/Mathlib/Algebra/Squarefree/Basic.lean index af8d698b23388d..0730696dc86763 100644 --- a/Mathlib/Algebra/Squarefree/Basic.lean +++ b/Mathlib/Algebra/Squarefree/Basic.lean @@ -270,7 +270,7 @@ theorem squarefree_iff_nodup_normalizedFactors [NormalizationMonoid R] {x : R} (x0 : x ≠ 0) : Squarefree x ↔ Multiset.Nodup (normalizedFactors x) := by classical rw [squarefree_iff_emultiplicity_le_one, Multiset.nodup_iff_count_le_one] - haveI := nontrivial_of_ne x 0 x0 + have := nontrivial_of_ne x 0 x0 constructor <;> intro h a · by_cases hmem : a ∈ normalizedFactors x · have ha := irreducible_of_normalized_factor _ hmem diff --git a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean index d1559a84faf99a..f6a64330b62810 100644 --- a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean +++ b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean @@ -708,7 +708,7 @@ abbrev invertibleFstOfInvertible (x : tsze R M) [Invertible x] : Invertible x.fs mul_invOf_self := by rw [← fst_mul, mul_invOf_self, fst_one] theorem fst_invOf (x : tsze R M) [Invertible x] [Invertible x.fst] : (⅟x).fst = ⅟(x.fst) := by - letI := invertibleFstOfInvertible x + let := invertibleFstOfInvertible x convert! (rfl : _ = ⅟x.fst) theorem mul_left_eq_one (r : R) (x : tsze R M) (h : r * x.fst = 1) : @@ -738,7 +738,7 @@ abbrev invertibleOfInvertibleFst (x : tsze R M) [Invertible x.fst] : Invertible theorem snd_invOf (x : tsze R M) [Invertible x] [Invertible x.fst] : (⅟x).snd = -(⅟x.fst •> x.snd <• ⅟x.fst) := by - letI := invertibleOfInvertibleFst x + let := invertibleOfInvertibleFst x convert! congr_arg (TrivSqZeroExt.snd (R := R) (M := M)) (_ : _ = ⅟x) convert! rfl @@ -796,7 +796,7 @@ protected theorem inv_mul_cancel {x : tsze R M} (hx : fst x ≠ 0) : x⁻¹ * x variable [SMulCommClass R Rᵐᵒᵖ M] @[simp] theorem invOf_eq_inv (x : tsze R M) [Invertible x] : ⅟x = x⁻¹ := by - letI := invertibleFstOfInvertible x + let := invertibleFstOfInvertible x ext <;> simp [fst_invOf, snd_invOf] protected theorem mul_inv_cancel {x : tsze R M} (hx : fst x ≠ 0) : x * x⁻¹ = 1 := by diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index fb0f92073d1e68..e77c7685f5ec3c 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -229,8 +229,8 @@ instance hasColimits : HasColimits AffineScheme.{u} := Adjunction.has_colimits_of_equivalence.{u} (opOpEquivalence AffineScheme.{u}).inverse instance hasLimits : HasLimits AffineScheme.{u} := by - haveI := Adjunction.has_colimits_of_equivalence Γ.{u} - haveI : HasLimits AffineScheme.{u}ᵒᵖᵒᵖ := Limits.hasLimits_op_of_hasColimits + have := Adjunction.has_colimits_of_equivalence Γ.{u} + have : HasLimits AffineScheme.{u}ᵒᵖᵒᵖ := Limits.hasLimits_op_of_hasColimits exact Adjunction.has_limits_of_equivalence (opOpEquivalence AffineScheme.{u}).inverse noncomputable instance Γ_preservesLimits : PreservesLimits Γ.{u}.rightOp := inferInstance @@ -464,7 +464,7 @@ set_option backward.isDefEq.respectTransparency false in theorem map_fromSpec {V : X.Opens} (hV : IsAffineOpen V) (f : op U ⟶ op V) : Spec.map (X.presheaf.map f) ≫ hU.fromSpec = hV.fromSpec := by have : IsAffine U := hU - haveI : IsAffine _ := hV + have : IsAffine _ := hV conv_rhs => rw [fromSpec, ← X.homOfLE_ι (V := U) f.unop.le, isoSpec_inv, Category.assoc, ← Scheme.isoSpec_inv_naturality_assoc, @@ -685,8 +685,8 @@ lemma appLE_eq_away_map {X Y : Scheme.{u}} (f : X ⟶ Y) {U : Y.Opens} (hU : IsA letI := hV.isLocalization_basicOpen (f.appLE U V e r) f.appLE (Y.basicOpen r) (X.basicOpen (f.appLE U V e r)) (by simp [Scheme.Hom.appLE]) = CommRingCat.ofHom (IsLocalization.Away.map _ _ (f.appLE U V e).hom r) := by - letI := hU.isLocalization_basicOpen r - letI := hV.isLocalization_basicOpen (f.appLE U V e r) + let := hU.isLocalization_basicOpen r + let := hV.isLocalization_basicOpen (f.appLE U V e r) ext : 1 apply IsLocalization.ringHom_ext (.powers r) rw [IsLocalization.Away.map, CommRingCat.hom_ofHom, IsLocalization.map_comp, @@ -702,8 +702,8 @@ lemma app_basicOpen_eq_away_map {X Y : Scheme.{u}} (f : X ⟶ Y) {U : Y.Opens} (CommRingCat.ofHom (IsLocalization.Away.map Γ(Y, Y.basicOpen r) Γ(X, X.basicOpen (f.app U r)) (f.app U).hom r) ≫ X.presheaf.map (eqToHom (by simp)).op) := by - haveI := hU.isLocalization_basicOpen r - haveI := h.isLocalization_basicOpen (f.app U r) + have := hU.isLocalization_basicOpen r + have := h.isLocalization_basicOpen (f.app U r) ext : 1 apply IsLocalization.ringHom_ext (.powers r) rw [IsLocalization.Away.map, CommRingCat.hom_comp, RingHom.comp_assoc, CommRingCat.hom_ofHom, @@ -831,7 +831,7 @@ lemma stalkMap_injective (f : X ⟶ Y) {U : Opens Y} (hU : IsAffineOpen U) (x : (h : ∀ g, f.stalkMap x (Y.presheaf.germ U (f x) hx g) = 0 → Y.presheaf.germ U (f x) hx g = 0) : Function.Injective (f.stalkMap x) := by - letI := Y.presheaf.algebra_section_stalk ⟨f x, hx⟩ + let := Y.presheaf.algebra_section_stalk ⟨f x, hx⟩ apply (hU.isLocalization_stalk ⟨f x, hx⟩).injective_of_map_algebraMap_zero exact h @@ -839,7 +839,7 @@ include hU in lemma mem_ideal_iff {s : Γ(X, U)} {I : Ideal Γ(X, U)} : s ∈ I ↔ ∀ (x : X) (h : x ∈ U), X.presheaf.germ U x h s ∈ I.map (X.presheaf.germ U x h).hom := by refine ⟨fun hs x hxU ↦ Ideal.mem_map_of_mem _ hs, fun H ↦ ?_⟩ - letI (x : _) : Algebra Γ(X, U) (X.presheaf.stalk (hU.fromSpec x)) := + let (x : _) : Algebra Γ(X, U) (X.presheaf.stalk (hU.fromSpec x)) := TopCat.Presheaf.algebra_section_stalk X.presheaf _ have (P : Ideal Γ(X, U)) [hP : P.IsPrime] : IsLocalization.AtPrime _ P := hU.isLocalization_stalk' ⟨P, hP⟩ (hU.isoSpec.inv _).2 diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index 0bfee543aed3b0..40adc99197af29 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -122,12 +122,12 @@ lemma exists_mem_of_isClosed_of_nonempty map_id _ := by simp [← cancel_mono (subschemeι _)] map_comp _ _ := by simp [← cancel_mono (subschemeι _)] } let ι : D' ⟶ D := { app i := subschemeι _, naturality _ _ _ := by simp [D'] } - haveI {i j} (f : i ⟶ j) : IsAffineHom (D'.map f) := by + have {i j} (f : i ⟶ j) : IsAffineHom (D'.map f) := by suffices IsAffineHom (D'.map f ≫ ι.app j) from .of_comp _ (ι.app j) simp only [subschemeMap_subschemeι, D', ι] infer_instance - haveI _ (i) : Nonempty (D'.obj i) := Set.nonempty_coe_sort.mpr (hZne i) - haveI _ (i) : CompactSpace (D'.obj i) := isCompact_iff_compactSpace.mp (hZcpt i) + have _ (i) : Nonempty (D'.obj i) := Set.nonempty_coe_sort.mpr (hZne i) + have _ (i) : CompactSpace (D'.obj i) := isCompact_iff_compactSpace.mp (hZcpt i) let c' : Cone D' := { pt := (⨆ i, (vanishingIdeal ⟨Z i, hZc i⟩).comap (c.π.app i)).subscheme π := diff --git a/Mathlib/AlgebraicGeometry/ColimitsOver.lean b/Mathlib/AlgebraicGeometry/ColimitsOver.lean index 583a137e8bbe08..644a9c6e82f97a 100644 --- a/Mathlib/AlgebraicGeometry/ColimitsOver.lean +++ b/Mathlib/AlgebraicGeometry/ColimitsOver.lean @@ -259,7 +259,7 @@ def isColimitGluedCocone : IsColimit d.gluedCocone := by rw [reassoc_of% this] simp · intro s a - letI 𝒲 (a : J) : (D.obj a).left.OpenCover := 𝒰.pullback₁ (D.obj a).hom + let 𝒲 (a : J) : (D.obj a).left.OpenCover := 𝒰.pullback₁ (D.obj a).hom ext refine (𝒲 a).hom_ext _ _ fun i ↦ ?_ dsimp diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean index f183afc8eca54e..5ef4ba3b118a6a 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean @@ -60,7 +60,7 @@ private lemma exists_variableChange_of_char_two_of_j_eq_zero rw [E.coe_Δ', Δ_of_isCharTwoJEqZeroNF_of_char_two, pow_ne_zero_iff (Nat.succ_ne_zero _)] at ha₃ have ha₃' := E'.Δ'.ne_zero rw [E'.coe_Δ', Δ_of_isCharTwoJEqZeroNF_of_char_two, pow_ne_zero_iff (Nat.succ_ne_zero _)] at ha₃' - haveI : NeZero (3 : F) := NeZero.mk <| by + have : NeZero (3 : F) := NeZero.mk <| by rw [show (3 : F) = 1 by linear_combination CharP.cast_eq_zero F 2] exact one_ne_zero obtain ⟨u, hu⟩ := IsSepClosed.exists_pow_nat_eq (E.a₃ / E'.a₃) 3 @@ -126,7 +126,7 @@ private lemma exists_variableChange_of_char_three_of_j_ne_zero rw [E'.coe_Δ', Δ_of_isCharThreeJNeZeroNF_of_char_three, mul_ne_zero_iff, neg_ne_zero, pow_ne_zero_iff three_ne_zero] at h obtain ⟨ha₂', ha₆'⟩ := h - haveI : NeZero (2 : F) := NeZero.mk <| by + have : NeZero (2 : F) := NeZero.mk <| by rw [show (2 : F) = -1 by linear_combination CharP.cast_eq_zero F 3, neg_ne_zero] exact one_ne_zero obtain ⟨u, hu⟩ := IsSepClosed.exists_pow_nat_eq (E.a₂ / E'.a₂) 2 @@ -158,7 +158,7 @@ private lemma exists_variableChange_of_char_three_of_j_eq_zero rw [E.coe_Δ', Δ_of_isShortNF_of_char_three, neg_ne_zero, pow_ne_zero_iff three_ne_zero] at ha₄ have ha₄' := E'.Δ'.ne_zero rw [E'.coe_Δ', Δ_of_isShortNF_of_char_three, neg_ne_zero, pow_ne_zero_iff three_ne_zero] at ha₄' - haveI : NeZero (4 : F) := NeZero.mk <| by + have : NeZero (4 : F) := NeZero.mk <| by rw [show (4 : F) = 1 by linear_combination CharP.cast_eq_zero F 3] exact one_ne_zero obtain ⟨u, hu⟩ := IsSepClosed.exists_pow_nat_eq (E.a₄ / E'.a₄) 4 @@ -213,17 +213,17 @@ private lemma exists_variableChange_of_char_ne_two_or_three ∃ C : VariableChange F, C • E = E' := by replace hchar2 : (2 : F) ≠ 0 := CharP.cast_ne_zero_of_ne_of_prime F Nat.prime_two hchar2 replace hchar3 : (3 : F) ≠ 0 := CharP.cast_ne_zero_of_ne_of_prime F Nat.prime_three hchar3 - haveI := NeZero.mk hchar2 - haveI : NeZero (4 : F) := NeZero.mk <| by + have := NeZero.mk hchar2 + have : NeZero (4 : F) := NeZero.mk <| by have := pow_ne_zero 2 hchar2 norm_num1 at this exact this - haveI : NeZero (6 : F) := NeZero.mk <| by + have : NeZero (6 : F) := NeZero.mk <| by have := mul_ne_zero hchar2 hchar3 norm_num1 at this exact this - letI : Invertible (2 : F) := invertibleOfNonzero hchar2 - letI : Invertible (3 : F) := invertibleOfNonzero hchar3 + let : Invertible (2 : F) := invertibleOfNonzero hchar2 + let : Invertible (3 : F) := invertibleOfNonzero hchar3 wlog _ : E.IsShortNF generalizing E · obtain ⟨C, hE⟩ := E.exists_variableChange_isShortNF rw [← variableChange_j E C] at heq @@ -237,7 +237,7 @@ private lemma exists_variableChange_of_char_ne_two_or_three simp_rw [j, Units.val_inv_eq_inv_val, inv_mul_eq_div, div_eq_div_iff E.Δ'.ne_zero E'.Δ'.ne_zero, coe_Δ', Δ_of_isShortNF, c₄_of_isShortNF] at heq replace heq : E.a₄ ^ 3 * E'.a₆ ^ 2 = E'.a₄ ^ 3 * E.a₆ ^ 2 := by - letI : Invertible (47775744 : F) := invertibleOfNonzero <| by + let : Invertible (47775744 : F) := invertibleOfNonzero <| by have := mul_ne_zero (pow_ne_zero 16 hchar2) (pow_ne_zero 6 hchar3) norm_num1 at this exact this diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean index 294a9ebfcb05d9..8187a52e0f7046 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean @@ -400,7 +400,7 @@ lemma toShortNFOfCharThree_a₂ : (W.toShortNFOfCharThree • W).a₂ = W.b₂ : theorem toShortNFOfCharThree_spec (hb₂ : W.b₂ = 0) : (W.toShortNFOfCharThree • W).IsShortNF := by have h : (2 : R) * 2 = 1 := by linear_combination CharP.cast_eq_zero R 3 - letI : Invertible (2 : R) := ⟨2, h, h⟩ + let : Invertible (2 : R) := ⟨2, h, h⟩ have H := W.toCharNeTwoNF_spec exact ⟨H.a₁, hb₂ ▸ W.toShortNFOfCharThree_a₂, H.a₃⟩ @@ -419,10 +419,10 @@ def toCharThreeNF : VariableChange F := theorem toCharThreeNF_spec_of_b₂_ne_zero (hb₂ : W.b₂ ≠ 0) : (W.toCharThreeNF • W).IsCharThreeJNeZeroNF := by have h : (2 : F) * 2 = 1 := by linear_combination CharP.cast_eq_zero F 3 - letI : Invertible (2 : F) := ⟨2, h, h⟩ + let : Invertible (2 : F) := ⟨2, h, h⟩ rw [toCharThreeNF, mul_smul] set W' := W.toShortNFOfCharThree • W - haveI : W'.IsCharNeTwoNF := W.toCharNeTwoNF_spec + have : W'.IsCharNeTwoNF := W.toCharNeTwoNF_spec constructor · simp [variableChange_a₁] · simp [variableChange_a₃] @@ -436,9 +436,9 @@ theorem toCharThreeNF_spec_of_b₂_eq_zero (hb₂ : W.b₂ = 0) : (W.toCharThree instance toCharThreeNF_spec : (W.toCharThreeNF • W).IsCharThreeNF := by by_cases hb₂ : W.b₂ = 0 - · haveI := W.toCharThreeNF_spec_of_b₂_eq_zero hb₂ + · have := W.toCharThreeNF_spec_of_b₂_eq_zero hb₂ infer_instance - · haveI := W.toCharThreeNF_spec_of_b₂_ne_zero hb₂ + · have := W.toCharThreeNF_spec_of_b₂_ne_zero hb₂ infer_instance theorem exists_variableChange_isCharThreeNF : ∃ C : VariableChange F, (C • W).IsCharThreeNF := @@ -686,10 +686,10 @@ def toCharTwoNF [DecidableEq F] : VariableChange F := instance toCharTwoNF_spec [DecidableEq F] : (W.toCharTwoNF • W).IsCharTwoNF := by by_cases ha₁ : W.a₁ = 0 · rw [toCharTwoNF, dif_pos ha₁] - haveI := W.toCharTwoJEqZeroNF_spec ha₁ + have := W.toCharTwoJEqZeroNF_spec ha₁ infer_instance · rw [toCharTwoNF, dif_neg ha₁] - haveI := W.toCharTwoJNeZeroNF_spec ha₁ + have := W.toCharTwoJNeZeroNF_spec ha₁ infer_instance theorem exists_variableChange_isCharTwoNF : ∃ C : VariableChange F, (C • W).IsCharTwoNF := by diff --git a/Mathlib/AlgebraicGeometry/FunctionField.lean b/Mathlib/AlgebraicGeometry/FunctionField.lean index 0c18e17f26aaf6..a5179e3e7b3c1b 100644 --- a/Mathlib/AlgebraicGeometry/FunctionField.lean +++ b/Mathlib/AlgebraicGeometry/FunctionField.lean @@ -59,7 +59,7 @@ theorem germ_injective_of_isIntegral [IsIntegral X] {U : X.Opens} (x : X) (hx : rw [← (X.presheaf.germ U x hx).hom.map_zero] at hy obtain ⟨W, hW, iU, iV, e⟩ := X.presheaf.germ_eq _ hx hx _ _ hy cases Subsingleton.elim iU iV - haveI : Nonempty W := ⟨⟨_, hW⟩⟩ + have : Nonempty W := ⟨⟨_, hW⟩⟩ exact map_injective_of_isIntegral X iU e theorem Scheme.germToFunctionField_injective [IsIntegral X] (U : X.Opens) [Nonempty U] : diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean index bee106c6039743..8f8e1018f242ab 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean @@ -576,7 +576,7 @@ noncomputable nonrec def vanishingIdeal (Z : Closeds X) : IdealSheafData X := (Spec.map (X.presheaf.map (homOfLE _).op) x) ?_ rwa [Set.mem_preimage, ← Scheme.Hom.comp_apply, IsAffineOpen.map_fromSpec _ (X.affineBasicOpen f).2] - · letI : Algebra Γ(X, U) Γ(X, X.affineBasicOpen f) := F.hom.toAlgebra + · let : Algebra Γ(X, U) Γ(X, X.affineBasicOpen f) := F.hom.toAlgebra have : IsLocalization.Away f Γ(X, X.basicOpen f) := U.2.isLocalization_of_eq_basicOpen _ _ rfl intro x hx diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean index d767fc855ecdee..275e08d6618fed 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean @@ -110,8 +110,8 @@ lemma isLocalization_away {U V : X.affineOpens} (h : U ≤ V) (f : Γ(X, V.1)) (hU : U = X.affineBasicOpen f) : letI := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal h)).toAlgebra IsLocalization.Away (Ideal.Quotient.mk (I.ideal V) f) (Γ(X, U) ⧸ (I.ideal U)) := by - letI := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal h)).toAlgebra - letI := (X.presheaf.map (homOfLE (X := X.Opens) h).op).hom.toAlgebra + let := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal h)).toAlgebra + let := (X.presheaf.map (homOfLE (X := X.Opens) h).op).hom.toAlgebra have : IsLocalization.Away f Γ(X, U) := by subst hU; exact V.2.isLocalization_of_eq_basicOpen _ _ rfl simp only [IsLocalization.Away, ← Submonoid.map_powers] @@ -122,14 +122,14 @@ lemma isLocalization_away {U V : X.affineOpens} instance isOpenImmersion_glueDataObjMap {V : X.affineOpens} (f : Γ(X, V.1)) : IsOpenImmersion (I.glueDataObjMap (X.affineBasicOpen_le f)) := by - letI := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal (X.affineBasicOpen_le f))).toAlgebra + let := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal (X.affineBasicOpen_le f))).toAlgebra have := I.isLocalization_away (X.affineBasicOpen_le f) f rfl exact IsOpenImmersion.of_isLocalization (Ideal.Quotient.mk _ f) lemma opensRange_glueDataObjMap {V : X.affineOpens} (f : Γ(X, V.1)) : (I.glueDataObjMap (X.affineBasicOpen_le f)).opensRange = (I.glueDataObjι V) ⁻¹ᵁ (V.1.ι ⁻¹ᵁ X.basicOpen f) := by - letI := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal (X.affineBasicOpen_le f))).toAlgebra + let := (Ideal.quotientMap _ _ (I.ideal_le_comap_ideal (X.affineBasicOpen_le f))).toAlgebra let f' : Γ(X, V) ⧸ I.ideal V := Ideal.Quotient.mk _ f have := I.isLocalization_away (X.affineBasicOpen_le f) f rfl ext1 diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index d2058253707e20..1c72fd31fb288e 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -112,7 +112,7 @@ instance (priority := 100) isOpenImmersion_of_isEmpty {X Y : Scheme} (f : X ⟶ instance (priority := 100) isIso_of_isEmpty {X Y : Scheme} (f : X ⟶ Y) [IsEmpty Y] : IsIso f := by - haveI : IsEmpty X := f.base.hom.1.isEmpty + have : IsEmpty X := f.base.hom.1.isEmpty have : Epi f.base := by rw [TopCat.epi_iff_surjective]; rintro (x : Y) exact isEmptyElim x @@ -546,7 +546,7 @@ lemma isIso_stalkMap_coprodSpec (x) : rw [← IsIso.comp_inv_eq, Scheme.Hom.stalkMap_congr_hom _ (Spec.map _) (coprodSpec_inl R S)] at this rw [coprodMk_inl, ← this] - letI := (RingHom.fst R S).toAlgebra + let := (RingHom.fst R S).toAlgebra have : IsOpenImmersion (Spec.map (CommRingCat.ofHom (RingHom.fst R S))) := IsOpenImmersion.of_isLocalization (1, 0) infer_instance @@ -554,7 +554,7 @@ lemma isIso_stalkMap_coprodSpec (x) : rw [← IsIso.comp_inv_eq, Scheme.Hom.stalkMap_congr_hom _ (Spec.map _) (coprodSpec_inr R S)] at this rw [coprodMk_inr, ← this] - letI := (RingHom.snd R S).toAlgebra + let := (RingHom.snd R S).toAlgebra have : IsOpenImmersion (Spec.map (CommRingCat.ofHom (RingHom.snd R S))) := IsOpenImmersion.of_isLocalization (0, 1) infer_instance @@ -614,7 +614,7 @@ lemma ι_sigmaSpec (R : ι → CommRingCat) (i) : instance (i) (R : ι → Type _) [∀ i, CommRing (R i)] : IsOpenImmersion (Spec.map (CommRingCat.ofHom (Pi.evalRingHom (R ·) i))) := by classical - letI := (Pi.evalRingHom R i).toAlgebra + let := (Pi.evalRingHom R i).toAlgebra have : IsLocalization.Away (Function.update (β := R) 0 i 1) (R i) := by apply IsLocalization.away_of_isIdempotentElem_of_mul · ext j; by_cases h : j = i <;> aesop diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index d32e5611a85a5b..f63ea0d48789dd 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -67,12 +67,12 @@ def SpecModulesToSheafFullyFaithful : (modulesSpecToSheaf (R := R)).FullyFaithfu congr($(f.1.naturality (homOfLE hrU).op).hom x) rw [← this, ← this, M.val.map_smul] generalize (Spec R).ringCatSheaf.obj.map (homOfLE hrU).op t = t - letI := Module.compHom (R := Γ(Spec R, basicOpen r)) Γ(M, basicOpen r) + let := Module.compHom (R := Γ(Spec R, basicOpen r)) Γ(M, basicOpen r) (algebraMap R Γ(Spec R, basicOpen r)) - haveI : IsScalarTower R Γ(Spec R, basicOpen r) Γ(M, basicOpen r) := + have : IsScalarTower R Γ(Spec R, basicOpen r) Γ(M, basicOpen r) := .of_algebraMap_smul fun _ _ ↦ rfl - letI := Module.compHom Γ(N, basicOpen r) (algebraMap R Γ(Spec R, basicOpen r)) - haveI : IsScalarTower R Γ(Spec R, basicOpen r) Γ(N, basicOpen r) := + let := Module.compHom Γ(N, basicOpen r) (algebraMap R Γ(Spec R, basicOpen r)) + have : IsScalarTower R Γ(Spec R, basicOpen r) Γ(N, basicOpen r) := .of_algebraMap_smul fun _ _ ↦ rfl exact (IsLocalization.linearMap_compatibleSMul (.powers (M := R) r) Γ(Spec R, basicOpen r) Γ(M, basicOpen r) Γ(N, basicOpen r)).map_smul @@ -260,7 +260,7 @@ noncomputable def Scheme.Modules.fromTildeΓ (M : (Spec (.of R)).Modules) : simp only [inducedFunctor_obj, Submonoid.powers_le, Submonoid.mem_comap] exact M.isUnit_algebraMap_end_of_le_basicOpen f.unop le_rfl naturality {f g : Rᵒᵖ} i := by - letI N := (modulesSpecToSheaf.obj M).presheaf.obj (.op ⊤) + let N := (modulesSpecToSheaf.obj M).presheaf.obj (.op ⊤) ext1 apply IsLocalizedModule.ext (.powers (M := R) f.unop) (tilde.toOpen _ (PrimeSpectrum.basicOpen (R := R) f.unop)).hom diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean index e2615dd23bd633..3339ee558dc2ef 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean @@ -171,7 +171,7 @@ instance : HasAffineProperty @IsAffineHom fun X _ _ _ ↦ IsAffine X where instance isAffineHom_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsAffineHom := by apply HasAffineProperty.isStableUnderBaseChange - letI := HasAffineProperty.isLocal_affineProperty + let := HasAffineProperty.isLocal_affineProperty apply AffineTargetMorphismProperty.IsStableUnderBaseChange.mk introv X hX H infer_instance @@ -295,8 +295,8 @@ theorem diagonal_isAffine_iff_forall_isAffineOpen_inf [IsAffine Y] (f : X ⟶ Y) constructor · intro H U V hU hV dsimp at H - haveI : IsAffine _ := hU - haveI : IsAffine _ := hV + have : IsAffine _ := hU + have : IsAffine _ := hV let g : pullback U.ι V.ι ⟶ X := pullback.fst _ _ ≫ U.ι have := IsOpenImmersion.isPullback (X.homOfLE inf_le_left) (X.homOfLE inf_le_right) U.ι V.ι (by simp) (by ext; simp) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean b/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean index 795563aef108b4..a1a71e44c80c3d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean @@ -82,7 +82,7 @@ lemma affineAnd_isLocal (hPi : RingHom.RespectsIso Q) (hQl : RingHom.Localizatio exact hf of_basicOpenCover {X Y _} f s hs hf := by dsimp [affineAnd] at hf - haveI : IsAffine X := by + have : IsAffine X := by apply isAffine_of_isAffineOpen_basicOpen (f.appTop '' s) · apply_fun Ideal.map (f.appTop).hom at hs rwa [Ideal.map_span, Ideal.map_top] at hs @@ -109,7 +109,7 @@ lemma affineAnd_isLocal_of_propertyIsLocal lemma affineAnd_isStableUnderBaseChange (hQi : RingHom.RespectsIso Q) (hQb : RingHom.IsStableUnderBaseChange Q) : (affineAnd Q).IsStableUnderBaseChange := by - haveI : (affineAnd Q).toProperty.RespectsIso := affineAnd_respectsIso hQi + have : (affineAnd Q).toProperty.RespectsIso := affineAnd_respectsIso hQi apply AffineTargetMorphismProperty.IsStableUnderBaseChange.mk intro X Y S _ _ f g ⟨hY, hg⟩ exact ⟨inferInstance, hQb.pullback_fst_appTop _ hQi f _ hg⟩ @@ -143,7 +143,7 @@ set_option backward.isDefEq.respectTransparency false in lemma targetAffineLocally_affineAnd_iff_affineLocally (hQ : RingHom.PropertyIsLocal Q) {X Y : Scheme.{u}} (f : X ⟶ Y) : targetAffineLocally (affineAnd Q) f ↔ IsAffineHom f ∧ affineLocally Q f := by - haveI : HasRingHomProperty (affineLocally Q) Q := ⟨hQ, rfl⟩ + have : HasRingHomProperty (affineLocally Q) Q := ⟨hQ, rfl⟩ rw [targetAffineLocally_affineAnd_iff' hQ.respectsIso] simp only [and_congr_right_iff] intro hf diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean index 466c4f3dba1f9d..caf16cd0d2b9e6 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean @@ -465,7 +465,7 @@ instance (P : AffineTargetMorphismProperty) [P.toProperty.RespectsIso] : exact H U · introv H rintro ⟨U, hU : IsAffineOpen U⟩; dsimp - haveI : IsAffine _ := hU.preimage_of_isIso e.hom + have : IsAffine _ := hU.preimage_of_isIso e.hom rw [morphismRestrict_comp, P.cancel_right_of_respectsIso] exact H ⟨(Opens.map e.hom.base).obj U, hU.preimage_of_isIso e.hom⟩ @@ -527,7 +527,7 @@ theorem restrict (hf : P f) (U : Y.affineOpens) : of_isPullback (isPullback_morphismRestrict f U).flip hf instance (priority := 900) : P.RespectsIso := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [eq_targetAffineLocally P] infer_instance @@ -535,7 +535,7 @@ theorem of_iSup_eq_top {ι} (U : ι → Y.affineOpens) (hU : ⨆ i, (U i : Y.Opens) = ⊤) (hU' : ∀ i, Q (f ∣_ U i)) : P f := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [eq_targetAffineLocally P] classical intro V @@ -568,14 +568,14 @@ theorem of_openCover theorem iff_of_openCover (𝒰 : Y.OpenCover) [∀ i, IsAffine (𝒰.X i)] : P f ↔ ∀ i, Q (𝒰.pullbackHom f i) := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [iff_of_iSup_eq_top (P := P) (fun i ↦ ⟨_, isAffineOpen_opensRange _⟩) 𝒰.iSup_opensRange] exact forall_congr' fun i ↦ Q.arrow_mk_iso_iff (morphismRestrictOpensRange f _) theorem iff_of_isAffine [IsAffine Y] : P f ↔ Q f := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [iff_of_openCover (P := P) (Scheme.coverOfIsIso.{0} (𝟙 Y))] trans Q (pullback.snd f (𝟙 _)) · exact ⟨fun H => H PUnit.unit, fun H _ => H⟩ @@ -584,7 +584,7 @@ theorem iff_of_isAffine [IsAffine Y] : P f ↔ Q f := by set_option backward.isDefEq.respectTransparency false in instance (priority := 900) : IsZariskiLocalAtTarget P := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P apply IsZariskiLocalAtTarget.mk' · rw [eq_targetAffineLocally P] intro X Y f U H V @@ -612,7 +612,7 @@ set_option backward.isDefEq.respectTransparency false in private theorem pullback_fst_of_right (hP' : Q.IsStableUnderBaseChange) {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [IsAffine S] (H : Q g) : P (pullback.fst f g) := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [iff_of_openCover (P := P) X.affineCover] intro i let e := pullbackSymmetry _ _ ≪≫ pullbackRightPullbackFstIso f g (X.affineCover.f i) @@ -641,7 +641,7 @@ theorem isStableUnderBaseChange (hP' : Q.IsStableUnderBaseChange) : simp [e] rw [← this, P.cancel_left_of_respectsIso] apply HasAffineProperty.pullback_fst_of_right hP' - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [← pullbackSymmetry_hom_comp_snd, Q.cancel_left_of_respectsIso] apply of_isPullback (.of_hasPullback _ _) H) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index 87d9a352ed1bba..611c7195607cc3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -100,7 +100,7 @@ theorem spec_of_surjective {R S : CommRingCat} (f : R ⟶ S) (h : Function.Surje IsClosedImmersion (Spec.map f) where isClosedEmbedding := PrimeSpectrum.isClosedEmbedding_comap_of_surjective _ _ h stalkMap_surjective x := by - haveI : (RingHom.toMorphismProperty (fun f ↦ Function.Surjective f)).RespectsIso := by + have : (RingHom.toMorphismProperty (fun f ↦ Function.Surjective f)).RespectsIso := by rw [← RingHom.toMorphismProperty_respectsIso_iff] exact RingHom.surjective_respectsIso apply (MorphismProperty.arrow_mk_iso_iff @@ -370,7 +370,7 @@ lemma Scheme.Hom.app_surjective (f : X ⟶ Y) (U : Y.Opens) (hU : IsAffineOpen U instance IsClosedImmersion.isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsClosedImmersion := by apply HasAffineProperty.isStableUnderBaseChange - haveI := HasAffineProperty.isLocal_affineProperty @IsClosedImmersion + have := HasAffineProperty.isLocal_affineProperty @IsClosedImmersion apply AffineTargetMorphismProperty.IsStableUnderBaseChange.mk intro X Y S _ _ f g ⟨ha, hsurj⟩ exact ⟨inferInstance, RingHom.surjective_isStableUnderBaseChange.pullback_fst_appTop _ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean index 211e8505231f67..c04919f3ce1fe3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean @@ -72,7 +72,7 @@ theorem HasAffineProperty.diagonal_of_openCover (P) {Q} [HasAffineProperty P Q] (h𝒰' : ∀ i j k, Q (pullback.mapDesc ((𝒰' i).f j) ((𝒰' i).f k) (𝒰.pullbackHom f i))) : P.diagonal f := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P let 𝒱 := (Scheme.Pullback.openCoverOfBase 𝒰 f f).bind fun i => Scheme.Pullback.openCoverOfLeftRight.{u} (𝒰' i) (𝒰' i) (pullback.snd _ _) (pullback.snd _ _) have i1 : ∀ i, IsAffine (𝒱.X i) := fun i => by dsimp [𝒱]; infer_instance @@ -108,7 +108,7 @@ theorem HasAffineProperty.diagonal_of_diagonal_of_isPullback [IsAffine U] [IsOpenImmersion g] {iV : V ⟶ X} {f' : V ⟶ U} (h : IsPullback iV f' f g) (H : P.diagonal f) : Q.diagonal f' := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P rw [← Q.diagonal.cancel_left_of_respectsIso h.isoPullback.inv, h.isoPullback_inv_snd] rintro U V f₁ f₂ hU hV hf₁ hf₂ @@ -122,7 +122,7 @@ set_option backward.defeqAttrib.useBackward true in theorem HasAffineProperty.diagonal_iff (P) {Q} [HasAffineProperty P Q] {X Y : Scheme.{u}} {f : X ⟶ Y} [IsAffine Y] : Q.diagonal f ↔ P.diagonal f := by - letI := isLocal_affineProperty P + let := isLocal_affineProperty P refine ⟨fun hf ↦ ?_, diagonal_of_diagonal_of_isPullback P .of_id_fst⟩ rw [← Q.diagonal.cancel_left_of_respectsIso (pullback.fst (f := f) (g := 𝟙 Y)), pullback.condition, Category.comp_id] at hf @@ -175,7 +175,7 @@ instance (P) {Q} [HasAffineProperty P Q] : HasAffineProperty P.diagonal Q.diagon isLocal_affineProperty := letI := HasAffineProperty.isLocal_affineProperty P; inferInstance eq_targetAffineLocally' := by ext X Y f - letI := HasAffineProperty.isLocal_affineProperty P + let := HasAffineProperty.isLocal_affineProperty P constructor · exact fun H U ↦ HasAffineProperty.diagonal_of_diagonal_of_isPullback P (isPullback_morphismRestrict f U).flip H @@ -374,7 +374,7 @@ lemma stalkwiseIsZariskiLocalAtTarget_of_respectsIso (hP : RingHom.RespectsIso P IsZariskiLocalAtTarget (stalkwise P) := by have hP' : (RingHom.toMorphismProperty P).RespectsIso := RingHom.toMorphismProperty_respectsIso_iff.mp hP - letI := stalkwise_respectsIso hP + let := stalkwise_respectsIso hP apply IsZariskiLocalAtTarget.mk' · intro X Y f U hf x apply ((RingHom.toMorphismProperty P).arrow_mk_iso_iff <| @@ -389,7 +389,7 @@ set_option backward.isDefEq.respectTransparency false in /-- If `P` respects isos, then `stalkwise P` is local at the source. -/ lemma stalkwise_isZariskiLocalAtSource_of_respectsIso (hP : RingHom.RespectsIso P) : IsZariskiLocalAtSource (stalkwise P) := by - letI := stalkwise_respectsIso hP + let := stalkwise_respectsIso hP apply IsZariskiLocalAtSource.mk' · intro X Y f U hf x rw [Scheme.Hom.stalkMap_comp, CommRingCat.hom_comp, hP.cancel_right_isIso] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean b/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean index e57a1ed93c8f18..5c22386c082a28 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean @@ -185,8 +185,8 @@ lemma isFinite_iff_locallyOfFiniteType_of_jacobsonSpace obtain ⟨φ, rfl⟩ := Spec.map_surjective f rw [IsFinite.SpecMap_iff, HasRingHomProperty.Spec_iff (P := @LocallyOfFiniteType)] have := (PrimeSpectrum.t1Space_iff_isField (R := R)).mp (show T1Space (Spec R) by infer_instance) - letI := this.toField - letI := φ.hom.toAlgebra + let := this.toField + let := φ.hom.toAlgebra have := PrimeSpectrum.isJacobsonRing_iff_jacobsonSpace.mpr ‹_› change Module.Finite _ _ ↔ Algebra.FiniteType _ _ exact ⟨fun _ ↦ inferInstance, fun _ ↦ finite_of_finite_type_of_isJacobsonRing _ _⟩ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean index 49fe5adb97ebef..e946dfff6dcb03 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean @@ -240,7 +240,7 @@ protected lemma of_hom_ext (f : X ⟶ Y) (_ : Spec.map φ ≫ g₁ = Spec.map φ ≫ g₂) (_ : g₁ ≫ f = g₂ ≫ f), g₁ = g₂) : FormallyUnramified f := by refine ⟨fun {U hU V hV hVU} ↦ ?_⟩ - letI := (f.appLE U V hVU).hom.toAlgebra + let := (f.appLE U V hVU).hom.toAlgebra refine Algebra.FormallyUnramified.iff_comp_injective.mpr fun R _ _ I hI g₁ g₂ hg₁g₂ ↦ ?_ have hg₁ : f.appLE U V hVU ≫ CommRingCat.ofHom g₁ = CommRingCat.ofHom (algebraMap _ R) := CommRingCat.hom_ext g₁.comp_algebraMap diff --git a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean index 8779719cf080a2..501572d427a8dd 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean @@ -59,7 +59,7 @@ lemma isOpenImmersion_SpecMap_iff_of_surjective {R S : CommRingCat} ← RingHom.ker_eq_comap_bot] simp [φ] · rintro ⟨e, he, he'⟩ - letI := f.hom.toAlgebra + let := f.hom.toAlgebra have : IsLocalization.Away (1 - e) S := IsLocalization.away_of_isIdempotentElem he.one_sub (by simpa using! he') hf exact IsOpenImmersion.of_isLocalization (1 - e) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean b/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean index 5baa0b7f663642..615fdaa507af14 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean @@ -157,9 +157,9 @@ theorem finite_appTop_of_universallyClosed (f : X ⟶ (Spec <| .of K)) have x : X := Nonempty.some inferInstance obtain ⟨_, ⟨U, hU, rfl⟩, hxU, -⟩ := X.isBasis_affineOpens.exists_subset_of_mem_open (Set.mem_univ x) isOpen_univ - letI := ((Scheme.ΓSpecIso (.of K)).commRingCatIsoToRingEquiv.toMulEquiv.isField + let := ((Scheme.ΓSpecIso (.of K)).commRingCatIsoToRingEquiv.toMulEquiv.isField (Field.toIsField K)).toField - letI := (isField_of_universallyClosed K f).toField + let := (isField_of_universallyClosed K f).toField have : Nonempty U := ⟨⟨x, hxU⟩⟩ apply RingHom.finite_of_algHom_finiteType_of_isJacobsonRing (A := Γ(X, U)) (g := (X.presheaf.map (homOfLE le_top).op).hom) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean index 26d5fefa8013e3..52850472c76fda 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean @@ -111,7 +111,7 @@ theorem isCompact_basicOpen (X : Scheme) {U : X.Opens} (hU : IsCompact (U : Set let g : s → X.affineOpens := fun V ↦ ⟨V.1 ⊓ X.basicOpen f, by rw [← X.basicOpen_res _ (homOfLE ((le_iSup₂ V.1 V.2).trans_eq e.symm)).op] exact V.1.2.basicOpen _⟩ - haveI : Finite s := hs.to_subtype + have : Finite s := hs.to_subtype refine ⟨Set.range g, Set.finite_range g, ?_⟩ rw [iSup_range, ← iSup_inf_eq, iSup_subtype, ← e, inf_eq_right.mpr (X.basicOpen_le f)] @@ -163,7 +163,7 @@ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in instance quasiCompact_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @QuasiCompact := by - letI := HasAffineProperty.isLocal_affineProperty @QuasiCompact + let := HasAffineProperty.isLocal_affineProperty @QuasiCompact apply HasAffineProperty.isStableUnderBaseChange apply AffineTargetMorphismProperty.IsStableUnderBaseChange.mk intro X Y S _ _ f g h @@ -274,7 +274,7 @@ theorem exists_pow_mul_eq_zero_of_res_basicOpen_eq_zero_of_isCompact (X : Scheme · rw [map_zero] · simp only [Scheme.basicOpen_res, inf_le_right] choose n hn using H' - haveI := hs.to_subtype + have := hs.to_subtype cases nonempty_fintype s use Finset.univ.sup n suffices ∀ i : s, X.presheaf.map (homOfLE (h₁ i)).op (f ^ Finset.univ.sup n * x) = 0 by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean index b4af43fadb9d62..f590788e7494fa 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean @@ -174,7 +174,7 @@ theorem Scheme.quasiSeparatedSpace_of_isOpenCover {I : Type*} (U : I → X.Opens) (hU : IsOpenCover U) (hU₁ : ∀ i, IsAffineOpen (U i)) (hU₂ : ∀ i j, IsCompact (X := X) (U i ∩ U j)) : QuasiSeparatedSpace X := by - letI := HasAffineProperty.isLocal_affineProperty @QuasiCompact + let := HasAffineProperty.isLocal_affineProperty @QuasiCompact rw [← quasiCompact_affineProperty_iff_quasiSeparatedSpace X.toSpecΓ] have : ∀ i, IsAffine ((X.openCoverOfIsOpenCover U hU).X i) := hU₁ refine AffineTargetMorphismProperty.diagonal_of_openCover_source _ @@ -337,7 +337,7 @@ theorem exists_eq_pow_mul_of_isCompact_of_isQuasiSeparated (X : Scheme.{u}) (U : ⟨hSU _ _ Set.subset_union_left S.2 hS Set.subset_union_right U.1.2 U.2.isCompact, (S ⊓ U.1).2⟩ - haveI := hs'.to_subtype + have := hs'.to_subtype cases nonempty_fintype s replace hs : S ⊓ U.1 = iSup fun i : s => (i : X.Opens) := by ext1; simpa using hs have hs₁ (i : s) : i.1.1 ≤ S := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean index 942a7ce2461eaa..496276ab0b9e2d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean @@ -206,9 +206,9 @@ lemma exists_basicOpen_le_appLE_of_appLE_of_isAffine have hxa : x ∈ X.basicOpen (f.appLE U₂ V₂ e₂ r') := by simpa [Scheme.Hom.appLE, ← Scheme.preimage_basicOpen] using And.intro hx₂ (hBrr' ▸ hBfx) obtain ⟨s, s', hBss', hBx⟩ := exists_basicOpen_le_affine_inter V₁.2 ha x ⟨hx₁, hxa⟩ - haveI := V₂.2.isLocalization_basicOpen (f.appLE U₂ V₂ e₂ r') - haveI := U₂.2.isLocalization_basicOpen r' - haveI := ha.isLocalization_basicOpen s' + have := V₂.2.isLocalization_basicOpen (f.appLE U₂ V₂ e₂ r') + have := U₂.2.isLocalization_basicOpen r' + have := ha.isLocalization_basicOpen s' have ers : X.basicOpen s ≤ f ⁻¹ᵁ Y.basicOpen r := by rw [hBss', hBrr'] apply le_trans (X.basicOpen_le _) @@ -541,7 +541,7 @@ set_option backward.isDefEq.respectTransparency false in lemma isStableUnderBaseChange (hP : RingHom.IsStableUnderBaseChange Q) : P.IsStableUnderBaseChange := by apply HasAffineProperty.isStableUnderBaseChange - letI := HasAffineProperty.isLocal_affineProperty P + let := HasAffineProperty.isLocal_affineProperty P apply AffineTargetMorphismProperty.IsStableUnderBaseChange.mk intro X Y S _ _ f g H rw [← HasAffineProperty.iff_of_isAffine (P := P)] at H ⊢ @@ -633,12 +633,12 @@ lemma iff_exists_appLE_locally obtain ⟨r, hr, hrs⟩ := this refine ⟨⟨U, hU⟩, ⟨X.basicOpen r, hV.basicOpen r⟩, hrs, (X.basicOpen_le r).trans e, ?_⟩ rw [← f.appLE_map e (homOfLE (X.basicOpen_le r)).op] - haveI : IsLocalization.Away r Γ(X, X.basicOpen r) := hV.isLocalization_basicOpen r + have : IsLocalization.Away r Γ(X, X.basicOpen r) := hV.isLocalization_basicOpen r exact hfs r hr _ · obtain ⟨U, V, hxV, e, hf⟩ := hf x use U, V, hxV, e simp only [iff_of_isAffine (P := P), Scheme.Hom.appLE, homOfLE_leOfHom] at hf ⊢ - haveI : (toMorphismProperty (Locally Q)).RespectsIso := toMorphismProperty_respectsIso_iff.mp <| + have : (toMorphismProperty (Locally Q)).RespectsIso := toMorphismProperty_respectsIso_iff.mp <| (isLocal_ringHomProperty P).respectsIso exact (MorphismProperty.arrow_mk_iso_iff (toMorphismProperty (Locally Q)) (arrowResLEAppIso f U V e)).mpr (locally_of hQi _ hf) @@ -648,8 +648,8 @@ lemma iff_exists_appLE (hQ : StableUnderCompositionWithLocalizationAwaySource Q) : P f ↔ ∀ (x : X), ∃ (U : Y.affineOpens) (V : X.affineOpens) (_ : x ∈ V.1) (e : V.1 ≤ f ⁻¹ᵁ U.1), Q (f.appLE U V e).hom := by - haveI inst : HasRingHomProperty P Q := inferInstance - haveI : HasRingHomProperty P (Locally Q) := by + have inst : HasRingHomProperty P Q := inferInstance + have : HasRingHomProperty P (Locally Q) := by apply @copy (P := P) (P' := P) (Q := Q) (Q' := Locally Q) · infer_instance · rfl @@ -657,7 +657,7 @@ lemma iff_exists_appLE exact (locally_iff_of_localizationSpanTarget (isLocal_ringHomProperty P).respectsIso (isLocal_ringHomProperty P).ofLocalizationSpanTarget _).symm rw [iff_exists_appLE_locally (P := P) hQ] - haveI : HasRingHomProperty P Q := inst + have : HasRingHomProperty P Q := inst apply (isLocal_ringHomProperty P (Q := Q)).respectsIso omit [HasRingHomProperty P Q] in @@ -668,7 +668,7 @@ lemma locally_of_iff (hQl : LocalizationAwayPreserves Q) Q (f.appLE U V e).hom) : HasRingHomProperty P (Locally Q) where isLocal_ringHomProperty := locally_propertyIsLocal hQl hQa eq_affineLocally' := by - haveI : HasRingHomProperty (affineLocally (Locally Q)) (Locally Q) := + have : HasRingHomProperty (affineLocally (Locally Q)) (Locally Q) := ⟨locally_propertyIsLocal hQl hQa, rfl⟩ ext X Y f rw [h, iff_exists_appLE_locally (P := affineLocally (Locally Q)) hQa.left hQa.respectsIso] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean index 853b0ae33aa695..ec6d7babd6592f 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean @@ -101,7 +101,7 @@ instance (f : X ⟶ Y) (U : X.Opens) (V : Y.Opens) (e) [IsSeparated f] : instance (R S : CommRingCat.{u}) (f : R ⟶ S) : IsSeparated (Spec.map f) := by constructor - letI := f.hom.toAlgebra + let := f.hom.toAlgebra change IsClosedImmersion (Limits.pullback.diagonal (Spec.map (CommRingCat.ofHom (algebraMap R S)))) rw [diagonal_SpecMap, MorphismProperty.cancel_right_of_respectsIso @IsClosedImmersion] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean b/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean index c2148914765695..e20cdadb21aa32 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean @@ -220,7 +220,7 @@ instance smoothOfRelativeDimension_comp {Z : Scheme.{u}} (g : Y ⟶ Z) g.appLE_map_assoc, Scheme.Hom.appLE_comp_appLE] refine ⟨U₂, hU₂, X.basicOpen s, hV₁'.basicOpen s, hx₁, e, heq ▸ ?_⟩ apply IsStandardSmoothOfRelativeDimension.comp ?_ hf₂ - haveI : IsLocalization.Away r Γ(Y, Y.basicOpen r) := hV₂.isLocalization_basicOpen r + have : IsLocalization.Away r Γ(Y, Y.basicOpen r) := hV₂.isLocalization_basicOpen r exact (isStandardSmoothOfRelativeDimension_stableUnderCompositionWithLocalizationAway n).left _ r _ hf₁ @@ -246,7 +246,7 @@ lemma formallySmooth_stalkMap_iff {f : X ⟶ Y} {x : X} (U : Y.Opens) letI := (f.appLE U V hVU).hom.toAlgebra (f.stalkMap x).hom.FormallySmooth ↔ hV.primeIdealOf ⟨x, hx⟩ ∈ Algebra.smoothLocus Γ(Y, U) Γ(X, V) := by - letI := (f.appLE U V hVU).hom.toAlgebra + let := (f.appLE U V hVU).hom.toAlgebra let p := (hU.primeIdealOf ⟨f x, hVU hx⟩).asIdeal let q := (hV.primeIdealOf ⟨x, hx⟩).asIdeal have : q.LiesOver p := diff --git a/Mathlib/AlgebraicGeometry/Normalization.lean b/Mathlib/AlgebraicGeometry/Normalization.lean index c46bb56d0fbf37..bba3c77eb14d13 100644 --- a/Mathlib/AlgebraicGeometry/Normalization.lean +++ b/Mathlib/AlgebraicGeometry/Normalization.lean @@ -99,7 +99,7 @@ lemma coequifibered_normalizationDiagramMap : (f.isQuasiSeparated_preimage U.2.isQuasiSeparated) (f.app _ r) change IsLocalization.Away ((algebraMap Γ(Y, U.1) (integralClosure Γ(Y, U.1) Γ(X, f ⁻¹ᵁ U.1))) r) (integralClosure Γ(Y, Y.basicOpen r) Γ(X, f ⁻¹ᵁ Y.basicOpen r)) - letI : Algebra ↑Γ(Y, U.1) ↑Γ(X, f ⁻¹ᵁ Y.basicOpen r) := + let : Algebra ↑Γ(Y, U.1) ↑Γ(X, f ⁻¹ᵁ Y.basicOpen r) := (f.appLE _ _ (f.preimage_mono (Y.basicOpen_le _))).hom.toAlgebra have : IsScalarTower Γ(Y, U.1) Γ(X, f ⁻¹ᵁ U.1) Γ(X, f ⁻¹ᵁ Y.basicOpen r) := .of_algebraMap_eq' rfl have : IsScalarTower Γ(Y, U.1) Γ(Y, Y.basicOpen r) Γ(X, f ⁻¹ᵁ Y.basicOpen r) := @@ -204,7 +204,7 @@ instance : IsIntegralHom f.fromNormalization := by rw [← MorphismProperty.cancel_left_of_respectsIso @IsIntegralHom e.inv, ← MorphismProperty.cancel_right_of_respectsIso @IsIntegralHom _ U.2.isoSpec.hom] have : (f.normalizationDiagramMap.app (.op U)).hom.IsIntegral := by - letI := (f.app U).hom.toAlgebra + let := (f.app U).hom.toAlgebra change (algebraMap Γ(Y, U) (integralClosure Γ(Y, U) Γ(X, f ⁻¹ᵁ U))).IsIntegral exact algebraMap_isIntegral_iff.mpr inferInstance convert! IsIntegralHom.SpecMap_iff.mpr this @@ -256,7 +256,7 @@ set_option backward.isDefEq.respectTransparency false in lemma fromNormalization_app {U : Y.Opens} (hU : IsAffineOpen U) : f.fromNormalization.app U = CommRingCat.ofHom (algebraMap _ _) ≫ (f.normalizationObjIso hU).inv := by - letI := (f.app U).hom.toAlgebra + let := (f.app U).hom.toAlgebra have : IsIso (((normalizationOpenCover f).f ⟨U, hU⟩).app (f.fromNormalization ⁻¹ᵁ U)) := Scheme.Hom.isIso_app _ _ (by simp [← fromNormalization_preimage]) have H : ⊤ = ((normalizationOpenCover f).f ⟨U, hU⟩ ≫ fromNormalization f) ⁻¹ᵁ U := by @@ -289,7 +289,7 @@ instance [IsIntegralHom f] : IsIso f.toNormalization := by Hom.opensRange_pullbackFst, ← f.fromNormalization_preimage, ← Scheme.Hom.comp_preimage]) rw [← MorphismProperty.cancel_left_of_respectsIso (.isomorphisms _) (e ≪≫ (U.2.preimage f).isoSpec).inv] - letI := (f.app U.1).hom.toAlgebra + let := (f.app U.1).hom.toAlgebra convert_to! IsIso (Spec.map (CommRingCat.ofHom (integralClosure Γ(Y, U.1) Γ(X, f ⁻¹ᵁ U.1)).val.toRingHom)) · rw [← cancel_mono (f.normalizationOpenCover.f U), ← cancel_epi (U.2.preimage f).isoSpec.hom] @@ -400,7 +400,7 @@ lemma toNormalization_normalizationDesc (H : f = f₁ ≫ f₂) : f.toNormalization ≫ f.normalizationDesc f₁ f₂ H = f₁ := by refine Scheme.Cover.hom_ext (X.openCoverOfIsOpenCover _ (.comap (iSup_affineOpens_eq_top Y) f.base.hom)) _ _ fun U ↦ ?_ - letI := (f.app U.1).hom.toAlgebra + let := (f.app U.1).hom.toAlgebra refine (Scheme.Hom.ι_toNormalization_assoc ..).trans ?_ dsimp [normalizationOpenCover, normalizationDesc] simp only [colimit.ι_desc, ← Spec.map_comp_assoc] diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean index b3d1dc0389c669..2d3a1472a40f32 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean @@ -310,8 +310,8 @@ lemma awayι_preimage_basicOpen : (pullbackAwayιIso 𝒜 f_deg hm g_deg hm' rfl).inv.homeomorph.surjective), ← opensRange_awayι _ _ g_deg hm'] simp [IsOpenImmersion.range_pullbackFst] - · letI := (awayMap (f := f) 𝒜 g_deg rfl).toAlgebra - letI := HomogeneousLocalization.Away.isLocalization_mul f_deg g_deg rfl hm.ne' + · let := (awayMap (f := f) 𝒜 g_deg rfl).toAlgebra + let := HomogeneousLocalization.Away.isLocalization_mul f_deg g_deg rfl hm.ne' exact PrimeSpectrum.localization_away_comap_range _ _ open TopologicalSpace.Opens in diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean index 10c2bdfa34cc70..421865fdbc6e94 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean @@ -218,7 +218,7 @@ theorem valuativeCriterion_existence_aux simp only [ψ, map_pow, pow_eq_zero_iff', map_eq_zero, ne_eq] at this have : φ 1 = 0 := by convert! (this j).1; ext; simp simp only [map_one, one_ne_zero] at this - letI := (awayMap 𝒜 (f := x j) (hxdi i₀) rfl).toAlgebra + let := (awayMap 𝒜 (f := x j) (hxdi i₀) rfl).toAlgebra have := Away.isLocalization_mul (hxdi j) (hxdi i₀) rfl (hdi _).ne' have hunit : IsUnit (φ (Away.isLocalizationElem (hxdi j) (hxdi i₀))) := isUnit_iff_ne_zero.mpr fun rid ↦ hKmax.ne' (.symm (by simpa [ψ, rid, Finset.prod_eq_zero_iff, (hdi _).ne'] using hi1)) diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index b56912df297135..b5584e1c408462 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -725,7 +725,7 @@ lemma isLocalization_atPrime (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 @IsLocalization (Away 𝒜 f) _ ((toSpec 𝒜 f).base x).asIdeal.primeCompl (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) _ (mapId 𝒜 (Submonoid.powers_le.mpr x.2)).toAlgebra := by - letI : Algebra (Away 𝒜 f) (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) := + let : Algebra (Away 𝒜 f) (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) := (mapId 𝒜 (Submonoid.powers_le.mpr x.2)).toAlgebra constructor; constructor · rintro ⟨y, hy⟩ @@ -817,10 +817,10 @@ lemma stalkMap_toSpec (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : set_option backward.isDefEq.respectTransparency false in lemma isIso_toSpec (f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : IsIso (toSpec 𝒜 f) := by - haveI : IsIso (toSpec 𝒜 f).base := toSpec_base_isIso 𝒜 f_deg hm - haveI _ (x) : IsIso ((toSpec 𝒜 f).stalkMap x) := by + have : IsIso (toSpec 𝒜 f).base := toSpec_base_isIso 𝒜 f_deg hm + have _ (x) : IsIso ((toSpec 𝒜 f).stalkMap x) := by rw [stalkMap_toSpec 𝒜 f x f_deg hm]; infer_instance - haveI : LocallyRingedSpace.IsOpenImmersion (toSpec 𝒜 f) := + have : LocallyRingedSpace.IsOpenImmersion (toSpec 𝒜 f) := LocallyRingedSpace.IsOpenImmersion.of_stalk_iso (toSpec 𝒜 f) (TopCat.homeoOfIso (asIso <| (toSpec 𝒜 f).base)).isOpenEmbedding exact LocallyRingedSpace.IsOpenImmersion.to_iso _ diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index 6d7e1302696a37..760c2610436a9c 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -192,7 +192,7 @@ theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : X.Opens | h₂ X Y f => refine ⟨f ⁻¹ᵁ f.opensRange, f.opensRange, by simp, rfl, ?_⟩ rintro H hX s hs _ ⟨x, rfl⟩ - haveI := isReduced_of_isOpenImmersion f + have := isReduced_of_isOpenImmersion f specialize H (f.app _ s) _ x ⟨x, rfl⟩ · rw [← Scheme.preimage_basicOpen, hs]; ext1; simp [Opens.map] · have H : (X.presheaf.germ _ x _).hom _ = 0 := H @@ -249,10 +249,10 @@ instance (priority := 900) isReduced_of_isIntegral [IsIntegral X] : IsReduced X intro U rcases U.1.eq_empty_or_nonempty with h | h · have : U = ⊥ := SetLike.ext' h - haveI : Subsingleton Γ(X, U) := + have : Subsingleton Γ(X, U) := CommRingCat.subsingleton_of_isTerminal (X.sheaf.isTerminalOfEqEmpty this) infer_instance - · haveI : Nonempty U := by simpa + · have : Nonempty U := by simpa infer_instance instance Scheme.component_nontrivial (X : Scheme.{u}) (U : X.Opens) [Nonempty U] : @@ -267,9 +267,9 @@ instance irreducibleSpace_of_isIntegral [IsIntegral X] : IrreducibleSpace X := b simp_rw [isPreirreducible_iff_isClosed_union_isClosed, not_forall, not_or] at H rcases H with ⟨S, T, hS, hT, h₁, h₂, h₃⟩ rw [Set.not_univ_subset] at h₂ h₃ - haveI : Nonempty (⟨Sᶜ, hS.1⟩ : X.Opens) := ⟨⟨_, h₂.choose_spec⟩⟩ - haveI : Nonempty (⟨Tᶜ, hT.1⟩ : X.Opens) := ⟨⟨_, h₃.choose_spec⟩⟩ - haveI : Nonempty (⟨Sᶜ, hS.1⟩ ⊔ ⟨Tᶜ, hT.1⟩ : X.Opens) := ⟨⟨_, Or.inl h₂.choose_spec⟩⟩ + have : Nonempty (⟨Sᶜ, hS.1⟩ : X.Opens) := ⟨⟨_, h₂.choose_spec⟩⟩ + have : Nonempty (⟨Tᶜ, hT.1⟩ : X.Opens) := ⟨⟨_, h₃.choose_spec⟩⟩ + have : Nonempty (⟨Sᶜ, hS.1⟩ ⊔ ⟨Tᶜ, hT.1⟩ : X.Opens) := ⟨⟨_, Or.inl h₂.choose_spec⟩⟩ let e : Γ(X, _) ≅ CommRingCat.of _ := (X.sheaf.isProductOfDisjoint ⟨_, hS.1⟩ ⟨_, hT.1⟩ ?_).conePointUniqueUpToIso (CommRingCat.prodFanIsLimit _ _) @@ -287,7 +287,7 @@ theorem isIntegral_of_irreducibleSpace_of_isReduced [IsReduced X] [H : Irreducib IsIntegral X := by constructor; · infer_instance intro U hU - haveI := (@LocallyRingedSpace.component_nontrivial X.toLocallyRingedSpace U hU).1 + have := (@LocallyRingedSpace.component_nontrivial X.toLocallyRingedSpace U hU).1 have : NoZeroDivisors (X.toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace.presheaf.obj (op U)) := by refine ⟨fun {a b} e => ?_⟩ diff --git a/Mathlib/AlgebraicGeometry/Pullbacks.lean b/Mathlib/AlgebraicGeometry/Pullbacks.lean index bd40b94c85ad3f..1a38ac3c192834 100644 --- a/Mathlib/AlgebraicGeometry/Pullbacks.lean +++ b/Mathlib/AlgebraicGeometry/Pullbacks.lean @@ -507,7 +507,7 @@ def openCoverOfLeft (𝒰 : OpenCover.{v} X) (f : X ⟶ Z) (g : Y ⟶ Z) : mem₀ := by rw [ofArrows_mem_precoverage_iff] refine ⟨fun x ↦ ?_, fun i ↦ ?_⟩ - · letI 𝒱 := ((gluing 𝒰.ulift f g).openCover.pushforwardIso + · let 𝒱 := ((gluing 𝒰.ulift f g).openCover.pushforwardIso (limit.isoLimitCone ⟨_, gluedIsLimit 𝒰.ulift f g⟩).inv).copy 𝒰.ulift.I₀ (fun i => pullback (𝒰.ulift.f i ≫ f) g) (fun i => pullback.map _ _ _ _ (𝒰.ulift.f i) (𝟙 _) (𝟙 _) (Category.comp_id _) (by simp)) diff --git a/Mathlib/AlgebraicGeometry/Sites/Etale.lean b/Mathlib/AlgebraicGeometry/Sites/Etale.lean index 6bcfcdeea6eb76..357b3376c30b20 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Etale.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Etale.lean @@ -77,7 +77,7 @@ lemma ofArrows_mem_smallEtaleTopology_iff let V : Cover (precoverage @Etale) W.left := Cover.mkOfCovers W.left (fun w ↦ (Z (i w)).left) (fun w ↦ (f (i w)).left) (fun w ↦ ⟨_, _, hz w⟩) inferInstance - letI : Cover.Over X V := + let : Cover.Over X V := { over w := ⟨(Z (i w)).hom⟩ isOver_map w := by cat_disch } have (w : W.left) : Etale (V.X w ↘ X) := (Z (i w)).prop diff --git a/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean b/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean index bc84f286e65bbc..db8609d3765cc5 100644 --- a/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean +++ b/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean @@ -50,7 +50,7 @@ lemma IsJointlySurjectivePreserving.exists_preimage_snd_triplet_of_prop (hf : P f) (x : X) (y : Y) (h : f x = g y) : ∃ a : ↑(pullback f g), pullback.snd f g a = y := by let iso := pullbackSymmetry f g - haveI : HasPullback g f := hasPullback_symmetry f g + have : HasPullback g f := hasPullback_symmetry f g obtain ⟨a, ha⟩ := exists_preimage_fst_triplet_of_prop hf y x h.symm use (pullbackSymmetry f g).inv a rwa [← Scheme.Hom.comp_apply, pullbackSymmetry_inv_comp_snd] diff --git a/Mathlib/AlgebraicGeometry/Sites/Small.lean b/Mathlib/AlgebraicGeometry/Sites/Small.lean index eb2ee33aaa6afc..137bcc660f4a02 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Small.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Small.lean @@ -113,8 +113,8 @@ lemma overGrothendieckTopology_eq_toGrothendieck_overPretopology : · intro hR obtain ⟨𝒰, hle⟩ := exists_cover_of_mem_grothendieckTopology hR rw [mem_grothendieckTopology_iff] at hR - letI (i : 𝒰.I₀) : (𝒰.X i).Over S := { hom := 𝒰.f i ≫ X.hom } - letI : 𝒰.Over S := + let (i : 𝒰.I₀) : (𝒰.X i).Over S := { hom := 𝒰.f i ≫ X.hom } + let : 𝒰.Over S := { over := inferInstance isOver_map := fun i ↦ ⟨rfl⟩ } use 𝒰.toPresieveOver, ⟨𝒰, inferInstance, rfl⟩ @@ -249,7 +249,7 @@ lemma mem_toGrothendieck_smallPretopology (X : Q.Over ⊤ S) (R : Sieve X) : mem₀ := by rw [presieve₀_mem_precoverage_iff] refine ⟨fun x ↦ ⟨x, y x, hy x⟩, hP⟩ } - letI : 𝒰.Over S := + let : 𝒰.Over S := { over := fun i ↦ inferInstance isOver_map := fun i ↦ inferInstance } refine ⟨𝒰.toPresieveOverProp fun i ↦ MorphismProperty.Comma.prop _, ?_, ?_⟩ diff --git a/Mathlib/AlgebraicGeometry/SpreadingOut.lean b/Mathlib/AlgebraicGeometry/SpreadingOut.lean index bad1ab4203d0da..e9a6e69c450d7c 100644 --- a/Mathlib/AlgebraicGeometry/SpreadingOut.lean +++ b/Mathlib/AlgebraicGeometry/SpreadingOut.lean @@ -243,16 +243,16 @@ lemma exists_lift_of_germInjective_aux {U : X.Opens} {x : X} (hxU) (e : φRA ≫ φ = φRX ≫ X.presheaf.germ U x hxU) : ∃ (V : X.Opens) (hxV : x ∈ V), V ≤ U ∧ RingHom.range φ.hom ≤ RingHom.range (X.presheaf.germ V x hxV).hom := by - letI := φRA.hom.toAlgebra + let := φRA.hom.toAlgebra obtain ⟨s, hs⟩ := hφRA choose W hxW f hf using fun t ↦ X.presheaf.exists_germ_eq (φ t) have H : x ∈ s.inf W ⊓ U := by rw [← SetLike.mem_coe, TopologicalSpace.Opens.coe_inf, TopologicalSpace.Opens.coe_finset_inf] exact ⟨by simpa using fun x _ ↦ hxW x, hxU⟩ refine ⟨s.inf W ⊓ U, H, inf_le_right, ?_⟩ - letI := φRX.hom.toAlgebra - letI := (φRX ≫ X.presheaf.germ U x hxU).hom.toAlgebra - letI := (φRX ≫ X.presheaf.map (homOfLE (inf_le_right (a := s.inf W))).op).hom.toAlgebra + let := φRX.hom.toAlgebra + let := (φRX ≫ X.presheaf.germ U x hxU).hom.toAlgebra + let := (φRX ≫ X.presheaf.map (homOfLE (inf_le_right (a := s.inf W))).op).hom.toAlgebra let φ' : A →ₐ[R] X.presheaf.stalk x := { φ.hom with commutes' := DFunLike.congr_fun (congr_arg CommRingCat.Hom.hom e) } let ψ : Γ(X, s.inf W ⊓ U) →ₐ[R] X.presheaf.stalk x := diff --git a/Mathlib/AlgebraicGeometry/Stalk.lean b/Mathlib/AlgebraicGeometry/Stalk.lean index 72a527c40f8f2e..d5819c24cc2007 100644 --- a/Mathlib/AlgebraicGeometry/Stalk.lean +++ b/Mathlib/AlgebraicGeometry/Stalk.lean @@ -79,7 +79,7 @@ theorem IsAffineOpen.fromSpecStalk_eq_fromSpecStalk {x : X} (hxU : x ∈ U) : instance IsAffineOpen.fromSpecStalk_isPreimmersion {X : Scheme.{u}} {U : Opens X} (hU : IsAffineOpen U) (x : X) (hx : x ∈ U) : IsPreimmersion (hU.fromSpecStalk hx) := by dsimp [IsAffineOpen.fromSpecStalk] - haveI : IsPreimmersion (Spec.map (X.presheaf.germ U x hx)) := + have : IsPreimmersion (Spec.map (X.presheaf.germ U x hx)) := letI : Algebra Γ(X, U) (X.presheaf.stalk x) := (X.presheaf.germ U x hx).hom.toAlgebra haveI := hU.isLocalization_stalk ⟨x, hx⟩ IsPreimmersion.of_isLocalization (R := Γ(X, U)) (S := X.presheaf.stalk x) diff --git a/Mathlib/AlgebraicGeometry/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/StructureSheaf.lean index 065a8b4d8d8362..72c6d227ac68a8 100644 --- a/Mathlib/AlgebraicGeometry/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/StructureSheaf.lean @@ -985,9 +985,9 @@ set_option backward.isDefEq.respectTransparency false in lemma Localizations.comapFun_mk (y : PrimeSpectrum.Top S) (a : M) (b : (y.comap σ).asIdeal.primeCompl) : Localizations.comapFun f y (.mk a b) = .mk (f a) ⟨σ b.1, b.2⟩ := by - letI := Module.compHom N σ - letI := σ.toAlgebra - haveI : IsScalarTower R S N := .of_algebraMap_smul fun _ _ ↦ rfl + let := Module.compHom N σ + let := σ.toAlgebra + have : IsScalarTower R S N := .of_algebraMap_smul fun _ _ ↦ rfl apply ((Module.End.isUnit_iff _).mp (IsLocalizedModule.map_units (S := y.asIdeal.primeCompl) (LocalizedModule.mkLinearMap y.asIdeal.primeCompl N) ⟨σ b, b.2⟩)).1 dsimp @@ -1020,9 +1020,9 @@ theorem isLocallyFraction_comapFun (U : Opens (PrimeSpectrum.Top R)) (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap σ ⁻¹' U.1) (s : ∀ x : U, Localizations M x.1) (hs : (isLocallyFraction R M).toPrelocalPredicate.pred s) : (isLocallyFraction S N).toPrelocalPredicate.pred (comapFun f U V hUV s) := by - letI := Module.compHom N σ - letI := σ.toAlgebra - haveI : IsScalarTower R S N := .of_algebraMap_smul fun _ _ ↦ rfl + let := Module.compHom N σ + let := σ.toAlgebra + have : IsScalarTower R S N := .of_algebraMap_smul fun _ _ ↦ rfl rintro ⟨p, hpV⟩ obtain ⟨W, m, iWU, a, b, h_frac⟩ := hs ⟨PrimeSpectrum.comap σ p, hUV hpV⟩ refine ⟨⟨_, (PrimeSpectrum.continuous_comap σ).isOpen_preimage _ W.2⟩ ⊓ V, diff --git a/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean b/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean index 0394d01b69ff79..36739968f748a9 100644 --- a/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean +++ b/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean @@ -144,9 +144,9 @@ set_option backward.isDefEq.respectTransparency false in lemma of_specializingMap (H : (topologically @SpecializingMap).universally f) : ValuativeCriterion.Existence f := by rintro ⟨R, K, i₁, i₂, ⟨w⟩⟩ - haveI : IsDomain (CommRingCat.of R) := ‹_› - haveI : ValuationRing (CommRingCat.of R) := ‹_› - letI : Field (CommRingCat.of K) := ‹_› + have : IsDomain (CommRingCat.of R) := ‹_› + have : ValuationRing (CommRingCat.of R) := ‹_› + let : Field (CommRingCat.of K) := ‹_› replace H := H (pullback.snd i₂ f) i₂ (pullback.fst i₂ f) (.of_hasPullback i₂ f) let lft := pullback.lift (Spec.map (CommRingCat.ofHom (algebraMap R K))) i₁ w.symm obtain ⟨x, h₁, h₂⟩ := @H (lft (closedPoint _)) _ (specializes_closedPoint (R := R) _) diff --git a/Mathlib/AlgebraicTopology/DoldKan/NReflectsIso.lean b/Mathlib/AlgebraicTopology/DoldKan/NReflectsIso.lean index b73fc26d9b4b64..74464e436023ef 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/NReflectsIso.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/NReflectsIso.lean @@ -43,7 +43,7 @@ instance : (N₁ : SimplicialObject C ⥤ Karoubi (ChainComplex C ℕ)).Reflects intro -- restating the result in a way that allows induction on the degree n suffices ∀ n : ℕ, IsIso (f.app (op ⦋n⦌)) by - haveI : ∀ Δ : SimplexCategoryᵒᵖ, IsIso (f.app Δ) := fun Δ => this Δ.unop.len + have : ∀ Δ : SimplexCategoryᵒᵖ, IsIso (f.app Δ) := fun Δ => this Δ.unop.len apply NatIso.isIso_of_isIso_app -- restating the assumption in a more practical form have h₁ := HomologicalComplex.congr_hom (Karoubi.hom_ext_iff.mp (IsIso.hom_inv_id (N₁.map f))) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 2aadc5ef00a66b..32e553ab4ed331 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -813,10 +813,10 @@ theorem eq_σ_of_epi {n : ℕ} (θ : ⦋n + 1⦌ ⟶ ⦋n⦌) [Epi θ] : ∃ i : rw [← mono_iff_injective] grind [→ le_of_mono]) use i - haveI : Epi (σ i ≫ θ') := by + have : Epi (σ i ≫ θ') := by rw [← h] infer_instance - haveI := CategoryTheory.epi_of_epi (σ i) θ' + have := CategoryTheory.epi_of_epi (σ i) θ' rw [h, eq_id_of_epi θ', Category.comp_id] theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i : Fin (n + 2), θ = δ i := by @@ -824,10 +824,10 @@ theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i rw [← epi_iff_surjective] grind [→ le_of_epi]) use i - haveI : Mono (θ' ≫ δ i) := by + have : Mono (θ' ≫ δ i) := by rw [← h] infer_instance - haveI := CategoryTheory.mono_of_mono θ' (δ i) + have := CategoryTheory.mono_of_mono θ' (δ i) rw [h, eq_id_of_mono θ', Category.id_comp] theorem len_lt_of_mono {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) [Mono i] (hi' : Δ ≠ Δ') : @@ -849,14 +849,14 @@ instance (Δ Δ' : SimplexCategory) (θ : Δ ⟶ Δ') : Epi (factorThruImage θ) theorem image_eq {Δ Δ' Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ Δ'} [Epi e] {i : Δ' ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : image φ = Δ' := by - haveI := strongEpi_of_epi e + have := strongEpi_of_epi e let e := image.isoStrongEpiMono e i fac ext exact le_antisymm (len_le_of_epi e.hom) (len_le_of_mono e.hom) theorem image_ι_eq {Δ Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ image φ} [Epi e] {i : image φ ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : image.ι φ = i := by - haveI := strongEpi_of_epi e + have := strongEpi_of_epi e rw [← image.isoStrongEpiMono_hom_comp_ι e i fac, SimplexCategory.eq_id_of_isIso (image.isoStrongEpiMono e i fac).hom, Category.id_comp] diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean index 808bbc3b83a4c1..06e3c23bef6591 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean @@ -528,7 +528,7 @@ instance (x y : OneTruncation₂ ((truncation 2).obj Δ[0])) : Unique (x ⟶ y) obtain rfl : y = default := Unique.uniq _ _ exact 𝟙rq instUniqueOneTruncation₂DeltaZero.default uniq _ := by - letI : Subsingleton (((truncation 2).obj Δ[0]).obj (.op ⦋1⦌₂)) := + let : Subsingleton (((truncation 2).obj Δ[0]).obj (.op ⦋1⦌₂)) := inferInstanceAs (Subsingleton (ULift.{_, 0} (⦋1⦌ ⟶ ⦋0⦌))) ext exact this.allEq _ _ diff --git a/Mathlib/Analysis/BoxIntegral/Integrability.lean b/Mathlib/Analysis/BoxIntegral/Integrability.lean index 79185dec889b35..78b21d0d7a3be0 100644 --- a/Mathlib/Analysis/BoxIntegral/Integrability.lean +++ b/Mathlib/Analysis/BoxIntegral/Integrability.lean @@ -110,7 +110,7 @@ theorem HasIntegral.of_aeEq_zero {l : IntegrationParams} {I : Box ι} {f : (ι refine hasIntegral_iff.2 fun ε ε0 => ?_ lift ε to ℝ≥0 using ε0.lt.le; rw [gt_iff_lt, NNReal.coe_pos] at ε0 rcases NNReal.exists_pos_sum_of_countable ε0.ne' ℕ with ⟨δ, δ0, c, hδc, hcε⟩ - haveI := Fact.mk (I.measure_coe_lt_top μ) + have := Fact.mk (I.measure_coe_lt_top μ) change μ.restrict I {x | f x ≠ 0} = 0 at hf set N : (ι → ℝ) → ℕ := fun x => ⌈‖f x‖⌉₊ have N0 : ∀ {x}, N x = 0 ↔ f x = 0 := by simp [N] @@ -176,7 +176,7 @@ theorem hasBoxIntegral (f : SimpleFunc (ι → ℝ) E) (μ : Measure (ι → ℝ | @const y s hs => simpa [hs] using! BoxIntegral.hasIntegralIndicatorConst l hl hs I y μ | @add f g _ hfi hgi => - borelize E; haveI := Fact.mk (I.measure_coe_lt_top μ) + borelize E; have := Fact.mk (I.measure_coe_lt_top μ) rw [integral_add] exacts [hfi.add hgi, integrable_iff.2 fun _ _ => measure_lt_top _ _, integrable_iff.2 fun _ _ => measure_lt_top _ _] @@ -202,7 +202,7 @@ theorem IntegrableOn.hasBoxIntegral [CompleteSpace E] {f : (ι → ℝ) → E} { borelize E -- First we replace an `ae_strongly_measurable` function by a measurable one. rcases hf.aestronglyMeasurable with ⟨g, hg, hfg⟩ - haveI : SeparableSpace (range g ∪ {0} : Set E) := hg.separableSpace_range_union_singleton + have : SeparableSpace (range g ∪ {0} : Set E) := hg.separableSpace_range_union_singleton rw [integral_congr_ae hfg]; have hgi : IntegrableOn g I μ := (integrable_congr hfg).1 hf refine BoxIntegral.HasIntegral.congr_ae ?_ hfg.symm hl clear! f diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean index 79341b514c28bc..acbf8358e6f475 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean @@ -158,7 +158,7 @@ open scoped NonUnitalContinuousFunctionalCalculus in lemma inrNonUnitalStarAlgHom_comp_cfcₙHom_eq_cfcₙAux (a : A) (ha : p a) : letI _ := RCLike.nonUnitalContinuousFunctionalCalculus hp₁ (inrNonUnitalStarAlgHom 𝕜 A).comp (cfcₙHom ha) = cfcₙAux hp₁ a ha := by - letI _ := RCLike.nonUnitalContinuousFunctionalCalculus hp₁ + let _ := RCLike.nonUnitalContinuousFunctionalCalculus hp₁ apply ContinuousMapZero.UniqueHom.eq_of_continuous_of_map_id _ _ _ (Unitization.continuous_inr.comp <| cfcₙHom_continuous ha) (continuous_cfcₙAux hp₁ a ha) diff --git a/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean b/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean index 36568b8076f591..211d87a80843c2 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Convolution.lean @@ -228,7 +228,7 @@ theorem hasFDerivAt_convolution_right_with_param {g : P → G → E'} {s : Set P rcases Metric.mem_nhds_iff.1 V_mem with ⟨δ, δpos, hδ⟩ refine ⟨min δ ε, lt_min δpos εpos, min_le_right δ ε, ?_⟩ exact (add_subset_add_left ((ball_subset_ball (min_le_left _ _)).trans hδ)).trans hV - letI := ContinuousLinearMap.hasOpNorm (𝕜 := 𝕜) (𝕜₂ := 𝕜) (E := E) + let := ContinuousLinearMap.hasOpNorm (𝕜 := 𝕜) (𝕜₂ := 𝕜) (E := E) (F := (P × G →L[𝕜] E') →L[𝕜] P × G →L[𝕜] F) (σ₁₂ := RingHom.id 𝕜) let bound : G → ℝ := indicator U fun t => ‖(L.precompR (P × G))‖ * ‖f t‖ * C have I4 : ∀ᵐ a : G ∂μ, ∀ x : P × G, dist x q₀ < δ → diff --git a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean index 9eea53aa522cbb..4276e5a0d0b4ad 100644 --- a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean +++ b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean @@ -327,7 +327,7 @@ protected theorem injOn (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) protected theorem surjective [CompleteSpace E] (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) univ c) (hc : Subsingleton E ∨ c < N⁻¹) : Surjective f := by rcases hc with hE | hc - · haveI : Subsingleton F := (Equiv.subsingleton_congr f'.toEquiv).1 hE + · have : Subsingleton F := (Equiv.subsingleton_congr f'.toEquiv).1 hE exact surjective_to_subsingleton _ · apply forall_of_forall_mem_closedBall (fun y : F => ∃ a, f a = y) (f 0) _ have hc' : (0 : ℝ) < N⁻¹ - c := by rw [sub_pos]; exact hc diff --git a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FiniteDimensional.lean b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FiniteDimensional.lean index 786bee9c4324cb..07e541f43ed914 100644 --- a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FiniteDimensional.lean +++ b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FiniteDimensional.lean @@ -47,7 +47,7 @@ theorem exists_homeomorph_extension {E : Type*} [NormedAddCommGroup E] [NormedSp convert! hu ext x simp only [g, add_sub_cancel_left, ContinuousLinearEquiv.coe_coe, Pi.sub_apply] - haveI : FiniteDimensional ℝ E := f'.symm.finiteDimensional + have : FiniteDimensional ℝ E := f'.symm.finiteDimensional exact ⟨hg.toHomeomorph g hc, fg⟩ end ApproximatesLinearOn diff --git a/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean b/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean index 60ab3b165970af..a65c966af5f657 100644 --- a/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean +++ b/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean @@ -111,7 +111,7 @@ theorem IsLocalExtrOn.exists_multipliers_of_hasStrictFDerivAt {ι : Type*} [Fint {f : ι → E → ℝ} {f' : ι → StrongDual ℝ E} (hextr : IsLocalExtrOn φ {x | ∀ i, f i x = f i x₀} x₀) (hf' : ∀ i, HasStrictFDerivAt (f i) (f' i) x₀) (hφ' : HasStrictFDerivAt φ φ' x₀) : ∃ (Λ : ι → ℝ) (Λ₀ : ℝ), (Λ, Λ₀) ≠ 0 ∧ (∑ i, Λ i • f' i) + Λ₀ • φ' = 0 := by - letI := Classical.decEq ι + let := Classical.decEq ι replace hextr : IsLocalExtrOn φ {x | (fun i => f i x) = fun i => f i x₀} x₀ := by simpa only [funext_iff] using hextr rcases hextr.exists_linear_map_of_hasStrictFDerivAt (hasStrictFDerivAt_pi.2 fun i => hf' i) diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index c836382083c822..a83c1b6a95c470 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -133,7 +133,7 @@ lemma logDeriv_eqOn_iff [IsRCLikeNormedField 𝕜] {f g : 𝕜 → 𝕜'} {s : S simp only [Pi.sub_apply, Pi.mul_apply, Pi.inv_apply, Pi.div_apply, Pi.pow_apply, Pi.zero_apply] grind [logDeriv_apply, Pi.div_apply] - letI := IsRCLikeNormedField.rclike 𝕜 + let := IsRCLikeNormedField.rclike 𝕜 obtain ⟨a, ha⟩ := hs2.exists_is_const_of_deriv_eq_zero hsc (hf.mul (hg.inv hgn)) hfg grind [Pi.mul_apply, Pi.inv_apply, Pi.smul_apply, smul_eq_mul] · rintro ⟨z, hz0, hz⟩ x hx diff --git a/Mathlib/Analysis/Calculus/MeanValue.lean b/Mathlib/Analysis/Calculus/MeanValue.lean index fabcfd43dc9227..de2f76a7db82e1 100644 --- a/Mathlib/Analysis/Calculus/MeanValue.lean +++ b/Mathlib/Analysis/Calculus/MeanValue.lean @@ -415,7 +415,7 @@ variable {𝕜 G : Type*} [NontriviallyNormedField 𝕜] [IsRCLikeNormedField {f g : E → G} {C : ℝ} {s : Set E} {x y : E} {f' g' : E → E →L[𝕜] G} {φ : E →L[𝕜] G} instance (priority := 100) : PathConnectedSpace 𝕜 := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 infer_instance /-- The mean value theorem on a convex set: if the derivative of a function is bounded by `C`, then @@ -423,8 +423,8 @@ the function is `C`-Lipschitz. Version with `HasFDerivWithinAt`. -/ theorem norm_image_sub_le_of_norm_hasFDerivWithin_le (hf : ∀ x ∈ s, HasFDerivWithinAt f (f' x) s x) (bound : ∀ x ∈ s, ‖f' x‖ ≤ C) (hs : Convex ℝ s) (xs : x ∈ s) (ys : y ∈ s) : ‖f y - f x‖ ≤ C * ‖y - x‖ := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 - letI : NormedSpace ℝ G := .restrictScalars ℝ 𝕜 G + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : NormedSpace ℝ G := .restrictScalars ℝ 𝕜 G /- By composition with `AffineMap.lineMap x y`, we reduce to a statement for functions defined on `[0,1]`, for which it is proved in `norm_image_sub_le_of_norm_deriv_le_segment`. We just have to check the differentiability of the composition and bounds on its derivative, @@ -516,7 +516,7 @@ theorem _root_.lipschitzWith_of_nnnorm_fderiv_le {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {f : E → G} {C : ℝ≥0} (hf : Differentiable 𝕜 f) (bound : ∀ x, ‖fderiv 𝕜 f x‖₊ ≤ C) : LipschitzWith C f := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 let A : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E rw [← lipschitzOnWith_univ] exact lipschitzOnWith_of_nnnorm_fderiv_le (fun x _ ↦ hf x) (fun x _ ↦ bound x) convex_univ @@ -566,7 +566,7 @@ theorem _root_.is_const_of_fderiv_eq_zero {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {f : E → G} (hf : Differentiable 𝕜 f) (hf' : ∀ x, fderiv 𝕜 f x = 0) (x y : E) : f x = f y := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 let A : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E exact convex_univ.is_const_of_fderivWithin_eq_zero hf.differentiableOn (fun x _ => by rw [fderivWithin_univ]; exact hf' x) trivial trivial @@ -643,7 +643,7 @@ theorem _root_.eq_of_fderiv_eq {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {f g : E → G} (hf : Differentiable 𝕜 f) (hg : Differentiable 𝕜 g) (hf' : ∀ x, fderiv 𝕜 f x = fderiv 𝕜 g x) (x : E) (hfgx : f x = g x) : f = g := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 let A : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E suffices Set.univ.EqOn f g from funext fun x => this <| mem_univ x exact convex_univ.eqOn_of_fderivWithin_eq hf.differentiableOn hg.differentiableOn @@ -820,7 +820,7 @@ theorem hasStrictFDerivAt_of_hasFDerivAt_of_continuousAt rw [← dist_eq_norm] exact le_of_lt (hε H').2 -- apply mean value theorem - letI : NormedSpace ℝ G := .restrictScalars ℝ 𝕜 G + let : NormedSpace ℝ G := .restrictScalars ℝ 𝕜 G refine (convex_ball _ _).norm_image_sub_le_of_norm_hasFDerivWithin_le' ?_ hf' h.2 h.1 exact fun y hy => (hε hy).1.hasFDerivWithinAt diff --git a/Mathlib/Analysis/Calculus/ParametricIntegral.lean b/Mathlib/Analysis/Calculus/ParametricIntegral.lean index a6a6365b699152..451dcdc1010172 100644 --- a/Mathlib/Analysis/Calculus/ParametricIntegral.lean +++ b/Mathlib/Analysis/Calculus/ParametricIntegral.lean @@ -214,7 +214,7 @@ theorem hasFDerivAt_integral_of_dominated_of_fderiv_le {F' : H → α → H →L (bound_integrable : Integrable (bound : α → ℝ) μ) (h_diff : ∀ᵐ a ∂μ, ∀ x ∈ s, HasFDerivAt (F · a) (F' x a) x) : HasFDerivAt (fun x ↦ ∫ a, F x a ∂μ) (∫ a, F' x₀ a ∂μ) x₀ := by - letI : NormedSpace ℝ H := NormedSpace.restrictScalars ℝ 𝕜 H + let : NormedSpace ℝ H := NormedSpace.restrictScalars ℝ 𝕜 H rcases Metric.mem_nhds_iff.1 hs with ⟨ε, ε_pos, hε⟩ have x₀_in : x₀ ∈ ball x₀ ε := mem_ball_self ε_pos have diff_x₀ : ∀ᵐ a ∂μ, HasFDerivAt (F · a) (F' x₀ a) x₀ := diff --git a/Mathlib/Analysis/Calculus/SmoothSeries.lean b/Mathlib/Analysis/Calculus/SmoothSeries.lean index a4e9ff00e3668c..fa903770b9abc9 100644 --- a/Mathlib/Analysis/Calculus/SmoothSeries.lean +++ b/Mathlib/Analysis/Calculus/SmoothSeries.lean @@ -46,7 +46,7 @@ theorem summable_of_summable_hasFDerivAt_of_isPreconnected (hu : Summable u) (hs (h's : IsPreconnected s) (hf : ∀ n x, x ∈ s → HasFDerivAt (f n) (f' n x) x) (hf' : ∀ n x, x ∈ s → ‖f' n x‖ ≤ u n) (hx₀ : x₀ ∈ s) (hf0 : Summable (f · x₀)) (hx : x ∈ s) : Summable fun n => f n x := by - haveI := Classical.decEq α + have := Classical.decEq α rw [summable_iff_cauchySeq_finset] at hf0 ⊢ have A : UniformCauchySeqOn (fun t : Finset α => fun x => ∑ i ∈ t, f' i x) atTop s := (tendstoUniformlyOn_tsum hu hf').uniformCauchySeqOn @@ -103,7 +103,7 @@ then the series converges everywhere. -/ theorem summable_of_summable_hasFDerivAt (hu : Summable u) (hf : ∀ n x, HasFDerivAt (f n) (f' n x) x) (hf' : ∀ n x, ‖f' n x‖ ≤ u n) (hf0 : Summable fun n => f n x₀) (x : E) : Summable fun n => f n x := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 let _ : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 _ exact summable_of_summable_hasFDerivAt_of_isPreconnected hu isOpen_univ isPreconnected_univ (fun n x _ => hf n x) (fun n x _ => hf' n x) (mem_univ _) hf0 (mem_univ _) @@ -123,7 +123,7 @@ then the series is differentiable and its derivative is the sum of the derivativ theorem hasFDerivAt_tsum (hu : Summable u) (hf : ∀ n x, HasFDerivAt (f n) (f' n x) x) (hf' : ∀ n x, ‖f' n x‖ ≤ u n) (hf0 : Summable fun n => f n x₀) (x : E) : HasFDerivAt (fun y => ∑' n, f n y) (∑' n, f' n x) x := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 let A : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 _ exact hasFDerivAt_tsum_of_isPreconnected hu isOpen_univ isPreconnected_univ (fun n x _ => hf n x) (fun n x _ => hf' n x) (mem_univ _) hf0 (mem_univ _) diff --git a/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean b/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean index 894bf7351a290e..56d6e1172fca6e 100644 --- a/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean +++ b/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean @@ -115,8 +115,8 @@ sequence in a neighborhood of `x`. -/ theorem uniformCauchySeqOnFilter_of_fderiv (hf' : UniformCauchySeqOnFilter f' l (𝓝 x)) (hf : ∀ᶠ n : ι × E in l ×ˢ 𝓝 x, HasFDerivAt (f n.1) (f' n.1 n.2) n.2) (hfg : Cauchy (map (fun n => f n x) l)) : UniformCauchySeqOnFilter f l (𝓝 x) := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 - letI : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 _ + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 _ rw [SeminormedAddGroup.uniformCauchySeqOnFilter_iff_tendstoUniformlyOnFilter_zero] at hf' ⊢ suffices TendstoUniformlyOnFilter (fun (n : ι × ι) (z : E) => f n.1 z - f n.2 z - (f n.1 x - f n.2 x)) 0 @@ -179,8 +179,8 @@ convergence. See `cauchy_map_of_uniformCauchySeqOn_fderiv`. theorem uniformCauchySeqOn_ball_of_fderiv {r : ℝ} (hf' : UniformCauchySeqOn f' l (Metric.ball x r)) (hf : ∀ n : ι, ∀ y : E, y ∈ Metric.ball x r → HasFDerivAt (f n) (f' n y) y) (hfg : Cauchy (map (fun n => f n x) l)) : UniformCauchySeqOn f l (Metric.ball x r) := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 - letI : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 _ + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 _ have : NeBot l := (cauchy_map_iff.1 hfg).1 rcases le_or_gt r 0 with (hr | hr) · simp only [Metric.ball_eq_empty.2 hr, UniformCauchySeqOn, Set.mem_empty_iff_false, @@ -310,7 +310,7 @@ theorem hasFDerivAt_of_tendstoUniformlyOnFilter [NeBot l] (hf' : TendstoUniformlyOnFilter f' g' l (𝓝 x)) (hf : ∀ᶠ n : ι × E in l ×ˢ 𝓝 x, HasFDerivAt (f n.1) (f' n.1 n.2) n.2) (hfg : ∀ᶠ y in 𝓝 x, Tendsto (fun n => f n y) l (𝓝 (g y))) : HasFDerivAt g (g' x) x := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 -- The proof strategy follows several steps: -- 1. The quantifiers in the definition of the derivative are -- `∀ ε > 0, ∃ δ > 0, ∀ y ∈ B_δ(x)`. We will introduce a quantifier in the middle: diff --git a/Mathlib/Analysis/Complex/Polynomial/Basic.lean b/Mathlib/Analysis/Complex/Polynomial/Basic.lean index 33f5a14955277e..7706f87cd22de0 100644 --- a/Mathlib/Analysis/Complex/Polynomial/Basic.lean +++ b/Mathlib/Analysis/Complex/Polynomial/Basic.lean @@ -77,7 +77,7 @@ theorem card_complex_roots_eq_card_real_add_card_not_gal_inv (p : ℚ[X]) : (galActionHom p ℂ (restrict p ℂ (AlgEquiv.restrictScalars ℚ Complex.conjAe))).support.card := by by_cases hp : p = 0 - · haveI : IsEmpty (p.rootSet ℂ) := by rw [hp, rootSet_zero]; infer_instance + · have : IsEmpty (p.rootSet ℂ) := by rw [hp, rootSet_zero]; infer_instance simp_rw [(galActionHom p ℂ _).support.eq_empty_of_isEmpty, hp, rootSet_zero, Set.toFinset_empty, Finset.card_empty] have inj : Function.Injective (IsScalarTower.toAlgHom ℚ ℝ ℂ) := (algebraMap ℝ ℂ).injective diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean index 1d0e7e65be6fbf..aaa307340c876b 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean @@ -155,7 +155,7 @@ theorem dist_coe_center (z w : ℍ) (r : ℝ) : dist (z : ℂ) (w.center r) = theorem cmp_dist_eq_cmp_dist_coe_center (z w : ℍ) (r : ℝ) : cmp (dist z w) r = cmp (dist (z : ℂ) (w.center r)) (w.im * Real.sinh r) := by - letI := metricSpaceAux + let := metricSpaceAux rcases lt_or_ge r 0 with hr₀ | hr₀ · trans Ordering.gt exacts [(hr₀.trans_le dist_nonneg).cmp_eq_gt, @@ -258,7 +258,7 @@ instance : MetricSpace ℍ := apply_rules [Continuous.div, Continuous.mul, continuous_const, Continuous.arsinh, Continuous.dist, continuous_coe.comp, continuous_fst, continuous_snd, Real.continuous_sqrt.comp, continuous_im.comp] - · letI : MetricSpace ℍ := metricSpaceAux + · let : MetricSpace ℍ := metricSpaceAux refine le_of_nhds_le_nhds fun z => ?_ rw [nhds_induced] refine (nhds_basis_ball.le_basis_iff (nhds_basis_ball.comap _)).2 fun R hR => ?_ diff --git a/Mathlib/Analysis/ConstantSpeed.lean b/Mathlib/Analysis/ConstantSpeed.lean index 7eef2a7b6988ce..4f9bcae76ac79d 100644 --- a/Mathlib/Analysis/ConstantSpeed.lean +++ b/Mathlib/Analysis/ConstantSpeed.lean @@ -233,7 +233,7 @@ theorem edist_naturalParameterization_eq_zero {f : α → E} {s : Set α} (hf : LocallyBoundedVariationOn f s) {a : α} (as : a ∈ s) {b : α} (bs : b ∈ s) : edist (naturalParameterization f s a (variationOnFromTo f s a b)) (f b) = 0 := by dsimp only [naturalParameterization] - haveI : Nonempty α := ⟨a⟩ + have : Nonempty α := ⟨a⟩ obtain ⟨cs, hc⟩ := Function.invFunOn_pos (b := variationOnFromTo f s a b) ⟨b, bs, rfl⟩ rw [variationOnFromTo.eq_left_iff hf as cs bs] at hc apply variationOnFromTo.edist_zero_of_eq_zero hf cs bs hc diff --git a/Mathlib/Analysis/Convex/Cone/TensorProduct.lean b/Mathlib/Analysis/Convex/Cone/TensorProduct.lean index 635db471ec4b07..b3b1cc6bb9d9c6 100644 --- a/Mathlib/Analysis/Convex/Cone/TensorProduct.lean +++ b/Mathlib/Analysis/Convex/Cone/TensorProduct.lean @@ -88,7 +88,7 @@ theorem minTensorProduct_eq_max_of_simplicial_generating_left (C₁ : PointedCon minTensorProduct C₁ C₂.toPointedCone = maxTensorProduct C₁ C₂.toPointedCone := by classical obtain ⟨s, hs_fin, hs_lin, hs_span⟩ := h₁_simp - haveI : Fintype s := hs_fin.fintype + have : Fintype s := hs_fin.fintype -- The conic hull (R≥0-span) is contained in the linear span (ℝ-span) have hull_sub_span : (hull ℝ s : Set E) ⊆ Submodule.span ℝ s := by intro x hx diff --git a/Mathlib/Analysis/Convex/EGauge.lean b/Mathlib/Analysis/Convex/EGauge.lean index 51780123318d2d..92f81aab4b4549 100644 --- a/Mathlib/Analysis/Convex/EGauge.lean +++ b/Mathlib/Analysis/Convex/EGauge.lean @@ -335,7 +335,7 @@ variable {c : 𝕜} {x : E} {r : ℝ≥0} lemma egauge_ball_le_of_one_lt_norm (hc : 1 < ‖c‖) (h₀ : r ≠ 0 ∨ ‖x‖ ≠ 0) : egauge 𝕜 (ball 0 r) x ≤ ‖c‖ₑ * ‖x‖ₑ / r := by - letI : NontriviallyNormedField 𝕜 := ⟨c, hc⟩ + let : NontriviallyNormedField 𝕜 := ⟨c, hc⟩ rcases eq_zero_or_pos r with rfl | hr · rw [ENNReal.coe_zero, ENNReal.div_zero (mul_ne_zero _ _)] · apply le_top diff --git a/Mathlib/Analysis/Convex/Extreme.lean b/Mathlib/Analysis/Convex/Extreme.lean index 8f564a9b141487..a3daff0007e3da 100644 --- a/Mathlib/Analysis/Convex/Extreme.lean +++ b/Mathlib/Analysis/Convex/Extreme.lean @@ -117,7 +117,7 @@ theorem isExtreme_iInter {ι : Sort*} [Nonempty ι] {F : ι → Set E} theorem isExtreme_biInter {F : Set (Set E)} (hF : F.Nonempty) (hA : ∀ B ∈ F, IsExtreme 𝕜 A B) : IsExtreme 𝕜 A (⋂ B ∈ F, B) := by - haveI := hF.to_subtype + have := hF.to_subtype simpa only [iInter_subtype] using isExtreme_iInter fun i : F ↦ hA _ i.2 theorem isExtreme_sInter {F : Set (Set E)} (hF : F.Nonempty) (hAF : ∀ B ∈ F, IsExtreme 𝕜 A B) : diff --git a/Mathlib/Analysis/Convex/Integral.lean b/Mathlib/Analysis/Convex/Integral.lean index b3b35f2b7c8076..fbb93244a6bb2d 100644 --- a/Mathlib/Analysis/Convex/Integral.lean +++ b/Mathlib/Analysis/Convex/Integral.lean @@ -58,7 +58,7 @@ theorem Convex.integral_mem [IsProbabilityMeasure μ] (hs : Convex ℝ s) (hsc : (hf : ∀ᵐ x ∂μ, f x ∈ s) (hfi : Integrable f μ) : (∫ x, f x ∂μ) ∈ s := by borelize E rcases hfi.aestronglyMeasurable with ⟨g, hgm, hfg⟩ - haveI : SeparableSpace (range g ∩ s : Set E) := + have : SeparableSpace (range g ∩ s : Set E) := (hgm.isSeparable_range.mono inter_subset_left).separableSpace obtain ⟨y₀, h₀⟩ : (range g ∩ s).Nonempty := by rcases (hf.and hfg).exists with ⟨x₀, h₀⟩ @@ -314,7 +314,7 @@ theorem ae_eq_const_or_norm_average_lt_of_norm_le_const [StrictConvexSpace ℝ E · simp [average_eq, integral_undef hfi, hC0] rcases (le_top : μ univ ≤ ∞).eq_or_lt with hμt | hμt · simp [average_eq, measureReal_def, hμt, hC0] - haveI : IsFiniteMeasure μ := ⟨hμt⟩ + have : IsFiniteMeasure μ := ⟨hμt⟩ replace h_le : ∀ᵐ x ∂μ, f x ∈ closedBall (0 : E) C := by simpa only [mem_closedBall_zero_iff] simpa only [interior_closedBall _ hC0.ne', mem_ball_zero_iff] using (strictConvex_closedBall ℝ (0 : E) C).ae_eq_const_or_average_mem_interior isClosed_closedBall @@ -339,6 +339,6 @@ a.e. on a set `t` of finite measure, then either this function is a.e. equal to theorem ae_eq_const_or_norm_setIntegral_lt_of_norm_le_const [StrictConvexSpace ℝ E] (ht : μ t ≠ ∞) (h_le : ∀ᵐ x ∂μ.restrict t, ‖f x‖ ≤ C) : f =ᵐ[μ.restrict t] const α (⨍ x in t, f x ∂μ) ∨ ‖∫ x in t, f x ∂μ‖ < μ.real t * C := by - haveI := Fact.mk ht.lt_top + have := Fact.mk ht.lt_top rw [← measureReal_restrict_apply_univ] exact ae_eq_const_or_norm_integral_lt_of_norm_le_const h_le diff --git a/Mathlib/Analysis/Convex/Intrinsic.lean b/Mathlib/Analysis/Convex/Intrinsic.lean index 6c1f2aabafd068..d57a8c3d9b594a 100644 --- a/Mathlib/Analysis/Convex/Intrinsic.lean +++ b/Mathlib/Analysis/Convex/Intrinsic.lean @@ -256,7 +256,7 @@ private theorem intrinsicInterior_image_of_homeomorph_affineSpan : intrinsicInterior 𝕜 (f '' s) = f '' intrinsicInterior 𝕜 s := by rcases s.eq_empty_or_nonempty with rfl | hs · simp - · haveI : Nonempty s := hs.to_subtype + · have : Nonempty s := hs.to_subtype rw [intrinsicInterior, ← image_interior_preimage_comp e he_homeo, (funext he : (↑) ∘ e = f ∘ (↑)), preimage_image_eq_of_homeomorph_affineSpan e he_homeo he, image_comp]; rfl @@ -268,7 +268,7 @@ private theorem intrinsicFrontier_image_of_homeomorph_affineSpan : intrinsicFrontier 𝕜 (f '' s) = f '' intrinsicFrontier 𝕜 s := by rcases s.eq_empty_or_nonempty with rfl | hs · simp - · haveI : Nonempty s := hs.to_subtype + · have : Nonempty s := hs.to_subtype rw [intrinsicFrontier, ← image_frontier_preimage_comp e he_homeo, (funext he : (↑) ∘ e = f ∘ (↑)), preimage_image_eq_of_homeomorph_affineSpan e he_homeo he, image_comp]; rfl @@ -280,7 +280,7 @@ private theorem intrinsicClosure_image_of_homeomorph_affineSpan : intrinsicClosure 𝕜 (f '' s) = f '' intrinsicClosure 𝕜 s := by rcases s.eq_empty_or_nonempty with rfl | hs · simp - · haveI : Nonempty s := hs.to_subtype + · have : Nonempty s := hs.to_subtype rw [intrinsicClosure, ← image_closure_preimage_comp e he_homeo, (funext he : (↑) ∘ e = f ∘ (↑)), preimage_image_eq_of_homeomorph_affineSpan e he_homeo he, image_comp]; rfl @@ -449,7 +449,7 @@ variable [NormedAddCommGroup V] [NormedSpace ℝ V] [FiniteDimensional ℝ V] {s /-- The intrinsic interior of a nonempty convex set is nonempty. -/ protected theorem Set.Nonempty.intrinsicInterior (hscv : Convex ℝ s) (hsne : s.Nonempty) : (intrinsicInterior ℝ s).Nonempty := by - haveI := hsne.coe_sort + have := hsne.coe_sort obtain ⟨p, hp⟩ := hsne let p' : _root_.affineSpan ℝ s := ⟨p, subset_affineSpan _ _ hp⟩ rw [intrinsicInterior, image_nonempty, diff --git a/Mathlib/Analysis/Convex/KreinMilman.lean b/Mathlib/Analysis/Convex/KreinMilman.lean index 6661d3ac8102d4..e75e1d19d09e82 100644 --- a/Mathlib/Analysis/Convex/KreinMilman.lean +++ b/Mathlib/Analysis/Convex/KreinMilman.lean @@ -82,7 +82,7 @@ theorem IsCompact.extremePoints_nonempty (hscomp : IsCompact s) (hsnemp : s.None · exact ⟨s, ⟨hsnemp, hscomp.isClosed, IsExtreme.rfl⟩, fun _ => False.elim⟩ refine ⟨⋂₀ F, ⟨?_, isClosed_sInter fun t ht => (hFS ht).2.1, isExtreme_sInter hFnemp fun t ht => (hFS ht).2.2⟩, fun t ht => sInter_subset_of_mem ht⟩ - haveI : Nonempty (↥F) := hFnemp.to_subtype + have : Nonempty (↥F) := hFnemp.to_subtype rw [sInter_eq_iInter] refine IsCompact.nonempty_iInter_of_directed_nonempty_isCompact_isClosed _ (fun t u => ?_) (fun t => (hFS t.mem).1) diff --git a/Mathlib/Analysis/Convex/MetricSpace.lean b/Mathlib/Analysis/Convex/MetricSpace.lean index 848ed2f4e6d82d..32c1b7127a55bc 100644 --- a/Mathlib/Analysis/Convex/MetricSpace.lean +++ b/Mathlib/Analysis/Convex/MetricSpace.lean @@ -276,7 +276,7 @@ instance (priority := low) {V P : Type*} instance IsConvexDist.subtype (s : Set X) (hs : IsConvexSet ℝ s) : letI : ConvexSpace ℝ s := .subtype s hs IsConvexDist s := by - letI : ConvexSpace ℝ s := .subtype s hs + let : ConvexSpace ℝ s := .subtype s hs refine ⟨fun f ↦ ?_⟩ convert dist_iConvexComb_fst_snd_le (X := X) (f.map fun x ↦ (x.1, x.2)) <;> simp [Subtype.dist_eq, Finsupp.sum_mapDomain_index, add_mul] diff --git a/Mathlib/Analysis/Convex/Side.lean b/Mathlib/Analysis/Convex/Side.lean index 6cf3ee3d020915..3a8f2fc1e56e81 100644 --- a/Mathlib/Analysis/Convex/Side.lean +++ b/Mathlib/Analysis/Convex/Side.lean @@ -780,7 +780,7 @@ variable [NormedAddTorsor V P] theorem isConnected_setOf_wSameSide {s : AffineSubspace ℝ P} (x : P) (h : (s : Set P).Nonempty) : IsConnected { y | s.WSameSide x y } := by obtain ⟨p, hp⟩ := h - haveI : Nonempty s := ⟨⟨p, hp⟩⟩ + have : Nonempty s := ⟨⟨p, hp⟩⟩ by_cases hx : x ∈ s · simp only [wSameSide_of_left_mem, hx] have := AddTorsor.connectedSpace V P @@ -801,7 +801,7 @@ theorem isPreconnected_setOf_wSameSide (s : AffineSubspace ℝ P) (x : P) : theorem isConnected_setOf_sSameSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) (h : (s : Set P).Nonempty) : IsConnected { y | s.SSameSide x y } := by obtain ⟨p, hp⟩ := h - haveI : Nonempty s := ⟨⟨p, hp⟩⟩ + have : Nonempty s := ⟨⟨p, hp⟩⟩ rw [setOf_sSameSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Ioi.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn @@ -821,7 +821,7 @@ theorem isPreconnected_setOf_sSameSide (s : AffineSubspace ℝ P) (x : P) : theorem isConnected_setOf_wOppSide {s : AffineSubspace ℝ P} (x : P) (h : (s : Set P).Nonempty) : IsConnected { y | s.WOppSide x y } := by obtain ⟨p, hp⟩ := h - haveI : Nonempty s := ⟨⟨p, hp⟩⟩ + have : Nonempty s := ⟨⟨p, hp⟩⟩ by_cases hx : x ∈ s · simp only [wOppSide_of_left_mem, hx] have := AddTorsor.connectedSpace V P @@ -842,7 +842,7 @@ theorem isPreconnected_setOf_wOppSide (s : AffineSubspace ℝ P) (x : P) : theorem isConnected_setOf_sOppSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) (h : (s : Set P).Nonempty) : IsConnected { y | s.SOppSide x y } := by obtain ⟨p, hp⟩ := h - haveI : Nonempty s := ⟨⟨p, hp⟩⟩ + have : Nonempty s := ⟨⟨p, hp⟩⟩ rw [setOf_sOppSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Iio.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn diff --git a/Mathlib/Analysis/Convex/StdSimplex.lean b/Mathlib/Analysis/Convex/StdSimplex.lean index 46b59101d93b89..89f918927fa058 100644 --- a/Mathlib/Analysis/Convex/StdSimplex.lean +++ b/Mathlib/Analysis/Convex/StdSimplex.lean @@ -162,7 +162,7 @@ theorem Set.Finite.convexHull_eq_image {E : Type*} [AddCommGroup E] [Module R E] haveI := hs.fintype (⇑(∑ x : s, (LinearMap.proj (R := R) x).smulRight x.1)) '' stdSimplex R s := by classical - letI := hs.fintype + let := hs.fintype rw [← convexHull_basis_eq_stdSimplex, LinearMap.image_convexHull, ← Set.range_comp] apply congr_arg aesop diff --git a/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean b/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean index 5f229581b1a28e..08ff71a07bec34 100644 --- a/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean +++ b/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean @@ -132,7 +132,7 @@ theorem IsOpen.ae_eq_zero_of_integral_contMDiff_smul_eq_zero' {U : Set M} (hU : rw [← ae_restrict_iff' meas_U, ae_restrict_iff_subtype meas_U] let U : Opens M := ⟨U, hU⟩ change ∀ᵐ (x : U) ∂_, _ - haveI : SigmaCompactSpace U := isSigmaCompact_iff_sigmaCompactSpace.mp hSig + have : SigmaCompactSpace U := isSigmaCompact_iff_sigmaCompactSpace.mp hSig refine ae_eq_zero_of_integral_contMDiff_smul_eq_zero I ?_ fun g g_smth g_supp ↦ ?_ · exact (locallyIntegrable_comap meas_U).mpr hf specialize h (Subtype.val.extend g 0) (g_smth.extend_zero g_supp) diff --git a/Mathlib/Analysis/Distribution/TemperedDistribution.lean b/Mathlib/Analysis/Distribution/TemperedDistribution.lean index 871955ee5ae633..713e7dd5da0358 100644 --- a/Mathlib/Analysis/Distribution/TemperedDistribution.lean +++ b/Mathlib/Analysis/Distribution/TemperedDistribution.lean @@ -201,7 +201,7 @@ def toTemperedDistributionCLM (μ : Measure E := by volume_tac) [μ.HasTemperate cont := by apply PointwiseConvergenceCLM.continuous_of_continuous_eval intro g - haveI : Fact (1 ≤ (1 - p⁻¹)⁻¹) := by simp [fact_iff] + have : Fact (1 ≤ (1 - p⁻¹)⁻¹) := by simp [fact_iff] have hpq : ENNReal.HolderConjugate p (1 - p⁻¹)⁻¹ := ENNReal.HolderConjugate.inv_one_sub_inv' hp.out exact (((lsmul ℂ ℂ (E := F)).flip.lpPairing μ p (1 - p⁻¹)⁻¹).flip (g.toLp (1 - p⁻¹)⁻¹ μ)).cont diff --git a/Mathlib/Analysis/Fourier/AddCircle.lean b/Mathlib/Analysis/Fourier/AddCircle.lean index 36d822059852c1..7a045982cec4ca 100644 --- a/Mathlib/Analysis/Fourier/AddCircle.lean +++ b/Mathlib/Analysis/Fourier/AddCircle.lean @@ -356,7 +356,7 @@ def fourierCoeffOn {a b : ℝ} (hab : a < b) (f : ℝ → E) (n : ℤ) : E := theorem fourierCoeffOn_eq_integral {a b : ℝ} (f : ℝ → E) (n : ℤ) (hab : a < b) : fourierCoeffOn hab f n = (1 / (b - a)) • ∫ x in a..b, fourier (-n) (x : AddCircle (b - a)) • f x := by - haveI := Fact.mk (by linarith : 0 < b - a) + have := Fact.mk (by linarith : 0 < b - a) rw [fourierCoeffOn, fourierCoeff_eq_intervalIntegral _ _ a, add_sub, add_sub_cancel_left] congr 1 simp_rw [intervalIntegral.integral_of_le hab.le] @@ -366,7 +366,7 @@ theorem fourierCoeffOn_eq_integral {a b : ℝ} (f : ℝ → E) (n : ℤ) (hab : theorem fourierCoeffOn.const_smul {a b : ℝ} (f : ℝ → E) (c : ℂ) (n : ℤ) (hab : a < b) : fourierCoeffOn hab (c • f) n = c • fourierCoeffOn hab f n := by - haveI := Fact.mk (by linarith : 0 < b - a) + have := Fact.mk (by linarith : 0 < b - a) apply fourierCoeff.const_smul theorem fourierCoeffOn.const_mul {a b : ℝ} (f : ℝ → ℂ) (c : ℂ) (n : ℤ) (hab : a < b) : @@ -458,7 +458,7 @@ the sum of the squared norms of the Fourier coefficients equals the `L²` norm o theorem hasSum_sq_fourierCoeffOn {a b : ℝ} {f : ℝ → ℂ} (hab : a < b) (hL2 : MemLp f 2 (volume.restrict (Ioc a b))) : HasSum (fun i => ‖fourierCoeffOn hab f i‖ ^ 2) ((b - a)⁻¹ • ∫ x in a..b, ‖f x‖ ^ 2) := by - haveI := Fact.mk (by linarith : 0 < b - a) + have := Fact.mk (by linarith : 0 < b - a) rw [← add_sub_cancel a b] at hL2 have h := hL2.memLp_liftIoc.haarAddCircle convert hasSum_sq_fourierCoeff h.toLp diff --git a/Mathlib/Analysis/Hofer.lean b/Mathlib/Analysis/Hofer.lean index 0b7bb7279de384..198fc7866ba3e2 100644 --- a/Mathlib/Analysis/Hofer.lean +++ b/Mathlib/Analysis/Hofer.lean @@ -40,7 +40,7 @@ theorem hofer {X : Type*} [MetricSpace X] [CompleteSpace X] (x : X) (ε : ℝ) ( intro k x' have := H (ε / 2 ^ k) (by positivity) x' (div_le_self ε_pos.le <| one_le_pow₀ one_le_two) simpa [reformulation] using! this - haveI : Nonempty X := ⟨x⟩ + have : Nonempty X := ⟨x⟩ choose! F hF using H -- Use the axiom of choice -- Now define u by induction starting at x, with u_{n+1} = F(n, u_n) diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index 61d64cedb022f6..58848c1045874c 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -605,21 +605,21 @@ lemma adjoint_one : (1 : E →ₗ[𝕜] E).adjoint = 1 := by simp /-- 7.6(b) from [axler2024]. See `ContinuousLinearMap.orthogonal_ker` for the infinite-dimensional version. -/ lemma orthogonal_ker (A : E →ₗ[𝕜] F) : A.kerᗮ = A.adjoint.range := by - haveI := FiniteDimensional.complete 𝕜 E - haveI := FiniteDimensional.complete 𝕜 F + have := FiniteDimensional.complete 𝕜 E + have := FiniteDimensional.complete 𝕜 F simpa using! A.toContinuousLinearMap.orthogonal_ker /-- 7.6(a) from [axler2024]. See `ContinuousLinearMap.orthogonal_range` for the infinite-dimensional version. -/ lemma orthogonal_range (A : E →ₗ[𝕜] F) : A.rangeᗮ = A.adjoint.ker := by - haveI := FiniteDimensional.complete 𝕜 E - haveI := FiniteDimensional.complete 𝕜 F + have := FiniteDimensional.complete 𝕜 E + have := FiniteDimensional.complete 𝕜 F simpa using! A.toContinuousLinearMap.orthogonal_range /-- 7.64(b) in [axler2024] -/ lemma ker_adjoint_comp_self (A : E →ₗ[𝕜] F) : (A.adjoint ∘ₗ A).ker = A.ker := by - haveI := FiniteDimensional.complete 𝕜 E - haveI := FiniteDimensional.complete 𝕜 F + have := FiniteDimensional.complete 𝕜 E + have := FiniteDimensional.complete 𝕜 F simpa using! A.toContinuousLinearMap.ker_adjoint_comp_self lemma ker_self_comp_adjoint (A : E →ₗ[𝕜] F) : (A ∘ₗ A.adjoint).ker = A.adjoint.ker := by @@ -1055,7 +1055,7 @@ theorem LinearIsometry.adjoint_comp_self' {E E' : Type*} [NormedAddCommGroup E] [InnerProductSpace 𝕜 E] [FiniteDimensional 𝕜 E] [NormedAddCommGroup E'] [InnerProductSpace 𝕜 E'] [FiniteDimensional 𝕜 E'] (f : E →ₗᵢ[𝕜] E') : f.adjoint ∘ₗ f.toLinearMap = LinearMap.id := by - haveI := FiniteDimensional.complete 𝕜 E - haveI := FiniteDimensional.complete 𝕜 E' + have := FiniteDimensional.complete 𝕜 E + have := FiniteDimensional.complete 𝕜 E' ext x exact congr($(f.adjoint_comp_self) x) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index 6171f8318e2fb8..f4c81e88568377 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -455,7 +455,7 @@ theorem norm_sub_mul_self_real (x y : F) : /-- Cauchy–Schwarz inequality with norm -/ theorem norm_inner_le_norm (x y : E) : ‖⟪x, y⟫‖ ≤ ‖x‖ * ‖y‖ := by rw [norm_eq_sqrt_re_inner (𝕜 := 𝕜) x, norm_eq_sqrt_re_inner (𝕜 := 𝕜) y] - letI : PreInnerProductSpace.Core 𝕜 E := PreInnerProductSpace.toCore + let : PreInnerProductSpace.Core 𝕜 E := PreInnerProductSpace.toCore exact InnerProductSpace.Core.norm_inner_le_norm x y theorem nnnorm_inner_le_nnnorm (x y : E) : ‖⟪x, y⟫‖₊ ≤ ‖x‖₊ * ‖y‖₊ := @@ -712,7 +712,7 @@ theorem norm_inner_eq_norm_tfae (x y : E) : rw [← sq_eq_sq₀, mul_pow, ← mul_right_inj' this, eq_comm, ← sub_eq_zero, ← mul_sub] at h <;> try positivity simp only [@norm_sq_eq_re_inner 𝕜] at h - letI : InnerProductSpace.Core 𝕜 E := InnerProductSpace.toCore + let : InnerProductSpace.Core 𝕜 E := InnerProductSpace.toCore erw [← InnerProductSpace.Core.cauchy_schwarz_aux (𝕜 := 𝕜) (F := E)] at h rw [InnerProductSpace.Core.normSq_eq_zero, sub_eq_zero] at h rw [div_eq_inv_mul, mul_smul, h, inv_smul_smul₀] @@ -952,7 +952,7 @@ abbrev InnerProductSpace.rclikeToReal : InnerProductSpace ℝ E := add_left := fun x y z => by simp +instances only [Inner.rclikeToReal, inner_add_left, map_add] smul_left := fun x y r => by - letI := NormedSpace.restrictScalars ℝ 𝕜 E + let := NormedSpace.restrictScalars ℝ 𝕜 E have : r • x = (r : 𝕜) • x := rfl simp +instances only [Inner.rclikeToReal, this, conj_trivial, inner_smul_left, conj_ofReal, re_ofReal_mul] } diff --git a/Mathlib/Analysis/InnerProductSpace/Defs.lean b/Mathlib/Analysis/InnerProductSpace/Defs.lean index 2bc916e9ff9f00..7c03c08f0564e5 100644 --- a/Mathlib/Analysis/InnerProductSpace/Defs.lean +++ b/Mathlib/Analysis/InnerProductSpace/Defs.lean @@ -427,7 +427,7 @@ omit c in lemma toSeminormedSpaceCore (c : PreInnerProductSpace.Core 𝕜 F) : SeminormedSpace.Core 𝕜 F where norm_nonneg x := norm_nonneg x norm_smul c x := by - letI : NormedSpace 𝕜 F := toNormedSpace + let : NormedSpace 𝕜 F := toNormedSpace exact _root_.norm_smul c x norm_triangle x y := norm_add_le x y @@ -494,7 +494,7 @@ lemma toNormedSpaceCore (cd : InnerProductSpace.Core 𝕜 F) : NormedSpace.Core norm_nonneg x := norm_nonneg x norm_eq_zero_iff x := norm_eq_zero norm_smul c x := by - letI : NormedSpace 𝕜 F := toNormedSpace + let : NormedSpace 𝕜 F := toNormedSpace exact _root_.norm_smul c x norm_triangle x y := norm_add_le x y diff --git a/Mathlib/Analysis/InnerProductSpace/LaxMilgram.lean b/Mathlib/Analysis/InnerProductSpace/LaxMilgram.lean index 3acc990035f6e7..c789ad39fcb3e0 100644 --- a/Mathlib/Analysis/InnerProductSpace/LaxMilgram.lean +++ b/Mathlib/Analysis/InnerProductSpace/LaxMilgram.lean @@ -81,7 +81,7 @@ theorem isClosed_range (coercive : IsCoercive B) : IsClosed (B♯.range : Set V) exact antilipschitz.isClosed_range B♯.uniformContinuous theorem range_eq_top (coercive : IsCoercive B) : B♯.range = ⊤ := by - haveI := coercive.isClosed_range.completeSpace_coe + have := coercive.isClosed_range.completeSpace_coe rw [← B♯.range.orthogonal_orthogonal] rw [Submodule.eq_top_iff'] intro v w mem_w_orthogonal diff --git a/Mathlib/Analysis/InnerProductSpace/Orientation.lean b/Mathlib/Analysis/InnerProductSpace/Orientation.lean index 7ff0181b423f2e..8dcdff2be957b9 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orientation.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orientation.lean @@ -155,8 +155,8 @@ protected def finOrthonormalBasis (hn : 0 < n) (h : finrank ℝ E = n) (x : Orie @[simp] theorem finOrthonormalBasis_orientation (hn : 0 < n) (h : finrank ℝ E = n) (x : Orientation ℝ E (Fin n)) : (x.finOrthonormalBasis hn h).toBasis.orientation = x := by - haveI := Fin.pos_iff_nonempty.1 hn - haveI : FiniteDimensional ℝ E := .of_finrank_pos <| h.symm ▸ hn + have := Fin.pos_iff_nonempty.1 hn + have : FiniteDimensional ℝ E := .of_finrank_pos <| h.symm ▸ hn exact ((@stdOrthonormalBasis _ _ _ _ _ this).reindex <| finCongr h).orientation_adjustToOrientation x @@ -244,7 +244,7 @@ value by the product of the norms of the vectors `v i`. -/ theorem abs_volumeForm_apply_le (v : Fin n → E) : |o.volumeForm v| ≤ ∏ i : Fin n, ‖v i‖ := by rcases n with - | n · refine o.eq_or_eq_neg_of_isEmpty.elim ?_ ?_ <;> rintro rfl <;> simp - haveI : FiniteDimensional ℝ E := .of_fact_finrank_eq_succ n + have : FiniteDimensional ℝ E := .of_fact_finrank_eq_succ n have : finrank ℝ E = Fintype.card (Fin n.succ) := by simpa using _i.out let b : OrthonormalBasis (Fin n.succ) ℝ E := gramSchmidtOrthonormalBasis this v have hb : b.toBasis.det v = ∏ i, ⟪b i, v i⟫ := gramSchmidtOrthonormalBasis_det this v @@ -266,7 +266,7 @@ theorem abs_volumeForm_apply_of_pairwise_orthogonal {v : Fin n → E} (hv : Pairwise fun i j => ⟪v i, v j⟫ = 0) : |o.volumeForm v| = ∏ i : Fin n, ‖v i‖ := by rcases n with - | n · refine o.eq_or_eq_neg_of_isEmpty.elim ?_ ?_ <;> rintro rfl <;> simp - haveI : FiniteDimensional ℝ E := .of_fact_finrank_eq_succ n + have : FiniteDimensional ℝ E := .of_fact_finrank_eq_succ n have hdim : finrank ℝ E = Fintype.card (Fin n.succ) := by simpa using _i.out let b : OrthonormalBasis (Fin n.succ) ℝ E := gramSchmidtOrthonormalBasis hdim v have hb : b.toBasis.det v = ∏ i, ⟪b i, v i⟫ := gramSchmidtOrthonormalBasis_det hdim v diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 297d9435e95b06..2e113640ce7dfe 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -756,9 +756,9 @@ protected def mkOfOrthogonalEqBot (hon : Orthonormal 𝕜 v) (hsp : (span 𝕜 ( OrthonormalBasis.mk hon (by refine Eq.ge ?_ - haveI : FiniteDimensional 𝕜 (span 𝕜 (range v)) := + have : FiniteDimensional 𝕜 (span 𝕜 (range v)) := FiniteDimensional.span_of_finite 𝕜 (finite_range v) - haveI : CompleteSpace (span 𝕜 (range v)) := FiniteDimensional.complete 𝕜 _ + have : CompleteSpace (span 𝕜 (range v)) := FiniteDimensional.complete 𝕜 _ rwa [orthogonal_eq_bot_iff] at hsp) @[simp] diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean index fa9b6e01850880..8bf7fffdb1823f 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Basic.lean @@ -82,7 +82,7 @@ instance HasOrthogonalProjection.map_linearIsometryEquiv' [K.HasOrthogonalProjec instance : (⊤ : Submodule 𝕜 E).HasOrthogonalProjection := ⟨fun v ↦ ⟨v, trivial, by simp⟩⟩ instance (K : ClosedSubmodule 𝕜 E) [CompleteSpace E] : K.HasOrthogonalProjection := by - letI := K.isClosed' + let := K.isClosed' infer_instance /-- If `K` admits an orthogonal projection, `K` and `Kᗮ` are complements of each other. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean b/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean index f1542dd9fe6327..cfa7199aec6241 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean @@ -91,7 +91,7 @@ orthogonal subspace with `K₂` add to that of `K₂`. -/ theorem finrank_add_inf_finrank_orthogonal {K₁ K₂ : Submodule 𝕜 E} [FiniteDimensional 𝕜 K₂] (h : K₁ ≤ K₂) : finrank 𝕜 K₁ + finrank 𝕜 (K₁ᗮ ⊓ K₂ : Submodule 𝕜 E) = finrank 𝕜 K₂ := by - haveI : FiniteDimensional 𝕜 K₁ := Submodule.finiteDimensional_of_le h + have : FiniteDimensional 𝕜 K₁ := Submodule.finiteDimensional_of_le h have hd := Submodule.finrank_sup_add_finrank_inf_eq K₁ (K₁ᗮ ⊓ K₂) rw [← inf_assoc, (Submodule.orthogonal_disjoint K₁).eq_bot, bot_inf_eq, finrank_bot, Submodule.sup_orthogonal_inf_of_hasOrthogonalProjection h] at hd @@ -126,7 +126,7 @@ theorem finrank_add_finrank_orthogonal' [FiniteDimensional 𝕜 E] {K : Submodul span of a nonzero vector is one less than the dimension of the space. -/ theorem finrank_orthogonal_span_singleton {n : ℕ} [_i : Fact (finrank 𝕜 E = n + 1)] {v : E} (hv : v ≠ 0) : finrank 𝕜 (𝕜 ∙ v)ᗮ = n := by - haveI : FiniteDimensional 𝕜 E := .of_fact_finrank_eq_succ n + have : FiniteDimensional 𝕜 E := .of_fact_finrank_eq_succ n exact finrank_add_finrank_orthogonal' <| by simp [finrank_span_singleton hv, _i.elim, add_comm] @@ -136,7 +136,7 @@ theorem mem_span_singleton_of_inner_eq_zero_of_inner_eq_zero [Fact (finrank 𝕜 E = 2)] {u v w : E} (hv : v ≠ 0) (hw : w ≠ 0) (huv : ⟪v, u⟫_𝕜 = 0) (hwv : ⟪v, w⟫_𝕜 = 0) : u ∈ 𝕜 ∙ w := by - haveI : FiniteDimensional 𝕜 E := .of_fact_finrank_eq_succ 1 + have : FiniteDimensional 𝕜 E := .of_fact_finrank_eq_succ 1 suffices heq : (𝕜 ∙ v)ᗮ = 𝕜 ∙ w by rwa [← heq, mem_orthogonal_singleton_iff_inner_right] exact eq_span_singleton_of_mem_of_finrank_eq_one (finrank_orthogonal_span_singleton (n := 1) hv) @@ -173,7 +173,7 @@ theorem LinearIsometryEquiv.reflections_generate_dim_aux [FiniteDimensional ℝ · obtain ⟨V, hV₁, hV₂⟩ := IH φ hn' exact ⟨V, hV₁.trans n.le_succ, hV₂⟩ -- Take a nonzero element `v` of the orthogonal complement of `W`. - haveI : Nontrivial Wᗮ := nontrivial_of_finrank_pos (by lia : 0 < finrank ℝ Wᗮ) + have : Nontrivial Wᗮ := nontrivial_of_finrank_pos (by lia : 0 < finrank ℝ Wᗮ) obtain ⟨v, hv⟩ := exists_ne (0 : Wᗮ) have hφv : φ v ∈ Wᗮ := by intro w hw @@ -255,7 +255,7 @@ orthogonal complement. -/ theorem OrthogonalFamily.isInternal_iff_of_isComplete [DecidableEq ι] {V : ι → Submodule 𝕜 E} (hV : OrthogonalFamily 𝕜 (fun i => V i) fun i => (V i).subtypeₗᵢ) (hc : IsComplete (↑(iSup V) : Set E)) : DirectSum.IsInternal V ↔ (iSup V)ᗮ = ⊥ := by - haveI : CompleteSpace (↥(iSup V)) := hc.completeSpace_coe + have : CompleteSpace (↥(iSup V)) := hc.completeSpace_coe simp only [DirectSum.isInternal_submodule_iff_iSupIndep_and_iSup_eq_top, hV.independent, true_and, orthogonal_eq_bot_iff] @@ -321,7 +321,7 @@ noncomputable abbrev OrthogonalFamily.decomposition decompose' x := DFinsupp.equivFunOnFintype.symm fun i => (V i).orthogonalProjectionOnto x left_inv x := by dsimp only - letI := fun i => Classical.decEq (V i) + let := fun i => Classical.decEq (V i) rw [DirectSum.coeAddMonoidHom, DirectSum.toAddMonoid, DFinsupp.liftAddHom_apply] -- This used to be `rw`, but we need `erw` after https://github.com/leanprover/lean4/pull/2644 erw [DFinsupp.sumAddHom_apply]; rw [DFinsupp.sum_eq_sum_fintype] diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean index 6e1e5fbdfe7621..8310c62e48e4ce 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean @@ -34,7 +34,7 @@ Then there exists a (unique) `v` in `K` that minimizes the distance `‖u - v‖ theorem exists_norm_eq_iInf_of_complete_convex {K : Set F} (ne : K.Nonempty) (h₁ : IsComplete K) (h₂ : Convex ℝ K) : ∀ u : F, ∃ v ∈ K, ‖u - v‖ = ⨅ w : K, ‖u - w‖ := fun u => by let δ := ⨅ w : K, ‖u - w‖ - letI : Nonempty K := ne.to_subtype + let : Nonempty K := ne.to_subtype have zero_le_δ : 0 ≤ δ := le_ciInf fun _ => norm_nonneg _ have δ_le : ∀ w : K, δ ≤ ‖u - w‖ := ciInf_le ⟨0, Set.forall_mem_range.2 fun _ => norm_nonneg _⟩ have δ_le' : ∀ w ∈ K, δ ≤ ‖u - w‖ := fun w hw => δ_le ⟨w, hw⟩ @@ -137,7 +137,7 @@ theorem exists_norm_eq_iInf_of_complete_convex {K : Set F} (ne : K.Nonempty) (h space. -/ theorem norm_eq_iInf_iff_real_inner_le_zero {K : Set F} (h : Convex ℝ K) {u : F} {v : F} (hv : v ∈ K) : (‖u - v‖ = ⨅ w : K, ‖u - w‖) ↔ ∀ w ∈ K, ⟪u - v, w - v⟫_ℝ ≤ 0 := by - letI : Nonempty K := ⟨⟨v, hv⟩⟩ + let : Nonempty K := ⟨⟨v, hv⟩⟩ constructor · intro eq w hw let δ := ⨅ w : K, ‖u - w‖ @@ -229,7 +229,7 @@ This point `v` is usually called the orthogonal projection of `u` onto `K`. -/ theorem exists_norm_eq_iInf_of_complete_subspace (h : IsComplete (↑K : Set E)) : ∀ u : E, ∃ v ∈ K, ‖u - v‖ = ⨅ w : (K : Set E), ‖u - w‖ := by - letI : InnerProductSpace ℝ E := InnerProductSpace.rclikeToReal 𝕜 E + let : InnerProductSpace ℝ E := InnerProductSpace.rclikeToReal 𝕜 E let K' : Submodule ℝ E := Submodule.restrictScalars ℝ K exact exists_norm_eq_iInf_of_complete_convex ⟨0, K'.zero_mem⟩ h K'.convex @@ -284,7 +284,7 @@ for all `w ∈ K`, `⟪u - v, w⟫ = 0` (i.e., `u - v` is orthogonal to the subs -/ theorem norm_eq_iInf_iff_inner_eq_zero {u : E} {v : E} (hv : v ∈ K) : (‖u - v‖ = ⨅ w : K, ‖u - w‖) ↔ ∀ w ∈ K, ⟪u - v, w⟫ = 0 := by - letI : InnerProductSpace ℝ E := InnerProductSpace.rclikeToReal 𝕜 E + let : InnerProductSpace ℝ E := InnerProductSpace.rclikeToReal 𝕜 E let K' : Submodule ℝ E := K.restrictScalars ℝ constructor · intro H diff --git a/Mathlib/Analysis/InnerProductSpace/Rayleigh.lean b/Mathlib/Analysis/InnerProductSpace/Rayleigh.lean index d1eb401d913e89..7a2eb7a76150d8 100644 --- a/Mathlib/Analysis/InnerProductSpace/Rayleigh.lean +++ b/Mathlib/Analysis/InnerProductSpace/Rayleigh.lean @@ -257,7 +257,7 @@ variable [CompleteSpace E] {T : E →L[𝕜] E} theorem eq_smul_self_of_isLocalExtrOn (hT : IsSelfAdjoint T) {x₀ : E} (hextr : IsLocalExtrOn T.reApplyInnerSelf (sphere (0 : E) ‖x₀‖) x₀) : T x₀ = (T.rayleighQuotient x₀ : 𝕜) • x₀ := by - letI := InnerProductSpace.rclikeToReal 𝕜 E + let := InnerProductSpace.rclikeToReal 𝕜 E let hSA := hT.isSymmetric.restrictScalars.toSelfAdjoint.prop exact hSA.eq_smul_self_of_isLocalExtrOn_real hextr @@ -324,7 +324,7 @@ namespace IsSymmetric finite-dimensional vector space is an eigenvalue for that operator. -/ theorem hasEigenvalue_iSup_of_finiteDimensional [Nontrivial E] (hT : T.IsSymmetric) : HasEigenvalue T (⨆ x : { x : E // x ≠ 0 }, RCLike.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by - haveI := FiniteDimensional.proper_rclike 𝕜 E + have := FiniteDimensional.proper_rclike 𝕜 E let T' := hT.toSelfAdjoint obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0 have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _ @@ -343,7 +343,7 @@ theorem hasEigenvalue_iSup_of_finiteDimensional [Nontrivial E] (hT : T.IsSymmetr finite-dimensional vector space is an eigenvalue for that operator. -/ theorem hasEigenvalue_iInf_of_finiteDimensional [Nontrivial E] (hT : T.IsSymmetric) : HasEigenvalue T (⨅ x : { x : E // x ≠ 0 }, RCLike.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by - haveI := FiniteDimensional.proper_rclike 𝕜 E + have := FiniteDimensional.proper_rclike 𝕜 E let T' := hT.toSelfAdjoint obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0 have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _ diff --git a/Mathlib/Analysis/InnerProductSpace/Spectrum.lean b/Mathlib/Analysis/InnerProductSpace/Spectrum.lean index 5e27101335fda7..b6eaae80d2bd5e 100644 --- a/Mathlib/Analysis/InnerProductSpace/Spectrum.lean +++ b/Mathlib/Analysis/InnerProductSpace/Spectrum.lean @@ -140,7 +140,7 @@ theorem orthogonalComplement_iSup_eigenspaces_eq_bot (hT : T.IsSymmetric) : have hT' : IsSymmetric _ := hT.restrict_invariant hT.orthogonalComplement_iSup_eigenspaces_invariant -- a self-adjoint operator on a nontrivial inner product space has an eigenvalue - haveI := + have := hT'.subsingleton_of_no_eigenvalue_finiteDimensional hT.orthogonalComplement_iSup_eigenspaces exact Submodule.eq_bot_of_subsingleton diff --git a/Mathlib/Analysis/InnerProductSpace/l2Space.lean b/Mathlib/Analysis/InnerProductSpace/l2Space.lean index a4d66041103696..f91432211feb98 100644 --- a/Mathlib/Analysis/InnerProductSpace/l2Space.lean +++ b/Mathlib/Analysis/InnerProductSpace/l2Space.lean @@ -430,7 +430,7 @@ protected theorem hasSum_repr_symm (b : HilbertBasis ι 𝕜 E) (f : ℓ²(ι, exact (↑b.repr.symm.toContinuousLinearEquiv : ℓ²(ι, 𝕜) →L[𝕜] E).hasSum this ext i apply b.repr.injective - letI : NormedSpace 𝕜 (lp (fun _i : ι => 𝕜) 2) := by infer_instance + let : NormedSpace 𝕜 (lp (fun _i : ι => 𝕜) 2) := by infer_instance have : lp.single (E := (fun _ : ι => 𝕜)) 2 i (f i * 1) = f i • lp.single 2 i 1 := lp.single_smul (E := (fun _ : ι => 𝕜)) 2 i (f i) (1 : 𝕜) rw [mul_one] at this diff --git a/Mathlib/Analysis/LocallyConvex/Bounded.lean b/Mathlib/Analysis/LocallyConvex/Bounded.lean index e566bef73d8e25..14832b54bbd622 100644 --- a/Mathlib/Analysis/LocallyConvex/Bounded.lean +++ b/Mathlib/Analysis/LocallyConvex/Bounded.lean @@ -390,7 +390,7 @@ variable [UniformSpace E] [IsUniformAddGroup E] [ContinuousSMul 𝕜 E] theorem TotallyBounded.isVonNBounded {s : Set E} (hs : TotallyBounded s) : Bornology.IsVonNBounded 𝕜 s := by if h : ∃ x : 𝕜, 1 < ‖x‖ then - letI : NontriviallyNormedField 𝕜 := ⟨h⟩ + let : NontriviallyNormedField 𝕜 := ⟨h⟩ rw [totallyBounded_iff_subset_finite_iUnion_nhds_zero] at hs intro U hU have h : Filter.Tendsto (fun x : E × E => x.fst + x.snd) (𝓝 0) (𝓝 0) := @@ -406,7 +406,7 @@ theorem TotallyBounded.isVonNBounded {s : Set E} (hs : TotallyBounded s) : refine fun y _ => Absorbs.mono_left ?_ hx_fstsnd exact (absorbent_nhds_zero hx.1.1).vadd_absorbs hx.2.2.absorbs_self else - haveI : BoundedSpace 𝕜 := ⟨Metric.isBounded_iff.2 ⟨1, by simp_all [dist_eq_norm]⟩⟩ + have : BoundedSpace 𝕜 := ⟨Metric.isBounded_iff.2 ⟨1, by simp_all [dist_eq_norm]⟩⟩ exact Bornology.IsVonNBounded.of_boundedSpace end IsUniformAddGroup diff --git a/Mathlib/Analysis/LocallyConvex/HahnBanach.lean b/Mathlib/Analysis/LocallyConvex/HahnBanach.lean index 1082d18d304e88..7036a95558e333 100644 --- a/Mathlib/Analysis/LocallyConvex/HahnBanach.lean +++ b/Mathlib/Analysis/LocallyConvex/HahnBanach.lean @@ -51,9 +51,9 @@ variable [NormedField 𝕜] [IsRCLikeNormedField 𝕜] theorem Module.Dual.exists_extension_of_le_seminorm [Module 𝕜 E] (S : Submodule 𝕜 E) (f : Dual 𝕜 S) {p : Seminorm 𝕜 E} (hp : ∀ x, ‖f x‖ ≤ p x) : ∃ g : Dual 𝕜 E, (∀ x : S, g x = f x) ∧ ∀ x, ‖g x‖ ≤ p x := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 - letI : Module ℝ E := .restrictScalars ℝ 𝕜 E - letI : IsScalarTower ℝ 𝕜 E := .restrictScalars _ _ _ + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : Module ℝ E := .restrictScalars ℝ 𝕜 E + let : IsScalarTower ℝ 𝕜 E := .restrictScalars _ _ _ let fr : Dual ℝ S := reLm.comp (f.restrictScalars ℝ) obtain ⟨g, (hg : ∀ x : S, g x = fr x), hgp⟩ := fr.exists_extension_of_le_seminorm_real (S.restrictScalars ℝ) (p := p.restrictScalars ℝ) @@ -106,7 +106,7 @@ space. -/ lemma ContinuousLinearMap.exist_extension_of_finiteDimensional_range {S : Submodule 𝕜 E} (f : S →L[𝕜] F) [FiniteDimensional 𝕜 f.range] : ∃ g : E →L[𝕜] F, f = g.comp S.subtypeL := by - letI : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 + let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 let b := Module.finBasis 𝕜 f.range let e := b.equivFunL let fi := fun i ↦ (LinearMap.toContinuousLinearMap (b.coord i)).comp diff --git a/Mathlib/Analysis/LocallyConvex/WeakDual.lean b/Mathlib/Analysis/LocallyConvex/WeakDual.lean index 92f685b76fa21a..881346ba1a82e5 100644 --- a/Mathlib/Analysis/LocallyConvex/WeakDual.lean +++ b/Mathlib/Analysis/LocallyConvex/WeakDual.lean @@ -137,9 +137,9 @@ functionals. -/ theorem mem_span_iff_continuous {f : ι → E →ₗ[𝕜] 𝕜} (φ : E →ₗ[𝕜] 𝕜) : φ ∈ Submodule.span 𝕜 (Set.range f) ↔ Continuous[⨅ i, induced (f i) inferInstance, inferInstance] φ := by - letI t𝕜 : TopologicalSpace 𝕜 := inferInstance - letI t₁ : TopologicalSpace E := ⨅ i, induced (f i) t𝕜 - letI t₂ (s : Finset ι) : TopologicalSpace E := ⨅ i : s, induced (f i) t𝕜 + let t𝕜 : TopologicalSpace 𝕜 := inferInstance + let t₁ : TopologicalSpace E := ⨅ i, induced (f i) t𝕜 + let t₂ (s : Finset ι) : TopologicalSpace E := ⨅ i : s, induced (f i) t𝕜 suffices Continuous[t₁, t𝕜] φ ↔ ∃ s : Finset ι, Continuous[t₂ s, t𝕜] φ by simp_rw [this, ← mem_span_iff_continuous_of_finite, Submodule.span_range_eq_iSup, @@ -163,7 +163,7 @@ theorem mem_span_iff_bound {f : ι → E →ₗ[𝕜] 𝕜} (φ : E →ₗ[𝕜] φ ∈ Submodule.span 𝕜 (Set.range f) ↔ ∃ s : Finset ι, ∃ c : ℝ≥0, φ.toSeminorm ≤ c • (s.sup fun i ↦ (f i).toSeminorm) := by - letI t𝕜 : TopologicalSpace 𝕜 := inferInstance + let t𝕜 : TopologicalSpace 𝕜 := inferInstance let t := ⨅ i, induced (f i) t𝕜 have : IsTopologicalAddGroup E := topologicalAddGroup_iInf fun _ ↦ topologicalAddGroup_induced _ have : WithSeminorms (fun i ↦ (f i).toSeminorm) := by diff --git a/Mathlib/Analysis/Matrix/LDL.lean b/Mathlib/Analysis/Matrix/LDL.lean index f9e34f9e8eec95..83f01ab263e5a5 100644 --- a/Mathlib/Analysis/Matrix/LDL.lean +++ b/Mathlib/Analysis/Matrix/LDL.lean @@ -59,8 +59,8 @@ theorem LDL.lowerInv_eq_gramSchmidtBasis : ((Pi.basisFun 𝕜 n).toMatrix (@gramSchmidtBasis 𝕜 (n → 𝕜) _ (Sᵀ.toNormedAddCommGroup hS.transpose) (Sᵀ.toInnerProductSpace hS.transpose.posSemidef) n _ _ _ (Pi.basisFun 𝕜 n)))ᵀ := by - letI := (Sᵀ.toNormedAddCommGroup hS.transpose) - letI := (Sᵀ.toInnerProductSpace hS.transpose.posSemidef) + let := (Sᵀ.toNormedAddCommGroup hS.transpose) + let := (Sᵀ.toInnerProductSpace hS.transpose.posSemidef) ext i j rw [LDL.lowerInv, Basis.coePiBasisFun.toMatrix_eq_transpose, coe_gramSchmidtBasis] rfl diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean index 9ce6fe4f1ad9a8..559c5ad9cf6dd6 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean @@ -63,7 +63,7 @@ theorem AffineBasis.interior_convexHull {ι E : Type*} [Finite ι] [NormedAddCom AffineSubspace.eq_univ_of_subsingleton_span_eq_top (subsingleton_range _) b.tot simp [this] · -- The positive-dimensional case. - haveI : FiniteDimensional ℝ E := b.finiteDimensional + have : FiniteDimensional ℝ E := b.finiteDimensional have : convexHull ℝ (range b) = ⋂ i, b.coord i ⁻¹' Ici 0 := by rw [b.convexHull_eq_nonneg_coord, setOf_forall]; rfl ext @@ -126,7 +126,7 @@ theorem affineSpan_eq_top_of_nonempty_interior {s : Set V} theorem AffineBasis.centroid_mem_interior_convexHull {ι} [Fintype ι] (b : AffineBasis ι ℝ V) : Finset.univ.centroid ℝ b ∈ interior (convexHull ℝ (range b)) := by - haveI := b.nonempty + have := b.nonempty simp only [b.interior_convexHull, mem_setOf_eq, b.coord_apply_centroid (Finset.mem_univ _), inv_pos, Nat.cast_pos, Finset.card_pos, Finset.univ_nonempty, forall_true_iff] diff --git a/Mathlib/Analysis/Normed/Affine/MazurUlam.lean b/Mathlib/Analysis/Normed/Affine/MazurUlam.lean index 64159ec8e19bc6..7b9dafac98dbc3 100644 --- a/Mathlib/Analysis/Normed/Affine/MazurUlam.lean +++ b/Mathlib/Analysis/Normed/Affine/MazurUlam.lean @@ -49,7 +49,7 @@ theorem midpoint_fixed {x y : PE} : set z := midpoint ℝ x y -- Consider the set of `e : E ≃ᵢ E` such that `e x = x` and `e y = y` set s := { e : PE ≃ᵢ PE | e x = x ∧ e y = y } - haveI : Nonempty s := ⟨⟨IsometryEquiv.refl PE, rfl, rfl⟩⟩ + have : Nonempty s := ⟨⟨IsometryEquiv.refl PE, rfl, rfl⟩⟩ -- On the one hand, `e` cannot send the midpoint `z` of `[x, y]` too far have h_bdd : BddAbove (range fun e : s => dist ((e : PE ≃ᵢ PE) z) z) := by refine ⟨dist x z + dist x z, forall_mem_range.2 <| Subtype.forall.2 ?_⟩ diff --git a/Mathlib/Analysis/Normed/Algebra/Exponential.lean b/Mathlib/Analysis/Normed/Algebra/Exponential.lean index a1a169cb33b4c4..899c00549cd086 100644 --- a/Mathlib/Analysis/Normed/Algebra/Exponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/Exponential.lean @@ -377,7 +377,7 @@ theorem isUnit_exp_of_mem_ball [CharZero 𝕂] {x : 𝔸} theorem invOf_exp_of_mem_ball [CharZero 𝕂] {x : 𝔸} (hx : x ∈ Metric.eball (0 : 𝔸) (expSeries 𝕂 𝔸).radius) [Invertible (exp x)] : ⅟(exp x) = exp (-x) := by - letI := invertibleExpOfMemBall hx; convert! (rfl : ⅟(exp x) = _) + let := invertibleExpOfMemBall hx; convert! (rfl : ⅟(exp x) = _) /-- Any continuous ring homomorphism commutes with `NormedSpace.exp`. -/ theorem map_exp_of_mem_ball [Algebra 𝕂 𝔹] [CharZero 𝕂] {F} [FunLike F 𝔸 𝔹] [RingHomClass F 𝔸 𝔹] diff --git a/Mathlib/Analysis/Normed/Algebra/QuaternionExponential.lean b/Mathlib/Analysis/Normed/Algebra/QuaternionExponential.lean index a9da2d7116e7fc..1fa83cb1e4a22a 100644 --- a/Mathlib/Analysis/Normed/Algebra/QuaternionExponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/QuaternionExponential.lean @@ -42,7 +42,7 @@ theorem expSeries_even_of_imaginary {q : Quaternion ℝ} (hq : q.re = 0) (n : ↑((-1 : ℝ) ^ n * ‖q‖ ^ (2 * n) / (2 * n)!) := by rw [expSeries_apply_eq] have hq2 : q ^ 2 = -normSq q := sq_eq_neg_normSq.mpr hq - letI k : ℝ := ↑(2 * n)! + let k : ℝ := ↑(2 * n)! calc k⁻¹ • q ^ (2 * n) = k⁻¹ • (-normSq q) ^ n := by rw [pow_mul, hq2] _ = k⁻¹ • ↑((-1 : ℝ) ^ n * ‖q‖ ^ (2 * n)) := ?_ diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index 152771a3d46fe5..3e85035d51555c 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -120,7 +120,7 @@ theorem mem_resolventSet_of_norm_lt_mul {a : A} {k : 𝕜} (h : ‖a‖ * ‖(1 nontriviality A have hk : k ≠ 0 := ne_zero_of_norm_ne_zero ((mul_nonneg (norm_nonneg _) (norm_nonneg _)).trans_lt h).ne' - letI ku := Units.map ↑ₐ.toMonoidHom (Units.mk0 k hk) + let ku := Units.map ↑ₐ.toMonoidHom (Units.mk0 k hk) rw [← inv_inv ‖(1 : A)‖, mul_inv_lt_iff₀' (inv_pos.2 <| norm_pos_iff.2 (one_ne_zero : (1 : A) ≠ 0))] at h have hku : ‖-a‖ < ‖(↑ku⁻¹ : A)‖⁻¹ := by simpa [ku, norm_algebraMap] using h diff --git a/Mathlib/Analysis/Normed/Field/Dense.lean b/Mathlib/Analysis/Normed/Field/Dense.lean index 8925e7da7400f5..36f04de14093ee 100644 --- a/Mathlib/Analysis/Normed/Field/Dense.lean +++ b/Mathlib/Analysis/Normed/Field/Dense.lean @@ -51,8 +51,8 @@ theorem IsAlgClosed.of_denseRange {K L : Type*} [Field K] [NontriviallyNormedFie intro f fmon firr have fnatdeg0 : f.natDegree ≠ 0 := (Irreducible.natDegree_pos firr).ne' let F := f.SplittingField - letI : NormedField F := spectralNorm.normedField L F - letI : NormedAlgebra L F := spectralNorm.normedAlgebra L F + let : NormedField F := spectralNorm.normedField L F + let : NormedAlgebra L F := spectralNorm.normedAlgebra L F let a := rootOfSplits (SplittingField.splits f) (by simpa using degree_ne_of_natDegree_ne fnatdeg0) have fa0 : f.aeval a = 0 := by diff --git a/Mathlib/Analysis/Normed/Group/Uniform.lean b/Mathlib/Analysis/Normed/Group/Uniform.lean index f3b432ea05b8e2..82be8e8e0979af 100644 --- a/Mathlib/Analysis/Normed/Group/Uniform.lean +++ b/Mathlib/Analysis/Normed/Group/Uniform.lean @@ -347,7 +347,7 @@ namespace AntilipschitzWith @[to_additive] theorem mul_lipschitzWith (hf : AntilipschitzWith Kf f) (hg : LipschitzWith Kg g) (hK : Kg < Kf⁻¹) : AntilipschitzWith (Kf⁻¹ - Kg)⁻¹ fun x => f x * g x := by - letI : PseudoMetricSpace α := PseudoEMetricSpace.toPseudoMetricSpace hf.edist_ne_top + let : PseudoMetricSpace α := PseudoEMetricSpace.toPseudoMetricSpace hf.edist_ne_top refine AntilipschitzWith.of_le_mul_dist fun x y => ?_ rw [NNReal.coe_inv, ← _root_.div_eq_inv_mul] rw [le_div_iff₀ (NNReal.coe_pos.2 <| tsub_pos_iff_lt.2 hK)] diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 29f923f2419acb..4be115938cf607 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -1013,7 +1013,7 @@ variable [DecidableEq ι] @[simp] theorem nnnorm_single (i : ι) (b : β i) : ‖single p i b‖₊ = ‖b‖₊ := by - haveI : Nonempty ι := ⟨i⟩ + have : Nonempty ι := ⟨i⟩ induction p generalizing hp with | top => simp_rw [nnnorm_eq_ciSup] @@ -1262,7 +1262,7 @@ lemma isBoundedSMulSeminormedAddCommGroupToPi [∀ i, Module R (α i)] [∀ i, IsBoundedSMul R (α i)] : letI := pseudoMetricSpaceToPi p α IsBoundedSMul R (Π i, α i) := by - letI := pseudoMetricSpaceToPi p α + let := pseudoMetricSpaceToPi p α refine ⟨fun x y z ↦ ?_, fun x y z ↦ ?_⟩ · simpa [dist_pseudoMetricSpaceToPi] using dist_smul_pair x (toLp p y) (toLp p z) · simpa [dist_pseudoMetricSpaceToPi] using dist_pair_smul x y (toLp p z) @@ -1272,7 +1272,7 @@ lemma normSMulClassSeminormedAddCommGroupToPi [∀ i, Module R (α i)] [∀ i, NormSMulClass R (α i)] : letI := seminormedAddCommGroupToPi p α NormSMulClass R (Π i, α i) := by - letI := seminormedAddCommGroupToPi p α + let := seminormedAddCommGroupToPi p α refine ⟨fun x y ↦ ?_⟩ simp [norm_seminormedAddCommGroupToPi, norm_smul] diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 739a0034d95587..3e83aac3ee4109 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -1047,7 +1047,7 @@ lemma isBoundedSMulSeminormedAddCommGroupToProd [Module R α] [Module R β] [IsBoundedSMul R α] [IsBoundedSMul R β] : letI := pseudoMetricSpaceToProd p α β IsBoundedSMul R (α × β) := by - letI := pseudoMetricSpaceToProd p α β + let := pseudoMetricSpaceToProd p α β refine ⟨fun x y z ↦ ?_, fun x y z ↦ ?_⟩ · simpa [dist_pseudoMetricSpaceToProd] using dist_smul_pair x (toLp p y) (toLp p z) · simpa [dist_pseudoMetricSpaceToProd] using dist_pair_smul x y (toLp p z) @@ -1057,7 +1057,7 @@ lemma normSMulClassSeminormedAddCommGroupToProd [Module R α] [Module R β] [NormSMulClass R α] [NormSMulClass R β] : letI := seminormedAddCommGroupToProd p α β NormSMulClass R (α × β) := by - letI := seminormedAddCommGroupToProd p α β + let := seminormedAddCommGroupToProd p α β exact ⟨fun x y ↦ norm_smul x (toLp p y)⟩ /-- This definition allows to endow `α × β` with a normed space structure corresponding to diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index 172f73b6945bf4..e3ecc77a6213e8 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -283,7 +283,7 @@ theorem sub {f g : ∀ i, E i} (hf : Memℓp f p) (hg : Memℓp g p) : Memℓp ( theorem finsetSum {ι} (s : Finset ι) {f : ι → ∀ i, E i} (hf : ∀ i ∈ s, Memℓp (f i) p) : Memℓp (fun a => ∑ i ∈ s, f i a) p := by - haveI : DecidableEq ι := Classical.decEq _ + have : DecidableEq ι := Classical.decEq _ revert hf refine Finset.induction_on s ?_ ?_ · simp only [zero_mem_ℓp', Finset.sum_empty, imp_true_iff] @@ -599,7 +599,7 @@ section ComparePointwise theorem norm_apply_le_norm (hp : p ≠ 0) (f : lp E p) (i : α) : ‖f i‖ ≤ ‖f‖ := by rcases eq_or_ne p ∞ with (rfl | hp') - · haveI : Nonempty α := ⟨i⟩ + · have : Nonempty α := ⟨i⟩ exact (isLUB_norm f).1 ⟨i, rfl⟩ have hp'' : 0 < p.toReal := ENNReal.toReal_pos hp hp' have : ∀ i, 0 ≤ ‖f i‖ ^ p.toReal := fun i ↦ by positivity @@ -712,7 +712,7 @@ theorem norm_const_smul_le (hp : p ≠ 0) (c : 𝕜) (f : lp E p) : ‖c • f simp_rw [← Set.range_comp, Function.comp_def] at hfc exact norm_le_of_forall_le (by positivity) fun i ↦ norm_smul_le c (f i) |>.trans <| hfc.1 ⟨i, rfl⟩ - · letI inst : NNNorm (lp E p) := ⟨fun f => ⟨‖f‖, norm_nonneg' _⟩⟩ + · let inst : NNNorm (lp E p) := ⟨fun f => ⟨‖f‖, norm_nonneg' _⟩⟩ have coe_nnnorm : ∀ f : lp E p, ↑‖f‖₊ = ‖f‖ := fun _ => rfl suffices ‖c • f‖₊ ^ p.toReal ≤ (‖c‖₊ * ‖f‖₊) ^ p.toReal by rwa [NNReal.rpow_le_rpow_iff hp] at this @@ -1095,7 +1095,7 @@ protected theorem norm_sum_single (hp : 0 < p.toReal) (f : ∀ i, E i) (s : Fins @[simp] protected theorem norm_single (hp : 0 < p) (i : α) (x : E i) : ‖lp.single p i x‖ = ‖x‖ := by - haveI : Nonempty α := ⟨i⟩ + have : Nonempty α := ⟨i⟩ induction p with | top => simp only [norm_eq_ciSup, lp.coeFn_single] diff --git a/Mathlib/Analysis/Normed/Module/Basic.lean b/Mathlib/Analysis/Normed/Module/Basic.lean index af6d6e2b774a5c..430def7cd51eb1 100644 --- a/Mathlib/Analysis/Normed/Module/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Basic.lean @@ -236,7 +236,7 @@ Lean would have to search for `NormedSpace 𝕜 E` with unknown `𝕜`. We register this as an instance in two cases: `𝕜 = E` and `𝕜 = ℝ`. -/ protected theorem NormedSpace.noncompactSpace : NoncompactSpace E := by by_cases! H : ∃ c : 𝕜, c ≠ 0 ∧ ‖c‖ ≠ 1 - · letI := NontriviallyNormedField.ofNormNeOne H + · let := NontriviallyNormedField.ofNormNeOne H exact ⟨fun h ↦ NormedSpace.unbounded_univ 𝕜 E h.isBounded⟩ · rcases exists_ne (0 : E) with ⟨x, hx⟩ suffices IsClosedEmbedding (Infinite.natEmbedding 𝕜 · • x) from this.noncompactSpace @@ -689,7 +689,7 @@ See note [reducible non-instances]. -/ abbrev NormedAddCommGroup.ofCore (core : NormedSpace.Core 𝕜 E) : NormedAddCommGroup E := { SeminormedAddCommGroup.ofCore core.toCore with eq_of_dist_eq_zero := by - letI := SeminormedAddCommGroup.ofCore core.toCore + let := SeminormedAddCommGroup.ofCore core.toCore intro x y h rw [← sub_eq_zero, ← core.norm_eq_zero_iff, ← norm_neg_add] exact h } @@ -703,7 +703,7 @@ abbrev NormedAddCommGroup.ofCoreReplaceUniformity [U : UniformSpace E] (core : N NormedAddCommGroup E := { SeminormedAddCommGroup.ofCoreReplaceUniformity core.toCore H with eq_of_dist_eq_zero := by - letI := SeminormedAddCommGroup.ofCore core.toCore + let := SeminormedAddCommGroup.ofCore core.toCore intro x y h rw [← sub_eq_zero, ← core.norm_eq_zero_iff, ← norm_neg_add] exact h } @@ -718,7 +718,7 @@ abbrev NormedAddCommGroup.ofCoreReplaceTopology [T : TopologicalSpace E] NormedAddCommGroup E := { SeminormedAddCommGroup.ofCoreReplaceTopology core.toCore H with eq_of_dist_eq_zero := by - letI := SeminormedAddCommGroup.ofCore core.toCore + let := SeminormedAddCommGroup.ofCore core.toCore intro x y h rw [← sub_eq_zero, ← core.norm_eq_zero_iff, ← norm_neg_add] exact h } @@ -737,7 +737,7 @@ abbrev NormedAddCommGroup.ofCoreReplaceAll [U : UniformSpace E] [B : Bornology E NormedAddCommGroup E := { SeminormedAddCommGroup.ofCoreReplaceAll core.toCore HU HB with eq_of_dist_eq_zero := by - letI := SeminormedAddCommGroup.ofCore core.toCore + let := SeminormedAddCommGroup.ofCore core.toCore intro x y h rw [← sub_eq_zero, ← core.norm_eq_zero_iff, ← norm_neg_add] exact h } diff --git a/Mathlib/Analysis/Normed/Module/Complemented.lean b/Mathlib/Analysis/Normed/Module/Complemented.lean index 077e5edb4a4ac7..3483b2bb18d340 100644 --- a/Mathlib/Analysis/Normed/Module/Complemented.lean +++ b/Mathlib/Analysis/Normed/Module/Complemented.lean @@ -81,7 +81,7 @@ variable [CompleteSpace E] {p q : Subspace 𝕜 E} theorem IsCompl.isTopCompl_of_isClosed (h : IsCompl p q) (hp : IsClosed (p : Set E)) (hq : IsClosed (q : Set E)) : IsTopCompl p q := by - haveI := hp.completeSpace_coe; haveI := hq.completeSpace_coe + have := hp.completeSpace_coe; have := hq.completeSpace_coe rw [isTopCompl_iff_continuous_symm_prodEquivOfIsCompl h] exact (p.prodEquivOfIsCompl q h).continuous_symm (continuous_prodEquivOfIsCompl h) diff --git a/Mathlib/Analysis/Normed/Module/Dual.lean b/Mathlib/Analysis/Normed/Module/Dual.lean index bfe7243f4aa58e..c879c34369bd60 100644 --- a/Mathlib/Analysis/Normed/Module/Dual.lean +++ b/Mathlib/Analysis/Normed/Module/Dual.lean @@ -117,7 +117,7 @@ theorem polar_closedBall {𝕜 E : Type*} [RCLike 𝕜] [NormedAddCommGroup E] [ theorem polar_ball {𝕜 E : Type*} [RCLike 𝕜] [NormedAddCommGroup E] [NormedSpace 𝕜 E] {r : ℝ} (hr : 0 < r) : StrongDual.polar 𝕜 (ball (0 : E) r) = closedBall (0 : StrongDual 𝕜 E) r⁻¹ := by - letI : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E + let : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E rw [← polar_closedBall hr, ← closure_ball _ hr.ne', polar_closure] /-- Given a neighborhood `s` of the origin in a normed space `E`, the dual norms of all elements of diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index efa1834193c4dc..e0dfb1aab6f191 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -184,7 +184,7 @@ theorem ContinuousLinearMap.continuous_det : Continuous fun f : E →L[𝕜] E = -- TODO: this could be easier with `det_cases` by_cases h : ∃ s : Finset E, Nonempty (Basis (↥s) 𝕜 E) · rcases h with ⟨s, ⟨b⟩⟩ - haveI : FiniteDimensional 𝕜 E := b.finiteDimensional_of_finite + have : FiniteDimensional 𝕜 E := b.finiteDimensional_of_finite classical simp_rw [LinearMap.det_eq_det_toMatrix_of_finset b] refine Continuous.matrix_det ?_ @@ -347,7 +347,7 @@ theorem isOpen_setOf_affineIndependent {ι : Type*} [Finite ι] : · simp_rw [affineIndependent_iff_linearIndependent_vsub 𝕜 _ i₀] let ι' := { x // x ≠ i₀ } cases nonempty_fintype ι - haveI : Fintype ι' := Subtype.fintype _ + have : Fintype ι' := Subtype.fintype _ convert_to! IsOpen ((fun (p : ι → E) (i : ι') ↦ p i -ᵥ p i₀) ⁻¹' {p : ι' → E | LinearIndependent 𝕜 p}) exact isOpen_setOf_linearIndependent.preimage (by fun_prop) @@ -418,7 +418,7 @@ theorem exists_norm_le_le_norm_sub_of_finset {c : 𝕜} (hc : 1 < ‖c‖) {R : (h : ¬FiniteDimensional 𝕜 E) (s : Finset E) : ∃ x : E, ‖x‖ ≤ R ∧ ∀ y ∈ s, 1 ≤ ‖y - x‖ := by let F := Submodule.span 𝕜 (s : Set E) have hF : F.FG := ⟨s, rfl⟩ - haveI : FiniteDimensional 𝕜 F := .of_fg hF + have : FiniteDimensional 𝕜 F := .of_fg hF have Fclosed : IsClosed (F : Set E) := Submodule.closed_of_finiteDimensional _ have : ∃ x, x ∉ F := by contrapose! h diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean index d179029f25fa13..39bf5c820a5533 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean @@ -559,7 +559,7 @@ section @[simp] theorem norm_ofSubsingleton [Subsingleton ι] (i : ι) (f : G →L[𝕜] G') : ‖ofSubsingleton 𝕜 G G' i f‖ = ‖f‖ := by - letI : Unique ι := uniqueOfSubsingleton i + let : Unique ι := uniqueOfSubsingleton i simp [norm_def, ContinuousLinearMap.norm_def, (Equiv.funUnique _ _).symm.surjective.forall] @[simp] diff --git a/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean b/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean index 2f96bba86fc9c1..a57b8fa378a933 100644 --- a/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean +++ b/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean @@ -91,8 +91,8 @@ lemma hasProdUniformlyOn_one_add (hK : IsCompact K) (hu : Summable u) tendstoUniformlyOn_iff_tendstoUniformly_comp_coe] by_cases hKe : K = ∅ · simp [TendstoUniformly, hKe] - · haveI hCK : CompactSpace K := isCompact_iff_compactSpace.mp hK - haveI hne : Nonempty K := by rwa [Set.nonempty_coe_sort, Set.nonempty_iff_ne_empty] + · have hCK : CompactSpace K := isCompact_iff_compactSpace.mp hK + have hne : Nonempty K := by rwa [Set.nonempty_coe_sort, Set.nonempty_iff_ne_empty] let f' i : C(K, R) := ⟨_, continuousOn_iff_continuous_restrict.mp (hcts i)⟩ have hf'_bd : ∀ᶠ i in cofinite, ‖f' i‖ ≤ u i := by simp only [ContinuousMap.norm_le_of_nonempty] diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean index 6c07e93e422bf7..85d108520eaa5c 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean @@ -123,8 +123,8 @@ theorem norm_eval_le_injectiveSeminorm (f : ContinuousMultilinearMap 𝕜 E F) ( set G := (⨂[𝕜] i, E i) ⧸ LinearMap.ker (lift f.toMultilinearMap) set G' := LinearMap.range (lift f.toMultilinearMap) set e := LinearMap.quotKerEquivRange (lift f.toMultilinearMap) - letI := SeminormedAddCommGroup.induced G G' e - letI := NormedSpace.induced 𝕜 G G' e + let := SeminormedAddCommGroup.induced G G' e + let := NormedSpace.induced 𝕜 G G' e set f'₀ := lift.symm (e.symm.toLinearMap ∘ₗ LinearMap.rangeRestrict (lift f.toMultilinearMap)) have hf'₀ : ∀ (x : Π (i : ι), E i), ‖f'₀ x‖ ≤ ‖f‖ * ∏ i, ‖x i‖ := fun x ↦ by change ‖e (f'₀ x)‖ ≤ _ diff --git a/Mathlib/Analysis/Normed/Operator/Banach.lean b/Mathlib/Analysis/Normed/Operator/Banach.lean index ba85918fe33a85..26a7925b5d0952 100644 --- a/Mathlib/Analysis/Normed/Operator/Banach.lean +++ b/Mathlib/Analysis/Normed/Operator/Banach.lean @@ -518,7 +518,7 @@ theorem closed_complemented_range_of_isCompl_of_ker_eq_bot {F : Type*} [NormedAd [NormedSpace 𝕜 F] [CompleteSpace F] (f : E →L[𝕜] F) (G : Submodule 𝕜 F) (h : IsCompl f.range G) (hG : IsClosed (G : Set F)) (hker : f.ker = ⊥) : IsClosed (f.range : Set F) := by - haveI : CompleteSpace G := hG.completeSpace_coe + have : CompleteSpace G := hG.completeSpace_coe let g := coprodSubtypeLEquivOfIsCompl f h hker rw [range_eq_map_coprodSubtypeLEquivOfIsCompl f h hker] apply g.toHomeomorph.isClosed_image.2 @@ -535,7 +535,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] [CompleteSpace is continuous. -/ theorem LinearMap.continuous_of_isClosed_graph (hg : IsClosed (g.graph : Set <| E × F)) : Continuous g := by - letI : CompleteSpace g.graph := completeSpace_coe_iff_isComplete.mpr hg.isComplete + let : CompleteSpace g.graph := completeSpace_coe_iff_isComplete.mpr hg.isComplete let φ₀ : E →ₗ[𝕜] E × F := LinearMap.id.prod g have : Function.LeftInverse Prod.fst φ₀ := fun x => rfl let φ : E ≃ₗ[𝕜] g.graph := diff --git a/Mathlib/Analysis/Normed/Operator/NormedSpace.lean b/Mathlib/Analysis/Normed/Operator/NormedSpace.lean index 74ba95d31cf2bd..7272c4bbf258d3 100644 --- a/Mathlib/Analysis/Normed/Operator/NormedSpace.lean +++ b/Mathlib/Analysis/Normed/Operator/NormedSpace.lean @@ -303,7 +303,7 @@ variable (𝕜) @[simp] theorem coord_norm (x : E) (h : x ≠ 0) : ‖coord 𝕜 x h‖ = ‖x‖⁻¹ := by have hx : 0 < ‖x‖ := norm_pos_iff.mpr h - haveI : Nontrivial (𝕜 ∙ x) := Submodule.nontrivial_span_singleton h + have : Nontrivial (𝕜 ∙ x) := Submodule.nontrivial_span_singleton h exact ContinuousLinearMap.homothety_norm _ fun y => homothety_inverse _ hx _ (LinearEquiv.toSpanNonzeroSingleton_homothety 𝕜 x h) _ diff --git a/Mathlib/Analysis/Normed/Order/UpperLower.lean b/Mathlib/Analysis/Normed/Order/UpperLower.lean index 1002ad60b906cd..364b117e86af48 100644 --- a/Mathlib/Analysis/Normed/Order/UpperLower.lean +++ b/Mathlib/Analysis/Normed/Order/UpperLower.lean @@ -212,7 +212,7 @@ protected lemma IsClosed.lowerClosure_pi (hs : IsClosed s) (hs' : BddAbove s) : cases nonempty_fintype ι refine IsSeqClosed.isClosed fun f x hf hx ↦ ?_ choose g hg hfg using hf - haveI : BoundedGENhdsClass ℝ := by infer_instance + have : BoundedGENhdsClass ℝ := by infer_instance obtain ⟨a, ha⟩ := hx.bddBelow_range obtain ⟨b, hb, φ, hφ, hbf⟩ := tendsto_subseq_of_bounded (hs'.isBounded_inter bddBelow_Ici) fun n ↦ ⟨hg n, (ha <| mem_range_self _).trans <| hfg _⟩ diff --git a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean index f887dd057b06cd..466d40538cf042 100644 --- a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean +++ b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean @@ -176,8 +176,8 @@ theorem exists_nonarchimedean_pow_mul_seminorm_of_finiteDimensional (hfd : Finit have h1 : LinearIndepOn K id ({1} : Set L) := .singleton one_ne_zero set ι := { x // x ∈ LinearIndepOn.extend h1 (Set.subset_univ ({1} : Set L)) } set B : Basis ι K L := Basis.extend h1 - letI hfin : Fintype ι := FiniteDimensional.fintypeBasisIndex B - haveI hem : Nonempty ι := B.index_nonempty + let hfin : Fintype ι := FiniteDimensional.fintypeBasisIndex B + have hem : Nonempty ι := B.index_nonempty have h1L : (1 : L) ∈ LinearIndepOn.extend h1 _ := Basis.subset_extend _ (Set.mem_singleton (1 : L)) have hB1 : B ⟨1, h1L⟩ = (1 : L) := by rw [Basis.coe_extend, Subtype.coe_mk] diff --git a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean index e8e8c4ef5c0ea9..be9786239df23c 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean @@ -583,7 +583,7 @@ variable [IsUltrametricDist K] theorem spectralNorm_neg {y : L} (hy : IsAlgebraic K y) : spectralNorm K L (-y) = spectralNorm K L y := by set E := K⟮y⟯ - haveI h_finiteDimensional_E : FiniteDimensional K E := + have h_finiteDimensional_E : FiniteDimensional K E := IntermediateField.adjoin.finiteDimensional hy.isIntegral set g := IntermediateField.AdjoinSimple.gen K y have hy : -y = (algebraMap K⟮y⟯ L) (-g) := rfl @@ -596,7 +596,7 @@ theorem spectralNorm_neg {y : L} (hy : IsAlgebraic K y) : theorem spectralNorm_smul (k : K) {y : L} (hy : IsAlgebraic K y) : spectralNorm K L (k • y) = ‖k‖₊ * spectralNorm K L y := by set E := K⟮y⟯ - haveI h_finiteDimensional_E : FiniteDimensional K E := + have h_finiteDimensional_E : FiniteDimensional K E := IntermediateField.adjoin.finiteDimensional hy.isIntegral set g := IntermediateField.AdjoinSimple.gen K y have hgy : k • y = (algebraMap (↥K⟮y⟯) L) (k • g) := rfl @@ -612,7 +612,7 @@ theorem spectralNorm_smul (k : K) {y : L} (hy : IsAlgebraic K y) : theorem spectralNorm_mul {x y : L} (hx : IsAlgebraic K x) (hy : IsAlgebraic K y) : spectralNorm K L (x * y) ≤ spectralNorm K L x * spectralNorm K L y := by set E := K⟮x, y⟯ - haveI h_finiteDimensional_E : FiniteDimensional K E := + have h_finiteDimensional_E : FiniteDimensional K E := IntermediateField.finiteDimensional_adjoin_pair hx.isIntegral hy.isIntegral set gx := IntermediateField.AdjoinPair.gen₁ K x y set gy := IntermediateField.AdjoinPair.gen₂ K x y @@ -631,7 +631,7 @@ variable [h_alg : Algebra.IsAlgebraic K L] theorem isPowMul_spectralNorm : IsPowMul (spectralNorm K L) := by intro x n hn set E := K⟮x⟯ - haveI h_finiteDimensional_E : FiniteDimensional K E := + have h_finiteDimensional_E : FiniteDimensional K E := IntermediateField.adjoin.finiteDimensional (h_alg.isAlgebraic x).isIntegral set g := IntermediateField.AdjoinSimple.gen K x with hg have h_map : algebraMap E L g ^ n = x ^ n := rfl @@ -644,7 +644,7 @@ theorem isPowMul_spectralNorm : IsPowMul (spectralNorm K L) := by theorem isNonarchimedean_spectralNorm : IsNonarchimedean (spectralNorm K L) := by intro x y set E := K⟮x, y⟯ - haveI h_finiteDimensional_E : FiniteDimensional K E := + have h_finiteDimensional_E : FiniteDimensional K E := IntermediateField.finiteDimensional_adjoin_pair (h_alg.isAlgebraic x).isIntegral (h_alg.isAlgebraic y).isIntegral set gx := IntermediateField.AdjoinPair.gen₁ K x y @@ -935,8 +935,8 @@ def uniformSpace : UniformSpace L := (metricSpace K L).toUniformSpace by the spectral norm. -/ instance (priority := 100) completeSpace [h_fin : FiniteDimensional K L] : @CompleteSpace L (uniformSpace K L) := by - letI := (normedAddCommGroup K L) - letI := (normedSpace K L) + let := (normedAddCommGroup K L) + let := (normedSpace K L) exact FiniteDimensional.complete K L omit [Algebra.IsAlgebraic K L] in diff --git a/Mathlib/Analysis/RCLike/TangentCone.lean b/Mathlib/Analysis/RCLike/TangentCone.lean index 2720c6f8d38bce..39cf5b82497327 100644 --- a/Mathlib/Analysis/RCLike/TangentCone.lean +++ b/Mathlib/Analysis/RCLike/TangentCone.lean @@ -23,12 +23,12 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [h𝕜 : IsRCLikeNormedFi theorem tangentConeAt_real_subset_isRCLikeNormedField : tangentConeAt ℝ s x ⊆ tangentConeAt 𝕜 s x := by - letI := h𝕜.rclike + let := h𝕜.rclike exact tangentConeAt_mono_field theorem UniqueDiffWithinAt.of_real (hs : UniqueDiffWithinAt ℝ s x) : UniqueDiffWithinAt 𝕜 s x := by - letI := h𝕜.rclike + let := h𝕜.rclike exact hs.mono_field theorem UniqueDiffOn.of_real (hs : UniqueDiffOn ℝ s) : diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index 6285f64161f237..11b5244eb49f77 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -488,7 +488,7 @@ noncomputable instance instSupSet : SupSet (Seminorm 𝕜 E) where rcases h with ⟨q, hq⟩ obtain rfl | h := s.eq_empty_or_nonempty · simp [Real.iSup_of_isEmpty] - haveI : Nonempty ↑s := h.coe_sort + have : Nonempty ↑s := h.coe_sort simp only [iSup_apply] refine ciSup_le fun i => ((i : Seminorm 𝕜 E).add_le' x y).trans <| add_le_add @@ -555,7 +555,7 @@ protected theorem sSup_empty : sSup (∅ : Set (Seminorm 𝕜 E)) = ⊥ := by set_option backward.privateInPublic true in private theorem isLUB_sSup (s : Set (Seminorm 𝕜 E)) (hs₁ : BddAbove s) (hs₂ : s.Nonempty) : IsLUB s (sSup s) := by - refine ⟨fun p hp x => ?_, fun p hp x => ?_⟩ <;> haveI : Nonempty ↑s := hs₂.coe_sort <;> + refine ⟨fun p hp x => ?_, fun p hp x => ?_⟩ <;> have : Nonempty ↑s := hs₂.coe_sort <;> dsimp <;> rw [Seminorm.coe_sSup_eq hs₁, iSup_apply] · rcases hs₁ with ⟨q, hq⟩ exact le_ciSup ⟨q x, forall_mem_range.mpr fun i : s => hq i.2 x⟩ ⟨p, hp⟩ @@ -725,12 +725,12 @@ lemma closedBall_eq_metric : /-- The image of a ball under addition with a singleton is another ball. -/ theorem vadd_ball (p : Seminorm 𝕜 E) : x +ᵥ p.ball y r = p.ball (x +ᵥ y) r := by - letI := AddGroupSeminorm.toSeminormedAddCommGroup p.toAddGroupSeminorm + let := AddGroupSeminorm.toSeminormedAddCommGroup p.toAddGroupSeminorm simp [ball_eq_metric] /-- The image of a closed ball under addition with a singleton is another closed ball. -/ theorem vadd_closedBall (p : Seminorm 𝕜 E) : x +ᵥ p.closedBall y r = p.closedBall (x +ᵥ y) r := by - letI := AddGroupSeminorm.toSeminormedAddCommGroup p.toAddGroupSeminorm + let := AddGroupSeminorm.toSeminormedAddCommGroup p.toAddGroupSeminorm simp [closedBall_eq_metric] end SMul @@ -1093,8 +1093,8 @@ protected theorem uniformContinuous_of_continuousAt_zero [UniformSpace E] [IsUni protected theorem continuous_of_continuousAt_zero [TopologicalSpace E] [IsTopologicalAddGroup E] {p : Seminorm 𝕝 E} (hp : ContinuousAt p 0) : Continuous p := by - letI := IsTopologicalAddGroup.rightUniformSpace E - haveI : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup + let := IsTopologicalAddGroup.rightUniformSpace E + have : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup exact (Seminorm.uniformContinuous_of_continuousAt_zero hp).continuous /-- A seminorm is uniformly continuous if `p.ball 0 r ∈ 𝓝 0` for *all* `r > 0`. diff --git a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean index b6bbf6d738c11c..2b2dbd9b9e2f95 100644 --- a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean +++ b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean @@ -181,7 +181,7 @@ and reproduced on wikipedia. -/ theorem bernsteinApproximation_uniform [LocallyConvexSpace ℝ E] (f : C(I, E)) : Tendsto (fun n : ℕ => bernsteinApproximation n f) atTop (𝓝 f) := by - letI : UniformSpace E := IsTopologicalAddGroup.rightUniformSpace E + let : UniformSpace E := IsTopologicalAddGroup.rightUniformSpace E have : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup /- Topology on a locally convex TVS is given by a family of seminorms `‖x‖_U = gauge U x`, where the open symmetric convex sets `U` form a basis of neighborhoods in this topology, diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean index 0a67f28fa8aa8e..924eb23fb2ce45 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean @@ -207,7 +207,7 @@ theorem _root_.fourierIntegral_gaussian (hb : 0 < b.re) (t : ℂ) : theorem _root_.fourier_gaussian_pi' (hb : 0 < b.re) (c : ℂ) : (𝓕 fun x : ℝ => cexp (-π * b * x ^ 2 + 2 * π * c * x)) = fun t : ℝ => 1 / b ^ (1 / 2 : ℂ) * cexp (-π / b * (t + I * c) ^ 2) := by - haveI : b ≠ 0 := by contrapose! hb; rw [hb, zero_re] + have : b ≠ 0 := by contrapose! hb; rw [hb, zero_re] have h : (-↑π * b).re < 0 := by simpa only [neg_mul, neg_re, re_ofReal_mul, neg_lt_zero] using mul_pos pi_pos hb ext1 t diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Integral.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Integral.lean index 98d734a4e48889..4f759ed2004a92 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Integral.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Integral.lean @@ -110,7 +110,7 @@ lemma integrableOn_ball_of_norm_le_rpow (hd : 1 ≤ Module.finrank ℝ E) {f : E (hα : α < Module.finrank ℝ E) (h_decay : ∀ᵐ x ∂μ.restrict (ball 0 r), ‖f x‖ ≤ C * ‖x‖ ^ (-α)) (h_meas : AEStronglyMeasurable f μ) : IntegrableOn f (ball 0 r) μ := by - haveI : Nontrivial E := by + have : Nontrivial E := by apply Module.nontrivial_of_finrank_pos (R := ℝ) positivity have hint : IntegrableOn (fun y ↦ y ^ (Module.finrank ℝ E - 1) • (C * y ^ (-α))) (Ioo 0 r) := by diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean index 7932da5e271491..940d207a167d3a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean @@ -126,7 +126,7 @@ theorem tan_add {x y : ℂ} add_div, sub_div] simp only [← div_mul_div_comm, tan, mul_one, one_mul, div_self (cos_ne_zero_iff.mpr h1), div_self (cos_ne_zero_iff.mpr h2)] - · haveI t := tan_int_mul_pi_div_two + · have t := tan_int_mul_pi_div_two obtain ⟨hx, hy, hxy⟩ := t (2 * k + 1), t (2 * l + 1), t (2 * k + 1 + (2 * l + 1)) simp only [Int.cast_add, Int.cast_two, Int.cast_mul, Int.cast_one] at hx hy hxy rw [hx, hy, add_zero, zero_div, mul_div_assoc, mul_div_assoc, ← diff --git a/Mathlib/Analysis/SpecificLimits/Basic.lean b/Mathlib/Analysis/SpecificLimits/Basic.lean index 38df94ff449430..3e6f9b38f9ce90 100644 --- a/Mathlib/Analysis/SpecificLimits/Basic.lean +++ b/Mathlib/Analysis/SpecificLimits/Basic.lean @@ -604,7 +604,7 @@ def posSumOfEncodable {ε : ℝ} (hε : 0 < ε) (ι) [Encodable ι] : theorem Set.Countable.exists_pos_hasSum_le {ι : Type*} {s : Set ι} (hs : s.Countable) {ε : ℝ} (hε : 0 < ε) : ∃ ε' : ι → ℝ, (∀ i, 0 < ε' i) ∧ ∃ c, HasSum (fun i : s ↦ ε' i) c ∧ c ≤ ε := by classical - haveI := hs.toEncodable + have := hs.toEncodable rcases posSumOfEncodable hε s with ⟨f, hf0, ⟨c, hfc, hcε⟩⟩ refine ⟨fun i ↦ if h : i ∈ s then f ⟨i, h⟩ else 1, fun i ↦ ?_, ⟨c, ?_, hcε⟩⟩ · conv_rhs => simp diff --git a/Mathlib/CategoryTheory/Abelian/Basic.lean b/Mathlib/CategoryTheory/Abelian/Basic.lean index 40f6ab0cf38964..1b63f75a0ce1fc 100644 --- a/Mathlib/CategoryTheory/Abelian/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/Basic.lean @@ -718,13 +718,13 @@ instance epi_pullback_of_epi_g [Epi g] : Epi (pullback.fst f g) := set_option backward.isDefEq.respectTransparency false in theorem epi_snd_of_isLimit [Epi f] {s : PullbackCone f g} (hs : IsLimit s) : Epi s.snd := by - haveI : Epi (NatTrans.app (limit.cone (cospan f g)).π WalkingCospan.right) := + have : Epi (NatTrans.app (limit.cone (cospan f g)).π WalkingCospan.right) := Abelian.epi_pullback_of_epi_f f g apply epi_of_epi_fac (IsLimit.conePointUniqueUpToIso_hom_comp (limit.isLimit _) hs _) set_option backward.isDefEq.respectTransparency false in theorem epi_fst_of_isLimit [Epi g] {s : PullbackCone f g} (hs : IsLimit s) : Epi s.fst := by - haveI : Epi (NatTrans.app (limit.cone (cospan f g)).π WalkingCospan.left) := + have : Epi (NatTrans.app (limit.cone (cospan f g)).π WalkingCospan.left) := Abelian.epi_pullback_of_epi_g f g apply epi_of_epi_fac (IsLimit.conePointUniqueUpToIso_hom_comp (limit.isLimit _) hs _) @@ -790,14 +790,14 @@ instance mono_pushout_of_mono_g [Mono g] : Mono (pushout.inl f g) := set_option backward.isDefEq.respectTransparency false in theorem mono_inr_of_isColimit [Mono f] {s : PushoutCocone f g} (hs : IsColimit s) : Mono s.inr := by - haveI : Mono (NatTrans.app (colimit.cocone (span f g)).ι WalkingCospan.right) := + have : Mono (NatTrans.app (colimit.cocone (span f g)).ι WalkingCospan.right) := Abelian.mono_pushout_of_mono_f f g apply mono_of_mono_fac (IsColimit.comp_coconePointUniqueUpToIso_hom hs (colimit.isColimit _) _) set_option backward.isDefEq.respectTransparency false in theorem mono_inl_of_isColimit [Mono g] {s : PushoutCocone f g} (hs : IsColimit s) : Mono s.inl := by - haveI : Mono (NatTrans.app (colimit.cocone (span f g)).ι WalkingCospan.left) := + have : Mono (NatTrans.app (colimit.cocone (span f g)).ι WalkingCospan.left) := Abelian.mono_pushout_of_mono_g f g apply mono_of_mono_fac (IsColimit.comp_coconePointUniqueUpToIso_hom hs (colimit.isColimit _) _) diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean index 8e4f0f73a84f83..3de366e5bce4db 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean @@ -143,7 +143,7 @@ lemma HasExactColimitsOfShape.of_codomain_equivalence (J : Type*) [Category* J] [Category* D] (e : C ≌ D) [HasColimitsOfShape J C] [HasExactColimitsOfShape J C] : haveI : HasColimitsOfShape J D := Adjunction.hasColimitsOfShape_of_equivalence e.inverse HasExactColimitsOfShape J D := by - haveI : HasColimitsOfShape J D := Adjunction.hasColimitsOfShape_of_equivalence e.inverse + have : HasColimitsOfShape J D := Adjunction.hasColimitsOfShape_of_equivalence e.inverse refine ⟨⟨fun _ _ _ => ⟨@fun K => ?_⟩⟩⟩ refine preservesLimit_of_natIso K (?_ : e.congrRight.inverse ⋙ colim ⋙ e.functor ≅ colim) apply e.symm.congrRight.fullyFaithfulFunctor.preimageIso @@ -167,7 +167,7 @@ lemma HasExactLimitsOfShape.of_codomain_equivalence (J : Type*) [Category* J] {D [Category* D] (e : C ≌ D) [HasLimitsOfShape J C] [HasExactLimitsOfShape J C] : haveI : HasLimitsOfShape J D := Adjunction.hasLimitsOfShape_of_equivalence e.inverse HasExactLimitsOfShape J D := by - haveI : HasLimitsOfShape J D := Adjunction.hasLimitsOfShape_of_equivalence e.inverse + have : HasLimitsOfShape J D := Adjunction.hasLimitsOfShape_of_equivalence e.inverse refine ⟨⟨fun _ _ _ => ⟨@fun K => ?_⟩⟩⟩ refine preservesColimit_of_natIso K (?_ : e.congrRight.inverse ⋙ lim ⋙ e.functor ≅ lim) apply e.symm.congrRight.fullyFaithfulFunctor.preimageIso @@ -311,10 +311,10 @@ lemma AB5OfSize_of_univLE [HasFilteredColimitsOfSize.{w₂, w₂'} C] [UnivLE.{w [UnivLE.{w', w₂'}] [AB5OfSize.{w₂, w₂'} C] : haveI : HasFilteredColimitsOfSize.{w, w'} C := hasFilteredColimitsOfSize_of_univLE.{w} AB5OfSize.{w, w'} C := by - haveI : HasFilteredColimitsOfSize.{w, w'} C := hasFilteredColimitsOfSize_of_univLE.{w} + have : HasFilteredColimitsOfSize.{w, w'} C := hasFilteredColimitsOfSize_of_univLE.{w} constructor intro J _ _ - haveI := IsFiltered.of_equivalence ((ShrinkHoms.equivalence.{w₂} J).trans <| + have := IsFiltered.of_equivalence ((ShrinkHoms.equivalence.{w₂} J).trans <| Shrink.equivalence.{w₂', w₂} (ShrinkHoms.{w'} J)) exact HasExactColimitsOfShape.of_domain_equivalence _ ((ShrinkHoms.equivalence.{w₂} J).trans <| Shrink.equivalence.{w₂', w₂} (ShrinkHoms.{w'} J)).symm @@ -345,10 +345,10 @@ lemma AB5StarOfSize_of_univLE [HasCofilteredLimitsOfSize.{w₂, w₂'} C] [UnivL [UnivLE.{w', w₂'}] [AB5StarOfSize.{w₂, w₂'} C] : haveI : HasCofilteredLimitsOfSize.{w, w'} C := hasCofilteredLimitsOfSize_of_univLE.{w} AB5StarOfSize.{w, w'} C := by - haveI : HasCofilteredLimitsOfSize.{w, w'} C := hasCofilteredLimitsOfSize_of_univLE.{w} + have : HasCofilteredLimitsOfSize.{w, w'} C := hasCofilteredLimitsOfSize_of_univLE.{w} constructor intro J _ _ - haveI := IsCofiltered.of_equivalence ((ShrinkHoms.equivalence.{w₂} J).trans <| + have := IsCofiltered.of_equivalence ((ShrinkHoms.equivalence.{w₂} J).trans <| Shrink.equivalence.{w₂', w₂} (ShrinkHoms.{w'} J)) exact HasExactLimitsOfShape.of_domain_equivalence _ ((ShrinkHoms.equivalence.{w₂} J).trans <| Shrink.equivalence.{w₂', w₂} (ShrinkHoms.{w'} J)).symm diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/Subobject.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/Subobject.lean index 5962d1650bdae0..44e4b91088e15f 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/Subobject.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/Subobject.lean @@ -65,7 +65,7 @@ the objects in the image of the functor `F`. -/ lemma subobjectMk_of_isColimit_eq_iSup : haveI := mono_of_isColimit_monoOver F hc f hf Subobject.mk f = ⨆ j, Subobject.mk (F.obj j).obj.hom := by - haveI := mono_of_isColimit_monoOver F hc f hf + have := mono_of_isColimit_monoOver F hc f hf apply le_antisymm · rw [le_iSup_iff] intro s H diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Basic.lean b/Mathlib/CategoryTheory/Abelian/Injective/Basic.lean index 446af0e0b77b05..59b2fa5b3b4c23 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Basic.lean @@ -34,7 +34,7 @@ variable {C : Type u} [Category.{v} C] [Abelian C] /-- The preadditive Yoneda functor on `J` preserves homology if `J` is injective. -/ instance preservesHomology_preadditiveYonedaObj_of_injective (J : C) [hJ : Injective J] : (preadditiveYonedaObj J).PreservesHomology := by - letI := (injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' J).mp hJ + let := (injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' J).mp hJ apply Functor.preservesHomology_of_preservesEpis_and_kernels /-- The preadditive Yoneda functor on `J` preserves colimits if `J` is injective. -/ diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean index 80480ea8fccd10..b1353b7fcfb467 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean @@ -58,7 +58,7 @@ variable [HasExt.{w} C] (X : C) (n : ℕ) lemma subsingleton [hX : HasInjectiveDimensionLT X n] (i : ℕ) (hi : n ≤ i) (Y : C) : Subsingleton (Ext.{w} Y X i) := by - letI := HasExt.standard C + let := HasExt.standard C have := hX.subsingleton' i hi exact Ext.chgUniv.{w, max u v}.symm.subsingleton @@ -67,7 +67,7 @@ lemma mk (hX : ∀ (i : ℕ) (_ : n ≤ i) ⦃Y : C⦄, ∀ (e : Ext Y X i), e = HasInjectiveDimensionLT X n where subsingleton' i hi Y := by have : Subsingleton (Ext Y X i) := ⟨fun e₁ e₂ ↦ by simp only [hX i hi]⟩ - letI := HasExt.standard C + let := HasExt.standard C exact Ext.chgUniv.{max u v, w}.symm.subsingleton end HasInjectiveDimensionLT @@ -90,7 +90,7 @@ lemma hasInjectiveDimensionLT_iff [HasExt.{w} C] : variable {X} in lemma Limits.IsZero.hasInjectiveDimensionLT_zero (hX : IsZero X) : HasInjectiveDimensionLT X 0 := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] intro i hi Y e rw [← e.comp_mk₀_id, hX.eq_zero_of_tgt (𝟙 X), Ext.mk₀_zero, Ext.comp_zero] @@ -99,7 +99,7 @@ instance : HasInjectiveDimensionLT (0 : C) 0 := (isZero_zero C).hasInjectiveDimensionLT_zero lemma isZero_of_hasInjectiveDimensionLT_zero [HasInjectiveDimensionLT X 0] : IsZero X := by - letI := HasExt.standard C + let := HasExt.standard C rw [IsZero.iff_id_eq_zero] apply Ext.homEquiv₀.symm.injective simpa only [Ext.homEquiv₀_symm_apply, Ext.mk₀_zero] @@ -111,7 +111,7 @@ lemma hasInjectiveDimensionLT_zero_iff_isZero : HasInjectiveDimensionLT X 0 ↔ lemma hasInjectiveDimensionLT_of_ge (m : ℕ) (h : n ≤ m) [HasInjectiveDimensionLT X n] : HasInjectiveDimensionLT X m := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] intro i hi Y e exact e.eq_zero_of_hasInjectiveDimensionLT n (by lia) @@ -129,7 +129,7 @@ instance [HasInjectiveDimensionLT X n] : inferInstanceAs (HasInjectiveDimensionLT X (n + 1)) instance [Injective X] : HasInjectiveDimensionLT X 1 := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] intro i hi Y e obtain _ | i := i @@ -149,7 +149,7 @@ lemma injective_iff_subsingleton_ext_one [HasExt.{w} C] : variable {X} in lemma injective_iff_hasInjectiveDimensionLT_one : Injective X ↔ HasInjectiveDimensionLT X 1 := by - letI := HasExt.standard C + let := HasExt.standard C exact ⟨fun _ ↦ inferInstance, fun _ ↦ injective_iff_subsingleton_ext_one.2 (HasInjectiveDimensionLT.subsingleton X 1 1 (by rfl))⟩ @@ -161,7 +161,7 @@ end lemma Retract.hasInjectiveDimensionLT {X Y : C} (h : Retract X Y) (n : ℕ) [HasInjectiveDimensionLT Y n] : HasInjectiveDimensionLT X n := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] intro i hi T x rw [← x.comp_mk₀_id, ← h.retract, ← Ext.mk₀_comp_mk₀, ← Ext.comp_assoc_of_second_deg_zero, @@ -186,7 +186,7 @@ include hS lemma hasInjectiveDimensionLT_X₂ (h₁ : HasInjectiveDimensionLT S.X₁ n) (h₃ : HasInjectiveDimensionLT S.X₃ n) : HasInjectiveDimensionLT S.X₂ n := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] intro i hi Y x₂ obtain ⟨x₃, rfl⟩ := Ext.covariant_sequence_exact₂ _ hS x₂ @@ -196,7 +196,7 @@ lemma hasInjectiveDimensionLT_X₂ (h₁ : HasInjectiveDimensionLT S.X₁ n) lemma hasInjectiveDimensionLT_X₁ (h₁ : HasInjectiveDimensionLT S.X₃ n) (h₂ : HasInjectiveDimensionLT S.X₂ (n + 1)) : HasInjectiveDimensionLT S.X₁ (n + 1) := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] rintro (_ | i) hi Y x₃ · simp at hi @@ -207,7 +207,7 @@ lemma hasInjectiveDimensionLT_X₁ (h₁ : HasInjectiveDimensionLT S.X₃ n) lemma hasInjectiveDimensionLT_X₃ (h₂ : HasInjectiveDimensionLT S.X₂ n) (h₃ : HasInjectiveDimensionLT S.X₁ (n + 1)) : HasInjectiveDimensionLT S.X₃ n := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasInjectiveDimensionLT_iff] intro i hi Y x₁ obtain ⟨x₂, rfl⟩ := Ext.covariant_sequence_exact₃ _ hS x₁ (add_comm _ _) diff --git a/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean b/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean index 6363c73b342102..9c61dd118dcb4e 100644 --- a/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean +++ b/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean @@ -116,7 +116,7 @@ instance : Epi (Abelian.factorThruImage f) := _ fun R (g : I ⟶ R) (hpg : p ≫ g = 0) => by -- Since C is abelian, u := ker g ≫ i is the kernel of some morphism h. let u := kernel.ι g ≫ i - haveI hu := normalMonoOfMono u + have hu := normalMonoOfMono u let h := hu.g -- By hypothesis, p factors through the kernel of g via some t. obtain ⟨t, ht⟩ := kernel.lift' g p hpg @@ -137,7 +137,7 @@ instance : Epi (Abelian.factorThruImage f) := -- i factors through u = ker h via some s. obtain ⟨s, hs⟩ := NormalMono.lift' u i hih have hs' : (s ≫ kernel.ι g) ≫ i = 𝟙 I ≫ i := by rw [Category.assoc, hs, Category.id_comp] - haveI : Epi (kernel.ι g) := epi_of_epi_fac ((cancel_mono _).1 hs') + have : Epi (kernel.ι g) := epi_of_epi_fac ((cancel_mono _).1 hs') -- ker g is an epimorphism, but ker g ≫ g = 0 = ker g ≫ 0, so g = 0 as required. exact zero_of_epi_comp _ (kernel.condition g) @@ -152,7 +152,7 @@ instance : Mono (Abelian.factorThruCoimage f) := NormalEpiCategory.mono_of_cancel_zero _ fun R (g : R ⟶ I) (hgi : g ≫ i = 0) => by -- Since C is abelian, u := p ≫ coker g is the cokernel of some morphism h. let u := p ≫ cokernel.π g - haveI hu := normalEpiOfEpi u + have hu := normalEpiOfEpi u let h := hu.g -- By hypothesis, i factors through the cokernel of g via some t. obtain ⟨t, ht⟩ := cokernel.desc' g i hgi @@ -173,7 +173,7 @@ instance : Mono (Abelian.factorThruCoimage f) := -- p factors through u = coker h via some s. obtain ⟨s, hs⟩ := NormalEpi.desc' u p hhp have hs' : p ≫ cokernel.π g ≫ s = p ≫ 𝟙 I := by rw [← Category.assoc, hs, Category.comp_id] - haveI : Mono (cokernel.π g) := mono_of_mono_fac ((cancel_epi _).1 hs') + have : Mono (cokernel.π g) := mono_of_mono_fac ((cancel_epi _).1 hs') -- coker g is a monomorphism, but g ≫ coker g = 0 = 0 ≫ coker g, so g = 0 as required. exact zero_of_comp_mono _ (cokernel.condition g) @@ -232,7 +232,7 @@ instance mono_r {A : C} : Mono (r A) := by have hyy : y = 0 := by erw [← Category.comp_id y, ← Limits.prod.lift_snd (𝟙 A) (𝟙 A), ← Category.assoc, hy, Category.assoc, prod.lift_snd, HasZeroMorphisms.comp_zero] - haveI : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _) + have : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _) apply (cancel_mono (prod.lift (𝟙 A) (0 : A ⟶ A))).1 rw [← hy, hyy, zero_comp, zero_comp] @@ -245,7 +245,7 @@ instance epi_r {A : C} : Epi (r A) := by · intro s apply Limits.prod.hom_ext <;> simp · intro s m h - haveI : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _) + have : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _) apply (cancel_mono (prod.lift (𝟙 A) (0 : A ⟶ A))).1 convert! h apply Limits.prod.hom_ext <;> simp diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Basic.lean b/Mathlib/CategoryTheory/Abelian/Projective/Basic.lean index 39d166dd681b0a..101094ad0d7280 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Basic.lean @@ -33,7 +33,7 @@ variable {C : Type u} [Category.{v} C] [Abelian C] noncomputable instance preservesHomology_preadditiveCoyonedaObj_of_projective (P : C) [hP : Projective P] : (preadditiveCoyonedaObj P).PreservesHomology := by - haveI := (projective_iff_preservesEpimorphisms_preadditiveCoyonedaObj P).mp hP + have := (projective_iff_preservesEpimorphisms_preadditiveCoyonedaObj P).mp hP apply Functor.preservesHomology_of_preservesEpis_and_kernels /-- The preadditive co-Yoneda functor on `P` preserves finite colimits if `P` is projective. -/ diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean index 84d39c8c75290e..8c4f17c08fec88 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean @@ -58,7 +58,7 @@ variable [HasExt.{w} C] (X : C) (n : ℕ) lemma subsingleton [hX : HasProjectiveDimensionLT X n] (i : ℕ) (hi : n ≤ i) (Y : C) : Subsingleton (Ext.{w} X Y i) := by - letI := HasExt.standard C + let := HasExt.standard C have := hX.subsingleton' i hi exact Ext.chgUniv.{w, max u v}.symm.subsingleton @@ -67,7 +67,7 @@ lemma mk (hX : ∀ (i : ℕ) (_ : n ≤ i) ⦃Y : C⦄, ∀ (e : Ext X Y i), e = HasProjectiveDimensionLT X n where subsingleton' i hi Y := by have : Subsingleton (Ext X Y i) := ⟨fun e₁ e₂ ↦ by simp only [hX i hi]⟩ - letI := HasExt.standard C + let := HasExt.standard C exact Ext.chgUniv.{max u v, w}.symm.subsingleton end HasProjectiveDimensionLT @@ -90,7 +90,7 @@ lemma hasProjectiveDimensionLT_iff [HasExt.{w} C] : variable {X} in lemma Limits.IsZero.hasProjectiveDimensionLT_zero (hX : IsZero X) : HasProjectiveDimensionLT X 0 := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] intro i hi Y e rw [← e.mk₀_id_comp, hX.eq_of_src (𝟙 X) 0, Ext.mk₀_zero, Ext.zero_comp] @@ -99,7 +99,7 @@ instance : HasProjectiveDimensionLT (0 : C) 0 := (isZero_zero C).hasProjectiveDimensionLT_zero lemma isZero_of_hasProjectiveDimensionLT_zero [HasProjectiveDimensionLT X 0] : IsZero X := by - letI := HasExt.standard C + let := HasExt.standard C rw [IsZero.iff_id_eq_zero] apply Ext.homEquiv₀.symm.injective simpa only [Ext.homEquiv₀_symm_apply, Ext.mk₀_zero] @@ -111,7 +111,7 @@ lemma hasProjectiveDimensionLT_zero_iff_isZero : HasProjectiveDimensionLT X 0 lemma hasProjectiveDimensionLT_of_ge (m : ℕ) (h : n ≤ m) [HasProjectiveDimensionLT X n] : HasProjectiveDimensionLT X m := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] intro i hi Y e exact e.eq_zero_of_hasProjectiveDimensionLT n (by lia) @@ -129,7 +129,7 @@ instance [HasProjectiveDimensionLT X n] : inferInstanceAs (HasProjectiveDimensionLT X (n + 1)) instance [Projective X] : HasProjectiveDimensionLT X 1 := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] intro i hi Y e obtain _ | i := i @@ -150,7 +150,7 @@ lemma projective_iff_subsingleton_ext_one [HasExt.{w} C] : variable {X} in lemma projective_iff_hasProjectiveDimensionLT_one : Projective X ↔ HasProjectiveDimensionLT X 1 := by - letI := HasExt.standard C + let := HasExt.standard C exact ⟨fun _ ↦ inferInstance, fun _ ↦ projective_iff_subsingleton_ext_one.2 (HasProjectiveDimensionLT.subsingleton X 1 1 (by rfl))⟩ @@ -165,7 +165,7 @@ end lemma Retract.hasProjectiveDimensionLT {X Y : C} (h : Retract X Y) (n : ℕ) [HasProjectiveDimensionLT Y n] : HasProjectiveDimensionLT X n := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] intro i hi T x rw [← x.mk₀_id_comp, ← h.retract, ← Ext.mk₀_comp_mk₀, @@ -192,7 +192,7 @@ include hS lemma hasProjectiveDimensionLT_X₂ (h₁ : HasProjectiveDimensionLT S.X₁ n) (h₃ : HasProjectiveDimensionLT S.X₃ n) : HasProjectiveDimensionLT S.X₂ n := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] intro i hi Y x₂ obtain ⟨x₃, rfl⟩ := Ext.contravariant_sequence_exact₂ hS _ x₂ @@ -202,7 +202,7 @@ lemma hasProjectiveDimensionLT_X₂ (h₁ : HasProjectiveDimensionLT S.X₁ n) lemma hasProjectiveDimensionLT_X₃ (h₁ : HasProjectiveDimensionLT S.X₁ n) (h₂ : HasProjectiveDimensionLT S.X₂ (n + 1)) : HasProjectiveDimensionLT S.X₃ (n + 1) := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] rintro (_ | i) hi Y x₃ · simp at hi @@ -213,7 +213,7 @@ lemma hasProjectiveDimensionLT_X₃ (h₁ : HasProjectiveDimensionLT S.X₁ n) lemma hasProjectiveDimensionLT_X₁ (h₂ : HasProjectiveDimensionLT S.X₂ n) (h₃ : HasProjectiveDimensionLT S.X₃ (n + 1)) : HasProjectiveDimensionLT S.X₁ n := by - letI := HasExt.standard C + let := HasExt.standard C rw [hasProjectiveDimensionLT_iff] intro i hi Y x₁ obtain ⟨x₂, rfl⟩ := Ext.contravariant_sequence_exact₁ hS _ x₁ (add_comm _ _) diff --git a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean index 80c12cda020d5c..69fd41dc0feb2c 100644 --- a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean +++ b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean @@ -382,11 +382,11 @@ theorem exact_of_pseudo_exact (S : ShortComplex C) -- Let's give a name to the second pullback morphism. let j : pullback (kernel.ι (cokernel.π S.f)) (kernel.ι S.g) ⟶ kernel S.g := pullback.snd _ _ -- Since `q` is an epimorphism, in particular this means that `j` is an epimorphism. - haveI pe : Epi j := epi_of_epi_fac hz₂ + have pe : Epi j := epi_of_epi_fac hz₂ -- But it is also a monomorphism, because `kernel.ι (cokernel.π f)` is: A kernel is -- always a monomorphism and the pullback of a monomorphism is a monomorphism. -- But mono + epi = iso, so `j` is an isomorphism. - haveI : IsIso j := isIso_of_mono_of_epi _ + have : IsIso j := isIso_of_mono_of_epi _ -- But then `kernel.ι g` can be expressed using all of the maps of the pullback square, and we -- are done. rw [(Iso.eq_inv_comp (asIso j)).2 pullback.condition.symm] diff --git a/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean b/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean index 6c7b58e5c62803..a2f3aa0b411a9e 100644 --- a/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean +++ b/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean @@ -431,20 +431,20 @@ lemma hasZeroObject : HasZeroObject D := Abelian.hasZeroObject lemma preservesFiniteLimits : PreservesFiniteLimits L := by - letI := abelian L P + let := abelian L P rw [((Functor.preservesFiniteLimits_tfae L).out 3 2 :)] intro _ _ f exact preservesKernel L P f lemma preservesFiniteColimits : PreservesFiniteColimits L := by - letI := abelian L P + let := abelian L P rw [((Functor.preservesFiniteColimits_tfae L).out 3 2 :)] intro _ _ f exact preservesCokernel L P f lemma isIso_map_iff {X Y : C} (f : X ⟶ Y) : IsIso (L.map f) ↔ P.isoModSerre f := by - letI := abelian L P + let := abelian L P rw [isIso_iff_mono_and_epi, mono_map_iff L P, epi_map_iff L P, isoModSerre_iff] lemma inverseImage_isomorphisms : @@ -457,7 +457,7 @@ variable (G : D ⥤ E) set_option backward.isDefEq.respectTransparency false in lemma preservesFiniteLimits_comp_iff : PreservesFiniteLimits (L ⋙ G) ↔ PreservesFiniteLimits G := by - letI := abelian L P + let := abelian L P have := preservesFiniteLimits L P refine ⟨fun _ ↦ ?_, fun _ ↦ comp_preservesFiniteLimits _ _⟩ have := (Localization.functor_additive_iff L P.isoModSerre G).mpr @@ -479,7 +479,7 @@ lemma preservesFiniteLimits_comp_iff : set_option backward.isDefEq.respectTransparency false in lemma preservesFiniteColimits_comp_iff : PreservesFiniteColimits (L ⋙ G) ↔ PreservesFiniteColimits G := by - letI := abelian L P + let := abelian L P have := preservesFiniteColimits L P refine ⟨fun _ ↦ ?_, fun _ ↦ comp_preservesFiniteColimits _ _⟩ have := (Localization.functor_additive_iff L P.isoModSerre G).mpr (by diff --git a/Mathlib/CategoryTheory/Abelian/Transfer.lean b/Mathlib/CategoryTheory/Abelian/Transfer.lean index 099e982bca1390..5bba283bc30c19 100644 --- a/Mathlib/CategoryTheory/Abelian/Transfer.lean +++ b/Mathlib/CategoryTheory/Abelian/Transfer.lean @@ -61,7 +61,7 @@ theorem hasKernels [PreservesFiniteLimits G] (i : F ⋙ G ≅ 𝟭 C) : HasKerne have : i.inv.app X ≫ G.map (F.map f) ≫ i.hom.app Y = f := by simpa using NatIso.naturality_1 i f rw [← this] - haveI : HasKernel (G.map (F.map f) ≫ i.hom.app _) := Limits.hasKernel_comp_mono _ _ + have : HasKernel (G.map (F.map f) ≫ i.hom.app _) := Limits.hasKernel_comp_mono _ _ apply Limits.hasKernel_iso_comp } set_option backward.isDefEq.respectTransparency false in @@ -72,7 +72,7 @@ theorem hasCokernels (i : F ⋙ G ≅ 𝟭 C) (adj : G ⊣ F) : HasCokernels C : have : i.inv.app X ≫ G.map (F.map f) ≫ i.hom.app Y = f := by simpa using NatIso.naturality_1 i f rw [← this] - haveI : HasCokernel (G.map (F.map f) ≫ i.hom.app _) := Limits.hasCokernel_comp_iso _ _ + have : HasCokernel (G.map (F.map f) ≫ i.hom.app _) := Limits.hasCokernel_comp_iso _ _ apply Limits.hasCokernel_epi_comp } end AbelianOfAdjunction diff --git a/Mathlib/CategoryTheory/Adhesive/Basic.lean b/Mathlib/CategoryTheory/Adhesive/Basic.lean index b10b4cf4c2cf85..25aeddb6b46e12 100644 --- a/Mathlib/CategoryTheory/Adhesive/Basic.lean +++ b/Mathlib/CategoryTheory/Adhesive/Basic.lean @@ -480,9 +480,9 @@ theorem adhesive_of_preserves_and_reflects_isomorphism (F : C ⥤ D) [PreservesColimitsOfShape WalkingSpan F] [F.ReflectsIsomorphisms] : Adhesive C := by - haveI : ReflectsLimitsOfShape WalkingCospan F := + have : ReflectsLimitsOfShape WalkingCospan F := reflectsLimitsOfShape_of_reflectsIsomorphisms - haveI : ReflectsColimitsOfShape WalkingSpan F := + have : ReflectsColimitsOfShape WalkingSpan F := reflectsColimitsOfShape_of_reflectsIsomorphisms exact adhesive_of_preserves_and_reflects F diff --git a/Mathlib/CategoryTheory/Adjunction/Reflective.lean b/Mathlib/CategoryTheory/Adjunction/Reflective.lean index b582845ff693cd..71c357b1d7d589 100644 --- a/Mathlib/CategoryTheory/Adjunction/Reflective.lean +++ b/Mathlib/CategoryTheory/Adjunction/Reflective.lean @@ -94,13 +94,13 @@ set_option backward.isDefEq.respectTransparency false in theorem mem_essImage_of_unit_isSplitMono [Reflective i] {A : C} [IsSplitMono ((reflectorAdjunction i).unit.app A)] : i.essImage A := by let η : 𝟭 C ⟶ reflector i ⋙ i := (reflectorAdjunction i).unit - haveI : IsIso (η.app (i.obj ((reflector i).obj A))) := + have : IsIso (η.app (i.obj ((reflector i).obj A))) := Functor.essImage.unit_isIso ((i.obj_mem_essImage _)) have : Epi (η.app A) := by refine @epi_of_epi _ _ _ _ _ (retraction (η.app A)) (η.app A) ?_ rw [show retraction _ ≫ η.app A = _ from η.naturality (retraction (η.app A))] apply epi_comp (η.app (i.obj ((reflector i).obj A))) - haveI := isIso_of_epi_of_isSplitMono (η.app A) + have := isIso_of_epi_of_isSplitMono (η.app A) exact (reflectorAdjunction i).mem_essImage_of_unit_isIso A /-- Composition of reflective functors. -/ @@ -225,13 +225,13 @@ set_option backward.isDefEq.respectTransparency false in lemma mem_essImage_of_counit_isSplitEpi [Coreflective j] {A : D} [IsSplitEpi ((coreflectorAdjunction j).counit.app A)] : j.essImage A := by let ε : coreflector j ⋙ j ⟶ 𝟭 D := (coreflectorAdjunction j).counit - haveI : IsIso (ε.app (j.obj ((coreflector j).obj A))) := + have : IsIso (ε.app (j.obj ((coreflector j).obj A))) := Functor.essImage.counit_isIso ((j.obj_mem_essImage _)) have : Mono (ε.app A) := by refine @mono_of_mono _ _ _ _ _ (ε.app A) (section_ (ε.app A)) ?_ rw [show ε.app A ≫ section_ _ = _ from (ε.naturality (section_ (ε.app A))).symm] apply mono_comp _ (ε.app (j.obj ((coreflector j).obj A))) - haveI := isIso_of_mono_of_isSplitEpi (ε.app A) + have := isIso_of_mono_of_isSplitEpi (ε.app A) exact (coreflectorAdjunction j).mem_essImage_of_counit_isIso A instance Coreflective.comp (F : C ⥤ D) (G : D ⥤ E) [Coreflective F] [Coreflective G] : diff --git a/Mathlib/CategoryTheory/Category/Cat/Limit.lean b/Mathlib/CategoryTheory/Category/Cat/Limit.lean index 85c58e1dcad83f..623bb8e47b117e 100644 --- a/Mathlib/CategoryTheory/Category/Cat/Limit.lean +++ b/Mathlib/CategoryTheory/Category/Cat/Limit.lean @@ -55,11 +55,11 @@ def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : · exact congr_hom (limit.w (F ⋙ Cat.objects) f) Y map_id X := by ext f - letI : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X)) + let : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X)) simp [Functor.congr_hom congr($(F.map_id X).toFunctor) f] map_comp {_ _ Z} f g := by ext h - letI : Category (objects.obj (F.obj Z)) := (inferInstance : Category (F.obj Z)) + let : Category (objects.obj (F.obj Z)) := (inferInstance : Category (F.obj Z)) simp [Functor.congr_hom congr($(F.map_comp f g).toFunctor) h, eqToHom_map] set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/CategoryTheory/CofilteredSystem.lean b/Mathlib/CategoryTheory/CofilteredSystem.lean index 3d73003635fa6c..f6e31d4a2d6347 100644 --- a/Mathlib/CategoryTheory/CofilteredSystem.lean +++ b/Mathlib/CategoryTheory/CofilteredSystem.lean @@ -67,9 +67,9 @@ theorem nonempty_sections_of_finite_cofiltered_system.init {J : Type u} [SmallCa [IsCofilteredOrEmpty J] (F : J ⥤ Type u) [hf : ∀ j, Finite (F.obj j)] [hne : ∀ j, Nonempty (F.obj j)] : F.sections.Nonempty := by let F' : J ⥤ TopCat := F ⋙ TopCat.discrete - haveI : ∀ j, DiscreteTopology (F'.obj j) := fun _ => ⟨rfl⟩ - haveI : ∀ j, Finite (F'.obj j) := hf - haveI : ∀ j, Nonempty (F'.obj j) := hne + have : ∀ j, DiscreteTopology (F'.obj j) := fun _ => ⟨rfl⟩ + have : ∀ j, Finite (F'.obj j) := hf + have : ∀ j, Nonempty (F'.obj j) := hne obtain ⟨⟨u, hu⟩⟩ := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u} F' exact ⟨u, hu⟩ @@ -83,12 +83,12 @@ theorem nonempty_sections_of_finite_cofiltered_system {J : Type u} [Category.{w} let J' : Type max w v u := AsSmall.{max w v} J let down : J' ⥤ J := AsSmall.down let F' : J' ⥤ Type (max u v w) := down ⋙ F ⋙ uliftFunctor.{max u w, v} - haveI : ∀ i, Nonempty (F'.obj i) := fun i => ⟨⟨Classical.arbitrary (F.obj (down.obj i))⟩⟩ - haveI : ∀ i, Finite (F'.obj i) := fun i => Finite.of_equiv (F.obj (down.obj i)) Equiv.ulift.symm + have : ∀ i, Nonempty (F'.obj i) := fun i => ⟨⟨Classical.arbitrary (F.obj (down.obj i))⟩⟩ + have : ∀ i, Finite (F'.obj i) := fun i => Finite.of_equiv (F.obj (down.obj i)) Equiv.ulift.symm -- Step 2: apply the bootstrap theorem cases isEmpty_or_nonempty J · fconstructor <;> apply isEmptyElim - haveI : IsCofiltered J := ⟨⟩ + have : IsCofiltered J := ⟨⟩ obtain ⟨u, hu⟩ := nonempty_sections_of_finite_cofiltered_system.init F' -- Step 3: interpret the results use fun j => (u ⟨j⟩).down @@ -311,7 +311,7 @@ set_option backward.defeqAttrib.useBackward true in theorem eval_section_surjective_of_surjective (i : J) : (fun s : F.sections => s.val i).Surjective := fun x => by let s : Set (F.obj i) := {x} - haveI := F.toPreimages_nonempty_of_surjective s Fsur (singleton_nonempty x) + have := F.toPreimages_nonempty_of_surjective s Fsur (singleton_nonempty x) obtain ⟨sec, h⟩ := nonempty_sections_of_finite_cofiltered_system (F.toPreimages s) refine ⟨⟨fun j => (sec j).val, fun jk => by simpa [Subtype.ext_iff] using! h jk⟩, ?_⟩ · have := (sec i).prop @@ -321,8 +321,8 @@ theorem eval_section_surjective_of_surjective (i : J) : theorem eventually_injective [Nonempty J] [Finite F.sections] : ∃ j, ∀ (i) (f : i ⟶ j), Function.Injective (F.map f) := by - haveI : ∀ j, Fintype (F.obj j) := fun j => Fintype.ofFinite (F.obj j) - haveI : Fintype F.sections := Fintype.ofFinite F.sections + have : ∀ j, Fintype (F.obj j) := fun j => Fintype.ofFinite (F.obj j) + have : Fintype F.sections := Fintype.ofFinite F.sections have card_le : ∀ j, Fintype.card (F.obj j) ≤ Fintype.card F.sections := fun j => Fintype.card_le_of_surjective _ (F.eval_section_surjective_of_surjective Fsur j) let fn j := Fintype.card F.sections - Fintype.card (F.obj j) diff --git a/Mathlib/CategoryTheory/Comma/Final.lean b/Mathlib/CategoryTheory/Comma/Final.lean index 04608f5d124a3e..c1c46db052aa44 100644 --- a/Mathlib/CategoryTheory/Comma/Final.lean +++ b/Mathlib/CategoryTheory/Comma/Final.lean @@ -158,7 +158,7 @@ lemma map_final {A : Type u₁} [Category.{v₁} A] {B : Type u₂} [Category.{v {G : B ⥤ B'} {H : T ⥤ T'} (iL : F ⋙ L' ≅ L ⋙ H) (iR : G ⋙ R' ≅ R ⋙ H) [IsFiltered B] [R.Final] [R'.Final] [F.Final] [G.Final] : (Comma.map iL.hom iR.inv).Final := ⟨fun ⟨i₂, j₂, u₂⟩ => by - haveI := final_of_natIso iR + have := final_of_natIso iR rw [isConnected_iff_of_equivalence (StructuredArrow.commaMapEquivalence iL.hom iR.inv _)] have : StructuredArrow.map₂ u₂ iR.hom ≅ StructuredArrow.post j₂ G R' ⋙ StructuredArrow.map₂ (G := 𝟭 _) (F := 𝟭 _) (R' := R ⋙ H) u₂ iR.hom ⋙ @@ -171,7 +171,7 @@ lemma map_final {A : Type u₁} [Category.{v₁} A] {B : Type u₂} [Category.{v isoWhiskerLeft _ ((StructuredArrow.map₂CompMap₂Iso _ _ _ _).symm ≪≫ isoWhiskerLeft _ (StructuredArrow.preIsoMap₂ _ _ _).symm) ≪≫ isoWhiskerRight (StructuredArrow.postIsoMap₂ j₂ G R').symm _ - haveI := final_of_natIso this.symm + have := final_of_natIso this.symm rw [IsIso.Iso.inv_inv] infer_instance⟩ diff --git a/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean b/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean index c21e8beff8e233..f847a89d7e6491 100644 --- a/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean +++ b/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean @@ -34,8 +34,8 @@ where `forget C` reflects isomorphisms, itself reflects isomorphisms. -/ instance reflectsIsomorphisms_forget₂ [HasForget₂ C D] [(forget C).ReflectsIsomorphisms] : (forget₂ C D).ReflectsIsomorphisms := { reflects := fun X Y f {i} => by - haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _ - haveI : IsIso ((forget C).map f) := by + have i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _ + have : IsIso ((forget C).map f) := by rwa [← @HasForget₂.forget_comp C _ _ _ _ _ D _ _ _ _ _] apply isIso_of_reflects_iso f (forget C) } diff --git a/Mathlib/CategoryTheory/Extensive.lean b/Mathlib/CategoryTheory/Extensive.lean index 3f5988a12aa152..7b6f27b595f43c 100644 --- a/Mathlib/CategoryTheory/Extensive.lean +++ b/Mathlib/CategoryTheory/Extensive.lean @@ -420,8 +420,8 @@ theorem finitaryExtensive_of_preserves_and_reflects_isomorphism (F : C ⥤ D) [F [HasFiniteCoproducts C] [HasPullbacks C] [PreservesLimitsOfShape WalkingCospan F] [PreservesColimitsOfShape (Discrete WalkingPair) F] [F.ReflectsIsomorphisms] : FinitaryExtensive C := by - haveI : ReflectsLimitsOfShape WalkingCospan F := reflectsLimitsOfShape_of_reflectsIsomorphisms - haveI : ReflectsColimitsOfShape (Discrete WalkingPair) F := + have : ReflectsLimitsOfShape WalkingCospan F := reflectsLimitsOfShape_of_reflectsIsomorphisms + have : ReflectsColimitsOfShape (Discrete WalkingPair) F := reflectsColimitsOfShape_of_reflectsIsomorphisms exact finitaryExtensive_of_preserves_and_reflects F diff --git a/Mathlib/CategoryTheory/FiberedCategory/Cartesian.lean b/Mathlib/CategoryTheory/FiberedCategory/Cartesian.lean index 49c62e0554ec61..64a7f20c18169f 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/Cartesian.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/Cartesian.lean @@ -390,7 +390,7 @@ instance domainUniqueUpToIso_inv_isHomLift (h : f' = g.hom ≫ f) (φ : a ⟶ b) instance domainUniqueUpToIso_hom_isHomLift (h : f' = g.hom ≫ f) (φ : a ⟶ b) (φ' : a' ⟶ b) [IsStronglyCartesian p f φ] [IsStronglyCartesian p f' φ'] : IsHomLift p g.inv (domainIsoOfBaseIso p h φ φ').inv := by - haveI : p.IsHomLift ((fun x ↦ g.inv ≫ x) (g.hom ≫ f)) φ := by + have : p.IsHomLift ((fun x ↦ g.inv ≫ x) (g.hom ≫ f)) φ := by simpa using IsCartesian.toIsHomLift simpa using IsStronglyCartesian.map_isHomLift p f' φ' (congrArg (g.inv ≫ ·) h.symm) φ diff --git a/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean b/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean index c972b51e66f4c0..eca167cd40f154 100644 --- a/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean +++ b/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean @@ -69,9 +69,9 @@ theorem isFiltered_of_isFiltered_costructuredArrow (L : A ⥤ T) (R : B ⥤ T) ((sB.inverse ⋙ R ⋙ sT.functor).obj ⟨b⟩) ≌ CostructuredArrow L (R.obj b) := fun b => (CostructuredArrow.pre sA.inverse (L ⋙ sT.functor) _).asEquivalence.trans (CostructuredArrow.post L sT.functor _).asEquivalence.symm - haveI : ∀ b, IsFiltered (CostructuredArrow _ ((sB.inverse ⋙ R ⋙ sT.functor).obj b)) := + have : ∀ b, IsFiltered (CostructuredArrow _ ((sB.inverse ⋙ R ⋙ sT.functor).obj b)) := fun b => IsFiltered.of_equivalence (sC b.1).symm - haveI := isFiltered_of_isFiltered_costructuredArrow_small + have := isFiltered_of_isFiltered_costructuredArrow_small (sA.inverse ⋙ L ⋙ sT.functor) (sB.inverse ⋙ R ⋙ sT.functor) exact IsFiltered.of_equivalence sA.symm diff --git a/Mathlib/CategoryTheory/Filtered/Final.lean b/Mathlib/CategoryTheory/Filtered/Final.lean index 3a35baf057910e..506f1e8bc02c20 100644 --- a/Mathlib/CategoryTheory/Filtered/Final.lean +++ b/Mathlib/CategoryTheory/Filtered/Final.lean @@ -314,7 +314,7 @@ theorem Functor.initial_iff_isCofiltered_costructuredArrow [IsCofilteredOrEmpty /-- If `C` is filtered, then the structured arrow category on the diagonal functor `C ⥤ C × C` is filtered as well. -/ instance [IsFilteredOrEmpty C] (X : C × C) : IsFiltered (StructuredArrow X (diag C)) := by - haveI : ∀ Y, IsFiltered (StructuredArrow Y (Under.forget X.1)) := by + have : ∀ Y, IsFiltered (StructuredArrow Y (Under.forget X.1)) := by rw [← final_iff_isFiltered_structuredArrow (Under.forget X.1)] infer_instance apply IsFiltered.of_equivalence (StructuredArrow.ofDiagEquivalence X).symm @@ -334,7 +334,7 @@ theorem IsFiltered.isSifted [IsFiltered C] : IsSifted C where /-- If `C` is cofiltered, then the costructured arrow category on the diagonal functor `C ⥤ C × C` is cofiltered as well. -/ instance [IsCofilteredOrEmpty C] (X : C × C) : IsCofiltered (CostructuredArrow (diag C) X) := by - haveI : ∀ Y, IsCofiltered (CostructuredArrow (Over.forget X.1) Y) := by + have : ∀ Y, IsCofiltered (CostructuredArrow (Over.forget X.1) Y) := by rw [← initial_iff_isCofiltered_costructuredArrow (Over.forget X.1)] infer_instance apply IsCofiltered.of_equivalence (CostructuredArrow.ofDiagEquivalence X).symm @@ -385,7 +385,7 @@ instance StructuredArrow.final_map₂_id [IsFiltered C] {E : Type u₃} [Categor {T : C ⥤ D} [T.Final] {S : D ⥤ E} [S.Final] {T' : C ⥤ E} {d : D} {e : E} (u : e ⟶ S.obj d) (α : T ⋙ S ⟶ T') [IsIso α] : Final (map₂ (F := 𝟭 _) u α) := by - haveI : IsFiltered (StructuredArrow e (T ⋙ S)) := + have : IsFiltered (StructuredArrow e (T ⋙ S)) := (T ⋙ S).final_iff_isFiltered_structuredArrow.mp inferInstance e apply final_of_natIso (map₂IsoPreEquivalenceInverseCompProj d e u α).symm @@ -393,7 +393,7 @@ set_option backward.isDefEq.respectTransparency false in /-- `StructuredArrow.map` is final if the functor `T` is final and its domain is filtered. -/ instance StructuredArrow.final_map [IsFiltered C] {S S' : D} (f : S ⟶ S') (T : C ⥤ D) [T.Final] : Final (map (T := T) f) := by - haveI := NatIso.isIso_of_isIso_app (𝟙 T) + have := NatIso.isIso_of_isIso_app (𝟙 T) have : (map₂ (F := 𝟭 C) (G := 𝟭 D) f (𝟙 T)).Final := by apply StructuredArrow.final_map₂_id (S := 𝟭 D) (T := T) (T' := T) f (𝟙 T) apply final_of_natIso (mapIsoMap₂ f).symm diff --git a/Mathlib/CategoryTheory/Functor/Flat.lean b/Mathlib/CategoryTheory/Functor/Flat.lean index 665c09322a853a..99352559888677 100644 --- a/Mathlib/CategoryTheory/Functor/Flat.lean +++ b/Mathlib/CategoryTheory/Functor/Flat.lean @@ -332,7 +332,7 @@ noncomputable instance lan_preservesFiniteLimits_of_flat (F : C ⥤ D) [Represen intro J _ _ apply preservesLimitsOfShape_of_evaluation (F.op.lan : (Cᵒᵖ ⥤ E) ⥤ Dᵒᵖ ⥤ E) J intro K - haveI : IsFiltered (CostructuredArrow F.op K) := + have : IsFiltered (CostructuredArrow F.op K) := IsFiltered.of_equivalence (structuredArrowOpEquivalence F (unop K)) exact preservesLimitsOfShape_of_natIso (lanEvaluationIsoColim _ _ _).symm @@ -344,14 +344,14 @@ variable [HasFiniteLimits C] instance lan_preservesFiniteLimits_of_preservesFiniteLimits (F : C ⥤ D) [PreservesFiniteLimits F] : PreservesFiniteLimits (F.op.lan : _ ⥤ Dᵒᵖ ⥤ E) := by - haveI := flat_of_preservesFiniteLimits F + have := flat_of_preservesFiniteLimits F infer_instance theorem flat_iff_lan_flat (F : C ⥤ D) : RepresentablyFlat F ↔ RepresentablyFlat (F.op.lan : _ ⥤ Dᵒᵖ ⥤ Type u₁) := ⟨fun _ => inferInstance, fun H => by - haveI := preservesFiniteLimits_of_flat (F.op.lan : _ ⥤ Dᵒᵖ ⥤ Type u₁) - haveI : PreservesFiniteLimits F := by + have := preservesFiniteLimits_of_flat (F.op.lan : _ ⥤ Dᵒᵖ ⥤ Type u₁) + have : PreservesFiniteLimits F := by apply preservesFiniteLimits_of_preservesFiniteLimitsOfSize.{u₁} intros; apply preservesLimit_of_lan_preservesLimit apply flat_of_preservesFiniteLimits⟩ diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean b/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean index 8f258c7b23fce8..ddda48b185e5df 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean @@ -647,8 +647,8 @@ def LeftExtension.isUniversalPrecomp₂ refine ⟨⟨StructuredArrow.homMk (hb.desc u) <| by ext x - haveI hb_fac_app := congr_app (hb.fac u) (L.obj x) - haveI hα_fac_app := + have hb_fac_app := congr_app (hb.fac u) (L.obj x) + have hα_fac_app := congr_app (hα.fac <| LeftExtension.mk _ <| y.hom ≫ (L.associator L' y.right).hom) x dsimp at hα_fac_app hb_fac_app diff --git a/Mathlib/CategoryTheory/Functor/ReflectsIso/Balanced.lean b/Mathlib/CategoryTheory/Functor/ReflectsIso/Balanced.lean index 958801256b9cb0..1f2f7530845fc1 100644 --- a/Mathlib/CategoryTheory/Functor/ReflectsIso/Balanced.lean +++ b/Mathlib/CategoryTheory/Functor/ReflectsIso/Balanced.lean @@ -32,8 +32,8 @@ instance (priority := 100) reflectsIsomorphisms_of_reflectsMonomorphisms_of_refl [Balanced C] (F : C ⥤ D) [ReflectsMonomorphisms F] [ReflectsEpimorphisms F] : F.ReflectsIsomorphisms where reflects f hf := by - haveI : Epi f := epi_of_epi_map F inferInstance - haveI : Mono f := mono_of_mono_map F inferInstance + have : Epi f := epi_of_epi_map F inferInstance + have : Mono f := mono_of_mono_map F inferInstance exact isIso_of_mono_of_epi f lemma Functor.balanced_of_preserves (F : C ⥤ D) diff --git a/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean b/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean index 9c09661cfabb0d..b317846095c902 100644 --- a/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean @@ -63,7 +63,7 @@ instance reflectsIsomorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [F.ReflectsIsomorphisms] [G.ReflectsIsomorphisms] : (F ⋙ G).ReflectsIsomorphisms := ⟨fun f (hf : IsIso (G.map _)) => by - haveI := isIso_of_reflects_iso (F.map f) G + have := isIso_of_reflects_iso (F.map f) G exact isIso_of_reflects_iso f F⟩ set_option backward.defeqAttrib.useBackward true in diff --git a/Mathlib/CategoryTheory/Galois/Basic.lean b/Mathlib/CategoryTheory/Galois/Basic.lean index dc171180037365..a09a71f7f31d2c 100644 --- a/Mathlib/CategoryTheory/Galois/Basic.lean +++ b/Mathlib/CategoryTheory/Galois/Basic.lean @@ -156,22 +156,22 @@ instance {G : Type*} [Group G] [Finite G] : /-- Fiber functors reflect monomorphisms. -/ instance : ReflectsMonomorphisms F := ReflectsMonomorphisms.mk <| by intro X Y f _ - haveI : IsIso (pullback.fst (F.map f) (F.map f)) := + have : IsIso (pullback.fst (F.map f) (F.map f)) := isIso_fst_of_mono (F.map f) - haveI : IsIso (F.map (pullback.fst f f)) := by + have : IsIso (F.map (pullback.fst f f)) := by rw [← PreservesPullback.iso_hom_fst] exact IsIso.comp_isIso - haveI : IsIso (pullback.fst f f) := isIso_of_reflects_iso (pullback.fst _ _) F + have : IsIso (pullback.fst f f) := isIso_of_reflects_iso (pullback.fst _ _) F exact (pullback.diagonal_isKernelPair f).mono_of_isIso_fst /-- Fiber functors are faithful. -/ instance : F.Faithful where map_injective {X Y} f g h := by - haveI : IsIso (equalizer.ι (F.map f) (F.map g)) := equalizer.ι_of_eq h - haveI : IsIso (F.map (equalizer.ι f g)) := by + have : IsIso (equalizer.ι (F.map f) (F.map g)) := equalizer.ι_of_eq h + have : IsIso (F.map (equalizer.ι f g)) := by rw [← equalizerComparison_comp_π f g F] exact IsIso.comp_isIso - haveI : IsIso (equalizer.ι f g) := isIso_of_reflects_iso _ F + have : IsIso (equalizer.ι f g) := isIso_of_reflects_iso _ F exact eq_of_epi_equalizer section @@ -220,12 +220,6 @@ variable [PreGaloisCategory C] [FiberFunctor F] /-- An object is initial if and only if its fiber is empty. -/ lemma initial_iff_fiber_empty (X : C) : Nonempty (IsInitial X) ↔ IsEmpty (F.obj X) := by rw [(IsInitial.isInitialIffObj F X).nonempty_congr] - haveI : PreservesFiniteColimits (forget FintypeCat) := by - change PreservesFiniteColimits FintypeCat.incl - infer_instance - haveI : ReflectsColimit (Functor.empty.{0} _) (forget FintypeCat) := by - change ReflectsColimit (Functor.empty.{0} _) FintypeCat.incl - infer_instance exact Concrete.initial_iff_empty_of_preserves_of_reflects (F.obj X) /-- An object is not initial if and only if its fiber is nonempty. -/ @@ -314,7 +308,7 @@ lemma fiberBinaryProductEquiv_symm_snd_apply {X Y : C} (x : F.obj X) (y : F.obj lemma evaluation_injective_of_isConnected (A X : C) [IsConnected A] (a : F.obj A) : Function.Injective (fun (f : A ⟶ X) ↦ F.map f a) := by intro f g (h : F.map f a = F.map g a) - haveI : IsIso (equalizer.ι f g) := by + have : IsIso (equalizer.ι f g) := by apply IsConnected.noTrivialComponent _ (equalizer.ι f g) exact not_initial_of_inhabited F ((fiberEqualizerEquiv F f g).symm ⟨a, h⟩) exact eq_of_epi_equalizer diff --git a/Mathlib/CategoryTheory/Galois/Equivalence.lean b/Mathlib/CategoryTheory/Galois/Equivalence.lean index 67a3796c5440fb..e9629f623eefa8 100644 --- a/Mathlib/CategoryTheory/Galois/Equivalence.lean +++ b/Mathlib/CategoryTheory/Galois/Equivalence.lean @@ -54,7 +54,7 @@ instance {F : C ⥤ FintypeCat.{u₁}} [FiberFunctor F] : (functorToContAction F instance : (functorToContAction F).EssSurj := by let F' : C ⥤ FintypeCat.{u₁} := F ⋙ FintypeCat.uSwitch.{w, u₁} - letI : FiberFunctor F' := FiberFunctor.comp_right _ + let : FiberFunctor F' := FiberFunctor.comp_right _ have : (functorToContAction F').EssSurj := inferInstance let f : Aut F ≃ₜ* Aut F' := (autEquivAutWhiskerRight F (FintypeCat.uSwitchEquivalence.{w, u₁}).fullyFaithfulFunctor) diff --git a/Mathlib/CategoryTheory/Galois/EssSurj.lean b/Mathlib/CategoryTheory/Galois/EssSurj.lean index 8ee8df169abd5d..70857ca5969333 100644 --- a/Mathlib/CategoryTheory/Galois/EssSurj.lean +++ b/Mathlib/CategoryTheory/Galois/EssSurj.lean @@ -75,8 +75,8 @@ lemma has_decomp_quotients (X : Action FintypeCat G) ∃ (ι : Type) (_ : Finite ι) (f : ι → OpenSubgroup (G)), Nonempty ((∐ fun i ↦ G ⧸ₐ (f i).toSubgroup) ≅ X) := by obtain ⟨ι, hf, f, u, hc⟩ := has_decomp_connected_components' X - letI (i : ι) : TopologicalSpace (f i).V := ⊥ - haveI (i : ι) : DiscreteTopology (f i).V := ⟨rfl⟩ + let (i : ι) : TopologicalSpace (f i).V := ⊥ + have (i : ι) : DiscreteTopology (f i).V := ⟨rfl⟩ have (i : ι) : ContinuousSMul G (f i).V := ContinuousSMul.mk <| by let r : f i ⟶ X := Sigma.ι f i ≫ u.hom let r'' (p : G × (f i).V) : G × X.V := (p.1, r.hom p.2) @@ -227,8 +227,8 @@ set_option backward.isDefEq.respectTransparency false in lemma exists_lift_of_quotient_openSubgroup (V : OpenSubgroup (Aut F)) : ∃ (X : C), Nonempty ((functorToAction F).obj X ≅ Aut F ⧸ₐ V.toSubgroup) := by obtain ⟨I, hf, hc, hi⟩ := exists_set_ker_evaluation_subset_of_isOpen F (one_mem V) V.isOpen' - haveI (X : I) : IsConnected X.val := hc X X.property - haveI (X : I) : Nonempty (F.obj X.val) := nonempty_fiber_of_isConnected F X + have (X : I) : IsConnected X.val := hc X X.property + have (X : I) : Nonempty (F.obj X.val) := nonempty_fiber_of_isConnected F X have hn : Nonempty (F.obj <| (∏ᶜ fun X : I => X)) := nonempty_fiber_pi_of_nonempty_of_finite F _ obtain ⟨A, f, hgal⟩ := exists_hom_from_galois_of_fiber_nonempty F (∏ᶜ fun X : I => X) hn obtain ⟨a⟩ := nonempty_fiber_of_isConnected F A diff --git a/Mathlib/CategoryTheory/Galois/Examples.lean b/Mathlib/CategoryTheory/Galois/Examples.lean index 7b3b1937554876..63002611a87534 100644 --- a/Mathlib/CategoryTheory/Galois/Examples.lean +++ b/Mathlib/CategoryTheory/Galois/Examples.lean @@ -113,7 +113,7 @@ theorem Action.pretransitive_of_isConnected (X : Action FintypeCat G) connectedness, the orbit equals `X.V`. -/ let T : Set X.V := MulAction.orbit G x have : Fintype T := Fintype.ofFinite T - letI : MulAction G (FintypeCat.of T) := inferInstanceAs <| MulAction G + let : MulAction G (FintypeCat.of T) := inferInstanceAs <| MulAction G ↑(MulAction.orbit G x) let T' : Action FintypeCat G := Action.FintypeCat.ofMulAction G (FintypeCat.of T) let i : T' ⟶ X := ⟨FintypeCat.homMk Subtype.val, fun _ ↦ rfl⟩ @@ -140,9 +140,9 @@ theorem Action.isConnected_of_transitive (X : FintypeCat) [MulAction G X] obtain ⟨(y : Y.V)⟩ := (not_initial_iff_fiber_nonempty (Action.forget _ _) Y).mp hni have : IsIso i.hom := by refine (ConcreteCategory.isIso_iff_bijective i.hom).mpr ⟨?_, fun x' ↦ ?_⟩ - · haveI : Mono i.hom := map_mono (forget₂ _ _) i + · have : Mono i.hom := map_mono (forget₂ _ _) i exact ConcreteCategory.injective_of_mono_of_preservesPullback i.hom - · letI x : X := i.hom y + · let x : X := i.hom y obtain ⟨σ, hσ⟩ := MulAction.exists_smul_eq G x x' use σ • y change (Y.ρ σ ≫ i.hom) y = x' diff --git a/Mathlib/CategoryTheory/Galois/Prorepresentability.lean b/Mathlib/CategoryTheory/Galois/Prorepresentability.lean index d33c328d858baa..753fe0ed691300 100644 --- a/Mathlib/CategoryTheory/Galois/Prorepresentability.lean +++ b/Mathlib/CategoryTheory/Galois/Prorepresentability.lean @@ -452,7 +452,7 @@ instance FiberFunctor.isPretransitive_of_isConnected (X : C) [IsConnected X] : MulAction.IsPretransitive (Aut F) (F.obj X) where exists_smul_eq x y := by let F' : C ⥤ FintypeCat.{u₂} := F ⋙ FintypeCat.uSwitch.{w, u₂} - letI : FiberFunctor F' := FiberFunctor.comp_right _ + let : FiberFunctor F' := FiberFunctor.comp_right _ let e (Y : C) : F'.obj Y ≃ F.obj Y := (F.obj Y).uSwitchEquiv set x' : F'.obj X := (e X).symm x with hx' set y' : F'.obj X := (e X).symm y with hy' diff --git a/Mathlib/CategoryTheory/Galois/Topology.lean b/Mathlib/CategoryTheory/Galois/Topology.lean index 08d22dfd2817d5..8cea1acfba7216 100644 --- a/Mathlib/CategoryTheory/Galois/Topology.lean +++ b/Mathlib/CategoryTheory/Galois/Topology.lean @@ -209,8 +209,8 @@ lemma nhds_one_has_basis_stabilizers : (nhds (1 : Aut F)).HasBasis (fun _ ↦ Tr intro t (ht : t.hom.app A a = a) apply hU apply hmem - haveI (X : I) : IsConnected X.val := hc X.val X.property - haveI (X : I) : Nonempty (F.obj X.val) := nonempty_fiber_of_isConnected F X + have (X : I) : IsConnected X.val := hc X.val X.property + have (X : I) : Nonempty (F.obj X.val) := nonempty_fiber_of_isConnected F X intro X ext x simp only [FintypeCat.id_apply] diff --git a/Mathlib/CategoryTheory/Generator/Abelian.lean b/Mathlib/CategoryTheory/Generator/Abelian.lean index b67595ab22abd7..97ece904d2a5c8 100644 --- a/Mathlib/CategoryTheory/Generator/Abelian.lean +++ b/Mathlib/CategoryTheory/Generator/Abelian.lean @@ -36,8 +36,8 @@ variable {C : Type u} [Category.{v} C] [Abelian C] theorem has_injective_coseparator [HasLimits C] [EnoughInjectives C] (G : C) (hG : IsSeparator G) : ∃ G : C, Injective G ∧ IsCoseparator G := by - haveI : WellPowered.{v} C := wellPowered_of_isDetector G hG.isDetector - haveI : HasProductsOfShape (Subobject (op G)) C := hasProductsOfShape_of_small.{v} _ _ + have : WellPowered.{v} C := wellPowered_of_isDetector G hG.isDetector + have : HasProductsOfShape (Subobject (op G)) C := hasProductsOfShape_of_small.{v} _ _ let T : C := Injective.under (piObj fun P : Subobject (op G) => unop P) refine ⟨T, inferInstance, (Preadditive.isCoseparator_iff _).2 fun X Y f hf => ?_⟩ refine (Preadditive.isSeparator_iff _).1 hG _ fun h => ?_ diff --git a/Mathlib/CategoryTheory/Generator/Basic.lean b/Mathlib/CategoryTheory/Generator/Basic.lean index 64fa142dd8cc16..734040759580d7 100644 --- a/Mathlib/CategoryTheory/Generator/Basic.lean +++ b/Mathlib/CategoryTheory/Generator/Basic.lean @@ -432,9 +432,9 @@ theorem hasInitial_of_isCoseparating [LocallySmall.{w} C] [WellPowered.{w} C] [HasLimitsOfSize.{w, w} C] {P : ObjectProperty C} [ObjectProperty.Small.{w} P] (hP : P.IsCoseparating) : HasInitial C := by have := hasFiniteLimits_of_hasLimitsOfSize C - haveI := hasProductsOfShape_of_small C (Subtype P) - haveI := fun A => hasProductsOfShape_of_small.{w} C (StructuredArrow A P.ι) - letI := completeLatticeOfCompleteSemilatticeInf (Subobject (piObj (Subtype.val : Subtype P → C))) + have := hasProductsOfShape_of_small C (Subtype P) + have := fun A => hasProductsOfShape_of_small.{w} C (StructuredArrow A P.ι) + let := completeLatticeOfCompleteSemilatticeInf (Subobject (piObj (Subtype.val : Subtype P → C))) suffices ∀ A : C, Unique (((⊥ : Subobject (piObj (Subtype.val : Subtype P → C))) : C) ⟶ A) by exact hasInitial_of_unique ((⊥ : Subobject (piObj (Subtype.val : Subtype P → C))) : C) have := hP.mono_productTo @@ -459,7 +459,7 @@ theorem hasInitial_of_isCoseparating [LocallySmall.{w} C] [WellPowered.{w} C] theorem hasTerminal_of_isSeparating [LocallySmall.{w} Cᵒᵖ] [WellPowered.{w} Cᵒᵖ] [HasColimitsOfSize.{w, w} C] {P : ObjectProperty C} [ObjectProperty.Small.{w} P] (hP : P.IsSeparating) : HasTerminal C := by - haveI : HasInitial Cᵒᵖ := hasInitial_of_isCoseparating (P.isCoseparating_op_iff.2 hP) + have : HasInitial Cᵒᵖ := hasInitial_of_isCoseparating (P.isCoseparating_op_iff.2 hP) exact hasTerminal_of_hasInitial_op section WellPowered @@ -663,7 +663,7 @@ theorem isSeparator_iff_epi (G : C) [∀ A : C, HasCoproduct fun _ : G ⟶ A => rw [isSeparator_def] refine ⟨fun h A => ⟨fun u v huv => h _ _ fun i => ?_⟩, fun h X Y f g hh => ?_⟩ · simpa using Sigma.ι _ i ≫= huv - · haveI := h X + · have := h X refine (cancel_epi (Sigma.desc fun f : G ⟶ X => f)).1 (colimit.hom_ext fun j => ?_) simpa using hh j.as @@ -673,7 +673,7 @@ theorem isCoseparator_iff_mono (G : C) [∀ A : C, HasProduct fun _ : A ⟶ G => rw [isCoseparator_def] refine ⟨fun h A => ⟨fun u v huv => h _ _ fun i => ?_⟩, fun h X Y f g hh => ?_⟩ · simpa using huv =≫ Pi.π _ i - · haveI := h Y + · have := h Y refine (cancel_mono (Pi.lift fun f : Y ⟶ G => f)).1 (limit.hom_ext fun j => ?_) simpa using hh j.as diff --git a/Mathlib/CategoryTheory/Groupoid/Basic.lean b/Mathlib/CategoryTheory/Groupoid/Basic.lean index 40e3094a1d7a21..4f91ccc3a22d6b 100644 --- a/Mathlib/CategoryTheory/Groupoid/Basic.lean +++ b/Mathlib/CategoryTheory/Groupoid/Basic.lean @@ -24,7 +24,7 @@ section Thin theorem isThin_iff : Quiver.IsThin C ↔ ∀ c : C, Subsingleton (c ⟶ c) := by refine ⟨fun h c => h c c, fun h c d => Subsingleton.intro fun f g => ?_⟩ - haveI := h d + have := h d calc f = f ≫ inv g ≫ g := by simp only [inv_eq_inv, IsIso.inv_hom_id, Category.comp_id] _ = f ≫ inv f ≫ g := by congr 1 diff --git a/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean b/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean index 220d795a454a37..f4b2708127ba9e 100644 --- a/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean +++ b/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean @@ -153,9 +153,9 @@ lemma vComp_iff_of_equivalences (eL : C₂ ≌ C₃) (eR : D₂ ≌ D₃) (w ≫ᵥ w'.hom).GuitartExact ↔ w.GuitartExact := by constructor · intro hww' - letI : CatCommSq H₂ eL.functor eR.functor H₃ := ⟨w'⟩ + let : CatCommSq H₂ eL.functor eR.functor H₃ := ⟨w'⟩ have hw' : CatCommSq.iso H₂ eL.functor eR.functor H₃ = w' := rfl - letI : CatCommSq H₃ eL.inverse eR.inverse H₂ := CatCommSq.vInvEquiv _ _ _ _ inferInstance + let : CatCommSq H₃ eL.inverse eR.inverse H₂ := CatCommSq.vInvEquiv _ _ _ _ inferInstance let w'' := CatCommSq.iso H₃ eL.inverse eR.inverse H₂ let α : (L₁ ⋙ eL.functor) ⋙ eL.inverse ≅ L₁ := Functor.associator _ _ _ ≪≫ Functor.isoWhiskerLeft L₁ eL.unitIso.symm ≪≫ L₁.rightUnitor diff --git a/Mathlib/CategoryTheory/Idempotents/Basic.lean b/Mathlib/CategoryTheory/Idempotents/Basic.lean index 1c4be74659cbe9..634afd5e7ed2d0 100644 --- a/Mathlib/CategoryTheory/Idempotents/Basic.lean +++ b/Mathlib/CategoryTheory/Idempotents/Basic.lean @@ -84,7 +84,7 @@ theorem isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent : · intro h refine ⟨?_⟩ intro X p hp - haveI : HasEqualizer (𝟙 X) p := h X p hp + have : HasEqualizer (𝟙 X) p := h X p hp refine ⟨equalizer (𝟙 X) p, equalizer.ι (𝟙 X) p, equalizer.lift p (show p ≫ 𝟙 X = p ≫ p by rw [hp, comp_id]), ?_, equalizer.lift_ι _ _⟩ ext @@ -105,11 +105,11 @@ theorem isIdempotentComplete_iff_idempotents_have_kernels [Preadditive C] : rw [isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent] constructor · intro h X p hp - haveI : HasEqualizer (𝟙 X) (𝟙 X - p) := h X (𝟙 _ - p) (idem_of_id_sub_idem p hp) + have : HasEqualizer (𝟙 X) (𝟙 X - p) := h X (𝟙 _ - p) (idem_of_id_sub_idem p hp) convert! hasKernel_of_hasEqualizer (𝟙 X) (𝟙 X - p) rw [sub_sub_cancel] · intro h X p hp - haveI : HasKernel (𝟙 _ - p) := h X (𝟙 _ - p) (idem_of_id_sub_idem p hp) + have : HasKernel (𝟙 _ - p) := h X (𝟙 _ - p) (idem_of_id_sub_idem p hp) apply Preadditive.hasEqualizer_of_hasKernel /-- An abelian category is idempotent complete. -/ diff --git a/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean b/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean index 75d3640e2a9a42..113db5b6ae5b34 100644 --- a/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean +++ b/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean @@ -61,7 +61,7 @@ instance functor_category_isIdempotentComplete [IsIdempotentComplete C] : IsIdempotentComplete (J ⥤ C) := by refine ⟨fun F p hp => ?_⟩ have hC := (isIdempotentComplete_iff_hasEqualizer_of_id_and_idempotent C).mp inferInstance - haveI : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j) + have : ∀ j : J, HasEqualizer (𝟙 _) (p.app j) := fun j => hC _ _ (congr_app hp j) /- We construct the direct factor `Y` associated to `p : F ⟶ F` by computing the equalizer of the identity and `p.app j` on each object `(j : J)`. -/ let Y : J ⥤ C := diff --git a/Mathlib/CategoryTheory/Limits/Comma.lean b/Mathlib/CategoryTheory/Limits/Comma.lean index 31172ac7aeb408..a8fdbc1630c0d0 100644 --- a/Mathlib/CategoryTheory/Limits/Comma.lean +++ b/Mathlib/CategoryTheory/Limits/Comma.lean @@ -192,8 +192,8 @@ namespace Arrow set_option backward.isDefEq.respectTransparency false in instance hasLimit (F : J ⥤ Arrow T) [i₁ : HasLimit (F ⋙ leftFunc)] [i₂ : HasLimit (F ⋙ rightFunc)] : HasLimit F := by - haveI : HasLimit (F ⋙ Comma.fst _ _) := i₁ - haveI : HasLimit (F ⋙ Comma.snd _ _) := i₂ + have : HasLimit (F ⋙ Comma.fst _ _) := i₁ + have : HasLimit (F ⋙ Comma.snd _ _) := i₂ apply Comma.hasLimit instance hasLimitsOfShape [HasLimitsOfShape J T] : HasLimitsOfShape J (Arrow T) where @@ -207,8 +207,8 @@ instance hasLimits [HasLimits T] : HasLimits (Arrow T) := set_option backward.isDefEq.respectTransparency false in instance hasColimit (F : J ⥤ Arrow T) [i₁ : HasColimit (F ⋙ leftFunc)] [i₂ : HasColimit (F ⋙ rightFunc)] : HasColimit F := by - haveI : HasColimit (F ⋙ Comma.fst _ _) := i₁ - haveI : HasColimit (F ⋙ Comma.snd _ _) := i₂ + have : HasColimit (F ⋙ Comma.fst _ _) := i₁ + have : HasColimit (F ⋙ Comma.snd _ _) := i₂ apply Comma.hasColimit instance hasColimitsOfShape [HasColimitsOfShape J T] : HasColimitsOfShape J (Arrow T) where @@ -239,8 +239,8 @@ instance [G.Faithful] [G.Full] {Y : A} : HasInitial (StructuredArrow (G.obj Y) G set_option backward.isDefEq.respectTransparency false in instance hasLimit [i₁ : HasLimit (F ⋙ proj X G)] [i₂ : PreservesLimit (F ⋙ proj X G) G] : HasLimit F := by - haveI : HasLimit (F ⋙ Comma.snd (Functor.fromPUnit X) G) := i₁ - haveI : PreservesLimit (F ⋙ Comma.snd (Functor.fromPUnit X) G) _ := i₂ + have : HasLimit (F ⋙ Comma.snd (Functor.fromPUnit X) G) := i₁ + have : PreservesLimit (F ⋙ Comma.snd (Functor.fromPUnit X) G) _ := i₂ apply Comma.hasLimit instance hasLimitsOfShape [HasLimitsOfShape J A] [PreservesLimitsOfShape J G] : @@ -294,8 +294,8 @@ instance hasTerminal [G.Faithful] [G.Full] {Y : A} : set_option backward.isDefEq.respectTransparency false in instance hasColimit [i₁ : HasColimit (F ⋙ proj G X)] [i₂ : PreservesColimit (F ⋙ proj G X) G] : HasColimit F := by - haveI : HasColimit (F ⋙ Comma.fst G (Functor.fromPUnit X)) := i₁ - haveI : PreservesColimit (F ⋙ Comma.fst G (Functor.fromPUnit X)) _ := i₂ + have : HasColimit (F ⋙ Comma.fst G (Functor.fromPUnit X)) := i₁ + have : PreservesColimit (F ⋙ Comma.fst G (Functor.fromPUnit X)) _ := i₂ apply Comma.hasColimit instance hasColimitsOfShape [HasColimitsOfShape J A] [PreservesColimitsOfShape J G] : diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 106186e51c2118..6870f7db907606 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -532,9 +532,9 @@ instance reflects_cone_isomorphism (F : C ⥤ D) [F.ReflectsIsomorphisms] (K : J (functoriality K F).ReflectsIsomorphisms := by constructor intro A B f _ - haveI : IsIso (F.map f.hom) := + have : IsIso (F.map f.hom) := (forget (K ⋙ F)).map_isIso ((functoriality K F).map f) - haveI := ReflectsIsomorphisms.reflects F f.hom + have := ReflectsIsomorphisms.reflects F f.hom apply cone_iso_of_hom_iso end diff --git a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean index 16c1a911232acc..dea563fee68bb1 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean @@ -126,11 +126,11 @@ set_option backward.defeqAttrib.useBackward true in lemma preservesFinOfPreservesBinaryAndTerminal : ∀ (n : ℕ) (f : Fin n → C), PreservesLimit (Discrete.functor f) F | 0 => fun f => by - letI : PreservesLimitsOfShape (Discrete (Fin 0)) F := + let : PreservesLimitsOfShape (Discrete (Fin 0)) F := preservesLimitsOfShape_of_equiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _ infer_instance | n + 1 => by - haveI := preservesFinOfPreservesBinaryAndTerminal n + have := preservesFinOfPreservesBinaryAndTerminal n intro f apply preservesLimit_of_preserves_limit_cone @@ -157,7 +157,7 @@ lemma Limits.PreservesFiniteProducts.of_preserves_binary_and_terminal : preserves n := by refine ⟨fun {K} ↦ ?_⟩ let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _ - haveI := preservesFinOfPreservesBinaryAndTerminal F n fun n => K.obj ⟨n⟩ + have := preservesFinOfPreservesBinaryAndTerminal F n fun n => K.obj ⟨n⟩ apply preservesLimit_of_iso_diagram F that end Preserves @@ -251,11 +251,11 @@ set_option backward.defeqAttrib.useBackward true in lemma preserves_fin_of_preserves_binary_and_initial : ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F | 0 => fun f => by - letI : PreservesColimitsOfShape (Discrete (Fin 0)) F := + let : PreservesColimitsOfShape (Discrete (Fin 0)) F := preservesColimitsOfShape_of_equiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _ infer_instance | n + 1 => by - haveI := preserves_fin_of_preserves_binary_and_initial n + have := preserves_fin_of_preserves_binary_and_initial n intro f apply preservesColimit_of_preserves_colimit_cocone @@ -282,7 +282,7 @@ lemma preservesShape_fin_of_preserves_binary_and_initial (n : ℕ) : PreservesColimitsOfShape (Discrete (Fin n)) F where preservesColimit {K} := by let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _ - haveI := preserves_fin_of_preserves_binary_and_initial F n fun n => K.obj ⟨n⟩ + have := preserves_fin_of_preserves_binary_and_initial F n fun n => K.obj ⟨n⟩ apply preservesColimit_of_iso_diagram F that /-- If `F` preserves the initial object and binary coproducts then it preserves finite products. -/ diff --git a/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean b/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean index 5915e5f70240f2..4306b75fe86e82 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean @@ -555,10 +555,10 @@ theorem hasFiniteColimits_of_hasInitial_and_pushouts [HasInitial C] [HasPushouts lemma preservesFiniteColimits_of_preservesInitial_and_pushouts [HasInitial C] [HasPushouts C] (G : C ⥤ D) [PreservesColimitsOfShape (Discrete.{0} PEmpty) G] [PreservesColimitsOfShape WalkingSpan G] : PreservesFiniteColimits G := by - haveI : HasFiniteColimits C := hasFiniteColimits_of_hasInitial_and_pushouts - haveI : PreservesColimitsOfShape (Discrete WalkingPair) G := + have : HasFiniteColimits C := hasFiniteColimits_of_hasInitial_and_pushouts + have : PreservesColimitsOfShape (Discrete WalkingPair) G := preservesBinaryCoproducts_of_preservesInitial_and_pushouts G - haveI : PreservesColimitsOfShape (WalkingParallelPair) G := + have : PreservesColimitsOfShape (WalkingParallelPair) G := (preservesCoequalizers_of_preservesPushouts_and_binaryCoproducts G) refine @preservesFiniteColimits_of_preservesCoequalizers_and_finiteCoproducts _ _ _ _ _ _ G _ ?_ diff --git a/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean b/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean index a6eac607f7df52..d65f644094c053 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean @@ -47,7 +47,7 @@ theorem hasInitial_of_weakly_initial_and_hasWideEqualizers [HasWideEqualizers.{v (hT : ∀ X, Nonempty (T ⟶ X)) : HasInitial C := by let endos := T ⟶ T let i := wideEqualizer.ι (id : endos → endos) - haveI : Nonempty endos := ⟨𝟙 _⟩ + have : Nonempty endos := ⟨𝟙 _⟩ have : ∀ X : C, Unique (wideEqualizer (id : endos → endos) ⟶ X) := by intro X refine ⟨⟨i ≫ Classical.choice (hT X)⟩, fun a => ?_⟩ @@ -58,7 +58,7 @@ theorem hasInitial_of_weakly_initial_and_hasWideEqualizers [HasWideEqualizers.{v rw [Category.assoc, Category.assoc] apply wideEqualizer.condition (id : endos → endos) (h ≫ e ≫ i) rw [Category.comp_id, cancel_mono_id i] at this - haveI : IsSplitEpi e := IsSplitEpi.mk' ⟨i ≫ h, this⟩ + have : IsSplitEpi e := IsSplitEpi.mk' ⟨i ≫ h, this⟩ rw [← cancel_epi e] apply equalizer.condition exact hasInitial_of_unique (wideEqualizer (id : endos → endos)) diff --git a/Mathlib/CategoryTheory/Limits/Final.lean b/Mathlib/CategoryTheory/Limits/Final.lean index 40de447a51ef95..7083e202e084c2 100644 --- a/Mathlib/CategoryTheory/Limits/Final.lean +++ b/Mathlib/CategoryTheory/Limits/Final.lean @@ -928,15 +928,15 @@ variable {C : Type u₁} [Category.{v₁} C] {c : C} lemma final_fromPUnit_of_isTerminal (hc : Limits.IsTerminal c) : (fromPUnit c).Final where out c' := by - letI : Inhabited (StructuredArrow c' (fromPUnit c)) := ⟨.mk (Y := default) (hc.from c')⟩ - letI : Subsingleton (StructuredArrow c' (fromPUnit c)) := + let : Inhabited (StructuredArrow c' (fromPUnit c)) := ⟨.mk (Y := default) (hc.from c')⟩ + let : Subsingleton (StructuredArrow c' (fromPUnit c)) := ⟨fun i j ↦ StructuredArrow.obj_ext _ _ (by cat_disch) (hc.hom_ext _ _)⟩ infer_instance lemma initial_fromPUnit_of_isInitial (hc : Limits.IsInitial c) : (fromPUnit c).Initial where out c' := by - letI : Inhabited (CostructuredArrow (fromPUnit c) c') := ⟨.mk (Y := default) (hc.to c')⟩ - letI : Subsingleton (CostructuredArrow (fromPUnit c) c') := + let : Inhabited (CostructuredArrow (fromPUnit c) c') := ⟨.mk (Y := default) (hc.to c')⟩ + let : Subsingleton (CostructuredArrow (fromPUnit c) c') := ⟨fun i j ↦ CostructuredArrow.obj_ext _ _ (by cat_disch) (hc.hom_ext _ _)⟩ infer_instance @@ -1102,7 +1102,7 @@ instance Grothendieck.final_pre [hG : Final G] : (Grothendieck.pre F G).Final := constructor rintro ⟨d, f⟩ let ⟨u, c, g⟩ : Nonempty (StructuredArrow d G) := inferInstance - letI : Nonempty (StructuredArrow ⟨d, f⟩ (pre F G)) := + let : Nonempty (StructuredArrow ⟨d, f⟩ (pre F G)) := ⟨u, ⟨c, (F.map g).toFunctor.obj f⟩, ⟨(by exact g), (by exact 𝟙 _)⟩⟩ apply zigzag_isConnected rintro ⟨⟨⟨⟩⟩, ⟨bi, fi⟩, ⟨gbi, gfi⟩⟩ ⟨⟨⟨⟩⟩, ⟨bj, fj⟩, ⟨gbj, gfj⟩⟩ diff --git a/Mathlib/CategoryTheory/Limits/HasLimits.lean b/Mathlib/CategoryTheory/Limits/HasLimits.lean index 32b9ff4f07b696..167bdd3d91ff3f 100644 --- a/Mathlib/CategoryTheory/Limits/HasLimits.lean +++ b/Mathlib/CategoryTheory/Limits/HasLimits.lean @@ -387,7 +387,7 @@ variable (D : L ⥤ K) @[simp] theorem limit.pre_pre [h : HasLimit (D ⋙ E ⋙ F)] : haveI : HasLimit ((D ⋙ E) ⋙ F) := h limit.pre F E ≫ limit.pre (E ⋙ F) D = limit.pre F (D ⋙ E) := by - haveI : HasLimit ((D ⋙ E) ⋙ F) := h + have : HasLimit ((D ⋙ E) ⋙ F) := h ext j; erw [assoc, limit.pre_π, limit.pre_π, limit.pre_π]; rfl variable {E F} @@ -432,7 +432,7 @@ theorem limit.post_post {E : Type u''} [Category.{v''} E] (H : D ⥤ E) [h : Has -- H G (limit F) ⟶ limit (F ⋙ (G ⋙ H)) haveI : HasLimit (F ⋙ G ⋙ H) := h H.map (limit.post F G) ≫ limit.post (F ⋙ G) H = limit.post F (G ⋙ H) := by - haveI : HasLimit (F ⋙ G ⋙ H) := h + have : HasLimit (F ⋙ G ⋙ H) := h ext; erw [assoc, limit.post_π, ← H.map_comp, limit.post_π, limit.post_π]; rfl end Post @@ -444,7 +444,7 @@ theorem limit.pre_post {D : Type u'} [Category.{v'} D] (E : K ⥤ J) (F : J ⥤ -- G (limit F) ⟶ limit F ⋙ G ⟶ limit (E ⋙ (F ⋙ G)) or haveI : HasLimit (E ⋙ F ⋙ G) := h G.map (limit.pre F E) ≫ limit.post (E ⋙ F) G = limit.post F G ≫ limit.pre (F ⋙ G) E := by - haveI : HasLimit (E ⋙ F ⋙ G) := h + have : HasLimit (E ⋙ F ⋙ G) := h ext; erw [assoc, limit.post_π, ← G.map_comp, limit.pre_π, assoc, limit.pre_π, limit.post_π] open CategoryTheory.Equivalence @@ -458,7 +458,7 @@ instance hasLimit_equivalence_comp (e : K ≌ J) [HasLimit F] : HasLimit (e.func /-- If a `E ⋙ F` has a limit, and `E` is an equivalence, we can construct a limit of `F`. -/ theorem hasLimit_of_equivalence_comp (e : K ≌ J) [HasLimit (e.functor ⋙ F)] : HasLimit F := by - haveI : HasLimit (e.inverse ⋙ e.functor ⋙ F) := Limits.hasLimit_equivalence_comp e.symm + have : HasLimit (e.inverse ⋙ e.functor ⋙ F) := Limits.hasLimit_equivalence_comp e.symm apply hasLimit_of_iso (e.invFunIdAssoc F) lemma hasLimit_equivalence_comp_iff (e : K ≌ J) : HasLimit (e.functor ⋙ F) ↔ HasLimit F := @@ -976,7 +976,7 @@ theorem colimit.pre_pre [h : HasColimit (D ⋙ E ⋙ F)] : colimit.pre (E ⋙ F) D ≫ colimit.pre F E = colimit.pre F (D ⋙ E) := by ext j rw [← assoc, colimit.ι_pre, colimit.ι_pre] - haveI : HasColimit ((D ⋙ E) ⋙ F) := h + have : HasColimit ((D ⋙ E) ⋙ F) := h exact (colimit.ι_pre F (D ⋙ E) j).symm variable {E F} @@ -1029,7 +1029,7 @@ theorem colimit.post_post {E : Type u''} [Category.{v''} E] (H : D ⥤ E) colimit.post (F ⋙ G) H ≫ H.map (colimit.post F G) = colimit.post F (G ⋙ H) := by ext j rw [← assoc, colimit.ι_post, ← H.map_comp, colimit.ι_post] - haveI : HasColimit (F ⋙ G ⋙ H) := h + have : HasColimit (F ⋙ G ⋙ H) := h exact (colimit.ι_post F (G ⋙ H) j).symm end Post @@ -1044,7 +1044,7 @@ theorem colimit.pre_post {D : Type u'} [Category.{v'} D] (E : K ⥤ J) (F : J colimit.pre (F ⋙ G) E ≫ colimit.post F G := by ext j rw [← assoc, colimit.ι_post, ← G.map_comp, colimit.ι_pre, ← assoc] - haveI : HasColimit (E ⋙ F ⋙ G) := h + have : HasColimit (E ⋙ F ⋙ G) := h erw [colimit.ι_pre (F ⋙ G) E j, colimit.ι_post] open CategoryTheory.Equivalence @@ -1057,7 +1057,7 @@ instance hasColimit_equivalence_comp (e : K ≌ J) [HasColimit F] : HasColimit ( /-- If a `E ⋙ F` has a colimit, and `E` is an equivalence, we can construct a colimit of `F`. -/ theorem hasColimit_of_equivalence_comp (e : K ≌ J) [HasColimit (e.functor ⋙ F)] : HasColimit F := by - haveI : HasColimit (e.inverse ⋙ e.functor ⋙ F) := Limits.hasColimit_equivalence_comp e.symm + have : HasColimit (e.inverse ⋙ e.functor ⋙ F) := Limits.hasColimit_equivalence_comp e.symm apply hasColimit_of_iso (e.invFunIdAssoc F).symm lemma hasColimit_equivalence_comp_iff (e : K ≌ J) : HasColimit (e.functor ⋙ F) ↔ HasColimit F := diff --git a/Mathlib/CategoryTheory/Limits/IsConnected.lean b/Mathlib/CategoryTheory/Limits/IsConnected.lean index 72d660634779fe..13144ac27ef694 100644 --- a/Mathlib/CategoryTheory/Limits/IsConnected.lean +++ b/Mathlib/CategoryTheory/Limits/IsConnected.lean @@ -149,7 +149,7 @@ variable (C : Type*) [Category* C] /-- Prove that a category is connected by supplying an explicit initial object. -/ lemma isConnected_of_isInitial {x : C} (h : Limits.IsInitial x) : IsConnected C := by - letI : Nonempty C := ⟨x⟩ + let : Nonempty C := ⟨x⟩ apply isConnected_of_zigzag intro j₁ j₂ use [x, j₂] @@ -159,7 +159,7 @@ lemma isConnected_of_isInitial {x : C} (h : Limits.IsInitial x) : IsConnected C /-- Prove that a category is connected by supplying an explicit terminal object. -/ lemma isConnected_of_isTerminal {x : C} (h : Limits.IsTerminal x) : IsConnected C := by - letI : Nonempty C := ⟨x⟩ + let : Nonempty C := ⟨x⟩ apply isConnected_of_zigzag intro j₁ j₂ use [x, j₂] diff --git a/Mathlib/CategoryTheory/Limits/Lattice.lean b/Mathlib/CategoryTheory/Limits/Lattice.lean index 324785f5ee4e52..260e9f9e176599 100644 --- a/Mathlib/CategoryTheory/Limits/Lattice.lean +++ b/Mathlib/CategoryTheory/Limits/Lattice.lean @@ -99,7 +99,7 @@ theorem finite_coproduct_eq_finset_sup [SemilatticeSup α] [OrderBot α] {ι : T -- see Note [lower instance priority] instance (priority := 100) [SemilatticeInf α] [OrderTop α] : HasBinaryProducts α := by have : ∀ x y : α, HasLimit (pair x y) := by - letI := hasFiniteLimits_of_hasFiniteLimits_of_size.{u} α + let := hasFiniteLimits_of_hasFiniteLimits_of_size.{u} α infer_instance apply hasBinaryProducts_of_hasLimit_pair @@ -118,7 +118,7 @@ theorem prod_eq_inf [SemilatticeInf α] [OrderTop α] (x y : α) : Limits.prod x -- see Note [lower instance priority] instance (priority := 100) [SemilatticeSup α] [OrderBot α] : HasBinaryCoproducts α := by have : ∀ x y : α, HasColimit (pair x y) := by - letI := hasFiniteColimits_of_hasFiniteColimits_of_size.{u} α + let := hasFiniteColimits_of_hasFiniteColimits_of_size.{u} α infer_instance apply hasBinaryCoproducts_of_hasColimit_pair diff --git a/Mathlib/CategoryTheory/Limits/MonoCoprod.lean b/Mathlib/CategoryTheory/Limits/MonoCoprod.lean index 8f6fd6777fbe73..3229ffa052a6a5 100644 --- a/Mathlib/CategoryTheory/Limits/MonoCoprod.lean +++ b/Mathlib/CategoryTheory/Limits/MonoCoprod.lean @@ -54,7 +54,7 @@ variable {C} instance (priority := 100) monoCoprodOfHasZeroMorphisms [HasZeroMorphisms C] : MonoCoprod C := ⟨fun A B c hc => by - haveI : IsSplitMono c.inl := + have : IsSplitMono c.inl := IsSplitMono.mk' (SplitMono.mk (BinaryCofan.IsColimit.desc hc (𝟙 A) 0) (IsColimit.fac _ _ _)) infer_instance⟩ @@ -63,7 +63,7 @@ namespace MonoCoprod set_option backward.isDefEq.respectTransparency false in theorem binaryCofan_inr {A B : C} [MonoCoprod C] (c : BinaryCofan A B) (hc : IsColimit c) : Mono c.inr := by - haveI hc' : IsColimit (BinaryCofan.mk c.inr c.inl) := + have hc' : IsColimit (BinaryCofan.mk c.inr c.inl) := BinaryCofan.IsColimit.mk _ (fun f₁ f₂ => BinaryCofan.IsColimit.desc (s := c) hc f₂ f₁) (by simp) (by simp) diff --git a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean index 66f8eb57f06f89..8016311053c3b0 100644 --- a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean @@ -101,7 +101,7 @@ instance CostructuredArrow.closedUnderLimitsOfShape_discrete_empty [L.Faithful] (P.costructuredArrowObj L (X := L.obj Y)).IsClosedUnderLimitsOfShape (Discrete PEmpty.{1}) where limitsOfShape_le := by rintro X p - letI t : IsTerminal X := (ObjectProperty.limitsOfShape_isEmpty_iff _ _ _ |>.mp p).some + let t : IsTerminal X := (ObjectProperty.limitsOfShape_isEmpty_iff _ _ _ |>.mp p).some let e : X ≅ CostructuredArrow.mk (𝟙 (L.obj Y)) := t.uniqueUpToIso CostructuredArrow.mkIdTerminal simpa [MorphismProperty.costructuredArrowObj_iff, P.costructuredArrow_iso_iff e] using P.id_mem (L.obj Y) @@ -183,7 +183,7 @@ instance StructuredArrow.closedUnderColimitsOfShape_discrete_empty [L.Faithful] (P.structuredArrowObj L (X := L.obj Y)).IsClosedUnderColimitsOfShape (Discrete PEmpty.{1}) where colimitsOfShape_le := by rintro X p - letI t : IsInitial X := (ObjectProperty.colimitsOfShape_isEmpty_iff _ _ _ |>.mp p).some + let t : IsInitial X := (ObjectProperty.colimitsOfShape_isEmpty_iff _ _ _ |>.mp p).some let e : X ≅ StructuredArrow.mk (𝟙 (L.obj Y)) := t.uniqueUpToIso StructuredArrow.mkIdInitial simpa [MorphismProperty.structuredArrowObj_iff, P.structuredArrow_iso_iff e] using P.id_mem (L.obj Y) diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean b/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean index 5dbce868ff5ce4..2e76a7699b92dc 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean @@ -231,7 +231,7 @@ instance of_preservesColimits_in_each_variable symm apply (P j₁).hom_ext intro j₂ - haveI := (P j₁).fac s j₂ + have := (P j₁).fac s j₂ simp only [Functor.mapCocone_pt, Functor.mapCocone_ι_app, Q₀, s] at this simp only [Functor.mapCocone_pt, Functor.mapCocone_ι_app, NatTrans.naturality, this, Q₀, s]) @@ -361,7 +361,7 @@ instance of_preservesLimits_in_each_variable symm apply (P j₁).hom_ext intro j₂ - haveI := (P j₁).fac s j₂ + have := (P j₁).fac s j₂ simp only [whiskeringLeft₂_obj_obj_obj_obj_obj, Functor.mapCone_pt, Functor.mapCone_π_app, s, Q₀] at this simp only [whiskeringLeft₂_obj_obj_obj_obj_obj, diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean index 6e746297d1eeca..5b428c617faf3a 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean @@ -79,7 +79,7 @@ lemma preservesFilteredColimitsOfSize_of_univLE (F : C ⥤ D) [UnivLE.{w, w'}] PreservesFilteredColimitsOfSize.{w, w₂} F where preserves_filtered_colimits J _ _ := by let e := ((ShrinkHoms.equivalence.{w'} J).trans <| Shrink.equivalence _).symm - haveI := IsFiltered.of_equivalence e.symm + have := IsFiltered.of_equivalence e.symm exact preservesColimitsOfShape_of_equiv e F /-- @@ -135,7 +135,7 @@ lemma reflectsFilteredColimitsOfSize_of_univLE (F : C ⥤ D) [UnivLE.{w, w'}] ReflectsFilteredColimitsOfSize.{w, w₂} F where reflects_filtered_colimits J _ _ := by let e := ((ShrinkHoms.equivalence.{w'} J).trans <| Shrink.equivalence _).symm - haveI := IsFiltered.of_equivalence e.symm + have := IsFiltered.of_equivalence e.symm exact reflectsColimitsOfShape_of_equiv e F /-- @@ -195,7 +195,7 @@ lemma preservesCofilteredLimitsOfSize_of_univLE (F : C ⥤ D) [UnivLE.{w, w'}] PreservesCofilteredLimitsOfSize.{w, w₂} F where preserves_cofiltered_limits J _ _ := by let e := ((ShrinkHoms.equivalence.{w'} J).trans <| Shrink.equivalence _).symm - haveI := IsCofiltered.of_equivalence e.symm + have := IsCofiltered.of_equivalence e.symm exact preservesLimitsOfShape_of_equiv e F /-- @@ -251,7 +251,7 @@ lemma reflectsCofilteredLimitsOfSize_of_univLE (F : C ⥤ D) [UnivLE.{w, w'}] ReflectsCofilteredLimitsOfSize.{w, w₂} F where reflects_cofiltered_limits J _ _ := by let e := ((ShrinkHoms.equivalence.{w'} J).trans <| Shrink.equivalence _).symm - haveI := IsCofiltered.of_equivalence e.symm + have := IsCofiltered.of_equivalence e.symm exact reflectsLimitsOfShape_of_equiv e F /-- diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Finite.lean b/Mathlib/CategoryTheory/Limits/Preserves/Finite.lean index e70dd1385a60ee..53a5e58d2c29a3 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Finite.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Finite.lean @@ -59,7 +59,7 @@ instance (priority := 100) preservesLimitsOfShapeOfPreservesFiniteLimits (F : C lemma PreservesLimitsOfSize.preservesFiniteLimits (F : C ⥤ D) [PreservesLimitsOfSize.{w, w₂} F] : PreservesFiniteLimits F where preservesFiniteLimits J (sJ : SmallCategory J) fJ := by - haveI := preservesSmallestLimits_of_preservesLimits F + have := preservesSmallestLimits_of_preservesLimits F exact preservesLimitsOfShape_of_equiv (FinCategory.equivAsType J) F -- Added as a specialization of the dangerous instance above, for limits indexed in Type 0. @@ -80,7 +80,7 @@ lemma preservesFiniteLimits_of_preservesFiniteLimitsOfSize (F : C ⥤ D) ∀ (J : Type w) {𝒥 : SmallCategory J} (_ : @FinCategory J 𝒥), PreservesLimitsOfShape J F) : PreservesFiniteLimits F where preservesFiniteLimits J (_ : SmallCategory J) _ := by - haveI := h (ULiftHom (ULift J)) CategoryTheory.finCategoryUlift + have := h (ULiftHom (ULift J)) CategoryTheory.finCategoryUlift exact preservesLimitsOfShape_of_equiv (ULiftHomULiftCategory.equiv J).symm F /-- The composition of two left exact functors is left exact. -/ @@ -143,7 +143,7 @@ instance (priority := 100) (F : C ⥤ D) [ReflectsFiniteProducts F] (J : Type u) lemma ReflectsLimitsOfSize.reflectsFiniteLimits (F : C ⥤ D) [ReflectsLimitsOfSize.{w, w₂} F] : ReflectsFiniteLimits F where reflects J (sJ : SmallCategory J) fJ := by - haveI := reflectsSmallestLimits_of_reflectsLimits F + have := reflectsSmallestLimits_of_reflectsLimits F exact reflectsLimitsOfShape_of_equiv (FinCategory.equivAsType J) F -- Added as a specialization of the dangerous instance above, for colimits indexed in Type 0. @@ -214,7 +214,7 @@ instance (priority := 100) preservesColimitsOfShapeOfPreservesFiniteColimits lemma PreservesColimitsOfSize.preservesFiniteColimits (F : C ⥤ D) [PreservesColimitsOfSize.{w, w₂} F] : PreservesFiniteColimits F where preservesFiniteColimits J (sJ : SmallCategory J) fJ := by - haveI := preservesSmallestColimits_of_preservesColimits F + have := preservesSmallestColimits_of_preservesColimits F exact preservesColimitsOfShape_of_equiv (FinCategory.equivAsType J) F -- Added as a specialization of the dangerous instance above, for colimits indexed in Type 0. @@ -235,8 +235,8 @@ lemma preservesFiniteColimits_of_preservesFiniteColimitsOfSize (F : C ⥤ D) ∀ (J : Type w) {𝒥 : SmallCategory J} (_ : @FinCategory J 𝒥), PreservesColimitsOfShape J F) : PreservesFiniteColimits F where preservesFiniteColimits J (_ : SmallCategory J) _ := by - letI : Category (ULiftHom (ULift J)) := ULiftHom.category - haveI := h (ULiftHom (ULift J)) CategoryTheory.finCategoryUlift + let : Category (ULiftHom (ULift J)) := ULiftHom.category + have := h (ULiftHom (ULift J)) CategoryTheory.finCategoryUlift exact preservesColimitsOfShape_of_equiv (ULiftHomULiftCategory.equiv J).symm F /-- The composition of two right exact functors is right exact. -/ @@ -284,7 +284,7 @@ attribute [instance] ReflectsFiniteColimits.reflects lemma ReflectsColimitsOfSize.reflectsFiniteColimits (F : C ⥤ D) [ReflectsColimitsOfSize.{w, w₂} F] : ReflectsFiniteColimits F where reflects J (sJ : SmallCategory J) fJ := by - haveI := reflectsSmallestColimits_of_reflectsColimits F + have := reflectsSmallestColimits_of_reflectsColimits F exact reflectsColimitsOfShape_of_equiv (FinCategory.equivAsType J) F -- Added as a specialization of the dangerous instance above, for colimits indexed in Type 0. diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean b/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean index 5e460381f09c30..62183f262e47b8 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean @@ -84,7 +84,7 @@ instance preservesLimitsOfShape_colim_grothendieck [HasColimitsOfShape C H] [Has _ ≅ limit (K ⋙ colim) := HasLimit.isoOfNatIso (associator _ _ _ ≪≫ isoWhiskerLeft _ fiberwiseColimCompColimIso) - haveI : IsIso (limit.post K colim) := by + have : IsIso (limit.post K colim) := by convert! Iso.isIso_hom i₂ ext simp only [colim_obj, Functor.comp_obj, limit.post_π, colim_map, Iso.trans_def, diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean index b6f53dbfb62472..648b8b55d7e5d8 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean @@ -144,7 +144,7 @@ lemma preservesBiproducts_shrink (F : C ⥤ D) [PreservesZeroMorphisms F] instance (priority := 100) preservesFiniteBiproductsOfPreservesBiproducts (F : C ⥤ D) [PreservesZeroMorphisms F] [PreservesBiproducts.{w₁} F] : PreservesFiniteBiproducts F where - preserves {J} _ := by letI := preservesBiproducts_shrink.{0} F; infer_instance + preserves {J} _ := by let := preservesBiproducts_shrink.{0} F; infer_instance /-- A functor `F` preserves binary biproducts of `X` and `Y` if `F` maps every bilimit bicone over `X` and `Y` to a bilimit bicone over `F.obj X` and `F.obj Y`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean index df1b7a6308947f..a4e859af2ebd2e 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean @@ -189,7 +189,7 @@ instance : IsIso (coequalizerComparison f g G) := by instance map_π_epi : Epi (G.map (coequalizer.π f g)) := ⟨fun {W} h k => by rw [← ι_comp_coequalizerComparison] - haveI : Epi (coequalizer.π (G.map f) (G.map g) ≫ coequalizerComparison f g G) := by + have : Epi (coequalizer.π (G.map f) (G.map g) ≫ coequalizerComparison f g G) := by apply epi_comp apply (cancel_epi _).1⟩ diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Terminal.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Terminal.lean index e5f61fbbd735ea..f222b8dc7366be 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Terminal.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Terminal.lean @@ -86,7 +86,7 @@ has limits of shape `J` and `G` preserves them, then `D` does not necessarily ha -/ theorem hasTerminal_of_hasTerminal_of_preservesLimit [PreservesLimit (Functor.empty.{0} C) G] : HasTerminal D := ⟨fun F => by - haveI := HasLimit.mk ⟨_, isLimitOfHasTerminalOfPreservesLimit G⟩ + have := HasLimit.mk ⟨_, isLimitOfHasTerminalOfPreservesLimit G⟩ apply hasLimit_of_iso F.uniqueFromEmpty.symm⟩ variable [HasTerminal D] @@ -178,7 +178,7 @@ shape `J`. theorem hasInitial_of_hasInitial_of_preservesColimit [PreservesColimit (Functor.empty.{0} C) G] : HasInitial D := ⟨fun F => by - haveI := HasColimit.mk ⟨_, isColimitOfHasInitialOfPreservesColimit G⟩ + have := HasColimit.mk ⟨_, isColimitOfHasInitialOfPreservesColimit G⟩ apply hasColimit_of_iso F.uniqueFromEmpty⟩ variable [HasInitial D] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 8ede7661f528eb..86513d565ea1a3 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -391,7 +391,7 @@ theorem hasBiproductsOfShape_of_equiv {K : Type w'} [HasBiproductsOfShape K C] ( instance (priority := 100) hasBiproductsOfShape_finite [HasFiniteBiproducts C] [Finite J] : HasBiproductsOfShape J C := by rcases Finite.exists_equiv_fin J with ⟨n, ⟨e⟩⟩ - haveI : HasBiproductsOfShape (Fin n) C := HasFiniteBiproducts.out n + have : HasBiproductsOfShape (Fin n) C := HasFiniteBiproducts.out n exact hasBiproductsOfShape_of_equiv C e instance (priority := 100) hasFiniteProducts_of_hasFiniteBiproducts [HasFiniteBiproducts C] : diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean index e02b96e3fe1a9b..a788f7f375946a 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean @@ -1347,7 +1347,7 @@ def splitMonoOfIdempotentOfIsLimitFork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) (i : IsLimit c) : SplitMono c.ι where retraction := i.lift (Fork.ofι f (by simp [hf])) id := by - letI := mono_of_isLimit_fork i + let := mono_of_isLimit_fork i rw [← cancel_mono_id c.ι, Category.assoc, Fork.IsLimit.lift_ι, Fork.ι_ofι, ← c.condition] exact Category.comp_id c.ι @@ -1427,7 +1427,7 @@ def splitEpiOfIdempotentOfIsColimitCofork {X : C} {f : X ⟶ X} (hf : f ≫ f = (i : IsColimit c) : SplitEpi c.π where section_ := i.desc (Cofork.ofπ f (by simp [hf])) id := by - letI := epi_of_isColimit_cofork i + let := epi_of_isColimit_cofork i rw [← cancel_epi_id c.π, ← Category.assoc, Cofork.IsColimit.π_desc, Cofork.π_ofπ, ← c.condition] exact Category.id_comp _ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/FiniteLimits.lean b/Mathlib/CategoryTheory/Limits/Shapes/FiniteLimits.lean index 8103b89be052e2..08c3f7e8ea6ad8 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/FiniteLimits.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/FiniteLimits.lean @@ -73,7 +73,7 @@ theorem hasFiniteLimits_of_hasFiniteLimits_of_size (h : ∀ (J : Type w) {𝒥 : SmallCategory J} (_ : @FinCategory J 𝒥), HasLimitsOfShape J C) : HasFiniteLimits C where out := fun J hJ hhJ => by - haveI := h (ULiftHom.{w} (ULift.{w} J)) <| @CategoryTheory.finCategoryUlift J hJ hhJ + have := h (ULiftHom.{w} (ULift.{w} J)) <| @CategoryTheory.finCategoryUlift J hJ hhJ have l : @Equivalence J (ULiftHom (ULift J)) hJ (@ULiftHom.category (ULift J) (@uliftCategory J hJ)) := @ULiftHomULiftCategory.equiv J hJ @@ -117,7 +117,7 @@ theorem hasFiniteColimits_of_hasFiniteColimits_of_size (h : ∀ (J : Type w) {𝒥 : SmallCategory J} (_ : @FinCategory J 𝒥), HasColimitsOfShape J C) : HasFiniteColimits C where out := fun J hJ hhJ => by - haveI := h (ULiftHom.{w} (ULift.{w} J)) <| @CategoryTheory.finCategoryUlift J hJ hhJ + have := h (ULiftHom.{w} (ULift.{w} J)) <| @CategoryTheory.finCategoryUlift J hJ hhJ have l : @Equivalence J (ULiftHom (ULift J)) hJ (@ULiftHom.category (ULift J) (@uliftCategory J hJ)) := @ULiftHomULiftCategory.equiv J hJ @@ -224,7 +224,7 @@ class HasFiniteWidePullbacks : Prop where instance hasLimitsOfShape_widePullbackShape (J : Type) [Finite J] [HasFiniteWidePullbacks C] : HasLimitsOfShape (WidePullbackShape J) C := by - haveI := @HasFiniteWidePullbacks.out C _ _ J + have := @HasFiniteWidePullbacks.out C _ _ J infer_instance /-- A category `HasFiniteWidePushouts` if it has all colimits of shape `WidePushoutShape J` for @@ -236,7 +236,7 @@ class HasFiniteWidePushouts : Prop where instance hasColimitsOfShape_widePushoutShape (J : Type) [Finite J] [HasFiniteWidePushouts C] : HasColimitsOfShape (WidePushoutShape J) C := by - haveI := @HasFiniteWidePushouts.out C _ _ J + have := @HasFiniteWidePushouts.out C _ _ J infer_instance /-- Finite wide pullbacks are finite limits, so if `C` has all finite limits, diff --git a/Mathlib/CategoryTheory/Limits/Shapes/FiniteProducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/FiniteProducts.lean index 38f8a5716013e6..ffa74e33e699b6 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/FiniteProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/FiniteProducts.lean @@ -43,7 +43,7 @@ instance (priority := 10) hasFiniteProducts_of_hasFiniteLimits [HasFiniteLimits instance hasLimitsOfShape_discrete [HasFiniteProducts C] (ι : Type w) [Finite ι] : HasLimitsOfShape (Discrete ι) C := by rcases Finite.exists_equiv_fin ι with ⟨n, ⟨e⟩⟩ - haveI : HasLimitsOfShape (Discrete (Fin n)) C := HasFiniteProducts.out n + have : HasLimitsOfShape (Discrete (Fin n)) C := HasFiniteProducts.out n exact hasLimitsOfShape_of_equivalence (Discrete.equivalence e.symm) /-- We can now write this for powers. -/ @@ -68,7 +68,7 @@ class HasFiniteCoproducts : Prop where instance hasColimitsOfShape_discrete [HasFiniteCoproducts C] (ι : Type w) [Finite ι] : HasColimitsOfShape (Discrete ι) C := by rcases Finite.exists_equiv_fin ι with ⟨n, ⟨e⟩⟩ - haveI : HasColimitsOfShape (Discrete (Fin n)) C := HasFiniteCoproducts.out n + have : HasColimitsOfShape (Discrete (Fin n)) C := HasFiniteCoproducts.out n exact hasColimitsOfShape_of_equivalence (Discrete.equivalence e.symm) /-- If `C` has finite colimits then it has finite coproducts. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Images.lean b/Mathlib/CategoryTheory/Limits/Shapes/Images.lean index 7a32afb6b3122a..db0925d48b3637 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Images.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Images.lean @@ -1029,8 +1029,8 @@ theorem hasStrongEpiMonoFactorisations_imp_of_isEquivalence (F : C ⥤ D) [IsEqu ⟨fun {X} {Y} f => by let em : StrongEpiMonoFactorisation (F.inv.map f) := (HasStrongEpiMonoFactorisations.has_fac (F.inv.map f)).some - haveI : Mono (F.map em.m ≫ F.asEquivalence.counitIso.hom.app Y) := mono_comp _ _ - haveI : StrongEpi (F.asEquivalence.counitIso.inv.app X ≫ F.map em.e) := strongEpi_comp _ _ + have : Mono (F.map em.m ≫ F.asEquivalence.counitIso.hom.app Y) := mono_comp _ _ + have : StrongEpi (F.asEquivalence.counitIso.inv.app X ≫ F.map em.e) := strongEpi_comp _ _ exact Nonempty.intro { I := F.obj em.I diff --git a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean index f68d561c9176f3..2336b2f854393f 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean @@ -193,11 +193,11 @@ theorem IsInitial.isSplitEpi_to {X Y : C} (t : IsInitial X) (f : Y ⟶ X) : IsSp /-- Any morphism from a terminal object is mono. -/ theorem IsTerminal.mono_from {X Y : C} (t : IsTerminal X) (f : X ⟶ Y) : Mono f := by - haveI := t.isSplitMono_from f; infer_instance + have := t.isSplitMono_from f; infer_instance /-- Any morphism to an initial object is epi. -/ theorem IsInitial.epi_to {X Y : C} (t : IsInitial X) (f : Y ⟶ X) : Epi f := by - haveI := t.isSplitEpi_to f; infer_instance + have := t.isSplitEpi_to f; infer_instance /-- If `T` and `T'` are terminal, they are isomorphic. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean index b440455edad094..2fa2ad31bce3b6 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean @@ -158,7 +158,7 @@ def normalMonoOfMono [IsNormalMonoCategory C] (f : X ⟶ Y) [Mono f] : NormalMon instance (priority := 100) regularMonoCategoryOfNormalMonoCategory [IsNormalMonoCategory C] : IsRegularMonoCategory C where regularMonoOfMono f _ := by - haveI := normalMonoOfMono f + have := normalMonoOfMono f infer_instance end @@ -326,7 +326,7 @@ def normalEpiOfEpi [IsNormalEpiCategory C] (f : X ⟶ Y) [Epi f] : NormalEpi f : instance (priority := 100) regularEpiCategoryOfNormalEpiCategory [IsNormalEpiCategory C] : IsRegularEpiCategory C where regularEpiOfEpi f _ := by - haveI := normalEpiOfEpi f + have := normalEpiOfEpi f infer_instance end CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean index 7ed24f4290765c..0ffb967cc20582 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean @@ -36,7 +36,7 @@ variable (X : Type v₂) /-- If `C` has products indexed by `X`, then `Cᵒᵖ` has coproducts indexed by `X`. -/ instance hasCoproductsOfShape_opposite [HasProductsOfShape X C] : HasCoproductsOfShape X Cᵒᵖ := by - haveI : HasLimitsOfShape (Discrete X)ᵒᵖ C := + have : HasLimitsOfShape (Discrete X)ᵒᵖ C := hasLimitsOfShape_of_equivalence (Discrete.opposite X).symm infer_instance diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean index ffe8ab9e0a96bc..d24b7e08387847 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean @@ -33,12 +33,12 @@ variable {C : Type u₁} [Category.{v₁} C] variable {J : Type u₂} [Category.{v₂} J] instance hasPullbacks_opposite [HasPushouts C] : HasPullbacks Cᵒᵖ := by - haveI : HasColimitsOfShape WalkingCospanᵒᵖ C := + have : HasColimitsOfShape WalkingCospanᵒᵖ C := hasColimitsOfShape_of_equivalence walkingCospanOpEquiv.symm apply hasLimitsOfShape_op_of_hasColimitsOfShape instance hasPushouts_opposite [HasPullbacks C] : HasPushouts Cᵒᵖ := by - haveI : HasLimitsOfShape WalkingSpanᵒᵖ C := + have : HasLimitsOfShape WalkingSpanᵒᵖ C := hasLimitsOfShape_of_equivalence walkingSpanOpEquiv.symm infer_instance diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean index 3d08f695eb27e5..1b283d8e6d6d7b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean @@ -159,12 +159,12 @@ attribute [instance 1] HasCoreflexiveEqualizers.has_eq theorem hasCoequalizer_of_common_section [HasReflexiveCoequalizers C] {A B : C} {f g : A ⟶ B} (r : B ⟶ A) (rf : r ≫ f = 𝟙 _) (rg : r ≫ g = 𝟙 _) : HasCoequalizer f g := by - letI := IsReflexivePair.mk' r rf rg + let := IsReflexivePair.mk' r rf rg infer_instance theorem hasEqualizer_of_common_retraction [HasCoreflexiveEqualizers C] {A B : C} {f g : A ⟶ B} (r : B ⟶ A) (fr : f ≫ r = 𝟙 _) (gr : g ≫ r = 𝟙 _) : HasEqualizer f g := by - letI := IsCoreflexivePair.mk' r fr gr + let := IsCoreflexivePair.mk' r fr gr infer_instance /-- If `C` has coequalizers, then it has reflexive coequalizers. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean b/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean index 260c995a2118c9..f7436a1a3ab60b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean @@ -709,13 +709,13 @@ def regularEpiOfEpi [IsRegularEpiCategory C] (f : X ⟶ Y) [Epi f] : RegularEpi instance (priority := 100) regularEpiCategoryOfSplitEpiCategory [SplitEpiCategory C] : IsRegularEpiCategory C where regularEpiOfEpi f _ := by - haveI := isSplitEpi_of_epi f + have := isSplitEpi_of_epi f infer_instance instance (priority := 100) strongEpiCategory_of_regularEpiCategory [IsRegularEpiCategory C] : StrongEpiCategory C where strongEpi_of_epi f _ := by - haveI := isRegularEpi_of_regularEpi <| regularEpiOfEpi f + have := isRegularEpi_of_regularEpi <| regularEpiOfEpi f infer_instance end CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean b/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean index 4b0713b479ab5b..15fc725c4ae7a2 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean @@ -71,8 +71,8 @@ theorem IsInitial.isIso_to (hI : IsInitial I) {A : C} (f : A ⟶ I) : IsIso f := HasStrictInitialObjects.out f hI theorem IsInitial.strict_hom_ext (hI : IsInitial I) {A : C} (f g : A ⟶ I) : f = g := by - haveI := hI.isIso_to f - haveI := hI.isIso_to g + have := hI.isIso_to f + have := hI.isIso_to g exact eq_of_inv_eq_inv (hI.hom_ext (inv f) (inv g)) theorem IsInitial.subsingleton_to (hI : IsInitial I) {A : C} : Subsingleton (A ⟶ I) := @@ -184,8 +184,8 @@ theorem IsTerminal.isIso_from (hI : IsTerminal I) {A : C} (f : I ⟶ A) : IsIso HasStrictTerminalObjects.out f hI theorem IsTerminal.strict_hom_ext (hI : IsTerminal I) {A : C} (f g : I ⟶ A) : f = g := by - haveI := hI.isIso_from f - haveI := hI.isIso_from g + have := hI.isIso_from f + have := hI.isIso_from g exact eq_of_inv_eq_inv (hI.hom_ext (inv f) (inv g)) /-- If `X ⟶ Y` with `Y` being a strict terminal object, then `X` is also a terminal object. -/ @@ -219,7 +219,7 @@ theorem limit_π_isIso_of_is_strict_terminal (F : J ⥤ C) [HasLimit F] (i : J) obtain rfl : f = 𝟙 _ := Subsingleton.elim _ _ simp · cases h - haveI : IsIso (F.map f) := (H _ h_1).isIso_from _ + have : IsIso (F.map f) := (H _ h_1).isIso_from _ rw [← IsIso.comp_inv_eq] apply (H _ h_1).hom_ext · cases h_1 diff --git a/Mathlib/CategoryTheory/Limits/Sifted.lean b/Mathlib/CategoryTheory/Limits/Sifted.lean index f52aaf77e2cf86..e8151ee9fabd95 100644 --- a/Mathlib/CategoryTheory/Limits/Sifted.lean +++ b/Mathlib/CategoryTheory/Limits/Sifted.lean @@ -70,7 +70,7 @@ set_option backward.defeqAttrib.useBackward true in /-- Being sifted is preserved by equivalences of categories -/ lemma isSifted_of_equiv [IsSifted C] {D : Type u₁} [Category.{v₁} D] (e : D ≌ C) : IsSifted D := letI : Final (diag D) := by - letI : D × D ≌ C × C := Equivalence.prod e e + let : D × D ≌ C × C := Equivalence.prod e e have sq : (e.inverse ⋙ diag D ⋙ this.functor ≅ diag C) := NatIso.ofComponents (fun c ↦ by dsimp [this] exact Iso.prod (e.counitIso.app c) (e.counitIso.app c)) @@ -104,7 +104,7 @@ set_option backward.isDefEq.respectTransparency false in instance [HasBinaryCoproducts C] : IsSiftedOrEmpty C := by constructor rintro ⟨c₁, c₂⟩ - haveI : _root_.Nonempty <| StructuredArrow (c₁, c₂) (diag C) := + have : _root_.Nonempty <| StructuredArrow (c₁, c₂) (diag C) := ⟨.mk ((coprod.inl : c₁ ⟶ c₁ ⨿ c₂), (coprod.inr : c₂ ⟶ c₁ ⨿ c₂))⟩ apply isConnected_of_zigzag rintro ⟨_, c, f⟩ ⟨_, c', g⟩ diff --git a/Mathlib/CategoryTheory/Limits/VanKampen.lean b/Mathlib/CategoryTheory/Limits/VanKampen.lean index 15d6a166144b66..2e0f4a851ceddb 100644 --- a/Mathlib/CategoryTheory/Limits/VanKampen.lean +++ b/Mathlib/CategoryTheory/Limits/VanKampen.lean @@ -68,7 +68,7 @@ noncomputable def IsUniversalColimit.isColimit {F : J ⥤ C} {c : Cocone F} (h : IsUniversalColimit c) : IsColimit c := by refine ((h c (𝟙 F) (𝟙 c.pt :) (by rw [Functor.map_id, Category.comp_id, Category.id_comp]) (.of_isIso _)) fun j => ?_).some - haveI : IsIso (𝟙 c.pt) := inferInstance + have : IsIso (𝟙 c.pt) := inferInstance exact IsPullback.of_vert_isIso ⟨by simp⟩ /-- A van Kampen colimit is a colimit. -/ @@ -82,7 +82,7 @@ theorem IsInitial.isVanKampenColimit [HasStrictInitialObjects C] {X : C} (h : Is intro F' c' α f hf hα have : F' = Functor.empty C := by apply Functor.hext <;> rintro ⟨⟨⟩⟩ subst this - haveI := h.isIso_to f + have := h.isIso_to f refine ⟨by rintro _ ⟨⟨⟩⟩, fun _ => ⟨IsColimit.ofIsoColimit h (Cocone.ext (asIso f).symm <| by rintro ⟨⟨⟩⟩)⟩⟩ @@ -109,7 +109,7 @@ theorem IsVanKampenColimit.of_iso {F : J ⥤ C} {c c' : Cocone F} (H : IsVanKamp apply forall_congr' intro j conv_lhs => rw [← Category.comp_id (α.app j)] - haveI : IsIso e.inv.hom := Functor.map_isIso (Cocone.forget _) e.inv + have : IsIso e.inv.hom := Functor.map_isIso (Cocone.forget _) e.inv exact (IsPullback.of_vert_isIso ⟨by simp⟩).paste_vert_iff (NatTrans.congr_app h j).symm set_option backward.isDefEq.respectTransparency false in @@ -279,7 +279,7 @@ theorem IsUniversalColimit.map_reflective intro X apply IsIso.eq_inv_of_inv_hom_id exact adj.left_triangle_components _ - haveI : ∀ X, IsIso (Gl.map (adj.unit.app X)) := by + have : ∀ X, IsIso (Gl.map (adj.unit.app X)) := by simp_rw [hadj] infer_instance have hα'' : ∀ j, Gl.map (Gr.map <| α'.app j) = adj.counit.app _ ≫ α.app j := by @@ -503,13 +503,13 @@ theorem BinaryCofan.isVanKampen_mk {X Y : C} (c : BinaryCofan X Y) obtain ⟨hl, hr⟩ := h₁ αX αY (e.inv ≫ f) (by simp [e, hX]) (by simp [e, hY]) constructor · rw [← Category.id_comp αX, ← Iso.hom_inv_id_assoc e f] - haveI : IsIso (𝟙 X') := inferInstance + have : IsIso (𝟙 X') := inferInstance have : c'.inl ≫ e.hom = 𝟙 X' ≫ (cofans X' Y').inl := by dsimp [e] simp exact (IsPullback.of_vert_isIso ⟨this⟩).paste_vert hl · rw [← Category.id_comp αY, ← Iso.hom_inv_id_assoc e f] - haveI : IsIso (𝟙 Y') := inferInstance + have : IsIso (𝟙 Y') := inferInstance have : c'.inr ≫ e.hom = 𝟙 Y' ≫ (cofans X' Y').inr := by dsimp [e] simp diff --git a/Mathlib/CategoryTheory/Localization/Adjunction.lean b/Mathlib/CategoryTheory/Localization/Adjunction.lean index d9ca2264034a1f..9c6875b1f54b96 100644 --- a/Mathlib/CategoryTheory/Localization/Adjunction.lean +++ b/Mathlib/CategoryTheory/Localization/Adjunction.lean @@ -56,7 +56,7 @@ lemma ε_app (X₁ : C₁) : (ε adj L₁ W₁ L₂ G' F').app (L₁.obj X₁) = L₁.map (adj.unit.app X₁) ≫ (CatCommSq.iso F L₂ L₁ F').hom.app (G.obj X₁) ≫ F'.map ((CatCommSq.iso G L₁ L₂ G').hom.app X₁) := by - letI : Lifting L₁ W₁ ((G ⋙ F) ⋙ L₁) (G' ⋙ F') := + let : Lifting L₁ W₁ ((G ⋙ F) ⋙ L₁) (G' ⋙ F') := Lifting.mk (CatCommSq.hComp G F L₁ L₂ L₁ G' F').iso.symm simp only [ε, liftNatTrans_app, Lifting.iso, Iso.symm, Functor.id_obj, Functor.comp_obj, Functor.rightUnitor_hom_app, @@ -74,7 +74,7 @@ lemma η_app (X₂ : C₂) : G'.map ((CatCommSq.iso F L₂ L₁ F').inv.app X₂) ≫ (CatCommSq.iso G L₁ L₂ G').inv.app (F.obj X₂) ≫ L₂.map (adj.counit.app X₂) := by - letI : Lifting L₂ W₂ ((F ⋙ G) ⋙ L₂) (F' ⋙ G') := + let : Lifting L₂ W₂ ((F ⋙ G) ⋙ L₂) (F' ⋙ G') := Lifting.mk (CatCommSq.hComp F G L₂ L₁ L₂ F' G').iso.symm simp only [η, liftNatTrans_app, Lifting.iso, Iso.symm, CatCommSq.hComp_iso_inv_app, whiskerRight_app, Functor.rightUnitor_inv_app, comp_id, assoc] diff --git a/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean b/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean index 74cf1be098c1f4..964a49b51ab50c 100644 --- a/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean +++ b/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean @@ -80,7 +80,7 @@ noncomputable def map (φ : W.LeftFraction X Y) (L : C ⥤ D) (hL : W.IsInverted @[reassoc (attr := simp)] lemma map_comp_map_s (φ : W.LeftFraction X Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) : φ.map L hL ≫ L.map φ.s = L.map φ.f := by - letI := hL _ φ.hs + let := hL _ φ.hs simp [map] variable (W) @@ -94,14 +94,14 @@ set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma map_ofInv_hom_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) : (ofInv s hs).map L hL ≫ L.map s = 𝟙 _ := by - letI := hL _ hs + let := hL _ hs simp [map] set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma map_hom_ofInv_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) : L.map s ≫ (ofInv s hs).map L hL = 𝟙 _ := by - letI := hL _ hs + let := hL _ hs simp [map] variable {W} @@ -155,7 +155,7 @@ noncomputable def map (φ : W.RightFraction X Y) (L : C ⥤ D) (hL : W.IsInverte @[reassoc (attr := simp)] lemma map_s_comp_map (φ : W.RightFraction X Y) (L : C ⥤ D) (hL : W.IsInvertedBy L) : L.map φ.s ≫ φ.map L hL = L.map φ.f := by - letI := hL _ φ.hs + let := hL _ φ.hs simp [map] variable (W) @@ -170,14 +170,14 @@ set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma map_ofInv_hom_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) : (ofInv s hs).map L hL ≫ L.map s = 𝟙 _ := by - letI := hL _ hs + let := hL _ hs simp [map] set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma map_hom_ofInv_id (s : Y ⟶ X) (hs : W s) (L : C ⥤ D) (hL : W.IsInvertedBy L) : L.map s ≫ (ofInv s hs).map L hL = 𝟙 _ := by - letI := hL _ hs + let := hL _ hs simp [map] variable {W} diff --git a/Mathlib/CategoryTheory/Localization/Construction.lean b/Mathlib/CategoryTheory/Localization/Construction.lean index 25bf8f4eb82a31..639507424e0f57 100644 --- a/Mathlib/CategoryTheory/Localization/Construction.lean +++ b/Mathlib/CategoryTheory/Localization/Construction.lean @@ -219,7 +219,7 @@ theorem morphismProperty_eq_top (P : MorphismProperty W.Localization) apply MorphismProperty.top_apply · intro let G : _ ⥤ W.Localization := Quotient.functor _ - haveI : G.Full := Quotient.full_functor _ + have : G.Full := Quotient.full_functor _ suffices ∀ (X₁ X₂ : Paths (LocQuiver W)) (f : X₁ ⟶ X₂), P (G.map f) by rcases X with ⟨⟨X⟩⟩ rcases Y with ⟨⟨Y⟩⟩ diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean index 77ffa0d7158fb2..0cc96c9149d8a3 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean @@ -71,8 +71,8 @@ lemma isLeftDerivabilityStructure_of_isLocalizedEquivalence hw := (W₂'.arrow_mk_iso_iff (Arrow.isoMk (iso.app _) e₂)).1 (R.map _ ρ.hw) }⟩ let F := B.localizedFunctor W₁'.Q W₂'.Q let e' := CatCommSq.iso B.functor W₁'.Q W₂'.Q F - letI iso' : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ - letI : CatCommSq T.functor (L.functor ⋙ W₁'.Q) (R.functor ⋙ W₂'.Q) F := + let iso' : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ + let : CatCommSq T.functor (L.functor ⋙ W₁'.Q) (R.functor ⋙ W₂'.Q) F := CatCommSq.vComp (H₂ := B.functor) _ _ _ _ _ _ have : (TwoSquare.hComp iso.inv e'.inv).GuitartExact := by convert! diff --git a/Mathlib/CategoryTheory/Localization/Equivalence.lean b/Mathlib/CategoryTheory/Localization/Equivalence.lean index dd2c17808661b4..826484251ba969 100644 --- a/Mathlib/CategoryTheory/Localization/Equivalence.lean +++ b/Mathlib/CategoryTheory/Localization/Equivalence.lean @@ -108,7 +108,7 @@ lemma of_equivalences (L₁ : C₁ ⥤ D₁) (W₁ : MorphismProperty C₁) [L (E : C₁ ≌ C₂) (E' : D₁ ≌ D₂) [CatCommSq E.functor L₁ L₂ E'.functor] (hW₁ : W₁ ≤ W₂.isoClosure.inverseImage E.functor) (hW₂ : W₂.IsInvertedBy L₂) : L₂.IsLocalization W₂ := by - haveI : (E.functor ⋙ L₂).IsLocalization W₁ := + have : (E.functor ⋙ L₂).IsLocalization W₁ := of_equivalence_target L₁ W₁ _ E' ((CatCommSq.iso _ _ _ _).symm) exact of_equivalence_source (E.functor ⋙ L₂) W₁ L₂ W₂ E hW₁ hW₂ (Iso.refl _) diff --git a/Mathlib/CategoryTheory/Localization/HomEquiv.lean b/Mathlib/CategoryTheory/Localization/HomEquiv.lean index b77ff45803589b..6a6c9df9dff9ae 100644 --- a/Mathlib/CategoryTheory/Localization/HomEquiv.lean +++ b/Mathlib/CategoryTheory/Localization/HomEquiv.lean @@ -77,7 +77,7 @@ lemma homMap_apply (G : D₁ ⥤ D₂) (e : Φ.functor ⋙ L₂ ≅ L₁ ⋙ G) let G' := Φ.localizedFunctor L₁ L₂ let e' := CatCommSq.iso Φ.functor L₁ L₂ G' change e'.hom.app X ≫ G'.map f ≫ e'.inv.app Y = _ - letI : Localization.Lifting L₁ W₁ (Φ.functor ⋙ L₂) G := ⟨e.symm⟩ + let : Localization.Lifting L₁ W₁ (Φ.functor ⋙ L₂) G := ⟨e.symm⟩ let α : G' ≅ G := Localization.liftNatIso L₁ W₁ (L₁ ⋙ G') (Φ.functor ⋙ L₂) _ _ e'.symm have : e = e' ≪≫ Functor.isoWhiskerLeft _ α := by ext diff --git a/Mathlib/CategoryTheory/Localization/Linear.lean b/Mathlib/CategoryTheory/Localization/Linear.lean index 4accef731aee7e..f190e5f4ede621 100644 --- a/Mathlib/CategoryTheory/Localization/Linear.lean +++ b/Mathlib/CategoryTheory/Localization/Linear.lean @@ -41,7 +41,7 @@ noncomputable def linear : Linear R D := Linear.ofRingMorphism lemma functor_linear : letI := linear R L W Functor.Linear R L := by - letI := linear R L W + let := linear R L W constructor intro X Y f r change L.map (r • f) = ((Linear.toCatCenter R C r).localization L W).app (L.obj X) ≫ L.map f diff --git a/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean b/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean index 2be304d60b9ec4..c169d37975d6ba 100644 --- a/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean +++ b/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean @@ -183,7 +183,7 @@ lemma isEquivalence [h : Φ.IsLocalizedEquivalence] [CatCommSq Φ.functor L₁ L instance [Φ.IsLocalizedEquivalence] : Φ.op.IsLocalizedEquivalence := by let G := Φ.localizedFunctor W₁.Q W₂.Q - letI : CatCommSq Φ.op.functor W₁.Q.op W₂.Q.op G.op := + let : CatCommSq Φ.op.functor W₁.Q.op W₂.Q.op G.op := ⟨NatIso.op (CatCommSq.iso Φ.functor W₁.Q W₂.Q G).symm⟩ have := Φ.isEquivalence W₁.Q W₂.Q G exact IsLocalizedEquivalence.mk' Φ.op W₁.Q.op W₂.Q.op G.op @@ -208,7 +208,7 @@ an equivalence of categories and that `W₁` and `W₂` essentially correspond t other via this equivalence, then `Φ` is a localized equivalence. -/ lemma IsLocalizedEquivalence.of_equivalence [Φ.functor.IsEquivalence] (h : W₂ ≤ W₁.map Φ.functor) : IsLocalizedEquivalence Φ := by - haveI : Functor.IsLocalization (Φ.functor ⋙ MorphismProperty.Q W₂) W₁ := by + have : Functor.IsLocalization (Φ.functor ⋙ MorphismProperty.Q W₂) W₁ := by refine Functor.IsLocalization.of_equivalence_source W₂.Q W₂ (Φ.functor ⋙ W₂.Q) W₁ (asEquivalence Φ.functor).symm ?_ (Φ.inverts W₂.Q) ((associator _ _ _).symm ≪≫ isoWhiskerRight ((Equivalence.unitIso _).symm) _ ≪≫ @@ -305,7 +305,7 @@ instance [Φ.IsLocalizedFullyFaithful] : (Φ.localizedFunctor L₁ L₂).Faithfu instance [Φ.IsLocalizedFullyFaithful] : Φ.op.IsLocalizedFullyFaithful := by let G := Φ.localizedFunctor W₁.Q W₂.Q - letI : CatCommSq Φ.op.functor W₁.Q.op W₂.Q.op G.op := + let : CatCommSq Φ.op.functor W₁.Q.op W₂.Q.op G.op := ⟨NatIso.op (CatCommSq.iso Φ.functor W₁.Q W₂.Q G).symm⟩ exact IsLocalizedFullyFaithful.mk' Φ.op W₁.Q.op W₂.Q.op G.op (Φ.fullyFaithful W₁.Q W₂.Q G).op @@ -328,7 +328,7 @@ lemma isLocalization_of_isLocalizedFullyFaithful (Arrow.isoOfNatIso iso f)).1 (Localization.inverts L₂ W₂ _ (Φ.map _ hf)) let G := Localization.lift L₁ h W₁.Q let e : W₁.Q ⋙ G ≅ L₁ := Localization.fac L₁ h W₁.Q - letI : CatCommSq Φ.functor W₁.Q L₂ (G ⋙ F) := + let : CatCommSq Φ.functor W₁.Q L₂ (G ⋙ F) := ⟨iso ≪≫ isoWhiskerRight e.symm _ ≪≫ associator _ _ _⟩ have hG : G.FullyFaithful := Functor.FullyFaithful.ofCompFaithful (Φ.fullyFaithful W₁.Q L₂ (G ⋙ F)) diff --git a/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean index 5fa9970fc17379..5c493fa695cb7c 100644 --- a/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean @@ -156,7 +156,7 @@ transformation. instance lifting_isMonoidal : letI : F.Monoidal := functorMonoidalOfComp L W F G (Lifting.iso L W G F).hom.IsMonoidal := by - letI : F.Monoidal := functorMonoidalOfComp L W F G + let : F.Monoidal := functorMonoidalOfComp L W F G refine ⟨?_, fun _ _ ↦ ?_⟩ · simp [functorMonoidalOfComp_ε] · simp [functorMonoidalOfComp_μ] diff --git a/Mathlib/CategoryTheory/Localization/Pi.lean b/Mathlib/CategoryTheory/Localization/Pi.lean index 2c5c8a508c3ec2..5d4d0ffcce0cb3 100644 --- a/Mathlib/CategoryTheory/Localization/Pi.lean +++ b/Mathlib/CategoryTheory/Localization/Pi.lean @@ -39,7 +39,7 @@ instance pi {J : Type w} [Finite J] {C : J → Type u₁} {D : J → Type u₂} let L₁ := fun j => (L₂ (e j)) let E := Pi.equivalenceOfEquiv C₂ e let E' := Pi.equivalenceOfEquiv D₂ e - haveI : CatCommSq E.functor (Functor.pi L₁) (Functor.pi L₂) E'.functor := + have : CatCommSq E.functor (Functor.pi L₁) (Functor.pi L₂) E'.functor := (CatCommSq.hInvEquiv E (Functor.pi L₁) (Functor.pi L₂) E').symm ⟨Iso.refl _⟩ refine IsLocalization.of_equivalences (Functor.pi L₁) (MorphismProperty.pi (fun j => (W₂ (e j)))) (Functor.pi L₂) @@ -53,13 +53,13 @@ instance pi {J : Type w} [Finite J] {C : J → Type u₁} {D : J → Type u₂} exact hg exact H (e.apply_symm_apply i) _ (hf (e.symm i)) · intro C D _ _ L W _ _ - haveI : ∀ j, IsEquivalence (L j) := by rintro ⟨⟩ + have : ∀ j, IsEquivalence (L j) := by rintro ⟨⟩ refine IsLocalization.of_isEquivalence _ _ (fun _ _ _ _ => ?_) rw [MorphismProperty.isomorphisms.iff, isIso_pi_iff] rintro ⟨⟩ · intro J _ hJ C D _ _ L W _ _ let L₁ := (L none).prod (Functor.pi (fun j => L (some j))) - haveI : CatCommSq (Pi.optionEquivalence C).symm.functor L₁ (Functor.pi L) + have : CatCommSq (Pi.optionEquivalence C).symm.functor L₁ (Functor.pi L) (Pi.optionEquivalence D).symm.functor := ⟨NatIso.pi' (by rintro (_ | i) <;> apply Iso.refl)⟩ refine IsLocalization.of_equivalences L₁ diff --git a/Mathlib/CategoryTheory/Localization/Predicate.lean b/Mathlib/CategoryTheory/Localization/Predicate.lean index c882cb52d75bcb..312e74a3cf0c8f 100644 --- a/Mathlib/CategoryTheory/Localization/Predicate.lean +++ b/Mathlib/CategoryTheory/Localization/Predicate.lean @@ -285,7 +285,7 @@ variable {E} theorem natTrans_ext (L : C ⥤ D) (W) [L.IsLocalization W] {F₁ F₂ : D ⥤ E} {τ τ' : F₁ ⟶ F₂} (h : ∀ X : C, τ.app (L.obj X) = τ'.app (L.obj X)) : τ = τ' := by - haveI := essSurj L W + have := essSurj L W ext Y rw [← cancel_epi (F₁.map (L.objObjPreimageIso Y).hom), τ.naturality, τ'.naturality, h] @@ -422,7 +422,7 @@ instance (F : D ⥤ E) [F.IsEquivalence] [L.IsLocalization W] : lemma of_isEquivalence (L : C ⥤ D) (W : MorphismProperty C) (hW : W ≤ MorphismProperty.isomorphisms C) [IsEquivalence L] : L.IsLocalization W := by - haveI : (𝟭 C).IsLocalization W := for_id W hW + have : (𝟭 C).IsLocalization W := for_id W hW exact of_equivalence_target (𝟭 C) W L L.asEquivalence L.leftUnitor end IsLocalization diff --git a/Mathlib/CategoryTheory/Localization/Prod.lean b/Mathlib/CategoryTheory/Localization/Prod.lean index 8668c963f58658..f4835488c1efec 100644 --- a/Mathlib/CategoryTheory/Localization/Prod.lean +++ b/Mathlib/CategoryTheory/Localization/Prod.lean @@ -62,7 +62,7 @@ noncomputable def prodLift₁ [W₂.ContainsIdentities] (hF : (W₁.prod W₂).IsInvertedBy F) : W₁.Localization ⥤ C₂ ⥤ E := Construction.lift (curry.obj F) (fun _ _ f₁ hf₁ => by - haveI : ∀ (X₂ : C₂), IsIso (((curry.obj F).map f₁).app X₂) := + have : ∀ (X₂ : C₂), IsIso (((curry.obj F).map f₁).app X₂) := fun X₂ => hF _ ⟨hf₁, MorphismProperty.id_mem _ _⟩ apply NatIso.isIso_of_isIso_app) @@ -80,7 +80,7 @@ noncomputable def prodLift : W₁.Localization × W₂.Localization ⥤ E := by refine uncurry.obj (Construction.lift (prodLift₁ F hF).flip ?_).flip intro _ _ f₂ hf₂ - haveI : ∀ (X₁ : W₁.Localization), + have : ∀ (X₁ : W₁.Localization), IsIso (((Functor.flip (prodLift₁ F hF)).map f₂).app X₁) := fun X₁ => by obtain ⟨X₁, rfl⟩ := (Construction.objEquiv W₁).surjective X₁ exact ((MorphismProperty.isomorphisms E).arrow_mk_iso_iff @@ -138,7 +138,7 @@ and if both `W₁` and `W₂` contain identities, then the product functor `L₁.prod L₂ : C₁ × C₂ ⥤ D₁ × D₂` is a localization functor for `W₁.prod W₂`. -/ instance prod [L₁.IsLocalization W₁] [L₂.IsLocalization W₂] : (L₁.prod L₂).IsLocalization (W₁.prod W₂) := by - haveI := Construction.prodIsLocalization W₁ W₂ + have := Construction.prodIsLocalization W₁ W₂ exact of_equivalence_target (W₁.Q.prod W₂.Q) (W₁.prod W₂) (L₁.prod L₂) ((uniq W₁.Q L₁ W₁).prod (uniq W₂.Q L₂ W₂)) (NatIso.prod (compUniqFunctor W₁.Q L₁ W₁) (compUniqFunctor W₂.Q L₂ W₂)) diff --git a/Mathlib/CategoryTheory/Localization/Resolution.lean b/Mathlib/CategoryTheory/Localization/Resolution.lean index b8f5c6f731127f..33c4e815e81fc6 100644 --- a/Mathlib/CategoryTheory/Localization/Resolution.lean +++ b/Mathlib/CategoryTheory/Localization/Resolution.lean @@ -389,7 +389,7 @@ lemma hasRightResolutions_arrow_of_essSurj_of_full [R.functor.EssSurj] [R.functor.Full] [W₂'.RespectsIso] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) [T.arrow.HasRightResolutions] : B.arrow.HasRightResolutions := by - letI : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ + let : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ exact hasRightResolutions_of_iso_of_essSurj (CatCommSq.iso T.arrow.functor L.arrow.functor R.arrow.functor B.arrow.functor) @@ -397,7 +397,7 @@ lemma hasLeftResolutions_arrow_of_essSurj_of_full [R.functor.EssSurj] [R.functor.Full] [W₂'.RespectsIso] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) [T.arrow.HasLeftResolutions] : B.arrow.HasLeftResolutions := by - letI : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ + let : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ exact hasLeftResolutions_of_iso_of_essSurj (CatCommSq.iso T.arrow.functor L.arrow.functor R.arrow.functor B.arrow.functor) @@ -405,7 +405,7 @@ lemma hasRightResolutions_arrow_iff_of_equivalences [R.functor.IsEquivalence] [R.IsInduced] [L.functor.IsEquivalence] [W₂'.RespectsIso] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) : T.arrow.HasRightResolutions ↔ B.arrow.HasRightResolutions := by - letI : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ + let : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ exact hasRightResolutions_iff_iso_of_essSurj_of_full (CatCommSq.iso T.arrow.functor L.arrow.functor R.arrow.functor B.arrow.functor) @@ -413,7 +413,7 @@ lemma hasLeftResolutions_arrow_iff_of_equivalences [R.functor.IsEquivalence] [R.IsInduced] [L.functor.IsEquivalence] [W₂'.RespectsIso] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) : T.arrow.HasLeftResolutions ↔ B.arrow.HasLeftResolutions := by - letI : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ + let : CatCommSq T.functor L.functor R.functor B.functor := ⟨iso⟩ exact hasLeftResolutions_iff_iso_of_essSurj_of_full (CatCommSq.iso T.arrow.functor L.arrow.functor R.arrow.functor B.arrow.functor) diff --git a/Mathlib/CategoryTheory/Localization/SmallHom.lean b/Mathlib/CategoryTheory/Localization/SmallHom.lean index 4f51495bb7d588..dac9d35fa0eb80 100644 --- a/Mathlib/CategoryTheory/Localization/SmallHom.lean +++ b/Mathlib/CategoryTheory/Localization/SmallHom.lean @@ -163,8 +163,8 @@ lemma equiv_comp (L : C ⥤ D) [L.IsLocalization W] {X Y Z : C} [HasSmallLocaliz [HasSmallLocalizedHom.{w} W Y Z] [HasSmallLocalizedHom.{w} W X Z] (α : SmallHom.{w} W X Y) (β : SmallHom.{w} W Y Z) : equiv W L (α.comp β) = equiv W L α ≫ equiv W L β := by - letI := small_of_hasSmallLocalizedHom.{w} W W.Q X Y - letI := small_of_hasSmallLocalizedHom.{w} W W.Q Y Z + let := small_of_hasSmallLocalizedHom.{w} W W.Q X Y + let := small_of_hasSmallLocalizedHom.{w} W W.Q Y Z obtain ⟨α, rfl⟩ := (equivShrink _).surjective α obtain ⟨β, rfl⟩ := (equivShrink _).surjective β dsimp [equiv, comp] diff --git a/Mathlib/CategoryTheory/Monad/Comonadicity.lean b/Mathlib/CategoryTheory/Monad/Comonadicity.lean index 70e929cac334bb..d609e4248e6660 100644 --- a/Mathlib/CategoryTheory/Monad/Comonadicity.lean +++ b/Mathlib/CategoryTheory/Monad/Comonadicity.lean @@ -302,7 +302,7 @@ def comonadicOfHasPreservesReflectsFSplitEqualizers [HasEqualizerOfIsCosplitPair change IsIso (IsLimit.conePointUniqueUpToIso _ ?_).inv · infer_instance apply @unitEqualizerOfCoreflectsEqualizer _ _ _ _ _ _ _ _ ?_ - letI _ : + let _ : F.IsCosplitPair (G.map (F.map (adj.unit.app Y))) (adj.unit.app (G.obj (F.obj Y))) := ComonadicityInternal.main_pair_F_cosplit _ ((comparison adj).obj Y) diff --git a/Mathlib/CategoryTheory/Monad/Limits.lean b/Mathlib/CategoryTheory/Monad/Limits.lean index e74d2fc24dc126..06482610e5a70a 100644 --- a/Mathlib/CategoryTheory/Monad/Limits.lean +++ b/Mathlib/CategoryTheory/Monad/Limits.lean @@ -352,7 +352,7 @@ theorem hasColimitsOfShape_of_reflective (R : D ⥤ C) [Reflective R] [HasColimi HasColimitsOfShape J D where has_colimit := fun F => by let c := (monadicLeftAdjoint R).mapCocone (colimit.cocone (F ⋙ R)) - letI : PreservesColimitsOfShape J _ := + let : PreservesColimitsOfShape J _ := (monadicAdjunction R).leftAdjoint_preservesColimits.1 let t : IsColimit c := isColimitOfPreserves (monadicLeftAdjoint R) (colimit.isColimit _) apply HasColimit.mk ⟨_, (IsColimit.precomposeInvEquiv _ _).symm t⟩ @@ -371,11 +371,11 @@ lemma leftAdjoint_preservesTerminal_of_reflective (R : D ⥤ C) [Reflective R] : PreservesLimitsOfShape (Discrete.{v} PEmpty) (monadicLeftAdjoint R) where preservesLimit {K} := by let F := Functor.empty.{v} D - letI : PreservesLimit (F ⋙ R) (monadicLeftAdjoint R) := by + let : PreservesLimit (F ⋙ R) (monadicLeftAdjoint R) := by constructor intro c h - haveI : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩ - haveI : HasLimit F := hasLimit_of_reflective F R + have : HasLimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩ + have : HasLimit F := hasLimit_of_reflective F R constructor apply isLimitChangeEmptyCone D (limit.isLimit F) apply (asIso ((monadicAdjunction R).counit.app _)).symm.trans @@ -681,7 +681,7 @@ theorem hasLimitsOfShape_of_coreflective (R : D ⥤ C) [Coreflective R] [HasLimi HasLimitsOfShape J D where has_limit := fun F => by let c := (comonadicRightAdjoint R).mapCone (limit.cone (F ⋙ R)) - letI : PreservesLimitsOfShape J _ := + let : PreservesLimitsOfShape J _ := (comonadicAdjunction R).rightAdjoint_preservesLimits.1 let t : IsLimit c := isLimitOfPreserves (comonadicRightAdjoint R) (limit.isLimit _) apply HasLimit.mk ⟨_, (IsLimit.postcomposeHomEquiv _ _).symm t⟩ @@ -700,11 +700,11 @@ lemma rightAdjoint_preservesInitial_of_coreflective (R : D ⥤ C) [Coreflective PreservesColimitsOfShape (Discrete.{v} PEmpty) (comonadicRightAdjoint R) where preservesColimit {K} := by let F := Functor.empty.{v} D - letI : PreservesColimit (F ⋙ R) (comonadicRightAdjoint R) := by + let : PreservesColimit (F ⋙ R) (comonadicRightAdjoint R) := by constructor intro c h - haveI : HasColimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩ - haveI : HasColimit F := hasColimit_of_coreflective F R + have : HasColimit (F ⋙ R) := ⟨⟨⟨c, h⟩⟩⟩ + have : HasColimit F := hasColimit_of_coreflective F R constructor apply isColimitChangeEmptyCocone D (colimit.isColimit F) apply (asIso ((comonadicAdjunction R).unit.app _)).trans diff --git a/Mathlib/CategoryTheory/Monad/Monadicity.lean b/Mathlib/CategoryTheory/Monad/Monadicity.lean index 1fc4d6a64f9c32..1c7aa77231f9a3 100644 --- a/Mathlib/CategoryTheory/Monad/Monadicity.lean +++ b/Mathlib/CategoryTheory/Monad/Monadicity.lean @@ -319,7 +319,7 @@ def monadicOfHasPreservesReflectsGSplitCoequalizers [HasCoequalizerOfIsSplitPair · infer_instance -- Porting note: passing instances through apply @counitCoequalizerOfReflectsCoequalizer _ _ _ _ _ _ _ _ ?_ - letI _ : + let _ : G.IsSplitPair (F.map (G.map (adj.counit.app Y))) (adj.counit.app (F.obj (G.obj Y))) := MonadicityInternal.main_pair_G_split _ ((comparison adj).obj Y) diff --git a/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean b/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean index ffd1a2eb940b39..b71d35582b3161 100644 --- a/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean +++ b/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean @@ -135,7 +135,7 @@ def oppositeLeftAction [MonoidalLeftAction C D] : actionAssocIso_hom_naturality | op f, op g, op h => by apply Quiver.Hom.unop_inj - haveI := (αₗ (unop _) (unop _) (unop _)).inv ≫= + have := (αₗ (unop _) (unop _) (unop _)).inv ≫= MonoidalLeftAction.actionAssocIso_hom_naturality f g h simp only [Iso.inv_hom_id_assoc] at this simp [← this] @@ -175,7 +175,7 @@ def leftActionOfOppositeLeftAction [MonoidalLeftAction Cᵒᵖ Dᵒᵖ] : MonoidalLeftAction.actionHom_def f.op g.op actionAssocIso_hom_naturality f g h := by apply Quiver.Hom.op_inj - haveI := (αₗ (op _) (op _) (op _)).inv ≫= + have := (αₗ (op _) (op _) (op _)).inv ≫= MonoidalLeftAction.actionAssocIso_hom_naturality f.op g.op h.op simp only [Iso.inv_hom_id_assoc] at this simp [← this] @@ -347,7 +347,7 @@ def oppositeRightAction [MonoidalRightAction C D] : actionAssocIso_hom_naturality | op f, op g, op h => by apply Quiver.Hom.unop_inj - haveI := (αᵣ (unop _) (unop _) (unop _)).inv ≫= + have := (αᵣ (unop _) (unop _) (unop _)).inv ≫= MonoidalRightAction.actionAssocIso_hom_naturality f g h simp only [Iso.inv_hom_id_assoc] at this simp [← this] @@ -387,7 +387,7 @@ def rightActionOfOppositeRightAction [MonoidalRightAction Cᵒᵖ Dᵒᵖ] : MonoidalRightAction.actionHom_def f.op g.op actionAssocIso_hom_naturality f g h := by apply Quiver.Hom.op_inj - haveI := (αᵣ (op _) (op _) (op _)).inv ≫= + have := (αᵣ (op _) (op _) (op _)).inv ≫= MonoidalRightAction.actionAssocIso_hom_naturality f.op g.op h.op simp only [Iso.inv_hom_id_assoc] at this simp [← this] diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean index b02b3fafc21679..198b65045a1c60 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean @@ -688,12 +688,12 @@ theorem prodComparisonBifunctorNatTrans_comp : prodComparisonBifunctorNatTrans ( ext; simp [prodComparison_comp] instance (A : C) [∀ B, IsIso (prodComparison F A B)] : IsIso (prodComparisonNatTrans F A) := by - letI : ∀ X, IsIso ((prodComparisonNatTrans F A).app X) := by assumption + let : ∀ X, IsIso ((prodComparisonNatTrans F A).app X) := by assumption apply NatIso.isIso_of_isIso_app set_option backward.defeqAttrib.useBackward true in instance [∀ A B, IsIso (prodComparison F A B)] : IsIso (prodComparisonBifunctorNatTrans F) := by - letI : ∀ X, IsIso ((prodComparisonBifunctorNatTrans F).app X) := + let : ∀ X, IsIso ((prodComparisonBifunctorNatTrans F).app X) := fun _ ↦ by dsimp; apply NatIso.isIso_of_isIso_app apply NatIso.isIso_of_isIso_app diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/CommMon_.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/CommMon_.lean index df898edd0bd41f..b8c8c1b9e0505d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/CommMon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/CommMon_.lean @@ -26,7 +26,7 @@ variable (X) in lemma IsCommMonObj.ofRepresentableBy (F : Cᵒᵖ ⥤ CommMonCat) (α : (F ⋙ forget _).RepresentableBy X) : letI : MonObj X := .ofRepresentableBy X (F ⋙ forget₂ CommMonCat MonCat) α IsCommMonObj X := by - letI : MonObj X := .ofRepresentableBy X (F ⋙ forget₂ CommMonCat MonCat) α + let : MonObj X := .ofRepresentableBy X (F ⋙ forget₂ CommMonCat MonCat) α have : μ = α.homEquiv'.symm (α.homEquiv' (fst X X) * α.homEquiv' (snd X X)) := rfl constructor simp_rw [this, ← α.homEquiv'.apply_eq_iff_eq, α.homEquiv'_comp, diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean index 81119fa7777267..29c9809982535a 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean @@ -148,7 +148,7 @@ instance {K : Type*} [Category* K] [HasColimitsOfShape K C] PreservesColimitsOfShape K (tensorLeft F) := by apply preservesColimitsOfShape_of_evaluation intro k - haveI : tensorLeft F ⋙ (evaluation J C).obj k ≅ (evaluation J C).obj k ⋙ tensorLeft (F.obj k) := + have : tensorLeft F ⋙ (evaluation J C).obj k ≅ (evaluation J C).obj k ⋙ tensorLeft (F.obj k) := NatIso.ofComponents (fun _ ↦ Iso.refl _) exact preservesColimitsOfShape_of_natIso this.symm diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean index 369d70592156be..fdff0703d10af5 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean @@ -148,7 +148,7 @@ lemma essImage_yonedaGrp : · rintro ⟨G, ⟨α⟩⟩ exact ⟨G.X, ⟨Functor.representableByEquiv.symm (Functor.isoWhiskerRight α (forget _))⟩⟩ · rintro ⟨X, ⟨e⟩⟩ - letI := GrpObj.ofRepresentableBy X F e + let := GrpObj.ofRepresentableBy X F e exact ⟨⟨X⟩, ⟨yonedaGrpObjIsoOfRepresentableBy X F e⟩⟩ @[to_additive (attr := reassoc)] diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean index d006a8456885bd..6e548c09b5da89 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean @@ -417,7 +417,7 @@ lemma essImage_yonedaMon : · rintro ⟨M, ⟨α⟩⟩ exact ⟨M.X, ⟨Functor.representableByEquiv.symm (Functor.isoWhiskerRight α (forget _))⟩⟩ · rintro ⟨X, ⟨e⟩⟩ - letI := MonObj.ofRepresentableBy X F e + let := MonObj.ofRepresentableBy X F e exact ⟨Mon.mk X, ⟨yonedaMonObjIsoOfRepresentableBy X F e⟩⟩ @[to_additive (attr := reassoc (attr := simp))] diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean index 02f96505e73e9e..bcc03e4a3b0405 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean @@ -115,10 +115,10 @@ This actually shows a slightly stronger version: any morphism to an initial obje exponentiable object is an isomorphism. -/ theorem strict_initial {I : C} (t : IsInitial I) (f : A ⟶ I) : IsIso f := by - haveI : Mono f := by + have : Mono f := by rw [← lift_snd (𝟙 A) f, ← zeroMul_hom t] exact mono_comp _ _ - haveI : IsSplitEpi f := IsSplitEpi.mk' ⟨t.to _, t.hom_ext _ _⟩ + have : IsSplitEpi f := IsSplitEpi.mk' ⟨t.to _, t.hom_ext _ _⟩ apply isIso_of_mono_of_isSplitEpi instance to_initial_isIso [HasInitial C] (f : A ⟶ ⊥_ C) : IsIso f := @@ -127,8 +127,8 @@ instance to_initial_isIso [HasInitial C] (f : A ⟶ ⊥_ C) : IsIso f := /-- If an initial object `0` exists in a CCC then every morphism from it is monic. -/ theorem initial_mono {I : C} (B : C) (t : IsInitial I) [MonoidalClosed C] : Mono (t.to B) := ⟨fun g h _ => by - haveI := strict_initial t g - haveI := strict_initial t h + have := strict_initial t g + have := strict_initial t h exact eq_of_inv_eq_inv (t.hom_ext _ _)⟩ instance Initial.mono_to [HasInitial C] (B : C) [MonoidalClosed C] : Mono (initial.to B) := diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean index 7f13bdcd60cb0a..70d9ed282599c7 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean @@ -147,7 +147,7 @@ abbrev CartesianMonoidalCategory.ofReflective [CartesianMonoidalCategory C] [Ref · change (reflector i ⋙ i).obj (i.obj X ⊗ i.obj Y) ≅ (𝟭 C).obj (i.obj X ⊗ i.obj Y) letI : IsIso ((reflectorAdjunction i).unit.app (i.obj X ⊗ i.obj Y)) := by apply Functor.essImage.unit_isIso - haveI := reflective_products i + have := reflective_products i use Limits.prod X Y constructor apply Limits.PreservesLimitPair.iso i _ _ |>.trans @@ -187,7 +187,7 @@ instance (priority := 10) exponentialIdeal_of_preservesBinaryProducts prodComparison_natural_whiskerLeft_assoc, ← whiskerLeft_comp_assoc, ir.left_triangle_components, whiskerLeft_id, Category.id_comp] apply IsIso.hom_inv_id_assoc - haveI : IsSplitMono (η.app (A ⟹ i.obj B)) := IsSplitMono.mk' ⟨_, this⟩ + have : IsSplitMono (η.app (A ⟹ i.obj B)) := IsSplitMono.mk' ⟨_, this⟩ apply mem_essImage_of_unit_isSplitMono variable [ExponentialIdeal i] diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean index a1f3dfdb59c13e..c5771c09092832 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean @@ -1004,23 +1004,23 @@ def monoidalOfLawfulDayConvolutionMonoidalCategoryStruct simp only [Functor.map_comp, Functor.map_id, ι_map_tensorHom_hom_eq_tensorHom, ι_map_associator_hom_eq_associator_hom] -- this is a bit painful... - letI : DayConvolution + let : DayConvolution (((ι C V D |>.obj a) ⊛ (ι C V D |>.obj b)) ⊛ (ι C V D |>.obj c)) (ι C V D |>.obj d) := convolution C V D _ _ - letI : DayConvolution + let : DayConvolution ((ι C V D |>.obj a) ⊛ (ι C V D |>.obj b)) ((ι C V D |>.obj c) ⊛ (ι C V D |>.obj d)) := convolution C V D _ _ - letI : DayConvolution + let : DayConvolution ((ι C V D |>.obj a) ⊛ ((ι C V D |>.obj b) ⊛ (ι C V D |>.obj c))) (ι C V D |>.obj d) := convolution C V D _ _ - letI : DayConvolution + let : DayConvolution (ι C V D |>.obj a) ((ι C V D |>.obj b) ⊛ ((ι C V D |>.obj c) ⊛ (ι C V D |>.obj d))) := convolution C V D _ _ - letI : DayConvolution + let : DayConvolution (ι C V D |>.obj a) (((ι C V D |>.obj b) ⊛ (ι C V D |>.obj c)) ⊛ (ι C V D |>.obj d)) := convolution C V D _ _ @@ -1232,9 +1232,9 @@ def mkLawfulDayConvolutionMonoidalCategoryStruct : associator_hom_unit_unit d₁ d₂ d₃ x₁ x₂ x₃ := by simp only [externalProductBifunctor_obj_obj, Functor.comp_obj, tensor_obj, associator, Functor.FullyFaithful.preimageIso_hom, Functor.FullyFaithful.map_preimage] - letI : DayConvolution (ι C V D |>.obj d₁) ((ι C V D |>.obj d₂) ⊛ (ι C V D |>.obj d₃)) := + let : DayConvolution (ι C V D |>.obj d₁) ((ι C V D |>.obj d₂) ⊛ (ι C V D |>.obj d₃)) := convolutions C V _ _ - letI : DayConvolution ((ι C V D |>.obj d₁) ⊛ (ι C V D |>.obj d₂)) (ι C V D |>.obj d₃) := + let : DayConvolution ((ι C V D |>.obj d₁) ⊛ (ι C V D |>.obj d₂)) (ι C V D |>.obj d₃) := convolutions C V _ _ apply DayConvolution.associator_hom_unit_unit leftUnitor_hom_unit_app _ _ := by diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution/Braided.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution/Braided.lean index 801982829465fa..9d96cdbb66f7fb 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution/Braided.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution/Braided.lean @@ -157,7 +157,7 @@ lemma hexagon_forward (H : C ⥤ V) externalProductBifunctor_obj_obj, unit_app_map_app_assoc, NatTrans.id_app, id_tensorHom] rw [← BraidedCategory.hexagon_reverse, ← whiskerLeft_comp_assoc] - haveI := unit_app_braiding_hom_app F H x z =≫ (H ⊛ F).map (β_ z x).inv + have := unit_app_braiding_hom_app F H x z =≫ (H ⊛ F).map (β_ z x).inv dsimp at this simp only [Category.assoc, Iso.map_hom_inv_id, Category.comp_id] at this rw [← this, whiskerLeft_comp_assoc] @@ -197,7 +197,7 @@ lemma hexagon_reverse (H : C ⥤ V) unit_app_map_app_assoc, NatTrans.id_app, tensorHom_id] congr 2 rw [← BraidedCategory.hexagon_forward, ← comp_whiskerRight_assoc] - haveI := unit_app_braiding_hom_app F H x z =≫ (H ⊛ F).map (β_ z x).inv + have := unit_app_braiding_hom_app F H x z =≫ (H ⊛ F).map (β_ z x).inv dsimp at this simp only [Category.assoc, Iso.map_hom_inv_id, Category.comp_id] at this rw [← this, comp_whiskerRight_assoc] diff --git a/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean b/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean index a3e22d97ec9d8a..8e95ecf5431765 100644 --- a/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean +++ b/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean @@ -63,7 +63,7 @@ def isPointwiseLeftKanExtensionAtExtensionUnitLeft (prod.rightUnitorEquivalence (CostructuredArrow L d)).inverse ⋙ (𝟭 _).prod (Functor.fromPUnit.{0} <| .mk <| 𝟙 _) letI : I.Final := by - letI : Functor.fromPUnit.{0} (.mk (𝟙 e) : CostructuredArrow (𝟭 E) e) |>.Final := + let : Functor.fromPUnit.{0} (.mk (𝟙 e) : CostructuredArrow (𝟭 E) e) |>.Final := Functor.final_fromPUnit_of_isTerminal <| CostructuredArrow.mkIdTerminal (S := 𝟭 E) (Y := e) apply Iff.mp <| Functor.final_iff_final_comp (F := (prod.rightUnitorEquivalence <| CostructuredArrow L d).inverse) @@ -111,7 +111,7 @@ def isPointwiseLeftKanExtensionAtExtensionUnitRight (prod.leftUnitorEquivalence <| CostructuredArrow L d).inverse ⋙ (Functor.fromPUnit.{0} <| .mk <| 𝟙 _).prod (𝟭 _) letI : I.Final := by - letI : Functor.fromPUnit.{0} (.mk (𝟙 e) : CostructuredArrow (𝟭 E) e) |>.Final := + let : Functor.fromPUnit.{0} (.mk (𝟙 e) : CostructuredArrow (𝟭 E) e) |>.Final := Functor.final_fromPUnit_of_isTerminal <| CostructuredArrow.mkIdTerminal (S := 𝟭 E) (Y := e) apply Iff.mp <| Functor.final_iff_final_comp (F := (prod.leftUnitorEquivalence <| CostructuredArrow L d).inverse) diff --git a/Mathlib/CategoryTheory/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Functor.lean index 41ce57b77f91ea..08dc1192c212ce 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor.lean @@ -924,7 +924,7 @@ def rightAdjointLaxMonoidal : G.LaxMonoidal where counit_naturality, counit_naturality_assoc, left_triangle_components_assoc, MonoidalCategory.whiskerLeft_comp] rw [← δ_natural_left_assoc, ← δ_natural_left_assoc, ← δ_natural_left_assoc] - haveI := @NatTrans.whiskerRight_app_tensor_app_assoc _ _ _ _ _ _ _ _ _ adj.counit adj.counit + have := @NatTrans.whiskerRight_app_tensor_app_assoc _ _ _ _ _ _ _ _ _ adj.counit adj.counit dsimp only [id_obj, comp_obj, Functor.comp_map, Functor.id_map] at this rw [this, this, tensorHom_def, assoc, ← comp_whiskerRight_assoc, left_triangle_components, id_whiskerRight, id_comp, @@ -967,7 +967,7 @@ class IsMonoidal [G.LaxMonoidal] : Prop where instance : letI := adj.rightAdjointLaxMonoidal adj.IsMonoidal := by - letI := adj.rightAdjointLaxMonoidal + let := adj.rightAdjointLaxMonoidal constructor · rfl · intro _ _ @@ -1070,7 +1070,7 @@ set_option backward.defeqAttrib.useBackward true in instance : letI := adj.leftAdjointOplaxMonoidal adj.IsMonoidal := by - letI := adj.leftAdjointOplaxMonoidal + let := adj.leftAdjointOplaxMonoidal refine ⟨?_, fun X Y ↦ ?_⟩ · simp [homEquiv_counit, leftAdjointOplaxMonoidal_η] · simp [homEquiv_counit, ← μ_natural, leftAdjointOplaxMonoidal_δ] diff --git a/Mathlib/CategoryTheory/Monoidal/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Mon.lean index aa681901e8873f..5974028edb9ff5 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon.lean @@ -230,7 +230,7 @@ instance instIsMonHomComp (f : M ⟶ N) (g : N ⟶ O) [IsMonHom f] [IsMonHom g] attribute [local simp] MonObj.ofIso_one MonObj.ofIso_mul in @[to_additive] instance isMonHom_ofIso (e : M ≅ X) : letI := MonObj.ofIso e; IsMonHom e.hom := by - letI := MonObj.ofIso e; exact { } + let := MonObj.ofIso e; exact { } @[to_additive] instance (f : M ≅ N) [IsMonHom f.hom] : IsMonHom f.inv where diff --git a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean index 76b62391d25e68..9ac6d9c937c4a6 100644 --- a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean +++ b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean @@ -236,7 +236,7 @@ a monoidal natural transformation. lemma natTransIsMonoidal_of_transport {F G : C ⥤ D} [F.Monoidal] (e : F ≅ G) : letI : G.Monoidal := transport e e.hom.IsMonoidal := by - letI : G.Monoidal := transport e + let : G.Monoidal := transport e refine ⟨rfl, fun X Y ↦ ?_⟩ simp [transport_μ, tensorHom_comp_tensorHom_assoc] diff --git a/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean b/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean index 2f3a35a8d1f94f..25c2e189fcb983 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean @@ -45,35 +45,35 @@ set_option backward.defeqAttrib.useBackward true in theorem of_comp {C₁ C₂ C₃ : Type*} [Category* C₁] [Category* C₂] [Category* C₃] (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (hF : W.IsInvertedBy F) (G : C₂ ⥤ C₃) : W.IsInvertedBy (F ⋙ G) := fun X Y f hf => by - haveI := hF f hf + have := hF f hf dsimp infer_instance set_option backward.defeqAttrib.useBackward true in theorem op {W : MorphismProperty C} {L : C ⥤ D} (h : W.IsInvertedBy L) : W.op.IsInvertedBy L.op := fun X Y f hf => by - haveI := h f.unop hf + have := h f.unop hf dsimp infer_instance set_option backward.defeqAttrib.useBackward true in theorem rightOp {W : MorphismProperty C} {L : Cᵒᵖ ⥤ D} (h : W.op.IsInvertedBy L) : W.IsInvertedBy L.rightOp := fun X Y f hf => by - haveI := h f.op hf + have := h f.op hf dsimp infer_instance set_option backward.defeqAttrib.useBackward true in theorem leftOp {W : MorphismProperty C} {L : C ⥤ Dᵒᵖ} (h : W.IsInvertedBy L) : W.op.IsInvertedBy L.leftOp := fun X Y f hf => by - haveI := h f.unop hf + have := h f.unop hf dsimp infer_instance set_option backward.defeqAttrib.useBackward true in theorem unop {W : MorphismProperty C} {L : Cᵒᵖ ⥤ Dᵒᵖ} (h : W.op.IsInvertedBy L) : W.IsInvertedBy L.unop := fun X Y f hf => by - haveI := h f.op hf + have := h f.op hf dsimp infer_instance diff --git a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean index 88affa6db43406..c9cab609ae86aa 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean @@ -183,7 +183,7 @@ theorem IsStableUnderBaseChange.mk' [RespectsIso P] P (pullback.fst f g)) : IsStableUnderBaseChange P where of_isPullback {X Y Y' S f g f' g'} sq hg := by - haveI : HasPullback f g := sq.flip.hasPullback + have : HasPullback f g := sq.flip.hasPullback let e := sq.flip.isoPullback rw [← P.cancel_left_of_respectsIso e.inv, sq.flip.isoPullback_inv_fst] exact hP₂ _ _ _ f g hg @@ -311,7 +311,7 @@ theorem IsStableUnderCobaseChange.mk' [RespectsIso P] P (pushout.inr f g)) : IsStableUnderCobaseChange P where of_isPushout {A A' B B' f g f' g'} sq hf := by - haveI : HasPushout f g := sq.flip.hasPushout + have : HasPushout f g := sq.flip.hasPushout let e := sq.flip.isoPushout rw [← P.cancel_right_of_respectsIso _ e.hom, sq.flip.inr_isoPushout_hom] exact hP₂ _ _ _ f g hf diff --git a/Mathlib/CategoryTheory/MorphismProperty/TransfiniteComposition.lean b/Mathlib/CategoryTheory/MorphismProperty/TransfiniteComposition.lean index 4fa14df20f1198..a1b2326ce82d73 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/TransfiniteComposition.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/TransfiniteComposition.lean @@ -257,7 +257,7 @@ lemma mem_map_bot_le {j : J} (g : ⊥ ⟶ j) : W (hf.F.map g) := by rw [← homOfLE_comp bot_le (Order.le_succ j), hf.F.map_comp] exact W.comp_mem _ _ hj' (hf.map_mem j hj) | isSuccLimit j hj hj' => - letI : OrderBot (Set.Iio j) := + let : OrderBot (Set.Iio j) := { bot := ⟨⊥, Order.IsSuccLimit.bot_lt hj⟩ bot_le j := bot_le } exact MorphismProperty.colimitsOfShape_le _ diff --git a/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean index e6c2ab7b09469c..e27291f6378e69 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean @@ -78,7 +78,7 @@ lemma binaryProductsClosure_le_iff [HasTerminal C] {P Q : ObjectProperty C} [Q.IsClosedUnderBinaryProducts] [Q.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] : P.binaryProductsClosure ≤ Q ↔ P ≤ Q := by refine ⟨fun h ↦ (P.le_limitsClosure _).trans h, fun h ↦ ?_⟩ - letI : Q.IsClosedUnderIsomorphisms := IsClosedUnderBinaryProducts.closedUnderIsomorphisms Q + let : Q.IsClosedUnderIsomorphisms := IsClosedUnderBinaryProducts.closedUnderIsomorphisms Q exact limitsClosure_le h /-- The typeclass saying that `P : ObjectProperty C` is stable under finite products. -/ @@ -182,7 +182,7 @@ lemma binaryCoproductsClosure_le_iff [HasInitial C] {P Q : ObjectProperty C} [Q.IsClosedUnderBinaryCoproducts] [Q.IsClosedUnderColimitsOfShape (Discrete.{0} PEmpty)] : P.binaryCoproductsClosure ≤ Q ↔ P ≤ Q := by refine ⟨fun h ↦ (P.le_colimitsClosure _).trans h, fun h ↦ ?_⟩ - letI : Q.IsClosedUnderIsomorphisms := IsClosedUnderBinaryCoproducts.closedUnderIsomorphisms Q + let : Q.IsClosedUnderIsomorphisms := IsClosedUnderBinaryCoproducts.closedUnderIsomorphisms Q exact colimitsClosure_le h /-- The typeclass saying that `P : ObjectProperty C` is stable under finite coproducts. -/ diff --git a/Mathlib/CategoryTheory/ObjectProperty/Kernels.lean b/Mathlib/CategoryTheory/ObjectProperty/Kernels.lean index 36c2163b861617..004b18e3f7bd2c 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Kernels.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Kernels.lean @@ -88,7 +88,7 @@ lemma prop_kernel [P.IsClosedUnderKernels] {X Y : C} (f : X ⟶ Y) [HasKernel f] instance [P.IsClosedUnderSubobjects] : P.IsClosedUnderKernels where kernels_le := by intro _ ⟨_, k, hk, hf⟩ - letI := Fork.IsLimit.mono hk + let := Fork.IsLimit.mono hk exact P.prop_of_mono k.ι hf.1 lemma hasLimit_parallelPair_comp_ι {X Y : P.FullSubcategory} (f : X ⟶ Y) [HasKernel f.hom] : @@ -136,7 +136,7 @@ lemma prop_cokernel [P.IsClosedUnderCokernels] {X Y : C} (f : X ⟶ Y) [HasCoker instance [P.IsClosedUnderQuotients] : P.IsClosedUnderCokernels where cokernels_le := by intro _ ⟨_, k, hk, hf⟩ - letI := Cofork.IsColimit.epi hk + let := Cofork.IsColimit.epi hk exact P.prop_of_epi k.π hf.2 lemma hasColimit_parallelPair_comp_ι {X Y : P.FullSubcategory} (f : X ⟶ Y) [HasCokernel f.hom] : diff --git a/Mathlib/CategoryTheory/PUnit.lean b/Mathlib/CategoryTheory/PUnit.lean index 90e23fb3a72964..489efd80680371 100644 --- a/Mathlib/CategoryTheory/PUnit.lean +++ b/Mathlib/CategoryTheory/PUnit.lean @@ -84,7 +84,7 @@ theorem equiv_punit_iff_unique : apply ULift.ext simp [eq_iff_true_of_subsingleton] · rintro ⟨⟨p⟩, h⟩ - haveI := fun x y => (h x y).some + have := fun x y => (h x y).some refine Nonempty.intro (CategoryTheory.Equivalence.mk ((Functor.const _).obj ⟨⟨⟩⟩) diff --git a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean index f21956f433342a..63564f4d54522e 100644 --- a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean +++ b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean @@ -513,7 +513,7 @@ def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] rw [splitEpiOfIdempotentOfIsColimitCofork_section_, isColimitCoforkOfCokernelCofork_desc, isCokernelEpiComp_desc] dsimp only [cokernelCoforkOfCofork_ofπ] - letI := epi_of_isColimit_cofork i + let := epi_of_isColimit_cofork i apply zero_of_epi_comp c.π simp only [sub_comp, comp_sub, Category.comp_id, Category.assoc, IsSplitMono.id, sub_self, Cofork.IsColimit.π_desc_assoc, CokernelCofork.π_ofπ, IsSplitMono.id_assoc] @@ -627,7 +627,7 @@ def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : rw [splitMonoOfIdempotentOfIsLimitFork_retraction, isLimitForkOfKernelFork_lift, isKernelCompMono_lift] dsimp only [kernelForkOfFork_ι] - letI := mono_of_isLimit_fork i + let := mono_of_isLimit_fork i apply zero_of_comp_mono c.ι simp only [comp_sub, Category.comp_id, Category.assoc, sub_self, Fork.IsLimit.lift_ι, Fork.ι_ofι, IsSplitEpi.id_assoc] @@ -916,7 +916,7 @@ set_option backward.isDefEq.respectTransparency false in preserves the biproduct of `f`. For the converse, see `mapBiproduct`. -/ lemma preservesBiproduct_of_mono_biproductComparison {f : J → C} [HasBiproduct f] [HasBiproduct (F.obj ∘ f)] [Mono (biproductComparison F f)] : PreservesBiproduct f F := by - haveI : HasProduct fun b => F.obj (f b) := by + have : HasProduct fun b => F.obj (f b) := by change HasProduct (F.obj ∘ f) infer_instance have that : piComparison F f = @@ -924,19 +924,19 @@ lemma preservesBiproduct_of_mono_biproductComparison {f : J → C} [HasBiproduct biproductComparison F f ≫ (biproduct.isoProduct _).hom := by ext j convert! piComparison_comp_π F f j; simp [← Function.comp_def, ← Functor.map_comp] - haveI : IsIso (biproductComparison F f) := isIso_of_mono_of_isSplitEpi _ - haveI : IsIso (piComparison F f) := by + have : IsIso (biproductComparison F f) := isIso_of_mono_of_isSplitEpi _ + have : IsIso (piComparison F f) := by rw [that] infer_instance - haveI := PreservesProduct.of_iso_comparison F f + have := PreservesProduct.of_iso_comparison F f apply preservesBiproduct_of_preservesProduct /-- If the (coproduct-like) biproduct comparison for `F` and `f` is an epimorphism, then `F` preserves the biproduct of `F` and `f`. For the converse, see `mapBiproduct`. -/ lemma preservesBiproduct_of_epi_biproductComparison' {f : J → C} [HasBiproduct f] [HasBiproduct (F.obj ∘ f)] [Epi (biproductComparison' F f)] : PreservesBiproduct f F := by - haveI : Epi (splitEpiBiproductComparison F f).section_ := by simpa - haveI : IsIso (biproductComparison F f) := + have : Epi (splitEpiBiproductComparison F f).section_ := by simpa + have : IsIso (biproductComparison F f) := IsIso.of_epi_section' (splitEpiBiproductComparison F f) apply preservesBiproduct_of_mono_biproductComparison @@ -1039,11 +1039,11 @@ lemma preservesBinaryBiproduct_of_mono_biprodComparison {X Y : C} [HasBinaryBipr prodComparison F X Y = (F.mapIso (biprod.isoProd X Y)).inv ≫ biprodComparison F X Y ≫ (biprod.isoProd _ _).hom := by ext <;> simp [← Functor.map_comp] - haveI : IsIso (biprodComparison F X Y) := isIso_of_mono_of_isSplitEpi _ - haveI : IsIso (prodComparison F X Y) := by + have : IsIso (biprodComparison F X Y) := isIso_of_mono_of_isSplitEpi _ + have : IsIso (prodComparison F X Y) := by rw [that] infer_instance - haveI := PreservesLimitPair.of_iso_prod_comparison F X Y + have := PreservesLimitPair.of_iso_prod_comparison F X Y apply preservesBinaryBiproduct_of_preservesBinaryProduct /-- If the (coproduct-like) biproduct comparison for `F`, `X` and `Y` is an epimorphism, then @@ -1051,8 +1051,8 @@ lemma preservesBinaryBiproduct_of_mono_biprodComparison {X Y : C} [HasBinaryBipr lemma preservesBinaryBiproduct_of_epi_biprodComparison' {X Y : C} [HasBinaryBiproduct X Y] [HasBinaryBiproduct (F.obj X) (F.obj Y)] [Epi (biprodComparison' F X Y)] : PreservesBinaryBiproduct X Y F := by - haveI : Epi (splitEpiBiprodComparison F X Y).section_ := by simpa - haveI : IsIso (biprodComparison F X Y) := + have : Epi (splitEpiBiprodComparison F X Y).section_ := by simpa + have : IsIso (biprodComparison F X Y) := IsIso.of_epi_section' (splitEpiBiprodComparison F X Y) apply preservesBinaryBiproduct_of_mono_biprodComparison diff --git a/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean index 4e6e7ca93aa2af..b4447e823ae67e 100644 --- a/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean @@ -291,7 +291,7 @@ theorem injective_of_map_injective (adj : F ⊣ G) [G.Full] [G.Faithful] (I : D) (hI : Injective (G.obj I)) : Injective I := ⟨fun {X} {Y} f g => by intro - haveI : PreservesLimitsOfSize.{0, 0} G := adj.rightAdjoint_preservesLimits + have : PreservesLimitsOfSize.{0, 0} G := adj.rightAdjoint_preservesLimits rcases hI.factors (G.map f) (G.map g) with ⟨w,h⟩ use inv (adj.counit.app _) ≫ F.map w ≫ adj.counit.app _ exact G.map_injective (by simpa)⟩ @@ -304,7 +304,7 @@ def mapInjectivePresentation (adj : F ⊣ G) [F.PreservesMonomorphisms] (X : D) injective := adj.map_injective _ I.injective f := G.map I.f mono := by - haveI : PreservesLimitsOfSize.{0, 0} G := adj.rightAdjoint_preservesLimits; infer_instance + have : PreservesLimitsOfSize.{0, 0} G := adj.rightAdjoint_preservesLimits; infer_instance /-- Given an adjunction `F ⊣ G` such that `F` preserves monomorphisms and is faithful, then any injective presentation of `F(X)` can be pulled back to an injective presentation of `X`. diff --git a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean index def108ecf37a58..afead0faa8e030 100644 --- a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean +++ b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean @@ -86,8 +86,8 @@ morphisms if it preserves all kernels. -/ lemma preservesEqualizer_of_preservesKernels [∀ {X Y} (f : X ⟶ Y), PreservesLimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) : PreservesLimit (parallelPair f g) F := by - letI := preservesBinaryBiproducts_of_preservesBinaryProducts F - haveI := additive_of_preservesBinaryBiproducts F + let := preservesBinaryBiproducts_of_preservesBinaryProducts F + have := additive_of_preservesBinaryBiproducts F constructor; intro c i let c' := isLimitKernelForkOfFork (i.ofIsoLimit (Fork.isoForkOfι c)) dsimp only [kernelForkOfFork_ofι] at c' @@ -108,7 +108,7 @@ lemma preservesEqualizers_of_preservesKernels [∀ {X Y} (f : X ⟶ Y), PreservesLimit (parallelPair f 0) F] : PreservesLimitsOfShape WalkingParallelPair F where preservesLimit {K} := by - letI := preservesEqualizer_of_preservesKernels F (K.map WalkingParallelPairHom.left) + let := preservesEqualizer_of_preservesKernels F (K.map WalkingParallelPairHom.left) (K.map WalkingParallelPairHom.right) apply preservesLimit_of_iso_diagram F (diagramIsoParallelPair K).symm @@ -169,8 +169,8 @@ morphisms if it preserves all cokernels. -/ lemma preservesCoequalizer_of_preservesCokernels [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] {X Y : C} (f g : X ⟶ Y) : PreservesColimit (parallelPair f g) F := by - letI := preservesBinaryBiproducts_of_preservesBinaryCoproducts F - haveI := additive_of_preservesBinaryBiproducts F + let := preservesBinaryBiproducts_of_preservesBinaryCoproducts F + have := additive_of_preservesBinaryBiproducts F constructor intro c i let c' := isColimitCokernelCoforkOfCofork (i.ofIsoColimit (Cofork.isoCoforkOfπ c)) @@ -193,7 +193,7 @@ lemma preservesCoequalizers_of_preservesCokernels [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesColimitsOfShape WalkingParallelPair F where preservesColimit {K} := by - letI := preservesCoequalizer_of_preservesCokernels F (K.map Limits.WalkingParallelPairHom.left) + let := preservesCoequalizer_of_preservesCokernels F (K.map Limits.WalkingParallelPairHom.left) (K.map Limits.WalkingParallelPairHom.right) apply preservesColimit_of_iso_diagram F (diagramIsoParallelPair K).symm @@ -202,10 +202,10 @@ colimits. -/ lemma preservesFiniteColimits_of_preservesCokernels [HasFiniteCoproducts C] [HasCoequalizers C] [HasZeroObject C] [HasZeroObject D] [∀ {X Y} (f : X ⟶ Y), PreservesColimit (parallelPair f 0) F] : PreservesFiniteColimits F := by - letI := preservesCoequalizers_of_preservesCokernels F - letI := preservesInitialObject_of_preservesZeroMorphisms F - letI := preservesColimitsOfShape_pempty_of_preservesInitial F - letI : PreservesFiniteCoproducts F := + let := preservesCoequalizers_of_preservesCokernels F + let := preservesInitialObject_of_preservesZeroMorphisms F + let := preservesColimitsOfShape_pempty_of_preservesInitial F + let : PreservesFiniteCoproducts F := ⟨fun _ ↦ PreservesFiniteCoproducts.of_preserves_binary_and_initial F _⟩ exact preservesFiniteColimits_of_preservesCoequalizers_and_finiteCoproducts F diff --git a/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean index 98949b25140fc5..99fbffc078481d 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean @@ -214,7 +214,7 @@ set_option backward.isDefEq.respectTransparency false in theorem projective_of_map_projective (adj : F ⊣ G) [F.Full] [F.Faithful] (P : C) (hP : Projective (F.obj P)) : Projective P where factors f g _ := by - haveI := Adjunction.leftAdjoint_preservesColimits.{0, 0} adj + have := Adjunction.leftAdjoint_preservesColimits.{0, 0} adj rcases (@hP).1 (F.map f) (F.map g) with ⟨f', hf'⟩ use adj.unit.app _ ≫ G.map f' ≫ (inv <| adj.unit.app _) exact F.map_injective (by simpa) diff --git a/Mathlib/CategoryTheory/Preadditive/Schur.lean b/Mathlib/CategoryTheory/Preadditive/Schur.lean index 4b32d29f7232e4..3f7acddcd52ef2 100644 --- a/Mathlib/CategoryTheory/Preadditive/Schur.lean +++ b/Mathlib/CategoryTheory/Preadditive/Schur.lean @@ -68,7 +68,7 @@ noncomputable instance [HasKernels C] {X : C} [Simple X] : DivisionRing (End X) mul_inv_cancel f hf := by dsimp rw [dif_neg hf] - haveI := isIso_of_hom_simple hf + have := isIso_of_hom_simple hf exact IsIso.inv_hom_id f nnqsmul := _ nnqsmul_def := fun _ _ => rfl @@ -160,7 +160,7 @@ theorem finrank_hom_simple_simple_le_one (X Y : C) [FiniteDimensional 𝕜 (X · rw [finrank_zero_of_subsingleton] exact zero_le_one · obtain ⟨f, nz⟩ := (nontrivial_iff_exists_ne 0).mp h - haveI fi := (isIso_iff_nonzero f).mpr nz + have fi := (isIso_iff_nonzero f).mpr nz refine finrank_le_one f ?_ intro g obtain ⟨c, w⟩ := endomorphism_simple_eq_smul_id 𝕜 (g ≫ inv f) diff --git a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean index d4745dd6b9f4a7..47ac60b78f5665 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean @@ -64,7 +64,7 @@ variable {κ} {J : Type u} [SmallCategory J] [IsCardinalFiltered J κ] lemma isCardinalFiltered_pt (hF : ∀ j, IsCardinalFiltered (F.obj j) κ) : haveI := isFiltered_of_isCardinalFiltered J κ IsCardinalFiltered (CoconePt hc) κ := by - haveI := isFiltered_of_isCardinalFiltered J κ + have := isFiltered_of_isCardinalFiltered J κ refine isCardinalFiltered_preorder _ _ (fun K f hK ↦ ?_) rw [← hasCardinalLT_iff_cardinal_mk_lt] at hK choose j₀ x₀ hx₀ using fun k ↦ Types.jointly_surjective_of_isColimit hc (f k) @@ -208,7 +208,7 @@ instance : ObjectProperty.EssentiallySmall.{u} (hasCardinalLTWithTerminal κ) wh obtain ⟨f⟩ : Cardinal.mk J.obj ≤ Cardinal.mk X := by simpa [hX] using ((hasCardinalLT_iff_cardinal_mk_lt _ _).1 hJ).le let e := Equiv.ofInjective _ f.injective - letI : PartialOrder (Set.range f) := PartialOrder.lift _ e.symm.injective + let : PartialOrder (Set.range f) := PartialOrder.lift _ e.symm.injective let e' : Set.range f ≃o J.obj := { toEquiv := e.symm, map_rel_iff' := by rfl } exact ⟨_, ⟨⟨Set.range f, inferInstance, ⟨⟨IsCardinalFiltered.of_equivalence κ e'.symm.equivalence⟩⟩⟩⟩, diff --git a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean index 5a9df97b791eff..2574454c5dec62 100644 --- a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean +++ b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean @@ -174,7 +174,7 @@ lemma hasCardinalLT_transfiniteIterate_φ (j : κ₁.ord.ToType) : induction j using SuccOrder.limitRecOn with | isMin j hj => have := Cardinal.nonempty_ord_toType (c := κ₁) (IsRegular.ne_zero Fact.out) - letI := WellFoundedLT.toOrderBot κ₁.ord.ToType + let := WellFoundedLT.toOrderBot κ₁.ord.ToType simpa [hj.eq_bot] | succ j hj hj' => have hκ₂ : κ₂.IsRegular := Fact.out @@ -204,7 +204,7 @@ lemma monotone_transfiniteIterate_φ : omit [PartialOrder X] [Fact κ₂.IsRegular] in lemma subset_iUnion : A ⊆ ⋃ (j : κ₁.ord.ToType), transfiniteIterate (φ Y m) j A := by have := Cardinal.nonempty_ord_toType (c := κ₁) (IsRegular.ne_zero Fact.out) - letI := WellFoundedLT.toOrderBot κ₁.ord.ToType + let := WellFoundedLT.toOrderBot κ₁.ord.ToType exact subset_trans (by simp) (Set.subset_iUnion _ ⊥) include h₀ hY hY' hm hA in diff --git a/Mathlib/CategoryTheory/Quotient/Linear.lean b/Mathlib/CategoryTheory/Quotient/Linear.lean index d17a32660e0f4b..25882519774864 100644 --- a/Mathlib/CategoryTheory/Quotient/Linear.lean +++ b/Mathlib/CategoryTheory/Quotient/Linear.lean @@ -116,7 +116,7 @@ instance linear_functor (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ f₂), r (a • f₁) (a • f₂)) [Preadditive (Quotient r)] [(functor r).Additive] : letI := linear R r hr; Functor.Linear R (functor r) := by - letI := linear R r hr; exact { } + let := linear R r hr; exact { } end Quotient diff --git a/Mathlib/CategoryTheory/Shift/Adjunction.lean b/Mathlib/CategoryTheory/Shift/Adjunction.lean index e83e02ed9beffc..ba1a8caa4a0e1b 100644 --- a/Mathlib/CategoryTheory/Shift/Adjunction.lean +++ b/Mathlib/CategoryTheory/Shift/Adjunction.lean @@ -413,7 +413,7 @@ set_option backward.defeqAttrib.useBackward true in lemma commShift_of_leftAdjoint [F.CommShift A] : letI := adj.rightAdjointCommShift A adj.CommShift A := by - letI := adj.rightAdjointCommShift A + let := adj.rightAdjointCommShift A refine CommShift.mk' _ _ ⟨fun a ↦ ?_⟩ ext X dsimp @@ -502,7 +502,7 @@ set_option backward.defeqAttrib.useBackward true in lemma commShift_of_rightAdjoint [G.CommShift A] : letI := adj.leftAdjointCommShift A adj.CommShift A := by - letI := adj.leftAdjointCommShift A + let := adj.leftAdjointCommShift A refine CommShift.mk' _ _ ⟨fun a ↦ ?_⟩ ext X dsimp @@ -620,7 +620,7 @@ noncomputable def commShiftInverse [E.functor.CommShift A] : E.inverse.CommShift lemma commShift_of_functor [E.functor.CommShift A] : letI := E.commShiftInverse A E.CommShift A := by - letI := E.commShiftInverse A + let := E.commShiftInverse A exact CommShift.mk' _ _ (E.toAdjunction.commShift_of_leftAdjoint A).commShift_unit /-- @@ -635,7 +635,7 @@ set_option backward.isDefEq.respectTransparency false in lemma commShift_of_inverse [E.inverse.CommShift A] : letI := E.commShiftFunctor A E.CommShift A := by - letI := E.commShiftFunctor A + let := E.commShiftFunctor A have := E.symm.commShift_of_functor A exact inferInstanceAs (E.symm.symm.CommShift A) diff --git a/Mathlib/CategoryTheory/Shift/CommShift.lean b/Mathlib/CategoryTheory/Shift/CommShift.lean index 7f8d6bd467a2dd..c36d2531705d21 100644 --- a/Mathlib/CategoryTheory/Shift/CommShift.lean +++ b/Mathlib/CategoryTheory/Shift/CommShift.lean @@ -414,7 +414,7 @@ instance of_iso_symm [NatTrans.CommShift e.hom A] : NatTrans.CommShift e.symm.ho lemma of_isIso [IsIso τ] [NatTrans.CommShift τ A] : NatTrans.CommShift (inv τ) A := by - haveI : NatTrans.CommShift (asIso τ).hom A := by assumption + have : NatTrans.CommShift (asIso τ).hom A := by assumption change NatTrans.CommShift (asIso τ).inv A infer_instance @@ -481,7 +481,7 @@ def ofIso : G.CommShift A where lemma ofIso_compatibility : letI := ofIso e A NatTrans.CommShift e.hom A := by - letI := ofIso e A + let := ofIso e A exact ⟨fun a => by ext; simp [ofIso_commShiftIso_hom_app]⟩ end CommShift @@ -602,7 +602,7 @@ set_option backward.isDefEq.respectTransparency false in lemma ofComp_compatibility : letI := ofComp e NatTrans.CommShift e.hom A := by - letI := ofComp e + let := ofComp e refine ⟨fun a ↦ ?_⟩ ext X simp [commShiftIso_comp_hom_app, show F.commShiftIso a = OfComp.iso e a from rfl, diff --git a/Mathlib/CategoryTheory/Shift/Localization.lean b/Mathlib/CategoryTheory/Shift/Localization.lean index ba1303396ea965..c98abdc19b2de0 100644 --- a/Mathlib/CategoryTheory/Shift/Localization.lean +++ b/Mathlib/CategoryTheory/Shift/Localization.lean @@ -241,7 +241,7 @@ set_option backward.isDefEq.respectTransparency false in instance NatTrans.commShift_iso_hom_of_localization : letI := Functor.commShiftOfLocalization L W A F F' NatTrans.CommShift (Lifting.iso L W F F').hom A := by - letI := Functor.commShiftOfLocalization L W A F F' + let := Functor.commShiftOfLocalization L W A F F' constructor intro a ext X @@ -307,7 +307,7 @@ set_option backward.isDefEq.respectTransparency false in lemma natTransCommShift_hom : letI := Φ.commShift M L₁ L₂ G e NatTrans.CommShift e.hom M := by - letI := Φ.commShift M L₁ L₂ G e + let := Φ.commShift M L₁ L₂ G e refine ⟨fun m ↦ ?_⟩ ext X simp [Functor.commShiftIso_comp_hom_app, commShift_iso_hom_app, ← Functor.map_comp_assoc] diff --git a/Mathlib/CategoryTheory/Simple.lean b/Mathlib/CategoryTheory/Simple.lean index b433d6015c5c0f..0db17621155756 100644 --- a/Mathlib/CategoryTheory/Simple.lean +++ b/Mathlib/CategoryTheory/Simple.lean @@ -102,7 +102,7 @@ theorem kernel_zero_of_nonzero_from_simple {X Y : C} [Simple X] {f : X ⟶ Y} [H (w : f ≠ 0) : kernel.ι f = 0 := by classical by_contra h - haveI := isIso_of_mono_of_nonzero h + have := isIso_of_mono_of_nonzero h exact w (eq_zero_of_epi_kernel f) -- See also `mono_of_nonzero_from_simple`, which requires `Preadditive C`. @@ -112,7 +112,7 @@ theorem kernel_zero_of_nonzero_from_simple {X Y : C} [Simple X] {f : X ⟶ Y} [H theorem epi_of_nonzero_to_simple [HasEqualizers C] {X Y : C} [Simple Y] {f : X ⟶ Y} [HasImage f] (w : f ≠ 0) : Epi f := by rw [← image.fac f] - haveI : IsIso (image.ι f) := isIso_of_mono_of_nonzero fun h => w (eq_zero_of_image_eq_zero h) + have : IsIso (image.ι f) := isIso_of_mono_of_nonzero fun h => w (eq_zero_of_image_eq_zero h) apply epi_comp theorem mono_to_simple_zero_of_not_iso {X Y : C} [Simple Y] {f : X ⟶ Y} [Mono f] @@ -180,7 +180,7 @@ theorem cokernel_zero_of_nonzero_to_simple {X Y : C} [Simple Y] {f : X ⟶ Y} (w cokernel.π f = 0 := by classical by_contra h - haveI := isIso_of_epi_of_nonzero h + have := isIso_of_epi_of_nonzero h exact w (eq_zero_of_mono_cokernel f) theorem epi_from_simple_zero_of_not_iso {X Y : C} [Simple X] {f : X ⟶ Y} [Epi f] diff --git a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean index e4fea004e81e05..577e18af7001ad 100644 --- a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean @@ -493,7 +493,7 @@ variable {D} set_option backward.isDefEq.respectTransparency false in theorem isIso_toSheafify {P : Cᵒᵖ ⥤ D} (hP : Presheaf.IsSheaf J P) : IsIso (J.toSheafify P) := by dsimp [toSheafify] - haveI := isIso_toPlus_of_isSheaf J P hP + have := isIso_toPlus_of_isSheaf J P hP change (IsIso (toPlus J P ≫ (J.plusFunctor D).map (toPlus J P))) infer_instance diff --git a/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean b/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean index 407c524ae3f725..120b4161042a90 100644 --- a/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean +++ b/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean @@ -214,7 +214,7 @@ theorem w : forkMap P R ≫ firstMap P R = forkMap P R ≫ secondMap P R := by ext fg simp only [firstMap, secondMap, forkMap] simp only [limit.lift_π, limit.lift_π_assoc, assoc, Fan.mk_π_app] - haveI := Presieve.HasPairwisePullbacks.has_pullbacks fg.1.2.2 fg.2.2.2 + have := Presieve.HasPairwisePullbacks.has_pullbacks fg.1.2.2 fg.2.2.2 rw [← P.map_comp, ← op_comp, pullback.condition] simp diff --git a/Mathlib/CategoryTheory/Sites/Equivalence.lean b/Mathlib/CategoryTheory/Sites/Equivalence.lean index f9db07fde0ed3b..5925f220ae84e9 100644 --- a/Mathlib/CategoryTheory/Sites/Equivalence.lean +++ b/Mathlib/CategoryTheory/Sites/Equivalence.lean @@ -289,7 +289,7 @@ lemma PreservesSheafification.transport rw [← J.W_whiskerLeft_iff (G := G) (K := K)] at hf have := K.W_of_preservesSheafification F (whiskerLeft G.op f) hf rw [whiskerRight_left] at this - haveI := K.W.of_postcomp (W' := MorphismProperty.isomorphisms _) _ _ (Iso.isIso_inv _) <| + have := K.W.of_postcomp (W' := MorphismProperty.isomorphisms _) _ _ (Iso.isIso_inv _) <| K.W.of_precomp (W' := MorphismProperty.isomorphisms _) _ _ (Iso.isIso_hom _) this rwa [K.W_whiskerLeft_iff (G := G) (J := J) (f := whiskerRight f F)] at this diff --git a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean index c80ad160c9acd2..0fb018ee82765d 100644 --- a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean +++ b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean @@ -184,10 +184,10 @@ theorem pullbackCompatible_iff (x : FamilyOfElements P R) [R.HasPairwisePullback constructor · intro t Y₁ Y₂ f₁ f₂ hf₁ hf₂ apply t - haveI := HasPairwisePullbacks.has_pullbacks hf₁ hf₂ + have := HasPairwisePullbacks.has_pullbacks hf₁ hf₂ apply pullback.condition · intro t Y₁ Y₂ Z g₁ g₂ f₁ f₂ hf₁ hf₂ comm - haveI := HasPairwisePullbacks.has_pullbacks hf₁ hf₂ + have := HasPairwisePullbacks.has_pullbacks hf₁ hf₂ rw [← pullback.lift_fst _ _ comm, op_comp, Functor.map_comp, comp_apply, t hf₁ hf₂, ← comp_apply, ← Functor.map_comp, ← op_comp, pullback.lift_snd] diff --git a/Mathlib/CategoryTheory/Sites/LeftExact.lean b/Mathlib/CategoryTheory/Sites/LeftExact.lean index 2b595f5006ae30..6b603310282077 100644 --- a/Mathlib/CategoryTheory/Sites/LeftExact.lean +++ b/Mathlib/CategoryTheory/Sites/LeftExact.lean @@ -257,9 +257,9 @@ instance preservesLimitsOfShape_presheafToSheaf [PreservesLimits (forget D)] [∀ X : C, Small.{t, max u v} (J.Cover X)ᵒᵖ] : PreservesLimitsOfShape K (plusPlusSheaf J D) := by let e := (FinCategory.equivAsType K).symm.trans (AsSmall.equiv.{0, 0, t}) - haveI : HasLimitsOfShape (AsSmall.{t} (FinCategory.AsType K)) D := + have : HasLimitsOfShape (AsSmall.{t} (FinCategory.AsType K)) D := Limits.hasLimitsOfShape_of_equivalence e - haveI : FinCategory (AsSmall.{t} (FinCategory.AsType K)) := by + have : FinCategory (AsSmall.{t} (FinCategory.AsType K)) := by constructor · change Fintype (ULift _) infer_instance diff --git a/Mathlib/CategoryTheory/Sites/Point/Basic.lean b/Mathlib/CategoryTheory/Sites/Point/Basic.lean index c9421f9d5182a2..2ed8ce616fc0d4 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Basic.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Basic.lean @@ -343,7 +343,7 @@ lemma toPresheafFiber_presheafFiberCompIso_hom_app (X : C) (x : Φ.fiber.obj X) (P : Cᵒᵖ ⥤ A) : Φ.toPresheafFiber X x (P ⋙ F) ≫ (Φ.presheafFiberCompIso F).hom.app P = F.map (Φ.toPresheafFiber X x P) := by - haveI := Functor.Final.preservesColimitsOfShape_of_final + have := Functor.Final.preservesColimitsOfShape_of_final (FinallySmall.fromFilteredFinalModel.{w} (Φ.fiber.Elementsᵒᵖ)) F simp only [presheafFiberCompIso] exact ι_preservesColimitIso_inv F ((CategoryOfElements.π Φ.fiber).op ⋙ P) _ diff --git a/Mathlib/CategoryTheory/Sites/Sheaf.lean b/Mathlib/CategoryTheory/Sites/Sheaf.lean index 1ee14826e07ea4..c9003c0cae617f 100644 --- a/Mathlib/CategoryTheory/Sites/Sheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Sheaf.lean @@ -706,7 +706,7 @@ theorem isSheaf_comp_of_isSheaf (s : A ⥤ B) [PreservesLimitsOfSize.{v₁, max theorem isSheaf_iff_isSheaf_comp (s : A ⥤ B) [HasLimitsOfSize.{v₁, max v₁ u₁} A] [PreservesLimitsOfSize.{v₁, max v₁ u₁} s] [s.ReflectsIsomorphisms] : IsSheaf J P ↔ IsSheaf J (P ⋙ s) := by - letI : ReflectsLimitsOfSize s := reflectsLimits_of_reflectsIsomorphisms + let : ReflectsLimitsOfSize s := reflectsLimits_of_reflectsIsomorphisms exact ⟨isSheaf_comp_of_isSheaf J P s, isSheaf_of_isSheaf_comp J P s⟩ /-- diff --git a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean index 2e73c9c13525a5..cafe1921428c54 100644 --- a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean +++ b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean @@ -118,9 +118,9 @@ lemma preservesColimit {A B X Y : C} (i : A ⟶ B) (hi : I i) (f : X ⟶ Y) lemma hasColimitsOfShape_discrete (X Y : C) (p : X ⟶ Y) : HasColimitsOfShape (Discrete (FunctorObjIndex I.homFamily p)) C := by - haveI := locallySmall I κ - haveI := isSmall I κ - haveI := hasCoproducts I κ + have := locallySmall I κ + have := isSmall I κ + have := hasCoproducts I κ exact hasColimitsOfShape_of_equivalence (Discrete.equivalence (equivShrink.{w} _)).symm @@ -157,10 +157,10 @@ def propArrow : MorphismProperty (Arrow C) := fun _ _ f ↦ set_option backward.defeqAttrib.useBackward true in lemma succStruct_prop_le_propArrow : (succStruct I κ).prop ≤ (propArrow.{w} I).functorCategory (Arrow C) := by - haveI := locallySmall I κ - haveI := isSmall I κ - haveI := hasColimitsOfShape_discrete I κ - haveI := hasPushouts I κ + have := locallySmall I κ + have := isSmall I κ + have := hasColimitsOfShape_discrete I κ + have := hasPushouts I κ intro _ _ _ ⟨F⟩ f constructor · nth_rw 1 [← I.ofHoms_homFamily] @@ -382,9 +382,9 @@ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in lemma hasRightLiftingProperty_πObj {A B : C} (i : A ⟶ B) (hi : I i) (f : X ⟶ Y) : HasLiftingProperty i (πObj I κ f) := ⟨by - haveI := hasColimitsOfShape_discrete I κ - haveI := hasPushouts I κ - haveI := preservesColimit I κ i hi _ (relativeCellComplexιObj I κ f) + have := hasColimitsOfShape_discrete I κ + have := hasPushouts I κ + have := preservesColimit I κ i hi _ (relativeCellComplexιObj I κ f) intro g b sq obtain ⟨j, t, ht⟩ := Types.jointly_surjective _ (isColimitOfPreserves (coyoneda.obj (Opposite.op A)) diff --git a/Mathlib/CategoryTheory/Subobject/MonoOver.lean b/Mathlib/CategoryTheory/Subobject/MonoOver.lean index a6f4efb7ff6877..7e71cef9cfd97a 100644 --- a/Mathlib/CategoryTheory/Subobject/MonoOver.lean +++ b/Mathlib/CategoryTheory/Subobject/MonoOver.lean @@ -288,7 +288,7 @@ variable [HasPullbacks C] by pulling back a monomorphism along `f`. -/ def pullback (f : X ⟶ Y) : MonoOver Y ⥤ MonoOver X := MonoOver.lift (Over.pullback f) (fun g => by - haveI : Mono ((forget Y).obj g).hom := (inferInstance : Mono g.arrow) + have : Mono ((forget Y).obj g).hom := (inferInstance : Mono g.arrow) apply pullback.snd_of_mono) /-- pullback commutes with composition (up to a natural isomorphism) -/ diff --git a/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean b/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean index 46e9f82dc19dd8..dc0576d7f7409a 100644 --- a/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean @@ -241,8 +241,8 @@ instance [Preadditive D₁] [Preadditive D₂] [L₁.Additive] [L₂.Additive] : set_option backward.defeqAttrib.useBackward true in instance : ((A.triangulatedLocalizerMorphism B).localizedFunctor L₁ L₂).Faithful := by - letI := Localization.preadditive L₁ (B.inverseImage A.ι).trW - letI := Localization.preadditive L₂ B.trW + let := Localization.preadditive L₁ (B.inverseImage A.ι).trW + let := Localization.preadditive L₂ B.trW have := Localization.functor_additive L₁ (B.inverseImage A.ι).trW have := Localization.functor_additive L₂ B.trW let F := (A.triangulatedLocalizerMorphism B).localizedFunctor L₁ L₂ @@ -276,7 +276,7 @@ instance [A.IsVerdierLeftLocalizing B] : let L₂ := B.trW.Q let F : (B.inverseImage A.ι).trW.Localization ⥤ B.trW.Localization := (A.triangulatedLocalizerMorphism B).localizedFunctor L₁ L₂ - letI : CatCommSq (A.op.triangulatedLocalizerMorphism B.op).functor + let : CatCommSq (A.op.triangulatedLocalizerMorphism B.op).functor (A.opEquivalence.functor ⋙ L₁.op) L₂.op F.op := ⟨Functor.isoWhiskerLeft A.opEquivalence.functor (NatIso.op (CatCommSq.iso (A.triangulatedLocalizerMorphism B).functor L₁ L₂ F).symm)⟩ diff --git a/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean b/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean index 0015ed2a201246..d2ba7f2eab74e6 100644 --- a/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean +++ b/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean @@ -54,7 +54,7 @@ Any sequence of `2 * p - 1` elements of `ZMod p` contains a subsequence of `p` e zero. -/ private theorem ZMod.erdos_ginzburg_ziv_prime (a : ι → ZMod p) (hs : #s = 2 * p - 1) : ∃ t ⊆ s, #t = p ∧ ∑ i ∈ t, a i = 0 := by - haveI : NeZero p := inferInstance + have : NeZero p := inferInstance classical -- Let `N` be the number of common roots of our polynomials `f₁` and `f₂` (`f s ff` and `f s tt`). set N := Fintype.card {x // eval x (f₁ s a) = 0 ∧ eval x (f₂ s a) = 0} @@ -118,7 +118,7 @@ theorem Int.erdos_ginzburg_ziv (a : ι → ℤ) (hs : 2 * n - 1 ≤ #s) : | one => simpa using exists_subset_card_eq hs -- When `n := p` is prime, we use the prime case `Int.erdos_ginzburg_ziv_prime`. | prime p hp => - haveI := Fact.mk hp + have := Fact.mk hp obtain ⟨t, hts, ht⟩ := exists_subset_card_eq hs obtain ⟨u, hut, hu⟩ := Int.erdos_ginzburg_ziv_prime a ht exact ⟨u, hut.trans hts, hu⟩ diff --git a/Mathlib/Combinatorics/Additive/RuzsaCovering.lean b/Mathlib/Combinatorics/Additive/RuzsaCovering.lean index 9f37658ccf961e..2482cd65e1d471 100644 --- a/Mathlib/Combinatorics/Additive/RuzsaCovering.lean +++ b/Mathlib/Combinatorics/Additive/RuzsaCovering.lean @@ -31,7 +31,7 @@ variable [DecidableEq G] {A B : Finset G} @[to_additive /-- **Ruzsa's covering lemma** -/] theorem ruzsa_covering_mul (hB : B.Nonempty) (hK : #(A * B) ≤ K * #B) : ∃ F ⊆ A, #F ≤ K ∧ A ⊆ F * (B / B) := by - haveI : ∀ F, Decidable ((F : Set G).PairwiseDisjoint (· • B)) := fun F ↦ Classical.dec _ + have : ∀ F, Decidable ((F : Set G).PairwiseDisjoint (· • B)) := fun F ↦ Classical.dec _ set C := {F ∈ A.powerset | (SetLike.coe F).PairwiseDisjoint (· • B)} obtain ⟨F, hFmax⟩ := C.exists_maximal <| filter_nonempty_iff.2 ⟨∅, empty_mem_powerset _, by simp [coe_empty]⟩ diff --git a/Mathlib/Combinatorics/Configuration.lean b/Mathlib/Combinatorics/Configuration.lean index a24fbf50717b85..84b4579c6b7d35 100644 --- a/Mathlib/Combinatorics/Configuration.lean +++ b/Mathlib/Combinatorics/Configuration.lean @@ -194,7 +194,7 @@ theorem HasLines.pointCount_le_lineCount [HasLines P L] {p : P} {l : L} (h : p [Finite { l : L // p ∈ l }] : pointCount P l ≤ lineCount L p := by by_cases hf : Infinite { p : P // p ∈ l } · simp [pointCount] - haveI := fintypeOfNotInfinite hf + have := fintypeOfNotInfinite hf cases nonempty_fintype { l : L // p ∈ l } rw [lineCount, pointCount, Nat.card_eq_fintype_card, Nat.card_eq_fintype_card] have : ∀ p' : { p // p ∈ l }, p ≠ p' := fun p' hp' => h ((congr_arg (· ∈ l) hp').mpr p'.2) @@ -289,8 +289,8 @@ noncomputable def HasLines.hasPoints [HasLines P L] [Fintype P] [Fintype L] let : ∀ l₁ l₂ : L, l₁ ≠ l₂ → ∃ p : P, p ∈ l₁ ∧ p ∈ l₂ := fun l₁ l₂ hl => by classical obtain ⟨f, _, hf2⟩ := HasLines.exists_bijective_of_card_eq h - haveI : Nontrivial L := ⟨⟨l₁, l₂, hl⟩⟩ - haveI := Fintype.one_lt_card_iff_nontrivial.mp ((congr_arg _ h).mpr Fintype.one_lt_card) + have : Nontrivial L := ⟨⟨l₁, l₂, hl⟩⟩ + have := Fintype.one_lt_card_iff_nontrivial.mp ((congr_arg _ h).mpr Fintype.one_lt_card) have h₁ : ∀ p : P, 0 < lineCount L p := fun p => Exists.elim (exists_ne p) fun q hq => (congr_arg _ Nat.card_eq_fintype_card).mpr diff --git a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean index ecfe13df569322..22b6f2466c672e 100644 --- a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean +++ b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean @@ -501,7 +501,7 @@ variable (𝕜) [Ring 𝕜] [PartialOrder α] [LocallyFiniteOrder α] [Decidable @[simp] lemma mu_toDual (a b : α) : mu 𝕜 (toDual a) (toDual b) = mu 𝕜 b a := by - letI : DecidableLE α := Classical.decRel _ + let : DecidableLE α := Classical.decRel _ let mud : IncidenceAlgebra 𝕜 αᵒᵈ := { toFun := fun a b ↦ mu 𝕜 (ofDual b) (ofDual a) eq_zero_of_not_le' := fun a b hab ↦ apply_eq_zero_of_not_le (by exact hab) _ } @@ -536,7 +536,7 @@ variable [Ring 𝕜] [PartialOrder α] [OrderTop α] [LocallyFiniteOrder α] [De O'Donnell. -/ lemma moebius_inversion_top (f g : α → 𝕜) (h : ∀ x, g x = ∑ y ∈ Ici x, f y) (x : α) : f x = ∑ y ∈ Ici x, mu 𝕜 x y * g y := by - letI : DecidableLE α := Classical.decRel _ + let : DecidableLE α := Classical.decRel _ symm calc ∑ y ∈ Ici x, mu 𝕜 x y * g y = ∑ y ∈ Ici x, mu 𝕜 x y * ∑ z ∈ Ici y, f z := by simp_rw [h] diff --git a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean index 364d1fc78694b8..74801a7646491f 100644 --- a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean +++ b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean @@ -166,7 +166,7 @@ private lemma locallyLinear (hs : ThreeAPFree (s : Set α)) : private lemma card_edgeFinset (hs : ThreeAPFree (s : Set α)) [DecidableEq α] : #(graph <| triangleIndices s).edgeFinset = 3 * card α * #s := by - haveI := noAccidental hs + have := noAccidental hs rw [(locallyLinear hs).card_edgeFinset, card_triangles, card_triangleIndices, mul_assoc] end RuzsaSzemeredi @@ -176,7 +176,7 @@ variable (α) [Fintype α] [DecidableEq α] [CommRing α] [Fact <| IsUnit (2 : lemma addRothNumber_le_ruzsaSzemerediNumber : card α * addRothNumber (univ : Finset α) ≤ ruzsaSzemerediNumber (Sum α (Sum α α)) := by obtain ⟨s, -, hscard, hs⟩ := addRothNumber_spec (univ : Finset α) - haveI := noAccidental hs + have := noAccidental hs rw [← hscard, ← card_triangleIndices, ← card_triangles] exact (locallyLinear hs).le_ruzsaSzemerediNumber @@ -184,7 +184,7 @@ lemma rothNumberNat_le_ruzsaSzemerediNumberNat (n : ℕ) : (2 * n + 1) * rothNumberNat n ≤ ruzsaSzemerediNumberNat (6 * n + 3) := by let α := Fin (2 * n + 1) have : Nat.Coprime 2 (2 * n + 1) := by simp - haveI : Fact (IsUnit (2 : Fin (2 * n + 1))) := ⟨by simpa + have : Fact (IsUnit (2 : Fin (2 * n + 1))) := ⟨by simpa using! (ZMod.unitOfCoprime 2 this).isUnit⟩ open scoped Fin.CommRing in calc diff --git a/Mathlib/Combinatorics/Hall/Basic.lean b/Mathlib/Combinatorics/Hall/Basic.lean index 7d0a04f1b1a91b..df8abd2574ee75 100644 --- a/Mathlib/Combinatorics/Hall/Basic.lean +++ b/Mathlib/Combinatorics/Hall/Basic.lean @@ -120,10 +120,10 @@ theorem Finset.all_card_le_biUnion_card_iff_exists_injective {ι : Type u} {α : constructor · intro h -- Set up the functor - haveI : ∀ ι' : (Finset ι)ᵒᵖ, Nonempty ((hallMatchingsFunctor t).obj ι') := fun ι' => + have : ∀ ι' : (Finset ι)ᵒᵖ, Nonempty ((hallMatchingsFunctor t).obj ι') := fun ι' => hallMatchingsOn.nonempty t h ι'.unop classical - haveI : ∀ ι' : (Finset ι)ᵒᵖ, Finite ((hallMatchingsFunctor t).obj ι') := by + have : ∀ ι' : (Finset ι)ᵒᵖ, Finite ((hallMatchingsFunctor t).obj ι') := by intro ι' rw [hallMatchingsFunctor] infer_instance @@ -196,7 +196,7 @@ rather than `Rel.image`. theorem Fintype.all_card_le_filter_rel_iff_exists_injective {α : Type u} {β : Type v} [Fintype β] (r : α → β → Prop) [DecidableRel r] : (∀ A : Finset α, #A ≤ #{b | ∃ a ∈ A, r a b}) ↔ ∃ f : α → β, Injective f ∧ ∀ x, r x (f x) := by - haveI := Classical.decEq β + have := Classical.decEq β let r' a : Finset β := {b | r a b} have h : ∀ A : Finset α, ({b | ∃ a ∈ A, r a b} : Finset _) = A.biUnion r' := by intro A diff --git a/Mathlib/Combinatorics/Hall/Finite.lean b/Mathlib/Combinatorics/Hall/Finite.lean index 3bd50b4a414a08..12bc02d8426363 100644 --- a/Mathlib/Combinatorics/Hall/Finite.lean +++ b/Mathlib/Combinatorics/Hall/Finite.lean @@ -54,7 +54,7 @@ set_option backward.isDefEq.respectTransparency false in theorem hall_cond_of_erase {x : ι} (a : α) (ha : ∀ s : Finset ι, s.Nonempty → s ≠ univ → #s < #(s.biUnion t)) (s' : Finset { x' : ι | x' ≠ x }) : #s' ≤ #(s'.biUnion fun x' => (t x').erase a) := by - haveI := Classical.decEq ι + have := Classical.decEq ι specialize ha (s'.image fun z => z.1) rw [image_nonempty, Finset.card_image_of_injective s' Subtype.coe_injective] at ha by_cases! he : s'.Nonempty @@ -86,8 +86,8 @@ theorem hall_hard_inductive_step_A {n : ℕ} (hn : Fintype.card ι = n + 1) ∃ f : ι' → α, Function.Injective f ∧ ∀ x, f x ∈ t' x) (ha : ∀ s : Finset ι, s.Nonempty → s ≠ univ → #s < #(s.biUnion t)) : ∃ f : ι → α, Function.Injective f ∧ ∀ x, f x ∈ t x := by - haveI : Nonempty ι := Fintype.card_pos_iff.mp (hn.symm ▸ Nat.succ_pos _) - haveI := Classical.decEq ι + have : Nonempty ι := Fintype.card_pos_iff.mp (hn.symm ▸ Nat.succ_pos _) + have := Classical.decEq ι -- Choose an arbitrary element `x : ι` and `y : t x`. let x := Classical.arbitrary ι have tx_ne : (t x).Nonempty := by @@ -134,7 +134,7 @@ theorem hall_cond_of_restrict {ι : Type u} {t : ι → Finset α} {s : Finset theorem hall_cond_of_compl {ι : Type u} {t : ι → Finset α} {s : Finset ι} (hus : #s = #(s.biUnion t)) (ht : ∀ s : Finset ι, #s ≤ #(s.biUnion t)) (s' : Finset (sᶜ : Set ι)) : #s' ≤ #(s'.biUnion fun x' => t x' \ s.biUnion t) := by - haveI := Classical.decEq ι + have := Classical.decEq ι have disj : Disjoint s (s'.image fun z => z.1) := by simp only [disjoint_left, not_exists, mem_image, SetCoe.exists, exists_and_right, exists_eq_right] @@ -169,7 +169,7 @@ theorem hall_hard_inductive_step_B {n : ℕ} (hn : Fintype.card ι = n + 1) ∃ f : ι' → α, Function.Injective f ∧ ∀ x, f x ∈ t' x) (s : Finset ι) (hs : s.Nonempty) (hns : s ≠ univ) (hus : #s = #(s.biUnion t)) : ∃ f : ι → α, Function.Injective f ∧ ∀ x, f x ∈ t x := by - haveI := Classical.decEq ι + have := Classical.decEq ι -- Restrict to `s` rw [Nat.add_one] at hn have card_ι'_le : Fintype.card s ≤ n := by diff --git a/Mathlib/Combinatorics/Nullstellensatz.lean b/Mathlib/Combinatorics/Nullstellensatz.lean index 22bb48f127226e..5fc5d84d50ed2a 100644 --- a/Mathlib/Combinatorics/Nullstellensatz.lean +++ b/Mathlib/Combinatorics/Nullstellensatz.lean @@ -178,7 +178,7 @@ private lemma Alon.of_mem_P_support {ι : Type*} (i : ι) (S : Finset R) (m : ι rw [hP, support_rename_of_injective (Function.injective_of_subsingleton _)] at hm simp only [Finset.mem_image, mem_support_iff, ne_eq] at hm obtain ⟨e, he, hm⟩ := hm - haveI : Nontrivial R := nontrivial_of_ne _ _ he + have : Nontrivial R := nontrivial_of_ne _ _ he refine ⟨e (), ?_, ?_⟩ · suffices e ≼[lex] single () #S by simpa [MonomialOrder.lex_le_iff_of_unique] using this @@ -210,7 +210,7 @@ theorem combinatorial_nullstellensatz_exists_linearCombination ∃ (h : σ →₀ MvPolynomial σ R), (∀ i, ((∏ s ∈ S i, (X i - C s)) * h i).totalDegree ≤ f.totalDegree) ∧ f = linearCombination (MvPolynomial σ R) (fun i ↦ ∏ r ∈ S i, (X i - C r)) h := by - letI : LinearOrder σ := WellOrderingRel.isWellOrder.linearOrder + let : LinearOrder σ := WellOrderingRel.isWellOrder.linearOrder obtain ⟨h, r, hf, hh, hr⟩ := degLex.div (b := fun i ↦ Alon.P (S i) i) (fun i ↦ by simp only [(Alon.monic_P ..).leadingCoeff_eq_one, isUnit_one]) f use h diff --git a/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean b/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean index 3b62bb027300c8..fdd7d3948251ce 100644 --- a/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean +++ b/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean @@ -69,7 +69,7 @@ theorem dart_fst_fiber_card_eq_degree [DecidableEq V] (v : V) : card_image_of_injective univ (G.dartOfNeighborSet_injective v) theorem dart_card_eq_sum_degrees : Fintype.card G.Dart = ∑ v, G.degree v := by - haveI := Classical.decEq V + have := Classical.decEq V simp only [← card_univ, ← dart_fst_fiber_card_eq_degree] exact card_eq_sum_card_fiberwise (by simp) @@ -160,7 +160,7 @@ theorem odd_card_odd_degree_vertices_ne [Fintype V] [DecidableEq V] [DecidableRe theorem exists_ne_odd_degree_of_exists_odd_degree [Fintype V] [DecidableRel G.Adj] (v : V) (h : Odd (G.degree v)) : ∃ w : V, w ≠ v ∧ Odd (G.degree w) := by - haveI := Classical.decEq V + have := Classical.decEq V rcases G.odd_card_odd_degree_vertices_ne v h with ⟨k, hg⟩ have hg' : 0 < #{w | w ≠ v ∧ Odd (G.degree w)} := by rw [hg] diff --git a/Mathlib/Combinatorics/SimpleGraph/Finsubgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Finsubgraph.lean index 41eeb98124fe6b..91a74d9b7585aa 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finsubgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finsubgraph.lean @@ -156,9 +156,9 @@ theorem nonempty_hom_of_forall_finite_subgraph_hom [Finite W] -- Obtain a `Fintype` instance for `W`. cases nonempty_fintype W -- Establish the required interface instances. - haveI : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' => + have : ∀ G' : G.Finsubgraphᵒᵖ, Nonempty ((finsubgraphHomFunctor G F).obj G') := fun G' => ⟨h G'.unop G'.unop.property⟩ - haveI : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by + have : ∀ G' : G.Finsubgraphᵒᵖ, Fintype ((finsubgraphHomFunctor G F).obj G') := by intro G' haveI : Fintype (G'.unop.val.verts : Type u) := G'.unop.property.fintype haveI : Fintype (↥G'.unop.val.verts → W) := by classical exact Pi.instFintype diff --git a/Mathlib/Combinatorics/SimpleGraph/Matching.lean b/Mathlib/Combinatorics/SimpleGraph/Matching.lean index 87b8654c30b185..ace4d61a420733 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Matching.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Matching.lean @@ -309,7 +309,7 @@ lemma even_card_of_isPerfectMatching [Fintype V] [DecidableEq V] [DecidableRel G `[SetLike X], X → Set α → Sort _` are blocked by the discrimination tree. This can be fixed by redeclaring the instance for `X` using the double coercion but the proper fix seems to avoid the double coercion. -/ - letI : DecidablePred fun x ↦ x ∈ (M.induce c.supp).verts := fun a ↦ G.instDecidableMemSupp c a + let : DecidablePred fun x ↦ x ∈ (M.induce c.supp).verts := fun a ↦ G.instDecidableMemSupp c a have := (hM.induce_connectedComponent_isMatching c).even_card simp only [Subgraph.induce_verts, Set.toFinset_card] at this exact this @@ -331,9 +331,9 @@ lemma odd_matches_node_outside [Finite V] {u : Set V} and_true] at hv' ⊢ trivial apply Nat.not_even_iff_odd.2 c.prop - haveI : Fintype ↑(Subgraph.induce M (Subtype.val '' supp c.val)).verts := Fintype.ofFinite _ + have : Fintype ↑(Subgraph.induce M (Subtype.val '' supp c.val)).verts := Fintype.ofFinite _ classical - haveI := Fintype.ofFinite c.val.supp + have := Fintype.ofFinite c.val.supp simpa [Finset.card_image_of_injective] using hMmatch.even_card end Finite diff --git a/Mathlib/Combinatorics/SimpleGraph/Operations.lean b/Mathlib/Combinatorics/SimpleGraph/Operations.lean index 43932a8732e0b1..19ba94a37b0bfa 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Operations.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Operations.lean @@ -220,7 +220,7 @@ instance : Fintype (edge s t).edgeSet := by rw [edge]; infer_instance theorem edgeFinset_sup_edge [Fintype (edgeSet (G ⊔ edge s t))] (hn : ¬G.Adj s t) (h : s ≠ t) : (G ⊔ edge s t).edgeFinset = G.edgeFinset.cons s(s, t) (by simp_all) := by - letI := Classical.decEq V + let := Classical.decEq V rw [edgeFinset_sup, cons_eq_insert, insert_eq, union_comm] simp_rw [edgeFinset, edgeSet_edge_of_ne h]; rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Prod.lean b/Mathlib/Combinatorics/SimpleGraph/Prod.lean index 77766e4de029b2..6523376a74b33c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Prod.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Prod.lean @@ -208,18 +208,18 @@ protected theorem Preconnected.ofBoxProdRight [Nonempty α] (h : (G □ H).Preco exact ⟨w.ofBoxProdRight⟩ protected theorem Connected.boxProd (hG : G.Connected) (hH : H.Connected) : (G □ H).Connected := by - haveI := hG.nonempty - haveI := hH.nonempty + have := hG.nonempty + have := hH.nonempty exact ⟨hG.preconnected.boxProd hH.preconnected⟩ protected theorem Connected.ofBoxProdLeft (h : (G □ H).Connected) : G.Connected := by - haveI := (nonempty_prod.1 h.nonempty).1 - haveI := (nonempty_prod.1 h.nonempty).2 + have := (nonempty_prod.1 h.nonempty).1 + have := (nonempty_prod.1 h.nonempty).2 exact ⟨h.preconnected.ofBoxProdLeft⟩ protected theorem Connected.ofBoxProdRight (h : (G □ H).Connected) : H.Connected := by - haveI := (nonempty_prod.1 h.nonempty).1 - haveI := (nonempty_prod.1 h.nonempty).2 + have := (nonempty_prod.1 h.nonempty).1 + have := (nonempty_prod.1 h.nonempty).2 exact ⟨h.preconnected.ofBoxProdRight⟩ @[simp] @@ -243,7 +243,7 @@ theorem neighborFinset_boxProd (x : α × β) (G.neighborFinset x.1 ×ˢ {x.2}).disjUnion ({x.1} ×ˢ H.neighborFinset x.2) (Finset.disjoint_product.mpr <| Or.inl <| neighborFinset_disjoint_singleton _ _) := by -- swap out the fintype instance for the canonical one - letI : Fintype ((G □ H).neighborSet x) := SimpleGraph.boxProdFintypeNeighborSet _ + let : Fintype ((G □ H).neighborSet x) := SimpleGraph.boxProdFintypeNeighborSet _ convert_to (G □ H).neighborFinset x = _ using 2 exact Eq.trans (Finset.map_map _ _ _) Finset.attach_map_val diff --git a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean index bda19262960e8e..c4e84e9b3d8ae7 100644 --- a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean +++ b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -173,7 +173,7 @@ theorem IsSRGWith.param_eq {V : Type u} [Fintype V] (G : SimpleGraph V) [DecidableRel G.Adj] (h : G.IsSRGWith n k ℓ μ) (hn : 0 < n) : k * (k - ℓ - 1) = (n - k - 1) * μ := by - letI := Classical.decEq V + let := Classical.decEq V rw [← h.card, Fintype.card_pos_iff] at hn obtain ⟨v⟩ := hn convert! card_mul_eq_card_mul G.Adj (s := G.neighborFinset v) (t := Gᶜ.neighborFinset v) _ _ diff --git a/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean b/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean index 79107f325d24c5..730fae530d9c62 100644 --- a/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean +++ b/Mathlib/Combinatorics/SimpleGraph/UniversalVerts.lean @@ -52,7 +52,7 @@ lemma Subgraph.IsMatching.exists_of_universalVerts [Finite V] {s : Set V} refine ⟨t, ht.1, ?_⟩ obtain ⟨f⟩ : Nonempty (s ≃ t) := by rw [← Cardinal.eq, ← t.cast_ncard t.toFinite, ← s.cast_ncard s.toFinite, ht.2] - letI hd := Set.disjoint_of_subset_left ht.1 h + let hd := Set.disjoint_of_subset_left ht.1 h have hadj (v : s) : G.Adj v (f v) := ht.1 (f v).2 (hd.ne_of_mem (f v).2 v.2) |>.symm exact Subgraph.IsMatching.exists_of_disjoint_sets_of_equiv hd.symm f hadj diff --git a/Mathlib/Computability/Primrec/Basic.lean b/Mathlib/Computability/Primrec/Basic.lean index f120385f6f3f83..54aec2d4fd1113 100644 --- a/Mathlib/Computability/Primrec/Basic.lean +++ b/Mathlib/Computability/Primrec/Basic.lean @@ -683,7 +683,7 @@ theorem list_idxOf₁ [DecidableEq α] (l : List α) : Primrec fun a => l.idxOf theorem dom_finite [Finite α] (f : α → σ) : Primrec f := let ⟨l, _, m⟩ := Finite.exists_univ_list α option_some_iff.1 <| by - haveI := decidableEqOfEncodable α + have := decidableEqOfEncodable α refine ((list_getElem?₁ (l.map f)).comp (list_idxOf₁ l)).of_eq fun a => ?_ rw [List.getElem?_map, List.getElem?_idxOf (m a), Option.map_some] @@ -857,14 +857,14 @@ variable [Primcodable α] [Primcodable β] [Primcodable σ] theorem subtype_val {p : α → Prop} [DecidablePred p] {hp : PrimrecPred p} : haveI := Primcodable.subtype hp Primrec (@Subtype.val α p) := by - letI := Primcodable.subtype hp + let := Primcodable.subtype hp refine (Primcodable.prim (Subtype p)).of_eq fun n => ?_ rcases @decode (Subtype p) _ n with (_ | ⟨a, h⟩) <;> rfl theorem subtype_val_iff {p : β → Prop} [DecidablePred p] {hp : PrimrecPred p} {f : α → Subtype p} : haveI := Primcodable.subtype hp (Primrec fun a => (f a).1) ↔ Primrec f := by - letI := Primcodable.subtype hp + let := Primcodable.subtype hp refine ⟨fun h => ?_, fun hf => subtype_val.comp hf⟩ refine Nat.Primrec.of_eq h fun n => ?_ rcases @decode α _ n with - | a; · rfl @@ -892,7 +892,7 @@ theorem ulower_up : Primrec (ULower.up : ULower α → α) := option_get (Primrec.decode₂.comp (subtype_val (hp := Primcodable.mem_range_encode))) theorem fin_val_iff {n} {f : α → Fin n} : (Primrec fun a => (f a).1) ↔ Primrec f := by - letI : Primcodable { a // a < n } := Primcodable.subtype (nat_lt.comp .id (const _)) + let : Primcodable { a // a < n } := Primcodable.subtype (nat_lt.comp .id (const _)) exact (Iff.trans (by rfl) subtype_val_iff).trans (of_equiv_iff _) theorem fin_val {n} : Primrec (fun (i : Fin n) => (i : ℕ)) := diff --git a/Mathlib/Computability/Primrec/List.lean b/Mathlib/Computability/Primrec/List.lean index d27fe68baba292..1149e4f5cb9e22 100644 --- a/Mathlib/Computability/Primrec/List.lean +++ b/Mathlib/Computability/Primrec/List.lean @@ -55,7 +55,7 @@ set_option backward.privateInPublic true in private theorem list_foldl' {f : α → List β} {g : α → σ} {h : α → σ × β → σ} (hf : haveI := prim H; Primrec f) (hg : Primrec g) (hh : haveI := prim H; Primrec₂ h) : Primrec fun a => (f a).foldl (fun s b => h a (s, b)) (g a) := by - letI := prim H + let := prim H let G (a : α) (IH : σ × List β) : σ × List β := List.casesOn IH.2 IH fun b l => (h a (IH.1, b), l) have hG : Primrec₂ G := list_casesOn' H (snd.comp snd) snd <| to₂ <| @@ -306,7 +306,7 @@ theorem nat_omega_rec' (f : β → σ) {m : β → ℕ} {l : β → List β} {g (hm : Primrec m) (hl : Primrec l) (hg : Primrec₂ g) (Ord : ∀ b, ∀ b' ∈ l b, m b' < m b) (H : ∀ b, g b ((l b).map f) = some (f b)) : Primrec f := by - haveI : DecidableEq β := Encodable.decidableEqOfEncodable β + have : DecidableEq β := Encodable.decidableEqOfEncodable β let mapGraph (M : List (β × σ)) (bs : List β) : List σ := bs.flatMap (Option.toList <| M.lookup ·) let bindList (b : β) : ℕ → List β := fun n ↦ n.rec [b] fun _ bs ↦ bs.flatMap l let graph (b : β) : ℕ → List (β × σ) := fun i ↦ i.rec [] fun i ih ↦ diff --git a/Mathlib/Computability/TuringMachine/PostTuringMachine.lean b/Mathlib/Computability/TuringMachine/PostTuringMachine.lean index e0d80394355756..5d510545c4cbba 100644 --- a/Mathlib/Computability/TuringMachine/PostTuringMachine.lean +++ b/Mathlib/Computability/TuringMachine/PostTuringMachine.lean @@ -635,7 +635,7 @@ theorem exists_enc_dec [Inhabited Γ] [Finite Γ] : ∃ (n : ℕ) (enc : Γ → List.Vector Bool n) (dec : List.Vector Bool n → Γ), enc default = List.Vector.replicate n false ∧ ∀ a, dec (enc a) = a := by rcases Finite.exists_equiv_fin Γ with ⟨n, ⟨e⟩⟩ - letI : DecidableEq Γ := e.decidableEq + let : DecidableEq Γ := e.decidableEq let G : Fin n ↪ Fin n → Bool := ⟨fun a b ↦ a = b, fun a b h ↦ Bool.of_decide_true <| (congr_fun h b).trans <| Bool.decide_true rfl⟩ diff --git a/Mathlib/Condensed/Discrete/Characterization.lean b/Mathlib/Condensed/Discrete/Characterization.lean index 4ec71ead5d9179..50046d821d15f9 100644 --- a/Mathlib/Condensed/Discrete/Characterization.lean +++ b/Mathlib/Condensed/Discrete/Characterization.lean @@ -148,13 +148,13 @@ theorem isDiscrete_tfae (M : CondensedMod.{u} R) : intro h rw [isDiscrete_iff_isDiscrete_forget, ((CondensedSet.isDiscrete_tfae _).out 0 6 :)] intro S - letI : PreservesFilteredColimitsOfSize.{u, u} (forget (ModuleCat R)) := + let : PreservesFilteredColimitsOfSize.{u, u} (forget (ModuleCat R)) := preservesFilteredColimitsOfSize_shrink.{u, u + 1, u, u + 1} _ exact ⟨isColimitOfPreserves (forget (ModuleCat R)) (h S).some⟩ tfae_have 1 → 7 := by intro h S rw [isDiscrete_iff_isDiscrete_forget, ((CondensedSet.isDiscrete_tfae _).out 0 6 :)] at h - letI : ReflectsFilteredColimitsOfSize.{u, u} (forget (ModuleCat R)) := + let : ReflectsFilteredColimitsOfSize.{u, u} (forget (ModuleCat R)) := reflectsFilteredColimitsOfSize_shrink.{u, u + 1, u, u + 1} _ exact ⟨isColimitOfReflects (forget (ModuleCat R)) (h S).some⟩ tfae_finish @@ -252,13 +252,13 @@ theorem isDiscrete_tfae (M : LightCondMod.{u} R) : intro h rw [isDiscrete_iff_isDiscrete_forget, ((LightCondSet.isDiscrete_tfae _).out 0 5 :)] intro S - letI : PreservesFilteredColimitsOfSize.{0, 0} (forget (ModuleCat R)) := + let : PreservesFilteredColimitsOfSize.{0, 0} (forget (ModuleCat R)) := preservesFilteredColimitsOfSize_shrink.{0, u, 0, u} _ exact ⟨isColimitOfPreserves (forget (ModuleCat R)) (h S).some⟩ tfae_have 1 → 6 := by intro h S rw [isDiscrete_iff_isDiscrete_forget, ((LightCondSet.isDiscrete_tfae _).out 0 5 :)] at h - letI : ReflectsFilteredColimitsOfSize.{0, 0} (forget (ModuleCat R)) := + let : ReflectsFilteredColimitsOfSize.{0, 0} (forget (ModuleCat R)) := reflectsFilteredColimitsOfSize_shrink.{0, u, 0, u} _ exact ⟨isColimitOfReflects (forget (ModuleCat R)) (h S).some⟩ tfae_finish diff --git a/Mathlib/Condensed/Discrete/LocallyConstant.lean b/Mathlib/Condensed/Discrete/LocallyConstant.lean index aeadb3ecb9f5d6..243892767a9913 100644 --- a/Mathlib/Condensed/Discrete/LocallyConstant.lean +++ b/Mathlib/Condensed/Discrete/LocallyConstant.lean @@ -350,7 +350,7 @@ noncomputable def adjunction [HasExplicitFiniteCoproducts.{u} P] : ext (x : X.obj.obj _) dsimp have := CompHausLike.preregular hs - letI : PreservesFiniteProducts ((sheafToPresheaf (coherentTopology _) _).obj X) := + let : PreservesFiniteProducts ((sheafToPresheaf (coherentTopology _) _).obj X) := inferInstanceAs (PreservesFiniteProducts X.obj) apply presheaf_ext ((unit P hs).app _ x) intro a diff --git a/Mathlib/Data/Analysis/Topology.lean b/Mathlib/Data/Analysis/Topology.lean index 8af8bb6e22b76f..bb9c59b9a76c52 100644 --- a/Mathlib/Data/Analysis/Topology.lean +++ b/Mathlib/Data/Analysis/Topology.lean @@ -135,7 +135,7 @@ theorem isClosed_iff [TopologicalSpace α] (F : Realizer α) {s : Set α} : F.isOpen_iff.trans <| forall_congr' fun a ↦ show (a ∉ s → ∃ b : F.σ, a ∈ F.F b ∧ ∀ z ∈ F.F b, z ∉ s) ↔ _ by - haveI := Classical.propDecidable; rw [not_imp_comm] + have := Classical.propDecidable; rw [not_imp_comm] simp [not_exists, not_and, not_forall, and_comm] theorem mem_interior_iff [TopologicalSpace α] (F : Realizer α) {s : Set α} {a : α} : diff --git a/Mathlib/Data/DFinsupp/Defs.lean b/Mathlib/Data/DFinsupp/Defs.lean index feccf9203b85e9..eeb6c9478f63da 100644 --- a/Mathlib/Data/DFinsupp/Defs.lean +++ b/Mathlib/Data/DFinsupp/Defs.lean @@ -884,7 +884,7 @@ instance decidableZero [∀ (i) (x : β i), Decidable (x = 0)] (f : Π₀ i, β case mp => intro hs₁; ext i -- This instance prevent consuming `DecidableEq ι` in the next `by_cases`. - letI := Classical.propDecidable + let := Classical.propDecidable by_cases hs₂ : i ∈ s.val case pos => exact hs₁ _ hs₂ case neg => exact (s.prop i).resolve_left hs₂ diff --git a/Mathlib/Data/DFinsupp/FiniteInfinite.lean b/Mathlib/Data/DFinsupp/FiniteInfinite.lean index a1efaa0e13f44d..f87d0596508b63 100644 --- a/Mathlib/Data/DFinsupp/FiniteInfinite.lean +++ b/Mathlib/Data/DFinsupp/FiniteInfinite.lean @@ -34,7 +34,7 @@ instance DFinsupp.fintype {ι : Sort _} {π : ι → Sort _} [DecidableEq ι] [ instance DFinsupp.infinite_of_left {ι : Sort _} {π : ι → Sort _} [∀ i, Nontrivial (π i)] [∀ i, Zero (π i)] [Infinite ι] : Infinite (Π₀ i, π i) := by - letI := Classical.decEq ι; choose m hm using fun i => exists_ne (0 : π i) + let := Classical.decEq ι; choose m hm using fun i => exists_ne (0 : π i) exact Infinite.of_injective _ (DFinsupp.single_left_injective hm) /-- See `DFinsupp.infinite_of_right` for this in instance form, with the drawback that diff --git a/Mathlib/Data/DFinsupp/WellFounded.lean b/Mathlib/Data/DFinsupp/WellFounded.lean index 9826cab5551827..811b6320f24fe2 100644 --- a/Mathlib/Data/DFinsupp/WellFounded.lean +++ b/Mathlib/Data/DFinsupp/WellFounded.lean @@ -189,8 +189,8 @@ theorem Pi.Lex.wellFounded [IsStrictTotalOrder ι r] [Finite ι] (hs : ∀ i, We WellFounded (Pi.Lex r (fun {i} ↦ s i)) := by obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i) · convert! emptyWf.wf - letI : ∀ i, Zero (α i) := fun i => ⟨(hs i).min ⊤ ⟨x i, trivial⟩⟩ - haveI := Fintype.ofFinite ι + let : ∀ i, Zero (α i) := fun i => ⟨(hs i).min ⊤ ⟨x i, trivial⟩⟩ + have := Fintype.ofFinite ι refine InvImage.wf equivFunOnFintype.symm (Lex.wellFounded' (fun i a => ?_) hs ?_) exacts [(hs i).not_lt_min ⊤ trivial, Finite.wellFounded_of_trans_of_irrefl (Function.swap r)] @@ -246,8 +246,8 @@ instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, Well ⟨by obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i) · convert! emptyWf.wf - letI : ∀ i, Zero (α i) := fun i => ⟨(hw i).wf.min ⊤ ⟨x i, trivial⟩⟩ - haveI := Fintype.ofFinite ι + let : ∀ i, Zero (α i) := fun i => ⟨(hw i).wf.min ⊤ ⟨x i, trivial⟩⟩ + have := Fintype.ofFinite ι refine InvImage.wf equivFunOnFintype.symm (DFinsupp.wellFoundedLT fun i a => ?_).wf exact (hw i).wf.not_lt_min ⊤ trivial⟩ diff --git a/Mathlib/Data/ENNReal/Operations.lean b/Mathlib/Data/ENNReal/Operations.lean index 6b159c27b59719..188771aeb1a05e 100644 --- a/Mathlib/Data/ENNReal/Operations.lean +++ b/Mathlib/Data/ENNReal/Operations.lean @@ -644,7 +644,7 @@ lemma iSup_add [Nonempty ι] (f : ι → ℝ≥0∞) : (⨆ i, f i) + a = ⨆ i, lemma add_biSup' {p : ι → Prop} (h : ∃ i, p i) (f : ι → ℝ≥0∞) : a + ⨆ i, ⨆ _ : p i, f i = ⨆ i, ⨆ _ : p i, a + f i := by - haveI : Nonempty {i // p i} := nonempty_subtype.2 h + have : Nonempty {i // p i} := nonempty_subtype.2 h simp only [iSup_subtype', add_iSup] lemma biSup_add' {p : ι → Prop} (h : ∃ i, p i) (f : ι → ℝ≥0∞) : diff --git a/Mathlib/Data/ENat/Lattice.lean b/Mathlib/Data/ENat/Lattice.lean index b01e851d604887..ded4493d69fee1 100644 --- a/Mathlib/Data/ENat/Lattice.lean +++ b/Mathlib/Data/ENat/Lattice.lean @@ -195,7 +195,7 @@ lemma iSup_add [Nonempty ι] (f : ι → ℕ∞) : (⨆ i, f i) + a = ⨆ i, f i lemma add_biSup' {p : ι → Prop} (h : ∃ i, p i) (f : ι → ℕ∞) : a + ⨆ i, ⨆ _ : p i, f i = ⨆ i, ⨆ _ : p i, a + f i := by - haveI : Nonempty {i // p i} := nonempty_subtype.2 h + have : Nonempty {i // p i} := nonempty_subtype.2 h simp only [iSup_subtype', add_iSup] lemma biSup_add' {p : ι → Prop} (h : ∃ i, p i) (f : ι → ℕ∞) : diff --git a/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean b/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean index 34f9abdd539be6..e52150e65f7b90 100644 --- a/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean +++ b/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean @@ -40,7 +40,7 @@ theorem bubble_sort_induction' {n : ℕ} {α : Type*} [LinearOrder α] {f : Fin (h : ∀ (σ : Equiv.Perm (Fin n)) (i j : Fin n), i < j → (f ∘ σ) j < (f ∘ σ) i → P (f ∘ σ) → P (f ∘ σ ∘ Equiv.swap i j)) : P (f ∘ sort f) := by - letI := @Preorder.lift _ (Lex (Fin n → α)) _ fun σ : Equiv.Perm (Fin n) => toLex (f ∘ σ) + let := @Preorder.lift _ (Lex (Fin n → α)) _ fun σ : Equiv.Perm (Fin n) => toLex (f ∘ σ) refine @WellFounded.induction_bot' _ _ _ (IsWellFounded.wf : WellFounded (· < ·)) (Equiv.refl _) (sort f) P (fun σ => f ∘ σ) (fun σ hσ hfσ => ?_) hf diff --git a/Mathlib/Data/Finite/Prod.lean b/Mathlib/Data/Finite/Prod.lean index 7b421a871790c3..50cf574e7cb635 100644 --- a/Mathlib/Data/Finite/Prod.lean +++ b/Mathlib/Data/Finite/Prod.lean @@ -25,8 +25,8 @@ variable {α β : Type*} namespace Finite instance [Finite α] [Finite β] : Finite (α × β) := by - haveI := Fintype.ofFinite α - haveI := Fintype.ofFinite β + have := Fintype.ofFinite α + have := Fintype.ofFinite β infer_instance instance {α β : Sort*} [Finite α] [Finite β] : Finite (PProd α β) := @@ -47,8 +47,8 @@ lemma Prod.finite_iff [Nonempty α] [Nonempty β] : Finite (α × β) ↔ Finite instance Pi.finite {α : Sort*} {β : α → Sort*} [Finite α] [∀ a, Finite (β a)] : Finite (∀ a, β a) := by classical - haveI := Fintype.ofFinite (PLift α) - haveI := fun a => Fintype.ofFinite (PLift (β a)) + have := Fintype.ofFinite (PLift α) + have := fun a => Fintype.ofFinite (PLift (β a)) exact Finite.of_equiv (∀ a : PLift α, PLift (β (Equiv.plift a))) (Equiv.piCongr Equiv.plift fun _ => Equiv.plift) @@ -57,7 +57,7 @@ instance Function.Embedding.finite {α β : Sort*} [Finite β] : Finite (α ↪ rcases isEmpty_or_nonempty (α ↪ β) with _ | h · infer_instance · refine h.elim fun f => ?_ - haveI : Finite α := Finite.of_injective _ f.injective + have : Finite α := Finite.of_injective _ f.injective exact Finite.of_injective _ DFunLike.coe_injective instance Equiv.finite_right {α β : Sort*} [Finite β] : Finite (α ≃ β) := diff --git a/Mathlib/Data/Finite/Sigma.lean b/Mathlib/Data/Finite/Sigma.lean index b9c65110831698..256c3465df9a6a 100644 --- a/Mathlib/Data/Finite/Sigma.lean +++ b/Mathlib/Data/Finite/Sigma.lean @@ -19,8 +19,8 @@ variable {α : Type*} namespace Finite instance {β : α → Type*} [Finite α] [∀ a, Finite (β a)] : Finite (Σ a, β a) := by - letI := Fintype.ofFinite α - letI := fun a => Fintype.ofFinite (β a) + let := Fintype.ofFinite α + let := fun a => Fintype.ofFinite (β a) infer_instance instance {ι : Sort*} {π : ι → Sort*} [Finite ι] [∀ i, Finite (π i)] : Finite (Σ' i, π i) := diff --git a/Mathlib/Data/Finite/Sum.lean b/Mathlib/Data/Finite/Sum.lean index 62f7e64b2e818d..674e91adacfcb6 100644 --- a/Mathlib/Data/Finite/Sum.lean +++ b/Mathlib/Data/Finite/Sum.lean @@ -18,8 +18,8 @@ variable {α β : Type*} namespace Finite instance [Finite α] [Finite β] : Finite (α ⊕ β) := by - haveI := Fintype.ofFinite α - haveI := Fintype.ofFinite β + have := Fintype.ofFinite α + have := Fintype.ofFinite β infer_instance theorem sum_left (β) [Finite (α ⊕ β)] : Finite α := diff --git a/Mathlib/Data/Finite/Vector.lean b/Mathlib/Data/Finite/Vector.lean index d7aceb37ae1446..045144d62cebb7 100644 --- a/Mathlib/Data/Finite/Vector.lean +++ b/Mathlib/Data/Finite/Vector.lean @@ -16,10 +16,10 @@ public section variable {α : Type*} instance List.Vector.finite [Finite α] {n : ℕ} : Finite (Vector α n) := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α infer_instance instance [Finite α] {n : ℕ} : Finite (Sym α n) := by classical - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α infer_instance diff --git a/Mathlib/Data/Finset/Fold.lean b/Mathlib/Data/Finset/Fold.lean index 29130f8c9aca33..16aa414d5ab191 100644 --- a/Mathlib/Data/Finset/Fold.lean +++ b/Mathlib/Data/Finset/Fold.lean @@ -116,7 +116,7 @@ theorem fold_image_idem [DecidableEq α] {g : γ → α} {s : Finset γ} [hi : S induction s using Finset.cons_induction with | empty => rw [fold_empty, image_empty, fold_empty] | cons x xs hx ih => - haveI := Classical.decEq γ + have := Classical.decEq γ rw [fold_cons, cons_eq_insert, image_insert, fold_insert_idem, ih] simp only [Function.comp_apply] diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index c6c5fb2cf921cb..ecfc861c076427 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -696,7 +696,7 @@ theorem subset_set_image_iff [DecidableEq β] {s : Set α} {t : Finset β} {f : ↑t ⊆ f '' s ↔ ∃ s' : Finset α, ↑s' ⊆ s ∧ s'.image f = t := by constructor · intro h - letI : CanLift β s (f ∘ (↑)) fun y => y ∈ f '' s := ⟨fun y ⟨x, hxt, hy⟩ => ⟨⟨x, hxt⟩, hy⟩⟩ + let : CanLift β s (f ∘ (↑)) fun y => y ∈ f '' s := ⟨fun y ⟨x, hxt, hy⟩ => ⟨⟨x, hxt⟩, hy⟩⟩ lift t to Finset s using h refine ⟨t.map (Embedding.subtype _), map_subtype_subset _, ?_⟩ ext y; simp diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index 6b25b519cddedc..d16bab002decea 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -193,8 +193,8 @@ theorem sup_coe {P : α → Prop} {Pbot : P ⊥} {Psup : ∀ ⦃x y⦄, P x → letI := Subtype.semilatticeSup Psup letI := Subtype.orderBot Pbot (t.sup f).val = t.sup fun x => ↑(f x) := by - letI := Subtype.semilatticeSup Psup - letI := Subtype.orderBot Pbot + let := Subtype.semilatticeSup Psup + let := Subtype.orderBot Pbot apply apply_sup_eq_sup_comp Subtype.val <;> intros <;> rfl @[simp] @@ -771,7 +771,7 @@ theorem map_finset_sup [DecidableEq α] [DecidableEq β] (s : Finset γ) (f : γ theorem count_finset_sup [DecidableEq β] (s : Finset α) (f : α → Multiset β) (b : β) : count b (s.sup f) = s.sup fun a => count b (f a) := by - letI := Classical.decEq α + let := Classical.decEq α refine s.induction ?_ ?_ · exact count_zero _ · intro i s _ ih diff --git a/Mathlib/Data/Finset/Preimage.lean b/Mathlib/Data/Finset/Preimage.lean index ce8b341335b897..b84ccb84d821d5 100644 --- a/Mathlib/Data/Finset/Preimage.lean +++ b/Mathlib/Data/Finset/Preimage.lean @@ -156,7 +156,7 @@ lemma sup_preimage_val_id [Lattice α] [OrderBot α] {P : α → Prop} letI := Subtype.orderBot Pbot (t.preimage Subtype.val Subtype.val_injective.injOn).sup id = (⟨t.sup id, sup_induction Pbot (fun _ h _ => Psup h) ht⟩ : Subtype P) := by - letI : OrderBot (Subtype P) := Subtype.orderBot Pbot + let : OrderBot (Subtype P) := Subtype.orderBot Pbot ext simp only [sup_coe, id_eq] apply sup_preimage_self diff --git a/Mathlib/Data/Finset/Slice.lean b/Mathlib/Data/Finset/Slice.lean index 8f693aee928be5..7a146bd63ee4f4 100644 --- a/Mathlib/Data/Finset/Slice.lean +++ b/Mathlib/Data/Finset/Slice.lean @@ -148,7 +148,7 @@ theorem biUnion_slice [DecidableEq α] : (Iic <| Fintype.card α).biUnion 𝒜.s @[simp] theorem sum_card_slice : ∑ r ∈ Iic (Fintype.card α), #(𝒜 # r) = #𝒜 := by - letI := Classical.decEq α + let := Classical.decEq α rw [← card_biUnion, biUnion_slice] exact Finset.pairwiseDisjoint_slice.subset (Set.subset_univ _) diff --git a/Mathlib/Data/Finset/Sort.lean b/Mathlib/Data/Finset/Sort.lean index 42d098fba84e1b..6eace95eb3ee01 100644 --- a/Mathlib/Data/Finset/Sort.lean +++ b/Mathlib/Data/Finset/Sort.lean @@ -350,6 +350,6 @@ def Fintype.orderIsoFinOfCardEq lemma nonempty_orderEmbedding_of_finite_infinite (α : Type*) [LinearOrder α] [hα : Finite α] (β : Type*) [LinearOrder β] [hβ : Infinite β] : Nonempty (α ↪o β) := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α obtain ⟨s, hs⟩ := Infinite.exists_subset_card_eq β (Fintype.card α) exact ⟨((Fintype.orderIsoFinOfCardEq α rfl).symm.toOrderEmbedding).trans (s.orderEmbOfFin hs)⟩ diff --git a/Mathlib/Data/Fintype/CardEmbedding.lean b/Mathlib/Data/Fintype/CardEmbedding.lean index 08e24c7ad64839..a73e45ac82c8f3 100644 --- a/Mathlib/Data/Fintype/CardEmbedding.lean +++ b/Mathlib/Data/Fintype/CardEmbedding.lean @@ -42,7 +42,7 @@ theorem card_embedding_eq {α β : Type*} [Fintype α] [Fintype β] [emb : Finty rw [Subsingleton.elim emb Embedding.fintype] refine Fintype.induction_empty_option (P := fun t ↦ ‖t ↪ β‖ = ‖β‖.descFactorial ‖t‖) (fun α₁ α₂ h₂ e ih ↦ ?_) (?_) (fun γ h ih ↦ ?_) α <;> clear! α - · letI := Fintype.ofEquiv _ e.symm + · let := Fintype.ofEquiv _ e.symm rw [← card_congr (Equiv.embeddingCongr e (Equiv.refl β)), ih, card_congr e] · rw [card_pempty, Nat.descFactorial_zero, card_eq_one_iff] exact ⟨Embedding.ofIsEmpty, fun x ↦ DFunLike.ext _ _ isEmptyElim⟩ diff --git a/Mathlib/Data/Fintype/EquivFin.lean b/Mathlib/Data/Fintype/EquivFin.lean index 5d004ad9f28f5f..00976b3e45105a 100644 --- a/Mathlib/Data/Fintype/EquivFin.lean +++ b/Mathlib/Data/Fintype/EquivFin.lean @@ -535,7 +535,7 @@ set_option backward.privateInPublic true in private theorem natEmbeddingAux_injective (α : Type*) [Infinite α] : Function.Injective (natEmbeddingAux α) := by rintro m n h - letI := Classical.decEq α + let := Classical.decEq α wlog hmlen : m ≤ n generalizing m n · exact (this h.symm <| le_of_not_ge hmlen).symm by_contra hmn diff --git a/Mathlib/Data/Fintype/Pi.lean b/Mathlib/Data/Fintype/Pi.lean index ff970b9c1b4ac9..e04e7d7d844da2 100644 --- a/Mathlib/Data/Fintype/Pi.lean +++ b/Mathlib/Data/Fintype/Pi.lean @@ -103,7 +103,7 @@ lemma eval_image_piFinset (t : ∀ a, Finset (δ a)) (a : α) [DecidableEq (δ a lemma eval_image_piFinset_const {β} [DecidableEq β] (t : Finset β) (a : α) : ((piFinset fun _i : α ↦ t).image fun f ↦ f a) = t := by obtain rfl | ht := t.eq_empty_or_nonempty - · haveI : Nonempty α := ⟨a⟩ + · have : Nonempty α := ⟨a⟩ simp · exact eval_image_piFinset (fun _ ↦ t) a fun _ _ ↦ ht diff --git a/Mathlib/Data/Fintype/Prod.lean b/Mathlib/Data/Fintype/Prod.lean index af15f7d4eba125..3af498bdeb3901 100644 --- a/Mathlib/Data/Fintype/Prod.lean +++ b/Mathlib/Data/Fintype/Prod.lean @@ -70,7 +70,7 @@ theorem infinite_prod : Infinite (α × β) ↔ Infinite α ∧ Nonempty β ∨ H.elim (and_imp.2 <| @Prod.infinite_of_left α β) (and_imp.2 <| @Prod.infinite_of_right α β)⟩ rw [and_comm] rcases Infinite.nonempty (α × β) with ⟨a, b⟩ - contrapose! H; haveI := H.1 ⟨b⟩; haveI := H.2 ⟨a⟩ + contrapose! H; have := H.1 ⟨b⟩; have := H.2 ⟨a⟩ infer_instance instance Pi.infinite_of_left {ι : Sort*} {π : ι → Type*} [∀ i, Nontrivial <| π i] [Infinite ι] : diff --git a/Mathlib/Data/Holor.lean b/Mathlib/Data/Holor.lean index 0e22f8fdc84e3d..b7475620ba7423 100644 --- a/Mathlib/Data/Holor.lean +++ b/Mathlib/Data/Holor.lean @@ -218,7 +218,7 @@ theorem slice_zero [Zero α] (i : ℕ) (hid : i < d) : slice (0 : Holor α (d :: theorem slice_sum [AddCommMonoid α] {β : Type} (i : ℕ) (hid : i < d) (s : Finset β) (f : β → Holor α (d :: ds)) : (∑ x ∈ s, slice (f x) i hid) = slice (∑ x ∈ s, f x) i hid := by - letI := Classical.decEq β + let := Classical.decEq β refine Finset.induction_on s ?_ ?_ · simp [slice_zero] · intro _ _ h_not_in ih diff --git a/Mathlib/Data/Int/ModEq.lean b/Mathlib/Data/Int/ModEq.lean index 2af03e37ca02ab..af9eb4fd26e2d1 100644 --- a/Mathlib/Data/Int/ModEq.lean +++ b/Mathlib/Data/Int/ModEq.lean @@ -207,7 +207,7 @@ lemma of_mul_right (m : ℤ) : a ≡ b [ZMOD n * m] → a ≡ b [ZMOD n] := /-- To cancel a common factor `c` from a `ModEq` we must divide the modulus `m` by `gcd m c`. -/ theorem cancel_right_div_gcd (hm : 0 < m) (h : a * c ≡ b * c [ZMOD m]) : a ≡ b [ZMOD m / gcd m c] := by - letI d := gcd m c + let d := gcd m c rw [modEq_iff_dvd] at h ⊢ refine Int.dvd_of_dvd_mul_right_of_gcd_one (?_ : m / d ∣ c / d * (b - a)) ?_ · rw [mul_comm, ← Int.mul_ediv_assoc (b - a) (gcd_dvd_right ..), Int.sub_mul] diff --git a/Mathlib/Data/List/AList.lean b/Mathlib/Data/List/AList.lean index 69b8bcdd3809c6..25f3e41c871cf4 100644 --- a/Mathlib/Data/List/AList.lean +++ b/Mathlib/Data/List/AList.lean @@ -172,7 +172,7 @@ end theorem keys_subset_keys_of_entries_subset_entries {s₁ s₂ : AList β} (h : s₁.entries ⊆ s₂.entries) : s₁.keys ⊆ s₂.keys := by intro k hk - letI : DecidableEq α := Classical.decEq α + let : DecidableEq α := Classical.decEq α have := h (mem_lookup_iff.1 (Option.get_mem (lookup_isSome.2 hk))) rw [← mem_lookup_iff, Option.mem_def] at this rw [← mem_keys, ← lookup_isSome, this] diff --git a/Mathlib/Data/List/OffDiag.lean b/Mathlib/Data/List/OffDiag.lean index 14faa79e5d657f..59d9ea7e995ea7 100644 --- a/Mathlib/Data/List/OffDiag.lean +++ b/Mathlib/Data/List/OffDiag.lean @@ -84,14 +84,14 @@ protected theorem Perm.offDiag {l₁ l₂ : List α} (h : l₁ ~ l₂) : l₁.of classical simp_all [perm_iff_count, count_offDiag_eq_mul_sub_ite] protected theorem Nodup.offDiag (h : l.Nodup) : l.offDiag.Nodup := by - letI := Classical.decEq α + let := Classical.decEq α rw [nodup_iff_count_le_one] rintro ⟨x, y⟩ rw [count_offDiag_eq_mul_sub_ite l x y] grind protected theorem Nodup.of_offDiag (h : l.offDiag.Nodup) : l.Nodup := by - letI := Classical.decEq α + let := Classical.decEq α simp only [nodup_iff_count_le_one, Prod.forall, count_offDiag_eq_mul_sub_ite] at * intro a specialize h a a diff --git a/Mathlib/Data/Multiset/Powerset.lean b/Mathlib/Data/Multiset/Powerset.lean index ca861d006ad89e..b5341d26df26ec 100644 --- a/Mathlib/Data/Multiset/Powerset.lean +++ b/Mathlib/Data/Multiset/Powerset.lean @@ -150,13 +150,13 @@ theorem revzip_powersetAux_lemma {α : Type*} [DecidableEq α] (l : List α) {l' theorem revzip_powersetAux_perm_aux' {l : List α} : revzip (powersetAux l) ~ revzip (powersetAux' l) := by - haveI := Classical.decEq α + have := Classical.decEq α rw [revzip_powersetAux_lemma l revzip_powersetAux, revzip_powersetAux_lemma l revzip_powersetAux'] exact powersetAux_perm_powersetAux'.map _ theorem revzip_powersetAux_perm {l₁ l₂ : List α} (p : l₁ ~ l₂) : revzip (powersetAux l₁) ~ revzip (powersetAux l₂) := by - haveI := Classical.decEq α + have := Classical.decEq α simp only [fun l : List α => revzip_powersetAux_lemma l revzip_powersetAux, coe_eq_coe.2 p] exact (powersetAux_perm p).map _ diff --git a/Mathlib/Data/Multiset/ZeroCons.lean b/Mathlib/Data/Multiset/ZeroCons.lean index cf8fd0a7193fa7..bba540882d9761 100644 --- a/Mathlib/Data/Multiset/ZeroCons.lean +++ b/Mathlib/Data/Multiset/ZeroCons.lean @@ -218,7 +218,7 @@ theorem cons_ne_zero {a : α} {m : Multiset α} : a ::ₘ m ≠ 0 := theorem cons_eq_cons {a b : α} {as bs : Multiset α} : a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by - haveI : DecidableEq α := Classical.decEq α + have : DecidableEq α := Classical.decEq α constructor · intro eq by_cases h : a = b diff --git a/Mathlib/Data/Nat/Cast/Defs.lean b/Mathlib/Data/Nat/Cast/Defs.lean index 2c5591c4b1ac85..aa0ed1759839b7 100644 --- a/Mathlib/Data/Nat/Cast/Defs.lean +++ b/Mathlib/Data/Nat/Cast/Defs.lean @@ -156,7 +156,7 @@ protected abbrev AddMonoidWithOne.binary [AddMonoid R] [One R] : AddMonoidWithOn natCast := Nat.binCast, natCast_zero := by simp only [Nat.binCast], natCast_succ := fun n => by - letI : AddMonoidWithOne R := AddMonoidWithOne.unary + let : AddMonoidWithOne R := AddMonoidWithOne.unary rw [Nat.binCast_eq, Nat.binCast_eq, Nat.cast_succ] } theorem one_add_one_eq_two [AddMonoidWithOne R] : 1 + 1 = (2 : R) := by diff --git a/Mathlib/Data/Nat/Choose/Lucas.lean b/Mathlib/Data/Nat/Choose/Lucas.lean index b2192eea6d83e0..491d55b7b34fff 100644 --- a/Mathlib/Data/Nat/Choose/Lucas.lean +++ b/Mathlib/Data/Nat/Choose/Lucas.lean @@ -192,7 +192,7 @@ lemma primeFactors_gcd_choose_of_isPrimePow (h : IsPrimePow n) : intro p hp simp only [mem_primeFactors, ne_eq] at hp obtain ⟨hp₁, hp₂, hp₃⟩ := hp - haveI : Fact (Nat.Prime p) := ⟨hp₁⟩ + have : Fact (Nat.Prime p) := ⟨hp₁⟩ simp_rw [Finset.dvd_gcd_iff, ← modEq_zero_iff_dvd] at hp₂ have := eq_pow_multiplicity_of_choose_modEq_zero_nat h.pos hp₂ have dvd_pow : n.minFac ∣ p ^ multiplicity p n := this ▸ minFac_dvd _ @@ -218,7 +218,7 @@ theorem gcd_choose_eq_one_of_not_isPrimePow (hn : 1 < n) (hpn : ¬ IsPrimePow n) contrapose! hpn obtain ⟨q, hq, h⟩ := Nat.exists_prime_and_dvd hpn simp_rw [Finset.dvd_gcd_iff, ← modEq_zero_iff_dvd] at h - haveI : Fact (Nat.Prime q) := ⟨hq⟩ + have : Fact (Nat.Prime q) := ⟨hq⟩ have := eq_pow_multiplicity_of_choose_modEq_zero_nat (zero_lt_of_lt hn) h refine (isPrimePow_nat_iff n).mpr ⟨q, _, hq, Dvd.multiplicity_pos ?_, this.symm⟩ specialize h 1 (by grind) diff --git a/Mathlib/Data/Nat/Choose/Multinomial.lean b/Mathlib/Data/Nat/Choose/Multinomial.lean index a9ed09a52cd00c..964228f88bc058 100644 --- a/Mathlib/Data/Nat/Choose/Multinomial.lean +++ b/Mathlib/Data/Nat/Choose/Multinomial.lean @@ -326,7 +326,7 @@ theorem sum_pow_of_commute (x : α → R) (s : Finset α) convert! @Nat.cast_one R _ simp · rw [_root_.pow_succ, mul_zero] - haveI : IsEmpty (Finset.sym (∅ : Finset α) n.succ) := Finset.instIsEmpty + have : IsEmpty (Finset.sym (∅ : Finset α) n.succ) := Finset.instIsEmpty apply (Fintype.sum_empty _).symm | insert a s ha ih => ?_ intro n; specialize ih (hc.mono <| s.subset_insert a) diff --git a/Mathlib/Data/Nat/Nth.lean b/Mathlib/Data/Nat/Nth.lean index 11e306887a5938..6b7f6d039fd65b 100644 --- a/Mathlib/Data/Nat/Nth.lean +++ b/Mathlib/Data/Nat/Nth.lean @@ -157,7 +157,7 @@ theorem nth_le_nth (hf : (setOf p).Infinite) {k n} : nth p k ≤ nth p n ↔ k theorem range_nth_of_infinite (hf : (setOf p).Infinite) : Set.range (nth p) = setOf p := by rw [nth_eq_orderIsoOfNat hf] - haveI := hf.to_subtype + have := hf.to_subtype classical exact Nat.Subtype.coe_comp_ofNat_range theorem nth_mem_of_infinite (hf : (setOf p).Infinite) (n : ℕ) : p (nth p n) := diff --git a/Mathlib/Data/Nat/Totient.lean b/Mathlib/Data/Nat/Totient.lean index c31f22ad920296..5c3cada18691a7 100644 --- a/Mathlib/Data/Nat/Totient.lean +++ b/Mathlib/Data/Nat/Totient.lean @@ -121,8 +121,8 @@ theorem _root_.ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n) rfl theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by - haveI : Fact (1 < n) := ⟨one_lt_two.trans hn⟩ - haveI : NeZero n := NeZero.of_gt hn + have : Fact (1 < n) := ⟨one_lt_two.trans hn⟩ + have : NeZero n := NeZero.of_gt hn suffices 2 = orderOf (-1 : (ZMod n)ˣ) by rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this] exact orderOf_dvd_card @@ -133,9 +133,9 @@ theorem totient_mul {m n : ℕ} (h : m.Coprime n) : φ (m * n) = φ m * φ n := rcases Nat.mul_eq_zero.1 hmn0 with h | h <;> simp only [totient_zero, mul_zero, zero_mul, h] else by - haveI : NeZero (m * n) := ⟨hmn0⟩ - haveI : NeZero m := ⟨left_ne_zero_of_mul hmn0⟩ - haveI : NeZero n := ⟨right_ne_zero_of_mul hmn0⟩ + have : NeZero (m * n) := ⟨hmn0⟩ + have : NeZero m := ⟨left_ne_zero_of_mul hmn0⟩ + have : NeZero n := ⟨right_ne_zero_of_mul hmn0⟩ simp only [← ZMod.card_units_eq_totient] rw [Fintype.card_congr (Units.mapEquiv (ZMod.chineseRemainder h).toMulEquiv).toEquiv, Fintype.card_congr (@MulEquiv.prodUnits (ZMod m) (ZMod n) _ _).toEquiv, Fintype.card_prod] @@ -231,7 +231,7 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] : Fintype.card (ZMod p)ˣ ≤ p - 1 := by - haveI : NeZero p := ⟨(pos_of_gt hp).ne'⟩ + have : NeZero p := ⟨(pos_of_gt hp).ne'⟩ rw [ZMod.card_units_eq_totient p] exact Nat.le_sub_one_of_lt (Nat.totient_lt p hp) diff --git a/Mathlib/Data/PFunctor/Univariate/M.lean b/Mathlib/Data/PFunctor/Univariate/M.lean index ed201bd32b8416..5eff067e410d48 100644 --- a/Mathlib/Data/PFunctor/Univariate/M.lean +++ b/Mathlib/Data/PFunctor/Univariate/M.lean @@ -570,7 +570,7 @@ theorem bisim (R : M P → M P → Prop) (h : ∀ x y, R x y → ∃ a f f', M.dest x = ⟨a, f⟩ ∧ M.dest y = ⟨a, f'⟩ ∧ ∀ i, R (f i) (f' i)) : ∀ x y, R x y → x = y := by introv h' - haveI := Inhabited.mk x.head + have := Inhabited.mk x.head apply eq_of_bisim R _ _ _ h'; clear h' x y constructor <;> introv ih <;> rcases h _ _ ih with ⟨a'', g, g', h₀, h₁, h₂⟩ <;> clear h · replace h₀ := congr_arg Sigma.fst h₀ diff --git a/Mathlib/Data/Prod/Basic.lean b/Mathlib/Data/Prod/Basic.lean index afaeaafe82632a..e3141291db236b 100644 --- a/Mathlib/Data/Prod/Basic.lean +++ b/Mathlib/Data/Prod/Basic.lean @@ -277,8 +277,8 @@ theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → @[simp] theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} : Bijective (map f g) ↔ Bijective f ∧ Bijective g := by - haveI := Nonempty.map f ‹_› - haveI := Nonempty.map g ‹_› + have := Nonempty.map f ‹_› + have := Nonempty.map g ‹_› exact (map_injective.and map_surjective).trans and_and_and_comm @[simp] diff --git a/Mathlib/Data/Seq/Computation.lean b/Mathlib/Data/Seq/Computation.lean index 07b1fbbd784efd..829450471c9fda 100644 --- a/Mathlib/Data/Seq/Computation.lean +++ b/Mathlib/Data/Seq/Computation.lean @@ -446,7 +446,7 @@ theorem Results.val_unique {s : Computation α} {a b m n} (h1 : Results s a m) ( mem_unique h1.mem h2.mem theorem Results.len_unique {s : Computation α} {a b m n} (h1 : Results s a m) (h2 : Results s b n) : - m = n := by haveI := h1.terminates; haveI := h2.terminates; rw [← h1.length, h2.length] + m = n := by have := h1.terminates; have := h2.terminates; rw [← h1.length, h2.length] theorem exists_results_of_mem {s : Computation α} {a} (h : a ∈ s) : ∃ n, Results s a n := haveI := terminates_of_mem h @@ -482,7 +482,7 @@ theorem results_think {s : Computation α} {a n} (h : Results s a n) : Results ( theorem of_results_think {s : Computation α} {a n} (h : Results (think s) a n) : ∃ m, Results s a m ∧ n = m + 1 := by - haveI := of_think_terminates h.terminates + have := of_think_terminates h.terminates have := results_of_terminates' _ (of_think_mem h.mem) exact ⟨_, this, Results.len_unique h (results_think this)⟩ diff --git a/Mathlib/Data/Seq/Parallel.lean b/Mathlib/Data/Seq/Parallel.lean index e484882e53299b..3a7e7bcb34e7ea 100644 --- a/Mathlib/Data/Seq/Parallel.lean +++ b/Mathlib/Data/Seq/Parallel.lean @@ -325,8 +325,8 @@ theorem parallel_promises {S : WSeq (Computation α)} {a} (H : ∀ s ∈ S, s ~> theorem mem_parallel {S : WSeq (Computation α)} {a} (H : ∀ s ∈ S, s ~> a) {c} (cs : c ∈ S) (ac : a ∈ c) : a ∈ parallel S := by - haveI := terminates_of_mem ac - haveI := terminates_parallel cs + have := terminates_of_mem ac + have := terminates_parallel cs exact mem_of_promises _ (parallel_promises H) theorem parallel_congr_lem {S T : WSeq (Computation α)} {a} (H : S.LiftRel Equiv T) : diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index b3bbdde0aaf5aa..d3fbeb48451339 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -983,8 +983,8 @@ theorem inj_on_of_surj_on_of_ncard_le {t : Set β} (f : ∀ a ∈ s, β) (hf : obtain ⟨a, ha, rfl⟩ := hsurj y hy simp only [Subtype.exists] exact ⟨_, ha, rfl⟩ - haveI := hs.fintype - haveI := Fintype.ofSurjective _ hsurj + have := hs.fintype + have := Fintype.ofSurjective _ hsurj set f'' : ∀ a, a ∈ s.toFinset → β := fun a h ↦ f a (by simpa using h) exact @Finset.inj_on_of_surj_on_of_card_le _ _ _ t.toFinset f'' diff --git a/Mathlib/Data/Set/Countable.lean b/Mathlib/Data/Set/Countable.lean index 6aaf912cdda781..15939332431531 100644 --- a/Mathlib/Data/Set/Countable.lean +++ b/Mathlib/Data/Set/Countable.lean @@ -195,7 +195,7 @@ theorem exists_seq_iSup_eq_top_iff_countable [CompleteLattice α] {p : α → Pr · rintro ⟨S, hSc, hps, hS⟩ rcases eq_empty_or_nonempty S with (rfl | hne) · rw [sSup_empty] at hS - haveI := subsingleton_of_bot_eq_top hS + have := subsingleton_of_bot_eq_top hS rcases h with ⟨x, hx⟩ exact ⟨fun _ => x, fun _ => hx, Subsingleton.elim _ _⟩ · rcases (Set.countable_iff_exists_surjective hne).1 hSc with ⟨s, hs⟩ diff --git a/Mathlib/Data/Set/Finite/Basic.lean b/Mathlib/Data/Set/Finite/Basic.lean index 5c1a0dd85ed32e..164da8b8cc5640 100644 --- a/Mathlib/Data/Set/Finite/Basic.lean +++ b/Mathlib/Data/Set/Finite/Basic.lean @@ -751,7 +751,7 @@ so `u n` is related to the image of `{0, 1, ..., n-1}` under `u`. -/ theorem seq_of_forall_finite_exists {γ : Type*} {P : γ → Set γ → Prop} (h : ∀ t : Set γ, t.Finite → ∃ c, P c t) : ∃ u : ℕ → γ, ∀ n, P (u n) (u '' Iio n) := by - haveI : Nonempty γ := (h ∅ finite_empty).nonempty + have : Nonempty γ := (h ∅ finite_empty).nonempty choose! c hc using h set f : (n : ℕ) → (g : (m : ℕ) → m < n → γ) → γ := fun n g => c (range fun k : Iio n => g k.1 k.2) set u : ℕ → γ := fun n ↦ Nat.strongRecOn n f @@ -816,7 +816,7 @@ theorem Finite.card_toFinset {s : Set α} [Fintype s] (h : s.Finite) : theorem card_ne_eq [Fintype α] (a : α) [Fintype { x : α | x ≠ a }] : Fintype.card { x : α | x ≠ a } = Fintype.card α - 1 := by - haveI := Classical.decEq α + have := Classical.decEq α rw [← toFinset_card, toFinset_setOf, Finset.filter_ne', Finset.card_erase_of_mem (Finset.mem_univ _), Finset.card_univ] diff --git a/Mathlib/Data/Set/Finite/Lattice.lean b/Mathlib/Data/Set/Finite/Lattice.lean index 5722f01641983a..1092899d5557cd 100644 --- a/Mathlib/Data/Set/Finite/Lattice.lean +++ b/Mathlib/Data/Set/Finite/Lattice.lean @@ -102,7 +102,7 @@ instance finite_sUnion {s : Set (Set α)} [Finite s] [H : ∀ t : s, Finite (t : theorem finite_biUnion {ι : Type*} (s : Set ι) [Finite s] (t : ι → Set α) (H : ∀ i ∈ s, Finite (t i)) : Finite (⋃ x ∈ s, t x) := by rw [biUnion_eq_iUnion] - haveI : ∀ i : s, Finite (t i) := fun i => H i i.property + have : ∀ i : s, Finite (t i) := fun i => H i i.property infer_instance instance finite_biUnion' {ι : Type*} (s : Set ι) [Finite s] (t : ι → Set α) [∀ i, Finite (t i)] : @@ -361,7 +361,7 @@ theorem iUnion_pi_of_monotone {ι ι' : Type*} [LinearOrder ι'] [Nonempty ι'] {I : Set ι} {s : ∀ i, ι' → Set (α i)} (hI : I.Finite) (hs : ∀ i ∈ I, Monotone (s i)) : ⋃ j : ι', I.pi (fun i => s i j) = I.pi fun i => ⋃ j, s i j := by simp only [pi_def, biInter_eq_iInter, preimage_iUnion] - haveI := hI.fintype.finite + have := hI.fintype.finite refine iUnion_iInter_of_monotone (ι' := ι') (fun (i : I) j₁ j₂ h => ?_) exact preimage_mono <| hs i i.2 h @@ -395,12 +395,12 @@ theorem Finite.biInf_iSup_eq {ι : Type v} {κ : ι → Sort w} [Nonempty (Π a, classical suffices h : ∀ {κ : ι → Type w} [Nonempty (Π a, κ a)] (f : Π a, κ a → α), ⨅ a ∈ s, ⨆ b, f a b = ⨆ g : (Π a, κ a), ⨅ a ∈ s, f a (g a) by - haveI : Nonempty (Π a, PLift (κ a)) := (Equiv.piCongrRight fun _ => Equiv.plift).nonempty + have : Nonempty (Π a, PLift (κ a)) := (Equiv.piCongrRight fun _ => Equiv.plift).nonempty simpa [← Equiv.plift.symm.iSup_comp, ← (Equiv.piCongrRight fun _ => Equiv.plift).symm.iSup_comp] using h (κ := fun a => PLift (κ a)) fun a b => f a b.down intro κ _ f - haveI := hs.to_subtype - haveI : Nonempty (Π a : { a // a ∉ s }, κ ↑a) := ‹Nonempty (Π a, κ a)›.map fun f a ↦ f a + have := hs.to_subtype + have : Nonempty (Π a : { a // a ∉ s }, κ ↑a) := ‹Nonempty (Π a, κ a)›.map fun f a ↦ f a simp [← iInf_subtype'', iInf_iSup_eq_of_finite (ι := s), ← Equiv.piEquivPiSubtypeProd (· ∈ s) _ |>.symm.iSup_comp, iSup_prod, iSup_const] @@ -471,7 +471,7 @@ theorem DirectedOn.exists_mem_subset_of_finset_subset_biUnion {α ι : Type*} {f {c : Set ι} (hn : c.Nonempty) (hc : DirectedOn (fun i j => f i ⊆ f j) c) {s : Finset α} (hs : (s : Set α) ⊆ ⋃ i ∈ c, f i) : ∃ i ∈ c, (s : Set α) ⊆ f i := by rw [Set.biUnion_eq_iUnion] at hs - haveI := hn.coe_sort + have := hn.coe_sort simpa using (directed_comp.2 hc.directed_val).exists_mem_subset_of_finset_subset_biUnion hs theorem DirectedOn.exists_mem_subset_of_finite_of_subset_sUnion {α : Type*} {c : Set (Set α)} diff --git a/Mathlib/Data/Set/Finite/Range.lean b/Mathlib/Data/Set/Finite/Range.lean index 20c10cfdb777a2..fe0b2c694b6e6e 100644 --- a/Mathlib/Data/Set/Finite/Range.lean +++ b/Mathlib/Data/Set/Finite/Range.lean @@ -63,7 +63,7 @@ namespace Finite.Set instance finite_range (f : ι → α) [Finite ι] : Finite (range f) := by classical - haveI := Fintype.ofFinite (PLift ι) + have := Fintype.ofFinite (PLift ι) infer_instance instance finite_replacement [Finite α] (f : α → β) : diff --git a/Mathlib/Data/Set/Function.lean b/Mathlib/Data/Set/Function.lean index 409e09c29778d0..e7386cd4f81f6a 100644 --- a/Mathlib/Data/Set/Function.lean +++ b/Mathlib/Data/Set/Function.lean @@ -1048,7 +1048,7 @@ theorem surjOn_iff_exists_bijOn_subset : SurjOn f s t ↔ ∃ s' ⊆ s, BijOn f · rcases eq_empty_or_nonempty t with (rfl | ht) · exact fun _ => ⟨∅, empty_subset _, bijOn_empty f⟩ · intro h - haveI : Nonempty α := ⟨Classical.choose (h.comap_nonempty ht)⟩ + have : Nonempty α := ⟨Classical.choose (h.comap_nonempty ht)⟩ exact ⟨_, h.mapsTo_invFunOn.image_subset, h.bijOn_subset⟩ · rintro ⟨s', hs', hfs'⟩ exact hfs'.surjOn.mono hs' (Subset.refl _) diff --git a/Mathlib/Data/Set/Lattice.lean b/Mathlib/Data/Set/Lattice.lean index f83b4087cb7c9f..ed47b589df1942 100644 --- a/Mathlib/Data/Set/Lattice.lean +++ b/Mathlib/Data/Set/Lattice.lean @@ -737,7 +737,7 @@ theorem biInter_pair (a b : α) (s : α → Set β) : ⋂ x ∈ ({a, b} : Set α theorem biInter_inter {ι α : Type*} {s : Set ι} (hs : s.Nonempty) (f : ι → Set α) (t : Set α) : ⋂ i ∈ s, f i ∩ t = (⋂ i ∈ s, f i) ∩ t := by - haveI : Nonempty s := hs.to_subtype + have : Nonempty s := hs.to_subtype simp [biInter_eq_iInter, ← iInter_inter] theorem inter_biInter {ι α : Type*} {s : Set ι} (hs : s.Nonempty) (f : ι → Set α) (t : Set α) : diff --git a/Mathlib/Data/Set/Lattice/Image.lean b/Mathlib/Data/Set/Lattice/Image.lean index ed904b54db22b2..a95c83b908a008 100644 --- a/Mathlib/Data/Set/Lattice/Image.lean +++ b/Mathlib/Data/Set/Lattice/Image.lean @@ -231,7 +231,7 @@ theorem InjOn.image_biInter_eq {p : ι → Prop} {s : ∀ i, p i → Set α} (hp {f : α → β} (h : InjOn f (⋃ (i) (hi), s i hi)) : (f '' ⋂ (i) (hi), s i hi) = ⋂ (i) (hi), f '' s i hi := by simp only [iInter, iInf_subtype'] - haveI : Nonempty { i // p i } := nonempty_subtype.2 hp + have : Nonempty { i // p i } := nonempty_subtype.2 hp apply InjOn.image_iInter_eq simpa only [iUnion, iSup_subtype'] using h diff --git a/Mathlib/Data/Sym/NatCard.lean b/Mathlib/Data/Sym/NatCard.lean index d4422769418e61..58c579fe634c26 100644 --- a/Mathlib/Data/Sym/NatCard.lean +++ b/Mathlib/Data/Sym/NatCard.lean @@ -32,7 +32,7 @@ instance {k : ℕ} [Infinite α] [NeZero k] : Infinite (Sym α k) := theorem natCard_sym_eq_multichoose (k : ℕ) : Nat.card (Sym α k) = multichoose (Nat.card α) k := by cases finite_or_infinite α - · obtain ⟨_⟩ := nonempty_fintype α; letI := Classical.decEq α + · obtain ⟨_⟩ := nonempty_fintype α; let := Classical.decEq α simp_rw [Nat.card_eq_fintype_card] exact card_sym_eq_multichoose _ _ cases k <;> simp @@ -62,7 +62,7 @@ theorem natCard_subtype_diag : Nat.card { a : Sym2 α // a.IsDiag } = Nat.card theorem natCard_subtype_not_diag : Nat.card { a : Sym2 α // ¬a.IsDiag } = (Nat.card α).choose 2 := by cases finite_or_infinite α - · obtain ⟨_⟩ := nonempty_fintype α; letI := Classical.decEq α + · obtain ⟨_⟩ := nonempty_fintype α; let := Classical.decEq α simp_rw [Nat.card_eq_fintype_card] exact card_subtype_not_diag · simp @@ -76,7 +76,7 @@ lemma ncard_diagSet_compl : (diagSetᶜ : Set (Sym2 α)).ncard = (Nat.card α).c /-- Type **stars and bars** for the case `n = 2`. -/ protected theorem natCard : Nat.card (Sym2 α) = Nat.choose (Nat.card α + 1) 2 := by cases finite_or_infinite α - · obtain ⟨_⟩ := nonempty_fintype α; letI := Classical.decEq α + · obtain ⟨_⟩ := nonempty_fintype α; let := Classical.decEq α simp_rw [Nat.card_eq_fintype_card] exact Sym2.card · simp diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index 492558652011b0..d634b3c113afa1 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -397,7 +397,7 @@ theorem castHom_injective : Function.Injective (ZMod.castHom (dvd_refl n) R) := theorem castHom_bijective [Fintype R] (h : Fintype.card R = n) : Function.Bijective (ZMod.castHom (dvd_refl n) R) := by - haveI : NeZero n := + have : NeZero n := ⟨by intro hn rw [hn] at h @@ -778,7 +778,7 @@ theorem coe_mul_inv_eq_one {n : ℕ} (x : ℕ) (h : Nat.Coprime x n) : lemma mul_val_inv (hmn : m.Coprime n) : (m * (m⁻¹ : ZMod n).val : ZMod n) = 1 := by obtain rfl | hn := eq_or_ne n 0 · simp [m.coprime_zero_right.1 hmn] - haveI : NeZero n := ⟨hn⟩ + have : NeZero n := ⟨hn⟩ rw [ZMod.natCast_zmod_val, ZMod.coe_mul_inv_eq_one _ hmn] lemma val_inv_mul (hmn : m.Coprime n) : ((m⁻¹ : ZMod n).val * m : ZMod n) = 1 := by @@ -901,9 +901,9 @@ def chineseRemainder {m n : ℕ} (h : m.Coprime n) : ZMod (m * n) ≃+* ZMod m fin_cases x simp [to_fun, inv_fun, castHom, Prod.ext_iff, eq_iff_true_of_subsingleton] else by - haveI : NeZero (m * n) := ⟨hmn0⟩ - haveI : NeZero m := ⟨left_ne_zero_of_mul hmn0⟩ - haveI : NeZero n := ⟨right_ne_zero_of_mul hmn0⟩ + have : NeZero (m * n) := ⟨hmn0⟩ + have : NeZero m := ⟨left_ne_zero_of_mul hmn0⟩ + have : NeZero n := ⟨right_ne_zero_of_mul hmn0⟩ have left_inv : Function.LeftInverse inv_fun to_fun := by intro x dsimp only [to_fun, inv_fun, ZMod.castHom_apply] diff --git a/Mathlib/Data/ZMod/QuotientGroup.lean b/Mathlib/Data/ZMod/QuotientGroup.lean index 008f9fc2161340..9501f74a766c66 100644 --- a/Mathlib/Data/ZMod/QuotientGroup.lean +++ b/Mathlib/Data/ZMod/QuotientGroup.lean @@ -144,7 +144,7 @@ instance minimalPeriod_pos [Finite <| orbit (zpowers a) b] : NeZero <| minimalPeriod (a • ·) b := ⟨by cases nonempty_fintype (orbit (zpowers a) b) - haveI : Nonempty (orbit (zpowers a) b) := (nonempty_orbit b).to_subtype + have : Nonempty (orbit (zpowers a) b) := (nonempty_orbit b).to_subtype rw [minimalPeriod_eq_card] exact Fintype.card_ne_zero⟩ diff --git a/Mathlib/Data/ZMod/Units.lean b/Mathlib/Data/ZMod/Units.lean index 202fac6b751b8d..c93c732e5bedd1 100644 --- a/Mathlib/Data/ZMod/Units.lean +++ b/Mathlib/Data/ZMod/Units.lean @@ -119,7 +119,7 @@ theorem coe_int_mul_inv_eq_one {n : ℕ} {x : ℤ} (h : IsCoprime x n) : by_cases hn : n = 0 · simp only [hn, Nat.cast_zero, isCoprime_zero_right] at h rcases Int.isUnit_eq_one_or h with h | h <;> simp [h] - haveI : NeZero n := ⟨hn⟩ + have : NeZero n := ⟨hn⟩ rw [← natCast_zmod_val x] apply coe_mul_inv_eq_one rwa [Int.isCoprime_iff_gcd_eq_one, ← Int.gcd_emod, ← val_intCast] at h diff --git a/Mathlib/Dynamics/Ergodic/Function.lean b/Mathlib/Dynamics/Ergodic/Function.lean index 86b366bccf56d5..63d8939bc590ff 100644 --- a/Mathlib/Dynamics/Ergodic/Function.lean +++ b/Mathlib/Dynamics/Ergodic/Function.lean @@ -82,7 +82,7 @@ theorem ae_eq_const_of_ae_eq_comp_ae {g : α → X} (h : QuasiErgodic f μ) (hgm : AEStronglyMeasurable g μ) (hg_eq : g ∘ f =ᵐ[μ] g) : ∃ c, g =ᵐ[μ] const α c := by borelize X rcases hgm.isSeparable_ae_range with ⟨t, ht, hgt⟩ - haveI := ht.secondCountableTopology + have := ht.secondCountableTopology exact h.ae_eq_const_of_ae_eq_comp_of_ae_range₀ hgt hgm.aemeasurable.nullMeasurable hg_eq theorem eq_const_of_compQuasiMeasurePreserving_eq (h : QuasiErgodic f μ) {g : α →ₘ[μ] X} diff --git a/Mathlib/FieldTheory/AbelRuffini.lean b/Mathlib/FieldTheory/AbelRuffini.lean index 2b3433e54375e0..b3f2131950000a 100644 --- a/Mathlib/FieldTheory/AbelRuffini.lean +++ b/Mathlib/FieldTheory/AbelRuffini.lean @@ -67,12 +67,12 @@ theorem gal_isSolvable_tower (p q : F[X]) (hpq : (p.map (algebraMap F q.Splittin IsSolvable q.Gal := by let K := p.SplittingField let L := q.SplittingField - haveI : Fact ((p.map (algebraMap F L)).Splits) := ⟨hpq⟩ + have : Fact ((p.map (algebraMap F L)).Splits) := ⟨hpq⟩ let ϕ : Gal(L/K) ≃* (q.map (algebraMap F K)).Gal := (IsSplittingField.algEquiv L (q.map (algebraMap F K))).autCongr have ϕ_inj : Function.Injective ϕ.toMonoidHom := ϕ.injective - haveI : IsSolvable Gal(K/F) := hp - haveI : IsSolvable Gal(L/K) := solvable_of_solvable_injective ϕ_inj + have : IsSolvable Gal(K/F) := hp + have : IsSolvable Gal(L/K) := solvable_of_solvable_injective ϕ_inj exact isSolvable_of_isScalarTower F p.SplittingField q.SplittingField section GalXPowSubC diff --git a/Mathlib/FieldTheory/AxGrothendieck.lean b/Mathlib/FieldTheory/AxGrothendieck.lean index 94d369434cca0b..67e15d8a62a70f 100644 --- a/Mathlib/FieldTheory/AxGrothendieck.lean +++ b/Mathlib/FieldTheory/AxGrothendieck.lean @@ -173,7 +173,7 @@ theorem ACF_models_genericPolyMapSurjOnOfInjOn_of_prime [Finite ι] Theory.ACF p ⊨ᵇ genericPolyMapSurjOnOfInjOn φ mons := by classical have : Fact p.Prime := ⟨hp⟩ - letI := compatibleRingOfRing (AlgebraicClosure (ZMod p)) + let := compatibleRingOfRing (AlgebraicClosure (ZMod p)) rw [← (ACF_isComplete (Or.inl hp)).realize_sentence_iff _ (AlgebraicClosure (ZMod p)), realize_genericPolyMapSurjOnOfInjOn] rintro v ⟨f, _⟩ @@ -207,7 +207,7 @@ theorem ax_grothendieck_of_definable [CompatibleRing K] {c : Set K} S.MapsTo (fun v i => eval v (ps i)) S → S.InjOn (fun v i => eval v (ps i)) → S.SurjOn (fun v i => eval v (ps i)) S := by - letI := Fintype.ofFinite ι + let := Fintype.ofFinite ι let p : ℕ := ringChar K rw [Set.definable_iff_finitely_definable] at hS rcases hS with ⟨c, _, hS⟩ @@ -232,7 +232,7 @@ theorem ax_grothendieck_zeroLocus S.MapsTo (fun v i => eval v (p i)) S → S.InjOn (fun v i => eval v (p i)) → S.SurjOn (fun v i => eval v (p i)) S := by - letI := compatibleRingOfRing K + let := compatibleRingOfRing K intro S obtain ⟨s, rfl⟩ : I.FG := IsNoetherian.noetherian I exact ax_grothendieck_of_definable S (mvPolynomial_zeroLocus_definable s) p diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index 51a8083ba22a60..d21c2965a25f5b 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -326,7 +326,7 @@ variable {F E} theorem cardinal_eq_two_pow_rank [Algebra.IsSeparable F E] (rank_inf : ℵ₀ ≤ Module.rank F E) : #(Field.Emb F E) = 2 ^ Module.rank F E := by - haveI := Fact.mk rank_inf + have := Fact.mk rank_inf rw [Emb.Cardinal.embEquivPi.cardinal_eq, mk_pi] apply le_antisymm · rw [← power_eq_two_power rank_inf natCast_le_aleph0 rank_inf] diff --git a/Mathlib/FieldTheory/Cardinality.lean b/Mathlib/FieldTheory/Cardinality.lean index e7907e72b100c1..61407dfbda7bc7 100644 --- a/Mathlib/FieldTheory/Cardinality.lean +++ b/Mathlib/FieldTheory/Cardinality.lean @@ -46,8 +46,8 @@ theorem Fintype.isPrimePow_card_of_field {α} [Fintype α] [Field α] : IsPrimeP theorem Fintype.nonempty_field_iff {α} [Fintype α] : Nonempty (Field α) ↔ IsPrimePow ‖α‖ := by refine ⟨fun ⟨h⟩ => Fintype.isPrimePow_card_of_field, ?_⟩ rintro ⟨p, n, hp, hn, hα⟩ - haveI := Fact.mk hp.nat_prime - haveI : Fintype (GaloisField p n) := Fintype.ofFinite (GaloisField p n) + have := Fact.mk hp.nat_prime + have : Fintype (GaloisField p n) := Fintype.ofFinite (GaloisField p n) exact ⟨(Fintype.equivOfCardEq (((Fintype.card_eq_nat_card).trans (GaloisField.card p n hn.ne')).trans hα)).symm.field⟩ diff --git a/Mathlib/FieldTheory/ChevalleyWarning.lean b/Mathlib/FieldTheory/ChevalleyWarning.lean index 19623e48580c95..7f32608376b302 100644 --- a/Mathlib/FieldTheory/ChevalleyWarning.lean +++ b/Mathlib/FieldTheory/ChevalleyWarning.lean @@ -54,7 +54,7 @@ local notation "q" => Fintype.card K theorem MvPolynomial.sum_eval_eq_zero (f : MvPolynomial σ K) (h : f.totalDegree < (q - 1) * Fintype.card σ) : ∑ x, eval x f = 0 := by - haveI : DecidableEq K := Classical.decEq K + have : DecidableEq K := Classical.decEq K calc ∑ x, eval x f = ∑ x : σ → K, ∑ d ∈ f.support, f.coeff d * ∏ i, x i ^ d i := by simp only [eval_eq'] @@ -81,7 +81,7 @@ theorem MvPolynomial.sum_eval_eq_zero (f : MvPolynomial σ K) _ = 0 := by rw [sum_pow_lt_card_sub_one K _ hi, mul_zero] intro a let e' : { j // j = i } ⊕ { j // j ≠ i } ≃ σ := Equiv.sumCompl _ - letI : Unique { j // j = i } := + let : Unique { j // j = i } := { default := ⟨i, rfl⟩ uniq := fun ⟨j, h⟩ => Subtype.val_injective h } calc diff --git a/Mathlib/FieldTheory/Differential/Basic.lean b/Mathlib/FieldTheory/Differential/Basic.lean index 0c26b95d62dc6e..d3151b3e0c6f4c 100644 --- a/Mathlib/FieldTheory/Differential/Basic.lean +++ b/Mathlib/FieldTheory/Differential/Basic.lean @@ -148,9 +148,9 @@ lemma differentialAlgebraFiniteDimensional [FiniteDimensional F K] : letI := differentialFiniteDimensional F K DifferentialAlgebra F K := by let k := (Field.exists_primitive_element F K).choose - haveI h : F⟮k⟯ = ⊤ := (Field.exists_primitive_element F K).choose_spec - haveI : Fact (minpoly F k).Monic := ⟨minpoly.monic (IsAlgebraic.of_finite ..).isIntegral⟩ - haveI : Fact (Irreducible (minpoly F k)) := + have h : F⟮k⟯ = ⊤ := (Field.exists_primitive_element F K).choose_spec + have : Fact (minpoly F k).Monic := ⟨minpoly.monic (IsAlgebraic.of_finite ..).isIntegral⟩ + have : Fact (Irreducible (minpoly F k)) := ⟨minpoly.irreducible (IsAlgebraic.of_finite ..).isIntegral⟩ apply DifferentialAlgebra.equiv diff --git a/Mathlib/FieldTheory/Differential/Liouville.lean b/Mathlib/FieldTheory/Differential/Liouville.lean index cf3775cc229db0..284d70fa8567fe 100644 --- a/Mathlib/FieldTheory/Differential/Liouville.lean +++ b/Mathlib/FieldTheory/Differential/Liouville.lean @@ -124,7 +124,7 @@ private local instance isLiouville_of_finiteDimensional_galois [FiniteDimensiona [IsGalois F K] : IsLiouville F K where isLiouville (a : F) (ι : Type) [Fintype ι] (c : ι → F) (hc : ∀ x, (c x)′ = 0) (u : ι → K) (v : K) (h : a = ∑ x, c x * logDeriv (u x) + v′) := by - haveI : CharZero K := charZero_of_injective_algebraMap + have : CharZero K := charZero_of_injective_algebraMap (FaithfulSMul.algebraMap_injective F K) -- We sum `e x` over all isomorphisms `e : K ≃ₐ[F] K`. -- Because this is a Galois extension each of the relevant values will be in `F`. diff --git a/Mathlib/FieldTheory/Extension.lean b/Mathlib/FieldTheory/Extension.lean index 7406aef78c527b..498bfcae6415e8 100644 --- a/Mathlib/FieldTheory/Extension.lean +++ b/Mathlib/FieldTheory/Extension.lean @@ -238,8 +238,8 @@ private theorem exists_algHom_adjoin_of_splits'' {L : IntermediateField F E} (fun c _ hc _ _ ↦ Lifts.exists_upper_bound c hc) ⟨L, f⟩ le_rfl refine ⟨φ.emb.comp (inclusion <| (le_extendScalars_iff hfφ.1 <| adjoin L S).mp <| adjoin_le_iff.mpr fun s h ↦ ?_), AlgHom.ext hfφ.2⟩ - letI := (inclusion hfφ.1).toAlgebra - letI : SMul L φ.carrier := Algebra.toSMul + let := (inclusion hfφ.1).toAlgebra + let : SMul L φ.carrier := Algebra.toSMul have : IsScalarTower L φ.carrier E := ⟨fun x y ↦ smul_assoc x (y : E)⟩ have := φ.exists_lift_of_splits' (hK s h).1.tower_top ((hK s h).1.minpoly_splits_tower_top' ?_) · obtain ⟨y, h1, h2⟩ := this @@ -264,7 +264,7 @@ theorem exists_algHom_adjoin_of_splits' : refine Eq.trans congr($hφ y) ?_ simp only [AlgHom.coe_comp, Function.comp_apply, f'] exact congr_arg f (AlgEquiv.symm_apply_apply _ _) - letI : Algebra L L' := (AlgEquiv.ofInjectiveField _).toRingHom.toAlgebra + let : Algebra L L' := (AlgEquiv.ofInjectiveField _).toRingHom.toAlgebra have : IsScalarTower L L' E := IsScalarTower.of_algebraMap_eq' rfl refine ⟨(hK s hs).1.tower_top, (hK s hs).1.minpoly_splits_tower_top' ?_⟩ convert! (hK s hs).2 diff --git a/Mathlib/FieldTheory/Finite/Basic.lean b/Mathlib/FieldTheory/Finite/Basic.lean index edee55fb926e4b..fa6d6d9a573729 100644 --- a/Mathlib/FieldTheory/Finite/Basic.lean +++ b/Mathlib/FieldTheory/Finite/Basic.lean @@ -254,8 +254,8 @@ variable (K) [Field K] [Fintype K] /-- The cardinality `q` is a power of the characteristic of `K`. -/ @[stacks 09HY "first part"] theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n : ℕ) := by - haveI hp : Fact p.Prime := ⟨CharP.char_is_prime K p⟩ - letI : Module (ZMod p) K := { (ZMod.castHom dvd_rfl K : ZMod p →+* _).toModule with } + have hp : Fact p.Prime := ⟨CharP.char_is_prime K p⟩ + let : Module (ZMod p) K := { (ZMod.castHom dvd_rfl K : ZMod p →+* _).toModule with } obtain ⟨n, h⟩ := VectorSpace.card_fintype (ZMod p) K rw [ZMod.card] at h refine ⟨⟨n, ?_⟩, hp.1, h⟩ @@ -487,7 +487,7 @@ open Polynomial theorem expand_card (f : K[X]) : expand K q f = f ^ q := by obtain ⟨p, hp⟩ := CharP.exists K rcases FiniteField.card K p with ⟨⟨n, npos⟩, ⟨hp, hn⟩⟩ - haveI : Fact p.Prime := ⟨hp⟩ + have : Fact p.Prime := ⟨hp⟩ dsimp at hn rw [hn, ← map_iterateFrobenius_expand, iterateFrobenius_eq_pow, frobenius_pow hn, RingHom.one_def, map_id] @@ -540,7 +540,7 @@ namespace CharP theorem sq_add_sq (R : Type*) [Ring R] [IsDomain R] (p : ℕ) [NeZero p] [CharP R p] (x : ℤ) : ∃ a b : ℕ, ((a : R) ^ 2 + (b : R) ^ 2) = x := by - haveI := char_is_prime_of_pos R p + have := char_is_prime_of_pos R p obtain ⟨a, b, hab⟩ := ZMod.sq_add_sq p x refine ⟨a.val, b.val, ?_⟩ simpa using congr_arg (ZMod.castHom dvd_rfl R) hab @@ -638,7 +638,7 @@ end ZMod `a ^ (p - 1) ≡ 1 [ZMOD p]`. -/ theorem Int.ModEq.pow_card_sub_one_eq_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ} (hpn : IsCoprime n p) : n ^ (p - 1) ≡ 1 [ZMOD p] := by - haveI : Fact p.Prime := ⟨hp⟩ + have : Fact p.Prime := ⟨hp⟩ have : ¬(n : ZMod p) = 0 := by rw [CharP.intCast_eq_zero_iff _ p, ← (Nat.prime_iff_prime_int.mp hp).coprime_iff_not_dvd] · exact hpn.symm @@ -649,7 +649,7 @@ theorem Int.prime_dvd_pow_sub_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ} (hpn : (ModEq.pow_card_sub_one_eq_one hp hpn).symm.dvd theorem Int.ModEq.pow_prime_eq_self {p : ℕ} (hp : Nat.Prime p) (n : ℤ) : n ^ p ≡ n [ZMOD p] := by - haveI : Fact p.Prime := ⟨hp⟩ + have : Fact p.Prime := ⟨hp⟩ simp [← ZMod.intCast_eq_intCast_iff] theorem Int.prime_dvd_pow_self_sub {p : ℕ} (hp : Nat.Prime p) (n : ℤ) : (p : ℤ) ∣ n ^ p - n := diff --git a/Mathlib/FieldTheory/Finite/Extension.lean b/Mathlib/FieldTheory/Finite/Extension.lean index 299773369de76c..328fc12eeb24f6 100644 --- a/Mathlib/FieldTheory/Finite/Extension.lean +++ b/Mathlib/FieldTheory/Finite/Extension.lean @@ -52,7 +52,7 @@ def Extension : Type := theorem finrank_zmod_extension [Algebra (ZMod p) k] : Module.finrank (ZMod p) (Extension k p n) = Module.finrank (ZMod p) k * n := by - letI := ZMod.algebra k p + let := ZMod.algebra k p unfold Extension convert! GaloisField.finrank p (n := Module.finrank (ZMod p) k * n) <| @@ -75,7 +75,7 @@ instance [Algebra (ZMod p) k] : IsScalarTower (ZMod p) k (Extension k p n) := .of_algebraMap_eq' <| Subsingleton.elim _ _ theorem natCard_extension : Nat.card (Extension k p n) = Nat.card k ^ n := by - letI := ZMod.algebra k p + let := ZMod.algebra k p rw [← pow_finrank_eq_natCard p, ← pow_finrank_eq_natCard p, finrank_zmod_extension, pow_mul] theorem finrank_extension : Module.finrank k (Extension k p n) = n := by diff --git a/Mathlib/FieldTheory/Finite/GaloisField.lean b/Mathlib/FieldTheory/Finite/GaloisField.lean index a3cc93bce9b2e4..59fe36a193b68b 100644 --- a/Mathlib/FieldTheory/Finite/GaloisField.lean +++ b/Mathlib/FieldTheory/Finite/GaloisField.lean @@ -79,7 +79,7 @@ variable (p : ℕ) [h_prime : Fact p.Prime] (n : ℕ) set_option backward.isDefEq.respectTransparency false in theorem finrank {n} (h : n ≠ 0) : Module.finrank (ZMod p) (GaloisField p n) = n := by - haveI : Fintype (GaloisField p n) := Fintype.ofFinite (GaloisField p n) + have : Fintype (GaloisField p n) := Fintype.ofFinite (GaloisField p n) set g_poly := (X ^ p ^ n - X : (ZMod p)[X]) have hp : 1 < p := h_prime.out.one_lt have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp @@ -130,7 +130,7 @@ theorem finrank {n} (h : n ≠ 0) : Module.finrank (ZMod p) (GaloisField p n) = theorem card (h : n ≠ 0) : Nat.card (GaloisField p n) = p ^ n := by let b := IsNoetherian.finsetBasis (ZMod p) (GaloisField p n) - haveI : Fintype (GaloisField p n) := Fintype.ofFinite (GaloisField p n) + have : Fintype (GaloisField p n) := Fintype.ofFinite (GaloisField p n) rw [Nat.card_eq_fintype_card, Module.card_fintype b, ← Module.finrank_eq_card_basis b, ZMod.card, finrank p h] @@ -175,14 +175,14 @@ variable {K : Type*} [Field K] [Algebra (ZMod p) K] theorem _root_.FiniteField.splits_X_pow_nat_card_sub_X [Finite K] : Splits (map (algebraMap (ZMod p) K) (X ^ Nat.card K - X)) := by - haveI : Fintype K := Fintype.ofFinite K + have : Fintype K := Fintype.ofFinite K rw [Nat.card_eq_fintype_card] exact (FiniteField.isSplittingField_sub K (ZMod p)).splits theorem _root_.FiniteField.isSplittingField_of_nat_card_eq (h : Nat.card K = p ^ n) : IsSplittingField (ZMod p) K (X ^ p ^ n - X) := by - haveI : Finite K := (Nat.card_pos_iff.mp (h ▸ pow_pos h_prime.1.pos n)).2 - haveI : Fintype K := Fintype.ofFinite K + have : Finite K := (Nat.card_pos_iff.mp (h ▸ pow_pos h_prime.1.pos n)).2 + have : Fintype K := Fintype.ofFinite K rw [← h, Nat.card_eq_fintype_card] exact FiniteField.isSplittingField_sub K (ZMod p) @@ -198,8 +198,8 @@ instance (priority := 100) {K K' : Type*} [Field K] [Field K'] [Finite K'] [Alge IsGalois K K' := by cases nonempty_fintype K' obtain ⟨p, hp⟩ := CharP.exists K - haveI : CharP K p := hp - haveI : CharP K' p := charP_of_injective_algebraMap' K p + have : CharP K p := hp + have : CharP K' p := charP_of_injective_algebraMap' K p exact IsGalois.of_separable_splitting_field (galois_poly_separable p (Fintype.card K') (let ⟨n, _, hn⟩ := FiniteField.card K' p diff --git a/Mathlib/FieldTheory/Finite/Trace.lean b/Mathlib/FieldTheory/Finite/Trace.lean index 390d29ce143aea..d6723889a553c7 100644 --- a/Mathlib/FieldTheory/Finite/Trace.lean +++ b/Mathlib/FieldTheory/Finite/Trace.lean @@ -37,7 +37,7 @@ open Fintype theorem trace_to_zmod_nondegenerate (F : Type*) [Field F] [Finite F] [Algebra (ZMod (ringChar F)) F] {a : F} (ha : a ≠ 0) : ∃ b : F, Algebra.trace (ZMod (ringChar F)) F (a * b) ≠ 0 := by - haveI : Fact (ringChar F).Prime := ⟨CharP.char_is_prime F _⟩ + have : Fact (ringChar F).Prime := ⟨CharP.char_is_prime F _⟩ have htr := (traceForm_nondegenerate (ZMod (ringChar F)) F).1 a simp_rw [Algebra.traceForm_apply] at htr by_contra! hf diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 1f888afb4d915f..7c801194e20be2 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -522,7 +522,7 @@ theorem of_separable_splitting_field_aux [hFE : FiniteDimensional F E] [sp : p.I Σ f : K →ₐ[F] E, @AlgHom K K⟮x⟯ E _ _ _ _ (RingHom.toAlgebra f) := by change (K⟮x⟯ →ₐ[F] E) ≃ Σ f : K →ₐ[F] E, _ exact algHomEquivSigma - haveI : ∀ f : K →ₐ[F] E, Finite (@AlgHom K K⟮x⟯ E _ _ _ _ (RingHom.toAlgebra f)) := fun f => by + have : ∀ f : K →ₐ[F] E, Finite (@AlgHom K K⟮x⟯ E _ _ _ _ (RingHom.toAlgebra f)) := fun f => by have := Finite.of_equiv _ key_equiv apply Finite.of_injective (Sigma.mk f) fun _ _ H => eq_of_heq (Sigma.ext_iff.mp H).2 have : FiniteDimensional F K := FiniteDimensional.left F K E diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 718a1f72439570..507a2b42dbd982 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -418,11 +418,11 @@ theorem algebraMap_quotientMulEquiv_smul [Finite G] [Finite G'] (N : Subgroup G) [MulSemiringAction G C] [IsGaloisGroup G A C] [IsGaloisGroup N B C] [MulSemiringAction G' B] [IsGaloisGroup G' A B] (g : G) (x : B) : algebraMap B C (quotientMulEquiv G G' A B C N g • x) = g • algebraMap B C x := by - haveI : IsDomain B := (FaithfulSMul.algebraMap_injective B C).isDomain - letI := mulSemiringActionOfNormal G B C N - letI := mulSemiringActionQuotient G B C N - haveI := smulCommClassQuotient G A B C N - haveI := quotient G A B C N + have : IsDomain B := (FaithfulSMul.algebraMap_injective B C).isDomain + let := mulSemiringActionOfNormal G B C N + let := mulSemiringActionQuotient G B C N + have := smulCommClassQuotient G A B C N + have := quotient G A B C N rw [← algebraMap_smulOfNormal G B C N g x] congr apply mulEquivCongr_apply_smul diff --git a/Mathlib/FieldTheory/Galois/Profinite.lean b/Mathlib/FieldTheory/Galois/Profinite.lean index 8c3ec86b00cdbf..1fa9e055db3ca3 100644 --- a/Mathlib/FieldTheory/Galois/Profinite.lean +++ b/Mathlib/FieldTheory/Galois/Profinite.lean @@ -190,8 +190,8 @@ lemma proj_of_le (L : FiniteGaloisIntermediateField k K) (proj L g x).val = (proj L' g ⟨x, h x.2⟩).val := by induction L with | _ L => ?_ induction L' with | _ L' => ?_ - letI : Algebra L L' := RingHom.toAlgebra (Subsemiring.inclusion h) - letI : IsScalarTower k L L' := IsScalarTower.of_algebraMap_eq (congrFun rfl) + let : Algebra L L' := RingHom.toAlgebra (Subsemiring.inclusion h) + let : IsScalarTower k L L' := IsScalarTower.of_algebraMap_eq (congrFun rfl) rw [← finGaloisGroupFunctor_map_proj_eq_proj g h.hom] change (algebraMap L' K (algebraMap L L' (AlgEquiv.restrictNormal (proj (mk L') g) L x))) = _ rw [AlgEquiv.restrictNormal_commutes (proj (mk L') g) L] diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean index b6280f1e11761d..8dd79bbbdeb15e 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean @@ -399,7 +399,7 @@ noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) : (AdjoinRoot.liftAlgHom (minpoly F α) _ (AdjoinSimple.gen F α) (aeval_gen_minpoly F α)) (by set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α :) - haveI := Fact.mk (minpoly.irreducible h) + have := Fact.mk (minpoly.irreducible h) constructor · exact RingHom.injective f · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by @@ -526,7 +526,7 @@ theorem exists_lt_finrank_of_infinite_dimensional rw [show L = ⊤ from eq_top_iff.2 fun x _ ↦ hnfd x] at fin exact topEquiv.toLinearEquiv.finiteDimensional let L' := L ⊔ F⟮x⟯ - haveI := adjoin.finiteDimensional (Algebra.IsIntegral.isIntegral (R := F) x) + have := adjoin.finiteDimensional (Algebra.IsIntegral.isIntegral (R := F) x) refine ⟨L', inferInstance, by_contra fun h ↦ ?_⟩ have h1 : L = L' := eq_of_le_of_finrank_le le_sup_left ((not_lt.1 h).trans hn) have h2 : F⟮x⟯ ≤ L' := le_sup_right @@ -563,7 +563,7 @@ theorem isAlgebraic_iSup {ι : Type*} {t : ι → IntermediateField K L} rintro ⟨x, hx⟩ obtain ⟨s, hx⟩ := exists_finset_of_mem_supr' hx rw [isAlgebraic_iff, Subtype.coe_mk, ← Subtype.coe_mk (p := (· ∈ _)) x hx, ← isAlgebraic_iff] - haveI : ∀ i : Σ i, t i, FiniteDimensional K K⟮(i.2 : L)⟯ := fun ⟨i, x⟩ ↦ + have : ∀ i : Σ i, t i, FiniteDimensional K K⟮(i.2 : L)⟯ := fun ⟨i, x⟩ ↦ adjoin.finiteDimensional (isIntegral_iff.1 (Algebra.IsIntegral.isIntegral x)) apply IsAlgebraic.of_finite @@ -578,7 +578,7 @@ A direct corollary of `finiteDimensional_iSup_of_finite`. -/ theorem finiteDimensional_adjoin {S : Set L} [Finite S] (hS : ∀ x ∈ S, IsIntegral K x) : FiniteDimensional K (adjoin K S) := by rw [← biSup_adjoin_simple, ← iSup_subtype''] - haveI (x : S) := adjoin.finiteDimensional (hS x.1 x.2) + have (x : S) := adjoin.finiteDimensional (hS x.1 x.2) exact finiteDimensional_iSup_of_finite end PowerBasis @@ -637,7 +637,7 @@ theorem _root_.Polynomial.irreducible_comp {f g : K[X]} (hfm : f.Monic) (hgm : g (this.trans natDegree_comp.symm).ge).irreducible hp₁ have := Fact.mk hp₁ let Kx := AdjoinRoot p - letI := (AdjoinRoot.powerBasis hp₁.ne_zero).finite + let := (AdjoinRoot.powerBasis hp₁.ne_zero).finite have key₁ : f = minpoly K (aeval (root p) g) := by refine minpoly.eq_of_irreducible_of_monic hf ?_ hfm rw [← aeval_comp] diff --git a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean index 0898d2e4d45ed6..89785371530833 100644 --- a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean @@ -115,7 +115,7 @@ theorem eq_iff_finrank_eq_of_le' [FiniteDimensional F L] (h_le : F ≤ E) : lemma finrank_lt_of_gt [FiniteDimensional F L] (H : F < E) : Module.finrank E L < Module.finrank F L := by - letI := (IntermediateField.inclusion H.le).toAlgebra + let := (IntermediateField.inclusion H.le).toAlgebra have : IsScalarTower F E L := .of_algebraMap_eq' rfl refine lt_of_le_of_ne ?_ ?_ · exact Module.finrank_top_le_finrank_of_isScalarTower _ _ _ diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index 3e4e49af1025a5..32c932c6c3b446 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -286,7 +286,7 @@ def Subalgebra.toIntermediateField' (S : Subalgebra K L) (hS : IsField S) : Inte by_cases hx0 : x = 0 · rw [hx0, inv_zero] exact S.zero_mem - letI hS' := hS.toField + let hS' := hS.toField obtain ⟨y, hy⟩ := hS.mul_inv_cancel (show (⟨x, hx⟩ : S) ≠ 0 from Subtype.coe_ne_coe.1 hx0) rw [Subtype.ext_iff, S.coe_mul, S.coe_one, Subtype.coe_mk, mul_eq_one_iff_inv_eq₀ hx0] at hy exact hy.symm ▸ y.2 diff --git a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean index 93456508dc1f3a..d506815e10ab59 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean @@ -346,8 +346,8 @@ private instance FractionRing.isAlgebraic : letI : IsDomain R := (FaithfulSMul.algebraMap_injective R S).isDomain _ letI : Algebra (FractionRing R) (FractionRing S) := FractionRing.liftAlgebra R _ Algebra.IsAlgebraic (FractionRing R) (FractionRing S) := by - letI : IsDomain R := (FaithfulSMul.algebraMap_injective R S).isDomain _ - letI : Algebra (FractionRing R) (FractionRing S) := FractionRing.liftAlgebra R _ + let : IsDomain R := (FaithfulSMul.algebraMap_injective R S).isDomain _ + let : Algebra (FractionRing R) (FractionRing S) := FractionRing.liftAlgebra R _ have := FractionRing.isScalarTower_liftAlgebra R (FractionRing S) have := (IsFractionRing.isAlgebraic_iff' R S (FractionRing S)).1 inferInstance exact ⟨fun _ ↦ (IsFractionRing.isAlgebraic_iff R (FractionRing R) (FractionRing S)).1 diff --git a/Mathlib/FieldTheory/IsAlgClosed/Classification.lean b/Mathlib/FieldTheory/IsAlgClosed/Classification.lean index f68f24028abb3f..755fe0c8892a40 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Classification.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Classification.lean @@ -95,7 +95,7 @@ theorem cardinal_le_max_transcendence_basis (hv : IsTranscendenceBasis R v) : calc Cardinal.lift.{max u w} #K ≤ Cardinal.lift.{max u w} (max #(Algebra.adjoin R (Set.range v)) ℵ₀) := by - letI := isAlgClosure_of_transcendence_basis v hv + let := isAlgClosure_of_transcendence_basis v hv simpa using Algebra.IsAlgebraic.cardinalMk_le_max (Algebra.adjoin R (Set.range v)) K _ = Cardinal.lift.{v} (max #(MvPolynomial ι R) ℵ₀) := by rw [lift_max, ← Cardinal.lift_mk_eq.2 ⟨hv.1.aevalEquiv.toEquiv⟩, lift_aleph0, @@ -173,8 +173,8 @@ theorem ringEquiv_of_equiv_of_charZero [CharZero K] [CharZero L] (hK : ℵ₀ < private theorem ringEquiv_of_Cardinal_eq_of_charP (p : ℕ) [Fact p.Prime] [CharP K p] [CharP L p] (hK : ℵ₀ < #K) (hKL : Nonempty (K ≃ L)) : Nonempty (K ≃+* L) := by - letI : Algebra (ZMod p) K := ZMod.algebra _ _ - letI : Algebra (ZMod p) L := ZMod.algebra _ _ + let : Algebra (ZMod p) K := ZMod.algebra _ _ + let : Algebra (ZMod p) L := ZMod.algebra _ _ obtain ⟨s, hs⟩ := exists_isTranscendenceBasis (ZMod p) K obtain ⟨t, ht⟩ := exists_isTranscendenceBasis (ZMod p) L have hL : ℵ₀ < #L := by @@ -193,11 +193,11 @@ if they have the same cardinality and the same characteristic. -/ theorem ringEquiv_of_equiv_of_char_eq (p : ℕ) [CharP K p] [CharP L p] (hK : ℵ₀ < #K) (hKL : Nonempty (K ≃ L)) : Nonempty (K ≃+* L) := by rcases CharP.char_is_prime_or_zero K p with (hp | hp) - · haveI : Fact p.Prime := ⟨hp⟩ + · have : Fact p.Prime := ⟨hp⟩ exact ringEquiv_of_Cardinal_eq_of_charP p hK hKL · simp only [hp] at * - letI : CharZero K := CharP.charP_to_charZero K - letI : CharZero L := CharP.charP_to_charZero L + let : CharZero K := CharP.charP_to_charZero K + let : CharZero L := CharP.charP_to_charZero L exact ringEquiv_of_equiv_of_charZero hK hKL end IsAlgClosed diff --git a/Mathlib/FieldTheory/KrullTopology.lean b/Mathlib/FieldTheory/KrullTopology.lean index 2388afc6796f00..e92eb2b63fae20 100644 --- a/Mathlib/FieldTheory/KrullTopology.lean +++ b/Mathlib/FieldTheory/KrullTopology.lean @@ -231,7 +231,7 @@ instance {K L : Type*} [Field K] [Field L] [Algebra K L] [Algebra.IsIntegral K L have hστ : σ⁻¹ * τ ≠ 1 := by rwa [Ne, inv_mul_eq_one] rcases DFunLike.exists_ne hστ with ⟨x, hx : (σ⁻¹ * τ) x ≠ x⟩ let E := IntermediateField.adjoin K ({x} : Set L) - haveI := IntermediateField.adjoin.finiteDimensional + have := IntermediateField.adjoin.finiteDimensional (Algebra.IsIntegral.isIntegral (R := K) x) refine ⟨σ • E.fixingSubgroup, ⟨E.fixingSubgroup_isClosed.leftCoset σ, E.fixingSubgroup_isOpen.leftCoset σ⟩, diff --git a/Mathlib/FieldTheory/KummerExtension.lean b/Mathlib/FieldTheory/KummerExtension.lean index d20b29ba748424..72af873d95f851 100644 --- a/Mathlib/FieldTheory/KummerExtension.lean +++ b/Mathlib/FieldTheory/KummerExtension.lean @@ -179,8 +179,8 @@ section AdjoinRoot include hζ H in /-- Also see `Polynomial.separable_X_pow_sub_C_unit` -/ theorem Polynomial.separable_X_pow_sub_C_of_irreducible : (X ^ n - C a).Separable := by - letI := Fact.mk H - letI : Algebra K K[n√a] := inferInstance + let := Fact.mk H + let : Algebra K K[n√a] := inferInstance have hn := Nat.pos_iff_ne_zero.mpr (ne_zero_of_irreducible_X_pow_sub_C H) by_cases hn' : n = 1 · rw [hn', pow_one]; exact separable_X_sub_C @@ -253,7 +253,7 @@ def autAdjoinRootXPowSubCEquiv [NeZero n] : intro η have := Fact.mk H have : IsDomain K[n√a] := inferInstance - letI : Algebra K K[n√a] := inferInstance + let : Algebra K K[n√a] := inferInstance apply (rootsOfUnityEquivOfPrimitiveRoots (algebraMap K K[n√a]).injective hζ).injective ext simp only [AdjoinRoot.algebraMap_eq, OneHom.toFun_eq_coe, MonoidHom.toOneHom_coe, @@ -268,7 +268,7 @@ def autAdjoinRootXPowSubCEquiv [NeZero n] : right_inv := by intro e have := Fact.mk H - letI : Algebra K K[n√a] := inferInstance + let : Algebra K K[n√a] := inferInstance apply AlgEquiv.coe_toAlgHom_injective apply AdjoinRoot.algHom_ext simp only [AdjoinRootXPowSubCEquivToRootsOfUnity, AdjoinRoot.algebraMap_eq, OneHom.toFun_eq_coe, @@ -311,7 +311,7 @@ lemma isSplittingField_AdjoinRoot_X_pow_sub_C : letI : Algebra K K[n√a] := inferInstance IsSplittingField K K[n√a] (X ^ n - C a) := by have := Fact.mk H - letI : Algebra K K[n√a] := inferInstance + let : Algebra K K[n√a] := inferInstance constructor · rw [Polynomial.map_sub, Polynomial.map_pow, Polynomial.map_C, Polynomial.map_X] @@ -333,8 +333,8 @@ noncomputable def adjoinRootXPowSubCEquiv (hζ : (primitiveRoots n K).Nonempty) (H : Irreducible (X ^ n - C a)) (hα : α ^ n = algebraMap K L a) : K[n√a] ≃ₐ[K] L := .ofBijective (AdjoinRoot.liftAlgHom (X ^ n - C a) (Algebra.ofId _ _) α (by simp [hα])) <| by - haveI := Fact.mk H - letI := isSplittingField_AdjoinRoot_X_pow_sub_C hζ H + have := Fact.mk H + let := isSplittingField_AdjoinRoot_X_pow_sub_C hζ H refine ⟨(liftAlgHom (X ^ n - C a) _ α _).injective, ?_⟩ rw [← AlgHom.range_eq_top, ← IsSplittingField.adjoin_rootSet _ (X ^ n - C a), eq_comm, Splits.adjoin_rootSet_eq_range, IsSplittingField.adjoin_rootSet] diff --git a/Mathlib/FieldTheory/LinearDisjoint.lean b/Mathlib/FieldTheory/LinearDisjoint.lean index 5894be8689642f..5405cd8891701d 100644 --- a/Mathlib/FieldTheory/LinearDisjoint.lean +++ b/Mathlib/FieldTheory/LinearDisjoint.lean @@ -630,10 +630,10 @@ theorem isDomain' {A B : Type*} [Field A] [Algebra F A] [Field B] [Algebra F B] theorem of_isField (H : IsField (A ⊗[F] L)) : A.LinearDisjoint L := by apply Subalgebra.LinearDisjoint.of_isField -- need these otherwise the `exact` will stuck at typeclass - haveI : SMulCommClass F A A := SMulCommClass.of_commMonoid F A A - haveI : SMulCommClass F A.toSubalgebra A.toSubalgebra := ‹SMulCommClass F A A› - letI : Mul (A ⊗[F] L) := Algebra.TensorProduct.instMul - letI : Mul (A.toSubalgebra ⊗[F] (IsScalarTower.toAlgHom F L E).range) := + have : SMulCommClass F A A := SMulCommClass.of_commMonoid F A A + have : SMulCommClass F A.toSubalgebra A.toSubalgebra := ‹SMulCommClass F A A› + let : Mul (A ⊗[F] L) := Algebra.TensorProduct.instMul + let : Mul (A.toSubalgebra ⊗[F] (IsScalarTower.toAlgHom F L E).range) := Algebra.TensorProduct.instMul exact Algebra.TensorProduct.congr (AlgEquiv.refl : A ≃ₐ[F] A) (AlgEquiv.ofInjective (IsScalarTower.toAlgHom F L E) (RingHom.injective _)) @@ -674,7 +674,7 @@ theorem isField_of_forall (A : Type v) [Field A] (B : Type w) [Field B] obtain ⟨M, hM⟩ := Ideal.exists_maximal (A ⊗[F] B) apply not_imp_not.1 (Ring.ne_bot_of_isMaximal_of_not_isField hM) let K : Type (max v w) := A ⊗[F] B ⧸ M - letI : Field K := Ideal.Quotient.field _ + let : Field K := Ideal.Quotient.field _ let i := IsScalarTower.toAlgHom F (A ⊗[F] B) K let fa := i.comp (Algebra.TensorProduct.includeLeft : A →ₐ[F] _) let fb := i.comp (Algebra.TensorProduct.includeRight : B →ₐ[F] _) diff --git a/Mathlib/FieldTheory/Minpoly/Basic.lean b/Mathlib/FieldTheory/Minpoly/Basic.lean index 60a802900b6e8f..ca19e0abb3af52 100644 --- a/Mathlib/FieldTheory/Minpoly/Basic.lean +++ b/Mathlib/FieldTheory/Minpoly/Basic.lean @@ -112,7 +112,7 @@ theorem map_ne_one [Nontrivial B] {R : Type*} [Semiring R] [Nontrivial R] (f : A /-- A minimal polynomial is not a unit. -/ theorem not_isUnit [Nontrivial B] : ¬IsUnit (minpoly A x) := by - haveI : Nontrivial A := (algebraMap A B).domain_nontrivial + have : Nontrivial A := (algebraMap A B).domain_nontrivial by_cases hx : IsIntegral A x · exact mt (monic hx).eq_one_of_isUnit (ne_one A x) · rw [eq_zero hx] @@ -213,7 +213,7 @@ open Polynomial in theorem degree_eq_one_iff : (minpoly A x).degree = 1 ↔ x ∈ (algebraMap A B).range := by refine ⟨minpoly.mem_range_of_degree_eq_one _ _, ?_⟩ rintro ⟨x, rfl⟩ - haveI := Module.nontrivial A B + have := Module.nontrivial A B exact (degree_X_sub_C x ▸ minpoly.min A (algebraMap A B x) (monic_X_sub_C x) (by simp)).antisymm (Nat.WithBot.add_one_le_of_lt <| minpoly.degree_pos isIntegral_algebraMap) diff --git a/Mathlib/FieldTheory/Normal/Basic.lean b/Mathlib/FieldTheory/Normal/Basic.lean index 96b5e118c94bab..bdd25a16e7bbf0 100644 --- a/Mathlib/FieldTheory/Normal/Basic.lean +++ b/Mathlib/FieldTheory/Normal/Basic.lean @@ -67,7 +67,7 @@ theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] : exact Normal.of_algEquiv (AlgEquiv.ofBijective (Algebra.ofId F E) (Algebra.bijective_algebraMap_iff.2 this.symm)) refine normal_iff.mpr fun x ↦ ?_ - haveI : FiniteDimensional F E := IsSplittingField.finiteDimensional E p + have : FiniteDimensional F E := IsSplittingField.finiteDimensional E p have hx := IsIntegral.of_finite F x let L := (p * minpoly F x).SplittingField have hL := SplittingField.splits (p * minpoly F x) @@ -77,7 +77,7 @@ theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] : rw [← j.comp_algebraMap, ← Polynomial.map_map] at hL2 refine ⟨hx, Splits.of_splits_map (j : E →+* L) hL2 fun a ha ↦ ?_⟩ rw [Polynomial.map_map, j.comp_algebraMap] at ha - letI : Algebra F⟮x⟯ L := ((algHomAdjoinIntegralEquiv F hx).symm ⟨a, ha⟩).toRingHom.toAlgebra + let : Algebra F⟮x⟯ L := ((algHomAdjoinIntegralEquiv F hx).symm ⟨a, ha⟩).toRingHom.toAlgebra let j' : E →ₐ[F⟮x⟯] L := IsSplittingField.lift E (p.map (algebraMap F F⟮x⟯)) ?_ · change a ∈ j.range rw [← IsSplittingField.adjoin_rootSet_eq_range E p j, @@ -100,7 +100,7 @@ instance normal_iSup {ι : Type*} (t : ι → IntermediateField F K) [h : ∀ i, obtain ⟨s, hx⟩ := exists_finset_of_mem_supr'' (fun i => (h i).1) x.2 let E : IntermediateField F K := ⨆ i ∈ s, adjoin F ((minpoly F (i.2 :)).rootSet K) have hF : Normal F E := by - haveI : IsSplittingField F E (∏ i ∈ s, minpoly F i.snd) := by + have : IsSplittingField F E (∏ i ∈ s, minpoly F i.snd) := by refine isSplittingField_iSup ?_ fun i _ => adjoin_rootSet_isSplittingField ?_ · exact Finset.prod_ne_zero_iff.mpr fun i _ => minpoly.ne_zero ((h i.1).isIntegral i.2) · simpa [Polynomial.map_map] using! ((h i.1).splits i.2).map (algebraMap (t i.1) K) diff --git a/Mathlib/FieldTheory/Normal/Closure.lean b/Mathlib/FieldTheory/Normal/Closure.lean index 38be50328034fd..75e15cd4f7e671 100644 --- a/Mathlib/FieldTheory/Normal/Closure.lean +++ b/Mathlib/FieldTheory/Normal/Closure.lean @@ -174,7 +174,7 @@ instance normal [h : Normal F L] : Normal F (normalClosure F K L) := by @[stacks 0BMG "When `L` is normal over `K`, this agrees with 0BMG (1) finiteness."] instance is_finiteDimensional [FiniteDimensional F K] : FiniteDimensional F (normalClosure F K L) := by - haveI : ∀ f : K →ₐ[F] L, FiniteDimensional F f.fieldRange := fun f ↦ + have : ∀ f : K →ₐ[F] L, FiniteDimensional F f.fieldRange := fun f ↦ f.toLinearMap.finiteDimensional_range apply IntermediateField.finiteDimensional_iSup_of_finite diff --git a/Mathlib/FieldTheory/Perfect.lean b/Mathlib/FieldTheory/Perfect.lean index b3987a9aa0062b..f84e7d48620242 100644 --- a/Mathlib/FieldTheory/Perfect.lean +++ b/Mathlib/FieldTheory/Perfect.lean @@ -299,7 +299,7 @@ lemma PerfectRing.toPerfectField (K : Type*) (p : ℕ) refine PerfectField.mk fun hf ↦ ?_ rcases separable_or p hf with h | ⟨-, g, -, rfl⟩ · assumption - · exfalso; revert hf; haveI := Fact.mk hp; simp + · exfalso; revert hf; have := Fact.mk hp; simp namespace PerfectField diff --git a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean index fc229f5e2f5dd5..b752e99329a38f 100644 --- a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean +++ b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean @@ -230,7 +230,7 @@ theorem restrictDvd_def [Decidable (q = 0)] (hpq : p ∣ q) : theorem restrictDvd_surjective (hpq : p ∣ q) (hq : q ≠ 0) : Function.Surjective (restrictDvd hpq) := by classical - haveI := Fact.mk <| + have := Fact.mk <| (SplittingField.splits q).of_dvd (map_ne_zero hq) ((map_dvd_map' _).mpr hpq) simpa only [restrictDvd_def, dif_neg hq] using! restrict_surjective _ _ @@ -253,7 +253,7 @@ theorem restrictProd_injective : Function.Injective (restrictProd p q) := by ext (x hx) rw [rootSet_def, aroots_mul hpq] at hx rcases Multiset.mem_add.mp (Multiset.mem_toFinset.mp hx) with h | h - · haveI : Fact ((p.map (algebraMap F (p * q).SplittingField)).Splits) := + · have : Fact ((p.map (algebraMap F (p * q).SplittingField)).Splits) := ⟨(SplittingField.splits (p * q)).of_dvd (map_ne_zero hpq) ((map_dvd_map' _).mpr (dvd_mul_right p q))⟩ have key : @@ -264,7 +264,7 @@ theorem restrictProd_injective : Function.Injective (restrictProd p q) := by Subtype.ext_iff.mp (Equiv.apply_symm_apply (rootsEquivRoots p _) ⟨x, _⟩).symm rw [key, ← AlgEquiv.restrictNormal_commutes, ← AlgEquiv.restrictNormal_commutes] exact congr_arg _ (AlgEquiv.ext_iff.mp hfg.1 _) - · haveI : Fact ((q.map (algebraMap F (p * q).SplittingField)).Splits) := + · have : Fact ((q.map (algebraMap F (p * q).SplittingField)).Splits) := ⟨(SplittingField.splits (p * q)).of_dvd (map_ne_zero hpq) ((map_dvd_map' _).mpr (dvd_mul_left q p))⟩ have key : @@ -335,7 +335,7 @@ def restrictComp (hq : q.natDegree ≠ 0) : (p.comp q).Gal →* p.Gal := theorem restrictComp_surjective (hq : q.natDegree ≠ 0) : Function.Surjective (restrictComp p q hq) := by - haveI : Fact (Splits (p.map (algebraMap F (SplittingField (comp p q))))) := + have : Fact (Splits (p.map (algebraMap F (SplittingField (comp p q))))) := ⟨splits_in_splittingField_of_comp p q hq⟩ simpa only [restrictComp] using! restrict_surjective _ _ @@ -359,7 +359,7 @@ theorem prime_degree_dvd_card [CharZero F] (p_irr : Irreducible p) (p_deg : p.na have hα : IsIntegral F α := .of_finite F α use Module.finrank F⟮α⟯ p.SplittingField suffices (minpoly F α).natDegree = p.natDegree by - letI _ : AddCommGroup F⟮α⟯ := Ring.toAddCommGroup + let _ : AddCommGroup F⟮α⟯ := Ring.toAddCommGroup rw [← Module.finrank_mul_finrank F F⟮α⟯ p.SplittingField, IntermediateField.adjoin.finrank hα, this] suffices minpoly F α ∣ p by diff --git a/Mathlib/FieldTheory/PrimitiveElement.lean b/Mathlib/FieldTheory/PrimitiveElement.lean index 7808f3e877d094..bf7018053ae58d 100644 --- a/Mathlib/FieldTheory/PrimitiveElement.lean +++ b/Mathlib/FieldTheory/PrimitiveElement.lean @@ -218,7 +218,7 @@ theorem exists_primitive_element : ∃ α : E, F⟮α⟯ = ⊤ := by intro K β hK obtain ⟨α, hK⟩ := hK rw [← hK, adjoin_simple_adjoin_simple] - haveI : Infinite F := isEmpty_fintype.mp F_inf + have : Infinite F := isEmpty_fintype.mp F_inf obtain ⟨γ, hγ⟩ := primitive_element_inf_aux F α β exact ⟨γ, hγ.symm⟩ exact induction_on_adjoin P base ih ⊤ @@ -279,7 +279,7 @@ theorem FiniteDimensional.of_finite_intermediateField [Finite (IntermediateField F E)] : FiniteDimensional F E := by let IF := { K : IntermediateField F E // ∃ x, K = F⟮x⟯ } have := isAlgebraic_of_finite_intermediateField F E - haveI : ∀ K : IF, FiniteDimensional F K.1 := fun ⟨_, x, rfl⟩ ↦ adjoin.finiteDimensional + have : ∀ K : IF, FiniteDimensional F K.1 := fun ⟨_, x, rfl⟩ ↦ adjoin.finiteDimensional (Algebra.IsIntegral.isIntegral _) have hfin := finiteDimensional_iSup_of_finite (t := fun K : IF ↦ K.1) have htop : ⨆ K : IF, K.1 = ⊤ := le_top.antisymm fun x _ ↦ @@ -289,7 +289,7 @@ theorem FiniteDimensional.of_finite_intermediateField theorem exists_primitive_element_of_finite_intermediateField [Finite (IntermediateField F E)] (K : IntermediateField F E) : ∃ α : E, F⟮α⟯ = K := by - haveI := FiniteDimensional.of_finite_intermediateField F E + have := FiniteDimensional.of_finite_intermediateField F E rcases finite_or_infinite F with (_ | _) · obtain ⟨α, h⟩ := exists_primitive_element_of_finite_bot F K exact ⟨α, by simpa only [lift_adjoin_simple, lift_top] using congr_arg lift h⟩ @@ -308,7 +308,7 @@ theorem FiniteDimensional.of_exists_primitive_element [Algebra.IsAlgebraic F E] -- A finite simple extension has only finitely many intermediate fields theorem finite_intermediateField_of_exists_primitive_element [Algebra.IsAlgebraic F E] (h : ∃ α : E, F⟮α⟯ = ⊤) : Finite (IntermediateField F E) := by - haveI := FiniteDimensional.of_exists_primitive_element F E h + have := FiniteDimensional.of_exists_primitive_element F E h obtain ⟨α, hprim⟩ := h -- Let `f` be the minimal polynomial of `α ∈ E` over `F` let f : F[X] := minpoly F α @@ -401,7 +401,7 @@ theorem primitive_element_iff_algHom_eq_of_eval (α : E) (φ : E →ₐ[F] A) : F⟮α⟯ = ⊤ ↔ ∀ ψ : E →ₐ[F] A, φ α = ψ α → φ = ψ := by refine ⟨fun h ψ hψ ↦ (Field.primitive_element_iff_algHom_eq_of_eval' F A hA α).mp h hψ, fun h ↦ eq_of_le_of_finrank_eq' le_top ?_⟩ - letI : Algebra F⟮α⟯ A := (φ.comp F⟮α⟯.val).toAlgebra + let : Algebra F⟮α⟯ A := (φ.comp F⟮α⟯.val).toAlgebra rw [IntermediateField.finrank_top, ← AlgHom.card_of_splits _ _ A, Fintype.card_eq_one_iff] · exact ⟨{ __ := φ, commutes' := fun _ ↦ rfl }, fun ψ ↦ AlgHom.restrictScalars_injective F <| Eq.symm <| h _ (ψ.commutes <| AdjoinSimple.gen F α).symm⟩ diff --git a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean index 71681f5634f0ed..3723fd1cc88636 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean @@ -248,7 +248,7 @@ then `K / E` is also purely inseparable. -/ theorem IsPurelyInseparable.tower_top [Algebra E K] [IsScalarTower F E K] [h : IsPurelyInseparable F K] : IsPurelyInseparable E K := by obtain ⟨q, _⟩ := ExpChar.exists F - haveI := expChar_of_injective_algebraMap (algebraMap F E).injective q + have := expChar_of_injective_algebraMap (algebraMap F E).injective q rw [isPurelyInseparable_iff_pow_mem _ q] at h ⊢ intro x obtain ⟨n, y, h⟩ := h x @@ -260,7 +260,7 @@ purely inseparable. -/ theorem IsPurelyInseparable.trans [Algebra E K] [IsScalarTower F E K] [h1 : IsPurelyInseparable F E] [h2 : IsPurelyInseparable E K] : IsPurelyInseparable F K := by obtain ⟨q, _⟩ := ExpChar.exists F - haveI := expChar_of_injective_algebraMap (algebraMap F E).injective q + have := expChar_of_injective_algebraMap (algebraMap F E).injective q rw [isPurelyInseparable_iff_pow_mem _ q] at h1 h2 ⊢ intro x obtain ⟨n, y, h2⟩ := h2 x @@ -375,7 +375,7 @@ theorem injective_comp_algebraMap [CommRing L] [IsReduced L] : replace heq := congr($heq y) simp_rw [RingHom.comp_apply, h, map_pow] at heq nontriviality L - haveI := expChar_of_injective_ringHom (f.comp (algebraMap F E)).injective q + have := expChar_of_injective_ringHom (f.comp (algebraMap F E)).injective q exact iterateFrobenius_inj L q n heq theorem injective_restrictDomain [CommRing L] [IsReduced L] [Algebra R L] [IsScalarTower R F E] : @@ -483,8 +483,8 @@ instance separableClosure.isPurelyInseparable [Algebra.IsAlgebraic F E] : set L := separableClosure F E refine ⟨(IsAlgebraic.tower_top L (Algebra.IsAlgebraic.isAlgebraic (R := F) x)).isIntegral, fun h ↦ ?_⟩ - haveI := (isSeparable_adjoin_simple_iff_isSeparable L E).2 h - haveI : Algebra.IsSeparable F (restrictScalars F L⟮x⟯) := Algebra.IsSeparable.trans F L L⟮x⟯ + have := (isSeparable_adjoin_simple_iff_isSeparable L E).2 h + have : Algebra.IsSeparable F (restrictScalars F L⟮x⟯) := Algebra.IsSeparable.trans F L L⟮x⟯ have hx : x ∈ L⟮x⟯.restrictScalars F := mem_adjoin_simple_self _ x exact ⟨⟨x, mem_separableClosure_iff.2 <| isSeparable_of_mem_isSeparable F E hx⟩, rfl⟩ @@ -511,9 +511,9 @@ separable closure of `F` in `E` if and only if `E` is purely inseparable over it theorem separableClosure_le_iff [Algebra.IsAlgebraic F E] (L : IntermediateField F E) : separableClosure F E ≤ L ↔ IsPurelyInseparable L E := by refine ⟨fun h ↦ ?_, fun _ ↦ separableClosure_le F E L⟩ - letI := (inclusion h).toAlgebra - letI : SMul (separableClosure F E) L := Algebra.toSMul - haveI : IsScalarTower (separableClosure F E) L E := IsScalarTower.of_algebraMap_eq (congrFun rfl) + let := (inclusion h).toAlgebra + let : SMul (separableClosure F E) L := Algebra.toSMul + have : IsScalarTower (separableClosure F E) L E := IsScalarTower.of_algebraMap_eq (congrFun rfl) exact IsPurelyInseparable.tower_top (separableClosure F E) L E /-- If an intermediate field of `E / F` is separable over `F`, and `E` is purely inseparable @@ -539,7 +539,7 @@ theorem IsPurelyInseparable.of_injective_comp_algebraMap (L : Type w) [Field L] [Nonempty (E →+* L)] (h : Function.Injective fun f : E →+* L ↦ f.comp (algebraMap F E)) : IsPurelyInseparable F E := by rw [isPurelyInseparable_iff_finSepDegree_eq_one, finSepDegree, Nat.card_eq_one_iff_unique] - letI := (Classical.arbitrary (E →+* L)).toAlgebra + let := (Classical.arbitrary (E →+* L)).toAlgebra let j : AlgebraicClosure E →ₐ[E] L := IsAlgClosed.lift exact ⟨⟨fun f g ↦ DFunLike.ext' <| j.injective.comp_left (congr_arg (⇑) <| @h (j.toRingHom.comp f) (j.toRingHom.comp g) (by ext; simp))⟩, inferInstance⟩ @@ -558,7 +558,7 @@ purely inseparable. -/ theorem isSepClosed_iff_isPurelyInseparable_algebraicClosure [IsAlgClosure F E] : IsSepClosed F ↔ IsPurelyInseparable F E := ⟨fun _ ↦ inferInstance, fun H ↦ by - haveI := IsAlgClosure.isAlgClosed F (K := E) + have := IsAlgClosure.isAlgClosed F (K := E) rwa [← separableClosure.eq_bot_iff, IsSepClosed.separableClosure_eq_bot_iff] at H⟩ variable {F E} in @@ -626,7 +626,7 @@ theorem adjoin_eq_of_isAlgebraic [Algebra.IsAlgebraic F E] : set S := separableClosure E K have h := congr_arg lift (adjoin_eq_of_isAlgebraic_of_isSeparable (F := F) S) rw [lift_top, lift_adjoin] at h - haveI : IsScalarTower F S K := IsScalarTower.of_algebraMap_eq (congrFun rfl) + have : IsScalarTower F S K := IsScalarTower.of_algebraMap_eq (congrFun rfl) rw [← h, ← map_eq_of_separableClosure_eq_bot F (separableClosure_eq_bot E K)] simp only [S, coe_map, IsScalarTower.coe_toAlgHom', IntermediateField.algebraMap_apply] diff --git a/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean b/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean index d22f0846dcb214..46234c6a9314fb 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean @@ -179,7 +179,7 @@ end map `perfectClosure F E` is perfect. -/ instance perfectClosure.perfectRing (p : ℕ) [ExpChar E p] [PerfectRing E p] : PerfectRing (perfectClosure F E) p := .ofSurjective _ p fun x ↦ by - haveI := RingHom.expChar _ (algebraMap F E).injective p + have := RingHom.expChar _ (algebraMap F E).injective p obtain ⟨x', hx⟩ := surjective_frobenius E p x.1 obtain ⟨n, y, hy⟩ := (mem_perfectClosure_iff_pow_mem p).1 x.2 rw [frobenius_def] at hx @@ -240,10 +240,10 @@ theorem adjoin_eq_adjoin_pow_expChar_pow_of_isSeparable (S : Set E) rw [adjoin_le_iff] rintro _ ⟨y, hy, rfl⟩ exact pow_mem (subset_adjoin F S hy) _ - letI := (inclusion hi).toAlgebra - haveI : Algebra.IsSeparable M (extendScalars hi) := + let := (inclusion hi).toAlgebra + have : Algebra.IsSeparable M (extendScalars hi) := Algebra.isSeparable_tower_top_of_isSeparable F M L - haveI : IsPurelyInseparable M (extendScalars hi) := by + have : IsPurelyInseparable M (extendScalars hi) := by rw [extendScalars_adjoin hi, isPurelyInseparable_adjoin_iff_pow_mem M _ q] exact fun x hx ↦ ⟨n, ⟨x ^ q ^ n, subset_adjoin F _ ⟨x, hx, rfl⟩⟩, rfl⟩ simpa only [extendScalars_restrictScalars, restrictScalars_bot_eq_self] using congr_arg @@ -275,7 +275,7 @@ theorem adjoin_eq_adjoin_pow_expChar_of_isSeparable' [Algebra.IsSeparable F E] ( `F⟮a⟯ = F⟮a ^ q ^ n⟯` for any natural number `n`. -/ theorem adjoin_simple_eq_adjoin_pow_expChar_pow_of_isSeparable {a : E} (ha : IsSeparable F a) (q : ℕ) [ExpChar F q] (n : ℕ) : F⟮a⟯ = F⟮a ^ q ^ n⟯ := by - haveI := (isSeparable_adjoin_simple_iff_isSeparable F E).mpr ha + have := (isSeparable_adjoin_simple_iff_isSeparable F E).mpr ha simpa using adjoin_eq_adjoin_pow_expChar_pow_of_isSeparable F E {a} q n /-- If `E / F` is a separable field extension of exponential characteristic `q`, then @@ -318,7 +318,7 @@ theorem Field.span_map_pow_expChar_pow_eq_top_of_isSeparable [Algebra.IsSeparabl rw [this] refine (Submodule.span_mono <| Set.range_comp_subset_range _ _).antisymm (Submodule.span_le.2 ?_) rw [Set.range_comp, ← Set.image_univ] - haveI := expChar_of_injective_algebraMap (algebraMap F E).injective q + have := expChar_of_injective_algebraMap (algebraMap F E).injective q apply h ▸ Submodule.image_span_subset_span (LinearMap.iterateFrobenius F E q n) _ /-- If `E / F` is a finite separable extension of exponential characteristic `q`, if `{ u_i }` is a @@ -332,7 +332,7 @@ private theorem LinearIndependent.map_pow_expChar_pow_of_fd_isSeparable have h' := h.linearIndepOn_id let ι' := h'.extend (Set.range v).subset_univ let b : Basis ι' F E := Basis.extend h' - letI : Fintype ι' := FiniteDimensional.fintypeBasisIndex b + let : Fintype ι' := FiniteDimensional.fintypeBasisIndex b have H := linearIndependent_of_top_le_span_of_card_eq_finrank (Field.span_map_pow_expChar_pow_eq_top_of_isSeparable q n b.span_eq).ge (Module.finrank_eq_card_basis b).symm @@ -350,7 +350,7 @@ theorem LinearIndependent.map_pow_expChar_pow_of_isSeparable [Algebra.IsSeparabl rw [linearIndependent_iff_finset_linearIndependent] at h ⊢ intro s let E' := adjoin F (s.image v : Set E) - haveI : FiniteDimensional F E' := finiteDimensional_adjoin + have : FiniteDimensional F E' := finiteDimensional_adjoin fun x _ ↦ Algebra.IsIntegral.isIntegral x let v' (i : s) : E' := ⟨v i.1, subset_adjoin F _ (Finset.mem_image.2 ⟨i.1, i.2, rfl⟩)⟩ have h' : LinearIndependent F v' := (h s).of_comp E'.val.toLinearMap @@ -364,7 +364,7 @@ theorem LinearIndependent.map_pow_expChar_pow_of_isSeparable' (hsep : ∀ i : ι, IsSeparable F (v i)) (h : LinearIndependent F v) : LinearIndependent F (v · ^ q ^ n) := by let E' := adjoin F (Set.range v) - haveI : Algebra.IsSeparable F E' := (isSeparable_adjoin_iff_isSeparable F _).2 <| by + have : Algebra.IsSeparable F E' := (isSeparable_adjoin_iff_isSeparable F _).2 <| by rintro _ ⟨y, rfl⟩; exact hsep y let v' (i : ι) : E' := ⟨v i, subset_adjoin F _ ⟨i, rfl⟩⟩ have h' : LinearIndependent F v' := h.of_comp E'.val.toLinearMap @@ -410,8 +410,8 @@ end theorem perfectField_of_perfectClosure_eq_bot [h : PerfectField E] (eq : perfectClosure F E = ⊥) : PerfectField F := by let p := ringExpChar F - haveI := expChar_of_injective_algebraMap (algebraMap F E).injective p - haveI := PerfectRing.ofSurjective F p fun x ↦ by + have := expChar_of_injective_algebraMap (algebraMap F E).injective p + have := PerfectRing.ofSurjective F p fun x ↦ by obtain ⟨y, h⟩ := surjective_frobenius E p (algebraMap F E x) have : y ∈ perfectClosure F E := ⟨1, x, by rw [← h, pow_one, frobenius_def, ringExpChar.eq F p]⟩ obtain ⟨z, rfl⟩ := eq ▸ this diff --git a/Mathlib/FieldTheory/PurelyInseparable/Tower.lean b/Mathlib/FieldTheory/PurelyInseparable/Tower.lean index 832583fd13a49b..f34105fab10298 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Tower.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Tower.lean @@ -66,7 +66,7 @@ theorem LinearIndependent.map_of_isPurelyInseparable_of_isSeparable [IsPurelyIns {ι : Type*} {v : ι → K} (hsep : ∀ i : ι, IsSeparable F (v i)) (h : LinearIndependent F v) : LinearIndependent E v := by obtain ⟨q, _⟩ := ExpChar.exists F - haveI := expChar_of_injective_algebraMap (algebraMap F K).injective q + have := expChar_of_injective_algebraMap (algebraMap F K).injective q refine linearIndependent_iff.mpr fun l hl ↦ Finsupp.ext fun i ↦ ?_ choose f hf using fun i ↦ (isPurelyInseparable_iff_pow_mem F q).1 ‹_› (l i) let n := l.support.sup f @@ -149,7 +149,7 @@ intermediate result used to prove it. -/ lemma sepDegree_eq_of_isPurelyInseparable [IsPurelyInseparable F E] : sepDegree F K = sepDegree E K := by convert! sepDegree_eq_of_isPurelyInseparable_of_isSeparable F E (separableClosure E K) - haveI : IsScalarTower F (separableClosure E K) K := IsScalarTower.of_algebraMap_eq (congrFun rfl) + have : IsScalarTower F (separableClosure E K) K := IsScalarTower.of_algebraMap_eq (congrFun rfl) rw [sepDegree, ← separableClosure.map_eq_of_separableClosure_eq_bot F (separableClosure.separableClosure_eq_bot E K)] exact (separableClosure F (separableClosure E K)).equivMap @@ -227,10 +227,10 @@ theorem IntermediateField.sepDegree_adjoin_eq_of_isAlgebraic_of_isPurelyInsepara rw [restrictScalars_adjoin_of_algEquiv (E := K) j rfl, restrictScalars_adjoin] exact adjoin.mono _ _ _ Set.subset_union_right let i : M →+* L := Subsemiring.inclusion hi - letI : Algebra M L := i.toAlgebra - letI : SMul M L := Algebra.toSMul - haveI : IsScalarTower F M L := IsScalarTower.of_algebraMap_eq (congrFun rfl) - haveI : IsPurelyInseparable M L := by + let : Algebra M L := i.toAlgebra + let : SMul M L := Algebra.toSMul + have : IsScalarTower F M L := IsScalarTower.of_algebraMap_eq (congrFun rfl) + have : IsPurelyInseparable M L := by change IsPurelyInseparable M (extendScalars hi) obtain ⟨q, _⟩ := ExpChar.exists F have : extendScalars hi = adjoin M (E' : Set K) := restrictScalars_injective F <| by @@ -270,8 +270,8 @@ theorem minpoly.map_eq_of_isSeparable_of_isPurelyInseparable (x : K) refine eq_of_monic_of_dvd_of_natDegree_le (monic hi') ((monic hi).map (algebraMap F E)) (dvd_map_of_isScalarTower F E x) (le_of_eq ?_) have hsep' := IsSeparable.tower_top E hsep - haveI := (isSeparable_adjoin_simple_iff_isSeparable _ _).2 hsep - haveI := (isSeparable_adjoin_simple_iff_isSeparable _ _).2 hsep' + have := (isSeparable_adjoin_simple_iff_isSeparable _ _).2 hsep + have := (isSeparable_adjoin_simple_iff_isSeparable _ _).2 hsep' have := Algebra.IsSeparable.isAlgebraic F F⟮x⟯ rw [Polynomial.natDegree_map, ← adjoin.finrank hi, ← adjoin.finrank hi', ← finSepDegree_eq_finrank_of_isSeparable F _, ← finSepDegree_eq_finrank_of_isSeparable E _, diff --git a/Mathlib/FieldTheory/RatFunc/Basic.lean b/Mathlib/FieldTheory/RatFunc/Basic.lean index d99cb6ca38a10a..4425d45880ab37 100644 --- a/Mathlib/FieldTheory/RatFunc/Basic.lean +++ b/Mathlib/FieldTheory/RatFunc/Basic.lean @@ -198,7 +198,7 @@ variable [Monoid R] [DistribMulAction R K[X]] variable [IsScalarTower R K[X] K[X]] theorem mk_smul (c : R) (p q : K[X]) : RatFunc.mk (c • p) q = c • RatFunc.mk p q := by - letI : SMulZeroClass R (FractionRing K[X]) := inferInstance + let : SMulZeroClass R (FractionRing K[X]) := inferInstance by_cases hq : q = 0 · rw [hq, mk_zero, mk_zero, ← ofFractionRing_smul, smul_zero] · rw [mk_eq_localization_mk _ hq, mk_eq_localization_mk _ hq, ← Localization.smul_mk, ← diff --git a/Mathlib/FieldTheory/RatFunc/IntermediateField.lean b/Mathlib/FieldTheory/RatFunc/IntermediateField.lean index 5fd7aeac0fe1f0..e12687c9a206da 100644 --- a/Mathlib/FieldTheory/RatFunc/IntermediateField.lean +++ b/Mathlib/FieldTheory/RatFunc/IntermediateField.lean @@ -148,7 +148,7 @@ theorem irreducible_minpolyX' (hf : ¬∃ c, f = C c) : Irreducible (f.minpolyX exact sub_eq_add_neg (Polynomial.C f.num) (Polynomial.C f.denom * Polynomial.X) theorem irreducible_minpolyX (hf : ¬∃ c, f = C c) : Irreducible (f.minpolyX K⟮f⟯) := by - haveI : UniqueFactorizationMonoid K[f] := + have : UniqueFactorizationMonoid K[f] := (f.transcendental_of_ne_C hf).uniqueFactorizationMonoid_adjoin rw [← f.minpolyX_map K[f] K⟮f⟯, ← IsPrimitive.irreducible_iff_irreducible_map_fraction_map] diff --git a/Mathlib/FieldTheory/Relrank.lean b/Mathlib/FieldTheory/Relrank.lean index 28f775aedb62d4..e59bc4bd2205f2 100644 --- a/Mathlib/FieldTheory/Relrank.lean +++ b/Mathlib/FieldTheory/Relrank.lean @@ -107,8 +107,8 @@ alias ⟨_, relfinrank_eq_one_of_le⟩ := relfinrank_eq_one_iff theorem relrank_mul_rank_top (h : A ≤ B) : relrank A B * Module.rank B E = Module.rank A E := by rw [relrank_eq_rank_of_le h] - letI : Algebra A B := (inclusion h).toAlgebra - haveI : IsScalarTower A B E := IsScalarTower.of_algebraMap_eq' rfl + let : Algebra A B := (inclusion h).toAlgebra + have : IsScalarTower A B E := IsScalarTower.of_algebraMap_eq' rfl exact rank_mul_rank A B E theorem relfinrank_mul_finrank_top (h : A ≤ B) : relfinrank A B * finrank B E = finrank A E := by @@ -229,10 +229,10 @@ theorem relrank_mul_relrank (h1 : A ≤ B) (h2 : B ≤ C) : relrank A B * relrank B C = relrank A C := by have h3 := h1.trans h2 rw [relrank_eq_rank_of_le h1, relrank_eq_rank_of_le h2, relrank_eq_rank_of_le h3] - letI : Algebra A B := (inclusion h1).toAlgebra - letI : Algebra B C := (inclusion h2).toAlgebra - letI : Algebra A C := (inclusion h3).toAlgebra - haveI : IsScalarTower A B C := IsScalarTower.of_algebraMap_eq' rfl + let : Algebra A B := (inclusion h1).toAlgebra + let : Algebra B C := (inclusion h2).toAlgebra + let : Algebra A C := (inclusion h3).toAlgebra + have : IsScalarTower A B C := IsScalarTower.of_algebraMap_eq' rfl exact rank_mul_rank A B C variable {A B C} in @@ -435,7 +435,7 @@ theorem relfinrank_mul_finrank_top (h : A ≤ B) : relfinrank A B * finrank B E variable {A B} in theorem rank_bot_mul_relrank (h : A ≤ B) : Module.rank F A * relrank A B = Module.rank F B := by rw [relrank_eq_rank_of_le h] - letI : Algebra A B := (inclusion h).toAlgebra + let : Algebra A B := (inclusion h).toAlgebra exact rank_mul_rank F A B variable {A B} in diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 6fe3e6458fa074..f118e695465557 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -345,11 +345,11 @@ theorem separable_or {f : F[X]} (hf : Irreducible f) : classical exact if H : derivative f = 0 then by rcases p.eq_zero_or_pos with (rfl | hp) - · haveI := CharP.charP_to_charZero F + · have := CharP.charP_to_charZero F have := derivative_eq_zero.1 H have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne' contradiction - haveI := isLocalHom_expand F hp + have := isLocalHom_expand F hp exact Or.inr ⟨by rw [separable_iff_derivative_ne_zero hf, Classical.not_not, H], contract p f, @@ -565,7 +565,7 @@ variable {F} in because the minimal polynomial of a non-integral element is `0`, which is not separable. -/ theorem IsSeparable.isIntegral {x : K} (h : IsSeparable F x) : IsIntegral F x := by cases subsingleton_or_nontrivial F - · haveI := Module.subsingleton F K + · have := Module.subsingleton F K exact ⟨1, monic_one, Subsingleton.elim _ _⟩ · exact of_not_not (h.ne_zero <| minpoly.eq_zero ·) @@ -702,7 +702,7 @@ include f variable {F} in theorem IsSeparable.of_algHom {x : E} (h : IsSeparable F (f x)) : IsSeparable F x := by let _ : Algebra E E' := RingHom.toAlgebra f.toRingHom - haveI : IsScalarTower F E E' := IsScalarTower.of_algebraMap_eq fun x => (f.commutes x).symm + have : IsScalarTower F E E' := IsScalarTower.of_algebraMap_eq fun x => (f.commutes x).symm exact h.tower_bot diff --git a/Mathlib/FieldTheory/SeparableClosure.lean b/Mathlib/FieldTheory/SeparableClosure.lean index 43518d5675b070..e8344ba55beafe 100644 --- a/Mathlib/FieldTheory/SeparableClosure.lean +++ b/Mathlib/FieldTheory/SeparableClosure.lean @@ -436,7 +436,7 @@ theorem insepDegree_bot' : insepDegree F (⊥ : IntermediateField E K) = insepDe variable (F) in lemma _root_.Field.insepDegree_top_le_insepDegree_of_isScalarTower : insepDegree E K ≤ insepDegree F K := by - letI := (IntermediateField.inclusion (separableClosure.le_restrictScalars F E K)).toAlgebra + let := (IntermediateField.inclusion (separableClosure.le_restrictScalars F E K)).toAlgebra have : IsScalarTower (separableClosure F K) ((separableClosure E K).restrictScalars F) K := .of_algebraMap_eq' rfl exact Module.rank_top_le_rank_of_isScalarTower @@ -445,14 +445,14 @@ lemma _root_.Field.insepDegree_top_le_insepDegree_of_isScalarTower : variable {K} in lemma _root_.Field.insepDegree_le_of_left_le {E₁ E₂ : IntermediateField F K} (H : E₁ ≤ E₂) : insepDegree E₂ K ≤ insepDegree E₁ K := by - letI := (IntermediateField.inclusion H).toAlgebra + let := (IntermediateField.inclusion H).toAlgebra have : IsScalarTower E₁ E₂ K := .of_algebraMap_eq' rfl exact insepDegree_top_le_insepDegree_of_isScalarTower _ _ _ variable (F) in lemma _root_.Field.finInsepDegree_top_le_finInsepDegree_of_isScalarTower [Module.Finite F K] : finInsepDegree E K ≤ finInsepDegree F K := by - letI := (IntermediateField.inclusion (separableClosure.le_restrictScalars F E K)).toAlgebra + let := (IntermediateField.inclusion (separableClosure.le_restrictScalars F E K)).toAlgebra have : IsScalarTower (separableClosure F K) ((separableClosure E K).restrictScalars F) K := .of_algebraMap_eq' rfl exact Module.finrank_top_le_finrank_of_isScalarTower @@ -461,7 +461,7 @@ lemma _root_.Field.finInsepDegree_top_le_finInsepDegree_of_isScalarTower [Module variable {K} in lemma finInsepDegree_le_of_left_le {E₁ E₂ : IntermediateField F K} (H : E₁ ≤ E₂) [Module.Finite E₁ K] : finInsepDegree E₂ K ≤ finInsepDegree E₁ K := by - letI := (IntermediateField.inclusion H).toAlgebra + let := (IntermediateField.inclusion H).toAlgebra have : IsScalarTower E₁ E₂ K := .of_algebraMap_eq' rfl exact finInsepDegree_top_le_finInsepDegree_of_isScalarTower _ _ _ diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index 690441f0b98017..65e870ea96ac4c 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -485,7 +485,7 @@ theorem natSepDegree_expand (q : ℕ) [hF : ExpChar F q] {n : ℕ} : (expand F (q ^ n) f).natSepDegree = f.natSepDegree := by obtain - | hprime := hF · simp only [one_pow, expand_one] - haveI := Fact.mk hprime + have := Fact.mk hprime classical simpa only [natSepDegree_eq_of_isAlgClosed (AlgebraicClosure F), aroots_def, map_expand, Fintype.card_coe] using Fintype.card_eq.2 @@ -585,7 +585,7 @@ theorem eq_X_pow_char_pow_sub_C_of_natSepDegree_eq_one_of_irreducible (q : ℕ) exact ⟨0, y, .inl rfl, hf⟩ | prime hq => refine ⟨n, y, (em _).imp id fun hn ⟨z, hy⟩ ↦ ?_, hf⟩ - haveI := expChar_of_injective_ringHom (R := F) C_injective q + have := expChar_of_injective_ringHom (R := F) C_injective q rw [hf, ← Nat.succ_pred hn, pow_succ, pow_mul, ← hy, frobenius_def, map_pow, ← sub_pow_expChar] at hi exact not_irreducible_pow hq.ne_one hi @@ -671,8 +671,8 @@ separable degree one if and only if the minimal polynomial is of the form `(X - x) ^ (q ^ n)` for some `n : ℕ`. -/ theorem natSepDegree_eq_one_iff_eq_X_sub_C_pow : (minpoly F x).natSepDegree = 1 ↔ ∃ n : ℕ, (minpoly F x).map (algebraMap F E) = (X - C x) ^ q ^ n := by - haveI := expChar_of_injective_algebraMap (algebraMap F E).injective q - haveI := expChar_of_injective_ringHom (C_injective (R := E)) q + have := expChar_of_injective_algebraMap (algebraMap F E).injective q + have := expChar_of_injective_ringHom (C_injective (R := E)) q refine ⟨fun h ↦ ?_, fun ⟨n, h⟩ ↦ (natSepDegree_eq_one_iff_pow_mem q).2 ?_⟩ · obtain ⟨n, y, h⟩ := (natSepDegree_eq_one_iff_eq_X_pow_sub_C q).1 h have hx := congr_arg (Polynomial.aeval x) h.symm @@ -716,7 +716,7 @@ private theorem finSepDegree_adjoin_simple_dvd_finrank (α : E) : algebraic over `F`. -/ theorem finSepDegree_adjoin_simple_le_finrank (α : E) (halg : IsAlgebraic F α) : finSepDegree F F⟮α⟯ ≤ finrank F F⟮α⟯ := by - haveI := adjoin.finiteDimensional halg.isIntegral + have := adjoin.finiteDimensional halg.isIntegral exact Nat.le_of_dvd finrank_pos <| finSepDegree_adjoin_simple_dvd_finrank F E α /-- If `α` is algebraic over `F`, then the separable degree of `F⟮α⟯ / F` is equal to the degree @@ -800,7 +800,7 @@ theorem IntermediateField.isSeparable_adjoin_simple_iff_isSeparable {x : E} : refine ⟨fun _ ↦ ?_, fun hsep ↦ ?_⟩ · exact isSeparable_of_mem_isSeparable F E <| mem_adjoin_simple_self F x · have h := IsSeparable.isIntegral hsep - haveI := adjoin.finiteDimensional h + have := adjoin.finiteDimensional h rwa [← finSepDegree_eq_finrank_iff, finSepDegree_adjoin_simple_eq_finrank_iff F E x h.isAlgebraic] @@ -811,7 +811,7 @@ theorem IsSeparable.of_algebra_isSeparable_of_isSeparable [Algebra E K] [IsScala [Algebra.IsSeparable F E] {x : K} (hsep : IsSeparable E x) : IsSeparable F x := by set f := minpoly E x with hf let E' : IntermediateField F E := adjoin F f.coeffs - haveI : FiniteDimensional F E' := + have : FiniteDimensional F E' := finiteDimensional_adjoin fun x _ ↦ Algebra.IsSeparable.isIntegral F x let g : E'[X] := f.toSubring E'.toSubring (subset_adjoin F _) have h : g.map (algebraMap E' E) = f := f.map_toSubring E'.toSubring (subset_adjoin F _) @@ -823,10 +823,10 @@ theorem IsSeparable.of_algebra_isSeparable_of_isSeparable [Algebra E K] [IsScala isIntegral_trans (R := F) (A := E) _ (IsSeparable.isIntegral hsep) |>.tower_top simp only [IsSeparable, ← hf, ← h, separable_map] at hsep replace hsep := hsep.of_dvd <| minpoly.dvd E' x hzero - haveI : Algebra.IsSeparable F E' := Algebra.isSeparable_tower_bot_of_isSeparable F E' E - haveI := (isSeparable_adjoin_simple_iff_isSeparable _ _).2 hsep - haveI := adjoin.finiteDimensional halg - haveI : FiniteDimensional F E'⟮x⟯ := FiniteDimensional.trans F E' E'⟮x⟯ + have : Algebra.IsSeparable F E' := Algebra.isSeparable_tower_bot_of_isSeparable F E' E + have := (isSeparable_adjoin_simple_iff_isSeparable _ _).2 hsep + have := adjoin.finiteDimensional halg + have : FiniteDimensional F E'⟮x⟯ := FiniteDimensional.trans F E' E'⟮x⟯ have := finSepDegree_mul_finSepDegree_of_isAlgebraic F E' E'⟮x⟯ rw [finSepDegree_eq_finrank_of_isSeparable F E', finSepDegree_eq_finrank_of_isSeparable E' E'⟮x⟯, @@ -908,7 +908,7 @@ theorem perfectField_iff_splits_of_natSepDegree_eq_one (F : Type*) [Field F] : rw [h.natSepDegree_eq_natDegree, hf] at key exact Splits.of_natDegree_le_one key obtain ⟨p, _⟩ := ExpChar.exists F - haveI := PerfectRing.ofSurjective F p fun x ↦ by + have := PerfectRing.ofSurjective F p fun x ↦ by obtain ⟨y, hy⟩ := Splits.exists_eval_eq_zero (h _ (pow_one p ▸ natSepDegree_X_pow_char_pow_sub_C p 1 x)) ((degree_X_pow_sub_C (expChar_pos F p) x).symm ▸ Nat.cast_pos.2 (expChar_pos F p)).ne' diff --git a/Mathlib/Geometry/Euclidean/Altitude.lean b/Mathlib/Geometry/Euclidean/Altitude.lean index cf2c704ce1e916..25cda183f866e8 100644 --- a/Mathlib/Geometry/Euclidean/Altitude.lean +++ b/Mathlib/Geometry/Euclidean/Altitude.lean @@ -106,7 +106,7 @@ lemma altitude_restrict_eq_comap_subtype {n : ℕ} (s : Simplex ℝ P n) (S : Af (hS : affineSpan ℝ (Set.range s.points) ≤ S) (i : Fin (n + 1)) : haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).altitude i = (s.altitude i).comap S.subtype := by - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance rw [← s.map_altitude_restrict S hS, comap_map_eq_of_injective S.subtype_injective] open Module @@ -287,7 +287,7 @@ variable {n : ℕ} (s : Simplex ℝ P n) lemma inner_vsub_altitudeFoot_vsub_altitudeFoot_eq_zero {i j : Fin (n + 1)} (h : i ≠ j) : have : NeZero n := by grind [neZero_iff] ⟪s.points j -ᵥ s.altitudeFoot i, s.points i -ᵥ s.altitudeFoot i⟫ = 0 := by - haveI : NeZero n := by grind [neZero_iff] + have : NeZero n := by grind [neZero_iff] refine Submodule.inner_right_of_mem_orthogonal (K := vectorSpan ℝ (s.points '' {i}ᶜ)) (vsub_mem_vectorSpan_of_mem_affineSpan_of_mem_affineSpan diff --git a/Mathlib/Geometry/Euclidean/Angle/Bisector.lean b/Mathlib/Geometry/Euclidean/Angle/Bisector.lean index a560ad1adffb1b..32f422e6e20709 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Bisector.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Bisector.lean @@ -142,9 +142,9 @@ lemma oangle_eq_of_dist_orthogonalProjection_eq {p p' : P} {s₁ s₂ : AffineSu dist p (orthogonalProjection s₁ p) = dist p (orthogonalProjection s₂ p) → ∡ (orthogonalProjection s₁ p : P) p' p = ∡ p p' (orthogonalProjection s₂ p) := by intro hne h - haveI : Nonempty s₁ := ⟨p', hp'₁⟩ - haveI : Nonempty s₂ := ⟨p', hp'₂⟩ - haveI : Nonempty (s₁ ⊓ s₂ : AffineSubspace ℝ P) := ⟨p', hp'₁, hp'₂⟩ + have : Nonempty s₁ := ⟨p', hp'₁⟩ + have : Nonempty s₂ := ⟨p', hp'₂⟩ + have : Nonempty (s₁ ⊓ s₂ : AffineSubspace ℝ P) := ⟨p', hp'₁, hp'₂⟩ have hp₁ : orthogonalProjection s₁ p ≠ p' := by intro hp rw [hp, eq_comm, dist_orthogonalProjection_eq_dist_iff_eq_of_mem hp'₂] at h @@ -217,8 +217,8 @@ lemma dist_orthogonalProjection_eq_of_two_zsmul_oangle_eq {p p' : P} (2 : ℤ) • ∡ p p' (orthogonalProjection s₂ p) → dist p (orthogonalProjection s₁ p) = dist p (orthogonalProjection s₂ p) := by intro hp₁ hp₂ h - haveI : Nonempty s₁ := ⟨p', hp'₁⟩ - haveI : Nonempty s₂ := ⟨p', hp'₂⟩ + have : Nonempty s₁ := ⟨p', hp'₁⟩ + have : Nonempty s₂ := ⟨p', hp'₂⟩ have h' : ∡ (orthogonalProjection s₁ p : P) p' p = ∡ p p' (orthogonalProjection s₂ p) := oangle_eq_oangle_rev_of_two_zsmul_eq_of_angle_eq_pi_div_two h (angle_self_orthogonalProjection _ hp'₁) (angle_self_orthogonalProjection _ hp'₂) diff --git a/Mathlib/Geometry/Euclidean/Angle/Oriented/Projection.lean b/Mathlib/Geometry/Euclidean/Angle/Oriented/Projection.lean index f044c886ffed2f..bd93a5cc6c1879 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Oriented/Projection.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Oriented/Projection.lean @@ -32,7 +32,7 @@ lemma oangle_self_orthogonalProjection (p : P) {p' : P} {s : AffineSubspace ℝ haveI : Nonempty s := ⟨p', h⟩ ∡ p (orthogonalProjection s p) p' = (π / 2 : ℝ) ∨ ∡ p (orthogonalProjection s p) p' = (-π / 2 : ℝ) := by - haveI : Nonempty s := ⟨p', h⟩ + have : Nonempty s := ⟨p', h⟩ have hpne : p ≠ orthogonalProjection s p := Ne.symm (orthogonalProjection_eq_self_iff.not.2 hp) have ha := oangle_eq_angle_or_eq_neg_angle hpne hp' rw [angle_self_orthogonalProjection p h] at ha diff --git a/Mathlib/Geometry/Euclidean/Angle/Oriented/Rotation.lean b/Mathlib/Geometry/Euclidean/Angle/Oriented/Rotation.lean index 7e56474c341b6e..495f17778b3708 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Oriented/Rotation.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Oriented/Rotation.lean @@ -105,7 +105,7 @@ theorem rotation_eq_matrix_toLin (θ : Real.Angle) {x : V} (hx : x ≠ 0) : /-- The determinant of `rotation` (as a linear map) is equal to `1`. -/ @[simp] theorem det_rotation (θ : Real.Angle) : LinearMap.det (o.rotation θ).toLinearMap = 1 := by - haveI : Nontrivial V := nontrivial_of_finrank_eq_succ (@Fact.out (finrank ℝ V = 2) _) + have : Nontrivial V := nontrivial_of_finrank_eq_succ (@Fact.out (finrank ℝ V = 2) _) obtain ⟨x, hx⟩ : ∃ x, x ≠ (0 : V) := exists_ne (0 : V) rw [o.rotation_eq_matrix_toLin θ hx] simpa [sq] using θ.cos_sq_add_sin_sq @@ -329,7 +329,7 @@ theorem oangle_eq_iff_eq_pos_smul_rotation_or_eq_zero {x y : V} (θ : Real.Angle theorem exists_linearIsometryEquiv_eq_of_det_pos {f : V ≃ₗᵢ[ℝ] V} (hd : 0 < LinearMap.det (f.toLinearEquiv : V →ₗ[ℝ] V)) : ∃ θ : Real.Angle, f = o.rotation θ := by - haveI : Nontrivial V := nontrivial_of_finrank_eq_succ (@Fact.out (finrank ℝ V = 2) _) + have : Nontrivial V := nontrivial_of_finrank_eq_succ (@Fact.out (finrank ℝ V = 2) _) obtain ⟨x, hx⟩ : ∃ x, x ≠ (0 : V) := exists_ne (0 : V) use o.oangle x (f x) apply LinearIsometryEquiv.toLinearEquiv_injective diff --git a/Mathlib/Geometry/Euclidean/Angle/Sphere.lean b/Mathlib/Geometry/Euclidean/Angle/Sphere.lean index eb8f55b8d8c157..884fb30fa6fba4 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Sphere.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Sphere.lean @@ -114,7 +114,7 @@ theorem isDiameter_of_angle_eq_pi_div_two {p₁ p₂ p₃ : P} {s : Sphere P} (hne₁₂ : p₁ ≠ p₂) (hne₂₃ : p₂ ≠ p₃) (hangle : ∠ p₁ p₂ p₃ = π / 2) : s.IsDiameter p₁ p₃ := by - haveI : FiniteDimensional ℝ V := .of_finrank_eq_succ (Fact.out : finrank ℝ V = 2) + have : FiniteDimensional ℝ V := .of_finrank_eq_succ (Fact.out : finrank ℝ V = 2) have hne₁₃ : p₁ ≠ p₃ := fun h ↦ by rw [h, angle_self_of_ne hne₂₃.symm] at hangle; linarith [Real.pi_pos] have hd := Sphere.isDiameter_ofDiameter p₁ p₃ diff --git a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Projection.lean b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Projection.lean index e78798f049de94..5c87eda1e0a9c6 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Projection.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Projection.lean @@ -29,7 +29,7 @@ open scoped Real [s.direction.HasOrthogonalProjection] (h : p' ∈ s) : haveI : Nonempty s := ⟨p', h⟩ ∠ p (orthogonalProjection s p) p' = π / 2 := by - haveI : Nonempty s := ⟨p', h⟩ + have : Nonempty s := ⟨p', h⟩ rw [angle, ← InnerProductGeometry.inner_eq_zero_iff_angle_eq_pi_div_two] exact Submodule.inner_left_of_mem_orthogonal (K := s.direction) (AffineSubspace.vsub_mem_direction h (orthogonalProjection_mem _)) diff --git a/Mathlib/Geometry/Euclidean/Circumcenter.lean b/Mathlib/Geometry/Euclidean/Circumcenter.lean index 4f79e5b964beae..38f13272631a25 100644 --- a/Mathlib/Geometry/Euclidean/Circumcenter.lean +++ b/Mathlib/Geometry/Euclidean/Circumcenter.lean @@ -56,7 +56,7 @@ theorem existsUnique_dist_eq_of_insert {s : AffineSubspace ℝ P} (hp : p ∉ s) (hu : ∃! cs : Sphere P, cs.center ∈ s ∧ ps ⊆ (cs : Set P)) : ∃! cs₂ : Sphere P, cs₂.center ∈ affineSpan ℝ (insert p (s : Set P)) ∧ insert p ps ⊆ (cs₂ : Set P) := by - haveI : Nonempty s := Set.Nonempty.to_subtype (hnps.mono hps) + have : Nonempty s := Set.Nonempty.to_subtype (hnps.mono hps) rcases hu with ⟨⟨cc, cr⟩, ⟨hcc, hcr⟩, hcccru⟩ simp only at hcc hcr hcccru let x := dist cc (orthogonalProjection s p) @@ -143,7 +143,7 @@ theorem _root_.AffineIndependent.existsUnique_dist_eq {ι : Type*} [hne : Nonemp rcases m with - | m · rw [Fintype.card_eq_one_iff] at hn obtain ⟨i, hi⟩ := hn - haveI : Unique ι := ⟨⟨i⟩, hi⟩ + have : Unique ι := ⟨⟨i⟩, hi⟩ use ⟨p i, 0⟩ simp only [Set.range_unique, AffineSubspace.mem_affineSpan_singleton] constructor @@ -162,7 +162,7 @@ theorem _root_.AffineIndependent.existsUnique_dist_eq {ι : Type*} [hne : Nonemp Finset.card_sdiff, Finset.card_univ, hn] simp · simp - haveI : Nonempty ι2 := Fintype.card_pos_iff.1 (hc.symm ▸ Nat.zero_lt_succ _) + have : Nonempty ι2 := Fintype.card_pos_iff.1 (hc.symm ▸ Nat.zero_lt_succ _) have ha2 : AffineIndependent ℝ fun i2 : ι2 => p i2 := ha.subtype _ replace hm := hm ha2 _ hc have hr : Set.range p = insert (p i) (Set.range fun i2 : ι2 => p i2) := by diff --git a/Mathlib/Geometry/Euclidean/Incenter.lean b/Mathlib/Geometry/Euclidean/Incenter.lean index 2d2c443c690725..4a8fbcee5d77f2 100644 --- a/Mathlib/Geometry/Euclidean/Incenter.lean +++ b/Mathlib/Geometry/Euclidean/Incenter.lean @@ -386,7 +386,7 @@ variable {s} in haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).excenter signs = s.excenter signs := by rw [← s.excenterExists_restrict S hS] at h - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance exact (h.excenter_map S.subtypeₐᵢ).symm /-- The incenter of a simplex. -/ @@ -798,7 +798,7 @@ variable {s} in haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).touchpoint signs i = s.touchpoint signs i := by rw [← s.excenterExists_restrict S hS] at h - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance exact (h.touchpoint_map S.subtypeₐᵢ i).symm lemma touchpoint_mem_affineSpan (signs : Finset (Fin (n + 1))) (i : Fin (n + 1)) : @@ -1146,7 +1146,7 @@ variable {s} in haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).touchpointWeights signs = s.touchpointWeights signs := by rw [← s.excenterExists_restrict S hS] at h - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance exact (h.touchpointWeights_map S.subtypeₐᵢ).symm variable {s} in diff --git a/Mathlib/Geometry/Euclidean/MongePoint.lean b/Mathlib/Geometry/Euclidean/MongePoint.lean index dbd753a21e81b8..fdda4bdaf6ad67 100644 --- a/Mathlib/Geometry/Euclidean/MongePoint.lean +++ b/Mathlib/Geometry/Euclidean/MongePoint.lean @@ -127,7 +127,7 @@ theorem mongePoint_restrict {n : ℕ} (s : Simplex ℝ P n) (S : AffineSubspace (hS : affineSpan ℝ (Set.range s.points) ≤ S) : haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).mongePoint = s.mongePoint := by - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance simp_rw [mongePoint] rw [← Simplex.centroid, ← Simplex.centroid] simp [centroid_restrict, circumcenter_restrict] diff --git a/Mathlib/Geometry/Euclidean/NinePointCircle.lean b/Mathlib/Geometry/Euclidean/NinePointCircle.lean index 3bd274ff36de7d..f0f77ee351ab70 100644 --- a/Mathlib/Geometry/Euclidean/NinePointCircle.lean +++ b/Mathlib/Geometry/Euclidean/NinePointCircle.lean @@ -139,7 +139,7 @@ theorem eulerPoint_restrict {n : ℕ} (s : Simplex ℝ P n) (S : AffineSubspace (hS : affineSpan ℝ (Set.range s.points) ≤ S) (i : Fin (n + 1)) : haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).eulerPoint i = s.eulerPoint i := by - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance simp [eulerPoint] theorem points_vsub_eulerPoint {n : ℕ} (s : Simplex ℝ P n) (i : Fin (n + 1)) : diff --git a/Mathlib/Geometry/Euclidean/Projection.lean b/Mathlib/Geometry/Euclidean/Projection.lean index 0e40071d98d269..5232d7dd2f158e 100644 --- a/Mathlib/Geometry/Euclidean/Projection.lean +++ b/Mathlib/Geometry/Euclidean/Projection.lean @@ -306,7 +306,7 @@ lemma dist_orthogonalProjection_eq_dist_iff_eq_of_mem {s : AffineSubspace 𝕜 P [s.direction.HasOrthogonalProjection] {p₁ p₂ : P} (hp₂ : p₂ ∈ s) : haveI : Nonempty s := ⟨p₂, hp₂⟩ dist p₁ (orthogonalProjection s p₁) = dist p₁ p₂ ↔ orthogonalProjection s p₁ = p₂ := by - haveI : Nonempty s := ⟨p₂, hp₂⟩ + have : Nonempty s := ⟨p₂, hp₂⟩ constructor · intro h rwa [← sq_eq_sq₀ dist_nonneg dist_nonneg, pow_two, pow_two, dist_comm _ p₂, diff --git a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean index 89c2f614e760ed..14bf842b552b13 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean @@ -379,7 +379,7 @@ inclusion into a larger affine subspace `S₂` is cospherical. -/ theorem Cospherical.inclusion_iff {S₁ S₂ : AffineSubspace ℝ P} [Nonempty S₁] {ps : Set S₁} [S₁.direction.HasOrthogonalProjection] [S₂.direction.HasOrthogonalProjection] (hS : S₁ ≤ S₂) : Cospherical (AffineSubspace.inclusion hS '' ps) ↔ Cospherical ps := by - haveI : Nonempty S₂ := by obtain ⟨p⟩ := ‹Nonempty S₁›; exact ⟨⟨p, hS p.property⟩⟩ + have : Nonempty S₂ := by obtain ⟨p⟩ := ‹Nonempty S₁›; exact ⟨⟨p, hS p.property⟩⟩ simp [(Cospherical.subtype_val_iff (S := S₂) (ps := AffineSubspace.inclusion hS '' ps)).symm, Set.image_image] diff --git a/Mathlib/Geometry/Euclidean/Sphere/Power.lean b/Mathlib/Geometry/Euclidean/Sphere/Power.lean index c1fc4fbcd7aa5c..a79253fd8dd3e4 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Power.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Power.lean @@ -198,7 +198,7 @@ theorem cospherical_of_mul_dist_eq_mul_dist_of_angle_eq_pi {p₁ p₂ p₃ p₄ have hf2 : Fact (finrank ℝ S.direction = 2) := ⟨by rw [hS, direction_affineSpan, t.independent.finrank_vectorSpan] simp⟩ - letI : Module.Oriented ℝ S.direction (Fin 2) := + let : Module.Oriented ℝ S.direction (Fin 2) := ⟨Basis.orientation (finBasisOfFinrankEq _ _ hf2.out)⟩ have hncol : ¬ Collinear ℝ {p₁', p', p₃'} := by rw [← affineIndependent_iff_not_collinear_set, diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index b74ab6fd4af0cc..31e0e7f45ed0db 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -223,9 +223,9 @@ open TopologicalSpace theorem ChartedSpace.secondCountable_of_countable_cover [SecondCountableTopology H] {s : Set M} (hs : ⋃ (x) (_ : x ∈ s), (chartAt H x).source = univ) (hsc : s.Countable) : SecondCountableTopology M := by - haveI : ∀ x : M, SecondCountableTopology (chartAt H x).source := + have : ∀ x : M, SecondCountableTopology (chartAt H x).source := fun x ↦ (chartAt (H := H) x).secondCountableTopology_source - haveI := hsc.toEncodable + have := hsc.toEncodable rw [biUnion_eq_iUnion] at hs exact secondCountableTopology_of_countable_cover (fun x : s ↦ (chartAt H (x : M)).open_source) hs @@ -546,13 +546,13 @@ lemma ChartedSpace.sum_chartAt_inr (x' : M') : @[simp, mfld_simps] lemma sum_chartAt_inl_apply {x y : M} : (chartAt H (.inl x : M ⊕ M')) (Sum.inl y) = (chartAt H x) y := by - haveI : Nonempty H := nonempty_of_chartedSpace x + have : Nonempty H := nonempty_of_chartedSpace x rw [ChartedSpace.sum_chartAt_inl] exact OpenPartialHomeomorph.lift_openEmbedding_apply _ _ @[simp, mfld_simps] lemma sum_chartAt_inr_apply {x y : M'} : (chartAt H (.inr x : M ⊕ M')) (Sum.inr y) = (chartAt H x) y := by - haveI : Nonempty H := nonempty_of_chartedSpace x + have : Nonempty H := nonempty_of_chartedSpace x rw [ChartedSpace.sum_chartAt_inr] exact OpenPartialHomeomorph.lift_openEmbedding_apply _ _ @@ -656,7 +656,7 @@ protected def openPartialHomeomorph (e : PartialEquiv M H) (he : e ∈ c.atlas) open_source := by convert! c.open_source' he open_target := by convert! c.open_target he continuousOn_toFun := by - letI : TopologicalSpace M := c.toTopologicalSpace + let : TopologicalSpace M := c.toTopologicalSpace rw [continuousOn_open_iff (c.open_source' he)] intro s s_open rw [inter_comm] @@ -664,7 +664,7 @@ protected def openPartialHomeomorph (e : PartialEquiv M H) (he : e ∈ c.atlas) simp only [exists_prop, mem_iUnion, mem_singleton_iff] exact ⟨e, he, ⟨s, s_open, rfl⟩⟩ continuousOn_invFun := by - letI : TopologicalSpace M := c.toTopologicalSpace + let : TopologicalSpace M := c.toTopologicalSpace apply continuousOn_isOpen_of_generateFrom intro t ht simp only [exists_prop, mem_iUnion, mem_singleton_iff] at ht diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean index fa43fc3ba3dfaa..0e744acc5bf41a 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean @@ -415,7 +415,7 @@ variable {e : M → H} (h : IsOpenEmbedding e) {n : ℕ∞ω} then `e` is `C^n`. -/ lemma contMDiff_isOpenEmbedding [Nonempty M] : haveI := h.singletonChartedSpace; ContMDiff I I n e := by - haveI := h.isManifold_singleton (I := I) (n := ω) + have := h.isManifold_singleton (I := I) (n := ω) rw [@contMDiff_iff _ _ _ _ _ _ _ _ _ _ h.singletonChartedSpace] use h.continuous intro x y @@ -441,7 +441,7 @@ then the inverse of `e` is `C^n`. -/ lemma contMDiffOn_isOpenEmbedding_symm [Nonempty M] : haveI := h.singletonChartedSpace; ContMDiffOn I I n (IsOpenEmbedding.toOpenPartialHomeomorph e h).symm (range e) := by - haveI := h.isManifold_singleton (I := I) (n := ω) + have := h.isManifold_singleton (I := I) (n := ω) rw [@contMDiffOn_iff] constructor · rw [← h.toOpenPartialHomeomorph_target] diff --git a/Mathlib/Geometry/Manifold/Diffeomorph.lean b/Mathlib/Geometry/Manifold/Diffeomorph.lean index 8aec58763bbdb0..51fefea662bdd4 100644 --- a/Mathlib/Geometry/Manifold/Diffeomorph.lean +++ b/Mathlib/Geometry/Manifold/Diffeomorph.lean @@ -403,9 +403,9 @@ def transContinuousLinearEquiv : ModelWithCorners 𝕜 E' H where · simp only [PartialEquiv.coe_trans, Equiv.toPartialEquiv_apply, LinearEquiv.coe_toEquiv, ContinuousLinearEquiv.coe_toLinearEquiv, toPartialEquiv_coe] rw [range_comp] - letI := h.rclike - letI := NormedSpace.restrictScalars ℝ 𝕜 E - letI := NormedSpace.restrictScalars ℝ 𝕜 E' + let := h.rclike + let := NormedSpace.restrictScalars ℝ 𝕜 E + let := NormedSpace.restrictScalars ℝ 𝕜 E' let eR : E →L[ℝ] E' := ContinuousLinearMap.restrictScalars ℝ (e : E →L[𝕜] E') change Convex ℝ (⇑eR '' range ↑I) apply I.convex_range.linear_image diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 5dc7b8202b1ab3..4be4e83777f6a7 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -196,8 +196,8 @@ def ModelWithCorners.ofTargetUniv (𝕜 : Type*) [NontriviallyNormedField 𝕜] have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm] simp only [this, htarget, dite_else_true] intro h - letI := h.rclike 𝕜 - letI := NormedSpace.restrictScalars ℝ 𝕜 E + let := h.rclike 𝕜 + let := NormedSpace.restrictScalars ℝ 𝕜 E exact convex_univ nonempty_interior' := by have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm] @@ -311,8 +311,8 @@ lemma _root_.Convex.convex_isRCLikeNormedField [NormedSpace ℝ E] [h : IsRCLike letI := h.rclike letI := NormedSpace.restrictScalars ℝ 𝕜 E Convex ℝ s := by - letI := h.rclike - letI := NormedSpace.restrictScalars ℝ 𝕜 E + let := h.rclike + let := NormedSpace.restrictScalars ℝ 𝕜 E simp only [Convex, StarConvex] at hs ⊢ intro u hu v hv a b ha hb hab convert! hs hu hv ha hb hab using 2 @@ -340,7 +340,7 @@ def ofConvexRange theorem convex_range [NormedSpace ℝ E] : Convex ℝ (range I) := by by_cases h : IsRCLikeNormedField 𝕜 - · letI : RCLike 𝕜 := h.rclike + · let : RCLike 𝕜 := h.rclike have W := I.convex_range' simp only [h, ↓reduceDIte, toPartialEquiv_coe] at W simp only [Convex, StarConvex] at W ⊢ @@ -354,16 +354,16 @@ theorem convex_range [NormedSpace ℝ E] : Convex ℝ (range I) := by protected theorem uniqueDiffOn : UniqueDiffOn 𝕜 (range I) := by by_cases h : IsRCLikeNormedField 𝕜 - · letI := h.rclike 𝕜 - letI := NormedSpace.restrictScalars ℝ 𝕜 E + · let := h.rclike 𝕜 + let := NormedSpace.restrictScalars ℝ 𝕜 E apply uniqueDiffOn_convex_of_isRCLikeNormedField _ I.nonempty_interior simpa [h] using I.convex_range · simp [range_eq_univ_of_not_isRCLikeNormedField I h, uniqueDiffOn_univ] theorem range_subset_closure_interior : range I ⊆ closure (interior (range I)) := by by_cases h : IsRCLikeNormedField 𝕜 - · letI := h.rclike 𝕜 - letI := NormedSpace.restrictScalars ℝ 𝕜 E + · let := h.rclike 𝕜 + let := NormedSpace.restrictScalars ℝ 𝕜 E rw [Convex.closure_interior_eq_closure_of_nonempty_interior (𝕜 := ℝ)] · apply subset_closure · apply I.convex_range @@ -513,8 +513,8 @@ def ModelWithCorners.prod {𝕜 : Type u} [NontriviallyNormedField 𝕜] {E : Ty have : range (fun (x : ModelProd H H') ↦ (I x.1, I' x.2)) = range (Prod.map I I') := rfl rw [this, Set.range_prodMap] split_ifs with h - · letI := h.rclike - letI := NormedSpace.restrictScalars ℝ 𝕜 E; letI := NormedSpace.restrictScalars ℝ 𝕜 E' + · let := h.rclike + let := NormedSpace.restrictScalars ℝ 𝕜 E; let := NormedSpace.restrictScalars ℝ 𝕜 E' exact I.convex_range.prod I'.convex_range · simp [range_eq_univ_of_not_isRCLikeNormedField, h] nonempty_interior' := by @@ -536,8 +536,8 @@ def ModelWithCorners.pi {𝕜 : Type u} [NontriviallyNormedField 𝕜] {ι : Typ convex_range' := by rw [PartialEquiv.pi_apply, Set.range_piMap] split_ifs with h - · letI := h.rclike - letI := fun i ↦ NormedSpace.restrictScalars ℝ 𝕜 (E i) + · let := h.rclike + let := fun i ↦ NormedSpace.restrictScalars ℝ 𝕜 (E i) exact convex_pi fun i _hi ↦ (I i).convex_range · simp [range_eq_univ_of_not_isRCLikeNormedField, h] nonempty_interior' := by @@ -805,7 +805,7 @@ theorem isManifold_of_contDiffOn {𝕜 : Type*} [NontriviallyNormedField 𝕜] ContDiffOn 𝕜 n (I ∘ e.symm ≫ₕ e' ∘ I.symm) (I.symm ⁻¹' (e.symm ≫ₕ e').source ∩ range I)) : IsManifold I n M where compatible := by - haveI : HasGroupoid M (contDiffGroupoid n I) := hasGroupoid_of_pregroupoid _ (h _ _) + have : HasGroupoid M (contDiffGroupoid n I) := hasGroupoid_of_pregroupoid _ (h _ _) apply StructureGroupoid.compatible /-- For any model with corners, the model space is a `C^n` manifold -/ diff --git a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean index 0388d393f42a59..35af7c80c9d15e 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean @@ -874,14 +874,14 @@ theorem extChartAt_comp [ChartedSpace H H'] (x : M') : theorem writtenInExtChartAt_chartAt_comp [ChartedSpace H H'] (x : M') {y} (hy : y ∈ letI := ChartedSpace.comp H H' M'; (extChartAt I x).target) : (letI := ChartedSpace.comp H H' M'; writtenInExtChartAt I I x (chartAt H' x) y) = y := by - letI := ChartedSpace.comp H H' M' + let := ChartedSpace.comp H H' M' simp_all only [mfld_simps, chartAt_comp] theorem writtenInExtChartAt_chartAt_symm_comp [ChartedSpace H H'] (x : M') {y} (hy : y ∈ letI := ChartedSpace.comp H H' M'; (extChartAt I x).target) : (letI := ChartedSpace.comp H H' M' writtenInExtChartAt I I (chartAt H' x x) (chartAt H' x).symm y) = y := by - letI := ChartedSpace.comp H H' M' + let := ChartedSpace.comp H H' M' simp_all only [mfld_simps, chartAt_comp] end ExtendedCharts diff --git a/Mathlib/Geometry/Manifold/Metrizable.lean b/Mathlib/Geometry/Manifold/Metrizable.lean index 9c8f856fbaba3c..cdd13fd5f4efb4 100644 --- a/Mathlib/Geometry/Manifold/Metrizable.lean +++ b/Mathlib/Geometry/Manifold/Metrizable.lean @@ -28,7 +28,7 @@ theorem Manifold.metrizableSpace {E : Type*} [NormedAddCommGroup E] [NormedSpace [FiniteDimensional ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) (M : Type*) [TopologicalSpace M] [ChartedSpace H M] [SigmaCompactSpace M] [T2Space M] : MetrizableSpace M := by - haveI := I.locallyCompactSpace; haveI := ChartedSpace.locallyCompactSpace H M - haveI := I.secondCountableTopology - haveI := ChartedSpace.secondCountable_of_sigmaCompact H M + have := I.locallyCompactSpace; have := ChartedSpace.locallyCompactSpace H M + have := I.secondCountableTopology + have := ChartedSpace.secondCountable_of_sigmaCompact H M exact metrizableSpace_of_t3_secondCountable M diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index 9eea8726d755ad..a916bb439155ec 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -365,8 +365,8 @@ theorem exists_isSubordinate [T2Space M] [SigmaCompactSpace M] (hs : IsClosed s) (hU : ∀ x ∈ s, U x ∈ 𝓝 x) : ∃ (ι : Type uM) (f : SmoothBumpCovering ι I M s), f.IsSubordinate U := by -- First we deduce some missing instances - haveI : LocallyCompactSpace H := I.locallyCompactSpace - haveI : LocallyCompactSpace M := ChartedSpace.locallyCompactSpace H M + have : LocallyCompactSpace H := I.locallyCompactSpace + have : LocallyCompactSpace M := ChartedSpace.locallyCompactSpace H M -- Next we choose a covering by supports of smooth bump functions have hB := fun x hx => SmoothBumpFunction.nhds_basis_support (I := I) (hU x hx) rcases refinement_of_locallyCompact_sigmaCompact_of_nhds_basis_set hs hB with @@ -562,8 +562,8 @@ variable [T2Space M] [SigmaCompactSpace M] `s`, then there exists a `SmoothPartitionOfUnity ι M s` that is subordinate to `U`. -/ theorem exists_isSubordinate {s : Set M} (hs : IsClosed s) (U : ι → Set M) (ho : ∀ i, IsOpen (U i)) (hU : s ⊆ ⋃ i, U i) : ∃ f : SmoothPartitionOfUnity ι I M s, f.IsSubordinate U := by - haveI : LocallyCompactSpace H := I.locallyCompactSpace - haveI : LocallyCompactSpace M := ChartedSpace.locallyCompactSpace H M + have : LocallyCompactSpace H := I.locallyCompactSpace + have : LocallyCompactSpace M := ChartedSpace.locallyCompactSpace H M -- porting note(https://github.com/leanprover-community/batteries/issues/116): -- split `rcases` into `have` + `rcases` have := BumpCovering.exists_isSubordinate_of_prop (ContMDiff I 𝓘(ℝ) ∞) ?_ hs U ho hU diff --git a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean index aca6592592b743..687abb5f64b7f8 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean @@ -529,7 +529,7 @@ manifold satisfies the `IsRiemannianManifold I M` predicate. -/ instance [RegularSpace M] : letI : PseudoEMetricSpace M := .ofRiemannianMetric I M IsRiemannianManifold I M := by - letI : PseudoEMetricSpace M := .ofRiemannianMetric I M + let : PseudoEMetricSpace M := .ofRiemannianMetric I M exact ⟨fun x y ↦ rfl⟩ variable (M) in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index e120727df246fe..5c09cb521e7377 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -426,8 +426,8 @@ instance ContMDiffFiberwiseLinear.hasGroupoid : HasGroupoid (TotalSpace F E) (contMDiffFiberwiseLinear B F IB n) where compatible := by rintro _ _ ⟨e, he, rfl⟩ ⟨e', he', rfl⟩ - haveI : MemTrivializationAtlas e := ⟨he⟩ - haveI : MemTrivializationAtlas e' := ⟨he'⟩ + have : MemTrivializationAtlas e := ⟨he⟩ + have : MemTrivializationAtlas e' := ⟨he'⟩ rw [mem_contMDiffFiberwiseLinear_iff] refine ⟨_, _, e.open_baseSet.inter e'.open_baseSet, contMDiffOn_coordChangeL e e', contMDiffOn_symm_coordChangeL e e', ?_⟩ diff --git a/Mathlib/Geometry/Manifold/WhitneyEmbedding.lean b/Mathlib/Geometry/Manifold/WhitneyEmbedding.lean index 84b12fa4431b1b..cbf721d805019f 100644 --- a/Mathlib/Geometry/Manifold/WhitneyEmbedding.lean +++ b/Mathlib/Geometry/Manifold/WhitneyEmbedding.lean @@ -113,8 +113,8 @@ public theorem exists_immersion_euclidean {ι : Type*} [Finite ι] (f : SmoothBu CMDiff ∞ e ∧ Injective e ∧ ∀ x : M, Injective (mfderiv% e x) := by cases nonempty_fintype ι set F := EuclideanSpace ℝ (Fin <| finrank ℝ (ι → E × ℝ)) - letI : IsNoetherian ℝ (E × ℝ) := IsNoetherian.iff_fg.2 inferInstance - letI : FiniteDimensional ℝ (ι → E × ℝ) := IsNoetherian.iff_fg.1 inferInstance + let : IsNoetherian ℝ (E × ℝ) := IsNoetherian.iff_fg.2 inferInstance + let : FiniteDimensional ℝ (ι → E × ℝ) := IsNoetherian.iff_fg.1 inferInstance set eEF : (ι → E × ℝ) ≃L[ℝ] F := ContinuousLinearEquiv.ofFinrankEq finrank_euclideanSpace_fin.symm refine ⟨_, eEF ∘ f.embeddingPiTangent, @@ -135,6 +135,6 @@ public theorem exists_embedding_euclidean_of_compact [T2Space M] [CompactSpace M CMDiff ∞ e ∧ IsClosedEmbedding e ∧ ∀ x : M, Injective (mfderiv% e x) := by rcases SmoothBumpCovering.exists_isSubordinate I isClosed_univ fun (x : M) _ => univ_mem with ⟨ι, f, -⟩ - haveI := f.fintype + have := f.fintype rcases f.exists_immersion_euclidean with ⟨n, e, hsmooth, hinj, hinj_mfderiv⟩ exact ⟨n, e, hsmooth, hsmooth.continuous.isClosedEmbedding hinj, hinj_mfderiv⟩ diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean index aa7cc3a65ffbc6..47476b21365096 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean @@ -68,7 +68,7 @@ noncomputable def coproduct : LocallyRingedSpace where (F ⋙ forgetToSheafedSpace) isLocalRing x := by obtain ⟨i, y, ⟨⟩⟩ := SheafedSpace.colimit_exists_rep (F ⋙ forgetToSheafedSpace) x - haveI : IsLocalRing (((F ⋙ forgetToSheafedSpace).obj i).presheaf.stalk y) := + have : IsLocalRing (((F ⋙ forgetToSheafedSpace).obj i).presheaf.stalk y) := (F.obj i).isLocalRing _ exact (asIso ((colimit.ι (C := SheafedSpace.{u + 1, u, u} CommRingCat.{u}) @@ -139,7 +139,7 @@ theorem coequalizer_π_app_isLocalHom rw [← this, PresheafedSpace.comp_c_app, ← PresheafedSpace.colimitPresheafObjIsoComponentwiseLimit_hom_π] -- Porting note (https://github.com/leanprover-community/mathlib4/issues/10754): this instance has to be manually added - haveI : IsIso (PreservesCoequalizer.iso + have : IsIso (PreservesCoequalizer.iso SheafedSpace.forgetToPresheafedSpace f.toShHom g.toShHom).hom.c := inferInstance apply +allowSynthFailures RingHom.isLocalHom_comp diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 0d6bdc89118317..9c5c5cb048acd4 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -499,7 +499,7 @@ instance forget_preservesLimitsOfRight : PreservesLimit (cospan g f) (forget C) set_option backward.isDefEq.respectTransparency false in theorem pullback_snd_isIso_of_range_subset (H : Set.range g.base ⊆ Set.range f.base) : IsIso (pullback.snd f g) := by - haveI := TopCat.snd_iso_of_left_embedding_range_subset hf.base_open.isEmbedding g.base H + have := TopCat.snd_iso_of_left_embedding_range_subset hf.base_open.isEmbedding g.base H have : IsIso (pullback.snd f g).base := by delta pullback.snd rw [← limit.isoLimitCone_hom_π ⟨_, pullbackConeOfLeftIsLimit f g⟩ WalkingCospan.right] @@ -776,7 +776,7 @@ theorem of_stalk_iso {X Y : SheafedSpace C} (f : X ⟶ Y) (hf : IsOpenEmbedding rintro ⟨_, y, hy, rfl⟩ specialize H y delta PresheafedSpace.Hom.stalkMap at H - haveI H' := TopCat.Presheaf.stalkPushforward.stalkPushforward_iso_of_isInducing C + have H' := TopCat.Presheaf.stalkPushforward.stalkPushforward_iso_of_isInducing C hf.toIsInducing X.presheaf y have := IsIso.comp_isIso' H (@IsIso.inv_isIso _ _ _ _ _ H') rwa [Category.assoc, IsIso.hom_inv_id, Category.comp_id] at this } @@ -864,7 +864,7 @@ theorem ofRestrict_invApp {C : Type*} [Category* C] (X : SheafedSpace C) {Y : To /-- An open immersion is an iso if the underlying continuous map is epi. -/ theorem to_iso [h' : Epi f.hom.base] : IsIso f := by - haveI : IsIso (forgetToPresheafedSpace.map f) := PresheafedSpace.IsOpenImmersion.to_iso f.hom + have : IsIso (forgetToPresheafedSpace.map f) := PresheafedSpace.IsOpenImmersion.to_iso f.hom apply isIso_of_reflects_iso _ (SheafedSpace.forgetToPresheafedSpace) instance stalk_iso [HasColimits C] (x : X) : diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean index 57306bd71776d9..1371a4be78e12e 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean @@ -286,7 +286,7 @@ def ofRestrict {U : TopCat} (X : PresheafedSpace C) {f : U ⟶ (X : TopCat)} set_option backward.isDefEq.respectTransparency false in instance ofRestrict_mono {U : TopCat} (X : PresheafedSpace C) (f : U ⟶ X.1) (hf : IsOpenEmbedding f) : Mono (X.ofRestrict hf) := by - haveI : Mono f := (TopCat.mono_iff_injective _).mpr hf.injective + have : Mono f := (TopCat.mono_iff_injective _).mpr hf.injective constructor intro Z g₁ g₂ eq ext1 @@ -298,7 +298,7 @@ instance ofRestrict_mono {U : TopCat} (X : PresheafedSpace C) (f : U ⟶ X.1) have hV : (Opens.map (X.ofRestrict hf).base).obj (hf.functor.obj V) = V := by ext1 exact Set.preimage_image_eq _ hf.injective - haveI : + have : IsIso (hf.isOpenMap.adjunction.counit.app (unop (op (hf.functor.obj V)))) := NatIso.isIso_app_of_isIso (whiskerLeft hf.functor hf.isOpenMap.adjunction.counit) V diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index bb35843efbde61..e1f4c40a973d8e 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -81,7 +81,7 @@ variable {M} theorem commProb_eq_one_iff [h : Nonempty M] : commProb M = 1 ↔ IsMulCommutative M := by classical - haveI := Fintype.ofFinite M + have := Fintype.ofFinite M rw [commProb, ← Set.coe_setOf, Nat.card_eq_fintype_card, Nat.card_eq_fintype_card] rw [div_eq_one_iff_eq, ← Nat.cast_pow, Nat.cast_inj, sq, ← card_prod, set_fintype_card_eq_univ_iff, Set.eq_univ_iff_forall] diff --git a/Mathlib/GroupTheory/Exponent.lean b/Mathlib/GroupTheory/Exponent.lean index 370941c0f6b2b0..baa75fb99d4236 100644 --- a/Mathlib/GroupTheory/Exponent.lean +++ b/Mathlib/GroupTheory/Exponent.lean @@ -236,7 +236,7 @@ theorem lcm_orderOf_dvd_exponent [Fintype G] : @[to_additive exists_addOrderOf_eq_pow_padic_val_nat_add_exponent] theorem _root_.Nat.Prime.exists_orderOf_eq_pow_factorization_exponent {p : ℕ} (hp : p.Prime) : ∃ g : G, orderOf g = p ^ (exponent G).factorization p := by - haveI := Fact.mk hp + have := Fact.mk hp rcases eq_or_ne ((exponent G).factorization p) 0 with (h | h) · refine ⟨1, by rw [h, pow_zero, orderOf_one]⟩ have he : 0 < exponent G := diff --git a/Mathlib/GroupTheory/FiniteAbelian/Basic.lean b/Mathlib/GroupTheory/FiniteAbelian/Basic.lean index 6b780fe470f485..cdbd825b6e0b2b 100644 --- a/Mathlib/GroupTheory/FiniteAbelian/Basic.lean +++ b/Mathlib/GroupTheory/FiniteAbelian/Basic.lean @@ -97,11 +97,11 @@ variable (M : Type u) theorem finite_of_fg_torsion [AddCommGroup M] [Module ℤ M] [Module.Finite ℤ M] (hM : Module.IsTorsion ℤ M) : _root_.Finite M := by rcases Module.equiv_directSum_of_isTorsion hM with ⟨ι, _, p, h, e, ⟨l⟩⟩ - haveI : ∀ i : ι, NeZero (p i ^ e i).natAbs := fun i => + have : ∀ i : ι, NeZero (p i ^ e i).natAbs := fun i => ⟨Int.natAbs_ne_zero.mpr <| pow_ne_zero (e i) (h i).ne_zero⟩ - haveI : ∀ i : ι, _root_.Finite <| ℤ ⧸ Submodule.span ℤ {p i ^ e i} := fun i => + have : ∀ i : ι, _root_.Finite <| ℤ ⧸ Submodule.span ℤ {p i ^ e i} := fun i => Finite.of_equiv _ (p i ^ e i).quotientSpanEquivZMod.symm.toEquiv - haveI : _root_.Finite (⨁ i, ℤ ⧸ (Submodule.span ℤ {p i ^ e i} : Submodule ℤ ℤ)) := + have : _root_.Finite (⨁ i, ℤ ⧸ (Submodule.span ℤ {p i ^ e i} : Submodule ℤ ℤ)) := Finite.of_equiv _ DFinsupp.equivFunOnFintype.symm exact Finite.of_equiv _ l.symm.toEquiv @@ -141,7 +141,7 @@ theorem equiv_directSum_zmod_of_finite [Finite G] : · have : Unique (Fin Nat.zero →₀ ℤ) := { uniq := by subsingleton } exact ⟨ι, fι, p, hp, e, ⟨f.trans AddEquiv.uniqueProd⟩⟩ - · haveI := @Fintype.prodLeft _ _ _ (Fintype.ofEquiv G f.toEquiv) _ + · have := @Fintype.prodLeft _ _ _ (Fintype.ofEquiv G f.toEquiv) _ exact (Fintype.ofSurjective (fun f : Fin n.succ →₀ ℤ => f 0) fun a => ⟨Finsupp.single 0 a, Finsupp.single_eq_same⟩).false.elim diff --git a/Mathlib/GroupTheory/Finiteness.lean b/Mathlib/GroupTheory/Finiteness.lean index b23c7420082cfc..9fb6565793c25a 100644 --- a/Mathlib/GroupTheory/Finiteness.lean +++ b/Mathlib/GroupTheory/Finiteness.lean @@ -126,7 +126,7 @@ variable {ι : Type*} [Finite ι] {M : ι → Type*} [∀ i, Monoid (M i)] {P : @[to_additive] theorem Submonoid.iSup_map_mulSingle [DecidableEq ι] : ⨆ i, map (MonoidHom.mulSingle M i) (P i) = pi Set.univ P := by - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι refine iSup_map_mulSingle_le.antisymm fun x hx => ?_ rw [← Finset.noncommProd_mulSingle x] exact noncommProd_mem _ _ _ _ fun i _ => mem_iSup_of_mem _ (mem_map_of_mem _ (hx i trivial)) @@ -136,7 +136,7 @@ theorem Submonoid.iSup_map_mulSingle [DecidableEq ι] : /-- Finite product of finitely generated additive submonoids is finitely generated. -/] theorem Submonoid.FG.pi (hP : ∀ i, (P i).FG) : (pi Set.univ P).FG := by classical - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι choose s hs using hP refine ⟨Finset.univ.biUnion fun i => (s i).image (MonoidHom.mulSingle M i), ?_⟩ simp_rw [Finset.coe_biUnion, Finset.coe_univ, Set.biUnion_univ, closure_iUnion, Finset.coe_image, diff --git a/Mathlib/GroupTheory/GroupAction/Defs.lean b/Mathlib/GroupTheory/GroupAction/Defs.lean index 6293a15c31103f..caf5017f31ea4b 100644 --- a/Mathlib/GroupTheory/GroupAction/Defs.lean +++ b/Mathlib/GroupTheory/GroupAction/Defs.lean @@ -297,7 +297,7 @@ of the orbit of `U` under `G`. -/] theorem quotient_preimage_image_eq_union_mul (U : Set α) : letI := orbitRel G α Quotient.mk' ⁻¹' Quotient.mk' '' U = ⋃ g : G, (g • ·) '' U := by - letI := orbitRel G α + let := orbitRel G α set f : α → Quotient (MulAction.orbitRel G α) := Quotient.mk' ext a constructor @@ -318,7 +318,7 @@ theorem quotient_preimage_image_eq_union_mul (U : Set α) : theorem disjoint_image_image_iff {U V : Set α} : letI := orbitRel G α Disjoint (Quotient.mk' '' U) (Quotient.mk' '' V) ↔ ∀ x ∈ U, ∀ g : G, g • x ∉ V := by - letI := orbitRel G α + let := orbitRel G α set f : α → Quotient (MulAction.orbitRel G α) := Quotient.mk' refine ⟨fun h a a_in_U g g_in_V => diff --git a/Mathlib/GroupTheory/GroupAction/DomAct/Basic.lean b/Mathlib/GroupTheory/GroupAction/DomAct/Basic.lean index 3e8b3da14ed0d0..c9ed16172396e6 100644 --- a/Mathlib/GroupTheory/GroupAction/DomAct/Basic.lean +++ b/Mathlib/GroupTheory/GroupAction/DomAct/Basic.lean @@ -183,7 +183,7 @@ instance [SMul M α] [FaithfulSMul M α] [Nontrivial β] : FaithfulSMul Mᵈᵐ eq_of_smul_eq_smul {c₁ c₂} h := mk.symm.injective <| eq_of_smul_eq_smul fun a : α ↦ by rcases exists_pair_ne β with ⟨x, y, hne⟩ contrapose! hne - haveI := Classical.decEq α + have := Classical.decEq α replace h := congr_fun (h (update (const α x) (mk.symm c₂ • a) y)) a simpa [smul_apply, hne] using h diff --git a/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean b/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean index 102af46eb06390..05007575b5599e 100644 --- a/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean +++ b/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean @@ -631,7 +631,7 @@ theorem _root_.IsMultiplyPretransitive.alternatingGroup_le theorem isPretransitive_of_three_le_card (h : 3 ≤ Nat.card α) : IsPretransitive (alternatingGroup α) α := by rw [← is_one_pretransitive_iff] - letI := isMultiplyPretransitive α + let := isMultiplyPretransitive α apply isMultiplyPretransitive_of_le (n := Nat.card α - 2) _ (sub_le _ _) rwa [← add_le_add_iff_right 2, Nat.sub_add_cancel (le_trans (by norm_num) h)] @@ -652,7 +652,7 @@ theorem isTrivialBlock_of_isBlock {B : Set α} (hB : IsBlock (alternatingGroup suffices IsPreprimitive (alternatingGroup α) α by apply IsPreprimitive.isTrivialBlock_of_isBlock hB apply isPreprimitive_of_is_two_pretransitive - letI := isMultiplyPretransitive α + let := isMultiplyPretransitive α apply isMultiplyPretransitive_of_le (n := Nat.card α - 2) _ (sub_le _ _) rwa [← add_le_add_iff_right 2, Nat.sub_add_cancel (le_of_lt h2)] diff --git a/Mathlib/GroupTheory/GroupAction/Primitive.lean b/Mathlib/GroupTheory/GroupAction/Primitive.lean index 9758266c463384..7d5ddb7cdaac33 100644 --- a/Mathlib/GroupTheory/GroupAction/Primitive.lean +++ b/Mathlib/GroupTheory/GroupAction/Primitive.lean @@ -216,7 +216,7 @@ theorem isPreprimitive_congr (hφ : Function.Surjective φ) (hf : Function.Bijec · intro _ apply IsPreprimitive.of_surjective hf.surjective · intro _ - haveI := (isPretransitive_congr hφ hf).mpr toIsPretransitive + have := (isPretransitive_congr hφ hf).mpr toIsPretransitive exact { isTrivialBlock_of_isBlock {B} hB := by rw [← Set.preimage_image_eq B hf.injective] diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index f8c36afe217b70..5ede368ffb7b41 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -912,7 +912,7 @@ theorem nilpotent_center_quotient_ind {P : ∀ (G) [Group G] [IsNilpotent G], Pr obtain ⟨n, h⟩ : ∃ n, Group.nilpotencyClass G = n := ⟨_, rfl⟩ induction n generalizing G with | zero => - haveI := nilpotencyClass_zero_iff_subsingleton.mp h + have := nilpotencyClass_zero_iff_subsingleton.mp h exact hbase _ | succ n ih => have hn : Group.nilpotencyClass (G ⧸ center G) = n := by @@ -1235,7 +1235,7 @@ theorem Group.isNilpotent_of_product_of_sylow_group let ps := (Nat.card G).primeFactors have : ∀ (p : ps) (P : Sylow p G), IsNilpotent (↑P : Subgroup G) := by intro p P - haveI : Fact (Nat.Prime ↑p) := Fact.mk <| Nat.prime_of_mem_primeFactors p.2 + have : Fact (Nat.Prime ↑p) := Fact.mk <| Nat.prime_of_mem_primeFactors p.2 exact P.isPGroup'.isNilpotent exact nilpotent_of_mulEquiv e diff --git a/Mathlib/GroupTheory/NoncommPiCoprod.lean b/Mathlib/GroupTheory/NoncommPiCoprod.lean index bf213e8c34802c..58eb9fa5e654e8 100644 --- a/Mathlib/GroupTheory/NoncommPiCoprod.lean +++ b/Mathlib/GroupTheory/NoncommPiCoprod.lean @@ -157,7 +157,7 @@ def noncommPiCoprodEquiv [DecidableEq ι] : @[to_additive] theorem noncommPiCoprod_mrange : MonoidHom.mrange (noncommPiCoprod ϕ hcomm) = ⨆ i : ι, MonoidHom.mrange (ϕ i) := by - letI := Classical.decEq ι + let := Classical.decEq ι apply le_antisymm · rintro x ⟨f, rfl⟩ refine Submonoid.noncommProd_mem _ _ _ (fun _ _ _ _ h => hcomm h _ _) (fun i _ => ?_) @@ -215,7 +215,7 @@ namespace MonoidHom theorem noncommPiCoprod_range [Fintype ι] {hcomm : Pairwise fun i j : ι => ∀ (x : H i) (y : H j), Commute (ϕ i x) (ϕ j y)} : (noncommPiCoprod ϕ hcomm).range = ⨆ i : ι, (ϕ i).range := by - letI := Classical.decEq ι + let := Classical.decEq ι apply le_antisymm · rintro x ⟨f, rfl⟩ refine Subgroup.noncommProd_mem _ (fun _ _ _ _ h => hcomm h _ _) ?_ @@ -250,7 +250,7 @@ theorem independent_range_of_coprime_order (hcoprime : Pairwise fun i j => Nat.Coprime (Fintype.card (H i)) (Fintype.card (H j))) : iSupIndep fun i => (ϕ i).range := by cases nonempty_fintype ι - letI := Classical.decEq ι + let := Classical.decEq ι rintro i rw [disjoint_iff_inf_le] rintro f ⟨hxi, hxp⟩ diff --git a/Mathlib/GroupTheory/Order/Min.lean b/Mathlib/GroupTheory/Order/Min.lean index b57ab12b6d13c1..1a01d16637880b 100644 --- a/Mathlib/GroupTheory/Order/Min.lean +++ b/Mathlib/GroupTheory/Order/Min.lean @@ -101,7 +101,7 @@ protected lemma minOrder {n : ℕ} (hn : n ≠ 0) (hn₁ : n ≠ 1) : minOrder ( le_minOrder_iff_forall_addSubgroup.2 fun s hs _ ↦ ?_ · rw [Nat.card_zmultiples, ZMod.addOrderOf_coe _ hn, gcd_eq_right (div_dvd_of_dvd n.minFac_dvd), Nat.div_div_self n.minFac_dvd hn] - · haveI : Nontrivial s := s.bot_or_nontrivial.resolve_left hs + · have : Nontrivial s := s.bot_or_nontrivial.resolve_left hs exact WithTop.coe_le_coe.2 <| minFac_le_of_dvd Finite.one_lt_card <| (card_addSubgroup_dvd_card _).trans n.card_zmod.dvd diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index b7ee3e5669e10e..1cfda9fa4845f1 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -1254,7 +1254,7 @@ lemma Nat.Coprime.pow_left_bijective {G} [Group G] (hn : (Nat.card G).Coprime n) theorem image_range_orderOf [DecidableEq G] : letI : Fintype (zpowers x) := (Subgroup.zpowers x).instFintypeSubtypeMemOfDecidablePred Finset.image (fun i => x ^ i) (Finset.range (orderOf x)) = (zpowers x : Set G).toFinset := by - letI : Fintype (zpowers x) := (Subgroup.zpowers x).instFintypeSubtypeMemOfDecidablePred + let : Fintype (zpowers x) := (Subgroup.zpowers x).instFintypeSubtypeMemOfDecidablePred ext x rw [Set.mem_toFinset, SetLike.mem_coe, mem_zpowers_iff_mem_range_orderOf] diff --git a/Mathlib/GroupTheory/PGroup.lean b/Mathlib/GroupTheory/PGroup.lean index dc5803d822673a..11d41f6cb5dcc7 100644 --- a/Mathlib/GroupTheory/PGroup.lean +++ b/Mathlib/GroupTheory/PGroup.lean @@ -57,7 +57,7 @@ theorem iff_card [Fact p.Prime] [Finite G] : IsPGroup p G ↔ ∃ n : ℕ, Nat.c rw [← List.prod_replicate, ← List.eq_replicate_of_mem this, Nat.prod_primeFactorsList hG] intro q hq obtain ⟨hq1, hq2⟩ := (Nat.mem_primeFactorsList hG).mp hq - haveI : Fact q.Prime := ⟨hq1⟩ + have : Fact q.Prime := ⟨hq1⟩ obtain ⟨g, hg⟩ := exists_prime_orderOf_dvd_card' q hq2 obtain ⟨k, hk⟩ := (iff_orderOf.mp h) g exact (hq1.pow_eq_iff.mp (hg.symm.trans hk).symm).1.symm @@ -152,8 +152,8 @@ variable {α : Type*} [MulAction G α] theorem card_orbit (a : α) [Finite (orbit G a)] : ∃ n : ℕ, Nat.card (orbit G a) = p ^ n := by let ϕ := orbitEquivQuotientStabilizer G a - haveI := Finite.of_equiv (orbit G a) ϕ - haveI := (stabilizer G a).finiteIndex_of_finite_quotient + have := Finite.of_equiv (orbit G a) ϕ + have := (stabilizer G a).finiteIndex_of_finite_quotient rw [Nat.card_congr ϕ] exact hG.index (stabilizer G a) @@ -230,7 +230,7 @@ theorem center_nontrivial [Nontrivial G] [Finite G] : Nontrivial (Subgroup.cente exact ⟨⟨1, ⟨g, hg.1⟩, mt Subtype.ext_iff.mp hg.2⟩⟩ theorem bot_lt_center [Nontrivial G] [Finite G] : ⊥ < Subgroup.center G := by - haveI := center_nontrivial hG + have := center_nontrivial hG classical exact bot_lt_iff_ne_bot.mpr ((Subgroup.center G).one_lt_card_iff_ne_bot.mp Finite.one_lt_card) @@ -358,7 +358,7 @@ theorem card_center_eq_prime_pow (hGpn : Nat.card G = p ^ n) (hn : 0 < n) : have : Finite G := Nat.finite_of_card_ne_zero (hGpn ▸ pow_ne_zero n (NeZero.ne p)) have hcG := to_subgroup (of_card hGpn) (center G) rcases iff_card.1 hcG with _ - haveI : Nontrivial G := (nontrivial_iff_card <| of_card hGpn).2 ⟨n, hn, hGpn⟩ + have : Nontrivial G := (nontrivial_iff_card <| of_card hGpn).2 ⟨n, hn, hGpn⟩ exact (nontrivial_iff_card hcG).mp (center_nontrivial (of_card hGpn)) /-- The quotient by the center of a group of cardinality `p ^ 2` is cyclic. -/ diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index 4b876072012319..98e68a7c38bdb5 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -734,7 +734,7 @@ theorem IsCycleOn.isCycle_subtypePerm (hf : f.IsCycleOn s) (hs : s.Nontrivial) : protected theorem IsCycleOn.subtypePerm (hf : f.IsCycleOn s) : (f.subtypePerm fun _ => hf.apply_mem_iff : Perm s).IsCycleOn _root_.Set.univ := by obtain hs | hs := s.subsingleton_or_nontrivial - · haveI := hs.coe_sort + · have := hs.coe_sort exact isCycleOn_of_subsingleton _ _ convert! (hf.isCycle_subtypePerm hs).isCycleOn rw [eq_comm, Set.eq_univ_iff_forall] @@ -872,8 +872,8 @@ theorem Countable.exists_cycleOn (hs : s.Countable) : simpa using List.mem_of_formPerm_apply_ne hx⟩ convert! hs'.toFinset.nodup_toList.isCycleOn_formPerm simp - · haveI := hs.to_subtype - haveI := hs'.to_subtype + · have := hs.to_subtype + have := hs'.to_subtype obtain ⟨f⟩ : Nonempty (ℤ ≃ s) := inferInstance refine ⟨(Equiv.addRight 1).extendDomain f, ?_, fun x hx => of_not_not fun h => hx <| Perm.extendDomain_apply_not_subtype _ _ h⟩ diff --git a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean index 7d9885f7fbb800..e344b1014b5d2e 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean @@ -252,7 +252,7 @@ instance instDecidableRelSameCycle [DecidableEq α] [Fintype α] (f : Perm α) : rcases hxy.exists_pow_eq_of_mem_support_aux hx with ⟨i, hixy, hi⟩ refine ⟨i, lt_of_lt_of_le hixy (card_le_univ _), hi⟩ case neg => - haveI : Nonempty α := ⟨x⟩ + have : Nonempty α := ⟨x⟩ rw [notMem_support] at hx exact ⟨0, Fintype.card_pos, hxy.eq_of_left hx⟩ diff --git a/Mathlib/GroupTheory/Perm/Cycle/Type.lean b/Mathlib/GroupTheory/Perm/Cycle/Type.lean index 598fc03b84d568..a86e7903c97fe1 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Type.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Type.lean @@ -549,7 +549,7 @@ end Cauchy theorem subgroup_eq_top_of_swap_mem [DecidableEq α] {H : Subgroup (Perm α)} [d : DecidablePred (· ∈ H)] {τ : Perm α} (h0 : (Fintype.card α).Prime) (h1 : Fintype.card α ∣ Fintype.card H) (h2 : τ ∈ H) (h3 : IsSwap τ) : H = ⊤ := by - haveI : Fact (Fintype.card α).Prime := ⟨h0⟩ + have : Fact (Fintype.card α).Prime := ⟨h0⟩ obtain ⟨σ, hσ⟩ := exists_prime_orderOf_dvd_card (Fintype.card α) h1 have hσ1 : orderOf (σ : Perm α) = Fintype.card α := (Subgroup.orderOf_coe σ).trans hσ have hσ2 : IsCycle ↑σ := isCycle_of_prime_order'' h0 hσ1 diff --git a/Mathlib/GroupTheory/PushoutI.lean b/Mathlib/GroupTheory/PushoutI.lean index 64677d3c0e3f85..4ad57f1eb9e609 100644 --- a/Mathlib/GroupTheory/PushoutI.lean +++ b/Mathlib/GroupTheory/PushoutI.lean @@ -561,8 +561,8 @@ noncomputable def equiv : PushoutI φ ≃ NormalWord d := theorem prod_injective {ι : Type*} {G : ι → Type*} [(i : ι) → Group (G i)] {φ : (i : ι) → H →* G i} {d : Transversal φ} : Function.Injective (prod : NormalWord d → PushoutI φ) := by - letI := Classical.decEq ι - letI := fun i => Classical.decEq (G i) + let := Classical.decEq ι + let := fun i => Classical.decEq (G i) classical exact equiv.symm.injective instance : FaithfulSMul (PushoutI φ) (NormalWord d) := diff --git a/Mathlib/GroupTheory/Rank.lean b/Mathlib/GroupTheory/Rank.lean index bc8ff00d160dbc..7445f03c685340 100644 --- a/Mathlib/GroupTheory/Rank.lean +++ b/Mathlib/GroupTheory/Rank.lean @@ -102,7 +102,7 @@ lemma rank_closure_finset_le_card (s : Finset G) : rank (closure (s : Set G)) @[to_additive] lemma rank_closure_finite_le_nat_card (s : Set G) [Finite s] : rank (closure s) ≤ Nat.card s := by - haveI := Fintype.ofFinite s + have := Fintype.ofFinite s rw [Nat.card_eq_fintype_card, ← s.toFinset_card, ← rank_congr (congr_arg _ s.coe_toFinset)] exact rank_closure_finset_le_card s.toFinset diff --git a/Mathlib/GroupTheory/Schreier.lean b/Mathlib/GroupTheory/Schreier.lean index 301f28f1521dc7..74f3a54f2259d7 100644 --- a/Mathlib/GroupTheory/Schreier.lean +++ b/Mathlib/GroupTheory/Schreier.lean @@ -141,10 +141,10 @@ variable (H) @[to_additive] theorem exists_finset_card_le_mul [FiniteIndex H] {S : Finset G} (hS : closure (S : Set G) = ⊤) : ∃ T : Finset H, #T ≤ H.index * #S ∧ closure (T : Set H) = ⊤ := by - letI := H.fintypeQuotientOfFiniteIndex - haveI : DecidableEq G := Classical.decEq G + let := H.fintypeQuotientOfFiniteIndex + have : DecidableEq G := Classical.decEq G obtain ⟨R₀, hR, hR1⟩ := H.exists_isComplement_right 1 - haveI : Fintype R₀ := Fintype.ofEquiv _ hR.rightQuotientEquiv + have : Fintype R₀ := Fintype.ofEquiv _ hR.rightQuotientEquiv let R : Finset G := Set.toFinset R₀ replace hR : IsComplement (H : Set G) R := by rwa [Set.coe_toFinset] replace hR1 : (1 : G) ∈ R := by rwa [Set.mem_toFinset] @@ -170,7 +170,7 @@ instance fg_of_index_ne_zero [hG : Group.FG G] [FiniteIndex H] : Group.FG H := b theorem rank_le_index_mul_rank [hG : Group.FG G] [FiniteIndex H] : Group.rank H ≤ H.index * Group.rank G := by - haveI := H.fg_of_index_ne_zero + have := H.fg_of_index_ne_zero obtain ⟨S, hS₀, hS⟩ := Group.rank_spec G obtain ⟨T, hT₀, hT⟩ := exists_finset_card_le_mul H hS calc @@ -189,7 +189,7 @@ theorem card_commutator_dvd_index_center_pow [Finite (commutatorSet G)] : -- First handle the case when `Z(G)` has infinite index and `[G : Z(G)]` is defined to be `0` by_cases hG : (center G).index = 0 · simp_rw [hG, zero_mul, zero_add, pow_one, dvd_zero] - haveI : FiniteIndex (center G) := ⟨hG⟩ + have : FiniteIndex (center G) := ⟨hG⟩ -- Rewrite as `|Z(G) ∩ G'| * [G' : Z(G) ∩ G'] ∣ [G : Z(G)] ^ ([G : Z(G)] * n) * [G : Z(G)]` rw [← ((center G).subgroupOf (_root_.commutator G)).card_mul_index, pow_succ] -- We have `h1 : [G' : Z(G) ∩ G'] ∣ [G : Z(G)]` @@ -197,7 +197,7 @@ theorem card_commutator_dvd_index_center_pow [Finite (commutatorSet G)] : -- So we can reduce to proving `|Z(G) ∩ G'| ∣ [G : Z(G)] ^ ([G : Z(G)] * n)` refine mul_dvd_mul ?_ h1 -- We know that `[G' : Z(G) ∩ G'] < ∞` by `h1` and `hG` - haveI : FiniteIndex ((center G).subgroupOf (_root_.commutator G)) := + have : FiniteIndex ((center G).subgroupOf (_root_.commutator G)) := ⟨ne_zero_of_dvd_ne_zero hG h1⟩ -- We have `h2 : rank (Z(G) ∩ G') ≤ [G' : Z(G) ∩ G'] * rank G'` by Schreier's lemma have h2 := rank_le_index_mul_rank ((center G).subgroupOf (_root_.commutator G)) diff --git a/Mathlib/GroupTheory/SchurZassenhaus.lean b/Mathlib/GroupTheory/SchurZassenhaus.lean index a65caa3d9f5101..0052fbe5e7ca20 100644 --- a/Mathlib/GroupTheory/SchurZassenhaus.lean +++ b/Mathlib/GroupTheory/SchurZassenhaus.lean @@ -49,7 +49,7 @@ theorem smul_diff_smul' [hH : Normal H] (g : Gᵐᵒᵖ) : diff (MonoidHom.id H) (g • α) (g • β) = ⟨g.unop⁻¹ * (diff (MonoidHom.id H) α β : H) * g.unop, hH.mem_comm ((congr_arg (· ∈ H) (mul_inv_cancel_left _ _)).mpr (SetLike.coe_mem _))⟩ := by - letI := H.fintypeQuotientOfFiniteIndex + let := H.fintypeQuotientOfFiniteIndex let ϕ : H →* H := { toFun := fun h => ⟨g.unop⁻¹ * h * g.unop, @@ -80,7 +80,7 @@ noncomputable instance : MulAction G H.QuotientDiff where theorem smul_diff' (h : H) : diff (MonoidHom.id H) α (op (h : G) • β) = diff (MonoidHom.id H) α β * h ^ H.index := by - letI := H.fintypeQuotientOfFiniteIndex + let := H.fintypeQuotientOfFiniteIndex rw [diff, diff, index_eq_card, Nat.card_eq_fintype_card, ← Finset.card_univ, ← Finset.prod_const, ← Finset.prod_mul_distrib] refine Finset.prod_congr rfl fun q _ => ?_ @@ -231,25 +231,25 @@ private theorem step4 : (Nat.card N).minFac.Prime := /-- Do not use this lemma: It is made obsolete by `exists_right_complement'_of_coprime` -/ private theorem step5 {P : Sylow (Nat.card N).minFac N} : P.1 ≠ ⊥ := by - haveI : Fact (Nat.card N).minFac.Prime := ⟨step4 h1 h3⟩ + have : Fact (Nat.card N).minFac.Prime := ⟨step4 h1 h3⟩ apply P.ne_bot_of_dvd_card exact (Nat.card N).minFac_dvd include h2 in /-- Do not use this lemma: It is made obsolete by `exists_right_complement'_of_coprime` -/ private theorem step6 : IsPGroup (Nat.card N).minFac N := by - haveI : Fact (Nat.card N).minFac.Prime := ⟨step4 h1 h3⟩ + have : Fact (Nat.card N).minFac.Prime := ⟨step4 h1 h3⟩ refine Sylow.nonempty.elim fun P => P.2.of_surjective P.1.subtype ?_ rw [← MonoidHom.range_eq_top, range_subtype] - haveI : (P.1.map N.subtype).Normal := + have : (P.1.map N.subtype).Normal := normalizer_eq_top_iff.mp (step1 h1 h2 h3 _ P.normalizer_sup_eq_top) exact (step3 h1 h2 h3 P.1).resolve_left (step5 h1 h3) include h2 in /-- Do not use this lemma: It is made obsolete by `exists_right_complement'_of_coprime` -/ theorem step7 : IsMulCommutative N := by - haveI := N.bot_or_nontrivial.resolve_left (step0 h1 h3) - haveI : Fact (Nat.card N).minFac.Prime := ⟨step4 h1 h3⟩ + have := N.bot_or_nontrivial.resolve_left (step0 h1 h3) + have : Fact (Nat.card N).minFac.Prime := ⟨step4 h1 h3⟩ exact ⟨⟨fun g h => ((eq_top_iff.mp ((step3 h1 h2 h3 (center N)).resolve_left (step6 h1 h2 h3).bot_lt_center.ne') (mem_top h)).comm g).symm⟩⟩ @@ -266,7 +266,7 @@ private theorem exists_right_complement'_of_coprime_aux' [Finite G] (hG : Nat.ca induction n using Nat.strongRecOn with | ind n ih => ?_ rintro G _ _ rfl N _ hN refine not_forall_not.mp fun h3 => ?_ - haveI := SchurZassenhausInduction.step7 hN (fun G' _ _ hG' => by apply ih _ hG'; rfl) h3 + have := SchurZassenhausInduction.step7 hN (fun G' _ _ hG' => by apply ih _ hG'; rfl) h3 exact not_exists_of_forall_not h3 (exists_right_complement'_of_coprime_aux hN) /-- **Schur-Zassenhaus** for normal subgroups: diff --git a/Mathlib/GroupTheory/Solvable.lean b/Mathlib/GroupTheory/Solvable.lean index 9ec89956631467..81ef26cc5c3af8 100644 --- a/Mathlib/GroupTheory/Solvable.lean +++ b/Mathlib/GroupTheory/Solvable.lean @@ -113,7 +113,7 @@ instance (priority := 100) CommGroup.isSolvable {G : Type*} [CommGroup G] : IsSo theorem isSolvable_of_comm {G : Type*} [hG : Group G] (h : ∀ a b : G, a * b = b * a) : IsSolvable G := by - letI hG' : CommGroup G := { hG with mul_comm := h } + let hG' : CommGroup G := { hG with mul_comm := h } cases hG exact CommGroup.isSolvable diff --git a/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean b/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean index 8fb79b38b4cf4a..594a581ab4086b 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Quaternion.lean @@ -203,7 +203,7 @@ theorem xa_pow_four (i : ZMod (2 * n)) : xa i ^ 4 = 1 := by @[simp] theorem orderOf_xa [NeZero n] (i : ZMod (2 * n)) : orderOf (xa i) = 4 := by change _ = 2 ^ 2 - haveI : Fact (Nat.Prime 2) := Fact.mk Nat.prime_two + have : Fact (Nat.Prime 2) := Fact.mk Nat.prime_two apply orderOf_eq_prime_pow · intro h simp only [pow_one, xa_sq] at h @@ -229,7 +229,7 @@ theorem orderOf_a_one : orderOf (a 1 : QuaternionGroup n) = 2 * n := by intro n h rw [one_def, a_one_pow] apply mt a.inj - haveI : CharZero (ZMod (2 * 0)) := ZMod.charZero + have : CharZero (ZMod (2 * 0)) := ZMod.charZero simpa using h.ne' apply (Nat.le_of_dvd (NeZero.pos _) (orderOf_dvd_of_pow_eq_one (@a_one_pow_n n))).lt_or_eq.resolve_left diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index 89411ada9907f4..cbbde606ac6498 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -452,9 +452,9 @@ private theorem not_dvd_index_aux [hp : Fact p.Prime] (P : Sylow p G) [P.Normal] theorem not_dvd_index' [hp : Fact p.Prime] [Finite (Sylow p G)] (P : Sylow p G) (hP : P.relIndex (normalizer P) ≠ 0) : ¬ p ∣ P.index := by rw [← relIndex_mul_index le_normalizer, P.coe_coe, ← card_eq_index_normalizer] - haveI : (P.subtype le_normalizer).Normal := + have : (P.subtype le_normalizer).Normal := Subgroup.normal_in_normalizer - haveI : (P.subtype le_normalizer).FiniteIndex := ⟨hP⟩ + have : (P.subtype le_normalizer).FiniteIndex := ⟨hP⟩ replace hP := not_dvd_index_aux (P.subtype le_normalizer) exact hp.1.not_dvd_mul hP (not_dvd_card_sylow p G) @@ -796,7 +796,7 @@ theorem normal_of_all_max_subgroups_normal [Finite G] rcases eq_top_or_exists_le_coatom (normalizer (P : Set G)) with (heq | ⟨K, hK, hNK⟩) · exact heq - · haveI := hnc _ hK + · have := hnc _ hK have hPK : P ≤ K := le_trans le_normalizer hNK refine (hK.1 ?_).elim rw [← sup_of_le_right hNK, P.normalizer_sup_eq_top' hPK]) @@ -819,8 +819,8 @@ noncomputable def directProductOfNormal [Finite G] have : ∀ p, Fintype (P p) := fun p ↦ Fintype.ofFinite (P p) have hcomm : Pairwise fun p₁ p₂ : ps => ∀ x y : G, x ∈ P p₁ → y ∈ P p₂ → Commute x y := by rintro ⟨p₁, hp₁⟩ ⟨p₂, hp₂⟩ hne - haveI hp₁' := Fact.mk (Nat.prime_of_mem_primeFactors hp₁) - haveI hp₂' := Fact.mk (Nat.prime_of_mem_primeFactors hp₂) + have hp₁' := Fact.mk (Nat.prime_of_mem_primeFactors hp₁) + have hp₂' := Fact.mk (Nat.prime_of_mem_primeFactors hp₂) have hne' : p₁ ≠ p₂ := by simpa using hne apply Subgroup.commute_of_normal_of_disjoint _ _ (hn (P p₁)) (hn (P p₂)) apply IsPGroup.disjoint_of_ne p₁ p₂ hne' _ _ (P p₁).isPGroup' (P p₂).isPGroup' @@ -838,8 +838,8 @@ noncomputable def directProductOfNormal [Finite G] · apply Subgroup.injective_noncommPiCoprod_of_iSupIndep apply independent_of_coprime_order hcomm rintro ⟨p₁, hp₁⟩ ⟨p₂, hp₂⟩ hne - haveI hp₁' := Fact.mk (Nat.prime_of_mem_primeFactors hp₁) - haveI hp₂' := Fact.mk (Nat.prime_of_mem_primeFactors hp₂) + have hp₁' := Fact.mk (Nat.prime_of_mem_primeFactors hp₁) + have hp₂' := Fact.mk (Nat.prime_of_mem_primeFactors hp₂) have hne' : p₁ ≠ p₂ := by simpa using hne simp only [← Nat.card_eq_fintype_card] apply IsPGroup.coprime_card_of_ne p₁ p₂ hne' _ _ (P p₁).isPGroup' (P p₂).isPGroup' diff --git a/Mathlib/GroupTheory/Transfer.lean b/Mathlib/GroupTheory/Transfer.lean index 1c16a59aae9e89..17c0205663b2a4 100644 --- a/Mathlib/GroupTheory/Transfer.lean +++ b/Mathlib/GroupTheory/Transfer.lean @@ -166,7 +166,7 @@ theorem transfer_eq_prod_quotient_orbitRel_zpowers_quot [FiniteIndex H] (g : G) ⟨q.out.out⁻¹ * g ^ Function.minimalPeriod (g • ·) q.out * q.out.out, QuotientGroup.out_conj_pow_minimalPeriod_mem H g q.out⟩ := by classical - letI := H.fintypeQuotientOfFiniteIndex + let := H.fintypeQuotientOfFiniteIndex calc transfer ϕ g = ∏ q : G ⧸ H, _ := transfer_def ϕ (transferTransversal H g) g _ = _ := ((quotientEquivSigmaZMod H g).symm.prod_comp _).symm @@ -189,7 +189,7 @@ theorem transfer_eq_pow_aux (g : G) by_cases hH : H.index = 0 · rw [hH, pow_zero] exact H.one_mem - letI := fintypeOfIndexNeZero hH + let := fintypeOfIndexNeZero hH classical replace key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g ^ k ∈ H := fun k g₀ hk => (congr_arg (· ∈ H) (key k g₀ hk)).mp hk @@ -208,7 +208,7 @@ theorem transfer_eq_pow [FiniteIndex H] (g : G) (key : ∀ (k : ℕ) (g₀ : G), g₀⁻¹ * g ^ k * g₀ ∈ H → g₀⁻¹ * g ^ k * g₀ = g ^ k) : transfer ϕ g = ϕ ⟨g ^ H.index, transfer_eq_pow_aux g key⟩ := by classical - letI := H.fintypeQuotientOfFiniteIndex + let := H.fintypeQuotientOfFiniteIndex change ∀ (k g₀) (hk : g₀⁻¹ * g ^ k * g₀ ∈ H), ↑(⟨g₀⁻¹ * g ^ k * g₀, hk⟩ : H) = g ^ k at key rw [transfer_eq_prod_quotient_orbitRel_zpowers_quot, ← Finset.prod_map_toList, ← Function.comp_def ϕ, List.prod_map_hom] @@ -255,7 +255,7 @@ variable [Fact p.Prime] [Finite (Sylow p G)] /-- Auxiliary lemma in order to state `transferSylow_eq_pow`. -/ theorem transferSylow_eq_pow_aux (g : G) (hg : g ∈ P) (k : ℕ) (g₀ : G) (h : g₀⁻¹ * g ^ k * g₀ ∈ P) : g₀⁻¹ * g ^ k * g₀ = g ^ k := by - haveI : IsMulCommutative P := + have : IsMulCommutative P := ⟨⟨fun a b => Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩ replace hg := P.pow_mem hg k obtain ⟨n, hn, h⟩ := P.conj_eq_normalizer_conj_of_mem (g ^ k) g₀ hg h diff --git a/Mathlib/LinearAlgebra/AffineSpace/Basis.lean b/Mathlib/LinearAlgebra/AffineSpace/Basis.lean index ed2d0296154c9f..f7e58ce586ba0a 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Basis.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Basis.lean @@ -253,7 +253,7 @@ theorem coe_coord_of_subsingleton_eq_one [Subsingleton ι] (i : ι) : (b.coord i rw [← image_univ] apply Subsingleton.image apply subsingleton_of_subsingleton - haveI := AffineSubspace.subsingleton_of_subsingleton_span_eq_top hp b.tot + have := AffineSubspace.subsingleton_of_subsingleton_span_eq_top hp b.tot let s : Finset ι := {i} have hi : i ∈ s := by simp [s] have hw : s.sum (Function.const ι (1 : k)) = 1 := by simp [s] diff --git a/Mathlib/LinearAlgebra/AffineSpace/FiniteDimensional.lean b/Mathlib/LinearAlgebra/AffineSpace/FiniteDimensional.lean index 5890ae57f58b85..5f3694065a14ba 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/FiniteDimensional.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/FiniteDimensional.lean @@ -96,7 +96,7 @@ theorem finite_of_fin_dim_affineIndependent [FiniteDimensional k V] {p : ι → (hi : AffineIndependent k p) : Finite ι := by nontriviality ι; inhabit ι rw [affineIndependent_iff_linearIndependent_vsub k p default] at hi - letI : IsNoetherian k V := IsNoetherian.iff_fg.2 inferInstance + let : IsNoetherian k V := IsNoetherian.iff_fg.2 inferInstance exact (Set.finite_singleton default).finite_of_compl (Set.finite_coe_iff.1 hi.finite_of_isNoetherian) @@ -383,7 +383,7 @@ variable (k) finite-dimensional. -/ instance finiteDimensional_vectorSpan_insert_set (s : Set P) [FiniteDimensional k (vectorSpan k s)] (p : P) : FiniteDimensional k (vectorSpan k (insert p s)) := by - haveI : FiniteDimensional k (affineSpan k s).direction := + have : FiniteDimensional k (affineSpan k s).direction := (direction_affineSpan k s).symm ▸ inferInstance rw [← direction_affineSpan, ← affineSpan_insert_affineSpan, direction_affineSpan] exact finiteDimensional_vectorSpan_insert (affineSpan k s) p @@ -393,7 +393,7 @@ direction of the `affineSpan` is finite-dimensional. -/ instance finiteDimensional_direction_affineSpan_insert_set (s : Set P) [FiniteDimensional k (affineSpan k s).direction] (p : P) : FiniteDimensional k (affineSpan k (insert p s)).direction := by - haveI : FiniteDimensional k (vectorSpan k s) := (direction_affineSpan k s) ▸ inferInstance + have : FiniteDimensional k (vectorSpan k s) := (direction_affineSpan k s) ▸ inferInstance rw [direction_affineSpan] infer_instance diff --git a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean index 77f39139c1b99f..91d9230991f1a2 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean @@ -797,7 +797,7 @@ theorem affineIndependent_of_ne {p₁ p₂ : P} (h : p₁ ≠ p₂) : AffineInde fin_cases i · simp at hi · simp [i₁] - haveI : Unique { x // x ≠ (0 : Fin 2) } := ⟨⟨i₁⟩, he'⟩ + have : Unique { x // x ≠ (0 : Fin 2) } := ⟨⟨i₁⟩, he'⟩ refine .of_subsingleton default ?_ rw [he' default] simpa using! h.symm diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean index 734b662a501c96..6e2715dc6104ca 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean @@ -350,7 +350,7 @@ lemma face_restrict {n : ℕ} (s : Affine.Simplex k P n) {S : AffineSubspace k P (h : #fs = m + 1) : letI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).face h = (s.face h).restrict S ((s.affineSpan_face_le h).trans hS) := by - letI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + let := Nonempty.map (AffineSubspace.inclusion hS) inferInstance ext i rw [restrict_points_coe] simp_rw [Affine.Simplex.face_points] @@ -441,7 +441,7 @@ lemma setInterior_restrict (I : Set k) {n : ℕ} (s : Simplex k P n) {S : Affine (hS : affineSpan k (Set.range s.points) ≤ S) : letI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).setInterior I = S.subtype ⁻¹' (s.setInterior I) := by - letI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + let := Nonempty.map (AffineSubspace.inclusion hS) inferInstance rw [← S.subtype_injective.image_injective.eq_iff, Set.image_preimage_eq_of_subset (s.setInterior_subset_affineSpan.trans (by simpa using! hS)), ← (s.restrict S hS).setInterior_map I S.subtype_injective] diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Centroid.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Centroid.lean index 2856c6aba0432c..73172cf4a5215f 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Centroid.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Centroid.lean @@ -220,7 +220,7 @@ theorem centroid_restrict [CharZero k] {n : ℕ} (s : Simplex k P n) (S : Affine haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).centroid = s.centroid := by rw [eq_comm] - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance have hf : Function.Injective (S.subtype) := by simp only [coe_subtype, Subtype.val_injective] exact (s.restrict S hS).centroid_map S.subtype hf @@ -403,7 +403,7 @@ theorem faceOppositeCentroid_eq_smul_vsub_vadd_point [CharZero k] (s : Simplex k haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).faceOppositeCentroid i = s.faceOppositeCentroid i := by rw [eq_comm] - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance have hf : Function.Injective (S.subtype) := by simp only [coe_subtype, Subtype.val_injective] exact (s.restrict S hS).faceOppositeCentroid_map S.subtype hf (i := i) @@ -585,7 +585,7 @@ theorem medial_restrict [CharZero k] (s : Simplex k P n) (S : AffineSubspace k P (hS : affineSpan k (Set.range s.points) ≤ S) : haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).medial = s.medial.restrict S (s.affineSpan_range_medial ▸ hS) := by - haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance + have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance ext i simp [medial_points] diff --git a/Mathlib/LinearAlgebra/Alternating/Basic.lean b/Mathlib/LinearAlgebra/Alternating/Basic.lean index fde00ab331897f..fb400ee7e58883 100644 --- a/Mathlib/LinearAlgebra/Alternating/Basic.lean +++ b/Mathlib/LinearAlgebra/Alternating/Basic.lean @@ -785,7 +785,7 @@ theorem map_linearDependent {K M N : Type*} [Ring K] [IsDomain K] [AddCommGroup [AddCommGroup N] [Module K N] [IsTorsionFree K N] (f : M [⋀^ι]→ₗ[K] N) (v : ι → M) (h : ¬LinearIndependent K v) : f v = 0 := by obtain ⟨s, g, h, i, hi, hz⟩ := not_linearIndependent_iff.mp h - letI := Classical.decEq ι + let := Classical.decEq ι suffices f (update v i (g i • v i)) = 0 by rw [f.map_update_smul, Function.update_eq_self, smul_eq_zero] at this exact Or.resolve_left this hz diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index 8926b75a69fe96..a98476d639a01b 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -247,7 +247,7 @@ theorem LinearMap.exists_leftInverse_of_injective (f : V →ₗ[K] V') (hf_inj : let C := this.extend (subset_univ _) have BC := this.subset_extend (subset_univ _) let hC := Basis.extend this - haveI Vinh : Inhabited V := ⟨0⟩ + have Vinh : Inhabited V := ⟨0⟩ refine ⟨(hC.constr ℕ : _ → _) (C.restrict (invFun f)), hB.ext fun b => ?_⟩ rw [image_subset_iff] at BC have fb_eq : f b = hC ⟨f b, BC b.2⟩ := by diff --git a/Mathlib/LinearAlgebra/BilinearForm/DualLattice.lean b/Mathlib/LinearAlgebra/BilinearForm/DualLattice.lean index 628935e785ca77..efc81f12a41770 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/DualLattice.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/DualLattice.lean @@ -119,7 +119,7 @@ lemma dualSubmodule_dualSubmodule_flip_of_basis {ι : Type*} [Finite ι] B.dualSubmodule (B.flip.dualSubmodule (Submodule.span R (Set.range b))) = Submodule.span R (Set.range b) := by classical - letI := b.finiteDimensional_of_finite + let := b.finiteDimensional_of_finite rw [dualSubmodule_span_of_basis _ hB.flip, dualSubmodule_span_of_basis B hB, dualBasis_dualBasis_flip hB] @@ -128,7 +128,7 @@ lemma dualSubmodule_flip_dualSubmodule_of_basis {ι : Type*} [Finite ι] B.flip.dualSubmodule (B.dualSubmodule (Submodule.span R (Set.range b))) = Submodule.span R (Set.range b) := by classical - letI := b.finiteDimensional_of_finite + let := b.finiteDimensional_of_finite rw [dualSubmodule_span_of_basis B hB, dualSubmodule_span_of_basis _ hB.flip, dualBasis_flip_dualBasis hB] @@ -137,7 +137,7 @@ lemma dualSubmodule_dualSubmodule_of_basis B.dualSubmodule (B.dualSubmodule (Submodule.span R (Set.range b))) = Submodule.span R (Set.range b) := by classical - letI := b.finiteDimensional_of_finite + let := b.finiteDimensional_of_finite rw [dualSubmodule_span_of_basis B hB, dualSubmodule_span_of_basis B hB, dualBasis_dualBasis hB hB'] diff --git a/Mathlib/LinearAlgebra/Charpoly/Basic.lean b/Mathlib/LinearAlgebra/Charpoly/Basic.lean index c3e7afb498ccc3..bd9cfef2154e36 100644 --- a/Mathlib/LinearAlgebra/Charpoly/Basic.lean +++ b/Mathlib/LinearAlgebra/Charpoly/Basic.lean @@ -75,7 +75,7 @@ theorem charpoly_monic : f.charpoly.Monic := open Module in lemma charpoly_natDegree [StrongRankCondition R] : natDegree (charpoly f) = finrank R M := by - haveI := nontrivial_of_invariantBasisNumber + have := nontrivial_of_invariantBasisNumber rw [charpoly, Matrix.charpoly_natDegree_eq_dim, finrank_eq_card_chooseBasisIndex] end Coeff diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/BaseChange.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/BaseChange.lean index 90023cafd4e138..49a9a2c7b20935 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/BaseChange.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/BaseChange.lean @@ -85,8 +85,8 @@ def toBaseChange (Q : QuadraticForm R V) : CliffordAlgebra (Q.baseChange A) →ₐ[A] A ⊗[R] CliffordAlgebra Q := CliffordAlgebra.lift _ <| by refine ⟨TensorProduct.AlgebraTensorModule.map (LinearMap.id : A →ₗ[A] A) (ι Q), ?_⟩ - letI : Invertible (2 : A) := (Invertible.map (algebraMap R A) 2).copy 2 (map_ofNat _ _).symm - letI : Invertible (2 : A ⊗[R] CliffordAlgebra Q) := + let : Invertible (2 : A) := (Invertible.map (algebraMap R A) 2).copy 2 (map_ofNat _ _).symm + let : Invertible (2 : A ⊗[R] CliffordAlgebra Q) := (Invertible.map (algebraMap R _) 2).copy 2 (map_ofNat _ _).symm suffices hpure_tensor : ∀ v w, (1 * 1) ⊗ₜ[R] (ι Q v * ι Q w) + (1 * 1) ⊗ₜ[R] (ι Q w * ι Q v) = QuadraticMap.polarBilin (Q.baseChange A) (1 ⊗ₜ[R] v) (1 ⊗ₜ[R] w) ⊗ₜ[R] 1 by diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean index c9dfc7c666d345..0dce58a81e591e 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean @@ -34,12 +34,12 @@ def invertibleιOfInvertible (m : M) [Invertible (Q m)] : Invertible (ι Q m) wh /-- For a vector with invertible quadratic form, $v^{-1} = \frac{v}{Q(v)}$ -/ theorem invOf_ι (m : M) [Invertible (Q m)] [Invertible (ι Q m)] : ⅟(ι Q m) = ι Q (⅟(Q m) • m) := by - letI := invertibleιOfInvertible Q m + let := invertibleιOfInvertible Q m convert! (rfl : ⅟(ι Q m) = _) theorem isUnit_ι_of_isUnit {m : M} (h : IsUnit (Q m)) : IsUnit (ι Q m) := by cases h.nonempty_invertible - letI := invertibleιOfInvertible Q m + let := invertibleιOfInvertible Q m exact isUnit_of_invertible (ι Q m) /-- $aba^{-1}$ is a vector. -/ @@ -66,7 +66,7 @@ def invertibleOfInvertibleι (m : M) [Invertible (ι Q m)] : Invertible (Q m) := theorem isUnit_of_isUnit_ι {m : M} (h : IsUnit (ι Q m)) : IsUnit (Q m) := by cases h.nonempty_invertible - letI := invertibleOfInvertibleι Q m + let := invertibleOfInvertibleι Q m exact isUnit_of_invertible (Q m) @[simp] theorem isUnit_ι_iff {m : M} : IsUnit (ι Q m) ↔ IsUnit (Q m) := diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean index ba083d909116e3..abfb945c6049b4 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean @@ -73,15 +73,15 @@ theorem conjAct_smul_ι_mem_range_ι {x : (CliffordAlgebra Q)ˣ} (hx : x ∈ lip induction hx using Subgroup.closure_induction'' generalizing m with | mem x hx => obtain ⟨a, ha⟩ := hx - letI := x.invertible - letI : Invertible (ι Q a) := by rwa [ha] - letI : Invertible (Q a) := invertibleOfInvertibleι Q a + let := x.invertible + let : Invertible (ι Q a) := by rwa [ha] + let : Invertible (Q a) := invertibleOfInvertibleι Q a simp_rw [← invOf_units x, ← ha, ι_mul_ι_mul_invOf_ι, LinearMap.mem_range_self] | inv_mem x hx => obtain ⟨a, ha⟩ := hx - letI := x.invertible - letI : Invertible (ι Q a) := by rwa [ha] - letI : Invertible (Q a) := invertibleOfInvertibleι Q a + let := x.invertible + let : Invertible (ι Q a) := by rwa [ha] + let : Invertible (Q a) := invertibleOfInvertibleι Q a simp_rw [← invOf_units x, inv_inv, ← ha, invOf_ι_mul_ι_mul_ι, LinearMap.mem_range_self] | one => simp_rw [inv_one, Units.val_one, one_mul, mul_one, LinearMap.mem_range_self] | mul y z _ _ hy hz => @@ -100,18 +100,18 @@ theorem involute_act_ι_mem_range_ι [Invertible (2 : R)] induction hx using Subgroup.closure_induction'' generalizing b with | mem x hx => obtain ⟨a, ha⟩ := hx - letI := x.invertible - letI : Invertible (ι Q a) := by rwa [ha] - letI : Invertible (Q a) := invertibleOfInvertibleι Q a + let := x.invertible + let : Invertible (ι Q a) := by rwa [ha] + let : Invertible (Q a) := invertibleOfInvertibleι Q a simp_rw [← invOf_units x, ← ha, involute_ι, neg_mul, ι_mul_ι_mul_invOf_ι Q a b, ← map_neg, LinearMap.mem_range_self] | inv_mem x hx => obtain ⟨a, ha⟩ := hx - letI := x.invertible - letI : Invertible (ι Q a) := by rwa [ha] - letI : Invertible (Q a) := invertibleOfInvertibleι Q a - letI := invertibleNeg (ι Q a) - letI := Invertible.map involute (ι Q a) + let := x.invertible + let : Invertible (ι Q a) := by rwa [ha] + let : Invertible (Q a) := invertibleOfInvertibleι Q a + let := invertibleNeg (ι Q a) + let := Invertible.map involute (ι Q a) simp_rw [← invOf_units x, inv_inv, ← ha, map_invOf, involute_ι, invOf_neg, neg_mul, invOf_ι_mul_ι_mul_ι, ← map_neg, LinearMap.mem_range_self] | one => simp_rw [inv_one, Units.val_one, map_one, one_mul, mul_one, LinearMap.mem_range_self] diff --git a/Mathlib/LinearAlgebra/Coevaluation.lean b/Mathlib/LinearAlgebra/Coevaluation.lean index c47b8e15479f78..74520c923036af 100644 --- a/Mathlib/LinearAlgebra/Coevaluation.lean +++ b/Mathlib/LinearAlgebra/Coevaluation.lean @@ -63,7 +63,7 @@ theorem contractLeft_assoc_coevaluation : (TensorProduct.assoc K _ _ _).symm.toLinearMap ∘ₗ (coevaluation K V).lTensor (Module.Dual K V) = (TensorProduct.lid K _).symm.toLinearMap ∘ₗ (TensorProduct.rid K _).toLinearMap := by - letI := Classical.decEq (Basis.ofVectorSpaceIndex K V) + let := Classical.decEq (Basis.ofVectorSpaceIndex K V) apply TensorProduct.ext apply (Basis.ofVectorSpace K V).dualBasis.ext; intro j; apply LinearMap.ext_ring rw [LinearMap.compr₂ₛₗ_apply, LinearMap.compr₂ₛₗ_apply, TensorProduct.mk_apply] @@ -81,7 +81,7 @@ theorem contractLeft_assoc_coevaluation' : (contractLeft K V).lTensor _ ∘ₗ (TensorProduct.assoc K _ _ _).toLinearMap ∘ₗ (coevaluation K V).rTensor V = (TensorProduct.rid K _).symm.toLinearMap ∘ₗ (TensorProduct.lid K _).toLinearMap := by - letI := Classical.decEq (Basis.ofVectorSpaceIndex K V) + let := Classical.decEq (Basis.ofVectorSpaceIndex K V) apply TensorProduct.ext apply LinearMap.ext_ring; apply (Basis.ofVectorSpace K V).ext; intro j rw [LinearMap.compr₂ₛₗ_apply, LinearMap.compr₂ₛₗ_apply, TensorProduct.mk_apply] diff --git a/Mathlib/LinearAlgebra/DFinsupp.lean b/Mathlib/LinearAlgebra/DFinsupp.lean index 2e04a2199f62fc..0b8fcbbf6a2712 100644 --- a/Mathlib/LinearAlgebra/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/DFinsupp.lean @@ -546,7 +546,7 @@ theorem iSupIndep.dfinsupp_lsum_injective {p : ι → Submodule R N} (h : iSupIn rw [iSupIndep_iff_forall_dfinsupp] at h suffices LinearMap.ker (lsum ℕ fun i => (p i).subtype) = ⊥ by -- Lean can't find this without our help - letI thisI : AddCommGroup (Π₀ i, p i) := inferInstance + let thisI : AddCommGroup (Π₀ i, p i) := inferInstance rw [LinearMap.ker_eq_bot] at this exact this rw [LinearMap.ker_eq_bot'] diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 8390d28ac03e97..41d5ba4cfd525a 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -211,7 +211,7 @@ theorem det_eq_det_toMatrix_of_finset [DecidableEq M] {s : Finset M} (b : Basis @[simp] theorem det_toMatrix (b : Basis ι A M) (f : M →ₗ[A] M) : Matrix.det (toMatrix b b f) = LinearMap.det f := by - haveI := Classical.decEq M + have := Classical.decEq M rw [det_eq_det_toMatrix_of_finset b.reindexFinsetRange, det_toMatrix_eq_det_toMatrix b b.reindexFinsetRange] @@ -267,7 +267,7 @@ theorem det_smul [Module.Free A M] (c : A) (f : M →ₗ[A] M) : theorem det_zero' {ι : Type*} [Finite ι] [Nonempty ι] (b : Basis ι A M) : LinearMap.det (0 : M →ₗ[A] M) = 0 := by - haveI := Classical.decEq ι + have := Classical.decEq ι cases nonempty_fintype ι rw [← det_toMatrix b, map_zero, det_zero] @@ -669,7 +669,7 @@ theorem AlternatingMap.map_basis_eq_zero_iff {ι : Type*} [Finite ι] (e : Basis (f : M [⋀^ι]→ₗ[R] R) : f e = 0 ↔ f = 0 := ⟨fun h => by cases nonempty_fintype ι - letI := Classical.decEq ι + let := Classical.decEq ι simpa [h] using f.eq_smul_basis_det e, fun h => h.symm ▸ AlternatingMap.zero_apply _⟩ diff --git a/Mathlib/LinearAlgebra/Dimension/ErdosKaplansky.lean b/Mathlib/LinearAlgebra/Dimension/ErdosKaplansky.lean index 0f9db109afca68..defc91af3f6d26 100644 --- a/Mathlib/LinearAlgebra/Dimension/ErdosKaplansky.lean +++ b/Mathlib/LinearAlgebra/Dimension/ErdosKaplansky.lean @@ -48,11 +48,11 @@ theorem max_aleph0_card_le_rank_fun_nat : max ℵ₀ #K ≤ Module.rank K (ℕ refine (Subfield.cardinalMk_closure_le_max _).trans_lt (max_lt_iff.mpr ⟨mk_range_le.trans_lt ?_, card_K⟩) rwa [mk_prod, ← aleph0, lift_uzero, bK.mk_eq_rank'', mul_aleph0_eq aleph0_le] - letI := Module.compHom K (RingHom.op L.subtype) + let := Module.compHom K (RingHom.op L.subtype) obtain ⟨⟨ιL, bL⟩⟩ := Module.Free.exists_basis (R := Lᵐᵒᵖ) (M := K) have card_ιL : ℵ₀ ≤ #ιL := by contrapose! hLK - haveI := @Fintype.ofFinite _ (lt_aleph0_iff_finite.mp hLK) + have := @Fintype.ofFinite _ (lt_aleph0_iff_finite.mp hLK) rw [bL.repr.toEquiv.cardinal_eq, mk_finsupp_of_fintype, ← MulOpposite.opEquiv.cardinal_eq] at card_K ⊢ apply power_nat_le @@ -92,7 +92,7 @@ theorem rank_fun_infinite {ι : Type v} [hι : Infinite ι] : Module.rank K (ι rw [lift_umax.{u, v}, lift_id'.{u, v}] at this have key := (lift_le.{v}.mpr <| max_aleph0_card_le_rank_fun_nat K).trans this rw [lift_max, lift_aleph0, max_le_iff] at key - haveI : Infinite ιK := by + have : Infinite ιK := by rw [← aleph0_le_mk_iff, bK.mk_eq_rank'']; exact key.1 rw [bK.repr.toEquiv.cardinal_eq, mk_finsupp_lift_of_infinite, lift_umax.{u, v}, lift_id'.{u, v}, bK.mk_eq_rank'', eq_comm, max_eq_left] diff --git a/Mathlib/LinearAlgebra/Dimension/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Finite.lean index 954e193f16af00..cd9d8d184ae78d 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finite.lean @@ -412,7 +412,7 @@ theorem Module.finrank_zero_iff [IsDomain R] [IsTorsionFree R M] : /-- Similar to `rank_quotient_add_rank_le` but for `finrank` and a finite `M`. -/ lemma Module.finrank_quotient_add_finrank_le (N : Submodule R M) : finrank R (M ⧸ N) + finrank R N ≤ finrank R M := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R have := rank_quotient_add_rank_le N rw [← finrank_eq_rank R M, ← finrank_eq_rank R, ← N.finrank_eq_rank] at this exact mod_cast this @@ -505,7 +505,7 @@ variable [IsDomain R] [IsTorsionFree R M] [StrongRankCondition R] then the module has dimension one. -/ theorem rank_eq_one (v : M) (n : v ≠ 0) (h : ∀ w : M, ∃ c : R, c • v = w) : Module.rank R M = 1 := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R obtain ⟨b⟩ := (Basis.basis_singleton_iff.{_, _, u} PUnit).mpr ⟨v, n, h⟩ rw [rank_eq_card_basis b, Fintype.card_punit, Nat.cast_one] diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index e61fdf32557a31..e12364c8698979 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -314,7 +314,7 @@ theorem Basis.nonempty_unique_index_of_finrank_eq_one Nonempty (Unique ι) := by -- why isn't this an instance? have : Nontrivial R := nontrivial_of_invariantBasisNumber R - haveI : Module.Finite R M := + have : Module.Finite R M := Module.finite_of_finrank_pos (Nat.lt_of_sub_eq_succ d1) have : Finite ι := Module.Finite.finite_basis b have : Fintype ι := Fintype.ofFinite ι diff --git a/Mathlib/LinearAlgebra/Dimension/FreeAndStrongRankCondition.lean b/Mathlib/LinearAlgebra/Dimension/FreeAndStrongRankCondition.lean index 8907719c5773e6..5ea999facd4c73 100644 --- a/Mathlib/LinearAlgebra/Dimension/FreeAndStrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/Dimension/FreeAndStrongRankCondition.lean @@ -37,7 +37,7 @@ noncomputable def Basis.ofRankEqZero [Module.Free K V] {ι : Type*} [IsEmpty ι] (hV : Module.rank K V = 0) : Basis ι K V := haveI : Subsingleton V := by obtain ⟨_, b⟩ := Module.Free.exists_basis (R := K) (M := V) - haveI := mk_eq_zero_iff.1 (hV ▸ b.mk_eq_rank'') + have := mk_eq_zero_iff.1 (hV ▸ b.mk_eq_rank'') exact b.repr.toEquiv.subsingleton Basis.empty _ @@ -47,7 +47,7 @@ theorem Basis.ofRankEqZero_apply [Module.Free K V] {ι : Type*} [IsEmpty ι] theorem le_rank_iff_exists_linearIndependent [Module.Free K V] {c : Cardinal} : c ≤ Module.rank K V ↔ ∃ s : Set V, #s = c ∧ LinearIndepOn K id s := by - haveI := nontrivial_of_invariantBasisNumber K + have := nontrivial_of_invariantBasisNumber K constructor · intro h obtain ⟨κ, t'⟩ := Module.Free.exists_basis (R := K) (M := V) @@ -104,18 +104,18 @@ theorem rank_le_one_iff [Module.Free K V] : single non-zero vector of which all vectors are multiples. -/ theorem rank_eq_one_iff [Module.Free K V] : Module.rank K V = 1 ↔ ∃ v₀ : V, v₀ ≠ 0 ∧ ∀ v, ∃ r : K, r • v₀ = v := by - haveI := nontrivial_of_invariantBasisNumber K + have := nontrivial_of_invariantBasisNumber K refine ⟨fun h ↦ ?_, fun ⟨v₀, h, hv⟩ ↦ (rank_le_one_iff.2 ⟨v₀, hv⟩).antisymm ?_⟩ · obtain ⟨v₀, hv⟩ := rank_le_one_iff.1 h.le refine ⟨v₀, fun hzero ↦ ?_, hv⟩ simp_rw [hzero, smul_zero, exists_const] at hv - haveI : Subsingleton V := .intro fun _ _ ↦ by simp_rw [← hv] + have : Subsingleton V := .intro fun _ _ ↦ by simp_rw [← hv] exact one_ne_zero (h ▸ rank_subsingleton' K V) · by_contra H rw [not_le, Cardinal.lt_one_iff] at H obtain ⟨κ, b⟩ := Module.Free.exists_basis (R := K) (M := V) - haveI := mk_eq_zero_iff.1 (H ▸ b.mk_eq_rank'') - haveI := b.repr.toEquiv.subsingleton + have := mk_eq_zero_iff.1 (H ▸ b.mk_eq_rank'') + have := b.repr.toEquiv.subsingleton exact h (Subsingleton.elim _ _) /-- A submodule has dimension at most `1` if and only if there is a @@ -146,7 +146,7 @@ single vector, not necessarily in the submodule, such that the submodule is contained in its span. -/ theorem rank_submodule_le_one_iff' (s : Submodule K V) [Module.Free K s] : Module.rank K s ≤ 1 ↔ ∃ v₀, s ≤ K ∙ v₀ := by - haveI := nontrivial_of_invariantBasisNumber K + have := nontrivial_of_invariantBasisNumber K constructor · rw [rank_submodule_le_one_iff] rintro ⟨v₀, _, h⟩ @@ -170,7 +170,7 @@ theorem Submodule.rank_le_one_iff_isPrincipal (W : Submodule K V) [Module.Free K theorem Module.rank_le_one_iff_top_isPrincipal [Module.Free K V] : Module.rank K V ≤ 1 ↔ (⊤ : Submodule K V).IsPrincipal := by - haveI := Module.Free.of_equiv (topEquiv (R := K) (M := V)).symm + have := Module.Free.of_equiv (topEquiv (R := K) (M := V)).symm rw [← Submodule.rank_le_one_iff_isPrincipal, rank_top] /-- A module has dimension 1 iff there is some `v : V` so `{v}` is a basis. @@ -210,10 +210,10 @@ theorem Module.finrank_le_one_iff_top_isPrincipal [Module.Free K V] [Module.Fini variable (K V) in theorem lift_cardinalMk_eq_lift_cardinalMk_field_pow_lift_rank [Module.Free K V] [Module.Finite K V] : lift.{u} #V = lift.{v} #K ^ lift.{u} (Module.rank K V) := by - haveI := nontrivial_of_invariantBasisNumber K + have := nontrivial_of_invariantBasisNumber K obtain ⟨s, hs⟩ := Module.Free.exists_basis (R := K) (M := V) -- `Module.Finite.finite_basis` is in a much later file, so we copy its proof to here - haveI : Finite s := by + have : Finite s := by obtain ⟨t, ht⟩ := ‹Module.Finite K V› exact basis_finite_of_finite_spans t.finite_toSet ht hs have := lift_mk_eq'.2 ⟨hs.repr.toEquiv⟩ @@ -249,8 +249,8 @@ theorem eq_bot_of_rank_le_one (h : Module.rank F S ≤ 1) [Module.Free F S] : S obtain ⟨y, hy⟩ := (bijective_algebraMap_of_linearEquiv (b.repr ≪≫ₗ Finsupp.uniqueLinearEquiv _ _ default).symm).surjective ⟨x, hx⟩ exact ⟨y, congr(Subtype.val $(hy))⟩ - haveI := mk_eq_zero_iff.1 (b.mk_eq_rank''.symm ▸ Cardinal.lt_one_iff.1 (h.lt_of_ne h1)) - haveI := b.repr.toEquiv.subsingleton + have := mk_eq_zero_iff.1 (b.mk_eq_rank''.symm ▸ Cardinal.lt_one_iff.1 (h.lt_of_ne h1)) + have := b.repr.toEquiv.subsingleton exact False.elim <| one_ne_zero congr(S.val $(Subsingleton.elim 1 0)) theorem eq_bot_of_finrank_one (h : finrank F S = 1) [Module.Free F S] : S = ⊥ := by @@ -269,8 +269,8 @@ theorem rank_eq_one_iff [Nontrivial E] [Module.Free F S] : Module.rank F S = 1 ← Algebra.toSubmodule_bot, rank_toSubmodule] at this · by_contra H rw [not_le, Cardinal.lt_one_iff] at H - haveI := mk_eq_zero_iff.1 (H ▸ b.mk_eq_rank'') - haveI := b.repr.toEquiv.subsingleton + have := mk_eq_zero_iff.1 (H ▸ b.mk_eq_rank'') + have := b.repr.toEquiv.subsingleton exact one_ne_zero congr((⊥ : Subalgebra F E).val $(Subsingleton.elim 1 0)) @[simp] @@ -280,12 +280,12 @@ theorem finrank_eq_one_iff [Nontrivial E] [Module.Free F S] : finrank F S = 1 theorem bot_eq_top_iff_rank_eq_one [Nontrivial E] [Module.Free F E] : (⊥ : Subalgebra F E) = ⊤ ↔ Module.rank F E = 1 := by - haveI := Module.Free.of_equiv (Subalgebra.topEquiv (R := F) (A := E)).toLinearEquiv.symm + have := Module.Free.of_equiv (Subalgebra.topEquiv (R := F) (A := E)).toLinearEquiv.symm rw [← rank_top, Subalgebra.rank_eq_one_iff, eq_comm] theorem bot_eq_top_iff_finrank_eq_one [Nontrivial E] [Module.Free F E] : (⊥ : Subalgebra F E) = ⊤ ↔ finrank F E = 1 := by - haveI := Module.Free.of_equiv (Subalgebra.topEquiv (R := F) (A := E)).toLinearEquiv.symm + have := Module.Free.of_equiv (Subalgebra.topEquiv (R := F) (A := E)).toLinearEquiv.symm rw [← finrank_top, ← subalgebra_top_finrank_eq_submodule_top_finrank, Subalgebra.finrank_eq_one_iff, eq_comm] diff --git a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean index 1d820f2b0b100c..7f8caec8071cfa 100644 --- a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean +++ b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean @@ -77,13 +77,13 @@ attribute [local instance] nontrivial_of_hasRankNullity theorem LinearMap.lift_rank_range_add_rank_ker (f : M →ₗ[R] M') : lift.{u} (Module.rank R (LinearMap.range f)) + lift.{v} (Module.rank R (LinearMap.ker f)) = lift.{v} (Module.rank R M) := by - haveI := fun p : Submodule R M => Classical.decEq (M ⧸ p) + have := fun p : Submodule R M => Classical.decEq (M ⧸ p) rw [← f.quotKerEquivRange.lift_rank_eq, ← lift_add, rank_quotient_add_rank] /-- The **rank-nullity theorem** -/ theorem LinearMap.rank_range_add_rank_ker (f : M →ₗ[R] M₁) : Module.rank R (LinearMap.range f) + Module.rank R (LinearMap.ker f) = Module.rank R M := by - haveI := fun p : Submodule R M => Classical.decEq (M ⧸ p) + have := fun p : Submodule R M => Classical.decEq (M ⧸ p) rw [← f.quotKerEquivRange.rank_eq, rank_quotient_add_rank] theorem LinearMap.lift_rank_eq_of_surjective {f : M →ₗ[R] M'} (h : Surjective f) : diff --git a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean index 368c32cb3e9fed..d7b19b667c68df 100644 --- a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean @@ -68,11 +68,11 @@ have the same cardinalities. -/ theorem mk_eq_mk_of_basis (v : Basis ι R M) (v' : Basis ι' R M) : Cardinal.lift.{w'} #ι = Cardinal.lift.{w} #ι' := by classical - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R cases fintypeOrInfinite ι · -- `v` is a finite basis, so by `basis_finite_of_finite_spans` so is `v'`. -- haveI : Finite (range v) := Set.finite_range v - haveI := basis_finite_of_finite_spans (Set.finite_range v) v.span_eq v' + have := basis_finite_of_finite_spans (Set.finite_range v) v.span_eq v' cases nonempty_fintype ι' -- We clean up a little: rw [Cardinal.mk_fintype, Cardinal.mk_fintype] @@ -88,7 +88,7 @@ theorem mk_eq_mk_of_basis (v : Basis ι R M) (v' : Basis ι' R M) : -- we see they have the same cardinality. have w₁ := infinite_basis_le_maximal_linearIndependent' v _ v'.linearIndependent v'.maximal rcases Cardinal.lift_mk_le'.mp w₁ with ⟨f⟩ - haveI : Infinite ι' := Infinite.of_injective f f.2 + have : Infinite ι' := Infinite.of_injective f f.2 have w₂ := infinite_basis_le_maximal_linearIndependent' v' _ v.linearIndependent v.maximal exact le_antisymm w₁ w₂ @@ -130,8 +130,8 @@ but still assumes we have a finite spanning set. -/ theorem basis_le_span' {ι : Type*} (b : Basis ι R M) {w : Set M} [Fintype w] (s : span R w = ⊤) : #ι ≤ Fintype.card w := by - haveI := nontrivial_of_invariantBasisNumber R - haveI := basis_finite_of_finite_spans w.toFinite s b + have := nontrivial_of_invariantBasisNumber R + have := basis_finite_of_finite_spans w.toFinite s b cases nonempty_fintype ι rw [Cardinal.mk_fintype ι] simp only [Nat.cast_le] @@ -144,7 +144,7 @@ then the cardinality of any basis is bounded by the cardinality of any spanning -/ theorem Module.Basis.le_span {J : Set M} (v : Basis ι R M) (hJ : span R J = ⊤) : #(range v) ≤ #J := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R cases fintypeOrInfinite J · rw [← Cardinal.lift_le, Cardinal.mk_range_eq_of_injective v.injective, Cardinal.mk_fintype J] convert! Cardinal.lift_le.{v}.2 (basis_le_span' v hJ) @@ -216,8 +216,8 @@ the cardinality of `ι` is bounded by the cardinality of `w`. -/ theorem linearIndependent_le_span' {ι : Type*} (v : ι → M) (i : LinearIndependent R v) (w : Set M) [Fintype w] (s : range v ≤ span R w) : #ι ≤ Fintype.card w := by - haveI : Finite ι := i.finite_of_le_span_finite v w s - letI := Fintype.ofFinite ι + have : Finite ι := i.finite_of_le_span_finite v w s + let := Fintype.ofFinite ι rw [Cardinal.mk_fintype] simp only [Nat.cast_le] exact linearIndependent_le_span_aux' v i w s @@ -268,7 +268,7 @@ theorem linearIndependent_le_basis {ι : Type w} (b : Basis ι R M) {κ : Type w -- We split into cases depending on whether `ι` is infinite. cases fintypeOrInfinite ι · rw [Cardinal.mk_fintype ι] -- When `ι` is finite, we have `linearIndependent_le_span`, - haveI : Nontrivial R := nontrivial_of_invariantBasisNumber R + have : Nontrivial R := nontrivial_of_invariantBasisNumber R rw [Fintype.card_congr (Equiv.ofInjective b b.injective)] exact linearIndependent_le_span v i (range b) b.span_eq · -- and otherwise we have `linearIndependent_le_infinite_basis`. @@ -317,11 +317,11 @@ theorem maximal_linearIndependent_eq_infinite_basis {ι : Type w} (b : Basis ι {κ : Type w} (v : κ → M) (i : LinearIndependent R v) (m : i.Maximal) : #κ = #ι := by apply le_antisymm · exact linearIndependent_le_basis b v i - · haveI : Nontrivial R := nontrivial_of_invariantBasisNumber R + · have : Nontrivial R := nontrivial_of_invariantBasisNumber R exact infinite_basis_le_maximal_linearIndependent b v i m theorem Module.Basis.mk_eq_rank'' {ι : Type v} (v : Basis ι R M) : #ι = Module.rank R M := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R rw [Module.rank_def] apply le_antisymm · trans @@ -345,7 +345,7 @@ cardinality of the basis. -/ theorem rank_eq_card_basis {ι : Type w} [Fintype ι] (h : Basis ι R M) : Module.rank R M = Fintype.card ι := by classical - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R rw [← h.mk_range_eq_rank, Cardinal.mk_fintype, Set.card_range_of_injective h.injective] namespace Module.Basis @@ -367,7 +367,7 @@ theorem card_le_card_of_le {N O : Submodule R M} (hNO : N ≤ O) [Fintype ι] theorem mk_eq_rank (v : Basis ι R M) : Cardinal.lift.{v} #ι = Cardinal.lift.{w} (Module.rank R M) := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R rw [← v.mk_range_eq_rank, Cardinal.mk_range_eq_of_injective v.injective] theorem mk_eq_rank'.{m} (v : Basis ι R M) : @@ -378,7 +378,7 @@ end Module.Basis theorem rank_span {v : ι → M} (hv : LinearIndependent R v) : Module.rank R ↑(span R (range v)) = #(range v) := by - haveI := nontrivial_of_invariantBasisNumber R + have := nontrivial_of_invariantBasisNumber R rw [← Cardinal.lift_inj, ← (Basis.span hv).mk_eq_rank, Cardinal.mk_range_eq_of_injective (@LinearIndependent.injective ι R M v _ _ _ _ hv)] diff --git a/Mathlib/LinearAlgebra/Dual/Basis.lean b/Mathlib/LinearAlgebra/Dual/Basis.lean index 8c652b22e163be..101f08ef55c396 100644 --- a/Mathlib/LinearAlgebra/Dual/Basis.lean +++ b/Mathlib/LinearAlgebra/Dual/Basis.lean @@ -197,7 +197,7 @@ omit [DecidableEq ι] @[simp] theorem linearCombination_coord [Finite ι] (b : Basis ι R M) (f : ι →₀ R) (i : ι) : Finsupp.linearCombination R b.coord f (b i) = f i := by - haveI := Classical.decEq ι + have := Classical.decEq ι rw [← coe_dualBasis, linearCombination_dualBasis] end CommSemiring diff --git a/Mathlib/LinearAlgebra/Dual/Lemmas.lean b/Mathlib/LinearAlgebra/Dual/Lemmas.lean index c2415b5462af86..0610a58a9d622e 100644 --- a/Mathlib/LinearAlgebra/Dual/Lemmas.lean +++ b/Mathlib/LinearAlgebra/Dual/Lemmas.lean @@ -1027,9 +1027,9 @@ open Submodule in theorem dualAnnihilator_dualAnnihilator_eq_map (W : Subspace K V) [FiniteDimensional K W] : W.dualAnnihilator.dualAnnihilator = W.map (Dual.eval K V) := by let e1 := (Free.chooseBasis K W).toDualEquiv ≪≫ₗ W.quotAnnihilatorEquiv.symm - haveI := e1.finiteDimensional + have := e1.finiteDimensional let e2 := (Free.chooseBasis K _).toDualEquiv ≪≫ₗ W.dualAnnihilator.dualQuotEquivDualAnnihilator - haveI := LinearEquiv.finiteDimensional (V₂ := W.dualAnnihilator.dualAnnihilator) e2 + have := LinearEquiv.finiteDimensional (V₂ := W.dualAnnihilator.dualAnnihilator) e2 rw [eq_of_le_of_finrank_eq (map_le_dualAnnihilator_dualAnnihilator W)] rw [← (equivMapOfInjective _ (eval_apply_injective K (V := V)) W).finrank_eq, e1.finrank_eq] exact e2.finrank_eq diff --git a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean index 62909b38c9dc33..f37aecde29546a 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean @@ -83,7 +83,7 @@ theorem iSup_maxGenEigenspace_eq_top [IsAlgClosed K] [FiniteDimensional K V] (f · rw [← top_le_iff] simp only [Submodule.finrank_eq_zero.1 (Eq.trans (finrank_top _ _) h_dim), bot_le] -- Otherwise the vector space is nontrivial. - · haveI : Nontrivial V := finrank_pos_iff.1 (by rw [h_dim]; apply Nat.zero_lt_succ) + · have : Nontrivial V := finrank_pos_iff.1 (by rw [h_dim]; apply Nat.zero_lt_succ) -- Hence, `f` has an eigenvalue `μ₀`. obtain ⟨μ₀, hμ₀⟩ : ∃ μ₀, f.HasEigenvalue μ₀ := exists_eigenvalue f -- We define `ES` to be the generalized eigenspace diff --git a/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean index 754cc90df5e7c1..ec57052dce2f9a 100644 --- a/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean @@ -216,8 +216,8 @@ theorem ι_eq_zero_iff (x : M) : ι R x = 0 ↔ x = 0 := by rw [← ι_inj R x 0 @[simp] theorem ι_eq_algebraMap_iff (x : M) (r : R) : ι R x = algebraMap R _ r ↔ x = 0 ∧ r = 0 := by refine ⟨fun h => ?_, ?_⟩ - · letI : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) - haveI : IsCentralScalar R M := ⟨fun r m => rfl⟩ + · let : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) + have : IsCentralScalar R M := ⟨fun r m => rfl⟩ have hf0 : toTrivSqZeroExt (ι R x) = (0, x) := toTrivSqZeroExt_ι _ rw [h, AlgHom.commutes] at hf0 have : r = 0 ∧ 0 = x := Prod.ext_iff.1 hf0 @@ -450,10 +450,10 @@ theorem toTrivSqZeroExt_comp_map [Module Rᵐᵒᵖ M] [IsCentralScalar R M] [Mo theorem ιInv_comp_map (f : M →ₗ[R] N) : ιInv.comp (map f).toLinearMap = f.comp ιInv := by - letI : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) - haveI : IsCentralScalar R M := ⟨fun r m => rfl⟩ - letI : Module Rᵐᵒᵖ N := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) - haveI : IsCentralScalar R N := ⟨fun r m => rfl⟩ + let : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) + have : IsCentralScalar R M := ⟨fun r m => rfl⟩ + let : Module Rᵐᵒᵖ N := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) + have : IsCentralScalar R N := ⟨fun r m => rfl⟩ unfold ιInv conv_lhs => rw [LinearMap.comp_assoc, ← AlgHom.comp_toLinearMap, toTrivSqZeroExt_comp_map, AlgHom.comp_toLinearMap, ← LinearMap.comp_assoc, TrivSqZeroExt.sndHom_comp_map] diff --git a/Mathlib/LinearAlgebra/ExteriorPower/Basis.lean b/Mathlib/LinearAlgebra/ExteriorPower/Basis.lean index 6e65099ebe6f75..50e27174fe674f 100644 --- a/Mathlib/LinearAlgebra/ExteriorPower/Basis.lean +++ b/Mathlib/LinearAlgebra/ExteriorPower/Basis.lean @@ -149,7 +149,7 @@ lemma basis_repr {I : Type*} [LinearOrder I] (b : Basis I R M) (s : powersetCard instance instFree [Module.Free R M] : Module.Free R (⋀[R]^n M) := by classical have ⟨I, b⟩ := Module.Free.exists_basis R M - letI : LinearOrder I := linearOrderOfSTO WellOrderingRel + let : LinearOrder I := linearOrderOfSTO WellOrderingRel exact Module.Free.of_basis (b.exteriorPower n) variable [Nontrivial R] diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index 83c1c3b59a1cf9..49794d6963ed7b 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -74,7 +74,7 @@ theorem _root_.Submodule.eq_top_of_finrank_eq [FiniteDimensional K V] {S : Submo simpa [bS] using bS.linearIndependent.linearIndepOn_id.image (f := Submodule.subtype S) (by simp) set b := Basis.extend this with b_eq - letI i2 : Fintype (((↑) : S → V) '' Basis.ofVectorSpaceIndex K S) := + let i2 : Fintype (((↑) : S → V) '' Basis.ofVectorSpaceIndex K S) := (LinearIndependent.set_finite_of_isNoetherian this).fintype have : (↑) '' Basis.ofVectorSpaceIndex K S = this.extend (Set.subset_univ _) := Set.eq_of_subset_of_card_le (this.subset_extend _) @@ -586,7 +586,7 @@ lemma exists_smul_eq_of_finrank_eq_one theorem eq_span_singleton_of_mem_of_finrank_eq_one {S : Submodule K V} {w : V} (hS : finrank K S = 1) (hw : w ∈ S) (hw0 : w ≠ 0) : S = K ∙ w := by - haveI : FiniteDimensional K S := Module.finite_of_finrank_pos (by lia) + have : FiniteDimensional K S := Module.finite_of_finrank_pos (by lia) exact Eq.symm <| eq_of_le_of_finrank_le (by simpa) (by rw [hS, finrank_span_singleton hw0]) diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean index cc7f05239646e7..7fc2c784f0d21b 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean @@ -324,7 +324,7 @@ noncomputable def finsetBasisOfLinearIndependentOfCardEqFinrank {s : Finset V} ( theorem coe_finsetBasisOfLinearIndependentOfCardEqFinrank {s : Finset V} (hs : s.Nonempty) (lin_ind : LinearIndependent K ((↑) : s → V)) (card_eq : s.card = finrank K V) : ⇑(finsetBasisOfLinearIndependentOfCardEqFinrank hs lin_ind card_eq) = ((↑) : s → V) := by - haveI : Nonempty s := ⟨⟨hs.choose, hs.choose_spec⟩⟩ + have : Nonempty s := ⟨⟨hs.choose, hs.choose_spec⟩⟩ simp [finsetBasisOfLinearIndependentOfCardEqFinrank] /-- A linear independent set of `finrank K V`-many vectors forms a basis. -/ @@ -351,10 +351,10 @@ section finrank_eq_one /-- Any `K`-algebra module that is 1-dimensional over `K` is simple. -/ theorem is_simple_module_of_finrank_eq_one {A} [Semiring A] [Module A V] [SMul K A] [IsScalarTower K A V] (h : finrank K V = 1) : IsSimpleOrder (Submodule A V) := by - haveI := nontrivial_of_finrank_eq_succ h + have := nontrivial_of_finrank_eq_succ h refine ⟨fun S => or_iff_not_imp_left.2 fun hn => ?_⟩ rw [← restrictScalars_inj K] at hn ⊢ - haveI : FiniteDimensional _ _ := .of_finrank_eq_succ h + have : FiniteDimensional _ _ := .of_finrank_eq_succ h refine eq_top_of_finrank_eq ((Submodule.finrank_le _).antisymm ?_) simpa only [h, finrank_bot] using! Submodule.finrank_strictMono (Ne.bot_lt hn) @@ -375,8 +375,8 @@ theorem Subalgebra.isSimpleOrder_of_finrank (hr : finrank F E = 2) : ⟨⟨⊥, ⊤, fun h => by cases hr.symm.trans (Subalgebra.bot_eq_top_iff_finrank_eq_one.1 h)⟩⟩ eq_bot_or_eq_top := by intro S - haveI : FiniteDimensional F E := .of_finrank_eq_succ hr - haveI : FiniteDimensional F S := + have : FiniteDimensional F E := .of_finrank_eq_succ hr + have : FiniteDimensional F S := FiniteDimensional.finiteDimensional_submodule (Subalgebra.toSubmodule S) have : finrank F S ≤ 2 := hr ▸ S.toSubmodule.finrank_le have : 0 < finrank F S := finrank_pos_iff.mpr inferInstance diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index 925148ef6dc70f..68ad97b090c321 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -192,7 +192,7 @@ theorem span_image_eq_map_linearCombination (s : Set α) : · refine map_le_iff_le_comap.2 fun z hz => ?_ have : ∀ i, z i • v i ∈ span R (v '' s) := by intro c - haveI := Classical.decPred fun x => x ∈ s + have := Classical.decPred fun x => x ∈ s by_cases h : c ∈ s · exact smul_mem _ _ (subset_span (Set.mem_image_of_mem _ h)) · simp [(Finsupp.mem_supported' R _).1 hz _ h] diff --git a/Mathlib/LinearAlgebra/Finsupp/Supported.lean b/Mathlib/LinearAlgebra/Finsupp/Supported.lean index a774d2ba9954e7..49591e6219a67a 100644 --- a/Mathlib/LinearAlgebra/Finsupp/Supported.lean +++ b/Mathlib/LinearAlgebra/Finsupp/Supported.lean @@ -136,7 +136,7 @@ theorem supported_univ : supported M R (Set.univ : Set α) = ⊤ := theorem supported_iUnion {δ : Type*} (s : δ → Set α) : supported M R (⋃ i, s i) = ⨆ i, supported M R (s i) := by refine le_antisymm ?_ (iSup_le fun i => supported_mono <| Set.subset_iUnion _ _) - haveI := Classical.decPred fun x => x ∈ ⋃ i, s i + have := Classical.decPred fun x => x ∈ ⋃ i, s i suffices LinearMap.range ((Submodule.subtype _).comp (restrictDom M R (⋃ i, s i))) ≤ ⨆ i, supported M R (s i) by @@ -248,7 +248,7 @@ theorem lmapDomain_disjoint_ker (f : α → α') {s : Set α} rintro l ⟨h₁, h₂⟩ rw [SetLike.mem_coe, mem_ker, lmapDomain_apply, mapDomain] at h₂ simp only [mem_bot]; ext x - haveI := Classical.decPred fun x => x ∈ s + have := Classical.decPred fun x => x ∈ s by_cases xs : x ∈ s · have : Finsupp.sum l (fun a => Finsupp.single (f a)) (f x) = 0 := by rw [h₂] diff --git a/Mathlib/LinearAlgebra/FreeModule/Determinant.lean b/Mathlib/LinearAlgebra/FreeModule/Determinant.lean index 46f48f44a9699a..d9c34213b74c2e 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Determinant.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Determinant.lean @@ -26,6 +26,6 @@ public section @[simp high] theorem LinearMap.det_zero'' {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] [Module.Free R M] [Module.Finite R M] [Nontrivial M] : LinearMap.det (0 : M →ₗ[R] M) = 0 := by - letI : Nonempty (Module.Free.ChooseBasisIndex R M) := (Module.Free.chooseBasis R M).index_nonempty + let : Nonempty (Module.Free.ChooseBasisIndex R M) := (Module.Free.chooseBasis R M).index_nonempty nontriviality R exact LinearMap.det_zero' (Module.Free.chooseBasis R M) diff --git a/Mathlib/LinearAlgebra/FreeModule/Norm.lean b/Mathlib/LinearAlgebra/FreeModule/Norm.lean index 995a84b92d811b..2962cae544ddf3 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Norm.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Norm.lean @@ -62,7 +62,7 @@ instance (b : Basis ι F[X] S) {I : Ideal S} (hI : I ≠ ⊥) (i : ι) : theorem finrank_quotient_span_eq_natDegree_norm [Algebra F S] [IsScalarTower F F[X] S] (b : Basis ι F[X] S) {f : S} (hf : f ≠ 0) : Module.finrank F (S ⧸ span ({f} : Set S)) = (Algebra.norm F[X] f).natDegree := by - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι have h := span_singleton_eq_bot.not.2 hf rw [natDegree_eq_of_degree_eq (degree_eq_degree_of_associated <| associated_norm_prod_smith b hf)] diff --git a/Mathlib/LinearAlgebra/FreeModule/PID.lean b/Mathlib/LinearAlgebra/FreeModule/PID.lean index 52b563a86523fb..fc285a3509f0c2 100644 --- a/Mathlib/LinearAlgebra/FreeModule/PID.lean +++ b/Mathlib/LinearAlgebra/FreeModule/PID.lean @@ -278,7 +278,7 @@ See also the stronger version `Submodule.smithNormalForm`. -/ theorem Submodule.nonempty_basis_of_pid {ι : Type*} [Finite ι] (b : Basis ι R M) (N : Submodule R M) : ∃ n : ℕ, Nonempty (Basis (Fin n) R N) := by - haveI := Classical.decEq M + have := Classical.decEq M cases nonempty_fintype ι induction N using inductionOnRank b with | ih N ih => let b' := (b.reindex (Fintype.equivFin ι)).map (LinearEquiv.ofTop _ rfl).symm diff --git a/Mathlib/LinearAlgebra/LinearDisjoint.lean b/Mathlib/LinearAlgebra/LinearDisjoint.lean index 92b016cadf3c42..25b17df3e801df 100644 --- a/Mathlib/LinearAlgebra/LinearDisjoint.lean +++ b/Mathlib/LinearAlgebra/LinearDisjoint.lean @@ -491,7 +491,7 @@ theorem not_linearIndependent_pair_of_commute_of_flat_left [Module.Flat R M] let n : Fin 2 → N := (inclusion inf_le_right) ∘ ![a, b] have hn : LinearIndependent R n := h.map' _ (ker_inclusion _ _ _) -- need this instance otherwise it only has semigroup structure - letI : AddCommGroup (Fin 2 →₀ M) := Finsupp.instAddCommGroup + let : AddCommGroup (Fin 2 →₀ M) := Finsupp.instAddCommGroup let m : Fin 2 →₀ M := .single 0 ⟨b.1, b.2.1⟩ - .single 1 ⟨a.1, a.2.1⟩ have hm : mulRightMap M n m = 0 := by simp [m, n, show _ * _ = _ * _ from hc] rw [← LinearMap.mem_ker, H.linearIndependent_right_of_flat hn, mem_bot] at hm @@ -507,7 +507,7 @@ theorem not_linearIndependent_pair_of_commute_of_flat_right [Module.Flat R N] let m : Fin 2 → M := (inclusion inf_le_left) ∘ ![a, b] have hm : LinearIndependent R m := h.map' _ (ker_inclusion _ _ _) -- need this instance otherwise it only has semigroup structure - letI : AddCommGroup (Fin 2 →₀ N) := Finsupp.instAddCommGroup + let : AddCommGroup (Fin 2 →₀ N) := Finsupp.instAddCommGroup let n : Fin 2 →₀ N := .single 0 ⟨b.1, b.2.2⟩ - .single 1 ⟨a.1, a.2.2⟩ have hn : mulLeftMap N m n = 0 := by simp [m, n, show _ * _ = _ * _ from hc] rw [← LinearMap.mem_ker, H.linearIndependent_left_of_flat hm, mem_bot] at hn diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean b/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean index 4ed7daffa65bde..fb44bd661aa109 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean @@ -496,8 +496,8 @@ theorem LinearIndepOn.image {s : Set M} {f : M →ₗ[R] M'} @[stacks 0CKL] theorem linearIndependent_monoidHom (G : Type*) [MulOneClass G] (L : Type*) [CommRing L] [IsDomain L] : LinearIndependent L (M := G → L) (fun f => f : (G →* L) → G → L) := by - letI := Classical.decEq (G →* L) - letI : MulAction L L := DistribMulAction.toMulAction + let := Classical.decEq (G →* L) + let : MulAction L L := DistribMulAction.toMulAction -- We prove linear independence by showing that only the trivial linear combination vanishes. apply linearIndependent_iff'.2 intro s diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean index 057bfa60361098..b44f5c5518aaf4 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean @@ -593,8 +593,8 @@ theorem linearIndependent_iffₒₛ : ∀ (s t : Finset ι) (f : ι → R), Disjoint s t → ∑ i ∈ s, f i • v i = ∑ i ∈ t, f i • v i → (∀ i ∈ s, f i = 0) ∧ ∀ i ∈ t, f i = 0 := by classical - letI : Sub R := CanonicallyOrderedAdd.toSub - haveI : OrderedSub R := CanonicallyOrderedAdd.toOrderedSub + let : Sub R := CanonicallyOrderedAdd.toSub + have : OrderedSub R := CanonicallyOrderedAdd.toOrderedSub rw [linearIndependent_iff'ₛ] refine ⟨fun h s t f hst heq => ?_, fun h s f g heq => ?_⟩ · specialize h (s ∪ t) (fun i => if i ∈ s then f i else 0) (fun i => if i ∈ t then f i else 0) ?_ diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean index ab631ec1d803f9..0cbe3abb88dfd9 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean @@ -206,7 +206,7 @@ theorem exists_maximal_linearIndepOn' (v : ι → M) : intro f hfsupp g hgsupp hsum rcases eq_empty_or_nonempty c with (rfl | hn) · rw [show f = 0 by simpa using! hfsupp, show g = 0 by simpa using! hgsupp] - haveI : Std.Refl r := ⟨fun _ => Set.Subset.refl _⟩ + have : Std.Refl r := ⟨fun _ => Set.Subset.refl _⟩ classical obtain ⟨I, _I_mem, hI⟩ : ∃ I ∈ c, (f.support ∪ g.support : Set ι) ⊆ I := f.support.coe_union _ ▸ hc.directedOn.exists_mem_subset_of_finset_subset_biUnion hn <| by diff --git a/Mathlib/LinearAlgebra/Matrix/Adjugate.lean b/Mathlib/LinearAlgebra/Matrix/Adjugate.lean index 8d43586fa43715..6f4e185c30b71c 100644 --- a/Mathlib/LinearAlgebra/Matrix/Adjugate.lean +++ b/Mathlib/LinearAlgebra/Matrix/Adjugate.lean @@ -341,7 +341,7 @@ theorem _root_.AlgHom.map_adjugate {R A B : Type*} [CommSemiring R] [CommRing A] theorem det_adjugate (A : Matrix n n α) : (adjugate A).det = A.det ^ (Fintype.card n - 1) := by -- get rid of the `- 1` rcases (Fintype.card n).eq_zero_or_pos with h_card | h_card - · haveI : IsEmpty n := Fintype.card_eq_zero_iff.mp h_card + · have : IsEmpty n := Fintype.card_eq_zero_iff.mp h_card rw [h_card, Nat.zero_sub, pow_zero, adjugate_subsingleton, det_one] replace h_card := tsub_add_cancel_of_le h_card.nat_succ_le -- express `A` as an evaluation of a polynomial in n^2 variables, and solve in the polynomial ring @@ -406,7 +406,7 @@ theorem adjugate_fin_three_of (a b c d e f g h i : α) : theorem det_eq_sum_mul_adjugate_row (A : Matrix n n α) (i : n) : det A = ∑ j : n, A i j * adjugate A j i := by - haveI : Nonempty n := ⟨i⟩ + have : Nonempty n := ⟨i⟩ obtain ⟨n', hn'⟩ := Nat.exists_eq_succ_of_ne_zero (Fintype.card_ne_zero : Fintype.card n ≠ 0) obtain ⟨e⟩ := Fintype.truncEquivFinOfCardEq hn' let A' := reindex e e A diff --git a/Mathlib/LinearAlgebra/Matrix/Basis.lean b/Mathlib/LinearAlgebra/Matrix/Basis.lean index 226675ca15bc1d..39fe6645ead7f2 100644 --- a/Mathlib/LinearAlgebra/Matrix/Basis.lean +++ b/Mathlib/LinearAlgebra/Matrix/Basis.lean @@ -181,7 +181,7 @@ variable [Fintype ι'] theorem basis_toMatrix_mul_linearMap_toMatrix [Finite κ] [Fintype κ'] [DecidableEq ι'] : c.toMatrix c' * LinearMap.toMatrix b' c' f = LinearMap.toMatrix b' c f := (Matrix.toLin b' c).injective <| by - haveI := Classical.decEq κ' + have := Classical.decEq κ' rw [toLin_toMatrix, toLin_mul b' c' c, toLin_toMatrix, c.toLin_toMatrix, LinearMap.id_comp] theorem basis_toMatrix_mul [Fintype κ] [Finite ι] [DecidableEq κ] @@ -244,9 +244,9 @@ namespace Module.Basis @[simp] theorem toMatrix_mul_toMatrix {ι'' : Type*} [Fintype ι'] (b'' : ι'' → M) : b.toMatrix b' * b'.toMatrix b'' = b.toMatrix b'' := by - haveI := Classical.decEq ι - haveI := Classical.decEq ι' - haveI := Classical.decEq ι'' + have := Classical.decEq ι + have := Classical.decEq ι' + have := Classical.decEq ι'' ext i j simp only [Matrix.mul_apply, toMatrix_apply, sum_repr_mul_repr] diff --git a/Mathlib/LinearAlgebra/Matrix/Block.lean b/Mathlib/LinearAlgebra/Matrix/Block.lean index 33723314f1fcab..8778b6bd5c30d8 100644 --- a/Mathlib/LinearAlgebra/Matrix/Block.lean +++ b/Mathlib/LinearAlgebra/Matrix/Block.lean @@ -323,7 +323,7 @@ theorem BlockTriangular.det_fintype [DecidableEq α] [Fintype α] [LinearOrder theorem det_of_upperTriangular [LinearOrder m] (h : M.BlockTriangular id) : M.det = ∏ i : m, M i i := by - haveI : DecidableEq R := Classical.decEq _ + have : DecidableEq R := Classical.decEq _ simp_rw [h.det, image_id, det_toSquareBlock_id] theorem det_of_lowerTriangular [LinearOrder m] (M : Matrix m m R) (h : M.BlockTriangular toDual) : @@ -395,7 +395,7 @@ theorem toBlock_inverse_eq_zero [LinearOrder α] [Invertible M] (hM : BlockTrian ext i j simpa using hM (lt_of_lt_of_le j.2 <| le_of_not_gt i.2) have h_mul_eq_zero : M⁻¹.toBlock q p * M.toBlock p p = 0 := by simpa [h_zero] using h_sum - haveI : Invertible (M.toBlock p p) := hM.invertibleToBlock k + have : Invertible (M.toBlock p p) := hM.invertibleToBlock k have : (fun i => k ≤ b i) = q := by ext exact not_lt.symm @@ -410,7 +410,7 @@ theorem blockTriangular_inv_of_blockTriangular [LinearOrder α] [Invertible M] induction s using Finset.strongInduction generalizing m with | H s ih => subst hs intro i j hij - haveI : Inhabited m := ⟨i⟩ + have : Inhabited m := ⟨i⟩ let k := (univ.image b).max' (univ_nonempty.image _) let b' := fun i : { a // b a < k } => b ↑i let A := M.toBlock (fun i => b i < k) fun j => b j < k @@ -418,7 +418,7 @@ theorem blockTriangular_inv_of_blockTriangular [LinearOrder α] [Invertible M] · have : M⁻¹.toBlock (fun i => k ≤ b i) (fun i => b i < k) ⟨i, hbi.ge⟩ ⟨j, hbi ▸ hij⟩ = 0 := by simp only [toBlock_inverse_eq_zero hM k, Matrix.zero_apply] simp [this.symm] - haveI : Invertible A := hM.invertibleToBlock _ + have : Invertible A := hM.invertibleToBlock _ have hA : A.BlockTriangular b' := hM.submatrix have hb' : image b' univ ⊂ image b univ := by convert! image_subtype_univ_ssubset_image_univ k b _ (fun a => a < k) (lt_irrefl _) diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/FiniteField.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/FiniteField.lean index 646f43ace77764..d58ead18bb217d 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/FiniteField.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/FiniteField.lean @@ -30,7 +30,7 @@ theorem FiniteField.Matrix.charpoly_pow_card {K : Type*} [Field K] [Fintype K] ( cases (isEmpty_or_nonempty n).symm · obtain ⟨p, hp⟩ := CharP.exists K rcases FiniteField.card K p with ⟨⟨k, kpos⟩, ⟨hp, hk⟩⟩ - haveI : Fact p.Prime := ⟨hp⟩ + have : Fact p.Prime := ⟨hp⟩ dsimp at hk; rw [hk] apply (frobenius_inj K[X] p).iterate k repeat' rw [iterate_frobenius (R := K[X])]; rw [← hk] diff --git a/Mathlib/LinearAlgebra/Matrix/Invertible.lean b/Mathlib/LinearAlgebra/Matrix/Invertible.lean index 1ddc70e5caf5e9..656fe672d4883b 100644 --- a/Mathlib/LinearAlgebra/Matrix/Invertible.lean +++ b/Mathlib/LinearAlgebra/Matrix/Invertible.lean @@ -111,7 +111,7 @@ instance invertibleTranspose [Invertible A] : Invertible Aᵀ where mul_invOf_self := by rw [← transpose_mul, invOf_mul_self, transpose_one] lemma transpose_invOf [Invertible A] [Invertible Aᵀ] : (⅟A)ᵀ = ⅟(Aᵀ) := by - letI := invertibleTranspose A + let := invertibleTranspose A convert! (rfl : _ = ⅟(Aᵀ)) /-- `Aᵀ` is invertible when `A` is. -/ @@ -198,7 +198,7 @@ def invertibleAddMulMul : Invertible (A + U * C * V) where See `Matrix.invOf_add_mul_mul'` for the Binomial Inverse Theorem. -/ theorem invOf_add_mul_mul [Invertible (A + U * C * V)] : ⅟(A + U * C * V) = ⅟A - ⅟A * U * ⅟(⅟C + V * ⅟A * U) * V * ⅟A := by - letI := invertibleAddMulMul A U C V + let := invertibleAddMulMul A U C V convert! (rfl : ⅟(A + U * C * V) = _) end Woodbury @@ -242,7 +242,7 @@ def invertibleAddMulMul' : Invertible (A + U * C * V) where See `Matrix.invOf_add_mul_mul` for the Woodbury identity. -/ theorem invOf_add_mul_mul' [Invertible (A + U * C * V)] : ⅟(A + U * C * V) = ⅟A - ⅟A * U * C * ⅟(C + C * V * ⅟A * U * C) * C * V * ⅟A := by - letI := invertibleAddMulMul' A U C V + let := invertibleAddMulMul' A U C V convert! (rfl : ⅟(A + U * C * V) = _) end BinomialInverseTheorem diff --git a/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean index f98961391940e6..58c6e2d0a85b46 100644 --- a/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean @@ -95,7 +95,7 @@ variable {A : Matrix n n R} lemma IsIrreducible.exists_pos [Nontrivial n] (h_irr : IsIrreducible A) (i : n) : ∃ j, 0 < A i j := by - letI : Quiver n := toQuiver A + let : Quiver n := toQuiver A by_contra h_row have no_out : ∀ j : n, IsEmpty (i ⟶ j) := fun j => ⟨fun e => h_row ⟨j, e.down⟩⟩ @@ -117,7 +117,7 @@ theorem pow_apply_pos_iff_nonempty_path (hA : ∀ i j, 0 ≤ A i j) (k : ℕ) (i j : n) : letI := toQuiver A 0 < (A ^ k) i j ↔ Nonempty {p : Path i j // p.length = k} := by - letI := toQuiver A + let := toQuiver A induction k generalizing i j with | zero => refine ⟨fun h_pos ↦ ?_, fun ⟨p, hp⟩ ↦ ?_⟩ @@ -160,7 +160,7 @@ theorem isIrreducible_iff_exists_pow_pos [Fintype n] [IsOrderedRing R] [PosMulStrictMono R] [Nontrivial R] [DecidableEq n] (hA : ∀ i j, 0 ≤ A i j) : IsIrreducible A ↔ ∀ i j, ∃ k > 0, 0 < (A ^ k) i j := by - letI : Quiver n := toQuiver A + let : Quiver n := toQuiver A constructor · intro h_irr i j obtain ⟨p, hp_len⟩ := h_irr.2 i j @@ -207,14 +207,14 @@ theorem IsIrreducible.transpose (hA : IsIrreducible A) : IsIrreducible Aᵀ := b simpa [Matrix.transpose_apply] using hA.nonneg j i refine ⟨hA_T_nonneg, ?_⟩ intro i j - letI : Quiver n := toQuiver A + let : Quiver n := toQuiver A obtain ⟨p, hp_pos⟩ := hA.connected j i cases p with | nil => simp at hp_pos | @cons b _ q e => let qT := transposePath (A := A) (q.cons e) - letI : Quiver n := toQuiver Aᵀ + let : Quiver n := toQuiver Aᵀ use qT simp [qT, transposePath, Quiver.Path.length_comp, Quiver.Path.length_toPath] diff --git a/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean b/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean index 0cda6cc66b8de5..3daaf66b9fea83 100644 --- a/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean @@ -84,7 +84,7 @@ def invertibleOfDetInvertible [Invertible A.det] : Invertible A where rw [smul_mul_assoc, adjugate_mul, smul_smul, invOf_mul_self, one_smul] theorem invOf_eq [Invertible A.det] [Invertible A] : ⅟A = ⅟A.det • A.adjugate := by - letI := invertibleOfDetInvertible A + let := invertibleOfDetInvertible A convert! (rfl : ⅟A = _) /-- `A.det` is invertible if `A` has a left inverse. -/ @@ -107,7 +107,7 @@ def detInvertibleOfInvertible [Invertible A] : Invertible A.det := detInvertibleOfLeftInverse A (⅟A) (invOf_mul_self _) theorem det_invOf [Invertible A] [Invertible A.det] : (⅟A).det = ⅟A.det := by - letI := detInvertibleOfInvertible A + let := detInvertibleOfInvertible A convert! (rfl : _ = ⅟A.det) /-- Together `Matrix.detInvertibleOfInvertible` and `Matrix.invertibleOfDetInvertible` form an @@ -181,14 +181,14 @@ theorem nonsing_inv_apply (h : IsUnit A.det) : A⁻¹ = (↑h.unit⁻¹ : α) /-- The nonsingular inverse is the same as `invOf` when `A` is invertible. -/ @[simp] theorem invOf_eq_nonsing_inv [Invertible A] : ⅟A = A⁻¹ := by - letI := detInvertibleOfInvertible A + let := detInvertibleOfInvertible A rw [inv_def, Ring.inverse_invertible, invOf_eq] /-- Coercing the result of `Units.instInv` is the same as coercing first and applying the nonsingular inverse. -/ @[simp, norm_cast] theorem coe_units_inv (A : (Matrix n n α)ˣ) : ↑A⁻¹ = (A⁻¹ : Matrix n n α) := by - letI := A.invertible + let := A.invertible rw [← invOf_eq_nonsing_inv, invOf_units] /-- The nonsingular inverse is the same as the general `Ring.inverse`. -/ @@ -412,7 +412,7 @@ theorem det_nonsing_inv_mul_det (h : IsUnit A.det) : A⁻¹.det * A.det = 1 := b theorem det_nonsing_inv : A⁻¹.det = A.det⁻¹ʳ := by by_cases h : IsUnit A.det · cases h.nonempty_invertible - letI := invertibleOfDetInvertible A + let := invertibleOfDetInvertible A rw [Ring.inverse_invertible, ← invOf_eq_nonsing_inv, det_invOf] cases isEmpty_or_nonempty n · rw [det_isEmpty, det_isEmpty, Ring.inverse_one] @@ -535,14 +535,14 @@ def invertibleOfDiagonalInvertible (v : n → α) [Invertible (diagonal v)] : In invOf := diag (⅟(diagonal v)) invOf_mul_self := funext fun i => by - letI : Invertible (diagonal v).det := detInvertibleOfInvertible _ + let : Invertible (diagonal v).det := detInvertibleOfInvertible _ rw [invOf_eq, diag_smul, adjugate_diagonal, diag_diagonal] dsimp rw [mul_assoc, prod_erase_mul _ _ (Finset.mem_univ _), ← det_diagonal] exact mul_invOf_self _ mul_invOf_self := funext fun i => by - letI : Invertible (diagonal v).det := detInvertibleOfInvertible _ + let : Invertible (diagonal v).det := detInvertibleOfInvertible _ rw [invOf_eq, diag_smul, adjugate_diagonal, diag_diagonal] dsimp rw [mul_left_comm, mul_prod_erase _ _ (Finset.mem_univ _), ← det_diagonal] @@ -607,7 +607,7 @@ theorem add_mul_mul_inv_eq_sub (hA : IsUnit A) (hC : IsUnit C) (hAC : IsUnit (C obtain ⟨_⟩ := hC.nonempty_invertible obtain ⟨iAC⟩ := hAC.nonempty_invertible simp only [← invOf_eq_nonsing_inv] at iAC - letI := invertibleAddMulMul A U C V + let := invertibleAddMulMul A U C V simp only [← invOf_eq_nonsing_inv] apply invOf_add_mul_mul @@ -617,7 +617,7 @@ theorem add_mul_mul_inv_eq_sub' (hA : IsUnit A) (h : IsUnit (C + C * V * A⁻¹ obtain ⟨_⟩ := hA.nonempty_invertible obtain ⟨ih⟩ := h.nonempty_invertible simp only [← invOf_eq_nonsing_inv] at ih - letI := invertibleAddMulMul' A U C V + let := invertibleAddMulMul' A U C V simp only [← invOf_eq_nonsing_inv] apply invOf_add_mul_mul' @@ -723,7 +723,7 @@ theorem inv_submatrix_equiv (A : Matrix m m α) (e₁ e₂ : n ≃ m) : (A.submatrix e₁ e₂)⁻¹ = A⁻¹.submatrix e₂ e₁ := by by_cases h : IsUnit A · cases h.nonempty_invertible - letI := submatrixEquivInvertible A e₁ e₂ + let := submatrixEquivInvertible A e₁ e₂ rw [← invOf_eq_nonsing_inv, ← invOf_eq_nonsing_inv, invOf_submatrix_equiv_eq A] · have := (isUnit_submatrix_equiv e₁ e₂).not.mpr h simp_rw [nonsing_inv_eq_ringInverse, Ring.inverse_non_unit _ h, Ring.inverse_non_unit _ this, diff --git a/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean b/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean index e0b537b11e3d75..46694f098cc12e 100644 --- a/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean +++ b/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean @@ -96,13 +96,13 @@ def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : theorem invOf_fromBlocks_zero₂₁_eq (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α) [Invertible A] [Invertible D] [Invertible (fromBlocks A B 0 D)] : ⅟(fromBlocks A B 0 D) = fromBlocks (⅟A) (-(⅟A * B * ⅟D)) 0 (⅟D) := by - letI := fromBlocksZero₂₁Invertible A B D + let := fromBlocksZero₂₁Invertible A B D convert! (rfl : ⅟(fromBlocks A B 0 D) = _) theorem invOf_fromBlocks_zero₁₂_eq (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α) [Invertible A] [Invertible D] [Invertible (fromBlocks A 0 C D)] : ⅟(fromBlocks A 0 C D) = fromBlocks (⅟A) 0 (-(⅟D * C * ⅟A)) (⅟D) := by - letI := fromBlocksZero₁₂Invertible A C D + let := fromBlocksZero₁₂Invertible A C D convert! (rfl : ⅟(fromBlocks A 0 C D) = _) /-- Both diagonal entries of an invertible upper-block-triangular matrix are invertible (by reading @@ -192,7 +192,7 @@ theorem inv_fromBlocks_zero₂₁_of_isUnit_iff (A : Matrix m m α) (B : Matrix · have hD := hAD.mp hA cases hA.nonempty_invertible cases hD.nonempty_invertible - letI := fromBlocksZero₂₁Invertible A B D + let := fromBlocksZero₂₁Invertible A B D simp_rw [← invOf_eq_nonsing_inv, invOf_fromBlocks_zero₂₁_eq] · have hD := hAD.not.mp hA have : ¬IsUnit (fromBlocks A B 0 D) := @@ -209,7 +209,7 @@ theorem inv_fromBlocks_zero₁₂_of_isUnit_iff (A : Matrix m m α) (C : Matrix · have hD := hAD.mp hA cases hA.nonempty_invertible cases hD.nonempty_invertible - letI := fromBlocksZero₁₂Invertible A C D + let := fromBlocksZero₁₂Invertible A C D simp_rw [← invOf_eq_nonsing_inv, invOf_fromBlocks_zero₁₂_eq] · have hD := hAD.not.mp hA have : ¬IsUnit (fromBlocks A 0 C D) := @@ -280,7 +280,7 @@ theorem invOf_fromBlocks₂₂_eq (A : Matrix m m α) (B : Matrix m n α) (C : M ⅟(fromBlocks A B C D) = fromBlocks (⅟(A - B * ⅟D * C)) (-(⅟(A - B * ⅟D * C) * B * ⅟D)) (-(⅟D * C * ⅟(A - B * ⅟D * C))) (⅟D + ⅟D * C * ⅟(A - B * ⅟D * C) * B * ⅟D) := by - letI := fromBlocks₂₂Invertible A B C D + let := fromBlocks₂₂Invertible A B C D convert! (rfl : ⅟(fromBlocks A B C D) = _) theorem invOf_fromBlocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) @@ -289,7 +289,7 @@ theorem invOf_fromBlocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : M ⅟(fromBlocks A B C D) = fromBlocks (⅟A + ⅟A * B * ⅟(D - C * ⅟A * B) * C * ⅟A) (-(⅟A * B * ⅟(D - C * ⅟A * B))) (-(⅟(D - C * ⅟A * B) * C * ⅟A)) (⅟(D - C * ⅟A * B)) := by - letI := fromBlocks₁₁Invertible A B C D + let := fromBlocks₁₁Invertible A B C D convert! (rfl : ⅟(fromBlocks A B C D) = _) /-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding @@ -376,7 +376,7 @@ theorem det_fromBlocks₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix @[simp] theorem det_fromBlocks_one₁₁ (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) : (Matrix.fromBlocks 1 B C D).det = det (D - C * B) := by - haveI : Invertible (1 : Matrix m m α) := invertibleOne + have : Invertible (1 : Matrix m m α) := invertibleOne rw [det_fromBlocks₁₁, invOf_one, Matrix.mul_one, det_one, one_mul] /-- Determinant of a 2×2 block matrix, expanded around an invertible bottom right element in terms @@ -393,7 +393,7 @@ theorem det_fromBlocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix @[simp] theorem det_fromBlocks_one₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) : (Matrix.fromBlocks A B C 1).det = det (A - B * C) := by - haveI : Invertible (1 : Matrix n n α) := invertibleOne + have : Invertible (1 : Matrix n n α) := invertibleOne rw [det_fromBlocks₂₂, invOf_one, Matrix.mul_one, det_one, one_mul] /-- The **Weinstein–Aronszajn identity**. Note the `1` on the LHS is of shape m×m, while the `1` on diff --git a/Mathlib/LinearAlgebra/Matrix/ToLin.lean b/Mathlib/LinearAlgebra/Matrix/ToLin.lean index bbd8ec8bd71fcd..239eaf34325b88 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLin.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLin.lean @@ -173,7 +173,7 @@ variable [Fintype m] theorem range_vecMulLinear (M : Matrix m n R) : LinearMap.range M.vecMulLinear = span R (range M.row) := by - letI := Classical.decEq m + let := Classical.decEq m simp_rw [range_eq_map, ← iSup_range_single, Submodule.map_iSup, range_eq_map, ← Ideal.span_singleton_one, Ideal.span, Submodule.map_span, image_image, image_singleton, Matrix.vecMulLinear_apply, iSup_span, range_eq_iUnion, iUnion_singleton_eq_range, @@ -772,7 +772,7 @@ lemma LinearMap.toMatrix_pow (f : M₁ →ₗ[R] M₁) (k : ℕ) : theorem Matrix.toLin_mul [Finite l] [DecidableEq m] (A : Matrix l m R) (B : Matrix m n R) : Matrix.toLin v₁ v₃ (A * B) = (Matrix.toLin v₂ v₃ A).comp (Matrix.toLin v₁ v₂ B) := by apply (LinearMap.toMatrix v₁ v₃).injective - haveI : DecidableEq l := fun _ _ ↦ Classical.propDecidable _ + have : DecidableEq l := fun _ _ ↦ Classical.propDecidable _ rw [LinearMap.toMatrix_comp v₁ v₂ v₃] repeat' rw [LinearMap.toMatrix_toLin] diff --git a/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean b/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean index 0fff49a15762ba..5aa01b1e6aa10f 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean @@ -136,7 +136,7 @@ private theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq · ext i refine (RingHom.map_mulVec _ _ _ i).symm.trans ?_ rw [mul_eq, Pi.zero_apply, map_zero, Pi.zero_apply] - · letI := Classical.decEq K + · let := Classical.decEq K obtain ⟨⟨b, hb⟩, ba_eq⟩ := IsLocalization.exist_integer_multiples_of_finset (nonZeroDivisors A) (Finset.univ.image v) choose f hf using ba_eq diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index 6c744b0fe0734a..c65bd76e461ac7 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -486,7 +486,7 @@ coordinate. Here, we give an auxiliary statement tailored for an inductive proof `map_sum_finset`. -/ theorem map_sum_finset_aux [DecidableEq ι] [Fintype ι] {n : ℕ} (h : (∑ i, #(A i)) = n) : (f fun i => ∑ j ∈ A i, g i j) = ∑ r ∈ piFinset A, f fun i => g i (r i) := by - letI := fun i => Classical.decEq (α i) + let := fun i => Classical.decEq (α i) induction n using Nat.strong_induction_on generalizing A with | h n IH => -- If one of the sets is empty, then all the sums are zero by_cases! Ai_empty : ∃ i, A i = ∅ @@ -678,11 +678,11 @@ def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M MultilinearMap R (fun _ : ι₂ => M₂) M₃ where toFun v := m fun i => v (σ i) map_update_add' v i a b := by - letI := σ.injective.decidableEq + let := σ.injective.decidableEq simp_rw [Function.update_apply_equiv_apply v] rw [m.map_update_add] map_update_smul' v i a b := by - letI := σ.injective.decidableEq + let := σ.injective.decidableEq simp_rw [Function.update_apply_equiv_apply v] rw [m.map_update_smul] @@ -947,24 +947,24 @@ def domDomCongrLinearEquiv' {ι' : Type*} (σ : ι ≃ ι') : toFun f := { toFun := f ∘ (σ.piCongrLeft' M₁).symm map_update_add' := fun m i => by - letI := σ.decidableEq + let := σ.decidableEq rw [← σ.apply_symm_apply i] intro x y simp only [comp_apply, piCongrLeft'_symm_update, f.map_update_add] map_update_smul' := fun m i c => by - letI := σ.decidableEq + let := σ.decidableEq rw [← σ.apply_symm_apply i] intro x simp only [Function.comp, piCongrLeft'_symm_update, f.map_update_smul] } invFun f := { toFun := f ∘ σ.piCongrLeft' M₁ map_update_add' := fun m i => by - letI := σ.symm.decidableEq + let := σ.symm.decidableEq rw [← σ.symm_apply_apply i] intro x y simp only [comp_apply, piCongrLeft'_update, f.map_update_add] map_update_smul' := fun m i c => by - letI := σ.symm.decidableEq + let := σ.symm.decidableEq rw [← σ.symm_apply_apply i] intro x simp only [Function.comp, piCongrLeft'_update, f.map_update_smul] } @@ -1424,7 +1424,7 @@ def map [Nonempty ι] (f : MultilinearMap R M₁ M₂) (p : ∀ i, Submodule R ( carrier := f '' { v | ∀ i, v i ∈ p i } smul_mem' := fun c _ ⟨x, hx, hf⟩ => by let ⟨i⟩ := ‹Nonempty ι› - letI := Classical.decEq ι + let := Classical.decEq ι refine ⟨update x i (c • x i), fun j => if hij : j = i then ?_ else ?_, hf ▸ ?_⟩ · rw [hij, update_self] exact (p i).smul_mem _ (hx i) diff --git a/Mathlib/LinearAlgebra/Multilinear/Curry.lean b/Mathlib/LinearAlgebra/Multilinear/Curry.lean index 6b7e3551c8a396..59033dde003028 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Curry.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Curry.lean @@ -240,12 +240,12 @@ def currySum (f : MultilinearMap R N M₂) : MultilinearMap R (fun i : ι ↦ N (.inl i)) (MultilinearMap R (fun i : ι' ↦ N (.inr i)) M₂) where toFun u := { toFun v := f (Sum.rec u v) - map_update_add' := by letI := Classical.decEq ι; simp - map_update_smul' := by letI := Classical.decEq ι; simp } + map_update_add' := by let := Classical.decEq ι; simp + map_update_smul' := by let := Classical.decEq ι; simp } map_update_add' u i x y := - ext fun _ ↦ by letI := Classical.decEq ι'; simp + ext fun _ ↦ by let := Classical.decEq ι'; simp map_update_smul' u i c x := - ext fun _ ↦ by letI := Classical.decEq ι'; simp + ext fun _ ↦ by let := Classical.decEq ι'; simp @[simp low] theorem currySum_apply (f : MultilinearMap R N M₂) @@ -276,12 +276,12 @@ def uncurrySum MultilinearMap R N M₂ where toFun u := g (fun i ↦ u (.inl i)) (fun i' ↦ u (.inr i')) map_update_add' := by - letI := Classical.decEq ι - letI := Classical.decEq ι' + let := Classical.decEq ι + let := Classical.decEq ι' rintro _ _ (_ | _) _ _ <;> simp map_update_smul' := by - letI := Classical.decEq ι - letI := Classical.decEq ι' + let := Classical.decEq ι + let := Classical.decEq ι' rintro _ _ (_ | _) _ _ <;> simp @[simp] diff --git a/Mathlib/LinearAlgebra/Multilinear/DirectSum.lean b/Mathlib/LinearAlgebra/Multilinear/DirectSum.lean index 3215af10f7219b..0074a6ba6151b3 100644 --- a/Mathlib/LinearAlgebra/Multilinear/DirectSum.lean +++ b/Mathlib/LinearAlgebra/Multilinear/DirectSum.lean @@ -57,7 +57,7 @@ theorem fromDirectSumEquiv_lof [Finite ι] [(i : ι) → DecidableEq (κ i)] (f : (p : (i : ι) → κ i) → MultilinearMap R (fun i ↦ M i (p i)) M') (p : (i : ι) → κ i) (x : (i : ι) → M i (p i)) : fromDirectSumEquiv f (fun i => lof R _ _ _ (x i)) = f p x := by - haveI : Fintype ι := Fintype.ofFinite ι + have : Fintype ι := Fintype.ofFinite ι rw [fromDirectSumEquiv, ← fromDFinsuppEquiv_single] convert! rfl @@ -78,7 +78,7 @@ theorem fromDirectSumEquiv_symm_apply [Finite ι] [(i : ι) → DecidableEq (κ (f : MultilinearMap R (fun i ↦ ⨁ j : κ i, M i j) M') (p : (i : ι) → κ i) : fromDirectSumEquiv.symm f p = f.compLinearMap (fun i ↦ DirectSum.lof _ _ _ (p i)) := by - haveI : Fintype ι := Fintype.ofFinite ι + have : Fintype ι := Fintype.ofFinite ι simp_rw [fromDirectSumEquiv, DirectSum.lof, ← fromDFinsuppEquiv_symm_apply] convert! rfl diff --git a/Mathlib/LinearAlgebra/Multilinear/FiniteDimensional.lean b/Mathlib/LinearAlgebra/Multilinear/FiniteDimensional.lean index bf870eaf711596..d91d38f741877f 100644 --- a/Mathlib/LinearAlgebra/Multilinear/FiniteDimensional.lean +++ b/Mathlib/LinearAlgebra/Multilinear/FiniteDimensional.lean @@ -35,7 +35,7 @@ private theorem free_and_finite_fin (n : ℕ) (N : Fin n → Type*) [∀ i, AddC Module.Free R (MultilinearMap R N M₂) ∧ Module.Finite R (MultilinearMap R N M₂) := by induction n with | zero => - haveI : IsEmpty (Fin Nat.zero) := inferInstanceAs (IsEmpty (Fin 0)) + have : IsEmpty (Fin Nat.zero) := inferInstanceAs (IsEmpty (Fin 0)) exact ⟨Module.Free.of_equiv (constLinearEquivOfIsEmpty R R N M₂), Module.Finite.equiv (constLinearEquivOfIsEmpty R R N M₂)⟩ diff --git a/Mathlib/LinearAlgebra/Multilinear/TensorProduct.lean b/Mathlib/LinearAlgebra/Multilinear/TensorProduct.lean index a9282df0563c9a..9d3c31d33af7b4 100644 --- a/Mathlib/LinearAlgebra/Multilinear/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/Multilinear/TensorProduct.lean @@ -42,12 +42,12 @@ def domCoprodDep (a : MultilinearMap R (fun i₁ ↦ N (.inl i₁)) N₁) toFun v := a (fun i₁ ↦ v (.inl i₁)) ⊗ₜ b (fun i₂ ↦ v (.inr i₂)) map_update_add' := by rintro _ _ (_ | _) _ _ - · letI := Classical.decEq ι₁; simp - · letI := Classical.decEq ι₂; simp + · let := Classical.decEq ι₁; simp + · let := Classical.decEq ι₂; simp map_update_smul' := by rintro _ m (i₁ | i₂) p q - · letI := Classical.decEq ι₁; simp - · letI := Classical.decEq ι₂; simp + · let := Classical.decEq ι₁; simp + · let := Classical.decEq ι₂; simp /-- A more bundled version of `MultilinearMap.domCoprodDep`, as a linear map from the tensor product of spaces of multilinear maps. -/ diff --git a/Mathlib/LinearAlgebra/Orientation.lean b/Mathlib/LinearAlgebra/Orientation.lean index 197742e8649f8b..f6633180871c65 100644 --- a/Mathlib/LinearAlgebra/Orientation.lean +++ b/Mathlib/LinearAlgebra/Orientation.lean @@ -149,7 +149,7 @@ of `f.det`. -/ theorem map_orientation_eq_det_inv_smul [Finite ι] (e : Basis ι R M) (x : Orientation R M ι) (f : M ≃ₗ[R] M) : Orientation.map ι f x = (LinearEquiv.det f)⁻¹ • x := by cases nonempty_fintype ι - letI := Classical.decEq ι + let := Classical.decEq ι induction x using Module.Ray.ind with | h g hg => rw [Orientation.map_apply, smul_rayOfNeZero, ray_eq_iff, Units.smul_def, (g.compLinearMap f.symm).eq_smul_basis_det e, g.eq_smul_basis_det e, @@ -338,7 +338,7 @@ equal or negations. -/ theorem eq_or_eq_neg [FiniteDimensional R M] (x₁ x₂ : Orientation R M ι) (h : Fintype.card ι = finrank R M) : x₁ = x₂ ∨ x₁ = -x₂ := by have e := (finBasis R M).reindex (Fintype.equivFinOfCardEq h).symm - letI := Classical.decEq ι + let := Classical.decEq ι rcases e.orientation_eq_or_eq_neg x₁ with (h₁ | h₁) <;> rcases e.orientation_eq_or_eq_neg x₂ with (h₂ | h₂) <;> simp [h₁, h₂] @@ -379,7 +379,7 @@ theorem map_eq_neg_iff_det_neg (x : Orientation R M ι) (f : M ≃ₗ[R] M) have H : 0 < finrank R M := by rw [← h] exact Fintype.card_pos - haveI : FiniteDimensional R M := of_finrank_pos H + have : FiniteDimensional R M := of_finrank_pos H rw [map_eq_det_inv_smul _ _ h, units_inv_smul, units_smul_eq_neg_iff, LinearEquiv.coe_det] /-- If the index type has cardinality equal to the finite dimension, a basis with the given diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean index 07b38727efe4e6..e9b880da072aa9 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean @@ -48,7 +48,7 @@ theorem Basis.piTensorProduct_repr_tprod_apply [Fintype ι] (b : Π i, Basis (κ @[simp] theorem Basis.piTensorProduct_apply [Finite ι] (b : Π i, Basis (κ i) R (M i)) (p : Π i, κ i) : Basis.piTensorProduct b p = ⨂ₜ[R] i, (b i) (p i) := by - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι classical refine (Basis.piTensorProduct b).ext_elem (fun q ↦ ?_) simp [Finsupp.single_apply, Fintype.prod_ite_zero, ← funext_iff] diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean index e8a27bfb9e26cd..eb6fc3f8c96cf2 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean @@ -80,8 +80,8 @@ theorem dualDistribInvOfBasis_apply [Fintype ι] [∀ i, Fintype (κ i)] (b : Π theorem dualDistrib_dualDistribInvOfBasis_left_inverse [Finite ι] [∀ i, Finite (κ i)] (b : Π i, Basis (κ i) R (M i)) : (dualDistrib) ∘ₗ (dualDistribInvOfBasis b) = LinearMap.id := by - haveI := Fintype.ofFinite ι - haveI := fun i => Fintype.ofFinite (κ i) + have := Fintype.ofFinite ι + have := fun i => Fintype.ofFinite (κ i) classical refine (Basis.piTensorProduct b).dualBasis.ext (fun p ↦ ?_) refine (Basis.piTensorProduct b).ext (fun q ↦ ?_) @@ -90,8 +90,8 @@ theorem dualDistrib_dualDistribInvOfBasis_left_inverse [Finite ι] [∀ i, Finit theorem dualDistrib_dualDistribInvOfBasis_right_inverse [Finite ι] [∀ i, Finite (κ i)] (b : Π i, Basis (κ i) R (M i)) : (dualDistribInvOfBasis b) ∘ₗ dualDistrib = LinearMap.id := by - haveI := Fintype.ofFinite ι - haveI := fun i => Fintype.ofFinite (κ i) + have := Fintype.ofFinite ι + have := fun i => Fintype.ofFinite (κ i) classical refine (Basis.piTensorProduct (fun i => (b i).dualBasis)).ext (fun p ↦ ?_) refine (Basis.piTensorProduct (fun i => (b i).dualBasis)).ext_elem (fun q ↦ ?_) diff --git a/Mathlib/LinearAlgebra/Projectivization/Cardinality.lean b/Mathlib/LinearAlgebra/Projectivization/Cardinality.lean index 0c4023612a4ee1..66e92dd580e37e 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Cardinality.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Cardinality.lean @@ -77,9 +77,9 @@ lemma card : Nat.card V - 1 = Nat.card (ℙ k V) * (Nat.card k - 1) := by simp | inl h => classical - haveI : Fintype V := Fintype.ofFinite V - haveI : Fintype (ℙ k V) := Fintype.ofFinite (ℙ k V) - haveI : Fintype k := Fintype.ofFinite k + have : Fintype V := Fintype.ofFinite V + have : Fintype (ℙ k V) := Fintype.ofFinite (ℙ k V) + have : Fintype k := Fintype.ofFinite k have hV : Fintype.card { v : V // v ≠ 0 } = Fintype.card V - 1 := by simp simp_rw [← Fintype.card_eq_nat_card, ← Fintype.card_units (α := k), ← hV] rw [Fintype.card_congr (nonZeroEquivProjectivizationProdUnits k V), Fintype.card_prod] diff --git a/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean b/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean index 32a6e3158224af..eb34a5fc7acebb 100644 --- a/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean +++ b/Mathlib/LinearAlgebra/Projectivization/PSL/PSL2.lean @@ -101,7 +101,7 @@ open Matrix.SpecialLinearGroup lemma PSL_commutator_eq_top (hF : ∃ a : F, a ≠ 0 ∧ a ^ 2 ≠ 1) : commutator PSL(2, F) = ⊤ := by obtain ⟨a, ha, hasq⟩ := hF - haveI : Group.IsPerfect SL(2, F) := ⟨SL2.commutator_eq_top ha hasq⟩ + have : Group.IsPerfect SL(2, F) := ⟨SL2.commutator_eq_top ha hasq⟩ have : Group.IsPerfect (Matrix.ProjectiveSpecialLinearGroup (Fin 2) F) := inferInstance exact this.commutator_eq_top diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index 1bd2bf12f0d792..fa61690db36e59 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -1065,7 +1065,7 @@ alias ⟨IsOrtho.symm, _⟩ := isOrtho_comm theorem _root_.LinearMap.BilinForm.toQuadraticMap_isOrtho [IsCancelAdd R] [NoZeroDivisors R] [CharZero R] {B : BilinMap R M R} {x y : M} (h : B.IsSymm) : B.toQuadraticMap.IsOrtho x y ↔ B x y = 0 := by - letI : AddCancelMonoid R := { ‹IsCancelAdd R›, (inferInstance : AddCommMonoid R) with } + let : AddCancelMonoid R := { ‹IsCancelAdd R›, (inferInstance : AddCommMonoid R) with } simp_rw [isOrtho_def, B.toQuadraticMap_apply, map_add, LinearMap.add_apply, add_comm _ (B y y), add_add_add_comm _ _ (B y y), add_comm (B y y)] rw [add_eq_left (a := B x x + B y y), ← h.eq, RingHom.id_apply, add_self_eq_zero] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean index 3344cb5b23f2f6..6bd56e82995fa4 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean @@ -116,7 +116,7 @@ theorem _root_.LinearMap.BilinMap.toQuadraticMap_surjective [Module.Free R M] : Function.Surjective (LinearMap.BilinMap.toQuadraticMap : LinearMap.BilinMap R M N → _) := by intro Q obtain ⟨ι, b⟩ := Module.Free.exists_basis (R := R) (M := M) - letI : LinearOrder ι := IsWellOrder.linearOrder WellOrderingRel + let : LinearOrder ι := IsWellOrder.linearOrder WellOrderingRel exact ⟨_, toQuadraticMap_toBilin _ b⟩ @[simp] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean b/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean index f2e5f4e238dccb..9f201320904a8a 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/TensorProduct.lean @@ -72,7 +72,7 @@ protected abbrev tmul (Q₁ : QuadraticMap A M₁ N₁) theorem associated_tmul [Invertible (2 : A)] (Q₁ : QuadraticMap A M₁ N₁) (Q₂ : QuadraticMap R M₂ N₂) : (Q₁.tmul Q₂).associated = Q₁.associated.tmul Q₂.associated := by - letI : Invertible (2 : A) := (Invertible.map (algebraMap R A) 2).copy 2 (map_ofNat _ _).symm + let : Invertible (2 : A) := (Invertible.map (algebraMap R A) 2).copy 2 (map_ofNat _ _).symm rw [QuadraticMap.tmul, BilinMap.tmul] have : Subsingleton (Invertible (2 : A)) := inferInstance convert! diff --git a/Mathlib/LinearAlgebra/RootSystem/Base.lean b/Mathlib/LinearAlgebra/RootSystem/Base.lean index 022a13c4005114..0bc7398af7dc34 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Base.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Base.lean @@ -434,7 +434,7 @@ lemma height_ne_zero (i : ι) : lemma height_reflectionPerm_self (i : ι) : letI := P.indexNeg b.height (-i) = -b.height i := by - letI := P.indexNeg + let := P.indexNeg obtain ⟨f, hf₀, hf₁, hf₂⟩ := b.exists_root_eq_sum_int i have hf₃ : P.root (-i) = ∑ j ∈ b.support, (-f) j • P.root j := by simpa simp only [height_eq_sum hf₂, height_eq_sum hf₃, Pi.neg_apply, Finset.sum_neg_distrib] @@ -458,7 +458,7 @@ lemma height_add {i j k : ι} (hk : P.root k = P.root i + P.root j) : lemma height_sub {i j k : ι} (hk : P.root k = P.root i - P.root j) : b.height k = b.height i - b.height j := by - letI := P.indexNeg + let := P.indexNeg replace hk : P.root k = P.root i + P.root (-j) := by simpa [← sub_eq_add_neg] rw [sub_eq_add_neg, ← b.height_reflectionPerm_self, b.height_add hk] @@ -553,7 +553,7 @@ lemma IsPos.add_zsmul {i j k : ι} {z : ℤ} (hij : i ≠ j) b.IsPos k := by replace hij : LinearIndependent R ![P.root j, P.root i] := by refine IsReduced.linearIndependent P hij.symm fun contra ↦ ?_ - letI := P.indexNeg + let := P.indexNeg replace contra : i = -j := by rw [eq_comm, neg_eq_iff_eq_neg]; simpa using contra rw [contra, isPos_iff, height_reflectionPerm_self, height_one_of_mem_support hj] at hi lia @@ -630,7 +630,7 @@ lemma induction_add (i : ι) {p : ι → Prop} (h₁ : ∀ i ∈ b.support, p i) (h₂ : ∀ i j k, P.root k = P.root i + P.root j → p i → j ∈ b.support → p k) : p i := by - letI := P.indexNeg + let := P.indexNeg rcases IsPos.or_neg b i with hi | hi · exact hi.induction_on_add h₁ h₂ · suffices p (-i) by rw [← neg_neg i]; exact h₀ (-i) this @@ -667,7 +667,7 @@ lemma induction_reflect (i : ι) {p : ι → Prop} (h₁ : ∀ i ∈ b.support, p i) (h₂ : ∀ i j, p i → j ∈ b.support → p (P.reflectionPerm j i)) : p i := by - letI := P.indexNeg + let := P.indexNeg rcases IsPos.or_neg b i with hi | hi · exact hi.induction_on_reflect h₁ h₂ · suffices p (-i) by rw [← neg_neg i]; exact h₀ (-i) this @@ -677,7 +677,7 @@ lemma forall_mem_support_invtSubmodule_iff (q : Submodule R M) : (∀ i ∈ b.support, q ∈ invtSubmodule (P.reflection i)) ↔ (∀ i, q ∈ invtSubmodule (P.reflection i)) := by refine ⟨fun hq i ↦ ?_, fun hq i _ ↦ hq i⟩ - letI := P.indexNeg + let := P.indexNeg have (j : ι) : P.reflection (-j) = P.reflection j := by ext x; simp [reflection_apply, two_smul] refine b.induction_reflect i (by simp_all) hq ?_ clear i diff --git a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean index 527c373656cc7b..6e4ee701a2c614 100644 --- a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean +++ b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean @@ -53,7 +53,7 @@ variable [CommRing R] [Module R M] [Module R N] (P : RootPairing ι R M N) lemma baseOf_pairwise_pairing_le_zero [CharZero R] [IsDomain R] [P.IsCrystallographic] (hf : ∀ i, f (P.root i) ≠ 0) : (baseOf P.root f).Pairwise fun i j ↦ P.pairingIn ℤ i j ≤ 0 := by - letI _i := P.indexNeg + let _i := P.indexNeg intro i hi j hj hne have := IsAddIndecomposable.pairwise_baseOf_sub_notMem P.root (by simp) f hf hi hj hne contrapose! this @@ -117,7 +117,7 @@ lemma linearIndepOn_root_baseOf (f : M →+ ℚ) (hf : ∀ i, f (P.root i) ≠ 0 LinearIndepOn R P.root (baseOf P.root f) := by let _i : Module ℚ M := Module.compHom M (algebraMap ℚ R) let _i : Module ℚ N := Module.compHom N (algebraMap ℚ R) - letI := P.indexNeg + let := P.indexNeg have : Fintype (baseOf P.root f) := Fintype.ofFinite _ let v (i : baseOf P.root f) : P.rootSpan ℚ := P.rootSpanMem ℚ i change LinearIndependent R ((P.rootSpan ℚ).subtype ∘ v) @@ -155,7 +155,7 @@ lemma eq_baseOf_of_linearIndepOn_of_mem_or_neg_mem_closure -P.root i ∈ AddSubmonoid.closure (P.root '' s)) (f : M →+ ℚ) (hf : ∀ i ∈ s, f (P.root i) = 1) : s = baseOf P.root f := by - letI _i := P.indexNeg + let _i := P.indexNeg have h_card : (baseOf P.root f).ncard = s.ncard := by have hf' (i : ι) : f (P.root i) ≠ 0 := AddSubmonoid.apply_ne_zero_of_mem_or_neg_mem_closure P.root f s (by aesop) i (P.ne_zero i) (by simp) (hsp i) @@ -187,7 +187,7 @@ lemma eq_baseOf_iff (s : Set ι) (f : M →+ ℚ) LinearIndepOn R P.root s ∧ ∀ i, P.root i ∈ AddSubmonoid.closure (P.root '' s) ∨ -P.root i ∈ AddSubmonoid.closure (P.root '' s) := by - letI := P.indexNeg + let := P.indexNeg refine ⟨?_, fun ⟨hli, sp⟩ ↦ P.eq_baseOf_of_linearIndepOn_of_mem_or_neg_mem_closure s hli sp f hf⟩ rintro rfl exact ⟨P.linearIndepOn_root_baseOf f hf', fun i ↦ @@ -281,8 +281,8 @@ lemma coroot_mem_or_neg_mem_closure_of_root (s : Set ι) (i : ι) : P.coroot i ∈ AddSubmonoid.closure (P.coroot '' s) ∨ -P.coroot i ∈ AddSubmonoid.closure (P.coroot '' s) := by - letI _i := P.indexNeg - letI _i : Fintype ι := Fintype.ofFinite ι + let _i := P.indexNeg + let _i : Fintype ι := Fintype.ofFinite ι let _i : Module ℚ M := Module.compHom M (algebraMap ℚ R) let _i : Module ℚ N := Module.compHom N (algebraMap ℚ R) obtain ⟨f, hf'⟩ := exists_dual_forall_apply_eq_one (hli.restrict_scalars' ℚ) @@ -322,7 +322,7 @@ lemma nonempty_base : Nonempty P.Base := by let _i : Module ℚ M := Module.compHom M (algebraMap ℚ R) obtain ⟨f, hf⟩ : ∃ f : Dual ℚ M, ∀ i, f (P.root i) ≠ 0 := exists_dual_forall_apply_ne_zero P.root <| by simp [P.ne_zero] - letI := P.indexNeg + let := P.indexNeg exact ⟨Base.mk' P (baseOf P.root (f : M →+ ℚ)) (P.linearIndepOn_root_baseOf f hf) (fun i ↦ mem_or_neg_mem_closure_baseOf P.root (f : M →+ ℚ) i (hf i) (by simp))⟩ diff --git a/Mathlib/LinearAlgebra/RootSystem/Chain.lean b/Mathlib/LinearAlgebra/RootSystem/Chain.lean index 32e447d5562087..6cf43c476911c9 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Chain.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Chain.lean @@ -226,7 +226,7 @@ private lemma chainCoeff_reflectionPerm_left_aux : letI := P.indexNeg Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) = Icc (-P.chainBotCoeff (-i) j : ℤ) (P.chainTopCoeff (-i) j) := by - letI := P.indexNeg + let := P.indexNeg by_cases h : LinearIndependent R ![P.root i, P.root j] · have h' : LinearIndependent R ![P.root (-i), P.root j] := by simpa ext z @@ -241,7 +241,7 @@ private lemma chainCoeff_reflectionPerm_right_aux : letI := P.indexNeg Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) = Icc (-P.chainBotCoeff i (-j) : ℤ) (P.chainTopCoeff i (-j)) := by - letI := P.indexNeg + let := P.indexNeg by_cases h : LinearIndependent R ![P.root i, P.root j] · have h' : LinearIndependent R ![P.root i, P.root (-j)] := by simpa ext z @@ -255,7 +255,7 @@ private lemma chainCoeff_reflectionPerm_right_aux : @[simp] lemma chainTopCoeff_reflectionPerm_left : P.chainTopCoeff (P.reflectionPerm i i) j = P.chainBotCoeff i j := by - letI := P.indexNeg + let := P.indexNeg have (z : ℤ) : z ∈ Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) ↔ z ∈ Icc (-P.chainBotCoeff (-i) j : ℤ) (P.chainTopCoeff (-i) j) := by rw [P.chainCoeff_reflectionPerm_left_aux] @@ -266,7 +266,7 @@ lemma chainTopCoeff_reflectionPerm_left : @[simp] lemma chainBotCoeff_reflectionPerm_left : P.chainBotCoeff (P.reflectionPerm i i) j = P.chainTopCoeff i j := by - letI := P.indexNeg + let := P.indexNeg have (z : ℤ) : z ∈ Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) ↔ z ∈ Icc (-P.chainBotCoeff (-i) j : ℤ) (P.chainTopCoeff (-i) j) := by rw [P.chainCoeff_reflectionPerm_left_aux] @@ -277,7 +277,7 @@ lemma chainBotCoeff_reflectionPerm_left : @[simp] lemma chainTopCoeff_reflectionPerm_right : P.chainTopCoeff i (P.reflectionPerm j j) = P.chainBotCoeff i j := by - letI := P.indexNeg + let := P.indexNeg have (z : ℤ) : z ∈ Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) ↔ z ∈ Icc (-P.chainBotCoeff i (-j) : ℤ) (P.chainTopCoeff i (-j)) := by rw [P.chainCoeff_reflectionPerm_right_aux] @@ -288,7 +288,7 @@ lemma chainTopCoeff_reflectionPerm_right : @[simp] lemma chainBotCoeff_reflectionPerm_right : P.chainBotCoeff i (P.reflectionPerm j j) = P.chainTopCoeff i j := by - letI := P.indexNeg + let := P.indexNeg have (z : ℤ) : z ∈ Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) ↔ z ∈ Icc (-P.chainBotCoeff i (-j) : ℤ) (P.chainTopCoeff i (-j)) := by rw [P.chainCoeff_reflectionPerm_right_aux] @@ -335,7 +335,7 @@ lemma chainBotCoeff_of_add {k : ι} (hk : P.root k = P.root j + P.root i) : lemma chainTopCoeff_of_sub {k : ι} (hk : P.root k = P.root j - P.root i) : P.chainTopCoeff i k = P.chainTopCoeff i j + 1 := by - letI := P.indexNeg + let := P.indexNeg replace hk : P.root k = P.root j + P.root (-i) := by simpa [sub_eq_add_neg] using hk simpa using chainBotCoeff_of_add (by simpa) hk diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean index edce6dcdfeb79f..09b07eeb1050dd 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean @@ -191,7 +191,7 @@ lemma chainBotCoeff_if_one_zero [P.IsNotG2] (h : P.root i + P.root j ∈ range P lemma chainTopCoeff_if_one_zero [P.IsNotG2] (h : P.root i - P.root j ∈ range P.root) : P.chainTopCoeff i j = if P.pairingIn ℤ i j = 0 then 1 else 0 := by - letI := P.indexNeg + let := P.indexNeg replace h : P.root i + P.root (-j) ∈ range P.root := by simpa [← sub_eq_add_neg] using h simpa using P.chainBotCoeff_if_one_zero h diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean index a91cfa25f73804..f78200eabdb85e 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean @@ -260,7 +260,7 @@ lemma ω_mul_h [Fintype ι] (i : b.support) : lemma ω_mul_e [Fintype ι] (i : b.support) : ω b * e i = f i * ω b := by - letI := P.indexNeg + let := P.indexNeg classical ext (k | k) (l | l) · simp [ω, e, f] @@ -351,7 +351,7 @@ lemma e_lie_u (i j : b.support) : lemma e_lie_v_ne {i j : ι} {k : b.support} (h : P.root j = P.root k + P.root i) : ⁅e k, v b i⁆ = (P.chainBotCoeff k i + 1 : R) • v b j := by - letI := P.indexNeg + let := P.indexNeg ext (l | l) · replace h : i ≠ -k := by rintro rfl; exact P.ne_zero j <| by simpa using h simp [e, h, -indexNeg_neg] diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean index f5504e6ef84b64..d28b0e379d952a 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean @@ -212,7 +212,7 @@ private lemma chainBotCoeff_mul_chainTopCoeff.aux_1 intro _ him_mem hjl_mem hjk_mem /- Setup some typeclasses and name the 6th root `n`. -/ have := chainBotCoeff_mul_chainTopCoeff.isNotG2 hi hj hij h₁ h₂ h₃ - letI := P.indexNeg + let := P.indexNeg have : IsAddTorsionFree M := .of_isTorsionFree R M obtain ⟨n, hn⟩ := h₃ /- Establish basic relationships about roots and their sums / differences. -/ @@ -272,7 +272,7 @@ private lemma chainBotCoeff_mul_chainTopCoeff.aux_2 P.root j + P.root (-k) ∈ range P.root → ¬ (P.chainBotCoeff i m = 1 ∧ P.chainBotCoeff j (-l) = 0) := by intro _ him_mem hjl_mem hjk_mem - letI := P.indexNeg + let := P.indexNeg /- Setup some typeclasses. -/ have := chainBotCoeff_mul_chainTopCoeff.isNotG2 hi hj hij h₁ h₂ h₃ have : IsAddTorsionFree M := .of_isTorsionFree R M @@ -338,7 +338,7 @@ lemma chainBotCoeff_mul_chainTopCoeff : (P.chainTopCoeff j l + 1) * (P.chainBotCoeff i k + 1) := by /- Setup some typeclasses. -/ have := chainBotCoeff_mul_chainTopCoeff.isNotG2 hi hj hij h₁ h₂ h₃ - letI := P.indexNeg + let := P.indexNeg suffices (P.chainBotCoeff i m + 1) * (P.chainBotCoeff j (-k) + 1) = (P.chainBotCoeff j (-l) + 1) * (P.chainBotCoeff i k + 1) by simpa /- Establish basic relationships about roots and their sums / differences. -/ diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean index d593b9de77e832..adc05655bb9d2e 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean @@ -139,7 +139,7 @@ private lemma lie_e_f_same_aux (k : ι) (hki : k ≠ i) (hki' : k ≠ P.reflecti /-- Lemma 3.4 from [Geck](Geck2017). -/ lemma lie_e_f_same : ⁅e i, f i⁆ = h i := by - letI := P.indexNeg + let := P.indexNeg have : Module.IsReflexive R M := .of_isPerfPair P.toLinearMap have : IsAddTorsionFree M := .of_isTorsionFree R M classical @@ -205,7 +205,7 @@ omit [P.IsReduced] private lemma lie_e_f_ne_aux₀ (k : b.support) (l : ι) : ⁅e i, f j⁆ (Sum.inl k) (Sum.inr l) = 0 := by classical - letI := P.indexNeg + let := P.indexNeg have aux₁ : ∀ x ∈ Finset.univ, ¬ (P.root x = P.root i + P.root l ∧ k = j ∧ x = j) := by rintro x - ⟨hl, -, rfl⟩ exact b.sub_notMem_range_root i.property j.property ⟨-l, by simp [hl]⟩ @@ -221,7 +221,7 @@ include hij private lemma lie_e_f_ne_aux₁ : ⁅e i, f j⁆ᵀ (Sum.inr j) = 0 := by have hij' : (i : ι) ≠ (j : ι) := hij ∘ SetLike.coe_eq_coe.mp - letI := P.indexNeg + let := P.indexNeg classical ext (k | k) · rw [Matrix.transpose_apply, lie_e_f_ne_aux₀, Pi.zero_apply] @@ -252,7 +252,7 @@ private lemma lie_e_f_ne_aux₁ : private lemma lie_e_f_ne_aux₂ : letI := P.indexNeg ⁅e i, f j⁆ᵀ (Sum.inr (-i)) = 0 := by - letI := P.indexNeg + let := P.indexNeg classical ext (k | k) · rw [Matrix.transpose_apply, lie_e_f_ne_aux₀, Pi.zero_apply] @@ -265,7 +265,7 @@ private lemma lie_e_f_ne_aux₂ : lemma lie_e_f_ne [P.IsReduced] [P.IsIrreducible] : ⁅e i, f j⁆ = 0 := by have hij' : (i : ι) ≠ (j : ι) := hij ∘ SetLike.coe_eq_coe.mp - letI := P.indexNeg + let := P.indexNeg classical ext (k | k) (l | l) · rw [ne_comm] at hij diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean index 80afc55a86c57b..c076a6eb4574ff 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean @@ -54,7 +54,7 @@ private lemma isNilpotent_e_aux {j : ι} (n : ℕ) (h : letI _i := P.indexNeg; j (e i ^ n).col (.inr j) = x • Pi.single (.inr k) 1 := by have : Module.IsReflexive R M := .of_isPerfPair P.toLinearMap have : IsAddTorsionFree M := .of_isTorsionFree R M - letI := P.indexNeg + let := P.indexNeg have aux (n : ℕ) : (e i ^ (n + 1)).col (.inr j) = (e i).mulVec ((e i ^ n).col (.inr j)) := by rw [pow_succ', ← Matrix.mulVec_single_one, ← Matrix.mulVec_mulVec]; simp induction n with @@ -100,7 +100,7 @@ lemma isNilpotent_e : classical have : Module.IsReflexive R M := .of_isPerfPair P.toLinearMap have : IsAddTorsionFree M := .of_isTorsionFree R M - letI := P.indexNeg + let := P.indexNeg rw [Matrix.isNilpotent_iff_forall_col] have case_inl (j : b.support) : (e i ^ 2).col (Sum.inl j) = 0 := by ext (k | k) @@ -151,7 +151,7 @@ omit [P.IsReduced] [IsDomain R] [DecidableEq ι] in @[simp] lemma trace_h_eq_zero : (h i).trace = 0 := by classical - letI _i := P.indexNeg + let _i := P.indexNeg suffices ∑ j, P.pairingIn ℤ j i = 0 by simp only [h_eq_diagonal, Matrix.trace_diagonal, Fintype.sum_sum_type, Finset.univ_eq_attach, Sum.elim_inl, Pi.zero_apply, Finset.sum_const_zero, Sum.elim_inr, zero_add] @@ -270,7 +270,7 @@ omit [P.IsRootSystem] in private lemma instIsIrreducible_aux₂ [P.IsReduced] [P.IsIrreducible] {U : LieSubmodule K (lieAlgebra b) (b.support ⊕ ι → K)} {i : ι} (hi : v b i ∈ U) : U = ⊤ := by - letI _i := P.indexNeg + let _i := P.indexNeg have hωu (i : b.support) : ω b *ᵥ (u i) = u i := by ext (j | j) <;> simp [ω, u, Pi.single_apply, one_apply] have hωv (i : ι) : ω b *ᵥ (v b i) = v b (-i) := by ext (j | j) <;> simp [ω, v, Pi.single_apply] diff --git a/Mathlib/LinearAlgebra/RootSystem/Hom.lean b/Mathlib/LinearAlgebra/RootSystem/Hom.lean index 8bf34ac72f09d8..8b3cac1a050cf5 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Hom.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Hom.lean @@ -226,7 +226,7 @@ lemma coweightHom_injective (P : RootPairing ι R M N) : Injective (coweightHom have h := congrArg (LinearMap.comp (M₃ := Module.Dual R M) (σ₂₃ := .id R) P.flip.toPerfPair) hfg rw [← f.weight_coweight_transpose, ← g.weight_coweight_transpose] at h have : f.weightMap = g.weightMap := by - haveI : Module.IsReflexive R M := .of_isPerfPair P.toLinearMap + have : Module.IsReflexive R M := .of_isPerfPair P.toLinearMap refine (Module.dualMap_dualMap_eq_iff R M).mp (congrArg LinearMap.dualMap ((LinearEquiv.eq_comp_toLinearMap_iff f.weightMap.dualMap g.weightMap.dualMap).mp h)) exact congrFun (congrArg DFunLike.coe this) x diff --git a/Mathlib/LinearAlgebra/Semisimple.lean b/Mathlib/LinearAlgebra/Semisimple.lean index 099bf504ffefdf..b1f03b5a9386d0 100644 --- a/Mathlib/LinearAlgebra/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Semisimple.lean @@ -223,7 +223,7 @@ theorem isSemisimple_of_squarefree_aeval_eq_zero {p : K[X]} have : FiniteDimensional K R := (AdjoinRoot.powerBasis hp.ne_zero).finite have : IsArtinianRing R := .of_finite K R have : IsSemisimpleRing R := IsArtinianRing.isSemisimpleRing_of_isReduced R - letI : Module R (AEval' f) := Module.IsTorsionBySet.module hpf + let : Module R (AEval' f) := Module.IsTorsionBySet.module hpf let e : AEval' f →ₛₗ[Ideal.Quotient.mk (Ideal.span {p})] AEval' f := { AddMonoidHom.id _ with map_smul' := fun _ _ ↦ rfl } exact (e.isSemisimpleModule_iff_of_bijective bijective_id).mpr inferInstance diff --git a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean index 704c34f0748b31..0c7432ee0cca7a 100644 --- a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean @@ -286,8 +286,8 @@ variable {R} @[simp] theorem ι_eq_algebraMap_iff (x : M) (r : R) : ι R x = algebraMap R _ r ↔ x = 0 ∧ r = 0 := by refine ⟨fun h => ?_, ?_⟩ - · letI : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) - haveI : IsCentralScalar R M := ⟨fun r m => rfl⟩ + · let : Module Rᵐᵒᵖ M := Module.compHom _ ((RingHom.id R).fromOpposite mul_comm) + have : IsCentralScalar R M := ⟨fun r m => rfl⟩ have hf0 : toTrivSqZeroExt (ι R x) = (0, x) := lift_ι_apply _ _ rw [h, AlgHom.commutes] at hf0 have : r = 0 ∧ 0 = x := Prod.ext_iff.1 hf0 diff --git a/Mathlib/LinearAlgebra/Trace.lean b/Mathlib/LinearAlgebra/Trace.lean index 74e07668dda7cc..e963d728cee9ab 100644 --- a/Mathlib/LinearAlgebra/Trace.lean +++ b/Mathlib/LinearAlgebra/Trace.lean @@ -302,10 +302,10 @@ theorem trace_conj' (f : M →ₗ[R] M) (e : M ≃ₗ[R] N) : trace R N (e.conj classical by_cases hM : ∃ s : Finset M, Nonempty (Basis s R M) · obtain ⟨s, ⟨b⟩⟩ := hM - haveI := Module.Finite.of_basis b - haveI := (Module.free_def R M).mpr ⟨_, ⟨b⟩⟩ - haveI := Module.Finite.of_basis (b.map e) - haveI := (Module.free_def R N).mpr ⟨_, ⟨(b.map e).reindex (e.toEquiv.image _)⟩⟩ + have := Module.Finite.of_basis b + have := (Module.free_def R M).mpr ⟨_, ⟨b⟩⟩ + have := Module.Finite.of_basis (b.map e) + have := (Module.free_def R N).mpr ⟨_, ⟨(b.map e).reindex (e.toEquiv.image _)⟩⟩ rw [e.conj_apply, trace_comp_comm', ← comp_assoc, LinearEquiv.comp_coe, LinearEquiv.self_trans_symm, LinearEquiv.refl_toLinearMap, id_comp] · rw [trace, trace, dif_neg hM, dif_neg ?_, zero_apply, zero_apply] diff --git a/Mathlib/Logic/Denumerable.lean b/Mathlib/Logic/Denumerable.lean index 64df6daf6dd46f..5aaaa995d10a59 100644 --- a/Mathlib/Logic/Denumerable.lean +++ b/Mathlib/Logic/Denumerable.lean @@ -94,7 +94,7 @@ def ofEquiv (α) {β} [Denumerable α] (e : β ≃ α) : Denumerable β := @[simp] theorem ofEquiv_ofNat (α) {β} [Denumerable α] (e : β ≃ α) (n) : @ofNat β (ofEquiv _ e) n = e.symm (ofNat α n) := by - letI := ofEquiv _ e + let := ofEquiv _ e refine ofNat_of_decode ?_ rw [decode_ofEquiv e] simp diff --git a/Mathlib/Logic/Equiv/Fin/Rotate.lean b/Mathlib/Logic/Equiv/Fin/Rotate.lean index 81a6d5d4778c7a..8553b11f066640 100644 --- a/Mathlib/Logic/Equiv/Fin/Rotate.lean +++ b/Mathlib/Logic/Equiv/Fin/Rotate.lean @@ -128,8 +128,8 @@ theorem finRotate_symm_lt_iff_ne_zero [NeZero n] (i : Fin n) : def finCycle (k : Fin n) : Equiv.Perm (Fin n) where toFun i := i + k invFun i := i - k - left_inv i := by haveI := NeZero.of_pos k.pos; simp - right_inv i := by haveI := NeZero.of_pos k.pos; simp + left_inv i := by have := NeZero.of_pos k.pos; simp + right_inv i := by have := NeZero.of_pos k.pos; simp lemma finCycle_eq_finRotate_iterate {k : Fin n} : finCycle k = (finRotate n)^[k.1] := by match n with diff --git a/Mathlib/Logic/Equiv/List.lean b/Mathlib/Logic/Equiv/List.lean index 06a9ad7ac808f8..e0925ea0fd802b 100644 --- a/Mathlib/Logic/Equiv/List.lean +++ b/Mathlib/Logic/Equiv/List.lean @@ -64,7 +64,7 @@ instance _root_.List.encodable : Encodable (List α) := ⟨encodeList, decodeList, decodeList_encodeList_eq_self⟩ instance _root_.List.countable {α : Type*} [Countable α] : Countable (List α) := by - haveI := Encodable.ofCountable α + have := Encodable.ofCountable α infer_instance @[simp] diff --git a/Mathlib/Logic/Nontrivial/Basic.lean b/Mathlib/Logic/Nontrivial/Basic.lean index 3d557a0ff7a017..d0eec00ab8e63f 100644 --- a/Mathlib/Logic/Nontrivial/Basic.lean +++ b/Mathlib/Logic/Nontrivial/Basic.lean @@ -68,7 +68,7 @@ variable {I : Type*} {f : I → Type*} theorem nontrivial_at (i' : I) [inst : ∀ i, Nonempty (f i)] [Nontrivial (f i')] : Nontrivial (∀ i : I, f i) := by classical - letI := Classical.decEq (∀ i : I, f i) + let := Classical.decEq (∀ i : I, f i) exact (Function.update_injective (fun i ↦ Classical.choice (inst i)) i').nontrivial /-- As a convenience, provide an instance automatically if `(f default)` is nontrivial. diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean index 2a9879dab3d43c..cb37da1a32f73c 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean @@ -201,7 +201,7 @@ theorem exists_borelSpace_of_countablyGenerated_of_separatesPoints (α : Type*) [m : MeasurableSpace α] [CountablyGenerated α] [SeparatesPoints α] : ∃ _ : TopologicalSpace α, SecondCountableTopology α ∧ T4Space α ∧ BorelSpace α := by rcases measurableEquiv_nat_bool_of_countablyGenerated α with ⟨s, ⟨f⟩⟩ - letI := induced f inferInstance + let := induced f inferInstance let F := f.toEquiv.toHomeomorphOfIsInducing <| .induced _ exact ⟨inferInstance, F.secondCountableTopology, F.symm.t4Space, f.measurableEmbedding.borelSpace F.isInducing⟩ diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean index 69fa66fdf6c2eb..15bbffb72192fe 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metrizable.lean @@ -31,7 +31,7 @@ measurable. -/ theorem measurable_of_tendsto_metrizable' {ι} {f : ι → α → β} {g : α → β} (u : Filter ι) [NeBot u] [IsCountablyGenerated u] (hf : ∀ i, Measurable (f i)) (lim : Tendsto f u (𝓝 g)) : Measurable g := by - letI : PseudoMetricSpace β := pseudoMetrizableSpacePseudoMetric β + let : PseudoMetricSpace β := pseudoMetrizableSpacePseudoMetric β apply measurable_of_isClosed' intro s h1s h2s h3s have : Measurable fun x => infNndist (g x) s := by diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index 20c22dc9b98969..1bc877ce80b251 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -55,7 +55,7 @@ variable [TopologicalSpace α] [SecondCountableTopology α] [LinearOrder α] [Or theorem borel_eq_generateFrom_Iio : borel α = .generateFrom (range Iio) := by refine le_antisymm ?_ (generateFrom_le ?_) · rw [borel_eq_generateFrom_of_subbasis (@OrderTopology.topology_eq_generate_intervals α _ _ _)] - letI : MeasurableSpace α := MeasurableSpace.generateFrom (range Iio) + let : MeasurableSpace α := MeasurableSpace.generateFrom (range Iio) have H : ∀ a : α, MeasurableSet (Iio a) := fun a => GenerateMeasurable.basic _ ⟨_, rfl⟩ refine generateFrom_le ?_ rintro _ ⟨a, rfl | rfl⟩ @@ -296,7 +296,7 @@ theorem Dense.borel_eq_generateFrom_Icc_mem_aux {α : Type*} [TopologicalSpace borel α = .generateFrom {S : Set α | ∃ l ∈ s, ∃ u ∈ s, l ≤ u ∧ Icc l u = S} := by set S : Set (Set α) := { S | ∃ l ∈ s, ∃ u ∈ s, l ≤ u ∧ Icc l u = S } refine le_antisymm ?_ (generateFrom_Icc_mem_le_borel _ _) - letI : MeasurableSpace α := generateFrom S + let : MeasurableSpace α := generateFrom S rw [borel_eq_generateFrom_Iio] refine generateFrom_le (forall_mem_range.2 fun a => ?_) rcases hd.exists_countable_dense_subset_bot_top with ⟨t, hts, hc, htd, htb, -⟩ @@ -357,7 +357,7 @@ theorem Dense.borel_eq_generateFrom_Ico_mem_aux {α : Type*} [TopologicalSpace borel α = .generateFrom { S : Set α | ∃ l ∈ s, ∃ u ∈ s, l < u ∧ Ico l u = S } := by set S : Set (Set α) := { S | ∃ l ∈ s, ∃ u ∈ s, l < u ∧ Ico l u = S } refine le_antisymm ?_ (generateFrom_Ico_mem_le_borel _ _) - letI : MeasurableSpace α := generateFrom S + let : MeasurableSpace α := generateFrom S rw [borel_eq_generateFrom_Iio] refine generateFrom_le (forall_mem_range.2 fun a => ?_) rcases hd.exists_countable_dense_subset_bot_top with ⟨t, hts, hc, htd, htb, -⟩ @@ -745,7 +745,7 @@ theorem AEMeasurable.isLUB {ι} {μ : Measure δ} [Countable ι] {f : ι → δ AEMeasurable g μ := by classical nontriviality α - haveI hα : Nonempty α := inferInstance + have hα : Nonempty α := inferInstance rcases isEmpty_or_nonempty ι with hι | hι · simp only [IsEmpty.exists_iff, setOf_false, isLUB_empty_iff] at hg exact aemeasurable_const' (hg.mono fun a ha => hg.mono fun b hb => (ha _).antisymm (hb _)) @@ -959,7 +959,7 @@ protected theorem Measurable.sInf {ι} {f : ι → δ → α} {s : Set ι} (hs : theorem Measurable.biSup {ι} (s : Set ι) {f : ι → δ → α} (hs : s.Countable) (hf : ∀ i ∈ s, Measurable (f i)) : Measurable fun b => ⨆ i ∈ s, f i b := by - haveI : Encodable s := hs.toEncodable + have : Encodable s := hs.toEncodable by_cases H : ∀ i, i ∈ s · have : ∀ b, ⨆ i ∈ s, f i b = ⨆ (i : s), f i b := fun b ↦ cbiSup_eq_of_forall (f := fun i ↦ f i b) H diff --git a/Mathlib/MeasureTheory/Constructions/Pi.lean b/Mathlib/MeasureTheory/Constructions/Pi.lean index c025ed63bbb813..1e8728a5b51a1f 100644 --- a/Mathlib/MeasureTheory/Constructions/Pi.lean +++ b/Mathlib/MeasureTheory/Constructions/Pi.lean @@ -219,7 +219,7 @@ theorem pi_pi_aux [∀ i, SigmaFinite (μ i)] (s : ∀ i, Set (α i)) (hs : ∀ refine le_antisymm ?_ ?_ · rw [Measure.pi, toMeasure_apply _ _ (MeasurableSet.pi countable_univ fun i _ => hs i)] apply OuterMeasure.pi_pi_le - · haveI : Encodable ι := Fintype.toEncodable ι + · have : Encodable ι := Fintype.toEncodable ι simp_rw [← pi'_pi μ s, Measure.pi, toMeasure_apply _ _ (MeasurableSet.pi countable_univ fun i _ => hs i)] suffices (pi' μ).toOuterMeasure ≤ OuterMeasure.pi fun i => (μ i).toOuterMeasure by exact this _ @@ -270,7 +270,7 @@ theorem pi_eq_generateFrom {C : ∀ i, Set (Set (α i))} (generateFrom_eq_pi hC fun i => (h3C i).isCountablySpanning).symm (IsPiSystem.pi h2C) ?_ rintro _ ⟨s, hs, rfl⟩ rw [mem_univ_pi] at hs - haveI := fun i => (h3C i).sigmaFinite + have := fun i => (h3C i).sigmaFinite simp_rw [h₁ s hs, pi_pi_aux μ s fun i => h4C i _ (hs i)] /-- A measure on a finite product space equals the product measure if they are equal on @@ -289,7 +289,7 @@ theorem pi'_eq_pi [Encodable ι] [∀ i, SigmaFinite (μ i)] : pi' μ = Measure. @[simp] theorem pi_pi [∀ i, SigmaFinite (μ i)] (s : (i : ι) → Set (α i)) : Measure.pi μ (pi univ s) = ∏ i, μ i (s i) := by - haveI : Encodable ι := Fintype.toEncodable ι + have : Encodable ι := Fintype.toEncodable ι rw [← pi'_eq_pi, pi'_pi] nonrec theorem pi_univ [∀ i, SigmaFinite (μ i)] : Measure.pi μ univ = ∏ i, μ i univ := by @@ -340,7 +340,7 @@ instance {α : ι → Type*} [∀ i, MeasureSpace (α i)] [∀ i, SigmaFinite (v theorem pi_of_empty {α : Type*} [Fintype α] [IsEmpty α] {β : α → Type*} {m : ∀ a, MeasurableSpace (β a)} (μ : ∀ a : α, Measure (β a)) (x : ∀ a, β a := isEmptyElim) : Measure.pi μ = dirac x := by - haveI : ∀ a, SigmaFinite (μ a) := isEmptyElim + have : ∀ a, SigmaFinite (μ a) := isEmptyElim refine pi_eq fun s _ => ?_ rw [Fintype.prod_empty, dirac_apply_of_mem] exact isEmptyElim (α := α) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index d571c9ee50a733..a229c479854842 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -155,7 +155,7 @@ instance pi_countable {ι : Type*} [Countable ι] {α : ι → Type*} [∀ n, Me inferInstance instance [StandardBorelSpace α] : MeasurableEq α := by - letI := upgradeStandardBorel α + let := upgradeStandardBorel α infer_instance end instances @@ -203,7 +203,7 @@ theorem analyticSet_range_of_polishSpace {β : Type*} [TopologicalSpace β] [Pol theorem _root_.IsOpen.analyticSet_image {β : Type*} [TopologicalSpace β] [PolishSpace β] {s : Set β} (hs : IsOpen s) {f : β → α} (f_cont : Continuous f) : AnalyticSet (f '' s) := by rw [image_eq_range] - haveI : PolishSpace s := hs.polishSpace + have : PolishSpace s := hs.polishSpace exact analyticSet_range_of_polishSpace (f_cont.comp continuous_subtype_val) /-- A set is analytic if and only if it is the continuous image of some Polish space. -/ @@ -255,7 +255,7 @@ theorem AnalyticSet.iInter [hι : Nonempty ι] [Countable ι] [T2Space α] {s : intro n exact isClosed_eq ((f_cont n).comp (continuous_apply n)) ((f_cont i₀).comp (continuous_apply i₀)) - haveI : PolishSpace t := t_closed.polishSpace + have : PolishSpace t := t_closed.polishSpace let F : t → α := fun x => f i₀ ((x : γ) i₀) have F_cont : Continuous F := (f_cont i₀).comp ((continuous_apply i₀).comp continuous_subtype_val) have F_range : range F = ⋂ n : ι, s n := by @@ -297,7 +297,7 @@ theorem AnalyticSet.iUnion [Countable ι] {s : ι → Set α} (hs : ∀ n, Analy theorem _root_.IsClosed.analyticSet [PolishSpace α] {s : Set α} (hs : IsClosed s) : AnalyticSet s := by - haveI : PolishSpace s := hs.polishSpace + have : PolishSpace s := hs.polishSpace rw [← @Subtype.range_val α s] exact analyticSet_range_of_polishSpace continuous_subtype_val @@ -333,7 +333,7 @@ theorem _root_.Measurable.exists_continuous {α β : Type*} [t : TopologicalSpac obtain ⟨b, b_count, -, hb⟩ : ∃ b : Set (Set (range f)), b.Countable ∧ ∅ ∉ b ∧ IsTopologicalBasis b := exists_countable_basis (range f) - haveI : Countable b := b_count.to_subtype + have : Countable b := b_count.to_subtype have : ∀ s : b, IsClopenable (rangeFactorization f ⁻¹' s) := fun s ↦ by apply MeasurableSet.isClopenable exact hf.subtype_mk (hb.isOpen s.2).measurableSet @@ -352,11 +352,11 @@ theorem _root_.MeasurableSet.analyticSet_image {X Y : Type*} [MeasurableSpace X] [StandardBorelSpace X] [TopologicalSpace Y] [MeasurableSpace Y] [OpensMeasurableSpace Y] {f : X → Y} [SecondCountableTopology (range f)] {s : Set X} (hs : MeasurableSet s) (hf : Measurable f) : AnalyticSet (f '' s) := by - letI := upgradeStandardBorel X + let := upgradeStandardBorel X rw [eq_borel_upgradeStandardBorel X] at hs rcases hf.exists_continuous with ⟨τ', hle, hfc, hτ'⟩ - letI m' : MeasurableSpace X := @borel _ τ' - haveI b' : BorelSpace X := ⟨rfl⟩ + let m' : MeasurableSpace X := @borel _ τ' + have b' : BorelSpace X := ⟨rfl⟩ have hle := borel_anti hle exact (hle _ hs).analyticSet.image_of_continuous hfc @@ -478,7 +478,7 @@ theorem measurablySeparable_range_of_disjoint [T2Space α] [MeasurableSpace α] ∃ u v : Set α, IsOpen u ∧ IsOpen v ∧ f x ∈ u ∧ g y ∈ v ∧ Disjoint u v := by apply t2_separation exact disjoint_iff_forall_ne.1 h (mem_range_self _) (mem_range_self _) - letI : MetricSpace (ℕ → ℕ) := metricSpaceNatNat + let : MetricSpace (ℕ → ℕ) := metricSpaceNatNat obtain ⟨εx, εxpos, hεx⟩ : ∃ (εx : ℝ), εx > 0 ∧ Metric.ball x εx ⊆ f ⁻¹' u := by apply Metric.mem_nhds_iff.1 exact hf.continuousAt.preimage_mem_nhds (u_open.mem_nhds xu) @@ -563,7 +563,7 @@ theorem map_measurableSpace_eq [CountablySeparated Z] theorem map_measurableSpace_eq_borel [SecondCountableTopology Y] {f : X → Y} (hf : Measurable f) (hsurj : Surjective f) : MeasurableSpace.map f ‹MeasurableSpace X› = borel Y := by have d := hf.mono le_rfl OpensMeasurableSpace.borel_le - letI := borel Y; haveI : BorelSpace Y := ⟨rfl⟩ + let := borel Y; have : BorelSpace Y := ⟨rfl⟩ exact d.map_measurableSpace_eq hsurj theorem borelSpace_codomain [SecondCountableTopology Y] {f : X → Y} (hf : Measurable f) @@ -678,10 +678,10 @@ theorem MeasureTheory.measurableSet_range_of_continuous_injective {β : Type*} [ the image `f '' (s i)` would be included in `v` by continuity of `f`, so its closure would be contained in the closure of `v`, and therefore it would be disjoint from `w`. This is a contradiction since `x` belongs both to this closure and to `w`. -/ - letI := TopologicalSpace.upgradeIsCompletelyMetrizable γ + let := TopologicalSpace.upgradeIsCompletelyMetrizable γ obtain ⟨b, b_count, b_nonempty, hb⟩ : ∃ b : Set (Set γ), b.Countable ∧ ∅ ∉ b ∧ IsTopologicalBasis b := exists_countable_basis γ - haveI : Encodable b := b_count.toEncodable + have : Encodable b := b_count.toEncodable let A := { p : b × b // Disjoint (p.1 : Set γ) p.2 } -- for each pair of disjoint sets in the topological basis `b`, consider Borel sets separating -- their images, by injectivity of `f` and the Lusin separation theorem. @@ -768,7 +768,7 @@ theorem MeasureTheory.measurableSet_range_of_continuous_injective {β : Type*} [ (add_le_add ((dist_le_diam_of_mem (hs m).1 (hy m) zsm).trans (hs m).2) ((dist_le_diam_of_mem (hs n).1 zsn (hy n)).trans (hs n).2)) _ ≤ 2 * u m := by linarith [u_anti.antitone hmn] - haveI : Nonempty γ := ⟨y 0⟩ + have : Nonempty γ := ⟨y 0⟩ -- let `z` be its limit. let z := limUnder atTop y have y_lim : Tendsto y atTop (𝓝 z) := cauchy_y.tendsto_limUnder @@ -806,7 +806,7 @@ theorem IsClosed.measurableSet_image_of_continuousOn_injOn [MeasurableSpace β] [OpensMeasurableSpace β] {s : Set γ} (hs : IsClosed s) {f : γ → β} (f_cont : ContinuousOn f s) (f_inj : InjOn f s) : MeasurableSet (f '' s) := by rw [image_eq_range] - haveI : PolishSpace s := IsClosed.polishSpace hs + have : PolishSpace s := IsClosed.polishSpace hs apply measurableSet_range_of_continuous_injective · rwa [continuousOn_iff_continuous_restrict] at f_cont · rwa [injOn_iff_injective] at f_inj @@ -836,7 +836,7 @@ theorem MeasurableSet.image_of_measurable_injOn {f : γ → α} [MeasurableSpace γ] [StandardBorelSpace γ] (hs : MeasurableSet s) (f_meas : Measurable f) (f_inj : InjOn f s) : MeasurableSet (f '' s) := by - letI := upgradeStandardBorel γ + let := upgradeStandardBorel γ let tγ : TopologicalSpace γ := inferInstance rcases exists_opensMeasurableSpace_of_countablySeparated α with ⟨τ, _, _, _⟩ -- for a finer Polish topology, `f` is continuous. Therefore, one may apply the corresponding @@ -845,8 +845,8 @@ theorem MeasurableSet.image_of_measurable_injOn {f : γ → α} ∃ t' : TopologicalSpace γ, t' ≤ tγ ∧ @Continuous γ _ t' _ f ∧ @PolishSpace γ t' := f_meas.exists_continuous have hs' := (borel_anti t't s) <| by rwa [← eq_borel_upgradeStandardBorel γ] - letI : MeasurableSpace γ := @borel γ t' - letI : BorelSpace γ := ⟨rfl⟩ + let : MeasurableSpace γ := @borel γ t' + let : BorelSpace γ := ⟨rfl⟩ exact hs'.image_of_continuousOn_injOn f_cont.continuousOn f_inj /-- An injective continuous function on a Polish space is a measurable embedding. -/ @@ -987,7 +987,7 @@ lemma MeasureTheory.measurableSet_tendsto_fun [MeasurableSpace γ] [Countable ι [OpensMeasurableSpace γ] {f : ι → β → γ} (hf : ∀ i, Measurable (f i)) {g : β → γ} (hg : Measurable g) : MeasurableSet { x | Tendsto (fun n ↦ f n x) l (𝓝 (g x)) } := by - letI := TopologicalSpace.pseudoMetrizableSpacePseudoMetric γ + let := TopologicalSpace.pseudoMetrizableSpacePseudoMetric γ simp_rw [tendsto_iff_dist_tendsto_zero (f := fun n ↦ f n _)] exact measurableSet_tendsto (𝓝 0) (fun n ↦ (hf n).dist hg) @@ -1000,7 +1000,7 @@ theorem MeasureTheory.measurableSet_exists_tendsto [TopologicalSpace γ] MeasurableSet { x | ∃ c, Tendsto (fun n => f n x) l (𝓝 c) } := by rcases l.eq_or_neBot with rfl | hl · simp - letI := TopologicalSpace.upgradeIsCompletelyPseudoMetrizable γ + let := TopologicalSpace.upgradeIsCompletelyPseudoMetrizable γ rcases l.exists_antitone_basis with ⟨u, hu⟩ simp_rw [← cauchy_map_iff_exists_tendsto] change MeasurableSet { x | _ ∧ _ } @@ -1097,7 +1097,7 @@ variable [MeasurableSpace α] [StandardBorelSpace α] making `s` clopen. -/ theorem MeasurableSet.isClopenable' {s : Set α} (hs : MeasurableSet s) : ∃ _ : TopologicalSpace α, BorelSpace α ∧ PolishSpace α ∧ IsClosed s ∧ IsOpen s := by - letI := upgradeStandardBorel α + let := upgradeStandardBorel α obtain ⟨t, hle, ht, s_clopen⟩ := hs.isClopenable refine ⟨t, ?_, ht, s_clopen⟩ constructor @@ -1108,7 +1108,7 @@ theorem MeasurableSet.isClopenable' {s : Set α} (hs : MeasurableSet s) : theorem MeasurableSet.standardBorel {s : Set α} (hs : MeasurableSet s) : StandardBorelSpace s := by obtain ⟨_, _, _, s_closed, _⟩ := hs.isClopenable' - haveI := s_closed.polishSpace + have := s_closed.polishSpace infer_instance end StandardBorelSpace @@ -1131,7 +1131,7 @@ noncomputable def borelSchroederBernstein {f : α → β} {g : β → α} (fmeas /-- Any uncountable standard Borel space is Borel isomorphic to the Cantor space `ℕ → Bool`. -/ noncomputable def measurableEquivNatBoolOfNotCountable (h : ¬Countable α) : α ≃ᵐ (ℕ → Bool) := by apply Nonempty.some - letI := upgradeStandardBorel α + let := upgradeStandardBorel α obtain ⟨f, -, fcts, finj⟩ := isClosed_univ.exists_nat_bool_injection_of_not_countable (α := α) (by rwa [← countable_coe_iff, (Equiv.Set.univ _).countable_iff]) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean b/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean index 2582708a2b5916..b3c9f2544b451e 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean @@ -38,7 +38,7 @@ theorem measurableSet_exists_tendsto [IsCompletelyPseudoMetrizableSpace E] obtain rfl | hl := eq_or_neBot l · simp_all borelize E - letI := upgradeIsCompletelyPseudoMetrizable E + let := upgradeIsCompletelyPseudoMetrizable E let s := closure (⋃ i, range (f i)) have : SecondCountableTopology s := @UniformSpace.secondCountable_of_separable s _ _ (IsSeparable.iUnion (fun i ↦ (hf i).isSeparable_range)).closure.separableSpace diff --git a/Mathlib/MeasureTheory/Constructions/Projective.lean b/Mathlib/MeasureTheory/Constructions/Projective.lean index 707e4c914832ab..b963e82a21221e 100644 --- a/Mathlib/MeasureTheory/Constructions/Projective.lean +++ b/Mathlib/MeasureTheory/Constructions/Projective.lean @@ -151,7 +151,7 @@ lemma measure_univ_unique (hμ : IsProjectiveLimit μ P) (hν : IsProjectiveLimi theorem unique [∀ i, IsFiniteMeasure (P i)] (hμ : IsProjectiveLimit μ P) (hν : IsProjectiveLimit ν P) : μ = ν := by - haveI : IsFiniteMeasure μ := hμ.isFiniteMeasure + have : IsFiniteMeasure μ := hμ.isFiniteMeasure refine ext_of_generate_finite (measurableCylinders α) generateFrom_measurableCylinders.symm isPiSystem_measurableCylinders (fun s hs ↦ ?_) (hμ.measure_univ_unique hν) obtain ⟨I, S, hS, rfl⟩ := (mem_measurableCylinders _).mp hs diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index efe2280ce46e21..d76c0537778d51 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -964,7 +964,7 @@ theorem exists_closedBall_covering_tsum_measure_le (μ : Measure α) [SFinite μ (∑' x : t0, μ (closedBall x (r x))) = ∑' x : t0, μ (closedBall x (r0 x)) := by congr 1; ext x; rw [r_t0 x x.2] _ = μ (⋃ x : t0, closedBall x (r0 x)) := by - haveI : Encodable t0 := t0_count.toEncodable + have : Encodable t0 := t0_count.toEncodable rw [measure_iUnion] · exact (pairwise_subtype_iff_pairwise_set _ _).2 t0_disj · exact fun i => measurableSet_closedBall @@ -986,7 +986,7 @@ theorem exists_closedBall_covering_tsum_measure_le (μ : Measure α) [SFinite μ _ = ∑' x : S i, μ (closedBall x (r1 x)) := by grind _ = μ (⋃ x : S i, closedBall x (r1 x)) := by - haveI : Encodable (S i) := (S_count i).toEncodable + have : Encodable (S i) := (S_count i).toEncodable rw [measure_iUnion] · exact (pairwise_subtype_iff_pairwise_set _ _).2 (S_disj i) · exact fun i => measurableSet_closedBall diff --git a/Mathlib/MeasureTheory/Covering/Differentiation.lean b/Mathlib/MeasureTheory/Covering/Differentiation.lean index 7daede20a4718e..d766c48e2e1982 100644 --- a/Mathlib/MeasureTheory/Covering/Differentiation.lean +++ b/Mathlib/MeasureTheory/Covering/Differentiation.lean @@ -137,7 +137,7 @@ theorem measure_le_of_frequently_le [SecondCountableTopology α] [BorelSpace α] apply Frequently.mono this rintro a ⟨ρa, _, aU⟩ exact ⟨ρa, aU⟩ - haveI : Encodable h.index := h.index_countable.toEncodable + have : Encodable h.index := h.index_countable.toEncodable calc ρ s ≤ ∑' x : h.index, ρ (h.covering x) := h.measure_le_tsum_of_absolutelyContinuous hρ _ ≤ ∑' x : h.index, ν (h.covering x) := ENNReal.tsum_le_tsum fun x => (h.covering_mem x.2).1 @@ -708,7 +708,7 @@ almost every point of `s` is a Lebesgue density point for `s`. A version for non holds, but it only gives the first conclusion, see `ae_tendsto_measure_inter_div`. -/ theorem ae_tendsto_measure_inter_div_of_measurableSet {s : Set α} (hs : MeasurableSet s) : ∀ᵐ x ∂μ, Tendsto (fun a => μ (s ∩ a) / μ a) (v.filterAt x) (𝓝 (s.indicator 1 x)) := by - haveI : IsLocallyFiniteMeasure (μ.restrict s) := + have : IsLocallyFiniteMeasure (μ.restrict s) := isLocallyFiniteMeasure_of_le restrict_le_self filter_upwards [ae_tendsto_rnDeriv v (μ.restrict s), rnDeriv_restrict_self μ hs] intro x hx h'x diff --git a/Mathlib/MeasureTheory/Covering/Vitali.lean b/Mathlib/MeasureTheory/Covering/Vitali.lean index f708ea56c5007e..431125f68cf616 100644 --- a/Mathlib/MeasureTheory/Covering/Vitali.lean +++ b/Mathlib/MeasureTheory/Covering/Vitali.lean @@ -414,7 +414,7 @@ theorem exists_disjoint_covering_ae exact subset_iUnion (fun a : { a // a ∉ w } => closedBall (c a) (3 * r a)) b'' -- now that we have proved our main inclusion, we can use it to estimate the measure of the points -- in `ball x (r x)` not covered by `u`. - haveI : Countable v := (u_count.mono vu).to_subtype + have : Countable v := (u_count.mono vu).to_subtype calc μ ((s \ ⋃ a ∈ u, B a) ∩ ball x (R x)) ≤ μ (⋃ a : { a // a ∉ w }, closedBall (c a) (3 * r a)) := measure_mono M diff --git a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean index 78b0a17871d839..26f6a7324eb037 100644 --- a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean +++ b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean @@ -80,7 +80,7 @@ theorem ae_eq_zero_of_forall_dual_of_isSeparable [NormedAddCommGroup E] [NormedS (hf : ∀ c : StrongDual 𝕜 E, (fun x => ⟪f x, c⟫) =ᵐ[μ] 0) (h't : ∀ᵐ x ∂μ, f x ∈ t) : f =ᵐ[μ] 0 := by rcases ht with ⟨d, d_count, hd⟩ - haveI : Encodable d := d_count.toEncodable + have : Encodable d := d_count.toEncodable have : ∀ x : d, ∃ g : StrongDual 𝕜 E, ‖g‖ ≤ 1 ∧ g x = ‖(x : E)‖ := fun x => exists_dual_vector'' 𝕜 (x : E) choose s hs using this @@ -183,7 +183,7 @@ theorem AEFinStronglyMeasurable.ae_nonneg_of_forall_setIntegral_nonneg {f : α let t := hf.sigmaFiniteSet suffices 0 ≤ᵐ[μ.restrict t] f from ae_of_ae_restrict_of_ae_restrict_compl _ this hf.ae_eq_zero_compl.symm.le - haveI : SigmaFinite (μ.restrict t) := hf.sigmaFinite_restrict + have : SigmaFinite (μ.restrict t) := hf.sigmaFinite_restrict refine ae_nonneg_of_forall_setIntegral_nonneg_of_sigmaFinite (fun s hs hμts => ?_) fun s hs hμts => ?_ · rw [IntegrableOn, Measure.restrict_restrict hs] @@ -288,7 +288,7 @@ theorem AEFinStronglyMeasurable.ae_eq_zero_of_forall_setIntegral_eq_zero {f : α let t := hf.sigmaFiniteSet suffices f =ᵐ[μ.restrict t] 0 from ae_of_ae_restrict_of_ae_restrict_compl _ this hf.ae_eq_zero_compl - haveI : SigmaFinite (μ.restrict t) := hf.sigmaFinite_restrict + have : SigmaFinite (μ.restrict t) := hf.sigmaFinite_restrict refine ae_eq_zero_of_forall_setIntegral_eq_of_sigmaFinite ?_ ?_ · intro s hs hμs rw [IntegrableOn, Measure.restrict_restrict hs] @@ -333,7 +333,7 @@ theorem ae_eq_zero_of_forall_setIntegral_eq_of_finStronglyMeasurable_trim (hm : (hf_zero : ∀ s : Set α, MeasurableSet[m] s → μ s < ∞ → ∫ x in s, f x ∂μ = 0) (hf : FinStronglyMeasurable f (μ.trim hm)) : f =ᵐ[μ] 0 := by obtain ⟨t, ht_meas, htf_zero, htμ⟩ := hf.exists_set_sigmaFinite - haveI : SigmaFinite ((μ.restrict t).trim hm) := by rwa [restrict_trim hm μ ht_meas] at htμ + have : SigmaFinite ((μ.restrict t).trim hm) := by rwa [restrict_trim hm μ ht_meas] at htμ have htf_zero : f =ᵐ[μ.restrict tᶜ] 0 := by rw [EventuallyEq, ae_restrict_iff' (MeasurableSet.compl (hm _ ht_meas))] exact Eventually.of_forall htf_zero diff --git a/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean b/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean index 6162320fd09227..6d8e1ddff0ba21 100644 --- a/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean +++ b/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean @@ -40,7 +40,7 @@ theorem MeasureTheory.aemeasurable_of_exist_almost_disjoint_supersets {α : Type { x | f x < p } ⊆ u ∧ { x | q < f x } ⊆ v ∧ μ (u ∩ v) = 0) : AEMeasurable f μ := by classical - haveI : Encodable s := s_count.toEncodable + have : Encodable s := s_count.toEncodable have h' : ∀ p q, ∃ u v, MeasurableSet u ∧ MeasurableSet v ∧ { x | f x < p } ⊆ u ∧ { x | q < f x } ⊆ v ∧ (p ∈ s → q ∈ s → p < q → μ (u ∩ v) = 0) := by intro p q @@ -64,7 +64,7 @@ theorem MeasureTheory.aemeasurable_of_exist_almost_disjoint_supersets {α : Type μ t ≤ ∑' (p : s) (q : ↥(s ∩ Ioi p)), μ (u' p ∩ v p q) := by refine (measure_iUnion_le _).trans ?_ refine ENNReal.tsum_le_tsum fun p => ?_ - haveI := (s_count.mono (s.inter_subset_left (t := Ioi ↑p))).to_subtype + have := (s_count.mono (s.inter_subset_left (t := Ioi ↑p))).to_subtype apply measure_iUnion_le _ ≤ ∑' (p : s) (q : ↥(s ∩ Ioi p)), μ (u p q ∩ v p q) := by gcongr with p q diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean index 3fb364c2e5c72c..7a06aec3ea3e6c 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean @@ -301,7 +301,7 @@ instance [hm : Fact (m ≤ m0)] [CompleteSpace F] [hp : Fact (1 ≤ p)] : theorem isComplete_aestronglyMeasurable [hp : Fact (1 ≤ p)] [CompleteSpace F] (hm : m ≤ m0) : IsComplete {f : Lp F p μ | AEStronglyMeasurable[m] f μ} := by rw [← completeSpace_coe_iff_isComplete] - haveI : Fact (m ≤ m0) := ⟨hm⟩ + have : Fact (m ≤ m0) := ⟨hm⟩ change CompleteSpace (lpMeasSubgroup F m p μ) infer_instance diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean index 11d4636a70d5e6..a82501d2a0f100 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean @@ -113,7 +113,7 @@ theorem condExpL2_indicator_of_measurable (hm : m ≤ m0) (hs : MeasurableSet[m] (condExpL2 E 𝕜 hm (indicatorConstLp 2 (hm s hs) hμs c) : α →₂[μ] E) = indicatorConstLp 2 (hm s hs) hμs c := by rw [condExpL2] - haveI : Fact (m ≤ m0) := ⟨hm⟩ + have : Fact (m ≤ m0) := ⟨hm⟩ have h_mem : indicatorConstLp 2 (hm s hs) hμs c ∈ lpMeas E 𝕜 m 2 μ := mem_lpMeas_indicatorConstLp hm hs hμs let ind := (⟨indicatorConstLp 2 (hm s hs) hμs c, h_mem⟩ : lpMeas E 𝕜 m 2 μ) diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean index 5a13702022a906..8bcb431f846b69 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean @@ -43,7 +43,7 @@ theorem condExp_ae_eq_restrict_zero (hs : MeasurableSet[m] s) (hf : f =ᵐ[μ.re swap; · simp_rw [condExp_of_not_le hm]; rfl by_cases hμm : SigmaFinite (μ.trim hm) swap; · simp_rw [condExp_of_not_sigmaFinite hm hμm]; rfl - haveI : SigmaFinite (μ.trim hm) := hμm + have : SigmaFinite (μ.trim hm) := hμm have : SigmaFinite ((μ.restrict s).trim hm) := by rw [← restrict_trim hm _ hs] exact Restrict.sigmaFinite _ s @@ -78,7 +78,7 @@ theorem condExp_indicator (hf_int : Integrable f μ) (hs : MeasurableSet[m] s) : swap; · simp_rw [condExp_of_not_le hm, Set.indicator_zero']; rfl by_cases hμm : SigmaFinite (μ.trim hm) swap; · simp_rw [condExp_of_not_sigmaFinite hm hμm, Set.indicator_zero']; rfl - haveI : SigmaFinite (μ.trim hm) := hμm + have : SigmaFinite (μ.trim hm) := hμm -- use `have` to perform what should be the first calc step because of an error I don't -- understand have : s.indicator (μ[f | m]) =ᵐ[μ] s.indicator (μ[s.indicator f + sᶜ.indicator f | m]) := by diff --git a/Mathlib/MeasureTheory/Function/FactorsThrough.lean b/Mathlib/MeasureTheory/Function/FactorsThrough.lean index 11d9a0fc7c5160..43e35c7f25ffeb 100644 --- a/Mathlib/MeasureTheory/Function/FactorsThrough.lean +++ b/Mathlib/MeasureTheory/Function/FactorsThrough.lean @@ -78,7 +78,7 @@ then there exists some measurable function `h : Y → Z` such that `g = h ∘ f` theorem _root_.Measurable.exists_eq_measurable_comp [Nonempty Z] [MeasurableSpace Z] [StandardBorelSpace Z] (hg : Measurable[mY.comap f] g) : ∃ h : Y → Z, Measurable h ∧ g = h ∘ f := by - letI := upgradeStandardBorel Z + let := upgradeStandardBorel Z obtain ⟨h, mh, hh⟩ := hg.stronglyMeasurable.exists_eq_measurable_comp exact ⟨h, mh.measurable, hh⟩ diff --git a/Mathlib/MeasureTheory/Function/Jacobian.lean b/Mathlib/MeasureTheory/Function/Jacobian.lean index 4df52b8c00a28a..a641df4f1adc90 100644 --- a/Mathlib/MeasureTheory/Function/Jacobian.lean +++ b/Mathlib/MeasureTheory/Function/Jacobian.lean @@ -219,7 +219,7 @@ theorem exists_closed_cover_approximatesLinearOn_of_hasFDerivWithinAt [SecondCou isClosed_closure.inter isClosed_closedBall -- reindex the sets `K n z p`, to let them only depend on an integer parameter `q`. obtain ⟨F, hF⟩ : ∃ F : ℕ → ℕ × T × ℕ, Function.Surjective F := by - haveI : Encodable T := T_count.toEncodable + have : Encodable T := T_count.toEncodable have : Nonempty T := by rcases hs with ⟨x, xs⟩ rcases s_subset x xs with ⟨n, z, _⟩ @@ -366,7 +366,7 @@ theorem addHaar_image_le_mul_of_det_lt (A : E →L[ℝ] E) {m : ℝ≥0} (∑' x : ↥t, μ (closedBall (↑x) (r ↑x))) ≤ μ s + a := Besicovitch.exists_closedBall_covering_tsum_measure_le μ ha.ne' (fun _ => Ioi 0) s fun x _ δ δpos => ⟨δ / 2, by simp [half_pos δpos, δpos]⟩ - haveI : Encodable t := t_count.toEncodable + have : Encodable t := t_count.toEncodable calc μ (f '' s) ≤ μ (⋃ x : t, f '' (s ∩ closedBall x (r x))) := by rw [biUnion_eq_iUnion] at st diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index cc312fd5c05404..e00aada65caaf8 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -771,8 +771,8 @@ lemma integrable_count_iff : have hs' : (Function.support f).Countable := by simpa only [Ne, Pi.zero_apply, eq_comm, Function.support, norm_eq_zero] using hs.countable_support - letI : MeasurableSpace β := borel β - haveI : BorelSpace β := ⟨rfl⟩ + let : MeasurableSpace β := borel β + have : BorelSpace β := ⟨rfl⟩ refine aestronglyMeasurable_iff_aemeasurable_separable.mpr ⟨?_, ?_⟩ · refine (measurable_zero.measurable_of_countable_ne ?_).aemeasurable simpa only [Ne, Pi.zero_apply, eq_comm, Function.support] using hs' diff --git a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean index 14d1260b68cf3c..d13f2470fe04c4 100644 --- a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean @@ -519,7 +519,7 @@ variable {a : X} theorem integrableOn_Iic_iff_integrableAtFilter_atBot [LinearOrder X] [CompactIccSpace X] : IntegrableOn f (Iic a) μ ↔ IntegrableAtFilter f atBot μ ∧ LocallyIntegrableOn f (Iic a) μ := by refine ⟨fun h ↦ ⟨⟨Iic a, Iic_mem_atBot a, h⟩, h.locallyIntegrableOn⟩, fun ⟨⟨s, hsl, hs⟩, h⟩ ↦ ?_⟩ - haveI : Nonempty X := Nonempty.intro a + have : Nonempty X := Nonempty.intro a obtain ⟨a', ha'⟩ := mem_atBot_sets.mp hsl refine (integrableOn_union.mpr ⟨hs.mono ha' le_rfl, ?_⟩).mono Iic_subset_Iic_union_Icc le_rfl exact h.integrableOn_compact_subset Icc_subset_Iic_self isCompact_Icc diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean index 7b081115e69594..fd5d7b12a712c1 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean @@ -36,7 +36,7 @@ lemma enorm_le_eLpNorm_count (f : α → ε) (i : α) (hp : p ≠ 0) : omit [MeasurableSingletonClass α] in lemma eLpNorm_count_lt_top_of_lt [Finite α] (h : ∀ i, ‖f i‖ₑ < ∞) : eLpNorm f p .count < ∞ := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α refine (eLpNorm_mono_enorm (g := fun _ ↦ Finset.univ.sup (‖f ·‖ₑ)) ?_).trans_lt ?_ · exact fun x ↦ Finset.le_sup (f := (‖f ·‖ₑ)) (Finset.mem_univ x) · exact (memLp_const_enorm <| by simp [h, LT.lt.ne]).eLpNorm_lt_top diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean index 563f5f2398056d..a9a9f4f8b8065e 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean @@ -144,7 +144,7 @@ theorem MemLp.sub {f g : α → E} (hf : MemLp f p μ) (hg : MemLp g p μ) : Mem theorem memLp_finsetSum [ContinuousAdd ε'] {ι} (s : Finset ι) {f : ι → α → ε'} (hf : ∀ i ∈ s, MemLp (f i) p μ) : MemLp (fun a => ∑ i ∈ s, f i a) p μ := by - haveI : DecidableEq ι := Classical.decEq _ + have : DecidableEq ι := Classical.decEq _ revert hf refine Finset.induction_on s ?_ ?_ · simp diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index 3778440c72a4c4..59ed2d5ebb1fb5 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -227,7 +227,7 @@ def dite (s : Set α) (hs : MeasurableSet s) (f : s →ₛ β) (g : (sᶜ : Set toFun x := open scoped Classical in if hx : x ∈ s then f ⟨x, hx⟩ else g ⟨x, hx⟩ measurableSet_fiber' x := by classical - letI : MeasurableSpace β := ⊤ + let : MeasurableSpace β := ⊤ exact Measurable.dite f.measurable g.measurable hs trivial finite_range' := (f.finite_range.union g.finite_range).subset (by grind) @@ -318,7 +318,7 @@ def extend [MeasurableSpace β] (f₁ : α →ₛ γ) (g : α → β) (hg : Meas (f₁.finite_range.union <| f₂.finite_range.subset (image_subset_range _ _)).subset (range_extend_subset _ _ _) measurableSet_fiber' := by - letI : MeasurableSpace γ := ⊤; haveI : MeasurableSingletonClass γ := ⟨fun _ => trivial⟩ + let : MeasurableSpace γ := ⊤; have : MeasurableSingletonClass γ := ⟨fun _ => trivial⟩ exact fun x => hg.measurable_extend f₁.measurable f₂.measurable (measurableSet_singleton _) @[simp] diff --git a/Mathlib/MeasureTheory/Function/SimpleFuncDense.lean b/Mathlib/MeasureTheory/Function/SimpleFuncDense.lean index 6e73d26a9b78c4..bd88e4fb0c77ae 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFuncDense.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFuncDense.lean @@ -131,7 +131,7 @@ theorem approxOn_zero {f : β → α} (hf : Measurable f) {s : Set α} {y₀ : theorem approxOn_mem {f : β → α} (hf : Measurable f) {s : Set α} {y₀ : α} (h₀ : y₀ ∈ s) [SeparableSpace s] (n : ℕ) (x : β) : approxOn f hf s y₀ h₀ n x ∈ s := by - haveI : Nonempty s := ⟨⟨y₀, h₀⟩⟩ + have : Nonempty s := ⟨⟨y₀, h₀⟩⟩ suffices ∀ n, (Nat.casesOn n y₀ ((↑) ∘ denseSeq s) : α) ∈ s by apply this rintro (_ | n) exacts [h₀, Subtype.mem _] @@ -154,7 +154,7 @@ theorem approxOn_comp {γ : Type*} [MeasurableSpace γ] {f : β → α} (hf : Me theorem tendsto_approxOn {f : β → α} (hf : Measurable f) {s : Set α} {y₀ : α} (h₀ : y₀ ∈ s) [SeparableSpace s] {x : β} (hx : f x ∈ closure s) : Tendsto (fun n => approxOn f hf s y₀ h₀ n x) atTop (𝓝 <| f x) := by - haveI : Nonempty s := ⟨⟨y₀, h₀⟩⟩ + have : Nonempty s := ⟨⟨y₀, h₀⟩⟩ rw [← @Subtype.range_coe _ s, ← image_univ, ← (denseRange_denseSeq s).closure_eq] at hx simp -iota only [approxOn, coe_comp] refine tendsto_nearestPt (closure_minimal ?_ isClosed_closure hx) @@ -244,7 +244,7 @@ lemma HasCompactSupport.measurable_of_prod [TopologicalSpace α] [PseudoMetrizableSpace α] [MeasurableSpace α] [BorelSpace α] {f : X × Y → α} (hf : Continuous f) (h'f : HasCompactSupport f) : Measurable f := by - letI : PseudoMetricSpace α := TopologicalSpace.pseudoMetrizableSpacePseudoMetric α + let : PseudoMetricSpace α := TopologicalSpace.pseudoMetrizableSpacePseudoMetric α obtain ⟨u, -, u_pos, u_lim⟩ : ∃ u, StrictAnti u ∧ (∀ (n : ℕ), 0 < u n) ∧ Tendsto u atTop (𝓝 0) := exists_seq_strictAnti_tendsto (0 : ℝ) have : ∀ n, ∃ (g : SimpleFunc (X × Y) α), ∀ x, dist (f x) (g x) < u n := diff --git a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean index 26cd321dd22ecd..f0efda5fe33c7b 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean @@ -652,7 +652,7 @@ lemma isDenseEmbedding (hp_ne_top : p ≠ ∞) : intro f rw [mem_closure_iff_seq_limit] have hfi' : MemLp f p μ := Lp.memLp f - haveI : SeparableSpace (range f ∪ {0} : Set E) := + have : SeparableSpace (range f ∪ {0} : Set E) := (Lp.stronglyMeasurable f).separableSpace_range_union_singleton refine ⟨fun n => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index 2159a038b2d446..2bd25eb785e359 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -674,7 +674,7 @@ theorem _root_.MeasurableEmbedding.aestronglyMeasurable_map_iff {γ : Type*} theorem _root_.Topology.IsEmbedding.aestronglyMeasurable_comp_iff [PseudoMetrizableSpace β] [PseudoMetrizableSpace γ] {g : β → γ} {f : α → β} (hg : IsEmbedding g) : AEStronglyMeasurable (fun x => g (f x)) μ ↔ AEStronglyMeasurable f μ := by - letI := pseudoMetrizableSpacePseudoMetric γ + let := pseudoMetrizableSpacePseudoMetric γ borelize β γ refine ⟨fun H => aestronglyMeasurable_iff_aemeasurable_separable.2 ⟨?_, ?_⟩, fun H => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 3258e70d0b2e8f..450d437d3ad961 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -252,7 +252,7 @@ theorem finStronglyMeasurable_of_set_sigmaFinite [TopologicalSpace β] [Zero β] {m : MeasurableSpace α} {μ : Measure α} (hf_meas : StronglyMeasurable f) {t : Set α} (ht : MeasurableSet t) (hft_zero : ∀ x ∈ tᶜ, f x = 0) (htμ : SigmaFinite (μ.restrict t)) : FinStronglyMeasurable f μ := by - haveI : SigmaFinite (μ.restrict t) := htμ + have : SigmaFinite (μ.restrict t) := htμ let S := spanningSets (μ.restrict t) have hS_meas : ∀ n, MeasurableSet (S n) := measurableSet_spanningSets (μ.restrict t) let f_approx := hf_meas.approx @@ -268,7 +268,7 @@ theorem finStronglyMeasurable_of_set_sigmaFinite [TopologicalSpace β] [Zero β] refine fun n => measure_biUnion_lt_top {y ∈ (fs n).range | y ≠ 0}.finite_toSet fun y hy => ?_ rw [SimpleFunc.restrict_preimage_singleton _ ((hS_meas n).inter ht)] swap - · letI : (y : β) → Decidable (y = 0) := fun y => Classical.propDecidable _ + · let : (y : β) → Decidable (y = 0) := fun y => Classical.propDecidable _ rw [Finset.mem_coe, Finset.mem_filter] at hy exact hy.2 refine (measure_mono Set.inter_subset_left).trans_lt ?_ @@ -685,7 +685,7 @@ variable {mα : MeasurableSpace α} [MeasurableSpace β] theorem _root_.Measurable.stronglyMeasurable [TopologicalSpace β] [PseudoMetrizableSpace β] [SecondCountableTopology β] [OpensMeasurableSpace β] (hf : Measurable f) : StronglyMeasurable f := by - letI := pseudoMetrizableSpacePseudoMetric β + let := pseudoMetrizableSpacePseudoMetric β nontriviality β; inhabit β exact ⟨SimpleFunc.approxOn f hf Set.univ default (Set.mem_univ _), fun x ↦ SimpleFunc.tendsto_approxOn hf (Set.mem_univ _) (by simp)⟩ @@ -733,7 +733,7 @@ theorem _root_.Continuous.stronglyMeasurable_of_mulSupport_subset_isCompact [PseudoMetrizableSpace β] [One β] {f : α → β} (hf : Continuous f) {k : Set α} (hk : IsCompact k) (h'f : mulSupport f ⊆ k) : StronglyMeasurable f := by borelize β - letI : PseudoMetricSpace β := pseudoMetrizableSpacePseudoMetric β + let : PseudoMetricSpace β := pseudoMetrizableSpacePseudoMetric β rw [stronglyMeasurable_iff_measurable_separable] exact ⟨hf.measurable, (isCompact_range_of_mulSupport_subset_isCompact hf hk h'f).isSeparable⟩ @@ -756,14 +756,14 @@ lemma _root_.HasCompactSupport.stronglyMeasurable_of_prod {X Y : Type*} [Zero α StronglyMeasurable f := by borelize α apply stronglyMeasurable_iff_measurable_separable.2 ⟨h'f.measurable_of_prod hf, ?_⟩ - letI : PseudoMetricSpace α := pseudoMetrizableSpacePseudoMetric α + let : PseudoMetricSpace α := pseudoMetrizableSpacePseudoMetric α exact IsCompact.isSeparable (s := range f) (h'f.isCompact_range hf) /-- If `g` is a topological embedding, then `f` is strongly measurable iff `g ∘ f` is. -/ theorem _root_.Embedding.comp_stronglyMeasurable_iff {m : MeasurableSpace α} [TopologicalSpace β] [PseudoMetrizableSpace β] [TopologicalSpace γ] [PseudoMetrizableSpace γ] {g : β → γ} {f : α → β} (hg : IsEmbedding g) : (StronglyMeasurable fun x => g (f x)) ↔ StronglyMeasurable f := by - letI := pseudoMetrizableSpacePseudoMetric γ + let := pseudoMetrizableSpacePseudoMetric γ borelize β γ refine ⟨fun H => stronglyMeasurable_iff_measurable_separable.2 ⟨?_, ?_⟩, fun H => diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean index 9655fb43723819..1e7699373db071 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lp.lean @@ -43,7 +43,7 @@ theorem MemLp.finStronglyMeasurable_of_stronglyMeasurable (hf : MemLp f p μ) (hf_meas : StronglyMeasurable f) (hp_ne_zero : p ≠ 0) (hp_ne_top : p ≠ ∞) : FinStronglyMeasurable f μ := by borelize G - haveI : SeparableSpace (Set.range f ∪ {0} : Set G) := + have : SeparableSpace (Set.range f ∪ {0} : Set G) := hf_meas.separableSpace_range_union_singleton let fs := SimpleFunc.approxOn f hf_meas.measurable (Set.range f ∪ {0}) 0 (by simp) refine ⟨fs, ?_, ?_⟩ diff --git a/Mathlib/MeasureTheory/Group/AddCircle.lean b/Mathlib/MeasureTheory/Group/AddCircle.lean index 1274c8372799de..a15d9fa162de53 100644 --- a/Mathlib/MeasureTheory/Group/AddCircle.lean +++ b/Mathlib/MeasureTheory/Group/AddCircle.lean @@ -80,7 +80,7 @@ theorem isAddFundamentalDomain_of_ae_ball (I : Set <| AddCircle T) (u x : AddCir exact fun g => quasiMeasurePreserving_add_left (G := AddCircle T) volume g · -- `volume univ ≤ ∑' (g : G), volume (g +ᵥ I)` replace hI := hI.trans closedBall_ae_eq_ball.symm - haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype + have : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype have hG_card : #(Finset.univ : Finset G) = n := by change _ = addOrderOf u rw [← Nat.card_zmultiples, Nat.card_eq_fintype_card]; rfl @@ -96,7 +96,7 @@ theorem volume_of_add_preimage_eq (s I : Set <| AddCircle T) (u x : AddCircle T) (hI : I =ᵐ[volume] ball x (T / (2 * addOrderOf u))) : volume s = addOrderOf u • volume (s ∩ I) := by let G := AddSubgroup.zmultiples u - haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype + have : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype have hsG : ∀ g : G, (g +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s := by rintro ⟨y, hy⟩; exact (vadd_ae_eq_self_of_mem_zmultiples hs hy :) rw [(isAddFundamentalDomain_of_ae_ball I u x hu hI).measure_eq_card_smul_of_vadd_ae_eq_self s hsG, diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index 2b2f9959e7d482..c3d2649b7ff7bb 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -287,7 +287,7 @@ is determined by the measure of its intersection with a fundamental domain for t its intersection with a fundamental domain for the action of `G`. -/] theorem measure_eq_card_smul_of_smul_ae_eq_self [Finite G] (h : IsFundamentalDomain G s μ) (t : Set α) (ht : ∀ g : G, (g • t : Set α) =ᵐ[μ] t) : μ t = Nat.card G • μ (t ∩ s) := by - haveI : Fintype G := Fintype.ofFinite G + have : Fintype G := Fintype.ofFinite G rw [h.measure_eq_tsum] replace ht : ∀ g : G, (g • t ∩ s : Set α) =ᵐ[μ] (t ∩ s : Set α) := fun g => ae_eq_set_inter (ht g) (ae_eq_refl s) @@ -783,7 +783,7 @@ theorem IsFundamentalDomain.measurePreserving_quotient_mk MeasurePreserving π (ν.restrict 𝓕) μ where measurable := measurable_quotient_mk' (s := α_mod_G) map_eq := by - haveI : HasFundamentalDomain G α ν := ⟨𝓕, h𝓕⟩ + have : HasFundamentalDomain G α ν := ⟨𝓕, h𝓕⟩ rw [h𝓕.projection_respects_measure (μ := μ)] variable [SMulInvariantMeasure G α ν] [Countable G] [MeasurableConstSMul G α] diff --git a/Mathlib/MeasureTheory/Integral/Asymptotics.lean b/Mathlib/MeasureTheory/Integral/Asymptotics.lean index e942352e0cca11..f7b8fdb328bba5 100644 --- a/Mathlib/MeasureTheory/Integral/Asymptotics.lean +++ b/Mathlib/MeasureTheory/Integral/Asymptotics.lean @@ -72,7 +72,7 @@ theorem IsBigO.eventually_integrableOn [Norm F] obtain ⟨u, hu, v, hv, huv⟩ := Filter.mem_prod_iff.mp htl obtain ⟨w, hwl, hw⟩ := hfm.exists_mem refine eventually_iff_exists_mem.mpr ⟨w ∩ v, inter_mem hwl hv, fun x hx ↦ ?_⟩ - haveI : IsFiniteMeasure (μ.restrict s) := ⟨Measure.restrict_apply_univ s ▸ hμ⟩ + have : IsFiniteMeasure (μ.restrict s) := ⟨Measure.restrict_apply_univ s ▸ hμ⟩ refine Integrable.mono' (integrable_const (C * ‖g x‖)) (hw x hx.1) ?_ filter_upwards [MeasureTheory.self_mem_ae_restrict hs] intro y hy diff --git a/Mathlib/MeasureTheory/Integral/Average.lean b/Mathlib/MeasureTheory/Integral/Average.lean index 4e604f32d5840e..f3829d379218fa 100644 --- a/Mathlib/MeasureTheory/Integral/Average.lean +++ b/Mathlib/MeasureTheory/Integral/Average.lean @@ -379,7 +379,7 @@ theorem average_pair [CompleteSpace E] theorem measure_smul_setAverage (f : α → E) {s : Set α} (h : μ s ≠ ∞) : μ.real s • ⨍ x in s, f x ∂μ = ∫ x in s, f x ∂μ := by - haveI := Fact.mk h.lt_top + have := Fact.mk h.lt_top rw [← measure_smul_average, measureReal_restrict_apply_univ] theorem average_union {f : α → E} {s t : Set α} (hd : AEDisjoint μ s t) (ht : NullMeasurableSet t μ) @@ -387,7 +387,7 @@ theorem average_union {f : α → E} {s t : Set α} (hd : AEDisjoint μ s t) (ht ⨍ x in s ∪ t, f x ∂μ = (μ.real s / (μ.real s + μ.real t)) • ⨍ x in s, f x ∂μ + (μ.real t / (μ.real s + μ.real t)) • ⨍ x in t, f x ∂μ := by - haveI := Fact.mk hsμ.lt_top; haveI := Fact.mk htμ.lt_top + have := Fact.mk hsμ.lt_top; have := Fact.mk htμ.lt_top rw [restrict_union₀ hd ht, average_add_measure hfs hft, measureReal_restrict_apply_univ, measureReal_restrict_apply_univ] @@ -500,7 +500,7 @@ theorem measure_le_setAverage_pos (hμ : μ s ≠ 0) (hμ₁ : μ s ≠ ∞) (hf replace H : (μ.restrict s) {x | f x ≤ ⨍ a in s, f a ∂μ} = 0 := by rwa [restrict_apply₀, inter_comm] exact AEStronglyMeasurable.nullMeasurableSet_le hf.1 aestronglyMeasurable_const - haveI := Fact.mk hμ₁.lt_top + have := Fact.mk hμ₁.lt_top refine (integral_sub_average (μ.restrict s) f).not_gt ?_ refine (setIntegral_pos_iff_support_of_nonneg_ae ?_ ?_).2 ?_ · refine measure_mono_null (fun x hx ↦ ?_) H diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index 64877fbe3b945b..5aab70490dd61e 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -1269,7 +1269,7 @@ theorem integral_trim (hm : m ≤ m0) {f : β → G} (hf : StronglyMeasurable[m] · have hf_int_m : ¬Integrable f (μ.trim hm) := fun hf_int_m => hf_int (integrable_of_integrable_trim hm hf_int_m) rw [integral_undef hf_int, integral_undef hf_int_m] - haveI : SeparableSpace (range f ∪ {0} : Set G) := hf.separableSpace_range_union_singleton + have : SeparableSpace (range f ∪ {0} : Set G) := hf.separableSpace_range_union_singleton let f_seq := @SimpleFunc.approxOn G β _ _ _ m _ hf.measurable (range f ∪ {0}) 0 (by simp) _ have hf_seq_meas : ∀ n, StronglyMeasurable[m] (f_seq n) := fun n => @SimpleFunc.stronglyMeasurable β G m _ (f_seq n) @@ -1325,7 +1325,7 @@ theorem eLpNorm_one_le_of_le {r : ℝ≥0} (hfint : Integrable f μ) (hfint' : 0 · exact le_top · simp [hr] · simp - haveI := hμ + have := hμ rw [integral_eq_integral_pos_part_sub_integral_neg_part hfint, sub_nonneg] at hfint' have hposbdd : ∫ ω, max (f ω) 0 ∂μ ≤ μ.real Set.univ • (r : ℝ) := by rw [← integral_const] diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean index b1dce490b5b59a..30d05807d0b676 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean @@ -588,7 +588,7 @@ theorem setIntegral_map_equiv {Y} [MeasurableSpace Y] (e : X ≃ᵐ Y) (f : Y theorem norm_setIntegral_le_of_norm_le_const_ae {C : ℝ} (hs : μ s < ∞) (hC : ∀ᵐ x ∂μ.restrict s, ‖f x‖ ≤ C) : ‖∫ x in s, f x ∂μ‖ ≤ C * μ.real s := by rw [← Measure.restrict_apply_univ] at * - haveI : IsFiniteMeasure (μ.restrict s) := ⟨hs⟩ + have : IsFiniteMeasure (μ.restrict s) := ⟨hs⟩ simpa using norm_integral_le_of_norm_le_const hC theorem norm_setIntegral_le_of_norm_le_const_ae' {C : ℝ} (hs : μ s < ∞) @@ -1010,7 +1010,7 @@ theorem LpToLpRestrictCLM_coeFn [Fact (1 ≤ p)] (s : Set X) (f : Lp F p μ) : @[continuity] theorem continuous_setIntegral [NormedSpace ℝ E] (s : Set X) : Continuous fun f : X →₁[μ] E => ∫ x in s, f x ∂μ := by - haveI : Fact ((1 : ℝ≥0∞) ≤ 1) := ⟨le_rfl⟩ + have : Fact ((1 : ℝ≥0∞) ≤ 1) := ⟨le_rfl⟩ have h_comp : (fun f : X →₁[μ] E => ∫ x in s, f x ∂μ) = integral (μ.restrict s) ∘ fun f => LpToLpRestrictCLM X E ℝ μ 1 s f := by diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index dd62fc98ff3080..f0909f581d93b8 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -309,7 +309,7 @@ theorem curveIntegral_segment [NormedSpace ℝ E] [NormedSpace ℝ F] (ω : E @[simp] theorem curveIntegral_segment_const [NormedSpace ℝ E] [CompleteSpace F] (ω : E →L[𝕜] F) (a b : E) : ∫ᶜ _ in .segment a b, ω = ω (b - a) := by - letI : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F + let : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F simp [curveIntegral_segment] /-- If `‖ω z‖ ≤ C` at all points of the segment `[a -[ℝ] b]`, @@ -317,7 +317,7 @@ then the curve integral `∫ᶜ x in .segment a b, ω x` has norm at most `C * theorem norm_curveIntegral_segment_le [NormedSpace ℝ E] {C : ℝ} (h : ∀ z ∈ [a -[ℝ] b], ‖ω z‖ ≤ C) : ‖∫ᶜ x in .segment a b, ω x‖ ≤ C * ‖b - a‖ := calc ‖∫ᶜ x in .segment a b, ω x‖ ≤ C * ‖b - a‖ * |1 - 0| := by - letI : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F + let : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F rw [curveIntegral_segment] refine intervalIntegral.norm_integral_le_of_norm_le_const fun t ht ↦ ?_ rw [segment_eq_image_lineMap] at h @@ -360,7 +360,7 @@ protected theorem CurveIntegrable.add (h₁ : CurveIntegrable ω₁ γ) (h₂ : -- TODO: `to_fun` generates wrong lemma name theorem curveIntegral_add (h₁ : CurveIntegrable ω₁ γ) (h₂ : CurveIntegrable ω₂ γ) : curveIntegral (ω₁ + ω₂) γ = ∫ᶜ x in γ, ω₁ x + ∫ᶜ x in γ, ω₂ x := by - letI : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F + let : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F simp only [curveIntegral, curveIntegralFun_add] exact intervalIntegral.integral_add h₁ h₂ @@ -436,7 +436,7 @@ variable {𝕝 : Type*} [RCLike 𝕝] [NormedSpace 𝕝 F] [NormedSpace 𝕝 E] theorem curveIntegralFun_restrictScalars : curveIntegralFun (fun t ↦ (ω t).restrictScalars 𝕝) γ = curveIntegralFun ω γ := by ext - letI : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E + let : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E simp [curveIntegralFun_def] @[simp] @@ -447,7 +447,7 @@ theorem curveIntegrable_restrictScalars_iff : @[simp] theorem curveIntegral_restrictScalars : ∫ᶜ x in γ, (ω x).restrictScalars 𝕝 = ∫ᶜ x in γ, ω x := by - letI : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F + let : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F simp [curveIntegral_def] end RestrictScalars @@ -473,7 +473,7 @@ theorem curveIntegrable_smul_iff : CurveIntegrable (c • ω) γ ↔ c = 0 ∨ C @[simp] theorem curveIntegral_smul : curveIntegral (c • ω) γ = c • curveIntegral ω γ := by - letI : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F + let : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F simp [curveIntegral_def, intervalIntegral.integral_smul] @[simp] diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean index 0a2ea18dc93e94..a87cb3a0d2a5d2 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean @@ -395,7 +395,7 @@ variable [CompleteSpace E] {f : 𝕜 → E} {s : Set 𝕜} then it admits a primitive. -/ theorem exists_forall_hasDerivWithinAt (hs : Convex ℝ s) (hf : DifferentiableOn 𝕜 f s) : ∃ g : 𝕜 → E, ∀ a ∈ s, HasDerivWithinAt g (f a) s a := by - letI : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E + let : NormedSpace ℝ E := .restrictScalars ℝ 𝕜 E apply hs.exists_forall_hasFDerivWithinAt_of_hasFDerivWithinAt_symmetric · intro a ha exact (ContinuousLinearMap.smulRightL 𝕜 𝕜 E 1).hasFDerivAt diff --git a/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean b/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean index 1a9b39c030e3d8..934e06eb232299 100644 --- a/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean +++ b/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean @@ -606,7 +606,7 @@ theorem setToSimpleFunc_indicator (T : Set α → F →L[ℝ] F') (hT_empty : T setToSimpleFunc_zero_apply] simp_rw [setToSimpleFunc] obtain rfl | hs_univ := eq_or_ne s univ - · haveI hα := hs_empty.to_type + · have hα := hs_empty.to_type simp [← Function.const_def] rw [range_indicator hs hs_empty hs_univ] by_cases hx0 : x = 0 diff --git a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean index f487a4f34cfd7c..cc0a24004fb02a 100644 --- a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean +++ b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean @@ -470,7 +470,7 @@ theorem integrableOn_Lp_of_measure_ne_top {E} [NormedAddCommGroup E] {p : ℝ≥ refine memLp_one_iff_integrable.mp ?_ have hμ_restrict_univ : (μ.restrict s) Set.univ < ∞ := by simpa only [Set.univ_inter, MeasurableSet.univ, Measure.restrict_apply, lt_top_iff_ne_top] - haveI hμ_finite : IsFiniteMeasure (μ.restrict s) := ⟨hμ_restrict_univ⟩ + have hμ_finite : IsFiniteMeasure (μ.restrict s) := ⟨hμ_restrict_univ⟩ exact ((Lp.memLp _).restrict s).mono_exponent hp theorem Integrable.lintegral_lt_top {f : α → ℝ} (hf : Integrable f μ) : @@ -749,7 +749,7 @@ theorem ContinuousOn.aestronglyMeasurable_of_isSeparable [TopologicalSpace α] [PseudoMetrizableSpace β] {f : α → β} {s : Set α} {μ : Measure α} (hf : ContinuousOn f s) (hs : MeasurableSet s) (h's : TopologicalSpace.IsSeparable s) : AEStronglyMeasurable f (μ.restrict s) := by - letI := pseudoMetrizableSpacePseudoMetric α + let := pseudoMetrizableSpacePseudoMetric α borelize β rw [aestronglyMeasurable_iff_aemeasurable_separable] refine ⟨hf.aemeasurable hs, f '' s, hf.isSeparable_image h's, ?_⟩ diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean index 4faffca6cfa62f..6cb4b260335c09 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean @@ -398,7 +398,7 @@ theorem measure_integral_sub_integral_sub_linear_isLittleO_of_tendsto_ae ((∫ x in va t..vb t, f x ∂μ) - ∫ x in ua t..ub t, f x ∂μ) - ((∫ _ in ub t..vb t, cb ∂μ) - ∫ _ in ua t..va t, ca ∂μ)) =o[lt] fun t => ‖∫ _ in ua t..va t, (1 : ℝ) ∂μ‖ + ‖∫ _ in ub t..vb t, (1 : ℝ) ∂μ‖ := by - haveI := FTCFilter.meas_gen la; haveI := FTCFilter.meas_gen lb + have := FTCFilter.meas_gen la; have := FTCFilter.meas_gen lb refine ((measure_integral_sub_linear_isLittleO_of_tendsto_ae hmeas_a ha_lim hua hva).neg_left.add_add (measure_integral_sub_linear_isLittleO_of_tendsto_ae hmeas_b hb_lim hub hvb)).congr' diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean index 358f01e9d06fb1..b19f15eb3d8637 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/IntegrationByParts.lean @@ -269,7 +269,7 @@ theorem integral_deriv_smul_comp''' (hf : ContinuousOn f [[a, b]]) exact hf.surjOn_uIcc left_mem_uIcc (Ioo_subset_Icc_self hx) have h3g : StronglyMeasurableAtFilter g (𝓝[J] f x) := hg_cont.stronglyMeasurableAtFilter_nhdsWithin measurableSet_Icc (f x) - haveI : Fact (f x ∈ J) := ⟨h2x⟩ + have : Fact (f x ∈ J) := ⟨h2x⟩ have : HasDerivWithinAt (fun u ↦ ∫ x in f a..u, g x) (g (f x)) J (f x) := intervalIntegral.integral_hasDerivWithinAt_right h2g h3g (hg_cont (f x) h2x) refine (this.scomp x ((hff' x hx).Ioo_of_Ioi hd.1) ?_).Ioi_of_Ioo hd.1 diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean index dfcd118af50d5e..ba16fc6a18c571 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean @@ -350,7 +350,7 @@ theorem intervalIntegral_add_eq (hf : Periodic f T) (t s : ℝ) : simpa only [← sub_eq_add_neg, add_sub_cancel_right] using this hf.neg (t + T) (s + T) (by aesop : 0 < -T) simp only [integral_of_le, hT.le, le_add_iff_nonneg_right] - haveI : VAddInvariantMeasure (AddSubgroup.zmultiples T) ℝ volume := + have : VAddInvariantMeasure (AddSubgroup.zmultiples T) ℝ volume := ⟨fun c s _ => measure_preimage_add _ _ _⟩ apply IsAddFundamentalDomain.setIntegral_eq (G := AddSubgroup.zmultiples T) exacts [isAddFundamentalDomain_Ioc hT t, isAddFundamentalDomain_Ioc hT s, hf.map_vadd_zmultiples] diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean index 2ea6517fac6fcb..8244a70061a28d 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean @@ -588,7 +588,7 @@ theorem lintegral_iUnion [Countable β] {s : β → Set α} (hm : ∀ i, Measura theorem lintegral_biUnion₀ {t : Set β} {s : β → Set α} (ht : t.Countable) (hm : ∀ i ∈ t, NullMeasurableSet (s i) μ) (hd : t.Pairwise (AEDisjoint μ on s)) (f : α → ℝ≥0∞) : ∫⁻ a in ⋃ i ∈ t, s i, f a ∂μ = ∑' i : t, ∫⁻ a in s i, f a ∂μ := by - haveI := ht.toEncodable + have := ht.toEncodable rw [biUnion_eq_iUnion, lintegral_iUnion₀ (SetCoe.forall'.1 hm) (hd.subtype _ _)] theorem lintegral_biUnion {t : Set β} {s : β → Set α} (ht : t.Countable) diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index 4dd785826d3770..b01e9957e1dd42 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -1408,7 +1408,7 @@ theorem StronglyMeasurable.setToFun_prod_right {β : Type*} {mβ : MeasurableSpa by_cases hF : CompleteSpace F; swap; · simp [setToFun, hF, stronglyMeasurable_const] borelize E - haveI : SeparableSpace (range (Function.uncurry f) ∪ {0} : Set E) := + have : SeparableSpace (range (Function.uncurry f) ∪ {0} : Set E) := hf.separableSpace_range_union_singleton let s : ℕ → SimpleFunc (β × α) E := SimpleFunc.approxOn _ hf.measurable (range (Function.uncurry f) ∪ {0}) 0 (by simp) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean index cdb6f9017c6a3c..532e06a0b45274 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean @@ -100,7 +100,7 @@ theorem CountablyGenerated.comap [m : MeasurableSpace β] [h : CountablyGenerate @CountablyGenerated α (.comap f m) := by rcases h with ⟨⟨b, hbc, rfl⟩⟩ rw [comap_generateFrom] - letI := generateFrom (preimage f '' b) + let := generateFrom (preimage f '' b) exact ⟨_, hbc.image _, rfl⟩ theorem CountablyGenerated.sup {m₁ m₂ : MeasurableSpace β} (h₁ : @CountablyGenerated β m₁) @@ -282,7 +282,7 @@ then this is witnessed by sets in `S`. -/ theorem separating_of_generateFrom (S : Set (Set α)) [h : @SeparatesPoints α (generateFrom S)] : ∀ x y : α, (∀ s ∈ S, x ∈ s ↔ y ∈ s) → x = y := by - letI := generateFrom S + let := generateFrom S intro x y hxy rw [← forall_generateFrom_mem_iff_mem_iff] at hxy exact separatesPoints_def <| fun _ hs ↦ (hxy _ hs).mp diff --git a/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean index 5c6f705086b839..f00d8bdb7368a8 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean @@ -33,7 +33,7 @@ namespace MeasurableSpace @[simp] theorem generateFrom_singleton (s : Set α) : generateFrom {s} = MeasurableSpace.comap (· ∈ s) ⊤ := by classical - letI : MeasurableSpace α := generateFrom {s} + let : MeasurableSpace α := generateFrom {s} refine le_antisymm (generateFrom_le fun t ht => ⟨{True}, trivial, by simp [ht.symm]⟩) ?_ rintro _ ⟨u, -, rfl⟩ exact (show MeasurableSet s from GenerateMeasurable.basic _ <| mem_singleton s).mem trivial @@ -132,7 +132,7 @@ instance iInf_isMeasurablyGenerated {f : ι → Filter α} [∀ i, IsMeasurablyG refine ⟨⋂ i : t, U i, ?_, ?_, ?_⟩ · rw [← Equiv.plift.surjective.iInf_comp, mem_iInf] exact ⟨t, ht, U, hUf, rfl⟩ - · haveI := ht.countable.toEncodable.countable + · have := ht.countable.toEncodable.countable exact MeasurableSet.iInter fun i => (hU i).1 · exact iInter_mono fun i => (hU i).2 diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index 3905185f5bf840..cd80effcb4f1be 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -243,7 +243,7 @@ end AEMeasurable theorem aemeasurable_const' (h : ∀ᵐ (x) (y) ∂μ, f x = f y) : AEMeasurable f μ := by rcases eq_or_ne μ 0 with (rfl | hμ) · exact aemeasurable_zero_measure - · haveI := ae_neBot.2 hμ + · have := ae_neBot.2 hμ rcases h.exists with ⟨x, hx⟩ exact ⟨const α (f x), measurable_const, EventuallyEq.symm hx⟩ @@ -306,7 +306,7 @@ theorem aemeasurable_Ioi_of_forall_Ioc {β} {mβ : MeasurableSpace β} [LinearOr [(atTop : Filter α).IsCountablyGenerated] {x : α} {g : α → β} (g_meas : ∀ t > x, AEMeasurable g (μ.restrict (Ioc x t))) : AEMeasurable g (μ.restrict (Ioi x)) := by - haveI : Nonempty α := ⟨x⟩ + have : Nonempty α := ⟨x⟩ obtain ⟨u, hu_tendsto⟩ := exists_seq_tendsto (atTop : Filter α) have Ioi_eq_iUnion : Ioi x = ⋃ n : ℕ, Ioc x (u n) := by rw [iUnion_Ioc_eq_Ioi_self_iff.mpr _] diff --git a/Mathlib/MeasureTheory/Measure/Content.lean b/Mathlib/MeasureTheory/Measure/Content.lean index 284f7f517b31fb..7e76aa87c9b382 100644 --- a/Mathlib/MeasureTheory/Measure/Content.lean +++ b/Mathlib/MeasureTheory/Measure/Content.lean @@ -320,7 +320,7 @@ theorem borel_le_caratheodory : S ≤ μ.outerMeasure.caratheodory := by rw [μ.outerMeasure_of_isOpen ((U' : Set G) ∩ U) (U'.isOpen.inter hU)] simp only [innerContent, iSup_subtype'] rw [Opens.coe_mk] - haveI : Nonempty { L : Compacts G // (L : Set G) ⊆ U' ∩ U } := ⟨⟨⊥, empty_subset _⟩⟩ + have : Nonempty { L : Compacts G // (L : Set G) ⊆ U' ∩ U } := ⟨⟨⊥, empty_subset _⟩⟩ rw [ENNReal.iSup_add] refine iSup_le ?_ rintro ⟨L, hL⟩ @@ -335,7 +335,7 @@ theorem borel_le_caratheodory : S ≤ μ.outerMeasure.caratheodory := by rw [μ.outerMeasure_of_isOpen (↑U' \ L') (IsOpen.sdiff U'.2 isClosed_closure)] simp only [innerContent, iSup_subtype'] rw [Opens.coe_mk] - haveI : Nonempty { M : Compacts G // (M : Set G) ⊆ ↑U' \ closure L } := ⟨⟨⊥, empty_subset _⟩⟩ + have : Nonempty { M : Compacts G // (M : Set G) ⊆ ↑U' \ closure L } := ⟨⟨⊥, empty_subset _⟩⟩ rw [ENNReal.add_iSup] refine iSup_le ?_ rintro ⟨M, hM⟩ diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasureExt.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasureExt.lean index 4117ad9a102fb8..4236ff5b808afc 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasureExt.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasureExt.lean @@ -73,7 +73,7 @@ theorem ext_of_forall_mem_subalgebra_integral_eq_of_polish [TopologicalSpace E] [BorelSpace E] {P P' : Measure E} [IsFiniteMeasure P] [IsFiniteMeasure P'] {A : StarSubalgebra 𝕜 (E →ᵇ 𝕜)} (hA : (A.map (toContinuousMapStarₐ 𝕜)).SeparatesPoints) (heq : ∀ g ∈ A, ∫ x, (g : E → 𝕜) x ∂P = ∫ x, (g : E → 𝕜) x ∂P') : P = P' := by - letI := TopologicalSpace.upgradeIsCompletelyMetrizable E + let := TopologicalSpace.upgradeIsCompletelyMetrizable E exact ext_of_forall_mem_subalgebra_integral_eq_of_pseudoEMetric_complete_countable hA heq end MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean index 8a2fc542a13335..3f849138663f48 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean @@ -104,7 +104,7 @@ theorem continuous_pi [∀ i, TopologicalSpace (α i)] [∀ i, SecondCountableTo apply this.tendsto_probabilityMeasure_of_tendsto_of_mem · rintro - ⟨s, rfl, smeas, hs⟩ exact MeasurableSet.univ_pi smeas - · letI : ∀ i, PseudoMetricSpace (α i) := + · let : ∀ i, PseudoMetricSpace (α i) := fun i ↦ TopologicalSpace.pseudoMetrizableSpacePseudoMetric (α i) intro u u_open x xu obtain ⟨ε, εpos, hε⟩ : ∃ ε > 0, ball x ε ⊆ u := Metric.isOpen_iff.1 u_open x xu diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean index c80dbc9d83fc47..a34f6dda00349d 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean @@ -165,8 +165,8 @@ theorem continuous_prod [TopologicalSpace α] [TopologicalSpace β] [SecondCount apply this.tendsto_probabilityMeasure_of_tendsto_of_mem · rintro s ⟨a, b, ameas, -, bmeas, -, rfl⟩ exact ameas.prod bmeas - · letI : PseudoMetricSpace α := TopologicalSpace.pseudoMetrizableSpacePseudoMetric α - letI : PseudoMetricSpace β := TopologicalSpace.pseudoMetrizableSpacePseudoMetric β + · let : PseudoMetricSpace α := TopologicalSpace.pseudoMetrizableSpacePseudoMetric α + let : PseudoMetricSpace β := TopologicalSpace.pseudoMetrizableSpacePseudoMetric β intro u u_open x xu obtain ⟨ε, εpos, hε⟩ : ∃ ε > 0, ball x ε ⊆ u := Metric.isOpen_iff.1 u_open x xu rcases exists_null_frontier_thickening (μ.1 : Measure α) {x.1} εpos with ⟨r, hr, μr⟩ diff --git a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean index 43a481127a239a..f58e0dcb245c69 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean @@ -536,7 +536,7 @@ instance isMulLeftInvariant_haarMeasure (K₀ : PositiveCompacts G) : @[to_additive] theorem haarMeasure_self {K₀ : PositiveCompacts G} : haarMeasure K₀ K₀ = 1 := by - haveI : LocallyCompactSpace G := K₀.locallyCompactSpace_of_group + have : LocallyCompactSpace G := K₀.locallyCompactSpace_of_group simp only [haarMeasure, coe_smul, Pi.smul_apply, smul_eq_mul] rw [← K₀.isCompact.measure_closure, Content.measure_apply _ isClosed_closure.measurableSet, ENNReal.inv_mul_cancel] @@ -546,7 +546,7 @@ theorem haarMeasure_self {K₀ : PositiveCompacts G} : haarMeasure K₀ K₀ = 1 /-- The Haar measure is regular. -/ @[to_additive /-- The additive Haar measure is regular. -/] instance regular_haarMeasure {K₀ : PositiveCompacts G} : (haarMeasure K₀).Regular := by - haveI : LocallyCompactSpace G := K₀.locallyCompactSpace_of_group + have : LocallyCompactSpace G := K₀.locallyCompactSpace_of_group apply Regular.smul rw [← K₀.isCompact.measure_closure, Content.measure_apply _ isClosed_closure.measurableSet, ENNReal.inv_ne_top] @@ -560,7 +560,7 @@ theorem haarMeasure_closure_self {K₀ : PositiveCompacts G} : haarMeasure K₀ @[to_additive /-- The additive Haar measure is sigma-finite in a second countable group. -/] instance sigmaFinite_haarMeasure [SecondCountableTopology G] {K₀ : PositiveCompacts G} : SigmaFinite (haarMeasure K₀) := by - haveI : LocallyCompactSpace G := K₀.locallyCompactSpace_of_group; infer_instance + have : LocallyCompactSpace G := K₀.locallyCompactSpace_of_group; infer_instance /-- The Haar measure is a Haar measure, i.e., it is invariant and gives finite mass to compact sets and positive mass to nonempty open sets. -/ diff --git a/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean b/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean index 6fdb13e36dee52..ec56bf802a7533 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean @@ -81,7 +81,7 @@ end parallelepiped spanned by any orthonormal basis. -/ theorem OrthonormalBasis.volume_parallelepiped (b : OrthonormalBasis ι ℝ F) : volume (parallelepiped b) = 1 := by - haveI : Fact (finrank ℝ F = finrank ℝ F) := ⟨rfl⟩ + have : Fact (finrank ℝ F = finrank ℝ F) := ⟨rfl⟩ let o := (stdOrthonormalBasis ℝ F).toBasis.orientation rw [← o.measure_eq_volume] exact o.measure_orthonormalBasis b diff --git a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean index 02bd9b10e08766..79a2af3fb88b5f 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean @@ -162,7 +162,7 @@ theorem MeasureTheory.Measure.IsMulLeftInvariant.quotientMeasureEqMeasurePreimag ext U _ have meas_π : Measurable (QuotientGroup.mk : G → G ⧸ Γ) := continuous_quotient_mk'.measurable let μ' : Measure (G ⧸ Γ) := (ν.restrict s).map π - haveI has_fund : HasFundamentalDomain Γ.op G ν := ⟨⟨s, fund_dom_s⟩⟩ + have has_fund : HasFundamentalDomain Γ.op G ν := ⟨⟨s, fund_dom_s⟩⟩ have i : QuotientMeasureEqMeasurePreimage ν μ' := fund_dom_s.quotientMeasureEqMeasurePreimage_quotientMeasure have : μ'.IsMulLeftInvariant := @@ -225,7 +225,7 @@ theorem MeasureTheory.QuotientMeasureEqMeasurePreimage.haarMeasure_quotient [Loc obtain ⟨K⟩ := PositiveCompacts.nonempty' (α := G) let K' : PositiveCompacts (G ⧸ Γ) := K.map π QuotientGroup.continuous_mk QuotientGroup.isOpenMap_coe - haveI : IsMulLeftInvariant μ := + have : IsMulLeftInvariant μ := MeasureTheory.QuotientMeasureEqMeasurePreimage.mulInvariantMeasure_quotient ν rw [haarMeasure_unique μ K'] have finiteCovol : covolume Γ.op G ν ≠ ⊤ := @@ -296,7 +296,7 @@ theorem IsFundamentalDomain.QuotientMeasureEqMeasurePreimage_smulHaarMeasure { have c_ne_top : c ≠ ∞ := measure_inter_ne_top_of_right_ne_top h𝓕_finite set μ := c • haarMeasure K have hμK : μ K = c := by simp [μ, haarMeasure_self] - haveI : SigmaFinite μ := by + have : SigmaFinite μ := by clear_value c lift c to NNReal using c_ne_top exact SMul.sigmaFinite c diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean index 82b1e677a1f03b..2ef5d93cf2b87b 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean @@ -217,7 +217,7 @@ end HasOuterApproxClosed --namespace noncomputable instance (X : Type*) [TopologicalSpace X] [TopologicalSpace.PseudoMetrizableSpace X] : HasOuterApproxClosed X := by - letI : PseudoMetricSpace X := TopologicalSpace.pseudoMetrizableSpacePseudoMetric X + let : PseudoMetricSpace X := TopologicalSpace.pseudoMetrizableSpacePseudoMetric X refine ⟨fun F hF ↦ ?_⟩ use fun n ↦ thickenedIndicator (δ := (1 : ℝ) / (n + 1)) Nat.one_div_pos_of_nat F refine ⟨?_, ⟨?_, ?_⟩⟩ diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 8a42736fa80c53..d109983459085d 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -500,7 +500,7 @@ theorem mkMetric_le_liminf_tsum {β : Type*} {ι : β → Type*} [∀ n, Countab {l : Filter β} (r : β → ℝ≥0∞) (hr : Tendsto r l (𝓝 0)) (t : ∀ n : β, ι n → Set X) (ht : ∀ᶠ n in l, ∀ i, ediam (t n i) ≤ r n) (hst : ∀ᶠ n in l, s ⊆ ⋃ i, t n i) (m : ℝ≥0∞ → ℝ≥0∞) : mkMetric m s ≤ liminf (fun n => ∑' i, m (ediam (t n i))) l := by - haveI : ∀ n, Encodable (ι n) := fun n => Encodable.ofCountable _ + have : ∀ n, Encodable (ι n) := fun n => Encodable.ofCountable _ simp only [mkMetric_apply] refine iSup₂_le fun ε hε => ?_ refine le_of_forall_gt_imp_ge_of_dense fun c hc => ?_ @@ -651,7 +651,7 @@ theorem hausdorffMeasure_le_one_of_subsingleton {s : Set X} (hs : s.Subsingleton · rw [(subsingleton_iff_singleton hx).1 hs] rcases eq_or_lt_of_le hd with (rfl | dpos) · simp only [le_refl, hausdorffMeasure_zero_singleton] - · haveI := nullSingletonClass_hausdorff X dpos + · have := nullSingletonClass_hausdorff X dpos simp only [zero_le, measure_singleton] end Measure @@ -689,7 +689,7 @@ theorem hausdorffMeasure_image_le (h : HolderOnWith C r f s) (hr : 0 < r) {d : · simp only [ENNReal.rpow_zero, one_mul, mul_zero] rw [hausdorffMeasure_zero_singleton] exact one_le_hausdorffMeasure_zero_of_nonempty ⟨x, hx⟩ - · haveI := nullSingletonClass_hausdorff Y h'd + · have := nullSingletonClass_hausdorff Y h'd simp only [zero_le, measure_singleton] -- Now assume `C ≠ 0` · have hCd0 : (C : ℝ≥0∞) ^ d ≠ 0 := by simp [hC0.ne'] @@ -771,7 +771,7 @@ theorem hausdorffMeasure_preimage_le (hf : AntilipschitzWith K f) (hd : 0 ≤ d) · rcases eq_empty_or_nonempty (f ⁻¹' s) with (hs | ⟨x, hx⟩) · simp only [hs, measure_empty, zero_le] have : f ⁻¹' s = {x} := by - haveI : Subsingleton X := hf.subsingleton + have : Subsingleton X := hf.subsingleton have : (f ⁻¹' s).Subsingleton := subsingleton_univ.anti (subset_univ _) exact (subsingleton_iff_singleton hx).1 this rw [this] @@ -779,7 +779,7 @@ theorem hausdorffMeasure_preimage_le (hf : AntilipschitzWith K f) (hd : 0 ≤ d) · simp only [ENNReal.rpow_zero, one_mul] rw [hausdorffMeasure_zero_singleton] exact one_le_hausdorffMeasure_zero_of_nonempty ⟨f x, hx⟩ - · haveI := nullSingletonClass_hausdorff X h'd + · have := nullSingletonClass_hausdorff X h'd simp only [zero_le, measure_singleton] have hKd0 : (K : ℝ≥0∞) ^ d ≠ 0 := by simp [h0] have hKd : (K : ℝ≥0∞) ^ d ≠ ∞ := by simp [hd] @@ -1027,7 +1027,7 @@ theorem hausdorffMeasure_smul_right_image [NormedAddCommGroup E] [NormedSpace [MeasurableSpace E] [BorelSpace E] (v : E) (s : Set ℝ) : μH[1] ((fun r => r • v) '' s) = ‖v‖₊ • μH[1] s := by obtain rfl | hv := eq_or_ne v 0 - · haveI := nullSingletonClass_hausdorff E one_pos + · have := nullSingletonClass_hausdorff E one_pos obtain rfl | hs := s.eq_empty_or_nonempty · simp simp [hs] diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean index 817ddd25d63ce9..e1301292f1006f 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean @@ -52,7 +52,7 @@ variable {ι : Type*} [Fintype ι] /-- The volume on the real line (as a particular case of the volume on a finite-dimensional inner product space) coincides with the Stieltjes measure coming from the identity function. -/ theorem volume_eq_stieltjes_id : (volume : Measure ℝ) = StieltjesFunction.id.measure := by - haveI : IsAddLeftInvariant StieltjesFunction.id.measure := + have : IsAddLeftInvariant StieltjesFunction.id.measure := ⟨fun a => Eq.symm <| Real.measure_ext_Ioo_rat fun p q => by diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean index 0f79b4b9d11fa6..c22322acd7ddfc 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/EqHaar.lean @@ -233,7 +233,7 @@ theorem map_linearMap_addHaar_eq_smul_addHaar {f : E →ₗ[ℝ] E} (hf : Linear -- we reduce to the case of `E = ι → ℝ`, for which we have already proved the result using -- matrices in `map_linearMap_addHaar_pi_eq_smul_addHaar`. let ι := Fin (finrank ℝ E) - haveI : FiniteDimensional ℝ (ι → ℝ) := by infer_instance + have : FiniteDimensional ℝ (ι → ℝ) := by infer_instance have : finrank ℝ E = finrank ℝ (ι → ℝ) := by simp [ι] have e : E ≃ₗ[ℝ] ι → ℝ := LinearEquiv.ofFinrankEq E (ι → ℝ) this -- next line is to avoid `g` getting reduced by `simp`. @@ -249,7 +249,7 @@ theorem map_linearMap_addHaar_eq_smul_addHaar {f : E →ₗ[ℝ] E} (hf : Linear have Cg : Continuous g := LinearMap.continuous_of_finiteDimensional g have Cesymm : Continuous e.symm := (e.symm : (ι → ℝ) →ₗ[ℝ] E).continuous_of_finiteDimensional rw [← map_map Cesymm.measurable (Cg.comp Ce).measurable, ← map_map Cg.measurable Ce.measurable] - haveI : IsAddHaarMeasure (map e μ) := (e : E ≃+ (ι → ℝ)).isAddHaarMeasure_map μ Ce Cesymm + have : IsAddHaarMeasure (map e μ) := (e : E ≃+ (ι → ℝ)).isAddHaarMeasure_map μ Ce Cesymm have ecomp : e.symm ∘ e = id := by ext x; simp only [id, Function.comp_apply, LinearEquiv.symm_apply_apply] rw [map_linearMap_addHaar_pi_eq_smul_addHaar hf (map e μ), Measure.map_smul, @@ -367,10 +367,10 @@ theorem addHaar_smul (r : ℝ) (s : Set E) : · simp only [measure_empty, mul_zero, smul_set_empty] rw [zero_smul_set hs, ← singleton_zero] by_cases h : finrank ℝ E = 0 - · haveI : Subsingleton E := finrank_zero_iff.1 h + · have : Subsingleton E := finrank_zero_iff.1 h simp only [h, one_mul, ENNReal.ofReal_one, abs_one, Subsingleton.eq_univ_of_nonempty hs, pow_zero, Subsingleton.eq_univ_of_nonempty (singleton_nonempty (0 : E))] - · haveI : Nontrivial E := nontrivial_of_finrank_pos (bot_lt_iff_ne_bot.2 h) + · have : Nontrivial E := nontrivial_of_finrank_pos (bot_lt_iff_ne_bot.2 h) simp only [h, zero_mul, ENNReal.ofReal_zero, abs_zero, Ne, not_false_iff, zero_pow, measure_singleton] diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean index 81fef1f10b6d72..2aeca2034d8903 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean @@ -80,13 +80,13 @@ theorem MeasureTheory.measure_lt_one_eq_integral_div_gamma {p : ℝ} (hp : 0 < p μ {x : E | g x < 1} = .ofReal ((∫ (x : E), Real.exp (-(g x) ^ p) ∂μ) / Real.Gamma (finrank ℝ E / p + 1)) := by -- We copy `E` to a new type `F` on which we will put the norm defined by `g` - letI F : Type _ := E + let F : Type _ := E let p : AddGroupNorm F := ⟨⟨g, h1, h3, h2⟩, fun x hx ↦ h4 hx⟩ - letI : NormedAddCommGroup F := AddGroupNorm.toNormedAddCommGroup p - letI : NormedSpace ℝ F := { norm_smul_le := fun _ _ ↦ h5 _ _ } + let : NormedAddCommGroup F := AddGroupNorm.toNormedAddCommGroup p + let : NormedSpace ℝ F := { norm_smul_le := fun _ _ ↦ h5 _ _ } -- We put the new topology on F - letI : TopologicalSpace F := UniformSpace.toTopologicalSpace - letI : MeasurableSpace F := borel F + let : TopologicalSpace F := UniformSpace.toTopologicalSpace + let : MeasurableSpace F := borel F have : BorelSpace F := { measurable_eq := rfl } -- The map between `E` and `F` as a continuous linear equivalence let φ := @LinearEquiv.toContinuousLinearEquiv ℝ _ E _ _ tE _ _ F _ _ _ _ _ _ _ _ _ @@ -113,13 +113,13 @@ theorem MeasureTheory.measure_lt_one_eq_integral_div_gamma {p : ℝ} (hp : 0 < p theorem MeasureTheory.measure_le_eq_lt [Nontrivial E] (r : ℝ) : μ {x : E | g x ≤ r} = μ {x : E | g x < r} := by -- We copy `E` to a new type `F` on which we will put the norm defined by `g` - letI F : Type _ := E + let F : Type _ := E let p : AddGroupNorm F := ⟨⟨g, h1, h3, h2⟩, fun x hx ↦ h4 hx⟩ - letI : NormedAddCommGroup F := AddGroupNorm.toNormedAddCommGroup p - letI : NormedSpace ℝ F := { norm_smul_le := fun _ _ ↦ h5 _ _ } + let : NormedAddCommGroup F := AddGroupNorm.toNormedAddCommGroup p + let : NormedSpace ℝ F := { norm_smul_le := fun _ _ ↦ h5 _ _ } -- We put the new topology on F - letI : TopologicalSpace F := UniformSpace.toTopologicalSpace - letI : MeasurableSpace F := borel F + let : TopologicalSpace F := UniformSpace.toTopologicalSpace + let : MeasurableSpace F := borel F have : BorelSpace F := { measurable_eq := rfl } -- The map between `E` and `F` as a continuous linear equivalence let φ := @LinearEquiv.toContinuousLinearEquiv ℝ _ E _ _ tE _ _ F _ _ _ _ _ _ _ _ _ diff --git a/Mathlib/MeasureTheory/Measure/LevyConvergence.lean b/Mathlib/MeasureTheory/Measure/LevyConvergence.lean index 4294777be177cd..debad61a4c309c 100644 --- a/Mathlib/MeasureTheory/Measure/LevyConvergence.lean +++ b/Mathlib/MeasureTheory/Measure/LevyConvergence.lean @@ -158,7 +158,7 @@ lemma ProbabilityMeasure.tendsto_of_tight_of_separatesPoints (𝕜 : Type*) [RCL {A : StarSubalgebra 𝕜 (E →ᵇ 𝕜)} (hA : (A.map (toContinuousMapStarₐ 𝕜)).SeparatesPoints) (hμ : ∀ g ∈ A, Tendsto (fun n ↦ ∫ x, g x ∂(μ n)) 𝓕 (𝓝 (∫ x, g x ∂μ₀))) : Tendsto μ 𝓕 (𝓝 μ₀) := by - letI := TopologicalSpace.upgradeIsCompletelyMetrizable E + let := TopologicalSpace.upgradeIsCompletelyMetrizable E obtain rfl | _ := 𝓕.eq_or_neBot · simp refine (Filter.tendsto_iff_ultrafilter _ _ _).2 fun U hU ↦ ?_ diff --git a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean index c33e6c53d47498..d3a7b39bf86c01 100644 --- a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean +++ b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean @@ -695,7 +695,7 @@ instance (X : Type*) [TopologicalSpace X] [PseudoMetrizableSpace X] [SeparableSp instance instMetrizableSpaceProbabilityMeasure (X : Type*) [TopologicalSpace X] [PseudoMetrizableSpace X] [SeparableSpace X] [MeasurableSpace X] [BorelSpace X] : MetrizableSpace (ProbabilityMeasure X) := by - letI : PseudoMetricSpace X := TopologicalSpace.pseudoMetrizableSpacePseudoMetric X + let : PseudoMetricSpace X := TopologicalSpace.pseudoMetrizableSpacePseudoMetric X exact LevyProkhorov.probabilityMeasureHomeomorph.isEmbedding.metrizableSpace end Levy_Prokhorov_metrizes_convergence_in_distribution diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 11af89700356d5..6bc4c96d4b6017 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -160,7 +160,7 @@ theorem measure_add_measure_compl (h : MeasurableSet s) : μ s + μ sᶜ = μ un theorem measure_biUnion₀ {s : Set β} {f : β → Set α} (hs : s.Countable) (hd : s.Pairwise (AEDisjoint μ on f)) (h : ∀ b ∈ s, NullMeasurableSet (f b) μ) : μ (⋃ b ∈ s, f b) = ∑' p : s, μ (f p) := by - haveI := hs.toEncodable + have := hs.toEncodable rw [biUnion_eq_iUnion] exact measure_iUnion₀ (hd.on_injective Subtype.coe_injective fun x => x.2) fun x => h x x.2 @@ -411,7 +411,7 @@ theorem measure_iUnion_toMeasurable {ι : Sort*} [Countable ι] (s : ι → Set theorem measure_biUnion_toMeasurable {I : Set β} (hc : I.Countable) (s : β → Set α) : μ (⋃ b ∈ I, toMeasurable μ (s b)) = μ (⋃ b ∈ I, s b) := by - haveI := hc.toEncodable + have := hc.toEncodable simp only [biUnion_eq_iUnion, measure_iUnion_toMeasurable] @[simp] @@ -542,7 +542,7 @@ theorem measure_iUnion_eq_iSup_accumulate [Preorder ι] [IsDirectedOrder ι] theorem measure_biUnion_eq_iSup {s : ι → Set α} {t : Set ι} (ht : t.Countable) (hd : DirectedOn ((· ⊆ ·) on s) t) : μ (⋃ i ∈ t, s i) = ⨆ i ∈ t, μ (s i) := by - haveI := ht.to_subtype + have := ht.to_subtype rw [biUnion_eq_iUnion, hd.directed_val.measure_iUnion, ← iSup_subtype''] /-- **Continuity from above**: diff --git a/Mathlib/MeasureTheory/Measure/Portmanteau.lean b/Mathlib/MeasureTheory/Measure/Portmanteau.lean index e64bd9c2ba8bb3..1a39a02bffa3a1 100644 --- a/Mathlib/MeasureTheory/Measure/Portmanteau.lean +++ b/Mathlib/MeasureTheory/Measure/Portmanteau.lean @@ -435,7 +435,7 @@ lemma limsup_measure_closed_le_of_forall_tendsto_measure Tendsto (fun i ↦ μs i E) L (𝓝 (μ E))) (F : Set Ω) (F_closed : IsClosed F) : L.limsup (fun i ↦ μs i F) ≤ μ F := by - letI : PseudoMetricSpace Ω := TopologicalSpace.pseudoMetrizableSpacePseudoMetric Ω + let : PseudoMetricSpace Ω := TopologicalSpace.pseudoMetrizableSpacePseudoMetric Ω rcases L.eq_or_neBot with rfl | _ · simp only [limsup_bot, bot_eq_zero', zero_le] have ex := exists_null_frontiers_thickening μ F diff --git a/Mathlib/MeasureTheory/Measure/Prod.lean b/Mathlib/MeasureTheory/Measure/Prod.lean index 2f3c5ca3e1db60..cf5dd69edca651 100644 --- a/Mathlib/MeasureTheory/Measure/Prod.lean +++ b/Mathlib/MeasureTheory/Measure/Prod.lean @@ -576,7 +576,7 @@ theorem prod_eq_generateFrom {μ : Measure α} {ν : Measure β} {C : Set (Set (generateFrom_eq_prod hC hD h3C.isCountablySpanning h3D.isCountablySpanning).symm (h2C.prod h2D) ?_ rintro _ ⟨s, hs, t, ht, rfl⟩ - haveI := h3D.sigmaFinite + have := h3D.sigmaFinite rw [h₁ s hs t ht, prod_prod] /- Note that the next theorem is not true for s-finite measures: let `μ = ν = ∞ • Leb` on `[0,1]` diff --git a/Mathlib/MeasureTheory/Measure/Regular.lean b/Mathlib/MeasureTheory/Measure/Regular.lean index fb81fe7c2f5584..e7f1eb7f5721a5 100644 --- a/Mathlib/MeasureTheory/Measure/Regular.lean +++ b/Mathlib/MeasureTheory/Measure/Regular.lean @@ -1060,7 +1060,7 @@ theorem _root_.MeasurableSet.measure_eq_iSup_isClosed_of_ne_top [WeaklyRegular weakly regular. -/ theorem restrict_of_measure_ne_top [BorelSpace α] [WeaklyRegular μ] {A : Set α} (h'A : μ A ≠ ∞) : WeaklyRegular (μ.restrict A) := by - haveI : Fact (μ A < ∞) := ⟨h'A.lt_top⟩ + have : Fact (μ A < ∞) := ⟨h'A.lt_top⟩ refine InnerRegularWRT.weaklyRegular_of_finite (μ.restrict A) (fun V V_open r hr ↦ ?_) have : InnerRegularWRT (μ.restrict A) IsClosed (fun s ↦ MeasurableSet s) := InnerRegularWRT.restrict_of_measure_ne_top innerRegular_measurable h'A @@ -1088,7 +1088,7 @@ instance (priority := 100) of_pseudoMetrizableSpace_secondCountable_of_locallyFi ⟨InnerRegularWRT.of_pseudoMetrizableSpace μ⟩ protected theorem smul [WeaklyRegular μ] {x : ℝ≥0∞} (hx : x ≠ ∞) : (x • μ).WeaklyRegular := by - haveI := OuterRegular.smul μ hx + have := OuterRegular.smul μ hx exact ⟨WeaklyRegular.innerRegular.smul x⟩ instance smul_nnreal [WeaklyRegular μ] (c : ℝ≥0) : WeaklyRegular (c • μ) := @@ -1124,8 +1124,8 @@ instance (priority := 100) [Regular μ] : InnerRegularCompactLTTop μ := protected theorem map [BorelSpace α] [MeasurableSpace β] [TopologicalSpace β] [BorelSpace β] [Regular μ] (f : α ≃ₜ β) : (Measure.map f μ).Regular := by - haveI := OuterRegular.map f μ - haveI := IsFiniteMeasureOnCompacts.map μ f + have := OuterRegular.map f μ + have := IsFiniteMeasureOnCompacts.map μ f exact ⟨Regular.innerRegular.map' f.toMeasurableEquiv (fun U hU => hU.preimage f.continuous) @@ -1143,8 +1143,8 @@ open Topology in protected theorem comap' [BorelSpace α] {mβ : MeasurableSpace β} [TopologicalSpace β] [BorelSpace β] (μ : Measure β) [Regular μ] {f : α → β} (hf : IsOpenEmbedding f) : (μ.comap f).Regular := by - haveI := OuterRegular.comap' μ hf.continuous hf.measurableEmbedding - haveI := IsFiniteMeasureOnCompacts.comap' μ hf.continuous hf.measurableEmbedding + have := OuterRegular.comap' μ hf.continuous hf.measurableEmbedding + have := IsFiniteMeasureOnCompacts.comap' μ hf.continuous hf.measurableEmbedding exact ⟨InnerRegularWRT.comap Regular.innerRegular hf.measurableEmbedding (fun _ hU ↦ hf.isOpen_iff_image_isOpen.mp hU) (fun _ hKrange hK ↦ hf.isInducing.isCompact_preimage' hK hKrange)⟩ @@ -1154,8 +1154,8 @@ protected theorem comap [BorelSpace α] {mβ : MeasurableSpace β} [TopologicalS Regular.comap' μ f.isOpenEmbedding protected theorem smul [Regular μ] {x : ℝ≥0∞} (hx : x ≠ ∞) : (x • μ).Regular := by - haveI := OuterRegular.smul μ hx - haveI := IsFiniteMeasureOnCompacts.smul μ hx + have := OuterRegular.smul μ hx + have := IsFiniteMeasureOnCompacts.smul μ hx exact ⟨Regular.innerRegular.smul x⟩ instance smul_nnreal [Regular μ] (c : ℝ≥0) : Regular (c • μ) := Regular.smul coe_ne_top diff --git a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean index 31eda309cefffb..604fffdc981283 100644 --- a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean +++ b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean @@ -101,7 +101,7 @@ theorem exists_isCompact_closure_measure_compl_lt [TopologicalSpace α] of natural numbers `u n`, such that `interUnionBalls seq u t`, which is the intersection over `n` of the `t n`-neighborhood of `seq 1, ..., seq (u n)`, covers the space arbitrarily well. -/ - letI := upgradeIsCompletelyPseudoMetrizable α + let := upgradeIsCompletelyPseudoMetrizable α cases isEmpty_or_nonempty α case inl => refine ⟨∅, by simp, ?_⟩ diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index 8c50c7c32662ea..64f7cae76c64bb 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -394,7 +394,7 @@ theorem restrict_iUnion_congr [Countable ι] {s : ι → Set α} : theorem restrict_biUnion_congr {s : Set ι} {t : ι → Set α} (hc : s.Countable) : μ.restrict (⋃ i ∈ s, t i) = ν.restrict (⋃ i ∈ s, t i) ↔ ∀ i ∈ s, μ.restrict (t i) = ν.restrict (t i) := by - haveI := hc.toEncodable + have := hc.toEncodable simp only [biUnion_eq_iUnion, SetCoe.forall', restrict_iUnion_congr] theorem restrict_sUnion_congr {S : Set (Set α)} (hc : S.Countable) : @@ -557,7 +557,7 @@ theorem ae_restrict_union_eq (s t : Set α) : theorem ae_restrict_biUnion_eq (s : ι → Set α) {t : Set ι} (ht : t.Countable) : ae (μ.restrict (⋃ i ∈ t, s i)) = ⨆ i ∈ t, ae (μ.restrict (s i)) := by - haveI := ht.to_subtype + have := ht.to_subtype rw [biUnion_eq_iUnion, ae_restrict_iUnion_eq, ← iSup_subtype''] theorem ae_restrict_biUnion_finset_eq (s : ι → Set α) (t : Finset ι) : diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean index 18fff318c3ff61..ff9b25f67c9c75 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean @@ -430,7 +430,7 @@ theorem ext_on_measurableSpace_of_generate_finite {α} (m₀ : MeasurableSpace [IsFiniteMeasure μ] (C : Set (Set α)) (hμν : ∀ s ∈ C, μ s = ν s) {m : MeasurableSpace α} (h : m ≤ m₀) (hA : m = MeasurableSpace.generateFrom C) (hC : IsPiSystem C) (h_univ : μ Set.univ = ν Set.univ) {s : Set α} (hs : MeasurableSet[m] s) : μ s = ν s := by - haveI : IsFiniteMeasure ν := by + have : IsFiniteMeasure ν := by constructor rw [← h_univ] apply IsFiniteMeasure.measure_univ_lt_top diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean index 05a501fdba695a..d760ba899effb4 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/NullSingletonClass.lean @@ -94,7 +94,7 @@ theorem exists_accPt_of_nullSingletonClass {X : Type*} [TopologicalSpace X] [Mea {μ : Measure X} [NullSingletonClass μ] {E : Set X} [SeparableSpace E] (hE : 0 < μ E) : ∃ x, AccPt x (𝓟 E) := by by_contra! h - haveI : DiscreteTopology E := discreteTopology_of_noAccPts fun x _ => h x + have : DiscreteTopology E := discreteTopology_of_noAccPts fun x _ => h x exact hE.ne' <| (Set.countable_coe_iff.mp <| separableSpace_iff_countable.mp ‹_›).measure_zero μ @[deprecated (since := "2026-06-09")] diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean index 4be87e7cb30e9e..bb8950924f987c 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean @@ -594,7 +594,7 @@ lemma Measure.sigmaFinite_iff_measure_singleton_lt_top [Countable α] : theorem sigmaFinite_bot_iff (μ : @Measure α ⊥) : SigmaFinite μ ↔ IsFiniteMeasure μ := by refine ⟨fun h => ⟨?_⟩, fun h => by infer_instance⟩ - haveI : SigmaFinite μ := h + have : SigmaFinite μ := h let s := spanningSets μ have hs_univ : ⋃ i, s i = Set.univ := iUnion_spanningSets μ have hs_meas : ∀ i, MeasurableSet[⊥] (s i) := measurableSet_spanningSets μ diff --git a/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean b/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean index 42836f08747de6..18d825d93554b2 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean @@ -230,7 +230,7 @@ theorem restrict_ofFunction (s : Set α) (hm : Monotone m) : theorem smul_ofFunction {c : ℝ≥0∞} (hc : c ≠ ∞) : c • OuterMeasure.ofFunction m m_empty = OuterMeasure.ofFunction (c • m) (by simp [m_empty]) := by ext1 s - haveI : Nonempty { t : ℕ → Set α // s ⊆ ⋃ i, t i } := ⟨⟨fun _ => s, subset_iUnion (fun _ => s) 0⟩⟩ + have : Nonempty { t : ℕ → Set α // s ⊆ ⋃ i, t i } := ⟨⟨fun _ => s, subset_iUnion (fun _ => s) 0⟩⟩ simp only [smul_apply, ofFunction_apply, ENNReal.tsum_mul_left, Pi.smul_apply, smul_eq_mul, iInf_subtype'] rw [ENNReal.mul_iInf fun h => (hc h).elim] @@ -391,7 +391,7 @@ the minimum value of a measure on that set: it is the infimum sum of measures of sets that covers that set, where a different measure can be used for each set in the cover. -/ theorem biInf_apply {ι} {I : Set ι} (hI : I.Nonempty) (m : ι → OuterMeasure α) (s : Set α) : (⨅ i ∈ I, m i) s = ⨅ (t : ℕ → Set α) (_ : s ⊆ iUnion t), ∑' n, ⨅ i ∈ I, m i (t n) := by - haveI := hI.to_subtype + have := hI.to_subtype simp only [← iInf_subtype'', iInf_apply] /-- The value of the Infimum of a nonempty family of outer measures on a set is not simply @@ -433,7 +433,7 @@ theorem map_iInf_comap {ι β} [Nonempty ι] {f : α → β} (m : ι → OuterMe theorem map_biInf_comap {ι β} {I : Set ι} (hI : I.Nonempty) {f : α → β} (m : ι → OuterMeasure β) : map f (⨅ i ∈ I, comap f (m i)) = ⨅ i ∈ I, map f (comap f (m i)) := by - haveI := hI.to_subtype + have := hI.to_subtype rw [← iInf_subtype'', ← iInf_subtype''] exact map_iInf_comap _ @@ -450,7 +450,7 @@ theorem restrict_iInf {ι} [Nonempty ι] (s : Set α) (m : ι → OuterMeasure theorem restrict_biInf {ι} {I : Set ι} (hI : I.Nonempty) (s : Set α) (m : ι → OuterMeasure α) : restrict s (⨅ i ∈ I, m i) = ⨅ i ∈ I, restrict s (m i) := by - haveI := hI.to_subtype + have := hI.to_subtype rw [← iInf_subtype'', ← iInf_subtype''] exact restrict_iInf _ _ diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean index 11c223168aeaf3..d45d4d5a06fdd5 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean @@ -226,11 +226,11 @@ theorem toJordanDecomposition_eq_of_eq_add_withDensity {f : α → ℝ} (hf : Me @JordanDecomposition.mk α _ (t.toJordanDecomposition.posPart + μ.withDensity fun x => ENNReal.ofReal (f x)) (t.toJordanDecomposition.negPart + μ.withDensity fun x => ENNReal.ofReal (-f x)) - (by haveI := isFiniteMeasure_withDensity_ofReal hfi.2; infer_instance) - (by haveI := isFiniteMeasure_withDensity_ofReal hfi.neg.2; infer_instance) + (by have := isFiniteMeasure_withDensity_ofReal hfi.2; infer_instance) + (by have := isFiniteMeasure_withDensity_ofReal hfi.neg.2; infer_instance) (jordanDecomposition_add_withDensity_mutuallySingular hf htμ) := by - haveI := isFiniteMeasure_withDensity_ofReal hfi.2 - haveI := isFiniteMeasure_withDensity_ofReal hfi.neg.2 + have := isFiniteMeasure_withDensity_ofReal hfi.2 + have := isFiniteMeasure_withDensity_ofReal hfi.neg.2 refine toJordanDecomposition_eq ?_ simp_rw [JordanDecomposition.toSignedMeasure, hadd] ext i hi diff --git a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean index 47c85aa59371b4..cbd042c9ed8922 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean @@ -520,7 +520,7 @@ theorem hasSum_setIntegral_iUnion {ι : Type*} [Countable ι] {s : ι → Set X} HasSum (fun n ↦ ∫ᵛ x in s n, f x ∂[B; μ]) (∫ᵛ x in ⋃ n, s n, f x ∂[B; μ]) := by classical rcases finite_or_infinite ι with hι | hι - · letI : Fintype ι := Fintype.ofFinite ι + · let : Fintype ι := Fintype.ofFinite ι have : ∫ᵛ x in ⋃ n, s n, f x ∂[B; μ] = ∑ i, ∫ᵛ x in s i, f x ∂[B; μ] := by rw [setIntegral_iUnion_fintype hm hd (fun i ↦ ?_)] exact hfi.mono (MeasurableSet.iUnion hm) (by simp [subset_iUnion s]) diff --git a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean index 1bbde10a8da904..165e673a4d9498 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean @@ -175,7 +175,7 @@ theorem withDensityᵥ_toReal {f : α → ℝ≥0∞} (hfm : AEMeasurable f μ) (μ.withDensityᵥ fun x => (f x).toReal) = @toSignedMeasure α _ (μ.withDensity f) (isFiniteMeasure_withDensity hf) := by have hfi := integrable_toReal_of_lintegral_ne_top hfm hf - haveI := isFiniteMeasure_withDensity hf + have := isFiniteMeasure_withDensity hf ext i hi rw [withDensityᵥ_apply hfi hi, toSignedMeasure_apply_measurable hi, measureReal_def, withDensity_apply _ hi, integral_toReal hfm.restrict] @@ -190,8 +190,8 @@ theorem withDensityᵥ_eq_withDensity_pos_part_sub_withDensity_neg_part {f : α (isFiniteMeasure_withDensity_ofReal hfi.2) - @toSignedMeasure α _ (μ.withDensity fun x => ENNReal.ofReal <| -f x) (isFiniteMeasure_withDensity_ofReal hfi.neg.2) := by - haveI := isFiniteMeasure_withDensity_ofReal hfi.2 - haveI := isFiniteMeasure_withDensity_ofReal hfi.neg.2 + have := isFiniteMeasure_withDensity_ofReal hfi.2 + have := isFiniteMeasure_withDensity_ofReal hfi.neg.2 ext i hi rw [withDensityᵥ_apply hfi hi, integral_eq_lintegral_pos_part_sub_lintegral_neg_part hfi.integrableOn, diff --git a/Mathlib/ModelTheory/Algebra/Ring/Definability.lean b/Mathlib/ModelTheory/Algebra/Ring/Definability.lean index bc64fe626ef1b1..e4cdc861170563 100644 --- a/Mathlib/ModelTheory/Algebra/Ring/Definability.lean +++ b/Mathlib/ModelTheory/Algebra/Ring/Definability.lean @@ -32,8 +32,8 @@ theorem mvPolynomial_zeroLocus_definable {ι K : Type*} [Field K] (zeroLocus K (Ideal.span (S : Set (MvPolynomial ι K)))) := by rw [Set.definable_iff_exists_formula_sum] let p' := genericPolyMap (fun p : S => p.1.support) - letI := Classical.decEq ι - letI := Classical.decEq K + let := Classical.decEq ι + let := Classical.decEq K rw [MvPolynomial.zeroLocus_span] refine ⟨BoundedFormula.iInf (fun i : S => Term.equal diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean index dbdb246371611b..fbd2168261ddf4 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean @@ -111,7 +111,7 @@ variable [Finite α] lemma isSemilinearSet_boundedFormula_realize {n} (φ : presburger[[A]].BoundedFormula α n) : IsSemilinearSet {v : α ⊕ Fin n → ℕ | φ.Realize (v ∘ Sum.inl) (v ∘ Sum.inr)} := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α induction φ with simp only [BoundedFormula.Realize] | equal t₁ t₂ => rcases term_realize_eq_add_dotProduct t₁ with ⟨k₁, u₁, ht₁⟩ diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean index 26520550127936..d750166966ec53 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean @@ -140,7 +140,7 @@ private theorem Nat.isSemilinearSet_of_isSlice {ι : Type*} [Finite ι] {s : Set (hs : IsSlice s) : IsSemilinearSet s := by classical suffices h : ∀ (a : ι → ℕ) (t : Finset ι), (∀ x ∈ s, ∀ i ∉ t, x i = a i) → IsSemilinearSet s by - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι exact h 0 Finset.univ (by simp) intro a t ht induction t using Finset.strongInductionOn generalizing s a with | _ t ih @@ -249,7 +249,7 @@ public lemma IsSemilinearSet.exists_fg_eq_subtypeVal (hs : IsSemilinearSet s) : ∃ (P : AddSubmonoid M) (s' : Set P), P.FG ∧ IsSemilinearSet s' ∧ s = Subtype.val '' s' := by rcases hs with ⟨S, hS, hS', rfl⟩ choose! P t hP ht ht' using fun s hs => (hS' s hs).exists_fg_eq_subtypeVal - haveI : Finite S := hS + have : Finite S := hS refine ⟨⨆ s : S, P s, ⋃ (s : S), AddSubmonoid.inclusion (le_iSup _ s) '' t s.1, .iSup _ fun s => hP s s.2, .iUnion fun s => (ht s s.2).isSemilinearSet.image _, ?_⟩ simp_rw [sUnion_eq_iUnion, image_iUnion, image_image, AddSubmonoid.coe_inclusion, @@ -270,7 +270,7 @@ public lemma IsSemilinearSet.exists_fg_eq_subtypeVal₂ (hs₁ : IsSemilinearSet private lemma Nat.isSemilinearSet_inter_of_isLinearSet [Finite ι] {s₁ s₂ : Set (ι → ℕ)} (hs₁ : IsLinearSet s₁) (hs₂ : IsLinearSet s₂) : IsSemilinearSet (s₁ ∩ s₂) := by classical - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι rw [isLinearSet_iff_exists_matrix] at hs₁ hs₂ rcases hs₁ with ⟨u, n, A, rfl⟩ rcases hs₂ with ⟨v, m, B, rfl⟩ @@ -440,7 +440,7 @@ private noncomputable def fundamentalDomain : Set (ι → ℕ) := private theorem finite_fundamentalDomain : hs.fundamentalDomain.Finite := by classical - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι apply (finite_Iic (hs.base + ∑ i : hs.basisSet, i.1)).subset intro x hx rw [mem_Iic, ← toRatVec_mono, map_add, map_sum, ← add_sub_cancel (toRatVec hs.base) (toRatVec x), @@ -620,7 +620,7 @@ private theorem isSemilinearSet_setOfFractNe : IsSemilinearSet hs.setOfFractNe : apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet) (LinearMap.funLeft ℕ ℕ Sum.inr) classical - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι convert! Nat.isSemilinearSet_setOf_mulVec_eq (κ := (ι ⊕ ι) ⊕ ι) 0 i (Matrix.fromCols (Matrix.fromCols 1 0) 1) (Matrix.fromCols (Matrix.fromCols 0 1) 0) using @@ -682,7 +682,7 @@ private theorem isSemilinearSet_setOfFloorNeg : IsSemilinearSet hs.setOfFloorNeg rw [setOf_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet.sdiff) (LinearMap.funLeft ℕ ℕ Sum.inr) - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι convert! Nat.isSemilinearSet_setOf_mulVec_eq (κ := ((ι ⊕ ι) ⊕ ι) ⊕ ι) i.1 hs.base (Matrix.fromCols (Matrix.fromCols (Matrix.fromCols 1 1) 0) 1) @@ -743,7 +743,7 @@ private theorem isSemilinearSet_setOfFloorPos : IsSemilinearSet hs.setOfFloorPos rw [setOf_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet.sdiff) (LinearMap.funLeft ℕ ℕ Sum.inr) - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι convert! Nat.isSemilinearSet_setOf_mulVec_eq (κ := ((ι ⊕ ι) ⊕ ι) ⊕ ι) 0 (hs.base + i.1) (Matrix.fromCols (Matrix.fromCols (Matrix.fromCols 1 0) 0) 1) diff --git a/Mathlib/ModelTheory/Definability.lean b/Mathlib/ModelTheory/Definability.lean index b219893edfb6f8..01d99e26babc3a 100644 --- a/Mathlib/ModelTheory/Definability.lean +++ b/Mathlib/ModelTheory/Definability.lean @@ -149,13 +149,13 @@ theorem definable_biUnion_finset {ι : Type*} {f : ι → Set (α → M)} theorem definable_iInter_of_finite {ι : Type*} [Finite ι] {f : ι → Set (α → M)} (hf : ∀ i, A.Definable L (f i)) : A.Definable L (⋂ i, f i) := by - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι convert! definable_finset_inf hf Finset.univ using 1 simp theorem definable_iUnion_of_finite {ι : Type*} [Finite ι] {f : ι → Set (α → M)} (hf : ∀ i, A.Definable L (f i)) : A.Definable L (⋃ i, f i) := by - haveI := Fintype.ofFinite ι + have := Fintype.ofFinite ι convert! definable_finset_sup hf Finset.univ using 1 simp diff --git a/Mathlib/ModelTheory/Fraisse.lean b/Mathlib/ModelTheory/Fraisse.lean index 9b89473fed2ffe..509a109eabc56d 100644 --- a/Mathlib/ModelTheory/Fraisse.lean +++ b/Mathlib/ModelTheory/Fraisse.lean @@ -376,7 +376,7 @@ protected theorem isExtensionPair : L.IsExtensionPair M N := by have S_in_age_N : ⟨S, inferInstance⟩ ∈ L.age N := by rw [hN.age, ← hM.age] exact ⟨(fg_iff_structure_fg S).1 S_FG, ⟨subtype _⟩⟩ - haveI nonempty_S_N : Nonempty (S ↪[L] N) := S_in_age_N.2 + have nonempty_S_N : Nonempty (S ↪[L] N) := S_in_age_N.2 let ⟨g, g_eq⟩ := hN.ultrahomogeneous.extend_embedding (f.dom.fg_iff_structure_fg.1 f_FG) ((subtype f.cod).comp f.toEquiv.toEmbedding) (inclusion (le_sup_left : _ ≤ S)) refine ⟨⟨⟨S, g.toHom.range, g.equivRange⟩, S_FG⟩, diff --git a/Mathlib/ModelTheory/Graph.lean b/Mathlib/ModelTheory/Graph.lean index 8506874b319565..deff4b767ccf25 100644 --- a/Mathlib/ModelTheory/Graph.lean +++ b/Mathlib/ModelTheory/Graph.lean @@ -77,7 +77,7 @@ theorem Theory.simpleGraph_model_iff [Language.graph.Structure V] : instance simpleGraph_model (G : SimpleGraph V) : @Theory.Model _ V G.structure Theory.simpleGraph := by - letI := G.structure + let := G.structure rw [Theory.simpleGraph_model_iff] exact ⟨G.loopless, G.symm⟩ diff --git a/Mathlib/ModelTheory/LanguageMap.lean b/Mathlib/ModelTheory/LanguageMap.lean index 19a26d6160d725..f6cb5d1463a1e0 100644 --- a/Mathlib/ModelTheory/LanguageMap.lean +++ b/Mathlib/ModelTheory/LanguageMap.lean @@ -264,7 +264,7 @@ theorem Injective.isExpansionOn_default {ϕ : L →ᴸ L'} [∀ (n) (r : L'.Relations n), Decidable (r ∈ Set.range fun r : L.Relations n => ϕ.onRelation r)] (h : ϕ.Injective) (M : Type*) [Inhabited M] [L.Structure M] : @IsExpansionOn L L' ϕ M _ (ϕ.defaultExpansion M) := by - letI := ϕ.defaultExpansion M + let := ϕ.defaultExpansion M refine ⟨fun {n} f xs => ?_, fun {n} r xs => ?_⟩ · have hf : ϕ.onFunction f ∈ Set.range fun f : L.Functions n => ϕ.onFunction f := ⟨f, rfl⟩ refine (dif_pos hf).trans ?_ @@ -361,8 +361,8 @@ def LHom.constantsOnMap (f : α → β) : constantsOn α →ᴸ constantsOn β w theorem constantsOnMap_isExpansionOn {f : α → β} {fα : α → M} {fβ : β → M} (h : fβ ∘ f = fα) : @LHom.IsExpansionOn _ _ (LHom.constantsOnMap f) M (constantsOn.structure fα) (constantsOn.structure fβ) := by - letI := constantsOn.structure fα - letI := constantsOn.structure fβ + let := constantsOn.structure fα + let := constantsOn.structure fβ exact ⟨fun {n} => Nat.casesOn n (fun F _x => (congr_fun h F :)) fun n F => isEmptyElim F, fun R => isEmptyElim R⟩ diff --git a/Mathlib/ModelTheory/Order.lean b/Mathlib/ModelTheory/Order.lean index fc01bc4c2f53c7..68783ea21debee 100644 --- a/Mathlib/ModelTheory/Order.lean +++ b/Mathlib/ModelTheory/Order.lean @@ -359,7 +359,7 @@ def leOfStructure : LE M where le a b := Structure.RelMap (leSymb : L.Relations 2) ![a, b] instance : @OrderedStructure L M _ (L.leOfStructure M) _ := by - letI := L.leOfStructure M + let := L.leOfStructure M constructor simp only [Fin.forall_fin_succ_pi, Fin.cons_zero, Fin.forall_fin_zero_pi] intros @@ -471,8 +471,8 @@ lemma dlo_isExtensionPair classical rw [isExtensionPair_iff_exists_embedding_closure_singleton_sup] intro S S_fg f m - letI := Language.order.linearOrderOfModels M - letI := Language.order.linearOrderOfModels N + let := Language.order.linearOrderOfModels M + let := Language.order.linearOrderOfModels N have := Language.order.denselyOrdered_of_dlo N have := Language.order.noBotOrder_of_dlo N have := Language.order.noTopOrder_of_dlo N @@ -499,7 +499,7 @@ lemma dlo_isExtensionPair set_option backward.isDefEq.respectTransparency false in instance (M : Type w) [Language.order.Structure M] [M ⊨ Language.order.dlo] [Nonempty M] : Infinite M := by - letI := orderStructure ℚ + let := orderStructure ℚ obtain ⟨f, _⟩ := embedding_from_cg cg_of_countable default (dlo_isExtensionPair ℚ M) exact Infinite.of_injective f f.injective @@ -511,8 +511,8 @@ lemma dlo_age [Language.order.Structure M] [Mdlo : M ⊨ Language.order.dlo] [No ext N refine ⟨fun ⟨hF, h⟩ => ⟨hF.finite, Theory.IsUniversal.models_of_embedding h.some⟩, fun ⟨hF, h⟩ => ⟨FG.of_finite, ?_⟩⟩ - letI := Language.order.linearOrderOfModels M - letI := Language.order.linearOrderOfModels N + let := Language.order.linearOrderOfModels M + let := Language.order.linearOrderOfModels N exact ⟨StrongHomClass.toEmbedding (nonempty_orderEmbedding_of_finite_infinite N M).some⟩ /-- Any countable nonempty model of the theory of dense linear orders is a Fraïssé limit of the @@ -528,7 +528,7 @@ set_option backward.isDefEq.respectTransparency false in theorem isFraisse_finite_linear_order : IsFraisse {M : CategoryTheory.Bundled.{0} Language.order.Structure | Finite M ∧ M ⊨ Language.order.linearOrderTheory} := by - letI : Language.order.Structure ℚ := orderStructure _ + let : Language.order.Structure ℚ := orderStructure _ exact (isFraisseLimit_of_countable_nonempty_dlo ℚ).isFraisse open Cardinal @@ -566,9 +566,9 @@ example (α β : Type w') [LinearOrder α] [LinearOrder β] [Countable α] [DenselyOrdered α] [NoMinOrder α] [NoMaxOrder α] [Nonempty α] [Countable β] [DenselyOrdered β] [NoMinOrder β] [NoMaxOrder β] [Nonempty β] : Nonempty (α ≃o β) := by - letI := orderStructure α - letI := orderStructure β - letI := StrongHomClass.toOrderIsoClass Language.order α β (α ≃[Language.order] β) + let := orderStructure α + let := orderStructure β + let := StrongHomClass.toOrderIsoClass Language.order α β (α ≃[Language.order] β) exact ⟨(IsFraisseLimit.nonempty_equiv (isFraisseLimit_of_countable_nonempty_dlo α) (isFraisseLimit_of_countable_nonempty_dlo β)).some⟩ diff --git a/Mathlib/ModelTheory/Satisfiability.lean b/Mathlib/ModelTheory/Satisfiability.lean index c36c9f809fde4c..0e68449bba6d96 100644 --- a/Mathlib/ModelTheory/Satisfiability.lean +++ b/Mathlib/ModelTheory/Satisfiability.lean @@ -89,7 +89,7 @@ theorem isSatisfiable_onTheory_iff {L' : Language.{w, w'}} {φ : L →ᴸ L'} (h (φ.onTheory T).IsSatisfiable ↔ T.IsSatisfiable := by classical refine ⟨isSatisfiable_of_isSatisfiable_onTheory φ, fun h' => ?_⟩ - haveI : Inhabited h'.some := Classical.inhabited_of_nonempty' + have : Inhabited h'.some := Classical.inhabited_of_nonempty' exact Model.isSatisfiable (h'.some.defaultExpansion h) theorem IsSatisfiable.isFinitelySatisfiable (h : T.IsSatisfiable) : T.IsFinitelySatisfiable := @@ -130,9 +130,9 @@ theorem isSatisfiable_union_distinctConstantsTheory_of_card_le (T : L.Theory) (s (M : Type w') [Nonempty M] [L.Structure M] [M ⊨ T] (h : Cardinal.lift.{w'} #s ≤ Cardinal.lift.{w} #M) : ((L.lhomWithConstants α).onTheory T ∪ L.distinctConstantsTheory s).IsSatisfiable := by - haveI : Inhabited M := Classical.inhabited_of_nonempty inferInstance + have : Inhabited M := Classical.inhabited_of_nonempty inferInstance rw [Cardinal.lift_mk_le'] at h - letI : (constantsOn α).Structure M := constantsOn.structure (Function.extend (↑) h.some default) + let : (constantsOn α).Structure M := constantsOn.structure (Function.extend (↑) h.some default) have : M ⊨ (L.lhomWithConstants α).onTheory T ∪ L.distinctConstantsTheory s := by refine ((LHom.onTheory_model _ _).2 inferInstance).union ?_ rw [model_distinctConstantsTheory] @@ -166,7 +166,7 @@ theorem exists_large_model_of_infinite_model (T : L.Theory) (κ : Cardinal.{w}) obtain ⟨N⟩ := isSatisfiable_union_distinctConstantsTheory_of_infinite T (Set.univ : Set κ.out) M refine ⟨(N.is_model.mono Set.subset_union_left).bundled.reduct _, ?_⟩ - haveI : N ⊨ distinctConstantsTheory _ _ := N.is_model.mono Set.subset_union_right + have : N ⊨ distinctConstantsTheory _ _ := N.is_model.mono Set.subset_union_right rw [ModelType.reduct_Carrier, coe_of] refine _root_.trans (lift_le.2 (le_of_eq (Cardinal.mk_out κ).symm)) ?_ rw [← mk_univ] @@ -229,8 +229,8 @@ theorem exists_elementaryEmbedding_card_eq_of_ge (M : Type w') [L.Structure M] [ rw [← lift_le.{w'}, lift_lift, lift_lift] at h1 exact ⟨h2, h1⟩) (hN0.trans (by rw [← lift_umax, lift_id])) - letI := (lhomWithConstants L M).reduct N - haveI h : N ⊨ L.elementaryDiagram M := + let := (lhomWithConstants L M).reduct N + have h : N ⊨ L.elementaryDiagram M := (NN0.theory_model_iff (L.elementaryDiagram M)).2 inferInstance refine ⟨Bundled.of N, ⟨?_⟩, hN⟩ apply ElementaryEmbedding.ofModelsElementaryDiagram L M N @@ -271,7 +271,7 @@ theorem exists_model_card_eq (h : ∃ M : ModelType.{u, v, max u v} T, Infinite cases h with | intro M MI => obtain ⟨N, hN, rfl⟩ := exists_elementarilyEquivalent_card_eq L M κ h1 h2 - haveI : Nonempty N := hN.nonempty + have : Nonempty N := hN.nonempty exact ⟨hN.theory_model.bundled, rfl⟩ variable (T) @@ -328,19 +328,19 @@ theorem models_formula_iff_onTheory_models_equivSentence {φ : L.Formula α} : T ⊨ᵇ φ ↔ (L.lhomWithConstants α).onTheory T ⊨ᵇ Formula.equivSentence φ := by refine ⟨fun h => models_sentence_iff.2 (fun M => ?_), fun h => models_formula_iff.2 (fun M v => ?_)⟩ - · letI := (L.lhomWithConstants α).reduct M + · let := (L.lhomWithConstants α).reduct M rw [Formula.realize_equivSentence] have : M ⊨ T := (LHom.onTheory_model _ _).1 M.is_model -- why isn't M.is_model inferInstance? let M' := Theory.ModelType.of T M exact h M' (fun a => (L.con a : M)) _ - · letI : (constantsOn α).Structure M := constantsOn.structure v + · let : (constantsOn α).Structure M := constantsOn.structure v have : M ⊨ (L.lhomWithConstants α).onTheory T := (LHom.onTheory_model _ _).2 inferInstance exact (Formula.realize_equivSentence _ _).1 (h.realize_sentence M) theorem ModelsBoundedFormula.realize_formula {φ : L.Formula α} (h : T ⊨ᵇ φ) (M : Type*) [L.Structure M] [M ⊨ T] [Nonempty M] {v : α → M} : φ.Realize v := by rw [models_formula_iff_onTheory_models_equivSentence] at h - letI : (constantsOn α).Structure M := constantsOn.structure v + let : (constantsOn α).Structure M := constantsOn.structure v have : M ⊨ (L.lhomWithConstants α).onTheory T := (LHom.onTheory_model _ _).2 inferInstance exact (Formula.realize_equivSentence _ _).1 (h.realize_sentence M) @@ -373,7 +373,7 @@ theorem models_iff_finset_models {φ : L.Sentence} : simp only [models_iff_not_satisfiable] rw [isSatisfiable_iff_isFinitelySatisfiable, IsFinitelySatisfiable] contrapose! - letI := Classical.decEq (Sentence L) + let := Classical.decEq (Sentence L) constructor · intro h T0 hT0 simpa using h (T0 ∪ {Formula.not φ}) @@ -517,8 +517,8 @@ theorem Categorical.isComplete (h : κ.Categorical T) (h1 : ℵ₀ ≤ κ) by_contra! ⟨⟨MF, hMF⟩, MT, hMT⟩ rw [Sentence.realize_not, Classical.not_not] at hMT refine hMF ?_ - haveI := hT MT - haveI := hT MF + have := hT MT + have := hT MF obtain ⟨NT, MNT, hNT⟩ := exists_elementarilyEquivalent_card_eq L MT κ h1 h2 obtain ⟨NF, MNF, hNF⟩ := exists_elementarilyEquivalent_card_eq L MF κ h1 h2 obtain ⟨TF⟩ := h (MNT.toModel T) (MNF.toModel T) hNT hNF diff --git a/Mathlib/ModelTheory/Substructures.lean b/Mathlib/ModelTheory/Substructures.lean index a7039badaf7741..934ce661ade2b7 100644 --- a/Mathlib/ModelTheory/Substructures.lean +++ b/Mathlib/ModelTheory/Substructures.lean @@ -321,7 +321,7 @@ lemma mem_closure_iff_of_isRelational [L.IsRelational] (s : Set M) (m : M) : theorem _root_.Set.Countable.substructure_closure [Countable (Σ l, L.Functions l)] (h : s.Countable) : Countable.{w + 1} (closure L s) := by - haveI : Countable s := h.to_subtype + have : Countable s := h.to_subtype rw [← mk_le_aleph0_iff, ← lift_le_aleph0] exact lift_card_closure_le_card_term.trans mk_le_aleph0 @@ -378,7 +378,7 @@ theorem closure_insert (s : Set M) (m : M) : closure L (insert m s) = closure L instance small_bot : Small.{u} (⊥ : L.Substructure M) := by rw [← closure_empty] - haveI : Small.{u} (∅ : Set M) := small_subsingleton _ + have : Small.{u} (∅ : Set M) := small_subsingleton _ exact Substructure.small_closure theorem iSup_eq_closure {ι : Sort*} (S : ι → L.Substructure M) : @@ -400,7 +400,7 @@ theorem mem_iSup_of_directed {ι : Type*} [hι : Nonempty ι] {S : ι → L.Subs theorem mem_sSup_of_directedOn {S : Set (L.Substructure M)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : M} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, Subtype.exists, exists_prop] variable (L) (M) diff --git a/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean b/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean index 9bb6058a90ae1f..281104403f2f70 100644 --- a/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean +++ b/Mathlib/NumberTheory/ClassNumber/AdmissibleAbsoluteValue.lean @@ -72,7 +72,7 @@ whose remainders are close together, pointwise. -/ theorem exists_approx_aux (n : ℕ) (h : abv.IsAdmissible) : ∀ {ε : ℝ} (_hε : 0 < ε) {b : R} (_hb : b ≠ 0) (A : Fin (h.card ε ^ n).succ → Fin n → R), ∃ i₀ i₁, i₀ ≠ i₁ ∧ ∀ k, (abv (A i₁ k % b - A i₀ k % b) : ℝ) < abv b • ε := by - haveI := Classical.decEq R + have := Classical.decEq R induction n with | zero => intro ε _hε b _hb A diff --git a/Mathlib/NumberTheory/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/Cyclotomic/Basic.lean index 7e7c1e70257a3b..7eed25c14848e9 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Basic.lean @@ -291,9 +291,9 @@ variable (A B) protected theorem equiv {C : Type*} [CommRing C] [Algebra A C] [h : IsCyclotomicExtension S A B] (f : B ≃ₐ[A] C) : IsCyclotomicExtension S A C := by - letI : Algebra B C := f.toAlgHom.toRingHom.toAlgebra - haveI : IsCyclotomicExtension {1} B C := singleton_one_of_algebraMap_bijective f.surjective - haveI : IsScalarTower A B C := IsScalarTower.of_algHom f.toAlgHom + let : Algebra B C := f.toAlgHom.toRingHom.toAlgebra + have : IsCyclotomicExtension {1} B C := singleton_one_of_algebraMap_bijective f.surjective + have : IsScalarTower A B C := IsScalarTower.of_algHom f.toAlgHom exact (iff_union_singleton_one _ _ _).2 (trans S {1} A B C f.injective) theorem neZero_of_mem [IsCyclotomicExtension S A B] [IsDomain B] (hn : n ∈ S) : NeZero (n : B) := @@ -410,8 +410,8 @@ protected theorem finite [IsDomain B] [h₁ : Finite S] [h₂ : IsCyclotomicExte theorem numberField [h : NumberField K] [Finite S] [IsCyclotomicExtension S K L] : NumberField L := { to_charZero := charZero_of_injective_algebraMap (algebraMap K L).injective to_finiteDimensional := by - haveI := charZero_of_injective_algebraMap (algebraMap K L).injective - haveI := IsCyclotomicExtension.finite S K L + have := charZero_of_injective_algebraMap (algebraMap K L).injective + have := IsCyclotomicExtension.finite S K L exact Module.Finite.trans K _ } /-- If `S` is finite and `IsCyclotomicExtension S K A`, then `finiteDimensional K A`. -/ @@ -634,7 +634,7 @@ theorem splitting_field_cyclotomic : IsSplittingField K L (cyclotomic n K) := { splits' := splits_cyclotomic K L (mem_singleton n) adjoin_rootSet' := by rw [← ((iff_adjoin_eq_top {n} K L).1 inferInstance).2] - letI := Classical.decEq L + let := Classical.decEq L obtain ⟨ζ : L, hζ⟩ := IsCyclotomicExtension.exists_isPrimitiveRoot K L (mem_singleton n) (NeZero.ne _) exact adjoin_roots_cyclotomic_eq_adjoin_nth_roots hζ } @@ -675,7 +675,7 @@ instance isCyclotomicExtension [NeZero (n : K)] : IsCyclotomicExtension {n} K (CyclotomicField n K) := by have : NeZero (n : CyclotomicField n K) := NeZero.nat_of_injective (algebraMap K _).injective - letI := Classical.decEq (CyclotomicField n K) + let := Classical.decEq (CyclotomicField n K) have := (degree_cyclotomic_pos n K (NeZero.pos n)).ne' obtain ⟨ζ, hζ⟩ := Splits.exists_eval_eq_zero (SplittingField.splits (cyclotomic n K)) (by rwa [degree_map]) @@ -811,7 +811,7 @@ instance [IsFractionRing A K] [IsDomain A] [NeZero (n : A)] : obtain ⟨⟨z, w⟩, hw⟩ := this k refine ⟨⟨algebraMap A (CyclotomicRing n A K) z, algebraMap A (CyclotomicRing n A K) w, map_mem_nonZeroDivisors _ (algebraBase_injective n A K) w.2⟩, ?_⟩ - letI : IsScalarTower A K (CyclotomicField n K) := + let : IsScalarTower A K (CyclotomicField n K) := IsScalarTower.of_algebraMap_eq (congr_fun rfl) rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply, @IsScalarTower.algebraMap_apply A K _ _ _ _ _ (_root_.CyclotomicField.algebra n K) _ _ w, diff --git a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean index eaa68d6f06b3d3..0f40c346fad4e0 100644 --- a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean +++ b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean @@ -309,13 +309,13 @@ noncomputable def cyclotomicCharacter (p : ℕ) [Fact p.Prime] : { toFun g := cyclotomicCharacter.toFun p g map_one' := by by_cases H : ∀ (i : ℕ), ∃ ζ : L, IsPrimitiveRoot ζ (p ^ i) - · haveI _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ + · have _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ refine PadicInt.ext_of_toZModPow.mp fun n ↦ ?_ simp [cyclotomicCharacter.toZModPow_toFun] · simp [cyclotomicCharacter.toFun, dif_neg H] map_mul' f g := by by_cases H : ∀ (i : ℕ), ∃ ζ : L, IsPrimitiveRoot ζ (p ^ i) - · haveI _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ + · have _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ refine PadicInt.ext_of_toZModPow.mp fun n ↦ ?_ simp [cyclotomicCharacter.toZModPow_toFun] · simp [cyclotomicCharacter.toFun, dif_neg H] } @@ -339,7 +339,7 @@ lemma cyclotomicCharacter.continuous (p : ℕ) [Fact p.Prime] by_cases H : ∀ (i : ℕ), ∃ ζ : L, IsPrimitiveRoot ζ (p ^ i); swap · simp only [cyclotomicCharacter, cyclotomicCharacter.toFun, dif_neg H, MonoidHom.coe_comp] exact continuous_const (y := 1) - haveI _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ + have _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ choose ζ hζ using H refine Continuous.of_coeHom_comp ?_ apply continuous_of_continuousAt_one diff --git a/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean b/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean index 21e681b2319ffd..dc74f022f495ea 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Discriminant.lean @@ -40,7 +40,7 @@ variable [ce : IsCyclotomicExtension {n} ℚ K] discriminant of the power basis given by `ζ - 1`. -/ theorem discr_zeta_eq_discr_zeta_sub_one (hζ : IsPrimitiveRoot ζ n) : discr ℚ (hζ.powerBasis ℚ).basis = discr ℚ (hζ.subOnePowerBasis ℚ).basis := by - haveI : NumberField K := @NumberField.mk _ _ _ (IsCyclotomicExtension.finiteDimensional {n} ℚ K) + have : NumberField K := @NumberField.mk _ _ _ (IsCyclotomicExtension.finiteDimensional {n} ℚ K) have H₁ : (aeval (hζ.powerBasis ℚ).gen) (X - 1 : ℤ[X]) = (hζ.subOnePowerBasis ℚ).gen := by simp have H₂ : (aeval (hζ.subOnePowerBasis ℚ).gen) (X + 1 : ℤ[X]) = (hζ.powerBasis ℚ).gen := by simp refine discr_eq_discr_of_toMatrix_coeff_isIntegral _ (fun i j => toMatrix_isIntegral H₁ ?_ ?_ _ _) @@ -65,9 +65,9 @@ theorem discr_prime_pow_ne_two [IsCyclotomicExtension {p ^ (k + 1)} K L] [hp : F (hζ : IsPrimitiveRoot ζ (p ^ (k + 1))) (hirr : Irreducible (cyclotomic (p ^ (k + 1)) K)) (hk : p ^ (k + 1) ≠ 2) : discr K (hζ.powerBasis K).basis = (-1) ^ ((p ^ (k + 1)).totient / 2) * p ^ (p ^ k * ((p - 1) * (k + 1) - 1)) := by - haveI hne := IsCyclotomicExtension.neZero' (p ^ (k + 1)) K L - haveI mf : Module.Finite K L := finiteDimensional {p ^ (k + 1)} K L - haveI se : Algebra.IsSeparable K L := isSeparable {p ^ (k + 1)} K L + have hne := IsCyclotomicExtension.neZero' (p ^ (k + 1)) K L + have mf : Module.Finite K L := finiteDimensional {p ^ (k + 1)} K L + have se : Algebra.IsSeparable K L := isSeparable {p ^ (k + 1)} K L rw [discr_powerBasis_eq_norm, finrank L hirr, hζ.powerBasis_gen _, ← hζ.minpoly_eq_cyclotomic_of_irreducible hirr, totient_prime_pow hp.out (succ_pos k), Nat.add_one_sub_one] diff --git a/Mathlib/NumberTheory/Cyclotomic/Gal.lean b/Mathlib/NumberTheory/Cyclotomic/Gal.lean index fb8e0532ac4489..8d1c76196a7cfa 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Gal.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Gal.lean @@ -81,7 +81,7 @@ noncomputable def autEquivPow (h : Irreducible (cyclotomic n K)) : Gal(L/K) ≃* invFun := fun t => (hζ.powerBasis K).equivOfMinpoly ((hμ t).powerBasis K) (by - haveI := IsCyclotomicExtension.neZero' n K L + have := IsCyclotomicExtension.neZero' n K L simp only [IsPrimitiveRoot.powerBasis_gen] have hr := IsPrimitiveRoot.minpoly_eq_cyclotomic_of_irreducible diff --git a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean index 39cdd13911878b..49dc6c38d86dd1 100644 --- a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean +++ b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean @@ -178,7 +178,7 @@ variable {K} (L) /-- If `Irreducible (cyclotomic n K)` (in particular for `K = ℚ`), then the `finrank` of a cyclotomic extension is `n.totient`. -/ theorem finrank (hirr : Irreducible (cyclotomic n K)) : finrank K L = n.totient := by - haveI := IsCyclotomicExtension.neZero' n K L + have := IsCyclotomicExtension.neZero' n K L rw [((zeta_spec n K L).powerBasis K).finrank, IsPrimitiveRoot.powerBasis_dim, ← (zeta_spec n K L).minpoly_eq_cyclotomic_of_irreducible hirr, natDegree_cyclotomic] @@ -197,7 +197,7 @@ theorem _root_.IsPrimitiveRoot.lcm_totient_le_finrank [FiniteDimensional K L] {p let z := x ^ (p / factorizationLCMLeft p q) * y ^ (q / factorizationLCMRight p q) let k := PNat.lcm ⟨p, hppos⟩ ⟨q, hqpos⟩ have : IsPrimitiveRoot z k := hx.pow_mul_pow_lcm hy hppos.ne' hqpos.ne' - haveI := IsPrimitiveRoot.adjoin_isCyclotomicExtension K this + have := IsPrimitiveRoot.adjoin_isCyclotomicExtension K this convert! Submodule.finrank_le (Subalgebra.toSubmodule (adjoin K { z })) rw [show Nat.lcm p q = (k : ℕ) from rfl] at hirr simpa using! (IsCyclotomicExtension.finrank (Algebra.adjoin K {z}) hirr).symm @@ -290,7 +290,7 @@ include hζ `1` if `n ≠ 2`. -/ theorem norm_eq_one [IsDomain L] [IsCyclotomicExtension {n} K L] (hn : n ≠ 2) (hirr : Irreducible (cyclotomic n K)) : norm K ζ = 1 := by - haveI := IsCyclotomicExtension.neZero' n K L + have := IsCyclotomicExtension.neZero' n K L by_cases h1 : n = 1 · rw [h1, one_right_iff] at hζ rw [hζ, show 1 = algebraMap K L 1 by simp, Algebra.norm_algebraMap, one_pow] @@ -332,12 +332,12 @@ include hζ `ζ - 1` is `eval 1 (cyclotomic n ℤ)`. -/ theorem sub_one_norm_eq_eval_cyclotomic [IsCyclotomicExtension {n} K L] (h : 2 < n) (hirr : Irreducible (cyclotomic n K)) : norm K (ζ - 1) = ↑(eval 1 (cyclotomic n ℤ)) := by - haveI := IsCyclotomicExtension.neZero' n K L + have := IsCyclotomicExtension.neZero' n K L let E := AlgebraicClosure L obtain ⟨z, hz⟩ := IsAlgClosed.exists_root _ (degree_cyclotomic_pos n E (NeZero.pos _)).ne.symm apply (algebraMap K E).injective - letI := IsCyclotomicExtension.finiteDimensional {n} K L - letI := IsCyclotomicExtension.isGalois {n} K L + let := IsCyclotomicExtension.finiteDimensional {n} K L + let := IsCyclotomicExtension.isGalois {n} K L rw [norm_eq_prod_embeddings] conv_lhs => congr @@ -378,7 +378,7 @@ theorem minpoly_sub_one_eq_cyclotomic_comp [Algebra K A] [IsDomain A] {ζ : A} [IsCyclotomicExtension {n} K A] (hζ : IsPrimitiveRoot ζ n) (h : Irreducible (Polynomial.cyclotomic n K)) : minpoly K (ζ - 1) = (cyclotomic n K).comp (X + 1) := by - haveI := IsCyclotomicExtension.neZero' n K A + have := IsCyclotomicExtension.neZero' n K A rw [show ζ - 1 = ζ + algebraMap K A (-1) by simp [sub_eq_add_neg], minpoly.add_algebraMap ζ, hζ.minpoly_eq_cyclotomic_of_irreducible h] @@ -467,7 +467,7 @@ theorem norm_sub_one_of_prime_ne_two' [hpri : Fact p.Prime] (hirr : Irreducible (cyclotomic p K)) (h : p ≠ 2) : norm K (ζ - 1) = p := by replace hirr : Irreducible (cyclotomic (p ^ (0 + 1)) K) := by simp [hirr] replace hζ : IsPrimitiveRoot ζ (p ^ (0 + 1)) := by simp [hζ] - haveI : IsCyclotomicExtension {p ^ (0 + 1)} K L := by simp [hcyc] + have : IsCyclotomicExtension {p ^ (0 + 1)} K L := by simp [hcyc] simpa using norm_sub_one_of_prime_ne_two hζ hirr h /-- If `Irreducible (cyclotomic (2 ^ (k + 1)) K)` (in particular for `K = ℚ`), then the norm of diff --git a/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean b/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean index f666358b220b7f..e24ca61b0261ee 100644 --- a/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean +++ b/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean @@ -183,7 +183,7 @@ lemma hasSum_int_cosKernel (a : ℝ) {t : ℝ} (ht : 0 < t) : lemma hasSum_int_evenKernel₀ (a : ℝ) {t : ℝ} (ht : 0 < t) : HasSum (fun n : ℤ ↦ if n + a = 0 then 0 else rexp (-π * (n + a) ^ 2 * t)) (evenKernel a t - if (a : UnitAddCircle) = 0 then 1 else 0) := by - haveI := Classical.propDecidable -- speed up instance search for `if / then / else` + have := Classical.propDecidable -- speed up instance search for `if / then / else` simp_rw [AddCircle.coe_eq_zero_iff, zsmul_one] split_ifs with h · obtain ⟨k, rfl⟩ := h diff --git a/Mathlib/NumberTheory/LegendreSymbol/Basic.lean b/Mathlib/NumberTheory/LegendreSymbol/Basic.lean index d7a0950ee86474..f88b8b925788ee 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/Basic.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/Basic.lean @@ -225,7 +225,7 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero {p : ℕ} [Fact p.Prime] {a : ℤ} (ha : of the equation `x^2 - a*y^2 = 0` with `x ≠ 0`. -/ theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha : (a : ZMod p) ≠ 0) {x y : ZMod p} (hx : x ≠ 0) (hxy : x ^ 2 - a * y ^ 2 = 0) : legendreSym p a = 1 := by - haveI hy : y ≠ 0 := by + have hy : y ≠ 0 := by rintro rfl rw [zero_pow two_ne_zero, mul_zero, sub_zero, sq_eq_zero_iff] at hxy exact hx hxy diff --git a/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean b/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean index b6bd0e447a5270..0d7e121c0a5497 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean @@ -204,7 +204,7 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0 /-- **Eisenstein's lemma** -/ theorem eisenstein_lemma {p : ℕ} [Fact p.Prime] (hp : p ≠ 2) {a : ℕ} (ha1 : a % 2 = 1) (ha0 : (a : ZMod p) ≠ 0) : legendreSym p a = (-1) ^ ∑ x ∈ Ico 1 (p / 2).succ, x * a / p := by - haveI hp' : Fact (p % 2 = 1) := ⟨(Nat.Prime.mod_two_eq_one_iff_ne_two Fact.out).mpr hp⟩ + have hp' : Fact (p % 2 = 1) := ⟨(Nat.Prime.mod_two_eq_one_iff_ne_two Fact.out).mpr hp⟩ have ha0' : ((a : ℤ) : ZMod p) ≠ 0 := by norm_cast rw [neg_one_pow_eq_pow_mod_two, gauss_lemma hp ha0', neg_one_pow_eq_pow_mod_two, (by norm_cast : ((a : ℤ) : ZMod p) = (a : ZMod p)), diff --git a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean index 501714b52998c2..64c2a695430e8a 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean @@ -140,7 +140,7 @@ theorem trichotomy (a : ℤ) (b : ℕ) : J(a | b) = 0 ∨ J(a | b) = 1 ∨ J(a | (by intro _ ha' rcases List.mem_pmap.mp ha' with ⟨p, hp, rfl⟩ - haveI : Fact p.Prime := ⟨prime_of_mem_primeFactorsList hp⟩ + have : Fact p.Prime := ⟨prime_of_mem_primeFactorsList hp⟩ exact quadraticChar_isQuadratic (ZMod p) a) /-- The symbol `J(1 | b)` has the value `1`. -/ diff --git a/Mathlib/NumberTheory/LocalField/Basic.lean b/Mathlib/NumberTheory/LocalField/Basic.lean index dd9694d4d63bb9..5d67a6c2ae686a 100644 --- a/Mathlib/NumberTheory/LocalField/Basic.lean +++ b/Mathlib/NumberTheory/LocalField/Basic.lean @@ -61,16 +61,16 @@ variable (K : Type*) [Field K] [ValuativeRel K] [TopologicalSpace K] [IsNonarchi attribute [local simp] zero_lt_iff instance : IsTopologicalDivisionRing K := by - letI := IsTopologicalAddGroup.rightUniformSpace K - haveI := isUniformAddGroup_of_addCommGroup (G := K) + let := IsTopologicalAddGroup.rightUniformSpace K + have := isUniformAddGroup_of_addCommGroup (G := K) infer_instance lemma isCompact_closedBall (γ : ValueGroupWithZero K) : IsCompact { x | valuation K x ≤ γ } := by obtain ⟨γ, rfl⟩ := ValuativeRel.valuation_surjective γ by_cases hγ : γ = 0 · simp [hγ] - letI := IsTopologicalAddGroup.rightUniformSpace K - letI := isUniformAddGroup_of_addCommGroup (G := K) + let := IsTopologicalAddGroup.rightUniformSpace K + let := isUniformAddGroup_of_addCommGroup (G := K) obtain ⟨s, hs, -, hs'⟩ := LocallyCompactSpace.local_compact_nhds (0 : K) .univ Filter.univ_mem obtain ⟨r, hr, hr1, H⟩ : ∃ r', r' ≠ 0 ∧ valuation K r' < 1 ∧ { x | valuation K x ≤ valuation K r' } ⊆ s := by @@ -115,8 +115,8 @@ instance : IsDiscreteValuationRing 𝒪[K] := noncomputable def valueGroupWithZeroIsoInt : ValueGroupWithZero K ≃*o ℤᵐ⁰ := by apply Nonempty.some - letI := IsTopologicalAddGroup.rightUniformSpace K - haveI := isUniformAddGroup_of_addCommGroup (G := K) + let := IsTopologicalAddGroup.rightUniformSpace K + have := isUniformAddGroup_of_addCommGroup (G := K) obtain ⟨_⟩ := Valued.integer.locallyFiniteOrder_units_mrange_of_isCompact_integer (isCompact_iff_compactSpace.mpr (inferInstance : CompactSpace 𝒪[K])) let e : (MonoidHom.mrange (valuation K)) ≃*o ValueGroupWithZero K := diff --git a/Mathlib/NumberTheory/LucasLehmer.lean b/Mathlib/NumberTheory/LucasLehmer.lean index 137d17b82b52ba..afc09ce76a8afc 100644 --- a/Mathlib/NumberTheory/LucasLehmer.lean +++ b/Mathlib/NumberTheory/LucasLehmer.lean @@ -555,7 +555,7 @@ theorem order_ω (p' : ℕ) (h : lucasLehmerResidue (p' + 2) = 0) : orderOf_dvd_iff_pow_eq_one.1 o have h : (1 : ZMod (q (p' + 2))) = -1 := congr_arg Prod.fst (ω_pow.symm.trans (ω_pow_eq_neg_one p' h)) - haveI : Fact (2 < (q (p' + 2) : ℕ)) := ⟨two_lt_q _⟩ + have : Fact (2 < (q (p' + 2) : ℕ)) := ⟨two_lt_q _⟩ apply ZMod.neg_one_ne_one h.symm · apply orderOf_dvd_iff_pow_eq_one.2 apply Units.ext diff --git a/Mathlib/NumberTheory/Modular.lean b/Mathlib/NumberTheory/Modular.lean index dbd0b531c022d9..9b80cbcdb1791b 100644 --- a/Mathlib/NumberTheory/Modular.lean +++ b/Mathlib/NumberTheory/Modular.lean @@ -115,7 +115,7 @@ theorem tendsto_normSq_coprime_pair : Filter.Tendsto (fun p : Fin 2 → ℤ => normSq ((p 0 : ℂ) * z + p 1)) cofinite atTop := by -- using this instance rather than the automatic `Function.module` makes unification issues in -- `LinearEquiv.isClosedEmbedding_of_injective` less bad later in the proof. - letI : Module ℝ (Fin 2 → ℝ) := NormedSpace.toModule + let : Module ℝ (Fin 2 → ℝ) := NormedSpace.toModule let π₀ : (Fin 2 → ℝ) →ₗ[ℝ] ℝ := LinearMap.proj 0 let π₁ : (Fin 2 → ℝ) →ₗ[ℝ] ℝ := LinearMap.proj 1 let f : (Fin 2 → ℝ) →ₗ[ℝ] ℂ := π₀.smulRight (z : ℂ) + π₁.smulRight 1 @@ -294,7 +294,7 @@ theorem exists_max_im : ∃ g : SL(2, ℤ), ∀ g' : SL(2, ℤ), (g' • z).im theorem exists_row_one_eq_and_min_re {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) : ∃ g : SL(2, ℤ), g 1 = cd ∧ ∀ g' : SL(2, ℤ), g 1 = g' 1 → |(g • z).re| ≤ |(g' • z).re| := by - haveI : Nonempty { g : SL(2, ℤ) // g 1 = cd } := + have : Nonempty { g : SL(2, ℤ) // g 1 = cd } := let ⟨x, hx⟩ := bottom_row_surj hcd ⟨⟨x, hx.2⟩⟩ obtain ⟨g, hg⟩ := Filter.Tendsto.exists_forall_le (tendsto_abs_re_smul z hcd) diff --git a/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean b/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean index 0e53a993d11ea0..beb3d1992c98bb 100644 --- a/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean +++ b/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean @@ -299,7 +299,7 @@ lemma finiteIndex_conjGL (g : GL (Fin 2) ℚ) : (conjGL ⊤ (g.map <| Rat.castHo obtain ⟨N, hN, hN'⟩ := exists_Gamma_le_conj' g 1 rw [Gamma_one_top, ← MonoidHom.range_eq_map] at hN' suffices Γ(N) ≤ (t • 𝒮ℒ ⊓ 𝒮ℒ).comap (mapGL ℝ) by - haveI _ : NeZero N := ⟨hN⟩ + have _ : NeZero N := ⟨hN⟩ simpa only [index_comap] using! (finiteIndex_of_le this).index_ne_zero intro k hk simpa [mem_pointwise_smul_iff_inv_smul_mem] using! @@ -329,7 +329,7 @@ lemma IsCongruenceSubgroup.conjGL {Γ : Subgroup SL(2, ℤ)} (hΓ : IsCongruence (g : GL (Fin 2) ℚ) : IsCongruenceSubgroup (conjGL Γ (g.map <| Rat.castHom ℝ)) := by obtain ⟨M, hN, hΓM⟩ := hΓ - haveI _ : NeZero M := ⟨hN⟩ + have _ : NeZero M := ⟨hN⟩ obtain ⟨N, hN, hN'⟩ := exists_Gamma_le_conj' g M rw [Subgroup.pointwise_smul_subset_iff] at hN' refine ⟨N, ‹_›, fun x hx ↦ ?_⟩ diff --git a/Mathlib/NumberTheory/ModularForms/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/QExpansion.lean index cddcd9165a1348..ddf5691779616f 100644 --- a/Mathlib/NumberTheory/ModularForms/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/QExpansion.lean @@ -244,7 +244,7 @@ private lemma hasFPowerSeriesOnBall_update {f : ℍ → ℂ} (hh : 0 < h) {c : rcases eq_or_ne r 0 with rfl | hr' · simp · lift r to NNReal using hr.ne_top - letI : FiniteDimensional ℝ ℂ := basisOneI.finiteDimensional_of_finite + let : FiniteDimensional ℝ ℂ := basisOneI.finiteDimensional_of_finite apply FormalMultilinearSeries.le_radius_of_summable simpa [smul_eq_mul, norm_mul, mul_comm, mul_left_comm, mul_assoc] using (hasSum_cuspFunction_of_hasSum_punctured hh hf (q := r) (by simpa using hr) diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index e177981d40d19d..dfc5b778061fab 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -90,7 +90,7 @@ theorem isIntegralClosure_adjoin_singleton_of_prime_pow [hcycl : IsCyclotomicExt let B := hζ.subOnePowerBasis ℚ have hint : IsIntegral ℤ B.gen := (hζ.isIntegral (NeZero.pos _)).sub isIntegral_one -- This can't be a `local instance` because it has metavariables. - letI := IsCyclotomicExtension.finiteDimensional {p ^ k} ℚ K + let := IsCyclotomicExtension.finiteDimensional {p ^ k} ℚ K have H := discr_mul_isIntegral_mem_adjoin ℚ hint h obtain ⟨u, n, hun⟩ := discr_prime_pow_eq_unit_mul_pow' hζ rw [hun] at H @@ -98,7 +98,7 @@ theorem isIntegralClosure_adjoin_singleton_of_prime_pow [hcycl : IsCyclotomicExt rw [← smul_assoc, ← smul_mul_assoc, Units.inv_eq_val_inv, zsmul_eq_mul, ← Int.cast_mul, Units.inv_mul, Int.cast_one, one_mul, smul_def, map_pow] at H cases k - · haveI : IsCyclotomicExtension {1} ℚ K := by simpa using hcycl + · have : IsCyclotomicExtension {1} ℚ K := by simpa using hcycl have : x ∈ (⊥ : Subalgebra ℚ K) := by rw [singleton_one ℚ K] exact mem_top @@ -255,7 +255,7 @@ theorem subOneIntegralPowerBasisOfPrimePow_gen [IsCyclotomicExtension {p ^ k} theorem zeta_sub_one_prime_of_ne_two [IsCyclotomicExtension {p ^ (k + 1)} ℚ K] (hζ : IsPrimitiveRoot ζ (p ^ (k + 1))) (hodd : p ≠ 2) : Prime (hζ.toInteger - 1) := by - letI := IsCyclotomicExtension.numberField {p ^ (k + 1)} ℚ K + let := IsCyclotomicExtension.numberField {p ^ (k + 1)} ℚ K refine Ideal.prime_of_irreducible_absNorm_span (fun h ↦ ?_) ?_ · apply hζ.pow_ne_one_of_pos_of_lt one_ne_zero (one_lt_pow₀ hp.out.one_lt (by simp)) rw [sub_eq_zero] at h @@ -664,7 +664,7 @@ Computes the absolute discriminant of the `n`-th cyclotomic field. theorem discr [hK : IsCyclotomicExtension {n} ℚ K] : haveI : NumberField K := IsCyclotomicExtension.numberField {n} ℚ K discr K = (-1) ^ (φ n / 2) * (n ^ φ n / ∏ p ∈ n.primeFactors, p ^ (φ n / (p - 1))) := by - haveI : NumberField K := IsCyclotomicExtension.numberField {n} ℚ K + have : NumberField K := IsCyclotomicExtension.numberField {n} ℚ K rw [← Int.sign_mul_natAbs (NumberField.discr K), sign_discr, nrComplexPlaces_eq_totient_div_two n] congr induction n using Nat.recOnPrimeCoprime generalizing K hn with @@ -767,7 +767,7 @@ open IntermediateField Algebra in theorem adjoin_singleton_eq_top [hK : IsCyclotomicExtension {n} ℚ K] {ζ : K} (hζ : IsPrimitiveRoot ζ n) : ℤ[hζ.toInteger] = ⊤ := by - haveI : NumberField K := IsCyclotomicExtension.numberField {n} ℚ K + have : NumberField K := IsCyclotomicExtension.numberField {n} ℚ K induction n using Nat.recOnPrimeCoprime generalizing K hn with | zero => exact (neZero_zero_iff_false.mp hn).elim | prime_pow p k hp => diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean index b07cdf0a60b849..9144e95ea4163d 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean @@ -411,7 +411,7 @@ theorem finite_of_discr_bdd_of_isReal : simp_rw [Set.mem_iUnion] -- this is purely an optimization have : CharZero K := SubsemiringClass.instCharZero K - haveI : NumberField K := @NumberField.mk _ _ inferInstance hK₀ + have : NumberField K := @NumberField.mk _ _ inferInstance hK₀ obtain ⟨w₀, hw₀⟩ := hK₁ suffices minkowskiBound K ↑1 < (convexBodyLTFactor K) * B by obtain ⟨x, hx₁, hx₂⟩ := exists_primitive_element_lt_of_isReal K hw₀ this @@ -460,7 +460,7 @@ theorem finite_of_discr_bdd_of_isComplex : simp_rw [Set.mem_iUnion] -- this is purely an optimization have : CharZero K := SubsemiringClass.instCharZero K - haveI : NumberField K := @NumberField.mk _ _ inferInstance hK₀ + have : NumberField K := @NumberField.mk _ _ inferInstance hK₀ obtain ⟨w₀, hw₀⟩ := hK₁ suffices minkowskiBound K ↑1 < (convexBodyLT'Factor K) * boundOfDiscBdd N by obtain ⟨x, hx₁, hx₂⟩ := exists_primitive_element_lt_of_isComplex K hw₀ this @@ -503,7 +503,7 @@ theorem _root_.NumberField.finite_of_discr_bdd : rintro ⟨K, hK₀⟩ hK₁ -- this is purely an optimization have : CharZero K := SubsemiringClass.instCharZero K - haveI : NumberField K := @NumberField.mk _ _ inferInstance hK₀ + have : NumberField K := @NumberField.mk _ _ inferInstance hK₀ obtain ⟨w₀⟩ := (inferInstance : Nonempty (InfinitePlace K)) by_cases hw₀ : IsReal w₀ · apply Set.mem_union_left diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean index b6646e9377dd59..2fe245f773389e 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean @@ -178,7 +178,7 @@ noncomputable def lift [Algebra k K] [Algebra.IsAlgebraic k K] (φ : k →+* ℂ theorem lift_comp_algebraMap [Algebra k K] [Algebra.IsAlgebraic k K] (φ : k →+* ℂ) : (lift K φ).comp (algebraMap k K) = φ := by unfold lift - letI := φ.toAlgebra + let := φ.toAlgebra rw [AlgHom.toRingHom_eq_coe, AlgHom.comp_algebraMap_of_tower, RingHom.algebraMap_toAlgebra'] @[simp] @@ -243,8 +243,8 @@ lemma isReal_comp_iff {f : k ≃+* K} {φ : K →+* ℂ} : lemma exists_comp_symm_eq_of_comp_eq [Algebra k K] [IsGalois k K] (φ ψ : K →+* ℂ) (h : φ.comp (algebraMap k K) = ψ.comp (algebraMap k K)) : ∃ σ : Gal(K/k), φ.comp σ.symm = ψ := by - letI := (φ.comp (algebraMap k K)).toAlgebra - letI := φ.toAlgebra + let := (φ.comp (algebraMap k K)).toAlgebra + let := φ.toAlgebra have : IsScalarTower k K ℂ := IsScalarTower.of_algebraMap_eq' rfl let ψ' : K →ₐ[k] ℂ := { ψ with commutes' := fun r ↦ (RingHom.congr_fun h r).symm } use (AlgHom.restrictNormal' ψ' K).symm diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean index 5574e2aef5f7e5..dba874d28ca7c8 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean @@ -334,8 +334,8 @@ lemma isUnramified_mk_iff_forall_isConj [IsGalois k K] {φ : K →+* ℂ} : rw [not_isUnramified_iff] at hφ rw [comap_mk, isReal_mk_iff, ← not_isReal_iff_isComplex, isReal_mk_iff, ← ComplexEmbedding.isConj_one_iff (k := k)] at hφ - letI := (φ.comp (algebraMap k K)).toAlgebra - letI := φ.toAlgebra + let := (φ.comp (algebraMap k K)).toAlgebra + let := φ.toAlgebra have : IsScalarTower k K ℂ := IsScalarTower.of_algebraMap_eq' rfl let φ' : K →ₐ[k] ℂ := { star φ with commutes' := fun r ↦ by simpa using! RingHom.congr_fun hφ.2 r } diff --git a/Mathlib/NumberTheory/NumberField/Norm.lean b/Mathlib/NumberTheory/NumberField/Norm.lean index 5df13dd08fc944..62f3cb41da6f02 100644 --- a/Mathlib/NumberTheory/NumberField/Norm.lean +++ b/Mathlib/NumberTheory/NumberField/Norm.lean @@ -97,10 +97,10 @@ theorem norm_norm [Algebra F L] [FiniteDimensional F L] [IsScalarTower K F L] (x variable {F} theorem isUnit_norm [CharZero K] {x : 𝓞 F} : IsUnit (norm K x) ↔ IsUnit x := by - letI : Algebra K (AlgebraicClosure K) := AlgebraicClosure.instAlgebra K + let : Algebra K (AlgebraicClosure K) := AlgebraicClosure.instAlgebra K let L := normalClosure K F (AlgebraicClosure F) - haveI : FiniteDimensional F L := FiniteDimensional.right K F L - haveI : IsGalois F L := IsGalois.tower_top_of_isGalois K F L + have : FiniteDimensional F L := FiniteDimensional.right K F L + have : IsGalois F L := IsGalois.tower_top_of_isGalois K F L calc IsUnit (norm K x) ↔ IsUnit ((norm K) x ^ finrank F L) := (isUnit_pow_iff (pos_iff_ne_zero.mp finrank_pos)).symm diff --git a/Mathlib/NumberTheory/Padics/Complex.lean b/Mathlib/NumberTheory/Padics/Complex.lean index 72a0247aea24b5..bd2d2d227071ed 100644 --- a/Mathlib/NumberTheory/Padics/Complex.lean +++ b/Mathlib/NumberTheory/Padics/Complex.lean @@ -206,8 +206,8 @@ theorem isNonarchimedean : IsNonarchimedean (Norm.norm : ℂ_[p] → ℝ) := theorem norm_eq_norm' : (‖·‖ : ℂ_[p] → ℝ) = Valued.v.norm := by apply UniformSpace.Completion.extension_unique (f := @norm (PadicAlgCl p) _) (g := Valued.v.norm) · exact uniformContinuous_norm - · letI S := (Valued.toNormedField ℂ_[p] NNReal).toNormedCommRing.toNormedRing.toSeminormedRing - letI := S.toNonUnitalSeminormedRing.toSeminormedAddCommGroup.toSeminormedAddGroup + · let S := (Valued.toNormedField ℂ_[p] NNReal).toNormedCommRing.toNormedRing.toSeminormedRing + let := S.toNonUnitalSeminormedRing.toSeminormedAddCommGroup.toSeminormedAddGroup exact @uniformContinuous_norm ℂ_[p] this · intro x simp only [Valued.v.norm_def, RankOne.hom_eq_embedding] diff --git a/Mathlib/NumberTheory/Padics/RingHoms.lean b/Mathlib/NumberTheory/Padics/RingHoms.lean index 7c697875793946..9556b01b05ac21 100644 --- a/Mathlib/NumberTheory/Padics/RingHoms.lean +++ b/Mathlib/NumberTheory/Padics/RingHoms.lean @@ -580,7 +580,7 @@ theorem nthHomSeq_one : nthHomSeq f_compat 1 ≈ 1 := by change _ < _ at hε use 1 intro j hj - haveI : Fact (1 < p ^ j) := ⟨Nat.one_lt_pow (by lia) hp_prime.1.one_lt⟩ + have : Fact (1 < p ^ j) := ⟨Nat.one_lt_pow (by lia) hp_prime.1.one_lt⟩ suffices (ZMod.cast (1 : ZMod (p ^ j)) : ℚ) = 1 by simp [nthHomSeq, nthHom, this, hε] rw [ZMod.cast_eq_val, ZMod.val_one, Nat.cast_one] diff --git a/Mathlib/NumberTheory/Pell.lean b/Mathlib/NumberTheory/Pell.lean index 8b68eb9388aeb0..04b6b2d6504225 100644 --- a/Mathlib/NumberTheory/Pell.lean +++ b/Mathlib/NumberTheory/Pell.lean @@ -355,7 +355,7 @@ theorem exists_of_not_isSquare (h₀ : 0 < d) (hd : ¬IsSquare d) : obtain ⟨a, ha⟩ := (Int.pow_dvd_pow_iff two_ne_zero).mp ⟨d, hq⟩ rw [ha, mul_pow, mul_right_inj' (pow_pos (Int.natCast_pos.mpr q.pos) 2).ne'] at hq exact hd ⟨a, sq a ▸ hq.symm⟩ - haveI := neZero_iff.mpr (Int.natAbs_ne_zero.mpr hm₀) + have := neZero_iff.mpr (Int.natAbs_ne_zero.mpr hm₀) let f : ℚ → ZMod m.natAbs × ZMod m.natAbs := fun q => (q.num, q.den) obtain ⟨q₁, h₁ : q₁.num ^ 2 - d * (q₁.den : ℤ) ^ 2 = m, q₂, h₂ : q₂.num ^ 2 - d * (q₂.den : ℤ) ^ 2 = m, hne, hqf⟩ := diff --git a/Mathlib/NumberTheory/PrimesCongruentOne.lean b/Mathlib/NumberTheory/PrimesCongruentOne.lean index 0d250aa0429b1a..30f10e47ed7288 100644 --- a/Mathlib/NumberTheory/PrimesCongruentOne.lean +++ b/Mathlib/NumberTheory/PrimesCongruentOne.lean @@ -39,7 +39,7 @@ theorem exists_prime_gt_modEq_one {k : ℕ} (n : ℕ) (hk0 : k ≠ 0) : _ < (eval (b : ℤ) (cyclotomic (k + 1) ℤ)).natAbs := sub_one_lt_natAbs_cyclotomic_eval hk1 (succ_le_iff.1 hb).ne' let p := minFac (eval (↑b) (cyclotomic k ℤ)).natAbs - haveI hprime : Fact p.Prime := ⟨minFac_prime (ne_of_lt hgt).symm⟩ + have hprime : Fact p.Prime := ⟨minFac_prime (ne_of_lt hgt).symm⟩ have hroot : IsRoot (cyclotomic k (ZMod p)) (castRingHom (ZMod p) b) := by have : ((b : ℤ) : ZMod p) = ↑(Int.castRingHom (ZMod p) b) := by simp rw [IsRoot.def, ← map_cyclotomic_int k (ZMod p), eval_map, coe_castRingHom, @@ -52,7 +52,7 @@ theorem exists_prime_gt_modEq_one {k : ℕ} (n : ℕ) (hk0 : k ≠ 0) : · exact hpb (dvd_mul_of_dvd_right (dvd_factorial (minFac_pos _) habs) _) · have hdiv : orderOf (b : ZMod p) ∣ p - 1 := ZMod.orderOf_dvd_card_sub_one (mt (CharP.cast_eq_zero_iff _ _ _).1 hpb) - haveI : NeZero (k : ZMod p) := + have : NeZero (k : ZMod p) := NeZero.of_not_dvd (ZMod p) fun hpk => hpb (dvd_mul_of_dvd_left hpk _) have : k = orderOf (b : ZMod p) := (isRoot_cyclotomic_iff.mp hroot).eq_orderOf rw [← this] at hdiv diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 95df6e14862ac7..2da3a085e0caa7 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -199,7 +199,7 @@ theorem FinrankQuotientMap.linearIndependent_of_nontrivial [IsDedekindDomain R] use s obtain ⟨a, hag, j, hjs, hgI⟩ := Ideal.exist_integer_multiples_notMem hRS s g hj's hj'g choose g'' hg'' using hag - letI := Classical.propDecidable + let := Classical.propDecidable let g' i := if h : i ∈ s then g'' i h else 0 have hg' : ∀ i ∈ s, algebraMap _ _ (g' i) = a * g i := by intro i hi; exact (congr_arg _ (dif_pos hi)).trans (hg'' i hi) @@ -457,7 +457,7 @@ theorem rank_prime_pow_ramificationIdx [IsDedekindDomain S] [p.IsMaximal] [P.IsP @Module.rank (R ⧸ p) (S ⧸ P) _ _ (@Algebra.toModule _ _ _ _ <| @Quotient.algebraQuotientOfRamificationIdxNeZero _ _ _ _ _ _ _ ⟨he⟩) := by - letI : NeZero e := ⟨he⟩ + let : NeZero e := ⟨he⟩ have := rank_pow_quot p P hP0 0 (Nat.zero_le e) rw [pow_zero, Nat.sub_zero, Ideal.one_eq_top, Ideal.map_top] at this exact (rank_top (R ⧸ p) _).symm.trans this @@ -471,8 +471,8 @@ theorem finrank_prime_pow_ramificationIdx [IsDedekindDomain S] (hP0 : P ≠ ⊥) @finrank (R ⧸ p) (S ⧸ P) _ _ (@Algebra.toModule _ _ _ _ <| @Quotient.algebraQuotientOfRamificationIdxNeZero _ _ _ _ _ _ _ ⟨he⟩) := by - letI : NeZero e := ⟨he⟩ - letI : Algebra (R ⧸ p) (S ⧸ P) := Quotient.algebraQuotientOfRamificationIdxNeZero p P + let : NeZero e := ⟨he⟩ + let : Algebra (R ⧸ p) (S ⧸ P) := Quotient.algebraQuotientOfRamificationIdxNeZero p P have hdim := rank_prime_pow_ramificationIdx _ _ hP0 he by_cases hP : FiniteDimensional (R ⧸ p) (S ⧸ P) · have := (finiteDimensional_iff_of_rank_eq_nsmul he hdim).mpr hP diff --git a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean index e5931a31ab8a51..1fed89890a588a 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean @@ -198,10 +198,10 @@ theorem inertiaDeg'_algebra_tower (p : Ideal R) (P : Ideal S) (I : Ideal T) [p.I have h₂ := I.over_def P have h₃ := (LiesOver.trans I P p).over simp only [inertiaDeg', dif_pos h₁.symm, dif_pos h₂.symm, dif_pos h₃.symm] - letI : Algebra (R ⧸ p) (S ⧸ P) := Ideal.Quotient.algebraQuotientOfLEComap h₁.le - letI : Algebra (S ⧸ P) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₂.le - letI : Algebra (R ⧸ p) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₃.le - letI : IsScalarTower (R ⧸ p) (S ⧸ P) (T ⧸ I) := IsScalarTower.of_algebraMap_eq <| by + let : Algebra (R ⧸ p) (S ⧸ P) := Ideal.Quotient.algebraQuotientOfLEComap h₁.le + let : Algebra (S ⧸ P) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₂.le + let : Algebra (R ⧸ p) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₃.le + let : IsScalarTower (R ⧸ p) (S ⧸ P) (T ⧸ I) := IsScalarTower.of_algebraMap_eq <| by rintro ⟨x⟩; exact congr_arg _ (IsScalarTower.algebraMap_apply R S T x) exact (finrank_mul_finrank (R ⧸ p) (S ⧸ P) (T ⧸ I)).symm diff --git a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean index 4e5a335aecebcf..a4e30787f660b8 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean @@ -403,7 +403,7 @@ theorem ramificationIdx'_algebra_tower [IsDedekindDomain S] [IsDedekindDomain T] exact ne_bot_of_map_ne_bot hfg have hp0 : P ≠ ⊥ := ne_bot_of_map_ne_bot hg0 have hq0 : Q ≠ ⊥ := ne_bot_of_le_ne_bot hg0 hg - letI : P.IsMaximal := Ring.DimensionLEOne.maximalOfPrime hp0 hpm + let : P.IsMaximal := Ring.DimensionLEOne.maximalOfPrime hp0 hpm rw [IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hf0 hpm hp0, IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hg0 hqm hq0, IsDedekindDomain.ramificationIdx'_eq_normalizedFactors_count hfg hqm hq0, diff --git a/Mathlib/NumberTheory/WellApproximable.lean b/Mathlib/NumberTheory/WellApproximable.lean index 730fc04d079d20..cc134902446249 100644 --- a/Mathlib/NumberTheory/WellApproximable.lean +++ b/Mathlib/NumberTheory/WellApproximable.lean @@ -212,7 +212,7 @@ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto `E` is almost equal to `C p` for every prime. Combining this with 3 we find that `E` is almost invariant under the map `y ↦ y + 1/p` for every prime `p`. The required result then follows from `AddCircle.ae_empty_or_univ_of_forall_vadd_ae_eq_self`. -/ - letI : SemilatticeSup Nat.Primes := Nat.Subtype.semilatticeSup _ + let : SemilatticeSup Nat.Primes := Nat.Subtype.semilatticeSup _ set μ : Measure 𝕊 := volume set u : Nat.Primes → 𝕊 := fun p => ↑((↑(1 : ℕ) : ℝ) / ((p : ℕ) : ℝ) * T) have hu₀ : ∀ p : Nat.Primes, addOrderOf (u p) = (p : ℕ) := by diff --git a/Mathlib/NumberTheory/Wilson.lean b/Mathlib/NumberTheory/Wilson.lean index 9401f7b96b43c2..97c84e9181afc8 100644 --- a/Mathlib/NumberTheory/Wilson.lean +++ b/Mathlib/NumberTheory/Wilson.lean @@ -96,7 +96,7 @@ theorem prime_of_fac_equiv_neg_one (h : ((n - 1)! : ZMod n) = -1) (h1 : n ≠ 1) /-- **Wilson's Theorem**: For `n ≠ 1`, `(n-1)!` is congruent to `-1` modulo `n` iff n is prime. -/ theorem prime_iff_fac_equiv_neg_one (h : n ≠ 1) : Prime n ↔ ((n - 1)! : ZMod n) = -1 := by refine ⟨fun h1 => ?_, fun h2 => prime_of_fac_equiv_neg_one h2 h⟩ - haveI := Fact.mk h1 + have := Fact.mk h1 exact ZMod.wilsons_lemma n end Nat diff --git a/Mathlib/NumberTheory/Zsqrtd/Basic.lean b/Mathlib/NumberTheory/Zsqrtd/Basic.lean index fd00e21c96fb49..35cd025fc370f4 100644 --- a/Mathlib/NumberTheory/Zsqrtd/Basic.lean +++ b/Mathlib/NumberTheory/Zsqrtd/Basic.lean @@ -863,7 +863,7 @@ theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ rw [sub_eq_zero] at ha by_cases! h : 0 ≤ d · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h - haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩ + have : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩ exact divides_sq_eq_zero_z ha · suffices a.re * a.re = 0 by rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢ diff --git a/Mathlib/Order/Category/NonemptyFinLinOrd.lean b/Mathlib/Order/Category/NonemptyFinLinOrd.lean index ed2d2b2d98e1c1..da4a9663edfb35 100644 --- a/Mathlib/Order/Category/NonemptyFinLinOrd.lean +++ b/Mathlib/Order/Category/NonemptyFinLinOrd.lean @@ -210,12 +210,12 @@ instance : HasStrongEpiMonoFactorisations NonemptyFinLinOrd.{u} := let I := of (Set.image f ⊤) let e : X ⟶ I := ofHom ⟨fun x => ⟨f x, ⟨x, by tauto⟩⟩, fun x₁ x₂ h => f.hom.hom.monotone h⟩ let m : I ⟶ Y := ofHom ⟨fun y => y.1, by tauto⟩ - haveI : Epi e := by + have : Epi e := by rw [epi_iff_surjective] rintro ⟨_, y, h, rfl⟩ exact ⟨y, rfl⟩ - haveI : StrongEpi e := strongEpi_of_epi e - haveI : Mono m := ConcreteCategory.mono_of_injective _ (fun x y h => Subtype.ext h) + have : StrongEpi e := strongEpi_of_epi e + have : Mono m := ConcreteCategory.mono_of_injective _ (fun x y h => Subtype.ext h) exact ⟨⟨I, m, e, rfl⟩⟩⟩ end NonemptyFinLinOrd diff --git a/Mathlib/Order/CompleteLattice/Basic.lean b/Mathlib/Order/CompleteLattice/Basic.lean index 419c44485b3fad..9ac1a9e45d4ea7 100644 --- a/Mathlib/Order/CompleteLattice/Basic.lean +++ b/Mathlib/Order/CompleteLattice/Basic.lean @@ -470,7 +470,7 @@ theorem iSup_subtype'' {ι} (s : Set ι) (f : ι → α) : ⨆ i : s, f i = ⨆ @[to_dual] theorem biSup_const {a : α} {s : Set β} (hs : s.Nonempty) : ⨆ i ∈ s, a = a := by - haveI : Nonempty s := Set.nonempty_coe_sort.mpr hs + have : Nonempty s := Set.nonempty_coe_sort.mpr hs rw [← iSup_subtype'', iSup_const] @[to_dual] @@ -502,7 +502,7 @@ theorem sup_iSup [Nonempty ι] {f : ι → α} {a : α} : (a ⊔ ⨆ x, f x) = @[to_dual] theorem biSup_sup {p : ι → Prop} {f : ∀ i, p i → α} {a : α} (h : ∃ i, p i) : (⨆ (i) (h : p i), f i h) ⊔ a = ⨆ (i) (h : p i), f i h ⊔ a := by - haveI : Nonempty { i // p i } := + have : Nonempty { i // p i } := let ⟨i, hi⟩ := h ⟨⟨i, hi⟩⟩ rw [iSup_subtype', iSup_subtype', iSup_sup] diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean index 65502dab75bcbf..9767efeee07a8a 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean @@ -578,7 +578,7 @@ theorem l_ciSup (gc : GaloisConnection l u) {f : ι → α} (hf : BddAbove (rang theorem l_ciSup_set (gc : GaloisConnection l u) {s : Set γ} {f : γ → α} (hf : BddAbove (f '' s)) (hne : s.Nonempty) : l (⨆ i : s, f i) = ⨆ i : s, l (f i) := by - haveI := hne.to_subtype + have := hne.to_subtype rw [image_eq_range] at hf exact gc.l_ciSup hf diff --git a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean index 2de0ca976d89d7..727b409414c943 100644 --- a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean @@ -150,7 +150,7 @@ theorem Monotone.ciSup_mem_iInter_Icc_of_antitone [Preorder β] [IsDirectedOrder {f g : β → α} (hf : Monotone f) (hg : Antitone g) (h : f ≤ g) : (⨆ n, f n) ∈ ⋂ n, Icc (f n) (g n) := by refine mem_iInter.2 fun n => ?_ - haveI : Nonempty β := ⟨n⟩ + have : Nonempty β := ⟨n⟩ have h₁ : ∀ m, f m ≤ g n := fun m => hf.forall_le_of_antitone hg h m n have h₂ : Directed (· ≤ ·) f := hf.directed_le exact ⟨h₂.le_ciSup ⟨g <| n, forall_mem_range.2 h₁⟩ _, h₂.ciSup_le h₁⟩ @@ -213,7 +213,7 @@ theorem l_ciSup_of_directed (gc : GaloisConnection l u) {f : ι → α} (hd : Di theorem l_ciSup_set_of_directedOn (gc : GaloisConnection l u) {s : Set γ} {f : γ → α} (hd : DirectedOn (· ≤ ·) (f '' s)) (hf : BddAbove (f '' s)) (hne : s.Nonempty) : l (⨆ i : s, f i) = ⨆ i : s, l (f i) := by - haveI := hne.to_subtype + have := hne.to_subtype rw [image_eq_range] at hf refine gc.l_ciSup_of_directed ?_ hf simpa [← directedOn_range, ← comp_def, range_comp] diff --git a/Mathlib/Order/CountableDenseLinearOrder.lean b/Mathlib/Order/CountableDenseLinearOrder.lean index 3b331237fdc464..58be73b2115c5e 100644 --- a/Mathlib/Order/CountableDenseLinearOrder.lean +++ b/Mathlib/Order/CountableDenseLinearOrder.lean @@ -227,7 +227,7 @@ theorem embedding_from_countable_to_dense [Countable α] [DenselyOrdered β] [No cases nonempty_encodable α rcases exists_pair_lt β with ⟨x, y, hxy⟩ obtain ⟨a, ha⟩ := exists_between hxy - haveI : Nonempty (Set.Ioo x y) := ⟨⟨a, ha⟩⟩ + have : Nonempty (Set.Ioo x y) := ⟨⟨a, ha⟩⟩ let our_ideal : Ideal (PartialIso α _) := idealOfCofinals default (definedAtLeft (Set.Ioo x y)) let F a := funOfIdeal a our_ideal (cofinal_meets_idealOfCofinals _ _ a) diff --git a/Mathlib/Order/Disjoint.lean b/Mathlib/Order/Disjoint.lean index 844d5aa07f29c4..f2d81c18457c6a 100644 --- a/Mathlib/Order/Disjoint.lean +++ b/Mathlib/Order/Disjoint.lean @@ -168,8 +168,8 @@ lemma disjoint_subtype_iff {pr : α → Prop} (Pinf : ∀ ⦃s t : α⦄, pr s letI : SemilatticeInf (Subtype pr) := Subtype.semilatticeInf Pinf letI : OrderBot (Subtype pr) := Subtype.orderBot hbot Disjoint a b ↔ Disjoint a.val b.val := by - letI : SemilatticeInf (Subtype pr) := Subtype.semilatticeInf Pinf - letI : OrderBot (Subtype pr) := Subtype.orderBot hbot + let : SemilatticeInf (Subtype pr) := Subtype.semilatticeInf Pinf + let : OrderBot (Subtype pr) := Subtype.orderBot hbot rw [disjoint_iff, disjoint_iff, ← Subtype.coe_inf Pinf, ← Subtype.coe_bot hbot] exact Subtype.coe_inj.symm diff --git a/Mathlib/Order/Extension/Linear.lean b/Mathlib/Order/Extension/Linear.lean index 96bb308852051f..bd575698288406 100644 --- a/Mathlib/Order/Extension/Linear.lean +++ b/Mathlib/Order/Extension/Linear.lean @@ -27,7 +27,7 @@ theorem extend_partialOrder {α : Type u} (r : α → α → Prop) [IsPartialOrd let S := { s | IsPartialOrder α s } have hS : ∀ c, c ⊆ S → IsChain (· ≤ ·) c → ∀ y ∈ c, ∃ ub ∈ S, ∀ z ∈ c, z ≤ ub := by rintro c hc₁ hc₂ s hs - haveI := (hc₁ hs).1 + have := (hc₁ hs).1 refine ⟨sSup c, ?_, fun z hz => le_sSup hz⟩ refine { refl := ?_ @@ -37,19 +37,19 @@ theorem extend_partialOrder {α : Type u} (r : α → α → Prop) [IsPartialOrd · intro x exact ⟨s, hs, refl x⟩ · rintro x y z ⟨s₁, h₁s₁, h₂s₁⟩ ⟨s₂, h₁s₂, h₂s₂⟩ - haveI : IsPartialOrder _ _ := hc₁ h₁s₁ - haveI : IsPartialOrder _ _ := hc₁ h₁s₂ + have : IsPartialOrder _ _ := hc₁ h₁s₁ + have : IsPartialOrder _ _ := hc₁ h₁s₂ rcases hc₂.total h₁s₁ h₁s₂ with h | h · exact ⟨s₂, h₁s₂, _root_.trans (h _ _ h₂s₁) h₂s₂⟩ · exact ⟨s₁, h₁s₁, _root_.trans h₂s₁ (h _ _ h₂s₂)⟩ · rintro x y ⟨s₁, h₁s₁, h₂s₁⟩ ⟨s₂, h₁s₂, h₂s₂⟩ - haveI : IsPartialOrder _ _ := hc₁ h₁s₁ - haveI : IsPartialOrder _ _ := hc₁ h₁s₂ + have : IsPartialOrder _ _ := hc₁ h₁s₁ + have : IsPartialOrder _ _ := hc₁ h₁s₂ rcases hc₂.total h₁s₁ h₁s₂ with h | h · exact antisymm (h _ _ h₂s₁) h₂s₂ · apply antisymm h₂s₁ (h _ _ h₂s₂) obtain ⟨s, hrs, hs⟩ := zorn_le_nonempty₀ S hS r ‹_› - haveI : IsPartialOrder α s := hs.prop + have : IsPartialOrder α s := hs.prop refine ⟨s, { total := ?_, refl := hs.1.refl, trans := hs.1.trans, antisymm := hs.1.antisymm }, hrs⟩ intro x y diff --git a/Mathlib/Order/Filter/AtTopBot/BigOperators.lean b/Mathlib/Order/Filter/AtTopBot/BigOperators.lean index 6b205b40d618b4..48847d7fe443b0 100644 --- a/Mathlib/Order/Filter/AtTopBot/BigOperators.lean +++ b/Mathlib/Order/Filter/AtTopBot/BigOperators.lean @@ -57,7 +57,7 @@ the same assumptions. -/ theorem Function.Injective.map_atTop_finsetProd_eq {g : α → β} (hg : Function.Injective g) {f : β → M} (hf : ∀ x, x ∉ Set.range g → f x = 1) : map (fun s => ∏ i ∈ s, f (g i)) atTop = map (fun s => ∏ i ∈ s, f i) atTop := by - haveI := Classical.decEq β + have := Classical.decEq β apply le_antisymm <;> refine map_atTop_finsetProd_le_of_prod_eq fun s => ?_ · refine ⟨s.preimage g hg.injOn, fun t ht => ?_⟩ refine ⟨t.image g ∪ s, Finset.subset_union_right, ?_⟩ diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index c9c47c96d06c0e..255ea53e9fd563 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -488,7 +488,7 @@ theorem mem_iInf_of_directed {f : ι → Filter α} (h : Directed (· ≥ ·) f) theorem mem_biInf_of_directed {f : β → Filter α} {s : Set β} (h : DirectedOn (f ⁻¹'o (· ≥ ·)) s) (ne : s.Nonempty) {t : Set α} : (t ∈ ⨅ i ∈ s, f i) ↔ ∃ i ∈ s, t ∈ f i := by - haveI := ne.to_subtype + have := ne.to_subtype simp_rw [iInf_subtype', mem_iInf_of_directed h.directed_val, Subtype.exists, exists_prop] theorem biInf_sets_eq {f : β → Filter α} {s : Set β} (h : DirectedOn (f ⁻¹'o (· ≥ ·)) s) @@ -900,7 +900,7 @@ theorem frequently_iSup {p : α → Prop} {fs : β → Filter α} : theorem Eventually.choice {r : α → β → Prop} {l : Filter α} [l.NeBot] (h : ∀ᶠ x in l, ∃ y, r x y) : ∃ f : α → β, ∀ᶠ x in l, r x (f x) := by - haveI : Nonempty β := let ⟨_, hx⟩ := h.exists; hx.nonempty + have : Nonempty β := let ⟨_, hx⟩ := h.exists; hx.nonempty choose! f hf using fun x (hx : ∃ y, r x y) => hx exact ⟨f, h.mono hf⟩ diff --git a/Mathlib/Order/Filter/CountableInter.lean b/Mathlib/Order/Filter/CountableInter.lean index 157177640ee2e9..c4c652eb3a619d 100644 --- a/Mathlib/Order/Filter/CountableInter.lean +++ b/Mathlib/Order/Filter/CountableInter.lean @@ -55,7 +55,7 @@ theorem countable_iInter_mem [Countable ι] {s : ι → Set α} : (⋂ i, s i) theorem countable_bInter_mem {ι : Type*} {S : Set ι} (hS : S.Countable) {s : ∀ i ∈ S, Set α} : (⋂ i, ⋂ hi : i ∈ S, s i ‹_›) ∈ l ↔ ∀ i, ∀ hi : i ∈ S, s i ‹_› ∈ l := by rw [biInter_eq_iInter] - haveI := hS.toEncodable + have := hS.toEncodable exact countable_iInter_mem.trans Subtype.forall theorem eventually_countable_forall [Countable ι] {p : α → ι → Prop} : @@ -94,7 +94,7 @@ theorem EventuallyLE.countable_bUnion {ι : Type*} {S : Set ι} (hS : S.Countabl {s t : ∀ i ∈ S, Set α} (h : ∀ i hi, s i hi ≤ᶠ[l] t i hi) : ⋃ i ∈ S, s i ‹_› ≤ᶠ[l] ⋃ i ∈ S, t i ‹_› := by simp only [biUnion_eq_iUnion] - haveI := hS.toEncodable + have := hS.toEncodable exact EventuallyLE.countable_iUnion fun i => h i i.2 @[deprecated (since := "2026-03-03")] alias _root_.EventuallyLE.countable_bUnion := @@ -129,7 +129,7 @@ theorem EventuallyLE.countable_bInter {ι : Type*} {S : Set ι} (hS : S.Countabl {s t : ∀ i ∈ S, Set α} (h : ∀ i hi, s i hi ≤ᶠ[l] t i hi) : ⋂ i ∈ S, s i ‹_› ≤ᶠ[l] ⋂ i ∈ S, t i ‹_› := by simp only [biInter_eq_iInter] - haveI := hS.toEncodable + have := hS.toEncodable exact EventuallyLE.countable_iInter fun i => h i i.2 @[deprecated (since := "2026-03-03")] alias _root_.EventuallyLE.countable_bInter := diff --git a/Mathlib/Order/Filter/Finite.lean b/Mathlib/Order/Filter/Finite.lean index 9a83bbff60523e..23abbf5698b21a 100644 --- a/Mathlib/Order/Filter/Finite.lean +++ b/Mathlib/Order/Filter/Finite.lean @@ -79,7 +79,7 @@ theorem mem_generate_iff {s : Set <| Set α} {U : Set α} : theorem mem_iInf_of_iInter {ι} {s : ι → Filter α} {U : Set α} {I : Set ι} (I_fin : I.Finite) {V : I → Set α} (hV : ∀ (i : I), V i ∈ s i) (hU : ⋂ i, V i ⊆ U) : U ∈ ⨅ i, s i := by - haveI := I_fin.fintype + have := I_fin.fintype refine mem_of_superset (iInter_mem.2 fun i => ?_) hU exact mem_iInf_of_mem (i : ι) (hV _) @@ -164,7 +164,7 @@ theorem _root_.Pairwise.exists_mem_filter_of_disjoint {ι : Type*} [Finite ι] { theorem _root_.Set.PairwiseDisjoint.exists_mem_filter {ι : Type*} {l : ι → Filter α} {t : Set ι} (hd : t.PairwiseDisjoint l) (ht : t.Finite) : ∃ s : ι → Set α, (∀ i, s i ∈ l i) ∧ t.PairwiseDisjoint s := by - haveI := ht.to_subtype + have := ht.to_subtype rcases (hd.subtype _ _).exists_mem_filter_of_disjoint with ⟨s, hsl, hsd⟩ lift s to (i : t) → {s // s ∈ l i} using hsl rcases @Subtype.exists_pi_extension ι (fun i => { s // s ∈ l i }) _ _ s with ⟨s, rfl⟩ diff --git a/Mathlib/Order/Filter/IsBounded.lean b/Mathlib/Order/Filter/IsBounded.lean index ac5ddefb6eee81..66a0d929650c80 100644 --- a/Mathlib/Order/Filter/IsBounded.lean +++ b/Mathlib/Order/Filter/IsBounded.lean @@ -180,7 +180,7 @@ theorem not_isBoundedUnder_of_tendsto_atBot [Preorder β] [NoMinOrder β] {f : theorem IsBoundedUnder.bddAbove_range_of_cofinite [Preorder β] [IsDirectedOrder β] {f : α → β} (hf : IsBoundedUnder (· ≤ ·) cofinite f) : BddAbove (range f) := by rcases hf with ⟨b, hb⟩ - haveI : Nonempty β := ⟨b⟩ + have : Nonempty β := ⟨b⟩ rw [← image_univ, ← union_compl_self { x | f x ≤ b }, image_union, bddAbove_union] exact ⟨⟨b, forall_mem_image.2 fun x => id⟩, (hb.image f).bddAbove⟩ diff --git a/Mathlib/Order/Filter/Map.lean b/Mathlib/Order/Filter/Map.lean index bd63d6f641c8eb..a40528371dad5b 100644 --- a/Mathlib/Order/Filter/Map.lean +++ b/Mathlib/Order/Filter/Map.lean @@ -715,7 +715,7 @@ theorem map_iInf_eq {f : ι → Filter α} {m : α → β} (hf : Directed (· theorem map_biInf_eq {ι : Type w} {f : ι → Filter α} {m : α → β} {p : ι → Prop} (h : DirectedOn (f ⁻¹'o (· ≥ ·)) { x | p x }) (ne : ∃ i, p i) : map m (⨅ (i) (_ : p i), f i) = ⨅ (i) (_ : p i), map m (f i) := by - haveI := nonempty_subtype.2 ne + have := nonempty_subtype.2 ne simp only [iInf_subtype'] exact map_iInf_eq h.directed_val diff --git a/Mathlib/Order/Filter/Pi.lean b/Mathlib/Order/Filter/Pi.lean index f894c0f5f64fdb..0ffcaac7825635 100644 --- a/Mathlib/Order/Filter/Pi.lean +++ b/Mathlib/Order/Filter/Pi.lean @@ -245,7 +245,7 @@ theorem pi_le_pi [∀ i, NeBot (f₁ i)] : pi f₁ ≤ pi f₂ ↔ ∀ i, f₁ i theorem pi_inj [∀ i, NeBot (f₁ i)] : pi f₁ = pi f₂ ↔ f₁ = f₂ := by refine ⟨fun h => ?_, congr_arg pi⟩ have hle : f₁ ≤ f₂ := pi_le_pi.1 h.le - haveI : ∀ i, NeBot (f₂ i) := fun i => neBot_of_le (hle i) + have : ∀ i, NeBot (f₂ i) := fun i => neBot_of_le (hle i) exact hle.antisymm (pi_le_pi.1 h.ge) theorem tendsto_piMap_pi {β : ι → Type*} {f : ∀ i, α i → β i} {l : ∀ i, Filter (α i)} diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index e6f62fd24324e3..e51ef5e2b5bcf6 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -267,7 +267,7 @@ theorem prod_inj {f₁ f₂ : Filter α} {g₁ g₂ : Filter β} [NeBot f₁] [N f₁ ×ˢ g₁ = f₂ ×ˢ g₂ ↔ f₁ = f₂ ∧ g₁ = g₂ := by refine ⟨fun h => ?_, fun h => h.1 ▸ h.2 ▸ rfl⟩ have hle : f₁ ≤ f₂ ∧ g₁ ≤ g₂ := prod_le_prod.1 h.le - haveI := neBot_of_le hle.1; haveI := neBot_of_le hle.2 + have := neBot_of_le hle.1; have := neBot_of_le hle.2 exact ⟨hle.1.antisymm <| (prod_le_prod.1 h.ge).1, hle.2.antisymm <| (prod_le_prod.1 h.ge).2⟩ theorem eventually_swap_iff {p : α × β → Prop} : diff --git a/Mathlib/Order/Filter/Ultrafilter/Defs.lean b/Mathlib/Order/Filter/Ultrafilter/Defs.lean index 26b11cfb7a8b8f..ffd0bf126c9b5a 100644 --- a/Mathlib/Order/Filter/Ultrafilter/Defs.lean +++ b/Mathlib/Order/Filter/Ultrafilter/Defs.lean @@ -340,7 +340,7 @@ theorem Iic_pure (a : α) : Iic (pure a : Filter α) = {⊥, pure a} := theorem mem_iff_ultrafilter : s ∈ f ↔ ∀ g : Ultrafilter α, ↑g ≤ f → s ∈ g := by refine ⟨fun hf g hg => hg hf, fun H => by_contra fun hf => ?_⟩ set g : Filter (sᶜ : Set α) := comap (↑) f - haveI : NeBot g := comap_neBot_iff_compl_range.2 (by simpa [compl_setOf]) + have : NeBot g := comap_neBot_iff_compl_range.2 (by simpa [compl_setOf]) simpa using H ((of g).map (↑)) (map_le_iff_le_comap.mpr (of_le g)) theorem le_iff_ultrafilter {f₁ f₂ : Filter α} : f₁ ≤ f₂ ↔ ∀ g : Ultrafilter α, ↑g ≤ f₁ → ↑g ≤ f₂ := @@ -375,13 +375,13 @@ noncomputable def ofComapInfPrincipal (h : m '' s ∈ g) : Ultrafilter α := theorem ofComapInfPrincipal_mem (h : m '' s ∈ g) : s ∈ ofComapInfPrincipal h := by let f := Filter.comap m g ⊓ 𝓟 s - haveI : f.NeBot := comap_inf_principal_neBot_of_image_mem h + have : f.NeBot := comap_inf_principal_neBot_of_image_mem h have : s ∈ f := mem_inf_of_right (mem_principal_self s) exact le_def.mp (of_le _) s this theorem ofComapInfPrincipal_eq_of_map (h : m '' s ∈ g) : (ofComapInfPrincipal h).map m = g := by let f := Filter.comap m g ⊓ 𝓟 s - haveI : f.NeBot := comap_inf_principal_neBot_of_image_mem h + have : f.NeBot := comap_inf_principal_neBot_of_image_mem h apply eq_of_le calc Filter.map m (of f) ≤ Filter.map m f := map_mono (of_le _) diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index b40d78664694ba..d556aec4547114 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -709,7 +709,7 @@ lemma krullDim_eq_top [InfiniteDimensionalOrder α] : krullDim α = ⊤ := le_antisymm le_top <| le_iSup_iff.mpr <| fun m hm ↦ match m, hm with | ⊥, hm => False.elim <| by - haveI : Inhabited α := ⟨LTSeries.withLength _ 0 0⟩ + have : Inhabited α := ⟨LTSeries.withLength _ 0 0⟩ exact not_le_of_gt (WithBot.bot_lt_coe _ : ⊥ < (0 : WithBot (WithTop ℕ))) <| hm default | ⊤, _ => le_refl _ | m, hm => by diff --git a/Mathlib/Order/Monotone/MonovaryOrder.lean b/Mathlib/Order/Monotone/MonovaryOrder.lean index 9f5841320901e2..1117a888d63587 100644 --- a/Mathlib/Order/Monotone/MonovaryOrder.lean +++ b/Mathlib/Order/Monotone/MonovaryOrder.lean @@ -44,7 +44,7 @@ variable {f g} lemma monovaryOn_iff_exists_monotoneOn : MonovaryOn f g s ↔ ∃ (_ : LinearOrder ι), MonotoneOn f s ∧ MonotoneOn g s := by classical - letI := linearOrderOfSTO (MonovaryOrder f g) + let := linearOrderOfSTO (MonovaryOrder f g) refine ⟨fun hfg => ⟨‹_›, monotoneOn_iff_forall_lt.2 fun i hi j hj hij => ?_, monotoneOn_iff_forall_lt.2 fun i hi j hj hij => ?_⟩, ?_⟩ · obtain h | ⟨h, -⟩ := Prod.lex_iff.1 hij <;> exact h.le diff --git a/Mathlib/Order/Partition/Equipartition.lean b/Mathlib/Order/Partition/Equipartition.lean index 777f7b00b1be55..b61cbc3d87afd0 100644 --- a/Mathlib/Order/Partition/Equipartition.lean +++ b/Mathlib/Order/Partition/Equipartition.lean @@ -142,7 +142,7 @@ theorem IsEquipartition.exists_partPreservingEquiv (hP : P.IsEquipartition) : have bij : z'.Bijective := by refine (bijective_iff_injective_and_card z').mpr ⟨fun a b e ↦ ?_, by simp⟩ simp_rw [z', z, Fin.mk.injEq, mul_comm #P.parts] at e - haveI : NeZero #P.parts := ⟨((Nat.zero_le _).trans_lt (gl a)).ne'⟩ + have : NeZero #P.parts := ⟨((Nat.zero_le _).trans_lt (gl a)).ne'⟩ change (#P.parts).divModEquiv.symm (_, _) = (#P.parts).divModEquiv.symm (_, _) at e simp only [Equiv.apply_eq_iff_eq, Prod.mk.injEq] at e apply_fun f diff --git a/Mathlib/Order/WellFoundedSet.lean b/Mathlib/Order/WellFoundedSet.lean index 7ef3749a6c2000..d3312cd54e6acf 100644 --- a/Mathlib/Order/WellFoundedSet.lean +++ b/Mathlib/Order/WellFoundedSet.lean @@ -389,8 +389,8 @@ protected theorem PartiallyWellOrderedOn.pi {α : ι → Type*} [Finite ι] {r : [∀ i, IsPreorder (α i) (r i)] {s : ∀ i, Set (α i)} (hs : ∀ i, PartiallyWellOrderedOn (s i) (r i)) : PartiallyWellOrderedOn (Set.univ.pi s) fun a b : ∀ i, α i => ∀ i, r i (a i) (b i) := by - haveI := Fintype.ofFinite ι - haveI : IsPreorder (∀ i, α i) (fun a b : ∀ i, α i => ∀ i, r i (a i) (b i)) := + have := Fintype.ofFinite ι + have : IsPreorder (∀ i, α i) (fun a b : ∀ i, α i => ∀ i, r i (a i) (b i)) := { refl a i := refl (a i) trans a b c hab hbc i := _root_.trans (hab i) (hbc i) } suffices ∀ (t : Finset ι), ∀ (f : ℕ → ∀ i, α i), (∀ n i, f n i ∈ s i) → diff --git a/Mathlib/Order/WellQuasiOrder.lean b/Mathlib/Order/WellQuasiOrder.lean index 0d34ea4abd0651..127e0624eece0c 100644 --- a/Mathlib/Order/WellQuasiOrder.lean +++ b/Mathlib/Order/WellQuasiOrder.lean @@ -88,8 +88,8 @@ product of well-quasi-ordered sets and `Pi.wellQuasiOrderedLE` when the relation theorem WellQuasiOrdered.pi {ι : Type*} {α : ι → Type*} [Finite ι] {r : ∀ i, (α i → α i → Prop)} [∀ i, IsPreorder (α i) (r i)] (hr : ∀ i, WellQuasiOrdered (r i)) : WellQuasiOrdered fun a b : ∀ i, α i => ∀ i, r i (a i) (b i) := by - haveI := Fintype.ofFinite ι - haveI : IsPreorder (∀ i, α i) (fun a b : ∀ i, α i => ∀ i, r i (a i) (b i)) := + have := Fintype.ofFinite ι + have : IsPreorder (∀ i, α i) (fun a b : ∀ i, α i => ∀ i, r i (a i) (b i)) := { refl a i := refl (a i) trans a b c hab hbc i := _root_.trans (hab i) (hbc i) } suffices ∀ (s : Finset ι) (f : ℕ → ∀ i, α i), diff --git a/Mathlib/Probability/CDF.lean b/Mathlib/Probability/CDF.lean index 52656abe68af9d..ec6345bbd532f6 100644 --- a/Mathlib/Probability/CDF.lean +++ b/Mathlib/Probability/CDF.lean @@ -105,7 +105,7 @@ lemma cdf_measure_stieltjesFunction (f : StieltjesFunction ℝ) (hf0 : Tendsto f open unitInterval in lemma unitInterval.cdf_eq_real (μ : Measure I) [IsProbabilityMeasure μ] (x : I) : cdf (μ.map Subtype.val) x.1 = μ.real (Icc 0 x) := by - haveI : IsProbabilityMeasure (μ.map Subtype.val) := isProbabilityMeasure_map (by fun_prop) + have : IsProbabilityMeasure (μ.map Subtype.val) := isProbabilityMeasure_map (by fun_prop) rw [ProbabilityTheory.cdf_eq_real, map_measureReal_apply measurable_subtype_coe measurableSet_Iic, subtype_Iic_eq_Icc] diff --git a/Mathlib/Probability/Independence/ZeroOne.lean b/Mathlib/Probability/Independence/ZeroOne.lean index 8966c4a502e96d..295f864ab87c27 100644 --- a/Mathlib/Probability/Independence/ZeroOne.lean +++ b/Mathlib/Probability/Independence/ZeroOne.lean @@ -181,7 +181,7 @@ theorem Kernel.indep_iSup_limsup (h_le : ∀ n, s n ≤ m0) (h_indep : iIndep s rw [iSup_comm] refine iSup_congr fun n => ?_ have h : ⨆ (i : β) (_ : n ∈ ns i), s n = ⨆ _ : ∃ i, n ∈ ns i, s n := by rw [iSup_exists] - haveI : Nonempty (∃ i : β, n ∈ ns i) := ⟨hns_univ n⟩ + have : Nonempty (∃ i : β, n ∈ ns i) := ⟨hns_univ n⟩ rw [h, iSup_const] theorem indep_iSup_limsup diff --git a/Mathlib/Probability/Kernel/Defs.lean b/Mathlib/Probability/Kernel/Defs.lean index cf3da6bb7a5360..d490b563f55331 100644 --- a/Mathlib/Probability/Kernel/Defs.lean +++ b/Mathlib/Probability/Kernel/Defs.lean @@ -391,7 +391,7 @@ theorem IsSFiniteKernel.finsetSum {κs : ι → Kernel α β} (I : Finset ι) | empty => rw [Finset.sum_empty]; infer_instance | insert i I hi_notMem_I h_ind => rw [Finset.sum_insert hi_notMem_I] - haveI : IsSFiniteKernel (κs i) := h i (Finset.mem_insert_self _ _) + have : IsSFiniteKernel (κs i) := h i (Finset.mem_insert_self _ _) have : IsSFiniteKernel (∑ x ∈ I, κs x) := h_ind fun i hiI => h i (Finset.mem_insert_of_mem hiI) exact IsSFiniteKernel.add _ _ diff --git a/Mathlib/Probability/Kernel/MeasurableIntegral.lean b/Mathlib/Probability/Kernel/MeasurableIntegral.lean index 0adc5b18d2add3..9b08a68cd9e4e5 100644 --- a/Mathlib/Probability/Kernel/MeasurableIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableIntegral.lean @@ -81,7 +81,7 @@ theorem StronglyMeasurable.integral_kernel_prod_right ⦃f : α → β → E⦄ by_cases hE : CompleteSpace E; swap · simp [integral, hE, stronglyMeasurable_const] borelize E - haveI : TopologicalSpace.SeparableSpace (range (uncurry f) ∪ {0} : Set E) := + have : TopologicalSpace.SeparableSpace (range (uncurry f) ∪ {0} : Set E) := hf.separableSpace_range_union_singleton let s : ℕ → SimpleFunc (α × β) E := SimpleFunc.approxOn _ hf.measurable (range (uncurry f) ∪ {0}) 0 (by simp) diff --git a/Mathlib/Probability/Martingale/Convergence.lean b/Mathlib/Probability/Martingale/Convergence.lean index f304cfd1f359f9..465482d146702d 100644 --- a/Mathlib/Probability/Martingale/Convergence.lean +++ b/Mathlib/Probability/Martingale/Convergence.lean @@ -198,7 +198,7 @@ theorem Submartingale.exists_ae_trim_tendsto_of_bdd [IsFiniteMeasure μ] (hf : S (hbdd : ∀ n, eLpNorm (f n) 1 μ ≤ R) : ∀ᵐ ω ∂μ.trim (sSup_le fun _ ⟨_, hn⟩ => hn ▸ ℱ.le _ : ⨆ n, ℱ n ≤ m0), ∃ c, Tendsto (fun n => f n ω) atTop (𝓝 c) := by - letI := (⨆ n, ℱ n) + let := (⨆ n, ℱ n) rw [ae_iff, trim_measurableSet_eq] · exact hf.exists_ae_tendsto_of_bdd hbdd · exact MeasurableSet.compl <| measurableSet_exists_tendsto diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index 17e0f30939b6f9..a952ae4571dee0 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -300,19 +300,19 @@ lemma rightCont_eq_of_nhdsGT_eq_bot [PartialOrder ι] [TopologicalSpace ι] [Ord /-- If the index type is a `SuccOrder`, then `𝓕₊ = 𝓕`. -/ @[simp] lemma rightCont_eq_self [LinearOrder ι] [SuccOrder ι] (𝓕 : Filtration ι m) : 𝓕₊ = 𝓕 := by - letI := Preorder.topology ι; haveI : OrderTopology ι := ⟨rfl⟩ + let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ ext _ rw [rightCont_eq_of_nhdsGT_eq_bot _ SuccOrder.nhdsGT] lemma rightCont_eq_of_isMax [PartialOrder ι] (𝓕 : Filtration ι m) {i : ι} (hi : IsMax i) : 𝓕₊ i = 𝓕 i := by - letI := Preorder.topology ι; haveI : OrderTopology ι := ⟨rfl⟩ + let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ exact rightCont_eq_of_nhdsGT_eq_bot _ (hi.Ioi_eq ▸ nhdsWithin_empty i) lemma rightCont_eq_of_exists_gt [LinearOrder ι] (𝓕 : Filtration ι m) {i : ι} (hi : ∃ j > i, Set.Ioo i j = ∅) : 𝓕₊ i = 𝓕 i := by - letI := Preorder.topology ι; haveI : OrderTopology ι := ⟨rfl⟩ + let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ obtain ⟨j, hij, hIoo⟩ := hi have hcov : i ⋖ j := covBy_iff_Ioo_eq.mpr ⟨hij, hIoo⟩ exact rightCont_eq_of_nhdsGT_eq_bot _ <| CovBy.nhdsGT hcov @@ -328,7 +328,7 @@ lemma rightCont_eq_of_neBot_nhdsGT [PartialOrder ι] [TopologicalSpace ι] [Orde lemma rightCont_eq_of_not_isMax [LinearOrder ι] [DenselyOrdered ι] (𝓕 : Filtration ι m) {i : ι} (hi : ¬IsMax i) : 𝓕₊ i = ⨅ j > i, 𝓕 j := by - letI := Preorder.topology ι; haveI : OrderTopology ι := ⟨rfl⟩ + let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ have : (𝓝[>] i).NeBot := nhdsGT_neBot_of_exists_gt (not_isMax_iff.mp hi) exact rightCont_eq_of_neBot_nhdsGT _ _ @@ -342,7 +342,7 @@ lemma rightCont_eq [LinearOrder ι] [DenselyOrdered ι] [NoMaxOrder ι] variable [PartialOrder ι] lemma le_rightCont (𝓕 : Filtration ι m) : 𝓕 ≤ 𝓕₊ := by - letI := Preorder.topology ι; haveI : OrderTopology ι := ⟨rfl⟩ + let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ intro i by_cases hne : (𝓝[>] i).NeBot · rw [rightCont_eq_of_neBot_nhdsGT] @@ -350,7 +350,7 @@ lemma le_rightCont (𝓕 : Filtration ι m) : 𝓕 ≤ 𝓕₊ := by · rw [rightCont_apply, if_neg hne] @[simp] lemma rightCont_self (𝓕 : Filtration ι m) : 𝓕₊₊ = 𝓕₊ := by - letI := Preorder.topology ι; haveI : OrderTopology ι := ⟨rfl⟩ + let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ apply le_antisymm _ 𝓕₊.le_rightCont intro i by_cases hne : (𝓝[>] i).NeBot diff --git a/Mathlib/Probability/Process/Predictable.lean b/Mathlib/Probability/Process/Predictable.lean index 5248d9c695c29d..3dcf24abbad8ac 100644 --- a/Mathlib/Probability/Process/Predictable.lean +++ b/Mathlib/Probability/Process/Predictable.lean @@ -174,8 +174,8 @@ variable [LinearOrder ι] [OrderBot ι] [MeasurableSpace ι] [TopologicalSpace lemma isStronglyProgressive {𝓕 : Filtration ι m} {u : ι → Ω → E} (h𝓕 : IsStronglyPredictable 𝓕 u) : IsStronglyProgressive 𝓕 u := by intro i - letI : MeasurableSpace (ι × Ω) := 𝓕.predictable - letI : MeasurableSpace (Set.Iic i × Ω) := Subtype.instMeasurableSpace.prod (𝓕 i) + let : MeasurableSpace (ι × Ω) := 𝓕.predictable + let : MeasurableSpace (Set.Iic i × Ω) := Subtype.instMeasurableSpace.prod (𝓕 i) let X m (x : Set.Iic i × Ω) := h𝓕.approx m ⟨x.1, x.2⟩ refine ⟨fun m ↦ SimpleFunc.mk (X m) ?_ ?_, ?_⟩ · exact fun e ↦ measurable_inclusion_predictable <| (h𝓕.approx m).measurableSet_fiber e @@ -192,8 +192,8 @@ section Discrete /-- If `u` is a discrete predictable process, then `u (n + 1)` is `𝓕 n`-measurable. -/ lemma measurable_add_one {𝓕 : Filtration ℕ m} {u : ℕ → Ω → E} (h𝓕 : IsStronglyPredictable 𝓕 u) (n : ℕ) : StronglyMeasurable[𝓕 n] (u (n + 1)) := by - letI : MeasurableSpace (ℕ × Ω) := 𝓕.predictable - letI : MeasurableSpace Ω := 𝓕 n + let : MeasurableSpace (ℕ × Ω) := 𝓕.predictable + let : MeasurableSpace Ω := 𝓕 n let X m := (Function.curry (h𝓕.approx m) (n + 1)) refine ⟨(fun m ↦ SimpleFunc.mk (X m) ?_ ?_), (fun ω ↦ h𝓕.tendsto_approx ⟨(n + 1), ω⟩)⟩ · intro s @@ -207,7 +207,7 @@ lemma measurable_add_one {𝓕 : Filtration ℕ m} {u : ℕ → Ω → E} lemma of_measurable_add_one {𝓕 : Filtration ℕ m} {u : ℕ → Ω → E} (h₀ : StronglyMeasurable[𝓕 0] (u 0)) (h : ∀ n, StronglyMeasurable[𝓕 n] (u (n + 1))) : IsStronglyPredictable 𝓕 u := by - letI : MeasurableSpace (ℕ × Ω) := 𝓕.predictable + let : MeasurableSpace (ℕ × Ω) := 𝓕.predictable -- first layer of approximation let X m (x : ℕ × Ω) := match x.1 with | 0 => h₀.approx m x.2 @@ -220,16 +220,16 @@ lemma of_measurable_add_one {𝓕 : Filtration ℕ m} {u : ℕ → Ω → E} refine MeasurableSet.iUnion <| fun n ↦ ?_ rcases n with rfl | n · apply measurableSet_predictable_singleton_bot_prod - letI : MeasurableSpace Ω := 𝓕 0 + let : MeasurableSpace Ω := 𝓕 0 exact (h₀.approx m).measurableSet_fiber s · apply measurableSet_predictable_singleton_prod by_cases! hmk : n + 1 ≤ m · rw [(by aesop : Function.curry (Y m) (n + 1) = Function.curry (X m) (n + 1))] - letI : MeasurableSpace Ω := 𝓕 n + let : MeasurableSpace Ω := 𝓕 n exact ((h n).approx m).measurableSet_fiber s · rw [(by aesop : Function.curry (Y m) (n + 1) = Function.curry (X m) 0)] apply 𝓕.mono (i := 0) (by simp) - letI : MeasurableSpace Ω := 𝓕 0 + let : MeasurableSpace Ω := 𝓕 0 exact (h₀.approx m).measurableSet_fiber s · apply Set.Finite.subset (s := ⋃ k ∈ Finset.range (m + 1), Set.range (Function.curry (X m) k)) · refine Set.Finite.biUnion' (by aesop) (fun n hn ↦ ?_) diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 1f84841c8797e3..6ba494a578c8c6 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -954,7 +954,7 @@ theorem isStronglyProgressive_min_stopping_time [PseudoMetrizableSpace ι] suffices h_meas : @Measurable _ _ (m_set s) (f i) fun x : s ↦ (x : Set.Iic i × Ω).snd from h_meas (f.mono (min_le_left _ _) _ (hτ.measurableSet_le (min i j))) exact measurable_snd.comp (@measurable_subtype_coe _ m_prod _) - · letI sc := sᶜ + · let sc := sᶜ suffices h_min_eq_left : (fun x : sc => min (↑(x : Set.Iic i × Ω).fst) (τ (x : Set.Iic i × Ω).snd)) = fun x : sc => ↑(x : Set.Iic i × Ω).fst by diff --git a/Mathlib/Probability/StrongLaw.lean b/Mathlib/Probability/StrongLaw.lean index bd87fe5c9227cb..f783f5ad0c7665 100644 --- a/Mathlib/Probability/StrongLaw.lean +++ b/Mathlib/Probability/StrongLaw.lean @@ -219,7 +219,7 @@ theorem sum_prob_mem_Ioc_le {X : Ω → ℝ} (hint : Integrable X) (hnonneg : 0 (hKN : K ≤ N) : ∑ j ∈ range K, ℙ {ω | X ω ∈ Set.Ioc (j : ℝ) N} ≤ ENNReal.ofReal (𝔼[X] + 1) := by let ρ : Measure ℝ := Measure.map X ℙ - haveI : IsProbabilityMeasure ρ := Measure.isProbabilityMeasure_map hint.aemeasurable + have : IsProbabilityMeasure ρ := Measure.isProbabilityMeasure_map hint.aemeasurable have A : ∑ j ∈ range K, ∫ _ in j..N, (1 : ℝ) ∂ρ ≤ 𝔼[X] + 1 := calc ∑ j ∈ range K, ∫ _ in j..N, (1 : ℝ) ∂ρ = diff --git a/Mathlib/Probability/UniformOn.lean b/Mathlib/Probability/UniformOn.lean index a3e07adddf3018..dde1c39b4d0397 100644 --- a/Mathlib/Probability/UniformOn.lean +++ b/Mathlib/Probability/UniformOn.lean @@ -139,7 +139,7 @@ theorem uniformOn_self (hs : s.Finite) (hs' : s.Nonempty) : uniformOn s s = 1 := theorem uniformOn_eq_one_of (hs : s.Finite) (hs' : s.Nonempty) (ht : s ⊆ t) : uniformOn s t = 1 := by - haveI := isProbabilityMeasure_uniformOn hs hs' + have := isProbabilityMeasure_uniformOn hs hs' refine eq_of_le_of_not_lt prob_le_one ?_ rw [not_lt, ← uniformOn_self hs hs'] exact measure_mono ht diff --git a/Mathlib/RepresentationTheory/Coinduced.lean b/Mathlib/RepresentationTheory/Coinduced.lean index 44a3d67e79da9e..6ecbcedcf78141 100644 --- a/Mathlib/RepresentationTheory/Coinduced.lean +++ b/Mathlib/RepresentationTheory/Coinduced.lean @@ -136,7 +136,7 @@ noncomputable def coindFunctor : Rep.{t} k G ⥤ Rep k H where instance {G : Type v'} [Group G] (S : Subgroup G) : (coindFunctor k S.subtype).PreservesEpimorphisms where preserves {X Y} f := (epi_iff_surjective _).2 fun y => by - letI := QuotientGroup.rightRel S + let := QuotientGroup.rightRel S choose! s hs using (Rep.epi_iff_surjective f).1 ‹_› choose! i hi using Quotient.mk'_surjective (α := G) let γ (g : G) : S := ⟨g * (i (Quotient.mk' g))⁻¹, diff --git a/Mathlib/RepresentationTheory/Maschke.lean b/Mathlib/RepresentationTheory/Maschke.lean index 9c70fc1fa34db6..1d0474598e46c9 100644 --- a/Mathlib/RepresentationTheory/Maschke.lean +++ b/Mathlib/RepresentationTheory/Maschke.lean @@ -145,8 +145,8 @@ set_option backward.isDefEq.respectTransparency false in theorem exists_leftInverse_of_injective (f : V →ₗ[k[G]] W) (hf : LinearMap.ker f = ⊥) : ∃ g : W →ₗ[k[G]] V, g.comp f = .id := by let A := k[G] - letI : Module k W := .compHom W (algebraMap k A) - letI : Module k V := .compHom V (algebraMap k A) + let : Module k W := .compHom W (algebraMap k A) + let : Module k V := .compHom V (algebraMap k A) have := IsScalarTower.of_compHom k A W have := IsScalarTower.of_compHom k A V set φ := (f.restrictScalars k).leftInverse diff --git a/Mathlib/RepresentationTheory/Subrepresentation.lean b/Mathlib/RepresentationTheory/Subrepresentation.lean index f69a7d13d6d269..e855a1e861ef5e 100644 --- a/Mathlib/RepresentationTheory/Subrepresentation.lean +++ b/Mathlib/RepresentationTheory/Subrepresentation.lean @@ -154,7 +154,7 @@ def ofSubmodule' (N : Submodule A[G] ρ.asModule) : Subrepresentation ρ where toSubmodule := { N with smul_mem' a w hw := by simpa using! (N.smul_mem (algebraMap A A[G] a) hw) } apply_mem_toSubmodule g w hw := by - letI _ : Module A[G] W := ρ.instModuleMonoidAlgebraAsModule + let _ : Module A[G] W := ρ.instModuleMonoidAlgebraAsModule have h : (MonoidAlgebra.single g (1 : A)) • w ∈ N := Submodule.smul_of_tower_mem N _ hw rw [Representation.single_smul, one_smul] at h diff --git a/Mathlib/RingTheory/Adjoin/Field.lean b/Mathlib/RingTheory/Adjoin/Field.lean index f81cd0b92fe5cc..6e006ad0e1c263 100644 --- a/Mathlib/RingTheory/Adjoin/Field.lean +++ b/Mathlib/RingTheory/Adjoin/Field.lean @@ -79,10 +79,10 @@ theorem Polynomial.lift_of_splits {F K L : Type*} [Field F] [Field K] [Field L] choose H3 _ using H3 rw [coe_insert, Set.insert_eq, Set.union_comm, Algebra.adjoin_union_eq_adjoin_adjoin] set Ks := Algebra.adjoin F (s : Set K) - haveI : FiniteDimensional F Ks := ((Submodule.fg_iff_finiteDimensional _).1 + have : FiniteDimensional F Ks := ((Submodule.fg_iff_finiteDimensional _).1 (fg_adjoin_of_finite s.finite_toSet H3)).of_subalgebra_toSubmodule - letI := fieldOfFiniteDimensional F Ks - letI := (f : Ks →+* L).toAlgebra + let := fieldOfFiniteDimensional F Ks + let := (f : Ks →+* L).toAlgebra have H5 : IsIntegral Ks a := H1.tower_top have H6 : ((minpoly Ks a).map (algebraMap Ks L)).Splits := by refine Splits.of_dvd H2 (map_ne_zero (minpoly.ne_zero H1)) ?_ diff --git a/Mathlib/RingTheory/Adjoin/PowerBasis.lean b/Mathlib/RingTheory/Adjoin/PowerBasis.lean index 22eea1d4c8c47c..227d1696b5821c 100644 --- a/Mathlib/RingTheory/Adjoin/PowerBasis.lean +++ b/Mathlib/RingTheory/Adjoin/PowerBasis.lean @@ -107,7 +107,7 @@ theorem repr_gen_pow_isIntegral (hB : IsIntegral R B.gen) have hlt : Q.natDegree < B.dim := by rw [← B.natDegree_minpoly, hmin, (minpoly.monic hB).natDegree_map, natDegree_lt_natDegree_iff hQ] - letI : Nontrivial R := Nontrivial.of_polynomial_ne hQ + let : Nontrivial R := Nontrivial.of_polynomial_ne hQ exact degree_modByMonic_lt _ (minpoly.monic hB) rw [this, aeval_eq_sum_range' hlt] simp only [map_sum, Finset.sum_apply'] diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index bf58bd9bd4f793..ba52f9a5871e15 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -1069,7 +1069,7 @@ polynomial over `L` divides some monic irreducible polynomial over `K`. -/ theorem Irreducible.exists_dvd_monic_irreducible_of_isIntegral {K L : Type*} [CommRing K] [IsDomain K] [Field L] [Algebra K L] [Algebra.IsIntegral K L] {f : L[X]} (hf : Irreducible f) : ∃ g : K[X], g.Monic ∧ Irreducible g ∧ f ∣ g.map (algebraMap K L) := by - haveI := Fact.mk hf + have := Fact.mk hf have h := hf.ne_zero have h2 := isIntegral_trans (R := K) _ (AdjoinRoot.isIntegral_root h) have h3 := (AdjoinRoot.minpoly_root h) ▸ minpoly.dvd_map_of_isScalarTower K L (AdjoinRoot.root f) diff --git a/Mathlib/RingTheory/Algebraic/Basic.lean b/Mathlib/RingTheory/Algebraic/Basic.lean index e4771691dbe162..b6da8df8b8c5c3 100644 --- a/Mathlib/RingTheory/Algebraic/Basic.lean +++ b/Mathlib/RingTheory/Algebraic/Basic.lean @@ -382,7 +382,7 @@ lemma IsAlgebraic.inv_iff {K} [Field K] [Algebra R K] {x : K} : IsAlgebraic R (x⁻¹) ↔ IsAlgebraic R x := by by_cases hx : x = 0 · simp [hx] - letI := invertibleOfNonzero hx + let := invertibleOfNonzero hx exact IsAlgebraic.invOf_iff (R := R) (x := x) alias ⟨_, IsAlgebraic.inv⟩ := IsAlgebraic.inv_iff @@ -413,8 +413,8 @@ theorem IsAlgebraic.extendScalars (hinj : Function.Injective (algebraMap R S)) { theorem IsAlgebraic.tower_top_of_subalgebra_le {A B : Subalgebra R S} (hle : A ≤ B) {x : S} (h : IsAlgebraic A x) : IsAlgebraic B x := by - letI : Algebra A B := (Subalgebra.inclusion hle).toAlgebra - haveI : IsScalarTower A B S := .of_algebraMap_eq fun _ ↦ rfl + let : Algebra A B := (Subalgebra.inclusion hle).toAlgebra + have : IsScalarTower A B S := .of_algebraMap_eq fun _ ↦ rfl exact h.extendScalars (Subalgebra.inclusion_injective hle) /-- If `x` is transcendental over `S`, then `x` is transcendental over `R` when `S` is an extension diff --git a/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean b/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean index 94856a80f5a219..4341d511a5dfeb 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean @@ -412,7 +412,7 @@ theorem algebraicIndependent_iUnion_of_directed {η : Type*} [Nonempty η] {s : theorem algebraicIndependent_sUnion_of_directed {s : Set (Set A)} (hsn : s.Nonempty) (hs : DirectedOn (· ⊆ ·) s) (h : ∀ a ∈ s, AlgebraicIndependent R ((↑) : a → A)) : AlgebraicIndependent R ((↑) : ⋃₀ s → A) := by - letI : Nonempty s := Nonempty.to_subtype hsn + let : Nonempty s := Nonempty.to_subtype hsn rw [sUnion_eq_iUnion] exact algebraicIndependent_iUnion_of_directed hs.directed_val (by simpa using h) diff --git a/Mathlib/RingTheory/AlgebraicIndependent/RankAndCardinality.lean b/Mathlib/RingTheory/AlgebraicIndependent/RankAndCardinality.lean index 7fdf3cac0a899f..e8a89eb73dc99d 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/RankAndCardinality.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/RankAndCardinality.lean @@ -44,9 +44,9 @@ theorem IsTranscendenceBasis.lift_cardinalMk_eq_max_lift lift.{max u w} #E = lift.{max v w} #F ⊔ lift.{max u v} #ι ⊔ ℵ₀ := by let K := Algebra.adjoin F (Set.range x) suffices #E = #K by simp [K, this, ← lift_mk_eq'.2 ⟨hx.1.aevalEquiv.toEquiv⟩] - haveI : Algebra.IsAlgebraic K E := hx.isAlgebraic + have : Algebra.IsAlgebraic K E := hx.isAlgebraic refine le_antisymm ?_ (mk_le_of_injective Subtype.val_injective) - haveI : Infinite K := hx.1.aevalEquiv.infinite_iff.1 inferInstance + have : Infinite K := hx.1.aevalEquiv.infinite_iff.1 inferInstance simpa only [sup_eq_left.2 (aleph0_le_mk K)] using Algebra.IsAlgebraic.cardinalMk_le_max K E theorem IsTranscendenceBasis.lift_rank_eq_max_lift @@ -54,7 +54,7 @@ theorem IsTranscendenceBasis.lift_rank_eq_max_lift {ι : Type w} {x : ι → E} [Nonempty ι] (hx : IsTranscendenceBasis F x) : lift.{max u w} (Module.rank F E) = lift.{max v w} #F ⊔ lift.{max u v} #ι ⊔ ℵ₀ := by let K := IntermediateField.adjoin F (Set.range x) - haveI : Algebra.IsAlgebraic K E := hx.isAlgebraic_field + have : Algebra.IsAlgebraic K E := hx.isAlgebraic_field rw [← rank_mul_rank F K E, lift_mul, ← hx.1.aevalEquivField.toLinearEquiv.lift_rank_eq, MvRatFunc.rank_eq_max_lift, lift_max, lift_max, lift_lift, lift_lift, lift_aleph0] refine mul_eq_left le_sup_right ((lift_le.2 ((rank_le_card K E).trans @@ -65,7 +65,7 @@ theorem Algebra.Transcendental.rank_eq_cardinalMk (F : Type u) (E : Type v) [Field F] [Field E] [Algebra F E] [Algebra.Transcendental F E] : Module.rank F E = #E := by obtain ⟨ι, x, hx⟩ := exists_isTranscendenceBasis' F E - haveI := hx.nonempty_iff_transcendental.2 ‹_› + have := hx.nonempty_iff_transcendental.2 ‹_› simpa [← hx.lift_cardinalMk_eq_max_lift] using hx.lift_rank_eq_max_lift theorem IntermediateField.rank_sup_le @@ -76,10 +76,10 @@ theorem IntermediateField.rank_sup_le by_cases hB : Algebra.IsAlgebraic F B · exact rank_sup_le_of_isAlgebraic A B (Or.inr hB) rw [← Algebra.transcendental_iff_not_isAlgebraic] at hA hB - haveI : Algebra.Transcendental F ↥(A ⊔ B) := .ringHom_of_comp_eq (RingHom.id F) + have : Algebra.Transcendental F ↥(A ⊔ B) := .ringHom_of_comp_eq (RingHom.id F) (inclusion le_sup_left) Function.surjective_id (inclusion_injective _) rfl - haveI := Algebra.Transcendental.infinite F A - haveI := Algebra.Transcendental.infinite F B + have := Algebra.Transcendental.infinite F A + have := Algebra.Transcendental.infinite F B simp_rw [Algebra.Transcendental.rank_eq_cardinalMk] rw [sup_def, mul_mk_eq_max, ← Cardinal.lift_le.{u}] refine (lift_cardinalMk_adjoin_le _ _).trans ?_ diff --git a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean index eb4677becdaabe..87083dd4ad8d06 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean @@ -142,8 +142,8 @@ lemma IsTranscendenceBasis.algebraMap_comp rw [Set.range_comp, ← AlgHom.map_adjoin] set Rx := adjoin R (range x) let e := Rx.equivMapOfInjective f (FaithfulSMul.algebraMap_injective S A) - letI := e.toRingHom.toAlgebra - haveI : IsScalarTower Rx (Rx.map f) A := .of_algebraMap_eq fun x ↦ rfl + let := e.toRingHom.toAlgebra + have : IsScalarTower Rx (Rx.map f) A := .of_algebraMap_eq fun x ↦ rfl have : Algebra.IsAlgebraic Rx S := hx.isAlgebraic have : Algebra.IsAlgebraic Rx A := .trans _ S _ exact .extendScalars e.injective @@ -158,7 +158,7 @@ lemma IsTranscendenceBasis.isAlgebraic_iff [IsDomain S] [NoZeroDivisors A] simpa [Sv, ← Subalgebra.isAlgebraic_iff, isAlgebraic_adjoin_iff] have le : Rv ≤ Sv.restrictScalars R := by rw [Subalgebra.restrictScalars_adjoin]; exact le_sup_right - letI : Algebra Rv Sv := (Subalgebra.inclusion le).toAlgebra + let : Algebra Rv Sv := (Subalgebra.inclusion le).toAlgebra have : IsScalarTower Rv Sv A := .of_algebraMap_eq fun x ↦ rfl have := (algebraMap R S).domain_nontrivial have := hv.isAlgebraic @@ -237,11 +237,11 @@ theorem IsTranscendenceBasis.nonempty_iff_transcendental [Nontrivial R] theorem IsTranscendenceBasis.isAlgebraic_field {F E : Type*} {x : ι → E} [Field F] [Field E] [Algebra F E] (hx : IsTranscendenceBasis F x) : Algebra.IsAlgebraic (IntermediateField.adjoin F (range x)) E := by - haveI := hx.isAlgebraic + have := hx.isAlgebraic set S := range x - letI : Algebra (adjoin F S) (IntermediateField.adjoin F S) := + let : Algebra (adjoin F S) (IntermediateField.adjoin F S) := (Subalgebra.inclusion (IntermediateField.algebra_adjoin_le_adjoin F S)).toRingHom.toAlgebra - haveI : IsScalarTower (adjoin F S) (IntermediateField.adjoin F S) E := + have : IsScalarTower (adjoin F S) (IntermediateField.adjoin F S) E := IsScalarTower.of_algebraMap_eq (congrFun rfl) exact Algebra.IsAlgebraic.extendScalars (R := adjoin F S) (Subalgebra.inclusion_injective _) diff --git a/Mathlib/RingTheory/ChainOfDivisors.lean b/Mathlib/RingTheory/ChainOfDivisors.lean index e9e83174dbeb93..47cb494adcd3e2 100644 --- a/Mathlib/RingTheory/ChainOfDivisors.lean +++ b/Mathlib/RingTheory/ChainOfDivisors.lean @@ -219,10 +219,10 @@ variable {N : Type*} [CommMonoidWithZero N] theorem factor_orderIso_map_one_eq_bot [IsCancelMulZero N] {m : Associates M} {n : Associates N} (d : { l : Associates M // l ≤ m } ≃o { l : Associates N // l ≤ n }) : (d ⟨1, one_dvd m⟩ : Associates N) = 1 := by - letI : OrderBot { l : Associates M // l ≤ m } := Subtype.orderBot bot_le - letI : OrderBot { l : Associates N // l ≤ n } := Subtype.orderBot bot_le + let : OrderBot { l : Associates M // l ≤ m } := Subtype.orderBot bot_le + let : OrderBot { l : Associates N // l ≤ n } := Subtype.orderBot bot_le simp only [← Associates.bot_eq_one, Subtype.mk_bot, bot_le, Subtype.coe_eq_bot_iff] - letI : BotHomClass ({ l // l ≤ m } ≃o { l // l ≤ n }) _ _ := OrderIsoClass.toBotHomClass + let : BotHomClass ({ l // l ≤ m } ≃o { l // l ≤ n }) _ _ := OrderIsoClass.toBotHomClass exact map_bot d set_option backward.isDefEq.respectTransparency false in @@ -291,8 +291,8 @@ theorem map_prime_of_factor_orderIso {m p : Associates M} {n : Associates N} (hn · have : b ≤ n := le_trans (le_of_lt hb) (d ⟨p, dvd_of_mem_normalizedFactors hp⟩).prop obtain ⟨x, hx⟩ := d.surjective ⟨b, this⟩ rw [← Subtype.coe_mk (p := (· ≤ n)) b this, ← hx] at hb - letI : OrderBot { l : Associates M // l ≤ m } := Subtype.orderBot bot_le - letI : OrderBot { l : Associates N // l ≤ n } := Subtype.orderBot bot_le + let : OrderBot { l : Associates M // l ≤ m } := Subtype.orderBot bot_le + let : OrderBot { l : Associates N // l ≤ n } := Subtype.orderBot bot_le suffices x = ⊥ by rw [this, OrderIso.map_bot d] at hx refine (Subtype.mk_eq_bot_iff ?_ _).mp hx.symm @@ -333,7 +333,7 @@ theorem emultiplicity_prime_eq_emultiplicity_image_by_factor_orderIso {m p : Ass emultiplicity (↑(d.symm (d ⟨p, dvd_of_mem_normalizedFactors hp⟩))) m by rw [d.symm_apply_apply ⟨p, dvd_of_mem_normalizedFactors hp⟩, Subtype.coe_mk] at this exact this - letI := Classical.decEq (Associates N) + let := Classical.decEq (Associates N) simpa only [Subtype.coe_eta] using emultiplicity_prime_le_emultiplicity_image_by_factor_orderIso (mem_normalizedFactors_factor_orderIso_of_mem_normalizedFactors hn hp d) d.symm @@ -404,7 +404,7 @@ theorem mem_normalizedFactors_factor_dvd_iso_of_mem_normalizedFactors {m p : M} exact mk_dvd_mk.mpr (dvd_of_mem_normalizedFactors hp)⟩) := by rw [mkFactorOrderIsoOfFactorDvdEquiv_apply_coe] rw [← Associates.prime_mk, this] - letI := Classical.decEq (Associates M) + let := Classical.decEq (Associates M) refine map_prime_of_factor_orderIso (mk_ne_zero.mpr hn) ?_ _ obtain ⟨q, hq, hq'⟩ := exists_mem_normalizedFactors_of_dvd (mk_ne_zero.mpr hm) diff --git a/Mathlib/RingTheory/Coprime/Ideal.lean b/Mathlib/RingTheory/Coprime/Ideal.lean index d5517b7176ad6d..b6e84354e62857 100644 --- a/Mathlib/RingTheory/Coprime/Ideal.lean +++ b/Mathlib/RingTheory/Coprime/Ideal.lean @@ -34,7 +34,7 @@ When ideals are all of the form `I i = R ∙ s i`, this is equivalent to the theorem iSup_iInf_eq_top_iff_pairwise {t : Finset ι} (h : t.Nonempty) (I : ι → Ideal R) : (⨆ i ∈ t, ⨅ (j) (_ : j ∈ t) (_ : j ≠ i), I j) = ⊤ ↔ (t : Set ι).Pairwise fun i j => I i ⊔ I j = ⊤ := by - haveI : DecidableEq ι := Classical.decEq ι + have : DecidableEq ι := Classical.decEq ι rw [eq_top_iff_one, Submodule.mem_iSup_finset_iff_exists_sum] refine h.cons_induction ?_ ?_ <;> clear t h · simp only [Finset.sum_singleton, Finset.coe_singleton, Set.pairwise_singleton, iff_true] diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index 8637e97f1922c2..42baecbe8eb5a1 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -573,9 +573,9 @@ theorem differentIdeal_eq_differentIdeal_mul_differentIdeal (C : Type*) [IsDomai isSeparable_tower_top_of_isSeparable (FractionRing A) _ _ have : Algebra.IsSeparable (FractionRing A) (FractionRing B) := isSeparable_tower_bot_of_isSeparable _ _ (FractionRing C) - haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ - haveI : FiniteDimensional (FractionRing A) (FractionRing C) := .of_isLocalization A C A⁰ - haveI : FiniteDimensional (FractionRing B) (FractionRing C) := .of_isLocalization B C B⁰ + have : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ + have : FiniteDimensional (FractionRing A) (FractionRing C) := .of_isLocalization A C A⁰ + have : FiniteDimensional (FractionRing B) (FractionRing C) := .of_isLocalization B C B⁰ rw [← coeIdeal_inj (K := FractionRing C), coeIdeal_mul, coeIdeal_differentIdeal A (FractionRing A), coeIdeal_differentIdeal B (FractionRing B)] rw [← extendedHom_coeIdeal_eq_map (K := FractionRing B), coeIdeal_differentIdeal A @@ -635,7 +635,7 @@ lemma conductor_mul_differentIdeal (conductor A x) * differentIdeal A B = Ideal.span {aeval x (derivative (minpoly A x))} := by classical have hAx : IsIntegral A x := IsIntegralClosure.isIntegral A L x - haveI := IsIntegralClosure.isFractionRing_of_finite_extension A K L B + have := IsIntegralClosure.isFractionRing_of_finite_extension A K L B apply FractionalIdeal.coeIdeal_injective (K := L) simp only [FractionalIdeal.coeIdeal_mul, FractionalIdeal.coeIdeal_span_singleton] rw [coeIdeal_differentIdeal A K L B, mul_inv_eq_iff_eq_mul₀] @@ -759,7 +759,7 @@ theorem not_dvd_differentIdeal_of_intTrace_not_mem exact differentIdeal_ne_bot · obtain rfl := hxQ simp at hx - letI : Algebra (A ⧸ p) (B ⧸ Q) := Ideal.Quotient.algebraQuotientOfLEComap (by + let : Algebra (A ⧸ p) (B ⧸ Q) := Ideal.Quotient.algebraQuotientOfLEComap (by rw [← Ideal.map_le_iff_le_comap, ← hP] exact Ideal.mul_le_left) let K := FractionRing A @@ -812,13 +812,13 @@ theorem not_dvd_differentIdeal_of_isCoprime_of_isSeparable (hPQ : IsCoprime P Q) (hP : P * Q = Ideal.map (algebraMap A B) p) [Algebra.IsSeparable (A ⧸ p) (B ⧸ P)] : ¬ P ∣ differentIdeal A B := by - letI : Algebra (A ⧸ p) (B ⧸ Q) := Ideal.Quotient.algebraQuotientOfLEComap (by + let : Algebra (A ⧸ p) (B ⧸ Q) := Ideal.Quotient.algebraQuotientOfLEComap (by rw [← Ideal.map_le_iff_le_comap, ← hP] exact Ideal.mul_le_left) have : IsScalarTower A (A ⧸ p) (B ⧸ Q) := .of_algebraMap_eq' rfl have : Module.Finite (A ⧸ p) (B ⧸ Q) := Module.Finite.of_restrictScalars_finite A (A ⧸ p) (B ⧸ Q) - letI e : (B ⧸ p.map (algebraMap A B)) ≃ₐ[A ⧸ p] ((B ⧸ P) × B ⧸ Q) := + let e : (B ⧸ p.map (algebraMap A B)) ≃ₐ[A ⧸ p] ((B ⧸ P) × B ⧸ Q) := { __ := (Ideal.quotEquivOfEq hP.symm).trans (Ideal.quotientMulEquivQuotientProd P Q hPQ), commutes' := Quotient.ind fun _ ↦ rfl } obtain ⟨x, hx⟩ : ∃ x, Algebra.trace (A ⧸ p) (B ⧸ P) x ≠ 0 := by @@ -888,14 +888,14 @@ lemma dvd_differentIdeal_of_not_isSeparable ← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_apply A B L, ← hz'] intro x hx rw [← Ideal.Quotient.eq_zero_iff_mem, ← Algebra.trace_quotient_eq_of_isDedekindDomain] - letI : Algebra (A ⧸ p) (B ⧸ a) := + let : Algebra (A ⧸ p) (B ⧸ a) := Ideal.Quotient.algebraQuotientOfLEComap (Ideal.map_le_iff_le_comap.mp (Ideal.dvd_iff_le.mp ⟨_, ha.trans (mul_comm _ _)⟩)) have : IsScalarTower A (A ⧸ p) (B ⧸ a) := .of_algebraMap_eq' rfl have : Module.Finite (A ⧸ p) (B ⧸ a) := .of_restrictScalars_finite A _ _ have := ((Ideal.prime_iff_isPrime hPbot).mpr inferInstance) rw [← this.irreducible.gcd_eq_one_iff, ← Ideal.isCoprime_iff_gcd] at hPa - letI e : (B ⧸ p.map (algebraMap A B)) ≃ₐ[A ⧸ p] ((B ⧸ P) × B ⧸ a) := + let e : (B ⧸ p.map (algebraMap A B)) ≃ₐ[A ⧸ p] ((B ⧸ P) × B ⧸ a) := { __ := (Ideal.quotEquivOfEq ha).trans (Ideal.quotientMulEquivQuotientProd P a hPa), commutes' := Quotient.ind fun _ ↦ rfl } have hx' : (e (Ideal.Quotient.mk _ x)).2 = 0 := by diff --git a/Mathlib/RingTheory/DedekindDomain/Dvr.lean b/Mathlib/RingTheory/DedekindDomain/Dvr.lean index 148e5ee14fe445..bc729ca4b09a2f 100644 --- a/Mathlib/RingTheory/DedekindDomain/Dvr.lean +++ b/Mathlib/RingTheory/DedekindDomain/Dvr.lean @@ -84,10 +84,10 @@ theorem IsLocalization.isDedekindDomain [IsDedekindDomain A] {M : Submonoid A} ( have h : ∀ y : M, IsUnit (algebraMap A (FractionRing A) y) := by rintro ⟨y, hy⟩ exact IsUnit.mk0 _ (mt IsFractionRing.to_map_eq_zero_iff.mp (nonZeroDivisors.ne_zero (hM hy))) - letI : Algebra Aₘ (FractionRing A) := RingHom.toAlgebra (IsLocalization.lift h) - haveI : IsScalarTower A Aₘ (FractionRing A) := + let : Algebra Aₘ (FractionRing A) := RingHom.toAlgebra (IsLocalization.lift h) + have : IsScalarTower A Aₘ (FractionRing A) := IsScalarTower.of_algebraMap_eq fun x => (IsLocalization.lift_eq h x).symm - haveI : IsFractionRing Aₘ (FractionRing A) := + have : IsFractionRing Aₘ (FractionRing A) := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization M _ _ refine (isDedekindDomain_iff _ (FractionRing A)).mpr ⟨?_, ?_, ?_, ?_⟩ · infer_instance @@ -113,7 +113,7 @@ instance Localization.AtPrime.isDedekindDomain [IsDedekindDomain A] (P : Ideal A theorem IsLocalization.AtPrime.not_isField {P : Ideal A} (hP : P ≠ ⊥) [pP : P.IsPrime] (Aₘ : Type*) [CommRing Aₘ] [Algebra A Aₘ] [IsLocalization.AtPrime Aₘ P] : ¬ IsField Aₘ := by intro h - letI := h.toField + let := h.toField obtain ⟨x, x_mem, x_ne⟩ := P.ne_bot_iff.mp hP exact (IsLocalRing.maximalIdeal.isMaximal _).ne_top @@ -129,9 +129,9 @@ theorem IsLocalization.AtPrime.isDiscreteValuationRing_of_dedekind_domain [IsDed {P : Ideal A} (hP : P ≠ ⊥) [pP : P.IsPrime] (Aₘ : Type*) [CommRing Aₘ] [IsDomain Aₘ] [Algebra A Aₘ] [IsLocalization.AtPrime Aₘ P] : IsDiscreteValuationRing Aₘ := by classical - letI : IsNoetherianRing Aₘ := + let : IsNoetherianRing Aₘ := IsLocalization.isNoetherianRing P.primeCompl _ IsDedekindRing.toIsNoetherian - letI : IsLocalRing Aₘ := IsLocalization.AtPrime.isLocalRing Aₘ P + let : IsLocalRing Aₘ := IsLocalization.AtPrime.isLocalRing Aₘ P have hnf := IsLocalization.AtPrime.not_isField A hP Aₘ exact ((IsDiscreteValuationRing.TFAE Aₘ hnf).out 0 2).mpr diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index c25fa26cb9ebc7..359ec6f95ae2c7 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -85,7 +85,7 @@ theorem IsDedekindDomain.HeightOneSpectrum.maxPowDividing_eq_pow_multiset_count theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) : {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by rw [← Set.finite_coe_iff, Set.coe_setOf] - haveI h_fin := fintypeSubtypeDvd I hI + have h_fin := fintypeSubtypeDvd I hI refine Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) ?_ intro v w hvw diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index 7a1360a71b601b..29985c38176515 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -306,7 +306,7 @@ and the lcm is their infimum, and use this to instantiate `NormalizedGCDMonoid ( @[simp] theorem sup_mul_inf (I J : Ideal A) : (I ⊔ J) * (I ⊓ J) = I * J := by - letI := UniqueFactorizationMonoid.toNormalizedGCDMonoid (Ideal A) + let := UniqueFactorizationMonoid.toNormalizedGCDMonoid (Ideal A) have hgcd : gcd I J = I ⊔ J := by rw [gcd_eq_normalize _ _, normalize_eq] · rw [dvd_iff_le, sup_le_iff, ← dvd_iff_le, ← dvd_iff_le] @@ -1230,7 +1230,7 @@ namespace IsDedekindDomain theorem primesOver_finite : (primesOver p B).Finite := by by_cases hpb : p = ⊥ · rw [hpb] at hpm ⊢ - haveI : IsDomain A := IsDomain.of_bot_isPrime A + have : IsDomain A := IsDomain.of_bot_isPrime A rw [primesOver_bot A B] exact Set.finite_singleton ⊥ · rw [← coe_primesOverFinset hpb B] diff --git a/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean b/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean index 7e8ffa3eefa9d3..7f5e41afbd3b09 100644 --- a/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean +++ b/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean @@ -61,10 +61,10 @@ include K L then `L` is the localization of the integral closure `C` of `A` in `L` at `A⁰`. -/ theorem IsIntegralClosure.isLocalization [IsDomain A] [Algebra.IsAlgebraic K L] : IsLocalization (Algebra.algebraMapSubmonoid C A⁰) L := by - haveI : IsDomain C := + have : IsDomain C := (IsIntegralClosure.equiv A C L (integralClosure A L)).toMulEquiv.isDomain (integralClosure A L) - haveI : IsTorsionFree A L := .trans_faithfulSMul A K L - haveI : IsTorsionFree A C := IsIntegralClosure.isTorsionFree A L + have : IsTorsionFree A L := .trans_faithfulSMul A K L + have : IsTorsionFree A C := IsIntegralClosure.isTorsionFree A L refine ⟨?_, fun z => ?_, fun {x y} h => ⟨1, ?_⟩⟩ · rintro ⟨_, x, hx, rfl⟩ rw [isUnit_iff_ne_zero, map_ne_zero_iff _ (IsIntegralClosure.algebraMap_injective C A L), @@ -123,7 +123,7 @@ variable (L) then `L` has a basis over `A` consisting of integral elements. -/ theorem FiniteDimensional.exists_is_basis_integral : ∃ (s : Finset L) (b : Basis s K L), ∀ x, IsIntegral A (b x) := by - letI := Classical.decEq L + let := Classical.decEq L let s' := IsNoetherian.finsetBasisIndex K L let bs' := IsNoetherian.finsetBasis K L obtain ⟨y, hy, his'⟩ := exists_integral_multiples A K (Finset.univ.image bs') @@ -150,10 +150,10 @@ integrally closed and Noetherian, the integral closure `C` of `A` in `L` is Noetherian over `A`. -/ theorem IsIntegralClosure.isNoetherian [IsIntegrallyClosed A] [IsNoetherianRing A] : IsNoetherian A C := by - haveI := Classical.decEq L + have := Classical.decEq L obtain ⟨s, b, hb_int⟩ := FiniteDimensional.exists_is_basis_integral A K L let b' := (traceForm K L).dualBasis (traceForm_nondegenerate K L) b - letI := isNoetherian_span_of_finite A (Set.finite_range b') + let := isNoetherian_span_of_finite A (Set.finite_range b') let f : C →ₗ[A] Submodule.span A (Set.range b') := (Submodule.inclusion (IsIntegralClosure.range_le_span_dualBasis C b hb_int)).comp ((Algebra.linearMap C L).restrictScalars A).rangeRestrict @@ -173,7 +173,7 @@ integrally closed and Noetherian, the integral closure `C` of `A` in `L` is finite over `A`. -/ theorem IsIntegralClosure.finite [IsIntegrallyClosed A] [IsNoetherianRing A] : Module.Finite A C := by - haveI := IsIntegralClosure.isNoetherian A K L C + have := IsIntegralClosure.isNoetherian A K L C exact Module.IsNoetherian.finite A C /-- If `L` is a finite separable extension of `K = Frac(A)`, where `A` is a principal ring @@ -190,9 +190,9 @@ and `L` has no zero smul divisors by `A`, the `A`-rank of the integral closure ` is equal to the `K`-rank of `L`. -/ theorem IsIntegralClosure.rank [IsPrincipalIdealRing A] [IsTorsionFree A L] : Module.finrank A C = Module.finrank K L := by - haveI : Module.Free A C := IsIntegralClosure.module_free A K L C - haveI : IsNoetherian A C := IsIntegralClosure.isNoetherian A K L C - haveI : IsLocalization (Algebra.algebraMapSubmonoid C A⁰) L := + have : Module.Free A C := IsIntegralClosure.module_free A K L C + have : IsNoetherian A C := IsIntegralClosure.isNoetherian A K L C + have : IsLocalization (Algebra.algebraMapSubmonoid C A⁰) L := IsIntegralClosure.isLocalization A K L C let b := Basis.localizationLocalization K A⁰ L (Module.Free.chooseBasis A C) rw [Module.finrank_eq_card_chooseBasisIndex, Module.finrank_eq_card_basis b] diff --git a/Mathlib/RingTheory/DedekindDomain/PID.lean b/Mathlib/RingTheory/DedekindDomain/PID.lean index 6472035ba9635f..87ad079d711df5 100644 --- a/Mathlib/RingTheory/DedekindDomain/PID.lean +++ b/Mathlib/RingTheory/DedekindDomain/PID.lean @@ -94,7 +94,7 @@ theorem FractionalIdeal.isPrincipal.of_finite_maximals_of_inv {A : Type*} [CommR have hinv' := hinv rw [coe_ext_iff, coe_mul] at hinv let s := hf.toFinset - haveI := Classical.decEq (Ideal R) + have := Classical.decEq (Ideal R) have coprime : ∀ M ∈ s, ∀ M' ∈ s.erase M, M ⊔ M' = ⊤ := by simp_rw [s, Finset.mem_erase, hf.mem_toFinset] rintro M hM M' ⟨hne, hM'⟩ @@ -190,8 +190,8 @@ theorem IsLocalization.OverPrime.mem_normalizedFactors_of_isPrime [IsDomain S] have non_zero_div : Algebra.algebraMapSubmonoid S p.primeCompl ≤ S⁰ := map_le_nonZeroDivisors_of_injective _ (FaithfulSMul.algebraMap_injective _ _) p.primeCompl_le_nonZeroDivisors - letI : Algebra (Localization.AtPrime p) Sₚ := localizationAlgebra p.primeCompl S - haveI : IsScalarTower R (Localization.AtPrime p) Sₚ := + let : Algebra (Localization.AtPrime p) Sₚ := localizationAlgebra p.primeCompl S + have : IsScalarTower R (Localization.AtPrime p) Sₚ := IsScalarTower.of_algebraMap_eq fun x => by rw [IsScalarTower.algebraMap_apply R S] exact (IsLocalization.map_eq (T := Algebra.algebraMapSubmonoid S (primeCompl p)) @@ -226,8 +226,8 @@ theorem IsLocalization.OverPrime.mem_normalizedFactors_of_isPrime [IsDomain S] then the localization `Sₚ` of `S` at `p` is a PID. -/ theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime [IsDomain S] : IsPrincipalIdealRing Sₚ := by - letI := Classical.decEq (Ideal Sₚ) - letI := Classical.decPred fun P : Ideal Sₚ => P.IsPrime + let := Classical.decEq (Ideal Sₚ) + let := Classical.decPred fun P : Ideal Sₚ => P.IsPrime refine IsPrincipalIdealRing.of_finite_primes (Set.Finite.ofFinset diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index cf440202db633a..b89d1f3d671ca9 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -132,7 +132,7 @@ theorem iff_pid_with_one_nonzero_prime (R : Type u) [CommRing R] [IsDomain R] : rw [irreducible_iff_uniformizer] at hQ2 exact hQ2.symm · rintro ⟨RPID, Punique⟩ - haveI : IsLocalRing R := IsLocalRing.of_unique_nonzero_prime Punique + have : IsLocalRing R := IsLocalRing.of_unique_nonzero_prime Punique refine { not_a_field' := ?_ } rcases Punique with ⟨P, ⟨hP1, hP2⟩, _⟩ have hPM : P ≤ maximalIdeal R := le_maximalIdeal hP2.1 @@ -272,7 +272,7 @@ theorem of_ufd_of_unique_irreducible {R : Type u} [CommRing R] [IsDomain R] (h₂ : ∀ ⦃p q : R⦄, Irreducible p → Irreducible q → Associated p q) : IsDiscreteValuationRing R := by rw [iff_pid_with_one_nonzero_prime] - haveI PID : IsPrincipalIdealRing R := aux_pid_of_ufd_of_unique_irreducible R h₁ h₂ + have PID : IsPrincipalIdealRing R := aux_pid_of_ufd_of_unique_irreducible R h₁ h₂ obtain ⟨p, hp⟩ := h₁ refine ⟨PID, ⟨Ideal.span {p}, ⟨?_, ?_⟩, ?_⟩⟩ · rw [Submodule.ne_bot_iff] @@ -292,7 +292,7 @@ is a discrete valuation ring. -/ theorem ofHasUnitMulPowIrreducibleFactorization {R : Type u} [CommRing R] [IsDomain R] (hR : HasUnitMulPowIrreducibleFactorization R) : IsDiscreteValuationRing R := by - letI : UniqueFactorizationMonoid R := hR.toUniqueFactorizationMonoid + let : UniqueFactorizationMonoid R := hR.toUniqueFactorizationMonoid apply of_ufd_of_unique_irreducible _ hR.unique_irreducible obtain ⟨p, hp, H⟩ := hR exact ⟨p, hp⟩ @@ -669,7 +669,7 @@ lemma maximalIdeal_eq_setOf_le_v_algebraMap : ∀ [IsDiscreteValuationRing O] {ϖ : O} (_h : Irreducible ϖ), (IsLocalRing.maximalIdeal O : Set O) = {y : O | v (algebraMap O K y) ≤ v (algebraMap O K ϖ)} := by - letI : IsDomain O := hv.hom_inj.isDomain + let : IsDomain O := hv.hom_inj.isDomain intro _ _ h rw [← hv.coe_span_singleton_eq_setOf_le_v_algebraMap, ← h.maximalIdeal_eq] @@ -678,7 +678,7 @@ lemma maximalIdeal_pow_eq_setOf_le_v_algebraMap_pow : ∀ [IsDiscreteValuationRing O] {ϖ : O} (_h : Irreducible ϖ) (n : ℕ), ((IsLocalRing.maximalIdeal O ^ n : Ideal O) : Set O) = {y : O | v (algebraMap O K y) ≤ v (algebraMap O K ϖ) ^ n} := by - letI : IsDomain O := hv.hom_inj.isDomain + let : IsDomain O := hv.hom_inj.isDomain intro _ ϖ h n have : (v (algebraMap O K ϖ)) ^ n = v (algebraMap O K (ϖ ^ n)) := by simp rw [this, ← hv.coe_span_singleton_eq_setOf_le_v_algebraMap, diff --git a/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean b/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean index f1a75c850f1310..f4c1f0e4f5cbde 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean @@ -229,7 +229,7 @@ variable {R} lemma IsLocalRing.finrank_CotangentSpace_eq_one_iff [IsNoetherianRing R] [IsLocalRing R] [IsDomain R] : finrank (ResidueField R) (CotangentSpace R) = 1 ↔ IsDiscreteValuationRing R := by by_cases hR : IsField R - · letI := hR.toField + · let := hR.toField simp only [finrank_cotangentSpace_eq_zero, zero_ne_one, false_iff] exact fun h ↦ h.3 maximalIdeal_eq_bot · exact (IsDiscreteValuationRing.TFAE R hR).out 5 0 diff --git a/Mathlib/RingTheory/Discriminant.lean b/Mathlib/RingTheory/Discriminant.lean index d1a54cd687e0ef..2972490392376e 100644 --- a/Mathlib/RingTheory/Discriminant.lean +++ b/Mathlib/RingTheory/Discriminant.lean @@ -203,7 +203,7 @@ theorem discr_powerBasis_eq_norm [Algebra.IsSeparable K L] : (-1) ^ (n * (n - 1) / 2) * norm K (aeval pb.gen (minpoly K pb.gen).derivative) := by let E := AlgebraicClosure L - letI := fun a b : E => Classical.propDecidable (Eq a b) + let := fun a b : E => Classical.propDecidable (Eq a b) have e : Fin pb.dim ≃ (L →ₐ[K] E) := by refine equivOfCardEq ?_ rw [Fintype.card_fin, AlgHom.card] diff --git a/Mathlib/RingTheory/EssentialFiniteness.lean b/Mathlib/RingTheory/EssentialFiniteness.lean index 0a76bea030a20b..ae39051f6bc1de 100644 --- a/Mathlib/RingTheory/EssentialFiniteness.lean +++ b/Mathlib/RingTheory/EssentialFiniteness.lean @@ -162,7 +162,7 @@ lemma essFiniteType_iff_exists_subalgebra : EssFiniteType R S ↔ ∃ (S₀ : Subalgebra R S) (M : Submonoid S₀), FiniteType R S₀ ∧ IsLocalization M S := by refine ⟨fun h ↦ ⟨subalgebra R S, submonoid R S, inferInstance, inferInstance⟩, ?_⟩ rintro ⟨S₀, M, _, _⟩ - letI := of_isLocalization S M + let := of_isLocalization S M exact comp R S₀ S instance EssFiniteType.baseChange [h : EssFiniteType R S] : EssFiniteType T (T ⊗[R] S) := by diff --git a/Mathlib/RingTheory/Etale/Basic.lean b/Mathlib/RingTheory/Etale/Basic.lean index c941952589073a..e13202a840d204 100644 --- a/Mathlib/RingTheory/Etale/Basic.lean +++ b/Mathlib/RingTheory/Etale/Basic.lean @@ -198,8 +198,8 @@ theorem localization_base [FormallyEtale R Sₘ] : FormallyEtale Rₘ Sₘ := /-- The localization of a formally étale map is formally étale. -/ theorem localization_map [FormallyEtale R S] : FormallyEtale Rₘ Sₘ := by - haveI : FormallyEtale S Sₘ := FormallyEtale.of_isLocalization (M.map (algebraMap R S)) - haveI : FormallyEtale R Sₘ := FormallyEtale.comp R S Sₘ + have : FormallyEtale S Sₘ := FormallyEtale.of_isLocalization (M.map (algebraMap R S)) + have : FormallyEtale R Sₘ := FormallyEtale.comp R S Sₘ exact FormallyEtale.localization_base M end Localization diff --git a/Mathlib/RingTheory/Etale/Kaehler.lean b/Mathlib/RingTheory/Etale/Kaehler.lean index 90b4de8ee12988..4fea33431d1202 100644 --- a/Mathlib/RingTheory/Etale/Kaehler.lean +++ b/Mathlib/RingTheory/Etale/Kaehler.lean @@ -188,11 +188,11 @@ lemma tensorCotangentInvFun_smul_mk (H : Function.Bijective ((f.mapKer halg).liftBaseChange Q.Ring)) (x : Q.Ring) (y : P.ker) : tensorCotangentInvFun f halg H (x • .mk ⟨f.toRingHom y, (f.mapKer halg y).2⟩) = x • 1 ⊗ₜ .mk y := by - letI := ((algebraMap S T).comp (algebraMap P.Ring S)).toAlgebra - haveI : IsScalarTower P.Ring S T := .of_algebraMap_eq' rfl - haveI : IsScalarTower P.Ring Q.Ring T := + let := ((algebraMap S T).comp (algebraMap P.Ring S)).toAlgebra + have : IsScalarTower P.Ring S T := .of_algebraMap_eq' rfl + have : IsScalarTower P.Ring Q.Ring T := .of_algebraMap_eq fun r ↦ halg ▸ (f.algebraMap_toRingHom r).symm - letI e := LinearEquiv.ofBijective _ H + let e := LinearEquiv.ofBijective _ H trans tensorCotangentInvFun f halg H (.mk ((f.mapKer halg).liftBaseChange Q.Ring (x ⊗ₜ y))) · simp; rfl change ((TensorProduct.mk _ _ _ 1).restrictScalars _ ∘ₗ Cotangent.mk).liftBaseChange _ @@ -352,12 +352,12 @@ lemma tensorH1CotangentOfIsLocalization_toLinearMap Extension.tensorH1CotangentOfFormallyEtale, LinearEquiv.ofBijective_apply, LinearMap.liftBaseChange_tmul, one_smul, Extension.equivH1CotangentOfFormallySmooth, LinearEquiv.trans_apply] - letI P : Extension R S := (Generators.self R S).toExtension - letI M' := M.comap (algebraMap P.Ring S) - letI fQ : Localization M' →ₐ[R] T := IsLocalization.liftAlgHom (M := M') + let P : Extension R S := (Generators.self R S).toExtension + let M' := M.comap (algebraMap P.Ring S) + let fQ : Localization M' →ₐ[R] T := IsLocalization.liftAlgHom (M := M') (f := (IsScalarTower.toAlgHom R S T).comp (IsScalarTower.toAlgHom R P.Ring S)) (fun ⟨y, hy⟩ ↦ by simpa using IsLocalization.map_units T ⟨algebraMap P.Ring S y, hy⟩) - letI Q : Extension R T := .ofSurjective fQ (by + let Q : Extension R T := .ofSurjective fQ (by intro x obtain ⟨x, ⟨s, hs⟩, rfl⟩ := IsLocalization.exists_mk'_eq M x obtain ⟨x, rfl⟩ := P.algebraMap_surjective x @@ -366,7 +366,7 @@ lemma tensorH1CotangentOfIsLocalization_toLinearMap simp only [fQ, IsLocalization.coe_liftAlgHom, AlgHom.toRingHom_eq_coe] rw [IsLocalization.lift_mk'_spec] simp) - letI f : (Generators.self R T).toExtension.Hom Q := + let f : (Generators.self R T).toExtension.Hom Q := { toRingHom := (MvPolynomial.aeval Q.σ).toRingHom toRingHom_algebraMap := (MvPolynomial.aeval Q.σ).commutes algebraMap_toRingHom := by diff --git a/Mathlib/RingTheory/Etale/StandardEtale.lean b/Mathlib/RingTheory/Etale/StandardEtale.lean index 64f44f09d4c17b..20862b46b49bb7 100644 --- a/Mathlib/RingTheory/Etale/StandardEtale.lean +++ b/Mathlib/RingTheory/Etale/StandardEtale.lean @@ -429,7 +429,7 @@ lemma IsStandardEtale.of_isLocalizationAway [IsStandardEtale R S] lemma IsStandardEtale.of_surjective [IsStandardEtale R S] [Algebra.Etale R T] (f : S →ₐ[R] T) (hf : Function.Surjective f) : IsStandardEtale R T := by - letI := f.toAlgebra + let := f.toAlgebra have : IsScalarTower R S T := .of_algebraMap_eq' f.comp_algebraMap.symm obtain ⟨e, he, hfe⟩ := (Ideal.isIdempotentElem_iff_of_fg _ (Algebra.FinitePresentation.ker_fG_of_surjective f hf)).mp diff --git a/Mathlib/RingTheory/Extension/Basic.lean b/Mathlib/RingTheory/Extension/Basic.lean index 949acefa98bf7c..46099df0ef9d58 100644 --- a/Mathlib/RingTheory/Extension/Basic.lean +++ b/Mathlib/RingTheory/Extension/Basic.lean @@ -135,7 +135,7 @@ def localization (P : Extension.{w} R S) : Extension R S' where (g := (algebraMap S S').comp (algebraMap P.Ring S)) (by simpa using fun x hx ↦ IsLocalization.map_units S' ⟨_, hx⟩)).toAlgebra isScalarTower := by - letI : Algebra (Localization (M.comap (algebraMap P.Ring S))) S' := + let : Algebra (Localization (M.comap (algebraMap P.Ring S))) S' := (IsLocalization.lift (M := (M.comap (algebraMap P.Ring S))) (g := (algebraMap S S').comp (algebraMap P.Ring S)) (by simpa using fun x hx ↦ IsLocalization.map_units S' ⟨_, hx⟩)).toAlgebra diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean index 0f6e4172bbc0d5..0faa990a267968 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean @@ -218,7 +218,7 @@ lemma Hom.sub_aux (f g : Hom P P') (x y) : (P'.σ ((algebraMap P.Ring S') x) * (f.toAlgHom y - g.toAlgHom y) + P'.σ ((algebraMap P.Ring S') y) * (f.toAlgHom x - g.toAlgHom x)) ∈ P'.ker ^ 2 := by - letI := ((algebraMap S S').comp (algebraMap P.Ring S)).toAlgebra + let := ((algebraMap S S').comp (algebraMap P.Ring S)).toAlgebra have : (f.toAlgHom x - P'.σ (algebraMap P.Ring S' x)) * (f.toAlgHom y - g.toAlgHom y) + (g.toAlgHom y - P'.σ (algebraMap P.Ring S' y)) * (f.toAlgHom x - g.toAlgHom x) diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index 5c03910ea8864e..7bb848e62593c1 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -659,7 +659,7 @@ lemma ker_ofAlgEquiv (P : Generators R S ι) {T : Type*} [CommRing T] [Algebra R lemma map_toComp_ker (Q : Generators S T ι') (P : Generators R S ι) : P.ker.map (Q.toComp P).toAlgHom = RingHom.ker (Q.ofComp P).toAlgHom := by - letI : DecidableEq (ι' →₀ ℕ) := Classical.decEq _ + let : DecidableEq (ι' →₀ ℕ) := Classical.decEq _ apply le_antisymm · rw [Ideal.map_le_iff_le_comap] rintro x (hx : algebraMap P.Ring S x = 0) diff --git a/Mathlib/RingTheory/FinitePresentation.lean b/Mathlib/RingTheory/FinitePresentation.lean index cc8c128a3d64b0..e649854b1930f2 100644 --- a/Mathlib/RingTheory/FinitePresentation.lean +++ b/Mathlib/RingTheory/FinitePresentation.lean @@ -132,7 +132,7 @@ theorem iff : · rintro ⟨n, f, hf⟩ exact ⟨n, RingHom.ker f.toRingHom, Ideal.quotientKerAlgEquivOfSurjective hf.1, hf.2⟩ · rintro ⟨n, I, e, hfg⟩ - letI := (FinitePresentation.mvPolynomial_aux R _).quotient hfg + let := (FinitePresentation.mvPolynomial_aux R _).quotient hfg exact equiv e /-- An algebra is finitely presented if and only if it is a quotient of a polynomial ring whose @@ -183,7 +183,7 @@ theorem trans [Algebra A B] [IsScalarTower R A B] [FinitePresentation R A] [FinitePresentation A B] : FinitePresentation R B := by have hfpB : FinitePresentation A B := inferInstance obtain ⟨n, I, e, hfg⟩ := iff.1 hfpB - letI : FinitePresentation R (MvPolynomial (Fin n) A ⧸ I) := + let : FinitePresentation R (MvPolynomial (Fin n) A ⧸ I) := (mvPolynomial_of_finitePresentation _).quotient hfg exact equiv (e.restrictScalars R) @@ -212,8 +212,8 @@ theorem of_restrict_scalars_finitePresentation [Algebra A B] [IsScalarTower R A FinitePresentation.{w₂, w₃} A B := by classical obtain ⟨n, f, hf, s, hs⟩ := FinitePresentation.out (R := R) (A := B) - letI RX := MvPolynomial (Fin n) R - letI AX := MvPolynomial (Fin n) A + let RX := MvPolynomial (Fin n) R + let AX := MvPolynomial (Fin n) A refine ⟨n, MvPolynomial.aeval (f ∘ X), ?_, ?_⟩ · rw [← AlgHom.range_eq_top, ← Algebra.adjoin_range_eq_range_aeval, Set.range_comp f MvPolynomial.X, eq_top_iff, ← @adjoin_adjoin_of_tower R A B, @@ -230,7 +230,7 @@ theorem of_restrict_scalars_finitePresentation [Algebra A B] [IsScalarTower R A apply Subalgebra.restrictScalars_injective R rw [← adjoin_restrictScalars, adjoin_range_X, Subalgebra.restrictScalars_top, Subalgebra.restrictScalars_top] - letI g : t → AX := fun x => MvPolynomial.C (x : A) - map (algebraMap R A) (t' x) + let g : t → AX := fun x => MvPolynomial.C (x : A) - map (algebraMap R A) (t' x) refine ⟨s.image (map (algebraMap R A)) ∪ t.attach.image g, ?_⟩ rw [Finset.coe_union, Finset.coe_image, Finset.coe_image, Finset.attach_eq_univ, Finset.coe_univ, Set.image_univ] @@ -475,7 +475,7 @@ lemma polynomial_induction P R S f → Q S T g → Q R T (g.comp f)) {R : Type u} {S : Type v} [CommRing R] [CommRing S] (f : R →+* S) (hf : f.FinitePresentation) : Q R S f := by - letI := f.toAlgebra + let := f.toAlgebra obtain ⟨n, g, hg, hg'⟩ := hf let g' := g.toRingHom change Surjective g' at hg diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index c31975d59b8c2f..346c6ccb601fa6 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -154,7 +154,7 @@ theorem iff_quotient_freeAlgebra' : FiniteType R A ↔ rintro ⟨s, f, hsur⟩ use { x : A // x ∈ s }, inferInstance, f · rintro ⟨ι, hfintype, f, hsur⟩ - letI : Fintype ι := hfintype + let : Fintype ι := hfintype exact .of_surjective f hsur /-- A commutative algebra is finitely generated if and only if it is a quotient @@ -166,7 +166,7 @@ theorem iff_quotient_mvPolynomial' : FiniteType R S ↔ rintro ⟨s, f, hsur⟩ use { x : S // x ∈ s }, inferInstance, f · rintro ⟨ι, hfintype, f, hsur⟩ - letI : Fintype ι := hfintype + let : Fintype ι := hfintype exact .of_surjective f hsur /-- A commutative algebra is finitely generated if and only if it is a quotient of a polynomial ring @@ -363,7 +363,7 @@ image generates, as algebra, `R[M]`. -/ theorem exists_finset_adjoin_eq_top [h : FiniteType R R[M]] : ∃ G : Finset M, Algebra.adjoin R (of' R M '' G) = ⊤ := by obtain ⟨S, hS⟩ := h - letI : DecidableEq M := Classical.decEq M + let : DecidableEq M := Classical.decEq M use Finset.biUnion S fun f => f.coeff.support have : S.biUnion (fun f => f.coeff.support) = ⋃ f ∈ S, (f.coeff.support : Set M) := by simp only [Finset.set_biUnion_coe, Finset.coe_biUnion] @@ -512,7 +512,7 @@ generates, as algebra, `R[M]`. -/ theorem exists_finset_adjoin_eq_top [h : FiniteType R R[M]] : ∃ G : Finset M, Algebra.adjoin R (of R M '' G) = ⊤ := by obtain ⟨S, hS⟩ := h - letI : DecidableEq M := Classical.decEq M + let : DecidableEq M := Classical.decEq M use Finset.biUnion S fun f => f.coeff.support have : S.biUnion (fun f => f.coeff.support) = ⋃ f ∈ S, (f.coeff.support : Set M) := by simp only [Finset.set_biUnion_coe, Finset.coe_biUnion] @@ -631,8 +631,8 @@ A shortcut instance `commRing_strongRankCondition` is also provided. instance (priority := 100) CommRing.orzechProperty (R : Type*) [CommRing R] : OrzechProperty R := by refine ⟨fun {M} _ _ _ {N} f hf ↦ ?_⟩ - letI := addCommMonoidToAddCommGroup R (M := M) - letI := addCommMonoidToAddCommGroup R (M := N) + let := addCommMonoidToAddCommGroup R (M := M) + let := addCommMonoidToAddCommGroup R (M := N) let i := N.subtype let hi : Function.Injective i := N.injective_subtype refine LinearMap.ker_eq_bot.1 <| LinearMap.ker_eq_bot'.2 fun n hn ↦ ?_ @@ -644,9 +644,9 @@ instance (priority := 100) CommRing.orzechProperty let A := Subring.closure (Set.range b ∪ Set.range c.uncurry) let N' := span A ({n} ∪ Set.range nj) let M' := span A (Set.range mj) - haveI : IsNoetherianRing A := is_noetherian_subring_closure _ + have : IsNoetherianRing A := is_noetherian_subring_closure _ (.union (Set.finite_range _) (Set.finite_range _)) - haveI : Module.Finite A M' := span_of_finite A (Set.finite_range _) + have : Module.Finite A M' := span_of_finite A (Set.finite_range _) refine congr($((LinearMap.ker_eq_bot'.1 <| LinearMap.ker_eq_bot.2 <| IsNoetherian.injective_of_surjective_of_injective ((i.restrictScalars A).restrict fun x hx ↦ ?_ : N' →ₗ[A] M') diff --git a/Mathlib/RingTheory/Finiteness/Basic.lean b/Mathlib/RingTheory/Finiteness/Basic.lean index 7cb4b5fed17525..33801af9098662 100644 --- a/Mathlib/RingTheory/Finiteness/Basic.lean +++ b/Mathlib/RingTheory/Finiteness/Basic.lean @@ -382,15 +382,15 @@ lemma of_equiv_equiv {A₁ B₁ A₂ B₂ : Type*} [CommSemiring A₁] [CommSemi (e₂ : B₁ ≃+* B₂) (he : RingHom.comp (algebraMap A₂ B₂) ↑e₁ = RingHom.comp ↑e₂ (algebraMap A₁ B₁)) [Module.Finite A₁ B₁] : Module.Finite A₂ B₂ := by - letI := e₁.toRingHom.toAlgebra - letI := ((algebraMap A₁ B₁).comp e₁.symm.toRingHom).toAlgebra - haveI : IsScalarTower A₁ A₂ B₁ := IsScalarTower.of_algebraMap_eq + let := e₁.toRingHom.toAlgebra + let := ((algebraMap A₁ B₁).comp e₁.symm.toRingHom).toAlgebra + have : IsScalarTower A₁ A₂ B₁ := IsScalarTower.of_algebraMap_eq (fun x ↦ by simp [RingHom.algebraMap_toAlgebra]) let e : B₁ ≃ₐ[A₂] B₂ := { e₂ with commutes' := fun r ↦ by simpa [RingHom.algebraMap_toAlgebra] using DFunLike.congr_fun he.symm (e₁.symm r) } - haveI := of_restrictScalars_finite A₁ A₂ B₁ + have := of_restrictScalars_finite A₁ A₂ B₁ exact equiv e.toLinearEquiv end Algebra diff --git a/Mathlib/RingTheory/Finiteness/FiniteTypeLocal.lean b/Mathlib/RingTheory/Finiteness/FiniteTypeLocal.lean index f41af9b621f778..d5d18975af94cc 100644 --- a/Mathlib/RingTheory/Finiteness/FiniteTypeLocal.lean +++ b/Mathlib/RingTheory/Finiteness/FiniteTypeLocal.lean @@ -138,7 +138,7 @@ lemma Algebra.FiniteType.of_span_eq_top_source (s : Set R) (hs : Ideal.span (s : obtain ⟨s, h₁, hs⟩ := (Ideal.span_eq_top_iff_finite s).mp hs replace h (i : s) := h i.val (h₁ i.property) classical - letI := fun r : s => (Localization.awayMap (algebraMap R S) r).toAlgebra + let := fun r : s => (Localization.awayMap (algebraMap R S) r).toAlgebra set f := algebraMap R S constructor replace H := fun r => (h r).1 diff --git a/Mathlib/RingTheory/Finiteness/Finsupp.lean b/Mathlib/RingTheory/Finiteness/Finsupp.lean index 5a453d26a34539..49ff8576b1177a 100644 --- a/Mathlib/RingTheory/Finiteness/Finsupp.lean +++ b/Mathlib/RingTheory/Finiteness/Finsupp.lean @@ -34,9 +34,9 @@ finitely generated then so is M. -/ theorem fg_of_fg_map_of_fg_inf_ker (f : M →ₗ[R] P) {s : Submodule R M} (hs1 : (s.map f).FG) (hs2 : (s ⊓ LinearMap.ker f).FG) : s.FG := by - haveI := Classical.decEq R - haveI := Classical.decEq M - haveI := Classical.decEq P + have := Classical.decEq R + have := Classical.decEq M + have := Classical.decEq P obtain ⟨t1, ht1⟩ := hs1 obtain ⟨t2, ht2⟩ := hs2 have : ∀ y ∈ t1, ∃ x ∈ s, f x = y := by @@ -80,7 +80,7 @@ theorem fg_of_fg_map_of_fg_inf_ker (f : M →ₗ[R] P) {s : Submodule R M} add_sub_cancel _ _⟩ · rw [← Set.image_id (g '' ↑t1), Finsupp.mem_span_image_iff_linearCombination] refine ⟨_, ?_, rfl⟩ - haveI : Inhabited P := ⟨0⟩ + have : Inhabited P := ⟨0⟩ rw [← Finsupp.lmapDomain_supported _ _ g, mem_map] refine ⟨l, hl1, ?_⟩ rfl diff --git a/Mathlib/RingTheory/Finiteness/Ideal.lean b/Mathlib/RingTheory/Finiteness/Ideal.lean index 55320f6c2a1488..d672469d49a5a8 100644 --- a/Mathlib/RingTheory/Finiteness/Ideal.lean +++ b/Mathlib/RingTheory/Finiteness/Ideal.lean @@ -35,10 +35,10 @@ theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : (g : S →+* A) (hf : (RingHom.ker f).FG) (hg : (RingHom.ker g).FG) (hsur : Function.Surjective f) : (RingHom.ker (g.comp f)).FG := by - letI : Algebra R S := RingHom.toAlgebra f - letI : Algebra R A := RingHom.toAlgebra (g.comp f) - letI : Algebra S A := RingHom.toAlgebra g - letI : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl + let : Algebra R S := RingHom.toAlgebra f + let : Algebra R A := RingHom.toAlgebra (g.comp f) + let : Algebra S A := RingHom.toAlgebra g + let : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl let f₁ := Algebra.linearMap R S let g₁ := (IsScalarTower.toAlgHom R S A).toLinearMap exact Submodule.fg_ker_comp f₁ g₁ hf diff --git a/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean b/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean index e4a319f6b9aa12..0403a963280364 100644 --- a/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean +++ b/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean @@ -82,7 +82,7 @@ lemma Module.FinitePresentation.of_finite_of_finitePresentation Module.FinitePresentation R S := by classical obtain ⟨R', _, _, _, _, _, f, hf⟩ := Module.Finite.exists_free_surjective R S - letI := f.toRingHom.toAlgebra + let := f.toRingHom.toAlgebra have : IsScalarTower R R' S := .of_algebraMap_eq' f.comp_algebraMap.symm have : Module.FinitePresentation R R' := Module.finitePresentation_of_projective R R' diff --git a/Mathlib/RingTheory/Flat/Basic.lean b/Mathlib/RingTheory/Flat/Basic.lean index 4a47d982cc92fc..b82c8eaaa79e71 100644 --- a/Mathlib/RingTheory/Flat/Basic.lean +++ b/Mathlib/RingTheory/Flat/Basic.lean @@ -233,7 +233,7 @@ instance of_free [Free R M] : Flat R M := inferInstance instance {S} [CommSemiring S] [Algebra R S] [Module S M] [IsScalarTower R S M] [Flat S M] [Flat R N] : Flat S (M ⊗[R] N) := iff_rTensor_injectiveₛ.mpr fun P _ _ I ↦ by - letI := RestrictScalars.moduleOrig R S P + let := RestrictScalars.moduleOrig R S P change Submodule S (RestrictScalars R S P) at I change Function.Injective (rTensor _ I.subtype) simpa [AlgebraTensorModule.rTensor_tensor] using! @@ -290,8 +290,8 @@ lemma iff_rTensor_preserves_injective_linearMap' [Small.{v'} R] : Flat R M ↔ (f : N →ₗ[R] N'), Function.Injective f → Function.Injective (f.rTensor M) := ⟨by introv _; apply rTensor_preserves_injective_linearMap, fun h ↦ iff_rTensor_preserves_injective_linearMapₛ.mpr fun P N _ _ _ _ ↦ by - letI := Module.addCommMonoidToAddCommGroup R (M := P) - letI := Module.addCommMonoidToAddCommGroup R (M := N) + let := Module.addCommMonoidToAddCommGroup R (M := P) + let := Module.addCommMonoidToAddCommGroup R (M := N) apply h⟩ /-- `M` is flat if and only if `f ⊗ 𝟙 M` is injective whenever `f` is an injective linear map. diff --git a/Mathlib/RingTheory/Flat/EquationalCriterion.lean b/Mathlib/RingTheory/Flat/EquationalCriterion.lean index d574fc160be643..8b72cfa8d36a6b 100644 --- a/Mathlib/RingTheory/Flat/EquationalCriterion.lean +++ b/Mathlib/RingTheory/Flat/EquationalCriterion.lean @@ -272,7 +272,7 @@ theorem exists_factorization_of_finitePresentation [Flat R M] {P : Type*} [AddCo [Module R P] [FinitePresentation R P] (h₁ : P →ₗ[R] M) : ∃ (k : ℕ) (h₂ : P →ₗ[R] (Fin k →₀ R)) (h₃ : (Fin k →₀ R) →ₗ[R] M), h₁ = h₃ ∘ₗ h₂ := by have ⟨_, K, ϕ, hK⟩ := FinitePresentation.exists_fin R P - haveI : Module.Finite R K := .of_fg hK + have : Module.Finite R K := .of_fg hK have : (h₁ ∘ₗ ϕ.symm ∘ₗ K.mkQ) ∘ₗ K.subtype = 0 := by simp_rw [comp_assoc, (LinearMap.exact_subtype_mkQ K).linearMap_comp_eq_zero, comp_zero] obtain ⟨k, a, y, hay, ha⟩ := exists_factorization_of_comp_eq_zero_of_free this diff --git a/Mathlib/RingTheory/Flat/FaithfullyFlat/Basic.lean b/Mathlib/RingTheory/Flat/FaithfullyFlat/Basic.lean index 6456743c4165d5..c2d6c3c609d283 100644 --- a/Mathlib/RingTheory/Flat/FaithfullyFlat/Basic.lean +++ b/Mathlib/RingTheory/Flat/FaithfullyFlat/Basic.lean @@ -127,7 +127,7 @@ lemma lTensor_reflects_triviality [FaithfullyFlat R M] (N : Type*) [AddCommGroup N] [Module R N] [Subsingleton (M ⊗[R] N)] : Subsingleton N := by - haveI : Subsingleton (N ⊗[R] M) := (TensorProduct.comm R N M).toEquiv.injective.subsingleton + have : Subsingleton (N ⊗[R] M) := (TensorProduct.comm R N M).toEquiv.injective.subsingleton apply rTensor_reflects_triviality R M attribute [-simp] Ideal.Quotient.mk_eq_mk in @@ -139,7 +139,7 @@ lemma iff_flat_and_rTensor_faithful : refine ⟨fun fl => ⟨inferInstance, rTensor_nontrivial R M⟩, fun ⟨flat, faithful⟩ => ⟨?_⟩⟩ intro m hm rid specialize faithful (ULift (R ⧸ m)) inferInstance - haveI : Nontrivial ((R ⧸ m) ⊗[R] M) := + have : Nontrivial ((R ⧸ m) ⊗[R] M) := (congr (ULift.moduleEquiv : ULift (R ⧸ m) ≃ₗ[R] R ⧸ m) (LinearEquiv.refl R M)).symm.toEquiv.nontrivial have := (quotTensorEquivQuotSMul M m).toEquiv.symm.nontrivial @@ -195,7 +195,7 @@ instance directSum {ι : Type*} [Nonempty ι] (M : ι → Type*) [∀ i, AddComm refine ⟨inferInstance, fun N _ _ hN ↦ ?_⟩ obtain ⟨i⟩ := ‹Nonempty ι› obtain ⟨x, y, hxy⟩ := Nontrivial.exists_pair_ne (α := M i ⊗[R] N) - haveI : Nontrivial (⨁ (i : ι), M i ⊗[R] N) := + have : Nontrivial (⨁ (i : ι), M i ⊗[R] N) := ⟨DirectSum.of _ i x, DirectSum.of _ i y, fun h ↦ hxy (DirectSum.of_injective i h)⟩ apply (TensorProduct.directSumLeft R R M N).toEquiv.nontrivial diff --git a/Mathlib/RingTheory/FormalGroup/Basic.lean b/Mathlib/RingTheory/FormalGroup/Basic.lean index 4c6d3bf0156cb7..a397d7a32fbbee 100644 --- a/Mathlib/RingTheory/FormalGroup/Basic.lean +++ b/Mathlib/RingTheory/FormalGroup/Basic.lean @@ -242,7 +242,7 @@ lemma Xzero_subst_Xzero : F.Xzero.subst F.Xzero = F.Xzero := by PowerSeries.HasSubst.X', PowerSeries.HasSubst] lemma Xzero_eq_X : F.Xzero = PowerSeries.X := by - haveI : Invertible (F.Xzero.coeff 1) := (coeff_one_Xzero F) ▸ invertibleOne + have : Invertible (F.Xzero.coeff 1) := (coeff_one_Xzero F) ▸ invertibleOne calc _ = F.Xzero.substInv.subst (F.Xzero.subst F.Xzero) := by have aux₀ : PowerSeries.HasSubst F.Xzero := @@ -292,7 +292,7 @@ lemma zeroX_subst_zeroX : F.zeroX.subst F.zeroX = F.zeroX := by PowerSeries.HasSubst.X', PowerSeries.HasSubst] lemma zeroX_eq_X : F.zeroX = PowerSeries.X := by - haveI : Invertible (F.zeroX.coeff 1) := (coeff_one_zeroX F) ▸ invertibleOne + have : Invertible (F.zeroX.coeff 1) := (coeff_one_zeroX F) ▸ invertibleOne calc _ = F.zeroX.substInv.subst (F.zeroX.subst F.zeroX) := by have aux₀ : PowerSeries.HasSubst F.zeroX := diff --git a/Mathlib/RingTheory/FreeCommRing.lean b/Mathlib/RingTheory/FreeCommRing.lean index d04ee6c24b36e5..3123cb440278fd 100644 --- a/Mathlib/RingTheory/FreeCommRing.lean +++ b/Mathlib/RingTheory/FreeCommRing.lean @@ -239,7 +239,7 @@ theorem isSupported_of {p} {s : Set α} : IsSupported (of p) s ↔ p ∈ s := suffices IsSupported (of p) s → p ∈ s from ⟨this, fun hps => Subring.subset_closure ⟨p, hps, rfl⟩⟩ fun hps : IsSupported (of p) s => by classical - haveI := Classical.decPred (· ∈ s) + have := Classical.decPred (· ∈ s) have : ∀ x, IsSupported x s → ∃ n : ℤ, lift (fun a => if a ∈ s then (0 : ℤ[X]) else Polynomial.X) x = n := by intro x hx diff --git a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean index 4658ca2c7240e3..30c4f373268c3d 100644 --- a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean +++ b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean @@ -883,7 +883,7 @@ variable {x : A} (hx : x = f * g) theorem Away.isLocalization_mul (hd : d ≠ 0) : letI := (awayMap 𝒜 hg hx).toAlgebra IsLocalization.Away (isLocalizationElem hf hg) (Away 𝒜 x) := by - letI := (awayMap 𝒜 hg hx).toAlgebra + let := (awayMap 𝒜 hg hx).toAlgebra constructor; constructor · rintro ⟨r, n, rfl⟩ rw [map_pow, RingHom.algebraMap_toAlgebra] diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 035bbf98a04d5b..910f8186cdf59c 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -967,7 +967,7 @@ variable [NonUnitalNonAssocSemiring R] instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where -- TODO: This proof is painful because `coeff_mul` isn't stated in terms of `Finsupp.sum`. mul_left_cancel_of_ne_zero {x} hx y z hyz := by - letI : AddCancelCommMonoid R := ⟨⟩ + let : AddCancelCommMonoid R := ⟨⟩ contrapose! hyz simp only [ne_eq, ← coeff_inj, funext_iff, not_forall] at ⊢ hyz have : Set.IsWF {a | y.coeff a ≠ z.coeff a} := @@ -989,7 +989,7 @@ instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where · simp +contextual [← and_or_left, ← or_and_right] · simp +contextual [← and_or_left, ← or_and_right] mul_right_cancel_of_ne_zero {x} hx y z hyz := by - letI : AddCancelCommMonoid R := ⟨⟩ + let : AddCancelCommMonoid R := ⟨⟩ contrapose! hyz simp only [ne_eq, ← coeff_inj, funext_iff, not_forall] at ⊢ hyz have : Set.IsWF {a | y.coeff a ≠ z.coeff a} := diff --git a/Mathlib/RingTheory/Henselian.lean b/Mathlib/RingTheory/Henselian.lean index 574b704be8d90f..a107dd2c746fa2 100644 --- a/Mathlib/RingTheory/Henselian.lean +++ b/Mathlib/RingTheory/Henselian.lean @@ -198,7 +198,7 @@ instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] exact (ih.eval f).trans h₁ have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by intro n - haveI := isLocalHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I) + have := isLocalHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I) apply IsUnit.of_map (Ideal.Quotient.mk I) convert! h₂ using 1 exact SModEq.def.mp ((hc_mod n).eval _) diff --git a/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean b/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean index 4643bb3748d6f5..abbeef599d2cc3 100644 --- a/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean +++ b/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean @@ -287,7 +287,7 @@ theorem associatedPrimes.eq_singleton_of_isPrimary [IsNoetherianRing R] (hI : I. rw [Set.mem_singleton_iff] refine ⟨IsAssociatedPrime.eq_radical hI, ?_⟩ rintro rfl - haveI : Nontrivial (R ⧸ I) := by + have : Nontrivial (R ⧸ I) := by refine ⟨(Ideal.Quotient.mk I :) 1, (Ideal.Quotient.mk I :) 0, ?_⟩ rw [Ne, Ideal.Quotient.eq, sub_zero, ← Ideal.eq_top_iff_one] exact hI.1 diff --git a/Mathlib/RingTheory/Ideal/GoingUp.lean b/Mathlib/RingTheory/Ideal/GoingUp.lean index 43581c4e048d63..9fde57b65168e9 100644 --- a/Mathlib/RingTheory/Ideal/GoingUp.lean +++ b/Mathlib/RingTheory/Ideal/GoingUp.lean @@ -204,7 +204,7 @@ theorem eq_bot_of_comap_eq_bot [Nontrivial R] [IsDomain S] [Algebra.IsIntegral R theorem isMaximal_comap_of_isIntegral_of_isMaximal [Algebra.IsIntegral R S] (I : Ideal S) [hI : I.IsMaximal] : IsMaximal (I.comap (algebraMap R S)) := by refine Ideal.Quotient.maximal_of_isField _ ?_ - haveI : IsPrime (I.comap (algebraMap R S)) := comap_isPrime _ _ + have : IsPrime (I.comap (algebraMap R S)) := comap_isPrime _ _ exact isField_of_isIntegral_of_isField algebraMap_quotient_injective (by rwa [← Quotient.maximal_ideal_iff_isField_quotient]) @@ -286,7 +286,7 @@ theorem exists_ideal_over_prime_of_isIntegral_of_isDomain [Algebra.IsIntegral R exact absurd (hP x0) hx let Rₚ := Localization P.primeCompl let Sₚ := Localization (Algebra.algebraMapSubmonoid S P.primeCompl) - letI : IsDomain (Localization (Algebra.algebraMapSubmonoid S P.primeCompl)) := + let : IsDomain (Localization (Algebra.algebraMapSubmonoid S P.primeCompl)) := IsLocalization.isDomain_localization (le_nonZeroDivisors_of_noZeroDivisors hP0) obtain ⟨Qₚ : Ideal Sₚ, Qₚ_maximal⟩ := exists_maximal Sₚ have : Algebra.IsIntegral Rₚ Sₚ := ⟨isIntegral_localization⟩ diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 62de906cb2c249..135e2a6ff1a219 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -1140,11 +1140,11 @@ theorem map_radical_of_surjective {f : R →+* S} (hf : Function.Surjective f) { ext j constructor · rintro ⟨hj, hj'⟩ - haveI : j.IsPrime := hj' + have : j.IsPrime := hj' exact ⟨comap f j, ⟨⟨map_le_iff_le_comap.1 hj, comap_isPrime f j⟩, map_comap_of_surjective f hf j⟩⟩ · rintro ⟨J, ⟨hJ, hJ'⟩⟩ - haveI : J.IsPrime := hJ.right + have : J.IsPrime := hJ.right exact ⟨hJ' ▸ map_mono hJ.left, hJ' ▸ map_isPrime_of_surjective hf (le_trans h hJ.left)⟩ end CommRing diff --git a/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean b/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean index a8f308649071e7..96a0b40221f664 100644 --- a/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean @@ -187,7 +187,7 @@ end PPrime theorem cardQuot_mul [IsDedekindDomain S] [Module.Free ℤ S] (I J : Ideal S) : cardQuot (I * J) = cardQuot I * cardQuot J := by let b := Module.Free.chooseBasis ℤ S - haveI : Infinite S := Infinite.of_surjective _ b.repr.toEquiv.surjective + have : Infinite S := Infinite.of_surjective _ b.repr.toEquiv.surjective exact UniqueFactorizationMonoid.multiplicative_of_coprime cardQuot I J (cardQuot_bot _ _) (fun {I J} hI => by simp [Ideal.isUnit_iff.mp hI, Ideal.mul_top]) (fun {I} i hI => @@ -371,7 +371,7 @@ lemma exists_prime_and_absNorm_eq_pow (P : Ideal S) [P.IsMaximal] : (Ideal.finrank_eq_finrank (Module.Free.chooseBasis _ _) _ (Ideal.IsMaximal.ne_bot_of_isIntegral_int P)) cases nonempty_fintype (S ⧸ P) - letI := Ideal.Quotient.field P + let := Ideal.Quotient.field P obtain ⟨p, hpR⟩ := CharP.exists (S ⧸ P) obtain ⟨n, hp, e⟩ := FiniteField.card (S ⧸ P) p have hP : P.absNorm = p ^ (n : ℕ) := (Nat.card_eq_fintype_card.trans e:) diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 52f18f9b67028c..002be48d581530 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -181,7 +181,7 @@ theorem mem_ideal_smul_span_iff_exists_sum {ι : Type*} (f : ι → M) (x : M) : refine fun hx => span_induction ?_ ?_ ?_ ?_ (mem_smul_span.mp hx) · rintro x ⟨y, hy, x, ⟨i, rfl⟩, rfl⟩ refine ⟨Finsupp.single i y, fun j => ?_, ?_⟩ - · letI := Classical.decEq ι + · let := Classical.decEq ι rw [Finsupp.single_apply] split_ifs · assumption diff --git a/Mathlib/RingTheory/Ideal/Prod.lean b/Mathlib/RingTheory/Ideal/Prod.lean index 2f9f38b8b60868..afa0e0c1703ebb 100644 --- a/Mathlib/RingTheory/Ideal/Prod.lean +++ b/Mathlib/RingTheory/Ideal/Prod.lean @@ -172,7 +172,7 @@ theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Id mem_or_mem' {x y} := by simpa using h.mem_or_mem theorem isPrime_ideal_prod_top' {I : Ideal S} [h : I.IsPrime] : (prod (⊤ : Ideal R) I).IsPrime := by - letI : IsPrime (prod I (⊤ : Ideal R)) := isPrime_ideal_prod_top + let : IsPrime (prod I (⊤ : Ideal R)) := isPrime_ideal_prod_top rw [← map_prodComm_prod] -- Note: couldn't synthesize the right instances without the `R` and `S` hints exact map_isPrime_of_equiv (RingEquiv.prodComm (R := S) (S := R)) diff --git a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean index cd2056327ea71e..8b928643d7d8e6 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean @@ -93,10 +93,10 @@ instance isDomain [hI : I.IsPrime] : IsDomain (R ⧸ I) := theorem isDomain_iff_prime : IsDomain (R ⧸ I) ↔ I.IsPrime := by refine ⟨fun H => ⟨zero_ne_one_iff.1 ?_, fun {x y} h => ?_⟩, fun h => inferInstance⟩ - · haveI : Nontrivial (R ⧸ I) := ⟨H.2.1⟩ + · have : Nontrivial (R ⧸ I) := ⟨H.2.1⟩ exact zero_ne_one · simp only [← eq_zero_iff_mem, (mk I).map_mul] at h ⊢ - haveI := @IsDomain.to_noZeroDivisors (R ⧸ I) _ H + have := @IsDomain.to_noZeroDivisors (R ⧸ I) _ H exact eq_zero_or_eq_zero_of_mul_eq_zero h set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/RingTheory/Ideal/Quotient/Nilpotent.lean b/Mathlib/RingTheory/Ideal/Quotient/Nilpotent.lean index 1776fae04849ee..103265071af86a 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Nilpotent.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Nilpotent.lean @@ -37,7 +37,7 @@ theorem Ideal.IsNilpotent.induction_on (hI : IsNilpotent I) rw [← Ideal.zero_eq_bot, zero_pow two_ne_zero] rcases n with - | n · rw [pow_zero, Ideal.one_eq_top] at hI - haveI := subsingleton_of_bot_eq_top hI.symm + have := subsingleton_of_bot_eq_top hI.symm exact (hI' (Subsingleton.elim _ _)).elim rcases n with - | n · rw [pow_one] at hI diff --git a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean index 49867700683d63..b96f1f0e99050a 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean @@ -175,7 +175,7 @@ theorem bot_quotient_isMaximal_iff (I : Ideal R) [I.IsTwoSided] : mk_ker (I := I) ▸ comap_isMaximal_of_surjective (Quotient.mk I) Quotient.mk_surjective (K := ⊥) (H := hI), fun hI => by - letI := Quotient.divisionRing I + let := Quotient.divisionRing I exact bot_isMaximal⟩ /-- See also `Ideal.mem_quotient_iff_mem` in case `I ≤ J`. -/ diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean index 2d92eb83d2fc27..0ec0236f41a634 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean @@ -118,7 +118,7 @@ theorem isIntegral_of_smul_mem_submodule [IsDomain A] {M : Type*} [AddCommGroup exact Subtype.ext ((smul_eq_zero_iff_left ha₂).1 this) change IsIntegral R (A'.val ⟨x, hx⟩) rw [isIntegral_algHom_iff A'.val Subtype.val_injective, ← isIntegral_algHom_iff f this] - haveI : Module.Finite R N := by rwa [Module.Finite.iff_fg] + have : Module.Finite R N := by rwa [Module.Finite.iff_fg] apply Algebra.IsIntegral.isIntegral variable {f} @@ -134,7 +134,7 @@ variable (f) theorem RingHom.IsIntegralElem.of_mem_closure {x y z : S} (hx : f.IsIntegralElem x) (hy : f.IsIntegralElem y) (hz : z ∈ Subring.closure ({x, y} : Set S)) : f.IsIntegralElem z := by - letI : Algebra R S := f.toAlgebra + let : Algebra R S := f.toAlgebra have := (IsIntegral.fg_adjoin_singleton hx).mul (IsIntegral.fg_adjoin_singleton hy) rw [← Algebra.adjoin_union_coe_submodule, Set.singleton_union] at this exact diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean index 554bb37bc74460..c7983e5e6eb587 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean @@ -75,7 +75,7 @@ lemma exists_monic_aeval_eq_zero_forall_mem_pow_of_mem_map [Algebra.IsIntegral R ∃ p : R[X], p.Monic ∧ aeval x p = 0 ∧ ∀ i, p.coeff i ∈ I ^ (p.natDegree - i) := by classical let A : Subalgebra R R[X] := Algebra.adjoin R { C r * X | r ∈ I } - letI := Polynomial.algebra R S + let := Polynomial.algebra R S refine exists_monic_aeval_eq_zero_forall_mem_pow_of_isIntegral ?_ induction hx using Submodule.span_induction with | zero => simp [isIntegral_zero] diff --git a/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean b/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean index a5c4644937b610..fbf6632c550b9b 100644 --- a/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean +++ b/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean @@ -272,15 +272,15 @@ variable {A B} lemma Algebra.algebraMap_intTrace (x : B) : algebraMap A K (Algebra.intTrace A B x) = Algebra.trace K L (algebraMap B L x) := by - haveI : IsIntegralClosure B A (FractionRing B) := + have : IsIntegralClosure B A (FractionRing B) := IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. - haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := + have : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := isAlgebraic_of_isFractionRing A B .. - haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := + have : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ - haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ - haveI := IsIntegralClosure.isFractionRing_of_finite_extension A K L B + have : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ + have := IsIntegralClosure.isFractionRing_of_finite_extension A K L B apply (FractionRing.algEquiv A K).symm.injective rw [AlgEquiv.commutes, Algebra.intTrace, Algebra.map_intTraceAux, ← AlgEquiv.commutes (FractionRing.algEquiv B L)] @@ -292,26 +292,26 @@ lemma Algebra.algebraMap_intTrace (x : B) : lemma Algebra.algebraMap_intTrace_fractionRing (x : B) : algebraMap A (FractionRing A) (Algebra.intTrace A B x) = Algebra.trace (FractionRing A) (FractionRing B) (algebraMap B _ x) := by - haveI : IsIntegralClosure B A (FractionRing B) := + have : IsIntegralClosure B A (FractionRing B) := IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. - haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := + have : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := isAlgebraic_of_isFractionRing A B .. - haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := + have : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ - haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ + have : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ exact Algebra.map_intTraceAux x variable (A B) lemma Algebra.intTrace_eq_trace [Module.Free A B] : Algebra.intTrace A B = Algebra.trace A B := by ext x - haveI : IsIntegralClosure B A (FractionRing B) := + have : IsIntegralClosure B A (FractionRing B) := IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. - haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := + have : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := isAlgebraic_of_isFractionRing A B .. - haveI : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := + have : IsLocalization (algebraMapSubmonoid B A⁰) (FractionRing B) := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ apply IsFractionRing.injective A (FractionRing A) rw [Algebra.algebraMap_intTrace_fractionRing, Algebra.trace_localization A A⁰] @@ -333,22 +333,22 @@ lemma Algebra.intTrace_eq_of_isLocalization have : IsIntegralClosure B A L := IsIntegralClosure.of_isIntegrallyClosed _ _ _ -- TODO: How is this even supposed to fire? `R` and `S` cannot be inferred. - haveI : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := + have : Algebra.IsAlgebraic (FractionRing A) (FractionRing B) := isAlgebraic_of_isFractionRing A B .. have : IsLocalization (algebraMapSubmonoid B A⁰) L := IsIntegralClosure.isLocalization _ (FractionRing A) _ _ let f : Aₘ →+* K := IsLocalization.map _ (T := A⁰) (RingHom.id A) hM - letI := f.toAlgebra + let := f.toAlgebra have : IsScalarTower A Aₘ K := IsScalarTower.of_algebraMap_eq' (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, RingHomCompTriple.comp_eq]) - letI := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization M Aₘ K + let := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization M Aₘ K let g : Bₘ →+* L := IsLocalization.map _ (M := algebraMapSubmonoid B M) (T := algebraMapSubmonoid B A⁰) (RingHom.id B) (Submonoid.monotone_map hM) - letI := g.toAlgebra + let := g.toAlgebra have : IsScalarTower B Bₘ L := IsScalarTower.of_algebraMap_eq' (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, RingHomCompTriple.comp_eq]) - letI := ((algebraMap K L).comp f).toAlgebra + let := ((algebraMap K L).comp f).toAlgebra have : IsScalarTower Aₘ K L := IsScalarTower.of_algebraMap_eq' rfl have : IsScalarTower Aₘ Bₘ L := by apply IsScalarTower.of_algebraMap_eq' @@ -357,7 +357,7 @@ lemma Algebra.intTrace_eq_of_isLocalization RingHom.comp_assoc, ← IsScalarTower.algebraMap_eq, IsScalarTower.algebraMap_eq A B Bₘ, IsLocalization.map_comp, RingHom.comp_id, ← RingHom.comp_assoc, IsLocalization.map_comp, RingHom.comp_id, ← IsScalarTower.algebraMap_eq, ← IsScalarTower.algebraMap_eq] - letI := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization + let := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization (algebraMapSubmonoid B M) Bₘ L have : FiniteDimensional K L := .of_isLocalization A B A⁰ have : IsIntegralClosure Bₘ Aₘ L := @@ -404,7 +404,7 @@ variable {A B} lemma Algebra.algebraMap_intNorm (x : B) : algebraMap A K (Algebra.intNorm A B x) = Algebra.norm K (algebraMap B L x) := by - haveI := IsIntegralClosure.isFractionRing_of_finite_extension A K L B + have := IsIntegralClosure.isFractionRing_of_finite_extension A K L B apply (FractionRing.algEquiv A K).symm.injective rw [AlgEquiv.commutes, Algebra.intNorm, Algebra.map_intNormAux, ← AlgEquiv.commutes (FractionRing.algEquiv B L)] @@ -432,7 +432,7 @@ theorem Algebra.intNorm_intNorm {C : Type*} [CommRing C] [IsDomain C] [IsIntegra lemma Algebra.intNorm_eq_norm [Module.Free A B] [Module.Finite A B] : Algebra.intNorm A B = Algebra.norm A := by ext x - haveI : IsIntegralClosure B A (FractionRing B) := + have : IsIntegralClosure B A (FractionRing B) := IsIntegralClosure.of_isIntegrallyClosed _ _ _ apply IsFractionRing.injective A (FractionRing A) rw [Algebra.algebraMap_intNorm_fractionRing, Algebra.norm_localization A A⁰] @@ -440,7 +440,7 @@ lemma Algebra.intNorm_eq_norm [Module.Free A B] [Module.Finite A B] : @[simp] lemma Algebra.intNorm_zero [FiniteDimensional (FractionRing A) (FractionRing B)] : Algebra.intNorm A B 0 = 0 := by - haveI : IsIntegralClosure B A (FractionRing B) := + have : IsIntegralClosure B A (FractionRing B) := IsIntegralClosure.of_isIntegrallyClosed _ _ _ apply IsFractionRing.injective A (FractionRing A) simp @@ -482,17 +482,17 @@ lemma Algebra.intNorm_eq_of_isLocalization [FiniteDimensional (FractionRing A) ( let K := FractionRing A let L := FractionRing B let f : Aₘ →+* K := IsLocalization.map _ (T := A⁰) (RingHom.id A) hM - letI := f.toAlgebra + let := f.toAlgebra have : IsScalarTower A Aₘ K := IsScalarTower.of_algebraMap_eq' (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, RingHomCompTriple.comp_eq]) - letI := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization M Aₘ K + let := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization M Aₘ K let g : Bₘ →+* L := IsLocalization.map _ (M := algebraMapSubmonoid B M) (T := algebraMapSubmonoid B A⁰) (RingHom.id B) (Submonoid.monotone_map hM) - letI := g.toAlgebra + let := g.toAlgebra have : IsScalarTower B Bₘ L := IsScalarTower.of_algebraMap_eq' (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, RingHomCompTriple.comp_eq]) - letI := ((algebraMap K L).comp f).toAlgebra + let := ((algebraMap K L).comp f).toAlgebra have : IsScalarTower Aₘ K L := IsScalarTower.of_algebraMap_eq' rfl have : IsScalarTower Aₘ Bₘ L := by apply IsScalarTower.of_algebraMap_eq' @@ -501,7 +501,7 @@ lemma Algebra.intNorm_eq_of_isLocalization [FiniteDimensional (FractionRing A) ( RingHom.comp_assoc, ← IsScalarTower.algebraMap_eq, IsScalarTower.algebraMap_eq A B Bₘ, IsLocalization.map_comp, RingHom.comp_id, ← RingHom.comp_assoc, IsLocalization.map_comp, RingHom.comp_id, ← IsScalarTower.algebraMap_eq, ← IsScalarTower.algebraMap_eq] - letI := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization + let := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization (algebraMapSubmonoid B M) Bₘ L have : IsIntegralClosure Bₘ Aₘ L := IsIntegralClosure.of_isIntegrallyClosed _ _ _ @@ -516,7 +516,7 @@ variable [IsDomain A] [IsIntegrallyClosed A] [IsDomain B] [IsIntegrallyClosed B] lemma Algebra.algebraMap_intNorm_of_isGalois [IsGalois (FractionRing A) (FractionRing B)] {x : B} : algebraMap A B (Algebra.intNorm A B x) = ∏ σ : B ≃ₐ[A] B, σ x := by - haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ + have : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ rw [← (galRestrict A (FractionRing A) (FractionRing B) B).toEquiv.prod_comp] simp only [MulEquiv.toEquiv_eq_coe, EquivLike.coe_coe] convert! (prod_galRestrict_eq_norm A (FractionRing A) (FractionRing B) B x).symm @@ -524,7 +524,7 @@ lemma Algebra.algebraMap_intNorm_of_isGalois [IsGalois (FractionRing A) (Fractio open Polynomial IsScalarTower in theorem Algebra.dvd_algebraMap_intNorm_self (x : B) : x ∣ algebraMap A B (intNorm A B x) := by classical - haveI : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ + have : FiniteDimensional (FractionRing A) (FractionRing B) := .of_isLocalization A B A⁰ by_cases hx : x = 0 · exact ⟨1, by simp [hx]⟩ let K := FractionRing A diff --git a/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean b/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean index 1d3a91951ec546..1175bf4626029c 100644 --- a/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean +++ b/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean @@ -379,7 +379,7 @@ lemma isIntegrallyClosed_of_isLocalization [IsIntegrallyClosed R] [IsDomain R] ( (hM : M ≤ R⁰) [IsLocalization M S] : IsIntegrallyClosed S := by let K := FractionRing R let g : S →+* K := IsLocalization.map _ (T := R⁰) (RingHom.id R) hM - letI := g.toAlgebra + let := g.toAlgebra have : IsScalarTower R S K := IsScalarTower.of_algebraMap_eq' (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, RingHomCompTriple.comp_eq]) have := IsFractionRing.isFractionRing_of_isDomain_of_isLocalization M S K diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean index 19edd42a3f3ac5..ebfa202d4bf401 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean @@ -170,15 +170,15 @@ theorem RingEquiv.isIntegral_iff {R S T : Type*} [CommRing R] [Ring S] [CommRing (h : (algebraMap T S).comp φ.toRingHom = algebraMap R S) (a : S) : IsIntegral R a ↔ IsIntegral T a := by constructor <;> intro ha - · letI : Algebra R T := φ.toRingHom.toAlgebra - letI : IsScalarTower R T S := + · let : Algebra R T := φ.toRingHom.toAlgebra + let : IsScalarTower R T S := ⟨fun r t s ↦ by simp only [Algebra.smul_def, map_mul, ← h, mul_assoc]; rfl⟩ exact IsIntegral.tower_top ha · have h' : (algebraMap T S) = (algebraMap R S).comp φ.symm.toRingHom := by have : RingHomInvPair (φ : R →+* T) φ.symm := RingHomInvPair.of_ringEquiv _ simp only [← h, RingHom.comp_assoc, RingEquiv.toRingHom_eq_coe, RingHomCompTriple.comp_eq] - letI : Algebra T R := φ.symm.toRingHom.toAlgebra - letI : IsScalarTower T R S := + let : Algebra T R := φ.symm.toRingHom.toAlgebra + let : IsScalarTower T R S := ⟨fun r t s ↦ by simp only [Algebra.smul_def, map_mul, h', mul_assoc]; rfl⟩ exact IsIntegral.tower_top ha diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean index 865dc6869a9008..4321faad608df6 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean @@ -46,7 +46,7 @@ theorem isField_of_isIntegral_of_isField' [CommRing R] [CommRing S] [IsDomain S] exists_pair_ne := ⟨0, 1, zero_ne_one⟩ mul_comm := mul_comm mul_inv_cancel {x} hx := by - letI := hR.toField + let := hR.toField obtain ⟨y, rfl⟩ := (Algebra.IsIntegral.isIntegral (R := R) x).isUnit hx exact ⟨y.inv, y.val_inv⟩ @@ -492,7 +492,7 @@ theorem isIntegral_trans [Algebra.IsIntegral R A] (x : B) (hx : IsIntegral A x) refine .of_mem_of_fg ((S[x]).restrictScalars R) ?_ _ ((Subalgebra.mem_restrictScalars R).mpr <| subset_adjoin rfl) rw [← Module.Finite.iff_fg] - letI : SMul S Sx := { MSx with } -- need this even though MSx is there + let : SMul S Sx := { MSx with } -- need this even though MSx is there have : IsScalarTower R S Sx := Submodule.isScalarTower Sx -- Lean looks for `Module A Sx` without this exact Module.Finite.trans S Sx diff --git a/Mathlib/RingTheory/IntegralDomain.lean b/Mathlib/RingTheory/IntegralDomain.lean index 952c02b282160e..4e328a55a6da5d 100644 --- a/Mathlib/RingTheory/IntegralDomain.lean +++ b/Mathlib/RingTheory/IntegralDomain.lean @@ -120,7 +120,7 @@ variable [CommRing R] [IsDomain R] [Group G] theorem card_nthRoots_subgroup_units [Fintype G] [DecidableEq G] (f : G →* R) (hf : Injective f) {n : ℕ} (hn : 0 < n) (g₀ : G) : #{g | g ^ n = g₀} ≤ Multiset.card (nthRoots n (f g₀)) := by - haveI : DecidableEq R := Classical.decEq _ + have : DecidableEq R := Classical.decEq _ calc _ ≤ #(nthRoots n (f g₀)).toFinset := card_le_card_of_injOn f (by aesop (add safe unfold Set.MapsTo)) hf.injOn diff --git a/Mathlib/RingTheory/Invariant/Basic.lean b/Mathlib/RingTheory/Invariant/Basic.lean index e06ded1554491a..0021fbed57dec6 100644 --- a/Mathlib/RingTheory/Invariant/Basic.lean +++ b/Mathlib/RingTheory/Invariant/Basic.lean @@ -425,9 +425,9 @@ lemma Ideal.Quotient.exists_algHom_fixedPoint_quotient_under cases nonempty_fintype G algebraize [(algebraMap (A ⧸ P) k).comp (algebraMap A (A ⧸ P)), (algebraMap (B ⧸ Q) k).comp (algebraMap B (B ⧸ Q))] - haveI : IsScalarTower A (B ⧸ Q) k := .of_algebraMap_eq fun x ↦ + have : IsScalarTower A (B ⧸ Q) k := .of_algebraMap_eq fun x ↦ (IsScalarTower.algebraMap_apply (A ⧸ P) (B ⧸ Q) k (mk P x)) - haveI : IsScalarTower A B k := .of_algebraMap_eq fun x ↦ + have : IsScalarTower A B k := .of_algebraMap_eq fun x ↦ (IsScalarTower.algebraMap_apply (A ⧸ P) (B ⧸ Q) k (mk P x)) obtain ⟨P, hp⟩ := Algebra.IsInvariant.charpoly_mem_lifts A B G x have : Polynomial.aeval x P = 0 := by diff --git a/Mathlib/RingTheory/Invariant/Galois.lean b/Mathlib/RingTheory/Invariant/Galois.lean index c86f93056fb6d5..d72831064475ce 100644 --- a/Mathlib/RingTheory/Invariant/Galois.lean +++ b/Mathlib/RingTheory/Invariant/Galois.lean @@ -46,7 +46,7 @@ theorem Algebra.isInvariant_of_isGalois [FiniteDimensional K L] [h : IsGalois K letI := IsIntegralClosure.MulSemiringAction A K L B Algebra.IsInvariant A B Gal(L/K) := by replace h := ((IsGalois.tfae (F := K) (E := L)).out 0 1).mp h - letI := IsIntegralClosure.MulSemiringAction A K L B + let := IsIntegralClosure.MulSemiringAction A K L B refine ⟨fun b hb ↦ ?_⟩ replace hb : algebraMap B L b ∈ IntermediateField.fixedField (⊤ : Subgroup Gal(L/K)) := by rintro ⟨g, -⟩ diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index bd60b3fdb3bbeb..a01b7253707b93 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -540,8 +540,8 @@ theorem IsBaseChange.comp {f : M →ₗ[R] N} (hf : IsBaseChange S f) {g : N → (hg : IsBaseChange T g) : IsBaseChange T ((g.restrictScalars R).comp f) := by apply IsBaseChange.of_lift_unique intro Q _ _ _ _ i - letI := Module.compHom Q (algebraMap S T) - haveI : IsScalarTower S T Q := + let := Module.compHom Q (algebraMap S T) + have : IsScalarTower S T Q := ⟨fun x y z => by rw [Algebra.smul_def, mul_smul] rfl⟩ @@ -563,9 +563,9 @@ lemma IsBaseChange.of_comp {f : M →ₗ[R] N} (hf : IsBaseChange S f) {h : N IsBaseChange T h := by apply IsBaseChange.of_lift_unique intro Q _ _ _ _ r - letI : Module R Q := .restrictScalars R S Q - haveI : IsScalarTower R S Q := .restrictScalars R S Q - haveI : IsScalarTower R T Q := IsScalarTower.of_algebraMap_smul fun r x ↦ by + let : Module R Q := .restrictScalars R S Q + have : IsScalarTower R S Q := .restrictScalars R S Q + have : IsScalarTower R T Q := IsScalarTower.of_algebraMap_smul fun r x ↦ by simp [IsScalarTower.algebraMap_apply R S T] let r' : M →ₗ[R] Q := r ∘ₗ f let q : O →ₗ[T] Q := hc.lift r' @@ -760,7 +760,7 @@ lemma Algebra.IsPushout.comp_iff {T' : Type*} [CommSemiring T'] [Algebra R T'] [Algebra.IsPushout R S R' S'] : Algebra.IsPushout R T R' T' ↔ Algebra.IsPushout S T S' T' := by let f : R' →ₗ[R] S' := (IsScalarTower.toAlgHom R R' S').toLinearMap - haveI : IsScalarTower R S T' := .of_algebraMap_eq fun x ↦ by + have : IsScalarTower R S T' := .of_algebraMap_eq fun x ↦ by rw [algebraMap_apply R S' T', algebraMap_apply R S S', ← algebraMap_apply S S' T'] have heq : (toAlgHom S S' T').toLinearMap.restrictScalars R ∘ₗ f = (toAlgHom R R' T').toLinearMap := by diff --git a/Mathlib/RingTheory/Jacobson/Ideal.lean b/Mathlib/RingTheory/Jacobson/Ideal.lean index 0004ab71fe433a..dcda2cf703aa6d 100644 --- a/Mathlib/RingTheory/Jacobson/Ideal.lean +++ b/Mathlib/RingTheory/Jacobson/Ideal.lean @@ -185,7 +185,7 @@ theorem map_jacobson_of_surjective {f : R →+* S} (hf : Function.Surjective f) · refine sInf_le_sInf fun J hJ => ⟨comap f J, ⟨⟨le_comap_of_map_le hJ.1, ?_⟩, map_comap_of_surjective f hf J⟩⟩ - haveI : J.IsMaximal := hJ.right + have : J.IsMaximal := hJ.right exact comap_isMaximal_of_surjective f hf · refine sInf_le_sInf_of_subset_insert_top fun j hj => hj.recOn fun J hJ => ?_ rw [← hJ.2] @@ -218,7 +218,7 @@ theorem comap_jacobson_of_surjective {f : R →+* S} (hf : Function.Surjective f this⟩ · simp_rw [comap_sInf, le_iInf_iff] intro J hJ - haveI : J.IsMaximal := hJ.right + have : J.IsMaximal := hJ.right exact sInf_le ⟨comap_mono hJ.left, comap_isMaximal_of_surjective _ hf⟩ @[gcongr, mono] diff --git a/Mathlib/RingTheory/Jacobson/Polynomial.lean b/Mathlib/RingTheory/Jacobson/Polynomial.lean index 316e2f8f031888..f41906e35fedef 100644 --- a/Mathlib/RingTheory/Jacobson/Polynomial.lean +++ b/Mathlib/RingTheory/Jacobson/Polynomial.lean @@ -25,7 +25,7 @@ variable {R : Type*} [CommRing R] theorem jacobson_bot_polynomial_le_sInf_map_maximal : jacobson (⊥ : Ideal R[X]) ≤ sInf (map (C : R →+* R[X]) '' { J : Ideal R | J.IsMaximal }) := by refine le_sInf fun J => exists_imp.2 fun j hj => ?_ - haveI : j.IsMaximal := hj.1 + have : j.IsMaximal := hj.1 refine Trans.trans (jacobson_mono bot_le) (le_of_eq ?_ : J.jacobson ≤ J) suffices t : (⊥ : Ideal (Polynomial (R ⧸ j))).jacobson = ⊥ by rw [← hj.2, jacobson_eq_iff_jacobson_quotient_eq_bot] diff --git a/Mathlib/RingTheory/Jacobson/Ring.lean b/Mathlib/RingTheory/Jacobson/Ring.lean index 19f44282274054..7ac3933093829f 100644 --- a/Mathlib/RingTheory/Jacobson/Ring.lean +++ b/Mathlib/RingTheory/Jacobson/Ring.lean @@ -329,7 +329,7 @@ theorem jacobson_bot_of_integral_localization (⊥ : Ideal S).jacobson = (⊥ : Ideal S) := by have hM : ((Submonoid.powers x).map φ : Submonoid S) ≤ nonZeroDivisors S := map_le_nonZeroDivisors_of_injective φ hφ (powers_le_nonZeroDivisors_of_noZeroDivisors hx) - letI : IsDomain Sₘ := IsLocalization.isDomain_of_le_nonZeroDivisors _ hM + let : IsDomain Sₘ := IsLocalization.isDomain_of_le_nonZeroDivisors _ hM let φ' : Rₘ →+* Sₘ := IsLocalization.map _ φ (Submonoid.powers x).le_comap_map suffices ∀ I : Ideal Sₘ, I.IsMaximal → (I.comap (algebraMap S Sₘ)).IsMaximal by have hϕ' : comap (algebraMap S Sₘ) (⊥ : Ideal Sₘ) = (⊥ : Ideal S) := by @@ -703,7 +703,7 @@ theorem finite_of_algHom_finiteType_of_isJacobsonRing [Algebra.FiniteType K A] (f : L →ₐ[K] A) : Module.Finite K L := by obtain ⟨m, hm⟩ := Ideal.exists_maximal A - letI := Ideal.Quotient.field m + let := Ideal.Quotient.field m have := finite_of_finite_type_of_isJacobsonRing K (A ⧸ m) exact Module.Finite.of_injective ((Ideal.Quotient.mkₐ K m).comp f).toLinearMap (RingHom.injective _) diff --git a/Mathlib/RingTheory/Kaehler/Basic.lean b/Mathlib/RingTheory/Kaehler/Basic.lean index c1c64b7ac4ba81..7ea020e7aa01b1 100644 --- a/Mathlib/RingTheory/Kaehler/Basic.lean +++ b/Mathlib/RingTheory/Kaehler/Basic.lean @@ -504,7 +504,7 @@ theorem KaehlerDifferential.kerTotal_mkQ_single_algebraMap_one (x) : (x𝖣1) = rw [← (algebraMap R S).map_one, KaehlerDifferential.kerTotal_mkQ_single_algebraMap] theorem KaehlerDifferential.kerTotal_mkQ_single_smul (r : R) (x y) : (y𝖣r • x) = r • y𝖣x := by - letI : SMulZeroClass R S := inferInstance + let : SMulZeroClass R S := inferInstance rw [Algebra.smul_def, KaehlerDifferential.kerTotal_mkQ_single_mul, KaehlerDifferential.kerTotal_mkQ_single_algebraMap, add_zero, ← LinearMap.map_smul_of_tower, Finsupp.smul_single, mul_comm, Algebra.smul_def] diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index b0793212737291..58f83e3c6511f7 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -267,7 +267,7 @@ variable {Q} {Q'} in lemma δAux_toAlgHom (f : Hom Q Q') (x) : δAux R Q' (f.toAlgHom x) = δAux R Q x + Finsupp.linearCombination _ (δAux R Q' ∘ f.val) (Q.cotangentSpaceBasis.repr ((1 : T) ⊗ₜ[Q.Ring] D S Q.Ring x :)) := by - letI : AddCommGroup (T ⊗[S] Ω[S⁄R]) := inferInstance + let : AddCommGroup (T ⊗[S] Ω[S⁄R]) := inferInstance have : IsScalarTower Q.Ring Q.Ring T := IsScalarTower.left _ induction x using MvPolynomial.induction_on with | C s => simp [MvPolynomial.algebraMap_eq, δAux_C] @@ -289,7 +289,7 @@ lemma δAux_ofComp (x : (Q.comp P).Ring) : δAux R Q ((Q.ofComp P).toAlgHom x) = P.toExtension.toKaehler.baseChange T (CotangentSpace.compEquiv Q P (1 ⊗ₜ[(Q.comp P).Ring] (D R (Q.comp P).Ring) x : _)).2 := by - letI : AddCommGroup (T ⊗[S] Ω[S⁄R]) := inferInstance + let : AddCommGroup (T ⊗[S] Ω[S⁄R]) := inferInstance have : IsScalarTower (Q.comp P).Ring (Q.comp P).Ring T := IsScalarTower.left _ induction x using MvPolynomial.induction_on with | C s => @@ -437,7 +437,7 @@ lemma exact_map_δ : set_option backward.isDefEq.respectTransparency false in lemma δ_map (f : Hom Q' Q) (x) : δ Q P (Extension.H1Cotangent.map f.toExtensionHom x) = δ Q' P' x := by - letI : AddCommGroup (T ⊗[S] Ω[S⁄R]) := inferInstance + let : AddCommGroup (T ⊗[S] Ω[S⁄R]) := inferInstance obtain ⟨x, hx⟩ := x obtain ⟨⟨y, hy⟩, rfl⟩ := Extension.Cotangent.mk_surjective x change δ _ _ ⟨_, _⟩ = δ _ _ _ diff --git a/Mathlib/RingTheory/KrullDimension/Basic.lean b/Mathlib/RingTheory/KrullDimension/Basic.lean index f0903f03690d4c..b6cb632903383f 100644 --- a/Mathlib/RingTheory/KrullDimension/Basic.lean +++ b/Mathlib/RingTheory/KrullDimension/Basic.lean @@ -164,7 +164,7 @@ lemma Ring.KrullDimLE.mk₁ (H : ∀ I : Ideal R, I.IsPrime → I ∈ minimalPri lemma Ring.krullDimLE_one_iff_of_isPrime_bot [(⊥ : Ideal R).IsPrime] : Ring.KrullDimLE 1 R ↔ ∀ I : Ideal R, I ≠ ⊥ → I.IsPrime → I.IsMaximal := by - letI : OrderBot (PrimeSpectrum R) := { bot := ⟨⊥, ‹_›⟩, bot_le I := bot_le (a := I.1) } + let : OrderBot (PrimeSpectrum R) := { bot := ⟨⊥, ‹_›⟩, bot_le I := bot_le (a := I.1) } simp_rw [Ring.KrullDimLE, Order.krullDimLE_iff, Nat.cast_one, Order.krullDim_le_one_iff_forall_isMax, (PrimeSpectrum.equivSubtype R).forall_congr_left, Subtype.forall, PrimeSpectrum.isMax_iff, forall_comm (α := _ ≠ ⊥), diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index 86c866fe9a00d5..c2a5dd1a22e4be 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -1105,7 +1105,7 @@ theorem valuation_compare (f : K⸨X⸩) : change Valued.v (adicCompletion.ofCompletion ((LaurentSeriesPkg K).compare ratfuncAdicComplPkg f)) = Valued.v f rw [adicCompletion.valued_ofCompletion] - letI : UniformSpace (ratfuncAdicComplPkg (K := K).space) := + let : UniformSpace (ratfuncAdicComplPkg (K := K).space) := ratfuncAdicComplPkg.uniformStruct have raw_surj : Function.Surjective (Valued.v : (polynomialValuationX K).Completion → ℤᵐ⁰) := Valued.valuedCompletion_surjective_iff.mpr <| .of_comp ((idealX K).valuation_surjective K⟮X⟯) diff --git a/Mathlib/RingTheory/LinearDisjoint.lean b/Mathlib/RingTheory/LinearDisjoint.lean index fe0d53ff6a84e6..74ebfb88e9564f 100644 --- a/Mathlib/RingTheory/LinearDisjoint.lean +++ b/Mathlib/RingTheory/LinearDisjoint.lean @@ -593,9 +593,9 @@ theorem exists_field_of_isDomain_of_injective (A : Type v) [CommRing A] (B : Typ theorem of_isField (H : IsField (A ⊗[R] B)) : A.LinearDisjoint B := by nontriviality S rw [linearDisjoint_iff_injective] - letI : Field (A ⊗[R] B) := H.toField + let : Field (A ⊗[R] B) := H.toField -- need this otherwise `RingHom.injective` does not work - letI : NonAssocRing (A ⊗[R] B) := Ring.toNonAssocRing + let : NonAssocRing (A ⊗[R] B) := Ring.toNonAssocRing exact RingHom.injective _ /-- If `A ⊗[R] B` is a field, then for any `R`-algebra `S` @@ -617,7 +617,7 @@ theorem _root_.Algebra.TensorProduct.not_isField_of_transcendental (A : Type v) [CommRing A] (B : Type w) [CommRing B] [Algebra R A] [Algebra R B] [Module.Flat R A] [Module.Flat R B] [Algebra.Transcendental R A] [Algebra.Transcendental R B] : ¬IsField (A ⊗[R] B) := fun H ↦ by - letI := H.toField + let := H.toField obtain ⟨a, hta⟩ := ‹Algebra.Transcendental R A› obtain ⟨b, htb⟩ := ‹Algebra.Transcendental R B› have ha : Function.Injective (algebraMap R A) := Algebra.injective_of_transcendental @@ -626,10 +626,10 @@ theorem _root_.Algebra.TensorProduct.not_isField_of_transcendental let fb : B →ₐ[R] A ⊗[R] B := Algebra.TensorProduct.includeRight have hfa : Function.Injective fa := Algebra.TensorProduct.includeLeft_injective hb have hfb : Function.Injective fb := Algebra.TensorProduct.includeRight_injective ha - haveI := hfa.isDomain fa.toRingHom - haveI := hfb.isDomain fb.toRingHom - haveI := ha.isDomain _ - haveI : Module.Flat R (toSubmodule fa.range) := + have := hfa.isDomain fa.toRingHom + have := hfb.isDomain fb.toRingHom + have := ha.isDomain _ + have : Module.Flat R (toSubmodule fa.range) := .of_linearEquiv (AlgEquiv.ofInjective fa hfa).symm.toLinearEquiv have key1 : Module.rank R ↥(fa.range ⊓ fb.range) ≤ 1 := (include_range R A B).rank_inf_le_one_of_flat_left @@ -641,7 +641,7 @@ theorem _root_.Algebra.TensorProduct.not_isField_of_transcendental have htab : Function.Injective gab := hfa.comp hta algebraize_only [ga.toRingHom, gb.toRingHom] let f := Algebra.TensorProduct.mapOfCompatibleSMul R[X] R R A B - haveI := Algebra.TensorProduct.nontrivial_of_algebraMap_injective_of_isDomain R[X] A B hta htb + have := Algebra.TensorProduct.nontrivial_of_algebraMap_injective_of_isDomain R[X] A B hta htb have hf : Function.Injective f := RingHom.injective _ have key2 : gab.range ≤ fa.range ⊓ fb.range := by simp_rw [gab, ga, ← aeval_algHom] @@ -723,7 +723,7 @@ theorem of_finrank_sup_of_free [Module.Free R A] [Module.Free R B] (LinearEquiv.ofFinrankEq (A ⊗[R] B) _ (by simp)).toLinearMap replace hj : Function.Injective j' := by simpa [j'] have hf : Function.Surjective (mulMap' A B).toLinearMap := mulMap'_surjective A B - haveI := Subalgebra.finite_sup A B + have := Subalgebra.finite_sup A B rw [linearDisjoint_iff, Submodule.linearDisjoint_iff] exact Subtype.val_injective.comp (OrzechProperty.injective_of_surjective_of_injective j' _ hj hf) @@ -761,9 +761,9 @@ theorem of_finrank_coprime_of_free [Module.Free R A] [Module.Free R B] · rw [h2, Nat.coprime_zero_right] at H rw [eq_bot_of_finrank_one H] exact bot_left _ - haveI := Module.finite_of_finrank_pos (Nat.pos_of_ne_zero h1) - haveI := Module.finite_of_finrank_pos (Nat.pos_of_ne_zero h2) - haveI := finite_sup A B + have := Module.finite_of_finrank_pos (Nat.pos_of_ne_zero h1) + have := Module.finite_of_finrank_pos (Nat.pos_of_ne_zero h2) + have := finite_sup A B have : Module.finrank R A ≤ Module.finrank R ↥(A ⊔ B) := LinearMap.finrank_le_finrank_of_injective <| Submodule.inclusion_injective (show toSubmodule A ≤ toSubmodule (A ⊔ B) by simp) diff --git a/Mathlib/RingTheory/LittleWedderburn.lean b/Mathlib/RingTheory/LittleWedderburn.lean index d45ab2d60d826a..a3a327f76cb297 100644 --- a/Mathlib/RingTheory/LittleWedderburn.lean +++ b/Mathlib/RingTheory/LittleWedderburn.lean @@ -69,7 +69,7 @@ private theorem center_eq_top [Finite D] (hD : InductionHyp D) : Subring.center set Z := Subring.center D -- We proceed by contradiction; that is, we assume the center is strictly smaller than `D`. by_contra! hZ - letI : Field Z := hD.field hZ.lt_top + let : Field Z := hD.field hZ.lt_top set q := card Z with card_Z have hq : 1 < q := by rw [card_Z]; exact one_lt_card let n := finrank Z D @@ -118,12 +118,12 @@ private theorem center_eq_top [Finite D] (hD : InductionHyp D) : Subring.center by_contra! hZx refine (ConjClasses.mk_bijOn (Dˣ)).mapsTo (Set.subset_center_units ?_) hx exact Subring.centralizer_eq_top_iff_subset.mp hZx <| Set.mem_singleton _ - letI : Field Zx := hD.field hZx.lt_top - letI : Algebra Z Zx := (Subring.inclusion <| Subring.center_le_centralizer {(x : D)}).toAlgebra + let : Field Zx := hD.field hZx.lt_top + let : Algebra Z Zx := (Subring.inclusion <| Subring.center_le_centralizer {(x : D)}).toAlgebra let d := finrank Z Zx have card_Zx : card Zx = q ^ d := Module.card_eq_pow_finrank have h1qd : 1 ≤ q ^ d := by rw [← card_Zx]; exact card_pos - haveI : IsScalarTower Z Zx D := ⟨fun x y z ↦ mul_assoc _ _ _⟩ + have : IsScalarTower Z Zx D := ⟨fun x y z ↦ mul_assoc _ _ _⟩ rw [card_units, card_Zx] push_cast [h1qd, h1qn] apply Int.dvd_div_of_mul_dvd diff --git a/Mathlib/RingTheory/LocalProperties/Basic.lean b/Mathlib/RingTheory/LocalProperties/Basic.lean index 93684cdd70eae3..0ad855e9bca672 100644 --- a/Mathlib/RingTheory/LocalProperties/Basic.lean +++ b/Mathlib/RingTheory/LocalProperties/Basic.lean @@ -258,7 +258,7 @@ lemma RingHom.HoldsForLocalization.isLocalizationMap {f : R →+* S} (hy : M ≤ Submonoid.comap f T) (hf : P f) : P (IsLocalization.map (S := R') S' f hy) := by have hle : Submonoid.map f M ≤ T := by simpa [Submonoid.map_le_iff_le_comap] - letI : Algebra (Localization (M.map f)) S' := + let : Algebra (Localization (M.map f)) S' := IsLocalization.localizationAlgebraOfSubmonoidLe _ _ (M.map f) T hle have : IsScalarTower S (Localization (Submonoid.map f M)) S' := IsLocalization.localization_isScalarTower_of_submonoid_le _ _ _ _ _ @@ -286,7 +286,7 @@ end HoldsForLocalization theorem RingHom.HoldsForLocalizationAway.of_bijective (H : RingHom.HoldsForLocalizationAway P) (hf : Function.Bijective f) : P f := by - letI := f.toAlgebra + let := f.toAlgebra have := IsLocalization.of_le_isUnit (S := .powers (1 : R)) (by simp) have := IsLocalization.isLocalization_of_algEquiv (.powers (1 : R)) (AlgEquiv.ofBijective (Algebra.ofId R S) hf) @@ -312,7 +312,7 @@ lemma RingHom.LocalizationAwayPreserves.respectsIso (hP : LocalizationAwayPreserves P) : RespectsIso P where left {R S T} _ _ _ f e hf := by - letI := e.toRingHom.toAlgebra + let := e.toRingHom.toAlgebra have : IsLocalization.Away (1 : R) R := IsLocalization.away_of_isUnit_of_bijective _ isUnit_one (Equiv.refl _).bijective have : IsLocalization.Away (f 1) T := @@ -322,7 +322,7 @@ lemma RingHom.LocalizationAwayPreserves.respectsIso · rw [IsLocalization.Away.map, IsLocalization.map_comp]; rfl · rfl right {R S T} _ _ _ f e hf := by - letI := e.symm.toRingHom.toAlgebra + let := e.symm.toRingHom.toAlgebra have : IsLocalization.Away (1 : S) R := IsLocalization.away_of_isUnit_of_bijective _ isUnit_one e.symm.bijective have : IsLocalization.Away (f 1) T := @@ -338,12 +338,12 @@ lemma RingHom.StableUnderCompositionWithLocalizationAway.respectsIso (hP : StableUnderCompositionWithLocalizationAway P) : RespectsIso P where left {R S T} _ _ _ f e hf := by - letI := e.toRingHom.toAlgebra + let := e.toRingHom.toAlgebra have : IsLocalization.Away (1 : S) T := IsLocalization.away_of_isUnit_of_bijective _ isUnit_one e.bijective exact hP.right T (1 : S) f hf right {R S T} _ _ _ f e hf := by - letI := e.toRingHom.toAlgebra + let := e.toRingHom.toAlgebra have : IsLocalization.Away (1 : R) S := IsLocalization.away_of_isUnit_of_bijective _ isUnit_one e.bijective exact hP.left S (1 : R) f hf @@ -500,9 +500,9 @@ lemma RingHom.IsStableUnderBaseChange.isLocalization_map (M : Submonoid R) [IsLo P (IsLocalization.map Sᵣ f M.le_comap_map : Rᵣ →+* Sᵣ) := by algebraize [f, IsLocalization.map (S := Rᵣ) Sᵣ f M.le_comap_map, (IsLocalization.map (S := Rᵣ) Sᵣ f M.le_comap_map).comp (algebraMap R Rᵣ)] - haveI : IsScalarTower R S Sᵣ := IsScalarTower.of_algebraMap_eq' + have : IsScalarTower R S Sᵣ := IsScalarTower.of_algebraMap_eq' (IsLocalization.map_comp M.le_comap_map) - haveI : IsLocalization (Algebra.algebraMapSubmonoid S M) Sᵣ := + have : IsLocalization (Algebra.algebraMapSubmonoid S M) Sᵣ := inferInstanceAs <| IsLocalization (M.map f) Sᵣ apply hP.of_isLocalization M hf diff --git a/Mathlib/RingTheory/LocalProperties/Exactness.lean b/Mathlib/RingTheory/LocalProperties/Exactness.lean index 0458f36bcea7eb..cd1c1b94c7b3b1 100644 --- a/Mathlib/RingTheory/LocalProperties/Exactness.lean +++ b/Mathlib/RingTheory/LocalProperties/Exactness.lean @@ -299,10 +299,10 @@ lemma injective_of_isLocalization_of_span_eq_top (h : ∀ r : s, Function.Injective (IsLocalization.Away.map (Rᵣ r) (Sᵣ r) f r.1)) : Function.Injective f := by algebraize [f] - letI (r : s) : Algebra R (Sᵣ r) := (algebraMap S (Sᵣ r)).comp f |>.toAlgebra + let (r : s) : Algebra R (Sᵣ r) := (algebraMap S (Sᵣ r)).comp f |>.toAlgebra have (r : s) : IsScalarTower R S (Sᵣ r) := IsScalarTower.of_algebraMap_eq' rfl have : ∀ r, IsLocalization.Away (algebraMap R S r.val) (Sᵣ r) := ‹_› - letI (r : s) : Algebra (Rᵣ r) (Sᵣ r) := localizationAlgebra (.powers r.val) S + let (r : s) : Algebra (Rᵣ r) (Sᵣ r) := localizationAlgebra (.powers r.val) S have (r : s) : IsScalarTower R (Rᵣ r) (Sᵣ r) := .of_algebraMap_eq <| by simp [RingHom.algebraMap_toAlgebra] apply injective_of_isLocalized_span s hs Rᵣ (fun r : s ↦ Algebra.linearMap _ _) _ @@ -313,10 +313,10 @@ lemma surjective_of_isLocalization_of_span_eq_top (h : ∀ r : s, Function.Surjective (IsLocalization.Away.map (Rᵣ r) (Sᵣ r) f r.1)) : Function.Surjective f := by algebraize [f] - letI (r : s) : Algebra R (Sᵣ r) := (algebraMap S (Sᵣ r)).comp f |>.toAlgebra + let (r : s) : Algebra R (Sᵣ r) := (algebraMap S (Sᵣ r)).comp f |>.toAlgebra have (r : s) : IsScalarTower R S (Sᵣ r) := IsScalarTower.of_algebraMap_eq' rfl have : ∀ r, IsLocalization.Away (algebraMap R S r.val) (Sᵣ r) := ‹_› - letI (r : s) : Algebra (Rᵣ r) (Sᵣ r) := localizationAlgebra (.powers r.val) S + let (r : s) : Algebra (Rᵣ r) (Sᵣ r) := localizationAlgebra (.powers r.val) S have (r : s) : IsScalarTower R (Rᵣ r) (Sᵣ r) := .of_algebraMap_eq <| by simp [RingHom.algebraMap_toAlgebra] apply surjective_of_isLocalized_span s hs Rᵣ (fun r : s ↦ Algebra.linearMap _ _) _ diff --git a/Mathlib/RingTheory/LocalRing/Module.lean b/Mathlib/RingTheory/LocalRing/Module.lean index 6bbcdde8c76e2d..44da2179c9b467 100644 --- a/Mathlib/RingTheory/LocalRing/Module.lean +++ b/Mathlib/RingTheory/LocalRing/Module.lean @@ -77,9 +77,9 @@ theorem map_tensorProduct_mk_eq_top {N : Submodule R M} [Module.Finite R M] : N.map (TensorProduct.mk R k M 1) = ⊤ ↔ N = ⊤ := by constructor · intro hN - letI : Module k (M ⧸ (𝔪 • ⊤ : Submodule R M)) := + let : Module k (M ⧸ (𝔪 • ⊤ : Submodule R M)) := inferInstanceAs (Module (R ⧸ 𝔪) (M ⧸ 𝔪 • (⊤ : Submodule R M))) - letI : IsScalarTower R k (M ⧸ (𝔪 • ⊤ : Submodule R M)) := + let : IsScalarTower R k (M ⧸ (𝔪 • ⊤ : Submodule R M)) := inferInstanceAs (IsScalarTower R (R ⧸ 𝔪) (M ⧸ 𝔪 • (⊤ : Submodule R M))) let f := AlgebraTensorModule.lift (((LinearMap.ringLmapEquivSelf k k _).symm (Submodule.mkQ (𝔪 • ⊤ : Submodule R M))).restrictScalars R) @@ -170,8 +170,8 @@ lemma exists_basis_of_basis_baseChange [Module.FinitePresentation R M] (H : Function.Injective ((𝔪).subtype.rTensor M)) : ∃ (b : Basis ι R M), ∀ i, b i = v i := by let bk : Basis ι k (k ⊗[R] M) := Basis.mk hli (by rw [hsp]) - haveI : Finite ι := Module.Finite.finite_basis bk - letI : Fintype ι := Fintype.ofFinite ι + have : Finite ι := Module.Finite.finite_basis bk + let : Fintype ι := Fintype.ofFinite ι let i := Finsupp.linearCombination R v have hi : Surjective i := by rw [← LinearMap.range_eq_top, Finsupp.range_linearCombination] diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean index f3c37bcdb40462..3fec529a17962f 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean @@ -68,10 +68,10 @@ instance [Algebra.IsIntegral A B] : Algebra.IsAlgebraic p.ResidueField q.ResidueField := by have : Algebra.IsIntegral (A ⧸ p) (B ⧸ q) := .tower_top A - letI := ((algebraMap (B ⧸ q) q.ResidueField).comp (algebraMap (A ⧸ p) (B ⧸ q))).toAlgebra - haveI : IsScalarTower (A ⧸ p) (B ⧸ q) q.ResidueField := .of_algebraMap_eq' rfl - haveI : Algebra.IsAlgebraic (A ⧸ p) q.ResidueField := .trans _ (B ⧸ q) _ - haveI : IsScalarTower (A ⧸ p) p.ResidueField q.ResidueField := by + let := ((algebraMap (B ⧸ q) q.ResidueField).comp (algebraMap (A ⧸ p) (B ⧸ q))).toAlgebra + have : IsScalarTower (A ⧸ p) (B ⧸ q) q.ResidueField := .of_algebraMap_eq' rfl + have : Algebra.IsAlgebraic (A ⧸ p) q.ResidueField := .trans _ (B ⧸ q) _ + have : IsScalarTower (A ⧸ p) p.ResidueField q.ResidueField := by refine .of_algebraMap_eq fun x ↦ ?_ obtain ⟨x, rfl⟩ := Ideal.Quotient.mk_surjective x simp [RingHom.algebraMap_toAlgebra, ← IsScalarTower.algebraMap_apply] diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean index 84fafcea4a8714..93440dd039a746 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean @@ -131,7 +131,7 @@ theorem _root_.Ideal.exists_mem_span_singleton_map_residueField_eq I.map (mapRingHom (algebraMap R P.ResidueField)) := by obtain ⟨p, hp : _ = Ideal.span _⟩ := (inferInstance : (I.map (mapRingHom (algebraMap R P.ResidueField))).IsPrincipal) - letI := (mapRingHom (algebraMap (R ⧸ P) P.ResidueField)).toAlgebra + let := (mapRingHom (algebraMap (R ⧸ P) P.ResidueField)).toAlgebra have := Polynomial.isLocalization (R ⧸ P)⁰ P.ResidueField have : p ∈ (I.map (mapRingHom (algebraMap R (R ⧸ P)))).map (algebraMap _ _) := by rw [Ideal.map_map, RingHom.algebraMap_toAlgebra, mapRingHom_comp, diff --git a/Mathlib/RingTheory/LocalRing/Subring.lean b/Mathlib/RingTheory/LocalRing/Subring.lean index 40cb004025a5fb..c8e97022a9411c 100644 --- a/Mathlib/RingTheory/LocalRing/Subring.lean +++ b/Mathlib/RingTheory/LocalRing/Subring.lean @@ -27,7 +27,7 @@ open nonZeroDivisors embeds in a local (semi)ring `S`, then `R` is local. -/ theorem of_injective [IsLocalRing S] {f : R →+* S} (hf : Function.Injective f) (h : ∀ a, a ∈ R⁰ → IsUnit a) : IsLocalRing R := by - haveI : Nontrivial R := f.domain_nontrivial + have : Nontrivial R := f.domain_nontrivial refine .of_is_unit_or_is_unit_of_add_one fun {a b} hab ↦ (IsLocalRing.isUnit_or_isUnit_of_add_one (map_add f .. ▸ map_one f ▸ congrArg f hab)).imp ?_ ?_ <;> exact h _ ∘ mem_nonZeroDivisors_of_injective hf ∘ IsUnit.mem_nonZeroDivisors diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index 8f68522c0189c5..fafd44416928b5 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -724,7 +724,7 @@ theorem exists_reduced_fraction' {b : B} (hb : b ≠ 0) (hx : Irreducible x) : obtain ⟨⟨a₀, y⟩, H⟩ := surj (Submonoid.powers x) b obtain ⟨d, hy⟩ := (Submonoid.mem_powers_iff y.1 x).mp y.2 have ha₀ : a₀ ≠ 0 := by - haveI := isDomain_of_le_nonZeroDivisors B + have := isDomain_of_le_nonZeroDivisors B (powers_le_nonZeroDivisors_of_noZeroDivisors hx.ne_zero) simp only [← hy, map_pow] at H apply ((injective_iff_map_eq_zero' (algebraMap R B)).mp _ a₀).mpr.mt diff --git a/Mathlib/RingTheory/Localization/Away/Lemmas.lean b/Mathlib/RingTheory/Localization/Away/Lemmas.lean index 36c6b0d1ac3b95..8106e24f68cd01 100644 --- a/Mathlib/RingTheory/Localization/Away/Lemmas.lean +++ b/Mathlib/RingTheory/Localization/Away/Lemmas.lean @@ -38,7 +38,7 @@ lemma span_range_mulNumerator_eq_top {s : Set R} Ideal.span (Set.range (IsLocalization.Away.mulNumerator s p)) = ⊤ := by rw [← Ideal.radical_eq_top, eq_top_iff, ← hsone, Ideal.span_le] intro a ha - haveI : IsLocalization (Submonoid.powers a) (Rₜ ⟨a, ha⟩) := + have : IsLocalization (Submonoid.powers a) (Rₜ ⟨a, ha⟩) := inferInstanceAs <| IsLocalization.Away (⟨a, ha⟩ : s).val (Rₜ ⟨a, ha⟩) have h₁ : Ideal.span (p ⟨a, ha⟩) ≤ Ideal.span (algebraMap R (Rₜ ⟨a, ha⟩) '' Set.range (IsLocalization.Away.mulNumerator s p)) := by diff --git a/Mathlib/RingTheory/Localization/BaseChange.lean b/Mathlib/RingTheory/Localization/BaseChange.lean index 5be2d5aa24a705..deb3adecb4afca 100644 --- a/Mathlib/RingTheory/Localization/BaseChange.lean +++ b/Mathlib/RingTheory/Localization/BaseChange.lean @@ -51,7 +51,7 @@ given by `m/s ↦ (1/s) ⊗ₜ m`. -/ theorem isLocalizedModule_iff_isBaseChange : IsLocalizedModule S f ↔ IsBaseChange A f := by refine ⟨fun _ ↦ IsLocalizedModule.isBaseChange S A f, fun h ↦ ?_⟩ - letI : Module A (LocalizedModule S M) := LocalizedModule.moduleOfIsLocalization .. + let : Module A (LocalizedModule S M) := LocalizedModule.moduleOfIsLocalization .. have : IsBaseChange A (LocalizedModule.mkLinearMap S M) := IsLocalizedModule.isBaseChange S A _ let e := (this.equiv.symm.trans h.equiv).restrictScalars R convert! IsLocalizedModule.of_linearEquiv S (LocalizedModule.mkLinearMap S M) e @@ -244,9 +244,9 @@ open TensorProduct instance IsLocalizedModule.rTensor (g : M →ₗ[A] M') [h : IsLocalizedModule S g] : IsLocalizedModule S (AlgebraTensorModule.rTensor R N g) := by let Aₚ := Localization S - letI : Module Aₚ M' := (IsLocalizedModule.iso S g).symm.toAddEquiv.module Aₚ - haveI : IsScalarTower A Aₚ M' := (IsLocalizedModule.iso S g).symm.isScalarTower Aₚ - haveI : IsScalarTower R Aₚ M' := + let : Module Aₚ M' := (IsLocalizedModule.iso S g).symm.toAddEquiv.module Aₚ + have : IsScalarTower A Aₚ M' := (IsLocalizedModule.iso S g).symm.isScalarTower Aₚ + have : IsScalarTower R Aₚ M' := IsScalarTower.of_algebraMap_smul <| fun r x ↦ by simp [IsScalarTower.algebraMap_apply R A Aₚ] rw [isLocalizedModule_iff_isBaseChange (S := S) (A := Aₚ)] at h ⊢ exact isBaseChange_tensorProduct_map _ h @@ -322,7 +322,7 @@ theorem tensorLeftAlgEquiv_apply_one_tmul (x : Localization M) : let Rₘ := Localization M let Sₘ := Localization (Algebra.algebraMapSubmonoid S M) obtain ⟨x, y, rfl⟩ := IsLocalization.exists_mk'_eq M x - letI : Algebra Rₘ (S ⊗[R] Rₘ) := Algebra.TensorProduct.rightAlgebra + let : Algebra Rₘ (S ⊗[R] Rₘ) := Algebra.TensorProduct.rightAlgebra have h1 : (1 : S) ⊗ₜ[R] IsLocalization.mk' Rₘ x y = algebraMap _ _ (IsLocalization.mk' Rₘ x y) := rfl rw [h1, tensorLeftAlgEquiv, algEquiv_symm_apply, @@ -415,7 +415,7 @@ lemma IsLocalization.tensorProductEquivOfMapIncludeRight_tmul (M : Submonoid A) (x : S) (a : A) : IsLocalization.tensorProductEquivOfMapIncludeRight R S M B C (x ⊗ₜ algebraMap A B a) = algebraMap _ _ (x ⊗ₜ[R] a) := by - letI : Algebra (S ⊗[R] A) (S ⊗[R] B) := + let : Algebra (S ⊗[R] A) (S ⊗[R] B) := (Algebra.TensorProduct.map (AlgHom.id R S) (IsScalarTower.toAlgHom R _ _)).toAlgebra have heq : x ⊗ₜ[R] (algebraMap A B) a = algebraMap _ _ (x ⊗ₜ[R] a) := rfl simp [heq, IsLocalization.tensorProductEquivOfMapIncludeRight] diff --git a/Mathlib/RingTheory/Localization/Basic.lean b/Mathlib/RingTheory/Localization/Basic.lean index c59a1127945cf0..f70e235d540cbd 100644 --- a/Mathlib/RingTheory/Localization/Basic.lean +++ b/Mathlib/RingTheory/Localization/Basic.lean @@ -489,7 +489,7 @@ open IsLocalization theorem IsField.localization_map_bijective {R Rₘ : Type*} [CommRing R] [CommRing Rₘ] {M : Submonoid R} (hM : (0 : R) ∉ M) (hR : IsField R) [Algebra R Rₘ] [IsLocalization M Rₘ] : Function.Bijective (algebraMap R Rₘ) := by - letI := hR.toField + let := hR.toField replace hM := le_nonZeroDivisors_of_noZeroDivisors hM refine ⟨IsLocalization.injective _ hM, fun x => ?_⟩ obtain ⟨r, ⟨m, hm⟩, rfl⟩ := exists_mk'_eq M x diff --git a/Mathlib/RingTheory/Localization/Defs.lean b/Mathlib/RingTheory/Localization/Defs.lean index 2a6edce839a986..f2084b62f2ecf9 100644 --- a/Mathlib/RingTheory/Localization/Defs.lean +++ b/Mathlib/RingTheory/Localization/Defs.lean @@ -730,7 +730,7 @@ variable (M) theorem isLocalization_of_base_ringEquiv [IsLocalization M S] (h : R ≃+* P) : haveI := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra IsLocalization (M.map h) S := by - letI : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra + let : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra constructor; constructor · rintro ⟨_, ⟨y, hy, rfl⟩⟩ convert! IsLocalization.map_units S ⟨y, hy⟩ @@ -750,7 +750,7 @@ theorem isLocalization_iff_of_base_ringEquiv (h : R ≃+* P) : IsLocalization M S ↔ haveI := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra IsLocalization (M.map h) S := by - letI : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra + let : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra refine ⟨fun _ => isLocalization_of_base_ringEquiv M S h, ?_⟩ intro (H : IsLocalization (Submonoid.map (h : R ≃* P) M) S) convert! isLocalization_of_base_ringEquiv (Submonoid.map (h : R ≃* P) M) S h.symm diff --git a/Mathlib/RingTheory/Localization/FractionRing.lean b/Mathlib/RingTheory/Localization/FractionRing.lean index 54d432f40eba71..c403caf19d5c84 100644 --- a/Mathlib/RingTheory/Localization/FractionRing.lean +++ b/Mathlib/RingTheory/Localization/FractionRing.lean @@ -270,11 +270,11 @@ theorem isUnit_map_of_injective (hg : Function.Injective g) (y : nonZeroDivisors theorem mk'_eq_zero_iff_eq_zero [Algebra R K] [IsFractionRing R K] {x : R} {y : nonZeroDivisors R} : mk' K x y = 0 ↔ x = 0 := by - haveI := (algebraMap R K).domain_nontrivial + have := (algebraMap R K).domain_nontrivial simp [nonZeroDivisors.ne_zero] theorem mk'_eq_one_iff_eq {x : A} {y : nonZeroDivisors A} : mk' K x y = 1 ↔ x = y := by - haveI := (algebraMap A K).domain_nontrivial + have := (algebraMap A K).domain_nontrivial refine ⟨?_, fun hxy => by rw [hxy, mk'_self']⟩ intro hxy have hy : (algebraMap A K) ↑y ≠ (0 : K) := diff --git a/Mathlib/RingTheory/Localization/Ideal.lean b/Mathlib/RingTheory/Localization/Ideal.lean index 35ae3cd89208ca..1d231e301dfe06 100644 --- a/Mathlib/RingTheory/Localization/Ideal.lean +++ b/Mathlib/RingTheory/Localization/Ideal.lean @@ -348,7 +348,7 @@ open nonZeroDivisors theorem bot_lt_under_prime [IsDomain R] (hM : M ≤ R⁰) (p : Ideal S) [hpp : p.IsPrime] (hp0 : p ≠ ⊥) : ⊥ < p.under R := by - haveI : IsDomain S := isDomain_of_le_nonZeroDivisors _ hM + have : IsDomain S := isDomain_of_le_nonZeroDivisors _ hM rw [← Ideal.comap_bot_of_injective (algebraMap R S) (IsLocalization.injective _ hM)] convert! (orderIsoOfPrime M S).lt_iff_lt.mpr diff --git a/Mathlib/RingTheory/Localization/Integer.lean b/Mathlib/RingTheory/Localization/Integer.lean index 021a6a1474c278..2d307a6a86a984 100644 --- a/Mathlib/RingTheory/Localization/Integer.lean +++ b/Mathlib/RingTheory/Localization/Integer.lean @@ -86,7 +86,7 @@ theorem exists_integer_multiple (a : S) : ∃ b : M, IsInteger R ((b : R) • a) /-- We can clear the denominators of a `Finset`-indexed family of fractions. -/ theorem exist_integer_multiples {ι : Type*} (s : Finset ι) (f : ι → S) : ∃ b : M, ∀ i ∈ s, IsLocalization.IsInteger R ((b : R) • f i) := by - haveI := Classical.propDecidable + have := Classical.propDecidable refine ⟨∏ i ∈ s, (sec M (f i)).2, fun i hi => ⟨?_, ?_⟩⟩ · exact (∏ j ∈ s.erase i, (sec M (f j)).2) * (sec M (f i)).1 rw [map_mul, sec_spec', ← mul_assoc, ← (algebraMap R S).map_mul, ← Algebra.smul_def] diff --git a/Mathlib/RingTheory/Localization/Integral.lean b/Mathlib/RingTheory/Localization/Integral.lean index 8d608d1116c9c8..cd0fc56ae9e91a 100644 --- a/Mathlib/RingTheory/Localization/Integral.lean +++ b/Mathlib/RingTheory/Localization/Integral.lean @@ -86,9 +86,9 @@ variable {M} in theorem integerNormalization_eq_zero_iff [IsDomain R] (hM : M ≤ nonZeroDivisors R) (p : S[X]) : integerNormalization M p = 0 ↔ p = 0 := by obtain ⟨_, hb₁, hb₂⟩ := integerNormalization_spec M p - letI := isDomain_of_le_nonZeroDivisors S hM - letI := (faithfulSMul_iff_algebraMap_injective R S).mpr <| IsLocalization.injective S hM - letI : Function.Injective <| mapRingHom (algebraMap R S) := by + let := isDomain_of_le_nonZeroDivisors S hM + let := (faithfulSMul_iff_algebraMap_injective R S).mpr <| IsLocalization.injective S hM + let : Function.Injective <| mapRingHom (algebraMap R S) := by rw [coe_mapRingHom, map_injective_iff] exact IsLocalization.injective S hM rw [← _root_.map_eq_zero_iff (mapRingHom (algebraMap R S)) this, coe_mapRingHom, hb₂] @@ -173,7 +173,7 @@ theorem RingHom.isIntegralElem_localization_at_leadingCoeff {R S : Type*} [CommS (map Sₘ f M.le_comap_map : Rₘ →+* _).IsIntegralElem (algebraMap S Sₘ x) := by by_cases triv : (1 : Rₘ) = 0 · exact ⟨0, ⟨_root_.trans leadingCoeff_zero triv.symm, eval₂_zero _ _⟩⟩ - haveI : Nontrivial Rₘ := nontrivial_of_ne 1 0 triv + have : Nontrivial Rₘ := nontrivial_of_ne 1 0 triv obtain ⟨b, hb⟩ := isUnit_iff_exists_inv.mp (map_units Rₘ ⟨p.leadingCoeff, hM⟩) refine ⟨p.map (algebraMap R Rₘ) * C b, ⟨?_, ?_⟩⟩ · refine monic_mul_C_of_leadingCoeff_mul_eq_one ?_ @@ -254,7 +254,7 @@ theorem IsLocalization.scaleRoots_commonDenom_mem_lifts (p : Rₘ[X]) theorem IsIntegral.exists_multiple_integral_of_isLocalization [Algebra Rₘ S] [IsScalarTower R Rₘ S] (x : S) (hx : IsIntegral Rₘ x) : ∃ m : M, IsIntegral R (m • x) := by rcases subsingleton_or_nontrivial Rₘ with _ | nontriv - · haveI := (algebraMap Rₘ S).codomain_trivial + · have := (algebraMap Rₘ S).codomain_trivial exact ⟨1, Polynomial.X, Polynomial.monic_X, Subsingleton.elim _ _⟩ obtain ⟨p, hp₁, hp₂⟩ := hx -- Porting note: obtain doesn't support side goals @@ -331,7 +331,7 @@ lemma isIntegral_of_isIntegral_adjoin_of_mul_eq_one · simp_all let q' := q.sum fun i r ↦ X ^ i * r.reflect N have (i : _) : aeval t (reflect N (q.coeff i)) = t ^ N * (aeval s (q.coeff i)) := by - letI : Invertible t := ⟨s, hst, (mul_comm _ _).trans hst⟩ + let : Invertible t := ⟨s, hst, (mul_comm _ _).trans hst⟩ rw [aeval_def, ← eval₂_reflect_mul_pow _ _ N _ ((natDegree_reflect_le ..).trans (by simp [hN]))] simp +instances [mul_comm, this, aeval_def] refine ⟨q', ?_, ?_⟩ @@ -494,8 +494,8 @@ theorem isAlgebraic_iff' [Field K] [IsDomain R] [Algebra R K] [Algebra S K] simp only [Algebra.isAlgebraic_def] constructor · intro h x - letI := MulActionWithZero.nontrivial S K - letI := FractionRing.liftAlgebra R K + let := MulActionWithZero.nontrivial S K + let := FractionRing.liftAlgebra R K have := FractionRing.isScalarTower_liftAlgebra R K rw [IsFractionRing.isAlgebraic_iff R (FractionRing R) K, isAlgebraic_iff_isIntegral] obtain ⟨a : S, b, ha, rfl⟩ := div_surjective S x diff --git a/Mathlib/RingTheory/Localization/LocalizationLocalization.lean b/Mathlib/RingTheory/Localization/LocalizationLocalization.lean index fb4c01dd8d196d..bfbe023e990663 100644 --- a/Mathlib/RingTheory/Localization/LocalizationLocalization.lean +++ b/Mathlib/RingTheory/Localization/LocalizationLocalization.lean @@ -277,8 +277,8 @@ theorem isFractionRing_of_isLocalization (S T : Type*) [CommRing S] [CommRing T] theorem isFractionRing_of_isDomain_of_isLocalization [IsDomain R] (S T : Type*) [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] [Algebra S T] [IsScalarTower R S T] [IsLocalization M S] [IsFractionRing R T] : IsFractionRing S T := by - haveI := IsFractionRing.nontrivial R T - haveI := (algebraMap S T).domain_nontrivial + have := IsFractionRing.nontrivial R T + have := (algebraMap S T).domain_nontrivial apply isFractionRing_of_isLocalization M S T intro x hx rw [mem_nonZeroDivisors_iff_ne_zero] diff --git a/Mathlib/RingTheory/Localization/NormTrace.lean b/Mathlib/RingTheory/Localization/NormTrace.lean index 0ac9bdc4c3e206..1fb45d4bd9dca2 100644 --- a/Mathlib/RingTheory/Localization/NormTrace.lean +++ b/Mathlib/RingTheory/Localization/NormTrace.lean @@ -63,10 +63,10 @@ Then the norm of `a : Sₘ` over `Rₘ` is the norm of `a : S` over `R` if `S` i theorem Algebra.norm_localization [Module.Free R S] [Module.Finite R S] (a : S) : Algebra.norm Rₘ (algebraMap S Sₘ a) = algebraMap R Rₘ (Algebra.norm R a) := by cases subsingleton_or_nontrivial R - · haveI : Subsingleton Rₘ := Module.subsingleton R Rₘ + · have : Subsingleton Rₘ := Module.subsingleton R Rₘ simp [eq_iff_true_of_subsingleton] let b := Module.Free.chooseBasis R S - letI := Classical.decEq (Module.Free.ChooseBasisIndex R S) + let := Classical.decEq (Module.Free.ChooseBasisIndex R S) rw [Algebra.norm_eq_matrix_det (b.localizationLocalization Rₘ M Sₘ), Algebra.norm_eq_matrix_det b, RingHom.map_det, ← Algebra.map_leftMulMatrix_localization] @@ -84,10 +84,10 @@ Then the trace of `a : Sₘ` over `Rₘ` is the trace of `a : S` over `R` if `S` theorem Algebra.trace_localization [Module.Free R S] [Module.Finite R S] (a : S) : Algebra.trace Rₘ Sₘ (algebraMap S Sₘ a) = algebraMap R Rₘ (Algebra.trace R S a) := by cases subsingleton_or_nontrivial R - · haveI : Subsingleton Rₘ := Module.subsingleton R Rₘ + · have : Subsingleton Rₘ := Module.subsingleton R Rₘ simp [eq_iff_true_of_subsingleton] let b := Module.Free.chooseBasis R S - letI := Classical.decEq (Module.Free.ChooseBasisIndex R S) + let := Classical.decEq (Module.Free.ChooseBasisIndex R S) rw [Algebra.trace_eq_matrix_trace (b.localizationLocalization Rₘ M Sₘ), Algebra.trace_eq_matrix_trace b, ← Algebra.map_leftMulMatrix_localization] exact (AddMonoidHom.map_trace (algebraMap R Rₘ).toAddMonoidHom _).symm diff --git a/Mathlib/RingTheory/Morita/Matrix.lean b/Mathlib/RingTheory/Morita/Matrix.lean index aedf27525a3d56..a02d768515c31b 100644 --- a/Mathlib/RingTheory/Morita/Matrix.lean +++ b/Mathlib/RingTheory/Morita/Matrix.lean @@ -149,8 +149,8 @@ def toModuleCatFromModuleCatLinearEquiv (M : ModuleCat (Matrix ι ι R)) (j : ι simp [← mul_smul]⟩ map_add' _ _ := by ext; simp map_smul' x m := funext fun i ↦ Subtype.ext <| by - letI := Module.compHom M (Matrix.scalar (α := R) ι) - haveI := MatrixModCat.isScalarTower_toModuleCat R M + let := Module.compHom M (Matrix.scalar (α := R) ι) + have := MatrixModCat.isScalarTower_toModuleCat R M simp only [← mul_smul, RingHom.id_apply, Module.smul_apply, AddSubmonoidClass.coe_finsetSum, SetLike.val_smul, ← smul_assoc, ← Finset.sum_smul] congr diff --git a/Mathlib/RingTheory/MvPowerSeries/Expand.lean b/Mathlib/RingTheory/MvPowerSeries/Expand.lean index 7a2504c80c23c3..1df40bfe1c3eee 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Expand.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Expand.lean @@ -140,7 +140,7 @@ theorem support_expand_subset (φ : MvPowerSeries σ R) : (expand p hp φ).support ⊆ φ.support.image (p • ·) := by intro d hd have : ∀ i, p ∣ d i := fun _ => by_contra fun hc => hd (coeff_expand_of_not_dvd p hp φ hc) - letI m := d.mapRange (fun n => n / p) (Nat.zero_div p) + let m := d.mapRange (fun n => n / p) (Nat.zero_div p) have eq_aux : p • m = d := (Finsupp.ext fun a => Nat.eq_mul_of_div_eq_right (this a) rfl).symm rw [Function.mem_support, ← eq_aux, ← coeff_apply (expand p hp φ), coeff_expand_smul, coeff_apply] at hd diff --git a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean index 4bf62eae37dcea..10ff8630dd1051 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean @@ -98,19 +98,19 @@ theorem HasSubst.hasEval [TopologicalSpace S] (ha : HasSubst a) : (@hasSubst_iff_hasEval_of_discreteTopology σ τ _ _ a ⊥ (@DiscreteTopology.mk S ⊥ rfl)).mp ha theorem HasSubst.zero : HasSubst (fun (_ : σ) ↦ (0 : MvPowerSeries τ S)) := by - letI : UniformSpace S := ⊥ + let : UniformSpace S := ⊥ simpa [hasSubst_iff_hasEval_of_discreteTopology] using! HasEval.zero theorem HasSubst.add {a b : σ → MvPowerSeries τ S} (ha : HasSubst a) (hb : HasSubst b) : HasSubst (a + b) := by - letI : UniformSpace S := ⊥ + let : UniformSpace S := ⊥ rw [hasSubst_iff_hasEval_of_discreteTopology] at ha hb ⊢ exact ha.add hb theorem HasSubst.mul_left (b : σ → MvPowerSeries τ S) {a : σ → MvPowerSeries τ S} (ha : HasSubst a) : HasSubst (b * a) := by - letI : UniformSpace S := ⊥ + let : UniformSpace S := ⊥ rw [hasSubst_iff_hasEval_of_discreteTopology] at ha ⊢ exact ha.mul_left b @@ -123,7 +123,7 @@ theorem HasSubst.smul (r : MvPowerSeries τ S) {a : σ → MvPowerSeries τ S} ( HasSubst (r • a) := ha.mul_left _ protected theorem HasSubst.X : HasSubst (fun (s : σ) ↦ (X s : MvPowerSeries σ S)) := by - letI : UniformSpace S := ⊥ + let : UniformSpace S := ⊥ simpa [hasSubst_iff_hasEval_of_discreteTopology] using HasEval.X omit [Algebra R S] in @@ -200,8 +200,8 @@ theorem subst_eq_eval₂ theorem subst_coe (p : MvPolynomial σ R) : subst (R := R) a p = MvPolynomial.aeval a p := by - letI : UniformSpace R := ⊥ - letI : UniformSpace S := ⊥ + let : UniformSpace R := ⊥ + let : UniformSpace S := ⊥ rw [subst_eq_eval₂, eval₂_coe, MvPolynomial.aeval_def] variable {a : σ → MvPowerSeries τ S} @@ -228,13 +228,13 @@ theorem substAlgHom_eq_aeval @[simp] theorem coe_substAlgHom (ha : HasSubst a) : ⇑(substAlgHom ha) = subst (R := R) a := by - letI : UniformSpace R := ⊥ - letI : UniformSpace S := ⊥ + let : UniformSpace R := ⊥ + let : UniformSpace S := ⊥ rw [substAlgHom_eq_aeval, coe_aeval ha.hasEval, subst_eq_eval₂] theorem subst_self : subst (MvPowerSeries.X : σ → MvPowerSeries σ R) = id := by rw [← coe_substAlgHom HasSubst.X] - letI : UniformSpace R := ⊥ + let : UniformSpace R := ⊥ ext1 f simp only [substAlgHom_eq_aeval] have := aeval_unique (ε := AlgHom.id R (MvPowerSeries σ R)) continuous_id @@ -310,8 +310,8 @@ theorem coeff_subst_finite (ha : HasSubst a) (f : MvPowerSeries σ R) (e : τ theorem coeff_subst (ha : HasSubst a) (f : MvPowerSeries σ R) (e : τ →₀ ℕ) : coeff e (subst a f) = finsum (fun d ↦ coeff d f • (coeff e (d.prod fun s e => (a s) ^ e))) := by - letI : UniformSpace R := ⊥ - letI : UniformSpace S := ⊥ + let : UniformSpace R := ⊥ + let : UniformSpace S := ⊥ have := ((hasSum_aeval ha.hasEval f).map (coeff e) (continuous_coeff S e)) simp [← coe_substAlgHom ha, substAlgHom, ← this.tsum_eq, tsum_eq_finsum (coeff_subst_finite ha f e)] @@ -451,17 +451,17 @@ theorem HasSubst.comp (ha : HasSubst a) (hb : HasSubst b) : HasSubst (fun s ↦ substAlgHom hb (a s)) where const_coeff s := IsNilpotent_substAlgHom hb (ha.const_coeff s) coeff_zero := by - letI : UniformSpace S := ⊥ - letI : UniformSpace T := ⊥ + let : UniformSpace S := ⊥ + let : UniformSpace T := ⊥ rw [← coeff_zero_iff] apply Filter.Tendsto.comp _ (ha.hasEval.tendsto_zero) simpa [← map_zero (substAlgHom (R := S) hb)] using! (continuous_subst hb).continuousAt theorem substAlgHom_comp_substAlgHom (ha : HasSubst a) (hb : HasSubst b) : ((substAlgHom hb).restrictScalars R).comp (substAlgHom ha) = substAlgHom (ha.comp hb) := by - letI : UniformSpace R := ⊥ - letI : UniformSpace S := ⊥ - letI : UniformSpace T := ⊥ + let : UniformSpace R := ⊥ + let : UniformSpace S := ⊥ + let : UniformSpace T := ⊥ apply comp_aeval (R := R) (ε := (substAlgHom hb).restrictScalars R) ha.hasEval simpa [AlgHom.coe_restrictScalars'] using continuous_subst (R := S) hb diff --git a/Mathlib/RingTheory/Noetherian/Orzech.lean b/Mathlib/RingTheory/Noetherian/Orzech.lean index ed2d8f1243cb19..eb3f64234d857f 100644 --- a/Mathlib/RingTheory/Noetherian/Orzech.lean +++ b/Mathlib/RingTheory/Noetherian/Orzech.lean @@ -43,7 +43,7 @@ utilizing `LinearMap.iterateMapComap`. See also Orzech's original paper: *Onto endomorphisms are isomorphisms* [orzech1971]. -/ theorem IsNoetherian.injective_of_surjective_of_injective (i f : N →ₗ[R] M) (hi : Injective i) (hf : Surjective f) : Injective f := by - haveI := isNoetherian_of_injective i hi + have := isNoetherian_of_injective i hi obtain ⟨n, H⟩ := monotone_stabilizes_iff_noetherian.2 ‹_› ⟨_, monotone_nat_of_le_succ <| f.iterateMapComap_le_succ i ⊥ (by simp)⟩ exact LinearMap.ker_eq_bot.1 <| bot_unique <| diff --git a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean index 2032ab1081b90b..6a2cec329d3935 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean @@ -696,7 +696,7 @@ theorem coe_iSup_of_directed {ι} [Nonempty ι] {S : ι → NonUnitalSubring R} theorem mem_sSup_of_directedOn {S : Set (NonUnitalSubring R)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, exists_prop] diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index 188f76c8320d9d..7dc6408d1a7b31 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean @@ -631,7 +631,7 @@ theorem coe_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → NonUnitalSubse theorem mem_sSup_of_directedOn {S : Set (NonUnitalSubsemiring R)} (Sne : S.Nonempty) (hS : DirectedOn (· ≤ ·) S) {x : R} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by - haveI : Nonempty S := Sne.to_subtype + have : Nonempty S := Sne.to_subtype simp only [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, Subtype.exists, exists_prop] theorem coe_sSup_of_directedOn {S : Set (NonUnitalSubsemiring R)} (Sne : S.Nonempty) diff --git a/Mathlib/RingTheory/Norm/Basic.lean b/Mathlib/RingTheory/Norm/Basic.lean index 57096d1816ef5f..3d824925a0be44 100644 --- a/Mathlib/RingTheory/Norm/Basic.lean +++ b/Mathlib/RingTheory/Norm/Basic.lean @@ -72,7 +72,7 @@ theorem PowerBasis.norm_gen_eq_coeff_zero_minpoly (pb : PowerBasis R S) : theorem PowerBasis.norm_gen_eq_prod_roots [Algebra R F] (pb : PowerBasis R S) (hf : ((minpoly R pb.gen).map (algebraMap R F)).Splits) : algebraMap R F (norm R pb.gen) = ((minpoly R pb.gen).aroots F).prod := by - haveI := Module.nontrivial R F + have := Module.nontrivial R F have := minpoly.monic pb.isIntegral_gen rw [PowerBasis.norm_gen_eq_coeff_zero_minpoly, ← pb.natDegree_minpoly, map_mul, ← coeff_map, @@ -119,8 +119,8 @@ theorem norm_eq_zero_iff' [IsDomain R] [IsDomain S] [Module.Free R S] [Module.Fi theorem norm_eq_zero_iff_of_basis [IsDomain R] [IsDomain S] (b : Basis ι R S) {x : S} : Algebra.norm R x = 0 ↔ x = 0 := by - haveI : Module.Free R S := Module.Free.of_basis b - haveI : Module.Finite R S := Module.Finite.of_basis b + have : Module.Free R S := Module.Free.of_basis b + have : Module.Finite R S := Module.Finite.of_basis b exact norm_eq_zero_iff theorem norm_ne_zero_iff_of_basis [IsDomain R] [IsDomain S] (b : Basis ι R S) {x : S} : @@ -179,7 +179,7 @@ theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S) (hE : ((minpoly R pb.gen).map (algebraMap R F)).Splits) (hfx : IsSeparable R pb.gen) : algebraMap R F (norm R pb.gen) = (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by - letI := Classical.decEq F + let := Classical.decEq F rw [PowerBasis.norm_gen_eq_prod_roots pb hE] rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv' (fun σ => σ pb.gen) (fun x => x) ?_] @@ -194,13 +194,13 @@ theorem prod_embeddings_eq_finrank_pow [Algebra L F] [IsScalarTower K L F] [IsAl ∏ σ : F →ₐ[K] E, σ (algebraMap L F pb.gen) = ((@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ : L →ₐ[K] E => σ pb.gen) ^ finrank L F := by - haveI : FiniteDimensional L F := FiniteDimensional.right K L F - haveI : Algebra.IsSeparable L F := Algebra.isSeparable_tower_top_of_isSeparable K L F - letI : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb + have : FiniteDimensional L F := FiniteDimensional.right K L F + have : Algebra.IsSeparable L F := Algebra.isSeparable_tower_top_of_isSeparable K L F + let : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb rw [Fintype.prod_equiv algHomEquivSigma (fun σ : F →ₐ[K] E => _) fun σ => σ.1 pb.gen, ← Finset.univ_sigma_univ, Finset.prod_sigma, ← Finset.prod_pow] · refine Finset.prod_congr rfl fun σ _ => ?_ - letI : Algebra L E := σ.toRingHom.toAlgebra + let : Algebra L E := σ.toRingHom.toAlgebra simp_rw [Finset.prod_const] congr exact AlgHom.card L F E @@ -220,8 +220,8 @@ lemma norm_eq_of_ringEquiv {A B C : Type*} [CommRing A] [CommRing B] [Ring C] classical by_cases h : ∃ s : Finset C, Nonempty (Basis s B C) · obtain ⟨s, ⟨b⟩⟩ := h - letI : Algebra A B := RingHom.toAlgebra e - letI : IsScalarTower A B C := IsScalarTower.of_algebraMap_eq' he.symm + let : Algebra A B := RingHom.toAlgebra e + let : IsScalarTower A B C := IsScalarTower.of_algebraMap_eq' he.symm rw [Algebra.norm_eq_matrix_det b, Algebra.norm_eq_matrix_det (b.mapCoeffs e.symm (by simp [Algebra.smul_def, ← he])), e.map_det] @@ -236,7 +236,7 @@ lemma norm_eq_of_equiv_equiv {A₁ B₁ A₂ B₂ : Type*} [CommRing A₁] [Ring [CommRing A₂] [Ring B₂] [Algebra A₁ B₁] [Algebra A₂ B₂] (e₁ : A₁ ≃+* A₂) (e₂ : B₁ ≃+* B₂) (he : RingHom.comp (algebraMap A₂ B₂) ↑e₁ = RingHom.comp ↑e₂ (algebraMap A₁ B₁)) (x) : Algebra.norm A₁ x = e₁.symm (Algebra.norm A₂ (e₂ x)) := by - letI := (RingHom.comp (e₂ : B₁ →+* B₂) (algebraMap A₁ B₁)).toAlgebra' ?_ + let := (RingHom.comp (e₂ : B₁ →+* B₂) (algebraMap A₁ B₁)).toAlgebra' ?_ · let e' : B₁ ≃ₐ[A₁] B₂ := { e₂ with commutes' := fun _ ↦ rfl } rw [← Algebra.norm_eq_of_ringEquiv e₁ he, ← Algebra.norm_eq_of_algEquiv e'] simp [e'] diff --git a/Mathlib/RingTheory/Norm/Defs.lean b/Mathlib/RingTheory/Norm/Defs.lean index ead7185cfdb2e1..401d4bd8d9a15d 100644 --- a/Mathlib/RingTheory/Norm/Defs.lean +++ b/Mathlib/RingTheory/Norm/Defs.lean @@ -86,7 +86,7 @@ theorem norm_eq_matrix_det [Fintype ι] [DecidableEq ι] (b : Basis ι R S) (s : /-- If `x` is in the base ring `K`, then the norm is `x ^ [L : K]`. -/ theorem norm_algebraMap_of_basis [Fintype ι] (b : Basis ι R S) (x : R) : norm R (algebraMap R S x) = x ^ Fintype.card ι := by - haveI := Classical.decEq ι + have := Classical.decEq ι rw [norm_apply, ← det_toMatrix b, lmul_algebraMap] simp diff --git a/Mathlib/RingTheory/Norm/Transitivity.lean b/Mathlib/RingTheory/Norm/Transitivity.lean index 298a5e942acb68..88c2e96d9e241d 100644 --- a/Mathlib/RingTheory/Norm/Transitivity.lean +++ b/Mathlib/RingTheory/Norm/Transitivity.lean @@ -266,7 +266,7 @@ theorem norm_eq_prod_embeddings [Algebra.IsSeparable K L] [IsAlgClosed E] rw [norm_eq_norm_adjoin K x, map_pow, ← adjoin.powerBasis_gen hx, norm_eq_prod_embeddings_gen E (adjoin.powerBasis hx) (IsAlgClosed.splits _)] · exact (prod_embeddings_eq_finrank_pow L (L := K⟮x⟯) E (adjoin.powerBasis hx)).symm - · haveI := Algebra.isSeparable_tower_bot_of_isSeparable K K⟮x⟯ L + · have := Algebra.isSeparable_tower_bot_of_isSeparable K K⟮x⟯ L exact Algebra.IsSeparable.isSeparable K _ theorem norm_eq_prod_automorphisms [IsGalois K L] (x : L) : diff --git a/Mathlib/RingTheory/NormTrace.lean b/Mathlib/RingTheory/NormTrace.lean index c3b48a4a7c32f2..5d36a5568caa8a 100644 --- a/Mathlib/RingTheory/NormTrace.lean +++ b/Mathlib/RingTheory/NormTrace.lean @@ -22,7 +22,7 @@ lemma Algebra.norm_one_add_smul {A B} [CommRing A] [CommRing B] [Algebra A B] classical let ι := Module.Free.ChooseBasisIndex A B let b : Basis ι A B := Module.Free.chooseBasis _ _ - haveI : Fintype ι := inferInstance + have : Fintype ι := inferInstance clear_value ι b simp_rw [Algebra.norm_eq_matrix_det b, Algebra.trace_eq_matrix_trace b] simp only [map_add, map_one, map_smul, Matrix.det_one_add_smul a] diff --git a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean index fb8aabcebe768f..604572a1decf15 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean @@ -218,7 +218,7 @@ theorem ord_of_irreducible {ϖ : R} (hϖ : Irreducible ϖ) : ord R ϖ = 1 := by PrincipalIdealRing.isMaximal_of_irreducible hϖ rw [isSimpleModule_iff_isSimpleModule_of_algebraMap_surjective (S := R ⧸ Ideal.span {ϖ}) Ideal.Quotient.mk_surjective] - letI := Ideal.Quotient.field (Ideal.span {ϖ}) + let := Ideal.Quotient.field (Ideal.span {ϖ}) exact instIsSimpleModule _ end IsPrincipalIdealRing diff --git a/Mathlib/RingTheory/OreLocalization/Ring.lean b/Mathlib/RingTheory/OreLocalization/Ring.lean index b0baae937aea9f..b7435248b22793 100644 --- a/Mathlib/RingTheory/OreLocalization/Ring.lean +++ b/Mathlib/RingTheory/OreLocalization/Ring.lean @@ -99,7 +99,7 @@ instance {R₀} [Semiring R₀] [Module R₀ X] [Module R₀ R] lemma nsmul_eq_nsmul (n : ℕ) (x : X[S⁻¹]) : letI inst := OreLocalization.instModuleOfIsScalarTower (R₀ := ℕ) (R := R) (X := X) (S := S) HSMul.hSMul (self := @instHSMul _ _ inst.toSMul) n x = n • x := by - letI inst := OreLocalization.instModuleOfIsScalarTower (R₀ := ℕ) (R := R) (X := X) (S := S) + let inst := OreLocalization.instModuleOfIsScalarTower (R₀ := ℕ) (R := R) (X := X) (S := S) exact congr($(AddCommMonoid.uniqueNatModule.2 inst).smul n x) /-- The ring homomorphism from `R` to `R[S⁻¹]`, mapping `r : R` to the fraction `r /ₒ 1`. -/ @@ -185,7 +185,7 @@ instance : Ring R[S⁻¹] where lemma zsmul_eq_zsmul (n : ℤ) (x : X[S⁻¹]) : letI inst := OreLocalization.instModuleOfIsScalarTower (R₀ := ℤ) (R := R) (X := X) (S := S) HSMul.hSMul (self := @instHSMul _ _ inst.toSMul) n x = n • x := by - letI inst := OreLocalization.instModuleOfIsScalarTower (R₀ := ℤ) (R := R) (X := X) (S := S) + let inst := OreLocalization.instModuleOfIsScalarTower (R₀ := ℤ) (R := R) (X := X) (S := S) exact congr($(AddCommGroup.uniqueIntModule.2 inst).smul n x) open nonZeroDivisors diff --git a/Mathlib/RingTheory/OrzechProperty.lean b/Mathlib/RingTheory/OrzechProperty.lean index 8e6baa2b9e669a..facc0d1a7bd74d 100644 --- a/Mathlib/RingTheory/OrzechProperty.lean +++ b/Mathlib/RingTheory/OrzechProperty.lean @@ -80,11 +80,11 @@ theorem injective_of_surjective_of_injective {N : Type w} [AddCommMonoid N] [Module R N] (i f : N →ₗ[R] M) (hi : Injective i) (hf : Surjective f) : Injective f := by obtain ⟨n, g, hg⟩ := Module.Finite.exists_fin' R M - haveI := small_of_surjective hg - letI := Equiv.addCommMonoid (equivShrink M).symm - letI := Equiv.module R (equivShrink M).symm + have := small_of_surjective hg + let := Equiv.addCommMonoid (equivShrink M).symm + let := Equiv.module R (equivShrink M).symm let j : Shrink.{u} M ≃ₗ[R] M := Equiv.linearEquiv R (equivShrink M).symm - haveI := Module.Finite.equiv j.symm + have := Module.Finite.equiv j.symm let i' := j.symm.toLinearMap ∘ₗ i replace hi : Injective i' := by simpa [i'] using hi let f' := j.symm.toLinearMap ∘ₗ f ∘ₗ (LinearEquiv.ofInjective i' hi).symm.toLinearMap diff --git a/Mathlib/RingTheory/Perfection.lean b/Mathlib/RingTheory/Perfection.lean index a8705f4554fb14..c841ec2ffa7d45 100644 --- a/Mathlib/RingTheory/Perfection.lean +++ b/Mathlib/RingTheory/Perfection.lean @@ -809,8 +809,8 @@ include hv theorem isDomain : IsDomain (PreTilt O p) := by have hp : Nat.Prime p := Fact.out - haveI : Nontrivial (PreTilt O p) := ⟨(CharP.nontrivial_of_char_ne_one hp.ne_one).1⟩ - haveI : NoZeroDivisors (PreTilt O p) := + have : Nontrivial (PreTilt O p) := ⟨(CharP.nontrivial_of_char_ne_one hp.ne_one).1⟩ + have : NoZeroDivisors (PreTilt O p) := ⟨fun hfg => by simp_rw [← map_eq_zero hv] at hfg ⊢; contrapose! hfg; rw [Valuation.map_mul] exact mul_ne_zero hfg.1 hfg.2⟩ diff --git a/Mathlib/RingTheory/PiTensorProduct.lean b/Mathlib/RingTheory/PiTensorProduct.lean index df1663a1d5ae85..d83268dbd3e17c 100644 --- a/Mathlib/RingTheory/PiTensorProduct.lean +++ b/Mathlib/RingTheory/PiTensorProduct.lean @@ -276,9 +276,9 @@ noncomputable def constantBaseRingEquiv : (⨂[R] _ : ι, R) ≃ₐ[R] R := ((lift.tprod _).trans Finset.prod_const_one) (by -- one of these is required, the other is a performance optimization - letI : IsScalarTower R (⨂[R] x : ι, R) (⨂[R] x : ι, R) := + let : IsScalarTower R (⨂[R] x : ι, R) (⨂[R] x : ι, R) := IsScalarTower.right (R := R) (A := ⨂[R] (x : ι), R) - letI : SMulCommClass R (⨂[R] x : ι, R) (⨂[R] x : ι, R) := + let : SMulCommClass R (⨂[R] x : ι, R) (⨂[R] x : ι, R) := Algebra.to_smulCommClass (R := R) (A := ⨂[R] x : ι, R) rw [LinearMap.map_mul_iff] ext diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index ac7a2baaabd417..efa067a2e4aa17 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -813,7 +813,7 @@ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNo refine (mul_one _).symm.trans ?_ rw [← h, mul_zero] rfl - haveI : Nontrivial R := ⟨⟨0, 1, this⟩⟩ + have : Nontrivial R := ⟨⟨0, 1, this⟩⟩ have : p.leadingCoeff ∈ I.leadingCoeffNth N := by rw [HN] exact hm2 k ((I.mem_leadingCoeffNth _ _).2 diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean index 05e37ed8dd0363..91c2afa5a82764 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean @@ -517,7 +517,7 @@ theorem cyclotomic_prime_pow_eq_geom_sum {R : Type*} [CommRing R] {p n : ℕ} (h rw [eq_comm] at this rw [this, Nat.prod_properDivisors_prime_pow hp] induction n with - | zero => haveI := Fact.mk hp; simp [cyclotomic_prime] + | zero => have := Fact.mk hp; simp [cyclotomic_prime] | succ n_n n_ih => rw [← (eq_cyclotomic_iff (pow_pos hp.pos (n_n + 1 + 1)) _).mpr ?_] rw [Nat.prod_properDivisors_prime_pow hp, Finset.prod_range_succ, n_ih] diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean index eb538bb3c80dae..8171fbd7afb2de 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean @@ -50,7 +50,7 @@ theorem eval₂_one_cyclotomic_prime_pow {R S : Type*} [CommRing R] [Semiring S] private theorem cyclotomic_neg_one_pos {n : ℕ} (hn : 2 < n) {R} [CommRing R] [PartialOrder R] [IsStrictOrderedRing R] : 0 < eval (-1 : R) (cyclotomic n R) := by - haveI := NeZero.of_gt hn + have := NeZero.of_gt hn rw [← map_cyclotomic_int, ← Int.cast_one, ← Int.cast_neg, eval_intCast_map, Int.coe_castRingHom, Int.cast_pos] suffices 0 < eval (↑(-1 : ℤ)) (cyclotomic n ℝ) by @@ -146,7 +146,7 @@ theorem eval_one_cyclotomic_not_prime_pow {R : Type*} [Ring R] {n : ℕ} linarith [cyclotomic_nonneg n (le_refl (1 : ℤ))] rw [← Int.natAbs_eq_natAbs_iff, Int.natAbs_one, Nat.eq_one_iff_not_exists_prime_dvd] intro p hp hpe - haveI := Fact.mk hp + have := Fact.mk hp have := prod_cyclotomic_eq_geom_sum hn' ℤ apply_fun eval 1 at this rw [eval_geom_sum, one_geom_sum, eval_prod, eq_comm, ← diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean index 22a9397b02b9b3..d821b02c6576c1 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Expand.lean @@ -40,7 +40,7 @@ theorem cyclotomic_expand_eq_cyclotomic_mul {p n : ℕ} (hp : Nat.Prime p) (hdiv expand R p (cyclotomic n R) = cyclotomic (n * p) R * cyclotomic n R := by rcases Nat.eq_zero_or_pos n with (rfl | hnpos) · simp - haveI := NeZero.of_pos hnpos + have := NeZero.of_pos hnpos suffices expand ℤ p (cyclotomic n ℤ) = cyclotomic (n * p) ℤ * cyclotomic n ℤ by rw [← map_cyclotomic_int, ← map_expand, this, Polynomial.map_mul, map_cyclotomic_int, map_cyclotomic] @@ -88,7 +88,7 @@ theorem cyclotomic_expand_eq_cyclotomic {p n : ℕ} (hp : Nat.Prime p) (hdiv : p [CommRing R] : expand R p (cyclotomic n R) = cyclotomic (n * p) R := by rcases n.eq_zero_or_pos with (rfl | hzero) · simp - haveI := NeZero.of_pos hzero + have := NeZero.of_pos hzero suffices expand ℤ p (cyclotomic n ℤ) = cyclotomic (n * p) ℤ by rw [← map_cyclotomic_int, ← map_expand, this, map_cyclotomic_int] refine eq_of_monic_of_dvd_of_natDegree_le (cyclotomic.monic _ ℤ) @@ -130,7 +130,7 @@ section CharP `cyclotomic (n * p) R = (cyclotomic n R) ^ (p - 1)`. -/ theorem cyclotomic_mul_prime_eq_pow_of_not_dvd (R : Type*) {p n : ℕ} [hp : Fact (Nat.Prime p)] [Ring R] [CharP R p] (hn : ¬p ∣ n) : cyclotomic (n * p) R = cyclotomic n R ^ (p - 1) := by - letI : Algebra (ZMod p) R := ZMod.algebra _ _ + let : Algebra (ZMod p) R := ZMod.algebra _ _ suffices cyclotomic (n * p) (ZMod p) = cyclotomic n (ZMod p) ^ (p - 1) by rw [← map_cyclotomic _ (algebraMap (ZMod p) R), ← map_cyclotomic _ (algebraMap (ZMod p) R), this, Polynomial.map_pow] @@ -144,7 +144,7 @@ theorem cyclotomic_mul_prime_eq_pow_of_not_dvd (R : Type*) {p n : ℕ} [hp : Fac `cyclotomic (n * p) R = (cyclotomic n R) ^ p`. -/ theorem cyclotomic_mul_prime_dvd_eq_pow (R : Type*) {p n : ℕ} [hp : Fact (Nat.Prime p)] [Ring R] [CharP R p] (hn : p ∣ n) : cyclotomic (n * p) R = cyclotomic n R ^ p := by - letI : Algebra (ZMod p) R := ZMod.algebra _ _ + let : Algebra (ZMod p) R := ZMod.algebra _ _ suffices cyclotomic (n * p) (ZMod p) = cyclotomic n (ZMod p) ^ p by rw [← map_cyclotomic _ (algebraMap (ZMod p) R), ← map_cyclotomic _ (algebraMap (ZMod p) R), this, Polynomial.map_pow] diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Roots.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Roots.lean index 34cec1230f631d..c0f81b1c22540f 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Roots.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Roots.lean @@ -98,7 +98,7 @@ private theorem isRoot_cyclotomic_iff' {n : ℕ} {K : Type*} [Field K] {μ : K} theorem isRoot_cyclotomic_iff [NeZero (n : R)] {μ : R} : IsRoot (cyclotomic n R) μ ↔ IsPrimitiveRoot μ n := by have hf : Function.Injective _ := IsFractionRing.injective R (FractionRing R) - haveI : NeZero (n : FractionRing R) := NeZero.nat_of_injective hf + have : NeZero (n : FractionRing R) := NeZero.nat_of_injective hf rw [← isRoot_map_iff hf, ← IsPrimitiveRoot.map_iff_of_injective hf, map_cyclotomic, ← isRoot_cyclotomic_iff'] @@ -137,7 +137,7 @@ theorem cyclotomic_injective [CharZero R] : Function.Injective fun n => cyclotom · rw [cyclotomic_zero] at hnm replace hnm := congr_arg natDegree hnm rwa [natDegree_one, natDegree_cyclotomic, eq_comm, Nat.totient_eq_zero, eq_comm] at hnm - · haveI := NeZero.mk hzero + · have := NeZero.mk hzero rw [← map_cyclotomic_int _ R, ← map_cyclotomic_int _ R] at hnm replace hnm := map_injective (Int.castRingHom R) Int.cast_injective hnm replace hnm := congr_arg (map (Int.castRingHom ℂ)) hnm @@ -145,7 +145,7 @@ theorem cyclotomic_injective [CharZero R] : Function.Injective fun n => cyclotom have hprim := Complex.isPrimitiveRoot_exp _ hzero have hroot := isRoot_cyclotomic_iff (R := ℂ).2 hprim rw [hnm] at hroot - haveI hmzero : NeZero m := ⟨fun h => by simp [h] at hroot⟩ + have hmzero : NeZero m := ⟨fun h => by simp [h] at hroot⟩ rw [isRoot_cyclotomic_iff (R := ℂ)] at hroot replace hprim := hprim.eq_orderOf rwa [← IsPrimitiveRoot.eq_orderOf hroot] at hprim @@ -163,7 +163,7 @@ open IsPrimitiveRoot Complex theorem _root_.IsPrimitiveRoot.minpoly_eq_cyclotomic_of_irreducible {K : Type*} [Field K] {R : Type*} [CommRing R] [IsDomain R] {μ : R} {n : ℕ} [Algebra K R] (hμ : IsPrimitiveRoot μ n) (h : Irreducible <| cyclotomic n K) [NeZero (n : K)] : cyclotomic n K = minpoly K μ := by - haveI := NeZero.of_faithfulSMul K R n + have := NeZero.of_faithfulSMul K R n refine minpoly.eq_of_irreducible_of_monic h ?_ (cyclotomic.monic n K) rwa [aeval_def, eval₂_eq_eval_map, map_cyclotomic, ← IsRoot.def, isRoot_cyclotomic_iff] @@ -221,7 +221,7 @@ coefficients `αᵢ` are equal. This follows from the irreducibility of the `p`- polynomial. See de Launey–Flannery, *Algebraic Design Theory*, Lemma 2.8.5. -/ lemma sum_eq_zero_iff_forall_eq (hp : p.Prime) (hζ : IsPrimitiveRoot ζ p) (α : Fin p → ℚ) : ∑ i, α i * ζ ^ i.val = 0 ↔ ∀ i j, α i = α j := by - haveI : Fact p.Prime := ⟨hp⟩ + have : Fact p.Prime := ⟨hp⟩ let P : ℚ[X] := ∑ i, C (α i) * X ^ i.1 have hP (i : Fin p) : α i = P.coeff i := by simp [P, ← Fin.ext_iff] have hP' : P.degree ≤ ↑(p - 1) := diff --git a/Mathlib/RingTheory/Polynomial/Dickson.lean b/Mathlib/RingTheory/Polynomial/Dickson.lean index 99c6d0c632f322..d9f18bf30d1bac 100644 --- a/Mathlib/RingTheory/Polynomial/Dickson.lean +++ b/Mathlib/RingTheory/Polynomial/Dickson.lean @@ -211,7 +211,7 @@ theorem dickson_one_one_zmod_p (p : ℕ) [Fact p.Prime] : dickson 1 (1 : ZMod p) have : CharP K p := by rw [← f.charP_iff_charP] infer_instance - haveI : Infinite K := + have : Infinite K := Infinite.of_injective (algebraMap (Polynomial (ZMod p)) (FractionRing (Polynomial (ZMod p)))) (IsFractionRing.injective _ _) refine ⟨K, ?_, ?_, ?_⟩ <;> infer_instance diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean index f6c30922e9e39f..19a2573fd2b801 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean @@ -138,7 +138,7 @@ theorem dvd_coeff_zero_of_aeval_eq_prime_smul_of_minpoly_isEisensteinAt {B : Pow (hp : Prime p) (hBint : IsIntegral R B.gen) {z : L} {Q : R[X]} (hQ : aeval B.gen Q = p • z) (hzint : IsIntegral R z) (hei : (minpoly R B.gen).IsEisensteinAt 𝓟) : p ∣ Q.coeff 0 := by -- First define some abbreviations. - letI := B.finite + let := B.finite let P := minpoly R B.gen obtain ⟨n, hn⟩ := Nat.exists_eq_succ_of_ne_zero B.dim_pos.ne' have finrank_K_L : Module.finrank K L = B.dim := B.finrank diff --git a/Mathlib/RingTheory/Polynomial/RationalRoot.lean b/Mathlib/RingTheory/Polynomial/RationalRoot.lean index aac878274cb055..ce4be7bb114adf 100644 --- a/Mathlib/RingTheory/Polynomial/RationalRoot.lean +++ b/Mathlib/RingTheory/Polynomial/RationalRoot.lean @@ -69,7 +69,7 @@ then the numerator of `r` divides the constant coefficient -/ theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by simp only [coeff_scaleRoots] at this - haveI inst := Classical.propDecidable + have inst := Classical.propDecidable by_cases hr : num A r = 0 · simp_all [nonZeroDivisors.coe_ne_zero] · refine dvd_of_dvd_mul_left_of_no_prime_factors hr ?_ this diff --git a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean index 8ca60864c4d48a..6dfd433663cb7c 100644 --- a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean @@ -490,7 +490,7 @@ nonrec lemma resultant_eq_prod_eval [IsDomain R] by_cases hf0 : f = 0 · simp [hf0] wlog hfm : f.Monic - · letI inst := hR.toField + · let inst := hR.toField have H : (C f.leadingCoeff⁻¹ * f).Monic := by rw [Monic, ← coeff_natDegree, natDegree_C_mul (by simp [hf0]), coeff_C_mul]; simp [hf0] have := this (C f.leadingCoeff⁻¹ * f) g n hg (.mul (.C _) hf) hR (by simpa) H @@ -504,12 +504,12 @@ nonrec lemma resultant_eq_prod_eval [IsDomain R] · obtain ⟨r, rfl⟩ := hfm.natDegree_eq_zero.mp hf'; simp simp [← hf.natDegree_eq_card_roots, hf'] wlog hgm : g.Monic - · letI inst := hR.toField + · let inst := hR.toField have := this f (C g.leadingCoeff⁻¹ * g) n (by simpa [hg0, natDegree_C_mul]) hf hR hfm (by simpa) (by rw [Monic, ← coeff_natDegree, natDegree_C_mul (by simp [hg0]), coeff_C_mul]; simp [hg0]) rw [resultant_C_mul_right, inv_pow, inv_mul_eq_iff_eq_mul₀ (by simp [hg0])] at this simpa [← hf.natDegree_eq_card_roots, inv_pow, mul_left_comm (_ ^ g.natDegree), hg0] using this - letI inst := hR.toField + let inst := hR.toField let L := g.SplittingField apply (algebraMap R L).injective have := resultant_eq_prod_roots_sub (f.map (algebraMap R L)) @@ -545,10 +545,10 @@ nonrec lemma induction_of_Splits_of_injective_of_surjective.{u} · exact injective _ _ _ (FaithfulSMul.algebraMap_injective R (FractionRing R)) _ (this _ inferInstance (Field.toIsField _)) wlog hp : p.Splits generalizing R - · letI inst := hR.toField + · let inst := hR.toField exact injective _ _ _ (algebraMap R p.SplittingField).injective _ (this _ inferInstance (Field.toIsField _) (SplittingField.splits _)) - letI inst := hR.toField + let inst := hR.toField exact Splits _ _ hp /-- `Res(f, g₁ * g₂) = Res(f, g₁) * Res(f, g₂)`. -/ diff --git a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean index b6407237a13e81..f45711e135082e 100644 --- a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean +++ b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean @@ -66,7 +66,7 @@ theorem support_scaleRoots_eq (p : R[X]) {s : R} (hs : s ∈ nonZeroDivisors R) @[simp] theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by - haveI := Classical.propDecidable + have := Classical.propDecidable by_cases hp : p = 0 · rw [hp, zero_scaleRoots] refine le_antisymm (Finset.sup_mono (support_scaleRoots_le p s)) (degree_le_degree ?_) diff --git a/Mathlib/RingTheory/Polynomial/SeparableDegree.lean b/Mathlib/RingTheory/Polynomial/SeparableDegree.lean index 85c755c07fd0dc..7bf6632b6fcbae 100644 --- a/Mathlib/RingTheory/Polynomial/SeparableDegree.lean +++ b/Mathlib/RingTheory/Polynomial/SeparableDegree.lean @@ -131,7 +131,7 @@ theorem IsSeparableContraction.degree_eq [hF : ExpChar F q] (g : F[X]) · rcases hg with ⟨hg, m, hm⟩ let g' := Classical.choose hf obtain ⟨hg', m', hm'⟩ := Classical.choose_spec hf - haveI : Fact q.Prime := ⟨by assumption⟩ + have : Fact q.Prime := ⟨by assumption⟩ refine contraction_degree_eq_or_insep q g g' m m' ?_ hg hg' rw [hm, hm'] diff --git a/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean b/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean index 2c4bffb6833eac..4641cfdd30c492 100644 --- a/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean +++ b/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean @@ -90,7 +90,7 @@ open UniqueFactorizationMonoid namespace Polynomial instance (priority := 100) uniqueFactorizationMonoid : UniqueFactorizationMonoid D[X] := by - letI := Classical.arbitrary (NormalizedGCDMonoid D) + let := Classical.arbitrary (NormalizedGCDMonoid D) exact ufm_of_decomposition_of_wfDvdMonoid /-- If `D` is a unique factorization domain, `f` is a non-zero polynomial in `D[X]`, then `f` has diff --git a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean index cc868eaae619d9..647ddd0effbdf7 100644 --- a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean +++ b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean @@ -292,7 +292,7 @@ lemma universalFactorizationMapPresentation_jacobiMatrix : ((freeMonic R m).map (((mapAlgHom (Algebra.ofId _ _)).comp (rename Sum.inl)).toRingHom)) ((freeMonic R k).map (((mapAlgHom (Algebra.ofId _ _)).comp (rename Sum.inr)).toRingHom)) m k).reindex (finCongr (by lia)) (finCongr (by lia))).transpose := by - letI := (universalFactorizationMap R n m k hn).toAlgebra + let := (universalFactorizationMap R n m k hn).toAlgebra subst hn ext i j : 1 dsimp [Polynomial.sylvester] @@ -310,7 +310,7 @@ lemma universalFactorizationMapPresentation_jacobian : ((freeMonic R k).map Algebra.TensorProduct.includeRight.toRingHom)) := by cases subsingleton_or_nontrivial R · exact Subsingleton.elim _ _ - letI := (universalFactorizationMap R n m k hn).toAlgebra + let := (universalFactorizationMap R n m k hn).toAlgebra rw [Algebra.PreSubmersivePresentation.jacobian_eq_jacobiMatrix_det, MvPolynomial.universalFactorizationMapPresentation_jacobiMatrix] simp only [AlgHom.toRingHom_eq_coe, Matrix.det_neg, Matrix.det_transpose, Matrix.det_reindex_self, @@ -335,10 +335,10 @@ lemma finite_universalFactorizationMap : (universalFactorizationMap R n m k hn).Finite := by refine RingHom.IsIntegral.to_finite ?_ (.of_finitePresentation (finitePresentation_universalFactorizationMap R n m k hn)) - letI := (universalFactorizationMap R n m k hn).toAlgebra + let := (universalFactorizationMap R n m k hn).toAlgebra have : IsDomain (MvPolynomial (Fin m) ℤ ⊗[ℤ] MvPolynomial (Fin k) ℤ) := (MvPolynomial.tensorEquivSum ℤ (Fin m) (Fin k) ℤ).toRingEquiv.isDomain_iff.mpr inferInstance - letI := (universalFactorizationMap ℤ n m k hn).toAlgebra + let := (universalFactorizationMap ℤ n m k hn).toAlgebra let F : MvPolynomial (Fin m) ℤ ⊗[ℤ] MvPolynomial (Fin k) ℤ →ₐ[ℤ] MvPolynomial (Fin m) R ⊗[R] MvPolynomial (Fin k) R := Algebra.TensorProduct.lift @@ -417,8 +417,8 @@ def UniversalFactorizationRing.fromTensor : lemma UniversalFactorizationRing.fromTensor_comp_universalFactorizationMap : (fromTensor m k hn p).comp (MvPolynomial.universalFactorizationMap R n m k hn) = (Algebra.ofId R _).comp ((MvPolynomial.mapEquivMonic R _ n).symm p) := by - letI := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra - letI := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra + let := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra + let := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra exact AlgHom.ext fun x ↦ (Algebra.TensorProduct.tmul_one_eq_one_tmul x).symm lemma UniversalFactorizationRing.fromTensor_comp_universalFactorizationMap' : @@ -465,10 +465,10 @@ def UniversalFactorizationRing.homEquiv : commutes' r := congr($(f.2) r).trans (by simp [MvPolynomial.mapEquivMonic_symm_map_algebraMap]; rfl) } fun _ _ ↦ .all _ _ left_inv f := by - letI := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra - letI := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra - letI := Algebra.compHom S ((MvPolynomial.mapEquivMonic R _ n).symm p).toRingHom - haveI : IsScalarTower (MvPolynomial (Fin n) R) R S := .of_algebraMap_eq' rfl + let := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra + let := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra + let := Algebra.compHom S ((MvPolynomial.mapEquivMonic R _ n).symm p).toRingHom + have : IsScalarTower (MvPolynomial (Fin n) R) R S := .of_algebraMap_eq' rfl have : IsScalarTower R (MvPolynomial (Fin n) R) S := .of_algebraMap_eq fun r ↦ by simp [Algebra.compHom_algebraMap_apply] refine Algebra.TensorProduct.ext (by ext) ?_ @@ -478,8 +478,8 @@ def UniversalFactorizationRing.homEquiv : · ext; simp [MvPolynomial.universalFactorizationMapLiftEquiv, MvPolynomial.mapEquivMonic, UniversalFactorizationRing.factor₂, coeff_freeMonic]; rfl right_inv q := by - letI := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra - letI := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra + let := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra + let := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra simp only [UniversalFactorizationRing, MvPolynomial.mapEquivMonic, AlgHom.toRingHom_eq_coe, Equiv.coe_fn_symm_mk, MvPolynomial.coe_aeval_eq_eval, factor₁, MvPolynomial.universalFactorizationMapLiftEquiv, Equiv.coe_fn_mk, fromTensor, factor₂] @@ -518,8 +518,8 @@ lemma UniversalFactorizationRing.jacobian_resentation : · dsimp [UniversalFactorizationRing]; exact Subsingleton.elim _ _ cases subsingleton_or_nontrivial R · dsimp [UniversalFactorizationRing]; exact Subsingleton.elim _ _ - letI := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra - letI := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra + let := (MvPolynomial.universalFactorizationMap R n m k hn).toAlgebra + let := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra refine (Algebra.PreSubmersivePresentation.baseChange_jacobian _ _).trans ?_ change fromTensor _ _ _ _ _ = _ rw [MvPolynomial.universalFactorizationMapPresentation_jacobian] diff --git a/Mathlib/RingTheory/PowerSeries/Substitution.lean b/Mathlib/RingTheory/PowerSeries/Substitution.lean index 594ec0f9357e8b..388287f3320eff 100644 --- a/Mathlib/RingTheory/PowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/PowerSeries/Substitution.lean @@ -540,7 +540,7 @@ lemma coeff_one_substInv : P.substInv.coeff 1 = ⅟(P.coeff 1) := by include hP in lemma subst_substInv_left : P.substInv.subst P = X := by - haveI : Invertible (P.substInv.coeff 1) := by simpa using invertibleInvOf + have : Invertible (P.substInv.coeff 1) := by simpa using invertibleInvOf let Q := P.substInv.substInv have hQ : HasSubst Q := HasSubst.substInv P.substInv have eq_aux : P.substInv.subst Q = X := subst_substInv_right P.substInv P.constantCoeff_substInv @@ -580,18 +580,18 @@ lemma HasSubst.substInvOfIsUnit : HasSubst (P.substInvOfIsUnit hP') := by @[simp] lemma coeff_one_substInvOfIsUnit : (P.substInvOfIsUnit hP').coeff 1 = hP'.unit⁻¹ := by - letI := hP'.invertible + let := hP'.invertible rw [substInvOfIsUnit_eq_substInv, coeff_one_substInv] exact Units.mul_eq_one_iff_eq_inv.mp Invertible.invOf_mul_self include hP in lemma subst_substInvOfIsUnit_right : P.subst (substInvOfIsUnit P hP') = X := by - letI := hP'.invertible + let := hP'.invertible rw [P.substInvOfIsUnit_eq_substInv hP', P.subst_substInv_right hP] include hP in lemma subst_substInvOfIsUnit_left : (P.substInvOfIsUnit hP').subst P = X := by - letI := hP'.invertible + let := hP'.invertible rw [P.substInvOfIsUnit_eq_substInv hP', P.subst_substInv_left hP] end IsUnit diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index a06cd2ff1b50bb..de51fc451d10c5 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -482,7 +482,7 @@ theorem Prime.coprime_iff_not_dvd {p n : R} (hp : Prime p) : IsCoprime p n ↔ theorem exists_associated_pow_of_mul_eq_pow' {a b c : R} (hab : IsCoprime a b) {k : ℕ} (h : a * b = c ^ k) : ∃ d : R, Associated (d ^ k) a := by classical - letI := IsBezout.toGCDDomain R + let := IsBezout.toGCDDomain R exact exists_associated_pow_of_mul_eq_pow ((gcd_isUnit_iff _ _).mpr hab) h theorem exists_associated_pow_of_associated_pow_mul {a b c : R} (hab : IsCoprime a b) {k : ℕ} diff --git a/Mathlib/RingTheory/RingHom/Finite.lean b/Mathlib/RingTheory/RingHom/Finite.lean index 0f28149a7f48b5..d1cb1140d4587e 100644 --- a/Mathlib/RingTheory/RingHom/Finite.lean +++ b/Mathlib/RingTheory/RingHom/Finite.lean @@ -63,10 +63,10 @@ variable [Algebra R R'] [Algebra S S'] /-- If `S` is a finite `R`-algebra, then `S' = M⁻¹S` is a finite `R' = M⁻¹R`-algebra. -/ theorem RingHom.finite_localizationPreserves : RingHom.LocalizationPreserves @RingHom.Finite := by introv R hf - letI := f.toAlgebra - letI := ((algebraMap S S').comp f).toAlgebra + let := f.toAlgebra + let := ((algebraMap S S').comp f).toAlgebra let f' : R' →+* S' := IsLocalization.map S' f (Submonoid.le_comap_map M) - letI := f'.toAlgebra + let := f'.toAlgebra have : IsScalarTower R R' S' := IsScalarTower.of_algebraMap_eq' (IsLocalization.map_comp M.le_comap_map).symm have : IsScalarTower R S S' := IsScalarTower.of_algebraMap_eq' rfl @@ -88,12 +88,12 @@ theorem RingHom.finite_ofLocalizationSpan : RingHom.OfLocalizationSpan @RingHom. rw [RingHom.ofLocalizationSpan_iff_finite] introv R hs H -- We first setup the instances - letI := f.toAlgebra - letI := fun r : s => (Localization.awayMap f r).toAlgebra + let := f.toAlgebra + let := fun r : s => (Localization.awayMap f r).toAlgebra have (r : s) : IsLocalization ((Submonoid.powers (r : R)).map (algebraMap R S)) (Localization.Away (f r)) := by rw [Submonoid.map_powers]; exact Localization.isLocalization - haveI : ∀ r : s, IsScalarTower R (Localization.Away (r : R)) (Localization.Away (f r)) := + have : ∀ r : s, IsScalarTower R (Localization.Away (r : R)) (Localization.Away (f r)) := fun r => IsScalarTower.of_algebraMap_eq' (IsLocalization.map_comp (Submonoid.powers (r : R)).le_comap_map).symm -- By the hypothesis, we may find a finite generating set for each `Sᵣ`. This set can then be diff --git a/Mathlib/RingTheory/RingHom/Integral.lean b/Mathlib/RingTheory/RingHom/Integral.lean index 2ff7ff779b31bd..495900ac63e75d 100644 --- a/Mathlib/RingTheory/RingHom/Integral.lean +++ b/Mathlib/RingTheory/RingHom/Integral.lean @@ -44,12 +44,12 @@ open Polynomial in theorem isIntegral_ofLocalizationSpan : OfLocalizationSpan (RingHom.IsIntegral ·) := by introv R hs H r - letI := f.toAlgebra + let := f.toAlgebra change r ∈ (integralClosure R S).toSubmodule apply Submodule.mem_of_span_eq_top_of_smul_pow_mem _ s hs rintro ⟨t, ht⟩ - letI := (Localization.awayMap f t).toAlgebra - haveI : IsScalarTower R (Localization.Away t) (Localization.Away (f t)) := .of_algebraMap_eq' + let := (Localization.awayMap f t).toAlgebra + have : IsScalarTower R (Localization.Away t) (Localization.Away (f t)) := .of_algebraMap_eq' (IsLocalization.lift_comp _).symm have : _root_.IsIntegral (Localization.Away t) (algebraMap S (Localization.Away (f t)) r) := H ⟨t, ht⟩ (algebraMap _ _ r) diff --git a/Mathlib/RingTheory/RingHom/Locally.lean b/Mathlib/RingTheory/RingHom/Locally.lean index cc1a4f61fe5336..12c4aefc52ef3c 100644 --- a/Mathlib/RingTheory/RingHom/Locally.lean +++ b/Mathlib/RingTheory/RingHom/Locally.lean @@ -160,7 +160,7 @@ lemma locally_ofLocalizationSpanTarget (hP : RespectsIso P) : refine ⟨(a : s) × t a, IsLocalization.Away.mulNumerator s t, IsLocalization.Away.span_range_mulNumerator_eq_top hsone htone, fun ⟨a, b⟩ ↦ Localization.Away b.val, inferInstance, inferInstance, fun ⟨a, b⟩ ↦ ?_, ?_⟩ - · haveI : IsLocalization.Away ((algebraMap S (Localization.Away a.val)) + · have : IsLocalization.Away ((algebraMap S (Localization.Away a.val)) (IsLocalization.Away.sec a.val b.val).1) (Localization.Away b.val) := by apply IsLocalization.Away.of_associated (r := b.val) rw [← IsLocalization.Away.sec_spec] @@ -202,7 +202,7 @@ lemma locally_holdsForLocalizationAway (hPa : HoldsForLocalizationAway P) : simp only [Set.mem_singleton_iff, forall_eq, Ideal.span_singleton_one, exists_const] let e : S ≃ₐ[R] (Localization.Away (1 : S)) := (IsLocalization.atUnits S (Submonoid.powers 1) (by simp)).restrictScalars R - haveI : IsLocalization.Away r (Localization.Away (1 : S)) := + have : IsLocalization.Away r (Localization.Away (1 : S)) := IsLocalization.isLocalization_of_algEquiv (Submonoid.powers r) e rw [← IsScalarTower.algebraMap_eq] apply hPa _ r @@ -254,18 +254,18 @@ lemma locally_stableUnderCompositionWithLocalizationAwayTarget refine ⟨algebraMap S T '' s, ?_, ?_⟩ · rw [← Ideal.map_span, hsone, Ideal.map_top] · rintro - ⟨a, ha, rfl⟩ - letI : Algebra (Localization.Away a) (Localization.Away (algebraMap S T a)) := + let : Algebra (Localization.Away a) (Localization.Away (algebraMap S T a)) := (IsLocalization.Away.map _ _ (algebraMap S T) a).toAlgebra have : (algebraMap (Localization.Away a) (Localization.Away (algebraMap S T a))).comp (algebraMap S (Localization.Away a)) = (algebraMap T (Localization.Away (algebraMap S T a))).comp (algebraMap S T) := by simp [algebraMap_toAlgebra, IsLocalization.Away.map] rw [← comp_assoc, ← this, comp_assoc] - haveI : IsScalarTower S (Localization.Away a) (Localization.Away ((algebraMap S T) a)) := by + have : IsScalarTower S (Localization.Away a) (Localization.Away ((algebraMap S T) a)) := by apply IsScalarTower.of_algebraMap_eq intro x simp [algebraMap_toAlgebra, IsLocalization.Away.map, ← IsScalarTower.algebraMap_apply] - haveI : IsLocalization.Away (algebraMap S (Localization.Away a) t) + have : IsLocalization.Away (algebraMap S (Localization.Away a) t) (Localization.Away (algebraMap S T a)) := IsLocalization.Away.commutes _ T ((Localization.Away (algebraMap S T a))) a t apply hPa _ (algebraMap S (Localization.Away a) t) @@ -312,19 +312,19 @@ lemma locally_localizationAwayPreserves (hPl : LocalizationAwayPreserves P) : rw [locally_iff_exists hPl.respectsIso] let rₐ (a : s) : Localization.Away a.val := algebraMap _ _ (f r) let Sₐ (a : s) := Localization.Away (rₐ a) - haveI (a : s) : + have (a : s) : IsLocalization.Away (((algebraMap S (Localization.Away a.val)).comp f) r) (Sₐ a) := inferInstanceAs (IsLocalization.Away (rₐ a) (Sₐ a)) - haveI (a : s) : IsLocalization (Algebra.algebraMapSubmonoid (Localization.Away a.val) + have (a : s) : IsLocalization (Algebra.algebraMapSubmonoid (Localization.Away a.val) (Submonoid.map f (Submonoid.powers r))) (Sₐ a) := by convert! (inferInstance : IsLocalization.Away (rₐ a) (Sₐ a)) simp [rₐ, Algebra.algebraMapSubmonoid] have H (a : s) : Submonoid.powers (f r) ≤ (Submonoid.powers (rₐ a)).comap (algebraMap S (Localization.Away a.val)) := by simp [rₐ, Submonoid.powers_le] - letI (a : s) : Algebra S' (Sₐ a) := + let (a : s) : Algebra S' (Sₐ a) := (IsLocalization.map (Sₐ a) (algebraMap S (Localization.Away a.val)) (H a)).toAlgebra - haveI (a : s) : IsScalarTower S S' (Sₐ a) := + have (a : s) : IsScalarTower S S' (Sₐ a) := IsScalarTower.of_algebraMap_eq' (IsLocalization.map_comp (H a)).symm refine ⟨s, fun a ↦ algebraMap S S' a.val, ?_, Sₐ, inferInstance, inferInstance, fun a ↦ ?_, fun a ↦ ?_⟩ @@ -347,17 +347,17 @@ lemma locally_localizationPreserves (hPl : LocalizationPreserves P) : let Sₐ (a : s) := Localization (Mₐ a) have hM (a : s) : M.map ((algebraMap S (Localization.Away a.val)).comp f) = Mₐ a := (M.map_map _ _).symm - haveI (a : s) : + have (a : s) : IsLocalization (M.map ((algebraMap S (Localization.Away a.val)).comp f)) (Sₐ a) := by rw [hM] infer_instance - haveI (a : s) : + have (a : s) : IsLocalization (Algebra.algebraMapSubmonoid (Localization.Away a.val) (M.map f)) (Sₐ a) := inferInstanceAs <| IsLocalization (Mₐ a) (Sₐ a) - letI (a : s) : Algebra S' (Sₐ a) := + let (a : s) : Algebra S' (Sₐ a) := (IsLocalization.map (Sₐ a) (algebraMap S (Localization.Away a.val)) (M.map f).le_comap_map).toAlgebra - haveI (a : s) : IsScalarTower S S' (Sₐ a) := + have (a : s) : IsScalarTower S S' (Sₐ a) := IsScalarTower.of_algebraMap_eq' (IsLocalization.map_comp (M.map f).le_comap_map).symm refine ⟨s, fun a ↦ algebraMap S S' a.val, ?_, Sₐ, inferInstance, inferInstance, fun a ↦ ?_, fun a ↦ ?_⟩ diff --git a/Mathlib/RingTheory/RingHom/Surjective.lean b/Mathlib/RingTheory/RingHom/Surjective.lean index 96a4740065392f..9b8437a99e13a8 100644 --- a/Mathlib/RingTheory/RingHom/Surjective.lean +++ b/Mathlib/RingTheory/RingHom/Surjective.lean @@ -70,7 +70,7 @@ theorem surjective_localizationPreserves : theorem surjective_ofLocalizationSpan : OfLocalizationSpan surjective := by introv R e H rw [← Set.range_eq_univ, Set.eq_univ_iff_forall] - letI := f.toAlgebra + let := f.toAlgebra intro x apply Submodule.mem_of_span_eq_top_of_smul_pow_mem (LinearMap.range (Algebra.linearMap R S)) s e diff --git a/Mathlib/RingTheory/RingHom/Unramified.lean b/Mathlib/RingTheory/RingHom/Unramified.lean index bd73f63ea5d797..04d1583687db14 100644 --- a/Mathlib/RingTheory/RingHom/Unramified.lean +++ b/Mathlib/RingTheory/RingHom/Unramified.lean @@ -85,7 +85,7 @@ lemma ofLocalizationPrime : intro x let Rₓ := Localization.AtPrime (x.asIdeal.comap f) let Sₓ := Localization.AtPrime x.asIdeal - letI : Algebra Rₓ Sₓ := (Localization.localRingHom _ _ _ rfl).toAlgebra + let : Algebra Rₓ Sₓ := (Localization.localRingHom _ _ _ rfl).toAlgebra have : IsScalarTower R Rₓ Sₓ := .of_algebraMap_eq fun x ↦ (Localization.localRingHom_to_map _ _ _ rfl x).symm have : Algebra.FormallyUnramified Rₓ Sₓ := H _ _ diff --git a/Mathlib/RingTheory/RingHomProperties.lean b/Mathlib/RingTheory/RingHomProperties.lean index 84c8c5b3541f61..45359262e1ec24 100644 --- a/Mathlib/RingTheory/RingHomProperties.lean +++ b/Mathlib/RingTheory/RingHomProperties.lean @@ -166,8 +166,8 @@ set_option backward.isDefEq.respectTransparency false in theorem IsStableUnderBaseChange.pushout_inl (hP : RingHom.IsStableUnderBaseChange @P) (hP' : RingHom.RespectsIso @P) {R S T : CommRingCat} (f : R ⟶ S) (g : R ⟶ T) (H : P g.hom) : P (pushout.inl _ _ : S ⟶ pushout f g).hom := by - letI := f.hom.toAlgebra - letI := g.hom.toAlgebra + let := f.hom.toAlgebra + let := g.hom.toAlgebra rw [← show _ = pushout.inl f g from colimit.isoColimitCocone_ι_inv ⟨_, CommRingCat.pushoutCoconeIsColimit R S T⟩ WalkingSpan.left, CommRingCat.hom_comp, hP'.cancel_right_isIso] diff --git a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean index ea33f168a34ee2..0fe84cca67fdf1 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean @@ -78,7 +78,7 @@ theorem minpoly_dvd_expand {p : ℕ} (hdiv : ¬p ∣ n) : minpoly ℤ μ ∣ expand ℤ p (minpoly ℤ (μ ^ p)) := by rcases n.eq_zero_or_pos with (rfl | hpos) · simp_all - letI : IsIntegrallyClosed ℤ := GCDMonoid.toIsIntegrallyClosed + let : IsIntegrallyClosed ℤ := GCDMonoid.toIsIntegrallyClosed refine minpoly.isIntegrallyClosed_dvd (h.isIntegral hpos) ?_ rw [aeval_def, coe_expand, ← comp, eval₂_eq_eval_map, map_comp, Polynomial.map_pow, map_X, eval_comp, eval_X_pow, ← eval₂_eq_eval_map, ← aeval_def] @@ -174,7 +174,7 @@ theorem minpoly_eq_pow_coprime {m : ℕ} (hcop : Nat.Coprime m n) : rw [hind h (Nat.Coprime.coprime_mul_left hcop)]; clear hind replace hprime := hprime.nat_prime have hdiv := (Nat.Prime.coprime_iff_not_dvd hprime).1 (Nat.Coprime.coprime_mul_right hcop) - haveI := Fact.mk hprime + have := Fact.mk hprime rw [minpoly_eq_pow (h.pow_of_coprime a (Nat.Coprime.coprime_mul_left hcop)) hdiv] congr 1 ring diff --git a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean index 7195f3618a935e..dbe8ecc7c6226a 100644 --- a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean +++ b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean @@ -523,7 +523,7 @@ theorem zpowers_eq {k : ℕ} [NeZero k] {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) : lemma map_rootsOfUnity {S F} [CommRing S] [IsDomain S] [FunLike F R S] [MonoidHomClass F R S] {ζ : R} {n : ℕ} [NeZero n] (hζ : IsPrimitiveRoot ζ n) {f : F} (hf : Function.Injective f) : (rootsOfUnity n R).map (Units.map f) = rootsOfUnity n S := by - letI : CommMonoid Sˣ := inferInstance + let : CommMonoid Sˣ := inferInstance replace hζ := hζ.isUnit_unit NeZero.out rw [← hζ.zpowers_eq, ← (hζ.map_of_injective (Units.map_injective (f := (f : R →* S)) hf)).zpowers_eq, diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index 7b19346c53fe5f..232a3e877e6c25 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -445,7 +445,7 @@ open LinearMap in /-- A finite product of semisimple rings is semisimple. -/ instance {ι} [Finite ι] (R : ι → Type*) [Π i, Ring (R i)] [∀ i, IsSemisimpleRing (R i)] : IsSemisimpleRing (Π i, R i) := by - letI _ (i) : Module (Π i, R i) (R i) := Module.compHom _ (Pi.evalRingHom R i) + let _ (i) : Module (Π i, R i) (R i) := Module.compHom _ (Pi.evalRingHom R i) let e (i) : R i →ₛₗ[Pi.evalRingHom R i] R i := { AddMonoidHom.id (R i) with map_smul' := fun _ _ ↦ rfl } have (i : _) : IsSemisimpleModule (Π i, R i) (R i) := @@ -455,8 +455,8 @@ instance {ι} [Finite ι] (R : ι → Type*) [Π i, Ring (R i)] [∀ i, IsSemisi set_option backward.isDefEq.respectTransparency false in /-- A binary product of semisimple rings is semisimple. -/ instance [hR : IsSemisimpleRing R] [hS : IsSemisimpleRing S] : IsSemisimpleRing (R × S) := by - letI : Module (R × S) R := Module.compHom _ (.fst R S) - letI : Module (R × S) S := Module.compHom _ (.snd R S) + let : Module (R × S) R := Module.compHom _ (.fst R S) + let : Module (R × S) S := Module.compHom _ (.snd R S) -- e₁, e₂ got falsely flagged by the unused argument linter let _e₁ : R →ₛₗ[.fst R S] R := { AddMonoidHom.id R with map_smul' := fun _ _ ↦ rfl } let _e₂ : S →ₛₗ[.snd R S] S := { AddMonoidHom.id S with map_smul' := fun _ _ ↦ rfl } @@ -468,8 +468,8 @@ instance [hR : IsSemisimpleRing R] [hS : IsSemisimpleRing S] : IsSemisimpleRing theorem RingHom.isSemisimpleRing_of_surjective (f : R →+* S) (hf : Function.Surjective f) [IsSemisimpleRing R] : IsSemisimpleRing S := by - letI : Module R S := Module.compHom _ f - haveI : RingHomSurjective f := ⟨hf⟩ + let : Module R S := Module.compHom _ f + have : RingHomSurjective f := ⟨hf⟩ let e : S →ₛₗ[f] S := { AddMonoidHom.id S with map_smul' := fun _ _ ↦ rfl } rw [IsSemisimpleRing, ← e.isSemisimpleModule_iff_of_bijective Function.bijective_id] infer_instance diff --git a/Mathlib/RingTheory/Smooth/Basic.lean b/Mathlib/RingTheory/Smooth/Basic.lean index ed53c3ad419b47..15140cc011e956 100644 --- a/Mathlib/RingTheory/Smooth/Basic.lean +++ b/Mathlib/RingTheory/Smooth/Basic.lean @@ -332,7 +332,7 @@ Geometric intuition: we require that a first-order thickening of `Spec A` inside a retraction. -/ theorem iff_split_surjection (f : P →ₐ[R] A) (hf : Function.Surjective f) : FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by - letI := f.toAlgebra + let := f.toAlgebra rw [iff_split_injection hf, ← nonempty_subtype, ← nonempty_subtype, (retractionKerCotangentToTensorEquivSection hf).nonempty_congr] rfl @@ -410,7 +410,7 @@ variable (B : Type*) [CommRing B] [Algebra R B] [Algebra A B] [IsScalarTower R A theorem comp [FormallySmooth R A] [FormallySmooth A B] : FormallySmooth R B := by refine .of_comp_surjective fun C _ _ I hI f ↦ ?_ obtain ⟨f', e⟩ := FormallySmooth.comp_surjective _ _ I hI (f.comp (IsScalarTower.toAlgHom R A B)) - letI := f'.toRingHom.toAlgebra + let := f'.toRingHom.toAlgebra obtain ⟨f'', e'⟩ := comp_surjective _ _ I hI { f with commutes' := AlgHom.congr_fun e.symm } apply_fun AlgHom.restrictScalars R at e' exact ⟨f''.restrictScalars _, e'.trans (AlgHom.ext fun _ => rfl)⟩ @@ -460,8 +460,8 @@ variable (B : Type*) [CommRing B] [Algebra R B] instance [FormallySmooth R A] : FormallySmooth B (B ⊗[R] A) := by refine .of_comp_surjective fun C _ _ I hI f ↦ ?_ - letI := ((algebraMap B C).comp (algebraMap R B)).toAlgebra - haveI : IsScalarTower R B C := IsScalarTower.of_algebraMap_eq' rfl + let := ((algebraMap B C).comp (algebraMap R B)).toAlgebra + have : IsScalarTower R B C := IsScalarTower.of_algebraMap_eq' rfl refine ⟨TensorProduct.productLeftAlgHom (Algebra.ofId B C) ?_, ?_⟩ · exact FormallySmooth.lift I ⟨2, hI⟩ ((f.restrictScalars R).comp TensorProduct.includeRight) · apply AlgHom.restrictScalars_injective R @@ -502,8 +502,8 @@ instance [FormallySmooth R A] (M : Submonoid A) : FormallySmooth R (Localization theorem localization_base [FormallySmooth R Sₘ] : FormallySmooth Rₘ Sₘ := by refine .of_comp_surjective fun Q _ _ I e f ↦ ?_ - letI := ((algebraMap Rₘ Q).comp (algebraMap R Rₘ)).toAlgebra - letI : IsScalarTower R Rₘ Q := IsScalarTower.of_algebraMap_eq' rfl + let := ((algebraMap Rₘ Q).comp (algebraMap R Rₘ)).toAlgebra + let : IsScalarTower R Rₘ Q := IsScalarTower.of_algebraMap_eq' rfl let f : Sₘ →ₐ[Rₘ] Q := by refine { FormallySmooth.lift I ⟨2, e⟩ (f.restrictScalars R) with commutes' := ?_ } intro r @@ -521,8 +521,8 @@ theorem localization_base [FormallySmooth R Sₘ] : FormallySmooth Rₘ Sₘ := simp [f] theorem localization_map [FormallySmooth R A] : FormallySmooth Rₘ Sₘ := by - haveI : FormallySmooth A Sₘ := FormallySmooth.of_isLocalization (M.map (algebraMap R A)) - haveI : FormallySmooth R Sₘ := FormallySmooth.comp R A Sₘ + have : FormallySmooth A Sₘ := FormallySmooth.of_isLocalization (M.map (algebraMap R A)) + have : FormallySmooth R Sₘ := FormallySmooth.comp R A Sₘ exact FormallySmooth.localization_base M end Localization diff --git a/Mathlib/RingTheory/Smooth/Kaehler.lean b/Mathlib/RingTheory/Smooth/Kaehler.lean index a183f5d5c81e51..ab6c8d22956433 100644 --- a/Mathlib/RingTheory/Smooth/Kaehler.lean +++ b/Mathlib/RingTheory/Smooth/Kaehler.lean @@ -88,7 +88,7 @@ include hf' hg lemma isScalarTower_of_section_of_ker_sqZero : letI := g.toRingHom.toAlgebra; IsScalarTower P S (RingHom.ker (algebraMap P S)) := by - letI := g.toRingHom.toAlgebra + let := g.toRingHom.toAlgebra constructor intro p s m ext @@ -116,8 +116,8 @@ def retractionOfSectionOfKerSqZero : S ⊗[P] Ω[P⁄R] →ₗ[P] RingHom.ker (a lemma retractionOfSectionOfKerSqZero_tmul_D (s : S) (t : P) : retractionOfSectionOfKerSqZero g hf' hg (s ⊗ₜ .D _ _ t) = g s * t - g s * g (algebraMap _ _ t) := by - letI := g.toRingHom.toAlgebra - haveI := isScalarTower_of_section_of_ker_sqZero g hf' hg + let := g.toRingHom.toAlgebra + have := isScalarTower_of_section_of_ker_sqZero g hf' hg simp only [retractionOfSectionOfKerSqZero, LinearMap.coe_restrictScalars, LinearMap.liftBaseChange_tmul, SetLike.val_smul_of_tower] -- The issue is a mismatch between `RingHom.ker (algebraMap P S)` and @@ -376,7 +376,7 @@ lemma CotangentSpace.map_toInfinitesimal_bijective (P : Extension.{u} R S) : suffices CotangentSpace.map P.toInfinitesimal = (tensorKaehlerQuotKerSqEquiv _ _ _).symm.toLinearMap by rw [this]; exact (tensorKaehlerQuotKerSqEquiv _ _ _).symm.bijective - letI : Algebra P.Ring P.infinitesimal.Ring := inferInstanceAs (Algebra P.Ring (P.Ring ⧸ _)) + let : Algebra P.Ring P.infinitesimal.Ring := inferInstanceAs (Algebra P.Ring (P.Ring ⧸ _)) have : IsScalarTower P.Ring P.infinitesimal.Ring S := .of_algebraMap_eq' rfl apply LinearMap.restrictScalars_injective P.Ring ext x a diff --git a/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean b/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean index ae194ff26df03b..e793f5a4f983c4 100644 --- a/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean +++ b/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean @@ -329,7 +329,7 @@ instance IsStandardSmoothOfRelativeDimension.subsingleton_kaehlerDifferential [IsStandardSmoothOfRelativeDimension 0 R S] : Subsingleton Ω[S⁄R] := by cases subsingleton_or_nontrivial S · exact Module.subsingleton S _ - haveI : IsStandardSmooth R S := IsStandardSmoothOfRelativeDimension.isStandardSmooth 0 + have : IsStandardSmooth R S := IsStandardSmoothOfRelativeDimension.isStandardSmooth 0 exact Module.subsingleton_of_rank_zero (IsStandardSmoothOfRelativeDimension.rank_kaehlerDifferential 0) diff --git a/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean b/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean index 0bd9b1d81f856c..a52be8b7ec9824 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean @@ -91,7 +91,7 @@ lemma comap_freeLocus_le {A} [CommRing A] [Algebra R A] : let Aₚ := Localization.AtPrime p.asIdeal rw [Set.mem_preimage, mem_freeLocus_iff_tensor _ Rₚ] at hp rw [mem_freeLocus_iff_tensor _ Aₚ] - letI algebra : Algebra Rₚ Aₚ := (Localization.localRingHom + let algebra : Algebra Rₚ Aₚ := (Localization.localRingHom (comap (algebraMap R A) p).asIdeal p.asIdeal (algebraMap R A) rfl).toAlgebra have : IsScalarTower R Rₚ Aₚ := IsScalarTower.of_algebraMap_eq' (by simp [Rₚ, Aₚ, algebra, RingHom.algebraMap_toAlgebra, Localization.localRingHom, @@ -110,7 +110,7 @@ lemma freeLocus_localization (S : Submonoid R) : p.isPrime.ne_top (Ideal.eq_top_of_isUnit_mem _ H (IsLocalization.map_units _ ⟨x, hx⟩)) let Rₚ := Localization.AtPrime p' let Mₚ := LocalizedModule p'.primeCompl M - letI : Algebra (Localization S) Rₚ := + let : Algebra (Localization S) Rₚ := IsLocalization.localizationAlgebraOfSubmonoidLe _ _ S p'.primeCompl hp' have : IsScalarTower R (Localization S) Rₚ := IsLocalization.localization_isScalarTower_of_submonoid_le .. @@ -124,7 +124,7 @@ lemma freeLocus_localization (S : Submonoid R) : refine ⟨algebraMap _ _ s.1, x, fun H ↦ hx ?_, by simp⟩ rw [IsLocalization.mk'_eq_mul_mk'_one] exact Ideal.mul_mem_right _ _ H - letI : Module (Localization S) Mₚ := Module.compHom Mₚ (algebraMap _ Rₚ) + let : Module (Localization S) Mₚ := Module.compHom Mₚ (algebraMap _ Rₚ) have : IsScalarTower R (Localization S) Mₚ := ⟨fun r r' m ↦ show algebraMap _ Rₚ (r • r') • m = _ by simp [p', Rₚ, Mₚ, Algebra.smul_def, ← IsScalarTower.algebraMap_apply, mul_smul]; rfl⟩ @@ -197,11 +197,11 @@ lemma isLocallyConstant_rankAtStalk_freeLocus [Module.FinitePresentation R M] : simpa [Submonoid.powers_le, Ideal.primeCompl] let Rₚ := Localization.AtPrime p.asIdeal let Mₚ := LocalizedModule p.asIdeal.primeCompl M - letI : Algebra (Localization.Away f) Rₚ := + let : Algebra (Localization.Away f) Rₚ := IsLocalization.localizationAlgebraOfSubmonoidLe _ _ (.powers f) p.asIdeal.primeCompl hp' have : IsScalarTower R (Localization.Away f) Rₚ := IsLocalization.localization_isScalarTower_of_submonoid_le .. - letI : Module (Localization.Away f) Mₚ := Module.compHom Mₚ (algebraMap _ Rₚ) + let : Module (Localization.Away f) Mₚ := Module.compHom Mₚ (algebraMap _ Rₚ) have : IsScalarTower R (Localization.Away f) Mₚ := ⟨fun r r' m ↦ show algebraMap _ Rₚ (r • r') • m = _ by simp [Rₚ, Mₚ, Algebra.smul_def, ← IsScalarTower.algebraMap_apply, mul_smul]; rfl⟩ diff --git a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean index 6a73b5aede0902..9d42b9f5ad0864 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean @@ -220,7 +220,7 @@ theorem t1Space_iff_isField [IsDomain R] : T1Space (PrimeSpectrum R) ↔ IsField (by simp)) · refine ⟨fun x => (isClosed_singleton_iff_isMaximal x).2 ?_⟩ by_cases hx : x.asIdeal = ⊥ - · letI := h.toSemifield + · let := h.toSemifield exact hx.symm ▸ Ideal.bot_isMaximal · exact absurd h (Ring.not_isField_iff_exists_prime.2 ⟨x.asIdeal, ⟨hx, x.2⟩⟩) @@ -660,7 +660,7 @@ lemma range_comap_algebraMap_localization_compl_eq_range_comap_quotientMk letI := (mapRingHom (algebraMap R (Away c))).toAlgebra (range (comap (algebraMap R[X] (Away c)[X])))ᶜ = range (comap (mapRingHom (Ideal.Quotient.mk (.span {c})))) := by - letI := (mapRingHom (algebraMap R (Away c))).toAlgebra + let := (mapRingHom (algebraMap R (Away c))).toAlgebra have := Polynomial.isLocalization (.powers c) (Away c) rw [Submonoid.map_powers] at this have surj : Function.Surjective (mapRingHom (Ideal.Quotient.mk (.span {c}))) := diff --git a/Mathlib/RingTheory/SurjectiveOnStalks.lean b/Mathlib/RingTheory/SurjectiveOnStalks.lean index 7c1ee5de1a3fbb..5e13b5ab1860a3 100644 --- a/Mathlib/RingTheory/SurjectiveOnStalks.lean +++ b/Mathlib/RingTheory/SurjectiveOnStalks.lean @@ -200,7 +200,7 @@ private lemma SurjectiveOnStalks.tensorProductMap_id {S' : Type*} [CommRing S'] [Algebra R S] [Algebra R T] [Algebra R S'] {f : S →ₐ[R] S'} (Hf : f.SurjectiveOnStalks) : (Algebra.TensorProduct.map f (AlgHom.id R T)).SurjectiveOnStalks := by - letI := f.toRingHom.toAlgebra + let := f.toRingHom.toAlgebra have := IsScalarTower.of_algebraMap_eq' f.comp_algebraMap.symm change (Algebra.TensorProduct.map (Algebra.ofId S S') (AlgHom.id R T)).SurjectiveOnStalks convert_to ((Algebra.TensorProduct.cancelBaseChange R S S S' T).toAlgHom.comp diff --git a/Mathlib/RingTheory/TensorProduct/Finite.lean b/Mathlib/RingTheory/TensorProduct/Finite.lean index 9a44ca5362dbec..bc887b9d279e33 100644 --- a/Mathlib/RingTheory/TensorProduct/Finite.lean +++ b/Mathlib/RingTheory/TensorProduct/Finite.lean @@ -161,7 +161,7 @@ private lemma RingHom.Finite.tensorProductMap_id [Algebra R S] [Algebra R T] [Algebra R S'] {f : S →ₐ[R] S'} (Hf : f.Finite) : (Algebra.TensorProduct.map f (AlgHom.id R T)).toRingHom.Finite := by - letI := f.toRingHom.toAlgebra + let := f.toRingHom.toAlgebra have := IsScalarTower.of_algebraMap_eq' f.comp_algebraMap.symm have : Module.Finite S S' := finite_algebraMap.mp Hf change (Algebra.TensorProduct.map (Algebra.ofId S S') (AlgHom.id R T)).Finite diff --git a/Mathlib/RingTheory/TensorProduct/IsBaseChangePi.lean b/Mathlib/RingTheory/TensorProduct/IsBaseChangePi.lean index e972002da41e3a..c1b6dfe3f1630c 100644 --- a/Mathlib/RingTheory/TensorProduct/IsBaseChangePi.lean +++ b/Mathlib/RingTheory/TensorProduct/IsBaseChangePi.lean @@ -80,8 +80,8 @@ instance prodMap {M N M' N' : Type*} (f : M →ₗ[R] M') (g : N →ₗ[R] N') [IsLocalizedModule S f] [IsLocalizedModule S g] : IsLocalizedModule S (f.prodMap g) := by - letI : Module (Localization S) M' := IsLocalizedModule.module S f - letI : Module (Localization S) N' := IsLocalizedModule.module S g + let : Module (Localization S) M' := IsLocalizedModule.module S f + let : Module (Localization S) N' := IsLocalizedModule.module S g rw [isLocalizedModule_iff_isBaseChange S (Localization S)] apply IsBaseChange.prodMap · rw [← isLocalizedModule_iff_isBaseChange S] @@ -95,7 +95,7 @@ instance pi {ι : Type*} [Finite ι] [∀ i, Module R (M i)] [∀ i, Module R (M' i)] (f : ∀ i, M i →ₗ[R] M' i) [∀ i, IsLocalizedModule S (f i)] : IsLocalizedModule S (.pi fun i ↦ f i ∘ₗ .proj i) := by - letI (i : ι) : Module (Localization S) (M' i) := IsLocalizedModule.module S (f i) + let (i : ι) : Module (Localization S) (M' i) := IsLocalizedModule.module S (f i) rw [isLocalizedModule_iff_isBaseChange S (Localization S)] apply IsBaseChange.pi intro i diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index bc903ffb8e07dd..69acc938b4f36a 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -87,8 +87,8 @@ lemma _root_.LinearMap.map_mul_of_map_mul_tmul {f : A ⊗[R] B →ₗ[S] C} (x y : A ⊗[R] B) : f (x * y) = f x * f y := f.map_mul_iff.2 (by -- these instances are needed by the statement of `ext`, but not by the current definition. - letI : Algebra R C := .restrictScalars R S C - letI : IsScalarTower R S C := .restrictScalars R S C + let : Algebra R C := .restrictScalars R S C + let : IsScalarTower R S C := .restrictScalars R S C ext dsimp exact hf _ _ _ _) x y diff --git a/Mathlib/RingTheory/TensorProduct/Nontrivial.lean b/Mathlib/RingTheory/TensorProduct/Nontrivial.lean index a32958caefdce0..93358ea2d6f9e5 100644 --- a/Mathlib/RingTheory/TensorProduct/Nontrivial.lean +++ b/Mathlib/RingTheory/TensorProduct/Nontrivial.lean @@ -30,7 +30,7 @@ theorem nontrivial_of_algebraMap_injective_of_isDomain (R A B : Type*) [CommRing R] [CommRing A] [CommRing B] [Algebra R A] [Algebra R B] (ha : Function.Injective (algebraMap R A)) (hb : Function.Injective (algebraMap R B)) [IsDomain A] [IsDomain B] : Nontrivial (A ⊗[R] B) := by - haveI := ha.isDomain _ + have := ha.isDomain _ let FR := FractionRing R let FA := FractionRing A let FB := FractionRing B @@ -39,7 +39,7 @@ theorem nontrivial_of_algebraMap_injective_of_isDomain let fb : FR →ₐ[R] FB := IsFractionRing.liftAlgHom (g := Algebra.ofId R FB) ((IsFractionRing.injective B FB).comp hb) algebraize_only [fa.toRingHom, fb.toRingHom] - letI : CompatibleSMul FR R FA FB := CompatibleSMul.isScalarTower + let : CompatibleSMul FR R FA FB := CompatibleSMul.isScalarTower exact Algebra.TensorProduct.mapOfCompatibleSMul FR R R FA FB |>.comp (Algebra.TensorProduct.map (IsScalarTower.toAlgHom R A FA) (IsScalarTower.toAlgHom R B FB)) |>.toRingHom.domain_nontrivial diff --git a/Mathlib/RingTheory/Trace/Basic.lean b/Mathlib/RingTheory/Trace/Basic.lean index 071d0cb4105ce0..6a1ebb4d996197 100644 --- a/Mathlib/RingTheory/Trace/Basic.lean +++ b/Mathlib/RingTheory/Trace/Basic.lean @@ -80,7 +80,7 @@ theorem PowerBasis.trace_gen_eq_nextCoeff_minpoly [Nontrivial S] (pb : PowerBasi Algebra.trace K S pb.gen = -(minpoly K pb.gen).nextCoeff := by have d_pos : 0 < pb.dim := PowerBasis.dim_pos pb have d_pos' : 0 < (minpoly K pb.gen).natDegree := by simpa - haveI : Nonempty (Fin pb.dim) := ⟨⟨0, d_pos⟩⟩ + have : Nonempty (Fin pb.dim) := ⟨⟨0, d_pos⟩⟩ rw [trace_eq_matrix_trace pb.basis, trace_eq_neg_charpoly_coeff, charpoly_leftMulMatrix, ← pb.natDegree_minpoly, Fintype.card_fin, ← nextCoeff_of_natDegree_pos d_pos'] @@ -184,8 +184,8 @@ lemma Algebra.trace_eq_of_ringEquiv {A B C : Type*} [CommRing A] [CommRing B] [C classical by_cases h : ∃ s : Finset C, Nonempty (Basis s B C) · obtain ⟨s, ⟨b⟩⟩ := h - letI : Algebra A B := RingHom.toAlgebra e - letI : IsScalarTower A B C := IsScalarTower.of_algebraMap_eq' he.symm + let : Algebra A B := RingHom.toAlgebra e + let : IsScalarTower A B C := IsScalarTower.of_algebraMap_eq' he.symm rw [Algebra.trace_eq_matrix_trace b, Algebra.trace_eq_matrix_trace (b.mapCoeffs e.symm (by simp [Algebra.smul_def, ← he]))] rw [AddMonoidHom.map_trace] @@ -201,7 +201,7 @@ lemma Algebra.trace_eq_of_equiv_equiv {A₁ B₁ A₂ B₂ : Type*} [CommRing A [CommRing A₂] [CommRing B₂] [Algebra A₁ B₁] [Algebra A₂ B₂] (e₁ : A₁ ≃+* A₂) (e₂ : B₁ ≃+* B₂) (he : RingHom.comp (algebraMap A₂ B₂) ↑e₁ = RingHom.comp ↑e₂ (algebraMap A₁ B₁)) (x) : Algebra.trace A₁ B₁ x = e₁.symm (Algebra.trace A₂ B₂ (e₂ x)) := by - letI := (RingHom.comp (e₂ : B₁ →+* B₂) (algebraMap A₁ B₁)).toAlgebra + let := (RingHom.comp (e₂ : B₁ →+* B₂) (algebraMap A₁ B₁)).toAlgebra let e' : B₁ ≃ₐ[A₁] B₂ := { e₂ with commutes' := fun _ ↦ rfl } rw [← Algebra.trace_eq_of_ringEquiv e₁ he, ← Algebra.trace_eq_of_algEquiv e', RingEquiv.symm_apply_apply] @@ -219,8 +219,8 @@ theorem trace_eq_sum_embeddings_gen (pb : PowerBasis K L) (hE : ((minpoly K pb.gen).map (algebraMap K E)).Splits) (hfx : IsSeparable K pb.gen) : algebraMap K E (Algebra.trace K L pb.gen) = (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).sum fun σ => σ pb.gen := by - letI := Classical.decEq E - letI : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb + let := Classical.decEq E + let : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb rw [pb.trace_gen_eq_sum_roots hE, Fintype.sum_equiv pb.liftEquiv', Finset.sum_mem_multiset, Finset.sum_eq_multiset_sum, Multiset.toFinset_val, Multiset.dedup_eq_self.mpr _, Multiset.map_id] @@ -237,13 +237,13 @@ theorem sum_embeddings_eq_finrank_mul [FiniteDimensional K F] [Algebra.IsSeparab ∑ σ : F →ₐ[K] E, σ (algebraMap L F pb.gen) = finrank L F • (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).sum fun σ : L →ₐ[K] E => σ pb.gen := by - haveI : FiniteDimensional L F := FiniteDimensional.right K L F - haveI : Algebra.IsSeparable L F := Algebra.isSeparable_tower_top_of_isSeparable K L F - letI : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb + have : FiniteDimensional L F := FiniteDimensional.right K L F + have : Algebra.IsSeparable L F := Algebra.isSeparable_tower_top_of_isSeparable K L F + let : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb rw [Fintype.sum_equiv algHomEquivSigma (fun σ : F →ₐ[K] E => _) fun σ => σ.1 pb.gen, ← Finset.univ_sigma_univ, Finset.sum_sigma, ← Finset.sum_nsmul] · refine Finset.sum_congr rfl fun σ _ => ?_ - letI : Algebra L E := σ.toRingHom.toAlgebra + let : Algebra L E := σ.toRingHom.toAlgebra simp_rw [Finset.sum_const, Finset.card_univ, ← AlgHom.card L F E] · intro σ simp only [algHomEquivSigma, Equiv.coe_fn_mk, AlgHom.restrictDomain, AlgHom.comp_apply, @@ -257,7 +257,7 @@ theorem trace_eq_sum_embeddings [FiniteDimensional K L] [Algebra.IsSeparable K L trace_eq_sum_embeddings_gen E pb (IsAlgClosed.splits _), ← Algebra.smul_def, algebraMap_smul] · exact (sum_embeddings_eq_finrank_mul L E pb).symm - · haveI := Algebra.isSeparable_tower_bot_of_isSeparable K K⟮x⟯ L + · have := Algebra.isSeparable_tower_bot_of_isSeparable K K⟮x⟯ L exact Algebra.IsSeparable.isSeparable K _ theorem trace_eq_sum_automorphisms (x : L) [FiniteDimensional K L] [IsGalois K L] : @@ -463,7 +463,7 @@ theorem det_traceMatrix_ne_zero' [Algebra.IsSeparable K L] : det (traceMatrix K suffices algebraMap K (AlgebraicClosure L) (det (traceMatrix K pb.basis)) ≠ 0 by refine mt (fun ht => ?_) this rw [ht, map_zero] - haveI : FiniteDimensional K L := pb.finite + have : FiniteDimensional K L := pb.finite let e : Fin pb.dim ≃ (L →ₐ[K] AlgebraicClosure L) := (Fintype.equivFinOfCardEq ?_).symm · rw [RingHom.map_det, RingHom.mapMatrix_apply, traceMatrix_eq_embeddingsMatrixReindex_mul_trans K _ _ e, @@ -477,7 +477,7 @@ theorem det_traceMatrix_ne_zero' [Algebra.IsSeparable K L] : det (traceMatrix K theorem det_traceForm_ne_zero [Algebra.IsSeparable K L] [Fintype ι] [DecidableEq ι] (b : Basis ι K L) : det ((traceForm K L).toMatrix b) ≠ 0 := by - haveI : FiniteDimensional K L := b.finiteDimensional_of_finite + have : FiniteDimensional K L := b.finiteDimensional_of_finite let pb : PowerBasis K L := Field.powerBasisOfFiniteOfSeparable _ _ rw [← LinearMap.BilinForm.toMatrix_mul_basis_toMatrix pb.basis b, ← det_comm' (pb.basis.toMatrix_mul_toMatrix_flip b) _, ← Matrix.mul_assoc, det_mul] diff --git a/Mathlib/RingTheory/Trace/Defs.lean b/Mathlib/RingTheory/Trace/Defs.lean index 20bbbbb9f42612..54134b72751ed2 100644 --- a/Mathlib/RingTheory/Trace/Defs.lean +++ b/Mathlib/RingTheory/Trace/Defs.lean @@ -91,7 +91,7 @@ theorem trace_eq_matrix_trace [DecidableEq ι] (b : Basis ι R S) (s : S) : /-- If `x` is in the base field `K`, then the trace is `[L : K] * x`. -/ theorem trace_algebraMap_of_basis (b : Basis ι R S) (x : R) : trace R S (algebraMap R S x) = Fintype.card ι • x := by - haveI := Classical.decEq ι + have := Classical.decEq ι rw [trace_apply, LinearMap.trace_eq_matrix_trace R b, Matrix.trace] convert! Finset.sum_const x simp [-coe_lmul_eq_mul] @@ -118,8 +118,8 @@ set_option backward.isDefEq.respectTransparency false in theorem trace_trace_of_basis [Algebra S T] [IsScalarTower R S T] {ι κ : Type*} [Finite ι] [Finite κ] (b : Basis ι R S) (c : Basis κ S T) (x : T) : trace R S (trace S T x) = trace R T x := by - haveI := Classical.decEq ι - haveI := Classical.decEq κ + have := Classical.decEq ι + have := Classical.decEq κ cases nonempty_fintype ι cases nonempty_fintype κ rw [trace_eq_matrix_trace (b.smulTower c), trace_eq_matrix_trace b, trace_eq_matrix_trace c, diff --git a/Mathlib/RingTheory/Trace/Quotient.lean b/Mathlib/RingTheory/Trace/Quotient.lean index b54e87e655bc4a..a5c312a83dd7c5 100644 --- a/Mathlib/RingTheory/Trace/Quotient.lean +++ b/Mathlib/RingTheory/Trace/Quotient.lean @@ -93,28 +93,28 @@ lemma Algebra.trace_quotient_eq_of_isDedekindDomain (x) [IsDedekindDomain R] [Is Ideal.Quotient.mk p (Algebra.intTrace R S x) := by let Rₚ := Localization.AtPrime p let Sₚ := Localization (Algebra.algebraMapSubmonoid S p.primeCompl) - letI : Algebra Rₚ Sₚ := localizationAlgebra p.primeCompl S - haveI : IsScalarTower R Rₚ Sₚ := IsScalarTower.of_algebraMap_eq' + let : Algebra Rₚ Sₚ := localizationAlgebra p.primeCompl S + have : IsScalarTower R Rₚ Sₚ := IsScalarTower.of_algebraMap_eq' (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, ← IsScalarTower.algebraMap_eq]) - haveI : IsLocalization (Submonoid.map (algebraMap R S) (Ideal.primeCompl p)) Sₚ := + have : IsLocalization (Submonoid.map (algebraMap R S) (Ideal.primeCompl p)) Sₚ := inferInstanceAs (IsLocalization (Algebra.algebraMapSubmonoid S p.primeCompl) Sₚ) have e : Algebra.algebraMapSubmonoid S p.primeCompl ≤ S⁰ := Submonoid.map_le_of_le_comap _ <| p.primeCompl_le_nonZeroDivisors.trans (nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ (FaithfulSMul.algebraMap_injective _ _)) - haveI : IsDomain Sₚ := IsLocalization.isDomain_of_le_nonZeroDivisors _ e - haveI : IsTorsionFree Rₚ Sₚ := by + have : IsDomain Sₚ := IsLocalization.isDomain_of_le_nonZeroDivisors _ e + have : IsTorsionFree Rₚ Sₚ := by rw [isTorsionFree_iff_algebraMap_injective, RingHom.injective_iff_ker_eq_bot, RingHom.ker_eq_bot_iff_eq_zero] simp - haveI : Module.Finite Rₚ Sₚ := .of_isLocalization R S p.primeCompl - haveI : IsIntegrallyClosed Sₚ := isIntegrallyClosed_of_isLocalization _ _ e + have : Module.Finite Rₚ Sₚ := .of_isLocalization R S p.primeCompl + have : IsIntegrallyClosed Sₚ := isIntegrallyClosed_of_isLocalization _ _ e have : IsPrincipalIdealRing Rₚ := by by_cases hp : p = ⊥ · infer_instance · have := (IsDedekindDomain.isDedekindDomainDvr R).2 p hp inferInstance infer_instance - haveI : Module.Free Rₚ Sₚ := Module.free_of_finite_type_torsion_free' + have : Module.Free Rₚ Sₚ := Module.free_of_finite_type_torsion_free' apply (equivQuotMaximalIdeal p Rₚ).injective rw [trace_quotient_eq_trace_localization_quotient S p Rₚ Sₚ, IsScalarTower.algebraMap_eq S Sₚ, RingHom.comp_apply, Ideal.Quotient.algebraMap_eq, Algebra.trace_quotient_mk, diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index 8dd5a1c99d6929..5b22e5d6662b01 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -88,7 +88,7 @@ theorem prime_factors_unique [CommMonoidWithZero α] [IsCancelMulZero α] : let ⟨b, hbg, hb⟩ := (exists_associated_mem_of_dvd_prod (hf p (by simp)) fun q hq => hg _ hq) <| hfg.dvd_iff_dvd_right.1 (show p ∣ (p ::ₘ f).prod by simp) - haveI := Classical.decEq α + have := Classical.decEq α rw [← Multiset.cons_erase hbg] exact Multiset.Rel.cons hb @@ -122,7 +122,7 @@ end UniqueFactorizationMonoid then it is an associate of one of its prime factors. -/ theorem prime_factors_irreducible [CommMonoidWithZero α] {a : α} {f : Multiset α} (ha : Irreducible a) (pfa : (∀ b ∈ f, Prime b) ∧ f.prod ~ᵤ a) : ∃ p, a ~ᵤ p ∧ f = {p} := by - haveI := Classical.decEq α + have := Classical.decEq α refine @Multiset.induction_on _ (fun g => (g.prod ~ᵤ a) → (∀ b ∈ g, Prime b) → ∃ p, a ~ᵤ p ∧ g = {p}) f ?_ ?_ pfa.2 pfa.1 · intro h; exact (ha.not_isUnit (associated_one_iff_isUnit.1 (Associated.symm h))).elim diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean index 22f9f66073f64f..efe25fa88dcae1 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/ClassGroup.lean @@ -35,7 +35,7 @@ namespace IsGCDMonoid lemma isPrincipal_of_exists_mul_ne_zero_isPrincipal {J : Ideal R} (hJ : ∃ K : Ideal R, J * K ≠ 0 ∧ (J * K).IsPrincipal) : J.IsPrincipal := by - letI : NormalizedGCDMonoid R := Classical.arbitrary _ + let : NormalizedGCDMonoid R := Classical.arbitrary _ obtain ⟨K, hJK0, hK⟩ := hJ rcases hK.principal with ⟨x, hJK⟩ have hxmemJK : x ∈ J * K := by simp [hJK] diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean index 2ec546c11e0d2b..0c9c53795fab29 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean @@ -356,7 +356,7 @@ theorem dvd_of_mem_factors {a p : Associates α} (hm : p ∈ factors a) : theorem dvd_of_mem_factors' {a : α} {p : Associates α} {hp : Irreducible p} {hz : a ≠ 0} (h_mem : Subtype.mk p hp ∈ factors' a) : p ∣ Associates.mk a := by - haveI := Classical.decEq (Associates α) + have := Classical.decEq (Associates α) apply dvd_of_mem_factors rw [factors_mk _ hz] apply mem_factorSet_some.2 h_mem diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean index 27aef704ca559f..53789c68b3c751 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicative.lean @@ -58,7 +58,7 @@ theorem induction_on_prime_power {P : α → Prop} (s : Finset α) (i : α → (h1 : ∀ {x}, IsUnit x → P x) (hpr : ∀ {p} (i : ℕ), Prime p → P (p ^ i)) (hcp : ∀ {x y}, IsRelPrime x y → P x → P y → P (x * y)) : P (∏ p ∈ s, p ^ i p) := by - letI := Classical.decEq α + let := Classical.decEq α induction s using Finset.induction_on with | empty => simpa using h1 isUnit_one | insert p f' hpf' ih => @@ -76,14 +76,14 @@ then `P` holds on all `a : α`. -/ theorem induction_on_coprime {P : α → Prop} (a : α) (h0 : P 0) (h1 : ∀ {x}, IsUnit x → P x) (hpr : ∀ {p} (i : ℕ), Prime p → P (p ^ i)) (hcp : ∀ {x y}, IsRelPrime x y → P x → P y → P (x * y)) : P a := by - letI := Classical.decEq α + let := Classical.decEq α have P_of_associated : ∀ {x y}, Associated x y → P x → P y := by rintro x y ⟨u, rfl⟩ hx exact hcp (fun p _ hpx => isUnit_of_dvd_unit hpx u.isUnit) hx (h1 u.isUnit) by_cases ha0 : a = 0 · rwa [ha0] - haveI : Nontrivial α := ⟨⟨_, _, ha0⟩⟩ - letI : StrongNormalizationMonoid α := UniqueFactorizationMonoid.strongNormalizationMonoid + have : Nontrivial α := ⟨⟨_, _, ha0⟩⟩ + let : StrongNormalizationMonoid α := UniqueFactorizationMonoid.strongNormalizationMonoid refine P_of_associated (prod_normalizedFactors ha0) ?_ rw [← (normalizedFactors a).map_id, Finset.prod_multiset_map_count] refine induction_on_prime_power _ _ ?_ ?_ @h1 @hpr @hcp <;> simp only [Multiset.mem_toFinset] @@ -98,7 +98,7 @@ theorem multiplicative_prime_power {f : α → β} (s : Finset α) (i j : α → (hpr : ∀ {p} (i : ℕ), Prime p → f (p ^ i) = f p ^ i) (hcp : ∀ {x y}, IsRelPrime x y → f (x * y) = f x * f y) : f (∏ p ∈ s, p ^ (i p + j p)) = f (∏ p ∈ s, p ^ i p) * f (∏ p ∈ s, p ^ j p) := by - letI := Classical.decEq α + let := Classical.decEq α induction s using Finset.induction_on with | empty => simpa using h1 isUnit_one | insert p s hps ih => @@ -118,7 +118,7 @@ theorem multiplicative_of_coprime (f : α → β) (a b : α) (h0 : f 0 = 0) (hpr : ∀ {p} (i : ℕ), Prime p → f (p ^ i) = f p ^ i) (hcp : ∀ {x y}, IsRelPrime x y → f (x * y) = f x * f y) : f (a * b) = f a * f b := by - letI := Classical.decEq α + let := Classical.decEq α by_cases ha0 : a = 0 · rw [ha0, zero_mul, h0, zero_mul] by_cases hb0 : b = 0 @@ -129,8 +129,8 @@ theorem multiplicative_of_coprime (f : α → β) (a b : α) (h0 : f 0 = 0) _ = 0 := by simp only [h1 isUnit_one, hf1, mul_zero] _ = f a * f (b * 1) := by simp only [h1 isUnit_one, hf1, mul_zero] _ = f a * f b := by rw [mul_one] - haveI : Nontrivial α := ⟨⟨_, _, ha0⟩⟩ - letI : StrongNormalizationMonoid α := UniqueFactorizationMonoid.strongNormalizationMonoid + have : Nontrivial α := ⟨⟨_, _, ha0⟩⟩ + let : StrongNormalizationMonoid α := UniqueFactorizationMonoid.strongNormalizationMonoid suffices f (∏ p ∈ (normalizedFactors a).toFinset ∪ (normalizedFactors b).toFinset, p ^ ((normalizedFactors a).count p + (normalizedFactors b).count p)) = diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean index ec20b2835b46b2..9a08267a8ea4bd 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean @@ -157,7 +157,7 @@ lemma dvd_iff_emultiplicity_le {a b : R} (ha : a ≠ 0) : refine ⟨fun h _ _ ↦ emultiplicity_le_emultiplicity_of_dvd_right h, fun h ↦ ?_⟩ by_cases hb : b = 0 · simp_all - letI : StrongNormalizationMonoid R := UniqueFactorizationMonoid.strongNormalizationMonoid + let : StrongNormalizationMonoid R := UniqueFactorizationMonoid.strongNormalizationMonoid rw [dvd_iff_normalizedFactors_le_normalizedFactors ha hb, Multiset.le_iff_count] intro q by_cases hq : q ∈ normalizedFactors a diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean index 4c515f6c69eb24..d2973d64244ab3 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean @@ -186,7 +186,7 @@ theorem normalizedFactors_prod_eq (s : Multiset α) (hs : ∀ a ∈ s, Irreducib obtain rfl | ⟨b, hb⟩ := s.empty_or_exists_mem · rw [Multiset.cons_zero, Multiset.prod_singleton, Multiset.map_singleton, normalizedFactors_irreducible ia] - haveI := nontrivial_of_ne b 0 (ib b hb).ne_zero + have := nontrivial_of_ne b 0 (ib b hb).ne_zero rw [Multiset.prod_cons, Multiset.map_cons, normalizedFactors_mul ia.ne_zero (Multiset.prod_ne_zero fun h => (ib 0 h).ne_zero rfl), normalizedFactors_irreducible ia, ih ib, Multiset.singleton_add] diff --git a/Mathlib/RingTheory/Unramified/Basic.lean b/Mathlib/RingTheory/Unramified/Basic.lean index e92075346fa9e3..0c33400a02463d 100644 --- a/Mathlib/RingTheory/Unramified/Basic.lean +++ b/Mathlib/RingTheory/Unramified/Basic.lean @@ -73,8 +73,8 @@ variable {B : Type w} [CommRing B] [Algebra R B] (I : Ideal B) theorem comp_injective [FormallyUnramified R A] (hI : I ^ 2 = ⊥) : Function.Injective ((Ideal.Quotient.mkₐ R I).comp : (A →ₐ[R] B) → A →ₐ[R] B ⧸ I) := by intro f₁ f₂ e - letI := f₁.toRingHom.toAlgebra - haveI := IsScalarTower.of_algebraMap_eq' f₁.comp_algebraMap.symm + let := f₁.toRingHom.toAlgebra + have := IsScalarTower.of_algebraMap_eq' f₁.comp_algebraMap.symm have := ((KaehlerDifferential.linearMapEquivDerivation R A).toEquiv.trans (derivationToSquareZeroEquivLift I hI)).surjective.subsingleton @@ -220,7 +220,7 @@ theorem comp [FormallyUnramified R A] [FormallyUnramified A B] : have e' := FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B) (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc]) - letI := (f₁.restrictDomain A).toAlgebra + let := (f₁.restrictDomain A).toAlgebra let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl } let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm } ext1 x @@ -231,8 +231,8 @@ theorem comp [FormallyUnramified R A] [FormallyUnramified A B] : theorem of_restrictScalars [FormallyUnramified R B] : FormallyUnramified A B := by rw [iff_comp_injective] intro Q _ _ I e f₁ f₂ e' - letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra - letI : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl + let := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra + let : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl refine AlgHom.restrictScalars_injective R ?_ refine FormallyUnramified.ext I ⟨2, e⟩ ?_ intro x @@ -278,8 +278,8 @@ instance base_change [FormallyUnramified R A] : FormallyUnramified B (B ⊗[R] A) := by rw [iff_comp_injective] intro C _ _ I hI f₁ f₂ e - letI := ((algebraMap B C).comp (algebraMap R B)).toAlgebra - haveI : IsScalarTower R B C := IsScalarTower.of_algebraMap_eq' rfl + let := ((algebraMap B C).comp (algebraMap R B)).toAlgebra + have : IsScalarTower R B C := IsScalarTower.of_algebraMap_eq' rfl ext : 1 exact FormallyUnramified.ext I ⟨2, hI⟩ fun x => AlgHom.congr_fun e (1 ⊗ₜ x) @@ -323,9 +323,9 @@ theorem localization_base [FormallyUnramified R Sₘ] : FormallyUnramified Rₘ theorem localization_map [FormallyUnramified R S] : FormallyUnramified Rₘ Sₘ := by - haveI : FormallyUnramified S Sₘ := + have : FormallyUnramified S Sₘ := FormallyUnramified.of_isLocalization (M.map (algebraMap R S)) - haveI : FormallyUnramified R Sₘ := FormallyUnramified.comp R S Sₘ + have : FormallyUnramified R Sₘ := FormallyUnramified.comp R S Sₘ exact FormallyUnramified.localization_base M end Localization diff --git a/Mathlib/RingTheory/Unramified/Field.lean b/Mathlib/RingTheory/Unramified/Field.lean index 3c67cf6d23e714..f7256c8feb9b05 100644 --- a/Mathlib/RingTheory/Unramified/Field.lean +++ b/Mathlib/RingTheory/Unramified/Field.lean @@ -147,7 +147,7 @@ theorem isReduced_of_field : (Localization.AtPrime M) have := comp (AlgebraicClosure K) (AlgebraicClosure K ⊗[K] A) (Localization.AtPrime M) - letI := (isField_of_isAlgClosed_of_isLocalRing (AlgebraicClosure K) + let := (isField_of_isAlgClosed_of_isLocalRing (AlgebraicClosure K) (A := Localization.AtPrime M)).toField exact hy.eq_zero @@ -234,7 +234,7 @@ theorem Algebra.IsUnramifiedAt.not_minpoly_sq_dvd have := IsArtinianRing.of_finite K (Localization.AtPrime Q) have := Algebra.FormallyUnramified.isReduced_of_field K (Localization.AtPrime Q) IsArtinianRing.isField_of_isReduced_of_isLocalRing _ - letI := this.toField + let := this.toField set q := minpoly K (algebraMap A Q.ResidueField x) have : algebraMap A (Localization.AtPrime Q) (aeval x q) = 0 := by apply (algebraMap (Localization.AtPrime Q) Q.ResidueField).injective diff --git a/Mathlib/RingTheory/Unramified/LocalRing.lean b/Mathlib/RingTheory/Unramified/LocalRing.lean index 96a592af9c44bc..efd3e2940341f6 100644 --- a/Mathlib/RingTheory/Unramified/LocalRing.lean +++ b/Mathlib/RingTheory/Unramified/LocalRing.lean @@ -69,7 +69,7 @@ lemma FormallyUnramified.isField_quotient_map_maximalIdeal [FormallyUnramified R IsField (S ⧸ (maximalIdeal R).map (algebraMap R S)) := by let mR := (maximalIdeal R).map (algebraMap R S) have hmR : mR ≤ maximalIdeal S := ((local_hom_TFAE (algebraMap R S)).out 0 2 rfl rfl).mp ‹_› - letI : Algebra (ResidueField R) (S ⧸ mR) := (inferInstanceAs <| Algebra (R ⧸ _) _) + let : Algebra (ResidueField R) (S ⧸ mR) := (inferInstanceAs <| Algebra (R ⧸ _) _) have : IsScalarTower R (ResidueField R) (S ⧸ mR) := (inferInstanceAs <| IsScalarTower R (R ⧸ _) _) have : FormallyUnramified (ResidueField R) (S ⧸ mR) := .of_restrictScalars R _ _ have : EssFiniteType (ResidueField R) (S ⧸ mR) := .of_comp R _ _ diff --git a/Mathlib/RingTheory/Valuation/ValuationRing.lean b/Mathlib/RingTheory/Valuation/ValuationRing.lean index e82a9b454cd51f..d5f1081b0d5122 100644 --- a/Mathlib/RingTheory/Valuation/ValuationRing.lean +++ b/Mathlib/RingTheory/Valuation/ValuationRing.lean @@ -468,7 +468,7 @@ is a valuation ring. -/ theorem of_integers (v : Valuation K Γ) (hh : v.Integers 𝒪) : haveI := hh.hom_inj.isDomain ValuationRing 𝒪 := by - haveI := hh.hom_inj.isDomain + have := hh.hom_inj.isDomain suffices PreValuationRing 𝒪 from .mk constructor intro a b diff --git a/Mathlib/RingTheory/WittVector/Compare.lean b/Mathlib/RingTheory/WittVector/Compare.lean index f5084263c587bf..ea78a6c16ebf03 100644 --- a/Mathlib/RingTheory/WittVector/Compare.lean +++ b/Mathlib/RingTheory/WittVector/Compare.lean @@ -51,7 +51,7 @@ theorem eq_of_le_of_cast_pow_eq_zero [CharP R p] (i : ℕ) (hin : i ≤ n) rw [this, ne_eq, TruncatedWittVector.ext_iff, not_forall]; clear this use ⟨i, hin⟩ rw [WittVector.coeff_truncate, coeff_zero, Fin.val_mk, WittVector.coeff_p_pow] - haveI : Nontrivial R := CharP.nontrivial_of_char_ne_one hp.1.ne_one + have : Nontrivial R := CharP.nontrivial_of_char_ne_one hp.1.ne_one exact one_ne_zero section Iso diff --git a/Mathlib/RingTheory/WittVector/Frobenius.lean b/Mathlib/RingTheory/WittVector/Frobenius.lean index 83e2d0296f451b..bfddfffd959711 100644 --- a/Mathlib/RingTheory/WittVector/Frobenius.lean +++ b/Mathlib/RingTheory/WittVector/Frobenius.lean @@ -257,7 +257,7 @@ variable [CharP R p] @[simp] theorem coeff_frobenius_charP (x : 𝕎 R) (n : ℕ) : coeff (frobenius x) n = x.coeff n ^ p := by rw [coeff_frobenius] - letI : Algebra (ZMod p) R := ZMod.algebra _ _ + let : Algebra (ZMod p) R := ZMod.algebra _ _ -- outline of the calculation, proofs follow below calc aeval (fun k => x.coeff k) (frobeniusPoly p n) = diff --git a/Mathlib/RingTheory/WittVector/InitTail.lean b/Mathlib/RingTheory/WittVector/InitTail.lean index c3117a433dd17d..aa0b1f9d1673fe 100644 --- a/Mathlib/RingTheory/WittVector/InitTail.lean +++ b/Mathlib/RingTheory/WittVector/InitTail.lean @@ -108,7 +108,7 @@ theorem select_add_select_not : ∀ x : 𝕎 R, select P x + select (fun i => ¬ theorem coeff_add_of_disjoint (x y : 𝕎 R) (h : ∀ n, x.coeff n = 0 ∨ y.coeff n = 0) : (x + y).coeff n = x.coeff n + y.coeff n := by let P : ℕ → Prop := fun n => y.coeff n = 0 - haveI : DecidablePred P := Classical.decPred P + have : DecidablePred P := Classical.decPred P set z := mk p fun n => if P n then x.coeff n else y.coeff n have hx : select P z = x := by ext1 n; rw [select, coeff_mk, coeff_mk] diff --git a/Mathlib/RingTheory/WittVector/Isocrystal.lean b/Mathlib/RingTheory/WittVector/Isocrystal.lean index a91b60b777cdcc..e4f803497f2e1d 100644 --- a/Mathlib/RingTheory/WittVector/Isocrystal.lean +++ b/Mathlib/RingTheory/WittVector/Isocrystal.lean @@ -180,7 +180,7 @@ admits an isomorphism to one of the standard (indexed by `m : ℤ`) one-dimensio theorem isocrystal_classification (k : Type*) [Field k] [IsAlgClosed k] [CharP k p] (V : Type*) [AddCommGroup V] [Isocrystal p k V] (h_dim : finrank K(p, k) V = 1) : ∃ m : ℤ, Nonempty (StandardOneDimIsocrystal p k m ≃ᶠⁱ[p, k] V) := by - haveI : Nontrivial V := Module.nontrivial_of_finrank_eq_succ h_dim + have : Nontrivial V := Module.nontrivial_of_finrank_eq_succ h_dim obtain ⟨x, hx⟩ : ∃ x : V, x ≠ 0 := exists_ne 0 have : Φ(p, k) x ≠ 0 := by simpa only [map_zero] using Φ(p, k).injective.ne hx obtain ⟨a, ha, hax⟩ : ∃ a : K(p, k), a ≠ 0 ∧ Φ(p, k) x = a • x := by diff --git a/Mathlib/RingTheory/ZariskisMainTheorem.lean b/Mathlib/RingTheory/ZariskisMainTheorem.lean index 1d7ad580fa7bd8..c0e5a825954c65 100644 --- a/Mathlib/RingTheory/ZariskisMainTheorem.lean +++ b/Mathlib/RingTheory/ZariskisMainTheorem.lean @@ -149,10 +149,10 @@ lemma isIntegral_of_isIntegralElem_of_monic_of_natDegree_lt have ht't : t' * algebraMap S St t = 1 := by rw [mul_comm, IsLocalization.Away.mul_invSelf] let R₁ := Algebra.adjoin R {t'} let R₂ := Algebra.adjoin R₁ {algebraMap S St (φ X)} - letI : Algebra R₁ R₂ := R₂.algebra - letI : Algebra R₂ St := R₂.toAlgebra - letI : Algebra R₁ St := R₁.toAlgebra - haveI : IsScalarTower R₁ R₂ St := Subalgebra.isScalarTower_mid _ + let : Algebra R₁ R₂ := R₂.algebra + let : Algebra R₂ St := R₂.toAlgebra + let : Algebra R₁ St := R₁.toAlgebra + have : IsScalarTower R₁ R₂ St := Subalgebra.isScalarTower_mid _ have : Algebra.IsIntegral R₁ R₂ := by cases subsingleton_or_nontrivial R₁ · have := (algebraMap R₁ R₂).codomain_trivial; exact ⟨(Subsingleton.elim · 0 ▸ isIntegral_zero)⟩ @@ -194,7 +194,7 @@ lemma exists_isIntegral_leadingCoeff_pow_smul_sub_of_isIntegralElem_of_mul_mem_r set a := p.leadingCoeff let R' := Localization.Away a let S' := Localization.Away (algebraMap R S a) - letI : Algebra R' S' := (Localization.awayMap (algebraMap R S) a).toAlgebra + let : Algebra R' S' := (Localization.awayMap (algebraMap R S) a).toAlgebra have : IsScalarTower R R' S' := .of_algebraMap_eq (by simp +zetaDelta [RingHom.algebraMap_toAlgebra, IsLocalization.Away.map, ← algebraMap_apply R S]) have ha : IsUnit (algebraMap R R' a) := IsLocalization.Away.algebraMap_isUnit a @@ -464,7 +464,7 @@ private lemma ZariskisMainProperty.of_adjoin_eq_top (p : Ideal S) [p.IsPrime] [Algebra.WeaklyQuasiFiniteAt R p] (x : S) (hx : Algebra.adjoin R {x} = ⊤) : ZariskisMainProperty R p := by wlog H : integralClosure R S = ⊥ - · letI inst : Algebra (integralClosure R S) (Localization.AtPrime p) := + · let inst : Algebra (integralClosure R S) (Localization.AtPrime p) := OreLocalization.instAlgebra have inst : Algebra.WeaklyQuasiFiniteAt (integralClosure R S) p := .of_restrictScalars R (integralClosure R S) _ @@ -508,7 +508,7 @@ private lemma ZariskisMainProperty.of_algHom_polynomial (p : Ideal S) [p.IsPrime] [Algebra.WeaklyQuasiFiniteAt R p] (f : R[X] →ₐ[R] S) (hf : f.Finite) : ZariskisMainProperty R p := by wlog H : integralClosure R S = ⊥ - · letI inst : Algebra (integralClosure R S) (Localization.AtPrime p) := + · let inst : Algebra (integralClosure R S) (Localization.AtPrime p) := OreLocalization.instAlgebra have inst : Algebra.WeaklyQuasiFiniteAt (integralClosure R S) p := .of_restrictScalars R (integralClosure R S) _ @@ -595,7 +595,7 @@ private lemma ZariskisMainProperty.of_algHom_mvPolynomial MvPolynomial.aeval fun i ↦ ⟨f (.X i.succ), Algebra.subset_adjoin (by simp)⟩ have := IH (R := R) (S := R') (p.under R') φ <| by refine RingHom.finite_iff_isIntegral_and_finiteType.mpr ⟨?_, ?_⟩ - · letI := φ.toAlgebra + · let := φ.toAlgebra have : IsScalarTower (MvPolynomial (Fin n) R) R' S := .of_algebraMap_eq' <| by ext <;> simp [φ, (f'.toRingHom.comp C).algebraMap_toAlgebra, φ.algebraMap_toAlgebra, f', MvPolynomial.finSuccEquiv, MvPolynomial.optionEquivLeft] diff --git a/Mathlib/SetTheory/Cardinal/Arithmetic.lean b/Mathlib/SetTheory/Cardinal/Arithmetic.lean index 98b12da1d49fa8..be12df1074de38 100644 --- a/Mathlib/SetTheory/Cardinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Cardinal/Arithmetic.lean @@ -840,7 +840,7 @@ theorem mk_compl_eq_mk_compl_finite_lift {α : Type u} {β : Type v} [Finite α] (h2 : lift.{v, u} #s = lift.{u, v} #t) : lift.{v} #(sᶜ : Set α) = lift.{u} #(tᶜ : Set β) := by cases nonempty_fintype α - rcases lift_mk_eq'.1 h1 with ⟨e⟩; letI : Fintype β := Fintype.ofEquiv α e + rcases lift_mk_eq'.1 h1 with ⟨e⟩; let : Fintype β := Fintype.ofEquiv α e replace h1 : Fintype.card α = Fintype.card β := (Fintype.ofEquiv_card _).symm classical lift s to Finset α using s.toFinite @@ -886,7 +886,7 @@ theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : · exact extend_function_finite f h · apply extend_function f obtain ⟨g⟩ := id h - haveI := Infinite.of_injective _ g.injective + have := Infinite.of_injective _ g.injective rw [← lift_mk_eq'] at h ⊢ rwa [mk_compl_of_infinite s hs, mk_compl_of_infinite] rwa [← lift_lt, mk_range_eq_of_injective f.injective, ← h, lift_lt] diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index b95ae55919b8f8..e5c1792351d83c 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -80,7 +80,7 @@ theorem prod_eq_of_fintype {α : Type u} [h : Fintype α] (f : α → Cardinal.{ revert f refine Fintype.induction_empty_option ?_ ?_ ?_ α (h_fintype := h) · intro α β hβ e h f - letI := Fintype.ofEquiv β e.symm + let := Fintype.ofEquiv β e.symm rw [← e.prod_comp f, ← h] exact mk_congr (e.piCongrLeft _).symm · intro f @@ -362,7 +362,7 @@ theorem lt_aleph0 {c : Cardinal} : c < ℵ₀ ↔ ∃ n : ℕ, c = n := lift S to Finset ℕ using this simp contrapose! h' - haveI := Infinite.to_subtype h' + have := Infinite.to_subtype h' exact ⟨Infinite.natEmbedding S⟩, fun ⟨_, e⟩ => e.symm ▸ natCast_lt_aleph0⟩ lemma succ_eq_of_lt_aleph0 {c : Cardinal} (h : c < ℵ₀) : Order.succ c = c + 1 := by diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean index 2b981eef602627..53c57336de09aa 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean @@ -558,7 +558,7 @@ theorem mk_bounded_subset {α : Type*} (h : IsStrongPrelimit #α) {r : α → α [IsWellOrder α r] (hr : (#α).ord = type r) : #{ s : Set α // Bounded r s } = #α := by rcases eq_or_ne #α 0 with (ha | ha) · rw [ha] - haveI := mk_eq_zero_iff.1 ha + have := mk_eq_zero_iff.1 ha rw [mk_eq_zero_iff] constructor rintro ⟨s, hs⟩ @@ -589,7 +589,7 @@ theorem mk_subset_mk_lt_cof {α : Type*} (h : IsStrongPrelimit #α) : have h' : IsStrongLimit #α := ⟨ha, @h⟩ rcases exists_ord_eq α with ⟨r, wo, hr⟩ classical - letI := linearOrderOfSTO r + let := linearOrderOfSTO r apply le_antisymm · conv_rhs => rw [← mk_bounded_subset h hr] apply mk_subtype_le_of_subset diff --git a/Mathlib/SetTheory/Cardinal/Finite.lean b/Mathlib/SetTheory/Cardinal/Finite.lean index 4e24ecade762c3..641e8fc54643bd 100644 --- a/Mathlib/SetTheory/Cardinal/Finite.lean +++ b/Mathlib/SetTheory/Cardinal/Finite.lean @@ -191,7 +191,7 @@ def equivFinOfCardPos {α : Type*} (h : Nat.card α ≠ 0) : α ≃ Fin (Nat.car · simp only [card_eq_zero_of_infinite, ne_eq, not_true_eq_false] at h theorem card_of_subsingleton (a : α) [Subsingleton α] : Nat.card α = 1 := by - letI := Fintype.ofSubsingleton a + let := Fintype.ofSubsingleton a rw [card_eq_fintype_card, Fintype.card_ofSubsingleton a] theorem card_eq_one_iff_unique : Nat.card α = 1 ↔ Subsingleton α ∧ Nonempty α := @@ -235,14 +235,14 @@ theorem card_plift (α : Type*) : Nat.card (PLift α) = Nat.card α := theorem card_sigma {β : α → Type*} [Fintype α] [∀ a, Finite (β a)] : Nat.card (Sigma β) = ∑ a, Nat.card (β a) := by - letI _ (a : α) : Fintype (β a) := Fintype.ofFinite (β a) + let _ (a : α) : Fintype (β a) := Fintype.ofFinite (β a) simp_rw [Nat.card_eq_fintype_card, Fintype.card_sigma] theorem card_pi {β : α → Type*} [Fintype α] : Nat.card (∀ a, β a) = ∏ a, Nat.card (β a) := by simp_rw [Nat.card, mk_pi, prod_eq_of_fintype, toNat_lift, _root_.map_prod] theorem card_fun [Finite α] : Nat.card (α → β) = Nat.card β ^ Nat.card α := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α rw [Nat.card_pi, Finset.prod_const, Finset.card_univ, ← Nat.card_eq_fintype_card] @[simp] @@ -394,8 +394,8 @@ lemma card_fun {α β : Type*} : card (α → β) = card β ^ card α := by · simp [(card_eq_zero_iff_empty α).2 α_emp] rcases finite_or_infinite α · rcases finite_or_infinite β - · letI := Fintype.ofFinite α - letI := Fintype.ofFinite β + · let := Fintype.ofFinite α + let := Fintype.ofFinite β simp · simp only [card_eq_top_of_infinite] rw [top_epow] @@ -407,9 +407,9 @@ lemma card_fun {α β : Type*} : card (α → β) = card β ^ card α := by simp [b_0] · rw [b_1, one_epow] apply le_antisymm - · letI := (card_le_one_iff_subsingleton β).1 b_1.le + · let := (card_le_one_iff_subsingleton β).1 b_1.le exact (card_le_one_iff_subsingleton (α → β)).2 Pi.instSubsingleton - · letI := (one_le_card_iff_nonempty β).1 b_1.ge + · let := (one_le_card_iff_nonempty β).1 b_1.ge exact (one_le_card_iff_nonempty (α → β)).2 Pi.instNonempty · rw [epow_top b_2, card_eq_top] rw [one_lt_card_iff_nontrivial β] at b_2 diff --git a/Mathlib/SetTheory/Cardinal/NatCard.lean b/Mathlib/SetTheory/Cardinal/NatCard.lean index 9ab54e13a093c5..742c5bd2782791 100644 --- a/Mathlib/SetTheory/Cardinal/NatCard.lean +++ b/Mathlib/SetTheory/Cardinal/NatCard.lean @@ -49,12 +49,12 @@ open scoped Classical in theorem Nat.card_eq (α : Type*) : Nat.card α = if _ : Finite α then @Fintype.card α (Fintype.ofFinite α) else 0 := by cases finite_or_infinite α - · letI := Fintype.ofFinite α + · let := Fintype.ofFinite α simp only [this, *, Nat.card_eq_fintype_card, dif_pos] · simp only [*, card_eq_zero_of_infinite, not_finite_iff_infinite.mpr, dite_false] theorem Finite.card_pos_iff [Finite α] : 0 < Nat.card α ↔ Nonempty α := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α rw [Nat.card_eq_fintype_card, Fintype.card_pos_iff] theorem Finite.card_pos [Finite α] [h : Nonempty α] : 0 < Nat.card α := @@ -63,16 +63,16 @@ theorem Finite.card_pos [Finite α] [h : Nonempty α] : 0 < Nat.card α := namespace Finite theorem card_eq [Finite α] [Finite β] : Nat.card α = Nat.card β ↔ Nonempty (α ≃ β) := by - haveI := Fintype.ofFinite α - haveI := Fintype.ofFinite β + have := Fintype.ofFinite α + have := Fintype.ofFinite β simp only [Nat.card_eq_fintype_card, Fintype.card_eq] theorem card_le_one_iff_subsingleton [Finite α] : Nat.card α ≤ 1 ↔ Subsingleton α := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α simp only [Nat.card_eq_fintype_card, Fintype.card_le_one_iff_subsingleton] theorem one_lt_card_iff_nontrivial [Finite α] : 1 < Nat.card α ↔ Nontrivial α := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α simp only [Nat.card_eq_fintype_card, Fintype.one_lt_card_iff_nontrivial] theorem one_lt_card [Finite α] [h : Nontrivial α] : 1 < Nat.card α := @@ -80,14 +80,14 @@ theorem one_lt_card [Finite α] [h : Nontrivial α] : 1 < Nat.card α := @[simp] theorem card_option [Finite α] : Nat.card (Option α) = Nat.card α + 1 := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α simp only [Nat.card_eq_fintype_card, Fintype.card_option] theorem card_le_of_embedding [Finite β] (f : α ↪ β) : Nat.card α ≤ Nat.card β := Nat.card_le_card_of_injective _ f.injective theorem card_eq_zero_iff [Finite α] : Nat.card α = 0 ↔ IsEmpty α := by - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α simp only [Nat.card_eq_fintype_card, Fintype.card_eq_zero_iff] /-- If `f` is injective, then `Nat.card α ≤ Nat.card β`. We must also assume @@ -114,10 +114,10 @@ theorem card_le_of_surjective' {f : α → β} (hf : Function.Surjective f) theorem card_eq_zero_of_surjective {f : α → β} (hf : Function.Surjective f) (h : Nat.card β = 0) : Nat.card α = 0 := by cases finite_or_infinite β - · haveI := card_eq_zero_iff.mp h - haveI := Function.isEmpty f + · have := card_eq_zero_iff.mp h + have := Function.isEmpty f exact Nat.card_of_isEmpty - · haveI := Infinite.of_surjective f hf + · have := Infinite.of_surjective f hf exact Nat.card_eq_zero_of_infinite /-- NB: `Nat.card` is defined to be `0` for infinite types. -/ @@ -137,13 +137,13 @@ theorem card_range_le [Finite α] (f : α → β) : Nat.card (Set.range f) ≤ N theorem card_subtype_le [Finite α] (p : α → Prop) : Nat.card { x // p x } ≤ Nat.card α := by classical - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α simpa only [Nat.card_eq_fintype_card] using Fintype.card_subtype_le p theorem card_subtype_lt [Finite α] {p : α → Prop} {x : α} (hx : ¬p x) : Nat.card { x // p x } < Nat.card α := by classical - haveI := Fintype.ofFinite α + have := Fintype.ofFinite α simpa only [Nat.card_eq_fintype_card, gt_iff_lt] using Fintype.card_subtype_lt hx end Finite diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index 600df08519e708..bee5851a6a4934 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -362,7 +362,7 @@ protected theorem lt_wf : @WellFounded Cardinal.{u} (· < ·) := by_contradiction fun h => by let ι := { c : Cardinal // ¬Acc (· < ·) c } let f : ι → Cardinal := Subtype.val - haveI hι : Nonempty ι := ⟨⟨_, h⟩⟩ + have hι : Nonempty ι := ⟨⟨_, h⟩⟩ obtain ⟨⟨c : Cardinal, hc : ¬Acc (· < ·) c⟩, ⟨h_1 : ∀ j, (f ⟨c, hc⟩).out ↪ (f j).out⟩⟩ := Embedding.min_injective fun i => (f i).out refine hc (Acc.intro _ fun j h' => by_contradiction fun hj => h'.2 ?_) diff --git a/Mathlib/SetTheory/Ordinal/Family.lean b/Mathlib/SetTheory/Ordinal/Family.lean index 4f0fe3e266cc60..6fb387982ff065 100644 --- a/Mathlib/SetTheory/Ordinal/Family.lean +++ b/Mathlib/SetTheory/Ordinal/Family.lean @@ -424,7 +424,7 @@ theorem lt_bsup {o : Ordinal.{u}} (f : ∀ a < o, Ordinal.{max u v}) {a} : theorem IsNormal.bsup {f : Ordinal → Ordinal} (H : IsNormal f) {o : Ordinal} : ∀ (g : ∀ a < o, Ordinal), o ≠ 0 → f (bsup o g) = bsup o fun a h => f (g a h) := inductionOn o fun α r _ g h => by - haveI := type_ne_zero_iff_nonempty.1 h + have := type_ne_zero_iff_nonempty.1 h rw [← iSup'_eq_bsup r, Order.IsNormal.map_iSup H bddAbove_of_small, ← iSup'_eq_bsup r] <;> rfl diff --git a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean index d97e03ca2ebe51..4c11897bc95496 100644 --- a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean +++ b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean @@ -206,7 +206,7 @@ theorem exists_fundamental_sequence (a : Ordinal.{u}) : rcases ord_eq ι with ⟨r, wo, hr⟩ let r' := Subrel r fun i ↦ ∀ j, r j i → f j < f i let hrr' : r' ↪r r := Subrel.relEmbedding _ _ - haveI := hrr'.isWellOrder + have := hrr'.isWellOrder refine ⟨_, _, hrr'.ordinal_type_le.trans ?_, @fun i j _ h _ => (enum r' ⟨j, h⟩).prop _ ?_, le_antisymm (blsub_le fun i hi => lsub_le_iff.1 hf.le _) ?_⟩ diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index 5adbc6f5b49997..ec87ed35068b7a 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -425,14 +425,14 @@ instance add_nf (o₁ o₂) : ∀ [NF o₁] [NF o₂], NF (o₁ + o₂) theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂ | 0, o, _, _ => by simp | oadd e n a, o, h₁, h₂ => by - haveI := h₁.snd; have h' := repr_add a o + have := h₁.snd; have h' := repr_add a o conv_lhs at h' => simp [HAdd.hAdd, Add.add] have nf := ONote.add_nf a o conv at nf => simp [HAdd.hAdd, Add.add] conv in _ + o => simp [HAdd.hAdd, Add.add] rcases h : add a o with - | ⟨e', n', a'⟩ <;> simp only [add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢ - have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e' + have := h₁.fst; have := nf.fst; have ee := cmp_compares e e' cases he : cmp e e' <;> simp only [he, Ordering.compares_gt, Ordering.compares_lt, Ordering.compares_eq, repr, gt_iff_lt, PNat.add_coe, Nat.cast_add] at ee ⊢ · rw [← add_assoc, @add_of_omega0_opow_le _ (repr e') (ω ^ repr e' * (n' : ℕ))] @@ -472,7 +472,7 @@ theorem repr_sub : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ - o₂) = rep | 0, o, _, h₂ => by cases o <;> exact (Ordinal.zero_sub _).symm | oadd _ _ _, 0, _, _ => (Ordinal.sub_zero _).symm | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by - haveI := h₁.snd; haveI := h₂.snd; have h' := repr_sub a₁ a₂ + have := h₁.snd; have := h₂.snd; have h' := repr_sub a₁ a₂ conv_lhs at h' => dsimp [HSub.hSub, Sub.sub, sub] conv_lhs => dsimp only [HSub.hSub, Sub.sub]; dsimp only [sub] have ee := @cmp_compares _ _ h₁.fst h₂.fst @@ -530,8 +530,8 @@ theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a by_cases e0 : e₂ = 0 <;> simp only [e0, oadd_mul, ↓reduceIte] · apply NFBelow.oadd h₁.fst h₁.snd grw [← h₂.lt.pos, add_zero] - · haveI := h₁.fst - haveI := h₂.fst + · have := h₁.fst + have := h₂.fst apply NFBelow.oadd · infer_instance · rwa [repr_add] @@ -560,8 +560,8 @@ theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = rep simp only [xe, h₂.zero_of_zero e0, repr_zero, add_zero] rw [Nat.cast_add_one x, add_mul_add_one _ ao, mul_assoc] · simp only [repr] - haveI := h₁.fst - haveI := h₂.fst + have := h₁.fst + have := h₂.fst simp only [Mul.mul, mul, e0, ite_false, repr.eq_2, repr_add, opow_add, IH, repr, mul_add] rw [← mul_assoc] congr 2 @@ -641,8 +641,8 @@ theorem split_eq_scale_split' : ∀ {o o' m} [NF o], split' o = (o', m) → spli exact ⟨rfl, rfl⟩ · revert p rcases h' : split' a with ⟨a', m'⟩ - haveI := h.fst - haveI := h.snd + have := h.fst + have := h.snd simp only [split_eq_scale_split' h', and_imp] have : 1 + (e - 1) = e := by refine repr_inj.1 ?_ @@ -662,8 +662,8 @@ theorem nf_repr_split' : ∀ {o o' m} [NF o], split' o = (o', m) → NF o' ∧ r simp [h.zero_of_zero e0, NF.zero] · revert p rcases h' : split' a with ⟨a', m'⟩ - haveI := h.fst - haveI := h.snd + have := h.fst + have := h.snd obtain ⟨IH₁, IH₂⟩ := nf_repr_split' h' simp only [IH₂, and_imp] intros @@ -684,7 +684,7 @@ theorem scale_eq_mul (x) [NF x] : ∀ (o) [NF o], scale x o = oadd x 1 0 * o | 0, _ => rfl | oadd e n a, h => by simp only [HMul.hMul]; simp only [scale] - haveI := h.snd + have := h.snd by_cases e0 : e = 0 · simp_rw [scale_eq_mul] simp [Mul.mul, mul, e0, h.zero_of_zero, @@ -734,14 +734,14 @@ instance nf_opowAux (e a0 a) [NF e] [NF a0] [NF a] : ∀ k m, NF (opowAux e a0 a cases k with | zero => exact NF.oadd_zero _ _ | succ k => - haveI := nf_opowAux e a0 a k + have := nf_opowAux e a0 a k simp only [mulNat_eq_mul]; infer_instance instance nf_opow (o₁ o₂) [NF o₁] [NF o₂] : NF (o₁ ^ o₂) := by rcases e₁ : split o₁ with ⟨a, m⟩ have na := (nf_repr_split e₁).1 rcases e₂ : split' o₂ with ⟨b', k⟩ - haveI := (nf_repr_split' e₂).1 + have := (nf_repr_split' e₂).1 obtain - | ⟨a0, n, a'⟩ := a #adaptation_note /-- Proof repaired after leanprover/lean4#13363. The next branch was previously @@ -820,7 +820,7 @@ theorem repr_opow_aux₂ {a0 a'} [N0 : NF a0] [Na' : NF a'] (m : ℕ) (d : ω ((ω ^ repr a0) ^ (k : Ordinal)) * ((ω ^ repr a0) * (n : ℕ) + repr a') + R = ((ω ^ repr a0) * (n : ℕ) + repr a' + m) ^ succ (k : Ordinal) := by intro R' - haveI No : NF (oadd a0 n a') := + have No : NF (oadd a0 n a') := N0.oadd n (Na'.below_of_lt' <| lt_of_le_of_lt le_self_add h) induction k with | zero => cases m <;> simp [R', opowAux] @@ -944,8 +944,8 @@ theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o · simpa [Nat.one_le_iff_ne_zero] · rw [← Nat.cast_succ, lt_omega0] exact ⟨_, rfl⟩ - · haveI := N₁.fst - haveI := N₁.snd + · have := N₁.fst + have := N₁.snd obtain ⟨a00, ad⟩ := N₁.of_dvd_omega0 (split_dvd e₁) have al := split_add_lt e₁ have aa : repr (a' + ofNat m) = repr a' + m := by diff --git a/Mathlib/SetTheory/Ordinal/Rank.lean b/Mathlib/SetTheory/Ordinal/Rank.lean index cba2406e83081f..906dcaf237c9b0 100644 --- a/Mathlib/SetTheory/Ordinal/Rank.lean +++ b/Mathlib/SetTheory/Ordinal/Rank.lean @@ -94,7 +94,7 @@ theorem WellFoundedGT.rank_strictAnti [Preorder α] [WellFoundedGT α] : @[simp] theorem IsWellFounded.rank_eq_typein (r) [IsWellOrder α r] : rank r = Ordinal.typein r := by classical - letI := linearOrderOfSTO r + let := linearOrderOfSTO r ext a exact InitialSeg.eq (⟨(OrderEmbedding.ofStrictMono _ WellFoundedLT.rank_strictMono).ltEmbedding, fun a b h ↦ mem_range_rank_of_le h.le⟩) (Ordinal.typein r) a diff --git a/Mathlib/Tactic/NormNum/LegendreSymbol.lean b/Mathlib/Tactic/NormNum/LegendreSymbol.lean index 25a5be8211c825..7dac2cf1af7259 100644 --- a/Mathlib/Tactic/NormNum/LegendreSymbol.lean +++ b/Mathlib/Tactic/NormNum/LegendreSymbol.lean @@ -116,7 +116,7 @@ theorem jacobiSymNat.odd_even (a b c : ℕ) (r : ℤ) (ha : a % 2 = 1) (hb : b % decide rcases eq_or_ne c 0 with (rfl | hc') · rw [← hr, Nat.eq_zero_of_dvd_of_div_eq_zero (Nat.dvd_of_mod_eq_zero hb) hc] - · haveI : NeZero c := ⟨hc'⟩ + · have : NeZero c := ⟨hc'⟩ -- for `jacobiSym.mul_right` rwa [← Nat.mod_add_div b 2, hb, hc, Nat.zero_add, jacobiSymNat, jacobiSym.mul_right, ← jacobiSym.legendreSym.to_jacobiSym, ha', one_mul] diff --git a/Mathlib/Topology/Algebra/ConstMulAction.lean b/Mathlib/Topology/Algebra/ConstMulAction.lean index 69f48dd54a30fe..4a1d99ad78a349 100644 --- a/Mathlib/Topology/Algebra/ConstMulAction.lean +++ b/Mathlib/Topology/Algebra/ConstMulAction.lean @@ -580,7 +580,7 @@ space is T₂. -/] instance (priority := 100) t2Space_of_properlyDiscontinuousSMul_of_t2Space [T2Space T] [LocallyCompactSpace T] [ContinuousConstSMul Γ T] [ProperlyDiscontinuousSMul Γ T] : T2Space (Quotient (MulAction.orbitRel Γ T)) := by - letI := MulAction.orbitRel Γ T + let := MulAction.orbitRel Γ T set Q := Quotient (MulAction.orbitRel Γ T) rw [t2Space_iff_nhds] let f : T → Q := Quotient.mk' diff --git a/Mathlib/Topology/Algebra/ContinuousAffineMap.lean b/Mathlib/Topology/Algebra/ContinuousAffineMap.lean index 3a30c39adfc806..10e1a5f31ba0f2 100644 --- a/Mathlib/Topology/Algebra/ContinuousAffineMap.lean +++ b/Mathlib/Topology/Algebra/ContinuousAffineMap.lean @@ -498,7 +498,7 @@ def decompEquiv : (V →ᴬ[R] Q) ≃ Q × (V →L[R] W) where simp_rw [vadd_apply, f.contLinear.coe_toContinuousAffineMap, coe_const, Function.const_apply, ← f.map_vadd, vadd_eq_add, add_zero] right_inv := by - haveI := IsTopologicalAddTorsor.to_isTopologicalAddGroup W Q + have := IsTopologicalAddTorsor.to_isTopologicalAddGroup W Q rintro ⟨v, f⟩; ext <;> simp @[simp] @@ -519,7 +519,7 @@ theorem decompEquiv_symm_apply (p : Q × (V →L[R] W)) (x : V) : @[simp] theorem decompEquiv_symm_contLinear (p : Q × (V →L[R] W)) : ((decompEquiv R V Q).symm p).contLinear = p.2 := by - haveI := IsTopologicalAddTorsor.to_isTopologicalAddGroup W Q + have := IsTopologicalAddTorsor.to_isTopologicalAddGroup W Q ext; simp [decompEquiv] end diff --git a/Mathlib/Topology/Algebra/FilterBasis.lean b/Mathlib/Topology/Algebra/FilterBasis.lean index fa2f92fdcbbf81..15d529335c60eb 100644 --- a/Mathlib/Topology/Algebra/FilterBasis.lean +++ b/Mathlib/Topology/Algebra/FilterBasis.lean @@ -190,7 +190,7 @@ topological group. -/ additive group filter basis, then it's an additive topological group. -/] instance (priority := 100) isTopologicalGroup (B : GroupFilterBasis G) : @IsTopologicalGroup G B.topology _ := by - letI := B.topology + let := B.topology have basis := B.nhds_one_hasBasis have basis' := basis.prod basis refine IsTopologicalGroup.of_nhds_one ?_ ?_ ?_ ?_ @@ -264,10 +264,10 @@ a ring filter basis then it's a topological ring. -/ instance (priority := 100) isTopologicalRing {R : Type u} [Ring R] (B : RingFilterBasis R) : @IsTopologicalRing R B.topology _ := by let B' := B.toAddGroupFilterBasis - letI := B'.topology + let := B'.topology have basis := B'.nhds_zero_hasBasis have basis' := basis.prod basis - haveI := B'.isTopologicalAddGroup + have := B'.isTopologicalAddGroup apply IsTopologicalRing.of_addGroup_of_nhds_zero · rw [basis'.tendsto_iff basis] suffices ∀ U ∈ B', ∃ V W, (V ∈ B' ∧ W ∈ B') ∧ ∀ a b, a ∈ V → b ∈ W → a * b ∈ U by simpa diff --git a/Mathlib/Topology/Algebra/Group/GroupTopology.lean b/Mathlib/Topology/Algebra/Group/GroupTopology.lean index 43dfdcf1f08f9c..5074ba1bd69c40 100644 --- a/Mathlib/Topology/Algebra/Group/GroupTopology.lean +++ b/Mathlib/Topology/Algebra/Group/GroupTopology.lean @@ -50,8 +50,8 @@ variable [Group α] theorem continuous_mul' (g : GroupTopology α) : haveI := g.toTopologicalSpace Continuous fun p : α × α => p.1 * p.2 := by - letI := g.toTopologicalSpace - haveI := g.toIsTopologicalGroup + let := g.toTopologicalSpace + have := g.toIsTopologicalGroup exact continuous_mul /-- A version of the global `continuous_inv` suitable for dot notation. -/ @@ -59,8 +59,8 @@ theorem continuous_mul' (g : GroupTopology α) : theorem continuous_inv' (g : GroupTopology α) : haveI := g.toTopologicalSpace Continuous (Inv.inv : α → α) := by - letI := g.toTopologicalSpace - haveI := g.toIsTopologicalGroup + let := g.toTopologicalSpace + have := g.toIsTopologicalGroup exact continuous_inv @[to_additive] @@ -102,7 +102,7 @@ theorem toTopologicalSpace_top : (⊤ : GroupTopology α).toTopologicalSpace = instance : Bot (GroupTopology α) := let _t : TopologicalSpace α := ⊥ ⟨{ continuous_mul := by - haveI := discreteTopology_bot α + have := discreteTopology_bot α fun_prop continuous_inv := continuous_bot }⟩ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean index 01c9ccbcfcd3fa..bcff99254b71ce 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean @@ -183,7 +183,7 @@ Note that in this case `HasSum f a` is satisfied for *every* element `a` of the value assigned to the `tsum` is a question of conventions. -/] lemma tprod_bot (hL : ¬L.NeBot) (f : β → α) : ∏'[L] b, f b = ∏ᶠ b, f b := by simp only [tprod_def, dif_pos (multipliable_bot hL f)] - haveI : L.LeAtTop := L.leAtTop_of_not_NeBot hL + have : L.LeAtTop := L.leAtTop_of_not_NeBot hL rw [L.support_eq_univ, Set.inter_univ, Set.mulIndicator_univ] by_cases hf : (mulSupport f).Finite · rw [eq_true_intro hf, if_pos] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean index 59d7d6eb32c464..1a4cbbe72bc654 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean @@ -329,7 +329,7 @@ variable {G : Type*} [TopologicalSpace G] [CommGroup G] [IsTopologicalGroup G] { theorem Multipliable.vanishing (hf : Multipliable f) ⦃e : Set G⦄ (he : e ∈ 𝓝 (1 : G)) : ∃ s : Finset α, ∀ t, Disjoint t s → (∏ k ∈ t, f k) ∈ e := by classical - letI : UniformSpace G := IsTopologicalGroup.rightUniformSpace G + let : UniformSpace G := IsTopologicalGroup.rightUniformSpace G have : IsUniformGroup G := isUniformGroup_of_commGroup exact cauchySeq_finset_iff_prod_vanishing.1 hf.hasProd.cauchySeq e he @@ -337,7 +337,7 @@ theorem Multipliable.vanishing (hf : Multipliable f) ⦃e : Set G⦄ (he : e ∈ theorem Multipliable.tprod_vanishing (hf : Multipliable f) ⦃e : Set G⦄ (he : e ∈ 𝓝 1) : ∃ s : Finset α, ∀ t : Set α, Disjoint t s → (∏' b : t, f b) ∈ e := by classical - letI : UniformSpace G := IsTopologicalGroup.rightUniformSpace G + let : UniformSpace G := IsTopologicalGroup.rightUniformSpace G have : IsUniformGroup G := isUniformGroup_of_commGroup exact cauchySeq_finset_iff_tprod_vanishing.1 hf.hasProd.cauchySeq e he @@ -404,7 +404,7 @@ theorem multipliable_const_iff [Infinite β] [T2Space G] (a : G) : @[to_additive (attr := simp)] theorem tprod_const [T2Space G] (a : G) : ∏' _ : β, a = a ^ (Nat.card β) := by rcases finite_or_infinite β with hβ | hβ - · letI : Fintype β := Fintype.ofFinite β + · let : Fintype β := Fintype.ofFinite β rw [tprod_eq_prod (s := univ) (fun x hx ↦ (hx (mem_univ x)).elim)] simp only [prod_const, Nat.card_eq_fintype_card, Fintype.card] · simp only [Nat.card_eq_zero_of_infinite, pow_zero] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean index 4f65111db79aaf..3fa8bd6d7034fc 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean @@ -193,7 +193,7 @@ instance [Countable β] : IsCountablyGenerated (unconditional β).filter := lemma eq_unconditional_of_finite {β} [Finite β] (L : SummationFilter β) [L.LeAtTop] [L.NeBot] : L = unconditional β := by classical - haveI := Fintype.ofFinite β + have := Fintype.ofFinite β have hAtTop : (atTop : Filter (Finset β)) = pure Finset.univ := by rw [(isTop_iff_eq_top.mpr rfl).atTop_eq (a := Finset.univ), ← Finset.top_eq_univ, Ici_top, principal_singleton] diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean index ac1b694b34f284..a24630c413160c 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean @@ -629,9 +629,9 @@ instance QuotientGroup.completeSpace_right' (G : Type u) [Group G] [TopologicalS sequential antitone neighborhood basis `u` for `𝓝 (1 : G)` so that `(u (n + 1)) ^ 2 ⊆ u n`, and this descends to an antitone neighborhood basis `v` for `𝓝 (1 : G ⧸ N)`. Since `𝓤 (G ⧸ N)` is countably generated, it suffices to show any Cauchy sequence `x` converges. -/ - letI : UniformSpace (G ⧸ N) := IsTopologicalGroup.rightUniformSpace (G ⧸ N) - letI : UniformSpace G := IsTopologicalGroup.rightUniformSpace G - haveI : (𝓤 (G ⧸ N)).IsCountablyGenerated := comap.isCountablyGenerated _ _ + let : UniformSpace (G ⧸ N) := IsTopologicalGroup.rightUniformSpace (G ⧸ N) + let : UniformSpace G := IsTopologicalGroup.rightUniformSpace G + have : (𝓤 (G ⧸ N)).IsCountablyGenerated := comap.isCountablyGenerated _ _ obtain ⟨u, hu, u_mul⟩ := IsTopologicalGroup.exists_antitone_basis_nhds_one G obtain ⟨hv, v_anti⟩ := hu.map ((↑) : G → G ⧸ N) rw [← QuotientGroup.nhds_eq N 1, QuotientGroup.mk_one] at hv diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean b/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean index a77292075775c4..a600331bc4a9b0 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean @@ -64,7 +64,7 @@ lemma Subgroup.discreteTopology_iff_of_finiteIndex {H : Subgroup G} [H.FiniteInd @[to_additive] lemma Subgroup.discreteTopology_iff_of_isFiniteRelIndex {H K : Subgroup G} (hHK : H ≤ K) [IsFiniteRelIndex H K] : DiscreteTopology H ↔ DiscreteTopology K := by - haveI : (H.subgroupOf K).FiniteIndex := IsFiniteRelIndex.to_finiteIndex_subgroupOf + have : (H.subgroupOf K).FiniteIndex := IsFiniteRelIndex.to_finiteIndex_subgroupOf rw [← (subgroupOfContinuousMulEquivOfLe hHK).discreteTopology_iff, discreteTopology_iff_of_finiteIndex] diff --git a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean index 60e8aeb7c50f87..a11feca50ce8b5 100644 --- a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean +++ b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean @@ -210,8 +210,8 @@ variable [CompleteSpace 𝕜] private theorem continuous_equivFun_basis_aux [T2Space E] {ι : Type v} [Finite ι] (ξ : Basis ι 𝕜 E) : Continuous ξ.equivFun := by have := Fintype.ofFinite ι - letI : UniformSpace E := IsTopologicalAddGroup.rightUniformSpace E - letI : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup + let : UniformSpace E := IsTopologicalAddGroup.rightUniformSpace E + let : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup suffices ∀ n, Fintype.card ι = n → Continuous ξ.equivFun by exact this _ rfl intro n hn induction n generalizing ι E with @@ -219,12 +219,12 @@ private theorem continuous_equivFun_basis_aux [T2Space E] {ι : Type v} [Finite rw [Fintype.card_eq_zero_iff] at hn exact continuous_of_const fun x y => funext hn.elim | succ n IH => - haveI : FiniteDimensional 𝕜 E := ξ.finiteDimensional_of_finite + have : FiniteDimensional 𝕜 E := ξ.finiteDimensional_of_finite -- first step: thanks to the induction hypothesis, any n-dimensional subspace is equivalent -- to a standard space of dimension n, hence it is complete and therefore closed. have H₁ : ∀ s : Submodule 𝕜 E, finrank 𝕜 s = n → IsClosed (s : Set E) := by intro s s_dim - letI : IsUniformAddGroup s := s.toAddSubgroup.isUniformAddGroup + let : IsUniformAddGroup s := s.toAddSubgroup.isUniformAddGroup let b := Basis.ofVectorSpace 𝕜 s have U : IsUniformEmbedding b.equivFun.symm.toEquiv := by have : Fintype.card (Basis.ofVectorSpaceIndex 𝕜 s) = n := by @@ -640,7 +640,7 @@ theorem FiniteDimensional.of_totallyBounded_nhds_zero {U : Set Eᵤ} (hU_nhds : obtain ⟨F, hF_finite, hF_cover⟩ := totallyBounded_iff_subset_finite_iUnion_nhds_zero.mp hU_tb (c • U) ((set_smul_mem_nhds_zero_iff hc_ne).mpr hU_nhds) let M : Submodule 𝕜 Eᵤ := Submodule.span 𝕜 F - letI : FiniteDimensional 𝕜 M := Finite.span_of_finite 𝕜 hF_finite + let : FiniteDimensional 𝕜 M := Finite.span_of_finite 𝕜 hF_finite have h_cover : U ⊆ M + c • U := fun x hx ↦ by obtain ⟨f, hf, y, hy, rfl⟩ := Set.mem_iUnion₂.mp <| hF_cover hx exact ⟨f, Submodule.subset_span hf, y, hy, rfl⟩ diff --git a/Mathlib/Topology/Algebra/Module/LocallyConvex.lean b/Mathlib/Topology/Algebra/Module/LocallyConvex.lean index c73f0cfd0adb75..e4cf4206fca136 100644 --- a/Mathlib/Topology/Algebra/Module/LocallyConvex.lean +++ b/Mathlib/Topology/Algebra/Module/LocallyConvex.lean @@ -144,8 +144,8 @@ is closed admit disjoint convex open neighborhoods. -/ theorem Disjoint.exists_open_convexes (disj : Disjoint s t) (hs₁ : Convex 𝕜 s) (hs₂ : IsCompact s) (ht₁ : Convex 𝕜 t) (ht₂ : IsClosed t) : ∃ u v, IsOpen u ∧ IsOpen v ∧ Convex 𝕜 u ∧ Convex 𝕜 v ∧ s ⊆ u ∧ t ⊆ v ∧ Disjoint u v := by - letI : UniformSpace E := IsTopologicalAddGroup.rightUniformSpace E - haveI : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup + let : UniformSpace E := IsTopologicalAddGroup.rightUniformSpace E + have : IsUniformAddGroup E := isUniformAddGroup_of_addCommGroup have := (LocallyConvexSpace.convex_open_basis_zero 𝕜 E).comap fun x : E × E => x.2 - x.1 rw [← uniformity_eq_comap_nhds_zero] at this rcases disj.exists_uniform_thickening_of_basis this hs₂ ht₂ with ⟨V, ⟨hV0, hVopen, hVconvex⟩, hV⟩ @@ -173,7 +173,7 @@ variable {ι : Sort*} {𝕜 E F : Type*} [Semiring 𝕜] [PartialOrder 𝕜] protected theorem LocallyConvexSpace.sInf {ts : Set (TopologicalSpace E)} (h : ∀ t ∈ ts, @LocallyConvexSpace 𝕜 E _ _ _ _ t) : @LocallyConvexSpace 𝕜 E _ _ _ _ (sInf ts) := by - letI : TopologicalSpace E := sInf ts + let : TopologicalSpace E := sInf ts refine .ofBases 𝕜 E (fun _ => fun If : Set ts × (ts → Set E) => ⋂ i ∈ If.1, If.2 i) (fun x => fun If : Set ts × (ts → Set E) => If.1.Finite ∧ ∀ i ∈ If.1, If.2 i ∈ @nhds _ (↑i) x ∧ Convex 𝕜 (If.2 i)) @@ -195,7 +195,7 @@ protected theorem LocallyConvexSpace.inf {t₁ t₂ : TopologicalSpace E} protected theorem LocallyConvexSpace.induced {t : TopologicalSpace F} [LocallyConvexSpace 𝕜 F] (f : E →ₗ[𝕜] F) : @LocallyConvexSpace 𝕜 E _ _ _ _ (t.induced f) := by - letI : TopologicalSpace E := t.induced f + let : TopologicalSpace E := t.induced f refine LocallyConvexSpace.ofBases 𝕜 E (fun _ => preimage f) (fun x => fun s : Set F => s ∈ 𝓝 (f x) ∧ Convex 𝕜 s) (fun x => ?_) fun x s ⟨_, hs⟩ => hs.linear_preimage f diff --git a/Mathlib/Topology/Algebra/Module/ModuleTopology.lean b/Mathlib/Topology/Algebra/Module/ModuleTopology.lean index f67007d2e83bc8..e0066ae0635c71 100644 --- a/Mathlib/Topology/Algebra/Module/ModuleTopology.lean +++ b/Mathlib/Topology/Algebra/Module/ModuleTopology.lean @@ -387,8 +387,8 @@ theorem isQuotientMap_of_surjectiveₛₗ [τB : TopologicalSpace B'] [IsModuleT eq_coinduced := by -- We need to prove that the topology on B is coinduced from that on A. -- First tell the typeclass inference system that A and B are topological groups. - haveI := IsModuleTopology.toContinuousAdd R A - haveI := IsModuleTopology.toContinuousAdd S B' + have := IsModuleTopology.toContinuousAdd R A + have := IsModuleTopology.toContinuousAdd S B' -- Because φ is linear, it's continuous for the module topologies (by a previous result). have : Continuous φ := continuous_of_linearMapₛₗ hσ.continuous φ -- So the coinduced topology is finer than the module topology on B. @@ -400,7 +400,7 @@ theorem isQuotientMap_of_surjectiveₛₗ [τB : TopologicalSpace B'] [IsModuleT clear! τB -- and replace it with the coinduced topology (which will be the same, but that's what we're -- trying to prove). This means we don't have to fight with the typeclass system. - letI : TopologicalSpace B' := .coinduced φ inferInstance + let : TopologicalSpace B' := .coinduced φ inferInstance -- With this new topology on `B`, φ is a quotient map by definition, -- and hence an open quotient map by a result in the library. have hφo : IsOpenQuotientMap φ := AddMonoidHom.isOpenQuotientMap_of_isQuotientMap ⟨⟨rfl⟩, hφ⟩ @@ -494,8 +494,8 @@ theorem isOpenMap_of_surjective [TopologicalSpace B] [IsModuleTopology R B] lemma _root_.ModuleTopology.eq_coinduced_of_surjectiveₛₗ {σ : R →+* S} (hσ : IsOpenQuotientMap σ) (φ : A →ₛₗ[σ] B') (hφ : Function.Surjective φ) : moduleTopology S B' = TopologicalSpace.coinduced φ inferInstance := by - letI : TopologicalSpace B' := moduleTopology S B' - haveI : IsModuleTopology S B' := ⟨rfl⟩ + let : TopologicalSpace B' := moduleTopology S B' + have : IsModuleTopology S B' := ⟨rfl⟩ exact (isQuotientMap_of_surjectiveₛₗ hσ φ hφ).eq_coinduced lemma _root_.ModuleTopology.eq_coinduced_of_surjective @@ -627,7 +627,7 @@ theorem continuous_bilinear_of_pi_fintype (ι : Type*) [Finite ι] rw [h] -- But this map is obviously continuous, because for a fixed `i`, `bil (single i 1)` is -- linear and thus continuous, and scalar multiplication and finite sums are continuous - haveI : ContinuousAdd C := toContinuousAdd R C + have : ContinuousAdd C := toContinuousAdd R C fun_prop end semiring diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean index 047fedc1e464bc..897509f1d31a82 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean @@ -162,7 +162,7 @@ set_option backward.isDefEq.respectTransparency false in theorem isUniformEmbedding_restrictScalars : IsUniformEmbedding (restrictScalars 𝕜' : ContinuousMultilinearMap 𝕜 E F → ContinuousMultilinearMap 𝕜' E F) := by - letI : NontriviallyNormedField 𝕜 := + let : NontriviallyNormedField 𝕜 := ⟨let ⟨x, hx⟩ := @NontriviallyNormedField.non_trivial 𝕜' _; ⟨algebraMap 𝕜' 𝕜 x, by simpa⟩⟩ rw [← isUniformEmbedding_toUniformOnFun.of_comp_iff] convert! isUniformEmbedding_toUniformOnFun using 4 with s @@ -188,8 +188,8 @@ instance instIsTopologicalAddGroup : IsTopologicalAddGroup (ContinuousMultilinea instance instContinuousConstSMul {M : Type*} [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜 M F] [ContinuousConstSMul M F] : ContinuousConstSMul M (ContinuousMultilinearMap 𝕜 E F) := by - letI := IsTopologicalAddGroup.rightUniformSpace F - haveI := isUniformAddGroup_of_addCommGroup (G := F) + let := IsTopologicalAddGroup.rightUniformSpace F + have := isUniformAddGroup_of_addCommGroup (G := F) infer_instance instance instContinuousSMul [ContinuousSMul 𝕜 F] : @@ -206,8 +206,8 @@ theorem hasBasis_nhds_zero_of_basis {ι : Type*} {p : ι → Prop} {b : ι → S (𝓝 (0 : ContinuousMultilinearMap 𝕜 E F)).HasBasis (fun Si : Set (Π i, E i) × ι => IsVonNBounded 𝕜 Si.1 ∧ p Si.2) fun Si => { f | MapsTo f Si.1 (b Si.2) } := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup rw [nhds_induced] refine (UniformOnFun.hasBasis_nhds_zero_of_basis _ ?_ ?_ h).comap DFunLike.coe · exact ⟨∅, isVonNBounded_empty _ _⟩ diff --git a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean index 79e68720233db2..1a1b414cc74f97 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean @@ -202,24 +202,24 @@ instance instIsUniformAddGroup [UniformSpace F] [IsUniformAddGroup F] (𝔖 : Se instance instIsTopologicalAddGroup [TopologicalSpace F] [IsTopologicalAddGroup F] (𝔖 : Set (Set E)) : IsTopologicalAddGroup (E →SLᵤ[σ, 𝔖] F) := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup infer_instance theorem continuousEvalConst [TopologicalSpace F] [IsTopologicalAddGroup F] (𝔖 : Set (Set E)) (h𝔖 : ⋃₀ 𝔖 = Set.univ) : ContinuousEvalConst (E →SLᵤ[σ, 𝔖] F) E F where continuous_eval_const x := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup exact (UniformOnFun.uniformContinuous_eval h𝔖 x).continuous.comp (isEmbedding_coeFn σ F 𝔖).continuous theorem t2Space [TopologicalSpace F] [IsTopologicalAddGroup F] [T2Space F] (𝔖 : Set (Set E)) (h𝔖 : ⋃₀ 𝔖 = univ) : T2Space (E →SLᵤ[σ, 𝔖] F) := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup - haveI : T2Space (E →ᵤ[𝔖] F) := UniformOnFun.t2Space_of_covering h𝔖 + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + have : T2Space (E →ᵤ[𝔖] F) := UniformOnFun.t2Space_of_covering h𝔖 exact (isEmbedding_coeFn σ F 𝔖).t2Space instance instDistribMulAction (M : Type*) [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜₂ M F] @@ -259,8 +259,8 @@ theorem continuousSMul [RingHomSurjective σ] [RingHomIsometric σ] [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousSMul 𝕜₂ F] (𝔖 : Set (Set E)) (h𝔖₃ : ∀ S ∈ 𝔖, IsVonNBounded 𝕜₁ S) : ContinuousSMul 𝕜₂ (E →SLᵤ[σ, 𝔖] F) := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup let φ : (E →SLᵤ[σ, 𝔖] F) →ₗ[𝕜₂] E → F := ⟨⟨DFunLike.coe, fun _ _ => rfl⟩, fun _ _ => rfl⟩ exact UniformOnFun.continuousSMul_induced_of_image_bounded 𝕜₂ E F (E →SLᵤ[σ, 𝔖] F) φ @@ -272,8 +272,8 @@ theorem hasBasis_nhds_zero_of_basis [TopologicalSpace F] [IsTopologicalAddGroup (𝓝 (0 : E →SLᵤ[σ, 𝔖] F)).HasBasis (fun Si : Set E × ι => Si.1 ∈ 𝔖 ∧ p Si.2) fun Si => { f : E →SLᵤ[σ, 𝔖] F | ∀ x ∈ Si.1, f x ∈ b Si.2 } := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup rw [(isEmbedding_coeFn σ F 𝔖).isInducing.nhds_eq_comap] exact (UniformOnFun.hasBasis_nhds_zero_of_basis 𝔖 h𝔖₁ h𝔖₂ h).comap DFunLike.coe @@ -289,8 +289,8 @@ theorem nhds_zero_eq_of_basis [TopologicalSpace F] [IsTopologicalAddGroup F] ( 𝓝 (0 : E →SLᵤ[σ, 𝔖] F) = ⨅ (s : Set E) (_ : s ∈ 𝔖) (i : ι) (_ : p i), 𝓟 {f : E →SLᵤ[σ, 𝔖] F | MapsTo f s (b i)} := by - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup rw [(isEmbedding_coeFn σ F 𝔖).isInducing.nhds_eq_comap, UniformOnFun.nhds_eq_of_basis _ _ h.uniformity_of_nhds_zero] simp [MapsTo] @@ -408,8 +408,8 @@ theorem uniformSpace_mono [UniformSpace F] [IsUniformAddGroup F] (h : 𝔖₂ theorem topologicalSpace_mono [TopologicalSpace F] [IsTopologicalAddGroup F] (h : 𝔖₂ ⊆ 𝔖₁) : instTopologicalSpace σ F 𝔖₁ ≤ instTopologicalSpace σ F 𝔖₂ := by - letI := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup simp_rw [← uniformity_toTopologicalSpace_eq] exact UniformSpace.toTopologicalSpace_mono (uniformSpace_mono σ F h) @@ -492,8 +492,8 @@ def precompUniformConvergenceCLM [IsTopologicalAddGroup G] [ContinuousConstSMul map_add' f g := add_comp f g L map_smul' a f := smul_comp a f L cont := by - letI : UniformSpace G := IsTopologicalAddGroup.rightUniformSpace G - haveI : IsUniformAddGroup G := isUniformAddGroup_of_addCommGroup + let : UniformSpace G := IsTopologicalAddGroup.rightUniformSpace G + have : IsUniformAddGroup G := isUniformAddGroup_of_addCommGroup rw [(UniformConvergenceCLM.isEmbedding_coeFn _ _ _).continuous_iff] exact (UniformOnFun.precomp_uniformContinuous hL).continuous.comp (UniformConvergenceCLM.isEmbedding_coeFn _ _ _).continuous @@ -514,10 +514,10 @@ def postcompUniformConvergenceCLM [IsTopologicalAddGroup F] [IsTopologicalAddGro map_add' := comp_add L map_smul' := comp_smulₛₗ L cont := by - letI : UniformSpace G := IsTopologicalAddGroup.rightUniformSpace G - haveI : IsUniformAddGroup G := isUniformAddGroup_of_addCommGroup - letI : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F - haveI : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup + let : UniformSpace G := IsTopologicalAddGroup.rightUniformSpace G + have : IsUniformAddGroup G := isUniformAddGroup_of_addCommGroup + let : UniformSpace F := IsTopologicalAddGroup.rightUniformSpace F + have : IsUniformAddGroup F := isUniformAddGroup_of_addCommGroup rw [(UniformConvergenceCLM.isEmbedding_coeFn _ _ _).continuous_iff] exact (UniformOnFun.postcomp_uniformContinuous L.uniformContinuous).continuous.comp diff --git a/Mathlib/Topology/Algebra/Module/TopDualPairing.lean b/Mathlib/Topology/Algebra/Module/TopDualPairing.lean index 8aea033ca55dc5..1892ad9a632657 100644 --- a/Mathlib/Topology/Algebra/Module/TopDualPairing.lean +++ b/Mathlib/Topology/Algebra/Module/TopDualPairing.lean @@ -35,8 +35,8 @@ variable [FiniteDimensional 𝕜 E] [T2Space E] Hausdorff spaces over complete nontrivially normed fields. -/ instance topDualPairing_isContPerfPair : (topDualPairing 𝕜 E).IsContPerfPair where continuous_uncurry := by - haveI : IsModuleTopology 𝕜 E := isModuleTopologyOfFiniteDimensional - haveI : IsModuleTopology 𝕜 (E →L[𝕜] 𝕜) := isModuleTopologyOfFiniteDimensional + have : IsModuleTopology 𝕜 E := isModuleTopologyOfFiniteDimensional + have : IsModuleTopology 𝕜 (E →L[𝕜] 𝕜) := isModuleTopologyOfFiniteDimensional exact IsModuleTopology.continuous_bilinear_of_finite_left (topDualPairing 𝕜 E) bijective_left := Function.bijective_id bijective_right := by diff --git a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean index 998531ca974c38..06ac7590c5fb73 100644 --- a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean +++ b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean @@ -100,7 +100,7 @@ lemma UniformOnFun.continuousSMul_induced_of_image_bounded (φ : hom) (hφ : IsI obtain rfl := hφ.eq_induced; clear hφ simp +instances only [induced_iInf, UniformOnFun.topologicalSpace_eq, induced_compose] refine continuousSMul_iInf fun s ↦ continuousSMul_iInf fun hs ↦ ?_ - letI : TopologicalSpace H := + let : TopologicalSpace H := .induced (UniformFun.ofFun ∘ s.restrict ∘ φ) (UniformFun.topologicalSpace s E) set φ' : H →ₗ[𝕜] (s → E) := { toFun := s.restrict ∘ φ, diff --git a/Mathlib/Topology/Algebra/Monoid.lean b/Mathlib/Topology/Algebra/Monoid.lean index fc1387005e15c0..4343372716e917 100644 --- a/Mathlib/Topology/Algebra/Monoid.lean +++ b/Mathlib/Topology/Algebra/Monoid.lean @@ -540,10 +540,10 @@ theorem tendsto_mul_cocompact_nhds_zero [TopologicalSpace α] [TopologicalSpace theorem tendsto_mul_cofinite_nhds_zero {f : α → M} {g : β → M} (hf : Tendsto f cofinite (𝓝 0)) (hg : Tendsto g cofinite (𝓝 0)) : Tendsto (fun i : α × β ↦ f i.1 * g i.2) cofinite (𝓝 0) := by - letI : TopologicalSpace α := ⊥ - haveI : DiscreteTopology α := discreteTopology_bot α - letI : TopologicalSpace β := ⊥ - haveI : DiscreteTopology β := discreteTopology_bot β + let : TopologicalSpace α := ⊥ + have : DiscreteTopology α := discreteTopology_bot α + let : TopologicalSpace β := ⊥ + have : DiscreteTopology β := discreteTopology_bot β rw [← cocompact_eq_cofinite] at * exact tendsto_mul_cocompact_nhds_zero continuous_of_discreteTopology continuous_of_discreteTopology hf hg diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean b/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean index f2f0b97c865a8a..945815ac73ecce 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean @@ -109,7 +109,7 @@ theorem hasBasis_nhds_zero_adic (I : Ideal R) : theorem hasBasis_nhds_adic (I : Ideal R) (x : R) : HasBasis (@nhds R I.adicTopology x) (fun _n : ℕ => True) fun n => (fun y => x + y) '' (I ^ n : Ideal R) := by - letI := I.adicTopology + let := I.adicTopology have := I.hasBasis_nhds_zero_adic.map fun y => x + y rwa [map_add_left_nhds_zero x] at this @@ -166,7 +166,7 @@ theorem isAdic_iff [top : TopologicalSpace R] [IsTopologicalRing R] {J : Ideal R · intro H change _ = _ at H rw [H] - letI := J.adicTopology + let := J.adicTopology constructor · intro n exact (J.openAddSubgroup n).isOpen' @@ -177,7 +177,7 @@ theorem isAdic_iff [top : TopologicalSpace R] [IsTopologicalRing R] {J : Ideal R · apply @IsTopologicalRing.to_topologicalAddGroup · apply (RingSubgroupsBasis.toRingFilterBasis _).toAddGroupFilterBasis.isTopologicalAddGroup · ext s - letI := Ideal.adic_basis J + let := Ideal.adic_basis J rw [J.hasBasis_nhds_zero_adic.mem_iff] constructor <;> intro H · rcases H₂ s H with ⟨n, h⟩ diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean b/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean index bd3527ceffa655..08e03275544bba 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean @@ -186,7 +186,7 @@ def openAddSubgroup (i : ι) : @OpenAddSubgroup A _ hB.topology := -- See note [non-Archimedean non-instances] theorem nonarchimedean : @NonarchimedeanRing A _ hB.topology := by - letI := hB.topology + let := hB.topology constructor intro U hU obtain ⟨i, -, hi : (B i : Set A) ⊆ U⟩ := hB.hasBasis_nhds_zero.mem_iff.mp hU @@ -313,7 +313,7 @@ def openAddSubgroup (i : ι) : @OpenAddSubgroup M _ hB.topology := let _ := hB.topology { (B i).toAddSubgroup with isOpen' := by - letI := hB.topology + let := hB.topology rw [isOpen_iff_mem_nhds] intro a a_in rw [(hB.toModuleFilterBasis.toAddGroupFilterBasis.nhds_hasBasis a).mem_iff] @@ -325,7 +325,7 @@ def openAddSubgroup (i : ι) : @OpenAddSubgroup M _ hB.topology := -- See note [non-Archimedean non-instances] theorem nonarchimedean (hB : SubmodulesBasis B) : @NonarchimedeanAddGroup M _ hB.topology := by - letI := hB.topology + let := hB.topology constructor intro U hU obtain ⟨-, ⟨i, rfl⟩, hi : (B i : Set M) ⊆ U⟩ := @@ -378,7 +378,7 @@ theorem RingFilterBasis.submodulesBasisIsBasis (BR : RingFilterBasis R) {B : ι let _ := BR.topology { inter := hB.inter smul := by - letI := BR.topology + let := BR.topology intro m i rcases hB.smul m i with ⟨V, V_in, hV⟩ exact mem_of_superset (BR.toAddGroupFilterBasis.mem_nhds_zero V_in) hV } diff --git a/Mathlib/Topology/Algebra/RestrictedProduct/TopologicalSpace.lean b/Mathlib/Topology/Algebra/RestrictedProduct/TopologicalSpace.lean index 47b0e8187ea3cc..8f6efb7479c26c 100644 --- a/Mathlib/Topology/Algebra/RestrictedProduct/TopologicalSpace.lean +++ b/Mathlib/Topology/Algebra/RestrictedProduct/TopologicalSpace.lean @@ -410,7 +410,7 @@ theorem weaklyLocallyCompactSpace_of_cofinite [∀ i, WeaklyLocallyCompactSpace have hS : cofinite ≤ 𝓟 S := le_principal_iff.mpr (hAcompact.and x.2) have hSx : ∀ i ∈ S, x i ∈ A i := fun i hi ↦ hi.2 have hSA : ∀ i ∈ S, IsCompact (A i) := fun i hi ↦ hi.1 - haveI := weaklyLocallyCompactSpace_of_principal hS hSA + have := weaklyLocallyCompactSpace_of_principal hS hSA rcases exists_inclusion_eq_of_eventually R A hS hSx with ⟨x', hxx'⟩ rw [← hxx', nhds_eq_map_inclusion hAopen] rcases exists_compact_mem_nhds x' with ⟨K, K_compact, hK⟩ @@ -529,7 +529,7 @@ instance [Π i, Inv (R i)] [∀ i, InvMemClass (S i) (R i)] [∀ i, ContinuousIn continuous_inv := by rw [continuous_dom] intro T hT - haveI : ContinuousInv (Πʳ i, [R i, B i]_[𝓟 T]) := + have : ContinuousInv (Πʳ i, [R i, B i]_[𝓟 T]) := isEmbedding_coe_of_principal.continuousInv fun _ ↦ rfl exact (continuous_inclusion hT).comp continuous_inv @@ -540,7 +540,7 @@ instance {G : Type*} [Π i, SMul G (R i)] [∀ i, SMulMemClass (S i) G (R i)] continuous_const_smul g := by rw [continuous_dom] intro T hT - haveI : ContinuousConstSMul G (Πʳ i, [R i, B i]_[𝓟 T]) := + have : ContinuousConstSMul G (Πʳ i, [R i, B i]_[𝓟 T]) := isEmbedding_coe_of_principal.continuousConstSMul id rfl exact (continuous_inclusion hT).comp (continuous_const_smul g) diff --git a/Mathlib/Topology/Algebra/Semigroup.lean b/Mathlib/Topology/Algebra/Semigroup.lean index 98f129280c3c51..ad53ea93e5cab3 100644 --- a/Mathlib/Topology/Algebra/Semigroup.lean +++ b/Mathlib/Topology/Algebra/Semigroup.lean @@ -83,11 +83,11 @@ theorem exists_idempotent_in_compact_subsemigroup {M} [Semigroup M] [Topological (s_compact : IsCompact s) (s_add : ∀ᵉ (x ∈ s) (y ∈ s), x * y ∈ s) : ∃ m ∈ s, m * m = m := by let M' := { m // m ∈ s } - letI : Semigroup M' := + let : Semigroup M' := { mul := fun p q => ⟨p.1 * q.1, s_add _ p.2 _ q.2⟩ mul_assoc := fun p q r => Subtype.ext (mul_assoc _ _ _) } - haveI : CompactSpace M' := isCompact_iff_compactSpace.mp s_compact - haveI : Nonempty M' := nonempty_subtype.mpr snemp + have : CompactSpace M' := isCompact_iff_compactSpace.mp s_compact + have : Nonempty M' := nonempty_subtype.mpr snemp have : ∀ p : M', Continuous (· * p) := fun p => ((continuous_const_mul p.1).comp continuous_subtype_val).subtype_mk _ obtain ⟨⟨m, hm⟩, idem⟩ := exists_idempotent_of_compact_t2_of_continuous_mul_left this diff --git a/Mathlib/Topology/Algebra/UniformField.lean b/Mathlib/Topology/Algebra/UniformField.lean index b983eddb5bd019..8f853c718e5b0f 100644 --- a/Mathlib/Topology/Algebra/UniformField.lean +++ b/Mathlib/Topology/Algebra/UniformField.lean @@ -81,7 +81,7 @@ theorem continuous_hatInv [CompletableTopField K] {x : hat K} (h : x ≠ 0) : rw [this, ← Filter.map_map] apply Cauchy.map _ (Completion.uniformContinuous_coe K) apply CompletableTopField.nice - · haveI := isDenseInducing_coe.comap_nhds_neBot y + · have := isDenseInducing_coe.comap_nhds_neBot y apply cauchy_nhds.comap rw [Completion.comap_coe_eq_uniformity] · have eq_bot : 𝓝 (0 : hat K) ⊓ 𝓝 y = ⊥ := by @@ -122,7 +122,7 @@ theorem coe_inv (x : K) : (x : hat K)⁻¹ = ((x⁻¹ : K) : hat K) := by variable [IsUniformAddGroup K] theorem mul_hatInv_cancel {x : hat K} (x_ne : x ≠ 0) : x * hatInv x = 1 := by - haveI : T1Space (hat K) := T2Space.t1Space + have : T1Space (hat K) := T2Space.t1Space let f := fun x : hat K => x * hatInv x let c := (fun (x : K) => (x : hat K)) change f x = 1 @@ -186,7 +186,7 @@ instance Subfield.completableTopField (K : Subfield L) : CompletableTopField K w instance (priority := 100) completableTopField_of_complete (L : Type*) [Field L] [UniformSpace L] [IsTopologicalDivisionRing L] [T0Space L] [CompleteSpace L] : CompletableTopField L where nice F cau_F hF := by - haveI : NeBot F := cau_F.1 + have : NeBot F := cau_F.1 rcases CompleteSpace.complete cau_F with ⟨x, hx⟩ have hx' : x ≠ 0 := by rintro rfl diff --git a/Mathlib/Topology/Algebra/UniformFilterBasis.lean b/Mathlib/Topology/Algebra/UniformFilterBasis.lean index 2de650e0e88f03..8299736fad5ee2 100644 --- a/Mathlib/Topology/Algebra/UniformFilterBasis.lean +++ b/Mathlib/Topology/Algebra/UniformFilterBasis.lean @@ -43,8 +43,8 @@ protected theorem isUniformAddGroup : @IsUniformAddGroup G B.uniformSpace _ := theorem cauchy_iff {F : Filter G} : @Cauchy G B.uniformSpace F ↔ F.NeBot ∧ ∀ U ∈ B, ∃ M ∈ F, ∀ᵉ (x ∈ M) (y ∈ M), y - x ∈ U := by - letI := B.uniformSpace - haveI := B.isUniformAddGroup + let := B.uniformSpace + have := B.isUniformAddGroup suffices F ×ˢ F ≤ uniformity G ↔ ∀ U ∈ B, ∃ M ∈ F, ∀ᵉ (x ∈ M) (y ∈ M), y - x ∈ U by constructor <;> rintro ⟨h', h⟩ <;> refine ⟨h', ?_⟩ <;> [rwa [← this]; rwa [this]] rw [uniformity_eq_comap_nhds_zero G, ← map_le_iff_le_comap] diff --git a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean index 06703c0c4427b3..77dc51ef10203c 100644 --- a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean +++ b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean @@ -262,8 +262,8 @@ variable [_t : TopologicalSpace R] [IsValuativeTopology R] (v : Valuation R Γ theorem toTopologicalSpace_eq : _t = v.subgroups_basis.topology := by - letI u := IsTopologicalAddGroup.rightUniformSpace R - letI := isUniformAddGroup_of_addCommGroup (G := R) + let u := IsTopologicalAddGroup.rightUniformSpace R + let := isUniformAddGroup_of_addCommGroup (G := R) exact congrArg (fun u ↦ @UniformSpace.toTopologicalSpace R u) v.toUniformSpace_eq instance (priority := low) _root_.IsValuativeTopology.isTopologicalRing : IsTopologicalRing R := by diff --git a/Mathlib/Topology/Algebra/Valued/NormedValued.lean b/Mathlib/Topology/Algebra/Valued/NormedValued.lean index 828583db4053db..cd0ee47f892877 100644 --- a/Mathlib/Topology/Algebra/Valued/NormedValued.lean +++ b/Mathlib/Topology/Algebra/Valued/NormedValued.lean @@ -164,7 +164,7 @@ def toNormedField : NormedField L := norm_mul := fun x y => by simp only [Valuation.norm, ← NNReal.coe_mul, map_mul] toUniformSpace := Valued.toUniformSpace uniformity_dist := by - haveI : Nonempty { ε : ℝ // ε > 0 } := nonempty_Ioi_subtype + have : Nonempty { ε : ℝ // ε > 0 } := nonempty_Ioi_subtype ext U rw [hasBasis_iff.mp (Valued.hasBasis_uniformity L Γ₀), iInf_subtype', mem_iInf_of_directed] · simp only [true_and, mem_principal, Subtype.exists, gt_iff_lt, exists_prop] @@ -179,7 +179,7 @@ def toNormedField : NormedField L := simp only [mem_setOf_eq, Valuation.norm, hδ, NNReal.coe_lt_coe] at hx rw [mem_setOf, ← neg_sub, Valuation.map_neg] exact (RankOne.strictMono Valued.v).lt_iff_lt.mp hx - · haveI : Nontrivial Γ₀ˣ := (nontrivial_iff_exists_ne (1 : Γ₀ˣ)).mpr + · have : Nontrivial Γ₀ˣ := (nontrivial_iff_exists_ne (1 : Γ₀ˣ)).mpr ⟨RankOne.unit val.v, RankOne.unit_ne_one val.v⟩ obtain ⟨u, hu⟩ := Real.exists_lt_of_strictMono hv.strictMono hr_pos use u diff --git a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean index de9f51ff05bed3..7515edaf066add 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean @@ -139,7 +139,7 @@ def mk' (v : Valuation R Γ₀) : Valued R Γ₀ := toUniformSpace := @IsTopologicalAddGroup.rightUniformSpace R _ v.subgroups_basis.topology _ toIsUniformAddGroup := @isUniformAddGroup_of_addCommGroup _ _ v.subgroups_basis.topology _ is_topological_valuation := by - letI := @IsTopologicalAddGroup.rightUniformSpace R _ v.subgroups_basis.topology _ + let := @IsTopologicalAddGroup.rightUniformSpace R _ v.subgroups_basis.topology _ intro s rw [Filter.hasBasis_iff.mp v.subgroups_basis.hasBasis_nhds_zero s] simp_rw [restrict_lt_iff_lt_embedding] diff --git a/Mathlib/Topology/Baire/Lemmas.lean b/Mathlib/Topology/Baire/Lemmas.lean index 7d9c592d303eeb..280eb034d31ce2 100644 --- a/Mathlib/Topology/Baire/Lemmas.lean +++ b/Mathlib/Topology/Baire/Lemmas.lean @@ -190,7 +190,7 @@ an index set which is a countable set in any type. -/ theorem dense_biInter_of_Gδ {S : Set α} {f : ∀ x ∈ S, Set X} (ho : ∀ s (H : s ∈ S), IsGδ (f s H)) (hS : S.Countable) (hd : ∀ s (H : s ∈ S), Dense (f s H)) : Dense (⋂ s ∈ S, f s ‹_›) := by rw [biInter_eq_iInter] - haveI := hS.to_subtype + have := hS.to_subtype exact dense_iInter_of_Gδ (fun s => ho s s.2) fun s => hd s s.2 /-- Baire theorem: the intersection of two dense Gδ sets is dense. -/ @@ -221,7 +221,7 @@ is dense. Formulated here with a union over a countable set in any type. -/ theorem IsGδ.dense_biUnion_interior_of_closed {t : Set α} {s : Set X} (hs : IsGδ s) (hd : Dense s) (ht : t.Countable) {f : α → Set X} (hc : ∀ i ∈ t, IsClosed (f i)) (hU : s ⊆ ⋃ i ∈ t, f i) : Dense (⋃ i ∈ t, interior (f i)) := by - haveI := ht.to_subtype + have := ht.to_subtype simp only [biUnion_eq_iUnion, SetCoe.forall'] at * exact hs.dense_iUnion_interior_of_closed hd hc hU diff --git a/Mathlib/Topology/Bases.lean b/Mathlib/Topology/Bases.lean index bbfba69335b6d4..ee125a1602e517 100644 --- a/Mathlib/Topology/Bases.lean +++ b/Mathlib/Topology/Bases.lean @@ -82,7 +82,7 @@ structure IsTopologicalBasis (s : Set (Set α)) : Prop where subcollections of `s` form a topological basis. -/ theorem isTopologicalBasis_of_subbasis {s : Set (Set α)} (hs : t = generateFrom s) : IsTopologicalBasis ((fun f => ⋂₀ f) '' { f : Set (Set α) | f.Finite ∧ f ⊆ s }) := by - subst t; letI := generateFrom s + subst t; let := generateFrom s refine ⟨?_, ?_, le_antisymm (le_generateFrom ?_) <| generateFrom_anti fun t ht => ?_⟩ · rintro _ ⟨t₁, ⟨hft₁, ht₁b⟩, rfl⟩ _ ⟨t₂, ⟨hft₂, ht₂b⟩, rfl⟩ x h exact ⟨_, ⟨_, ⟨hft₁.union hft₂, union_subset ht₁b ht₂b⟩, sInter_union t₁ t₂⟩, h, Subset.rfl⟩ @@ -416,7 +416,7 @@ instance [TopologicalSpace β] [SeparableSpace α] [SeparableSpace β] : Separab instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, SeparableSpace (X i)] [Countable ι] : SeparableSpace (∀ i, X i) := by choose t htc htd using (exists_countable_dense <| X ·) - haveI := fun i ↦ (htc i).to_subtype + have := fun i ↦ (htc i).to_subtype nontriviality ∀ i, X i; inhabit ∀ i, X i classical set f : (Σ I : Finset ι, ∀ i : I, t i) → ∀ i, X i := fun ⟨I, g⟩ i ↦ @@ -528,7 +528,7 @@ theorem IsSeparable.univ_pi {ι : Type*} [Countable ι] {X : ι → Type*} {s : · rw [he] exact countable_empty.isSeparable · choose c c_count hc using h - haveI := fun i ↦ (c_count i).to_subtype + have := fun i ↦ (c_count i).to_subtype set g : (I : Finset ι) × ((i : I) → c i) → (i : ι) → X i := fun ⟨I, f⟩ i ↦ if hi : i ∈ I then f ⟨i, hi⟩ else f₀ i refine ⟨range g, countable_range g, fun f hf ↦ mem_closure_iff.2 fun o ho hfo ↦ ?_⟩ @@ -866,7 +866,7 @@ instance (priority := 100) [Countable α] [FirstCountableTopology α] : theorem secondCountableTopology_induced (α β) [t : TopologicalSpace β] [SecondCountableTopology β] (f : α → β) : @SecondCountableTopology α (t.induced f) := by rcases @SecondCountableTopology.is_open_generated_countable β _ _ with ⟨b, hb, eq⟩ - letI := t.induced f + let := t.induced f refine { is_open_generated_countable := ⟨preimage f '' b, hb.image _, ?_⟩ } rw [eq, induced_generateFrom_eq] @@ -915,7 +915,7 @@ theorem isOpen_iUnion_countable [SecondCountableTopology α] {ι} (s : ι → Se (H : ∀ i, IsOpen (s i)) : ∃ T : Set ι, T.Countable ∧ ⋃ i ∈ T, s i = ⋃ i, s i := by let B := { b ∈ countableBasis α | ∃ i, b ⊆ s i } choose f hf using fun b : B => b.2.2 - haveI : Countable B := ((countable_countableBasis α).mono (sep_subset _ _)).to_subtype + have : Countable B := ((countable_countableBasis α).mono (sep_subset _ _)).to_subtype refine ⟨_, countable_range f, (iUnion₂_subset_iUnion _ _).antisymm (sUnion_subset ?_)⟩ rintro _ ⟨i, rfl⟩ x xs rcases (isBasis_countableBasis α).exists_subset_of_mem_open xs (H _) with ⟨b, hb, xb, bs⟩ diff --git a/Mathlib/Topology/CWComplex/Classical/Basic.lean b/Mathlib/Topology/CWComplex/Classical/Basic.lean index 78eab46d614820..705253ee4cc7aa 100644 --- a/Mathlib/Topology/CWComplex/Classical/Basic.lean +++ b/Mathlib/Topology/CWComplex/Classical/Basic.lean @@ -407,7 +407,7 @@ lemma RelCWComplex.cellFrontier_zero_eq_empty [RelCWComplex C D] {j : cell C 0} @[alias_in CWComplex] lemma RelCWComplex.nonempty_cellFrontier [CWComplex C] {n : ℕ} (hn : n ≠ 0) (j : cell C n) : (cellFrontier n j).Nonempty := by - letI : NeZero n := ⟨hn⟩ + let : NeZero n := ⟨hn⟩ use map n j (Pi.single 0 1) simp only [cellFrontier, mem_image, mem_sphere_iff_norm, sub_zero] use Pi.single 0 1, by simp [Pi.norm_single] diff --git a/Mathlib/Topology/Category/CompHaus/Basic.lean b/Mathlib/Topology/Category/CompHaus/Basic.lean index 3d82ef12851a4c..b90b4b4da53606 100644 --- a/Mathlib/Topology/Category/CompHaus/Basic.lean +++ b/Mathlib/Topology/Category/CompHaus/Basic.lean @@ -192,8 +192,8 @@ theorem epi_iff_surjective {X Y : CompHaus.{u}} (f : X ⟶ Y) : Epi f ↔ Functi rintro ⟨y', hy'⟩ exact hy y' hy' obtain ⟨φ, hφ0, hφ1, hφ01⟩ := exists_continuous_zero_one_of_isClosed hC hD hCD - haveI : CompactSpace (ULift.{u} <| Set.Icc (0 : ℝ) 1) := Homeomorph.ulift.symm.compactSpace - haveI : T2Space (ULift.{u} <| Set.Icc (0 : ℝ) 1) := Homeomorph.ulift.symm.t2Space + have : CompactSpace (ULift.{u} <| Set.Icc (0 : ℝ) 1) := Homeomorph.ulift.symm.compactSpace + have : T2Space (ULift.{u} <| Set.Icc (0 : ℝ) 1) := Homeomorph.ulift.symm.t2Space let Z := of (ULift.{u} <| Set.Icc (0 : ℝ) 1) let g : Y ⟶ Z := ofHom _ ⟨fun y' => ⟨⟨φ y', hφ01 y'⟩⟩, diff --git a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean index dfa0f583b04854..ec025ce5116a93 100644 --- a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean +++ b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean @@ -202,10 +202,10 @@ theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstan · ext x exact hj.elim' (C.π.app j x) by_contra! h - haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h - haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j => + have : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h + have : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j => (inferInstance : T2Space (F.obj j)) - haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j => + have : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j => (inferInstance : CompactSpace (F.obj j)) have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u} (F ⋙ Profinite.toTopCat) diff --git a/Mathlib/Topology/Category/Stonean/Basic.lean b/Mathlib/Topology/Category/Stonean/Basic.lean index df64fba6809a24..ae6333485f8843 100644 --- a/Mathlib/Topology/Category/Stonean/Basic.lean +++ b/Mathlib/Topology/Category/Stonean/Basic.lean @@ -154,7 +154,7 @@ lemma epi_iff_surjective {X Y : Stonean} (f : X ⟶ Y) : instance instProjectiveCompHausCompHaus (X : Stonean) : Projective (toCompHaus.obj X) where factors := by intro B C φ f _ - haveI : ExtremallyDisconnected (toCompHaus.obj X).toTop := X.prop + have : ExtremallyDisconnected (toCompHaus.obj X).toTop := X.prop have hf : Function.Surjective f := by rwa [← CompHaus.epi_iff_surjective] obtain ⟨f', h⟩ := CompactT2.ExtremallyDisconnected.projective φ.hom.hom.continuous f.hom.hom.continuous @@ -167,7 +167,7 @@ instance instProjectiveCompHausCompHaus (X : Stonean) : Projective (toCompHaus.o instance (X : Stonean) : Projective (toProfinite.obj X) where factors := by intro B C φ f _ - haveI : ExtremallyDisconnected (toProfinite.obj X) := X.prop + have : ExtremallyDisconnected (toProfinite.obj X) := X.prop have hf : Function.Surjective f := by rwa [← Profinite.epi_iff_surjective] obtain ⟨f', h⟩ := CompactT2.ExtremallyDisconnected.projective φ.hom.hom.continuous f.hom.hom.continuous @@ -180,7 +180,7 @@ instance (X : Stonean) : Projective (toProfinite.obj X) where instance (X : Stonean) : Projective X where factors := by intro B C φ f _ - haveI : ExtremallyDisconnected X.toTop := X.prop + have : ExtremallyDisconnected X.toTop := X.prop have hf : Function.Surjective f := by rwa [← Stonean.epi_iff_surjective] obtain ⟨f', h⟩ := CompactT2.ExtremallyDisconnected.projective φ.hom.hom.continuous f.hom.hom.continuous diff --git a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean index 419cca5e85072f..62a504a5a47ba4 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean @@ -73,7 +73,7 @@ theorem partialSections.nonempty [IsCofilteredOrEmpty J] [h : ∀ j : J, Nonempt classical cases isEmpty_or_nonempty J · exact ⟨isEmptyElim, fun {j} => IsEmpty.elim' inferInstance j.1⟩ - haveI : IsCofiltered J := ⟨⟩ + have : IsCofiltered J := ⟨⟩ use fun j : J => if hj : j ∈ G then F.map (IsCofiltered.infTo G H hj) (h (IsCofiltered.inf G H)).some else (h _).some diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index b67db81e7d0fe4..13a4314451693a 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -222,8 +222,8 @@ theorem isInducing_prodMap {W X Y Z : TopCat.{u}} {f : W ⟶ X} {g : Y ⟶ Z} (h theorem isEmbedding_prodMap {W X Y Z : TopCat.{u}} {f : W ⟶ X} {g : Y ⟶ Z} (hf : IsEmbedding f) (hg : IsEmbedding g) : IsEmbedding (Limits.prod.map f g) := ⟨isInducing_prodMap hf.isInducing hg.isInducing, by - haveI := (TopCat.mono_iff_injective _).mpr hf.injective - haveI := (TopCat.mono_iff_injective _).mpr hg.injective + have := (TopCat.mono_iff_injective _).mpr hf.injective + have := (TopCat.mono_iff_injective _).mpr hg.injective exact (TopCat.mono_iff_injective _).mp inferInstance⟩ end Prod diff --git a/Mathlib/Topology/CompactOpen.lean b/Mathlib/Topology/CompactOpen.lean index f691e208772d12..f9a1d7a83bf422 100644 --- a/Mathlib/Topology/CompactOpen.lean +++ b/Mathlib/Topology/CompactOpen.lean @@ -375,8 +375,8 @@ theorem exists_tendsto_compactOpen_iff_forall [WeaklyLocallyCompactSpace X] [T2S ∀ (s₁) (hs₁ : IsCompact s₁) (s₂) (hs₂ : IsCompact s₂) (x : X) (hxs₁ : x ∈ s₁) (hxs₂ : x ∈ s₂), f s₁ hs₁ ⟨x, hxs₁⟩ = f s₂ hs₂ ⟨x, hxs₂⟩ := by rintro s₁ hs₁ s₂ hs₂ x hxs₁ hxs₂ - haveI := isCompact_iff_compactSpace.mp hs₁ - haveI := isCompact_iff_compactSpace.mp hs₂ + have := isCompact_iff_compactSpace.mp hs₁ + have := isCompact_iff_compactSpace.mp hs₂ have h₁ := (continuous_eval_const (⟨x, hxs₁⟩ : s₁)).continuousAt.tendsto.comp (hf s₁ hs₁) have h₂ := (continuous_eval_const (⟨x, hxs₂⟩ : s₂)).continuousAt.tendsto.comp (hf s₂ hs₂) exact tendsto_nhds_unique h₁ h₂ diff --git a/Mathlib/Topology/Compactification/StoneCech.lean b/Mathlib/Topology/Compactification/StoneCech.lean index d2e261792e3636..c6b25c9fc81e38 100644 --- a/Mathlib/Topology/Compactification/StoneCech.lean +++ b/Mathlib/Topology/Compactification/StoneCech.lean @@ -178,8 +178,8 @@ variable [T2Space γ] @[simp] lemma ultrafilter_extend_extends (f : α → γ) : Ultrafilter.extend f ∘ pure = f := by - letI : TopologicalSpace α := ⊥ - haveI : DiscreteTopology α := ⟨rfl⟩ + let : TopologicalSpace α := ⊥ + have : DiscreteTopology α := ⟨rfl⟩ exact funext (isDenseInducing_pure.extend_eq continuous_of_discreteTopology) @[simp] diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index 4df746261b2037..46fd7adce3589c 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -110,7 +110,7 @@ theorem IsCompact.image_of_continuousOn {f : X → Y} (hs : IsCompact s) (hf : C have : NeBot (l.comap f ⊓ 𝓟 s) := comap_inf_principal_neBot_of_image_mem lne (le_principal_iff.1 ls) obtain ⟨x, hxs, hx⟩ : ∃ x ∈ s, ClusterPt x (l.comap f ⊓ 𝓟 s) := @hs _ this inf_le_right - haveI := hx.neBot + have := hx.neBot use f x, mem_image_of_mem f hxs have : Tendsto f (𝓝 x ⊓ (comap f l ⊓ 𝓟 s)) (𝓝 (f x) ⊓ l) := by convert! (hf x hxs).inf (@tendsto_comap _ _ f l) using 1 @@ -627,7 +627,7 @@ theorem Tendsto.isCompact_insert_range_of_cocompact {f : X → Y} {y} theorem Tendsto.isCompact_insert_range_of_cofinite {f : ι → X} {x} (hf : Tendsto f cofinite (𝓝 x)) : IsCompact (insert x (range f)) := by - letI : TopologicalSpace ι := ⊥; haveI h : DiscreteTopology ι := ⟨rfl⟩ + let : TopologicalSpace ι := ⊥; have h : DiscreteTopology ι := ⟨rfl⟩ rw [← cocompact_eq_cofinite ι] at hf exact hf.isCompact_insert_range_of_cocompact continuous_of_discreteTopology @@ -1214,7 +1214,7 @@ theorem IsClosed.exists_minimal_nonempty_closed_subset [CompactSpace X] {S : Set zorn_subset opens fun c hc hz => by by_cases hcne : c.Nonempty · obtain ⟨U₀, hU₀⟩ := hcne - haveI : Nonempty { U // U ∈ c } := ⟨⟨U₀, hU₀⟩⟩ + have : Nonempty { U // U ∈ c } := ⟨⟨U₀, hU₀⟩⟩ obtain ⟨U₀compl, -, -⟩ := hc hU₀ use ⋃₀ c refine ⟨⟨?_, ?_, ?_⟩, fun U hU _ hx => ⟨U, hU, hx⟩⟩ diff --git a/Mathlib/Topology/Compactness/Lindelof.lean b/Mathlib/Topology/Compactness/Lindelof.lean index 1a5ec276e008cf..91b7679bff0d00 100644 --- a/Mathlib/Topology/Compactness/Lindelof.lean +++ b/Mathlib/Topology/Compactness/Lindelof.lean @@ -105,7 +105,7 @@ theorem IsLindelof.image_of_continuousOn {f : X → Y} (hs : IsLindelof s) (hf : have : NeBot (l.comap f ⊓ 𝓟 s) := comap_inf_principal_neBot_of_image_mem lne (le_principal_iff.1 ls) obtain ⟨x, hxs, hx⟩ : ∃ x ∈ s, ClusterPt x (l.comap f ⊓ 𝓟 s) := @hs _ this _ inf_le_right - haveI := hx.neBot + have := hx.neBot use f x, mem_image_of_mem f hxs have : Tendsto f (𝓝 x ⊓ (comap f l ⊓ 𝓟 s)) (𝓝 (f x) ⊓ l) := by convert! (hf x hxs).inf (@tendsto_comap _ _ f l) using 1 diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 905b1b9ea09162..5caac6abf7f4d1 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -700,7 +700,7 @@ theorem connectedSpace_iff_connectedComponent : exact ⟨x, eq_univ_of_univ_subset <| isPreconnected_univ.subset_connectedComponent (mem_univ x)⟩ · rintro ⟨x, h⟩ - haveI : PreconnectedSpace α := + have : PreconnectedSpace α := ⟨by rw [← h]; exact isPreconnected_connectedComponent⟩ exact ⟨⟨x⟩⟩ diff --git a/Mathlib/Topology/Connected/LocallyPathConnected.lean b/Mathlib/Topology/Connected/LocallyPathConnected.lean index d26494a7700b2a..b5ff93d8531de0 100644 --- a/Mathlib/Topology/Connected/LocallyPathConnected.lean +++ b/Mathlib/Topology/Connected/LocallyPathConnected.lean @@ -181,7 +181,7 @@ alias IsOpen.locPathConnectedSpace := IsOpen.locallyPathConnectedSpace theorem IsOpen.isConnected_iff_isPathConnected {U : Set X} (U_op : IsOpen U) : IsConnected U ↔ IsPathConnected U := by rw [isConnected_iff_connectedSpace, isPathConnected_iff_pathConnectedSpace] - haveI := U_op.locallyPathConnectedSpace + have := U_op.locallyPathConnectedSpace exact pathConnectedSpace_iff_connectedSpace.symm /-- Locally path-connected spaces are locally connected. -/ diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index b29d16279be30e..37d9f134d59266 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -548,7 +548,7 @@ class PathConnectedSpace (X : Type*) [TopologicalSpace X] : Prop where theorem pathConnectedSpace_iff_zerothHomotopy : PathConnectedSpace X ↔ Nonempty (ZerothHomotopy X) ∧ Subsingleton (ZerothHomotopy X) := by - letI := pathSetoid X + let := pathSetoid X constructor · intro h refine ⟨(nonempty_quotient_iff _).mpr h.1, ⟨?_⟩⟩ diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index 03c4a57177fd18..de701393db9592 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -1130,7 +1130,7 @@ theorem pi_generateFrom_eq {A : ι → Type*} {g : ∀ a, Set (Set (A a))} : refine le_antisymm ?_ ?_ · apply le_generateFrom rintro _ ⟨s, i, hi, rfl⟩ - letI := fun a => generateFrom (g a) + let := fun a => generateFrom (g a) exact isOpen_set_pi i.finite_toSet (fun a ha => GenerateOpen.basic _ (hi a ha)) · classical refine le_iInf fun i => coinduced_le_iff_le_induced.1 <| le_generateFrom fun s hs => ?_ @@ -1155,7 +1155,7 @@ theorem pi_generateFrom_eq_finite {X : ι → Type*} {g : ∀ a, Set (Set (X a)) refine le_antisymm (generateFrom_anti ?_) (le_generateFrom ?_) · exact fun s ⟨t, ht, Eq⟩ => ⟨t, Finset.univ, by simp [ht, Eq]⟩ · rintro s ⟨t, i, ht, rfl⟩ - letI := generateFrom { t | ∃ s : ∀ a, Set (X a), (∀ a, s a ∈ g a) ∧ t = pi univ s } + let := generateFrom { t | ∃ s : ∀ a, Set (X a), (∀ a, s a ∈ g a) ∧ t = pi univ s } refine isOpen_iff_forall_mem_open.2 fun f hf => ?_ choose c hcg hfc using fun a => sUnion_eq_univ_iff.1 (hg a) (f a) refine ⟨pi i t ∩ pi ((↑i)ᶜ : Set ι) c, inter_subset_left, ?_, ⟨hf, fun a _ => hfc a⟩⟩ diff --git a/Mathlib/Topology/ContinuousMap/Algebra.lean b/Mathlib/Topology/ContinuousMap/Algebra.lean index 4857f9538804c2..0170d061412772 100644 --- a/Mathlib/Topology/ContinuousMap/Algebra.lean +++ b/Mathlib/Topology/ContinuousMap/Algebra.lean @@ -337,7 +337,7 @@ instance instCommGroupContinuousMap [CommGroup β] [IsTopologicalGroup β] : @[to_additive] instance [CommGroup β] [IsTopologicalGroup β] : IsTopologicalGroup C(α, β) where continuous_mul := by - letI : UniformSpace β := IsTopologicalGroup.rightUniformSpace β + let : UniformSpace β := IsTopologicalGroup.rightUniformSpace β have : IsUniformGroup β := isUniformGroup_of_commGroup rw [continuous_iff_continuousAt] rintro ⟨f, g⟩ @@ -347,7 +347,7 @@ instance [CommGroup β] [IsTopologicalGroup β] : IsTopologicalGroup C(α, β) w ((tendsto_iff_forall_isCompact_tendstoUniformlyOn.mp Filter.tendsto_id K hK).prodMk (tendsto_iff_forall_isCompact_tendstoUniformlyOn.mp Filter.tendsto_id K hK)) continuous_inv := by - letI : UniformSpace β := IsTopologicalGroup.rightUniformSpace β + let : UniformSpace β := IsTopologicalGroup.rightUniformSpace β have : IsUniformGroup β := isUniformGroup_of_commGroup rw [continuous_iff_continuousAt] intro f diff --git a/Mathlib/Topology/ContinuousMap/Bounded/ArzelaAscoli.lean b/Mathlib/Topology/ContinuousMap/Bounded/ArzelaAscoli.lean index 4a249f8526e741..82d7e1bd8e8524 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/ArzelaAscoli.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/ArzelaAscoli.lean @@ -96,7 +96,7 @@ theorem arzela_ascoli₂ (s : Set β) (hs : IsCompact s) (A : Set (α →ᵇ β) let F : (α →ᵇ s) → α →ᵇ β := comp (↑) M refine IsCompact.of_isClosed_subset ((?_ : IsCompact (F ⁻¹' A)).image (continuous_comp M)) closed fun f hf => ?_ - · haveI : CompactSpace s := isCompact_iff_compactSpace.1 hs + · have : CompactSpace s := isCompact_iff_compactSpace.1 hs refine arzela_ascoli₁ _ (continuous_iff_isClosed.1 (continuous_comp M) _ closed) ?_ rw [isUniformEmbedding_subtype_val.isUniformInducing.equicontinuous_iff] exact H.comp (A.restrictPreimage F) diff --git a/Mathlib/Topology/Covering/Quotient.lean b/Mathlib/Topology/Covering/Quotient.lean index 476030c955bc6e..7296d6dae34a9d 100644 --- a/Mathlib/Topology/Covering/Quotient.lean +++ b/Mathlib/Topology/Covering/Quotient.lean @@ -123,7 +123,7 @@ noncomputable def fiberEquivGroup {x : X} (e : f ⁻¹' {x}) : f ⁻¹' {x} ≃ lemma mulActionFiber_isPretransitive (x : X) : letI := hf.mulActionFiber x MulAction.IsPretransitive G (f ⁻¹' {x}) := by - letI := hf.mulActionFiber x + let := hf.mulActionFiber x constructor intro e e' obtain ⟨g, hg⟩ := hf.apply_eq_iff_mem_orbit.mp (e'.2.trans e.2.symm) @@ -143,7 +143,7 @@ theorem toPermFiber_injective (x : X) : Function.Injective (hf.toPermFiber x) := fun _ _ eq ↦ hf.toPermFiber_ext x ⟨e, he⟩ congr($eq _) theorem exists_toPermFiber_eq {x : X} (e e' : f ⁻¹' {x}) : ∃ g, hf.toPermFiber x g e = e' := by - letI := hf.mulActionFiber x + let := hf.mulActionFiber x have := hf.mulActionFiber_isPretransitive x obtain ⟨g, rfl⟩ := MulAction.IsPretransitive.exists_smul_eq e e' (M := G) use g @@ -206,7 +206,7 @@ noncomputable def trivializationOfSMulDisjoint [TopologicalSpace G] [DiscreteTop @[to_additive] lemma isCoveringMapOn_of_smul_disjoint (disjoint : ∀ e : E, ∃ U ∈ 𝓝 e, ∀ g : G, ((g • ·) '' U ∩ U).Nonempty → g • e = e) : IsCoveringMapOn f (f '' {e | MulAction.stabilizer G e = ⊥}) := by - letI : TopologicalSpace G := ⊥; have : DiscreteTopology G := ⟨rfl⟩ + let : TopologicalSpace G := ⊥; have : DiscreteTopology G := ⟨rfl⟩ suffices ∀ x ∈ f '' {e | MulAction.stabilizer G e = ⊥}, ∃ t : Trivialization G f, x ∈ t.baseSet by choose t ht using this; exact IsCoveringMapOn.mk _ _ _ _ fun x ↦ ht x x.2 rintro x ⟨e, he, rfl⟩ diff --git a/Mathlib/Topology/DenseEmbedding.lean b/Mathlib/Topology/DenseEmbedding.lean index cf3e63756da367..92af2caba8769b 100644 --- a/Mathlib/Topology/DenseEmbedding.lean +++ b/Mathlib/Topology/DenseEmbedding.lean @@ -192,7 +192,7 @@ theorem extend_unique [T2Space γ] {f : α → γ} {g : β → γ} (di : IsDense theorem continuousAt_extend [T3Space γ] {b : β} {f : α → γ} (di : IsDenseInducing i) (hf : ∀ᶠ x in 𝓝 b, ∃ c, Tendsto f (comap i <| 𝓝 x) (𝓝 c)) : ContinuousAt (di.extend f) b := by set φ := di.extend f - haveI := di.comap_nhds_neBot + have := di.comap_nhds_neBot suffices ∀ V' ∈ 𝓝 (φ b), IsClosed V' → φ ⁻¹' V' ∈ 𝓝 b by simpa [ContinuousAt, (closed_nhds_basis (φ b)).tendsto_right_iff] intro V' V'_in V'_closed diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 2cff2fe9277615..2f829afc822bdb 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -167,7 +167,7 @@ lemma IsDiscrete.preimage' {s : Set Y} (hs : IsDiscrete s) lemma IsDiscrete.eq_of_specializes (hs : IsDiscrete s) {a b : X} (hab : a ⤳ b) (ha : a ∈ s) (hb : b ∈ s) : a = b := by - letI := hs.1 + let := hs.1 simpa only [← Topology.IsInducing.subtypeVal.specializes_iff, hab, Subtype.mk.injEq, true_iff] using specializes_iff_eq (X := s) (x := ⟨a, ha⟩) (y := ⟨b, hb⟩) diff --git a/Mathlib/Topology/ExtendFrom.lean b/Mathlib/Topology/ExtendFrom.lean index e796c7663e3dd6..1fc4b88965207d 100644 --- a/Mathlib/Topology/ExtendFrom.lean +++ b/Mathlib/Topology/ExtendFrom.lean @@ -72,7 +72,7 @@ theorem continuousOn_extendFrom [RegularSpace Y] {f : X → Y} {A B : Set X} (hB suffices ∀ y ∈ V ∩ B, φ y ∈ V' from mem_of_superset (inter_mem_inf V_in <| mem_principal_self B) this rintro y ⟨hyV, hyB⟩ - haveI := mem_closure_iff_nhdsWithin_neBot.mp (hB hyB) + have := mem_closure_iff_nhdsWithin_neBot.mp (hB hyB) have limy : Tendsto f (𝓝[A] y) (𝓝 <| φ y) := tendsto_extendFrom (hf y hyB) have hVy : V ∈ 𝓝 y := IsOpen.mem_nhds V_op hyV have : V ∩ A ∈ 𝓝[A] y := by simpa only [inter_comm] using inter_mem_nhdsWithin A hVy diff --git a/Mathlib/Topology/ExtremallyDisconnected.lean b/Mathlib/Topology/ExtremallyDisconnected.lean index 1916abbee2f674..f20d78a916ddb2 100644 --- a/Mathlib/Topology/ExtremallyDisconnected.lean +++ b/Mathlib/Topology/ExtremallyDisconnected.lean @@ -111,7 +111,7 @@ protected theorem CompactT2.Projective.extremallyDisconnected [CompactSpace X] [ by_cases hx : x ∈ U · exact ⟨⟨(x, false), Or.inr ⟨subset_closure hx, mem_singleton _⟩⟩, rfl⟩ · exact ⟨⟨(x, true), Or.inl ⟨hx, mem_singleton _⟩⟩, rfl⟩ - haveI : CompactSpace Z := isCompact_iff_compactSpace.mp hZ.isCompact + have : CompactSpace Z := isCompact_iff_compactSpace.mp hZ.isCompact obtain ⟨g, hg, g_sec⟩ := h continuous_id f_cont f_sur let φ := Subtype.val ∘ g have hφ : Continuous φ := continuous_subtype_val.comp hg diff --git a/Mathlib/Topology/FiberBundle/Basic.lean b/Mathlib/Topology/FiberBundle/Basic.lean index 81c8a34b2ded66..bddcb12e1ae666 100644 --- a/Mathlib/Topology/FiberBundle/Basic.lean +++ b/Mathlib/Topology/FiberBundle/Basic.lean @@ -783,7 +783,7 @@ theorem isOpen_source (e : Pretrivialization F (π F E)) : theorem isOpen_target_of_mem_pretrivializationAtlas_inter (e e' : Pretrivialization F (π F E)) (he' : e' ∈ a.pretrivializationAtlas) : IsOpen (e'.toPartialEquiv.target ∩ e'.toPartialEquiv.symm ⁻¹' e.source) := by - letI := a.totalSpaceTopology + let := a.totalSpaceTopology obtain ⟨u, hu1, hu2⟩ := continuousOn_iff'.mp (a.continuous_symm_of_mem_pretrivializationAtlas he') e.source (a.isOpen_source e) rw [inter_comm, hu2] @@ -822,7 +822,7 @@ theorem totalSpaceMk_preimage_source (b : B) : @[continuity] theorem continuous_totalSpaceMk (b : B) : Continuous[_, a.totalSpaceTopology] (TotalSpace.mk b) := by - letI := a.totalSpaceTopology + let := a.totalSpaceTopology let e := a.trivializationOfMemPretrivializationAtlas (a.pretrivialization_mem_atlas b) rw [e.toOpenPartialHomeomorph.continuous_iff_continuous_comp_left (a.totalSpaceMk_preimage_source b)] @@ -831,7 +831,7 @@ theorem continuous_totalSpaceMk (b : B) : theorem inducing_totalSpaceMk_of_inducing_comp (b : B) (h : IsInducing (a.pretrivializationAt b ∘ TotalSpace.mk b)) : @IsInducing _ _ _ a.totalSpaceTopology (TotalSpace.mk b) := by - letI := a.totalSpaceTopology + let := a.totalSpaceTopology rw [← restrict_comp_codRestrict (a.mem_pretrivializationAt_source b)] at h apply IsInducing.of_codRestrict (a.mem_pretrivializationAt_source b) refine h.of_comp ?_ (continuousOn_iff_continuous_restrict.mp @@ -858,8 +858,8 @@ def toFiberBundle : @FiberBundle B F _ _ E a.totalSpaceTopology _ := trivialization_mem_atlas' := fun x ↦ ⟨_, a.pretrivialization_mem_atlas x, rfl⟩ } theorem continuous_proj : @Continuous _ _ a.totalSpaceTopology _ (π F E) := by - letI := a.totalSpaceTopology - letI := a.toFiberBundle + let := a.totalSpaceTopology + let := a.toFiberBundle exact FiberBundle.continuous_proj F E instance {e₀} (he₀ : e₀ ∈ a.pretrivializationAtlas) : @@ -875,7 +875,7 @@ theorem continuousOn_of_comp_right {X : Type*} [TopologicalSpace X] {f : TotalSp ContinuousOn (f ∘ (a.pretrivializationAt b).toPartialEquiv.symm) ((s ∩ (a.pretrivializationAt b).baseSet) ×ˢ (Set.univ : Set F))) : @ContinuousOn _ _ a.totalSpaceTopology _ f (π F E ⁻¹' s) := by - letI := a.totalSpaceTopology + let := a.totalSpaceTopology intro z hz let e : Trivialization F (π F E) := a.trivializationOfMemPretrivializationAtlas (a.pretrivialization_mem_atlas z.proj) diff --git a/Mathlib/Topology/GDelta/Basic.lean b/Mathlib/Topology/GDelta/Basic.lean index 66109db6c0356e..a2ee08f033db7f 100644 --- a/Mathlib/Topology/GDelta/Basic.lean +++ b/Mathlib/Topology/GDelta/Basic.lean @@ -111,7 +111,7 @@ protected theorem IsGδ.iInter [Countable ι'] {s : ι' → Set X} (hs : ∀ i, theorem IsGδ.biInter {s : Set ι} (hs : s.Countable) {t : ∀ i ∈ s, Set X} (ht : ∀ (i) (hi : i ∈ s), IsGδ (t i hi)) : IsGδ (⋂ i ∈ s, t i ‹_›) := by rw [biInter_eq_iInter] - haveI := hs.to_subtype + have := hs.to_subtype exact .iInter fun x => ht x x.2 diff --git a/Mathlib/Topology/Homotopy/LocallyContractible.lean b/Mathlib/Topology/Homotopy/LocallyContractible.lean index 1f2349bda7e995..90b414ec0e1f54 100644 --- a/Mathlib/Topology/Homotopy/LocallyContractible.lean +++ b/Mathlib/Topology/Homotopy/LocallyContractible.lean @@ -158,8 +158,8 @@ instance [StronglyLocallyContractibleSpace X] [StronglyLocallyContractibleSpace rw [nhds_prod_eq] exact (contractible_basis x).prod (contractible_basis y) · intro (x, y) (Ux, Uy) ⟨hUx, hUy⟩ - haveI : ContractibleSpace Ux := hUx.2 - haveI : ContractibleSpace Uy := hUy.2 + have : ContractibleSpace Ux := hUx.2 + have : ContractibleSpace Uy := hUy.2 exact (Homeomorph.Set.prod Ux Uy).contractibleSpace end Products diff --git a/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean b/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean index 5e833eaa0a3ae7..a0c1a429a28a30 100644 --- a/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean +++ b/Mathlib/Topology/Homotopy/TopCat/ZerothHomotopy.lean @@ -98,7 +98,7 @@ lemma zerothHomotopyEquiv_symm_mk (x : (toSSet.obj X) _⦋0⦌) : zerothHomotopyEquiv.symm (.mk x) = .mk (toSSetObj₀Equiv x) := rfl instance [PathConnectedSpace X] : (toSSet.obj X).IsConnected := by - letI : Unique (ZerothHomotopy X) := Nonempty.some (by + let : Unique (ZerothHomotopy X) := Nonempty.some (by rw [unique_iff_subsingleton_and_nonempty] constructor <;> infer_instance) rw [SSet.isConnected_iff_nonempty_unique] diff --git a/Mathlib/Topology/Instances/Complex.lean b/Mathlib/Topology/Instances/Complex.lean index f476d7ae6403fc..713a64e09c69f9 100644 --- a/Mathlib/Topology/Instances/Complex.lean +++ b/Mathlib/Topology/Instances/Complex.lean @@ -52,8 +52,8 @@ continuous, then `ψ` is either the inclusion map or the composition of the incl complex conjugation. -/ theorem Complex.uniformContinuous_ringHom_eq_id_or_conj (K : Subfield ℂ) {ψ : K →+* ℂ} (hc : UniformContinuous ψ) : ψ.toFun = K.subtype ∨ ψ.toFun = conj ∘ K.subtype := by - letI : IsTopologicalDivisionRing ℂ := IsTopologicalDivisionRing.mk - letI : IsTopologicalRing K.topologicalClosure := + let : IsTopologicalDivisionRing ℂ := IsTopologicalDivisionRing.mk + let : IsTopologicalRing K.topologicalClosure := Subring.instIsTopologicalRing K.topologicalClosure.toSubring set ι : K → K.topologicalClosure := ⇑(Subfield.inclusion K.le_topologicalClosure) have ui : IsUniformInducing ι := @@ -63,7 +63,7 @@ theorem Complex.uniformContinuous_ringHom_eq_id_or_conj (K : Subfield ℂ) {ψ : let di := ui.isDenseInducing (?_ : DenseRange ι) · -- extψ : closure(K) →+* ℂ is the extension of ψ : K →+* ℂ let extψ := IsDenseInducing.extendRingHom ui di.dense hc - haveI hψ := (uniformContinuous_uniformly_extend ui di.dense hc).continuous + have hψ := (uniformContinuous_uniformly_extend ui di.dense hc).continuous rcases Complex.subfield_eq_of_closed (Subfield.isClosed_topologicalClosure K) with h | h · left let j := RingEquiv.subfieldCongr h diff --git a/Mathlib/Topology/IsLocalHomeomorph.lean b/Mathlib/Topology/IsLocalHomeomorph.lean index b4874b31b09838..46a7c4376cbfe5 100644 --- a/Mathlib/Topology/IsLocalHomeomorph.lean +++ b/Mathlib/Topology/IsLocalHomeomorph.lean @@ -53,7 +53,7 @@ theorem isLocalHomeomorphOn_iff_isOpenEmbedding_restrict {f : X → Y} : refine emb.comp ⟨.inclusion interior_subset, ?_⟩ rw [Set.range_inclusion]; exact isOpen_induced isOpen_interior obtain ⟨cont, inj, openMap⟩ := isOpenEmbedding_iff_continuous_injective_isOpenMap.mp this - haveI : Nonempty X := ⟨x⟩ + have : Nonempty X := ⟨x⟩ exact ⟨OpenPartialHomeomorph.ofContinuousOpenRestrict (Set.injOn_iff_injective.mpr inj).toPartialEquiv (continuousOn_iff_continuous_restrict.mpr cont) openMap isOpen_interior, diff --git a/Mathlib/Topology/LocallyConstant/Basic.lean b/Mathlib/Topology/LocallyConstant/Basic.lean index aa3f28e9167a39..8bd260514e4ecc 100644 --- a/Mathlib/Topology/LocallyConstant/Basic.lean +++ b/Mathlib/Topology/LocallyConstant/Basic.lean @@ -153,7 +153,7 @@ theorem iff_is_const [PreconnectedSpace X] {f : X → Y} : IsLocallyConstant f theorem range_finite [CompactSpace X] {f : X → Y} (hf : IsLocallyConstant f) : (Set.range f).Finite := by - letI : TopologicalSpace Y := ⊥; haveI := discreteTopology_bot Y + let : TopologicalSpace Y := ⊥; have := discreteTopology_bot Y exact (isCompact_range hf.continuous).finite_of_discrete @[to_additive] @@ -525,7 +525,7 @@ def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩ isLocallyConstant := by let dZ : TopologicalSpace Z := ⊥ - haveI : DiscreteTopology Z := discreteTopology_bot Z + have : DiscreteTopology Z := discreteTopology_bot Z obtain ⟨f, hf⟩ := f obtain ⟨g, hg⟩ := g rw [IsLocallyConstant.iff_continuous] at hf hg ⊢ @@ -584,7 +584,7 @@ lemma piecewise'_apply_left {C₀ C₁ C₂ : Set X} (h₀ : C₀ ⊆ C₁ ∪ C [DecidablePred (· ∈ C₁)] (hf : ∀ x (hx : x ∈ C₁ ∩ C₂), f₁ ⟨x, hx.1⟩ = f₂ ⟨x, hx.2⟩) (x : C₀) (hx : x.val ∈ C₁) : piecewise' h₀ h₁ h₂ f₁ f₂ hf x = f₁ ⟨x.val, hx⟩ := by - letI : ∀ j : C₀, Decidable (j ∈ Subtype.val ⁻¹' C₁) := fun j ↦ decidable_of_iff (↑j ∈ C₁) Iff.rfl + let : ∀ j : C₀, Decidable (j ∈ Subtype.val ⁻¹' C₁) := fun j ↦ decidable_of_iff (↑j ∈ C₁) Iff.rfl rw [piecewise', piecewise_apply_left (f := (f₁.comap ⟨(restrictPreimage C₁ ((↑) : C₀ → X)), continuous_subtype_val.restrictPreimage⟩)) (hx := hx)] @@ -596,7 +596,7 @@ lemma piecewise'_apply_right {C₀ C₁ C₂ : Set X} (h₀ : C₀ ⊆ C₁ ∪ [DecidablePred (· ∈ C₁)] (hf : ∀ x (hx : x ∈ C₁ ∩ C₂), f₁ ⟨x, hx.1⟩ = f₂ ⟨x, hx.2⟩) (x : C₀) (hx : x.val ∈ C₂) : piecewise' h₀ h₁ h₂ f₁ f₂ hf x = f₂ ⟨x.val, hx⟩ := by - letI : ∀ j : C₀, Decidable (j ∈ Subtype.val ⁻¹' C₁) := fun j ↦ decidable_of_iff (↑j ∈ C₁) Iff.rfl + let : ∀ j : C₀, Decidable (j ∈ Subtype.val ⁻¹' C₁) := fun j ↦ decidable_of_iff (↑j ∈ C₁) Iff.rfl rw [piecewise', piecewise_apply_right (f := (f₁.comap ⟨(restrictPreimage C₁ ((↑) : C₀ → X)), continuous_subtype_val.restrictPreimage⟩)) (hx := hx)] diff --git a/Mathlib/Topology/Maps/Basic.lean b/Mathlib/Topology/Maps/Basic.lean index 4efc1e7e0b3e4e..f05bc5d51367aa 100644 --- a/Mathlib/Topology/Maps/Basic.lean +++ b/Mathlib/Topology/Maps/Basic.lean @@ -176,7 +176,7 @@ theorem indiscreteTopology [IndiscreteTopology Y] {f : X → Y} (hf : IsInducing IndiscreteTopology X where eq_top := by cases IndiscreteTopology.eq_top Y - letI : TopologicalSpace Y := ⊤ + let : TopologicalSpace Y := ⊤ rw [hf.eq_induced, induced_top] theorem nontrivialTopology [NontrivialTopology X] {f : X → Y} (hf : IsInducing f) : diff --git a/Mathlib/Topology/MetricSpace/Contracting.lean b/Mathlib/Topology/MetricSpace/Contracting.lean index f5f8402044f70f..c4bd6fe2e61b90 100644 --- a/Mathlib/Topology/MetricSpace/Contracting.lean +++ b/Mathlib/Topology/MetricSpace/Contracting.lean @@ -153,7 +153,7 @@ theorem exists_fixedPoint' {s : Set α} (hsc : IsComplete s) (hsf : MapsTo f s s (hf : ContractingWith K <| hsf.restrict f s s) {x : α} (hxs : x ∈ s) (hx : edist x (f x) ≠ ∞) : ∃ y ∈ s, IsFixedPt f y ∧ Tendsto (fun n ↦ f^[n] x) atTop (𝓝 y) ∧ ∀ n : ℕ, edist (f^[n] x) y ≤ edist x (f x) * (K : ℝ≥0∞) ^ n / (1 - K) := by - haveI := hsc.completeSpace_coe + have := hsc.completeSpace_coe rcases hf.exists_fixedPoint ⟨x, hxs⟩ hx with ⟨y, hfy, h_tendsto, hle⟩ refine ⟨y, y.2, Subtype.ext_iff.1 hfy, ?_, fun n ↦ ?_⟩ · convert! (continuous_subtype_val.tendsto _).comp h_tendsto diff --git a/Mathlib/Topology/MetricSpace/HausdorffDimension.lean b/Mathlib/Topology/MetricSpace/HausdorffDimension.lean index ed5a2c477ce67d..fd7cd37ef566b4 100644 --- a/Mathlib/Topology/MetricSpace/HausdorffDimension.lean +++ b/Mathlib/Topology/MetricSpace/HausdorffDimension.lean @@ -197,7 +197,7 @@ theorem dimH_iUnion {ι : Sort*} [Countable ι] (s : ι → Set X) : @[simp] theorem dimH_bUnion {s : Set ι} (hs : s.Countable) (t : ι → Set X) : dimH (⋃ i ∈ s, t i) = ⨆ i ∈ s, dimH (t i) := by - haveI := hs.toEncodable + have := hs.toEncodable rw [biUnion_eq_iUnion, dimH_iUnion, ← iSup_subtype''] @[simp] diff --git a/Mathlib/Topology/MetricSpace/HolderNorm.lean b/Mathlib/Topology/MetricSpace/HolderNorm.lean index 966b5a9b538ed3..fdc37615f136da 100644 --- a/Mathlib/Topology/MetricSpace/HolderNorm.lean +++ b/Mathlib/Topology/MetricSpace/HolderNorm.lean @@ -148,7 +148,7 @@ lemma MemHolder.of_le' {s : ℝ≥0} (hf : MemHolder r f) (hs : s ≤ r) (hX : ∃ C : ℝ≥0, ∀ x y : X, edist x y ≤ C) : MemHolder s f := by obtain ⟨C, hX⟩ := hX - letI := PseudoEMetricSpace.toPseudoMetricSpace + let := PseudoEMetricSpace.toPseudoMetricSpace fun x y ↦ ne_top_of_le_ne_top ENNReal.coe_ne_top (hX x y) have := Metric.boundedSpace_iff_edist.2 ⟨C, hX⟩ exact hf.of_le hs @@ -171,7 +171,7 @@ lemma HolderOnWith.exists_holderOnWith_of_le' {D s : ℝ≥0} {A : Set X} (hA : ∀ ⦃x⦄, x ∈ A → ∀ ⦃y⦄, y ∈ A → edist x y ≤ D) : ∃ C, HolderOnWith C s f A := by simp_rw [← HolderWith.restrict_iff] at * - letI := PseudoEMetricSpace.toPseudoMetricSpace + let := PseudoEMetricSpace.toPseudoMetricSpace fun x y : A ↦ ne_top_of_le_ne_top ENNReal.coe_ne_top (hA x.2 y.2) have : BoundedSpace A := Metric.boundedSpace_iff_edist.2 ⟨D, fun x y ↦ hA x.2 y.2⟩ exact MemHolder.of_le hf hs diff --git a/Mathlib/Topology/MetricSpace/Kuratowski.lean b/Mathlib/Topology/MetricSpace/Kuratowski.lean index b09bddacde1d24..4770c93a1d7d19 100644 --- a/Mathlib/Topology/MetricSpace/Kuratowski.lean +++ b/Mathlib/Topology/MetricSpace/Kuratowski.lean @@ -88,7 +88,7 @@ theorem exists_isometric_embedding (α : Type u) [MetricSpace α] [SeparableSpac · use fun _ => 0; intro x; exact absurd h (Nonempty.ne_empty ⟨x, mem_univ x⟩) · -- We construct a map x : ℕ → α with dense image rcases h with ⟨basepoint⟩ - haveI : Inhabited α := ⟨basepoint⟩ + have : Inhabited α := ⟨basepoint⟩ have : ∃ s : Set α, s.Countable ∧ Dense s := exists_countable_dense α rcases this with ⟨S, ⟨S_countable, S_dense⟩⟩ rcases Set.countable_iff_exists_subset_range.1 S_countable with ⟨x, x_range⟩ diff --git a/Mathlib/Topology/MetricSpace/Perfect.lean b/Mathlib/Topology/MetricSpace/Perfect.lean index b128c20a2c79d9..aa0ef95fe13ac0 100644 --- a/Mathlib/Topology/MetricSpace/Perfect.lean +++ b/Mathlib/Topology/MetricSpace/Perfect.lean @@ -135,7 +135,7 @@ from the Cantor space `ℕ → Bool`. -/ theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α] [PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) : ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by - letI := TopologicalSpace.upgradeIsCompletelyMetrizable α + let := TopologicalSpace.upgradeIsCompletelyMetrizable α obtain ⟨D, hD, Dnonempty, hDC⟩ := exists_perfect_nonempty_of_isClosed_of_not_countable hC hunc obtain ⟨f, hfD, hf⟩ := hD.exists_nat_bool_injection Dnonempty exact ⟨f, hfD.trans hDC, hf⟩ diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index a503e533a8f72a..3627d695d61500 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -702,7 +702,7 @@ theorem exists_nat_nat_continuous_surjective_of_completeSpace (α : Type*) [Metr balls `closedBall (u xₙ) (1/2^n)` have a nonempty intersection. This set is closed, and we define `f x` there to be the unique point in the intersection. This function is continuous and surjective by design. -/ - letI : MetricSpace (ℕ → ℕ) := PiNat.metricSpaceNatNat + let : MetricSpace (ℕ → ℕ) := PiNat.metricSpaceNatNat have I0 : (0 : ℝ) < 1 / 2 := by simp have I1 : (1 / 2 : ℝ) < 1 := by norm_num rcases exists_dense_seq α with ⟨u, hu⟩ @@ -1075,7 +1075,7 @@ variable [TopologicalSpace X] [CompactSpace X] lemma isHomeomorph_toPiNat (continuous_f : ∀ i, Continuous (f i)) (separating_f : Pairwise fun x y ↦ ∃ i, f i x ≠ f i y) : IsHomeomorph (toPiNat : X → PiNatEmbed X Y f) := by - letI := emetricSpace separating_f + let := emetricSpace separating_f rw [isHomeomorph_iff_continuous_bijective] exact ⟨continuous_toPiNat continuous_f, (toPiNatEquiv X Y f).bijective⟩ diff --git a/Mathlib/Topology/MetricSpace/Polish.lean b/Mathlib/Topology/MetricSpace/Polish.lean index d42f8b1fadc484..ec205e848d4f8e 100644 --- a/Mathlib/Topology/MetricSpace/Polish.lean +++ b/Mathlib/Topology/MetricSpace/Polish.lean @@ -64,8 +64,8 @@ class PolishSpace (α : Type*) [h : TopologicalSpace α] : Prop instance [TopologicalSpace α] [SeparableSpace α] [IsCompletelyMetrizableSpace α] : PolishSpace α := by - letI := upgradeIsCompletelyMetrizable α - haveI := UniformSpace.secondCountable_of_separable α + let := upgradeIsCompletelyMetrizable α + have := UniformSpace.secondCountable_of_separable α constructor namespace PolishSpace @@ -79,9 +79,9 @@ theorem exists_nat_nat_continuous_surjective (α : Type*) [TopologicalSpace α] /-- Given a closed embedding into a Polish space, the source space is also Polish. -/ theorem _root_.Topology.IsClosedEmbedding.polishSpace [TopologicalSpace α] [TopologicalSpace β] [PolishSpace β] {f : α → β} (hf : IsClosedEmbedding f) : PolishSpace α := by - letI := upgradeIsCompletelyMetrizable β - letI : MetricSpace α := hf.isEmbedding.comapMetricSpace f - haveI : SecondCountableTopology α := hf.isEmbedding.secondCountableTopology + let := upgradeIsCompletelyMetrizable β + let : MetricSpace α := hf.isEmbedding.comapMetricSpace f + have : SecondCountableTopology α := hf.isEmbedding.secondCountableTopology have : CompleteSpace α := by rw [completeSpace_iff_isComplete_range hf.isEmbedding.to_isometry.isUniformInducing] exact hf.isClosed_range.isComplete @@ -122,7 +122,7 @@ protected theorem iInf {ι : Type*} [Countable ι] {t : ι → TopologicalSpace have : @SecondCountableTopology α u.toTopologicalSpace := htop.symm ▸ secondCountableTopology_iInf fun i ↦ letI := t i; (ht i).toSecondCountableTopology have : @T1Space α u.toTopologicalSpace := - htop.symm ▸ t1Space_antitone (iInf_le _ i₀) (by letI := t i₀; haveI := ht i₀; infer_instance) + htop.symm ▸ t1Space_antitone (iInf_le _ i₀) (by let := t i₀; have := ht i₀; infer_instance) infer_instance /-- Given a Polish space, and countably many finer Polish topologies, there exists another Polish @@ -244,7 +244,7 @@ instance instCompleteSpace [CompleteSpace α] : CompleteSpace (CompleteCopy s) : /-- An open subset of a Polish space is also Polish. -/ theorem _root_.IsOpen.polishSpace {α : Type*} [TopologicalSpace α] [PolishSpace α] {s : Set α} (hs : IsOpen s) : PolishSpace s := by - letI := upgradeIsCompletelyMetrizable α + let := upgradeIsCompletelyMetrizable α lift s to Opens α using hs exact inferInstanceAs (PolishSpace s.CompleteCopy) @@ -270,9 +270,9 @@ theorem _root_.IsClosed.isClopenable [TopologicalSpace α] [PolishSpace α] {s : Pulling back this topology by the canonical bijection with `α` gives the desired Polish topology in which `s` is both open and closed. -/ classical - haveI : PolishSpace s := hs.polishSpace + have : PolishSpace s := hs.polishSpace let t : Set α := sᶜ - haveI : PolishSpace t := hs.isOpen_compl.polishSpace + have : PolishSpace t := hs.isOpen_compl.polishSpace let f : s ⊕ t ≃ α := Equiv.Set.sumCompl s have hle : TopologicalSpace.coinduced f instTopologicalSpaceSum ≤ ‹_› := by simp only [instTopologicalSpaceSum, coinduced_sup, coinduced_compose, sup_le_iff, diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean index 107e604e11d6c1..c41d8cca739342 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean @@ -106,7 +106,7 @@ theorem totallyBounded_of_finite_discretization {s : Set α} · rw [hs] exact totallyBounded_empty rcases hs with ⟨x0, hx0⟩ - haveI : Inhabited s := ⟨⟨x0, hx0⟩⟩ + have : Inhabited s := ⟨⟨x0, hx0⟩⟩ refine totallyBounded_iff.2 fun ε ε0 => ?_ rcases H ε ε0 with ⟨β, fβ, F, hF⟩ let Finv := Function.invFun F @@ -214,7 +214,7 @@ namespace Topology protected lemma IsInducing.isSeparable_preimage {α : Type*} [TopologicalSpace α] [PseudoMetrizableSpace α] {f : β → α} [TopologicalSpace β] (hf : IsInducing f) {s : Set α} (hs : IsSeparable s) : IsSeparable (f ⁻¹' s) := by - letI : UniformSpace α := TopologicalSpace.pseudoMetrizableSpaceUniformity α + let : UniformSpace α := TopologicalSpace.pseudoMetrizableSpaceUniformity α have := pseudoMetrizableSpaceUniformity_countably_generated have : SeparableSpace s := hs.separableSpace have : SecondCountableTopology s := UniformSpace.secondCountable_of_separable _ diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean b/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean index dacf17f4201767..023a65d4d1cb14 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean @@ -140,7 +140,7 @@ lemma sphere_pi (x : ∀ b, X b) {r : ℝ} (h : 0 < r ∨ Nonempty β) : obtain hr | rfl | hr := lt_trichotomy r 0 · simp [hr] · rw [closedBall_eq_sphere_of_nonpos le_rfl, eq_comm, Set.inter_eq_right] - letI := h.resolve_left (lt_irrefl _) + let := h.resolve_left (lt_irrefl _) inhabit β refine subset_iUnion_of_subset default ?_ intro x hx diff --git a/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean b/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean index e03365274cc588..6cf8b5e81c2ee6 100644 --- a/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean +++ b/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean @@ -102,14 +102,14 @@ namespace IsCompletelyPseudoMetrizableSpace completeness. -/ instance (priority := 90) PseudoMetrizableSpace [TopologicalSpace X] [IsCompletelyPseudoMetrizableSpace X] : PseudoMetrizableSpace X := by - letI := upgradeIsCompletelyPseudoMetrizable X + let := upgradeIsCompletelyPseudoMetrizable X infer_instance /-- A countable product of completely pseudometrizable spaces is completely pseudometrizable. -/ instance pi_countable {ι : Type*} [Countable ι] {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, IsCompletelyPseudoMetrizableSpace (X i)] : IsCompletelyPseudoMetrizableSpace (Π i, X i) := by - letI := fun i ↦ upgradeIsCompletelyPseudoMetrizable (X i) + let := fun i ↦ upgradeIsCompletelyPseudoMetrizable (X i) infer_instance /-- The product of two completely pseudometrizable spaces is completely pseudometrizable. -/ @@ -132,8 +132,8 @@ theorem _root_.Topology.IsClosedEmbedding.IsCompletelyPseudoMetrizableSpace [Top [TopologicalSpace Y] [IsCompletelyPseudoMetrizableSpace Y] {f : X → Y} (hf : IsClosedEmbedding f) : IsCompletelyPseudoMetrizableSpace X := by - letI := upgradeIsCompletelyPseudoMetrizable Y - letI : PseudoMetricSpace X := hf.isEmbedding.comapPseudoMetricSpace + let := upgradeIsCompletelyPseudoMetrizable Y + let : PseudoMetricSpace X := hf.isEmbedding.comapPseudoMetricSpace have : CompleteSpace X := by rw [completeSpace_iff_isComplete_range hf.isEmbedding.to_isometry.isUniformInducing] exact hf.isClosed_range.isComplete @@ -165,7 +165,7 @@ instance IsCompletelyMetrizableSpace.toIsCompletelyPseudoMetrizableSpace [Topolo lemma IsCompletelyMetrizableSpace_of_isCompletelyPseudoMetrizableSpace [TopologicalSpace X] [IsCompletelyPseudoMetrizableSpace X] [T0Space X] : IsCompletelyMetrizableSpace X := by - letI := upgradeIsCompletelyPseudoMetrizable X + let := upgradeIsCompletelyPseudoMetrizable X use MetricSpace.ofT0PseudoMetricSpace X exact ⟨rfl, by infer_instance⟩ @@ -213,13 +213,13 @@ namespace IsCompletelyMetrizableSpace `EMetricSpace.metrizableSpace`. This prevents unnecessary attempts to infer completeness. -/ instance (priority := 90) MetrizableSpace [TopologicalSpace X] [IsCompletelyMetrizableSpace X] : MetrizableSpace X := by - letI := upgradeIsCompletelyMetrizable X + let := upgradeIsCompletelyMetrizable X infer_instance /-- A countable product of completely metrizable spaces is completely metrizable. -/ instance pi_countable {ι : Type*} [Countable ι] {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, IsCompletelyMetrizableSpace (X i)] : IsCompletelyMetrizableSpace (Π i, X i) := by - letI := fun i ↦ upgradeIsCompletelyMetrizable (X i) + let := fun i ↦ upgradeIsCompletelyMetrizable (X i) infer_instance /-- A disjoint union of completely metrizable spaces is completely metrizable. -/ @@ -249,8 +249,8 @@ the source space is also completely metrizable. -/ theorem _root_.Topology.IsClosedEmbedding.IsCompletelyMetrizableSpace [TopologicalSpace X] [TopologicalSpace Y] [IsCompletelyMetrizableSpace Y] {f : X → Y} (hf : IsClosedEmbedding f) : IsCompletelyMetrizableSpace X := by - letI := upgradeIsCompletelyMetrizable Y - letI : MetricSpace X := hf.isEmbedding.comapMetricSpace f + let := upgradeIsCompletelyMetrizable Y + let : MetricSpace X := hf.isEmbedding.comapMetricSpace f have : CompleteSpace X := by rw [completeSpace_iff_isComplete_range hf.isEmbedding.to_isometry.isUniformInducing] exact hf.isClosed_range.isComplete diff --git a/Mathlib/Topology/Metrizable/Uniformity.lean b/Mathlib/Topology/Metrizable/Uniformity.lean index 65a49d6ea9e06f..6814c779443e60 100644 --- a/Mathlib/Topology/Metrizable/Uniformity.lean +++ b/Mathlib/Topology/Metrizable/Uniformity.lean @@ -114,7 +114,7 @@ theorem le_two_mul_dist_ofPreNNDist (d : X → X → ℝ≥0) (dist_self : ∀ x Then `d x₀ xₖ ≤ L`, `d xₖ xₖ₊₁ ≤ L`, and `d xₖ₊₁ xₙ ≤ L`, thus `d x₀ xₙ ≤ 2 * L`. -/ rw [dist_ofPreNNDist, ← NNReal.coe_two, ← NNReal.coe_mul, NNReal.mul_iInf, NNReal.coe_le_coe] refine le_ciInf fun l => ?_ - haveI : IsTrans X fun x y => d x y = 0 := by + have : IsTrans X fun x y => d x y = 0 := by refine ⟨fun a b c hab hbc ↦ ?_⟩ rw [← nonpos_iff_eq_zero] simpa only [nonpos_iff_eq_zero, hab, hbc, dist_self c, max_self, mul_zero] using hd a b c c @@ -209,7 +209,7 @@ protected theorem UniformSpace.metrizable_uniformity (X : Type*) [UniformSpace X · simpa only [not_exists, Classical.not_not, eq_self_iff_true, true_iff] using h have hd_symm x y : d x y = d y x := by simp only [d, (U _).comm] have hr : (1 / 2 : ℝ≥0) ∈ Ioo (0 : ℝ≥0) 1 := ⟨half_pos one_pos, NNReal.half_lt_self one_ne_zero⟩ - letI I := PseudoMetricSpace.ofPreNNDist d (fun x => hd₀.2 rfl) hd_symm + let I := PseudoMetricSpace.ofPreNNDist d (fun x => hd₀.2 rfl) hd_symm have hdist_le : ∀ x y, dist x y ≤ d x y := PseudoMetricSpace.dist_ofPreNNDist_le _ _ _ have hle_d : ∀ {x y : X} {n : ℕ}, (1 / 2) ^ n ≤ d x y ↔ (x, y) ∉ U n := by intro x y n diff --git a/Mathlib/Topology/Metrizable/Urysohn.lean b/Mathlib/Topology/Metrizable/Urysohn.lean index 4bc1411538a7c5..ce8c6c66c541d6 100644 --- a/Mathlib/Topology/Metrizable/Urysohn.lean +++ b/Mathlib/Topology/Metrizable/Urysohn.lean @@ -42,11 +42,11 @@ theorem exists_isInducing_l_infty : ∃ f : X → ℕ →ᵇ ℝ, IsInducing f : rcases exists_countable_basis X with ⟨B, hBc, -, hB⟩ let s : Set (Set X × Set X) := { UV ∈ B ×ˢ B | closure UV.1 ⊆ UV.2 } -- `s` is a countable set. - haveI : Encodable s := ((hBc.prod hBc).mono (sep_subset _ _)).toEncodable + have : Encodable s := ((hBc.prod hBc).mono (sep_subset _ _)).toEncodable -- We don't have the space of bounded (possibly discontinuous) functions, so we equip `s` -- with the discrete topology and deal with `s →ᵇ ℝ` instead. - letI : TopologicalSpace s := ⊥ - haveI : DiscreteTopology s := ⟨rfl⟩ + let : TopologicalSpace s := ⊥ + have : DiscreteTopology s := ⟨rfl⟩ rsuffices ⟨f, hf⟩ : ∃ f : X → s →ᵇ ℝ, IsInducing f · exact ⟨fun x => (f x).extend (Encodable.encode' s) 0, (BoundedContinuousFunction.isometry_extend (Encodable.encode' s) diff --git a/Mathlib/Topology/NhdsWithin.lean b/Mathlib/Topology/NhdsWithin.lean index eb0c67cc29d980..1b865516dd12dd 100644 --- a/Mathlib/Topology/NhdsWithin.lean +++ b/Mathlib/Topology/NhdsWithin.lean @@ -593,7 +593,7 @@ lemma nhdsSetWithin_prod_le {s s' : Set α} {t t' : Set β} : lemma mem_nhdsSet_induced {α β : Type*} {t : TopologicalSpace β} (f : α → β) (s u : Set α) : u ∈ @nhdsSet α (t.induced f) s ↔ ∃ v ∈ 𝓝ˢ (f '' s), f ⁻¹' v ⊆ u := by - letI := t.induced f + let := t.induced f simp_rw [mem_nhdsSet_iff_exists, isOpen_induced_iff] refine ⟨fun ⟨v, ⟨v', hv'⟩, hv⟩ ↦ ?_, fun ⟨v, ⟨v', hv'⟩, hv⟩ ↦ ?_⟩ · refine ⟨v', ⟨v', hv'.1, ?_, subset_rfl⟩, hv'.2.trans_subset hv.2⟩ diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean index 39cc3938b52177..bda74e60b811cb 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean @@ -111,10 +111,10 @@ theorem prod_eq_prod_of_nonempty {eX eX' : OpenPartialHomeomorph X X'} {eY eY' : OpenPartialHomeomorph Y Y'} (h : (eX.prod eY).source.Nonempty) : eX.prod eY = eX'.prod eY' ↔ eX = eX' ∧ eY = eY' := by obtain ⟨⟨x, y⟩, -⟩ := id h - haveI : Nonempty X := ⟨x⟩ - haveI : Nonempty X' := ⟨eX x⟩ - haveI : Nonempty Y := ⟨y⟩ - haveI : Nonempty Y' := ⟨eY y⟩ + have : Nonempty X := ⟨x⟩ + have : Nonempty X' := ⟨eX x⟩ + have : Nonempty Y := ⟨y⟩ + have : Nonempty Y' := ⟨eY y⟩ simp_rw [OpenPartialHomeomorph.ext_iff, prod_apply, prod_symm_apply, prod_source, Prod.ext_iff, Set.prod_eq_prod_iff_of_nonempty h, forall_and, Prod.forall, forall_const, and_assoc, and_left_comm] diff --git a/Mathlib/Topology/Order.lean b/Mathlib/Topology/Order.lean index 56f78491229fab..4cdc12c5c91af1 100644 --- a/Mathlib/Topology/Order.lean +++ b/Mathlib/Topology/Order.lean @@ -77,7 +77,7 @@ theorem isOpen_generateFrom_of_mem {g : Set (Set α)} {s : Set α} (hs : s ∈ g theorem nhds_generateFrom {g : Set (Set α)} {a : α} : @nhds α (generateFrom g) a = ⨅ s ∈ { s | a ∈ s ∧ s ∈ g }, 𝓟 s := by - letI := generateFrom g + let := generateFrom g rw [nhds_def] refine le_antisymm (biInf_mono fun s ⟨as, sg⟩ => ⟨as, .basic _ sg⟩) <| le_iInf₂ ?_ rintro s ⟨ha, hs⟩ @@ -408,7 +408,7 @@ theorem isOpen_induced_iff [t : TopologicalSpace β] {s : Set α} {f : α → β theorem isClosed_induced_iff [t : TopologicalSpace β] {s : Set α} {f : α → β} : IsClosed[t.induced f] s ↔ ∃ t, IsClosed t ∧ f ⁻¹' t = s := by - letI := t.induced f + let := t.induced f simp only [← isOpen_compl_iff, isOpen_induced_iff] exact compl_surjective.exists.trans (by simp only [preimage_compl, compl_inj_iff]) @@ -422,7 +422,7 @@ theorem isClosed_coinduced {t : TopologicalSpace α} {s : Set β} {f : α → β theorem preimage_nhds_coinduced [TopologicalSpace α] {π : α → β} {s : Set β} {a : α} (hs : s ∈ @nhds β (TopologicalSpace.coinduced π ‹_›) (π a)) : π ⁻¹' s ∈ 𝓝 a := by - letI := TopologicalSpace.coinduced π ‹_› + let := TopologicalSpace.coinduced π ‹_› rcases mem_nhds_iff.mp hs with ⟨V, hVs, V_op, mem_V⟩ exact mem_nhds_iff.mpr ⟨π ⁻¹' V, Set.preimage_mono hVs, V_op, mem_V⟩ @@ -882,7 +882,7 @@ theorem continuous_id_of_le {t t' : TopologicalSpace α} (h : t ≤ t') : Contin -- 𝓝 in the induced topology theorem mem_nhds_induced [T : TopologicalSpace α] (f : β → α) (a : β) (s : Set β) : s ∈ @nhds β (TopologicalSpace.induced f T) a ↔ ∃ u ∈ 𝓝 (f a), f ⁻¹' u ⊆ s := by - letI := T.induced f + let := T.induced f simp_rw [mem_nhds_iff, isOpen_induced_iff] constructor · rintro ⟨u, usub, ⟨v, openv, rfl⟩, au⟩ diff --git a/Mathlib/Topology/Order/Compact.lean b/Mathlib/Topology/Order/Compact.lean index f0d3709f69b256..36108625e44d6b 100644 --- a/Mathlib/Topology/Order/Compact.lean +++ b/Mathlib/Topology/Order/Compact.lean @@ -145,7 +145,7 @@ variable {α β γ : Type*} [LinearOrder α] [TopologicalSpace α] theorem IsCompact.exists_isLeast [ClosedIicTopology α] {s : Set α} (hs : IsCompact s) (ne_s : s.Nonempty) : ∃ x, IsLeast s x := by - haveI : Nonempty s := ne_s.to_subtype + have : Nonempty s := ne_s.to_subtype suffices (s ∩ ⋂ x ∈ s, Iic x).Nonempty from ⟨this.choose, this.choose_spec.1, mem_iInter₂.mp this.choose_spec.2⟩ rw [biInter_eq_iInter] @@ -195,7 +195,7 @@ theorem atBot_le_cocompact [NoMinOrder α] [ClosedIicTopology α] : refine (Set.eq_empty_or_nonempty t).casesOn (fun h_empty ↦ ?_) (fun h_nonempty ↦ ?_) · rewrite [compl_univ_iff.mpr h_empty, univ_subset_iff] at hts convert! univ_mem - · haveI := h_nonempty.nonempty + · have := h_nonempty.nonempty obtain ⟨a, ha⟩ := ht.exists_isLeast h_nonempty obtain ⟨b, hb⟩ := exists_lt a exact Filter.mem_atBot_sets.mpr ⟨b, fun b' hb' ↦ hts <| Classical.byContradiction diff --git a/Mathlib/Topology/Order/IntermediateValue.lean b/Mathlib/Topology/Order/IntermediateValue.lean index 843b1fb9c18b9b..14c222e07ed536 100644 --- a/Mathlib/Topology/Order/IntermediateValue.lean +++ b/Mathlib/Topology/Order/IntermediateValue.lean @@ -849,7 +849,7 @@ or antitone (increasing or decreasing). -/ theorem ContinuousOn.strictMonoOn_of_injOn_Ioo {a b : α} {f : α → δ} (hab : a < b) (hf_c : ContinuousOn f (Ioo a b)) (hf_i : InjOn f (Ioo a b)) : StrictMonoOn f (Ioo a b) ∨ StrictAntiOn f (Ioo a b) := by - haveI : Inhabited (Ioo a b) := Classical.inhabited_of_nonempty (nonempty_Ioo_subtype hab) + have : Inhabited (Ioo a b) := Classical.inhabited_of_nonempty (nonempty_Ioo_subtype hab) let g : Ioo a b → δ := Set.restrict (Ioo a b) f have : StrictMono g ∨ StrictAnti g := Continuous.strictMono_of_inj hf_c.restrict hf_i.injective diff --git a/Mathlib/Topology/Order/IsLUB.lean b/Mathlib/Topology/Order/IsLUB.lean index b764d8851c42fb..c3dcdc6ce80b07 100644 --- a/Mathlib/Topology/Order/IsLUB.lean +++ b/Mathlib/Topology/Order/IsLUB.lean @@ -89,7 +89,7 @@ theorem IsLUB.mem_upperBounds_of_tendsto [Preorder γ] [TopologicalSpace γ] [Or (hb : Tendsto f (𝓝[s] a) (𝓝 b)) : b ∈ upperBounds (f '' s) := by rintro _ ⟨x, hx, rfl⟩ replace ha := ha.inter_Ici_of_mem hx - haveI := ha.nhdsWithin_neBot ⟨x, hx, le_rfl⟩ + have := ha.nhdsWithin_neBot ⟨x, hx, le_rfl⟩ refine ge_of_tendsto (hb.mono_left (nhdsWithin_mono a (inter_subset_left (t := Ici x)))) ?_ exact mem_of_superset self_mem_nhdsWithin fun y hy => hf hx hy.1 hy.2 diff --git a/Mathlib/Topology/Order/LawsonTopology.lean b/Mathlib/Topology/Order/LawsonTopology.lean index f55cea77976f08..b72e46d693d0f1 100644 --- a/Mathlib/Topology/Order/LawsonTopology.lean +++ b/Mathlib/Topology/Order/LawsonTopology.lean @@ -100,9 +100,9 @@ protected theorem isTopologicalBasis : TopologicalSpace.IsTopologicalBasis (laws (isTopologicalBasis_opens (α := WithScott α)) WithLower.toLower WithScott.toScott rw [@topology_eq_lawson α _ _ _, lawson] apply (congrArg₂ min _) _ - · letI _ := lower α + · let _ := lower α exact (@IsLower.withLowerHomeomorph α ‹_› (lower α) ⟨rfl⟩).isInducing.eq_induced - · letI _ := scott α univ + · let _ := scott α univ exact (@IsScott.withScottHomeomorph α _ (scott α univ) ⟨rfl⟩).isInducing.eq_induced end Preorder diff --git a/Mathlib/Topology/Order/LeftRightLim.lean b/Mathlib/Topology/Order/LeftRightLim.lean index 349daa40030a6a..0d580b39379eb8 100644 --- a/Mathlib/Topology/Order/LeftRightLim.lean +++ b/Mathlib/Topology/Order/LeftRightLim.lean @@ -281,8 +281,8 @@ theorem rightLim_eq_sInf [TopologicalSpace α] [OrderTopology α] [(𝓝[>] x).N rightLim_eq_of_tendsto (hf.tendsto_nhdsGT x) theorem leftLim_le (h : x ≤ y) : leftLim f x ≤ f y := by - letI : TopologicalSpace α := Preorder.topology α - haveI : OrderTopology α := ⟨rfl⟩ + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ rcases eq_or_neBot (𝓝[<] x) with h' | h' · simpa [leftLim, h'] using hf h rw [leftLim_eq_sSup hf] @@ -294,8 +294,8 @@ theorem leftLim_le (h : x ≤ y) : leftLim f x ≤ f y := by exact hf (hz.le.trans h) theorem le_leftLim (h : x < y) : f x ≤ leftLim f y := by - letI : TopologicalSpace α := Preorder.topology α - haveI : OrderTopology α := ⟨rfl⟩ + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ rcases eq_or_neBot (𝓝[<] y) with h' | h' · rw [leftLim_eq_of_eq_bot _ h'] exact hf h.le @@ -326,8 +326,8 @@ theorem leftLim_le_rightLim (h : x ≤ y) : leftLim f x ≤ rightLim f y := (hf.leftLim_le le_rfl).trans (hf.le_rightLim h) theorem rightLim_le_leftLim (h : x < y) : rightLim f x ≤ leftLim f y := by - letI : TopologicalSpace α := Preorder.topology α - haveI : OrderTopology α := ⟨rfl⟩ + let : TopologicalSpace α := Preorder.topology α + have : OrderTopology α := ⟨rfl⟩ rcases eq_or_neBot (𝓝[<] y) with (h' | h') · simpa [leftLim, h'] using rightLim_le hf h obtain ⟨a, ⟨xa, ay⟩⟩ : (Ioo x y).Nonempty := nonempty_of_mem (Ioo_mem_nhdsLT h) diff --git a/Mathlib/Topology/Order/LeftRightNhds.lean b/Mathlib/Topology/Order/LeftRightNhds.lean index 6d518605ac27d8..5767a8b5ac527d 100644 --- a/Mathlib/Topology/Order/LeftRightNhds.lean +++ b/Mathlib/Topology/Order/LeftRightNhds.lean @@ -368,7 +368,7 @@ theorem orderTopology_of_nhds_mabs {α : Type*} [TopologicalSpace α] [CommGroup (h_nhds : ∀ a : α, 𝓝 a = ⨅ r > 1, 𝓟 { b | |a / b|ₘ < r }) : OrderTopology α := by refine ⟨TopologicalSpace.ext_nhds fun a => ?_⟩ rw [h_nhds] - letI := Preorder.topology α; letI : OrderTopology α := ⟨rfl⟩ + let := Preorder.topology α; let : OrderTopology α := ⟨rfl⟩ exact (nhds_eq_iInf_mabs_div a).symm @[to_additive] diff --git a/Mathlib/Topology/Order/LowerUpperTopology.lean b/Mathlib/Topology/Order/LowerUpperTopology.lean index dea040dc9c0ff3..ff2580b0367db9 100644 --- a/Mathlib/Topology/Order/LowerUpperTopology.lean +++ b/Mathlib/Topology/Order/LowerUpperTopology.lean @@ -287,7 +287,7 @@ protected theorem isTopologicalBasis : IsTopologicalBasis (lowerBasis α) := by refine ⟨(fun a => (Ici a)ᶜ) '' F, ⟨hF.image _, image_subset_iff.2 fun _ _ => ⟨_, rfl⟩⟩, ?_⟩ simp only [sInter_image] · rintro ⟨F, ⟨hF, hs⟩, rfl⟩ - haveI := hF.to_subtype + have := hF.to_subtype rw [subset_def, Subtype.forall'] at hs choose f hf using hs exact ⟨_, finite_range f, by simp_rw [biInter_range, hf, sInter_eq_iInter]⟩ diff --git a/Mathlib/Topology/Order/ScottTopology.lean b/Mathlib/Topology/Order/ScottTopology.lean index 5e77f371f9f738..6f1d54273abad6 100644 --- a/Mathlib/Topology/Order/ScottTopology.lean +++ b/Mathlib/Topology/Order/ScottTopology.lean @@ -298,11 +298,11 @@ lemma isOpen_iff_Iic_compl_or_univ [TopologicalSpace α] [Topology.IsScott α un -- N.B. A number of conditions equivalent to `scott α = upper α` are given in Gierz _et al_, -- Chapter III, Exercise 3.23. lemma scott_eq_upper_of_completeLinearOrder : scott α univ = upper α := by - letI := upper α + let := upper α ext U rw [@Topology.IsUpper.isTopologicalSpace_basis _ _ (upper α) ({ topology_eq_upperTopology := rfl }) U] - letI := scott α univ + let := scott α univ rw [@isOpen_iff_Iic_compl_or_univ _ _ (scott α univ) ({ topology_eq_scott := rfl }) U] /-- The upper topology on a complete linear order is the Scott topology -/ diff --git a/Mathlib/Topology/Order/UpperLowerSetTopology.lean b/Mathlib/Topology/Order/UpperLowerSetTopology.lean index f5ef45ca370159..701388137247f8 100644 --- a/Mathlib/Topology/Order/UpperLowerSetTopology.lean +++ b/Mathlib/Topology/Order/UpperLowerSetTopology.lean @@ -197,7 +197,7 @@ attribute [nolint docBlame] IsUpperSet.topology_eq_upperSetTopology instance [Preorder α] : Topology.IsUpperSet (WithUpperSet α) := ⟨rfl⟩ instance [Preorder α] : @Topology.IsUpperSet α (upperSet α) _ := by - letI := upperSet α + let := upperSet α exact ⟨rfl⟩ /-- @@ -212,7 +212,7 @@ attribute [nolint docBlame] IsLowerSet.topology_eq_lowerSetTopology instance [Preorder α] : Topology.IsLowerSet (WithLowerSet α) := ⟨rfl⟩ instance [Preorder α] : @Topology.IsLowerSet α (lowerSet α) _ := by - letI := lowerSet α + let := lowerSet α exact ⟨rfl⟩ namespace IsUpperSet diff --git a/Mathlib/Topology/PartitionOfUnity.lean b/Mathlib/Topology/PartitionOfUnity.lean index 4f168a7c767a55..0816828b7d7e68 100644 --- a/Mathlib/Topology/PartitionOfUnity.lean +++ b/Mathlib/Topology/PartitionOfUnity.lean @@ -522,7 +522,7 @@ theorem sum_toPOUFun_eq (x : X) : ∑ᶠ i, f.toPOUFun i x = 1 - ∏ᶠ i, (1 - rw [hs, mulSupport_one_sub] exact fun i => id classical - letI : LinearOrder ι := linearOrderOfSTO WellOrderingRel + let : LinearOrder ι := linearOrderOfSTO WellOrderingRel rw [finsum_eq_sum_of_support_subset _ A, finprod_eq_prod_of_mulSupport_subset _ B, Finset.prod_one_sub_ordered, sub_sub_cancel] refine Finset.sum_congr rfl fun i _ => ?_ diff --git a/Mathlib/Topology/Separation/CompletelyRegular.lean b/Mathlib/Topology/Separation/CompletelyRegular.lean index 383562b85614ae..e1060e5e9b5b65 100644 --- a/Mathlib/Topology/Separation/CompletelyRegular.lean +++ b/Mathlib/Topology/Separation/CompletelyRegular.lean @@ -130,7 +130,7 @@ lemma completelyRegularSpace_induced lemma completelyRegularSpace_iInf {ι X : Type*} {t : ι → TopologicalSpace X} (ht : ∀ i, @CompletelyRegularSpace X (t i)) : @CompletelyRegularSpace X (⨅ i, t i) := by - letI := (⨅ i, t i) -- register this as default topological space to reduce `@`s + let := (⨅ i, t i) -- register this as default topological space to reduce `@`s rw [completelyRegularSpace_iff_isOpen] intro x K hK hxK simp_rw [← hK.mem_nhds_iff, nhds_iInf, mem_iInf, exists_finite_iff_finset, diff --git a/Mathlib/Topology/Separation/Connected.lean b/Mathlib/Topology/Separation/Connected.lean index 76fc3d5e5cbfd0..99d9e1285f2ce7 100644 --- a/Mathlib/Topology/Separation/Connected.lean +++ b/Mathlib/Topology/Separation/Connected.lean @@ -36,7 +36,7 @@ theorem PreconnectedSpace.trivial_of_discrete [PreconnectedSpace X] [DiscreteTop theorem IsPreconnected.infinite_of_nontrivial [T1Space X] {s : Set X} (h : IsPreconnected s) (hs : s.Nontrivial) : s.Infinite := by refine mt (fun hf => (subsingleton_coe s).mp ?_) (not_subsingleton_iff.mpr hs) - haveI := @Finite.instDiscreteTopology s _ _ hf.to_subtype + have := @Finite.instDiscreteTopology s _ _ hf.to_subtype exact @PreconnectedSpace.trivial_of_discrete _ _ (Subtype.preconnectedSpace h) _ theorem PreconnectedSpace.infinite [PreconnectedSpace X] [Nontrivial X] [T1Space X] : Infinite X := diff --git a/Mathlib/Topology/Separation/Profinite.lean b/Mathlib/Topology/Separation/Profinite.lean index e39c13acfcdf7d..1bc259a4f9b820 100644 --- a/Mathlib/Topology/Separation/Profinite.lean +++ b/Mathlib/Topology/Separation/Profinite.lean @@ -50,7 +50,7 @@ theorem nhds_basis_clopen (x : X) : (𝓝 x).HasBasis (fun s : Set X => x ∈ s let N := { s // IsClopen s ∧ x ∈ s } rsuffices ⟨⟨s, hs, hs'⟩, hs''⟩ : ∃ s : N, s.val ⊆ U · exact ⟨s, ⟨hs', hs⟩, hs''⟩ - haveI : Nonempty N := ⟨⟨univ, isClopen_univ, mem_univ x⟩⟩ + have : Nonempty N := ⟨⟨univ, isClopen_univ, mem_univ x⟩⟩ have hNcl : ∀ s : N, IsClosed s.val := fun s => s.property.1.1 have hdir : Directed GE.ge fun s : N => s.val := by rintro ⟨s, hs, hxs⟩ ⟨t, ht, hxt⟩ @@ -91,7 +91,7 @@ theorem loc_compact_Haus_tot_disc_of_zero_dim [TotallyDisconnectedSpace H] : let u : Set s := ((↑) : s → H) ⁻¹' interior s have u_open_in_s : IsOpen u := isOpen_interior.preimage continuous_subtype_val lift x to s using interior_subset xs - haveI : CompactSpace s := isCompact_iff_compactSpace.1 comp + have : CompactSpace s := isCompact_iff_compactSpace.1 comp obtain ⟨V : Set s, VisClopen, Vx, V_sub⟩ := compact_exists_isClopen_in_isOpen u_open_in_s xs have VisClopen' : IsClopen (((↑) : s → H) '' V) := by refine ⟨comp.isClosed.isClosedEmbedding_subtypeVal.isClosed_iff_image_isClosed.1 VisClopen.1, diff --git a/Mathlib/Topology/Sequences.lean b/Mathlib/Topology/Sequences.lean index 7fc21d9d8bcf05..2f4e07b6c7fd82 100644 --- a/Mathlib/Topology/Sequences.lean +++ b/Mathlib/Topology/Sequences.lean @@ -230,9 +230,9 @@ theorem SequentialSpace.coinduced [SequentialSpace X] {Y} (f : X → Y) : protected theorem SequentialSpace.iSup {X} {ι : Sort*} {t : ι → TopologicalSpace X} (h : ∀ i, @SequentialSpace X (t i)) : @SequentialSpace X (⨆ i, t i) := by - letI : TopologicalSpace X := ⨆ i, t i + let : TopologicalSpace X := ⨆ i, t i refine ⟨fun s hs ↦ isClosed_iSup_iff.2 fun i ↦ ?_⟩ - letI := t i + let := t i exact IsSeqClosed.isClosed fun u x hus hux ↦ hs hus <| hux.mono_right <| nhds_mono <| le_iSup _ _ protected theorem SequentialSpace.sup {X} {t₁ t₂ : TopologicalSpace X} diff --git a/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean b/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean index 10e884c34da052..37913946b61507 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean @@ -294,7 +294,7 @@ theorem isSheaf_iff_isSheafPreservesLimitPairwiseIntersections : F.IsSheaf ↔ F.IsSheafPreservesLimitPairwiseIntersections := by refine ⟨fun h U ↦ h.isSheafPreservesLimitPairwiseIntersections, fun h ↦ F.isSheaf_iff_isSheafPairwiseIntersections.mpr fun ι U ↦ ?_⟩ - haveI := h U + have := h U exact ⟨isLimitOfPreserves _ (Pairwise.coconeIsColimit U).op⟩ end TopCat.Presheaf diff --git a/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean b/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean index 392e27c8a3faf4..5ed46c6d44c791 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean @@ -147,7 +147,7 @@ variable {X Y : TopCat.{w}} {f : X ⟶ Y} {F : Y.Presheaf C} theorem Topology.IsOpenEmbedding.compatiblePreserving (hf : IsOpenEmbedding f) : CompatiblePreserving (Opens.grothendieckTopology Y) hf.functor := by - haveI : Mono f := (TopCat.mono_iff_injective f).mpr hf.injective + have : Mono f := (TopCat.mono_iff_injective f).mpr hf.injective apply compatiblePreservingOfDownwardsClosed intro U V i refine ⟨(Opens.map f).obj V, eqToIso <| Opens.ext <| Set.image_preimage_eq_of_subset fun x h ↦ ?_⟩ diff --git a/Mathlib/Topology/Sheaves/Stalks.lean b/Mathlib/Topology/Sheaves/Stalks.lean index b700bd02c76c02..00d6b1c30ba650 100644 --- a/Mathlib/Topology/Sheaves/Stalks.lean +++ b/Mathlib/Topology/Sheaves/Stalks.lean @@ -219,7 +219,7 @@ theorem comp (ℱ : X.Presheaf C) (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : theorem stalkPushforward_iso_of_isInducing {f : X ⟶ Y} (hf : IsInducing f) (F : X.Presheaf C) (x : X) : IsIso (F.stalkPushforward _ f x) := by - haveI := Functor.initial_of_adjunction (hf.adjunctionNhds x) + have := Functor.initial_of_adjunction (hf.adjunctionNhds x) convert! (Functor.Final.colimitIso (OpenNhds.map f x).op ((OpenNhds.inclusion x).op ⋙ F)).isIso_hom refine stalk_hom_ext _ fun U hU ↦ (stalkPushforward_germ _ f F _ x hU).trans ?_ diff --git a/Mathlib/Topology/ShrinkingLemma.lean b/Mathlib/Topology/ShrinkingLemma.lean index 770cac4e18c0b6..6f7f11eb5d5499 100644 --- a/Mathlib/Topology/ShrinkingLemma.lean +++ b/Mathlib/Topology/ShrinkingLemma.lean @@ -140,7 +140,7 @@ def chainSup (c : Set (PartialRefinement u s p)) (hc : IsChain (· ≤ ·) c) (n · use i simpa only [(find c ne i).apply_eq (mt (mem_find_carrier_iff _).1 hi)] · simp_rw [not_exists, not_and, not_imp_not, chainSupCarrier, mem_iUnion₂] at hx - haveI : Nonempty (PartialRefinement u s p) := ⟨ne.some⟩ + have : Nonempty (PartialRefinement u s p) := ⟨ne.some⟩ choose! v hvc hiv using hx rcases (hfin x hxs).exists_maximalFor v _ (mem_iUnion.1 (hU hxs)) with ⟨i, hxi : x ∈ u i, hmax : ∀ j, x ∈ u j → v i ≤ v j → v j ≤ v i⟩ @@ -216,7 +216,7 @@ corresponding original open set. -/ theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i)) (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) : ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by - haveI : Nonempty (PartialRefinement u s ⊤) := + have : Nonempty (PartialRefinement u s ⊤) := ⟨⟨u, ∅, uo, us, False.elim, False.elim, fun _ => rfl⟩⟩ have : ∀ c : Set (PartialRefinement u s ⊤), IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub := @@ -344,7 +344,7 @@ theorem exists_subset_iUnion_closure_subset_t2space (hs : IsCompact s) (uo : ∀ (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) : ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ (∀ i, closure (v i) ⊆ u i) ∧ (∀ i, IsCompact (closure (v i))) := by - haveI : Nonempty (PartialRefinement u s (fun w => IsCompact (closure w))) := + have : Nonempty (PartialRefinement u s (fun w => IsCompact (closure w))) := ⟨⟨u, ∅, uo, us, False.elim, False.elim, fun _ => rfl⟩⟩ have : ∀ c : Set (PartialRefinement u s (fun w => IsCompact (closure w))), IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub := diff --git a/Mathlib/Topology/UniformSpace/Cauchy.lean b/Mathlib/Topology/UniformSpace/Cauchy.lean index 74fd21c99e4b5b..346f9f6d9e8159 100644 --- a/Mathlib/Topology/UniformSpace/Cauchy.lean +++ b/Mathlib/Topology/UniformSpace/Cauchy.lean @@ -57,7 +57,7 @@ lemma cauchy_iff_le {l : Filter α} [hl : l.NeBot] : theorem Cauchy.ultrafilter_of {l : Filter α} (h : Cauchy l) : Cauchy (@Ultrafilter.of _ l h.1 : Filter α) := by - haveI := h.1 + have := h.1 have := Ultrafilter.of_le l exact ⟨Ultrafilter.neBot _, (Filter.prod_mono this this).trans h.2⟩ @@ -195,7 +195,7 @@ theorem CauchySeq.nonempty [Preorder β] {u : β → α} (hu : CauchySeq u) : No theorem CauchySeq.mem_entourage {β : Type*} [SemilatticeSup β] {u : β → α} (h : CauchySeq u) {V : SetRel α α} (hV : V ∈ 𝓤 α) : ∃ k₀, ∀ i j, k₀ ≤ i → k₀ ≤ j → (u i, u j) ∈ V := by - haveI := h.nonempty + have := h.nonempty have := h.tendsto_uniformity; rw [← prod_atTop_atTop_eq] at this simpa [MapsTo] using atTop_basis.prod_self.tendsto_left_iff.1 this V hV @@ -329,7 +329,7 @@ theorem isComplete_iff_clusterPt {s : Set α} : theorem isComplete_iff_ultrafilter {s : Set α} : IsComplete s ↔ ∀ l : Ultrafilter α, Cauchy (l : Filter α) → ↑l ≤ 𝓟 s → ∃ x ∈ s, ↑l ≤ 𝓝 x := by refine ⟨fun h l => h l, fun H => isComplete_iff_clusterPt.2 fun l hl hls => ?_⟩ - haveI := hl.1 + have := hl.1 rcases H (Ultrafilter.of l) hl.ultrafilter_of ((Ultrafilter.of_le l).trans hls) with ⟨x, hxs, hxl⟩ exact ⟨x, hxs, (ClusterPt.of_le_nhds hxl).mono (Ultrafilter.of_le l)⟩ @@ -505,7 +505,7 @@ theorem Filter.TotallyBounded.exists_subset_of_mem {f : Filter α} (hf : f.Total choose g hgs hgr using fun x : u => x.coe_prop.2 refine ⟨range g, ?_, ?_, ?_⟩ · exact range_subset_iff.2 hgs - · haveI : Fintype u := (fk.inter_of_left _).fintype + · have : Fintype u := (fk.inter_of_left _).fintype exact finite_range g · filter_upwards [hs, ks] with x xs ⟨y, hy, xy⟩ simp_rw [SetRel.preimage, exists_range_iff] diff --git a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean index c86814c50bb786..b4092ca5e7bab6 100644 --- a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean @@ -141,7 +141,7 @@ theorem tendstoLocallyUniformly_iff_tendstoUniformly_of_compactSpace [CompactSpa /-- For a compact set `s`, locally uniform convergence on `s` is just uniform convergence on `s`. -/ theorem tendstoLocallyUniformlyOn_iff_tendstoUniformlyOn_of_compact (hs : IsCompact s) : TendstoLocallyUniformlyOn F f p s ↔ TendstoUniformlyOn F f p s := by - haveI : CompactSpace s := isCompact_iff_compactSpace.mp hs + have : CompactSpace s := isCompact_iff_compactSpace.mp hs refine ⟨fun h => ?_, TendstoUniformlyOn.tendstoLocallyUniformlyOn⟩ rwa [tendstoLocallyUniformlyOn_iff_tendstoLocallyUniformly_comp_coe, tendstoLocallyUniformly_iff_tendstoUniformly_of_compactSpace, ← diff --git a/Mathlib/Topology/UniformSpace/OfCompactT2.lean b/Mathlib/Topology/UniformSpace/OfCompactT2.lean index 6f639c9f41ad79..d6d172b2e99a59 100644 --- a/Mathlib/Topology/UniformSpace/OfCompactT2.lean +++ b/Mathlib/Topology/UniformSpace/OfCompactT2.lean @@ -57,7 +57,7 @@ def uniformSpaceOfCompactR1 [TopologicalSpace γ] [CompactSpace γ] [R1Space γ] rw [le_iff_forall_inf_principal_compl] intro V V_in by_contra H - haveI : NeBot (F ⊓ 𝓟 Vᶜ) := ⟨H⟩ + have : NeBot (F ⊓ 𝓟 Vᶜ) := ⟨H⟩ -- Hence compactness would give us a cluster point (x, y) for F ⊓ 𝓟 Vᶜ obtain ⟨⟨x, y⟩, hxy⟩ : ∃ p : γ × γ, ClusterPt p (F ⊓ 𝓟 Vᶜ) := exists_clusterPt_of_compactSpace _ -- In particular (x, y) is a cluster point of 𝓟 Vᶜ, hence is not in the interior of V, diff --git a/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean b/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean index 452694a5ae1732..d95ba71c68bdcf 100644 --- a/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean +++ b/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean @@ -37,7 +37,7 @@ instance SetRel.isTrans_entourageProd {s : SetRel X X} {t : SetRel Y Y} [s.IsTra lemma IsUltraUniformity.comap {u : UniformSpace Y} (h : IsUltraUniformity Y) (f : X → Y) : @IsUltraUniformity _ (u.comap f) := by - letI := u.comap f + let := u.comap f refine .mk_of_hasBasis (h.hasBasis.comap (Prod.map f f)) ?_ ?_ <;> · dsimp rintro _ ⟨_, _, _⟩ @@ -46,7 +46,7 @@ lemma IsUltraUniformity.comap {u : UniformSpace Y} (h : IsUltraUniformity Y) (f lemma IsUltraUniformity.inf {u u' : UniformSpace X} (h : @IsUltraUniformity _ u) (h' : @IsUltraUniformity _ u') : @IsUltraUniformity _ (u ⊓ u') := by - letI := u ⊓ u' + let := u ⊓ u' refine .mk_of_hasBasis (h.hasBasis.inf h'.hasBasis) ?_ ?_ <;> · dsimp rintro _ ⟨⟨_, _, _⟩, _, _, _⟩ @@ -62,7 +62,7 @@ instance IsUltraUniformity.prod [UniformSpace X] [UniformSpace Y] lemma IsUltraUniformity.iInf {ι : Type*} {U : (i : ι) → UniformSpace X} (hU : ∀ i, @IsUltraUniformity X (U i)) : @IsUltraUniformity _ (⨅ i, U i : UniformSpace X) := by - letI : UniformSpace X := ⨅ i, U i + let : UniformSpace X := ⨅ i, U i refine .mk_of_hasBasis (iInf_uniformity ▸ Filter.HasBasis.iInf fun i ↦ (hU i).hasBasis) ?_ ?_ <;> · simp only [forall_and, Subtype.forall, id_eq, Set.iInter_coe_set, and_imp] rintro _ _ _ _ _ @@ -83,7 +83,7 @@ instance IsUltraUniformity.bot [UniformSpace X] [DiscreteUniformity X] : IsUltra apply mk_of_hasBasis this <;> { rw [forall_const]; infer_instance } lemma IsUltraUniformity.top : @IsUltraUniformity X (⊤ : UniformSpace X) := by - letI : UniformSpace X := ⊤ + let : UniformSpace X := ⊤ have := Filter.hasBasis_top (α := (X × X)) rw [← top_uniformity] at this apply mk_of_hasBasis this <;> { rw [forall_const]; infer_instance } diff --git a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean index 57505e711eab51..7d76a76a21dc7e 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean @@ -392,7 +392,7 @@ protected theorem postcomp_isUniformEmbedding [UniformSpace γ] {f : γ → β} `𝒰(α, γ, comap f u) = comap (fun g ↦ f ∘ g) 𝒰(α, γ, u₁)`. -/ protected theorem comap_eq {f : γ → β} : 𝒰(α, γ, ‹UniformSpace β›.comap f) = 𝒰(α, β, _).comap (f ∘ ·) := by - letI : UniformSpace γ := .comap f ‹_› + let : UniformSpace γ := .comap f ‹_› exact (UniformFun.postcomp_isUniformInducing (f := f) ⟨rfl⟩).comap_uniformSpace.symm set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/Topology/VectorBundle/Basic.lean b/Mathlib/Topology/VectorBundle/Basic.lean index a2f4df1e3a9076..8c57a42fefaa60 100644 --- a/Mathlib/Topology/VectorBundle/Basic.lean +++ b/Mathlib/Topology/VectorBundle/Basic.lean @@ -925,8 +925,8 @@ theorem toVectorBundle : @VectorBundle R _ F E _ _ _ _ _ _ a.totalSpaceTopology rintro _ _ ⟨e, he, rfl⟩ ⟨e', he', rfl⟩ refine (a.continuousOn_coordChange he he').congr fun b hb ↦ ?_ ext v - haveI h₁ := a.linear_trivializationOfMemPretrivializationAtlas he - haveI h₂ := a.linear_trivializationOfMemPretrivializationAtlas he' + have h₁ := a.linear_trivializationOfMemPretrivializationAtlas he + have h₂ := a.linear_trivializationOfMemPretrivializationAtlas he' rw [trivializationOfMemPretrivializationAtlas] at h₁ h₂ rw [a.coordChange_apply he he' hb v, ContinuousLinearEquiv.coe_coe, Trivialization.coordChangeL_apply] diff --git a/Mathlib/Topology/VectorBundle/Riemannian.lean b/Mathlib/Topology/VectorBundle/Riemannian.lean index a5ae4263dd779a..3df28f7e7b68da 100644 --- a/Mathlib/Topology/VectorBundle/Riemannian.lean +++ b/Mathlib/Topology/VectorBundle/Riemannian.lean @@ -498,7 +498,7 @@ that the bundle is a continuous Riemannian bundle. -/ instance (g : ContinuousRiemannianMetric F E) : letI : RiemannianBundle E := ⟨g.toRiemannianMetric⟩; IsContinuousRiemannianBundle F E := by - letI : RiemannianBundle E := ⟨g.toRiemannianMetric⟩ + let : RiemannianBundle E := ⟨g.toRiemannianMetric⟩ exact ⟨⟨g.inner, g.continuous, fun b v w ↦ rfl⟩⟩ end Construction From 056733e1c3149a8b9a4c85e4cb0f52db473df942 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Tue, 14 Jul 2026 19:17:21 +0000 Subject: [PATCH 0789/1300] chore(LinearAlgebra/Dimension/Torsion/Finite): a torsion module has rank zero (#41739) Also put `rank_eq_zero_iff_isTorsion` in the `Module` namespace. --- .../Dimension/Torsion/Finite.lean | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Dimension/Torsion/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Torsion/Finite.lean index 1f424c680bf03f..edeb022d8167a6 100644 --- a/Mathlib/LinearAlgebra/Dimension/Torsion/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Torsion/Finite.lean @@ -15,14 +15,26 @@ public import Mathlib.LinearAlgebra.Dimension.Finite public section +/-- A torsion module has rank zero. -/ +theorem Module.IsTorsion.rank_eq_zero {R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M] + [Nontrivial R] (h : IsTorsion R M) : Module.rank R M = 0 := by + by_contra! h' + obtain ⟨f, hf⟩ := by rwa [← Cardinal.one_le_iff_ne_zero, one_le_rank_iff] at h' + simpa [← map_smul, zero_notMem_nonZeroDivisors, hf] using @h (f 1) + +theorem Module.IsTorsion.finrank_eq_zero {R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M] + [Nontrivial R] (h : IsTorsion R M) : finrank R M = 0 := + finrank_eq_zero_of_rank_eq_zero h.rank_eq_zero + variable {R M : Type*} [CommRing R] [IsDomain R] [AddCommGroup M] [Module R M] -lemma rank_eq_zero_iff_isTorsion : Module.rank R M = 0 ↔ Module.IsTorsion R M := by - rw [Module.IsTorsion, rank_eq_zero_iff] - simp [mem_nonZeroDivisors_iff_ne_zero] +lemma Module.rank_eq_zero_iff_isTorsion : Module.rank R M = 0 ↔ Module.IsTorsion R M := by + simp [IsTorsion, rank_eq_zero_iff] + +@[deprecated (since := "2026-07-14")] alias +rank_eq_zero_iff_isTorsion := Module.rank_eq_zero_iff_isTorsion /-- The `StrongRankCondition` is automatic. See `commRing_strongRankCondition`. -/ theorem Module.finrank_eq_zero_iff_isTorsion [StrongRankCondition R] [Module.Finite R M] : finrank R M = 0 ↔ Module.IsTorsion R M := by - rw [← rank_eq_zero_iff_isTorsion (R := R), ← finrank_eq_rank] - norm_cast + simp [← rank_eq_zero_iff_isTorsion (R := R), ← finrank_eq_rank] From f98b1aa39a570b402eef93d709b461924e2d6da1 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 14 Jul 2026 19:53:24 +0000 Subject: [PATCH 0790/1300] feat(Data/Fintype/Order): generalize index type to `Sort*` (#41714) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is helpful when dealing with `biSup`s, as `⨆ i ∈ s, f i` expands to `⨆ i, ⨆ _ : i ∈ s, f i` and so sups over proofs are common. --- Mathlib/Data/Fintype/Order.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Data/Fintype/Order.lean b/Mathlib/Data/Fintype/Order.lean index 616051ccc6ca7f..0d19d84b5ae583 100644 --- a/Mathlib/Data/Fintype/Order.lean +++ b/Mathlib/Data/Fintype/Order.lean @@ -182,8 +182,8 @@ noncomputable instance Bool.completeAtomicBooleanAlgebra : CompleteAtomicBoolean section DirectedOrders -variable {α : Type*} {r : α → α → Prop} [IsTrans α r] {β γ : Type*} [Nonempty γ] {f : γ → α} - [Finite β] +variable {ι : Sort*} {α : Type*} {r : α → α → Prop} [IsTrans α r] {γ : Type*} [Nonempty γ] + {f : γ → α} [Finite ι] theorem Directed.finite_set_le (D : Directed r f) {s : Set γ} (hs : s.Finite) : ∃ z, ∀ i ∈ s, r (f i) (f z) := by @@ -197,10 +197,10 @@ lemma Directed.finite_le {ι κ : Sort*} [Nonempty ι] [Finite κ] {f : ι → variable [Nonempty α] [Preorder α] -theorem Finite.exists_le [IsDirectedOrder α] (f : β → α) : ∃ M, ∀ i, f i ≤ M := +theorem Finite.exists_le [IsDirectedOrder α] (f : ι → α) : ∃ M, ∀ i, f i ≤ M := directed_id.finite_le _ -theorem Finite.exists_ge [IsCodirectedOrder α] (f : β → α) : ∃ M, ∀ i, M ≤ f i := +theorem Finite.exists_ge [IsCodirectedOrder α] (f : ι → α) : ∃ M, ∀ i, M ≤ f i := directed_id.finite_le (r := (· ≥ ·)) _ theorem Set.Finite.exists_le [IsDirectedOrder α] {s : Set α} (hs : s.Finite) : @@ -212,14 +212,14 @@ theorem Set.Finite.exists_ge [IsCodirectedOrder α] {s : Set α} (hs : s.Finite) directed_id.finite_set_le (r := (· ≥ ·)) hs @[simp] -theorem Finite.bddAbove_range [IsDirectedOrder α] (f : β → α) : BddAbove (Set.range f) := by +theorem Finite.bddAbove_range [IsDirectedOrder α] (f : ι → α) : BddAbove (Set.range f) := by obtain ⟨M, hM⟩ := Finite.exists_le f refine ⟨M, fun a ha => ?_⟩ obtain ⟨b, rfl⟩ := ha exact hM b @[simp] -theorem Finite.bddBelow_range [IsCodirectedOrder α] (f : β → α) : BddBelow (Set.range f) := by +theorem Finite.bddBelow_range [IsCodirectedOrder α] (f : ι → α) : BddBelow (Set.range f) := by obtain ⟨M, hM⟩ := Finite.exists_ge f refine ⟨M, fun a ha => ?_⟩ obtain ⟨b, rfl⟩ := ha From 6449c8f82f4244db24ac9ea81209f63af933f651 Mon Sep 17 00:00:00 2001 From: Antoine Chambert-Loir Date: Wed, 15 Jul 2026 00:20:11 +0000 Subject: [PATCH 0791/1300] =?UTF-8?q?feat(LinearAlgebra/Transvection/Gener?= =?UTF-8?q?ation):=20non-exceptional=20case=20in=20Dieudonn=C3=A9's=20theo?= =?UTF-8?q?rem=20(#33392)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We prove the theorem of [Dieudonné-1955][J. Dieudonné, “Sur les générateurs des groupes classiques”]. Let `K` be a division ring and `V` be a `K`-module. * `LinearEquiv.mem_transvections_pow_mul_dilatransvections_of_fixedReduce_eq_one`: If `e.fixedReduce = 1`, then `e` can be written as the product of `finrank K (V ⧸ e.fixedSubmodule) - 1` transvections and one dilatransvection. This is the first part of the non-exceptional case in Dieudonné's theorem. (This statement is not interesting when `e = 1`.) * `LinearEquiv.mem_transvections_pow_mul_dilatransvections_of_fixedReduce_ne_smul_id`: If `e.fixedReduce` is not a homothety, then `e` can be written as the product of `finrank K (V ⧸ e.fixedSubmodule) - 1` transvections and one dilatransvection. This is the second part of the non-exceptional case in Dieudonné's theorem. * `LinearEquiv.IsExceptional`: A linear equivalence `e : V ≃ₗ[K] V` is exceptional if `1 < finrank K (V ⧸ e.fixedSubmodule)` and if `e.fixedReduce` is a nontrivial homothety. * `LinearEquiv.mem_dilatransvections_pow_of_notIsExceptional`: This is the non-exceptional case in Dieudonné's theorem, as a combination of the two preceding statements. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 1 + Mathlib/LinearAlgebra/Center.lean | 6 + .../LinearIndependent/Lemmas.lean | 13 + .../Transvection/Generation.lean | 499 ++++++++++++++++++ docs/references.bib | 14 + 5 files changed, 533 insertions(+) create mode 100644 Mathlib/LinearAlgebra/Transvection/Generation.lean diff --git a/Mathlib.lean b/Mathlib.lean index f152a16c49fc9c..c1d9e76f28c7b4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5291,6 +5291,7 @@ public import Mathlib.LinearAlgebra.TensorProduct.Vanishing public import Mathlib.LinearAlgebra.Trace public import Mathlib.LinearAlgebra.Transvection public import Mathlib.LinearAlgebra.Transvection.Basic +public import Mathlib.LinearAlgebra.Transvection.Generation public import Mathlib.LinearAlgebra.UnitaryGroup public import Mathlib.LinearAlgebra.Vandermonde public import Mathlib.Logic.Basic diff --git a/Mathlib/LinearAlgebra/Center.lean b/Mathlib/LinearAlgebra/Center.lean index 22a5bb7949394d..8e8d25428e207a 100644 --- a/Mathlib/LinearAlgebra/Center.lean +++ b/Mathlib/LinearAlgebra/Center.lean @@ -54,6 +54,12 @@ namespace LinearMap variable {R V : Type*} +theorem mem_center_of_apply_eq_smul [Semiring R] [AddCommMonoid V] + [Module R V] {f : V →ₗ[R] V} {a : R} + (hf : ∀ x, f x = a • x) : + f ∈ center (End R V) := by + simp [mem_center_iff, isMulCentral_iff, commute_iff_eq, mul_assoc, LinearMap.ext_iff, hf] + /-- A linear endomorphism of a free module of rank at least 2 that commutes with transvections consists of homotheties with central ratio. -/ theorem commute_transvections_iff_of_basis diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean index 0cbe3abb88dfd9..a9d6c3a893e3fb 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean @@ -294,6 +294,19 @@ variable {S : Type*} [CommRing S] [IsDomain S] [Module S R] [Module S M] [SMulCommClass S R M] [IsScalarTower S R M] [IsTorsionFree S R] (a b c d : S) +lemma LinearIndependent.pair_smul_smul_iff {u v : R} (hu : IsUnit u) (hv : IsUnit v) : + LinearIndependent R ![u • x, v • y] ↔ LinearIndependent R ![x, y] := by + simp only [LinearIndependent.pair_iff] + refine ⟨fun h s t hst ↦ ?_, fun h s t hst ↦ ?_⟩ + · specialize h (s * hu.unit⁻¹) (t * hv.unit⁻¹) + simp only [Units.mul_left_eq_zero] at h + apply h + simpa [← mul_smul, mul_assoc] + · specialize h (s * hu.unit) (t * hv.unit) + simp only [Units.mul_left_eq_zero] at h + apply h + simpa [mul_smul] + lemma LinearIndependent.pair_smul_iff {u : S} (hu : u ≠ 0) : LinearIndependent R ![u • x, u • y] ↔ LinearIndependent R ![x, y] := by simp only [LinearIndependent.pair_iff] diff --git a/Mathlib/LinearAlgebra/Transvection/Generation.lean b/Mathlib/LinearAlgebra/Transvection/Generation.lean new file mode 100644 index 00000000000000..fefe9a9ef8dd15 --- /dev/null +++ b/Mathlib/LinearAlgebra/Transvection/Generation.lean @@ -0,0 +1,499 @@ +/- +Copyright (c) 2025 Antoine Chambert-Loir. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Antoine Chambert-Loir +-/ + +module + +public import Mathlib.LinearAlgebra.Center +public import Mathlib.LinearAlgebra.Transvection.Basic + +/-! +# Dilatransvections generate the special linear group + +We prove the theorem of [dieudonne-1955][J. Dieudonné, “Sur les générateurs +des groupes classiques”]. + +Let `K` be a division ring and `V` be a `K`-module. + +* `LinearEquiv.mem_transvections_pow_mul_dilatransvections_of_fixedReduce_eq_one`: + If `e.fixedReduce = 1`, then `e` can be written as the product + of `finrank K (V ⧸ e.fixedSubmodule) - 1` transvections + and one dilatransvection. + This is the first part of the non-exceptional case in Dieudonné's theorem. + (This statement is not interesting when `e = 1`.) + +* `LinearEquiv.mem_transvections_pow_mul_dilatransvections_of_fixedReduce_ne_smul_id`: + If `e.fixedReduce` is not a homothety, then `e` can be written as the product + of `finrank K (V ⧸ e.fixedSubmodule) - 1` transvections and one dilatransvection. + This is the second part of the non-exceptional case in Dieudonné's theorem. + +* `LinearEquiv.IsExceptional`: + A linear equivalence `e : V ≃ₗ[K] V` is exceptional if `1 < finrank K (V ⧸ e.fixedSubmodule)` + and if `e.fixedReduce` is a nontrivial homothety. + +* `LinearEquiv.mem_dilatransvections_pow_of_not_isExceptional`: + This is the non-exceptional case in Dieudonné's theorem, + as a combination of the two preceding statements. + +## TODO + +* Prove the third and fourth cases of Dieudonné's theorem that + concern the case where `e` is exceptional: + `e` can be written as the product of `finrank K (V ⧸ e.fixedSubmodule)` + transvections and one dilatransvection but not less. + +* Prove that the general linear group is generated by dilatransvections. + +* Prove that the special linear group is generated by transvections + (with a bound on the minimal number of transvections needed). + +* In the statements above, the dilatransvection is at the right of the product; + show that it can be inserted anywhere. + (The point is that transvections normalize dilatransvections.) + +-/ + +@[expose] public section + +namespace LinearEquiv + +open Module.End Module MulAction Submodule LinearMap + +open scoped Pointwise + +variable {K : Type*} [DivisionRing K] + {V : Type*} [AddCommGroup V] [Module K V] [Module.Finite K V] + +variable (e f : V ≃ₗ[K] V) + +theorem finrank_fixedSubmodule_add_le : + finrank K e.fixedSubmodule + finrank K f.fixedSubmodule ≤ + finrank K ↥(e.fixedSubmodule ⊔ f.fixedSubmodule) + + finrank K (e * f).fixedSubmodule := by + have := finrank_mono (fixedSubmodule_inf_fixedSubmodule_le_comp e.toLinearMap f.toLinearMap) + rwa [← Nat.add_le_add_iff_left, finrank_sup_add_finrank_inf_eq] at this + +theorem finrank_le_one_add_finrank_fixedSubmodule_dilatransvection + (he : e ∈ dilatransvections K V) : + finrank K V ≤ 1 + finrank K e.fixedSubmodule := by + rw [fixedSubmodule_eq_ker, add_comm, ← Nat.add_le_add_iff_left, + ← add_assoc, finrank_range_add_finrank_ker, add_comm] + simpa [← mem_dilatransvections_iff_finrank] + +theorem le_one_add_finrank_fixedSubmodule_dilatransvection_mul (hf : f ∈ dilatransvections K V) : + finrank K e.fixedSubmodule ≤ 1 + finrank K (f * e).fixedSubmodule := by + have := finrank_fixedSubmodule_add_le f e + have := finrank_le_one_add_finrank_fixedSubmodule_dilatransvection f hf + have : finrank K ↥(f.fixedSubmodule ⊔ e.fixedSubmodule) ≤ finrank K V := + finrank_le _ + linarith + +theorem finrank_fixedSubmodule_dilatransvection_mul_le (hf : f ∈ dilatransvections K V) : + finrank K (f * e).fixedSubmodule ≤ 1 + finrank K e.fixedSubmodule := by + conv_rhs => rw [show e = f⁻¹ * (f * e) by simp] + rw [← inv_mem_dilatransvections_iff] at hf + exact le_one_add_finrank_fixedSubmodule_dilatransvection_mul (f * e) f⁻¹ hf + +theorem le_one_add_finrank_fixedSubmodule_mul_dilatransvection (hf : f ∈ dilatransvections K V) : + finrank K e.fixedSubmodule ≤ 1 + finrank K (e * f).fixedSubmodule := by + have := finrank_fixedSubmodule_add_le e f + have := finrank_le_one_add_finrank_fixedSubmodule_dilatransvection f hf + have : finrank K ↥(e.fixedSubmodule ⊔ f.fixedSubmodule) ≤ finrank K V := + finrank_le _ + linarith + +theorem finrank_fixedSubmodule_mul_dilatransvection_le (hf : f ∈ dilatransvections K V) : + finrank K (e * f).fixedSubmodule ≤ 1 + finrank K e.fixedSubmodule := by + conv_rhs => rw [show e = (e * f) * f⁻¹ by simp] + rw [← inv_mem_dilatransvections_iff] at hf + exact le_one_add_finrank_fixedSubmodule_mul_dilatransvection (e * f) f⁻¹ hf + +theorem fixedSubmodule_transvection_mul {f : Dual K V} {v : V} + (hv : v ∉ e.fixedSubmodule) (hf : e.fixedSubmodule.map f = ⊥) + (hfv : f (v - e v) = 0) (hfv' : f (e v) = 1) : + (transvection hfv * e).fixedSubmodule = e.fixedSubmodule ⊔ K ∙ v := by + symm + suffices e.fixedSubmodule ⊔ K ∙ v ≤ (transvection hfv * e).fixedSubmodule by + apply Submodule.eq_of_le_of_finrank_le this + rw [finrank_sup_span_singleton hv, add_comm] + apply finrank_fixedSubmodule_dilatransvection_mul_le + exact transvection_mem_dilatransvections hfv + simp only [sup_le_iff, Submodule.span_singleton_le_iff_mem] + have ht : e.fixedSubmodule ≤ (transvection hfv).fixedSubmodule := fun x hx ↦ by + rw [mem_fixedSubmodule_transvection_iff, smul_eq_zero] + left + rw [← Submodule.mem_bot K, ← hf] + exact mem_map_of_mem hx + constructor + · -- e.fixedSubmodule ≤ e'.fixedSubmodule + intro x hx + simp only [mem_fixedSubmodule_iff, LinearEquiv.coe_toLinearMap, LinearEquiv.mul_apply] + suffices transvection hfv x = x by + simp only [mem_fixedSubmodule_iff, LinearEquiv.coe_toLinearMap] at hx + simp only [hx, this] + rw [← LinearEquiv.coe_toLinearMap, ← mem_fixedSubmodule_iff] + exact ht hx + · -- u ∈ e.fixedSubmodule + simp only [mem_fixedSubmodule_iff, LinearEquiv.coe_toLinearMap, + LinearEquiv.mul_apply, transvection.apply] + simp [hfv'] + +/-- A linear equivalence `u : V ≃ₗ[K] V` is exceptional if +it is a nontrivial homothety modulo `u.fixedSubmodule`. -/ +abbrev IsExceptional (e : V ≃ₗ[K] V) : Prop := + 1 < finrank K (V ⧸ e.fixedSubmodule) ∧ + e.fixedReduce ≠ 1 ∧ ∃ a : K, ∀ x, fixedReduce e x = a • x + +/- Private auxiliary construction and lemmas to handle the non-exceptional cases. -/ + +variable {e} in +private def auxTransvection {f : Dual K V} {u : V} + (hf : e.fixedSubmodule ⊔ K ∙ (e u - u) ≤ LinearMap.ker f) : + V ≃ₗ[K] V := + transvection (f := f) (v := u - e u) (by + simp only [← LinearMap.mem_ker] + apply hf + apply Submodule.mem_sup_right + rw [mem_span_singleton] + exact ⟨-1, by simp⟩) + +omit [Module.Finite K V] in +variable {e} in +private theorem auxTransvection_fixed {f : Dual K V} {u : V} + (hf : e.fixedSubmodule ⊔ K ∙ (e u - u) ≤ LinearMap.ker f) : + e.fixedSubmodule ≤ (auxTransvection hf).fixedSubmodule := fun x hx ↦ by + simp [auxTransvection, LinearMap.transvection.apply, ← LinearMap.mem_ker, hf (mem_sup_left hx)] + +variable {e} in +private theorem auxTransvection_mul_fixed {f : Dual K V} {u : V} + {hf : e.fixedSubmodule ⊔ K ∙ (e u - u) ≤ LinearMap.ker f} (hfu : f u = 1) : + (auxTransvection hf * e).fixedSubmodule = e.fixedSubmodule ⊔ K ∙ u := by + apply fixedSubmodule_transvection_mul + · intro hu' + replace hu' := hf (mem_sup_left hu') + rw [mem_ker] at hu' + simp [hu'] at hfu + · rw [eq_bot_iff] + rw [gc_map_comap, Submodule.comap_bot] + exact le_trans le_sup_left hf + · rw [← hfu, ← sub_eq_zero, ← map_sub, ← mem_ker] + refine hf (mem_sup_right ?_) + simp + +theorem finrank_quotient_sup_span_singleton {W : Submodule K V} {v : V} (hv : v ∉ W) : + finrank K (V ⧸ (W ⊔ K ∙ v)) + 1 = finrank K (V ⧸ W) := by + have h1 := finrank_quotient_add_finrank (W ⊔ K ∙ v) + have h2 := finrank_quotient_add_finrank W + rw [finrank_sup_span_singleton hv] at h1 + omega + +theorem sup_span_singleton_lt_top {W : Submodule K V} (v : V) + (hW : 1 < finrank K (V ⧸ W)) : W ⊔ K ∙ v < ⊤ := by + rw [lt_top_iff_ne_top] + intro htop + have h1 := finrank_quotient_add_finrank W + have h2 : finrank K ↥(W ⊔ K ∙ v) ≤ finrank K W + 1 := by + refine le_trans (Submodule.finrank_add_le_finrank_add_finrank _ _) ?_ + simp only [add_le_add_iff_left] + exact le_trans (finrank_span_le_card {v}) (by simp) + rw [htop, finrank_top] at h2 + omega + +variable {e} in +private theorem finrank_mod_auxTransvection_mul_fixed {f : Dual K V} {u : V} + {hf : e.fixedSubmodule ⊔ K ∙ (e u - u) ≤ LinearMap.ker f} + (hfu : f u = 1) (hu : u ∉ e.fixedSubmodule) : + finrank K (V ⧸ (auxTransvection hf * e).fixedSubmodule) + 1 = finrank K (V ⧸ e.fixedSubmodule) + := by + rw [auxTransvection_mul_fixed hfu] + exact finrank_quotient_sup_span_singleton hu + +/-- If `e : V ≃ₗ[K] V` is such that `e.fixedReduce = 1`, then `e` is the product of +at most `finrank K (V ⧸ e.fixedSubmodule) - 1` transvections and one dilatransvection. + +This is the first non-exceptional case in Dieudonné's theorem. -/ +theorem mem_transvections_pow_mul_dilatransvections_of_fixedReduce_eq_one + {e : V ≃ₗ[K] V} (he : e.fixedReduce = 1) : + e ∈ transvections K V ^ (finrank K (V ⧸ e.fixedSubmodule) - 1) * dilatransvections K V := by + induction h : finrank K (V ⧸ e.fixedSubmodule) generalizing e he with + | zero => simp [mem_dilatransvections_iff_finrank_quotient, h] + | succ n hind => + match n with + | 0 => simp [mem_dilatransvections_iff_finrank_quotient, h] + | n + 1 => + simp only [add_assoc, Nat.reduceAdd] at h + simp only [add_tsub_cancel_right] at hind + simp only [add_tsub_cancel_right, pow_succ', mul_assoc, Set.mem_mul] + /- We construct a linear form `f` which vanishes on `e.fixedSubmodule`, + and a vector `v` such that `f v = 1`. + Consider the transvection `t = transvection f v`. + Then `t * e` satisfies the induction hypothesis and + the relation `e = t⁻¹ * (t * e)` implies that `e` satisfies the theorem. + This transvection is given by `auxTransvection`. -/ + have : ∃ f : Dual K V, ∃ v : V, e.fixedSubmodule ≤ ker f ∧ f v = 1 := by + have : ∃ u : V, u ∉ e.fixedSubmodule := by + by_contra! he + rw [← Submodule.eq_top_iff'] at he + rw [he, ← Nat.add_left_inj, Submodule.finrank_quotient_add_finrank, finrank_top] at h + simp at h + obtain ⟨u, hu⟩ := this + obtain ⟨f, hfu, hf⟩ := Submodule.exists_dual_map_eq_bot_of_notMem hu inferInstance + let v := (f u)⁻¹ • u + have hv : f v = 1 := by simp [v, inv_mul_cancel₀ hfu] + exact ⟨f, v, by rwa [LinearMap.le_ker_iff_map], hv⟩ + obtain ⟨f, v, hf, hv⟩ := this + -- We have chosen `f` and `v`. + -- Since `f v = 1`, one has `v ∉ e.fixedSubmodule`. + have hv_notMem : v ∉ e.fixedSubmodule := fun hv' ↦ by + apply one_ne_zero' K + rw [← hv, ← LinearMap.mem_ker] + exact hf hv' + -- Using that `e.fixedReduce = 1`, we have `v - e v ∈ e.fixedSubmodule`. + have hv' : v - e v ∈ e.fixedSubmodule := by + rw [← e.fixedSubmodule.ker_mkQ, LinearMap.mem_ker, + map_sub, sub_eq_zero] + simp [← fixedReduce_mk, he] + set t := auxTransvection (e := e) (f := f) (u := v) (by + simpa [hf] using hf (sub_mem_comm_iff.mp hv')) with ht + refine ⟨t⁻¹, ?_, t * e, ?_, by simp⟩ + · -- We prove that `t⁻¹` is a transvection + rw [inv_mem_transvections_iff, ht] + apply mem_transvections + -- It remains to prove that `t * e` satisfies the induction hypothesis + apply hind + · -- We prove that `(t * e).fixedReduce = 1`. + simp only [ht, one_eq_refl, fixedReduce_eq_one, auxTransvection_mul_fixed hv] at he ⊢ + intro w + simp only [auxTransvection, LinearEquiv.mul_apply, transvection.apply, + add_sub_right_comm] + apply mem_sup_left + apply Submodule.add_mem _ (he w) + exact smul_mem _ _ hv' + · -- `finrank` condition + rw [← Nat.add_left_inj, finrank_mod_auxTransvection_mul_fixed hv hv_notMem, h] + +/- Private lemmas for the second non-exceptional case. -/ + +omit [Module.Finite K V] in +variable {e} in +/-- If the images of `u` and `e u` in `V ⧸ e.fixedSubmodule` are linearly independent, +then `e u` does not belong to `e.fixedSubmodule ⊔ K ∙ (e u - u)`. -/ +private theorem apply_notMem_sup_of_linearIndependent {u : V} + (hu : LinearIndependent K + ![e.fixedSubmodule.mkQ u, e.fixedReduce (e.fixedSubmodule.mkQ u)]) : + e u ∉ e.fixedSubmodule ⊔ K ∙ (e u - u) := fun hu' ↦ by + rw [Submodule.mem_sup] at hu' + obtain ⟨y, hy, z, hz, hu'⟩ := hu' + rw [Submodule.mem_span_singleton] at hz + obtain ⟨a, rfl⟩ := hz + simp only [LinearIndependent.pair_iff] at hu + specialize hu a (1 - a) ?_ + · simp only [← LinearMap.map_smul, ← LinearEquiv.map_smul] + simp only [Submodule.mkQ_apply, fixedReduce_mk] + simp only [← Submodule.mkQ_apply, ← map_add, ← mem_ker, + Submodule.ker_mkQ] + convert hy + grind [smul_sub, sub_smul, one_smul, map_smul] + aesop + +omit [Module.Finite K V] in +variable {e} in +/-- If `e.fixedReduce` is not a homothety, then there are a linear form `f` and +a vector `v` such that `f` vanishes on `e.fixedSubmodule ⊔ K ∙ (e v - v)`, `f v = 1`, +and the images of `v` and `e v` in `V ⧸ e.fixedSubmodule` are linearly independent. -/ +private theorem exists_dual_of_fixedReduce_ne_smul + (he : ∀ a : K, ∃ x, e.fixedReduce x ≠ a • x) + (h : 1 < finrank K (V ⧸ e.fixedSubmodule)) : + ∃ (f : Dual K V) (v : V), + LinearIndependent K ![e.fixedSubmodule.mkQ v, e.fixedReduce (e.fixedSubmodule.mkQ v)] ∧ + e.fixedSubmodule ⊔ K ∙ (e v - v) ≤ LinearMap.ker f ∧ f v = 1 := by + -- Since `e.fixedReduce` is not a homothety, there is `v : V ⧸ e.fixedSubmodule` such + -- that `v` and `e.fixedReduce v` are linearly independent. + have : ∃ v, LinearIndependent K ![v, e.fixedReduce v] := by + contrapose! he + obtain ⟨a, ha⟩ := + LinearMap.exists_mem_center_apply_eq_smul_of_forall_notLinearIndependent h.ne' he + refine ⟨a, fun x ↦ by + simp only [← coe_toLinearMap, ha, LinearMap.smul_apply, one_apply, Subring.smul_def]⟩ + obtain ⟨v, hu⟩ := this + -- We lift `v` to `u : V`. + obtain ⟨u, rfl⟩ := e.fixedSubmodule.mkQ_surjective v + -- We can take `f : Dual K V` which vanishes on `e.fixedSubmodule ⊔ K ∙ (e u - u)` + -- and satisfies `f u ≠ 0`, and we rescale `u` to `v` so that `f v = 1`. + obtain ⟨f, hfu, hf⟩ := + exists_dual_map_eq_bot_of_notMem (apply_notMem_sup_of_linearIndependent hu) inferInstance + replace hfu : f u ≠ 0 := by + contrapose hfu + rw [← hfu, ← sub_eq_zero, ← map_sub, ← Submodule.mem_bot K, ← hf] + exact mem_map_of_mem (mem_sup_right (mem_span_singleton_self _)) + set v := (f u)⁻¹ • u with v_def + have hspan : K ∙ (e v - v) = K ∙ (e u - u) := by + simp only [Submodule.span_singleton_eq_span_singleton] + use (Ne.isUnit hfu).unit + simp [v_def, _root_.map_smul, Units.smul_isUnit, smul_sub, + ← mul_smul, mul_inv_cancel₀ hfu] + rw [← hspan, ← le_ker_iff_map] at hf + refine ⟨f, v, ?_, hf, + by simp only [_root_.map_smul, smul_eq_mul, v_def, inv_mul_cancel₀ hfu]⟩ + rw [← LinearIndependent.pair_smul_smul_iff (Ne.isUnit hfu).inv (Ne.isUnit hfu).inv] at hu + simpa only [← LinearMap.map_smul, ← LinearEquiv.map_smul, ← v_def] using hu + +variable {e} in +/-- Auxiliary lemma for the second non-exceptional case in Dieudonné's theorem: +with the notation of the proof of +`mem_transvections_pow_mul_dilatransvections_of_fixedReduce_ne_smul_id`, +the reductions of `auxTransvection hf * e` and `auxTransvection hg * e` +cannot both be homotheties. -/ +private theorem not_forall_fixedReduce_eq_smul {f g : Dual K V} {v : V} {a b : K} + (hv : LinearIndependent K + ![e.fixedSubmodule.mkQ v, e.fixedReduce (e.fixedSubmodule.mkQ v)]) + {hf : e.fixedSubmodule ⊔ K ∙ (e v - v) ≤ LinearMap.ker f} (hfv : f v = 1) + {hg : e.fixedSubmodule ⊔ K ∙ (e v - v) ≤ LinearMap.ker (f + g)} (hfgv : (f + g) v = 1) + (hg0 : g ≠ 0) (hne_top : e.fixedSubmodule ⊔ K ∙ (e v - v) ⊔ K ∙ v < ⊤) + (ha : ∀ x, (auxTransvection hf * e).fixedReduce x = a • x) + (hb : ∀ x, (auxTransvection hg * e).fixedReduce x = b • x) : + False := by + simp only [fixedReduce_eq_smul_iff, auxTransvection_mul_fixed hfv] at ha + simp only [fixedReduce_eq_smul_iff, auxTransvection_mul_fixed hfgv] at hb + /- Since `auxTransvection hf = transvection f (v - e v)` and + `auxTransvection hg = transvection (f + g) (v - e v)`, + subtracting the relations `ha` and `hb` gives the following: -/ + set c := b - a with hc + have key (x : V) : g (e x) • (v - e v) - c • x ∈ e.fixedSubmodule ⊔ K ∙ v := by + have ha := ha x + have hb := hb x + simp only [LinearEquiv.mul_apply, transvection.apply, auxTransvection] at ha hb + rw [LinearMap.add_apply, add_smul, ← add_assoc] at hb + convert Submodule.sub_mem _ hb ha using 1 + -- should be taken care by a `module` tactic that handles noncommutative rings + simp only [add_comm _ (g (e x) • _), ← add_assoc] + rw [sub_eq_add_neg] + simp only [add_sub_assoc, add_assoc, add_right_inj, sub_smul, smul_sub, hc] + abel + -- To get the contradiction, we distinguish whether `a = b` or not. + rcases eq_or_ne c 0 with hc0 | hc0 + · -- When `c = 0`, we contradict the linear independence given by `hv` + apply one_ne_zero (α := K) + rw [LinearIndependent.pair_iff] at hv + have hmem : v - e v ∈ e.fixedSubmodule ⊔ K ∙ v := by + simp only [hc0, zero_smul, sub_zero] at key + obtain ⟨w, hw⟩ : ∃ w, g w ≠ 0 := by + contrapose! hg0 + exact LinearMap.ext hg0 + simpa [hw] using key ((g w)⁻¹ • e⁻¹ w) + simp only [mem_sup, mem_span_singleton, exists_exists_eq_and] at hmem + obtain ⟨y, hy, k, hk⟩ := hmem + refine (hv (k - 1) 1 ?_).right + simp only [Submodule.mkQ_apply, fixedReduce_mk] + simp only [← e.fixedSubmodule.mkQ_apply, ← LinearMap.map_smul, ← map_add, + ← LinearMap.mem_ker, Submodule.ker_mkQ] + rw [← Submodule.neg_mem_iff] at hy + convert hy using 1 + rw [eq_comm, ← sub_eq_iff_eq_add] at hk + rw [← hk] + simp only [sub_smul, one_smul] + abel + · -- When `c ≠ 0`, we contradict `hne_top` + refine hne_top.ne ?_ + rw [eq_top_iff] + intro x _ + have h1 : g (e x) • (v - e v) ∈ K ∙ (e v - v) := + mem_span_singleton.mpr ⟨-g (e x), by rw [neg_smul, smul_sub, smul_sub, neg_sub]⟩ + have hle : e.fixedSubmodule ⊔ K ∙ v ≤ e.fixedSubmodule ⊔ K ∙ (e v - v) ⊔ K ∙ v := + sup_le_sup_right le_sup_left _ + have h2 : c • x ∈ e.fixedSubmodule ⊔ K ∙ (e v - v) ⊔ K ∙ v := by + rw [show c • x = g (e x) • (v - e v) - (g (e x) • (v - e v) - c • x) by abel] + exact Submodule.sub_mem _ (mem_sup_left (mem_sup_right h1)) (hle (key x)) + simpa [smul_smul, inv_mul_cancel₀ hc0] using Submodule.smul_mem _ c⁻¹ h2 + +/-- If an element `e : V ≃ₗ[K] V` is such that `e.fixedReduce` +is not a homothety, then `e` is the product of at +most `finrank K (V ⧸ e.fixedSubmodule) - 1` transvections +and one dilatransvection. + +This is the second non-exceptional case in Dieudonné's theorem. -/ +theorem mem_transvections_pow_mul_dilatransvections_of_fixedReduce_ne_smul_id + {e : V ≃ₗ[K] V} + (he : ∀ a : K, ∃ x, e.fixedReduce x ≠ a • x) : + e ∈ transvections K V ^ (finrank K (V ⧸ e.fixedSubmodule) - 1) * dilatransvections K V := by + induction h : finrank K (V ⧸ e.fixedSubmodule) generalizing e he with + | zero => simp [mem_dilatransvections_iff_finrank_quotient, h] + | succ n hind => + match n with + | 0 => simp [mem_dilatransvections_iff_finrank_quotient, h] + | n + 1 => + simp only [ne_eq, add_tsub_cancel_right] at hind ⊢ + simp only [add_assoc, Nat.reduceAdd] at h + rw [pow_succ', mul_assoc, Set.mem_mul] + /- The strategy is similar to the first non-exceptional case: + we construct `f : Dual K V` and `v : V` such that, + setting `t = auxTransvection hf`, we have `e = t⁻¹ * (t * e)` + and `t * e` satisfies the induction hypothesis, + after possibly replacing `f` by `f + g` for a suitable `g`. -/ + obtain ⟨f, v, hv, hf, hfv⟩ := exists_dual_of_fixedReduce_ne_smul he (by omega) + have hv_notMem : v ∉ e.fixedSubmodule := by + simpa [Submodule.Quotient.mk_eq_zero] using hv.ne_zero 0 + have hrank : finrank K (V ⧸ (e.fixedSubmodule ⊔ K ∙ v)) = n + 1 := by + have := finrank_quotient_sup_span_singleton hv_notMem + omega + -- The case `n = 0` is easy + rcases Nat.eq_zero_or_pos n with hn0 | hn_pos + · simp only [hn0, pow_zero, one_mul] + refine ⟨(auxTransvection hf)⁻¹, ?_, auxTransvection hf * e, ?_, by simp⟩ + · rw [inv_mem_transvections_iff] + apply mem_transvections + · rw [mem_dilatransvections_iff_finrank_quotient, + auxTransvection_mul_fixed hfv, hrank, hn0, zero_add] + by_cases he' : auxTransvection hf * e ∈ transvections K V ^ n * dilatransvections K V + · -- This is the easy case where one knows that `auxTransvection hf * e` is + -- the product of at most `n + 1` transvections + refine ⟨(auxTransvection hf)⁻¹, ?_, auxTransvection hf * e, he', by simp⟩ + rw [inv_mem_transvections_iff] + apply mem_transvections + -- Otherwise, we will need to modify `auxTransvection hf` by changing `f`. + have hne_top : e.fixedSubmodule ⊔ K ∙ (e v - v) ⊔ K ∙ v < ⊤ := by + rw [sup_right_comm] + exact sup_span_singleton_lt_top _ (by rw [hrank]; omega) + obtain ⟨g : Dual K V, hg0 : g ≠ 0, hg2⟩ := + Submodule.exists_dual_map_eq_bot_of_lt_top hne_top inferInstance + rw [← le_ker_iff_map] at hg2 + have hg : e.fixedSubmodule ⊔ K ∙ (e v - v) ≤ ker (f + g) := fun x hx ↦ by + rw [mem_ker, LinearMap.add_apply, mem_ker.mp (hf hx), + mem_ker.mp (hg2 (mem_sup_left hx)), add_zero] + have hfgv : (f + g) v = 1 := by + rw [LinearMap.add_apply, hfv, + mem_ker.mp (hg2 (mem_sup_right (mem_span_singleton_self v))), add_zero] + refine ⟨(auxTransvection hg)⁻¹, ?_, auxTransvection hg * e, ?_, by simp⟩ + · rw [inv_mem_transvections_iff] + apply mem_transvections + -- It remains to prove that `auxTransvection hg * e` satisfies the induction hypothesis + apply hind ?_ (by rw [auxTransvection_mul_fixed hfgv, hrank]) + -- The induction hypothesis implies that `(auxTransvection hf * e).fixedReduce` + -- is a homothety, for otherwise the previous case would apply. + obtain ⟨a, ha⟩ : ∃ a : K, ∀ x, (auxTransvection hf * e).fixedReduce x = a • x := by + contrapose! he' + exact hind he' (by rw [auxTransvection_mul_fixed hfv, hrank]) + -- Then `(auxTransvection hg * e).fixedReduce` cannot also be a homothety. + intro b + by_contra! hb + exact not_forall_fixedReduce_eq_smul hv hfv hfgv hg0 hne_top ha hb + +/-- If an element `e : V ≃ₗ[K] V` is not exceptional, +then it is the product of at most `finrank K (V ⧸ e.fixedSubmodule)` dilatransvections. + +This is the non-exceptional case in Dieudonné's theorem. -/ +theorem mem_transvections_pow_mul_dilatransvections_of_not_isExceptional + {e : V ≃ₗ[K] V} (he : ¬ IsExceptional e) : + e ∈ transvections K V ^ (finrank K (V ⧸ e.fixedSubmodule) - 1) * dilatransvections K V := by + simp only [not_and_or] at he + push Not at he + rcases he with he | he | he + · simpa [Nat.sub_eq_zero_of_le he, mem_dilatransvections_iff_finrank_quotient] using he + · exact mem_transvections_pow_mul_dilatransvections_of_fixedReduce_eq_one he + · exact mem_transvections_pow_mul_dilatransvections_of_fixedReduce_ne_smul_id he + +end LinearEquiv + +end diff --git a/docs/references.bib b/docs/references.bib index e77de3dee27a70..5a22b39d8fdf62 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -1685,6 +1685,20 @@ @Book{ DiestelUhl1977 zbl = {0369.46039} } +@Article{ dieudonne-1955, + title = {Sur les g\'en\'erateurs des groupes classiques}, + author = {Dieudonn{\'e}, Jean}, + year = 1955, + journal = {Summa Brasil. Math.}, + volume = {3}, + pages = {149--178}, + issn = {0039-498X}, + fjournal = {Summa Brasiliensis Mathematicae}, + langid = {french}, + zbmath = {3113534}, + zmnumber = {0067.01201} +} + @Article{ dieudonne1953, author = {Dieudonn\'{e}, Jean}, title = {On semi-simple {L}ie algebras}, From 462dde945bf18c2ae494fc5e012d24260e32a897 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 15 Jul 2026 01:00:25 +0000 Subject: [PATCH 0792/1300] chore(RingTheory/IntegralClosure/Algebra/Basic): generalize `isIntegral_natCast` and `isIntegral_intCast` (#41746) This PR generalizes `isIntegral_natCast` and `isIntegral_intCast` to be over an arbitrary base ring. I also renamed the `IsAlgebraic` lemmas to match. Co-authored-by: tb65536 --- Mathlib/Algebra/AlgebraicCard.lean | 2 +- Mathlib/RingTheory/Algebraic/Basic.lean | 12 ++++++++---- .../RingTheory/IntegralClosure/Algebra/Basic.lean | 7 ++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/AlgebraicCard.lean b/Mathlib/Algebra/AlgebraicCard.lean index d5ef0674d10f08..483252278724f1 100644 --- a/Mathlib/Algebra/AlgebraicCard.lean +++ b/Mathlib/Algebra/AlgebraicCard.lean @@ -32,7 +32,7 @@ namespace Algebraic theorem infinite_of_charZero (R A : Type*) [CommRing R] [Ring A] [Algebra R A] [CharZero A] : { x : A | IsAlgebraic R x }.Infinite := by let := MulActionWithZero.nontrivial R A - exact infinite_of_injective_forall_mem Nat.cast_injective isAlgebraic_nat + exact infinite_of_injective_forall_mem Nat.cast_injective isAlgebraic_natCast theorem aleph0_le_cardinalMk_of_charZero (R A : Type*) [CommRing R] [Ring A] [Algebra R A] [CharZero A] : ℵ₀ ≤ #{ x : A // IsAlgebraic R x } := diff --git a/Mathlib/RingTheory/Algebraic/Basic.lean b/Mathlib/RingTheory/Algebraic/Basic.lean index b6da8df8b8c5c3..4125d527302c78 100644 --- a/Mathlib/RingTheory/Algebraic/Basic.lean +++ b/Mathlib/RingTheory/Algebraic/Basic.lean @@ -142,19 +142,23 @@ theorem isAlgebraic_one [Nontrivial R] : IsAlgebraic R (1 : A) := by rw [← map_one (algebraMap R A)] exact isAlgebraic_algebraMap 1 -theorem isAlgebraic_nat [Nontrivial R] (n : ℕ) : IsAlgebraic R (n : A) := by +theorem isAlgebraic_natCast [Nontrivial R] (n : ℕ) : IsAlgebraic R (n : A) := by rw [← map_natCast (_ : R →+* A) n] exact isAlgebraic_algebraMap (Nat.cast n) -theorem isAlgebraic_int [Nontrivial R] (n : ℤ) : IsAlgebraic R (n : A) := by +theorem isAlgebraic_intCast [Nontrivial R] (n : ℤ) : IsAlgebraic R (n : A) := by rw [← map_intCast (algebraMap R A)] exact isAlgebraic_algebraMap (Int.cast n) -theorem isAlgebraic_rat (R : Type u) {A : Type v} [DivisionRing A] [Field R] [Algebra R A] (n : ℚ) : - IsAlgebraic R (n : A) := by +theorem isAlgebraic_ratCast (R : Type u) {A : Type v} [DivisionRing A] [Field R] [Algebra R A] + (n : ℚ) : IsAlgebraic R (n : A) := by rw [← map_ratCast (algebraMap R A)] exact isAlgebraic_algebraMap (Rat.cast n) +@[deprecated (since := "2026-07-14")] alias isAlgebraic_nat := isAlgebraic_natCast +@[deprecated (since := "2026-07-14")] alias isAlgebraic_int := isAlgebraic_intCast +@[deprecated (since := "2026-07-14")] alias isAlgebraic_rat := isAlgebraic_ratCast + theorem isAlgebraic_of_mem_rootSet {R : Type u} {A : Type v} [CommRing R] [Field A] [Algebra R A] {p : R[X]} {x : A} (hx : x ∈ p.rootSet A) : IsAlgebraic R x := ⟨p, ne_zero_of_mem_rootSet hx, aeval_eq_zero_of_mem_rootSet hx⟩ diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean index 0ec0236f41a634..18d7ea9e81a655 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean @@ -202,10 +202,11 @@ theorem IsIntegral.smul {R} [CommSemiring R] [Algebra R B] [Algebra S B] [Algebr .of_mem_of_fg _ hx.fg_adjoin_singleton _ <| by rw [← algebraMap_smul S]; apply Subalgebra.smul_mem; exact Algebra.subset_adjoin rfl -theorem isIntegral_intCast (a : ℤ) : IsIntegral ℤ (a : B) := - isIntegral_algebraMap +theorem isIntegral_intCast (n : ℤ) : IsIntegral R (n : B) := by + rw [← map_intCast (_ : R →+* B) n] + exact isIntegral_algebraMap -theorem isIntegral_natCast (a : ℕ) : IsIntegral ℤ (a : B) := by +theorem isIntegral_natCast (a : ℕ) : IsIntegral R (a : B) := by rw [← Int.cast_natCast] exact isIntegral_intCast a From 11d11a11a667a8fa8ea19d9456fe059f683e308f Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 15 Jul 2026 01:20:11 +0000 Subject: [PATCH 0793/1300] chore(NumberTheory/NumberField/InfinitePlace/Basic): add abbrev of `LiesOver` for `InfinitePlace` (#41747) This PR adds an abbrev of `LiesOver` for `InfinitePlace`. Co-authored-by: tb65536 --- .../NumberField/Completion/InfinitePlace.lean | 2 +- .../Completion/LiesOverInstances.lean | 2 +- .../NumberField/Completion/Ramification.lean | 16 ++++++++-------- .../NumberField/InfinitePlace/Basic.lean | 6 ++++++ .../NumberField/InfinitePlace/Ramification.lean | 8 ++++---- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean index c1298e0915b3cb..57b3270d3338e0 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/InfinitePlace.lean @@ -397,7 +397,7 @@ namespace LiesOver open Completion -variable [w.1.LiesOver v.1] +variable [w.LiesOver v] theorem isometry_algebraMap : Isometry (algebraMap (WithAbs v.1) (WithAbs w.1)) := AddMonoidHomClass.isometry_of_norm _ fun x ↦ by diff --git a/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean b/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean index 61bd2a56112998..9fc74578f6c1dd 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/LiesOverInstances.lean @@ -24,7 +24,7 @@ namespace NumberField.LiesOver open InfinitePlace InfinitePlace.Completion variable {K L : Type*} [Field K] [Field L] [Algebra K L] {v : InfinitePlace K} {w : InfinitePlace L} -variable [w.1.LiesOver v.1] +variable [w.LiesOver v] /-- The ring homomorphism `v.Completion →+* w.Completion` induced by `algebraMap K L`, when `w` lies over `v`. -/ diff --git a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean index 7a7a1aa8817508..823bf60b254f91 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean @@ -37,7 +37,7 @@ namespace NumberField.InfinitePlace open NumberField.ComplexEmbedding Finset AbsoluteValue.Completion --- to enable `w.1.LiesOver v.1 → Algebra v.Completion w.Completion` instance +-- to enable `w.LiesOver v → Algebra v.Completion w.Completion` instance open scoped NumberField.LiesOver variable {K L : Type*} [Field K] [Field L] [Algebra K L] (v : InfinitePlace K) {w : InfinitePlace L} @@ -45,7 +45,7 @@ variable {K L : Type*} [Field K] [Field L] [Algebra K L] (v : InfinitePlace K) { open Completion /-- If `w` is a ramified place over `v` then `w.Completion` has `v.Completion` dimension two. -/ -theorem IsRamified.finrank_eq_two [w.1.LiesOver v.1] (h : w.IsRamified K) : +theorem IsRamified.finrank_eq_two [w.LiesOver v] (h : w.IsRamified K) : Module.finrank v.Completion w.Completion = 2 := by have H := NumberField.InfinitePlace.isRamified_iff.mp h rw [NumberField.InfinitePlace.LiesOver.comap_eq w v] at H @@ -55,7 +55,7 @@ theorem IsRamified.finrank_eq_two [w.1.LiesOver v.1] (h : w.IsRamified K) : Complex.finrank_real_complex] /-- If `w` is an unramified place over `v` then `w.Completion` has `v.Completion` dimension one. -/ -theorem IsUnramified.finrank_eq_one [w.1.LiesOver v.1] (h : w.IsUnramified K) : +theorem IsUnramified.finrank_eq_one [w.LiesOver v] (h : w.IsUnramified K) : Module.finrank v.Completion w.Completion = 1 := by rcases v.isReal_or_isComplex with (hv | hv) · have := LiesOver.extensionEmbedding_liesOver_of_isReal w hv @@ -84,9 +84,9 @@ theorem IsUnramified.finrank_eq_one [w.1.LiesOver v.1] (h : w.IsUnramified K) : IsUnramified.finrank_eq_one variable (w) in -theorem mult_mul_finrank [w.1.LiesOver v.1] : +theorem mult_mul_finrank [w.LiesOver v] : v.mult * Module.finrank v.Completion w.Completion = w.mult := by - have hv : v = w.comap (algebraMap K L) := Subtype.ext ‹w.1.LiesOver v.1›.comp_eq.symm + have hv : v = w.comap (algebraMap K L) := Subtype.ext ‹w.LiesOver v›.comp_eq.symm rcases w.isUnramified_or_isRamified K with h | h · rw [h.finrank_eq_one v, hv, h.eq, mul_one] · rw [h.finrank_eq_two v, hv, h.isReal.mult_eq_one, h.isComplex.mult_eq_two, one_mul] @@ -98,13 +98,13 @@ variable (w) open scoped Classical in /-- The inertia degree of `w` over `v`. -/ protected noncomputable def inertiaDeg : ℕ := - if _ : w.1.LiesOver v.1 then (⊥ : Ideal w.Completion).inertiaDeg v.Completion else 0 + if _ : w.LiesOver v then (⊥ : Ideal w.Completion).inertiaDeg v.Completion else 0 -theorem inertiaDeg_of_liesOver [w.1.LiesOver v.1] : +theorem inertiaDeg_of_liesOver [w.LiesOver v] : v.inertiaDeg w = (⊥ : Ideal w.Completion).inertiaDeg v.Completion := by simp only [InfinitePlace.inertiaDeg, dif_pos] -theorem inertiaDeg_eq_finrank [w.1.LiesOver v.1] : +theorem inertiaDeg_eq_finrank [w.LiesOver v] : v.inertiaDeg w = Module.finrank v.Completion w.Completion := by rw [inertiaDeg_of_liesOver, Ideal.inertiaDeg_eq_of_isMaximal ⊥] exact Algebra.finrank_eq_of_equiv_equiv (RingEquiv.quotientBot v.Completion) diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index c4b3e62bd0113d..1f0acba649f289 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -175,6 +175,12 @@ theorem mk_eq_iff {φ ψ : K →+* ℂ} : mk φ = mk ψ ↔ φ = ψ ∨ ComplexE · rw [← mk_conjugate_eq] exact congr_arg mk h +/-- An infinite place `w` of `L / K` lies over the infinite place `v` of `K` if `v` is the +restriction of `w` to `K`. -/ +protected abbrev LiesOver {L : Type*} [Field L] [Algebra K L] + (w : InfinitePlace L) (v : InfinitePlace K) := + w.val.LiesOver v.val + /-- An infinite place is real if it is defined by a real embedding. -/ def IsReal (w : InfinitePlace K) : Prop := ∃ φ : K →+* ℂ, ComplexEmbedding.IsReal φ ∧ mk φ = w diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean index dba874d28ca7c8..936b67e35b06e9 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean @@ -596,7 +596,7 @@ variable {K L : Type*} [Field K] [Field L] [Algebra K L] section LiesOver -variable (w : InfinitePlace L) (v : InfinitePlace K) [w.1.LiesOver v.1] +variable (w : InfinitePlace L) (v : InfinitePlace K) [w.LiesOver v] namespace LiesOver @@ -651,13 +651,13 @@ section placesOver variable (v : InfinitePlace K) (L) /-- The set of infinite places of `L` that lie above a given infinite place of `K`. -/ -def placesOver : Set (InfinitePlace L) := { w | w.1.LiesOver v.1 } +def placesOver : Set (InfinitePlace L) := { w | w.LiesOver v } /-- The set of infinite places of `L` that are unramified over a given infinite place of `K`. -/ -def unramifiedPlacesOver : Set (InfinitePlace L) := { w | w.1.LiesOver v.1 ∧ w.IsUnramified K } +def unramifiedPlacesOver : Set (InfinitePlace L) := { w | w.LiesOver v ∧ w.IsUnramified K } /-- The set of infinite places of `L` that are ramified over a given infinite place of `K`. -/ -def ramifiedPlacesOver : Set (InfinitePlace L) := { w | w.1.LiesOver v.1 ∧ w.IsRamified K } +def ramifiedPlacesOver : Set (InfinitePlace L) := { w | w.LiesOver v ∧ w.IsRamified K } variable {L} {v} {w : InfinitePlace L} From faad2e989a8f8d7350faddbd9bdbf2f8e7939e7f Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Wed, 15 Jul 2026 08:54:52 +0000 Subject: [PATCH 0794/1300] perf: speedup kernel typechecking of `PadicInt.coe_adicCompletionIntegersEquiv_symm_apply` (#41700) Speed up kernel typechecking of `PadicInt.coe_adicCompletionIntegersEquiv_symm_apply` by using `simp -implicitDefEqProofs`. See [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/kernelbarfing.20in.20mathlib/near/609873490). --- Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean index ecb2fe4fb4f2a0..a79a385487f13c 100644 --- a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean +++ b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean @@ -267,7 +267,7 @@ commutes. -/ theorem coe_adicCompletionIntegersEquiv_symm_apply (p : Nat.Primes) (x : (primesEquiv.symm p).adicCompletionIntegers ℚ) : (adicCompletionIntegersEquiv R p).symm x = (adicCompletionEquiv R p).symm x := by - simp only [adicCompletionIntegersEquiv, ContinuousAlgEquiv.symm_trans_apply, + simp -implicitDefEqProofs only [adicCompletionIntegersEquiv, ContinuousAlgEquiv.symm_trans_apply, ContinuousAlgEquiv.symm_symm, adicCompletionEquiv, Equiv.cast_apply, eq_cast_iff_heq, ← adicCompletionIntegers.coe_padicIntEquiv_apply, ContinuousAlgEquiv.cast_symm_apply] rw [← Subtype.heq_iff_coe_heq (by rw [primesEquiv.apply_symm_apply]) From e0824fdc1cf95ea19518210636c74510a36acb05 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Wed, 15 Jul 2026 09:20:31 +0000 Subject: [PATCH 0795/1300] chore(FieldTheory/KrullTopology): move lemmas to earlier file (#39759) We move some lemmas unrelated to the Krull topology out of the `KrullTopology` file. They are placed in the earlier file `FieldTheory/IsGalois/Basic` instead. --- Mathlib/FieldTheory/Galois/Basic.lean | 60 ++++++++++++++++++++++- Mathlib/FieldTheory/KrullTopology.lean | 67 -------------------------- 2 files changed, 59 insertions(+), 68 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 7c801194e20be2..51cfbf7ee8239d 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -615,7 +615,9 @@ noncomputable def restrictRestrictAlgEquivMapHom (F K L E : Type*) [Field F] [Fi Gal(E/L) →* Gal(K/F) := (AlgEquiv.restrictNormalHom K).comp (MulSemiringAction.toAlgAut Gal(E/L) F E) -variable {F E : Type*} [Field F] [Field E] [Algebra F E] (K L : IntermediateField F E) [Normal F K] +variable {F E : Type*} (E' : Type*) [Field F] [Field E] [Field E'] + [Algebra F E] [Algebra F E'] [Algebra E E'] [IsScalarTower F E E'] + (K L : IntermediateField F E) [Normal F K] @[simp] theorem restrictRestrictAlgEquivMapHom_apply (φ : Gal(E/L)) (x : K) : @@ -645,6 +647,62 @@ theorem restrictRestrictAlgEquivMapHom_surjective [FiniteDimensional F K] [Finit obtain ⟨z, rfl⟩ : y ∈ (⊥ : IntermediateField F E) := h ▸ mem_inf.mpr ⟨hx₁, hy⟩ exact mem_bot.mp ⟨z, rfl⟩ +/-- If `K / E / k` is a field extension tower with `E / k` normal, +`L` is an intermediate field of `E / k`, then the fixing subgroup of `L` viewed as an +intermediate field of `K / k` is equal to the preimage of the fixing subgroup of `L` viewed as an +intermediate field of `E / k` under the natural map `Aut(K / k) → Aut(E / k)` +(`AlgEquiv.restrictNormalHom`). -/ +theorem map_fixingSubgroup [Normal F E] : + (L.map (IsScalarTower.toAlgHom F E E')).fixingSubgroup = + L.fixingSubgroup.comap (AlgEquiv.restrictNormalHom (F := F) (K₁ := E') E) := by + ext f + simp only [Subgroup.mem_comap, mem_fixingSubgroup_iff] + constructor + · rintro h x hx + change f.restrictNormal E x = x + apply_fun _ using (algebraMap E E').injective + rw [AlgEquiv.restrictNormal_commutes] + exact h _ ⟨x, hx, rfl⟩ + · rintro h _ ⟨x, hx, rfl⟩ + replace h := congr(algebraMap E E' $(show f.restrictNormal E x = x from h x hx)) + rwa [AlgEquiv.restrictNormal_commutes] at h + +/-- If `K / E / k` is a field extension tower with `E / k` and `K / k` normal, +`L` is an intermediate field of `E / k`, then the index of the fixing subgroup of `L` viewed as an +intermediate field of `K / k` is equal to the index of the fixing subgroup of `L` viewed as an +intermediate field of `E / k`. -/ +theorem map_fixingSubgroup_index [Normal F E] [Normal F E'] : + (L.map (IsScalarTower.toAlgHom F E E')).fixingSubgroup.index = L.fixingSubgroup.index := by + rw [L.map_fixingSubgroup E', L.fixingSubgroup.index_comap_of_surjective + (AlgEquiv.restrictNormalHom_surjective _)] + +variable {K} in +/-- If `K / k` is a Galois extension, `L` is an intermediate field of `K / k`, then `[L : k]` +as a natural number is equal to the index of the fixing subgroup of `L`. -/ +theorem finrank_eq_fixingSubgroup_index (L : IntermediateField F E') [IsGalois F E'] : + Module.finrank F L = L.fixingSubgroup.index := by + wlog hnfd : FiniteDimensional F L generalizing L + · rw [Module.finrank_of_infinite_dimensional hnfd] + by_contra! h + replace h : L.fixingSubgroup.FiniteIndex := ⟨h.symm⟩ + obtain ⟨L', hfd, hL'⟩ := + exists_lt_finrank_of_infinite_dimensional hnfd L.fixingSubgroup.index + let i := (liftAlgEquiv L').toLinearEquiv + replace hfd := i.finiteDimensional + rw [i.finrank_eq, this _ hfd] at hL' + exact (Subgroup.index_antitone <| fixingSubgroup_le <| + IntermediateField.lift_le L').not_gt hL' + let E := normalClosure F L E' + have hle : L ≤ E := by simpa only [fieldRange_val] using L.val.fieldRange_le_normalClosure + let L' := restrict hle + have h := Module.finrank_mul_finrank F ↥L' ↥E + classical + rw [← IsGalois.card_fixingSubgroup_eq_finrank L', ← IsGalois.card_aut_eq_finrank F E] at h + rw [← L'.fixingSubgroup.index_mul_card, Nat.mul_left_inj Finite.card_pos.ne'] at h + rw [(restrict_algEquiv hle).toLinearEquiv.finrank_eq, h, ← L'.map_fixingSubgroup_index E'] + congr 2 + exact lift_restrict hle + end IntermediateField end restrictRestrictAlgEquivMapHom diff --git a/Mathlib/FieldTheory/KrullTopology.lean b/Mathlib/FieldTheory/KrullTopology.lean index e92eb2b63fae20..ce6489c15a827b 100644 --- a/Mathlib/FieldTheory/KrullTopology.lean +++ b/Mathlib/FieldTheory/KrullTopology.lean @@ -44,10 +44,6 @@ all intermediate fields `E` with `E/K` finite dimensional. - `stabilizer_isOpen_of_isIntegral`: For an integral field extension `L/K`, the stabilizer in `Gal(L/K)` of any element in `L` is open for the Krull topology. -- `IntermediateField.finrank_eq_fixingSubgroup_index`: given a Galois extension `K/k` and an - intermediate field `L`, the `[L : k]` as a natural number is equal to the index of the - fixing subgroup of `L`. - ## Notation - In docstrings, we will write `Gal(L/E)` to denote the fixing subgroup of an intermediate field @@ -271,66 +267,3 @@ theorem stabilizer_isOpen_of_isIntegral [Algebra.IsIntegral K L] (x : L) : simpa using (forall_mem_adjoin_smul_eq_self_iff K (S := {x}) g).symm end MulAction - -namespace IntermediateField - -variable {k E : Type*} (K : Type*) [Field k] [Field E] [Field K] - [Algebra k E] [Algebra k K] [Algebra E K] [IsScalarTower k E K] (L : IntermediateField k E) - -/-- If `K / E / k` is a field extension tower with `E / k` normal, -`L` is an intermediate field of `E / k`, then the fixing subgroup of `L` viewed as an -intermediate field of `K / k` is equal to the preimage of the fixing subgroup of `L` viewed as an -intermediate field of `E / k` under the natural map `Aut(K / k) → Aut(E / k)` -(`AlgEquiv.restrictNormalHom`). -/ -theorem map_fixingSubgroup [Normal k E] : - (L.map (IsScalarTower.toAlgHom k E K)).fixingSubgroup = - L.fixingSubgroup.comap (AlgEquiv.restrictNormalHom (F := k) (K₁ := K) E) := by - ext f - simp only [Subgroup.mem_comap, mem_fixingSubgroup_iff] - constructor - · rintro h x hx - change f.restrictNormal E x = x - apply_fun _ using (algebraMap E K).injective - rw [AlgEquiv.restrictNormal_commutes] - exact h _ ⟨x, hx, rfl⟩ - · rintro h _ ⟨x, hx, rfl⟩ - replace h := congr(algebraMap E K $(show f.restrictNormal E x = x from h x hx)) - rwa [AlgEquiv.restrictNormal_commutes] at h - -/-- If `K / E / k` is a field extension tower with `E / k` and `K / k` normal, -`L` is an intermediate field of `E / k`, then the index of the fixing subgroup of `L` viewed as an -intermediate field of `K / k` is equal to the index of the fixing subgroup of `L` viewed as an -intermediate field of `E / k`. -/ -theorem map_fixingSubgroup_index [Normal k E] [Normal k K] : - (L.map (IsScalarTower.toAlgHom k E K)).fixingSubgroup.index = L.fixingSubgroup.index := by - rw [L.map_fixingSubgroup K, L.fixingSubgroup.index_comap_of_surjective - (AlgEquiv.restrictNormalHom_surjective _)] - -variable {K} in -/-- If `K / k` is a Galois extension, `L` is an intermediate field of `K / k`, then `[L : k]` -as a natural number is equal to the index of the fixing subgroup of `L`. -/ -theorem finrank_eq_fixingSubgroup_index (L : IntermediateField k K) [IsGalois k K] : - Module.finrank k L = L.fixingSubgroup.index := by - wlog hnfd : FiniteDimensional k L generalizing L - · rw [Module.finrank_of_infinite_dimensional hnfd] - by_contra! h - replace h : L.fixingSubgroup.FiniteIndex := ⟨h.symm⟩ - obtain ⟨L', hfd, hL'⟩ := - exists_lt_finrank_of_infinite_dimensional hnfd L.fixingSubgroup.index - let i := (liftAlgEquiv L').toLinearEquiv - replace hfd := i.finiteDimensional - rw [i.finrank_eq, this _ hfd] at hL' - exact (Subgroup.index_antitone <| fixingSubgroup_le <| - IntermediateField.lift_le L').not_gt hL' - let E := normalClosure k L K - have hle : L ≤ E := by simpa only [fieldRange_val] using L.val.fieldRange_le_normalClosure - let L' := restrict hle - have h := Module.finrank_mul_finrank k ↥L' ↥E - classical - rw [← IsGalois.card_fixingSubgroup_eq_finrank L', ← IsGalois.card_aut_eq_finrank k E] at h - rw [← L'.fixingSubgroup.index_mul_card, Nat.mul_left_inj Finite.card_pos.ne'] at h - rw [(restrict_algEquiv hle).toLinearEquiv.finrank_eq, h, ← L'.map_fixingSubgroup_index K] - congr 2 - exact lift_restrict hle - -end IntermediateField From ed810a9b2a5def62c3bd2920b085e08bfb330577 Mon Sep 17 00:00:00 2001 From: Patrick Massot <14060883+PatrickMassot@users.noreply.github.com> Date: Wed, 15 Jul 2026 09:34:44 +0000 Subject: [PATCH 0796/1300] chore(LocalFrame): remove outdated sentence in module docstring (#41070) --- Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index a051a620ddc6e5..bc69c57ad82ce3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -32,9 +32,6 @@ complete field). In the planned file `Mathlib/Geometry/Manifold/VectorBundle/Ort metric. This includes bundles of finite rank, modelled on a Hilbert space or on a Banach space which has smooth partitions of unity. -We will use this to construct local extensions of a vector to a section which is smooth on the -trivialisation domain. - ## Main definitions and results * `IsLocalFrameOn`: a family of sections `s i` of `V → M` is called a **C^k local frame** on a set From 6c26a11c1caeec10c0227f19a7c0386a6f11bc69 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 15 Jul 2026 10:06:21 +0000 Subject: [PATCH 0797/1300] chore: remove redundant `decreasing_by` (#41760) This PR removes all but one redundant `decreasing_by` blocks. The last one is in [Mathlib/Data/List/PeriodicityLemma.lean](https://github.com/leanprover-community/mathlib4/pull/41760/files/e8f86fa460b54f7f6ae80d1f05ae09b987cf7cdb#diff-36680f71f6eb8dcc91c5bf81a554bb9259650ee162a1944a3ecae5608ecbe198); removing that causes signifcant slowdown. Co-authored-by: Batixx --- Mathlib/Combinatorics/Enumerative/Composition.lean | 1 - Mathlib/Data/Nat/BinaryRec.lean | 2 +- Mathlib/Data/Nat/Fib/Zeckendorf.lean | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index 831a6111194d90..3df41fcd21e06d 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -661,7 +661,6 @@ def recOnSingleAppend {motive : ∀ n, Composition n → Sort*} {n : ℕ} (c : C | (k + 1) :: l => single_append k l.sum ⟨l, fun hi ↦ blocks_pos <| mem_cons_of_mem _ hi, rfl⟩ <| recOnSingleAppend _ zero single_append - decreasing_by simp /-- Induction (recursion) principle on `c : Composition _` that corresponds to the reverse induction on the list of blocks of `c`. -/ diff --git a/Mathlib/Data/Nat/BinaryRec.lean b/Mathlib/Data/Nat/BinaryRec.lean index a98f2a1a3b1505..6d032edc007928 100644 --- a/Mathlib/Data/Nat/BinaryRec.lean +++ b/Mathlib/Data/Nat/BinaryRec.lean @@ -91,7 +91,7 @@ def binaryRec {motive : Nat → Sort u} (zero : motive 0) (bit : ∀ b n, motive else let x := bit (1 &&& n != 0) (n >>> 1) (binaryRec zero bit (n >>> 1)) congrArg motive n.bit_testBit_zero_shiftRight_one ▸ x -termination_by if n = 0 then 0 else n.log2.succ +termination_by if n = 0 then 0 else n.log2.succ -- redundant, but removing causes slowdown decreasing_by obtain _ | n := n; · exact (n0 rfl).elim obtain _ | n := n; · simp diff --git a/Mathlib/Data/Nat/Fib/Zeckendorf.lean b/Mathlib/Data/Nat/Fib/Zeckendorf.lean index 5e417a6752f26e..3389b88441a283 100644 --- a/Mathlib/Data/Nat/Fib/Zeckendorf.lean +++ b/Mathlib/Data/Nat/Fib/Zeckendorf.lean @@ -124,8 +124,6 @@ def zeckendorf : ℕ → List ℕ | m@(_ + 1) => letI a := greatestFib m a :: zeckendorf (m - fib a) -decreasing_by simp_wf; subst_vars; apply zeckendorf_aux (zero_lt_succ _) - @[simp] lemma zeckendorf_zero : zeckendorf 0 = [] := zeckendorf.eq_1 .. From 86a97b0db12a5a2928157f561cf5bcd1e6ed3b96 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 15 Jul 2026 11:24:07 +0000 Subject: [PATCH 0798/1300] chore: remove all unneeded `classical` (#41532) This PR removes (hopefully) all occurences of `classical` where it is not needed. 481 out of 3132, about ~15% (much more than I had expected) Excludes MathlibTest. Co-authored-by: Batixx --- Archive/Examples/Kuratowski.lean | 2 +- Archive/Kuratowski.lean | 1 - Archive/Sensitivity.lean | 1 - .../AscendingDescendingSequences.lean | 1 - Archive/Wiedijk100Theorems/BallotProblem.lean | 1 - Archive/Wiedijk100Theorems/CubingACube.lean | 1 - .../Algebra/Subalgebra/Centralizer.lean | 1 - Mathlib/Algebra/BigOperators/Expect.lean | 1 - Mathlib/Algebra/BigOperators/Finprod.lean | 2 +- .../Algebra/BigOperators/Finsupp/Basic.lean | 8 +- .../BigOperators/Group/Finset/Basic.lean | 5 +- .../Category/Ring/FilteredColimits.lean | 1 - Mathlib/Algebra/Colimit/TensorProduct.lean | 1 - Mathlib/Algebra/DirectSum/Basic.lean | 4 +- Mathlib/Algebra/DirectSum/Module.lean | 4 +- Mathlib/Algebra/GCDMonoid/Basic.lean | 1 - Mathlib/Algebra/Group/AddChar.lean | 1 - Mathlib/Algebra/Group/Finsupp.lean | 2 - Mathlib/Algebra/GroupWithZero/Indicator.lean | 2 +- .../Algebra/Homology/HomologicalComplex.lean | 18 ++- Mathlib/Algebra/Homology/QuasiIso.lean | 1 - Mathlib/Algebra/Lie/CartanExists.lean | 1 - Mathlib/Algebra/Lie/Submodule.lean | 1 - Mathlib/Algebra/Module/DedekindDomain.lean | 1 - .../Algebra/Module/FinitePresentation.lean | 3 - .../Algebra/Module/LinearMap/Polynomial.lean | 1 - Mathlib/Algebra/Module/PID.lean | 2 - Mathlib/Algebra/Module/Submodule/Finsupp.lean | 1 - Mathlib/Algebra/Module/Submodule/Map.lean | 4 +- Mathlib/Algebra/Module/ZLattice/Basic.lean | 7 +- Mathlib/Algebra/Module/ZLattice/Covolume.lean | 3 - Mathlib/Algebra/Module/ZLattice/Summable.lean | 1 - Mathlib/Algebra/MonoidAlgebra/Basic.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Degree.lean | 1 - .../Algebra/MonoidAlgebra/ToDirectSum.lean | 2 +- Mathlib/Algebra/MvPolynomial/Basic.lean | 5 +- Mathlib/Algebra/MvPolynomial/Degrees.lean | 14 +- Mathlib/Algebra/MvPolynomial/Division.lean | 1 - Mathlib/Algebra/MvPolynomial/Nilpotent.lean | 2 +- Mathlib/Algebra/Order/Archimedean/Basic.lean | 3 +- Mathlib/Algebra/Order/Chebyshev.lean | 1 - Mathlib/Algebra/Polynomial/Basic.lean | 2 - Mathlib/Algebra/Polynomial/Degree/Domain.lean | 1 - .../Algebra/Polynomial/Degree/Operations.lean | 1 - Mathlib/Algebra/Polynomial/Div.lean | 4 - Mathlib/Algebra/Polynomial/FieldDivision.lean | 2 - Mathlib/Algebra/Polynomial/Roots.lean | 1 - Mathlib/Algebra/Polynomial/Splits.lean | 1 - Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean | 1 - Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean | 1 - Mathlib/AlgebraicGeometry/AffineScheme.lean | 1 - .../AffineTransitionLimit.lean | 3 - Mathlib/AlgebraicGeometry/Morphisms/Flat.lean | 2 - .../Morphisms/QuasiCompact.lean | 1 - .../ProjectiveSpectrum/Basic.lean | 1 - Mathlib/Analysis/Analytic/Inverse.lean | 2 - .../Calculus/ContDiff/FaaDiBruno.lean | 1 - Mathlib/Analysis/Calculus/FDeriv/Extend.lean | 127 +++++++++--------- Mathlib/Analysis/Calculus/FDeriv/Mul.lean | 2 +- Mathlib/Analysis/Calculus/SmoothSeries.lean | 78 ++++++----- .../Complex/CanonicalDecomposition.lean | 1 - .../Analysis/Complex/LocallyUniformLimit.lean | 1 - .../Analysis/Complex/Polynomial/Basic.lean | 1 - .../ValueDistribution/LogCounting/Basic.lean | 1 - .../Convex/DoublyStochasticMatrix.lean | 1 - Mathlib/Analysis/Convex/Exposed.lean | 1 - Mathlib/Analysis/Convex/Visible.lean | 1 - .../InnerProductSpace/Orthonormal.lean | 9 +- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 5 +- .../Analysis/InnerProductSpace/Positive.lean | 1 - .../Analysis/InnerProductSpace/l2Space.lean | 36 +++-- Mathlib/Analysis/Matrix/Normed.lean | 1 - Mathlib/Analysis/Meromorphic/Divisor.lean | 2 - Mathlib/Analysis/Normed/Affine/Convex.lean | 1 - .../Analysis/Normed/Group/FunctionSeries.lean | 7 +- .../Analysis/Normed/Group/InfiniteSum.lean | 2 +- Mathlib/Analysis/Normed/Group/Tannery.lean | 2 +- Mathlib/Analysis/Normed/Lp/ProdLp.lean | 1 - Mathlib/Analysis/Normed/Lp/lpSpace.lean | 1 - .../Analysis/Normed/Module/RieszLemma.lean | 55 ++++---- Mathlib/Analysis/Real/Hyperreal.lean | 1 - .../Limits/Constructions/Filtered.lean | 2 +- .../CategoryTheory/Limits/SmallComplete.lean | 55 ++++---- .../CategoryTheory/Monoidal/Preadditive.lean | 4 - Mathlib/CategoryTheory/Preadditive/Schur.lean | 2 +- Mathlib/CategoryTheory/Simple.lean | 47 +++---- .../Additive/VerySmallDoubling.lean | 1 - Mathlib/Combinatorics/Colex.lean | 3 - Mathlib/Combinatorics/Configuration.lean | 20 ++- .../Enumerative/Composition.lean | 25 ++-- Mathlib/Combinatorics/Matroid/Map.lean | 1 - Mathlib/Combinatorics/Nullstellensatz.lean | 2 - .../Quiver/Path/Decomposition.lean | 1 - .../SetFamily/FourFunctions.lean | 1 - .../Combinatorics/SetFamily/Intersecting.lean | 16 +-- .../Combinatorics/SimpleGraph/DegreeSum.lean | 25 ++-- .../SimpleGraph/Ends/Properties.lean | 1 - .../Extremal/ErdosStoneSimonovits.lean | 2 +- .../Combinatorics/SimpleGraph/Matching.lean | 2 - Mathlib/Combinatorics/SimpleGraph/Tutte.lean | 2 - Mathlib/Computability/Halting.lean | 2 +- Mathlib/Data/Finite/Vector.lean | 1 - Mathlib/Data/Finset/Card.lean | 1 - Mathlib/Data/Finset/Piecewise.lean | 4 +- Mathlib/Data/Finsupp/Basic.lean | 2 +- Mathlib/Data/Finsupp/BigOperators.lean | 2 +- Mathlib/Data/Finsupp/Indicator.lean | 2 +- Mathlib/Data/Finsupp/Interval.lean | 2 +- Mathlib/Data/Finsupp/Order.lean | 1 - Mathlib/Data/Finsupp/Single.lean | 2 - Mathlib/Data/Finsupp/Weight.lean | 1 - Mathlib/Data/Fintype/Order.lean | 1 - Mathlib/Data/Matrix/Block.lean | 7 +- Mathlib/Data/Nat/Choose/Multinomial.lean | 1 - Mathlib/Data/PEquiv.lean | 13 +- Mathlib/Data/Set/Card/Arithmetic.lean | 1 - Mathlib/Data/Set/Constructions.lean | 15 +-- Mathlib/Data/Set/PowersetCard.lean | 1 - Mathlib/Data/Setoid/Partition.lean | 2 +- Mathlib/Data/Sign/Basic.lean | 2 +- Mathlib/Dynamics/SymbolicDynamics/Basic.lean | 1 - Mathlib/FieldTheory/AxGrothendieck.lean | 1 - Mathlib/FieldTheory/Finite/Basic.lean | 60 ++++----- Mathlib/FieldTheory/Galois/Basic.lean | 5 +- Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean | 1 - Mathlib/FieldTheory/PrimitiveElement.lean | 2 - Mathlib/FieldTheory/Separable.lean | 2 - Mathlib/FieldTheory/SeparableDegree.lean | 1 - Mathlib/FieldTheory/SeparablyGenerated.lean | 1 - .../Convex/ConvexSpace/AffineSpace.lean | 1 - Mathlib/Geometry/Convex/ConvexSpace/Defs.lean | 1 - Mathlib/Geometry/Convex/Set.lean | 1 - .../Geometry/Group/Growth/QuotientInter.lean | 1 - .../Manifold/MFDeriv/SpecificFunctions.lean | 1 - .../Geometry/Manifold/PartitionOfUnity.lean | 1 - .../Manifold/VectorBundle/LocalFrame.lean | 2 - Mathlib/GroupTheory/ArchimedeanDensely.lean | 1 - .../GroupTheory/Congruence/BigOperators.lean | 1 - Mathlib/GroupTheory/CoprodI.lean | 43 +++--- Mathlib/GroupTheory/Coset/Card.lean | 4 +- Mathlib/GroupTheory/Divisible.lean | 2 +- Mathlib/GroupTheory/Nilpotent.lean | 13 +- Mathlib/GroupTheory/NoncommPiCoprod.lean | 20 ++- Mathlib/GroupTheory/Order/Min.lean | 1 - Mathlib/GroupTheory/OrderOfElement.lean | 2 - Mathlib/GroupTheory/PGroup.lean | 17 ++- Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 32 +++-- Mathlib/GroupTheory/Perm/Cycle/Factors.lean | 17 ++- Mathlib/GroupTheory/Perm/Finite.lean | 1 - Mathlib/GroupTheory/PushoutI.lean | 3 +- Mathlib/GroupTheory/Sylow.lean | 39 +++--- Mathlib/GroupTheory/Transfer.lean | 29 ++-- Mathlib/LinearAlgebra/AffineSpace/Basis.lean | 2 +- Mathlib/LinearAlgebra/Basis/Cardinality.lean | 2 +- .../BilinearForm/Orthogonal.lean | 19 ++- Mathlib/LinearAlgebra/Determinant.lean | 1 - .../LinearAlgebra/Dimension/DivisionRing.lean | 5 +- .../LinearAlgebra/Dimension/Localization.lean | 1 - .../Dimension/StrongRankCondition.lean | 1 - .../FiniteDimensional/Lemmas.lean | 45 +++---- .../Finsupp/LinearCombination.lean | 2 +- .../LinearAlgebra/Finsupp/VectorSpace.lean | 1 - Mathlib/LinearAlgebra/Matrix/Ideal.lean | 2 - Mathlib/LinearAlgebra/Matrix/PosDef.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Rank.lean | 1 - .../Matrix/SpecialLinearGroup.lean | 1 - Mathlib/LinearAlgebra/Matrix/WithConv.lean | 2 +- Mathlib/LinearAlgebra/Pi.lean | 2 - Mathlib/LinearAlgebra/QuadraticForm/Dual.lean | 1 - .../QuadraticForm/Signature.lean | 2 - Mathlib/LinearAlgebra/RootSystem/Base.lean | 1 - .../RootSystem/GeckConstruction/Basic.lean | 1 - Mathlib/LinearAlgebra/SModEq/Basic.lean | 2 - .../LinearAlgebra/SesquilinearForm/Basic.lean | 21 ++- Mathlib/Logic/Equiv/Fintype.lean | 1 - Mathlib/Logic/Hydra.lean | 1 - Mathlib/MeasureTheory/Constructions/Pi.lean | 3 - .../Constructions/Projective.lean | 1 - Mathlib/MeasureTheory/Covering/Vitali.lean | 1 - .../Function/LpSpace/InfiniteSum.lean | 1 - .../Integral/Bochner/VitaliCaratheodory.lean | 3 - .../MeasurableSpace/CountablyGenerated.lean | 1 - .../MeasurableSpace/MeasurablyGenerated.lean | 1 - Mathlib/MeasureTheory/Measure/AddContent.lean | 7 - Mathlib/MeasureTheory/Measure/Dirac.lean | 1 - .../MeasureTheory/Measure/Haar/Unique.lean | 1 - Mathlib/MeasureTheory/Measure/Hausdorff.lean | 1 - .../MeasureTheory/Measure/Portmanteau.lean | 1 - .../Measure/RegularityCompacts.lean | 1 - .../Measure/Typeclasses/SFinite.lean | 1 - .../OuterMeasure/OfAddContent.lean | 1 - Mathlib/MeasureTheory/PiSystem.lean | 1 - Mathlib/MeasureTheory/SetSemiring.lean | 14 -- .../VectorMeasure/SetIntegral.lean | 2 - .../ModelTheory/ElementarySubstructures.lean | 1 - Mathlib/ModelTheory/Satisfiability.lean | 75 +++++------ Mathlib/ModelTheory/Semantics.lean | 1 - .../ArithmeticFunction/LFunction.lean | 1 - Mathlib/NumberTheory/Cyclotomic/Basic.lean | 1 - Mathlib/NumberTheory/FLT/Three.lean | 5 +- Mathlib/NumberTheory/Modular.lean | 1 - Mathlib/NumberTheory/MulChar/Basic.lean | 2 +- .../NumberField/CanonicalEmbedding/Basic.lean | 1 - .../CanonicalEmbedding/NormLeOne.lean | 1 - .../NumberField/Discriminant/Defs.lean | 1 - Mathlib/NumberTheory/NumberField/House.lean | 1 - .../InfinitePlace/Ramification.lean | 1 - .../NumberField/ProductFormula.lean | 1 - .../RamificationInertia/Basic.lean | 2 - .../RamificationInertia/Ramification.lean | 3 - Mathlib/Order/CompleteLattice/Finset.lean | 1 - .../ConditionallyCompleteLattice/Finset.lean | 5 +- .../Order/Filter/AtTopBot/BigOperators.lean | 9 +- Mathlib/Order/Interval/Finset/Basic.lean | 18 ++- Mathlib/Order/Interval/Set/Basic.lean | 31 +++-- Mathlib/Order/PartialSups.lean | 1 - Mathlib/Order/Preorder/Chain.lean | 2 - .../Gaussian/HasGaussianLaw/Independence.lean | 1 - .../Distributions/SetBernoulli.lean | 2 - Mathlib/Probability/Independence/Basic.lean | 1 - .../Independence/Kernel/Indep.lean | 2 - .../Independence/Kernel/IndepFun.lean | 1 - .../Kernel/Composition/CompProd.lean | 1 - .../Kernel/Disintegration/Basic.lean | 1 - .../Kernel/MeasurableIntegral.lean | 1 - Mathlib/Probability/Kernel/WithDensity.lean | 3 +- .../Probability/Martingale/Upcrossing.lean | 1 - Mathlib/Probability/Process/HittingTime.lean | 2 - Mathlib/Probability/StrongLaw.lean | 1 - .../Homological/GroupCohomology/Basic.lean | 1 - .../GroupCohomology/Hilbert90.lean | 1 - .../Homological/Resolution.lean | 2 +- Mathlib/RepresentationTheory/Rep/Basic.lean | 2 +- Mathlib/RepresentationTheory/Rep/Iso.lean | 1 - Mathlib/RingTheory/AlgebraTower.lean | 1 - Mathlib/RingTheory/Bezout.lean | 62 +++++---- .../DedekindDomain/AdicValuation.lean | 8 -- .../RingTheory/DedekindDomain/Different.lean | 3 - Mathlib/RingTheory/DedekindDomain/Dvr.lean | 1 - .../DedekindDomain/Factorization.lean | 8 +- .../DedekindDomain/Ideal/Lemmas.lean | 2 - Mathlib/RingTheory/DedekindDomain/PID.lean | 1 - .../DiscreteValuationRing/Basic.lean | 2 - Mathlib/RingTheory/Discriminant.lean | 4 +- Mathlib/RingTheory/EssentialFiniteness.lean | 1 - Mathlib/RingTheory/Etale/QuasiFinite.lean | 1 - .../RingTheory/Extension/Cotangent/Basic.lean | 1 - .../RingTheory/Extension/Cotangent/Basis.lean | 1 - .../Extension/Presentation/Basic.lean | 1 - .../Extension/Presentation/Submersive.lean | 1 - Mathlib/RingTheory/FinitePresentation.lean | 1 - Mathlib/RingTheory/Finiteness/Basic.lean | 49 ++++--- Mathlib/RingTheory/Finiteness/Cofinite.lean | 2 +- Mathlib/RingTheory/Finiteness/Descent.lean | 1 - .../Finiteness/ModuleFinitePresentation.lean | 1 - .../RingTheory/Flat/EquationalCriterion.lean | 1 - Mathlib/RingTheory/FreeCommRing.lean | 1 - Mathlib/RingTheory/HahnSeries/Addition.lean | 1 - .../Ideal/MinimalPrime/Localization.lean | 1 - Mathlib/RingTheory/Ideal/Operations.lean | 13 +- .../IntegralClosure/Algebra/Ideal.lean | 1 - Mathlib/RingTheory/Invariant/Basic.lean | 1 - Mathlib/RingTheory/Lasker.lean | 1 - Mathlib/RingTheory/LocalRing/Quotient.lean | 1 - Mathlib/RingTheory/MvPolynomial/Ideal.lean | 1 - .../MvPolynomial/MonomialOrder.lean | 1 - .../MvPolynomial/WeightedHomogeneous.lean | 1 - Mathlib/RingTheory/MvPowerSeries/Expand.lean | 1 - .../RingTheory/MvPowerSeries/PiTopology.lean | 1 - .../MvPowerSeries/Substitution.lean | 1 - Mathlib/RingTheory/MvPowerSeries/Trunc.lean | 1 - Mathlib/RingTheory/Polynomial/GaussLemma.lean | 1 - Mathlib/RingTheory/Polynomial/IsIntegral.lean | 1 - Mathlib/RingTheory/Polynomial/Nilpotent.lean | 2 +- .../Polynomial/Resultant/Basic.lean | 1 - Mathlib/RingTheory/Polynomial/Subring.lean | 1 - .../UniversalFactorizationRing.lean | 2 - Mathlib/RingTheory/PolynomialAlgebra.lean | 2 +- Mathlib/RingTheory/PolynomialLaw/Basic.lean | 2 - Mathlib/RingTheory/PowerSeries/Order.lean | 3 - Mathlib/RingTheory/QuasiFinite/Basic.lean | 1 - .../RingTheory/RingHom/StandardSmooth.lean | 1 - Mathlib/RingTheory/RingHom/Surjective.lean | 1 - Mathlib/RingTheory/RootsOfUnity/Minpoly.lean | 1 - Mathlib/RingTheory/SimpleModule/Basic.lean | 1 - .../SimpleModule/WedderburnArtin.lean | 2 +- Mathlib/RingTheory/Smooth/Fiber.lean | 1 - .../RingTheory/Smooth/IntegralClosure.lean | 1 - .../Spectrum/Prime/ChevalleyComplexity.lean | 5 - .../RingTheory/Spectrum/Prime/Polynomial.lean | 1 - Mathlib/RingTheory/Support.lean | 1 - .../TensorProduct/DirectLimitFG.lean | 3 - Mathlib/RingTheory/Trace/Quotient.lean | 1 - .../UniqueFactorizationDomain/Basic.lean | 70 +++++----- .../UniqueFactorizationDomain/FactorSet.lean | 5 +- .../UniqueFactorizationDomain/Ideal.lean | 1 - .../RingTheory/Unramified/LocalStructure.lean | 3 - Mathlib/RingTheory/Valuation/Basic.lean | 1 - .../RingTheory/Valuation/ValuationRing.lean | 2 - Mathlib/RingTheory/ZMod/UnitsCyclic.lean | 1 - Mathlib/Tactic/CancelDenoms/Core.lean | 1 - .../Topology/Algebra/InfiniteSum/Defs.lean | 2 +- .../Topology/Algebra/InfiniteSum/Group.lean | 4 +- .../Topology/Algebra/InfiniteSum/Order.lean | 2 - .../Algebra/InfiniteSum/SummationFilter.lean | 1 - .../Algebra/Valued/LocallyCompact.lean | 1 - .../Algebra/Valued/ValuationTopology.lean | 1 - Mathlib/Topology/Algebra/Valued/WithVal.lean | 1 - .../Topology/CWComplex/Classical/Finite.lean | 1 - .../Compactness/CountablyCompact.lean | 1 - Mathlib/Topology/Compactness/Paracompact.lean | 81 ++++++----- Mathlib/Topology/Connected/Clopen.lean | 1 - Mathlib/Topology/ContinuousMap/Compact.lean | 1 - Mathlib/Topology/Irreducible.lean | 2 - Mathlib/Topology/LocallyFinsupp.lean | 1 - .../Topology/MetricSpace/CoveringNumbers.lean | 1 - Mathlib/Topology/MetricSpace/Infsep.lean | 26 ++-- Mathlib/Topology/MetricSpace/PiNat.lean | 1 - .../Sheaves/SheafCondition/UniqueGluing.lean | 21 ++- 320 files changed, 728 insertions(+), 1132 deletions(-) diff --git a/Archive/Examples/Kuratowski.lean b/Archive/Examples/Kuratowski.lean index 0116884290d4bd..517a4e6bda369e 100644 --- a/Archive/Examples/Kuratowski.lean +++ b/Archive/Examples/Kuratowski.lean @@ -253,7 +253,7 @@ theorem nodup_theFourteen_fourteenSet : (theFourteen fourteenSet).Nodup := /-- The number of distinct sets obtainable from `fourteenSet` is exactly 14. -/ theorem ncard_isObtainable_fourteenSet : {t | IsObtainable fourteenSet t}.ncard = 14 := by - classical rw [← card_theFourteen fourteenSet, ← Multiset.toFinset_card_of_nodup + rw [← card_theFourteen fourteenSet, ← Multiset.toFinset_card_of_nodup nodup_theFourteen_fourteenSet, ← Set.ncard_coe_finset] congr; ext; simp [mem_theFourteen_iff_isObtainable] diff --git a/Archive/Kuratowski.lean b/Archive/Kuratowski.lean index 7f7f7d8d6b22a4..88778f406a5574 100644 --- a/Archive/Kuratowski.lean +++ b/Archive/Kuratowski.lean @@ -101,7 +101,6 @@ theorem mem_theFourteen_iff_isObtainable {s t : Set X} : /-- **Kuratowski's closure-complement theorem**: the number of obtainable sets via closure and complement operations from a single set `s` is at most 14. -/ theorem ncard_isObtainable_le_fourteen (s : Set X) : {t | IsObtainable s t}.ncard ≤ 14 := by - classical convert! Set.ncard_coe_finset _ ▸ (theFourteen s).toFinset_card_le simp [Set.ext_iff, mem_theFourteen_iff_isObtainable] diff --git a/Archive/Sensitivity.lean b/Archive/Sensitivity.lean index e16a8c042c5fba..5458e4051ac856 100644 --- a/Archive/Sensitivity.lean +++ b/Archive/Sensitivity.lean @@ -238,7 +238,6 @@ since this cardinal is finite, as a natural number in `finrank_V` -/ theorem dim_V : Module.rank ℝ (V n) = 2 ^ n := by have : Module.rank ℝ (V n) = (2 ^ n : ℕ) := by - classical rw [rank_eq_card_basis (dualBases_e_ε _).basis, Q.card] assumption_mod_cast diff --git a/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean b/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean index a51e40209af26a..73a0d7f564a645 100644 --- a/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean +++ b/Archive/Wiedijk100Theorems/AscendingDescendingSequences.lean @@ -79,7 +79,6 @@ then `maxDecSequencesTo f i < maxDecSequencesTo f j`. -/ private lemma maxIncSequencesTo_lt {i j : α} (hij : i < j) (hfij : f i < f j) : maxIncSequencesTo f i < maxIncSequencesTo f j := by - classical rw [Nat.lt_iff_add_one_le] refine le_max' _ _ ?_ have : maxIncSequencesTo f i ∈ incSequencesTo f i := max'_mem _ incSequencesTo_nonempty diff --git a/Archive/Wiedijk100Theorems/BallotProblem.lean b/Archive/Wiedijk100Theorems/BallotProblem.lean index b7fb68ef7f0ef7..3f35b7cc5b72fd 100644 --- a/Archive/Wiedijk100Theorems/BallotProblem.lean +++ b/Archive/Wiedijk100Theorems/BallotProblem.lean @@ -305,7 +305,6 @@ theorem ballot_neg (p q : ℕ) (qp : q < p) : theorem ballot_problem' : ∀ q p, q < p → (uniformOn (countedSequence p q) staysPositive).toReal = (p - q) / (p + q) := by - classical apply Nat.diag_induction · intro p rw [ballot_same] diff --git a/Archive/Wiedijk100Theorems/CubingACube.lean b/Archive/Wiedijk100Theorems/CubingACube.lean index 647fcef5884878..e9deeb72863168 100644 --- a/Archive/Wiedijk100Theorems/CubingACube.lean +++ b/Archive/Wiedijk100Theorems/CubingACube.lean @@ -451,7 +451,6 @@ theorem valley_mi : Valley cs (cs (mi h v)).shiftUp := by refine ⟨?_, ?_, ?_⟩ · intro p; apply h.shiftUp_bottom_subset_bottoms mi_xm_ne_one · rintro i' hi' ⟨p2, hp2, h2p2⟩; simp only [head_shiftUp] at hi' - classical by_contra h2i' rw [tail_shiftUp] at h2p2 simp only [not_subset, tail_shiftUp] at h2i' diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean b/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean index 85f0870d237eb7..ab00c351667e84 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Centralizer.lean @@ -69,7 +69,6 @@ lemma centralizer_coe_image_includeLeft_eq_center_tensorProduct (Algebra.TensorProduct.includeLeft (S := R) '' S) = (Algebra.TensorProduct.map (Subalgebra.centralizer R (S : Set A)).val (AlgHom.id R B)).range := by - classical ext w constructor · intro hw diff --git a/Mathlib/Algebra/BigOperators/Expect.lean b/Mathlib/Algebra/BigOperators/Expect.lean index 1c0505e075c2ad..6eb5f5d9c556cc 100644 --- a/Mathlib/Algebra/BigOperators/Expect.lean +++ b/Mathlib/Algebra/BigOperators/Expect.lean @@ -346,7 +346,6 @@ variable [CommSemiring M] [Module ℚ≥0 M] [IsScalarTower ℚ≥0 M M] [SMulCo lemma expect_pow (s : Finset ι) (f : ι → M) (n : ℕ) : (𝔼 i ∈ s, f i) ^ n = 𝔼 p ∈ Fintype.piFinset fun _ : Fin n ↦ s, ∏ i, f (p i) := by - classical rw [expect, smul_pow, sum_pow', expect, Fintype.card_piFinset_const, inv_pow, Nat.cast_pow] end CommSemiring diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index 63ce51e2fa6fe3..803c32af269d78 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -336,7 +336,7 @@ variable {α β ι G M N : Type*} [CommMonoid M] [CommMonoid N] @[to_additive] theorem finprod_eq_mulIndicator_apply (s : Set α) (f : α → M) (a : α) : ∏ᶠ _ : a ∈ s, f a = mulIndicator s f a := by - classical convert! finprod_eq_if (M := M) (p := a ∈ s) (x := f a) + convert! finprod_eq_if (M := M) (p := a ∈ s) (x := f a) @[to_additive (attr := simp)] theorem finprod_apply_ne_one (f : α → M) (a : α) : ∏ᶠ _ : f a ≠ 1, f a = f a := by diff --git a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean index 1063de3e49fe92..1369d1b6c3a9ff 100644 --- a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean @@ -169,10 +169,9 @@ then its product over `f : α →₀ M` is the same as multiplying the value on `y : α` to the sum over `erase y f`. -/] theorem mul_prod_erase' (f : α →₀ M) (y : α) (g : α → M → N) (hg : ∀ i : α, g i 0 = 1) : g y (f y) * (erase y f).prod g = f.prod g := by - classical - by_cases hyf : y ∈ f.support - · exact Finsupp.mul_prod_erase f y g hyf - · rw [notMem_support_iff.mp hyf, hg y, erase_of_notMem_support hyf, one_mul] + by_cases hyf : y ∈ f.support + · exact Finsupp.mul_prod_erase f y g hyf + · rw [notMem_support_iff.mp hyf, hg y, erase_of_notMem_support hyf, one_mul] @[to_additive] theorem _root_.SubmonoidClass.finsuppProd_mem {S : Type*} [SetLike S N] [SubmonoidClass S N] @@ -600,7 +599,6 @@ lemma prod_mul_eq_prod_mul_of_exists [Zero M] [CommMonoid N] (a : α) (ha : a ∈ f.support) (h : g a (f a) * n₁ = g a (f a) * n₂) : f.prod g * n₁ = f.prod g * n₂ := by - classical exact Finset.prod_mul_eq_prod_mul_of_exists a ha h end Finsupp diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index dc1fd7e60a6421..9746c1d87dd066 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -310,9 +310,8 @@ lemma prod_mul_prod_comm (f g h i : ι → M) : theorem prod_filter_of_ne {p : ι → Prop} [DecidablePred p] (hp : ∀ x ∈ s, f x ≠ 1 → p x) : ∏ x ∈ s with p x, f x = ∏ x ∈ s, f x := (prod_subset (filter_subset _ _)) fun x => by - classical - rw [not_imp_comm, mem_filter] - exact fun h₁ h₂ => ⟨h₁, by simpa using hp _ h₁ h₂⟩ + rw [not_imp_comm, mem_filter] + exact fun h₁ h₂ => ⟨h₁, by simpa using hp _ h₁ h₂⟩ -- If we use `[DecidableEq M]` here, some rewrites fail because they find a wrong `Decidable` -- instance first; `{∀ x, Decidable (f x ≠ 1)}` doesn't work with `rw ← prod_filter_ne_one` diff --git a/Mathlib/Algebra/Category/Ring/FilteredColimits.lean b/Mathlib/Algebra/Category/Ring/FilteredColimits.lean index 8220c8ee8ca9b2..6daebb16d0c57f 100644 --- a/Mathlib/Algebra/Category/Ring/FilteredColimits.lean +++ b/Mathlib/Algebra/Category/Ring/FilteredColimits.lean @@ -366,7 +366,6 @@ instance forget_preservesFilteredColimits : PreservesFilteredColimits (forget Co omit [IsFiltered J] in protected lemma nontrivial {F : J ⥤ CommRingCat.{v}} [IsFilteredOrEmpty J] [∀ i, Nontrivial (F.obj i)] {c : Cocone F} (hc : IsColimit c) : Nontrivial c.pt := by - classical cases isEmpty_or_nonempty J · exact ((isColimitEquivIsInitialOfIsEmpty _ _ hc).to (.of (ULift ℤ))).hom.domain_nontrivial have i := ‹Nonempty J›.some diff --git a/Mathlib/Algebra/Colimit/TensorProduct.lean b/Mathlib/Algebra/Colimit/TensorProduct.lean index 54f86fa961debf..e8568cb46daec7 100644 --- a/Mathlib/Algebra/Colimit/TensorProduct.lean +++ b/Mathlib/Algebra/Colimit/TensorProduct.lean @@ -29,7 +29,6 @@ variable [AddCommMonoid M] [Module R M] [AddCommMonoid P] [Module R P] theorem Submodule.FG.exists_rTensor_fg_inclusion_eq {N : Submodule R P} (hN : N.FG) {x y : N ⊗[R] M} (eq : N.subtype.rTensor M x = N.subtype.rTensor M y) : ∃ N', N'.FG ∧ ∃ h : N ≤ N', (N.inclusion h).rTensor M x = (N.inclusion h).rTensor M y := by - classical lift N to {N : Submodule R P // N.FG} using hN apply_fun (Module.fgSystem.equiv R P).symm.toLinearMap.rTensor M at eq apply_fun directLimitLeft _ _ at eq diff --git a/Mathlib/Algebra/DirectSum/Basic.lean b/Mathlib/Algebra/DirectSum/Basic.lean index 7bd5417d8977b6..8be68d01e62ca2 100644 --- a/Mathlib/Algebra/DirectSum/Basic.lean +++ b/Mathlib/Algebra/DirectSum/Basic.lean @@ -440,10 +440,10 @@ def map : (⨁ i, α i) →+ ⨁ i, β i := DFinsupp.mapRange.addMonoidHom f DFinsupp.mapRange.addMonoidHom_comp _ _ lemma map_injective : Function.Injective (map f) ↔ ∀ i, Function.Injective (f i) := by - classical exact DFinsupp.mapRange_injective (hf := fun _ ↦ map_zero _) + exact DFinsupp.mapRange_injective (hf := fun _ ↦ map_zero _) lemma map_surjective : Function.Surjective (map f) ↔ (∀ i, Function.Surjective (f i)) := by - classical exact DFinsupp.mapRange_surjective (hf := fun _ ↦ map_zero _) + exact DFinsupp.mapRange_surjective (hf := fun _ ↦ map_zero _) lemma map_eq_iff (x y : ⨁ i, α i) : map f x = map f y ↔ ∀ i, f i (x i) = f i (y i) := by diff --git a/Mathlib/Algebra/DirectSum/Module.lean b/Mathlib/Algebra/DirectSum/Module.lean index df9c5d5c16977c..fda8ef8ea3877d 100644 --- a/Mathlib/Algebra/DirectSum/Module.lean +++ b/Mathlib/Algebra/DirectSum/Module.lean @@ -268,10 +268,10 @@ def lmap : (⨁ i, M i) →ₗ[R] ⨁ i, N i := DFinsupp.mapRange.linearMap f DFinsupp.mapRange.linearMap_comp _ _ theorem lmap_injective : Function.Injective (lmap f) ↔ ∀ i, Function.Injective (f i) := by - classical exact DFinsupp.mapRange_injective (hf := fun _ ↦ map_zero _) + exact DFinsupp.mapRange_injective (hf := fun _ ↦ map_zero _) theorem lmap_surjective : Function.Surjective (lmap f) ↔ (∀ i, Function.Surjective (f i)) := by - classical exact DFinsupp.mapRange_surjective (hf := fun _ ↦ map_zero _) + exact DFinsupp.mapRange_surjective (hf := fun _ ↦ map_zero _) lemma lmap_eq_iff (x y : ⨁ i, M i) : lmap f x = lmap f y ↔ ∀ i, f i (x i) = f i (y i) := diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index 7b7826686220ea..e90e78493a2721 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -105,7 +105,6 @@ noncomputable abbrev NormalizationMonoid.ofRightInverse {α : Type*} [MonoidWith /-- A cancellative monoid with zero always admits a `NormalizationMonoid` structure. -/ instance (α) [MonoidWithZero α] [IsLeftCancelMulZero α] : Nonempty (NormalizationMonoid α) := .intro <| by - classical exact .ofRightInverse (fun a ↦ by classical exact if a = 1 then 1 else a.out) (fun _ ↦ by split_ifs with h <;> simp [h]) (by simp) diff --git a/Mathlib/Algebra/Group/AddChar.lean b/Mathlib/Algebra/Group/AddChar.lean index 07bc98e0d9dc22..0c9bc3c17393f1 100644 --- a/Mathlib/Algebra/Group/AddChar.lean +++ b/Mathlib/Algebra/Group/AddChar.lean @@ -338,7 +338,6 @@ lemma sum_eq_ite (ψ : AddChar A R) [Decidable (ψ = 0)] : variable [CharZero R] lemma sum_eq_zero_iff_ne_zero : ∑ x, ψ x = 0 ↔ ψ ≠ 0 := by - classical rw [sum_eq_ite, Ne.ite_eq_right_iff]; exact Nat.cast_ne_zero.2 Fintype.card_ne_zero lemma sum_ne_zero_iff_eq_zero : ∑ x, ψ x ≠ 0 ↔ ψ = 0 := sum_eq_zero_iff_ne_zero.not_left diff --git a/Mathlib/Algebra/Group/Finsupp.lean b/Mathlib/Algebra/Group/Finsupp.lean index a3ddce45119979..487b64d8a8cb8f 100644 --- a/Mathlib/Algebra/Group/Finsupp.lean +++ b/Mathlib/Algebra/Group/Finsupp.lean @@ -269,7 +269,6 @@ protected lemma induction {motive : (ι →₀ M) → Prop} (f : ι →₀ M) (z lemma induction₂ {motive : (ι →₀ M) → Prop} (f : ι →₀ M) (zero : motive 0) (add_single : ∀ (a b) (f : ι →₀ M), a ∉ f.support → b ≠ 0 → motive f → motive (f + single a b)) : motive f := by - classical refine f.induction zero ?_ convert! add_single using 7 apply (addCommute_of_disjoint _).eq @@ -315,7 +314,6 @@ The lemma `induction_on_max` swaps the argument order in the sum. -/ lemma induction_on_max₂ (f : ι →₀ M) (zero : motive 0) (add_single : ∀ a b (f : ι →₀ M), (∀ c ∈ f.support, c < a) → b ≠ 0 → motive f → motive (f + single a b)) : motive f := by - classical refine f.induction_on_max zero ?_ convert! add_single using 7 with _ _ _ H have := fun c hc ↦ (H c hc).ne diff --git a/Mathlib/Algebra/GroupWithZero/Indicator.lean b/Mathlib/Algebra/GroupWithZero/Indicator.lean index db9d0159d74aa4..7dcce0f07f7fb0 100644 --- a/Mathlib/Algebra/GroupWithZero/Indicator.lean +++ b/Mathlib/Algebra/GroupWithZero/Indicator.lean @@ -76,7 +76,7 @@ lemma indicator_prod_one {t : Set κ} {j : κ} : variable (M₀) [Nontrivial M₀] lemma indicator_eq_zero_iff_notMem : indicator s 1 i = (0 : M₀) ↔ i ∉ s := by - classical simp [indicator_apply, imp_false] + simp lemma indicator_eq_one_iff_mem : indicator s 1 i = (1 : M₀) ↔ i ∈ s := by classical simp [indicator_apply, imp_false] diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index c98ed1fc1a863a..3e08e7221b051b 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -170,11 +170,10 @@ theorem next (α : Type*) [AddGroup α] [One α] (i : α) : (ComplexShape.down @[simp] theorem next_nat_zero : (ComplexShape.down ℕ).next 0 = 0 := by - classical - refine dif_neg ?_ - push Not - intro - apply Nat.noConfusion + refine dif_neg ?_ + push Not + intro + apply Nat.noConfusion @[simp] theorem next_nat_succ (i : ℕ) : (ComplexShape.down ℕ).next (i + 1) = i := @@ -195,11 +194,10 @@ theorem next (α : Type*) [AddRightCancelSemigroup α] [One α] (i : α) : @[simp] theorem prev_nat_zero : (ComplexShape.up ℕ).prev 0 = 0 := by - classical - refine dif_neg ?_ - push Not - intro - apply Nat.noConfusion + refine dif_neg ?_ + push Not + intro + apply Nat.noConfusion @[simp] theorem prev_nat_succ (i : ℕ) : (ComplexShape.up ℕ).prev (i + 1) = i := diff --git a/Mathlib/Algebra/Homology/QuasiIso.lean b/Mathlib/Algebra/Homology/QuasiIso.lean index 24b0e82c49d2e2..83e5a5d56c97f2 100644 --- a/Mathlib/Algebra/Homology/QuasiIso.lean +++ b/Mathlib/Algebra/Homology/QuasiIso.lean @@ -336,7 +336,6 @@ variable {ι : Type*} {C : Type u} [Category.{v} C] [Preadditive C] instance quasiIsoAt_hom (n : ι) [K.HasHomology n] [L.HasHomology n] : QuasiIsoAt e.hom n := by - classical rw [quasiIsoAt_iff, ShortComplex.quasiIso_iff] exact (e.toHomologyIso n).isIso_hom diff --git a/Mathlib/Algebra/Lie/CartanExists.lean b/Mathlib/Algebra/Lie/CartanExists.lean index 0519f0c7940697..4d4665d212cbfc 100644 --- a/Mathlib/Algebra/Lie/CartanExists.lean +++ b/Mathlib/Algebra/Lie/CartanExists.lean @@ -112,7 +112,6 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in lemma lieCharpoly_coeff_natDegree [Nontrivial R] (i j : ℕ) (hij : i + j = finrank R M) : ((lieCharpoly R M x y).coeff i).natDegree ≤ j := by - classical rw [← mul_one j, lieCharpoly, coeff_map] apply MvPolynomial.aeval_natDegree_le · apply (polyCharpoly_coeff_isHomogeneous φ (chooseBasis R L) _ _ hij).totalDegree_le diff --git a/Mathlib/Algebra/Lie/Submodule.lean b/Mathlib/Algebra/Lie/Submodule.lean index 82a263fbcad7bd..d90f34341667ac 100644 --- a/Mathlib/Algebra/Lie/Submodule.lean +++ b/Mathlib/Algebra/Lie/Submodule.lean @@ -383,7 +383,6 @@ instance : SupSet (LieSubmodule R L M) where change ⁅x, m⁆ ∈ sSup {(p : Submodule R M) | p ∈ S} obtain ⟨s, hs, hsm⟩ := Submodule.mem_sSup_iff_exists_finset.mp hm clear hm - classical induction s using Finset.induction_on generalizing m with | empty => replace hsm : m = 0 := by simpa using hsm diff --git a/Mathlib/Algebra/Module/DedekindDomain.lean b/Mathlib/Algebra/Module/DedekindDomain.lean index 8685ab42f0a892..b0f5e2bbb0e863 100644 --- a/Mathlib/Algebra/Module/DedekindDomain.lean +++ b/Mathlib/Algebra/Module/DedekindDomain.lean @@ -74,7 +74,6 @@ theorem isInternal_prime_power_torsion [Module.Finite R M] theorem exists_isInternal_prime_power_torsion [Module.Finite R M] (hM : Module.IsTorsion R M) : ∃ (P : Finset <| Ideal R) (_ : DecidableEq P) (_ : ∀ p ∈ P, Prime p) (e : P → ℕ), DirectSum.IsInternal fun p : P => torsionBySet R M (p ^ e p : Ideal R) := by - classical exact ⟨_, _, fun p hp => prime_of_factor p (Multiset.mem_toFinset.mp hp), _, isInternal_prime_power_torsion hM⟩ diff --git a/Mathlib/Algebra/Module/FinitePresentation.lean b/Mathlib/Algebra/Module/FinitePresentation.lean index de0440401bcbe2..375402f1d9763b 100644 --- a/Mathlib/Algebra/Module/FinitePresentation.lean +++ b/Mathlib/Algebra/Module/FinitePresentation.lean @@ -122,7 +122,6 @@ lemma Module.finitePresentation_of_free_of_surjective [Module.Free R M] [Module. (l : M →ₗ[R] N) (hl : Function.Surjective l) (hl' : (LinearMap.ker l).FG) : Module.FinitePresentation R N := by - classical let b := Module.Free.chooseBasis R M let π : Free.ChooseBasisIndex R M → (Set.finite_range (l ∘ b)).toFinset := fun i ↦ ⟨l (b i), by simp⟩ @@ -184,7 +183,6 @@ lemma Module.finitePresentation_of_surjective [h : Module.FinitePresentation R M lemma Module.FinitePresentation.fg_ker [Module.Finite R M] [h : Module.FinitePresentation R N] (l : M →ₗ[R] N) (hl : Function.Surjective l) : (LinearMap.ker l).FG := by - classical obtain ⟨s, hs, hs'⟩ := h have H : Function.Surjective (Finsupp.linearCombination R ((↑) : s → N)) := LinearMap.range_eq_top.mp @@ -331,7 +329,6 @@ lemma Module.FinitePresentation.trans (S : Type*) [CommRing S] [Algebra R S] open TensorProduct in instance {A} [CommRing A] [Algebra R A] [Module.FinitePresentation R M] : Module.FinitePresentation A (A ⊗[R] M) := by - classical obtain ⟨n, f, hf⟩ := Module.Finite.exists_fin' R M have inst := Module.finitePresentation_of_projective A (A ⊗[R] (Fin n → R)) apply Module.finitePresentation_of_surjective (f.baseChange A) diff --git a/Mathlib/Algebra/Module/LinearMap/Polynomial.lean b/Mathlib/Algebra/Module/LinearMap/Polynomial.lean index f4ac32d9e1ee8e..7917d4e60e82fe 100644 --- a/Mathlib/Algebra/Module/LinearMap/Polynomial.lean +++ b/Mathlib/Algebra/Module/LinearMap/Polynomial.lean @@ -253,7 +253,6 @@ lemma polyCharpolyAux_baseChange (A : Type*) [CommRing A] [Algebra R A] : simp only [RingHom.coe_comp, RingHom.coe_coe, Function.comp_apply, map_C, bind₁_C_right] · rintro ij simp only [RingHom.coe_comp, RingHom.coe_coe, Function.comp_apply, map_X, bind₁_X_right] - classical rw [toMvPolynomial_comp _ (basis A (Basis.end bₘ)), ← toMvPolynomial_baseChange] suffices toMvPolynomial (M₂ := (Module.End A (TensorProduct R A M))) (basis A bₘ.end) (basis A bₘ).end (tensorProduct R A M M) ij = X ij by diff --git a/Mathlib/Algebra/Module/PID.lean b/Mathlib/Algebra/Module/PID.lean index 499a385da36705..7bef59eaa54986 100644 --- a/Mathlib/Algebra/Module/PID.lean +++ b/Mathlib/Algebra/Module/PID.lean @@ -90,7 +90,6 @@ theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R (hM : Module.IsTorsion R M) : ∃ (ι : Type u) (_ : Fintype ι) (_ : DecidableEq ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ), DirectSum.IsInternal fun i => torsionBy R M <| p i ^ e i := by - classical refine ⟨_, ?_, _, _, ?_, _, Submodule.isInternal_prime_power_torsion_of_pid hM⟩ · exact Finset.fintypeCoeSort _ · rintro ⟨p, hp⟩ @@ -242,7 +241,6 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R M] (hM : Module.IsTor exact fun i => torsion_by_prime_power_decomposition.{u, v} (hp i) ((isTorsion'_powers_iff <| p i).mpr fun x => ⟨e i, smul_torsionBy _ _⟩) - classical refine ⟨Σ i, Fin (this i).choose, inferInstance, fun ⟨i, _⟩ => p i, fun ⟨i, _⟩ => hp i, fun ⟨i, j⟩ => (this i).choose_spec.choose j, diff --git a/Mathlib/Algebra/Module/Submodule/Finsupp.lean b/Mathlib/Algebra/Module/Submodule/Finsupp.lean index 7781dc199b3df6..086aff10784c82 100644 --- a/Mathlib/Algebra/Module/Submodule/Finsupp.lean +++ b/Mathlib/Algebra/Module/Submodule/Finsupp.lean @@ -44,7 +44,6 @@ lemma set_smul_eq_map [SMulCommClass R R N] : Submodule.map (N.subtype.comp (Finsupp.lsum R <| DistribSMul.toLinearMap _ _)) (Finsupp.supported N R sR) := by - classical apply set_smul_eq_of_le · intro r n hr hn exact ⟨Finsupp.single r ⟨n, hn⟩, Finsupp.single_mem_supported _ _ hr, by simp⟩ diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 8ee3ab95cc8422..0eba5457bb7a25 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -517,11 +517,11 @@ protected theorem map_smul (f : V →ₗ[K] V₂) (p : Submodule K V) (a : K) (h theorem comap_smul' (f : V →ₗ[K] V₂) (p : Submodule K V₂) (a : K) : p.comap (a • f) = ⨅ _ : a ≠ 0, p.comap f := by - classical by_cases h : a = 0 <;> simp [h, comap_smul] + by_cases h : a = 0 <;> simp [h, comap_smul] theorem map_smul' (f : V →ₗ[K] V₂) (p : Submodule K V) (a : K) : p.map (a • f) = ⨆ _ : a ≠ 0, map f p := by - classical by_cases h : a = 0 <;> simp [h, Submodule.map_smul] + by_cases h : a = 0 <;> simp [h, Submodule.map_smul] end Submodule diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index cac18e0e8dd386..15fc3113bf3843 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -171,12 +171,11 @@ theorem repr_fract_apply (m : E) (i : ι) : b.repr (fract b m) i = Int.fract (b. @[simp] theorem fract_fract (m : E) : fract b (fract b m) = fract b m := - Basis.ext_elem b fun _ => by classical simp only [repr_fract_apply, Int.fract_fract] + Basis.ext_elem b fun _ => by simp only [repr_fract_apply, Int.fract_fract] @[simp] theorem fract_zSpan_add (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) : fract b (v + m) = fract b m := by - classical refine (Basis.ext_elem_iff b).mpr fun i => ?_ simp_rw [repr_fract_apply, Int.fract_eq_fract] use (b.restrictScalars ℤ).repr ⟨v, h⟩ i @@ -189,7 +188,7 @@ theorem fract_add_ZSpan (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) : variable {b} in theorem fract_eq_self {x : E} : fract b x = x ↔ x ∈ fundamentalDomain b := by - classical simp only [Basis.ext_elem_iff b, repr_fract_apply, Int.fract_eq_self, + simp only [Basis.ext_elem_iff b, repr_fract_apply, Int.fract_eq_self, mem_fundamentalDomain, Set.mem_Ico] theorem fract_mem_fundamentalDomain (x : E) : fract b x ∈ fundamentalDomain b := @@ -205,14 +204,12 @@ theorem fractRestrict_surjective : Function.Surjective (fractRestrict b) := theorem fractRestrict_apply (x : E) : (fractRestrict b x : E) = fract b x := rfl theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ (Set.range b) := by - classical rw [eq_comm, Basis.ext_elem_iff b] simp_rw [repr_fract_apply, Int.fract_eq_fract, eq_comm, Basis.mem_span_iff_repr_mem, sub_eq_neg_add, map_add, map_neg, Finsupp.coe_add, Finsupp.coe_neg, Pi.add_apply, Pi.neg_apply, ← eq_intCast (algebraMap ℤ K) _, Set.mem_range] theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b i‖ := by - classical calc ‖fract b m‖ = ‖∑ i, b.repr (fract b m) i • b i‖ := by rw [b.sum_repr] _ = ‖∑ i, Int.fract (b.repr m i) • b i‖ := by simp_rw [repr_fract_apply] diff --git a/Mathlib/Algebra/Module/ZLattice/Covolume.lean b/Mathlib/Algebra/Module/ZLattice/Covolume.lean index 05d7349d94a083..8378bc4811ea93 100644 --- a/Mathlib/Algebra/Module/ZLattice/Covolume.lean +++ b/Mathlib/Algebra/Module/ZLattice/Covolume.lean @@ -195,7 +195,6 @@ theorem volume_image_eq_volume_div_covolume' {E : Type*} [NormedAddCommGroup E] (L : Submodule ℤ E) [DiscreteTopology L] [IsZLattice ℝ L] {ι : Type*} [Fintype ι] (b : Basis ι ℤ L) {s : Set E} (hs : NullMeasurableSet s) : volume ((b.ofZLatticeBasis ℝ).equivFun '' s) = volume s / ENNReal.ofReal (covolume L) := by - classical let e : Fin (finrank ℝ E) ≃ ι := Fintype.equivOfCardEq (by rw [Fintype.card_fin, finrank_eq_card_basis (b.ofZLatticeBasis ℝ)]) let f := (EuclideanSpace.equiv ι ℝ).symm.trans @@ -312,7 +311,6 @@ theorem tendsto_card_div_pow (b : Basis ι ℤ L) {s : Set (ι → ℝ)} (hs₁ (hs₂ : MeasurableSet s) (hs₃ : volume (frontier s) = 0) : Tendsto (fun n : ℕ ↦ (Nat.card (s ∩ (n : ℝ)⁻¹ • L : Set (ι → ℝ)) : ℝ) / n ^ card ι) atTop (𝓝 (volume.real s / covolume L)) := by - classical convert! tendsto_card_div_pow'' b hs₁ hs₂ ?_ · simp only [measureReal_def] rw [volume_image_eq_volume_div_covolume L b, ENNReal.toReal_div, @@ -326,7 +324,6 @@ theorem tendsto_card_le_div {X : Set (ι → ℝ)} (hX : ∀ ⦃x⦄ ⦃r : ℝ Tendsto (fun c : ℝ ↦ Nat.card ({x ∈ X | F x ≤ c} ∩ L : Set (ι → ℝ)) / (c : ℝ)) atTop (𝓝 (volume.real {x ∈ X | F x ≤ 1} / covolume L)) := by - classical let e : Free.ChooseBasisIndex ℤ ↥L ≃ ι := by refine Fintype.equivOfCardEq ?_ rw [← finrank_eq_card_chooseBasisIndex, ZLattice.rank ℝ, finrank_fintype_fun_eq_card] diff --git a/Mathlib/Algebra/Module/ZLattice/Summable.lean b/Mathlib/Algebra/Module/ZLattice/Summable.lean index 243715f9a2b4f2..ddd21638b73105 100644 --- a/Mathlib/Algebra/Module/ZLattice/Summable.lean +++ b/Mathlib/Algebra/Module/ZLattice/Summable.lean @@ -158,7 +158,6 @@ variable (L) lemma exists_finsetSum_norm_rpow_le_tsum : ∃ A > (0 : ℝ), ∀ r < (-Module.finrank ℤ L : ℝ), ∀ s : Finset L, ∑ z ∈ s, ‖z‖ ^ r ≤ A ^ r * ∑' k : ℕ, (k : ℝ) ^ (Module.finrank ℤ L - 1 + r) := by - classical cases subsingleton_or_nontrivial L · refine ⟨1, zero_lt_one, fun r hr s ↦ ?_⟩ have hr : r ≠ 0 := by linarith diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index e21a42366dbd79..7da1c96a60787e 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -128,7 +128,7 @@ def uniqueAlgEquiv [Subsingleton M] : A[M] ≃ₐ[R] A where variable (R M) in @[to_additive (dont_translate := A) (attr := simp)] lemma uniqueAlgEquiv_symm_apply [Subsingleton M] (a : A) : - (uniqueAlgEquiv R M).symm a = single 1 a := by classical ext; simp [uniqueAlgEquiv] + (uniqueAlgEquiv R M).symm a = single 1 a := by ext; simp [uniqueAlgEquiv] -- We want this lemma to fire before `uniqueAlgEquiv_symm_apply`. @[to_additive (dont_translate := A) (attr := simp↓ high)] diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index ae0f0ecd99c765..c4cc223d98c642 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -750,7 +750,7 @@ def uniqueRingEquiv [Subsingleton M] : R[M] ≃+* R where variable (M) in @[to_additive (dont_translate := R) (attr := simp)] lemma uniqueRingEquiv_symm_apply [Subsingleton M] (r : R) : - (uniqueRingEquiv M).symm r = single 1 r := by classical ext; simp [uniqueRingEquiv] + (uniqueRingEquiv M).symm r = single 1 r := by ext; simp [uniqueRingEquiv] -- We want this lemma to fire before `uniqueRingEquiv_symm_apply`. @[to_additive (dont_translate := R) (attr := simp↓ high)] diff --git a/Mathlib/Algebra/MonoidAlgebra/Degree.lean b/Mathlib/Algebra/MonoidAlgebra/Degree.lean index 259226a19b845f..69707c9be5ca1e 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Degree.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Degree.lean @@ -378,7 +378,6 @@ variable {D} @[simp] theorem leadingCoeff_single [Nonempty A] (hD : D.Injective) (a : A) (r : R) : (single a r).leadingCoeff D = r := by - classical rw [leadingCoeff, supDegree_single] split_ifs with hr · simp [hr] diff --git a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean index 252a0f83ce7af7..c4e84dd214b749 100644 --- a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean +++ b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean @@ -267,6 +267,6 @@ theorem AddMonoidAlgebra.toDirectSum_pow [DecidableEq ι] [AddMonoid ι] [Semiri theorem DirectSum.toAddMonoidAlgebra_pow [DecidableEq ι] [AddMonoid ι] [Semiring M] [∀ m : M, Decidable (m ≠ 0)] (f : ⨁ _ : ι, M) (n : ℕ) : (f ^ n).toAddMonoidAlgebra = toAddMonoidAlgebra f ^ n := by - classical exact map_pow addMonoidAlgebraRingEquivDirectSum.symm f n + exact map_pow addMonoidAlgebraRingEquivDirectSum.symm f n end Equivs diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 7afd4f5009d1e1..6aee400c27610b 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -882,12 +882,10 @@ lemma coeffs_C_subset (r : R) : (C (σ := σ) r).coeffs ⊆ {r} := by @[simp] lemma coeffs_mul_X (p : MvPolynomial σ R) (n : σ) : (p * X n).coeffs = p.coeffs := by - classical aesop (add simp mem_coeffs_iff) @[simp] lemma coeffs_X_mul (p : MvPolynomial σ R) (n : σ) : (X n * p).coeffs = p.coeffs := by - classical aesop (add simp mem_coeffs_iff) lemma coeffs_add [DecidableEq R] {p q : MvPolynomial σ R} (h : Disjoint p.support q.support) : @@ -928,7 +926,7 @@ theorem constantCoeff_eq : (constantCoeff : MvPolynomial σ R → R) = coeff 0 : variable (σ) in @[simp] theorem constantCoeff_C (r : R) : constantCoeff (C r : MvPolynomial σ R) = r := by - classical simp [constantCoeff_eq] + simp [constantCoeff_eq] variable (R) in @[simp] @@ -1002,7 +1000,6 @@ lemma one_coeffsIn : 1 ∈ coeffsIn σ M ↔ 1 ∈ M := by simpa using C_mem_coe @[simp] lemma mul_monomial_mem_coeffsIn : p * monomial i 1 ∈ coeffsIn σ M ↔ p ∈ coeffsIn σ M := by - classical simp only [mem_coeffsIn, coeff_mul_monomial'] constructor · rintro hp j diff --git a/Mathlib/Algebra/MvPolynomial/Degrees.lean b/Mathlib/Algebra/MvPolynomial/Degrees.lean index 1069e18a3961dc..3d773c61174d0c 100644 --- a/Mathlib/Algebra/MvPolynomial/Degrees.lean +++ b/Mathlib/Algebra/MvPolynomial/Degrees.lean @@ -250,7 +250,6 @@ theorem degreeOf_C (a : R) (x : σ) : degreeOf x (C a : MvPolynomial σ R) = 0 : theorem degreeOf_X [DecidableEq σ] (i j : σ) [Nontrivial R] : degreeOf i (X j : MvPolynomial σ R) = if i = j then 1 else 0 := by - classical by_cases c : i = j · simp only [c, if_true, degreeOf_def, degrees_X, Multiset.count_singleton] simp [c, degreeOf_def, degrees_X] @@ -578,13 +577,12 @@ theorem exists_degree_lt [Fintype σ] (f : MvPolynomial σ R) (n : ℕ) theorem coeff_eq_zero_of_totalDegree_lt {f : MvPolynomial σ R} {d : σ →₀ ℕ} (h : f.totalDegree < ∑ i ∈ d.support, d i) : coeff d f = 0 := by - classical - rw [totalDegree, Finset.sup_lt_iff] at h - · specialize h d - rw [mem_support_iff] at h - refine not_not.mp (mt h ?_) - exact lt_irrefl _ - · exact lt_of_le_of_lt (Nat.zero_le _) h + rw [totalDegree, Finset.sup_lt_iff] at h + · specialize h d + rw [mem_support_iff] at h + refine not_not.mp (mt h ?_) + exact lt_irrefl _ + · exact lt_of_le_of_lt (Nat.zero_le _) h theorem totalDegree_eq_zero_iff_eq_C {p : MvPolynomial σ R} : p.totalDegree = 0 ↔ p = C (p.coeff 0) := by diff --git a/Mathlib/Algebra/MvPolynomial/Division.lean b/Mathlib/Algebra/MvPolynomial/Division.lean index 2ab005d010f324..47a32344741244 100644 --- a/Mathlib/Algebra/MvPolynomial/Division.lean +++ b/Mathlib/Algebra/MvPolynomial/Division.lean @@ -340,7 +340,6 @@ theorem dvd_monomial_mul_iff_exists [IsCancelMulZero R] {n : σ →₀ ℕ} : refine ⟨n, le_refl n⟩ suffices ∀ (d) (n : σ →₀ ℕ) (hd : n.degree = d) (p q : MvPolynomial σ R), p ∣ monomial n 1 * q ↔ ∃ m r, m ≤ n ∧ r ∣ q ∧ p = monomial m 1 * r from this n.degree n rfl p q - classical intro d induction d with | zero => diff --git a/Mathlib/Algebra/MvPolynomial/Nilpotent.lean b/Mathlib/Algebra/MvPolynomial/Nilpotent.lean index 817993a0c2ab17..cea6a5185945b3 100644 --- a/Mathlib/Algebra/MvPolynomial/Nilpotent.lean +++ b/Mathlib/Algebra/MvPolynomial/Nilpotent.lean @@ -72,7 +72,7 @@ theorem isUnit_iff : IsUnit P ↔ IsUnit (P.coeff 0) ∧ ∀ i ≠ 0, IsNilpoten simpa using this.isUnit_add_right_of_commute (h₁.map C) (.all _ _) instance : IsLocalHom (C : _ →+* MvPolynomial σ R) where - map_nonunit := by classical simp +contextual [isUnit_iff, coeff_C] + map_nonunit := by simp +contextual [isUnit_iff] instance : IsLocalHom (algebraMap R (MvPolynomial σ R)) := inferInstanceAs (IsLocalHom C) diff --git a/Mathlib/Algebra/Order/Archimedean/Basic.lean b/Mathlib/Algebra/Order/Archimedean/Basic.lean index f2ba71cf32dfa8..5190122bf7cc2b 100644 --- a/Mathlib/Algebra/Order/Archimedean/Basic.lean +++ b/Mathlib/Algebra/Order/Archimedean/Basic.lean @@ -196,7 +196,7 @@ variable [Semiring R] [LinearOrder R] [IsStrictOrderedRing R] [Archimedean R] [E natural-number powers of every y greater than one. -/ theorem exists_nat_pow_near (hx : 1 ≤ x) (hy : 1 < y) : ∃ n : ℕ, y ^ n ≤ x ∧ x < y ^ (n + 1) := by have h : ∃ n : ℕ, x < y ^ n := pow_unbounded_of_one_lt _ hy - classical exact + exact let n := Nat.find h have hn : x < y ^ n := Nat.find_spec h have hnp : 0 < n := @@ -224,7 +224,6 @@ variable [ExistsAddOfLE K] another `y` greater than one. This is the same as `exists_mem_Ioc_zpow`, but with ≤ and < the other way around. -/ theorem exists_mem_Ico_zpow (hx : 0 < x) (hy : 1 < y) : ∃ n : ℤ, x ∈ Ico (y ^ n) (y ^ (n + 1)) := by - classical have he : ∃ m : ℤ, y ^ m ≤ x := by obtain ⟨N, hN⟩ := pow_unbounded_of_one_lt x⁻¹ hy use -N diff --git a/Mathlib/Algebra/Order/Chebyshev.lean b/Mathlib/Algebra/Order/Chebyshev.lean index e450d2b7f6c12d..33c9dbbe8ce392 100644 --- a/Mathlib/Algebra/Order/Chebyshev.lean +++ b/Mathlib/Algebra/Order/Chebyshev.lean @@ -58,7 +58,6 @@ monotone/antitone), the scalar product of their sum is less than the size of the scalar product. -/ theorem MonovaryOn.sum_smul_sum_le_card_smul_sum (hfg : MonovaryOn f g s) : (∑ i ∈ s, f i) • ∑ i ∈ s, g i ≤ #s • ∑ i ∈ s, f i • g i := by - classical obtain ⟨σ, hσ, hs⟩ := s.countable_toSet.exists_cycleOn rw [← card_range #s, sum_smul_sum_eq_sum_perm hσ] exact sum_le_card_nsmul _ _ _ fun n _ ↦ diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index 4f38dc96829bbb..851f328b8ec85e 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -1044,12 +1044,10 @@ theorem mem_coeffs_iff {p : R[X]} {c : R} : c ∈ p.coeffs ↔ ∃ n ∈ p.suppo simp [coeffs, eq_comm, (Finset.mem_image)] theorem coeffs_one : coeffs (1 : R[X]) ⊆ {1} := by - classical simp_rw [coeffs, Finset.image_subset_iff] simp_all [coeff_one] theorem coeff_mem_coeffs {p : R[X]} {n : ℕ} (h : p.coeff n ≠ 0) : p.coeff n ∈ p.coeffs := by - classical simp only [coeffs, mem_support_iff, Finset.mem_image, Ne] exact ⟨n, h, rfl⟩ diff --git a/Mathlib/Algebra/Polynomial/Degree/Domain.lean b/Mathlib/Algebra/Polynomial/Degree/Domain.lean index 9ae5e8abfb109d..878ee5dcebc5d9 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Domain.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Domain.lean @@ -52,7 +52,6 @@ lemma natDegree_smul {S : Type*} [Semiring S] [IsDomain S] [Module S R] [Module. @[simp] lemma natDegree_pow (p : R[X]) (n : ℕ) : natDegree (p ^ n) = n * natDegree p := by - classical obtain rfl | hp := eq_or_ne p 0 · obtain rfl | hn := eq_or_ne n 0 <;> simp [*] exact natDegree_pow' <| by diff --git a/Mathlib/Algebra/Polynomial/Degree/Operations.lean b/Mathlib/Algebra/Polynomial/Degree/Operations.lean index 470a8b06b11dbe..71f88889a733b0 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Operations.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Operations.lean @@ -718,7 +718,6 @@ lemma leadingCoeff_dvd_leadingCoeff {a p : R[X]} (hap : a ∣ p) : map_dvd leadingCoeffHom hap lemma degree_le_mul_left (p : R[X]) (hq : q ≠ 0) : degree p ≤ degree (p * q) := by - classical obtain rfl | hp := eq_or_ne p 0 · simp · rw [degree_mul, degree_eq_natDegree hp, degree_eq_natDegree hq] diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index 03b97312bdc07d..83d5f1a482e89a 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -209,7 +209,6 @@ theorem modByMonic_eq_of_not_monic (p : R[X]) (hq : ¬Monic q) : p %ₘ q = p := theorem modByMonic_eq_self_iff [Nontrivial R] (hq : Monic q) : p %ₘ q = p ↔ degree p < degree q := ⟨fun h => h ▸ degree_modByMonic_lt _ hq, fun h => by - classical have : ¬degree q ≤ degree p := not_le_of_gt h unfold modByMonic divModByMonicAux; dsimp; rw [dif_pos hq, if_neg (mt And.left this)]⟩ @@ -273,7 +272,6 @@ theorem divByMonic_eq_zero_iff [Nontrivial R] (hq : Monic q) : p /ₘ q = 0 ↔ have := modByMonic_add_div p q rwa [h, mul_zero, add_zero, modByMonic_eq_self_iff hq] at this, fun h => by - classical have : ¬degree q ≤ degree p := not_le_of_gt h unfold divByMonic divModByMonicAux; dsimp; rw [dif_pos hq, if_neg (mt And.left this)]⟩ @@ -556,7 +554,6 @@ theorem pow_rootMultiplicity_dvd (p : R[X]) (a : R) : (X - C a) ^ rootMultiplici letI := Classical.decEq R if h : p = 0 then by simp [h] else by - classical rw [rootMultiplicity_eq_multiplicity, if_neg h]; apply pow_multiplicity_dvd theorem pow_mul_divByMonic_rootMultiplicity_eq (p : R[X]) (a : R) : @@ -723,7 +720,6 @@ lemma eval_divByMonic_eq_trailingCoeff_comp {p : R[X]} {t : R} : `(X - a) ^ n` divides `p`. -/ lemma le_rootMultiplicity_iff (p0 : p ≠ 0) {a : R} {n : ℕ} : n ≤ rootMultiplicity a p ↔ (X - C a) ^ n ∣ p := by - classical simp_rw [rootMultiplicity, dif_neg p0, Nat.le_find_iff, not_not] refine ⟨fun h => ?_, fun h m hm => (pow_dvd_pow _ hm).trans h⟩ rcases n with - | n diff --git a/Mathlib/Algebra/Polynomial/FieldDivision.lean b/Mathlib/Algebra/Polynomial/FieldDivision.lean index 94f81cb00c56c3..553755e3e42955 100644 --- a/Mathlib/Algebra/Polynomial/FieldDivision.lean +++ b/Mathlib/Algebra/Polynomial/FieldDivision.lean @@ -368,7 +368,6 @@ instance instEuclideanDomain : EuclideanDomain R[X] := theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q := ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by - classical have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p := not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0] rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)] @@ -652,7 +651,6 @@ then `f / (X - a)` is coprime with `X - a`. Note that we do not assume `f a = 0`, because `f / (X - a) = (f - f a) / (X - a)`. -/ theorem isCoprime_of_is_root_of_eval_derivative_ne_zero {K : Type*} [Field K] (f : K[X]) (a : K) (hf' : f.derivative.eval a ≠ 0) : IsCoprime (X - C a : K[X]) (f /ₘ (X - C a)) := by - classical refine Or.resolve_left (EuclideanDomain.dvd_or_coprime (X - C a) (f /ₘ (X - C a)) (irreducible_of_degree_eq_one (Polynomial.degree_X_sub_C a))) ?_ diff --git a/Mathlib/Algebra/Polynomial/Roots.lean b/Mathlib/Algebra/Polynomial/Roots.lean index c55613f8ce6cd2..2f56ad2efa04db 100644 --- a/Mathlib/Algebra/Polynomial/Roots.lean +++ b/Mathlib/Algebra/Polynomial/Roots.lean @@ -97,7 +97,6 @@ theorem card_roots_sub_C' {p : R[X]} {a : R} (hp0 : 0 < degree p) : @[simp] theorem count_roots [DecidableEq R] (p : R[X]) : p.roots.count a = rootMultiplicity a p := by - classical by_cases hp : p = 0 · simp [hp] rw [roots_def, dif_neg hp] diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index 8035ef9225714b..479278254a51d4 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -686,7 +686,6 @@ theorem splits_iff_splits {f : R[X]} : (hf.of_dvd h0 hgf).degree_eq_one_of_irreducible hg, ?_⟩ rintro (rfl | hf) · aesop - classical by_cases hf0 : f = 0 · simp [hf0] obtain ⟨u, hu⟩ := factors_prod hf0 diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean index 55c81676972ae1..3e50c645da8563 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean @@ -1177,7 +1177,6 @@ variable (k G) [Monoid G] [MulSemiringAction G k] instance isScalarTower_self [IsScalarTower k k k] : IsScalarTower k (SkewMonoidAlgebra k G) (SkewMonoidAlgebra k G) := ⟨fun t a b ↦ by - classical simp only [smul_eq_mul] refine Eq.trans (sum_smul_index' (g := a) (b := t) ?_) ?_ <;> simp only [← smul_sum, smul_mul_assoc, ← smul_single, diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean index 65049171679131..974d23fc108dcd 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Lift.lean @@ -133,7 +133,6 @@ theorem equivMapDomain_refl (l : SkewMonoidAlgebra k G) : equivMapDomain (Equiv. @[simp] theorem equivMapDomain_single (f : G ≃ H) (a : G) (b : k) : equivMapDomain f (single a b) = single (f a) b := by - classical apply coeff_injective simp_rw [coeff_equivMapDomain, single, Finsupp.equivMapDomain_single] diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index e77c7685f5ec3c..c3d85f203b8d0b 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -1022,7 +1022,6 @@ theorem of_affine_open_cover {X : Scheme} {P : X.affineOpens → Prop} (_ : Ideal.span (s : Set (Γ(X, U))) = ⊤), (∀ f : s, P (X.affineBasicOpen f.1)) → P U) (hU : ∀ i, P (U i)) : P V := by - classical have : ∀ (x : V.1), ∃ f : Γ(X, V), ↑x ∈ X.basicOpen f ∧ P (X.affineBasicOpen f) := by intro x obtain ⟨i, hi⟩ := Opens.mem_iSup.mp (iSup_U.ge (Set.mem_univ x)) diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index 40adc99197af29..331e6b9ac11b68 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -1061,7 +1061,6 @@ lemma exists_isAffineOpen_preimage_eq [∀ i, QuasiSeparatedSpace (D.obj i)] (U : c.pt.Opens) (hU : IsAffineOpen U) : ∃ (i : I) (V : (D.obj i).Opens), IsAffineOpen V ∧ c.π.app i ⁻¹ᵁ V = U := by - classical obtain ⟨i, U, hU', rfl⟩ := exists_preimage_eq D c hc U hU.isCompact have (j : Over i) : CompactSpace ((opensDiagram D i U).obj j) := isCompact_iff_compactSpace.mp (QuasiCompact.isCompact_preimage _ U.2 hU') @@ -1106,7 +1105,6 @@ lemma Scheme.exists_isOpenCover_and_isAffine [IsCofiltered I] {J : Type*} (U : J → c.pt.Opens) (hU : IsOpenCover U) (hU' : ∀ i, IsAffineOpen (U i)) : ∃ (i : I) (s : Finset J) (V : s → (D.obj i).Opens), IsOpenCover V ∧ ∀ j, IsAffineOpen (V j) ∧ U j = c.π.app i ⁻¹ᵁ (V j) := by - classical have := compactSpace_of_isLimit D c hc obtain ⟨s, hs⟩ := isCompact_univ.elim_finite_subcover _ (fun i ↦ (U i).isOpen) hU.iSup_set_eq_univ.ge @@ -1233,7 +1231,6 @@ lemma Scheme.exists_π_app_comp_eq_of_locallyOfFinitePresentation [∀ i, CompactSpace (D.obj i)] [∀ i, QuasiSeparatedSpace (D.obj i)] (a : c.pt ⟶ X) (ha : c.π ≫ t = (Functor.const _).map (a ≫ f)) : ∃ (i : I) (g : D.obj i ⟶ X), c.π.app i ≫ g = a ∧ g ≫ f = t.app i := by - classical -- The open cover of `c := lim Dᵢ` indexed by triplets of affine opens `(U, V, W)` with -- `U ⊆ c`, `V ⊆ X`, `W ⊆ S` such that `U` maps to `V` maps to `W`. have 𝒰 := (c.pt.isBasis_affineOpens).isOpenCover_mem_and_le diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean index 095c53dd0d0a98..0430d1d66511fe 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean @@ -433,7 +433,6 @@ lemma isIso_pushoutSection_of_iSup_eq lemma mono_pushoutSection_of_isCompact_of_flat_right [Flat f] (hUS : IsAffineOpen US) (hUT : IsAffineOpen UT) (hUX : IsCompact (X := X) UX) : Mono (pushoutSection H hUST hUSX hUY) := by - classical obtain ⟨I, hI, e⟩ := isCompact_iff_finite_and_eq_biUnion_affineOpens.mp hUX have := hI.to_subtype exact mono_pushoutSection_of_iSup_eq (ι := I) H hUST hUSX hUY (·) (by rwa [iSup_subtype, eq_comm]) @@ -452,7 +451,6 @@ lemma isIso_pushoutSection_of_isQuasiSeparated_of_flat_right [Flat f] (hUS : IsAffineOpen US) (hUT : IsAffineOpen UT) (hUX : IsCompact (X := X) UX) (hUX' : IsQuasiSeparated (α := X) UX) : IsIso (pushoutSection H hUST hUSX hUY) := by - classical obtain ⟨I, hI, e⟩ := isCompact_iff_finite_and_eq_biUnion_affineOpens.mp hUX have hIUX (i : I) : i.1 ≤ UX := by rw [e]; intro i; aesop have := hI.to_subtype diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean index 52850472c76fda..058dc8c2279df7 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean @@ -105,7 +105,6 @@ theorem quasiCompact_iff_forall_isAffineOpen : theorem isCompact_basicOpen (X : Scheme) {U : X.Opens} (hU : IsCompact (U : Set X)) (f : Γ(X, U)) : IsCompact (X.basicOpen f : Set X) := by - classical refine isCompact_iff_finite_and_eq_biUnion_affineOpens.mpr ?_ obtain ⟨s, hs, e⟩ := isCompact_iff_finite_and_eq_biUnion_affineOpens.mp hU let g : s → X.affineOpens := fun V ↦ ⟨V.1 ⊓ X.basicOpen f, by diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean index 2d3a1472a40f32..20efeb92e9c7e6 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean @@ -98,7 +98,6 @@ lemma iSup_basicOpen_eq_top' {ι : Type*} (f : ι → A) (hfn : ∀ i, ∃ n, f i ∈ 𝒜 n) (hf : Algebra.adjoin (𝒜 0) (Set.range f) = ⊤) : ⨆ i, Proj.basicOpen 𝒜 (f i) = ⊤ := by - classical apply Proj.iSup_basicOpen_eq_top intro x hx convert_to x - GradedRing.projZeroRingHom 𝒜 x ∈ _ diff --git a/Mathlib/Analysis/Analytic/Inverse.lean b/Mathlib/Analysis/Analytic/Inverse.lean index 5a1ae3790ef0d7..884a476bf78ade 100644 --- a/Mathlib/Analysis/Analytic/Inverse.lean +++ b/Mathlib/Analysis/Analytic/Inverse.lean @@ -102,7 +102,6 @@ theorem leftInv_comp (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (h : p 1 = (continuousMultilinearCurryFin1 𝕜 E F).symm i) : (leftInv p i x).comp p = id 𝕜 E x := by ext n v - classical match n with | 0 => simp only [comp_coeff_zero', leftInv_coeff_zero, ContinuousMultilinearMap.uncurry0_apply, @@ -203,7 +202,6 @@ theorem comp_rightInv_aux1 {n : ℕ} (hn : 0 < n) (p : FormalMultilinearSeries p.comp q n v = ∑ c ∈ {c : Composition n | 1 < c.length}.toFinset, p c.length (q.applyComposition c v) + p 1 fun _ => q n v := by - classical have A : (Finset.univ : Finset (Composition n)) = {c | 1 < Composition.length c}.toFinset ∪ {Composition.single n hn} := by diff --git a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean index 1d5373d10243b0..44b818599812a4 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean @@ -1062,7 +1062,6 @@ theorem HasFTaylorSeriesUpToOn.comp {n : WithTop ℕ∞} {g : F → G} {f : E `faaDiBruno_aux1` and `faaDiBruno_aux2`, with terms of the same form at order `m+1`. Then, one needs to check that one gets each term once and exactly once, which is given by the bijection `OrderedFinpartition.extendEquiv m`. -/ - classical constructor · intro x hx simp [FormalMultilinearSeries.taylorComp, default, HasFTaylorSeriesUpToOn.zero_eq' hg (h hx)] diff --git a/Mathlib/Analysis/Calculus/FDeriv/Extend.lean b/Mathlib/Analysis/Calculus/FDeriv/Extend.lean index bc0824125353c3..ade989ad91a672 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Extend.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Extend.lean @@ -38,70 +38,69 @@ theorem hasFDerivWithinAt_closure_of_tendsto_fderiv {f : E → F} {s : Set E} {x (f_cont : ∀ y ∈ closure s, ContinuousWithinAt f s y) (h : Tendsto (fun y => fderiv ℝ f y) (𝓝[s] x) (𝓝 f')) : HasFDerivWithinAt f f' (closure s) x := by - classical - -- one can assume without loss of generality that `x` belongs to the closure of `s`, as the - -- statement is empty otherwise - by_cases! hx : x ∉ closure s - · rw [← closure_closure] at hx; exact HasFDerivWithinAt.of_notMem_closure hx - rw [hasFDerivWithinAt_iff_isLittleO, Asymptotics.isLittleO_iff] - /- One needs to show that `‖f y - f x - f' (y - x)‖ ≤ ε ‖y - x‖` for `y` close to `x` in - `closure s`, where `ε` is an arbitrary positive constant. By continuity of the functions, it - suffices to prove this for nearby points inside `s`. In a neighborhood of `x`, the derivative - of `f` is arbitrarily close to `f'` by assumption. The mean value inequality completes the - proof. -/ - intro ε ε_pos - obtain ⟨δ, δ_pos, hδ⟩ : ∃ δ > 0, ∀ y ∈ s, dist y x < δ → ‖fderiv ℝ f y - f'‖ < ε := by - simpa [dist_eq_norm] using tendsto_nhdsWithin_nhds.1 h ε ε_pos - set B := ball x δ - suffices ∀ y ∈ B ∩ closure s, ‖f y - f x - (f' y - f' x)‖ ≤ ε * ‖y - x‖ from - mem_nhdsWithin_iff.2 ⟨δ, δ_pos, fun y hy => by simpa using this y hy⟩ - suffices - ∀ p : E × E, - p ∈ closure ((B ∩ s) ×ˢ (B ∩ s)) → ‖f p.2 - f p.1 - (f' p.2 - f' p.1)‖ ≤ ε * ‖p.2 - p.1‖ by - rw [closure_prod_eq] at this - intro y y_in - apply this ⟨x, y⟩ - have : B ∩ closure s ⊆ closure (B ∩ s) := isOpen_ball.inter_closure - exact ⟨this ⟨mem_ball_self δ_pos, hx⟩, this y_in⟩ - have key : ∀ p : E × E, p ∈ (B ∩ s) ×ˢ (B ∩ s) → - ‖f p.2 - f p.1 - (f' p.2 - f' p.1)‖ ≤ ε * ‖p.2 - p.1‖ := by - rintro ⟨u, v⟩ ⟨u_in, v_in⟩ - have conv : Convex ℝ (B ∩ s) := (convex_ball _ _).inter s_conv - have diff : DifferentiableOn ℝ f (B ∩ s) := f_diff.mono inter_subset_right - have bound : ∀ z ∈ B ∩ s, ‖fderivWithin ℝ f (B ∩ s) z - f'‖ ≤ ε := by - intro z z_in - have h := hδ z - have : fderivWithin ℝ f (B ∩ s) z = fderiv ℝ f z := by - have op : IsOpen (B ∩ s) := isOpen_ball.inter s_open - rw [DifferentiableAt.fderivWithin _ (op.uniqueDiffOn z z_in)] - exact (diff z z_in).differentiableAt (IsOpen.mem_nhds op z_in) - rw [← this] at h - exact le_of_lt (h z_in.2 z_in.1) - simpa using conv.norm_image_sub_le_of_norm_fderivWithin_le' diff bound u_in v_in - rintro ⟨u, v⟩ uv_in - have f_cont' : ∀ y ∈ closure s, ContinuousWithinAt (f - ⇑f') s y := by - intro y y_in - exact Tendsto.sub (f_cont y y_in) f'.cont.continuousWithinAt - refine ContinuousWithinAt.closure_le uv_in ?_ ?_ key - all_goals - -- common start for both continuity proofs - have : (B ∩ s) ×ˢ (B ∩ s) ⊆ s ×ˢ s := by gcongr <;> exact inter_subset_right - obtain ⟨u_in, v_in⟩ : u ∈ closure s ∧ v ∈ closure s := by - simpa [closure_prod_eq] using closure_mono this uv_in - apply ContinuousWithinAt.mono _ this - simp only [ContinuousWithinAt] - · rw [nhdsWithin_prod_eq] - have : ∀ u v, f v - f u - (f' v - f' u) = f v - f' v - (f u - f' u) := by intros; abel - simp only [this] - exact - Tendsto.comp continuous_norm.continuousAt - ((Tendsto.comp (f_cont' v v_in) tendsto_snd).sub <| - Tendsto.comp (f_cont' u u_in) tendsto_fst) - · apply tendsto_nhdsWithin_of_tendsto_nhds - rw [nhds_prod_eq] - exact - tendsto_const_nhds.mul - (Tendsto.comp continuous_norm.continuousAt <| tendsto_snd.sub tendsto_fst) + -- one can assume without loss of generality that `x` belongs to the closure of `s`, as the + -- statement is empty otherwise + by_cases! hx : x ∉ closure s + · rw [← closure_closure] at hx; exact HasFDerivWithinAt.of_notMem_closure hx + rw [hasFDerivWithinAt_iff_isLittleO, Asymptotics.isLittleO_iff] + /- One needs to show that `‖f y - f x - f' (y - x)‖ ≤ ε ‖y - x‖` for `y` close to `x` in + `closure s`, where `ε` is an arbitrary positive constant. By continuity of the functions, it + suffices to prove this for nearby points inside `s`. In a neighborhood of `x`, the derivative + of `f` is arbitrarily close to `f'` by assumption. The mean value inequality completes the + proof. -/ + intro ε ε_pos + obtain ⟨δ, δ_pos, hδ⟩ : ∃ δ > 0, ∀ y ∈ s, dist y x < δ → ‖fderiv ℝ f y - f'‖ < ε := by + simpa [dist_eq_norm] using tendsto_nhdsWithin_nhds.1 h ε ε_pos + set B := ball x δ + suffices ∀ y ∈ B ∩ closure s, ‖f y - f x - (f' y - f' x)‖ ≤ ε * ‖y - x‖ from + mem_nhdsWithin_iff.2 ⟨δ, δ_pos, fun y hy => by simpa using this y hy⟩ + suffices + ∀ p : E × E, + p ∈ closure ((B ∩ s) ×ˢ (B ∩ s)) → ‖f p.2 - f p.1 - (f' p.2 - f' p.1)‖ ≤ ε * ‖p.2 - p.1‖ by + rw [closure_prod_eq] at this + intro y y_in + apply this ⟨x, y⟩ + have : B ∩ closure s ⊆ closure (B ∩ s) := isOpen_ball.inter_closure + exact ⟨this ⟨mem_ball_self δ_pos, hx⟩, this y_in⟩ + have key : ∀ p : E × E, p ∈ (B ∩ s) ×ˢ (B ∩ s) → + ‖f p.2 - f p.1 - (f' p.2 - f' p.1)‖ ≤ ε * ‖p.2 - p.1‖ := by + rintro ⟨u, v⟩ ⟨u_in, v_in⟩ + have conv : Convex ℝ (B ∩ s) := (convex_ball _ _).inter s_conv + have diff : DifferentiableOn ℝ f (B ∩ s) := f_diff.mono inter_subset_right + have bound : ∀ z ∈ B ∩ s, ‖fderivWithin ℝ f (B ∩ s) z - f'‖ ≤ ε := by + intro z z_in + have h := hδ z + have : fderivWithin ℝ f (B ∩ s) z = fderiv ℝ f z := by + have op : IsOpen (B ∩ s) := isOpen_ball.inter s_open + rw [DifferentiableAt.fderivWithin _ (op.uniqueDiffOn z z_in)] + exact (diff z z_in).differentiableAt (IsOpen.mem_nhds op z_in) + rw [← this] at h + exact le_of_lt (h z_in.2 z_in.1) + simpa using conv.norm_image_sub_le_of_norm_fderivWithin_le' diff bound u_in v_in + rintro ⟨u, v⟩ uv_in + have f_cont' : ∀ y ∈ closure s, ContinuousWithinAt (f - ⇑f') s y := by + intro y y_in + exact Tendsto.sub (f_cont y y_in) f'.cont.continuousWithinAt + refine ContinuousWithinAt.closure_le uv_in ?_ ?_ key + all_goals + -- common start for both continuity proofs + have : (B ∩ s) ×ˢ (B ∩ s) ⊆ s ×ˢ s := by gcongr <;> exact inter_subset_right + obtain ⟨u_in, v_in⟩ : u ∈ closure s ∧ v ∈ closure s := by + simpa [closure_prod_eq] using closure_mono this uv_in + apply ContinuousWithinAt.mono _ this + simp only [ContinuousWithinAt] + · rw [nhdsWithin_prod_eq] + have : ∀ u v, f v - f u - (f' v - f' u) = f v - f' v - (f u - f' u) := by intros; abel + simp only [this] + exact + Tendsto.comp continuous_norm.continuousAt + ((Tendsto.comp (f_cont' v v_in) tendsto_snd).sub <| + Tendsto.comp (f_cont' u u_in) tendsto_fst) + · apply tendsto_nhdsWithin_of_tendsto_nhds + rw [nhds_prod_eq] + exact + tendsto_const_nhds.mul + (Tendsto.comp continuous_norm.continuousAt <| tendsto_snd.sub tendsto_fst) /-- If a function is differentiable on the right of a point `a : ℝ`, continuous at `a`, and its derivative also converges at `a`, then `f` is differentiable on the right at `a`. -/ diff --git a/Mathlib/Analysis/Calculus/FDeriv/Mul.lean b/Mathlib/Analysis/Calculus/FDeriv/Mul.lean index 38a6697b0bb9ff..78915282e98b0d 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Mul.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Mul.lean @@ -442,7 +442,7 @@ theorem hasFDerivAt_list_prod_attach' {l : List ι} {x : {i // i ∈ l} → 𝔸 (∑ i : Fin l.length, ((l.attach.take i).map x).prod • (proj l.attach[i.cast List.length_attach.symm]) <• ((l.attach.drop (.succ i)).map x).prod) x := by - classical exact hasStrictFDerivAt_list_prod_attach'.hasFDerivAt + exact hasStrictFDerivAt_list_prod_attach'.hasFDerivAt /-- Auxiliary lemma for `hasStrictFDerivAt_multiset_prod`. diff --git a/Mathlib/Analysis/Calculus/SmoothSeries.lean b/Mathlib/Analysis/Calculus/SmoothSeries.lean index fa903770b9abc9..0c50c2eaa9de4b 100644 --- a/Mathlib/Analysis/Calculus/SmoothSeries.lean +++ b/Mathlib/Analysis/Calculus/SmoothSeries.lean @@ -73,15 +73,14 @@ theorem hasFDerivAt_tsum_of_isPreconnected (hu : Summable u) (hs : IsOpen s) (h's : IsPreconnected s) (hf : ∀ n x, x ∈ s → HasFDerivAt (f n) (f' n x) x) (hf' : ∀ n x, x ∈ s → ‖f' n x‖ ≤ u n) (hx₀ : x₀ ∈ s) (hf0 : Summable fun n => f n x₀) (hx : x ∈ s) : HasFDerivAt (fun y => ∑' n, f n y) (∑' n, f' n x) x := by - classical - have A : - ∀ x : E, x ∈ s → Tendsto (fun t : Finset α => ∑ n ∈ t, f n x) atTop (𝓝 (∑' n, f n x)) := by - intro y hy - apply Summable.hasSum - exact summable_of_summable_hasFDerivAt_of_isPreconnected hu hs h's hf hf' hx₀ hf0 hy - refine hasFDerivAt_of_tendstoUniformlyOn hs (tendstoUniformlyOn_tsum hu hf') - (fun t y hy => ?_) A hx - exact HasFDerivAt.fun_sum fun n _ => hf n y hy + have A : + ∀ x : E, x ∈ s → Tendsto (fun t : Finset α => ∑ n ∈ t, f n x) atTop (𝓝 (∑' n, f n x)) := by + intro y hy + apply Summable.hasSum + exact summable_of_summable_hasFDerivAt_of_isPreconnected hu hs h's hf hf' hx₀ hf0 hy + refine hasFDerivAt_of_tendstoUniformlyOn hs (tendstoUniformlyOn_tsum hu hf') + (fun t y hy => ?_) A hx + exact HasFDerivAt.fun_sum fun n _ => hf n y hy /-- Consider a series of functions `∑' n, f n x` on a preconnected open set. If the series converges at a point, and all functions in the series are differentiable with a summable bound on the @@ -254,34 +253,33 @@ theorem contDiff_tsum_of_eventually (hf : ∀ i, ContDiff 𝕜 N (f i)) (h'f : ∀ k : ℕ, k ≤ N → ∀ᶠ i in (Filter.cofinite : Filter α), ∀ x : E, ‖iteratedFDeriv 𝕜 k (f i) x‖ ≤ v k i) : ContDiff 𝕜 N fun x => ∑' i, f i x := by - classical - refine contDiff_iff_forall_nat_le.2 fun m hm => ?_ - let t : Set α := - { i : α | ¬∀ k : ℕ, k ∈ Finset.range (m + 1) → ∀ x, ‖iteratedFDeriv 𝕜 k (f i) x‖ ≤ v k i } - have ht : Set.Finite t := - haveI A : - ∀ᶠ i in (Filter.cofinite : Filter α), - ∀ k : ℕ, k ∈ Finset.range (m + 1) → ∀ x : E, ‖iteratedFDeriv 𝕜 k (f i) x‖ ≤ v k i := by - rw [eventually_all_finset] - intro i hi - apply h'f - simp only [Finset.mem_range_succ_iff] at hi - exact (WithTop.coe_le_coe.2 hi).trans hm - eventually_cofinite.2 A - let T : Finset α := ht.toFinset - have : (fun x => ∑' i, f i x) = (fun x => ∑ i ∈ T, f i x) + - fun x => ∑' i : { i // i ∉ T }, f i x := by - ext1 x - refine (Summable.sum_add_tsum_subtype_compl ?_ T).symm - refine .of_norm_bounded_eventually (hv 0 zero_le) ?_ - filter_upwards [h'f 0 zero_le] with i hi - simpa only [norm_iteratedFDeriv_zero] using hi x - rw [this] - apply (ContDiff.sum fun i _ => (hf i).of_le (mod_cast hm)).add - have h'u : ∀ k : ℕ, (k : ℕ∞) ≤ m → Summable (v k ∘ ((↑) : { i // i ∉ T } → α)) := fun k hk => - (hv k (hk.trans hm)).subtype _ - refine contDiff_tsum (fun i => (hf i).of_le (mod_cast hm)) h'u ?_ - rintro k ⟨i, hi⟩ x hk - simp only [t, T, Finite.mem_toFinset, mem_setOf_eq, Finset.mem_range, not_forall, not_le, - exists_prop, not_exists, not_and, not_lt] at hi - exact hi k (Nat.lt_succ_iff.2 (WithTop.coe_le_coe.1 hk)) x + refine contDiff_iff_forall_nat_le.2 fun m hm => ?_ + let t : Set α := + { i : α | ¬∀ k : ℕ, k ∈ Finset.range (m + 1) → ∀ x, ‖iteratedFDeriv 𝕜 k (f i) x‖ ≤ v k i } + have ht : Set.Finite t := + haveI A : + ∀ᶠ i in (Filter.cofinite : Filter α), + ∀ k : ℕ, k ∈ Finset.range (m + 1) → ∀ x : E, ‖iteratedFDeriv 𝕜 k (f i) x‖ ≤ v k i := by + rw [eventually_all_finset] + intro i hi + apply h'f + simp only [Finset.mem_range_succ_iff] at hi + exact (WithTop.coe_le_coe.2 hi).trans hm + eventually_cofinite.2 A + let T : Finset α := ht.toFinset + have : (fun x => ∑' i, f i x) = (fun x => ∑ i ∈ T, f i x) + + fun x => ∑' i : { i // i ∉ T }, f i x := by + ext1 x + refine (Summable.sum_add_tsum_subtype_compl ?_ T).symm + refine .of_norm_bounded_eventually (hv 0 zero_le) ?_ + filter_upwards [h'f 0 zero_le] with i hi + simpa only [norm_iteratedFDeriv_zero] using hi x + rw [this] + apply (ContDiff.sum fun i _ => (hf i).of_le (mod_cast hm)).add + have h'u : ∀ k : ℕ, (k : ℕ∞) ≤ m → Summable (v k ∘ ((↑) : { i // i ∉ T } → α)) := fun k hk => + (hv k (hk.trans hm)).subtype _ + refine contDiff_tsum (fun i => (hf i).of_le (mod_cast hm)) h'u ?_ + rintro k ⟨i, hi⟩ x hk + simp only [t, T, Finite.mem_toFinset, mem_setOf_eq, Finset.mem_range, not_forall, not_le, + exists_prop, not_exists, not_and, not_lt] at hi + exact hi k (Nat.lt_succ_iff.2 (WithTop.coe_le_coe.1 hk)) x diff --git a/Mathlib/Analysis/Complex/CanonicalDecomposition.lean b/Mathlib/Analysis/Complex/CanonicalDecomposition.lean index c12b3682f64313..720009514bed75 100644 --- a/Mathlib/Analysis/Complex/CanonicalDecomposition.lean +++ b/Mathlib/Analysis/Complex/CanonicalDecomposition.lean @@ -245,7 +245,6 @@ structure CanonicalDecomp (f g : ℂ → E) (R : ℝ) : Prop where -- decomposition is meromorphic in normal form. private lemma canonicalDecomposition_aux₁ (F : locallyFinsuppWithin (ball (0 : ℂ) R) ℤ) : MeromorphicNFOn (∏ᶠ u, (canonicalFactor R u) ^ (F u)) (ball (0 : ℂ) R) := by - classical refine meromorphicNFOn_finprod (fun w ↦ ?_) fun z hz a ha b hb ↦ ?_ · by_cases hw : w ∈ ball 0 R · exact fun _ _ ↦ (meromorphicNFOn_canonicalFactor hw).zpow (by trivial) diff --git a/Mathlib/Analysis/Complex/LocallyUniformLimit.lean b/Mathlib/Analysis/Complex/LocallyUniformLimit.lean index dfc0c7acfda663..afc9908533c307 100644 --- a/Mathlib/Analysis/Complex/LocallyUniformLimit.lean +++ b/Mathlib/Analysis/Complex/LocallyUniformLimit.lean @@ -172,7 +172,6 @@ theorem differentiableOn_tsum_of_summable_norm {u : ι → ℝ} (hu : Summable u (hf : ∀ i : ι, DifferentiableOn ℂ (F i) U) (hU : IsOpen U) (hF_le : ∀ (i : ι) (w : ℂ), w ∈ U → ‖F i w‖ ≤ u i) : DifferentiableOn ℂ (fun w : ℂ => ∑' i : ι, F i w) U := by - classical have hc := (tendstoUniformlyOn_tsum hu hF_le).tendstoLocallyUniformlyOn refine hc.differentiableOn (Eventually.of_forall fun s => ?_) hU exact DifferentiableOn.fun_sum fun i _ => hf i diff --git a/Mathlib/Analysis/Complex/Polynomial/Basic.lean b/Mathlib/Analysis/Complex/Polynomial/Basic.lean index 7706f87cd22de0..8b927b0fe34b28 100644 --- a/Mathlib/Analysis/Complex/Polynomial/Basic.lean +++ b/Mathlib/Analysis/Complex/Polynomial/Basic.lean @@ -129,7 +129,6 @@ theorem galActionHom_bijective_of_prime_degree {p : ℚ[X]} (p_irr : Irreducible (p_deg : p.natDegree.Prime) (p_roots : Fintype.card (p.rootSet ℂ) = Fintype.card (p.rootSet ℝ) + 2) : Function.Bijective (galActionHom p ℂ) := by - classical have h1 : Fintype.card (p.rootSet ℂ) = p.natDegree := by simp_rw [rootSet_def, Finset.coe_sort_coe, Fintype.card_coe] rw [Multiset.toFinset_card_of_nodup, ← Splits.natDegree_eq_card_roots, natDegree_map] diff --git a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean index 4de3fb6b6928a1..acc488b6b18548 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean @@ -131,7 +131,6 @@ The logarithmic counting function of a singleton indicator is asymptotically equ @[simp] lemma logCounting_single_eq_log_sub_const [DecidableEq E] [ProperSpace E] {e : E} {r : ℝ} {n : ℤ} (hr : ‖e‖ ≤ r) : logCounting (single e n) r = n * (log r - log ‖e‖) := by - classical simp only [logCounting, AddMonoidHom.coe_mk, ZeroHom.coe_mk] rw [finsum_eq_sum_of_support_subset _ (s := (finite_singleton e).toFinset) (by simp_all [toClosedBall, restrict_apply, single_apply])] diff --git a/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean b/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean index 5401ae19c71739..7cc0c9435e4b17 100644 --- a/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean +++ b/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean @@ -148,7 +148,6 @@ by nonnegative factors rather than positive ones only. lemma exists_mem_doublyStochastic_eq_smul_iff {M : Matrix n n R} {s : R} (hs : 0 ≤ s) : (∃ M' ∈ doublyStochastic R n, M = s • M') ↔ (∀ i j, 0 ≤ M i j) ∧ (∀ i, ∑ j, M i j = s) ∧ (∀ j, ∑ i, M i j = s) := by - classical constructor case mp => rintro ⟨M', hM', rfl⟩ diff --git a/Mathlib/Analysis/Convex/Exposed.lean b/Mathlib/Analysis/Convex/Exposed.lean index e5ed0d20521fc7..66d569963faad9 100644 --- a/Mathlib/Analysis/Convex/Exposed.lean +++ b/Mathlib/Analysis/Convex/Exposed.lean @@ -139,7 +139,6 @@ protected theorem inter [IsOrderedRing 𝕜] [ContinuousAdd 𝕜] {A B C : Set E theorem sInter [IsOrderedRing 𝕜] [ContinuousAdd 𝕜] {F : Finset (Set E)} (hF : F.Nonempty) (hAF : ∀ B ∈ F, IsExposed 𝕜 A B) : IsExposed 𝕜 A (⋂₀ F) := by - classical induction F using Finset.induction with | empty => exfalso; exact Finset.not_nonempty_empty hF | insert C F _ hF' => diff --git a/Mathlib/Analysis/Convex/Visible.lean b/Mathlib/Analysis/Convex/Visible.lean index cb55a8b199a1bb..9d475f297a2126 100644 --- a/Mathlib/Analysis/Convex/Visible.lean +++ b/Mathlib/Analysis/Convex/Visible.lean @@ -146,7 +146,6 @@ Note that the converse does not hold. -/ lemma IsVisible.mem_convexHull_isVisible (hx : x ∉ convexHull ℝ s) (hy : y ∈ convexHull ℝ s) (hxy : IsVisible ℝ (convexHull ℝ s) x y) : y ∈ convexHull ℝ {z ∈ s | IsVisible ℝ (convexHull ℝ s) x z} := by - classical obtain ⟨ι, _, w, a, hw₀, hw₁, ha, rfl⟩ := mem_convexHull_iff_exists_fintype.1 hy rw [← Fintype.sum_subset (s := {i | w i ≠ 0}) fun i hi ↦ mem_filter.2 ⟨mem_univ _, left_ne_zero_of_smul hi⟩] diff --git a/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean b/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean index 8fe7870331546e..2eb54e2e982f78 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean @@ -237,7 +237,6 @@ adapted from the corresponding development of the theory of linearly independent variable (𝕜 E) theorem orthonormal_empty : Orthonormal 𝕜 (fun x => x : (∅ : Set E) → E) := by - classical simp variable {𝕜 E} @@ -329,7 +328,7 @@ theorem Orthonormal.mapLinearIsometryEquiv {v : Basis ι 𝕜 E} (hv : Orthonorm def LinearMap.isometryOfOrthonormal (f : E →ₗ[𝕜] E') {v : Basis ι 𝕜 E} (hv : Orthonormal 𝕜 v) (hf : Orthonormal 𝕜 (f ∘ v)) : E →ₗᵢ[𝕜] E' := f.isometryOfInner fun x y => by - classical rw [← v.linearCombination_repr x, ← v.linearCombination_repr y, + rw [← v.linearCombination_repr x, ← v.linearCombination_repr y, Finsupp.apply_linearCombination, Finsupp.apply_linearCombination, hv.inner_finsupp_eq_sum_left, hf.inner_finsupp_eq_sum_left] @@ -350,7 +349,7 @@ def LinearEquiv.isometryOfOrthonormal (f : E ≃ₗ[𝕜] E') {v : Basis ι 𝕜 (hf : Orthonormal 𝕜 (f ∘ v)) : E ≃ₗᵢ[𝕜] E' := f.isometryOfInner fun x y => by rw [← LinearEquiv.coe_coe] at hf - classical rw [← v.linearCombination_repr x, ← v.linearCombination_repr y, + rw [← v.linearCombination_repr x, ← v.linearCombination_repr y, ← LinearEquiv.coe_coe f, Finsupp.apply_linearCombination, Finsupp.apply_linearCombination, hv.inner_finsupp_eq_sum_left, hf.inner_finsupp_eq_sum_left] @@ -374,7 +373,7 @@ def Orthonormal.equiv {v : Basis ι 𝕜 E} (hv : Orthonormal 𝕜 v) {v' : Basi ext i simp rw [h] - classical exact hv'.comp _ e.injective) + exact hv'.comp _ e.injective) @[simp] theorem Orthonormal.equiv_toLinearEquiv {v : Basis ι 𝕜 E} (hv : Orthonormal 𝕜 v) @@ -437,7 +436,7 @@ theorem Orthonormal.sum_inner_products_le {s : Finset ι} (hv : Orthonormal 𝕜 ∑ i ∈ s, ‖⟪v i, x⟫‖ ^ 2 ≤ ‖x‖ ^ 2 := by have h₂ : (∑ i ∈ s, ∑ j ∈ s, ⟪v i, x⟫ * ⟪x, v j⟫ * ⟪v j, v i⟫) = (∑ k ∈ s, ⟪v k, x⟫ * ⟪x, v k⟫ : 𝕜) := by - classical exact hv.inner_left_right_finset + exact hv.inner_left_right_finset have h₃ : ∀ z : 𝕜, re (z * conj z) = ‖z‖ ^ 2 := by intro z simp only [mul_conj] diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 2e113640ce7dfe..2910dcb346427c 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -640,7 +640,7 @@ theorem _root_.Module.Basis.coe_toOrthonormalBasis (v : Basis ι 𝕜 E) (hv : O (v.toOrthonormalBasis hv : ι → E) = (v : ι → E) := calc (v.toOrthonormalBasis hv : ι → E) = ((v.toOrthonormalBasis hv).toBasis : ι → E) := by - classical rw [OrthonormalBasis.coe_toBasis] + rw [OrthonormalBasis.coe_toBasis] _ = (v : ι → E) := by simp section Singleton @@ -720,7 +720,7 @@ protected def mk (hon : Orthonormal 𝕜 v) (hsp : ⊤ ≤ Submodule.span 𝕜 ( @[simp] protected theorem coe_mk (hon : Orthonormal 𝕜 v) (hsp : ⊤ ≤ Submodule.span 𝕜 (Set.range v)) : ⇑(OrthonormalBasis.mk hon hsp) = v := by - classical rw [OrthonormalBasis.mk, _root_.Module.Basis.coe_toOrthonormalBasis, Basis.coe_mk] + rw [OrthonormalBasis.mk, _root_.Module.Basis.coe_toOrthonormalBasis, Basis.coe_mk] /-- Any finite subset of an orthonormal family is an `OrthonormalBasis` for its span. -/ protected def span [DecidableEq E] {v' : ι' → E} (h : Orthonormal 𝕜 v') (s : Finset ι') : @@ -793,7 +793,6 @@ protected theorem coe_reindex (b : OrthonormalBasis ι 𝕜 E) (e : ι ≃ ι') @[simp] protected theorem repr_reindex (b : OrthonormalBasis ι 𝕜 E) (e : ι ≃ ι') (x : E) (i' : ι') : (b.reindex e).repr x i' = b.repr x (e.symm i') := by - classical rw [OrthonormalBasis.repr_apply_apply, b.repr_apply_apply, OrthonormalBasis.coe_reindex, comp_apply] diff --git a/Mathlib/Analysis/InnerProductSpace/Positive.lean b/Mathlib/Analysis/InnerProductSpace/Positive.lean index db2e667423e284..d1897b0d8e8c05 100644 --- a/Mathlib/Analysis/InnerProductSpace/Positive.lean +++ b/Mathlib/Analysis/InnerProductSpace/Positive.lean @@ -242,7 +242,6 @@ theorem IsPositive.trace_nonneg {f : E →ₗ[𝕜] E} (hf : f.IsPositive) : 0 unfold trace split_ifs with h · have : FiniteDimensional 𝕜 E := Module.Finite.of_basis h.choose_spec.some - classical simp_rw [traceAux_eq 𝕜 _ (stdOrthonormalBasis 𝕜 E).toBasis] exact posSemidef_toMatrix_iff (stdOrthonormalBasis 𝕜 E) |>.mpr hf |>.trace_nonneg · simp diff --git a/Mathlib/Analysis/InnerProductSpace/l2Space.lean b/Mathlib/Analysis/InnerProductSpace/l2Space.lean index f91432211feb98..53d6ffa1a20e7e 100644 --- a/Mathlib/Analysis/InnerProductSpace/l2Space.lean +++ b/Mathlib/Analysis/InnerProductSpace/l2Space.lean @@ -192,15 +192,14 @@ protected def linearIsometry (hV : OrthogonalFamily 𝕜 G V) : lp G 2 →ₗᵢ simpa only [LinearIsometry.map_smul, Pi.smul_apply, lp.coeFn_smul] using! (hV.summable_of_lp f).tsum_const_smul c norm_map' f := by - classical - -- needed for lattice instance on `Finset ι`, for `Filter.atTop_neBot` - have H : 0 < (2 : ℝ≥0∞).toReal := by simp - suffices ‖∑' i : ι, V i (f i)‖ ^ (2 : ℝ≥0∞).toReal = ‖f‖ ^ (2 : ℝ≥0∞).toReal by - exact Real.rpow_left_injOn H.ne' (norm_nonneg _) (norm_nonneg _) this - refine tendsto_nhds_unique ?_ (lp.hasSum_norm H f) - convert! (hV.summable_of_lp f).hasSum.norm.rpow_const (Or.inr H.le) using 1 - ext s - exact mod_cast (hV.norm_sum f s).symm + -- needed for lattice instance on `Finset ι`, for `Filter.atTop_neBot` + have H : 0 < (2 : ℝ≥0∞).toReal := by simp + suffices ‖∑' i : ι, V i (f i)‖ ^ (2 : ℝ≥0∞).toReal = ‖f‖ ^ (2 : ℝ≥0∞).toReal by + exact Real.rpow_left_injOn H.ne' (norm_nonneg _) (norm_nonneg _) this + refine tendsto_nhds_unique ?_ (lp.hasSum_norm H f) + convert! (hV.summable_of_lp f).hasSum.norm.rpow_const (Or.inr H.le) using 1 + ext s + exact mod_cast (hV.norm_sum f s).symm protected theorem linearIsometry_apply (f : lp G 2) : hV.linearIsometry f = ∑' i, V i (f i) := rfl @@ -443,16 +442,15 @@ protected theorem hasSum_repr (b : HilbertBasis ι 𝕜 E) (x : E) : @[simp] protected theorem dense_span (b : HilbertBasis ι 𝕜 E) : (span 𝕜 (Set.range b)).topologicalClosure = ⊤ := by - classical - rw [eq_top_iff] - rintro x - - refine mem_closure_of_tendsto (b.hasSum_repr x) (Eventually.of_forall ?_) - intro s - simp only [SetLike.mem_coe] - refine sum_mem ?_ - rintro i - - refine smul_mem _ _ ?_ - exact subset_span ⟨i, rfl⟩ + rw [eq_top_iff] + rintro x - + refine mem_closure_of_tendsto (b.hasSum_repr x) (Eventually.of_forall ?_) + intro s + simp only [SetLike.mem_coe] + refine sum_mem ?_ + rintro i - + refine smul_mem _ _ ?_ + exact subset_span ⟨i, rfl⟩ protected theorem hasSum_inner_mul_inner (b : HilbertBasis ι 𝕜 E) (x y : E) : HasSum (fun i => ⟪x, b i⟫ * ⟪b i, y⟫) ⟪x, y⟫ := by diff --git a/Mathlib/Analysis/Matrix/Normed.lean b/Mathlib/Analysis/Matrix/Normed.lean index 758ea5e35b49d2..6e9886a3553119 100644 --- a/Mathlib/Analysis/Matrix/Normed.lean +++ b/Mathlib/Analysis/Matrix/Normed.lean @@ -438,7 +438,6 @@ lemma linfty_opNNNorm_eq_opNNNorm (A : Matrix m n α) : refine Finset.sup_le fun i _ => ?_ cases isEmpty_or_nonempty n · simp - classical let x : n → α := fun j => unitOf (A i j) have hxn : ‖x‖₊ = 1 := by simp_rw [x, Pi.nnnorm_def, norm_unitOf, Finset.sup_const Finset.univ_nonempty] diff --git a/Mathlib/Analysis/Meromorphic/Divisor.lean b/Mathlib/Analysis/Meromorphic/Divisor.lean index 9605d5ffb3dda6..7a06a36c8fab29 100644 --- a/Mathlib/Analysis/Meromorphic/Divisor.lean +++ b/Mathlib/Analysis/Meromorphic/Divisor.lean @@ -373,7 +373,6 @@ If `f` is meromorphic, then the divisor of `f ^ n` is `n` times the divisor of ` -/ theorem divisor_pow {f : 𝕜 → 𝕜} (hf : MeromorphicOn f U) (n : ℕ) : divisor (f ^ n) U = n • divisor f U := by - classical ext z by_cases hn : n = 0 · simp [hn] @@ -392,7 +391,6 @@ If `f` is meromorphic, then the divisor of `f ^ n` is `n` times the divisor of ` -/ theorem divisor_zpow {f : 𝕜 → 𝕜} (hf : MeromorphicOn f U) (n : ℤ) : divisor (f ^ n) U = n • divisor f U := by - classical ext z by_cases hn : n = 0 · simp [hn] diff --git a/Mathlib/Analysis/Normed/Affine/Convex.lean b/Mathlib/Analysis/Normed/Affine/Convex.lean index 16bebba8cb4ea2..0882cdd7029aa0 100644 --- a/Mathlib/Analysis/Normed/Affine/Convex.lean +++ b/Mathlib/Analysis/Normed/Affine/Convex.lean @@ -50,7 +50,6 @@ variable [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] {s lemma exists_mem_interior_convexHull_affineBasis (hs : s ∈ 𝓝 x) : ∃ b : AffineBasis (Fin (finrank ℝ E + 1)) ℝ E, x ∈ interior (convexHull ℝ (range b)) ∧ convexHull ℝ (range b) ⊆ s := by - classical -- By translating, WLOG `x` is the origin. wlog hx : x = 0 · obtain ⟨b, hb⟩ := this (s := -x +ᵥ s) (by simpa using vadd_mem_nhds_vadd (-x) hs) rfl diff --git a/Mathlib/Analysis/Normed/Group/FunctionSeries.lean b/Mathlib/Analysis/Normed/Group/FunctionSeries.lean index 4fcb532af051f8..b730d84a5c9bf6 100644 --- a/Mathlib/Analysis/Normed/Group/FunctionSeries.lean +++ b/Mathlib/Analysis/Normed/Group/FunctionSeries.lean @@ -115,10 +115,9 @@ function is. -/ theorem continuousOn_tsum [TopologicalSpace β] {f : α → β → F} {s : Set β} (hf : ∀ i, ContinuousOn (f i) s) (hu : Summable u) (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : ContinuousOn (fun x => ∑' n, f n x) s := by - classical - refine (tendstoUniformlyOn_tsum hu hfu).continuousOn (Frequently.of_forall ?_) - intro t - exact continuousOn_finsetSum _ fun i _ => hf i + refine (tendstoUniformlyOn_tsum hu hfu).continuousOn (Frequently.of_forall ?_) + intro t + exact continuousOn_finsetSum _ fun i _ => hf i /-- An infinite sum of functions with summable sup norm is continuous if each individual function is. -/ diff --git a/Mathlib/Analysis/Normed/Group/InfiniteSum.lean b/Mathlib/Analysis/Normed/Group/InfiniteSum.lean index 816bca12bd4191..885c2e0ee09e97 100644 --- a/Mathlib/Analysis/Normed/Group/InfiniteSum.lean +++ b/Mathlib/Analysis/Normed/Group/InfiniteSum.lean @@ -142,7 +142,7 @@ theorem tsum_of_norm_bounded {f : ι → E} {g : ι → ℝ} {a : ℝ} (hg : Has by_cases hf : Summable f · exact hf.hasSum.norm_le_of_bounded hg h · rw [tsum_eq_zero_of_not_summable hf, norm_zero] - classical exact ge_of_tendsto' hg fun s => sum_nonneg fun i _hi => (norm_nonneg _).trans (h i) + exact ge_of_tendsto' hg fun s => sum_nonneg fun i _hi => (norm_nonneg _).trans (h i) /-- If `∑' i, ‖f i‖` is summable, then `‖∑' i, f i‖ ≤ (∑' i, ‖f i‖)`. Note that we do not assume that `∑' i, f i` is summable, and it might not be the case if `α` is not a complete space. -/ diff --git a/Mathlib/Analysis/Normed/Group/Tannery.lean b/Mathlib/Analysis/Normed/Group/Tannery.lean index 1fe465166b641a..3fd5661a00f984 100644 --- a/Mathlib/Analysis/Normed/Group/Tannery.lean +++ b/Mathlib/Analysis/Normed/Group/Tannery.lean @@ -63,7 +63,7 @@ lemma tendsto_tsum_of_dominated_convergence {α β G : Type*} {𝓕 : Filter α} let ⟨S, hS⟩ := h_sum obtain ⟨T, hT⟩ : ∃ (T : Finset β), dist (∑ b ∈ T, bound b) S < ε / 3 := by rw [HasSum, Metric.tendsto_nhds] at hS - classical exact Eventually.exists <| hS _ (by positivity) + exact Eventually.exists <| hS _ (by positivity) have h1 : ∑' (k : (Tᶜ : Set β)), bound k < ε / 3 := by calc _ ≤ ‖∑' (k : (Tᶜ : Set β)), bound k‖ := Real.le_norm_self _ _ = ‖S - ∑ b ∈ T, bound b‖ := congrArg _ ?_ diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 3e83aac3ee4109..bd2b72533cfd35 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -218,7 +218,6 @@ theorem prod_edist_self (f : WithLp p (α × β)) : edist f f = 0 := by This holds independent of `p` and does not require `[Fact (1 ≤ p)]`. We keep it separate from `WithLp.instProdPseudoEMetricSpace` so it can be used also for `p < 1`. -/ theorem prod_edist_comm (f g : WithLp p (α × β)) : edist f g = edist g f := by - classical rcases p.trichotomy with (rfl | rfl | h) · simp only [prod_edist_eq_card, edist_comm] · simp only [prod_edist_eq_sup, edist_comm] diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index e3ecc77a6213e8..65fc57d804ecf6 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -1199,7 +1199,6 @@ theorem ext_continuousAddMonoidHom f.comp (singleContinuousAddMonoidHom E p i) = g.comp (singleContinuousAddMonoidHom E p i)) : f = g := by ext x - classical have := lp.hasSum_single hp x rw [← (this.map f f.continuous).tsum_eq, ← (this.map g g.continuous).tsum_eq] congr! 2 with i diff --git a/Mathlib/Analysis/Normed/Module/RieszLemma.lean b/Mathlib/Analysis/Normed/Module/RieszLemma.lean index 2344fefa388518..5e1c8155be7138 100644 --- a/Mathlib/Analysis/Normed/Module/RieszLemma.lean +++ b/Mathlib/Analysis/Normed/Module/RieszLemma.lean @@ -48,34 +48,33 @@ exactly one assuming stronger assumptions on the underlying field, see `riesz_lemma_of_lt_one`. -/ theorem riesz_lemma {F : Subspace 𝕜 E} (hFc : IsClosed (F : Set E)) (hF : ∃ x : E, x ∉ F) {r : ℝ} (hr : r < 1) : ∃ x₀ : E, x₀ ∉ F ∧ ∀ y ∈ F, r * ‖x₀‖ ≤ ‖x₀ - y‖ := by - classical - obtain ⟨x, hx⟩ : ∃ x : E, x ∉ F := hF - let d := Metric.infDist x F - have hFn : (F : Set E).Nonempty := ⟨_, F.zero_mem⟩ - have hdp : 0 < d := - lt_of_le_of_ne Metric.infDist_nonneg fun heq => - hx ((hFc.mem_iff_infDist_zero hFn).2 heq.symm) - let r' := max r 2⁻¹ - have hr' : r' < 1 := by - simp only [r', max_lt_iff, hr, true_and] - norm_num - have hlt : 0 < r' := lt_of_lt_of_le (by simp) (le_max_right r 2⁻¹) - have hdlt : d < d / r' := (lt_div_iff₀ hlt).mpr ((mul_lt_iff_lt_one_right hdp).2 hr') - obtain ⟨y₀, hy₀F, hxy₀⟩ : ∃ y ∈ F, dist x y < d / r' := (Metric.infDist_lt_iff hFn).mp hdlt - have x_ne_y₀ : x - y₀ ∉ F := by - by_contra h - have : x - y₀ + y₀ ∈ F := F.add_mem h hy₀F - simp only [neg_add_cancel_right, sub_eq_add_neg] at this - exact hx this - refine ⟨x - y₀, x_ne_y₀, fun y hy => le_of_lt ?_⟩ - have hy₀y : y₀ + y ∈ F := F.add_mem hy₀F hy - calc - r * ‖x - y₀‖ ≤ r' * ‖x - y₀‖ := by gcongr; apply le_max_left - _ < d := by - rw [← dist_eq_norm] - exact (lt_div_iff₀' hlt).1 hxy₀ - _ ≤ dist x (y₀ + y) := Metric.infDist_le_dist_of_mem hy₀y - _ = ‖x - y₀ - y‖ := by rw [sub_sub, dist_eq_norm] + obtain ⟨x, hx⟩ : ∃ x : E, x ∉ F := hF + let d := Metric.infDist x F + have hFn : (F : Set E).Nonempty := ⟨_, F.zero_mem⟩ + have hdp : 0 < d := + lt_of_le_of_ne Metric.infDist_nonneg fun heq => + hx ((hFc.mem_iff_infDist_zero hFn).2 heq.symm) + let r' := max r 2⁻¹ + have hr' : r' < 1 := by + simp only [r', max_lt_iff, hr, true_and] + norm_num + have hlt : 0 < r' := lt_of_lt_of_le (by simp) (le_max_right r 2⁻¹) + have hdlt : d < d / r' := (lt_div_iff₀ hlt).mpr ((mul_lt_iff_lt_one_right hdp).2 hr') + obtain ⟨y₀, hy₀F, hxy₀⟩ : ∃ y ∈ F, dist x y < d / r' := (Metric.infDist_lt_iff hFn).mp hdlt + have x_ne_y₀ : x - y₀ ∉ F := by + by_contra h + have : x - y₀ + y₀ ∈ F := F.add_mem h hy₀F + simp only [neg_add_cancel_right, sub_eq_add_neg] at this + exact hx this + refine ⟨x - y₀, x_ne_y₀, fun y hy => le_of_lt ?_⟩ + have hy₀y : y₀ + y ∈ F := F.add_mem hy₀F hy + calc + r * ‖x - y₀‖ ≤ r' * ‖x - y₀‖ := by gcongr; apply le_max_left + _ < d := by + rw [← dist_eq_norm] + exact (lt_div_iff₀' hlt).1 hxy₀ + _ ≤ dist x (y₀ + y) := Metric.infDist_le_dist_of_mem hy₀y + _ = ‖x - y₀ - y‖ := by rw [sub_sub, dist_eq_norm] /-- A version of Riesz lemma: given a strict closed subspace `F`, one may find an element of norm `≤ R` diff --git a/Mathlib/Analysis/Real/Hyperreal.lean b/Mathlib/Analysis/Real/Hyperreal.lean index ca05db1a5571ab..7ad28f7837eb2e 100644 --- a/Mathlib/Analysis/Real/Hyperreal.lean +++ b/Mathlib/Analysis/Real/Hyperreal.lean @@ -809,7 +809,6 @@ theorem st_add {x y : ℝ*} (hx : ¬Infinite x) (hy : ¬Infinite y) : st (x + y) @[deprecated stdPart_neg (since := "2026-01-05")] theorem st_neg (x : ℝ*) : st (-x) = -st x := by - classical by_cases h : Infinite x · rw [h.st_eq, (infinite_neg.2 h).st_eq, neg_zero] · exact (isSt_st' (not_infinite_neg h)).unique (isSt_st' h).neg diff --git a/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean b/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean index bb51c4a2f23b3b..8b2d183efed400 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean @@ -122,7 +122,7 @@ open CoproductsFromFiniteFiltered theorem hasCoproducts_of_finite_and_filtered [HasFiniteCoproducts C] [HasFilteredColimitsOfSize.{w, w} C] : HasCoproducts.{w} C := fun α => by - classical exact ⟨fun F => HasColimit.mk (liftToFinsetColimitCocone F)⟩ + exact ⟨fun F => HasColimit.mk (liftToFinsetColimitCocone F)⟩ theorem has_colimits_of_finite_and_filtered [HasFiniteColimits C] [HasFilteredColimitsOfSize.{w, w} C] : HasColimitsOfSize.{w, w} C := diff --git a/Mathlib/CategoryTheory/Limits/SmallComplete.lean b/Mathlib/CategoryTheory/Limits/SmallComplete.lean index 81b4bed8cd1f05..bf2f8812aee070 100644 --- a/Mathlib/CategoryTheory/Limits/SmallComplete.lean +++ b/Mathlib/CategoryTheory/Limits/SmallComplete.lean @@ -48,33 +48,32 @@ rather than providing a `Preorder C` instance. -/ instance (priority := 100) : Quiver.IsThin C := fun X Y => ⟨fun r s => by - classical - by_contra r_ne_s - have z : (2 : Cardinal) ≤ #(X ⟶ Y) := by - rw [Cardinal.two_le_iff] - exact ⟨_, _, r_ne_s⟩ - let md := Σ Z W : C, Z ⟶ W - let α := #md - apply not_le_of_gt (Cardinal.cantor α) - let yp : C := ∏ᶜ fun _ : md => Y - apply _root_.trans _ _ - · exact #(X ⟶ yp) - · apply le_trans (Cardinal.power_le_power_right z) - rw [Cardinal.power_def] - apply le_of_eq - rw [Cardinal.eq] - refine ⟨⟨Pi.lift, fun f k => f ≫ Pi.π _ k, ?_, ?_⟩⟩ - · intro f - ext k - simp [yp] - · intro f - ext ⟨j⟩ - simp [yp] - · apply Cardinal.mk_le_of_injective _ - · intro f - exact ⟨_, _, f⟩ - · rintro f g k - cases k - rfl⟩ + by_contra r_ne_s + have z : (2 : Cardinal) ≤ #(X ⟶ Y) := by + rw [Cardinal.two_le_iff] + exact ⟨_, _, r_ne_s⟩ + let md := Σ Z W : C, Z ⟶ W + let α := #md + apply not_le_of_gt (Cardinal.cantor α) + let yp : C := ∏ᶜ fun _ : md => Y + apply _root_.trans _ _ + · exact #(X ⟶ yp) + · apply le_trans (Cardinal.power_le_power_right z) + rw [Cardinal.power_def] + apply le_of_eq + rw [Cardinal.eq] + refine ⟨⟨Pi.lift, fun f k => f ≫ Pi.π _ k, ?_, ?_⟩⟩ + · intro f + ext k + simp [yp] + · intro f + ext ⟨j⟩ + simp [yp] + · apply Cardinal.mk_le_of_injective _ + · intro f + exact ⟨_, _, f⟩ + · rintro f g k + cases k + rfl⟩ end CategoryTheory diff --git a/Mathlib/CategoryTheory/Monoidal/Preadditive.lean b/Mathlib/CategoryTheory/Monoidal/Preadditive.lean index 4f624b65b13564..e50a926ce756c8 100644 --- a/Mathlib/CategoryTheory/Monoidal/Preadditive.lean +++ b/Mathlib/CategoryTheory/Monoidal/Preadditive.lean @@ -310,7 +310,6 @@ theorem leftDistributor_rightDistributor_assoc {J : Type _} [Finite J] @[ext] theorem leftDistributor_ext_left {J : Type} [Finite J] {X Y : C} {f : J → C} {g h : X ⊗ ⨁ f ⟶ Y} (w : ∀ j, (X ◁ biproduct.ι f j) ≫ g = (X ◁ biproduct.ι f j) ≫ h) : g = h := by - classical cases nonempty_fintype J apply (cancel_epi (leftDistributor X f).inv).mp ext @@ -319,7 +318,6 @@ theorem leftDistributor_ext_left {J : Type} [Finite J] {X Y : C} {f : J → C} { @[ext] theorem leftDistributor_ext_right {J : Type} [Finite J] {X Y : C} {f : J → C} {g h : X ⟶ Y ⊗ ⨁ f} (w : ∀ j, g ≫ (Y ◁ biproduct.π f j) = h ≫ (Y ◁ biproduct.π f j)) : g = h := by - classical cases nonempty_fintype J apply (cancel_mono (leftDistributor Y f).hom).mp ext @@ -349,7 +347,6 @@ theorem leftDistributor_ext₂_right {J : Type} [Finite J] theorem rightDistributor_ext_left {J : Type} [Finite J] {f : J → C} {X Y : C} {g h : (⨁ f) ⊗ X ⟶ Y} (w : ∀ j, (biproduct.ι f j ▷ X) ≫ g = (biproduct.ι f j ▷ X) ≫ h) : g = h := by - classical cases nonempty_fintype J apply (cancel_epi (rightDistributor f X).inv).mp ext @@ -359,7 +356,6 @@ theorem rightDistributor_ext_left {J : Type} [Finite J] theorem rightDistributor_ext_right {J : Type} [Finite J] {f : J → C} {X Y : C} {g h : X ⟶ (⨁ f) ⊗ Y} (w : ∀ j, g ≫ (biproduct.π f j ▷ Y) = h ≫ (biproduct.π f j ▷ Y)) : g = h := by - classical cases nonempty_fintype J apply (cancel_mono (rightDistributor f Y).hom).mp ext diff --git a/Mathlib/CategoryTheory/Preadditive/Schur.lean b/Mathlib/CategoryTheory/Preadditive/Schur.lean index 3f7acddcd52ef2..99e8ea153c16f2 100644 --- a/Mathlib/CategoryTheory/Preadditive/Schur.lean +++ b/Mathlib/CategoryTheory/Preadditive/Schur.lean @@ -139,7 +139,7 @@ This can't be an instance as `𝕜` would be undetermined. @[implicit_reducible] noncomputable def fieldEndOfFiniteDimensional (X : C) [Simple X] [I : FiniteDimensional 𝕜 (X ⟶ X)] : Field (End X) := by - classical exact + exact { (inferInstance : DivisionRing (End X)) with mul_comm := fun f g => by obtain ⟨c, rfl⟩ := endomorphism_simple_eq_smul_id 𝕜 f diff --git a/Mathlib/CategoryTheory/Simple.lean b/Mathlib/CategoryTheory/Simple.lean index 0db17621155756..f2f3980aba8971 100644 --- a/Mathlib/CategoryTheory/Simple.lean +++ b/Mathlib/CategoryTheory/Simple.lean @@ -100,10 +100,9 @@ theorem simple_obj_iff {D : Type*} [Category* D] [HasZeroMorphisms D] (F : C ⥤ theorem kernel_zero_of_nonzero_from_simple {X Y : C} [Simple X] {f : X ⟶ Y} [HasKernel f] (w : f ≠ 0) : kernel.ι f = 0 := by - classical - by_contra h - have := isIso_of_mono_of_nonzero h - exact w (eq_zero_of_epi_kernel f) + by_contra h + have := isIso_of_mono_of_nonzero h + exact w (eq_zero_of_epi_kernel f) -- See also `mono_of_nonzero_from_simple`, which requires `Preadditive C`. /-- A nonzero morphism `f` to a simple object is an epimorphism @@ -117,9 +116,8 @@ theorem epi_of_nonzero_to_simple [HasEqualizers C] {X Y : C} [Simple Y] {f : X theorem mono_to_simple_zero_of_not_iso {X Y : C} [Simple Y] {f : X ⟶ Y} [Mono f] (w : IsIso f → False) : f = 0 := by - classical - by_contra h - exact w (isIso_of_mono_of_nonzero h) + by_contra h + exact w (isIso_of_mono_of_nonzero h) theorem id_nonzero (X : C) [Simple.{v} X] : 𝟙 X ≠ 0 := (Simple.mono_isIso_iff_nonzero (𝟙 X)).mp (by infer_instance) @@ -156,18 +154,17 @@ simple. -/ theorem simple_of_cosimple (X : C) (h : ∀ {Z : C} (f : X ⟶ Z) [Epi f], IsIso f ↔ f ≠ 0) : Simple X := ⟨fun {Y} f I => by - classical - fconstructor - · intros - have hx := cokernel.π_of_epi f - by_contra h - subst h - exact (h _).mp inferInstance hx - · intro hf - suffices Epi f by exact isIso_of_mono_of_epi _ - apply Preadditive.epi_of_cokernel_zero - by_contra h' - exact cokernel_not_iso_of_nonzero hf ((h _).mpr h')⟩ + fconstructor + · intros + have hx := cokernel.π_of_epi f + by_contra h + subst h + exact (h _).mp inferInstance hx + · intro hf + suffices Epi f by exact isIso_of_mono_of_epi _ + apply Preadditive.epi_of_cokernel_zero + by_contra h' + exact cokernel_not_iso_of_nonzero hf ((h _).mpr h')⟩ /-- A nonzero epimorphism from a simple object is an isomorphism. -/ theorem isIso_of_epi_of_nonzero {X Y : C} [Simple X] {f : X ⟶ Y} [Epi f] (w : f ≠ 0) : IsIso f := @@ -178,16 +175,14 @@ theorem isIso_of_epi_of_nonzero {X Y : C} [Simple X] {f : X ⟶ Y} [Epi f] (w : theorem cokernel_zero_of_nonzero_to_simple {X Y : C} [Simple Y] {f : X ⟶ Y} (w : f ≠ 0) : cokernel.π f = 0 := by - classical - by_contra h - have := isIso_of_epi_of_nonzero h - exact w (eq_zero_of_mono_cokernel f) + by_contra h + have := isIso_of_epi_of_nonzero h + exact w (eq_zero_of_mono_cokernel f) theorem epi_from_simple_zero_of_not_iso {X Y : C} [Simple X] {f : X ⟶ Y} [Epi f] (w : IsIso f → False) : f = 0 := by - classical - by_contra h - exact w (isIso_of_epi_of_nonzero h) + by_contra h + exact w (isIso_of_epi_of_nonzero h) end Abelian diff --git a/Mathlib/Combinatorics/Additive/VerySmallDoubling.lean b/Mathlib/Combinatorics/Additive/VerySmallDoubling.lean index d346c090e13132..05f426f3533afc 100644 --- a/Mathlib/Combinatorics/Additive/VerySmallDoubling.lean +++ b/Mathlib/Combinatorics/Additive/VerySmallDoubling.lean @@ -380,7 +380,6 @@ theorem doubling_lt_golden_ratio (hK₁ : 1 < K) (hKφ : K < φ) (hA₁ : #(A⁻¹ * A) ≤ K * #A) (hA₂ : #(A * A⁻¹) ≤ K * #A) : ∃ (H : Subgroup G) (_ : Fintype H) (Z : Finset G), #Z ≤ (2 - K) * K / ((φ - K) * (K - ψ)) ∧ (H : Set G) * Z = A * A⁻¹ := by - classical -- Some useful initial calculations have K_pos : 0 < K := by positivity have hK₀ : 0 < K := by positivity diff --git a/Mathlib/Combinatorics/Colex.lean b/Mathlib/Combinatorics/Colex.lean index 6daa6f3a5eb2f8..f9ef6177af7229 100644 --- a/Mathlib/Combinatorics/Colex.lean +++ b/Mathlib/Combinatorics/Colex.lean @@ -254,7 +254,6 @@ lemma erase_le_erase (ha : a ∈ s) (hb : b ∈ s) : toColex (s.erase a) ≤ toColex (s.erase b) ↔ b ≤ a := by obtain rfl | hab := eq_or_ne a b · simp - classical rw [← toColex_sdiff_le_toColex_sdiff', erase_sdiff_erase hab hb, erase_sdiff_erase hab.symm ha, singleton_le_singleton] @@ -269,7 +268,6 @@ variable [LinearOrder α] [LinearOrder β] {f : α → β} {𝒜 𝒜₁ 𝒜₂ instance instLinearOrder : LinearOrder (Colex (Finset α)) where le_total s t := by - classical obtain rfl | hts := eq_or_ne t s · simp have ⟨a, ha, hamax⟩ := exists_max_image _ id @@ -430,7 +428,6 @@ def IsInitSeg (𝒜 : Finset (Finset α)) (r : ℕ) : Prop := /-- Initial segments are nested in some way. In particular, if they're the same size they're equal. -/ lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by - classical simp_rw [← sdiff_eq_empty_iff_subset] by_contra! h have ⟨⟨s, hs⟩, t, ht⟩ := h diff --git a/Mathlib/Combinatorics/Configuration.lean b/Mathlib/Combinatorics/Configuration.lean index 84b4579c6b7d35..10a17ddcfae1a2 100644 --- a/Mathlib/Combinatorics/Configuration.lean +++ b/Mathlib/Combinatorics/Configuration.lean @@ -244,11 +244,10 @@ variable {P L} theorem HasLines.exists_bijective_of_card_eq [HasLines P L] [Fintype P] [Fintype L] (h : Fintype.card P = Fintype.card L) : ∃ f : L → P, Function.Bijective f ∧ ∀ l, pointCount P l = lineCount L (f l) := by - classical - obtain ⟨f, hf1, hf2⟩ := Nondegenerate.exists_injective_of_card_le (ge_of_eq h) - have hf3 := (Fintype.bijective_iff_injective_and_card f).mpr ⟨hf1, h.symm⟩ - exact ⟨f, hf3, fun l ↦ (sum_eq_sum_iff_of_le fun l _ ↦ pointCount_le_lineCount (hf2 l)).1 - ((hf3.sum_comp _).trans (sum_lineCount_eq_sum_pointCount P L)).symm _ <| mem_univ _⟩ + obtain ⟨f, hf1, hf2⟩ := Nondegenerate.exists_injective_of_card_le (ge_of_eq h) + have hf3 := (Fintype.bijective_iff_injective_and_card f).mpr ⟨hf1, h.symm⟩ + exact ⟨f, hf3, fun l ↦ (sum_eq_sum_iff_of_le fun l _ ↦ pointCount_le_lineCount (hf2 l)).1 + ((hf3.sum_comp _).trans (sum_lineCount_eq_sum_pointCount P L)).symm _ <| mem_univ _⟩ theorem HasLines.lineCount_eq_pointCount [HasLines P L] [Fintype P] [Fintype L] (hPL : Fintype.card P = Fintype.card L) {p : P} {l : L} (hpl : p ∉ l) : @@ -399,12 +398,11 @@ theorem Dual.order [Finite P] [Finite L] : order (Dual L) (Dual P) = order P L : variable {P} theorem lineCount_eq [Finite P] [Finite L] (p : P) : lineCount L p = order P L + 1 := by - classical - obtain ⟨q, -, -, l, -, -, -, -, h, -⟩ := Classical.choose_spec (@exists_config P L _ _) - cases nonempty_fintype { l : L // q ∈ l } - rw [order, lineCount_eq_lineCount L p q, lineCount_eq_lineCount L (Classical.choose _) q, - lineCount, Nat.card_eq_fintype_card, Nat.sub_add_cancel] - exact Fintype.card_pos_iff.mpr ⟨⟨l, h⟩⟩ + obtain ⟨q, -, -, l, -, -, -, -, h, -⟩ := Classical.choose_spec (@exists_config P L _ _) + cases nonempty_fintype { l : L // q ∈ l } + rw [order, lineCount_eq_lineCount L p q, lineCount_eq_lineCount L (Classical.choose _) q, + lineCount, Nat.card_eq_fintype_card, Nat.sub_add_cancel] + exact Fintype.card_pos_iff.mpr ⟨⟨l, h⟩⟩ variable (P) {L} diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index 3df41fcd21e06d..c5be665c6a8b7c 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -370,19 +370,18 @@ theorem mem_range_embedding_iff {j : Fin n} {i : Fin c.length} : /-- The embeddings of different blocks of a composition are disjoint. -/ theorem disjoint_range {i₁ i₂ : Fin c.length} (h : i₁ ≠ i₂) : Disjoint (Set.range (c.embedding i₁)) (Set.range (c.embedding i₂)) := by - classical - wlog h' : i₁ < i₂ - · exact (this c h.symm (h.lt_or_gt.resolve_left h')).symm - by_contra d - obtain ⟨x, hx₁, hx₂⟩ : - ∃ x : Fin n, x ∈ Set.range (c.embedding i₁) ∧ x ∈ Set.range (c.embedding i₂) := - Set.not_disjoint_iff.1 d - have A : (i₁ : ℕ).succ ≤ i₂ := Nat.succ_le_of_lt h' - apply lt_irrefl (x : ℕ) - calc - (x : ℕ) < c.sizeUpTo (i₁ : ℕ).succ := (c.mem_range_embedding_iff.1 hx₁).2 - _ ≤ c.sizeUpTo (i₂ : ℕ) := monotone_sum_take _ A - _ ≤ x := (c.mem_range_embedding_iff.1 hx₂).1 + wlog h' : i₁ < i₂ + · exact (this c h.symm (h.lt_or_gt.resolve_left h')).symm + by_contra d + obtain ⟨x, hx₁, hx₂⟩ : + ∃ x : Fin n, x ∈ Set.range (c.embedding i₁) ∧ x ∈ Set.range (c.embedding i₂) := + Set.not_disjoint_iff.1 d + have A : (i₁ : ℕ).succ ≤ i₂ := Nat.succ_le_of_lt h' + apply lt_irrefl (x : ℕ) + calc + (x : ℕ) < c.sizeUpTo (i₁ : ℕ).succ := (c.mem_range_embedding_iff.1 hx₁).2 + _ ≤ c.sizeUpTo (i₂ : ℕ) := monotone_sum_take _ A + _ ≤ x := (c.mem_range_embedding_iff.1 hx₂).1 theorem mem_range_embedding (j : Fin n) : j ∈ Set.range (c.embedding (c.index j)) := by have : c.embedding (c.index j) (c.invEmbedding j) ∈ Set.range (c.embedding (c.index j)) := diff --git a/Mathlib/Combinatorics/Matroid/Map.lean b/Mathlib/Combinatorics/Matroid/Map.lean index 8231123b3060a9..826d4ae508088f 100644 --- a/Mathlib/Combinatorics/Matroid/Map.lean +++ b/Mathlib/Combinatorics/Matroid/Map.lean @@ -296,7 +296,6 @@ def mapSetEmbedding (M : Matroid α) (f : M.E ↪ β) : Matroid β := Matroid.of (E := range f) (Indep := fun I ↦ M.Indep ↑(f ⁻¹' I) ∧ I ⊆ range f) (hM := by - classical obtain (rfl | ⟨⟨e, he⟩⟩) := eq_emptyOn_or_nonempty M · refine ⟨emptyOn β, ?_⟩ simp only [emptyOn_ground] at f diff --git a/Mathlib/Combinatorics/Nullstellensatz.lean b/Mathlib/Combinatorics/Nullstellensatz.lean index 5fc5d84d50ed2a..8e021845269d62 100644 --- a/Mathlib/Combinatorics/Nullstellensatz.lean +++ b/Mathlib/Combinatorics/Nullstellensatz.lean @@ -77,7 +77,6 @@ theorem eq_zero_of_eval_zero_at_prod_finset {σ : Type*} [Finite σ] [IsDomain R rwa [← RingHom.mem_ker, that] at this apply h _ (fun i ↦ S (e i)) · intro i - classical convert! Hdeg (e i) conv_lhs => rw [← e.symm_apply_apply i, degreeOf_rename_of_injective e.symm.injective] · intro x hx @@ -245,7 +244,6 @@ theorem combinatorial_nullstellensatz_exists_eval_nonzero [IsDomain R] (S : σ → Finset R) (htS : ∀ i, t i < #(S i)) : ∃ s : σ → R, (∀ i, s i ∈ S i) ∧ eval s f ≠ 0 := by let _ : LinearOrder σ := WellOrderingRel.isWellOrder.linearOrder - classical by_contra! Heval apply ht obtain ⟨h, hh, hf⟩ := combinatorial_nullstellensatz_exists_linearCombination S diff --git a/Mathlib/Combinatorics/Quiver/Path/Decomposition.lean b/Mathlib/Combinatorics/Quiver/Path/Decomposition.lean index bb39bae6a0b7b3..89617502949f63 100644 --- a/Mathlib/Combinatorics/Quiver/Path/Decomposition.lean +++ b/Mathlib/Combinatorics/Quiver/Path/Decomposition.lean @@ -47,7 +47,6 @@ theorem exists_mem_notMem_hom_path_path_of_notMem_mem {a b : V} (p : Path a b) ( (ha_in_S : a ∈ S) (hb_not_in_S : b ∉ S) : ∃ᵉ (u ∈ S) (v ∉ S) (e : u ⟶ v) (p₁ : Path a u) (p₂ : Path v b), p = p₁.comp (e.toPath.comp p₂) := by - classical have ha_not_in_compl : a ∉ Sᶜ := by simpa have hb_in_compl : b ∈ Sᶜ := by simpa obtain ⟨u, hu_not_in_compl, v, hv_in_compl, e, p₁, p₂, hp⟩ := diff --git a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean index 5976608d493bb9..4faef45cf644f4 100644 --- a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean +++ b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean @@ -321,7 +321,6 @@ lemma four_functions_theorem [DecidableEq α] (h₁ : 0 ≤ f₁) (h₂ : 0 ≤ · simpa only [← hs', ← ht', ← map_sups, ← map_infs, sum_map, Embedding.coeFn_mk, hg.extend_apply] using! this rintro s t - classical obtain ⟨a, rfl⟩ | hs := em (∃ a, g a = s) · obtain ⟨b, rfl⟩ | ht := em (∃ b, g b = t) · simp_rw [← sup_eq_union, ← inf_eq_inter, ← map_sup, ← map_inf, hg.extend_apply] diff --git a/Mathlib/Combinatorics/SetFamily/Intersecting.lean b/Mathlib/Combinatorics/SetFamily/Intersecting.lean index fcf04bb181a71d..7257221797d71d 100644 --- a/Mathlib/Combinatorics/SetFamily/Intersecting.lean +++ b/Mathlib/Combinatorics/SetFamily/Intersecting.lean @@ -104,12 +104,11 @@ theorem intersecting_iff_eq_empty_of_subsingleton [Subsingleton α] (s : Set α) /-- Maximal intersecting families are upper sets. -/ protected theorem Intersecting.isUpperSet (hs : s.Intersecting) (h : ∀ t : Set α, t.Intersecting → s ⊆ t → s = t) : IsUpperSet s := by - classical - rintro a b hab ha - rw [h (Insert.insert b s) _ (subset_insert _ _)] - · exact mem_insert _ _ - exact - hs.insert (mt (eq_bot_mono hab) <| hs.ne_bot ha) fun c hc hbc => hs ha hc <| hbc.mono_left hab + rintro a b hab ha + rw [h (Insert.insert b s) _ (subset_insert _ _)] + · exact mem_insert _ _ + exact + hs.insert (mt (eq_bot_mono hab) <| hs.ne_bot ha) fun c hc hbc => hs ha hc <| hbc.mono_left hab /-- Maximal intersecting families are upper sets. Finset version. -/ theorem Intersecting.isUpperSet' {s : Finset α} (hs : (s : Set α).Intersecting) @@ -153,9 +152,8 @@ theorem Intersecting.disjoint_map_compl {s : Finset α} (hs : (s : Set α).Inter theorem Intersecting.card_le [Fintype α] {s : Finset α} (hs : (s : Set α).Intersecting) : 2 * #s ≤ Fintype.card α := by - classical - refine (s.disjUnion _ hs.disjoint_map_compl).card_le_univ.trans_eq' ?_ - rw [Nat.two_mul, card_disjUnion, card_map] + refine (s.disjUnion _ hs.disjoint_map_compl).card_le_univ.trans_eq' ?_ + rw [Nat.two_mul, card_disjUnion, card_map] variable [Nontrivial α] [Fintype α] {s : Finset α} diff --git a/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean b/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean index fdd7d3948251ce..73bba052f953eb 100644 --- a/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean +++ b/Mathlib/Combinatorics/SimpleGraph/DegreeSum.lean @@ -125,19 +125,18 @@ end DegreeSum /-- The handshaking lemma. See also `SimpleGraph.sum_degrees_eq_twice_card_edges`. -/ theorem even_card_odd_degree_vertices [Fintype V] [DecidableRel G.Adj] : Even #{v | Odd (G.degree v)} := by - classical - have h := congr_arg (fun n => ↑n : ℕ → ZMod 2) G.sum_degrees_eq_twice_card_edges - simp only [ZMod.natCast_self, zero_mul, Nat.cast_mul] at h - rw [Nat.cast_sum, ← sum_filter_ne_zero] at h - rw [sum_congr (g := fun _v ↦ (1 : ZMod 2)) rfl] at h - · simp only [mul_one, nsmul_eq_mul, sum_const, Ne] at h - rw [← ZMod.natCast_eq_zero_iff_even] - convert! h - exact ZMod.natCast_ne_zero_iff_odd.symm - · intro v - rw [mem_filter_univ, Ne, ZMod.natCast_eq_zero_iff_even, ZMod.natCast_eq_one_iff_odd, - ← Nat.not_even_iff_odd] - tauto + have h := congr_arg (fun n => ↑n : ℕ → ZMod 2) G.sum_degrees_eq_twice_card_edges + simp only [ZMod.natCast_self, zero_mul, Nat.cast_mul] at h + rw [Nat.cast_sum, ← sum_filter_ne_zero] at h + rw [sum_congr (g := fun _v ↦ (1 : ZMod 2)) rfl] at h + · simp only [mul_one, nsmul_eq_mul, sum_const, Ne] at h + rw [← ZMod.natCast_eq_zero_iff_even] + convert! h + exact ZMod.natCast_ne_zero_iff_odd.symm + · intro v + rw [mem_filter_univ, Ne, ZMod.natCast_eq_zero_iff_even, ZMod.natCast_eq_one_iff_odd, + ← Nat.not_even_iff_odd] + tauto theorem odd_card_odd_degree_vertices_ne [Fintype V] [DecidableEq V] [DecidableRel G.Adj] (v : V) (h : Odd (G.degree v)) : Odd #{w | w ≠ v ∧ Odd (G.degree w)} := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Ends/Properties.lean b/Mathlib/Combinatorics/SimpleGraph/Ends/Properties.lean index 6fd3aab7770dee..67fd727013b44b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Ends/Properties.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Ends/Properties.lean @@ -46,7 +46,6 @@ instance componentComplFunctor_finite [LocallyFinite G] [Fact G.Preconnected] /-- A locally finite preconnected infinite graph has at least one end. -/ lemma nonempty_ends_of_infinite [LocallyFinite G] [Fact G.Preconnected] [Infinite V] : G.end.Nonempty := by - classical apply nonempty_sections_of_finite_inverse_system G.componentComplFunctor end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean index ef28446b9a0883..c6a8ba732b41ba 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean @@ -268,7 +268,7 @@ public theorem eventually_completeEquipartiteGraph_isContained_of_minDegree obtain ⟨K⟩ := completeEquipartiteGraph_isContained_iff.mp ih -- find `t` vertices not in `K` adjacent to `t` vertices in each `K.parts` using the -- pigeonhole principle - obtain ⟨⟨y, hy⟩, ht_le_card_filter⟩ := by classical + obtain ⟨⟨y, hy⟩, ht_le_card_filter⟩ := by apply ErdosStone.filter.pi.exists_le_card_fiber K hr_pos ht'_pos ht_lt_t' hδ rw [← div_le_iff₀ (sub_pos_of_lt ht_lt_rt'ε)] trans (N : ℝ) diff --git a/Mathlib/Combinatorics/SimpleGraph/Matching.lean b/Mathlib/Combinatorics/SimpleGraph/Matching.lean index ace4d61a420733..393f79de9a5d99 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Matching.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Matching.lean @@ -451,7 +451,6 @@ lemma Subgraph.IsPerfectMatching.symmDiff_isCycles lemma IsCycles.snd_of_mem_support_of_isPath_of_adj [Finite V] {v w w' : V} (hcyc : G.IsCycles) (p : G.Walk v w) (hw : w ≠ w') (hw' : w' ∈ p.support) (hp : p.IsPath) (hadj : G.Adj v w') : p.snd = w' := by - classical apply hp.snd_of_toSubgraph_adj rw [Walk.mem_support_iff_exists_getVert] at hw' obtain ⟨n, ⟨rfl, hnl⟩⟩ := hw' @@ -468,7 +467,6 @@ lemma IsCycles.snd_of_mem_support_of_isPath_of_adj [Finite V] {v w w' : V} private lemma IsCycles.reachable_sdiff_toSubgraph_spanningCoe_aux [Finite V] {v w : V} (hcyc : G.IsCycles) (p : G.Walk v w) (hp : p.IsPath) : (G \ p.toSubgraph.spanningCoe).Reachable w v := by - classical -- Consider the case when p is nil by_cases hvw : v = w · subst hvw diff --git a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean index 7640e0a025927f..364bd1268ef4c1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean @@ -79,7 +79,6 @@ private lemma Subgraph.IsMatching.exists_verts_compl_subset_universalVerts (h' : ∀ (K : G.deleteUniversalVerts.coe.ConnectedComponent), G.deleteUniversalVerts.coe.IsClique K.supp) : ∃ M : Subgraph G, M.IsMatching ∧ M.vertsᶜ ⊆ G.universalVerts := by - classical have hrep := ConnectedComponent.Represents.image_out G.deleteUniversalVerts.coe.oddComponents -- First we match one node from each odd component to a universal vertex obtain ⟨t, ht, M1, hM1⟩ := Subgraph.IsMatching.exists_of_universalVerts @@ -317,7 +316,6 @@ A graph has a perfect matching if and only if: For every subset `u` of vertices, subset induces at most `u.ncard` components of odd size. This is formally stated using the predicate `IsTutteViolator`, which is satisfied exactly when this condition does not hold. -/ theorem tutte : (∃ M : Subgraph G, M.IsPerfectMatching) ↔ ∀ u, ¬ G.IsTutteViolator u := by - classical refine ⟨by rintro ⟨M, hM⟩; apply not_isTutteViolator_of_isPerfectMatching hM, ?_⟩ contrapose! intro h diff --git a/Mathlib/Computability/Halting.lean b/Mathlib/Computability/Halting.lean index 7364d5bddd2d84..971cac8777655f 100644 --- a/Mathlib/Computability/Halting.lean +++ b/Mathlib/Computability/Halting.lean @@ -42,7 +42,7 @@ theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) : (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by - classical exact + exact have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f => ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩ ⟨fun h => diff --git a/Mathlib/Data/Finite/Vector.lean b/Mathlib/Data/Finite/Vector.lean index 045144d62cebb7..800920886a3992 100644 --- a/Mathlib/Data/Finite/Vector.lean +++ b/Mathlib/Data/Finite/Vector.lean @@ -20,6 +20,5 @@ instance List.Vector.finite [Finite α] {n : ℕ} : Finite (Vector α n) := by infer_instance instance [Finite α] {n : ℕ} : Finite (Sym α n) := by - classical have := Fintype.ofFinite α infer_instance diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index cc5329230c10c2..739c20791e4a18 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -450,7 +450,6 @@ See also `Set.exists_ne_map_eq_of_encard_lt_of_maps_to` and `Set.exists_ne_map_eq_of_ncard_lt_of_maps_to`. -/ theorem exists_ne_map_eq_of_card_lt_of_maps_to (hc : #t < #s) {f : α → β} (hf : Set.MapsTo f s t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by - classical by_contra! hz refine hc.not_ge (card_le_card_of_injOn f hf ?_) intro x hx y hy diff --git a/Mathlib/Data/Finset/Piecewise.lean b/Mathlib/Data/Finset/Piecewise.lean index c62e05d44565f1..5447c7da59ae61 100644 --- a/Mathlib/Data/Finset/Piecewise.lean +++ b/Mathlib/Data/Finset/Piecewise.lean @@ -65,7 +65,7 @@ lemma piecewise_insert_of_ne [DecidableEq ι] {i j : ι} [∀ i, Decidable (i lemma piecewise_insert [DecidableEq ι] (j : ι) [∀ i, Decidable (i ∈ insert j s)] : (insert j s).piecewise f g = update (s.piecewise f g) j (f j) := by - classical simp only [← piecewise_coe, ← Set.piecewise_insert] + simp only [← piecewise_coe, ← Set.piecewise_insert] ext congr simp @@ -148,7 +148,7 @@ variable {π : ι → Type*} {t : Set ι} {t' : ∀ i, Set (π i)} {f g f' g' h lemma piecewise_mem_set_pi (hf : f ∈ Set.pi t t') (hg : g ∈ Set.pi t t') : s.piecewise f g ∈ Set.pi t t' := by - classical rw [← piecewise_coe]; exact Set.piecewise_mem_pi (↑s) hf hg + rw [← piecewise_coe]; exact Set.piecewise_mem_pi (↑s) hf hg variable [∀ i, Preorder (π i)] diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 063fcb3498d22a..dce21538cb0048 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -685,7 +685,7 @@ theorem filter_apply_neg {a : α} (h : ¬p a) : f.filter p a = 0 := if_neg h theorem support_filter : (f.filter p).support = {x ∈ f.support | p x} := rfl theorem filter_zero : (0 : α →₀ M).filter p = 0 := by - classical rw [← support_eq_empty, support_filter, support_zero, Finset.filter_empty] + rw [← support_eq_empty, support_filter, support_zero, Finset.filter_empty] @[simp] theorem filter_single_of_pos {a : α} {b : M} (h : p a) : (single a b).filter p = single a b := diff --git a/Mathlib/Data/Finsupp/BigOperators.lean b/Mathlib/Data/Finsupp/BigOperators.lean index 686b4a2f52a53a..5127bcddf38fda 100644 --- a/Mathlib/Data/Finsupp/BigOperators.lean +++ b/Mathlib/Data/Finsupp/BigOperators.lean @@ -54,7 +54,7 @@ theorem Multiset.support_sum_subset [AddCommMonoid M] (s : Multiset (ι →₀ M theorem Finset.support_sum_subset [AddCommMonoid M] (s : Finset (ι →₀ M)) : (s.sum id).support ⊆ Finset.sup s Finsupp.support := by - classical convert! Multiset.support_sum_subset s.1; simp + convert! Multiset.support_sum_subset s.1; simp theorem List.mem_foldr_sup_support_iff [Zero M] {l : List (ι →₀ M)} {x : ι} : x ∈ l.foldr (Finsupp.support · ⊔ ·) ∅ ↔ ∃ f ∈ l, x ∈ f.support := by diff --git a/Mathlib/Data/Finsupp/Indicator.lean b/Mathlib/Data/Finsupp/Indicator.lean index 8fbae2ef979fc7..49b648b96f9200 100644 --- a/Mathlib/Data/Finsupp/Indicator.lean +++ b/Mathlib/Data/Finsupp/Indicator.lean @@ -39,7 +39,7 @@ def indicator (s : Finset ι) (f : ∀ i ∈ s, α) : ι →₀ α where haveI := Classical.decEq α ({i | f i.1 i.2 ≠ 0} : Finset s).map (Embedding.subtype _) mem_support_toFun i := by - classical simp + simp theorem indicator_of_mem (hi : i ∈ s) (f : ∀ i ∈ s, α) : indicator s f i = f i hi := @dif_pos _ (id _) hi _ _ _ diff --git a/Mathlib/Data/Finsupp/Interval.lean b/Mathlib/Data/Finsupp/Interval.lean index ca822c199d8dc9..9886dd34771358 100644 --- a/Mathlib/Data/Finsupp/Interval.lean +++ b/Mathlib/Data/Finsupp/Interval.lean @@ -126,7 +126,7 @@ variable [AddCommMonoid α] [PartialOrder α] [IsBotZeroClass α] variable [DecidableEq ι] [DecidableEq α] (f : ι →₀ α) theorem card_Iic : #(Iic f) = ∏ i ∈ f.support, #(Iic (f i)) := by - classical simp [Iic_eq_Icc, card_Icc, bot_eq_zero] + simp [Iic_eq_Icc, card_Icc, bot_eq_zero] theorem card_Iio : #(Iio f) = ∏ i ∈ f.support, #(Iic (f i)) - 1 := by rw [card_Iio_eq_card_Iic_sub_one, card_Iic] diff --git a/Mathlib/Data/Finsupp/Order.lean b/Mathlib/Data/Finsupp/Order.lean index 4d2258014b4fbf..e52e5480e00e83 100644 --- a/Mathlib/Data/Finsupp/Order.lean +++ b/Mathlib/Data/Finsupp/Order.lean @@ -85,7 +85,6 @@ variable [AddCommMonoid β] [Preorder β] [IsOrderedAddMonoid β] lemma sum_le_sum_index [DecidableEq ι] {f₁ f₂ : ι →₀ α} {h : ι → α → β} (hf : f₁ ≤ f₂) (hh : ∀ i ∈ f₁.support ∪ f₂.support, Monotone (h i)) (hh₀ : ∀ i ∈ f₁.support ∪ f₂.support, h i 0 = 0) : f₁.sum h ≤ f₂.sum h := by - classical rw [sum_of_support_subset _ Finset.subset_union_left _ hh₀, sum_of_support_subset _ Finset.subset_union_right _ hh₀] gcongr with i hi diff --git a/Mathlib/Data/Finsupp/Single.lean b/Mathlib/Data/Finsupp/Single.lean index 21adbb24170720..3addc245e32f4b 100644 --- a/Mathlib/Data/Finsupp/Single.lean +++ b/Mathlib/Data/Finsupp/Single.lean @@ -361,7 +361,6 @@ def erase (a : α) (f : α →₀ M) : α →₀ M where haveI := Classical.decEq α if a' = a then 0 else f a' mem_support_toFun a' := by - classical grind @[grind =] @@ -373,7 +372,6 @@ theorem erase_apply [DecidableEq α] {a a' : α} {f : α →₀ M} : @[simp] theorem support_erase [DecidableEq α] {a : α} {f : α →₀ M} : (f.erase a).support = f.support.erase a := by - classical grind @[simp] diff --git a/Mathlib/Data/Finsupp/Weight.lean b/Mathlib/Data/Finsupp/Weight.lean index e937d3e86043a7..ed69242d334529 100644 --- a/Mathlib/Data/Finsupp/Weight.lean +++ b/Mathlib/Data/Finsupp/Weight.lean @@ -172,7 +172,6 @@ theorem le_weight_of_ne_zero' {s : σ} {f : σ →₀ ℕ} (hs : f s ≠ 0) : w theorem weight_eq_zero_iff_eq_zero (w : σ → M) [NonTorsionWeight ℕ w] {f : σ →₀ ℕ} : weight w f = 0 ↔ f = 0 := by - classical constructor · intro h ext s diff --git a/Mathlib/Data/Fintype/Order.lean b/Mathlib/Data/Fintype/Order.lean index 0d19d84b5ae583..d7cbdccb30b258 100644 --- a/Mathlib/Data/Fintype/Order.lean +++ b/Mathlib/Data/Fintype/Order.lean @@ -191,7 +191,6 @@ theorem Directed.finite_set_le (D : Directed r f) {s : Set γ} (hs : s.Finite) : lemma Directed.finite_le {ι κ : Sort*} [Nonempty ι] [Finite κ] {f : ι → α} (hf : Directed r f) (g : κ → ι) : ∃ z, ∀ i, r (f (g i)) (f z) := by - classical simpa using (hf.comp_of_surjective PLift.down_surjective).finite_set_le (Set.finite_range (PLift.up ∘ g)) diff --git a/Mathlib/Data/Matrix/Block.lean b/Mathlib/Data/Matrix/Block.lean index 6b9a81d797763e..2bbc15b78771da 100644 --- a/Mathlib/Data/Matrix/Block.lean +++ b/Mathlib/Data/Matrix/Block.lean @@ -831,10 +831,9 @@ theorem toBlock_mul_eq_mul {m n k : Type*} [Fintype n] (p : m → Prop) (q : k theorem toBlock_mul_eq_add {m n k : Type*} [Fintype n] (p : m → Prop) (q : n → Prop) [DecidablePred q] (r : k → Prop) (A : Matrix m n R) (B : Matrix n k R) : (A * B).toBlock p r = A.toBlock p q * B.toBlock q r + (A.toBlock p fun i => ¬q i) * B.toBlock (fun i => ¬q i) r := by - classical - ext i k - simp only [toBlock_apply, mul_apply] - exact (Fintype.sum_subtype_add_sum_subtype q fun x => A (↑i) x * B x ↑k).symm + ext i k + simp only [toBlock_apply, mul_apply] + exact (Fintype.sum_subtype_add_sum_subtype q fun x => A (↑i) x * B x ↑k).symm end diff --git a/Mathlib/Data/Nat/Choose/Multinomial.lean b/Mathlib/Data/Nat/Choose/Multinomial.lean index 964228f88bc058..93c5eea8d6b261 100644 --- a/Mathlib/Data/Nat/Choose/Multinomial.lean +++ b/Mathlib/Data/Nat/Choose/Multinomial.lean @@ -270,7 +270,6 @@ lemma sum_pow_eq_sum_piAntidiag_of_commute (s : Finset α) (f : α → R) (hc : (s : Set α).Pairwise (Commute on f)) (n : ℕ) : (∑ i ∈ s, f i) ^ n = ∑ k ∈ piAntidiag s n, multinomial s k * s.noncommProd (fun i ↦ f i ^ k i) (hc.mono' fun _ _ h ↦ h.pow_pow ..) := by - classical induction s using Finset.cons_induction generalizing n with | empty => cases n <;> simp | cons a s has ih => ?_ diff --git a/Mathlib/Data/PEquiv.lean b/Mathlib/Data/PEquiv.lean index 8e7fa356c79030..3c8682402dec8a 100644 --- a/Mathlib/Data/PEquiv.lean +++ b/Mathlib/Data/PEquiv.lean @@ -166,13 +166,12 @@ theorem injective_of_forall_ne_isSome (f : α ≃. β) (a₂ : α) (h : ∀ a₁ : α, a₁ ≠ a₂ → isSome (f a₁)) : Injective f := HasLeftInverse.injective ⟨fun b => Option.recOn b a₂ fun b' => Option.recOn (f.symm b') a₂ id, fun x => by - classical - cases hfx : f x - · have : x = a₂ := not_imp_comm.1 (h x) (hfx.symm ▸ by simp) - simp [this] - · dsimp only - rw [(eq_some_iff f).2 hfx] - rfl⟩ + cases hfx : f x + · have : x = a₂ := not_imp_comm.1 (h x) (hfx.symm ▸ by simp) + simp [this] + · dsimp only + rw [(eq_some_iff f).2 hfx] + rfl⟩ /-- If the domain of a `PEquiv` is all of `α`, its forward direction is injective. -/ theorem injective_of_forall_isSome {f : α ≃. β} (h : ∀ a : α, isSome (f a)) : Injective f := diff --git a/Mathlib/Data/Set/Card/Arithmetic.lean b/Mathlib/Data/Set/Card/Arithmetic.lean index 2108122faf435d..2c619a9e85b302 100644 --- a/Mathlib/Data/Set/Card/Arithmetic.lean +++ b/Mathlib/Data/Set/Card/Arithmetic.lean @@ -118,7 +118,6 @@ lemma ncard_iUnion_of_finite [Finite ι] {s : ι → Set α} (hs : ∀ i, (s i). lemma Finite.encard_biUnion {t : Set ι} (ht : t.Finite) {s : ι → Set α} (hs : t.PairwiseDisjoint s) : (⋃ i ∈ t, s i).encard = ∑ᶠ i ∈ t, (s i).encard := by - classical by_cases! h : ∀ i ∈ t, (s i).Finite · have : (⋃ i ∈ t, s i).Finite := ht.biUnion (fun i hi ↦ h i hi) rw [← this.cast_ncard_eq, ncard_biUnion ht h hs, diff --git a/Mathlib/Data/Set/Constructions.lean b/Mathlib/Data/Set/Constructions.lean index 1fde47d3e54a09..f3145b445c10ce 100644 --- a/Mathlib/Data/Set/Constructions.lean +++ b/Mathlib/Data/Set/Constructions.lean @@ -52,14 +52,13 @@ variable {S} theorem finiteInter_mem (cond : FiniteInter S) (F : Finset (Set α)) : ↑F ⊆ S → ⋂₀ (↑F : Set (Set α)) ∈ S := by - classical - refine Finset.induction_on F (fun _ => ?_) ?_ - · simp [cond.univ_mem] - · intro a s _ h1 h2 - suffices a ∩ ⋂₀ ↑s ∈ S by simpa - exact - cond.inter_mem (h2 (Finset.mem_insert_self a s)) - (h1 fun x hx => h2 <| Finset.mem_insert_of_mem hx) + refine Finset.induction_on F (fun _ => ?_) ?_ + · simp [cond.univ_mem] + · intro a s _ h1 h2 + suffices a ∩ ⋂₀ ↑s ∈ S by simpa + exact + cond.inter_mem (h2 (Finset.mem_insert_self a s)) + (h1 fun x hx => h2 <| Finset.mem_insert_of_mem hx) theorem finiteInterClosure_insert {A : Set α} (cond : FiniteInter S) (P) (H : P ∈ finiteInterClosure (insert A S)) : P ∈ S ∨ ∃ Q ∈ S, P = A ∩ Q := by diff --git a/Mathlib/Data/Set/PowersetCard.lean b/Mathlib/Data/Set/PowersetCard.lean index f265c642600ca3..99aa4d495c4c54 100644 --- a/Mathlib/Data/Set/PowersetCard.lean +++ b/Mathlib/Data/Set/PowersetCard.lean @@ -240,7 +240,6 @@ instance instInfinite [NeZero n] [Infinite α] : Infinite (powersetCard α n) := protected theorem card : Nat.card (powersetCard α n) = (Nat.card α).choose n := by - classical cases fintypeOrInfinite α · simp [coe_finset] · rcases n with _ | n diff --git a/Mathlib/Data/Setoid/Partition.lean b/Mathlib/Data/Setoid/Partition.lean index 8f1be76aad388c..97ea7c4d5eb8ee 100644 --- a/Mathlib/Data/Setoid/Partition.lean +++ b/Mathlib/Data/Setoid/Partition.lean @@ -74,7 +74,7 @@ theorem finite_classes_ker {α β : Type*} [Finite β] (f : α → β) : (Setoid theorem card_classes_ker_le {α β : Type*} [Fintype β] (f : α → β) [Fintype (Setoid.ker f).classes] : Fintype.card (Setoid.ker f).classes ≤ Fintype.card β := by - classical exact + exact le_trans (Set.card_le_card (classes_ker_subset_fiber_set f)) (Fintype.card_range_le _) /-- Two equivalence relations are equal iff all their equivalence classes are equal. -/ diff --git a/Mathlib/Data/Sign/Basic.lean b/Mathlib/Data/Sign/Basic.lean index 681ed9c3fd2ee6..11b5c9810b1f59 100644 --- a/Mathlib/Data/Sign/Basic.lean +++ b/Mathlib/Data/Sign/Basic.lean @@ -65,7 +65,7 @@ theorem univ_eq : (Finset.univ : Finset SignType) = {0, -1, 1} := by theorem range_eq {α} (f : SignType → α) : Set.range f = {f zero, f neg, f pos} := by classical rw [← Fintype.coe_image_univ, univ_eq] - classical simp [Finset.coe_insert] + simp [Finset.coe_insert] @[simp, norm_cast] lemma coe_mul {α} [MulZeroOneClass α] [HasDistribNeg α] (a b : SignType) : ↑(a * b) = (a : α) * b := diff --git a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean index a4fc0e98d9f987..58d33b1b0a9c2c 100644 --- a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean +++ b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean @@ -370,7 +370,6 @@ Uniqueness (and the usual equations such as `Pattern.shift p v (v + w) = p.confi require a left-cancellation hypothesis and are proved in separate lemmas. -/] protected noncomputable def Pattern.mulShift (p : Pattern A G) (v : G) : G → A := by - classical intro h if hmem : h ∈ p.support.image (v * ·) then -- package existence of a preimage under (v * ·) diff --git a/Mathlib/FieldTheory/AxGrothendieck.lean b/Mathlib/FieldTheory/AxGrothendieck.lean index 67e15d8a62a70f..20b6578c37b418 100644 --- a/Mathlib/FieldTheory/AxGrothendieck.lean +++ b/Mathlib/FieldTheory/AxGrothendieck.lean @@ -171,7 +171,6 @@ theorem realize_genericPolyMapSurjOnOfInjOn theorem ACF_models_genericPolyMapSurjOnOfInjOn_of_prime [Finite ι] {p : ℕ} (hp : p.Prime) (φ : ring.Formula (α ⊕ ι)) (mons : ι → Finset (ι →₀ ℕ)) : Theory.ACF p ⊨ᵇ genericPolyMapSurjOnOfInjOn φ mons := by - classical have : Fact p.Prime := ⟨hp⟩ let := compatibleRingOfRing (AlgebraicClosure (ZMod p)) rw [← (ACF_isComplete (Or.inl hp)).realize_sentence_iff _ diff --git a/Mathlib/FieldTheory/Finite/Basic.lean b/Mathlib/FieldTheory/Finite/Basic.lean index fa6d6d9a573729..a40d4389b4dbcf 100644 --- a/Mathlib/FieldTheory/Finite/Basic.lean +++ b/Mathlib/FieldTheory/Finite/Basic.lean @@ -278,16 +278,15 @@ theorem cast_card_eq_zero : (q : K) = 0 := by simp theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by - classical - obtain ⟨x, hx⟩ := IsCyclic.exists_generator (α := Kˣ) - rw [← Nat.card_eq_fintype_card, ← Nat.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx, - orderOf_dvd_iff_pow_eq_one] - constructor - · intro h; apply h - · intro h y - simp_rw [← mem_powers_iff_mem_zpowers] at hx - rcases hx y with ⟨j, rfl⟩ - rw [← pow_mul, mul_comm, pow_mul, h, one_pow] + obtain ⟨x, hx⟩ := IsCyclic.exists_generator (α := Kˣ) + rw [← Nat.card_eq_fintype_card, ← Nat.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx, + orderOf_dvd_iff_pow_eq_one] + constructor + · intro h; apply h + · intro h y + simp_rw [← mem_powers_iff_mem_zpowers] at hx + rcases hx y with ⟨j, rfl⟩ + rw [← pow_mul, mul_comm, pow_mul, h, one_pow] /-- The sum of `x ^ i` as `x` ranges over the units of a finite field of cardinality `q` is equal to `0` unless `(q - 1) ∣ i`, in which case the sum is `q - 1`. -/ @@ -804,27 +803,26 @@ theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) : if and only if `a ^ (#F / 2) = 1`. -/ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) : IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by - classical - obtain ⟨g, hg⟩ := IsCyclic.exists_generator (α := Fˣ) - obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg - have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF) - constructor - · rintro ⟨y, rfl⟩ - rw [← pow_two, ← pow_mul, hodd] - apply_fun Units.val using Units.val_injective - push_cast - exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y) - · subst a; intro h - rw [← Nat.card_eq_fintype_card] at hodd h - have key : 2 * (Nat.card F / 2) ∣ n * (Nat.card F / 2) := by - rw [← pow_mul] at h - rw [hodd, ← Nat.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg] - apply orderOf_dvd_of_pow_eq_one h - have : 0 < Nat.card F / 2 := Nat.div_pos Finite.one_lt_card (by simp) - obtain ⟨m, rfl⟩ := Nat.dvd_of_mul_dvd_mul_right this key - refine ⟨g ^ m, ?_⟩ - dsimp - rw [mul_comm, pow_mul, pow_two] + obtain ⟨g, hg⟩ := IsCyclic.exists_generator (α := Fˣ) + obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg + have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF) + constructor + · rintro ⟨y, rfl⟩ + rw [← pow_two, ← pow_mul, hodd] + apply_fun Units.val using Units.val_injective + push_cast + exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y) + · subst a; intro h + rw [← Nat.card_eq_fintype_card] at hodd h + have key : 2 * (Nat.card F / 2) ∣ n * (Nat.card F / 2) := by + rw [← pow_mul] at h + rw [hodd, ← Nat.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg] + apply orderOf_dvd_of_pow_eq_one h + have : 0 < Nat.card F / 2 := Nat.div_pos Finite.one_lt_card (by simp) + obtain ⟨m, rfl⟩ := Nat.dvd_of_mul_dvd_mul_right this key + refine ⟨g ^ m, ?_⟩ + dsimp + rw [mul_comm, pow_mul, pow_two] /-- A non-zero `a : F` is a square if and only if `a ^ (#F / 2) = 1`. -/ theorem isSquare_iff (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) : diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 51cfbf7ee8239d..30d74790d3ccca 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -273,7 +273,6 @@ def fixingSubgroupEquiv : fixingSubgroup K ≃* Gal(E/K) where theorem fixingSubgroup_fixedField [FiniteDimensional F E] : fixingSubgroup (fixedField H) = H := by have H_le : H ≤ fixingSubgroup (fixedField H) := (le_iff_le _ _).mp le_rfl - classical suffices Nat.card H = Nat.card (fixingSubgroup (fixedField H)) by exact SetLike.coe_injective (Set.eq_of_inclusion_surjective ((Nat.bijective_iff_injective_and_card (Set.inclusion H_le)).mpr @@ -320,7 +319,6 @@ theorem fixedField_fixingSubgroup [FiniteDimensional F E] [h : IsGalois F E] : suffices finrank K E = finrank (IntermediateField.fixedField (IntermediateField.fixingSubgroup K)) E by exact (IntermediateField.eq_of_le_of_finrank_eq' K_le this).symm - classical rw [IntermediateField.finrank_fixedField_eq_card, Nat.card_congr (IntermediateField.fixingSubgroupEquiv K).toEquiv] exact (card_aut_eq_finrank K E).symm @@ -485,7 +483,7 @@ theorem is_separable_splitting_field [FiniteDimensional F E] [IsGalois F E] : theorem of_fixedField_eq_bot [FiniteDimensional F E] (h : IntermediateField.fixedField (⊤ : Subgroup Gal(E/F)) = ⊥) : IsGalois F E := by rw [← isGalois_iff_isGalois_bot, ← h] - classical exact IsGalois.of_fixed_field E (⊤ : Subgroup Gal(E/F)) + exact IsGalois.of_fixed_field E (⊤ : Subgroup Gal(E/F)) /-- Let $E / F$ be a finite extension of fields. If $|\text{Aut}(E/F)| = [E : F]$, then $E$ is Galois over $F$. -/ @@ -494,7 +492,6 @@ theorem of_card_aut_eq_finrank [FiniteDimensional F E] (h : Nat.card Gal(E/F) = finrank F E) : IsGalois F E := by apply of_fixedField_eq_bot have p : 0 < finrank (IntermediateField.fixedField (⊤ : Subgroup Gal(E/F))) E := finrank_pos - classical rw [← IntermediateField.finrank_eq_one_iff, ← mul_left_inj' (ne_of_lt p).symm, finrank_mul_finrank, ← h, one_mul, IntermediateField.finrank_fixedField_eq_card] apply Nat.card_congr diff --git a/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean b/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean index f73f39d383ef9b..0512776c018ead 100644 --- a/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean +++ b/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean @@ -157,7 +157,6 @@ lemma span_coeff_minpolyDiv : Submodule.span R (Set.range (coeff (minpolyDiv R x))) = Subalgebra.toSubmodule (R[x]) := by nontriviality S - classical apply le_antisymm · rw [Submodule.span_le] rintro _ ⟨i, rfl⟩ diff --git a/Mathlib/FieldTheory/PrimitiveElement.lean b/Mathlib/FieldTheory/PrimitiveElement.lean index bf7018053ae58d..7d3989b23c48dd 100644 --- a/Mathlib/FieldTheory/PrimitiveElement.lean +++ b/Mathlib/FieldTheory/PrimitiveElement.lean @@ -85,7 +85,6 @@ variable {F : Type*} [Field F] [Infinite F] {E : Type*} [Field E] (ϕ : F →+* theorem primitive_element_inf_aux_exists_c (f g : F[X]) : ∃ c : F, ∀ α' ∈ (f.map ϕ).roots, ∀ β' ∈ (g.map ϕ).roots, -(α' - α) / (β' - β) ≠ ϕ c := by - classical let sf := (f.map ϕ).roots let sg := (g.map ϕ).roots classical @@ -103,7 +102,6 @@ variable [Algebra F E] /-- This is the heart of the proof of the primitive element theorem. It shows that if `F` is infinite and `α` and `β` are separable over `F` then `F⟮α, β⟯` is generated by a single element. -/ theorem primitive_element_inf_aux [Algebra.IsSeparable F E] : ∃ γ : E, F⟮α, β⟯ = F⟮γ⟯ := by - classical have hα := Algebra.IsSeparable.isIntegral F α have hβ := Algebra.IsSeparable.isIntegral F β let f := minpoly F α diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index f118e695465557..8065b7de9d05a5 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -179,7 +179,6 @@ theorem emultiplicity_le_one_of_separable {p q : R[X]} (hq : ¬IsUnit q) (hsep : See `PerfectField.separable_iff_squarefree` for the converse when the coefficients are a perfect field. -/ theorem Separable.squarefree {p : R[X]} (hsep : Separable p) : Squarefree p := by - classical rw [squarefree_iff_emultiplicity_le_one p] exact fun f => or_iff_not_imp_right.mpr fun hunit => emultiplicity_le_one_of_separable hunit hsep @@ -782,7 +781,6 @@ theorem AlgHom.natCard_of_powerBasis (pb : PowerBasis K S) (h_sep : IsSeparable theorem AlgHom.card_of_powerBasis (pb : PowerBasis K S) (h_sep : IsSeparable K pb.gen) (h_splits : ((minpoly K pb.gen).map (algebraMap K L)).Splits) : @Fintype.card (S →ₐ[K] L) (PowerBasis.AlgHom.fintype pb) = pb.dim := by - classical rw [Fintype.card_eq_nat_card, AlgHom.natCard_of_powerBasis pb h_sep h_splits] end CardAlgHom diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index 65e870ea96ac4c..ba5df4fe9597cb 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -603,7 +603,6 @@ theorem eq_X_pow_char_pow_sub_C_pow_of_natSepDegree_eq_one (q : ℕ) [ExpChar F Nat.pos_of_ne_zero <| (natSepDegree_ne_zero_iff _).2 hI.natDegree_pos.ne' obtain ⟨n, y, H, hp⟩ := hM.eq_X_pow_char_pow_sub_C_of_natSepDegree_eq_one_of_irreducible q hI hD have hF := finiteMultiplicity_of_degree_pos_of_monic (degree_pos_of_irreducible hI) hM hm.ne_zero - classical have hne := (multiplicity_pos_of_dvd hf).ne' refine ⟨_, n, y, hne, H, ?_⟩ obtain ⟨c, hf, H⟩ := hF.exists_eq_pow_mul_and_not_dvd diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index 862f674dbacdd6..e1604a2fc0a54d 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -129,7 +129,6 @@ theorem coeff_toPolynomialAdjoinImageCompl_ne_zero theorem isAlgebraic_of_mem_vars_of_forall_totalDegree_le (hFa : F.aeval a = 0) (i : ι) (hi : i ∈ F.vars) : IsAlgebraic (Algebra.adjoin k (a '' {i}ᶜ)) (a i) := by - classical have ⟨σ, hσ, hσi⟩ := (mem_vars_iff_mem_support i).mp hi refine ⟨toPolynomialAdjoinImageCompl F a i, fun h ↦ coeff_toPolynomialAdjoinImageCompl_ne_zero HF σ hσ i diff --git a/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean b/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean index 1b9dadd35db131..3f491a9e6dc94c 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean @@ -48,7 +48,6 @@ theorem convexCombination_single (x : P) : theorem convexCombination_assoc (f : StdSimplex R (StdSimplex R P)) : convexCombination (f.map convexCombination) = convexCombination f.join := by - classical -- Choose a base point obtain ⟨b⟩ : Nonempty P := inferInstance -- Express both sides using weightedVSubOfPoint with base point b diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean index 9f7e74f57e4fd9..ac758307cd95a3 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean @@ -94,7 +94,6 @@ theorem mk_single (x : M) {nonneg total} : (mk (.single x (1 : R)) nonneg total) @[simp] lemma support_weights_eq_singleton : w.weights.support = {x} ↔ w = single x where mp := by - classical rw [support_eq_singleton'] rintro ⟨a, ha, hwa⟩ ext : 1 diff --git a/Mathlib/Geometry/Convex/Set.lean b/Mathlib/Geometry/Convex/Set.lean index 71d316bcad1392..c869531e0edac3 100644 --- a/Mathlib/Geometry/Convex/Set.lean +++ b/Mathlib/Geometry/Convex/Set.lean @@ -100,7 +100,6 @@ protected lemma IsConvexSet.iUnion {ι : Sort*} {s : ι → Set X} (hs : Directe protected lemma IsConvexSet.preimage {s : Set Y} (hf : IsAffineMap R f) (hs : IsConvexSet R s) : IsConvexSet R (f ⁻¹' s) := by - classical rintro w hw simp only [mem_preimage, hf.map_sConvexComb, sConvexComb_map] exact hs.iConvexComb_mem fun x hx ↦ hw <| by simpa diff --git a/Mathlib/Geometry/Group/Growth/QuotientInter.lean b/Mathlib/Geometry/Group/Growth/QuotientInter.lean index 32b41688f396bc..c6faf6930618d6 100644 --- a/Mathlib/Geometry/Group/Growth/QuotientInter.lean +++ b/Mathlib/Geometry/Group/Growth/QuotientInter.lean @@ -61,7 +61,6 @@ lemma card_pow_quotient_mul_pow_inter_subgroup_le : @[to_additive] lemma le_card_quotient_mul_sq_inter_subgroup (hAsymm : A⁻¹ = A) : #A ≤ #(A.image <| QuotientGroup.mk' H) * #{x ∈ A ^ 2 | x ∈ H} := by - classical set π := QuotientGroup.mk' H rw [card_eq_sum_card_image π] refine sum_le_card_nsmul _ _ _ <| forall_mem_image.2 fun a ha ↦ ?_ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 1ab6f3612e7c95..ed0716ef31beb2 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -1001,7 +1001,6 @@ lemma HasMFDerivWithinAt.prod [DecidableEq ι] (hf : ∀ i ∈ t, HasMFDerivWithinAt I 𝓘(𝕜, F') (f i) s z (f' i)) : HasMFDerivWithinAt I 𝓘(𝕜, F') (∏ i ∈ t, f i) s z (∑ i ∈ t, (∏ j ∈ t.erase i, f j z) • (f' i)) := by - classical induction t using Finset.induction_on with | empty => simpa using! hasMFDerivWithinAt_const .. | insert i t hi IH => diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index a916bb439155ec..2a3a5450cf8ece 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -810,7 +810,6 @@ theorem exists_contMDiff_support_eq_eq_one_iff · have : 0 < f x := lt_of_le_of_ne (f_pos x) (Ne.symm xs) linarith [g_pos x] · have : 0 < g x := by - classical apply lt_of_le_of_ne (g_pos x) (Ne.symm ?_) rw [← mem_support, g_supp] contrapose xs diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index bc69c57ad82ce3..9cc3b732ee1c29 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -453,7 +453,6 @@ near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% s) x) (i : ι) : CMDiffAt k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. - classical -- step 1: on e.baseSet, we know compute the coefficient very well let aux := fun x ↦ b.repr (e ((T% s) x)).2 i -- Since `e.baseSet` is open, this is sufficient. @@ -521,7 +520,6 @@ lemma mdifferentiableAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : MDiffAt (T% s) x) (i : ι) : MDiffAt ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. - classical -- step 1: on `e.baseSet`, we know the coefficient very well let aux := fun x ↦ b.repr (e ((T% s) x)).2 i -- Since `e.baseSet` is open, this is sufficient. diff --git a/Mathlib/GroupTheory/ArchimedeanDensely.lean b/Mathlib/GroupTheory/ArchimedeanDensely.lean index 97dd541504d7b6..5f15004f63addd 100644 --- a/Mathlib/GroupTheory/ArchimedeanDensely.lean +++ b/Mathlib/GroupTheory/ArchimedeanDensely.lean @@ -299,7 +299,6 @@ either isomorphic (and order-isomorphic) to `ℤᵐ⁰`, or is densely ordered. lemma LinearOrderedCommGroupWithZero.discrete_or_denselyOrdered (G : Type*) [LinearOrderedCommGroupWithZero G] [Nontrivial Gˣ] [MulArchimedean G] : Nonempty (G ≃*o ℤᵐ⁰) ∨ DenselyOrdered G := by - classical rw [← denselyOrdered_units_iff] refine (LinearOrderedCommGroup.discrete_or_denselyOrdered Gˣ).imp_left ?_ intro ⟨f⟩ diff --git a/Mathlib/GroupTheory/Congruence/BigOperators.lean b/Mathlib/GroupTheory/Congruence/BigOperators.lean index 25e62abbf084bd..0f01d857a79159 100644 --- a/Mathlib/GroupTheory/Congruence/BigOperators.lean +++ b/Mathlib/GroupTheory/Congruence/BigOperators.lean @@ -94,7 +94,6 @@ protected theorem dfinsuppProd {ι : Type*} {β : ι → Type*} {M : Type*} c (f.prod h) (g.prod h') := by refine Quotient.exact (show c.mk' _ = c.mk' _ from ?_) rw [map_dfinsuppProd, map_dfinsuppProd] - classical exact DFinsupp.prod_congr_of_eq_on_union (fun _ _ => Quotient.sound <| H _) (fun _ _ => Quotient.sound <| hf _) (fun _ _ => Quotient.sound <| hf' _) diff --git a/Mathlib/GroupTheory/CoprodI.lean b/Mathlib/GroupTheory/CoprodI.lean index dac37906ed9891..813df471b1eaa8 100644 --- a/Mathlib/GroupTheory/CoprodI.lean +++ b/Mathlib/GroupTheory/CoprodI.lean @@ -856,28 +856,27 @@ theorem lift_word_prod_nontrivial_of_head_card {i j} (w : NeWord H i j) include hcard in theorem lift_word_prod_nontrivial_of_not_empty {i j} (w : NeWord H i j) : lift f w.prod ≠ 1 := by - classical - rcases hcard with hcard | hcard - · obtain ⟨i, h1, h2⟩ := Cardinal.exists_ne_ne_of_three_le hcard i j - exact lift_word_prod_nontrivial_of_other_i f X hXnonempty hXdisj hpp w h1 h2 - · obtain ⟨k, hcard⟩ := hcard - by_cases hh : i = k <;> by_cases hl : j = k - · subst hh - subst hl - exact lift_word_prod_nontrivial_of_head_eq_last f X hXnonempty hXdisj hpp w - · subst hh - change j ≠ i at hl - exact lift_word_prod_nontrivial_of_head_card f X hXnonempty hXdisj hpp w hcard hl.symm - · subst hl - change i ≠ j at hh - have : lift f w.inv.prod ≠ 1 := - lift_word_prod_nontrivial_of_head_card f X hXnonempty hXdisj hpp w.inv hcard hh.symm - intro heq - apply this - simpa using heq - · change i ≠ k at hh - change j ≠ k at hl - exact lift_word_prod_nontrivial_of_other_i f X hXnonempty hXdisj hpp w hh.symm hl.symm + rcases hcard with hcard | hcard + · obtain ⟨i, h1, h2⟩ := Cardinal.exists_ne_ne_of_three_le hcard i j + exact lift_word_prod_nontrivial_of_other_i f X hXnonempty hXdisj hpp w h1 h2 + · obtain ⟨k, hcard⟩ := hcard + by_cases hh : i = k <;> by_cases hl : j = k + · subst hh + subst hl + exact lift_word_prod_nontrivial_of_head_eq_last f X hXnonempty hXdisj hpp w + · subst hh + change j ≠ i at hl + exact lift_word_prod_nontrivial_of_head_card f X hXnonempty hXdisj hpp w hcard hl.symm + · subst hl + change i ≠ j at hh + have : lift f w.inv.prod ≠ 1 := + lift_word_prod_nontrivial_of_head_card f X hXnonempty hXdisj hpp w.inv hcard hh.symm + intro heq + apply this + simpa using heq + · change i ≠ k at hh + change j ≠ k at hl + exact lift_word_prod_nontrivial_of_other_i f X hXnonempty hXdisj hpp w hh.symm hl.symm include hcard in theorem empty_of_word_prod_eq_one {w : Word H} (h : lift f w.prod = 1) : diff --git a/Mathlib/GroupTheory/Coset/Card.lean b/Mathlib/GroupTheory/Coset/Card.lean index 68a812f2d78fd3..0645afcf406c73 100644 --- a/Mathlib/GroupTheory/Coset/Card.lean +++ b/Mathlib/GroupTheory/Coset/Card.lean @@ -67,7 +67,7 @@ lemma card_mul_eq_card_subgroup_mul_card_quotient (s : Subgroup α) (t : Set α) @[to_additive (attr := wikidata Q505798) /-- **Lagrange's Theorem**: The order of an additive subgroup divides the order of its ambient additive group. -/] theorem card_subgroup_dvd_card (s : Subgroup α) : Nat.card s ∣ Nat.card α := by - classical simp [card_eq_card_quotient_mul_card_subgroup s, @dvd_mul_left ℕ] + simp [card_eq_card_quotient_mul_card_subgroup s, @dvd_mul_left ℕ] @[to_additive] theorem card_quotient_dvd_card (s : Subgroup α) : Nat.card (α ⧸ s) ∣ Nat.card α := by @@ -78,7 +78,7 @@ variable {H : Type*} [Group H] @[to_additive] theorem card_dvd_of_injective (f : α →* H) (hf : Function.Injective f) : Nat.card α ∣ Nat.card H := by - classical calc + calc Nat.card α = Nat.card (f.range : Subgroup H) := Nat.card_congr (Equiv.ofInjective f hf) _ ∣ Nat.card H := card_subgroup_dvd_card _ diff --git a/Mathlib/GroupTheory/Divisible.lean b/Mathlib/GroupTheory/Divisible.lean index 7c7bd39ddc27ab..61a7358f2531b5 100644 --- a/Mathlib/GroupTheory/Divisible.lean +++ b/Mathlib/GroupTheory/Divisible.lean @@ -131,7 +131,7 @@ implies the textbook approach. noncomputable def rootableByOfPowLeftSurj (H : ∀ {n : α}, n ≠ 0 → Function.Surjective (fun a => a ^ n : A → A)) : RootableBy A α where root a n := @dite _ (n = 0) (Classical.dec _) (fun _ => (1 : A)) fun hn => (H hn a).choose - root_zero _ := by classical exact dif_pos rfl + root_zero _ := by exact dif_pos rfl root_cancel a hn := by dsimp only rw [dif_neg hn] diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 5ede368ffb7b41..bfcad0e7520406 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -1231,13 +1231,12 @@ variable [Finite G] theorem Group.isNilpotent_of_product_of_sylow_group (e : (∀ p : (Nat.card G).primeFactors, ∀ P : Sylow p G, (↑P : Subgroup G)) ≃* G) : IsNilpotent G := by - classical - let ps := (Nat.card G).primeFactors - have : ∀ (p : ps) (P : Sylow p G), IsNilpotent (↑P : Subgroup G) := by - intro p P - have : Fact (Nat.Prime ↑p) := Fact.mk <| Nat.prime_of_mem_primeFactors p.2 - exact P.isPGroup'.isNilpotent - exact nilpotent_of_mulEquiv e + let ps := (Nat.card G).primeFactors + have : ∀ (p : ps) (P : Sylow p G), IsNilpotent (↑P : Subgroup G) := by + intro p P + have : Fact (Nat.Prime ↑p) := Fact.mk <| Nat.prime_of_mem_primeFactors p.2 + exact P.isPGroup'.isNilpotent + exact nilpotent_of_mulEquiv e /-- A finite group is nilpotent iff the normalizer condition holds, and iff all maximal groups are normal and iff all Sylow groups are normal and iff the group is the direct product of its Sylow diff --git a/Mathlib/GroupTheory/NoncommPiCoprod.lean b/Mathlib/GroupTheory/NoncommPiCoprod.lean index 58eb9fa5e654e8..9ad2c33927ad7e 100644 --- a/Mathlib/GroupTheory/NoncommPiCoprod.lean +++ b/Mathlib/GroupTheory/NoncommPiCoprod.lean @@ -107,7 +107,6 @@ def noncommPiCoprod : (∀ i : ι, N i) →* M where apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _) simp map_mul' f g := by - classical convert! @Finset.noncommProd_mul_distrib _ _ _ _ (fun i => ϕ i (f i)) (fun i => ϕ i (g i)) _ _ _ · exact map_mul _ _ _ · rintro i - j - h @@ -232,16 +231,15 @@ theorem injective_noncommPiCoprod_of_iSupIndep [Fintype ι] {hcomm : Pairwise fun i j : ι => ∀ (x : H i) (y : H j), Commute (ϕ i x) (ϕ j y)} (hind : iSupIndep fun i => (ϕ i).range) (hinj : ∀ i, Function.Injective (ϕ i)) : Function.Injective (noncommPiCoprod ϕ hcomm) := by - classical - apply (MonoidHom.ker_eq_bot_iff _).mp - rw [eq_bot_iff] - intro f heq1 - have : ∀ i, i ∈ Finset.univ → ϕ i (f i) = 1 := - Subgroup.eq_one_of_noncommProd_eq_one_of_iSupIndep _ _ (fun _ _ _ _ h => hcomm h _ _) - _ hind (by simp) heq1 - ext i - apply hinj - simp [this i (Finset.mem_univ i)] + apply (MonoidHom.ker_eq_bot_iff _).mp + rw [eq_bot_iff] + intro f heq1 + have : ∀ i, i ∈ Finset.univ → ϕ i (f i) = 1 := + Subgroup.eq_one_of_noncommProd_eq_one_of_iSupIndep _ _ (fun _ _ _ _ h => hcomm h _ _) + _ hind (by simp) heq1 + ext i + apply hinj + simp [this i (Finset.mem_univ i)] @[to_additive] theorem independent_range_of_coprime_order diff --git a/Mathlib/GroupTheory/Order/Min.lean b/Mathlib/GroupTheory/Order/Min.lean index 1a01d16637880b..903d3e73ad2019 100644 --- a/Mathlib/GroupTheory/Order/Min.lean +++ b/Mathlib/GroupTheory/Order/Min.lean @@ -91,7 +91,6 @@ namespace ZMod @[simp] protected lemma minOrder {n : ℕ} (hn : n ≠ 0) (hn₁ : n ≠ 1) : minOrder (ZMod n) = n.minFac := by have : Fact (1 < n) := ⟨one_lt_iff_ne_zero_and_ne_one.mpr ⟨hn, hn₁⟩⟩ - classical have : (↑(n / n.minFac) : ZMod n) ≠ 0 := by rw [Ne, ringChar.spec, ringChar.eq (ZMod n) n] exact diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index 1cfda9fa4845f1..ab9a1de50c4efa 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -655,7 +655,6 @@ lemma infinite_powers : (powers a : Set G).Infinite ↔ ¬ IsOfFinOrder a := fin /-- See also `orderOf_eq_card_powers`. -/ @[to_additive /-- See also `addOrder_eq_card_multiples`. -/] lemma Nat.card_submonoidPowers : Nat.card (powers a) = orderOf a := by - classical by_cases ha : IsOfFinOrder a · exact (Nat.card_congr (finEquivPowers ha).symm).trans <| by simp · have := (infinite_powers.2 ha).to_subtype @@ -742,7 +741,6 @@ lemma infinite_powers : (powers a : Set G).Infinite ↔ ¬ IsOfFinOrder a := fin /-- See also `orderOf_eq_card_powers`. -/ @[to_additive /-- See also `addOrder_eq_card_multiples`. -/] lemma Nat.card_submonoidPowers : Nat.card (powers a) = orderOf a := by - classical by_cases ha : IsOfFinOrder a · exact (Nat.card_congr (finEquivPowers ha).symm).trans <| by simp · have := (infinite_powers.2 ha).to_subtype diff --git a/Mathlib/GroupTheory/PGroup.lean b/Mathlib/GroupTheory/PGroup.lean index 11d41f6cb5dcc7..51b09b77d3f836 100644 --- a/Mathlib/GroupTheory/PGroup.lean +++ b/Mathlib/GroupTheory/PGroup.lean @@ -220,18 +220,17 @@ theorem exists_fixed_point_of_prime_dvd_card_of_fixed_point (hpα : p ∣ Nat.ca ⟨b, hb, fun hab => hba (by simp_rw [hab])⟩ theorem center_nontrivial [Nontrivial G] [Finite G] : Nontrivial (Subgroup.center G) := by - classical - have := (hG.of_equiv ConjAct.toConjAct).exists_fixed_point_of_prime_dvd_card_of_fixed_point G - rw [ConjAct.fixedPoints_eq_center] at this - have dvd : p ∣ Nat.card G := by - obtain ⟨n, hn0, hn⟩ := hG.nontrivial_iff_card.mp inferInstance - exact hn.symm ▸ dvd_pow_self _ (ne_of_gt hn0) - obtain ⟨g, hg⟩ := this dvd (Subgroup.center G).one_mem - exact ⟨⟨1, ⟨g, hg.1⟩, mt Subtype.ext_iff.mp hg.2⟩⟩ + have := (hG.of_equiv ConjAct.toConjAct).exists_fixed_point_of_prime_dvd_card_of_fixed_point G + rw [ConjAct.fixedPoints_eq_center] at this + have dvd : p ∣ Nat.card G := by + obtain ⟨n, hn0, hn⟩ := hG.nontrivial_iff_card.mp inferInstance + exact hn.symm ▸ dvd_pow_self _ (ne_of_gt hn0) + obtain ⟨g, hg⟩ := this dvd (Subgroup.center G).one_mem + exact ⟨⟨1, ⟨g, hg.1⟩, mt Subtype.ext_iff.mp hg.2⟩⟩ theorem bot_lt_center [Nontrivial G] [Finite G] : ⊥ < Subgroup.center G := by have := center_nontrivial hG - classical exact + exact bot_lt_iff_ne_bot.mpr ((Subgroup.center G).one_lt_card_iff_ne_bot.mp Finite.one_lt_card) end GIsPGroup diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index 98e68a7c38bdb5..dd18faf0f5e575 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -289,7 +289,7 @@ variable [Finite α] theorem IsCycle.exists_pow_eq (hf : IsCycle f) (hx : f x ≠ x) (hy : f y ≠ y) : ∃ i : ℕ, (f ^ i) x = y := by let ⟨n, hn⟩ := hf.exists_zpow_eq hx hy - classical exact + exact ⟨(n % orderOf f).toNat, by {have := n.emod_nonneg (Int.natCast_ne_zero.mpr (ne_of_gt (orderOf_pos f))) rwa [← zpow_natCast, Int.toNat_of_nonneg this, zpow_mod_orderOf]}⟩ @@ -609,13 +609,12 @@ theorem IsCycle.pow_eq_pow_iff [Finite β] {f : Perm β} (hf : IsCycle f) {a b : theorem IsCycle.isCycle_pow_pos_of_lt_prime_order [Finite β] {f : Perm β} (hf : IsCycle f) (hf' : (orderOf f).Prime) (n : ℕ) (hn : 0 < n) (hn' : n < orderOf f) : IsCycle (f ^ n) := by - classical - cases nonempty_fintype β - have : n.Coprime (orderOf f) := by - refine Nat.Coprime.symm ?_ - rw [Nat.Prime.coprime_iff_not_dvd hf'] - exact Nat.not_dvd_of_pos_of_lt hn hn' - exact (pow_iff hf).mpr this + cases nonempty_fintype β + have : n.Coprime (orderOf f) := by + refine Nat.Coprime.symm ?_ + rw [Nat.Prime.coprime_iff_not_dvd hf'] + exact Nat.not_dvd_of_pos_of_lt hn hn' + exact (pow_iff hf).mpr this end IsCycle @@ -779,15 +778,14 @@ theorem IsCycleOn.pow_card_apply {s : Finset α} (hf : f.IsCycleOn s) (ha : a theorem IsCycleOn.exists_pow_eq {s : Finset α} (hf : f.IsCycleOn s) (ha : a ∈ s) (hb : b ∈ s) : ∃ n < #s, (f ^ n) a = b := by - classical - obtain ⟨n, rfl⟩ := hf.2 ha hb - obtain ⟨k, hk⟩ := (Int.mod_modEq n #s).symm.dvd - refine ⟨n.natMod #s, Int.natMod_lt (Nonempty.card_pos ⟨a, ha⟩).ne', ?_⟩ - rw [← zpow_natCast, Int.natMod, - Int.toNat_of_nonneg (Int.emod_nonneg _ <| Nat.cast_ne_zero.2 - (Nonempty.card_pos ⟨a, ha⟩).ne'), sub_eq_iff_eq_add'.1 hk, zpow_add, zpow_mul] - simp only [zpow_natCast, coe_mul, comp_apply, EmbeddingLike.apply_eq_iff_eq] - exact IsFixedPt.perm_zpow (hf.pow_card_apply ha) _ + obtain ⟨n, rfl⟩ := hf.2 ha hb + obtain ⟨k, hk⟩ := (Int.mod_modEq n #s).symm.dvd + refine ⟨n.natMod #s, Int.natMod_lt (Nonempty.card_pos ⟨a, ha⟩).ne', ?_⟩ + rw [← zpow_natCast, Int.natMod, + Int.toNat_of_nonneg (Int.emod_nonneg _ <| Nat.cast_ne_zero.2 + (Nonempty.card_pos ⟨a, ha⟩).ne'), sub_eq_iff_eq_add'.1 hk, zpow_add, zpow_mul] + simp only [zpow_natCast, coe_mul, comp_apply, EmbeddingLike.apply_eq_iff_eq] + exact IsFixedPt.perm_zpow (hf.pow_card_apply ha) _ theorem IsCycleOn.exists_pow_eq' (hs : s.Finite) (hf : f.IsCycleOn s) (ha : a ∈ s) (hb : b ∈ s) : ∃ n : ℕ, (f ^ n) a = b := by diff --git a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean index e344b1014b5d2e..e03ab1b5aacc3b 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean @@ -447,15 +447,14 @@ theorem list_cycles_perm_list_cycles {α : Type*} [Finite α] {l₁ l₂ : List (h₀ : l₁.prod = l₂.prod) (h₁l₁ : ∀ σ : Perm α, σ ∈ l₁ → σ.IsCycle) (h₁l₂ : ∀ σ : Perm α, σ ∈ l₂ → σ.IsCycle) (h₂l₁ : l₁.Pairwise Disjoint) (h₂l₂ : l₂.Pairwise Disjoint) : l₁ ~ l₂ := by - classical - refine - (List.perm_ext_iff_of_nodup (nodup_of_pairwise_disjoint_cycles h₁l₁ h₂l₁) - (nodup_of_pairwise_disjoint_cycles h₁l₂ h₂l₂)).mpr - fun σ => ?_ - by_cases hσ : σ.IsCycle - · obtain _ := not_forall.mp (mt ext hσ.ne_one) - rw [mem_list_cycles_iff h₁l₁ h₂l₁, mem_list_cycles_iff h₁l₂ h₂l₂, h₀] - · exact iff_of_false (mt (h₁l₁ σ) hσ) (mt (h₁l₂ σ) hσ) + refine + (List.perm_ext_iff_of_nodup (nodup_of_pairwise_disjoint_cycles h₁l₁ h₂l₁) + (nodup_of_pairwise_disjoint_cycles h₁l₂ h₂l₂)).mpr + fun σ => ?_ + by_cases hσ : σ.IsCycle + · obtain _ := not_forall.mp (mt ext hσ.ne_one) + rw [mem_list_cycles_iff h₁l₁ h₂l₁, mem_list_cycles_iff h₁l₂ h₂l₂, h₀] + · exact iff_of_false (mt (h₁l₁ σ) hσ) (mt (h₁l₂ σ) hσ) /-- Factors a permutation `f` into a list of disjoint cyclic permutations that multiply to `f`. -/ def cycleFactors [Fintype α] [LinearOrder α] (f : Perm α) : diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index 4fbb18d909c321..6abea89347dbb3 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -128,7 +128,6 @@ theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : theorem mem_sumCongrHom_range_of_perm_mapsTo_inl {m n : Type*} [Finite m] [Finite n] {σ : Perm (m ⊕ n)} (h : Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl)) : σ ∈ (sumCongrHom m n).range := by - classical have h1 : ∀ x : m ⊕ n, (∃ a : m, Sum.inl a = x) → ∃ a : m, Sum.inl a = σ x := by rintro _ ⟨a, rfl⟩; exact h ⟨a, rfl⟩ have h3 : ∀ x : m ⊕ n, (∃ b : n, Sum.inr b = x) → ∃ b : n, Sum.inr b = σ x := by diff --git a/Mathlib/GroupTheory/PushoutI.lean b/Mathlib/GroupTheory/PushoutI.lean index 4ad57f1eb9e609..94331661c9031f 100644 --- a/Mathlib/GroupTheory/PushoutI.lean +++ b/Mathlib/GroupTheory/PushoutI.lean @@ -563,7 +563,7 @@ theorem prod_injective {ι : Type*} {G : ι → Type*} [(i : ι) → Group (G i) {d : Transversal φ} : Function.Injective (prod : NormalWord d → PushoutI φ) := by let := Classical.decEq ι let := fun i => Classical.decEq (G i) - classical exact equiv.symm.injective + exact equiv.symm.injective instance : FaithfulSMul (PushoutI φ) (NormalWord d) := ⟨fun h => by simpa using congr_arg prod (h empty)⟩ @@ -614,7 +614,6 @@ def Reduced (w : Word G) : Prop := theorem Reduced.exists_normalWord_prod_eq (d : Transversal φ) {w : Word G} (hw : Reduced φ w) : ∃ w' : NormalWord d, w'.prod = ofCoprodI w.prod ∧ w'.toList.map Sigma.fst = w.toList.map Sigma.fst := by - classical induction w using Word.consRecOn with | empty => exact ⟨empty, by simp, rfl⟩ | cons i g w hIdx hg1 ih => diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index cbbde606ac6498..4e16dfabe87cf3 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -315,27 +315,26 @@ theorem IsPGroup.sylow_mem_fixedPoints_iff {P : Subgroup G} (hP : IsPGroup p P) instance Sylow.isPretransitive_of_finite [hp : Fact p.Prime] [Finite (Sylow p G)] : IsPretransitive G (Sylow p G) := ⟨fun P Q => by - classical - have H := fun {R : Sylow p G} {S : orbit G P} => - calc - S ∈ fixedPoints R (orbit G P) ↔ S.1 ∈ fixedPoints R (Sylow p G) := - forall_congr' fun a => Subtype.ext_iff - _ ↔ R.1 ≤ S := R.2.sylow_mem_fixedPoints_iff - _ ↔ S.1.1 = R := ⟨fun h => R.3 S.1.2 h, ge_of_eq⟩ - suffices Set.Nonempty (fixedPoints Q (orbit G P)) by - exact Exists.elim this fun R hR => by - rw [← Sylow.ext (H.mp hR)] - exact R.2 - apply Q.2.nonempty_fixed_point_of_prime_not_dvd_card - refine fun h => hp.out.not_dvd_one (Nat.modEq_zero_iff_dvd.mp ?_) + have H := fun {R : Sylow p G} {S : orbit G P} => calc - 1 = Nat.card (fixedPoints P (orbit G P)) := ?_ - _ ≡ Nat.card (orbit G P) [MOD p] := (P.2.card_modEq_card_fixedPoints (orbit G P)).symm - _ ≡ 0 [MOD p] := Nat.modEq_zero_iff_dvd.mpr h - rw [← Nat.card_unique (α := ({⟨P, mem_orbit_self P⟩} : Set (orbit G P))), eq_comm] - congr - rw [Set.eq_singleton_iff_unique_mem] - exact ⟨H.mpr rfl, fun R h => Subtype.ext (Sylow.ext (H.mp h))⟩⟩ + S ∈ fixedPoints R (orbit G P) ↔ S.1 ∈ fixedPoints R (Sylow p G) := + forall_congr' fun a => Subtype.ext_iff + _ ↔ R.1 ≤ S := R.2.sylow_mem_fixedPoints_iff + _ ↔ S.1.1 = R := ⟨fun h => R.3 S.1.2 h, ge_of_eq⟩ + suffices Set.Nonempty (fixedPoints Q (orbit G P)) by + exact Exists.elim this fun R hR => by + rw [← Sylow.ext (H.mp hR)] + exact R.2 + apply Q.2.nonempty_fixed_point_of_prime_not_dvd_card + refine fun h => hp.out.not_dvd_one (Nat.modEq_zero_iff_dvd.mp ?_) + calc + 1 = Nat.card (fixedPoints P (orbit G P)) := ?_ + _ ≡ Nat.card (orbit G P) [MOD p] := (P.2.card_modEq_card_fixedPoints (orbit G P)).symm + _ ≡ 0 [MOD p] := Nat.modEq_zero_iff_dvd.mpr h + rw [← Nat.card_unique (α := ({⟨P, mem_orbit_self P⟩} : Set (orbit G P))), eq_comm] + congr + rw [Set.eq_singleton_iff_unique_mem] + exact ⟨H.mpr rfl, fun R h => Subtype.ext (Sylow.ext (H.mp h))⟩⟩ variable (p) (G) diff --git a/Mathlib/GroupTheory/Transfer.lean b/Mathlib/GroupTheory/Transfer.lean index 17c0205663b2a4..5d9b275211ff7a 100644 --- a/Mathlib/GroupTheory/Transfer.lean +++ b/Mathlib/GroupTheory/Transfer.lean @@ -165,21 +165,20 @@ theorem transfer_eq_prod_quotient_orbitRel_zpowers_quot [FiniteIndex H] (g : G) ϕ ⟨q.out.out⁻¹ * g ^ Function.minimalPeriod (g • ·) q.out * q.out.out, QuotientGroup.out_conj_pow_minimalPeriod_mem H g q.out⟩ := by - classical - let := H.fintypeQuotientOfFiniteIndex - calc - transfer ϕ g = ∏ q : G ⧸ H, _ := transfer_def ϕ (transferTransversal H g) g - _ = _ := ((quotientEquivSigmaZMod H g).symm.prod_comp _).symm - _ = _ := Finset.prod_sigma _ _ _ - _ = _ := by - refine Fintype.prod_congr _ _ (fun q => ?_) - simp only [quotientEquivSigmaZMod_symm_apply, transferTransversal_apply', - transferTransversal_apply''] - rw [Fintype.prod_eq_single (0 : ZMod (Function.minimalPeriod (g • ·) q.out)) _] - · simp only [if_pos, ZMod.cast_zero, zpow_zero, one_mul, mul_assoc] - · intro k hk - simp only [if_neg hk, inv_mul_cancel] - exact map_one ϕ + let := H.fintypeQuotientOfFiniteIndex + calc + transfer ϕ g = ∏ q : G ⧸ H, _ := transfer_def ϕ (transferTransversal H g) g + _ = _ := ((quotientEquivSigmaZMod H g).symm.prod_comp _).symm + _ = _ := Finset.prod_sigma _ _ _ + _ = _ := by + refine Fintype.prod_congr _ _ (fun q => ?_) + simp only [quotientEquivSigmaZMod_symm_apply, transferTransversal_apply', + transferTransversal_apply''] + rw [Fintype.prod_eq_single (0 : ZMod (Function.minimalPeriod (g • ·) q.out)) _] + · simp only [if_pos, ZMod.cast_zero, zpow_zero, one_mul, mul_assoc] + · intro k hk + simp only [if_neg hk, inv_mul_cancel] + exact map_one ϕ open scoped IsMulCommutative in /-- Auxiliary lemma in order to state `transfer_eq_pow`. -/ diff --git a/Mathlib/LinearAlgebra/AffineSpace/Basis.lean b/Mathlib/LinearAlgebra/AffineSpace/Basis.lean index f7e58ce586ba0a..8e2f81e7905bd2 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Basis.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Basis.lean @@ -184,7 +184,7 @@ theorem linear_eq_sumCoords (i : ι) : (b.coord i).linear = -(b.basisOf i).sumCo @[simp] theorem coord_reindex (i : ι') : (b.reindex e).coord i = b.coord (e.symm i) := by ext - classical simp [AffineBasis.coord] + simp [AffineBasis.coord] @[simp] theorem coord_apply_eq (i : ι) : b.coord i (b i) = 1 := by diff --git a/Mathlib/LinearAlgebra/Basis/Cardinality.lean b/Mathlib/LinearAlgebra/Basis/Cardinality.lean index e111ee2dcdf5b8..fc1258c2beb978 100644 --- a/Mathlib/LinearAlgebra/Basis/Cardinality.lean +++ b/Mathlib/LinearAlgebra/Basis/Cardinality.lean @@ -103,7 +103,7 @@ theorem union_support_maximal_linearIndependent_eq_range_basis {ι : Type w} (b have l₁ : l.some = l'.some := ind <| b.repr.injective <| ext fun j ↦ by obtain rfl | ne := eq_or_ne i j · simp_rw [repr_eq_zero] - classical simpa [single_apply, ne] using congr(b.repr $z j) + simpa [single_apply, ne] using congr(b.repr $z j) exact DFunLike.congr_fun l₁ a exact r'' (m (range v') i' r) diff --git a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean index b345f010b225ac..f513825c0aa530 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Orthogonal.lean @@ -121,16 +121,15 @@ theorem isOrtho_smul_right {x y : M₄} {a : R₄} (ha : a ≠ 0) : if for all `i`, `B (v i) (v i) ≠ 0`. -/ theorem linearIndependent_of_iIsOrtho {n : Type w} {B : BilinForm K V} {v : n → V} (hv₁ : B.iIsOrtho v) (hv₂ : ∀ i, B (v i) (v i) ≠ 0) : LinearIndependent K v := by - classical - rw [linearIndependent_iff'] - intro s w hs i hi - have : B (s.sum fun i : n => w i • v i) (v i) = 0 := by rw [hs, zero_left] - have hsum : (s.sum fun j : n => w j * B (v j) (v i)) = w i * B (v i) (v i) := by - apply Finset.sum_eq_single_of_mem i hi - intro j _ hij - rw [iIsOrtho_def.1 hv₁ _ _ hij, mul_zero] - simp_rw [sum_left, smul_left, hsum] at this - exact eq_zero_of_ne_zero_of_mul_right_eq_zero (hv₂ i) this + rw [linearIndependent_iff'] + intro s w hs i hi + have : B (s.sum fun i : n => w i • v i) (v i) = 0 := by rw [hs, zero_left] + have hsum : (s.sum fun j : n => w j * B (v j) (v i)) = w i * B (v i) (v i) := by + apply Finset.sum_eq_single_of_mem i hi + intro j _ hij + rw [iIsOrtho_def.1 hv₁ _ _ hij, mul_zero] + simp_rw [sum_left, smul_left, hsum] at this + exact eq_zero_of_ne_zero_of_mul_right_eq_zero (hv₂ i) this end diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 41d5ba4cfd525a..7af851413cdd2a 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -234,7 +234,6 @@ theorem det_toLin' (f : Matrix ι ι R) : LinearMap.det (Matrix.toLin' f) = Matr theorem det_cases [DecidableEq M] {P : A → Prop} (f : M →ₗ[A] M) (hb : ∀ (s : Finset M) (b : Basis s A M), P (Matrix.det (toMatrix b b f))) (h1 : P 1) : P (LinearMap.det f) := by - classical if H : ∃ s : Finset M, Nonempty (Basis s A M) then obtain ⟨s, ⟨b⟩⟩ := H rw [← det_toMatrix b] diff --git a/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean b/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean index b01b9a20735fb0..2e6f917a2ce024 100644 --- a/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean +++ b/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean @@ -56,9 +56,8 @@ theorem Module.Basis.finite_ofVectorSpaceIndex_of_rank_lt_aleph0 (h : Module.ran /-- Also see `rank_quotient_add_rank`. -/ theorem rank_quotient_add_rank_of_divisionRing (p : Submodule K V) : Module.rank K (V ⧸ p) + Module.rank K p = Module.rank K V := by - classical - let ⟨f⟩ := quotient_prod_linearEquiv p - exact rank_prod'.symm.trans f.rank_eq + let ⟨f⟩ := quotient_prod_linearEquiv p + exact rank_prod'.symm.trans f.rank_eq instance DivisionRing.hasRankNullity : HasRankNullity.{u₀} K where rank_quotient_add_rank := rank_quotient_add_rank_of_divisionRing diff --git a/Mathlib/LinearAlgebra/Dimension/Localization.lean b/Mathlib/LinearAlgebra/Dimension/Localization.lean index 9cefb23f6802de..d1034e24765706 100644 --- a/Mathlib/LinearAlgebra/Dimension/Localization.lean +++ b/Mathlib/LinearAlgebra/Dimension/Localization.lean @@ -217,7 +217,6 @@ variable {R} [Ring R] [IsDomain R] See [cohn_1995] Proposition 1.3.6 -/ lemma aleph0_le_rank_of_isEmpty_oreSet (hS : IsEmpty (OreLocalization.OreSet R⁰)) : ℵ₀ ≤ Module.rank R R := by - classical rw [← not_nonempty_iff, OreLocalization.nonempty_oreSet_iff_of_noZeroDivisors] at hS push Not at hS obtain ⟨r, s, h⟩ := hS diff --git a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean index d7b19b667c68df..b08f0a89857777 100644 --- a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean @@ -67,7 +67,6 @@ variable [InvariantBasisNumber R] have the same cardinalities. -/ theorem mk_eq_mk_of_basis (v : Basis ι R M) (v' : Basis ι' R M) : Cardinal.lift.{w'} #ι = Cardinal.lift.{w} #ι' := by - classical have := nontrivial_of_invariantBasisNumber R cases fintypeOrInfinite ι · -- `v` is a finite basis, so by `basis_finite_of_finite_spans` so is `v'`. diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean index 7fc2c784f0d21b..6c25b2c94354e5 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean @@ -398,29 +398,28 @@ variable [DivisionRing K] [AddCommGroup V] [Module K V] theorem exists_ker_pow_eq_ker_pow_succ [FiniteDimensional K V] (f : End K V) : ∃ k : ℕ, k ≤ finrank K V ∧ LinearMap.ker (f ^ k) = LinearMap.ker (f ^ k.succ) := by - classical - by_contra h_contra - simp_rw [not_exists, not_and] at h_contra - have h_le_ker_pow : ∀ n : ℕ, n ≤ (finrank K V).succ → - n ≤ finrank K (LinearMap.ker (f ^ n)) := by - intro n hn - induction n with - | zero => exact zero_le - | succ n ih => - have h_ker_lt_ker : LinearMap.ker (f ^ n) < LinearMap.ker (f ^ n.succ) := by - refine lt_of_le_of_ne ?_ (h_contra n (Nat.le_of_succ_le_succ hn)) - rw [pow_succ'] - apply LinearMap.ker_le_ker_comp - have h_finrank_lt_finrank : - finrank K (LinearMap.ker (f ^ n)) < finrank K (LinearMap.ker (f ^ n.succ)) := by - apply Submodule.finrank_lt_finrank_of_lt h_ker_lt_ker - calc - n.succ ≤ (finrank K ↑(LinearMap.ker (f ^ n))).succ := - Nat.succ_le_succ (ih (Nat.le_of_succ_le hn)) - _ ≤ finrank K ↑(LinearMap.ker (f ^ n.succ)) := Nat.succ_le_of_lt h_finrank_lt_finrank - have h_any_n_lt : ∀ n, n ≤ (finrank K V).succ → n ≤ finrank K V := fun n hn => - (h_le_ker_pow n hn).trans (Submodule.finrank_le _) - exact Nat.not_succ_le_self _ (h_any_n_lt (finrank K V).succ (finrank K V).succ.le_refl) + by_contra h_contra + simp_rw [not_exists, not_and] at h_contra + have h_le_ker_pow : ∀ n : ℕ, n ≤ (finrank K V).succ → + n ≤ finrank K (LinearMap.ker (f ^ n)) := by + intro n hn + induction n with + | zero => exact zero_le + | succ n ih => + have h_ker_lt_ker : LinearMap.ker (f ^ n) < LinearMap.ker (f ^ n.succ) := by + refine lt_of_le_of_ne ?_ (h_contra n (Nat.le_of_succ_le_succ hn)) + rw [pow_succ'] + apply LinearMap.ker_le_ker_comp + have h_finrank_lt_finrank : + finrank K (LinearMap.ker (f ^ n)) < finrank K (LinearMap.ker (f ^ n.succ)) := by + apply Submodule.finrank_lt_finrank_of_lt h_ker_lt_ker + calc + n.succ ≤ (finrank K ↑(LinearMap.ker (f ^ n))).succ := + Nat.succ_le_succ (ih (Nat.le_of_succ_le hn)) + _ ≤ finrank K ↑(LinearMap.ker (f ^ n.succ)) := Nat.succ_le_of_lt h_finrank_lt_finrank + have h_any_n_lt : ∀ n, n ≤ (finrank K V).succ → n ≤ finrank K V := fun n hn => + (h_le_ker_pow n hn).trans (Submodule.finrank_le _) + exact Nat.not_succ_le_self _ (h_any_n_lt (finrank K V).succ (finrank K V).succ.le_refl) theorem ker_pow_eq_ker_pow_finrank_of_le [FiniteDimensional K V] {f : End K V} {m : ℕ} (hm : finrank K V ≤ m) : LinearMap.ker (f ^ m) = LinearMap.ker (f ^ finrank K V) := by diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index 68ad97b090c321..758052df68067c 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -253,7 +253,7 @@ theorem linearCombinationOn_range (s : Set α) : theorem linearCombination_restrict (s : Set α) : linearCombination R (s.restrict v) = Submodule.subtype _ ∘ₗ linearCombinationOn α M R v s ∘ₗ (supportedEquivFinsupp s).symm.toLinearMap := by - classical ext; simp [linearCombinationOn] + ext; simp [linearCombinationOn] theorem linearCombination_comp (f : α' → α) : linearCombination R (v ∘ f) = (linearCombination R v).comp (lmapDomain R R f) := by diff --git a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean index 96ece9a77addc2..a0d45d69e07794 100644 --- a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean @@ -54,7 +54,6 @@ open Finsupp (linearCombination) theorem linearIndependent_single (hf : ∀ i, LinearIndependent R (f i)) : LinearIndependent R fun ix : Σ i, φ i ↦ single ix.1 (f ix.1 ix.2) := by - classical have : linearCombination R (fun ix : Σ i, φ i ↦ single ix.1 (f ix.1 ix.2)) = DFinsupp.mapRange.linearMap (fun i ↦ linearCombination R (f i)) ∘ₗ (sigmaFinsuppLequivDFinsupp R).toLinearMap := by ext; simp diff --git a/Mathlib/LinearAlgebra/Matrix/Ideal.lean b/Mathlib/LinearAlgebra/Matrix/Ideal.lean index 1ed4a0c51d8756..d414c545833ef4 100644 --- a/Mathlib/LinearAlgebra/Matrix/Ideal.lean +++ b/Mathlib/LinearAlgebra/Matrix/Ideal.lean @@ -189,7 +189,6 @@ theorem ofMatrix_rel [DecidableEq n] {c : RingCon (Matrix n n R)} {x y : R} : @[simp] theorem ofMatrix_matrix [DecidableEq n] [Nonempty n] (c : RingCon R) : ofMatrix (matrix n c) = c := by ext x y - classical constructor · intro h inhabit n @@ -210,7 +209,6 @@ congruence relation `!![⊤,⊤;⊤,(· ≡ · [PMOD 4])]` is a ring congruence theorem matrix_ofMatrix [DecidableEq n] (c : RingCon (Matrix n n R)) : matrix n (ofMatrix c) = c := by ext x y - classical constructor · intro h rw [matrix_eq_sum_single x, matrix_eq_sum_single y] diff --git a/Mathlib/LinearAlgebra/Matrix/PosDef.lean b/Mathlib/LinearAlgebra/Matrix/PosDef.lean index 586bda860a5a56..0333e51feeb5ca 100644 --- a/Mathlib/LinearAlgebra/Matrix/PosDef.lean +++ b/Mathlib/LinearAlgebra/Matrix/PosDef.lean @@ -282,7 +282,7 @@ theorem _root_.Matrix.posDef_conjTranspose_iff {M : Matrix n n R} : Mᴴ.PosDef ⟨(by simpa using ·.conjTranspose), .conjTranspose⟩ lemma diag_pos [Nontrivial R] {A : Matrix n n R} (hA : A.PosDef) {i : n} : 0 < A i i := by - classical simpa [trace] using hA.2 (x := Finsupp.single i 1) + simpa [trace] using hA.2 (x := Finsupp.single i 1) end PosDef diff --git a/Mathlib/LinearAlgebra/Matrix/Rank.lean b/Mathlib/LinearAlgebra/Matrix/Rank.lean index 95b199b09ff306..4293b61edb276d 100644 --- a/Mathlib/LinearAlgebra/Matrix/Rank.lean +++ b/Mathlib/LinearAlgebra/Matrix/Rank.lean @@ -118,7 +118,6 @@ lemma eRank_le_card_width [StrongRankCondition R] (A : Matrix m n R) : A.eRank exact A.cRank_le_card_width lemma eRank_le_card_height [StrongRankCondition R] (A : Matrix m n R) : A.eRank ≤ ENat.card m := by - classical wlog hfin : Finite m · simp [ENat.card_eq_top.2 (by simpa using hfin)] have _ := Fintype.ofFinite m diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index 1ba86b265e8534..fc99320116a591 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -674,7 +674,6 @@ lemma diag_eq_diag2n_prod (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) (⟨diagonal D, hD⟩ : SpecialLinearGroup ι F) = Finset.noncommProd {i : ι | i ≠ i₀} (fun i ↦ if hi : i ≠ i₀ then diag2n hi (D i) (diagonal_neZero D hD i) else 1) (diag_commute i₀ D hD) := by - classical set g : ι → ι → F := fun i k ↦ if k = i then D i else if k = i₀ then (D i)⁻¹ else 1 with hg_def apply coeMonoidHom_injective rw [Finset.map_noncommProd] diff --git a/Mathlib/LinearAlgebra/Matrix/WithConv.lean b/Mathlib/LinearAlgebra/Matrix/WithConv.lean index 8307d12892cd6f..18c2de86a5ebcf 100644 --- a/Mathlib/LinearAlgebra/Matrix/WithConv.lean +++ b/Mathlib/LinearAlgebra/Matrix/WithConv.lean @@ -122,7 +122,7 @@ def matrixToLin'StarAlgEquiv : WithConv (Matrix m n α) ≃⋆ₐ[α] WithConv ((n → α) →ₗ[α] m → α) where __ := congrLinearEquiv toLin' map_mul' _ _ := by ext; simp - map_star' _ := by classical exact Matrix.intrinsicStar_toLin' _ |>.symm + map_star' _ := by exact Matrix.intrinsicStar_toLin' _ |>.symm @[simp] lemma matrixToLin'StarAlgEquiv_apply (x : WithConv (Matrix m n α)) : matrixToLin'StarAlgEquiv m n α x = toConv x.ofConv.toLin' := rfl diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index a431fec8662b6e..ab0e63116f95c1 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -731,7 +731,6 @@ lemma Module.pi_induction {ι : Type v} [Finite ι] [AddCommMonoid N'] [Module R N] [Module R N'], motive N → motive' N' → motive' (N × N')) (M : ι → Type u) [∀ i, AddCommMonoid (M i)] [∀ i, Module R (M i)] (h : ∀ i, motive (M i)) : motive' (∀ i, M i) := by - classical cases nonempty_fintype ι revert M refine Fintype.induction_empty_option @@ -780,7 +779,6 @@ lemma Module.pi_induction' {ι : Type v} [Finite ι] (R : Type*) [Ring R] [AddCommGroup N'] [Module R N] [Module R N'], motive N → motive' N' → motive' (N × N')) (M : ι → Type u) [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] (h : ∀ i, motive (M i)) : motive' (∀ i, M i) := by - classical cases nonempty_fintype ι revert M refine Fintype.induction_empty_option diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean b/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean index 8596b4dcc08cb9..dd39c1b9923753 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean @@ -50,7 +50,6 @@ variable [CommRing R] [AddCommGroup M] [Module R M] theorem separatingLeft_dualProd : (dualProd R M).SeparatingLeft ↔ Function.Injective (Module.Dual.eval R M) := by - classical rw [separatingLeft_iff_ker_eq_bot, ker_eq_bot] let e := LinearEquiv.prodComm R _ _ ≪≫ₗ Module.dualProdDualEquivDual R (Module.Dual R M) M let h_d := e.symm.toLinearMap.comp (dualProd R M) diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean b/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean index 1dcfb657e36cc5..0a9dd0e186de8c 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean @@ -188,7 +188,6 @@ private lemma negSemidef_spanSubset (s : Set ι) (hs : ∀ i ∈ s, w i ≤ 0) : /-- Key lemma for Sylvester's law of inertia: compute the signature of a weighted sum of squares. -/ lemma sigPos_weightedSumSquares : sigPos (weightedSumSquares 𝕜 w) = {i | 0 < w i}.ncard := by - classical let p : Set ι := {i | 0 < w i} let m : Set ι := {i | w i ≤ 0} convert_to sigPos _ = p.ncard @@ -212,7 +211,6 @@ lemma sigNeg_weightedSumSquares : private lemma sigPos_add_sigNeg_add_radical₁ : sigPos (weightedSumSquares 𝕜 w) + sigNeg (weightedSumSquares 𝕜 w) + Module.finrank 𝕜 (weightedSumSquares 𝕜 w).radical = Nat.card ι := by - classical rw [radical_weightedSumSquares, sigPos_weightedSumSquares, sigNeg_weightedSumSquares, Pi.dim_spanSubset] calc {i | 0 < w i}.ncard + {i | w i < 0}.ncard + {i | w i = 0}.ncard diff --git a/Mathlib/LinearAlgebra/RootSystem/Base.lean b/Mathlib/LinearAlgebra/RootSystem/Base.lean index 0bc7398af7dc34..314de2a236f0d9 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Base.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Base.lean @@ -154,7 +154,6 @@ lemma eq_one_or_neg_one_of_mem_support_of_smul_mem_aux [Finite ι] [IsAddTorsionFree M] [IsAddTorsionFree N] (i : ι) (h : i ∈ b.support) (t : R) (ht : t • P.root i ∈ range P.root) : ∃ z : ℤ, z * t = 1 := by - classical obtain ⟨j, hj⟩ := ht obtain ⟨f, hf⟩ : ∃ f : b.support → ℤ, P.coroot i = ∑ i, (t * f i) • P.coroot i := by have : P.coroot j ∈ span ℤ (P.coroot '' b.support) := b.coroot_mem_span_int j diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean index f78200eabdb85e..65c0ab3b29b227 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean @@ -283,7 +283,6 @@ lemma ω_mul_f [Fintype ι] (i : b.support) : lemma lie_e_f_mul_ω [Fintype ι] (i j : b.support) : ⁅e i, f j⁆ * ω b = -ω b * ⁅e j, f i⁆ := by - classical calc ⁅e i, f j⁆ * ω b = e i * f j * ω b - f j * e i * ω b := by rw [Ring.lie_def, sub_mul] _ = e i * (f j * ω b) - f j * (e i * ω b) := by rw [mul_assoc, mul_assoc] _ = e i * (ω b * e j) - f j * (ω b * f i) := by rw [← ω_mul_e, ← ω_mul_f] diff --git a/Mathlib/LinearAlgebra/SModEq/Basic.lean b/Mathlib/LinearAlgebra/SModEq/Basic.lean index 52dcacb6cb1d40..ba70e88496bc93 100644 --- a/Mathlib/LinearAlgebra/SModEq/Basic.lean +++ b/Mathlib/LinearAlgebra/SModEq/Basic.lean @@ -93,7 +93,6 @@ theorem add (hxy₁ : x₁ ≡ y₁ [SMOD U]) (hxy₂ : x₂ ≡ y₂ [SMOD U]) @[gcongr] theorem sum {ι} {s : Finset ι} {x y : ι → M} (hxy : ∀ i ∈ s, x i ≡ y i [SMOD U]) : ∑ i ∈ s, x i ≡ ∑ i ∈ s, y i [SMOD U] := by - classical induction s using Finset.cons_induction with | empty => simp [SModEq.rfl] | cons i s _ ih => @@ -124,7 +123,6 @@ theorem mul {I : Ideal A} {x₁ x₂ y₁ y₂ : A} (hxy₁ : x₁ ≡ y₁ [SMO @[gcongr] theorem prod {I : Ideal A} {ι} {s : Finset ι} {x y : ι → A} (hxy : ∀ i ∈ s, x i ≡ y i [SMOD I]) : ∏ i ∈ s, x i ≡ ∏ i ∈ s, y i [SMOD I] := by - classical induction s using Finset.cons_induction with | empty => simp [SModEq.rfl] | cons i s _ ih => diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean index ac8fa0c5f91077..2bf7edd06ba716 100644 --- a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean @@ -120,17 +120,16 @@ theorem ortho_smul_right {B : V₁ →ₛₗ[I₁] V₂ →ₛₗ[I₂] V} {x y} independent if for all `i`, `B (v i) (v i) ≠ 0`. -/ theorem linearIndependent_of_isOrthoᵢ {B : V₁ →ₛₗ[I₁] V₁ →ₛₗ[I₁'] V} {v : n → V₁} (hv₁ : B.IsOrthoᵢ v) (hv₂ : ∀ i, B (v i) (v i) ≠ 0) : LinearIndependent K₁ v := by - classical - rw [linearIndependent_iff'] - intro s w hs i hi - have : B (s.sum fun i : n ↦ w i • v i) (v i) = 0 := by rw [hs, map_zero, zero_apply] - have hsum : (s.sum fun j : n ↦ I₁ (w j) • B (v j) (v i)) = I₁ (w i) • B (v i) (v i) := by - apply Finset.sum_eq_single_of_mem i hi - intro j _hj hij - rw [isOrthoᵢ_def.1 hv₁ _ _ hij, smul_zero] - simp_rw [B.map_sum₂, map_smulₛₗ₂, hsum] at this - apply (map_eq_zero I₁).mp - exact (smul_eq_zero.mp this).elim _root_.id (hv₂ i · |>.elim) + rw [linearIndependent_iff'] + intro s w hs i hi + have : B (s.sum fun i : n ↦ w i • v i) (v i) = 0 := by rw [hs, map_zero, zero_apply] + have hsum : (s.sum fun j : n ↦ I₁ (w j) • B (v j) (v i)) = I₁ (w i) • B (v i) (v i) := by + apply Finset.sum_eq_single_of_mem i hi + intro j _hj hij + rw [isOrthoᵢ_def.1 hv₁ _ _ hij, smul_zero] + simp_rw [B.map_sum₂, map_smulₛₗ₂, hsum] at this + apply (map_eq_zero I₁).mp + exact (smul_eq_zero.mp this).elim _root_.id (hv₂ i · |>.elim) end Field diff --git a/Mathlib/Logic/Equiv/Fintype.lean b/Mathlib/Logic/Equiv/Fintype.lean index 9c332cc9109a10..85d45a2e568841 100644 --- a/Mathlib/Logic/Equiv/Fintype.lean +++ b/Mathlib/Logic/Equiv/Fintype.lean @@ -167,7 +167,6 @@ theorem Perm.exists_extending_pair [Finite α] theorem Perm.exists_map_finset_eq (s t : Finset β) (h : s.card = t.card) : ∃ σ : Perm β, s.map σ.toEmbedding = t := by - classical obtain ⟨σ, hσ⟩ := Perm.exists_extending_pair (fun x : s => (x : β)) (fun x : s => ((s.equivOfCardEq h) x : β)) Subtype.val_injective (Subtype.val_injective.comp (s.equivOfCardEq h).injective) diff --git a/Mathlib/Logic/Hydra.lean b/Mathlib/Logic/Hydra.lean index 0990defc7d53f0..bb0149f4ab9829 100644 --- a/Mathlib/Logic/Hydra.lean +++ b/Mathlib/Logic/Hydra.lean @@ -64,7 +64,6 @@ theorem cutExpand_le_invImage_lex [DecidableEq α] [Std.Irrefl r] : CutExpand r ≤ InvImage (Finsupp.Lex (rᶜ ⊓ (· ≠ ·)) (· < ·)) toFinsupp := by rintro s t ⟨u, a, hr, he⟩ replace hr := fun a' ↦ mt (hr a') - classical refine ⟨a, fun b h ↦ ?_, ?_⟩ <;> simp_rw [toFinsupp_apply] · apply_fun count b at he simpa only [count_add, count_singleton, if_neg h.2, add_zero, count_eq_zero.2 (hr b h.1)] diff --git a/Mathlib/MeasureTheory/Constructions/Pi.lean b/Mathlib/MeasureTheory/Constructions/Pi.lean index 1e8728a5b51a1f..888e669c9737ed 100644 --- a/Mathlib/MeasureTheory/Constructions/Pi.lean +++ b/Mathlib/MeasureTheory/Constructions/Pi.lean @@ -369,14 +369,12 @@ theorem pi_eval_preimage_null {i : ι} {s : Set (α i)} (hs : μ i s = 0) : theorem quasiMeasurePreserving_eval (i : ι) : QuasiMeasurePreserving (Function.eval i) (Measure.pi μ) (μ i) := by - classical refine ⟨by fun_prop, AbsolutelyContinuous.mk fun s hs h2s => ?_⟩ rw [map_apply (by fun_prop) hs, pi_eval_preimage_null μ h2s] lemma pi_map_eval [DecidableEq ι] (i : ι) : (Measure.pi μ).map (Function.eval i) = (∏ j ∈ Finset.univ.erase i, μ j Set.univ) • (μ i) := by ext s hs - classical rw [Measure.map_apply (measurable_pi_apply i) hs, ← Set.univ_pi_update_univ, Measure.pi_pi, Measure.smul_apply, smul_eq_mul, ← Finset.prod_erase_mul _ _ (a := i) (by simp)] congrm ?_ * ?_ @@ -934,7 +932,6 @@ theorem measurePreserving_arrowCongr' {α₁ β₁ α₂ β₂ : Type*} [Fintype (hm : ∀ i, MeasurePreserving eβ (μ i) (ν (eα i))) : MeasurePreserving (MeasurableEquiv.arrowCongr' eα eβ) (Measure.pi fun i ↦ μ i) (Measure.pi fun i ↦ ν i) := by - classical convert! (measurePreserving_piCongrLeft (fun i : α₂ ↦ ν i) eα).comp (measurePreserving_pi μ (fun i : α₁ ↦ ν (eα i)) hm) diff --git a/Mathlib/MeasureTheory/Constructions/Projective.lean b/Mathlib/MeasureTheory/Constructions/Projective.lean index b963e82a21221e..f448461779196c 100644 --- a/Mathlib/MeasureTheory/Constructions/Projective.lean +++ b/Mathlib/MeasureTheory/Constructions/Projective.lean @@ -63,7 +63,6 @@ lemma eq_zero_of_isEmpty [h : IsEmpty (Π i, α i)] /-- Auxiliary lemma for `measure_univ_eq`. -/ lemma measure_univ_eq_of_subset (hP : IsProjectiveMeasureFamily P) (hJI : J ⊆ I) : P I univ = P J univ := by - classical have : (univ : Set (∀ i : I, α i)) = Finset.restrict₂ hJI ⁻¹' (univ : Set (∀ i : J, α i)) := by rw [preimage_univ] diff --git a/Mathlib/MeasureTheory/Covering/Vitali.lean b/Mathlib/MeasureTheory/Covering/Vitali.lean index 431125f68cf616..e14e5573397922 100644 --- a/Mathlib/MeasureTheory/Covering/Vitali.lean +++ b/Mathlib/MeasureTheory/Covering/Vitali.lean @@ -260,7 +260,6 @@ theorem exists_disjoint_covering_ae use the whole family `t`, but a subfamily `t'` supported on small balls (which is possible since the family is assumed to be fine at every point of `s`). -/ - classical -- choose around each `x` a small ball on which the measure is finite have : ∀ x, ∃ R, 0 < R ∧ R ≤ 1 ∧ μ (closedBall x (20 * R)) < ∞ := fun x ↦ by refine ((eventually_le_nhds one_pos).and ?_).exists_gt diff --git a/Mathlib/MeasureTheory/Function/LpSpace/InfiniteSum.lean b/Mathlib/MeasureTheory/Function/LpSpace/InfiniteSum.lean index 75fc22d9e98912..a3a8d6ffea084b 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/InfiniteSum.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/InfiniteSum.lean @@ -122,7 +122,6 @@ private theorem hasSum_coeFn_tsum_nat {p : ℝ≥0∞} [hp : Fact (1 ≤ p)] theorem hasSum_coeFn_tsum {p : ℝ≥0∞} [hp : Fact (1 ≤ p)] {ι : Type*} [Countable ι] [CompleteSpace E] {f : ι → Lp E p μ} (hf : ∑' n, ‖f n‖ₑ ≠ ∞) : ∀ᵐ a ∂μ, HasSum (fun n ↦ f n a) (⇑(∑' n, f n) a) := by - classical rcases finite_or_infinite ι with hι | hι · let : Fintype ι := Fintype.ofFinite ι filter_upwards [coeFn_fun_finsetSum univ f] with x hx diff --git a/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean b/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean index 58a130612dcecb..d72d09c1962ef4 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/VitaliCaratheodory.lean @@ -111,7 +111,6 @@ theorem SimpleFunc.exists_le_lowerSemicontinuous_lintegral_ge (f : α →ₛ ℝ SimpleFunc.coe_piecewise, le_zero_iff] · simp only [lintegral_const, zero_mul, zero_le, ENNReal.coe_zero] have ne_top : μ s ≠ ⊤ := by - classical simpa [f, hs, hc, lt_top_iff_ne_top, SimpleFunc.coe_const, Function.const_apply, lintegral_const, ENNReal.coe_indicator, Set.univ_inter, ENNReal.coe_ne_top, MeasurableSet.univ, ENNReal.mul_eq_top, SimpleFunc.const_zero, @@ -129,7 +128,6 @@ theorem SimpleFunc.exists_le_lowerSemicontinuous_lintegral_ge (f : α →ₛ ℝ Set.piecewise_eq_indicator, SimpleFunc.coe_piecewise, ← Function.const_def] grw [su] · suffices (c : ℝ≥0∞) * μ u ≤ c * μ s + ε by - classical simpa only [ENNReal.coe_indicator, u_open.measurableSet, lintegral_indicator, lintegral_const, MeasurableSet.univ, Measure.restrict_apply, Set.univ_inter, const_zero, coe_piecewise, coe_const, coe_zero, Set.piecewise_eq_indicator, Function.const_apply, hs] @@ -312,7 +310,6 @@ theorem SimpleFunc.exists_upperSemicontinuous_le_lintegral_le (f : α →ₛ ℝ (∫⁻ x, f x ∂μ) ≤ (∫⁻ x, g x ∂μ) + ε := by induction f using MeasureTheory.SimpleFunc.induction generalizing ε with | @const c s hs => - classical by_cases hc : c = 0 · exact ⟨fun _ => 0, by simp [hc, upperSemicontinuous_const]⟩ have μs_lt_top : μ s < ∞ := by simpa [hs, hc, ENNReal.mul_eq_top, lt_top_iff_ne_top] using int_f diff --git a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean index 532e06a0b45274..f55fe7f662619e 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean @@ -479,7 +479,6 @@ lemma measurableSet_generateFrom_memPartition_iff (t : ℕ → Set α) (n : ℕ) | empty => exact ⟨∅, by simp, by simp⟩ | compl u _ hu => obtain ⟨S, hS_subset, rfl⟩ := hu - classical refine ⟨(memPartition t n).toFinset \ S, ?_, ?_⟩ · simp only [Finset.coe_sdiff, coe_toFinset] exact sdiff_subset diff --git a/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean index f00d8bdb7368a8..cfb6d248b68e92 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean @@ -32,7 +32,6 @@ namespace MeasurableSpace /-- The sigma-algebra generated by a single set `s` is `{∅, s, sᶜ, univ}`. -/ @[simp] theorem generateFrom_singleton (s : Set α) : generateFrom {s} = MeasurableSpace.comap (· ∈ s) ⊤ := by - classical let : MeasurableSpace α := generateFrom {s} refine le_antisymm (generateFrom_le fun t ht => ⟨{True}, trivial, by simp [ht.symm]⟩) ?_ rintro _ ⟨u, -, rfl⟩ diff --git a/Mathlib/MeasureTheory/Measure/AddContent.lean b/Mathlib/MeasureTheory/Measure/AddContent.lean index 406fe7eb540342..2784ad6d26a872 100644 --- a/Mathlib/MeasureTheory/Measure/AddContent.lean +++ b/Mathlib/MeasureTheory/Measure/AddContent.lean @@ -108,7 +108,6 @@ lemma addContent_sUnion (h_ss : ↑I ⊆ C) lemma addContent_biUnion {ι : Type*} {a : Finset ι} {f : ι → Set α} (hf : ∀ i ∈ a, f i ∈ C) (h_dis : PairwiseDisjoint ↑a f) (h_mem : ⋃ i ∈ a, f i ∈ C) : m (⋃ i ∈ a, f i) = ∑ i ∈ a, m (f i) := by - classical have A : ⋃ i ∈ a, f i = ⋃₀ (a.image f) := by simp rw [A, addContent_sUnion]; rotate_left · grind @@ -156,7 +155,6 @@ lemma addContent_eq_add_disjointOfDiffUnion_of_subset (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) (hI_ss : ∀ t ∈ I, t ⊆ s) (h_dis : PairwiseDisjoint (I : Set (Set α)) id) : m s = ∑ i ∈ I, m i + ∑ i ∈ hC.disjointOfDiffUnion hs hI, m i := by - classical conv_lhs => rw [← hC.sUnion_union_disjointOfDiffUnion_of_subset hs hI hI_ss] rw [addContent_sUnion] · rw [sum_union] @@ -172,7 +170,6 @@ lemma addContent_eq_add_disjointOfDiffUnion_of_subset (hC : IsSetSemiring C) theorem eq_add_disjointOfDiff_of_subset (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) (hst : s ⊆ t) : m t = m s + ∑ i ∈ hC.disjointOfDiff ht hs, m i := by - classical conv_lhs => rw [← hC.sUnion_insert_disjointOfDiff ht hs hst] rw [← coe_insert, addContent_sUnion] · rw [sum_insert] @@ -285,7 +282,6 @@ lemma sum_addContent_le_of_subset (hC : IsSetSemiring C) (h_ss : ↑I ⊆ C) (h_dis : PairwiseDisjoint (I : Set (Set α)) id) (ht : t ∈ C) (hJt : ∀ s ∈ I, s ⊆ t) : ∑ u ∈ I, m u ≤ m t := by - classical rw [addContent_eq_add_disjointOfDiffUnion_of_subset hC ht h_ss hJt h_dis] exact le_add_right le_rfl @@ -336,7 +332,6 @@ theorem addContent_iUnion_eq_tsum_of_disjoint_of_addContent_iUnion_le {m : AddCo m (⋃ i, f i) = ∑' i, m (f i) := by refine le_antisymm (m_subadd f hf hf_Union hf_disj) ?_ refine ENNReal.summable.tsum_le_of_sum_le fun I ↦ ?_ - classical rw [← Finset.sum_image_of_disjoint addContent_empty (hf_disj.pairwiseDisjoint _)] refine sum_addContent_le_of_subset hC (I := I.image f) ?_ ?_ hf_Union ?_ · simp only [coe_image, Set.image_subset_iff] @@ -400,7 +395,6 @@ noncomputable def AddContent.onIoc (f : α → G) : toFun := AddContent.onIocAux f empty' := AddContent.onIocAux_empty f sUnion' := by - classical /- Consider a finite union of open-closed intervals whose union is again an open-closed interval `(u, v]`. We have to show that the sum of `f b - f a` over the intervals gives `f v - f u`. Informally, `(u, v]` is an ordered @@ -533,7 +527,6 @@ def IsSetRing.addContent_of_union (m : Set α → G) (hC : IsSetRing C) (m_empty toFun := m empty' := m_empty sUnion' I h_ss h_dis h_mem := by - classical induction I using Finset.induction with | empty => simp only [Finset.coe_empty, Set.sUnion_empty, Finset.sum_empty, m_empty] | insert s I hsI h => diff --git a/Mathlib/MeasureTheory/Measure/Dirac.lean b/Mathlib/MeasureTheory/Measure/Dirac.lean index c2bcd777e868f6..a773c3402a4c98 100644 --- a/Mathlib/MeasureTheory/Measure/Dirac.lean +++ b/Mathlib/MeasureTheory/Measure/Dirac.lean @@ -354,7 +354,6 @@ lemma ae_mem_finset_iff : (∀ᵐ a ∂μ, a ∈ s) ↔ μ = ∑ a ∈ s, μ {a} ext t ht rw [← measure_sdiff_null (s := t) hμ] dsimp - classical rw [Set.sdiff_compl, ← (s : Set α).biUnion_of_singleton] simp_rw [Finset.mem_coe, Set.inter_iUnion] rw [measure_biUnion_finset (fun i hi j hj hij ↦ .inter_left' _ <| .inter_right' _ ?_) diff --git a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean index 870fefd7dbc122..1d5afce3f30b57 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean @@ -293,7 +293,6 @@ theorem integral_isMulLeftInvariant_eq_smul_of_hasCompactSupport (μ' μ : Measure G) [IsHaarMeasure μ] [IsFiniteMeasureOnCompacts μ'] [IsMulLeftInvariant μ'] {f : G → ℝ} (hf : Continuous f) (h'f : HasCompactSupport f) : ∫ x, f x ∂μ' = ∫ x, f x ∂(haarScalarFactor μ' μ • μ) := by - classical rcases h'f.eq_zero_or_locallyCompactSpace_of_group hf with Hf | Hf · simp [Hf] · simp only [haarScalarFactor, Hf, not_true_eq_false, ite_false] diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index d109983459085d..bb9ef9fe2cb2d7 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -322,7 +322,6 @@ theorem mkMetric'_isMetric (m : Set X → ℝ≥0∞) : (mkMetric' m).IsMetric : (we use `≤ᶠ[𝓝[≥] 0]` to state this), then `mkMetric m₁ hm₁ ≤ c • mkMetric m₂ hm₂`. -/ theorem mkMetric_mono_smul {m₁ m₂ : ℝ≥0∞ → ℝ≥0∞} {c : ℝ≥0∞} (hc : c ≠ ∞) (h0 : c ≠ 0) (hle : m₁ ≤ᶠ[𝓝[≥] 0] c • m₂) : (mkMetric m₁ : OuterMeasure X) ≤ c • mkMetric m₂ := by - classical rcases (mem_nhdsGE_iff_exists_Ico_subset' zero_lt_one).1 hle with ⟨r, hr0, hr⟩ refine fun s => le_of_tendsto_of_tendsto (mkMetric'.tendsto_pre _ s) diff --git a/Mathlib/MeasureTheory/Measure/Portmanteau.lean b/Mathlib/MeasureTheory/Measure/Portmanteau.lean index 1a39a02bffa3a1..c6961aa0fa8194 100644 --- a/Mathlib/MeasureTheory/Measure/Portmanteau.lean +++ b/Mathlib/MeasureTheory/Measure/Portmanteau.lean @@ -797,7 +797,6 @@ lemma ProbabilityMeasure.exists_lt_measure_biUnion_of_isOpen (h : ∀ (u : Set Ω), IsOpen u → ∀ x ∈ u, ∃ s ∈ S, s ∈ 𝓝 x ∧ s ⊆ u) {G : Set Ω} (hG : IsOpen G) {r : ℝ≥0} (hr : r < ν G) : ∃ T : Finset (Set Ω), (∀ t ∈ T, t ∈ S) ∧ (r < ν (⋃ t ∈ T, t)) ∧ (⋃ t ∈ T, t) ⊆ G := by - classical obtain ⟨T, TS, T_count, hT⟩ : ∃ T : Set (Set Ω), T ⊆ S ∧ T.Countable ∧ ⋃ t ∈ T, t = G := by have : ∀ (x : G), ∃ s ∈ S, s ∈ 𝓝 (x : Ω) ∧ s ⊆ G := fun x ↦ h G hG x x.2 choose! s hsS hs_nhds hsG using this diff --git a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean index 604fffdc981283..87f2aba876a96b 100644 --- a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean +++ b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean @@ -122,7 +122,6 @@ theorem exists_isCompact_closure_measure_compl_lt [TopologicalSpace α] · rw [← compl_iUnion, h_univ, compl_univ] choose! s' s'bound using h3 rcases ENNReal.exists_pos_sum_of_countable' (ne_of_gt hε) ℕ with ⟨δ, hδ1, hδ2⟩ - classical let u : ℕ → ℕ := fun n ↦ s' n (δ n) refine ⟨interUnionBalls seq u t, isCompact_closure_interUnionBalls h_basis.toHasBasis seq u, ?_⟩ rw [interUnionBalls, Set.compl_iInter] diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean index bb8950924f987c..f009a30a3f6990 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean @@ -55,7 +55,6 @@ lemma sfiniteSeq_zero (n : ℕ) : sfiniteSeq (0 : Measure α) n = 0 := This lemma is superseded by the instance below. -/ lemma sfinite_sum_of_countable [Countable ι] (m : ι → Measure α) [∀ n, IsFiniteMeasure (m n)] : SFinite (Measure.sum m) := by - classical obtain ⟨f, hf⟩ : ∃ f : ι → ℕ, Function.Injective f := Countable.exists_injective_nat ι refine ⟨_, fun n ↦ ?_, (sum_extend_zero hf m).symm⟩ rcases em (n ∈ range f) with ⟨i, rfl⟩ | hn diff --git a/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean b/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean index 239c7d93657e88..352bb89446eaae 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean @@ -91,7 +91,6 @@ theorem isCaratheodory_ofFunction_of_mem (hC : IsSetSemiring C) (m : AddContent refine le_iInf fun f ↦ le_iInf fun hf ↦ le_iInf fun hf_subset ↦ ?_ let A : ℕ → Finset (Set α) := fun i ↦ hC.disjointOfDiff (hf i) (hC.inter_mem _ (hf i) _ hs) have h_diff_eq_sUnion i : f i \ s = ⋃₀ A i := by simp [A, IsSetSemiring.sUnion_disjointOfDiff] - classical have h_m_eq i : m (f i) = m (f i ∩ s) + ∑ u ∈ A i, m u := eq_add_disjointOfDiff_of_subset hC (hC.inter_mem (f i) (hf i) s hs) (hf i) inter_subset_left simp_rw [h_m_eq] diff --git a/Mathlib/MeasureTheory/PiSystem.lean b/Mathlib/MeasureTheory/PiSystem.lean index 06bfac122aa2f9..180796a19f7fba 100644 --- a/Mathlib/MeasureTheory/PiSystem.lean +++ b/Mathlib/MeasureTheory/PiSystem.lean @@ -144,7 +144,6 @@ lemma IsPiSystem.prod {C : Set (Set α)} {D : Set (Set β)} (hC : IsPiSystem C) lemma IsPiSystem.biInter_mem {S : Set (Set α)} (h_pi : IsPiSystem S) {t : Finset (Set α)} (t_ne : t.Nonempty) (ht : ∀ s ∈ t, s ∈ S) (h' : (⋂ s ∈ t, s).Nonempty) : (⋂ s ∈ t, s) ∈ S := by - classical induction t_ne using Finset.Nonempty.cons_induction with | singleton a => simpa using ht | cons a t hat t_ne ih => diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 74d5c72231956c..93f5672e20a9d9 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -78,7 +78,6 @@ lemma isPiSystem (hC : IsSetSemiring C) : IsPiSystem C := fun s hs t ht _ ↦ hC theorem exists_finpartition_sdiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : ∃ P : Finpartition (s \ t), ↑P.parts ⊆ C := by - classical obtain ⟨I, hIC, hI, hst⟩ := hC.sdiff_eq_sUnion' s hs t ht refine ⟨.ofErase I (supIndep_iff_pairwiseDisjoint.mpr hI) ?_, ?_⟩ · rw [sup_id_eq_sSup, sSup_eq_sUnion, hst] @@ -89,7 +88,6 @@ theorem exists_finpartition_sdiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t theorem mem_supClosure_iff (hC : IsSetSemiring C) : s ∈ supClosure C ↔ ∃ P : Finpartition s, ↑P.parts ⊆ C where mp := by - classical rintro ⟨S, hS, hSC, rfl⟩ rw [sup'_eq_sup] clear hS @@ -130,7 +128,6 @@ theorem isSetRing_supClosure (hC : IsSetSemiring C) : IsSetRing (supClosure C) w empty_mem := subset_supClosure hC.empty_mem union_mem _ _ h₁ h₂ := supClosed_supClosure h₁ h₂ sdiff_mem := by - classical rintro s _ hs ⟨T, hT, hTC, rfl⟩ rw [sup'_eq_sup] clear hT @@ -159,26 +156,22 @@ noncomputable def disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t lemma empty_notMem_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : ∅ ∉ hC.disjointOfDiff hs ht := by - classical simp only [disjointOfDiff, Finset.mem_sdiff, Finset.mem_singleton, not_true, and_false, not_false_iff] lemma subset_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : ↑(hC.disjointOfDiff hs ht) ⊆ C := by - classical simp only [disjointOfDiff, coe_sdiff, coe_singleton, sdiff_singleton_subset_iff] exact (hC.sdiff_eq_sUnion' s hs t ht).choose_spec.1.trans (Set.subset_insert _ _) lemma pairwiseDisjoint_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : PairwiseDisjoint (hC.disjointOfDiff hs ht : Set (Set α)) id := by - classical simp only [disjointOfDiff, coe_sdiff, coe_singleton] exact Set.PairwiseDisjoint.subset (hC.sdiff_eq_sUnion' s hs t ht).choose_spec.2.1 sdiff_subset lemma sUnion_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : ⋃₀ hC.disjointOfDiff hs ht = s \ t := by - classical rw [(hC.sdiff_eq_sUnion' s hs t ht).choose_spec.2.2] simp only [disjointOfDiff, coe_sdiff, coe_singleton] rw [sUnion_sdiff_singleton_empty] @@ -227,7 +220,6 @@ See `IsSetSemiring.disjointOfDiffUnion` for a definition that gives such a set. lemma exists_disjoint_finset_sdiff_eq (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : ∃ J : Finset (Set α), ↑J ⊆ C ∧ PairwiseDisjoint (J : Set (Set α)) id ∧ s \ ⋃₀ I = ⋃₀ J := by - classical induction I using Finset.induction with | empty => simp only [coe_empty, sUnion_empty, sdiff_empty] @@ -302,26 +294,22 @@ noncomputable def disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI lemma empty_notMem_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : ∅ ∉ hC.disjointOfDiffUnion hs hI := by - classical simp only [disjointOfDiffUnion, Finset.mem_sdiff, Finset.mem_singleton, not_true, and_false, not_false_iff] lemma disjointOfDiffUnion_subset (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : ↑(hC.disjointOfDiffUnion hs hI) ⊆ C := by - classical simp only [disjointOfDiffUnion, coe_sdiff, coe_singleton, sdiff_singleton_subset_iff] exact (hC.exists_disjoint_finset_sdiff_eq hs hI).choose_spec.1.trans (Set.subset_insert _ _) lemma pairwiseDisjoint_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : PairwiseDisjoint (hC.disjointOfDiffUnion hs hI : Set (Set α)) id := by - classical simp only [disjointOfDiffUnion, coe_sdiff, coe_singleton] exact Set.PairwiseDisjoint.subset (hC.exists_disjoint_finset_sdiff_eq hs hI).choose_spec.2.1 sdiff_subset lemma sdiff_sUnion_eq_sUnion_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : s \ ⋃₀ I = ⋃₀ hC.disjointOfDiffUnion hs hI := by - classical rw [(hC.exists_disjoint_finset_sdiff_eq hs hI).choose_spec.2.2] simp only [disjointOfDiffUnion, coe_sdiff, coe_singleton] rw [sUnion_sdiff_singleton_empty] @@ -403,7 +391,6 @@ theorem disjointOfUnion_props (hC : IsSetSemiring C) (h1 : ↑J ⊆ C) : ∧ (∀ j ∈ J, ⋃₀ K j ⊆ j) ∧ (∀ j ∈ J, ∅ ∉ K j) ∧ ⋃₀ J = ⋃₀ (⋃ x ∈ J, (K x : Set (Set α))) := by - classical induction J using Finset.cons_induction with | empty => simp | cons s J hJ hind => @@ -531,7 +518,6 @@ protected lemma Ioc [LinearOrder α] [Nonempty α] : rw [Set.Ioc_inter_Ioc] apply Ioc_mem_setOf_Ioc_le sdiff_eq_sUnion' := by - classical rintro s ⟨u, v, huv, rfl⟩ t ⟨u', v', hu'v', rfl⟩ rcases le_or_gt u' u with hu | hu · rcases Ioc_mem_setOf_Ioc_le (max u v') v with ⟨u'', v'', h'', heq⟩ diff --git a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean index cbd042c9ed8922..a875cde597fe3f 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean @@ -281,7 +281,6 @@ theorem integral_singleton [MeasurableSingletonClass X] {a : X} [CompleteSpace G theorem setIntegral_union_eq_left_of_ae (hs : MeasurableSet s) (ht : MeasurableSet t) (ht_eq : ∀ᵐ x ∂μ.variation.restrict t, f x = 0) : ∫ᵛ x in s ∪ t, f x ∂[B; μ] = ∫ᵛ x in s, f x ∂[B; μ] := by - classical rw [← integral_indicator hs, ← integral_indicator (hs.union ht)] apply integral_congr_ae rw [ae_restrict_iff' ht] at ht_eq @@ -518,7 +517,6 @@ theorem hasSum_setIntegral_iUnion {ι : Type*} [Countable ι] {s : ι → Set X} (hm : ∀ i, MeasurableSet (s i)) (hd : Pairwise (Disjoint on s)) (hfi : μ.IntegrableOn f (⋃ i, s i)) : HasSum (fun n ↦ ∫ᵛ x in s n, f x ∂[B; μ]) (∫ᵛ x in ⋃ n, s n, f x ∂[B; μ]) := by - classical rcases finite_or_infinite ι with hι | hι · let : Fintype ι := Fintype.ofFinite ι have : ∫ᵛ x in ⋃ n, s n, f x ∂[B; μ] = ∑ i, ∫ᵛ x in s i, f x ∂[B; μ] := by diff --git a/Mathlib/ModelTheory/ElementarySubstructures.lean b/Mathlib/ModelTheory/ElementarySubstructures.lean index bebffda1987a1c..cd078c268aa930 100644 --- a/Mathlib/ModelTheory/ElementarySubstructures.lean +++ b/Mathlib/ModelTheory/ElementarySubstructures.lean @@ -205,7 +205,6 @@ open Set Formula /-- An elementary substructure, regarded as a subset of the ambient structure, meets definable sets. -/ theorem meetsDefinable (S : L.ElementarySubstructure M) : L.MeetsDefinable (S : Set M) := by - classical rintro D ⟨x, hx⟩ ⟨φ, hφ⟩ have hφx : φ.Realize ![x] := by simp [Set.ext_iff] at hφ diff --git a/Mathlib/ModelTheory/Satisfiability.lean b/Mathlib/ModelTheory/Satisfiability.lean index 0e68449bba6d96..9227c2c63f97ea 100644 --- a/Mathlib/ModelTheory/Satisfiability.lean +++ b/Mathlib/ModelTheory/Satisfiability.lean @@ -100,23 +100,22 @@ finitely satisfiable. -/ theorem isSatisfiable_iff_isFinitelySatisfiable {T : L.Theory} : T.IsSatisfiable ↔ T.IsFinitelySatisfiable := ⟨Theory.IsSatisfiable.isFinitelySatisfiable, fun h => by - classical - set M : Finset T → Type max u v := fun T0 : Finset T => - (h (T0.map (Function.Embedding.subtype fun x => x ∈ T)) T0.map_subtype_subset).some.Carrier - let M' := Filter.Product (Ultrafilter.of (Filter.atTop : Filter (Finset T))) M - have h' : M' ⊨ T := by - refine ⟨fun φ hφ => ?_⟩ - rw [Ultraproduct.sentence_realize] - refine - Filter.Eventually.filter_mono (Ultrafilter.of_le _) - (Filter.eventually_atTop.2 - ⟨{⟨φ, hφ⟩}, fun s h' => - Theory.realize_sentence_of_mem (s.map (Function.Embedding.subtype fun x => x ∈ T)) - ?_⟩) - simp only [Finset.coe_map, Function.Embedding.coe_subtype, Set.mem_image, Finset.mem_coe, - Subtype.exists, exists_and_right, exists_eq_right] - exact ⟨hφ, h' (Finset.mem_singleton_self _)⟩ - exact ⟨ModelType.of T M'⟩⟩ + set M : Finset T → Type max u v := fun T0 : Finset T => + (h (T0.map (Function.Embedding.subtype fun x => x ∈ T)) T0.map_subtype_subset).some.Carrier + let M' := Filter.Product (Ultrafilter.of (Filter.atTop : Filter (Finset T))) M + have h' : M' ⊨ T := by + refine ⟨fun φ hφ => ?_⟩ + rw [Ultraproduct.sentence_realize] + refine + Filter.Eventually.filter_mono (Ultrafilter.of_le _) + (Filter.eventually_atTop.2 + ⟨{⟨φ, hφ⟩}, fun s h' => + Theory.realize_sentence_of_mem (s.map (Function.Embedding.subtype fun x => x ∈ T)) + ?_⟩) + simp only [Finset.coe_map, Function.Embedding.coe_subtype, Set.mem_image, Finset.mem_coe, + Subtype.exists, exists_and_right, exists_eq_right] + exact ⟨hφ, h' (Finset.mem_singleton_self _)⟩ + exact ⟨ModelType.of T M'⟩⟩ theorem isSatisfiable_directed_union_iff {ι : Type*} [Nonempty ι] {T : ι → L.Theory} (h : Directed (· ⊆ ·) T) : Theory.IsSatisfiable (⋃ i, T i) ↔ ∀ i, (T i).IsSatisfiable := by @@ -147,17 +146,16 @@ theorem isSatisfiable_union_distinctConstantsTheory_of_card_le (T : L.Theory) (s theorem isSatisfiable_union_distinctConstantsTheory_of_infinite (T : L.Theory) (s : Set α) (M : Type w') [L.Structure M] [M ⊨ T] [Infinite M] : ((L.lhomWithConstants α).onTheory T ∪ L.distinctConstantsTheory s).IsSatisfiable := by - classical - rw [distinctConstantsTheory_eq_iUnion, Set.union_iUnion, isSatisfiable_directed_union_iff] - · exact fun t => - isSatisfiable_union_distinctConstantsTheory_of_card_le T _ M - ((lift_le_aleph0.2 (finset_card_lt_aleph0 _).le).trans - (aleph0_le_lift.2 (aleph0_le_mk M))) - · apply Monotone.directed_le - refine monotone_const.union (monotone_distinctConstantsTheory.comp ?_) - simp only [Finset.coe_map, Function.Embedding.coe_subtype] - exact Monotone.comp (g := Set.image ((↑) : s → α)) (f := ((↑) : Finset s → Set s)) - Set.monotone_image fun _ _ => Finset.coe_subset.2 + rw [distinctConstantsTheory_eq_iUnion, Set.union_iUnion, isSatisfiable_directed_union_iff] + · exact fun t => + isSatisfiable_union_distinctConstantsTheory_of_card_le T _ M + ((lift_le_aleph0.2 (finset_card_lt_aleph0 _).le).trans + (aleph0_le_lift.2 (aleph0_le_mk M))) + · apply Monotone.directed_le + refine monotone_const.union (monotone_distinctConstantsTheory.comp ?_) + simp only [Finset.coe_map, Function.Embedding.coe_subtype] + exact Monotone.comp (g := Set.image ((↑) : s → α)) (f := ((↑) : Finset s → Set s)) + Set.monotone_image fun _ _ => Finset.coe_subset.2 /-- Any theory with an infinite model has arbitrarily large models. -/ theorem exists_large_model_of_infinite_model (T : L.Theory) (κ : Cardinal.{w}) (M : Type w') @@ -176,17 +174,16 @@ theorem exists_large_model_of_infinite_model (T : L.Theory) (κ : Cardinal.{w}) theorem isSatisfiable_iUnion_iff_isSatisfiable_iUnion_finset {ι : Type*} (T : ι → L.Theory) : IsSatisfiable (⋃ i, T i) ↔ ∀ s : Finset ι, IsSatisfiable (⋃ i ∈ s, T i) := by - classical - refine - ⟨fun h s => h.mono (Set.iUnion_mono fun _ => Set.iUnion_subset_iff.2 fun _ => refl _), - fun h => ?_⟩ - rw [isSatisfiable_iff_isFinitelySatisfiable] - intro s hs - rw [Set.iUnion_eq_iUnion_finset] at hs - obtain ⟨t, ht⟩ := Directed.exists_mem_subset_of_finset_subset_biUnion (by - exact Monotone.directed_le fun t1 t2 (h : ∀ ⦃x⦄, x ∈ t1 → x ∈ t2) => - Set.iUnion_mono fun _ => Set.iUnion_mono' fun h1 => ⟨h h1, refl _⟩) hs - exact (h t).mono ht + refine + ⟨fun h s => h.mono (Set.iUnion_mono fun _ => Set.iUnion_subset_iff.2 fun _ => refl _), + fun h => ?_⟩ + rw [isSatisfiable_iff_isFinitelySatisfiable] + intro s hs + rw [Set.iUnion_eq_iUnion_finset] at hs + obtain ⟨t, ht⟩ := Directed.exists_mem_subset_of_finset_subset_biUnion (by + exact Monotone.directed_le fun t1 t2 (h : ∀ ⦃x⦄, x ∈ t1 → x ∈ t2) => + Set.iUnion_mono fun _ => Set.iUnion_mono' fun h1 => ⟨h h1, refl _⟩) hs + exact (h t).mono ht end Theory diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index e10d87952cd7e7..034c211272d8ae 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -961,7 +961,6 @@ theorem exists_realize_equivSentence_iff_realize_exClosure (by simpa [Formula.Realize] using (realize_equivSentence_symm M (Formula.equivSentence φ) v).2 hv)⟩ · intro h - classical obtain ⟨v, hv⟩ := (Formula.realize_exClosure φ).1 h let v' := fun a => if hmem : a ∈ φ.freeVarFinset then v ⟨a, hmem⟩ else Classical.choice inferInstance diff --git a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean index bc9919c9511070..3e695d52275674 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean @@ -159,7 +159,6 @@ variable [CommRing R] to substituting `X` with `X ^ k` in the original power series. -/ theorem ofPowerSeries_pow (q : ℕ) {k : ℕ} (hk : k ≠ 0) (f : PowerSeries R) : ofPowerSeries (q ^ k) f = ofPowerSeries q (f.subst (PowerSeries.X ^ k)) := by - classical by_cases hq : 1 < q · ext n by_cases hn : ∃ i, q ^ i = n diff --git a/Mathlib/NumberTheory/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/Cyclotomic/Basic.lean index 7eed25c14848e9..b6675ff2f46493 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Basic.lean @@ -460,7 +460,6 @@ theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ} [NeZero n] [ theorem adjoin_primitive_root_eq_top {n : ℕ} [NeZero n] [IsDomain B] [h : IsCyclotomicExtension {n} A B] {ζ : B} (hζ : IsPrimitiveRoot ζ n) : adjoin A ({ζ} : Set B) = ⊤ := by - classical rw [← adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic hζ] rw [adjoin_roots_cyclotomic_eq_adjoin_nth_roots hζ] exact ((iff_adjoin_eq_top {n} A B).mp h).2 diff --git a/Mathlib/NumberTheory/FLT/Three.lean b/Mathlib/NumberTheory/FLT/Three.lean index 80e14f9531a959..3741a513e20ae3 100644 --- a/Mathlib/NumberTheory/FLT/Three.lean +++ b/Mathlib/NumberTheory/FLT/Three.lean @@ -566,7 +566,7 @@ lemma x_mul_y_mul_z_eq_u_mul_w_cube : S.x * S.y * S.z = S.u * S.w ^ 3 := by lemma exists_cube_associated : (∃ X, Associated (X ^ 3) S.x) ∧ (∃ Y, Associated (Y ^ 3) S.y) ∧ - ∃ Z, Associated (Z ^ 3) S.z := by classical + ∃ Z, Associated (Z ^ 3) S.z := by have h₁ := S.isCoprime_x_z.mul_left S.isCoprime_y_z have h₂ : Associated (S.w ^ 3) (S.x * S.y * S.z) := ⟨S.u, by rw [x_mul_y_mul_z_eq_u_mul_w_cube S, mul_comm]⟩ @@ -733,7 +733,7 @@ lemma Solution'_descent_multiplicity_lt : /-- Given any `S : Solution`, there is another `S₁ : Solution` such that `S₁.multiplicity < S.multiplicity` -/ theorem exists_Solution_multiplicity_lt : - ∃ S₁ : Solution hζ, S₁.multiplicity < S.multiplicity := by classical + ∃ S₁ : Solution hζ, S₁.multiplicity < S.multiplicity := by obtain ⟨S', hS'⟩ := exists_Solution_of_Solution' (Solution'_descent S) exact ⟨S', hS' ▸ Solution'_descent_multiplicity_lt S⟩ @@ -749,7 +749,6 @@ set_option backward.isDefEq.respectTransparency false in /-- Fermat's Last Theorem for `n = 3`: if `a b c : ℕ` are all non-zero then `a ^ 3 + b ^ 3 ≠ c ^ 3`. -/ public theorem fermatLastTheoremThree : FermatLastTheoremFor 3 := by - classical let K := CyclotomicField 3 ℚ let hζ := IsCyclotomicExtension.zeta_spec 3 ℚ K have : NumberField K := IsCyclotomicExtension.numberField {3} ℚ _ diff --git a/Mathlib/NumberTheory/Modular.lean b/Mathlib/NumberTheory/Modular.lean index 9b80cbcdb1791b..b12c549aac5970 100644 --- a/Mathlib/NumberTheory/Modular.lean +++ b/Mathlib/NumberTheory/Modular.lean @@ -275,7 +275,6 @@ attribute [local simp] UpperHalfPlane.coe_specialLinearGroup_apply /-- For `z : ℍ`, there is a `g : SL(2,ℤ)` maximizing `(g•z).im` -/ theorem exists_max_im : ∃ g : SL(2, ℤ), ∀ g' : SL(2, ℤ), (g' • z).im ≤ (g • z).im := by - classical let s : Set (Fin 2 → ℤ) := {cd | IsCoprime (cd 0) (cd 1)} have hs : s.Nonempty := ⟨![1, 1], isCoprime_one_left⟩ obtain ⟨p, hp_coprime, hp⟩ := diff --git a/Mathlib/NumberTheory/MulChar/Basic.lean b/Mathlib/NumberTheory/MulChar/Basic.lean index 4186c32b983f9b..1eaae6cdaf2b94 100644 --- a/Mathlib/NumberTheory/MulChar/Basic.lean +++ b/Mathlib/NumberTheory/MulChar/Basic.lean @@ -254,7 +254,7 @@ noncomputable instance inhabited : Inhabited (MulChar R R') := /-- Evaluation of the trivial character -/ @[simp] -theorem one_apply_coe (a : Rˣ) : (1 : MulChar R R') a = 1 := by classical exact dif_pos a.isUnit +theorem one_apply_coe (a : Rˣ) : (1 : MulChar R R') a = 1 := by exact dif_pos a.isUnit /-- Evaluation of the trivial character -/ lemma one_apply {x : R} (hx : IsUnit x) : (1 : MulChar R R') x = 1 := one_apply_coe hx.unit diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index e53507c24b94d7..1acd6f2757fe81 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -866,7 +866,6 @@ protected def integerLattice : Submodule ℤ (euclidean.mixedSpace K) := ZLattice.comap ℝ (mixedEmbedding.integerLattice K) (toMixed K).toLinearMap instance : DiscreteTopology (euclidean.integerLattice K) := by - classical rw [euclidean.integerLattice] infer_instance diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean index dcf939ca237774..c298550aef7ff8 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean @@ -779,7 +779,6 @@ theorem compactSet_eq_union_aux₂ {x : realSpace K} (hx₀ : x ≠ 0) theorem compactSet_eq_union : compactSet K = expMapBasis '' closure (paramSet K) ∪ {0} := by - classical ext x by_cases hx₀ : x = 0 · simpa [hx₀] using zero_mem_compactSet K diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean index 505f6e860e994c..4694a080fd9c01 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Defs.lean @@ -102,7 +102,6 @@ theorem Algebra.discr_eq_discr_of_toMatrix_coeff_isIntegral [NumberField K] intro i j convert! h' i ((b.indexEquiv b').symm j) simp [Basis.toMatrix_apply] - classical rw [← (b.reindex (b.indexEquiv b')).toMatrix_map_vecMul b', discr_of_matrix_vecMul, ← one_mul (discr ℚ b), Basis.coe_reindex, discr_reindex] congr diff --git a/Mathlib/NumberTheory/NumberField/House.lean b/Mathlib/NumberTheory/NumberField/House.lean index 509517939b2428..8ed34de1dd6c14 100644 --- a/Mathlib/NumberTheory/NumberField/House.lean +++ b/Mathlib/NumberTheory/NumberField/House.lean @@ -343,7 +343,6 @@ non-trivial underdetermined system of linear equations with algebraic integer co theorem exists_ne_zero_int_vec_house_le : ∃ (ξ : β → 𝓞 K), ξ ≠ 0 ∧ a *ᵥ ξ = 0 ∧ ∀ l, house (ξ l).1 ≤ c₁ K * ((c₁ K * q * A) ^ ((p : ℝ) / (q - p))) := by - classical let h := finrank ℚ K have hphqh : p * h < q * h := by gcongr; exact finrank_pos have h0ph : 0 < p * h := by rw [mul_pos_iff]; constructor; exact ⟨h0p, finrank_pos⟩ diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean index 936b67e35b06e9..fb92da2b73dfd2 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean @@ -744,7 +744,6 @@ private theorem mapsTo_embeddingConjugateIte : (unramifiedPlacesOver L v).MapsTo private theorem surjOn_embeddingConjugateIte : (unramifiedPlacesOver L v).SurjOn (embeddingConjugateIte v) (unmixedEmbeddingsOver L v.embedding) := by - classical refine fun ψ h ↦ ⟨mk ψ, mk_mem_unramifiedPlacesOver h, ?_⟩ rcases embedding_mk_eq ψ with (_ | hψ) · aesop (add simp [embeddingConjugateIte, unmixedEmbeddingsOver]) diff --git a/Mathlib/NumberTheory/NumberField/ProductFormula.lean b/Mathlib/NumberTheory/NumberField/ProductFormula.lean index 0a89c7a85a2412..40c7ea76fc1663 100644 --- a/Mathlib/NumberTheory/NumberField/ProductFormula.lean +++ b/Mathlib/NumberTheory/NumberField/ProductFormula.lean @@ -62,7 +62,6 @@ theorem FinitePlace.prod_eq_inv_abs_norm_int {x : 𝓞 K} (h_x_nezero : x ≠ 0) maxPowDividing, ← dvd_span_singleton] intro v hv simp only [map_pow, Nat.cast_pow, ← pow_zero (absNorm v.asIdeal : ℝ)] at hv - classical refine (Associates.count_ne_zero_iff_dvd h_span_nezero (irreducible v)).1 <| fun h ↦ hv ?_ congr have h_prod : (absNorm (∏ᶠ (v : HeightOneSpectrum (𝓞 K)), v.maxPowDividing (span {x})) : ℝ) = diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 2da3a085e0caa7..115003eb952bc6 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -606,7 +606,6 @@ theorem sum_ramification_inertia {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : theorem inertiaDeg_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (P : Ideal S) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver p] (hp0 : p ≠ ⊥) : p.inertiaDeg' P ≤ Module.finrank K L := by - classical have hP : P ∈ IsDedekindDomain.primesOverFinset p S := (IsDedekindDomain.mem_primesOverFinset_iff hp0 _).mpr ⟨hP₁, hP₂⟩ rw [← sum_ramification_inertia S K L hp0, ← Finset.add_sum_erase _ _ hP] @@ -616,7 +615,6 @@ theorem inertiaDeg_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaxima theorem ramificationIdx_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (P : Ideal S) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver p] : p.ramificationIdx' P ≤ Module.finrank K L := by - classical by_cases hp0 : p = ⊥ · simp [hp0] have hP : P ∈ IsDedekindDomain.primesOverFinset p S := diff --git a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean index a4e30787f660b8..d964166091eeef 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean @@ -266,7 +266,6 @@ theorem ramificationIdx'_eq_normalizedFactors_count theorem ramificationIdx'_eq_multiplicity (hp : map f p ≠ ⊥) (hP : P.IsPrime) : ramificationIdx' p P = multiplicity P (Ideal.map f p) := by - classical by_cases hP₂ : P = ⊥ · rw [hP₂, ← Ideal.zero_eq_bot, multiplicity_zero_eq_zero_of_ne_zero _ hp] exact Ideal.ramificationIdx'_of_not_le (mt le_bot_iff.mp hp) @@ -283,7 +282,6 @@ theorem ramificationIdx'_eq_factors_count theorem ramificationIdx'_ne_zero (hp0 : map f p ≠ ⊥) (hP : P.IsPrime) (le : map f p ≤ P) : ramificationIdx' p P ≠ 0 := by - classical have hP0 : P ≠ ⊥ := by rintro rfl exact hp0 (le_bot_iff.mp le) @@ -397,7 +395,6 @@ theorem ramificationIdx'_algebra_tower [IsDedekindDomain S] [IsDedekindDomain T] (hfg : map (algebraMap R T) p ≠ ⊥) (hg : map (algebraMap S T) P ≤ Q) : ramificationIdx' p Q = ramificationIdx' p P * ramificationIdx' P Q := by - classical have hf0 : map (algebraMap R S) p ≠ ⊥ := by rw [IsScalarTower.algebraMap_eq R S T, ← map_map] at hfg exact ne_bot_of_map_ne_bot hfg diff --git a/Mathlib/Order/CompleteLattice/Finset.lean b/Mathlib/Order/CompleteLattice/Finset.lean index 5567ca25a81436..eff556937c4e88 100644 --- a/Mathlib/Order/CompleteLattice/Finset.lean +++ b/Mathlib/Order/CompleteLattice/Finset.lean @@ -37,7 +37,6 @@ that works for `ι : Sort*`. -/ `⨅ i ∈ t, s i`. This version assumes `ι` is a `Type*`. See `iInf_eq_iInf_finset'` for a version that works for `ι : Sort*`. -/] theorem iSup_eq_iSup_finset (s : ι → α) : ⨆ i, s i = ⨆ t : Finset ι, ⨆ i ∈ t, s i := by - classical refine le_antisymm ?_ ?_ · exact iSup_le fun b => le_iSup_of_le {b} <| le_iSup_of_le b <| le_iSup_of_le (by simp) <| le_rfl · exact iSup_le fun t => iSup_le fun b => iSup_le fun _ => le_iSup _ _ diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 13265fb034c9c9..d509ed4ec1e65d 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -71,7 +71,7 @@ end ConditionallyCompleteLattice variable (f : ι → α) theorem Finset.ciSup_eq_max'_image {s : Finset ι} (h : ∃ x ∈ s, sSup ∅ ≤ f x) - (h' : (s.image f).Nonempty := by classical exact image_nonempty.mpr (h.imp fun _ ↦ And.left)) : + (h' : (s.image f).Nonempty := by exact image_nonempty.mpr (h.imp fun _ ↦ And.left)) : ⨆ i ∈ s, f i = (s.image f).max' h' := by classical rw [iSup, ← h'.csSup_eq_max', coe_image] @@ -89,9 +89,8 @@ theorem Finset.ciSup_eq_max'_image {s : Finset ι} (h : ∃ x ∈ s, sSup ∅ simp [hi] theorem Finset.ciInf_eq_min'_image {s : Finset ι} (h : ∃ x ∈ s, f x ≤ sInf ∅) - (h' : (s.image f).Nonempty := by classical exact image_nonempty.mpr (h.imp fun _ ↦ And.left)) : + (h' : (s.image f).Nonempty := by exact image_nonempty.mpr (h.imp fun _ ↦ And.left)) : ⨅ i ∈ s, f i = (s.image f).min' h' := by - classical rw [← OrderDual.toDual_inj, toDual_min', toDual_iInf] simp only [toDual_iInf] rw [ciSup_eq_max'_image _ h] diff --git a/Mathlib/Order/Filter/AtTopBot/BigOperators.lean b/Mathlib/Order/Filter/AtTopBot/BigOperators.lean index 48847d7fe443b0..b9a7c43ffc307c 100644 --- a/Mathlib/Order/Filter/AtTopBot/BigOperators.lean +++ b/Mathlib/Order/Filter/AtTopBot/BigOperators.lean @@ -35,11 +35,10 @@ theorem Filter.map_atTop_finsetProd_le_of_prod_eq {f : α → M} {g : β → M} ∃ v : Finset α, ∀ v', v ⊆ v' → ∃ u', u ⊆ u' ∧ ∏ x ∈ u', g x = ∏ b ∈ v', f b) : (atTop.map fun s : Finset α => ∏ b ∈ s, f b) ≤ atTop.map fun s : Finset β => ∏ x ∈ s, g x := by - classical - refine ((atTop_basis.map _).le_basis_iff (atTop_basis.map _)).2 fun b _ => ?_ - let ⟨v, hv⟩ := h_eq b - refine ⟨v, trivial, ?_⟩ - simpa [Finset.image_subset_iff] using! hv + refine ((atTop_basis.map _).le_basis_iff (atTop_basis.map _)).2 fun b _ => ?_ + let ⟨v, hv⟩ := h_eq b + refine ⟨v, trivial, ?_⟩ + simpa [Finset.image_subset_iff] using! hv @[deprecated (since := "2026-04-08")] alias Filter.map_atTop_finset_sum_le_of_sum_eq := Filter.map_atTop_finsetSum_le_of_sum_eq diff --git a/Mathlib/Order/Interval/Finset/Basic.lean b/Mathlib/Order/Interval/Finset/Basic.lean index e8e2ff53069fcd..5e3c90433fdc34 100644 --- a/Mathlib/Order/Interval/Finset/Basic.lean +++ b/Mathlib/Order/Interval/Finset/Basic.lean @@ -648,21 +648,19 @@ theorem Ico_filter_le_left {a b : α} [DecidablePred (· ≤ a)] (hab : a < b) : grind theorem card_Ico_eq_card_Icc_sub_one (a b : α) : #(Ico a b) = #(Icc a b) - 1 := by - classical - by_cases h : a ≤ b - · rw [Icc_eq_cons_Ico h, card_cons] - exact (Nat.add_sub_cancel _ _).symm - · rw [Ico_eq_empty fun h' => h h'.le, Icc_eq_empty h, card_empty, Nat.zero_sub] + by_cases h : a ≤ b + · rw [Icc_eq_cons_Ico h, card_cons] + exact (Nat.add_sub_cancel _ _).symm + · rw [Ico_eq_empty fun h' => h h'.le, Icc_eq_empty h, card_empty, Nat.zero_sub] theorem card_Ioc_eq_card_Icc_sub_one (a b : α) : #(Ioc a b) = #(Icc a b) - 1 := @card_Ico_eq_card_Icc_sub_one αᵒᵈ _ _ _ _ theorem card_Ioo_eq_card_Ico_sub_one (a b : α) : #(Ioo a b) = #(Ico a b) - 1 := by - classical - by_cases h : a < b - · rw [Ico_eq_cons_Ioo h, card_cons] - exact (Nat.add_sub_cancel _ _).symm - · rw [Ioo_eq_empty h, Ico_eq_empty h, card_empty, Nat.zero_sub] + by_cases h : a < b + · rw [Ico_eq_cons_Ioo h, card_cons] + exact (Nat.add_sub_cancel _ _).symm + · rw [Ioo_eq_empty h, Ico_eq_empty h, card_empty, Nat.zero_sub] theorem card_Ioo_eq_card_Ioc_sub_one (a b : α) : #(Ioo a b) = #(Ioc a b) - 1 := @card_Ioo_eq_card_Ico_sub_one αᵒᵈ _ _ _ _ diff --git a/Mathlib/Order/Interval/Set/Basic.lean b/Mathlib/Order/Interval/Set/Basic.lean index bc913bfeaa7fcf..ac1b1ac2111dd1 100644 --- a/Mathlib/Order/Interval/Set/Basic.lean +++ b/Mathlib/Order/Interval/Set/Basic.lean @@ -596,22 +596,21 @@ theorem mem_Iic_Iio_of_subset_of_subset {s : Set α} (ho : Iio a ⊆ s) (hc : s theorem mem_Icc_Ico_Ioc_Ioo_of_subset_of_subset {s : Set α} (ho : Ioo a b ⊆ s) (hc : s ⊆ Icc a b) : s ∈ ({Icc a b, Ico a b, Ioc a b, Ioo a b} : Set (Set α)) := by - classical - by_cases ha : a ∈ s <;> by_cases hb : b ∈ s - · refine Or.inl (Subset.antisymm hc ?_) - rwa [← Ico_sdiff_left, sdiff_singleton_subset_iff, insert_eq_of_mem ha, ← Icc_sdiff_right, - sdiff_singleton_subset_iff, insert_eq_of_mem hb] at ho - · refine Or.inr <| Or.inl <| Subset.antisymm ?_ ?_ - · rw [← Icc_sdiff_right] - exact subset_sdiff_singleton hc hb - · rwa [← Ico_sdiff_left, sdiff_singleton_subset_iff, insert_eq_of_mem ha] at ho - · refine Or.inr <| Or.inr <| Or.inl <| Subset.antisymm ?_ ?_ - · rw [← Icc_sdiff_left] - exact subset_sdiff_singleton hc ha - · rwa [← Ioc_sdiff_right, sdiff_singleton_subset_iff, insert_eq_of_mem hb] at ho - · refine Or.inr <| Or.inr <| Or.inr <| Subset.antisymm ?_ ho - rw [← Ico_sdiff_left, ← Icc_sdiff_right] - apply_rules [subset_sdiff_singleton] + by_cases ha : a ∈ s <;> by_cases hb : b ∈ s + · refine Or.inl (Subset.antisymm hc ?_) + rwa [← Ico_sdiff_left, sdiff_singleton_subset_iff, insert_eq_of_mem ha, ← Icc_sdiff_right, + sdiff_singleton_subset_iff, insert_eq_of_mem hb] at ho + · refine Or.inr <| Or.inl <| Subset.antisymm ?_ ?_ + · rw [← Icc_sdiff_right] + exact subset_sdiff_singleton hc hb + · rwa [← Ico_sdiff_left, sdiff_singleton_subset_iff, insert_eq_of_mem ha] at ho + · refine Or.inr <| Or.inr <| Or.inl <| Subset.antisymm ?_ ?_ + · rw [← Icc_sdiff_left] + exact subset_sdiff_singleton hc ha + · rwa [← Ioc_sdiff_right, sdiff_singleton_subset_iff, insert_eq_of_mem hb] at ho + · refine Or.inr <| Or.inr <| Or.inr <| Subset.antisymm ?_ ho + rw [← Ico_sdiff_left, ← Icc_sdiff_right] + apply_rules [subset_sdiff_singleton] @[to_dual] theorem eq_left_or_mem_Ioo_of_mem_Ico {x : α} (hmem : x ∈ Ico a b) : x = a ∨ x ∈ Ioo a b := diff --git a/Mathlib/Order/PartialSups.lean b/Mathlib/Order/PartialSups.lean index f4d87b5b4fd31a..817e11e1524383 100644 --- a/Mathlib/Order/PartialSups.lean +++ b/Mathlib/Order/PartialSups.lean @@ -65,7 +65,6 @@ lemma partialSups_apply (f : ι → α) (i : ι) : lemma partialSups_iff_forall {f : ι → α} (p : α → Prop) (hp : ∀ {a b}, p (a ⊔ b) ↔ p a ∧ p b) {i : ι} : p (partialSups f i) ↔ ∀ j ≤ i, p (f j) := by - classical rw [partialSups_apply, apply_sup'_eq_sup'_comp (γ := Propᵒᵈ) _ p, sup'_eq_sup] · change (Iic i).inf (p ∘ f) ↔ _ simp [Finset.inf_eq_iInf] diff --git a/Mathlib/Order/Preorder/Chain.lean b/Mathlib/Order/Preorder/Chain.lean index ac24fba1fc51b0..8536a31860ec24 100644 --- a/Mathlib/Order/Preorder/Chain.lean +++ b/Mathlib/Order/Preorder/Chain.lean @@ -301,7 +301,6 @@ theorem succChain_spec (h : ∃ t, IsChain r s ∧ SuperChain r s t) : simpa [SuccChain, dif_pos, exists_and_left.mp h] using this.2 theorem IsChain.succ (hs : IsChain r s) : IsChain r (SuccChain r s) := by - classical if h : ∃ t, IsChain r s ∧ SuperChain r s t then exact (succChain_spec h).1 else rw [exists_and_left] at h @@ -314,7 +313,6 @@ theorem IsChain.superChain_succChain (hs₁ : IsChain r s) (hs₂ : ¬IsMaxChain exact succChain_spec ⟨t, hs₁, ht, ssubset_iff_subset_ne.2 hst⟩ theorem subset_succChain : s ⊆ SuccChain r s := by - classical if h : ∃ t, IsChain r s ∧ SuperChain r s t then exact (succChain_spec h).2.1 else simp [SuccChain, h] diff --git a/Mathlib/Probability/Distributions/Gaussian/HasGaussianLaw/Independence.lean b/Mathlib/Probability/Distributions/Gaussian/HasGaussianLaw/Independence.lean index b205b06e591f1a..e24c909893788f 100644 --- a/Mathlib/Probability/Distributions/Gaussian/HasGaussianLaw/Independence.lean +++ b/Mathlib/Probability/Distributions/Gaussian/HasGaussianLaw/Independence.lean @@ -284,7 +284,6 @@ lemma IndepFun.hasGaussianLaw [NormedSpace ℝ E] [NormedSpace ℝ F] {X : Ω isGaussian_map := by have := hX.isProbabilityMeasure rw [isGaussian_iff_gaussian_charFunDual] - classical refine ⟨(∫ x, x ∂P.map X, ∫ y, y ∂P.map Y), .diagonalStrongDualProd (covarianceBilinDual (P.map X)) (covarianceBilinDual (P.map Y)), isPosSemidef_diagonalStrongDualProd isPosSemidef_covarianceBilinDual diff --git a/Mathlib/Probability/Distributions/SetBernoulli.lean b/Mathlib/Probability/Distributions/SetBernoulli.lean index e09c6be68ed550..cf776ae4cb3b12 100644 --- a/Mathlib/Probability/Distributions/SetBernoulli.lean +++ b/Mathlib/Probability/Distributions/SetBernoulli.lean @@ -75,7 +75,6 @@ section Countable variable [Countable ι] lemma setBernoulli_ae_subset : ∀ᵐ s ∂setBer(u, p), s ⊆ u := by - classical simp only [Filter.Eventually, mem_ae_iff, Set.compl_setOf, Set.not_subset_iff_exists_mem_notMem, Set.setOf_exists, Set.setOf_and, measure_iUnion_null_iff] rintro i @@ -130,7 +129,6 @@ lemma setBernoulli_real_singleton (p : I) (hsu : s ⊆ u) (hu : u.Finite) : lemma map_ncard_setBernoulli_real_singleton {u : Set ι} (hu : u.Finite) (p : I) (k : ℕ) : (setBer(u, p).map Set.ncard).real {k} = (u.ncard.choose k) * p ^ k * (1 - p) ^ (u.ncard - k) := by - classical have : {s ⊆ u | s.ncard ∈ ({k} : Set ℕ)}.Finite := hu.finite_subsets.subset (by grind) rw [measureReal_def, map_ncard_setBernoulli_apply, ← measureReal_def, ← Set.biUnion_of_singleton (setOf _)] diff --git a/Mathlib/Probability/Independence/Basic.lean b/Mathlib/Probability/Independence/Basic.lean index 41ce7f824cf9d6..d28b9586f87796 100644 --- a/Mathlib/Probability/Independence/Basic.lean +++ b/Mathlib/Probability/Independence/Basic.lean @@ -841,7 +841,6 @@ theorem iIndepFun.map_fun_eq_pi_map [Fintype ι] {β : ι → Type*} {m : ∀ i, MeasurableSpace (β i)} {f : Π i, Ω → β i} (hf : ∀ i, AEMeasurable (f i) μ) (h : iIndepFun f μ) : μ.map (fun ω i ↦ f i ω) = Measure.pi (fun i ↦ μ.map (f i)) := by - classical have := h.isProbabilityMeasure rw [iIndepFun_iff_measure_inter_preimage_eq_mul] at h have h₀ {s : ∀ i, Set (β i)} (hm : ∀ (i : ι), MeasurableSet (s i)) : diff --git a/Mathlib/Probability/Independence/Kernel/Indep.lean b/Mathlib/Probability/Independence/Kernel/Indep.lean index 4f9747d1c095fe..53e4a8b6990b76 100644 --- a/Mathlib/Probability/Independence/Kernel/Indep.lean +++ b/Mathlib/Probability/Independence/Kernel/Indep.lean @@ -586,7 +586,6 @@ theorem indepSets_piiUnionInter_of_disjoint {s : ι → Set (Set Ω)} theorem iIndepSet.indep_generateFrom_of_disjoint {s : ι → Set Ω} (hsm : ∀ n, MeasurableSet (s n)) (hs : iIndepSet s κ μ) (S T : Set ι) (hST : Disjoint S T) : Indep (generateFrom { t | ∃ n ∈ S, s n = t }) (generateFrom { t | ∃ k ∈ T, s k = t }) κ μ := by - classical rcases eq_or_ne μ 0 with rfl | hμ · simp obtain ⟨η, η_eq, hη⟩ : ∃ (η : Kernel α Ω), κ =ᵐ[μ] η ∧ IsMarkovKernel η := @@ -606,7 +605,6 @@ theorem iIndepSet.indep_generateFrom_of_disjoint {s : ι → Set Ω} theorem indep_iSup_of_disjoint {m : ι → MeasurableSpace Ω} (h_le : ∀ i, m i ≤ _mΩ) (h_indep : iIndep m κ μ) {S T : Set ι} (hST : Disjoint S T) : Indep (⨆ i ∈ S, m i) (⨆ i ∈ T, m i) κ μ := by - classical rcases eq_or_ne μ 0 with rfl | hμ · simp obtain ⟨η, η_eq, hη⟩ : ∃ (η : Kernel α Ω), κ =ᵐ[μ] η ∧ IsMarkovKernel η := diff --git a/Mathlib/Probability/Independence/Kernel/IndepFun.lean b/Mathlib/Probability/Independence/Kernel/IndepFun.lean index 56935576fa75f9..e48ccde3f8f8cc 100644 --- a/Mathlib/Probability/Independence/Kernel/IndepFun.lean +++ b/Mathlib/Probability/Independence/Kernel/IndepFun.lean @@ -616,7 +616,6 @@ variable {β : Type*} {m : MeasurableSpace β} [CommMonoid β] [MeasurableMul₂ theorem iIndepFun.indepFun_finsetProd_of_notMem (hf_Indep : iIndepFun f κ μ) (hf_meas : ∀ i, Measurable (f i)) {s : Finset ι} {i : ι} (hi : i ∉ s) : IndepFun (∏ j ∈ s, f j) (f i) κ μ := by - classical have h_right : f i = (fun p : ({i} : Finset ι) → β => p ⟨i, Finset.mem_singleton_self i⟩) ∘ fun a (j : ({i} : Finset ι)) => f j a := rfl diff --git a/Mathlib/Probability/Kernel/Composition/CompProd.lean b/Mathlib/Probability/Kernel/Composition/CompProd.lean index 399b39d718dd7c..962c306e3292a8 100644 --- a/Mathlib/Probability/Kernel/Composition/CompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/CompProd.lean @@ -185,7 +185,6 @@ lemma compProd_eq_zero_iff {κ : Kernel α β} {η : Kernel (α × β) γ} lemma compProd_preimage_fst {s : Set β} (hs : MeasurableSet s) (κ : Kernel α β) (η : Kernel (α × β) γ) [IsSFiniteKernel κ] [IsMarkovKernel η] (x : α) : (κ ⊗ₖ η) x (Prod.fst ⁻¹' s) = κ x s := by - classical simp_rw [compProd_apply (measurable_fst hs), ← Set.preimage_comp, Prod.fst_comp_mk, Set.preimage, Function.const_apply] have : ∀ b : β, η (x, b) {_c | b ∈ s} = s.indicator (fun _ ↦ 1) b := by diff --git a/Mathlib/Probability/Kernel/Disintegration/Basic.lean b/Mathlib/Probability/Kernel/Disintegration/Basic.lean index b8342df3429a1a..6ab729b88d15cf 100644 --- a/Mathlib/Probability/Kernel/Disintegration/Basic.lean +++ b/Mathlib/Probability/Kernel/Disintegration/Basic.lean @@ -74,7 +74,6 @@ private lemma IsCondKernel.apply_of_ne_zero_of_measurableSet [MeasurableSingleto have := isSFiniteKernel ρ ρCond (by rintro rfl; simp at hx) nth_rewrite 2 [← ρ.disintegrate ρCond] rw [Measure.compProd_apply (measurableSet_prod.mpr (Or.inl ⟨measurableSet_singleton x, hs⟩))] - classical have (a : _) : ρCond a (Prod.mk a ⁻¹' {x} ×ˢ s) = ({x} : Set α).indicator (ρCond · s) a := by obtain rfl | hax := eq_or_ne a x · simp only [singleton_prod, mem_singleton_iff, indicator_of_mem] diff --git a/Mathlib/Probability/Kernel/MeasurableIntegral.lean b/Mathlib/Probability/Kernel/MeasurableIntegral.lean index 9b08a68cd9e4e5..894cf3fd1c0365 100644 --- a/Mathlib/Probability/Kernel/MeasurableIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableIntegral.lean @@ -54,7 +54,6 @@ omit [IsSFiniteKernel κ] in @[fun_prop] theorem StronglyMeasurable.integral_kernel ⦃f : β → E⦄ (hf : StronglyMeasurable f) : StronglyMeasurable fun x ↦ ∫ y, f y ∂κ x := by - classical by_cases hE : CompleteSpace E; swap · simp [integral, hE, stronglyMeasurable_const] borelize E diff --git a/Mathlib/Probability/Kernel/WithDensity.lean b/Mathlib/Probability/Kernel/WithDensity.lean index 3bc75820980a20..bec7e016faf23a 100644 --- a/Mathlib/Probability/Kernel/WithDensity.lean +++ b/Mathlib/Probability/Kernel/WithDensity.lean @@ -55,12 +55,11 @@ noncomputable def withDensity (κ : Kernel α β) [IsSFiniteKernel κ] (f : α exact hf.setLIntegral_kernel_prod_right hs⟩ : Kernel α β)) fun _ => 0 theorem withDensity_of_not_measurable (κ : Kernel α β) [IsSFiniteKernel κ] - (hf : ¬Measurable (Function.uncurry f)) : withDensity κ f = 0 := by classical exact dif_neg hf + (hf : ¬Measurable (Function.uncurry f)) : withDensity κ f = 0 := by exact dif_neg hf protected theorem withDensity_apply (κ : Kernel α β) [IsSFiniteKernel κ] (hf : Measurable (Function.uncurry f)) (a : α) : withDensity κ f a = (κ a).withDensity (f a) := by - classical rw [withDensity, dif_pos hf] rfl diff --git a/Mathlib/Probability/Martingale/Upcrossing.lean b/Mathlib/Probability/Martingale/Upcrossing.lean index d266f8502d70b2..c2367d481806f2 100644 --- a/Mathlib/Probability/Martingale/Upcrossing.lean +++ b/Mathlib/Probability/Martingale/Upcrossing.lean @@ -561,7 +561,6 @@ theorem sub_eq_zero_of_upcrossingsBefore_lt (hab : a < b) (hn : upcrossingsBefor theorem mul_upcrossingsBefore_le (hf : a ≤ f N ω) (hab : a < b) : (b - a) * upcrossingsBefore a b f N ω ≤ ∑ k ∈ Finset.range N, upcrossingStrat a b f N k ω * (f (k + 1) - f k) ω := by - classical by_cases hN : N = 0 · simp [hN] simp_rw [upcrossingStrat, Finset.sum_mul, ← diff --git a/Mathlib/Probability/Process/HittingTime.lean b/Mathlib/Probability/Process/HittingTime.lean index 6f0144b035b6b5..0fe4ccb05c7b77 100644 --- a/Mathlib/Probability/Process/HittingTime.lean +++ b/Mathlib/Probability/Process/HittingTime.lean @@ -88,7 +88,6 @@ lemma hittingAfter_empty (n : ι) : hittingAfter u ∅ n = fun _ ↦ ⊤ := by e lemma hittingBtwn_univ {ι : Type*} [ConditionallyCompleteLinearOrder ι] {u : ι → Ω → β} (n m : ι) : hittingBtwn u .univ n m = fun _ ↦ min n m := by ext ω - classical simp only [hittingBtwn_def, Set.mem_Icc, Set.mem_univ, and_true, Set.setOf_true, Set.inter_univ] by_cases hnm : n ≤ m <;> simp [hnm] <;> grind @@ -121,7 +120,6 @@ theorem hittingBtwn_le {m : ι} (ω : Ω) : hittingBtwn u s n m ω ≤ m := by theorem notMem_of_lt_hittingBtwn {m k : ι} (hk₁ : k < hittingBtwn u s n m ω) (hk₂ : n ≤ k) : u k ω ∉ s := by - classical intro h have hexists : ∃ j ∈ Set.Icc n m, u j ω ∈ s := ⟨k, ⟨hk₂, le_trans hk₁.le <| hittingBtwn_le _⟩, h⟩ refine not_le.2 hk₁ ?_ diff --git a/Mathlib/Probability/StrongLaw.lean b/Mathlib/Probability/StrongLaw.lean index f783f5ad0c7665..c8f9eb0db80f95 100644 --- a/Mathlib/Probability/StrongLaw.lean +++ b/Mathlib/Probability/StrongLaw.lean @@ -650,7 +650,6 @@ lemma strong_law_ae_simpleFunc_comp (X : ℕ → Ω → E) (h' : Measurable (X 0 Tendsto (fun n : ℕ ↦ (n : ℝ)⁻¹ • (∑ i ∈ range n, φ (X i ω))) atTop (𝓝 μ[φ ∘ (X 0)]) := by -- this follows from the one-dimensional version when `φ` takes a single value, and is then -- extended to the general case by linearity. - classical refine SimpleFunc.induction (motive := fun ψ ↦ ∀ᵐ ω ∂μ, Tendsto (fun n : ℕ ↦ (n : ℝ)⁻¹ • (∑ i ∈ range n, ψ (X i ω))) atTop (𝓝 μ[ψ ∘ (X 0)])) ?_ ?_ φ · intro c s hs diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Basic.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Basic.lean index 26589cea82c1a9..dddfd6e54bc3c7 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Basic.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Basic.lean @@ -123,7 +123,6 @@ which calculates the group cohomology of `A`. -/ noncomputable abbrev inhomogeneousCochains : CochainComplex (ModuleCat k) ℕ := CochainComplex.of (fun n => ModuleCat.of k ((Fin n → G) → A)) (fun n => inhomogeneousCochains.d A n) fun n => by - classical rw [d_eq, d_eq] slice_lhs 3 4 => rw [Iso.hom_inv_id] slice_lhs 2 4 => rw [Category.id_comp, ((barComplex k G).linearYonedaObj k A).d_comp_d] diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Hilbert90.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Hilbert90.lean index 411b4eb031e159..b58f066d968989 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Hilbert90.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Hilbert90.lean @@ -133,7 +133,6 @@ that `N_{L/K}(x) = 1`, and a generator `g` of `Gal(L/K)`, there exists `y : Lˣ` such that `y/g y = x`. -/ theorem exists_div_of_norm_eq_one (hg : ∀ x, x ∈ Subgroup.zpowers g) {x : L} (hx : Algebra.norm K x = 1) : ∃ y : Lˣ, y / g y = x := by - classical suffices H : ∀ x, Algebra.norm K x = 1 → ∃ y : Lˣ, g y / y = x by have hxinv : Algebra.norm K x⁻¹ = 1 := by simp [Algebra.norm_inv, hx] obtain ⟨y, hy⟩ := H _ hxinv diff --git a/Mathlib/RepresentationTheory/Homological/Resolution.lean b/Mathlib/RepresentationTheory/Homological/Resolution.lean index 7708522c2163a4..9685e4a9ea3184 100644 --- a/Mathlib/RepresentationTheory/Homological/Resolution.lean +++ b/Mathlib/RepresentationTheory/Homological/Resolution.lean @@ -205,7 +205,7 @@ def xIso (n : ℕ) : (standardComplex k G).X n ≅ Rep.ofMulAction k G (Fin (n + instance x_projective (G : Type u) [Group G] (n : ℕ) : Projective ((standardComplex k G).X n) := by - classical exact inferInstanceAs <| Projective (Rep.diagonal k G (n + 1)) + exact inferInstanceAs <| Projective (Rep.diagonal k G (n + 1)) set_option backward.defeqAttrib.useBackward true in unif_hint where ⊢ Action.V (Action.ofMulAction G (Fin (n + 1) → G)) ≟ Fin (n + 1) → G in diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index f825c0de10ee70..8a0423b1a09416 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -925,7 +925,7 @@ abbrev freeLiftLEquiv : lemma free_ext (f g : free k G α ⟶ A) (h : ∀ i : α, f.hom (single i (.single 1 1)) = g.hom (single i (.single 1 1))) : f = g := by - classical exact (freeLiftLEquiv k G α A).injective (funext_iff.2 h) + exact (freeLiftLEquiv k G α A).injective (funext_iff.2 h) variable {A} section diff --git a/Mathlib/RepresentationTheory/Rep/Iso.lean b/Mathlib/RepresentationTheory/Rep/Iso.lean index ae54a42dccd7fc..aa51648026bf75 100644 --- a/Mathlib/RepresentationTheory/Rep/Iso.lean +++ b/Mathlib/RepresentationTheory/Rep/Iso.lean @@ -189,7 +189,6 @@ variable {G : Type u} [Group G] {n : ℕ} instance diagonal_succ_projective : Projective (diagonal k G (n + 1)) := by - classical exact Projective.of_iso (diagonalSuccIsoFree k G n).symm inferInstance instance leftRegular_projective : diff --git a/Mathlib/RingTheory/AlgebraTower.lean b/Mathlib/RingTheory/AlgebraTower.lean index c8ffbf2770592f..c26e7a0f00c837 100644 --- a/Mathlib/RingTheory/AlgebraTower.lean +++ b/Mathlib/RingTheory/AlgebraTower.lean @@ -100,7 +100,6 @@ variable [Module R S] [Module S A] [Module R A] [IsScalarTower R S A] theorem linearIndependent_smul {ι : Type*} {b : ι → S} {ι' : Type*} {c : ι' → A} (hb : LinearIndependent R b) (hc : LinearIndependent S c) : LinearIndependent R fun p : ι × ι' ↦ b p.1 • c p.2 := by - classical rw [← linearIndependent_equiv' (.prodComm ..) (g := fun p : ι' × ι ↦ b p.2 • c p.1) rfl, LinearIndependent, linearCombination_smul] simpa using! Function.Injective.comp hc diff --git a/Mathlib/RingTheory/Bezout.lean b/Mathlib/RingTheory/Bezout.lean index f3674690560a5f..5183a733fa7186 100644 --- a/Mathlib/RingTheory/Bezout.lean +++ b/Mathlib/RingTheory/Bezout.lean @@ -31,16 +31,15 @@ namespace IsBezout theorem iff_span_pair_isPrincipal : IsBezout R ↔ ∀ x y : R, (Ideal.span {x, y} : Ideal R).IsPrincipal := by - classical + constructor + · intro H x y; infer_instance + · intro H constructor - · intro H x y; infer_instance - · intro H - constructor - apply Submodule.fg_induction - · exact fun _ => ⟨⟨_, rfl⟩⟩ - · rintro _ _ _ _ ⟨⟨x, rfl⟩⟩ ⟨⟨y, rfl⟩⟩ - rw [← Submodule.span_insert] - exact H _ _ + apply Submodule.fg_induction + · exact fun _ => ⟨⟨_, rfl⟩⟩ + · rintro _ _ _ _ ⟨⟨x, rfl⟩⟩ ⟨⟨y, rfl⟩⟩ + rw [← Submodule.span_insert] + exact H _ _ theorem _root_.Function.Surjective.isBezout {S : Type v} [CommRing S] (f : R →+* S) (hf : Function.Surjective f) [IsBezout R] : IsBezout S := by @@ -55,28 +54,27 @@ theorem _root_.Function.Surjective.isBezout {S : Type v} [CommRing S] (f : R → theorem TFAE [IsBezout R] [IsDomain R] : List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R] := by - classical - tfae_have 1 → 2 - | _ => inferInstance - tfae_have 2 → 3 - | _ => inferInstance - tfae_have 3 → 4 - | _ => inferInstance - tfae_have 4 → 1 - | ⟨h⟩ => by - rw [isNoetherianRing_iff, isNoetherian_iff_fg_wellFounded] - refine ⟨RelEmbedding.wellFounded ?_ h⟩ - have : ∀ I : { J : Ideal R // J.FG }, ∃ x : R, (I : Ideal R) = Ideal.span {x} := - fun ⟨I, hI⟩ => (IsBezout.isPrincipal_of_FG I hI).1 - choose f hf using this - exact - { toFun := f - inj' := fun x y e => by ext1; rw [hf, hf, e] - map_rel_iff' := by - dsimp - intro a b - rw [← Ideal.span_singleton_lt_span_singleton, ← hf, ← hf] - rfl } - tfae_finish + tfae_have 1 → 2 + | _ => inferInstance + tfae_have 2 → 3 + | _ => inferInstance + tfae_have 3 → 4 + | _ => inferInstance + tfae_have 4 → 1 + | ⟨h⟩ => by + rw [isNoetherianRing_iff, isNoetherian_iff_fg_wellFounded] + refine ⟨RelEmbedding.wellFounded ?_ h⟩ + have : ∀ I : { J : Ideal R // J.FG }, ∃ x : R, (I : Ideal R) = Ideal.span {x} := + fun ⟨I, hI⟩ => (IsBezout.isPrincipal_of_FG I hI).1 + choose f hf using this + exact + { toFun := f + inj' := fun x y e => by ext1; rw [hf, hf, e] + map_rel_iff' := by + dsimp + intro a b + rw [← Ideal.span_singleton_lt_span_singleton, ← hf, ← hf] + rfl } + tfae_finish end IsBezout diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index d692d814ba6e86..a54d2a53198216 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -102,7 +102,6 @@ theorem intValuation.map_zero' : v.intValuationDef 0 = 0 := /-- The `v`-adic valuation of `1 : R` equals 1. -/ theorem intValuation.map_one' : v.intValuationDef 1 = 1 := by - classical rw [v.intValuationDef_if_neg one_ne_zero, Ideal.span_singleton_one, ← Ideal.one_eq_top, Associates.mk_one, Associates.factors_one, Associates.count_zero v.associates_irreducible, Int.ofNat_zero, neg_zero, exp_zero] @@ -110,7 +109,6 @@ theorem intValuation.map_one' : v.intValuationDef 1 = 1 := by /-- The `v`-adic valuation of a product equals the product of the valuations. -/ theorem intValuation.map_mul' (x y : R) : v.intValuationDef (x * y) = v.intValuationDef x * v.intValuationDef y := by - classical simp only [intValuationDef] by_cases hx : x = 0 · rw [hx, zero_mul, if_pos rfl, zero_mul] @@ -133,7 +131,6 @@ theorem intValuation.le_max_iff_min_le {a b c : ℕ} : /-- The `v`-adic valuation of a sum is bounded above by the maximum of the valuations. -/ theorem intValuation.map_add_le_max' (x y : R) : v.intValuationDef (x + y) ≤ max (v.intValuationDef x) (v.intValuationDef y) := by - classical by_cases hx : x = 0 · rw [hx, zero_add] order @@ -221,7 +218,6 @@ theorem intValuation_le_one (x : R) : v.intValuation x ≤ 1 := by /-- The `v`-adic valuation of `r : R` is less than 1 if and only if `v` divides the ideal `(r)`. -/ theorem intValuation_lt_one_iff_dvd (r : R) : v.intValuation r < 1 ↔ v.asIdeal ∣ Ideal.span {r} := by - classical by_cases hr : r = 0 · simp [hr] · rw [v.intValuation_if_neg hr, ← exp_zero, exp_lt_exp, @@ -245,7 +241,6 @@ theorem intValuation_eq_one_iff_mem_primeCompl (r : R) : `vⁿ` divides the ideal `(r)`. -/ theorem intValuation_le_pow_iff_dvd (r : R) (n : ℕ) : v.intValuation r ≤ exp (-(n : ℤ)) ↔ v.asIdeal ^ n ∣ Ideal.span {r} := by - classical by_cases hr : r = 0 · simp_rw [hr, Valuation.map_zero, Ideal.dvd_span_singleton, zero_le, Submodule.zero_mem] · rw [v.intValuation_if_neg hr, exp_le_exp, neg_le_neg_iff, Int.ofNat_le, @@ -274,7 +269,6 @@ theorem exp_le_intValuation_iff_emultiplicity_le {r : R} {n : ℕ} : /-- There exists `π : R` with `v`-adic valuation `WithZero.exp (-1)`. -/ theorem intValuation_exists_uniformizer : ∃ π : R, v.intValuation π = WithZero.exp (-1 : ℤ) := by - classical have hv : Irreducible (Associates.mk v.asIdeal) := v.associates_irreducible have hlt : v.asIdeal ^ 2 < v.asIdeal := by rw [← Ideal.dvdNotUnit_iff_lt] @@ -308,7 +302,6 @@ theorem intValuation_uniformizer (π : v.intValuation.Uniformizer) : /-- The `I`-adic valuation of a generator of `I` equals `(-1 : ℤᵐ⁰)` -/ theorem intValuation_singleton {r : R} (hr : r ≠ 0) (hv : v.asIdeal = Ideal.span {r}) : v.intValuation r = exp (-1 : ℤ) := by - classical rw [v.intValuation_if_neg hr, ← hv, Associates.count_self, Int.ofNat_one] exact v.associates_irreducible @@ -432,7 +425,6 @@ theorem mem_integers_of_valuation_le_one (x : K) use z rw [map_mul, mul_comm, mul_eq_mul_left_iff] at hx exact (hx.resolve_right fun h => by simp [hd0] at h).symm - classical have ine {r : R} : r ≠ 0 → Ideal.span {r} ≠ ⊥ := mt Ideal.span_singleton_eq_bot.mp rw [← Associates.mk_le_mk_iff_dvd, ← Associates.factors_le, Associates.factors_mk _ (ine hn0), Associates.factors_mk _ (ine hd0), WithTop.coe_le_coe, Multiset.le_iff_count] diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index 42baecbe8eb5a1..a09fb58226ff46 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -589,7 +589,6 @@ lemma traceForm_dualSubmodule_adjoin (traceForm K L).dualSubmodule (Subalgebra.toSubmodule (Algebra.adjoin A {x})) = (aeval x (derivative <| minpoly K x) : L)⁻¹ • (Subalgebra.toSubmodule (Algebra.adjoin A {x})) := by - classical have hKx : IsIntegral K x := Algebra.IsIntegral.isIntegral x let pb := (Algebra.adjoin.powerBasis' hKx).map ((Subalgebra.equivOfEq _ _ hx).trans (Subalgebra.topEquiv)) @@ -633,7 +632,6 @@ open Polynomial Pointwise in lemma conductor_mul_differentIdeal (x : B) (hx : Algebra.adjoin K {algebraMap B L x} = ⊤) : (conductor A x) * differentIdeal A B = Ideal.span {aeval x (derivative (minpoly A x))} := by - classical have hAx : IsIntegral A x := IsIntegralClosure.isIntegral A L x have := IsIntegralClosure.isFractionRing_of_finite_extension A K L B apply FractionalIdeal.coeIdeal_injective (K := L) @@ -909,7 +907,6 @@ variable {A} theorem not_dvd_differentIdeal_iff [Algebra.IsSeparable (FractionRing A) (FractionRing B)] {P : Ideal B} [P.IsPrime] : ¬ P ∣ differentIdeal A B ↔ Algebra.IsUnramifiedAt A P := by - classical rcases eq_or_ne P ⊥ with rfl | hPbot · simp_rw [← Ideal.zero_eq_bot, zero_dvd_iff] simp only [Submodule.zero_eq_bot, differentIdeal_ne_bot, not_false_eq_true, true_iff] diff --git a/Mathlib/RingTheory/DedekindDomain/Dvr.lean b/Mathlib/RingTheory/DedekindDomain/Dvr.lean index bc729ca4b09a2f..0117b1b8ebd0c9 100644 --- a/Mathlib/RingTheory/DedekindDomain/Dvr.lean +++ b/Mathlib/RingTheory/DedekindDomain/Dvr.lean @@ -128,7 +128,6 @@ theorem IsLocalization.AtPrime.not_isField {P : Ideal A} (hP : P ≠ ⊥) [pP : theorem IsLocalization.AtPrime.isDiscreteValuationRing_of_dedekind_domain [IsDedekindDomain A] {P : Ideal A} (hP : P ≠ ⊥) [pP : P.IsPrime] (Aₘ : Type*) [CommRing Aₘ] [IsDomain Aₘ] [Algebra A Aₘ] [IsLocalization.AtPrime Aₘ P] : IsDiscreteValuationRing Aₘ := by - classical let : IsNoetherianRing Aₘ := IsLocalization.isNoetherianRing P.primeCompl _ IsDedekindRing.toIsNoetherian let : IsLocalRing Aₘ := IsLocalization.AtPrime.isLocalRing Aₘ P diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 359ec6f95ae2c7..969f6ebc069e57 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -76,7 +76,6 @@ theorem IsDedekindDomain.HeightOneSpectrum.maxPowDividing_eq_pow_multiset_count {I : Ideal R} (hI : I ≠ 0) : maxPowDividing v I = v.asIdeal ^ Multiset.count v.asIdeal (normalizedFactors I) := by - classical rw [maxPowDividing, factors_mk _ hI, count_some (irreducible_mk.mpr v.irreducible), ← Multiset.count_map_eq_count' _ _ Subtype.val_injective, map_subtype_coe_factors', factors_eq_normalizedFactors, ← Multiset.count_map_eq_count' _ _ (mk_injective (M := Ideal R))] @@ -197,7 +196,6 @@ theorem finprod_count (I : Ideal R) (hI : I ≠ 0) : (Associates.mk v.asIdeal).c theorem finprod_heightOneSpectrum_factorization {I : Ideal R} (hI : I ≠ 0) : ∏ᶠ v : HeightOneSpectrum R, v.maxPowDividing I = I := by rw [← associated_iff_eq, ← Associates.mk_eq_mk_iff_associated] - classical apply Associates.eq_of_eq_counts · apply Associates.finprod_ne_zero I · apply Associates.mk_ne_zero.mpr hI @@ -363,7 +361,6 @@ theorem count_well_defined {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) {a : R} /-- For nonzero `I, I'`, `val_v(I*I') = val_v(I) + val_v(I')`. -/ theorem count_mul {I I' : FractionalIdeal R⁰ K} (hI : I ≠ 0) (hI' : I' ≠ 0) : count K v (I * I') = count K v I + count K v I' := by - classical have hv : Irreducible (Associates.mk v.asIdeal) := by apply v.associates_irreducible obtain ⟨a, J, ha, haJ⟩ := exists_eq_spanSingleton_mul I have ha_ne_zero : Associates.mk (Ideal.span {a} : Ideal R) ≠ 0 := by @@ -434,7 +431,7 @@ theorem count_self : count K v (v.asIdeal : FractionalIdeal R⁰ K) = 1 := by spanSingleton R⁰ ((algebraMap R K) 1)⁻¹ * ↑v.asIdeal := by rw [(algebraMap R K).map_one, inv_one, spanSingleton_one, one_mul] have hv_irred : Irreducible (Associates.mk v.asIdeal) := by apply v.associates_irreducible - classical rw [count_well_defined K v hv h_self, Associates.count_self hv_irred, + rw [count_well_defined K v hv h_self, Associates.count_self hv_irred, Ideal.span_singleton_one, ← Ideal.one_eq_top, Associates.mk_one, Associates.factors_one, Associates.count_zero hv_irred, ofNat_zero, sub_zero, ofNat_one] @@ -482,7 +479,6 @@ theorem count_maximal_coprime {w : HeightOneSpectrum R} (hw : w ≠ v) : coeIdeal_ne_zero.mpr w.ne_bot have hv : Irreducible (Associates.mk v.asIdeal) := by apply v.associates_irreducible have hw' : Irreducible (Associates.mk w.asIdeal) := by apply w.associates_irreducible - classical rw [count_well_defined K v hw_ne_zero hw_fact, Ideal.span_singleton_one, ← Ideal.one_eq_top, Associates.mk_one, Associates.factors_one, Associates.count_zero hv, ofNat_zero, sub_zero, natCast_eq_zero, ← pow_one (Associates.mk w.asIdeal), Associates.factors_prime_pow hw', @@ -809,7 +805,6 @@ over `p` to the power the ramification index. -/ theorem Ideal.map_algebraMap_eq_finsetProd_pow {p : Ideal S} [p.IsMaximal] (hp : p ≠ 0) : map (algebraMap S R) p = ∏ P ∈ p.primesOver R, P ^ P.ramificationIdx S := by - classical have h : map (algebraMap S R) p ≠ 0 := map_ne_bot_of_ne_bot hp rw [← finprod_heightOneSpectrum_factorization (I := p.map (algebraMap S R)) h] let hF : Fintype {v : HeightOneSpectrum R | v.asIdeal ∣ map (algebraMap S R) p} := @@ -862,7 +857,6 @@ lemma count_normalizedFactors_eq_multiplicity : as `multiplicity p.asIdeal I`. -/ lemma maxPowDividing_eq_pow_multiplicity : p.maxPowDividing I = p.asIdeal ^ multiplicity p.asIdeal I := by - classical rw [maxPowDividing_eq_pow_multiset_count _ hI, count_normalizedFactors_eq_multiplicity hI] /-- Normalize the multiplicity of a prime ideal `p` in the factorization of `I` diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index 29985c38176515..8d27d22e0c4558 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -427,7 +427,6 @@ theorem irreducible_pow_sup (hI : I ≠ ⊥) (hJ : Irreducible J) (n : ℕ) : theorem irreducible_pow_sup_of_le (hJ : Irreducible J) (n : ℕ) (hn : n ≤ emultiplicity J I) : J ^ n ⊔ I = J ^ n := by - classical by_cases hI : I = ⊥ · simp_all rw [irreducible_pow_sup hI hJ, min_eq_right] @@ -439,7 +438,6 @@ alias _root_.irreducible_pow_sup_of_le := irreducible_pow_sup_of_le theorem irreducible_pow_sup_of_ge (hI : I ≠ ⊥) (hJ : Irreducible J) (n : ℕ) (hn : emultiplicity J I ≤ n) : J ^ n ⊔ I = J ^ multiplicity J I := by - classical rw [irreducible_pow_sup hI hJ, min_eq_left] · congr rw [← Nat.cast_inj (R := ℕ∞), ← FiniteMultiplicity.emultiplicity_eq_multiplicity, diff --git a/Mathlib/RingTheory/DedekindDomain/PID.lean b/Mathlib/RingTheory/DedekindDomain/PID.lean index 87ad079d711df5..e769531f63098c 100644 --- a/Mathlib/RingTheory/DedekindDomain/PID.lean +++ b/Mathlib/RingTheory/DedekindDomain/PID.lean @@ -41,7 +41,6 @@ Then `P` is generated by `x`. -/ theorem Ideal.eq_span_singleton_of_mem_of_notMem_sq_of_notMem_prime_ne {P : Ideal R} (hP : P.IsPrime) [IsDedekindDomain R] {x : R} (x_mem : x ∈ P) (hxP2 : x ∉ P ^ 2) (hxQ : ∀ Q : Ideal R, IsPrime Q → Q ≠ P → x ∉ Q) : P = Ideal.span {x} := by - classical by_cases hP0 : P = ⊥ · subst hP0 rwa [eq_comm, span_singleton_eq_bot, ← mem_bot] diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index b89d1f3d671ca9..a3d516d25001d3 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -408,7 +408,6 @@ noncomputable def addVal (R : Type u) [CommRing R] [IsDomain R] [IsDiscreteValua theorem addVal_def (r : R) (u : Rˣ) {ϖ : R} (hϖ : Irreducible ϖ) (n : ℕ) (hr : r = u * ϖ ^ n) : addVal R r = n := by - classical rw [addVal, multiplicity_addValuation_apply, hr, emultiplicity_eq_of_associated_left (associated_of_irreducible R hϖ (Classical.choose_spec (exists_prime R)).irreducible), emultiplicity_eq_of_associated_right (Associated.symm ⟨u, mul_comm _ _⟩), @@ -454,7 +453,6 @@ theorem addVal_eq_top_iff {a : R} : addVal R a = ⊤ ↔ a = 0 := by exact addVal_zero theorem addVal_le_iff_dvd {a b : R} : addVal R a ≤ addVal R b ↔ a ∣ b := by - classical have hp := Classical.choose_spec (exists_prime R) constructor <;> intro h · by_cases ha0 : a = 0 diff --git a/Mathlib/RingTheory/Discriminant.lean b/Mathlib/RingTheory/Discriminant.lean index 2972490392376e..c5d0ad3a4e73a7 100644 --- a/Mathlib/RingTheory/Discriminant.lean +++ b/Mathlib/RingTheory/Discriminant.lean @@ -83,12 +83,11 @@ section Basic @[simp] theorem discr_reindex (b : Basis ι A B) (f : ι ≃ ι') : discr A (b ∘ ⇑f.symm) = discr A b := by - classical rw [← Basis.coe_reindex, discr_def, traceMatrix_reindex, det_reindex_self, ← discr_def] + rw [← Basis.coe_reindex, discr_def, traceMatrix_reindex, det_reindex_self, ← discr_def] /-- If `b` is not linear independent, then `Algebra.discr A b = 0`. -/ theorem discr_zero_of_not_linearIndependent [IsDomain A] {b : ι → B} (hli : ¬LinearIndependent A b) : discr A b = 0 := by - classical obtain ⟨g, hg, i, hi⟩ := Fintype.not_linearIndependent_iff.1 hli have : (traceMatrix A b) *ᵥ g = 0 := by ext i @@ -246,7 +245,6 @@ variable {R : Type z} [CommRing R] [Algebra R K] [Algebra R L] [IsScalarTower R /-- If `K` and `L` are fields and `IsScalarTower R K L`, and `b : ι → L` satisfies ` ∀ i, IsIntegral R (b i)`, then `IsIntegral R (discr K b)`. -/ theorem discr_isIntegral {b : ι → L} (h : ∀ i, IsIntegral R (b i)) : IsIntegral R (discr K b) := by - classical rw [discr_def] exact IsIntegral.det fun i j ↦ isIntegral_trace ((h i).mul (h j)) diff --git a/Mathlib/RingTheory/EssentialFiniteness.lean b/Mathlib/RingTheory/EssentialFiniteness.lean index ae39051f6bc1de..09c76102f4e222 100644 --- a/Mathlib/RingTheory/EssentialFiniteness.lean +++ b/Mathlib/RingTheory/EssentialFiniteness.lean @@ -199,7 +199,6 @@ instance EssFiniteType.baseChange [h : EssFiniteType R S] : EssFiniteType T (T lemma EssFiniteType.of_comp [h : EssFiniteType R T] : EssFiniteType S T := by rw [essFiniteType_iff] at h ⊢ - classical obtain ⟨σ, hσ⟩ := h use σ intro x diff --git a/Mathlib/RingTheory/Etale/QuasiFinite.lean b/Mathlib/RingTheory/Etale/QuasiFinite.lean index cfeb0d8b82fcf4..39fa3641085e44 100644 --- a/Mathlib/RingTheory/Etale/QuasiFinite.lean +++ b/Mathlib/RingTheory/Etale/QuasiFinite.lean @@ -212,7 +212,6 @@ lemma Algebra.exists_etale_isIdempotentElem_forall_liesOver_eq_aux P''.IsPrime → P''.LiesOver P → e₀ ∉ P'' → P'' = P'.comap (Algebra.TensorProduct.map (.id R' R') (integralClosure R S).val).toRingHom) ∧ ∀ P'' : Ideal (R' ⊗[R] S), P''.IsPrime → P''.LiesOver P → e ∉ P'' → P'' = P' := by - classical obtain ⟨s, hsq, hRs, hs, hs₀⟩ := exists_notMem_and_isIntegral_forall_mem_of_ne_of_liesOver p q obtain ⟨m, f, b, hfm, hbm, hab, hfab, hf⟩ : ∃ (m : ℕ) (f : R[X]) (b : p.ResidueField[X]), f.Monic ∧ b.Monic ∧ IsCoprime (X ^ (m + 1)) b ∧ diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean index 0faa990a267968..7ca1974ccb3ffb 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean @@ -462,7 +462,6 @@ set_option backward.isDefEq.respectTransparency false in lemma cotangentSpaceBasis_repr_tmul (r x i) : P.cotangentSpaceBasis.repr (r ⊗ₜ[P.Ring] KaehlerDifferential.D R P.Ring x : _) i = r * aeval P.val (pderiv i x) := by - classical simp only [cotangentSpaceBasis, Basis.baseChange_repr_tmul, mvPolynomialBasis_repr_apply, Algebra.smul_def, mul_comm r, algebraMap_apply, toExtension] diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index 9bb832bfc24773..10451df60b2326 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -294,7 +294,6 @@ public lemma exists_presentation_of_basis_cotangent [Algebra.FinitePresentation span_range_relation_eq_ker := by simpa using (RingHom.ker_eq_top_of_subsingleton _).symm } have : Subsingleton P'.toExtension.Cotangent := Module.subsingleton S _ exact ⟨P', default, by subsingleton, by subsingleton⟩ - classical choose f hf using Extension.Cotangent.mk_surjective (P := P.toExtension) let v (i : σ) : P.ker := f (b₀ i) let J : Ideal P.Ring := Ideal.span (Set.range <| Subtype.val ∘ v) diff --git a/Mathlib/RingTheory/Extension/Presentation/Basic.lean b/Mathlib/RingTheory/Extension/Presentation/Basic.lean index 5dc88a6f3a2fbf..5a74e519600bc1 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Basic.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Basic.lean @@ -461,7 +461,6 @@ lemma relation_comp_localizationAway_inl (P : Presentation R S ι σ) (h1 : P.σ (-1) = -1) (h0 : P.σ 0 = 0) (r : Unit) : ((Presentation.localizationAway T g).comp P).relation (Sum.inl r) = rename Sum.inr (P.σ g) * X (Sum.inl ()) - 1 := by - classical simp only [Presentation.comp, Sum.elim_inl, Presentation.compRelationAux, Presentation.localizationAway_relation, sub_eq_add_neg, C_mul_X_eq_monomial, ← map_one C, ← map_neg C] diff --git a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean index 60e65585343dde..ddc93e16ab104e 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean @@ -214,7 +214,6 @@ noncomputable def ofBijectiveAlgebraMap (h : Function.Bijective (algebraMap R S) @[simp] lemma ofBijectiveAlgebraMap_jacobian (h : Function.Bijective (algebraMap R S)) : (ofBijectiveAlgebraMap h).jacobian = 1 := by - classical have : (algebraMap (ofBijectiveAlgebraMap h).Ring S).mapMatrix (ofBijectiveAlgebraMap h).jacobiMatrix = 1 := by ext (i j : PEmpty) diff --git a/Mathlib/RingTheory/FinitePresentation.lean b/Mathlib/RingTheory/FinitePresentation.lean index e649854b1930f2..727b74aa458f5f 100644 --- a/Mathlib/RingTheory/FinitePresentation.lean +++ b/Mathlib/RingTheory/FinitePresentation.lean @@ -161,7 +161,6 @@ theorem mvPolynomial_of_finitePresentation [FinitePresentation R A] (ι : Type v FinitePresentation R (MvPolynomial ι A) := by have hfp : FinitePresentation R A := inferInstance rw [iff_quotient_mvPolynomial'] at hfp ⊢ - classical -- Make universe level `v` explicit so it matches that of `ι` obtain ⟨(ι' : Type v), _, f, hf_surj, hf_ker⟩ := hfp let g := (MvPolynomial.mapAlgHom f).comp (MvPolynomial.sumAlgEquiv R ι ι').toAlgHom diff --git a/Mathlib/RingTheory/Finiteness/Basic.lean b/Mathlib/RingTheory/Finiteness/Basic.lean index 33801af9098662..32a08ddc924b89 100644 --- a/Mathlib/RingTheory/Finiteness/Basic.lean +++ b/Mathlib/RingTheory/Finiteness/Basic.lean @@ -192,31 +192,30 @@ theorem FG.stabilizes_of_iSup_eq {M' : Submodule R M} (hM' : M'.FG) (N : ℕ → /-- Finitely generated submodules are precisely compact elements in the submodule lattice. -/ theorem fg_iff_compact (s : Submodule R M) : s.FG ↔ IsCompactElement s := by - classical - -- Introduce shorthand for span of an element - let sp : M → Submodule R M := fun a => span R {a} - -- Trivial rewrite lemma; a small hack since simp (only) & rw can't accomplish this smoothly. - have supr_rw : ∀ t : Finset M, ⨆ x ∈ t, sp x = ⨆ x ∈ (↑t : Set M), sp x := fun t => by rfl - constructor - · rintro ⟨t, rfl⟩ - rw [span_eq_iSup_of_singleton_spans, ← supr_rw, ← t.sup_eq_iSup sp] - apply CompleteLattice.isCompactElement_finsetSup - exact fun n _ => singleton_span_isCompactElement n - · intro h - rw [CompleteLattice.isCompactElement_iff_exists_le_sSup_of_le_sSup] at h - -- s is the Sup of the spans of its elements. - have sSup' : s = sSup (sp '' ↑s) := by - rw [sSup_eq_iSup, iSup_image, ← span_eq_iSup_of_singleton_spans, eq_comm, span_eq] - -- by h, s is then below (and equal to) the sup of the spans of finitely many elements. - obtain ⟨u, ⟨huspan, husup⟩⟩ := h (sp '' ↑s) (le_of_eq sSup') - have ssup : s = u.sup id := by - suffices u.sup id ≤ s from le_antisymm husup this - rw [sSup', Finset.sup_id_eq_sSup] - exact sSup_le_sSup huspan - obtain ⟨t, -, rfl⟩ := Finset.subset_set_image_iff.mp huspan - rw [Finset.sup_image, Function.id_comp, Finset.sup_eq_iSup, supr_rw, - ← span_eq_iSup_of_singleton_spans, eq_comm] at ssup - exact ⟨t, ssup⟩ + -- Introduce shorthand for span of an element + let sp : M → Submodule R M := fun a => span R {a} + -- Trivial rewrite lemma; a small hack since simp (only) & rw can't accomplish this smoothly. + have supr_rw : ∀ t : Finset M, ⨆ x ∈ t, sp x = ⨆ x ∈ (↑t : Set M), sp x := fun t => by rfl + constructor + · rintro ⟨t, rfl⟩ + rw [span_eq_iSup_of_singleton_spans, ← supr_rw, ← t.sup_eq_iSup sp] + apply CompleteLattice.isCompactElement_finsetSup + exact fun n _ => singleton_span_isCompactElement n + · intro h + rw [CompleteLattice.isCompactElement_iff_exists_le_sSup_of_le_sSup] at h + -- s is the Sup of the spans of its elements. + have sSup' : s = sSup (sp '' ↑s) := by + rw [sSup_eq_iSup, iSup_image, ← span_eq_iSup_of_singleton_spans, eq_comm, span_eq] + -- by h, s is then below (and equal to) the sup of the spans of finitely many elements. + obtain ⟨u, ⟨huspan, husup⟩⟩ := h (sp '' ↑s) (le_of_eq sSup') + have ssup : s = u.sup id := by + suffices u.sup id ≤ s from le_antisymm husup this + rw [sSup', Finset.sup_id_eq_sSup] + exact sSup_le_sSup huspan + obtain ⟨t, -, rfl⟩ := Finset.subset_set_image_iff.mp huspan + rw [Finset.sup_image, Function.id_comp, Finset.sup_eq_iSup, supr_rw, + ← span_eq_iSup_of_singleton_spans, eq_comm] at ssup + exact ⟨t, ssup⟩ end Submodule diff --git a/Mathlib/RingTheory/Finiteness/Cofinite.lean b/Mathlib/RingTheory/Finiteness/Cofinite.lean index 98924e5a4a6fcd..72a66a813a43ae 100644 --- a/Mathlib/RingTheory/Finiteness/Cofinite.lean +++ b/Mathlib/RingTheory/Finiteness/Cofinite.lean @@ -101,7 +101,7 @@ theorem CoFG.inf {S T : Submodule R M} (hS : S.CoFG) (hT : T.CoFG) : /-- Over a noetherian ring the infimum of a finite family of CoFG submodules is CoFG. -/ protected theorem CoFG.sInf {s : Finset (Submodule R M)} (hs : ∀ S ∈ s, S.CoFG) : - (sInf (s : Set (Submodule R M))).CoFG := by classical + (sInf (s : Set (Submodule R M))).CoFG := by induction s using Finset.induction with | empty => simp | insert w s hws hs' => diff --git a/Mathlib/RingTheory/Finiteness/Descent.lean b/Mathlib/RingTheory/Finiteness/Descent.lean index f93529f0bc1e64..d5199545405dd8 100644 --- a/Mathlib/RingTheory/Finiteness/Descent.lean +++ b/Mathlib/RingTheory/Finiteness/Descent.lean @@ -34,7 +34,6 @@ variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] lemma Module.Finite.of_finite_tensorProduct_of_faithfullyFlat {M : Type*} [AddCommGroup M] [Module R M] [Module.FaithfullyFlat R T] [Module.Finite T (T ⊗[R] M)] : Module.Finite R M := by - classical obtain ⟨n, s, hs⟩ := Module.Finite.exists_fin (R := T) (M := T ⊗[R] M) choose k t m h using fun i : Fin n ↦ TensorProduct.exists_sum_tmul_eq (s i) let f₀ : ((Σ i, Fin (k i)) → R) →ₗ[R] M := (Pi.basisFun R _).constr R fun ⟨i, j⟩ ↦ m i j diff --git a/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean b/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean index 0403a963280364..204c3712dc5945 100644 --- a/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean +++ b/Mathlib/RingTheory/Finiteness/ModuleFinitePresentation.lean @@ -80,7 +80,6 @@ it is finitely presented as a module over `R`. -/ lemma Module.FinitePresentation.of_finite_of_finitePresentation [Module.Finite R S] [Algebra.FinitePresentation R S] : Module.FinitePresentation R S := by - classical obtain ⟨R', _, _, _, _, _, f, hf⟩ := Module.Finite.exists_free_surjective R S let := f.toRingHom.toAlgebra have : IsScalarTower R R' S := .of_algebraMap_eq' f.comp_algebraMap.symm diff --git a/Mathlib/RingTheory/Flat/EquationalCriterion.lean b/Mathlib/RingTheory/Flat/EquationalCriterion.lean index 8b72cfa8d36a6b..f5de6812847b94 100644 --- a/Mathlib/RingTheory/Flat/EquationalCriterion.lean +++ b/Mathlib/RingTheory/Flat/EquationalCriterion.lean @@ -123,7 +123,6 @@ theorem tfae_equational_criterion : List.TFAE [ ∀ {l : ℕ} {f : Fin l →₀ R} {x : (Fin l →₀ R) →ₗ[R] M}, x f = 0 → ∃ (k : ℕ) (a : (Fin l →₀ R) →ₗ[R] (Fin k →₀ R)) (y : (Fin k →₀ R) →ₗ[R] M), x = y ∘ₗ a ∧ a f = 0] := by - classical tfae_have 1 ↔ 2 := iff_rTensor_injective' tfae_have 3 ↔ 2 := forall_vanishesTrivially_iff_forall_rTensor_injective R tfae_have 3 ↔ 4 := by diff --git a/Mathlib/RingTheory/FreeCommRing.lean b/Mathlib/RingTheory/FreeCommRing.lean index 3123cb440278fd..62c7e0e6fd8941 100644 --- a/Mathlib/RingTheory/FreeCommRing.lean +++ b/Mathlib/RingTheory/FreeCommRing.lean @@ -238,7 +238,6 @@ end Restriction theorem isSupported_of {p} {s : Set α} : IsSupported (of p) s ↔ p ∈ s := suffices IsSupported (of p) s → p ∈ s from ⟨this, fun hps => Subring.subset_closure ⟨p, hps, rfl⟩⟩ fun hps : IsSupported (of p) s => by - classical have := Classical.decPred (· ∈ s) have : ∀ x, IsSupported x s → ∃ n : ℤ, lift (fun a => if a ∈ s then (0 : ℤ[X]) else Polynomial.X) x = n := by diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index 7bd4bb28ae90f8..df89ccf3746cfc 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -176,7 +176,6 @@ lemma addOppositeEquiv_symm_orderTop (x : R⟦Γ⟧ᵃᵒᵖ) : @[simp] lemma addOppositeEquiv_leadingCoeff (x : Rᵃᵒᵖ⟦Γ⟧) : (addOppositeEquiv x).unop.leadingCoeff = x.leadingCoeff.unop := by - classical obtain rfl | hx := eq_or_ne x 0 · simp simp only [ne_eq, AddOpposite.unop_eq_zero_iff, EmbeddingLike.map_eq_zero_iff, hx, diff --git a/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean b/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean index 0815cca79f45dc..9f8af8cee49c32 100644 --- a/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean +++ b/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean @@ -40,7 +40,6 @@ variable {R S : Type*} [CommSemiring R] [CommSemiring S] {I J : Ideal R} theorem Ideal.iUnion_minimalPrimes : ⋃ p ∈ I.minimalPrimes, p = { x | ∃ y ∉ I.radical, x * y ∈ I.radical } := by - classical ext x simp only [Set.mem_iUnion, SetLike.mem_coe, exists_prop, Set.mem_setOf_eq] constructor diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 002be48d581530..1be8c87af8ceb4 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -672,13 +672,12 @@ theorem sup_eq_top_iff_isCoprime {R : Type*} [CommSemiring R] (x y : R) : ⟨_, mem_span_singleton'.mpr ⟨_, rfl⟩, _, mem_span_singleton'.mpr ⟨_, rfl⟩, h1⟩ theorem multiset_prod_le_inf {s : Multiset (Ideal R)} : s.prod ≤ s.inf := by - classical - refine s.induction_on ?_ ?_ - · rw [Multiset.inf_zero] - exact le_top - intro a s ih - rw [Multiset.prod_cons, Multiset.inf_cons] - exact le_trans mul_le_inf (inf_le_inf le_rfl ih) + refine s.induction_on ?_ ?_ + · rw [Multiset.inf_zero] + exact le_top + intro a s ih + rw [Multiset.prod_cons, Multiset.inf_cons] + exact le_trans mul_le_inf (inf_le_inf le_rfl ih) theorem prod_le_inf {s : Finset ι} {f : ι → Ideal R} : s.prod f ≤ s.inf f := multiset_prod_le_inf diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean index c7983e5e6eb587..9ca9ada5ad1a80 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean @@ -73,7 +73,6 @@ lemma exists_monic_aeval_eq_zero_forall_mem_pow_of_isIntegral lemma exists_monic_aeval_eq_zero_forall_mem_pow_of_mem_map [Algebra.IsIntegral R S] {I : Ideal R} {x : S} (hx : x ∈ I.map (algebraMap R S)) : ∃ p : R[X], p.Monic ∧ aeval x p = 0 ∧ ∀ i, p.coeff i ∈ I ^ (p.natDegree - i) := by - classical let A : Subalgebra R R[X] := Algebra.adjoin R { C r * X | r ∈ I } let := Polynomial.algebra R S refine exists_monic_aeval_eq_zero_forall_mem_pow_of_isIntegral ?_ diff --git a/Mathlib/RingTheory/Invariant/Basic.lean b/Mathlib/RingTheory/Invariant/Basic.lean index 0021fbed57dec6..3e5686b1f40541 100644 --- a/Mathlib/RingTheory/Invariant/Basic.lean +++ b/Mathlib/RingTheory/Invariant/Basic.lean @@ -274,7 +274,6 @@ private theorem fixed_of_fixed1_aux3 [NoZeroDivisors B] {b : B} {i j : ℕ} {p : private theorem fixed_of_fixed1 [Module.IsTorsionFree (B ⧸ Q) L] (f : Gal(L/K)) (b : B ⧸ Q) (hx : ∀ g : MulAction.stabilizer G Q, Ideal.Quotient.stabilizerHom Q P G g b = b) : f (algebraMap (B ⧸ Q) L b) = (algebraMap (B ⧸ Q) L b) := by - classical cases nonempty_fintype G obtain ⟨b₀, rfl⟩ := Ideal.Quotient.mk_surjective b rw [← Ideal.Quotient.algebraMap_eq] diff --git a/Mathlib/RingTheory/Lasker.lean b/Mathlib/RingTheory/Lasker.lean index c2219449a512b9..ba48f31b456057 100644 --- a/Mathlib/RingTheory/Lasker.lean +++ b/Mathlib/RingTheory/Lasker.lean @@ -63,7 +63,6 @@ lemma isPrimary_decomposition_pairwise_ne_radical {N : Submodule R M} {s : Finset (Submodule R M)} (hs : s.inf id = N) (hs' : ∀ ⦃J⦄, J ∈ s → J.IsPrimary) : ∃ t : Finset (Submodule R M), t.inf id = N ∧ (∀ ⦃J⦄, J ∈ t → J.IsPrimary) ∧ (t : Set (Submodule R M)).Pairwise ((· ≠ ·) on fun J ↦ (J.colon Set.univ).radical) := by - classical refine ⟨(s.image fun J ↦ {I ∈ s | (I.colon .univ).radical = (J.colon .univ).radical}).image fun t ↦ t.inf id, ?_, ?_, ?_⟩ · ext diff --git a/Mathlib/RingTheory/LocalRing/Quotient.lean b/Mathlib/RingTheory/LocalRing/Quotient.lean index 98fcbd0df701b9..ee5c4b00d368ac 100644 --- a/Mathlib/RingTheory/LocalRing/Quotient.lean +++ b/Mathlib/RingTheory/LocalRing/Quotient.lean @@ -64,7 +64,6 @@ variable [Module.Free R S] {ι : Type*} theorem finrank_quotient_map : finrank (R ⧸ p) (S ⧸ pS) = finrank R S := by - classical have : Module.Finite (R ⧸ p) (S ⧸ pS) := Module.Finite.of_restrictScalars_finite R _ _ apply le_antisymm · let b := Module.Free.chooseBasis R S diff --git a/Mathlib/RingTheory/MvPolynomial/Ideal.lean b/Mathlib/RingTheory/MvPolynomial/Ideal.lean index 474013b7e2a648..b0e4ab8bd6bde9 100644 --- a/Mathlib/RingTheory/MvPolynomial/Ideal.lean +++ b/Mathlib/RingTheory/MvPolynomial/Ideal.lean @@ -161,7 +161,6 @@ lemma span_leadingTerm_eq_span_monomial {B : Set (MvPolynomial σ R)} (hB : ∀ p ∈ B, IsUnit (m.leadingCoeff p)) : span (m.leadingTerm '' B) = span ((fun p ↦ MvPolynomial.monomial (m.degree p) (1 : R)) '' B) := by - classical apply le_antisymm all_goals rw [Ideal.span_le, Set.image_subset_iff] diff --git a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean index 7b5730682e44cd..9fa0ba26441393 100644 --- a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean +++ b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean @@ -1049,7 +1049,6 @@ lemma sPolynomial_leadingTerm_mul' [NoZeroDivisors R] (p₁ p₂ q₁ q₂ : MvP ((m.degree (p₁ * q₁)) ⊔ (m.degree (p₂ * q₂)) - m.degree q₁ ⊔ m.degree q₂) (m.leadingCoeff p₁ * m.leadingCoeff p₂) * m.sPolynomial q₁ q₂ := by - classical wlog! +distrib H : p₁ ≠ 0 ∧ p₂ ≠ 0 ∧ q₁ ≠ 0 ∧ q₂ ≠ 0 · (obtain rfl | rfl | rfl | rfl := H) <;> simp simp [H, leadingTerm, sPolynomial_monomial_mul, degree_mul] diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index 167c934b9e5fef..51931d1ddde85e 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -665,7 +665,6 @@ def weightedDecomposition [DecidableEq M] : conv_lhs => rw [← Subtype.coe_inj] rw [decompose'_apply, Submodule.coe_zero] right_inv x := by - classical apply DFinsupp.ext intro m rw [← Subtype.coe_inj, decompose'_apply] diff --git a/Mathlib/RingTheory/MvPowerSeries/Expand.lean b/Mathlib/RingTheory/MvPowerSeries/Expand.lean index 1df40bfe1c3eee..1f5964443d829b 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Expand.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Expand.lean @@ -148,7 +148,6 @@ theorem support_expand_subset (φ : MvPowerSeries σ R) : theorem support_expand (φ : MvPowerSeries σ R) : (expand p hp φ).support = φ.support.image (p • ·) := by - classical refine (support_expand_subset p hp φ).antisymm ?_ intro d hd obtain ⟨n, hn₁, hn₂⟩ := hd diff --git a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean index ca6f718d01b4e1..6d5da99a6def29 100644 --- a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean @@ -211,7 +211,6 @@ theorem variables_tendsto_zero [Semiring R] : theorem isTopologicallyNilpotent_of_constantCoeff_isNilpotent [CommSemiring R] {f : MvPowerSeries σ R} (hf : IsNilpotent (constantCoeff f)) : IsTopologicallyNilpotent f := by - classical obtain ⟨m, hm⟩ := hf simp_rw [IsTopologicallyNilpotent, tendsto_iff_coeff_tendsto, coeff_zero] exact fun d ↦ tendsto_atTop_of_eventually_const fun n hn ↦ diff --git a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean index 10ff8630dd1051..1a1728f9cd7f21 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean @@ -485,7 +485,6 @@ variable (w : τ → ℕ) theorem le_weightedOrder_subst (ha : HasSubst a) (f : MvPowerSeries σ R) : ⨅ (d : σ →₀ ℕ) (_ : coeff d f ≠ 0), d.weight (weightedOrder w ∘ a) ≤ (f.subst a).weightedOrder w := by - classical apply MvPowerSeries.le_weightedOrder intro d hd rw [coeff_subst ha, finsum_eq_zero_of_forall_eq_zero] diff --git a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean index 6da78eab0af087..60f51e1c0260ae 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean @@ -76,7 +76,6 @@ def truncFinset (R : Type*) [CommSemiring R] (s : Finset (σ →₀ ℕ)) : toFun p := ∑ x ∈ s, MvPolynomial.monomial x (p.coeff x) map_add' _ _ := by simp [sum_add_distrib] map_smul' _ _ := by - classical ext simp [MvPolynomial.coeff, single, MvPolynomial.monomial] diff --git a/Mathlib/RingTheory/Polynomial/GaussLemma.lean b/Mathlib/RingTheory/Polynomial/GaussLemma.lean index 584ae38d88571c..a4216cd9fd1076 100644 --- a/Mathlib/RingTheory/Polynomial/GaussLemma.lean +++ b/Mathlib/RingTheory/Polynomial/GaussLemma.lean @@ -284,7 +284,6 @@ theorem IsPrimitive.irreducible_iff_irreducible_map_fraction_map {p : R[X]} (hp mul_assoc, ← mul_assoc, ← map_mul, ← hu, map_mul, mul_assoc, mul_assoc, ← mul_assoc (C (u : R))] at h1 have h0 : a ≠ 0 ∧ b ≠ 0 := by - classical rw [Ne, Ne, ← not_or, ← mul_eq_zero, ← hab] intro con apply hp.ne_zero (map_injective (algebraMap R K) (IsFractionRing.injective _ _) _) diff --git a/Mathlib/RingTheory/Polynomial/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/IsIntegral.lean index 1bda775fc4645b..d35d84433c53fa 100644 --- a/Mathlib/RingTheory/Polynomial/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/IsIntegral.lean @@ -192,7 +192,6 @@ attribute [local instance] MvPolynomial.algebraMvPolynomial in attribute [-simp] AlgEquiv.symm_toRingEquiv in theorem MvPolynomial.isIntegral_iff_isIntegral_coeff.{w} {σ : Type w} {f : MvPolynomial σ S} : IsIntegral (MvPolynomial σ R) f ↔ ∀ n, IsIntegral R (f.coeff n) := by - classical refine ⟨fun H n ↦ ?mp, fun H ↦ ?mpr⟩ case mpr => rw [← f.support_sum_monomial_coeff] diff --git a/Mathlib/RingTheory/Polynomial/Nilpotent.lean b/Mathlib/RingTheory/Polynomial/Nilpotent.lean index 83a2a569d2e3b5..4b439e63eabb38 100644 --- a/Mathlib/RingTheory/Polynomial/Nilpotent.lean +++ b/Mathlib/RingTheory/Polynomial/Nilpotent.lean @@ -189,7 +189,7 @@ theorem not_isUnit_of_degree_pos_of_isReduced [IsReduced R] (p : R[X]) not_isUnit_of_natDegree_pos_of_isReduced _ (natDegree_pos_iff_degree_pos.mpr hpl) instance : IsLocalHom (C : _ →+* Polynomial R) where - map_nonunit := by classical simp +contextual [isUnit_iff_coeff_isUnit_isNilpotent, coeff_C] + map_nonunit := by simp +contextual [isUnit_iff_coeff_isUnit_isNilpotent, coeff_C] instance : IsLocalHom (algebraMap R (Polynomial R)) := inferInstanceAs (IsLocalHom C) diff --git a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean index 6dfd433663cb7c..0752c02e0453a4 100644 --- a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean @@ -150,7 +150,6 @@ theorem resultant_C_zero_left : resultant (C r) g 0 m = r ^ m := by simp set_option backward.defeqAttrib.useBackward true in /-- `Res(f, g) = (-1)ᵐⁿ Res(g, f)` -/ lemma resultant_comm : resultant f g m n = (-1) ^ (m * n) * resultant g f n m := by - classical rw [resultant, resultant, sylvester_comm, Matrix.det_reindex, Equiv.Perm.sign_eq_prod_prod_Ioi] congr 1 dsimp diff --git a/Mathlib/RingTheory/Polynomial/Subring.lean b/Mathlib/RingTheory/Polynomial/Subring.lean index ff8b4ada3378a9..6b06735dd148df 100644 --- a/Mathlib/RingTheory/Polynomial/Subring.lean +++ b/Mathlib/RingTheory/Polynomial/Subring.lean @@ -106,7 +106,6 @@ theorem coeff_ofSubring (p : T[X]) (n : ℕ) : coeff (ofSubring T p) n = (coeff @[simp] theorem coeffs_ofSubring {p : T[X]} : (↑(p.ofSubring T).coeffs : Set R) ⊆ T := by - classical intro i hi simp only [coeffs, Set.mem_image, mem_support_iff, Ne, Finset.mem_coe, (Finset.coe_image)] at hi diff --git a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean index 647ddd0effbdf7..e7771a1752a12e 100644 --- a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean +++ b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean @@ -244,7 +244,6 @@ lemma pderiv_inl_universalFactorizationMap_X (i j) : (universalFactorizationMap R n m k hn (X j))) = if ↑j < (i : ℕ) then 0 else if h : ↑j - ↑i < k then X (.inr ⟨↑j - ↑i, h⟩) else if ↑j - ↑i = k then 1 else 0 := by - classical trans ∑ x ∈ Finset.antidiagonal ↑j, if h : x.2 < k then if x.1 < m ∧ x.1 = ↑i then X (Sum.inr ⟨x.2, h⟩) else 0 else if x.2 = k ∧ x.1 < m ∧ x.1 = ↑i then 1 else 0 @@ -268,7 +267,6 @@ lemma pderiv_inr_universalFactorizationMap_X (i j) : (universalFactorizationMap R n m k hn (X j))) = if ↑j < (i : ℕ) then 0 else if h : ↑j - ↑i < m then X (.inl ⟨↑j - ↑i, h⟩) else if ↑j - ↑i = m then 1 else 0 := by - classical trans ∑ x ∈ Finset.antidiagonal ↑j, if x.2 < k then if h : x.1 < m then if x.2 = ↑i then X (Sum.inl ⟨x.1, h⟩) else 0 else if x.1 = m ∧ x.2 = ↑i then 1 else 0 else 0 · simp [universalFactorizationMap, mapEquivMonic, Polynomial.coeff_mul, coeff_freeMonic, diff --git a/Mathlib/RingTheory/PolynomialAlgebra.lean b/Mathlib/RingTheory/PolynomialAlgebra.lean index 74836adfc17bf9..a43a6f3d4cfe7a 100644 --- a/Mathlib/RingTheory/PolynomialAlgebra.lean +++ b/Mathlib/RingTheory/PolynomialAlgebra.lean @@ -67,7 +67,7 @@ theorem toFunLinear_tmul_apply (a : A) (p : R[X]) : -- in order to successfully rewrite by this lemma. theorem toFunLinear_mul_tmul_mul_aux_1 (p : R[X]) (k : ℕ) (h : Decidable ¬p.coeff k = 0) (a : A) : ite (¬coeff p k = 0) (a * (algebraMap R A) (coeff p k)) 0 = - a * (algebraMap R A) (coeff p k) := by classical split_ifs <;> simp [*] + a * (algebraMap R A) (coeff p k) := by split_ifs <;> simp [*] theorem toFunLinear_mul_tmul_mul_aux_2 (k : ℕ) (a₁ a₂ : A) (p₁ p₂ : R[X]) : a₁ * a₂ * (algebraMap R A) ((p₁ * p₂).coeff k) = diff --git a/Mathlib/RingTheory/PolynomialLaw/Basic.lean b/Mathlib/RingTheory/PolynomialLaw/Basic.lean index 1a1843e362c313..12a0679ced71f5 100644 --- a/Mathlib/RingTheory/PolynomialLaw/Basic.lean +++ b/Mathlib/RingTheory/PolynomialLaw/Basic.lean @@ -441,7 +441,6 @@ theorem exists_lift_of_mem_range_rTensor /-- Tensor products in `S ⊗[R] M` can be lifted to some `MvPolynomial R n ⊗[R] M`, for a finite `n`. -/ theorem π_surjective : Function.Surjective (π R M S) := by - classical intro t obtain ⟨B : Subalgebra R S, hB : B.FG, ht : t ∈ range _⟩ := TensorProduct.Algebra.exists_of_fg t obtain ⟨s : Finset S, hs : (PolynomialLaw.φ R s).range = B⟩ := exists_range_φ_eq_of_fg hB @@ -458,7 +457,6 @@ theorem exists_lift (t : S ⊗[R] M) : ∃ (n : ℕ) (ψ : MvPolynomial (Fin n) theorem exists_lift' (t : S ⊗[R] M) (s : S) : ∃ (n : ℕ) (ψ : MvPolynomial (Fin n) R →ₐ[R] S) (p : MvPolynomial (Fin n) R ⊗[R] M) (q : MvPolynomial (Fin n) R), ψ.toLinearMap.rTensor M p = t ∧ ψ q = s := by - classical obtain ⟨A, hA, ht⟩ := TensorProduct.Algebra.exists_of_fg t have hB : Subalgebra.FG (A ⊔ Algebra.adjoin R ({s} : Finset S)) := Subalgebra.FG.sup hA (Subalgebra.fg_adjoin_finset _) diff --git a/Mathlib/RingTheory/PowerSeries/Order.lean b/Mathlib/RingTheory/PowerSeries/Order.lean index 5f832329dc393b..34d20eb1524bf4 100644 --- a/Mathlib/RingTheory/PowerSeries/Order.lean +++ b/Mathlib/RingTheory/PowerSeries/Order.lean @@ -83,7 +83,6 @@ theorem coeff_order (h : φ ≠ 0) : coeff φ.order.toNat φ ≠ 0 := by /-- If the `n`th coefficient of a formal power series is nonzero, then the order of the power series is less than or equal to `n`. -/ theorem order_le (n : ℕ) (h : coeff n φ ≠ 0) : order φ ≤ n := by - classical rw [order, dif_neg] · simpa using ⟨n, le_rfl, h⟩ · exact exists_coeff_ne_zero_iff_ne_zero.mp ⟨n, h⟩ @@ -103,7 +102,6 @@ theorem coeff_of_lt_order_toNat (n : ℕ) (h : n < φ.order.toNat) : coeff n φ /-- The order of a formal power series is at least `n` if the `i`th coefficient is `0` for all `i < n`. -/ theorem nat_le_order (φ : R⟦X⟧) (n : ℕ) (h : ∀ i < n, coeff i φ = 0) : ↑n ≤ order φ := by - classical simp only [order] split_ifs · simp @@ -123,7 +121,6 @@ theorem le_order (φ : R⟦X⟧) (n : ℕ∞) (h : ∀ i : ℕ, ↑i < n → coe and the `i`th coefficient is `0` for all `i < n`. -/ theorem order_eq_nat {φ : R⟦X⟧} {n : ℕ} : order φ = n ↔ coeff n φ ≠ 0 ∧ ∀ i, i < n → coeff i φ = 0 := by - classical rcases eq_or_ne φ 0 with (rfl | hφ) · simp simp [order, dif_neg hφ, Nat.find_eq_iff] diff --git a/Mathlib/RingTheory/QuasiFinite/Basic.lean b/Mathlib/RingTheory/QuasiFinite/Basic.lean index 6e7c2e270be650..ebf1858e3a16d6 100644 --- a/Mathlib/RingTheory/QuasiFinite/Basic.lean +++ b/Mathlib/RingTheory/QuasiFinite/Basic.lean @@ -518,7 +518,6 @@ lemma _root_.Ideal.exists_not_mem_forall_mem_of_ne_of_liesOver (p : Ideal R) [p.IsPrime] (q : Ideal S) [q.IsPrime] [q.LiesOver p] [Algebra.EssFiniteType R S] [Algebra.QuasiFiniteAt R q] : ∃ s ∉ q, ∀ q' : Ideal S, q'.IsPrime → q' ≠ q → q'.LiesOver p → s ∈ q' := by - classical let e := PrimeSpectrum.preimageHomeomorphFiber _ S ⟨p, inferInstance⟩ let qF : PrimeSpectrum (p.Fiber S) := e ⟨⟨q, ‹_›⟩, PrimeSpectrum.ext (q.over_def p).symm⟩ have : Algebra.QuasiFiniteAt p.ResidueField qF.asIdeal := .baseChange q _ diff --git a/Mathlib/RingTheory/RingHom/StandardSmooth.lean b/Mathlib/RingTheory/RingHom/StandardSmooth.lean index 5d6074b5714dea..209c327966694f 100644 --- a/Mathlib/RingTheory/RingHom/StandardSmooth.lean +++ b/Mathlib/RingTheory/RingHom/StandardSmooth.lean @@ -253,7 +253,6 @@ where `n` is the relative dimension and `R[X₁,...,Xₙ] → S` is etale. -/ theorem IsStandardSmoothOfRelativeDimension.exists_etale_mvPolynomial {f : R →+* S} {n : ℕ} (hf : f.IsStandardSmoothOfRelativeDimension n) : ∃ g : MvPolynomial (Fin n) R →+* S, g.comp MvPolynomial.C = f ∧ g.Etale := by - classical algebraize [f] obtain ⟨g, hg⟩ := Algebra.IsStandardSmoothOfRelativeDimension.exists_etale_mvPolynomial n R S exact ⟨_, g.comp_algebraMap, hg⟩ diff --git a/Mathlib/RingTheory/RingHom/Surjective.lean b/Mathlib/RingTheory/RingHom/Surjective.lean index 9b8437a99e13a8..0fdb4559189639 100644 --- a/Mathlib/RingTheory/RingHom/Surjective.lean +++ b/Mathlib/RingTheory/RingHom/Surjective.lean @@ -47,7 +47,6 @@ theorem surjective_respectsIso : RespectsIso surjective := by theorem surjective_isStableUnderBaseChange : IsStableUnderBaseChange surjective := by refine IsStableUnderBaseChange.mk surjective_respectsIso ?_ - classical introv h x induction x with | zero => exact ⟨0, map_zero _⟩ diff --git a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean index 0fe84cca67fdf1..f4e241ab0da0b2 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean @@ -109,7 +109,6 @@ then the minimal polynomials of a primitive `n`-th root of unity `μ` and of `μ ^ p` are the same. -/ theorem minpoly_eq_pow {p : ℕ} [hprime : Fact p.Prime] (hdiv : ¬p ∣ n) : minpoly ℤ μ = minpoly ℤ (μ ^ p) := by - classical by_cases hn : n = 0 · simp_all have hpos := Nat.pos_of_ne_zero hn diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index 232a3e877e6c25..6392026072d026 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -388,7 +388,6 @@ theorem IsSemisimpleModule.exists_linearEquiv_dfinsupp [IsSemisimpleModule R M] have ⟨s, ind, sSup, simple⟩ := IsSemisimpleModule.exists_sSupIndep_sSup_simples_eq_top R M refine ⟨s, ?_, ind, SetCoe.forall.mpr simple⟩ rw [sSupIndep_iff] at ind - classical exact .symm <| .trans (.ofInjective _ ind.dfinsupp_lsum_injective) <| .trans (.ofEq _ ⊤ <| by rw [← Submodule.iSup_eq_range_dfinsupp_lsum, ← sSup, sSup_eq_iSup']) Submodule.topEquiv diff --git a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean index 060fae7d18d6f8..ad8e42afd26eb9 100644 --- a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean +++ b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean @@ -142,7 +142,7 @@ theorem exists_end_algEquiv_pi_matrix_end : Nonempty (End R M ≃ₐ[R₀] Π i, Matrix (Fin (d i)) (Fin (d i)) (End R (S i))) := by choose d pos S _ simple e using fun c : isotypicComponents R M ↦ (IsIsotypic.isotypicComponents c.2).submodule_linearEquiv_fun - classical exact ⟨_, _, _, fun _ ↦ simple _, fun _ ↦ pos _, ⟨.trans (endAlgEquiv R₀ R M) <| .trans + exact ⟨_, _, _, fun _ ↦ simple _, fun _ ↦ pos _, ⟨.trans (endAlgEquiv R₀ R M) <| .trans (.piCongrRight fun c ↦ ((e c).some.conjAlgEquiv R₀).trans (endVecAlgEquivMatrixEnd ..)) <| (.piCongrLeft' R₀ _ (Finite.equivFin _))⟩⟩ diff --git a/Mathlib/RingTheory/Smooth/Fiber.lean b/Mathlib/RingTheory/Smooth/Fiber.lean index 0fb987b25ad092..22d88fdd803c1c 100644 --- a/Mathlib/RingTheory/Smooth/Fiber.lean +++ b/Mathlib/RingTheory/Smooth/Fiber.lean @@ -153,7 +153,6 @@ lemma FormallySmooth.of_formallySmooth_residueField_tensor (M : Submonoid P) `S = (P/I)[M⁻¹] = P[M⁻¹]/I[M⁻¹]`, where `P` is a polynomial ring and `M` some submonoid of `P/I`. We then apply `FormallySmooth.of_formallySmooth_residueField_tensor_aux` to this presentation. -/ - classical obtain ⟨n, f₀, hf₀⟩ := Algebra.FiniteType.iff_quotient_mvPolynomial''.mp (inferInstance : Algebra.FiniteType R P) let M' := M.comap f₀ diff --git a/Mathlib/RingTheory/Smooth/IntegralClosure.lean b/Mathlib/RingTheory/Smooth/IntegralClosure.lean index b98a96dc4c56e1..1caf917619c7cc 100644 --- a/Mathlib/RingTheory/Smooth/IntegralClosure.lean +++ b/Mathlib/RingTheory/Smooth/IntegralClosure.lean @@ -160,7 +160,6 @@ attribute [local instance] Algebra.TensorProduct.rightAlgebra in lemma TensorProduct.toIntegralClosure_bijective_of_isLocalization (M : Submonoid R) [IsLocalization M S] : Function.Bijective (toIntegralClosure R S B) := by - classical let φ : integralClosure R B →ₐ[R] integralClosure S (S ⊗[R] B) := AlgHom.codRestrict (Algebra.TensorProduct.includeRight.comp (integralClosure R B).val) ((integralClosure S (S ⊗[R] B)).restrictScalars R) fun ⟨x, hx⟩ ↦ by diff --git a/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean b/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean index 758b10169ca3d5..38da79db859b08 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean @@ -338,7 +338,6 @@ private lemma induction_aux (R : Type*) [CommRing R] [Algebra R₀ R] choose! f₂ hf₂ using Ideal.Quotient.mkₐ_surjective R₀ (I := .span {c}) change (∀ _, q₂ _ = _) at hf₂ -- Lift everything together - classical let S₁ : Finset (BasicConstructibleSetData R) := T₁.image fun x ↦ ⟨c * f₁ x.f, _, g₁ x⟩ let S₂ : Finset (BasicConstructibleSetData R) := T₂.image fun x ↦ ⟨f₂ x.f, _, Fin.cons c (g₂ x)⟩ refine ⟨S₁ ∪ S₂, ?_, ?_⟩ @@ -431,7 +430,6 @@ private lemma induction_aux (R : Type*) [CommRing R] [Algebra R₀ R] See the docstring of `induction_structure` for the overview. -/ private lemma statement : ∀ S : InductionObj R n, Statement R₀ R n S := by intro S; revert R₀; revert S - classical apply induction_structure · intro R _ R₀ _ _ f refine ⟨(Finset.range (f.natDegree + 2)).image fun j ↦ ⟨f.coeff j, 0, 0⟩, ?_, ?_⟩ @@ -561,7 +559,6 @@ lemma chevalley_polynomialC {R : Type*} [CommRing R] (M : Submodule ℤ R) (hM : ∃ T : ConstructibleSetData R, comap Polynomial.C '' S.toSet = T.toSet ∧ ∀ C ∈ T, C.n ≤ S.degBound ∧ ∀ i, C.g i ∈ M ^ S.degBound ^ S.degBound := by - classical choose f hf₁ hf₂ hf₃ using fun C : BasicConstructibleSetData R[X] ↦ statement (R₀ := ℤ) ⟨C.g⟩ C.f refine ⟨S.biUnion f, ?_, ?_⟩ · simp only [BasicConstructibleSetData.toSet, ConstructibleSetData.toSet, Set.image_iUnion, @@ -679,7 +676,6 @@ lemma chevalley_mvPolynomialC comap MvPolynomial.C '' S.toSet = T.toSet ∧ ∀ C ∈ T, C.n ≤ numBound k (fun i ↦ 1 + (d.map Fin.val).count i) n ∧ ∀ i, C.g i ∈ M ^ (degBound k (fun i ↦ 1 + (d.map Fin.val).count i) n) := by - classical induction n generalizing k M with | zero => refine ⟨(S.map (isEmptyRingEquiv _ _).toRingHom), ?_, ?_⟩ @@ -814,7 +810,6 @@ lemma chevalley_mvPolynomial_mvPolynomial ∃ T : ConstructibleSetData (MvPolynomial (Fin n) R), comap f '' S.toSet = T.toSet ∧ ∀ C ∈ T, C.n ≤ numBound k m n d ∧ ∀ i j, (C.g i).degreeOf j ≤ degBound k m n d := by - classical let g : MvPolynomial (Fin m) (MvPolynomial (Fin n) R) →+* MvPolynomial (Fin m) R := eval₂Hom f.toRingHom X have hg : g.comp (algebraMap (MvPolynomial (Fin n) R) _) = f := by ext x : 2 <;> simp [g] diff --git a/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean b/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean index d8ec4669009cfa..50bf1077de1bd6 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean @@ -197,7 +197,6 @@ variable {σ : Type*} lemma mem_image_comap_C_basicOpen (f : MvPolynomial σ R) (x : PrimeSpectrum R) : x ∈ comap (C (σ := σ)) '' basicOpen f ↔ ∃ i, f.coeff i ∉ x.asIdeal := by - classical trans f.map (algebraMap R x.asIdeal.ResidueField) ≠ 0 · refine (mem_image_comap_basicOpen _ _).trans (not_iff_not.mpr ?_) let e : x.asIdeal.ResidueField ⊗[R] MvPolynomial σ R ≃ₐ[x.asIdeal.ResidueField] diff --git a/Mathlib/RingTheory/Support.lean b/Mathlib/RingTheory/Support.lean index b5e49ab6706dab..1b61e474aa4729 100644 --- a/Mathlib/RingTheory/Support.lean +++ b/Mathlib/RingTheory/Support.lean @@ -198,7 +198,6 @@ open PrimeSpectrum lemma Module.mem_support_iff_of_finite : p ∈ Module.support R M ↔ Module.annihilator R M ≤ p.asIdeal := by - classical obtain ⟨s, hs⟩ := ‹Module.Finite R M› refine ⟨annihilator_le_of_mem_support, fun H ↦ (mem_support_iff_of_span_eq_top hs).mpr ?_⟩ simp only [SetLike.le_def, Submodule.mem_annihilator_span_singleton] at H ⊢ diff --git a/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean b/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean index b0e8f0dcd134be..1302478a978d9a 100644 --- a/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean +++ b/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean @@ -198,7 +198,6 @@ variable {R M N} (u : M ⊗[R] N) theorem TensorProduct.exists_of_fg : ∃ (P : Submodule R M), P.FG ∧ u ∈ range (rTensor N P.subtype) := by - classical let ⟨P, t, ht⟩ := Module.DirectLimit.exists_of ((Submodule.FG.rTensor.directLimit R M N).symm u) use P.val, P.property, t rw [← Submodule.FG.rTensor.directLimit_apply, ht, LinearEquiv.apply_symm_apply] @@ -208,7 +207,6 @@ theorem TensorProduct.eq_of_fg_of_subtype_eq {t' : P ⊗[R] N} (h : rTensor N P.subtype t = rTensor N P.subtype t') : ∃ (Q : Submodule R M) (hPQ : P ≤ Q), Q.FG ∧ rTensor N (inclusion hPQ) t = rTensor N (inclusion hPQ) t' := by - classical simp only [← Submodule.FG.rTensor.directLimit_apply' R M N hP, EmbeddingLike.apply_eq_iff_eq] at h obtain ⟨Q, hPQ, h⟩ := Module.DirectLimit.exists_eq_of_of_eq h use Q.val, Subtype.coe_le_coe.mpr hPQ, Q.property @@ -327,7 +325,6 @@ theorem Submodule.exists_fg_of_baseChange_eq_zero (f : M →ₗ[R] N) {t : S ⊗[R] M} (ht : f.baseChange S t = 0) : ∃ (A : Subalgebra R S) (_ : A.FG) (u : A ⊗[R] M), f.baseChange A u = 0 ∧ A.val.toLinearMap.rTensor M u = t := by - classical obtain ⟨A, hA, ht_memA⟩ := TensorProduct.Algebra.exists_of_fg t obtain ⟨u, hu⟩ := _root_.id ht_memA have := TensorProduct.Algebra.eq_of_fg_of_subtype_eq hA (t := f.baseChange _ u) (t' := 0) diff --git a/Mathlib/RingTheory/Trace/Quotient.lean b/Mathlib/RingTheory/Trace/Quotient.lean index a5c312a83dd7c5..c81fa8f70d60b1 100644 --- a/Mathlib/RingTheory/Trace/Quotient.lean +++ b/Mathlib/RingTheory/Trace/Quotient.lean @@ -40,7 +40,6 @@ attribute [local instance] Ideal.Quotient.field lemma Algebra.trace_quotient_mk [IsLocalRing R] (x : S) : Algebra.trace (R ⧸ p) (S ⧸ pS) (Ideal.Quotient.mk pS x) = Ideal.Quotient.mk p (Algebra.trace R S x) := by - classical let ι := Module.Free.ChooseBasisIndex R S let b : Module.Basis ι R S := Module.Free.chooseBasis R S rw [trace_eq_matrix_trace b, trace_eq_matrix_trace (basisQuotient b), AddMonoidHom.map_trace] diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index 5b22e5d6662b01..9481b12ea06a52 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -73,7 +73,6 @@ instance Associates.ufm [CommMonoidWithZero α] [UniqueFactorizationMonoid α] : theorem prime_factors_unique [CommMonoidWithZero α] [IsCancelMulZero α] : ∀ {f g : Multiset α}, (∀ x ∈ f, Prime x) → (∀ x ∈ g, Prime x) → f.prod ~ᵤ g.prod → Multiset.Rel Associated f g := by - classical intro f induction f using Multiset.induction_on with | empty => @@ -317,41 +316,40 @@ include pf theorem WfDvdMonoid.of_exists_prime_factors : WfDvdMonoid α := ⟨by - classical - refine RelHomClass.wellFounded - (RelHom.mk ?_ ?_ : (DvdNotUnit : α → α → Prop) →r ((· < ·) : ℕ∞ → ℕ∞ → Prop)) wellFounded_lt - · intro a - by_cases h : a = 0 - · exact ⊤ - exact ↑(Multiset.card (Classical.choose (pf a h))) - rintro a b ⟨ane0, ⟨c, hc, b_eq⟩⟩ - rw [dif_neg ane0] - by_cases h : b = 0 - · simp [h, lt_top_iff_ne_top] - · rw [dif_neg h, Nat.cast_lt] - have cne0 : c ≠ 0 := by - refine mt (fun con => ?_) h - rw [b_eq, con, mul_zero] - calc - Multiset.card (Classical.choose (pf a ane0)) < - _ + Multiset.card (Classical.choose (pf c cne0)) := - lt_add_of_pos_right _ - (Multiset.card_pos.mpr fun con => hc (associated_one_iff_isUnit.mp ?_)) - _ = Multiset.card (Classical.choose (pf a ane0) + Classical.choose (pf c cne0)) := - (Multiset.card_add _ _).symm - _ = Multiset.card (Classical.choose (pf b h)) := - Multiset.card_eq_card_of_rel - (prime_factors_unique ?_ (Classical.choose_spec (pf _ h)).1 ?_) - · convert! (Classical.choose_spec (pf c cne0)).2.symm - rw [con, Multiset.prod_zero] - · intro x hadd - rw [Multiset.mem_add] at hadd - rcases hadd with h | h <;> apply (Classical.choose_spec (pf _ _)).1 _ h <;> assumption - · rw [Multiset.prod_add] - trans a * c - · apply Associated.mul_mul <;> apply (Classical.choose_spec (pf _ _)).2 <;> assumption - · rw [← b_eq] - apply (Classical.choose_spec (pf _ _)).2.symm; assumption⟩ + refine RelHomClass.wellFounded + (RelHom.mk ?_ ?_ : (DvdNotUnit : α → α → Prop) →r ((· < ·) : ℕ∞ → ℕ∞ → Prop)) wellFounded_lt + · intro a + by_cases h : a = 0 + · exact ⊤ + exact ↑(Multiset.card (Classical.choose (pf a h))) + rintro a b ⟨ane0, ⟨c, hc, b_eq⟩⟩ + rw [dif_neg ane0] + by_cases h : b = 0 + · simp [h, lt_top_iff_ne_top] + · rw [dif_neg h, Nat.cast_lt] + have cne0 : c ≠ 0 := by + refine mt (fun con => ?_) h + rw [b_eq, con, mul_zero] + calc + Multiset.card (Classical.choose (pf a ane0)) < + _ + Multiset.card (Classical.choose (pf c cne0)) := + lt_add_of_pos_right _ + (Multiset.card_pos.mpr fun con => hc (associated_one_iff_isUnit.mp ?_)) + _ = Multiset.card (Classical.choose (pf a ane0) + Classical.choose (pf c cne0)) := + (Multiset.card_add _ _).symm + _ = Multiset.card (Classical.choose (pf b h)) := + Multiset.card_eq_card_of_rel + (prime_factors_unique ?_ (Classical.choose_spec (pf _ h)).1 ?_) + · convert! (Classical.choose_spec (pf c cne0)).2.symm + rw [con, Multiset.prod_zero] + · intro x hadd + rw [Multiset.mem_add] at hadd + rcases hadd with h | h <;> apply (Classical.choose_spec (pf _ _)).1 _ h <;> assumption + · rw [Multiset.prod_add] + trans a * c + · apply Associated.mul_mul <;> apply (Classical.choose_spec (pf _ _)).2 <;> assumption + · rw [← b_eq] + apply (Classical.choose_spec (pf _ _)).2.symm; assumption⟩ theorem irreducible_iff_prime_of_exists_prime_factors {p : α} : Irreducible p ↔ Prime p := by by_cases hp0 : p = 0 diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean index 0c9c53795fab29..813990ae38a3af 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean @@ -226,9 +226,8 @@ theorem factors_zero : (0 : Associates α).factors = ⊤ := @[simp] theorem factors_mk (a : α) (h : a ≠ 0) : (Associates.mk a).factors = factors' a := by - classical - apply dif_neg - apply mt mk_eq_zero.1 h + apply dif_neg + apply mt mk_eq_zero.1 h @[simp] theorem factors_prod (a : Associates α) : a.factors.prod = a := by diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean index 4a392091aa3b51..f6db5564bcc18e 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean @@ -26,7 +26,6 @@ open UniqueFactorizationMonoid in theorem Ideal.IsPrime.exists_mem_prime_of_ne_bot {R : Type*} [CommSemiring R] [UniqueFactorizationMonoid R] {I : Ideal R} (hI₂ : I.IsPrime) (hI : I ≠ ⊥) : ∃ x ∈ I, Prime x := by - classical obtain ⟨a : R, ha₁ : a ∈ I, ha₂ : a ≠ 0⟩ := Submodule.exists_mem_ne_zero_of_ne_bot hI replace ha₁ : (factors a).prod ∈ I := by obtain ⟨u : Rˣ, hu : (factors a).prod * u = a⟩ := factors_prod ha₂ diff --git a/Mathlib/RingTheory/Unramified/LocalStructure.lean b/Mathlib/RingTheory/Unramified/LocalStructure.lean index 32967415cc43c2..c9aebd3eb22ba5 100644 --- a/Mathlib/RingTheory/Unramified/LocalStructure.lean +++ b/Mathlib/RingTheory/Unramified/LocalStructure.lean @@ -214,7 +214,6 @@ lemma exists_notMem_forall_ne_mem_and_adjoin_eq_top let p := Q.under R #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. -/ let : Module p.ResidueField (p.Fiber S) := TensorProduct.leftModule @@ -286,7 +285,6 @@ lemma exists_primesOver_under_adjoin_eq_singleton_and_residueField_bijective let p := Q.under R let := Localization.AtPrime.algebraOfLiesOver p (Q.under R[t]) let := Localization.AtPrime.algebraOfLiesOver (Q.under R[t]) Q - classical refine ⟨t, ?_, RingHom.injective _, ?_⟩ · refine Set.ext fun Q' ↦ ⟨fun ⟨_, _⟩ ↦ ?_, fun e ↦ by exact ⟨e ▸ inferInstance, ⟨e ▸ rfl⟩⟩⟩ by_contra! H @@ -389,7 +387,6 @@ theorem IsSmoothAt.exists_isStandardEtale_mvPolynomial ∃ f ∉ p, ∃ (n : ℕ) (_ : Algebra (MvPolynomial (Fin n) R) (Localization.Away f)), IsScalarTower R (MvPolynomial (Fin n) R) (Localization.Away f) ∧ IsStandardEtale (MvPolynomial (Fin n) R) (Localization.Away f) := by - classical obtain ⟨f, hfp, H⟩ := IsSmoothAt.exists_notMem_isStandardSmooth R p obtain ⟨n, φ, hgC, hg⟩ := RingHom.IsStandardSmooth.exists_etale_mvPolynomial (f := algebraMap R (Localization.Away f)) (by simpa [RingHom.isStandardSmooth_algebraMap]) diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index a669fb8572cbfd..f869fcfc62cca4 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -478,7 +478,6 @@ lemma embedding_restrict (x : R) : embedding (v.restrict x) = v x := lemma restrict_eq_mk {x : R} (hx : v x ≠ 0) : v.restrict x = (valueGroup.mk (.ofClass v) 1 x (by simp) hx : ValueGroup₀ (.ofClass v)) := by - classical simp [restrict_def, restrict₀_apply, dif_neg hx, valueGroup.mk] @[simp] diff --git a/Mathlib/RingTheory/Valuation/ValuationRing.lean b/Mathlib/RingTheory/Valuation/ValuationRing.lean index d5f1081b0d5122..2e3868e351bd39 100644 --- a/Mathlib/RingTheory/Valuation/ValuationRing.lean +++ b/Mathlib/RingTheory/Valuation/ValuationRing.lean @@ -304,7 +304,6 @@ variable {R : Type*} theorem _root_.PreValuationRing.iff_dvd_total [Semigroup R] : PreValuationRing R ↔ @Std.Total R (· ∣ ·) := by - classical refine ⟨fun H => ⟨fun a b => ?_⟩, fun H => ⟨fun a b => ?_⟩⟩ · obtain ⟨c, rfl | rfl⟩ := PreValuationRing.cond a b <;> simp · obtain ⟨c, rfl⟩ | ⟨c, rfl⟩ := H.total a b <;> use c <;> simp @@ -386,7 +385,6 @@ instance (priority := 100) [ValuationRing R] : IsBezout R := by · rw [sup_eq_left.mpr h]; exact ⟨⟨_, rfl⟩⟩ instance (priority := 100) [IsLocalRing R] [IsBezout R] : ValuationRing R := by - classical refine iff_dvd_total.mpr ⟨fun a b => ?_⟩ obtain ⟨g, e : _ = Ideal.span _⟩ := IsBezout.span_pair_isPrincipal a b obtain ⟨a, rfl⟩ := Ideal.mem_span_singleton'.mp diff --git a/Mathlib/RingTheory/ZMod/UnitsCyclic.lean b/Mathlib/RingTheory/ZMod/UnitsCyclic.lean index ee69cb34b172df..eca1e31672e31a 100644 --- a/Mathlib/RingTheory/ZMod/UnitsCyclic.lean +++ b/Mathlib/RingTheory/ZMod/UnitsCyclic.lean @@ -284,7 +284,6 @@ theorem isCyclic_units_two_mul_iff_of_odd (n : ℕ) (hn : Odd n) : theorem not_isCyclic_units_of_mul_coprime (m n : ℕ) (hm : Odd m) (hm1 : m ≠ 1) (hn : Odd n) (hn1 : n ≠ 1) (hmn : m.Coprime n) : ¬ IsCyclic (ZMod (m * n))ˣ := by - classical have _ : NeZero m := ⟨Nat.ne_of_odd_add hm⟩ have _ : NeZero n := ⟨Nat.ne_of_odd_add hn⟩ let e := (Units.mapEquiv (chineseRemainder hmn).toMulEquiv).trans .prodUnits diff --git a/Mathlib/Tactic/CancelDenoms/Core.lean b/Mathlib/Tactic/CancelDenoms/Core.lean index 2751270e0cc562..cd2312f16aa0a1 100644 --- a/Mathlib/Tactic/CancelDenoms/Core.lean +++ b/Mathlib/Tactic/CancelDenoms/Core.lean @@ -94,7 +94,6 @@ theorem cancel_factors_eq {α} [Field α] {a b ad bd a' b' gcd : α} (ha : ad * theorem cancel_factors_ne {α} [Field α] {a b ad bd a' b' gcd : α} (ha : ad * a = a') (hb : bd * b = b') (had : ad ≠ 0) (hbd : bd ≠ 0) (hgcd : gcd ≠ 0) : (a ≠ b) = (1 / gcd * (bd * a') ≠ 1 / gcd * (ad * b')) := by - classical rw [eq_iff_iff, not_iff_not, cancel_factors_eq ha hb had hbd hgcd] /-! ### Computing cancellation factors -/ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean index bcff99254b71ce..71666b3b22310f 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean @@ -325,7 +325,7 @@ variable [T2Space α] [L.NeBot] @[to_additive] theorem HasProd.unique {a₁ a₂ : α} : HasProd f a₁ L → HasProd f a₂ L → a₁ = a₂ := by - classical exact tendsto_nhds_unique + exact tendsto_nhds_unique @[to_additive] theorem HasProd.tprod_eq (ha : HasProd f a L) : ∏'[L] b, f b = a := diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean index 1a4cbbe72bc654..d039ee2321fa1c 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean @@ -202,7 +202,7 @@ variable [UniformSpace α] **Cauchy convergence test** -/] theorem multipliable_iff_cauchySeq_finset [CommMonoid α] [CompleteSpace α] {f : β → α} : Multipliable f ↔ CauchySeq fun s : Finset β ↦ ∏ b ∈ s, f b := by - classical exact cauchy_map_iff_exists_tendsto.symm + exact cauchy_map_iff_exists_tendsto.symm variable [CommGroup α] [IsUniformGroup α] {f g : β → α} @@ -349,7 +349,6 @@ cover the whole space. This does not need a summability assumption, as otherwise zero. -/] theorem tendsto_tprod_compl_atTop_one (f : α → G) : Tendsto (fun s : Finset α ↦ ∏' a : { x // x ∉ s }, f a) atTop (𝓝 1) := by - classical by_cases H : Multipliable f · intro e he obtain ⟨s, hs⟩ := H.tprod_vanishing he @@ -455,7 +454,6 @@ ring). lemma Multipliable.congr_cofinite₀ (hf : Multipliable f) (hf' : ∀ a, f a ≠ 0) (hfg : ∀ᶠ a in cofinite, f a = g a) : Multipliable g := by - classical obtain ⟨c, hc⟩ := hf obtain ⟨s, hs⟩ : ∃ s : Finset α, ∀ i ∉ s, f i = g i := ⟨hfg.toFinset, by simp⟩ exact (hc.congr_cofinite₀ (fun a _ ↦ hf' a) hs).multipliable diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean index 97017871e4fcc6..d625839ecea1e3 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean @@ -98,7 +98,6 @@ theorem prod_le_hasProd [L.NeBot] [L.LeAtTop] (s : Finset ι) (hs : ∀ i, i ∉ @[to_additive] theorem isLUB_hasProd (h : ∀ i, 1 ≤ f i) (hf : HasProd f a) : IsLUB (Set.range fun s ↦ ∏ i ∈ s, f i) a := by - classical exact isLUB_of_tendsto_atTop (Finset.prod_mono_set_of_one_le' h) hf @[to_additive] @@ -266,7 +265,6 @@ protected theorem Multipliable.tprod_ne_one_iff (hf : Multipliable f) : omit [IsOrderedMonoid α] in @[to_additive] theorem isLUB_hasProd' (hf : HasProd f a) : IsLUB (Set.range fun s ↦ ∏ i ∈ s, f i) a := by - classical exact isLUB_of_tendsto_atTop (Finset.prod_mono_set' f) hf end CanonicallyOrderedMul diff --git a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean index 3fa8bd6d7034fc..f9ef85a36b04fe 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean @@ -192,7 +192,6 @@ instance [Countable β] : IsCountablyGenerated (unconditional β).filter := `L.LeAtTop` and `L.NeBot`. -/ lemma eq_unconditional_of_finite {β} [Finite β] (L : SummationFilter β) [L.LeAtTop] [L.NeBot] : L = unconditional β := by - classical have := Fintype.ofFinite β have hAtTop : (atTop : Filter (Finset β)) = pure Finset.univ := by rw [(isTop_iff_eq_top.mpr rfl).atTop_eq (a := Finset.univ), ← Finset.top_eq_univ, diff --git a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean index b1d32d1ae33b4f..9c0ceadbc2bc0f 100644 --- a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean +++ b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean @@ -258,7 +258,6 @@ lemma locallyFiniteOrder_units_mrange_of_isCompact_integer (hc : IsCompact (X := -- there must be something in the cover that has the precise valuation of the element, -- because it must be outside the inner closed ball, and thus is covered by some sphere. obtain ⟨t, ht⟩ := this - classical refine (t.finite_toSet.dependent_image ?_).subset ?_ · refine fun i hi ↦ if hi' : v i ≤ z then z else Units.mk0 ⟨(v i), by simp⟩ ?_ push Not at hi' diff --git a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean index 7515edaf066add..fa3472bb477a28 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean @@ -60,7 +60,6 @@ theorem subgroups_basis : RingSubgroupsBasis fun γ : (ValueGroup₀ (.ofClass v))ˣ ↦ v.ltAddSubgroup <| Units.map (ValueGroup₀.embedding (f := (.ofClass v))) γ := { inter := by - classical rintro γ₀ γ₁ use min γ₀ γ₁ have hmin : embedding (min γ₀.1 γ₁.1) = min (embedding γ₀.1) (embedding γ₁.1) := diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index 0f0f940695bd2b..c0c0c2f435209d 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -642,7 +642,6 @@ theorem restrict_exists_div_eq {K : Type*} [DivisionRing K] {Γ₀ : Type*} (γ : (ValueGroup₀ (.ofClass v))ˣ) : ∃ r s, 0 < v r ∧ 0 < v s ∧ v.restrict r / v.restrict s = γ.1 := by obtain ⟨r, hr⟩ := ValueGroup₀.restrict₀_surjective (.ofClass v) γ - classical exact ⟨r, 1, by simp only [map_one, zero_lt_one, restrict_def, hr, div_one, and_self, and_true] rw [← map_zero v] diff --git a/Mathlib/Topology/CWComplex/Classical/Finite.lean b/Mathlib/Topology/CWComplex/Classical/Finite.lean index 993561d306d25e..5ce7bb7d026a8c 100644 --- a/Mathlib/Topology/CWComplex/Classical/Finite.lean +++ b/Mathlib/Topology/CWComplex/Classical/Finite.lean @@ -320,7 +320,6 @@ lemma RelCWComplex.finite_of_finite_cells (finite : _root_.Finite (Σ n, cell C -- We take the greatest `n` such that there is a `j : cell C n` and show that this fulfills -- the necessary conditions. have _ := Fintype.ofFinite (Σ n, cell C n) - classical let A := (Finset.univ : Finset (Σ n, cell C n)).image Sigma.fst use A.max' (Finset.image_nonempty.2 Finset.univ_nonempty) + 1 intro m _ diff --git a/Mathlib/Topology/Compactness/CountablyCompact.lean b/Mathlib/Topology/Compactness/CountablyCompact.lean index 175bb4d8985b8f..84a527bde374da 100644 --- a/Mathlib/Topology/Compactness/CountablyCompact.lean +++ b/Mathlib/Topology/Compactness/CountablyCompact.lean @@ -154,7 +154,6 @@ theorem IsCountablyCompact.elim_finite_subcover_image (hA : IsCountablyCompact A (hAU : A ⊆ ⋃ i ∈ b, U i) : ∃ t ⊆ b, t.Finite ∧ A ⊆ ⋃ i ∈ t, U i := by have := hb.to_subtype obtain ⟨t, ht⟩ := hA.elim_finite_subcover (fun (i : b) ↦ hUo i i.prop) (by simpa using hAU) - classical simp only [Subtype.forall', biUnion_eq_iUnion] at hUo hAU replace hb := hb.to_subtype obtain ⟨d, hd⟩ := hA.elim_finite_subcover hUo hAU diff --git a/Mathlib/Topology/Compactness/Paracompact.lean b/Mathlib/Topology/Compactness/Paracompact.lean index 7d791089d0724d..4a7fd7ab720f6a 100644 --- a/Mathlib/Topology/Compactness/Paracompact.lean +++ b/Mathlib/Topology/Compactness/Paracompact.lean @@ -211,47 +211,46 @@ theorem refinement_of_locallyCompact_sigmaCompact_of_nhds_basis_set [WeaklyLocal ∃ (α : Type v) (c : α → X) (r : ∀ a, ι (c a)), (∀ a, c a ∈ s ∧ p (c a) (r a)) ∧ (s ⊆ ⋃ a, B (c a) (r a)) ∧ LocallyFinite fun a ↦ B (c a) (r a) := by - classical - -- For technical reasons we prepend two empty sets to the sequence `CompactExhaustion.choice X` - set K' : CompactExhaustion X := CompactExhaustion.choice X - set K : CompactExhaustion X := K'.shiftr.shiftr - set Kdiff := fun n ↦ K (n + 1) \ interior (K n) - -- Now we restate some properties of `CompactExhaustion` for `K`/`Kdiff` - have hKcov : ∀ x, x ∈ Kdiff (K'.find x + 1) := fun x ↦ by - simpa only [K'.find_shiftr] using - sdiff_subset_sdiff_right interior_subset (K'.shiftr.mem_sdiff_shiftr_find x) - have Kdiffc : ∀ n, IsCompact (Kdiff n ∩ s) := - fun n ↦ ((K.isCompact _).diff isOpen_interior).inter_right hs - -- Next we choose a finite covering `B (c n i) (r n i)` of each - -- `Kdiff (n + 1) ∩ s` such that `B (c n i) (r n i) ∩ s` is disjoint with `K n` - have : ∀ (n) (x : ↑(Kdiff (n + 1) ∩ s)), (K n)ᶜ ∈ 𝓝 (x : X) := - fun n x ↦ (K.isClosed n).compl_mem_nhds fun hx' ↦ x.2.1.2 <| K.subset_interior_succ _ hx' - choose! r hrp hr using fun n (x : ↑(Kdiff (n + 1) ∩ s)) ↦ (hB x x.2.2).mem_iff.1 (this n x) - have hxr : ∀ (n x) (hx : x ∈ Kdiff (n + 1) ∩ s), B x (r n ⟨x, hx⟩) ∈ 𝓝 x := fun n x hx ↦ - (hB x hx.2).mem_of_mem (hrp _ ⟨x, hx⟩) - choose T hT using fun n ↦ (Kdiffc (n + 1)).elim_nhds_subcover' _ (hxr n) - set T' : ∀ n, Set ↑(Kdiff (n + 1) ∩ s) := fun n ↦ T n - -- Finally, we take the union of all these coverings - refine ⟨Σ n, T' n, fun a ↦ a.2, fun a ↦ r a.1 a.2, ?_, ?_, ?_⟩ - · rintro ⟨n, x, hx⟩ - exact ⟨x.2.2, hrp _ _⟩ - · refine fun x hx ↦ mem_iUnion.2 ?_ - rcases mem_iUnion₂.1 (hT _ ⟨hKcov x, hx⟩) with ⟨⟨c, hc⟩, hcT, hcx⟩ - exact ⟨⟨_, ⟨c, hc⟩, hcT⟩, hcx⟩ - · intro x - refine - ⟨interior (K (K'.find x + 3)), - IsOpen.mem_nhds isOpen_interior (K.subset_interior_succ _ (hKcov x).1), ?_⟩ - have : (⋃ k ≤ K'.find x + 2, range (Sigma.mk k) : Set (Σ n, T' n)).Finite := - (finite_le_nat _).biUnion fun k _ ↦ finite_range _ - apply this.subset - rintro ⟨k, c, hc⟩ - simp only [mem_iUnion, mem_setOf_eq, Subtype.coe_mk] - rintro ⟨x, hxB : x ∈ B c (r k c), hxK⟩ - refine ⟨k, ?_, ⟨c, hc⟩, rfl⟩ - have := (mem_compl_iff _ _).1 (hr k c hxB) - contrapose! this with hnk - exact K.subset hnk (interior_subset hxK) + -- For technical reasons we prepend two empty sets to the sequence `CompactExhaustion.choice X` + set K' : CompactExhaustion X := CompactExhaustion.choice X + set K : CompactExhaustion X := K'.shiftr.shiftr + set Kdiff := fun n ↦ K (n + 1) \ interior (K n) + -- Now we restate some properties of `CompactExhaustion` for `K`/`Kdiff` + have hKcov : ∀ x, x ∈ Kdiff (K'.find x + 1) := fun x ↦ by + simpa only [K'.find_shiftr] using + sdiff_subset_sdiff_right interior_subset (K'.shiftr.mem_sdiff_shiftr_find x) + have Kdiffc : ∀ n, IsCompact (Kdiff n ∩ s) := + fun n ↦ ((K.isCompact _).diff isOpen_interior).inter_right hs + -- Next we choose a finite covering `B (c n i) (r n i)` of each + -- `Kdiff (n + 1) ∩ s` such that `B (c n i) (r n i) ∩ s` is disjoint with `K n` + have : ∀ (n) (x : ↑(Kdiff (n + 1) ∩ s)), (K n)ᶜ ∈ 𝓝 (x : X) := + fun n x ↦ (K.isClosed n).compl_mem_nhds fun hx' ↦ x.2.1.2 <| K.subset_interior_succ _ hx' + choose! r hrp hr using fun n (x : ↑(Kdiff (n + 1) ∩ s)) ↦ (hB x x.2.2).mem_iff.1 (this n x) + have hxr : ∀ (n x) (hx : x ∈ Kdiff (n + 1) ∩ s), B x (r n ⟨x, hx⟩) ∈ 𝓝 x := fun n x hx ↦ + (hB x hx.2).mem_of_mem (hrp _ ⟨x, hx⟩) + choose T hT using fun n ↦ (Kdiffc (n + 1)).elim_nhds_subcover' _ (hxr n) + set T' : ∀ n, Set ↑(Kdiff (n + 1) ∩ s) := fun n ↦ T n + -- Finally, we take the union of all these coverings + refine ⟨Σ n, T' n, fun a ↦ a.2, fun a ↦ r a.1 a.2, ?_, ?_, ?_⟩ + · rintro ⟨n, x, hx⟩ + exact ⟨x.2.2, hrp _ _⟩ + · refine fun x hx ↦ mem_iUnion.2 ?_ + rcases mem_iUnion₂.1 (hT _ ⟨hKcov x, hx⟩) with ⟨⟨c, hc⟩, hcT, hcx⟩ + exact ⟨⟨_, ⟨c, hc⟩, hcT⟩, hcx⟩ + · intro x + refine + ⟨interior (K (K'.find x + 3)), + IsOpen.mem_nhds isOpen_interior (K.subset_interior_succ _ (hKcov x).1), ?_⟩ + have : (⋃ k ≤ K'.find x + 2, range (Sigma.mk k) : Set (Σ n, T' n)).Finite := + (finite_le_nat _).biUnion fun k _ ↦ finite_range _ + apply this.subset + rintro ⟨k, c, hc⟩ + simp only [mem_iUnion, mem_setOf_eq, Subtype.coe_mk] + rintro ⟨x, hxB : x ∈ B c (r k c), hxK⟩ + refine ⟨k, ?_, ⟨c, hc⟩, rfl⟩ + have := (mem_compl_iff _ _).1 (hr k c hxB) + contrapose! this with hnk + exact K.subset hnk (interior_subset hxK) /-- Let `X` be a locally compact sigma compact Hausdorff topological space. Suppose that for each `x` the sets `B x : ι x → Set X` with the predicate `p x : ι x → Prop` form a basis of the filter diff --git a/Mathlib/Topology/Connected/Clopen.lean b/Mathlib/Topology/Connected/Clopen.lean index b295ed09d65f34..35b4c706784bc4 100644 --- a/Mathlib/Topology/Connected/Clopen.lean +++ b/Mathlib/Topology/Connected/Clopen.lean @@ -276,7 +276,6 @@ theorem isConnected_iff_sUnion_disjoint_open {s : Set α} : ∀ U : Finset (Set α), (∀ u v : Set α, u ∈ U → v ∈ U → (s ∩ (u ∩ v)).Nonempty → u = v) → (∀ u ∈ U, IsOpen u) → (s ⊆ ⋃₀ ↑U) → ∃ u ∈ U, s ⊆ u := by rw [IsConnected, isPreconnected_iff_subset_of_disjoint] - classical refine ⟨fun ⟨hne, h⟩ U hU hUo hsU => ?_, fun h => ⟨?_, fun u v hu hv hs hsuv => ?_⟩⟩ · induction U using Finset.induction_on with | empty => exact absurd (by simpa using hsU) hne.not_subset_empty diff --git a/Mathlib/Topology/ContinuousMap/Compact.lean b/Mathlib/Topology/ContinuousMap/Compact.lean index 83583586041b6c..9fe734c25b057f 100644 --- a/Mathlib/Topology/ContinuousMap/Compact.lean +++ b/Mathlib/Topology/ContinuousMap/Compact.lean @@ -459,7 +459,6 @@ variable {E : Type*} [NormedAddCommGroup E] [CompleteSpace E] theorem summable_of_locally_summable_norm {ι : Type*} {F : ι → C(X, E)} (hF : ∀ K : Compacts X, Summable fun i => ‖(F i).restrict K‖) : Summable F := by - classical refine (ContinuousMap.exists_tendsto_compactOpen_iff_forall _).2 fun K hK => ?_ lift K to Compacts X using hK have A : ∀ s : Finset ι, restrict K (∑ i ∈ s, F i) = ∑ i ∈ s, restrict K (F i) := by diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index e7e91d08c1cfee..17dd0b09ab8e58 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -283,7 +283,6 @@ theorem isIrreducible_iff_sInter : IsIrreducible s ↔ ∀ (U : Finset (Set X)), (∀ u ∈ U, IsOpen u) → (∀ u ∈ U, (s ∩ u).Nonempty) → (s ∩ ⋂₀ ↑U).Nonempty := by - classical refine ⟨fun h U hu hU => ?_, fun h => ⟨?_, ?_⟩⟩ · induction U using Finset.induction_on with | empty => simpa using h.nonempty @@ -386,7 +385,6 @@ theorem IsPreirreducible.subset_irreducible {S U : Set X} (ht : IsPreirreducible replace ht : IsIrreducible t := ⟨⟨z, h₂ (h₁ hz)⟩, ht⟩ refine ⟨⟨z, h₁ hz⟩, ?_⟩ rintro u v hu hv ⟨x, hx, hx'⟩ ⟨y, hy, hy'⟩ - classical obtain ⟨x, -, hx'⟩ : Set.Nonempty (t ∩ ⋂₀ ↑({U, u, v} : Finset (Set X))) := by refine isIrreducible_iff_sInter.mp ht {U, u, v} ?_ ?_ · simp [*] diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 69e86e21c6d843..0d8819f14dca29 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -169,7 +169,6 @@ Simplifier lemma: `single x y` takes the value `y` at `x` and is zero otherwise. -/ @[simp] lemma single_apply [DecidableEq X] [Zero Y] {x₁ x₂ : X} {y : Y} : single x₁ y x₂ = if x₂ = x₁ then y else 0 := by - classical simp_rw [DFunLike.coe, single, Pi.single_apply] /-- diff --git a/Mathlib/Topology/MetricSpace/CoveringNumbers.lean b/Mathlib/Topology/MetricSpace/CoveringNumbers.lean index 2aac260334ff10..cab95f248e8316 100644 --- a/Mathlib/Topology/MetricSpace/CoveringNumbers.lean +++ b/Mathlib/Topology/MetricSpace/CoveringNumbers.lean @@ -384,7 +384,6 @@ See `Isometry.coveringNumber_image` for the version in an `EMetricSpace`, in whi a consequence of being an isometry. -/ lemma _root_.Isometry.coveringNumber_image' {f : X → Y} (hf : Isometry f) (hf_inj : Set.InjOn f A) : coveringNumber ε (f '' A) = coveringNumber ε A := by - classical refine le_antisymm ?_ ?_ · simp only [coveringNumber, le_iInf_iff] intro C hC_subset hC_cover diff --git a/Mathlib/Topology/MetricSpace/Infsep.lean b/Mathlib/Topology/MetricSpace/Infsep.lean index 1432be6a0ca356..5fb97b045864a6 100644 --- a/Mathlib/Topology/MetricSpace/Infsep.lean +++ b/Mathlib/Topology/MetricSpace/Infsep.lean @@ -154,16 +154,15 @@ theorem Finite.einfsep (hs : s.Finite) : s.einfsep = hs.offDiag.toFinset.inf (un theorem Finset.coe_einfsep {s : Finset α} : (s : Set α).einfsep = s.offDiag.inf (uncurry edist) := by - classical simp_rw [einfsep_of_fintype, ← Finset.coe_offDiag, Finset.toFinset_coe] + simp_rw [einfsep_of_fintype, ← Finset.coe_offDiag, Finset.toFinset_coe] theorem Nontrivial.einfsep_exists_of_finite [Finite s] (hs : s.Nontrivial) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ s.einfsep = edist x y := by - classical - cases nonempty_fintype s - simp_rw [einfsep_of_fintype] - rcases Finset.exists_mem_eq_inf s.offDiag.toFinset (by simpa) (uncurry edist) with ⟨w, hxy, hed⟩ - simp_rw [mem_toFinset] at hxy - exact ⟨w.fst, hxy.1, w.snd, hxy.2.1, hxy.2.2, hed⟩ + cases nonempty_fintype s + simp_rw [einfsep_of_fintype] + rcases Finset.exists_mem_eq_inf s.offDiag.toFinset (by simpa) (uncurry edist) with ⟨w, hxy, hed⟩ + simp_rw [mem_toFinset] at hxy + exact ⟨w.fst, hxy.1, w.snd, hxy.2.1, hxy.2.2, hed⟩ theorem Finite.einfsep_exists_of_nontrivial (hsf : s.Finite) (hs : s.Nontrivial) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ s.einfsep = edist x y := @@ -432,13 +431,12 @@ theorem _root_.Finset.coe_infsep_of_offDiag_empty theorem Nontrivial.infsep_exists_of_finite [Finite s] (hs : s.Nontrivial) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ s.infsep = dist x y := by - classical - cases nonempty_fintype s - simp_rw [hs.infsep_of_fintype] - rcases Finset.exists_mem_eq_inf' (s := s.offDiag.toFinset) (by simpa) (uncurry dist) with - ⟨w, hxy, hed⟩ - simp_rw [mem_toFinset] at hxy - exact ⟨w.fst, hxy.1, w.snd, hxy.2.1, hxy.2.2, hed⟩ + cases nonempty_fintype s + simp_rw [hs.infsep_of_fintype] + rcases Finset.exists_mem_eq_inf' (s := s.offDiag.toFinset) (by simpa) (uncurry dist) with + ⟨w, hxy, hed⟩ + simp_rw [mem_toFinset] at hxy + exact ⟨w.fst, hxy.1, w.snd, hxy.2.1, hxy.2.2, hed⟩ theorem Finite.infsep_exists_of_nontrivial (hsf : s.Finite) (hs : s.Nontrivial) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ s.infsep = dist x y := diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index 3627d695d61500..0204431e2fe0f3 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -846,7 +846,6 @@ protected def pseudoEMetricSpace : PseudoEMetricSpace (∀ i, F i) where PseudoEMetricSpace.uniformity_edist, le_antisymm_iff, le_iInf_iff, le_principal_iff] constructor · intro ε hε - classical obtain ⟨K, hK⟩ : ∃ K : Finset ι, ∑' i : {j // j ∉ K}, 2⁻¹ ^ encode (i : ι) < ε / 2 := ((tendsto_order.1 <| ENNReal.tendsto_tsum_compl_atTop_zero (tsum_geometric_encode_lt_top ENNReal.one_half_lt_one).ne).2 _ diff --git a/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean b/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean index 351db260af4098..2dd670b93d1774 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean @@ -237,17 +237,16 @@ theorem eq_of_locally_eq' (V : Opens X) (iUV : ∀ i : ι, U i ⟶ V) (hcover : theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : U₂ ⟶ V) (hcover : V ≤ U₁ ⊔ U₂) (s t : ToType (F.1.obj (op V))) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t) (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by - classical - fapply F.eq_of_locally_eq' fun t : Bool => if t then U₁ else U₂ - · exact fun i => if h : i then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂ - · refine le_trans hcover ?_ - rw [sup_le_iff] - constructor - · exact le_iSup (fun t : Bool => if t then U₁ else U₂) true - · exact le_iSup (fun t : Bool => if t then U₁ else U₂) false - · rintro ⟨_ | _⟩ - any_goals exact h₁ - any_goals exact h₂ + fapply F.eq_of_locally_eq' fun t : Bool => if t then U₁ else U₂ + · exact fun i => if h : i then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂ + · refine le_trans hcover ?_ + rw [sup_le_iff] + constructor + · exact le_iSup (fun t : Bool => if t then U₁ else U₂) true + · exact le_iSup (fun t : Bool => if t then U₁ else U₂) false + · rintro ⟨_ | _⟩ + any_goals exact h₁ + any_goals exact h₂ variable {F} {U} in theorem eq_app_of_locally_eq {V : Opens X} {G : Sheaf C X} {f : F ⟶ G} From 50b6a3e8856f7b91078153a43f1657cbfbd63c9f Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 15 Jul 2026 12:13:22 +0000 Subject: [PATCH 0799/1300] feat: use `to_dual` for `HeytingAlgebra` (#33543) This PR adds `to_dual` for `HeytingAlgebra`, `BiheytingAlgebra`, `GeneralizedHeytingAlgebra`. There is a bit of friction around dualizing `compl` to `hnot`, because this means that theorems about `compl` in boolean algebras will not be able to be translated nicely with `to_dual`. This should not be that many theorems, so this is acceptable. See also https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Dualize.20sdiff.20and.20himp/with/599261487 Since we have `GeneralizedCoheytingAlgebra.toDistribLattice`, I removed `CoheytingAlgebra.toDistribLattice`. Aligning the `Heyting` and `Coheyting` API is kind of awkward, because they are unfortunately quite different. One reason is that the arguments of `sup`/`inf` are often swapped in the dual version, which is not compatible with `to_dual`. I've worked around this with extensive use of `to_dual none`. There are quite some lemmas that in my eyes seem unnecessary, such as `le_sup_sdiff_sup_sdiff`, but I haven't removed any in this PR. --- Mathlib/Combinatorics/SetFamily/Kleitman.lean | 2 +- Mathlib/Data/Finset/Lattice/Fold.lean | 6 +- Mathlib/Order/Basic.lean | 12 +- Mathlib/Order/BooleanAlgebra/Basic.lean | 2 +- Mathlib/Order/Disjoint.lean | 1 + Mathlib/Order/GaloisConnection/Basic.lean | 1 - Mathlib/Order/Heyting/Basic.lean | 559 ++++++------------ Mathlib/Order/Notation.lean | 9 +- 8 files changed, 202 insertions(+), 390 deletions(-) diff --git a/Mathlib/Combinatorics/SetFamily/Kleitman.lean b/Mathlib/Combinatorics/SetFamily/Kleitman.lean index e87c0e246bf82d..f5b06e6a78b12a 100644 --- a/Mathlib/Combinatorics/SetFamily/Kleitman.lean +++ b/Mathlib/Combinatorics/SetFamily/Kleitman.lean @@ -64,7 +64,7 @@ theorem Finset.card_biUnion_le_of_intersecting (s : Finset ι) (f : ι → Finse refine (card_le_card <| biUnion_mono fun j hj ↦ (hf₁ _ hj).1).trans ?_ nth_rw 1 [cons_eq_insert i] rw [biUnion_insert] - refine (card_mono <| @le_sup_sdiff _ _ _ <| f' i).trans ((card_union_le _ _).trans ?_) + refine (card_mono <| @le_sup_sdiff _ _ (f' i) _).trans ((card_union_le _ _).trans ?_) rw [union_sdiff_left, sdiff_eq_inter_compl] refine le_of_mul_le_mul_left ?_ (pow_pos (zero_lt_two' ℕ) <| Fintype.card α + 1) rw [pow_succ, mul_add, mul_assoc, mul_comm _ 2, mul_assoc] diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index d16bab002decea..399d42aaf91c1b 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -407,10 +407,14 @@ theorem sup_himp_left (hs : s.Nonempty) (f : ι → α) (a : α) : (s.sup fun b => a ⇨ f b) = a ⇨ s.sup f := @inf_sdiff_right αᵒᵈ _ _ _ hs _ _ -@[to_dual (attr := simp)] +@[simp] protected theorem compl_sup (s : Finset ι) (f : ι → α) : (s.sup f)ᶜ = s.inf fun i => (f i)ᶜ := map_finset_sup (OrderIso.compl α) _ _ +@[simp] +protected theorem compl_inf (s : Finset ι) (f : ι → α) : (s.inf f)ᶜ = s.sup fun i => (f i)ᶜ := + map_finset_inf (OrderIso.compl α) _ _ + end BooleanAlgebra section LinearOrder diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index cff09b9564d8aa..250c217378841a 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -522,15 +522,16 @@ lemma LinearOrder.ext_lt {A B : LinearOrder α} (H : ∀ x y : α, (haveI := A; instance Prop.instCompl : Compl Prop := ⟨Not⟩ +@[to_dual instHNot] instance Pi.instCompl [∀ i, Compl (π i)] : Compl (∀ i, π i) := ⟨fun x i ↦ (x i)ᶜ⟩ -@[push ←] +@[to_dual (attr := push ←) hnot_def] theorem Pi.compl_def [∀ i, Compl (π i)] (x : ∀ i, π i) : xᶜ = fun i ↦ (x i)ᶜ := rfl -@[simp] +@[to_dual (attr := simp) hnot_apply] theorem Pi.compl_apply [∀ i, Compl (π i)] (x : ∀ i, π i) (i : ι) : xᶜ i = (x i)ᶜ := rfl @@ -647,15 +648,16 @@ theorem lt_update_self_iff : x < update x i a ↔ x i < a := by simp [lt_iff_le_ end Function -instance Pi.sdiff [∀ i, SDiff (π i)] : SDiff (∀ i, π i) := +@[to_dual instHImp] +instance Pi.instSDiff [∀ i, SDiff (π i)] : SDiff (∀ i, π i) := ⟨fun x y i ↦ x i \ y i⟩ -@[push ←] +@[to_dual (attr := push ←) himp_def] theorem Pi.sdiff_def [∀ i, SDiff (π i)] (x y : ∀ i, π i) : x \ y = fun i ↦ x i \ y i := rfl -@[simp] +@[to_dual (attr := simp) himp_apply] theorem Pi.sdiff_apply [∀ i, SDiff (π i)] (x y : ∀ i, π i) (i : ι) : (x \ y) i = x i \ y i := rfl diff --git a/Mathlib/Order/BooleanAlgebra/Basic.lean b/Mathlib/Order/BooleanAlgebra/Basic.lean index 4327fc2f0b9a95..8e12472df5b41b 100644 --- a/Mathlib/Order/BooleanAlgebra/Basic.lean +++ b/Mathlib/Order/BooleanAlgebra/Basic.lean @@ -352,7 +352,7 @@ lemma inf_sdiff_left_comm (a b c : α) : a ⊓ (b \ c) = b ⊓ (a \ c) := by simp_rw [← inf_sdiff_assoc, inf_comm] theorem inf_sdiff_distrib_left (a b c : α) : a ⊓ b \ c = (a ⊓ b) \ (a ⊓ c) := by - rw [sdiff_inf, sdiff_eq_bot_iff.2 inf_le_left, bot_sup_eq, inf_sdiff_assoc] + rw [sdiff_inf, (sdiff_eq_bot_iff (α := α)).2 inf_le_left, bot_sup_eq, inf_sdiff_assoc] theorem inf_sdiff_distrib_right (a b c : α) : a \ b ⊓ c = (a ⊓ c) \ (b ⊓ c) := by simp_rw [inf_comm _ c, inf_sdiff_distrib_left] diff --git a/Mathlib/Order/Disjoint.lean b/Mathlib/Order/Disjoint.lean index f2d81c18457c6a..7d5339050bb81a 100644 --- a/Mathlib/Order/Disjoint.lean +++ b/Mathlib/Order/Disjoint.lean @@ -307,6 +307,7 @@ section DistribLattice variable [DistribLattice α] [BoundedOrder α] {a b c : α} +@[to_dual] theorem Disjoint.le_of_codisjoint (hab : Disjoint a b) (hbc : Codisjoint b c) : a ≤ c := by rw [← @inf_top_eq _ _ _ a, ← @bot_sup_eq _ _ _ c, ← hab.eq_bot, ← hbc.eq_top, sup_inf_right] exact inf_le_inf_right _ le_sup_left diff --git a/Mathlib/Order/GaloisConnection/Basic.lean b/Mathlib/Order/GaloisConnection/Basic.lean index d02d327044277d..a626179797da76 100644 --- a/Mathlib/Order/GaloisConnection/Basic.lean +++ b/Mathlib/Order/GaloisConnection/Basic.lean @@ -119,7 +119,6 @@ end CompleteLattice -- Constructing Galois connections section Constructions -@[to_dual self] protected theorem compl [BooleanAlgebra α] [BooleanAlgebra β] {l : α → β} {u : β → α} (gc : GaloisConnection l u) : GaloisConnection (compl ∘ u ∘ compl) (compl ∘ l ∘ compl) := fun a b ↦ by diff --git a/Mathlib/Order/Heyting/Basic.lean b/Mathlib/Order/Heyting/Basic.lean index dcacfa7ccb0a1e..37ded42dddf058 100644 --- a/Mathlib/Order/Heyting/Basic.lean +++ b/Mathlib/Order/Heyting/Basic.lean @@ -34,6 +34,13 @@ Heyting algebras are the order-theoretic equivalent of Cartesian closed categori * `CoheytingAlgebra`: Co-Heyting algebra. * `BiheytingAlgebra`: Bi-Heyting algebra. +## Implementation notes + +Aligning the `Heyting` and `Coheyting` API with `to_dual` is kind of awkward, because they are +unfortunately quite different. One reason is that the arguments of sup/inf are often swapped +in the dual version, which is not compatible with `to_dual`. We work around this with extensive +use of `to_dual none`. + ## References * [Francis Borceux, *Handbook of Categorical Algebra III*][borceux-vol3] @@ -49,89 +56,39 @@ assert_not_exists RelIso open Function OrderDual +to_dual_name_hint Compl HNot +to_dual_name_hint SDiff HImp + universe u variable {ι α β : Type*} /-! ### Notation -/ -section -variable (α β) - +@[to_dual] instance Prod.instHImp [HImp α] [HImp β] : HImp (α × β) := ⟨fun a b => (a.1 ⇨ b.1, a.2 ⇨ b.2)⟩ +@[to_dual] instance Prod.instHNot [HNot α] [HNot β] : HNot (α × β) := ⟨fun a => (¬a.1, ¬a.2)⟩ -instance Prod.instSDiff [SDiff α] [SDiff β] : SDiff (α × β) := - ⟨fun a b => (a.1 \ b.1, a.2 \ b.2)⟩ - -instance Prod.instCompl [Compl α] [Compl β] : Compl (α × β) := - ⟨fun a => (a.1ᶜ, a.2ᶜ)⟩ - -end - -@[simp] +@[to_dual (attr := simp)] theorem fst_himp [HImp α] [HImp β] (a b : α × β) : (a ⇨ b).1 = a.1 ⇨ b.1 := rfl -@[simp] +@[to_dual (attr := simp)] theorem snd_himp [HImp α] [HImp β] (a b : α × β) : (a ⇨ b).2 = a.2 ⇨ b.2 := rfl -@[simp] +@[to_dual (attr := simp)] theorem fst_hnot [HNot α] [HNot β] (a : α × β) : (¬a).1 = ¬a.1 := rfl -@[simp] +@[to_dual (attr := simp)] theorem snd_hnot [HNot α] [HNot β] (a : α × β) : (¬a).2 = ¬a.2 := rfl -@[simp] -theorem fst_sdiff [SDiff α] [SDiff β] (a b : α × β) : (a \ b).1 = a.1 \ b.1 := - rfl - -@[simp] -theorem snd_sdiff [SDiff α] [SDiff β] (a b : α × β) : (a \ b).2 = a.2 \ b.2 := - rfl - -@[simp] -theorem fst_compl [Compl α] [Compl β] (a : α × β) : aᶜ.1 = a.1ᶜ := - rfl - -@[simp] -theorem snd_compl [Compl α] [Compl β] (a : α × β) : aᶜ.2 = a.2ᶜ := - rfl - -namespace Pi - -variable {π : ι → Type*} - -instance [∀ i, HImp (π i)] : HImp (∀ i, π i) := - ⟨fun a b i => a i ⇨ b i⟩ - -instance [∀ i, HNot (π i)] : HNot (∀ i, π i) := - ⟨fun a i => ¬a i⟩ - -@[push ←] -theorem himp_def [∀ i, HImp (π i)] (a b : ∀ i, π i) : a ⇨ b = fun i => a i ⇨ b i := - rfl - -@[push ←] -theorem hnot_def [∀ i, HNot (π i)] (a : ∀ i, π i) : ¬a = fun i => ¬a i := - rfl - -@[simp] -theorem himp_apply [∀ i, HImp (π i)] (a b : ∀ i, π i) (i : ι) : (a ⇨ b) i = a i ⇨ b i := - rfl - -@[simp] -theorem hnot_apply [∀ i, HNot (π i)] (a : ∀ i, π i) (i : ι) : (¬a) i = ¬a i := - rfl - -end Pi - /-- A generalized Heyting algebra is a lattice with an additional binary operation `⇨` called Heyting implication such that `(a ⇨ ·)` is right adjoint to `(a ⊓ ·)`. @@ -165,11 +122,9 @@ class CoheytingAlgebra (α : Type*) extends GeneralizedCoheytingAlgebra α, Orde top_sdiff (a : α) : ⊤ \ a = ¬a /-- A bi-Heyting algebra is a Heyting algebra that is also a co-Heyting algebra. -/ -class BiheytingAlgebra (α : Type*) extends HeytingAlgebra α, SDiff α, HNot α where - /-- `(· \ a)` is left adjoint to `(· ⊔ a)` -/ - sdiff_le_iff (a b c : α) : a \ b ≤ c ↔ a ≤ b ⊔ c - /-- `⊤ \ a` is `¬a` -/ - top_sdiff (a : α) : ⊤ \ a = ¬a +class BiheytingAlgebra (α : Type*) extends HeytingAlgebra α, CoheytingAlgebra α where + +attribute [to_dual existing] BiheytingAlgebra.toHeytingAlgebra -- See note [lower instance priority] attribute [instance 100] GeneralizedHeytingAlgebra.toOrderTop @@ -177,14 +132,7 @@ attribute [instance 100] GeneralizedCoheytingAlgebra.toOrderBot -- See note [lower instance priority] @[to_dual] -instance (priority := 100) HeytingAlgebra.toBoundedOrder [HeytingAlgebra α] : BoundedOrder α := - { bot_le := ‹HeytingAlgebra α›.bot_le } - --- See note [lower instance priority] -@[to_dual existing] -instance (priority := 100) BiheytingAlgebra.toCoheytingAlgebra [BiheytingAlgebra α] : - CoheytingAlgebra α := - { ‹BiheytingAlgebra α› with } +instance (priority := 100) HeytingAlgebra.toBoundedOrder [HeytingAlgebra α] : BoundedOrder α where -- See note [reducible non-instances] /-- Construct a Heyting algebra from the lattice structure and Heyting implication alone. -/ @@ -232,136 +180,171 @@ the same in this logic. See also `Prop.heytingAlgebra`. -/ section GeneralizedHeytingAlgebra +@[simp low] -- low priority so that it doesn't overwrite user-provided simp lemmas +theorem sdiff_le_iff [GeneralizedCoheytingAlgebra α] {a b c : α} : a \ b ≤ c ↔ a ≤ b ⊔ c := + GeneralizedCoheytingAlgebra.sdiff_le_iff _ _ _ + +theorem sdiff_le_iff' [GeneralizedCoheytingAlgebra α] {a b c : α} : a \ b ≤ c ↔ a ≤ c ⊔ b := by + rw [sdiff_le_iff, sup_comm] + variable [GeneralizedHeytingAlgebra α] {a b c d : α} /-- `p → q → r ↔ p ∧ q → r` -/ -@[simp] +@[to_dual existing sdiff_le_iff', simp] theorem le_himp_iff : a ≤ b ⇨ c ↔ a ⊓ b ≤ c := GeneralizedHeytingAlgebra.le_himp_iff _ _ _ /-- `p → q → r ↔ q ∧ p → r` -/ +@[to_dual existing sdiff_le_iff] theorem le_himp_iff' : a ≤ b ⇨ c ↔ b ⊓ a ≤ c := by rw [le_himp_iff, inf_comm] /-- `p → q → r ↔ q → p → r` -/ +@[to_dual sdiff_le_comm] theorem le_himp_comm : a ≤ b ⇨ c ↔ b ≤ a ⇨ c := by rw [le_himp_iff, le_himp_iff'] /-- `p → q → p` -/ +@[to_dual sdiff_le] theorem le_himp : a ≤ b ⇨ a := le_himp_iff.2 inf_le_left /-- `p → p → q ↔ p → q` -/ +@[to_dual sdiff_le_iff_left] theorem le_himp_iff_left : a ≤ a ⇨ b ↔ a ≤ b := by rw [le_himp_iff, inf_idem] /-- `p → p` -/ -@[simp] +@[to_dual (attr := simp)] theorem himp_self : a ⇨ a = ⊤ := top_le_iff.1 <| le_himp_iff.2 inf_le_right /-- `(p → q) ∧ p → q` -/ +@[to_dual le_sdiff_sup] theorem himp_inf_le : (a ⇨ b) ⊓ a ≤ b := le_himp_iff.1 le_rfl /-- `p ∧ (p → q) → q` -/ +@[to_dual le_sup_sdiff] theorem inf_himp_le : a ⊓ (a ⇨ b) ≤ b := by rw [inf_comm, ← le_himp_iff] /-- `p ∧ (p → q) ↔ p ∧ q` -/ -@[simp] +@[to_dual (attr := simp) sup_sdiff_self] +-- TODO: Should this be renamed to `inf_himp_self`? theorem inf_himp (a b : α) : a ⊓ (a ⇨ b) = a ⊓ b := le_antisymm (le_inf inf_le_left <| by rw [inf_comm, ← le_himp_iff]) <| inf_le_inf_left _ le_himp /-- `(p → q) ∧ p ↔ q ∧ p` -/ -@[simp] +@[to_dual (attr := simp)] theorem himp_inf_self (a b : α) : (a ⇨ b) ⊓ a = b ⊓ a := by rw [inf_comm, inf_himp, inf_comm] /-- The **deduction theorem** in the Heyting algebra model of intuitionistic logic: an implication holds iff the conclusion follows from the hypothesis. -/ -@[simp] +@[to_dual (attr := simp)] theorem himp_eq_top_iff : a ⇨ b = ⊤ ↔ a ≤ b := by rw [← top_le_iff, le_himp_iff, top_inf_eq] -/-- `p → true`, `true → p ↔ p` -/ -@[simp] +/-- `p → true` -/ +@[to_dual (attr := simp) bot_sdiff] theorem himp_top : a ⇨ ⊤ = ⊤ := himp_eq_top_iff.2 le_top -@[simp] +/-- `true → p ↔ p` -/ +@[to_dual (attr := simp) sdiff_bot] theorem top_himp : ⊤ ⇨ a = a := eq_of_forall_le_iff fun b => by rw [le_himp_iff, inf_top_eq] /-- `p → q → r ↔ p ∧ q → r` -/ +@[to_dual none] theorem himp_himp (a b c : α) : a ⇨ b ⇨ c = a ⊓ b ⇨ c := eq_of_forall_le_iff fun d => by simp_rw [le_himp_iff, inf_assoc] /-- `(q → r) → (p → q) → q → r` -/ +@[to_dual none] theorem himp_le_himp_himp_himp : b ⇨ c ≤ (a ⇨ b) ⇨ a ⇨ c := by rw [le_himp_iff, le_himp_iff, inf_assoc, himp_inf_self, ← inf_assoc, himp_inf_self, inf_assoc] exact inf_le_left -@[simp] +@[simp, to_dual none] theorem himp_inf_himp_inf_le : (b ⇨ c) ⊓ (a ⇨ b) ⊓ a ≤ c := by simpa using @himp_le_himp_himp_himp /-- `p → q → r ↔ q → p → r` -/ +@[to_dual (reorder := a c) sdiff_right_comm] theorem himp_left_comm (a b c : α) : a ⇨ b ⇨ c = b ⇨ a ⇨ c := by simp_rw [himp_himp, inf_comm] -@[simp] +@[to_dual (attr := simp)] theorem himp_idem : b ⇨ b ⇨ a = b ⇨ a := by rw [himp_himp, inf_idem] +@[to_dual (reorder := a c b) sup_sdiff_distrib] theorem himp_inf_distrib (a b c : α) : a ⇨ b ⊓ c = (a ⇨ b) ⊓ (a ⇨ c) := eq_of_forall_le_iff fun d => by simp_rw [le_himp_iff, le_inf_iff, le_himp_iff] +@[to_dual (reorder := a c b) sdiff_inf_distrib] theorem sup_himp_distrib (a b c : α) : a ⊔ b ⇨ c = (a ⇨ c) ⊓ (b ⇨ c) := eq_of_forall_le_iff fun d => by rw [le_inf_iff, le_himp_comm, sup_le_iff] simp_rw [le_himp_comm] +@[to_dual sdiff_le_sdiff_right] theorem himp_le_himp_left (h : a ≤ b) : c ⇨ a ≤ c ⇨ b := le_himp_iff.2 <| himp_inf_le.trans h +@[to_dual sdiff_le_sdiff_left] theorem himp_le_himp_right (h : a ≤ b) : b ⇨ c ≤ a ⇨ c := le_himp_iff.2 <| (inf_le_inf_left _ h).trans himp_inf_le -@[gcongr] +@[to_dual (reorder := hab hcd) (attr := gcongr)] theorem himp_le_himp (hab : a ≤ b) (hcd : c ≤ d) : b ⇨ c ≤ a ⇨ d := (himp_le_himp_right hab).trans <| himp_le_himp_left hcd -@[simp] +@[to_dual (attr := simp) sdiff_inf_self_left] theorem sup_himp_self_left (a b : α) : a ⊔ b ⇨ a = b ⇨ a := by rw [sup_himp_distrib, himp_self, top_inf_eq] -@[simp] +@[to_dual (attr := simp) sdiff_inf_self_right] theorem sup_himp_self_right (a b : α) : a ⊔ b ⇨ b = a ⇨ b := by rw [sup_himp_distrib, himp_self, inf_top_eq] +@[to_dual sdiff_eq_left] theorem Codisjoint.himp_eq_right (h : Codisjoint a b) : b ⇨ a = a := by conv_rhs => rw [← @top_himp _ _ a] rw [← h.eq_top, sup_himp_self_left] +@[to_dual sdiff_eq_right] theorem Codisjoint.himp_eq_left (h : Codisjoint a b) : a ⇨ b = b := h.symm.himp_eq_right -theorem Codisjoint.himp_inf_cancel_right (h : Codisjoint a b) : a ⇨ a ⊓ b = b := by +@[to_dual sup_sdiff_cancel_left] +theorem Codisjoint.himp_inf_cancel_left (h : Codisjoint a b) : a ⇨ a ⊓ b = b := by rw [himp_inf_distrib, himp_self, top_inf_eq, h.himp_eq_left] -theorem Codisjoint.himp_inf_cancel_left (h : Codisjoint a b) : b ⇨ a ⊓ b = a := by +@[to_dual sup_sdiff_cancel_right] +theorem Codisjoint.himp_inf_cancel_right (h : Codisjoint a b) : b ⇨ a ⊓ b = a := by rw [himp_inf_distrib, himp_self, inf_top_eq, h.himp_eq_right] /-- See `himp_le` for a stronger version in Boolean algebras. -/ +@[to_dual le_sdiff_of_le_left +/-- See `le_sdiff` for a stronger version in generalised Boolean algebras. -/] theorem Codisjoint.himp_le_of_right_le (hac : Codisjoint a c) (hba : b ≤ a) : c ⇨ b ≤ a := (himp_le_himp_left hba).trans_eq hac.himp_eq_right +@[to_dual sdiff_sdiff_le] theorem le_himp_himp : a ≤ (a ⇨ b) ⇨ b := le_himp_iff.2 inf_himp_le -@[simp] lemma himp_eq_himp_iff : b ⇨ a = a ⇨ b ↔ a = b := by simp [le_antisymm_iff] +@[to_dual (attr := simp)] +lemma himp_eq_himp_iff : b ⇨ a = a ⇨ b ↔ a = b := by simp [le_antisymm_iff] + +@[to_dual] lemma himp_ne_himp_iff : b ⇨ a ≠ a ⇨ b ↔ a ≠ b := himp_eq_himp_iff.not +@[to_dual none] theorem himp_triangle (a b c : α) : (a ⇨ b) ⊓ (b ⇨ c) ≤ a ⇨ c := by rw [le_himp_iff, inf_right_comm, ← le_himp_iff] exact himp_inf_le.trans le_himp_himp +@[to_dual none] theorem himp_inf_himp_cancel (hba : b ≤ a) (hcb : c ≤ b) : (a ⇨ b) ⊓ (b ⇨ c) = a ⇨ c := (himp_triangle _ _ _).antisymm <| le_inf (himp_le_himp_left hcb) (himp_le_himp_right hba) +@[to_dual gc_sdiff_sup] theorem gc_inf_himp : GaloisConnection (a ⊓ ·) (a ⇨ ·) := fun _ _ ↦ Iff.symm le_himp_iff' @@ -388,225 +371,157 @@ section GeneralizedCoheytingAlgebra variable [GeneralizedCoheytingAlgebra α] {a b c d : α} -@[simp low] -- low priority so that it doesn't overwrite user-provided simp lemmas -theorem sdiff_le_iff : a \ b ≤ c ↔ a ≤ b ⊔ c := - GeneralizedCoheytingAlgebra.sdiff_le_iff _ _ _ - -theorem sdiff_le_iff' : a \ b ≤ c ↔ a ≤ c ⊔ b := by rw [sdiff_le_iff, sup_comm] - -theorem sdiff_le_comm : a \ b ≤ c ↔ a \ c ≤ b := by rw [sdiff_le_iff, sdiff_le_iff'] - -theorem sdiff_le : a \ b ≤ a := - sdiff_le_iff.2 le_sup_right - +@[to_dual none] theorem Disjoint.disjoint_sdiff_left (h : Disjoint a b) : Disjoint (a \ c) b := h.mono_left sdiff_le +@[to_dual none] theorem Disjoint.disjoint_sdiff_right (h : Disjoint a b) : Disjoint a (b \ c) := h.mono_right sdiff_le -theorem sdiff_le_iff_left : a \ b ≤ b ↔ a ≤ b := by rw [sdiff_le_iff, sup_idem] - -@[simp] -theorem sdiff_self : a \ a = ⊥ := - le_bot_iff.1 <| sdiff_le_iff.2 le_sup_left - -theorem le_sup_sdiff : a ≤ b ⊔ a \ b := - sdiff_le_iff.1 le_rfl - -theorem le_sdiff_sup : a ≤ a \ b ⊔ b := by rw [sup_comm, ← sdiff_le_iff] - +@[to_dual none] theorem sup_sdiff_left : a ⊔ a \ b = a := sup_of_le_left sdiff_le +@[to_dual none] theorem sup_sdiff_right : a \ b ⊔ a = a := sup_of_le_right sdiff_le +@[to_dual none] theorem inf_sdiff_left : a \ b ⊓ a = a \ b := inf_of_le_left sdiff_le +@[to_dual none] theorem inf_sdiff_right : a ⊓ a \ b = a \ b := inf_of_le_right sdiff_le -@[simp] -theorem sup_sdiff_self (a b : α) : a ⊔ b \ a = a ⊔ b := - le_antisymm (sup_le_sup_left sdiff_le _) (sup_le le_sup_left le_sup_sdiff) - -@[simp] -theorem sdiff_sup_self (a b : α) : b \ a ⊔ a = b ⊔ a := by rw [sup_comm, sup_sdiff_self, sup_comm] - +@[to_dual none] alias sup_sdiff_self_left := sdiff_sup_self +@[to_dual none] alias sup_sdiff_self_right := sup_sdiff_self +@[to_dual none] theorem sup_sdiff_eq_sup (h : c ≤ a) : a ⊔ b \ c = a ⊔ b := sup_congr_left (sdiff_le.trans le_sup_right) <| le_sup_sdiff.trans <| sup_le_sup_right h _ -- cf. `Set.union_sdiff_cancel'` +@[to_dual none] theorem sup_sdiff_cancel' (hab : a ≤ b) (hbc : b ≤ c) : b ⊔ c \ a = c := by rw [sup_sdiff_eq_sup hab, sup_of_le_right hbc] +@[to_dual none] theorem sup_sdiff_cancel_right (h : a ≤ b) : a ⊔ b \ a = b := sup_sdiff_cancel' le_rfl h +@[to_dual none] theorem sdiff_sup_cancel (h : b ≤ a) : a \ b ⊔ b = a := by rw [sup_comm, sup_sdiff_cancel_right h] +@[to_dual none] theorem sdiff_left_inj (hac : c ≤ a) (hbc : c ≤ b) : a \ c = b \ c ↔ a = b := ⟨fun h => by rw [← sdiff_sup_cancel hac, h, sdiff_sup_cancel hbc], congrArg (· \ c)⟩ +@[to_dual none] theorem sup_le_of_le_sdiff_left (h : b ≤ c \ a) (hac : a ≤ c) : a ⊔ b ≤ c := sup_le hac <| h.trans sdiff_le +@[to_dual none] theorem sup_le_of_le_sdiff_right (h : a ≤ c \ b) (hbc : b ≤ c) : a ⊔ b ≤ c := sup_le (h.trans sdiff_le) hbc -@[simp] -theorem sdiff_eq_bot_iff : a \ b = ⊥ ↔ a ≤ b := by rw [← le_bot_iff, sdiff_le_iff, sup_bot_eq] - -@[simp] -theorem sdiff_bot : a \ ⊥ = a := - eq_of_forall_ge_iff fun b => by rw [sdiff_le_iff, bot_sup_eq] - -@[simp] -theorem bot_sdiff : ⊥ \ a = ⊥ := - sdiff_eq_bot_iff.2 bot_le - +@[to_dual none] theorem sdiff_sdiff_sdiff_le_sdiff : (a \ b) \ (a \ c) ≤ c \ b := by rw [sdiff_le_iff, sdiff_le_iff, sup_left_comm, sup_sdiff_self, sup_left_comm, sdiff_sup_self, sup_left_comm] exact le_sup_left -@[simp] +@[simp, to_dual none] theorem le_sup_sdiff_sup_sdiff : a ≤ b ⊔ (a \ c ⊔ c \ b) := by simpa using @sdiff_sdiff_sdiff_le_sdiff +@[to_dual none] theorem sdiff_sdiff (a b c : α) : (a \ b) \ c = a \ (b ⊔ c) := eq_of_forall_ge_iff fun d => by simp_rw [sdiff_le_iff, sup_assoc] +@[to_dual none] theorem sdiff_sdiff_left : (a \ b) \ c = a \ (b ⊔ c) := sdiff_sdiff _ _ _ -theorem sdiff_right_comm (a b c : α) : (a \ b) \ c = (a \ c) \ b := by - simp_rw [sdiff_sdiff, sup_comm] - +@[to_dual none] theorem sdiff_sdiff_comm : (a \ b) \ c = (a \ c) \ b := sdiff_right_comm _ _ _ -@[simp] -theorem sdiff_idem : (a \ b) \ b = a \ b := by rw [sdiff_sdiff_left, sup_idem] - -@[simp] +@[simp, to_dual none] theorem sdiff_sdiff_self : (a \ b) \ a = ⊥ := by rw [sdiff_sdiff_comm, sdiff_self, bot_sdiff] -theorem sup_sdiff_distrib (a b c : α) : (a ⊔ b) \ c = a \ c ⊔ b \ c := - eq_of_forall_ge_iff fun d => by simp_rw [sdiff_le_iff, sup_le_iff, sdiff_le_iff] - -theorem sdiff_inf_distrib (a b c : α) : a \ (b ⊓ c) = a \ b ⊔ a \ c := - eq_of_forall_ge_iff fun d => by - rw [sup_le_iff, sdiff_le_comm, le_inf_iff] - simp_rw [sdiff_le_comm] - +@[to_dual none] theorem sup_sdiff : (a ⊔ b) \ c = a \ c ⊔ b \ c := sup_sdiff_distrib _ _ _ -@[simp] +@[simp, to_dual none] theorem sup_sdiff_right_self : (a ⊔ b) \ b = a \ b := by rw [sup_sdiff, sdiff_self, sup_bot_eq] -@[simp] +@[simp, to_dual none] theorem sup_sdiff_left_self : (a ⊔ b) \ a = b \ a := by rw [sup_comm, sup_sdiff_right_self] -theorem sdiff_le_sdiff_right (h : a ≤ b) : a \ c ≤ b \ c := - sdiff_le_iff.2 <| h.trans <| le_sup_sdiff - -theorem sdiff_le_sdiff_left (h : a ≤ b) : c \ b ≤ c \ a := - sdiff_le_iff.2 <| le_sup_sdiff.trans <| sup_le_sup_right h _ - -@[gcongr] -theorem sdiff_le_sdiff (hab : a ≤ b) (hcd : c ≤ d) : a \ d ≤ b \ c := - (sdiff_le_sdiff_right hab).trans <| sdiff_le_sdiff_left hcd - -- cf. `IsCompl.inf_sup` +@[to_dual none] theorem sdiff_inf : a \ (b ⊓ c) = a \ b ⊔ a \ c := sdiff_inf_distrib _ _ _ -@[simp] -theorem sdiff_inf_self_left (a b : α) : a \ (a ⊓ b) = a \ b := by - rw [sdiff_inf, sdiff_self, bot_sup_eq] - -@[simp] -theorem sdiff_inf_self_right (a b : α) : b \ (a ⊓ b) = b \ a := by - rw [sdiff_inf, sdiff_self, sup_bot_eq] - -theorem Disjoint.sdiff_eq_left (h : Disjoint a b) : a \ b = a := by - conv_rhs => rw [← @sdiff_bot _ _ a] - rw [← h.eq_bot, sdiff_inf_self_left] - -theorem Disjoint.sdiff_eq_right (h : Disjoint a b) : b \ a = b := - h.symm.sdiff_eq_left - -theorem Disjoint.sup_sdiff_cancel_left (h : Disjoint a b) : (a ⊔ b) \ a = b := by - rw [sup_sdiff, sdiff_self, bot_sup_eq, h.sdiff_eq_right] - -theorem Disjoint.sup_sdiff_cancel_right (h : Disjoint a b) : (a ⊔ b) \ b = a := by - rw [sup_sdiff, sdiff_self, sup_bot_eq, h.sdiff_eq_left] - -/-- See `le_sdiff` for a stronger version in generalised Boolean algebras. -/ -theorem Disjoint.le_sdiff_of_le_left (hac : Disjoint a c) (hab : a ≤ b) : a ≤ b \ c := - hac.sdiff_eq_left.ge.trans <| sdiff_le_sdiff_right hab - -theorem sdiff_sdiff_le : a \ (a \ b) ≤ b := - sdiff_le_iff.2 le_sdiff_sup - -@[simp] lemma sdiff_eq_sdiff_iff : a \ b = b \ a ↔ a = b := by simp [le_antisymm_iff] -lemma sdiff_ne_sdiff_iff : a \ b ≠ b \ a ↔ a ≠ b := sdiff_eq_sdiff_iff.not - +@[to_dual none] theorem sdiff_triangle (a b c : α) : a \ c ≤ a \ b ⊔ b \ c := by rw [sdiff_le_iff, sup_left_comm, ← sdiff_le_iff] exact sdiff_sdiff_le.trans le_sup_sdiff +@[to_dual none] theorem sdiff_sup_sdiff_cancel (hba : b ≤ a) (hcb : c ≤ b) : a \ b ⊔ b \ c = a \ c := (sdiff_triangle _ _ _).antisymm' <| sup_le (sdiff_le_sdiff_left hcb) (sdiff_le_sdiff_right hba) /-- a version of `sdiff_sup_sdiff_cancel` with more general hypotheses. -/ +@[to_dual none] theorem sdiff_sup_sdiff_cancel' (hinf : a ⊓ c ≤ b) (hsup : b ≤ a ⊔ c) : a \ b ⊔ b \ c = a \ c := by refine (sdiff_triangle ..).antisymm' <| sup_le ?_ <| by simpa [sup_comm] rw [← sdiff_inf_self_left (b := c)] exact sdiff_le_sdiff_left hinf +@[to_dual none] theorem sdiff_le_sdiff_of_sup_le_sup_left (h : c ⊔ a ≤ c ⊔ b) : a \ c ≤ b \ c := by rw [← sup_sdiff_left_self, ← @sup_sdiff_left_self _ _ _ b] exact sdiff_le_sdiff_right h +@[to_dual none] theorem sdiff_le_sdiff_of_sup_le_sup_right (h : a ⊔ c ≤ b ⊔ c) : a \ c ≤ b \ c := by rw [← sup_sdiff_right_self, ← @sup_sdiff_right_self _ _ b] exact sdiff_le_sdiff_right h -@[simp] +@[simp, to_dual none] theorem inf_sdiff_sup_left : a \ c ⊓ (a ⊔ b) = a \ c := inf_of_le_left <| sdiff_le.trans le_sup_left -@[simp] +@[simp, to_dual none] theorem inf_sdiff_sup_right : a \ c ⊓ (b ⊔ a) = a \ c := inf_of_le_left <| sdiff_le.trans le_sup_right -theorem gc_sdiff_sup : GaloisConnection (· \ a) (a ⊔ ·) := - fun _ _ ↦ sdiff_le_iff - -- See note [lower instance priority] +@[to_dual existing] instance (priority := 100) GeneralizedCoheytingAlgebra.toDistribLattice : DistribLattice α := { ‹GeneralizedCoheytingAlgebra α› with le_sup_inf := fun a b c => by simp_rw [← sdiff_le_iff, le_inf_iff, sdiff_le_iff, ← le_inf_iff]; rfl } +@[to_dual existing] instance OrderDual.instGeneralizedHeytingAlgebra : GeneralizedHeytingAlgebra αᵒᵈ where himp := fun a b => toDual (ofDual b \ ofDual a) le_himp_iff := fun a b c => by rw [inf_comm]; exact sdiff_le_iff +@[to_dual existing] instance Prod.instGeneralizedCoheytingAlgebra [GeneralizedCoheytingAlgebra β] : GeneralizedCoheytingAlgebra (α × β) where sdiff_le_iff _ _ _ := and_congr sdiff_le_iff sdiff_le_iff +@[to_dual existing] instance Pi.instGeneralizedCoheytingAlgebra {α : ι → Type*} [∀ i, GeneralizedCoheytingAlgebra (α i)] : GeneralizedCoheytingAlgebra (∀ i, α i) where sdiff_le_iff i := by simp [le_def] @@ -617,141 +532,171 @@ section HeytingAlgebra variable [HeytingAlgebra α] {a b : α} -@[simp] +@[to_dual (attr := simp) top_sdiff'] theorem himp_bot (a : α) : a ⇨ ⊥ = aᶜ := HeytingAlgebra.himp_bot _ -@[simp] +@[to_dual (attr := simp) sdiff_top] theorem bot_himp (a : α) : ⊥ ⇨ a = ⊤ := himp_eq_top_iff.2 bot_le +@[to_dual] theorem compl_sup_distrib (a b : α) : (a ⊔ b)ᶜ = aᶜ ⊓ bᶜ := by simp_rw [← himp_bot, sup_himp_distrib] -@[simp] +@[to_dual (attr := simp)] theorem compl_sup : (a ⊔ b)ᶜ = aᶜ ⊓ bᶜ := compl_sup_distrib _ _ +@[to_dual sdiff_le_hnot] theorem compl_le_himp : aᶜ ≤ a ⇨ b := (himp_bot _).ge.trans <| himp_le_himp_left bot_le +@[to_dual none] theorem compl_sup_le_himp : aᶜ ⊔ b ≤ a ⇨ b := sup_le compl_le_himp le_himp +@[to_dual sdiff_le_inf_hnot] theorem sup_compl_le_himp : b ⊔ aᶜ ≤ a ⇨ b := sup_le le_himp compl_le_himp -- `p → ¬ p ↔ ¬ p` -@[simp] +@[to_dual (attr := simp) hnot_sdiff] theorem himp_compl (a : α) : a ⇨ aᶜ = aᶜ := by rw [← himp_bot, himp_himp, inf_idem] -- `p → ¬ q ↔ q → ¬ p` +@[to_dual (reorder := a b) hnot_sdiff_comm] theorem himp_compl_comm (a b : α) : a ⇨ bᶜ = b ⇨ aᶜ := by simp_rw [← himp_bot, himp_left_comm] +@[to_dual hnot_le_iff_codisjoint_left] theorem le_compl_iff_disjoint_right : a ≤ bᶜ ↔ Disjoint a b := by rw [← himp_bot, le_himp_iff, disjoint_iff_inf_le] +@[to_dual hnot_le_iff_codisjoint_right] theorem le_compl_iff_disjoint_left : a ≤ bᶜ ↔ Disjoint b a := le_compl_iff_disjoint_right.trans disjoint_comm +@[to_dual hnot_le_comm] theorem le_compl_comm : a ≤ bᶜ ↔ b ≤ aᶜ := by rw [le_compl_iff_disjoint_right, le_compl_iff_disjoint_left] +@[to_dual hnot_le_left] alias ⟨_, Disjoint.le_compl_right⟩ := le_compl_iff_disjoint_right +@[to_dual hnot_le_right] alias ⟨_, Disjoint.le_compl_left⟩ := le_compl_iff_disjoint_left +@[to_dual hnot_le_iff_hnot_le] alias le_compl_iff_le_compl := le_compl_comm +@[to_dual hnot_le_of_hnot_le] alias ⟨le_compl_of_le_compl, _⟩ := le_compl_comm +@[to_dual] theorem disjoint_compl_left : Disjoint aᶜ a := disjoint_iff_inf_le.mpr <| le_himp_iff.1 (himp_bot _).ge +@[to_dual] theorem disjoint_compl_right : Disjoint a aᶜ := disjoint_compl_left.symm +@[to_dual] theorem LE.le.disjoint_compl_left (h : b ≤ a) : Disjoint aᶜ b := _root_.disjoint_compl_left.mono_right h +@[to_dual] theorem LE.le.disjoint_compl_right (h : a ≤ b) : Disjoint a bᶜ := _root_.disjoint_compl_right.mono_left h +@[to_dual] theorem IsCompl.compl_eq (h : IsCompl a b) : aᶜ = b := h.1.le_compl_left.antisymm' <| Disjoint.le_of_codisjoint disjoint_compl_left h.2 +@[to_dual] theorem IsCompl.eq_compl (h : IsCompl a b) : a = bᶜ := h.1.le_compl_right.antisymm <| Disjoint.le_of_codisjoint disjoint_compl_left h.2.symm +@[to_dual none] theorem compl_unique (h₀ : a ⊓ b = ⊥) (h₁ : a ⊔ b = ⊤) : aᶜ = b := (IsCompl.of_eq h₀ h₁).compl_eq -@[simp] +@[to_dual (attr := simp)] theorem inf_compl_self (a : α) : a ⊓ aᶜ = ⊥ := disjoint_compl_right.eq_bot -@[simp] +@[to_dual (attr := simp)] theorem compl_inf_self (a : α) : aᶜ ⊓ a = ⊥ := disjoint_compl_left.eq_bot +@[to_dual] theorem inf_compl_eq_bot : a ⊓ aᶜ = ⊥ := inf_compl_self _ +@[to_dual] theorem compl_inf_eq_bot : aᶜ ⊓ a = ⊥ := compl_inf_self _ -@[simp] +@[to_dual (attr := simp)] theorem compl_top : (⊤ : α)ᶜ = ⊥ := eq_of_forall_le_iff fun a => by rw [le_compl_iff_disjoint_right, disjoint_top, le_bot_iff] -@[simp] +@[to_dual (attr := simp)] theorem compl_bot : (⊥ : α)ᶜ = ⊤ := by rw [← himp_bot, himp_self] -@[simp] theorem le_compl_self : a ≤ aᶜ ↔ a = ⊥ := by +@[to_dual (attr := simp)] +theorem le_compl_self : a ≤ aᶜ ↔ a = ⊥ := by rw [le_compl_iff_disjoint_left, disjoint_self] -@[simp] theorem ne_compl_self [Nontrivial α] : a ≠ aᶜ := by +@[to_dual (attr := simp)] +theorem ne_compl_self [Nontrivial α] : a ≠ aᶜ := by intro h cases le_compl_self.1 (le_of_eq h) simp at h -@[simp] theorem compl_ne_self [Nontrivial α] : aᶜ ≠ a := +@[to_dual (attr := simp)] +theorem compl_ne_self [Nontrivial α] : aᶜ ≠ a := ne_comm.1 ne_compl_self -@[simp] theorem lt_compl_self [Nontrivial α] : a < aᶜ ↔ a = ⊥ := by +@[to_dual (attr := simp)] +theorem lt_compl_self [Nontrivial α] : a < aᶜ ↔ a = ⊥ := by rw [lt_iff_le_and_ne]; simp +@[to_dual hnot_hnot_le] theorem le_compl_compl : a ≤ aᶜᶜ := disjoint_compl_right.le_compl_right +@[to_dual] theorem compl_anti : Antitone (compl : α → α) := fun _ _ h => le_compl_comm.1 <| h.trans le_compl_compl -@[gcongr] +@[to_dual (attr := gcongr)] theorem compl_le_compl (h : a ≤ b) : bᶜ ≤ aᶜ := compl_anti h -@[simp] +@[to_dual (attr := simp)] theorem compl_compl_compl (a : α) : aᶜᶜᶜ = aᶜ := (compl_anti le_compl_compl).antisymm le_compl_compl -@[simp] +@[to_dual (attr := simp)] theorem disjoint_compl_compl_left_iff : Disjoint aᶜᶜ b ↔ Disjoint a b := by simp_rw [← le_compl_iff_disjoint_left, compl_compl_compl] -@[simp] +@[to_dual (attr := simp)] theorem disjoint_compl_compl_right_iff : Disjoint a bᶜᶜ ↔ Disjoint a b := by simp_rw [← le_compl_iff_disjoint_right, compl_compl_compl] +@[to_dual le_hnot_inf_hnot] theorem compl_sup_compl_le : aᶜ ⊔ bᶜ ≤ (a ⊓ b)ᶜ := sup_le (compl_anti inf_le_left) <| compl_anti inf_le_right +@[to_dual] theorem compl_compl_inf_distrib (a b : α) : (a ⊓ b)ᶜᶜ = aᶜᶜ ⊓ bᶜᶜ := by refine ((compl_anti compl_sup_compl_le).trans (compl_sup_distrib _ _).le).antisymm ?_ rw [le_compl_iff_disjoint_right, disjoint_assoc, disjoint_compl_compl_left_iff, disjoint_left_comm, disjoint_compl_compl_left_iff, ← disjoint_assoc, inf_comm] exact disjoint_compl_right +@[to_dual] theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by apply le_antisymm · rw [le_himp_iff, ← compl_compl_inf_distrib] @@ -767,14 +712,28 @@ instance OrderDual.instCoheytingAlgebra : CoheytingAlgebra αᵒᵈ where sdiff_le_iff a b c := by rw [sup_comm]; exact le_himp_iff top_sdiff := @himp_bot α _ -@[simp] +@[to_dual existing] +instance OrderDual.instHeytingAlgebra {α : Type u_2} [CoheytingAlgebra α] : HeytingAlgebra αᵒᵈ where + compl := toDual ∘ hnot ∘ ofDual + himp a b := toDual (ofDual b \ ofDual a) + le_himp_iff a b c := by rw [inf_comm]; exact sdiff_le_iff + himp_bot := @top_sdiff' α _ + +@[to_dual (attr := simp)] theorem ofDual_hnot (a : αᵒᵈ) : ofDual (¬a) = (ofDual a)ᶜ := rfl -@[simp] +@[to_dual (attr := simp)] +theorem ofDual_sdiff (a b : αᵒᵈ) : ofDual (a \ b) = ofDual b ⇨ ofDual a := + rfl +@[to_dual (attr := simp)] theorem toDual_compl (a : α) : toDual aᶜ = ¬toDual a := rfl +@[to_dual (attr := simp)] +theorem toDual_himp (a b : α) : toDual (a ⇨ b) = toDual b \ toDual a := + rfl + instance Prod.instHeytingAlgebra [HeytingAlgebra β] : HeytingAlgebra (α × β) where himp_bot a := Prod.ext_iff.2 ⟨himp_bot a.1, himp_bot a.2⟩ @@ -788,145 +747,12 @@ section CoheytingAlgebra variable [CoheytingAlgebra α] {a b : α} -@[simp] -theorem top_sdiff' (a : α) : ⊤ \ a = ¬a := - CoheytingAlgebra.top_sdiff _ - -@[simp] -theorem sdiff_top (a : α) : a \ ⊤ = ⊥ := - sdiff_eq_bot_iff.2 le_top - -theorem hnot_inf_distrib (a b : α) : ¬(a ⊓ b) = ¬a ⊔ ¬b := by - simp_rw [← top_sdiff', sdiff_inf_distrib] - -theorem sdiff_le_hnot : a \ b ≤ ¬b := - (sdiff_le_sdiff_right le_top).trans_eq <| top_sdiff' _ - -theorem sdiff_le_inf_hnot : a \ b ≤ a ⊓ ¬b := - le_inf sdiff_le sdiff_le_hnot - --- See note [lower instance priority] -instance (priority := 100) CoheytingAlgebra.toDistribLattice : DistribLattice α := - { ‹CoheytingAlgebra α› with - le_sup_inf := - fun a b c => by simp_rw [← sdiff_le_iff, le_inf_iff, sdiff_le_iff, ← le_inf_iff]; rfl } - -@[simp] -theorem hnot_sdiff (a : α) : ¬a \ a = ¬a := by rw [← top_sdiff', sdiff_sdiff, sup_idem] - -theorem hnot_sdiff_comm (a b : α) : ¬a \ b = ¬b \ a := by simp_rw [← top_sdiff', sdiff_right_comm] - -theorem hnot_le_iff_codisjoint_right : ¬a ≤ b ↔ Codisjoint a b := by - rw [← top_sdiff', sdiff_le_iff, codisjoint_iff_le_sup] - -theorem hnot_le_iff_codisjoint_left : ¬a ≤ b ↔ Codisjoint b a := - hnot_le_iff_codisjoint_right.trans codisjoint_comm - -theorem hnot_le_comm : ¬a ≤ b ↔ ¬b ≤ a := by - rw [hnot_le_iff_codisjoint_right, hnot_le_iff_codisjoint_left] - -alias ⟨_, Codisjoint.hnot_le_right⟩ := hnot_le_iff_codisjoint_right - -alias ⟨_, Codisjoint.hnot_le_left⟩ := hnot_le_iff_codisjoint_left - -theorem codisjoint_hnot_right : Codisjoint a (¬a) := - codisjoint_iff_le_sup.2 <| sdiff_le_iff.1 (top_sdiff' _).le - -theorem codisjoint_hnot_left : Codisjoint (¬a) a := - codisjoint_hnot_right.symm - -theorem LE.le.codisjoint_hnot_left (h : a ≤ b) : Codisjoint (¬a) b := - _root_.codisjoint_hnot_left.mono_right h - -theorem LE.le.codisjoint_hnot_right (h : b ≤ a) : Codisjoint a (¬b) := - _root_.codisjoint_hnot_right.mono_left h - -theorem IsCompl.hnot_eq (h : IsCompl a b) : ¬a = b := - h.2.hnot_le_right.antisymm <| Disjoint.le_of_codisjoint h.1.symm codisjoint_hnot_right - -theorem IsCompl.eq_hnot (h : IsCompl a b) : a = ¬b := - h.2.hnot_le_left.antisymm' <| Disjoint.le_of_codisjoint h.1 codisjoint_hnot_right - -@[simp] -theorem sup_hnot_self (a : α) : a ⊔ ¬a = ⊤ := - Codisjoint.eq_top codisjoint_hnot_right - -@[simp] -theorem hnot_sup_self (a : α) : ¬a ⊔ a = ⊤ := - Codisjoint.eq_top codisjoint_hnot_left - -@[simp] -theorem hnot_bot : ¬(⊥ : α) = ⊤ := - eq_of_forall_ge_iff fun a => by rw [hnot_le_iff_codisjoint_left, codisjoint_bot, top_le_iff] - -@[simp] -theorem hnot_top : ¬(⊤ : α) = ⊥ := by rw [← top_sdiff', sdiff_self] - -theorem hnot_hnot_le : ¬¬a ≤ a := - codisjoint_hnot_right.hnot_le_left - -theorem hnot_anti : Antitone (hnot : α → α) := fun _ _ h => hnot_le_comm.1 <| hnot_hnot_le.trans h - -@[gcongr] -theorem hnot_le_hnot (h : a ≤ b) : ¬b ≤ ¬a := - hnot_anti h - -@[simp] -theorem hnot_hnot_hnot (a : α) : ¬¬¬a = ¬a := - hnot_hnot_le.antisymm <| hnot_anti hnot_hnot_le - -@[simp] -theorem codisjoint_hnot_hnot_left_iff : Codisjoint (¬¬a) b ↔ Codisjoint a b := by - simp_rw [← hnot_le_iff_codisjoint_right, hnot_hnot_hnot] - -@[simp] -theorem codisjoint_hnot_hnot_right_iff : Codisjoint a (¬¬b) ↔ Codisjoint a b := by - simp_rw [← hnot_le_iff_codisjoint_left, hnot_hnot_hnot] - -theorem le_hnot_inf_hnot : ¬(a ⊔ b) ≤ ¬a ⊓ ¬b := - le_inf (hnot_anti le_sup_left) <| hnot_anti le_sup_right - -theorem hnot_hnot_sup_distrib (a b : α) : ¬¬(a ⊔ b) = ¬¬a ⊔ ¬¬b := by - refine ((hnot_inf_distrib _ _).ge.trans <| hnot_anti le_hnot_inf_hnot).antisymm' ?_ - rw [hnot_le_iff_codisjoint_left, codisjoint_assoc, codisjoint_hnot_hnot_left_iff, - codisjoint_left_comm, codisjoint_hnot_hnot_left_iff, ← codisjoint_assoc, sup_comm] - exact codisjoint_hnot_right - -theorem hnot_hnot_sdiff_distrib (a b : α) : ¬¬(a \ b) = ¬¬a \ ¬¬b := by - apply le_antisymm - · refine hnot_le_comm.1 ((hnot_anti sdiff_le_inf_hnot).trans' ?_) - rw [hnot_inf_distrib, hnot_le_iff_codisjoint_right, codisjoint_left_comm, ← - hnot_le_iff_codisjoint_right] - exact le_sdiff_sup - · rw [sdiff_le_iff, ← hnot_hnot_sup_distrib] - exact hnot_anti (hnot_anti le_sup_sdiff) - -instance OrderDual.instHeytingAlgebra : HeytingAlgebra αᵒᵈ where - compl := toDual ∘ hnot ∘ ofDual - himp a b := toDual (ofDual b \ ofDual a) - le_himp_iff a b c := by rw [inf_comm]; exact sdiff_le_iff - himp_bot := @top_sdiff' α _ - -@[simp] -theorem ofDual_compl (a : αᵒᵈ) : ofDual aᶜ = ¬ofDual a := - rfl - -@[simp] -theorem ofDual_himp (a b : αᵒᵈ) : ofDual (a ⇨ b) = ofDual b \ ofDual a := - rfl - -@[simp] -theorem toDual_hnot (a : α) : toDual (¬a) = (toDual a)ᶜ := - rfl - -@[simp] -theorem toDual_sdiff (a b : α) : toDual (a \ b) = toDual b ⇨ toDual a := - rfl - +@[to_dual existing] instance Prod.instCoheytingAlgebra [CoheytingAlgebra β] : CoheytingAlgebra (α × β) where sdiff_le_iff _ _ _ := and_congr sdiff_le_iff sdiff_le_iff top_sdiff a := Prod.ext_iff.2 ⟨top_sdiff' a.1, top_sdiff' a.2⟩ +@[to_dual existing] instance Pi.instCoheytingAlgebra {α : ι → Type*} [∀ i, CoheytingAlgebra (α i)] : CoheytingAlgebra (∀ i, α i) where top_sdiff f := funext fun i ↦ top_sdiff' (f i) @@ -1011,6 +837,7 @@ protected abbrev Function.Injective.generalizedHeytingAlgebra [Max α] [Min α] -- See note [reducible non-instances] /-- Pullback a `GeneralizedCoheytingAlgebra` along an injection. -/ +@[to_dual existing (reorder := 3 4, le (x y), lt (x y), map_sup map_inf, map_sdiff (a b))] protected abbrev Function.Injective.generalizedCoheytingAlgebra [Max α] [Min α] [LE α] [LT α] [Bot α] [SDiff α] [GeneralizedCoheytingAlgebra β] (f : α → β) (hf : Injective f) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) @@ -1026,6 +853,8 @@ protected abbrev Function.Injective.generalizedCoheytingAlgebra [Max α] [Min α -- See note [reducible non-instances] /-- Pullback a `HeytingAlgebra` along an injection. -/ +@[to_dual (reorder := le (x y), lt (x y), map_sup map_inf, map_top map_bot, map_himp (a b)) +/-- Pullback a `CoheytingAlgebra` along an injection. -/] protected abbrev Function.Injective.heytingAlgebra [Max α] [Min α] [LE α] [LT α] [Top α] [Bot α] [Compl α] [HImp α] [HeytingAlgebra β] (f : α → β) (hf : Injective f) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) @@ -1038,22 +867,10 @@ protected abbrev Function.Injective.heytingAlgebra [Max α] [Min α] [LE α] [LT exact bot_le himp_bot a := hf <| by rw [map_himp, map_compl, map_bot, himp_bot] --- See note [reducible non-instances] -/-- Pullback a `CoheytingAlgebra` along an injection. -/ -protected abbrev Function.Injective.coheytingAlgebra [Max α] [Min α] [LE α] [LT α] [Top α] [Bot α] - [HNot α] [SDiff α] [CoheytingAlgebra β] (f : α → β) (hf : Injective f) - (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) - (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b) - (map_top : f ⊤ = ⊤) (map_bot : f ⊥ = ⊥) (map_hnot : ∀ a, f (¬a) = ¬f a) - (map_sdiff : ∀ a b, f (a \ b) = f a \ f b) : CoheytingAlgebra α where - __ := hf.generalizedCoheytingAlgebra f le lt map_sup map_inf map_bot map_sdiff - le_top a := by - rw [← le, map_top] - exact le_top - top_sdiff a := hf <| by rw [map_sdiff, map_hnot, map_top, top_sdiff'] - -- See note [reducible non-instances] /-- Pullback a `BiheytingAlgebra` along an injection. -/ +@[to_dual self (reorder := 3 4, 7 8, 9 10, 11 12, le (x y), lt (x y), + map_sup map_inf, map_top map_bot, map_compl map_hnot, map_himp map_sdiff (a b))] protected abbrev Function.Injective.biheytingAlgebra [Max α] [Min α] [LE α] [LT α] [Top α] [Bot α] [Compl α] [HNot α] [HImp α] [SDiff α] [BiheytingAlgebra β] (f : α → β) (hf : Injective f) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) @@ -1138,35 +955,19 @@ instance instBiheytingAlgebra : BiheytingAlgebra PUnit.{u + 1} := top_sdiff := fun _ => rfl, sdiff_le_iff := fun _ _ _ => Iff.rfl } -@[simp] +@[to_dual (attr := simp)] theorem top_eq : (⊤ : PUnit) = unit := rfl -@[simp] -theorem bot_eq : (⊥ : PUnit) = unit := - rfl - -@[simp] +@[to_dual (attr := simp)] theorem sup_eq : a ⊔ b = unit := rfl -@[simp] -theorem inf_eq : a ⊓ b = unit := - rfl - -@[simp] -theorem compl_eq : aᶜ = unit := - rfl - -@[simp] -theorem sdiff_eq : a \ b = unit := - rfl - -@[simp] +@[to_dual (attr := simp)] theorem hnot_eq : ¬a = unit := rfl -@[simp] +@[to_dual (attr := simp)] theorem himp_eq : a ⇨ b = unit := rfl diff --git a/Mathlib/Order/Notation.lean b/Mathlib/Order/Notation.lean index 9cd2fb4f2df3af..f63f62501b3d16 100644 --- a/Mathlib/Order/Notation.lean +++ b/Mathlib/Order/Notation.lean @@ -144,11 +144,16 @@ meta def delabInf : Delab := end Mathlib.Meta /-- Syntax typeclass for Heyting implication `⇨`. -/ -@[notation_class] +@[notation_class, to_dual SDiff] class HImp (α : Type*) where /-- Heyting implication `⇨` -/ himp : α → α → α +set_option linter.translateOverwrite false in +attribute [to_dual existing (reorder := 3 4) sdiff] HImp.himp +set_option linter.translateOverwrite false in +attribute [to_dual existing (reorder := himp (1 2))] HImp.mk + /-- Syntax typeclass for Heyting negation `¬`. The difference between `Compl` and `HNot` is that the former belongs to Heyting algebras, @@ -156,7 +161,7 @@ while the latter belongs to co-Heyting algebras. They are both pseudo-complement underestimates while `HNot` overestimates. In Boolean algebras, they are equal. See `hnot_eq_compl`. -/ -@[notation_class] +@[notation_class, to_dual Compl] class HNot (α : Type*) where /-- Heyting negation `¬` -/ hnot : α → α From c5f3b983e4a32cd64a5d604d7f3a943e888eab8e Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 12:13:24 +0000 Subject: [PATCH 0800/1300] chore(LinearAlgebra/Matrix/Defs): automated extraction from #41160 (#41770) This PR was automatically created from PR #41160 by @paulcadman via a [review comment](https://github.com/leanprover-community/mathlib4/pull/41160#discussion_r3586686324) by @ocfnash. Co-authored-by: paulcadman <92877+paulcadman@users.noreply.github.com> --- Mathlib/LinearAlgebra/Matrix/Defs.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index e36bc8ec9d5b62..a985501cb0eaf3 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -6,6 +6,7 @@ Authors: Ellen Arlt, Blair Shi, Sean Leather, Mario Carneiro, Johan Commelin, Lu module public import Mathlib.Algebra.Module.Pi +public import Mathlib.Data.Fin.Basic public import Mathlib.Logic.Nontrivial.Basic public import Mathlib.Tactic.CrossRefAttribute @@ -94,6 +95,14 @@ theorem of_apply (f : m → n → α) (i j) : of f i j = f i j := theorem of_symm_apply (f : Matrix m n α) (i j) : of.symm f i j = f i j := rfl +/-- Construct a matrix from an array in row-major ordering. -/ +def ofArray {m n : ℕ} (A : Array R) (hA : A.size = m * n) : Matrix (Fin m) (Fin n) R := + fun i j => A[Fin.mkDivMod i j] + +@[simp] +theorem ofArray_apply {m n : ℕ} (A : Array R) (hA : A.size = m * n) (i : Fin m) (j : Fin n) : + ofArray A hA i j = A[Fin.mkDivMod i j] := rfl + /-- `M.map f` is the matrix obtained by applying `f` to each entry of the matrix `M`. This is available in bundled forms as: From a687aebb4fb2c46405a3fe301fdceeefb633d0c7 Mon Sep 17 00:00:00 2001 From: Re'em <158774055+ReemMelamed@users.noreply.github.com> Date: Wed, 15 Jul 2026 13:10:22 +0000 Subject: [PATCH 0801/1300] feat(Algebra/Divisibility/Basic): introduce right division (RightDvd) (#40843) As suggested by @YaelDillies [here](https://github.com/leanprover-community/mathlib4/pull/40050#issuecomment-4719073791) in #40050, this PR introduces the concept of right division (`RightDvd`) as a relation in `Algebra/Divisibility/Basic`. Co-authored-by: ReemMelamed --- Mathlib/Algebra/Divisibility/Basic.lean | 71 ++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Divisibility/Basic.lean b/Mathlib/Algebra/Divisibility/Basic.lean index 97120cd19c3273..53bef9dac5aa63 100644 --- a/Mathlib/Algebra/Divisibility/Basic.lean +++ b/Mathlib/Algebra/Divisibility/Basic.lean @@ -2,11 +2,11 @@ Copyright (c) 2014 Jeremy Avigad. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Amelia Livingston, Yury Kudryashov, -Neil Strickland, Aaron Anderson +Neil Strickland, Aaron Anderson, Re'em Melamed-Katz -/ module -public import Mathlib.Algebra.Group.Basic +public import Mathlib.Algebra.Group.Opposite public import Mathlib.Tactic.Common public import Batteries.Tactic.SeqFocus @@ -110,8 +110,58 @@ theorem mul_dvd_mul_left (a : α) (h : b ∣ c) : a * b ∣ a * c := by theorem IsLeftRegular.dvd_cancel_left (h : IsLeftRegular a) : a * b ∣ a * c ↔ b ∣ c := ⟨fun dvd ↦ have ⟨d, eq⟩ := dvd; ⟨d, h (eq.trans <| mul_assoc ..)⟩, mul_dvd_mul_left a⟩ +/-- Right divisibility relation. `RightDvd a b` means `a` right-divides `b`, +i.e., `∃ c, b = c * a`. -/ +def RightDvd (a b : α) : Prop := ∃ c, b = c * a + +@[inherit_doc] +infix:50 " ∣ᵣ " => RightDvd + +@[trans] +protected theorem RightDvd.trans : a ∣ᵣ b → b ∣ᵣ c → a ∣ᵣ c + | ⟨d, h₁⟩, ⟨e, h₂⟩ => ⟨e * d, h₁ ▸ h₂.trans <| (mul_assoc e d a).symm⟩ + +/-- Transitivity of `RightDvd` for use in `calc` blocks. -/ +instance : IsTrans α RightDvd := + ⟨fun _ _ _ => RightDvd.trans⟩ + +@[simp] +theorem RightDvd.mul_self (a b : α) : a ∣ᵣ b * a := + ⟨b, rfl⟩ + +theorem RightDvd.mul_left (h : a ∣ᵣ b) (c : α) : a ∣ᵣ c * b := + h.trans (RightDvd.mul_self b c) + +theorem RightDvd.of_mul_left (h : b * a ∣ᵣ c) : a ∣ᵣ c := + (RightDvd.mul_self a b).trans h + +@[gcongr] +theorem RightDvd.mul_const (a : α) (h : b ∣ᵣ c) : b * a ∣ᵣ c * a := by + obtain ⟨d, rfl⟩ := h + use d + rw [mul_assoc] + +theorem IsRightRegular.rightDvd_cancel_right (h : IsRightRegular a) : + b * a ∣ᵣ c * a ↔ b ∣ᵣ c := + ⟨fun dvd ↦ have ⟨d, eq⟩ := dvd + ⟨d, h (eq.trans <| (mul_assoc ..).symm)⟩, RightDvd.mul_const a⟩ + +theorem rightDvd_iff_op_dvd_op : a ∣ᵣ b ↔ MulOpposite.op a ∣ MulOpposite.op b := + ⟨fun ⟨c, hc⟩ => ⟨MulOpposite.op c, by simp [hc]⟩, + fun ⟨c, hc⟩ => ⟨MulOpposite.unop c, by simpa using congrArg MulOpposite.unop hc⟩⟩ + end Semigroup +section RightCancelSemigroup + +variable [RightCancelSemigroup α] {a b c : α} + +@[simp] +theorem mul_rightDvd_mul_iff_left : b * a ∣ᵣ c * a ↔ b ∣ᵣ c := + ⟨fun ⟨d, eq⟩ ↦ ⟨d, mul_right_cancel (eq.trans (mul_assoc ..).symm)⟩, RightDvd.mul_const a⟩ + +end RightCancelSemigroup + section Monoid variable [Monoid α] {a b c : α} {m n : ℕ} @@ -143,6 +193,19 @@ alias Dvd.dvd.pow := dvd_pow lemma dvd_pow_self (a : α) {n : ℕ} (hn : n ≠ 0) : a ∣ a ^ n := dvd_rfl.pow hn +@[refl, simp] +protected theorem RightDvd.refl (a : α) : a ∣ᵣ a := + ⟨1, (one_mul a).symm⟩ + +protected theorem RightDvd.rfl {a : α} : a ∣ᵣ a := .refl _ + +instance : IsPreorder α RightDvd where + refl := .refl + +theorem RightDvd.of_eq (h : a = b) : a ∣ᵣ b := by rw [h] + +alias Eq.rightDvd := RightDvd.of_eq + end Monoid section CommSemigroup @@ -189,6 +252,10 @@ theorem dvd_mul [DecompositionMonoid α] {k m n : α} : rintro ⟨d₁, d₂, hy, hz, rfl⟩ gcongr +@[simp] +theorem rightDvd_iff_dvd : a ∣ᵣ b ↔ a ∣ b := + exists_congr fun c ↦ by rw [mul_comm] + end CommSemigroup section CommMonoid From 5ef639762b76eeeaca08f7e227234ab3ca278625 Mon Sep 17 00:00:00 2001 From: mitchell-horner <29882987+mitchell-horner@users.noreply.github.com> Date: Wed, 15 Jul 2026 13:58:28 +0000 Subject: [PATCH 0802/1300] feat(Combinatorics/SimpleGraph): define the Zarankiewicz function (#34633) Defines the Zarankiewicz function $z(m, n; s, t)$ in terms of bipartite graphs. --- Mathlib.lean | 1 + .../SimpleGraph/Extremal/Zarankiewicz.lean | 155 ++++++++++++++++++ Mathlib/Combinatorics/SimpleGraph/Maps.lean | 8 + 3 files changed, 164 insertions(+) create mode 100644 Mathlib/Combinatorics/SimpleGraph/Extremal/Zarankiewicz.lean diff --git a/Mathlib.lean b/Mathlib.lean index c1d9e76f28c7b4..5868d1305017c9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3660,6 +3660,7 @@ public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic public import Mathlib.Combinatorics.SimpleGraph.Extremal.ErdosStoneSimonovits public import Mathlib.Combinatorics.SimpleGraph.Extremal.Turan public import Mathlib.Combinatorics.SimpleGraph.Extremal.TuranDensity +public import Mathlib.Combinatorics.SimpleGraph.Extremal.Zarankiewicz public import Mathlib.Combinatorics.SimpleGraph.Finite public import Mathlib.Combinatorics.SimpleGraph.Finsubgraph public import Mathlib.Combinatorics.SimpleGraph.FiveWheelLike diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/Zarankiewicz.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/Zarankiewicz.lean new file mode 100644 index 00000000000000..4a83a7c4eccbe2 --- /dev/null +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/Zarankiewicz.lean @@ -0,0 +1,155 @@ +/- +Copyright (c) 2026 Mitchell Horner. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Mitchell Horner +-/ +module + +public import Mathlib.Algebra.Order.Floor.Semiring +public import Mathlib.Combinatorics.SimpleGraph.Bipartite +public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic +public import Mathlib.Combinatorics.SimpleGraph.Maps + +import Mathlib.Algebra.Order.Archimedean.Real.Basic +import Mathlib.Logic.Equiv.Fin.Basic +import Mathlib.Tactic.Rify + +/-! +# The Zarankiewicz function + +This file defines the **Zarankiewicz function** in terms of bipartite graphs. +-/ + +public section + +open Finset Fintype + +namespace SimpleGraph + +/-- The **Zarankiewicz function** of natural numbers `m`, `n`, `s`, and `t` is the maximum +number of edges in a `completeBipartiteGraph (Fin s) (Fin t)`-free bipartite graph with parts of +size `m` and `n`. + +This is the *extremal graph theory* version of the **Zarankiewicz function**. -/ +noncomputable def zarankiewicz (m n s t : ℕ) : ℕ := + open Classical in + sup { G : SimpleGraph (Fin m ⊕ Fin n) | G ≤ completeBipartiteGraph (Fin m) (Fin n) + ∧ (completeBipartiteGraph (Fin s) (Fin t)).Free G} (#·.edgeFinset) + +variable {m n s t : ℕ} {V W α β : Type*} [Fintype V] [Fintype W] [Fintype α] [Fintype β] + +open Classical in +theorem zarankiewicz_of_fintypeCard_eq + (hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) : + zarankiewicz m n s t = + sup { G : SimpleGraph (V ⊕ W) | G ≤ completeBipartiteGraph V W + ∧ (completeBipartiteGraph α β).Free G} (#·.edgeFinset) := by + let e₁ := completeBipartiteGraphCongr + (Fintype.equivFinOfCardEq hm) (Fintype.equivFinOfCardEq hn) + let K := completeBipartiteGraph (Fin s) (Fin t) + let e₂ := completeBipartiteGraphCongr + (Fintype.equivFinOfCardEq hs) (Fintype.equivFinOfCardEq ht) + rw [zarankiewicz, le_antisymm_iff] + and_intros + on_goal 1 => + let e₁ := e₁.symm + let K := completeBipartiteGraph α β + let e₂ := e₂.symm + all_goals + simp_rw [Finset.sup_le_iff, mem_filter, mem_univ, true_and] + intro G ⟨h_le, h_free⟩ + simp_rw [Iso.card_edgeFinset_eq (.map e₁.toEquiv G)] + have h' : G.map e₁.toEquiv.toEmbedding ∈ univ.filter fun G ↦ + G ≤ completeBipartiteGraph _ _ ∧ K.Free G := by + rw [mem_filter_univ, map_le_iff_le_comap] + refine ⟨fun _ _ hadj ↦ ?_, ?_⟩ + · replace h_le := h_le hadj + rw [← Embedding.map_adj_iff e₁.toEmbedding, ← comap_adj] at h_le + exact h_le + · rw [Function.Embedding.coeFn_mk, ← free_congr e₂ (.map e₁.toEquiv G)] + exact h_free + have h_le_sup := @le_sup _ _ _ _ _ (#·.edgeFinset) (G.map e₁.toEquiv.toEmbedding) h' + simp_rw [← card_coe, mem_edgeFinset] at h_le_sup ⊢ + exact h_le_sup + +/-- `zarankiewicz m n s t` is at most `x` if and only if every +`completeBipartiteGraph α β`-free bipartite graph `G` has at most `x` edges. -/ +theorem zarankiewicz_le_iff + (hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) (x : ℕ) : + zarankiewicz m n s t ≤ x ↔ + ∀ ⦃G : SimpleGraph (V ⊕ W)⦄ [DecidableRel G.Adj], G ≤ completeBipartiteGraph V W → + (completeBipartiteGraph α β).Free G → #G.edgeFinset ≤ x := by + simp_rw [zarankiewicz_of_fintypeCard_eq hm hn hs ht, + Finset.sup_le_iff, mem_filter, mem_univ, true_and] + exact ⟨fun h _ _ h_le h_free ↦ (h _ ⟨h_le, h_free⟩).trans_eq' <| by convert rfl, + fun h _ ⟨h_le, h_free⟩ ↦ by convert h h_le h_free⟩ + +/-- `zarankiewicz m n s t` is greater than `x` if and only if there +exists a `completeBipartiteGraph α β`-free bipartite graph `G` with more than `x` edges. -/ +theorem lt_zarankiewicz_iff + (hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) (x : ℕ) : + x < zarankiewicz m n s t ↔ + ∃ G : SimpleGraph (V ⊕ W), ∃ _ : DecidableRel G.Adj, G ≤ completeBipartiteGraph V W ∧ + (completeBipartiteGraph α β).Free G ∧ x < #G.edgeFinset := by + simp_rw [zarankiewicz_of_fintypeCard_eq hm hn hs ht, + Finset.lt_sup_iff, mem_filter, mem_univ, true_and] + exact ⟨fun ⟨_, ⟨h_le, h_free⟩, h_lt⟩ ↦ ⟨_, _, h_le, h_free, by convert h_lt⟩, + fun ⟨_, _, ⟨h_le, h_free, h_lt⟩⟩ ↦ ⟨_, ⟨h_le, h_free⟩, h_lt.trans_eq <| by convert rfl⟩⟩ + +variable {R : Type*} [Semiring R] [LinearOrder R] [FloorSemiring R] + +@[inherit_doc zarankiewicz_le_iff] +theorem zarankiewicz_le_iff_of_nonneg + (hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) {x : R} (h : 0 ≤ x) : + zarankiewicz m n s t ≤ x ↔ + ∀ ⦃G : SimpleGraph (V ⊕ W)⦄ [DecidableRel G.Adj], G ≤ completeBipartiteGraph V W → + (completeBipartiteGraph α β).Free G → #G.edgeFinset ≤ x := by + simp_rw [← Nat.le_floor_iff h] + exact zarankiewicz_le_iff hm hn hs ht ⌊x⌋₊ + +@[inherit_doc lt_zarankiewicz_iff] +theorem lt_zarankiewicz_iff_of_nonneg + (hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) {x : R} (h : 0 ≤ x) : + x < zarankiewicz m n s t ↔ + ∃ G : SimpleGraph (V ⊕ W), ∃ _ : DecidableRel G.Adj, G ≤ completeBipartiteGraph V W ∧ + (completeBipartiteGraph α β).Free G ∧ x < #G.edgeFinset := by + simp_rw [← Nat.floor_lt h] + exact lt_zarankiewicz_iff hm hn hs ht ⌊x⌋₊ + +open Classical in +/-- The Zarankiewicz function is at most the corresponding extremal number. -/ +theorem zarankiewicz_le_extremalNumber (hs : card α = s) (ht : card β = t) : + zarankiewicz m n s t ≤ extremalNumber (m + n) (completeBipartiteGraph α β) := by + conv => + enter [2, 1] + rw [← Fintype.card_fin (m + n)] + simp_rw [zarankiewicz, Finset.sup_le_iff, mem_filter, mem_univ, true_and] + intro B ⟨_, h⟩ + rw [(Iso.map finSumFinEquiv B).card_edgeFinset_eq] + refine card_edgeFinset_le_extremalNumber <| + (h.congr_left ?_).congr_right (Iso.map finSumFinEquiv B).symm + exact completeBipartiteGraphCongr + (Fintype.equivFinOfCardEq hs) (Fintype.equivFinOfCardEq ht) + +/-- The symmetric Zarankiewicz function is at least twice a corresponding extremal number. -/ +theorem two_mul_extremalNumber_le_zarankiewicz_symm + [Nonempty α] [Nonempty β] (hs : card α = s) (ht : card β = t) : + 2 * extremalNumber n (completeBipartiteGraph α β) ≤ zarankiewicz n n s t := by + conv => + enter [1, 2, 1] + rw [← Fintype.card_fin n] + rify + rw [← le_div_iff₀' (by positivity), extremalNumber_le_iff_of_nonneg _ (by positivity)] + intro G _ h + rw [le_div_iff₀' (by positivity), ← Nat.cast_two, ← Nat.cast_mul, Nat.cast_le] + apply Finset.le_sup_of_le (b := G.bipartiteDoubleCover) + · simp_rw [mem_filter, mem_univ, true_and] + refine ⟨bipartiteDoubleCover_le, ?_⟩ + contrapose! h + refine completeBipartiteGraph_isContained_bipartiteDoubleCover.mp <| + h.trans' ⟨Iso.toCopy ?_⟩ + exact completeBipartiteGraphCongr + (Fintype.equivFinOfCardEq hs) (Fintype.equivFinOfCardEq ht) + · convert card_edgeFinset_bipartiteDoubleCover.symm.le + +end SimpleGraph diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index 404a8eca0f79ef..c2497a1dacb10b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -799,6 +799,14 @@ def induceUnivIso (G : SimpleGraph V) : G.induce Set.univ ≃g G where map_rel_iff' := by simp only [Equiv.Set.univ, Equiv.coe_fn_mk, comap_adj, Embedding.coe_subtype, implies_true] +/-- The isomorphism between `completeBipartiteGraph V₁ W₁` and +`completeBipartiteGraph V₂ W₂` where `V₁ ≃ V₂` and `W₁ ≃ W₂`. -/ +@[simps!] +def completeBipartiteGraphCongr {V₁ V₂ W₁ W₂ : Type*} (hV : V₁ ≃ V₂) (hW : W₁ ≃ W₂) : + completeBipartiteGraph V₁ W₁ ≃g completeBipartiteGraph V₂ W₂ where + __ := hV.sumCongr hW + map_rel_iff' := by simp + section Finite variable [Fintype V] {n : ℕ} From a570e2ca7c8265dc89d47a85cf629e4048e726f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 15 Jul 2026 14:18:22 +0000 Subject: [PATCH 0803/1300] feat(CategoryTheory/Monoidal): `copy` for functor properties (#41764) From Toric, FLT --- .../Monoidal/Braided/Basic.lean | 24 +++++++++++++ Mathlib/CategoryTheory/Monoidal/Functor.lean | 34 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean index 10edcb978c5329..7193f5f45864af 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean @@ -414,6 +414,17 @@ def ofNatIso {F G : C ⥤ D} (i : F ≅ G) [F.LaxBraided] [G.LaxMonoidal] rw [this X Y, this Y X, ← braiding_naturality_assoc, ← Functor.LaxBraided.braided_assoc] simp +/-- Copy of a lax braided structure on a functor `F` with new `ε` and `μ` fields equal to the old +ones. + +This is useful to fix definitional equalities. -/ +@[implicit_reducible] +def copy {F : C ⥤ D} (hF : F.LaxBraided) (ε' : 𝟙_ D ⟶ F.obj (𝟙_ C)) + (μ' : ∀ X Y : C, F.obj X ⊗ F.obj Y ⟶ F.obj (X ⊗ Y)) + (hε : ε' = ε F := by cat_disch) (hμ : μ' = μ F := by cat_disch) : F.LaxBraided where + __ := hF.toLaxMonoidal.copy ε' μ' hε hμ + braided X Y := hμ ▸ hF.braided X Y + end Functor.LaxBraided section @@ -559,6 +570,19 @@ instance (F : C ⥤ D) (G : D ⥤ E) [F.Braided] [G.Braided] : (F ⋙ G).Braided lemma toMonoidal_injective (F : C ⥤ D) : Function.Injective (@Braided.toMonoidal _ _ _ _ _ _ _ _ _ : F.Braided → F.Monoidal) := by rintro ⟨⟩ ⟨⟩ rfl; rfl +/-- Copy of a braided structure on a functor `F` with new `ε`, `μ`, `η` and `δ` fields equal to the +old ones. + +This is useful to fix definitional equalities. -/ +@[implicit_reducible] +def copy {F : C ⥤ D} (hF : F.Braided) (ε' : 𝟙_ D ⟶ F.obj (𝟙_ C)) + (μ' : ∀ X Y : C, F.obj X ⊗ F.obj Y ⟶ F.obj (X ⊗ Y)) (η' : F.obj (𝟙_ C) ⟶ 𝟙_ D) + (δ' : ∀ X Y : C, F.obj (X ⊗ Y) ⟶ F.obj X ⊗ F.obj Y) + (hε : ε' = ε F := by cat_disch) (hμ : μ' = μ F := by cat_disch) + (hη : η' = η F := by cat_disch) (hδ : δ' = δ F := by cat_disch) : F.Braided where + __ := hF.toMonoidal.copy ε' μ' η' δ' hε hμ hη hδ + braided X Y := hμ ▸ hF.braided X Y + end Functor.Braided section CommMonoid diff --git a/Mathlib/CategoryTheory/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Functor.lean index 08dc1192c212ce..582806b4b8ef6b 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor.lean @@ -156,6 +156,16 @@ lemma whiskerLeft_μ_comp_μ (X Y Z : C) : μ F X Y ▷ F.obj Z ≫ μ F (X ⊗ Y) Z ≫ F.map (α_ X Y Z).hom := by rw [associativity, Iso.inv_hom_id_assoc] +/-- Copy of a lax monoidal structure with new `ε` and `μ` fields equal to the old ones. + +This is useful to fix definitional equalities. -/ +@[implicit_reducible] +def copy {F : C ⥤ D} (hF : F.LaxMonoidal) (ε' : 𝟙_ D ⟶ F.obj (𝟙_ C)) + (μ' : ∀ X Y : C, F.obj X ⊗ F.obj Y ⟶ F.obj (X ⊗ Y)) + (hε : ε' = ε F := by cat_disch) (hμ : μ' = μ F := by cat_disch) : F.LaxMonoidal where + ε := ε' + μ := μ' + end section @@ -330,6 +340,17 @@ lemma δ_comp_whiskerLeft_δ (X Y Z : C) : end +/-- Copy of an oplax monoidal structure on a functor `F` with new `η` and `δ` fields equal to the +old ones. + +This is useful to fix definitional equalities. -/ +@[implicit_reducible] +def copy {F : C ⥤ D} (hF : F.OplaxMonoidal) (η' : F.obj (𝟙_ C) ⟶ 𝟙_ D) + (δ' : ∀ X Y : C, F.obj (X ⊗ Y) ⟶ F.obj X ⊗ F.obj Y) + (hη : η' = η F := by cat_disch) (hδ : δ' = δ F := by cat_disch) : F.OplaxMonoidal where + η := η' + δ := δ' + @[simps] instance id : (𝟭 C).OplaxMonoidal where η := 𝟙 _ @@ -577,6 +598,19 @@ lemma toOplaxMonoidal_injective : Function.Injective · exact congr(($eq).η) · exact congr(($eq).δ) +/-- Copy of a monoidal structure on a functor `F` with new `ε`, `μ`, `η` and `δ` fields equal to the +old ones. + +This is useful to fix definitional equalities. -/ +@[implicit_reducible] +def copy {F : C ⥤ D} (hF : F.Monoidal) (ε' : 𝟙_ D ⟶ F.obj (𝟙_ C)) + (μ' : ∀ X Y : C, F.obj X ⊗ F.obj Y ⟶ F.obj (X ⊗ Y)) (η' : F.obj (𝟙_ C) ⟶ 𝟙_ D) + (δ' : ∀ X Y : C, F.obj (X ⊗ Y) ⟶ F.obj X ⊗ F.obj Y) + (hε : ε' = ε F := by cat_disch) (hμ : μ' = μ F := by cat_disch) + (hη : η' = η F := by cat_disch) (hδ : δ' = δ F := by cat_disch) : F.Monoidal where + __ := hF.toLaxMonoidal.copy ε' μ' hε hμ + __ := hF.toOplaxMonoidal.copy η' δ' hη hδ + end Monoidal variable (F : C ⥤ D) From 52e9692265c7a6de5a39913fa8f847d4909309eb Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:32:32 +0000 Subject: [PATCH 0804/1300] chore(CategoryTheory/Presentable/Basic): remove bad instance (#41660) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The instance `HasCardinalFilteredColimits.hasColimitsOfShape` is bad because it has no way to infer the value of `κ`. Almost 2 years ago there was a change to type classes, which caused Lean to not give a warning about this, in https://github.com/leanprover/lean4/pull/5376 and I think that is an issue. This PR is a copy of #27941. In the meantime, this instance has accidentally been added again in #30533. --- Mathlib/CategoryTheory/Presentable/Adjunction.lean | 3 ++- Mathlib/CategoryTheory/Presentable/Basic.lean | 12 +++++------- .../Presentable/OrthogonalReflection.lean | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Presentable/Adjunction.lean b/Mathlib/CategoryTheory/Presentable/Adjunction.lean index d1d26fe3e05839..3669dc677fcf2f 100644 --- a/Mathlib/CategoryTheory/Presentable/Adjunction.lean +++ b/Mathlib/CategoryTheory/Presentable/Adjunction.lean @@ -86,8 +86,9 @@ lemma isCardinalLocallyPresentable [IsCardinalLocallyPresentable C κ] lemma isCardinalAccessibleCategory [IsCardinalAccessibleCategory C κ] [G.IsCardinalAccessible κ] [G.Full] [G.Faithful] : IsCardinalAccessibleCategory D κ where - toHasCardinalFilteredColimits := ⟨fun _ _ _ ↦ + toHasCardinalFilteredColimits := ⟨fun J _ _ ↦ let : Reflective G := ⟨_, adj⟩ + have := HasCardinalFilteredColimits.hasColimitsOfShape C κ J hasColimitsOfShape_of_reflective G⟩ toHasCardinalFilteredGenerator := adj.hasCardinalFilteredGenerator κ diff --git a/Mathlib/CategoryTheory/Presentable/Basic.lean b/Mathlib/CategoryTheory/Presentable/Basic.lean index f1d14fbe781e7c..99f98d7b8dd95c 100644 --- a/Mathlib/CategoryTheory/Presentable/Basic.lean +++ b/Mathlib/CategoryTheory/Presentable/Basic.lean @@ -344,17 +344,15 @@ end section -variable (C) (κ : Cardinal.{w}) [Fact κ.IsRegular] - /-- A category has `κ`-filtered colimits if it has colimits of shape `J` for any `κ`-filtered category `J`. -/ -class HasCardinalFilteredColimits : Prop where - hasColimitsOfShape (J : Type w) [SmallCategory J] [IsCardinalFiltered J κ] : +class HasCardinalFilteredColimits (C : Type u₁) [Category.{v₁} C] + (κ : Cardinal.{w}) [Fact κ.IsRegular] : Prop where + hasColimitsOfShape (C) (J : Type w) [SmallCategory J] [IsCardinalFiltered J κ] : HasColimitsOfShape J C := by intros; infer_instance -attribute [instance] HasCardinalFilteredColimits.hasColimitsOfShape - -instance [HasColimitsOfSize.{w, w} C] : HasCardinalFilteredColimits.{w} C κ where +instance (κ : Cardinal.{w}) [Fact κ.IsRegular] [HasColimitsOfSize.{w, w} C] : + HasCardinalFilteredColimits.{w} C κ where end diff --git a/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean b/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean index 7ad827d1fb158d..3bc7f1e79301e6 100644 --- a/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean +++ b/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean @@ -99,6 +99,7 @@ lemma MorphismProperty.isCardinalAccessible_ι_isLocal W.isLocal.ι.IsCardinalAccessible κ where preservesColimitOfShape J _ _ := by have := W.isClosedUnderColimitsOfShape_isLocal J κ hW + have := HasCardinalFilteredColimits.hasColimitsOfShape C κ J infer_instance namespace OrthogonalReflection From 28313485bc624fcd16dcb162dd2e2c3c813aa8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 15 Jul 2026 14:47:27 +0000 Subject: [PATCH 0805/1300] chore(Data/Finsupp): rename `mapDomain_notin_range` to `mapDomain_of_notMem_range` (#41766) ... so that this follows the naming convention. Same for `embDomain` and for `HahnSeries`. --- Mathlib/Algebra/Group/Finsupp.lean | 2 +- .../InnerProductSpace/SingularValues.lean | 2 +- Mathlib/Combinatorics/Nullstellensatz.lean | 2 +- Mathlib/Data/Finsupp/Basic.lean | 16 +++++++++------- Mathlib/Data/Finsupp/Defs.lean | 4 +++- Mathlib/Data/Finsupp/Option.lean | 2 +- Mathlib/Data/Finsupp/Order.lean | 2 +- Mathlib/Data/Finsupp/Sigma.lean | 4 ++-- Mathlib/Data/List/ToFinsupp.lean | 2 +- Mathlib/RingTheory/Extension/Generators.lean | 2 +- Mathlib/RingTheory/HahnSeries/Addition.lean | 4 ++-- Mathlib/RingTheory/HahnSeries/Basic.lean | 4 +++- Mathlib/RingTheory/HahnSeries/Lex.lean | 4 ++-- .../RingTheory/HahnSeries/Multiplication.lean | 2 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 4 +++- Mathlib/RingTheory/IsAdjoinRoot.lean | 2 +- Mathlib/RingTheory/LaurentSeries.lean | 4 ++-- 17 files changed, 35 insertions(+), 27 deletions(-) diff --git a/Mathlib/Algebra/Group/Finsupp.lean b/Mathlib/Algebra/Group/Finsupp.lean index 487b64d8a8cb8f..984d91328bb8f8 100644 --- a/Mathlib/Algebra/Group/Finsupp.lean +++ b/Mathlib/Algebra/Group/Finsupp.lean @@ -137,7 +137,7 @@ def embDomain.addMonoidHom (f : ι ↪ F) : (ι →₀ M) →+ F →₀ M where by_cases h : b ∈ Set.range f · rcases h with ⟨a, rfl⟩ simp - · simp only [coe_add, Pi.add_apply, embDomain_notin_range _ _ _ h, add_zero] + · simp only [coe_add, Pi.add_apply, embDomain_of_notMem_range _ _ _ h, add_zero] @[simp] lemma embDomain_add (f : ι ↪ F) (v w : ι →₀ M) : diff --git a/Mathlib/Analysis/InnerProductSpace/SingularValues.lean b/Mathlib/Analysis/InnerProductSpace/SingularValues.lean index fe226adee921b1..33953e92c1ef32 100644 --- a/Mathlib/Analysis/InnerProductSpace/SingularValues.lean +++ b/Mathlib/Analysis/InnerProductSpace/SingularValues.lean @@ -121,7 +121,7 @@ theorem singularValues_of_lt {n : ℕ} (hn : finrank 𝕜 E = n) {i : ℕ} (hi : T.singularValues_fin hn ⟨i, hi⟩ theorem singularValues_of_finrank_le {i : ℕ} (hi : finrank 𝕜 E ≤ i) : T.singularValues i = 0 := by - apply Finsupp.embDomain_notin_range + apply Finsupp.embDomain_of_notMem_range simp [hi] theorem sq_singularValues_fin {n : ℕ} (hn : finrank 𝕜 E = n) (i : Fin n) : diff --git a/Mathlib/Combinatorics/Nullstellensatz.lean b/Mathlib/Combinatorics/Nullstellensatz.lean index 8e021845269d62..c957ad943dfe29 100644 --- a/Mathlib/Combinatorics/Nullstellensatz.lean +++ b/Mathlib/Combinatorics/Nullstellensatz.lean @@ -189,7 +189,7 @@ private lemma Alon.of_mem_P_support {ι : Type*} (i : ι) (S : Finset R) (m : ι ext j by_cases hj : j = i · rw [hj, mapDomain_apply (Function.injective_of_subsingleton _), single_eq_same] - · rw [mapDomain_notin_range, single_eq_of_ne hj] + · rw [mapDomain_of_notMem_range, single_eq_of_ne hj] simp [Set.range_const, Set.mem_singleton_iff, hj] variable [Finite σ] diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index dce21538cb0048..1650925f9429b5 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -281,12 +281,14 @@ lemma mapDomain_of_not_mem_image_support {f : α → β} {x : α →₀ M} {b : rw [mapDomain, sum_apply, sum, Finset.sum_eq_zero] exact fun a ha ↦ single_eq_of_ne fun eq => hb <| eq ▸ Set.mem_image_of_mem _ ha -theorem mapDomain_notin_range {f : α → β} (x : α →₀ M) (a : β) (h : a ∉ Set.range f) : +theorem mapDomain_of_notMem_range {f : α → β} (x : α →₀ M) (a : β) (h : a ∉ Set.range f) : mapDomain f x a = 0 := mapDomain_of_not_mem_image_support <| by grw [Set.image_subset_range]; exact h +@[deprecated (since := "2026-07-15")] alias mapDomain_notin_range := mapDomain_of_notMem_range + lemma mem_range_of_mapDomain_ne_zero {f : α → β} {x : α →₀ M} {b : β} (h : mapDomain f x b ≠ 0) : - b ∈ Set.range f := by contrapose! h; exact mapDomain_notin_range _ _ h + b ∈ Set.range f := by contrapose! h; exact mapDomain_of_notMem_range _ _ h @[simp] theorem mapDomain_id : mapDomain id v = v := @@ -421,7 +423,7 @@ theorem embDomain_eq_mapDomain (f : α ↪ β) (v : α →₀ M) : embDomain f v by_cases h : a ∈ Set.range f · rcases h with ⟨a, rfl⟩ rw [mapDomain_apply f.injective, embDomain_apply_self] - · rw [mapDomain_notin_range, embDomain_notin_range] <;> assumption + · rw [mapDomain_of_notMem_range, embDomain_of_notMem_range] <;> assumption @[to_additive] theorem prod_mapDomain_index_inj [CommMonoid N] {f : α → β} {s : α →₀ M} {h : β → M → N} @@ -546,7 +548,7 @@ lemma embDomain_comapDomain {f : α ↪ β} {g : β →₀ M} (hg : ↑g.support · obtain ⟨a, rfl⟩ := hb rw [embDomain_apply_self, comapDomain_apply] · replace hg : g b = 0 := notMem_support_iff.mp <| mt (hg ·) hb - rw [embDomain_notin_range _ _ _ hb, hg] + rw [embDomain_of_notMem_range _ _ _ hb, hg] @[simp] theorem comapDomain_embDomain (f : α ↪ β) (l : α →₀ M) : @@ -625,7 +627,7 @@ theorem comapDomain_mapDomain (hf : Function.Injective f) (l : α →₀ M) : lemma mem_range_mapDomain_iff (hf : Function.Injective f) (x : β →₀ M) : x ∈ Set.range (Finsupp.mapDomain f) ↔ ∀ b ∉ Set.range f, x b = 0 := by - refine ⟨fun ⟨y, hy⟩ x hx ↦ hy ▸ Finsupp.mapDomain_notin_range y x hx, fun h ↦ ?_⟩ + refine ⟨fun ⟨y, hy⟩ x hx ↦ hy ▸ Finsupp.mapDomain_of_notMem_range y x hx, fun h ↦ ?_⟩ refine ⟨Finsupp.comapDomain f x hf.injOn, Finsupp.mapDomain_comapDomain f hf _ fun i hi ↦ ?_⟩ by_contra hc simp only [Finset.mem_coe, Finsupp.mem_support_iff, ne_eq] at hi @@ -1066,7 +1068,7 @@ lemma sumElim_inr (f : α →₀ γ) (g : β →₀ γ) (x : β) : sumElim f g ( lemma sumElim_eq_add [AddCommMonoid M] (f : α →₀ M) (g : β →₀ M) : sumElim f g = mapDomain Sum.inl f + mapDomain Sum.inr g := by - ext (_ | _) <;> simp [mapDomain_notin_range, Sum.inl_injective, Sum.inr_injective] + ext (_ | _) <;> simp [mapDomain_of_notMem_range, Sum.inl_injective, Sum.inr_injective] @[simp] lemma mapDomain_swap_sumElim [AddCommMonoid M] (f : α →₀ M) (g : β →₀ M) : mapDomain Sum.swap (sumElim f g) = sumElim g f := by @@ -1224,7 +1226,7 @@ theorem extendDomain_eq_embDomain_subtype (f : Subtype P →₀ M) : by_cases h : P a · refine Eq.trans ?_ (embDomain_apply_self (.subtype P) f (Subtype.mk a h)).symm simp [h] - · rw [embDomain_notin_range] <;> simp [*] + · rw [embDomain_of_notMem_range] <;> simp [*] theorem support_extendDomain_subset (f : Subtype P →₀ M) : ↑(f.extendDomain).support ⊆ {x | P x} := by diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 7e9bf12623e815..149e198bc4b4dc 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -437,9 +437,11 @@ theorem embDomain_apply_self (f : α ↪ β) (v : α →₀ M) (a : α) : embDom grind @[grind =>] -theorem embDomain_notin_range (f : α ↪ β) (v : α →₀ M) (a : β) (h : a ∉ Set.range f) : +theorem embDomain_of_notMem_range (f : α ↪ β) (v : α →₀ M) (a : β) (h : a ∉ Set.range f) : embDomain f v a = 0 := by grind [embDomain] +@[deprecated (since := "2026-07-15")] alias embDomain_notin_range := embDomain_of_notMem_range + theorem embDomain_injective (f : α ↪ β) : Function.Injective (embDomain f : (α →₀ M) → β →₀ M) := fun l₁ l₂ h => ext fun a => by simpa only [embDomain_apply_self] using DFunLike.ext_iff.1 h (f a) diff --git a/Mathlib/Data/Finsupp/Option.lean b/Mathlib/Data/Finsupp/Option.lean index 53a2921070925f..3ac4384db4ae11 100644 --- a/Mathlib/Data/Finsupp/Option.lean +++ b/Mathlib/Data/Finsupp/Option.lean @@ -90,7 +90,7 @@ theorem some_single_some (a : α) (m : M) : ext; rw [some_apply]; exact embDomain_apply_self _ _ _ @[simp] lemma embDomain_some_none (f : α →₀ M) : f.embDomain .some .none = 0 := - embDomain_notin_range _ _ _ (by simp) + embDomain_of_notMem_range _ _ _ (by simp) @[simp] theorem embDomain_some_some (f : α →₀ M) (x) : f.embDomain .some (.some x) = f x := by diff --git a/Mathlib/Data/Finsupp/Order.lean b/Mathlib/Data/Finsupp/Order.lean index e52e5480e00e83..a8e477592f73e4 100644 --- a/Mathlib/Data/Finsupp/Order.lean +++ b/Mathlib/Data/Finsupp/Order.lean @@ -291,7 +291,7 @@ lemma mapDomain_tsub {f : ι → κ} (h : f.Injective) (f1 f2 : ι →₀ α) : (f1 - f2).mapDomain f = f1.mapDomain f - f2.mapDomain f := by ext y by_cases! hy : y ∉ Set.range f - · simp [mapDomain_notin_range _ _ hy] + · simp [mapDomain_of_notMem_range _ _ hy] · obtain ⟨x, rfl⟩ := hy simp [mapDomain_apply h] diff --git a/Mathlib/Data/Finsupp/Sigma.lean b/Mathlib/Data/Finsupp/Sigma.lean index 00f6d15913d811..faf3843ba3a4b6 100644 --- a/Mathlib/Data/Finsupp/Sigma.lean +++ b/Mathlib/Data/Finsupp/Sigma.lean @@ -53,7 +53,7 @@ theorem embSigma_apply [DecidableEq κ] {k : κ} (f : ι k →₀ M) (i : Σ k, simp only [embSigma, Embedding.sigmaMk] apply embDomain_apply_self · simp only [embSigma, Embedding.sigmaMk] - rw [embDomain_notin_range] + rw [embDomain_of_notMem_range] simp_all @[simp] @@ -65,7 +65,7 @@ theorem embSigma_apply_self {k : κ} (f : ι k →₀ M) (i : ι k) : /-- Values of `embSigma f` at indices outside the `k`-th summand are zero. -/ theorem embSigma_apply_of_ne {k k' : κ} (f : ι k →₀ M) (hk : k' ≠ k) (i : ι k') : embSigma f ⟨k', i⟩ = 0 := by - apply embDomain_notin_range + apply embDomain_of_notMem_range grind @[simp, grind =] diff --git a/Mathlib/Data/List/ToFinsupp.lean b/Mathlib/Data/List/ToFinsupp.lean index d7499e9849650d..fcbf2a46e23a27 100644 --- a/Mathlib/Data/List/ToFinsupp.lean +++ b/Mathlib/Data/List/ToFinsupp.lean @@ -99,7 +99,7 @@ theorem toFinsupp_append {R : Type*} [AddZeroClass R] (l₁ l₂ : List R) simp only [toFinsupp_apply, Finsupp.add_apply] cases lt_or_ge n l₁.length with | inl h => - rw [getD_append _ _ _ _ h, Finsupp.embDomain_notin_range, add_zero] + rw [getD_append _ _ _ _ h, Finsupp.embDomain_of_notMem_range, add_zero] rintro ⟨k, rfl : length l₁ + k = n⟩ lia | inr h => diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index 7bb848e62593c1..f434a77292e179 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -552,7 +552,7 @@ lemma toComp_toAlgHom_monomial (Q : Generators S T ι') (P : Generators R S ι) simp [rename_eq_aeval] rfl · ext f (i₁ | i₂) <;> - simp [Finsupp.mapDomain_notin_range, Finsupp.mapDomain_apply Sum.inr_injective] + simp [Finsupp.mapDomain_of_notMem_range, Finsupp.mapDomain_apply Sum.inr_injective] @[simp] lemma toAlgHom_ofComp_rename (Q : Generators S T ι') (P : Generators R S ι) (p : P.Ring) : diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index df89ccf3746cfc..e8381abf4fcd3d 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -297,7 +297,7 @@ theorem embDomain_add (f : Γ ↪o Γ') (x y : R⟦Γ⟧) : by_cases hg : g ∈ Set.range f · obtain ⟨a, rfl⟩ := hg simp - · simp [embDomain_notin_range hg] + · simp [embDomain_of_notMem_range hg] end Domain @@ -537,7 +537,7 @@ theorem embDomain_smul (f : Γ ↪o Γ') (r : R) (x : R⟦Γ⟧) : by_cases hg : g ∈ Set.range f · obtain ⟨a, rfl⟩ := hg simp - · simp [embDomain_notin_range hg] + · simp [embDomain_of_notMem_range hg] /-- Extending the domain of Hahn series is a linear map. -/ @[simps] diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index c4b2a64e471f73..42f8cb6ea4ff47 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -473,10 +473,12 @@ theorem support_embDomain_subset {f : Γ ↪o Γ'} {x : R⟦Γ⟧} : contrapose hg rw [mem_support, embDomain_notin_image_support hg, Classical.not_not] -theorem embDomain_notin_range {f : Γ ↪o Γ'} {x : R⟦Γ⟧} {b : Γ'} (hb : b ∉ Set.range f) : +theorem embDomain_of_notMem_range {f : Γ ↪o Γ'} {x : R⟦Γ⟧} {b : Γ'} (hb : b ∉ Set.range f) : (embDomain f x).coeff b = 0 := embDomain_notin_image_support fun con => hb (Set.image_subset_range _ _ con) +@[deprecated (since := "2026-07-15")] alias embDomain_notin_range := embDomain_of_notMem_range + @[simp] theorem embDomain_zero {f : Γ ↪o Γ'} : embDomain f (0 : R⟦Γ⟧) = 0 := by ext diff --git a/Mathlib/RingTheory/HahnSeries/Lex.lean b/Mathlib/RingTheory/HahnSeries/Lex.lean index bd86c3046f4539..8664bb6b893ab8 100644 --- a/Mathlib/RingTheory/HahnSeries/Lex.lean +++ b/Mathlib/RingTheory/HahnSeries/Lex.lean @@ -396,7 +396,7 @@ def embDomainOrderEmbedding [Zero R] : Lex R⟦Γ⟧ ↪o Lex R⟦Γ'⟧ where · rintro (⟨i, hj, hi⟩ | heq) · have himem : i ∈ Set.range f := by contrapose hi - simp [embDomain_notin_range hi] + simp [embDomain_of_notMem_range hi] obtain ⟨k, rfl⟩ := himem refine Or.inl ⟨k, fun j hjk ↦ ?_, by simpa using hi⟩ simpa using hj (f j) (f.lt_iff_lt.mpr hjk) @@ -406,7 +406,7 @@ def embDomainOrderEmbedding [Zero R] : Lex R⟦Γ⟧ ↪o Lex R⟦Γ'⟧ where by_cases hkmem : k ∈ Set.range f · obtain ⟨j', rfl⟩ := hkmem simpa using hj _ <| f.lt_iff_lt.mp hki - · simp_rw [embDomain_notin_range hkmem] + · simp_rw [embDomain_of_notMem_range hkmem] · simp /-- `HahnSeries.embDomain` as an `OrderAddMonoidHom`. -/ diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 910f8186cdf59c..08754b5adb0d16 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -883,7 +883,7 @@ theorem embDomain_mul [NonUnitalNonAssocSemiring R] (f : Γ ↪o Γ') simp only [mem_antidiagonal, embDomain_coeff, mem_support, ← hf, OrderEmbedding.eq_iff_eq] at h1 exact ⟨i, j, h1, rfl⟩ - · rw [embDomain_notin_range hg, eq_comm] + · rw [embDomain_of_notMem_range hg, eq_comm] contrapose! hg obtain ⟨_, hi, _, hj, rfl⟩ := support_mul_subset ((mem_support _ _).2 hg) obtain ⟨i, _, rfl⟩ := support_embDomain_subset hi diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index f33baf323acfe1..ab56f54f4b5965 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -641,9 +641,11 @@ theorem embDomain_image : s.embDomain f (f a) = s a := by exact congr rfl (f.injective (Classical.choose_spec (Set.mem_range_self a))) @[simp] -theorem embDomain_notin_range (h : b ∉ Set.range f) : s.embDomain f b = 0 := by +theorem embDomain_of_notMem_range (h : b ∉ Set.range f) : s.embDomain f b = 0 := by rw [embDomain_apply, dif_neg h] +@[deprecated (since := "2026-07-15")] alias embDomain_notin_range := embDomain_of_notMem_range + @[simp] theorem hsum_embDomain : (s.embDomain f).hsum = s.hsum := by classical diff --git a/Mathlib/RingTheory/IsAdjoinRoot.lean b/Mathlib/RingTheory/IsAdjoinRoot.lean index 9030176eeab859..b6e031fb808da2 100644 --- a/Mathlib/RingTheory/IsAdjoinRoot.lean +++ b/Mathlib/RingTheory/IsAdjoinRoot.lean @@ -438,7 +438,7 @@ def basis : Basis (Fin (natDegree f)) R S where rw [degree_eq_natDegree h.monic.ne_zero, degree_lt_iff_coeff_zero] intro m hm rw [Polynomial.coeff] - rw [Finsupp.mapDomain_notin_range] + rw [Finsupp.mapDomain_of_notMem_range] rw [Set.mem_range, not_exists] rintro i rfl exact i.prop.not_ge hm diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index c2a5dd1a22e4be..0f63f96ec0b8ab 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -242,7 +242,7 @@ theorem single_order_mul_powerSeriesPart (x : R⸨X⸩) : · rw [Int.eq_natAbs_of_nonneg (sub_nonneg_of_le h), coeff_coe_powerSeries, powerSeriesPart_coeff, ← Int.eq_natAbs_of_nonneg (sub_nonneg_of_le h), add_sub_cancel] - · rw [ofPowerSeries_apply, embDomain_notin_range] + · rw [ofPowerSeries_apply, embDomain_of_notMem_range] · contrapose! h exact order_le_of_coeff_ne_zero h.symm · contrapose h @@ -614,7 +614,7 @@ theorem val_le_one_iff_eq_coe (f : K⸨X⸩) : Valued.v f ≤ (1 : ℤᵐ⁰) on_goal 1 => simp only [h (Int.negSucc n) (Int.negSucc_lt_zero n)] on_goal 2 => rintro ⟨F, rfl⟩ _ _ all_goals - apply HahnSeries.embDomain_notin_range + apply HahnSeries.embDomain_of_notMem_range simp only [Nat.coe_castAddMonoidHom, RelEmbedding.coe_mk, Function.Embedding.coeFn_mk, Set.mem_range, not_exists, reduceCtorEq] intro From 3d71751c074b0a80427569e4ab311fbcd5cf3cd6 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Wed, 15 Jul 2026 16:59:03 +0000 Subject: [PATCH 0806/1300] feat(Order/RelIso/Basic): lift a function to an order morphism into `Relation.Map` or from `Function.onFun` (#38498) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For an `α`-relation `r` we have: ``` RelHom.toMap (f : α → β) : r →r Relation.Map r f f RelEmbedding.toMap (f : α ↪ β) : r ↪r Relation.Map r f f RelIso.toMap (f : α ≃ β) : r ≃r Relation.Map r f f ``` For a `β`-relation `r` we have: ``` RelHom.ofOnFun (f : α → β) : r.onFun f →r r RelEmbedding.ofOnFun (f : α ↪ β) : r.onFun f ↪r r RelIso.ofOnFun (f : α ≃ β) : r.onFun f ≃r r ``` --- Mathlib/Order/RelIso/Basic.lean | 87 +++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/Mathlib/Order/RelIso/Basic.lean b/Mathlib/Order/RelIso/Basic.lean index 97570a33df5ec1..dfa611212be01c 100644 --- a/Mathlib/Order/RelIso/Basic.lean +++ b/Mathlib/Order/RelIso/Basic.lean @@ -873,3 +873,90 @@ def ofUniqueOfRefl (r : α → α → Prop) (s : β → β → Prop) [Std.Refl r ⟨Equiv.ofUnique α β, iff_of_true (rel_of_subsingleton s _ _) (rel_of_subsingleton r _ _)⟩ end RelIso + +/-- A function `f : α → β` induces a relation homomorphism from an `α`-relation `r` to +`Relation.Map r f f`. -/ +def RelHom.toMap (r : α → α → Prop) (f : α → β) : r →r Relation.Map r f f where + toFun := f + map_rel' {a b} hr := ⟨a, b, hr, rfl, rfl⟩ + +@[simp] +theorem RelHom.coe_toMap (r : α → α → Prop) (f : α → β) : ⇑(RelHom.toMap r f) = f := + rfl + +/-- An embedding `f : α ↪ β` induces a relation embedding from an `α`-relation `r` to +`Relation.Map r f f`. -/ +def RelEmbedding.toMap (r : α → α → Prop) (f : α ↪ β) : r ↪r Relation.Map r f f where + __ := f + map_rel_iff' {a b} := by grind [Relation.onFun_map_eq_of_injective (r := r) f.injective] + +@[simp] +theorem RelEmbedding.coe_toMap (r : α → α → Prop) (f : α ↪ β) : ⇑(RelEmbedding.toMap r f) = f := + rfl + +/-- An equivalence `f : α ≃ β` induces a relation isomorphism from an `α`-relation `r` to +`Relation.Map r f f`. -/ +def RelIso.toMap (r : α → α → Prop) (f : α ≃ β) : r ≃r Relation.Map r f f where + __ := f + __ := RelEmbedding.toMap r f.toEmbedding + +@[simp] +theorem RelIso.coe_toMap (r : α → α → Prop) (f : α ≃ β) : ⇑(RelIso.toMap r f) = f := + rfl + +@[simp] +theorem RelIso.toEquiv_toMap (r : α → α → Prop) (f : α ≃ β) : RelIso.toMap r f = f := + rfl + +@[simp] +theorem RelIso.coe_symm_toMap (r : α → α → Prop) (f : α ≃ β) : ⇑(RelIso.toMap r f).symm = f.symm := + rfl + +@[simp] +theorem RelIso.toEquiv_symm_toMap (r : α → α → Prop) (f : α ≃ β) : + (RelIso.toMap r f).symm = f.symm := + rfl + +/-- For a `β`-relation `r`, a function `f : α → β` induces a relation homomorphism from `r.onFun f` +to `r`. -/ +def RelHom.ofOnFun (r : β → β → Prop) (f : α → β) : r.onFun f →r r where + toFun := f + map_rel' := id + +@[simp] +theorem RelHom.coe_ofOnFun (r : β → β → Prop) (f : α → β) : ⇑(RelHom.ofOnFun r f) = f := + rfl + +/-- For a `β`-relation `r`, an embedding `f : α ↪ β` induces a relation embedding from `r.onFun f` +to `r`. -/ +def RelEmbedding.ofOnFun (r : β → β → Prop) (f : α ↪ β) : r.onFun f ↪r r where + __ := f + map_rel_iff' := by rfl + +@[simp] +theorem RelEmbedding.coe_ofOnFun (r : β → β → Prop) (f : α ↪ β) : ⇑(RelEmbedding.ofOnFun r f) = f := + rfl + +/-- For a `β`-relation `r`, an equivalence `f : α ≃ β` induces a relation isomorphism from +`r.onFun f` to `r`. -/ +def RelIso.ofOnFun (r : β → β → Prop) (f : α ≃ β) : r.onFun f ≃r r where + __ := f + __ := RelEmbedding.ofOnFun r f.toEmbedding + +@[simp] +theorem RelIso.coe_ofOnFun (r : β → β → Prop) (f : α ≃ β) : ⇑(RelIso.ofOnFun r f) = f := + rfl + +@[simp] +theorem RelIso.toEquiv_ofOnFun (r : β → β → Prop) (f : α ≃ β) : RelIso.ofOnFun r f = f := + rfl + +@[simp] +theorem RelIso.coe_symm_ofOnFun (r : β → β → Prop) (f : α ≃ β) : + ⇑(RelIso.ofOnFun r f).symm = f.symm := + rfl + +@[simp] +theorem RelIso.toEquiv_symm_ofOnFun (r : β → β → Prop) (f : α ≃ β) : + (RelIso.ofOnFun r f).symm = f.symm := + rfl From 5ad5d522861eea75dec2770e6862e069564a5066 Mon Sep 17 00:00:00 2001 From: Jeremy Tan Jie Rui <54175463+Parcly-Taxel@users.noreply.github.com> Date: Wed, 15 Jul 2026 16:59:05 +0000 Subject: [PATCH 0807/1300] chore: delete deprecated declarations to the end of 2025 (#41178) The automated commits were made by running ``` #clear_deprecations "2025-11-01" "2025-12-31" really ``` (I had to do this in multiple sessions because VS Code kept running out of memory.) Co-authored-by: Parcly Taxel Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 1 - Mathlib/Algebra/Algebra/Basic.lean | 10 - Mathlib/Algebra/Algebra/Bilinear.lean | 3 - Mathlib/Algebra/Algebra/Defs.lean | 8 - Mathlib/Algebra/Algebra/Equiv.lean | 2 - .../Algebra/BigOperators/Finsupp/Basic.lean | 4 - .../Algebra/Category/FGModuleCat/Basic.lean | 3 - .../Category/Ring/FinitePresentation.lean | 10 - Mathlib/Algebra/DirectSum/Module.lean | 14 -- .../Group/Action/Pointwise/Set/Basic.lean | 15 -- Mathlib/Algebra/Group/Hom/Defs.lean | 3 - Mathlib/Algebra/Group/Indicator.lean | 3 - .../Group/Irreducible/Indecomposable.lean | 4 - Mathlib/Algebra/Group/Units/Defs.lean | 2 - Mathlib/Algebra/Module/LinearMap/Defs.lean | 4 - Mathlib/Algebra/Module/Submodule/Ker.lean | 3 - .../Algebra/Module/Submodule/LinearMap.lean | 3 - Mathlib/Algebra/MvPolynomial/Equiv.lean | 6 - Mathlib/Algebra/Order/AddGroupWithTop.lean | 14 -- Mathlib/Algebra/Order/Archimedean/Class.lean | 23 -- Mathlib/Algebra/Order/Field/Defs.lean | 16 -- Mathlib/Algebra/Order/Floor/Ring.lean | 6 - .../Order/GroupWithZero/Canonical.lean | 12 - Mathlib/Algebra/Order/IsBotOne.lean | 2 - Mathlib/Algebra/Order/Module/Archimedean.lean | 81 ------- .../Algebra/Order/Monoid/Unbundled/Basic.lean | 6 - .../Order/Monoid/Unbundled/TypeTags.lean | 2 - Mathlib/Algebra/Order/Ring/StandardPart.lean | 3 - Mathlib/Algebra/Polynomial/Bivariate.lean | 8 - Mathlib/Algebra/Polynomial/Derivative.lean | 3 - Mathlib/Algebra/Polynomial/Expand.lean | 6 - Mathlib/Algebra/Polynomial/Roots.lean | 2 - Mathlib/Algebra/Polynomial/Splits.lean | 229 ------------------ Mathlib/Algebra/QuadraticAlgebra/Basic.lean | 9 - Mathlib/Algebra/QuadraticAlgebra/Defs.lean | 48 ---- Mathlib/Algebra/Quotient.lean | 6 - Mathlib/Algebra/Ring/Equiv.lean | 8 - Mathlib/Algebra/Star/LinearMap.lean | 6 - .../GeneratorsRelations/NormalForms.lean | 2 - Mathlib/Analysis/Analytic/Binomial.lean | 15 -- Mathlib/Analysis/Analytic/OfScalars.lean | 3 - .../CStarAlgebra/Unitary/Connected.lean | 3 - .../BumpFunction/FiniteDimension.lean | 6 - Mathlib/Analysis/Calculus/Deriv/Basic.lean | 6 - Mathlib/Analysis/Calculus/Deriv/Mul.lean | 2 - Mathlib/Analysis/Complex/Basic.lean | 5 - .../CharacteristicFunction.lean | 10 - .../ValueDistribution/LogCounting/Basic.lean | 12 - .../ValueDistribution/Proximity/Basic.lean | 4 - .../Distribution/AEEqOfIntegralContDiff.lean | 14 -- .../Distribution/SchwartzSpace/Deriv.lean | 24 -- .../Distribution/SchwartzSpace/Fourier.lean | 6 - .../Distribution/TemperedDistribution.lean | 9 - .../Analysis/Distribution/TestFunction.lean | 4 - .../Analysis/Fourier/FourierTransform.lean | 39 --- .../Fourier/FourierTransformDeriv.lean | 39 --- Mathlib/Analysis/Fourier/Inversion.lean | 13 - Mathlib/Analysis/Fourier/LpSpace.lean | 6 - .../Analysis/Fourier/PoissonSummation.lean | 14 -- .../Fourier/RiemannLebesgueLemma.lean | 3 - .../Analysis/InnerProductSpace/Adjoint.lean | 6 - Mathlib/Analysis/InnerProductSpace/Basic.lean | 3 - .../Analysis/InnerProductSpace/Laplacian.lean | 3 - .../InnerProductSpace/Orthogonal.lean | 3 - Mathlib/Analysis/InnerProductSpace/PiL2.lean | 3 - .../Projection/Submodule.lean | 9 - .../Analysis/InnerProductSpace/Symmetric.lean | 4 - Mathlib/Analysis/Matrix/Order.lean | 3 - Mathlib/Analysis/MellinInversion.lean | 9 - Mathlib/Analysis/Meromorphic/Basic.lean | 29 --- Mathlib/Analysis/Normed/Field/Lemmas.lean | 13 - Mathlib/Analysis/Normed/Field/WithAbs.lean | 70 ------ Mathlib/Analysis/Normed/Group/Continuity.lean | 5 - Mathlib/Analysis/Normed/Lp/ProdLp.lean | 2 - .../Normed/Operator/LinearIsometry.lean | 8 - .../Analysis/Polynomial/MahlerMeasure.lean | 3 - .../Gaussian/FourierTransform.lean | 14 -- Mathlib/CategoryTheory/Abelian/Basic.lean | 2 - .../Abelian/SerreClass/Bousfield.lean | 4 - .../CategoryTheory/EffectiveEpi/Basic.lean | 2 - .../Functor/KanExtension/DenseAt.lean | 3 - Mathlib/CategoryTheory/Groupoid.lean | 6 - .../CategoryTheory/Limits/ExactFunctor.lean | 6 - .../Limits/Shapes/Multiequalizer.lean | 9 - .../Limits/Shapes/RegularMono.lean | 13 - .../Localization/Bousfield.lean | 24 -- .../PointwiseRightDerived.lean | 3 - .../CategoryTheory/Localization/Opposite.lean | 2 - .../Monoidal/Braided/Basic.lean | 6 - .../Monoidal/Cartesian/Grp.lean | 4 - .../Monoidal/Closed/Cartesian.lean | 83 ------- Mathlib/CategoryTheory/Monoidal/CommGrp_.lean | 6 - .../Monoidal/FunctorCategory.lean | 9 - Mathlib/CategoryTheory/Monoidal/Grp.lean | 21 -- .../Monoidal/OfHasFiniteProducts.lean | 66 ----- .../CategoryTheory/Monoidal/Subcategory.lean | 2 - .../ObjectProperty/FullSubcategory.lean | 3 - .../Preadditive/AdditiveFunctor.lean | 7 - .../Presentable/OrthogonalReflection.lean | 3 - Mathlib/CategoryTheory/Quotient.lean | 12 - .../Sites/Coherent/RegularSheaves.lean | 2 - .../CategoryTheory/Sites/Localization.lean | 3 - .../CategoryTheory/Sites/Subcanonical.lean | 3 - Mathlib/CategoryTheory/Sites/Subsheaf.lean | 33 --- Mathlib/CategoryTheory/Skeletal.lean | 3 - Mathlib/CategoryTheory/Subfunctor/Basic.lean | 22 -- .../CategoryTheory/Subfunctor/Equalizer.lean | 18 -- Mathlib/CategoryTheory/Subfunctor/Finite.lean | 20 -- Mathlib/CategoryTheory/Subfunctor/Image.lean | 27 --- .../CategoryTheory/Subfunctor/OfSection.lean | 9 - Mathlib/CategoryTheory/Subfunctor/Sieves.lean | 6 - .../CategoryTheory/Subfunctor/Subobject.lean | 6 - Mathlib/CategoryTheory/Subobject/Basic.lean | 3 - .../Subobject/Classifier/Defs.lean | 5 - .../CategoryTheory/Subobject/MonoOver.lean | 10 - .../Triangulated/Opposite/Basic.lean | 5 - Mathlib/CategoryTheory/Yoneda.lean | 19 -- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 3 - Mathlib/Combinatorics/SimpleGraph/Metric.lean | 5 - .../SimpleGraph/Walk/Traversal.lean | 10 - Mathlib/Computability/NFA.lean | 12 - Mathlib/Data/DFinsupp/Lex.lean | 9 - Mathlib/Data/ENat/Basic.lean | 3 - Mathlib/Data/Finset/Basic.lean | 4 - Mathlib/Data/Finset/Card.lean | 3 - Mathlib/Data/Finset/NoncommProd.lean | 6 - Mathlib/Data/Finset/Sort.lean | 4 - Mathlib/Data/Finsupp/Basic.lean | 3 - Mathlib/Data/Finsupp/Interval.lean | 3 - Mathlib/Data/Finsupp/Lex.lean | 9 - Mathlib/Data/Finsupp/Weight.lean | 7 - Mathlib/Data/Fintype/Card.lean | 6 - .../Data/Int/ConditionallyCompleteOrder.lean | 8 - Mathlib/Data/Int/Fib/Basic.lean | 3 - Mathlib/Data/List/Chain.lean | 13 - Mathlib/Data/List/Cycle.lean | 9 - Mathlib/Data/List/GetD.lean | 2 - Mathlib/Data/List/Sort.lean | 40 --- Mathlib/Data/Nat/Choose/Basic.lean | 4 - Mathlib/Data/Rat/Lemmas.lean | 8 - Mathlib/Data/Rel/Cover.lean | 2 - Mathlib/Data/Set/Basic.lean | 2 - Mathlib/Data/Sym/Sym2.lean | 15 -- Mathlib/Dynamics/Ergodic/Ergodic.lean | 3 - .../IntermediateField/Adjoin/Algebra.lean | 17 -- Mathlib/FieldTheory/IsAlgClosed/Basic.lean | 12 - Mathlib/FieldTheory/IsSepClosed.lean | 3 - Mathlib/FieldTheory/Normal/Closure.lean | 2 - Mathlib/FieldTheory/SeparableClosure.lean | 4 - Mathlib/FieldTheory/SeparableDegree.lean | 4 - .../Angle/Unoriented/TriangleInequality.lean | 2 - Mathlib/Geometry/Manifold/Immersion.lean | 8 - .../Geometry/Manifold/IsManifold/Basic.lean | 6 - .../Geometry/Manifold/LocalDiffeomorph.lean | 3 - .../Geometry/Manifold/PartitionOfUnity.lean | 48 ---- .../Manifold/VectorBundle/LocalFrame.lean | 3 - .../Geometry/RingedSpace/OpenImmersion.lean | 3 - .../Geometry/RingedSpace/SheafedSpace.lean | 8 - .../GroupAction/MultipleTransitivity.lean | 13 - Mathlib/GroupTheory/OrderOfElement.lean | 3 - Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 4 - Mathlib/GroupTheory/Perm/Finite.lean | 11 - .../GroupTheory/Perm/MaximalSubgroups.lean | 10 - Mathlib/GroupTheory/Perm/Support.lean | 2 - .../GroupTheory/SpecificGroups/Cyclic.lean | 3 - .../FiniteDimensional/Basic.lean | 12 - .../LinearAlgebra/Matrix/SemiringInverse.lean | 32 --- Mathlib/LinearAlgebra/RootSystem/Basic.lean | 4 - Mathlib/LinearAlgebra/RootSystem/Defs.lean | 5 - .../RootSystem/Finite/Nondegenerate.lean | 6 - Mathlib/LinearAlgebra/Span/Basic.lean | 5 - Mathlib/Logic/Relation.lean | 2 - .../Function/L1Space/Integrable.lean | 2 - .../MeasureTheory/MeasurableSpace/Card.lean | 6 - Mathlib/MeasureTheory/Measure/Doubling.lean | 3 - Mathlib/MeasureTheory/Measure/Real.lean | 2 - .../Measure/RegularityCompacts.lean | 4 - Mathlib/MeasureTheory/Measure/Tight.lean | 4 - Mathlib/NumberTheory/Bernoulli.lean | 3 - Mathlib/NumberTheory/Divisors.lean | 6 - Mathlib/NumberTheory/ModularForms/Basic.lean | 6 - .../EisensteinSeries/Summable.lean | 5 - .../ModularForms/SlashInvariantForms.lean | 4 - .../NumberField/Cyclotomic/Basic.lean | 20 -- .../NumberField/Cyclotomic/Ideal.lean | 13 - .../Padics/HeightOneSpectrum.lean | 2 - Mathlib/Order/Atoms.lean | 5 - Mathlib/Order/Basic.lean | 12 - Mathlib/Order/BoundedOrder/Basic.lean | 10 - Mathlib/Order/Category/FinPartOrd.lean | 8 - Mathlib/Order/Category/NonemptyFinLinOrd.lean | 6 - .../MulticoequalizerDiagram.lean | 5 - Mathlib/Order/Defs/Unbundled.lean | 7 - Mathlib/Order/Interval/Set/Basic.lean | 18 -- Mathlib/Order/Monotone/Defs.lean | 8 - Mathlib/Order/PiLex.lean | 6 - Mathlib/Order/RelSeries.lean | 8 - Mathlib/Order/SetAccumulate.lean | 2 - Mathlib/Order/SuccPred/Basic.lean | 16 -- Mathlib/Order/SuccPred/Limit.lean | 3 - Mathlib/Order/WithBot.lean | 24 -- Mathlib/Probability/Moments/Covariance.lean | 3 - Mathlib/Probability/Moments/Variance.lean | 2 - Mathlib/RepresentationTheory/FDRep.lean | 2 - .../GroupCohomology/Functoriality.lean | 3 - Mathlib/RingTheory/AlgebraTower.lean | 3 - Mathlib/RingTheory/DividedPowers/Padic.lean | 3 - Mathlib/RingTheory/Etale/Basic.lean | 8 - .../Flat/FaithfullyFlat/Algebra.lean | 7 - Mathlib/RingTheory/HahnSeries/Basic.lean | 4 - .../RingTheory/HahnSeries/Multiplication.lean | 3 - .../Ideal/AssociatedPrime/Basic.lean | 3 - .../Ideal/AssociatedPrime/Localization.lean | 4 - .../LocalRing/ResidueField/Fiber.lean | 3 - .../LocalRing/ResidueField/Ideal.lean | 3 - Mathlib/RingTheory/MvPolynomial/Expand.lean | 6 - .../MvPolynomial/MonomialOrder.lean | 4 - Mathlib/RingTheory/PicardGroup.lean | 8 - .../Polynomial/IntegralNormalization.lean | 3 - Mathlib/RingTheory/Polynomial/ScaleRoots.lean | 2 - .../SimpleModule/WedderburnArtin.lean | 4 - Mathlib/RingTheory/Smooth/Basic.lean | 3 - .../RingTheory/Spectrum/Prime/RingHom.lean | 33 --- .../RingTheory/Spectrum/Prime/Topology.lean | 12 - .../Valuation/ValuativeRel/Basic.lean | 118 --------- Mathlib/SetTheory/Cardinal/Aleph.lean | 15 -- .../Cardinal/Cofinality/Ordinal.lean | 6 - Mathlib/SetTheory/Cardinal/Regular.lean | 3 - Mathlib/SetTheory/Ordinal/Arithmetic.lean | 121 --------- Mathlib/SetTheory/Ordinal/Basic.lean | 24 -- Mathlib/SetTheory/Ordinal/Exponential.lean | 3 - Mathlib/SetTheory/Ordinal/Family.lean | 41 ---- Mathlib/SetTheory/Ordinal/FixedPoint.lean | 12 - .../Ordinal/FundamentalSequence.lean | 3 - Mathlib/SetTheory/Ordinal/Veblen.lean | 6 - Mathlib/Tactic/Basic.lean | 10 - Mathlib/Topology/Algebra/Algebra.lean | 3 - .../Algebra/InfiniteSum/ConditionalInt.lean | 8 - .../Algebra/InfiniteSum/UniformOn.lean | 6 - .../Module/ContinuousLinearMap/Basic.lean | 13 - .../ContinuousLinearMap/Idempotent.lean | 5 - .../Topology/Algebra/Module/Determinant.lean | 2 - .../Algebra/Module/FiniteDimension.lean | 10 - Mathlib/Topology/Category/UniformSpace.lean | 2 - .../Compactification/OnePoint/Basic.lean | 3 - .../Topology/ContinuousMap/Bounded/Basic.lean | 9 - Mathlib/Topology/DiscreteSubset.lean | 3 - Mathlib/Topology/Homotopy/Lifting.lean | 3 - Mathlib/Topology/IsLocalHomeomorph.lean | 2 - Mathlib/Topology/MetricSpace/Closeds.lean | 16 -- Mathlib/Topology/MetricSpace/PiNat.lean | 4 - Mathlib/Topology/NoetherianSpace.lean | 6 - Mathlib/Topology/Semicontinuity/Basic.lean | 18 -- Mathlib/Topology/Sequences.lean | 6 - Mathlib/Topology/Sets/Closeds.lean | 8 - Mathlib/Topology/UniformSpace/Closeds.lean | 2 - .../UniformSpace/DiscreteUniformity.lean | 10 - 257 files changed, 2780 deletions(-) delete mode 100644 Mathlib/Algebra/Order/Field/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index 5868d1305017c9..b77bb17d48d817 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -953,7 +953,6 @@ public import Mathlib.Algebra.Order.CompleteField public import Mathlib.Algebra.Order.Disjointed public import Mathlib.Algebra.Order.Field.Basic public import Mathlib.Algebra.Order.Field.Canonical -public import Mathlib.Algebra.Order.Field.Defs public import Mathlib.Algebra.Order.Field.GeomSum public import Mathlib.Algebra.Order.Field.Pi public import Mathlib.Algebra.Order.Field.Pointwise diff --git a/Mathlib/Algebra/Algebra/Basic.lean b/Mathlib/Algebra/Algebra/Basic.lean index 7888df545f1144..81ec13d6fbf7c0 100644 --- a/Mathlib/Algebra/Algebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Basic.lean @@ -117,16 +117,6 @@ theorem algebraMap_ofSubring {R : Type*} [CommRing R] (S : Subring R) : (algebraMap S R : S →+* R) = S.subtype := rfl -@[deprecated coe_algebraMap_ofSubsemiring (since := "2025-11-23")] -theorem coe_algebraMap_ofSubring {R : Type*} [CommRing R] (S : Subring R) : - (algebraMap S R : S → R) = Subtype.val := - rfl - -@[deprecated algebraMap_ofSubsemiring_apply (since := "2025-11-23")] -theorem algebraMap_ofSubring_apply {R : Type*} [CommRing R] (S : Subring R) (x : S) : - algebraMap S R x = x := - rfl - end SubsemiringAlgebra /-- Explicit characterization of the submonoid map in the case of an algebra. diff --git a/Mathlib/Algebra/Algebra/Bilinear.lean b/Mathlib/Algebra/Algebra/Bilinear.lean index 06665102ef2301..9ff4db4ac00bc2 100644 --- a/Mathlib/Algebra/Algebra/Bilinear.lean +++ b/Mathlib/Algebra/Algebra/Bilinear.lean @@ -162,9 +162,6 @@ theorem _root_.Algebra.lmul_isUnit_iff {x : A} : theorem toSpanSingleton_one_eq_algebraLinearMap : toSpanSingleton R A 1 = Algebra.linearMap R A := by ext; simp -@[deprecated (since := "2025-12-30")] alias toSpanSingleton_eq_algebra_linearMap := - toSpanSingleton_one_eq_algebraLinearMap - variable (R A) in /-- The multiplication map on an `R`-algebra, as an `A`-linear map from `A ⊗[R] A` to `A`. -/ @[simps!] def mul'' : A ⊗[R] A →ₗ[A] A where diff --git a/Mathlib/Algebra/Algebra/Defs.lean b/Mathlib/Algebra/Algebra/Defs.lean index 4e90e559aa5317..ed95babadabe62 100644 --- a/Mathlib/Algebra/Algebra/Defs.lean +++ b/Mathlib/Algebra/Algebra/Defs.lean @@ -396,14 +396,6 @@ variable {R A} @[simp] lemma algebraMap_self : algebraMap R R = .id _ := rfl lemma algebraMap_self_apply (x : R) : algebraMap R R x = x := rfl -namespace id - -@[deprecated _root_.smul_eq_mul (since := "2025-12-02")] -theorem smul_eq_mul (x y : R) : x • y = x * y := - rfl - -end id - end Semiring end Algebra diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index 9f592f5c7127d0..583fbc391281cc 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -902,8 +902,6 @@ endomorphisms. -/ __ := e.conjRingEquiv commutes' _ := by ext; change e.restrictScalars R _ = _; simp -@[deprecated (since := "2025-12-06")] alias algConj := conjAlgEquiv - theorem conjAlgEquiv_apply (e : M₁ ≃ₗ[S] M₂) (f : Module.End S M₁) : e.conjAlgEquiv R f = e.toLinearMap ∘ₗ f ∘ₗ e.symm.toLinearMap := rfl diff --git a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean index 1369d1b6c3a9ff..2638c57300dbc9 100644 --- a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean @@ -306,10 +306,6 @@ theorem support_finsetSum [DecidableEq β] [AddCommMonoid M] {s : Finset α} {f @[deprecated (since := "2026-04-08")] alias support_finset_sum := support_finsetSum -@[deprecated sum_fun_zero (since := "2025-12-19")] -theorem sum_zero [Zero M] [AddCommMonoid N] {f : α →₀ M} : (f.sum fun _ _ => (0 : N)) = 0 := - Finset.sum_const_zero - theorem sum_eq_one_iff (d : α →₀ ℕ) : sum d (fun _ n ↦ n) = 1 ↔ ∃ a, d = single a 1 := by classical refine ⟨fun h1 ↦ ?_, ?_⟩ diff --git a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean index eefbde73cc87b9..76a11fe84b764f 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean @@ -85,9 +85,6 @@ variable (R : Type u) [Ring R] @[simp] lemma hom_hom_id (A : FGModuleCat.{v} R) : (𝟙 A : A ⟶ A).hom.hom = LinearMap.id := rfl -@[deprecated (since := "2025-12-18")] alias hom_comp := hom_hom_comp -@[deprecated (since := "2025-12-18")] alias hom_id := hom_hom_id - instance : Inhabited (FGModuleCat.{v} R) := ⟨⟨ModuleCat.of R PUnit, by unfold ModuleCat.isFG; infer_instance⟩⟩ diff --git a/Mathlib/Algebra/Category/Ring/FinitePresentation.lean b/Mathlib/Algebra/Category/Ring/FinitePresentation.lean index 4094799bcb8e31..dd6ca98e91939e 100644 --- a/Mathlib/Algebra/Category/Ring/FinitePresentation.lean +++ b/Mathlib/Algebra/Category/Ring/FinitePresentation.lean @@ -161,28 +161,18 @@ lemma CommRingCat.preservesColimit_coyoneda_of_finitePresentation f₁.right (Under.w f₁) f₂.right (Under.w f₂) congr($(e).right) exact ⟨k, hik, hjk, Under.UnderMorphism.ext e⟩ -@[deprecated (since := "2025-12-19")] -alias preservesColimit_coyoneda_of_finitePresentation := - CommRingCat.preservesColimit_coyoneda_of_finitePresentation - /-- If `S` is a finitely presented `R`-algebra, then `Hom_R(S, -)` preserves filtered colimits. -/ lemma CommRingCat.preservesFilteredColimits_coyoneda (S : Under R) (hS : S.hom.hom.FinitePresentation) : PreservesFilteredColimits (coyoneda.obj (.op S)) := ⟨fun _ _ _ ↦ ⟨preservesColimit_coyoneda_of_finitePresentation R S hS _⟩⟩ -@[deprecated (since := "2025-12-19")] -alias preservesFilteredColimits_coyoneda := CommRingCat.preservesFilteredColimits_coyoneda - /-- If `S` is a finitely presented `R`-algebra, `S : Under R` is finitely presentable. -/ lemma CommRingCat.isFinitelyPresentable_under (S : Under R) (hS : S.hom.hom.FinitePresentation) : IsFinitelyPresentable.{u} S := by rw [isFinitelyPresentable_iff_preservesFilteredColimits] exact preservesFilteredColimits_coyoneda R S hS -@[deprecated (since := "2025-12-19")] -alias isFinitelyPresentable := CommRingCat.isFinitelyPresentable_under - variable {R} in lemma CommRingCat.isFinitelyPresentable_hom {S : CommRingCat.{u}} (f : R ⟶ S) (hf : f.hom.FinitePresentation) : diff --git a/Mathlib/Algebra/DirectSum/Module.lean b/Mathlib/Algebra/DirectSum/Module.lean index fda8ef8ea3877d..59db289b58665a 100644 --- a/Mathlib/Algebra/DirectSum/Module.lean +++ b/Mathlib/Algebra/DirectSum/Module.lean @@ -577,14 +577,10 @@ def congrAddEquiv (u : (i : ι) → N i ≃+ P i) : left_inv x := by aesop right_inv y := by aesop -@[deprecated (since := "2025-12-01")] alias congr_addEquiv := congrAddEquiv - theorem coe_congrAddEquiv (u : (i : ι) → N i ≃+ P i) : ⇑(congrAddEquiv u).toAddMonoidHom = ⇑(DirectSum.map fun i ↦ (u i).toAddMonoidHom) := rfl -@[deprecated (since := "2025-12-01")] alias coe_congr_addEquiv := coe_congrAddEquiv - /-- Direct sums of isomorphic modules are isomorphic. -/ def congrLinearEquiv (u : (i : ι) → N i ≃ₗ[R] P i) : (⨁ i, N i) ≃ₗ[R] ⨁ i, P i where @@ -592,28 +588,18 @@ def congrLinearEquiv (u : (i : ι) → N i ≃ₗ[R] P i) : map_smul' r x := by exact (DirectSum.lmap (fun i ↦ (u i).toLinearMap)).map_smul r x -@[deprecated (since := "2025-12-01")] alias congr_linearEquiv := congrLinearEquiv - theorem coe_congrLinearEquiv (u : (i : ι) → N i ≃ₗ[R] P i) : ⇑(congrLinearEquiv u) = ⇑(DirectSum.lmap (fun i ↦ (u i).toLinearMap)) := rfl -@[deprecated (since := "2025-12-01")] alias coe_congr_linearEquiv := coe_congrLinearEquiv - theorem congrLinearEquiv_toAddEquiv (u : (i : ι) → N i ≃ₗ[R] P i) : (congrLinearEquiv u).toAddEquiv = congrAddEquiv (fun i ↦ (u i).toAddEquiv) := rfl -@[deprecated (since := "2025-12-01")] -alias congr_linearEquiv_toAddEquiv := congrLinearEquiv_toAddEquiv - theorem congrLinearEquiv_toLinearMap (u : (i : ι) → N i ≃ₗ[R] P i) : (congrLinearEquiv u).toLinearMap = DirectSum.lmap (fun i ↦ (u i).toLinearMap) := rfl -@[deprecated (since := "2025-12-01")] -alias congr_linearEquiv_toLinearMap := congrLinearEquiv_toLinearMap - end Congr end DirectSum diff --git a/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean index f6768197835e42..1bb6da47788c48 100644 --- a/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean @@ -272,21 +272,11 @@ theorem smul_inter_nonempty_iff {s t : Set α} {x : α} : · rintro ⟨a, b, ⟨ha, hb⟩, rfl⟩ exact ⟨a, mem_inter (mem_smul_set.mpr ⟨b, hb, by simp⟩) ha⟩ -@[to_additive (attr := deprecated smul_inter_nonempty_iff (since := "2025-12-10"))] -theorem smul_inter_ne_empty_iff {s t : Set α} {x : α} : - x • s ∩ t ≠ ∅ ↔ ∃ a b, (a ∈ t ∧ b ∈ s) ∧ a * b⁻¹ = x := by - rw [← nonempty_iff_ne_empty, smul_inter_nonempty_iff] - @[to_additive] theorem smul_inter_nonempty_iff' {s t : Set α} {x : α} : (x • s ∩ t).Nonempty ↔ ∃ a b, (a ∈ t ∧ b ∈ s) ∧ a / b = x := by simp_rw [smul_inter_nonempty_iff, div_eq_mul_inv] -@[to_additive (attr := deprecated smul_inter_nonempty_iff' (since := "2025-12-10"))] -theorem smul_inter_ne_empty_iff' {s t : Set α} {x : α} : - x • s ∩ t ≠ ∅ ↔ ∃ a b, (a ∈ t ∧ b ∈ s) ∧ a / b = x := by - rw [← nonempty_iff_ne_empty, smul_inter_nonempty_iff'] - @[to_additive] theorem op_smul_inter_nonempty_iff {s t : Set α} {x : αᵐᵒᵖ} : (x • s ∩ t).Nonempty ↔ ∃ a b, (a ∈ s ∧ b ∈ t) ∧ a⁻¹ * b = MulOpposite.unop x := by @@ -298,11 +288,6 @@ theorem op_smul_inter_nonempty_iff {s t : Set α} {x : αᵐᵒᵖ} : have : MulOpposite.op (a⁻¹ * b) = x := congr_arg MulOpposite.op H exact ⟨b, mem_inter (mem_smul_set.mpr ⟨a, ha, by simp [← this]⟩) hb⟩ -@[to_additive (attr := deprecated op_smul_inter_nonempty_iff (since := "2025-12-10"))] -theorem op_smul_inter_ne_empty_iff {s t : Set α} {x : αᵐᵒᵖ} : - x • s ∩ t ≠ ∅ ↔ ∃ a b, (a ∈ s ∧ b ∈ t) ∧ a⁻¹ * b = MulOpposite.unop x := by - rw [← nonempty_iff_ne_empty, op_smul_inter_nonempty_iff] - @[to_additive (attr := simp)] theorem iUnion_inv_smul : ⋃ g : α, g⁻¹ • s = ⋃ g : α, g • s := (Function.Surjective.iSup_congr _ inv_surjective) fun _ ↦ rfl diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index 87ff9898f913a9..ce2308887eb5da 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -711,9 +711,6 @@ theorem map_exists_left_inv (f : F) {x : M} (hx : ∃ y, y * x = 1) : ∃ y, y * (hf : Function.Injective f) [IsDedekindFiniteMonoid N] : IsDedekindFiniteMonoid M where mul_eq_one_symm eq := hf <| by simpa [mul_eq_one_comm] using congr_arg f eq -@[deprecated (since := "2025-12-14")] -alias isDedekindFiniteMonoid_of_injective := IsDedekindFiniteMonoid.of_injective - @[to_additive] instance {M N : Type*} [Monoid M] [LeftCancelMonoid N] : MonoidHomClass (M →ₙ* N) M N where map_mul := MulHom.map_mul' diff --git a/Mathlib/Algebra/Group/Indicator.lean b/Mathlib/Algebra/Group/Indicator.lean index 9466e061e14c3a..9e58edb664a24a 100644 --- a/Mathlib/Algebra/Group/Indicator.lean +++ b/Mathlib/Algebra/Group/Indicator.lean @@ -233,6 +233,3 @@ end Set theorem map_mulIndicator {M N F : Type*} [One M] [One N] [FunLike F M N] [OneHomClass F M N] (f : F) (s : Set α) (g : α → M) (x : α) : f (s.mulIndicator g x) = s.mulIndicator (f ∘ g) x := by simp [Set.mulIndicator_comp_of_one] - -@[deprecated (since := "2025-12-08")] alias MonoidHom.map_mulIndicator := map_mulIndicator -@[deprecated (since := "2025-12-08")] alias AddMonoidHom.map_indicator := map_indicator diff --git a/Mathlib/Algebra/Group/Irreducible/Indecomposable.lean b/Mathlib/Algebra/Group/Irreducible/Indecomposable.lean index 84d433be7f56d1..e8d82f1c38826e 100644 --- a/Mathlib/Algebra/Group/Irreducible/Indecomposable.lean +++ b/Mathlib/Algebra/Group/Irreducible/Indecomposable.lean @@ -111,10 +111,6 @@ lemma Submonoid.closure_image_isMulIndecomposable_baseOf [Finite ι] replace hjk : v i ∈ closure (v '' t) := hjk ▸ mul_mem hj' hk' exact hi₁ hjk -@[deprecated (since := "2025-12-30")] -alias Submonoid.closure_image_one_lt_and_isMulIndecomposable := - Submonoid.closure_image_isMulIndecomposable_baseOf - @[to_additive] lemma Subgroup.closure_image_isMulIndecomposable_baseOf [Finite ι] [InvolutiveInv ι] [CommGroup S] [IsOrderedMonoid S] diff --git a/Mathlib/Algebra/Group/Units/Defs.lean b/Mathlib/Algebra/Group/Units/Defs.lean index 3a7b7dd89014d1..cf0954d8c353ad 100644 --- a/Mathlib/Algebra/Group/Units/Defs.lean +++ b/Mathlib/Algebra/Group/Units/Defs.lean @@ -425,8 +425,6 @@ variable [Subsingleton Mˣ] @[to_additive] lemma Units.eq_one (u : Mˣ) : u = 1 := Subsingleton.elim .. @[to_additive] lemma IsUnit.eq_one : IsUnit a → a = 1 := by rintro ⟨u, rfl⟩; simp [u.eq_one] -@[deprecated (since := "2025-11-19")] alias units_eq_one := Units.eq_one - @[to_additive (attr := simp)] lemma isUnit_iff_eq_one : IsUnit a ↔ a = 1 where mp := IsUnit.eq_one diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index 8286654704bb3a..bd62e3bf809d36 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -1030,8 +1030,6 @@ theorem mulLeft_apply (a b : A) : mulLeft R a b = a * b := rfl @[simp] theorem toAddMonoidHom_mulLeft (a : A) : (mulLeft R a : A →+ A) = AddMonoidHom.mulLeft a := rfl -@[deprecated (since := "2025-12-30")] alias mulLeft_toAddMonoidHom := toAddMonoidHom_mulLeft - variable (A) in @[simp] theorem mulLeft_zero_eq_zero : mulLeft R (0 : A) = 0 := ext zero_mul @@ -1057,8 +1055,6 @@ theorem mulRight_apply (a b : A) : mulRight R a b = b * a := rfl @[simp] theorem toAddMonoidHom_mulRight (a : A) : (mulRight R a : A →+ A) = AddMonoidHom.mulRight a := rfl -@[deprecated (since := "2025-12-30")] alias mulRight_toAddMonoidHom := toAddMonoidHom_mulRight - variable (A) in @[simp] theorem mulRight_zero_eq_zero : mulRight R (0 : A) = 0 := ext mul_zero diff --git a/Mathlib/Algebra/Module/Submodule/Ker.lean b/Mathlib/Algebra/Module/Submodule/Ker.lean index d052a15cceb08c..648550bf003221 100644 --- a/Mathlib/Algebra/Module/Submodule/Ker.lean +++ b/Mathlib/Algebra/Module/Submodule/Ker.lean @@ -193,9 +193,6 @@ theorem injOn_of_disjoint_ker {p : Submodule R M} {s : Set M} (h : s ⊆ p) theorem ker_eq_bot {f : M →ₛₗ[τ₁₂] M₂} : ker f = ⊥ ↔ Injective f := by simpa [disjoint_iff_inf_le] using disjoint_ker_iff_injOn (f := f) (p := ⊤) -@[deprecated (since := "2025-12-23")] -alias _root_.LinearMapClass.ker_eq_bot := ker_eq_bot - @[simp] lemma injective_domRestrict_iff {f : M →ₛₗ[τ₁₂] M₂} {S : Submodule R M} : Injective (f.domRestrict S) ↔ Disjoint S f.ker := by simp [← ker_eq_bot, ker_domRestrict, disjoint_iff_comap_eq_bot] diff --git a/Mathlib/Algebra/Module/Submodule/LinearMap.lean b/Mathlib/Algebra/Module/Submodule/LinearMap.lean index 928792321523ec..f56b84fd0be83f 100644 --- a/Mathlib/Algebra/Module/Submodule/LinearMap.lean +++ b/Mathlib/Algebra/Module/Submodule/LinearMap.lean @@ -278,9 +278,6 @@ theorem coe_sum {ι : Type*} (t : Finset ι) (f : ι → M →ₛₗ[σ₁₂] M map_zero' := rfl map_add' := fun _ _ => rfl }) _ _ -@[deprecated (since := "2025-11-24")] -alias coeFn_sum := coe_sum - theorem _root_.Module.End.submodule_pow_eq_zero_of_pow_eq_zero {N : Submodule R M} {g : Module.End R N} {G : Module.End R M} (h : G.comp N.subtype = N.subtype.comp g) {k : ℕ} (hG : G ^ k = 0) : g ^ k = 0 := by diff --git a/Mathlib/Algebra/MvPolynomial/Equiv.lean b/Mathlib/Algebra/MvPolynomial/Equiv.lean index df04f114b1b633..caf540ebdc0bce 100644 --- a/Mathlib/Algebra/MvPolynomial/Equiv.lean +++ b/Mathlib/Algebra/MvPolynomial/Equiv.lean @@ -739,9 +739,6 @@ theorem mem_support_coeff_finSuccEquiv {f : MvPolynomial (Fin (n + 1)) R} {i : · intro h simpa [mem_support_iff, ← finSuccEquiv_coeff_coeff m f i] using h -@[deprecated (since := "2025-11-28")] alias support_coeff_finSuccEquiv := -mem_support_coeff_finSuccEquiv - /-- The `totalDegree` of a multivariable polynomial `p` is at least `i` more than the `totalDegree` of the `i`th coefficient of `finSuccEquiv` applied to `p`, if this is nonzero. @@ -803,9 +800,6 @@ theorem nonempty_support_finSuccEquiv {f : MvPolynomial (Fin (n + 1)) R} (h : f (finSuccEquiv R n f).support.Nonempty := by rwa [Polynomial.support_nonempty, EmbeddingLike.map_ne_zero_iff] -@[deprecated (since := "2025-11-28")] alias support_finSuccEquiv_nonempty := -nonempty_support_finSuccEquiv - theorem degree_finSuccEquiv {f : MvPolynomial (Fin (n + 1)) R} (h : f ≠ 0) : (finSuccEquiv R n f).degree = degreeOf 0 f := by -- TODO: these should be lemmas diff --git a/Mathlib/Algebra/Order/AddGroupWithTop.lean b/Mathlib/Algebra/Order/AddGroupWithTop.lean index 4ed0b10b0c5ca3..31bde1e3952a65 100644 --- a/Mathlib/Algebra/Order/AddGroupWithTop.lean +++ b/Mathlib/Algebra/Order/AddGroupWithTop.lean @@ -109,8 +109,6 @@ variable [LinearOrderedAddCommGroupWithTop α] {a b c : α} attribute [simp] neg_top -@[deprecated (since := "2025-12-14")] protected alias add_neg_cancel := add_neg_cancel_of_ne_top - /-! Note: The following lemmas are special cases of the corresponding `IsAddUnit` lemmas. -/ lemma neg_add_cancel_of_ne_top (ha : a ≠ ⊤) : -a + a = 0 := by @@ -175,12 +173,6 @@ instance (priority := 100) toSubtractionMonoid : SubtractionMonoid α where have ha : a ≠ ⊤ := by rintro rfl; simp at h exact left_neg_eq_right_neg (a := a) (by simp [neg_add_cancel_of_ne_top, *]) h -@[deprecated (since := "2025-12-27")] -alias injective_add_left_of_ne_top := add_left_injective_of_ne_top - -@[deprecated (since := "2025-12-27")] -alias injective_add_right_of_ne_top := add_right_injective_of_ne_top - lemma sub_left_injective_of_ne_top (h : b ≠ ⊤) : Function.Injective fun x ↦ x - b := by simpa [sub_eq_add_neg] using add_left_injective_of_ne_top (-b) (by simpa) @@ -195,12 +187,6 @@ lemma sub_left_inj_of_ne_top (h : a ≠ ⊤) : b - a = c - a ↔ b = c := lemma sub_right_inj_of_ne_top (h : a ≠ ⊤) : a - b = a - c ↔ b = c := (sub_right_injective_of_ne_top h).eq_iff -@[deprecated (since := "2025-12-27")] -alias strictMono_add_left_of_ne_top := add_left_strictMono_of_ne_top - -@[deprecated (since := "2025-12-27")] -alias strictMono_add_right_of_ne_top := add_right_strictMono_of_ne_top - lemma sub_left_strictMono_of_ne_top (h : b ≠ ⊤) : StrictMono fun x ↦ x - b := by simpa [sub_eq_add_neg] using add_left_strictMono_of_ne_top (b := -b) (by simpa) diff --git a/Mathlib/Algebra/Order/Archimedean/Class.lean b/Mathlib/Algebra/Order/Archimedean/Class.lean index 23ab632c89c4d9..11d484e082362b 100644 --- a/Mathlib/Algebra/Order/Archimedean/Class.lean +++ b/Mathlib/Algebra/Order/Archimedean/Class.lean @@ -901,27 +901,4 @@ theorem mem_closedBallSubgroup_iff {a : M} {c : FiniteMulArchimedeanClass M} : theorem ballSubgroup_strictAnti : StrictAnti (ballSubgroup (M := M)) := fun _ _ h ↦ subgroup_strictAnti <| UpperSet.Ioi_strictMono _ h -attribute [deprecated subgroup (since := "2025-12-14")] MulArchimedeanClass.subgroup -attribute [deprecated subsemigroup_eq_subgroup (since := "2025-12-14")] - MulArchimedeanClass.subsemigroup_eq_subgroup_of_ne_top -attribute [deprecated subgroup_eq_bot (since := "2025-12-14")] MulArchimedeanClass.subgroup_eq_bot -attribute [deprecated mem_subgroup_iff (since := "2025-12-14")] MulArchimedeanClass.mem_subgroup_iff -attribute [deprecated subgroup_strictAnti (since := "2025-12-14")] - MulArchimedeanClass.subgroup_strictAntiOn -attribute [deprecated subgroup_strictAnti (since := "2025-12-14")] - MulArchimedeanClass.subgroup_antitone -attribute [deprecated ballSubgroup (since := "2025-12-14")] MulArchimedeanClass.ballSubgroup -attribute [deprecated closedBallSubgroup (since := "2025-12-14")] - MulArchimedeanClass.closedBallSubgroup -attribute [deprecated mem_ballSubgroup_iff (since := "2025-12-14")] - MulArchimedeanClass.mem_ballSubgroup_iff -attribute [deprecated mem_closedBallSubgroup_iff (since := "2025-12-14")] - MulArchimedeanClass.mem_closedBallSubgroup_iff -attribute [deprecated "Lemma for junk value." (since := "2025-12-14")] - MulArchimedeanClass.ballSubgroup_top -attribute [deprecated "Lemma for junk value." (since := "2025-12-14")] - MulArchimedeanClass.closedBallSubgroup_top -attribute [deprecated ballSubgroup_strictAnti (since := "2025-12-14")] - MulArchimedeanClass.ballSubgroup_antitone - end FiniteMulArchimedeanClass diff --git a/Mathlib/Algebra/Order/Field/Defs.lean b/Mathlib/Algebra/Order/Field/Defs.lean deleted file mode 100644 index e376d4179775df..00000000000000 --- a/Mathlib/Algebra/Order/Field/Defs.lean +++ /dev/null @@ -1,16 +0,0 @@ -/- -Copyright (c) 2014 Robert Y. Lewis. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Robert Y. Lewis, Leonardo de Moura, Mario Carneiro, Floris van Doorn --/ -module -- shake: keep-all - -public import Mathlib.Tactic.Basic -public import Mathlib.Tactic.Bound.Init -public import Mathlib.Util.CompileInductive - -deprecated_module -"for `[LinearOrderedSemifield]`, use `[Semifield K] [LinearOrder K] [IsStrictOrderedRing K]` \ -instead. -for `[LinearOrderedField]`, use `[Field K] [LinearOrder K] [IsStrictOrderedRing K]` instead." -(since := "2025-10-30") diff --git a/Mathlib/Algebra/Order/Floor/Ring.lean b/Mathlib/Algebra/Order/Floor/Ring.lean index 8aeced5d83d30d..d144ebe830a32c 100644 --- a/Mathlib/Algebra/Order/Floor/Ring.lean +++ b/Mathlib/Algebra/Order/Floor/Ring.lean @@ -118,9 +118,6 @@ variable [Ring R] [LinearOrder R] [FloorRing R] {z : ℤ} {a b : R} section floor -@[deprecated floor_lt (since := "2025-12-26")] -theorem floor_le_sub_one_iff : ⌊a⌋ ≤ z - 1 ↔ a < z := by rw [← floor_lt, le_sub_one_iff] - @[simp] theorem floor_le_neg_one_iff : ⌊a⌋ ≤ -1 ↔ a < 0 := by simpa using floor_le_iff (z := -1) @@ -578,9 +575,6 @@ end fract section ceil -@[deprecated lt_ceil (since := "2025-12-26")] -theorem add_one_le_ceil_iff : z + 1 ≤ ⌈a⌉ ↔ (z : R) < a := by rw [← lt_ceil, add_one_le_iff] - @[simp] theorem one_le_ceil_iff : 1 ≤ ⌈a⌉ ↔ 0 < a := by simpa using le_ceil_iff (z := 1) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 7c61a24d934051..4048f880d6cd9e 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -193,18 +193,6 @@ instance instLinearOrderedCommMonoidWithZeroMultiplicativeOrderDual simpa [← ofAdd_add, ← toDual_add] using! fun a ha b c hbc ↦ add_right_strictMono_of_ne_top (by simpa using! ha.ne') hbc -@[deprecated "Use simp" (since := "2025-11-17")] -theorem ofAdd_toDual_eq_zero_iff [LinearOrderedAddCommMonoidWithTop α] - (x : α) : Multiplicative.ofAdd (OrderDual.toDual x) = 0 ↔ x = ⊤ := Iff.rfl - -@[deprecated "Use simp" (since := "2025-11-17")] -theorem ofDual_toAdd_eq_top_iff [LinearOrderedAddCommMonoidWithTop α] - (x : Multiplicative αᵒᵈ) : OrderDual.ofDual x.toAdd = ⊤ ↔ x = 0 := Iff.rfl - -@[deprecated bot_eq_zero (since := "2025-11-17")] -theorem ofAdd_bot [LinearOrderedAddCommMonoidWithTop α] : - Multiplicative.ofAdd ⊥ = (0 : Multiplicative αᵒᵈ) := rfl - @[simp] theorem ofDual_toAdd_zero [LinearOrderedAddCommMonoidWithTop α] : OrderDual.ofDual (0 : Multiplicative αᵒᵈ).toAdd = ⊤ := rfl diff --git a/Mathlib/Algebra/Order/IsBotOne.lean b/Mathlib/Algebra/Order/IsBotOne.lean index e11e189ff8333f..359bc0f3efe45d 100644 --- a/Mathlib/Algebra/Order/IsBotOne.lean +++ b/Mathlib/Algebra/Order/IsBotOne.lean @@ -61,8 +61,6 @@ variable [Preorder α] [One α] [IsBotOneClass α] @[to_additive (attr := simp) not_lt_zero] theorem not_lt_one : ¬ a < 1 := one_le.not_gt -@[deprecated (since := "2025-12-03")] alias not_neg := not_lt_zero - @[deprecated (since := "2026-05-07")] alias not_lt_zero' := not_lt_zero diff --git a/Mathlib/Algebra/Order/Module/Archimedean.lean b/Mathlib/Algebra/Order/Module/Archimedean.lean index 8b886d083621cc..1bbc94304e0368 100644 --- a/Mathlib/Algebra/Order/Module/Archimedean.lean +++ b/Mathlib/Algebra/Order/Module/Archimedean.lean @@ -42,70 +42,6 @@ theorem mk_smul (a : M) {k : K} (h : k ≠ 0) : mk (k • a) = mk a := by theorem mk_le_mk_smul (a : M) (k : K) : mk a ≤ mk (k • a) := by obtain rfl | h := eq_or_ne k 0 <;> simp [*] -variable (K) - -/-- Given an upper set `s` of archimedean classes in a linearly ordered module `M` with Archimedean -scalars, all elements belonging to these classes form a submodule, except when `s = ⊤` for which the -set would be empty. For `s = ⊤`, we assign the junk value `⊥`. - -This has the same carrier as `ArchimedeanClass.addSubgroup`'s. -/ -noncomputable -def submodule (s : UpperSet (ArchimedeanClass M)) : Submodule K M where - __ := addSubgroup s - smul_mem' k {a} := by - obtain rfl | hs := eq_or_ne s ⊤ - · aesop - simpa [mem_addSubgroup_iff hs] using s.upper (mk_le_mk_smul a k) - -/-- An open ball defined by `ArchimedeanClass.submodule` of `UpperSet.Ioi c`. -For `c = ⊤`, we assign the junk value `⊥`. - -This has the same carrier as `ArchimedeanClass.ballAddSubgroup`'s. -/ -noncomputable -abbrev ball (c : ArchimedeanClass M) := submodule K (UpperSet.Ioi c) - -/-- A closed ball defined by `ArchimedeanClass.submodule` of `UpperSet.Ici c`. - -This has the same carrier as `ArchimedeanClass.closedBallAddSubgroup`'s. -/ -noncomputable -abbrev closedBall (c : ArchimedeanClass M) := submodule K (UpperSet.Ici c) - -@[simp] -theorem toAddSubgroup_ball (c : ArchimedeanClass M) : - (ball K c).toAddSubgroup = ballAddSubgroup c := rfl - -@[simp] -theorem toAddSubgroup_closedBall (c : ArchimedeanClass M) : - (closedBall K c).toAddSubgroup = closedBallAddSubgroup c := rfl - -@[simp] -theorem mem_ball_iff {a : M} {c : ArchimedeanClass M} (hc : c ≠ ⊤) : a ∈ ball K c ↔ c < mk a := - mem_ballAddSubgroup_iff hc - -@[simp] -theorem mem_closedBall_iff {a : M} {c : ArchimedeanClass M} : a ∈ closedBall K c ↔ c ≤ mk a := - mem_closedBallAddSubgroup_iff - -variable (M) in -@[simp] -theorem ball_top : ball (M := M) K ⊤ = ⊥ := - (Submodule.toAddSubgroup_inj _ _).mp <| ballAddSubgroup_top M - -variable (M) in -@[simp] -theorem closedBall_top : closedBall (M := M) K ⊤ = ⊥ := - (Submodule.toAddSubgroup_inj _ _).mp <| closedBallAddSubgroup_top M - -theorem ball_antitone : Antitone (ball (M := M) K) := by - intro _ _ h - exact (Submodule.toAddSubgroup_le _ _).mp <| ballAddSubgroup_antitone h - -theorem ball_le_closedBall {c : ArchimedeanClass M} : ball K c ≤ closedBall K c := by - obtain rfl | hc := eq_or_ne c ⊤ - · simp - intro a ha - simpa using ((mem_ball_iff K hc).mp ha).le - end ArchimedeanClass namespace FiniteArchimedeanClass @@ -160,21 +96,4 @@ theorem ball_strictAnti : StrictAnti (ball (M := M) K) := ballAddSubgroup_strict theorem ball_lt_closedBall {c : FiniteArchimedeanClass M} : ball K c < closedBall K c := submodule_strictAnti _ Set.Ioi_ssubset_Ici_self -attribute [deprecated submodule (since := "2025-12-14")] ArchimedeanClass.submodule -attribute [deprecated ball (since := "2025-12-14")] ArchimedeanClass.ball -attribute [deprecated closedBall (since := "2025-12-14")] ArchimedeanClass.closedBall -attribute [deprecated toAddSubgroup_ball (since := "2025-12-14")] - ArchimedeanClass.toAddSubgroup_ball -attribute [deprecated toAddSubgroup_closedBall (since := "2025-12-14")] - ArchimedeanClass.toAddSubgroup_closedBall -attribute [deprecated mem_ball_iff (since := "2025-12-14")] ArchimedeanClass.mem_ball_iff -attribute [deprecated mem_closedBall_iff (since := "2025-12-14")] - ArchimedeanClass.mem_closedBall_iff -attribute [deprecated "Lemma for junk value." (since := "2025-12-14")] ArchimedeanClass.ball_top -attribute [deprecated "Lemma for junk value." (since := "2025-12-14")] - ArchimedeanClass.closedBall_top -attribute [deprecated ball_strictAnti (since := "2025-12-14")] ArchimedeanClass.ball_antitone -attribute [deprecated ball_lt_closedBall (since := "2025-12-14")] - ArchimedeanClass.ball_le_closedBall - end FiniteArchimedeanClass diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean index ebf96411e49c3a..7963b58bc4777b 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean @@ -70,9 +70,6 @@ variable [LE α] theorem mul_le_mul_right [MulLeftMono α] {b c : α} (bc : b ≤ c) (a : α) : a * b ≤ a * c := CovariantClass.elim _ bc -@[deprecated (since := "2025-11-27")] -alias mul_le_mul_left' := mul_le_mul_right - @[to_additive le_of_add_le_add_left] theorem le_of_mul_le_mul_left' [MulLeftReflectLE α] {a b c : α} (bc : a * b ≤ a * c) : b ≤ c := MulLeftReflectLE.le_of_mul_le_mul_left' bc @@ -81,9 +78,6 @@ theorem le_of_mul_le_mul_left' [MulLeftReflectLE α] {a b c : α} (bc : a * b theorem mul_le_mul_left [i : MulRightMono α] {b c : α} (bc : b ≤ c) (a : α) : b * a ≤ c * a := i.elim a bc -@[deprecated (since := "2025-11-27")] -alias mul_le_mul_right' := mul_le_mul_left - @[to_additive le_of_add_le_add_right] theorem le_of_mul_le_mul_right' [MulRightReflectLE α] {a b c : α} (bc : b * a ≤ c * a) : b ≤ c := diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean index 373d81cb62a1e2..f3478598636d4f 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean @@ -95,8 +95,6 @@ theorem toMul_lt {a b : Additive α} : a.toMul < b.toMul ↔ a < b := @[gcongr] alias ⟨_, toMul_strictMono⟩ := toMul_lt @[gcongr] alias ⟨_, ofMul_strictMono⟩ := ofMul_lt -@[deprecated (since := "2025-11-18")] alias foMul_strictMono := ofMul_strictMono - end Preorder section OrderTop diff --git a/Mathlib/Algebra/Order/Ring/StandardPart.lean b/Mathlib/Algebra/Order/Ring/StandardPart.lean index 569ba5e7f072ed..05134d3e6ccbc5 100644 --- a/Mathlib/Algebra/Order/Ring/StandardPart.lean +++ b/Mathlib/Algebra/Order/Ring/StandardPart.lean @@ -73,9 +73,6 @@ theorem neg_mk {x : K} (h : 0 ≤ mk x) : -FiniteElement.mk x h = FiniteElement.mk (-x) (by rwa [mk_neg]) := rfl -@[deprecated (since := "2025-12-24")] -alias mk_neg := neg_mk - @[simp] theorem mk_add_mk (x y : K) (hx hy) : .mk x hx + .mk y hy = FiniteElement.mk (x + y) ((le_min hx hy).trans <| min_le_mk_add ..) := diff --git a/Mathlib/Algebra/Polynomial/Bivariate.lean b/Mathlib/Algebra/Polynomial/Bivariate.lean index 19e5486a598d95..a35b0764363c25 100644 --- a/Mathlib/Algebra/Polynomial/Bivariate.lean +++ b/Mathlib/Algebra/Polynomial/Bivariate.lean @@ -353,10 +353,6 @@ lemma pderiv_zero_equivMvPolynomial {R : Type*} [CommRing R] (p : R[X][Y]) : simp_rw [← Polynomial.C_mul_X_pow_eq_monomial] simp [map_nsmul] -set_option linter.dupNamespace false in -@[deprecated (since := "2025-12-09")] -alias Polynomial.Bivariate.pderiv_zero_equivMvPolynomial := pderiv_zero_equivMvPolynomial - lemma pderiv_one_equivMvPolynomial (p : R[X][Y]) : (equivMvPolynomial R p).pderiv 1 = equivMvPolynomial R (derivative p) := by induction p using Polynomial.induction_on' with @@ -368,10 +364,6 @@ lemma pderiv_one_equivMvPolynomial (p : R[X][Y]) : simp_rw [← Polynomial.C_mul_X_pow_eq_monomial] simp [derivative_pow] -set_option linter.dupNamespace false in -@[deprecated (since := "2025-12-09")] -alias Polynomial.Bivariate.pderiv_one_equivMvPolynomial := pderiv_one_equivMvPolynomial - end MvPolynomial end Bivariate diff --git a/Mathlib/Algebra/Polynomial/Derivative.lean b/Mathlib/Algebra/Polynomial/Derivative.lean index 0005c6c05137f9..78181a7c5ac083 100644 --- a/Mathlib/Algebra/Polynomial/Derivative.lean +++ b/Mathlib/Algebra/Polynomial/Derivative.lean @@ -358,9 +358,6 @@ noncomputable def derivativeFinsupp : R[X] →ₗ[R] ℕ →₀ R[X] where map_add' _ _ := by ext; simp map_smul' _ _ := by ext; simp -@[deprecated (since := "2025-12-15")] -alias derivativeFinsupp_apply_toFun := derivativeFinsupp_apply_apply - @[simp] theorem support_derivativeFinsupp_subset_range {p : R[X]} {n : ℕ} (h : p.natDegree < n) : (derivativeFinsupp p).support ⊆ range n := by diff --git a/Mathlib/Algebra/Polynomial/Expand.lean b/Mathlib/Algebra/Polynomial/Expand.lean index cfc9f72596a0da..d9f6a9738e5e72 100644 --- a/Mathlib/Algebra/Polynomial/Expand.lean +++ b/Mathlib/Algebra/Polynomial/Expand.lean @@ -266,9 +266,6 @@ theorem map_frobenius_expand (f : R[X]) : map (frobenius R p) (expand R p f) = f mul_pow, ← C.map_pow, frobenius_def] ring -@[deprecated (since := "2025-12-27")] -alias expand_char := map_frobenius_expand - theorem map_iterateFrobenius_expand (f : R[X]) (n : ℕ) : map (iterateFrobenius R p n) (expand R (p ^ n) f) = f ^ p ^ n := by induction n with @@ -279,9 +276,6 @@ theorem map_iterateFrobenius_expand (f : R[X]) (n : ℕ) : simp_rw [← map_frobenius_expand p, pow_succ', add_comm k, iterateFrobenius_add, ← map_map, ← map_expand, ← expand_mul, iterateFrobenius_one] -@[deprecated (since := "2025-12-27")] -alias map_expand_pow_char := map_iterateFrobenius_expand - end ExpChar end CommSemiring diff --git a/Mathlib/Algebra/Polynomial/Roots.lean b/Mathlib/Algebra/Polynomial/Roots.lean index 2f56ad2efa04db..26fb00fb88acf6 100644 --- a/Mathlib/Algebra/Polynomial/Roots.lean +++ b/Mathlib/Algebra/Polynomial/Roots.lean @@ -340,8 +340,6 @@ theorem roots_eq_of_degree_eq_card {S : Finset R} (hS : ∀ x ∈ S, p.eval x = 0) (hcard : S.card = p.degree) : p.roots = S.val := roots_eq_of_degree_le_card_of_ne_zero hS (by grind) (by contrapose! hcard; simp [hcard]) -@[deprecated (since := "2025-12-16")] alias roots_eq_of_degree_le_card := roots_eq_of_degree_eq_card - theorem roots_eq_of_natDegree_le_card_of_ne_zero {S : Finset R} (hS : ∀ x ∈ S, p.eval x = 0) (hcard : p.natDegree ≤ S.card) (hp : p ≠ 0) : p.roots = S.val := roots_eq_of_degree_le_card_of_ne_zero hS (degree_le_of_natDegree_le hcard) hp diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index 479278254a51d4..96454a3b8b4cc2 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -101,9 +101,6 @@ theorem Splits.of_degree_le_zero {f : R[X]} (hf : degree f ≤ 0) : theorem _root_.IsUnit.splits [NoZeroDivisors R] {f : R[X]} (hf : IsUnit f) : Splits f := .of_natDegree_eq_zero (natDegree_eq_zero_of_isUnit hf) -@[deprecated (since := "2025-11-27")] -alias splits_of_isUnit := IsUnit.splits - theorem Splits.of_natDegree_le_one_of_invertible {f : R[X]} (hf : f.natDegree ≤ 1) (h : Invertible f.leadingCoeff) : f.Splits := by obtain ⟨a, b, rfl⟩ := exists_eq_X_add_C_of_natDegree_le_one hf @@ -480,9 +477,6 @@ theorem Splits.of_dvd (hg : Splits g) (hg₀ : g ≠ 0) (hfg : f ∣ g) : Splits obtain ⟨g, rfl⟩ := hfg exact ((splits_mul (by simp_all) (by simp_all)).mp hg).1 -@[deprecated (since := "2025-11-27")] -alias Splits.splits_of_dvd := Splits.of_dvd - theorem splits_prod_iff {ι : Type*} {f : ι → R[X]} {s : Finset ι} (hf : ∀ i ∈ s, f i ≠ 0) : (∏ x ∈ s, f x).Splits ↔ ∀ x ∈ s, (f x).Splits := ⟨fun h _ hx ↦ h.of_dvd (Finset.prod_ne_zero_iff.mpr hf) (Finset.dvd_prod_of_mem f hx), @@ -550,9 +544,6 @@ theorem Splits.roots_map {f : R[X]} (hf : f.Splits) (i : R →+* S) : (f.map i).roots = f.roots.map i := hf.roots_map_of_injective i.injective -@[deprecated (since := "2025-11-27")] -alias Splits.map_roots := Splits.roots_map - theorem Splits.mem_range_of_isRoot {f : R[X]} (hf : f.Splits) (hf0 : f ≠ 0) {i : R →+* S} {x : S} (hx : (f.map i).IsRoot x) : x ∈ i.range := by @@ -710,182 +701,15 @@ section CommRing variable [CommRing K] [Field L] [Field F] variable (i : K →+* L) -@[deprecated (since := "2025-11-24")] -alias splits_zero := Splits.zero - -@[deprecated "Use `Splits.C` instead." (since := "2025-11-24")] -theorem splits_of_map_eq_C {f : K[X]} {a : L} (h : f.map i = C a) : Splits (f.map i) := - h ▸ Splits.C a - -@[deprecated (since := "2025-11-24")] -alias splits_C := Splits.C - -@[deprecated (since := "2025-11-24")] -alias splits_of_map_degree_eq_one := Splits.of_degree_eq_one - -@[deprecated (since := "2025-11-24")] -alias splits_of_degree_le_one := Splits.of_degree_le_one - -@[deprecated (since := "2025-11-24")] -alias splits_of_degree_eq_one := Splits.of_degree_eq_one - -@[deprecated (since := "2025-11-24")] -alias splits_of_natDegree_le_one := Splits.of_natDegree_le_one - -@[deprecated (since := "2025-11-24")] -alias splits_of_natDegree_eq_one := Splits.of_natDegree_eq_one - -@[deprecated (since := "2025-11-25")] -alias splits_of_splits_mul' := splits_mul - -@[deprecated "Use `Polynomial.map_map` instead." (since := "2025-11-24")] -theorem splits_map_iff {L : Type*} [CommRing L] (i : K →+* L) (j : L →+* F) {f : K[X]} : - Splits ((f.map i).map j) ↔ Splits (f.map (j.comp i)) := by - rw [Polynomial.map_map] - -@[deprecated (since := "2025-11-24")] -alias splits_one := Splits.one - -@[deprecated (since := "2025-11-24")] -alias splits_X_sub_C := Splits.X_sub_C - -@[deprecated (since := "2025-11-24")] -alias splits_X := Splits.X - -@[deprecated (since := "2025-11-24")] -alias splits_prod := Splits.prod - -@[deprecated (since := "2025-11-24")] -alias splits_pow := Splits.pow - -@[deprecated (since := "2025-11-24")] -alias splits_X_pow := Splits.X_pow - -@[deprecated "Use `Polynomial.map_id` instead." (since := "2025-11-24")] -theorem splits_id_iff_splits {f : K[X]} : - ((f.map i).map (RingHom.id L)).Splits ↔ (f.map i).Splits := by - rw [map_id] - variable {i} -@[deprecated (since := "2025-11-25")] -alias Splits.comp_of_map_degree_le_one := Splits.comp_of_degree_le_one - variable (i) -@[deprecated (since := "2025-12-01")] -alias exists_root_of_splits' := Splits.exists_eval_eq_zero - -@[deprecated (since := "2025-12-01")] -alias roots_ne_zero_of_splits' := Splits.roots_ne_zero - -@[deprecated (since := "2025-12-01")] -alias rootOfSplits' := rootOfSplits - -@[deprecated (since := "2025-12-01")] -alias map_rootOfSplits' := eval_rootOfSplits - -@[deprecated (since := "2025-12-01")] -alias natDegree_eq_card_roots' := Splits.natDegree_eq_card_roots - -@[deprecated (since := "2025-12-01")] -alias degree_eq_card_roots' := Splits.degree_eq_card_roots - end CommRing variable [CommRing R] [Field K] [Field L] [Field F] variable (i : K →+* L) -/-- This lemma is for polynomials over a field. -/ -@[deprecated (since := "2025-11-30")] -alias splits_iff := splits_iff_splits - -/-- This lemma is for polynomials over a field. -/ -@[deprecated (since := "2025-11-30")] -alias Splits.def := splits_iff_splits - -@[deprecated (since := "2025-11-25")] -alias splits_of_splits_mul := splits_mul - -@[deprecated (since := "2025-11-25")] -alias splits_of_splits_of_dvd := Splits.of_dvd - -@[deprecated "Use `Splits.of_dvd` directly." (since := "2025-11-30")] -theorem splits_of_splits_gcd_left [DecidableEq K] {f g : K[X]} (hf0 : f ≠ 0) - (hf : Splits f) : Splits (EuclideanDomain.gcd f g) := - Splits.of_dvd hf hf0 <| EuclideanDomain.gcd_dvd_left f g - -@[deprecated "Use `Splits.of_dvd` directly." (since := "2025-11-30")] -theorem splits_of_splits_gcd_right [DecidableEq K] {f g : K[X]} (hg0 : g ≠ 0) - (hg : Splits g) : Splits (EuclideanDomain.gcd f g) := - Splits.of_dvd hg hg0 <| EuclideanDomain.gcd_dvd_right f g - -@[deprecated (since := "2025-11-30")] -alias degree_eq_one_of_irreducible_of_splits := Splits.degree_eq_one_of_irreducible - -@[deprecated (since := "2025-12-01")] -alias exists_root_of_splits := Splits.exists_eval_eq_zero - -@[deprecated (since := "2025-12-01")] -alias roots_ne_zero_of_splits := Splits.roots_ne_zero - -@[deprecated (since := "2025-12-01")] -alias map_rootOfSplits := eval_rootOfSplits - -/-- `rootOfSplits'` is definitionally equal to `rootOfSplits`. -/ -@[deprecated "`rootOfSplits'` is now deprecated." (since := "2025-12-01")] -theorem rootOfSplits'_eq_rootOfSplits {f : K[X]} (hf : (f.map i).Splits) (hfd) : - rootOfSplits hf hfd = rootOfSplits hf (f.degree_map i ▸ hfd) := - rfl - -@[deprecated (since := "2025-11-30")] -alias natDegree_eq_card_roots := Splits.natDegree_eq_card_roots - -@[deprecated (since := "2025-11-30")] -alias degree_eq_card_roots := Splits.degree_eq_card_roots - -@[deprecated (since := "2025-12-02")] -alias roots_map := Splits.map_roots - -@[deprecated (since := "2025-12-02")] -alias image_rootSet := Splits.image_rootSet - -@[deprecated (since := "2025-12-06")] -alias adjoin_rootSet_eq_range := Splits.adjoin_rootSet_eq_range - -@[deprecated (since := "2025-11-25")] -alias eq_prod_roots_of_splits := Splits.eq_prod_roots - -@[deprecated (since := "2025-11-25")] -alias eq_prod_roots_of_splits_id := Splits.eq_prod_roots - -@[deprecated (since := "2025-12-06")] -alias aeval_eq_prod_aroots_sub_of_splits := Splits.aeval_eq_prod_aroots - -@[deprecated (since := "2025-12-06")] -alias eval_eq_prod_roots_sub_of_splits_id := Splits.eval_eq_prod_roots - -@[deprecated (since := "2025-12-02")] -alias eq_prod_roots_of_monic_of_splits_id := Splits.eq_prod_roots_of_monic - -@[deprecated (since := "2025-12-06")] -alias aeval_eq_prod_aroots_sub_of_monic_of_splits := Splits.aeval_eq_prod_aroots_of_monic - -@[deprecated (since := "2025-12-06")] -alias eval_eq_prod_roots_sub_of_monic_of_splits_id := Splits.eval_eq_prod_roots_of_monic - -@[deprecated (since := "2025-12-06")] -alias eq_X_sub_C_of_splits_of_single_root := Splits.eq_X_sub_C_of_single_root - -@[deprecated (since := "2025-12-13")] -alias mem_lift_of_splits_of_roots_mem_range := Splits.mem_lift_of_roots_mem_range - -@[deprecated (since := "2025-12-13")] -alias splits_of_natDegree_eq_two := Splits.of_natDegree_eq_two - -@[deprecated (since := "2025-12-13")] -alias splits_of_degree_eq_two := Splits.of_degree_eq_two - section UFD attribute [local instance] PrincipalIdealRing.to_uniqueFactorizationMonoid @@ -894,63 +718,10 @@ local infixl:50 " ~ᵤ " => Associated open UniqueFactorizationMonoid Associates -@[deprecated (since := "2025-12-02")] -alias splits_of_exists_multiset := splits_iff_exists_multiset - -@[deprecated (since := "2025-11-30")] -alias splits_of_splits_id := Splits.map - end UFD -@[deprecated (since := "2025-12-09")] -alias splits_of_comp := Splits.of_splits_map - -@[deprecated (since := "2025-12-09")] -alias splits_id_of_splits := Splits.of_splits_map - -@[deprecated (since := "2025-12-09")] -alias splits_comp_of_splits := Splits.map - variable [Algebra R K] [Algebra R L] -@[deprecated (since := "2025-12-13")] -alias splits_of_algHom := Splits.of_algHom - -@[deprecated (since := "2025-12-13")] -alias splits_of_isScalarTower := Splits.of_isScalarTower - -@[deprecated (since := "2025-12-08")] -alias eval₂_derivative_of_splits := Splits.eval_derivative - -@[deprecated (since := "2025-12-08")] -alias aeval_derivative_of_splits := Splits.eval_derivative - -@[deprecated (since := "2025-12-08")] -alias eval_derivative_of_splits := Splits.eval_derivative - -@[deprecated (since := "2025-12-08")] -alias aeval_root_derivative_of_splits := Splits.eval_root_derivative - -@[deprecated (since := "2025-12-12")] -alias eval_derivative_eq_eval_mul_sum_of_splits := Splits.eval_derivative_eq_eval_mul_sum - -@[deprecated (since := "2025-12-12")] -alias eval_derivative_div_eval_of_ne_zero_of_splits := Splits.eval_derivative_div_eval_of_ne_zero - -@[deprecated (since := "2025-12-12")] -alias coeff_zero_eq_leadingCoeff_mul_prod_roots_of_splits := - Splits.coeff_zero_eq_leadingCoeff_mul_prod_roots - -@[deprecated (since := "2025-12-12")] -alias coeff_zero_eq_prod_roots_of_monic_of_splits := Splits.coeff_zero_eq_prod_roots_of_monic - -@[deprecated (since := "2025-12-12")] -alias nextCoeff_eq_neg_sum_roots_mul_leadingCoeff_of_splits := - Splits.nextCoeff_eq_neg_sum_roots_mul_leadingCoeff - -@[deprecated (since := "2025-12-12")] -alias nextCoeff_eq_neg_sum_roots_of_monic_of_splits := Splits.nextCoeff_eq_neg_sum_roots_of_monic - end Splits end diff --git a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean index 585161108f95c1..01b2a6e5780c3a 100644 --- a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean +++ b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean @@ -78,8 +78,6 @@ theorem omega_mul_algebraMap_mul_mk (n x y : R) : (ω : QuadraticAlgebra R a b) * algebraMap _ _ n * ⟨x, y⟩ = ⟨a * n * y, n * x + n * b * y⟩ := by ext <;> simp; ring -@[deprecated (since := "2025-12-15")] alias omega_mul_coe_mul_mk := omega_mul_algebraMap_mul_mk - theorem mk_eq_add_smul_omega (x y : R) : (⟨x, y⟩ : QuadraticAlgebra R a b) = algebraMap _ _ x + y • ω := by ext <;> simp @@ -206,8 +204,6 @@ theorem norm_one : norm (1 : QuadraticAlgebra R a b) = 1 := by simp [norm] theorem norm_algebraMap (r : R) : norm (algebraMap R (QuadraticAlgebra R a b) r) = r ^ 2 := by simp [norm_def, pow_two] -@[deprecated (since := "2025-12-15")] alias norm_coe := norm_algebraMap - @[simp] theorem norm_natCast (n : ℕ) : norm (n : QuadraticAlgebra R a b) = n ^ 2 := by simp [norm_def, pow_two] @@ -220,8 +216,6 @@ theorem algebraMap_norm_eq_mul_star (z : QuadraticAlgebra R a b) : (algebraMap R _ (norm z : R)) = z * star z := by ext <;> simp [norm, star, mul_comm] <;> ring -@[deprecated (since := "2025-12-15")] alias coe_norm_eq_mul_star := algebraMap_norm_eq_mul_star - @[simp] theorem norm_neg (x : QuadraticAlgebra R a b) : (-x).norm = x.norm := by simp [norm] @@ -273,9 +267,6 @@ theorem algebraMap_mem_nonZeroDivisors_iff {r : R} : simp only [re_mul, algebraMap_re, algebraMap_im, mul_zero, add_zero, im_mul, zero_add] at hz simp [QuadraticAlgebra.ext_iff, re_zero, im_zero, h _ hz.left, h _ hz.right] -@[deprecated (since := "2025-12-15")] -alias coe_mem_nonZeroDivisors_iff := algebraMap_mem_nonZeroDivisors_iff - theorem star_mem_nonZeroDivisors {z : QuadraticAlgebra R a b} (hz : z ∈ (QuadraticAlgebra R a b)⁰) : star z ∈ (QuadraticAlgebra R a b)⁰ := by diff --git a/Mathlib/Algebra/QuadraticAlgebra/Defs.lean b/Mathlib/Algebra/QuadraticAlgebra/Defs.lean index dbe64d0bfbd622..780ca423edde6b 100644 --- a/Mathlib/Algebra/QuadraticAlgebra/Defs.lean +++ b/Mathlib/Algebra/QuadraticAlgebra/Defs.lean @@ -71,29 +71,19 @@ variable [Zero R] Note that, if `R` is a ring, you should use `algebraMap` instead of `C`. -/ protected def C (x : R) : QuadraticAlgebra R a b := ⟨x, 0⟩ -@[deprecated (since := "2025-12-15")] alias coe := QuadraticAlgebra.C - @[simp] theorem re_C : (.C r : QuadraticAlgebra R a b).re = r := rfl -@[deprecated (since := "2025-12-15")] alias re_coe := re_C - @[simp] theorem im_C : (.C r : QuadraticAlgebra R a b).im = 0 := rfl -@[deprecated (since := "2025-12-15")] alias im_coe := im_C - theorem C_injective : Function.Injective (.C : R → QuadraticAlgebra R a b) := fun _ _ h => congr_arg re h -@[deprecated (since := "2025-12-15")] alias coe_injective := C_injective - @[simp] theorem C_inj {x y : R} : (.C x : QuadraticAlgebra R a b) = .C y ↔ x = y := C_injective.eq_iff -@[deprecated (since := "2025-12-15")] alias coe_inj := C_inj - instance : Zero (QuadraticAlgebra R a b) := ⟨⟨0, 0⟩⟩ @[simp] theorem re_zero : (0 : QuadraticAlgebra R a b).re = 0 := rfl @@ -103,14 +93,10 @@ instance : Zero (QuadraticAlgebra R a b) := ⟨⟨0, 0⟩⟩ @[simp] theorem C_zero : (.C 0 : QuadraticAlgebra R a b) = 0 := rfl -@[deprecated (since := "2025-12-15")] alias coe_zero := C_zero - @[simp] theorem C_eq_zero_iff {r : R} : (.C r : QuadraticAlgebra R a b) = 0 ↔ r = 0 := by rw [← C_zero, C_inj] -@[deprecated (since := "2025-12-15")] alias coe_eq_zero_iff := C_eq_zero_iff - instance : Inhabited (QuadraticAlgebra R a b) := ⟨0⟩ section One @@ -125,14 +111,10 @@ instance : One (QuadraticAlgebra R a b) := ⟨⟨1, 0⟩⟩ @[simp] theorem C_one : (.C 1 : QuadraticAlgebra R a b) = 1 := rfl -@[deprecated (since := "2025-12-15")] alias coe_one := C_one - @[simp] theorem C_eq_one_iff {r : R} : (.C r : QuadraticAlgebra R a b) = 1 ↔ r = 1 := by rw [← C_one, C_inj] -@[deprecated (since := "2025-12-15")] alias coe_eq_one_iff := C_eq_one_iff - end One end Zero @@ -162,8 +144,6 @@ variable [AddZeroClass R] theorem C_add (x y : R) : (.C (x + y) : QuadraticAlgebra R a b) = .C x + .C y := by ext <;> simp -@[deprecated (since := "2025-12-15")] alias coe_add := C_add - end AddZeroClass section Neg @@ -187,8 +167,6 @@ section AddGroup theorem C_neg [NegZeroClass R] (x : R) : (.C (-x) : QuadraticAlgebra R a b) = -.C x := by ext <;> simp -@[deprecated (since := "2025-12-15")] alias coe_neg := C_neg - instance [Sub R] : Sub (QuadraticAlgebra R a b) where sub z w := ⟨z.re - w.re, z.im - w.im⟩ @@ -207,8 +185,6 @@ theorem C_sub (r1 r2 : R) [SubNegZeroMonoid R] : (.C (r1 - r2) : QuadraticAlgebra R a b) = .C r1 - .C r2 := QuadraticAlgebra.ext rfl zero_sub_zero.symm -@[deprecated (since := "2025-12-15")] alias coe_sub := C_sub - end AddGroup section Mul @@ -267,8 +243,6 @@ theorem C_smul [Zero R] [SMulZeroClass S R] (s : S) (r : R) : (.C (s • r) : QuadraticAlgebra R a b) = s • .C r := QuadraticAlgebra.ext rfl (smul_zero _).symm -@[deprecated (since := "2025-12-15")] alias coe_smul := C_smul - instance [AddMonoid R] : AddMonoid (QuadraticAlgebra R a b) := fast_instance% by refine (equivProd a b).injective.addMonoid _ rfl ?_ ?_ <;> intros <;> rfl @@ -302,8 +276,6 @@ theorem C_ofNat (n : ℕ) [n.AtLeastTwo] : (.C (ofNat(n) : R) : QuadraticAlgebra R a b) = ofNat(n) := by ext <;> rfl -@[deprecated (since := "2025-12-15")] alias coe_ofNat := C_ofNat - @[simp, norm_cast] theorem re_natCast (n : ℕ) : (n : QuadraticAlgebra R a b).re = n := rfl @@ -312,8 +284,6 @@ theorem im_natCast (n : ℕ) : (n : QuadraticAlgebra R a b).im = 0 := rfl theorem C_natCast (n : ℕ) : .C (n : R) = (↑n : QuadraticAlgebra R a b) := rfl -@[deprecated (since := "2025-12-15")] alias coe_natCast := C_natCast - @[scoped simp] theorem re_ofNat (n : ℕ) [n.AtLeastTwo] : (ofNat(n) : QuadraticAlgebra R a b).re = ofNat(n) := rfl @@ -338,8 +308,6 @@ theorem im_intCast (n : ℤ) : (n : QuadraticAlgebra R a b).im = 0 := rfl theorem C_intCast (n : ℤ) : .C (n : R) = (n : QuadraticAlgebra R a b) := rfl -@[deprecated (since := "2025-12-15")] alias coe_intCast := C_intCast - end AddCommGroupWithOne section NonUnitalNonAssocSemiring @@ -355,14 +323,10 @@ theorem C_mul_eq_smul (r : R) (x : QuadraticAlgebra R a b) : (.C r * x : QuadraticAlgebra R a b) = r • x := by ext <;> simp -@[deprecated (since := "2025-12-15")] alias coe_mul_eq_smul := C_mul_eq_smul - @[simp] theorem C_mul (x y : R) : .C (x * y) = (.C x * .C y : QuadraticAlgebra R a b) := by ext <;> simp -@[deprecated (since := "2025-12-15")] alias coe_mul := C_mul - end NonUnitalNonAssocSemiring section NonAssocSemiring @@ -471,24 +435,16 @@ instance [Semiring S] [Module S R] [Module.IsTorsionFree S R] : theorem C_pow (n : ℕ) (r : R) : (.C (r ^ n : R) : QuadraticAlgebra R a b) = (.C r) ^ n := (algebraMap R (QuadraticAlgebra R a b)).map_pow r n -@[deprecated (since := "2025-12-15")] alias coe_pow := C_pow - theorem mul_C_eq_smul (r : R) (x : QuadraticAlgebra R a b) : (x * .C r : QuadraticAlgebra R a b) = r • x := by rw [mul_comm, C_mul_eq_smul r x] -@[deprecated (since := "2025-12-15")] alias mul_coe_eq_smul := mul_C_eq_smul - @[simp] theorem C_eq_algebraMap : QuadraticAlgebra.C = (algebraMap R (QuadraticAlgebra R a b)) := rfl -@[deprecated (since := "2025-12-15")] alias coe_algebraMap := C_eq_algebraMap - theorem smul_C (r1 r2 : R) : r1 • (.C r2 : QuadraticAlgebra R a b) = .C (r1 * r2) := by rw [C_mul, C_mul_eq_smul] -@[deprecated (since := "2025-12-15")] alias smul_coe := smul_C - theorem algebraMap_dvd_iff {r : R} {z : QuadraticAlgebra R a b} : (algebraMap R (QuadraticAlgebra R a b) r) ∣ z ↔ r ∣ z.re ∧ r ∣ z.im := by constructor @@ -498,16 +454,12 @@ theorem algebraMap_dvd_iff {r : R} {z : QuadraticAlgebra R a b} : use ⟨r, i⟩ simp [QuadraticAlgebra.ext_iff, hr, hi, ← C_eq_algebraMap] -@[deprecated (since := "2025-12-15")] alias coe_dvd_iff := algebraMap_dvd_iff - @[simp] theorem algebraMap_dvd_iff_dvd {z w : R} : algebraMap R (QuadraticAlgebra R a b) z ∣ algebraMap R (QuadraticAlgebra R a b) w ↔ z ∣ w := by rw [algebraMap_dvd_iff] simp -@[deprecated (since := "2025-12-15")] alias coe_dvd_iff_dvd := algebraMap_dvd_iff_dvd - end CommSemiring section CommRing diff --git a/Mathlib/Algebra/Quotient.lean b/Mathlib/Algebra/Quotient.lean index b5d4f92ecc195d..b7397073c630c7 100644 --- a/Mathlib/Algebra/Quotient.lean +++ b/Mathlib/Algebra/Quotient.lean @@ -49,11 +49,5 @@ class HasQuotient (A : outParam <| Type u) (B : Type v) where /-- `HasQuotient.Quotient A b` (denoted as `A ⧸ b`) is the quotient of the type `A` by `b`. -/ Quotient (A) : B → Type max u v -/-- A deprecated variant of `HasQuotient.Quotient` -/ -@[deprecated HasQuotient.Quotient (since := "2025-12-18")] -abbrev HasQuotient.quotient' {A : outParam <| Type u} {B : Type v} - [HasQuotient A B] (b : B) : Type max u v := - HasQuotient.Quotient A b - /-- Quotient notation based on the `HasQuotient` typeclass -/ notation:35 G " ⧸ " H:34 => HasQuotient.Quotient G H diff --git a/Mathlib/Algebra/Ring/Equiv.lean b/Mathlib/Algebra/Ring/Equiv.lean index 9297647839f674..9889174662555c 100644 --- a/Mathlib/Algebra/Ring/Equiv.lean +++ b/Mathlib/Algebra/Ring/Equiv.lean @@ -893,10 +893,6 @@ def ofNonUnitalRingHom (hom : R →ₙ+* S) (inv : S →ₙ+* R) attribute [simp] ofNonUnitalRingHom_apply -@[deprecated (since := "2025-12-04")] alias ofHomInv' := ofNonUnitalRingHom -@[deprecated (since := "2025-12-04")] alias ofHomInv'_apply := ofNonUnitalRingHom_apply -@[deprecated (since := "2025-12-04")] alias ofHomInv'_symm_apply := ofNonUnitalRingHom_symm_apply - @[simp] theorem symm_ofNonUnitalRingHom (f : R →ₙ+* S) (g : S →ₙ+* R) (h₁ h₂) : (ofNonUnitalRingHom f g h₁ h₂).symm = ofNonUnitalRingHom g f h₂ h₁ := @@ -920,10 +916,6 @@ def ofRingHom (f : R →+* S) (g : S →+* R) (h₁ : f.comp g = RingHom.id S) attribute [simp] ofRingHom_apply -@[deprecated (since := "2025-12-04")] alias ofHomInv := ofRingHom -@[deprecated (since := "2025-12-04")] alias ofHomInv_apply := ofRingHom_apply -@[deprecated (since := "2025-12-04")] alias ofHomInv_symm_apply := ofRingHom_symm_apply - theorem coe_ringHom_ofRingHom (f : R →+* S) (g : S →+* R) (h₁ h₂) : ofRingHom f g h₁ h₂ = f := rfl diff --git a/Mathlib/Algebra/Star/LinearMap.lean b/Mathlib/Algebra/Star/LinearMap.lean index 0249b8488b7250..ee9d12fedd1a66 100644 --- a/Mathlib/Algebra/Star/LinearMap.lean +++ b/Mathlib/Algebra/Star/LinearMap.lean @@ -65,9 +65,6 @@ theorem IntrinsicStar.isSelfAdjoint_iff_map_star (f : WithConv (E →ₗ[R] F)) simp_rw [IsSelfAdjoint, WithConv.ext_iff, LinearMap.ext_iff, intrinsicStar_apply, star_eq_iff_star_eq, eq_comm] -@[deprecated (since := "2025-12-09")] -alias isSelfAdjoint_iff_map_star := IntrinsicStar.isSelfAdjoint_iff_map_star - /-- A star-preserving linear map is self-adjoint (with respect to the intrinsic star). -/ @[simp] protected theorem _root_.IntrinsicStar.StarHomClass.isSelfAdjoint {S : Type*} [FunLike S E F] @@ -75,9 +72,6 @@ protected theorem _root_.IntrinsicStar.StarHomClass.isSelfAdjoint {S : Type*} [F IsSelfAdjoint (toConv (f : E →ₗ[R] F) : WithConv (E →ₗ[R] F)) := IntrinsicStar.isSelfAdjoint_iff_map_star _ |>.mpr (map_star f) -@[deprecated (since := "2025-12-09")] -alias _root_.StarHomClass.isSelfAdjoint := _root_.IntrinsicStar.StarHomClass.isSelfAdjoint - variable {G : Type*} [AddCommMonoid G] [Module R G] [StarAddMonoid G] [StarModule R G] theorem intrinsicStar_comp (f : WithConv (E →ₗ[R] F)) (g : WithConv (G →ₗ[R] E)) : diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean b/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean index 284959334420aa..ddeb6a46ccf483 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/NormalForms.lean @@ -116,8 +116,6 @@ lemma cons {m a L} (hL : IsAdmissible (m + 1) L) (ha : a ≤ m) theorem sortedLT {m L} (hL : IsAdmissible m L) : L.SortedLT := hL.isChain.sortedLT -@[deprecated (since := "2025-11-27")] alias pairwise := sortedLT - /-- If `(a :: l)` is `m`-admissible then a is less than all elements of `l` -/ @[grind →] lemma head_lt {m a L} (hL : IsAdmissible m (a :: L)) : diff --git a/Mathlib/Analysis/Analytic/Binomial.lean b/Mathlib/Analysis/Analytic/Binomial.lean index d323470efb0c04..eae8dcd5478068 100644 --- a/Mathlib/Analysis/Analytic/Binomial.lean +++ b/Mathlib/Analysis/Analytic/Binomial.lean @@ -146,16 +146,10 @@ theorem one_add_cpow_hasFPowerSeriesOnBall_zero {a : ℂ} : · apply Complex.mem_slitPlane_of_norm_lt_one simpa [B] using hz -@[deprecated (since := "2025-12-08")] -alias _root_.one_add_cpow_hasFPowerSeriesOnBall_zero := one_add_cpow_hasFPowerSeriesOnBall_zero - theorem one_add_cpow_hasFPowerSeriesAt_zero {a : ℂ} : HasFPowerSeriesAt (fun x ↦ (1 + x) ^ a) (binomialSeries ℂ a) 0 := one_add_cpow_hasFPowerSeriesOnBall_zero.hasFPowerSeriesAt -@[deprecated (since := "2025-12-08")] -alias _root_.one_add_cpow_hasFPowerSeriesAt_zero := one_add_cpow_hasFPowerSeriesAt_zero - theorem one_div_one_sub_cpow_hasFPowerSeriesOnBall_zero (a : ℂ) : HasFPowerSeriesOnBall (fun x ↦ 1 / (1 - x) ^ a) (.ofScalars ℂ fun n ↦ Ring.choose (a + n - 1) n) 0 1 := by @@ -247,16 +241,10 @@ theorem one_add_rpow_hasFPowerSeriesOnBall_zero {a : ℝ} : · simp · intro x hx; simp_all; norm_cast -@[deprecated (since := "2025-12-08")] -alias _root_.one_add_rpow_hasFPowerSeriesOnBall_zero := one_add_rpow_hasFPowerSeriesOnBall_zero - theorem one_add_rpow_hasFPowerSeriesAt_zero {a : ℝ} : HasFPowerSeriesAt (fun x ↦ (1 + x) ^ a) (binomialSeries ℝ a) 0 := one_add_rpow_hasFPowerSeriesOnBall_zero.hasFPowerSeriesAt -@[deprecated (since := "2025-12-08")] -alias _root_.one_add_rpow_hasFPowerSeriesAt_zero := one_add_rpow_hasFPowerSeriesAt_zero - theorem one_div_one_sub_rpow_hasFPowerSeriesOnBall_zero (a : ℝ) : HasFPowerSeriesOnBall (fun x ↦ 1 / (1 - x) ^ a) (.ofScalars ℝ fun n ↦ Ring.choose (a + n - 1) n) 0 1 := by @@ -317,7 +305,4 @@ theorem hasFPowerSeriesOnBall_ofScalars_mul_add_zero (a b : ℝ) : · simp [div_eq_mul_inv] · ext; simp; ring -@[deprecated (since := "2025-12-28")] -alias hasFPowerSeriesOnBall_linear_zero := hasFPowerSeriesOnBall_ofScalars_mul_add_zero - end Real diff --git a/Mathlib/Analysis/Analytic/OfScalars.lean b/Mathlib/Analysis/Analytic/OfScalars.lean index eb4d78c2e000e8..b1465974ddfc62 100644 --- a/Mathlib/Analysis/Analytic/OfScalars.lean +++ b/Mathlib/Analysis/Analytic/OfScalars.lean @@ -215,9 +215,6 @@ theorem inv_le_ofScalars_radius_of_tendsto {r : ℝ≥0} (hr : r ≠ 0) gcongr exact ofScalars_norm_le E c n (Nat.pos_iff_ne_zero.mpr hn) -@[deprecated (since := "2025-11-21")] -alias ofScalars_radius_ge_inv_of_tendsto := inv_le_ofScalars_radius_of_tendsto - /-- The radius of convergence of a scalar series is the inverse of the non-zero limit `fun n ↦ ‖c n.succ‖ / ‖c n‖`. -/ theorem ofScalars_radius_eq_inv_of_tendsto [NormOneClass E] {r : ℝ≥0} (hr : r ≠ 0) diff --git a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean index ac8d947d77b276..6f001f355ec0b0 100644 --- a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean +++ b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean @@ -350,6 +350,3 @@ lemma Unitary.mem_pathComponentOne_iff {u : unitary A} : induction l with | nil => simp | cons x xs ih => simpa using! (joined_one_expUnitary x).mul ih - -@[deprecated (since := "2025-10-29")] alias unitary.mem_pathComponentOne_iff := - Unitary.mem_pathComponentOne_iff diff --git a/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean b/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean index f6657cd913bfa4..4f554cb97bb2e7 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean @@ -74,9 +74,6 @@ theorem exists_contDiff_tsupport_subset {s : Set E} {x : E} {n : ℕ∞} (hs : s apply mem_closedBall_self exact (half_pos d_pos).le -@[deprecated (since := "2025-12-17")] -alias exists_smooth_tsupport_subset := exists_contDiff_tsupport_subset - /-- Given an open set `s` in a finite-dimensional real normed vector space, there exists a smooth function with values in `[0, 1]` whose support is exactly `s`. -/ theorem IsOpen.exists_contDiff_support_eq {n : ℕ∞} {s : Set E} (hs : IsOpen s) : @@ -195,9 +192,6 @@ theorem IsOpen.exists_contDiff_support_eq {n : ℕ∞} {s : Set E} (hs : IsOpen apply (le_abs_self _).trans simpa only [norm_iteratedFDeriv_zero] using! hr n 0 zero_le y -@[deprecated (since := "2025-12-17")] -alias IsOpen.exists_smooth_support_eq := IsOpen.exists_contDiff_support_eq - end section diff --git a/Mathlib/Analysis/Calculus/Deriv/Basic.lean b/Mathlib/Analysis/Calculus/Deriv/Basic.lean index 89412bdad756e9..7689253f3a151d 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Basic.lean @@ -451,15 +451,11 @@ theorem fderivWithin_derivWithin : (fderivWithin 𝕜 f s x : 𝕜 → F) 1 = de theorem toSpanSingleton_derivWithin : toSpanSingleton 𝕜 (derivWithin f s x) = fderivWithin 𝕜 f s x := by simp [derivWithin] -@[deprecated (since := "2025-12-18")] alias derivWithin_fderivWithin := toSpanSingleton_derivWithin - theorem norm_derivWithin_eq_norm_fderivWithin : ‖derivWithin f s x‖ = ‖fderivWithin 𝕜 f s x‖ := by simp [← toSpanSingleton_derivWithin] theorem fderiv_apply_one_eq_deriv : (fderiv 𝕜 f x : 𝕜 → F) 1 = deriv f x := rfl -@[deprecated (since := "2025-12-18")] alias fderiv_deriv := fderiv_apply_one_eq_deriv - @[simp] theorem fderiv_eq_smul_deriv (y : 𝕜) : (fderiv 𝕜 f x : 𝕜 → F) y = y • deriv f x := by rw [← fderiv_apply_one_eq_deriv, ← map_smul] @@ -468,8 +464,6 @@ theorem fderiv_eq_smul_deriv (y : 𝕜) : (fderiv 𝕜 f x : 𝕜 → F) y = y theorem toSpanSingleton_deriv : toSpanSingleton 𝕜 (deriv f x) = fderiv 𝕜 f x := by simp only [deriv, ContinuousLinearMap.toSpanSingleton_apply_map_one] -@[deprecated (since := "2025-12-18")] alias deriv_fderiv := toSpanSingleton_deriv - lemma fderiv_eq_deriv_mul {f : 𝕜 → 𝕜} {x y : 𝕜} : (fderiv 𝕜 f x : 𝕜 → 𝕜) y = (deriv f x) * y := by simp [mul_comm] diff --git a/Mathlib/Analysis/Calculus/Deriv/Mul.lean b/Mathlib/Analysis/Calculus/Deriv/Mul.lean index f2ee38a74335a6..f688112f3812e3 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Mul.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Mul.lean @@ -33,8 +33,6 @@ open scoped Topology Filter ENNReal open Filter Asymptotics Set -open ContinuousLinearMap (smulRight smulRight_one_eq_iff) - variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] variable {E : Type w} [NormedAddCommGroup E] [NormedSpace 𝕜 E] diff --git a/Mathlib/Analysis/Complex/Basic.lean b/Mathlib/Analysis/Complex/Basic.lean index ded2fe18b25a89..86fff003bf0e4d 100644 --- a/Mathlib/Analysis/Complex/Basic.lean +++ b/Mathlib/Analysis/Complex/Basic.lean @@ -205,11 +205,6 @@ theorem restrictScalars_toSpanSingleton (x : ℂ) : dsimp apply mul_comm -@[deprecated (since := "2025-12-18")] alias restrictScalars_one_smulRight' := - restrictScalars_toSpanSingleton' -@[deprecated (since := "2025-12-18")] alias restrictScalars_one_smulRight := - restrictScalars_toSpanSingleton - /-- The complex-conjugation function from `ℂ` to itself is an isometric linear equivalence. -/ def conjLIE : ℂ ≃ₗᵢ[ℝ] ℂ := ⟨conjAe.toLinearEquiv, norm_conj⟩ diff --git a/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean b/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean index 04852c3720b6d7..a533a0991f2211 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean @@ -162,8 +162,6 @@ theorem characteristic_mul_zero_le {f₁ f₂ : ℂ → ℂ} {r : ℝ} (hr : 1 apply add_le_add (proximity_mul_zero_le h₁f₁ h₁f₂ r) (logCounting_mul_zero_le hr h₁f₁ h₂f₁ h₁f₂ h₂f₂) -@[deprecated (since := "2025-12-11")] alias characteristic_zero_mul_le := characteristic_mul_zero_le - /-- Asymptotically, the characteristic function for the zeros of `f * g` is less than or equal to the sum of the characteristic functions for the zeros of `f` and `g`, respectively. @@ -175,9 +173,6 @@ theorem characteristic_mul_zero_eventuallyLE {f₁ f₂ : ℂ → ℂ} filter_upwards [Filter.eventually_ge_atTop 1] using fun _ hr ↦ characteristic_mul_zero_le hr h₁f₁ h₂f₁ h₁f₂ h₂f₂ -@[deprecated (since := "2025-12-11")] -alias characteristic_zero_mul_eventually_le := characteristic_mul_zero_eventuallyLE - /-- For `1 ≤ r`, the characteristic function for the poles of `f * g` is less than or equal to the sum of the characteristic functions for the poles of `f` and `g`, respectively. @@ -191,8 +186,6 @@ theorem characteristic_mul_top_le {f₁ f₂ : ℂ → ℂ} {r : ℝ} (hr : 1 apply add_le_add (proximity_mul_top_le h₁f₁ h₁f₂ r) (logCounting_mul_top_le hr h₁f₁ h₂f₁ h₁f₂ h₂f₂) -@[deprecated (since := "2025-12-11")] alias characteristic_top_mul_le := characteristic_mul_top_le - /-- Asymptotically, the characteristic function for the poles of `f * g` is less than or equal to the sum of the characteristic functions for the poles of `f` and `g`, respectively. @@ -204,9 +197,6 @@ theorem characteristic_mul_top_eventuallyLE {f₁ f₂ : ℂ → ℂ} filter_upwards [Filter.eventually_ge_atTop 1] using fun _ hr ↦ characteristic_mul_top_le hr h₁f₁ h₂f₁ h₁f₂ h₂f₂ -@[deprecated (since := "2025-12-11")] -alias characteristic_top_mul_eventually_le := characteristic_mul_top_eventuallyLE - /-- For natural numbers `n`, the characteristic function for the zeros of `f ^ n` equals `n` times the characteristic counting function for the zeros of `f`. diff --git a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean index acc488b6b18548..23e9f3735672a1 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean @@ -245,8 +245,6 @@ theorem logCounting_eventuallyLE {E : Type*} [NormedAddCommGroup E] [ProperSpace logCounting f₁ ≤ᶠ[atTop] logCounting f₂ := by filter_upwards [eventually_ge_atTop 1] using fun _ hr ↦ logCounting_le h hr -@[deprecated (since := "2025-12-11")] alias logCounting_eventually_le := logCounting_eventuallyLE - end Function.locallyFinsuppWithin /-! @@ -506,8 +504,6 @@ theorem logCounting_mul_zero_le {f₁ f₂ : 𝕜 → 𝕜} {r : ℝ} (hr : 1 apply locallyFinsuppWithin.logCounting_le _ hr apply locallyFinsuppWithin.posPart_add -@[deprecated (since := "2025-12-11")] alias logCounting_zero_mul_le := logCounting_mul_zero_le - /-- Asymptotically, the logarithmic counting function for the zeros of `f * g` is less than or equal to the sum of the logarithmic counting functions for the zeros of `f` and `g`, respectively. @@ -519,9 +515,6 @@ theorem logCounting_mul_zero_eventuallyLE {f₁ f₂ : 𝕜 → 𝕜} filter_upwards [eventually_ge_atTop 1] using fun _ hr ↦ logCounting_mul_zero_le hr h₁f₁ h₂f₁ h₁f₂ h₂f₂ -@[deprecated (since := "2025-12-11")] -alias logCounting_zero_mul_eventually_le := logCounting_mul_zero_eventuallyLE - /-- For `1 ≤ r`, the logarithmic counting function for the poles of `f * g` is less than or equal to the sum of the logarithmic counting functions for the poles of `f` and `g`, respectively. @@ -536,8 +529,6 @@ theorem logCounting_mul_top_le {f₁ f₂ : 𝕜 → 𝕜} {r : ℝ} (hr : 1 ≤ apply locallyFinsuppWithin.logCounting_le _ hr apply locallyFinsuppWithin.negPart_add -@[deprecated (since := "2025-12-11")] alias logCounting_top_mul_le := logCounting_mul_top_le - /-- Asymptotically, the logarithmic counting function for the zeros of `f * g` is less than or equal to the sum of the logarithmic counting functions for the zeros of `f` and `g`, respectively. @@ -549,9 +540,6 @@ theorem logCounting_mul_top_eventuallyLE {f₁ f₂ : 𝕜 → 𝕜} filter_upwards [eventually_ge_atTop 1] using fun _ hr ↦ logCounting_mul_top_le hr h₁f₁ h₂f₁ h₁f₂ h₂f₂ -@[deprecated (since := "2025-12-11")] -alias logCounting_top_mul_eventually_le := logCounting_mul_top_eventuallyLE - /-- For natural numbers `n`, the logarithmic counting function for the zeros of `f ^ n` equals `n` times the logarithmic counting function for the zeros of `f`. diff --git a/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean b/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean index 6edcc952ca63ff..4af4060485c837 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean @@ -228,8 +228,6 @@ theorem proximity_mul_top_le {f₁ f₂ : ℂ → ℂ} (h₁f₁ : Meromorphic f · exact MeromorphicOn.circleIntegrable_posLog_norm (fun x a ↦ h₁f₂ x) _ = proximity f₁ ⊤ + proximity f₂ ⊤ := by simp [proximity] -@[deprecated (since := "2025-12-11")] alias proximity_top_mul_le := proximity_mul_top_le - /-- The proximity function `f * g` at `0` is less than or equal to the sum of the proximity functions of `f` and `g`, respectively. @@ -243,8 +241,6 @@ theorem proximity_mul_zero_le {f₁ f₂ : ℂ → ℂ} (h₁f₁ : Meromorphic _ = (proximity f₁ 0) + (proximity f₂ 0) := by rw [proximity_inv, proximity_inv] -@[deprecated (since := "2025-12-11")] alias proximity_zero_mul_le := proximity_mul_zero_le - /-- For natural numbers `n`, the proximity function of `f ^ n` at `⊤` equals `n` times the proximity function of `f` at `⊤`. diff --git a/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean b/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean index 08ff71a07bec34..037760b7168e25 100644 --- a/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean +++ b/Mathlib/Analysis/Distribution/AEEqOfIntegralContDiff.lean @@ -114,9 +114,6 @@ theorem ae_eq_zero_of_integral_contMDiff_smul_eq_zero [SigmaCompactSpace M] simpa [g_supp] using vK n simpa [this] using L -@[deprecated (since := "2025-12-17")] -alias ae_eq_zero_of_integral_smooth_smul_eq_zero := ae_eq_zero_of_integral_contMDiff_smul_eq_zero - -- An instance with keys containing `Opens` instance (U : Opens M) : BorelSpace U := inferInstanceAs (BorelSpace (U : Set M)) @@ -146,10 +143,6 @@ theorem IsOpen.ae_eq_zero_of_integral_contMDiff_smul_eq_zero' {U : Set M} (hU : · apply zero_smul · rintro ⟨x, rfl⟩; exact x.2 -@[deprecated (since := "2025-12-17")] -alias IsOpen.ae_eq_zero_of_integral_smooth_smul_eq_zero' := - IsOpen.ae_eq_zero_of_integral_contMDiff_smul_eq_zero' - variable [SigmaCompactSpace M] theorem IsOpen.ae_eq_zero_of_integral_contMDiff_smul_eq_zero {U : Set M} (hU : IsOpen U) @@ -165,10 +158,6 @@ theorem IsOpen.ae_eq_zero_of_integral_contMDiff_smul_eq_zero {U : Set M} (hU : I hU.ae_eq_zero_of_integral_contMDiff_smul_eq_zero' _ (isSigmaCompact_iff_sigmaCompactSpace.mpr inferInstance) hf h -@[deprecated (since := "2025-12-17")] -alias IsOpen.ae_eq_zero_of_integral_smooth_smul_eq_zero := - IsOpen.ae_eq_zero_of_integral_contMDiff_smul_eq_zero - /-- If two locally integrable functions on a finite-dimensional real manifold have the same integral when multiplied by any smooth compactly supported function, then they coincide almost everywhere. -/ theorem ae_eq_of_integral_contMDiff_smul_eq @@ -186,9 +175,6 @@ theorem ae_eq_of_integral_contMDiff_smul_eq filter_upwards [this] with x hx simpa [sub_eq_zero] using hx -@[deprecated (since := "2025-12-17")] -alias ae_eq_of_integral_smooth_smul_eq := ae_eq_of_integral_contMDiff_smul_eq - end Manifold section VectorSpace diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean index 3b24d3f773f237..a2fb1ea5576e0f 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean @@ -126,30 +126,9 @@ open LineDeriv theorem lineDerivOpCLM_eq (m : E) : lineDerivOpCLM 𝕜 𝓢(E, F) m = SchwartzMap.evalCLM 𝕜 E F m ∘L fderivCLM 𝕜 E F := rfl -@[deprecated (since := "2025-11-25")] -alias pderivCLM := lineDerivOpCLM - -@[deprecated (since := "2025-11-25")] -alias pderivCLM_apply := LineDeriv.lineDerivOpCLM_apply - theorem lineDerivOp_apply (m : E) (f : 𝓢(E, F)) (x : E) : ∂_{m} f x = lineDeriv ℝ f x m := f.differentiableAt.lineDeriv_eq_fderiv.symm -@[deprecated (since := "2025-11-25")] -alias iteratedPDeriv := LineDeriv.iteratedLineDerivOpCLM - -@[deprecated (since := "2025-11-25")] -alias iteratedPDeriv_zero := LineDeriv.iteratedLineDerivOp_zero - -@[deprecated (since := "2025-11-25")] -alias iteratedPDeriv_one := LineDeriv.iteratedLineDerivOp_one - -@[deprecated (since := "2025-11-25")] -alias iteratedPDeriv_succ_left := LineDeriv.iteratedLineDerivOp_succ_left - -@[deprecated (since := "2025-11-25")] -alias iteratedPDeriv_succ_right := LineDeriv.iteratedLineDerivOp_succ_right - theorem iteratedLineDerivOp_eq_iteratedFDeriv {n : ℕ} {m : Fin n → E} {f : 𝓢(E, F)} {x : E} : ∂^{m} f x = iteratedFDeriv ℝ n f x m := by induction n generalizing x with @@ -160,9 +139,6 @@ theorem iteratedLineDerivOp_eq_iteratedFDeriv {n : ℕ} {m : Fin n → E} {f : · simp only [lineDerivOp_apply_eq_fderiv, ← ih] · exact (f.smooth ⊤).differentiable_iteratedFDeriv (mod_cast ENat.coe_lt_top n) x -@[deprecated (since := "2025-11-25")] -alias iteratedPDeriv_eq_iteratedFDeriv := iteratedLineDerivOp_eq_iteratedFDeriv - end fderiv variable [NormedAddCommGroup D] [NormedSpace ℝ D] diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean index f42601caf9d4b2..29b759c53de55f 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean @@ -241,9 +241,6 @@ theorem integral_bilin_fourier_eq (f : 𝓢(V, E)) (g : 𝓢(V, F)) (M : E →L[ simpa using! VectorFourier.integral_bilin_fourierIntegral_eq_flip M (L := innerₗ V) continuous_fourierChar continuous_inner f.integrable g.integrable -@[deprecated (since := "2025-11-16")] -alias integral_bilin_fourierIntegral_eq := integral_bilin_fourier_eq - /-- The Fourier transform satisfies `∫ 𝓕 f • g = ∫ f • 𝓕 g`, i.e., it is self-adjoint. -/ theorem integral_fourier_smul_eq (f : 𝓢(V, ℂ)) (g : 𝓢(V, F)) : ∫ ξ, 𝓕 f ξ • g ξ = ∫ x, f x • 𝓕 g x := @@ -278,9 +275,6 @@ theorem integral_sesq_fourier_eq (f : 𝓢(V, E)) (g : 𝓢(V, F)) (M : E →L simpa [fourierInv_coe] using! VectorFourier.integral_sesq_fourierIntegral_eq_neg_flip M (L := innerₗ V) continuous_fourierChar continuous_inner f.integrable g.integrable -@[deprecated (since := "2025-11-16")] -alias integral_sesq_fourierIntegral_eq := integral_sesq_fourier_eq - /-- Plancherel's theorem for Schwartz functions. Version where the inner product is replaced by a general sesquilinear form `M`. -/ diff --git a/Mathlib/Analysis/Distribution/TemperedDistribution.lean b/Mathlib/Analysis/Distribution/TemperedDistribution.lean index 713e7dd5da0358..3bbfd124249ffd 100644 --- a/Mathlib/Analysis/Distribution/TemperedDistribution.lean +++ b/Mathlib/Analysis/Distribution/TemperedDistribution.lean @@ -602,16 +602,10 @@ def delta (x : E) : 𝓢'(E, ℂ) := toPointwiseConvergenceCLM _ _ _ _ <| (BoundedContinuousFunction.evalCLM ℂ x).comp (toBoundedContinuousFunctionCLM ℂ E ℂ) -@[deprecated (since := "2025-12-23")] -noncomputable alias _root_.SchwartzMap.delta := delta - @[simp] theorem delta_apply (x : E) (f : 𝓢(E, ℂ)) : delta x f = f x := rfl -@[deprecated (since := "2025-12-23")] -alias _root_.SchwartzMap.delta_apply := delta_apply - open MeasureTheory MeasureTheory.Measure variable [MeasurableSpace E] [BorelSpace E] [SecondCountableTopology E] @@ -621,9 +615,6 @@ variable [MeasurableSpace E] [BorelSpace E] [SecondCountableTopology E] theorem toTemperedDistribution_dirac_eq_delta (x : E) : (dirac x).toTemperedDistribution = delta x := by aesop -@[deprecated (since := "2025-12-23")] -alias _root_.SchwartzMap.integralCLM_dirac_eq_delta := toTemperedDistribution_dirac_eq_delta - end definition variable [InnerProductSpace ℝ E] [FiniteDimensional ℝ E] [MeasurableSpace E] [BorelSpace E] diff --git a/Mathlib/Analysis/Distribution/TestFunction.lean b/Mathlib/Analysis/Distribution/TestFunction.lean index 8ccaddbd709770..1069c26c593bde 100644 --- a/Mathlib/Analysis/Distribution/TestFunction.lean +++ b/Mathlib/Analysis/Distribution/TestFunction.lean @@ -323,15 +323,11 @@ noncomputable def ofSupportedInCLM [SMulCommClass ℝ 𝕜 F] {K : Compacts E} map_add' _ _ := rfl map_smul' _ _ := rfl -@[deprecated (since := "2025-12-10")] alias ofSupportedInLM := ofSupportedInCLM - @[simp] theorem coe_ofSupportedInCLM [SMulCommClass ℝ 𝕜 F] {K : Compacts E} (K_sub_Ω : (K : Set E) ⊆ Ω) : (ofSupportedInCLM 𝕜 K_sub_Ω : 𝓓^{n}_{K}(E, F) → 𝓓^{n}(Ω, F)) = ofSupportedIn K_sub_Ω := rfl -@[deprecated (since := "2025-12-10")] alias coe_ofSupportedInLM := coe_ofSupportedInCLM - /-- The **universal property** of the topology on `𝓓^{n}(Ω, F)`: a **linear** map from `𝓓^{n}(Ω, F)` to a locally convex topological vector space is continuous if and only if its precomposition with the inclusion `ofSupportedIn K_sub_Ω : 𝓓^{n}_{K}(E, F) → 𝓓^{n}(Ω, F)` is diff --git a/Mathlib/Analysis/Fourier/FourierTransform.lean b/Mathlib/Analysis/Fourier/FourierTransform.lean index 7d12ab08d9f1e3..0c2af6da809eaf 100644 --- a/Mathlib/Analysis/Fourier/FourierTransform.lean +++ b/Mathlib/Analysis/Fourier/FourierTransform.lean @@ -435,16 +435,10 @@ instance instFourierTransformInv : FourierTransformInv (V → E) (V → E) where lemma fourier_eq (f : V → E) (w : V) : 𝓕 f w = ∫ v, 𝐞 (-⟪v, w⟫) • f v := rfl -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_eq := fourier_eq - lemma fourier_eq' (f : V → E) (w : V) : 𝓕 f w = ∫ v, Complex.exp ((↑(-2 * π * ⟪v, w⟫) * Complex.I)) • f v := by simp_rw [fourier_eq, Circle.smul_def, Real.fourierChar_apply, mul_neg, neg_mul] -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_eq' := fourier_eq' - theorem fourier_congr_ae {f₁ f₂ : V → E} (hf : f₁ =ᵐ[volume] f₂) (x : V) : 𝓕 f₁ x = 𝓕 f₂ x := by apply integral_congr_ae filter_upwards [hf] with _ hf' @@ -454,31 +448,19 @@ lemma fourierInv_eq (f : V → E) (w : V) : 𝓕⁻ f w = ∫ v, 𝐞 ⟪v, w⟫ • f v := by simp [FourierTransformInv.fourierInv, VectorFourier.fourierIntegral] -@[deprecated (since := "2025-11-16")] -alias fourierIntegralInv_eq := fourierInv_eq - lemma fourierInv_eq' (f : V → E) (w : V) : 𝓕⁻ f w = ∫ v, Complex.exp ((↑(2 * π * ⟪v, w⟫) * Complex.I)) • f v := by simp_rw [fourierInv_eq, Circle.smul_def, Real.fourierChar_apply] -@[deprecated (since := "2025-11-16")] -alias fourierIntegralInv_eq' := fourierInv_eq' - lemma fourier_comp_linearIsometry (A : W ≃ₗᵢ[ℝ] V) (f : V → E) (w : W) : 𝓕 (f ∘ A) w = (𝓕 f) (A w) := by simp only [fourier_eq, ← A.inner_map_map, Function.comp_apply, ← MeasurePreserving.integral_comp A.measurePreserving A.toHomeomorph.measurableEmbedding] -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_comp_linearIsometry := fourier_comp_linearIsometry - lemma fourierInv_eq_fourier_neg (f : V → E) (w : V) : 𝓕⁻ f w = 𝓕 f (-w) := by simp [fourier_eq, fourierInv_eq] -@[deprecated (since := "2025-11-16")] -alias fourierIntegralInv_eq_fourierIntegral_neg := fourierInv_eq_fourier_neg - lemma fourierInv_eq_fourier_comp_neg (f : V → E) : 𝓕⁻ f = 𝓕 (fun x ↦ f (-x)) := by ext y @@ -486,58 +468,37 @@ lemma fourierInv_eq_fourier_comp_neg (f : V → E) : change 𝓕 f (LinearIsometryEquiv.neg ℝ y) = 𝓕 (f ∘ LinearIsometryEquiv.neg ℝ) y exact (fourier_comp_linearIsometry _ _ _).symm -@[deprecated (since := "2025-11-16")] -alias fourierIntegralInv_eq_fourierIntegral_comp_neg := fourierInv_eq_fourier_comp_neg - lemma fourierInv_comm (f : V → E) : 𝓕 (𝓕⁻ f) = 𝓕⁻ (𝓕 f) := by conv_rhs => rw [fourierInv_eq_fourier_comp_neg] simp_rw [← fourierInv_eq_fourier_neg] -@[deprecated (since := "2025-11-16")] -alias fourierIntegralInv_comm := fourierInv_comm - lemma fourierInv_comp_linearIsometry (A : W ≃ₗᵢ[ℝ] V) (f : V → E) (w : W) : 𝓕⁻ (f ∘ A) w = (𝓕⁻ f) (A w) := by simp [fourierInv_eq_fourier_neg, fourier_comp_linearIsometry] -@[deprecated (since := "2025-11-16")] -alias fourierIntegralInv_comp_linearIsometry := fourierInv_comp_linearIsometry - theorem fourier_real_eq (f : ℝ → E) (w : ℝ) : 𝓕 f w = ∫ v : ℝ, 𝐞 (-(v * w)) • f v := by simp_rw [mul_comm _ w] rfl -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_real_eq := fourier_real_eq - theorem fourier_real_eq_integral_exp_smul (f : ℝ → E) (w : ℝ) : 𝓕 f w = ∫ v : ℝ, Complex.exp (↑(-2 * π * v * w) * Complex.I) • f v := by simp_rw [fourier_real_eq, Circle.smul_def, Real.fourierChar_apply, mul_neg, neg_mul, mul_assoc] -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_real_eq_integral_exp_smul := fourier_real_eq_integral_exp_smul - theorem fourier_continuousLinearMap_apply {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] {f : V → (F →L[ℝ] E)} {a : F} {v : V} (hf : Integrable f) : 𝓕 f v a = 𝓕 (fun x ↦ f x a) v := fourierIntegral_continuousLinearMap_apply' (L := innerSL ℝ) hf -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_continuousLinearMap_apply := fourier_continuousLinearMap_apply - theorem fourier_continuousMultilinearMap_apply {ι : Type*} [Fintype ι] {M : ι → Type*} [∀ i, NormedAddCommGroup (M i)] [∀ i, NormedSpace ℝ (M i)] {f : V → ContinuousMultilinearMap ℝ M E} {m : (i : ι) → M i} {v : V} (hf : Integrable f) : 𝓕 f v m = 𝓕 (fun x ↦ f x m) v := fourierIntegral_continuousMultilinearMap_apply' (L := innerSL ℝ) hf -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_continuousMultilinearMap_apply := fourier_continuousMultilinearMap_apply - open scoped BoundedContinuousFunction /-- The Fourier transform from `L1` functions to bounded continuous functions. -/ diff --git a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean index 15d25a14e6e7a9..01d43a1b8b62e8 100644 --- a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean +++ b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean @@ -680,9 +680,6 @@ theorem hasFDerivAt_fourier HasFDerivAt (𝓕 f) (𝓕 (fourierSMulRight (innerSL ℝ) f) x) x := VectorFourier.hasFDerivAt_fourierIntegral (innerSL ℝ) hf_int hvf_int x -@[deprecated (since := "2025-11-16")] -alias hasFDerivAt_fourierIntegral := hasFDerivAt_fourier - /-- The Fréchet derivative of the Fourier transform of `f` is the Fourier transform of `fun v ↦ -2 * π * I ⟪v, ⬝⟫ f v`. -/ theorem fderiv_fourier @@ -690,17 +687,11 @@ theorem fderiv_fourier fderiv ℝ (𝓕 f) = 𝓕 (fourierSMulRight (innerSL ℝ) f) := VectorFourier.fderiv_fourierIntegral (innerSL ℝ) hf_int hvf_int -@[deprecated (since := "2025-11-16")] -alias fderiv_fourierIntegral := fderiv_fourier - theorem differentiable_fourier (hf_int : Integrable f) (hvf_int : Integrable (fun v ↦ ‖v‖ * ‖f v‖)) : Differentiable ℝ (𝓕 f) := VectorFourier.differentiable_fourierIntegral (innerSL ℝ) hf_int hvf_int -@[deprecated (since := "2025-11-16")] -alias differentiable_fourierIntegral := differentiable_fourier - /-- The Fourier integral of the Fréchet derivative of a function is obtained by multiplying the Fourier integral of the original function by `2πI ⟪v, w⟫`. -/ theorem fourier_fderiv @@ -709,18 +700,12 @@ theorem fourier_fderiv rw [← flip_innerSL_real V] exact VectorFourier.fourierIntegral_fderiv (innerSL ℝ) hf h'f hf' -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_fderiv := fourier_fderiv - /-- If `‖v‖^n * ‖f v‖` is integrable, then the Fourier transform of `f` is `C^n`. -/ theorem contDiff_fourier {N : ℕ∞} (hf : ∀ (n : ℕ), n ≤ N → Integrable (fun v ↦ ‖v‖ ^ n * ‖f v‖)) : ContDiff ℝ N (𝓕 f) := VectorFourier.contDiff_fourierIntegral (innerSL ℝ) hf -@[deprecated (since := "2025-11-16")] -alias contDiff_fourierIntegral := contDiff_fourier - /-- If `‖v‖^n * ‖f v‖` is integrable, then the `n`-th derivative of the Fourier transform of `f` is the Fourier transform of `fun v ↦ (-2 * π * I) ^ n ⟪v, ⬝⟫^n f v`. -/ theorem iteratedFDeriv_fourier {N : ℕ∞} @@ -729,9 +714,6 @@ theorem iteratedFDeriv_fourier {N : ℕ∞} iteratedFDeriv ℝ n (𝓕 f) = 𝓕 (fun v ↦ fourierPowSMulRight (innerSL ℝ) f v n) := VectorFourier.iteratedFDeriv_fourierIntegral (innerSL ℝ) hf h'f hn -@[deprecated (since := "2025-11-16")] -alias iteratedFDeriv_fourierIntegral := iteratedFDeriv_fourier - /-- The Fourier integral of the `n`-th derivative of a function is obtained by multiplying the Fourier integral of the original function by `(2πI L w ⬝ )^n`. -/ theorem fourier_iteratedFDeriv {N : ℕ∞} (hf : ContDiff ℝ N f) @@ -741,9 +723,6 @@ theorem fourier_iteratedFDeriv {N : ℕ∞} (hf : ContDiff ℝ N f) rw [← flip_innerSL_real V] exact VectorFourier.fourierIntegral_iteratedFDeriv (innerSL ℝ) hf h'f hn -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_iteratedFDeriv := fourier_iteratedFDeriv - set_option backward.isDefEq.respectTransparency false in set_option linter.flexible false in -- simp followed by positivity /-- One can bound `‖w‖^n * ‖D^k (𝓕 f) w‖` in terms of integrals of the derivatives of `f` (or order @@ -781,9 +760,6 @@ lemma pow_mul_norm_iteratedFDeriv_fourier_le gcongr exact norm_innerSL_le _ -@[deprecated (since := "2025-11-16")] -alias pow_mul_norm_iteratedFDeriv_fourierIntegral_le := pow_mul_norm_iteratedFDeriv_fourier_le - lemma hasDerivAt_fourier {f : ℝ → E} (hf : Integrable f) (hf' : Integrable (fun x : ℝ ↦ x • f x)) (w : ℝ) : HasDerivAt (𝓕 f) (𝓕 (fun x : ℝ ↦ (-2 * π * I * x) • f x) w) w := by @@ -804,18 +780,12 @@ lemma hasDerivAt_fourier simp [fourierSMulRight, L, smul_apply, ContinuousLinearMap.smulRight_apply, ContinuousLinearMap.mul_apply', ← neg_mul, mul_smul] -@[deprecated (since := "2025-11-16")] -alias hasDerivAt_fourierIntegral := hasDerivAt_fourier - theorem deriv_fourier {f : ℝ → E} (hf : Integrable f) (hf' : Integrable (fun x : ℝ ↦ x • f x)) : deriv (𝓕 f) = 𝓕 (fun x : ℝ ↦ (-2 * π * I * x) • f x) := by ext x exact (hasDerivAt_fourier hf hf' x).deriv -@[deprecated (since := "2025-11-16")] -alias deriv_fourierIntegral := deriv_fourier - set_option backward.isDefEq.respectTransparency false in /-- The Fourier integral of the Fréchet derivative of a function is obtained by multiplying the Fourier integral of the original function by `2πI x`. -/ @@ -832,9 +802,6 @@ theorem fourier_deriv simp only [fourierSMulRight_apply, neg_apply, innerSL_apply_apply ℝ, smul_smul, RCLike.inner_apply', conj_trivial, mul_one, neg_smul, smul_neg, neg_neg, neg_mul, ← coe_smul] -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_deriv := fourier_deriv - set_option backward.isDefEq.respectTransparency false in theorem iteratedDeriv_fourier {f : ℝ → E} {N : ℕ∞} {n : ℕ} (hf : ∀ (n : ℕ), n ≤ N → Integrable (fun x ↦ x ^ n • f x)) (hn : n ≤ N) : @@ -852,9 +819,6 @@ theorem iteratedDeriv_fourier {f : ℝ → E} {N : ℕ∞} {n : ℕ} simpa [innerSL_apply_apply _] simp only [← neg_mul, ← coe_smul, smul_smul, mul_pow, ofReal_pow, mul_assoc] -@[deprecated (since := "2025-11-16")] -alias iteratedDeriv_fourierIntegral := iteratedDeriv_fourier - set_option backward.isDefEq.respectTransparency false in theorem fourier_iteratedDeriv {f : ℝ → E} {N : ℕ∞} {n : ℕ} (hf : ContDiff ℝ N f) (h'f : ∀ (n : ℕ), n ≤ N → Integrable (iteratedDeriv n f)) (hn : n ≤ N) : @@ -869,7 +833,4 @@ theorem fourier_iteratedDeriv {f : ℝ → E} {N : ℕ∞} {n : ℕ} (hf : ContD fourier_iteratedFDeriv hf A hn] simp [← coe_smul, smul_smul, ← mul_pow, innerSL_apply_apply ℝ] -@[deprecated (since := "2025-11-16")] -alias fourierIntegral_iteratedDeriv := fourier_iteratedDeriv - end Real diff --git a/Mathlib/Analysis/Fourier/Inversion.lean b/Mathlib/Analysis/Fourier/Inversion.lean index ab7fa0a19f78a1..5fecc40d5bcbdc 100644 --- a/Mathlib/Analysis/Fourier/Inversion.lean +++ b/Mathlib/Analysis/Fourier/Inversion.lean @@ -168,9 +168,6 @@ theorem MeasureTheory.Integrable.fourierInv_fourier_eq tendsto_nhds_unique (Real.tendsto_integral_gaussian_smul hf h'f v) (Real.tendsto_integral_gaussian_smul' hf hv) -@[deprecated (since := "2025-11-16")] -alias MeasureTheory.Integrable.fourier_inversion := MeasureTheory.Integrable.fourierInv_fourier_eq - /-- **Fourier inversion formula**: If a function `f` on a finite-dimensional real inner product space is continuous, integrable, and its Fourier transform `𝓕 f` is also integrable, then `𝓕⁻ (𝓕 f) = f`. -/ @@ -180,9 +177,6 @@ theorem Continuous.fourierInv_fourier_eq (h : Continuous f) ext v exact hf.fourierInv_fourier_eq h'f h.continuousAt -@[deprecated (since := "2025-11-16")] -alias Continuous.fourier_inversion := Continuous.fourierInv_fourier_eq - /-- **Fourier inversion formula**: If a function `f` on a finite-dimensional real inner product space is integrable, and its Fourier transform `𝓕 f` is also integrable, then `𝓕 (𝓕⁻ f) = f` at continuity points of `f`. -/ @@ -192,10 +186,6 @@ theorem MeasureTheory.Integrable.fourier_fourierInv_eq rw [fourierInv_comm] exact hf.fourierInv_fourier_eq h'f hv -@[deprecated (since := "2025-11-16")] -alias MeasureTheory.Integrable.fourier_inversion_inv := - MeasureTheory.Integrable.fourier_fourierInv_eq - /-- **Fourier inversion formula**: If a function `f` on a finite-dimensional real inner product space is continuous, integrable, and its Fourier transform `𝓕 f` is also integrable, then `𝓕 (𝓕⁻ f) = f`. -/ @@ -204,6 +194,3 @@ theorem Continuous.fourier_fourierInv_eq (h : Continuous f) 𝓕 (𝓕⁻ f) = f := by ext v exact hf.fourier_fourierInv_eq h'f h.continuousAt - -@[deprecated (since := "2025-11-16")] -alias Continuous.fourier_inversion_inv := Continuous.fourier_fourierInv_eq diff --git a/Mathlib/Analysis/Fourier/LpSpace.lean b/Mathlib/Analysis/Fourier/LpSpace.lean index 5475d647eb65ba..936f6b6edc9304 100644 --- a/Mathlib/Analysis/Fourier/LpSpace.lean +++ b/Mathlib/Analysis/Fourier/LpSpace.lean @@ -104,9 +104,6 @@ theorem SchwartzMap.toLp_fourier_eq (f : 𝓢(E, F)) : 𝓕 (f.toLp 2) = (𝓕 f rw [one_mul] exact (norm_fourier_toL2_eq f).le -@[deprecated (since := "2025-12-31")] -alias SchwartzMap.toLp_fourierTransform_eq := SchwartzMap.toLp_fourier_eq - @[simp] theorem SchwartzMap.toLp_fourierInv_eq (f : 𝓢(E, F)) : 𝓕⁻ (f.toLp 2) = (𝓕⁻ f).toLp 2 := by apply LinearMap.extendOfNorm_eq @@ -117,9 +114,6 @@ theorem SchwartzMap.toLp_fourierInv_eq (f : 𝓢(E, F)) : 𝓕⁻ (f.toLp 2) = ( convert! (norm_fourier_toL2_eq (𝓕⁻ f)).symm.le simp -@[deprecated (since := "2025-12-31")] -alias SchwartzMap.toLp_fourierTransformInv_eq := SchwartzMap.toLp_fourierInv_eq - namespace MeasureTheory.Lp /-- The `𝓢'`-Fourier transform and the `L2`-Fourier transform coincide on `L2`. -/ diff --git a/Mathlib/Analysis/Fourier/PoissonSummation.lean b/Mathlib/Analysis/Fourier/PoissonSummation.lean index 879d0af7daf25e..67d7184c603604 100644 --- a/Mathlib/Analysis/Fourier/PoissonSummation.lean +++ b/Mathlib/Analysis/Fourier/PoissonSummation.lean @@ -115,9 +115,6 @@ theorem Real.tsum_eq_tsum_fourier {f : C(ℝ, ℂ)} using (hasSum_apply (summable_of_locally_summable_norm h_norm).hasSum x).tsum_eq · simp_rw [← Real.fourierCoeff_tsum_comp_add h_norm, smul_eq_mul, F, coe_mk] -@[deprecated (since := "2025-11-16")] -alias Real.tsum_eq_tsum_fourierIntegral := Real.tsum_eq_tsum_fourier - section RpowDecay variable {E : Type*} [NormedAddCommGroup E] @@ -202,10 +199,6 @@ theorem Real.tsum_eq_tsum_fourier_of_rpow_decay_of_summable {f : ℝ → ℂ} (h ((isBigO_norm_restrict_cocompact ⟨_, hc⟩ (zero_lt_one.trans hb) hf K).comp_tendsto Int.tendsto_coe_cofinite)) hFf x -@[deprecated (since := "2025-11-16")] -alias Real.tsum_eq_tsum_fourierIntegral_of_rpow_decay_of_summable := - Real.tsum_eq_tsum_fourier_of_rpow_decay_of_summable - /-- **Poisson's summation formula**, assuming that both `f` and its Fourier transform decay as `|x| ^ (-b)` for some `1 < b`. (This is the one-dimensional case of Corollary VII.2.6 of Stein and Weiss, *Introduction to Fourier analysis on Euclidean spaces*.) -/ @@ -216,10 +209,6 @@ theorem Real.tsum_eq_tsum_fourier_of_rpow_decay {f : ℝ → ℂ} (hc : Continuo Real.tsum_eq_tsum_fourier_of_rpow_decay_of_summable hc hb hf (summable_of_isBigO (Real.summable_abs_int_rpow hb) (hFf.comp_tendsto Int.tendsto_coe_cofinite)) x -@[deprecated (since := "2025-11-16")] -alias Real.tsum_eq_tsum_fourierIntegral_of_rpow_decay := - Real.tsum_eq_tsum_fourier_of_rpow_decay - end RpowDecay section Schwartz @@ -234,7 +223,4 @@ theorem SchwartzMap.tsum_eq_tsum_fourier (f : 𝓢(ℝ, ℂ)) (x : ℝ) : apply Real.tsum_eq_tsum_fourier_of_rpow_decay f.continuous one_lt_two (f.isBigO_cocompact_rpow (-2)) ((𝓕 f).isBigO_cocompact_rpow (-2)) -@[deprecated (since := "2025-11-16")] -alias SchwartzMap.tsum_eq_tsum_fourierIntegral := SchwartzMap.tsum_eq_tsum_fourier - end Schwartz diff --git a/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean b/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean index d45231572cf6f0..cc05da867d4ffa 100644 --- a/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean +++ b/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean @@ -215,9 +215,6 @@ theorem Real.tendsto_integral_exp_smul_cocompact (f : ℝ → E) : theorem Real.zero_at_infty_fourier (f : ℝ → E) : Tendsto (𝓕 f) (cocompact ℝ) (𝓝 0) := tendsto_integral_exp_inner_smul_cocompact f -@[deprecated (since := "2025-11-16")] -alias Real.zero_at_infty_fourierIntegral := Real.zero_at_infty_fourier - /-- Riemann-Lebesgue lemma for functions on a finite-dimensional inner-product space, formulated via dual space. **Do not use** -- it is only a stepping stone to `tendsto_integral_exp_smul_cocompact` where the inner-product-space structure isn't required. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index 58848c1045874c..8cf730c18282a2 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -965,17 +965,11 @@ lemma coe_linearIsometryEquiv_apply (u : unitary (H →L[𝕜] H)) : linearIsometryEquiv u = (u : H →L[𝕜] H) := rfl -@[deprecated (since := "2025-12-16")] alias linearIsometryEquiv_coe_apply := - coe_linearIsometryEquiv_apply - @[simp] lemma coe_symm_linearIsometryEquiv_apply (e : H ≃ₗᵢ[𝕜] H) : linearIsometryEquiv.symm e = (e : H →L[𝕜] H) := rfl -@[deprecated (since := "2025-12-16")] alias linearIsometryEquiv_coe_symm_apply := - coe_symm_linearIsometryEquiv_apply - theorem conjStarAlgEquiv_unitaryLinearIsometryEquiv (u : unitary (H →L[𝕜] H)) : (linearIsometryEquiv u).conjStarAlgEquiv = conjStarAlgAut 𝕜 _ u := rfl diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index f4c81e88568377..cc210a09b4d727 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -153,9 +153,6 @@ variable {F} variable {𝕜} -@[deprecated (since := "2025-12-26")] alias sesqFormOfInner := innerₛₗ -@[deprecated (since := "2025-12-26")] noncomputable alias bilinFormOfRealInner := innerₗ - /-- An inner product with a sum on the left. -/ theorem sum_inner {ι : Type*} (s : Finset ι) (f : ι → E) (x : E) : ⟪∑ i ∈ s, f i, x⟫ = ∑ i ∈ s, ⟪f i, x⟫ := diff --git a/Mathlib/Analysis/InnerProductSpace/Laplacian.lean b/Mathlib/Analysis/InnerProductSpace/Laplacian.lean index 2041f4bc929c6d..e82438586aa992 100644 --- a/Mathlib/Analysis/InnerProductSpace/Laplacian.lean +++ b/Mathlib/Analysis/InnerProductSpace/Laplacian.lean @@ -139,9 +139,6 @@ noncomputable instance instLaplacian : Laplacian (E → F) (E → F) where laplacian f x := tensorIteratedFDerivTwo ℝ f x (InnerProductSpace.canonicalCovariantTensor E) -@[deprecated (since := "2025-12-31")] -alias InnerProduct.laplacian := _root_.Laplacian.laplacian - open Laplacian /-- diff --git a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean index 7a191b6d044670..5077f2a85bcd59 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean @@ -221,9 +221,6 @@ theorem orthogonalBilin_innerₗ {E} [NormedAddCommGroup E] [InnerProductSpace (K : Submodule ℝ E) : K.orthogonalBilin (innerₗ E) = Kᗮ := rfl -@[deprecated (since := "2025-12-26")] -alias bilinFormOfRealInner_orthogonal := orthogonalBilin_innerₗ - /-! ### Orthogonality of submodules diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 2910dcb346427c..bf7f2c14dd78e5 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -559,9 +559,6 @@ protected theorem orthogonalProjectionOnto_apply_eq_sum {U : Submodule 𝕜 E} simpa only [b.repr_apply_apply, inner_orthogonalProjectionOnto_eq_of_mem_left] using (b.sum_repr (U.orthogonalProjectionOnto x)).symm -@[deprecated (since := "2025-12-31")] alias orthogonalProjection_eq_sum := - OrthonormalBasis.orthogonalProjectionOnto_apply_eq_sum - @[deprecated (since := "2026-05-05")] alias orthogonalProjection_apply_eq_sum := OrthonormalBasis.orthogonalProjectionOnto_apply_eq_sum diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean index f3ddc25cb6926e..5640963319a3c1 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean @@ -173,9 +173,6 @@ theorem orthogonalProjectionOnto_apply_eq_projectionOnto [K.HasOrthogonalProject alias orthogonalProjection_apply_eq_linearProjOfIsCompl := orthogonalProjectionOnto_apply_eq_projectionOnto -@[deprecated (since := "2025-12-26")] alias orthogonalProjection_eq_linearProjOfIsCompl := - orthogonalProjectionOnto_apply_eq_projectionOnto - theorem toLinearMap_orthogonalProjectionOnto_eq_projectionOnto [K.HasOrthogonalProjection] : (K.orthogonalProjectionOnto : E →ₗ[𝕜] K) = K.projectionOnto _ K.isCompl_orthogonal := rfl @@ -183,16 +180,10 @@ theorem toLinearMap_orthogonalProjectionOnto_eq_projectionOnto [K.HasOrthogonalP alias toLinearMap_orthogonalProjection_eq_linearProjOfIsCompl := toLinearMap_orthogonalProjectionOnto_eq_projectionOnto -@[deprecated (since := "2025-12-26")] alias orthogonalProjection_coe_eq_linearProjOfIsCompl := - toLinearMap_orthogonalProjectionOnto_eq_projectionOnto - open Submodule in theorem toLinearMap_starProjection_eq_isComplProjection [K.HasOrthogonalProjection] : K.starProjection.toLinearMap = K.projection Kᗮ K.isCompl_orthogonal := rfl -@[deprecated (since := "2025-12-26")] alias starProjection_coe_eq_isCompl_projection := - toLinearMap_starProjection_eq_isComplProjection - open Submodule in theorem starProjection_apply_eq_isComplProjection [K.HasOrthogonalProjection] (x : E) : K.starProjection x = K.projection Kᗮ K.isCompl_orthogonal x := rfl diff --git a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean index 0ae3aa1b3cca3d..4509f6fb9bcfd1 100644 --- a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean +++ b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean @@ -374,8 +374,4 @@ theorem IsSymmetric.isSymmetric_smul_iff {f : E →ₗ[𝕜] E} (hf : f.IsSymmet end LinearMap -@[deprecated (since := "2025-12-28")] alias - ContinuousLinearMap.IsIdempotentElem.isSymmetric_iff_orthogonal_range := - LinearMap.IsIdempotentElem.isSymmetric_iff_orthogonal_range - end Normed diff --git a/Mathlib/Analysis/Matrix/Order.lean b/Mathlib/Analysis/Matrix/Order.lean index 20eec4b66f66bc..3325a479995e3d 100644 --- a/Mathlib/Analysis/Matrix/Order.lean +++ b/Mathlib/Analysis/Matrix/Order.lean @@ -338,9 +338,6 @@ def toMatrixInnerProductSpace (M : Matrix n n 𝕜) (hM : M.PosSemidef) : InnerProductSpace 𝕜 (Matrix n n 𝕜) := InnerProductSpace.ofCore _ -@[deprecated (since := "2025-11-18")] alias PosDef.matrixNormedAddCommGroup := - toMatrixNormedAddCommGroup - open scoped Norms.L2Operator in set_option backward.isDefEq.respectTransparency false in /-- The isometric continuous functional calculus on `Matrix n n 𝕜` arising from the operator norm diff --git a/Mathlib/Analysis/MellinInversion.lean b/Mathlib/Analysis/MellinInversion.lean index 26d5ba10ed9d78..37601adc7e7396 100644 --- a/Mathlib/Analysis/MellinInversion.lean +++ b/Mathlib/Analysis/MellinInversion.lean @@ -69,9 +69,6 @@ theorem mellin_eq_fourier (f : ℝ → E) {s : ℂ} : _ = 𝓕 (fun (u : ℝ) ↦ (Real.exp (-s.re * u) • f (Real.exp (-u)))) (s.im / (2 * π)) := by simp [fourier_eq', mul_comm (_ / _)] -@[deprecated (since := "2025-11-16")] -alias mellin_eq_fourierIntegral := mellin_eq_fourier - theorem mellinInv_eq_fourierInv (σ : ℝ) (f : ℂ → E) {x : ℝ} (hx : 0 < x) : mellinInv σ f x = (x : ℂ) ^ (-σ : ℂ) • 𝓕⁻ (fun (y : ℝ) ↦ f (σ + 2 * π * y * I)) (-Real.log x) := calc @@ -89,9 +86,6 @@ theorem mellinInv_eq_fourierInv (σ : ℝ) (f : ℂ → E) {x : ℝ} (hx : 0 < x _ = (x : ℂ) ^ (-σ : ℂ) • 𝓕⁻ (fun (y : ℝ) ↦ f (σ + 2 * π * y * I)) (-Real.log x) := by simp [fourierInv_eq', mul_comm (Real.log _)] -@[deprecated (since := "2025-11-16")] -alias mellinInv_eq_fourierIntegralInv := mellinInv_eq_fourierInv - variable [CompleteSpace E] /-- The inverse Mellin transform of the Mellin transform applied to `x > 0` is x. -/ @@ -128,6 +122,3 @@ theorem mellinInv_mellin_eq (σ : ℝ) (f : ℝ → E) {x : ℝ} (hx : 0 < x) (h norm_cast rw [← smul_assoc, smul_eq_mul, Real.rpow_neg hx.le, inv_mul_cancel₀ (ne_of_gt (rpow_pos_of_pos hx σ)), one_smul] - -@[deprecated (since := "2025-11-16")] -alias mellin_inversion := mellinInv_mellin_eq diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 8986659627ce08..7d58e0151fcf9a 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -386,11 +386,6 @@ protected theorem deriv [CompleteSpace E] {f : 𝕜 → E} {x : 𝕜} (h : Merom MeromorphicAt.meromorphicAt_congr this] fun_prop -@[deprecated MeromorphicAt.deriv (since := "2025-12-21")] -theorem fun_deriv [CompleteSpace E] {f : 𝕜 → E} {x : 𝕜} (h : MeromorphicAt f x) : - MeromorphicAt (fun z ↦ _root_.deriv f z) x := - h.deriv - /-- Iterated derivatives of meromorphic functions are meromorphic. -/ @@ -401,12 +396,6 @@ Iterated derivatives of meromorphic functions are meromorphic. | zero => exact h | succ n IH => simpa only [Function.iterate_succ', Function.comp_apply] using IH.deriv -@[deprecated MeromorphicAt.iterated_deriv (since := "2025-12-21")] -theorem fun_iterated_deriv [CompleteSpace E] {n : ℕ} {f : 𝕜 → E} {x : 𝕜} - (h : MeromorphicAt f x) : - MeromorphicAt (fun z ↦ _root_.deriv^[n] f z) x := - h.iterated_deriv - end MeromorphicAt section smul_iff @@ -614,21 +603,11 @@ include hf in /-- Derivatives of meromorphic functions are meromorphic. -/ protected theorem deriv [CompleteSpace E] : MeromorphicOn (deriv f) U := fun z hz ↦ (hf z hz).deriv -include hf in -@[deprecated MeromorphicOn.deriv (since := "2025-12-21")] -theorem fun_deriv [CompleteSpace E] : MeromorphicOn (fun z ↦ _root_.deriv f z) U := hf.deriv - include hf in /-- Iterated derivatives of meromorphic functions are meromorphic. -/ theorem iterated_deriv [CompleteSpace E] {n : ℕ} : MeromorphicOn (_root_.deriv^[n] f) U := fun z hz ↦ (hf z hz).iterated_deriv -include hf in -@[deprecated MeromorphicOn.iterated_deriv (since := "2025-12-21")] -theorem fun_iterated_deriv [CompleteSpace E] {n : ℕ} : - MeromorphicOn (fun z ↦ _root_.deriv^[n] f z) U := - hf.iterated_deriv - end arithmetic include hf in @@ -764,11 +743,6 @@ theorem countable_compl_analyticAt [SecondCountableTopology 𝕜] [CompleteSpace {z | AnalyticAt 𝕜 f z}ᶜ.Countable := by simpa using (h.meromorphicOn (s := univ)).countable_compl_analyticAt_inter -@[deprecated (since := "2025-12-21")] alias MeromorphicOn.countable_compl_analyticAt := - countable_compl_analyticAt -@[deprecated (since := "2025-12-21")] alias _root_.MeromorphicOn.countable_compl_analyticAt := - countable_compl_analyticAt - /-- Meromorphic functions are measurable. -/ @@ -783,7 +757,4 @@ Meromorphic functions are measurable. exact .of_union_range_cover (.subtype_coe h₂.measurableSet) (.subtype_coe h₁.measurableSet) (by simp [-mem_compl_iff]) h₃.restrict.measurable (measurable_of_countable _) -@[deprecated (since := "2025-12-21")] alias MeromorphicOn.measurable := measurable -@[deprecated (since := "2025-12-21")] alias _root_.MeromorphicOn.measurable := measurable - end Meromorphic diff --git a/Mathlib/Analysis/Normed/Field/Lemmas.lean b/Mathlib/Analysis/Normed/Field/Lemmas.lean index 63924b51505a9b..51dad45f85dc63 100644 --- a/Mathlib/Analysis/Normed/Field/Lemmas.lean +++ b/Mathlib/Analysis/Normed/Field/Lemmas.lean @@ -84,8 +84,6 @@ lemma inv_cobounded₀ : (cobounded α)⁻¹ = 𝓝[≠] 0 := by lemma inv_nhdsNE_zero : (𝓝[≠] (0 : α))⁻¹ = cobounded α := by rw [← inv_cobounded₀, inv_inv] -@[deprecated (since := "2025-11-26")] alias inv_nhdsWithin_ne_zero := inv_nhdsNE_zero - lemma tendsto_inv₀_cobounded' : Tendsto Inv.inv (cobounded α) (𝓝[≠] 0) := inv_cobounded₀.le @@ -95,9 +93,6 @@ theorem tendsto_inv₀_cobounded : Tendsto Inv.inv (cobounded α) (𝓝 0) := lemma tendsto_inv₀_nhdsNE_zero : Tendsto Inv.inv (𝓝[≠] 0) (cobounded α) := inv_nhdsNE_zero.le -@[deprecated (since := "2025-11-26")] -alias tendsto_inv₀_nhdsWithin_ne_zero := tendsto_inv₀_nhdsNE_zero - end Filter /-- If `s` is a set disjoint from `𝓝 0`, then `fun x ↦ x⁻¹` is uniformly continuous on `s`. -/ @@ -207,9 +202,6 @@ instance (priority := 100) NormedDivisionRing.to_isTopologicalDivisionRing : lemma tendsto_norm_inv_nhdsNE_zero_atTop : Tendsto (fun x : α ↦ ‖x⁻¹‖) (𝓝[≠] 0) atTop := tendsto_norm_cobounded_atTop.comp tendsto_inv₀_nhdsNE_zero -@[deprecated (since := "2025-11-26")] -alias NormedField.tendsto_norm_inv_nhdsNE_zero_atTop := tendsto_norm_inv_nhdsNE_zero_atTop - lemma tendsto_zpow_nhdsNE_zero_cobounded {m : ℤ} (hm : m < 0) : Tendsto (· ^ m) (𝓝[≠] 0) (cobounded α) := by obtain ⟨m, rfl⟩ := neg_surjective m @@ -217,11 +209,6 @@ lemma tendsto_zpow_nhdsNE_zero_cobounded {m : ℤ} (hm : m < 0) : simpa [Function.comp_def] using (tendsto_pow_cobounded_cobounded (by lia)).comp tendsto_inv₀_nhdsNE_zero -@[deprecated tendsto_zpow_nhdsNE_zero_cobounded (since := "2025-11-26")] -lemma NormedField.tendsto_norm_zpow_nhdsNE_zero_atTop {m : ℤ} (hm : m < 0) : - Tendsto (fun x : α ↦ ‖x ^ m‖) (𝓝[≠] 0) atTop := - tendsto_norm_cobounded_atTop.comp (tendsto_zpow_nhdsNE_zero_cobounded hm) - end NormedDivisionRing namespace NormedField diff --git a/Mathlib/Analysis/Normed/Field/WithAbs.lean b/Mathlib/Analysis/Normed/Field/WithAbs.lean index af3bd66ec4948b..b4ee450f5f102c 100644 --- a/Mathlib/Analysis/Normed/Field/WithAbs.lean +++ b/Mathlib/Analysis/Normed/Field/WithAbs.lean @@ -90,38 +90,6 @@ end CommRing variable {K : Type*} [Field K] {v : AbsoluteValue K ℝ} {L : Type*} [NormedField L] {f : WithAbs v →+* L} -/-- If the absolute value `v` factors through an embedding `f` into a normed field, then -`f` is an isometry. -/ -@[deprecated AddMonoidHomClass.isometry_of_norm (since := "2025-11-28")] -theorem isometry_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : Isometry f := - AddMonoidHomClass.isometry_of_norm _ h - -/-- If the absolute value `v` factors through an embedding `f` into a normed field, then -the pseudometric space associated to the absolute value is the same as the pseudometric space -induced by `f`. -/ -@[deprecated "Use `Isometry.dist_eq` in combination with `AddMonoidHomClass.isometry_of_norm`" - (since := "2025-11-28")] -theorem pseudoMetricSpace_induced_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : - PseudoMetricSpace.induced f inferInstance = (normedField v).toPseudoMetricSpace := by - ext; exact AddMonoidHomClass.isometry_of_norm _ h |>.dist_eq _ _ - -/-- If the absolute value `v` factors through an embedding `f` into a normed field, then -the uniform structure associated to the absolute value is the same as the uniform structure -induced by `f`. -/ -@[deprecated "Use `IsUniformInducing.comap_uniformSpace in combination` with - AddMonoidHomClass.isometry_of_norm" (since := "2025-11-28")] -theorem uniformSpace_comap_eq_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : - UniformSpace.comap f inferInstance = (normedField v).toUniformSpace := - IsUniformInducing.comap_uniformSpace - (AddMonoidHomClass.isometry_of_norm _ h).isUniformInducing - -/-- If the absolute value `v` factors through an embedding `f` into a normed field, then -`f` is uniform inducing. -/ -@[deprecated "Use `Isometry.isUniformInducing` in combination with - AddMonoidHomClass.isometry_of_norm" (since := "2025-11-28")] -theorem isUniformInducing_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : IsUniformInducing f := - (AddMonoidHomClass.isometry_of_norm _ h).isUniformInducing - end WithAbs namespace AbsoluteValue @@ -140,44 +108,6 @@ noncomputable instance : Coe K v.Completion where variable {L : Type*} [NormedField L] [CompleteSpace L] {f : WithAbs v →+* L} {v} -/-- If the absolute value of a normed field factors through an embedding into another normed field -`L`, then we can extend that embedding to an embedding on the completion `v.Completion →+* L`. -/ -@[deprecated "Use `Isometry.extensionHom` in combination with `AddMonoidHomClass.isometry_of_norm`" - (since := "2025-11-28")] -noncomputable abbrev extensionEmbedding_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : - v.Completion →+* L := (AddMonoidHomClass.isometry_of_norm _ h).extensionHom - -@[deprecated "Use `Isometry.extensionHom_coe` in combination with - `AddMonoidHomClass.isometry_of_norm`" (since := "2025-11-28")] -theorem extensionEmbedding_of_comp_coe (h : ∀ x, ‖f x‖ = v x.ofAbs) (x : K) : - (AddMonoidHomClass.isometry_of_norm _ h).extensionHom x = f ((equiv v).symm x) := - AddMonoidHomClass.isometry_of_norm _ h |>.extensionHom_coe _ - -/-- If the absolute value of a normed field factors through an embedding into another normed field, -then the extended embedding `v.Completion →+* L` preserves distances. -/ -@[deprecated "Use `Isometry.dist_eq` in combination with `AddMonoidHomClass.isometry_of_norm`" - (since := "2025-11-28")] -theorem extensionEmbedding_dist_eq_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) (x y : v.Completion) : - let f := AddMonoidHomClass.isometry_of_norm _ h |>.extensionHom - dist (f x) (f y) = dist x y := - AddMonoidHomClass.isometry_of_norm _ h |>.completion_extension.dist_eq _ _ - -/-- If the absolute value of a normed field factors through an embedding into another normed field, -then the extended embedding `v.Completion →+* L` is an isometry. -/ -@[deprecated "Use `Isometry.completion_extension` in combination with - `AddMonoidHomClass.isometry_of_norm`" (since := "2025-11-28")] -theorem isometry_extensionEmbedding_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : - Isometry (AddMonoidHomClass.isometry_of_norm _ h |>.extensionHom) := - AddMonoidHomClass.isometry_of_norm _ h |>.completion_extension - -/-- If the absolute value of a normed field factors through an embedding into another normed field, -then the extended embedding `v.Completion →+* L` is a closed embedding. -/ -@[deprecated "Use `Isometry.isClosedEmbedding` in combination with `Isometry.completion_extension` - and `AddMonoidHomClass.isometry_of_norm`" (since := "2025-11-28")] -theorem isClosedEmbedding_extensionEmbedding_of_comp (h : ∀ x, ‖f x‖ = v x.ofAbs) : - IsClosedEmbedding (AddMonoidHomClass.isometry_of_norm _ h |>.extensionHom) := - (AddMonoidHomClass.isometry_of_norm _ h).completion_extension.isClosedEmbedding - /-- If the absolute value of a normed field factors through an embedding into another normed field that is locally compact, then the completion of the first normed field is also locally compact. -/ theorem locallyCompactSpace [LocallyCompactSpace L] (h : Isometry f) : diff --git a/Mathlib/Analysis/Normed/Group/Continuity.lean b/Mathlib/Analysis/Normed/Group/Continuity.lean index e4e9048e9eaae7..062cd64a5c88bf 100644 --- a/Mathlib/Analysis/Normed/Group/Continuity.lean +++ b/Mathlib/Analysis/Normed/Group/Continuity.lean @@ -171,9 +171,6 @@ theorem Inseparable.enorm_eq_enorm {E : Type*} [TopologicalSpace E] [ContinuousE {u v : E} (h : Inseparable u v) : ‖u‖ₑ = ‖v‖ₑ := h.map continuous_enorm |>.eq -@[deprecated (since := "2025-12-23")] -alias Inseparable.enorm_eq_enorm' := Inseparable.enorm_eq_enorm - @[to_additive] theorem mem_closure_one_iff_norm {x : E} : x ∈ closure ({1} : Set E) ↔ ‖x‖ = 0 := by rw [← closedBall_zero', mem_closedBall_one_iff, (norm_nonneg' x).ge_iff_eq'] @@ -219,8 +216,6 @@ variable [TopologicalSpace E] [ContinuousENorm E] {a : E} {l : Filter α} {f : lemma Filter.Tendsto.enorm (h : Tendsto f l (𝓝 a)) : Tendsto (‖f ·‖ₑ) l (𝓝 ‖a‖ₑ) := .comp continuous_enorm.continuousAt h -@[deprecated (since := "2025-12-23")] alias Filter.Tendsto.enorm' := Filter.Tendsto.enorm - end ContinuousENorm section SeminormedGroup diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index bd2b72533cfd35..727ee0cd33c50b 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -1195,8 +1195,6 @@ def withLpProdCongr (f : α ≃ₗᵢ[𝕜] α') (g : β ≃ₗᵢ[𝕜] β') : __ := (f.toLinearEquiv.prodCongr g.toLinearEquiv).withLpCongr p norm_map' := (f.toLinearIsometry.withLpProdMap p g.toLinearIsometry).norm_map -@[deprecated (since := "2025-12-22")] alias _root_.LinearIsometry.withLpProdCongr := withLpProdCongr - /-- Commutativity of the `L^p` product as a linear isometric equivalence. -/ def withLpProdComm : WithLp p (α × β) ≃ₗᵢ[𝕜] WithLp p (β × α) where __ := (LinearEquiv.prodComm 𝕜 α β).withLpCongr p diff --git a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean index bca3379c205e6f..e7d7846c89702a 100644 --- a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean +++ b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean @@ -211,18 +211,10 @@ theorem isComplete_image_iff [SemilinearIsometryClass 𝓕 σ₁₂ E E₂] (f : IsComplete (f '' s) ↔ IsComplete s := _root_.isComplete_image_iff (SemilinearIsometryClass.isometry f).isUniformInducing -@[deprecated LinearIsometry.isComplete_image_iff (since := "2025-12-25")] -theorem isComplete_image_iff' (f : LinearIsometry σ₁₂ E E₂) {s : Set E} : - IsComplete (f '' s) ↔ IsComplete s := - LinearIsometry.isComplete_image_iff _ - theorem isComplete_map_iff [RingHomSurjective σ₁₂] {p : Submodule R E} : IsComplete (p.map f.toLinearMap : Set E₂) ↔ IsComplete (p : Set E) := isComplete_image_iff f -@[deprecated (since := "2025-12-25")] -alias isComplete_map_iff' := isComplete_map_iff - instance completeSpace_map [RingHomSurjective σ₁₂] (p : Submodule R E) [CompleteSpace p] : CompleteSpace (p.map (f : E →ₛₗ[σ₁₂] E₂)) := ((isComplete_map_iff f).2 <| completeSpace_coe_iff_isComplete.1 ‹_›).completeSpace_coe diff --git a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean index d5261c5c7fdc98..3c827acbd101df 100644 --- a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean +++ b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean @@ -155,9 +155,6 @@ theorem logMahlerMeasure_mul_eq_add_logMahlerMeasure {p q : ℂ[X]} (hpq : p * q (p * q).logMahlerMeasure = p.logMahlerMeasure + q.logMahlerMeasure := by simp_all [logMahlerMeasure_eq_log_MahlerMeasure, mahlerMeasure_mul, log_mul] -@[deprecated (since := "2025-11-17")] -alias logMahlerMeasure_mul_eq_add_logMahelerMeasure := logMahlerMeasure_mul_eq_add_logMahlerMeasure - theorem logMahlerMeasure_C_mul {a : ℂ} (ha : a ≠ 0) {p : ℂ[X]} (hp : p ≠ 0) : (C a * p).logMahlerMeasure = log ‖a‖ + p.logMahlerMeasure := by rw [logMahlerMeasure_mul_eq_add_logMahlerMeasure (by simp [ha, hp]), logMahlerMeasure_const] diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean index 924eb23fb2ce45..858c9750c8c623 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean @@ -224,17 +224,11 @@ theorem _root_.fourier_gaussian_pi' (hb : 0 < b.re) (c : ℂ) : simp only [I_sq] ring -@[deprecated (since := "2025-11-16")] -alias _root_.fourierIntegral_gaussian_pi' := _root_.fourier_gaussian_pi' - theorem _root_.fourier_gaussian_pi (hb : 0 < b.re) : (𝓕 fun (x : ℝ) ↦ cexp (-π * b * x ^ 2)) = fun t : ℝ ↦ 1 / b ^ (1 / 2 : ℂ) * cexp (-π / b * t ^ 2) := by simpa only [mul_zero, zero_mul, add_zero] using fourier_gaussian_pi' hb 0 -@[deprecated (since := "2025-11-16")] -alias _root_.fourierIntegral_gaussian_pi := _root_.fourier_gaussian_pi - section InnerProductSpace variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V] [FiniteDimensional ℝ V] @@ -354,19 +348,11 @@ theorem _root_.fourier_gaussian_innerProductSpace' (hb : 0 < b.re) (x w : V) : simp [mul_pow] ring -@[deprecated (since := "2025-11-16")] -alias _root_.fourierIntegral_gaussian_innerProductSpace' := - _root_.fourier_gaussian_innerProductSpace' - theorem _root_.fourier_gaussian_innerProductSpace (hb : 0 < b.re) (w : V) : 𝓕 (fun (v : V) ↦ cexp (-b * ‖v‖ ^ 2)) w = (π / b) ^ (Module.finrank ℝ V / 2 : ℂ) * cexp (-π ^ 2 * ‖w‖ ^ 2 / b) := by simpa using fourier_gaussian_innerProductSpace' hb 0 w -@[deprecated (since := "2025-11-16")] -alias _root_.fourierIntegral_gaussian_innerProductSpace := - _root_.fourier_gaussian_innerProductSpace - end InnerProductSpace end GaussianFourier diff --git a/Mathlib/CategoryTheory/Abelian/Basic.lean b/Mathlib/CategoryTheory/Abelian/Basic.lean index 1b63f75a0ce1fc..095d0d9648ba61 100644 --- a/Mathlib/CategoryTheory/Abelian/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/Basic.lean @@ -437,8 +437,6 @@ def coim : Arrow C ⥤ C where map {f g} u := cokernel.desc _ (u.left ≫ Abelian.coimage.π g.hom) <| by simp [← Category.assoc, coimage.comp_π_eq_zero]; simp -@[deprecated (since := "2025-10-31")] noncomputable alias coimageFunctor := coim - set_option backward.defeqAttrib.useBackward true in /-- The image and coimage of an arrow are naturally isomorphic. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean b/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean index 9bab7beb6d0118..093194dde1cb28 100644 --- a/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean +++ b/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean @@ -53,10 +53,6 @@ lemma isoModSerre_kernel_eq_isLocal_of_rightAdjoint rw [ObjectProperty.isLocal_eq_inverseImage_isomorphisms adj, isoModSerre_kernel_eq_inverseImage_isomorphisms] -@[deprecated (since := "2025-11-20")] -alias isoModSerre_kernel_eq_leftBousfield_W_of_rightAdjoint := - isoModSerre_kernel_eq_isLocal_of_rightAdjoint - lemma isLocalization_isoModSerre_kernel_of_leftAdjoint {F : C ⥤ D} (adj : G ⊣ F) [F.Full] [F.Faithful] : G.IsLocalization G.kernel.isoModSerre := by diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean b/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean index 6b667f8dbe50e3..36e6f17b2ad02e 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean @@ -102,8 +102,6 @@ instance epi_of_effectiveEpi {X Y : C} (f : Y ⟶ X) [EffectiveEpi f] : Epi f wh rw [show m₂ = desc f (f ≫ m₂) (fun _ _ h => by simp [← assoc, h]) from uniq _ _ _ _ rfl] exact uniq _ _ _ _ h -@[deprecated (since := "2025-11-20")] alias epiOfEffectiveEpi := epi_of_effectiveEpi - instance (priority := 100) strongEpi_of_effectiveEpi {X Y : C} (f : X ⟶ Y) [EffectiveEpi f] : StrongEpi f := StrongEpi.mk' fun A B z hz u v sq ↦ diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean b/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean index ddb1edf780ce77..fc2769652643b5 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean @@ -87,9 +87,6 @@ noncomputable def DenseAt.precompOfFinal (G ⋙ F).DenseAt Y := (DenseAt.precompEquivOfFinal G).symm hY -@[deprecated (since := "2025-12-17")] -alias DenseAt.precompEquivalence := DenseAt.precompOfFinal - set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ D` is dense at `Y : D` and `G : D ⥤ D'` is an equivalence, then `F ⋙ G` is dense at `G.obj Y`. -/ diff --git a/Mathlib/CategoryTheory/Groupoid.lean b/Mathlib/CategoryTheory/Groupoid.lean index 968883bf434261..1c6dd4771e7431 100644 --- a/Mathlib/CategoryTheory/Groupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid.lean @@ -100,12 +100,6 @@ def Groupoid.isoEquivHom : (X ≅ Y) ≃ (X ⟶ Y) where variable (C) -/-- The functor from a groupoid `C` to its opposite sending every morphism to its inverse. -/ -@[simps, deprecated "Use Groupoid.invEquivalence.functor" (since := "2025-12-31")] -def Groupoid.invFunctor : C ⥤ Cᵒᵖ where - obj := Opposite.op - map {_ _} f := (inv f).op - set_option backward.defeqAttrib.useBackward true in /-- The equivalence from a groupoid `C` to its opposite sending every morphism to its inverse. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/ExactFunctor.lean b/Mathlib/CategoryTheory/Limits/ExactFunctor.lean index 57581749c25f4e..1c7031acf93d9f 100644 --- a/Mathlib/CategoryTheory/Limits/ExactFunctor.lean +++ b/Mathlib/CategoryTheory/Limits/ExactFunctor.lean @@ -294,10 +294,4 @@ end end -@[deprecated (since := "2025-12-18")] alias LeftExactFunctor.ofExact_map := - LeftExactFunctor.ofExact_map_hom - -@[deprecated (since := "2025-12-18")] alias RightExactFunctor.ofExact_map := - RightExactFunctor.ofExact_map_hom - end CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index 4ea64dd9d69f3e..fd787fbeca2559 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -700,9 +700,6 @@ theorem ofPiFork_ι (a : Fork (I.fstPiMapOfIsLimit c hd) (I.sndPiMapOfIsLimit c (ofPiFork a).ι i = a.ι ≫ c.proj _ := rfl -@[deprecated (since := "2025-12-08")] -alias ofPiFork_π_app_left := ofPiFork_ι - @[simp] theorem ofPiFork_π_app_right (a : Fork (I.fstPiMapOfIsLimit c hd) (I.sndPiMapOfIsLimit c hd)) (i) : @@ -957,12 +954,6 @@ theorem ofSigmaCofork_π (ofSigmaCofork a).π i = d.inj i ≫ a.π := rfl -@[deprecated (since := "2025-12-08")] -alias ofSigmaCofork_ι_app_right := ofSigmaCofork_π - -@[deprecated (since := "2025-12-08")] -alias ofSigmaCofork_ι_app_right' := ofSigmaCofork_π - /-- Constructor for isomorphisms between multicoforks. -/ @[simps!] def ext {K K' : Multicofork I} diff --git a/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean b/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean index f7436a1a3ab60b..c0db8284a35a4c 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean @@ -118,9 +118,6 @@ lemma isRegularMono_of_regularMono {f : X ⟶ Y} (h : RegularMono f) : IsRegular def IsRegularMono.getStruct (f : X ⟶ Y) [IsRegularMono f] : RegularMono f := IsRegularMono.regularMono.some -@[deprecated (since := "2025-12-01")] noncomputable alias regularMonoOfIsRegularMono := - IsRegularMono.getStruct - /-- An equalizer diagram gives rise to a regular monomorphism. -/ def Fork.IsLimit.regularMono {A B : C} {p₁ p₂ : A ⟶ B} {c : Fork p₁ p₂} (h : IsLimit c) : RegularMono c.ι where @@ -374,9 +371,6 @@ lemma isRegularEpi_of_regularEpi {f : X ⟶ Y} (h : RegularEpi f) : IsRegularEpi def IsRegularEpi.getStruct (f : X ⟶ Y) [h : IsRegularEpi f] : RegularEpi f := h.regularEpi.some -@[deprecated (since := "2025-12-01")] noncomputable alias regularEpiOfIsRegularEpi := - IsRegularEpi.getStruct - /-- A coequalizer diagram gives rise to a regular epimorphism. -/ def Cofork.IsColimit.regularEpi {A B : C} {p₁ p₂ : A ⟶ B} {c : Cofork p₁ p₂} (h : IsColimit c) : RegularEpi c.π where @@ -495,8 +489,6 @@ theorem effectiveEpi_of_kernelPair {B X : C} (f : X ⟶ B) [HasPullback f f] (hc : IsColimit (Cofork.ofπ f pullback.condition)) : EffectiveEpi f := RegularEpi.effectiveEpi <| regularEpiOfKernelPair f hc -@[deprecated (since := "2025-11-20")] alias effectiveEpiOfKernelPair := effectiveEpi_of_kernelPair - set_option backward.isDefEq.respectTransparency false in /-- Given a kernel pair of an effective epimorphism `f : X ⟶ B`, the induced cofork is a coequalizer. @@ -607,11 +599,6 @@ def regularOfIsPushoutFstOfRegular {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h RegularEpi k := regularOfIsPushoutSndOfRegular hf comm.symm (PushoutCocone.flipIsColimit t) -@[deprecated "No replacement" (since := "2025-11-20")] -lemma strongEpi_of_regularEpi (f : X ⟶ Y) (h : RegularEpi f) : StrongEpi f := - have := isRegularEpi_of_regularEpi h - inferInstance - /-- A regular epimorphism is an isomorphism if it is a monomorphism. -/ theorem isIso_of_regularEpi_of_mono (f : X ⟶ Y) (h : RegularEpi f) [Mono f] : IsIso f := have := isRegularEpi_of_regularEpi h diff --git a/Mathlib/CategoryTheory/Localization/Bousfield.lean b/Mathlib/CategoryTheory/Localization/Bousfield.lean index 4a0358f853bfcf..83b745e18c0edf 100644 --- a/Mathlib/CategoryTheory/Localization/Bousfield.lean +++ b/Mathlib/CategoryTheory/Localization/Bousfield.lean @@ -298,28 +298,4 @@ lemma MorphismProperty.le_isColocal_isColocal (W : MorphismProperty C) : W ≤ W.isColocal.isColocal := by rw [ObjectProperty.le_isColocal_iff] -@[deprecated (since := "2025-11-20")] alias ObjectProperty.le_isLocal_W := - ObjectProperty.le_isLocal_isLocal -@[deprecated (since := "2025-11-20")] alias MorphismProperty.le_leftBousfieldW_isLocal := - MorphismProperty.le_isLocal_isLocal - -namespace Localization.LeftBousfield - -open ObjectProperty - -@[deprecated (since := "2025-11-20")] alias W := isLocal -@[deprecated (since := "2025-11-20")] alias W.homEquiv := isLocal.homEquiv -@[deprecated (since := "2025-11-20")] alias W_isoClosure := isoClosure_isLocal -@[deprecated (since := "2025-11-20")] alias W_of_isIso := isLocal_of_isIso -@[deprecated (since := "2025-11-20")] alias W_iff_isIso := isLocal_iff_isIso -@[deprecated (since := "2025-11-20")] alias le_W_iff := le_isLocal_iff -@[deprecated (since := "2025-11-20")] alias galoisConnection := galoisConnection_isLocal -@[deprecated (since := "2025-11-20")] alias W_adj_unit_app := isLocal_adj_unit_app -@[deprecated (since := "2025-11-20")] alias W_iff_isIso_map := isLocal_iff_isIso_map -@[deprecated (since := "2025-11-20")] alias W_eq_inverseImage_isomorphisms := - isLocal_eq_inverseImage_isomorphisms -@[deprecated (since := "2025-11-20")] alias isLocalization := isLocalization_isLocal - -end Localization.LeftBousfield - end CategoryTheory diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean index c2040bba245e85..5e500b0d9b2c30 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean @@ -127,9 +127,6 @@ lemma isIso_iff_of_isRightDerivabilityStructure (X : C₁) : ((Φ.rightDerivedFunctorComparison L₁ L₂ F F₁ α₁ F₂ α₂).app (L₁.obj X)), rightDerivedFunctorComparison_fac_app, isIso_comp_right_iff] -@[deprecated (since := "2025-11-16")] alias isIso_α_iff_of_isRightDerivabilityStructure := - isIso_iff_of_isRightDerivabilityStructure - end end LocalizerMorphism diff --git a/Mathlib/CategoryTheory/Localization/Opposite.lean b/Mathlib/CategoryTheory/Localization/Opposite.lean index 462ce42060bb2d..7dbe10b1cf84da 100644 --- a/Mathlib/CategoryTheory/Localization/Opposite.lean +++ b/Mathlib/CategoryTheory/Localization/Opposite.lean @@ -78,8 +78,6 @@ lemma IsLocalization.op_iff (L : C ⥤ D) (W : MorphismProperty C) : ⟨fun _ ↦ inferInstanceAs (L.op.unop.IsLocalization W.op.unop), fun _ ↦ inferInstance⟩ -@[deprecated (since := "2025-12-10")] alias op_iff := IsLocalization.op_iff - end Functor namespace Localization diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean index 7193f5f45864af..4d9cdeef1e52ad 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean @@ -517,12 +517,6 @@ set_option backward.privateInPublic true in lemma isoOfComponents_inv_hom_hom_app (X : C) : (isoOfComponents e naturality unit tensor).inv.hom.hom.app X = (e X).inv := rfl -@[deprecated (since := "2025-12-18")] alias isoOfComponents_hom_hom_app := - isoOfComponents_hom_hom_hom_app - -@[deprecated (since := "2025-12-18")] alias isoOfComponents_inv_hom_app := - isoOfComponents_inv_hom_hom_app - end end LaxBraidedFunctor diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean index fdff0703d10af5..243c2fd46acf72 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean @@ -285,10 +285,6 @@ lemma hom_hom_div (f g : G ⟶ H) : (f / g).hom.hom = f.hom.hom / g.hom.hom := r lemma hom_hom_zpow (f : G ⟶ H) (n : ℤ) : (f ^ n).hom.hom = f.hom.hom ^ n := by cases n <;> simp -@[deprecated (since := "2025-12-18")] alias hom_inv := hom_hom_inv -@[deprecated (since := "2025-12-18")] alias hom_div := hom_hom_div -@[deprecated (since := "2025-12-18")] alias hom_zpow := hom_hom_zpow - end Hom attribute [local simp] mul_eq_mul comp_mul mul_comm mul_div_mul_comm in diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean index bcc03e4a3b0405..b4a9f62541f33a 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean @@ -98,17 +98,6 @@ def powZero [BraidedCategory C] {I : C} (t : IsInitial I) [MonoidalClosed C] : I rw [← curry_natural_left, curry_eq_iff, ← cancel_epi (mulZero t).inv] apply t.hom_ext -set_option linter.overlappingInstances false in -set_option backward.isDefEq.respectTransparency false in --- TODO: Generalise the below to its commuted variants. --- TODO: Define a distributive category, so that zero_mul and friends can be derived from this. -/-- In a CCC with binary coproducts, the distribution morphism is an isomorphism. -/ -@[deprecated "No replacement: use `asIso (coprodComparison (tensorLeft Z) _ _)` instead." -(since := "2025-12-22")] -noncomputable def prodCoprodDistrib [MonoidalCategory C] [HasBinaryCoproducts C] - [MonoidalClosed C] (X Y Z : C) : (Z ⊗ X) ⨿ Z ⊗ Y ≅ Z ⊗ (X ⨿ Y) := - asIso (coprodComparison (tensorLeft Z) _ _) - /-- If an initial object `I` exists in a CCC then it is a strict initial object, i.e. any morphism to `I` is an iso. This actually shows a slightly stronger version: any morphism to an initial object from an @@ -152,76 +141,4 @@ noncomputable def cartesianClosedOfEquiv (e : C ≌ D) [MonoidalClosed C] : Mono end Functor -@[deprecated (since := "2025-12-22")] alias Exponentiable := Closed -@[deprecated (since := "2025-12-22")] alias Exponentiable.mk := Closed.mk -@[deprecated (since := "2025-12-22")] alias binaryProductExponentiable := tensorClosed -@[deprecated (since := "2025-12-22")] alias terminalExponentiable := unitClosed -@[deprecated (since := "2025-12-22")] alias CartesianClosed := MonoidalClosed -@[deprecated (since := "2025-12-22")] alias CartesianClosed.mk := MonoidalClosed.mk -@[deprecated (since := "2025-12-22")] alias exp := ihom -@[deprecated (since := "2025-12-22")] alias exp.adjunction := ihom.adjunction -@[deprecated (since := "2025-12-22")] alias exp.ev := ihom.ev -@[deprecated (since := "2025-12-22")] alias exp.coev := ihom.coev -@[deprecated (since := "2025-12-22")] alias exp.ev_coev := ihom.ev_coev -@[deprecated (since := "2025-12-22")] alias exp.coev_ev := ihom.coev_ev -@[deprecated (since := "2025-12-22")] alias exp.ev_coev_assoc := ihom.ev_coev_assoc -@[deprecated (since := "2025-12-22")] alias exp.coev_ev_assoc := ihom.coev_ev_assoc -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry := MonoidalClosed.curry -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry := MonoidalClosed.uncurry -@[deprecated (since := "2025-12-22")] alias CartesianClosed.homEquiv_apply_eq := - MonoidalClosed.homEquiv_apply_eq -@[deprecated (since := "2025-12-22")] alias CartesianClosed.homEquiv_symm_apply_eq := - MonoidalClosed.homEquiv_symm_apply_eq -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_natural_left := - MonoidalClosed.curry_natural_left -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_natural_left_assoc := - MonoidalClosed.curry_natural_left_assoc -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_natural_right := - MonoidalClosed.curry_natural_right -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_natural_right_assoc := - MonoidalClosed.curry_natural_right_assoc -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_natural_right := - MonoidalClosed.uncurry_natural_right -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_natural_right_assoc := - MonoidalClosed.uncurry_natural_right_assoc -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_natural_left := - MonoidalClosed.uncurry_natural_left -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_natural_left_assoc := - MonoidalClosed.uncurry_natural_left_assoc -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_curry := - MonoidalClosed.uncurry_curry -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_uncurry := - MonoidalClosed.curry_uncurry -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_eq_iff := - MonoidalClosed.curry_eq_iff -@[deprecated (since := "2025-12-22")] alias CartesianClosed.eq_curry_iff := - MonoidalClosed.eq_curry_iff -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_eq := - MonoidalClosed.uncurry_eq -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_eq := - MonoidalClosed.curry_eq -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_id_eq_ev := - MonoidalClosed.uncurry_id_eq_ev -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_id_eq_coev := - MonoidalClosed.curry_id_eq_coev -@[deprecated (since := "2025-12-22")] alias CartesianClosed.curry_injective := - MonoidalClosed.curry_injective -@[deprecated (since := "2025-12-22")] alias CartesianClosed.uncurry_injective := - MonoidalClosed.uncurry_injective -@[deprecated (since := "2025-12-22")] alias expUnitNatIso := MonoidalClosed.unitNatIso -@[deprecated (since := "2025-12-22")] alias expUnitIsoSelf := MonoidalClosed.unitIsoSelf -@[deprecated (since := "2025-12-22")] alias pre := MonoidalClosed.pre -@[deprecated (since := "2025-12-22")] alias prod_map_pre_app_comp_ev := - MonoidalClosed.id_tensor_pre_app_comp_ev -@[deprecated (since := "2025-12-22")] alias uncurry_pre := - MonoidalClosed.uncurry_pre -@[deprecated (since := "2025-12-22")] alias coev_app_comp_pre_app := - MonoidalClosed.coev_app_comp_pre_app -@[deprecated (since := "2025-12-22")] alias pre_id := - MonoidalClosed.pre_id -@[deprecated (since := "2025-12-22")] alias pre_map := - MonoidalClosed.pre_map -@[deprecated (since := "2025-12-22")] alias internalHom := - MonoidalClosed.internalHom - end CategoryTheory diff --git a/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean b/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean index e230ff0d1f5d7f..eb242b0aee7340 100644 --- a/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean +++ b/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean @@ -70,9 +70,6 @@ theorem comp_hom {R S T : CommGrp C} (f : R ⟶ S) (g : S ⟶ T) : theorem hom_ext {A B : CommGrp C} (f g : A ⟶ B) (h : f.hom.hom.hom = g.hom.hom.hom) : f = g := InducedCategory.hom_ext (Grp.hom_ext _ _ h) -@[deprecated (since := "2025-12-18")] alias id' := id_hom -@[deprecated (since := "2025-12-18")] alias comp' := comp_hom - section variable (C) @@ -173,9 +170,6 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic true in @[simp] lemma mkIso_inv_hom_hom_hom : (mkIso e one_f mul_f).inv.hom.hom.hom = e.inv := rfl -@[deprecated (since := "2025-12-18")] alias mkIso_hom_hom := mkIso_hom_hom_hom_hom -@[deprecated (since := "2025-12-18")] alias mkIso_inv_hom := mkIso_inv_hom_hom_hom - end instance uniqueHomFromTrivial (A : CommGrp C) : Unique (trivial C ⟶ A) := diff --git a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean index c81166b9bba582..b08457cd1cb678 100644 --- a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean @@ -223,15 +223,6 @@ instance {C D E : Type*} [Category* C] [Category* D] [Category* E] [MonoidalCate [MonoidalCategory E] (L : D ⥤ E) [L.Monoidal] : ((Functor.whiskeringRight C D E).obj L).Monoidal where -@[deprecated (since := "2025-11-06")] alias instLaxMonoidalFunctorObjWhiskeringRight := - Functor.LaxMonoidal.whiskeringRight -@[deprecated (since := "2025-11-06")] alias instOplaxMonoidalFunctorObjWhiskeringRight := - Functor.OplaxMonoidal.whiskeringRight -@[deprecated (since := "2025-11-06")] alias ε_app := Functor.LaxMonoidal.whiskeringRight_ε_app -@[deprecated (since := "2025-11-06")] alias μ_app := Functor.LaxMonoidal.whiskeringRight_μ_app -@[deprecated (since := "2025-11-06")] alias η_app := Functor.OplaxMonoidal.whiskeringRight_η_app -@[deprecated (since := "2025-11-06")] alias δ_app := Functor.OplaxMonoidal.whiskeringRight_δ_app - set_option backward.defeqAttrib.useBackward true in @[simps!] instance Functor.Monoidal.whiskeringLeft diff --git a/Mathlib/CategoryTheory/Monoidal/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Grp.lean index 5e32e6fbaad479..3340a51f486750 100644 --- a/Mathlib/CategoryTheory/Monoidal/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Grp.lean @@ -114,9 +114,6 @@ theorem comp_hom_hom {R S T : Grp C} (f : R ⟶ S) (g : S ⟶ T) : Mon.Hom.hom (f ≫ g).hom = f.hom.hom ≫ g.hom.hom := rfl -@[deprecated (since := "2025-12-18")] alias id_hom := id_hom_hom -@[deprecated (since := "2025-12-18")] alias comp_hom := comp_hom_hom - @[to_additive (attr := ext)] theorem hom_ext {A B : Grp C} (f g : A ⟶ B) (h : f.hom.hom = g.hom.hom) : f = g := InducedCategory.hom_ext (Mon.Hom.ext h) @@ -447,9 +444,6 @@ abbrev mkIso {G H : Grp C} (e : G.X ≅ H.X) (one_f : η[G.X] ≫ e.hom = η[H.X have : IsMonHom e.hom := ⟨one_f, mul_f⟩ mkIso' e -@[deprecated (since := "2025-12-18")] alias mkIso_hom_hom := mkIso_hom_hom_hom -@[deprecated (since := "2025-12-18")] alias mkIso_inv_hom := mkIso_inv_hom_hom - @[to_additive] instance uniqueHomFromTrivial (A : Grp C) : Unique (trivial C ⟶ A) := (show _ ≃ (Mon.trivial C ⟶ A.toMon) from InducedCategory.homEquiv).unique @@ -531,15 +525,6 @@ lemma associator_hom_hom_hom (G H I : Grp C) : lemma associator_inv_hom_hom (G H I : Grp C) : (α_ G H I).inv.hom.hom = (α_ G.X H.X I.X).inv := rfl -@[deprecated (since := "2025-12-18")] alias whiskerLeft_hom := whiskerLeft_hom_hom -@[deprecated (since := "2025-12-18")] alias whiskerRight_hom := whiskerRight_hom_hom -@[deprecated (since := "2025-12-18")] alias leftUnitor_hom_hom := leftUnitor_hom_hom_hom -@[deprecated (since := "2025-12-18")] alias leftUnitor_inv_hom := leftUnitor_inv_hom_hom -@[deprecated (since := "2025-12-18")] alias rightUnitor_hom_hom := rightUnitor_hom_hom_hom -@[deprecated (since := "2025-12-18")] alias rightUnitor_inv_hom := rightUnitor_inv_hom_hom -@[deprecated (since := "2025-12-18")] alias associator_hom_hom := associator_hom_hom_hom -@[deprecated (since := "2025-12-18")] alias associator_inv_hom := associator_inv_hom_hom - @[to_additive] instance instMonoidalCategory : MonoidalCategory (Grp C) where tensorHom_def := by intros; ext; simp [tensorHom_def] @@ -565,9 +550,6 @@ lemma fst_hom_hom (G H : Grp C) : (fst G H).hom.hom = fst G.X H.X := rfl @[to_additive (attr := simp)] lemma snd_hom_hom (G H : Grp C) : (snd G H).hom.hom = snd G.X H.X := rfl -@[deprecated (since := "2025-12-18")] alias fst_hom := fst_hom_hom -@[deprecated (since := "2025-12-18")] alias snd_hom := snd_hom_hom - set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simps)] instance : (forget₂Mon C).Monoidal where @@ -587,9 +569,6 @@ lemma braiding_hom_hom_hom (G H : Grp C) : (β_ G H).hom.hom.hom = (β_ G.X H.X) @[to_additive (attr := simp)] lemma braiding_inv_hom_hom (G H : Grp C) : (β_ G H).inv.hom.hom = (β_ G.X H.X).inv := rfl -@[deprecated (since := "2025-12-18")] alias braiding_hom_hom := braiding_hom_hom_hom -@[deprecated (since := "2025-12-18")] alias braiding_inv_hom := braiding_inv_hom_hom - end Grp variable diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index e3b93682c62958..f0fec6b9d06d37 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -144,70 +144,4 @@ def symmetricOfHasFiniteCoproducts [HasInitial C] [HasBinaryCoproducts C] : end -namespace monoidalOfHasFiniteProducts - -variable {C} -variable {D : Type*} [Category* D] (F : C ⥤ D) - [HasTerminal C] [HasBinaryProducts C] - [HasTerminal D] [HasBinaryProducts D] - -@[deprecated Functor.OplaxMonoidal.ofChosenFiniteProducts (since := "2025-10-19")] -instance : - have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal - have : HasFiniteProducts D := hasFiniteProducts_of_has_binary_and_terminal - let : CartesianMonoidalCategory C := .ofHasFiniteProducts - let : CartesianMonoidalCategory D := .ofHasFiniteProducts - F.OplaxMonoidal := by extract_lets; exact .ofChosenFiniteProducts F - -open Functor.OplaxMonoidal - -@[deprecated "No replacement" (since := "2025-10-19")] -lemma η_eq : - have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal - have : HasFiniteProducts D := hasFiniteProducts_of_has_binary_and_terminal - let : CartesianMonoidalCategory C := .ofHasFiniteProducts - let : CartesianMonoidalCategory D := .ofHasFiniteProducts - η F = terminalComparison F := rfl - -@[deprecated "No replacement" (since := "2025-10-19")] -lemma δ_eq (X Y : C) : - have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal - have : HasFiniteProducts D := hasFiniteProducts_of_has_binary_and_terminal - let : CartesianMonoidalCategory C := .ofHasFiniteProducts - let : CartesianMonoidalCategory D := .ofHasFiniteProducts - δ F X Y = prodComparison F X Y := rfl - -variable [PreservesLimit (Functor.empty.{0} C) F] - [PreservesLimitsOfShape (Discrete WalkingPair) F] - -set_option backward.defeqAttrib.useBackward true in -@[deprecated inferInstance (since := "2025-10-19")] -instance : - have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal - have : HasFiniteProducts D := hasFiniteProducts_of_has_binary_and_terminal - let : CartesianMonoidalCategory C := .ofHasFiniteProducts - let : CartesianMonoidalCategory D := .ofHasFiniteProducts - IsIso (η F) := by dsimp [η_eq]; apply instIsIsoTerminalComparison - -set_option backward.defeqAttrib.useBackward true in -@[deprecated inferInstance (since := "2025-10-19")] -instance (X Y : C) : - have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal - have : HasFiniteProducts D := hasFiniteProducts_of_has_binary_and_terminal - let : CartesianMonoidalCategory C := .ofHasFiniteProducts - let : CartesianMonoidalCategory D := .ofHasFiniteProducts - IsIso (δ F X Y) := by dsimp [δ_eq]; apply instIsIsoProdComparison - -/-- Promote a functor that preserves finite products to a monoidal functor between -categories equipped with the monoidal category structure given by finite products. -/ -@[deprecated Functor.Monoidal.ofChosenFiniteProducts (since := "2025-10-19")] -instance : - have : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal - have : HasFiniteProducts D := hasFiniteProducts_of_has_binary_and_terminal - let : CartesianMonoidalCategory C := .ofHasFiniteProducts - let : CartesianMonoidalCategory D := .ofHasFiniteProducts - F.Monoidal := by extract_lets; exact .ofOplaxMonoidal F - -end monoidalOfHasFiniteProducts - end CategoryTheory diff --git a/Mathlib/CategoryTheory/Monoidal/Subcategory.lean b/Mathlib/CategoryTheory/Monoidal/Subcategory.lean index 74e6a94d9d27b3..0f31e48949a973 100644 --- a/Mathlib/CategoryTheory/Monoidal/Subcategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Subcategory.lean @@ -199,8 +199,6 @@ theorem ihom_map_hom (X : P.FullSubcategory) {Y Z : P.FullSubcategory} (f : Y ⟶ Z) : ((ihom X).map f).hom = (ihom X.obj).map f.hom := rfl -@[deprecated (since := "2025-12-18")] alias ihom_map := ihom_map_hom - end Closed end ObjectProperty diff --git a/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean b/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean index 83f2dfe56b0822..d355bce2f7dbbf 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean @@ -76,9 +76,6 @@ lemma FullSubcategory.id_hom (X : P.FullSubcategory) : lemma FullSubcategory.comp_hom {X Y Z : P.FullSubcategory} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).hom = f.hom ≫ g.hom := rfl -@[deprecated (since := "2025-12-18")] alias FullSubcategory.id_def := FullSubcategory.id_hom -@[deprecated (since := "2025-12-18")] alias FullSubcategory.comp_def := FullSubcategory.comp_hom - variable {P} in /-- Constructor for morphisms in a full subcategory. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean b/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean index c8554346bf6ea6..51b870c3b9f22d 100644 --- a/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean +++ b/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean @@ -384,13 +384,6 @@ theorem AdditiveFunctor.ofExact_map_hom {F G : C ⥤ₑ D} (α : F ⟶ G) : ((AdditiveFunctor.ofExact C D).map α).hom = α.hom := rfl -@[deprecated (since := "2025-12-18")] -alias AdditiveFunctor.ofLeftExact_map := AdditiveFunctor.ofLeftExact_map_hom -@[deprecated (since := "2025-12-18")] -alias AdditiveFunctor.ofRightExact_map := AdditiveFunctor.ofRightExact_map_hom -@[deprecated (since := "2025-12-18")] -alias AdditiveFunctor.ofExact_map := AdditiveFunctor.ofExact_map_hom - end Exact end Preadditive diff --git a/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean b/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean index 3bc7f1e79301e6..d23ea18becbe2e 100644 --- a/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean +++ b/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean @@ -292,9 +292,6 @@ lemma isLocal_isLocal_toSucc : exact ⟨Multicoequalizer.desc _ _ (fun ⟨⟩ ↦ pushout.desc (Sigma.desc f) g) (fun d ↦ (hT d.1.1.hom d.1.2).1 (by simp [reassoc_of% d.2.2])), by simp⟩ -@[deprecated (since := "2025-11-20")] alias leftBousfieldW_isLocal_toSucc := - isLocal_isLocal_toSucc - set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in lemma isIso_toSucc_iff : diff --git a/Mathlib/CategoryTheory/Quotient.lean b/Mathlib/CategoryTheory/Quotient.lean index f91fb662557a3f..7ef7d22c73abf6 100644 --- a/Mathlib/CategoryTheory/Quotient.lean +++ b/Mathlib/CategoryTheory/Quotient.lean @@ -106,9 +106,6 @@ class Congruence : Prop /-- `r` is an equivalence on every hom-set. -/ equivalence : ∀ {X Y}, _root_.Equivalence (@r X Y) -@[deprecated (since := "2025-12-23")] alias Congruence.compLeft := HomRel.comp_left -@[deprecated (since := "2025-12-23")] alias Congruence.compRight := HomRel.comp_right - /-- For `F : C ⥤ D`, `F.homRel` is a congruence. -/ instance Functor.congruence_homRel {C D : Type*} [Category* C] [Category* D] (F : C ⥤ D) : Congruence F.homRel where @@ -128,15 +125,6 @@ structure Quotient (r : HomRel C) where instance [Inhabited C] : Inhabited (Quotient r) := ⟨{ as := default }⟩ -@[deprecated (since := "2025-12-23")] alias Quotient.CompClosure := HomRel.CompClosure -@[deprecated (since := "2025-12-23")] alias Quotient.CompClosure.of := HomRel.CompClosure.of -@[deprecated (since := "2025-12-23")] alias Quotient.comp_left := HomRel.comp_left -@[deprecated (since := "2025-12-23")] alias Quotient.comp_right := HomRel.comp_right -@[deprecated (since := "2025-12-23")] alias Quotient.compClosure_iff_self := - HomRel.compClosure_iff_self -@[deprecated (since := "2025-12-23")] alias Quotient.compClosure_eq_self := - HomRel.compClosure_eq_self - namespace Quotient /-- Hom-sets of the quotient category. -/ diff --git a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean index 50b5cccb9a70d0..8a134df66a9f58 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean @@ -91,8 +91,6 @@ def mapToEqualizer (P : Cᵒᵖ ⥤ Type*) {W X B : C} (f : X ⟶ B) ↾fun t ↦ ⟨P.map f.op t, by simp only [Set.mem_setOf_eq, ← comp_apply, ← Functor.map_comp, ← op_comp, w]⟩ -@[deprecated (since := "2025-11-23")] alias MapToEqualizer := mapToEqualizer - theorem EqualizerCondition.bijective_mapToEqualizer_pullback' {P : Cᵒᵖ ⥤ Type*} (hP : EqualizerCondition P) {X B : C} {π : X ⟶ B} [EffectiveEpi π] (c : PullbackCone π π) (hc : IsLimit c) : diff --git a/Mathlib/CategoryTheory/Sites/Localization.lean b/Mathlib/CategoryTheory/Sites/Localization.lean index 493bdf16cecad4..0b50036ff53fb1 100644 --- a/Mathlib/CategoryTheory/Sites/Localization.lean +++ b/Mathlib/CategoryTheory/Sites/Localization.lean @@ -44,9 +44,6 @@ lemma W_eq_isLocal_range_sheafToPresheaf_obj : · rintro ⟨F, rfl⟩ exact F.property -@[deprecated (since := "2025-11-20")] alias W_eq_W_range_sheafToPresheaf_obj := - W_eq_isLocal_range_sheafToPresheaf_obj - lemma W_sheafToPresheaf_map_iff_isIso {F₁ F₂ : Sheaf J A} (φ : F₁ ⟶ F₂) : J.W ((sheafToPresheaf J A).map φ) ↔ IsIso φ := by rw [W_eq_isLocal_range_sheafToPresheaf_obj, diff --git a/Mathlib/CategoryTheory/Sites/Subcanonical.lean b/Mathlib/CategoryTheory/Sites/Subcanonical.lean index ef05b6fd22bb64..925ca1dc8fe2db 100644 --- a/Mathlib/CategoryTheory/Sites/Subcanonical.lean +++ b/Mathlib/CategoryTheory/Sites/Subcanonical.lean @@ -139,9 +139,6 @@ theorem uliftYonedaEquiv_symm_app_apply {X : C} {F : Sheaf J (Type (max v v'))} dsimp% (J.uliftYonedaEquiv.symm x).hom.app Y ⟨f⟩ = F.obj.map f.op x := rfl -@[deprecated (since := "2025-11-10")] alias yonedaULiftEquiv_symm_app_apply := - uliftYonedaEquiv_symm_app_apply - set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- See also `uliftYonedaEquiv_naturality'` for a more general version. -/ diff --git a/Mathlib/CategoryTheory/Sites/Subsheaf.lean b/Mathlib/CategoryTheory/Sites/Subsheaf.lean index c2b64a3eb952aa..cb834133ebf691 100644 --- a/Mathlib/CategoryTheory/Sites/Subsheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Subsheaf.lean @@ -50,8 +50,6 @@ theorem Subfunctor.isSeparated {J : GrothendieckTopology C} (h : Presieve.IsSepa Presieve.IsSeparated J G.toFunctor := fun _ S hS _ _ _ hx₁ hx₂ ↦ Subtype.ext <| h S hS _ _ _ (hx₁.map G.ι) (hx₂.map G.ι) -@[deprecated (since := "2025-12-11")] alias Subpresheaf.isSeparated := Subfunctor.isSeparated - set_option backward.defeqAttrib.useBackward true in /-- The sheafification of a subpresheaf as a subpresheaf. Note that this is a sheaf only when the whole presheaf is a sheaf. -/ @@ -64,8 +62,6 @@ def Subfunctor.sheafify : Subfunctor F where dsimp at h ⊢ rwa [← comp_apply, ← Functor.map_comp] -@[deprecated (since := "2025-12-11")] alias Subpresheaf.sheafify := Subfunctor.sheafify - theorem Subfunctor.le_sheafify : G ≤ G.sheafify J := by intro U s hs change _ ∈ J _ @@ -74,8 +70,6 @@ theorem Subfunctor.le_sheafify : G ≤ G.sheafify J := by rintro V i - exact G.map i.op hs -@[deprecated (since := "2025-12-11")] alias Subpresheaf.le_sheafify := Subfunctor.le_sheafify - variable {J} theorem Subfunctor.eq_sheafify (h : Presieve.IsSheaf J F) (hG : Presieve.IsSheaf J G.toFunctor) : @@ -89,8 +83,6 @@ theorem Subfunctor.eq_sheafify (h : Presieve.IsSheaf J F) (hG : Presieve.IsSheaf intro V i hi exact (congr_arg Subtype.val ((hG _ hs).valid_glue (G.family_of_elements_compatible s) _ hi) :) -@[deprecated (since := "2025-12-11")] alias Subpresheaf.eq_sheafify := Subfunctor.eq_sheafify - set_option backward.defeqAttrib.useBackward true in theorem Subfunctor.sheafify_isSheaf (hF : Presieve.IsSheaf J F) : Presieve.IsSheaf J (G.sheafify J).toFunctor := by @@ -124,16 +116,10 @@ theorem Subfunctor.sheafify_isSheaf (hF : Presieve.IsSheaf J F) : rw [ht _ hi] exact h₁ _ _ hi -@[deprecated (since := "2025-12-11")] -alias Subpresheaf.sheafify_isSheaf := Subfunctor.sheafify_isSheaf - theorem Subfunctor.eq_sheafify_iff (h : Presieve.IsSheaf J F) : G = G.sheafify J ↔ Presieve.IsSheaf J G.toFunctor := ⟨fun e => e.symm ▸ G.sheafify_isSheaf h, G.eq_sheafify h⟩ -@[deprecated (since := "2025-12-11")] -alias Subpresheaf.eq_sheafify_iff := Subfunctor.eq_sheafify_iff - theorem Subfunctor.isSheaf_iff (h : Presieve.IsSheaf J F) : Presieve.IsSheaf J G.toFunctor ↔ ∀ (U) (s : F.obj U), G.sieveOfSection s ∈ J (unop U) → s ∈ G.obj U := by @@ -141,15 +127,10 @@ theorem Subfunctor.isSheaf_iff (h : Presieve.IsSheaf J F) : change _ ↔ G.sheafify J ≤ G exact ⟨Eq.ge, (G.le_sheafify J).antisymm⟩ -@[deprecated (since := "2025-12-11")] alias Subpresheaf.isSheaf_iff := Subfunctor.isSheaf_iff - theorem Subfunctor.sheafify_sheafify (h : Presieve.IsSheaf J F) : (G.sheafify J).sheafify J = G.sheafify J := ((Subfunctor.eq_sheafify_iff _ h).mpr <| G.sheafify_isSheaf h).symm -@[deprecated (since := "2025-12-11")] -alias Subpresheaf.sheafify_sheafify := Subfunctor.sheafify_sheafify - set_option backward.defeqAttrib.useBackward true in /-- The lift of a presheaf morphism onto the sheafification subpresheaf. -/ noncomputable def Subfunctor.sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve.IsSheaf J F') : @@ -173,8 +154,6 @@ noncomputable def Subfunctor.sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve · dsimp [Presieve.FamilyOfElements.map] at hj ⊢ rwa [Functor.map_comp, comp_apply] -@[deprecated (since := "2025-12-11")] alias Subpresheaf.sheafifyLift := Subfunctor.sheafifyLift - theorem Subfunctor.to_sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve.IsSheaf J F') : Subfunctor.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by ext U s @@ -184,9 +163,6 @@ theorem Subfunctor.to_sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve.IsShea exact (Presieve.IsSheafFor.valid_glue (h _ ((homOfLe (_ : _ ≤ sheafify _ _)).app _ _).2) ((G.family_of_elements_compatible _).map _) _ _).trans (this _ _) -@[deprecated (since := "2025-12-11")] -alias Subpresheaf.to_sheafifyLift := Subfunctor.to_sheafifyLift - set_option backward.defeqAttrib.useBackward true in theorem Subfunctor.to_sheafify_lift_unique (h : Presieve.IsSheaf J F') (l₁ l₂ : (G.sheafify J).toFunctor ⟶ F') @@ -199,9 +175,6 @@ theorem Subfunctor.to_sheafify_lift_unique (h : Presieve.IsSheaf J F') rw [← dsimp% l₁.naturality_apply, ← dsimp% l₂.naturality_apply] exact ConcreteCategory.congr_hom (congr_app e <| op V) ⟨_, hi⟩ -@[deprecated (since := "2025-12-11")] -alias Subpresheaf.to_sheafify_lift_unique := Subfunctor.to_sheafify_lift_unique - theorem Subfunctor.sheafify_le (h : G ≤ G') (hF : Presieve.IsSheaf J F) (hG' : Presieve.IsSheaf J G'.toFunctor) : G.sheafify J ≤ G' := by intro U x hx @@ -215,8 +188,6 @@ theorem Subfunctor.sheafify_le (h : G ≤ G') (hF : Presieve.IsSheaf J F) rw [← Subfunctor.nat_trans_naturality] rfl -@[deprecated (since := "2025-12-11")] alias Subpresheaf.sheafify_le := Subfunctor.sheafify_le - section Image variable (J) in @@ -225,10 +196,6 @@ variable (J) in def Subfunctor.toRangeSheafify (f : F' ⟶ F) : F' ⟶ ((Subfunctor.range f).sheafify J).toFunctor := toRange f ≫ Subfunctor.homOfLe ((range f).le_sheafify J) -@[deprecated (since := "2025-12-11")] -alias Subpresheaf.toRangeSheafify := Subfunctor.toRangeSheafify - - /-- The image sheaf of a morphism between sheaves, defined to be the sheafification of `image_presheaf`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Skeletal.lean b/Mathlib/CategoryTheory/Skeletal.lean index c739b129ecd056..84f6112dac9815 100644 --- a/Mathlib/CategoryTheory/Skeletal.lean +++ b/Mathlib/CategoryTheory/Skeletal.lean @@ -112,9 +112,6 @@ abbrev toSkeleton (X : C) : Skeleton C := ⟦X⟧ noncomputable def fromSkeletonToSkeletonIso (X : C) : (fromSkeleton C).obj (toSkeleton X) ≅ X := Nonempty.some (Quotient.mk_out X) -@[deprecated (since := "2025-12-18")] alias preCounitIso := - fromSkeletonToSkeletonIso - @[reassoc, simp] lemma Skeleton.comp_hom {X Y Z : Skeleton C} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).hom = f.hom ≫ g.hom := rfl diff --git a/Mathlib/CategoryTheory/Subfunctor/Basic.lean b/Mathlib/CategoryTheory/Subfunctor/Basic.lean index 741777bea72237..94175766be0a19 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Basic.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Basic.lean @@ -43,8 +43,6 @@ structure Subfunctor (F : C ⥤ Type w) where `F i x` is in `F(V)`. -/ map : ∀ {U V : C} (i : U ⟶ V), obj U ⊆ F.map i ⁻¹' obj V -@[deprecated (since := "2025-12-11")] alias Subpresheaf := Subfunctor - variable {F F' F'' : C ⥤ Type w} (G G' : Subfunctor F) instance : PartialOrder (Subfunctor F) := @@ -190,26 +188,6 @@ theorem nat_trans_naturality (f : F' ⟶ G.toFunctor) {U V : C} (i : U ⟶ V) (x : F'.obj U) : (f.app V (F'.map i x)).1 = F.map i (f.app U x).1 := congrArg Subtype.val (NatTrans.naturality_apply f i x) -@[deprecated (since := "2025-12-11")] alias Subpresheaf.le_def := le_def -@[deprecated (since := "2025-12-11")] alias Subpresheaf.top_obj := top_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.bot_obj := bot_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.sSup_obj := sSup_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.sInf_obj := sInf_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.iSup_obj := iSup_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.iInf_obj := iInf_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.max_obj := max_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.min_obj := min_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.max_min := max_min -@[deprecated (since := "2025-12-11")] alias Subpresheaf.iSup_min := iSup_min -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toFunctor := toFunctor -@[deprecated (since := "2025-12-11")] alias Subpresheaf.ι := ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.homOfLe := homOfLe -@[deprecated (since := "2025-12-11")] alias Subpresheaf.homOfLe_ι := homOfLe_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.eq_top_iff_isIso := eq_top_iff_isIso -@[deprecated (since := "2025-12-11")] alias Subpresheaf.nat_trans_naturality := nat_trans_naturality -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toPresheaf := toFunctor -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toPresheaf_obj := toFunctor_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toPresheaf_map_coe := toFunctor_map @[deprecated (since := "2026-02-10")] alias toFunctor_map_coe := toFunctor_map end Subfunctor diff --git a/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean b/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean index 364761364fe79d..71b89df27f1ac2 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean @@ -124,24 +124,6 @@ def equalizer.forkIsLimit : Limits.IsLimit (equalizer.fork f g) := (fun s ↦ by dsimp) (fun s m hm ↦ by simp [← cancel_mono (Subfunctor.equalizer f g).ι, ← hm]) -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer := Subfunctor.equalizer -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer_le := equalizer_le -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer_self := equalizer_self -@[deprecated (since := "2025-12-11")] alias Subpresheaf.mem_equalizer_iff := mem_equalizer_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_le_equalizer_iff := - range_le_equalizer_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer_eq_iff := equalizer_eq_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.ι := equalizer.ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.ι_ι := equalizer.ι_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.condition := equalizer.condition -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.lift := equalizer.lift -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.lift_ι' := equalizer.lift_ι' -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.lift_ι := equalizer.lift_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.fork := equalizer.fork -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.fork_ι := equalizer.fork_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equalizer.forkIsLimit := - equalizer.forkIsLimit - end Subfunctor end CategoryTheory diff --git a/Mathlib/CategoryTheory/Subfunctor/Finite.lean b/Mathlib/CategoryTheory/Subfunctor/Finite.lean index 247230d2f41919..4b67b03d016887 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Finite.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Finite.lean @@ -112,26 +112,6 @@ lemma image_isFinite [G.IsFinite] {F' : Cᵒᵖ ⥤ Type w} (f : F ⟶ F') : (G.image f).IsFinite := ((isGeneratedBy_of_isFinite G).image f).isFinite -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy := IsGeneratedBy -@[deprecated (since := "2025-12-11")] alias Subpresheaf.isGeneratedBy_iff := isGeneratedBy_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy.iSup_eq := - IsGeneratedBy.iSup_eq -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy.ofSection_le := - IsGeneratedBy.ofSection_le -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy.mem := IsGeneratedBy.mem -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy.of_equiv := - IsGeneratedBy.of_equiv -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy.image := IsGeneratedBy.image -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsFinite := IsFinite -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsFinite.Index := IsFinite.Index -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsFinite.X := IsFinite.X -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsFinite.x := IsFinite.x -@[deprecated (since := "2025-12-11")] alias Subpresheaf.isGeneratedBy_of_isFinite := - isGeneratedBy_of_isFinite -@[deprecated (since := "2025-12-11")] alias Subpresheaf.IsGeneratedBy.isFinite := - IsGeneratedBy.isFinite -@[deprecated (since := "2025-12-11")] alias Subpresheaf.image_isFinite := image_isFinite - end Subfunctor variable (F) diff --git a/Mathlib/CategoryTheory/Subfunctor/Image.lean b/Mathlib/CategoryTheory/Subfunctor/Image.lean index 3ddcbd5e105479..fde5358e932507 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Image.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Image.lean @@ -195,33 +195,6 @@ lemma preimage_image_of_epi (G : Subfunctor F) (p : F' ⟶ F) [hp : Epi p] : end preimage -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range := range -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_id := range_id -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_ι := range_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.lift := lift -@[deprecated (since := "2025-12-11")] alias Subpresheaf.lift_ι := lift_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toRange := toRange -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toRange_ι := toRange_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.toRange_app_val := toRange_app_val -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_toRange := range_toRange -@[deprecated (since := "2025-12-11")] alias Subpresheaf.epi_iff_range_eq_top := epi_iff_range_eq_top -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_eq_top := range_eq_top -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_comp_le := range_comp_le -@[deprecated (since := "2025-12-11")] alias Subpresheaf.image := image -@[deprecated (since := "2025-12-11")] alias Subpresheaf.image_top := image_top -@[deprecated (since := "2025-12-11")] alias Subpresheaf.image_iSup := image_iSup -@[deprecated (since := "2025-12-11")] alias Subpresheaf.image_comp := image_comp -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_comp := range_comp -@[deprecated (since := "2025-12-11")] alias Subpresheaf.preimage := preimage -@[deprecated (since := "2025-12-11")] alias Subpresheaf.preimage_id := preimage_id -@[deprecated (since := "2025-12-11")] alias Subpresheaf.preimage_comp := preimage_comp -@[deprecated (since := "2025-12-11")] alias Subpresheaf.image_le_iff := image_le_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.fromPreimage := fromPreimage -@[deprecated (since := "2025-12-11")] alias Subpresheaf.fromPreimage_ι := fromPreimage_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.preimage_eq_top_iff := preimage_eq_top_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.preimage_image_of_epi := - preimage_image_of_epi - end Subfunctor end CategoryTheory diff --git a/Mathlib/CategoryTheory/Subfunctor/OfSection.lean b/Mathlib/CategoryTheory/Subfunctor/OfSection.lean index fc2da55b41872d..45284abc25d019 100644 --- a/Mathlib/CategoryTheory/Subfunctor/OfSection.lean +++ b/Mathlib/CategoryTheory/Subfunctor/OfSection.lean @@ -106,15 +106,6 @@ lemma range_eq_ofSection' {X : C} (f : yoneda.obj X ⋙ uliftFunctor.{w} ⟶ F) end -@[deprecated (since := "2025-12-11")] alias Subpresheaf.ofSection := ofSection -@[deprecated (since := "2025-12-11")] alias Subpresheaf.mem_ofSection_obj := mem_ofSection_obj -@[deprecated (since := "2025-12-11")] alias Subpresheaf.ofSection_le_iff := ofSection_le_iff -@[deprecated (since := "2025-12-11")] alias Subpresheaf.ofSection_image := ofSection_image -@[deprecated (since := "2025-12-11")] alias Subpresheaf.ofSection_eq_range := ofSection_eq_range -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_eq_ofSection := range_eq_ofSection -@[deprecated (since := "2025-12-11")] alias Subpresheaf.ofSection_eq_range' := ofSection_eq_range' -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_eq_ofSection' := range_eq_ofSection' - end Subfunctor end CategoryTheory diff --git a/Mathlib/CategoryTheory/Subfunctor/Sieves.lean b/Mathlib/CategoryTheory/Subfunctor/Sieves.lean index eff8f1348a56cf..1d46057b08e8e4 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Sieves.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Sieves.lean @@ -47,10 +47,4 @@ theorem family_of_elements_compatible {U : Cᵒᵖ} (s : F.obj U) : change F.map g₁.op (F.map f₁.op s) = F.map g₂.op (F.map f₂.op s) rw [← comp_apply, ← Functor.map_comp, ← comp_apply, ← Functor.map_comp, ← op_comp, ← op_comp, e] -@[deprecated (since := "2025-12-11")] alias Subpresheaf.sieveOfSection := sieveOfSection -@[deprecated (since := "2025-12-11")] alias Subpresheaf.familyOfElementsOfSection := - familyOfElementsOfSection -@[deprecated (since := "2025-12-11")] alias Subpresheaf.family_of_elements_compatible := - family_of_elements_compatible - end CategoryTheory.Subfunctor diff --git a/Mathlib/CategoryTheory/Subfunctor/Subobject.lean b/Mathlib/CategoryTheory/Subfunctor/Subobject.lean index 46021576b39db4..67b21419cbb2b0 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Subobject.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Subobject.lean @@ -75,12 +75,6 @@ noncomputable def orderIsoSubobject : Subfunctor F ≃o Subobject F where exact leOfHom (((equivalenceMonoOver F).trans (ThinSkeleton.equivalence _).symm).functor.map (homOfLE h)) -@[deprecated (since := "2025-12-11")] alias Subpresheaf.equivalenceMonoOver := equivalenceMonoOver -@[deprecated (since := "2025-12-11")] alias Subpresheaf.range_subobjectMk_ι := range_subobjectMk_ι -@[deprecated (since := "2025-12-11")] alias Subpresheaf.subobjectMk_range_arrow := - subobjectMk_range_arrow -@[deprecated (since := "2025-12-11")] alias Subpresheaf.orderIsoSubobject := orderIsoSubobject - end Subfunctor end CategoryTheory diff --git a/Mathlib/CategoryTheory/Subobject/Basic.lean b/Mathlib/CategoryTheory/Subobject/Basic.lean index 520297ad6eb9cf..7fea3ab1d23c74 100644 --- a/Mathlib/CategoryTheory/Subobject/Basic.lean +++ b/Mathlib/CategoryTheory/Subobject/Basic.lean @@ -474,9 +474,6 @@ lemma isIso_hom_left_iff_subobjectMk_eq : fun h ↦ ⟨Subobject.ofMkLEMk _ _ h.symm.le, by simp [← cancel_mono P.1.hom], by simp [← cancel_mono Q.1.hom]⟩⟩ -@[deprecated (since := "2025-12-18")] -alias isIso_left_iff_subobjectMk_eq := isIso_hom_left_iff_subobjectMk_eq - lemma isIso_iff_subobjectMk_eq : IsIso f ↔ Subobject.mk P.1.hom = Subobject.mk Q.1.hom := by rw [isIso_iff_isIso_hom_left, isIso_hom_left_iff_subobjectMk_eq] diff --git a/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean b/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean index bce43342532765..4f7658e683f1a0 100644 --- a/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean +++ b/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean @@ -499,11 +499,6 @@ alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_hom_left_ alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_hom_left_comp := iso_inv_hom_left_comp -set_option linter.dupNamespace false in -@[deprecated (since := "2025-12-18")] -alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_left_comp := - iso_inv_hom_left_comp - set_option backward.isDefEq.respectTransparency false in lemma isPullback {U X : C} (m : U ⟶ X) [Mono m] : IsPullback m (h.π m) (h.χ m) h.Ω₀.arrow := by diff --git a/Mathlib/CategoryTheory/Subobject/MonoOver.lean b/Mathlib/CategoryTheory/Subobject/MonoOver.lean index 7e71cef9cfd97a..e026bebecc1bae 100644 --- a/Mathlib/CategoryTheory/Subobject/MonoOver.lean +++ b/Mathlib/CategoryTheory/Subobject/MonoOver.lean @@ -74,8 +74,6 @@ def mk {X A : C} (f : A ⟶ X) [hf : Mono f] : MonoOver X where obj := Over.mk f property := hf -@[deprecated (since := "2025-12-18")] alias mk' := mk - /-- The inclusion from monomorphisms over X to morphisms over X. -/ abbrev forget (X : C) : MonoOver X ⥤ Over X := ObjectProperty.ι _ @@ -90,8 +88,6 @@ theorem forget_obj_left {f} : ((forget X).obj f).left = (f : C) := theorem mk_coe {X A : C} (f : A ⟶ X) [Mono f] : (mk f : C) = A := rfl -@[deprecated (since := "2025-12-18")] alias mk'_coe' := mk_coe - /-- Convenience notation for the underlying arrow of a monomorphism over X. -/ abbrev arrow (f : MonoOver X) : (f : C) ⟶ X := f.obj.hom @@ -99,8 +95,6 @@ abbrev arrow (f : MonoOver X) : (f : C) ⟶ X := f.obj.hom theorem mk_arrow {X A : C} (f : A ⟶ X) [Mono f] : (mk f).arrow = f := rfl -@[deprecated (since := "2025-12-18")] alias mk'_arrow := mk_arrow - theorem forget_obj_hom {f} : ((forget X).obj f).hom = f.arrow := rfl /-- The forget functor `MonoOver X ⥤ Over X` is fully faithful. -/ @@ -143,8 +137,6 @@ package it as an isomorphism. -/ def mkArrowIso {X : C} (f : MonoOver X) : mk f.arrow ≅ f := isoMk (Iso.refl _) -@[deprecated (since := "2025-12-18")] alias mk'ArrowIso := mkArrowIso - instance {A B : MonoOver X} (f : A ⟶ B) [IsIso f] : IsIso f.hom.left := inferInstanceAs (IsIso ((MonoOver.forget _ ⋙ Over.forget _).map f)) @@ -152,8 +144,6 @@ lemma isIso_iff_isIso_hom_left {A B : MonoOver X} (f : A ⟶ B) : IsIso f ↔ IsIso f.hom.left := (isIso_iff_of_reflects_iso _ (MonoOver.forget X ⋙ Over.forget _)).symm -@[deprecated (since := "2025-12-18")] alias isIso_iff_isIso_left := isIso_iff_isIso_hom_left - /-- Lift a functor between over categories to a functor between `MonoOver` categories, given suitable evidence that morphisms are taken to monomorphisms. -/ diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean index 54e667a5967a55..03d775d4886f77 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean @@ -272,11 +272,6 @@ lemma opShiftFunctorEquivalence_add_unitIso_inv_app_eq ← unop_comp, Iso.inv_hom_id_app, Functor.comp_obj, Functor.op_obj, unop_id, Functor.map_id, id_comp, ← Functor.map_comp, Iso.hom_inv_id_app] -@[deprecated (since := "2025-12-08")] alias opShiftFunctorEquivalence_unitIso_hom_app_eq := - opShiftFunctorEquivalence_add_unitIso_hom_app_eq -@[deprecated (since := "2025-12-08")] alias opShiftFunctorEquivalence_unitIso_inv_app_eq := - opShiftFunctorEquivalence_add_unitIso_inv_app_eq - lemma shift_unop_opShiftFunctorEquivalence_counitIso_inv_app (X : Cᵒᵖ) (n : ℤ) : ((opShiftFunctorEquivalence C n).counitIso.inv.app X).unop⟦n⟧' = ((opShiftFunctorEquivalence C n).unitIso.hom.app ((Opposite.op ((X.unop)⟦n⟧)))).unop := diff --git a/Mathlib/CategoryTheory/Yoneda.lean b/Mathlib/CategoryTheory/Yoneda.lean index bad0f42df83e0d..ee8bda56ccf243 100644 --- a/Mathlib/CategoryTheory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Yoneda.lean @@ -1307,13 +1307,6 @@ def homNatIso {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} (hF : F.FullyFai (fun Y => Equiv.toIso (Equiv.ulift.trans <| hF.homEquiv.symm.trans Equiv.ulift.symm)) (fun f => by ext; exact Equiv.ulift.injective (hF.map_injective (by simp))) -/-- `FullyFaithful.homEquiv` as a natural isomorphism. -/ -@[deprecated homNatIso (since := "2025-10-28")] -def homNatIsoMaxRight {D : Type u₂} [Category.{max v₁ v₂} D] {F : C ⥤ D} (hF : F.FullyFaithful) - (X : C) : F.op ⋙ yoneda.obj (F.obj X) ≅ uliftYoneda.{v₂}.obj X := - isoWhiskerLeft F.op (uliftYonedaIsoYoneda.symm.app _) ≪≫ hF.homNatIso _ ≪≫ - NatIso.ofComponents (fun _ => Equiv.toIso (Equiv.ulift.trans Equiv.ulift.symm)) - /-- `FullyFaithful.homEquiv` as a natural isomorphism. -/ @[simps! +dsimpLhs] def compUliftYonedaCompWhiskeringLeft {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} @@ -1322,18 +1315,6 @@ def compUliftYonedaCompWhiskeringLeft {D : Type u₂} [Category.{v₂} D] {F : C NatIso.ofComponents (fun X => hF.homNatIso _) fun f => by ext; exact Equiv.ulift.injective (hF.map_injective (by simp)) -@[deprecated (since := "2025-10-20")] alias compYonedaCompWhiskeringLeft := - compUliftYonedaCompWhiskeringLeft - -/-- `FullyFaithful.homEquiv` as a natural isomorphism. -/ -@[deprecated compUliftYonedaCompWhiskeringLeft (since := "2025-10-28")] -def compYonedaCompWhiskeringLeftMaxRight {D : Type u₂} [Category.{max v₁ v₂} D] {F : C ⥤ D} - (hF : F.FullyFaithful) : F ⋙ yoneda ⋙ (whiskeringLeft _ _ _).obj F.op ≅ uliftYoneda.{v₂} := by - refine isoWhiskerLeft F (isoWhiskerRight uliftYonedaIsoYoneda.{v₁}.symm _) ≪≫ - hF.compUliftYonedaCompWhiskeringLeft ≪≫ - NatIso.ofComponents (fun _ => NatIso.ofComponents - (fun _ => Equiv.toIso (Equiv.ulift.trans Equiv.ulift.symm))) - /-- `FullyFaithful.homEquiv` as a natural isomorphism, using coyoneda. -/ @[simps! hom_app inv_app] def homNatIso' {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} (hF : F.FullyFaithful) (X : C) : diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 10e5a526660762..4bf986b7af7616 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -511,9 +511,6 @@ theorem edgeSet_top : (⊤ : SimpleGraph V).edgeSet = Sym2.diagSetᶜ := theorem edgeSet_subset_compl_diagSet : G.edgeSet ⊆ Sym2.diagSetᶜ := by simpa [Set.subset_compl_iff_disjoint_left, edgeSet, edgeSetEmbedding] using G.loopless -@[deprecated (since := "2025-12-10")] -alias edgeSet_subset_setOf_not_isDiag := edgeSet_subset_compl_diagSet - @[simp] theorem edgeSet_sup : (G₁ ⊔ G₂).edgeSet = G₁.edgeSet ∪ G₂.edgeSet := by ext ⟨x, y⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Metric.lean b/Mathlib/Combinatorics/SimpleGraph/Metric.lean index fcdda131c2b47b..972055dd8912c8 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Metric.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Metric.lean @@ -319,11 +319,6 @@ theorem Adj.diff_dist_adj (hadj : G.Adj v w) : have : G.dist u v ≤ G.dist u w + G.dist w v := huw.dist_triangle_left v lia -@[deprecated Adj.diff_dist_adj (since := "2025-12-11"), nolint unusedArguments] -theorem Connected.diff_dist_adj (_ : G.Connected) (hadj : G.Adj v w) : - G.dist u w = G.dist u v ∨ G.dist u w = G.dist u v + 1 ∨ G.dist u w = G.dist u v - 1 := by - apply Adj.diff_dist_adj hadj - theorem Walk.isPath_of_length_eq_dist (p : G.Walk u v) (hp : p.length = G.dist u v) : p.IsPath := by classical diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean index 5021d878c1c93f..74a26d858848b9 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean @@ -231,11 +231,6 @@ theorem firstDart_eq_head_darts {p : G.Walk v w} (hnil : ¬p.Nil) : p.firstDart hnil = p.darts.head (darts_eq_nil.not.mpr hnil) := head_darts_eq_firstDart _ |>.symm -@[deprecated "Use `head_darts_eq_firstDart`" (since := "2025-12-10")] -theorem head_darts_fst {G : SimpleGraph V} {a b : V} (p : G.Walk a b) (hp : p.darts ≠ []) : - (p.darts.head hp).fst = a := by - simp - @[simp] theorem firstDart_mem_darts {p : G.Walk v w} (hnil : ¬p.Nil) : p.firstDart hnil ∈ p.darts := p.firstDart_eq_head_darts _ ▸ List.head_mem _ @@ -249,11 +244,6 @@ theorem lastDart_eq_getLast_darts {p : G.Walk v w} (hnil : ¬p.Nil) : p.lastDart hnil = p.darts.getLast (darts_eq_nil.not.mpr hnil) := by grind [lastDart_eq, not_nil_iff_lt_length] -@[deprecated "Use `getLast_darts_eq_lastDart`" (since := "2025-12-10")] -theorem getLast_darts_snd {G : SimpleGraph V} {a b : V} (p : G.Walk a b) (hp : p.darts ≠ []) : - (p.darts.getLast hp).snd = b := by - simp - @[simp] theorem lastDart_mem_darts {p : G.Walk v w} (hnil : ¬p.Nil) : p.lastDart hnil ∈ p.darts := p.lastDart_eq_getLast_darts _ ▸ List.getLast_mem _ diff --git a/Mathlib/Computability/NFA.lean b/Mathlib/Computability/NFA.lean index ec0693bc70abda..f8f4b2a794a18a 100644 --- a/Mathlib/Computability/NFA.lean +++ b/Mathlib/Computability/NFA.lean @@ -119,11 +119,6 @@ theorem evalFrom_append (S : Set σ) (x y : List α) : M.evalFrom S (x ++ y) = M.evalFrom (M.evalFrom S x) y := by simp only [evalFrom, List.foldl_append] -@[deprecated "Use evalFrom_append, evalFrom_cons, and evalFrom_nil" (since := "2025-11-17")] -theorem evalFrom_append_singleton (S : Set σ) (x : List α) (a : α) : - M.evalFrom S (x ++ [a]) = M.stepSet (M.evalFrom S x) a := by - simp only [evalFrom_append, evalFrom_cons, evalFrom_nil] - variable (M) in @[simp] theorem evalFrom_union (S T : Set σ) (x : List α) : @@ -145,13 +140,6 @@ theorem evalFrom_iUnion₂ {ι : Sort*} {κ : ι → Sort*} (f : ∀ i, κ i → M.evalFrom (⋃ (i) (j), f i j) x = ⋃ (i) (j), M.evalFrom (f i j) x := by simp -variable (M) in -@[deprecated evalFrom_iUnion₂ (since := "2025-11-17")] -theorem evalFrom_biUnion {ι : Type*} (t : Set ι) (f : ι → Set σ) : - ∀ (x : List α), M.evalFrom (⋃ i ∈ t, f i) x = ⋃ i ∈ t, M.evalFrom (f i) x - | [] => by simp - | a :: x => by simp [stepSet, evalFrom_biUnion _ _ x] - variable (M) in theorem evalFrom_eq_biUnion_singleton (S : Set σ) (x : List α) : M.evalFrom S x = ⋃ s ∈ S, M.evalFrom {s} x := by diff --git a/Mathlib/Data/DFinsupp/Lex.lean b/Mathlib/Data/DFinsupp/Lex.lean index b2d249782a7be0..ba2d11f0f070ae 100644 --- a/Mathlib/Data/DFinsupp/Lex.lean +++ b/Mathlib/Data/DFinsupp/Lex.lean @@ -54,9 +54,6 @@ theorem Lex.lt_iff [LT ι] [∀ i, LT (α i)] {a b : Lex (Π₀ i, α i)} : a < b ↔ ∃ i, (∀ j, j < i → a j = b j) ∧ a i < b i := .rfl -@[deprecated (since := "2025-11-29")] -alias lex_lt_iff := Lex.lt_iff - theorem Colex.lt_iff [LT ι] [∀ i, LT (α i)] {a b : Colex (Π₀ i, α i)} : a < b ↔ ∃ i, (∀ j, i < j → a j = b j) ∧ a i < b i := .rfl @@ -83,9 +80,6 @@ theorem Lex.lt_iff_of_unique [Unique ι] [∀ i, LT (α i)] [Preorder ι] {x y : x < y ↔ x default < y default := lex_iff_of_unique -@[deprecated (since := "2025-11-29")] -alias lex_lt_iff_of_unique := Lex.lt_iff_of_unique - theorem colex_lt_iff_of_unique [Unique ι] [∀ i, LT (α i)] [Preorder ι] {x y : Colex (Π₀ i, α i)} : x < y ↔ x default < y default := lex_iff_of_unique @@ -121,9 +115,6 @@ theorem Lex.le_iff_of_unique [Unique ι] [∀ i, PartialOrder (α i)] {x y : Lex x ≤ y ↔ x default ≤ y default := Pi.lex_le_iff_of_unique -@[deprecated (since := "2025-11-29")] -alias lex_le_iff_of_unique := Lex.le_iff_of_unique - theorem Colex.le_iff_of_unique [Unique ι] [∀ i, PartialOrder (α i)] {x y : Colex (Π₀ i, α i)} : x ≤ y ↔ x default ≤ y default := Lex.le_iff_of_unique (ι := ιᵒᵈ) diff --git a/Mathlib/Data/ENat/Basic.lean b/Mathlib/Data/ENat/Basic.lean index b6bc86c0d471fb..51cc047600a5ec 100644 --- a/Mathlib/Data/ENat/Basic.lean +++ b/Mathlib/Data/ENat/Basic.lean @@ -331,9 +331,6 @@ theorem coe_lt_add_one_iff {m : ℕ} {n : ℕ∞} : m < n + 1 ↔ m ≤ n := theorem le_coe_iff {n : ℕ∞} {k : ℕ} : n ≤ ↑k ↔ ∃ (n₀ : ℕ), n = n₀ ∧ n₀ ≤ k := WithTop.le_coe_iff -@[deprecated not_lt_zero (since := "2025-12-03")] -protected lemma not_lt_zero (n : ℕ∞) : ¬ n < 0 := not_lt_zero - @[simp] lemma coe_lt_top (n : ℕ) : (n : ℕ∞) < ⊤ := WithTop.coe_lt_top n diff --git a/Mathlib/Data/Finset/Basic.lean b/Mathlib/Data/Finset/Basic.lean index d438187eae57a5..a084f3ba85f11d 100644 --- a/Mathlib/Data/Finset/Basic.lean +++ b/Mathlib/Data/Finset/Basic.lean @@ -325,8 +325,6 @@ theorem disjoint_filter_filter_not (s t : Finset α) (p : α → Prop) Disjoint (s.filter p) (t.filter fun a => ¬p a) := s.disjoint_filter_filter' t disjoint_compl_right -@[deprecated (since := "2025-12-12")] alias disjoint_filter_filter_neg := disjoint_filter_filter_not - theorem filter_disjUnion (s : Finset α) (t : Finset α) (h : Disjoint s t) : (s.disjUnion t h).filter p = (s.filter p).disjUnion (t.filter p) (disjoint_filter_filter h) := eq_of_veq <| Multiset.filter_add _ _ _ @@ -428,8 +426,6 @@ theorem filter_union_filter_not_eq [∀ x, Decidable (¬p x)] (s : Finset α) : (s.filter p ∪ s.filter fun a => ¬p a) = s := filter_union_filter_of_codisjoint _ _ _ <| @codisjoint_hnot_right _ _ p -@[deprecated (since := "2025-12-12")] alias filter_union_filter_neg_eq := filter_union_filter_not_eq - end end Filter diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 739c20791e4a18..36844cf000c3f0 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -645,9 +645,6 @@ theorem card_filter_add_card_filter_not classical rw [← card_union_of_disjoint (disjoint_filter_filter_not _ _ _), filter_union_filter_not_eq] -@[deprecated (since := "2025-12-12")] -alias filter_card_add_filter_neg_card_eq_card := card_filter_add_card_filter_not - /-- Given a subset `s` of a set `t`, of sizes at most and at least `n` respectively, there exists a set `u` of size `n` which is both a superset of `s` and a subset of `t`. -/ lemma exists_subsuperset_card_eq (hst : s ⊆ t) (hsn : #s ≤ n) (hnt : n ≤ #t) : diff --git a/Mathlib/Data/Finset/NoncommProd.lean b/Mathlib/Data/Finset/NoncommProd.lean index 5244f0d8a1901a..f24979578a0875 100644 --- a/Mathlib/Data/Finset/NoncommProd.lean +++ b/Mathlib/Data/Finset/NoncommProd.lean @@ -418,12 +418,6 @@ theorem noncommProd_mulSingle [Fintype ι] [DecidableEq ι] (x : ∀ i, M i) : · simp only [Pi.mulSingle_eq_same] · simpa using fun _ a ↦ Pi.mulSingle_eq_of_ne (a ·.symm) _ -@[deprecated noncommProd_mulSingle (since := "2025-11-25")] -alias noncommProd_mul_single := noncommProd_mulSingle - -@[deprecated (since := "2025-12-09")] -alias noncommSum_add_single := noncommSum_single - @[to_additive] theorem _root_.MonoidHom.pi_ext [Finite ι] [DecidableEq ι] {f g : (∀ i, M i) →* γ} (h : ∀ i x, f (Pi.mulSingle i x) = g (Pi.mulSingle i x)) : f = g := by diff --git a/Mathlib/Data/Finset/Sort.lean b/Mathlib/Data/Finset/Sort.lean index 6eace95eb3ee01..90d63007a84764 100644 --- a/Mathlib/Data/Finset/Sort.lean +++ b/Mathlib/Data/Finset/Sort.lean @@ -132,13 +132,9 @@ variable [LinearOrder α] theorem sortedLT_sort (s : Finset α) : (sort s).SortedLT := (pairwise_sort _ _).sortedLE.sortedLT_of_nodup (sort_nodup _ _) -@[deprecated (since := "2025-11-27")] alias sort_sorted_lt := sortedLT_sort - theorem sortedGT_sort (s : Finset α) : (sort s (· ≥ ·)).SortedGT := (pairwise_sort _ _).sortedGE.sortedGT_of_nodup (sort_nodup _ _) -@[deprecated (since := "2025-11-27")] alias sort_sorted_gt := sortedGT_sort - theorem sorted_zero_eq_min'_aux (s : Finset α) (h : 0 < s.sort.length) (H : s.Nonempty) : s.sort.get ⟨0, h⟩ = s.min' H := by let l := s.sort diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 1650925f9429b5..66515acfcfe193 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -1217,9 +1217,6 @@ theorem subtypeDomain_not_piecewise (f : Subtype P →₀ M) (g : {a // ¬ P a} @[simps! (attr := grind =) support apply] def extendDomain (f : Subtype P →₀ M) : α →₀ M := piecewise f 0 -@[deprecated (since := "2025-12-15")] -alias extendDomain_toFun := extendDomain_apply - theorem extendDomain_eq_embDomain_subtype (f : Subtype P →₀ M) : extendDomain f = embDomain (.subtype _) f := by ext a diff --git a/Mathlib/Data/Finsupp/Interval.lean b/Mathlib/Data/Finsupp/Interval.lean index 9886dd34771358..107b29abe56a70 100644 --- a/Mathlib/Data/Finsupp/Interval.lean +++ b/Mathlib/Data/Finsupp/Interval.lean @@ -67,9 +67,6 @@ def rangeIcc (f g : ι →₀ α) : ι →₀ Finset α where rw [mem_union, ← not_iff_not, not_or, notMem_support_iff, notMem_support_iff, not_ne_iff] exact Icc_eq_singleton_iff.symm -@[deprecated (since := "2025-12-15")] -alias rangeIcc_toFun := rangeIcc_apply - lemma coe_rangeIcc (f g : ι →₀ α) : rangeIcc f g i = Icc (f i) (g i) := rfl @[simp] diff --git a/Mathlib/Data/Finsupp/Lex.lean b/Mathlib/Data/Finsupp/Lex.lean index 3aa7a80b5988c4..de5c7b88193acb 100644 --- a/Mathlib/Data/Finsupp/Lex.lean +++ b/Mathlib/Data/Finsupp/Lex.lean @@ -56,9 +56,6 @@ theorem Lex.lt_iff [LT α] [LT N] {a b : Lex (α →₀ N)} : a < b ↔ ∃ i, (∀ j, j < i → a j = b j) ∧ a i < b i := .rfl -@[deprecated (since := "2025-11-29")] -alias lex_lt_iff := Lex.lt_iff - theorem Colex.lt_iff [LT α] [LT N] {a b : Colex (α →₀ N)} : a < b ↔ ∃ i, (∀ j, i < j → a j = b j) ∧ a i < b i := .rfl @@ -79,9 +76,6 @@ theorem Lex.lt_iff_of_unique [Unique α] [LT N] [Preorder α] {x y : Lex (α → x < y ↔ x default < y default := lex_iff_of_unique -@[deprecated (since := "2025-11-29")] -alias lex_lt_iff_of_unique := Lex.lt_iff_of_unique - theorem Colex.lt_iff_of_unique [Unique α] [LT N] [Preorder α] {x y : Colex (α →₀ N)} : x < y ↔ x default < y default := Lex.lt_iff_of_unique (α := αᵒᵈ) @@ -126,9 +120,6 @@ theorem Lex.le_iff_of_unique [Unique α] [PartialOrder N] {x y : Lex (α →₀ x ≤ y ↔ x default ≤ y default := Pi.lex_le_iff_of_unique -@[deprecated (since := "2025-11-29")] -alias lex_le_iff_of_unique := Lex.le_iff_of_unique - theorem Colex.le_iff_of_unique [Unique α] [PartialOrder N] {x y : Colex (α →₀ N)} : x ≤ y ↔ x default ≤ y default := Lex.le_iff_of_unique (α := αᵒᵈ) diff --git a/Mathlib/Data/Finsupp/Weight.lean b/Mathlib/Data/Finsupp/Weight.lean index ed69242d334529..ec47216dd6c7f7 100644 --- a/Mathlib/Data/Finsupp/Weight.lean +++ b/Mathlib/Data/Finsupp/Weight.lean @@ -217,15 +217,8 @@ def degree : (σ →₀ R) →+ R where map_zero' := by simp map_add' := fun _ _ => sum_add_index' (h := fun _ ↦ id) (congrFun rfl) fun _ _ ↦ congrFun rfl -@[deprecated (since := "2025-12-09")] alias degree_add := map_add - -@[deprecated (since := "2025-12-09")] alias degree_zero := map_zero - theorem degree_apply (d : σ →₀ R) : degree d = ∑ i ∈ d.support, d i := rfl -@[deprecated (since := "2025-12-09")] -alias degree_def := degree_apply - theorem degree_eq_sum [Fintype σ] (f : σ →₀ R) : f.degree = ∑ i, f i := by rw [degree_apply, Finset.sum_subset] <;> simp diff --git a/Mathlib/Data/Fintype/Card.lean b/Mathlib/Data/Fintype/Card.lean index 953def12af2219..cc275a389de665 100644 --- a/Mathlib/Data/Fintype/Card.lean +++ b/Mathlib/Data/Fintype/Card.lean @@ -359,12 +359,6 @@ alias ⟨_root_.Function.Injective.surjective_of_finite, _root_.Function.Surjective.injective_of_finite⟩ := injective_iff_surjective_of_equiv -@[deprecated (since := "2025-11-28")] -alias _root_.Function.Injective.surjective_of_fintype := Injective.surjective_of_finite - -@[deprecated (since := "2025-11-28")] -alias _root_.Function.Surjective.injective_of_fintype := Surjective.injective_of_finite - end Finite @[simp] diff --git a/Mathlib/Data/Int/ConditionallyCompleteOrder.lean b/Mathlib/Data/Int/ConditionallyCompleteOrder.lean index 233b8ad916f2ba..579381997ebb1b 100644 --- a/Mathlib/Data/Int/ConditionallyCompleteOrder.lean +++ b/Mathlib/Data/Int/ConditionallyCompleteOrder.lean @@ -51,8 +51,6 @@ theorem csSup_eq_greatestOfBdd {s : Set ℤ} [DecidablePred (· ∈ s)] (b : ℤ simp only [sSup, dif_pos this] convert! (coe_greatestOfBdd_eq Hb (Classical.choose_spec (⟨b, Hb⟩ : BddAbove s)) Hinh).symm -@[deprecated (since := "2025-12-24")] alias csSup_eq_greatest_of_bdd := csSup_eq_greatestOfBdd - @[simp] theorem csSup_empty : sSup (∅ : Set ℤ) = 0 := dif_neg (by simp) @@ -60,16 +58,12 @@ theorem csSup_empty : sSup (∅ : Set ℤ) = 0 := theorem csSup_of_not_bddAbove {s : Set ℤ} (h : ¬BddAbove s) : sSup s = 0 := dif_neg (by simp [h]) -@[deprecated (since := "2025-12-24")] alias csSup_of_not_bdd_above := csSup_of_not_bddAbove - theorem csInf_eq_leastOfBdd {s : Set ℤ} [DecidablePred (· ∈ s)] (b : ℤ) (Hb : ∀ z ∈ s, b ≤ z) (Hinh : ∃ z : ℤ, z ∈ s) : sInf s = leastOfBdd b Hb Hinh := by have : s.Nonempty ∧ BddBelow s := ⟨Hinh, b, Hb⟩ simp only [sInf, dif_pos this] convert! (coe_leastOfBdd_eq Hb (Classical.choose_spec (⟨b, Hb⟩ : BddBelow s)) Hinh).symm -@[deprecated (since := "2025-12-24")] alias csInf_eq_least_of_bdd := csInf_eq_leastOfBdd - @[simp] theorem csInf_empty : sInf (∅ : Set ℤ) = 0 := dif_neg (by simp) @@ -77,8 +71,6 @@ theorem csInf_empty : sInf (∅ : Set ℤ) = 0 := theorem csInf_of_not_bddBelow {s : Set ℤ} (h : ¬BddBelow s) : sInf s = 0 := dif_neg (by simp [h]) -@[deprecated (since := "2025-12-24")] alias csInf_of_not_bdd_below := csInf_of_not_bddBelow - theorem csSup_mem {s : Set ℤ} (h1 : s.Nonempty) (h2 : BddAbove s) : sSup s ∈ s := by convert! (greatestOfBdd _ (Classical.choose_spec h2) h1).2.1 exact dif_pos ⟨h1, h2⟩ diff --git a/Mathlib/Data/Int/Fib/Basic.lean b/Mathlib/Data/Int/Fib/Basic.lean index e38a4d23db051a..e1c6d1fba0dd88 100644 --- a/Mathlib/Data/Int/Fib/Basic.lean +++ b/Mathlib/Data/Int/Fib/Basic.lean @@ -155,9 +155,6 @@ theorem gcd_fib (m n : ℤ) : gcd (fib m) (fib n) = Nat.fib (gcd m n) := by <;> obtain ⟨n, (rfl | rfl)⟩ := n.eq_nat_or_neg <;> simp [fib_neg, Nat.fib_gcd, apply_ite, apply_ite_left] -@[deprecated gcd_fib (since := "2025-12-09")] -theorem fib_gcd (m n : ℤ) : fib (gcd m n) = gcd (fib m) (fib n) := by simpa using (gcd_fib m n).symm - private theorem fib_natCast_dvd {m : ℕ} {n : ℤ} (h : (m : ℤ) ∣ n) : fib m ∣ fib n := by rwa [← gcd_eq_left_iff_dvd (by simp), gcd_fib, ← fib_natCast, (gcd_eq_left_iff_dvd (by simp)).mpr] diff --git a/Mathlib/Data/List/Chain.lean b/Mathlib/Data/List/Chain.lean index 5e240bbd46b04e..cb5c1a63ef5f6f 100644 --- a/Mathlib/Data/List/Chain.lean +++ b/Mathlib/Data/List/Chain.lean @@ -264,19 +264,6 @@ theorem IsChain.imp_head {x y} (h : ∀ {z}, R x z → R y z) {l} (hl : IsChain IsChain R (y :: l) := IsChain.cons_of_imp @h hl -@[deprecated isChain_iff_getElem (since := "2025-11-25")] -theorem isChain_iff_get {R} : ∀ {l : List α}, IsChain R l ↔ - ∀ (i : Fin (l.length.pred)), - haveI H := Nat.sub_one_add_one (Nat.lt_of_lt_pred i.pos).ne' - R (l.get (i.castSucc.cast H)) (l.get (i.succ.cast H)) := by - simp [isChain_iff_getElem, Fin.forall_iff, Nat.lt_sub_iff_add_lt] - -@[deprecated isChain_iff_getElem (since := "2025-11-25")] -theorem isChain_cons_iff_get {R} {a : α} {l : List α} : IsChain R (a :: l) ↔ - ∀ (i : Fin l.length), R ((a :: l).get i.castSucc) ((a :: l).get i.succ) := by - simp only [isChain_iff_getElem, length_cons, Fin.forall_iff, Nat.add_lt_add_iff_right, - getElem_cons_succ, Fin.castSucc_mk, get_eq_getElem, Fin.succ_mk] - theorem exists_not_getElem_of_not_isChain (h : ¬List.IsChain R l) : ∃ n : ℕ, ∃ h : n + 1 < l.length, ¬R l[n] l[n + 1] := by simp_all [isChain_iff_getElem] diff --git a/Mathlib/Data/List/Cycle.lean b/Mathlib/Data/List/Cycle.lean index 05afb88727f8f8..279622cb6c048c 100644 --- a/Mathlib/Data/List/Cycle.lean +++ b/Mathlib/Data/List/Cycle.lean @@ -70,10 +70,6 @@ theorem nextOr_eq_nextOr_of_mem_dropLast (xs : List α) (x d d' : α) (x_mem : x · rw [nextOr, nextOr, IH] simpa [h] using x_mem -@[deprecated "Use `grind [nextOr_eq_nextOr_of_mem_dropLast, dropLast_concat_getLast]` to get the \ - original statement" (since := "2025-11-29")] -alias nextOr_eq_nextOr_of_mem_of_ne := nextOr_eq_nextOr_of_mem_dropLast - theorem mem_of_nextOr_ne {xs : List α} {x d : α} (h : nextOr xs x d ≠ d) : x ∈ xs := by induction xs with | nil => simp at h @@ -160,11 +156,6 @@ theorem next_cons_eq_next_of_mem_dropLast (h : x ∈ l.dropLast) (y : α) (hy : next l x (mem_of_mem_dropLast h) := by rwa [next, next, nextOr_cons_of_ne _ _ _ _ hy, nextOr_eq_nextOr_of_mem_dropLast] -@[deprecated "Use \ - `grind [next_cons_eq_next_of_mem_dropLast, dropLast_concat_getLast, ne_nil_of_mem]` to get the \ - original statement" (since := "2025-11-29")] -alias next_ne_head_ne_getLast := next_cons_eq_next_of_mem_dropLast - theorem next_cons_concat (y : α) (hy : x ≠ y) (hx : x ∉ l) (h : x ∈ y :: l ++ [x] := mem_append_right _ (mem_singleton_self x)) : next (y :: l ++ [x]) x h = y := by diff --git a/Mathlib/Data/List/GetD.lean b/Mathlib/Data/List/GetD.lean index 79a0bd6ef01c46..b1f7dde5cfbddb 100644 --- a/Mathlib/Data/List/GetD.lean +++ b/Mathlib/Data/List/GetD.lean @@ -75,8 +75,6 @@ theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ (l ++ l').getD n d = l'.getD (n - l.length) d := by grind -@[deprecated (since := "2025-11-17")] alias getD_eq_getD_getElem? := getD_eq_getElem?_getD - theorem getD_surjective_iff {l : List α} {d : α} : (l.getD · d).Surjective ↔ (∀ x, x = d ∨ x ∈ l) := by apply forall_congr' diff --git a/Mathlib/Data/List/Sort.lean b/Mathlib/Data/List/Sort.lean index 4a15b3585095ac..1ad915e253bce7 100644 --- a/Mathlib/Data/List/Sort.lean +++ b/Mathlib/Data/List/Sort.lean @@ -56,8 +56,6 @@ theorem orderedInsert_cons_of_le {a b : α} (l : List α) (h : a ≼ b) : orderedInsert r a (b :: l) = a :: b :: l := dif_pos h -@[deprecated (since := "2025-11-27")] alias orderedInsert_of_le := orderedInsert_cons_of_le - theorem orderedInsert_of_not_le {a b : α} (l : List α) (h : ¬ a ≼ b) : orderedInsert r a (b :: l) = b :: orderedInsert r a l := dif_neg h @@ -335,8 +333,6 @@ theorem Pairwise.merge {l l' : List α} (h : Pairwise r l) (h' : Pairwise r l') (fun a b => by simpa using Std.Total.total a b) l l' (by simpa using h) (by simpa using h') -@[deprecated (since := "2025-11-27")] alias Sorted.merge := Pairwise.merge - variable (r) /-- Variant of `pairwise_mergeSort` using relation typeclasses. -/ @@ -346,8 +342,6 @@ theorem pairwise_mergeSort' (l : List α) : Pairwise r (mergeSort l (r · ·)) : (by simpa using total_of r) l -@[deprecated (since := "2025-11-27")] alias sorted_mergeSort' := pairwise_mergeSort' - variable [Std.Antisymm r] theorem mergeSort_eq_self {l : List α} : Pairwise r l → mergeSort l (r · ·) = l := @@ -496,37 +490,20 @@ protected theorem SortedLT.sortedLE {l : List α} (h : l.SortedLT) : l.SortedLE protected theorem SortedGT.sortedGE {l : List α} (h : l.SortedGT) : l.SortedGE := h.strictAnti_get.antitone.sortedGE -@[deprecated (since := "2025-11-27")] alias Sorted.le_of_lt := SortedLT.sortedLE -@[deprecated (since := "2025-11-27")] alias Sorted.ge_of_gt := SortedGT.sortedGE - protected theorem SortedLT.nodup (h : l.SortedLT) : l.Nodup := h.strictMono_get.injective.nodup protected theorem SortedGT.nodup (h : l.SortedGT) : l.Nodup := h.strictAnti_get.injective.nodup theorem sortedLE_replicate {a : α} (n : ℕ) : (replicate n a).SortedLE := (pairwise_replicate.mpr (Or.inr le_rfl)).sortedLE -@[deprecated (since := "2025-11-27")] alias sorted_le_replicate := sortedLE_replicate - theorem sortedLT_finRange (n : ℕ) : (finRange n).SortedLT := sortedLT_of_getElem_lt_getElem_of_lt <| by simp theorem sortedLT_range (n : ℕ) : (range n).SortedLT := pairwise_lt_range.sortedLT -@[deprecated (since := "2025-11-27")] alias sorted_lt_range := sortedLT_range - -@[deprecated "use sortedLT_range.sortedLE" (since := "2025-11-27")] -theorem sorted_le_range (n) : - (range n).SortedLE := (sortedLT_range n).sortedLE - theorem sortedLT_range' (a b) {s} (hs : s ≠ 0) : (range' a b s).SortedLT := (pairwise_lt_range' _ (Nat.pos_of_ne_zero hs)).sortedLT -@[deprecated (since := "2025-11-27")] alias sorted_lt_range' := sortedLT_range' - -@[deprecated "use sortedLT_range'.sortedLE" (since := "2025-11-27")] -theorem sorted_le_range' (a b) {s} (hs : s ≠ 0) : - (range' a b s).SortedLE := (sortedLT_range' a b hs).sortedLE - theorem sortedLE_range' (a b s) : (range' a b s).SortedLE := (pairwise_le_range' _).sortedLE @@ -558,11 +535,6 @@ strictly antitone. -/ simp only [sortedGT_iff_strictAnti_get, StrictAnti, Fin.forall_iff, length_ofFn, get_ofFn, Fin.cast_mk, Fin.mk_lt_mk] -@[deprecated (since := "2025-11-27")] alias sorted_le_ofFn_iff := sortedLE_ofFn_iff -@[deprecated (since := "2025-11-27")] alias sorted_lt_ofFn_iff := sortedLT_ofFn_iff -@[deprecated (since := "2025-11-27")] alias sorted_ge_ofFn_iff := sortedGE_ofFn_iff -@[deprecated (since := "2025-11-27")] alias sorted_gt_ofFn_iff := sortedGT_ofFn_iff - /-- The list obtained from a monotone tuple is sorted. -/ protected alias ⟨SortedLE.monotone, _root_.Monotone.sortedLE_ofFn⟩ := sortedLE_ofFn_iff /-- The list obtained from an antitone tuple is sorted. -/ @@ -652,9 +624,6 @@ protected theorem SortedLE.sortedLT_of_nodup {l : List α} (h₁ : l.SortedLE) ( protected theorem SortedGE.sortedGT_of_nodup {l : List α} (h₁ : l.SortedGE) (h₂ : l.Nodup) : l.SortedGT := (h₁.antitone_get.strictAnti_of_injective h₂.injective_get).sortedGT -@[deprecated (since := "2025-11-27")] alias Sorted.lt_of_le := SortedLE.sortedLT_of_nodup -@[deprecated (since := "2025-11-27")] alias Sorted.gt_of_ge := SortedGE.sortedGT_of_nodup - theorem sortedLT_iff_nodup_and_sortedLE : l.SortedLT ↔ l.Nodup ∧ l.SortedLE := ⟨fun h => ⟨h.nodup, h.sortedLE⟩, fun h => h.2.sortedLT_of_nodup h.1⟩ @@ -754,15 +723,11 @@ variable {α β : Type*} {ra : α → α → Prop} {rb : β → β → Prop} theorem pairwise_listMap (e : ra ↪r rb) {l : List α} : (l.map e).Pairwise rb ↔ l.Pairwise ra := by simp [pairwise_map, e.map_rel_iff] -@[deprecated (since := "2025-11-27")] alias sorted_listMap := pairwise_listMap - @[simp] theorem pairwise_swap_listMap (e : ra ↪r rb) {l : List α} : (l.map e).Pairwise (Function.swap rb) ↔ l.Pairwise (Function.swap ra) := by simp [pairwise_map, e.map_rel_iff] -@[deprecated (since := "2025-11-27")] alias sorted_swap_listMap := pairwise_swap_listMap - end RelEmbedding namespace RelIso @@ -807,11 +772,6 @@ theorem sortedGT_listMap (e : α ↪o β) {l : List α} : (l.map e).SortedGT ↔ l.SortedGT := by simp_rw [← sortedLT_reverse, ← map_reverse, sortedLT_listMap] -@[deprecated (since := "2025-11-27")] alias sorted_le_listMap := sortedLE_listMap -@[deprecated (since := "2025-11-27")] alias sorted_lt_listMap := sortedLT_listMap -@[deprecated (since := "2025-11-27")] alias sorted_ge_listMap := sortedGE_listMap -@[deprecated (since := "2025-11-27")] alias sorted_gt_listMap := sortedGT_listMap - end OrderEmbedding namespace OrderIso diff --git a/Mathlib/Data/Nat/Choose/Basic.lean b/Mathlib/Data/Nat/Choose/Basic.lean index efef1f793d39f9..1cd090d71c8175 100644 --- a/Mathlib/Data/Nat/Choose/Basic.lean +++ b/Mathlib/Data/Nat/Choose/Basic.lean @@ -137,10 +137,6 @@ theorem add_one_mul_choose_eq : ∀ n k, (n + 1) * choose n k = choose (n + 1) ( mul_add_one, ← add_one_mul_choose_eq n, Nat.add_right_comm _ _ (_ * _), ← Nat.mul_add, ← choose_succ_succ', ← add_one_mul] -@[deprecated add_one_mul_choose_eq (since := "2025-12-09")] -theorem succ_mul_choose_eq : ∀ n k, succ n * choose n k = choose (succ n) (succ k) * succ k := - add_one_mul_choose_eq - theorem choose_mul_factorial_mul_factorial : ∀ {n k}, k ≤ n → choose n k * k ! * (n - k)! = n ! | 0, _, hk => by simp [Nat.eq_zero_of_le_zero hk] | n + 1, 0, _ => by simp diff --git a/Mathlib/Data/Rat/Lemmas.lean b/Mathlib/Data/Rat/Lemmas.lean index fe43e95dfecb29..0f504d45b2ebdc 100644 --- a/Mathlib/Data/Rat/Lemmas.lean +++ b/Mathlib/Data/Rat/Lemmas.lean @@ -56,14 +56,6 @@ theorem num_den_mk {q : ℚ} {n d : ℤ} (hd : d ≠ 0) (qdf : q = n /. d) : rw [qdf] exact Rat.num_ne_zero.2 ((divInt_ne_zero hd).mpr hn) -@[deprecated Rat.num_divInt (since := "2025-12-27")] -theorem num_mk (n d : ℤ) : (n /. d).num = d.sign * n / n.gcd d := - Int.gcd_comm .. ▸ Rat.num_divInt .. - -@[deprecated Rat.den_divInt (since := "2025-12-27")] -theorem den_mk (n d : ℤ) : (n /. d).den = if d = 0 then 1 else d.natAbs / n.gcd d := - Int.gcd_comm .. ▸ Rat.den_divInt .. - theorem add_den_dvd_lcm (q₁ q₂ : ℚ) : (q₁ + q₂).den ∣ q₁.den.lcm q₂.den := by rw [add_def, normalize_eq, Nat.div_dvd_iff_dvd_mul (Nat.gcd_dvd_right _ _) (Nat.gcd_pos_of_pos_right _ (by simp [Nat.pos_iff_ne_zero])), ← Nat.gcd_mul_lcm, diff --git a/Mathlib/Data/Rel/Cover.lean b/Mathlib/Data/Rel/Cover.lean index c2dd4502b33f27..50ea431063238f 100644 --- a/Mathlib/Data/Rel/Cover.lean +++ b/Mathlib/Data/Rel/Cover.lean @@ -80,6 +80,4 @@ lemma IsCover.of_maximal_isSeparated [U.IsRefl] [U.IsSymm] @[simp] lemma isCover_id : IsCover .id s N ↔ s ⊆ N := by simp [IsCover, subset_def] -@[deprecated (since := "2025-12-19")] alias isCover_relId := isCover_id - end SetRel diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index f351d53127ac98..27e048988a4e4f 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -813,8 +813,6 @@ theorem sep_eq_inter_sep {α : Type*} {s t : Set α} {p : α → Prop} (hst : s rw [← inter_setOf_eq_sep s p, ← inter_setOf_eq_sep t p, ← inter_assoc, ← left_eq_inter.mpr hst] -@[deprecated (since := "2025-12-10")] alias sep_of_subset := sep_eq_inter_sep - @[simp] theorem inter_ssubset_right_iff : s ∩ t ⊂ t ↔ ¬ t ⊆ s := inf_lt_right diff --git a/Mathlib/Data/Sym/Sym2.lean b/Mathlib/Data/Sym/Sym2.lean index 3e617857b0a269..d335f439ab8dd3 100644 --- a/Mathlib/Data/Sym/Sym2.lean +++ b/Mathlib/Data/Sym/Sym2.lean @@ -553,18 +553,11 @@ def diagSet : Set (Sym2 α) := {z | z.IsDiag} @[simp] lemma mem_diagSet : z ∈ diagSet ↔ z.IsDiag := .rfl -@[deprecated mem_diagSet (since := "2025-12-10")] -theorem mem_diagSet_iff_isDiag (z : Sym2 α) : z ∈ diagSet ↔ z.IsDiag := .rfl - @[simp] lemma range_diag : .range (diag : α → Sym2 α) = diagSet := by ext ⟨a, b⟩; simp [diag, eq_comm] theorem diagSet_eq_setOf_isDiag : diagSet = {z : Sym2 α | z.IsDiag} := rfl -@[deprecated Set.compl_setOf (since := "2025-12-10")] -theorem diagSet_compl_eq_setOf_not_isDiag : diagSetᶜ = {z : Sym2 α | ¬z.IsDiag} := - congrArg _ diagSet_eq_setOf_isDiag - theorem diagSet_eq_univ_of_subsingleton [Subsingleton α] : @diagSet α = Set.univ := by ext; simp instance IsDiag.decidablePred (α : Type u) [DecidableEq α] : DecidablePred (@IsDiag α) := @@ -648,14 +641,6 @@ lemma diagSet_compl_eq_fromRel_ne : diagSetᶜ = fromRel (α := α) (r := Ne) in @[simp] lemma fromRel_subset_compl_diagSet (hr : Std.Symm r) : fromRel hr ⊆ diagSetᶜ ↔ Std.Irrefl r := by simp [Set.subset_compl_iff_disjoint_left] -@[deprecated diagSet_subset_fromRel (since := "2025-12-10")] -theorem reflexive_iff_diagSet_subset_fromRel (sym : Std.Symm r) : - Std.Refl r ↔ diagSet ⊆ fromRel sym := by simp - -@[deprecated fromRel_subset_compl_diagSet (since := "2025-12-10")] -theorem irreflexive_iff_fromRel_subset_diagSet_compl (sym : Std.Symm r) : - Std.Irrefl r ↔ fromRel sym ⊆ diagSetᶜ := by simp - theorem fromRel_irrefl {sym : Std.Symm r} : Std.Irrefl r ↔ ∀ {z}, z ∈ fromRel sym → ¬IsDiag z where mp := by intro ⟨h⟩; apply Sym2.ind; aesop mpr h := ⟨fun _ hr ↦ h (fromRel_prop.mpr hr) rfl⟩ diff --git a/Mathlib/Dynamics/Ergodic/Ergodic.lean b/Mathlib/Dynamics/Ergodic/Ergodic.lean index d0d2eb3aebaedd..a6f34fde5c1924 100644 --- a/Mathlib/Dynamics/Ergodic/Ergodic.lean +++ b/Mathlib/Dynamics/Ergodic/Ergodic.lean @@ -98,9 +98,6 @@ theorem preErgodic_of_preErgodic_semiconj (hg : MeasurePreserving g μ μ') (hf apply hf.aeconst_set (hg.measurable hs₀) rw [← preimage_comp, h_comm.comp_eq, preimage_comp, hs₁] -@[deprecated (since := "2025-11-19")] -alias preErgodic_of_preErgodic_conjugate := preErgodic_of_preErgodic_semiconj - theorem ergodic_of_ergodic_semiconj (hg : MeasurePreserving g μ μ') (hf : Ergodic f μ) {f' : β → β} (hf' : Measurable f') (h_comm : Semiconj g f f') : Ergodic f' μ' := ⟨hg.of_semiconj hf.toMeasurePreserving h_comm hf', diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean index c39742442eae26..4356fb001bd12b 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean @@ -149,18 +149,10 @@ theorem adjoin_toSubalgebra_of_isAlgebraic {S : Set E} (hS : ∀ x ∈ S, IsAlge adjoin_eq_algebra_adjoin _ _ fun _ ↦ (Algebra.IsIntegral.adjoin fun x hx ↦ (hS x hx).isIntegral).inv_mem -@[deprecated (since := "2025-11-24")] alias adjoin_algebraic_toSubalgebra := - adjoin_toSubalgebra_of_isAlgebraic - theorem adjoin_simple_toSubalgebra_of_isAlgebraic (hα : IsAlgebraic F α) : F⟮α⟯.toSubalgebra = F[α] := adjoin_toSubalgebra_of_isAlgebraic <| by simpa -@[deprecated "Use `adjoin_simple_toSubalgebra_of_isAlgebraic` instead" (since := "2025-11-24")] -theorem adjoin_simple_toSubalgebra_of_integral (hα : IsIntegral F α) : - F⟮α⟯.toSubalgebra = F[α] := - adjoin_toSubalgebra_of_isAlgebraic <| by simpa [isAlgebraic_iff_isIntegral] - @[simp] theorem adjoin_toSubalgebra [Algebra.IsAlgebraic F E] (S : Set E) : (adjoin F S).toSubalgebra = Algebra.adjoin F S := @@ -195,9 +187,6 @@ lemma _root_.Algebra.finite_of_essFiniteType_of_isAlgebraic simpa [← toSubalgebra_inj] using hs exact Algebra.IsIntegral.finite -@[deprecated (since := "2025-12-08")] -alias finite_of_fg_of_isAlgebraic := Algebra.finite_of_essFiniteType_of_isAlgebraic - section RingHom variable {A B C : Type*} [Field A] [CommSemiring B] [Field C] [Algebra A B] @@ -287,17 +276,11 @@ theorem adjoin_intermediateField_toSubalgebra_of_isAlgebraic_left (L : Intermedi (adjoin E (L : Set K)).toSubalgebra = Algebra.adjoin E (L : Set K) := adjoin_intermediateField_toSubalgebra_of_isAlgebraic E L (Or.inl halg) -@[deprecated (since := "2025-11-24")] alias adjoin_toSubalgebra_of_isAlgebraic_left := - adjoin_intermediateField_toSubalgebra_of_isAlgebraic_left - theorem adjoin_intermediateField_toSubalgebra_of_isAlgebraic_right (L : IntermediateField F K) [halg : Algebra.IsAlgebraic F L] : (adjoin E (L : Set K)).toSubalgebra = Algebra.adjoin E (L : Set K) := adjoin_intermediateField_toSubalgebra_of_isAlgebraic E L (Or.inr halg) -@[deprecated (since := "2025-11-24")] alias adjoin_toSubalgebra_of_isAlgebraic_right := - adjoin_intermediateField_toSubalgebra_of_isAlgebraic_right - end Tower end AdjoinSimple diff --git a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean index d506815e10ab59..346eb1c2ea3bde 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean @@ -62,18 +62,6 @@ non-constant polynomials have a root. See `IsAlgClosed.exists_root` and class IsAlgClosed : Prop where splits : ∀ p : k[X], p.Splits -@[deprecated (since := "2025-12-09")] -alias IsAlgClosed.factors := IsAlgClosed.splits - -/-- Every polynomial splits in the field extension `f : K →+* k` if `k` is algebraically closed. - -See also `IsAlgClosed.splits_domain` for the case where `K` is algebraically closed. --/ -@[deprecated "This is a special case of `IsAlgClosed.splits`." (since := "2025-12-09")] -theorem IsAlgClosed.splits_codomain {k K : Type*} [Field k] [IsAlgClosed k] [CommRing K] - {f : K →+* k} (p : K[X]) : (p.map f).Splits := - IsAlgClosed.splits (p.map f) - /-- Every polynomial splits in the field extension `f : K →+* k` if `K` is algebraically closed. -/ theorem IsAlgClosed.splits_domain {k K : Type*} [Field k] [IsAlgClosed k] [Field K] {f : k →+* K} (p : k[X]) : (p.map f).Splits := diff --git a/Mathlib/FieldTheory/IsSepClosed.lean b/Mathlib/FieldTheory/IsSepClosed.lean index fd98ad49f7d954..9a6d4cbdcdea99 100644 --- a/Mathlib/FieldTheory/IsSepClosed.lean +++ b/Mathlib/FieldTheory/IsSepClosed.lean @@ -66,9 +66,6 @@ see `IsSepClosed.splits_codomain` and `IsSepClosed.splits_domain`. class IsSepClosed : Prop where splits_of_separable : ∀ p : k[X], p.Separable → p.Splits -@[deprecated (since := "2025-12-09")] -alias IsSepClosed.factors_of_separable := IsSepClosed.splits_of_separable - /-- An algebraically closed field is also separably closed. -/ instance IsSepClosed.of_isAlgClosed [IsAlgClosed k] : IsSepClosed k := ⟨fun p _ ↦ IsAlgClosed.splits p⟩ diff --git a/Mathlib/FieldTheory/Normal/Closure.lean b/Mathlib/FieldTheory/Normal/Closure.lean index 75e15cd4f7e671..741f14a8f38e3e 100644 --- a/Mathlib/FieldTheory/Normal/Closure.lean +++ b/Mathlib/FieldTheory/Normal/Closure.lean @@ -262,8 +262,6 @@ noncomputable def normalClosureOperator : ClosureOperator (IntermediateField F L le_closure' := le_normalClosure idempotent' K := normalClosure_of_normal (normalClosure F K L) -@[deprecated (since := "2025-11-21")] alias closureOperator := normalClosureOperator - variable {K : IntermediateField F L} {F L} lemma normal_iff_normalClosure_eq : Normal F K ↔ normalClosure F K L = K := diff --git a/Mathlib/FieldTheory/SeparableClosure.lean b/Mathlib/FieldTheory/SeparableClosure.lean index e8344ba55beafe..e6527ebee11585 100644 --- a/Mathlib/FieldTheory/SeparableClosure.lean +++ b/Mathlib/FieldTheory/SeparableClosure.lean @@ -374,10 +374,6 @@ lemma exists_finset_maximalFor_isTranscendenceBasis_separableClosure inferInstanceAs <| Module.Finite (separableClosure (adjoin F (s : Set E)) E) E exact d.not_lt_argminOn _ ht (by apply finrank_lt_of_gt H) -@[deprecated (since := "2025-12-08")] -alias FG.exists_finset_maximalFor_isTranscendenceBasis_separableClosure := - IntermediateField.exists_finset_maximalFor_isTranscendenceBasis_separableClosure - @[simp] theorem sepDegree_bot : sepDegree F (⊥ : IntermediateField F E) = 1 := by have := lift_sepDegree_eq_of_equiv _ _ _ (botEquiv F E) diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index ba5df4fe9597cb..96b438c8359acf 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -853,10 +853,6 @@ theorem IntermediateField.isSeparable_adjoin_pair_of_isSeparable {x y : E} namespace Field -/-- Any element `x` of `F` is a separable element of `E / F` when embedded into `E`. -/ -@[deprecated (since := "2025-11-21")] -protected alias isSeparable_algebraMap := _root_.isSeparable_algebraMap - variable {F E} /-- If `x` and `y` are both separable elements, then `x * y` is also a separable element. -/ diff --git a/Mathlib/Geometry/Euclidean/Angle/Unoriented/TriangleInequality.lean b/Mathlib/Geometry/Euclidean/Angle/Unoriented/TriangleInequality.lean index 2a092573861fee..48fd2d90c08250 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Unoriented/TriangleInequality.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Unoriented/TriangleInequality.lean @@ -38,8 +38,6 @@ lemma inner_ortho_nonneg {x y : V} (hx : ‖x‖ = 1) (hy : ‖y‖ = 1) : 0 ≤ inner_self_eq_one_of_norm_eq_one hx, real_inner_smul_right, real_inner_comm, sub_nonneg] grw [← sq, sq_le_one_iff_abs_le_one, abs_real_inner_le_norm, hx, hy, one_mul] -@[deprecated (since := "2025-12-20")] alias inner_ortho_nonneg_of_norm_eq_one := inner_ortho_nonneg - lemma inner_normalize_ortho (x y : V) : ⟪y, normalize (ortho y x)⟫ = 0 := by simp only [NormedSpace.normalize, real_inner_smul_right, mul_eq_zero, inv_eq_zero, norm_eq_zero] right; rw [ortho, real_inner_comm, Submodule.starProjection_inner_eq_zero] diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index 545786bc5c650f..1b80bee02fe21e 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -403,8 +403,6 @@ protected lemma _root_.ModelWithCorners.isImmersionAtOfComplement {n : ℕ} {x : (IsManifold.subset_maximalAtlas (by simp)) (IsManifold.subset_maximalAtlas (by simp)) (by simp [Function.comp_def]) -@[deprecated (since := "2025-12-16")] alias ofOpen := of_opens - /-- Prefer using `IsImmersionAtOfComplement.continuousAt` instead -/ theorem continuousOn (h : IsImmersionAtOfComplement F I J n f x) : ContinuousOn f h.domChart.source := by @@ -663,8 +661,6 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) (hx : x ∈ s) use PUnit, by infer_instance, by infer_instance apply Manifold.IsImmersionAtOfComplement.of_opens -@[deprecated (since := "2025-12-16")] alias ofOpen := of_opens - /-- Every `ModelWithCorners 𝕜 E H` is an immersion when viewed as a map `H → E`. -/ protected lemma _root_.ModelWithCorners.isImmersionAt {n : ℕ} {x : H} : IsImmersionAt I (modelWithCornersSelf 𝕜 E) n I x := by @@ -821,8 +817,6 @@ lemma sumInr {M' : Type*} [TopologicalSpace M'] [ChartedSpace H M'] [IsManifold rw [(chartAt H x).right_inv (by simp_all), I.right_inv (by simp_all)] simpa -@[deprecated (since := "2025-12-16")] alias ofOpen := of_opens - /-- A `C^n` immersion is `C^n`. -/ theorem contMDiff (h : IsImmersionOfComplement F I J n f) : CMDiff n f := fun x ↦ (h x).contMDiffAt @@ -896,8 +890,6 @@ lemma of_opens [IsManifold I n M] (s : TopologicalSpace.Opens M) : use PUnit, by infer_instance, by infer_instance exact IsImmersionOfComplement.of_opens s -@[deprecated (since := "2025-12-16")] alias ofOpen := of_opens - /-- Every `ModelWithCorners 𝕜 E H` is an immersion when viewed as a map `H → E`. -/ protected lemma _root_.ModelWithCorners.isImmersion {n : ℕ} : IsImmersion I (modelWithCornersSelf 𝕜 E) n I := by diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 4be4e83777f6a7..50a22f39400c7e 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -203,9 +203,6 @@ def ModelWithCorners.ofTargetUniv (𝕜 : Type*) [NontriviallyNormedField 𝕜] have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm] simp [this, htarget] -@[deprecated (since := "2025-12-19")] -alias ModelWithCorners.of_target_univ := ModelWithCorners.ofTargetUniv - attribute [simp, mfld_simps] ModelWithCorners.source_eq /-- A vector space is a model with corners, denoted as `𝓘(𝕜, E)` within the `Manifold` namespace. -/ @@ -335,9 +332,6 @@ def ofConvexRange have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm] simp [this, hint] -@[deprecated (since := "2025-12-19")] noncomputable alias of_convex_range := - ModelWithCorners.ofConvexRange - theorem convex_range [NormedSpace ℝ E] : Convex ℝ (range I) := by by_cases h : IsRCLikeNormedField 𝕜 · let : RCLike 𝕜 := h.rclike diff --git a/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean b/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean index db32ceb65a874e..efaba061235323 100644 --- a/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean +++ b/Mathlib/Geometry/Manifold/LocalDiffeomorph.lean @@ -380,9 +380,6 @@ def IsLocalDiffeomorph.diffeomorphOfBijective have : y = (Φ x) x := ((hgInverse.2 y).congr (hfx hx)).mp rfl exact this ▸ (Φ x).map_source hx } -@[deprecated (since := "2025-12-19")] -alias IsLocalDiffeomorph.diffeomorph_of_bijective := IsLocalDiffeomorph.diffeomorphOfBijective - end Basic section Differential diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index 2a3a5450cf8ece..36b75f9d63a6a5 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -501,9 +501,6 @@ theorem exists_contMDiffMap_zero_one_of_isClosed [T2Space M] [SigmaCompactSpace refine fun i => f.toSmoothPartitionOfUnity_zero_of_zero ?_ exact notMem_support.1 (subset_compl_comm.1 (hf.support_subset i) hx) -@[deprecated (since := "2025-12-17")] -alias exists_smooth_zero_one_of_isClosed := exists_contMDiffMap_zero_one_of_isClosed - /-- Given two disjoint closed sets `s, t` in a Hausdorff normal σ-compact finite-dimensional manifold `M`, there exists a smooth function `f : M → [0,1]` that vanishes in a neighbourhood of `s` and is equal to `1` in a neighbourhood of `t`. -/ @@ -522,9 +519,6 @@ theorem exists_contMDiffMap_zero_one_nhds_of_isClosed · exact eventually_of_mem (mem_of_superset (u_op.mem_nhdsSet.mpr hsu) subset_closure) hfu · exact eventually_of_mem (mem_of_superset (v_op.mem_nhdsSet.mpr htv) subset_closure) hfv -@[deprecated (since := "2025-12-17")] -alias exists_smooth_zero_one_nhds_of_isClosed := exists_contMDiffMap_zero_one_nhds_of_isClosed - /-- Given two sets `s, t` in a Hausdorff normal σ-compact finite-dimensional manifold `M` with `s` open and `s ⊆ interior t`, there is a smooth function `f : M → [0,1]` which is equal to `s` in a neighbourhood of `s` and has support contained in `t`. -/ @@ -538,9 +532,6 @@ theorem exists_contMDiffMap_one_nhds_of_subset_interior refine ⟨f, h1, fun x hx ↦ ?_, hf⟩ exact h0.self_of_nhdsSet _ fun hx' ↦ hx <| interior_subset hx' -@[deprecated (since := "2025-12-17")] -alias exists_smooth_one_nhds_of_subset_interior := exists_contMDiffMap_one_nhds_of_subset_interior - namespace SmoothPartitionOfUnity /-- A `SmoothPartitionOfUnity` that consists of a single function, uniformly equal to one, @@ -639,14 +630,6 @@ theorem exists_contMDiffSection_forall_mem_convex_of_local have h_x_in_Umap_j : x ∈ W j := interior_subset (hρU j h_x_in_tsupport_ρj) exact h_mem_t j x h_x_in_Umap_j -@[deprecated (since := "2025-12-17")] -alias exists_contMDiffOn_section_forall_mem_convex_of_local := - exists_contMDiffSection_forall_mem_convex_of_local - -@[deprecated (since := "2025-12-17")] -alias exists_smooth_section_forall_mem_convex_of_local := - exists_contMDiffSection_forall_mem_convex_of_local - /-- Let `M` be a σ-compact Hausdorff finite-dimensional topological manifold. Let `t : M → Set F` be a family of convex sets. Suppose that for each point `x : M` there exists a neighborhood `U ∈ 𝓝 x` and a function `g : M → F` such that `g` is $C^n$ smooth on `U` and `g y ∈ t y` for all @@ -663,13 +646,6 @@ theorem exists_contMDiffMap_forall_mem_convex_of_local (ht : ∀ x, Convex ℝ ( ⟨U, hU, g, fun y hy ↦ Bundle.contMDiffWithinAt_section |>.mpr <| hgs y hy, hgt⟩) ⟨⟨s, (Bundle.contMDiffAt_section _ |>.mp <| s.contMDiff ·)⟩, hs⟩ -@[deprecated (since := "2025-12-17")] -alias exists_contMDiffOn_forall_mem_convex_of_local := - exists_contMDiffMap_forall_mem_convex_of_local - -@[deprecated (since := "2025-12-17")] -alias exists_smooth_forall_mem_convex_of_local := exists_contMDiffMap_forall_mem_convex_of_local - /-- Let `M` be a σ-compact Hausdorff finite-dimensional topological manifold. Let `t : M → Set F` be a family of convex sets. Suppose that for each point `x : M` there exists a vector `c : F` such that for all `y` in a neighborhood of `x` we have `c ∈ t y`. Then there exists a smooth function @@ -681,10 +657,6 @@ theorem exists_contMDiffMap_forall_mem_convex_of_local_const (ht : ∀ x, Convex let ⟨c, hc⟩ := Hloc x ⟨_, hc, fun _ => c, contMDiffOn_const, fun _ => id⟩ -@[deprecated (since := "2025-12-17")] -alias exists_smooth_forall_mem_convex_of_local_const := - exists_contMDiffMap_forall_mem_convex_of_local_const - /-- Let `M` be a smooth σ-compact manifold with extended distance. Let `K : ι → Set M` be a locally finite family of closed sets, let `U : ι → Set M` be a family of open sets such that `K i ⊆ U i` for all `i`. Then there exists a positive smooth function `δ : M → ℝ≥0` such that for any `i` and @@ -705,10 +677,6 @@ theorem Metric.exists_contMDiffMap_forall_closedEBall_subset alias Emetric.exists_contMDiffMap_forall_closedBall_subset := Metric.exists_contMDiffMap_forall_closedEBall_subset -@[deprecated (since := "2025-12-17")] -alias Emetric.exists_smooth_forall_closedBall_subset := - Metric.exists_contMDiffMap_forall_closedEBall_subset - /-- Let `M` be a smooth σ-compact manifold with a metric. Let `K : ι → Set M` be a locally finite family of closed sets, let `U : ι → Set M` be a family of open sets such that `K i ⊆ U i` for all `i`. Then there exists a positive smooth function `δ : M → ℝ≥0` such that for any `i` and `x ∈ K i`, @@ -725,10 +693,6 @@ theorem Metric.exists_contMDiffMap_forall_closedBall_subset rw [← Metric.closedEBall_ofReal (hδ0 _).le] exact hδ i x hx -@[deprecated (since := "2025-12-17")] -alias Metric.exists_smooth_forall_closedBall_subset := - Metric.exists_contMDiffMap_forall_closedBall_subset - lemma IsOpen.exists_contMDiff_support_eq_aux {s : Set H} (hs : IsOpen s) : ∃ f : H → ℝ, f.support = s ∧ CMDiff n f ∧ Set.range f ⊆ Set.Icc 0 1 := by have h's : IsOpen (I.symm ⁻¹' s) := I.continuous_symm.isOpen_preimage _ hs @@ -739,9 +703,6 @@ lemma IsOpen.exists_contMDiff_support_eq_aux {s : Set H} (hs : IsOpen s) : · exact f_diff.comp_contMDiff I.contMDiff · exact Subset.trans (range_comp_subset_range _ _) f_range -@[deprecated (since := "2025-12-17")] -alias IsOpen.exists_msmooth_support_eq_aux := IsOpen.exists_contMDiff_support_eq_aux - /-- Given an open set in a finite-dimensional real manifold, there exists a nonnegative smooth function with support equal to `s`. -/ theorem IsOpen.exists_contMDiff_support_eq {s : Set M} (hs : IsOpen s) : @@ -791,9 +752,6 @@ theorem IsOpen.exists_contMDiff_support_eq {s : Set M} (hs : IsOpen s) : · intro x apply finsum_nonneg (fun c ↦ h''g c x) -@[deprecated (since := "2025-12-17")] -alias IsOpen.exists_msmooth_support_eq := IsOpen.exists_contMDiff_support_eq - /-- Given an open set `s` containing a closed set `t` in a finite-dimensional real manifold, there exists a smooth function with support equal to `s`, taking values in `[0,1]`, and equal to `1` exactly on `t`. -/ @@ -829,9 +787,6 @@ theorem exists_contMDiff_support_eq_eq_one_iff · intro x simp [div_eq_one_iff_eq (A x).ne', left_eq_add, ← notMem_support, g_supp] -@[deprecated (since := "2025-12-17")] -alias exists_msmooth_support_eq_eq_one_iff := exists_contMDiff_support_eq_eq_one_iff - /-- Given two disjoint closed sets `s, t` in a Hausdorff σ-compact finite-dimensional manifold, there exists an infinitely smooth function that is equal to `0` exactly on `s` and to `1` exactly on `t`. See also `exists_contMDiffMap_zero_one_of_isClosed` for a @@ -844,6 +799,3 @@ theorem exists_contMDiff_zero_iff_one_iff_of_isClosed {s t : Set M} ⟨f, f_diff, f_range, fs, ft⟩ refine ⟨f, f_diff, f_range, ?_, ft⟩ simp [← notMem_support, fs] - -@[deprecated (since := "2025-12-17")] -alias exists_msmooth_zero_iff_one_iff_of_isClosed := exists_contMDiff_zero_iff_one_iff_of_isClosed diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 9cc3b732ee1c29..37737a691ee37e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -178,9 +178,6 @@ noncomputable def fintypeOfFiniteDimensional [VectorBundle 𝕜 F V] [FiniteDime exact Finite.equiv phi.symm exact FiniteDimensional.fintypeBasisIndex (hs.toBasisAt hx) -@[deprecated (since := "2025-12-19")] -alias fintype_of_finiteDimensional := fintypeOfFiniteDimensional - open scoped Classical in /-- Coefficients of a section `s` of `V` w.r.t. a local frame `{s i}` on `u`. Outside of `u`, this returns the junk value 0. -/ diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 9c5c5cb048acd4..66683c5dd8a3e5 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -568,9 +568,6 @@ theorem toSheafedSpaceHom_hom_base : (toSheafedSpaceHom Y f).hom.base = f.base : theorem toSheafedSpaceHom_hom_c : (toSheafedSpaceHom Y f).hom.c = f.c := rfl -@[deprecated (since := "2025-12-18")] alias toSheafedSpaceHom_base := toSheafedSpaceHom_hom_base -@[deprecated (since := "2025-12-18")] alias toSheafedSpaceHom_c := toSheafedSpaceHom_hom_c - instance toSheafedSpace_isOpenImmersion : SheafedSpace.IsOpenImmersion (toSheafedSpaceHom Y f) := H diff --git a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean index b3dbb9eeab7721..87d8e317595398 100644 --- a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean @@ -154,14 +154,6 @@ theorem congr_hom_app {X Y : SheafedSpace C} {α β : X ⟶ Y} (h : α = β) (U) α.hom.c.app U = β.hom.c.app U ≫ X.presheaf.map (eqToHom (by subst h; rfl)) := (PresheafedSpace.congr_app (by rw [h]) U) -@[deprecated (since := "2025-12-18")] alias id_base := id_hom_base -@[deprecated (since := "2025-12-18")] alias id_c := id_hom_c -@[deprecated (since := "2025-12-18")] alias id_c_app := id_hom_c_app -@[deprecated (since := "2025-12-18")] alias comp_base := comp_hom_base -@[deprecated (since := "2025-12-18")] alias comp_c_app := comp_hom_c_app -@[deprecated (since := "2025-12-18")] alias comp_c_app' := comp_hom_c_app' -@[deprecated (since := "2025-12-18")] alias congr_app := congr_hom_app - variable (C) /-- The forgetful functor from `SheafedSpace` to `Top`. -/ diff --git a/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean b/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean index 05007575b5599e..5234be0abb992a 100644 --- a/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean +++ b/Mathlib/GroupTheory/GroupAction/MultipleTransitivity.lean @@ -663,16 +663,3 @@ theorem isPreprimitive_of_three_le_card (h : 3 ≤ Nat.card α) : { isTrivialBlock_of_isBlock := isTrivialBlock_of_isBlock α } end alternatingGroup - -namespace AlternatingGroup - -@[deprecated (since := "2025-12-16")] -alias isMultiplyPretransitive := alternatingGroup.isMultiplyPretransitive -@[deprecated (since := "2025-12-16")] -alias isPretransitive_of_three_le_card := alternatingGroup.isPretransitive_of_three_le_card -@[deprecated (since := "2025-12-16")] -alias isTrivialBlock_of_isBlock := alternatingGroup.isTrivialBlock_of_isBlock -@[deprecated (since := "2025-12-16")] -alias isPreprimitive_of_three_le_card := alternatingGroup.isPreprimitive_of_three_le_card - -end AlternatingGroup diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index ab9a1de50c4efa..1ec66ffca4826a 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -1189,9 +1189,6 @@ theorem pow_card_eq_one' {G : Type*} [Group G] {x : G} : x ^ Nat.card G = 1 := theorem pow_card_eq_one : x ^ Fintype.card G = 1 := by rw [← Nat.card_eq_fintype_card, pow_card_eq_one'] -@[deprecated "Use simp" (since := "2025-12-05")] -theorem pow_gcd_card_eq_one_iff : x ^ n.gcd (Fintype.card G) = 1 ↔ x ^ n = 1 := by simp - @[to_additive] theorem Subgroup.pow_index_mem {G : Type*} [Group G] (H : Subgroup G) [Normal H] (g : G) : g ^ index H ∈ H := by rw [← eq_one_iff, QuotientGroup.mk_pow H, index, pow_card_eq_one'] diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index dd18faf0f5e575..0cbcee57dc2738 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -123,14 +123,10 @@ theorem sameCycle_apply_right : SameCycle f x (f y) ↔ SameCycle f x y := by theorem sameCycle_symm_apply_left : SameCycle f (f.symm x) y ↔ SameCycle f x y := by rw [← sameCycle_apply_left, apply_symm_apply] -@[deprecated (since := "2025-11-17")] alias sameCycle_inv_apply_left := sameCycle_symm_apply_left - @[simp] theorem sameCycle_symm_apply_right : SameCycle f x (f.symm y) ↔ SameCycle f x y := by rw [← sameCycle_apply_right, apply_symm_apply] -@[deprecated (since := "2025-11-17")] alias sameCycle_inv_apply_right := sameCycle_symm_apply_right - @[simp] theorem sameCycle_zpow_left {n : ℤ} : SameCycle f ((f ^ n) x) y ↔ SameCycle f x y := (Equiv.addRight (n : ℤ)).exists_congr_left.trans <| by simp [SameCycle, zpow_add] diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index 6abea89347dbb3..70b4e3369386a4 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -61,9 +61,6 @@ theorem perm_symm_on_of_perm_on_finset {s : Finset α} {f : Perm α} (h : ∀ x obtain ⟨y2, hy2, rfl⟩ := h0 y hy simpa using hy2 -@[deprecated (since := "2025-11-17")] -alias perm_inv_on_of_perm_on_finset := perm_symm_on_of_perm_on_finset - theorem perm_symm_mapsTo_of_mapsTo (f : Perm α) {s : Set α} [Finite s] (h : Set.MapsTo f s s) : Set.MapsTo f.symm s s := by cases nonempty_fintype s @@ -73,24 +70,16 @@ theorem perm_symm_mapsTo_of_mapsTo (f : Perm α) {s : Set α} [Finite s] (h : Se (fun a ha => Set.mem_toFinset.mpr (h (Set.mem_toFinset.mp ha))) (Set.mem_toFinset.mpr hx) -@[deprecated (since := "2025-11-17")] alias perm_inv_mapsTo_of_mapsTo := perm_symm_mapsTo_of_mapsTo - @[simp] theorem perm_symm_mapsTo_iff_mapsTo {f : Perm α} {s : Set α} [Finite s] : Set.MapsTo f.symm s s ↔ Set.MapsTo f s s := ⟨perm_symm_mapsTo_of_mapsTo f⁻¹, perm_symm_mapsTo_of_mapsTo f⟩ -@[deprecated (since := "2025-11-17")] -alias perm_inv_mapsTo_iff_mapsTo := perm_symm_mapsTo_iff_mapsTo - theorem perm_symm_on_of_perm_on_finite {f : Perm α} {p : α → Prop} [Finite { x // p x }] (h : ∀ x, p x → p (f x)) {x : α} (hx : p x) : p (f.symm x) := by have : Finite { x | p x } := by simpa simpa using perm_symm_mapsTo_of_mapsTo (s := {x | p x}) f h hx -@[deprecated (since := "2025-11-17")] -alias perm_inv_on_of_perm_on_finite := perm_symm_on_of_perm_on_finite - /-- If the permutation `f` maps `{x // p x}` into itself, then this returns the permutation on `{x // p x}` induced by `f`. Note that the `h` hypothesis is weaker than for `Equiv.Perm.subtypePerm`. -/ diff --git a/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean b/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean index 3516919c0eb728..36496e5dc9de92 100644 --- a/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean +++ b/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean @@ -130,8 +130,6 @@ theorem exists_mem_stabilizer_smul_eq : classical exact ⟨swap a b, swap_mem_stabilizer ha hb, swap_apply_left a b⟩ -@[deprecated (since := "2025-12-16")] alias moves_in := exists_mem_stabilizer_smul_eq - theorem stabilizer.surjective_toPerm (s : Set α) : Function.Surjective (toPerm : stabilizer (Perm α) s → Perm s) := fun g ↦ by classical @@ -248,10 +246,6 @@ lemma subsingleton_of_ssubset_of_stabilizer_le exact hB.preimage f' exact isPreprimitive_stabilizer_of_surjective _ hG -@[deprecated (since := "2025-12-16")] -alias _root_.IsBlock.subsingleton_of_ssubset_compl_of_stabilizer_le := - subsingleton_of_ssubset_of_stabilizer_le - lemma subsingleton_of_ssubset_of_stabilizer_Perm_le {B : Set α} {G : Subgroup (Perm α)} (hB : IsBlock G B) (hB_ss_sc : B ⊂ s) (hG : stabilizer (Perm α) s ≤ G) : @@ -328,10 +322,6 @@ lemma compl_subset_of_stabilizer_le_of_not_subset_of_not_subset_compl rw [← is_one_pretransitive_iff] apply ofFixingSubgroup.isMultiplyPretransitive M s rfl -@[deprecated (since := "2025-12-16")] -alias _root_.IsBlock.compl_subset_of_stabilizer_le_of_not_subset_of_not_subset_compl := - compl_subset_of_stabilizer_le_of_not_subset_of_not_subset_compl - end MulAction.IsBlock namespace Equiv.Perm diff --git a/Mathlib/GroupTheory/Perm/Support.lean b/Mathlib/GroupTheory/Perm/Support.lean index 520542a620cae2..e7734d72ea1103 100644 --- a/Mathlib/GroupTheory/Perm/Support.lean +++ b/Mathlib/GroupTheory/Perm/Support.lean @@ -221,8 +221,6 @@ variable (p q : Perm α) lemma set_support_symm_eq : {x | p.symm x ≠ x} = {x | p x ≠ x} := by ext; simp [eq_symm_apply, eq_comm] -@[deprecated (since := "2025-11-17")] alias set_support_inv_eq := set_support_symm_eq - theorem set_support_apply_mem {p : Perm α} {a : α} : p a ∈ { x | p x ≠ x } ↔ a ∈ { x | p x ≠ x } := by simp diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean index a5247cb57e02cb..7b47b759d095d4 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean @@ -272,9 +272,6 @@ theorem Group.is_simple_iff_prime_card [Group α] [IsMulCommutative α] : theorem CommGroup.is_simple_iff_prime_card [CommGroup α] : IsSimpleGroup α ↔ (Nat.card α).Prime := Group.is_simple_iff_prime_card -@[deprecated (since := "2025-11-19")] -alias CommGroup.is_simple_iff_isCyclic_and_prime_card := CommGroup.is_simple_iff_prime_card - section SpecificInstances instance : IsAddCyclic ℤ := ⟨1, fun n ↦ ⟨n, by simp only [smul_eq_mul, mul_one]⟩⟩ diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index 49794d6963ed7b..3cd133e24fcfad 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -366,18 +366,6 @@ theorem comp_eq_id_comm {f g : M →ₗ[R] M} : f ∘ₗ g = id ↔ g ∘ₗ f = end Semiring -/-- In a finite-dimensional space, if linear maps are inverse to each other on one side then they -are also inverse to each other on the other side. -/ -@[deprecated mul_eq_one_symm (since := "2025-11-30")] -theorem mul_eq_one_of_mul_eq_one [FiniteDimensional K V] {f g : V →ₗ[K] V} (hfg : f * g = 1) : - g * f = 1 := mul_eq_one_symm hfg - -/-- In a finite-dimensional space, linear maps are inverse to each other on one side if and only if -they are inverse to each other on the other side. -/ -@[deprecated mul_eq_one_comm (since := "2025-11-30")] protected -theorem mul_eq_one_comm [FiniteDimensional K V] {f g : V →ₗ[K] V} : f * g = 1 ↔ g * f = 1 := - mul_eq_one_comm - theorem comap_eq_sup_ker_of_disjoint {p : Submodule K V} [FiniteDimensional K p] {f : V →ₗ[K] V} (h : ∀ x ∈ p, f x ∈ p) (h' : Disjoint p (ker f)) : p.comap f = p ⊔ ker f := by diff --git a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean index aeb9537a349ff2..528656d59fcc4c 100644 --- a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean @@ -295,36 +295,4 @@ instance (priority := low) instIsStablyFiniteRingOfCommSemiring : IsStablyFinite ((isAddUnit_detp_smul_mul_adjp hAB).add ((isAddUnit_detp_mul_detp hAB).smul_right _)).add_left_inj] at h -@[deprecated (since := "2025-11-29")] protected alias mul_eq_one_comm := mul_eq_one_comm - -variable (A B) - -/-- We can construct an instance of invertible A if A has a left inverse. -/ -@[deprecated invertibleOfLeftInverse (since := "2025-12-06"), implicit_reducible] -protected def invertibleOfLeftInverse (h : B * A = 1) : Invertible A := - invertibleOfLeftInverse _ _ h - -/-- We can construct an instance of invertible A if A has a right inverse. -/ -@[deprecated invertibleOfRightInverse (since := "2025-12-06"), implicit_reducible] -protected def invertibleOfRightInverse (h : A * B = 1) : Invertible A := - invertibleOfRightInverse _ _ h - -variable {A B} - -@[deprecated IsUnit.of_mul_eq_one_right (since := "2025-12-06")] -theorem isUnit_of_left_inverse (h : B * A = 1) : IsUnit A := - .of_mul_eq_one_right _ h - -@[deprecated isUnit_iff_exists_inv' (since := "2025-12-06")] -theorem exists_left_inverse_iff_isUnit : (∃ B, B * A = 1) ↔ IsUnit A := - isUnit_iff_exists_inv'.symm - -@[deprecated IsUnit.of_mul_eq_one (since := "2025-12-06")] -theorem isUnit_of_right_inverse (h : A * B = 1) : IsUnit A := - .of_mul_eq_one _ h - -@[deprecated isUnit_iff_exists_inv (since := "2025-12-06")] -theorem exists_right_inverse_iff_isUnit : (∃ B, A * B = 1) ↔ IsUnit A := - isUnit_iff_exists_inv.symm - end Matrix diff --git a/Mathlib/LinearAlgebra/RootSystem/Basic.lean b/Mathlib/LinearAlgebra/RootSystem/Basic.lean index 12e44086c77825..86ea435573a876 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Basic.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Basic.lean @@ -214,8 +214,6 @@ protected lemma IsRootSystem.ext [CharZero R] [IsDomain R] [IsTorsionFree R M] · exact P₁.coroot_root_two i · exact P₁.mapsTo_reflection_root i -@[deprecated (since := "2025-12-14")] alias _root_.RootSystem.ext := IsRootSystem.ext - private lemma coroot_eq_coreflection_of_root_eq_of_span_eq_top [CharZero R] [IsDomain R] [IsTorsionFree R M] (p : M →ₗ[R] N →ₗ[R] R) [p.IsPerfPair] (root : ι ↪ M) @@ -267,8 +265,6 @@ def mk'' : refine (coroot_eq_coreflection_of_root_eq_of_span_eq_top p root coroot hp hs hsp ?_) rw [equiv_of_mapsTo_apply, (exist_eq_reflection_of_mapsTo p root coroot i j hs).choose_spec] -@[deprecated (since := "2025-12-14")] noncomputable alias _root_.RootSystem.mk' := mk'' - variable {p root coroot hp hs hsp} in lemma isRootSystem_mk'' (h_int : ∀ i j, ∃ z : ℤ, z = p (root i) (coroot j)) : (mk'' p root coroot hp hs hsp).IsRootSystem where diff --git a/Mathlib/LinearAlgebra/RootSystem/Defs.lean b/Mathlib/LinearAlgebra/RootSystem/Defs.lean index 3dd44ce2f78b71..f90abb5db851e2 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Defs.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Defs.lean @@ -119,8 +119,6 @@ class IsRootSystem : Prop where span_root_eq_top : span R (range P.root) = ⊤ span_coroot_eq_top : span R (range P.coroot) = ⊤ -@[deprecated (since := "2025-12-14")] alias RootSystem := IsRootSystem - attribute [simp] IsRootSystem.span_root_eq_top attribute [simp] IsRootSystem.span_coroot_eq_top @@ -545,9 +543,6 @@ lemma reflectionPerm_eq_reflectionPerm_iff [P.IsRootSystem] (i j : ι) : ext x exact (P.reflectionPerm_eq_reflectionPerm_iff_of_span i j).mp h x <| by simp -@[deprecated (since := "2025-12-14")] -alias _root_.RootSystem.reflectionPerm_eq_reflectionPerm_iff := reflectionPerm_eq_reflectionPerm_iff - @[simp] lemma toPerfPair_comp_root : P.toPerfPair ∘ P.root = P.root' := rfl @[simp] lemma toPerfPair_flip_comp_coroot : diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean index 20eda0b8dfc45e..6b85caa8e09c0a 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean @@ -262,9 +262,6 @@ lemma rootForm_nondegenerate [P.IsRootSystem] : simpa [(rootForm_symmetric P).isRefl.nondegenerate_iff_separatingLeft, LinearMap.separatingLeft_iff_ker_eq_bot] using P.disjoint_rootSpan_ker_rootForm -@[deprecated (since := "2025-12-14")] -alias _root_.RootSystem.rootForm_nondegenerate := rootForm_nondegenerate - end IsDomain section Field @@ -443,9 +440,6 @@ lemma rootForm_anisotropic [P.IsRootSystem] : P.RootForm.toQuadraticMap.Anisotropic := fun x ↦ P.eq_zero_of_mem_rootSpan_of_rootForm_self_eq_zero <| by simp -@[deprecated (since := "2025-12-14")] -alias _root_.RootSystem.rootForm_anisotropic := rootForm_anisotropic - end LinearOrderedCommRing end RootPairing diff --git a/Mathlib/LinearAlgebra/Span/Basic.lean b/Mathlib/LinearAlgebra/Span/Basic.lean index cd957fe7a6343d..1d7829afd199c4 100644 --- a/Mathlib/LinearAlgebra/Span/Basic.lean +++ b/Mathlib/LinearAlgebra/Span/Basic.lean @@ -748,8 +748,6 @@ lemma smulRight_id : id.smulRight = toSpanSingleton R M := rfl theorem toSpanSingleton_apply_one (x : M) : toSpanSingleton R M x 1 = x := one_smul _ _ -@[deprecated (since := "2025-12-05")] alias toSpanSingleton_one := toSpanSingleton_apply_one - theorem toSpanSingleton_injective : Function.Injective (toSpanSingleton R M) := fun _ _ eq ↦ by simpa using congr($eq 1) @@ -785,9 +783,6 @@ theorem isIdempotentElem_map_one_iff {f : Module.End R R} : simp_rw [Module.End.mul_apply] exact ⟨fun h r ↦ by rw [← mul_one r, ← smul_eq_mul, map_smul, map_smul, h], (· 1)⟩ -@[deprecated (since := "2025-12-05")] alias isIdempotentElem_apply_one_iff := - isIdempotentElem_map_one_iff - /-- The range of `toSpanSingleton x` is the span of `x`. -/ theorem range_toSpanSingleton (x : M) : range (toSpanSingleton R M x) = .span R {x} := diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index abd4bda0904338..ee08b2e5be7480 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -964,8 +964,6 @@ alias reflTransGen_of_isTrans_reflexive := reflTransGen_le_of_le @[deprecated (since := "2026-02-21")] alias reflTransGen_of_transitive_reflexive := reflTransGen_le_of_le -@[deprecated (since := "2025-12-17")] alias reflTransGen_minimal := reflTransGen_le_of_le - theorem reflTransGen_le_of_equivalence_of_le {r' : α → α → Prop} (hr : Equivalence r) : r' ≤ r → ReflTransGen r' ≤ r := @reflTransGen_le_of_le _ _ _ hr.stdRefl hr.isTrans diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index e00aada65caaf8..4b20ff68db26a5 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -1067,8 +1067,6 @@ theorem Integrable.bdd_mul {f g : α → 𝕜} {c : ℝ} (hg : Integrable g μ) Integrable (fun x => f x * g x) μ := hg.bdd_smul c hf hf_bound -@[deprecated (since := "2025-11-26")] alias Integrable.bdd_mul' := Integrable.bdd_mul - theorem Integrable.mul_bdd {f g : α → 𝕜} {c : ℝ} (hf : Integrable f μ) (hg : AEStronglyMeasurable g μ) (hg_bound : ∀ᵐ x ∂μ, ‖g x‖ ≤ c) : Integrable (fun x => f x * g x) μ := diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Card.lean b/Mathlib/MeasureTheory/MeasurableSpace/Card.lean index 4b72b2e6a457fb..9fa88ef9201adb 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Card.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Card.lean @@ -125,9 +125,6 @@ theorem generateMeasurableRec_omega_one (s : Set (Set α)) : iUnion_mem_generateMeasurableRec fun n => ⟨_, Ordinal.lt_iSup_add_one I n, (hI n).2⟩⟩ simp -@[deprecated (since := "2025-12-22")] -alias generateMeasurableRec_omega1 := generateMeasurableRec_omega_one - theorem generateMeasurableRec_subset (s : Set (Set α)) (i : Ordinal) : generateMeasurableRec s i ⊆ { t | GenerateMeasurable s t } := by apply WellFoundedLT.induction i @@ -158,9 +155,6 @@ theorem generateMeasurableRec_of_omega_one_le (s : Set (Set α)) {i : Ordinal.{v rw [← generateMeasurable_eq_rec] exact generateMeasurableRec_subset s i -@[deprecated (since := "2025-12-22")] -alias generateMeasurableRec_of_omega1_le := generateMeasurableRec_of_omega_one_le - /-- At each step of the inductive construction, the cardinality bound `≤ #s ^ ℵ₀` holds. -/ theorem cardinal_generateMeasurableRec_le (s : Set (Set α)) (i : Ordinal.{v}) : #(generateMeasurableRec s i) ≤ max #s 2 ^ ℵ₀ := by diff --git a/Mathlib/MeasureTheory/Measure/Doubling.lean b/Mathlib/MeasureTheory/Measure/Doubling.lean index bf9d8c7e21a59c..df6db88bb11394 100644 --- a/Mathlib/MeasureTheory/Measure/Doubling.lean +++ b/Mathlib/MeasureTheory/Measure/Doubling.lean @@ -65,9 +65,6 @@ theorem eventually_measure_le_doublingConstant_mul : ∀ᶠ ε in 𝓝[>] 0, ∀ x, μ (closedBall x (2 * ε)) ≤ doublingConstant μ * μ (closedBall x ε) := Classical.choose_spec <| exists_measure_closedBall_le_mul μ -@[deprecated (since := "2025-12-17")] -alias exists_measure_closedBall_le_mul' := eventually_measure_le_doublingConstant_mul - theorem exists_eventually_forall_measure_closedBall_le_mul (K : ℝ) : ∃ C : ℝ≥0, ∀ᶠ ε in 𝓝[>] 0, ∀ x, ∀ t ≤ K, μ (closedBall x (t * ε)) ≤ C * μ (closedBall x ε) := by let C := doublingConstant μ diff --git a/Mathlib/MeasureTheory/Measure/Real.lean b/Mathlib/MeasureTheory/Measure/Real.lean index ec1f88b8aa8fe4..2be899626f4e66 100644 --- a/Mathlib/MeasureTheory/Measure/Real.lean +++ b/Mathlib/MeasureTheory/Measure/Real.lean @@ -54,8 +54,6 @@ theorem measureReal_zero_apply (s : Set α) : (0 : Measure α).real s = 0 := rfl @[simp] theorem measureReal_empty : μ.real ∅ = 0 := by simp [Measure.real] -@[deprecated (since := "2025-11-22")] alias measureReal_univ_eq_one := probReal_univ - @[simp] theorem measureReal_univ_pos [IsFiniteMeasure μ] [NeZero μ] : 0 < μ.real Set.univ := ENNReal.toReal_pos (NeZero.ne (μ Set.univ)) (by finiteness) diff --git a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean index 87f2aba876a96b..40636b9ca6ea48 100644 --- a/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean +++ b/Mathlib/MeasureTheory/Measure/RegularityCompacts.lean @@ -215,8 +215,4 @@ theorem innerRegular_isCompact_isClosed_measurableSet_of_finite [TopologicalSpac exact ⟨hs_compact.inter_right ht_open.isClosed_compl, hs_closed.inter (isClosed_compl_iff.mpr ht_open)⟩ -@[deprecated (since := "2025-12-08")] alias -PolishSpace.innerRegular_isCompact_isClosed_measurableSet := -innerRegular_isCompact_isClosed_measurableSet_of_finite - end MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/Tight.lean b/Mathlib/MeasureTheory/Measure/Tight.lean index f701950d3f29f4..72539e7df6e59a 100644 --- a/Mathlib/MeasureTheory/Measure/Tight.lean +++ b/Mathlib/MeasureTheory/Measure/Tight.lean @@ -68,10 +68,6 @@ lemma isTightMeasureSet_iff_exists_isCompact_measure_compl_le : · obtain ⟨K, h1, h2⟩ := h ε hε exact ⟨Kᶜ, ⟨K, h1, subset_rfl⟩, fun A hA μ hμS ↦ (μ.mono hA).trans (h2 μ hμS)⟩ -@[deprecated (since := "2025-12-13")] alias -IsTightMeasureSet_iff_exists_isCompact_measure_compl_le := -isTightMeasureSet_iff_exists_isCompact_measure_compl_le - /-- Finite measures that are inner regular with respect to closed compact sets are tight. -/ theorem isTightMeasureSet_singleton_of_innerRegularWRT [OpensMeasurableSpace 𝓧] [IsFiniteMeasure μ] (h : μ.InnerRegularWRT (fun s ↦ IsCompact s ∧ IsClosed s) MeasurableSet) : diff --git a/Mathlib/NumberTheory/Bernoulli.lean b/Mathlib/NumberTheory/Bernoulli.lean index 9a289e32988008..8382b79b7c72fa 100644 --- a/Mathlib/NumberTheory/Bernoulli.lean +++ b/Mathlib/NumberTheory/Bernoulli.lean @@ -193,9 +193,6 @@ theorem bernoulli'_eq_zero_of_odd {n : ℕ} (h_odd : Odd n) (hlt : 1 < n) : bern simpa [mul_assoc, sub_mul, mul_comm (evalNegHom (exp ℚ)), exp_mul_exp_neg_eq_one] congr -@[deprecated (since := "2025-12-09")] -alias bernoulli'_odd_eq_zero := bernoulli'_eq_zero_of_odd - /-- The Bernoulli numbers are defined to be `bernoulli'` with a parity sign. -/ def bernoulli (n : ℕ) : ℚ := (-1) ^ n * bernoulli' n diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index c086371b9328e5..d78798242b1b1d 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -159,12 +159,6 @@ lemma pairwise_divisorsAntidiagonalList_snd {n : ℕ} : rintro a b hab _ _ ha rfl rfl _ _ hb rfl rfl rwa [Nat.div_lt_div_left hn ⟨_, hb.symm⟩ ⟨_, ha.symm⟩] -@[deprecated (since := "2025-11-27")] alias sorted_divisorsAntidiagonalList_fst := - pairwise_divisorsAntidiagonalList_fst - -@[deprecated (since := "2025-11-27")] alias sorted_divisorsAntidiagonalList_snd := - pairwise_divisorsAntidiagonalList_snd - lemma sortedLT_map_fst_divisorsAntidiagonalList {n : ℕ} : (n.divisorsAntidiagonalList.map Prod.fst).SortedLT := (List.pairwise_map.mpr <| pairwise_divisorsAntidiagonalList_fst).sortedLT diff --git a/Mathlib/NumberTheory/ModularForms/Basic.lean b/Mathlib/NumberTheory/ModularForms/Basic.lean index adb231dd128cb8..5cc5a365590183 100644 --- a/Mathlib/NumberTheory/ModularForms/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/Basic.lean @@ -340,8 +340,6 @@ def mul {k_1 k_2 : ℤ} [Γ.HasDetPlusMinusOne] (f : ModularForm Γ k_1) (g : Mo bdd_at_cusps' hc γ hγ := by simpa [mul_slash] using! ((f.bdd_at_cusps' hc γ hγ).mul (g.bdd_at_cusps' hc γ hγ)).smul _ -@[deprecated (since := "2025-12-06")] alias mul_coe := coe_mul - /-- The constant function with value `x : ℂ` as a modular form of weight 0 and any level. -/ @[simps! -fullyApplied] def const (x : ℂ) [Γ.HasDetOne] : ModularForm Γ 0 where toSlashInvariantForm := .const x @@ -349,8 +347,6 @@ def mul {k_1 k_2 : ℤ} [Γ.HasDetPlusMinusOne] (f : ModularForm Γ k_1) (g : Mo bdd_at_cusps' hc g hg := by simpa only [coe_const, slash_def, SlashInvariantForm.toFun_eq_coe, Function.const_apply, neg_zero, zpow_zero] using! atImInfty.const_boundedAtFilter _ -@[deprecated (since := "2025-12-06")] alias const_toFun := coe_const - @[simp] lemma const_apply [Γ.HasDetOne] (x : ℂ) (τ : ℍ) : (const x : ModularForm Γ 0) τ = x := rfl @@ -361,8 +357,6 @@ lemma const_apply [Γ.HasDetOne] (x : ℂ) (τ : ℍ) : (const x : ModularForm bdd_at_cusps' hc g hg := by simpa only [coe_constℝ, slash_def, SlashInvariantForm.toFun_eq_coe, Function.const_apply, neg_zero, zpow_zero] using! atImInfty.const_boundedAtFilter _ -@[deprecated (since := "2025-12-06")] alias constℝ_toFun := coe_constℝ - @[simp] lemma constℝ_apply [Γ.HasDetPlusMinusOne] (x : ℝ) (τ : ℍ) : (constℝ x : ModularForm Γ 0) τ = x := diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean index 6f8f25272e6c3e..4d62407a28593e 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean @@ -166,11 +166,6 @@ lemma linear_isTheta_right_add (c e : ℤ) (z : ℂ) : simpa [-Int.cofinite_eq] using .inr <| tendsto_norm_comp_cofinite_atTop_of_isClosedEmbedding Int.isClosedEmbedding_coe_real -@[deprecated linear_isTheta_right_add (since := "2025-12-27")] -lemma linear_isTheta_right (c : ℤ) (z : ℂ) : - (fun (d : ℤ) ↦ (c * z + d)) =Θ[cofinite] fun n ↦ (n : ℝ) := by - simpa using linear_isTheta_right_add c 0 z - lemma linear_isTheta_left (d : ℤ) {z : ℂ} (hz : z ≠ 0) : (fun (c : ℤ) ↦ (c * z + d)) =Θ[cofinite] fun n ↦ (n : ℝ) := by apply IsTheta.add_isLittleO diff --git a/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean b/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean index 7b811a0b046993..c6e068784ff198 100644 --- a/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean +++ b/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean @@ -228,8 +228,6 @@ def const [Γ.HasDetOne] (x : ℂ) : SlashInvariantForm Γ 0 where toFun := Function.const _ x slash_action_eq' g hg := by ext; simp [slash_def, σ, Subgroup.HasDetOne.det_eq hg] -@[deprecated (since := "2025-12-06")] alias const_toFun := coe_const - /-- The `SlashInvariantForm` corresponding to `Function.const _ x`. -/ @[simps -fullyApplied] def constℝ [Γ.HasDetPlusMinusOne] (x : ℝ) : SlashInvariantForm Γ 0 where @@ -237,8 +235,6 @@ def constℝ [Γ.HasDetPlusMinusOne] (x : ℝ) : SlashInvariantForm Γ 0 where slash_action_eq' g hg := funext fun τ ↦ by simp [slash_apply, Subgroup.HasDetPlusMinusOne.abs_det hg, -Matrix.GeneralLinearGroup.val_det_apply] -@[deprecated (since := "2025-12-06")] alias constℝ_toFun := coe_constℝ - instance [Γ.HasDetPlusMinusOne] : One (SlashInvariantForm Γ 0) where one := { constℝ 1 with toFun := 1 } diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index dfc5b778061fab..aeffd5753b9329 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -629,8 +629,6 @@ theorem discr_prime_pow [IsCyclotomicExtension {p ^ k} ℚ K] : convert! ← ((IsPrimitiveRoot.powerBasis ℚ hζ).basis_eq_pow i).symm using 1 · simp_rw [algebraMap_int_eq, map_mul, map_pow, map_neg, map_one, map_natCast] -@[deprecated (since := "2025-11-24")] alias absdiscr_prime_pow := discr_prime_pow - open Nat in /-- We compute the absolute discriminant of a `p ^ (k + 1)`-th cyclotomic field. Beware that in the case `p ^ k = 2` the formula uses `1 / 2 = 0`. See also the results below. -/ @@ -640,8 +638,6 @@ theorem discr_prime_pow_succ [IsCyclotomicExtension {p ^ (k + 1)} ℚ K] : (-1) ^ (p ^ k * (p - 1) / 2) * p ^ (p ^ k * ((p - 1) * (k + 1) - 1)) := by simpa [totient_prime_pow hp.out (succ_pos k)] using discr_prime_pow p (k + 1) K -@[deprecated (since := "2025-11-19")] alias absdiscr_prime_pow_succ := discr_prime_pow_succ - /-- We compute the absolute discriminant of a `p`-th cyclotomic field where `p` is prime. -/ theorem discr_prime [IsCyclotomicExtension {p} ℚ K] : haveI : NumberField K := IsCyclotomicExtension.numberField {p} ℚ K @@ -652,8 +648,6 @@ theorem discr_prime [IsCyclotomicExtension {p} ℚ K] : rw [discr_prime_pow_succ p 0 K] simp [Nat.sub_sub] -@[deprecated (since := "2025-11-19")] alias absdiscr_prime := discr_prime - variable (n) [hn : NeZero n] set_option backward.isDefEq.respectTransparency false in @@ -844,9 +838,6 @@ instance _root_.IsCyclotomicExtension.ringOfIntegers [IsCyclotomicExtension {n} let _ := (zeta_spec n ℚ K).adjoin_isCyclotomicExtension ℤ IsCyclotomicExtension.equiv _ ℤ _ (zeta_spec n ℚ K).adjoinEquivRingOfIntegers -@[deprecated (since := "2025-11-26")] alias _root_.IsCyclotomicExtension.ring_of_integers' := - _root_.IsCyclotomicExtension.ringOfIntegers - /-- The integral `PowerBasis` of `𝓞 K` given by a primitive root of unity, where `K` is an `n`-th cyclotomic extension of `ℚ`. -/ noncomputable def integralPowerBasis [IsCyclotomicExtension {n} ℚ K] @@ -882,17 +873,6 @@ theorem subOneIntegralPowerBasis_gen [IsCyclotomicExtension {n} ℚ K] ⟨ζ - 1, Subalgebra.sub_mem _ (hζ.isIntegral (NeZero.pos _)) (Subalgebra.one_mem _)⟩ := by simp [subOneIntegralPowerBasis] -@[deprecated (since := "2025-11-26")] alias integralPowerBasis' := integralPowerBasis -@[deprecated (since := "2025-11-26")] alias integralPowerBasis'_gen := integralPowerBasis_gen -@[deprecated (since := "2025-11-26")] alias power_basis_int'_dim := integralPowerBasis_dim -@[deprecated (since := "2025-11-26")] alias subOneIntegralPowerBasis' := subOneIntegralPowerBasis -@[deprecated (since := "2025-11-26")] alias subOneIntegralPowerBasis'_gen := - subOneIntegralPowerBasis_gen -@[deprecated (since := "2025-11-26")] alias subOneIntegralPowerBasis'_gen_prime := - subOneIntegralPowerBasis_gen -@[deprecated (since := "2025-11-26")] alias subOneIntegralPowerBasis_gen_prime := - subOneIntegralPowerBasis_gen - end IsPrimitiveRoot end discr diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index d0cfae01b281aa..32b1942b836d64 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -279,9 +279,6 @@ theorem ramificationIdxIn_eq_of_prime : rw [← pow_one p] at hK rw [ramificationIdxIn_eq_of_prime_pow p 0, pow_zero, one_mul] -@[deprecated (since := "2025-12-03")] alias ramificationIdxIn_of_prime := - ramificationIdxIn_eq_of_prime - end Prime section notDvd @@ -310,9 +307,6 @@ theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : ← (zeta_spec m ℚ K).coe_toInteger, ← RingOfIntegers.minpoly_coe ζ] simp [ζ] -@[deprecated (since := "2025-12-10")] -alias inertiaDeg_of_not_dvd := inertiaDeg_eq_of_not_dvd - theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : ramificationIdx P ℤ = 1 := by let ζ := (zeta_spec m ℚ K).toInteger @@ -332,9 +326,6 @@ theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : · rw [ENat.coe_one] exact Order.one_le_iff_pos.mpr <| emultiplicity_pos_of_dvd h₂.2.2 -@[deprecated (since := "2025-12-10")] -alias ramificationIdx_of_not_dvd := ramificationIdx_eq_of_not_dvd - theorem inertiaDegIn_eq_of_not_dvd (hm : ¬ p ∣ m) : 𝒑.inertiaDegIn (𝓞 K) = orderOf (p : ZMod m) := by have : IsGalois ℚ K := isGalois {m} ℚ K @@ -347,10 +338,6 @@ theorem ramificationIdxIn_eq_of_not_dvd (hm : ¬ p ∣ m) : obtain ⟨⟨P, _, _⟩⟩ := 𝒑.nonempty_primesOver (S := 𝓞 K) rw [ramificationIdxIn_eq_ramificationIdx 𝒑 P Gal(K/ℚ), ramificationIdx_eq_of_not_dvd p K P hm] -@[deprecated (since := "2025-12-03")] alias inertiaDegIn_of_not_dvd := inertiaDegIn_eq_of_not_dvd -@[deprecated (since := "2025-12-03")] alias ramificationIdxIn_of_not_dvd := - ramificationIdxIn_eq_of_not_dvd - end notDvd section general diff --git a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean index a79a385487f13c..cc10d171d392fa 100644 --- a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean +++ b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean @@ -76,8 +76,6 @@ isomorphic to `ℤ`. -/ noncomputable def Rat.IsIntegralClosure.intEquiv : R ≃+* ℤ := (NumberField.RingOfIntegers.equiv R).symm.trans ringOfIntegersEquiv -@[deprecated (since := "2025-12-22")] alias Rat.intEquiv := Rat.IsIntegralClosure.intEquiv - @[simp] theorem Rat.IsIntegralClosure.intEquiv_apply_eq_ringOfIntegersEquiv (x : 𝓞 ℚ) : intEquiv (𝓞 ℚ) x = ringOfIntegersEquiv x := by diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index 626c404ca544a2..af99908a4d15f6 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -692,11 +692,6 @@ instance {α} [CompleteAtomicBooleanAlgebra α] : IsAtomistic α := instance {α} [CompleteAtomicBooleanAlgebra α] : IsCoatomistic α := isAtomistic_dual_iff_isCoatomistic.1 inferInstance -@[deprecated "Use `IsAtom.le_sSup` instead" (since := "2025-11-24")] -theorem exists_mem_le_of_le_sSup_of_isAtom {α} [CompleteAtomicBooleanAlgebra α] {a} - (ha : IsAtom a) {s : Set α} (hs : a ≤ sSup s) : ∃ b ∈ s, a ≤ b := - (IsAtom.le_sSup ha).mp hs - lemma eq_setOf_le_sSup_and_isAtom {α} [CompleteAtomicBooleanAlgebra α] {S : Set α} (hS : ∀ a ∈ S, IsAtom a) : S = {a | a ≤ sSup S ∧ IsAtom a} := by ext a diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 250c217378841a..8d2b62def97f62 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -74,12 +74,6 @@ variable [LE α] {a b c : α} @[to_dual self] protected lemma LE.le.ge (h : a ≤ b) : b ≥ a := h @[to_dual self] protected lemma GE.ge.le (h : a ≥ b) : b ≤ a := h -@[deprecated le_of_eq_of_le (since := "2025-11-29")] -theorem le_of_le_of_eq' : b ≤ c → a = b → a ≤ c := flip le_of_eq_of_le - -@[deprecated le_of_le_of_eq (since := "2025-11-29")] -theorem le_of_eq_of_le' : b = c → a ≤ b → a ≤ c := flip le_of_le_of_eq - @[to_dual trans_eq'] alias LE.le.trans_eq := le_of_le_of_eq @[to_dual trans_ge] alias Eq.trans_le := le_of_eq_of_le @@ -92,12 +86,6 @@ variable [LT α] {a b c : α} @[to_dual self] protected lemma LT.lt.gt (h : a < b) : b > a := h @[to_dual self] protected lemma GT.gt.lt (h : a > b) : b < a := h -@[deprecated lt_of_eq_of_lt (since := "2025-11-29")] -theorem lt_of_lt_of_eq' : b < c → a = b → a < c := flip lt_of_eq_of_lt - -@[deprecated lt_of_lt_of_eq (since := "2025-11-29")] -theorem lt_of_eq_of_lt' : b = c → a < b → a < c := flip lt_of_lt_of_eq - @[to_dual trans_eq'] alias LT.lt.trans_eq := lt_of_lt_of_eq @[to_dual trans_gt] alias Eq.trans_lt := lt_of_eq_of_lt diff --git a/Mathlib/Order/BoundedOrder/Basic.lean b/Mathlib/Order/BoundedOrder/Basic.lean index feb773fd46f647..c2a53f60429ece 100644 --- a/Mathlib/Order/BoundedOrder/Basic.lean +++ b/Mathlib/Order/BoundedOrder/Basic.lean @@ -246,16 +246,6 @@ instance [LE α] [h : OrderBot α] : OrderTop αᵒᵈ where end OrderDual -section OrderBot - -variable [PartialOrder α] [OrderBot α] [Preorder β] {a b : α} - -@[deprecated not_bot_lt_iff (since := "2025-12-03")] -theorem eq_bot_of_minimal (h : ∀ b, ¬b < a) : a = ⊥ := - (eq_bot_or_bot_lt a).resolve_right (h ⊥) - -end OrderBot - /-! ### Bounded order -/ diff --git a/Mathlib/Order/Category/FinPartOrd.lean b/Mathlib/Order/Category/FinPartOrd.lean index f8c5819bbff339..f44f1fe62bf255 100644 --- a/Mathlib/Order/Category/FinPartOrd.lean +++ b/Mathlib/Order/Category/FinPartOrd.lean @@ -71,8 +71,6 @@ abbrev ofHom {X Y : Type u} [PartialOrder X] [Fintype X] [PartialOrder Y] [Finty @[simp] lemma hom_hom_id {X : FinPartOrd} : (𝟙 X : X ⟶ X).hom.hom = OrderHom.id := rfl -@[deprecated (since := "2025-12-18")] alias hom_id := hom_hom_id - /- Provided for rewriting. -/ lemma id_apply (X : FinPartOrd) (x : X) : (𝟙 X : X ⟶ X) x = x := by simp @@ -81,8 +79,6 @@ lemma id_apply (X : FinPartOrd) (x : X) : lemma hom_hom_comp {X Y Z : FinPartOrd} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).hom.hom = g.hom.hom.comp f.hom.hom := rfl -@[deprecated (since := "2025-12-18")] alias hom_comp := hom_hom_comp - /- Provided for rewriting. -/ lemma comp_apply {X Y Z : FinPartOrd} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : (f ≫ g) x = g (f x) := by simp @@ -96,14 +92,10 @@ lemma hom_hom_ofHom {X Y : Type u} [PartialOrder X] [Fintype X] [PartialOrder Y] (f : X →o Y) : (ofHom f).hom.hom = f := rfl -@[deprecated (since := "2025-12-18")] alias hom_ofHom := hom_hom_ofHom - @[simp] lemma ofHom_hom_hom {X Y : FinPartOrd} (f : X ⟶ Y) : ofHom f.hom.hom = f := rfl -@[deprecated (since := "2025-12-18")] alias ofHom_hom := ofHom_hom_hom - /-- Constructs an isomorphism of finite partial orders from an order isomorphism between them. -/ @[simps] def Iso.mk {α β : FinPartOrd.{u}} (e : α ≃o β) : α ≅ β where diff --git a/Mathlib/Order/Category/NonemptyFinLinOrd.lean b/Mathlib/Order/Category/NonemptyFinLinOrd.lean index da4a9663edfb35..6b06b384126d25 100644 --- a/Mathlib/Order/Category/NonemptyFinLinOrd.lean +++ b/Mathlib/Order/Category/NonemptyFinLinOrd.lean @@ -66,8 +66,6 @@ abbrev ofHom {X Y : Type u} [Nonempty X] [LinearOrder X] [Fintype X] @[simp] lemma hom_hom_id {X : NonemptyFinLinOrd} : (𝟙 X : X ⟶ X).hom.hom = OrderHom.id := rfl -@[deprecated (since := "2025-12-18")] alias hom_id := hom_hom_id - /- Provided for rewriting. -/ lemma id_apply (X : NonemptyFinLinOrd) (x : X) : (𝟙 X : X ⟶ X) x = x := by simp @@ -76,8 +74,6 @@ lemma id_apply (X : NonemptyFinLinOrd) (x : X) : lemma hom_hom_comp {X Y Z : NonemptyFinLinOrd} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).hom.hom = g.hom.hom.comp f.hom.hom := rfl -@[deprecated (since := "2025-12-18")] alias hom_comp := hom_hom_comp - /- Provided for rewriting. -/ lemma comp_apply {X Y Z : NonemptyFinLinOrd} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : (f ≫ g) x = g (f x) := by simp @@ -91,8 +87,6 @@ lemma hom_hom_ofHom {X Y : Type u} [Nonempty X] [LinearOrder X] [Fintype X] [Non [LinearOrder Y] [Fintype Y] (f : X →o Y) : (ofHom f).hom.hom = f := rfl -@[deprecated (since := "2025-12-18")] alias hom_ofHom := hom_hom_ofHom - @[simp] lemma ofHom_hom {X Y : NonemptyFinLinOrd} (f : X ⟶ Y) : ofHom f.hom.hom = f := rfl diff --git a/Mathlib/Order/CompleteLattice/MulticoequalizerDiagram.lean b/Mathlib/Order/CompleteLattice/MulticoequalizerDiagram.lean index 7d6dee0e57b357..1dc48d4a8fd2c2 100644 --- a/Mathlib/Order/CompleteLattice/MulticoequalizerDiagram.lean +++ b/Mathlib/Order/CompleteLattice/MulticoequalizerDiagram.lean @@ -57,9 +57,6 @@ attribute [grind cases] BicartSq namespace BicartSq -@[deprecated (since := "2025-11-26")] alias max_eq := sup_eq -@[deprecated (since := "2025-11-26")] alias min_eq := inf_eq - variable {x₁ x₂ x₃ x₄} (sq : BicartSq x₁ x₂ x₃ x₄) include sq @@ -90,8 +87,6 @@ structure MulticoequalizerDiagram : Prop where namespace MulticoequalizerDiagram -@[deprecated (since := "2025-11-26")] alias min_eq := eq_inf - attribute [local grind] MulticoequalizerDiagram attribute [local grind =] MultispanShape.prod_fst MultispanShape.prod_snd diff --git a/Mathlib/Order/Defs/Unbundled.lean b/Mathlib/Order/Defs/Unbundled.lean index ace9616160bde2..6515efb649d119 100644 --- a/Mathlib/Order/Defs/Unbundled.lean +++ b/Mathlib/Order/Defs/Unbundled.lean @@ -22,9 +22,6 @@ and proves some basic lemmas about them. /-! ### Unbundled classes -/ -/-- An empty relation does not relate any elements. -/ -@[deprecated (since := "2025-12-22")] alias EmptyRelation := emptyRelation - /-- `IsIrrefl X r` means the binary relation `r` on `X` is irreflexive (that is, `r x x` never holds). -/ @[deprecated Std.Irrefl (since := "2026-01-07")] @@ -34,10 +31,6 @@ abbrev IsIrrefl (α : Sort*) (r : α → α → Prop) : Prop := Std.Irrefl r @[deprecated Std.Refl (since := "2026-01-08")] abbrev IsRefl (α : Sort*) (r : α → α → Prop) : Prop := Std.Refl r -/-- `IsSymm X r` means the binary relation `r` on `X` is symmetric. -/ -@[deprecated Std.Symm (since := "2025-12-26")] -abbrev IsSymm (α : Sort*) (r : α → α → Prop) : Prop := Std.Symm r - /-- `IsAsymm X r` means that the binary relation `r` on `X` is asymmetric, that is, `r a b → ¬ r b a`. -/ @[deprecated Std.Asymm (since := "2026-01-03")] diff --git a/Mathlib/Order/Interval/Set/Basic.lean b/Mathlib/Order/Interval/Set/Basic.lean index ac1b1ac2111dd1..5af8734f820976 100644 --- a/Mathlib/Order/Interval/Set/Basic.lean +++ b/Mathlib/Order/Interval/Set/Basic.lean @@ -84,27 +84,9 @@ theorem left_notMem_Ioo : a ∉ Ioo a b := by simp @[to_dual right_notMem_Ico] theorem left_notMem_Ioc : a ∉ Ioc a b := by simp -@[deprecated left_notMem_Ioo (since := "2025-12-26")] -theorem left_mem_Ioo : a ∈ Ioo a b ↔ False := by simp - -@[deprecated left_notMem_Ioc (since := "2025-12-26")] -theorem left_mem_Ioc : a ∈ Ioc a b ↔ False := by simp - @[to_dual right_mem_Ioc] theorem left_mem_Ico : a ∈ Ico a b ↔ a < b := by simp @[to_dual right_mem_Icc] theorem left_mem_Icc : a ∈ Icc a b ↔ a ≤ b := by simp -@[deprecated (since := "2025-12-26")] -alias left_mem_Ici := self_mem_Ici - -@[deprecated right_notMem_Ioo (since := "2025-12-26")] -theorem right_mem_Ioo : b ∈ Ioo a b ↔ False := by simp - -@[deprecated right_notMem_Ico (since := "2025-12-26")] -theorem right_mem_Ico : b ∈ Ico a b ↔ False := by simp - -@[deprecated (since := "2025-12-26")] -alias right_mem_Iic := self_mem_Iic - @[to_dual (attr := simp)] theorem Iio_toDual : Iio (toDual a) = ofDual ⁻¹' Ioi a := rfl diff --git a/Mathlib/Order/Monotone/Defs.lean b/Mathlib/Order/Monotone/Defs.lean index 76e1afbe8215dc..42f482df67ff03 100644 --- a/Mathlib/Order/Monotone/Defs.lean +++ b/Mathlib/Order/Monotone/Defs.lean @@ -347,18 +347,10 @@ theorem Function.Injective.of_lt_imp_ne [LinearOrder α] {f : α → β} (h : Injective f := by grind [Injective] -@[deprecated (since := "2025-12-23")] -alias injective_of_lt_imp_ne := Function.Injective.of_lt_imp_ne - theorem Function.Injective.of_eq_imp_le [PartialOrder α] {f : α → β} (h : ∀ {x y}, f x = f y → x ≤ y) : f.Injective := fun _ _ hxy ↦ h hxy |>.antisymm <| h hxy.symm -@[deprecated Injective.of_eq_imp_le (since := "2025-12-23")] -theorem injective_of_le_imp_le [PartialOrder α] [Preorder β] (f : α → β) - (h : ∀ {x y}, f x ≤ f y → x ≤ y) : Injective f := - .of_eq_imp_le (h ·.le) - /-! ### Monotonicity under composition -/ diff --git a/Mathlib/Order/PiLex.lean b/Mathlib/Order/PiLex.lean index c4300651ca5b6d..225f65c937542d 100644 --- a/Mathlib/Order/PiLex.lean +++ b/Mathlib/Order/PiLex.lean @@ -106,16 +106,10 @@ theorem Lex.lt_iff_of_unique [Unique ι] [∀ i, LT (β i)] [Preorder ι] {x y : x < y ↔ x default < y default := lex_iff_of_unique -@[deprecated (since := "2025-11-29")] -alias lex_lt_iff_of_unique := Lex.lt_iff_of_unique - theorem Colex.lt_iff_of_unique [Unique ι] [∀ i, LT (β i)] [Preorder ι] {x y : Colex (∀ i, β i)} : x < y ↔ x default < y default := lex_iff_of_unique -@[deprecated (since := "2025-11-29")] -alias colex_lt_iff_of_unique := Colex.lt_iff_of_unique - instance Lex.isStrictOrder [LinearOrder ι] [∀ a, PartialOrder (β a)] : IsStrictOrder (Lex (∀ i, β i)) (· < ·) where irrefl := fun a ⟨k, _, hk₂⟩ => lt_irrefl (a k) hk₂ diff --git a/Mathlib/Order/RelSeries.lean b/Mathlib/Order/RelSeries.lean index e47695bfec369b..8feefa3b54c09a 100644 --- a/Mathlib/Order/RelSeries.lean +++ b/Mathlib/Order/RelSeries.lean @@ -255,14 +255,6 @@ lemma toList_getElem (p : RelSeries r) {i : ℕ} (hi : i < p.toList.length) : p.toList[(i : ℕ)] = p ⟨i, by simpa using hi⟩ := by simp only [toList, List.getElem_ofFn] -@[deprecated toList_getElem (since := "2025-11-25")] -lemma toList_getElem_eq_apply (p : RelSeries r) (i : Fin (p.length + 1)) : - p.toList[(i : ℕ)] = p i := p.toList_getElem _ - -@[deprecated toList_getElem (since := "2025-11-25")] -lemma toList_getElem_eq_apply_of_lt_length {p : RelSeries r} {i : ℕ} (hi : i < p.length + 1) : - p.toList[i]'(by simpa using hi) = p ⟨i, hi⟩ := p.toList_getElem _ - lemma toList_getElem_zero_eq_head (p : RelSeries r) : p.toList[0] = p.head := p.toList_getElem _ diff --git a/Mathlib/Order/SetAccumulate.lean b/Mathlib/Order/SetAccumulate.lean index c06377ea68a96a..b4094f35daac20 100644 --- a/Mathlib/Order/SetAccumulate.lean +++ b/Mathlib/Order/SetAccumulate.lean @@ -30,8 +30,6 @@ namespace Set def accumulate [LE α] (s : α → Set β) (x : α) : Set β := ⋃ y ≤ x, s y -@[deprecated (since := "2025-12-14")] alias Accumulate := accumulate - theorem accumulate_def [LE α] {x : α} : accumulate s x = ⋃ y ≤ x, s y := rfl diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 8318ad5a29c0ab..0a973b0fb5742a 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -352,9 +352,6 @@ theorem le_succ_and_le_iff : b ≤ succ a ∧ a ≤ b ↔ b = a ∨ b = succ a : rw [and_comm] exact le_and_le_succ_iff -@[deprecated (since := "2025-12-04")] -alias le_le_succ_iff := le_and_le_succ_iff - /-- See also `Order.le_succ_of_wcovBy`. -/ @[to_dual /-- See also `Order.pred_le_of_wcovBy`. -/] lemma succ_eq_of_covBy (h : a ⋖ b) : succ a = b := (succ_le_of_lt h.lt).antisymm h.wcovBy.le_succ @@ -633,13 +630,6 @@ variable [Preorder α] [PredOrder α] {a b : α} -- TODO: auto-generate all of these through `to_dual` -@[deprecated pred_lt_of_le_of_not_isMin (since := "2025-12-04")] -theorem pred_lt_of_not_isMin_of_le (ha : ¬IsMin a) : a ≤ b → pred a < b := - (pred_lt_of_not_isMin ha).trans_le - -@[deprecated (since := "2025-12-04")] -alias pred_le_pred_of_not_isMin_of_le := pred_mono - @[to_dual existing] theorem isMin_iterate_pred_of_eq_of_lt {n m : ℕ} (h_eq : pred^[n] a = pred^[m] a) (h_lt : n < m) : IsMin (pred^[n] a) := @@ -650,14 +640,8 @@ theorem isMin_iterate_pred_of_eq_of_ne {n m : ℕ} (h_eq : pred^[n] a = pred^[m] (h_ne : n ≠ m) : IsMin (pred^[n] a) := @isMax_iterate_succ_of_eq_of_ne αᵒᵈ _ _ _ _ _ h_eq h_ne -@[deprecated (since := "2025-12-04")] -alias pred_le_pred_of_le := pred_mono - end Preorder -@[deprecated le_and_pred_le_iff (since := "2025-12-04")] -alias pred_le_le_iff := pred_le_and_le_iff - /-! ### Successor-predecessor orders -/ section SuccPredOrder diff --git a/Mathlib/Order/SuccPred/Limit.lean b/Mathlib/Order/SuccPred/Limit.lean index e7269ec2a418fa..1a90f86fa04ee4 100644 --- a/Mathlib/Order/SuccPred/Limit.lean +++ b/Mathlib/Order/SuccPred/Limit.lean @@ -376,9 +376,6 @@ theorem isMin_or_mem_range_succ_or_isSuccLimit (a) : theorem isSuccPrelimit_of_succ_lt (H : ∀ a < b, succ a < b) : IsSuccPrelimit b := fun a hab ↦ (H a hab.lt).ne hab.succ_eq -@[deprecated (since := "2025-12-20")] -alias isPredPrelimit_of_pred_lt := isPredPrelimit_of_lt_pred - @[to_dual lt_pred] theorem IsSuccPrelimit.succ_lt (hb : IsSuccPrelimit b) (ha : a < b) : succ a < b := by by_cases h : IsMax a diff --git a/Mathlib/Order/WithBot.lean b/Mathlib/Order/WithBot.lean index 0e18c399398b22..330fe865bdd45f 100644 --- a/Mathlib/Order/WithBot.lean +++ b/Mathlib/Order/WithBot.lean @@ -440,9 +440,6 @@ lemma unbot_le_unbot_iff (hx : x ≠ ⊥) (hy : y ≠ ⊥) : x.unbot hx ≤ y.un @[to_dual] alias ⟨_, unbot_mono⟩ := unbot_le_unbot_iff -@[deprecated (since := "2025-12-05")] -alias unbot_le_unbot := unbot_le_unbot_iff - @[to_dual untopD_le_iff] lemma le_unbotD_iff (hx : x ≠ ⊥) : b ≤ x.unbotD a ↔ b ≤ x := by lift x to α using hx; simp @[to_dual le_untopD_iff] @@ -500,9 +497,6 @@ lemma unbot_lt_iff (hx : x ≠ ⊥) : unbot x hx < b ↔ x < b := by lift x to @[to_dual (reorder := hx hy)] lemma unbot_lt_unbot_iff (hx hy) : unbot x hx < unbot y hy ↔ x < y := by simp -@[deprecated (since := "2025-12-05")] -alias unbot_lt_unbot := unbot_lt_unbot_iff - @[to_dual untopD_lt_iff] lemma lt_unbotD_iff (hx : x ≠ ⊥) : b < x.unbotD a ↔ b < x := by lift x to α using hx; simp @[to_dual lt_untopD_iff] @@ -897,33 +891,15 @@ protected def ofDual : WithBot αᵒᵈ ≃ WithTop α := @[to_dual (attr := simp)] theorem toDual_symm : WithBot.toDual.symm = WithTop.ofDual (α := α) := rfl -@[to_dual] -theorem toDual_symm_apply (a : WithTop αᵒᵈ) : WithBot.toDual.symm a = WithTop.ofDual a := rfl - -attribute [deprecated toDual_symm (since := "2025-12-30")] toDual_symm_apply -attribute [deprecated WithTop.toDual_symm (since := "2025-12-30")] WithTop.toDual_symm_apply - @[to_dual (attr := simp)] theorem ofDual_symm : WithBot.ofDual.symm = WithTop.toDual (α := α) := rfl -@[to_dual] -theorem ofDual_symm_apply (a : WithTop α) : WithBot.ofDual.symm a = WithTop.toDual a := rfl - -attribute [deprecated ofDual_symm (since := "2025-12-30")] ofDual_symm_apply -attribute [deprecated WithTop.ofDual_symm (since := "2025-12-30")] WithTop.ofDual_symm_apply - @[to_dual (attr := simp)] theorem toDual_bot : WithBot.toDual (⊥ : WithBot α) = ⊤ := rfl -@[deprecated (since := "2025-12-30")] alias toDual_apply_bot := toDual_bot -@[deprecated (since := "2025-12-30")] alias _root_.WithTop.toDual_apply_top := WithTop.toDual_top - @[to_dual (attr := simp)] theorem ofDual_bot : WithBot.ofDual (⊥ : WithBot αᵒᵈ) = ⊤ := rfl -@[deprecated (since := "2025-12-30")] alias ofDual_apply_bot := ofDual_bot -@[deprecated (since := "2025-12-30")] alias _root_.WithTop.ofDual_apply_top := WithTop.ofDual_top - open OrderDual @[to_dual (attr := simp)] diff --git a/Mathlib/Probability/Moments/Covariance.lean b/Mathlib/Probability/Moments/Covariance.lean index 049fc788fa1d84..fca6592f15e0f3 100644 --- a/Mathlib/Probability/Moments/Covariance.lean +++ b/Mathlib/Probability/Moments/Covariance.lean @@ -153,9 +153,6 @@ lemma covariance_fun_div_right (c : ℝ) : cov[X, fun ω ↦ Y ω / c; μ] = cov[X, Y; μ] / c := by simp_rw [← inv_mul_eq_div, covariance_const_mul_right] -@[deprecated (since := "2025-11-29")] alias covariance_mul_left := covariance_const_mul_left -@[deprecated (since := "2025-11-29")] alias covariance_mul_right := covariance_const_mul_right - @[simp] lemma covariance_neg_left : cov[-X, Y; μ] = -cov[X, Y; μ] := by calc cov[-X, Y; μ] diff --git a/Mathlib/Probability/Moments/Variance.lean b/Mathlib/Probability/Moments/Variance.lean index c5b09a75a54bd2..b04e1139a3eff3 100644 --- a/Mathlib/Probability/Moments/Variance.lean +++ b/Mathlib/Probability/Moments/Variance.lean @@ -211,8 +211,6 @@ theorem variance_mul_const (c : ℝ) (X : Ω → ℝ) (μ : Measure Ω) : variance (fun ω => X ω * c) μ = variance X μ * c ^ 2 := by simp [mul_comm, variance_const_mul] -@[deprecated (since := "2025-11-29")] alias variance_mul := variance_const_mul - theorem variance_smul (c : ℝ) (X : Ω → ℝ) (μ : Measure Ω) : variance (c • X) μ = c ^ 2 * variance X μ := variance_const_mul c X μ diff --git a/Mathlib/RepresentationTheory/FDRep.lean b/Mathlib/RepresentationTheory/FDRep.lean index 2948477a662e19..96c79b0a647ff9 100644 --- a/Mathlib/RepresentationTheory/FDRep.lean +++ b/Mathlib/RepresentationTheory/FDRep.lean @@ -103,8 +103,6 @@ lemma endRingEquiv_comp_ρ (V : FDRep R G) : @[simp] lemma hom_hom_action_ρ (V : FDRep R G) (g : G) : (Action.ρ V g).hom.hom = (ρ V g) := rfl -@[deprecated (since := "2025-12-18")] alias hom_action_ρ := hom_hom_action_ρ - /-- The underlying `LinearEquiv` of an isomorphism of representations. -/ def isoToLinearEquiv {V W : FDRep R G} (i : V ≅ W) : V ≃ₗ[R] W := FGModuleCat.isoToLinearEquiv ((Action.forget (FGModuleCat R) G).mapIso i) diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean index f7db8e10cb5783..69f6b38f9a14bf 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Functoriality.lean @@ -346,9 +346,6 @@ theorem mapCocycles₁_one (φ : res 1 A ⟶ B) : refine ModuleCat.hom_ext (LinearMap.ext fun _ ↦ funext fun y => ?_) simp [mapShortComplexH1, shortComplexH1, Pi.zero_apply y] -@[deprecated (since := "2025-6-09")] -alias H1Map_id := map_id - set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp), elementwise (attr := simp)] lemma H1π_comp_map : diff --git a/Mathlib/RingTheory/AlgebraTower.lean b/Mathlib/RingTheory/AlgebraTower.lean index c26e7a0f00c837..782738cd65f9a0 100644 --- a/Mathlib/RingTheory/AlgebraTower.lean +++ b/Mathlib/RingTheory/AlgebraTower.lean @@ -71,9 +71,6 @@ then a basis for `M` as `R`-module is also a basis for `M` as `R'`-module. -/ noncomputable def algebraMapCoeffs : Basis ι A M := b.mapCoeffs (RingEquiv.ofBijective _ h) fun c x => by simp -@[deprecated (since := "2025-12-15")] -alias algebraMapCoeffs_repr_apply_toFun := algebraMapCoeffs_repr_apply_apply - @[simp] theorem algebraMapCoeffs_repr (m : M) : (b.algebraMapCoeffs A h).repr m = (b.repr m).mapRange (algebraMap R A) (map_zero _) := by diff --git a/Mathlib/RingTheory/DividedPowers/Padic.lean b/Mathlib/RingTheory/DividedPowers/Padic.lean index 3c5c3bd9f30b60..5b243cdcfd5d1c 100644 --- a/Mathlib/RingTheory/DividedPowers/Padic.lean +++ b/Mathlib/RingTheory/DividedPowers/Padic.lean @@ -71,9 +71,6 @@ noncomputable def DividedPowers.ofInjective (f : A →+* B) (hf : Injective f) · rw [dif_pos hx] exact (Exists.choose_spec (hmem m hx)).1 hm -@[deprecated (since := "2025-12-09")] -alias PadicInt.dividedPowers_of_injective := DividedPowers.ofInjective - end Injective namespace PadicInt diff --git a/Mathlib/RingTheory/Etale/Basic.lean b/Mathlib/RingTheory/Etale/Basic.lean index e13202a840d204..a871c5bde780f1 100644 --- a/Mathlib/RingTheory/Etale/Basic.lean +++ b/Mathlib/RingTheory/Etale/Basic.lean @@ -130,10 +130,6 @@ lemma _root_.Algebra.FormallySmooth.iff_restrictScalars [FormallyEtale R A] : Algebra.FormallySmooth R B ↔ Algebra.FormallySmooth A B := ⟨fun _ ↦ .of_restrictScalars R _ _, fun _ ↦ .comp _ A _⟩ -set_option linter.dupNamespace false in -@[deprecated (since := "2025-12-09")] -alias Algebra.FormallyEtale.of_restrictScalars := of_restrictScalars - end Comp lemma iff_of_surjective @@ -143,10 +139,6 @@ lemma iff_of_surjective rw [FormallyEtale.iff_formallyUnramified_and_formallySmooth, ← FormallySmooth.iff_of_surjective h, and_iff_right (FormallyUnramified.of_surjective (Algebra.ofId R S) h)] -set_option linter.dupNamespace false in -@[deprecated (since := "2025-12-09")] -alias Algebra.FormallyEtale.iff_of_surjective := iff_of_surjective - section BaseChange open scoped TensorProduct diff --git a/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean b/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean index d304770bc068e5..fb7569ae240790 100644 --- a/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean +++ b/Mathlib/RingTheory/Flat/FaithfullyFlat/Algebra.lean @@ -56,9 +56,6 @@ lemma Module.FaithfullyFlat.of_comap_surjective [Flat A B] exact (Submodule.restrictScalars_eq_top_iff _ _ _).ne.mpr fun top ↦ m'.isPrime.ne_top <| top_le_iff.mp <| top ▸ Ideal.map_comap_le -@[deprecated (since := "2025-12-10")] -alias Module.FaithfullyFlat.of_specComap_surjective := Module.FaithfullyFlat.of_comap_surjective - /-- If `A` is local and `B` is a local and flat `A`-algebra, then `B` is faithfully flat. -/ lemma Module.FaithfullyFlat.of_flat_of_isLocalHom [IsLocalRing A] [IsLocalRing B] [Flat A B] [IsLocalHom (algebraMap A B)] : Module.FaithfullyFlat A B := by @@ -151,10 +148,6 @@ lemma PrimeSpectrum.comap_surjective_of_faithfullyFlat : (PrimeSpectrum.mem_range_comap_iff (algebraMap A B)).mpr I.asIdeal.comap_map_eq_self_of_faithfullyFlat -@[deprecated (since := "2025-12-10")] -alias PrimeSpectrum.specComap_surjective_of_faithfullyFlat := - PrimeSpectrum.comap_surjective_of_faithfullyFlat - section IsLocalRing variable (A B) diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index 42f8cb6ea4ff47..badf6fc2ae41d1 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -375,10 +375,6 @@ theorem coeff_order_eq_zero {x : R⟦Γ⟧} : x.coeff x.order = 0 ↔ x = 0 := b rw [order_of_ne hx] exact x.isWF_support.min_mem (support_nonempty_iff.2 hx) -@[deprecated coeff_order_eq_zero (since := "2025-12-09")] -theorem coeff_order_ne_zero {x : R⟦Γ⟧} (hx : x ≠ 0) : x.coeff x.order ≠ 0 := - coeff_order_eq_zero.not.2 hx - theorem order_le_of_coeff_ne_zero {Γ} [Zero Γ] [LinearOrder Γ] {x : R⟦Γ⟧} {g : Γ} (h : x.coeff g ≠ 0) : x.order ≤ g := le_trans (le_of_eq (order_of_ne (ne_zero_of_coeff_ne_zero h))) diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 08754b5adb0d16..29d9385e622d66 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -497,9 +497,6 @@ theorem support_mul_subset [NonUnitalNonAssocSemiring R] {x y : R⟦Γ⟧} : rw [← of_symm_smul_of_eq_mul, ← vadd_eq_add] exact HahnModule.support_smul_subset_vadd_support -@[deprecated (since := "2025-12-09")] -alias support_mul_subset_add_support := support_mul_subset - instance [NonUnitalNonAssocSemiring R] : NonUnitalNonAssocSemiring R⟦Γ⟧ where zero_mul _ := by ext diff --git a/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean b/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean index abbeef599d2cc3..068ce13791c006 100644 --- a/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean +++ b/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean @@ -107,9 +107,6 @@ variable {I J M} {M' : Type*} [AddCommMonoid M'] [Module R M'] (f : M →ₗ[R] theorem AssociatedPrimes.mem_iff : I ∈ associatedPrimes R M ↔ IsAssociatedPrime I M := Iff.rfl -@[deprecated (since := "2025-11-24")] -alias AssociatePrimes.mem_iff := AssociatedPrimes.mem_iff - theorem IsAssociatedPrime.isPrime (h : IsAssociatedPrime I M) : I.IsPrime := h.1 instance (I : associatedPrimes R M) : I.1.IsPrime := I.2.1 diff --git a/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean b/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean index 91c6a9966c74c6..1c528dcb354863 100644 --- a/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean +++ b/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean @@ -75,10 +75,6 @@ lemma mem_associatedPrimes_atPrime_of_mem_associatedPrimes p.primeCompl (LocalizedModule.mkLinearMap p.primeCompl M) simpa [Localization.AtPrime.under_maximalIdeal] using ass -@[deprecated (since := "2025-11-27")] -alias mem_associatePrimes_localizedModule_atPrime_of_mem_associated_primes := - mem_associatedPrimes_atPrime_of_mem_associatedPrimes - include S f in @[stacks 0310 "(2)"] lemma comap_mem_associatedPrimes_of_mem_associatedPrimes_of_isLocalizedModule_of_fg (p : Ideal R') diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean index cb77bd69707339..93c620109dc6f4 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean @@ -195,9 +195,6 @@ noncomputable def PrimeSpectrum.preimageOrderIsoFiber (p : PrimeSpectrum R) : · rw [← q₂.2] at hr; simpa [IsScalarTower.algebraMap_apply R S q₂.1.asIdeal.ResidueField] · rw [← q₁.2] at hr; simpa [IsScalarTower.algebraMap_apply R S q₁.1.asIdeal.ResidueField] -@[deprecated (since := "2025-12-07")] -alias PrimeSpectrum.preimageOrderIsoTensorResidueField := PrimeSpectrum.preimageOrderIsoFiber - variable (R S) in /-- The `OrderIso` between the set of primes lying over a prime ideal `p : Ideal R`, and the prime spectrum of `κ(p) ⊗[R] S`. -/ diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean index e76b5c7af8ce7c..4922d98f03efa2 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean @@ -97,9 +97,6 @@ lemma Ideal.algebraMap_quotient_residueField_mk (x) : algebraMap (R ⧸ I) I.ResidueField (Ideal.Quotient.mk _ x) = algebraMap R I.ResidueField x := rfl -@[deprecated (since := "2025-12-02")] -alias algebraMap_mk := Ideal.algebraMap_quotient_residueField_mk - lemma Ideal.injective_algebraMap_quotient_residueField : Function.Injective (algebraMap (R ⧸ I) I.ResidueField) := by rw [RingHom.injective_iff_ker_eq_bot] diff --git a/Mathlib/RingTheory/MvPolynomial/Expand.lean b/Mathlib/RingTheory/MvPolynomial/Expand.lean index e18a24c63620c7..6c058b757fef73 100644 --- a/Mathlib/RingTheory/MvPolynomial/Expand.lean +++ b/Mathlib/RingTheory/MvPolynomial/Expand.lean @@ -27,9 +27,6 @@ theorem map_frobenius_expand {f : MvPolynomial σ R} : f.induction_on' fun _ _ => by simp [monomial_pow, frobenius] fun _ _ ha hb => by rw [map_add, map_add, ha, hb, add_pow_expChar] -@[deprecated (since := "2025-12-27")] -alias expand_char := map_frobenius_expand - theorem map_iterateFrobenius_expand (f : MvPolynomial σ R) (n : ℕ) : map (iterateFrobenius R p n) (expand (p ^ n) f) = f ^ p ^ n := by induction n with @@ -40,7 +37,4 @@ theorem map_iterateFrobenius_expand (f : MvPolynomial σ R) (n : ℕ) : simp_rw [← map_frobenius_expand p, pow_succ', add_comm k, iterateFrobenius_add, ← map_map, ← map_expand, ← expand_mul, iterateFrobenius_one] -@[deprecated (since := "2025-12-27")] -alias map_expand_pow_char := map_iterateFrobenius_expand - end MvPolynomial diff --git a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean index 9fa0ba26441393..049f199d565e02 100644 --- a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean +++ b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean @@ -612,8 +612,6 @@ theorem degree_smul_of_isRegular {r : R} (hr : IsRegular r) {f : MvPolynomial σ m.degree (r • f) = m.degree f := m.degree_smul_of_mem_nonZeroDivisors hr.mem_nonZeroDivisors -@[deprecated (since := "2025-12-12")] alias degree_smul := degree_smul_of_isRegular - theorem degree_prod_le {ι : Type*} {P : ι → MvPolynomial σ R} {s : Finset ι} : m.degree (∏ i ∈ s, P i) ≼[m] ∑ i ∈ s, m.degree (P i) := by classical @@ -1022,8 +1020,6 @@ lemma sPolynomial_monomial_mul [NoZeroDivisors R] (p₁ p₂ : MvPolynomial σ R tsub_add_eq_add_tsub le_sup_left, tsub_add_eq_add_tsub le_sup_right, add_comm d₁, add_comm d₂, add_tsub_add_eq_tsub_right, add_tsub_add_eq_tsub_right] -@[deprecated (since := "2025-12-15")] alias sPolynomial_mul_monomial := sPolynomial_monomial_mul - lemma sPolynomial_monomial_mul' [NoZeroDivisors R] (p₁ p₂ : MvPolynomial σ R) (d₁ d₂ : σ →₀ ℕ) (c₁ c₂ : R) : m.sPolynomial (monomial d₁ c₁ * p₁) (monomial d₂ c₂ * p₂) = diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 12bfc620754045..44a4586f86b575 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -826,14 +826,6 @@ noncomputable def tensorSubmoduleAlgebraEquivMul (I : Submodule R A) : end Module.Flat -namespace Module.Invertible - -@[deprecated (since := "2025-11-23")] alias embAlgebra := Flat.toAlgebra -@[deprecated (since := "2025-11-23")] alias embAlgebra_injective := Flat.toAlgebra_injective -@[deprecated (since := "2025-11-23")] alias toSubmodule := Flat.submoduleAlgebra - -end Module.Invertible - section PicardGroup variable [CommSemiring A] [Algebra R A] [FaithfulSMul R A] diff --git a/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean b/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean index 4c45e4ac62d04b..16fa71e9d8e32a 100644 --- a/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean +++ b/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean @@ -125,9 +125,6 @@ theorem integralNormalization_mul_C_leadingCoeff (p : R[X]) : exact coe_lt_degree.mp h' · simp [coeff_eq_zero_of_degree_lt (lt_of_le_of_ne (le_of_not_gt h') h)] -@[deprecated (since := "2025-11-24")] alias integralNormalization_degree := - degree_integralNormalization - variable {A : Type*} [CommSemiring S] [Semiring A] theorem leadingCoeff_smul_integralNormalization (p : S[X]) : diff --git a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean index f45711e135082e..baba79d9b534a5 100644 --- a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean +++ b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean @@ -308,8 +308,6 @@ lemma Splits.scaleRoots {p : R[X]} (hp : p.Splits) (r : R) : · rw [(monic_multiset_prod_of_monic _ _ fun a _ ↦ monic_X_add_C _).leadingCoeff] simpa -@[deprecated (since := "2025-12-09")] alias Factors.scaleRoots := Splits.scaleRoots - end CommSemiring section Ring diff --git a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean index ad8e42afd26eb9..fe5b1c45c6dc4f 100644 --- a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean +++ b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean @@ -152,10 +152,6 @@ theorem exists_end_ringEquiv_pi_matrix_end : Nonempty (End R M ≃+* Π i, Matrix (Fin (d i)) (Fin (d i)) (End R (S i))) := have ⟨n, S, d, hS, hd, ⟨e⟩⟩ := exists_end_algEquiv_pi_matrix_end ℕ R M; ⟨n, S, d, hS, hd, ⟨e⟩⟩ -@[deprecated (since := "2025-11-16")] alias exists_end_algEquiv := exists_end_algEquiv_pi_matrix_end -@[deprecated (since := "2025-11-16")] -alias exists_end_ringEquiv := exists_end_ringEquiv_pi_matrix_end - -- TODO: can also require D be in `Type u`, since every simple module is the quotient by an ideal. theorem exists_end_algEquiv_pi_matrix_divisionRing : ∃ (n : ℕ) (D : Fin n → Type v) (d : Fin n → ℕ) (_ : ∀ i, DivisionRing (D i)) diff --git a/Mathlib/RingTheory/Smooth/Basic.lean b/Mathlib/RingTheory/Smooth/Basic.lean index 15140cc011e956..ae4cdf01a84d7e 100644 --- a/Mathlib/RingTheory/Smooth/Basic.lean +++ b/Mathlib/RingTheory/Smooth/Basic.lean @@ -74,9 +74,6 @@ class FormallySmooth : Prop where attribute [instance] FormallySmooth.projective_kaehlerDifferential FormallySmooth.subsingleton_h1Cotangent -@[deprecated (since := "2025-10-25")] -alias FormallySmooth.iff_subsingleton_and_projective := Algebra.formallySmooth_iff - set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in variable (R A) in diff --git a/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean b/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean index 3592cf2015d84b..74a0776d095f5a 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean @@ -35,8 +35,6 @@ def PrimeSpectrum.comap {R S : Type*} [CommSemiring R] [CommSemiring S] (f : R (p : PrimeSpectrum S) : PrimeSpectrum R := ⟨Ideal.comap f p.asIdeal, inferInstance⟩ -@[deprecated (since := "2025-12-10")] alias RingHom.specComap := PrimeSpectrum.comap - namespace PrimeSpectrum open RingHom @@ -50,27 +48,19 @@ theorem comap_asIdeal (y : PrimeSpectrum S) : (comap f y).asIdeal = Ideal.comap f y.asIdeal := rfl -@[deprecated (since := "2025-12-10")] alias specComap_asIdeal := comap_asIdeal - @[simp] theorem comap_id : comap (RingHom.id R) = fun x => x := rfl -@[deprecated (since := "2025-12-10")] alias specComap_id := comap_id - @[simp] theorem comap_comp (f : R →+* S) (g : S →+* S') : comap (g.comp f) = (comap f).comp (comap g) := rfl -@[deprecated (since := "2025-12-10")] alias specComap_comp := comap_comp - theorem comap_comp_apply (f : R →+* S) (g : S →+* S') (x : PrimeSpectrum S') : comap (g.comp f) x = comap f (comap g x) := rfl -@[deprecated (since := "2025-12-10")] alias specComap_comp_apply := comap_comp_apply - theorem preimage_comap_zeroLocus_aux (f : R →+* S) (s : Set R) : comap f ⁻¹' zeroLocus s = zeroLocus (f '' s) := by ext x @@ -81,17 +71,12 @@ theorem preimage_comap_zeroLocus (s : Set R) : comap f ⁻¹' zeroLocus s = zeroLocus (f '' s) := preimage_comap_zeroLocus_aux f s -@[deprecated (since := "2025-12-10")] alias preimage_specComap_zeroLocus := preimage_comap_zeroLocus - theorem comap_injective_of_surjective (f : R →+* S) (hf : Function.Surjective f) : Function.Injective (comap f) := fun x y h => PrimeSpectrum.ext (Ideal.comap_injective_of_surjective f hf (congr_arg PrimeSpectrum.asIdeal h : (comap f x).asIdeal = (comap f y).asIdeal)) -@[deprecated (since := "2025-12-10")] -alias specComap_injective_of_surjective := comap_injective_of_surjective - instance [Algebra R S] (p : PrimeSpectrum S) : p.asIdeal.LiesOver (p.comap <| algebraMap R S).asIdeal where over := rfl @@ -219,9 +204,6 @@ lemma iUnion_range_comap_comp_evalRingHom obtain ⟨i, p, rfl⟩ := exists_comap_evalRingHom_eq p exact Set.mem_iUnion_of_mem i ⟨p, rfl⟩ -@[deprecated (since := "2025-12-11")] -alias iUnion_range_specComap_comp_evalRingHom := iUnion_range_comap_comp_evalRingHom - end Pi end PrimeSpectrum @@ -252,18 +234,12 @@ theorem image_comap_zeroLocus_eq_zeroLocus_comap (hf : Surjective f) (I : Ideal refine p.asIdeal.sub_mem hx' (hp ?_) rwa [mem_ker, map_sub, sub_eq_zero] -@[deprecated (since := "2025-12-10")] -alias image_specComap_zeroLocus_eq_zeroLocus_comap := image_comap_zeroLocus_eq_zeroLocus_comap - theorem range_comap_of_surjective (hf : Surjective f) : Set.range (comap f) = zeroLocus (ker f) := by rw [← Set.image_univ] convert! image_comap_zeroLocus_eq_zeroLocus_comap _ _ hf _ rw [zeroLocus_bot] -@[deprecated (since := "2025-12-10")] -alias range_specComap_of_surjective := range_comap_of_surjective - variable {S} /-- Let `f : R →+* S` be a surjective ring homomorphism, then `Spec S` is order-isomorphic to `Z(I)` @@ -323,9 +299,6 @@ lemma RingHom.strictMono_comap_of_surjective {S : Type*} [CommRing S] {f : R →+* S} (hf : Function.Surjective f) : StrictMono (comap f) := fun _ _ h ↦ (Ideal.relIsoOfSurjective _ hf).strictMono h -@[deprecated (since := "2025-12-10")] -alias RingHom.strictMono_specComap_of_surjective := RingHom.strictMono_comap_of_surjective - end SpecOfSurjective section ResidueField @@ -337,9 +310,6 @@ lemma PrimeSpectrum.residueField_comap (I : PrimeSpectrum R) : rw [Set.range_unique, Set.singleton_eq_singleton_iff] exact PrimeSpectrum.ext (Ideal.ext fun x ↦ Ideal.algebraMap_residueField_eq_zero) -@[deprecated (since := "2025-12-10")] -alias PrimeSpectrum.residueField_specComap := PrimeSpectrum.residueField_comap - end ResidueField variable {R S} in @@ -351,6 +321,3 @@ theorem IsLocalHom.of_comap_surjective [CommSemiring R] [CommSemiring S] (f : R obtain ⟨⟨q, hqp⟩, hq⟩ := hf ⟨p, hp.isPrime⟩ simp only [PrimeSpectrum.ext_iff, comap_asIdeal] at hq exact hqp.ne_top (q.eq_top_of_isUnit_mem (q.mem_comap.mp (by rwa [hq])) hfx) - -@[deprecated (since := "2025-12-10")] -alias IsLocalHom.of_specComap_surjective := IsLocalHom.of_comap_surjective diff --git a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean index 9d42b9f5ad0864..c7dea1f60d1fa8 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean @@ -336,10 +336,6 @@ lemma continuous_comap (f : R →+* S) : Continuous (comap f) := by rintro _ ⟨s, rfl⟩ exact ⟨_, preimage_comap_zeroLocus_aux f s⟩ -@[deprecated "RingHom.specComap and PrimeSpectrum.comap were unified,\ -so this lemma is now a no-op." (since := "2025-12-10"), nolint synTaut] -lemma comap_apply (f : R →+* S) (x : PrimeSpectrum S) : comap f x = comap f x := rfl - variable (f : R →+* S) variable (S) @@ -353,9 +349,6 @@ theorem localization_comap_injective [Algebra R S] (M : Submonoid R) [IsLocaliza ext1 exact h -@[deprecated (since := "2025-12-10")] -alias localization_specComap_injective := localization_comap_injective - theorem localization_comap_range [Algebra R S] (M : Submonoid R) [IsLocalization M S] : Set.range (comap (algebraMap R S)) = { p | Disjoint (M : Set R) p.asIdeal } := by refine Set.ext fun x ↦ ⟨?_, fun h ↦ ?_⟩ @@ -365,8 +358,6 @@ theorem localization_comap_range [Algebra R S] (M : Submonoid R) [IsLocalization ext1 exact IsLocalization.under_map_of_isPrime_disjoint M S x.2 h -@[deprecated (since := "2025-12-10")] alias localization_specComap_range := localization_comap_range - theorem localization_comap_isInducing [Algebra R S] (M : Submonoid R) [IsLocalization M S] : IsInducing (comap (algebraMap R S)) := by refine ⟨TopologicalSpace.ext_isClosed fun Z ↦ ?_⟩ @@ -1236,9 +1227,6 @@ lemma _root_.RingHom.IsIntegral.comap_surjective {f : R →+* S} (hf : f.IsInteg have : FaithfulSMul R S := (faithfulSMul_iff_algebraMap_injective R S).mpr hinj exact Algebra.IsIntegral.comap_surjective _ _ -@[deprecated (since := "2025-12-10")] -alias _root_.RingHom.IsIntegral.specComap_surjective := _root_.RingHom.IsIntegral.comap_surjective - end IsIntegral /-- Zero loci of minimal prime ideals over `I` are irreducible components in `zeroLocus I` and any diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 0cb1d9d4957031..0d694d4572df9c 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -105,21 +105,11 @@ class ValuativePreorder (R : Type*) [Semiring R] [ValuativeRel R] [Preorder R] w namespace ValuativeRel -@[deprecated (since := "2025-12-20")] alias Rel := vle -@[deprecated (since := "2025-12-20")] alias rel_total := vle_total -@[deprecated (since := "2025-12-20")] alias rel_trans := vle_trans -@[deprecated (since := "2025-12-20")] alias rel_add := vle_add -@[deprecated (since := "2025-12-20")] alias rel_mul_right := mul_vle_mul_left -@[deprecated (since := "2025-12-20")] alias rel_mul_cancel := vle_mul_cancel -@[deprecated (since := "2025-12-20")] alias not_rel_one_zero := not_vle_one_zero - variable {R : Type*} [Semiring R] [ValuativeRel R] {x x' y y' z : R} /-- The valuation less-than relation, defined as `x <ᵥ y ↔ ¬ y ≤ᵥ x`. -/ def vlt (x y : R) : Prop := ¬ y ≤ᵥ x -@[deprecated (since := "2025-12-20")] alias SRel := vlt - @[inherit_doc] infix:50 " <ᵥ " => ValuativeRel.vlt macro_rules | `($a <ᵥ $b) => `(binrel% ValuativeRel.vlt $a $b) @@ -137,11 +127,6 @@ macro_rules | `($a =ᵥ $b) => `(binrel% ValuativeRel.veq $a $b) @[simp, grind =] lemma not_vlt : ¬ x <ᵥ y ↔ y ≤ᵥ x := not_vle.not_left lemma veq_def : x =ᵥ y ↔ x ≤ᵥ y ∧ y ≤ᵥ x := .rfl -@[deprecated not_vle (since := "2025-12-20")] -lemma srel_iff : x <ᵥ y ↔ ¬ y ≤ᵥ x := Iff.rfl - -@[deprecated (since := "2025-12-20")] alias not_srel_iff := not_vlt - protected alias ⟨_, vle.not_vlt⟩ := not_vlt protected alias ⟨_, vlt.not_vle⟩ := not_vle @@ -166,18 +151,12 @@ protected alias veq.not_vgt := not_vgt_of_veq @[simp, refl] lemma vle_refl (x : R) : x ≤ᵥ x := or_self_iff.1 <| vle_total x x lemma vle_rfl : x ≤ᵥ x := vle_refl x -@[deprecated (since := "2025-12-20")] alias rel_refl := vle_refl -@[deprecated (since := "2025-12-20")] alias rel_rfl := vle_rfl - protected alias vle.refl := vle_refl protected alias vle.rfl := vle_rfl instance : @Std.Refl R (· ≤ᵥ ·) where refl _ := vle_rfl -@[deprecated (since := "2025-12-20")] protected alias Rel.refl := vle.refl -@[deprecated (since := "2025-12-20")] protected alias Rel.rfl := vle.rfl - @[simp, refl] lemma veq_refl (x : R) : x =ᵥ x := AntisymmRel.rfl lemma veq_rfl : x =ᵥ x := veq_refl x @@ -191,8 +170,6 @@ instance : @Std.Refl R (· =ᵥ ·) where theorem zero_vle (x : R) : 0 ≤ᵥ x := by simpa using mul_vle_mul_left ((vle_total 0 1).resolve_right not_vle_one_zero) x -@[deprecated (since := "2025-12-20")] alias zero_rel := zero_vle - @[simp] theorem not_vlt_zero (x : R) : ¬ x <ᵥ 0 := by simp @@ -204,8 +181,6 @@ theorem vlt.ne_zero (h : x <ᵥ y) : y ≠ 0 := by lemma zero_vlt_one : (0 : R) <ᵥ 1 := not_vle_one_zero -@[deprecated (since := "2025-12-20")] alias zero_srel_one := zero_vlt_one - @[deprecated mul_vle_mul_left (since := "2026-01-06")] lemma vle_mul_right (z) (h : x ≤ᵥ y) : x * z ≤ᵥ y * z := mul_vle_mul_left h z @@ -213,24 +188,16 @@ lemma vle_mul_right (z) (h : x ≤ᵥ y) : x * z ≤ᵥ y * z := lemma mul_vle_mul_right (h : x ≤ᵥ y) (z) : z * x ≤ᵥ z * y := vle_trans (veq_mul_comm _ _).1 (vle_trans (mul_vle_mul_left h z) ((veq_mul_comm _ _).1)) -@[deprecated (since := "2025-12-20")] alias rel_mul_left := mul_vle_mul_right - instance : @Trans R R R vle vle vle where trans := vle_trans protected alias vle.trans := vle_trans -@[deprecated (since := "2025-12-20")] protected alias Rel.trans := vle.trans - lemma vle_trans' (h1 : y ≤ᵥ z) (h2 : x ≤ᵥ y) : x ≤ᵥ z := h2.trans h1 -@[deprecated (since := "2025-12-20")] alias rel_trans' := vle_trans' - protected alias vle.trans' := vle_trans' -@[deprecated (since := "2025-12-20")] protected alias Rel.trans' := vle.trans' - lemma veq_trans (h1 : x =ᵥ y) (h2 : y =ᵥ z) : x =ᵥ z := AntisymmRel.trans h1 h2 @@ -252,21 +219,13 @@ instance : @Trans R R R vle veq vle where lemma vlt_of_vlt_of_vle (h1 : x <ᵥ y) (h2 : y ≤ᵥ z) : x <ᵥ z := fun h ↦ (h1 (vle_trans h2 h)).elim -@[deprecated (since := "2025-12-20")] alias srel_of_srel_of_rel := vlt_of_vlt_of_vle - alias vlt.trans_vle := vlt_of_vlt_of_vle -@[deprecated (since := "2025-12-20")] alias SRel.trans_rel := vlt.trans_vle - lemma vlt_of_vle_of_vlt (h1 : x ≤ᵥ y) (h2 : y <ᵥ z) : x <ᵥ z := fun h ↦ (h2 (vle_trans h h1)).elim -@[deprecated (since := "2025-12-20")] alias srel_of_rel_of_srel := vlt_of_vle_of_vlt - alias vle.trans_vlt := vlt_of_vle_of_vlt -@[deprecated (since := "2025-12-20")] alias Rel.trans_srel := srel_of_rel_of_srel - instance : @Trans R R R vlt vle vlt where trans := vlt_of_vlt_of_vle @@ -276,13 +235,9 @@ instance : @Trans R R R vle vlt vlt where lemma vlt.vle (h : x <ᵥ y) : x ≤ᵥ y := (vle_total _ _).resolve_right h -@[deprecated (since := "2025-12-20")] alias SRel.rel := vlt.vle - lemma vlt.trans (h1 : x <ᵥ y) (h2 : y <ᵥ z) : x <ᵥ z := h1.trans_vle h2.vle -@[deprecated (since := "2025-12-20")] alias SRel.trans := vlt.trans - instance : @Trans R R R vlt vlt vlt where trans := vlt.trans @@ -306,13 +261,9 @@ theorem vlt_imp_vlt_of_vle_of_vle (h1 : x ≤ᵥ x') (h2 : y' ≤ᵥ y) : x' < lemma mul_vle_mul {x x' y y' : R} (h1 : x ≤ᵥ y) (h2 : x' ≤ᵥ y') : x * x' ≤ᵥ y * y' := (mul_vle_mul_left h1 _).trans (mul_vle_mul_right h2 _) -@[deprecated (since := "2025-12-20")] alias mul_rel_mul := mul_vle_mul - @[simp] lemma mul_vle_mul_iff_left (hz : 0 <ᵥ z) : x * z ≤ᵥ y * z ↔ x ≤ᵥ y := ⟨vle_mul_cancel hz, (mul_vle_mul_left · _)⟩ -@[deprecated (since := "2025-12-20")] alias mul_rel_mul_iff_left := mul_vle_mul_iff_left - @[simp] lemma mul_vle_mul_iff_right (hx : 0 <ᵥ x) : x * y ≤ᵥ x * z ↔ y ≤ᵥ z := by refine ⟨fun h ↦ ?_ , fun h ↦ ?_⟩ · grw [veq_mul_comm, veq_mul_comm (x := x)] at h @@ -320,24 +271,18 @@ lemma mul_vle_mul {x x' y y' : R} (h1 : x ≤ᵥ y) (h2 : x' ≤ᵥ y') : x * x' · grw [veq_mul_comm, veq_mul_comm (x := x)] rwa [mul_vle_mul_iff_left hx] -@[deprecated (since := "2025-12-20")] alias mul_rel_mul_iff_right := mul_vle_mul_iff_right - @[simp] lemma mul_vlt_mul_iff_left (hz : 0 <ᵥ z) : x * z <ᵥ y * z ↔ x <ᵥ y := (mul_vle_mul_iff_left hz).not @[gcongr] alias ⟨_, mul_vlt_mul_left⟩ := mul_vlt_mul_iff_left @[deprecated (since := "2026-01-06")] alias vlt_mul_right := mul_vlt_mul_left -@[deprecated (since := "2025-12-20")] alias mul_srel_mul_iff_left := mul_vlt_mul_iff_left - @[simp] lemma mul_vlt_mul_iff_right (hx : 0 <ᵥ x) : x * y <ᵥ x * z ↔ y <ᵥ z := (mul_vle_mul_iff_right hx).not @[gcongr] alias ⟨_, mul_vlt_mul_right⟩ := mul_vlt_mul_iff_right @[deprecated (since := "2026-01-06")] alias vlt_mul_left := mul_vlt_mul_right -@[deprecated (since := "2025-12-20")] alias mul_srel_mul_iff_right := mul_vlt_mul_iff_right - @[gcongr] lemma mul_veq_mul (h1 : x =ᵥ y) (h2 : x' =ᵥ y') : x * x' =ᵥ y * y' := ⟨mul_vle_mul h1.vle h2.vle, mul_vle_mul h1.vge h2.vge⟩ @@ -351,16 +296,12 @@ lemma veq_mul_mul_mul_comm (x y z w : R) : x * y * (z * w) =ᵥ x * z * (y * w) theorem vle_add_cases (x y : R) : x + y ≤ᵥ x ∨ x + y ≤ᵥ y := (vle_total y x).imp (fun h => vle_add .rfl h) (fun h => vle_add h .rfl) -@[deprecated (since := "2025-12-20")] alias rel_add_cases := vle_add_cases - @[simp] lemma zero_vlt_mul (hx : 0 <ᵥ x) (hy : 0 <ᵥ y) : 0 <ᵥ x * y := by contrapose hy rw [not_vlt] at hy ⊢ grw [show (0 : R) = x * 0 by simp, veq_mul_comm, veq_mul_comm x] at hy exact vle_mul_cancel hx hy -@[deprecated (since := "2025-12-20")] alias zero_srel_mul := zero_vlt_mul - variable (R) in /-- The submonoid of elements `x : R` whose valuation is positive. -/ def posSubmonoid : Submonoid R where @@ -370,8 +311,6 @@ def posSubmonoid : Submonoid R where @[simp] lemma zero_vlt_coe_posSubmonoid (x : posSubmonoid R) : 0 <ᵥ x.val := x.prop -@[deprecated (since := "2025-12-20")] alias zero_srel_coe_posSubmonoid := zero_vlt_coe_posSubmonoid - @[simp] lemma posSubmonoid_def (x : R) : x ∈ posSubmonoid R ↔ 0 <ᵥ x := Iff.rfl @@ -806,13 +745,9 @@ variable {x y : R} lemma vle_iff_le : x ≤ᵥ y ↔ v x ≤ v y := Compatible.vle_iff_le _ _ -@[deprecated (since := "2025-12-20")] alias rel_iff_le := vle_iff_le - lemma vlt_iff_lt : x <ᵥ y ↔ v x < v y := by simp [lt_iff_not_ge, ← Compatible.vle_iff_le] -@[deprecated (since := "2025-12-20")] alias srel_iff_lt := vlt_iff_lt - lemma veq_iff_eq : x =ᵥ y ↔ v x = v y := by simp_rw [veq_def, vle_iff_le v, antisymm_iff] @@ -821,11 +756,6 @@ lemma vlt_one_iff : x <ᵥ 1 ↔ v x < 1 := by simp [v.vlt_iff_lt] lemma one_vle_iff : 1 ≤ᵥ x ↔ 1 ≤ v x := by simp [v.vle_iff_le] lemma one_vlt_iff : 1 <ᵥ x ↔ 1 < v x := by simp [v.vlt_iff_lt] -@[deprecated (since := "2025-12-20")] alias rel_one_iff := vle_one_iff -@[deprecated (since := "2025-12-20")] alias srel_one_iff := vlt_one_iff -@[deprecated (since := "2025-12-20")] alias one_rel_iff := one_vle_iff -@[deprecated (since := "2025-12-20")] alias one_srel_iff := one_vlt_iff - @[simp] lemma apply_posSubmonoid_ne_zero (x : posSubmonoid R) : v (x : R) ≠ 0 := by simp [(isEquiv v (valuation R)).eq_zero, valuation_posSubmonoid_ne_zero] @@ -904,69 +834,43 @@ variable {R : Type*} [Ring R] [ValuativeRel R] {a b c d : R} @[deprecated (since := "2026-01-06")] alias vle_mul_right_iff := mul_vle_mul_iff_left -@[deprecated (since := "2025-12-20")] alias rel_mul_right_iff := vle_mul_right_iff - @[deprecated (since := "2026-01-06")] alias vle_mul_left_iff := mul_vle_mul_iff_right -@[deprecated (since := "2025-12-20")] alias rel_mul_left_iff := mul_vle_mul_iff_right - @[deprecated (since := "2026-01-06")] alias vlt_mul_right_iff := mul_vlt_mul_iff_left -@[deprecated (since := "2025-12-20")] alias srel_mul_right_iff := mul_vlt_mul_iff_left - -@[deprecated (since := "2025-12-20")] alias srel_mul_right := mul_vlt_mul_right - @[deprecated (since := "2026-01-06")] alias vlt_mul_left_iff := mul_vlt_mul_iff_right -@[deprecated (since := "2025-12-20")] alias srel_mul_left_iff := mul_vlt_mul_iff_right - -@[deprecated (since := "2025-12-20")] alias srel_mul_left := mul_vlt_mul_right - lemma mul_vlt_mul_of_vlt_of_vle (hab : a <ᵥ b) (hcd : c ≤ᵥ d) (hd : 0 <ᵥ d) : a * c <ᵥ b * d := (mul_vle_mul_right hcd _).trans_vlt (mul_vlt_mul_left hd hab) -@[deprecated (since := "2025-12-20")] alias mul_srel_mul_of_srel_of_rel := mul_vlt_mul_of_vlt_of_vle - lemma mul_vlt_mul_of_vle_of_vlt (hab : a ≤ᵥ b) (hcd : c <ᵥ d) (ha : 0 <ᵥ a) : a * c <ᵥ b * d := (mul_vlt_mul_right ha hcd).trans_vle (mul_vle_mul_left hab _) -@[deprecated (since := "2025-12-20")] alias mul_srel_mul_of_rel_of_srel := mul_vlt_mul_of_vle_of_vlt - @[gcongr] lemma mul_vlt_mul (hab : a <ᵥ b) (hcd : c <ᵥ d) : a * c <ᵥ b * d := (mul_vle_mul_right hcd.vle _).trans_vlt (mul_vlt_mul_left ((zero_vle c).trans_vlt hcd) hab) -@[deprecated (since := "2025-12-20")] alias mul_srel_mul := mul_vlt_mul - lemma pow_vle_pow (hab : a ≤ᵥ b) (n : ℕ) : a ^ n ≤ᵥ b ^ n := by induction n with | zero => simp | succ _ hn => simp [pow_succ, mul_vle_mul hn hab] -@[deprecated (since := "2025-12-20")] alias pow_rel_pow := pow_vle_pow - lemma pow_vlt_pow (hab : a <ᵥ b) {n : ℕ} (hn : n ≠ 0) : a ^ n <ᵥ b ^ n := by induction n using Nat.twoStepInduction with | zero => contradiction | one => simpa | more _ _ => simp_all [pow_succ, mul_vlt_mul] -@[deprecated (since := "2025-12-20")] alias pow_srel_pow := pow_vlt_pow - lemma pow_vle_pow_of_vle_one (ha : a ≤ᵥ 1) {n m : ℕ} (hnm : n ≤ m) : a ^ m ≤ᵥ a ^ n := by obtain ⟨m, rfl⟩ := exists_add_of_le hnm simpa [pow_add] using mul_vle_mul_right (pow_vle_pow ha m) _ -@[deprecated (since := "2025-12-20")] alias pow_rel_pow_of_rel_one := pow_vle_pow_of_vle_one - lemma pow_vle_pow_of_one_vle (ha : 1 ≤ᵥ a) {n m : ℕ} (hnm : n ≤ m) : a ^ n ≤ᵥ a ^ m := by obtain ⟨m, rfl⟩ := exists_add_of_le hnm simpa [pow_add] using mul_vle_mul_right (pow_vle_pow ha m) _ -@[deprecated (since := "2025-12-20")] alias pow_rel_pow_of_one_rel := pow_vle_pow_of_one_vle - end Ring section DivisionRing @@ -977,14 +881,10 @@ variable {K : Type*} [DivisionRing K] [ValuativeRel K] {a b c x : K} lemma vle_zero_iff : a ≤ᵥ 0 ↔ a = 0 := by rw [← supp_def, Ideal.eq_bot_of_prime (supp K), Ideal.mem_bot] -@[deprecated (since := "2025-12-20")] alias rel_zero_iff := vle_zero_iff - @[simp] lemma zero_vlt_iff : 0 <ᵥ a ↔ a ≠ 0 := by simp [vlt] -@[deprecated (since := "2025-12-20")] alias zero_srel_iff := zero_vlt_iff - @[simp] lemma zero_veq_iff : a =ᵥ 0 ↔ a = 0 where mp h := vle_zero_iff.1 h.1 @@ -997,43 +897,27 @@ lemma veq_zero_iff : 0 =ᵥ a ↔ 0 = a := by lemma vle_div_iff (hc : c ≠ 0) : a ≤ᵥ b / c ↔ a * c ≤ᵥ b := by rw [← mul_vle_mul_iff_left (by simpa), div_mul_cancel₀ _ (by lia)] -@[deprecated (since := "2025-12-20")] alias rel_div_iff := vle_div_iff - lemma div_vle_iff (hc : c ≠ 0) : a / c ≤ᵥ b ↔ a ≤ᵥ b * c := by rw [← mul_vle_mul_iff_left (by simpa), div_mul_cancel₀ _ (by lia)] -@[deprecated (since := "2025-12-20")] alias div_rel_iff := div_vle_iff - lemma one_vle_div_iff (hb : b ≠ 0) : 1 ≤ᵥ a / b ↔ b ≤ᵥ a := by simp [vle_div_iff hb] -@[deprecated (since := "2025-12-20")] alias one_rel_div_iff := one_vle_div_iff - lemma div_vle_one_iff (hb : b ≠ 0) : a / b ≤ᵥ 1 ↔ a ≤ᵥ b := by simp [div_vle_iff hb] -@[deprecated (since := "2025-12-20")] alias div_rel_one_iff := div_vle_one_iff - lemma one_vle_inv (hx : x ≠ 0) : 1 ≤ᵥ x⁻¹ ↔ x ≤ᵥ 1 := by simpa using one_vle_div_iff (a := 1) hx -@[deprecated (since := "2025-12-20")] alias one_rel_inv := one_vle_inv - lemma inv_vle_one (hx : x ≠ 0) : x⁻¹ ≤ᵥ 1 ↔ 1 ≤ᵥ x := by simpa using div_vle_one_iff (a := 1) hx -@[deprecated (since := "2025-12-20")] alias inv_rel_one := inv_vle_one - lemma inv_vlt_one (hx : x ≠ 0) : x⁻¹ <ᵥ 1 ↔ 1 <ᵥ x := (one_vle_inv hx).not -@[deprecated (since := "2025-12-20")] alias inv_srel_one := inv_vlt_one - lemma one_vlt_inv (hx : x ≠ 0) : 1 <ᵥ x⁻¹ ↔ x <ᵥ 1 := (inv_vle_one hx).not -@[deprecated (since := "2025-12-20")] alias one_srel_inv := one_vlt_inv - end DivisionRing open NNReal in variable (R) in @@ -1382,8 +1266,6 @@ variable [CommSemiring A] [Semiring B] [ValuativeRel A] [ValuativeRel B] lemma vlt_iff_vlt {a b : A} : algebraMap A B a <ᵥ algebraMap A B b ↔ a <ᵥ b := by rw [← not_vle, vle_iff_vle, not_vle] -@[deprecated (since := "2025-12-20")] alias srel_iff_srel := vlt_iff_vlt - variable (A B) in /-- The morphism of `posSubmonoid`s associated to an algebra map. This is used in constructing `ValuativeExtension.mapValueGroupWithZero`. -/ diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean index 3ffc2f0591903c..36682350f70b1c 100644 --- a/Mathlib/SetTheory/Cardinal/Aleph.lean +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -253,9 +253,6 @@ theorem omega0_lt_omega_one : ω < ω₁ := by rw [← omega_zero, omega_lt_omega] exact zero_lt_one -@[deprecated (since := "2025-12-22")] -alias omega0_lt_omega1 := omega0_lt_omega_one - theorem isNormal_omega : IsNormal omega := isNormal_preOmega.comp (isNormal_add_right _) @@ -784,38 +781,26 @@ variable {c : Cardinal.{u}} {n : ℕ} theorem aleph_one_le_lift : ℵ₁ ≤ lift.{v} c ↔ ℵ₁ ≤ c := by simp -@[deprecated (since := "2025-12-22")] alias aleph1_le_lift := aleph_one_le_lift - @[simp] theorem lift_le_aleph_one : lift.{v} c ≤ ℵ₁ ↔ c ≤ ℵ₁ := by simpa using lift_le (b := ℵ₁) -@[deprecated (since := "2025-12-22")] alias lift_le_aleph1 := lift_le_aleph_one - @[simp] theorem aleph_one_lt_lift : ℵ₁ < lift.{v} c ↔ ℵ₁ < c := by simpa using lift_lt (a := ℵ₁) -@[deprecated (since := "2025-12-22")] alias aleph1_lt_lift := aleph_one_lt_lift - @[deprecated lift_le_aleph0 (since := "2026-03-23")] theorem lift_lt_aleph_one : lift.{v} c < ℵ₁ ↔ c < ℵ₁ := by simp -@[deprecated (since := "2025-12-22")] alias lift_lt_aleph1 := lift_lt_aleph_one - @[simp] theorem aleph_one_eq_lift : ℵ₁ = lift.{v} c ↔ ℵ₁ = c := by simpa using lift_inj (a := ℵ₁) -@[deprecated (since := "2025-12-22")] alias aleph1_eq_lift := aleph_one_eq_lift - @[simp] theorem lift_eq_aleph_one : lift.{v} c = ℵ₁ ↔ c = ℵ₁ := by simp [eqComm] -@[deprecated (since := "2025-12-22")] alias lift_eq_aleph1 := lift_eq_aleph_one - @[simp] theorem aleph_natCast_le_lift : ℵ_ n ≤ lift.{v} c ↔ ℵ_ n ≤ c := by simpa using lift_le (a := ℵ_ n) diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean index 53c57336de09aa..ab0ba04bff0862 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean @@ -240,9 +240,6 @@ theorem cof_map_of_isNormal {f} (hf : IsNormal f) {a} (ha : IsSuccLimit a) : cof @[deprecated (since := "2026-03-19")] alias cof_eq_of_isNormal := cof_map_of_isNormal -@[deprecated (since := "2025-12-25")] -alias IsNormal.cof_eq := cof_eq_of_isNormal - theorem le_cof_map_of_isNormal {f} (hf : IsNormal f) (a) : cof a ≤ cof (f a) := by cases a using limitRecOn with | zero => simp @@ -254,9 +251,6 @@ theorem le_cof_map_of_isNormal {f} (hf : IsNormal f) (a) : cof a ≤ cof (f a) : @[deprecated (since := "2026-03-19")] alias cof_le_of_isNormal := le_cof_map_of_isNormal -@[deprecated (since := "2025-12-25")] -alias IsNormal.cof_le := le_cof_map_of_isNormal - theorem sSup_add_one_lt_of_lt_cof {s : Set Ordinal.{u}} {a : Ordinal.{u}} (ha : #s < (lift.{u + 1} a).cof) (hs : ∀ i ∈ s, i < a) : sSup ((· + 1) '' s) < a := by let f := OrderIso.ofRelIsoLT (enum (α := s) (· < ·)) diff --git a/Mathlib/SetTheory/Cardinal/Regular.lean b/Mathlib/SetTheory/Cardinal/Regular.lean index efc04cfe4172e3..429805d88c6a31 100644 --- a/Mathlib/SetTheory/Cardinal/Regular.lean +++ b/Mathlib/SetTheory/Cardinal/Regular.lean @@ -104,9 +104,6 @@ theorem _root_.Ordinal.iSup_lt_omega_one {α : Type*} [Countable α] {f : α → @[deprecated (since := "2026-03-23")] alias iSup_sequence_lt_omega_one := Ordinal.iSup_lt_omega_one -@[deprecated (since := "2025-12-22")] -alias iSup_sequence_lt_omega1 := Ordinal.iSup_lt_omega_one - theorem isRegular_preAleph_add_one {o : Ordinal} (h : ω ≤ o) : IsRegular (preAleph (o + 1)) := by rw [← succ_preAleph] exact isRegular_succ (aleph0_le_preAleph.2 h) diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 6695747a689e33..b5bf8f88eb9bf0 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -179,46 +179,6 @@ theorem limitRecOn_limit {motive} (o H₁ H₂ H₃ h) : @limitRecOn motive o H₁ H₂ H₃ = H₃ o h fun x _h => @limitRecOn motive x H₁ H₂ H₃ := SuccOrder.limitRecOn_of_isSuccLimit .. -/-- Bounded recursion on ordinals. Similar to `limitRecOn`, with the assumption `o < l` - added to all cases. The final term's domain is the ordinals below `l`. -/ -@[deprecated limitRecOn (since := "2025-12-26"), elab_as_elim] -def boundedLimitRecOn {l : Ordinal} (lLim : IsSuccLimit l) {motive : Iio l → Sort*} (o : Iio l) - (zero : motive ⟨0, lLim.bot_lt⟩) - (succ : (o : Iio l) → motive o → motive ⟨succ o, lLim.succ_lt o.2⟩) - (limit : (o : Iio l) → IsSuccLimit o.1 → (Π o' < o, motive o') → motive o) : motive o := by - obtain ⟨o, ho⟩ := o - induction o using limitRecOn with - | zero => exact zero - | add_one o IH => - have ho' : o < l := (lt_succ o).trans ho - exact succ ⟨o, ho'⟩ (IH ho') - | limit o ho' IH => exact limit _ ho' fun a ha ↦ IH a.1 ha (ha.trans (c := l) ho) - -@[deprecated limitRecOn_zero (since := "2025-12-26")] -theorem boundedLimitRec_zero {l} (lLim : IsSuccLimit l) {motive} (H₁ H₂ H₃) : - @boundedLimitRecOn l lLim motive ⟨0, lLim.bot_lt⟩ H₁ H₂ H₃ = H₁ := by - rw [boundedLimitRecOn] - dsimp - rw [limitRecOn_zero] - -@[deprecated limitRecOn_succ (since := "2025-12-26")] -theorem boundedLimitRec_succ {l} (lLim : IsSuccLimit l) {motive} (o H₁ H₂ H₃) : - @boundedLimitRecOn l lLim motive ⟨succ o.1, lLim.succ_lt o.2⟩ H₁ H₂ H₃ = H₂ o - (@boundedLimitRecOn l lLim motive o H₁ H₂ H₃) := by - rw [boundedLimitRecOn] - dsimp - rw [limitRecOn_succ] - rfl - -@[deprecated limitRecOn_limit (since := "2025-12-26")] -theorem boundedLimitRec_limit {l} (lLim : IsSuccLimit l) {motive} (o H₁ H₂ H₃ oLim) : - @boundedLimitRecOn l lLim motive o H₁ H₂ H₃ = H₃ o oLim (fun x _ ↦ - @boundedLimitRecOn l lLim motive x H₁ H₂ H₃) := by - rw [boundedLimitRecOn] - dsimp - rw [limitRecOn_limit] - rfl - instance orderTopToTypeSucc (o : Ordinal) : OrderTop (succ o).ToType := @OrderTop.mk _ _ (Top.mk _) le_enum_succ @@ -314,87 +274,6 @@ theorem lift_pred (o : Ordinal.{v}) : lift.{u} (pred o) = pred (lift.{u} o) := b · simp · rwa [ho.ordinalPred_eq, eq_comm, pred_eq_iff_isSuccPrelimit, isSuccPrelimit_lift] -/-- A normal ordinal function is a strictly increasing function which is - order-continuous, i.e., the image `f o` of a limit ordinal `o` is the sup of `f a` for - `a < o`. -/ -@[deprecated Order.IsNormal (since := "2025-12-25")] -protected def IsNormal (f : Ordinal → Ordinal) : Prop := - Order.IsNormal f - -@[deprecated IsNormal.le_iff_forall_le (since := "2025-12-25")] -theorem IsNormal.limit_le {f} (H : Ordinal.IsNormal f) : - ∀ {o}, IsSuccLimit o → ∀ {a}, f o ≤ a ↔ ∀ b < o, f b ≤ a := - H.le_iff_forall_le - -@[deprecated IsNormal.lt_iff_exists_lt (since := "2025-12-25")] -theorem IsNormal.limit_lt {f} (H : Ordinal.IsNormal f) {o} (h : IsSuccLimit o) {a} : - a < f o ↔ ∃ b < o, a < f b := - H.lt_iff_exists_lt h - -@[deprecated Order.IsNormal.strictMono (since := "2025-12-25")] -theorem IsNormal.strictMono {f} (H : Ordinal.IsNormal f) : StrictMono f := - Order.IsNormal.strictMono H - -@[deprecated Order.IsNormal.strictMono (since := "2025-12-25")] -theorem IsNormal.monotone {f} (H : Ordinal.IsNormal f) : Monotone f := - H.strictMono.monotone - -@[deprecated isNormal_iff (since := "2025-12-25")] -theorem isNormal_iff_strictMono_limit (f : Ordinal → Ordinal) : - Ordinal.IsNormal f ↔ StrictMono f ∧ ∀ o, IsSuccLimit o → ∀ a, (∀ b < o, f b ≤ a) → f o ≤ a := - isNormal_iff - -@[deprecated StrictMono.lt_iff_lt (since := "2025-12-25")] -theorem IsNormal.lt_iff {f} (H : Ordinal.IsNormal f) {a b} : f a < f b ↔ a < b := - H.strictMono.lt_iff_lt - -@[deprecated StrictMono.le_iff_le (since := "2025-12-25")] -theorem IsNormal.le_iff {f} (H : Ordinal.IsNormal f) {a b} : f a ≤ f b ↔ a ≤ b := - H.strictMono.le_iff_le - -@[deprecated Injective.eq_iff (since := "2025-12-25")] -theorem IsNormal.inj {f} (H : Ordinal.IsNormal f) {a b} : f a = f b ↔ a = b := - H.strictMono.injective.eq_iff - -@[deprecated StrictMono.id_le (since := "2025-12-25")] -theorem IsNormal.id_le {f} (H : Ordinal.IsNormal f) : id ≤ f := - H.strictMono.id_le - -@[deprecated StrictMono.le_apply (since := "2025-12-25")] -theorem IsNormal.le_apply {f} (H : Ordinal.IsNormal f) {a} : a ≤ f a := - H.strictMono.le_apply - -@[deprecated StrictMono.le_apply (since := "2025-12-25")] -theorem IsNormal.le_iff_eq {f} (H : Ordinal.IsNormal f) {a} : f a ≤ a ↔ f a = a := - H.le_apply.ge_iff_eq' - -@[deprecated IsNormal.map_isLUB (since := "2025-12-25")] -theorem IsNormal.le_set {f o} (H : Ordinal.IsNormal f) (p : Set Ordinal) (p0 : p.Nonempty) (b) - (H₂ : ∀ o, b ≤ o ↔ ∀ a ∈ p, a ≤ o) : f b ≤ o ↔ ∀ a ∈ p, f a ≤ o := by - have hp := H.map_isLUB ⟨(H₂ b).1 le_rfl, fun a ↦ (H₂ _).2⟩ p0 - refine ⟨fun hb a ha ↦ (hp.1 (mem_image_of_mem _ ha)).trans hb, fun H ↦ hp.2 ?_⟩ - simpa [mem_upperBounds] - -@[deprecated IsNormal.map_isLUB (since := "2025-12-25")] -theorem IsNormal.le_set' {f o} (H : Ordinal.IsNormal f) (p : Set α) (p0 : p.Nonempty) - (g : α → Ordinal) (b) (H₂ : ∀ o, b ≤ o ↔ ∀ a ∈ p, g a ≤ o) : - f b ≤ o ↔ ∀ a ∈ p, f (g a) ≤ o := by - simpa [H₂] using H.le_set (g '' p) (p0.image g) b - -@[deprecated IsNormal.id (since := "2025-12-25")] -theorem IsNormal.refl : Ordinal.IsNormal id := - .id - -@[deprecated IsNormal.comp (since := "2025-12-25")] -theorem IsNormal.trans {f g} (H₁ : Ordinal.IsNormal f) (H₂ : Ordinal.IsNormal g) : - IsNormal (f ∘ g) := - H₁.comp H₂ - -@[deprecated IsNormal.map_isSuccLimit (since := "2025-12-25")] -theorem IsNormal.isSuccLimit {f} (H : Ordinal.IsNormal f) {o} (ho : IsSuccLimit o) : - IsSuccLimit (f o) := - H.map_isSuccLimit ho - /-! ### Subtraction on ordinals -/ /-- `a - b` is the unique ordinal satisfying `b + (a - b) = a` when `b ≤ a`. -/ diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index fa5a7b2d04f2ad..79a5ed4c70f2d3 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -120,9 +120,6 @@ Ordinal.ToType.toOrd : o.ToType → Iio o def Ordinal.ToType (o : Ordinal.{u}) : Type u := o.out.α -@[deprecated (since := "2025-12-04")] -alias Ordinal.toType := Ordinal.ToType - @[no_expose] instance linearOrder_toType (o : Ordinal) : LinearOrder o.ToType := @IsWellOrder.linearOrder _ o.out.r o.out.wo @@ -358,17 +355,6 @@ instance : OrderBot Ordinal where theorem bot_eq_zero : (⊥ : Ordinal) = 0 := rfl -@[deprecated nonpos_iff_eq_zero (since := "2025-11-21")] -protected theorem le_zero {o : Ordinal} : o ≤ 0 ↔ o = 0 := - le_bot_iff - -@[deprecated not_neg (since := "2025-11-21")] -protected theorem not_lt_zero (o : Ordinal) : ¬o < 0 := - not_lt_bot - -@[deprecated eq_zero_or_pos (since := "2025-11-21")] -protected theorem eq_zero_or_pos : ∀ a : Ordinal, a = 0 ∨ 0 < a := eq_bot_or_bot_lt - theorem type_le_iff {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s] : type r ≤ type s ↔ Nonempty (r ≼i s) := Iff.rfl @@ -548,8 +534,6 @@ def ToType.mk {o : Ordinal} : Set.Iio o ≃o o.ToType where right_inv _ := enum_typein _ _ map_rel_iff' := enum_le_enum' _ -@[deprecated (since := "2025-12-04")] noncomputable alias enumIsoToType := ToType.mk - /-- Convert an element of `α.toType` to the corresponding `Ordinal` -/ abbrev ToType.toOrd {o : Ordinal} (α : o.ToType) : Set.Iio o := ToType.mk.symm α @@ -892,12 +876,6 @@ instance canonicallyOrderedAdd : CanonicallyOrderedAdd Ordinal where le_add_self a b := by simpa using add_le_add_left bot_le a le_self_add a b := by simpa using add_le_add_right bot_le a -@[deprecated le_self_add (since := "2025-11-21")] -protected theorem le_add_right (a b : Ordinal) : a ≤ a + b := le_self_add - -@[deprecated le_add_self (since := "2025-11-21")] -protected theorem le_add_left (a b : Ordinal) : a ≤ b + a := le_add_self - @[deprecated zero_max (since := "2026-05-07")] theorem max_zero_left : ∀ a : Ordinal, max 0 a = a := zero_max @@ -1413,5 +1391,3 @@ theorem List.SortedGT.lt_ord_of_lt [LinearOrder α] [WellFoundedLT α] {l m : Li | head as => exact List.head_le_of_lt hmltl | tail b hi => exact le_of_lt (lt_of_lt_of_le (List.rel_of_pairwise_cons hm.pairwise hi) (List.head_le_of_lt hmltl)) - -@[deprecated (since := "2025-11-27")] alias List.Sorted.lt_ord_of_lt := List.SortedGT.lt_ord_of_lt diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 69ffde62389d92..88c0412600f5fc 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -534,9 +534,6 @@ theorem iSup_pow_natCast {o : Ordinal} (ho : 0 < o) : ⨆ n : ℕ, o ^ n = o ^ · simpa using apply_omega0_of_isNormal (isNormal_opow ho₁) · simp -@[deprecated (since := "2025-12-25")] -alias iSup_pow := iSup_pow_natCast - @[simp, norm_cast] lemma natCast_log (m n : ℕ) : ↑(Nat.log m n) = Ordinal.log ↑m ↑n := by obtain hm | hm := le_or_gt m 1 diff --git a/Mathlib/SetTheory/Ordinal/Family.lean b/Mathlib/SetTheory/Ordinal/Family.lean index 6fb387982ff065..95daef9dcf4029 100644 --- a/Mathlib/SetTheory/Ordinal/Family.lean +++ b/Mathlib/SetTheory/Ordinal/Family.lean @@ -242,33 +242,6 @@ theorem unbounded_range_of_le_iSup {α β : Type u} (r : α → α → Prop) [Is (Ordinal.iSup_le fun y => ((typein_lt_typein r).2 <| hx _ <| mem_range_self y).le) (typein_lt_type r x) -@[deprecated Order.IsNormal.map_iSup (since := "2025-12-25")] -theorem IsNormal.map_iSup_of_bddAbove {f : Ordinal.{u} → Ordinal.{v}} (H : Ordinal.IsNormal f) - {ι : Type*} (g : ι → Ordinal.{u}) (hg : BddAbove (range g)) - [Nonempty ι] : f (⨆ i, g i) = ⨆ i, f (g i) := - Order.IsNormal.map_iSup H hg - -@[deprecated Order.IsNormal.map_iSup (since := "2025-12-25")] -theorem IsNormal.map_iSup {f : Ordinal.{u} → Ordinal.{v}} (H : Ordinal.IsNormal f) - {ι : Type w} (g : ι → Ordinal.{u}) [Small.{u} ι] [Nonempty ι] : - f (⨆ i, g i) = ⨆ i, f (g i) := - Order.IsNormal.map_iSup H bddAbove_of_small - -@[deprecated Order.IsNormal.map_sSup (since := "2025-12-25")] -theorem IsNormal.map_sSup_of_bddAbove {f : Ordinal.{u} → Ordinal.{v}} (H : Ordinal.IsNormal f) - {s : Set Ordinal.{u}} (hs : BddAbove s) (hn : s.Nonempty) : f (sSup s) = sSup (f '' s) := - Order.IsNormal.map_sSup H hn hs - -@[deprecated Order.IsNormal.map_sSup (since := "2025-12-25")] -theorem IsNormal.map_sSup {f : Ordinal.{u} → Ordinal.{v}} (H : IsNormal f) - {s : Set Ordinal.{u}} (hn : s.Nonempty) [Small.{u} s] : f (sSup s) = sSup (f '' s) := - Order.IsNormal.map_sSup H hn bddAbove_of_small - -@[deprecated Order.IsNormal.apply_of_isSuccLimit (since := "2025-12-25")] -theorem IsNormal.apply_of_isSuccLimit {f : Ordinal.{u} → Ordinal.{v}} (H : Ordinal.IsNormal f) - {o : Ordinal} (ho : IsSuccLimit o) : f o = ⨆ a : Iio o, f a := - Order.IsNormal.apply_of_isSuccLimit H ho - theorem sSup_ord (s : Set Cardinal) : (sSup s).ord = sSup (ord '' s) := by obtain rfl | hn := s.eq_empty_or_nonempty · simp @@ -882,11 +855,6 @@ theorem isNormal_iff_lt_succ_and_blsub_eq {f : Ordinal.{u} → Ordinal.{max u v} constructor <;> intro H o ho <;> have := H o ho <;> rwa [← bsup_eq_blsub_of_lt_succ_limit ho fun a _ => h a] at * -@[deprecated IsNormal.ext_iff (since := "2025-12-25")] -theorem IsNormal.eq_iff_zero_and_succ {f g : Ordinal.{u} → Ordinal.{u}} (hf : IsNormal f) - (hg : IsNormal g) : f = g ↔ f 0 = g 0 ∧ ∀ a, f a = g a → f (succ a) = g (succ a) := - Order.IsNormal.ext_iff hf hg - end blsub end Ordinal @@ -933,9 +901,6 @@ theorem apply_omega0_of_isNormal {f : Ordinal.{u} → Ordinal.{v}} (hf : IsNorma ⨆ n : ℕ, f n = f ω := by rw [← iSup_natCast, hf.map_iSup bddAbove_of_small] -@[deprecated (since := "2025-12-25")] -alias IsNormal.apply_omega0 := apply_omega0_of_isNormal - @[simp] theorem add_iSup (o : Ordinal.{u}) {ι} [Small.{u} ι] [Nonempty ι] (f : ι → Ordinal) : o + ⨆ i, f i = ⨆ i, o + f i := @@ -966,14 +931,8 @@ lemma mul_iSup (o : Ordinal) {ι} (f : ι → Ordinal) : o * ⨆ i, f i = ⨆ i, theorem iSup_add_natCast (o : Ordinal) : ⨆ n : ℕ, o + n = o + ω := by rw [← iSup_natCast, Ordinal.add_iSup] -@[deprecated (since := "2025-12-25")] -alias iSup_add_nat := iSup_add_natCast - @[simp] theorem iSup_mul_natCast (o : Ordinal) : ⨆ n : ℕ, o * n = o * ω := by rw [← iSup_natCast, Ordinal.mul_iSup] -@[deprecated (since := "2025-12-25")] -alias iSup_mul_nat := iSup_mul_natCast - end Ordinal diff --git a/Mathlib/SetTheory/Ordinal/FixedPoint.lean b/Mathlib/SetTheory/Ordinal/FixedPoint.lean index d7d7f98d60afe5..374961af0e9f5e 100644 --- a/Mathlib/SetTheory/Ordinal/FixedPoint.lean +++ b/Mathlib/SetTheory/Ordinal/FixedPoint.lean @@ -298,30 +298,18 @@ theorem apply_lt_nfp (H : IsNormal f) {a b} : f b < nfp f a ↔ b < nfp f a := b rw [← @apply_lt_nfpFamily_iff Unit (fun _ => f) _ _ (fun _ => H) a b] exact ⟨fun h _ => h, fun h => h Unit.unit⟩ -@[deprecated (since := "2025-12-25")] -alias IsNormal.apply_lt_nfp := apply_lt_nfp - theorem nfp_le_apply (H : IsNormal f) {a b} : nfp f a ≤ f b ↔ nfp f a ≤ b := le_iff_le_iff_lt_iff_lt.2 (apply_lt_nfp H) -@[deprecated (since := "2025-12-25")] -alias IsNormal.nfp_le_apply := nfp_le_apply - theorem nfp_le_fp (H : Monotone f) {a b} (ab : a ≤ b) (h : f b ≤ b) : nfp f a ≤ b := nfpFamily_le_fp (fun _ => H) ab fun _ => h theorem nfp_fp (H : IsNormal f) : ∀ a, f (nfp f a) = nfp f a := @nfpFamily_fp Unit (fun _ => f) _ () H -@[deprecated (since := "2025-12-25")] -alias IsNormal.nfp_fp := nfp_fp - theorem apply_le_nfp (H : IsNormal f) {a b} : f b ≤ nfp f a ↔ b ≤ nfp f a := ⟨H.strictMono.le_apply.trans, fun h => by simpa only [nfp_fp H] using H.monotone h⟩ -@[deprecated (since := "2025-12-25")] -alias IsNormal.apply_le_nfp := apply_le_nfp - theorem nfp_eq_self {a} (h : f a = a) : nfp f a = a := nfpFamily_eq_self fun _ => h diff --git a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean index 4c11897bc95496..c8a1d6e808134d 100644 --- a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean +++ b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean @@ -237,7 +237,4 @@ theorem IsFundamentalSequence.of_isNormal {f : Ordinal.{u} → Ordinal.{u}} (hf hg.2.2] exact IsNormal.blsub_eq.{u, u} hf ha -@[deprecated (since := "2025-12-25")] -alias IsNormal.isFundamentalSequence := IsFundamentalSequence.of_isNormal - end Ordinal diff --git a/Mathlib/SetTheory/Ordinal/Veblen.lean b/Mathlib/SetTheory/Ordinal/Veblen.lean index 8d6a66f96a7009..d05e6608d0e89a 100644 --- a/Mathlib/SetTheory/Ordinal/Veblen.lean +++ b/Mathlib/SetTheory/Ordinal/Veblen.lean @@ -90,9 +90,6 @@ theorem isNormal_veblenWith (o : Ordinal) : IsNormal (veblenWith f o) := by · rwa [veblenWith_zero] · exact isNormal_veblenWith' f h -@[deprecated (since := "2025-12-25")] -protected alias IsNormal.veblenWith := isNormal_veblenWith - theorem mem_range_veblenWith (h : o ≠ 0) : a ∈ range (veblenWith f o) ↔ ∀ b < o, veblenWith f b a = a := by rw [veblenWith_of_ne_zero f h, mem_range_derivFamily (fun _ ↦ isNormal_veblenWith hf _)] @@ -213,9 +210,6 @@ theorem isNormal_veblenWith_zero (hp : 0 < f 0) : IsNormal (veblenWith f · 0) : rw [lt_succ_iff] exact le_max_left _ b -@[deprecated (since := "2025-12-25")] -alias IsNormal.veblenWith_zero := isNormal_veblenWith_zero - theorem veblenWith_veblenWith_eq_veblenWith_iff (h : o₂ ≤ o₁) : veblenWith f o₁ (veblenWith f o₂ a) = veblenWith f o₂ a ↔ veblenWith f o₁ a = a := by grind [veblenWith_inj, → veblenWith_eq_self_of_le] diff --git a/Mathlib/Tactic/Basic.lean b/Mathlib/Tactic/Basic.lean index e5923542ac3500..405074ee98c5f1 100644 --- a/Mathlib/Tactic/Basic.lean +++ b/Mathlib/Tactic/Basic.lean @@ -114,16 +114,6 @@ where /-- Try calling `assumption` on all goals; succeeds if it closes at least one goal. -/ macro "assumption'" : tactic => `(tactic| any_goals assumption) -/-- Deprecated: use `guard_target =~ t` instead. -/ -@[deprecated "Use `guard_target =~` instead." (since := "2025-12-11")] -elab "match_target " t:term : tactic => do - logWarningAt t <| - m!"deprecation warning: replace `match_target {t}` with `guard_target =~ {t}`." - withMainContext do - let (val) ← elabTerm t (← inferType (← getMainTarget)) - if not (← isDefEq val (← getMainTarget)) then - throwError "failed" - /-- This tactic clears all auxiliary declarations from the context. -/ elab (name := clearAuxDecl) "clear_aux_decl" : tactic => withMainContext do let mut g ← getMainGoal diff --git a/Mathlib/Topology/Algebra/Algebra.lean b/Mathlib/Topology/Algebra/Algebra.lean index ba2b5f453e2f4f..7b4f51e59c150b 100644 --- a/Mathlib/Topology/Algebra/Algebra.lean +++ b/Mathlib/Topology/Algebra/Algebra.lean @@ -95,9 +95,6 @@ theorem coe_algebraMapCLM : ⇑(algebraMapCLM R A) = algebraMap R A := theorem toLinearMap_algebraMapCLM : (algebraMapCLM R A).toLinearMap = Algebra.linearMap R A := rfl -@[deprecated (since := "2025-12-05")] alias algebraMapCLM_toLinearMap := toLinearMap_algebraMapCLM -@[deprecated (since := "2025-12-05")] alias algebraMapCLM_coe := coe_algebraMapCLM - lemma ContinuousLinearMap.toSpanSingleton_one_eq_algebraMapCLM : toSpanSingleton R (M₁ := A) 1 = algebraMapCLM R A := by ext; simp diff --git a/Mathlib/Topology/Algebra/InfiniteSum/ConditionalInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/ConditionalInt.lean index 33c9e954f3a774..1398385623d06f 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/ConditionalInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/ConditionalInt.lean @@ -131,20 +131,12 @@ lemma _root_.HasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc {a : α} simpa [Pi.div_def, fun N : ℕ ↦ prod_Icc_eq_prod_Ico_mul f (show (-N : ℤ) ≤ N by lia)] using hf2 -@[deprecated (since := "2025-12-15")] -alias HasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc := - _root_.HasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc - @[to_additive] lemma multipliable_symmetricIco_of_multipliable_symmetricIcc (hf : Multipliable f (symmetricIcc ℤ)) (hf2 : Tendsto (fun N : ℕ ↦ (f N)⁻¹) atTop (𝓝 1)) : Multipliable f (symmetricIco ℤ) := (hf.hasProd.hasProd_symmetricIco_of_hasProd_symmetricIcc hf2).multipliable -@[deprecated (since := "2025-12-15")] -alias multipliable_symmetricIco_of_multiplible_symmetricIcc := - multipliable_symmetricIco_of_multipliable_symmetricIcc - @[to_additive] lemma tprod_symmetricIcc_eq_tprod_symmetricIco [T2Space α] (hf : Multipliable f (symmetricIcc ℤ)) (hf2 : Tendsto (fun N : ℕ ↦ (f N)⁻¹) atTop (𝓝 1)) : diff --git a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean index c689c6aa502fff..657bcee7088956 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean @@ -98,12 +98,6 @@ theorem HasProdUniformlyOn.tprod_eqOn [T2Space α] (h : HasProdUniformlyOn f g s s.EqOn (∏' b, f b ·) g := fun _ hx ↦ (h.hasProd hx).tprod_eq -@[deprecated (since := "2025-11-23")] -alias HasProdUniformlyOn.tprod_eq := HasProdUniformlyOn.tprod_eqOn - -@[deprecated (since := "2025-11-23")] -alias HasSumUniformlyOn.tsum_eq := HasSumUniformlyOn.tsum_eqOn - @[to_additive] theorem MultipliableUniformlyOn.multipliable (h : MultipliableUniformlyOn f s) (hx : x ∈ s) : Multipliable (f · x) := diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean index 19850c87fc323c..ed53c3f3e73580 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean @@ -726,8 +726,6 @@ theorem smulRight_comp_smulRight {M₃ : Type*} [AddCommMonoid M₃] [Module R ext simp -@[deprecated (since := "2025-12-18")] alias smulRight_comp := smulRight_comp_smulRight - theorem range_smulRight_apply {R : Type*} [DivisionSemiring R] [Module R M₁] [Module R M₂] [TopologicalSpace R] [ContinuousSMul R M₂] {f : M₁ →L[R] R} (hf : f ≠ 0) (x : M₂) : range (f.smulRight x : M₁ →ₗ[R] M₂) = Submodule.span R {x} := @@ -754,15 +752,11 @@ theorem toSpanSingleton_zero : toSpanSingleton R₁ (0 : M₁) = 0 := by ext; si theorem toSpanSingleton_apply_one (x : M₁) : toSpanSingleton R₁ x 1 = x := one_smul _ _ -@[deprecated (since := "2025-12-05")] alias toSpanSingleton_one := toSpanSingleton_apply_one - @[simp] theorem toSpanSingleton_apply_map_one (c : R₁ →L[R₁] M₂) : toSpanSingleton R₁ (c 1) = c := by ext simp [← ContinuousLinearMap.map_smul_of_tower] -@[deprecated (since := "2025-12-18")] alias smulRight_one_one := toSpanSingleton_apply_map_one - theorem toSpanSingleton_add [ContinuousAdd M₁] (x y : M₁) : toSpanSingleton R₁ (x + y) = toSpanSingleton R₁ x + toSpanSingleton R₁ y := coe_inj.mp <| LinearMap.toSpanSingleton_add _ _ @@ -778,9 +772,6 @@ theorem smulRight_one_eq_toSpanSingleton (x : M₁) : (1 : R₁ →L[R₁] R₁).smulRight x = toSpanSingleton R₁ x := rfl -@[deprecated (since := "2025-12-05")] alias one_smulRight_eq_toSpanSingleton := - smulRight_one_eq_toSpanSingleton - @[simp] theorem toLinearMap_toSpanSingleton (x : M₁) : (toSpanSingleton R₁ x).toLinearMap = LinearMap.toSpanSingleton R₁ M₁ x := rfl @@ -799,8 +790,6 @@ theorem toSpanSingleton_comp (f : M₁ →L[R₁] R₁) (g : M₂) : toSpanSingleton R₁ f = toSpanSingleton R₁ f' ↔ f = f' := by simp [ContinuousLinearMap.ext_ring_iff] -@[deprecated (since := "2025-12-18")] alias smulRight_one_eq_iff := toSpanSingleton_inj - theorem toSpanSingleton_comp_toSpanSingleton [ContinuousMul R₁] {x : M₂} {c : R₁} : (toSpanSingleton R₁ x) ∘L (toSpanSingleton R₁ c) = toSpanSingleton R₁ (c • x) := smulRight_comp_smulRight 1 1 @@ -922,8 +911,6 @@ theorem toSpanSingleton_pow [TopologicalSpace R] [IsTopologicalRing R] (c : R) ( | succ n ihn => rw [pow_succ, ihn, mul_def, toSpanSingleton_comp_toSpanSingleton, smul_eq_mul, pow_succ'] -@[deprecated (since := "2025-12-18")] alias smulRight_one_pow := toSpanSingleton_pow - end Ring section DivisionRing diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Idempotent.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Idempotent.lean index 75747bacd25b97..c71c38da9d1bff 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Idempotent.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Idempotent.lean @@ -97,11 +97,6 @@ theorem commute_iff_of_isUnit {f T : M →L[R] M} (hT : IsUnit T) simpa [Commute, SemiconjBy, Module.End.mul_eq_comp, ← toLinearMap_comp] using! LinearMap.IsIdempotentElem.commute_iff_of_isUnit this hf.toLinearMap -@[deprecated (since := "2025-12-27")] alias range_eq_ker := - LinearMap.IsIdempotentElem.range_eq_ker -@[deprecated (since := "2025-12-27")] alias ker_eq_range := - LinearMap.IsIdempotentElem.ker_eq_range - theorem isClosed_range [T1Space M] {p : M →L[R] M} (hp : IsIdempotentElem p) : IsClosed (p.range : Set M) := LinearMap.IsIdempotentElem.range_eq_ker hp.toLinearMap ▸ isClosed_ker (.id R M - p) diff --git a/Mathlib/Topology/Algebra/Module/Determinant.lean b/Mathlib/Topology/Algebra/Module/Determinant.lean index 3d284a22f66939..4e5bb0f7ed40cd 100644 --- a/Mathlib/Topology/Algebra/Module/Determinant.lean +++ b/Mathlib/Topology/Algebra/Module/Determinant.lean @@ -36,8 +36,6 @@ theorem det_smulRight {𝕜 : Type*} [CommRing 𝕜] [TopologicalSpace 𝕜] [Co theorem det_toSpanSingleton {𝕜 : Type*} [CommRing 𝕜] [TopologicalSpace 𝕜] [ContinuousMul 𝕜] (v : 𝕜) : (toSpanSingleton 𝕜 v).det = v := by rw [← smulRight_id, det_smulRight]; simp -@[deprecated (since := "2025-12-18")] alias det_one_smulRight := det_toSpanSingleton - end ContinuousLinearMap namespace ContinuousLinearEquiv diff --git a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean index a11feca50ce8b5..187f8f62f3f110 100644 --- a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean +++ b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean @@ -332,16 +332,6 @@ theorem det_toContinuousLinearMap (f : E →ₗ[𝕜] E) : (LinearMap.toContinuousLinearMap f).det = LinearMap.det f := rfl -@[deprecated coe_toContinuousLinearMap (since := "2025-12-23")] -theorem ker_toContinuousLinearMap (f : E →ₗ[𝕜] F') : - (LinearMap.toContinuousLinearMap f).ker = ker f := by - simp - -@[deprecated coe_toContinuousLinearMap (since := "2025-12-23")] -theorem range_toContinuousLinearMap (f : E →ₗ[𝕜] F') : - (LinearMap.toContinuousLinearMap f).range = range f := - rfl - /-- A surjective linear map `f` with finite-dimensional codomain is an open map. -/ theorem isOpenMap_of_finiteDimensional (f : F →ₗ[𝕜] E) (hf : Function.Surjective f) : IsOpenMap f := diff --git a/Mathlib/Topology/Category/UniformSpace.lean b/Mathlib/Topology/Category/UniformSpace.lean index 40982664016d45..bfc27e87c775f0 100644 --- a/Mathlib/Topology/Category/UniformSpace.lean +++ b/Mathlib/Topology/Category/UniformSpace.lean @@ -232,8 +232,6 @@ theorem extension_comp_hom {X : UniformSpaceCat} {Y : CpltSepUniformSpace} ext x exact congr_fun (Completion.extension_comp_coe f.hom.property) x -@[deprecated (since := "2025-12-18")] alias extension_comp_coe := extension_comp_hom - set_option backward.isDefEq.respectTransparency false in /-- The completion functor is left adjoint to the forgetful functor. -/ noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat := diff --git a/Mathlib/Topology/Compactification/OnePoint/Basic.lean b/Mathlib/Topology/Compactification/OnePoint/Basic.lean index ed57d3affd569b..7b11727c02f2f1 100644 --- a/Mathlib/Topology/Compactification/OnePoint/Basic.lean +++ b/Mathlib/Topology/Compactification/OnePoint/Basic.lean @@ -135,9 +135,6 @@ theorem range_coe_union_infty : range ((↑) : X → OnePoint X) ∪ {∞} = uni theorem insert_infty_range_coe : insert ∞ (range (@some X)) = univ := insert_none_range_some _ -@[deprecated "Use simp" (since := "2025-11-22")] -theorem range_coe_inter_infty : range ((↑) : X → OnePoint X) ∩ {∞} = ∅ := by simp - @[simp] theorem compl_range_coe : (range ((↑) : X → OnePoint X))ᶜ = {∞} := compl_range_some X diff --git a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean index 8ee7a7818b0865..f114cf07b1a555 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean @@ -277,9 +277,6 @@ instance [Inhabited β] : Inhabited (α →ᵇ β) := theorem lipschitz_eval_const (x : α) : LipschitzWith 1 fun f : α →ᵇ β => f x := LipschitzWith.mk_one fun _ _ => dist_coe_le_dist x -@[deprecated (since := "2025-11-29")] -alias lipschitz_evalx := lipschitz_eval_const - @[fun_prop] theorem uniformContinuous_coe : @UniformContinuous (α →ᵇ β) (α → β) _ _ (⇑) := uniformContinuous_pi.2 fun x => (lipschitz_eval_const x).uniformContinuous @@ -295,12 +292,6 @@ instance : ContinuousEval (α →ᵇ β) α β where /-- When `x` is fixed, `(f : α →ᵇ β) ↦ f x` is continuous. -/ instance : ContinuousEvalConst (α →ᵇ β) α β := inferInstance -@[deprecated (since := "2025-11-29")] protected alias continuous_eval_const := - ContinuousEvalConst.continuous_eval_const - -@[deprecated (since := "2025-11-29")] protected alias continuous_eval := - ContinuousEval.continuous_eval - /-- Bounded continuous functions taking values in a complete space form a complete space. -/ instance instCompleteSpace [CompleteSpace β] : CompleteSpace (α →ᵇ β) := complete_of_cauchySeq_tendsto fun (f : ℕ → α →ᵇ β) (hf : CauchySeq f) => by diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 2f829afc822bdb..2006d086f5c68a 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -539,7 +539,4 @@ theorem discreteTopology_iUnion_finite {ι : Type*} [Finite ι] {s : ι → Set simp only [← isDiscrete_iff_discreteTopology] at * exact .iUnion hs hs' -@[deprecated (since := "2025-11-28")] -alias discreteTopology_iUnion_fintype := discreteTopology_iUnion_finite - end discrete_union diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index d6bb44b3bfee66..812ea115341c92 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -460,9 +460,6 @@ lemma injective_path_homotopic_map (e₀ e₁ : E) : iterate 2 rw [Path.Homotopic.Quotient.eq] exact (cov.homotopicRel_iff_comp ⟨0, .inl rfl, γ₀.source.trans γ₁.source.symm⟩).mpr -@[deprecated (since := "2025-11-20")] -alias injective_path_homotopic_mapFn := injective_path_homotopic_map - /-- A continuous map `f` from a simply-connected, locally path-connected space `A` to another space `X` lifts uniquely through a covering map `p : E → X`, after specifying any lift `e₀ : E` of any point `a₀ : A`. -/ diff --git a/Mathlib/Topology/IsLocalHomeomorph.lean b/Mathlib/Topology/IsLocalHomeomorph.lean index 46a7c4376cbfe5..b68ee085e39d3c 100644 --- a/Mathlib/Topology/IsLocalHomeomorph.lean +++ b/Mathlib/Topology/IsLocalHomeomorph.lean @@ -254,8 +254,6 @@ noncomputable def toHomeomorphOfBijective (hf : IsLocalHomeomorph f) (hb : f.Bij X ≃ₜ Y := (Equiv.ofBijective f hb).toHomeomorphOfContinuousOpen hf.continuous hf.isOpenMap -@[deprecated (since := "2025-12-19")] alias toHomeomorph_of_bijective := toHomeomorphOfBijective - /-- Continuous local sections of a local homeomorphism are open embeddings. -/ theorem isOpenEmbedding_of_comp (hf : IsLocalHomeomorph g) (hgf : IsOpenEmbedding (g ∘ f)) (cont : Continuous f) : IsOpenEmbedding f := diff --git a/Mathlib/Topology/MetricSpace/Closeds.lean b/Mathlib/Topology/MetricSpace/Closeds.lean index 84b99c80909c4a..a99e197f1afe61 100644 --- a/Mathlib/Topology/MetricSpace/Closeds.lean +++ b/Mathlib/Topology/MetricSpace/Closeds.lean @@ -296,18 +296,6 @@ namespace EMetric open Metric -@[deprecated (since := "2025-11-19")] -alias NonemptyCompacts.continuous_toCloseds := - TopologicalSpace.NonemptyCompacts.continuous_toCloseds - -@[deprecated (since := "2025-11-19")] -alias NonemptyCompacts.isClosed_subsets_of_isClosed := - TopologicalSpace.NonemptyCompacts.isClosed_subsets_of_isClosed - -@[deprecated (since := "2025-11-19")] -alias Closeds.isClosed_subsets_of_isClosed := - TopologicalSpace.Closeds.isClosed_subsets_of_isClosed - @[deprecated (since := "2026-01-08")] alias mem_hausdorffEntourage_of_hausdorffEdist_lt := mem_hausdorffEntourage_of_hausdorffEDist_lt @@ -332,10 +320,6 @@ alias Closeds.lipschitz_sup := TopologicalSpace.Closeds.lipschitz_sup alias NonemptyCompacts.isometry_toCloseds := TopologicalSpace.NonemptyCompacts.isometry_toCloseds -@[deprecated (since := "2025-11-19")] -alias NonemptyCompacts.isUniformEmbedding_toCloseds := - TopologicalSpace.NonemptyCompacts.isUniformEmbedding_toCloseds - @[deprecated (since := "2026-01-08")] alias NonemptyCompacts.isClosed_in_closeds := TopologicalSpace.NonemptyCompacts.isClosed_in_closeds diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index 0204431e2fe0f3..d219092d8cfa98 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -1163,10 +1163,6 @@ theorem exists_embedding_to_hilbert_cube : ∃ F : X → ℕ → I, IsEmbedding (isUniformEmbedding_embed injective_distDenseSeq).isEmbedding exact ⟨_, isEmbedding_secondstep.comp firststep.isEmbedding⟩ -@[deprecated "This version is more general as compact metric spaces are separable" -(since := "2025-11-27")] alias -exists_closed_embedding_to_hilbert_cube := Metric.PiNatEmbed.exists_embedding_to_hilbert_cube - end MetricSpace end PiNatEmbed end Metric diff --git a/Mathlib/Topology/NoetherianSpace.lean b/Mathlib/Topology/NoetherianSpace.lean index 4444c3b1ee54c0..46e13727497905 100644 --- a/Mathlib/Topology/NoetherianSpace.lean +++ b/Mathlib/Topology/NoetherianSpace.lean @@ -212,12 +212,6 @@ theorem NoetherianSpace.exists_isOpen_nonempty_subset_irreducibleComponent [Noet rw [hZ, closure_empty, ← Set.nonempty_iff_empty_ne] exact H.1.nonempty -@[deprecated exists_isOpen_nonempty_subset_irreducibleComponent (since := "2025-12-11")] -theorem NoetherianSpace.exists_open_ne_empty_le_irreducibleComponent [NoetherianSpace α] - (Z : Set α) (H : Z ∈ irreducibleComponents α) : - ∃ o : Set α, IsOpen o ∧ o.Nonempty ∧ o ≤ Z := by - simpa using exists_isOpen_nonempty_subset_irreducibleComponent Z H - lemma NoetherianSpace.of_subset {W V : Set α} [NoetherianSpace W] (h : V ⊆ W) : NoetherianSpace V := Topology.IsInducing.noetherianSpace (Topology.IsEmbedding.inclusion h).isInducing diff --git a/Mathlib/Topology/Semicontinuity/Basic.lean b/Mathlib/Topology/Semicontinuity/Basic.lean index 989b1b661f0a15..25a093cc66f5aa 100644 --- a/Mathlib/Topology/Semicontinuity/Basic.lean +++ b/Mathlib/Topology/Semicontinuity/Basic.lean @@ -408,15 +408,6 @@ theorem Continuous.comp_lowerSemicontinuous_antitone {g : γ → δ} {f : α → (hf : LowerSemicontinuous f) (gmon : Antitone g) : UpperSemicontinuous (g ∘ f) := fun x => hg.continuousAt.comp_lowerSemicontinuousAt_antitone (hf x) gmon -@[deprecated (since := "2025-12-06")] -alias LowerSemicontinuousAt.comp_continuousAt := LowerSemicontinuousAt.comp - -@[deprecated (since := "2025-12-06")] -alias LowerSemicontinuousAt.comp_continuousAt_of_eq := LowerSemicontinuousAt.comp - -@[deprecated (since := "2025-12-06")] -alias LowerSemicontinuous.comp_continuous := LowerSemicontinuous.comp - end /-! #### Addition -/ @@ -1034,15 +1025,6 @@ theorem Continuous.comp_upperSemicontinuous_antitone {g : γ → δ} {f : α → variable [Preorder β] -@[deprecated (since := "2025-12-06")] -alias UpperSemicontinuousAt.comp_continuousAt := UpperSemicontinuousAt.comp - -@[deprecated (since := "2025-12-06")] -alias UpperSemicontinuousAt.comp_continuousAt_of_eq := UpperSemicontinuousAt.comp - -@[deprecated (since := "2025-12-06")] -alias UpperSemicontinuous.comp_continuous := UpperSemicontinuous.comp - end /-! #### Addition -/ diff --git a/Mathlib/Topology/Sequences.lean b/Mathlib/Topology/Sequences.lean index 2f4e07b6c7fd82..2825cddf51a682 100644 --- a/Mathlib/Topology/Sequences.lean +++ b/Mathlib/Topology/Sequences.lean @@ -413,13 +413,7 @@ only if it is sequentially compact. -/ theorem isCompact_iff_isSeqCompact : IsCompact s ↔ IsSeqCompact s := ⟨fun H => H.isSeqCompact, fun H => H.isCompact⟩ -@[deprecated (since := "2025-12-23")] -protected alias UniformSpace.isCompact_iff_isSeqCompact := isCompact_iff_isSeqCompact - theorem compactSpace_iff_seqCompactSpace : CompactSpace X ↔ SeqCompactSpace X := by simp only [← isCompact_univ_iff, seqCompactSpace_iff, isCompact_iff_isSeqCompact] -@[deprecated (since := "2025-12-23")] -protected alias UniformSpace.compactSpace_iff_seqCompactSpace := compactSpace_iff_seqCompactSpace - end MetrizableSpaceSeqCompact diff --git a/Mathlib/Topology/Sets/Closeds.lean b/Mathlib/Topology/Sets/Closeds.lean index 02f04161f319f8..49d759e8d5cb29 100644 --- a/Mathlib/Topology/Sets/Closeds.lean +++ b/Mathlib/Topology/Sets/Closeds.lean @@ -194,10 +194,6 @@ instance instCoframe : Coframe (Closeds α) := fast_instance% .ofMinimalAxioms c instance [T1Space α] : Singleton α (Closeds α) where singleton x := ⟨{x}, isClosed_singleton⟩ -/-- The term of `TopologicalSpace.Closeds α` corresponding to a singleton. -/ -@[deprecated "Use `{x}` instead" (since := "2025-11-23")] -abbrev singleton [T1Space α] (x : α) : Closeds α := {x} - @[simp] theorem mk_singleton [T1Space α] {x : α} : (⟨{x}, isClosed_singleton⟩ : Closeds α) = {x} := @@ -436,10 +432,6 @@ theorem coe_mk (s : Set α) (h : IsIrreducible s) (h' : IsClosed s) : (mk s h h' instance [T1Space α] : Singleton α (IrreducibleCloseds α) where singleton x := ⟨{x}, isIrreducible_singleton, isClosed_singleton⟩ -/-- The term of `TopologicalSpace.IrreducibleCloseds α` corresponding to a singleton. -/ -@[deprecated "Use `{x}` instead" (since := "2025-11-23")] -abbrev singleton [T1Space α] (x : α) : IrreducibleCloseds α := {x} - @[simp] theorem mk_singleton [T1Space α] {x : α} : (⟨{x}, isIrreducible_singleton, isClosed_singleton⟩ : IrreducibleCloseds α) = {x} := diff --git a/Mathlib/Topology/UniformSpace/Closeds.lean b/Mathlib/Topology/UniformSpace/Closeds.lean index 9306374ea70f17..31a020be6fbe21 100644 --- a/Mathlib/Topology/UniformSpace/Closeds.lean +++ b/Mathlib/Topology/UniformSpace/Closeds.lean @@ -166,8 +166,6 @@ theorem _root_.IsClosed.powerset_hausdorff {F : Set α} (hF : IsClosed F) : simp_rw [Set.powerset, ← isOpen_compl_iff, Set.compl_setOf, ← Set.inter_compl_nonempty_iff] exact isOpen_inter_nonempty_of_isOpen hF.isOpen_compl -@[deprecated (since := "2025-11-23")] alias isClosed_powerset := IsClosed.powerset_hausdorff - theorem isClopen_singleton_empty : IsClopen {(∅ : Set α)} := by constructor · rw [← Set.powerset_empty] diff --git a/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean b/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean index e9e3813a70882c..b9de3393d2bba1 100644 --- a/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean +++ b/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean @@ -39,15 +39,9 @@ theorem _root_.discreteUniformity_iff_eq_principal_setRelId {X : Type*} [Uniform DiscreteUniformity X ↔ uniformity X = 𝓟 SetRel.id := by rw [discreteUniformity_iff_eq_bot, UniformSpace.ext_iff, Filter.ext_iff, bot_uniformity] -@[deprecated (since := "2025-12-19")] -alias _root_.discreteUniformity_iff_eq_principal_relId := - _root_.discreteUniformity_iff_eq_principal_setRelId - theorem eq_principal_setRelId : uniformity X = 𝓟 SetRel.id := discreteUniformity_iff_eq_principal_setRelId.mp inferInstance -@[deprecated (since := "2025-12-19")] alias eq_principal_relId := eq_principal_setRelId - /-- The discrete uniformity induces the discrete topology. -/ instance : DiscreteTopology X where eq_bot := by @@ -57,10 +51,6 @@ theorem _root_.discreteUniformity_iff_setRelId_mem_uniformity {X : Type*} [Unifo DiscreteUniformity X ↔ SetRel.id ∈ uniformity X := by rw [← uniformSpace_eq_bot, discreteUniformity_iff_eq_bot] -@[deprecated (since := "2025-12-19")] -alias _root_.discreteUniformity_iff_relId_mem_uniformity := - _root_.discreteUniformity_iff_setRelId_mem_uniformity - theorem relId_mem_uniformity : SetRel.id ∈ uniformity X := discreteUniformity_iff_setRelId_mem_uniformity.mp inferInstance From 5e638355928523b79dc193b1dc146ae143e50af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Wed, 15 Jul 2026 17:25:17 +0000 Subject: [PATCH 0808/1300] feat(Topology/Sets): separability of `(Nonempty)Compacts` (#40109) --- Mathlib/Topology/Sets/VietorisTopology.lean | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index b2feab21cf604d..0e37beec6b55e1 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -659,6 +659,24 @@ instance [LocallyCompactSpace α] : LocallyCompactSpace (Compacts α) := by vietoris.specializes_of_subset_closure ?_ ?_⟩ <;> grind [coe_mk, subset_closure] +instance [SeparableSpace α] : SeparableSpace (Compacts α) := by + obtain ⟨s, hs₁, hs₂⟩ := exists_countable_dense α + refine ⟨_, (countable_setOf_finite_subset hs₁).preimage SetLike.coe_injective, ?_⟩ + simp [dense_iff_closure_eq, closure_finite_subsets, hs₂.closure_eq] + +@[simp] +theorem separableSpace_iff : SeparableSpace (Compacts α) ↔ SeparableSpace α := by + refine ⟨fun _ => ?_, fun _ => inferInstance⟩ + cases isEmpty_or_nonempty α + · infer_instance + obtain ⟨s, hs₁, hs₂⟩ := exists_countable_dense (Compacts α) + refine ⟨(fun K => Classical.epsilon (· ∈ K)) '' s, hs₁.image _, + dense_iff_inter_open.mpr fun U hU ⟨x, hx⟩ => ?_⟩ + obtain ⟨K, ⟨hK₁, hK₂⟩, hK₃⟩ := hs₂.inter_open_nonempty _ + ((isOpen_subsets_of_isOpen hU).inter (isOpen_inter_nonempty_of_isOpen hU)) ⟨{x}, by simpa⟩ + refine ⟨Classical.epsilon (· ∈ K), ?_, mem_image_of_mem _ hK₃⟩ + exact hK₁ <| Classical.epsilon_spec (hK₂.mono inter_subset_left) + end Compacts namespace NonemptyCompacts @@ -900,6 +918,16 @@ theorem _root_.TopologicalSpace.Compacts.locallyCompactSpace_iff : ⟨fun _ => NonemptyCompacts.locallyCompactSpace_iff.mp isOpenEmbedding_toCompacts.locallyCompactSpace, fun _ => inferInstance⟩ +instance [SeparableSpace α] : SeparableSpace (NonemptyCompacts α) := + isOpenEmbedding_toCompacts.separableSpace + +@[simp] +theorem separableSpace_iff : SeparableSpace (NonemptyCompacts α) ↔ SeparableSpace α := by + refine ⟨fun _ => ?_, fun _ => inferInstance⟩ + rw [← Compacts.separableSpace_iff, ← isSeparable_univ_iff, ← union_compl_self {⊥}, + ← range_toCompacts] + exact (finite_singleton _).isSeparable.union (isSeparable_range continuous_toCompacts) + end NonemptyCompacts end TopologicalSpace From 805e37bcd56717e0be3ca2cbc4117e5e5590460f Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 15 Jul 2026 21:15:53 +0000 Subject: [PATCH 0809/1300] feat(PowerSeries): pentagonal number theorem (#33143) The proof is split in two files: `Mathlib/Combinatorics/Enumerative/Ring.lean` for the algebraic part, and `Mathlib/Combinatorics/Enumerative/PowerSeries.lean` for the summability part. In the near future, I also plan to prove the real/complex version that branches off from the algebraic part. --- Mathlib.lean | 4 +- .../Basic.lean} | 5 - .../Enumerative/Pentagonal/PowerSeries.lean | 184 ++++++++++++++++++ .../Enumerative/Pentagonal/Ring.lean | 164 ++++++++++++++++ Mathlib/RingTheory/Nilpotent/Basic.lean | 8 + docs/1000.yaml | 2 +- 6 files changed, 360 insertions(+), 7 deletions(-) rename Mathlib/Combinatorics/Enumerative/{Pentagonal.lean => Pentagonal/Basic.lean} (95%) create mode 100644 Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean create mode 100644 Mathlib/Combinatorics/Enumerative/Pentagonal/Ring.lean diff --git a/Mathlib.lean b/Mathlib.lean index b77bb17d48d817..31cbd4c6482732 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3561,7 +3561,9 @@ public import Mathlib.Combinatorics.Enumerative.InclusionExclusion public import Mathlib.Combinatorics.Enumerative.Partition.Basic public import Mathlib.Combinatorics.Enumerative.Partition.GenFun public import Mathlib.Combinatorics.Enumerative.Partition.Glaisher -public import Mathlib.Combinatorics.Enumerative.Pentagonal +public import Mathlib.Combinatorics.Enumerative.Pentagonal.Basic +public import Mathlib.Combinatorics.Enumerative.Pentagonal.PowerSeries +public import Mathlib.Combinatorics.Enumerative.Pentagonal.Ring public import Mathlib.Combinatorics.Enumerative.Schroder public import Mathlib.Combinatorics.Enumerative.Stirling public import Mathlib.Combinatorics.Extremal.RuzsaSzemeredi diff --git a/Mathlib/Combinatorics/Enumerative/Pentagonal.lean b/Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean similarity index 95% rename from Mathlib/Combinatorics/Enumerative/Pentagonal.lean rename to Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean index 5e5b97ceeadb34..fabec9d4e950a3 100644 --- a/Mathlib/Combinatorics/Enumerative/Pentagonal.lean +++ b/Mathlib/Combinatorics/Enumerative/Pentagonal/Basic.lean @@ -21,11 +21,6 @@ convention, but implicitly shows the monotonicity in `pentagonal_lt_pentagonal_n * `pentagonal`: pentagonal numbers as a function `ℤ → ℕ`. -## TODO - -Show the relation between pentagonal numbers and partitions, including the pentagonal number -theorem. - ## References * https://en.wikipedia.org/wiki/Pentagonal_number diff --git a/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean b/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean new file mode 100644 index 00000000000000..8a72260798fcdf --- /dev/null +++ b/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean @@ -0,0 +1,184 @@ +/- +Copyright (c) 2025 Weiyi Wang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Weiyi Wang +-/ +module + +public import Mathlib.Algebra.Ring.NegOnePow +public import Mathlib.Combinatorics.Enumerative.Pentagonal.Basic +public import Mathlib.RingTheory.PowerSeries.PiTopology + +import Mathlib.Combinatorics.Enumerative.Pentagonal.Ring +import Mathlib.RingTheory.Nilpotent.Basic + +/-! +# Pentagonal number theorem for power series + +This file proves the pentagonal number theorem for power series: + +$$ \prod_{n = 0}^{\infty} (1 - x^{n + 1}) = \sum_{k=-\infty}^{\infty} (-1)^k x^{a_k} $$ + +where $a_k = k(3k - 1)/2$ are the pentagonal numbers. We state the theorem in two parts by +introducing the intermediate power series `PowerSeries.pentagonalSeries`, whose coefficients are +defined using pentagonal numbers. We then show that this series is equal to both sides. + +## Main theorems + +* `PowerSeries.WithPiTopology.hasProd_one_sub_X_pow`: `PowerSeries.pentagonalSeries` is equal to + infinite product on the left-hand side of the formula. +* `PowerSeries.coeff_prod_one_sub_X_pow_eventually_eq` restates the left-hand side without requiring + topology. +* `PowerSeries.WithPiTopology.hasSum_pentagonalSeries`: `PowerSeries.pentagonalSeries` is equal to + the infinite sum on the right-hand side of the formula. +* `PowerSeries.coeff_pentagonalSeries` restates the right-hand side without requiring topology. +-/ + +open Filter PowerSeries WithPiTopology Topology +variable (R : Type*) [CommRing R] + +namespace Pentagonal +-- private auxiliary lemma + +theorem tendsto_order_pow_mul_prod_one_sub_pow (k : ℕ) : + Tendsto (fun n ↦ (X ^ ((k + 1) * n) * + ∏ i ∈ Finset.range (n + 1), (1 - X ^ (k + i + 1)) : R⟦X⟧).order) atTop (𝓝 ⊤) := by + nontriviality R using Subsingleton.eq_zero + refine ENat.tendsto_nhds_top_iff_natCast_lt.mpr fun n ↦ eventually_atTop.mpr ⟨n + 1, ?_⟩ + intro m hm + grw [← le_order_mul, order_X_pow] + refine lt_add_of_lt_of_nonneg ?_ (by simp) + norm_cast + grind + +theorem tendsto_order_neg_X_pow (k : ℕ) : + Tendsto (fun i ↦ (-(X : R⟦X⟧) ^ (i + k + 1)).order) atTop (𝓝 ⊤) := by + nontriviality R using Subsingleton.eq_zero + simp_rw [order_neg, order_X_pow, add_assoc] + exact ENat.tendsto_natCast_nhds_top.comp (tendsto_add_atTop_nat _) + +variable [TopologicalSpace R] + +theorem summable_pow_mul_prod_one_sub_pow (k : ℕ) : + Summable + fun n ↦ (X ^ ((k + 1) * n) * ∏ i ∈ Finset.range (n + 1), (1 - X ^ (k + i + 1)) : R⟦X⟧) := + summable_of_tendsto_order_atTop_nhds_top R (tendsto_order_pow_mul_prod_one_sub_pow R k) + +theorem multipliable_one_sub_X_pow (k : ℕ) : Multipliable fun n ↦ (1 : R⟦X⟧) - X ^ (n + k + 1) := by + simpa [sub_eq_add_neg] using + multipliable_one_add_of_tendsto_order_atTop_nhds_top R (tendsto_order_neg_X_pow R k) + +end Pentagonal + +public section Public +namespace PowerSeries + +open Classical in +/-- The power series $\sum_{k=-\infty}^{\infty}(-1)^k x^{k * (3k - 1) / 2}$. -/ +noncomputable +def pentagonalSeries : R⟦X⟧ := + .mk fun n ↦ if h : ∃ k, pentagonal k = n then + Int.negOnePow h.choose + else + 0 + +theorem coeff_pentagonalSeries_eq_zero {n : ℕ} (h : n ∉ Set.range pentagonal) : + (pentagonalSeries R).coeff n = 0 := dif_neg <| by simpa using h + +@[simp] +theorem coeff_pentagonalSeries_pentagonal (k : ℤ) : + (pentagonalSeries R).coeff (pentagonal k) = Int.negOnePow k := by + simp [pentagonalSeries] + +@[simp] +theorem coeff_pentagonalSeries_eq_zero_iff [Nontrivial R] {n : ℕ} : + (pentagonalSeries R).coeff n = 0 ↔ n ∉ Set.range pentagonal := by + grind [pentagonalSeries, coeff_mk, neg_one_pow_ne_zero, Int.coe_negOnePow] + +namespace WithPiTopology +variable [TopologicalSpace R] + +/-- `PowerSeries.pentagonalSeries` as an infinite sum over integers -/ +theorem hasSum_pentagonalSeries : + HasSum (fun k : ℤ ↦ (Int.negOnePow k : R⟦X⟧) * X ^ pentagonal k) (pentagonalSeries R) := by + suffices HasSum ((fun n ↦ C ((pentagonalSeries R).coeff n) * X ^ n) ∘ pentagonal) + (pentagonalSeries R) by + convert this + simp + rw [pentagonal_injective.hasSum_iff fun n hn ↦ by simp [coeff_pentagonalSeries_eq_zero R hn]] + simpa [monomial_eq_C_mul_X_pow] using (pentagonalSeries R).hasSum_of_monomials_self + +theorem pentagonalSeries_eq_tsum [T2Space R] : + pentagonalSeries R = ∑' k, (Int.negOnePow k : R⟦X⟧) * X ^ pentagonal k := + (hasSum_pentagonalSeries R).tsum_eq.symm + +/-- `PowerSeries.pentagonalSeries` as an infinite sum over natural numbers. In this version, terms +are ordered by strictly increasing exponent `pentagonal k` for `k = 0, 1, -1, 2, -2, 3, ...`, +and every two terms are grouped together. -/ +theorem hasSum_pow_pentagonal_sub_pentagonalSeries : + HasSum (fun k : ℕ ↦ (-1) ^ k * (X ^ pentagonal (-k) - X ^ pentagonal (k + 1))) + (pentagonalSeries R) := by + have h := hasSum_pentagonalSeries R + rw [← neg_injective.hasSum_iff (fun x hx ↦ by absurd hx; use -x; simp)] at h + convert h.nat_add_neg_add_one using 2 with k + simp_rw [Function.comp_apply, neg_neg, Int.negOnePow_add] + simp + ring + +theorem pentagonalSeries_eq_tsum_pow_pentagonal_sub [T2Space R] : + pentagonalSeries R = ∑' (k : ℕ), (-1) ^ k * (X ^ pentagonal (-k) - X ^ pentagonal (k + 1)) := + (hasSum_pow_pentagonal_sub_pentagonalSeries R).tsum_eq.symm + +/-- See the public version `PowerSeries.WithPiTopology.tprod_one_sub_X_pow` that removes +`IsTopologicalRing`. -/ +private theorem tprod_one_sub_X_pow' [IsTopologicalRing R] [T2Space R] : + ∏' n, (1 - X ^ (n + 1) : R⟦X⟧) = pentagonalSeries R := by + nontriviality R + rw [pentagonalSeries_eq_tsum_pow_pentagonal_sub] + refine Pentagonal.tprod_one_sub_pow ?_ ?_ ?_ ?_ ?_ + · rw [IsTopologicallyNilpotent, tendsto_iff_coeff_tendsto] + refine fun d ↦ tendsto_atTop_of_eventually_const fun i (hi : i ≥ d + 1) ↦ ?_ + grind + · exact Pentagonal.summable_pow_mul_prod_one_sub_pow R + · exact Pentagonal.multipliable_one_sub_X_pow R + · exact (hasSum_pow_pentagonal_sub_pentagonalSeries R).summable + · rw [tendsto_iff_coeff_tendsto] + refine fun n ↦ tendsto_atTop_of_eventually_const fun k (hk : k ≥ n) ↦ ?_ + rw [map_zero] + apply coeff_of_lt_order + grw [← le_order_mul, ← le_order_mul] + refine (lt_add_of_lt_of_nonneg (lt_add_of_nonneg_of_lt (by simp) ?_) (by simp)) + rw [order_X_pow, Nat.cast_lt, ← Nat.add_one_le_iff, Nat.le_div_iff_mul_le (by simp)] + apply Nat.mul_le_mul <;> linarith + +end WithPiTopology + +/-- **Pentagonal number theorem** for power series, expressed as the statement that the coefficients +of the product `∏ n, 1 - X ^ (n + 1)` are eventually constants as `(pentagonalSeries R).coeff`. -/ +theorem coeff_prod_one_sub_X_pow_eventually_eq (n : ℕ) : + ∀ᶠ s in atTop, (∏ n ∈ s, (1 - X ^ (n + 1) : R⟦X⟧)).coeff n = (pentagonalSeries R).coeff n := by + let : TopologicalSpace R := ⊥ + have : DiscreteTopology R := ⟨rfl⟩ + have h := (multipliable_one_sub_X_pow R).hasProd + rw [tprod_one_sub_X_pow' R, HasProd, tendsto_iff_coeff_tendsto] at h + simpa using h n + +namespace WithPiTopology +variable [TopologicalSpace R] + +/-- **Pentagonal number theorem** for power series, expressed as an infinite product. See also +`PowerSeries.WithPiTopology.hasSum_pentagonalSeries` that expresses `pentagonalSeries` as an +infinite sum. -/ +theorem hasProd_one_sub_X_pow : + HasProd (fun n ↦ (1 - X ^ (n + 1) : R⟦X⟧)) (pentagonalSeries R) := by + rw [HasProd, tendsto_iff_coeff_tendsto] + intro n + apply tendsto_nhds_of_eventually_eq + simpa using coeff_prod_one_sub_X_pow_eventually_eq R n + +theorem tprod_one_sub_X_pow [T2Space R] : ∏' n, (1 - X ^ (n + 1) : R⟦X⟧) = pentagonalSeries R := + (hasProd_one_sub_X_pow R).tprod_eq + +end WithPiTopology +end PowerSeries +end Public diff --git a/Mathlib/Combinatorics/Enumerative/Pentagonal/Ring.lean b/Mathlib/Combinatorics/Enumerative/Pentagonal/Ring.lean new file mode 100644 index 00000000000000..ed47906b59c1fa --- /dev/null +++ b/Mathlib/Combinatorics/Enumerative/Pentagonal/Ring.lean @@ -0,0 +1,164 @@ +/- +Copyright (c) 2025 Weiyi Wang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Weiyi Wang +-/ +module + +public import Mathlib.Combinatorics.Enumerative.Pentagonal.Basic +public import Mathlib.Topology.Algebra.InfiniteSum.Ring +public import Mathlib.Topology.Algebra.TopologicallyNilpotent + +/-! +# Pentagonal number theorem + +This is an intermediate file that proves the pentagonal number theorem in a general topological ring +modulo summability and multipliability. The complete proof for formal power series is in +`Mathlib/RingTheory/PowerSeries/Pentagonal.lean`. TODO: also prove for real/complex numbers. + +## Declarations + +* `Pentagonal.tprod_one_sub_pow`: pentagonal number theorem with a few summability and + multipliability assumptions. + +## References + +https://math.stackexchange.com/questions/55738/how-to-prove-eulers-pentagonal-theorem-some-hints-will-help + +-/ + +namespace Pentagonal +open Filter Topology +variable {R : Type*} [CommRing R] + +/-- +We define an auxiliary sequence + +$$ a_{k, n} = x^{(k+1)n} \prod_{i=0}^{n} (1 - x^{k + i + 1}) $$ + +We will also use its sum + +$$ A_k = \sum_{n=0}^{\infty} a_{k, n} $$ -/ +def powMulProdOneSubPow (k n : ℕ) (x : R) : R := + x ^ ((k + 1) * n) * ∏ i ∈ Finset.range (n + 1), (1 - x ^ (k + i + 1)) + +/-- And a second auxiliary sequence + +$$ b_{k, n} = x^{(k+1)n} (x^{2k + n + 3} - 1) \prod_{i=0}^{n-1} (1 - x^{k + i + 2}) $$ -/ +def aux (k n : ℕ) (x : R) : R := + x ^ ((k + 1) * n) * (x ^ (2 * k + n + 3) - 1) * ∏ i ∈ Finset.range n, (1 - x ^ (k + i + 2)) + +/-- `powMulProdOneSubPow` and `aux` have relation + +$$ a_{k,n} + x^{3k + 5}a_{k + 1, n} = b_{k, n+1} - b_{k, n} $$ -/ +theorem aux_sub_aux (k n : ℕ) (x : R) : + powMulProdOneSubPow k n x + x ^ (3 * k + 5) * powMulProdOneSubPow (k + 1) n x = + aux k (n + 1) x - aux k n x := by + simp_rw [aux, Finset.prod_range_succ, powMulProdOneSubPow] + rw [Finset.prod_range_succ', Finset.prod_range_succ] + ring_nf + +variable [TopologicalSpace R] [IsTopologicalRing R] [T2Space R] + +/-- By summing with telescoping, we get a recurrence formula for $A$ + +$$ A_k = 1 - x^{2k + 3} - x^{3k + 5}A_{k + 1} $$ +-/ +theorem tsum_powMulProdOneSubPow (k : ℕ) {x : R} (hx : IsTopologicallyNilpotent x) + (hsum : ∀ k, Summable (powMulProdOneSubPow k · x)) + (h : ∀ k, Multipliable (fun n ↦ 1 - x ^ (n + k + 1))) : + ∑' n, powMulProdOneSubPow k n x = + 1 - x ^ (2 * k + 3) - x ^ (3 * k + 5) * ∑' n, powMulProdOneSubPow (k + 1) n x := by + rw [eq_sub_iff_add_eq, show 1 - x ^ (2 * k + 3) = 0 - aux k 0 x by simp [aux]] + rw [← (hsum _).tsum_mul_left, ← (hsum _).tsum_add ((hsum _).mul_left _)] + apply HasSum.tsum_eq + rw [((hsum _).add ((hsum _).mul_left _)).hasSum_iff_tendsto_nat] + simp_rw [aux_sub_aux, Finset.sum_range_sub (aux k · x)] + apply Tendsto.sub_const + rw [show 𝓝 0 = 𝓝 (0 * (0 - 1) * ∏' i, (1 - x ^ (k + i + 2))) by simp] + refine (Tendsto.mul ?_ ?_).mul ?_ + · exact hx.comp (strictMono_mul_left_of_pos (by simp)).tendsto_atTop + · exact (hx.comp (add_right_strictMono.add_monotone monotone_const).tendsto_atTop).sub_const _ + · apply Multipliable.tendsto_prod_tprod_nat + convert h (k + 1) using 4 + ring + +/-- The Euler function is related to $A_0$ by + +$$ \prod_{n = 0}^{\infty} (1 - x^{n + 1}) = 1 - x - x^2 A_0 $$ -/ +theorem tprod_one_sub_pow_eq_powMulProdOneSubPow_zero {x : R} + (hsum : ∀ k, Summable (powMulProdOneSubPow k · x)) + (h : ∀ k, Multipliable fun n ↦ 1 - x ^ (n + k + 1)) : + ∏' n, (1 - x ^ (n + 1)) = 1 - x - x ^ 2 * ∑' n, powMulProdOneSubPow 0 n x := by + have hsum := hsum 0 + simp_rw [powMulProdOneSubPow, zero_add, one_mul] at hsum + have hsum' : Summable fun i ↦ x ^ (i + 1) * ∏ n ∈ Finset.range i, (1 - x ^ (n + 1)) := by + apply Summable.comp_nat_add (k := 1) + conv in fun k ↦ _ => + ext k + rw [pow_add, pow_add, mul_assoc (x ^ k), mul_comm (x ^ k), mul_assoc (x ^ 1 * x ^ 1)] + exact hsum.mul_left _ + rw [tprod_one_sub_ordered (by simpa [Nat.Iio_eq_range] using hsum') (by simpa using h 0)] + simp_rw [Nat.Iio_eq_range, sub_sub, sub_right_inj, hsum'.tsum_eq_zero_add] + conv in fun k ↦ x ^ (k + 1 + 1) * _ => + ext k + rw [pow_add, pow_add, mul_assoc (x ^ k), mul_comm (x ^ k), + ← pow_add x 1 1, one_add_one_eq_two, mul_assoc (x ^ 2)] + simp [hsum.tsum_mul_left, powMulProdOneSubPow] + +/-- Applying the recurrence formula repeatedly, we get + +$$ \prod_{n = 0}^{\infty} (1 - x^{n + 1}) = +\left(\sum_{k=0}^{j} (-1)^k \left(x^{k(3k+1)/2} - x^{(k+1)(3k+2)/2}\right) \right) + +(-1)^{j+1}x^{(j+1)(3j+4)/2}A_j $$ -/ +theorem tprod_one_sub_pow_eq_powMulProdOneSubPow (j : ℕ) {x : R} (hx : IsTopologicallyNilpotent x) + (hsum : ∀ k, Summable (powMulProdOneSubPow k · x)) + (h : ∀ k, Multipliable (fun n ↦ 1 - x ^ (n + k + 1))) : + ∏' n, (1 - x ^ (n + 1)) = ∑ k ∈ Finset.range (j + 1), + (-1) ^ k * (x ^ (k * (3 * k + 1) / 2) - x ^ ((k + 1) * (3 * k + 2) / 2)) + + (-1) ^ (j + 1) * x ^ ((j + 1) * (3 * j + 4) / 2) * ∑' n, powMulProdOneSubPow j n x := by + induction j with + | zero => + simp [tprod_one_sub_pow_eq_powMulProdOneSubPow_zero hsum h, powMulProdOneSubPow, + ← sub_eq_add_neg] + | succ n ih => + rw [ih, tsum_powMulProdOneSubPow _ hx hsum h, Finset.sum_range_succ _ (n + 1)] + have h (n) : (n + 1 + 1) * (3 * (n + 1) + 2) / 2 = + (n + 1) * (3 * n + 4) / 2 + (2 * n + 3) := by + rw [← Nat.add_mul_div_left _ _ (by simp)] + ring_nf + simp_rw [h] + have h (n) : (n + 1 + 1) * (3 * (n + 1) + 4) / 2 = + (n + 1) * (3 * n + 4) / 2 + (3 * n + 5) := by + rw [← Nat.add_mul_div_left _ _ (by simp)] + ring_nf + simp_rw [h] + ring_nf + +/-- **Pentagonal number theorem**, assuming appropriate multipliability and summability. + +$$ \prod_{n = 0}^{\infty} (1 - x^{n + 1}) = +\sum_{k=0}^{\infty} (-1)^k \left(x^{k(3k+1)/2} - x^{(k+1)(3k+2)/2}\right) $$ -/ +public theorem tprod_one_sub_pow {x : R} (hx : IsTopologicallyNilpotent x) + (hsum : ∀ k, Summable + (fun n ↦ x ^ ((k + 1) * n) * ∏ i ∈ Finset.range (n + 1), (1 - x ^ (k + i + 1)))) + (hlhs : ∀ k, Multipliable (fun n ↦ 1 - x ^ (n + k + 1))) + (hrhs : Summable fun k : ℕ ↦ + (-1) ^ k * (x ^ pentagonal (-k) - x ^ pentagonal (k + 1))) + (htail : Tendsto (fun k ↦ (-1) ^ (k + 1) * x ^ ((k + 1) * (3 * k + 4) / 2) * + ∑' (n : ℕ), x ^ ((k + 1) * n) * ∏ i ∈ Finset.range (n + 1), (1 - x ^ (k + i + 1))) + atTop (𝓝 0)) : + ∏' n, (1 - x ^ (n + 1)) = + ∑' (k : ℕ), (-1) ^ k * (x ^ pentagonal (-k) - x ^ pentagonal (k + 1)) := by + have h := fun n ↦ tprod_one_sub_pow_eq_powMulProdOneSubPow n hx hsum hlhs + simp_rw [← sub_eq_iff_eq_add] at h + refine (HasSum.tsum_eq ?_).symm + rw [hrhs.hasSum_iff_tendsto_nat, (map_add_atTop_eq_nat 1).symm] + apply tendsto_map' + have h1 (k : ℕ) : pentagonal (k + 1) = ((k + 1) * (3 * k + 2) / 2) := by grind [pentagonal_def] + have h2 (k : ℕ) : pentagonal (-k) = (k * (3 * k + 1) / 2) := by grind [pentagonal_neg] + simp_rw [h1, h2, Function.comp_def, ← h] + rw [← tendsto_sub_nhds_zero_iff] + simpa [powMulProdOneSubPow] using htail.neg + +end Pentagonal diff --git a/Mathlib/RingTheory/Nilpotent/Basic.lean b/Mathlib/RingTheory/Nilpotent/Basic.lean index d373352c32d105..873ee88550945c 100644 --- a/Mathlib/RingTheory/Nilpotent/Basic.lean +++ b/Mathlib/RingTheory/Nilpotent/Basic.lean @@ -44,6 +44,14 @@ theorem IsNilpotent.neg [Ring R] (h : IsNilpotent x) : IsNilpotent (-x) := by use n rw [neg_pow, hn, mul_zero] +theorem not_isNilpotent_neg_one [Ring R] [Nontrivial R] : ¬ IsNilpotent (-1 : R) := by + intro h + simpa [not_isNilpotent_one] using h.neg + +theorem neg_one_pow_ne_zero [Ring R] [Nontrivial R] (n : ℕ) : (-1 : R) ^ n ≠ 0 := by + intro h + exact not_isNilpotent_neg_one ⟨n, h⟩ + @[simp] theorem isNilpotent_neg_iff [Ring R] : IsNilpotent (-x) ↔ IsNilpotent x := ⟨fun h => neg_neg x ▸ h.neg, fun h => h.neg⟩ diff --git a/docs/1000.yaml b/docs/1000.yaml index 3b3cef90ecd4b2..a5dda2cc4d3a59 100644 --- a/docs/1000.yaml +++ b/docs/1000.yaml @@ -323,7 +323,7 @@ Q282331: Q282649: title: Pentagonal number theorem - url: https://github.com/wwylele/PentagonalNumberTheorem + decl: PowerSeries.WithPiTopology.hasProd_one_sub_X_pow authors: Weiyi Wang comment: Formal power series only. Missing power series over complex numbers. date: 2025-08-24 From 3dffaf2f18b47d11948f6390838ea6f2ae662aaf Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 15 Jul 2026 22:25:47 +0000 Subject: [PATCH 0810/1300] chore(Combinatorics): restore deprecated pentagonal.lean module (#41397) --- Mathlib.lean | 1 + Mathlib/Combinatorics/Enumerative/Pentagonal.lean | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 Mathlib/Combinatorics/Enumerative/Pentagonal.lean diff --git a/Mathlib.lean b/Mathlib.lean index 31cbd4c6482732..b2b7f153003840 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3561,6 +3561,7 @@ public import Mathlib.Combinatorics.Enumerative.InclusionExclusion public import Mathlib.Combinatorics.Enumerative.Partition.Basic public import Mathlib.Combinatorics.Enumerative.Partition.GenFun public import Mathlib.Combinatorics.Enumerative.Partition.Glaisher +public import Mathlib.Combinatorics.Enumerative.Pentagonal public import Mathlib.Combinatorics.Enumerative.Pentagonal.Basic public import Mathlib.Combinatorics.Enumerative.Pentagonal.PowerSeries public import Mathlib.Combinatorics.Enumerative.Pentagonal.Ring diff --git a/Mathlib/Combinatorics/Enumerative/Pentagonal.lean b/Mathlib/Combinatorics/Enumerative/Pentagonal.lean new file mode 100644 index 00000000000000..5ef2b6297dfe59 --- /dev/null +++ b/Mathlib/Combinatorics/Enumerative/Pentagonal.lean @@ -0,0 +1,10 @@ +/- +Copyright (c) 2026 Weiyi Wang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Weiyi Wang +-/ +module + +public import Mathlib.Combinatorics.Enumerative.Pentagonal.Basic + +deprecated_module (since := "2026-07-15") From 79d0395a1825a6264ad5d269e35e60537518955e Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Thu, 16 Jul 2026 01:47:53 +0000 Subject: [PATCH 0811/1300] chore: bump toolchain to v4.33.0-rc1 (#41779) Co-authored-by: Anne C.A. Baanen Co-authored-by: Anne Baanen Co-authored-by: Anne Baanen <2116570+Vierkantor@users.noreply.github.com> Co-authored-by: Joscha Co-authored-by: Bryan Gin-ge Chen Co-authored-by: leanprover-community-mathlib4-bot Co-authored-by: Sebastian Ullrich Co-authored-by: Julia Markus Himmel <2065352+TwoFX@users.noreply.github.com> Co-authored-by: mathlib-nightly-testing[bot] Co-authored-by: Johan Commelin --- Archive/Hairer.lean | 1 + Archive/Imo/Imo1987Q1.lean | 2 + Archive/Imo/Imo2013Q1.lean | 2 + Archive/Imo/Imo2019Q2.lean | 2 +- Archive/Imo/Imo2024Q5.lean | 10 +- Archive/MinimalSheffer.lean | 4 +- Archive/Sensitivity.lean | 1 + .../Wiedijk100Theorems/FriendshipGraphs.lean | 1 + Archive/Wiedijk100Theorems/Konigsberg.lean | 1 + Archive/ZagierTwoSquares.lean | 3 + Cache/Hashing.lean | 2 +- Cache/IO.lean | 4 +- Counterexamples/AharoniKorman.lean | 5 + Counterexamples/MapFloor.lean | 2 + Counterexamples/Phillips.lean | 4 +- .../ZeroDivisorsInAddMonoidAlgebras.lean | 1 + Mathlib/Algebra/Algebra/Epi.lean | 1 + Mathlib/Algebra/Algebra/Equiv.lean | 1 + Mathlib/Algebra/Algebra/NonUnitalHom.lean | 2 + Mathlib/Algebra/Algebra/Operations.lean | 1 + Mathlib/Algebra/Algebra/Opposite.lean | 7 + .../Algebra/Spectrum/Quasispectrum.lean | 1 + Mathlib/Algebra/Algebra/Subalgebra/Basic.lean | 5 +- .../Algebra/Algebra/Subalgebra/Directed.lean | 3 + .../Algebra/Algebra/Subalgebra/Lattice.lean | 3 + Mathlib/Algebra/Algebra/ZMod.lean | 2 +- Mathlib/Algebra/BigOperators/Expect.lean | 1 + Mathlib/Algebra/BigOperators/Fin.lean | 2 + Mathlib/Algebra/BigOperators/Finprod.lean | 7 + .../BigOperators/Group/Finset/Basic.lean | 1 + .../BigOperators/Group/Finset/Powerset.lean | 1 + .../BigOperators/Group/Multiset/Basic.lean | 1 + .../BigOperators/GroupWithZero/Finset.lean | 1 + Mathlib/Algebra/BrauerGroup/Defs.lean | 2 +- .../Algebra/Category/FGModuleCat/Basic.lean | 1 + .../Category/FGModuleCat/Colimits.lean | 2 +- .../Algebra/Category/FGModuleCat/Limits.lean | 2 +- Mathlib/Algebra/Category/Grp/Abelian.lean | 4 +- Mathlib/Algebra/Category/Grp/Colimits.lean | 6 +- Mathlib/Algebra/Category/Grp/EpiMono.lean | 3 + Mathlib/Algebra/Category/Grp/Images.lean | 2 + Mathlib/Algebra/Category/Grp/Limits.lean | 1 - .../Algebra/Category/ModuleCat/Abelian.lean | 4 +- .../Category/ModuleCat/Adjunctions.lean | 15 +- .../Category/ModuleCat/ChangeOfRings.lean | 12 +- .../Algebra/Category/ModuleCat/Descent.lean | 2 +- .../ModuleCat/Differentials/Basic.lean | 1 + .../ModuleCat/Differentials/Presheaf.lean | 1 + .../Algebra/Category/ModuleCat/EpiMono.lean | 2 +- .../Category/ModuleCat/FilteredColimits.lean | 2 +- .../Algebra/Category/ModuleCat/Images.lean | 2 + .../ModuleCat/Monoidal/Adjunction.lean | 8 + .../Algebra/Category/ModuleCat/Presheaf.lean | 4 + .../ModuleCat/Presheaf/ColimitFunctor.lean | 17 ++- .../Category/ModuleCat/Presheaf/Free.lean | 5 + .../ModuleCat/Presheaf/Generator.lean | 1 + .../Category/ModuleCat/Presheaf/Monoidal.lean | 1 - .../ModuleCat/Presheaf/Pushforward.lean | 2 + .../ModuleCat/Presheaf/Sheafification.lean | 2 +- .../Category/ModuleCat/Presheaf/Sheafify.lean | 8 +- .../ModuleCat/ProjectiveDimension.lean | 1 + .../ModuleCat/Sheaf/ChangeOfRings.lean | 1 + .../Category/ModuleCat/Sheaf/Free.lean | 2 + .../ModuleCat/Sheaf/PullbackFree.lean | 1 + .../Sheaf/PushforwardContinuous.lean | 2 + .../ModuleCat/Sheaf/Quasicoherent.lean | 3 + Mathlib/Algebra/Category/ModuleCat/Stalk.lean | 1 - Mathlib/Algebra/Category/ModuleCat/Ulift.lean | 3 + .../Category/MonCat/FilteredColimits.lean | 2 +- Mathlib/Algebra/Category/MonCat/Limits.lean | 1 - .../Algebra/Category/Ring/Adjunctions.lean | 1 + .../Algebra/Category/Ring/Constructions.lean | 2 + .../Category/Ring/FinitePresentation.lean | 1 + .../Algebra/Category/Ring/Under/Basic.lean | 1 + .../Algebra/Category/Ring/Under/Property.lean | 9 +- Mathlib/Algebra/Central/Basic.lean | 1 + Mathlib/Algebra/CharP/Invertible.lean | 6 +- Mathlib/Algebra/CharP/MixedCharZero.lean | 2 +- Mathlib/Algebra/Colimit/DirectLimit.lean | 6 + Mathlib/Algebra/Colimit/Finiteness.lean | 3 +- Mathlib/Algebra/Colimit/Module.lean | 3 + Mathlib/Algebra/Colimit/Ring.lean | 2 + .../Computation/ApproximationCorollaries.lean | 1 + .../Computation/TerminatesIffRat.lean | 1 + .../Computation/Translations.lean | 2 + Mathlib/Algebra/DirectSum/Basic.lean | 9 +- Mathlib/Algebra/DirectSum/Decomposition.lean | 12 +- Mathlib/Algebra/DirectSum/Idempotents.lean | 1 - Mathlib/Algebra/DirectSum/Internal.lean | 6 + Mathlib/Algebra/DirectSum/LinearMap.lean | 1 + Mathlib/Algebra/DirectSum/Module.lean | 5 + Mathlib/Algebra/DirectSum/Ring.lean | 1 + Mathlib/Algebra/DualQuaternion.lean | 1 + Mathlib/Algebra/Exact/Basic.lean | 4 + Mathlib/Algebra/Expr.lean | 8 +- Mathlib/Algebra/Field/IsField.lean | 4 +- Mathlib/Algebra/Field/Rat.lean | 2 + Mathlib/Algebra/Free.lean | 1 + Mathlib/Algebra/FreeAlgebra.lean | 2 + Mathlib/Algebra/FreeMonoid/Basic.lean | 3 +- Mathlib/Algebra/GCDMonoid/Basic.lean | 18 +-- Mathlib/Algebra/GradedMonoid.lean | 1 + Mathlib/Algebra/Group/Action/Basic.lean | 4 +- .../Group/Action/Pointwise/Finset.lean | 4 +- .../Group/Action/Pointwise/Set/Basic.lean | 4 +- Mathlib/Algebra/Group/Conj.lean | 1 + Mathlib/Algebra/Group/End.lean | 2 + Mathlib/Algebra/Group/Finsupp.lean | 1 + Mathlib/Algebra/Group/Hom/Basic.lean | 4 +- Mathlib/Algebra/Group/Hom/Defs.lean | 12 +- Mathlib/Algebra/Group/Invertible/Basic.lean | 8 +- Mathlib/Algebra/Group/Invertible/Defs.lean | 12 +- Mathlib/Algebra/Group/Pi/Basic.lean | 2 +- .../Algebra/Group/Pointwise/Finset/Basic.lean | 22 +-- .../Group/Pointwise/Finset/Scalar.lean | 4 +- .../Algebra/Group/Pointwise/Set/Basic.lean | 22 +-- .../Algebra/Group/Pointwise/Set/Scalar.lean | 4 +- Mathlib/Algebra/Group/Subgroup/Basic.lean | 3 + Mathlib/Algebra/Group/Subgroup/Ker.lean | 2 + Mathlib/Algebra/Group/Subgroup/Map.lean | 2 + Mathlib/Algebra/Group/Subgroup/Pointwise.lean | 1 + .../Algebra/Group/Subgroup/ZPowers/Basic.lean | 1 + .../Algebra/Group/Submonoid/Operations.lean | 2 + .../Algebra/Group/Submonoid/Pointwise.lean | 4 +- Mathlib/Algebra/Group/Units/Defs.lean | 6 +- Mathlib/Algebra/Group/WithOne/Basic.lean | 1 + .../Algebra/GroupWithZero/Action/Defs.lean | 4 +- Mathlib/Algebra/GroupWithZero/Associated.lean | 1 + Mathlib/Algebra/GroupWithZero/Basic.lean | 2 +- Mathlib/Algebra/GroupWithZero/Indicator.lean | 1 + Mathlib/Algebra/GroupWithZero/InjSurj.lean | 2 +- Mathlib/Algebra/GroupWithZero/Invertible.lean | 4 +- Mathlib/Algebra/GroupWithZero/ProdHom.lean | 6 + Mathlib/Algebra/GroupWithZero/Range.lean | 3 +- .../Algebra/GroupWithZero/Units/Basic.lean | 4 +- Mathlib/Algebra/GroupWithZero/WithZero.lean | 3 + Mathlib/Algebra/Homology/Additive.lean | 4 + Mathlib/Algebra/Homology/Augment.lean | 2 + .../Algebra/Homology/BifunctorAssociator.lean | 2 + Mathlib/Algebra/Homology/BifunctorShift.lean | 2 +- .../Homology/CochainComplexOpposite.lean | 5 + Mathlib/Algebra/Homology/CommSq.lean | 2 + Mathlib/Algebra/Homology/ComplexShape.lean | 4 +- .../Algebra/Homology/ComplexShapeSigns.lean | 8 +- .../Homology/DerivedCategory/Basic.lean | 2 + .../DerivabilityStructureInjectives.lean | 2 + .../Homology/DerivedCategory/Ext/Basic.lean | 2 - .../DerivedCategory/Ext/ExactSequences.lean | 2 + .../Homology/DerivedCategory/Ext/Map.lean | 19 +-- .../DerivedCategory/Ext/TStructure.lean | 1 - .../Homology/DerivedCategory/Fractions.lean | 2 + .../Homology/DerivedCategory/KInjective.lean | 6 +- .../Homology/DerivedCategory/KProjective.lean | 6 +- .../Homology/DerivedCategory/ShortExact.lean | 1 + .../DerivedCategory/SmallShiftedHom.lean | 1 - .../Algebra/Homology/DifferentialObject.lean | 3 + Mathlib/Algebra/Homology/Embedding/Basic.lean | 6 + .../Homology/Embedding/CochainComplex.lean | 1 + .../Algebra/Homology/Embedding/Connect.lean | 2 + .../Algebra/Homology/Embedding/Extend.lean | 2 + .../Homology/Embedding/ExtendHomology.lean | 2 + .../Homology/Embedding/ExtendHomotopy.lean | 2 + .../Algebra/Homology/Embedding/HomEquiv.lean | 3 + .../Homology/Embedding/Restriction.lean | 2 + .../Embedding/RestrictionHomology.lean | 1 + .../Algebra/Homology/Embedding/TruncGE.lean | 6 + .../Homology/Embedding/TruncGEHomology.lean | 1 + .../Algebra/Homology/Embedding/TruncLE.lean | 1 + .../Algebra/Homology/Factorizations/CM5a.lean | 1 + .../Algebra/Homology/Factorizations/CM5b.lean | 1 + .../Homology/HomologicalBicomplex.lean | 3 + .../Algebra/Homology/HomologicalComplex.lean | 3 + .../Homology/HomologicalComplexBiprod.lean | 2 + .../Algebra/Homology/HomologySequence.lean | 3 + .../Homology/HomologySequenceLemmas.lean | 2 + Mathlib/Algebra/Homology/Homotopy.lean | 10 ++ .../HomotopyCategory/DegreewiseSplit.lean | 1 + .../Homology/HomotopyCategory/HomComplex.lean | 1 + .../HomComplexCohomology.lean | 1 + .../HomotopyCategory/HomComplexShift.lean | 3 + .../HomotopyCategory/HomComplexSingle.lean | 1 + .../HomotopyCategory/KProjective.lean | 1 + .../HomotopyCategory/MappingCone.lean | 3 + .../Homology/HomotopyCategory/Plus.lean | 3 + .../HomotopyCategory/Pretriangulated.lean | 1 + .../Homology/HomotopyCategory/Shift.lean | 9 ++ .../HomotopyCategory/SingleFunctors.lean | 1 + .../HomotopyCategory/Triangulated.lean | 1 + Mathlib/Algebra/Homology/HomotopyCofiber.lean | 3 +- .../Homology/LeftResolution/Basic.lean | 3 +- .../Homology/LeftResolution/Reduced.lean | 1 - .../Homology/LeftResolution/Transport.lean | 4 +- Mathlib/Algebra/Homology/Localization.lean | 1 + .../Homology/ModelCategory/Lifting.lean | 3 + Mathlib/Algebra/Homology/Monoidal.lean | 6 + Mathlib/Algebra/Homology/Opposite.lean | 18 ++- Mathlib/Algebra/Homology/ShortComplex/Ab.lean | 1 + .../Algebra/Homology/ShortComplex/Basic.lean | 3 + .../ShortComplex/ConcreteCategory.lean | 1 - .../ShortComplex/FunctorEquivalence.lean | 7 +- .../ShortComplex/HomologicalComplex.lean | 2 + .../Homology/ShortComplex/Homology.lean | 5 + .../Homology/ShortComplex/LeftHomology.lean | 3 + .../Algebra/Homology/ShortComplex/Limits.lean | 4 +- .../Homology/ShortComplex/RightHomology.lean | 3 + Mathlib/Algebra/Homology/Single.lean | 8 + Mathlib/Algebra/Homology/SingleHomology.lean | 5 + .../Homology/SpectralObject/Basic.lean | 1 + .../Homology/SpectralObject/Cycles.lean | 2 + .../Algebra/Homology/SpectralObject/Page.lean | 6 + .../SpectralObject/SpectralSequence.lean | 6 + Mathlib/Algebra/Homology/TotalComplex.lean | 6 +- .../Algebra/Homology/TotalComplexShift.lean | 2 + .../Homology/TotalComplexSymmetry.lean | 9 ++ Mathlib/Algebra/Jordan/Basic.lean | 5 + Mathlib/Algebra/Lie/Abelian.lean | 1 + Mathlib/Algebra/Lie/AdjointAction/Basic.lean | 1 + Mathlib/Algebra/Lie/BaseChange.lean | 3 +- Mathlib/Algebra/Lie/Basic.lean | 7 +- Mathlib/Algebra/Lie/Basis.lean | 3 + Mathlib/Algebra/Lie/Classical.lean | 2 +- Mathlib/Algebra/Lie/Derivation/Basic.lean | 6 + Mathlib/Algebra/Lie/DirectSum.lean | 2 + Mathlib/Algebra/Lie/EngelSubalgebra.lean | 1 + Mathlib/Algebra/Lie/Extension.lean | 4 +- Mathlib/Algebra/Lie/Graded.lean | 3 + Mathlib/Algebra/Lie/LieTheorem.lean | 1 + Mathlib/Algebra/Lie/Matrix.lean | 1 + Mathlib/Algebra/Lie/OfAssociative.lean | 9 +- Mathlib/Algebra/Lie/Quotient.lean | 1 + Mathlib/Algebra/Lie/SemiDirect.lean | 1 + Mathlib/Algebra/Lie/Solvable.lean | 1 + Mathlib/Algebra/Lie/Submodule.lean | 1 + Mathlib/Algebra/Lie/TensorProduct.lean | 1 + Mathlib/Algebra/Lie/UniversalEnveloping.lean | 1 + Mathlib/Algebra/Lie/Weights/Basic.lean | 1 + Mathlib/Algebra/Lie/Weights/Chain.lean | 1 + Mathlib/Algebra/Lie/Weights/IsSimple.lean | 2 + Mathlib/Algebra/Lie/Weights/Killing.lean | 1 + Mathlib/Algebra/Module/CharacterModule.lean | 6 + Mathlib/Algebra/Module/Equiv/Basic.lean | 2 + Mathlib/Algebra/Module/Equiv/Defs.lean | 7 +- Mathlib/Algebra/Module/GradedModule.lean | 2 +- Mathlib/Algebra/Module/Injective.lean | 1 + Mathlib/Algebra/Module/Lattice.lean | 1 + Mathlib/Algebra/Module/LinearMap/Defs.lean | 5 +- Mathlib/Algebra/Module/LinearMap/Index.lean | 2 + .../Algebra/Module/LinearMap/Polynomial.lean | 2 + .../Algebra/Module/LocalizedModule/Basic.lean | 5 + Mathlib/Algebra/Module/NatInt.lean | 4 +- Mathlib/Algebra/Module/PID.lean | 1 + .../Algebra/Module/Presentation/Cokernel.lean | 4 + .../Module/Presentation/Differentials.lean | 1 + .../Module/Presentation/DirectSum.lean | 1 + Mathlib/Algebra/Module/SnakeLemma.lean | 1 + .../Algebra/Module/Submodule/Bilinear.lean | 1 + Mathlib/Algebra/Module/Submodule/Defs.lean | 2 +- .../Algebra/Module/Submodule/Invariant.lean | 5 + Mathlib/Algebra/Module/Submodule/Ker.lean | 1 + .../Algebra/Module/Submodule/LinearMap.lean | 2 + Mathlib/Algebra/Module/Submodule/Map.lean | 8 +- Mathlib/Algebra/Module/Submodule/Range.lean | 2 + .../Module/Submodule/RestrictScalars.lean | 1 + Mathlib/Algebra/Module/Torsion/Basic.lean | 8 +- Mathlib/Algebra/Module/TransferInstance.lean | 1 + Mathlib/Algebra/Module/ZLattice/Covolume.lean | 3 + Mathlib/Algebra/Module/ZLattice/Summable.lean | 1 + Mathlib/Algebra/MonoidAlgebra/Basic.lean | 10 ++ Mathlib/Algebra/MonoidAlgebra/Defs.lean | 13 ++ Mathlib/Algebra/MonoidAlgebra/Degree.lean | 2 + Mathlib/Algebra/MonoidAlgebra/Grading.lean | 2 + Mathlib/Algebra/MonoidAlgebra/Lift.lean | 1 + Mathlib/Algebra/MonoidAlgebra/MapDomain.lean | 15 ++ Mathlib/Algebra/MonoidAlgebra/Module.lean | 5 + .../Algebra/MonoidAlgebra/NoZeroDivisors.lean | 1 + .../Algebra/MonoidAlgebra/PointwiseSMul.lean | 1 + Mathlib/Algebra/MonoidAlgebra/Support.lean | 3 + Mathlib/Algebra/MvPolynomial/Basic.lean | 2 + Mathlib/Algebra/MvPolynomial/CommRing.lean | 1 + Mathlib/Algebra/MvPolynomial/Degrees.lean | 1 + Mathlib/Algebra/MvPolynomial/Equiv.lean | 3 + Mathlib/Algebra/MvPolynomial/Eval.lean | 2 + Mathlib/Algebra/MvPolynomial/Rename.lean | 2 + Mathlib/Algebra/MvPolynomial/Variables.lean | 1 + Mathlib/Algebra/Opposites.lean | 6 +- Mathlib/Algebra/Order/Antidiag/Finsupp.lean | 3 + .../Algebra/Order/Antidiag/FinsuppEquiv.lean | 1 + Mathlib/Algebra/Order/Antidiag/Nat.lean | 2 + Mathlib/Algebra/Order/Antidiag/Pi.lean | 4 + Mathlib/Algebra/Order/Antidiag/Prod.lean | 1 + Mathlib/Algebra/Order/Archimedean/Basic.lean | 2 +- Mathlib/Algebra/Order/Archimedean/Class.lean | 1 + .../BigOperators/Group/LocallyFinite.lean | 1 + Mathlib/Algebra/Order/CompleteField.lean | 1 + Mathlib/Algebra/Order/Floor/Defs.lean | 6 +- Mathlib/Algebra/Order/Group/Lattice.lean | 2 +- .../Order/GroupWithZero/Canonical.lean | 1 + Mathlib/Algebra/Order/GroupWithZero/Lex.lean | 12 ++ Mathlib/Algebra/Order/Hom/MonoidWithZero.lean | 1 + Mathlib/Algebra/Order/Interval/Basic.lean | 1 + Mathlib/Algebra/Order/IsBotOne.lean | 2 +- .../Algebra/Order/Module/HahnEmbedding.lean | 1 + .../Order/Monoid/LocallyFiniteOrder.lean | 3 + .../Algebra/Order/Monoid/Unbundled/Basic.lean | 4 +- .../Order/Monoid/Unbundled/WithTop.lean | 2 + Mathlib/Algebra/Order/Ring/StandardPart.lean | 21 +++ Mathlib/Algebra/Polynomial/Basic.lean | 6 + Mathlib/Algebra/Polynomial/BigOperators.lean | 2 + Mathlib/Algebra/Polynomial/Bivariate.lean | 1 + Mathlib/Algebra/Polynomial/Coeff.lean | 2 + Mathlib/Algebra/Polynomial/Degree/Defs.lean | 1 + Mathlib/Algebra/Polynomial/Derivation.lean | 3 + Mathlib/Algebra/Polynomial/Expand.lean | 2 + Mathlib/Algebra/Polynomial/Laurent.lean | 2 + Mathlib/Algebra/Polynomial/Module/AEval.lean | 2 + Mathlib/Algebra/Polynomial/Module/Basic.lean | 2 + Mathlib/Algebra/Polynomial/OfFn.lean | 4 + Mathlib/Algebra/Polynomial/Reverse.lean | 4 + Mathlib/Algebra/Polynomial/Splits.lean | 1 + Mathlib/Algebra/QuadraticAlgebra/Basic.lean | 2 + Mathlib/Algebra/Quandle.lean | 2 + Mathlib/Algebra/Quaternion.lean | 1 + Mathlib/Algebra/Ring/CentroidHom.lean | 1 + Mathlib/Algebra/Ring/Equiv.lean | 3 + Mathlib/Algebra/Ring/Hom/Defs.lean | 8 +- Mathlib/Algebra/Ring/Invertible.lean | 2 +- Mathlib/Algebra/Ring/Subring/Basic.lean | 1 + Mathlib/Algebra/RingQuot.lean | 1 + Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean | 2 +- Mathlib/Algebra/Star/CentroidHom.lean | 1 + Mathlib/Algebra/Star/Module.lean | 1 + Mathlib/Algebra/Star/NonUnitalSubalgebra.lean | 1 + Mathlib/Algebra/Star/RingQuot.lean | 2 +- Mathlib/Algebra/Star/StarAlgHom.lean | 1 + Mathlib/Algebra/Star/UnitaryStarAlgAut.lean | 1 + Mathlib/Algebra/Symmetrized.lean | 1 + Mathlib/Algebra/TrivSqZeroExt/Basic.lean | 1 + Mathlib/Algebra/TrivSqZeroExt/Ideal.lean | 1 + Mathlib/AlgebraicGeometry/AffineScheme.lean | 26 ++++ Mathlib/AlgebraicGeometry/AffineSpace.lean | 19 +++ .../AffineTransitionLimit.lean | 4 + .../AlgebraicGeometry/AlgClosed/Basic.lean | 3 + Mathlib/AlgebraicGeometry/Artinian.lean | 2 + .../Birational/Birational.lean | 1 + .../Birational/Composition.lean | 5 +- .../Birational/RationalMap.lean | 13 ++ Mathlib/AlgebraicGeometry/Cover/Directed.lean | 7 +- .../Cover/MorphismProperty.lean | 6 +- Mathlib/AlgebraicGeometry/Cover/Open.lean | 1 + Mathlib/AlgebraicGeometry/Cover/Over.lean | 5 + .../AlgebraicGeometry/Cover/QuasiCompact.lean | 1 + .../EllipticCurve/Affine/Formula.lean | 9 +- .../EllipticCurve/Affine/Point.lean | 3 + Mathlib/AlgebraicGeometry/Fiber.lean | 4 + .../GammaSpecAdjunction.lean | 14 +- .../Geometrically/Basic.lean | 2 + .../Geometrically/Connected.lean | 3 + .../Geometrically/Integral.lean | 3 + .../Geometrically/Irreducible.lean | 3 + .../Geometrically/Reduced.lean | 3 + Mathlib/AlgebraicGeometry/Gluing.lean | 13 ++ .../AlgebraicGeometry/IdealSheaf/Basic.lean | 3 + .../IdealSheaf/Functorial.lean | 1 + .../IdealSheaf/Subscheme.lean | 13 ++ Mathlib/AlgebraicGeometry/Limits.lean | 1 + Mathlib/AlgebraicGeometry/Modules/Sheaf.lean | 16 ++ Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 21 ++- .../AlgebraicGeometry/Morphisms/Affine.lean | 8 + .../Morphisms/AffineAnd.lean | 1 + .../AlgebraicGeometry/Morphisms/Basic.lean | 2 + .../Morphisms/ClosedImmersion.lean | 15 ++ .../Morphisms/Constructors.lean | 4 + .../AlgebraicGeometry/Morphisms/Descent.lean | 1 + .../AlgebraicGeometry/Morphisms/Etale.lean | 10 ++ .../AlgebraicGeometry/Morphisms/Finite.lean | 15 ++ .../Morphisms/FinitePresentation.lean | 3 + .../Morphisms/FiniteType.lean | 4 + Mathlib/AlgebraicGeometry/Morphisms/Flat.lean | 7 + .../Morphisms/FlatDescent.lean | 10 ++ .../AlgebraicGeometry/Morphisms/FlatMono.lean | 1 + .../AlgebraicGeometry/Morphisms/FlatRank.lean | 2 + .../Morphisms/FormallyUnramified.lean | 3 + .../Morphisms/Immersion.lean | 5 + .../AlgebraicGeometry/Morphisms/Integral.lean | 8 + .../Morphisms/LocalClosure.lean | 4 + .../Morphisms/Preimmersion.lean | 5 + .../AlgebraicGeometry/Morphisms/Proper.lean | 7 + .../Morphisms/QuasiCompact.lean | 6 + .../Morphisms/QuasiFinite.lean | 8 + .../Morphisms/QuasiSeparated.lean | 10 ++ .../Morphisms/RingHomProperties.lean | 4 + .../Morphisms/Separated.lean | 9 ++ .../AlgebraicGeometry/Morphisms/Smooth.lean | 5 + .../Morphisms/SurjectiveOnStalks.lean | 1 + .../Morphisms/UnderlyingMap.lean | 2 + .../Morphisms/UniversallyClosed.lean | 4 + .../Morphisms/UniversallyInjective.lean | 5 + .../Morphisms/UniversallyOpen.lean | 2 + .../Morphisms/WeaklyEtale.lean | 9 ++ Mathlib/AlgebraicGeometry/Noetherian.lean | 3 + Mathlib/AlgebraicGeometry/Normalization.lean | 4 + Mathlib/AlgebraicGeometry/OpenImmersion.lean | 13 ++ .../ProjectiveSpectrum/Basic.lean | 6 + .../ProjectiveSpectrum/Functor.lean | 6 + .../ProjectiveSpectrum/Proper.lean | 4 + .../ProjectiveSpectrum/Scheme.lean | 13 ++ .../ProjectiveSpectrum/StructureSheaf.lean | 18 ++- .../ProjectiveSpectrum/Topology.lean | 1 + Mathlib/AlgebraicGeometry/Properties.lean | 4 + .../AlgebraicGeometry/PullbackCarrier.lean | 7 + Mathlib/AlgebraicGeometry/Pullbacks.lean | 9 +- Mathlib/AlgebraicGeometry/QuasiAffine.lean | 1 + Mathlib/AlgebraicGeometry/RelativeGluing.lean | 4 +- Mathlib/AlgebraicGeometry/ResidueField.lean | 5 + Mathlib/AlgebraicGeometry/Restrict.lean | 12 ++ Mathlib/AlgebraicGeometry/Scheme.lean | 9 ++ Mathlib/AlgebraicGeometry/Sites/Affine.lean | 2 + .../AlgebraicGeometry/Sites/AffineEtale.lean | 6 + .../AlgebraicGeometry/Sites/BigZariski.lean | 2 + .../Sites/ConstantSheaf.lean | 1 + Mathlib/AlgebraicGeometry/Sites/Etale.lean | 2 + .../AlgebraicGeometry/Sites/EtalePoint.lean | 3 +- Mathlib/AlgebraicGeometry/Sites/Fpqc.lean | 4 + .../Sites/MorphismProperty.lean | 1 + Mathlib/AlgebraicGeometry/Sites/Proetale.lean | 18 +++ .../Sites/Representability.lean | 5 +- Mathlib/AlgebraicGeometry/Sites/Small.lean | 3 + .../Sites/SmallAffineZariski.lean | 3 + Mathlib/AlgebraicGeometry/Spec.lean | 15 ++ Mathlib/AlgebraicGeometry/SpreadingOut.lean | 7 + Mathlib/AlgebraicGeometry/Stalk.lean | 13 ++ Mathlib/AlgebraicGeometry/StructureSheaf.lean | 31 +++- .../AlgebraicGeometry/ValuativeCriterion.lean | 2 + .../ZariskisMainTheorem.lean | 3 + .../AlternatingFaceMapComplex.lean | 4 + Mathlib/AlgebraicTopology/CechNerve.lean | 6 +- .../DoldKan/Compatibility.lean | 4 + .../DoldKan/Equivalence.lean | 3 + .../DoldKan/EquivalencePseudoabelian.lean | 3 + .../DoldKan/FunctorGamma.lean | 1 + .../AlgebraicTopology/DoldKan/FunctorN.lean | 2 +- .../AlgebraicTopology/DoldKan/Homotopies.lean | 1 + .../AlgebraicTopology/DoldKan/NCompGamma.lean | 3 - .../AlgebraicTopology/DoldKan/Normalized.lean | 1 + Mathlib/AlgebraicTopology/DoldKan/PInfty.lean | 6 + .../DoldKan/SplitSimplicialObject.lean | 5 + .../AlgebraicTopology/EilenbergSteenrod.lean | 9 ++ .../AlgebraicTopology/ExtraDegeneracy.lean | 5 +- .../FundamentalGroupoid/Basic.lean | 1 + .../FundamentalGroupoid/InducedMaps.lean | 1 - .../ModelCategory/Basic.lean | 2 +- .../BifibrantObjectHomotopy.lean | 22 ++- .../CofibrantObjectHomotopy.lean | 1 + .../ModelCategory/Cylinder.lean | 1 + .../ModelCategory/Transport.lean | 2 +- Mathlib/AlgebraicTopology/MooreComplex.lean | 3 + .../SimplexCategory/Augmented/Basic.lean | 9 ++ .../SimplexCategory/Basic.lean | 3 + .../SimplexCategory/DeltaZeroIter.lean | 1 + .../SimplexCategory/Rev.lean | 2 + .../AlgebraicTopology/SimplicialNerve.lean | 4 + .../SimplicialObject/Basic.lean | 27 +++- .../SimplicialObject/Coskeletal.lean | 1 - .../SimplicialObject/DeltaZeroIter.lean | 6 +- .../SimplicialObject/Op.lean | 2 + .../SimplicialObject/Split.lean | 8 + .../IsUniquelyCodimOneFace.lean | 1 + .../SimplicialSet/AnodyneExtensions/Op.lean | 1 + .../AnodyneExtensions/Pairing.lean | 2 + .../AnodyneExtensions/PairingCore.lean | 1 + .../SimplicialSet/AnodyneExtensions/Rank.lean | 3 + .../RelativeCellComplex.lean | 9 +- .../AnodyneExtensions/UnionProd.lean | 16 ++ .../SimplicialSet/CoherentIso.lean | 2 + .../SimplicialSet/Coskeletal.lean | 2 + .../SimplicialSet/FiniteProd.lean | 1 + .../SimplicialSet/HoFunctorMonoidal.lean | 29 ++++ .../SimplicialSet/Homology/Basic.lean | 3 +- .../SimplicialSet/Homology/Nondegenerate.lean | 4 +- .../SimplicialSet/HomotopyCat.lean | 15 ++ .../SimplicialSet/HornColimits.lean | 3 + .../SimplicialSet/Monoidal.lean | 1 + .../SimplicialSet/Nerve.lean | 4 + .../SimplicialSet/NerveAdjunction.lean | 10 ++ .../SimplicialSet/NerveNondegenerate.lean | 1 + .../NonDegenerateSimplicesColimit.lean | 2 + .../SimplicialSet/NonsingularColimit.lean | 1 + .../SimplicialSet/ProdStdSimplexOne.lean | 3 + .../SimplicialSet/PushoutProduct.lean | 3 + .../SimplicialSet/RelativeMorphism.lean | 1 + .../SimplicialSet/Skeleton.lean | 25 ++- .../SimplicialSet/StdSimplex.lean | 3 + .../SimplicialSet/StrictSegal.lean | 4 + .../SimplicialSet/Subcomplex.lean | 1 + .../SimplicialSet/SubcomplexColimits.lean | 1 + .../SimplicialSet/Subdivision.lean | 3 + .../SingularHomology/Basic.lean | 1 + Mathlib/AlgebraicTopology/SingularSet.lean | 7 + Mathlib/Analysis/Analytic/Composition.lean | 2 + Mathlib/Analysis/Analytic/Inverse.lean | 3 + Mathlib/Analysis/Analytic/IteratedFDeriv.lean | 1 + .../Analysis/AperiodicOrder/Delone/Basic.lean | 4 + .../BoxIntegral/DivergenceTheorem.lean | 1 + .../Analysis/BoxIntegral/Partition/Basic.lean | 4 + .../BoxIntegral/Partition/Filter.lean | 1 + .../Analysis/BoxIntegral/Partition/Split.lean | 1 + .../Analysis/BoxIntegral/UnitPartition.lean | 1 + .../Analysis/CStarAlgebra/CStarMatrix.lean | 11 +- .../Isometric.lean | 3 + .../NonUnital.lean | 8 +- .../Restrict.lean | 6 + .../ContinuousFunctionalCalculus/Unique.lean | 4 + Mathlib/Analysis/CStarAlgebra/Matrix.lean | 4 +- .../Analysis/CStarAlgebra/Module/Defs.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Spectrum.lean | 1 + .../CStarAlgebra/Unitary/Connected.lean | 2 +- .../Analysis/CStarAlgebra/Unitary/Maps.lean | 1 + .../Analysis/CStarAlgebra/Unitization.lean | 1 + .../Calculus/AddTorsor/AffineMap.lean | 6 + Mathlib/Analysis/Calculus/ContDiff/Basic.lean | 1 + .../Calculus/ContDiff/FaaDiBruno.lean | 1 + .../Analysis/Calculus/Deriv/AffineMap.lean | 3 + Mathlib/Analysis/Calculus/Deriv/Basic.lean | 1 + .../Analysis/Calculus/Deriv/MeanValue.lean | 1 + Mathlib/Analysis/Calculus/Deriv/Star.lean | 1 + .../Analysis/Calculus/FDeriv/Analytic.lean | 1 + .../Analysis/Calculus/FDeriv/Symmetric.lean | 3 + .../Calculus/FormalMultilinearSeries.lean | 1 + Mathlib/Analysis/Calculus/Implicit.lean | 1 + Mathlib/Analysis/Calculus/MeanValue.lean | 1 + Mathlib/Analysis/Complex/AbsMax.lean | 2 + Mathlib/Analysis/Complex/Circle.lean | 3 + Mathlib/Analysis/Complex/CoveringMap.lean | 1 + Mathlib/Analysis/Complex/Exponential.lean | 2 + Mathlib/Analysis/Complex/Hadamard.lean | 1 + Mathlib/Analysis/Complex/Isometry.lean | 3 + Mathlib/Analysis/Complex/JensenFormula.lean | 1 + Mathlib/Analysis/Complex/Norm.lean | 1 + Mathlib/Analysis/Complex/OpenMapping.lean | 1 + Mathlib/Analysis/Complex/Schwarz.lean | 1 + .../FunctionsBoundedAtInfty.lean | 1 + .../Complex/UpperHalfPlane/Metric.lean | 2 +- .../Complex/UpperHalfPlane/MoebiusAction.lean | 5 + .../Complex/UpperHalfPlane/ProperAction.lean | 1 + .../ValueDistribution/FirstMainTheorem.lean | 1 + .../LogCounting/Asymptotic.lean | 1 + .../ValueDistribution/LogCounting/Basic.lean | 5 + Mathlib/Analysis/Convex/Basic.lean | 2 + Mathlib/Analysis/Convex/Between.lean | 15 ++ Mathlib/Analysis/Convex/BetweenList.lean | 4 + Mathlib/Analysis/Convex/Birkhoff.lean | 1 + Mathlib/Analysis/Convex/Cone/Extension.lean | 1 + .../Analysis/Convex/Cone/TensorProduct.lean | 1 + Mathlib/Analysis/Convex/Hull.lean | 1 + Mathlib/Analysis/Convex/Independent.lean | 1 + Mathlib/Analysis/Convex/Intrinsic.lean | 1 + Mathlib/Analysis/Convex/NNReal.lean | 1 + Mathlib/Analysis/Convex/PathConnected.lean | 4 + Mathlib/Analysis/Convex/Segment.lean | 5 + Mathlib/Analysis/Convex/Side.lean | 11 ++ .../Analysis/Convex/StrictConvexBetween.lean | 1 + Mathlib/Analysis/Convex/Topology.lean | 2 + Mathlib/Analysis/Convex/Visible.lean | 4 + .../Analysis/Distribution/TestFunction.lean | 5 +- Mathlib/Analysis/Fourier/AddCircle.lean | 1 + Mathlib/Analysis/Fourier/AddCircleMulti.lean | 1 + .../BoundedContinuousFunctionChar.lean | 3 + .../Analysis/Fourier/PoissonSummation.lean | 1 + .../Analysis/InnerProductSpace/Adjoint.lean | 5 + .../Analysis/InnerProductSpace/Affine.lean | 2 + Mathlib/Analysis/InnerProductSpace/Basic.lean | 4 +- Mathlib/Analysis/InnerProductSpace/Defs.lean | 10 +- .../Analysis/InnerProductSpace/LinearMap.lean | 5 + .../InnerProductSpace/LinearPMap.lean | 2 + .../Analysis/InnerProductSpace/OfNorm.lean | 2 +- .../InnerProductSpace/Orientation.lean | 1 + Mathlib/Analysis/InnerProductSpace/PiL2.lean | 3 + .../Analysis/InnerProductSpace/Positive.lean | 1 + .../Projection/FiniteDimensional.lean | 1 + .../Projection/Reflection.lean | 1 + .../InnerProductSpace/Reproducing.lean | 1 + .../Analysis/InnerProductSpace/Subspace.lean | 1 + .../Analysis/InnerProductSpace/Symmetric.lean | 1 + .../InnerProductSpace/TensorProduct.lean | 2 + Mathlib/Analysis/LocallyConvex/AbsConvex.lean | 1 + .../Analysis/LocallyConvex/AbsConvexOpen.lean | 1 + .../Analysis/LocallyConvex/HahnBanach.lean | 1 + .../Analysis/LocallyConvex/Separation.lean | 1 + Mathlib/Analysis/LocallyConvex/WeakSpace.lean | 1 + .../Analysis/LocallyConvex/WithSeminorms.lean | 2 +- Mathlib/Analysis/Matrix/Normed.lean | 1 + Mathlib/Analysis/Matrix/Order.lean | 6 +- Mathlib/Analysis/Matrix/PosDef.lean | 4 +- Mathlib/Analysis/Matrix/Spectrum.lean | 1 + Mathlib/Analysis/MeanInequalities.lean | 1 + .../Meromorphic/FactorizedRational.lean | 5 + Mathlib/Analysis/Normed/Affine/AddTorsor.lean | 12 ++ .../Normed/Affine/AddTorsorBases.lean | 1 + .../Analysis/Normed/Algebra/Exponential.lean | 5 +- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 1 + .../Normed/Algebra/TrivSqZeroExt.lean | 2 + Mathlib/Analysis/Normed/Field/Basic.lean | 4 +- Mathlib/Analysis/Normed/Field/UnitBall.lean | 1 + Mathlib/Analysis/Normed/Group/AddTorsor.lean | 4 +- .../Analysis/Normed/Group/FunctionSeries.lean | 1 + Mathlib/Analysis/Normed/Group/Quotient.lean | 1 + .../Normed/Group/SemiNormedGrp/Kernels.lean | 4 + Mathlib/Analysis/Normed/Lp/PiLp.lean | 3 + Mathlib/Analysis/Normed/Lp/ProdLp.lean | 2 + Mathlib/Analysis/Normed/Lp/lpHolder.lean | 1 + Mathlib/Analysis/Normed/Lp/lpSpace.lean | 3 + .../Normed/Module/Ball/Homeomorph.lean | 1 + Mathlib/Analysis/Normed/Module/Bases.lean | 1 + Mathlib/Analysis/Normed/Module/Basic.lean | 8 +- .../Normed/Module/ContinuousInverse.lean | 1 + .../Normed/Module/FiniteDimension.lean | 1 + .../Normed/Module/Multilinear/Basic.lean | 1 + .../Normed/Module/Multilinear/Curry.lean | 5 + .../PiTensorProduct/InjectiveSeminorm.lean | 1 + Mathlib/Analysis/Normed/Module/WeakDual.lean | 1 + Mathlib/Analysis/Normed/Operator/Banach.lean | 1 + .../Operator/Compact/FredholmAlternative.lean | 1 + .../Normed/Operator/ContinuousAlgEquiv.lean | 2 + Mathlib/Analysis/Normed/Operator/Extend.lean | 1 + Mathlib/Analysis/Normed/Ring/Basic.lean | 2 +- .../Normed/Unbundled/FiniteExtension.lean | 1 + .../Normed/Unbundled/SpectralNorm.lean | 23 +-- Mathlib/Analysis/RCLike/Basic.lean | 5 +- .../Analysis/RCLike/BoundedContinuous.lean | 1 + Mathlib/Analysis/RCLike/ContinuousMap.lean | 1 + Mathlib/Analysis/RCLike/Sqrt.lean | 1 + .../SpecialFunctions/Complex/Circle.lean | 1 + .../Complex/CircleAddChar.lean | 1 + .../Rpow/ConjSqrt.lean | 11 ++ .../Rpow/RingInverseOrder.lean | 1 + .../Elliptic/Weierstrass.lean | 1 + .../Gaussian/FourierTransform.lean | 1 + .../Analysis/SpecialFunctions/Log/Basic.lean | 1 + .../SpecialFunctions/Log/ENNRealLogExp.lean | 1 + .../Analysis/SpecialFunctions/Sigmoid.lean | 1 + Mathlib/Analysis/SumOverResidueClass.lean | 2 + Mathlib/CategoryTheory/Abelian/Basic.lean | 6 +- .../DiagramLemmas/KernelCokernelComp.lean | 2 + .../Abelian/EpiWithInjectiveKernel.lean | 2 +- Mathlib/CategoryTheory/Abelian/Ext.lean | 3 + .../Abelian/GrothendieckAxioms/Basic.lean | 4 +- .../GrothendieckCategory/ColimCoyoneda.lean | 1 + .../EnoughInjectives.lean | 1 + .../ModuleEmbedding/GabrielPopescu.lean | 1 + .../Abelian/Injective/Dimension.lean | 1 + .../CategoryTheory/Abelian/Injective/Ext.lean | 2 - .../Abelian/Injective/Resolution.lean | 5 + .../CategoryTheory/Abelian/LeftDerived.lean | 7 +- .../Abelian/NonPreadditive.lean | 3 +- Mathlib/CategoryTheory/Abelian/Opposite.lean | 2 + .../Abelian/Preradical/Basic.lean | 3 - .../Abelian/Preradical/Colon.lean | 7 +- .../Abelian/Projective/Dimension.lean | 1 + .../Abelian/Projective/Ext.lean | 3 - .../Abelian/Projective/Resolution.lean | 4 + .../Abelian/Pseudoelements.lean | 2 +- .../CategoryTheory/Abelian/RightDerived.lean | 6 +- .../Abelian/SerreClass/Localization.lean | 2 +- .../CategoryTheory/Abelian/ShortExact.lean | 2 +- Mathlib/CategoryTheory/Abelian/Subobject.lean | 1 + Mathlib/CategoryTheory/Abelian/Transfer.lean | 4 +- Mathlib/CategoryTheory/Action.lean | 4 + Mathlib/CategoryTheory/Action/Basic.lean | 33 ++++ Mathlib/CategoryTheory/Action/Concrete.lean | 5 + Mathlib/CategoryTheory/Action/Continuous.lean | 10 ++ Mathlib/CategoryTheory/Action/Monoidal.lean | 17 +++ .../CategoryTheory/Adjunction/Additive.lean | 2 +- .../Adjunction/AdjointFunctorTheorems.lean | 1 - Mathlib/CategoryTheory/Adjunction/Basic.lean | 13 +- .../Adjunction/CompositionIso.lean | 2 +- .../Adjunction/FullyFaithful.lean | 13 +- .../Adjunction/FullyFaithfulLimits.lean | 1 + .../Adjunction/Lifting/Left.lean | 5 +- .../Adjunction/Lifting/Right.lean | 1 - Mathlib/CategoryTheory/Adjunction/Limits.lean | 8 +- Mathlib/CategoryTheory/Adjunction/Mates.lean | 13 +- .../CategoryTheory/Adjunction/Opposites.lean | 2 + .../Adjunction/Parametrized.lean | 2 +- .../CategoryTheory/Adjunction/Quadruple.lean | 1 + .../CategoryTheory/Adjunction/Reflective.lean | 6 +- .../CategoryTheory/Adjunction/Restrict.lean | 2 - Mathlib/CategoryTheory/Adjunction/Triple.lean | 15 +- Mathlib/CategoryTheory/Adjunction/Unique.lean | 2 - .../CategoryTheory/Adjunction/Whiskering.lean | 2 +- .../Bicategory/Adjunction/Cat.lean | 8 + .../Bicategory/CatEnriched.lean | 3 + .../CategoryTheory/Bicategory/Coherence.lean | 10 ++ .../CategoryTheory/Bicategory/Extension.lean | 3 + Mathlib/CategoryTheory/Bicategory/Free.lean | 1 + .../Bicategory/Functor/Cat.lean | 9 ++ .../Functor/Cat/ObjectProperty.lean | 1 + .../Bicategory/Functor/Lax.lean | 9 ++ .../Bicategory/Functor/Oplax.lean | 3 + .../Bicategory/Functor/Pseudofunctor.lean | 27 ++++ .../Bicategory/FunctorBicategory/Pseudo.lean | 1 + .../Bicategory/Grothendieck.lean | 6 +- .../Bicategory/Kan/Adjunction.lean | 4 + .../Bicategory/Monad/Basic.lean | 2 +- .../Bicategory/NaturalTransformation/Lax.lean | 3 + .../NaturalTransformation/Oplax.lean | 9 ++ .../NaturalTransformation/Pseudo.lean | 17 +++ .../CategoryTheory/Bicategory/Opposites.lean | 1 + .../CategoryTheory/Bicategory/Product.lean | 2 +- .../Bicategory/Strict/Pseudofunctor.lean | 12 ++ Mathlib/CategoryTheory/Bicategory/Yoneda.lean | 3 +- Mathlib/CategoryTheory/CatCommSq.lean | 14 +- .../CategoryTheory/Category/Bipointed.lean | 3 + Mathlib/CategoryTheory/Category/Cat.lean | 13 +- .../Category/Cat/Adjunction.lean | 2 + .../Category/Cat/CartesianClosed.lean | 2 +- .../CategoryTheory/Category/Cat/Limit.lean | 3 + .../Category/Factorisation.lean | 2 + .../CategoryTheory/Category/KleisliCat.lean | 1 + .../CategoryTheory/Category/PartialFun.lean | 4 + Mathlib/CategoryTheory/Category/Quiv.lean | 8 + Mathlib/CategoryTheory/Category/ReflQuiv.lean | 17 ++- Mathlib/CategoryTheory/Category/RelCat.lean | 15 ++ Mathlib/CategoryTheory/Category/TwoP.lean | 10 ++ Mathlib/CategoryTheory/Category/ULift.lean | 1 + Mathlib/CategoryTheory/Center/Linear.lean | 6 +- Mathlib/CategoryTheory/CofilteredSystem.lean | 3 +- Mathlib/CategoryTheory/Comma/Arrow.lean | 13 +- Mathlib/CategoryTheory/Comma/Basic.lean | 23 ++- .../CategoryTheory/Comma/CardinalArrow.lean | 1 + Mathlib/CategoryTheory/Comma/Final.lean | 3 +- Mathlib/CategoryTheory/Comma/Over/Basic.lean | 57 ++++++- .../CategoryTheory/Comma/Over/OverClass.lean | 1 + .../CategoryTheory/Comma/Over/Pullback.lean | 4 +- .../Comma/Over/StrictInitial.lean | 1 + .../CategoryTheory/Comma/Presheaf/Basic.lean | 11 ++ .../Comma/StructuredArrow/Basic.lean | 121 ++++++++++----- .../Comma/StructuredArrow/CommaMap.lean | 5 +- .../Comma/StructuredArrow/Final.lean | 2 +- .../Comma/StructuredArrow/Functor.lean | 6 + .../ComposableArrows/Basic.lean | 25 +++ .../CategoryTheory/ComposableArrows/One.lean | 1 + .../ComposableArrows/Three.lean | 5 + .../ConcreteCategory/Basic.lean | 1 + .../ConcreteCategory/Forget.lean | 3 +- Mathlib/CategoryTheory/Conj.lean | 3 + Mathlib/CategoryTheory/Core.lean | 16 +- .../CategoryTheory/Dialectica/Monoidal.lean | 3 + .../CategoryTheory/DifferentialObject.lean | 3 +- Mathlib/CategoryTheory/Discrete/Basic.lean | 10 +- .../Discrete/StructuredArrow.lean | 2 + .../CategoryTheory/Discrete/SumsProducts.lean | 3 + .../CategoryTheory/Distributive/Monoidal.lean | 1 + .../EffectiveEpi/Coproduct.lean | 1 + .../CategoryTheory/EffectiveEpi/Enough.lean | 1 - .../EffectiveEpi/Preserves.lean | 7 +- Mathlib/CategoryTheory/Elements.lean | 5 + .../CategoryTheory/Endofunctor/Algebra.lean | 6 + Mathlib/CategoryTheory/Endomorphism.lean | 3 + Mathlib/CategoryTheory/Enriched/Basic.lean | 18 ++- .../CategoryTheory/Enriched/EnrichedCat.lean | 3 + .../Enriched/FunctorCategory.lean | 6 +- .../Enriched/Ordinary/Basic.lean | 4 +- Mathlib/CategoryTheory/EpiMono.lean | 2 +- Mathlib/CategoryTheory/EqToHom.lean | 1 + Mathlib/CategoryTheory/Equivalence.lean | 52 ++++--- .../CategoryTheory/Equivalence/Symmetry.lean | 9 ++ Mathlib/CategoryTheory/Extensive.lean | 3 + .../FiberedCategory/BasedCategory.lean | 4 +- .../CategoryTheory/FiberedCategory/Fiber.lean | 1 + .../FiberedCategory/Fibered.lean | 4 +- .../FiberedCategory/Grothendieck.lean | 7 +- .../FiberedCategory/HasFibers.lean | 3 +- .../Filtered/CostructuredArrow.lean | 2 +- Mathlib/CategoryTheory/Filtered/Final.lean | 7 +- .../CategoryTheory/Filtered/Grothendieck.lean | 4 +- .../CategoryTheory/FinCategory/AsType.lean | 2 + Mathlib/CategoryTheory/FintypeCat.lean | 4 +- Mathlib/CategoryTheory/Functor/Basic.lean | 3 +- Mathlib/CategoryTheory/Functor/Const.lean | 4 +- Mathlib/CategoryTheory/Functor/Currying.lean | 17 ++- .../CategoryTheory/Functor/CurryingThree.lean | 4 + .../Functor/Derived/Adjunction.lean | 4 +- .../Functor/Derived/PointwiseLeftDerived.lean | 2 +- .../Derived/PointwiseRightDerived.lean | 2 +- Mathlib/CategoryTheory/Functor/EpiMono.lean | 2 - Mathlib/CategoryTheory/Functor/Flat.lean | 1 + .../CategoryTheory/Functor/FullyFaithful.lean | 3 + .../CategoryTheory/Functor/FunctorHom.lean | 1 + .../CategoryTheory/Functor/Functorial.lean | 2 +- .../Functor/KanExtension/Adjunction.lean | 2 +- .../Functor/KanExtension/Basic.lean | 35 +++-- .../Functor/KanExtension/DenseAt.lean | 2 + .../Functor/KanExtension/Pointwise.lean | 13 +- .../Functor/KanExtension/Preserves.lean | 6 +- .../Functor/ReflectsIso/Basic.lean | 2 +- .../Functor/ReflectsIso/Jointly.lean | 1 + .../Functor/ReflectsIso/Limits.lean | 2 + .../CategoryTheory/Functor/RegularEpi.lean | 1 + .../CategoryTheory/Functor/Trifunctor.lean | 4 + Mathlib/CategoryTheory/Functor/TwoSquare.lean | 3 +- Mathlib/CategoryTheory/Galois/Action.lean | 2 +- Mathlib/CategoryTheory/Galois/Basic.lean | 14 +- .../CategoryTheory/Galois/Decomposition.lean | 5 +- .../CategoryTheory/Galois/Equivalence.lean | 2 + Mathlib/CategoryTheory/Galois/EssSurj.lean | 2 +- Mathlib/CategoryTheory/Galois/Examples.lean | 2 +- Mathlib/CategoryTheory/Galois/Full.lean | 2 +- .../CategoryTheory/Galois/GaloisObjects.lean | 3 +- .../Galois/IsFundamentalgroup.lean | 3 +- .../Galois/Prorepresentability.lean | 8 +- Mathlib/CategoryTheory/Galois/Topology.lean | 4 +- Mathlib/CategoryTheory/Generator/Basic.lean | 2 +- .../CategoryTheory/Generator/Presheaf.lean | 1 + Mathlib/CategoryTheory/GlueData.lean | 2 + Mathlib/CategoryTheory/GradedObject.lean | 19 +++ .../GradedObject/Bifunctor.lean | 4 + .../CategoryTheory/GradedObject/Braiding.lean | 6 + .../CategoryTheory/GradedObject/Monoidal.lean | 4 + .../GradedObject/Trifunctor.lean | 11 ++ .../CategoryTheory/GradedObject/Unitor.lean | 7 +- Mathlib/CategoryTheory/Grothendieck.lean | 24 ++- Mathlib/CategoryTheory/Groupoid.lean | 8 +- .../CategoryTheory/Groupoid/FreeGroupoid.lean | 2 + .../Groupoid/FreeGroupoidOfCategory.lean | 1 + .../CategoryTheory/Groupoid/Subgroupoid.lean | 3 +- .../CategoryTheory/GuitartExact/Basic.lean | 9 ++ .../GuitartExact/HorizontalComposition.lean | 5 + .../GuitartExact/KanExtension.lean | 7 +- .../CategoryTheory/GuitartExact/Quotient.lean | 1 + .../GuitartExact/VerticalComposition.lean | 5 +- Mathlib/CategoryTheory/Idempotents/Basic.lean | 1 - .../Idempotents/FunctorCategories.lean | 3 + .../Idempotents/FunctorExtension.lean | 9 +- .../Idempotents/HomologicalComplex.lean | 4 + .../CategoryTheory/Idempotents/Karoubi.lean | 3 +- .../Idempotents/KaroubiKaroubi.lean | 9 ++ Mathlib/CategoryTheory/InducedCategory.lean | 4 +- Mathlib/CategoryTheory/IsConnected.lean | 3 +- Mathlib/CategoryTheory/IsoCat.lean | 3 +- Mathlib/CategoryTheory/Join/Basic.lean | 48 +++++- Mathlib/CategoryTheory/Join/Final.lean | 2 + Mathlib/CategoryTheory/Join/Opposites.lean | 21 ++- .../CategoryTheory/Join/Pseudofunctor.lean | 26 +++- .../LiftingProperties/Adjunction.lean | 1 - .../LiftingProperties/Over.lean | 1 + .../LiftingProperties/PushoutProduct.lean | 2 +- Mathlib/CategoryTheory/Limits/Chosen/End.lean | 1 + .../CategoryTheory/Limits/ColimitLimit.lean | 2 +- Mathlib/CategoryTheory/Limits/Comma.lean | 2 +- .../CategoryTheory/Limits/ConeCategory.lean | 21 ++- Mathlib/CategoryTheory/Limits/Cones.lean | 59 ++++++- Mathlib/CategoryTheory/Limits/Connected.lean | 2 + .../Constructions/EventuallyConstant.lean | 4 + .../FiniteProductsOfBinaryProducts.lean | 2 + .../LimitsOfProductsAndEqualizers.lean | 17 ++- .../Limits/Constructions/Over/Connected.lean | 4 + .../Limits/Constructions/Over/Products.lean | 8 + .../Limits/Constructions/ZeroObjects.lean | 4 + Mathlib/CategoryTheory/Limits/Creates.lean | 52 ++++--- Mathlib/CategoryTheory/Limits/Elements.lean | 2 + .../CategoryTheory/Limits/ExactFunctor.lean | 6 + .../FilteredColimitCommutesFiniteLimit.lean | 7 +- .../FilteredColimitCommutesProduct.lean | 4 + Mathlib/CategoryTheory/Limits/Final.lean | 27 ++-- Mathlib/CategoryTheory/Limits/FintypeCat.lean | 1 + .../Limits/FormalCoproducts/Basic.lean | 1 + .../FormalCoproducts/ExtraDegeneracy.lean | 1 + Mathlib/CategoryTheory/Limits/Fubini.lean | 3 +- .../Limits/FullSubcategory.lean | 12 +- .../Limits/FunctorCategory/Basic.lean | 6 + .../FunctorCategory/BinaryBiproducts.lean | 1 + .../Limits/FunctorCategory/EpiMono.lean | 2 +- .../Limits/FunctorCategory/Shapes/Images.lean | 1 + .../FunctorCategory/Shapes/Pullbacks.lean | 1 + Mathlib/CategoryTheory/Limits/HasLimits.lean | 19 +-- Mathlib/CategoryTheory/Limits/IndYoneda.lean | 8 + .../Limits/Indization/Category.lean | 3 +- .../Limits/Indization/FilteredColimits.lean | 2 +- .../Limits/Indization/IndObject.lean | 3 + .../Limits/Indization/LocallySmall.lean | 3 +- .../Limits/Indization/ParallelPair.lean | 2 +- Mathlib/CategoryTheory/Limits/IsLimit.lean | 23 ++- Mathlib/CategoryTheory/Limits/MonoCoprod.lean | 3 +- .../Limits/MorphismProperty.lean | 9 +- Mathlib/CategoryTheory/Limits/Over.lean | 2 + Mathlib/CategoryTheory/Limits/Preorder.lean | 16 +- .../Limits/Preserves/Basic.lean | 6 +- .../Limits/Preserves/Bifunctor.lean | 13 +- .../Limits/Preserves/BifunctorCokernel.lean | 1 + .../Limits/Preserves/Creates/Finite.lean | 18 +-- .../Limits/Preserves/Creates/Opposites.lean | 144 +++++++++--------- .../Limits/Preserves/FunctorCategory.lean | 2 +- .../Limits/Preserves/Grothendieck.lean | 2 +- .../Limits/Preserves/Limits.lean | 2 - .../CategoryTheory/Limits/Preserves/Over.lean | 2 + .../Limits/Preserves/Presheaf.lean | 3 + .../Preserves/Shapes/BinaryProducts.lean | 2 + .../Limits/Preserves/Shapes/Biproducts.lean | 1 + .../Limits/Preserves/Shapes/Equalizers.lean | 2 + .../Limits/Preserves/Shapes/Kernels.lean | 2 + .../Preserves/Shapes/Multiequalizer.lean | 2 + .../Limits/Preserves/Shapes/Over.lean | 2 + .../Limits/Preserves/Shapes/Products.lean | 2 + .../Limits/Preserves/Shapes/Pullbacks.lean | 5 + .../Limits/Preserves/Shapes/Square.lean | 1 + .../Limits/Preserves/SigmaConst.lean | 4 +- .../Limits/Preserves/Yoneda.lean | 2 +- Mathlib/CategoryTheory/Limits/Presheaf.lean | 8 +- .../Limits/Shapes/BinaryBiproducts.lean | 6 + .../Limits/Shapes/BinaryProducts.lean | 10 +- .../Limits/Shapes/Biproducts.lean | 5 + .../Limits/Shapes/ConcreteCategory.lean | 2 +- Mathlib/CategoryTheory/Limits/Shapes/End.lean | 7 + .../Limits/Shapes/Equalizers.lean | 12 +- .../Limits/Shapes/FiniteMultiequalizer.lean | 2 + .../Limits/Shapes/FunctorToTypes.lean | 13 ++ .../Limits/Shapes/Grothendieck.lean | 2 +- .../CategoryTheory/Limits/Shapes/Images.lean | 3 + .../Limits/Shapes/IsTerminal.lean | 14 +- .../Limits/Shapes/KernelPair.lean | 1 + .../CategoryTheory/Limits/Shapes/Kernels.lean | 15 ++ .../Limits/Shapes/Multiequalizer.lean | 12 ++ .../Limits/Shapes/NormalMono/Basic.lean | 26 ++-- .../Limits/Shapes/Opposites/Equalizers.lean | 14 ++ .../Limits/Shapes/Opposites/Products.lean | 10 +- .../Limits/Shapes/Opposites/Pullbacks.lean | 27 ++++ .../Limits/Shapes/Preorder/PrincipalSeg.lean | 1 + .../TransfiniteCompositionOfShape.lean | 1 + .../Limits/Shapes/Products.lean | 18 ++- .../Shapes/Pullback/Categorical/Basic.lean | 23 ++- .../Categorical/CatCospanTransform.lean | 8 + .../Limits/Shapes/Pullback/Cospan.lean | 10 ++ .../Shapes/Pullback/EquifiberedLimits.lean | 3 +- .../Shapes/Pullback/IsPullback/Basic.lean | 2 + .../Limits/Shapes/Pullback/Mono.lean | 2 + .../Limits/Shapes/Pullback/Pasting.lean | 4 + .../Limits/Shapes/Pullback/PullbackCone.lean | 11 ++ .../Shapes/Pullback/PullbackObjObj.lean | 2 + .../Limits/Shapes/Reflexive.lean | 7 +- .../Limits/Shapes/RegularMono.lean | 3 + .../Limits/Shapes/SequentialProduct.lean | 1 + .../Limits/Shapes/SingleObj.lean | 3 + .../Limits/Shapes/SplitCoequalizer.lean | 1 + .../Limits/Shapes/SplitEqualizer.lean | 1 + .../Limits/Shapes/WideEqualizers.lean | 9 ++ .../Limits/Shapes/WidePullbacks.lean | 12 ++ .../Limits/Shapes/ZeroMorphisms.lean | 5 +- Mathlib/CategoryTheory/Limits/Sifted.lean | 6 +- .../Limits/Types/ColimitType.lean | 1 - .../CategoryTheory/Limits/Types/Filtered.lean | 11 +- .../CategoryTheory/Limits/Types/Limits.lean | 1 + .../Limits/Types/Multicoequalizer.lean | 2 + .../CategoryTheory/Limits/Types/Products.lean | 4 + .../CategoryTheory/Limits/Types/Yoneda.lean | 4 +- Mathlib/CategoryTheory/Limits/VanKampen.lean | 6 + .../Limits/Weighted/HasWeightedLimit.lean | 2 +- Mathlib/CategoryTheory/Limits/Yoneda.lean | 5 +- .../Localization/Adjunction.lean | 5 +- .../Localization/Bifunctor.lean | 7 +- .../Localization/Bousfield.lean | 4 +- .../Localization/CalculusOfFractions.lean | 3 +- .../CalculusOfFractions/OfAdjunction.lean | 3 - .../CalculusOfFractions/Preadditive.lean | 6 +- .../Localization/Construction.lean | 2 +- .../DerivabilityStructure/Basic.lean | 4 +- .../DerivabilityStructure/Constructor.lean | 2 + .../DerivabilityStructure/Derives.lean | 1 - .../OfFunctorialResolutions.lean | 5 +- .../OfLocalizedEquivalences.lean | 6 +- .../PointwiseRightDerived.lean | 4 +- .../Localization/FiniteProducts.lean | 3 +- .../Localization/HasLocalization.lean | 2 +- .../CategoryTheory/Localization/HomEquiv.lean | 4 +- .../CategoryTheory/Localization/Linear.lean | 2 +- .../Localization/LocalizerMorphism.lean | 4 +- .../Localization/LocallySmall.lean | 4 +- .../Localization/Monoidal/Basic.lean | 6 +- .../Localization/Monoidal/Braided.lean | 7 + .../Localization/Monoidal/Functor.lean | 9 +- .../Localization/Predicate.lean | 7 +- Mathlib/CategoryTheory/Localization/Prod.lean | 2 +- .../Localization/Resolution.lean | 1 + .../CategoryTheory/Localization/SmallHom.lean | 3 - .../Localization/SmallShiftedHom.lean | 6 +- .../Localization/Triangulated.lean | 2 +- .../Localization/Trifunctor.lean | 7 +- .../ChosenPullbacksAlong.lean | 16 +- .../ExponentiableMorphism.lean | 6 +- .../LocallyCartesianClosed/Over.lean | 34 +++++ .../LocallyCartesianClosed/Sections.lean | 5 + Mathlib/CategoryTheory/LocallyDirected.lean | 1 + Mathlib/CategoryTheory/Monad/Adjunction.lean | 16 +- Mathlib/CategoryTheory/Monad/Algebra.lean | 7 +- Mathlib/CategoryTheory/Monad/Basic.lean | 12 +- Mathlib/CategoryTheory/Monad/Coequalizer.lean | 1 - .../CategoryTheory/Monad/Comonadicity.lean | 18 ++- Mathlib/CategoryTheory/Monad/Equalizer.lean | 1 - Mathlib/CategoryTheory/Monad/EquivMon.lean | 1 - Mathlib/CategoryTheory/Monad/Kleisli.lean | 9 +- Mathlib/CategoryTheory/Monad/Limits.lean | 22 +-- Mathlib/CategoryTheory/Monad/Monadicity.lean | 16 +- Mathlib/CategoryTheory/Monad/Products.lean | 2 +- .../CategoryTheory/Monoidal/Action/Basic.lean | 2 + .../CategoryTheory/Monoidal/Action/End.lean | 6 +- .../Monoidal/Action/Opposites.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Arrow.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Bimod.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Bimon_.lean | 16 ++ .../Monoidal/Braided/Basic.lean | 14 +- .../Monoidal/Braided/Multifunctor.lean | 21 ++- .../Monoidal/Braided/Reflection.lean | 8 +- .../Monoidal/Cartesian/Basic.lean | 10 +- .../Monoidal/Cartesian/Cat.lean | 1 + .../Monoidal/Cartesian/CommGrp_.lean | 2 +- .../Monoidal/Cartesian/FunctorCategory.lean | 1 + .../Monoidal/Cartesian/Grp.lean | 8 +- .../Monoidal/Cartesian/GrpLimits.lean | 2 +- .../Monoidal/Cartesian/Mon.lean | 8 +- .../Monoidal/Cartesian/Over.lean | 45 +++++- Mathlib/CategoryTheory/Monoidal/Category.lean | 10 +- Mathlib/CategoryTheory/Monoidal/Center.lean | 29 ++++ .../CategoryTheory/Monoidal/Closed/Basic.lean | 16 +- .../Monoidal/Closed/Cartesian.lean | 2 +- .../Monoidal/Closed/Functor.lean | 3 +- .../Closed/FunctorCategory/Basic.lean | 3 +- .../Closed/FunctorCategory/Complete.lean | 4 +- .../Closed/FunctorCategory/Groupoid.lean | 5 +- .../CategoryTheory/Monoidal/Closed/Ideal.lean | 5 +- .../CategoryTheory/Monoidal/Closed/Types.lean | 2 +- .../CategoryTheory/Monoidal/Closed/Zero.lean | 2 +- .../CategoryTheory/Monoidal/CommComon_.lean | 2 +- Mathlib/CategoryTheory/Monoidal/CommGrp_.lean | 5 +- Mathlib/CategoryTheory/Monoidal/CommMon_.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Comon_.lean | 3 + Mathlib/CategoryTheory/Monoidal/Conv.lean | 1 + .../Monoidal/DayConvolution.lean | 35 +++-- .../Monoidal/DayConvolution/Closed.lean | 1 - .../Monoidal/DayConvolution/DayFunctor.lean | 1 + Mathlib/CategoryTheory/Monoidal/End.lean | 15 +- .../Monoidal/ExternalProduct/Basic.lean | 9 +- .../ExternalProduct/KanExtension.lean | 4 +- .../Monoidal/Free/Coherence.lean | 6 +- Mathlib/CategoryTheory/Monoidal/Functor.lean | 47 +++--- .../Monoidal/FunctorCategory.lean | 5 + Mathlib/CategoryTheory/Monoidal/Grp.lean | 13 +- Mathlib/CategoryTheory/Monoidal/Hopf_.lean | 4 + .../Monoidal/Internal/FunctorCategory.lean | 10 ++ .../Monoidal/Internal/Limits.lean | 1 + .../Monoidal/Internal/Module.lean | 2 +- .../CategoryTheory/Monoidal/Limits/Basic.lean | 3 + .../Monoidal/Limits/Colimits.lean | 1 + Mathlib/CategoryTheory/Monoidal/Mod.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Mon.lean | 10 +- .../CategoryTheory/Monoidal/Multifunctor.lean | 21 ++- .../Monoidal/NaturalTransformation.lean | 2 - .../Monoidal/OfHasFiniteProducts.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Opposite.lean | 44 +++++- .../CategoryTheory/Monoidal/Opposite/Mon.lean | 2 + .../Monoidal/PushoutProduct.lean | 4 +- .../CategoryTheory/Monoidal/Rigid/Basic.lean | 22 ++- .../Monoidal/Rigid/Braided.lean | 14 +- .../Monoidal/Rigid/OfEquivalence.lean | 14 +- Mathlib/CategoryTheory/Monoidal/Skeleton.lean | 2 +- .../CategoryTheory/Monoidal/Subcategory.lean | 2 + .../CategoryTheory/Monoidal/Transport.lean | 6 +- .../MorphismProperty/Basic.lean | 2 + .../MorphismProperty/Comma.lean | 15 ++ .../MorphismProperty/Concrete.lean | 1 + .../MorphismProperty/Factorization.lean | 8 + .../MorphismProperty/Limits.lean | 1 + .../MorphismProperty/Local.lean | 1 + .../MorphismProperty/OverAdjunction.lean | 26 +++- .../MorphismProperty/Representable.lean | 4 + Mathlib/CategoryTheory/NatTrans.lean | 1 + .../ObjectProperty/Equivalence.lean | 1 + .../ObjectProperty/FiniteProducts.lean | 2 + .../ObjectProperty/FullSubcategory.lean | 7 +- .../ObjectProperty/LimitsClosure.lean | 1 + .../ObjectProperty/LimitsOfShape.lean | 1 + .../ObjectProperty/Opposite.lean | 1 + Mathlib/CategoryTheory/Opposites.lean | 16 +- Mathlib/CategoryTheory/PUnit.lean | 1 + .../CategoryTheory/PathCategory/Basic.lean | 17 +++ .../PathCategory/MorphismProperty.lean | 3 + Mathlib/CategoryTheory/Pi/Basic.lean | 9 +- Mathlib/CategoryTheory/Pi/Monoidal.lean | 7 + .../Preadditive/Biproducts.lean | 12 ++ .../CategoryTheory/Preadditive/CommGrp_.lean | 1 + .../Preadditive/Injective/Basic.lean | 2 - .../Preadditive/Injective/Preserves.lean | 1 - .../CategoryTheory/Preadditive/LeftExact.lean | 1 + Mathlib/CategoryTheory/Preadditive/Mat.lean | 11 +- .../Preadditive/Projective/Basic.lean | 2 - .../Preadditive/Projective/Preserves.lean | 1 - .../Preadditive/Projective/Resolution.lean | 2 +- Mathlib/CategoryTheory/Preadditive/Schur.lean | 2 +- .../CategoryTheory/Preadditive/Transfer.lean | 2 +- .../Preadditive/Yoneda/Basic.lean | 5 + .../Presentable/Adjunction.lean | 1 - .../Presentable/CardinalDirectedPoset.lean | 3 + Mathlib/CategoryTheory/Presentable/Dense.lean | 1 + .../Presentable/IsCardinalFiltered.lean | 4 + Mathlib/CategoryTheory/Presentable/Type.lean | 2 +- .../CategoryTheory/Products/Associator.lean | 5 +- Mathlib/CategoryTheory/Products/Basic.lean | 15 +- .../CategoryTheory/Products/Bifunctor.lean | 2 +- Mathlib/CategoryTheory/Products/Unitor.lean | 2 +- Mathlib/CategoryTheory/Quotient.lean | 8 +- Mathlib/CategoryTheory/Quotient/Linear.lean | 8 +- .../CategoryTheory/Quotient/Preadditive.lean | 2 +- Mathlib/CategoryTheory/Retract.lean | 6 + Mathlib/CategoryTheory/Shift/Adjunction.lean | 19 +-- Mathlib/CategoryTheory/Shift/Basic.lean | 35 ++--- Mathlib/CategoryTheory/Shift/CommShift.lean | 28 +--- .../CategoryTheory/Shift/CommShiftTwo.lean | 2 + Mathlib/CategoryTheory/Shift/Induced.lean | 11 +- .../Shift/InducedShiftSequence.lean | 3 +- .../CategoryTheory/Shift/Localization.lean | 11 +- Mathlib/CategoryTheory/Shift/Opposite.lean | 11 +- Mathlib/CategoryTheory/Shift/Pullback.lean | 5 +- .../CategoryTheory/Shift/ShiftSequence.lean | 6 +- Mathlib/CategoryTheory/Shift/ShiftedHom.lean | 7 - .../Shift/ShiftedHomOpposite.lean | 2 - .../CategoryTheory/Shift/SingleFunctors.lean | 2 - .../Shift/SingleFunctorsLift.lean | 4 +- Mathlib/CategoryTheory/ShrinkYoneda.lean | 8 + Mathlib/CategoryTheory/Sigma/Basic.lean | 3 + Mathlib/CategoryTheory/SingleObj.lean | 1 + Mathlib/CategoryTheory/Sites/Adjunction.lean | 2 +- Mathlib/CategoryTheory/Sites/Canonical.lean | 8 +- .../Sites/Coherent/RegularSheaves.lean | 3 +- .../Sites/Coherent/SheafComparison.lean | 3 +- .../CategoryTheory/Sites/CompatiblePlus.lean | 2 +- .../Sites/CompatibleSheafification.lean | 5 + .../Sites/ConcreteSheafification.lean | 6 + .../CategoryTheory/Sites/ConstantSheaf.lean | 4 +- Mathlib/CategoryTheory/Sites/Continuous.lean | 7 +- .../CategoryTheory/Sites/CoverLifting.lean | 3 +- .../CategoryTheory/Sites/CoverPreserving.lean | 1 + .../Sites/DenseSubsite/Basic.lean | 8 +- .../DenseSubsite/OneHypercoverDense.lean | 16 +- .../Sites/Descent/DescentData.lean | 6 +- .../Sites/Descent/DescentDataAsCoalgebra.lean | 3 + .../Sites/Descent/DescentDataPrime.lean | 1 + .../Sites/Descent/IsPrestack.lean | 2 +- .../Sites/Descent/Precoverage.lean | 4 + .../Sites/EffectiveEpimorphic.lean | 2 + Mathlib/CategoryTheory/Sites/EpiMono.lean | 2 +- .../Sites/EqualizerSheafCondition.lean | 4 + Mathlib/CategoryTheory/Sites/Equivalence.lean | 7 +- .../CategoryTheory/Sites/GlobalSections.lean | 1 + .../CategoryTheory/Sites/Grothendieck.lean | 2 + .../Sites/Hypercover/Homotopy.lean | 1 + .../Sites/Hypercover/IsSheaf.lean | 1 + .../CategoryTheory/Sites/Hypercover/One.lean | 36 +++++ .../Sites/Hypercover/Saturate.lean | 3 + .../CategoryTheory/Sites/Hypercover/Zero.lean | 14 +- Mathlib/CategoryTheory/Sites/IsSheafFor.lean | 3 + Mathlib/CategoryTheory/Sites/Limits.lean | 3 +- Mathlib/CategoryTheory/Sites/LocalSite.lean | 1 + Mathlib/CategoryTheory/Sites/Monoidal.lean | 4 +- Mathlib/CategoryTheory/Sites/Over.lean | 16 ++ Mathlib/CategoryTheory/Sites/Point/Basic.lean | 2 +- Mathlib/CategoryTheory/Sites/Point/Comap.lean | 1 - .../Sites/Point/Conservative.lean | 2 - Mathlib/CategoryTheory/Sites/Point/Map.lean | 1 + .../CategoryTheory/Sites/Point/Monoidal.lean | 2 +- .../Sites/Point/OfIsCofiltered.lean | 1 + .../Sites/Point/Skyscraper.lean | 7 + Mathlib/CategoryTheory/Sites/Precoverage.lean | 4 +- Mathlib/CategoryTheory/Sites/Preserves.lean | 1 + .../Sites/PreservesLocallyBijective.lean | 1 + .../Sites/PreservesSheafification.lean | 8 +- .../Sites/PseudofunctorSheafOver.lean | 1 + Mathlib/CategoryTheory/Sites/Sheaf.lean | 13 +- Mathlib/CategoryTheory/Sites/SheafHom.lean | 5 + .../CategoryTheory/Sites/SheafOfTypes.lean | 1 + .../CategoryTheory/Sites/Sheafification.lean | 4 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 14 +- .../CategoryTheory/Sites/Subcanonical.lean | 9 +- Mathlib/CategoryTheory/Sites/Subsheaf.lean | 6 + Mathlib/CategoryTheory/Sites/Whiskering.lean | 5 +- Mathlib/CategoryTheory/Skeletal.lean | 8 +- .../SmallObject/Construction.lean | 3 +- .../IsCardinalForSmallObjectArgument.lean | 6 +- .../SmallObject/Iteration/Basic.lean | 2 + .../SmallObject/Iteration/Nonempty.lean | 3 +- .../TransfiniteCompositionLifting.lean | 2 + .../SmallObject/TransfiniteIteration.lean | 5 + .../SmallObject/WellOrderInductionData.lean | 1 + .../CategoryTheory/SmallRepresentatives.lean | 4 + Mathlib/CategoryTheory/Square.lean | 7 + .../CategoryTheory/Subfunctor/Equalizer.lean | 3 + .../Subfunctor/SubmonoidFunctor.lean | 1 + .../Subobject/ArtinianObject.lean | 1 + Mathlib/CategoryTheory/Subobject/Basic.lean | 8 + .../Subobject/Classifier/Defs.lean | 10 +- Mathlib/CategoryTheory/Subobject/Comma.lean | 1 + .../CategoryTheory/Subobject/FactorThru.lean | 1 + Mathlib/CategoryTheory/Subobject/Lattice.lean | 6 + Mathlib/CategoryTheory/Subobject/Limits.lean | 6 + .../CategoryTheory/Subobject/MonoOver.lean | 2 + .../Subobject/NoetherianObject.lean | 1 + Mathlib/CategoryTheory/Sums/Associator.lean | 5 + Mathlib/CategoryTheory/Sums/Basic.lean | 4 +- Mathlib/CategoryTheory/Sums/Products.lean | 10 +- Mathlib/CategoryTheory/Thin.lean | 2 +- Mathlib/CategoryTheory/Topos/Sheaf.lean | 6 +- .../Triangulated/Adjunction.lean | 2 +- .../CategoryTheory/Triangulated/Basic.lean | 2 +- .../CategoryTheory/Triangulated/Functor.lean | 8 +- .../Triangulated/HomologicalFunctor.lean | 3 +- .../Triangulated/LocalizingSubcategory.lean | 6 +- .../Triangulated/Opposite/Basic.lean | 30 +++- .../Triangulated/Opposite/Functor.lean | 6 +- .../Opposite/Pretriangulated.lean | 2 +- .../Triangulated/Opposite/Triangle.lean | 3 +- .../Triangulated/Pretriangulated.lean | 5 +- .../Triangulated/Subcategory.lean | 5 +- .../TStructure/AbelianSubcategory.lean | 2 +- .../Triangulated/TStructure/Basic.lean | 1 + .../Triangulated/TStructure/ETrunc.lean | 5 +- .../Triangulated/TStructure/Heart.lean | 2 +- .../TStructure/SpectralObject.lean | 3 +- .../Triangulated/TStructure/TruncLEGT.lean | 8 +- .../Triangulated/TStructure/TruncLTGE.lean | 20 +-- .../Triangulated/TriangleShift.lean | 2 +- .../CategoryTheory/Triangulated/Yoneda.lean | 1 + Mathlib/CategoryTheory/Whiskering.lean | 20 ++- .../CategoryTheory/WithTerminal/Basic.lean | 56 ++++++- Mathlib/CategoryTheory/WithTerminal/Cone.lean | 12 ++ Mathlib/CategoryTheory/Yoneda.lean | 16 +- .../Combinatorics/Additive/Corner/Roth.lean | 3 +- Mathlib/Combinatorics/Additive/Energy.lean | 1 + Mathlib/Combinatorics/Colex.lean | 1 + Mathlib/Combinatorics/Configuration.lean | 4 +- Mathlib/Combinatorics/Derangements/Basic.lean | 2 + .../Enumerative/Catalan/Tree.lean | 1 + .../Enumerative/Composition.lean | 6 + .../Combinatorics/Enumerative/DyckWord.lean | 2 + .../Enumerative/InclusionExclusion.lean | 1 + .../Enumerative/Partition/Basic.lean | 1 + .../Extremal/RuzsaSzemeredi.lean | 1 + Mathlib/Combinatorics/Hall/Basic.lean | 2 + Mathlib/Combinatorics/Hall/Finite.lean | 1 + Mathlib/Combinatorics/Hindman.lean | 4 +- Mathlib/Combinatorics/KatonaCircle.lean | 1 + Mathlib/Combinatorics/Matroid/Basic.lean | 1 + .../Combinatorics/Matroid/IndepAxioms.lean | 3 +- Mathlib/Combinatorics/Matroid/Map.lean | 4 + Mathlib/Combinatorics/Matroid/Sum.lean | 1 + .../Combinatorics/Quiver/Arborescence.lean | 3 +- .../Quiver/ConnectedComponent.lean | 4 +- Mathlib/Combinatorics/Quiver/Push.lean | 1 + Mathlib/Combinatorics/Quiver/SingleObj.lean | 2 +- Mathlib/Combinatorics/Schnirelmann.lean | 1 + .../SetFamily/AhlswedeZhang.lean | 1 + .../SetFamily/FourFunctions.lean | 1 + .../SetFamily/KruskalKatona.lean | 2 +- .../Combinatorics/SimpleGraph/Acyclic.lean | 3 + .../Combinatorics/SimpleGraph/AdjMatrix.lean | 3 +- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 1 + .../Combinatorics/SimpleGraph/Bipartite.lean | 2 + Mathlib/Combinatorics/SimpleGraph/Clique.lean | 3 + .../SimpleGraph/CompleteMultipartite.lean | 7 +- .../SimpleGraph/Connectivity/Connected.lean | 2 +- .../SimpleGraph/Connectivity/Finite.lean | 3 + Mathlib/Combinatorics/SimpleGraph/Copy.lean | 1 + Mathlib/Combinatorics/SimpleGraph/Dart.lean | 1 + .../Combinatorics/SimpleGraph/Ends/Defs.lean | 2 + .../Extremal/ErdosStoneSimonovits.lean | 2 + .../SimpleGraph/Extremal/Turan.lean | 4 +- .../SimpleGraph/Hamiltonian.lean | 2 +- .../Combinatorics/SimpleGraph/IncMatrix.lean | 1 + .../Combinatorics/SimpleGraph/LapMatrix.lean | 1 + .../Combinatorics/SimpleGraph/LineGraph.lean | 1 + Mathlib/Combinatorics/SimpleGraph/Maps.lean | 2 + .../Combinatorics/SimpleGraph/Matching.lean | 3 + Mathlib/Combinatorics/SimpleGraph/Paths.lean | 2 + .../SimpleGraph/StronglyRegular.lean | 2 + .../Combinatorics/SimpleGraph/Subgraph.lean | 9 +- Mathlib/Combinatorics/SimpleGraph/Sum.lean | 4 + Mathlib/Combinatorics/SimpleGraph/Trails.lean | 4 +- Mathlib/Combinatorics/SimpleGraph/Tutte.lean | 1 + .../Combinatorics/SimpleGraph/Walk/Basic.lean | 2 + .../SimpleGraph/Walk/Counting.lean | 2 + .../SimpleGraph/Walk/Decomp.lean | 2 + .../Combinatorics/SimpleGraph/Walk/Maps.lean | 6 + .../SimpleGraph/Walk/Operations.lean | 9 +- Mathlib/Combinatorics/Young/YoungDiagram.lean | 2 + Mathlib/Computability/Ackermann.lean | 3 + Mathlib/Computability/ContextFreeGrammar.lean | 1 + Mathlib/Computability/DFA.lean | 1 + Mathlib/Computability/Encoding.lean | 1 + Mathlib/Computability/Language.lean | 4 + Mathlib/Computability/NFA.lean | 1 + Mathlib/Computability/Partrec.lean | 8 + Mathlib/Computability/PartrecBasis.lean | 5 +- Mathlib/Computability/PartrecCode.lean | 10 +- Mathlib/Computability/Primrec/Basic.lean | 4 +- Mathlib/Computability/Primrec/List.lean | 4 +- Mathlib/Computability/RE.lean | 1 + Mathlib/Computability/Reduce.lean | 3 + .../Computability/TuringMachine/Config.lean | 10 ++ .../TuringMachine/StackTuringMachine.lean | 5 +- Mathlib/Computability/TuringMachine/Tape.lean | 2 +- .../TuringMachine/ToPartrec.lean | 5 + Mathlib/Condensed/Discrete/Colimit.lean | 24 ++- .../Condensed/Discrete/LocallyConstant.lean | 3 + Mathlib/Condensed/Light/Functors.lean | 1 + .../Condensed/Light/InternallyProjective.lean | 1 - Mathlib/Condensed/Light/Small.lean | 1 + Mathlib/Condensed/Light/TopCatAdjunction.lean | 4 + Mathlib/Condensed/TopCatAdjunction.lean | 5 + Mathlib/Control/Applicative.lean | 3 + Mathlib/Control/Bifunctor.lean | 3 + Mathlib/Control/EquivFunctor.lean | 1 + Mathlib/Control/Fold.lean | 4 + Mathlib/Control/Functor.lean | 2 + Mathlib/Control/Functor/Multivariate.lean | 7 +- Mathlib/Control/LawfulFix.lean | 2 +- Mathlib/Control/Monad/Writer.lean | 2 +- Mathlib/Control/Traversable/Equiv.lean | 4 +- Mathlib/Control/ULiftable.lean | 8 +- Mathlib/Data/Analysis/Filter.lean | 2 + Mathlib/Data/Analysis/Topology.lean | 2 +- Mathlib/Data/Complex/Basic.lean | 7 +- Mathlib/Data/DFinsupp/BigOperators.lean | 2 + Mathlib/Data/DFinsupp/Defs.lean | 2 + Mathlib/Data/DFinsupp/Lex.lean | 17 +++ Mathlib/Data/DFinsupp/Multiset.lean | 1 + Mathlib/Data/DFinsupp/WellFounded.lean | 4 + Mathlib/Data/ENNReal/Action.lean | 1 + Mathlib/Data/ENNReal/Inv.lean | 2 + Mathlib/Data/ENNReal/Operations.lean | 2 + Mathlib/Data/EReal/Inv.lean | 1 + Mathlib/Data/EReal/Operations.lean | 2 + Mathlib/Data/Fin/Fin2.lean | 1 + Mathlib/Data/Fin/Tuple/Basic.lean | 4 + Mathlib/Data/Fin/Tuple/Embedding.lean | 1 + Mathlib/Data/Fin/Tuple/Sort.lean | 1 + Mathlib/Data/Fin/Tuple/Take.lean | 1 + Mathlib/Data/FinEnum.lean | 14 +- Mathlib/Data/FinEnum/Option.lean | 2 +- Mathlib/Data/Finmap.lean | 1 + Mathlib/Data/Finset/Defs.lean | 2 + Mathlib/Data/Finset/Image.lean | 6 + Mathlib/Data/Finset/Insert.lean | 1 + Mathlib/Data/Finset/Lattice/Prod.lean | 1 + Mathlib/Data/Finset/NatAntidiagonal.lean | 5 +- Mathlib/Data/Finset/NoncommProd.lean | 8 + Mathlib/Data/Finset/PImage.lean | 1 + Mathlib/Data/Finset/Powerset.lean | 2 + Mathlib/Data/Finset/Preimage.lean | 2 + Mathlib/Data/Finset/Sum.lean | 1 + Mathlib/Data/Finset/Union.lean | 2 + Mathlib/Data/Finsupp/Basic.lean | 9 ++ Mathlib/Data/Finsupp/Defs.lean | 1 + Mathlib/Data/Finsupp/Lex.lean | 7 + Mathlib/Data/Finsupp/ToDFinsupp.lean | 1 + Mathlib/Data/Finsupp/Weight.lean | 2 + Mathlib/Data/Fintype/Basic.lean | 4 +- Mathlib/Data/Fintype/Card.lean | 5 +- Mathlib/Data/Fintype/Defs.lean | 4 +- Mathlib/Data/Fintype/EquivFin.lean | 4 +- Mathlib/Data/Fintype/OfMap.lean | 16 +- Mathlib/Data/Fintype/Option.lean | 4 +- Mathlib/Data/Fintype/Perm.lean | 3 +- Mathlib/Data/Fintype/Quotient.lean | 3 +- Mathlib/Data/Fintype/Sets.lean | 4 +- Mathlib/Data/Fintype/Sum.lean | 2 +- Mathlib/Data/FunLike/Fintype.lean | 4 +- Mathlib/Data/Holor.lean | 3 + Mathlib/Data/Int/Cast/Lemmas.lean | 2 +- .../Data/Int/ConditionallyCompleteOrder.lean | 3 + Mathlib/Data/Int/WithZero.lean | 2 + Mathlib/Data/List/Cycle.lean | 1 + Mathlib/Data/List/GetD.lean | 2 +- Mathlib/Data/List/NodupEquivFin.lean | 1 + Mathlib/Data/List/Rotate.lean | 2 +- Mathlib/Data/Matrix/Basic.lean | 1 + Mathlib/Data/Matrix/Basis.lean | 1 + Mathlib/Data/Matrix/Block.lean | 1 + Mathlib/Data/Matrix/ColumnRowPartitioned.lean | 1 + Mathlib/Data/Matrix/Composition.lean | 1 + Mathlib/Data/Matrix/Mul.lean | 2 + Mathlib/Data/Matrix/PEquiv.lean | 1 + Mathlib/Data/Matrix/Reflection.lean | 4 + Mathlib/Data/Multiset/Bind.lean | 1 + Mathlib/Data/Multiset/Filter.lean | 8 +- Mathlib/Data/Multiset/Find.lean | 5 +- Mathlib/Data/Multiset/Fintype.lean | 3 + Mathlib/Data/Multiset/Functor.lean | 1 + Mathlib/Data/Multiset/MapFold.lean | 1 + Mathlib/Data/Multiset/Powerset.lean | 1 + Mathlib/Data/NNRat/Defs.lean | 5 + Mathlib/Data/Nat/Cast/Basic.lean | 2 +- Mathlib/Data/Nat/Choose/Multinomial.lean | 2 +- Mathlib/Data/Nat/Factorization/PrimePow.lean | 1 + Mathlib/Data/Nat/Nth.lean | 1 + Mathlib/Data/Nat/Totient.lean | 3 +- Mathlib/Data/Ordmap/Invariants.lean | 1 + Mathlib/Data/Ordmap/Ordset.lean | 2 + Mathlib/Data/PEquiv.lean | 2 + Mathlib/Data/PFun.lean | 7 + Mathlib/Data/PFunctor/Multivariate/Basic.lean | 2 + Mathlib/Data/PFunctor/Multivariate/M.lean | 4 + Mathlib/Data/PFunctor/Multivariate/W.lean | 3 + Mathlib/Data/PFunctor/Univariate/Basic.lean | 2 + Mathlib/Data/PFunctor/Univariate/M.lean | 3 + Mathlib/Data/PNat/Basic.lean | 1 + Mathlib/Data/PNat/Factors.lean | 7 + Mathlib/Data/PNat/Find.lean | 1 + Mathlib/Data/PNat/Interval.lean | 5 + Mathlib/Data/PNat/Prime.lean | 1 + Mathlib/Data/PNat/Xgcd.lean | 1 + Mathlib/Data/Part.lean | 4 +- Mathlib/Data/QPF/Multivariate/Basic.lean | 8 +- .../QPF/Multivariate/Constructions/Cofix.lean | 3 + .../QPF/Multivariate/Constructions/Comp.lean | 1 + .../QPF/Multivariate/Constructions/Fix.lean | 3 + .../QPF/Multivariate/Constructions/Quot.lean | 6 +- .../QPF/Multivariate/Constructions/Sigma.lean | 1 + Mathlib/Data/QPF/Univariate/Basic.lean | 19 ++- Mathlib/Data/Quot.lean | 2 +- Mathlib/Data/Rat/Cast/Defs.lean | 2 + Mathlib/Data/Rat/Cast/Lemmas.lean | 1 + Mathlib/Data/Rat/Cast/OfScientific.lean | 1 + Mathlib/Data/Rat/Lemmas.lean | 1 + Mathlib/Data/Semiquot.lean | 1 + Mathlib/Data/Seq/Basic.lean | 25 ++- Mathlib/Data/Seq/Defs.lean | 2 + Mathlib/Data/Set/Card.lean | 3 +- Mathlib/Data/Set/Countable.lean | 2 +- Mathlib/Data/Set/Defs.lean | 2 + Mathlib/Data/Set/Finite/Basic.lean | 15 +- Mathlib/Data/Set/Finite/Lattice.lean | 2 +- Mathlib/Data/Set/Finite/Monad.lean | 2 +- Mathlib/Data/Set/NAry.lean | 1 + Mathlib/Data/Set/Operations.lean | 1 + Mathlib/Data/Set/Pairwise/Lattice.lean | 1 + Mathlib/Data/Set/Restrict.lean | 1 + Mathlib/Data/Setoid/Basic.lean | 8 +- Mathlib/Data/Setoid/Partition.lean | 7 +- Mathlib/Data/Sign/Basic.lean | 1 + Mathlib/Data/Sign/Defs.lean | 1 + Mathlib/Data/String/Basic.lean | 3 +- Mathlib/Data/Sum/Basic.lean | 2 + Mathlib/Data/Sym/Basic.lean | 6 + Mathlib/Data/Sym/Sym2.lean | 5 + Mathlib/Data/TypeVec.lean | 7 + Mathlib/Data/Vector/Basic.lean | 10 ++ Mathlib/Data/Vector/Defs.lean | 1 + Mathlib/Data/W/Basic.lean | 4 +- Mathlib/Data/W/Constructions.lean | 1 + Mathlib/Data/WSeq/Basic.lean | 13 ++ Mathlib/Data/ZMod/Aut.lean | 1 + Mathlib/Data/ZMod/Basic.lean | 3 + .../RotationNumber/TranslationNumber.lean | 1 + .../Dynamics/Ergodic/Action/OfMinimal.lean | 1 + Mathlib/Dynamics/Ergodic/AddCircle.lean | 1 + Mathlib/Dynamics/Ergodic/Ergodic.lean | 1 + Mathlib/Dynamics/Flow.lean | 2 +- Mathlib/FieldTheory/AxGrothendieck.lean | 2 +- Mathlib/FieldTheory/CardinalEmb.lean | 1 + Mathlib/FieldTheory/Differential/Basic.lean | 2 +- Mathlib/FieldTheory/Extension.lean | 1 + Mathlib/FieldTheory/Finite/Basic.lean | 2 +- Mathlib/FieldTheory/Finiteness.lean | 2 +- Mathlib/FieldTheory/Fixed.lean | 6 + Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 2 + .../IntermediateField/Adjoin/Basic.lean | 2 +- .../IsAlgClosed/AlgebraicClosure.lean | 2 + Mathlib/FieldTheory/Isaacs.lean | 1 + Mathlib/FieldTheory/KrullTopology.lean | 2 +- Mathlib/FieldTheory/KummerExtension.lean | 1 + Mathlib/FieldTheory/Minpoly/Field.lean | 2 +- Mathlib/FieldTheory/Minpoly/IsConjRoot.lean | 2 +- .../Minpoly/IsIntegrallyClosed.lean | 1 + Mathlib/FieldTheory/Perfect.lean | 1 + .../FieldTheory/PolynomialGaloisGroup.lean | 10 +- Mathlib/FieldTheory/PrimitiveElement.lean | 1 + .../FieldTheory/PurelyInseparable/Basic.lean | 1 + Mathlib/FieldTheory/RatFunc/Basic.lean | 23 ++- .../RatFunc/IntermediateField.lean | 1 + Mathlib/FieldTheory/RatFunc/Valuation.lean | 2 +- Mathlib/FieldTheory/SeparablyGenerated.lean | 1 + Mathlib/Geometry/Convex/Cone/Basic.lean | 2 +- Mathlib/Geometry/Convex/Cone/Pointed.lean | 3 + .../Convex/ConvexSpace/AffineSpace.lean | 1 + Mathlib/Geometry/Convex/ConvexSpace/Defs.lean | 1 + Mathlib/Geometry/Convex/Hull.lean | 2 + Mathlib/Geometry/Convex/Set.lean | 1 + Mathlib/Geometry/Diffeology/Basic.lean | 8 +- Mathlib/Geometry/Euclidean/Altitude.lean | 1 + Mathlib/Geometry/Euclidean/Incenter.lean | 2 + .../Geometry/Euclidean/Inversion/Basic.lean | 1 + Mathlib/Geometry/Euclidean/MongePoint.lean | 1 + Mathlib/Geometry/Euclidean/PerpBisector.lean | 1 + Mathlib/Geometry/Euclidean/SignedDist.lean | 6 + Mathlib/Geometry/Euclidean/Sphere/Basic.lean | 1 + .../Euclidean/Sphere/SecondInter.lean | 3 + .../Geometry/Euclidean/Sphere/Tangent.lean | 2 + .../Algebra/LeftInvariantDerivation.lean | 3 + Mathlib/Geometry/Manifold/ChartedSpace.lean | 14 +- .../Geometry/Manifold/ContMDiff/Atlas.lean | 2 + .../Geometry/Manifold/ContMDiff/Basic.lean | 2 + Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 2 + .../Manifold/ContMDiff/NormedSpace.lean | 1 + .../Geometry/Manifold/GroupLieAlgebra.lean | 1 + Mathlib/Geometry/Manifold/HasGroupoid.lean | 4 +- Mathlib/Geometry/Manifold/Immersion.lean | 1 + Mathlib/Geometry/Manifold/Instances/Icc.lean | 1 + Mathlib/Geometry/Manifold/Instances/Real.lean | 3 + .../Geometry/Manifold/Instances/Sphere.lean | 3 + .../Geometry/Manifold/IsManifold/Basic.lean | 2 + .../Manifold/IsManifold/ExtChartAt.lean | 5 + .../Manifold/IsManifold/InteriorBoundary.lean | 2 +- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 1 + Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 11 +- Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean | 3 + .../Manifold/MFDeriv/NormedSpace.lean | 1 + .../Manifold/MFDeriv/SpecificFunctions.lean | 15 +- .../Geometry/Manifold/MFDeriv/Tangent.lean | 2 + .../Geometry/Manifold/PartitionOfUnity.lean | 2 +- .../Manifold/Sheaf/LocallyRingedSpace.lean | 3 + Mathlib/Geometry/Manifold/Sheaf/Smooth.lean | 11 ++ .../Manifold/VectorBundle/LocalFrame.lean | 4 +- .../Manifold/VectorBundle/Tangent.lean | 2 + .../Manifold/VectorField/LieBracket.lean | 3 + .../Manifold/VectorField/Pullback.lean | 2 + Mathlib/Geometry/RingedSpace/Basic.lean | 1 + .../RingedSpace/LocallyRingedSpace.lean | 8 + .../LocallyRingedSpace/HasColimits.lean | 1 + .../LocallyRingedSpace/ResidueField.lean | 2 + .../Geometry/RingedSpace/OpenImmersion.lean | 17 ++- .../Geometry/RingedSpace/PresheafedSpace.lean | 2 + .../RingedSpace/PresheafedSpace/Gluing.lean | 2 + .../PresheafedSpace/HasColimits.lean | 3 + .../Geometry/RingedSpace/SheafedSpace.lean | 2 + Mathlib/Geometry/RingedSpace/Stalks.lean | 2 + Mathlib/GroupTheory/ArchimedeanDensely.lean | 7 + Mathlib/GroupTheory/ClassEquation.lean | 1 + Mathlib/GroupTheory/Complement.lean | 6 + Mathlib/GroupTheory/Congruence/Basic.lean | 1 + Mathlib/GroupTheory/Congruence/Hom.lean | 1 + Mathlib/GroupTheory/CoprodI.lean | 3 + Mathlib/GroupTheory/Coset/Defs.lean | 4 +- Mathlib/GroupTheory/Coxeter/Basic.lean | 4 + Mathlib/GroupTheory/Coxeter/Inversion.lean | 2 +- Mathlib/GroupTheory/Coxeter/Matrix.lean | 7 + Mathlib/GroupTheory/Divisible.lean | 10 +- Mathlib/GroupTheory/DivisibleHull.lean | 5 + Mathlib/GroupTheory/DoubleCoset.lean | 3 +- Mathlib/GroupTheory/Exponent.lean | 3 + Mathlib/GroupTheory/FixedPointFree.lean | 2 +- Mathlib/GroupTheory/FreeAbelianGroup.lean | 3 + Mathlib/GroupTheory/FreeGroup/Basic.lean | 3 + .../GroupTheory/FreeGroup/IsFreeGroup.lean | 3 + .../FreeGroup/NielsenSchreier.lean | 6 + .../GroupTheory/GroupAction/CardCommute.lean | 1 + Mathlib/GroupTheory/GroupAction/ConjAct.lean | 1 + Mathlib/GroupTheory/GroupAction/Hom.lean | 12 +- Mathlib/GroupTheory/GroupAction/Jordan.lean | 2 +- .../GroupAction/SubMulAction/Combination.lean | 1 + .../SubMulAction/OfFixingSubgroup.lean | 2 + Mathlib/GroupTheory/GroupExtension/Basic.lean | 1 + Mathlib/GroupTheory/HNNExtension.lean | 11 +- Mathlib/GroupTheory/Index.lean | 7 +- .../MonoidLocalization/GrothendieckGroup.lean | 1 + .../GroupTheory/MonoidLocalization/Maps.lean | 3 + Mathlib/GroupTheory/Nilpotent.lean | 2 +- Mathlib/GroupTheory/NoncommCoprod.lean | 2 + Mathlib/GroupTheory/NoncommPiCoprod.lean | 4 + Mathlib/GroupTheory/OrderOfElement.lean | 6 +- .../GroupTheory/OreLocalization/Basic.lean | 2 +- Mathlib/GroupTheory/PGroup.lean | 3 +- Mathlib/GroupTheory/Perm/Centralizer.lean | 6 +- Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 5 +- Mathlib/GroupTheory/Perm/Cycle/Concrete.lean | 7 + Mathlib/GroupTheory/Perm/Cycle/Factors.lean | 3 + Mathlib/GroupTheory/Perm/Cycle/Type.lean | 3 + Mathlib/GroupTheory/Perm/Fin.lean | 2 + Mathlib/GroupTheory/Perm/Finite.lean | 2 + Mathlib/GroupTheory/Perm/Sign.lean | 5 +- Mathlib/GroupTheory/Perm/Support.lean | 1 + Mathlib/GroupTheory/PushoutI.lean | 3 + Mathlib/GroupTheory/QuotientGroup/Basic.lean | 2 + Mathlib/GroupTheory/QuotientGroup/Finite.lean | 8 +- .../Alternating/MaximalSubgroups.lean | 2 + .../SpecificGroups/Alternating/Simple.lean | 1 + .../GroupTheory/SpecificGroups/Cyclic.lean | 6 +- .../SpecificGroups/Cyclic/Basic.lean | 2 +- .../GroupTheory/SpecificGroups/Dihedral.lean | 1 + Mathlib/GroupTheory/Subgroup/Center.lean | 3 +- Mathlib/GroupTheory/Submonoid/Inverses.lean | 1 + Mathlib/GroupTheory/Sylow.lean | 3 +- Mathlib/GroupTheory/Torsion.lean | 3 +- Mathlib/Lean/PrettyPrinter/Delaborator.lean | 2 +- .../AffineSpace/AffineEquiv.lean | 7 + .../LinearAlgebra/AffineSpace/AffineMap.lean | 29 ++++ .../AffineSpace/AffineSubspace/Basic.lean | 5 + .../AffineSpace/AffineSubspace/Shift.lean | 2 + Mathlib/LinearAlgebra/AffineSpace/Ceva.lean | 3 + .../AffineSpace/Combination.lean | 5 + .../AffineSpace/Independent.lean | 5 + .../LinearAlgebra/AffineSpace/Midpoint.lean | 1 + .../AffineSpace/MidpointZero.lean | 2 + .../LinearAlgebra/AffineSpace/Ordered.lean | 38 +++++ .../AffineSpace/Simplex/Basic.lean | 1 + Mathlib/LinearAlgebra/AffineSpace/Slope.lean | 2 + .../LinearAlgebra/Alternating/DomCoprod.lean | 1 + Mathlib/LinearAlgebra/Basis/Basic.lean | 4 + Mathlib/LinearAlgebra/Basis/Bilinear.lean | 1 + Mathlib/LinearAlgebra/Basis/Cardinality.lean | 1 + Mathlib/LinearAlgebra/Basis/Defs.lean | 5 +- Mathlib/LinearAlgebra/Basis/Exact.lean | 1 + Mathlib/LinearAlgebra/Basis/Fin.lean | 2 + Mathlib/LinearAlgebra/Basis/SMul.lean | 1 + Mathlib/LinearAlgebra/Basis/Submodule.lean | 1 + Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 3 +- .../BilinearForm/Properties.lean | 1 + Mathlib/LinearAlgebra/BilinearMap.lean | 2 + .../LinearAlgebra/CliffordAlgebra/Basic.lean | 1 + .../LinearAlgebra/CliffordAlgebra/Equivs.lean | 3 + .../CliffordAlgebra/EvenEquiv.lean | 2 + .../CliffordAlgebra/Inversion.lean | 4 +- Mathlib/LinearAlgebra/Complex/Module.lean | 4 +- Mathlib/LinearAlgebra/Contraction.lean | 2 + Mathlib/LinearAlgebra/CrossProduct.lean | 1 + Mathlib/LinearAlgebra/DFinsupp.lean | 4 + Mathlib/LinearAlgebra/Determinant.lean | 4 + Mathlib/LinearAlgebra/Dimension/Basic.lean | 1 + .../Dimension/Constructions.lean | 2 + Mathlib/LinearAlgebra/Dimension/Finite.lean | 4 +- Mathlib/LinearAlgebra/Dimension/Free.lean | 1 + .../LinearAlgebra/Dimension/RankNullity.lean | 1 + .../Dimension/StrongRankCondition.lean | 2 +- .../Dimension/Torsion/Basic.lean | 1 + Mathlib/LinearAlgebra/DirectSum/Finsupp.lean | 2 + .../DirectSum/TensorProduct.lean | 4 + Mathlib/LinearAlgebra/Dual/BaseChange.lean | 3 + Mathlib/LinearAlgebra/Dual/Basis.lean | 2 + Mathlib/LinearAlgebra/Dual/Lemmas.lean | 2 +- Mathlib/LinearAlgebra/Eigenspace/Basic.lean | 7 + Mathlib/LinearAlgebra/Eigenspace/Matrix.lean | 1 + Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean | 2 + .../LinearAlgebra/Eigenspace/Semisimple.lean | 1 + .../Eigenspace/Triangularizable.lean | 1 + .../LinearAlgebra/ExteriorAlgebra/Basic.lean | 3 + .../LinearAlgebra/ExteriorPower/Basic.lean | 1 + .../FiniteDimensional/Basic.lean | 6 +- .../LinearAlgebra/FiniteDimensional/Defs.lean | 2 +- Mathlib/LinearAlgebra/FiniteSpan.lean | 1 + Mathlib/LinearAlgebra/Finsupp/LSum.lean | 1 + .../Finsupp/LinearCombination.lean | 1 + Mathlib/LinearAlgebra/Finsupp/Pi.lean | 1 + Mathlib/LinearAlgebra/Finsupp/Supported.lean | 3 + .../LinearAlgebra/Finsupp/VectorSpace.lean | 1 + Mathlib/LinearAlgebra/FixedSubmodule.lean | 1 + Mathlib/LinearAlgebra/FreeModule/Basic.lean | 1 + .../FreeModule/Finite/CardQuotient.lean | 1 + Mathlib/LinearAlgebra/FreeModule/Int.lean | 1 + Mathlib/LinearAlgebra/FreeModule/PID.lean | 5 + Mathlib/LinearAlgebra/FreeProduct/Basic.lean | 3 + .../GeneralLinearGroup/AlgEquiv.lean | 1 + Mathlib/LinearAlgebra/Isomorphisms.lean | 2 + .../LinearIndependent/Basic.lean | 1 + .../LinearAlgebra/LinearIndependent/Defs.lean | 2 + .../LinearIndependent/Lemmas.lean | 1 + Mathlib/LinearAlgebra/LinearPMap.lean | 3 + Mathlib/LinearAlgebra/Matrix/Basis.lean | 3 +- Mathlib/LinearAlgebra/Matrix/Block.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Cartan.lean | 4 + .../LinearAlgebra/Matrix/Charpoly/Coeff.lean | 1 + .../Matrix/Determinant/Basic.lean | 2 + .../Matrix/Determinant/Misc.lean | 3 + .../Matrix/Determinant/TotallyUnimodular.lean | 2 + Mathlib/LinearAlgebra/Matrix/Dual.lean | 1 + Mathlib/LinearAlgebra/Matrix/DualNumber.lean | 1 + .../Matrix/FixedDetMatrices.lean | 3 + .../Matrix/GeneralLinearGroup/Projective.lean | 3 +- Mathlib/LinearAlgebra/Matrix/Hadamard.lean | 1 + .../Matrix/InvariantBasisNumber.lean | 2 + .../Matrix/Irreducible/Defs.lean | 3 +- .../Matrix/NonsingularInverse.lean | 18 +-- Mathlib/LinearAlgebra/Matrix/Notation.lean | 4 + Mathlib/LinearAlgebra/Matrix/PosDef.lean | 1 - Mathlib/LinearAlgebra/Matrix/Rank.lean | 4 + .../LinearAlgebra/Matrix/SchurComplement.lean | 12 +- .../LinearAlgebra/Matrix/SemiringInverse.lean | 5 +- .../Matrix/SesquilinearForm.lean | 2 + .../Matrix/SpecialLinearGroup.lean | 7 + Mathlib/LinearAlgebra/Matrix/ToLin.lean | 11 ++ .../LinearAlgebra/Matrix/Transvection.lean | 2 +- .../LinearAlgebra/Multilinear/DFinsupp.lean | 1 + Mathlib/LinearAlgebra/Orientation.lean | 1 + .../PerfectPairing/Restrict.lean | 2 + Mathlib/LinearAlgebra/Pi.lean | 1 + .../LinearAlgebra/PiTensorProduct/Basic.lean | 4 + .../PiTensorProduct/Generators.lean | 2 + Mathlib/LinearAlgebra/Prod.lean | 4 + .../Projectivization/Action.lean | 1 + .../LinearAlgebra/Projectivization/Basic.lean | 2 +- .../LinearAlgebra/QuadraticForm/Basic.lean | 5 +- .../LinearAlgebra/QuadraticForm/Basis.lean | 1 + Mathlib/LinearAlgebra/QuadraticForm/Dual.lean | 1 + .../QuadraticForm/Signature.lean | 1 + Mathlib/LinearAlgebra/Quotient/Basic.lean | 2 + Mathlib/LinearAlgebra/Ray.lean | 1 + Mathlib/LinearAlgebra/Reflection.lean | 6 + Mathlib/LinearAlgebra/RootSystem/Base.lean | 1 + .../LinearAlgebra/RootSystem/BaseChange.lean | 3 + .../LinearAlgebra/RootSystem/BaseExists.lean | 1 + .../RootSystem/CartanMatrix.lean | 3 + Mathlib/LinearAlgebra/RootSystem/Defs.lean | 7 +- .../LinearAlgebra/RootSystem/Finite/G2.lean | 4 +- .../RootSystem/GeckConstruction/Lemmas.lean | 1 + .../LinearAlgebra/RootSystem/IsValuedIn.lean | 1 + .../LinearAlgebra/RootSystem/OfBilinear.lean | 1 + .../RootSystem/RootPositive.lean | 2 + Mathlib/LinearAlgebra/Semisimple.lean | 2 + .../LinearAlgebra/SesquilinearForm/Basic.lean | 2 + .../LinearAlgebra/SesquilinearForm/Star.lean | 1 + Mathlib/LinearAlgebra/Span/Defs.lean | 1 + Mathlib/LinearAlgebra/SpecialLinearGroup.lean | 2 + Mathlib/LinearAlgebra/StdBasis.lean | 1 + .../LinearAlgebra/SymmetricAlgebra/Basic.lean | 1 + .../LinearAlgebra/TensorAlgebra/Basic.lean | 2 + Mathlib/LinearAlgebra/TensorPower/Basic.lean | 3 + .../LinearAlgebra/TensorProduct/Basic.lean | 1 + .../TensorProduct/Graded/External.lean | 2 + Mathlib/LinearAlgebra/TensorProduct/Pi.lean | 1 + Mathlib/LinearAlgebra/TensorProduct/Prod.lean | 1 + .../TensorProduct/RightExactness.lean | 2 + .../TensorProduct/Subalgebra.lean | 1 + .../LinearAlgebra/TensorProduct/Tower.lean | 1 + Mathlib/LinearAlgebra/UnitaryGroup.lean | 1 + Mathlib/Logic/Basic.lean | 8 +- Mathlib/Logic/Denumerable.lean | 8 +- Mathlib/Logic/Embedding/Set.lean | 1 + Mathlib/Logic/Encodable/Basic.lean | 14 +- Mathlib/Logic/Equiv/Basic.lean | 6 +- Mathlib/Logic/Equiv/Defs.lean | 2 +- Mathlib/Logic/Equiv/Embedding.lean | 1 + Mathlib/Logic/Equiv/Fin/Basic.lean | 2 + Mathlib/Logic/Equiv/Fintype.lean | 5 +- Mathlib/Logic/Equiv/List.lean | 4 +- Mathlib/Logic/Equiv/Option.lean | 3 + Mathlib/Logic/Equiv/PartialEquiv.lean | 4 +- Mathlib/Logic/Equiv/Set.lean | 7 +- Mathlib/Logic/Relation.lean | 2 +- Mathlib/Logic/Small/Defs.lean | 1 + Mathlib/Logic/Unique.lean | 8 +- .../Constructions/BorelSpace/Basic.lean | 2 +- .../Constructions/Cylinders.lean | 2 +- Mathlib/MeasureTheory/Constructions/Pi.lean | 5 +- .../Constructions/Polish/Basic.lean | 2 +- .../Constructions/UnitInterval.lean | 4 + .../MeasureTheory/Covering/LiminfLimsup.lean | 1 + Mathlib/MeasureTheory/Function/AEEqFun.lean | 5 +- .../Function/ConvergenceInDistribution.lean | 6 + .../Function/LocallyIntegrable.lean | 4 + .../MeasureTheory/Function/LpSpace/Basic.lean | 2 + .../MeasureTheory/Function/SimpleFunc.lean | 1 + .../Function/SimpleFuncDenseLp.lean | 1 + .../Function/StronglyMeasurable/Basic.lean | 1 + Mathlib/MeasureTheory/Group/AEStabilizer.lean | 3 + Mathlib/MeasureTheory/Group/Action.lean | 1 + Mathlib/MeasureTheory/Integral/Average.lean | 2 + .../MeasureTheory/Integral/Bochner/L1.lean | 2 +- .../Integral/CurveIntegral/Basic.lean | 4 + .../Integral/CurveIntegral/Poincare.lean | 1 + .../Integral/DominatedConvergence.lean | 1 + .../Integral/IntervalIntegral/Basic.lean | 1 + .../IntervalIntegral/DistLEIntegral.lean | 2 + .../Integral/IntervalIntegral/Periodic.lean | 2 + Mathlib/MeasureTheory/Integral/Layercake.lean | 1 + .../Integral/Lebesgue/Basic.lean | 1 + Mathlib/MeasureTheory/Integral/Pi.lean | 2 +- Mathlib/MeasureTheory/Integral/Prod.lean | 1 + .../Integral/RieszMarkovKakutani/Basic.lean | 4 +- .../Integral/RieszMarkovKakutani/Real.lean | 1 + Mathlib/MeasureTheory/Integral/SetToL1.lean | 2 +- .../MeasureTheory/Integral/TorusIntegral.lean | 1 + .../MeasureTheory/MeasurableSpace/Basic.lean | 4 +- .../MeasurableSpace/Constructions.lean | 3 +- .../MeasureTheory/MeasurableSpace/Defs.lean | 6 +- .../MeasurableSpace/Embedding.lean | 3 + .../MeasurableSpace/EventuallyMeasurable.lean | 2 +- .../MeasurableSpace/Invariants.lean | 2 +- .../Measure/CharacteristicFunction/Basic.lean | 2 + Mathlib/MeasureTheory/Measure/Comap.lean | 2 + Mathlib/MeasureTheory/Measure/Complex.lean | 2 + Mathlib/MeasureTheory/Measure/Content.lean | 3 +- .../Measure/ContinuousPreimage.lean | 1 + Mathlib/MeasureTheory/Measure/DiracProba.lean | 1 + .../MeasureTheory/Measure/FiniteMeasure.lean | 1 + Mathlib/MeasureTheory/Measure/Haar/Basic.lean | 4 + .../MeasureTheory/Measure/Haar/Extension.lean | 1 + .../MeasureTheory/Measure/Haar/OfBasis.lean | 1 + .../Measure/HasOuterApproxClosedProd.lean | 1 + Mathlib/MeasureTheory/Measure/Hausdorff.lean | 2 + .../Measure/LevyConvergence.lean | 1 + .../Measure/LevyProkhorovMetric.lean | 2 +- Mathlib/MeasureTheory/Measure/Map.lean | 1 + Mathlib/MeasureTheory/Measure/OpenPos.lean | 1 + .../Measure/ProbabilityMeasure.lean | 2 + Mathlib/MeasureTheory/Measure/Prokhorov.lean | 1 + .../Measure/ResolventTransform.lean | 1 + Mathlib/MeasureTheory/Measure/Restrict.lean | 1 + .../Measure/SeparableMeasure.lean | 2 + Mathlib/MeasureTheory/Measure/Sub.lean | 1 + Mathlib/MeasureTheory/OuterMeasure/AE.lean | 6 + .../OuterMeasure/Caratheodory.lean | 2 +- .../OuterMeasure/OfAddContent.lean | 1 + Mathlib/MeasureTheory/PiSystem.lean | 3 +- .../VectorMeasure/AddContent.lean | 1 + .../MeasureTheory/VectorMeasure/Basic.lean | 4 +- .../MeasureTheory/VectorMeasure/Integral.lean | 19 +++ .../Variation/Semivariation.lean | 2 + .../VectorMeasure/WithDensityVec.lean | 1 + Mathlib/ModelTheory/Algebra/Field/Basic.lean | 2 +- Mathlib/ModelTheory/Algebra/Field/CharP.lean | 2 +- .../Algebra/Field/IsAlgClosed.lean | 4 +- .../Algebra/Ring/FreeCommRing.lean | 1 + .../Arithmetic/Presburger/Definability.lean | 1 + .../Presburger/Semilinear/Basic.lean | 3 + .../Presburger/Semilinear/Defs.lean | 1 + Mathlib/ModelTheory/Basic.lean | 4 +- Mathlib/ModelTheory/Definability.lean | 2 +- Mathlib/ModelTheory/DirectLimit.lean | 5 + Mathlib/ModelTheory/Equivalence.lean | 2 +- Mathlib/ModelTheory/FinitelyGenerated.lean | 1 + Mathlib/ModelTheory/Fraisse.lean | 2 + Mathlib/ModelTheory/Graph.lean | 2 +- Mathlib/ModelTheory/LanguageMap.lean | 6 +- Mathlib/ModelTheory/Order.lean | 14 +- Mathlib/ModelTheory/PartialEquiv.lean | 5 +- Mathlib/ModelTheory/Semantics.lean | 3 + Mathlib/ModelTheory/Substructures.lean | 2 + Mathlib/ModelTheory/Syntax.lean | 1 + .../NumberTheory/ArithmeticFunction/Defs.lean | 4 + .../ArithmeticFunction/LFunction.lean | 3 + .../ArithmeticFunction/Moebius.lean | 1 + .../NumberTheory/ArithmeticFunction/Zeta.lean | 5 + Mathlib/NumberTheory/Chebyshev.lean | 2 + Mathlib/NumberTheory/ClassNumber/Finite.lean | 5 +- Mathlib/NumberTheory/Dioph.lean | 2 + Mathlib/NumberTheory/Divisors.lean | 2 + .../EulerProduct/DirichletLSeries.lean | 2 +- Mathlib/NumberTheory/EulerProduct/ExpLog.lean | 1 + Mathlib/NumberTheory/Height/NumberField.lean | 4 +- Mathlib/NumberTheory/KummerDedekind.lean | 1 + Mathlib/NumberTheory/LSeries/Convolution.lean | 3 + Mathlib/NumberTheory/LSeries/Dirichlet.lean | 2 + Mathlib/NumberTheory/LSeries/Injectivity.lean | 1 + .../NumberTheory/LSeries/Nonvanishing.lean | 1 + Mathlib/NumberTheory/LucasLehmer.lean | 6 +- Mathlib/NumberTheory/Modular.lean | 2 + Mathlib/NumberTheory/ModularForms/Bounds.lean | 2 +- .../ModularForms/CongruenceSubgroups.lean | 1 + Mathlib/NumberTheory/ModularForms/Cusps.lean | 4 + .../ModularForms/Discriminant.lean | 2 + .../EisensteinSeries/E2/Defs.lean | 1 + .../EisensteinSeries/E2/Transform.lean | 1 + .../NumberTheory/ModularForms/Identities.lean | 1 + .../ModularForms/SlashActions.lean | 2 +- Mathlib/NumberTheory/NumberField/Basic.lean | 1 + Mathlib/NumberTheory/NumberField/CMField.lean | 3 +- .../NumberField/CanonicalEmbedding/Basic.lean | 4 + .../CanonicalEmbedding/FundamentalCone.lean | 3 + .../NumberField/Completion/FinitePlace.lean | 1 + .../NumberField/Cyclotomic/Basic.lean | 12 ++ .../NumberField/Cyclotomic/Ideal.lean | 1 + .../NumberField/Cyclotomic/Three.lean | 5 +- Mathlib/NumberTheory/NumberField/House.lean | 1 + .../NumberField/Ideal/Asymptotics.lean | 3 +- .../NumberField/Ideal/KummerDedekind.lean | 1 + .../NumberField/InfinitePlace/Basic.lean | 5 + Mathlib/NumberTheory/NumberField/Norm.lean | 1 + .../NumberField/Units/DirichletTheorem.lean | 3 + .../Padics/HeightOneSpectrum.lean | 3 + Mathlib/NumberTheory/Padics/Hensel.lean | 3 + Mathlib/NumberTheory/Padics/MahlerBasis.lean | 1 + .../NumberTheory/Padics/PadicIntegers.lean | 5 + Mathlib/NumberTheory/Padics/RingHoms.lean | 5 + Mathlib/NumberTheory/Padics/WithVal.lean | 1 + .../RamificationInertia/Basic.lean | 1 + .../RamificationInertia/Ramification.lean | 2 + Mathlib/NumberTheory/SmoothNumbers.lean | 1 + .../TsumDivisorsAntidiagonal.lean | 1 + Mathlib/NumberTheory/WellApproximable.lean | 1 + Mathlib/Order/Antisymmetrization.lean | 3 +- Mathlib/Order/Atoms.lean | 16 +- Mathlib/Order/Birkhoff.lean | 4 + Mathlib/Order/BooleanAlgebra/Defs.lean | 2 +- Mathlib/Order/BooleanGenerators.lean | 4 +- Mathlib/Order/Bounds/Basic.lean | 4 +- Mathlib/Order/BourbakiWitt.lean | 9 ++ Mathlib/Order/Category/NonemptyFinLinOrd.lean | 1 + Mathlib/Order/Category/PartOrdEmb.lean | 1 - .../Order/CompactlyGenerated/Intervals.lean | 1 + Mathlib/Order/Comparable.lean | 4 +- Mathlib/Order/Compare.lean | 2 +- Mathlib/Order/CompleteBooleanAlgebra.lean | 8 +- Mathlib/Order/CompleteLattice/Defs.lean | 8 +- Mathlib/Order/CompleteLattice/PiLex.lean | 8 + Mathlib/Order/Completion.lean | 2 + .../ConditionallyCompleteLattice/Defs.lean | 4 +- Mathlib/Order/Copy.lean | 30 ++-- Mathlib/Order/CountableDenseLinearOrder.lean | 1 + Mathlib/Order/Defs/PartialOrder.lean | 2 +- Mathlib/Order/DirectedInverseSystem.lean | 6 +- Mathlib/Order/Disjointed.lean | 1 + Mathlib/Order/Extension/Well.lean | 2 +- Mathlib/Order/Filter/Basic.lean | 1 + Mathlib/Order/Filter/CountableInter.lean | 1 + Mathlib/Order/Filter/Finite.lean | 2 + Mathlib/Order/Filter/Germ/Basic.lean | 4 +- Mathlib/Order/Filter/Partial.lean | 2 + Mathlib/Order/Filter/Pointwise.lean | 32 ++-- Mathlib/Order/Filter/Prod.lean | 1 + Mathlib/Order/Filter/Ultrafilter/Basic.lean | 1 + Mathlib/Order/Fin/Tuple.lean | 1 + Mathlib/Order/GaloisConnection/Defs.lean | 2 +- Mathlib/Order/Height.lean | 1 + Mathlib/Order/Hom/Basic.lean | 3 + Mathlib/Order/Hom/CompleteLattice.lean | 1 + Mathlib/Order/Hom/Lex.lean | 2 + Mathlib/Order/Hom/PowersetCard.lean | 2 + Mathlib/Order/Hom/Set.lean | 4 + Mathlib/Order/Interval/Finset/Basic.lean | 2 +- Mathlib/Order/Interval/Finset/Defs.lean | 12 +- Mathlib/Order/Interval/Finset/Fin.lean | 32 ++++ Mathlib/Order/Interval/Finset/Gaps.lean | 2 +- Mathlib/Order/Interval/Finset/Nat.lean | 1 + Mathlib/Order/Interval/Set/InitialSeg.lean | 4 + Mathlib/Order/Interval/Set/IsoIoo.lean | 1 + Mathlib/Order/Interval/Set/ProjIcc.lean | 2 + Mathlib/Order/JordanHolder.lean | 4 + Mathlib/Order/KrullDimension.lean | 3 + Mathlib/Order/Lattice.lean | 6 +- Mathlib/Order/Lattice/Nat.lean | 1 + Mathlib/Order/LiminfLimsup.lean | 1 + Mathlib/Order/ModularLattice.lean | 4 + Mathlib/Order/Monotone/Basic.lean | 4 + Mathlib/Order/OmegaCompletePartialOrder.lean | 2 +- Mathlib/Order/OrderDual.lean | 3 +- Mathlib/Order/OrderIsoNat.lean | 1 + Mathlib/Order/PartialSups.lean | 1 + Mathlib/Order/Partition/Finpartition.lean | 1 + Mathlib/Order/PiLex.lean | 16 +- Mathlib/Order/RelClasses.lean | 4 +- Mathlib/Order/RelSeries.lean | 23 ++- Mathlib/Order/SetDissipate.lean | 2 - Mathlib/Order/Sublocale.lean | 3 + Mathlib/Order/SuccPred/Basic.lean | 9 +- .../Order/SuccPred/CompleteLinearOrder.lean | 2 +- .../Order/SuccPred/LinearLocallyFinite.lean | 8 +- Mathlib/Order/SupClosed.lean | 3 +- Mathlib/Order/Types/Defs.lean | 2 +- Mathlib/Order/UpperLower/Closure.lean | 2 +- Mathlib/Order/UpperLower/CompleteLattice.lean | 1 + Mathlib/Order/WellFounded.lean | 2 +- .../Probability/Distributions/Binomial.lean | 1 + .../Probability/Distributions/Fernique.lean | 1 + .../Distributions/Gaussian/CharFun.lean | 2 + .../Distributions/Gaussian/Real.lean | 1 + .../Probability/Distributions/Uniform.lean | 1 + .../Kernel/Composition/CompProd.lean | 1 + .../Disintegration/MeasurableStieltjes.lean | 2 + .../Kernel/IonescuTulcea/Maps.lean | 3 + .../Kernel/IonescuTulcea/PartialTraj.lean | 3 +- .../Kernel/IonescuTulcea/Traj.lean | 1 + .../Kernel/MeasurableIntegral.lean | 2 + .../Martingale/OptionalStopping.lean | 1 + Mathlib/Probability/Moments/ComplexMGF.lean | 1 + .../Probability/Moments/CovarianceBilin.lean | 6 + .../ProbabilityMassFunction/Monad.lean | 1 + Mathlib/Probability/Process/Filtration.lean | 2 + Mathlib/Probability/Process/Predictable.lean | 2 +- Mathlib/Probability/Process/Stopping.lean | 8 +- Mathlib/Probability/ProductMeasure.lean | 2 + Mathlib/RepresentationTheory/Action.lean | 2 +- Mathlib/RepresentationTheory/Basic.lean | 4 + Mathlib/RepresentationTheory/Coinduced.lean | 6 + .../RepresentationTheory/Coinvariants.lean | 3 +- .../Continuous/TopRep.lean | 1 + Mathlib/RepresentationTheory/Equiv.lean | 1 + Mathlib/RepresentationTheory/FDRep.lean | 4 +- Mathlib/RepresentationTheory/FiniteIndex.lean | 5 + .../ContCohomology/Functoriality.lean | 2 + .../GroupCohomology/LongExactSequence.lean | 1 + .../GroupCohomology/LowDegree.lean | 7 + .../GroupHomology/Functoriality.lean | 3 + .../GroupHomology/LongExactSequence.lean | 2 + .../Homological/GroupHomology/LowDegree.lean | 10 +- .../Homological/Resolution.lean | 2 +- Mathlib/RepresentationTheory/Induced.lean | 2 +- .../RepresentationTheory/Intertwining.lean | 1 + Mathlib/RepresentationTheory/Invariants.lean | 2 + Mathlib/RepresentationTheory/Maschke.lean | 1 + Mathlib/RepresentationTheory/Rep/Basic.lean | 2 + Mathlib/RepresentationTheory/Rep/Res.lean | 1 + Mathlib/RepresentationTheory/Submodule.lean | 1 + Mathlib/RepresentationTheory/Tannaka.lean | 3 + .../RingTheory/AdicCompletion/Algebra.lean | 15 +- Mathlib/RingTheory/AdicCompletion/Basic.lean | 4 + .../AdicCompletion/Completeness.lean | 3 + .../AdicCompletion/Functoriality.lean | 4 + Mathlib/RingTheory/Adjoin/FG.lean | 1 + Mathlib/RingTheory/Adjoin/PowerBasis.lean | 3 + Mathlib/RingTheory/AdjoinRoot.lean | 14 ++ Mathlib/RingTheory/AlgebraTower.lean | 4 +- Mathlib/RingTheory/Algebraic/Integral.lean | 1 + .../RingTheory/Algebraic/MvPolynomial.lean | 1 + .../AlgebraicIndependent/Adjoin.lean | 1 + .../AlgebraicIndependent/Transcendental.lean | 1 + Mathlib/RingTheory/Artinian/Module.lean | 6 + Mathlib/RingTheory/Bezout.lean | 1 + Mathlib/RingTheory/Bialgebra/Basic.lean | 2 +- Mathlib/RingTheory/Bialgebra/Equiv.lean | 1 + Mathlib/RingTheory/Bialgebra/Hom.lean | 1 + .../RingTheory/Bialgebra/MonoidAlgebra.lean | 4 + Mathlib/RingTheory/ChainOfDivisors.lean | 2 + Mathlib/RingTheory/ClassGroup/Basic.lean | 3 + Mathlib/RingTheory/Coalgebra/Equiv.lean | 3 + Mathlib/RingTheory/Congruence/Hom.lean | 3 + .../DedekindDomain/AdicValuation.lean | 5 +- .../RingTheory/DedekindDomain/Different.lean | 7 +- .../DedekindDomain/Factorization.lean | 2 + .../DedekindDomain/Ideal/Lemmas.lean | 5 + .../DedekindDomain/IntegralClosure.lean | 1 + .../DedekindDomain/SelmerGroup.lean | 1 + Mathlib/RingTheory/Derivation/Basic.lean | 2 + Mathlib/RingTheory/Derivation/Lie.lean | 1 + Mathlib/RingTheory/Derivation/MapCoeffs.lean | 4 + .../DiscreteValuationRing/Basic.lean | 4 +- Mathlib/RingTheory/DividedPowers/Padic.lean | 3 + .../RingTheory/DividedPowers/SubDPIdeal.lean | 1 + Mathlib/RingTheory/Etale/Basic.lean | 1 - Mathlib/RingTheory/Etale/Kaehler.lean | 1 + Mathlib/RingTheory/Etale/QuasiFinite.lean | 3 +- Mathlib/RingTheory/Etale/StandardEtale.lean | 10 ++ Mathlib/RingTheory/Etale/Weakly.lean | 1 + Mathlib/RingTheory/EuclideanDomain.lean | 2 +- Mathlib/RingTheory/Extension/Basic.lean | 3 + .../Extension/Cotangent/BaseChange.lean | 5 + .../RingTheory/Extension/Cotangent/Basic.lean | 3 + .../RingTheory/Extension/Cotangent/Basis.lean | 4 + .../RingTheory/Extension/Cotangent/Free.lean | 1 + .../Extension/Cotangent/LocalizationAway.lean | 1 + .../RingTheory/Extension/ExtendScalars.lean | 2 + Mathlib/RingTheory/Extension/Generators.lean | 4 + .../Extension/Presentation/Basic.lean | 1 + .../Extension/Presentation/Core.lean | 2 + .../Extension/Presentation/Submersive.lean | 2 +- Mathlib/RingTheory/Filtration.lean | 1 + Mathlib/RingTheory/Finiteness/Basic.lean | 1 + .../Finiteness/FinitePresentationLocal.lean | 1 + Mathlib/RingTheory/Flat/Equalizer.lean | 2 + Mathlib/RingTheory/Flat/Localization.lean | 1 + Mathlib/RingTheory/FormalGroup/Basic.lean | 2 + Mathlib/RingTheory/FractionalIdeal/Basic.lean | 2 + .../FractionalIdeal/Operations.lean | 13 ++ Mathlib/RingTheory/FreeCommRing.lean | 1 + Mathlib/RingTheory/Frobenius.lean | 2 + Mathlib/RingTheory/GradedAlgebra/Basic.lean | 3 +- .../GradedAlgebra/Homogeneous/Ideal.lean | 1 + .../HomogeneousLocalization.lean | 9 +- .../GradedAlgebra/TensorProduct.lean | 1 + Mathlib/RingTheory/HahnSeries/Addition.lean | 2 + Mathlib/RingTheory/HahnSeries/Basic.lean | 1 + Mathlib/RingTheory/HahnSeries/HEval.lean | 1 + Mathlib/RingTheory/HahnSeries/Lex.lean | 1 + .../RingTheory/HahnSeries/Multiplication.lean | 5 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 3 + Mathlib/RingTheory/HopfAlgebra/Basic.lean | 1 + .../Ideal/AssociatedPrime/Basic.lean | 1 + .../Ideal/AssociatedPrime/Localization.lean | 1 + Mathlib/RingTheory/Ideal/Basis.lean | 1 + Mathlib/RingTheory/Ideal/Cotangent.lean | 4 + .../RingTheory/Ideal/CotangentBaseChange.lean | 2 + Mathlib/RingTheory/Ideal/GoingDown.lean | 1 + Mathlib/RingTheory/Ideal/Height.lean | 1 + .../RingTheory/Ideal/KrullsHeightTheorem.lean | 1 + Mathlib/RingTheory/Ideal/Maps.lean | 6 + Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 1 + Mathlib/RingTheory/Ideal/Operations.lean | 1 + Mathlib/RingTheory/Ideal/Prod.lean | 1 + Mathlib/RingTheory/Ideal/Quotient/Basic.lean | 1 + .../Ideal/Quotient/ChineseRemainder.lean | 1 + .../RingTheory/Ideal/Quotient/Operations.lean | 10 +- .../Ideal/Quotient/PowTransition.lean | 1 + Mathlib/RingTheory/IdealFilter/Topology.lean | 4 +- .../IntegralClosure/IntegralRestrict.lean | 5 + .../IntegralClosure/IntegrallyClosed.lean | 1 + .../IsIntegralClosure/Basic.lean | 1 + Mathlib/RingTheory/IntegralDomain.lean | 6 +- Mathlib/RingTheory/Invariant/Basic.lean | 3 + Mathlib/RingTheory/Invariant/Profinite.lean | 1 + Mathlib/RingTheory/IsAdjoinRoot.lean | 7 + Mathlib/RingTheory/IsPrimary.lean | 1 + Mathlib/RingTheory/IsTensorProduct.lean | 8 + Mathlib/RingTheory/Kaehler/Basic.lean | 1 + Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 6 + .../KrullDimension/NonZeroDivisors.lean | 1 + .../RingTheory/KrullDimension/Regular.lean | 2 + Mathlib/RingTheory/Lasker.lean | 2 +- Mathlib/RingTheory/LaurentSeries.lean | 4 + Mathlib/RingTheory/LittleWedderburn.lean | 3 +- Mathlib/RingTheory/LocalProperties/Basic.lean | 1 + .../LocalProperties/Projective.lean | 1 + .../RingTheory/LocalRing/LocalSubring.lean | 2 + Mathlib/RingTheory/LocalRing/Module.lean | 2 + Mathlib/RingTheory/LocalRing/Pullback.lean | 1 + .../LocalRing/ResidueField/Ideal.lean | 3 + .../LocalRing/ResidueField/Instances.lean | 3 + .../LocalRing/ResidueField/Polynomial.lean | 3 + .../Localization/AtPrime/Basic.lean | 10 +- .../Localization/AtPrime/Extension.lean | 1 + .../RingTheory/Localization/Away/Basic.lean | 3 + .../RingTheory/Localization/BaseChange.lean | 1 + Mathlib/RingTheory/Localization/Basic.lean | 9 +- Mathlib/RingTheory/Localization/Defs.lean | 6 +- .../RingTheory/Localization/Finiteness.lean | 2 + .../RingTheory/Localization/FractionRing.lean | 8 +- Mathlib/RingTheory/Localization/Ideal.lean | 2 + Mathlib/RingTheory/Localization/Integral.lean | 2 + .../LocalizationLocalization.lean | 1 + Mathlib/RingTheory/Localization/Module.lean | 3 + Mathlib/RingTheory/Multiplicity.lean | 1 + Mathlib/RingTheory/MvPolynomial/Expand.lean | 1 + Mathlib/RingTheory/MvPolynomial/Ideal.lean | 2 + .../MvPolynomial/Symmetric/Defs.lean | 1 + .../Symmetric/FundamentalTheorem.lean | 1 + .../Symmetric/NewtonIdentities.lean | 2 + .../MvPolynomial/WeightedHomogeneous.lean | 10 +- Mathlib/RingTheory/MvPowerSeries/Basic.lean | 3 + Mathlib/RingTheory/MvPowerSeries/Equiv.lean | 1 + .../RingTheory/MvPowerSeries/Evaluation.lean | 1 + Mathlib/RingTheory/MvPowerSeries/Expand.lean | 2 + .../RingTheory/MvPowerSeries/LexOrder.lean | 6 +- .../MvPowerSeries/LinearTopology.lean | 2 + Mathlib/RingTheory/MvPowerSeries/Order.lean | 1 + .../RingTheory/MvPowerSeries/PiTopology.lean | 2 +- Mathlib/RingTheory/MvPowerSeries/Rename.lean | 1 + .../MvPowerSeries/Substitution.lean | 6 + Mathlib/RingTheory/MvPowerSeries/Trunc.lean | 1 + Mathlib/RingTheory/Nilpotent/Lemmas.lean | 2 + .../RingTheory/OrderOfVanishing/Basic.lean | 1 + .../RingTheory/OreLocalization/OreSet.lean | 4 +- Mathlib/RingTheory/Perfection.lean | 3 + Mathlib/RingTheory/PiTensorProduct.lean | 1 + Mathlib/RingTheory/PicardGroup.lean | 9 ++ Mathlib/RingTheory/Polynomial/GaussNorm.lean | 1 + Mathlib/RingTheory/Polynomial/Quotient.lean | 1 + .../Polynomial/Resultant/Basic.lean | 3 + .../Polynomial/UniqueFactorization.lean | 2 +- .../UniversalFactorizationRing.lean | 11 ++ Mathlib/RingTheory/PolynomialLaw/Basic.lean | 1 + Mathlib/RingTheory/PowerBasis.lean | 5 +- .../RingTheory/PowerSeries/Evaluation.lean | 1 + Mathlib/RingTheory/PrincipalIdealDomain.lean | 2 +- Mathlib/RingTheory/QuasiFinite/Basic.lean | 2 + .../RingTheory/QuasiFinite/Polynomial.lean | 1 + Mathlib/RingTheory/QuasiFinite/Weakly.lean | 1 + .../RamificationInertia/Ramification.lean | 1 + Mathlib/RingTheory/Regular/IsSMulRegular.lean | 1 + .../RingTheory/Regular/RegularSequence.lean | 2 + Mathlib/RingTheory/RingHom/Locally.lean | 1 + Mathlib/RingTheory/RingHomProperties.lean | 1 + Mathlib/RingTheory/SimpleModule/Basic.lean | 1 + Mathlib/RingTheory/SimpleModule/Isotypic.lean | 2 + .../SimpleModule/WedderburnArtin.lean | 1 + Mathlib/RingTheory/SimpleRing/Field.lean | 1 + Mathlib/RingTheory/Smooth/AdicCompletion.lean | 1 + Mathlib/RingTheory/Smooth/Basic.lean | 4 +- .../RingTheory/Smooth/IntegralClosure.lean | 1 + Mathlib/RingTheory/Smooth/Kaehler.lean | 1 + Mathlib/RingTheory/Smooth/Pi.lean | 1 + Mathlib/RingTheory/Smooth/Quotient.lean | 1 + .../Smooth/StandardSmoothCotangent.lean | 1 + .../Smooth/StandardSmoothOfFree.lean | 2 + .../Spectrum/Maximal/Localization.lean | 2 + Mathlib/RingTheory/Spectrum/Prime/Basic.lean | 1 + .../Spectrum/Prime/ChevalleyComplexity.lean | 1 + .../RingTheory/Spectrum/Prime/LTSeries.lean | 2 + .../RingTheory/Spectrum/Prime/RingHom.lean | 1 + .../RingTheory/Spectrum/Prime/Topology.lean | 2 + Mathlib/RingTheory/Support.lean | 1 + Mathlib/RingTheory/TensorProduct/Basic.lean | 1 + .../TensorProduct/DirectLimitFG.lean | 3 + Mathlib/RingTheory/TensorProduct/Free.lean | 1 + .../TensorProduct/IsBaseChangeFree.lean | 1 + Mathlib/RingTheory/TensorProduct/Maps.lean | 1 + .../RingTheory/TensorProduct/Quotient.lean | 2 + Mathlib/RingTheory/TotallySplit.lean | 1 + Mathlib/RingTheory/TwoSidedIdeal/Basic.lean | 2 +- Mathlib/RingTheory/TwoSidedIdeal/Lattice.lean | 1 + .../RingTheory/TwoSidedIdeal/Operations.lean | 6 + .../UniqueFactorizationDomain/Finite.lean | 2 +- .../UniqueFactorizationDomain/GCDMonoid.lean | 2 +- .../NormalizedFactors.lean | 2 +- Mathlib/RingTheory/Unramified/Basic.lean | 1 - .../RingTheory/Unramified/LocalStructure.lean | 2 + Mathlib/RingTheory/Valuation/Basic.lean | 15 +- .../RingTheory/Valuation/Discrete/Basic.lean | 2 + .../Discrete/IsDiscreteValuationRing.lean | 1 + .../Valuation/Discrete/RankOne.lean | 3 +- .../Valuation/ExtendToLocalization.lean | 1 + Mathlib/RingTheory/Valuation/Integers.lean | 1 + .../RingTheory/Valuation/LocalSubring.lean | 3 + Mathlib/RingTheory/Valuation/RankOne.lean | 7 +- .../RingTheory/Valuation/ValuationRing.lean | 1 + .../Valuation/ValuationSubring.lean | 1 + .../Valuation/ValuativeRel/Basic.lean | 5 +- .../Valuation/ValuativeRel/Trivial.lean | 2 +- .../WittVector/FrobeniusFractionField.lean | 1 + Mathlib/RingTheory/WittVector/InitTail.lean | 2 +- Mathlib/RingTheory/WittVector/Isocrystal.lean | 3 + Mathlib/RingTheory/ZariskisMainTheorem.lean | 1 + Mathlib/SetTheory/Cardinal/Arithmetic.lean | 2 + Mathlib/SetTheory/Cardinal/Basic.lean | 1 + .../Cardinal/Cofinality/Ordinal.lean | 1 + Mathlib/SetTheory/Cardinal/HasCardinalLT.lean | 1 + Mathlib/SetTheory/Cardinal/Order.lean | 1 + Mathlib/SetTheory/Descriptive/Tree.lean | 3 + Mathlib/SetTheory/Lists.lean | 9 +- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 5 + Mathlib/SetTheory/Ordinal/Basic.lean | 6 +- .../SetTheory/Ordinal/CantorNormalForm.lean | 1 + Mathlib/SetTheory/Ordinal/Family.lean | 1 + .../Ordinal/FundamentalSequence.lean | 1 + Mathlib/SetTheory/ZFC/Basic.lean | 3 +- Mathlib/SetTheory/ZFC/Class.lean | 1 + Mathlib/SetTheory/ZFC/Ordinal.lean | 1 + .../ComputeAsymptotics/Multiseries/Basic.lean | 1 + .../Multiseries/Corecursion.lean | 5 +- .../ComputeAsymptotics/Multiseries/Defs.lean | 14 ++ Mathlib/Tactic/Core.lean | 4 +- Mathlib/Tactic/FieldSimp.lean | 1 + Mathlib/Tactic/FieldSimp/Lemmas.lean | 3 + Mathlib/Tactic/HigherOrder.lean | 4 +- Mathlib/Tactic/Inhabit.lean | 4 +- Mathlib/Tactic/Module.lean | 7 + Mathlib/Tactic/NormNum/Basic.lean | 4 +- Mathlib/Tactic/NormNum/GCD.lean | 4 +- Mathlib/Tactic/NormNum/Irrational.lean | 4 +- Mathlib/Tactic/NormNum/IsCoprime.lean | 4 +- Mathlib/Tactic/NormNum/IsSquare.lean | 4 +- Mathlib/Tactic/NormNum/NatSqrt.lean | 4 +- Mathlib/Tactic/NormNum/RealSqrt.lean | 4 +- Mathlib/Tactic/NormNum/Result.lean | 4 +- Mathlib/Tactic/PNatToNat.lean | 1 + Mathlib/Tactic/Ring/RingNF.lean | 2 +- Mathlib/Tactic/Simproc/Divisors.lean | 4 +- Mathlib/Tactic/Simps/Basic.lean | 1 + Mathlib/Tactic/Translate/Core.lean | 8 +- Mathlib/Testing/Plausible/Functions.lean | 7 +- Mathlib/Topology/Algebra/Affine.lean | 6 + Mathlib/Topology/Algebra/AffineSubspace.lean | 1 + .../Category/ProfiniteGrp/Completion.lean | 1 + .../Algebra/Category/ProfiniteGrp/Limits.lean | 3 + .../Topology/Algebra/ContinuousAffineMap.lean | 6 + Mathlib/Topology/Algebra/Field.lean | 4 + Mathlib/Topology/Algebra/FilterBasis.lean | 10 +- .../Topology/Algebra/InfiniteSum/Basic.lean | 1 + .../Topology/Algebra/InfiniteSum/Defs.lean | 1 + .../Topology/Algebra/InfiniteSum/Group.lean | 1 + .../Algebra/InfiniteSum/Nonarchimedean.lean | 1 + .../Topology/Algebra/IsUniformGroup/Defs.lean | 4 +- .../Topology/Algebra/LinearMapCompletion.lean | 1 + Mathlib/Topology/Algebra/LinearTopology.lean | 1 + .../Topology/Algebra/Module/Complement.lean | 1 + Mathlib/Topology/Algebra/Module/Equiv.lean | 1 + .../Module/FiniteDimensionBilinear.lean | 1 + .../Topology/Algebra/Module/LinearPMap.lean | 1 + .../Algebra/Module/Spaces/CharacterSpace.lean | 1 + .../Spaces/PointwiseConvergenceCLM.lean | 3 + .../Module/Spaces/UniformConvergenceCLM.lean | 6 +- Mathlib/Topology/Algebra/Module/Star.lean | 7 + .../Algebra/Module/UniformConvergence.lean | 1 + Mathlib/Topology/Algebra/MulAction.lean | 1 + .../Algebra/Nonarchimedean/AdicTopology.lean | 8 +- .../Algebra/Nonarchimedean/Bases.lean | 8 +- .../Algebra/RestrictedProduct/Units.lean | 1 + Mathlib/Topology/Algebra/Ring/Compact.lean | 1 + Mathlib/Topology/Algebra/StarSubalgebra.lean | 1 + .../Algebra/TopologicallyNilpotent.lean | 1 + .../Topology/Algebra/UniformFilterBasis.lean | 2 +- Mathlib/Topology/Algebra/UniformRing.lean | 4 + .../ValuativeRel/ValuativeTopology.lean | 3 + .../Algebra/Valued/LocallyCompact.lean | 1 + .../Topology/Algebra/Valued/NormedValued.lean | 2 + .../Algebra/Valued/ValuationTopology.lean | 5 +- .../Topology/Algebra/Valued/ValuedField.lean | 4 + Mathlib/Topology/Algebra/Valued/WithVal.lean | 5 + Mathlib/Topology/Basic.lean | 2 +- Mathlib/Topology/Bornology/Basic.lean | 4 +- .../Topology/CWComplex/Classical/Basic.lean | 3 +- .../Topology/CWComplex/Classical/Finite.lean | 8 +- .../Topology/Category/CompHausLike/Basic.lean | 2 +- .../Category/CompHausLike/Cartesian.lean | 3 +- Mathlib/Topology/Category/Compactum.lean | 11 ++ .../Topology/Category/Profinite/AsLimit.lean | 1 + .../Category/Profinite/Nobeling/Basic.lean | 6 +- .../Category/Profinite/Nobeling/Span.lean | 3 +- .../Profinite/Nobeling/Successor.lean | 6 + .../Profinite/Nobeling/ZeroLimit.lean | 4 + .../Topology/Category/Profinite/Product.lean | 4 +- .../Category/TopCat/Limits/Basic.lean | 9 ++ .../Category/TopCat/Limits/Products.lean | 2 + .../Topology/Category/TopCat/OpenNhds.lean | 4 + Mathlib/Topology/Category/TopCat/Opens.lean | 1 + Mathlib/Topology/Category/TopCat/ULift.lean | 2 + Mathlib/Topology/Category/TopPair.lean | 6 + Mathlib/Topology/Category/UniformSpace.lean | 5 + Mathlib/Topology/CompactOpen.lean | 1 + .../OnePoint/ProjectiveLine.lean | 3 + .../Topology/Compactification/StoneCech.lean | 2 + Mathlib/Topology/Compactness/Compact.lean | 2 +- .../Compactness/CompactlyCoherentSpace.lean | 1 - .../Compactness/CompactlyGeneratedSpace.lean | 2 +- Mathlib/Topology/Compactness/Lindelof.lean | 1 + .../Topology/Compactness/LocallyFinite.lean | 2 +- .../Topology/Compactness/SigmaCompact.lean | 2 +- Mathlib/Topology/Connected/Clopen.lean | 2 +- Mathlib/Topology/Connected/PathConnected.lean | 2 +- Mathlib/Topology/Constructible.lean | 1 + Mathlib/Topology/Constructions.lean | 1 + Mathlib/Topology/Constructions/SumProd.lean | 3 + Mathlib/Topology/ContinuousMap/Basic.lean | 1 + Mathlib/Topology/ContinuousMap/Compact.lean | 3 + .../ContinuousMap/CompactlySupported.lean | 2 + .../ContinuousMap/ContinuousMapZero.lean | 2 + Mathlib/Topology/ContinuousMap/Sigma.lean | 3 + .../ContinuousMap/StoneWeierstrass.lean | 5 +- Mathlib/Topology/Convenient/GeneratedBy.lean | 2 +- Mathlib/Topology/Covering/Basic.lean | 2 + Mathlib/Topology/Covering/Quotient.lean | 1 + Mathlib/Topology/Defs/Filter.lean | 2 +- Mathlib/Topology/Defs/Induced.lean | 4 +- .../EMetricSpace/BoundedVariation.lean | 1 + Mathlib/Topology/EMetricSpace/Defs.lean | 2 +- .../Topology/EMetricSpace/PairReduction.lean | 2 + Mathlib/Topology/FiberBundle/Basic.lean | 7 +- .../Topology/FiberBundle/Constructions.lean | 4 +- .../Topology/FiberBundle/Trivialization.lean | 1 + Mathlib/Topology/FiberPartition.lean | 2 + Mathlib/Topology/Filter.lean | 1 + Mathlib/Topology/Gluing.lean | 3 + Mathlib/Topology/Homeomorph/Lemmas.lean | 2 + Mathlib/Topology/Homotopy/Basic.lean | 1 + Mathlib/Topology/Homotopy/HSpaces.lean | 2 +- Mathlib/Topology/Homotopy/HomotopyGroup.lean | 5 +- Mathlib/Topology/Homotopy/Lifting.lean | 8 +- Mathlib/Topology/Homotopy/Path.lean | 1 + Mathlib/Topology/Homotopy/Product.lean | 1 + Mathlib/Topology/Homotopy/TopCat/Basic.lean | 1 + .../Topology/Instances/AddCircle/Defs.lean | 1 + Mathlib/Topology/Instances/CantorSet.lean | 1 + Mathlib/Topology/Instances/Complex.lean | 1 + .../Topology/Instances/ENNReal/Lemmas.lean | 2 +- Mathlib/Topology/Irreducible.lean | 1 + Mathlib/Topology/IsClosedRestrict.lean | 1 + Mathlib/Topology/IsLocalHomeomorph.lean | 1 + .../Topology/MetricSpace/CauSeqFilter.lean | 1 + Mathlib/Topology/MetricSpace/Defs.lean | 2 +- Mathlib/Topology/MetricSpace/Gluing.lean | 4 +- .../Topology/MetricSpace/GromovHausdorff.lean | 1 + Mathlib/Topology/MetricSpace/Isometry.lean | 6 + Mathlib/Topology/MetricSpace/PiNat.lean | 6 +- .../MetricSpace/Pseudo/Constructions.lean | 4 +- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 4 +- .../Metrizable/CompletelyMetrizable.lean | 8 +- Mathlib/Topology/Metrizable/Uniformity.lean | 2 +- Mathlib/Topology/Neighborhoods.lean | 1 + Mathlib/Topology/NhdsWithin.lean | 2 + .../Topology/OmegaCompletePartialOrder.lean | 1 + Mathlib/Topology/Order.lean | 8 +- Mathlib/Topology/Order/Basic.lean | 2 +- Mathlib/Topology/Order/Bornology.lean | 3 +- Mathlib/Topology/Order/Completion.lean | 3 + Mathlib/Topology/Order/HullKernel.lean | 1 + Mathlib/Topology/Order/LawsonTopology.lean | 2 +- .../Topology/Order/LowerUpperTopology.lean | 4 +- Mathlib/Topology/Order/ScottTopology.lean | 4 +- .../Topology/Order/UpperLowerSetTopology.lean | 4 +- Mathlib/Topology/Order/WithTop.lean | 1 + Mathlib/Topology/Separation/Basic.lean | 3 +- Mathlib/Topology/Separation/Hausdorff.lean | 2 +- Mathlib/Topology/Sets/Closeds.lean | 2 +- Mathlib/Topology/Sets/Opens.lean | 2 +- Mathlib/Topology/Sheaves/Alexandrov.lean | 2 + Mathlib/Topology/Sheaves/Flasque.lean | 4 +- Mathlib/Topology/Sheaves/Presheaf.lean | 12 +- Mathlib/Topology/Sheaves/Skyscraper.lean | 2 + Mathlib/Topology/Sheaves/Stalks.lean | 11 ++ Mathlib/Topology/Sober.lean | 1 + .../Spectral/ConstructibleTopology.lean | 2 +- Mathlib/Topology/TietzeExtension.lean | 2 + .../Topology/UniformSpace/AbsoluteValue.lean | 2 +- .../UniformSpace/AbstractCompletion.lean | 1 + Mathlib/Topology/UniformSpace/Defs.lean | 2 +- .../Topology/UniformSpace/OfCompactT2.lean | 2 +- Mathlib/Topology/UniformSpace/OfFun.lean | 4 +- .../UniformConvergenceTopology.lean | 6 +- .../UniformSpace/UniformEmbedding.lean | 2 +- Mathlib/Topology/UnitInterval.lean | 5 +- Mathlib/Topology/VectorBundle/Basic.lean | 5 +- .../Topology/VectorBundle/Constructions.lean | 1 + Mathlib/Util/AddRelatedDecl.lean | 51 +++++++ Mathlib/Util/CompileInductive.lean | 19 +-- MathlibTest/CategoryTheory/FunctorAssoc.lean | 17 +++ MathlibTest/ClickSuggestions/Benchmark.lean | 3 +- MathlibTest/DefEqAbuse.lean | 4 +- MathlibTest/DeriveFintype.lean | 4 + MathlibTest/FastInstance.lean | 4 +- MathlibTest/InferInstanceAsPercent.lean | 10 +- MathlibTest/InstanceDiamonds.lean | 1 + MathlibTest/Linter/Whitespace.lean | 3 +- MathlibTest/Simproc/VecPerm.lean | 3 + MathlibTest/TacticCheckInstancesReassoc.lean | 45 ++++++ MathlibTest/TacticCheckInstancesSimps.lean | 38 +++++ MathlibTest/depRewrite.lean | 3 + MathlibTest/matrix.lean | 1 + lake-manifest.json | 16 +- lakefile.lean | 1 + lean-toolchain | 2 +- scripts/nolints.json | 4 +- scripts/set_option_utils.py | 1 + 2433 files changed, 8421 insertions(+), 2018 deletions(-) create mode 100644 MathlibTest/TacticCheckInstancesReassoc.lean create mode 100644 MathlibTest/TacticCheckInstancesSimps.lean diff --git a/Archive/Hairer.lean b/Archive/Hairer.lean index 3a76922a89ee45..7c3e39ffa40ebb 100644 --- a/Archive/Hairer.lean +++ b/Archive/Hairer.lean @@ -93,6 +93,7 @@ def L : MvPolynomial ι ℝ →ₗ[ℝ] (fun p f₁ f₂ ↦ by simp_rw [smul_eq_mul, ← integral_add (int p _) (int p _), ← mul_add]; rfl) fun r p f ↦ by simp_rw [← integral_smul, smul_comm r]; rfl +set_option backward.isDefEq.respectTransparency.types false in lemma inj_L : Injective (L ι) := (injective_iff_map_eq_zero _).mpr fun p hp ↦ by have H : ∀ᵐ x : EuclideanSpace ℝ ι, x ∈ ball 0 1 → eval x p = 0 := diff --git a/Archive/Imo/Imo1987Q1.lean b/Archive/Imo/Imo1987Q1.lean index c352c7910d960e..f8000aa5f9b540 100644 --- a/Archive/Imo/Imo1987Q1.lean +++ b/Archive/Imo/Imo1987Q1.lean @@ -31,6 +31,7 @@ open Finset (range sum_const) namespace Imo1987Q1 +set_option backward.isDefEq.respectTransparency false in /-- The set of pairs `(x : α, σ : Perm α)` such that `σ x = x` is equivalent to the set of pairs `(x : α, σ : Perm {x}ᶜ)`. -/ def fixedPointsEquiv : { σx : α × Perm α // σx.2 σx.1 = σx.1 } ≃ Σ x : α, Perm ({x}ᶜ : Set α) := @@ -41,6 +42,7 @@ def fixedPointsEquiv : { σx : α × Perm α // σx.2 σx.1 = σx.1 } ≃ Σ x : (sigmaCongrRight fun x => Equiv.setCongr <| by simp only [SetCoe.forall]; simp) _ ≃ Σ x : α, Perm ({x}ᶜ : Set α) := sigmaCongrRight fun x => by apply Equiv.Set.compl +set_option backward.isDefEq.respectTransparency false in theorem card_fixed_points : card { σx : α × Perm α // σx.2 σx.1 = σx.1 } = card α * (card α - 1)! := by simp only [card_congr (fixedPointsEquiv α), card_sigma, card_perm] diff --git a/Archive/Imo/Imo2013Q1.lean b/Archive/Imo/Imo2013Q1.lean index 0c379f5a42bdd7..c495c9dc7573c9 100644 --- a/Archive/Imo/Imo2013Q1.lean +++ b/Archive/Imo/Imo2013Q1.lean @@ -39,6 +39,8 @@ theorem prod_lemma (m : ℕ → ℕ+) (k : ℕ) (nm : ℕ+) : end Imo2013Q1 open Imo2013Q1 + +set_option backward.isDefEq.respectTransparency.types false in theorem imo2013_q1 (n : ℕ+) (k : ℕ) : ∃ m : ℕ → ℕ+, (1 : ℚ) + (2 ^ k - 1) / n = ∏ i ∈ Finset.range k, (1 + 1 / (m i : ℚ)) := by induction k generalizing n with diff --git a/Archive/Imo/Imo2019Q2.lean b/Archive/Imo/Imo2019Q2.lean index 9a8aafe704dd53..e8d16c06c9097f 100644 --- a/Archive/Imo/Imo2019Q2.lean +++ b/Archive/Imo/Imo2019Q2.lean @@ -94,7 +94,7 @@ structure Imo2019q2Cfg where C_ne_Q₁ : C ≠ Q₁ /-- A default choice of orientation, for lemmas that need to pick one. -/ -@[implicit_reducible] +@[instance_reducible] def someOrientation [hd2 : Fact (finrank ℝ V = 2)] : Module.Oriented ℝ V (Fin 2) := ⟨Basis.orientation (finBasisOfFinrankEq _ _ hd2.out)⟩ diff --git a/Archive/Imo/Imo2024Q5.lean b/Archive/Imo/Imo2024Q5.lean index ebdb10c91fe044..0ba79f1f9813d9 100644 --- a/Archive/Imo/Imo2024Q5.lean +++ b/Archive/Imo/Imo2024Q5.lean @@ -128,6 +128,7 @@ def MonsterData.reflect (m : MonsterData N) : MonsterData N where toFun := Fin.rev ∘ m inj' := fun i j hij ↦ by simpa using hij +set_option backward.isDefEq.respectTransparency false in lemma MonsterData.reflect_reflect (m : MonsterData N) : m.reflect.reflect = m := by ext i simp [MonsterData.reflect] @@ -149,7 +150,7 @@ lemma MonsterData.mk_mem_monsterCells_iff_of_le {m : MonsterData N} {r : Fin (N simp only [monsterCells, Set.mem_range, Prod.mk.injEq] refine ⟨?_, ?_⟩ · rintro ⟨r', rfl, rfl⟩ - simp only [Subtype.coe_eta] + simp only · rintro rfl exact ⟨⟨r, hr1, hrN⟩, rfl, rfl⟩ @@ -449,6 +450,7 @@ def Path.reflect (p : Path N) : Path N where simp_rw [Adjacent, Nat.dist, Cell.reflect, Fin.rev] at h ⊢ lia +set_option backward.isDefEq.respectTransparency false in lemma Path.firstMonster_reflect (p : Path N) (m : MonsterData N) : p.reflect.firstMonster m.reflect = (p.firstMonster m).map Cell.reflect := by simp_rw [firstMonster, reflect, List.find?_map] @@ -524,6 +526,7 @@ lemma Strategy.ForcesWinIn.mono (s : Strategy N) {k₁ k₂ : ℕ} (h : s.Forces /-! ### Proof of lower bound with constructions used therein -/ +set_option backward.isDefEq.respectTransparency false in /-- An arbitrary choice of monster positions, which is modified to put selected monsters in desired places. -/ def baseMonsterData (N : ℕ) : MonsterData N where @@ -539,6 +542,7 @@ def baseMonsterData (N : ℕ) : MonsterData N where def monsterData12 (hN : 2 ≤ N) (c₁ c₂ : Fin (N + 1)) : MonsterData N := ((baseMonsterData N).setValue (row2 hN) c₂).setValue (row1 hN) c₁ +set_option backward.isDefEq.respectTransparency false in lemma monsterData12_apply_row2 (hN : 2 ≤ N) {c₁ c₂ : Fin (N + 1)} (h : c₁ ≠ c₂) : monsterData12 hN c₁ c₂ (row2 hN) = c₂ := by rw [monsterData12, Function.Embedding.setValue_eq_of_ne] @@ -729,6 +733,7 @@ def winningStrategy (hN : 2 ≤ N) : Strategy N | 1 => fun r => path1 hN ((r 0).getD 0).2 | _ + 2 => fun r => path2 hN ((r 0).getD 0).2 ((r 1).getD 0).1 +set_option backward.isDefEq.respectTransparency false in lemma path0_firstMonster_eq_apply_row1 (hN : 2 ≤ N) (m : MonsterData N) : (path0 hN).firstMonster m = some (1, m (row1 hN)) := by simp_rw [path0, Path.firstMonster, Path.ofFn] @@ -958,6 +963,7 @@ lemma winningStrategy_play_one_eq_none_or_play_two_eq_none_of_edge_zero (hN : 2 exact path2OfEdge0_firstMonster_eq_none_of_path1OfEdge0_firstMonster_eq_some hN hx2N.1 hx2N.2 hc₁0 hx.symm +set_option backward.isDefEq.respectTransparency false in lemma winningStrategy_play_one_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} (hc₁N : (m (row1 hN) : ℕ) = N) : (winningStrategy hN).play m 3 ⟨1, by simp⟩ = ((winningStrategy hN).play m.reflect 3 ⟨1, by simp⟩).map Cell.reflect := by @@ -972,6 +978,7 @@ lemma winningStrategy_play_one_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} simp_rw [winningStrategy_play_one hN, path1, path1OfEdgeN, dif_neg hc₁0, if_pos hc₁N, dif_pos hc₁r0, ← Path.firstMonster_reflect, MonsterData.reflect_reflect] +set_option backward.isDefEq.respectTransparency false in lemma winningStrategy_play_two_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} (hc₁N : (m (row1 hN) : ℕ) = N) : (winningStrategy hN).play m 3 ⟨2, by simp⟩ = ((winningStrategy hN).play m.reflect 3 ⟨2, by simp⟩).map Cell.reflect := by @@ -994,6 +1001,7 @@ lemma winningStrategy_play_two_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} · rcases h with ⟨x, hx⟩ simp [hx, Cell.reflect] +set_option backward.isDefEq.respectTransparency false in lemma winningStrategy_play_one_eq_none_or_play_two_eq_none_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} (hc₁N : (m (row1 hN) : ℕ) = N) : (winningStrategy hN).play m 3 ⟨1, by simp⟩ = none ∨ diff --git a/Archive/MinimalSheffer.lean b/Archive/MinimalSheffer.lean index 19f9bbef6f1d99..a01a21f9b0e955 100644 --- a/Archive/MinimalSheffer.lean +++ b/Archive/MinimalSheffer.lean @@ -46,7 +46,7 @@ class VeroffAlgebra (α : Type*) extends Inhabited α where variable {α : Type*} /-- Derive a Veroff algebra from a Boolean algebra. -/ -@[implicit_reducible] +@[instance_reducible] def BooleanAlgebra.veroffAlgebra [BooleanAlgebra α] : VeroffAlgebra α where default := ⊥ f a b := (a ⊓ b)ᶜ @@ -207,7 +207,7 @@ class SingleShefferAlgebra (α : Type*) extends Inhabited α where variable {α : Type*} /-- Derive a `SingleShefferAlgebra` from a Boolean algebra. -/ -@[implicit_reducible] +@[instance_reducible] def BooleanAlgebra.singleShefferAlgebra [BooleanAlgebra α] : SingleShefferAlgebra α where default := ⊥ f a b := (a ⊓ b)ᶜ diff --git a/Archive/Sensitivity.lean b/Archive/Sensitivity.lean index 5458e4051ac856..b9d1b92d8c5959 100644 --- a/Archive/Sensitivity.lean +++ b/Archive/Sensitivity.lean @@ -403,6 +403,7 @@ theorem exists_eigenvalue (H : Set (Q m.succ)) (hH : Card H ≥ 2 ^ m + 1) : rw [Set.toFinset_card] at hH linarith +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- **Huang sensitivity theorem** also known as the **Huang degree theorem** -/ theorem huang_degree_theorem (H : Set (Q m.succ)) (hH : Card H ≥ 2 ^ m + 1) : diff --git a/Archive/Wiedijk100Theorems/FriendshipGraphs.lean b/Archive/Wiedijk100Theorems/FriendshipGraphs.lean index 7e473acaac194f..7c4c125c004b73 100644 --- a/Archive/Wiedijk100Theorems/FriendshipGraphs.lean +++ b/Archive/Wiedijk100Theorems/FriendshipGraphs.lean @@ -173,6 +173,7 @@ theorem isRegularOf_not_existsPolitician (hG' : ¬ExistsPolitician G) : open scoped Classical in include hG in +set_option backward.isDefEq.respectTransparency.types false in /-- Let `A` be the adjacency matrix of a `d`-regular friendship graph, and let `v` be a vector all of whose components are `1`. Then `v` is an eigenvector of `A ^ 2`, and we can compute the eigenvalue to be `d * d`, or as `d + (Fintype.card V - 1)`, so those quantities must be equal. diff --git a/Archive/Wiedijk100Theorems/Konigsberg.lean b/Archive/Wiedijk100Theorems/Konigsberg.lean index a7b598b01317c8..165b5a6a1dc0e2 100644 --- a/Archive/Wiedijk100Theorems/Konigsberg.lean +++ b/Archive/Wiedijk100Theorems/Konigsberg.lean @@ -17,6 +17,7 @@ between them has no Eulerian trail. namespace Konigsberg +set_option backward.isDefEq.respectTransparency.types false in /-- The vertices for the Königsberg graph; four vertices for the bodies of land and seven vertices for the bridges. -/ inductive Verts : Type diff --git a/Archive/ZagierTwoSquares.lean b/Archive/ZagierTwoSquares.lean index f3ca1d717a3649..61f14901867c4d 100644 --- a/Archive/ZagierTwoSquares.lean +++ b/Archive/ZagierTwoSquares.lean @@ -113,6 +113,7 @@ def complexInvo : Function.End (zagierSet k) := fun ⟨⟨x, y, z⟩, h⟩ => variable [hk : Fact (4 * k + 1).Prime] +set_option backward.isDefEq.respectTransparency false in /-- `complexInvo k` is indeed an involution. -/ theorem complexInvo_sq : complexInvo k ^ 2 = 1 := by change complexInvo k ∘ complexInvo k = id @@ -139,6 +140,7 @@ theorem complexInvo_sq : complexInvo k ^ 2 = 1 := by ← Nat.add_sub_assoc less, ← add_assoc, Nat.sub_add_cancel more, Nat.sub_sub _ _ y, ← two_mul, add_comm, Nat.add_sub_cancel] +set_option backward.isDefEq.respectTransparency false in /-- Any fixed point of `complexInvo k` must be `(1, 1, k)`. -/ theorem eq_of_mem_fixedPoints {t : zagierSet k} (mem : t ∈ fixedPoints (complexInvo k)) : t.val = (1, 1, k) := by @@ -169,6 +171,7 @@ theorem eq_of_mem_fixedPoints {t : zagierSet k} (mem : t ∈ fixedPoints (comple def singletonFixedPoint : Finset (zagierSet k) := {⟨(1, 1, k), (by simp only [zagierSet, Set.mem_setOf_eq]; linarith)⟩} +set_option backward.isDefEq.respectTransparency false in /-- `complexInvo k` has exactly one fixed point. -/ theorem card_fixedPoints_eq_one : Fintype.card (fixedPoints (complexInvo k)) = 1 := by rw [show 1 = Finset.card (singletonFixedPoint k) by rfl, ← Set.toFinset_card] diff --git a/Cache/Hashing.lean b/Cache/Hashing.lean index 418e884d1262cd..2da5f5b57fa25f 100644 --- a/Cache/Hashing.lean +++ b/Cache/Hashing.lean @@ -9,7 +9,7 @@ import Lean.Elab.ParseImportsFast namespace Cache.Hashing -open Lean IO +open Lean Cache.IO open System hiding SearchPath /-- diff --git a/Cache/IO.lean b/Cache/IO.lean index c83b5752d383e2..c8e18c204a914a 100644 --- a/Cache/IO.lean +++ b/Cache/IO.lean @@ -120,7 +120,7 @@ NOTE: making changes to the generated `.ltar` files invalidates them while it *d the file hash! This means any such change needs to be accompanied by a change to the root hash affecting *all* files (e.g. any modification to lakefile, lean-toolchain or manifest). -/ -def rootHashGeneration : UInt64 := 4 +def rootHashGeneration : UInt64 := 5 /-- `CacheM` stores the following information: @@ -310,6 +310,8 @@ def mkBuildPaths (mod : Name) : CacheM <| List (FilePath × Bool) := do (packageDir / LIBDIR / path.withExtension "olean.private.hash", false), (packageDir / LIBDIR / path.withExtension "ilean", true), (packageDir / LIBDIR / path.withExtension "ilean.hash", true), + (packageDir / LIBDIR / path.withExtension "ir.sig", false), + (packageDir / LIBDIR / path.withExtension "ir.sig.hash", false), (packageDir / LIBDIR / path.withExtension "ir", false), (packageDir / LIBDIR / path.withExtension "ir.hash", false), (packageDir / IRDIR / path.withExtension "c", true), diff --git a/Counterexamples/AharoniKorman.lean b/Counterexamples/AharoniKorman.lean index ffc861009c76ce..da1859c03f22e1 100644 --- a/Counterexamples/AharoniKorman.lean +++ b/Counterexamples/AharoniKorman.lean @@ -205,6 +205,7 @@ lemma induction_on_level {n : ℕ} {p : (x : Hollom) → x ∈ level n → Prop} rintro x y _ rfl exact h _ _ +set_option backward.isDefEq.respectTransparency false in /-- For each `n`, there is an order embedding from ℕ × ℕ (which has the product order) to the Hollom partial order. @@ -218,6 +219,7 @@ lemma embed_apply (n : ℕ) (x y : ℕ) : embed n (x, y) = h(x, y, n) := rfl lemma embed_strictMono {n : ℕ} : StrictMono (embed n) := (embed n).strictMono +set_option backward.isDefEq.respectTransparency false in lemma level_eq_range (n : ℕ) : level n = Set.range (embed n) := by simp [level, Set.range, embed] @@ -812,6 +814,7 @@ variable {n : ℕ} lemma R_subset_level : R n C ⊆ level n := Set.sep_subset (level n) _ +set_option backward.isDefEq.respectTransparency false in /-- A helper lemma to show `square_subset_R`. In particular shows that if `C ∩ level n` is finite, the set of points `x` such that `x` is at least as large as every element of `C ∩ level n` contains an @@ -853,6 +856,7 @@ lemma square_subset_above (h : (C ∩ level n).Finite) : specialize hab _ _ hfg lia +set_option backward.isDefEq.respectTransparency false in lemma square_subset_R (h : (C ∩ level n).Finite) : ∀ᶠ a in atTop, embed n '' Set.Ici (a, a) ⊆ R n C \ (C ∩ level n) := by filter_upwards [square_subset_above h] with a ha @@ -935,6 +939,7 @@ lemma S_subset_R : S n C ⊆ R n C := by lemma S_subset_level : S n C ⊆ level n := S_subset_R.trans R_subset_level +set_option backward.isDefEq.respectTransparency false in /-- Assuming `C ∩ level n` is finite, and `C ∩ level (n + 1)` is finite, that there exists cofinitely many `a` such that `{(x, y, n) | x ≥ a ∧ y ≥ a} ⊆ S \ (C ∩ level n)`. diff --git a/Counterexamples/MapFloor.lean b/Counterexamples/MapFloor.lean index c45e5c9454e12d..9edd2ddce521df 100644 --- a/Counterexamples/MapFloor.lean +++ b/Counterexamples/MapFloor.lean @@ -59,6 +59,7 @@ instance isOrderedAddMonoid : IsOrderedAddMonoid ℤ[ε] := Function.Injective.isOrderedAddMonoid (toLex ∘ coeff) (fun _ _ => funext fun _ => coeff_add _ _ _) .rfl +set_option backward.isDefEq.respectTransparency false in theorem pos_iff {p : ℤ[ε]} : 0 < p ↔ 0 < p.trailingCoeff := by rw [trailingCoeff] refine @@ -118,6 +119,7 @@ theorem forgetEpsilons_floor_lt (n : ℤ) : exact (if_neg <| by rw [coeff_sub, intCast_coeff_zero]; simp [this]).trans (by rw [coeff_sub, intCast_coeff_zero]; simp) +set_option backward.isDefEq.respectTransparency false in /-- The ceil of `n + ε` is `n + 1` but its image under `forgetEpsilons` is `n`, whose ceil is itself. -/ theorem lt_forgetEpsilons_ceil (n : ℤ) : diff --git a/Counterexamples/Phillips.lean b/Counterexamples/Phillips.lean index 384d1931679214..bea08c8a88d13b 100644 --- a/Counterexamples/Phillips.lean +++ b/Counterexamples/Phillips.lean @@ -288,13 +288,13 @@ theorem exists_discrete_support_nonpos (f : BoundedAdditiveMeasure α) : simp only [u, not_exists, mem_iUnion, mem_sdiff] tauto · congr 1 - simp only [G, s, Function.iterate_succ', Subtype.coe_mk, union_sdiff_left, Function.comp] + simp only [G, s, Function.iterate_succ', union_sdiff_left, Function.comp] have I2 : ∀ n : ℕ, (n : ℝ) * (ε / 2) ≤ f ↑(s n) := by intro n induction n with | zero => simp only [s, empty, BoundedAdditiveMeasure.empty, id, Nat.cast_zero, zero_mul, - Function.iterate_zero, Subtype.coe_mk, le_rfl] + Function.iterate_zero, le_rfl] | succ n IH => have : (s (n + 1)).1 = (s (n + 1)).1 \ (s n).1 ∪ (s n).1 := by simpa only [s, Function.iterate_succ', union_sdiff_self] diff --git a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean index 08f0094e39a030..5b0f8d98d00373 100644 --- a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean +++ b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean @@ -213,6 +213,7 @@ theorem f111 : ofLex (Finsupp.single (1 : F) (1 : F)) 1 = 1 := theorem f110 : ofLex (Finsupp.single (1 : F) (1 : F)) 0 = 0 := single_apply_eq_zero.mpr fun h => h.symm +set_option backward.isDefEq.respectTransparency false in /-- Here we see that (not-necessarily strict) monotonicity of addition on `Lex (F →₀ F)` is not a consequence of monotonicity of addition on `F`. Strict monotonicity of addition on `F` is enough and is the content of `Finsupp.Lex.addLeftStrictMono`. -/ diff --git a/Mathlib/Algebra/Algebra/Epi.lean b/Mathlib/Algebra/Algebra/Epi.lean index 52f7f61ab1ba33..8e114e11a53858 100644 --- a/Mathlib/Algebra/Algebra/Epi.lean +++ b/Mathlib/Algebra/Algebra/Epi.lean @@ -122,6 +122,7 @@ section Module variable (M : Type*) [AddCommMonoid M] [Module R M] [Module A M] [IsScalarTower R A M] +set_option backward.isDefEq.respectTransparency false in /-- If an `R`-algebra `A` is epi, then the scalar multiplication `A ⊗[R] M → M` is injective, for any `A`-module `M`. -/ lemma injective_lift_lsmul : diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index 583fbc391281cc..5ad24a529a6ae8 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -895,6 +895,7 @@ variable {R S M₁ M₂ : Type*} [CommSemiring R] [AddCommMonoid M₁] [Module R [SMulCommClass S R M₁] [SMulCommClass S R M₂] [SMul R S] [IsScalarTower R S M₁] [IsScalarTower R S M₂] +set_option backward.isDefEq.respectTransparency false in variable (R) in /-- A linear equivalence of two modules induces an equivalence of algebras of their endomorphisms. -/ diff --git a/Mathlib/Algebra/Algebra/NonUnitalHom.lean b/Mathlib/Algebra/Algebra/NonUnitalHom.lean index 81b640abd850c2..5ddd9c8393692f 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalHom.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalHom.lean @@ -317,6 +317,7 @@ theorem coe_inverse (f : A →ₙₐ[R] B₁) (g : B₁ → A) (h₁ : Function. (h₂ : Function.RightInverse g f) : (inverse f g h₁ h₂ : B₁ → A) = g := rfl +set_option backward.isDefEq.respectTransparency false in /-- The inverse of a bijective morphism is a morphism. -/ def inverse' (f : A →ₛₙₐ[φ] B) (g : B → A) (k : Function.RightInverse φ' φ) @@ -368,6 +369,7 @@ def snd : A × B →ₙₐ[R] B where variable {R A B} variable [DistribMulAction R C] +set_option backward.isDefEq.respectTransparency false in /-- The prod of two morphisms is a morphism. -/ @[simps toFun] def prod (f : A →ₙₐ[R] B) (g : A →ₙₐ[R] C) : A →ₙₐ[R] B × C where diff --git a/Mathlib/Algebra/Algebra/Operations.lean b/Mathlib/Algebra/Algebra/Operations.lean index ac958fba49be6a..388205521e3742 100644 --- a/Mathlib/Algebra/Algebra/Operations.lean +++ b/Mathlib/Algebra/Algebra/Operations.lean @@ -729,6 +729,7 @@ noncomputable def span.ringHom : SetSemiring A →+* Submodule R A where map_add' := span_union map_mul' s t := by simp_rw [SetSemiring.down_mul, span_mul_span] +set_option backward.isDefEq.respectTransparency false in variable (R) in /-- `(span R {·})` as a `MonoidWithZeroHom`. -/ noncomputable def spanSingleton : A →*₀ Submodule R A where diff --git a/Mathlib/Algebra/Algebra/Opposite.lean b/Mathlib/Algebra/Algebra/Opposite.lean index d9099b935aeaef..99e8b0f7554cec 100644 --- a/Mathlib/Algebra/Algebra/Opposite.lean +++ b/Mathlib/Algebra/Algebra/Opposite.lean @@ -41,6 +41,7 @@ variable [IsScalarTower R S A] namespace MulOpposite +set_option backward.isDefEq.respectTransparency false in instance instAlgebra : Algebra R Aᵐᵒᵖ where algebraMap := (algebraMap R A).toOpposite fun _ _ => Algebra.commutes _ _ smul_def' c x := unop_injective <| by @@ -133,6 +134,9 @@ end AlgHom namespace AlgEquiv +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An algebra iso `A ≃ₐ[R] B` can equivalently be viewed as an algebra iso `Aᵐᵒᵖ ≃ₐ[R] Bᵐᵒᵖ`. This is the action of the (fully faithful) `ᵐᵒᵖ`-functor on morphisms. -/ @[simps!] @@ -162,6 +166,9 @@ theorem toRingEquiv_unop (f : Aᵐᵒᵖ ≃ₐ[R] Bᵐᵒᵖ) : (AlgEquiv.unop f).toRingEquiv = RingEquiv.unop f.toRingEquiv := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Swap the `ᵐᵒᵖ` on an algebra isomorphism to the opposite side. -/ @[simps!] def opComm : (A ≃ₐ[R] Bᵐᵒᵖ) ≃ (Aᵐᵒᵖ ≃ₐ[R] B) := diff --git a/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean b/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean index 01711a7aa8dadb..89ea7868bed4fa 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean @@ -268,6 +268,7 @@ instance quasispectrum.instZero [Nontrivial R] (a : A) : Zero (quasispectrum R a variable {R} +set_option backward.isDefEq.respectTransparency false in /-- A version of `NonUnitalAlgHom.quasispectrum_apply_subset` which allows for `quasispectrum R`, where `R` is a *semi*ring, but `φ` must still function over a scalar ring `S`. In this case, we need `S` to be explicit. The primary use case is, for instance, `R := ℝ≥0` and `S := ℝ` or diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean index a34f06fcba9763..06c6fc29c2b983 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean @@ -287,7 +287,7 @@ instance toCommRing {R A} [CommRing R] [CommRing A] [Algebra R A] (S : Subalgebr end /-- The forgetful map from `Subalgebra` to `Submodule` as an `OrderEmbedding` -/ -@[implicit_reducible] -- Not `@[reducible]` because it is an order embedding rather than a function. +@[instance_reducible] -- Not `@[reducible]` because it is an order embedding rather than a function. def toSubmodule : Subalgebra R A ↪o Submodule R A where toEmbedding := { toFun := fun S => @@ -645,6 +645,9 @@ noncomputable def ofInjectiveField {E F : Type*} [DivisionRing E] [Semiring F] [ [Algebra R E] [Algebra R F] (f : E →ₐ[R] F) : E ≃ₐ[R] f.range := ofInjective f f.toRingHom.injective +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given an equivalence `e : A ≃ₐ[R] B` of `R`-algebras and a subalgebra `S` of `A`, `subalgebraMap` is the induced equivalence between `S` and `S.map e` -/ @[simps!] diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Directed.lean b/Mathlib/Algebra/Algebra/Subalgebra/Directed.lean index 9f7129dabe3f2b..d59c692627c511 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Directed.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Directed.lean @@ -88,6 +88,7 @@ noncomputable def iSupLift (dir : Directed (· ≤ ·) K) (f : ∀ i, K i →ₐ exact liftSup.comp (inclusion hT) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem iSupLift_inclusion {dir : Directed (· ≤ ·) K} {f : ∀ i, K i →ₐ[R] B} {hf : ∀ (i j : ι) (h : K i ≤ K j), f i = (f j).comp (inclusion h)} @@ -103,6 +104,7 @@ theorem iSupLift_comp_inclusion {dir : Directed (· ≤ ·) K} {f : ∀ i, K i {T : Subalgebra R A} {hT : T ≤ iSup K} {i : ι} (h : K i ≤ T) : (iSupLift K dir f hf T hT).comp (inclusion h) = f i := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem iSupLift_mk {dir : Directed (· ≤ ·) K} {f : ∀ i, K i →ₐ[R] B} {hf : ∀ (i j : ι) (h : K i ≤ K j), f i = (f j).comp (inclusion h)} @@ -111,6 +113,7 @@ theorem iSupLift_mk {dir : Directed (· ≤ ·) K} {f : ∀ i, K i →ₐ[R] B} dsimp [iSupLift, inclusion] rw [Set.iUnionLift_mk] +set_option backward.isDefEq.respectTransparency false in theorem iSupLift_of_mem {dir : Directed (· ≤ ·) K} {f : ∀ i, K i →ₐ[R] B} {hf : ∀ (i j : ι) (h : K i ≤ K j), f i = (f j).comp (inclusion h)} {T : Subalgebra R A} {hT : T ≤ iSup K} {i : ι} (x : T) (hx : (x : A) ∈ K i) : diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean b/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean index 0e4d16ce2a3182..141383dfa8ed2b 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Lattice.lean @@ -296,6 +296,9 @@ noncomputable def botEquivOfInjective (h : Function.Injective (algebraMap R A)) AlgEquiv.ofBijective (Algebra.ofId R _) ⟨fun _x _y hxy => h (congr_arg Subtype.val hxy :), fun ⟨_y, x, hx⟩ => ⟨x, Subtype.ext hx⟩⟩ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The bottom subalgebra is isomorphic to the field. -/ @[simps! symm_apply] noncomputable def botEquiv (F R : Type*) [Field F] [Semiring R] [Nontrivial R] [Algebra F R] : diff --git a/Mathlib/Algebra/Algebra/ZMod.lean b/Mathlib/Algebra/Algebra/ZMod.lean index f85f479649561a..63a9d05116a9b7 100644 --- a/Mathlib/Algebra/Algebra/ZMod.lean +++ b/Mathlib/Algebra/Algebra/ZMod.lean @@ -50,7 +50,7 @@ abbrev algebra (p : ℕ) [CharP R p] : Algebra (ZMod p) R := set_option backward.isDefEq.respectTransparency false in /-- Any ring with a `ZMod p`-module structure can be upgraded to a `ZMod p`-algebra. Not an instance because this is usually not the default way, and this will cause typeclass search loop. -/ -@[implicit_reducible] +@[instance_reducible] def algebraOfModule (n : ℕ) (R : Type*) [Ring R] [Module (ZMod n) R] : Algebra (ZMod n) R := Algebra.ofModule' (proof · · |>.1) (proof · · |>.2) where proof (r : ZMod n) (x : R) : r • 1 * x = r • x ∧ x * r • 1 = r • x := by diff --git a/Mathlib/Algebra/BigOperators/Expect.lean b/Mathlib/Algebra/BigOperators/Expect.lean index 6eb5f5d9c556cc..1c9ee18e86f466 100644 --- a/Mathlib/Algebra/BigOperators/Expect.lean +++ b/Mathlib/Algebra/BigOperators/Expect.lean @@ -282,6 +282,7 @@ end bij @[simp] lemma expect_neg_index [DecidableEq ι] [InvolutiveNeg ι] (s : Finset ι) (f : ι → M) : 𝔼 i ∈ -s, f i = 𝔼 i ∈ s, f (-i) := expect_image neg_injective.injOn +set_option backward.isDefEq.respectTransparency false in lemma _root_.map_expect {F : Type*} [FunLike F M N] [LinearMapClass F ℚ≥0 M N] (g : F) (f : ι → M) (s : Finset ι) : g (𝔼 i ∈ s, f i) = 𝔼 i ∈ s, g (f i) := by simp only [expect, map_smul, map_sum] diff --git a/Mathlib/Algebra/BigOperators/Fin.lean b/Mathlib/Algebra/BigOperators/Fin.lean index 820c987873e884..8fcbbfdf1a86b0 100644 --- a/Mathlib/Algebra/BigOperators/Fin.lean +++ b/Mathlib/Algebra/BigOperators/Fin.lean @@ -617,6 +617,7 @@ theorem finFunctionFinEquiv_single {m n : ℕ} [NeZero m] (i : Fin n) (j : Fin m rintro x hx rw [Pi.single_eq_of_ne hx, Fin.val_zero, zero_mul] +set_option backward.isDefEq.respectTransparency false in /-- Equivalence between `∀ i : Fin m, Fin (n i)` and `Fin (∏ i : Fin m, n i)`. -/ def finPiFinEquiv {m : ℕ} {n : Fin m → ℕ} : (∀ i : Fin m, Fin (n i)) ≃ Fin (∏ i : Fin m, n i) := Equiv.ofRightInverseOfCardLE (le_of_eq <| by simp_rw [Fintype.card_pi, Fintype.card_fin]) @@ -688,6 +689,7 @@ def finSigmaFinEquiv {m : ℕ} {n : Fin m → ℕ} : (i : Fin m) × Fin (n i) _ ≃ _ := finSumFinEquiv _ ≃ _ := finCongr (Fin.sum_univ_castSucc n).symm +set_option backward.isDefEq.respectTransparency false in @[simp] theorem finSigmaFinEquiv_apply {m : ℕ} {n : Fin m → ℕ} (k : (i : Fin m) × Fin (n i)) : (finSigmaFinEquiv k : ℕ) = ∑ i : Fin k.1, n (Fin.castLE k.1.2.le i) + k.2 := by diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index 803c32af269d78..1619e29b840153 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -395,6 +395,7 @@ theorem finprod_def (f : α → M) [Decidable (HasFiniteMulSupport f)] : rw [HasFiniteMulSupport, mulSupport_comp_eq_preimage] exact mt (fun hf => hf.of_preimage Equiv.plift.surjective) h +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem finprod_of_infinite_mulSupport {f : α → M} (hf : (mulSupport f).Infinite) : ∏ᶠ i, f i = 1 := by @@ -477,6 +478,7 @@ theorem finprod_cond_eq_prod_of_cond_iff (f : α → M) {p : α → Prop} {t : F contrapose! hxs exact (h hxs).2 hx +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem finprod_cond_ne (f : α → M) (a : α) [DecidableEq α] (hf : HasFiniteMulSupport f) : (∏ᶠ (i) (_ : i ≠ a), f i) = ∏ i ∈ hf.toFinset.erase a, f i := by @@ -509,6 +511,7 @@ theorem finprod_mem_eq_prod (f : α → M) {s : Set α} (hf : (s ∩ mulSupport ∏ᶠ i ∈ s, f i = ∏ i ∈ hf.toFinset, f i := finprod_mem_eq_prod_of_inter_mulSupport_eq _ <| by simp [inter_assoc] +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem finprod_mem_eq_prod_filter (f : α → M) (s : Set α) [DecidablePred (· ∈ s)] (hf : HasFiniteMulSupport f) : @@ -642,6 +645,7 @@ lemma finprod_zero_le_one {M α : Type*} [CommMonoidWithZero M] [PartialOrder M] -/ +set_option backward.isDefEq.respectTransparency false in /-- If the multiplicative supports of `f` and `g` are finite, then the product of `f i * g i` equals the product of `f i` multiplied by the product of `g i`. -/ @[to_additive @@ -1107,6 +1111,7 @@ lemma finprod_mem_powerset_sdiff_elem {f : Set α → M} {s : Set α} {a : α} ( @[deprecated (since := "2026-06-03")] alias finprod_mem_powerset_diff_elem := finprod_mem_powerset_sdiff_elem +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem mul_finprod_cond_ne (a : α) (hf : HasFiniteMulSupport f) : (f a * ∏ᶠ (i) (_ : i ≠ a), f i) = ∏ᶠ i, f i := by @@ -1284,6 +1289,7 @@ theorem finsum_mem_mul {R : Type*} [NonUnitalNonAssocSemiring R] [NoZeroDivisors ext a by_cases h : a ∈ s <;> simp_all +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma finprod_apply {α ι : Type*} {f : ι → α → N} (hf : HasFiniteMulSupport f) (a : α) : (∏ᶠ i, f i) a = ∏ᶠ i, f i a := by @@ -1342,6 +1348,7 @@ theorem finprod_mem_finset_product₃ {γ : Type*} (s : Finset (α × β × γ)) simp_rw [finprod_mem_finset_product'] simp +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem finprod_curry (f : α × β → M) (hf : HasFiniteMulSupport f) : ∏ᶠ ab, f ab = ∏ᶠ (a) (b), f (a, b) := by diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index 9746c1d87dd066..a4436803d59118 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -153,6 +153,7 @@ lemma prod_filter_not_mul_prod_filter (s : Finset ι) (p : ι → Prop) [Decidab (∏ x ∈ s with ¬p x, f x) * ∏ x ∈ s with p x, f x = ∏ x ∈ s, f x := by rw [mul_comm, prod_filter_mul_prod_filter_not] +set_option backward.isDefEq.respectTransparency.types false in @[to_additive] theorem prod_filter_xor (p q : ι → Prop) [DecidablePred p] [DecidablePred q] : (∏ x ∈ s with (Xor (p x) (q x)), f x) = diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Powerset.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Powerset.lean index df6800dcc64955..5bdd415f438b15 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Powerset.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Powerset.lean @@ -47,6 +47,7 @@ lemma prod_powerset_cons (ha : a ∉ s) (f : Finset α → β) : simp_rw [cons_eq_insert] rw [prod_powerset_insert ha, prod_attach _ fun t ↦ f (insert a t)] +set_option backward.isDefEq.respectTransparency false in /-- A product over `powerset s` is equal to the double product over sets of subsets of `s` with `#s = k`, for `k = 0, ..., #s`. -/ @[to_additive /-- A sum over `powerset s` is equal to the double sum over sets of subsets of `s` diff --git a/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean index 04badc18840eb4..bb8f39d2d3e753 100644 --- a/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Multiset/Basic.lean @@ -195,6 +195,7 @@ theorem prod_map_inv : (m.map fun i => (f i)⁻¹).prod = (m.map f).prod⁻¹ := theorem prod_map_div : (m.map fun i => f i / g i).prod = (m.map f).prod / (m.map g).prod := m.prod_hom₂ (· / ·) mul_div_mul_comm (div_one _) _ _ +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem prod_map_zpow {n : ℤ} : (m.map fun i => f i ^ n).prod = (m.map f).prod ^ n := by convert! (m.map f).prod_hom (zpowGroupHom n : G →* G) diff --git a/Mathlib/Algebra/BigOperators/GroupWithZero/Finset.lean b/Mathlib/Algebra/BigOperators/GroupWithZero/Finset.lean index 161fd1db9edb53..ea97561f206602 100644 --- a/Mathlib/Algebra/BigOperators/GroupWithZero/Finset.lean +++ b/Mathlib/Algebra/BigOperators/GroupWithZero/Finset.lean @@ -77,6 +77,7 @@ lemma prod_boole : ∏ i, (ite (p i) 1 0 : M₀) = ite (∀ i, p i) 1 0 := by si end Fintype +set_option backward.isDefEq.respectTransparency false in lemma Units.mk0_prod [CommGroupWithZero G₀] (s : Finset ι) (f : ι → G₀) (h) : Units.mk0 (∏ i ∈ s, f i) h = ∏ i ∈ s.attach, Units.mk0 (f i) fun hh ↦ h (Finset.prod_eq_zero i.2 hh) := by diff --git a/Mathlib/Algebra/BrauerGroup/Defs.lean b/Mathlib/Algebra/BrauerGroup/Defs.lean index 8b82a886f653dd..2b54517bb12e66 100644 --- a/Mathlib/Algebra/BrauerGroup/Defs.lean +++ b/Mathlib/Algebra/BrauerGroup/Defs.lean @@ -89,7 +89,7 @@ end IsBrauerEquivalent variable (K) /-- `CSA` equipped with Brauer Equivalence is indeed a setoid. -/ -@[implicit_reducible] +@[instance_reducible] def Brauer.CSA_Setoid : Setoid (CSA K) where r := IsBrauerEquivalent iseqv := IsBrauerEquivalent.is_eqv diff --git a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean index 76a11fe84b764f..1de129acf007ae 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean @@ -183,6 +183,7 @@ variable (K : Type u) [Field K] instance (V W : FGModuleCat.{v} K) : Module.Finite K (V.obj ⟶ W.obj) := ((inferInstance : Module.Finite K (V →ₗ[K] W))).equiv ModuleCat.homLinearEquiv.symm +set_option backward.isDefEq.respectTransparency.types false in instance (V W : FGModuleCat.{v} K) : Module.Finite K (V ⟶ W) := ((inferInstance : Module.Finite K (V.obj ⟶ W.obj))).equiv InducedCategory.homLinearEquiv.symm diff --git a/Mathlib/Algebra/Category/FGModuleCat/Colimits.lean b/Mathlib/Algebra/Category/FGModuleCat/Colimits.lean index 57f060aa8d6d3d..3f651e84df2be2 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Colimits.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Colimits.lean @@ -47,7 +47,7 @@ instance (F : J ⥤ FGModuleCat k) : ((ModuleCat.epi_iff_surjective _).1 inferInstance) /-- The forgetful functor from `FGModuleCat k` to `ModuleCat k` creates all finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def forget₂CreatesColimit (F : J ⥤ FGModuleCat k) : CreatesColimit F (forget₂ (FGModuleCat k) (ModuleCat.{v} k)) := createsColimitOfFullyFaithfulOfIso diff --git a/Mathlib/Algebra/Category/FGModuleCat/Limits.lean b/Mathlib/Algebra/Category/FGModuleCat/Limits.lean index b69d9069967393..76acb6a4d3fff6 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Limits.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Limits.lean @@ -55,7 +55,7 @@ instance (F : J ⥤ FGModuleCat k) : ((ModuleCat.mono_iff_injective _).1 inferInstance) /-- The forgetful functor from `FGModuleCat k` to `ModuleCat k` creates all finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def forget₂CreatesLimit (F : J ⥤ FGModuleCat k) : CreatesLimit F (forget₂ (FGModuleCat k) (ModuleCat.{v} k)) := createsLimitOfFullyFaithfulOfIso diff --git a/Mathlib/Algebra/Category/Grp/Abelian.lean b/Mathlib/Algebra/Category/Grp/Abelian.lean index 7c562be12b48e8..8149f6ee485631 100644 --- a/Mathlib/Algebra/Category/Grp/Abelian.lean +++ b/Mathlib/Algebra/Category/Grp/Abelian.lean @@ -29,13 +29,13 @@ namespace AddCommGrpCat variable {X Y Z : AddCommGrpCat.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) /-- In the category of abelian groups, every monomorphism is normal. -/ -@[implicit_reducible] +@[instance_reducible] def normalMono (_ : Mono f) : NormalMono f := equivalenceReflectsNormalMono (forget₂ (ModuleCat.{u} ℤ) AddCommGrpCat.{u}).inv <| ModuleCat.normalMono _ inferInstance /-- In the category of abelian groups, every epimorphism is normal. -/ -@[implicit_reducible] +@[instance_reducible] def normalEpi (_ : Epi f) : NormalEpi f := equivalenceReflectsNormalEpi (forget₂ (ModuleCat.{u} ℤ) AddCommGrpCat.{u}).inv <| ModuleCat.normalEpi _ inferInstance diff --git a/Mathlib/Algebra/Category/Grp/Colimits.lean b/Mathlib/Algebra/Category/Grp/Colimits.lean index 9f0f528f0bc554..bcef27d14efa93 100644 --- a/Mathlib/Algebra/Category/Grp/Colimits.lean +++ b/Mathlib/Algebra/Category/Grp/Colimits.lean @@ -126,8 +126,7 @@ lemma quotToQuotUlift_ι [DecidableEq J] (j : J) (x : F.obj j) : dsimp [quotToQuotUlift, Quot.ι] conv_lhs => erw [AddMonoidHom.comp_apply (QuotientAddGroup.mk' (Relations F)) (DFinsupp.singleAddHom _ j), QuotientAddGroup.lift_mk'] - simp only [DFinsupp.singleAddHom_apply, DFinsupp.sumAddHom_single, AddMonoidHom.coe_comp, - Function.comp_apply] + simp only [DFinsupp.singleAddHom_apply, DFinsupp.sumAddHom_single] rfl set_option backward.defeqAttrib.useBackward true in @@ -143,6 +142,7 @@ def quotUliftToQuot [DecidableEq J] : Quot (F ⋙ uliftFunctor.{u'}) →+ Quot F obtain ⟨j, j', u, a, rfl⟩ := hx simp +set_option backward.isDefEq.respectTransparency.types false in lemma quotUliftToQuot_ι [DecidableEq J] (j : J) (x : (F ⋙ uliftFunctor.{u'}).obj j) : quotUliftToQuot F (Quot.ι _ j x) = Quot.ι F j x.down := by dsimp [quotUliftToQuot, Quot.ι] @@ -152,6 +152,7 @@ lemma quotUliftToQuot_ι [DecidableEq J] (j : J) (x : (F ⋙ uliftFunctor.{u'}). DFinsupp.sumAddHom_single, AddMonoidHom.coe_comp, Function.comp_apply] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The additive equivalence between `Quot F` and `Quot (F ⋙ uliftFunctor.{u'})`. -/ @@ -300,6 +301,7 @@ namespace AddCommGrpCat open QuotientAddGroup +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- The categorical cokernel of a morphism in `AddCommGrpCat` agrees with the usual group-theoretical quotient. diff --git a/Mathlib/Algebra/Category/Grp/EpiMono.lean b/Mathlib/Algebra/Category/Grp/EpiMono.lean index 1414285658ead5..ecca59b6ecd775 100644 --- a/Mathlib/Algebra/Category/Grp/EpiMono.lean +++ b/Mathlib/Algebra/Category/Grp/EpiMono.lean @@ -135,6 +135,7 @@ theorem fromCoset_eq_of_mem_range {b : B} (hb : b ∈ f.hom.range) : example (G : Type) [Group G] (S : Subgroup G) : Set G := S +set_option backward.isDefEq.respectTransparency.types false in theorem fromCoset_ne_of_nin_range {b : B} (hb : b ∉ f.hom.range) : fromCoset ⟨b • ↑f.hom.range, b, rfl⟩ ≠ fromCoset ⟨f.hom.range, 1, one_leftCoset _⟩ := by intro r @@ -171,6 +172,7 @@ theorem τ_symm_apply_infinity : Equiv.symm τ ∞ = fromCoset ⟨f.hom.range, 1, one_leftCoset _⟩ := by rw [tau, Equiv.symm_swap, Equiv.swap_apply_right] +set_option backward.isDefEq.respectTransparency.types false in /-- Let `g : B ⟶ S(X')` be defined as such that, for any `β : B`, `g(β)` is the function sending point at infinity to point at infinity and sending coset `y` to `β • y`. -/ @@ -280,6 +282,7 @@ theorem comp_eq : (f ≫ ofHom g) = f ≫ ofHom h := by use a rw [this] +set_option backward.isDefEq.respectTransparency.types false in theorem g_ne_h (x : B) (hx : x ∉ f.hom.range) : g ≠ h := by intro r apply fromCoset_ne_of_nin_range _ hx diff --git a/Mathlib/Algebra/Category/Grp/Images.lean b/Mathlib/Algebra/Category/Grp/Images.lean index 3d103f20cbe859..2d5bbf1c62cc81 100644 --- a/Mathlib/Algebra/Category/Grp/Images.lean +++ b/Mathlib/Algebra/Category/Grp/Images.lean @@ -55,6 +55,7 @@ attribute [local simp] image.fac variable {f} +set_option backward.isDefEq.respectTransparency.types false in /-- the universal property for the image factorisation -/ noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I := ofHom @@ -77,6 +78,7 @@ noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I := rw [(Classical.indefiniteDescription (fun z => f z = _) _).2] rfl } +set_option backward.isDefEq.respectTransparency.types false in theorem image.lift_fac (F' : MonoFactorisation f) : image.lift F' ≫ F'.m = image.ι f := by ext x change (F'.e ≫ F'.m) _ = _ diff --git a/Mathlib/Algebra/Category/Grp/Limits.lean b/Mathlib/Algebra/Category/Grp/Limits.lean index 0e1076b924b990..17b3eda4e2e7db 100644 --- a/Mathlib/Algebra/Category/Grp/Limits.lean +++ b/Mathlib/Algebra/Category/Grp/Limits.lean @@ -39,7 +39,6 @@ variable (F : J ⥤ GrpCat.{u}) instance groupObj (j) : Group ((F ⋙ forget GrpCat).obj j) := inferInstanceAs <| Group (F.obj j) -set_option backward.isDefEq.respectTransparency false in /-- The flat sections of a functor into `GrpCat` form a subgroup of all sections. -/ @[to_additive /-- The flat sections of a functor into `AddGrpCat` form an additive subgroup of all sections. -/] diff --git a/Mathlib/Algebra/Category/ModuleCat/Abelian.lean b/Mathlib/Algebra/Category/ModuleCat/Abelian.lean index 0c4cd3385802ff..54da0a7772bd94 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Abelian.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Abelian.lean @@ -29,7 +29,7 @@ namespace ModuleCat variable {R : Type u} [Ring R] {M N : ModuleCat.{v} R} (f : M ⟶ N) /-- In the category of modules, every monomorphism is normal. -/ -@[implicit_reducible] +@[instance_reducible] def normalMono (hf : Mono f) : NormalMono f where Z := of R (N ⧸ LinearMap.range f.hom) g := ofHom (LinearMap.range f.hom).mkQ @@ -51,7 +51,7 @@ def normalMono (hf : Mono f) : NormalMono f where LinearEquiv.ofEq _ _ (Submodule.ker_mkQ _).symm))) <| by ext; rfl /-- In the category of modules, every epimorphism is normal. -/ -@[implicit_reducible] +@[instance_reducible] def normalEpi (hf : Epi f) : NormalEpi f where W := of R (LinearMap.ker f.hom) g := ofHom (LinearMap.ker f.hom).subtype diff --git a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean index 7332a20631d816..97710a7ea0f8dd 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean @@ -89,8 +89,8 @@ def freeHomEquiv {X : Type u} {M : ModuleCat.{u} R} : variable (R) -/-- The free-forgetful adjunction for R-modules. --/ +set_option backward.isDefEq.respectTransparency.types false in +/-- The free-forgetful adjunction for R-modules. -/ def adj : free R ⊣ forget (ModuleCat.{u} R) := Adjunction.mkOfHomEquiv { homEquiv := fun _ _ => freeHomEquiv @@ -114,6 +114,7 @@ variable [CommRing R] namespace FreeMonoidal +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical isomorphism `𝟙_ (ModuleCat R) ≅ (free R).obj (𝟙_ (Type u))`. (This should not be used directly: it is part of the implementation of the monoidal structure on the functor `free R`.) -/ @@ -129,9 +130,11 @@ def εIso : 𝟙_ (ModuleCat R) ≅ (free R).obj (𝟙_ (Type u)) where erw [Finsupp.lapply_apply, Finsupp.lsingle_apply] rw [Finsupp.single_eq_same] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma εIso_hom_one : (εIso R).hom 1 = freeMk PUnit.unit := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma εIso_inv_freeMk (x : PUnit) : (εIso R).inv (freeMk x) = 1 := by dsimp [εIso, freeMk] @@ -161,6 +164,7 @@ lemma μIso_inv_freeMk {X Y : Type u} (z : X ⊗ Y) : erw [finsuppTensorFinsupp'_symm_single_eq_single_one_tmul] end FreeMonoidal +set_option backward.isDefEq.respectTransparency.types false in open FreeMonoidal in /-- The free functor `Type u ⥤ ModuleCat R` is a monoidal functor. -/ instance : (free R).Monoidal := @@ -192,9 +196,11 @@ instance : (free R).Monoidal := open Functor.LaxMonoidal Functor.OplaxMonoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma free_ε_one : ε (free R) 1 = freeMk PUnit.unit := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma free_η_freeMk (x : PUnit) : η (free R) (freeMk x) = 1 := by apply FreeMonoidal.εIso_inv_freeMk @@ -240,6 +246,7 @@ open Finsupp -- Conceptually, it would be nice to construct this via "transport of enrichment", -- using the fact that `ModuleCat.Free R : Type ⥤ ModuleCat R` and `ModuleCat.forget` are both lax -- monoidal. This still seems difficult, so we just do it by hand. +set_option backward.isDefEq.respectTransparency.types false in instance categoryFree : Category (Free R C) where Hom := fun X Y : C => (X ⟶ Y) →₀ R id := fun X : C => Finsupp.single (𝟙 X) 1 @@ -253,6 +260,7 @@ namespace Free section +set_option backward.isDefEq.respectTransparency.types false in instance : Preadditive (Free R C) where homGroup _ _ := Finsupp.instAddCommGroup add_comp X Y Z f f' g := by @@ -264,6 +272,7 @@ instance : Preadditive (Free R C) where congr; ext r h rw [Finsupp.sum_add_index'] <;> · simp [mul_add] +set_option backward.isDefEq.respectTransparency.types false in instance : Linear R (Free R C) where homModule _ _ := Finsupp.module _ R smul_comp X Y Z r f g := by @@ -337,6 +346,7 @@ def lift (F : C ⥤ D) : Free R C ⥤ D where rw [single_comp_single _ _ f' g' r s] simp [mul_comm r s, mul_smul] +set_option backward.isDefEq.respectTransparency.types false in theorem lift_map_single (F : C ⥤ D) {X Y : C} (f : X ⟶ Y) (r : R) : (lift R F).map (single f r) = r • F.map f := by simp @@ -354,6 +364,7 @@ instance lift_linear (F : C ⥤ D) : (lift R F).Linear R where dsimp rw [Finsupp.sum_smul_index] <;> simp [Finsupp.smul_sum, mul_smul] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The embedding into the `R`-linear completion, followed by the lift, is isomorphic to the original functor. diff --git a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean index bdafae24b18577..ecd029ee9db7e0 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean @@ -471,6 +471,7 @@ instance mulAction : MulAction S <| (restrictScalars f).obj (of _ S) →ₗ[R] M one_smul := fun g => LinearMap.ext fun s : S => by simp mul_smul := fun (s t : S) g => LinearMap.ext fun x : S => by simp [mul_assoc] } +set_option backward.isDefEq.respectTransparency.types false in instance distribMulAction : DistribMulAction S <| (restrictScalars f).obj (of _ S) →ₗ[R] M := { CoextendScalars.mulAction f _ with smul_add := fun s g h => LinearMap.ext fun _ : S => by simp @@ -497,6 +498,7 @@ This is an implementation detail: use `(coextendScalars f).obj` instead. def obj' : ModuleCat S := of _ ((restrictScalars f).obj (of _ S) →ₗ[R] M) +set_option backward.isDefEq.respectTransparency.types false in /-- If `M, M'` are `R`-modules, then any `R`-linear map `g : M ⟶ M'` induces an `S`-linear map `(S →ₗ[R] M) ⟶ (S →ₗ[R] M')` defined by `h ↦ g ∘ h` -/ @[simps!] @@ -626,8 +628,7 @@ protected noncomputable def unit' : 𝟭 (ModuleCat S) ⟶ restrictScalars f ⋙ naturality Y Y' g := hom_ext <| LinearMap.ext fun y : Y => CoextendScalars.ext <| LinearMap.ext fun s : S => by -- Porting note (https://github.com/leanprover-community/mathlib4/issues/10745): previously simp [CoextendScalars.map_apply] - simp only [ModuleCat.hom_comp, Functor.id_map, Functor.id_obj, - Functor.comp_map] + simp only [Functor.id_map, Functor.id_obj, Functor.comp_map] change s • (g y) = g (s • y) rw [map_smul] @@ -986,8 +987,8 @@ noncomputable def extendScalarsComp : ((extendRestrictScalarsAdj f₁₂).comp (extendRestrictScalarsAdj f₂₃)) (extendRestrictScalarsAdj (f₂₃.comp f₁₂))).symm (restrictScalarsComp f₁₂ f₂₃).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma homEquiv_extendScalarsComp (M : ModuleCat R₁) : (extendRestrictScalarsAdj (f₂₃.comp f₁₂)).homEquiv _ _ ((extendScalarsComp f₁₂ f₂₃).hom.app M) = @@ -995,8 +996,8 @@ lemma homEquiv_extendScalarsComp (M : ModuleCat R₁) : (restrictScalars f₁₂).map ((extendRestrictScalarsAdj f₂₃).unit.app _) ≫ (restrictScalarsComp f₁₂ f₂₃).inv.app _ := by dsimp [extendScalarsComp, conjugateIsoEquiv, conjugateEquiv] - simp only [Category.assoc, Category.id_comp, Category.comp_id, - Adjunction.comp_unit_app, Adjunction.homEquiv_unit, + simp only [Functor.comp_obj, Category.assoc, Category.id_comp, + Category.comp_id, Adjunction.comp_unit_app, Adjunction.homEquiv_unit, Functor.map_comp, Adjunction.unit_naturality_assoc, Adjunction.right_triangle_components] rfl @@ -1053,6 +1054,7 @@ lemma extendScalars_id_comp : erw [extendScalarsId_hom_app_one_tmul] rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma extendScalars_comp_id : (extendScalarsComp f₁₂ (RingHom.id R₂)).hom ≫ Functor.whiskerLeft _ (extendScalarsId R₂).hom ≫ diff --git a/Mathlib/Algebra/Category/ModuleCat/Descent.lean b/Mathlib/Algebra/Category/ModuleCat/Descent.lean index f5bb399eb354fd..d8fff96c019e2e 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Descent.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Descent.lean @@ -55,7 +55,7 @@ lemma ModuleCat.reflectsIsomorphisms_extendScalars_of_faithfullyFlat rwa [Module.FaithfullyFlat.lTensor_bijective_iff_bijective] at h /-- Extension of scalars by a faithfully flat ring map is comonadic. -/ -@[implicit_reducible] +@[instance_reducible] def comonadicExtendScalars (hf : f.FaithfullyFlat) : ComonadicLeftAdjoint (extendScalars f) := by have := preservesFiniteLimits_extendScalars_of_flat hf.flat diff --git a/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean index af3967d4d00478..5679de7bae1a05 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Differentials/Basic.lean @@ -73,6 +73,7 @@ def d (b : B) : M := @[simp] lemma d_add (b b' : B) : D.d (b + b') = D.d b + D.d b' := by simp [d] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma d_mul (b b' : B) : D.d (b * b') = b • D.d b' + b' • D.d b := by simp [d] diff --git a/Mathlib/Algebra/Category/ModuleCat/Differentials/Presheaf.lean b/Mathlib/Algebra/Category/ModuleCat/Differentials/Presheaf.lean index 381db8f0797c9f..63b60eb1d85684 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Differentials/Presheaf.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Differentials/Presheaf.lean @@ -138,6 +138,7 @@ lemma d_app (d : M.Derivation' φ') {X : Dᵒᵖ} (a : S'.obj X) : d.d (φ'.app X a) = 0 := Derivation.d_app d _ +set_option backward.isDefEq.respectTransparency.types false in /-- The derivation relative to the morphism of commutative rings `φ'.app X` induced by a derivation relative to a morphism of presheaves of commutative rings. -/ noncomputable def app (d : M.Derivation' φ') (X : Dᵒᵖ) : (M.obj X).Derivation (φ'.app X) := diff --git a/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean b/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean index a9a88bee1e05ce..40377fdd233362 100644 --- a/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean +++ b/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean @@ -51,7 +51,7 @@ theorem epi_iff_surjective : Epi f ↔ Function.Surjective f := by rw [epi_iff_range_eq_top, LinearMap.range_eq_top] /-- If the zero morphism is an epi then the codomain is trivial. -/ -@[implicit_reducible] +@[instance_reducible] def uniqueOfEpiZero (X) [h : Epi (0 : X ⟶ of R M)] : Unique M := uniqueOfSurjectiveZero X ((ModuleCat.epi_iff_surjective _).mp h) diff --git a/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean b/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean index 0f8b07457d348c..a2f9f7c7512ce0 100644 --- a/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean +++ b/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean @@ -69,7 +69,6 @@ def colimitSMulAux (r : R) (x : Σ j, F.obj j) : M F := M.mk F ⟨x.1, r • x.2⟩ set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem colimitSMulAux_eq_of_rel (r : R) (x y : Σ j, F.obj j) (h : Types.FilteredColimit.Rel (F ⋙ forget (ModuleCat R)) x y) : colimitSMulAux F r x = colimitSMulAux F r y := by @@ -150,6 +149,7 @@ def coconeMorphism (j : J) : F.obj j ⟶ colimit F := map_smul' := by solve_by_elim } /-- The cocone over the proposed colimit module. -/ +@[implicit_reducible] def colimitCocone : Cocone F where pt := colimit F ι := diff --git a/Mathlib/Algebra/Category/ModuleCat/Images.lean b/Mathlib/Algebra/Category/ModuleCat/Images.lean index 0377c499e94cd6..47574ab1b4dab1 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Images.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Images.lean @@ -53,6 +53,7 @@ attribute [local simp] image.fac variable {f} +set_option backward.isDefEq.respectTransparency.types false in /-- The universal property for the image factorisation -/ noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I := ofHom @@ -72,6 +73,7 @@ noncomputable def image.lift (F' : MonoFactorisation f) : image f ⟶ F'.I := simp_rw [F'.fac, (Classical.indefiniteDescription (fun z => f z = _) _).2] rfl } +set_option backward.isDefEq.respectTransparency.types false in theorem image.lift_fac (F' : MonoFactorisation f) : image.lift F' ≫ F'.m = image.ι f := by ext x change (F'.e ≫ F'.m) _ = _ diff --git a/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean b/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean index 61d9e40861ab29..ca5cc293feead0 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Monoidal/Adjunction.lean @@ -40,6 +40,7 @@ lemma extendsScalars_map_rightUnitor_inv_one_tmul (M : ModuleCat R) (m : M) : letI := f.toAlgebra (extendScalars f).map (ρ_ M).inv ((1 : S) ⊗ₜ[R] m) = (1 : S) ⊗ₜ[R] (m ⊗ₜ 1) := rfl +set_option backward.isDefEq.respectTransparency.types false in open ModuleCat.MonoidalCategory in noncomputable instance : (extendScalars f).Monoidal := letI : Algebra R S := f.toAlgebra @@ -75,16 +76,19 @@ noncomputable instance : (extendScalars f).Monoidal := rw [one_smul] rfl)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma extendScalars_ε : letI := f.toAlgebra dsimp% ε (extendScalars f) = (AlgebraTensorModule.rid R S S).toModuleIso.inv := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma extendScalars_η : letI := f.toAlgebra dsimp% η (extendScalars f) = (AlgebraTensorModule.rid R S S).toModuleIso.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma extendScalars_μ (M₁ M₂ : ModuleCat R) : letI := f.toAlgebra @@ -92,6 +96,7 @@ lemma extendScalars_μ (M₁ M₂ : ModuleCat R) : (AlgebraTensorModule.distribBaseChange R S M₁ M₂).toModuleIso.inv := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma extendScalars_δ (M₁ M₂ : ModuleCat R) : letI := f.toAlgebra @@ -99,15 +104,18 @@ lemma extendScalars_δ (M₁ M₂ : ModuleCat R) : (AlgebraTensorModule.distribBaseChange R S M₁ M₂).toModuleIso.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma extendScalars_δ_tmul (M₁ M₂ : ModuleCat R) (m₁ : M₁) (m₂ : M₂) : letI := f.toAlgebra dsimp% δ (extendScalars f) M₁ M₂ (((1 : S) ⊗ₜ[R] (m₁ ⊗ₜ[R] m₂) :)) = ((1 : S) ⊗ₜ[R] m₁) ⊗ₜ[S] ((1 : S) ⊗ₜ[R] m₂) := rfl +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance : (restrictScalars f).LaxMonoidal := (extendRestrictScalarsAdj f).rightAdjointLaxMonoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrictScalars_η (r : R) : ε (restrictScalars f) r = f r := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean index f0044570af4178..fa7349e109397f 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf.lean @@ -213,6 +213,7 @@ lemma ofPresheaf_presheaf : (ofPresheaf M map_smul).presheaf = M := rfl end +set_option backward.isDefEq.respectTransparency.types false in /-- The morphism of presheaves of modules `M₁ ⟶ M₂` given by a morphism of abelian presheaves `M₁.presheaf ⟶ M₂.presheaf` which satisfy a suitable linearity condition. -/ @@ -338,6 +339,7 @@ lemma sections_ext {M : PresheafOfModules.{v} R} (s t : M.sections) (h : ∀ (X : Cᵒᵖ), s.val X = t.val X) : s = t := Subtype.ext (by ext; apply h) +set_option backward.isDefEq.respectTransparency.types false in /-- The map `M.sections → N.sections` induced by a morphisms `M ⟶ N` of presheaves of modules. -/ @[simps!] def sectionsMap {M N : PresheafOfModules.{v} R} (f : M ⟶ N) (s : M.sections) : N.sections := @@ -418,6 +420,7 @@ noncomputable def forgetToPresheafModuleCatObjMap {Y Z : Cᵒᵖ} (f : Y ⟶ Z) lemma forgetToPresheafModuleCatObjMap_apply {Y Z : Cᵒᵖ} (f : Y ⟶ Z) (m : M.obj Y) : (forgetToPresheafModuleCatObjMap X hX M f).hom m = M.map f m := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Implementation of the functor `PresheafOfModules R ⥤ Cᵒᵖ ⥤ ModuleCat (R.obj X)` when `X` is initial. @@ -457,6 +460,7 @@ noncomputable def forgetToPresheafModuleCatMap ext x exact naturality_apply f g x +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from presheaves of modules over a presheaf of rings `R` to presheaves of `R(X)`-modules where `X` is an initial object. diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/ColimitFunctor.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/ColimitFunctor.lean index 9f4ea88b2bab53..226ca278563546 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/ColimitFunctor.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/ColimitFunctor.lean @@ -52,7 +52,7 @@ noncomputable def constFunctor : ModuleCat cR.pt ⥤ PresheafOfModules.{w} R whe { obj X := (ModuleCat.restrictScalars (cR.ι.app X).hom).obj M map {X Y} f := (ModuleCat.restrictScalarsComp' _ _ _ - (by ext; dsimp; rw [← Cocone.w cR f]; dsimp; rfl)).hom.app _ } + (by ext; dsimp; rw [← Cocone.w cR f]; dsimp)).hom.app _ } map φ := { app X := (ModuleCat.restrictScalars (cR.ι.app X).hom).map φ } section @@ -221,6 +221,7 @@ lemma homEquiv'_symm_apply {N : ModuleCat.{w} cR.pt} (homEquiv' hcR hcM).symm β (cM.ι.app X x) = β.app X x := ConcreteCategory.congr_hom (hcM.ι_app_homEquiv_symm β X) x +set_option backward.isDefEq.respectTransparency.types false in lemma map_smul_homEquiv'_iff {N : ModuleCat.{w} cR.pt} (α : ModuleColimit hcR hcM →+ N) : dsimp% (∀ (U : Cᵒᵖ) (r : R.obj U) (m : M.obj U), (homEquiv' hcR hcM α).app U (r • m) = @@ -236,6 +237,7 @@ lemma map_smul_homEquiv'_iff {N : ModuleCat.{w} cR.pt} congr 1 exact (smul_eq ..).symm +set_option backward.isDefEq.respectTransparency.types false in /-- This is the universal property of `PresheafOfModules.ModuleColimit` as a module. See also `PresheafOfModules.colimitAdjunction`. -/ noncomputable def homEquiv {N : ModuleCat.{w} cR.pt} : @@ -262,16 +264,19 @@ noncomputable def homEquiv {N : ModuleCat.{w} cR.pt} : ((homEquiv' hcR hcM).map_add ((forget₂ _ AddCommGrpCat).map φ₁).hom ((forget₂ _ AddCommGrpCat).map φ₂).hom) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma homEquiv_app_apply {N : ModuleCat.{w} cR.pt} (α : ModuleCat.of cR.pt (ModuleColimit hcR hcM) ⟶ N) {X : Cᵒᵖ} (x : M.obj X) : dsimp% (homEquiv hcR hcM α).app X x = α (cM.ι.app X x) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma homEquiv_naturality_right {N N' : ModuleCat.{w} cR.pt} (φ : ModuleCat.of cR.pt (ModuleColimit hcR hcM) ⟶ N) (g : N ⟶ N') : homEquiv hcR hcM (φ ≫ g) = homEquiv hcR hcM φ ≫ (constFunctor cR).map g := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma homEquiv_symm_apply {N : ModuleCat.{w} cR.pt} (β : M ⟶ (constFunctor cR).obj N) {X : Cᵒᵖ} (x : M.obj X) : @@ -283,6 +288,7 @@ section variable {M' : PresheafOfModules.{w} R} {cM' : Cocone M'.presheaf} (hcM' : IsColimit cM') +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The linear map between the colimit modules induced by a morphism of modules. -/ noncomputable def map (f : M ⟶ M') : @@ -299,17 +305,20 @@ noncomputable def map (f : M ⟶ M') : erw [h₁, h₂, ModuleColimit.smul_eq, ← (f.app U).hom.map_smul] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma map_apply (f : M ⟶ M') {U : Cᵒᵖ} (m : M.obj U) : dsimp% map hcR hcM hcM' f (ιM m) = ιM (f.app _ m) := ConcreteCategory.congr_hom (hcM.fac ((Cocone.precompose ((toPresheaf _).map f)).obj cM') U) m +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma map_id : map hcR hcM hcM (𝟙 M) = .id := by ext m obtain ⟨U, m, rfl⟩ := ιM_jointly_surjective m simp +set_option backward.isDefEq.respectTransparency.types false in lemma comp_map (f : M ⟶ M') {M'' : PresheafOfModules.{w} R} {cM'' : Cocone M''.presheaf} @@ -321,6 +330,7 @@ lemma comp_map end +set_option backward.isDefEq.respectTransparency.types false in lemma homEquiv_naturality_left {M' : PresheafOfModules.{w} R} {cM' : Cocone M'.presheaf} (hcM' : IsColimit cM') {N : ModuleCat.{w} cR.pt} (φ' : ModuleCat.of cR.pt (ModuleColimit hcR hcM') ⟶ N) @@ -333,6 +343,7 @@ lemma homEquiv_naturality_left {M' : PresheafOfModules.{w} R} {cM' : Cocone M'.p apply congr_arg exact map_apply hcR hcM hcM' f m +set_option backward.isDefEq.respectTransparency.types false in lemma homEquiv_naturality_left_symm {M' : PresheafOfModules.{w} R} {cM' : Cocone M'.presheaf} (hcM' : IsColimit cM') {N : ModuleCat.{w} cR.pt} (f : M ⟶ M') (g : M' ⟶ (constFunctor cR).obj N) : @@ -346,6 +357,7 @@ end ModuleColimit end +set_option backward.isDefEq.respectTransparency.types false in /-- The colimit module functor from the category of presheaves of modules over a presheaf of rings `R` on a cofiltered category to the category of modules over a colimit of `R`. -/ @@ -354,6 +366,7 @@ noncomputable def colimitFunctor : PresheafOfModules.{w} R ⥤ ModuleCat.{w} cR. map f := ModuleCat.ofHom (ModuleColimit.map _ _ _ f) map_comp f g := by ext : 1; exact (ModuleColimit.comp_map ..).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Given a presheaf of rings `R` on a cofiltered category, this is the adjunction between `colimitFunctor : PresheafOfModules R ⥤ ModuleCat cR.pt` and the constant functor. -/ @@ -364,6 +377,7 @@ noncomputable def colimitAdjunction : homEquiv_naturality_left_symm _ _ := ModuleColimit.homEquiv_naturality_left_symm _ _ _ _ _ homEquiv_naturality_right _ _ := ModuleColimit.homEquiv_naturality_right _ _ _ _ } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma colimitAdjunction_homEquiv (F : PresheafOfModules R) (G : ModuleCat cR.pt) : @@ -372,6 +386,7 @@ lemma colimitAdjunction_homEquiv (colimit.isColimit F.presheaf)).toEquiv := by simp [colimitAdjunction] +set_option backward.isDefEq.respectTransparency.types false in open ModuleColimit in lemma colimitAdjunction_homEquiv_symm_apply {F : PresheafOfModules R} {G : ModuleCat cR.pt} diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Free.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Free.lean index 9f3b41a0720b39..e31937cdc05b32 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Free.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Free.lean @@ -35,6 +35,7 @@ namespace PresheafOfModules variable {C : Type u₁} [Category.{v₁} C] (R : Cᵒᵖ ⥤ RingCat.{u}) +set_option backward.isDefEq.respectTransparency.types false in variable {R} in /-- Given a presheaf of types `F : Cᵒᵖ ⥤ Type u`, this is the presheaf of modules over `R` which sends `X : Cᵒᵖ` to the free `R.obj X`-module on `F.obj X`. -/ @@ -44,6 +45,7 @@ noncomputable def freeObj (F : Cᵒᵖ ⥤ Type u) : PresheafOfModules.{u} R whe map {X Y} f := ModuleCat.freeDesc (↾fun x ↦ ModuleCat.freeMk (F.map f x)) map_id := by aesop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The free presheaf of modules functor `(Cᵒᵖ ⥤ Type u) ⥤ PresheafOfModules.{u} R`. -/ @[simps] @@ -57,6 +59,7 @@ variable {R} variable {F : Cᵒᵖ ⥤ Type u} {G : PresheafOfModules.{u} R} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The morphism of presheaves of modules `freeObj F ⟶ G` corresponding to a morphism `F ⟶ G.presheaf ⋙ forget _` of presheaves of types. -/ @@ -105,11 +108,13 @@ noncomputable def freeAdjunction : free_hom_ext (by ext; simp [freeHomEquiv, toPresheaf]) homEquiv_naturality_right := fun {F G₁ G₂} f g ↦ rfl } +set_option backward.isDefEq.respectTransparency.types false in variable (F G) in @[simp] lemma freeAdjunction_homEquiv : (freeAdjunction R).homEquiv F G = freeHomEquiv := by simp [freeAdjunction, Adjunction.mkOfHomEquiv_homEquiv] +set_option backward.isDefEq.respectTransparency.types false in variable (R F) in @[simp] lemma freeAdjunction_unit_app : diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Generator.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Generator.lean index 993e866bad7cae..9f993d95a9fa0d 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Generator.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Generator.lean @@ -168,6 +168,7 @@ lemma ι_fromFreeYonedaCoproduct_apply (m : M.Elements) (X : Cᵒᵖ) (x : m.fre ConcreteCategory.congr_hom ((evaluation R X ⋙ forget _).congr_map (M.ι_fromFreeYonedaCoproduct m)) x +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma fromFreeYonedaCoproduct_app_mk (m : M.Elements) : M.fromFreeYonedaCoproduct.app _ (M.freeYonedaCoproductMk m) = m.2 := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Monoidal.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Monoidal.lean index 9866fbafee0ccc..e7f98beb3789c7 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Monoidal.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Monoidal.lean @@ -101,7 +101,6 @@ end Monoidal open Monoidal -set_option backward.isDefEq.respectTransparency false in open ModuleCat.MonoidalCategory in noncomputable instance monoidalCategoryStruct : MonoidalCategoryStruct (PresheafOfModules.{u} (R ⋙ forget₂ _ _)) where diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean index 1b537629bacb2a..7f42f32372baff 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Pushforward.lean @@ -108,6 +108,7 @@ lemma pushforward_obj_map_apply (M : PresheafOfModules.{v} R) {X Y : Cᵒᵖ} (f (m : (ModuleCat.restrictScalars (φ.app X).hom).obj (M.obj (Opposite.op (F.obj X.unop)))) : (((pushforward φ).obj M).map f).hom m = M.map (F.map f.unop).op m := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `@[simp]`-normal form of `pushforward_obj_map_apply`. -/ @[simp] lemma pushforward_obj_map_apply' (M : PresheafOfModules.{v} R) {X Y : Cᵒᵖ} (f : X ⟶ Y) @@ -121,6 +122,7 @@ lemma pushforward_map_app_apply {M N : PresheafOfModules.{v} R} (α : M ⟶ N) ( (m : (ModuleCat.restrictScalars (φ.app X).hom).obj (M.obj (Opposite.op (F.obj X.unop)))) : (((pushforward φ).map α).app X).hom m = α.app (Opposite.op (F.obj X.unop)) m := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `@[simp]`-normal form of `pushforward_map_app_apply`. -/ @[simp] lemma pushforward_map_app_apply' {M N : PresheafOfModules.{v} R} (α : M ⟶ N) (X : Cᵒᵖ) diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafification.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafification.lean index 1be45f473ed2fc..581dc44dd399cb 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafification.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafification.lean @@ -106,6 +106,7 @@ lemma toPresheaf_map_sheafificationHomEquiv rw [toPresheaf_map_sheafificationHomEquiv_def, Adjunction.homEquiv_unit] dsimp +set_option backward.isDefEq.respectTransparency.types false in lemma toSheaf_map_sheafificationHomEquiv_symm {P : PresheafOfModules.{v} R₀} {F : SheafOfModules.{v} R} (g : P ⟶ (restrictScalars α).obj ((SheafOfModules.forget _).obj F)) : @@ -118,7 +119,6 @@ lemma toSheaf_map_sheafificationHomEquiv_symm rfl set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given a locally bijective morphism `α : R₀ ⟶ R.val` where `R₀` is a presheaf of rings and `R` a sheaf of rings, this is the adjunction `sheafification.{v} α ⊣ SheafOfModules.forget R ⋙ restrictScalars α`. -/ diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean index 5319e8a1fa916a..6e1d44b598d08c 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean @@ -57,6 +57,7 @@ variable {R₀ R : Cᵒᵖ ⥤ RingCat.{u}} (α : R₀ ⟶ R) [Presheaf.IsLocall (r₀ : FamilyOfElements (R₀ ⋙ forget _) P) (m₀ : FamilyOfElements (M₀.presheaf ⋙ forget _) P) include hA +set_option backward.isDefEq.respectTransparency.types false in lemma _root_.PresheafOfModules.Sheafify.app_eq_of_isLocallyInjective {Y : C} (r₀ r₀' : R₀.obj (Opposite.op Y)) (m₀ m₀' : M₀.obj (Opposite.op Y)) @@ -149,6 +150,7 @@ structure SMulCandidate where h ⦃Y : Cᵒᵖ⦄ (f : X ⟶ Y) (r₀ : R₀.obj Y) (hr₀ : α.app Y r₀ = R.obj.map f r) (m₀ : M₀.obj Y) (hm₀ : φ.app Y m₀ = A.obj.map f m) : A.obj.map f x = φ.app Y (r₀ • m₀) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Constructor for `SMulCandidate`. -/ def SMulCandidate.mk' (S : Sieve X.unop) (hS : S ∈ J X.unop) @@ -170,13 +172,13 @@ def SMulCandidate.mk' (S : Sieve X.unop) (hS : S ∈ J X.unop) · rw [← RingCat.comp_apply, NatTrans.naturality, RingCat.comp_apply, ha₀] apply (hr₀ _ hg).symm.trans simp - rfl · erw [NatTrans.naturality_apply φ, hb₀] apply (hm₀ _ hg).symm.trans dsimp rw [Functor.map_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in instance : Nonempty (SMulCandidate α φ r m) := ⟨by let S := (Presheaf.imageSieve α r ⊓ Presheaf.imageSieve φ m) have hS : S ∈ J _ := by @@ -224,6 +226,7 @@ lemma map_smul_eq {Y : Cᵒᵖ} (f : X ⟶ Y) (r₀ : R₀.obj Y) (hr₀ : α.ap A.obj.map f (smul α φ r m) = φ.app Y (r₀ • m₀) := (smulCandidate α φ r m).h f r₀ hr₀ m₀ hm₀ +set_option backward.isDefEq.respectTransparency.types false in protected lemma one_smul : smul α φ 1 m = m := by apply A.isSeparated _ _ (Presheaf.imageSieve_mem J φ m) rintro Y f ⟨m₀, hm₀⟩ @@ -290,7 +293,7 @@ variable (X) /-- The module structure on the sections of the sheafification of the underlying presheaf of abelian groups of a presheaf of modules. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def module : Module (R.obj.obj X) (A.obj.obj X) where smul r m := smul α φ r m one_smul := Sheafify.one_smul α φ @@ -335,6 +338,7 @@ noncomputable def toSheafify : M₀ ⟶ (restrictScalars α).obj (sheafify α φ lemma toSheafify_app_apply (X : Cᵒᵖ) (x : M₀.obj X) : ((toSheafify α φ).app X).hom x = φ.app X x := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `@[simp]`-normal form of `toSheafify_app_apply`. -/ @[simp] lemma toSheafify_app_apply' (X : Cᵒᵖ) (x : M₀.obj X) : diff --git a/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean b/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean index 8ceec875a545f7..45e18839de5af7 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean @@ -32,6 +32,7 @@ variable [Small.{v} R] {R' : Type u'} [CommRing R'] [Small.{v'} R'] (e : R ≃+* variable {M : ModuleCat.{v} R} {N : ModuleCat.{v'} R'} +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] RingHomInvPair.of_ringEquiv in lemma hasProjectiveDimensionLE_of_semiLinearEquiv (e' : M ≃ₛₗ[RingHomClass.toRingHom e] N) (n : ℕ) [HasProjectiveDimensionLE M n] : HasProjectiveDimensionLE N n := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/ChangeOfRings.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/ChangeOfRings.lean index c293c026fc508f..2fc74e201285de 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/ChangeOfRings.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/ChangeOfRings.lean @@ -49,6 +49,7 @@ namespace PresheafOfModules variable {R R' : Cᵒᵖ ⥤ RingCat.{u}} (α : R ⟶ R') {M₁ M₂ : PresheafOfModules.{v} R'} +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `PresheafOfModules.restrictScalars α` induces bijections on morphisms if `α` is locally surjective and the target presheaf is a sheaf. -/ noncomputable def restrictHomEquivOfIsLocallySurjective diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean index 4f00bd861e4819..ff886ef04601bc 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Free.lean @@ -70,6 +70,7 @@ lemma freeHomEquiv_comp_apply {M N : SheafOfModules.{u} R} {I : Type u} (f : free I ⟶ M) (p : M ⟶ N) (i : I) : N.freeHomEquiv (f ≫ p) i = sectionsMap p (M.freeHomEquiv f i) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma freeHomEquiv_symm_comp {M N : SheafOfModules.{u} R} {I : Type u} (s : I → M.sections) (p : M ⟶ N) : M.freeHomEquiv.symm s ≫ p = N.freeHomEquiv.symm (fun i ↦ sectionsMap p (s i)) := @@ -84,6 +85,7 @@ lemma freeHomEquiv_apply {M : SheafOfModules.{u} R} {I : Type u} freeHomEquiv M f i = sectionsMap f (freeSection i) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma unitHomEquiv_symm_freeHomEquiv_apply {I : Type u} {M : SheafOfModules.{u} R} (f : free I ⟶ M) (i : I) : M.unitHomEquiv.symm (M.freeHomEquiv f i) = ιFree i ≫ f := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean index 34a404e16be455..168efa53e8b32d 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PullbackFree.lean @@ -68,6 +68,7 @@ noncomputable def unitToPushforwardObjUnit : unit S ⟶ (pushforward.{u} φ).obj lemma unitToPushforwardObjUnit_val_app_apply {X : Cᵒᵖ} (a : S.obj.obj X) : (unitToPushforwardObjUnit φ).val.app X a = φ.hom.app X a := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma pushforwardSections_unitHomEquiv {M : SheafOfModules.{u} R} (f : unit R ⟶ M) : pushforwardSections φ (M.unitHomEquiv f) = diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean index e0d9552472687d..761ec32d8ac4be 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/PushforwardContinuous.lean @@ -221,6 +221,7 @@ lemma pushforwardNatTrans_comp (α : F ⟶ G) (β : G ⟶ H) lemma pushforwardNatTrans_app_val_app_apply (α : F ⟶ G) (X U x) : ((pushforwardNatTrans φ α).app X).val.app U x = X.val.map (α.app U.unop).op x := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural isomorphism gives a natural isomorphism between the pushforward functors. -/ @[simps] @@ -303,6 +304,7 @@ lemma pushforwardPushforwardAdj_counit_app_val_app (M U x) : ((pushforwardPushforwardAdj adj φ ψ H₁ H₂).counit.app M).val.app U x = M.val.map (adj.unit.app U.unop).op x := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance isLeftAdjoint_pushforward_of_isIso [F.IsCocontinuous J K] [IsIso φ] [F.IsLeftAdjoint] : (pushforward.{u} φ).IsLeftAdjoint := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean index cecd0a5950edee..3cd448913291b4 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Quasicoherent.lean @@ -136,6 +136,7 @@ noncomputable def Presentation.ofIsIso {M N : SheafOfModules.{u} R} (f : M ⟶ N @[deprecated (since := "2026-04-15")] alias Presentation.of_isIso := Presentation.ofIsIso +set_option backward.isDefEq.respectTransparency.types false in instance {M N : SheafOfModules.{u} R} (f : M ⟶ N) [IsIso f] (σ : M.Presentation) [σ.IsFinite] : (σ.ofIsIso f).IsFinite where isFiniteType_generators := inferInstanceAs (σ.generators.ofEpi _).IsFiniteType @@ -170,6 +171,7 @@ theorem Presentation.mapRelations_mapGenerators : simp only [mapRelations, GeneratingSections.mapFreeHom, Category.assoc, Iso.inv_hom_id_assoc, ← Functor.map_comp, kernel.condition, Functor.map_zero, comp_zero] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Let `F` be a functor from sheaf of `R`-module to sheaf of `S`-module, if `F` preserves colimits and `F.obj (unit R) ≅ unit S`, given a `P : Presentation M`, then we will get a @@ -398,6 +400,7 @@ instance : (isQuasicoherent R).IsClosedUnderIsomorphisms where intro ⟨⟨q⟩⟩ exact ⟨⟨q.ofIsIso e.hom⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {M N : SheafOfModules.{u} R} (f : M ⟶ N) [IsIso f] (σ : M.QuasicoherentData) [σ.IsFinitePresentation] : (σ.ofIsIso f).IsFinitePresentation where diff --git a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean index e1dc19ba163ba2..aa61c5a60d282a 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean @@ -36,7 +36,6 @@ variable {C : Type*} [SmallCategory C] [IsFiltered C] (R : C ⥤ RingCat) (M : C [∀ i, Module (R.obj i) (M.obj i)] (H : ∀ {i j} (f : i ⟶ j) r m, M.map f (r • m) = R.map f r • M.map f m) -set_option backward.isDefEq.respectTransparency false in /-- (Implementation). The scalar multiplication function on `ColimitType`. -/ protected noncomputable def colimit.smul (r : (R ⋙ forget _).ColimitType) (m : (M ⋙ forget _).ColimitType) : diff --git a/Mathlib/Algebra/Category/ModuleCat/Ulift.lean b/Mathlib/Algebra/Category/ModuleCat/Ulift.lean index d8ede937f0c089..464a9101e246a1 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Ulift.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Ulift.lean @@ -47,6 +47,9 @@ def fullyFaithfulUliftFunctor : (uliftFunctor R).FullyFaithful where preimage f := ModuleCat.ofHom (ULift.moduleEquiv.toLinearMap.comp (f.hom.comp ULift.moduleEquiv.symm.toLinearMap)) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The `ULift` functor on `ModuleCat` is compatible with the one defined on categories of types. -/ @[simps! +dsimpLhs] def uliftFunctorForgetIso : diff --git a/Mathlib/Algebra/Category/MonCat/FilteredColimits.lean b/Mathlib/Algebra/Category/MonCat/FilteredColimits.lean index 7bd13a893314d7..7283057c35f46f 100644 --- a/Mathlib/Algebra/Category/MonCat/FilteredColimits.lean +++ b/Mathlib/Algebra/Category/MonCat/FilteredColimits.lean @@ -124,7 +124,6 @@ theorem colimitMulAux_eq_of_rel_left {x x' y : Σ j, F.obj j} ConcreteCategory.comp_apply, hfg] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Multiplication in the colimit is well-defined in the right argument. -/ @[to_additive /-- Addition in the colimit is well-defined in the right argument. -/] theorem colimitMulAux_eq_of_rel_right {x y y' : Σ j, F.obj j} @@ -258,6 +257,7 @@ noncomputable def colimitDesc (t : Cocone F) : colimit.{v, u} F ⟶ t.pt := rw [colimit_mul_mk_eq F ⟨i, x⟩ ⟨j, y⟩ (max' i j) (IsFiltered.leftToMax i j) (IsFiltered.rightToMax i j)] dsimp + set_option backward.isDefEq.respectTransparency true in rw [map_mul, t.w_apply, t.w_apply] } /-- The proposed colimit cocone is a colimit in `MonCat`. -/ diff --git a/Mathlib/Algebra/Category/MonCat/Limits.lean b/Mathlib/Algebra/Category/MonCat/Limits.lean index a567874386d21b..626bd86d5d1072 100644 --- a/Mathlib/Algebra/Category/MonCat/Limits.lean +++ b/Mathlib/Algebra/Category/MonCat/Limits.lean @@ -38,7 +38,6 @@ variable {J : Type v} [Category.{w} J] (F : J ⥤ MonCat.{u}) instance monoidObj (j : J) : Monoid (F.obj j) := inferInstanceAs <| Monoid (F.obj j) -set_option backward.isDefEq.respectTransparency false in /-- The flat sections of a functor into `MonCat` form a submonoid of all sections. -/ @[to_additive /-- The flat sections of a functor into `AddMonCat` form an additive submonoid of all sections. -/] diff --git a/Mathlib/Algebra/Category/Ring/Adjunctions.lean b/Mathlib/Algebra/Category/Ring/Adjunctions.lean index 5011c10efd4cc9..c7edd66e6cf6ed 100644 --- a/Mathlib/Algebra/Category/Ring/Adjunctions.lean +++ b/Mathlib/Algebra/Category/Ring/Adjunctions.lean @@ -85,6 +85,7 @@ set_option backward.isDefEq.respectTransparency false in def coyonedaUnique {n : Type v} [Unique n] : coyoneda.obj (op n) ≅ 𝟭 CommRingCat.{max u v} := NatIso.ofComponents (fun X ↦ (RingEquiv.piUnique _).toCommRingCatIso) (fun f ↦ by ext; simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The monoid algebra functor `CommGrpCat ⥤ R-Alg` given by `G ↦ R[G]`. -/ @[simps] diff --git a/Mathlib/Algebra/Category/Ring/Constructions.lean b/Mathlib/Algebra/Category/Ring/Constructions.lean index ff793325838353..309ddebc076f41 100644 --- a/Mathlib/Algebra/Category/Ring/Constructions.lean +++ b/Mathlib/Algebra/Category/Ring/Constructions.lean @@ -408,11 +408,13 @@ def equalizerForkIsLimit : IsLimit (equalizerFork f g) := by ext x exact Subtype.ext <| RingHom.congr_fun (congrArg Hom.hom hm) x +set_option backward.isDefEq.respectTransparency.types false in instance : IsLocalHom (equalizerFork f g).ι.hom := inferInstanceAs <| IsLocalHom (f.hom.eqLocus g.hom).subtype open WalkingParallelPair WalkingParallelPairHom Opposite +set_option backward.isDefEq.respectTransparency.types false in instance equalizer_ι_isLocalHom (F : WalkingParallelPair ⥤ CommRingCat.{u}) : IsLocalHom (limit.π F WalkingParallelPair.zero).hom := by refine Limits.π_isLocalHom _ (limit.isLimit _) zero fun x hx i ↦ ?_ diff --git a/Mathlib/Algebra/Category/Ring/FinitePresentation.lean b/Mathlib/Algebra/Category/Ring/FinitePresentation.lean index dd6ca98e91939e..0df848395b8354 100644 --- a/Mathlib/Algebra/Category/Ring/FinitePresentation.lean +++ b/Mathlib/Algebra/Category/Ring/FinitePresentation.lean @@ -139,6 +139,7 @@ lemma RingHom.EssFiniteType.exists_eq_comp_ι_app_of_isColimit (hf : f.hom.Finit rw [c.w, hg'] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `S` is a finitely presented `R`-algebra, then `Hom_R(S, -)` preserves filtered colimits. -/ lemma CommRingCat.preservesColimit_coyoneda_of_finitePresentation diff --git a/Mathlib/Algebra/Category/Ring/Under/Basic.lean b/Mathlib/Algebra/Category/Ring/Under/Basic.lean index 02bc2f62ae8b53..378eac1234c29c 100644 --- a/Mathlib/Algebra/Category/Ring/Under/Basic.lean +++ b/Mathlib/Algebra/Category/Ring/Under/Basic.lean @@ -93,6 +93,7 @@ end AlgHom namespace AlgEquiv +set_option backward.isDefEq.respectTransparency.types false in /-- Make an isomorphism in `Under R` from an algebra isomorphism. -/ def toUnder {A B : Type u} [CommRing A] [CommRing B] [Algebra R A] [Algebra R B] (f : A ≃ₐ[R] B) : diff --git a/Mathlib/Algebra/Category/Ring/Under/Property.lean b/Mathlib/Algebra/Category/Ring/Under/Property.lean index 630f31d646a012..d58aa65795a2e8 100644 --- a/Mathlib/Algebra/Category/Ring/Under/Property.lean +++ b/Mathlib/Algebra/Category/Ring/Under/Property.lean @@ -34,6 +34,7 @@ variable {Q : ∀ {R S : Type u} [CommRing R] [CommRing S], (R →+* S) → Prop open MorphismProperty +set_option backward.isDefEq.respectTransparency.types false in lemma RingHom.HasFiniteProducts.isClosedUnderLimitsOfShape (hQi : RespectsIso Q) (hQp : HasFiniteProducts Q) (R : CommRingCat.{u}) : (toMorphismProperty Q).underObj (X := R).IsClosedUnderFiniteProducts := by @@ -47,6 +48,7 @@ lemma RingHom.HasFiniteProducts.isClosedUnderLimitsOfShape (hQi : RespectsIso Q) rw [underObj_iff, ← Under.w e.inv, (toMorphismProperty Q).cancel_right_of_respectsIso] exact hQp _ fun i ↦ hpres _ +set_option backward.isDefEq.respectTransparency.types false in lemma RingHom.HasEqualizers.isClosedUnderLimitsOfShape (hQi : RespectsIso Q) (hQe : HasEqualizers Q) (R : CommRingCat.{u}) : (toMorphismProperty Q).underObj (X := R).IsClosedUnderLimitsOfShape WalkingParallelPair := by @@ -67,7 +69,7 @@ lemma RingHom.HasEqualizers.isClosedUnderLimitsOfShape (hQi : RespectsIso Q) /-- If `Q` is stable under finite products, the inclusion from the subcategory of `Under R` defined by `Q` creates finite products. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def RingHom.HasFiniteProducts.createsFiniteProductsForget (hQi : RespectsIso Q) (hQp : HasFiniteProducts Q) (R : CommRingCat.{u}) : CreatesFiniteProducts (MorphismProperty.Under.forget (toMorphismProperty Q) ⊤ R) := by @@ -97,7 +99,7 @@ lemma RingHom.HasFiniteProducts.preservesFiniteProducts_pushout (hQi : RingHom.R /-- If `Q` is stable under equalizers, the inclusion from the subcategory of `Under R` defined by `Q` creates equalizers. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def RingHom.HasEqualizers.createsLimitsWalkingParallelPair (hQi : RespectsIso Q) (hQe : HasEqualizers Q) (R : CommRingCat.{u}) : CreatesLimitsOfShape WalkingParallelPair @@ -116,7 +118,7 @@ namespace CommRingCat /-- If `Q` is stable under finite products and equalizers, the inclusion from the subcategory of `Under R` defined by `Q` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Under.createsFiniteLimitsForget (hQi : RingHom.RespectsIso Q) (hQp : RingHom.HasFiniteProducts Q) (hQe : RingHom.HasEqualizers Q) (R : CommRingCat.{u}) : CreatesFiniteLimits (Under.forget (RingHom.toMorphismProperty Q) ⊤ R) := @@ -139,6 +141,7 @@ open RingHom variable {P} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma CommRingCat.preservesLimit_parallelPair_tensorProd_iff_tensorEqualizer_bijective {R S : CommRingCat.{u}} [Algebra R S] {A B : Under R} {f g : A ⟶ B} : diff --git a/Mathlib/Algebra/Central/Basic.lean b/Mathlib/Algebra/Central/Basic.lean index 932b5ef110a970..60593efe7a21d8 100644 --- a/Mathlib/Algebra/Central/Basic.lean +++ b/Mathlib/Algebra/Central/Basic.lean @@ -59,6 +59,7 @@ lemma baseField_essentially_unique obtain ⟨x', H⟩ := H exact ⟨x', (algebraMap K D).injective <| by simp [← H, algebraMap_eq_smul_one]⟩ +set_option backward.isDefEq.respectTransparency false in lemma of_algEquiv (e : D ≃ₐ[K] D') : IsCentral K D' where out x hx := have ⟨k, hk⟩ := h.1 ((MulEquivClass.apply_mem_center_iff e.symm).mpr hx) diff --git a/Mathlib/Algebra/CharP/Invertible.lean b/Mathlib/Algebra/CharP/Invertible.lean index 2f2598a2400b9d..66cb9d757c8a4d 100644 --- a/Mathlib/Algebra/CharP/Invertible.lean +++ b/Mathlib/Algebra/CharP/Invertible.lean @@ -56,7 +56,7 @@ theorem CharP.natCast_gcdA_mul_intCast_eq_gcd (n : ℕ) : /-- In a ring of characteristic `p`, `(n : R)` is invertible when `n` is coprime with `p`, with inverse `n.gcdA p`. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfCoprime {n : ℕ} (h : n.Coprime p) : Invertible (n : R) where invOf := n.gcdA p @@ -93,13 +93,13 @@ variable [Semifield K] /-- A natural number `t` is invertible in a semifield `K` if the characteristic of `K` does not divide `t`. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfRingCharNotDvd {t : ℕ} (not_dvd : ¬ringChar K ∣ t) : Invertible (t : K) := invertibleOfNonzero fun h => not_dvd ((ringChar.spec K t).mp h) /-- A natural number `t` is invertible in a semifield `K` of characteristic `p` if `p` does not divide `t`. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfCharPNotDvd {p : ℕ} [CharP K p] {t : ℕ} (not_dvd : ¬p ∣ t) : Invertible (t : K) := invertibleOfNonzero fun h => not_dvd ((CharP.cast_eq_zero_iff K p t).mp h) diff --git a/Mathlib/Algebra/CharP/MixedCharZero.lean b/Mathlib/Algebra/CharP/MixedCharZero.lean index 25e505bb05cced..a6452839d1c98f 100644 --- a/Mathlib/Algebra/CharP/MixedCharZero.lean +++ b/Mathlib/Algebra/CharP/MixedCharZero.lean @@ -214,7 +214,7 @@ private lemma pnatCast_eq_natCast [Fact (∀ I : Ideal R, I ≠ ⊤ → CharZero simp only [IsUnit.unit_spec] /-- Equal characteristic implies `ℚ`-algebra. -/ -@[implicit_reducible] +@[instance_reducible] private noncomputable def algebraRat (h : ∀ I : Ideal R, I ≠ ⊤ → CharZero (R ⧸ I)) : Algebra ℚ R := haveI : Fact (∀ I : Ideal R, I ≠ ⊤ → CharZero (R ⧸ I)) := ⟨h⟩ diff --git a/Mathlib/Algebra/Colimit/DirectLimit.lean b/Mathlib/Algebra/Colimit/DirectLimit.lean index 3a000c17f440e7..c00d58f3f96d15 100644 --- a/Mathlib/Algebra/Colimit/DirectLimit.lean +++ b/Mathlib/Algebra/Colimit/DirectLimit.lean @@ -634,6 +634,7 @@ lemma map₀_algebraMap (i : ι) (r : R) : map₀ f (fun i ↦ algebraMap R (G i) r) = ⟦⟨i, algebraMap R (G i) r⟩⟧ := map₀_def _ _ (fun _ _ _ => AlgHomClass.commutes _ _) i +set_option backward.isDefEq.respectTransparency.types false in instance : Algebra R (DirectLimit G f) where algebraMap := map₀RingHom (f := f).comp (algebraMap R (∀ i, G i)) commutes' r := DirectLimit.induction f fun i _ ↦ by @@ -643,6 +644,7 @@ instance : Algebra R (DirectLimit G f) where dsimp [Pi.algebraMap_def, map₀RingHom] rw [smul_def, map₀_algebraMap i, mul_def, Algebra.smul_def'] +set_option backward.isDefEq.respectTransparency.types false in lemma algebraMap_def (i : ι) (r : R) : algebraMap R (DirectLimit G f) r = ⟦⟨i, algebraMap R (G i) r⟩⟧ := map₀_algebraMap i r @@ -843,6 +845,7 @@ variable [∀ i, Semiring (G i)] [∀ i, Algebra R (G i)] variable [∀ i j h, AlgHomClass (T h) R (G i) (G j)] variable [Nonempty ι] +set_option backward.isDefEq.respectTransparency.types false in variable (G f) in /-- The canonical map from a component to the direct limit. -/ @[simps] @@ -851,10 +854,12 @@ def of (i) : G i →ₐ[R] DirectLimit G f where __ := (DirectLimit.Ring.of G f i) commutes' r := by rw [algebraMap_def i] +set_option backward.isDefEq.respectTransparency.types false in lemma of_f {i j} (hij) (x) : of G f j (f i j hij x) = of G f i x := .symm <| eq_of_le .. variable (P : Type*) [Semiring P] [Algebra R P] +set_option backward.isDefEq.respectTransparency.types false in variable (G f) in /-- The universal property of the direct limit: maps from the components to another R-algebra that respect the directed system structure (i.e. make some diagram commute) give rise @@ -876,6 +881,7 @@ theorem lift_comp_of {i} : (lift G f P g Hg).comp (of G f i) = g i := rfl theorem lift_of (i x) : lift G f P g Hg (of G f i x) = g i x := rfl +set_option backward.isDefEq.respectTransparency.types false in @[ext] theorem hom_ext {g₁ g₂ : DirectLimit G f →ₐ[R] P} (h : ∀ i, g₁.comp (of G f i) = g₂.comp (of G f i)) : diff --git a/Mathlib/Algebra/Colimit/Finiteness.lean b/Mathlib/Algebra/Colimit/Finiteness.lean index 0730c41a1b9bd6..0b1368eb5abe64 100644 --- a/Mathlib/Algebra/Colimit/Finiteness.lean +++ b/Mathlib/Algebra/Colimit/Finiteness.lean @@ -31,7 +31,7 @@ variable (R M : Type*) [Semiring R] [AddCommMonoid M] [Module R M] def fgSystem (N₁ N₂ : {N : Submodule R M // N.FG}) (le : N₁ ≤ N₂) : N₁ →ₗ[R] N₂ := Submodule.inclusion le -open DirectLimit +open Module.DirectLimit namespace fgSystem @@ -54,6 +54,7 @@ noncomputable def equiv : DirectLimit _ (fgSystem R M) ≃ₗ[R] M := variable {R M} +set_option backward.isDefEq.respectTransparency.types false in lemma equiv_comp_of (N : {N : Submodule R M // N.FG}) : (equiv R M).toLinearMap ∘ₗ of _ _ _ _ N = N.1.subtype := by ext; simp [equiv] diff --git a/Mathlib/Algebra/Colimit/Module.lean b/Mathlib/Algebra/Colimit/Module.lean index 893980b6590ca1..97586ab60c675a 100644 --- a/Mathlib/Algebra/Colimit/Module.lean +++ b/Mathlib/Algebra/Colimit/Module.lean @@ -408,6 +408,7 @@ lemma map_comp (g₁ : (i : ι) → G i →+ G' i) (g₂ : (i : ι) → G' i → DirectLimit G f →+ DirectLimit G'' f'') := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in /-- Consider direct limits `lim G` and `lim G'` with direct system `f` and `f'` respectively, any family of equivalences `eᵢ : Gᵢ ≅ G'ᵢ` such that `e ∘ f = f' ∘ e` induces an equivalence @@ -424,12 +425,14 @@ def congr (e : (i : ι) → G i ≃+ G' i) simp [← eq1]) (by simp [map_comp]) (by simp [map_comp]) +set_option backward.isDefEq.respectTransparency.types false in lemma congr_apply_of (e : (i : ι) → G i ≃+ G' i) (he : ∀ i j h, (e j).toAddMonoidHom.comp (f i j h) = (f' i j h).comp (e i)) {i : ι} (g : G i) : congr e he (of G f i g) = of G' f' i (e i g) := map_apply_of _ he _ +set_option backward.isDefEq.respectTransparency.types false in lemma congr_symm_apply_of (e : (i : ι) → G i ≃+ G' i) (he : ∀ i j h, (e j).toAddMonoidHom.comp (f i j h) = (f' i j h).comp (e i)) {i : ι} (g : G' i) : diff --git a/Mathlib/Algebra/Colimit/Ring.lean b/Mathlib/Algebra/Colimit/Ring.lean index 1091157c329aac..986be6cadd1567 100644 --- a/Mathlib/Algebra/Colimit/Ring.lean +++ b/Mathlib/Algebra/Colimit/Ring.lean @@ -256,6 +256,7 @@ lemma map_comp (g₁ : (i : ι) → G i →+* G' i) (g₂ : (i : ι) → G' i DirectLimit G (fun _ _ h ↦ f _ _ h) →+* DirectLimit G'' fun _ _ h ↦ f'' _ _ h) := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in /-- Consider direct limits `lim G` and `lim G'` with direct system `f` and `f'` respectively, any family of equivalences `eᵢ : Gᵢ ≅ G'ᵢ` such that `e ∘ f = f' ∘ e` induces an equivalence @@ -279,6 +280,7 @@ lemma congr_apply_of (e : (i : ι) → G i ≃+* G' i) congr e he (of G _ i g) = of G' (fun _ _ h ↦ f' _ _ h) i (e i g) := map_apply_of _ he _ +set_option backward.isDefEq.respectTransparency.types false in lemma congr_symm_apply_of (e : (i : ι) → G i ≃+* G' i) (he : ∀ i j h, (e j).toRingHom.comp (f i j h) = (f' i j h).comp (e i)) {i : ι} (g : G' i) : diff --git a/Mathlib/Algebra/ContinuedFractions/Computation/ApproximationCorollaries.lean b/Mathlib/Algebra/ContinuedFractions/Computation/ApproximationCorollaries.lean index 4d0ef641dff642..214e20b7da0413 100644 --- a/Mathlib/Algebra/ContinuedFractions/Computation/ApproximationCorollaries.lean +++ b/Mathlib/Algebra/ContinuedFractions/Computation/ApproximationCorollaries.lean @@ -115,6 +115,7 @@ theorem of_convergence_epsilon : _ ≤ fib (n + 1) * fib (n + 2) := by gcongr; lia _ ≤ B * nB := by gcongr +set_option backward.isDefEq.respectTransparency false in theorem of_convergence [TopologicalSpace K] [OrderTopology K] : Filter.Tendsto (of v).convs Filter.atTop <| 𝓝 v := by simpa [LinearOrderedAddCommGroup.tendsto_nhds, abs_sub_comm] using of_convergence_epsilon v diff --git a/Mathlib/Algebra/ContinuedFractions/Computation/TerminatesIffRat.lean b/Mathlib/Algebra/ContinuedFractions/Computation/TerminatesIffRat.lean index a39a0fd0f0b7b4..ff0750a92820f9 100644 --- a/Mathlib/Algebra/ContinuedFractions/Computation/TerminatesIffRat.lean +++ b/Mathlib/Algebra/ContinuedFractions/Computation/TerminatesIffRat.lean @@ -193,6 +193,7 @@ end IntFractPair theorem coe_of_h_rat_eq (v_eq_q : v = (↑q : K)) : (↑((of q).h : ℚ) : K) = (of v).h := by simp_all +set_option backward.isDefEq.respectTransparency false in theorem coe_of_s_get?_rat_eq (v_eq_q : v = (↑q : K)) (n : ℕ) : (((of q).s.get? n).map (Pair.map (↑)) : Option <| Pair K) = (of v).s.get? n := by simp only [of, IntFractPair.seq1, Stream'.Seq.map_get?, Stream'.Seq.get?_tail] diff --git a/Mathlib/Algebra/ContinuedFractions/Computation/Translations.lean b/Mathlib/Algebra/ContinuedFractions/Computation/Translations.lean index 4b0408bbbd1a3b..7048c29d4bc9aa 100644 --- a/Mathlib/Algebra/ContinuedFractions/Computation/Translations.lean +++ b/Mathlib/Algebra/ContinuedFractions/Computation/Translations.lean @@ -213,6 +213,7 @@ Now let's show how the values of the sequences correspond to one another. -/ +set_option backward.isDefEq.respectTransparency.types false in theorem IntFractPair.exists_succ_get?_stream_of_gcf_of_get?_eq_some {gp_n : Pair K} (s_nth_eq : (of v).s.get? n = some gp_n) : ∃ ifp : IntFractPair K, IntFractPair.stream v (n + 1) = some ifp ∧ (ifp.b : K) = gp_n.b := by @@ -222,6 +223,7 @@ theorem IntFractPair.exists_succ_get?_stream_of_gcf_of_get?_eq_some {gp_n : Pair simpa using s_nth_eq simp_all only [Option.some.injEq, exists_eq_left'] +set_option backward.isDefEq.respectTransparency false in /-- Shows how the entries of the sequence of the computed continued fraction can be obtained by the integer parts of the stream of integer and fractional parts. -/ diff --git a/Mathlib/Algebra/DirectSum/Basic.lean b/Mathlib/Algebra/DirectSum/Basic.lean index 8be68d01e62ca2..d9fa25f9b299b4 100644 --- a/Mathlib/Algebra/DirectSum/Basic.lean +++ b/Mathlib/Algebra/DirectSum/Basic.lean @@ -35,6 +35,7 @@ variable (ι : Type v) (β : ι → Type w) /-- `DirectSum ι β` is the direct sum of a family of additive commutative monoids `β i`. Note: `open DirectSum` will enable the notation `⨁ i, β i` for `DirectSum ι β`. -/ +@[implicit_reducible] def DirectSum [∀ i, AddCommMonoid (β i)] : Type _ := Π₀ i, β i deriving AddCommMonoid, Inhabited, DFunLike @@ -369,8 +370,7 @@ theorem coeAddMonoidHom_eq_dfinsuppSum [DecidableEq ι] {M S : Type*} [DecidableEq M] [AddCommMonoid M] [SetLike S M] [AddSubmonoidClass S M] (A : ι → S) (x : DirectSum ι fun i => A i) : DirectSum.coeAddMonoidHom A x = DFinsupp.sum x fun i => (fun x : A i => ↑x) := by - simp only [DirectSum.coeAddMonoidHom, toAddMonoid, DFinsupp.liftAddHom, AddEquiv.coe_mk, - Equiv.coe_fn_mk] + simp only [DirectSum.coeAddMonoidHom, toAddMonoid, DFinsupp.liftAddHom, AddEquiv.coe_mk] exact DFinsupp.sumAddHom_apply _ x @[simp] @@ -403,6 +403,7 @@ theorem IsInternal.addSubmonoid_iSup_eq_top {M : Type*} [DecidableEq ι] [AddCom variable {M S : Type*} [AddCommMonoid M] [SetLike S M] [AddSubmonoidClass S M] +set_option backward.isDefEq.respectTransparency false in theorem support_subset [DecidableEq ι] [DecidableEq M] (A : ι → S) (x : DirectSum ι fun i => A i) : (Function.support fun i => (x i : M)) ⊆ ↑(DFinsupp.support x) := by intro m @@ -459,5 +460,5 @@ and the corresponding finite product. -/ def DirectSum.addEquivProd {ι : Type*} [Fintype ι] (G : ι → Type*) [(i : ι) → AddCommMonoid (G i)] : DirectSum ι G ≃+ ((i : ι) → G i) := ⟨DFinsupp.equivFunOnFintype, fun g h ↦ funext fun _ ↦ by - simp only [DFinsupp.equivFunOnFintype, Equiv.toFun_as_coe, Equiv.coe_fn_mk, add_apply, - Pi.add_apply]⟩ + simp only [DFinsupp.equivFunOnFintype, Equiv.toFun_as_coe, Equiv.coe_fn_mk, + ← DFinsupp.add_apply, Pi.add_apply]⟩ diff --git a/Mathlib/Algebra/DirectSum/Decomposition.lean b/Mathlib/Algebra/DirectSum/Decomposition.lean index ab7887ab66ded5..fb313888817c22 100644 --- a/Mathlib/Algebra/DirectSum/Decomposition.lean +++ b/Mathlib/Algebra/DirectSum/Decomposition.lean @@ -76,7 +76,7 @@ abbrev Decomposition.ofAddHom (decompose : M →+ ⨁ i, ℳ i) right_inv := DFunLike.congr_fun h_right_inv /-- Noncomputably conjure a decomposition instance from a `DirectSum.IsInternal` proof. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def IsInternal.chooseDecomposition (h : IsInternal ℳ) : DirectSum.Decomposition ℳ where decompose' := (Equiv.ofBijective _ h).symm @@ -146,11 +146,19 @@ theorem degree_eq_of_mem_mem {x : M} {i j : ι} (hxi : x ∈ ℳ i) (hxj : x ∈ i = j := by contrapose! hx; rw [← decompose_of_mem_same ℳ hxj, decompose_of_mem_ne ℳ hxi hx] +#adaptation_note +/-- +`simps!` won't apply `AddEquiv.symm_mk` without the `id <|` in `map_add'`. +`decompose` and `Equiv.symm` are not implicit-reducible, so the type of the proof doesn't match the +expected type up to implicit reducibility. If we remove `id`, we don't get an immediate error, +but some downstream declarations will break. +-/ /-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as an additive monoid to a direct sum of components. -/ @[simps!] def decomposeAddEquiv : M ≃+ ⨁ i, ℳ i := - AddEquiv.symm { (decompose ℳ).symm with map_add' := map_add (DirectSum.coeAddMonoidHom ℳ) } + AddEquiv.symm { (decompose ℳ).symm with + map_add' := id <| map_add (DirectSum.coeAddMonoidHom ℳ) } @[simp] theorem decompose_zero : decompose ℳ (0 : M) = 0 := diff --git a/Mathlib/Algebra/DirectSum/Idempotents.lean b/Mathlib/Algebra/DirectSum/Idempotents.lean index 9c26923e73bb1f..fda597c7059e30 100644 --- a/Mathlib/Algebra/DirectSum/Idempotents.lean +++ b/Mathlib/Algebra/DirectSum/Idempotents.lean @@ -37,7 +37,6 @@ lemma decompose_eq_mul_idempotent (x : R) (i : I) : decompose V x i = x * idempo lemma isIdempotentElem_idempotent (i : I) : IsIdempotentElem (idempotent V i : R) := by rw [IsIdempotentElem, ← decompose_eq_mul_idempotent, idempotent, decompose_coe, of_eq_same] -set_option backward.isDefEq.respectTransparency false in /-- If a semiring can be decomposed into direct sum of finite left ideals `Vᵢ` where `1 = e₁ + ... + eₙ` and `eᵢ ∈ Vᵢ`, then `eᵢ` is a family of complete orthogonal idempotents. -/ diff --git a/Mathlib/Algebra/DirectSum/Internal.lean b/Mathlib/Algebra/DirectSum/Internal.lean index b0f553a0a9d362..ed6b72b9c09ee3 100644 --- a/Mathlib/Algebra/DirectSum/Internal.lean +++ b/Mathlib/Algebra/DirectSum/Internal.lean @@ -163,6 +163,7 @@ theorem coe_mul_apply_eq_dfinsuppSum [AddMonoid ι] [SetLike.GradedMonoid A] · rw [of_eq_of_ne _ _ _ (Ne.symm h)] rfl +set_option backward.isDefEq.respectTransparency false in open Finset in theorem coe_mul_apply_eq_sum_antidiagonal [AddMonoid ι] [HasAntidiagonal ι] [SetLike.GradedMonoid A] (r r' : ⨁ i, A i) (n : ι) : @@ -172,6 +173,7 @@ theorem coe_mul_apply_eq_sum_antidiagonal [AddMonoid ι] [HasAntidiagonal ι] apply Finset.sum_subset (fun _ ↦ by simp) aesop (erase simp not_and) (add simp not_and_or) +set_option backward.isDefEq.respectTransparency false in theorem coe_of_mul_apply_aux [AddMonoid ι] [SetLike.GradedMonoid A] {i : ι} (r : A i) (r' : ⨁ i, A i) {j n : ι} (H : ∀ x : ι, i + x = n ↔ x = j) : ((of (fun i => A i) i r * r') n : R) = r * r' j := by @@ -186,6 +188,7 @@ theorem coe_of_mul_apply_aux [AddMonoid ι] [SetLike.GradedMonoid A] {i : ι} (r · rfl rw [DFinsupp.notMem_support_iff.mp h, ZeroMemClass.coe_zero, mul_zero] +set_option backward.isDefEq.respectTransparency false in theorem coe_mul_of_apply_aux [AddMonoid ι] [SetLike.GradedMonoid A] (r : ⨁ i, A i) {i : ι} (r' : A i) {j n : ι} (H : ∀ x : ι, x + i = n ↔ x = j) : ((r * of (fun i => A i) i r') n : R) = r j * r' := by @@ -223,6 +226,7 @@ section CanonicallyOrderedAddCommMonoid variable [Semiring R] [SetLike σ R] [AddSubmonoidClass σ R] (A : ι → σ) variable [AddCommMonoid ι] [PartialOrder ι] [CanonicallyOrderedAdd ι] [SetLike.GradedMonoid A] +set_option backward.isDefEq.respectTransparency.types false in theorem coe_of_mul_apply_of_not_le {i : ι} (r : A i) (r' : ⨁ i, A i) (n : ι) (h : ¬i ≤ n) : ((of (fun i => A i) i r * r') n : R) = 0 := by classical @@ -234,6 +238,7 @@ theorem coe_of_mul_apply_of_not_le {i : ι} (r : A i) (r' : ⨁ i, A i) (n : ι) · rw [DFinsupp.sum, Finset.sum_ite_of_false, Finset.sum_const_zero] exact fun x _ H => h ((self_le_add_right i x).trans_eq H) +set_option backward.isDefEq.respectTransparency.types false in theorem coe_mul_of_apply_of_not_le (r : ⨁ i, A i) {i : ι} (r' : A i) (n : ι) (h : ¬i ≤ n) : ((r * of (fun i => A i) i r') n : R) = 0 := by classical @@ -436,6 +441,7 @@ section Semiring variable [Semiring R] [SetLike σ R] [AddSubmonoidClass σ R] variable {A : ι → σ} [SetLike.GradedMonoid A] +set_option backward.isDefEq.respectTransparency.types false in theorem mul_apply_eq_zero {r r' : ⨁ i, A i} {m n : ι} (hr : ∀ i < m, r i = 0) (hr' : ∀ i < n, r' i = 0) ⦃k : ι⦄ (hk : k < m + n) : (r * r') k = 0 := by diff --git a/Mathlib/Algebra/DirectSum/LinearMap.lean b/Mathlib/Algebra/DirectSum/LinearMap.lean index 0f7ed92c3481eb..119c4f6e26947c 100644 --- a/Mathlib/Algebra/DirectSum/LinearMap.lean +++ b/Mathlib/Algebra/DirectSum/LinearMap.lean @@ -30,6 +30,7 @@ section IsInternal variable [DecidableEq ι] +set_option backward.isDefEq.respectTransparency.types false in /-- If a linear map `f : M₁ → M₂` respects direct sum decompositions of `M₁` and `M₂`, then it has a block diagonal matrix with respect to bases compatible with the direct sum decompositions. -/ lemma toMatrix_directSum_collectedBasis_eq_blockDiagonal' {R M₁ M₂ : Type*} [CommSemiring R] diff --git a/Mathlib/Algebra/DirectSum/Module.lean b/Mathlib/Algebra/DirectSum/Module.lean index 59db289b58665a..13d425782230c6 100644 --- a/Mathlib/Algebra/DirectSum/Module.lean +++ b/Mathlib/Algebra/DirectSum/Module.lean @@ -137,6 +137,7 @@ theorem linearMap_ext ⦃ψ ψ' : (⨁ i, M i) →ₗ[R] N⦄ (H : ∀ i, ψ.comp (lof R ι M i) = ψ'.comp (lof R ι M i)) : ψ = ψ' := DFinsupp.lhom_ext' H +set_option backward.isDefEq.respectTransparency false in /-- The inclusion of a subset of the direct summands into a larger subset of the direct summands, as a linear map. -/ def lsetToSet (S T : Set ι) (H : S ⊆ T) : (⨁ i : S, M i) →ₗ[R] ⨁ i : T, M i := @@ -424,12 +425,14 @@ variable {A} theorem range_coeLinearMap : LinearMap.range (coeLinearMap A) = ⨆ i, A i := (Submodule.iSup_eq_range_dfinsupp_lsum _).symm +set_option backward.isDefEq.respectTransparency false in @[simp] theorem IsInternal.ofBijective_coeLinearMap_same (h : IsInternal A) {i : ι} (x : A i) : (LinearEquiv.ofBijective (coeLinearMap A) h).symm x i = x := by rw [← coeLinearMap_of, LinearEquiv.ofBijective_symm_apply_apply, of_eq_same] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem IsInternal.ofBijective_coeLinearMap_of_ne (h : IsInternal A) {i j : ι} (hij : i ≠ j) (x : A i) : @@ -474,12 +477,14 @@ theorem IsInternal.collectedBasis_coe (h : IsInternal A) {α : ι → Type*} theorem IsInternal.collectedBasis_mem (h : IsInternal A) {α : ι → Type*} (v : ∀ i, Basis (α i) R (A i)) (a : Σ i, α i) : h.collectedBasis v a ∈ A a.1 := by simp +set_option backward.isDefEq.respectTransparency false in theorem IsInternal.collectedBasis_repr_of_mem (h : IsInternal A) {α : ι → Type*} (v : ∀ i, Basis (α i) R (A i)) {x : M} {i : ι} {a : α i} (hx : x ∈ A i) : (h.collectedBasis v).repr x ⟨i, a⟩ = (v i).repr ⟨x, hx⟩ a := by change (sigmaFinsuppLequivDFinsupp R).symm (DFinsupp.mapRange _ (fun i ↦ map_zero _) _) _ = _ simp [h.ofBijective_coeLinearMap_of_mem hx] +set_option backward.isDefEq.respectTransparency false in theorem IsInternal.collectedBasis_repr_of_mem_ne (h : IsInternal A) {α : ι → Type*} (v : ∀ i, Basis (α i) R (A i)) {x : M} {i j : ι} (hij : i ≠ j) {a : α j} (hx : x ∈ A i) : (h.collectedBasis v).repr x ⟨j, a⟩ = 0 := by diff --git a/Mathlib/Algebra/DirectSum/Ring.lean b/Mathlib/Algebra/DirectSum/Ring.lean index 3f887f3139cf5c..0b6bb7481cea90 100644 --- a/Mathlib/Algebra/DirectSum/Ring.lean +++ b/Mathlib/Algebra/DirectSum/Ring.lean @@ -298,6 +298,7 @@ theorem mul_eq_dfinsuppSum [∀ (i : ι) (x : A i), Decidable (x ≠ 0)] (a a' : funext x simp [AddMonoidHom.dfinsuppSum_apply, DFinsupp.sumAddHom_apply, DirectSum.toAddMonoid] +set_option backward.isDefEq.respectTransparency false in /-- A heavily unfolded version of the definition of multiplication -/ theorem mul_eq_sum_support_ghas_mul [∀ (i : ι) (x : A i), Decidable (x ≠ 0)] (a a' : ⨁ i, A i) : a * a' = diff --git a/Mathlib/Algebra/DualQuaternion.lean b/Mathlib/Algebra/DualQuaternion.lean index 3b49c02830a40d..565840eca5825e 100644 --- a/Mathlib/Algebra/DualQuaternion.lean +++ b/Mathlib/Algebra/DualQuaternion.lean @@ -31,6 +31,7 @@ variable {R : Type*} [CommRing R] namespace Quaternion +set_option backward.isDefEq.respectTransparency.types false in /-- The dual quaternions can be equivalently represented as a quaternion with dual coefficients, or as a dual number with quaternion coefficients. diff --git a/Mathlib/Algebra/Exact/Basic.lean b/Mathlib/Algebra/Exact/Basic.lean index 5aae5f12791023..ec439f202f708f 100644 --- a/Mathlib/Algebra/Exact/Basic.lean +++ b/Mathlib/Algebra/Exact/Basic.lean @@ -374,6 +374,7 @@ variable {f : M →ₗ[R] N} {g : N →ₗ[R] P} open LinearMap +set_option backward.isDefEq.respectTransparency.types false in /-- Given an exact sequence `0 → M → N → P`, giving a section `P → N` is equivalent to giving a splitting `N ≃ M × P`. -/ noncomputable @@ -410,6 +411,7 @@ def Exact.splitSurjectiveEquiv (h : Function.Exact f g) (hf : Function.Injective apply e.injective ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in /-- Given an exact sequence `M → N → P → 0`, giving a retraction `N → M` is equivalent to giving a splitting `N ≃ M × P`. -/ noncomputable @@ -560,6 +562,7 @@ lemma ker_eq_bot_range_liftQ_iff (h : range f ≤ ker g) : obtain ⟨x, rfl⟩ := Submodule.Quotient.mk_surjective _ x simpa using hfg x +set_option backward.isDefEq.respectTransparency.types false in lemma injective_range_liftQ_of_exact (h : Function.Exact f g) : Function.Injective ((range f).liftQ g (h · |>.mpr)) := by simpa only [← LinearMap.ker_eq_bot, ker_eq_bot_range_liftQ_iff, exact_iff] using h @@ -582,6 +585,7 @@ noncomputable def Function.Exact.linearEquivOfSurjective (h : Function.Exact f g LinearEquiv.ofBijective ((LinearMap.range f).liftQ g (h · |>.mpr)) ⟨LinearMap.injective_range_liftQ_of_exact h, LinearMap.surjective_range_liftQ _ hg⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Function.Exact.linearEquivOfSurjective_symm_apply (h : Function.Exact f g) (hg : Function.Surjective g) (x : N) : diff --git a/Mathlib/Algebra/Expr.lean b/Mathlib/Algebra/Expr.lean index 8a68c40ae87c11..a4bb7798353ea2 100644 --- a/Mathlib/Algebra/Expr.lean +++ b/Mathlib/Algebra/Expr.lean @@ -18,21 +18,21 @@ This file provides instances on `x y : Q($α)` such that `x + y = q($x + $y)`. open Qq /-- Produce a `One` instance for `Q($α)` such that `1 : Q($α)` is `q(1 : $α)`. -/ -@[implicit_reducible] +@[instance_reducible] def Expr.instOne {u : Lean.Level} (α : Q(Type u)) (_ : Q(One $α)) : One Q($α) where one := q(1 : $α) /-- Produce a `Zero` instance for `Q($α)` such that `0 : Q($α)` is `q(0 : $α)`. -/ -@[implicit_reducible] +@[instance_reducible] def Expr.instZero {u : Lean.Level} (α : Q(Type u)) (_ : Q(Zero $α)) : Zero Q($α) where zero := q(0 : $α) /-- Produce a `Mul` instance for `Q($α)` such that `x * y : Q($α)` is `q($x * $y)`. -/ -@[implicit_reducible] +@[instance_reducible] def Expr.instMul {u : Lean.Level} (α : Q(Type u)) (_ : Q(Mul $α)) : Mul Q($α) where mul x y := q($x * $y) /-- Produce an `Add` instance for `Q($α)` such that `x + y : Q($α)` is `q($x + $y)`. -/ -@[implicit_reducible] +@[instance_reducible] def Expr.instAdd {u : Lean.Level} (α : Q(Type u)) (_ : Q(Add $α)) : Add Q($α) where add x y := q($x + $y) diff --git a/Mathlib/Algebra/Field/IsField.lean b/Mathlib/Algebra/Field/IsField.lean index ba5c64299d332c..f6a3085f7edbbb 100644 --- a/Mathlib/Algebra/Field/IsField.lean +++ b/Mathlib/Algebra/Field/IsField.lean @@ -71,7 +71,7 @@ theorem not_isField_of_subsingleton (R : Type u) [Semiring R] [Subsingleton R] : open scoped Classical in /-- Transferring from `IsField` to `Semifield`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def IsField.toSemifield {R : Type u} [Semiring R] (h : IsField R) : Semifield R where __ := ‹Semiring R› __ := h @@ -82,7 +82,7 @@ noncomputable def IsField.toSemifield {R : Type u} [Semiring R] (h : IsField R) nnqsmul_def _ _ := rfl /-- Transferring from `IsField` to `Field`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def IsField.toField {R : Type u} [Ring R] (h : IsField R) : Field R where __ := (‹Ring R› :) -- this also works without the `( :)`, but it's slow __ := h.toSemifield diff --git a/Mathlib/Algebra/Field/Rat.lean b/Mathlib/Algebra/Field/Rat.lean index 1d7edec13d0932..253655521fb440 100644 --- a/Mathlib/Algebra/Field/Rat.lean +++ b/Mathlib/Algebra/Field/Rat.lean @@ -75,11 +75,13 @@ theorem divNat_eq_div (a b : ℕ) : divNat a b = a / b := by ext simp [Rat.mkRat_eq_div] +set_option backward.isDefEq.respectTransparency false in lemma num_inv_of_ne_zero {q : ℚ≥0} (hq : q ≠ 0) : q⁻¹.num = q.den := by rw [inv_def, divNat, num, coe_mk, Rat.divInt_ofNat, ← Rat.mk_eq_mkRat _ _ (num_ne_zero.mpr hq), Int.natAbs_natCast] simpa using q.coprime_num_den.symm +set_option backward.isDefEq.respectTransparency false in lemma den_inv_of_ne_zero {q : ℚ≥0} (hq : q ≠ 0) : q⁻¹.den = q.num := by rw [inv_def, divNat, den, coe_mk, Rat.divInt_ofNat, ← Rat.mk_eq_mkRat _ _ (num_ne_zero.mpr hq)] simpa using q.coprime_num_den.symm diff --git a/Mathlib/Algebra/Free.lean b/Mathlib/Algebra/Free.lean index 4fc7edd49571d3..92518530e644c4 100644 --- a/Mathlib/Algebra/Free.lean +++ b/Mathlib/Algebra/Free.lean @@ -344,6 +344,7 @@ theorem quot_mk_assoc_left (x y z w : α) : Quot.mk (AssocRel α) (x * (y * z * w)) = Quot.mk _ (x * (y * (z * w))) := Quot.sound (AssocRel.left _ _ _ _) +set_option backward.isDefEq.respectTransparency false in @[to_additive] instance : Semigroup (AssocQuotient α) where mul x y := by diff --git a/Mathlib/Algebra/FreeAlgebra.lean b/Mathlib/Algebra/FreeAlgebra.lean index 6658040586f4be..e1e915d3040767 100644 --- a/Mathlib/Algebra/FreeAlgebra.lean +++ b/Mathlib/Algebra/FreeAlgebra.lean @@ -222,6 +222,7 @@ instance instDistrib : Distrib (FreeAlgebra R X) where rintro ⟨⟩ ⟨⟩ ⟨⟩ exact Quot.sound Rel.right_distrib +set_option backward.isDefEq.respectTransparency false in instance instAddCommMonoid : AddCommMonoid (FreeAlgebra R X) where add_assoc := by rintro ⟨⟩ ⟨⟩ ⟨⟩ @@ -535,6 +536,7 @@ end FreeAlgebra `CoeSort` below. Closing it and reopening it fixes it... -/ namespace FreeAlgebra +set_option backward.isDefEq.respectTransparency.types false in /-- An induction principle for the free algebra. If `C` holds for the `algebraMap` of `r : R` into `FreeAlgebra R X`, the `ι` of `x : X`, and is diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index ce8a872ce25477..806fe80a9bcdac 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -340,7 +340,7 @@ theorem hom_map_lift (g : M →* N) (f : α → M) (x : FreeMonoid α) : g (lift DFunLike.ext_iff.1 (comp_lift g f) x /-- Define a multiplicative action of `FreeMonoid α` on `β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Define an additive action of `FreeAddMonoid α` on `β`. -/] def mkMulAction (f : α → β → β) : MulAction (FreeMonoid α) β where smul l b := l.toList.foldr f b @@ -381,6 +381,7 @@ theorem map_of (f : α → β) (x : α) : map f (of x) = of (f x) := rfl @[to_additive] theorem mem_map {m : β} : m ∈ map f a ↔ ∃ n ∈ a, f n = m := List.mem_map +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem map_map {α₁ : Type*} {g : α₁ → α} {x : FreeMonoid α₁} : map f (map g x) = map (f ∘ g) x := by diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index e90e78493a2721..21d09cc04654af 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -1057,7 +1057,7 @@ private theorem map_mk_unit_aux {f : Associates α →* α} variable [IsCancelMulZero α] /-- Define `NormalizationMonoid` on a structure from a `MonoidHom` inverse to `Associates.mk`. -/ -@[implicit_reducible] +@[instance_reducible] def strongNormalizationMonoidOfMonoidHomRightInverse [DecidableEq α] (f : Associates α →* α) (hinv : Function.RightInverse f Associates.mk) : StrongNormalizationMonoid α where @@ -1087,7 +1087,7 @@ noncomputable alias normalizationMonoidOfMonoidHomRightInverse := strongNormalizationMonoidOfMonoidHomRightInverse /-- Define `GCDMonoid` on a structure just from the `gcd` and its properties. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def gcdMonoidOfGCD [DecidableEq α] (gcd : α → α → α) (gcd_dvd_left : ∀ a b, gcd a b ∣ a) (gcd_dvd_right : ∀ a b, gcd a b ∣ b) (dvd_gcd : ∀ {a b c}, a ∣ c → a ∣ b → a ∣ gcd c b) : GCDMonoid α := @@ -1115,7 +1115,7 @@ noncomputable def gcdMonoidOfGCD [DecidableEq α] (gcd : α → α → α) set_option backward.isDefEq.respectTransparency false in /-- Define `NormalizedGCDMonoid` on a structure just from the `gcd` and its properties. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def normalizedGCDMonoidOfGCD [NormalizationMonoid α] [DecidableEq α] (gcd : α → α → α) (gcd_dvd_left : ∀ a b, gcd a b ∣ a) (gcd_dvd_right : ∀ a b, gcd a b ∣ b) (dvd_gcd : ∀ {a b c}, a ∣ c → a ∣ b → a ∣ gcd c b) @@ -1144,7 +1144,7 @@ noncomputable def normalizedGCDMonoidOfGCD [NormalizationMonoid α] [DecidableEq from (Classical.choose_spec ((gcd_dvd_left a 0).trans (.intro 0 rfl))).symm } /-- Define `GCDMonoid` on a structure just from the `lcm` and its properties. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def gcdMonoidOfLCM [DecidableEq α] (lcm : α → α → α) (dvd_lcm_left : ∀ a b, a ∣ lcm a b) (dvd_lcm_right : ∀ a b, b ∣ lcm a b) (lcm_dvd : ∀ {a b c}, c ∣ a → b ∣ a → lcm c b ∣ a) : GCDMonoid α := @@ -1210,7 +1210,7 @@ noncomputable def gcdMonoidOfLCM [DecidableEq α] (lcm : α → α → α) set_option backward.isDefEq.respectTransparency false in /-- Define `NormalizedGCDMonoid` on a structure just from the `lcm` and its properties. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def normalizedGCDMonoidOfLCM [NormalizationMonoid α] [DecidableEq α] (lcm : α → α → α) (dvd_lcm_left : ∀ a b, a ∣ lcm a b) (dvd_lcm_right : ∀ a b, b ∣ lcm a b) (lcm_dvd : ∀ {a b c}, c ∣ a → b ∣ a → lcm c b ∣ a) @@ -1266,7 +1266,7 @@ noncomputable def normalizedGCDMonoidOfLCM [NormalizationMonoid α] [DecidableEq apply ac } /-- Define a `GCDMonoid` structure on a monoid just from the existence of a `gcd`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def gcdMonoidOfExistsGCD [DecidableEq α] (h : ∀ a b : α, ∃ c : α, ∀ d : α, d ∣ a ∧ d ∣ b ↔ d ∣ c) : GCDMonoid α := gcdMonoidOfGCD (fun a b => Classical.choose (h a b)) @@ -1275,7 +1275,7 @@ noncomputable def gcdMonoidOfExistsGCD [DecidableEq α] fun {a b c} ac ab => (Classical.choose_spec (h c b) a).1 ⟨ac, ab⟩ /-- Define a `NormalizedGCDMonoid` structure on a monoid just from the existence of a `gcd`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def normalizedGCDMonoidOfExistsGCD [NormalizationMonoid α] [DecidableEq α] (h : ∀ a b : α, ∃ c : α, ∀ d : α, d ∣ a ∧ d ∣ b ↔ d ∣ c) : NormalizedGCDMonoid α := normalizedGCDMonoidOfGCD (fun a b => normalize (Classical.choose (h a b))) @@ -1310,7 +1310,7 @@ theorem nonempty_strongNormalizedGCDMonoid_iff {α} [CommMonoidWithZero α] : ⟨strongNormalizedGCDMonoidOfExistsGCD fun _ _ ↦ ⟨_, fun _ ↦ (dvd_gcd_iff ..).symm⟩⟩⟩ /-- Define a `GCDMonoid` structure on a monoid just from the existence of an `lcm`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def gcdMonoidOfExistsLCM [DecidableEq α] (h : ∀ a b : α, ∃ c : α, ∀ d : α, a ∣ d ∧ b ∣ d ↔ c ∣ d) : GCDMonoid α := gcdMonoidOfLCM (fun a b => Classical.choose (h a b)) @@ -1319,7 +1319,7 @@ noncomputable def gcdMonoidOfExistsLCM [DecidableEq α] fun {a b c} ac ab => (Classical.choose_spec (h c b) a).1 ⟨ac, ab⟩ /-- Define a `NormalizedGCDMonoid` structure on a monoid just from the existence of an `lcm`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def normalizedGCDMonoidOfExistsLCM [NormalizationMonoid α] [DecidableEq α] (h : ∀ a b : α, ∃ c : α, ∀ d : α, a ∣ d ∧ b ∣ d ↔ c ∣ d) : NormalizedGCDMonoid α := normalizedGCDMonoidOfLCM (fun a b => normalize (Classical.choose (h a b))) diff --git a/Mathlib/Algebra/GradedMonoid.lean b/Mathlib/Algebra/GradedMonoid.lean index e979eb59e8d2e8..3a58bc08dfdf24 100644 --- a/Mathlib/Algebra/GradedMonoid.lean +++ b/Mathlib/Algebra/GradedMonoid.lean @@ -416,6 +416,7 @@ theorem GradedMonoid.mk_list_dProd (l : List α) (fι : α → ι) (fA : ∀ a, | head::tail => simp [← GradedMonoid.mk_list_dProd tail _ _, GradedMonoid.mk_mul_mk, List.prod_cons] +set_option backward.isDefEq.respectTransparency false in /-- A variant of `GradedMonoid.mk_list_dProd` for rewriting in the other direction. -/ theorem GradedMonoid.list_prod_map_eq_dProd (l : List α) (f : α → GradedMonoid A) : (l.map f).prod = GradedMonoid.mk _ (l.dProd (fun i => (f i).1) fun i => (f i).2) := by diff --git a/Mathlib/Algebra/Group/Action/Basic.lean b/Mathlib/Algebra/Group/Action/Basic.lean index c414d3ab2fdfc8..7990462bc9f6b7 100644 --- a/Mathlib/Algebra/Group/Action/Basic.lean +++ b/Mathlib/Algebra/Group/Action/Basic.lean @@ -95,7 +95,7 @@ section Arrow variable {G A B : Type*} [DivisionMonoid G] [MulAction G A] /-- If `G` acts on `A`, then it acts also on `A → B`, by `(g • F) a = F (g⁻¹ • a)`. -/ -@[to_additive (attr := implicit_reducible, simps) arrowAddAction +@[to_additive (attr := instance_reducible, simps) arrowAddAction /-- If `G` acts on `A`, then it acts also on `A → B`, by `(g +ᵥ F) a = F (g⁻¹ +ᵥ a)` -/] def arrowAction : MulAction G (A → B) where smul g F a := F (g⁻¹ • a) @@ -111,7 +111,7 @@ attribute [local instance] arrowAction variable [Monoid M] /-- When `M` is a monoid, `ArrowAction` is additionally a `MulDistribMulAction`. -/ -@[implicit_reducible] +@[instance_reducible] def arrowMulDistribMulAction : MulDistribMulAction G (A → M) where smul_one _ := rfl smul_mul _ _ _ := rfl diff --git a/Mathlib/Algebra/Group/Action/Pointwise/Finset.lean b/Mathlib/Algebra/Group/Action/Pointwise/Finset.lean index 2a7468e8f5fd28..a1ce1fe211cb3b 100644 --- a/Mathlib/Algebra/Group/Action/Pointwise/Finset.lean +++ b/Mathlib/Algebra/Group/Action/Pointwise/Finset.lean @@ -79,7 +79,7 @@ instance isCentralScalar [SMul α β] [SMul αᵐᵒᵖ β] [IsCentralScalar α /-- A multiplicative action of a monoid `α` on a type `β` gives a multiplicative action of `Finset α` on `Finset β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive action of an additive monoid `α` on a type `β` gives an additive action of `Finset α` on `Finset β` -/] protected def mulAction [DecidableEq α] [Monoid α] [MulAction α β] : @@ -89,7 +89,7 @@ protected def mulAction [DecidableEq α] [Monoid α] [MulAction α β] : /-- A multiplicative action of a monoid on a type `β` gives a multiplicative action on `Finset β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive action of an additive monoid on a type `β` gives an additive action on `Finset β`. -/] protected def mulActionFinset [Monoid α] [MulAction α β] : MulAction α (Finset β) := diff --git a/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean index 1bb6da47788c48..4431b953987b0d 100644 --- a/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean @@ -168,7 +168,7 @@ instance isCentralScalar [SMul α β] [SMul αᵐᵒᵖ β] [IsCentralScalar α /-- A multiplicative action of a monoid `α` on a type `β` gives a multiplicative action of `Set α` on `Set β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive action of an additive monoid `α` on a type `β` gives an additive action of `Set α` on `Set β` -/] protected noncomputable def mulAction [Monoid α] [MulAction α β] : MulAction (Set α) (Set β) where @@ -176,7 +176,7 @@ protected noncomputable def mulAction [Monoid α] [MulAction α β] : MulAction one_smul s := image2_singleton_left.trans <| by simp_rw [one_smul, image_id'] /-- A multiplicative action of a monoid on a type `β` gives a multiplicative action on `Set β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive action of an additive monoid on a type `β` gives an additive action on `Set β`. -/] protected def mulActionSet [Monoid α] [MulAction α β] : MulAction α (Set β) where mul_smul _ _ _ := by simp only [← image_smul, image_image, ← mul_smul] diff --git a/Mathlib/Algebra/Group/Conj.lean b/Mathlib/Algebra/Group/Conj.lean index 691ab9ca1ead6b..c71fa9e5fcdc8f 100644 --- a/Mathlib/Algebra/Group/Conj.lean +++ b/Mathlib/Algebra/Group/Conj.lean @@ -230,6 +230,7 @@ theorem mk_injective : Function.Injective (@ConjClasses.mk α _) := fun _ _ => theorem mk_bijective : Function.Bijective (@ConjClasses.mk α _) := ⟨mk_injective, mk_surjective⟩ +set_option backward.isDefEq.respectTransparency false in /-- The bijection between a `CommGroup` and its `ConjClasses`. -/ @[to_additive /-- The bijection between an `AddCommGroup` and its `AddConjClasses`. -/] def mkEquiv : α ≃ ConjClasses α := diff --git a/Mathlib/Algebra/Group/End.lean b/Mathlib/Algebra/Group/End.lean index 9c3dabedf1513b..d097f727d007bf 100644 --- a/Mathlib/Algebra/Group/End.lean +++ b/Mathlib/Algebra/Group/End.lean @@ -410,6 +410,7 @@ private theorem pow_aux (hf : ∀ x, p (f x) ↔ p x) : ∀ {n : ℕ} (x), p ((f | 0, _ => Iff.rfl | _ + 1, _ => (pow_aux hf (f _)).trans (hf _) +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in @[simp] @@ -469,6 +470,7 @@ theorem ofSubtype_apply_mem_iff_mem (f : Perm (Subtype p)) (x : α) : simpa only [h, iff_true, MonoidHom.coe_mk, ofSubtype_apply_of_mem f h] using (f ⟨x, h⟩).2 else by simp [h, ofSubtype_apply_of_not_mem f h] +set_option backward.isDefEq.respectTransparency false in theorem ofSubtype_injective : Function.Injective (ofSubtype : Perm (Subtype p) → Perm α) := by intro x y h rw [Perm.ext_iff] at h ⊢ diff --git a/Mathlib/Algebra/Group/Finsupp.lean b/Mathlib/Algebra/Group/Finsupp.lean index 984d91328bb8f8..3d4cdeca1bd839 100644 --- a/Mathlib/Algebra/Group/Finsupp.lean +++ b/Mathlib/Algebra/Group/Finsupp.lean @@ -176,6 +176,7 @@ lemma support_single_add_single_subset [DecidableEq ι] {f₁ f₂ : ι} {g₁ g refine subset_trans Finsupp.support_add <| union_subset_iff.mpr ⟨?_, ?_⟩ <;> exact subset_trans Finsupp.support_single_subset (by simp) +set_option backward.isDefEq.respectTransparency false in @[deprecated uniqueAddEquiv_symm_apply (since := "2026-05-06")] lemma _root_.AddEquiv.finsuppUnique_symm {M : Type*} [AddZeroClass M] (d : M) : AddEquiv.finsuppUnique.symm d = single () d := by ext; simp [AddEquiv.finsuppUnique] diff --git a/Mathlib/Algebra/Group/Hom/Basic.lean b/Mathlib/Algebra/Group/Hom/Basic.lean index 94b3d51bf17eb8..45fb02c63c31d7 100644 --- a/Mathlib/Algebra/Group/Hom/Basic.lean +++ b/Mathlib/Algebra/Group/Hom/Basic.lean @@ -302,13 +302,13 @@ lemma comp_div (f : G →* H) (g h : M →* G) : f.comp (g / h) = f.comp g / f.c end InvDiv /-- If `H` is commutative and `G →* H` is injective, then `G` is commutative. -/ -@[implicit_reducible] +@[instance_reducible] def commGroupOfInjective [Group G] [CommGroup H] (f : G →* H) (hf : Function.Injective f) : CommGroup G := ⟨by simp_rw [← hf.eq_iff, map_mul, mul_comm, implies_true]⟩ /-- If `G` is commutative and `G →* H` is surjective, then `H` is commutative. -/ -@[implicit_reducible] +@[instance_reducible] def commGroupOfSurjective [CommGroup G] [Group H] (f : G →* H) (hf : Function.Surjective f) : CommGroup H := ⟨by simp_rw [hf.forall₂, ← map_mul, mul_comm, implies_true]⟩ diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index ce2308887eb5da..5aa3b8cc69dd75 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -731,21 +731,21 @@ instance {M N : Type*} [Monoid M] [CancelMonoid N] : MonoidHomClass (M →ₙ* N end MonoidHom /-- The identity map from a type with 1 to itself. -/ -@[to_additive (attr := simps, implicit_reducible) +@[to_additive (attr := simps, instance_reducible) /-- The identity map from a type with zero to itself. -/] def OneHom.id (M : Type*) [One M] : OneHom M M where toFun x := x map_one' := rfl /-- The identity map from a type with multiplication to itself. -/ -@[to_additive (attr := simps, implicit_reducible) +@[to_additive (attr := simps, instance_reducible) /-- The identity map from a type with addition to itself. -/] def MulHom.id (M : Type*) [Mul M] : M →ₙ* M where toFun x := x map_mul' _ _ := rfl /-- The identity map from a monoid to itself. -/ -@[to_additive (attr := simps, implicit_reducible) +@[to_additive (attr := simps, instance_reducible) /-- The identity map from an additive monoid to itself. -/] def MonoidHom.id (M : Type*) [MulOne M] : M →* M where toFun x := x @@ -762,19 +762,19 @@ lemma MulHom.coe_id {M : Type*} [Mul M] : (MulHom.id M : M → M) = _root_.id := lemma MonoidHom.coe_id {M : Type*} [MulOne M] : (MonoidHom.id M : M → M) = _root_.id := rfl /-- Composition of `OneHom`s as a `OneHom`. -/ -@[to_additive (attr := implicit_reducible) /-- Composition of `ZeroHom`s as a `ZeroHom`. -/] +@[to_additive (attr := instance_reducible) /-- Composition of `ZeroHom`s as a `ZeroHom`. -/] def OneHom.comp [One M] [One N] [One P] (hnp : OneHom N P) (hmn : OneHom M N) : OneHom M P where toFun x := hnp (hmn x) map_one' := by simp /-- Composition of `MulHom`s as a `MulHom`. -/ -@[to_additive (attr := implicit_reducible) /-- Composition of `AddHom`s as an `AddHom`. -/] +@[to_additive (attr := instance_reducible) /-- Composition of `AddHom`s as an `AddHom`. -/] def MulHom.comp [Mul M] [Mul N] [Mul P] (hnp : N →ₙ* P) (hmn : M →ₙ* N) : M →ₙ* P where toFun x := hnp (hmn x) map_mul' x y := by simp /-- Composition of monoid morphisms as a monoid morphism. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Composition of additive monoid morphisms as an additive monoid morphism. -/] def MonoidHom.comp [MulOne M] [MulOne N] [MulOne P] (hnp : N →* P) (hmn : M →* N) : M →* P where diff --git a/Mathlib/Algebra/Group/Invertible/Basic.lean b/Mathlib/Algebra/Group/Invertible/Basic.lean index c3bdb9985fe699..dd782dfcc428e8 100644 --- a/Mathlib/Algebra/Group/Invertible/Basic.lean +++ b/Mathlib/Algebra/Group/Invertible/Basic.lean @@ -51,7 +51,7 @@ theorem IsUnit.nonempty_invertible [Monoid α] {a : α} (h : IsUnit a) : Nonempt /-- Convert `IsUnit` to `Invertible` using `Classical.choice`. Prefer `casesI h.nonempty_invertible` over `letI := h.invertible` if you want to avoid choice. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def IsUnit.invertible [Monoid α] {a : α} (h : IsUnit a) : Invertible a := Classical.choice h.nonempty_invertible @@ -123,7 +123,7 @@ lemma invOf_pow (m : α) [Invertible m] (n : ℕ) [Invertible (m ^ n)] : ⅟(m ^ @invertible_unique _ _ _ _ _ (invertiblePow m n) rfl /-- If `x ^ n = 1` then `x` has an inverse, `x^(n - 1)`. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfPowEqOne (x : α) (n : ℕ) (hx : x ^ n = 1) (hn : n ≠ 0) : Invertible x := inferInstanceAs <| Invertible (Units.ofPowEqOne x n hx hn : α) @@ -131,7 +131,7 @@ end Monoid /-- Monoid homs preserve invertibility. -/ -@[implicit_reducible] +@[instance_reducible] def Invertible.map {R : Type*} {S : Type*} {F : Type*} [MulOneClass R] [MulOneClass S] [FunLike F R S] [MonoidHomClass F R S] (f : F) (r : R) [Invertible r] : Invertible (f r) where @@ -151,7 +151,7 @@ theorem map_invOf {R : Type*} {S : Type*} {F : Type*} [MulOneClass R] [Monoid S] then `r : R` is invertible if `f r` is. The inverse is computed as `g (⅟(f r))` -/ -@[simps! -isSimp, implicit_reducible] +@[simps! -isSimp, instance_reducible] def Invertible.ofLeftInverse {R : Type*} {S : Type*} {G : Type*} [MulOneClass R] [MulOneClass S] [FunLike G S R] [MonoidHomClass G S R] (f : R → S) (g : G) (r : R) (h : Function.LeftInverse g f) [Invertible (f r)] : Invertible r := diff --git a/Mathlib/Algebra/Group/Invertible/Defs.lean b/Mathlib/Algebra/Group/Invertible/Defs.lean index 63e1a5e82f456a..2d1673614e51a0 100644 --- a/Mathlib/Algebra/Group/Invertible/Defs.lean +++ b/Mathlib/Algebra/Group/Invertible/Defs.lean @@ -179,7 +179,7 @@ theorem Invertible.congr [Invertible a] [Invertible b] (h : a = b) : end Monoid /-- If `r` is invertible and `s = r` and `si = ⅟r`, then `s` is invertible with `⅟s = si`. -/ -@[implicit_reducible] +@[instance_reducible] def Invertible.copy' [MulOneClass α] {r : α} (hr : Invertible r) (s : α) (si : α) (hs : s = r) (hsi : si = ⅟r) : Invertible s where invOf := si @@ -192,7 +192,7 @@ abbrev Invertible.copy [MulOneClass α] {r : α} (hr : Invertible r) (s : α) (h hr.copy' _ _ hs rfl /-- Each element of a group is invertible. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfGroup [Group α] (a : α) : Invertible a := ⟨a⁻¹, inv_mul_cancel a, mul_inv_cancel a⟩ @@ -201,7 +201,7 @@ theorem invOf_eq_group_inv [Group α] (a : α) [Invertible a] : ⅟a = a⁻¹ := invOf_eq_right_inv (mul_inv_cancel a) /-- `1` is the inverse of itself -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOne [Monoid α] : Invertible (1 : α) := ⟨1, mul_one _, one_mul _⟩ @@ -224,7 +224,7 @@ theorem invOf_inj [Monoid α] {a b : α} [Invertible a] [Invertible b] : ⅟a = ⟨invertible_unique _ _, invertible_unique _ _⟩ /-- `⅟b * ⅟a` is the inverse of `a * b` -/ -@[implicit_reducible] +@[instance_reducible] def invertibleMul [Monoid α] (a b : α) [Invertible a] [Invertible b] : Invertible (a * b) := ⟨⅟b * ⅟a, by simp [← mul_assoc], by simp [← mul_assoc]⟩ @@ -264,12 +264,12 @@ theorem mul_right_eq_iff_eq_mul_invOf : a * c = b ↔ a = b * ⅟c := by variable [IsDedekindFiniteMonoid α] (a b : α) /-- An element in a Dedekind-finite monoid is invertible if it has a left inverse. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfLeftInverse (h : b * a = 1) : Invertible a := ⟨b, h, mul_eq_one_symm h⟩ /-- An element in a Dedekind-finite monoid is invertible if it has a right inverse. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfRightInverse (h : a * b = 1) : Invertible a := ⟨b, mul_eq_one_symm h, h⟩ diff --git a/Mathlib/Algebra/Group/Pi/Basic.lean b/Mathlib/Algebra/Group/Pi/Basic.lean index 644bea1dc47db9..1b4e34b84ed51f 100644 --- a/Mathlib/Algebra/Group/Pi/Basic.lean +++ b/Mathlib/Algebra/Group/Pi/Basic.lean @@ -198,7 +198,7 @@ lemma comp_ne_one_iff [One β] [One γ] (f : α → β) {g : β → γ} (hg : In end Function /-- If the one function is surjective, the codomain is trivial. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If the zero function is surjective, the codomain is trivial. -/] def uniqueOfSurjectiveOne (α : Type*) {β : Type*} [One β] (h : Function.Surjective (1 : α → β)) : Unique β := diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index bd48fb945910d2..4bb215a376f6db 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean @@ -66,7 +66,7 @@ section One variable [One α] {s : Finset α} {a : α} /-- The finset `1 : Finset α` is defined as `{1}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The finset `0 : Finset α` is defined as `{0}` in scope `Pointwise`. -/] protected def one : One (Finset α) := ⟨{1}⟩ @@ -184,7 +184,7 @@ section Inv variable [DecidableEq α] [Inv α] {s t : Finset α} {a : α} /-- The pointwise inversion of finset `s⁻¹` is defined as `{x⁻¹ | x ∈ s}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise negation of finset `-s` is defined as `{-x | x ∈ s}` in scope `Pointwise`. -/] protected def inv : Inv (Finset α) := ⟨image Inv.inv⟩ @@ -317,7 +317,7 @@ variable [DecidableEq α] [Mul α] [Mul β] [FunLike F α β] [MulHomClass F α /-- The pointwise multiplication of finsets `s * t` and `t` is defined as `{x * y | x ∈ s, y ∈ t}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise addition of finsets `s + t` is defined as `{x + y | x ∈ s, y ∈ t}` in scope `Pointwise`. -/] protected def mul : Mul (Finset α) := @@ -536,7 +536,7 @@ variable [DecidableEq α] [Div α] {s s₁ s₂ t t₁ t₂ u : Finset α} {a b /-- The pointwise division of finsets `s / t` is defined as `{x / y | x ∈ s, y ∈ t}` in locale `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise subtraction of finsets `s - t` is defined as `{x - y | x ∈ s, y ∈ t}` in scope `Pointwise`. -/] protected def div : Div (Finset α) := @@ -714,7 +714,7 @@ protected def zpow [One α] [Mul α] [Inv α] : Pow (Finset α) ℤ := scoped[Pointwise] attribute [instance] Finset.nsmul Finset.npow Finset.zsmul Finset.zpow /-- `Finset α` is a `Semigroup` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Finset α` is an `AddSemigroup` under pointwise operations if `α` is. -/] protected def semigroup [Semigroup α] : Semigroup (Finset α) := coe_injective.semigroup _ coe_mul @@ -724,7 +724,7 @@ section CommSemigroup variable [CommSemigroup α] {s t : Finset α} /-- `Finset α` is a `CommSemigroup` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Finset α` is an `AddCommSemigroup` under pointwise operations if `α` is. -/] protected def commSemigroup : CommSemigroup (Finset α) := coe_injective.commSemigroup _ coe_mul @@ -744,7 +744,7 @@ section MulOneClass variable [MulOneClass α] /-- `Finset α` is a `MulOneClass` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Finset α` is an `AddZeroClass` under pointwise operations if `α` is. -/] protected def mulOneClass : MulOneClass (Finset α) := coe_injective.mulOneClass _ (coe_singleton 1) coe_mul @@ -808,7 +808,7 @@ theorem coe_pow (s : Finset α) (n : ℕ) : ↑(s ^ n) = (s : Set α) ^ n := by | succ n ih => rw [npowRec, pow_succ, coe_mul, ih] /-- `Finset α` is a `Monoid` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Finset α` is an `AddMonoid` under pointwise operations if `α` is. -/] protected def monoid : Monoid (Finset α) := coe_injective.monoid _ coe_one coe_mul coe_pow @@ -934,7 +934,7 @@ section CommMonoid variable [CommMonoid α] /-- `Finset α` is a `CommMonoid` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Finset α` is an `AddCommMonoid` under pointwise operations if `α` is. -/] protected def commMonoid : CommMonoid (Finset α) := coe_injective.commMonoid _ coe_one coe_mul coe_pow @@ -959,7 +959,7 @@ protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = {a} ∧ t = {b} simp_rw [← coe_inj, coe_mul, coe_one, Set.mul_eq_one_iff, coe_singleton] /-- `Finset α` is a division monoid under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Finset α` is a subtraction monoid under pointwise operations if `α` is. -/] protected def divisionMonoid : DivisionMonoid (Finset α) := coe_injective.divisionMonoid _ coe_one coe_mul coe_inv coe_div coe_pow coe_zpow @@ -1013,7 +1013,7 @@ lemma singleton_zpow (a : α) (n : ℤ) : ({a} : Finset α) ^ n = {a ^ n} := by end DivisionMonoid /-- `Finset α` is a commutative division monoid under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) subtractionCommMonoid +@[to_additive (attr := instance_reducible) subtractionCommMonoid /-- `Finset α` is a commutative subtraction monoid under pointwise operations if `α` is. -/] protected def divisionCommMonoid [DivisionCommMonoid α] : DivisionCommMonoid (Finset α) := diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean index 1e97e9c0f6849b..fc380aa9b54e2e 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean @@ -63,7 +63,7 @@ section SMul variable [DecidableEq β] [SMul α β] {s s₁ s₂ : Finset α} {t t₁ t₂ u : Finset β} {a : α} {b : β} /-- The pointwise product of two finsets `s` and `t`: `s • t = {x • y | x ∈ s, y ∈ t}`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise sum of two finsets `s` and `t`: `s +ᵥ t = {x +ᵥ y | x ∈ s, y ∈ t}`. -/] protected def smul : SMul (Finset α) (Finset β) := ⟨image₂ (· • ·)⟩ @@ -153,7 +153,7 @@ section SMul variable [DecidableEq β] [SMul α β] {s s₁ s₂ t : Finset β} {a : α} {b : β} /-- The scaling of a finset `s` by a scalar `a`: `a • s = {a • x | x ∈ s}`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The translation of a finset `s` by a vector `a`: `a +ᵥ s = {a +ᵥ x | x ∈ s}`. -/] protected def smulFinset : SMul α (Finset β) where smul a := image <| (a • ·) diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean index 1b733efbea028f..16b7b3e0ef6e9a 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean @@ -78,7 +78,7 @@ section One variable [One α] {s : Set α} {a : α} /-- The set `1 : Set α` is defined as `{1}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The set `0 : Set α` is defined as `{0}` in scope `Pointwise`. -/] protected def one : One (Set α) := ⟨{1}⟩ @@ -144,7 +144,7 @@ section Inv /-- The pointwise inversion of set `s⁻¹` is defined as `{x | x⁻¹ ∈ s}` in scope `Pointwise`. It is equal to `{x⁻¹ | x ∈ s}`, see `Set.image_inv_eq_inv`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise negation of set `-s` is defined as `{x | -x ∈ s}` in scope `Pointwise`. It is equal to `{-x | x ∈ s}`, see `Set.image_neg_eq_neg`. -/] protected def inv [Inv α] : Inv (Set α) := @@ -290,7 +290,7 @@ variable {ι : Sort*} {κ : ι → Sort*} [Mul α] {s s₁ s₂ t t₁ t₂ u : /-- The pointwise multiplication of sets `s * t` and `t` is defined as `{x * y | x ∈ s, y ∈ t}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise addition of sets `s + t` is defined as `{x + y | x ∈ s, y ∈ t}` in locale `Pointwise`. -/] protected def mul : Mul (Set α) := @@ -432,7 +432,7 @@ variable {ι : Sort*} {κ : ι → Sort*} [Div α] {s s₁ s₂ t t₁ t₂ u : /-- The pointwise division of sets `s / t` is defined as `{x / y | x ∈ s, y ∈ t}` in locale `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise subtraction of sets `s - t` is defined as `{x - y | x ∈ s, y ∈ t}` in locale `Pointwise`. -/] protected def div : Div (Set α) := @@ -562,7 +562,7 @@ protected def ZPow [One α] [Mul α] [Inv α] : Pow (Set α) ℤ := scoped[Pointwise] attribute [instance] Set.NSMul Set.NPow Set.ZSMul Set.ZPow /-- `Set α` is a `Semigroup` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Set α` is an `AddSemigroup` under pointwise operations if `α` is. -/] protected def semigroup [Semigroup α] : Semigroup (Set α) := { Set.mul with mul_assoc := fun _ _ _ => image2_assoc mul_assoc } @@ -572,7 +572,7 @@ section CommSemigroup variable [CommSemigroup α] {s t : Set α} /-- `Set α` is a `CommSemigroup` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Set α` is an `AddCommSemigroup` under pointwise operations if `α` is. -/] protected def commSemigroup : CommSemigroup (Set α) := { Set.semigroup with mul_comm := fun _ _ => image2_comm mul_comm } @@ -592,7 +592,7 @@ section MulOneClass variable [MulOneClass α] /-- `Set α` is a `MulOneClass` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Set α` is an `AddZeroClass` under pointwise operations if `α` is. -/] protected def mulOneClass : MulOneClass (Set α) := { Set.one, Set.mul with @@ -632,7 +632,7 @@ section Monoid variable [Monoid α] {s t : Set α} {a : α} {m n : ℕ} /-- `Set α` is a `Monoid` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Set α` is an `AddMonoid` under pointwise operations if `α` is. -/] protected def monoid : Monoid (Set α) := { Set.semigroup, Set.mulOneClass, @Set.NPow α _ _ with } @@ -759,7 +759,7 @@ lemma Nontrivial.pow (hs : s.Nontrivial) : ∀ {n}, n ≠ 0 → (s ^ n).Nontrivi end CancelMonoid /-- `Set α` is a `CommMonoid` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Set α` is an `AddCommMonoid` under pointwise operations if `α` is. -/] protected def commMonoid [CommMonoid α] : CommMonoid (Set α) := { Set.monoid, Set.commSemigroup with } @@ -795,7 +795,7 @@ protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = {a} ∧ t = {b} rw [← nonempty_inv, inter_inv]; simp_rw [← image_inv_eq_inv, image_image, mul_inv_rev, inv_inv] /-- `Set α` is a division monoid under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Set α` is a subtraction monoid under pointwise operations if `α` is. -/] protected def divisionMonoid : DivisionMonoid (Set α) := { Set.monoid, Set.involutiveInv, Set.div, @Set.ZPow α _ _ _ with @@ -854,7 +854,7 @@ lemma singleton_zpow (a : α) (n : ℤ) : ({a} : Set α) ^ n = {a ^ n} := by cas end DivisionMonoid /-- `Set α` is a commutative division monoid under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) subtractionCommMonoid +@[to_additive (attr := instance_reducible) subtractionCommMonoid /-- `Set α` is a commutative subtraction monoid under pointwise operations if `α` is. -/] protected def divisionCommMonoid [DivisionCommMonoid α] : DivisionCommMonoid (Set α) := diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Scalar.lean b/Mathlib/Algebra/Group/Pointwise/Set/Scalar.lean index b0b7ea34271069..cf7de00d2cf20f 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Scalar.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Scalar.lean @@ -66,13 +66,13 @@ namespace Set section SMul /-- The dilation of set `x • s` is defined as `{x • y | y ∈ s}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The translation of set `x +ᵥ s` is defined as `{x +ᵥ y | y ∈ s}` in scope `Pointwise`. -/] protected def smulSet [SMul α β] : SMul α (Set β) where smul a := image (a • ·) /-- The pointwise scalar multiplication of sets `s • t` is defined as `{x • y | x ∈ s, y ∈ t}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The pointwise scalar addition of sets `s +ᵥ t` is defined as `{x +ᵥ y | x ∈ s, y ∈ t}` in locale `Pointwise`. -/] protected def smul [SMul α β] : SMul (Set α) (Set β) where smul := image2 (· • ·) diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 812e977e3439de..66e94cd9c1cebd 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -830,6 +830,7 @@ def liftOfRightInverseAux (hf : Function.RightInverse f_inv f) (g : G₁ →* G rw [f.mem_ker, f.map_mul, f.map_inv, mul_inv_eq_one, f.map_mul] simp only [hf _] +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem liftOfRightInverseAux_comp_apply (hf : Function.RightInverse f_inv f) (g : G₁ →* G₃) (hg : f.ker ≤ g.ker) (x : G₁) : (f.liftOfRightInverseAux f_inv hf g hg) (f x) = g x := by @@ -937,6 +938,7 @@ instance (priority := 100) normal_subgroupOf {H N : Subgroup G} [N.Normal] : (N.subgroupOf H).Normal := Subgroup.normal_comap _ +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem comap_normalClosure_image_ge (s : Set G) (f : G →* N) : (normalClosure s) ≤ (normalClosure (f '' s)).comap f := by @@ -1077,6 +1079,7 @@ namespace IsConj open Subgroup +set_option backward.isDefEq.respectTransparency false in theorem normalClosure_eq_top_of {N : Subgroup G} [hn : N.Normal] {g g' : G} {hg : g ∈ N} {hg' : g' ∈ N} (hc : IsConj g g') (ht : normalClosure ({⟨g, hg⟩} : Set N) = ⊤) : normalClosure ({⟨g', hg'⟩} : Set N) = ⊤ := by diff --git a/Mathlib/Algebra/Group/Subgroup/Ker.lean b/Mathlib/Algebra/Group/Subgroup/Ker.lean index 17796f56170410..e67add089fe1fa 100644 --- a/Mathlib/Algebra/Group/Subgroup/Ker.lean +++ b/Mathlib/Algebra/Group/Subgroup/Ker.lean @@ -300,6 +300,7 @@ theorem ker_one : (1 : G →* M).ker = ⊤ := theorem ker_id : (MonoidHom.id G).ker = ⊥ := rfl +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem ker_eq_top_iff {f : G →* M} : f.ker = ⊤ ↔ f = 1 := by simp [ker, ← top_le_iff, SetLike.le_def, f.ext_iff] @@ -517,6 +518,7 @@ theorem map_subtype_le_map_subtype {G' : Subgroup G} {H K : Subgroup G'} : H.map G'.subtype ≤ K.map G'.subtype ↔ H ≤ K := map_le_map_iff_of_injective G'.subtype_injective +set_option backward.isDefEq.respectTransparency false in /-- Subgroups of the subgroup `H` are considered as subgroups that are less than or equal to `H`. -/ @[to_additive (attr := simps apply_coe) /-- Additive subgroups of the subgroup `H` are considered as diff --git a/Mathlib/Algebra/Group/Subgroup/Map.lean b/Mathlib/Algebra/Group/Subgroup/Map.lean index 5946958e6bda6c..18e5b603b44325 100644 --- a/Mathlib/Algebra/Group/Subgroup/Map.lean +++ b/Mathlib/Algebra/Group/Subgroup/Map.lean @@ -393,6 +393,7 @@ end Subgroup namespace MulEquiv variable {H : Type*} [Group H] +set_option backward.isDefEq.respectTransparency false in /-- An isomorphism of groups gives an order isomorphism between the lattices of subgroups, defined by sending subgroups to their inverse images. @@ -419,6 +420,7 @@ lemma coe_comapSubgroup (e : G ≃* H) : comapSubgroup e = Subgroup.comap e.toMo @[to_additive (attr := simp)] lemma symm_comapSubgroup (e : G ≃* H) : (comapSubgroup e).symm = comapSubgroup e.symm := rfl +set_option backward.isDefEq.respectTransparency false in /-- An isomorphism of groups gives an order isomorphism between the lattices of subgroups, defined by sending subgroups to their forward images. diff --git a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean index 8f1f0a2c036a8a..056d5154d9d5b0 100644 --- a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean +++ b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean @@ -552,6 +552,7 @@ theorem Normal.of_conjugate_fixed {H : Subgroup G} (h : ∀ g : G, (MulAut.conj ← mul_assoc, inv_mul_cancel, one_mul] exact hn +set_option backward.isDefEq.respectTransparency false in theorem normalCore_eq_iInf_conjAct (H : Subgroup G) : H.normalCore = ⨅ (g : ConjAct G), g • H := by ext g diff --git a/Mathlib/Algebra/Group/Subgroup/ZPowers/Basic.lean b/Mathlib/Algebra/Group/Subgroup/ZPowers/Basic.lean index 5440c705af0fc6..a0e1738206669b 100644 --- a/Mathlib/Algebra/Group/Subgroup/ZPowers/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/ZPowers/Basic.lean @@ -111,6 +111,7 @@ namespace Subgroup variable {s : Set G} {g : G} +set_option backward.isDefEq.respectTransparency false in @[to_additive] instance zpowers_isMulCommutative (g : G) : IsMulCommutative (zpowers g) := ⟨⟨fun ⟨_, _, h₁⟩ ⟨_, _, h₂⟩ ↦ by simp [← h₁, ← h₂, zpow_mul_comm]⟩⟩ diff --git a/Mathlib/Algebra/Group/Submonoid/Operations.lean b/Mathlib/Algebra/Group/Submonoid/Operations.lean index d498ccecce2a86..40db10c2cc5728 100644 --- a/Mathlib/Algebra/Group/Submonoid/Operations.lean +++ b/Mathlib/Algebra/Group/Submonoid/Operations.lean @@ -798,6 +798,7 @@ theorem comap_bot' (f : F) : (⊥ : Submonoid N).comap f = mker f := theorem restrict_mker (f : M →* N) : mker (f.restrict S) = (MonoidHom.mker f).comap S.subtype := rfl +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem mrangeRestrict_mker (f : M →* N) : mker (mrangeRestrict f) = mker f := by ext x @@ -1122,6 +1123,7 @@ section Units namespace Submonoid +set_option backward.isDefEq.respectTransparency false in /-- The multiplicative equivalence between the type of units of `M` and the submonoid of unit elements of `M`. -/ @[to_additive (attr := simps!) /-- The additive equivalence between the type of additive units of diff --git a/Mathlib/Algebra/Group/Submonoid/Pointwise.lean b/Mathlib/Algebra/Group/Submonoid/Pointwise.lean index f3c3a07ab3a768..e2c09a095bacfa 100644 --- a/Mathlib/Algebra/Group/Submonoid/Pointwise.lean +++ b/Mathlib/Algebra/Group/Submonoid/Pointwise.lean @@ -127,7 +127,7 @@ theorem pow_smul_mem_closure_smul {N : Type*} [CommMonoid N] [MulAction M N] [Is variable [Group G] /-- The submonoid with every element inverted. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The additive submonoid with every element negated. -/] protected def inv : Inv (Submonoid G) where inv S := @@ -146,7 +146,7 @@ theorem mem_inv {g : G} {S : Submonoid G} : g ∈ S⁻¹ ↔ g⁻¹ ∈ S := Iff.rfl /-- Inversion is involutive on submonoids. -/ -@[to_additive (attr := implicit_reducible) /-- Inversion is involutive on additive submonoids. -/] +@[to_additive (attr := instance_reducible) /-- Inversion is involutive on additive submonoids. -/] def involutiveInv : InvolutiveInv (Submonoid G) := SetLike.coe_injective.involutiveInv _ fun _ => rfl diff --git a/Mathlib/Algebra/Group/Units/Defs.lean b/Mathlib/Algebra/Group/Units/Defs.lean index cf0954d8c353ad..df6228899a2fbb 100644 --- a/Mathlib/Algebra/Group/Units/Defs.lean +++ b/Mathlib/Algebra/Group/Units/Defs.lean @@ -636,12 +636,12 @@ section NoncomputableDefs variable {M : Type*} /-- Constructs an inv operation for a `Monoid` consisting only of units. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def invOfIsUnit [Monoid M] (h : ∀ a : M, IsUnit a) : Inv M where inv := fun a => ↑(h a).unit⁻¹ /-- Constructs a `Group` structure on a `Monoid` consisting only of units. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def groupOfIsUnit [hM : Monoid M] (h : ∀ a : M, IsUnit a) : Group M := { hM with toInv := invOfIsUnit h, @@ -650,7 +650,7 @@ noncomputable def groupOfIsUnit [hM : Monoid M] (h : ∀ a : M, IsUnit a) : Grou rw [Units.inv_mul_eq_iff_eq_mul, (h a).unit_spec, mul_one] } /-- Constructs a `CommGroup` structure on a `CommMonoid` consisting only of units. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def commGroupOfIsUnit [hM : CommMonoid M] (h : ∀ a : M, IsUnit a) : CommGroup M := { hM with toInv := invOfIsUnit h, diff --git a/Mathlib/Algebra/Group/WithOne/Basic.lean b/Mathlib/Algebra/Group/WithOne/Basic.lean index 165315cf6d0ddc..ce147eefed87c6 100644 --- a/Mathlib/Algebra/Group/WithOne/Basic.lean +++ b/Mathlib/Algebra/Group/WithOne/Basic.lean @@ -31,6 +31,7 @@ variable {α : Type u} {β : Type v} {γ : Type w} namespace WithOne +set_option backward.isDefEq.respectTransparency false in @[to_additive] instance instInvolutiveInv [InvolutiveInv α] : InvolutiveInv (WithOne α) where inv_inv a := (Option.map_map _ _ _).trans <| by simp_rw [inv_comp_inv, Option.map_id, id] diff --git a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean index a190d119283050..25971ff5f2c0f1 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean @@ -160,7 +160,7 @@ protected abbrev Function.Surjective.smulWithZero (f : ZeroHom A A') (hf : Surje variable (A) /-- Compose a `SMulWithZero` with a `ZeroHom`, with action `f r' • m` -/ -@[implicit_reducible] +@[instance_reducible] def SMulWithZero.compHom (f : ZeroHom M₀' M₀) : SMulWithZero M₀' A where smul := (f · • ·) smul_zero m := smul_zero (f m) @@ -240,7 +240,7 @@ protected abbrev Function.Surjective.mulActionWithZero (f : ZeroHom A A') (hf : variable (A) /-- Compose a `MulActionWithZero` with a `MonoidWithZeroHom`, with action `f r' • m` -/ -@[implicit_reducible] +@[instance_reducible] def MulActionWithZero.compHom (f : M₀' →*₀ M₀) : MulActionWithZero M₀' A where __ := SMulWithZero.compHom A f.toZeroHom mul_smul r s m := by change f (r * s) • m = f r • f s • m; simp [mul_smul] diff --git a/Mathlib/Algebra/GroupWithZero/Associated.lean b/Mathlib/Algebra/GroupWithZero/Associated.lean index 585655daa2f27b..de3d8bd0385611 100644 --- a/Mathlib/Algebra/GroupWithZero/Associated.lean +++ b/Mathlib/Algebra/GroupWithZero/Associated.lean @@ -413,6 +413,7 @@ theorem quotient_mk_eq_mk [Monoid M] (a : M) : ⟦a⟧ = Associates.mk a := theorem quot_mk_eq_mk [Monoid M] (a : M) : Quot.mk Setoid.r a = Associates.mk a := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem quot_out [Monoid M] (a : Associates M) : Associates.mk (Quot.out a) = a := by rw [← quot_mk_eq_mk, Quot.out_eq] diff --git a/Mathlib/Algebra/GroupWithZero/Basic.lean b/Mathlib/Algebra/GroupWithZero/Basic.lean index cd2d00c15c8442..b645df61d0cab8 100644 --- a/Mathlib/Algebra/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Basic.lean @@ -108,7 +108,7 @@ theorem eq_zero_of_zero_eq_one (h : (0 : M₀) = 1) (a : M₀) : a = 0 := by Somewhat arbitrarily, we define the default element to be `0`. All other elements will be provably equal to it, but not necessarily definitionally equal. -/ -@[implicit_reducible] +@[instance_reducible] def uniqueOfZeroEqOne (h : (0 : M₀) = 1) : Unique M₀ where default := 0 uniq := eq_zero_of_zero_eq_one h diff --git a/Mathlib/Algebra/GroupWithZero/Indicator.lean b/Mathlib/Algebra/GroupWithZero/Indicator.lean index 7dcce0f07f7fb0..fc6fa7031b3bdd 100644 --- a/Mathlib/Algebra/GroupWithZero/Indicator.lean +++ b/Mathlib/Algebra/GroupWithZero/Indicator.lean @@ -68,6 +68,7 @@ variable [MulZeroOneClass M₀] {s t : Set ι} {i : ι} lemma inter_indicator_one : (s ∩ t).indicator (1 : ι → M₀) = s.indicator 1 * t.indicator 1 := funext fun _ ↦ by simp only [← inter_indicator_mul, Pi.mul_apply, Pi.one_apply, one_mul]; congr +set_option backward.isDefEq.respectTransparency false in lemma indicator_prod_one {t : Set κ} {j : κ} : (s ×ˢ t).indicator (1 : ι × κ → M₀) (i, j) = s.indicator 1 i * t.indicator 1 j := by simp_rw [indicator, mem_prod_eq] diff --git a/Mathlib/Algebra/GroupWithZero/InjSurj.lean b/Mathlib/Algebra/GroupWithZero/InjSurj.lean index f4dcc90064bab7..382fae62eb993e 100644 --- a/Mathlib/Algebra/GroupWithZero/InjSurj.lean +++ b/Mathlib/Algebra/GroupWithZero/InjSurj.lean @@ -201,7 +201,7 @@ protected abbrev Function.Injective.commGroupWithZero [Zero G₀'] [Mul G₀'] [ /-- Push forward a `CommGroupWithZero` along a surjective function. See note [reducible non-instances]. -/ -@[implicit_reducible] +@[instance_reducible] protected def Function.Surjective.commGroupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) diff --git a/Mathlib/Algebra/GroupWithZero/Invertible.lean b/Mathlib/Algebra/GroupWithZero/Invertible.lean index e2304a4584fe59..ee672b5ca71e32 100644 --- a/Mathlib/Algebra/GroupWithZero/Invertible.lean +++ b/Mathlib/Algebra/GroupWithZero/Invertible.lean @@ -49,7 +49,7 @@ section GroupWithZero variable [GroupWithZero α] /-- `a⁻¹` is an inverse of `a` if `a ≠ 0` -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfNonzero {a : α} (h : a ≠ 0) : Invertible a := ⟨a⁻¹, inv_mul_cancel₀ h, mul_inv_cancel₀ h⟩ @@ -82,7 +82,7 @@ theorem div_self_of_invertible (a : α) [Invertible a] : a / a = 1 := div_self (Invertible.ne_zero a) /-- `b / a` is the inverse of `a / b` -/ -@[implicit_reducible] +@[instance_reducible] def invertibleDiv (a b : α) [Invertible a] [Invertible b] : Invertible (a / b) := ⟨b / a, by simp [← mul_div_assoc], by simp [← mul_div_assoc]⟩ diff --git a/Mathlib/Algebra/GroupWithZero/ProdHom.lean b/Mathlib/Algebra/GroupWithZero/ProdHom.lean index bebe0d12635fba..8d2a3a0abebed6 100644 --- a/Mathlib/Algebra/GroupWithZero/ProdHom.lean +++ b/Mathlib/Algebra/GroupWithZero/ProdHom.lean @@ -96,6 +96,7 @@ lemma inr_apply_unit [DecidablePred fun x : H₀ ↦ x = 0] (x : H₀ˣ) : @[simp] lemma fst_apply_coe (x : G₀ˣ × H₀ˣ) : fst G₀ H₀ x = x.fst := by rfl @[simp] lemma snd_apply_coe (x : G₀ˣ × H₀ˣ) : snd G₀ H₀ x = x.snd := by rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem fst_inl [DecidablePred fun x : G₀ ↦ x = 0] (x : G₀) : fst _ H₀ (inl _ _ x) = x := by @@ -107,6 +108,7 @@ theorem fst_comp_inl [DecidablePred fun x : G₀ ↦ x = 0] : (fst ..).comp (inl G₀ H₀) = .id _ := ext fun _ ↦ fst_inl _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem snd_comp_inl [DecidablePred fun x : G₀ ↦ x = 0] : (snd ..).comp (inl G₀ H₀) = 1 := by @@ -118,6 +120,7 @@ theorem snd_inl_apply_of_ne_zero [DecidablePred fun x : G₀ ↦ x = 0] {x : G snd _ _ (inl _ H₀ x) = 1 := by rw [← comp_apply, snd_comp_inl, one_apply_of_ne_zero hx] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem fst_comp_inr [DecidablePred fun x : H₀ ↦ x = 0] : (fst ..).comp (inr G₀ H₀) = 1 := by @@ -129,6 +132,7 @@ theorem fst_inr_apply_of_ne_zero [DecidablePred fun x : H₀ ↦ x = 0] {x : H fst _ _ (inr G₀ _ x) = 1 := by rw [← comp_apply, fst_comp_inr, one_apply_of_ne_zero hx] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem snd_inr [DecidablePred fun x : H₀ ↦ x = 0] (x : H₀) : snd _ _ (inr G₀ _ x) = x := by @@ -158,10 +162,12 @@ lemma snd_surjective : Function.Surjective (snd G₀ H₀) := by variable [DecidablePred fun x : G₀ ↦ x = 0] [DecidablePred fun x : H₀ ↦ x = 0] +set_option backward.isDefEq.respectTransparency false in theorem inl_mul_inr_eq_mk_of_unit (m : G₀ˣ) (n : H₀ˣ) : (inl G₀ H₀ m * inr G₀ H₀ n) = (m, n) := by simp [inl, WithZero.withZeroUnitsEquiv, inr, ← WithZero.coe_mul] +set_option backward.isDefEq.respectTransparency false in theorem commute_inl_inr (m : G₀) (n : H₀) : Commute (inl G₀ H₀ m) (inr G₀ H₀ n) := by obtain rfl | ⟨_, rfl⟩ := GroupWithZero.eq_zero_or_unit m <;> obtain rfl | ⟨_, rfl⟩ := GroupWithZero.eq_zero_or_unit n <;> diff --git a/Mathlib/Algebra/GroupWithZero/Range.lean b/Mathlib/Algebra/GroupWithZero/Range.lean index 9608935be7c209..c656abccc958d6 100644 --- a/Mathlib/Algebra/GroupWithZero/Range.lean +++ b/Mathlib/Algebra/GroupWithZero/Range.lean @@ -202,6 +202,7 @@ lemma valueGroup_eq_range : Units.val '' (valueGroup f) = (range f \ {0}) := by refine ⟨Units.mk0 x hx₀, ?_, rfl⟩ simpa [Units.val_mk0, mem_range] using ⟨y, hy⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] lemma ValueGroup₀.restrict₀_range_eq_top : range (ValueGroup₀.restrict₀ f) = ⊤ := by rw [top_eq_univ, range_eq_univ] @@ -229,7 +230,7 @@ variable [MonoidWithZero A] [CommGroupWithZero B] (f : A →*₀ B) theorem mem_valueGroup_iff_of_comm {y : Bˣ} : y ∈ valueGroup f ↔ ∃ a, f a ≠ 0 ∧ ∃ x, f a * y = f x := by refine ⟨fun hy ↦ ?_, fun ⟨a, ha, x, hy⟩ ↦ ?_⟩ - · simp only [valueGroup, valueMonoid, Submonoid.coe_set_mk, Subsemigroup.coe_set_mk] at hy + · simp only [valueGroup, valueMonoid] at hy induction hy using Subgroup.closure_induction with | mem _ h => obtain ⟨a, ha⟩ := h diff --git a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean index 873e7ab2b6ddf8..f5962b7713cfc6 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean @@ -511,7 +511,7 @@ variable {M : Type*} [Nontrivial M] open scoped Classical in /-- Constructs a `GroupWithZero` structure on a `MonoidWithZero` consisting only of units and 0. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def groupWithZeroOfIsUnitOrEqZero [hM : MonoidWithZero M] (h : ∀ a : M, IsUnit a ∨ a = 0) : GroupWithZero M := { hM with @@ -523,7 +523,7 @@ noncomputable def groupWithZeroOfIsUnitOrEqZero [hM : MonoidWithZero M] /-- Constructs a `CommGroupWithZero` structure on a `CommMonoidWithZero` consisting only of units and 0. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def commGroupWithZeroOfIsUnitOrEqZero [hM : CommMonoidWithZero M] (h : ∀ a : M, IsUnit a ∨ a = 0) : CommGroupWithZero M := { groupWithZeroOfIsUnitOrEqZero h, hM with } diff --git a/Mathlib/Algebra/GroupWithZero/WithZero.lean b/Mathlib/Algebra/GroupWithZero/WithZero.lean index d86e3ee518fc58..5b62e51974c245 100644 --- a/Mathlib/Algebra/GroupWithZero/WithZero.lean +++ b/Mathlib/Algebra/GroupWithZero/WithZero.lean @@ -262,6 +262,7 @@ instance instDivInvMonoid [DivInvMonoid α] : DivInvMonoid (WithZero α) where instance instDivInvOneMonoid [DivInvOneMonoid α] : DivInvOneMonoid (WithZero α) where +set_option backward.isDefEq.respectTransparency false in instance instInvolutiveInv [InvolutiveInv α] : InvolutiveInv (WithZero α) where inv_inv a := (Option.map_map _ _ _).trans <| by simp @@ -300,6 +301,7 @@ def unitsWithZeroEquiv : (WithZero α)ˣ ≃* α where instance [Nontrivial α] : Nontrivial (WithZero α)ˣ := unitsWithZeroEquiv.toEquiv.surjective.nontrivial +set_option backward.isDefEq.respectTransparency false in theorem coe_unitsWithZeroEquiv_eq_units_val (γ : (WithZero α)ˣ) : ↑(unitsWithZeroEquiv γ) = γ.val := by simp only [WithZero.unitsWithZeroEquiv, MulEquiv.coe_mk, Equiv.coe_fn_mk, WithZero.coe_unzero] @@ -320,6 +322,7 @@ lemma withZeroUnitsEquiv_symm_apply_coe {G : Type*} [GroupWithZero G] WithZero.withZeroUnitsEquiv.symm (a : G) = a := by simp +set_option backward.isDefEq.respectTransparency false in /-- A version of `Equiv.optionCongr` for `WithZero`. -/ @[simps!] def _root_.MulEquiv.withZero [Group β] : diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 6b9c84d330b1bd..075b5c8c028f94 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -122,6 +122,7 @@ instance Functor.map_homogical_complex_additive (F : V ⥤ W) [F.Additive] (c : variable (W₁) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor on homological complexes induced by the identity functor is isomorphic to the identity functor. -/ @@ -147,6 +148,7 @@ instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] : ext exact F.map_injective ((HomologicalComplex.eval W c _).congr_map h) +set_option backward.isDefEq.respectTransparency.types false in instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] [F.Full] : (F.mapHomologicalComplex c).Full where map_surjective {X Y} f := ⟨ @@ -213,6 +215,7 @@ def Functor.mapHomologicalComplexCompIso {W' : Type*} [Category W'] [Preadditive F.mapHomologicalComplex c ⋙ G.mapHomologicalComplex c ≅ H.mapHomologicalComplex c := NatIso.mapHomologicalComplex e c +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories induces an equivalences between the respective categories of homological complex. @@ -234,6 +237,7 @@ namespace ChainComplex variable {α : Type*} [AddRightCancelSemigroup α] [One α] [DecidableEq α] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem map_chain_complex_of (F : W₁ ⥤ W₂) [F.PreservesZeroMorphisms] (X : α → W₁) (d : ∀ n, X (n + 1) ⟶ X n) (sq : ∀ n, d (n + 1) ≫ d n = 0) : diff --git a/Mathlib/Algebra/Homology/Augment.lean b/Mathlib/Algebra/Homology/Augment.lean index 0db91bf9035150..2e754ced6a1f67 100644 --- a/Mathlib/Algebra/Homology/Augment.lean +++ b/Mathlib/Algebra/Homology/Augment.lean @@ -119,6 +119,7 @@ theorem chainComplex_d_succ_succ_zero (C : ChainComplex V ℕ) (i : ℕ) : C.d ( rw [C.shape] exact i.succ_succ_ne_one.symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Augmenting a truncated complex with the original object and morphism is isomorphic (with components the identity) to the original complex. @@ -280,6 +281,7 @@ theorem cochainComplex_d_succ_succ_zero (C : CochainComplex V ℕ) (i : ℕ) : C simp only [ComplexShape.up_Rel, zero_add] exact (Nat.one_lt_succ_succ _).ne +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Augmenting a truncated complex with the original object and morphism is isomorphic (with components the identity) to the original complex. diff --git a/Mathlib/Algebra/Homology/BifunctorAssociator.lean b/Mathlib/Algebra/Homology/BifunctorAssociator.lean index af70bcf3fb53fd..9de2cc124aca4c 100644 --- a/Mathlib/Algebra/Homology/BifunctorAssociator.lean +++ b/Mathlib/Algebra/Homology/BifunctorAssociator.lean @@ -314,6 +314,7 @@ lemma ι_D₂ [HasGoodTrifunctor₁₂Obj F₁₂ G K₁ K₂ K₃ c₁₂ c₄] d₂ F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j' := by simp [D₂] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ι_D₃ : ι F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j h ≫ D₃ F₁₂ G K₁ K₂ K₃ c₁₂ c₄ j j' = @@ -334,6 +335,7 @@ lemma ι_D₃ : end +set_option backward.isDefEq.respectTransparency.types false in lemma d_eq (j j' : ι₄) [HasGoodTrifunctor₁₂Obj F₁₂ G K₁ K₂ K₃ c₁₂ c₄] : (mapBifunctor (mapBifunctor K₁ K₂ F₁₂ c₁₂) K₃ G c₄).d j j' = D₁ F₁₂ G K₁ K₂ K₃ c₁₂ c₄ j j' + D₂ F₁₂ G K₁ K₂ K₃ c₁₂ c₄ j j' + diff --git a/Mathlib/Algebra/Homology/BifunctorShift.lean b/Mathlib/Algebra/Homology/BifunctorShift.lean index 1181a469aa314d..0fd2c236ff3bab 100644 --- a/Mathlib/Algebra/Homology/BifunctorShift.lean +++ b/Mathlib/Algebra/Homology/BifunctorShift.lean @@ -132,6 +132,7 @@ variable [HasZeroMorphisms C₁] [Preadditive C₂] [Preadditive D] (F : C₁ ⥤ C₂ ⥤ D) [F.PreservesZeroMorphisms] [∀ (X₁ : C₁), (F.obj X₁).Additive] (y : ℤ) [HasMapBifunctor K₁ K₂ F] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `mapBifunctorShift₂Iso`. -/ @[simps! hom_f_f inv_f_f] @@ -322,7 +323,6 @@ instance {K₂ L₂ : CochainComplex C₂ ℤ} (g : K₂ ⟶ L₂) : CochainComplex.ι_mapBifunctorShift₁Iso_hom_f_assoc _ _ _ _ _ _ _ _ (p + n) (d + n) rfl rfl] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in noncomputable instance : F.map₂CochainComplex.CommShift₂Int where comm K₁ K₂ p q := by diff --git a/Mathlib/Algebra/Homology/CochainComplexOpposite.lean b/Mathlib/Algebra/Homology/CochainComplexOpposite.lean index 1fa7a1301583ec..b2e163e4b82dea 100644 --- a/Mathlib/Algebra/Homology/CochainComplexOpposite.lean +++ b/Mathlib/Algebra/Homology/CochainComplexOpposite.lean @@ -57,6 +57,7 @@ namespace ChainComplex variable [HasZeroMorphisms C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] HomologicalComplex.XIsoOfEq in /-- The equivalence of categories `ChainComplex C ℤ ≌ CochainComplex C ℤ`. -/ @@ -114,6 +115,7 @@ def homotopyOp (h : Homotopy f g) : symm exact prevD_eq _ (j' := n - 1) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma homotopyOp_hom_eq (h : Homotopy f g) (p q p' q' : ℤ) (hp : p + p' = 0 := by lia) (hq : q + q' = 0 := by lia) : @@ -157,6 +159,7 @@ def homotopyUnop (h : Homotopy ((opEquivalence C).functor.map f.op) dsimp simp [H (- -(n + 1)) (- -n) (n + 1) n (by simp) (by simp), ← op_comp_assoc, ← op_comp]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma homotopyUnop_hom_eq (h : Homotopy ((opEquivalence C).functor.map f.op) @@ -171,6 +174,7 @@ lemma homotopyUnop_hom_eq end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Two morphisms of cochain complexes indexed by `ℤ` are homotopic iff they are homotopic after the application of the functor @@ -189,6 +193,7 @@ def homotopyOpEquiv {K L : CochainComplex C ℤ} {f g : K ⟶ L} : simp [homotopyOp_hom_eq _ p q (-p) (-q), homotopyUnop_hom_eq _ (-q) (-p) q p] +set_option backward.isDefEq.respectTransparency.types false in lemma exactAt_op {K : CochainComplex C ℤ} {n : ℤ} (hK : K.ExactAt n) (m : ℤ) (hm : n + m = 0 := by lia) : ((opEquivalence C).functor.obj (op K)).ExactAt m := by diff --git a/Mathlib/Algebra/Homology/CommSq.lean b/Mathlib/Algebra/Homology/CommSq.lean index c86adab4086186..71d8a72a8122ec 100644 --- a/Mathlib/Algebra/Homology/CommSq.lean +++ b/Mathlib/Algebra/Homology/CommSq.lean @@ -55,6 +55,7 @@ noncomputable def CommSq.shortComplex (sq : CommSq f g inl inr) : ShortComplex C g := biprod.desc inl inr zero := by simp [sq.w] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A commutative square in a preadditive category is a pushout square iff the corresponding diagram `X₁ ⟶ X₂ ⊞ X₃ ⟶ X₄ ⟶ 0` makes `X₄` a cokernel. -/ @@ -136,6 +137,7 @@ noncomputable def CommSq.shortComplex' (sq : CommSq fst snd f g) : ShortComplex g := biprod.desc f (-g) zero := by simp [sq.w] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A commutative square in a preadditive category is a pullback square iff the corresponding diagram `0 ⟶ X₁ ⟶ X₂ ⊞ X₃ ⟶ X₄ ⟶ 0` makes `X₁` a kernel. -/ diff --git a/Mathlib/Algebra/Homology/ComplexShape.lean b/Mathlib/Algebra/Homology/ComplexShape.lean index f26391859d369c..79e961dc96d294 100644 --- a/Mathlib/Algebra/Homology/ComplexShape.lean +++ b/Mathlib/Algebra/Homology/ComplexShape.lean @@ -88,7 +88,7 @@ def refl (ι : Type*) : ComplexShape ι where /-- The reverse of a `ComplexShape`. -/ -@[simps] +@[simps, implicit_reducible] def symm (c : ComplexShape ι) : ComplexShape ι where Rel i j := c.Rel j i next_eq w w' := c.prev_eq w w' @@ -96,7 +96,7 @@ def symm (c : ComplexShape ι) : ComplexShape ι where /-- If `c : ComplexShape α` is such that `c.Rel` is decidable, it is also the case of `c.symm.Rel`. -/ -@[implicit_reducible] +@[instance_reducible] def decidableRelSymm {α : Type*} (c : ComplexShape α) [DecidableRel c.Rel] : DecidableRel c.symm.Rel := fun a b ↦ decidable_of_iff (c.Rel b a) Iff.rfl diff --git a/Mathlib/Algebra/Homology/ComplexShapeSigns.lean b/Mathlib/Algebra/Homology/ComplexShapeSigns.lean index b4cff6ba6d2ac6..b71a2e9b49f547 100644 --- a/Mathlib/Algebra/Homology/ComplexShapeSigns.lean +++ b/Mathlib/Algebra/Homology/ComplexShapeSigns.lean @@ -177,6 +177,7 @@ instance : TensorSigns (ComplexShape.down ℕ) where @[simp] lemma ε_down_ℕ (n : ℕ) : (ComplexShape.down ℕ).ε n = (-1 : ℤˣ) ^ n := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : TensorSigns (ComplexShape.up ℤ) where ε' := MonoidHom.mk' Int.negOnePow Int.negOnePow_add @@ -275,7 +276,7 @@ end ComplexShape /-- The total complex shape for `c₂`, `c₁` and `c₁₂` that is deduced from a total complex shape for `c₁`, `c₂` and `c₁₂`. -/ -@[implicit_reducible] +@[instance_reducible] def TotalComplexShape.symm [TotalComplexShape c₁ c₂ c₁₂] : TotalComplexShape c₂ c₁ c₁₂ where π := fun ⟨i₂, i₁⟩ ↦ ComplexShape.π c₁ c₂ c₁₂ ⟨i₁, i₂⟩ @@ -301,7 +302,7 @@ class TotalComplexShapeSymmetry [TotalComplexShape c₁ c₂ c₁₂] [TotalComp /-- The symmetry between the total complex shape for `c₁`, `c₂` and `c₁₂`, and its symmetric total complex shape. -/ -@[implicit_reducible] +@[instance_reducible] def TotalComplexShape.symmSymmetry [TotalComplexShape c₁ c₂ c₁₂] : letI := TotalComplexShape.symm c₁ c₂ c₁₂ TotalComplexShapeSymmetry c₁ c₂ c₁₂ := @@ -342,6 +343,7 @@ lemma σ_ε₂ (i₁ : I₁) {i₂ i₂' : I₂} (h₂ : c₂.Rel i₂ i₂') : σ c₁ c₂ c₁₂ i₁ i₂ * ε₂ c₁ c₂ c₁₂ ⟨i₁, i₂⟩ = ε₁ c₂ c₁ c₁₂ ⟨i₂, i₁⟩ * σ c₁ c₂ c₁₂ i₁ i₂' := TotalComplexShapeSymmetry.σ_ε₂ i₁ h₂ +set_option backward.isDefEq.respectTransparency.types false in @[simps] instance : TotalComplexShapeSymmetry (up ℤ) (up ℤ) (up ℤ) where symm p q := add_comm q p @@ -360,7 +362,7 @@ end ComplexShape /-- The obvious `TotalComplexShapeSymmetry c₂ c₁ c₁₂` deduced from a `TotalComplexShapeSymmetry c₁ c₂ c₁₂`. -/ -@[implicit_reducible] +@[instance_reducible] def TotalComplexShapeSymmetry.symmetry [TotalComplexShape c₁ c₂ c₁₂] [TotalComplexShape c₂ c₁ c₁₂] [TotalComplexShapeSymmetry c₁ c₂ c₁₂] : TotalComplexShapeSymmetry c₂ c₁ c₁₂ where diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean index d78c2f9f096135..7bf89d3b17c64a 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean @@ -272,6 +272,7 @@ def singleFunctorsPostcompQIso : SingleFunctors.postcompIsoOfIso (CochainComplex.singleFunctors C) (quotientCompQhIso C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma singleFunctorsPostcompQIso_hom_hom (n : ℤ) : (singleFunctorsPostcompQIso C).hom.hom n = 𝟙 _ := by @@ -282,6 +283,7 @@ lemma singleFunctorsPostcompQIso_hom_hom (n : ℤ) : erw [Category.id_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma singleFunctorsPostcompQIso_inv_hom (n : ℤ) : (singleFunctorsPostcompQIso C).inv.hom n = 𝟙 _ := by diff --git a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean index 2699d12c106b74..bb73fd7f98c8b4 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/DerivabilityStructureInjectives.lean @@ -126,6 +126,7 @@ instance (K : FibrantObject (Plus C)) (n : ℤ) : rw [fibrantObjects, modelCategoryQuillen.isFibrant_iff] at hK infer_instance +set_option backward.isDefEq.respectTransparency.types false in variable (C) in set_option backward.defeqAttrib.useBackward true in /-- The equivalence between `CochainComplex.Plus (InjectiveObject C)` @@ -313,6 +314,7 @@ private def iso : (CochainComplex.Plus.localizerMorphism C).functor ⋙ (R C).functor ≅ (L C).functor ⋙ (localizerMorphism C).functor := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open HomologicalComplex CochainComplex in private instance : TwoSquare.GuitartExact (iso C).hom := diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean index f63799346ef521..2ee4d31030b25e 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean @@ -56,7 +56,6 @@ abbrev HasExt : Prop := ∀ (X Y : C), HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ ((CochainComplex.singleFunctor C 0).obj X) ((CochainComplex.singleFunctor C 0).obj Y) -set_option backward.isDefEq.respectTransparency false in lemma hasExt_iff [HasDerivedCategory.{w'} C] : HasExt.{w} C ↔ ∀ (X Y : C) (n : ℤ) (_ : 0 ≤ n), Small.{w} ((singleFunctor C 0).obj X ⟶ @@ -94,7 +93,6 @@ lemma HasExt.standard : HasExt.{max u v} C := by let := HasDerivedCategory.standard exact hasExt_of_hasDerivedCategory _ -set_option backward.isDefEq.respectTransparency false in instance [HasExt.{w} C] (X Y : C) (a b : ℤ) [HasDerivedCategory.{w'} C] : Small.{w} ((singleFunctor C a).obj X ⟶ (singleFunctor C b).obj Y) := by have (a b : ℤ) : diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean index 565031ebfe26c7..2c75b666f850df 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/ExactSequences.lean @@ -45,6 +45,7 @@ lemma hom_comp_singleFunctor_map_shift [HasDerivedCategory.{w'} C] variable {X : C} {S : ShortComplex C} (hS : S.ShortExact) +set_option backward.isDefEq.respectTransparency.types false in lemma preadditiveCoyoneda_homologySequenceδ_singleTriangle_apply [HasDerivedCategory.{w'} C] {X : C} {n₀ : ℕ} (x : Ext X S.X₃ n₀) {n₁ : ℕ} (h : n₀ + 1 = n₁) : @@ -185,6 +186,7 @@ lemma singleFunctor_map_comp_hom [HasDerivedCategory.{w'} C] ((mk₀ f).comp x (zero_add n)).hom := by simp only [comp_hom, mk₀_hom, ShiftedHom.mk₀_comp] +set_option backward.isDefEq.respectTransparency.types false in lemma preadditiveYoneda_homologySequenceδ_singleTriangle_apply [HasDerivedCategory.{w'} C] {Y : C} {n₀ : ℕ} (x : Ext S.X₁ Y n₀) {n₁ : ℕ} (h : 1 + n₀ = n₁) : diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Map.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Map.lean index f59e9bda08aabe..d72005751c6eaa 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Map.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Map.lean @@ -68,13 +68,13 @@ lemma DerivedCategory.map_triangleOfSESδ [HasDerivedCategory.{t} C] [HasDerived (Q.map (CochainComplex.mappingCone.descShortComplex S))), ← Functor.map_comp, descShortComplex_triangleOfSESδ, F.mapDerivedCategoryFactors_hom_naturality_assoc, ← CochainComplex.mappingCone.mapHomologicalComplexIso_hom_descShortComplex, - Functor.map_comp, Category.assoc, Functor.map_comp_assoc, - descShortComplex_triangleOfSESδ_assoc] + Functor.map_comp_assoc, descShortComplex_triangleOfSESδ_assoc] dsimp - rw [← Functor.map_comp_assoc, ← CochainComplex.mappingCone.map_δ, Functor.map_comp_assoc, - ← Category.assoc, ← F.mapDerivedCategoryFactors_hom_naturality_assoc] - simp [← Q.map_comp_assoc, NatTrans.shift_app, - Functor.commShiftIso_comp_hom_app, Functor.commShiftIso_comp_inv_app] + rw [← Functor.map_comp_assoc] + rw [← CochainComplex.mappingCone.map_δ, Functor.map_comp_assoc, + ← F.mapDerivedCategoryFactors_hom_naturality_assoc, Functor.map_comp] + simp [NatTrans.shift_app, Functor.commShiftIso_comp_hom_app, Functor.commShiftIso_comp_inv_app, + ← Functor.map_comp_assoc] set_option backward.isDefEq.respectTransparency false in @[reassoc] @@ -102,7 +102,9 @@ lemma ShortComplex.ShortExact.mapShiftedHom_singleδ' ← Functor.map_comp_assoc] simp -set_option backward.isDefEq.respectTransparency false in +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma ShortComplex.ShortExact.mapShiftedHom_singleδ [HasDerivedCategory.{t} C] [HasDerivedCategory.{t'} D] @@ -133,7 +135,6 @@ noncomputable def Abelian.Ext.mapExactFunctor [HasExt.{w} C] [HasExt.{w'} D] {X ((F.mapCochainComplexSingleFunctor 0).app X) ((F.mapCochainComplexSingleFunctor 0).app Y) f set_option backward.isDefEq.respectTransparency false in -open Functor in lemma Abelian.Ext.mapExactFunctor_hom [HasDerivedCategory.{t} C] [HasDerivedCategory.{t'} D] [HasExt.{w} C] [HasExt.{w'} D] {X Y : C} {n : ℕ} (e : Ext X Y n) : @@ -207,7 +208,7 @@ end namespace Abelian.Ext -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in lemma mapExactFunctor_mk₀ [HasExt.{w} C] [HasExt.{w'} D] {X Y : C} (f : X ⟶ Y) : (mk₀ f).mapExactFunctor F = mk₀ (F.map f) := by dsimp [Ext.mapExactFunctor, mk₀] diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean index 27705d8ad2371a..c4eeede118eaed 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -37,7 +37,6 @@ open Localization Limits ZeroObject DerivedCategory Pretriangulated namespace HasExt -set_option backward.isDefEq.respectTransparency false in variable {C} in lemma hasSmallLocalizedShiftedHom_of_isLE_of_isGE [HasExt.{w} C] (K L : CochainComplex C ℤ) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Fractions.lean b/Mathlib/Algebra/Homology/DerivedCategory/Fractions.lean index 7e734c31df414d..8b44157a42a89b 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Fractions.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Fractions.lean @@ -39,6 +39,7 @@ instance : (HomotopyCategory.quasiIso C (ComplexShape.up ℤ)).HasRightCalculusO rw [HomotopyCategory.quasiIso_eq_trW_subcategoryAcyclic] infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- Any morphism `f : Q.obj X ⟶ Q.obj Y` in the derived category can be written as `f = inv (Q.map s) ≫ Q.map g` with `s : X' ⟶ X` a quasi-isomorphism and `g : X' ⟶ Y`. -/ lemma right_fac {X Y : CochainComplex C ℤ} (f : Q.obj X ⟶ Q.obj Y) : @@ -52,6 +53,7 @@ lemma right_fac {X Y : CochainComplex C ℤ} (f : Q.obj X ⟶ Q.obj Y) : rw [← isIso_Qh_map_iff] at hs exact ⟨X', s, hs, g, hφ⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Any morphism `f : Q.obj X ⟶ Q.obj Y` in the derived category can be written as `f = Q.map g ≫ inv (Q.map s)` with `g : X ⟶ Y'` and `s : Y ⟶ Y'` a quasi-isomorphism. -/ lemma left_fac {X Y : CochainComplex C ℤ} (f : Q.obj X ⟶ Q.obj Y) : diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index 221f901691d12c..dacf756f0199d1 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -45,7 +45,6 @@ lemma Qh_map_bijective [HasDerivedCategory C] (K ⟶ (HomotopyCategory.quotient _ _).obj L) → _) := (CochainComplex.IsKInjective.rightOrthogonal L).map_bijective_of_isTriangulated _ _ -set_option backward.isDefEq.respectTransparency false in open HomologicalComplex in attribute [local instance] HasDerivedCategory.standard in lemma quasiIso_iff {K L : CochainComplex C ℤ} [K.IsKInjective] [L.IsKInjective] (f : K ⟶ L) : @@ -56,8 +55,8 @@ lemma quasiIso_iff {K L : CochainComplex C ℤ} [K.IsKInjective] [L.IsKInjective obtain ⟨g, hg⟩ := (Qh_map_bijective _ _).surjective ((quotientCompQhIso C).hom.app L ≫ inv (Q.map f) ≫ (quotientCompQhIso C).inv.app K) refine ⟨g, (Qh_map_bijective _ _).injective ?_, (Qh_map_bijective _ _).injective ?_⟩ - · simp [hg]; rfl - · simp [hg, ← quotientCompQhIso_inv_naturality, -NatTrans.naturality]; rfl + · simp [hg] + · simp [hg, ← quotientCompQhIso_inv_naturality, -NatTrans.naturality] end IsKInjective @@ -66,7 +65,6 @@ namespace HomComplex.CohomologyClass variable (K L : CochainComplex C ℤ) (n : ℤ) [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] -set_option backward.isDefEq.respectTransparency false in lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by let := HasDerivedCategory.standard C diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean index 62bc40a28b8297..24234f78ff7e71 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean @@ -47,7 +47,6 @@ lemma Qh_map_bijective [HasDerivedCategory C] ((HomotopyCategory.quotient _ _).obj K ⟶ L) → _) := (CochainComplex.IsKProjective.leftOrthogonal K).map_bijective_of_isTriangulated _ _ -set_option backward.isDefEq.respectTransparency false in attribute [local instance] HasDerivedCategory.standard in lemma quasiIso_iff {K L : CochainComplex C ℤ} [K.IsKProjective] [L.IsKProjective] (f : K ⟶ L) : QuasiIso f ↔ homotopyEquivalences C (.up ℤ) f := by @@ -57,8 +56,8 @@ lemma quasiIso_iff {K L : CochainComplex C ℤ} [K.IsKProjective] [L.IsKProjecti obtain ⟨g, hg⟩ := (Qh_map_bijective _ _).surjective ((quotientCompQhIso C).hom.app L ≫ inv (Q.map f) ≫ (quotientCompQhIso C).inv.app K) refine ⟨g, (Qh_map_bijective _ _).injective ?_, (Qh_map_bijective _ _).injective ?_⟩ - · simp [hg]; rfl - · simp [hg, ← quotientCompQhIso_inv_naturality f, -NatTrans.naturality]; rfl + · simp [hg] + · simp [hg, ← quotientCompQhIso_inv_naturality f, -NatTrans.naturality] end IsKProjective @@ -67,7 +66,6 @@ namespace HomComplex.CohomologyClass variable (K L : CochainComplex C ℤ) (n : ℤ) [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] -set_option backward.isDefEq.respectTransparency false in lemma bijective_toSmallShiftedHom_of_isKProjective [K.IsKProjective] : Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by let := HasDerivedCategory.standard C diff --git a/Mathlib/Algebra/Homology/DerivedCategory/ShortExact.lean b/Mathlib/Algebra/Homology/DerivedCategory/ShortExact.lean index 52ec6540aa84e0..ad3d0d471fda3f 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/ShortExact.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/ShortExact.lean @@ -99,6 +99,7 @@ section map variable {S₁ S₂ : ShortComplex (CochainComplex C ℤ)} (h₁ : S₁.ShortExact) (h₂ : S₂.ShortExact) (f : S₁ ⟶ S₂) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The morphism `triangleOfSES h₁ ⟶ triangleOfSES h₂` that is induced by a morphism of short diff --git a/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean b/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean index b56ffa0b408a35..35323ac5e028e2 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean @@ -33,7 +33,6 @@ variable {C : Type u} [Category.{v} C] [Abelian C] {K L : CochainComplex C ℤ} {n : ℤ} [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] -set_option backward.isDefEq.respectTransparency false in /-- Given `x : CohomologyClass K L n`, this is the element in the type `SmallShiftedHom` relatively to quasi-isomorphisms that is associated to the `x`. -/ diff --git a/Mathlib/Algebra/Homology/DifferentialObject.lean b/Mathlib/Algebra/Homology/DifferentialObject.lean index 0f1a6025bc82b2..5bd5eb6ce941e4 100644 --- a/Mathlib/Algebra/Homology/DifferentialObject.lean +++ b/Mathlib/Algebra/Homology/DifferentialObject.lean @@ -99,6 +99,7 @@ def dgoToHomologicalComplex : have : f.f i ≫ Y.d i = X.d i ≫ f.f _ := (congr_fun f.comm i).symm simp only [dite_true, Category.assoc, eqToHom_f', reassoc_of% this] } +set_option backward.isDefEq.respectTransparency.types false in /-- The functor from homological complexes to differential graded objects. -/ @[simps] @@ -110,6 +111,7 @@ def homologicalComplexToDGO : d := fun i => X.d i _ } map {X Y} f := { f := f.f } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit isomorphism for `dgoEquivHomologicalComplex`. -/ @@ -133,6 +135,7 @@ def dgoEquivHomologicalComplexCounitIso : { hom := { f := fun i => 𝟙 (X.X i) } inv := { f := fun i => 𝟙 (X.X i) } }) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of differential graded objects in `V` is equivalent to the category of homological complexes in `V`. diff --git a/Mathlib/Algebra/Homology/Embedding/Basic.lean b/Mathlib/Algebra/Homology/Embedding/Basic.lean index 17bd456cd318e9..c43326357b4176 100644 --- a/Mathlib/Algebra/Homology/Embedding/Basic.lean +++ b/Mathlib/Algebra/Homology/Embedding/Basic.lean @@ -182,6 +182,7 @@ def embeddingUp'Add (a b : A) : Embedding (up' a) (up' a) := (fun _ _ h => by simpa using h) (by dsimp; simp_rw [add_right_comm _ b a, add_right_cancel_iff, implies_true]) +set_option backward.isDefEq.respectTransparency false in instance (a b : A) : (embeddingUp'Add a b).IsRelIff := by dsimp [embeddingUp'Add]; infer_instance instance (a b : A) : (embeddingUp'Add a b).IsTruncGE where @@ -195,6 +196,7 @@ def embeddingDown'Add (a b : A) : Embedding (down' a) (down' a) := (fun _ _ h => by simpa using h) (by dsimp; simp_rw [add_right_comm _ b a, add_right_cancel_iff, implies_true]) +set_option backward.isDefEq.respectTransparency false in instance (a b : A) : (embeddingDown'Add a b).IsRelIff := by dsimp [embeddingDown'Add]; infer_instance @@ -211,6 +213,7 @@ def embeddingUpNat : Embedding (up ℕ) (up ℤ) := (fun _ _ h => by simpa using h) (by dsimp; lia) +set_option backward.isDefEq.respectTransparency false in instance : embeddingUpNat.IsRelIff := by dsimp [embeddingUpNat]; infer_instance instance : embeddingUpNat.IsTruncGE where @@ -224,6 +227,7 @@ def embeddingDownNat : Embedding (down ℕ) (up ℤ) := (fun _ _ h => by simpa using h) (by dsimp; lia) +set_option backward.isDefEq.respectTransparency false in instance : embeddingDownNat.IsRelIff := by dsimp [embeddingDownNat]; infer_instance set_option backward.defeqAttrib.useBackward true in @@ -240,6 +244,7 @@ def embeddingUpIntGE : Embedding (up ℕ) (up ℤ) := (fun _ _ h => by dsimp at h; lia) (by dsimp; lia) +set_option backward.isDefEq.respectTransparency false in instance : (embeddingUpIntGE p).IsRelIff := by dsimp [embeddingUpIntGE]; infer_instance set_option backward.defeqAttrib.useBackward true in @@ -254,6 +259,7 @@ def embeddingUpIntLE : Embedding (down ℕ) (up ℤ) := (fun _ _ h => by dsimp at h; lia) (by dsimp; lia) +set_option backward.isDefEq.respectTransparency false in instance : (embeddingUpIntLE p).IsRelIff := by dsimp [embeddingUpIntLE]; infer_instance set_option backward.defeqAttrib.useBackward true in diff --git a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean index ad35d9c62b186f..a03db783bd220e 100644 --- a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean +++ b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean @@ -232,6 +232,7 @@ instance (X : ChainComplex C ℕ) : CochainComplex.IsStrictlyLE (X.extend embeddingDownNat) 0 where isZero _ _ := isZero_extend_X _ _ _ (by aesop) +set_option backward.isDefEq.respectTransparency.types false in /-- A cochain complex that is both strictly `≤ n` and `≥ n` is isomorphic to a complex `(single _ _ n).obj M` for some object `M`. -/ lemma exists_iso_single (n : ℤ) [K.IsStrictlyGE n] [K.IsStrictlyLE n] : diff --git a/Mathlib/Algebra/Homology/Embedding/Connect.lean b/Mathlib/Algebra/Homology/Embedding/Connect.lean index 40a5bd6d2b0524..eb86596ebd7655 100644 --- a/Mathlib/Algebra/Homology/Embedding/Connect.lean +++ b/Mathlib/Algebra/Homology/Embedding/Connect.lean @@ -93,6 +93,7 @@ def d : ∀ (n m : ℤ), X K L n ⟶ X K L m @[simp] lemma d_zero_one : h.d 0 1 = L.d 0 1 := rfl @[simp] lemma d_sub_two_sub_one : h.d (-2) (-1) = K.d 1 0 := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma shape (n m : ℤ) (hnm : n + 1 ≠ m) : h.d n m = 0 := match n, m with | .ofNat n, .ofNat m => L.shape _ _ (by simp at hnm ⊢; lia) @@ -152,6 +153,7 @@ def restrictionGEIso : (j' := (n + 1 : ℕ)) (by simp) (by simp), cochainComplex_d, h.d_ofNat] simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `h : ConnectData K L`, then `h.cochainComplex` identifies to `K` in degrees `≤ -1`. -/ @[simps!] diff --git a/Mathlib/Algebra/Homology/Embedding/Extend.lean b/Mathlib/Algebra/Homology/Embedding/Extend.lean index 4d668afb9ed8ac..47c6cecdd69e81 100644 --- a/Mathlib/Algebra/Homology/Embedding/Extend.lean +++ b/Mathlib/Algebra/Homology/Embedding/Extend.lean @@ -69,6 +69,7 @@ lemma d_none_eq_zero (i j : Option ι) (hi : i = none) : lemma d_none_eq_zero' (i j : Option ι) (hj : j = none) : d K i j = 0 := by subst hj; cases i <;> rfl +set_option backward.isDefEq.respectTransparency.types false in lemma d_eq {i j : Option ι} {a b : ι} (hi : i = some a) (hj : j = some b) : d K i j = (XIso K hi).hom ≫ K.d a b ≫ (XIso K hj).inv := by subst hi hj @@ -97,6 +98,7 @@ noncomputable def mapX : ∀ (i : Option ι), X K i ⟶ X L i | some i => φ.f i | none => 0 +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma mapX_some {i : Option ι} {a : ι} (hi : i = some a) : mapX φ i = (XIso K hi).hom ≫ φ.f a ≫ (XIso L hi).inv := by diff --git a/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean b/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean index a25c3e4aaf3047..80f1510f13b1a2 100644 --- a/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean +++ b/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean @@ -261,6 +261,7 @@ lemma rightHomologyData_g' (h : (K.sc' i j k).RightHomologyData) (hk'' : e.f k = rw [assoc] at this rw [this, K.extend_d_eq e hj' hk'', h.p_g'_assoc, shortComplexFunctor'_obj_g] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The homology data of `(K.extend e).sc' i' j' k'` that is deduced from a homology data of `K.sc' i j k`. -/ @@ -271,6 +272,7 @@ noncomputable def homologyData (h : (K.sc' i j k).HomologyData) : right := rightHomologyData K e hj' hi hi' hk hk' h.right iso := h.iso +set_option backward.isDefEq.respectTransparency.types false in /-- The homology data of `(K.extend e).sc j'` that is deduced from a homology data of `K.sc' i j k`. -/ @[simps!] diff --git a/Mathlib/Algebra/Homology/Embedding/ExtendHomotopy.lean b/Mathlib/Algebra/Homology/Embedding/ExtendHomotopy.lean index 117b9a21ec44a6..275a0669c57631 100644 --- a/Mathlib/Algebra/Homology/Embedding/ExtendHomotopy.lean +++ b/Mathlib/Algebra/Homology/Embedding/ExtendHomotopy.lean @@ -34,6 +34,7 @@ namespace extend variable (e : c.Embedding c') (φ : ∀ i j, K.X i ⟶ L.X j) +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `Homotopy.extend` -/ noncomputable def homAux (i' j' : Option ι) : extend.X K i' ⟶ extend.X L j' := match i', j' with @@ -41,6 +42,7 @@ noncomputable def homAux (i' j' : Option ι) : extend.X K i' ⟶ extend.X L j' : | _, none => 0 | some i, some j => φ i j +set_option backward.isDefEq.respectTransparency.types false in lemma homAux_eq (i' j' : Option ι) (i j : ι) (hi : i' = some i) (hj : j' = some j) : homAux φ i' j' = (extend.XIso K hi).hom ≫ φ i j ≫ (extend.XIso L hj).inv := by subst hi hj diff --git a/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean b/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean index 9387307deb8881..00121968fcfee4 100644 --- a/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean +++ b/Mathlib/Algebra/Homology/Embedding/HomEquiv.lean @@ -115,6 +115,7 @@ lemma liftExtend_f : (L.extendXIso e hi).inv := by apply liftExtend.f_eq +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `φ : K.restriction e ⟶ L` such that `hφ : e.HasLift φ`, this is the isomorphisms in the category of arrows between the maps @@ -147,6 +148,7 @@ variable (ψ : K ⟶ L.extend e) noncomputable def f (i : ι) : (K.restriction e).X i ⟶ L.X i := ψ.f (e.f i) ≫ (L.extendXIso e rfl).hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma f_eq {i : ι} {i' : ι'} (h : e.f i = i') : f ψ i = (K.restrictionXIso e h).hom ≫ ψ.f i' ≫ (L.extendXIso e h).hom := by @@ -195,6 +197,7 @@ lemma homRestrict_liftExtend (φ : K.restriction e ⟶ L) (hφ : e.HasLift φ) : ext i simp [e.homRestrict_f _ rfl, e.liftExtend_f _ _ rfl] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma homRestrict_precomp (α : K' ⟶ K) (ψ : K ⟶ L.extend e) : diff --git a/Mathlib/Algebra/Homology/Embedding/Restriction.lean b/Mathlib/Algebra/Homology/Embedding/Restriction.lean index 0fe781b43e9ee8..6b4af0a1d60a96 100644 --- a/Mathlib/Algebra/Homology/Embedding/Restriction.lean +++ b/Mathlib/Algebra/Homology/Embedding/Restriction.lean @@ -43,6 +43,7 @@ def restrictionXIso {i : ι} {i' : ι'} (h : e.f i = i') : eqToIso (h ▸ rfl) set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma restriction_d_eq {i j : ι} {i' j' : ι'} (hi : e.f i = i') (hj : e.f j = j') : (K.restriction e).d i j = (K.restrictionXIso e hi).hom ≫ K.d i' j' ≫ @@ -59,6 +60,7 @@ def restrictionMap : K.restriction e ⟶ L.restriction e where f i := φ.f (e.f i) set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma restrictionMap_f' {i : ι} {i' : ι'} (hi : e.f i = i') : (restrictionMap φ e).f i = (K.restrictionXIso e hi).hom ≫ diff --git a/Mathlib/Algebra/Homology/Embedding/RestrictionHomology.lean b/Mathlib/Algebra/Homology/Embedding/RestrictionHomology.lean index 6c19f184c18a2c..638385aecfa183 100644 --- a/Mathlib/Algebra/Homology/Embedding/RestrictionHomology.lean +++ b/Mathlib/Algebra/Homology/Embedding/RestrictionHomology.lean @@ -35,6 +35,7 @@ variable (i j k : ι) (hi : c.prev j = i) (hk : c.next j = k) {i' j' k' : ι'} (hi' : e.f i = i') (hj' : e.f j = j') (hk' : e.f k = k') (hi'' : c'.prev j' = i') (hk'' : c'.next j' = k') +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism `(K.restriction e).sc' i j k ≅ K.sc' i' j' k'` when `e` is an embedding of complex shapes, `i'`, `j`, `k`' are the respective diff --git a/Mathlib/Algebra/Homology/Embedding/TruncGE.lean b/Mathlib/Algebra/Homology/Embedding/TruncGE.lean index d8798f8abc86a3..25c81687628d28 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncGE.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncGE.lean @@ -116,6 +116,7 @@ noncomputable def truncGE'XIsoOpcycles {i : ι} {i' : ι'} (hi' : e.f i = i') (h (K.truncGE' e).X i ≅ K.opcycles i' := (truncGE'.XIsoOpcycles K e hi) ≪≫ eqToIso (by subst hi'; rfl) +set_option backward.isDefEq.respectTransparency.types false in lemma truncGE'_d_eq {i j : ι} (hij : c.Rel i j) {i' j' : ι'} (hi' : e.f i = i') (hj' : e.f j = j') (hi : ¬ e.BoundaryGE i) : (K.truncGE' e).d i j = (K.truncGE'XIso e hi' hi).hom ≫ K.d i' j' ≫ @@ -125,6 +126,7 @@ lemma truncGE'_d_eq {i j : ι} (hij : c.Rel i j) {i' j' : ι'} subst hi' hj' simp [truncGE'XIso] +set_option backward.isDefEq.respectTransparency.types false in lemma truncGE'_d_eq_fromOpcycles {i j : ι} (hij : c.Rel i j) {i' j' : ι'} (hi' : e.f i = i') (hj' : e.f j = j') (hi : e.BoundaryGE i) : (K.truncGE' e).d i j = (K.truncGE'XIsoOpcycles e hi' hi).hom ≫ K.fromOpcycles i' j' ≫ @@ -234,6 +236,7 @@ noncomputable def f (i : ι) : (K.restriction e).X i ⟶ (K.truncGE' e).X i := else (K.truncGE'XIso e rfl hi).inv +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma f_eq_iso_hom_pOpcycles_iso_inv {i : ι} {i' : ι'} (hi' : e.f i = i') (hi : e.BoundaryGE i) : f K e i = (K.restrictionXIso e hi').hom ≫ K.pOpcycles i' ≫ @@ -243,6 +246,7 @@ lemma f_eq_iso_hom_pOpcycles_iso_inv {i : ι} {i' : ι'} (hi' : e.f i = i') (hi subst hi' simp [restrictionXIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma f_eq_iso_hom_iso_inv {i : ι} {i' : ι'} (hi' : e.f i = i') (hi : ¬ e.BoundaryGE i) : f K e i = (K.restrictionXIso e hi').hom ≫ (K.truncGE'XIso e hi' hi).inv := by @@ -273,6 +277,7 @@ end restrictionToTruncGE' noncomputable def restrictionToTruncGE' : K.restriction e ⟶ K.truncGE' e where f := restrictionToTruncGE'.f K e +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma restrictionToTruncGE'_hasLift : e.HasLift (K.restrictionToTruncGE' e) := by intro j hj i' _ @@ -298,6 +303,7 @@ lemma isIso_restrictionToTruncGE' (i : ι) (hi : ¬ e.BoundaryGE i) : rw [K.restrictionToTruncGE'_f_eq_iso_hom_iso_inv e rfl hi] infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {K L} in @[reassoc (attr := simp)] diff --git a/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean b/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean index bc11bec38b692a..62f8735be33724 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncGEHomology.lean @@ -80,6 +80,7 @@ lemma homologyι_truncGE'XIsoOpcycles_inv_d : homologyι_comp_fromOpcycles_assoc, zero_comp] · rw [shape _ _ _ hjk, comp_zero] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `truncGE'.homologyData`. -/ noncomputable def isLimitKernelFork : diff --git a/Mathlib/Algebra/Homology/Embedding/TruncLE.lean b/Mathlib/Algebra/Homology/Embedding/TruncLE.lean index 30f0ff662f3b41..df7623dd3bc1b3 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncLE.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncLE.lean @@ -57,6 +57,7 @@ lemma truncLE'_d_eq {i j : ι} (hij : c.Rel i j) {i' j' : ι'} (K.truncLE'XIso e hj' hj).inv := Quiver.Hom.op_inj (by simpa using! K.op.truncGE'_d_eq e.op hij hj' hi' (by simpa)) +set_option backward.isDefEq.respectTransparency.types false in lemma truncLE'_d_eq_toCycles {i j : ι} (hij : c.Rel i j) {i' j' : ι'} (hi' : e.f i = i') (hj' : e.f j = j') (hj : e.BoundaryLE j) : (K.truncLE' e).d i j = (K.truncLE'XIso e hi' (e.not_boundaryLE_prev hij)).hom ≫ diff --git a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean index a8b90f9b7f277b..7986eecf05df60 100644 --- a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean +++ b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean @@ -370,6 +370,7 @@ lemma quasiIso_truncGEπ [Mono f] [Mono (homologyMap f n)] : rw [quasiIso_πTruncGE_iff] exact isGE_cokernel f n hf +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local instance] HasDerivedCategory.standard in lemma quasiIsoAt_ι [Mono f] [Mono (homologyMap f n)] (q : ℤ) (hq : q ≤ n) : diff --git a/Mathlib/Algebra/Homology/Factorizations/CM5b.lean b/Mathlib/Algebra/Homology/Factorizations/CM5b.lean index af60defc796c64..d09ecc5d239408 100644 --- a/Mathlib/Algebra/Homology/Factorizations/CM5b.lean +++ b/Mathlib/Algebra/Homology/Factorizations/CM5b.lean @@ -75,6 +75,7 @@ noncomputable def i : K ⟶ mappingCone (𝟙 (I K)) ⊞ L := simp [HomComplex.δ_v 1 2 (by lia) _ p q hpq (p + 1) (p + 1) (by lia) rfl])) (HomComplex.Cochain.ofHoms (fun n => Injective.ι _)) (by cat_disch)) f +set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma i_f_comp (n : ℤ) : (i f).f n ≫ (biprod.fst : mappingCone (𝟙 (I K)) ⊞ L ⟶ _).f n ≫ diff --git a/Mathlib/Algebra/Homology/HomologicalBicomplex.lean b/Mathlib/Algebra/Homology/HomologicalBicomplex.lean index 7c82ce0a8a027a..2e9e8bf964dad9 100644 --- a/Mathlib/Algebra/Homology/HomologicalBicomplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalBicomplex.lean @@ -176,6 +176,7 @@ def flipFunctor : comm' := by intros; simp } comm' := by intros; ext; simp } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `HomologicalComplex₂.flipEquivalence`. -/ @[simps!] @@ -185,6 +186,7 @@ def flipEquivalenceUnitIso : HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) (by simp)) (by cat_disch)) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `HomologicalComplex₂.flipEquivalence`. -/ @[simps!] @@ -194,6 +196,7 @@ def flipEquivalenceCounitIso : HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) (by simp)) (by cat_disch)) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Flipping a complex of complexes over the diagonal, as an equivalence of categories. -/ @[simps] diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 3e08e7221b051b..92c5358a95dd46 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -737,6 +737,7 @@ lemma mk_congr_succ_d₂ {S S' : ShortComplex V} (h : S = S') : subst h simp +set_option backward.isDefEq.respectTransparency.types false in lemma mkAux_eq_shortComplex_mk_d_comp_d (n : ℕ) : mkAux X₀ X₁ X₂ d₀ d₁ s succ n = ShortComplex.mk _ _ ((mk X₀ X₁ X₂ d₀ d₁ s succ).d_comp_d (n + 2) (n + 1) n) := by @@ -753,6 +754,7 @@ def mkXIso (n : ℕ) : (mkAux_eq_shortComplex_mk_d_comp_d X₀ X₁ X₂ d₀ d₁ s succ n)] rfl) +set_option backward.isDefEq.respectTransparency.types false in lemma mk_d (n : ℕ) : (mk X₀ X₁ X₂ d₀ d₁ s succ).d (n + 3) (n + 2) = (mkXIso X₀ X₁ X₂ d₀ d₁ s succ n).hom ≫ (succ @@ -793,6 +795,7 @@ theorem mk'_d_1_0 : (mk' X₀ X₁ d₀ succ').d 1 0 = d₀ := by change ite (1 = 0 + 1) (𝟙 X₁ ≫ d₀) 0 = d₀ rw [if_pos rfl, Category.id_comp] +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism from `(mk' X₀ X₁ d₀ succ').X (n + 2)` that is given by the inductive construction. -/ def mk'XIso (n : ℕ) : diff --git a/Mathlib/Algebra/Homology/HomologicalComplexBiprod.lean b/Mathlib/Algebra/Homology/HomologicalComplexBiprod.lean index d8234ae73ca56d..4135b304884899 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplexBiprod.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplexBiprod.lean @@ -58,12 +58,14 @@ lemma inr_biprodXIso_inv (i : ι) : biprod.inr ≫ (biprodXIso K L i).inv = (biprod.inr : L ⟶ K ⊞ L).f i := by simp [biprodXIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma biprodXIso_hom_fst (i : ι) : (biprodXIso K L i).hom ≫ biprod.fst = (biprod.fst : K ⊞ L ⟶ K).f i := by simp [biprodXIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma biprodXIso_hom_snd (i : ι) : diff --git a/Mathlib/Algebra/Homology/HomologySequence.lean b/Mathlib/Algebra/Homology/HomologySequence.lean index c0445b350b4200..0b0b69e73648f8 100644 --- a/Mathlib/Algebra/Homology/HomologySequence.lean +++ b/Mathlib/Algebra/Homology/HomologySequence.lean @@ -109,12 +109,14 @@ noncomputable def composableArrows₃ [K.HasHomology i] [K.HasHomology j] : ComposableArrows C 3 := ComposableArrows.mk₃ (K.homologyι i) (K.opcyclesToCycles i j) (K.homologyπ j) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [K.HasHomology i] [K.HasHomology j] : Mono ((composableArrows₃ K i j).map' 0 1) := by dsimp infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [K.HasHomology i] [K.HasHomology j] : Epi ((composableArrows₃ K i j).map' 2 3) := by @@ -153,6 +155,7 @@ variable (C) attribute [local simp] homologyMap_comp cyclesMap_comp opcyclesMap_comp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `HomologicalComplex C c ⥤ ComposableArrows C 3` that maps `K` to the diagram `K.homology i ⟶ K.opcycles i ⟶ K.cycles j ⟶ K.homology j`. -/ diff --git a/Mathlib/Algebra/Homology/HomologySequenceLemmas.lean b/Mathlib/Algebra/Homology/HomologySequenceLemmas.lean index 96602c613cc295..c35667a6657a61 100644 --- a/Mathlib/Algebra/Homology/HomologySequenceLemmas.lean +++ b/Mathlib/Algebra/Homology/HomologySequenceLemmas.lean @@ -40,6 +40,7 @@ namespace HomologicalComplex namespace HomologySequence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The morphism `snakeInput hS₁ i j hij ⟶ snakeInput hS₂ i j hij` induced by a morphism `φ : S₁ ⟶ S₂` of short complexes of homological complexes, that @@ -52,6 +53,7 @@ noncomputable def mapSnakeInput (i j : ι) (hij : c.Rel i j) : f₂ := (cyclesFunctor C c j).mapShortComplex.map φ f₃ := (homologyFunctor C c j).mapShortComplex.map φ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma δ_naturality (i j : ι) (hij : c.Rel i j) : hS₁.δ i j hij ≫ HomologicalComplex.homologyMap φ.τ₁ _ = diff --git a/Mathlib/Algebra/Homology/Homotopy.lean b/Mathlib/Algebra/Homology/Homotopy.lean index a931b79b3bbc97..9459cf7dc9c6f3 100644 --- a/Mathlib/Algebra/Homology/Homotopy.lean +++ b/Mathlib/Algebra/Homology/Homotopy.lean @@ -483,6 +483,7 @@ def mkInductiveAux₁ : section +set_option backward.isDefEq.respectTransparency.types false in /-- An auxiliary construction for `mkInductive`. -/ def mkInductiveAux₂ : @@ -493,23 +494,27 @@ def mkInductiveAux₂ : one comm_one succ n ⟨(P.xNextIso rfl).hom ≫ I.1, I.2.1 ≫ (Q.xPrevIso rfl).inv, by simpa using! I.2.2⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mkInductiveAux₂_zero : mkInductiveAux₂ e zero comm_zero one comm_one succ 0 = ⟨0, zero ≫ (Q.xPrevIso rfl).inv, by simpa using comm_zero⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mkInductiveAux₂_add_one (n) : mkInductiveAux₂ e zero comm_zero one comm_one succ (n + 1) = letI I := mkInductiveAux₁ e zero one comm_one succ n ⟨(P.xNextIso rfl).hom ≫ I.1, I.2.1 ≫ (Q.xPrevIso rfl).inv, by simpa using! I.2.2⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem mkInductiveAux₃ (i j : ℕ) (h : i + 1 = j) : (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.1 ≫ (Q.xPrevIso h).hom = (P.xNextIso h).inv ≫ (mkInductiveAux₂ e zero comm_zero one comm_one succ j).1 := by subst j rcases i with (_ | _ | i) <;> simp [mkInductiveAux₂] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed chain complexes, working by induction. @@ -613,6 +618,7 @@ def mkCoinductiveAux₁ : section +set_option backward.isDefEq.respectTransparency.types false in /-- An auxiliary construction for `mkInductive`. -/ def mkCoinductiveAux₂ : @@ -622,23 +628,27 @@ def mkCoinductiveAux₂ : let I := mkCoinductiveAux₁ e zero one comm_one succ n ⟨I.1 ≫ (Q.xPrevIso rfl).inv, (P.xNextIso rfl).hom ≫ I.2.1, by simpa using! I.2.2⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mkCoinductiveAux₂_zero : mkCoinductiveAux₂ e zero comm_zero one comm_one succ 0 = ⟨0, (P.xNextIso rfl).hom ≫ zero, by simpa using comm_zero⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mkCoinductiveAux₂_add_one (n) : mkCoinductiveAux₂ e zero comm_zero one comm_one succ (n + 1) = letI I := mkCoinductiveAux₁ e zero one comm_one succ n ⟨I.1 ≫ (Q.xPrevIso rfl).inv, (P.xNextIso rfl).hom ≫ I.2.1, by simpa using! I.2.2⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem mkCoinductiveAux₃ (i j : ℕ) (h : i + 1 = j) : (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.1 = (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).1 ≫ (Q.xPrevIso h).hom := by subst j rcases i with (_ | _ | i) <;> simp [mkCoinductiveAux₂] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes, working by induction. diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean b/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean index 3cb9ceb13198ed..e5fe56e3d4ea1c 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean @@ -216,6 +216,7 @@ noncomputable def triangleRotateShortComplexSplitting (n : ℤ) : r := (snd φ).v n n (add_zero n) id := by simp [ext_from_iff φ _ _ rfl] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma cocycleOfDegreewiseSplit_triangleRotateShortComplexSplitting_v (p : ℤ) : diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 95f768f08d271c..781737c50ae548 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -778,6 +778,7 @@ def Cocycle.postcomp {n : ℤ} (z : Cocycle F G n) (f : G ⟶ K) : Cocycle F K n namespace Cochain +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given two morphisms of complexes `φ₁ φ₂ : F ⟶ G`, the datum of a homotopy between `φ₁` and `φ₂` is equivalent to the datum of a `1`-cochain `z` such that `δ (-1) 0 z` is the difference diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index d251133210dbbf..7d3ea6fd41faa6 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -53,6 +53,7 @@ def coboundaries : AddSubgroup (Cocycle K L n) where rintro α ⟨m, hm, β, hβ⟩ exact ⟨m, hm, -β, by aesop⟩ +set_option backward.isDefEq.respectTransparency.types false in variable {K L n} in lemma mem_coboundaries_iff (α : Cocycle K L n) (m : ℤ) (hm : m + 1 = n) : α ∈ coboundaries K L n ↔ ∃ (β : Cochain K L m), δ m n β = α := by diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean index ee5bf10f3124ec..d7dba586be210c 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean @@ -116,6 +116,7 @@ lemma shift_v (a : ℤ) (p q : ℤ) (hpq : p + n = q) (p' q' : ℤ) subst hp' hq' rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma shift_v' (a : ℤ) (p q : ℤ) (hpq : p + n = q) : (γ.shift a).v p q hpq = γ.v (p + a) (q + a) (by lia) := by @@ -583,6 +584,7 @@ def equivHomShift : (K ⟶ L⟦n⟧) ≃+ Cocycle K L n := (equivHom _ _).trans (rightShiftAddEquiv _ _ _ (zero_add n)).symm +set_option backward.isDefEq.respectTransparency.types false in lemma equivHomShift_comp {K' : CochainComplex C ℤ} (g : K' ⟶ K) (f : K ⟶ L⟦n⟧) : equivHomShift (g ≫ f) = Cocycle.precomp (equivHomShift f) g := by @@ -594,6 +596,7 @@ lemma equivHomShift_symm_precomp equivHomShift.symm (z.precomp g) = g ≫ equivHomShift.symm z := equivHomShift.injective (by simp [equivHomShift_comp]) +set_option backward.isDefEq.respectTransparency.types false in lemma equivHomShift_comp_shift (f : K ⟶ L⟦n⟧) {L' : CochainComplex C ℤ} (g : L ⟶ L') : equivHomShift (f ≫ g⟦n⟧') = Cocycle.postcomp (equivHomShift f) g := by ext p q rfl diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index e7e8d5105eb8cb..5f69fc2041de8b 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -86,6 +86,7 @@ noncomputable def fromSingleEquiv {p q n : ℤ} (h : p + n = q) : right_inv f := by simp map_add' := by simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma fromSingleEquiv_fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : fromSingleEquiv h (fromSingleMk f h) = f := by diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/KProjective.lean b/Mathlib/Algebra/Homology/HomotopyCategory/KProjective.lean index 8a4206394750e5..e53b0d77c9ef06 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/KProjective.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/KProjective.lean @@ -106,6 +106,7 @@ lemma isKProjective_of_op {K : CochainComplex C ℤ} ((opEquivalence C).functor.map f.op) (acyclic_op hL)).trans (.ofEq (by simp)))⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] opEquivalence ChainComplex.cochainComplexEquivalence in open Cochain.InductionUp in diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/MappingCone.lean b/Mathlib/Algebra/Homology/HomotopyCategory/MappingCone.lean index 5160488fd7fa88..f8d62c2be710f3 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/MappingCone.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/MappingCone.lean @@ -168,6 +168,7 @@ lemma inr_snd_assoc {K : CochainComplex C ℤ} {d e : ℤ} (γ : Cochain G K d) obtain rfl : d = e := by lia rw [← Cochain.comp_assoc_of_first_is_zero_cochain, inr_snd, Cochain.id_comp] +set_option backward.isDefEq.respectTransparency.types false in lemma ext_to (i j : ℤ) (hij : i + 1 = j) {A : C} {f g : A ⟶ (mappingCone φ).X i} (h₁ : f ≫ (fst φ).1.v i j hij = g ≫ (fst φ).1.v i j hij) (h₂ : f ≫ (snd φ).v i i (add_zero i) = g ≫ (snd φ).v i i (add_zero i)) : @@ -255,6 +256,7 @@ lemma id_X (p q : ℤ) (hpq : p + 1 = q) : Cochain.comp_v _ _ (add_neg_cancel 1) p q p hpq (by lia)] using Cochain.congr_v (id φ) p p (add_zero p) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma inl_v_d (i j k : ℤ) (hij : i + (-1) = j) (hik : k + (-1) = i) : @@ -281,6 +283,7 @@ lemma d_fst_v' (i j : ℤ) (hij : i + 1 = j) : -(fst φ).1.v (i - 1) i (by lia) ≫ F.d i j := d_fst_v φ (i - 1) i j (by lia) hij +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma d_snd_v (i j : ℤ) (hij : i + 1 = j) : (mappingCone φ).d i j ≫ (snd φ).v j j (add_zero _) = diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean index 352d3a8ee1bca5..07a060e2b0b553 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Plus.lean @@ -203,6 +203,7 @@ section variable [HasZeroObject C] [HasBinaryBiproducts C] +set_option backward.isDefEq.respectTransparency.types false in open HomologicalComplex in set_option backward.defeqAttrib.useBackward true in instance : @@ -239,6 +240,7 @@ noncomputable def singleFunctorCompιIso (n : ℤ) : singleFunctor C n ⋙ ι C ≅ HomotopyCategory.singleFunctor C n := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in instance (n : ℤ) : (singleFunctor C n).Additive := by dsimp [singleFunctor, singleFunctors] infer_instance @@ -256,6 +258,7 @@ namespace Functor variable {C D} variable (F : C ⥤ D) [F.Additive] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor between bounded below homotopy categories that is induced by an additive functor. -/ diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Pretriangulated.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Pretriangulated.lean index a38b8e5ab1fe2f..d6b6251685c0b8 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/Pretriangulated.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Pretriangulated.lean @@ -488,6 +488,7 @@ lemma isomorphic_distinguished (T₁ : Triangle (HomotopyCategory C (ComplexShap obtain ⟨X, Y, f, ⟨e'⟩⟩ := hT₁ exact ⟨X, Y, f, ⟨e ≪≫ e'⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable [HasZeroObject C] in lemma contractible_distinguished (X : HomotopyCategory C (ComplexShape.up ℤ)) : diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean index fde81639dbe022..1620345d889941 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean @@ -83,6 +83,7 @@ variable (C) attribute [local simp] XIsoOfEq_hom_naturality +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The shift functor by `n` on `CochainComplex C ℤ` identifies to the identity functor when `n = 0`. -/ @@ -111,6 +112,7 @@ def shiftFunctorAdd' (n₁ n₂ n₁₂ : ℤ) (h : n₁ + n₂ = n₁₂) : attribute [local simp] XIsoOfEq +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : HasShift (CochainComplex C ℤ) ℤ := hasShiftMk _ _ { F := shiftFunctor C @@ -127,23 +129,28 @@ instance (n : ℤ) {R : Type*} [Ring R] [Linear R C] : end +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctor_obj_X' (K : CochainComplex C ℤ) (n p : ℤ) : ((CategoryTheory.shiftFunctor (CochainComplex C ℤ) n).obj K).X p = K.X (p + n) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctor_map_f' {K L : CochainComplex C ℤ} (φ : K ⟶ L) (n p : ℤ) : ((CategoryTheory.shiftFunctor (CochainComplex C ℤ) n).map φ).f p = φ.f (p + n) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctor_obj_d' (K : CochainComplex C ℤ) (n i j : ℤ) : ((CategoryTheory.shiftFunctor (CochainComplex C ℤ) n).obj K).d i j = n.negOnePow • K.d _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma shiftFunctorAdd_inv_app_f (K : CochainComplex C ℤ) (a b n : ℤ) : ((shiftFunctorAdd (CochainComplex C ℤ) a b).inv.app K).f n = (K.XIsoOfEq (by dsimp; rw [add_comm a, add_assoc])).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma shiftFunctorAdd_hom_app_f (K : CochainComplex C ℤ) (a b n : ℤ) : ((shiftFunctorAdd (CochainComplex C ℤ) a b).hom.app K).f n = (K.XIsoOfEq (by dsimp; rw [add_comm a, add_assoc])).hom := by @@ -175,6 +182,7 @@ lemma XIsoOfEq_shift (K : CochainComplex C ℤ) (n : ℤ) {p q : ℤ} (hpq : p = variable (C) +set_option backward.isDefEq.respectTransparency.types false in lemma shiftFunctorAdd'_eq (a b c : ℤ) (h : a + b = c) : CategoryTheory.shiftFunctorAdd' (CochainComplex C ℤ) a b c h = shiftFunctorAdd' C a b c h := by @@ -206,6 +214,7 @@ variable (C) attribute [local simp] XIsoOfEq_hom_naturality +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Shifting cochain complexes by `n` and evaluating in a degree `i` identifies to the evaluation in degree `i'` when `n + i = i'`. -/ diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean b/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean index 2a3a0d3a619473..dab3233c370f21 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean @@ -34,6 +34,7 @@ namespace CochainComplex open HomologicalComplex +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The collection of all single functors `C ⥤ CochainComplex C ℤ` along with their compatibilities with shifts. (This definition has purposely no `simps` diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Triangulated.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Triangulated.lean index d741b1d3512ba9..fb3ed7522a4b6e 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/Triangulated.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Triangulated.lean @@ -149,6 +149,7 @@ lemma mappingConeCompHomotopyEquiv_hom_inv_id : (mappingConeCompHomotopyEquiv f g).inv = 𝟙 _ := by simp [mappingConeCompHomotopyEquiv] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma mappingConeCompHomotopyEquiv_comm₁ : diff --git a/Mathlib/Algebra/Homology/HomotopyCofiber.lean b/Mathlib/Algebra/Homology/HomotopyCofiber.lean index 36be79f5f5c90a..22faf6867b78bf 100644 --- a/Mathlib/Algebra/Homology/HomotopyCofiber.lean +++ b/Mathlib/Algebra/Homology/HomotopyCofiber.lean @@ -256,7 +256,7 @@ end homotopyCofiber /-- The homotopy cofiber of a morphism of homological complexes, also known as the mapping cone. -/ -@[simps] +@[simps, implicit_reducible] noncomputable def homotopyCofiber : HomologicalComplex C c where X i := homotopyCofiber.X φ i d i j := homotopyCofiber.d φ i j @@ -340,6 +340,7 @@ lemma desc_f' (j : ι) (hj : ¬ c.Rel j (c.next j)) : (desc φ α hα).f j = sndX φ j ≫ α.f j := by apply dif_neg hj +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma inlX_desc_f (i j : ι) (hjk : c.Rel j i) : inlX φ i j hjk ≫ (desc φ α hα).f j = hα.hom i j := by diff --git a/Mathlib/Algebra/Homology/LeftResolution/Basic.lean b/Mathlib/Algebra/Homology/LeftResolution/Basic.lean index f1812fe8f42e35..6a80153301a37f 100644 --- a/Mathlib/Algebra/Homology/LeftResolution/Basic.lean +++ b/Mathlib/Algebra/Homology/LeftResolution/Basic.lean @@ -85,7 +85,6 @@ noncomputable def chainComplexXIso (n : ℕ) : (Λ.chainComplex X).X (n + 2) ≅ Λ.F.obj (kernel (ι.map ((Λ.chainComplex X).d (n + 1) n))) := by apply ChainComplex.mk'XIso -set_option backward.isDefEq.respectTransparency false in lemma map_chainComplex_d (n : ℕ) : ι.map ((Λ.chainComplex X).d (n + 2) (n + 1)) = ι.map (Λ.chainComplexXIso X n).hom ≫ Λ.π.app (kernel (ι.map ((Λ.chainComplex X).d (n + 1) n))) ≫ @@ -98,8 +97,8 @@ lemma map_chainComplex_d (n : ℕ) : attribute [irreducible] chainComplex +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma exactAt_map_chainComplex_succ (n : ℕ) : ((ι.mapHomologicalComplex _).obj (Λ.chainComplex X)).ExactAt (n + 1) := by rw [HomologicalComplex.exactAt_iff' _ (n + 2) (n + 1) n diff --git a/Mathlib/Algebra/Homology/LeftResolution/Reduced.lean b/Mathlib/Algebra/Homology/LeftResolution/Reduced.lean index 256429bdee2b0b..af10ddb18adcde 100644 --- a/Mathlib/Algebra/Homology/LeftResolution/Reduced.lean +++ b/Mathlib/Algebra/Homology/LeftResolution/Reduced.lean @@ -94,7 +94,6 @@ lemma karoubi.π_app_toKaroubi_obj (X : A) : (karoubi.π Λ).app ((toKaroubi _).obj X) = (karoubi.π' Λ).app X := by simp [π, whiskeringLeftObjToKaroubiFullyFaithful] -set_option backward.isDefEq.respectTransparency false in instance (X : A) : Epi ((karoubi.π Λ).app ((toKaroubi _).obj X)) := by rw [karoubi.π_app_toKaroubi_obj] infer_instance diff --git a/Mathlib/Algebra/Homology/LeftResolution/Transport.lean b/Mathlib/Algebra/Homology/LeftResolution/Transport.lean index 3755ee4cf22158..c37a923c087eea 100644 --- a/Mathlib/Algebra/Homology/LeftResolution/Transport.lean +++ b/Mathlib/Algebra/Homology/LeftResolution/Transport.lean @@ -28,10 +28,9 @@ variable {A C : Type*} [Category* C] [Category* A] namespace LeftResolution -open Functor +open CategoryTheory.Functor set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Transport `LeftResolution` via equivalences of categories. -/ def transport {ι : C ⥤ A} (Λ : LeftResolution ι) {ι' : C' ⥤ A'} (eA : A' ≌ A) (eC : C' ≌ C) (e : ι' ⋙ eA.functor ≅ eC.functor ⋙ ι) : @@ -48,7 +47,6 @@ def transport {ι : C ⥤ A} (Λ : LeftResolution ι) {ι' : C' ⥤ A'} (rightUnitor _).hom) _) ≫ eA.unitIso.inv epi_π_app _ := by dsimp; infer_instance -set_option backward.isDefEq.respectTransparency false in /-- If we have an isomorphism `e : G ⋙ ι' ≅ ι`, then any `Λ : LeftResolution ι` induces `Λ.ofCompIso e : LeftResolution ι'`. -/ def ofCompIso {ι : C ⥤ A} (Λ : LeftResolution ι) {ι' : C' ⥤ A} {G : C ⥤ C'} diff --git a/Mathlib/Algebra/Homology/Localization.lean b/Mathlib/Algebra/Homology/Localization.lean index 715f0183478b8c..5cf355a56d8932 100644 --- a/Mathlib/Algebra/Homology/Localization.lean +++ b/Mathlib/Algebra/Homology/Localization.lean @@ -403,6 +403,7 @@ noncomputable instance : variable {c} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma mapHomologicalComplexUpToQuasiIsoFactorsh_hom_app (K : HomologicalComplex C c) : diff --git a/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean b/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean index 4a8d77e9b58f8b..4136c5fe2af3c5 100644 --- a/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean +++ b/Mathlib/Algebra/Homology/ModelCategory/Lifting.lean @@ -56,6 +56,7 @@ cokernel of `i : A ⟶ B` and `K` a kernel of `p : X ⟶ Y` (see `cocycle₁`). def cocycle₁' : Cocycle B X 1 := Cocycle.mk (δ 0 1 (cochain₀ sq hsq)) 2 (by simp) (by simp [δ_δ]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma coe_cocycle₁'_v_comp_eq_zero (n m : ℤ) (hnm : n + 1 = m := by lia) : @@ -65,6 +66,7 @@ lemma coe_cocycle₁'_v_comp_eq_zero (n m : ℤ) (hnm : n + 1 = m := by lia) : simp [cocycle₁', -HomologicalComplex.Hom.comm, ← p.comm, fac_right, reassoc_of% fac_right, b.comm] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma comp_coe_cocyle₁'_v_eq_zero (n m : ℤ) (hnm : n + 1 = m := by lia) : @@ -122,6 +124,7 @@ lemma comp_coe_cocycle₁_comp : ext n m hnm simp [cocycle₁] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Consider a commutative square in the category `CochainComplex C ℤ` diff --git a/Mathlib/Algebra/Homology/Monoidal.lean b/Mathlib/Algebra/Homology/Monoidal.lean index b4473aebf23bf7..1f1c41dc705523 100644 --- a/Mathlib/Algebra/Homology/Monoidal.lean +++ b/Mathlib/Algebra/Homology/Monoidal.lean @@ -125,6 +125,7 @@ section variable [∀ X₂, PreservesColimit (Functor.empty.{0} C) ((curriedTensor C).flip.obj X₂)] +set_option backward.isDefEq.respectTransparency.types false in instance : GradedObject.HasTensor (tensorUnit C c).X K.X := GradedObject.hasTensor_of_iso (tensorUnitIso C c) (Iso.refl _) @@ -147,6 +148,7 @@ section variable [∀ X₁, PreservesColimit (Functor.empty.{0} C) ((curriedTensor C).obj X₁)] +set_option backward.isDefEq.respectTransparency.types false in instance : GradedObject.HasTensor K.X (tensorUnit C c).X := GradedObject.hasTensor_of_iso (Iso.refl _) (tensorUnitIso C c) @@ -175,6 +177,7 @@ section LeftUnitor variable [∀ X₂, PreservesColimit (Functor.empty.{0} C) ((curriedTensor C).flip.obj X₂)] +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `leftUnitor`. -/ noncomputable def leftUnitor' : (tensorObj (tensorUnit C c) K).X ≅ K.X := @@ -225,6 +228,7 @@ section RightUnitor variable [∀ X₁, PreservesColimit (Functor.empty.{0} C) ((curriedTensor C).obj X₁)] +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `rightUnitor`. -/ noncomputable def rightUnitor' : (tensorObj K (tensorUnit C c)).X ≅ K.X := @@ -279,6 +283,7 @@ variable (C c) [∀ (X₁ X₂ : GradedObject I C), GradedObject.HasTensor X₁ [∀ (X₁ X₂ X₃ : GradedObject I C), GradedObject.HasGoodTensorTensor₂₃ X₁ X₂ X₃] [DecidableEq I] +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance monoidalCategoryStruct : MonoidalCategoryStruct (HomologicalComplex C c) where tensorObj K₁ K₂ := tensorObj K₁ K₂ @@ -335,6 +340,7 @@ noncomputable def Monoidal.inducingFunctorData : noncomputable instance monoidalCategory : MonoidalCategory (HomologicalComplex C c) := Monoidal.induced _ (Monoidal.inducingFunctorData C c) +set_option backward.isDefEq.respectTransparency.types false in noncomputable example {D : Type*} [Category* D] [Preadditive D] [MonoidalCategory D] [HasZeroObject D] [HasFiniteCoproducts D] [((curriedTensor D).Additive)] [∀ (X : D), (((curriedTensor D).obj X).Additive)] diff --git a/Mathlib/Algebra/Homology/Opposite.lean b/Mathlib/Algebra/Homology/Opposite.lean index f839402d2fa9bc..95ddefeb50cc8d 100644 --- a/Mathlib/Algebra/Homology/Opposite.lean +++ b/Mathlib/Algebra/Homology/Opposite.lean @@ -53,6 +53,7 @@ theorem imageToKernel_op {X Y Z : V} (f : X ⟶ Y) (g : Y ⟶ Z) (w : f ≫ g = ← imageSubobject_arrow, ← imageUnopOp_inv_comp_op_factorThruImage g.op] rfl +set_option backward.isDefEq.respectTransparency.types false in theorem imageToKernel_unop {X Y Z : Vᵒᵖ} (f : X ⟶ Y) (g : Y ⟶ Z) (w : f ≫ g = 0) : imageToKernel g.unop f.unop (by rw [← unop_comp, w, unop_zero]) = (imageSubobjectIso _ ≪≫ (imageUnopUnop _).symm).hom ≫ @@ -143,12 +144,14 @@ def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInve ext x simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `opEquivalence`. -/ def opCounitIso : opInverse V c ⋙ opFunctor V c ≅ 𝟭 (HomologicalComplex Vᵒᵖ c.symm) := NatIso.ofComponents fun X => HomologicalComplex.Hom.isoOfComponents fun _ => Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a category of complexes with objects in `V`, there is a natural equivalence between its opposite category and a category of complexes with objects in `Vᵒᵖ`. -/ @[simps] @@ -200,12 +203,14 @@ def unopUnitIso : 𝟭 (HomologicalComplex Vᵒᵖ c)ᵒᵖ ≅ unopFunctor V c ext x simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `unopEquivalence`. -/ def unopCounitIso : unopInverse V c ⋙ unopFunctor V c ≅ 𝟭 (HomologicalComplex V c.symm) := NatIso.ofComponents fun X => HomologicalComplex.Hom.isoOfComponents fun _ => Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a category of complexes with objects in `Vᵒᵖ`, there is a natural equivalence between its opposite category and a category of complexes with objects in `V`. -/ @[simps] @@ -375,25 +380,36 @@ section variable {K L : HomologicalComplex V c} (φ : K ⟶ L) (i : ι) [K.HasHomology i] [L.HasHomology i] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma homologyOp_hom_naturality : homologyMap ((opFunctor _ _).map φ.op) _ ≫ (K.homologyOp i).hom = (L.homologyOp i).hom ≫ (homologyMap φ i).op := ShortComplex.homologyOpIso_hom_naturality ((shortComplexFunctor V c i).map φ) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma opcyclesOpIso_hom_naturality : opcyclesMap ((opFunctor _ _).map φ.op) _ ≫ (K.opcyclesOpIso i).hom = (L.opcyclesOpIso i).hom ≫ (cyclesMap φ i).op := ShortComplex.opcyclesOpIso_hom_naturality ((shortComplexFunctor V c i).map φ) -set_option backward.isDefEq.respectTransparency false in -- This is needed in Algebra/Homology/Embedding/TruncLE.lean +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma opcyclesOpIso_inv_naturality : (cyclesMap φ i).op ≫ (K.opcyclesOpIso i).inv = (L.opcyclesOpIso i).inv ≫ opcyclesMap ((opFunctor _ _).map φ.op) _ := ShortComplex.opcyclesOpIso_inv_naturality ((shortComplexFunctor V c i).map φ) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma cyclesOpIso_hom_naturality : cyclesMap ((opFunctor _ _).map φ.op) _ ≫ (K.cyclesOpIso i).hom = diff --git a/Mathlib/Algebra/Homology/ShortComplex/Ab.lean b/Mathlib/Algebra/Homology/ShortComplex/Ab.lean index 1e243adf91d991..cc5fed3e0e56d4 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Ab.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Ab.lean @@ -100,6 +100,7 @@ noncomputable def abHomologyIso : S.homology ≅ AddCommGrpCat.of ((AddMonoidHom.ker S.g.hom) ⧸ AddMonoidHom.range S.abToCycles) := S.abLeftHomologyData.homologyIso +set_option backward.isDefEq.respectTransparency.types false in lemma exact_iff_surjective_abToCycles : S.Exact ↔ Function.Surjective S.abToCycles := by rw [S.abLeftHomologyData.exact_iff_epi_f', abLeftHomologyData_f', diff --git a/Mathlib/Algebra/Homology/ShortComplex/Basic.lean b/Mathlib/Algebra/Homology/ShortComplex/Basic.lean index 4f1674401779fc..4592fde38cb51a 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Basic.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Basic.lean @@ -301,6 +301,7 @@ def unopFunctor : ShortComplex Cᵒᵖ ⥤ (ShortComplex C)ᵒᵖ where obj S := Opposite.op (S.unop) map φ := (unopMap φ).op +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The obvious equivalence of categories `(ShortComplex C)ᵒᵖ ≌ ShortComplex Cᵒᵖ`. -/ @[simps] @@ -312,9 +313,11 @@ def opEquiv : (ShortComplex C)ᵒᵖ ≌ ShortComplex Cᵒᵖ where variable {C} +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical isomorphism `S.unop.op ≅ S` for a short complex `S` in `Cᵒᵖ` -/ abbrev unopOp (S : ShortComplex Cᵒᵖ) : S.unop.op ≅ S := (opEquiv C).counitIso.app S +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical isomorphism `S.op.unop ≅ S` for a short complex `S` -/ abbrev opUnop (S : ShortComplex C) : S.op.unop ≅ S := Iso.unop ((opEquiv C).unitIso.app (Opposite.op S)) diff --git a/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean b/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean index 7b72b407653665..337af372b432e6 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean @@ -166,7 +166,6 @@ lemma δ_apply (x₃ : ToType (D.L₀.X₃)) (x₂ : ToType (D.L₁.X₂)) (x₁ rw [ConcreteCategory.comp_apply, eq₁] exact h₁.symm -set_option backward.isDefEq.respectTransparency false in /-- This lemma allows the computation of the connecting homomorphism `D.δ` when `D : SnakeInput C` and `C` is a concrete category. -/ lemma δ_apply' (x₃ : (forget₂ C Ab).obj D.L₀.X₃) diff --git a/Mathlib/Algebra/Homology/ShortComplex/FunctorEquivalence.lean b/Mathlib/Algebra/Homology/ShortComplex/FunctorEquivalence.lean index af18cdb9ab7b82..b45fb88625e230 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/FunctorEquivalence.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/FunctorEquivalence.lean @@ -20,7 +20,7 @@ that `C` has zero morphisms), then there is an equivalence of categories namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor variable (J C : Type*) [Category* J] [Category* C] [HasZeroMorphisms C] @@ -30,6 +30,7 @@ namespace FunctorEquivalence attribute [local simp] ShortComplex.Hom.comm₁₂ ShortComplex.Hom.comm₂₃ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The obvious functor `ShortComplex (J ⥤ C) ⥤ J ⥤ ShortComplex C`. -/ @[simps] @@ -40,6 +41,7 @@ def functor : ShortComplex (J ⥤ C) ⥤ J ⥤ ShortComplex C where map φ := { app := fun j => ((evaluation J C).obj j).mapShortComplex.map φ } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The obvious functor `(J ⥤ ShortComplex C) ⥤ ShortComplex (J ⥤ C)`. -/ @[simps] @@ -51,6 +53,7 @@ def inverse : (J ⥤ ShortComplex C) ⥤ ShortComplex (J ⥤ C) where map φ := Hom.mk (whiskerRight φ π₁) (whiskerRight φ π₂) (whiskerRight φ π₃) (by cat_disch) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit isomorphism of the equivalence `ShortComplex.functorEquivalence : ShortComplex (J ⥤ C) ≌ J ⥤ ShortComplex C`. -/ @@ -62,6 +65,7 @@ def unitIso : 𝟭 _ ≅ functor J C ⋙ inverse J C := (NatIso.ofComponents (fun _ => Iso.refl _) (by simp)) (by cat_disch) (by cat_disch)) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit isomorphism of the equivalence `ShortComplex.functorEquivalence : ShortComplex (J ⥤ C) ≌ J ⥤ ShortComplex C`. -/ @@ -73,6 +77,7 @@ def counitIso : inverse J C ⋙ functor J C ≅ 𝟭 _ := end FunctorEquivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The obvious equivalence `ShortComplex (J ⥤ C) ≌ J ⥤ ShortComplex C`. -/ @[simps] diff --git a/Mathlib/Algebra/Homology/ShortComplex/HomologicalComplex.lean b/Mathlib/Algebra/Homology/ShortComplex/HomologicalComplex.lean index 8bf6fe4a551d0f..428bfbec684acc 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/HomologicalComplex.lean @@ -48,6 +48,7 @@ complex `K` to the short complex `K.X (c.prev i) ⟶ K.X i ⟶ K.X (c.next i)`. noncomputable def shortComplexFunctor (i : ι) := shortComplexFunctor' C c (c.prev i) i (c.next i) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism `shortComplexFunctor C c j ≅ shortComplexFunctor' C c i j k` when `c.prev j = i` and `c.next j = k`. -/ @@ -910,6 +911,7 @@ noncomputable def homologyIsoSc' : K.homology j ≅ (K.sc' i j k).homology := lemma homology_sc'_eq_homology [(K.sc' (c.prev j) j (c.next j)).HasHomology] : (K.sc' (c.prev j) j (c.next j)).homology = K.homology j := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma homologyIsoSc'_eq_refl [(K.sc' (c.prev j) j (c.next j)).HasHomology] : diff --git a/Mathlib/Algebra/Homology/ShortComplex/Homology.lean b/Mathlib/Algebra/Homology/ShortComplex/Homology.lean index b68c0c098a0417..9d4b0fc3859f81 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Homology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Homology.lean @@ -178,6 +178,9 @@ noncomputable def ofEpiOfIsIsoOfMono' (φ : S₁ ⟶ S₂) (h : HomologyData S right := RightHomologyData.ofEpiOfIsIsoOfMono' φ h.right iso := h.iso +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- If `e : S₁ ≅ S₂` is an isomorphism of short complexes and `h₁ : HomologyData S₁`, this is the homology data for `S₂` deduced from the isomorphism. -/ @[simps!] @@ -413,6 +416,7 @@ lemma LeftHomologyData.homologyIso_leftHomologyData [S.HasHomology] : dsimp [homologyIso, leftHomologyIso, ShortComplex.leftHomologyIso] rw [← leftHomologyMap'_comp, comp_id] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma RightHomologyData.homologyIso_rightHomologyData [S.HasHomology] : S.rightHomologyData.homologyIso = S.rightHomologyIso.symm := by @@ -1050,6 +1054,7 @@ noncomputable def homologyOpIso [S.HasHomology] : S.op.homology ≅ Opposite.op S.homology := S.op.leftHomologyIso.symm ≪≫ S.leftHomologyOpIso ≪≫ S.rightHomologyIso.symm.op +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma homologyMap'_op : (homologyMap' φ h₁ h₂).op = h₂.iso.inv.op ≫ homologyMap' (opMap φ) h₂.op h₁.op ≫ h₁.iso.hom.op := diff --git a/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean b/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean index 866f7a60ff3579..16648c557c4a46 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean @@ -133,6 +133,7 @@ lemma isIso_i (hg : S.g = 0) : IsIso h.i := ⟨h.liftK (𝟙 S.X₂) (by rw [hg, id_comp]), by simp only [← cancel_mono h.i, id_comp, assoc, liftK_i, comp_id], liftK_i _ _ _⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isIso_π (hf : S.f = 0) : IsIso h.π := by have ⟨φ, hφ⟩ := CokernelCofork.IsColimit.desc' h.hπ' (𝟙 _) @@ -142,6 +143,7 @@ lemma isIso_π (hf : S.f = 0) : IsIso h.π := by variable (S) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When the second map `S.g` is zero, this is the left homology data on `S` given by any colimit cokernel cofork of `S.f` -/ @@ -393,6 +395,7 @@ def ofIsLimitKernelFork (φ : S₁ ⟶ S₂) variable (S) +set_option backward.isDefEq.respectTransparency.types false in /-- When both maps `S.f` and `S.g` of a short complex `S` are zero, this is the left homology map data (for the identity of `S`) which relates the left homology data `ofZeros` and `ofIsColimitCokernelCofork`. -/ diff --git a/Mathlib/Algebra/Homology/ShortComplex/Limits.lean b/Mathlib/Algebra/Homology/ShortComplex/Limits.lean index 4c8d7970bd8976..dfc1c1722f7856 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Limits.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Limits.lean @@ -22,13 +22,14 @@ of a certain shape `J`, then it is also the case of the category `ShortComplex C namespace CategoryTheory -open Category Limits Functor +open Category Limits CategoryTheory.Functor variable {J C : Type*} [Category* J] [Category* C] [HasZeroMorphisms C] {F : J ⥤ ShortComplex C} namespace ShortComplex +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If a cone with values in `ShortComplex C` is such that it becomes limit when we apply the three projections `ShortComplex C ⥤ C`, then it is limit. -/ @@ -161,6 +162,7 @@ instance preservesMonomorphisms_π₃ : end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If a cocone with values in `ShortComplex C` is such that it becomes colimit when we apply the three projections `ShortComplex C ⥤ C`, then it is colimit. -/ diff --git a/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean b/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean index 8d67f596bcdfee..1fb56af551cbc3 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean @@ -485,6 +485,7 @@ def ofIsColimitCokernelCofork (φ : S₁ ⟶ S₂) variable (S) +set_option backward.isDefEq.respectTransparency.types false in /-- When both maps `S.f` and `S.g` of a short complex `S` are zero, this is the right homology map data (for the identity of `S`) which relates the right homology data `RightHomologyData.ofIsLimitKernelFork` and `ofZeros` . -/ @@ -1148,6 +1149,7 @@ noncomputable def ofEpiOfIsIsoOfMono : RightHomologyData S₂ := by @[simp] lemma ofEpiOfIsIsoOfMono_H : (ofEpiOfIsIsoOfMono φ h).H = h.H := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma ofEpiOfIsIsoOfMono_p : (ofEpiOfIsIsoOfMono φ h).p = inv φ.τ₂ ≫ h.p := by simp [ofEpiOfIsIsoOfMono, opMap] @@ -1179,6 +1181,7 @@ noncomputable def ofEpiOfIsIsoOfMono' : RightHomologyData S₁ := by @[simp] lemma ofEpiOfIsIsoOfMono'_H : (ofEpiOfIsIsoOfMono' φ h).H = h.H := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma ofEpiOfIsIsoOfMono'_p : (ofEpiOfIsIsoOfMono' φ h).p = φ.τ₂ ≫ h.p := by simp [ofEpiOfIsIsoOfMono', opMap] diff --git a/Mathlib/Algebra/Homology/Single.lean b/Mathlib/Algebra/Homology/Single.lean index 3a954e803a4ceb..f613890c7ae62d 100644 --- a/Mathlib/Algebra/Homology/Single.lean +++ b/Mathlib/Algebra/Homology/Single.lean @@ -204,6 +204,7 @@ variable {V} lemma single₀_obj_zero (A : V) : ((single₀ V).obj A).X 0 = A := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma single₀_map_f_zero {A B : V} (f : A ⟶ B) : @@ -232,12 +233,14 @@ noncomputable def toSingle₀Equiv (C : ChainComplex V ℕ) (X : V) : left_inv φ := by cat_disch right_inv f := by simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toSingle₀Equiv_symm_apply_f_zero {C : ChainComplex V ℕ} {X : V} (f : C.X 0 ⟶ X) (hf : C.d 1 0 ≫ f = 0) : ((toSingle₀Equiv C X).symm ⟨f, hf⟩).f 0 = f := by simp [toSingle₀Equiv] +set_option backward.isDefEq.respectTransparency.types false in /-- Morphisms from a single object chain complex with `X` concentrated in degree 0 to an `ℕ`-indexed chain complex `C` are the same as morphisms `f : X → C.X 0`. -/ @@ -249,6 +252,7 @@ noncomputable def fromSingle₀Equiv (C : ChainComplex V ℕ) (X : V) : left_inv := by cat_disch right_inv := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma fromSingle₀Equiv_symm_apply_f_zero {C : ChainComplex V ℕ} {X : V} (f : X ⟶ C.X 0) : @@ -274,6 +278,7 @@ variable {V} lemma single₀_obj_zero (A : V) : ((single₀ V).obj A).X 0 = A := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma single₀_map_f_zero {A B : V} (f : A ⟶ B) : @@ -300,12 +305,14 @@ noncomputable def fromSingle₀Equiv (C : CochainComplex V ℕ) (X : V) : left_inv φ := by cat_disch right_inv := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma fromSingle₀Equiv_symm_apply_f_zero {C : CochainComplex V ℕ} {X : V} (f : X ⟶ C.X 0) (hf : f ≫ C.d 0 1 = 0) : ((fromSingle₀Equiv C X).symm ⟨f, hf⟩).f 0 = f := by simp [fromSingle₀Equiv] +set_option backward.isDefEq.respectTransparency.types false in /-- Morphisms to a single object cochain complex with `X` concentrated in degree 0 to an `ℕ`-indexed cochain complex `C` are the same as morphisms `f : C.X 0 ⟶ X`. -/ @@ -317,6 +324,7 @@ noncomputable def toSingle₀Equiv (C : CochainComplex V ℕ) (X : V) : left_inv := by cat_disch right_inv := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toSingle₀Equiv_symm_apply_f_zero {C : CochainComplex V ℕ} {X : V} (f : C.X 0 ⟶ X) : diff --git a/Mathlib/Algebra/Homology/SingleHomology.lean b/Mathlib/Algebra/Homology/SingleHomology.lean index 8ab0c9128a685d..822522705b7a0e 100644 --- a/Mathlib/Algebra/Homology/SingleHomology.lean +++ b/Mathlib/Algebra/Homology/SingleHomology.lean @@ -65,12 +65,14 @@ noncomputable def singleObjHomologySelfIso : ((single C c j).obj A).homology j ≅ A := (((single C c j).obj A).isoHomologyπ _ j rfl rfl).symm ≪≫ singleObjCyclesSelfIso c j A +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma singleObjCyclesSelfIso_inv_iCycles : (singleObjCyclesSelfIso _ _ _).inv ≫ ((single C c j).obj A).iCycles j = (singleObjXSelf c j A).inv := by simp [singleObjCyclesSelfIso] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma homologyπ_singleObjHomologySelfIso_hom : ((single C c j).obj A).homologyπ j ≫ (singleObjHomologySelfIso _ _ _).hom = @@ -84,12 +86,14 @@ lemma singleObjHomologySelfIso_hom_singleObjHomologySelfIso_inv : simp only [← cancel_mono (singleObjHomologySelfIso _ _ _).hom, assoc, Iso.inv_hom_id, comp_id, homologyπ_singleObjHomologySelfIso_hom] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma singleObjCyclesSelfIso_hom_singleObjOpcyclesSelfIso_hom : (singleObjCyclesSelfIso c j A).hom ≫ (singleObjOpcyclesSelfIso c j A).hom = ((single C c j).obj A).iCycles j ≫ ((single C c j).obj A).pOpcycles j := by simp [singleObjCyclesSelfIso, singleObjOpcyclesSelfIso] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma singleObjCyclesSelfIso_inv_homologyπ : (singleObjCyclesSelfIso _ _ _).inv ≫ ((single C c j).obj A).homologyπ j = @@ -130,6 +134,7 @@ lemma pOpcycles_singleObjOpcyclesSelfIso_inv : variable {A} variable {B : C} (f : A ⟶ B) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma singleObjCyclesSelfIso_hom_naturality : cyclesMap ((single C c j).map f) j ≫ (singleObjCyclesSelfIso c j B).hom = diff --git a/Mathlib/Algebra/Homology/SpectralObject/Basic.lean b/Mathlib/Algebra/Homology/SpectralObject/Basic.lean index a3e0a1a237d15d..c4a7f0e8bdd839 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Basic.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Basic.lean @@ -64,6 +64,7 @@ def δ {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) (n₀ n₁ : ℤ) (hn₁ : n₀ (X.H n₀).obj (mk₁ g) ⟶ (X.H n₁).obj (mk₁ f) := (X.δ' n₀ n₁ hn₁).app (mk₂ f g) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma δ_naturality {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) diff --git a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean index 9c554a6b54f557..8720cc8a24458f 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean @@ -302,6 +302,7 @@ lemma toCycles_i (n : ℤ) : X.toCycles f g fg h n ≫ X.iCycles f g n = (X.H n).map (twoδ₁Toδ₀ f g fg h) := kernel.lift_ι .. +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma toCycles_cyclesMap (α : mk₂ f g ⟶ mk₂ f' g') (β : mk₁ fg ⟶ mk₁ fg') (n : ℤ) @@ -333,6 +334,7 @@ lemma p_fromOpcycles (n : ℤ) : (X.H n).map (twoδ₂Toδ₁ f g fg h) := cokernel.π_desc .. +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma opcyclesMap_fromOpcycles (α : mk₂ f g ⟶ mk₂ f' g') (β : mk₁ fg ⟶ mk₁ fg') (n : ℤ) diff --git a/Mathlib/Algebra/Homology/SpectralObject/Page.lean b/Mathlib/Algebra/Homology/SpectralObject/Page.lean index e238bd05a5dfd6..4944b8f3b23ece 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Page.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Page.lean @@ -437,6 +437,7 @@ noncomputable def descE (hn₂ : n₁ + 1 = n₂ := by lia) : X.E f₁ f₂ f₃ n₀ n₁ n₂ hn₁ hn₂ ⟶ A := (X.cokernelSequenceE_exact f₁ f₂ f₃ f₁₂ h₁₂ n₀ n₁ n₂).desc x (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma toCycles_πE_descE (hn₂ : n₁ + 1 = n₂ := by lia) : X.toCycles f₁ f₂ f₁₂ h₁₂ n₁ ≫ X.πE f₁ f₂ f₃ n₀ n₁ n₂ hn₁ hn₂ ≫ @@ -688,6 +689,9 @@ section variable {i j : ι} (f : i ⟶ j) {i' j' : ι} (f' : i' ⟶ j') +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An homology data for `X.shortComplex n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j)`, expressing `H^n₁(f)` as the homology of this short complex, see `EIsoH`. -/ @@ -706,6 +710,7 @@ noncomputable def EIsoH (n₀ n₁ n₂ : ℤ) X.E (𝟙 i) f (𝟙 j) n₀ n₁ n₂ hn₁ hn₂ ≅ (X.H n₁).obj (mk₁ f) := (X.homologyDataIdId ..).left.homologyIso +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma EIsoH_hom_naturality (α : mk₁ f ⟶ mk₁ f') (β : mk₃ (𝟙 _) f (𝟙 _) ⟶ mk₃ (𝟙 _) f' (𝟙 _)) @@ -871,6 +876,7 @@ noncomputable def shortComplexOpcyclesThreeδ₂Toδ₁ ShortComplex.mk _ _ (X.opcyclesMap_threeδ₂Toδ₁_opcyclesToE f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃ n₀ n₁ n₂ hn₁ hn₂) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) : Mono (X.shortComplexOpcyclesThreeδ₂Toδ₁ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃ n₀ n₁ n₂ hn₁ hn₂).f := by diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index a0b5f70d184daf..91e6c7d8189ac0 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -185,6 +185,7 @@ noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : d := pageD X data r shape pq pq' hpq := dif_neg hpq +set_option backward.isDefEq.respectTransparency.types false in /-- The short complex of the `r`th page of the spectral sequence on position `pq'` identifies to the short complex given by the differentials of the spectral object. Then, the homology of this short complex can be computed using @@ -579,6 +580,9 @@ variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (n₀ n₁ n₂ : ℤ) (hn₁' : n₁ = data.deg pq') +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in unseal spectralSequence in /-- The homology data for the short complexes given by the differentials of a spectral sequence attached to a spectral object in an abelian category. -/ @@ -612,6 +616,7 @@ lemma spectralSequenceHomologyData_right_p X.mapFourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₃' _ _ _ (data.le₃₃' hrr' hr pq' hi₃ hi₃') n₀ n₁ n₂ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma spectralSequenceHomologyData_right_homologyIso_eq_left_homologyIso (hn₁ : n₀ + 1 = n₁ := by lia) (hn₂ : n₁ + 1 = n₂ := by lia) : @@ -622,6 +627,7 @@ lemma spectralSequenceHomologyData_right_homologyIso_eq_left_homologyIso ext1 simp [ShortComplex.HomologyData.right_homologyIso_eq_left_homologyIso_trans_iso] +set_option backward.isDefEq.respectTransparency.types false in unseal spectralSequence in lemma spectralSequence_iso (hn₁ : n₀ + 1 = n₁ := by lia) (hn₂ : n₁ + 1 = n₂ := by lia) : (X.spectralSequence data).iso r r' pq' = diff --git a/Mathlib/Algebra/Homology/TotalComplex.lean b/Mathlib/Algebra/Homology/TotalComplex.lean index bd6d9e398455b1..14e126e05f0240 100644 --- a/Mathlib/Algebra/Homology/TotalComplex.lean +++ b/Mathlib/Algebra/Homology/TotalComplex.lean @@ -69,11 +69,13 @@ noncomputable def d₂ : ComplexShape.ε₂ c₁ c₂ c₁₂ ⟨i₁, i₂⟩ • ((K.X i₁).d i₂ (c₂.next i₂) ≫ K.toGradedObject.ιMapObjOrZero (ComplexShape.π c₁ c₂ c₁₂) ⟨i₁, _⟩ i₁₂) +set_option backward.isDefEq.respectTransparency.types false in lemma d₁_eq_zero (h : ¬ c₁.Rel i₁ (c₁.next i₁)) : K.d₁ c₁₂ i₁ i₂ i₁₂ = 0 := by dsimp [d₁] rw [K.shape_f _ _ h, zero_comp, smul_zero] +set_option backward.isDefEq.respectTransparency.types false in lemma d₂_eq_zero (h : ¬ c₂.Rel i₂ (c₂.next i₂)) : K.d₂ c₁₂ i₁ i₂ i₁₂ = 0 := by dsimp [d₂] @@ -144,12 +146,14 @@ noncomputable def D₂ (i₁₂ i₁₂' : I₁₂) : namespace totalAux +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ιMapObj_D₁ (i₁₂ i₁₂' : I₁₂) (i : I₁ × I₂) (h : ComplexShape.π c₁ c₂ c₁₂ i = i₁₂) : K.toGradedObject.ιMapObj (ComplexShape.π c₁ c₂ c₁₂) i i₁₂ h ≫ K.D₁ c₁₂ i₁₂ i₁₂' = K.d₁ c₁₂ i.1 i.2 i₁₂' := by simp [D₁] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ιMapObj_D₂ (i₁₂ i₁₂' : I₁₂) (i : I₁ × I₂) (h : ComplexShape.π c₁ c₂ c₁₂ i = i₁₂) : K.toGradedObject.ιMapObj (ComplexShape.π c₁ c₂ c₁₂) i i₁₂ h ≫ K.D₂ c₁₂ i₁₂ i₁₂' = @@ -257,7 +261,7 @@ lemma D₁_D₂ (i₁₂ i₁₂' i₁₂'' : I₁₂) : K.D₁ c₁₂ i₁₂ i₁₂' ≫ K.D₂ c₁₂ i₁₂' i₁₂'' = - K.D₂ c₁₂ i₁₂ i₁₂' ≫ K.D₁ c₁₂ i₁₂' i₁₂'' := by simp /-- The total complex of a bicomplex. -/ -@[simps -isSimp d] +@[simps -isSimp d, implicit_reducible] noncomputable def total : HomologicalComplex C c₁₂ where X := K.toGradedObject.mapObj (ComplexShape.π c₁ c₂ c₁₂) d i₁₂ i₁₂' := K.D₁ c₁₂ i₁₂ i₁₂' + K.D₂ c₁₂ i₁₂ i₁₂' diff --git a/Mathlib/Algebra/Homology/TotalComplexShift.lean b/Mathlib/Algebra/Homology/TotalComplexShift.lean index 0e333f78bf8896..32b54bb2d2351d 100644 --- a/Mathlib/Algebra/Homology/TotalComplexShift.lean +++ b/Mathlib/Algebra/Homology/TotalComplexShift.lean @@ -207,6 +207,7 @@ lemma ι_totalShift₁Iso_hom_f (a b n : ℤ) (h : a + b = n) (a' : ℤ) (ha' : dsimp [totalShift₁Iso, totalShift₁XIso] simp only [ι_totalDesc, comp_id, id_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma ι_totalShift₁Iso_inv_f (a b n : ℤ) (h : a + b = n) (a' n' : ℤ) @@ -331,6 +332,7 @@ lemma ι_totalShift₂Iso_hom_f (a b n : ℤ) (h : a + b = n) (b' : ℤ) (hb' : dsimp [totalShift₂Iso, totalShift₂XIso] simp only [ι_totalDesc, comp_id, id_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma ι_totalShift₂Iso_inv_f (a b n : ℤ) (h : a + b = n) (b' n' : ℤ) diff --git a/Mathlib/Algebra/Homology/TotalComplexSymmetry.lean b/Mathlib/Algebra/Homology/TotalComplexSymmetry.lean index 39bac3981fd64a..8719f198caecaf 100644 --- a/Mathlib/Algebra/Homology/TotalComplexSymmetry.lean +++ b/Mathlib/Algebra/Homology/TotalComplexSymmetry.lean @@ -117,18 +117,25 @@ noncomputable def totalFlipIso : K.flip.total c ≅ K.total c := totalFlipIsoX_hom_D₂, Preadditive.add_comp] rw [add_comm]) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma totalFlipIso_hom_f_D₁ (j j' : J) : (K.totalFlipIso c).hom.f j ≫ K.D₁ c j j' = K.flip.D₂ c j j' ≫ (K.totalFlipIso c).hom.f j' := by apply totalFlipIsoX_hom_D₁ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma totalFlipIso_hom_f_D₂ (j j' : J) : (K.totalFlipIso c).hom.f j ≫ K.D₂ c j j' = K.flip.D₁ c j j' ≫ (K.totalFlipIso c).hom.f j' := by apply totalFlipIsoX_hom_D₂ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ιTotal_totalFlipIso_f_hom (i₁ : I₁) (i₂ : I₂) (j : J) (h : ComplexShape.π c₂ c₁ c (i₂, i₁) = j) : @@ -137,6 +144,7 @@ lemma ιTotal_totalFlipIso_f_hom (by rw [← ComplexShape.π_symm c₁ c₂ c i₁ i₂, h]) := by simp [totalFlipIso, totalFlipIsoX] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ιTotal_totalFlipIso_f_inv (i₁ : I₁) (i₂ : I₂) (j : J) (h : ComplexShape.π c₁ c₂ c (i₁, i₂) = j) : @@ -151,6 +159,7 @@ section variable [TotalComplexShapeSymmetry c₂ c₁ c] [TotalComplexShapeSymmetrySymmetry c₁ c₂ c] +set_option backward.isDefEq.respectTransparency.types false in lemma flip_totalFlipIso : K.flip.totalFlipIso c = (K.totalFlipIso c).symm := by ext j i₁ i₂ h rw [Iso.symm_hom, ιTotal_totalFlipIso_f_hom] diff --git a/Mathlib/Algebra/Jordan/Basic.lean b/Mathlib/Algebra/Jordan/Basic.lean index 55dfe8ff8daaae..a1c85f37210874 100644 --- a/Mathlib/Algebra/Jordan/Basic.lean +++ b/Mathlib/Algebra/Jordan/Basic.lean @@ -161,6 +161,7 @@ The endomorphisms on an additive monoid `AddMonoid.End` form a `Ring`, and this with a Lie Bracket via `Ring.bracket`. -/ +set_option backward.isDefEq.respectTransparency false in theorem two_nsmul_lie_lmul_lmul_add_eq_lie_lmul_lmul_add [IsCommJordan A] (a b : A) : 2 • (⁅L a, L (a * b)⁆ + ⁅L b, L (b * a)⁆) = ⁅L (a * a), L b⁆ + ⁅L (b * b), L a⁆ := by suffices 2 • ⁅L a, L (a * b)⁆ + 2 • ⁅L b, L (b * a)⁆ + ⁅L b, L (a * a)⁆ + ⁅L a, L (b * b)⁆ = 0 by @@ -170,6 +171,7 @@ theorem two_nsmul_lie_lmul_lmul_add_eq_lie_lmul_lmul_add [IsCommJordan A] (a b : (commute_lmul_lmul_sq a).lie_eq, (commute_lmul_lmul_sq b).lie_eq, zero_add, add_zero, two_smul] abel +set_option backward.isDefEq.respectTransparency false in -- Porting note: the monolithic `calc`-based proof of `two_nsmul_lie_lmul_lmul_add_add_eq_zero` -- has had four auxiliary parts `aux{0,1,2,3}` split off from it. private theorem aux0 {a b c : A} : ⁅L (a + b + c), L ((a + b + c) * (a + b + c))⁆ = @@ -183,6 +185,7 @@ private theorem aux0 {a b c : A} : ⁅L (a + b + c), L ((a + b + c) * (a + b + c simp only [add_lie] abel_nf +set_option backward.isDefEq.respectTransparency false in private theorem aux1 {a b c : A} : ⁅L a + L b + L c, L (a * a) + L (b * b) + L (c * c) + 2 • L (a * b) + 2 • L (c * a) + 2 • L (b * c)⁆ @@ -198,6 +201,7 @@ private theorem aux1 {a b c : A} : variable [IsCommJordan A] +set_option backward.isDefEq.respectTransparency false in private theorem aux2 {a b c : A} : ⁅L a, L (a * a)⁆ + ⁅L a, L (b * b)⁆ + ⁅L a, L (c * c)⁆ + ⁅L a, 2 • L (a * b)⁆ + ⁅L a, 2 • L (c * a)⁆ + ⁅L a, 2 • L (b * c)⁆ + @@ -230,6 +234,7 @@ private theorem aux3 {a b c : A} : iterate 2 rw [← lie_skew (L (a * a)), ← lie_skew (L (b * b)), ← lie_skew (L (c * c))] abel +set_option backward.isDefEq.respectTransparency false in theorem two_nsmul_lie_lmul_lmul_add_add_eq_zero (a b c : A) : 2 • (⁅L a, L (b * c)⁆ + ⁅L b, L (c * a)⁆ + ⁅L c, L (a * b)⁆) = 0 := by symm diff --git a/Mathlib/Algebra/Lie/Abelian.lean b/Mathlib/Algebra/Lie/Abelian.lean index b6282a5809a925..43c6f90d13b74d 100644 --- a/Mathlib/Algebra/Lie/Abelian.lean +++ b/Mathlib/Algebra/Lie/Abelian.lean @@ -205,6 +205,7 @@ theorem isTrivial_iff_max_triv_eq_top : IsTrivial L M ↔ maxTrivSubmodule R L M variable {R L M N} +set_option backward.isDefEq.respectTransparency false in /-- `maxTrivSubmodule` is functorial. -/ def maxTrivHom (f : M →ₗ⁅R,L⁆ N) : maxTrivSubmodule R L M →ₗ⁅R,L⁆ maxTrivSubmodule R L N where toFun m := ⟨f m, fun x => diff --git a/Mathlib/Algebra/Lie/AdjointAction/Basic.lean b/Mathlib/Algebra/Lie/AdjointAction/Basic.lean index e98f73e26067ed..df3b907a30a845 100644 --- a/Mathlib/Algebra/Lie/AdjointAction/Basic.lean +++ b/Mathlib/Algebra/Lie/AdjointAction/Basic.lean @@ -30,6 +30,7 @@ attribute [local instance 100] LieRing.ofAssociativeRing variable {R A : Type*} [CommRing R] [Ring A] [Algebra R A] +set_option backward.isDefEq.respectTransparency false in /-- Commuting elements have commuting adjoint actions. -/ theorem LieAlgebra.commute_ad_of_commute {a b : A} (h : Commute a b) : Commute (LieAlgebra.ad R A a) (LieAlgebra.ad R A b) := by diff --git a/Mathlib/Algebra/Lie/BaseChange.lean b/Mathlib/Algebra/Lie/BaseChange.lean index 053db2056415ce..75dd94397a8eb6 100644 --- a/Mathlib/Algebra/Lie/BaseChange.lean +++ b/Mathlib/Algebra/Lie/BaseChange.lean @@ -120,6 +120,7 @@ instance instLieRingModule : LieRingModule (A ⊗[R] L) (A ⊗[R] M) where lie_add x y z := by simp only [bracket_def, map_add] leibniz_lie := bracket_leibniz_lie R A L M +set_option backward.isDefEq.respectTransparency false in instance instLieModule : LieModule A (A ⊗[R] L) (A ⊗[R] M) where smul_lie t x m := by simp only [bracket_def, map_smul, LinearMap.smul_apply] lie_smul _ _ _ := map_smul _ _ _ @@ -148,7 +149,6 @@ end ExtendScalars namespace RestrictScalars -open RestrictScalars variable [h : LieRing L] @@ -183,6 +183,7 @@ variable (N : LieSubmodule R L M) open LieModule +set_option backward.isDefEq.respectTransparency false in variable {R L M} in /-- If `A` is an `R`-algebra, any Lie submodule of a Lie module `M` with coefficients in `R` may be pushed forward to a Lie submodule of `A ⊗ M` with coefficients in `A`. diff --git a/Mathlib/Algebra/Lie/Basic.lean b/Mathlib/Algebra/Lie/Basic.lean index e90318b3481721..4faaf1c401eb03 100644 --- a/Mathlib/Algebra/Lie/Basic.lean +++ b/Mathlib/Algebra/Lie/Basic.lean @@ -245,6 +245,7 @@ instance : LieModule ℤ L M where smul_lie n x m := zsmul_lie x m n lie_smul n x m := lie_zsmul x m n +set_option backward.isDefEq.respectTransparency false in instance LinearMap.instLieRingModule : LieRingModule L (M →ₗ[R] N) where bracket x f := { toFun := fun m => ⁅x, f m⁆ - f ⁅x, m⁆ @@ -270,6 +271,7 @@ instance LinearMap.instLieRingModule : LieRingModule L (M →ₗ[R] N) where theorem LieHom.lie_apply (f : M →ₗ[R] N) (x : L) (m : M) : ⁅x, f⁆ m = ⁅x, f m⁆ - f ⁅x, m⁆ := rfl +set_option backward.isDefEq.respectTransparency false in instance LinearMap.instLieModule : LieModule R L (M →ₗ[R] N) where smul_lie t x f := by ext n @@ -298,7 +300,7 @@ instance Module.Dual.instLieModule : LieModule R L (M →ₗ[R] R) where variable (L) in /-- It is sometimes useful to regard a `LieRing` as a `NonUnitalNonAssocRing`. -/ -@[implicit_reducible] +@[instance_reducible] def LieRing.toNonUnitalNonAssocRing : NonUnitalNonAssocRing L := { mul := Bracket.bracket left_distrib := lie_add @@ -472,7 +474,7 @@ variable (f : L₁ →ₗ⁅R⁆ L₂) /-- A Lie ring module may be pulled back along a morphism of Lie algebras. See note [reducible non-instances]. -/ -@[implicit_reducible] +@[instance_reducible] def LieRingModule.compLieHom : LieRingModule L₁ M where bracket x m := ⁅f x, m⁆ lie_add x := lie_add (f x) @@ -484,6 +486,7 @@ theorem LieRingModule.compLieHom_apply (x : L₁) (m : M) : ⁅x, m⁆ = ⁅f x, m⁆ := rfl +set_option backward.isDefEq.respectTransparency false in /-- A Lie module may be pulled back along a morphism of Lie algebras. -/ theorem LieModule.compLieHom [Module R M] [LieModule R L₂ M] : @LieModule R L₁ M _ _ _ _ _ (LieRingModule.compLieHom M f) := diff --git a/Mathlib/Algebra/Lie/Basis.lean b/Mathlib/Algebra/Lie/Basis.lean index 2d0156503cd810..85a7b0df5153a2 100644 --- a/Mathlib/Algebra/Lie/Basis.lean +++ b/Mathlib/Algebra/Lie/Basis.lean @@ -277,6 +277,7 @@ def baseSupp (i : ι) : Dual R b.cartan := simp [f, this, Finsupp.single_apply] simp [this] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma symm_baseSupp : b.symm.baseSupp = -b.baseSupp := by let b₁ : Module.Basis ι R b.cartan := @@ -331,6 +332,7 @@ lemma linearIndependent_baseSupp [IsDomain R] [CharZero R] : variable [IsDomain R] [CharZero R] +set_option backward.isDefEq.respectTransparency.types false in /-- Lemma 4.4 from [Geck](Geck2017). -/ lemma borelUpper_le_biSup : b.borelUpper ≤ ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) := by @@ -390,6 +392,7 @@ private lemma cartan_borelLower_borelUpper_le : variable [IsTorsionFree R L] +set_option backward.isDefEq.respectTransparency.types false in lemma iSupIndep_rootSpace : letI U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • (-b.baseSupp) i) letI V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) diff --git a/Mathlib/Algebra/Lie/Classical.lean b/Mathlib/Algebra/Lie/Classical.lean index 22f75bdcb60b24..ca8afa7134c773 100644 --- a/Mathlib/Algebra/Lie/Classical.lean +++ b/Mathlib/Algebra/Lie/Classical.lean @@ -203,7 +203,7 @@ theorem pso_inv {i : R} (hi : i * i = -1) : Pso p q R i * Pso p q R (-i) = 1 := simp [Pso, h, hi, one_apply] /-- There is a constructive inverse of `Pso p q R i`. -/ -@[implicit_reducible] +@[instance_reducible] def invertiblePso {i : R} (hi : i * i = -1) : Invertible (Pso p q R i) := invertibleOfRightInverse _ _ (pso_inv p q R hi) diff --git a/Mathlib/Algebra/Lie/Derivation/Basic.lean b/Mathlib/Algebra/Lie/Derivation/Basic.lean index 912e31d7cb36cb..564378d8fb77ec 100644 --- a/Mathlib/Algebra/Lie/Derivation/Basic.lean +++ b/Mathlib/Algebra/Lie/Derivation/Basic.lean @@ -107,6 +107,7 @@ lemma apply_lie_eq_add (D : LieDerivation R L L) (a b : L) : D ⁅a, b⁆ = ⁅a, D b⁆ + ⁅D a, b⁆ := by rw [LieDerivation.apply_lie_eq_sub, sub_eq_add_neg, lie_skew] +set_option backward.isDefEq.respectTransparency false in /-- Two Lie derivations equal on a set are equal on its Lie span. -/ theorem eqOn_lieSpan {s : Set L} (h : Set.EqOn D1 D2 s) : Set.EqOn D1 D2 (LieSubalgebra.lieSpan R L s) := by @@ -317,6 +318,7 @@ instance : LieRing (LieDerivation R L L) where leibniz_lie d e f := by ext a; simp only [commutator_apply, add_apply, map_sub]; abel +set_option backward.isDefEq.respectTransparency false in /-- The set of Lie derivations from a Lie algebra `L` to itself is a Lie algebra. -/ instance instLieAlgebra : LieAlgebra R (LieDerivation R L L) where lie_smul := fun r d e => by ext a; simp only [commutator_apply, map_smul, smul_sub, smul_apply] @@ -333,6 +335,7 @@ variable (R L : Type*) [CommRing R] [LieRing L] [LieAlgebra R L] attribute [local instance 100] LieRing.ofAssociativeRing +set_option backward.isDefEq.respectTransparency false in /-- The Lie algebra morphism from Lie derivations into linear endomorphisms. -/ def toLinearMapLieHom : LieDerivation R L L →ₗ⁅R⁆ L →ₗ[R] L where toFun := toLinearMap @@ -344,6 +347,7 @@ def toLinearMapLieHom : LieDerivation R L L →ₗ⁅R⁆ L →ₗ[R] L where lemma toLinearMapLieHom_injective : Function.Injective (toLinearMapLieHom R L) := fun _ _ h ↦ ext fun a ↦ congrFun (congrArg DFunLike.coe h) a +set_option backward.isDefEq.respectTransparency false in /-- Lie derivations over a Noetherian Lie algebra form a Noetherian module. -/ instance instNoetherian [IsNoetherian R L] : IsNoetherian R (LieDerivation R L L) := isNoetherian_of_linearEquiv (LinearEquiv.ofInjective _ (toLinearMapLieHom_injective R L)).symm @@ -355,6 +359,7 @@ section Inner variable (R L M : Type*) [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M] [LieRingModule L M] [LieModule R L M] +set_option backward.isDefEq.respectTransparency false in /-- The natural map from a Lie module to the derivations taking values in it. -/ @[simps!] def inner : M →ₗ[R] LieDerivation R L M where @@ -378,6 +383,7 @@ instance instLieRingModule : LieRingModule L (LieDerivation R L M) where ⁅x, (D : L →ₗ[R] M)⁆ = ⁅x, D⁆ := by ext; simp +set_option backward.isDefEq.respectTransparency false in instance instLieModule : LieModule R L (LieDerivation R L M) where smul_lie t x D := by ext; simp lie_smul t x D := by ext; simp diff --git a/Mathlib/Algebra/Lie/DirectSum.lean b/Mathlib/Algebra/Lie/DirectSum.lean index 890b08ca949466..853510ae4ce247 100644 --- a/Mathlib/Algebra/Lie/DirectSum.lean +++ b/Mathlib/Algebra/Lie/DirectSum.lean @@ -70,6 +70,7 @@ instance : LieModule R L (⨁ i, M i) where variable (R ι L M) +set_option backward.isDefEq.respectTransparency false in /-- The inclusion of each component into a direct sum as a morphism of Lie modules. -/ def lieModuleOf [DecidableEq ι] (j : ι) : M j →ₗ⁅R,L⁆ ⨁ i, M i := { lof R ι M j with @@ -101,6 +102,7 @@ section Algebras variable (L : ι → Type w) variable [∀ i, LieRing (L i)] [∀ i, LieAlgebra R (L i)] +set_option backward.isDefEq.respectTransparency false in instance lieRing : LieRing (⨁ i, L i) := { (inferInstance : AddCommGroup _) with bracket := zipWith (fun _ => fun x y => ⁅x, y⁆) fun _ => lie_zero 0 diff --git a/Mathlib/Algebra/Lie/EngelSubalgebra.lean b/Mathlib/Algebra/Lie/EngelSubalgebra.lean index 77c52aedbc4bfe..44a2f30a061f39 100644 --- a/Mathlib/Algebra/Lie/EngelSubalgebra.lean +++ b/Mathlib/Algebra/Lie/EngelSubalgebra.lean @@ -143,6 +143,7 @@ lemma normalizer_eq_self_of_engel_le [IsArtinian R L] apply aux₁ simp only [Submodule.coe_subtype, SetLike.coe_mem] +set_option backward.isDefEq.respectTransparency.types false in /-- A Lie subalgebra of a Noetherian Lie algebra is nilpotent if it is contained in the Engel subalgebra of all its elements. -/ lemma isNilpotent_of_forall_le_engel [IsNoetherian R L] diff --git a/Mathlib/Algebra/Lie/Extension.lean b/Mathlib/Algebra/Lie/Extension.lean index a8476d586df5d1..80fbb9a4f0df9e 100644 --- a/Mathlib/Algebra/Lie/Extension.lean +++ b/Mathlib/Algebra/Lie/Extension.lean @@ -299,6 +299,7 @@ lemma lie_incl_mem_ker {E : Extension R M L} (x : E.L) (y : M) : ⁅x, E.incl y⁆ ∈ E.proj.ker := by rw [LieHom.mem_ker, LieHom.map_lie, proj_incl, lie_zero] +set_option backward.isDefEq.respectTransparency.types false in /-- The Lie algebra isomorphism from the kernel of an extension to the kernel of the projection. -/ noncomputable def toKer (E : Extension R M L) : M ≃ₗ⁅R⁆ E.proj.ker where @@ -312,6 +313,7 @@ noncomputable def toKer (E : Extension R M L) : rfl right_inv x := by simpa [Subtype.ext_iff] using! Equiv.apply_ofInjective_symm E.incl_injective _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lie_toKer_apply (E : Extension R M L) (x : M) (y : E.L) : ⁅y, (E.toKer x : E.L)⁆ = ⁅y, E.incl x⁆ := by rfl @@ -322,7 +324,7 @@ instance [IsLieAbelian M] (E : Extension R M L) : IsLieAbelian E.proj.ker := /-- Given an extension of `L` by `M` whose kernel `M` is abelian, the kernel `M` gets an `L`-module structure. We do not make this an instance, because we may have to work with more than one extension. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] noncomputable def ringModuleOf [IsLieAbelian M] (E : Extension R M L) : LieRingModule L M where bracket x y := E.toKer.symm ⁅E.proj_surjective.hasRightInverse.choose x, E.toKer y⁆ add_lie x y m := by diff --git a/Mathlib/Algebra/Lie/Graded.lean b/Mathlib/Algebra/Lie/Graded.lean index 14ef244ac42f03..5c772994581ff5 100644 --- a/Mathlib/Algebra/Lie/Graded.lean +++ b/Mathlib/Algebra/Lie/Graded.lean @@ -83,6 +83,7 @@ lemma decompose_symm_bracket (x y : ⨁ i, ℒ i) : simp only [← decomposeLinearEquiv_symm_apply] simp +set_option backward.isDefEq.respectTransparency false in instance : LieAlgebra R (⨁ i, ℒ i) where add_smul _ _ _ := by simp [add_smul] zero_smul _ := by simp @@ -141,6 +142,7 @@ lemma ofGradingSum_of (φ : ι →+ R) (i : ι) (a : ℒ i) : ofGradingSum ℒ φ (of (ℒ ·) i a) = (φ i) • (of (ℒ ·) i a) := by simp [← lof_eq_of R, ofGradingSum] +set_option backward.isDefEq.respectTransparency false in /-- The Lie derivation on a graded Lie algebra that scalar-multiplies by an additive function of the degree. -/ def ofGrading (φ : ι →+ R) : @@ -150,6 +152,7 @@ def ofGrading (φ : ι →+ R) : map_smul' _ _ := by simp leibniz' x y := by simp [decomposeLinearEquiv_apply, decomposeLinearEquiv_symm_apply] +set_option backward.isDefEq.respectTransparency false in lemma ofGrading_apply_apply (φ : ι →+ R) {i : ι} {a : L} (ha : a ∈ ℒ i) : ofGrading ℒ φ a = φ i • a := by simp [ofGrading, decomposeLinearEquiv_apply, decompose_of_mem ℒ ha] diff --git a/Mathlib/Algebra/Lie/LieTheorem.lean b/Mathlib/Algebra/Lie/LieTheorem.lean index 99cfd0cfdef20b..24c3d02bf21ebf 100644 --- a/Mathlib/Algebra/Lie/LieTheorem.lean +++ b/Mathlib/Algebra/Lie/LieTheorem.lean @@ -49,6 +49,7 @@ local notation "π" => LieModule.toEnd R _ V private abbrev T (w : A) : Module.End R V := (π w) - χ w • 1 +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- An auxiliary lemma used only in the definition `LieModule.weightSpaceOfIsLieTower` below. -/ private lemma weightSpaceOfIsLieTower_aux (z : L) (v : V) (hv : v ∈ weightSpace V χ) : diff --git a/Mathlib/Algebra/Lie/Matrix.lean b/Mathlib/Algebra/Lie/Matrix.lean index 600cc77f1444d4..34d0abfefd99ec 100644 --- a/Mathlib/Algebra/Lie/Matrix.lean +++ b/Mathlib/Algebra/Lie/Matrix.lean @@ -81,6 +81,7 @@ theorem lieConj_symm_apply (P A : Matrix n n R) (h : Invertible P) : variable {m : Type w₁} [DecidableEq m] [Fintype m] (e : n ≃ m) +set_option backward.isDefEq.respectTransparency false in /-- For square matrices, the natural map that reindexes a matrix's rows and columns with equivalent types, `Matrix.reindex`, is an equivalence of Lie algebras. -/ def reindexLieEquiv : Matrix n n R ≃ₗ⁅R⁆ Matrix m m R := diff --git a/Mathlib/Algebra/Lie/OfAssociative.lean b/Mathlib/Algebra/Lie/OfAssociative.lean index f8019d976aaa2e..76b0ed404f56f4 100644 --- a/Mathlib/Algebra/Lie/OfAssociative.lean +++ b/Mathlib/Algebra/Lie/OfAssociative.lean @@ -46,7 +46,7 @@ variable {A : Type v} [Ring A] namespace LieRing /-- An associative ring gives rise to a Lie ring by taking the bracket to be the ring commutator. -/ -@[implicit_reducible] +@[instance_reducible] def ofAssociativeRing : LieRing A where add_lie _ _ _ := by simp only [Ring.lie_def, right_distrib, left_distrib]; abel lie_add _ _ _ := by simp only [Ring.lie_def, right_distrib, left_distrib]; abel @@ -69,6 +69,7 @@ section AssociativeModule variable {M : Type w} [AddCommGroup M] [Module A M] +set_option backward.isDefEq.respectTransparency false in /-- We can regard a module over an associative ring `A` as a Lie ring module over `A` with Lie bracket equal to its ring commutator. @@ -96,6 +97,7 @@ section LieAlgebra variable {R : Type u} [CommRing R] [Algebra R A] +set_option backward.isDefEq.respectTransparency false in /-- An associative algebra gives rise to a Lie algebra by taking the bracket to be the ring commutator. -/ instance (priority := 100) LieAlgebra.ofAssociativeAlgebra : LieAlgebra R A where @@ -141,6 +143,7 @@ namespace AlgHom variable {B : Type w} {C : Type w₁} [Ring B] [Ring C] [Algebra R B] [Algebra R C] variable (f : A →ₐ[R] B) (g : B →ₐ[R] C) +set_option backward.isDefEq.respectTransparency false in /-- The map `ofAssociativeAlgebra` associating a Lie algebra to an associative algebra is functorial. -/ def toLieHom : A →ₗ⁅R⁆ B := @@ -237,6 +240,7 @@ lemma ext_of_isFaithful [IsFaithful R L M] {x y : L} (h : ∀ m : M, ⁅x, m⁆ x = y := (toEnd_eq_iff R L M).mp <| LinearMap.ext h +set_option backward.isDefEq.respectTransparency false in @[simp] lemma toEnd_eq_zero_iff [IsFaithful R L M] {x : L} : toEnd R L M x = 0 ↔ x = 0 := by @@ -370,6 +374,7 @@ end LieSubmodule open LieAlgebra +set_option backward.isDefEq.respectTransparency false in theorem LieAlgebra.ad_eq_lmul_left_sub_lmul_right (A : Type v) [Ring A] [Algebra R A] : (ad R A : A → Module.End R A) = LinearMap.mulLeft R - LinearMap.mulRight R := by ext a b; simp [LieRing.of_associative_ring_bracket] @@ -382,6 +387,7 @@ theorem LieSubalgebra.ad_comp_incl_eq (K : LieSubalgebra R L) (x : K) : end AdjointAction +set_option backward.isDefEq.respectTransparency false in /-- A subalgebra of an associative algebra is a Lie subalgebra of the associated Lie algebra. -/ def lieSubalgebraOfSubalgebra (R : Type u) [CommRing R] (A : Type v) [Ring A] [Algebra R A] (A' : Subalgebra R A) : LieSubalgebra R A := @@ -423,6 +429,7 @@ variable {R : Type u} {A₁ : Type v} {A₂ : Type w} variable [CommRing R] [Ring A₁] [Ring A₂] [Algebra R A₁] [Algebra R A₂] variable (e : A₁ ≃ₐ[R] A₂) +set_option backward.isDefEq.respectTransparency false in /-- An equivalence of associative algebras is an equivalence of associated Lie algebras. -/ def toLieEquiv : A₁ ≃ₗ⁅R⁆ A₂ := { e.toLinearEquiv with diff --git a/Mathlib/Algebra/Lie/Quotient.lean b/Mathlib/Algebra/Lie/Quotient.lean index 9743601e0cebb9..426abefa3c5f57 100644 --- a/Mathlib/Algebra/Lie/Quotient.lean +++ b/Mathlib/Algebra/Lie/Quotient.lean @@ -82,6 +82,7 @@ theorem is_quotient_mk (m : M) : Quotient.mk'' m = (mk m : M ⧸ N) := variable [LieAlgebra R L] [LieModule R L M] (I J : LieIdeal R L) +set_option backward.isDefEq.respectTransparency false in /-- Given a Lie module `M` over a Lie algebra `L`, together with a Lie submodule `N ⊆ M`, there is a natural linear map from `L` to the endomorphisms of `M` leaving `N` invariant. -/ def lieSubmoduleInvariant : L →ₗ[R] Submodule.compatibleMaps N.toSubmodule N.toSubmodule := diff --git a/Mathlib/Algebra/Lie/SemiDirect.lean b/Mathlib/Algebra/Lie/SemiDirect.lean index 1aadbffaf653cd..0532ebe7a19e85 100644 --- a/Mathlib/Algebra/Lie/SemiDirect.lean +++ b/Mathlib/Algebra/Lie/SemiDirect.lean @@ -96,6 +96,7 @@ instance : LieRing (K ⋊⁅ψ⁆ L) where lie_self _ := by simp leibniz_lie _ _ _ := by simp; grind [lie_skew] +set_option backward.isDefEq.respectTransparency false in instance : LieAlgebra R (K ⋊⁅ψ⁆ L) where lie_smul _ _ _ := by simp [smul_sub, smul_add] diff --git a/Mathlib/Algebra/Lie/Solvable.lean b/Mathlib/Algebra/Lie/Solvable.lean index c6923c1c2982f7..bb82448d13643e 100644 --- a/Mathlib/Algebra/Lie/Solvable.lean +++ b/Mathlib/Algebra/Lie/Solvable.lean @@ -114,6 +114,7 @@ theorem derivedSeriesOfIdeal_mono {I J : LieIdeal R L} (h : I ≤ J) (k : ℕ) : theorem derivedSeriesOfIdeal_antitone {k l : ℕ} (h : l ≤ k) : D k I ≤ D l I := derivedSeriesOfIdeal_le le_rfl h +set_option backward.isDefEq.respectTransparency.types false in theorem derivedSeriesOfIdeal_add_le_add (J : LieIdeal R L) (k l : ℕ) : D (k + l) (I + J) ≤ D k I + D l J := by let D₁ : LieIdeal R L →o LieIdeal R L := diff --git a/Mathlib/Algebra/Lie/Submodule.lean b/Mathlib/Algebra/Lie/Submodule.lean index d90f34341667ac..8c2f4846992481 100644 --- a/Mathlib/Algebra/Lie/Submodule.lean +++ b/Mathlib/Algebra/Lie/Submodule.lean @@ -970,6 +970,7 @@ lemma map_le_range {M' : Type*} rw [← LieModuleHom.map_top] exact LieSubmodule.map_mono le_top +set_option backward.isDefEq.respectTransparency false in @[simp] lemma map_incl_lt_iff_lt_top {N' : LieSubmodule R L N} : N'.map (LieSubmodule.incl N) < N ↔ N' < ⊤ := by diff --git a/Mathlib/Algebra/Lie/TensorProduct.lean b/Mathlib/Algebra/Lie/TensorProduct.lean index 80726c4340b0e4..3db80295299c09 100644 --- a/Mathlib/Algebra/Lie/TensorProduct.lean +++ b/Mathlib/Algebra/Lie/TensorProduct.lean @@ -66,6 +66,7 @@ instance lieRingModule : LieRingModule L (M ⊗[R] N) where map_add, LieHom.lie_apply, Module.End.lie_apply, LinearMap.lTensor_tmul] abel +set_option backward.isDefEq.respectTransparency false in /-- The tensor product of two Lie modules is a Lie module. -/ instance lieModule : LieModule R L (M ⊗[R] N) where smul_lie c x t := by diff --git a/Mathlib/Algebra/Lie/UniversalEnveloping.lean b/Mathlib/Algebra/Lie/UniversalEnveloping.lean index 8ebf54ba4ef5fa..98c49ce3e83b9f 100644 --- a/Mathlib/Algebra/Lie/UniversalEnveloping.lean +++ b/Mathlib/Algebra/Lie/UniversalEnveloping.lean @@ -75,6 +75,7 @@ def mkAlgHom : TensorAlgebra R L →ₐ[R] UniversalEnvelopingAlgebra R L := variable {L} attribute [local instance 100] LieRing.ofAssociativeRing +set_option backward.isDefEq.respectTransparency false in /-- The natural Lie algebra morphism from a Lie algebra to its universal enveloping algebra. -/ @[simps!] def ι : L →ₗ⁅R⁆ UniversalEnvelopingAlgebra R L := diff --git a/Mathlib/Algebra/Lie/Weights/Basic.lean b/Mathlib/Algebra/Lie/Weights/Basic.lean index 79af6197d3d0f5..e3c007ab485e30 100644 --- a/Mathlib/Algebra/Lie/Weights/Basic.lean +++ b/Mathlib/Algebra/Lie/Weights/Basic.lean @@ -266,6 +266,7 @@ lemma isNonZero_iff_ne_zero [Nontrivial (genWeightSpace M (0 : L → R))] {χ : noncomputable instance : DecidablePred (IsNonZero (R := R) (L := L) (M := M)) := Classical.decPred _ +set_option backward.isDefEq.respectTransparency.types false in variable (R L M) in /-- The set of weights is equivalent to a subtype. -/ def equivSetOf : Weight R L M ≃ {χ : L → R | genWeightSpace M χ ≠ ⊥} where diff --git a/Mathlib/Algebra/Lie/Weights/Chain.lean b/Mathlib/Algebra/Lie/Weights/Chain.lean index 3a53471a551f9b..5d97ddf5978a82 100644 --- a/Mathlib/Algebra/Lie/Weights/Chain.lean +++ b/Mathlib/Algebra/Lie/Weights/Chain.lean @@ -203,6 +203,7 @@ lemma trace_toEnd_genWeightSpaceChain_eq_zero | add => simp_all | smul => simp_all +set_option backward.isDefEq.respectTransparency.types false in /-- Given a (potential) root `α` relative to a Cartan subalgebra `H`, if we restrict to the ideal `I = corootSpace α` of `H` (informally, `I = ⁅H(α), H(-α)⁆`), we may find an integral linear combination between `α` and any weight `χ` of a representation. diff --git a/Mathlib/Algebra/Lie/Weights/IsSimple.lean b/Mathlib/Algebra/Lie/Weights/IsSimple.lean index fedb3e7ceb88fa..6fb2317ca1e60d 100644 --- a/Mathlib/Algebra/Lie/Weights/IsSimple.lean +++ b/Mathlib/Algebra/Lie/Weights/IsSimple.lean @@ -139,6 +139,7 @@ lemma rootSet_apply_coroot_eq_zero_of_notMem_rootSet (I : LieIdeal K L) LinearMap.BilinForm.orthogonal_span_singleton_eq_toLin_ker, LinearMap.mem_ker] exact traceForm_eq_zero_of_mem_ker_of_mem_span_coroot h_ker (Submodule.mem_span_singleton_self _) +set_option backward.isDefEq.respectTransparency.types false in /-- The intersection of a Lie ideal and a Cartan subalgebra is the span of the coroots whose roots have root spaces in the ideal. -/ lemma restr_inf_cartan_eq_biSup_corootSubmodule (I : LieIdeal K L) : @@ -375,6 +376,7 @@ private theorem chi_not_in_q_aux (h_chi_not_in_q : ↑χ ∉ q) : end +set_option backward.isDefEq.respectTransparency.types false in include hq hx_χ hαq in private theorem invtSubmoduleToLieIdeal_aux (hm_α : m_α ∈ sl2SubmoduleOfRoot hα₀) : ⁅x_χ, m_α⁆ ∈ ⨆ α : {α : Weight K H L // ↑α ∈ q ∧ α.IsNonZero}, sl2SubmoduleOfRoot α.2.2 := by diff --git a/Mathlib/Algebra/Lie/Weights/Killing.lean b/Mathlib/Algebra/Lie/Weights/Killing.lean index 0fcc327d084cda..663e391a432b2d 100644 --- a/Mathlib/Algebra/Lie/Weights/Killing.lean +++ b/Mathlib/Algebra/Lie/Weights/Killing.lean @@ -693,6 +693,7 @@ lemma coe_coroot_mem_corootSubmodule (α : Weight K H L) : (LieSubmodule.mem_map _).mpr ⟨⟨coroot α, (coroot α).property⟩, coroot_mem_corootSpace α, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in open Submodule in lemma sl2SubmoduleOfRoot_eq_sup (α : Weight K H L) (hα : α.IsNonZero) : sl2SubmoduleOfRoot hα = genWeightSpace L α ⊔ genWeightSpace L (-α) ⊔ corootSubmodule α := by diff --git a/Mathlib/Algebra/Module/CharacterModule.lean b/Mathlib/Algebra/Module/CharacterModule.lean index 9579e31907b86a..74223e75f94778 100644 --- a/Mathlib/Algebra/Module/CharacterModule.lean +++ b/Mathlib/Algebra/Module/CharacterModule.lean @@ -47,6 +47,7 @@ def CharacterModule : Type uA := A →+ AddCircle (1 : ℚ) namespace CharacterModule +set_option backward.isDefEq.respectTransparency.types false in instance : FunLike (CharacterModule A) A (AddCircle (1 : ℚ)) where coe c := c.toFun coe_injective _ _ _ := by simp_all @@ -113,6 +114,7 @@ def congr (e : A ≃ₗ[R] B) : CharacterModule A ≃ₗ[R] CharacterModule B := open TensorProduct +set_option backward.isDefEq.respectTransparency.types false in /-- Any linear map `L : A → B⋆` induces a character in `(A ⊗ B)⋆` by `a ⊗ b ↦ L a b`. -/ @@ -136,6 +138,7 @@ Any character `c` in `(A ⊗ B)⋆` induces a linear map `A → B⋆` by `a ↦ map_add' _ _ := rfl map_smul' r c := by ext; exact congr(c $(TensorProduct.tmul_smul _ _ _)).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Linear maps into a character module are exactly characters of the tensor product. -/ @@ -166,6 +169,9 @@ protected lemma int.divByNat_self (n : ℕ) : variable {A} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The `ℤ`-submodule spanned by a single element `a` is isomorphic to the quotient of `ℤ` by the ideal generated by the order of `a`. -/ @[simps!] noncomputable def intSpanEquivQuotAddOrderOf (a : A) : diff --git a/Mathlib/Algebra/Module/Equiv/Basic.lean b/Mathlib/Algebra/Module/Equiv/Basic.lean index d54d846e37e0eb..566923c75a50ea 100644 --- a/Mathlib/Algebra/Module/Equiv/Basic.lean +++ b/Mathlib/Algebra/Module/Equiv/Basic.lean @@ -563,6 +563,7 @@ See also `LinearEquiv.arrowCongr` for the linear version of this isomorphism. -/ ext x simp only [map_add, add_apply, Function.comp_apply, coe_comp, coe_coe] +set_option backward.isDefEq.respectTransparency false in /-- If `M` and `M₂` are linearly isomorphic then the endomorphism rings of `M` and `M₂` are isomorphic. @@ -665,6 +666,7 @@ variable [RingHomCompTriple σ₂'₂'' σ₂''₁'' σ₂'₁''] [RingHomCompTr variable [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] [RingHomCompTriple σ₃₂ σ₂₁ σ₃₁] variable [RingHomCompTriple σ₁'₂' σ₂'₃' σ₁'₃'] [RingHomCompTriple σ₃'₂' σ₂'₁' σ₃'₁'] +set_option backward.isDefEq.respectTransparency false in /-- A linear isomorphism between the domains and codomains of two spaces of linear maps gives a linear isomorphism between the two function spaces. diff --git a/Mathlib/Algebra/Module/Equiv/Defs.lean b/Mathlib/Algebra/Module/Equiv/Defs.lean index 5d4616cf15966c..14a412f258926e 100644 --- a/Mathlib/Algebra/Module/Equiv/Defs.lean +++ b/Mathlib/Algebra/Module/Equiv/Defs.lean @@ -140,6 +140,7 @@ instance : Coe (M ≃ₛₗ[σ] M₂) (M →ₛₗ[σ] M₂) := -- This exists for compatibility, previously `≃ₗ[R]` extended `≃` instead of `≃+`. /-- The equivalence of types underlying a linear equivalence. -/ +@[implicit_reducible] def toEquiv (e : M ≃ₛₗ[σ] M₂) : M ≃ M₂ := e.toAddEquiv.toEquiv theorem toEquiv_injective : @@ -243,7 +244,7 @@ theorem refl_apply [Module R M] (x : M) : refl R M x = x := rfl /-- Linear equivalences are symmetric. -/ -@[symm] +@[symm, implicit_reducible] def symm (e : M ≃ₛₗ[σ] M₂) : M₂ ≃ₛₗ[σ'] M := { e.toLinearMap.inverse e.invFun e.left_inv e.right_inv, e.toEquiv.symm with @@ -541,8 +542,7 @@ theorem coe_symm_mk [Module R M] [Module R M₂] @[simp] theorem coe_symm_mk' [Module R M] [Module R M₂] {f inv_fun left_inv right_inv} : - ⇑(⟨f, inv_fun, left_inv, right_inv⟩ : M ≃ₗ[R] M₂).symm = inv_fun := - rfl + ⇑(⟨f, inv_fun, left_inv, right_inv⟩ : M ≃ₗ[R] M₂).symm = inv_fun := rfl protected theorem bijective : Function.Bijective e := e.toEquiv.bijective @@ -584,6 +584,7 @@ def _root_.RingEquiv.toSemilinearEquiv (f : R ≃+* S) : toFun := f map_smul' := f.map_mul } +set_option backward.isDefEq.respectTransparency false in @[simp] lemma _root_.RingEquiv.symm_toSemilinearEquiv_symm_apply (f : R ≃+* S) (x : R) : f.symm.toSemilinearEquiv.symm (σ' := RingHomClass.toRingHom f) x = f x := rfl diff --git a/Mathlib/Algebra/Module/GradedModule.lean b/Mathlib/Algebra/Module/GradedModule.lean index d224109039f88e..f2e0bd81ff0d05 100644 --- a/Mathlib/Algebra/Module/GradedModule.lean +++ b/Mathlib/Algebra/Module/GradedModule.lean @@ -198,7 +198,7 @@ variable [AddCommMonoid M] [Module A M] [SetLike σ M] [AddSubmonoidClass σ' A] /-- The smul multiplication of `A` on `⨁ i, 𝓜 i` from `(⨁ i, 𝓐 i) →+ (⨁ i, 𝓜 i) →+ ⨁ i, 𝓜 i` turns `⨁ i, 𝓜 i` into an `A`-module -/ -@[implicit_reducible] +@[instance_reducible] def isModule : Module A (⨁ i, 𝓜 i) := { Module.compHom _ (DirectSum.decomposeRingEquiv 𝓐 : A ≃+* ⨁ i, 𝓐 i).toRingHom with smul := fun a b => DirectSum.decompose 𝓐 a • b } diff --git a/Mathlib/Algebra/Module/Injective.lean b/Mathlib/Algebra/Module/Injective.lean index ca85a85e159ea9..79a3d21da9da63 100644 --- a/Mathlib/Algebra/Module/Injective.lean +++ b/Mathlib/Algebra/Module/Injective.lean @@ -473,6 +473,7 @@ instance Module.Injective.pi ext i exact DFunLike.congr_fun (hl i) x⟩ +set_option backward.isDefEq.respectTransparency false in universe u' in attribute [local instance] RingHomInvPair.of_ringEquiv in theorem Module.Injective.of_ringEquiv {R : Type u} [Ring R] [Small.{v} R] {S : Type u'} [Ring S] diff --git a/Mathlib/Algebra/Module/Lattice.lean b/Mathlib/Algebra/Module/Lattice.lean index c97a642252df6f..bac5f85eaa181e 100644 --- a/Mathlib/Algebra/Module/Lattice.lean +++ b/Mathlib/Algebra/Module/Lattice.lean @@ -148,6 +148,7 @@ noncomputable def _root_.Module.Basis.extendOfIsLattice [IsFractionRing R K] {κ simp [b.span_eq, Submodule.map_top, span_eq_top] Basis.mk hli hsp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma _root_.Module.Basis.extendOfIsLattice_apply [IsFractionRing R K] {κ : Type*} {M : Submodule R V} [IsLattice K M] (b : Basis κ R M) (k : κ) : diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index bd62e3bf809d36..a56f661b2103e5 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -264,7 +264,7 @@ theorem toLinearMap_injective {F : Type*} [FunLike F M M₃] [SemilinearMapClass exact DFunLike.congr_fun h m /-- Identity map as a `LinearMap` -/ -@[implicit_reducible] +@[instance_reducible] def id : M →ₗ[R] M := { DistribMulActionHom.id R with toFun x := x } @@ -482,7 +482,7 @@ variable {module_M₁ : Module R₁ M₁} {module_M₂ : Module R₂ M₂} {modu variable {σ₁₂ : R₁ →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R₁ →+* R₃} /-- Composition of two linear maps is a linear map -/ -@[implicit_reducible] +@[instance_reducible] def comp [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] (f : M₂ →ₛₗ[σ₂₃] M₃) (g : M₁ →ₛₗ[σ₁₂] M₂) : M₁ →ₛₗ[σ₁₃] M₃ where toFun x := f (g x) @@ -558,6 +558,7 @@ variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] variable [Module R M] [Module S M₂] {σ : R →+* S} {σ' : S →+* R} [RingHomInvPair σ σ'] /-- If a function `g` is a left and right inverse of a linear map `f`, then `g` is linear itself. -/ +@[implicit_reducible] def inverse (f : M →ₛₗ[σ] M₂) (g : M₂ → M) (h₁ : LeftInverse g f) (h₂ : RightInverse g f) : M₂ →ₛₗ[σ'] M := by dsimp [LeftInverse, Function.RightInverse] at h₁ h₂ diff --git a/Mathlib/Algebra/Module/LinearMap/Index.lean b/Mathlib/Algebra/Module/LinearMap/Index.lean index 1dc717c908778c..8da65af7fb176d 100644 --- a/Mathlib/Algebra/Module/LinearMap/Index.lean +++ b/Mathlib/Algebra/Module/LinearMap/Index.lean @@ -65,6 +65,7 @@ public lemma index_of_surjective (hf : Surjective f) : rw [index_eq_finrank_sub, range_eq_top.mpr hf] simp [finrank_eq_zero_of_subsingleton] +set_option backward.isDefEq.respectTransparency.types false in @[simp] public lemma index_id : (id : M →ₗ[R] M).index = 0 := by nontriviality R @@ -97,6 +98,7 @@ public lemma index_eq_of_finiteDimensional [FiniteDimensional k M] [FiniteDimens have h₃ := f.ker.finrank_quotient_add_finrank lia +set_option backward.isDefEq.respectTransparency.types false in open Submodule in @[simp] public lemma index_comp {P : Type*} [AddCommGroup P] [Module k P] (g : N →ₗ[k] P) [FiniteDimensional k f.ker] [FiniteDimensional k g.ker] diff --git a/Mathlib/Algebra/Module/LinearMap/Polynomial.lean b/Mathlib/Algebra/Module/LinearMap/Polynomial.lean index 7917d4e60e82fe..c57b90b6ba5702 100644 --- a/Mathlib/Algebra/Module/LinearMap/Polynomial.lean +++ b/Mathlib/Algebra/Module/LinearMap/Polynomial.lean @@ -127,6 +127,7 @@ lemma toMvPolynomial_add (M N : Matrix m n R) : ext i : 1 simp only [toMvPolynomial, add_apply, map_add, Finset.sum_add_distrib, Pi.add_apply] +set_option backward.isDefEq.respectTransparency.types false in lemma toMvPolynomial_mul (M : Matrix m n R) (N : Matrix n o R) (i : m) : (M * N).toMvPolynomial i = bind₁ N.toMvPolynomial (M.toMvPolynomial i) := by simp only [toMvPolynomial, mul_apply, map_sum, Finset.sum_comm (γ := o), bind₁, aeval, @@ -302,6 +303,7 @@ lemma polyCharpolyAux_coeff_eval [Module.Finite R M] [Module.Free R M] (x : L) ( nontriviality R rw [← polyCharpolyAux_map_eq_charpoly φ b bₘ x, Polynomial.coeff_map] +set_option backward.isDefEq.respectTransparency.types false in lemma polyCharpolyAux_map_eval [Module.Finite R M] [Module.Free R M] (x : ι → R) : (polyCharpolyAux φ b bₘ).map (MvPolynomial.eval x) = diff --git a/Mathlib/Algebra/Module/LocalizedModule/Basic.lean b/Mathlib/Algebra/Module/LocalizedModule/Basic.lean index aa83748e5a0326..696e971054ab64 100644 --- a/Mathlib/Algebra/Module/LocalizedModule/Basic.lean +++ b/Mathlib/Algebra/Module/LocalizedModule/Basic.lean @@ -563,6 +563,7 @@ lemma IsLocalizedModule.injective_iff_isRegular [IsLocalizedModule S f] : Function.Injective f ↔ ∀ c : S, IsSMulRegular M c := by simp_rw [IsSMulRegular, Function.Injective, eq_iff_exists S, exists_imp, forall_comm (α := S)] +set_option backward.isDefEq.respectTransparency false in instance IsLocalizedModule.of_linearEquiv (e : M' ≃ₗ[R] M'') [hf : IsLocalizedModule S f] : IsLocalizedModule S (e ∘ₗ f : M →ₗ[R] M'') where map_units s := by @@ -579,6 +580,7 @@ instance IsLocalizedModule.of_linearEquiv (e : M' ≃ₗ[R] M'') [hf : IsLocaliz EmbeddingLike.apply_eq_iff_eq] at h exact hf.exists_of_eq h +set_option backward.isDefEq.respectTransparency false in instance IsLocalizedModule.of_linearEquiv_right (e : M'' ≃ₗ[R] M) [hf : IsLocalizedModule S f] : IsLocalizedModule S (f ∘ₗ e : M'' →ₗ[R] M') where map_units s := hf.map_units s @@ -1129,6 +1131,7 @@ theorem mk_eq_mk' (s : S) (m : M) : rw [eq_comm, mk'_eq_iff, Submonoid.smul_def, LocalizedModule.smul'_mk, ← Submonoid.smul_def, LocalizedModule.mk_cancel, LocalizedModule.mkLinearMap_apply] +set_option backward.isDefEq.respectTransparency false in variable (A) in lemma mk'_smul_mk' (x : R) (m : M) (s t : S) : IsLocalization.mk' A x s • mk' f m t = mk' f (x • m) (s * t) := by @@ -1168,6 +1171,7 @@ lemma liftOfLE_comp : (liftOfLE S₁ S₂ h f₁ f₂).comp f₁ = f₂ := lift_ @[simp] lemma liftOfLE_apply (x) : liftOfLE S₁ S₂ h f₁ f₂ (f₁ x) = f₂ x := lift_apply .. +set_option backward.isDefEq.respectTransparency false in /-- The image of `m/s` under `liftOfLE` is `m/s`. -/ @[simp] lemma liftOfLE_mk' (m : M) (s : S₁) : @@ -1322,6 +1326,7 @@ theorem map_comp' (g : M₀ →ₗ[R] M₁) (h : M₁ →ₗ[R] M₂) : section Algebra +set_option backward.isDefEq.respectTransparency false in theorem mkOfAlgebra {R S S' : Type*} [CommSemiring R] [Ring S] [Ring S'] [Algebra R S] [Algebra R S'] (M : Submonoid R) (f : S →ₐ[R] S') (h₁ : ∀ x ∈ M, IsUnit (algebraMap R S' x)) (h₂ : ∀ y, ∃ x : S × M, x.2 • y = f x.1) (h₃ : ∀ x, f x = 0 → ∃ m : M, m • x = 0) : diff --git a/Mathlib/Algebra/Module/NatInt.lean b/Mathlib/Algebra/Module/NatInt.lean index 80968cbeb8c4a2..853ea5298476f6 100644 --- a/Mathlib/Algebra/Module/NatInt.lean +++ b/Mathlib/Algebra/Module/NatInt.lean @@ -132,7 +132,7 @@ theorem nat_smul_eq_nsmul (h : Module ℕ M) (n : ℕ) (x : M) : h.smul n x = n /-- All `ℕ`-module structures are equal. Not an instance since in mathlib all `AddCommMonoid` should normally have exactly one `ℕ`-module structure by design. -/ -@[implicit_reducible] +@[instance_reducible] def AddCommMonoid.uniqueNatModule : Unique (Module ℕ M) where default := inferInstance uniq P := (Module.ext' P _) fun n => by convert! nat_smul_eq_nsmul P n @@ -184,7 +184,7 @@ theorem int_smul_eq_zsmul (h : Module ℤ M) (n : ℤ) (x : M) : h.smul n x = n /-- All `ℤ`-module structures are equal. Not an instance since in mathlib all `AddCommGroup` should normally have exactly one `ℤ`-module structure by design. -/ -@[implicit_reducible] +@[instance_reducible] def AddCommGroup.uniqueIntModule : Unique (Module ℤ M) where default := inferInstance uniq P := (Module.ext' P _) fun n => by convert! int_smul_eq_zsmul P n diff --git a/Mathlib/Algebra/Module/PID.lean b/Mathlib/Algebra/Module/PID.lean index 7bef59eaa54986..9b4a981dfc1ba1 100644 --- a/Mathlib/Algebra/Module/PID.lean +++ b/Mathlib/Algebra/Module/PID.lean @@ -165,6 +165,7 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^ open Finset Multiset +set_option backward.isDefEq.respectTransparency.types false in omit dec in /-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some `R ⧸ R ∙ (p ^ e i)` for some `e i`. -/ diff --git a/Mathlib/Algebra/Module/Presentation/Cokernel.lean b/Mathlib/Algebra/Module/Presentation/Cokernel.lean index 5e7bd266e20efd..9c03942065a1fe 100644 --- a/Mathlib/Algebra/Module/Presentation/Cokernel.lean +++ b/Mathlib/Algebra/Module/Presentation/Cokernel.lean @@ -98,6 +98,7 @@ variable (hg₁ : Submodule.span A (Set.range g₁) = ⊤) namespace cokernelSolution +set_option backward.isDefEq.respectTransparency false in /-- The cokernel can be defined by generators and relations. -/ noncomputable def isPresentationCore : Relations.Solution.IsPresentationCore.{w} @@ -134,6 +135,9 @@ def cokernel : Presentation A (M₂ ⧸ LinearMap.range f) := end Cokernel +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given an exact sequence of `A`-modules `M₁ → M₂ → M₃ → 0`, this is the presentation of `M₃` that is obtained from a presentation `pres₂` of `M₂`, a choice of generators `g₁ : ι → M₁` of `M₁`, and an additional data in a `Presentation.CokernelData` structure. -/ diff --git a/Mathlib/Algebra/Module/Presentation/Differentials.lean b/Mathlib/Algebra/Module/Presentation/Differentials.lean index 1dae5b2780204c..97d84e50e31266 100644 --- a/Mathlib/Algebra/Module/Presentation/Differentials.lean +++ b/Mathlib/Algebra/Module/Presentation/Differentials.lean @@ -151,6 +151,7 @@ lemma differentials.comm₂₃ : pres.differentialsSolution.π := comm₂₃' pres +set_option backward.isDefEq.respectTransparency.types false in open differentials in lemma differentialsSolution_isPresentation : pres.differentialsSolution.IsPresentation := by diff --git a/Mathlib/Algebra/Module/Presentation/DirectSum.lean b/Mathlib/Algebra/Module/Presentation/DirectSum.lean index 4b889999a013fb..caa9245fc39ede 100644 --- a/Mathlib/Algebra/Module/Presentation/DirectSum.lean +++ b/Mathlib/Algebra/Module/Presentation/DirectSum.lean @@ -84,6 +84,7 @@ namespace IsPresentation variable {solution : ∀ (i : ι), (relations i).Solution (M i)} (h : ∀ i, (solution i).IsPresentation) +set_option backward.isDefEq.respectTransparency false in /-- The direct sum admits a presentation by generators and relations. -/ noncomputable def directSum.isRepresentationCore : Solution.IsPresentationCore.{w'} (directSum solution) where diff --git a/Mathlib/Algebra/Module/SnakeLemma.lean b/Mathlib/Algebra/Module/SnakeLemma.lean index bb7a8776f1f85d..6c18efd9843577 100644 --- a/Mathlib/Algebra/Module/SnakeLemma.lean +++ b/Mathlib/Algebra/Module/SnakeLemma.lean @@ -82,6 +82,7 @@ lemma SnakeLemma.eq_of_eq (x : K₃) rw [← sub_eq_zero, ← map_sub, hz₁, hπ₁] exact ⟨_, rfl⟩ +set_option backward.isDefEq.respectTransparency false in /-- **Snake Lemma** Suppose we have an exact commutative diagram diff --git a/Mathlib/Algebra/Module/Submodule/Bilinear.lean b/Mathlib/Algebra/Module/Submodule/Bilinear.lean index 4d739f6616c6dc..658cfd25f5e2bc 100644 --- a/Mathlib/Algebra/Module/Submodule/Bilinear.lean +++ b/Mathlib/Algebra/Module/Submodule/Bilinear.lean @@ -57,6 +57,7 @@ theorem map₂_le {f : M →ₗ[R] N →ₗ[R] P} {p : Submodule R M} {q : Submo ⟨fun H _m hm _n hn => H <| apply_mem_map₂ _ hm hn, fun H => iSup_le fun ⟨m, hm⟩ => map_le_iff_le_comap.2 fun n hn => H m hm n hn⟩ +set_option backward.isDefEq.respectTransparency false in variable (R) in theorem map₂_span_span (f : M →ₗ[R] N →ₗ[R] P) (s : Set M) (t : Set N) : map₂ f (span R s) (span R t) = span R (Set.image2 (fun m n => f m n) s t) := by diff --git a/Mathlib/Algebra/Module/Submodule/Defs.lean b/Mathlib/Algebra/Module/Submodule/Defs.lean index 9b7075715d3ddc..4f8673dd42f748 100644 --- a/Mathlib/Algebra/Module/Submodule/Defs.lean +++ b/Mathlib/Algebra/Module/Submodule/Defs.lean @@ -179,7 +179,7 @@ instance (priority := 75) toModule : Module R S' := fast_instance% /-- This can't be an instance because Lean wouldn't know how to find `R`, but we can still use this to manually derive `Module` on specific types. -/ -@[implicit_reducible] +@[instance_reducible] def toModule' (S R' R A : Type*) [Semiring R] [NonUnitalNonAssocSemiring A] [Module R A] [Semiring R'] [SMul R' R] [Module R' A] [IsScalarTower R' R A] [SetLike S A] [AddSubmonoidClass S A] [SMulMemClass S R A] (s : S) : diff --git a/Mathlib/Algebra/Module/Submodule/Invariant.lean b/Mathlib/Algebra/Module/Submodule/Invariant.lean index ec04da8d126ce9..620c23580f7b15 100644 --- a/Mathlib/Algebra/Module/Submodule/Invariant.lean +++ b/Mathlib/Algebra/Module/Submodule/Invariant.lean @@ -98,9 +98,11 @@ lemma sup_mem {p q : Submodule R M} (hp : p ∈ f.invtSubmodule) (hq : q ∈ f.i variable (f) +set_option backward.isDefEq.respectTransparency false in @[simp] protected lemma top_mem : ⊤ ∈ f.invtSubmodule := by simp [invtSubmodule] +set_option backward.isDefEq.respectTransparency false in @[simp] protected lemma bot_mem : ⊥ ∈ f.invtSubmodule := by simp [invtSubmodule] @@ -125,10 +127,12 @@ protected lemma one : invtSubmodule (1 : End R M) = ⊤ := invtSubmodule.id +set_option backward.isDefEq.respectTransparency false in protected lemma mk_eq_bot_iff {p : Submodule R M} (hp : p ∈ f.invtSubmodule) : (⟨p, hp⟩ : f.invtSubmodule) = ⊥ ↔ p = ⊥ := Subtype.mk_eq_bot_iff (by simp [invtSubmodule]) _ +set_option backward.isDefEq.respectTransparency false in protected lemma mk_eq_top_iff {p : Submodule R M} (hp : p ∈ f.invtSubmodule) : (⟨p, hp⟩ : f.invtSubmodule) = ⊤ ↔ p = ⊤ := Subtype.mk_eq_top_iff (by simp [invtSubmodule]) _ @@ -171,6 +175,7 @@ protected lemma isCompl_iff {p q : f.invtSubmodule} : obtain ⟨q, hq⟩ := q simp +set_option backward.isDefEq.respectTransparency false in lemma map_subtype_mem_of_mem_invtSubmodule {p : Submodule R M} (hp : p ∈ f.invtSubmodule) {q : Submodule R p} (hq : q ∈ invtSubmodule (LinearMap.restrict f hp)) : Submodule.map p.subtype q ∈ f.invtSubmodule := by diff --git a/Mathlib/Algebra/Module/Submodule/Ker.lean b/Mathlib/Algebra/Module/Submodule/Ker.lean index 648550bf003221..edc703d483c836 100644 --- a/Mathlib/Algebra/Module/Submodule/Ker.lean +++ b/Mathlib/Algebra/Module/Submodule/Ker.lean @@ -121,6 +121,7 @@ theorem ker_codRestrict (p : Submodule R₂ M₂) (f : M →ₛₗ[τ₁₂] M lemma ker_domRestrict (p : Submodule R M) (f : M →ₛₗ[τ₁₂] M₂) : ker (domRestrict f p) = (ker f).comap p.subtype := ker_comp .. +set_option backward.isDefEq.respectTransparency false in theorem ker_restrict {p : Submodule R M} {q : Submodule R₂ M₂} {f : M →ₛₗ[τ₁₂] M₂} (hf : ∀ x : M, x ∈ p → f x ∈ q) : ker (f.restrict hf) = (ker f).comap p.subtype := by diff --git a/Mathlib/Algebra/Module/Submodule/LinearMap.lean b/Mathlib/Algebra/Module/Submodule/LinearMap.lean index f56b84fd0be83f..9287cb8d82cd56 100644 --- a/Mathlib/Algebra/Module/Submodule/LinearMap.lean +++ b/Mathlib/Algebra/Module/Submodule/LinearMap.lean @@ -185,6 +185,7 @@ section variable {M₂' : Type*} [AddCommMonoid M₂'] [Module R₂ M₂'] (p : M₂' →ₗ[R₂] M₂) (hp : Injective p) (h : ∀ c, f c ∈ range p) +set_option backward.isDefEq.respectTransparency false in /-- A linear map `f : M → M₂` whose values lie in the image of an injective linear map `p : M₂' → M₂` admits a unique lift to a linear map `M → M₂'`. -/ noncomputable def codLift : @@ -224,6 +225,7 @@ theorem restrict_apply {f : M →ₛₗ[σ₁₂] M₂} {p : Submodule R M} {q : (hf : ∀ x ∈ p, f x ∈ q) (x : p) : f.restrict hf x = ⟨f x, hf x.1 x.2⟩ := rfl +set_option backward.isDefEq.respectTransparency false in lemma restrict_sub {R R₂ M M₂ : Type*} [Ring R] [Ring R₂] {σ₁₂ : R →+* R₂} [AddCommGroup M] [AddCommGroup M₂] [Module R M] [Module R₂ M₂] {p : Submodule R M} {q : Submodule R₂ M₂} {f g : M →ₛₗ[σ₁₂] M₂} diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 0eba5457bb7a25..87b6047a2a4e44 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -168,6 +168,7 @@ theorem map_equivMapOfInjective_symm_apply (f : M →ₛₗ[σ₁₂] M₂) (i : i.eq_iff, LinearEquiv.apply_symm_apply] /-- The pullback of a submodule `p ⊆ M₂` along `f : M → M₂` -/ +@[implicit_reducible] def comap (f : M →ₛₗ[σ₁₂] M₂) (p : Submodule R₂ M₂) : Submodule R M := { p.toAddSubmonoid.comap f with carrier := f ⁻¹' p @@ -537,8 +538,8 @@ of `t.subtype`. -/ def comapSubtypeEquivOfLe {p q : Submodule R M} (hpq : p ≤ q) : comap q.subtype p ≃ₗ[R] p where toFun x := ⟨x, x.2⟩ invFun x := ⟨⟨x, hpq x.2⟩, x.2⟩ - left_inv x := by simp only [SetLike.eta] - right_inv x := by simp only [SetLike.eta] + left_inv x := by simp + right_inv x := by simp map_add' _ _ := rfl map_smul' _ _ := rfl @@ -692,11 +693,13 @@ theorem comap_domRestrict (p : Submodule R₂ M₂) (f : M₂ →ₛₗ[σ₂₁ comap (domRestrict f p) p' = comap p.subtype (comap f p') := comap_comp p.subtype f p' +set_option backward.isDefEq.respectTransparency.types false in theorem map_restrict [RingHomSurjective σ₂₁] {p : Submodule R₂ M₂} {q : Submodule R M} {f : M₂ →ₛₗ[σ₂₁] M} (h : ∀ x ∈ p, f x ∈ q) (p') : map (f.restrict h) p' = comap q.subtype (map f (map p.subtype p')) := by rw [restrict_eq_codRestrict_domRestrict, map_codRestrict, map_domRestrict] +set_option backward.isDefEq.respectTransparency.types false in theorem comap_restrict {p : Submodule R₂ M₂} {q : Submodule R M} {f : M₂ →ₛₗ[σ₂₁] M} (h : ∀ x ∈ p, f x ∈ q) (p') : comap (f.restrict h) p' = comap p.subtype (comap f (map q.subtype p')) := by @@ -719,6 +722,7 @@ variable {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} variable {re₁₂ : RingHomInvPair σ₁₂ σ₂₁} {re₂₁ : RingHomInvPair σ₂₁ σ₁₂} variable (e : M ≃ₛₗ[σ₁₂] M₂) +set_option backward.isDefEq.respectTransparency false in /-- A linear equivalence of two modules restricts to a linear equivalence from any submodule `p` of the domain onto the image of that submodule. diff --git a/Mathlib/Algebra/Module/Submodule/Range.lean b/Mathlib/Algebra/Module/Submodule/Range.lean index 8197d95db2ec94..475edaadb09491 100644 --- a/Mathlib/Algebra/Module/Submodule/Range.lean +++ b/Mathlib/Algebra/Module/Submodule/Range.lean @@ -144,6 +144,7 @@ def iterateRange (f : M →ₗ[R] M) : ℕ →o (Submodule R M)ᵒᵈ where toFun n := LinearMap.range (f ^ n) monotone' := monotone_nat_of_le_succ fun | n, _, ⟨x, rfl⟩ => ⟨f x, rfl⟩ +set_option backward.isDefEq.respectTransparency false in lemma iterateRange_succ {f : M →ₗ[R] M} {n : ℕ} : iterateRange f (n + 1) = (iterateRange f n).map f := by simp only [iterateRange_coe, range_eq_map, ← map_comp, Module.End.iterate_succ'] @@ -351,6 +352,7 @@ lemma restrictScalars_map [SMul R R₂] [Module R₂ M] [Module R M₂] [IsScala [IsScalarTower R R₂ M₂] (f : M →ₗ[R₂] M₂) (M' : Submodule R₂ M) : (M'.map f).restrictScalars R = (M'.restrictScalars R).map (f.restrictScalars R) := rfl +set_option backward.isDefEq.respectTransparency false in /-- If `N ⊆ M` then submodules of `N` are the same as submodules of `M` contained in `N`. See also `Submodule.mapIic`. -/ diff --git a/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean b/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean index a1d249200d4eee..8164d043f5b905 100644 --- a/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean +++ b/Mathlib/Algebra/Module/Submodule/RestrictScalars.lean @@ -137,6 +137,7 @@ lemma restrictScalars_sInf (s : Set (Submodule R M)) : (sInf s).restrictScalars S = sInf (restrictScalars S '' s) := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma restrictScalars_sSup (s : Set (Submodule R M)) : (sSup s).restrictScalars S = sSup (restrictScalars S '' s) := by diff --git a/Mathlib/Algebra/Module/Torsion/Basic.lean b/Mathlib/Algebra/Module/Torsion/Basic.lean index 5ec9aad55261ff..b270a3c789eecc 100644 --- a/Mathlib/Algebra/Module/Torsion/Basic.lean +++ b/Mathlib/Algebra/Module/Torsion/Basic.lean @@ -549,7 +549,7 @@ variable [Ring R] [AddCommGroup M] [Module R M] variable {I : Ideal R} {r : R} /-- can't be an instance because `hM` can't be inferred -/ -@[implicit_reducible] +@[instance_reducible] def IsTorsionBySet.hasSMul (hM : IsTorsionBySet R M I) : SMul (R ⧸ I) M where smul b := QuotientAddGroup.lift I.toAddSubgroup (smulAddHom R M) (by rwa [isTorsionBySet_iff_subset_annihilator] at hM) b @@ -573,7 +573,7 @@ theorem IsTorsionBy.mk_smul [(Ideal.span {r}).IsTwoSided] (hM : IsTorsionBy R M rfl /-- An `(R ⧸ I)`-module is an `R`-module which `IsTorsionBySet R M I`. -/ -@[implicit_reducible] +@[instance_reducible] def IsTorsionBySet.module [I.IsTwoSided] (hM : IsTorsionBySet R M I) : Module (R ⧸ I) M := letI := hM.hasSMul; fast_instance% I.mkQ_surjective.moduleLeft _ (IsTorsionBySet.mk_smul hM) @@ -608,7 +608,7 @@ where finally /-- Any module is also a module over the quotient of the ring by the annihilator. Not an instance because it causes synthesis failures / timeouts. -/ -@[implicit_reducible] +@[instance_reducible] def quotientAnnihilator : Module (R ⧸ Module.annihilator R M) M := (isTorsionBySet_annihilator R M).module @@ -1005,7 +1005,7 @@ lemma torsionBy.mod_self_nsmul' (s : ℕ) {x : A} (h : x ∈ A[n]) : nsmul_eq_mod_nsmul s (torsionBy.nsmul_iff.mp h) /-- For a natural number `n`, the `n`-torsion subgroup of `A` is a `ZMod n` module. -/ -@[implicit_reducible] +@[instance_reducible] def torsionBy.zmodModule : Module (ZMod n) A[n] := AddCommGroup.zmodModule torsionBy.nsmul diff --git a/Mathlib/Algebra/Module/TransferInstance.lean b/Mathlib/Algebra/Module/TransferInstance.lean index f3e43ed03f1560..f41ca4f27218fb 100644 --- a/Mathlib/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Algebra/Module/TransferInstance.lean @@ -63,6 +63,7 @@ def linearEquiv (e : α ≃ β) [AddCommMonoid β] [Module R β] : simp only [toFun_as_coe, RingHom.id_apply, EmbeddingLike.apply_eq_iff_eq] exact Iff.mpr (apply_eq_iff_eq_symm_apply _) rfl } +set_option backward.isDefEq.respectTransparency false in variable (R) in /-- Transfer `Module.IsTorsionFree` across an `Equiv` -/ protected lemma moduleIsTorsionFree (e : α ≃ β) [AddCommMonoid β] [Module R β] diff --git a/Mathlib/Algebra/Module/ZLattice/Covolume.lean b/Mathlib/Algebra/Module/ZLattice/Covolume.lean index 8378bc4811ea93..1e055b28c7e9be 100644 --- a/Mathlib/Algebra/Module/ZLattice/Covolume.lean +++ b/Mathlib/Algebra/Module/ZLattice/Covolume.lean @@ -140,6 +140,7 @@ theorem covolume_eq_det_inv {ι : Type*} [Fintype ι] (L : Submodule ℤ (ι → IsUnit.unit_spec, ← Basis.det_basis, LinearEquiv.coe_det] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Let `L₁` be a sub-`ℤ`-lattice of `L₂`. Then the index of `L₁` inside `L₂` is equal to `covolume L₁ / covolume L₂`. @@ -188,6 +189,7 @@ theorem volume_image_eq_volume_div_covolume {ι : Type*} [Fintype ι] (L : Submo LinearEquiv.symm_symm, covolume_eq_det_inv L b, ENNReal.div_eq_inv_mul, ENNReal.ofReal_inv_of_pos (abs_pos.2 (LinearEquiv.det _).ne_zero), inv_inv, LinearEquiv.coe_det] +set_option backward.isDefEq.respectTransparency.types false in /-- A more general version of `ZLattice.volume_image_eq_volume_div_covolume`; see the `Naming conventions` section in the introduction. -/ theorem volume_image_eq_volume_div_covolume' {E : Type*} [NormedAddCommGroup E] @@ -220,6 +222,7 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {L : Submodule ℤ E} [DiscreteTopology L] [IsZLattice ℝ L] variable {ι : Type*} [Fintype ι] (b : Basis ι ℤ L) +set_option backward.isDefEq.respectTransparency.types false in /-- A version of `ZLattice.covolume.tendsto_card_div_pow` for the general case; see the `Naming convention` section in the introduction. -/ theorem tendsto_card_div_pow'' [FiniteDimensional ℝ E] [MeasurableSpace E] [BorelSpace E] diff --git a/Mathlib/Algebra/Module/ZLattice/Summable.lean b/Mathlib/Algebra/Module/ZLattice/Summable.lean index ddd21638b73105..50c5a3667ef148 100644 --- a/Mathlib/Algebra/Module/ZLattice/Summable.lean +++ b/Mathlib/Algebra/Module/ZLattice/Summable.lean @@ -155,6 +155,7 @@ lemma sum_piFinset_Icc_rpow_le {ι : Type*} [Fintype ι] [DecidableEq ι] variable (L) +set_option backward.isDefEq.respectTransparency.types false in lemma exists_finsetSum_norm_rpow_le_tsum : ∃ A > (0 : ℝ), ∀ r < (-Module.finrank ℤ L : ℝ), ∀ s : Finset L, ∑ z ∈ s, ‖z‖ ^ r ≤ A ^ r * ∑' k : ℕ, (k : ℝ) ^ (Module.finrank ℤ L - 1 + r) := by diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index 7da1c96a60787e..57fa8f1f929668 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -125,6 +125,7 @@ def uniqueAlgEquiv [Subsingleton M] : A[M] ≃ₐ[R] A where toRingEquiv := uniqueRingEquiv _ commutes' r := by simp +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in @[to_additive (dont_translate := A) (attr := simp)] lemma uniqueAlgEquiv_symm_apply [Subsingleton M] (a : A) : @@ -163,6 +164,7 @@ def curryAlgEquiv : A[M × N] ≃ₐ[R] A[N][M] where lemma curryAlgEquiv_single (m : M) (n : N) (a : A) : curryAlgEquiv R (single (m, n) a) = single m (single n a) := by simp [curryAlgEquiv] +set_option backward.isDefEq.respectTransparency.types false in @[to_additive (attr := simp)] lemma curryAlgEquiv_symm_single (m : M) (n : N) (a : A) : (curryAlgEquiv R).symm (single m <| single n a) = (single (m, n) a) := by @@ -230,6 +232,7 @@ lemma algHom_ext' ⦃φ₁ φ₂ : A[M] →ₐ[R] B⦄ (single_one_left : φ₁.comp singleOneAlgHom = φ₂.comp singleOneAlgHom) : φ₁ = φ₂ := algHom_ext (congr($single_one_right ·)) single_one_left +set_option backward.isDefEq.respectTransparency false in variable (R A M) in /-- Any monoid homomorphism `M →* A` can be lifted to an algebra homomorphism `R[M] →ₐ[R] A`. -/ def lift : (M →* A) ≃ (R[M] →ₐ[R] A) where @@ -278,6 +281,7 @@ theorem lift_mapRingHom_algebraMap [CommSemiring S] [Algebra S A] @[deprecated (since := "2026-06-18")] alias lift_mapRangeRingHom_algebraMap := lift_mapRingHom_algebraMap +set_option backward.isDefEq.respectTransparency false in variable (R A) in /-- If `f : M → N` is a monoid homomorphism, then `MonoidAlgebra.mapDomain f` is an algebra homomorphism between their monoid algebras. -/ @@ -288,9 +292,11 @@ def mapDomainAlgHom (f : M →* N) : A[M] →ₐ[R] A[N] where toRingHom := mapDomainRingHom A f commutes' := by simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := A) (attr := simp)] lemma mapDomainAlgHom_id : mapDomainAlgHom R A (.id M) = .id R A[M] := by ext <;> simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := A) (attr := simp)] lemma mapDomainAlgHom_comp (f : M →* N) (g : N →* O) : mapDomainAlgHom R A (g.comp f) = (mapDomainAlgHom R A g).comp (mapDomainAlgHom R A f) := by @@ -315,6 +321,7 @@ lemma coeff_domCongr (e : M ≃* N) (f : A[M]) (n : N) : @[to_additive] theorem domCongr_toAlgHom (e : M ≃* N) : (domCongr R A e).toAlgHom = mapDomainAlgHom R A e := rfl +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma domCongr_support (e : M ≃* N) (x : A[M]) : (domCongr R A e x).coeff.support = x.coeff.support.map e := by simp [domCongr, equivMapDomain] @@ -593,6 +600,7 @@ lemma algHom_ext' ⦃φ₁ φ₂ : A[M] →ₐ[R] B⦄ (single_one_left : φ₁.comp singleZeroAlgHom = φ₂.comp singleZeroAlgHom) : φ₁ = φ₂ := algHom_ext (congr($single_one_right ·)) single_one_left +set_option backward.isDefEq.respectTransparency false in variable (R M A) in /-- Any monoid homomorphism `M →* A` can be lifted to an algebra homomorphism `R[M] →ₐ[R] A`. -/ @@ -676,6 +684,7 @@ end AddMonoidAlgebra variable [CommSemiring R] [Semiring A] [Algebra R A] +set_option backward.isDefEq.respectTransparency false in variable (A M) in /-- The algebra equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of `Multiplicative`. -/ @@ -684,6 +693,7 @@ def AddMonoidAlgebra.toMultiplicativeAlgEquiv [AddMonoid M] : toRingEquiv := AddMonoidAlgebra.toMultiplicative A M commutes' r := by simp [AddMonoidAlgebra.toMultiplicative] +set_option backward.isDefEq.respectTransparency false in variable (A M) in /-- The algebra equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive`. -/ diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index c4cc223d98c642..b404caafd7e06a 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -324,6 +324,7 @@ lemma coeff_smul_apply (a : A) (x : R[M]) (m : M) : coeff (a • x) m = a • co @[deprecated (since := "2026-06-18")] alias smul_apply := coeff_smul_apply +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp) (dont_translate := A) smul_single] lemma smul_single (a : A) (m : M) (r : R) : a • single m r = single m (a • r) := by ext; simp @@ -430,6 +431,7 @@ theorem coeff_single_apply {a a' : M} {b : R} [Decidable (a = a')] : @[to_additive (attr := simp)] lemma single_eq_zero : single m r = 0 ↔ r = 0 := by simp [← coeff_inj] +set_option backward.isDefEq.respectTransparency false in @[to_additive] lemma single_ne_zero : single m r ≠ 0 ↔ r ≠ 0 := single_eq_zero.not @[to_additive (attr := elab_as_elim)] @@ -516,6 +518,7 @@ lemma coeff_mul [DecidableEq M] (x y : R[M]) (m : M) : mul_apply] alias mul_apply := coeff_mul +set_option backward.isDefEq.respectTransparency false in open Finset in @[to_additive (dont_translate := R) coeff_mul_antidiag] lemma coeff_mul_antidiag (x y : R[M]) (m : M) (s : Finset (M × M)) @@ -554,6 +557,7 @@ lemma single_commute (hm : ∀ m', Commute m m') (hr : ∀ r', Commute r r') (x ext m' r' : 2; exact single_commute_single (hm m') (hr r') exact congr($this x) +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) coeff_mul_single_eq_coeff_mul] lemma coeff_mul_single_eq_coeff_mul (m₂ : M) (H : ∀ m' ∈ x.coeff.support, m' * m = m₁ ↔ m' = m₂) : (x * single m r).coeff m₁ = x.coeff m₂ * r := by @@ -566,6 +570,7 @@ lemma coeff_mul_single_eq_coeff_mul (m₂ : M) (H : ∀ m' ∈ x.coeff.support, @[deprecated (since := "2026-06-18")] alias mul_single_apply_aux := coeff_mul_single_eq_coeff_mul +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) coeff_single_mul_eq_mul_coeff] lemma coeff_single_mul_eq_mul_coeff (m₂ : M) (H : ∀ m' ∈ x.coeff.support, m * m' = m₁ ↔ m' = m₂) : (single m r * x).coeff m₁ = r * x.coeff m₂ := by @@ -582,10 +587,12 @@ lemma coeff_single_mul_eq_mul_coeff (m₂ : M) (H : ∀ m' ∈ x.coeff.support, lemma coeff_mul_single_of_forall_mul_ne (r : R) (x : R[M]) (h : ∀ d, d * m ≠ m') : (x * single m r).coeff m' = 0 := by classical simp [coeff_mul, h] +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp) (dont_translate := R) coeff_single_mul_of_forall_add_ne] lemma coeff_single_mul_of_forall_mul_ne (r : R) (x : R[M]) (h : ∀ d, m * d ≠ m') : (single m r * x).coeff m' = 0 := by classical simp [coeff_mul, h] +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := deprecated coeff_mul_single_of_forall_mul_ne (since := "2026-06-18")) (dont_translate := R)] lemma mul_single_apply_of_not_exists_mul (r : R) {g g' : M} (x : R[M]) @@ -747,6 +754,7 @@ def uniqueRingEquiv [Subsingleton M] : R[M] ≃+* R where refine (coeff_mul ..).trans ?_ simp [Finsupp.sum_unique, Unique.eq_default] +set_option backward.isDefEq.respectTransparency.types false in variable (M) in @[to_additive (dont_translate := R) (attr := simp)] lemma uniqueRingEquiv_symm_apply [Subsingleton M] (r : R) : @@ -787,6 +795,7 @@ def curryRingEquiv : R[M × N] ≃+* R[N][M] where lemma curryRingEquiv_single (m : M) (n : N) (r : R) : curryRingEquiv (single (m, n) r) = single m (single n r) := by simp [curryRingEquiv] +set_option backward.isDefEq.respectTransparency.types false in @[to_additive (attr := simp)] lemma curryRingEquiv_symm_single (m : M) (n : N) (r : R) : curryRingEquiv.symm (single m <| single n r) = (single (m, n) r) := by @@ -816,6 +825,7 @@ lemma coeff_mul_single_apply (x : R[G]) (r : R) (g h : G) : @[deprecated (since := "2026-06-18")] alias mul_single_apply := coeff_mul_single_apply +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp) (dont_translate := R) coeff_single_mul_apply] lemma coeff_single_mul_apply (x : R[G]) (r : R) (g h : G) : (single g r * x).coeff h = r * x.coeff (g⁻¹ * h) := @@ -823,6 +833,7 @@ lemma coeff_single_mul_apply (x : R[G]) (r : R) (g h : G) : @[deprecated (since := "2026-06-18")] alias single_mul_apply := coeff_single_mul_apply +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) coeff_mul_apply_left] lemma coeff_mul_apply_left (x y : R[G]) (g : G) : (x * y).coeff g = x.coeff.sum fun h r ↦ r * y.coeff (h⁻¹ * g) := by @@ -830,6 +841,7 @@ lemma coeff_mul_apply_left (x y : R[G]) (g : G) : @[deprecated (since := "2026-06-18")] alias mul_apply_left := coeff_mul_apply_left +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) coeff_mul_apply_right] lemma coeff_mul_apply_right (x y : R[G]) (g : G) : (x * y).coeff g = y.coeff.sum fun h r ↦ x.coeff (g * h⁻¹) * r := by @@ -985,6 +997,7 @@ def singleHom [AddZeroClass M] : R × Multiplicative M →* R[M] where map_one' := rfl map_mul' _a _b := (single_mul_single ..).symm +set_option backward.isDefEq.respectTransparency false in theorem induction_on [AddMonoid M] {p : R[M] → Prop} (x : R[M]) (hM : ∀ m, p (of R M <| .ofAdd m)) (hadd : ∀ x y : R[M], p x → p y → p (x + y)) (hsmul : ∀ (r : R) (x), p x → p (r • x)) : p x := diff --git a/Mathlib/Algebra/MonoidAlgebra/Degree.lean b/Mathlib/Algebra/MonoidAlgebra/Degree.lean index 69707c9be5ca1e..76b97d8645fc62 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Degree.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Degree.lean @@ -440,6 +440,7 @@ lemma supDegree_mem_support (hD : D.Injective) (hp : p ≠ 0) : obtain ⟨a, ha, he⟩ := exists_supDegree_mem_support D hp rwa [he, Function.leftInverse_invFun hD] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma leadingCoeff_eq_zero (hD : D.Injective) : p.leadingCoeff D = 0 ↔ p = 0 := by refine ⟨(fun h => ?_).mtr, fun h => h ▸ leadingCoeff_zero⟩ @@ -512,6 +513,7 @@ lemma coeff_supDegree_add_supDegree (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 @[deprecated (since := "2026-06-18")] alias apply_supDegree_add_supDegree := coeff_supDegree_add_supDegree +set_option backward.isDefEq.respectTransparency false in lemma supDegree_mul (hD : D.Injective) (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) (hpq : leadingCoeff D p * leadingCoeff D q ≠ 0) diff --git a/Mathlib/Algebra/MonoidAlgebra/Grading.lean b/Mathlib/Algebra/MonoidAlgebra/Grading.lean index ce985acf86dc7e..bd77bc1cc0ac19 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Grading.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Grading.lean @@ -67,6 +67,7 @@ theorem mem_grade_iff (m : M) (a : R[M]) : a ∈ grade R m ↔ a.coeff.support rw [← Finset.coe_subset, Finset.coe_singleton] rfl +set_option backward.isDefEq.respectTransparency.types false in theorem mem_grade_iff' (m : M) (a : R[M]) : a ∈ grade R m ↔ a ∈ LinearMap.range (lsingle (R := R) m) := by rw [mem_grade_iff, Finsupp.support_subset_singleton']; simp [← coeff_inj, eq_comm] @@ -154,6 +155,7 @@ theorem decomposeAux_coe {i : ι} (x : gradeBy R f i) : apply DirectSum.of_eq_of_gradedMonoid_eq congr 2 +set_option backward.isDefEq.respectTransparency.types false in instance gradeBy.gradedAlgebra : GradedAlgebra (gradeBy R f) := .ofAlgHom _ (decomposeAux f) (by ext; simp [decomposeAux_single]) <| by simp [decomposeAux_coe] diff --git a/Mathlib/Algebra/MonoidAlgebra/Lift.lean b/Mathlib/Algebra/MonoidAlgebra/Lift.lean index e1e568811444da..277423aa4c5b84 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Lift.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Lift.lean @@ -60,6 +60,7 @@ section Mul variable [Semiring k] [Mul G] [Semiring R] +set_option backward.isDefEq.respectTransparency false in theorem liftNC_mul {g_hom : Type*} [FunLike g_hom G R] [MulHomClass g_hom G R] (f : k →+* R) (g : g_hom) (a b : k[G]) (h_comm : ∀ {x y}, y ∈ a.coeff.support → Commute (f (b.coeff x)) (g y)) : diff --git a/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean b/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean index 4c26e9fb3c9cc1..6ae7e4da44424a 100644 --- a/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean +++ b/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean @@ -53,6 +53,7 @@ lemma mapDomain_single : mapDomain f (single a r) = single (f a) r := by ext; si lemma mapDomain_injective (hf : Injective f) : Injective (mapDomain (R := R) f) := ofCoeff_injective.comp <| (Finsupp.mapDomain_injective hf).comp coeff_injective +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) (attr := simp) mapDomain_one] theorem mapDomain_one [One M] [One N] {F : Type*} [FunLike F M N] [OneHomClass F M N] (f : F) : mapDomain f (1 : R[M]) = (1 : R[N]) := by @@ -88,9 +89,11 @@ protected lemma map_sum (f : R →+ S) (s : Finset ι) (x : ι → R[M]) : @[to_additive (attr := simp)] lemma map_single (f : R →+ S) (r : R) (m : M) : map f (single m r) = single m (f r) := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma map_id (x : R[M]) : map (.id R) x = x := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma map_map (f : S →+ T) (g : R →+ S) (x : R[M]) : map f (map g x) = map (f.comp g) x := by ext; simp @@ -150,6 +153,7 @@ def comapDomainAddMonoidHom (f : M → N) (hf : Injective f) : R[N] →+ R[M] wh map_zero' := by simp map_add' := by simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma comapDomain_single_map (f : M → N) (hf) (m : M) (r : R) : comapDomain f hf (single (f m) r) = single m r := by ext; simp @@ -178,15 +182,18 @@ def mapDomainNonUnitalRingHom (f : M →ₙ* N) : R[M] →ₙ+* R[N] where map_add' := mapDomain_add _ map_mul' := mapDomain_mul f +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) (attr := simp)] lemma mapDomainNonUnitalRingHom_id : mapDomainNonUnitalRingHom R (.id M) = .id R[M] := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) (attr := simp)] lemma mapDomainNonUnitalRingHom_comp (f : N →ₙ* O) (g : M →ₙ* N) : mapDomainNonUnitalRingHom R (f.comp g) = (mapDomainNonUnitalRingHom R f).comp (mapDomainNonUnitalRingHom R g) := by ext; simp [Finsupp.mapDomain_comp] +set_option backward.isDefEq.respectTransparency false in variable (R) in /-- Equivalent monoids have additively isomorphic monoid algebras. @@ -202,12 +209,14 @@ def mapDomainAddEquiv (e : M ≃ N) : R[M] ≃+ R[N] where right_inv x := by ext; simp map_add' x y := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma coeff_mapDomainAddEquiv (e : M ≃ N) (x : R[M]) : (mapDomainAddEquiv R e x).coeff = equivMapDomain e x.coeff := by ext; simp [mapDomainAddEquiv] @[deprecated (since := "2026-06-18")] alias mapDomainAddEquiv_apply := coeff_mapDomainAddEquiv +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapDomainAddEquiv_single (e : M ≃ N) (r : R) (m : M) : mapDomainAddEquiv R e (single m r) = single (e m) r := by simp [mapDomainAddEquiv] @@ -238,6 +247,7 @@ def mapAddEquiv (e : R ≃+ S) : R[M] ≃+ S[M] where @[deprecated (since := "2026-03-20")] alias mapRangeAddEquiv := mapAddEquiv +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma coeff_mapAddEquiv (e : R ≃+ S) (x : R[M]) (m : M) : (mapAddEquiv M e x).coeff m = e (x.coeff m) := by simp [mapAddEquiv] @@ -246,6 +256,7 @@ lemma coeff_mapAddEquiv (e : R ≃+ S) (x : R[M]) (m : M) : @[deprecated (since := "2026-03-20")] alias mapRangeAddEquiv_apply := coeff_mapAddEquiv +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapAddEquiv_single (e : R ≃+ S) (r : R) (m : M) : mapAddEquiv M e (single m r) = single m (e r) := by simp [mapAddEquiv] @@ -294,6 +305,7 @@ attribute [local ext high] ringHom_ext @[to_additive (dont_translate := R) (attr := simp)] lemma mapDomainRingHom_id : mapDomainRingHom R (.id M) = .id R[M] := by ext <;> simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R) (attr := simp)] lemma mapDomainRingHom_comp (f : N →* O) (g : M →* N) : mapDomainRingHom R (f.comp g) = (mapDomainRingHom R f).comp (mapDomainRingHom R g) := by @@ -321,6 +333,7 @@ lemma coe_mapRingHom (f : R →+* S) : ⇑(mapRingHom M f) = map f := rfl @[deprecated (since := "2026-03-20")] alias coe_mapRangeRingHom := coe_mapRingHom +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma coeff_mapRingHom (f : R →+* S) (x : R[M]) (m : M) : (mapRingHom M f x).coeff m = f (x.coeff m) := by simp [mapRingHom] @@ -355,6 +368,7 @@ lemma mapRingHom_comp_mapDomainRingHom (f : R →+* S) (g : M →* N) : @[deprecated (since := "2026-03-20")] alias mapRangeRingHom_comp_mapDomainRingHom := mapRingHom_comp_mapDomainRingHom +set_option backward.isDefEq.respectTransparency false in variable (R) in /-- Isomorphic monoids have isomorphic monoid algebras. -/ @[to_additive (dont_translate := R) @@ -369,6 +383,7 @@ lemma coeff_mapDomainRingEquiv (e : M ≃* N) (x : R[M]) : @[deprecated (since := "2026-06-18")] alias mapDomainRingEquiv_apply := coeff_mapDomainRingEquiv +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapDomainRingEquiv_single (e : M ≃* N) (r : R) (m : M) : mapDomainRingEquiv R e (single m r) = single (e m) r := by simp [mapDomainRingEquiv] diff --git a/Mathlib/Algebra/MonoidAlgebra/Module.lean b/Mathlib/Algebra/MonoidAlgebra/Module.lean index 8f8721f29c6dcf..f543912d3e6e0e 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Module.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Module.lean @@ -152,6 +152,7 @@ lemma supported_eq_map : supported R S s = (Finsupp.supported S R s).map (coeffLinearEquiv R).symm.toLinearMap := Submodule.comap_equiv_eq_map_symm .. +set_option backward.isDefEq.respectTransparency false in variable (R S s) in @[to_additive (dont_translate := R)] lemma supported_eq_span_single : supported R R s = .span R ((fun m ↦ single m 1) '' s) := by @@ -161,6 +162,9 @@ lemma supported_eq_span_single : supported R R s = .span R ((fun m ↦ single m @[to_additive (attr := gcongr)] lemma supported_mono (hst : s ⊆ t) : supported R S s ≤ supported R S t := fun _ h ↦ h.trans hst +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Interpret `Finsupp.restrictSupportEquiv` as a linear equivalence between `supported M R s` and `s →₀ M`. -/ @[to_additive (dont_translate := R) (attr := simps!) @@ -201,6 +205,7 @@ def comapDistribMulActionSelf [Group G] [Semiring S] : DistribMulAction G S[G] : have := Finsupp.comapDistribMulAction (G := G) (α := G) (M := S) fast_instance% coeffEquiv.distribMulAction _ +set_option backward.isDefEq.respectTransparency.types false in @[to_additive (dont_translate := R)] lemma single_mem_span_single [Semiring R] [Nontrivial R] {m : M} {s : Set M} : single m 1 ∈ Submodule.span R ((single · (1 : R)) '' s) ↔ m ∈ s := by diff --git a/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean b/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean index bb6018557c6049..41f4d0293ac46a 100644 --- a/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean +++ b/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean @@ -86,6 +86,7 @@ theorem coeff_mul_mul_of_uniqueMul [Mul A] {f g : R[A]} {a0 b0 : A} @[deprecated (since := "2026-06-18")] alias mul_apply_mul_eq_mul_of_uniqueMul := coeff_mul_mul_of_uniqueMul +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := R)] instance [NoZeroDivisors R] [Mul A] [UniqueProds A] : NoZeroDivisors R[A] where eq_zero_or_eq_zero_of_mul_eq_zero {a b} hab := by diff --git a/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean b/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean index a3c2846537cd6e..cae8743aa7bb94 100644 --- a/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean +++ b/Mathlib/Algebra/MonoidAlgebra/PointwiseSMul.lean @@ -25,6 +25,7 @@ variable {G P R V : Type*} namespace MonoidAlgebra +set_option backward.isDefEq.respectTransparency.types false in @[to_additive] theorem mem_smulAntidiagonal_of_group [Group G] [MulAction G P] [Semiring R] [Zero V] (f : R[G]) (x : P → V) (p : P) (gh : G × P) : diff --git a/Mathlib/Algebra/MonoidAlgebra/Support.lean b/Mathlib/Algebra/MonoidAlgebra/Support.lean index ed19081cfeeaec..ca1beaa6f8bebb 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Support.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Support.lean @@ -56,6 +56,7 @@ theorem support_coeff_mul_single_subset [DecidableEq G] (x : k[G]) (r : k) (a : change image₂ _ _ _ ⊆ _ rw [image₂_singleton_right] +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := k) support_coeff_single_mul_eq_image] theorem support_coeff_single_mul_eq_image [DecidableEq G] (f : k[G]) {r : k} (hr : ∀ y, r * y = 0 ↔ y = 0) {x : G} (lx : IsLeftRegular x) : @@ -64,6 +65,7 @@ theorem support_coeff_single_mul_eq_image [DecidableEq G] (f : k[G]) {r : k} obtain ⟨y, yf, rfl⟩ : ∃ a ∈ f.coeff.support, x * a = y := by grind simp [coeff_mul, mem_support_iff.mp yf, hr, lx.eq_iff] +set_option backward.isDefEq.respectTransparency false in @[to_additive (dont_translate := k) support_coeff_mul_single_eq_image] theorem support_coeff_mul_single_eq_image [DecidableEq G] (f : k[G]) {r : k} (hr : ∀ y, y * r = 0 ↔ y = 0) {x : G} (rx : IsRightRegular x) : @@ -127,6 +129,7 @@ variable {k : Type u₁} {G : Type u₂} [Semiring k] section Span +set_option backward.isDefEq.respectTransparency.types false in /-- An element of `k[G]` is in the submodule generated by its support. -/ theorem mem_span_support_coeff (f : k[G]) : f ∈ Submodule.span k (of' k G '' f.coeff.support) := by simp [of', ← supported_eq_span_single, mem_supported] diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 6aee400c27610b..995bcd5ebce741 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -513,6 +513,7 @@ section Coeff def coeff (m : σ →₀ ℕ) (p : MvPolynomial σ R) : R := @DFunLike.coe ((σ →₀ ℕ) →₀ R) _ _ _ (AddMonoidAlgebra.coeff p) m +set_option backward.isDefEq.respectTransparency false in @[simp, grind =] theorem mem_support_iff {p : MvPolynomial σ R} {m : σ →₀ ℕ} : m ∈ p.support ↔ p.coeff m ≠ 0 := by simp [support, coeff] @@ -638,6 +639,7 @@ theorem coeff_X_same (i : σ) : coeff (Finsupp.single i 1) (X i : MvPolynomial σ R) = 1 := by classical rw [coeff_X, if_pos rfl] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem coeff_C_mul (m) (a : R) (p : MvPolynomial σ R) : coeff m (C a * p) = a * coeff m p := by classical diff --git a/Mathlib/Algebra/MvPolynomial/CommRing.lean b/Mathlib/Algebra/MvPolynomial/CommRing.lean index 3cee9c465cea2e..269611dec10106 100644 --- a/Mathlib/Algebra/MvPolynomial/CommRing.lean +++ b/Mathlib/Algebra/MvPolynomial/CommRing.lean @@ -86,6 +86,7 @@ section Degrees theorem degrees_neg (p : MvPolynomial σ R) : (-p).degrees = p.degrees := by rw [degrees, support_neg]; rfl +set_option backward.isDefEq.respectTransparency false in theorem degrees_sub_le [DecidableEq σ] {p q : MvPolynomial σ R} : (p - q).degrees ≤ p.degrees ∪ q.degrees := by simpa [degrees_def] using! AddMonoidAlgebra.supDegree_sub_le diff --git a/Mathlib/Algebra/MvPolynomial/Degrees.lean b/Mathlib/Algebra/MvPolynomial/Degrees.lean index 3d773c61174d0c..4d8ca1b2a3b18a 100644 --- a/Mathlib/Algebra/MvPolynomial/Degrees.lean +++ b/Mathlib/Algebra/MvPolynomial/Degrees.lean @@ -150,6 +150,7 @@ theorem degrees_eq_zero_iff_support_subset_zero : p.degrees = 0 ↔ p.support have := Finsupp.support_eq_empty.mpr (h s <| mem_support_iff.mpr hs1) ▸ hs2 grind +set_option backward.isDefEq.respectTransparency false in theorem le_degrees_add_left (h : Disjoint p.degrees q.degrees) : p.degrees ≤ (p + q).degrees := by classical apply Finset.sup_le diff --git a/Mathlib/Algebra/MvPolynomial/Equiv.lean b/Mathlib/Algebra/MvPolynomial/Equiv.lean index caf540ebdc0bce..40cd229bb9f00a 100644 --- a/Mathlib/Algebra/MvPolynomial/Equiv.lean +++ b/Mathlib/Algebra/MvPolynomial/Equiv.lean @@ -390,6 +390,7 @@ theorem iterToSum_C_X (c : S₂) : iterToSum R S₁ S₂ (C (X c)) = X (Sum.inr @[deprecated (since := "2026-06-18")] alias iterToSum_sumToIter := RingEquiv.symm_apply_apply @[deprecated (since := "2026-06-18")] alias sumToIter_iterToSum := RingEquiv.apply_symm_apply +set_option backward.isDefEq.respectTransparency false in /-- The algebra isomorphism between multivariable polynomials in a sum of two types, and multivariable polynomials in one of the types, with coefficients in multivariable polynomials in the other type. @@ -581,6 +582,7 @@ lemma natDegree_optionEquivLeft (p : MvPolynomial (Option σ) R) : · rw [c, map_zero, Polynomial.natDegree_zero, degreeOf_zero] · rw [Polynomial.natDegree, degree_optionEquivLeft R c, Nat.cast_withBot, WithBot.unbotD_coe] +set_option backward.isDefEq.respectTransparency false in lemma totalDegree_coeff_optionEquivLeft_add_le (p : MvPolynomial (Option S₁) R) (i : ℕ) (hi : i ≤ p.totalDegree) : ((optionEquivLeft R S₁ p).coeff i).totalDegree + i ≤ p.totalDegree := by @@ -593,6 +595,7 @@ lemma totalDegree_coeff_optionEquivLeft_add_le · simp [Finsupp.sum_add_index, Finsupp.sum_embDomain, add_comm i] · simpa [mem_support_iff, ← optionEquivLeft_coeff_some_coeff_none R S₁] using hσ +set_option backward.isDefEq.respectTransparency false in lemma totalDegree_coeff_optionEquivLeft_le (p : MvPolynomial (Option S₁) R) (i : ℕ) : ((optionEquivLeft R S₁ p).coeff i).totalDegree ≤ p.totalDegree := by diff --git a/Mathlib/Algebra/MvPolynomial/Eval.lean b/Mathlib/Algebra/MvPolynomial/Eval.lean index 46547815cf52ca..5d8c61ea7a51e3 100644 --- a/Mathlib/Algebra/MvPolynomial/Eval.lean +++ b/Mathlib/Algebra/MvPolynomial/Eval.lean @@ -223,6 +223,7 @@ theorem eval₂_eta (p : MvPolynomial σ R) : eval₂ C X p = p := by apply MvPolynomial.induction_on p <;> simp +contextual [eval₂_add, eval₂_mul] +set_option backward.isDefEq.respectTransparency false in theorem eval₂_congr (g₁ g₂ : σ → S₁) (h : ∀ {i : σ} {c : σ →₀ ℕ}, i ∈ c.support → coeff c p ≠ 0 → g₁ i = g₂ i) : p.eval₂ f g₁ = p.eval₂ f g₂ := by @@ -478,6 +479,7 @@ theorem C_dvd_iff_map_hom_eq_zero (q : R →+* S₁) (r : R) (hr : ∀ r' : R, q rw [C_dvd_iff_dvd_coeff, MvPolynomial.ext_iff] simp only [coeff_map, coeff_zero, hr] +set_option backward.isDefEq.respectTransparency false in theorem map_mapRange_eq_iff (f : R →+* S₁) (g : S₁ → R) (hg : g 0 = 0) (φ : MvPolynomial σ S₁) : map f (.ofCoeff <| Finsupp.mapRange g hg <| AddMonoidAlgebra.coeff φ) = φ ↔ ∀ d, f (g (coeff d φ)) = coeff d φ := by diff --git a/Mathlib/Algebra/MvPolynomial/Rename.lean b/Mathlib/Algebra/MvPolynomial/Rename.lean index 159560456c0fc9..7b6c1a1a887fd1 100644 --- a/Mathlib/Algebra/MvPolynomial/Rename.lean +++ b/Mathlib/Algebra/MvPolynomial/Rename.lean @@ -54,6 +54,7 @@ section Rename def rename (f : σ → τ) : MvPolynomial σ R →ₐ[R] MvPolynomial τ R := AddMonoidAlgebra.mapDomainAlgHom _ _ (mapDomain.addMonoidHom f) +set_option backward.isDefEq.respectTransparency.types false in theorem rename_C (f : σ → τ) (r : R) : rename f (C r) = C r := by unfold rename C monomial MvPolynomial; simp @@ -345,6 +346,7 @@ theorem coeff_rename_embDomain (f : σ ↪ τ) (φ : MvPolynomial σ R) (d : σ (rename f φ).coeff (d.embDomain f) = φ.coeff d := by rw [Finsupp.embDomain_eq_mapDomain f, coeff_rename_mapDomain f f.injective] +set_option backward.isDefEq.respectTransparency false in theorem coeff_rename_eq_zero (f : σ → τ) (φ : MvPolynomial σ R) (d : τ →₀ ℕ) (h : ∀ u : σ →₀ ℕ, u.mapDomain f = d → φ.coeff u = 0) : (rename f φ).coeff d = 0 := by classical diff --git a/Mathlib/Algebra/MvPolynomial/Variables.lean b/Mathlib/Algebra/MvPolynomial/Variables.lean index a832754446ea5a..0bc02c4263c284 100644 --- a/Mathlib/Algebra/MvPolynomial/Variables.lean +++ b/Mathlib/Algebra/MvPolynomial/Variables.lean @@ -236,6 +236,7 @@ section EvalVars variable [CommSemiring S] +set_option backward.isDefEq.respectTransparency false in theorem eval₂Hom_eq_constantCoeff_of_vars (f : R →+* S) {g : σ → S} {p : MvPolynomial σ R} (hp : ∀ i ∈ p.vars, g i = 0) : eval₂Hom f g p = f (constantCoeff p) := by conv_lhs => rw [p.as_sum] diff --git a/Mathlib/Algebra/Opposites.lean b/Mathlib/Algebra/Opposites.lean index b9d19e7f62af83..d92899c5359482 100644 --- a/Mathlib/Algebra/Opposites.lean +++ b/Mathlib/Algebra/Opposites.lean @@ -73,12 +73,14 @@ postfix:max "ᵃᵒᵖ" => AddOpposite namespace MulOpposite /-- The element of `MulOpposite α` that represents `x : α`. -/ -@[to_additive /-- The element of `αᵃᵒᵖ` that represents `x : α`. -/] +-- implicit-reducible so that `op_star` can be `rfl` +@[to_additive /-- The element of `αᵃᵒᵖ` that represents `x : α`. -/, implicit_reducible] def op : α → αᵐᵒᵖ := PreOpposite.op' /-- The element of `α` represented by `x : αᵐᵒᵖ`. -/ -@[to_additive (attr := pp_nodot) /-- The element of `α` represented by `x : αᵃᵒᵖ`. -/] +@[to_additive (attr := pp_nodot) /-- The element of `α` represented by `x : αᵃᵒᵖ`. -/, + implicit_reducible] -- implicit-reducible so that `op_star` can be `rfl` def unop : αᵐᵒᵖ → α := PreOpposite.unop' diff --git a/Mathlib/Algebra/Order/Antidiag/Finsupp.lean b/Mathlib/Algebra/Order/Antidiag/Finsupp.lean index 7d7efc43d009cf..418a7c2c10e81f 100644 --- a/Mathlib/Algebra/Order/Antidiag/Finsupp.lean +++ b/Mathlib/Algebra/Order/Antidiag/Finsupp.lean @@ -46,6 +46,7 @@ def finsuppAntidiag (s : Finset ι) (n : μ) : Finset (ι →₀ μ) := (piAntidiag s n).attach.map ⟨fun f ↦ ⟨s.filter (f.1 · ≠ 0), f.1, by simpa using (mem_piAntidiag.1 f.2).2⟩, fun _ _ hfg ↦ Subtype.ext (congr_arg (⇑) hfg)⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mem_finsuppAntidiag : f ∈ finsuppAntidiag s n ↔ s.sum f = n ∧ f.support ⊆ s := by simp [finsuppAntidiag, ← DFunLike.coe_fn_eq, subset_iff] @@ -88,6 +89,7 @@ theorem mem_finsuppAntidiag_insert {a : ι} {s : Finset ι} intro x hx rw [update_of_ne (ne_of_mem_of_not_mem hx h) n1 ⇑g] +set_option backward.isDefEq.respectTransparency false in theorem finsuppAntidiag_insert {a : ι} {s : Finset ι} (h : a ∉ s) (n : μ) : finsuppAntidiag (insert a s) n = (antidiagonal n).biUnion @@ -118,6 +120,7 @@ theorem finsuppAntidiag_mono {s t : Finset ι} (h : s ⊆ t) (n : μ) : variable [AddCommMonoid μ'] [HasAntidiagonal μ'] [DecidableEq μ'] +set_option backward.isDefEq.respectTransparency false in -- This should work under the assumption that e is an embedding and an AddHom lemma mapRange_finsuppAntidiag_subset {e : μ ≃+ μ'} {s : Finset ι} {n : μ} : (finsuppAntidiag s n).map (mapRange.addEquiv e).toEmbedding ⊆ finsuppAntidiag s (e n) := by diff --git a/Mathlib/Algebra/Order/Antidiag/FinsuppEquiv.lean b/Mathlib/Algebra/Order/Antidiag/FinsuppEquiv.lean index 46e04d0d7535ae..72ca953453ec21 100644 --- a/Mathlib/Algebra/Order/Antidiag/FinsuppEquiv.lean +++ b/Mathlib/Algebra/Order/Antidiag/FinsuppEquiv.lean @@ -37,6 +37,7 @@ namespace Finset variable [DecidableEq ι] [AddCommMonoid μ] [HasAntidiagonal μ] [DecidableEq μ] {s : Finset ι} {n : μ} +set_option backward.isDefEq.respectTransparency false in variable (s n) in /-- The equivalence between `Finset.finsuppAntidiag s n` and the subtype of `s →₀ μ` whose sum is `n`. -/ diff --git a/Mathlib/Algebra/Order/Antidiag/Nat.lean b/Mathlib/Algebra/Order/Antidiag/Nat.lean index 0aa55fa23256da..e0079f66298e3c 100644 --- a/Mathlib/Algebra/Order/Antidiag/Nat.lean +++ b/Mathlib/Algebra/Order/Antidiag/Nat.lean @@ -29,6 +29,7 @@ open Finset open scoped ArithmeticFunction namespace PNat +set_option backward.isDefEq.respectTransparency false in instance instHasAntidiagonal : Finset.HasAntidiagonal (Additive ℕ+) := /- The set of divisors of a positive natural number. This is `Nat.divisorsAntidiagonal` without a special case for `n = 0`. -/ @@ -60,6 +61,7 @@ def finMulAntidiag (d : ℕ) (n : ℕ) : Finset (Fin d → ℕ) := else ∅ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mem_finMulAntidiag {d n : ℕ} {f : Fin d → ℕ} : f ∈ finMulAntidiag d n ↔ ∏ i, f i = n ∧ n ≠ 0 := by diff --git a/Mathlib/Algebra/Order/Antidiag/Pi.lean b/Mathlib/Algebra/Order/Antidiag/Pi.lean index 9202ca123bbffc..ce8416da368259 100644 --- a/Mathlib/Algebra/Order/Antidiag/Pi.lean +++ b/Mathlib/Algebra/Order/Antidiag/Pi.lean @@ -58,6 +58,7 @@ In this section, we define the antidiagonals in `Fin d → μ` by recursion on ` computationally efficient, although probably not as efficient as `Finset.Nat.antidiagonalTuple`. -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary construction for `finAntidiagonal` that bundles a proof of lawfulness (`mem_finAntidiagonal`), as this is needed to invoke `disjiUnion`. Using `Finset.disjiUnion` makes this computationally much more efficient than using `Finset.biUnion`. -/ @@ -91,6 +92,7 @@ def finAntidiagonal.aux (d : ℕ) (n : μ) : {s : Finset (Fin d → μ) // ∀ f · intro hf exact ⟨_, _, hf, _, rfl, Fin.cons_self_tail f⟩ } +set_option backward.isDefEq.respectTransparency false in /-- `finAntidiagonal d n` is the type of `d`-tuples with sum `n`. TODO: deduplicate with the less general `Finset.Nat.antidiagonalTuple`. -/ @@ -107,6 +109,7 @@ choosing an identification `s ≃ Fin s.card` and proving that the end result do choice. -/ +set_option backward.isDefEq.respectTransparency false in /-- The finset of functions `ι → μ` with support contained in `s` and sum `n`. -/ def piAntidiag (s : Finset ι) (n : μ) : Finset (ι → μ) := by refine (Fintype.truncEquivFinOfCardEq <| Fintype.card_coe s).lift @@ -123,6 +126,7 @@ def piAntidiag (s : Finset ι) (n : μ) : Finset (ι → μ) := by variable {s : Finset ι} {n : μ} {f : ι → μ} +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mem_piAntidiag : f ∈ piAntidiag s n ↔ s.sum f = n ∧ ∀ i, f i ≠ 0 → i ∈ s := by rw [piAntidiag] induction Fintype.truncEquivFinOfCardEq (Fintype.card_coe s) using Trunc.ind with | _ e diff --git a/Mathlib/Algebra/Order/Antidiag/Prod.lean b/Mathlib/Algebra/Order/Antidiag/Prod.lean index 398a5813e4bc4f..20680f96467c52 100644 --- a/Mathlib/Algebra/Order/Antidiag/Prod.lean +++ b/Mathlib/Algebra/Order/Antidiag/Prod.lean @@ -270,6 +270,7 @@ open Multiplicative variable {A : Type*} [AddMonoid A] [HasAntidiagonal A] +set_option backward.isDefEq.respectTransparency.types false in instance : HasMulAntidiagonal (Multiplicative A) where mulAntidiagonal a := (antidiagonal (toAdd a)).map ⟨fun p ↦ (ofAdd p.1 , ofAdd p.2), fun _ _ h ↦ by aesop⟩ diff --git a/Mathlib/Algebra/Order/Archimedean/Basic.lean b/Mathlib/Algebra/Order/Archimedean/Basic.lean index 5190122bf7cc2b..739a8386bdac7f 100644 --- a/Mathlib/Algebra/Order/Archimedean/Basic.lean +++ b/Mathlib/Algebra/Order/Archimedean/Basic.lean @@ -475,7 +475,7 @@ instance : MulArchimedean NNRat := Nonneg.instMulArchimedean /-- A linear ordered archimedean ring is a floor ring. This is not an `instance` because in some cases we have a computable `floor` function. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Archimedean.floorRing (R) [Ring R] [LinearOrder R] [IsStrictOrderedRing R] [Archimedean R] : FloorRing R := .ofBounded _ exists_nat_ge diff --git a/Mathlib/Algebra/Order/Archimedean/Class.lean b/Mathlib/Algebra/Order/Archimedean/Class.lean index 11d484e082362b..458356b380fd2e 100644 --- a/Mathlib/Algebra/Order/Archimedean/Class.lean +++ b/Mathlib/Algebra/Order/Archimedean/Class.lean @@ -864,6 +864,7 @@ theorem subsemigroup_eq_subgroup : MulArchimedeanClass.subsemigroup (toUpperSetMulArchimedeanClass s) = (subgroup s : Set M) := rfl +set_option backward.isDefEq.respectTransparency false in variable (M) in @[to_additive (attr := simp)] theorem subgroup_eq_bot : subgroup (M := M) ⊤ = ⊥ := by diff --git a/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean b/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean index 01e9559229ffbb..0ccb893cdef688 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean @@ -125,6 +125,7 @@ lemma prod_prod_Ioi_mul_eq_prod_prod_off_diag (f : α → α → M) : end LinearOrder +set_option backward.isDefEq.respectTransparency false in /-- Given a sequence of finite sets `s₀ ⊆ s₁ ⊆ s₂ ⋯`, the product of `gᵢ` over `i ∈ sₙ` is equal to `∏_{i ∈ s₀} gᵢ` * `∏_{j < n, i ∈ sⱼ₊₁ \ sⱼ} gᵢ`. -/ @[to_additive /-- Given a sequence of finite sets `s₀ ⊆ s₁ ⊆ s₂ ⋯`, the sum of `gᵢ` over `i ∈ sₙ` is diff --git a/Mathlib/Algebra/Order/CompleteField.lean b/Mathlib/Algebra/Order/CompleteField.lean index e0515d95472fab..f576610e5cf93b 100644 --- a/Mathlib/Algebra/Order/CompleteField.lean +++ b/Mathlib/Algebra/Order/CompleteField.lean @@ -279,6 +279,7 @@ def inducedOrderRingHom : α →+*o β := two_ne_zero (inducedMap_one _ _) with monotone' := inducedMap_mono _ _ } +set_option backward.isDefEq.respectTransparency false in /-- The isomorphism of ordered rings between two conditionally complete linearly ordered fields. -/ def inducedOrderRingIso : β ≃+*o γ := { inducedOrderRingHom β γ with diff --git a/Mathlib/Algebra/Order/Floor/Defs.lean b/Mathlib/Algebra/Order/Floor/Defs.lean index 8e1e7c083be6a1..1b56a36497d868 100644 --- a/Mathlib/Algebra/Order/Floor/Defs.lean +++ b/Mathlib/Algebra/Order/Floor/Defs.lean @@ -190,7 +190,7 @@ instance : FloorRing ℤ where rw [Int.cast_id, id_def] /-- A `FloorRing` constructor from the `floor` function alone. -/ -@[implicit_reducible] +@[instance_reducible] def FloorRing.ofFloor (α) [Ring α] [LinearOrder α] [IsOrderedRing α] (floor : α → ℤ) (gc_coe_floor : GaloisConnection (↑) floor) : FloorRing α := { floor @@ -199,7 +199,7 @@ def FloorRing.ofFloor (α) [Ring α] [LinearOrder α] [IsOrderedRing α] (floor gc_ceil_coe := fun a z => by rw [neg_le, ← gc_coe_floor, Int.cast_neg, neg_le_neg_iff] } /-- A `FloorRing` constructor from the `ceil` function alone. -/ -@[implicit_reducible] +@[instance_reducible] def FloorRing.ofCeil (α) [Ring α] [LinearOrder α] [IsOrderedRing α] (ceil : α → ℤ) (gc_ceil_coe : GaloisConnection ceil (↑)) : FloorRing α := { floor := fun a => -ceil (-a) @@ -228,7 +228,7 @@ theorem exists_floor' /-- Construct a `FloorRing` instance noncomputably, from the hypothesis that every element is bounded above by a natural number. -/ -@[no_expose, implicit_reducible] +@[no_expose, instance_reducible] noncomputable def FloorRing.ofBounded (α) [Ring α] [LinearOrder α] [IsOrderedRing α] [Nontrivial α] (bounded : ∀ x : α, ∃ n : ℕ, x ≤ n) : FloorRing α := diff --git a/Mathlib/Algebra/Order/Group/Lattice.lean b/Mathlib/Algebra/Order/Group/Lattice.lean index 58d100aebc7618..0bbd1acea016ee 100644 --- a/Mathlib/Algebra/Order/Group/Lattice.lean +++ b/Mathlib/Algebra/Order/Group/Lattice.lean @@ -119,7 +119,7 @@ lemma inf_mul_sup [MulLeftMono α] (a b : α) : (a ⊓ b) * (a ⊔ b) = a * b := /-- Every lattice ordered commutative group is a distributive lattice. -/ -- Non-comm case needs cancellation law https://ncatlab.org/nlab/show/distributive+lattice -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Every lattice ordered commutative additive group is a distributive lattice -/] def CommGroup.toDistribLattice (α : Type*) [Lattice α] [CommGroup α] [MulLeftMono α] : DistribLattice α where diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 4048f880d6cd9e..5928ae2e20b0ff 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -98,6 +98,7 @@ instance instLinearOrderedAddCommMonoidWithTopAdditiveOrderDual : top_add' a := by ext; simp [bot_eq_zero] isAddLeftRegular_of_ne_top := by simp +contextual [IsRegular.of_ne_zero, bot_eq_zero] +set_option backward.isDefEq.respectTransparency false in instance instLinearOrderedAddCommMonoidWithTopOrderDualAdditive : LinearOrderedAddCommMonoidWithTop (Additive α)ᵒᵈ where top_add' a := by ext; simp; simp [bot_eq_zero (α := α)] diff --git a/Mathlib/Algebra/Order/GroupWithZero/Lex.lean b/Mathlib/Algebra/Order/GroupWithZero/Lex.lean index 269634aa201b2a..a63642708b5da3 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Lex.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Lex.lean @@ -34,6 +34,7 @@ namespace MonoidWithZeroHom variable {M₀ N₀ : Type*} +set_option backward.isDefEq.respectTransparency false in lemma inl_mono [LinearOrderedCommGroupWithZero M₀] [GroupWithZero N₀] [Preorder N₀] [DecidablePred fun x : M₀ ↦ x = 0] : Monotone (inl M₀ N₀) := by refine (WithZero.map'_mono MonoidHom.inl_mono).comp ?_ @@ -46,6 +47,7 @@ lemma inl_strictMono [LinearOrderedCommGroupWithZero M₀] [GroupWithZero N₀] [DecidablePred fun x : M₀ ↦ x = 0] : StrictMono (inl M₀ N₀) := inl_mono.strictMono_of_injective inl_injective +set_option backward.isDefEq.respectTransparency false in lemma inr_mono [GroupWithZero M₀] [Preorder M₀] [LinearOrderedCommGroupWithZero N₀] [DecidablePred fun x : N₀ ↦ x = 0] : Monotone (inr M₀ N₀) := by refine (WithZero.map'_mono MonoidHom.inr_mono).comp ?_ @@ -77,6 +79,9 @@ variable (α β : Type*) [LinearOrderedCommGroupWithZero α] [LinearOrderedCommG open MonoidWithZeroHom +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given linearly ordered groups with zero M, N, the natural inclusion ordered homomorphism from M to `WithZero (Mˣ ×ₗ Nˣ)`, which is the linearly ordered group with zero that can be identified as their product. -/ @@ -85,6 +90,9 @@ nonrec def inl : α →*₀o WithZero (αˣ ×ₗ βˣ) where __ := (WithZero.map' (toLexMulEquiv ..).toMonoidHom).comp (inl α β) monotone' := by simpa using (WithZero.map'_mono (Prod.Lex.toLex_mono)).comp inl_mono +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given linearly ordered groups with zero M, N, the natural inclusion ordered homomorphism from N to `WithZero (Mˣ ×ₗ Nˣ)`, which is the linearly ordered group with zero that can be identified as their product. -/ @@ -93,6 +101,7 @@ nonrec def inr : β →*₀o WithZero (αˣ ×ₗ βˣ) where __ := (WithZero.map' (toLexMulEquiv ..).toMonoidHom).comp (inr α β) monotone' := by simpa using (WithZero.map'_mono (Prod.Lex.toLex_mono)).comp inr_mono +set_option backward.isDefEq.respectTransparency.types false in /-- Given linearly ordered groups with zero M, N, the natural projection ordered homomorphism from `WithZero (Mˣ ×ₗ Nˣ)` to M, which is the linearly ordered group with zero that can be identified as their product. -/ @@ -109,6 +118,7 @@ nonrec def fst : WithZero (αˣ ×ₗ βˣ) →*₀o α where · simp · simpa using Prod.Lex.monotone_fst _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem fst_comp_inl : (fst _ _).comp (inl α β) = .id α := by ext x @@ -117,11 +127,13 @@ theorem fst_comp_inl : (fst _ _).comp (inl α β) = .id α := by variable {α β} +set_option backward.isDefEq.respectTransparency false in lemma inl_eq_coe_inlₗ {m : α} (hm : m ≠ 0) : inl α β m = OrderMonoidHom.inlₗ αˣ βˣ (Units.mk0 _ hm) := by lift m to αˣ using isUnit_iff_ne_zero.mpr hm simp +set_option backward.isDefEq.respectTransparency false in lemma inr_eq_coe_inrₗ {n : β} (hn : n ≠ 0) : inr α β n = OrderMonoidHom.inrₗ αˣ βˣ (Units.mk0 _ hn) := by lift n to βˣ using isUnit_iff_ne_zero.mpr hn diff --git a/Mathlib/Algebra/Order/Hom/MonoidWithZero.lean b/Mathlib/Algebra/Order/Hom/MonoidWithZero.lean index a9d8bb03ff4868..13aec3c3e85ba0 100644 --- a/Mathlib/Algebra/Order/Hom/MonoidWithZero.lean +++ b/Mathlib/Algebra/Order/Hom/MonoidWithZero.lean @@ -269,6 +269,7 @@ end LinearOrderedCommMonoidWithZero end OrderMonoidWithZeroHom +set_option backward.isDefEq.respectTransparency false in /-- Any ordered group is isomorphic to the units of itself adjoined with `0`. -/ @[simps! -isSimp] def OrderMonoidIso.unitsWithZero {α : Type*} [Group α] [Preorder α] : (WithZero α)ˣ ≃*o α where diff --git a/Mathlib/Algebra/Order/Interval/Basic.lean b/Mathlib/Algebra/Order/Interval/Basic.lean index b833e2ff856d15..df0af1a9951de5 100644 --- a/Mathlib/Algebra/Order/Interval/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Basic.lean @@ -227,6 +227,7 @@ instance commMonoid [CommMonoid α] [Preorder α] [IsOrderedMonoid α] : end NonemptyInterval +set_option backward.isDefEq.respectTransparency false in @[to_additive] instance Interval.mulOneClass [CommMonoid α] [Preorder α] [IsOrderedMonoid α] : MulOneClass (Interval α) where diff --git a/Mathlib/Algebra/Order/IsBotOne.lean b/Mathlib/Algebra/Order/IsBotOne.lean index 359bc0f3efe45d..71ddfa91212a9a 100644 --- a/Mathlib/Algebra/Order/IsBotOne.lean +++ b/Mathlib/Algebra/Order/IsBotOne.lean @@ -43,7 +43,7 @@ alias zero_le' := zero_le variable (α) in /-- Create an `OrderBot` instance, setting `1` as the bottom element. -/ -@[expose, to_additive (attr := implicit_reducible) +@[expose, to_additive (attr := instance_reducible) /-- Create an `OrderBot` instance, setting `0` as the bottom element. -/] def IsBotOneClass.toOrderBot : OrderBot α where bot := 1 diff --git a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean index 8a775ef6df973c..e29d0b34cead58 100644 --- a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean +++ b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean @@ -209,6 +209,7 @@ theorem hahnCoeff_apply {x : seed.baseDomain} {f : Π₀ c, seed.stratum c} let f' : ⨁ c, seed.stratum' c := f.mapRange (fun c x ↦ (⟨⟨x.val, hxm x⟩, by simp⟩ : seed.stratum' c)) (by simp) have hf : f c = (seed.baseDomain.subtype.submoduleComap (seed.stratum c)) (f' c) := by + set_option backward.isDefEq.respectTransparency false in apply Subtype.ext simp [f'] have hx : x = (decompose seed.stratum').symm f' := by diff --git a/Mathlib/Algebra/Order/Monoid/LocallyFiniteOrder.lean b/Mathlib/Algebra/Order/Monoid/LocallyFiniteOrder.lean index 0675be29429bd3..23c39c9066ab88 100644 --- a/Mathlib/Algebra/Order/Monoid/LocallyFiniteOrder.lean +++ b/Mathlib/Algebra/Order/Monoid/LocallyFiniteOrder.lean @@ -164,6 +164,7 @@ def LocallyFiniteOrder.orderAddMonoidEquiv [Nontrivial G] : lemma LocallyFiniteOrder.orderAddMonoidEquiv_apply [Nontrivial G] (x : G) : orderAddMonoidEquiv G x = addMonoidHom G x := rfl +set_option backward.isDefEq.respectTransparency false in /-- Any linearly ordered abelian group that is locally finite embeds to `Multiplicative ℤ`. -/ noncomputable def LocallyFiniteOrder.orderMonoidEquiv (G : Type*) [CommGroup G] [LinearOrder G] @@ -172,6 +173,7 @@ def LocallyFiniteOrder.orderMonoidEquiv (G : Type*) [CommGroup G] [LinearOrder G have : LocallyFiniteOrder (Additive G) := ‹LocallyFiniteOrder G› (orderAddMonoidEquiv (Additive G)).toMultiplicative +set_option backward.isDefEq.respectTransparency false in /-- Any linearly ordered abelian group that is locally finite embeds into `Multiplicative ℤ`. -/ noncomputable def LocallyFiniteOrder.orderMonoidHom (G : Type*) [CommGroup G] [LinearOrder G] @@ -180,6 +182,7 @@ def LocallyFiniteOrder.orderMonoidHom (G : Type*) [CommGroup G] [LinearOrder G] have : LocallyFiniteOrder (Additive G) := ‹LocallyFiniteOrder G› ⟨(orderAddMonoidHom (Additive G)).toMultiplicative, (orderAddMonoidHom (Additive G)).2⟩ +set_option backward.isDefEq.respectTransparency false in lemma LocallyFiniteOrder.orderMonoidHom_strictMono {G : Type*} [CommGroup G] [LinearOrder G] [IsOrderedMonoid G] [LocallyFiniteOrder G] : StrictMono (orderMonoidHom G) := diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean index 7963b58bc4777b..8879ea063dc1d4 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean @@ -1133,7 +1133,7 @@ variable [PartialOrder α] to the appropriate covariant class. -/ /-- A semigroup with a partial order and satisfying `LeftCancelSemigroup` (i.e. `a * c < b * c → a < b`) is a `LeftCancelSemigroup`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive semigroup with a partial order and satisfying `AddLeftCancelSemigroup` (i.e. `c + a < c + b → a < b`) is a `AddLeftCancelSemigroup`. -/] def Contravariant.toLeftCancelSemigroup [MulLeftReflectLE α] : LeftCancelSemigroup α where @@ -1142,7 +1142,7 @@ def Contravariant.toLeftCancelSemigroup [MulLeftReflectLE α] : LeftCancelSemigr to the appropriate covariant class. -/ /-- A semigroup with a partial order and satisfying `RightCancelSemigroup` (i.e. `a * c < b * c → a < b`) is a `RightCancelSemigroup`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive semigroup with a partial order and satisfying `AddRightCancelSemigroup` (`a + c < b + c → a < b`) is a `AddRightCancelSemigroup`. -/] def Contravariant.toRightCancelSemigroup [MulRightReflectLE α] : RightCancelSemigroup α where diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean index 54a80da3c58f50..40a49218ad1d4b 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/WithTop.lean @@ -131,6 +131,7 @@ lemma _root_.IsAddRightRegular.withTop (ha : IsAddRightRegular a) : IsAddRightRegular (a : WithTop α) := by rintro (_ | b) (_ | c) <;> simp [none_eq_top, some_eq_coe, ← coe_add, ha.eq_iff] +set_option backward.isDefEq.respectTransparency false in lemma _root_.AddLECancellable.withTop [LE α] (ha : AddLECancellable a) : AddLECancellable (a : WithTop α) := by rintro (_ | b) (_ | c) @@ -491,6 +492,7 @@ lemma _root_.IsAddRightRegular.withBot (ha : IsAddRightRegular a) : IsAddRightRegular (a : WithBot α) := by rintro (_ | b) (_ | c) <;> simp [none_eq_bot, some_eq_coe, ← coe_add]; simpa using @ha _ _ +set_option backward.isDefEq.respectTransparency false in lemma _root_.AddLECancellable.withBot [LE α] (ha : AddLECancellable a) : AddLECancellable (a : WithBot α) := by rintro (_ | b) (_ | c) diff --git a/Mathlib/Algebra/Order/Ring/StandardPart.lean b/Mathlib/Algebra/Order/Ring/StandardPart.lean index 05134d3e6ccbc5..9d20ef772f8284 100644 --- a/Mathlib/Algebra/Order/Ring/StandardPart.lean +++ b/Mathlib/Algebra/Order/Ring/StandardPart.lean @@ -116,6 +116,7 @@ instance : FloorRing (FiniteElement K) := end FiniteElement +set_option backward.isDefEq.respectTransparency.types false in variable (K) in /-- The residue field of `FiniteElement`. This quotient inherits an order from `K`, which makes it into a linearly ordered Archimedean field. -/ @@ -125,6 +126,7 @@ deriving Field namespace FiniteResidueField +set_option backward.isDefEq.respectTransparency.types false in instance ordConnected_preimage_mk' : ∀ x, Set.OrdConnected <| Quotient.mk (Submodule.quotientRel (IsLocalRing.maximalIdeal (FiniteElement K))) ⁻¹' {x} := by refine fun x ↦ ⟨?_⟩ @@ -134,21 +136,25 @@ instance ordConnected_preimage_mk' : ∀ x, Set.OrdConnected <| Quotient.mk IsLocalRing.mem_maximalIdeal, mem_nonunits_iff, FiniteElement.not_isUnit_iff_mk_pos] at hy ⊢ apply hy.trans_le (mk_antitoneOn _ _ _) <;> simpa +set_option backward.isDefEq.respectTransparency.types false in instance : LinearOrder (FiniteResidueField K) := haveI := Classical.decRel fun x y : FiniteElement K ↦ letI := Submodule.quotientRel (IsLocalRing.maximalIdeal (FiniteElement K)) x ≈ y inferInstanceAs <| LinearOrder (Quotient _) +set_option backward.isDefEq.respectTransparency.types false in /-- The quotient map from finite elements on the field to the associated residue field. -/ def mk : FiniteElement K →+*o FiniteResidueField K where monotone' _ _ h := Quotient.mk_monotone h __ := IsLocalRing.residue (FiniteElement K) +set_option backward.isDefEq.respectTransparency.types false in @[induction_eliminator] theorem ind {motive : FiniteResidueField K → Prop} (mk : ∀ x, motive (mk x)) : ∀ x, motive x := Quotient.ind mk +set_option backward.isDefEq.respectTransparency.types false in instance ordConnected_preimage_mk : ∀ x, Set.OrdConnected (mk ⁻¹' ({x} : Set (FiniteResidueField K))) := ordConnected_preimage_mk' @@ -163,22 +169,27 @@ theorem mk_eq_zero {x : FiniteElement K} : mk x = 0 ↔ 0 < ArchimedeanClass.mk apply mk_eq_mk.trans simp +set_option backward.isDefEq.respectTransparency.types false in theorem mk_ne_zero {x : FiniteElement K} : mk x ≠ 0 ↔ ArchimedeanClass.mk x.1 = 0 := by rw [ne_eq, mk_eq_zero, not_lt, x.2.ge_iff_eq'] +set_option backward.isDefEq.respectTransparency.types false in theorem mk_le_mk {x y : FiniteElement K} : mk x ≤ mk y ↔ x ≤ y ∨ mk x = mk y := by refine (Quotient.mk_le_mk (H := ordConnected_preimage_mk')).trans ?_ rw [← Quotient.eq_iff_equiv] rfl +set_option backward.isDefEq.respectTransparency.types false in theorem mk_lt_mk {x y : FiniteElement K} : mk x < mk y ↔ x < y ∧ mk x ≠ mk y := by refine (Quotient.mk_lt_mk (H := ordConnected_preimage_mk')).trans ?_ rw [← Quotient.eq_iff_equiv] rfl +set_option backward.isDefEq.respectTransparency.types false in theorem lt_of_mk_lt_mk {x y : FiniteElement K} (h : mk x < mk y) : x < y := (mk_lt_mk.1 h).1 +set_option backward.isDefEq.respectTransparency.types false in private theorem mul_le_mul_of_nonneg_left' {x y z : FiniteResidueField K} (h : x ≤ y) (hz : 0 ≤ z) : z * x ≤ z * y := by induction x with | mk x @@ -189,6 +200,7 @@ private theorem mul_le_mul_of_nonneg_left' {x y z : FiniteResidueField K} (h : x rw [mk_le_mk] at h hz ⊢ grind [mul_le_mul_of_nonneg_left] +set_option backward.isDefEq.respectTransparency.types false in instance : IsOrderedRing (FiniteResidueField K) where zero_le_one := mk.monotone' zero_le_one add_le_add_left x y h z := by @@ -203,6 +215,7 @@ instance : IsOrderedRing (FiniteResidueField K) where simp_rw [mul_comm _ x] exact mul_le_mul_of_nonneg_left' h hx +set_option backward.isDefEq.respectTransparency.types false in instance : Archimedean (FiniteResidueField K) where arch x y hy := by induction x with | mk x @@ -217,6 +230,7 @@ instance : Archimedean (FiniteResidueField K) where · exact abs_of_pos <| lt_of_mk_lt_mk hx · exact abs_of_pos <| lt_of_mk_lt_mk hy +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mk_ratCast (q : ℚ) : mk (q : FiniteElement K) = q := by change mk (FiniteElement.mk ..) = _ @@ -225,6 +239,7 @@ theorem mk_ratCast (q : ℚ) : mk (q : FiniteElement K) = q := by ← FiniteElement.mk_natCast, FiniteElement.mk_mul_mk] simp_all +set_option backward.isDefEq.respectTransparency.types false in /-- An embedding from an Archimedean field into `K` induces an embedding into `FiniteResidueField K`. -/ def ofArchimedean (f : R →+*o K) : R →+*o FiniteResidueField K where @@ -252,6 +267,7 @@ theorem ofArchimedean_injective (f : R →+*o K) : Function.Injective (ofArchime rw [ofArchimedean_apply, mk_ne_zero] exact mk_map_of_archimedean' f hr +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem ofArchimedean_inj (f : R →+*o K) {x y : R} : ofArchimedean f x = ofArchimedean f y ↔ x = y := @@ -261,6 +277,7 @@ end FiniteResidueField /-! ### Standard part -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The standard part of a `FiniteElement` is the unique real number with an infinitesimal difference. @@ -270,12 +287,14 @@ def stdPart (x : K) : ℝ := if h : 0 ≤ mk x then OrderRingHom.comp Classical.ofNonempty FiniteResidueField.mk (.mk x h) else 0 +set_option backward.isDefEq.respectTransparency.types false in theorem stdPart_of_mk_nonneg (f : FiniteResidueField K →+*o ℝ) (h : 0 ≤ mk x) : stdPart x = f (.mk <| .mk x h) := by rw [stdPart, dif_pos h, OrderRingHom.comp_apply] congr exact Subsingleton.allEq _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem stdPart_eq_zero {x : K} : stdPart x = 0 ↔ mk x ≠ 0 where mpr h := by @@ -362,6 +381,7 @@ theorem stdPart_div (hx : 0 ≤ mk x) (hy : 0 ≤ -mk y) : rw [div_eq_mul_inv, div_eq_mul_inv, stdPart_mul hx, stdPart_inv] rwa [mk_inv] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem stdPart_ratCast (q : ℚ) : stdPart (q : K) = q := by rw [stdPart_of_mk_nonneg Classical.ofNonempty (mk_ratCast_nonneg q), FiniteElement.mk_ratCast, @@ -388,6 +408,7 @@ theorem stdPart_map_real (f : ℝ →+*o K) (r : ℝ) : stdPart (f r) = r := by theorem stdPart_real (r : ℝ) : stdPart r = r := stdPart_map_real (.id ℝ) r +set_option backward.isDefEq.respectTransparency.types false in theorem ofArchimedean_stdPart (f : ℝ →+*o K) (hx : 0 ≤ mk x) : FiniteResidueField.ofArchimedean f (stdPart x) = .mk (.mk x hx) := by rw [stdPart, dif_pos hx, ← OrderRingHom.comp_apply, ← OrderRingHom.comp_assoc, diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index 851f328b8ec85e..115ba3c369fd51 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -496,6 +496,7 @@ theorem X_ne_C [Nontrivial R] (a : R) : X ≠ C a := by intro he simpa using monomial_eq_monomial_iff.1 he +set_option backward.isDefEq.respectTransparency false in /-- `X` commutes with everything, even when the coefficients are noncommutative. -/ theorem X_mul : X * p = p * X := by rcases p with ⟨⟩ @@ -618,6 +619,7 @@ theorem coeff_X : coeff (X : R[X]) n = if 1 = n then 1 else 0 := theorem coeff_X_of_ne_one {n : ℕ} (hn : n ≠ 1) : coeff (X : R[X]) n = 0 := by rw [coeff_X, if_neg hn.symm] +set_option backward.isDefEq.respectTransparency false in @[simp, grind =] theorem mem_support_iff : n ∈ p.support ↔ p.coeff n ≠ 0 := by rcases p with ⟨⟩ @@ -697,6 +699,7 @@ theorem Nontrivial.of_polynomial_ne (h : p ≠ q) : Nontrivial R := theorem forall_eq_iff_forall_eq : (∀ f g : R[X], f = g) ↔ ∀ a b : R, a = b := by simpa only [← subsingleton_iff] using subsingleton_iff_subsingleton +set_option backward.isDefEq.respectTransparency false in theorem ext_iff {p q : R[X]} : p = q ↔ ∀ n, coeff p n = coeff q n := by rcases p with ⟨f⟩ rcases q with ⟨g⟩ @@ -962,6 +965,7 @@ theorem ofFinsupp_erase (p : R[ℕ]) (n : ℕ) : (⟨p.erase n⟩ : R[X]) = (⟨p⟩ : R[X]).erase n := by simp only [erase_def] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem support_erase (p : R[X]) (n : ℕ) : support (p.erase n) = (support p).erase n := by simp [support] @@ -1000,6 +1004,7 @@ If `p.natDegree < n` and `a ≠ 0`, this increases the degree to `n`. -/ def update (p : R[X]) (n : ℕ) (a : R) : R[X] := Polynomial.ofFinsupp (p.toFinsupp.update n a) +set_option backward.isDefEq.respectTransparency false in theorem coeff_update (p : R[X]) (n : ℕ) (a : R) : (p.update n a).coeff = Function.update p.coeff n a := by ext; simp [coeff, update] @@ -1019,6 +1024,7 @@ theorem update_zero_eq_erase (p : R[X]) (n : ℕ) : p.update n 0 = p.erase n := ext rw [coeff_update_apply, coeff_erase] +set_option backward.isDefEq.respectTransparency false in theorem support_update (p : R[X]) (n : ℕ) (a : R) [Decidable (a = 0)] : support (p.update n a) = if a = 0 then p.support.erase n else insert n p.support := by classical simp [support, update, Finsupp.support_update] diff --git a/Mathlib/Algebra/Polynomial/BigOperators.lean b/Mathlib/Algebra/Polynomial/BigOperators.lean index a8ccdda0b743dd..a95597b181e5cf 100644 --- a/Mathlib/Algebra/Polynomial/BigOperators.lean +++ b/Mathlib/Algebra/Polynomial/BigOperators.lean @@ -66,6 +66,7 @@ lemma natDegree_sum_le_of_forall_le {n : ℕ} (f : ι → S[X]) (h : ∀ i ∈ s natDegree (∑ i ∈ s, f i) ≤ n := le_trans (natDegree_sum_le s f) <| (Finset.fold_max_le n).mpr <| by simpa +set_option backward.isDefEq.respectTransparency false in /-- The leading coefficient of a sum of polynomials with the same degree is the sum of the leading coefficients, provided that this sum is nonzero. -/ @@ -393,6 +394,7 @@ the sum of the degrees, where the degree of the zero polynomial is ⊥. theorem degree_prod [Nontrivial R] : (∏ i ∈ s, f i).degree = ∑ i ∈ s, (f i).degree := map_prod (@degreeMonoidHom R _ _ _) _ _ +set_option backward.isDefEq.respectTransparency false in /-- The leading coefficient of a product of polynomials is equal to the product of the leading coefficients. diff --git a/Mathlib/Algebra/Polynomial/Bivariate.lean b/Mathlib/Algebra/Polynomial/Bivariate.lean index a35b0764363c25..33d87021a86a41 100644 --- a/Mathlib/Algebra/Polynomial/Bivariate.lean +++ b/Mathlib/Algebra/Polynomial/Bivariate.lean @@ -234,6 +234,7 @@ abbrev aevalAeval (x y : A) : R[X][Y] →ₐ[R] A := lemma aevalAevalEquiv_apply (xy : A × A) : aevalAevalEquiv R A xy = aevalAeval xy.1 xy.2 := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem coe_aevalAeval_eq_evalEval (x y : A) : ⇑(aevalAeval x y) = evalEval x y := by ext simp [aeval, aevalEquiv] diff --git a/Mathlib/Algebra/Polynomial/Coeff.lean b/Mathlib/Algebra/Polynomial/Coeff.lean index b098d6d5f05c6d..084d9feb1abc0a 100644 --- a/Mathlib/Algebra/Polynomial/Coeff.lean +++ b/Mathlib/Algebra/Polynomial/Coeff.lean @@ -64,6 +64,7 @@ theorem card_support_mul_le : #(p * q).support ≤ #p.support * #q.support := by grw [AddMonoidAlgebra.support_coeff_mul_subset] _ ≤ #p.support * #q.support := Finset.card_image₂_le .. +set_option backward.isDefEq.respectTransparency false in /-- `Polynomial.sum` as a linear map. -/ @[simps] def lsum {R A M : Type*} [Semiring R] [Semiring A] [AddCommMonoid M] [Module R A] [Module R M] @@ -117,6 +118,7 @@ theorem coeff_mul (p q : R[X]) (n : ℕ) : @[simp] theorem mul_coeff_zero (p q : R[X]) : coeff (p * q) 0 = coeff p 0 * coeff q 0 := by simp [coeff_mul] +set_option backward.isDefEq.respectTransparency false in theorem mul_coeff_one (p q : R[X]) : coeff (p * q) 1 = coeff p 0 * coeff q 1 + coeff p 1 * coeff q 0 := by rw [coeff_mul, Nat.antidiagonal_eq_map] diff --git a/Mathlib/Algebra/Polynomial/Degree/Defs.lean b/Mathlib/Algebra/Polynomial/Degree/Defs.lean index 6d775d7dbf5d86..3279fb019fd69d 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Defs.lean @@ -365,6 +365,7 @@ theorem leadingCoeff_eq_zero_iff_deg_eq_bot : leadingCoeff p = 0 ↔ degree p = theorem natDegree_C_mul_X_pow_le (a : R) (n : ℕ) : natDegree (C a * X ^ n) ≤ n := natDegree_le_iff_degree_le.2 <| degree_C_mul_X_pow_le _ _ +set_option backward.isDefEq.respectTransparency false in theorem degree_erase_le (p : R[X]) (n : ℕ) : degree (p.erase n) ≤ degree p := by apply sup_mono simpa using Finset.erase_subset .. diff --git a/Mathlib/Algebra/Polynomial/Derivation.lean b/Mathlib/Algebra/Polynomial/Derivation.lean index 86479cb9a7a556..41dbee4c2422d5 100644 --- a/Mathlib/Algebra/Polynomial/Derivation.lean +++ b/Mathlib/Algebra/Polynomial/Derivation.lean @@ -29,6 +29,7 @@ section CommSemiring variable {R A : Type*} [CommSemiring R] +set_option backward.isDefEq.respectTransparency false in /-- `Polynomial.derivative` as a derivation. -/ @[simps] def derivative' : Derivation R R[X] R[X] where @@ -71,6 +72,7 @@ lemma mkDerivation_apply (a : A) (f : R[X]) : @[simp] theorem mkDerivation_X (a : A) : mkDerivation R a X = a := by simp [mkDerivation_apply] +set_option backward.isDefEq.respectTransparency false in lemma mkDerivation_one_eq_derivative' : mkDerivation R (1 : R[X]) = derivative' := by ext : 1 simp [derivative'] @@ -106,6 +108,7 @@ variable {R A M : Type*} [CommSemiring R] [CommSemiring A] [Algebra R A] [AddCom open Polynomial Module +set_option backward.isDefEq.respectTransparency false in set_option linter.style.whitespace false in -- manual alignment is not recognised /-- For a derivation `d : A → M` and an element `a : A`, `d.compAEval a` is the diff --git a/Mathlib/Algebra/Polynomial/Expand.lean b/Mathlib/Algebra/Polynomial/Expand.lean index d9f6a9738e5e72..4f64e2f5a600f9 100644 --- a/Mathlib/Algebra/Polynomial/Expand.lean +++ b/Mathlib/Algebra/Polynomial/Expand.lean @@ -47,6 +47,7 @@ variable {R} theorem expand_eq_comp_X_pow {f : R[X]} : expand R p f = f.comp (X ^ p) := rfl +set_option backward.isDefEq.respectTransparency false in theorem expand_eq_sum {f : R[X]} : expand R p f = f.sum fun e a => C a * (X ^ p) ^ e := by simp [expand, eval₂_eq_sum] @@ -58,6 +59,7 @@ theorem expand_C (r : R) : expand R p (C r) = C r := theorem expand_X : expand R p X = X ^ p := eval₂_X _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem expand_monomial (r : R) : expand R p (monomial q r) = monomial (q * p) r := by simp_rw [← smul_X_eq_monomial, map_smul, map_pow, expand_X, mul_comm, pow_mul] diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index e7c7d9340ea465..ce2a095caf6ad1 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -294,6 +294,7 @@ nonnegative degree coincide with the ones of `f`. The terms of negative degree def trunc : R[T;T⁻¹] →+ R[X] := (toFinsuppIso R).symm.toAddMonoidHom.comp <| comapDomainAddMonoidHom (↑) Nat.cast_injective +set_option backward.isDefEq.respectTransparency false in @[simp] theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by apply (toFinsuppIso R).injective @@ -518,6 +519,7 @@ theorem mk'_one_X_pow (n : ℕ) : IsLocalization.mk' R[T;T⁻¹] 1 (⟨X^n, n, rfl⟩ : Submonoid.powers (X : R[X])) = T (-n) := by rw [mk'_eq 1 n, toLaurent_one, one_mul] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mk'_one_X : IsLocalization.mk' R[T;T⁻¹] 1 (⟨X, 1, pow_one X⟩ : Submonoid.powers (X : R[X])) = T (-1) := by diff --git a/Mathlib/Algebra/Polynomial/Module/AEval.lean b/Mathlib/Algebra/Polynomial/Module/AEval.lean index b6eb75e695dd37..e92faff4d6eb1a 100644 --- a/Mathlib/Algebra/Polynomial/Module/AEval.lean +++ b/Mathlib/Algebra/Polynomial/Module/AEval.lean @@ -70,6 +70,7 @@ lemma of_aeval_smul (f : R[X]) (m : M) : of R M a (aeval a f • m) = f • of R @[simp] lemma of_symm_smul (f : R[X]) (m : AEval R M a) : (of R M a).symm (f • m) = aeval a f • (of R M a).symm m := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma C_smul (t : R) (m : AEval R M a) : C t • m = t • m := (of R M a).symm.injective <| by simp @@ -167,6 +168,7 @@ def equiv_mapSubmodule : map_add' x y := rfl map_smul' t x := rfl +set_option backward.isDefEq.respectTransparency false in /-- The natural `R[X]`-linear equivalence between the two ways to represent an invariant submodule. -/ noncomputable def restrict_equiv_mapSubmodule : diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index aa72d371907c63..480708b1aa4e45 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -188,6 +188,7 @@ instance isScalarTower' (M : Type u) [AddCommGroup M] [Module R M] [Module S M] intro x y z rw [← @IsScalarTower.algebraMap_smul S R, ← @IsScalarTower.algebraMap_smul S R, smul_assoc] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem monomial_smul_single (i : ℕ) (r : R) (j : ℕ) (m : M) : monomial i r • single R j m = single R (i + j) (r • m) := by @@ -317,6 +318,7 @@ theorem map_smul (f : M →ₗ[R] M') (p : R[X]) (q : PolynomialModule R M) : | monomial => rw [monomial_smul_single, map_single, Polynomial.map_monomial, map_single, monomial_smul_single, f.map_smul, algebraMap_smul] +set_option backward.isDefEq.respectTransparency.types false in /-- Evaluate a polynomial `p : PolynomialModule R M` at `r : R`. -/ @[simps! -isSimp] def eval (r : R) : PolynomialModule R M →ₗ[R] M where diff --git a/Mathlib/Algebra/Polynomial/OfFn.lean b/Mathlib/Algebra/Polynomial/OfFn.lean index 2d8521f1f06382..b35beb9f699644 100644 --- a/Mathlib/Algebra/Polynomial/OfFn.lean +++ b/Mathlib/Algebra/Polynomial/OfFn.lean @@ -40,6 +40,7 @@ section ofFn variable {R : Type*} [Semiring R] [DecidableEq R] +set_option backward.isDefEq.respectTransparency false in /-- `ofFn n v` is the polynomial whose coefficients are the entries of the vector `v`. -/ def ofFn (n : ℕ) : (Fin n → R) →ₗ[R] R[X] where toFun v := ⟨.ofCoeff (List.ofFn v).toFinsupp⟩ @@ -64,12 +65,14 @@ lemma ne_zero_of_ofFn_ne_zero {n : ℕ} {v : Fin n → R} (h : ofFn n v ≠ 0) : subst h simp +set_option backward.isDefEq.respectTransparency false in /-- If `i < n` the `i`-th coefficient of `ofFn n v` is `v i`. -/ @[simp] theorem ofFn_coeff_eq_val_of_lt {n i : ℕ} (v : Fin n → R) (hi : i < n) : (ofFn n v).coeff i = v ⟨i, hi⟩ := by simp [ofFn, hi] +set_option backward.isDefEq.respectTransparency false in /-- If `n ≤ i` the `i`-th coefficient of `ofFn n v` is `0`. -/ @[simp] theorem ofFn_coeff_eq_zero_of_ge {n i : ℕ} (v : Fin n → R) (hi : n ≤ i) : @@ -97,6 +100,7 @@ theorem ofFn_eq_sum_monomial {n : ℕ} (v : Fin n → R) : ofFn n v = · rw [as_sum_range' (ofFn n v) n <| ofFn_natDegree_lt (Nat.one_le_iff_ne_zero.mpr h) v] simp [Finset.sum_range] +set_option backward.isDefEq.respectTransparency false in theorem toFn_comp_ofFn_eq_id (n : ℕ) (v : Fin n → R) : toFn n (ofFn n v) = v := by simp [toFn, ofFn, LinearMap.pi] diff --git a/Mathlib/Algebra/Polynomial/Reverse.lean b/Mathlib/Algebra/Polynomial/Reverse.lean index 57e12c9b888666..64628cd5115ff1 100644 --- a/Mathlib/Algebra/Polynomial/Reverse.lean +++ b/Mathlib/Algebra/Polynomial/Reverse.lean @@ -66,6 +66,7 @@ theorem revAt_invol {N i : ℕ} : (revAt N) (revAt N i) = i := theorem revAt_le {N i : ℕ} (H : i ≤ N) : revAt N i = N - i := if_pos H +set_option backward.isDefEq.respectTransparency false in lemma revAt_eq_self_of_lt {N i : ℕ} (h : N < i) : revAt N i = i := by simp [revAt, Nat.not_le.mpr h] theorem revAt_add {N O n o : ℕ} (hn : n ≤ N) (ho : o ≤ O) : @@ -87,6 +88,7 @@ Eventually, it will be used with `N` exactly equal to the degree of `f`. -/ noncomputable def reflect (N : ℕ) : R[X] → R[X] | ⟨f⟩ => ⟨.ofCoeff <| f.coeff.embDomain (revAt N)⟩ +set_option backward.isDefEq.respectTransparency false in theorem reflect_support (N : ℕ) (f : R[X]) : (reflect N f).support = Finset.image (revAt N) f.support := by cases f; ext1; simp [reflect] @@ -176,6 +178,7 @@ theorem reflect_mul (f g : R[X]) {F G : ℕ} (Ff : f.natDegree ≤ F) (Gg : g.na reflect (F + G) (f * g) = reflect F f * reflect G g := reflect_mul_induction _ _ F G f g f.support.card.le_succ g.support.card.le_succ Ff Gg +set_option backward.isDefEq.respectTransparency false in lemma natDegree_reflect_le {N : ℕ} {p : R[X]} : (p.reflect N).natDegree ≤ max N p.natDegree := by simp +contextual [-le_sup_iff, natDegree_le_iff_coeff_eq_zero, @@ -229,6 +232,7 @@ theorem reverse_zero : reverse (0 : R[X]) = 0 := @[simp] theorem reverse_eq_zero : f.reverse = 0 ↔ f = 0 := by simp [reverse] +set_option backward.isDefEq.respectTransparency false in theorem reverse_natDegree_le (f : R[X]) : f.reverse.natDegree ≤ f.natDegree := by rw [natDegree_le_iff_degree_le, degree_le_iff_coeff_zero] intro n hn diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index 96454a3b8b4cc2..b7da22f4a56f1a 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -498,6 +498,7 @@ lemma map_sub_sprod_roots_eq_prod_map_eval congr! with x hx ext; simp +set_option backward.isDefEq.respectTransparency false in lemma map_sub_roots_sprod_eq_prod_map_eval (s : Multiset R) (g : R[X]) (hg : g.Monic) (hg' : g.Splits) : ((g.roots ×ˢ s).map fun ij ↦ ij.1 - ij.2).prod = diff --git a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean index 01b2a6e5780c3a..659edf8b3748fa 100644 --- a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean +++ b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean @@ -84,12 +84,14 @@ theorem mk_eq_add_smul_omega (x y : R) : variable {A : Type*} [Ring A] [Algebra R A] +set_option backward.isDefEq.respectTransparency false in @[ext] theorem algHom_ext {f g : QuadraticAlgebra R a b →ₐ[R] A} (h : f ω = g ω) : f = g := by ext ⟨x, y⟩ simp [mk_eq_add_smul_omega, h] +set_option backward.isDefEq.respectTransparency false in /-- The unique `AlgHom` from `QuadraticAlgebra R a b` to an `R`-algebra `A`, constructed by replacing `ω` with the provided root. Conversely, this associates to every algebra morphism `QuadraticAlgebra R a b →ₐ[R] A` diff --git a/Mathlib/Algebra/Quandle.lean b/Mathlib/Algebra/Quandle.lean index 63cca3e68288f9..fd39b97a931215 100644 --- a/Mathlib/Algebra/Quandle.lean +++ b/Mathlib/Algebra/Quandle.lean @@ -422,6 +422,7 @@ theorem dihedralAct.inv (n : ℕ) (a : ZMod n) : Function.Involutive (dihedralAc dsimp only [dihedralAct] simp +set_option backward.isDefEq.respectTransparency false in instance (n : ℕ) : Quandle (Dihedral n) where act := dihedralAct n self_distrib := by @@ -647,6 +648,7 @@ theorem well_def {R : Type*} [Rack R] {G : Type*} [Group G] (f : R →◃ Quandl end toEnvelGroup.mapAux +set_option backward.isDefEq.respectTransparency false in /-- Given a map from a rack to a group, lift it to being a map from the enveloping group. More precisely, the `EnvelGroup` functor is left adjoint to `Quandle.Conj`. -/ diff --git a/Mathlib/Algebra/Quaternion.lean b/Mathlib/Algebra/Quaternion.lean index 83aaf47e2793c9..ae9cd00586702e 100644 --- a/Mathlib/Algebra/Quaternion.lean +++ b/Mathlib/Algebra/Quaternion.lean @@ -752,6 +752,7 @@ protected instance algebra [CommSemiring S] [Algebra S R] : Algebra S ℍ[R] := instance : Star ℍ[R] := inferInstanceAs <| Star ℍ[R,-1,0,-1] instance : StarRing ℍ[R] := inferInstanceAs <| StarRing ℍ[R,-1,0,-1] +set_option backward.isDefEq.respectTransparency.types false in instance : IsStarNormal a := inferInstanceAs <| IsStarNormal (R := ℍ[R,-1,0,-1]) a @[ext] diff --git a/Mathlib/Algebra/Ring/CentroidHom.lean b/Mathlib/Algebra/Ring/CentroidHom.lean index 40144449bb936c..9ad10a98f6dee7 100644 --- a/Mathlib/Algebra/Ring/CentroidHom.lean +++ b/Mathlib/Algebra/Ring/CentroidHom.lean @@ -519,6 +519,7 @@ section NonAssocSemiring variable [NonAssocSemiring α] +set_option backward.isDefEq.respectTransparency false in /-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/ def centerIsoCentroid : Subsemiring.center α ≃+* CentroidHom α := { centerToCentroid with diff --git a/Mathlib/Algebra/Ring/Equiv.lean b/Mathlib/Algebra/Ring/Equiv.lean index 9889174662555c..01f6881c0fb665 100644 --- a/Mathlib/Algebra/Ring/Equiv.lean +++ b/Mathlib/Algebra/Ring/Equiv.lean @@ -537,6 +537,9 @@ theorem piCongrLeft'_symm {R : Type*} [NonUnitalNonAssocSemiring R] (e : α ≃ (RingEquiv.piCongrLeft' (fun _ => R) e).symm = RingEquiv.piCongrLeft' _ e.symm := by simp only [piCongrLeft', RingEquiv.symm, MulEquiv.symm, Equiv.piCongrLeft'_symm] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Transport dependent functions through an equivalence of the base space. This is `Equiv.piCongrLeft` as a `RingEquiv`. -/ diff --git a/Mathlib/Algebra/Ring/Hom/Defs.lean b/Mathlib/Algebra/Ring/Hom/Defs.lean index b03d493b08ff69..86e2ff51531ddf 100644 --- a/Mathlib/Algebra/Ring/Hom/Defs.lean +++ b/Mathlib/Algebra/Ring/Hom/Defs.lean @@ -171,7 +171,7 @@ end variable [NonUnitalNonAssocSemiring α] [NonUnitalNonAssocSemiring β] /-- The identity non-unital ring homomorphism from a non-unital semiring to itself. -/ -@[implicit_reducible] +@[instance_reducible] protected def id (α : Type*) [NonUnitalNonAssocSemiring α] : α →ₙ+* α where toFun x := x map_mul' _ _ := rfl @@ -208,7 +208,7 @@ theorem coe_mulHom_id : (NonUnitalRingHom.id α : α →ₙ* α) = MulHom.id α variable [NonUnitalNonAssocSemiring γ] /-- Composition of non-unital ring homomorphisms is a non-unital ring homomorphism. -/ -@[implicit_reducible] +@[instance_reducible] def comp (g : β →ₙ+* γ) (f : α →ₙ+* β) : α →ₙ+* γ := { g.toMulHom.comp f.toMulHom, g.toAddMonoidHom.comp f.toAddMonoidHom with } @@ -509,7 +509,7 @@ def mk' [NonAssocSemiring α] [NonAssocRing β] (f : α →* β) variable {_ : NonAssocSemiring α} {_ : NonAssocSemiring β} /-- The identity ring homomorphism from a semiring to itself. -/ -@[implicit_reducible] +@[instance_reducible] def id (α : Type*) [NonAssocSemiring α] : α →+* α where toFun x := x map_zero' := rfl @@ -538,7 +538,7 @@ theorem coe_monoidHom_id : (id α : α →* α) = MonoidHom.id α := variable {_ : NonAssocSemiring γ} /-- Composition of ring homomorphisms is a ring homomorphism. -/ -@[implicit_reducible] +@[instance_reducible] def comp (g : β →+* γ) (f : α →+* β) : α →+* γ := { g.toNonUnitalRingHom.comp f.toNonUnitalRingHom with toFun x := g (f x), map_one' := by simp } diff --git a/Mathlib/Algebra/Ring/Invertible.lean b/Mathlib/Algebra/Ring/Invertible.lean index bfc4dc0b75b186..f6dd9d7a84a87f 100644 --- a/Mathlib/Algebra/Ring/Invertible.lean +++ b/Mathlib/Algebra/Ring/Invertible.lean @@ -61,7 +61,7 @@ theorem IsAddUnit.mul_right {x : R} (h : IsAddUnit x) (y : R) : IsAddUnit (x * y end NonUnitalNonAssocSemiring /-- `-⅟a` is the inverse of `-a` -/ -@[implicit_reducible] +@[instance_reducible] def invertibleNeg [Mul R] [One R] [HasDistribNeg R] (a : R) [Invertible a] : Invertible (-a) := ⟨-⅟a, by simp, by simp⟩ diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index 7e59b08ac1fbca..a39e4dfbea06d8 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -975,6 +975,7 @@ theorem ofLeftInverse_symm_apply {g : S → R} {f : R →+* S} (h : Function.Lef def subringMap (e : R ≃+* S) : s ≃+* s.map e.toRingHom := e.subsemiringMap s.toSubsemiring +set_option backward.isDefEq.respectTransparency false in /-- A ring isomorphism `e : R ≃+* S` descends to subrings `s' ≃+* s` provided `x ∈ s' ↔ e x ∈ s`. -/ @[simps!] diff --git a/Mathlib/Algebra/RingQuot.lean b/Mathlib/Algebra/RingQuot.lean index 86352ce1c777b7..3fe3f3b96190e3 100644 --- a/Mathlib/Algebra/RingQuot.lean +++ b/Mathlib/Algebra/RingQuot.lean @@ -488,6 +488,7 @@ theorem ringQuot_ext' {s : A → A → Prop} (f g : RingQuot s →ₐ[S] B) rcases mkAlgHom_surjective S s x with ⟨x, rfl⟩ exact AlgHom.congr_fun w x +set_option backward.isDefEq.respectTransparency false in irreducible_def preLiftAlgHom {s : A → A → Prop} {f : A →ₐ[S] B} (h : ∀ ⦃x y⦄, s x y → f x = f y) : RingQuot s →ₐ[S] B := { toFun := fun x ↦ Quot.lift f diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean index 3e50c645da8563..1defc05fd53742 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean @@ -863,7 +863,7 @@ def comapMulAction : MulAction G (SkewMonoidAlgebra M α) where attribute [local instance] comapMulAction /-- This is not an instance as it conflicts with `SkewMonoidAlgebra.distribMulAction` when `G = kˣ`. -/ -@[implicit_reducible] +@[instance_reducible] def comapDistribMulActionSelf [AddCommMonoid k] : DistribMulAction G (SkewMonoidAlgebra k G) where smul_zero g := by diff --git a/Mathlib/Algebra/Star/CentroidHom.lean b/Mathlib/Algebra/Star/CentroidHom.lean index c19be02a62c6cf..f90ec24349cf35 100644 --- a/Mathlib/Algebra/Star/CentroidHom.lean +++ b/Mathlib/Algebra/Star/CentroidHom.lean @@ -117,6 +117,7 @@ section NonAssocStarSemiring variable [NonAssocSemiring α] [StarRing α] +set_option backward.isDefEq.respectTransparency false in /-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/ def starCenterIsoCentroid : StarSubsemiring.center α ≃⋆+* CentroidHom α where __ := starCenterToCentroid diff --git a/Mathlib/Algebra/Star/Module.lean b/Mathlib/Algebra/Star/Module.lean index 2b343fc94591af..3d5047d9080155 100644 --- a/Mathlib/Algebra/Star/Module.lean +++ b/Mathlib/Algebra/Star/Module.lean @@ -216,6 +216,7 @@ theorem skewAdjointPart_comp_subtype_skewAdjoint : variable (A) +set_option backward.isDefEq.respectTransparency false in /-- The decomposition of elements of a star module into their self- and skew-adjoint parts, as a linear equivalence. -/ @[simps!] diff --git a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean index 80934eec23f179..4f9e0b65f26caf 100644 --- a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean @@ -1049,6 +1049,7 @@ instance instIsMulCommutative_iSup [Nonempty ι] [Preorder ι] [IsDirectedOrder IsMulCommutative (⨆ i, S i : NonUnitalStarSubalgebra R A) := isMulCommutative_iSup S.monotone.directed_le +set_option backward.isDefEq.respectTransparency false in /-- Define a non-unital star algebra homomorphism on a directed supremum of non-unital star subalgebras by defining it on each non-unital star subalgebra, and proving that it agrees on the intersection of non-unital star subalgebras. -/ diff --git a/Mathlib/Algebra/Star/RingQuot.lean b/Mathlib/Algebra/Star/RingQuot.lean index 7bb4c00a742dea..8ac151788c6ed4 100644 --- a/Mathlib/Algebra/Star/RingQuot.lean +++ b/Mathlib/Algebra/Star/RingQuot.lean @@ -43,7 +43,7 @@ private theorem star'_quot (hr : ∀ a b, r a b → r (star a) (star b)) {a} : (star' r hr ⟨Quot.mk _ a⟩ : RingQuot r) = ⟨Quot.mk _ (star a)⟩ := rfl /-- Transfer a `StarRing` instance through a quotient, if the quotient is invariant to `star` -/ -@[implicit_reducible] +@[instance_reducible] def starRing {R : Type u} [Semiring R] [StarRing R] (r : R → R → Prop) (hr : ∀ a b, r a b → r (star a) (star b)) : StarRing (RingQuot r) where star := star' r hr diff --git a/Mathlib/Algebra/Star/StarAlgHom.lean b/Mathlib/Algebra/Star/StarAlgHom.lean index badc8dfcf88451..b397f0e47014c3 100644 --- a/Mathlib/Algebra/Star/StarAlgHom.lean +++ b/Mathlib/Algebra/Star/StarAlgHom.lean @@ -656,6 +656,7 @@ instance (priority := 100) {F R A B : Type*} [Monoid R] [NonUnitalNonAssocSemiri NonUnitalAlgHomClass F R A B := { } +set_option backward.isDefEq.respectTransparency false in -- See note [lower instance priority] instance (priority := 100) (F R A B : Type*) [CommSemiring R] [Semiring A] [Algebra R A] [Semiring B] [Algebra R B] [EquivLike F A B] [NonUnitalAlgEquivClass F R A B] : diff --git a/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean b/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean index 6dfa47f00a244d..3d9e4031b89ab4 100644 --- a/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean +++ b/Mathlib/Algebra/Star/UnitaryStarAlgAut.lean @@ -24,6 +24,7 @@ variable {S R : Type*} [Semiring R] [StarMul R] [SMul S R] [IsScalarTower S R R] [SMulCommClass S R R] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in variable (S R) in /-- Each unitary element `u` defines a ⋆-algebra automorphism such that `x ↦ u * x * star u`. diff --git a/Mathlib/Algebra/Symmetrized.lean b/Mathlib/Algebra/Symmetrized.lean index d2127d0905153b..1745cc4c4efb96 100644 --- a/Mathlib/Algebra/Symmetrized.lean +++ b/Mathlib/Algebra/Symmetrized.lean @@ -247,6 +247,7 @@ theorem invOf_sym [Mul α] [AddMonoidWithOne α] [Invertible (2 : α)] (a : α) ⅟(sym a) = sym (⅟a) := rfl +set_option backward.isDefEq.respectTransparency false in instance nonAssocSemiring [Semiring α] [Invertible (2 : α)] : NonAssocSemiring αˢʸᵐ := { SymAlg.addCommMonoid with zero_mul := fun _ => by diff --git a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean index f6a64330b62810..c440a125680b88 100644 --- a/Mathlib/Algebra/TrivSqZeroExt/Basic.lean +++ b/Mathlib/Algebra/TrivSqZeroExt/Basic.lean @@ -726,6 +726,7 @@ theorem mul_right_eq_one (x : tsze R M) (r : R) (h : x.fst * r = 1) : variable [SMulCommClass R Rᵐᵒᵖ M] +set_option backward.isDefEq.respectTransparency false in /-- `x : tzre R M` is invertible when `x.fst : R` is. -/ abbrev invertibleOfInvertibleFst (x : tsze R M) [Invertible x.fst] : Invertible x where invOf := (⅟x.fst, -(⅟x.fst •> x.snd <• ⅟x.fst)) diff --git a/Mathlib/Algebra/TrivSqZeroExt/Ideal.lean b/Mathlib/Algebra/TrivSqZeroExt/Ideal.lean index 07c93c2a4fe6db..e0455c79023574 100644 --- a/Mathlib/Algebra/TrivSqZeroExt/Ideal.lean +++ b/Mathlib/Algebra/TrivSqZeroExt/Ideal.lean @@ -29,6 +29,7 @@ variable (R M : Type*) /-- The kernel of the `AlgHom` `fstHom R R M` -/ def kerIdeal : Ideal (TrivSqZeroExt R M) := RingHom.ker (fstHom R R M) +set_option backward.isDefEq.respectTransparency false in theorem mem_kerIdeal_iff_inr (x : TrivSqZeroExt R M) : x ∈ kerIdeal R M ↔ x = inr x.snd := by obtain ⟨r, m⟩ := x simp only [kerIdeal, RingHom.mem_ker, fstHom_apply, fst_mk] diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index c3d85f203b8d0b..8c4c6eb0e317a8 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -258,6 +258,7 @@ def Scheme.affineOpens (X : Scheme) : Set X.Opens := instance {Y : Scheme.{u}} (U : Y.affineOpens) : IsAffine U := U.property +set_option backward.isDefEq.respectTransparency.types false in theorem isAffineOpen_opensRange {X Y : Scheme} [IsAffine X] (f : X ⟶ Y) [H : IsOpenImmersion f] : IsAffineOpen f.opensRange := by refine .of_isIso (IsOpenImmersion.isoOfRangeEq f (Y.ofRestrict _) ?_).inv @@ -295,6 +296,7 @@ instance (X : Scheme) [CompactSpace X] (𝒰 : X.OpenCover) [∀ i, IsAffine ( IsAffine (𝒰.finiteSubcover.X i) := inferInstanceAs (IsAffine (𝒰.X _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {X} [IsAffine X] (i) : IsAffine ((Scheme.coverOfIsIso (P := @IsOpenImmersion) (𝟙 X)).X i) := by @@ -355,6 +357,7 @@ lemma Scheme.Opens.toSpecΓ_top {X : Scheme} : (⊤ : X.Opens).toSpecΓ = (⊤ : X.Opens).ι ≫ X.toSpecΓ := by simp [Scheme.Opens.toSpecΓ, toSpecΓ_naturality]; rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Scheme.Opens.toSpecΓ_appTop {X : Scheme.{u}} (U : X.Opens) : U.toSpecΓ.appTop = (Scheme.ΓSpecIso Γ(X, U)).hom ≫ U.topIso.inv := by @@ -378,6 +381,7 @@ namespace IsAffineOpen variable {X Y : Scheme.{u}} {U : X.Opens} (hU : IsAffineOpen U) (f : Γ(X, U)) +set_option backward.isDefEq.respectTransparency.types false in attribute [-simp] eqToHom_op in /-- The isomorphism `U ≅ Spec Γ(X, U)` for an affine `U`. -/ @[simps! -isSimp inv] @@ -407,6 +411,7 @@ lemma isoSpec_hom_apply (x : U) : congr 1 exact IsLocalRing.comap_closedPoint (U.stalkIso x).inv.hom +set_option backward.isDefEq.respectTransparency.types false in lemma isoSpec_hom_appTop : hU.isoSpec.hom.appTop = (Scheme.ΓSpecIso Γ(X, U)).hom ≫ U.topIso.inv := by simp [isoSpec, Scheme.isoSpec] @@ -597,6 +602,7 @@ theorem basicOpen_fromSpec_app : (Spec Γ(X, U)).basicOpen (hU.fromSpec.app U f) = PrimeSpectrum.basicOpen f := by rw [← hU.fromSpec_preimage_basicOpen, Scheme.preimage_basicOpen] +set_option backward.isDefEq.respectTransparency.types false in include hU in theorem basicOpen : IsAffineOpen (X.basicOpen f) := by @@ -633,6 +639,7 @@ theorem exists_basicOpen_le {V : X.Opens} (x : V) (h : ↑x ∈ U) : simpa [Scheme.image_basicOpen] using! (U.ι.image_mono h₂).trans (U.ι.image_preimage_le _) exact ⟨U.topIso.hom.hom r, by simp [Scheme.Opens.toScheme_presheaf_obj, h₁, h₂]⟩ +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance {R : CommRingCat} {U} : Algebra R Γ(Spec R, U) := inferInstanceAs (Algebra R ((Spec.structureSheaf R).presheaf.obj _)) @@ -641,6 +648,7 @@ instance {R : CommRingCat} {U} : Algebra R Γ(Spec R, U) := lemma algebraMap_Spec_obj {R : CommRingCat} {U} : algebraMap R Γ(Spec R, U) = ((Scheme.ΓSpecIso R).inv ≫ (Spec R).presheaf.map (homOfLE le_top).op).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in instance {R : CommRingCat} {f : R} : IsLocalization.Away f Γ(Spec R, PrimeSpectrum.basicOpen f) := inferInstanceAs (IsLocalization.Away f @@ -654,11 +662,13 @@ def basicOpenSectionsToAffine : hU.fromSpec.app (X.basicOpen f) ≫ (Spec Γ(X, U)).presheaf.map (eqToHom (hU.fromSpec_preimage_basicOpen f).symm).op +set_option backward.isDefEq.respectTransparency.types false in instance basicOpenSectionsToAffine_isIso : IsIso (basicOpenSectionsToAffine hU f) := (hU.fromSpec.isIso_app _ (hU.opensRange_fromSpec.symm ▸ X.basicOpen_le f)).comp_isIso' inferInstance +set_option backward.isDefEq.respectTransparency.types false in include hU in theorem isLocalization_basicOpen : IsLocalization.Away f Γ(X, X.basicOpen f) := by @@ -766,6 +776,7 @@ noncomputable def primeIdealOf (x : U) : PrimeSpectrum Γ(X, U) := hU.isoSpec.hom x +set_option backward.isDefEq.respectTransparency.types false in theorem fromSpec_primeIdealOf (x : U) : hU.fromSpec (hU.primeIdealOf x) = x.1 := by dsimp only [IsAffineOpen.fromSpec, Subtype.coe_mk, IsAffineOpen.primeIdealOf] @@ -777,6 +788,7 @@ theorem primeIdealOf_eq_map_closedPoint (x : U) : hU.primeIdealOf x = Spec.map (X.presheaf.germ _ x x.2) (closedPoint _) := hU.isoSpec_hom_apply _ +set_option backward.isDefEq.respectTransparency.types false in lemma comap_primeIdealOf_appLE {f : X ⟶ Y} {x : X} (U : Y.Opens) (hU : IsAffineOpen U) (V : X.Opens) (hV : IsAffineOpen V) (hVU : V ≤ f ⁻¹ᵁ U) (hx : x ∈ V) : (hV.primeIdealOf ⟨x, hx⟩).comap (f.appLE U V hVU).hom = hU.primeIdealOf ⟨f x, hVU hx⟩ := by @@ -788,6 +800,7 @@ lemma comap_primeIdealOf_appLE {f : X ⟶ Y} {x : X} (U : Y.Opens) apply Subtype.ext simp +set_option backward.isDefEq.respectTransparency.types false in /-- If a point `x : U` is a closed point, then its corresponding prime ideal is maximal. -/ theorem primeIdealOf_isMaximal_of_isClosed (x : U) (hx : IsClosed {(x : X)}) : (hU.primeIdealOf x).asIdeal.IsMaximal := by @@ -801,6 +814,7 @@ theorem primeIdealOf_isMaximal_of_isClosed (x : U) (hx : IsClosed {(x : X)}) : apply (TopCat.isIso_iff_isHomeomorph _).mp infer_instance +set_option backward.isDefEq.respectTransparency.types false in theorem isLocalization_stalk' (y : PrimeSpectrum Γ(X, U)) (hy : hU.fromSpec y ∈ U) : @IsLocalization.AtPrime (R := Γ(X, U)) @@ -835,6 +849,7 @@ lemma stalkMap_injective (f : X ⟶ Y) {U : Opens Y} (hU : IsAffineOpen U) (x : apply (hU.isLocalization_stalk ⟨f x, hx⟩).injective_of_map_algebraMap_zero exact h +set_option backward.isDefEq.respectTransparency.types false in include hU in lemma mem_ideal_iff {s : Γ(X, U)} {I : Ideal Γ(X, U)} : s ∈ I ↔ ∀ (x : X) (h : x ∈ U), X.presheaf.germ U x h s ∈ I.map (X.presheaf.germ U x h).hom := by @@ -863,6 +878,7 @@ lemma ideal_ext_iff {I J : Ideal Γ(X, U)} : I.map (X.presheaf.germ U x h).hom = J.map (X.presheaf.germ U x h).hom := by simp_rw [le_antisymm_iff, hU.ideal_le_iff, forall_and] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given affine opens `x ∈ V ⊆ f⁻¹(U)`, the stalk map of `f` at `x` is isomorphic to `Localization.localRingHom` of `f.appLE U V`. -/ @@ -947,6 +963,7 @@ theorem self_le_iSup_basicOpen_iff {s : Set Γ(X, U)} : end IsAffineOpen +set_option backward.isDefEq.respectTransparency.types false in /-- The affine open cover given by a covering family of affine opens. -/ @[simps I₀ X f] def Scheme.AffineOpenCover.ofIsOpenCover {X : Scheme.{u}} {ι : Type*} (U : ι → X.Opens) @@ -984,6 +1001,7 @@ lemma stalkMap_injective_of_isAffine {X Y : Scheme} (f : X ⟶ Y) [IsAffine Y] ( Function.Injective (f.stalkMap x) := (isAffineOpen_top Y).stalkMap_injective f x trivial h +set_option backward.isDefEq.respectTransparency.types false in /-- Given a spanning set of `Γ(X, U)`, the corresponding basic open sets cover `U`. See `IsAffineOpen.basicOpen_union_eq_self_iff` for the inverse direction for affine open sets. @@ -1072,6 +1090,7 @@ lemma toSpecΓ_preimage_zeroLocus (s : Set Γ(X, ⊤)) : X.toSpecΓ ⁻¹' PrimeSpectrum.zeroLocus s = X.zeroLocus s := LocallyRingedSpace.toΓSpec_preimage_zeroLocus_eq s +set_option backward.isDefEq.respectTransparency.types false in /-- If `X` is affine, the image of the zero locus of global sections of `X` under `X.isoSpec` is the zero locus in terms of the prime spectrum of `Γ(X, ⊤)`. -/ lemma isoSpec_image_zeroLocus [IsAffine X] @@ -1084,6 +1103,7 @@ lemma toSpecΓ_image_zeroLocus [IsAffine X] (s : Set Γ(X, ⊤)) : X.toSpecΓ '' X.zeroLocus s = PrimeSpectrum.zeroLocus s := X.isoSpec_image_zeroLocus _ +set_option backward.isDefEq.respectTransparency.types false in lemma isoSpec_inv_preimage_zeroLocus [IsAffine X] (s : Set Γ(X, ⊤)) : X.isoSpec.inv ⁻¹' X.zeroLocus s = PrimeSpectrum.zeroLocus s := by rw [← toSpecΓ_preimage_zeroLocus, ← Set.preimage_comp, ← TopCat.coe_comp, ← Scheme.Hom.comp_base, @@ -1130,6 +1150,7 @@ lemma Opens.toSpecΓ_preimage_zeroLocus {X : Scheme.{u}} (U : X.Opens) (s : Set end Scheme +set_option backward.isDefEq.respectTransparency.types false in lemma IsAffineOpen.fromSpec_preimage_zeroLocus {X : Scheme.{u}} {U : X.Opens} (hU : IsAffineOpen U) (s : Set Γ(X, U)) : hU.fromSpec ⁻¹' X.zeroLocus s = PrimeSpectrum.zeroLocus s := by @@ -1204,6 +1225,7 @@ def Scheme.Hom.liftQuotient (f : X.Hom (Spec A)) (I : Ideal A) X.toSpecΓ ≫ Spec.map (CommRingCat.ofHom (Ideal.Quotient.lift _ ((Scheme.ΓSpecIso _).inv ≫ f.appTop).hom hI)) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Scheme.Hom.liftQuotient_comp (f : X.Hom (Spec A)) (I : Ideal A) (hI : I ≤ RingHom.ker ((Scheme.ΓSpecIso A).inv ≫ f.appTop).hom) : @@ -1263,6 +1285,7 @@ section Stalks variable {R S : CommRingCat.{u}} (f : R ⟶ S) (p : PrimeSpectrum S) (x : PrimeSpectrum R) +set_option backward.isDefEq.respectTransparency.types false in variable (R) (x : PrimeSpectrum R) in /-- The stalk of `Spec R` at `x` is isomorphic to `Rₚ`, where `p` is the prime corresponding to `x`. -/ @@ -1283,6 +1306,9 @@ lemma Spec.germ_stalkMapIso_hom : (Scheme.ΓSpecIso R).hom ≫ CommRingCat.ofHom (algebraMap R _) := by simp [← Iso.inv_comp_eq, ← Spec.algebraMap_stalkIso_inv_assoc] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Variant of `AlgebraicGeometry.localRingHom_comp_stalkIso` for `Spec.map`. -/ @[elementwise] lemma Scheme.localRingHom_comp_stalkIso {R S : CommRingCat.{u}} (f : R ⟶ S) (p : PrimeSpectrum S) : diff --git a/Mathlib/AlgebraicGeometry/AffineSpace.lean b/Mathlib/AlgebraicGeometry/AffineSpace.lean index c886fc0dfce1a6..46bf5875477a92 100644 --- a/Mathlib/AlgebraicGeometry/AffineSpace.lean +++ b/Mathlib/AlgebraicGeometry/AffineSpace.lean @@ -69,6 +69,7 @@ instance over : 𝔸(n; S).CanonicallyOver S where /-- The map from the affine `n`-space over `S` to the integral model `Spec ℤ[n]`. -/ def toSpecMvPoly : 𝔸(n; S) ⟶ Spec ℤ[n] := pullback.snd _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Morphisms into `Spec ℤ[n]` are equivalent the choice of `n` global sections. @@ -134,6 +135,7 @@ lemma hom_ext {f g : X ⟶ 𝔸(n; S)} rw [toSpecMvPolyIntEquiv_comp, toSpecMvPolyIntEquiv_comp] exact h₂ i +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma comp_homOfVector {X Y : Scheme} (v : n → Γ(Y, ⊤)) (f : X ⟶ Y) (g : Y ⟶ S) : f ≫ homOfVector g v = homOfVector (f ≫ g) (f.appTop ∘ v) := by @@ -158,6 +160,7 @@ def homOverEquiv {X : Scheme.{u}} [X.Over S] : · rw [homOfVector_appTop_coord] right_inv v := by ext i; simp [-TopologicalSpace.Opens.map_top, homOfVector_appTop_coord] +set_option backward.isDefEq.respectTransparency.types false in variable (n) in /-- The affine space over an affine base is isomorphic to the spectrum of the polynomial ring. @@ -206,11 +209,13 @@ lemma isoOfIsAffine_hom_appTop [IsAffine S] : (eval₂Hom ((𝔸(n; S) ↘ S).appTop).hom (coord S)) := by simp [isoOfIsAffine_hom] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma isoOfIsAffine_inv_appTop_coord [IsAffine S] (i) : (isoOfIsAffine n S).inv.appTop (coord _ i) = (Scheme.ΓSpecIso (.of _)).inv (.X i) := homOfVector_appTop_coord _ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma isoOfIsAffine_inv_over [IsAffine S] : (isoOfIsAffine n S).inv ≫ 𝔸(n; S) ↘ S = Spec.map (CommRingCat.ofHom C) ≫ S.isoSpec.inv := @@ -225,6 +230,7 @@ def SpecIso (R : CommRingCat.{u}) : isoOfIsAffine _ _ ≪≫ Scheme.Spec.mapIso (MvPolynomial.mapEquiv _ (Scheme.ΓSpecIso R).symm.commRingCatIsoToRingEquiv).toCommRingCatIso.op +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma SpecIso_hom_appTop (R : CommRingCat.{u}) : (SpecIso n R).hom.appTop = (Scheme.ΓSpecIso _).hom ≫ @@ -233,6 +239,7 @@ lemma SpecIso_hom_appTop (R : CommRingCat.{u}) : ext i simp [SpecIso] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma SpecIso_inv_appTop_coord (R : CommRingCat.{u}) (i) : (SpecIso n R).inv.appTop (coord _ i) = (Scheme.ΓSpecIso (.of _)).inv (.X i) := by @@ -243,6 +250,7 @@ lemma SpecIso_inv_appTop_coord (R : CommRingCat.{u}) (i) : congr 1 exact map_X _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma SpecIso_inv_over (R : CommRingCat.{u}) : (SpecIso n R).inv ≫ 𝔸(n; Spec R) ↘ Spec R = Spec.map (CommRingCat.ofHom C) := by @@ -281,6 +289,7 @@ lemma map_toSpecMvPoly {S T : Scheme.{u}} (f : S ⟶ T) : lemma map_id : map n (𝟙 S) = 𝟙 𝔸(n; S) := by ext1 <;> simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc, simp] lemma map_comp {S S' S'' : Scheme} (f : S ⟶ S') (g : S' ⟶ S'') : map n (f ≫ g) = map n f ≫ map n g := by @@ -288,6 +297,7 @@ lemma map_comp {S S' S'' : Scheme} (f : S ⟶ S') (g : S' ⟶ S'') : · simp · simp +set_option backward.isDefEq.respectTransparency.types false in lemma map_SpecMap {R S : CommRingCat.{u}} (φ : R ⟶ S) : map n (Spec.map φ) = (SpecIso n S).hom ≫ Spec.map (CommRingCat.ofHom (MvPolynomial.map φ.hom)) ≫ @@ -337,11 +347,13 @@ lemma reindex_appTop_coord {n m : Type u} (i : m → n) (S : Scheme.{u}) (j : m) lemma reindex_id : reindex id S = 𝟙 𝔸(n; S) := by ext1 <;> simp +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] lemma reindex_comp {n₁ n₂ n₃ : Type u} (i : n₁ ⟶ n₂) (j : n₂ ⟶ n₃) (S : Scheme.{u}) : reindex (i ≫ j) S = reindex j S ≫ reindex i S := by ext k <;> simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma map_reindex {n₁ n₂ : Type u} (i : n₁ → n₂) {S T : Scheme.{u}} (f : S ⟶ T) : map n₂ f ≫ reindex i T = reindex i S ≫ map n₁ f := by @@ -358,14 +370,17 @@ def functor : (Type u)ᵒᵖ ⥤ Scheme.{u} ⥤ Scheme.{u} where end functorial section instances +set_option backward.isDefEq.respectTransparency.types false in instance : IsAffineHom (𝔸(n; S) ↘ S) := MorphismProperty.pullback_fst _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance : Surjective (𝔸(n; S) ↘ S) := MorphismProperty.pullback_fst _ _ <| by have := isIso_of_isTerminal specULiftZIsTerminal terminalIsTerminal (terminal.from _) rw [← terminal.comp_from (Spec.map (CommRingCat.ofHom C)), MorphismProperty.cancel_right_of_respectsIso (P := @Surjective)] exact ⟨MvPolynomial.comap_C_surjective⟩ +set_option backward.isDefEq.respectTransparency.types false in instance [Finite n] : LocallyOfFinitePresentation (𝔸(n; S) ↘ S) := MorphismProperty.pullback_fst _ _ <| by have := isIso_of_isTerminal specULiftZIsTerminal.{u} terminalIsTerminal (terminal.from _) @@ -406,6 +421,7 @@ instance : GeometricallyReduced (𝔸(n; S) ↘ S) := by ((h.isoIsPullback _ _ (isPullback_map _)) ≪≫ (SpecIso n (.of K))).symm infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance [h : IsReduced S] : IsReduced 𝔸(n; S) := by wlog hS : ∃ R, S = Spec R · rw [IsReduced.iff_of_openCover _ (S.affineCover.pullback₁ (𝔸(n; S) ↘ S))] @@ -421,6 +437,7 @@ instance : GeometricallyIntegral (𝔸(n; S) ↘ S) := instance [IsIntegral S] : IsIntegral 𝔸(n; S) := isIntegral_of_irreducibleSpace_of_isReduced _ +set_option backward.isDefEq.respectTransparency.types false in open MorphismProperty in instance [IsEmpty n] : IsIso (𝔸(n; S) ↘ S) := pullback_fst (P := isomorphisms _) _ _ <| by @@ -432,6 +449,7 @@ instance [IsEmpty n] : IsIso (𝔸(n; S) ↘ S) := pullback_fst ⟨C_injective n _, C_surjective _⟩⟩ · exact isIso_of_isTerminal specULiftZIsTerminal terminalIsTerminal (terminal.from _) +set_option backward.isDefEq.respectTransparency.types false in lemma isIntegralHom_over_iff_isEmpty : IsIntegralHom (𝔸(n; S) ↘ S) ↔ IsEmpty S ∨ IsEmpty n := by constructor · intro h @@ -464,6 +482,7 @@ lemma isIntegralHom_over_iff_isEmpty : IsIntegralHom (𝔸(n; S) ↘ S) ↔ IsEm lemma not_isIntegralHom [Nonempty S] [Nonempty n] : ¬ IsIntegralHom (𝔸(n; S) ↘ S) := by simp [isIntegralHom_over_iff_isEmpty] +set_option backward.isDefEq.respectTransparency.types false in lemma spec_le_iff (R : CommRingCat) (p q : Spec R) : p ≤ q ↔ q.asIdeal ≤ p.asIdeal := by aesop (add simp PrimeSpectrum.le_iff_specializes) diff --git a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean index 331e6b9ac11b68..9c81bfdff1d8b9 100644 --- a/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean +++ b/Mathlib/AlgebraicGeometry/AffineTransitionLimit.lean @@ -175,6 +175,7 @@ lemma exists_mem_of_isClosed_of_nonempty' section Opens +set_option backward.isDefEq.respectTransparency false in include hc in /-- Let `{ Dᵢ }` be a cofiltered diagram of compact schemes with affine transition maps. If `U ⊆ Dⱼ` contains the image of `limᵢ Dᵢ ⟶ Dⱼ`, then it contains the image of some `Dₖ ⟶ Dⱼ`. -/ @@ -195,6 +196,7 @@ lemma exists_map_eq_top attribute [local simp] Scheme.Hom.resLE_comp_resLE +set_option backward.isDefEq.respectTransparency.types false in /-- Given a diagram `{ Dᵢ }` of schemes and an open `U ⊆ Dᵢ`, this is the diagram of `{ Dⱼᵢ⁻¹ U }_{j ≤ i}`. -/ @[simps] noncomputable @@ -356,6 +358,7 @@ lemma exists_preimage_eq end Opens +set_option backward.isDefEq.respectTransparency.types false in include hc in lemma isAffineHom_π_app [IsCofiltered I] [∀ {i j} (f : i ⟶ j), IsAffineHom (D.map f)] (i : I) : IsAffineHom (c.π.app i) where @@ -1053,6 +1056,7 @@ lemma Scheme.exists_isAffine_of_isLimit [IsCofiltered I] exact ⟨j, ⟨isIso_of_isOpenImmersion_of_opensRange_eq_top _ ((preimage_opensRange_toSpecΓ (D.map fij)).symm.trans hj)⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in include hc in @[stacks 01Z4 "(1)"] diff --git a/Mathlib/AlgebraicGeometry/AlgClosed/Basic.lean b/Mathlib/AlgebraicGeometry/AlgClosed/Basic.lean index eb685a5d628f8f..06fdb9596096f5 100644 --- a/Mathlib/AlgebraicGeometry/AlgClosed/Basic.lean +++ b/Mathlib/AlgebraicGeometry/AlgClosed/Basic.lean @@ -60,6 +60,7 @@ lemma pointOfClosedPoint_comp : pointOfClosedPoint f x hx ≫ f = 𝟙 _ := by lemma pointOfClosedPoint_apply (a : _) : pointOfClosedPoint f x hx a = x := by simp [pointOfClosedPoint] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `k` is algebraically closed, then the closed points of `X` are in bijection with the `k`-points of `X`. -/ @@ -85,6 +86,7 @@ def pointEquivClosedPoint : rw [reassoc_of% Scheme.descResidueField_stalkClosedPointTo_fromSpecResidueField, p.2] right_inv x := by simp +set_option backward.isDefEq.respectTransparency.types false in lemma ext_of_apply_closedPoint_eq {f g : Spec (.of K) ⟶ X} (h : X ⟶ Spec (.of K)) [LocallyOfFiniteType h] @@ -92,6 +94,7 @@ lemma ext_of_apply_closedPoint_eq (H : f (IsLocalRing.closedPoint K) = g (IsLocalRing.closedPoint K)) : f = g := congr($((pointEquivClosedPoint h).injective (a₁ := ⟨f, hf⟩) (a₂ := ⟨g, hg⟩) (Subtype.ext H)).1) +set_option backward.isDefEq.respectTransparency.types false in /-- Let `X` and `Y` be locally of finite type `K`-schemes with `K` algebraically closed and `Y` separated over `K`. Suppose `X` is reduced, then two `K`-morphisms `f g : X ⟶ Y` are equal if they are equal on the closed points of a dense locally closed subset of `X`. -/ diff --git a/Mathlib/AlgebraicGeometry/Artinian.lean b/Mathlib/AlgebraicGeometry/Artinian.lean index 4fb8016f87be0c..f465a94b506c1e 100644 --- a/Mathlib/AlgebraicGeometry/Artinian.lean +++ b/Mathlib/AlgebraicGeometry/Artinian.lean @@ -131,6 +131,7 @@ theorem isLocallyArtinian_iff_openCover (𝒰 : X.OpenCover) : obtain ⟨i, x, rfl⟩ := 𝒰.exists_eq x simpa using (𝒰.f i).isOpenEmbedding.isOpenMap _ (isOpen_discrete {x}) +set_option backward.isDefEq.respectTransparency.types false in theorem isLocallyArtinian_iff_of_isOpenCover {ι : Type*} {U : ι → X.Opens} (hU : TopologicalSpace.IsOpenCover U) (hU' : ∀ i, IsAffineOpen (U i)) : IsLocallyArtinian X ↔ ∀ i, IsArtinianRing Γ(X, U i) := by @@ -141,6 +142,7 @@ theorem isLocallyArtinian_iff_of_isOpenCover {ι : Type*} {U : ι → X.Opens} instance (priority := low) {X : Scheme} [IsEmpty X] : IsLocallyArtinian X where +set_option backward.isDefEq.respectTransparency.types false in instance (priority := low) {X : Scheme} [DiscreteTopology X] [IsReduced X] : IsLocallyArtinian X := by wlog hX : Subsingleton X generalizing X diff --git a/Mathlib/AlgebraicGeometry/Birational/Birational.lean b/Mathlib/AlgebraicGeometry/Birational/Birational.lean index a191e2e295f390..78980dd602d023 100644 --- a/Mathlib/AlgebraicGeometry/Birational/Birational.lean +++ b/Mathlib/AlgebraicGeometry/Birational/Birational.lean @@ -282,6 +282,7 @@ noncomputable def Hom.partialIso (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f lemma Hom.birational (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] : Birational U X := ⟨f.partialIso⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma Hom.birationalOver (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] (sX : X ⟶ S) (sU : U ⟶ S) (hf : f ≫ sX = sU) : BirationalOver sU sX := diff --git a/Mathlib/AlgebraicGeometry/Birational/Composition.lean b/Mathlib/AlgebraicGeometry/Birational/Composition.lean index 852abbeadf6a90..6a924f6f6953a0 100644 --- a/Mathlib/AlgebraicGeometry/Birational/Composition.lean +++ b/Mathlib/AlgebraicGeometry/Birational/Composition.lean @@ -54,6 +54,7 @@ noncomputable def comp (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap f.hom.denseRange.inter_open_nonempty _ g.domain.2 g.dense_domain.nonempty hom := (f.domain.ι.isoImage _).inv ≫ f.hom ∣_ g.domain ≫ g.hom +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in lemma comp_restrict_left (f : X.PartialMap Y) [IsDominant f.hom] (U : X.Opens) (hU : Dense (U : Set X)) (hU' : U ≤ f.domain) (g : Y.PartialMap Z) : @@ -63,6 +64,7 @@ lemma comp_restrict_left (f : X.PartialMap Y) [IsDominant f.hom] (U : X.Opens) · simp [ι_image_homOfLE_eq_ι_image_inf] · simp [morphismRestrict_comp, isoImage_ι_inv_morphismRestrict_homOfLE_assoc, isoOfEq_hom] +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in lemma comp_restrict_right (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) (V : Y.Opens) (hV : Dense (V : Set Y)) (hV' : V ≤ g.domain) : @@ -112,6 +114,7 @@ instance isDominant_comp_hom (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.Part have := IsZariskiLocalAtTarget.restrict ‹IsDominant f.hom› g.domain infer_instance +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma comp_assoc {X₁ X₂ X₃ Y : Scheme.{u}} [PreirreducibleSpace X₁] [IrreducibleSpace X₂] @@ -129,6 +132,7 @@ lemma comp_assoc {X₁ X₂ X₃ Y : Scheme.{u}} [PreirreducibleSpace X₁] [Irr congr 1 simp [← cancel_mono (Opens.ι _)] +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma comp_toPartialMap (f : X.PartialMap Y) [IsDominant f.hom] (g : Y ⟶ Z) : @@ -137,7 +141,6 @@ lemma comp_toPartialMap (f : X.PartialMap Y) [IsDominant f.hom] (g : Y ⟶ Z) : · simp · simp_rw [comp_hom, Hom.toPartialMap_domain, Hom.toPartialMap_hom, compHom_hom, topIso_hom, morphismRestrict_ι_assoc, f.domain.isoImage_ι_inv_ι_assoc, isoOfEq_hom] - rfl set_option backward.defeqAttrib.useBackward true in lemma comp_id (f : X.PartialMap Y) [IsDominant f.hom] : f.comp (PartialMap.id Y) = f := by simp diff --git a/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean b/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean index 4a0717389ddacb..6742dba156a73d 100644 --- a/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean +++ b/Mathlib/AlgebraicGeometry/Birational/RationalMap.lean @@ -89,10 +89,12 @@ set_option backward.defeqAttrib.useBackward true in lemma restrict_id (f : X.PartialMap Y) : f.restrict f.domain f.dense_domain le_rfl = f := by ext1 <;> simp [restrict_domain] +set_option backward.isDefEq.respectTransparency.types false in lemma restrict_id_hom (f : X.PartialMap Y) : (f.restrict f.domain f.dense_domain le_rfl).hom = f.hom := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma restrict_restrict (f : X.PartialMap Y) @@ -101,6 +103,7 @@ lemma restrict_restrict (f : X.PartialMap Y) (f.restrict U hU hU').restrict V hV hV' = f.restrict V hV (hV'.trans hU') := by ext1 <;> simp [restrict_domain] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma restrict_restrict_hom (f : X.PartialMap Y) (U : X.Opens) (hU : Dense (U : Set X)) (hU' : U ≤ f.domain) @@ -147,6 +150,7 @@ variable (X) in /-- The identity partial map. -/ protected abbrev id : X.PartialMap X := (𝟙 X : X ⟶ X).toPartialMap +set_option backward.isDefEq.respectTransparency false in @[simp] lemma id_compHom (f : X ⟶ Y) : (PartialMap.id X).compHom f = f.toPartialMap := by apply PartialMap.ext _ _ rfl @@ -160,6 +164,7 @@ lemma isOver_iff [X.Over S] [Y.Over S] {f : X.PartialMap Y} : f.IsOver S ↔ (f.compHom (Y ↘ S)).hom = f.domain.ι ≫ X ↘ S := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isOver_iff_eq_restrict [X.Over S] [Y.Over S] {f : X.PartialMap Y} : f.IsOver S ↔ f.compHom (Y ↘ S) = (X ↘ S).toPartialMap.restrict _ f.dense_domain (by simp) := by @@ -237,6 +242,7 @@ lemma fromSpecStalkOfMem_compHom (f : X.PartialMap Y) (g : Y ⟶ Z) (x) (hx) : (f.compHom g).fromSpecStalkOfMem (x := x) hx = f.fromSpecStalkOfMem hx ≫ g := by simp [fromSpecStalkOfMem] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma fromSpecStalkOfMem_toPartialMap (f : X ⟶ Y) (x) : @@ -256,6 +262,7 @@ lemma equiv_of_restrict_eq (f g : X.PartialMap Y) {W₁ W₂ : X.Opens} {hW₁ : subst e exact ⟨W₁, hW₁, hW₁', hW₂', congr($(H).hom)⟩ +set_option backward.isDefEq.respectTransparency false in @[refl] lemma equiv.refl (f : X.PartialMap Y) : f.equiv f := ⟨f.domain, f.dense_domain, by simp⟩ @@ -283,6 +290,7 @@ lemma equivalence_rel : Equivalence (@Scheme.PartialMap.equiv X Y) where instance : Setoid (X.PartialMap Y) := ⟨@PartialMap.equiv X Y, equivalence_rel⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma restrict_equiv (f : X.PartialMap Y) (U : X.Opens) (hU : Dense (U : Set X)) (hU' : U ≤ f.domain) : (f.restrict U hU hU').equiv f := @@ -347,6 +355,7 @@ lemma equiv_iff_of_domain_eq_of_isSeparated [X.Over S] [Y.Over S] [IsReduced X] obtain rfl : Uf = Ug := hfg simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A partial map from a reduced scheme to a separated scheme is equivalent to a morphism if and only if it is equal to the restriction of the morphism. -/ @@ -421,6 +430,7 @@ lemma RationalMap.exists_partialMap_over [X.Over S] [Y.Over S] (f : X ⤏ Y) [f. ∃ g : X.PartialMap Y, g.IsOver S ∧ g.toRationalMap = f := IsOver.exists_partialMap_over +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The composition of a rational map and a morphism on the right. -/ def RationalMap.compHom (f : X ⤏ Y) (g : Y ⟶ Z) : X ⤏ Z := by @@ -454,6 +464,7 @@ lemma PartialMap.exists_restrict_isOver [X.Over S] [Y.Over S] (f : X.PartialMap obtain ⟨U, hU, hUl, hUr, e⟩ := PartialMap.toRationalMap_eq_iff.mp hf₂ exact ⟨U, hU, hUr, by rw [IsOver, ← e]; infer_instance⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma RationalMap.isOver_iff [X.Over S] [Y.Over S] {f : X ⤏ Y} : f.IsOver S ↔ f.compHom (Y ↘ S) = (X ↘ S).toRationalMap := by @@ -518,6 +529,7 @@ lemma RationalMap.eq_of_fromFunctionField_eq [IsIntegral X] (f g : X.RationalMap refine PartialMap.toRationalMap_eq_iff.mpr ?_ exact PartialMap.equiv_of_fromSpecStalkOfMem_eq _ _ _ _ H +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `S`-schemes `X` and `Y` such that `Y` is locally of finite type and `X` is integral, @@ -615,6 +627,7 @@ lemma PartialMap.toPartialMap_toRationalMap_restrict [IsReduced X] [Y.IsSeparate (toRationalMap_eq_iff.mp H.choose_spec.1) exact ((ext_iff _ _).mp this.symm).choose_spec.symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma RationalMap.toRationalMap_toPartialMap [IsReduced X] [Y.IsSeparated] diff --git a/Mathlib/AlgebraicGeometry/Cover/Directed.lean b/Mathlib/AlgebraicGeometry/Cover/Directed.lean index fe9840a3d15876..121b3fdc57af59 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Directed.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Directed.lean @@ -228,6 +228,7 @@ lemma map_glueMorphismsOfLocallyDirected {Y : Scheme.{u}} (g : ∀ i, 𝒰.X i 𝒰.f i ≫ 𝒰.glueMorphismsOfLocallyDirected g h = g i := by simp [glueMorphismsOfLocallyDirected] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `𝒰` is an open cover of `X` that is locally directed, `X` is the colimit of the components of `𝒰`. -/ @@ -258,9 +259,10 @@ lemma map_glueMorphismsOverOfLocallyDirected_left {S : Scheme.{u}} {X : Over S} end OpenCover +set_option backward.isDefEq.respectTransparency.types false in /-- If `𝒰` is an open cover such that the images of the components form a basis of the topology of `X`, `𝒰` is directed by the ordering of subset inclusion of the images. -/ -@[implicit_reducible] +@[instance_reducible] def Cover.LocallyDirected.ofIsBasisOpensRange {𝒰 : X.OpenCover} [Preorder 𝒰.I₀] (hle : ∀ {i j : 𝒰.I₀}, i ≤ j ↔ (𝒰.f i).opensRange ≤ (𝒰.f j).opensRange) (H : TopologicalSpace.Opens.IsBasis (Set.range <| fun i ↦ (𝒰.f i).opensRange)) : @@ -293,6 +295,7 @@ lemma Cover.LocallyDirected.ofIsBasisOpensRange_le_iff (i j : 𝒰.I₀) : letI := Cover.LocallyDirected.ofIsBasisOpensRange hle H i ≤ j ↔ (𝒰.f i).opensRange ≤ (𝒰.f j).opensRange := hle +set_option backward.isDefEq.respectTransparency.types false in lemma Cover.LocallyDirected.ofIsBasisOpensRange_trans {i j : 𝒰.I₀} : letI := Cover.LocallyDirected.ofIsBasisOpensRange hle H (hij : i ≤ j) → 𝒰.trans (homOfLE hij) = IsOpenImmersion.lift (𝒰.f j) (𝒰.f i) (hle.mp hij) := @@ -317,12 +320,14 @@ def directedAffineCover : X.OpenCover where instance : Preorder X.directedAffineCover.I₀ := inferInstanceAs <| Preorder X.affineOpens +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Scheme.Cover.LocallyDirected X.directedAffineCover := .ofIsBasisOpensRange (by intros; simp; rfl) <| by convert! X.isBasis_affineOpens simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma directedAffineCover_trans {U V : X.affineOpens} (hUV : U ≤ V) : Cover.trans X.directedAffineCover (homOfLE hUV) = X.homOfLE hUV := rfl diff --git a/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean b/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean index 533fbe95d15a9b..fe84c8700dc990 100644 --- a/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean +++ b/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean @@ -151,8 +151,12 @@ def Cover.copy [P.RespectsIso] {X : Scheme.{u}} (𝒰 : X.Cover (precoverage P)) intro i exact 𝒰.map_prop _ +-- `respectTransparency false` is needed for `simps!`. +-- Consider making implicit-reducible: +-- `Precoverage.ZeroHypercover.bind`, `Cover.mkOfCovers`, `coverOfIso` +set_option backward.isDefEq.respectTransparency false in /-- The pushforward of a cover along an isomorphism. -/ -@[simps! I₀ X f] +@[simps! I₀ X f, implicit_reducible] def Cover.pushforwardIso [P.RespectsIso] [P.ContainsIdentities] [P.IsStableUnderComposition] {X Y : Scheme.{u}} (𝒰 : Cover.{v} (precoverage P) X) (f : X ⟶ Y) [IsIso f] : Cover.{v} (precoverage P) Y := diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index 7d4cf90cf18dc8..f776366f95300a 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -300,6 +300,7 @@ theorem affineBasisCover_map_range (X : Scheme.{u}) (x : X) congr exact (PrimeSpectrum.localization_away_comap_range (Localization.Away r) r :) +set_option backward.isDefEq.respectTransparency.types false in theorem affineBasisCover_is_basis (X : Scheme.{u}) : TopologicalSpace.IsTopologicalBasis {x : Set X | diff --git a/Mathlib/AlgebraicGeometry/Cover/Over.lean b/Mathlib/AlgebraicGeometry/Cover/Over.lean index 6c01bf3df1f520..12498f90327b2d 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Over.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Over.lean @@ -89,6 +89,7 @@ def Cover.pullbackCoverOver : W.Cover (precoverage P) where instance (j : 𝒰.I₀) : ((𝒰.pullbackCoverOver S f).X j).Over S where hom := (pullback (f.asOver S) ((𝒰.f j).asOver S)).hom +set_option backward.isDefEq.respectTransparency.types false in instance : (𝒰.pullbackCoverOver S f).Over S where isOver_map j := { comp_over := by exact Over.w (pullback.fst (f.asOver S) ((𝒰.f j).asOver S)) } @@ -115,6 +116,7 @@ def Cover.pullbackCoverOver' : W.Cover (precoverage P) where instance (j : 𝒰.I₀) : ((𝒰.pullbackCoverOver' S f).X j).Over S where hom := (pullback ((𝒰.f j).asOver S) (f.asOver S)).hom +set_option backward.isDefEq.respectTransparency.types false in instance : (𝒰.pullbackCoverOver' S f).Over S where isOver_map j := { comp_over := by exact Over.w (pullback.snd ((𝒰.f j).asOver S) (f.asOver S)) } @@ -153,6 +155,7 @@ instance (j : 𝒰.I₀) : ((𝒰.pullbackCoverOverProp S f hX hW hQ).X j).Over hom := (pullback (f.asOverProp (hX := hW) (hY := hX) S) ((𝒰.f j).asOverProp (hX := hQ j) (hY := hX) S)).hom +set_option backward.isDefEq.respectTransparency.types false in instance : (𝒰.pullbackCoverOverProp S f hX hW hQ).Over S where isOver_map j := { comp_over := by exact (pullback.fst (f.asOverProp S) ((𝒰.f j).asOverProp S)).w } @@ -185,6 +188,7 @@ instance (j : 𝒰.I₀) : ((𝒰.pullbackCoverOverProp' S f hX hW hQ).X j).Over hom := (pullback ((𝒰.f j).asOverProp (hX := hQ j) (hY := hX) S) (f.asOverProp (hX := hW) (hY := hX) S)).hom +set_option backward.isDefEq.respectTransparency.types false in instance : (𝒰.pullbackCoverOverProp' S f hX hW hQ).Over S where isOver_map j := { comp_over := by exact (pullback.snd ((𝒰.f j).asOverProp S) (f.asOverProp S)).w } @@ -198,6 +202,7 @@ variable {X : Scheme.{u}} (𝒰 : X.Cover (precoverage P)) (𝒱 : ∀ x, (𝒰. instance (j : (𝒰.bind 𝒱).I₀) : ((𝒰.bind 𝒱).X j).Over S := inferInstanceAs <| ((𝒱 j.1).X j.2).Over S +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {X : Scheme.{u}} (𝒰 : X.Cover (precoverage P)) (𝒱 : ∀ x, (𝒰.X x).Cover (precoverage P)) [X.Over S] [𝒰.Over S] [∀ x, (𝒱 x).Over S] : Cover.Over S (𝒰.bind 𝒱) where diff --git a/Mathlib/AlgebraicGeometry/Cover/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Cover/QuasiCompact.lean index ea345eee74d357..415ab1694207ed 100644 --- a/Mathlib/AlgebraicGeometry/Cover/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Cover/QuasiCompact.lean @@ -144,6 +144,7 @@ instance of_finite {𝒰 : S.Cover K} [Scheme.JointlySurjective K] refine .of_finite_of_isSpectralMap (fun i ↦ (𝒰.f i).isSpectralMap) ?_ U.2 hU.isCompact exact (fun x _ ↦ ⟨𝒰.idx x, 𝒰.covers x⟩) +set_option backward.isDefEq.respectTransparency.types false in instance [IsAffine S] {P : MorphismProperty Scheme.{u}} (𝒰 : S.AffineCover P) [Finite 𝒰.I₀] : QuasiCompactCover 𝒰.cover.toPreZeroHypercover := haveI : Finite 𝒰.cover.I₀ := ‹_› diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean index 6adf1fe57679c8..a65a2ff44f8272 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean @@ -104,12 +104,19 @@ lemma Y_sub_polynomialY : Y - W'.polynomialY = W'.negPolynomial := by lemma Y_sub_negPolynomial : Y - W'.negPolynomial = W'.polynomialY := by rw [← Y_sub_polynomialY, sub_sub_cancel] +#adaptation_note +/-- +Without this `implicit_reducible` attribute, `simpNF` gives a linter error on `slope_of_Y_eq` +because of a nonconfluence: `negY` can be unfolded on the LHS, which prevents discharging the +side condition of `slope_of_Y_eq` -- except if `negY` is implicit-reducible. +So this attribute improves the confluence of `simp`. +-/ variable (W') in /-- The `Y`-coordinate of `-(x, y)` for a nonsingular affine point `(x, y)` on a Weierstrass curve `W`. This depends on `W`, and has argument order: `x`, `y`. -/ -@[simp] +@[simp, implicit_reducible] def negY (x y : R) : R := -y - W'.a₁ * x - W'.a₃ diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean index 5e2d6d1ff2f2c2..d9f1b1fde1b2ea 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean @@ -118,6 +118,7 @@ protected noncomputable def basis : Basis (Fin 2) R[X] W'.CoordinateRing := (subsingleton_or_nontrivial R).by_cases (fun _ => default) fun _ => (AdjoinRoot.powerBasis' monic_polynomial).basis.reindex <| finCongr natDegree_polynomial +set_option backward.isDefEq.respectTransparency.types false in lemma basis_apply (n : Fin 2) : CoordinateRing.basis W' n = (AdjoinRoot.powerBasis' monic_polynomial).gen ^ (n : ℕ) := by classical @@ -241,6 +242,7 @@ variable (W') in noncomputable def XYIdeal (x : R) (y : R[X]) : Ideal W'.CoordinateRing := .span {XClass W' x, YClass W' y} +set_option backward.isDefEq.respectTransparency.types false in /-- The `R`-algebra isomorphism from `R[W] / ⟨X - x, Y - y(X)⟩` to `R` obtained by evaluation at some `y(X)` in `R[X]` and at some `x` in `R` provided that `W(x, y(x)) = 0`. -/ noncomputable def quotientXYIdealEquiv {x : R} {y : R[X]} (h : (W'.polynomial.eval y).eval x = 0) : @@ -707,6 +709,7 @@ lemma add_of_X_ne' {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h some _ _ h₁ + some _ _ h₂ = -some _ _ (nonsingular_negAdd h₁ h₂ fun hxy => hx hxy.left) := add_of_X_ne hx +set_option backward.isDefEq.respectTransparency.types false in /-- The group homomorphism mapping a nonsingular affine point `(x, y)` of a Weierstrass curve `W` to the class of the non-zero fractional ideal `⟨X - x, Y - y⟩` in the ideal class group of `F[W]`. -/ @[simps] diff --git a/Mathlib/AlgebraicGeometry/Fiber.lean b/Mathlib/AlgebraicGeometry/Fiber.lean index 186ddc1e9f5700..e58fc93fbd26af 100644 --- a/Mathlib/AlgebraicGeometry/Fiber.lean +++ b/Mathlib/AlgebraicGeometry/Fiber.lean @@ -95,6 +95,7 @@ lemma Scheme.Hom.range_fiberι (f : X ⟶ Y) (y : Y) : Set.range (f.fiberι y) = f ⁻¹' {y} := by simp [fiber, fiberι, Scheme.Pullback.range_fst, Scheme.range_fromSpecResidueField] +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (y : Y) : IsPreimmersion (f.fiberι y) := MorphismProperty.pullback_fst _ _ inferInstance @@ -119,6 +120,7 @@ def Scheme.Hom.asFiber (f : X ⟶ Y) (x : X) : f.fiber (f x) := lemma Scheme.Hom.fiberι_asFiber (f : X ⟶ Y) (x : X) : f.fiberι _ (f.asFiber x) = x := f.fiberι_fiberHomeo_symm _ _ +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) [QuasiCompact f] (y : Y) : CompactSpace (f.fiber y) := haveI : QuasiCompact (f.fiberToSpecResidueField y) := MorphismProperty.pullback_snd _ _ inferInstance @@ -132,11 +134,13 @@ lemma Scheme.Hom.isCompact_preimage_singleton (f : X ⟶ Y) [QuasiCompact f] (y @[deprecated (since := "2026-02-05")] alias QuasiCompact.isCompact_preimage_singleton := Scheme.Hom.isCompact_preimage_singleton +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) [IsAffineHom f] (y : Y) : IsAffine (f.fiber y) := haveI : IsAffineHom (f.fiberToSpecResidueField y) := MorphismProperty.pullback_snd _ _ inferInstance isAffine_of_isAffineHom (f.fiberToSpecResidueField y) +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (y : Y) [LocallyOfFiniteType f] : JacobsonSpace (f.fiber y) := have : LocallyOfFiniteType (f.fiberToSpecResidueField y) := MorphismProperty.pullback_snd _ _ inferInstance diff --git a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean index 53e9b03f6e29ac..aa0d42e7e47967 100644 --- a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean +++ b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean @@ -125,6 +125,7 @@ theorem isUnit_res_toΓSpecMapBasicOpen : IsUnit (X.toToΓSpecMapBasicOpen r r) rw [← CommRingCat.comp_apply, ← Functor.map_comp] congr +set_option backward.isDefEq.respectTransparency.types false in /-- Define the sheaf hom on individual basic opens for the unit. -/ def toΓSpecCApp : (structureSheaf <| Γ.obj <| op X).obj.obj (op <| basicOpen r) ⟶ @@ -191,6 +192,7 @@ theorem toΓSpecSheafedSpace_app_eq : X.toΓSpecSheafedSpace.hom.c.app (op (basicOpen r)) = X.toΓSpecCApp r := by apply TopCat.Sheaf.extend_hom_app _ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] theorem toΓSpecSheafedSpace_app_spec (r : Γ.obj (op X)) : CommRingCat.ofHom (algebraMap (Γ.obj (op X)) _) ≫ X.toΓSpecSheafedSpace.hom.c.app (op (basicOpen r)) = @@ -252,6 +254,7 @@ lemma toΓSpec_preimage_zeroLocus_eq {X : LocallyRingedSpace.{u}} rw [← PrimeSpectrum.zeroLocus_iUnion₂] simp +set_option backward.isDefEq.respectTransparency.types false in theorem comp_ring_hom_ext {X : LocallyRingedSpace.{u}} {R : CommRingCat.{u}} {f : R ⟶ Γ.obj (op X)} {β : X ⟶ Spec.locallyRingedSpaceObj R} (w : X.toΓSpec.base ≫ (Spec.locallyRingedSpaceMap f).base = β.base) @@ -269,6 +272,7 @@ theorem comp_ring_hom_ext {X : LocallyRingedSpace.{u}} {R : CommRingCat.{u}} {f erw [toΓSpecSheafedSpace_app_spec, ← X.presheaf.map_comp] exact h r +set_option backward.isDefEq.respectTransparency.types false in /-- `toSpecΓ _` is an isomorphism so these are mutually two-sided inverses. -/ theorem Γ_Spec_left_triangle : toSpecΓ (Γ.obj (op X)) ≫ X.toΓSpec.c.app (op ⊤) = 𝟙 _ := by unfold toSpecΓ @@ -303,6 +307,7 @@ def identityToΓSpec : 𝟭 LocallyRingedSpace.{u} ⟶ Γ.rightOp ⋙ Spec.toLoc namespace ΓSpec +set_option backward.isDefEq.respectTransparency.types false in theorem left_triangle (X : LocallyRingedSpace) : SpecΓIdentity.inv.app (Γ.obj (op X)) ≫ (identityToΓSpec.app X).c.app (op ⊤) = 𝟙 _ := X.Γ_Spec_left_triangle @@ -333,27 +338,31 @@ def locallyRingedSpaceAdjunction : Γ.rightOp ⊣ Spec.toLocallyRingedSpace.{u} Quiver.Hom.unop_op, NatIso.op_inv, NatTrans.op_app, SpecΓIdentity_inv_app] exact congr_arg Quiver.Hom.op (left_triangle X) right_triangle_components R := by - simp only [Functor.id_obj, NatIso.op_inv, NatTrans.op_app, SpecΓIdentity_inv_app, - Spec.toLocallyRingedSpace_map] + simp only [Functor.id_obj, NatIso.op_inv, NatTrans.op_app, SpecΓIdentity_inv_app] exact right_triangle R.unop +set_option backward.isDefEq.respectTransparency.types false in lemma toSpecΓ_unop (R : CommRingCatᵒᵖ) : AlgebraicGeometry.toSpecΓ (Opposite.unop R) = CommRingCat.ofHom (algebraMap _ _) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `@[simp]`-normal form of `locallyRingedSpaceAdjunction_counit_app'`. -/ @[simp] lemma toSpecΓ_of (R : Type u) [CommRing R] : AlgebraicGeometry.toSpecΓ (CommRingCat.of R) = CommRingCat.ofHom (algebraMap _ _) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma locallyRingedSpaceAdjunction_counit_app (R : CommRingCatᵒᵖ) : locallyRingedSpaceAdjunction.counit.app R = (CommRingCat.ofHom (algebraMap _ _)).op := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma locallyRingedSpaceAdjunction_counit_app' (R : Type u) [CommRing R] : locallyRingedSpaceAdjunction.counit.app (op <| CommRingCat.of R) = (CommRingCat.ofHom (algebraMap _ _)).op := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma unop_locallyRingedSpaceAdjunction_counit_app' (R : Type u) [CommRing R] : (locallyRingedSpaceAdjunction.counit.app (op <| CommRingCat.of R)).unop = (CommRingCat.ofHom (algebraMap _ _)) := rfl @@ -443,6 +452,7 @@ instance isIso_adjunction_counit : IsIso ΓSpec.adjunction.counit := by end ΓSpec +set_option backward.isDefEq.respectTransparency.types false in theorem Scheme.toSpecΓ_apply (X : Scheme.{u}) (x) : Scheme.toSpecΓ X x = Spec.map (X.presheaf.Γgerm x) (IsLocalRing.closedPoint _) := rfl diff --git a/Mathlib/AlgebraicGeometry/Geometrically/Basic.lean b/Mathlib/AlgebraicGeometry/Geometrically/Basic.lean index b6c245a2f37e03..e9deefedb33d94 100644 --- a/Mathlib/AlgebraicGeometry/Geometrically/Basic.lean +++ b/Mathlib/AlgebraicGeometry/Geometrically/Basic.lean @@ -57,6 +57,7 @@ lemma geometrically_eq_universally (P : ObjectProperty Scheme.{u}) : apply h.flip.of_iso (.refl _) (.refl _) W.isoSpec (.refl _) <;> simp · exact hf _ _ _ h.flip inferInstance inferInstance +set_option backward.isDefEq.respectTransparency.types false in lemma geometrically_inf (P Q : ObjectProperty Scheme.{u}) : geometrically (P ⊓ Q) = geometrically P ⊓ geometrically Q := by simp only [geometrically_eq_universally, ← MorphismProperty.universally_inf] @@ -65,6 +66,7 @@ lemma geometrically_inf (P Q : ObjectProperty Scheme.{u}) : variable (P : ObjectProperty Scheme.{u}) +set_option backward.isDefEq.respectTransparency.types false in instance : (geometrically P).IsStableUnderBaseChange := by rw [geometrically_eq_universally] infer_instance diff --git a/Mathlib/AlgebraicGeometry/Geometrically/Connected.lean b/Mathlib/AlgebraicGeometry/Geometrically/Connected.lean index a2d29f1a5e128c..060f361329b5ed 100644 --- a/Mathlib/AlgebraicGeometry/Geometrically/Connected.lean +++ b/Mathlib/AlgebraicGeometry/Geometrically/Connected.lean @@ -47,15 +47,18 @@ lemma GeometricallyConnected.eq_geometrically : instance : IsStableUnderBaseChange @GeometricallyConnected := GeometricallyConnected.eq_geometrically ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyConnected g] : GeometricallyConnected (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyConnected f] : GeometricallyConnected (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance instance (V : S.Opens) [GeometricallyConnected f] : GeometricallyConnected (f ∣_ V) := MorphismProperty.of_isPullback (isPullback_morphismRestrict ..).flip ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (s : S) [GeometricallyConnected f] : GeometricallyConnected (f.fiberToSpecResidueField s) := MorphismProperty.pullback_snd _ _ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Geometrically/Integral.lean b/Mathlib/AlgebraicGeometry/Geometrically/Integral.lean index 9755185a422c12..2dc55ece5e133f 100644 --- a/Mathlib/AlgebraicGeometry/Geometrically/Integral.lean +++ b/Mathlib/AlgebraicGeometry/Geometrically/Integral.lean @@ -66,15 +66,18 @@ lemma GeometricallyIntegral.of_geometricallyReduced_of_geometricallyIrreducible instance : IsStableUnderBaseChange @GeometricallyIntegral := GeometricallyIntegral.eq_geometrically ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyIntegral g] : GeometricallyIntegral (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyIntegral f] : GeometricallyIntegral (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance instance (V : S.Opens) [GeometricallyIntegral f] : GeometricallyIntegral (f ∣_ V) := MorphismProperty.of_isPullback (isPullback_morphismRestrict ..).flip ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (s : S) [GeometricallyIntegral f] : GeometricallyIntegral (f.fiberToSpecResidueField s) := MorphismProperty.pullback_snd _ _ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Geometrically/Irreducible.lean b/Mathlib/AlgebraicGeometry/Geometrically/Irreducible.lean index d52551a96300e8..0a421c973f5ea2 100644 --- a/Mathlib/AlgebraicGeometry/Geometrically/Irreducible.lean +++ b/Mathlib/AlgebraicGeometry/Geometrically/Irreducible.lean @@ -49,15 +49,18 @@ lemma GeometricallyIrreducible.eq_geometrically : instance : IsStableUnderBaseChange @GeometricallyIrreducible := GeometricallyIrreducible.eq_geometrically ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyIrreducible g] : GeometricallyIrreducible (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyIrreducible f] : GeometricallyIrreducible (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance instance (V : S.Opens) [GeometricallyIrreducible f] : GeometricallyIrreducible (f ∣_ V) := MorphismProperty.of_isPullback (isPullback_morphismRestrict ..).flip ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (s : S) [GeometricallyIrreducible f] : GeometricallyIrreducible (f.fiberToSpecResidueField s) := MorphismProperty.pullback_snd _ _ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Geometrically/Reduced.lean b/Mathlib/AlgebraicGeometry/Geometrically/Reduced.lean index 4ec04afaef6caf..5934193fc589df 100644 --- a/Mathlib/AlgebraicGeometry/Geometrically/Reduced.lean +++ b/Mathlib/AlgebraicGeometry/Geometrically/Reduced.lean @@ -51,15 +51,18 @@ lemma GeometricallyReduced.eq_geometrically : instance : IsStableUnderBaseChange @GeometricallyReduced := GeometricallyReduced.eq_geometrically ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyReduced g] : GeometricallyReduced (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [GeometricallyReduced f] : GeometricallyReduced (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance instance (V : S.Opens) [GeometricallyReduced f] : GeometricallyReduced (f ∣_ V) := MorphismProperty.of_isPullback (isPullback_morphismRestrict ..).flip ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (s : S) [GeometricallyReduced f] : GeometricallyReduced (f.fiberToSpecResidueField s) := MorphismProperty.pullback_snd _ _ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Gluing.lean b/Mathlib/AlgebraicGeometry/Gluing.lean index 2c642da6af605a..2be5518b2eb191 100644 --- a/Mathlib/AlgebraicGeometry/Gluing.lean +++ b/Mathlib/AlgebraicGeometry/Gluing.lean @@ -140,6 +140,7 @@ def gluedScheme : Scheme := by exact Set.mem_image_of_mem _ ⟨z, hz⟩ · infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : CreatesColimit 𝖣.diagram.multispan forgetToLocallyRingedSpace := createsColimitOfFullyFaithfulOfIso D.gluedScheme (HasColimit.isoOfNatIso (𝖣.diagramIso forgetToLocallyRingedSpace).symm) @@ -205,6 +206,7 @@ def vPullbackConeIsLimit (i j : D.J) : IsLimit (D.vPullbackCone i j) := local notation "D_" => TopCat.GlueData.toGlueData <| D.toLocallyRingedSpaceGlueData.toSheafedSpaceGlueData.toPresheafedSpaceGlueData.toTopGlueData +set_option backward.isDefEq.respectTransparency.types false in /-- The underlying topological space of the glued scheme is isomorphic to the gluing of the underlying spaces -/ def isoCarrier : @@ -239,6 +241,7 @@ See `AlgebraicGeometry.Scheme.GlueData.ι_eq_iff`. -/ def Rel (a b : Σ i, ((D.U i).carrier : Type _)) : Prop := ∃ x : (D.V (a.1, b.1)).carrier, D.f _ _ x = a.2 ∧ (D.t _ _ ≫ D.f _ _) x = b.2 +set_option backward.isDefEq.respectTransparency.types false in theorem ι_eq_iff (i j : D.J) (x : (D.U i).carrier) (y : (D.U j).carrier) : 𝖣.ι i x = 𝖣.ι j y ↔ D.Rel ⟨i, x⟩ ⟨j, y⟩ := by refine Iff.trans ?_ @@ -250,6 +253,7 @@ theorem ι_eq_iff (i j : D.J) (x : (D.U i).carrier) (y : (D.U j).carrier) : rfl -- `rfl` was not needed before https://github.com/leanprover-community/mathlib4/pull/13170 · infer_instance +set_option backward.isDefEq.respectTransparency.types false in theorem isOpen_iff (U : Set D.glued.carrier) : IsOpen U ↔ ∀ i, IsOpen (D.ι i ⁻¹' U) := by rw [← (TopCat.homeoOfIso D.isoCarrier.symm).isOpen_preimage, TopCat.GlueData.isOpen_iff] apply forall_congr' @@ -345,6 +349,7 @@ def gluedCover : Scheme.GlueData.{u} where cocycle x y z := glued_cover_cocycle 𝒰 x y z f_open _ := inferInstance +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical morphism from the gluing of an open cover of `X` into `X`. This is an isomorphism, as witnessed by an `IsIso` instance. -/ def fromGlued : 𝒰.gluedCover.glued ⟶ X := by @@ -358,6 +363,7 @@ def fromGlued : 𝒰.gluedCover.glued ⟶ X := by theorem ι_fromGlued (x : 𝒰.I₀) : 𝒰.gluedCover.ι x ≫ 𝒰.fromGlued = 𝒰.f x := Multicoequalizer.π_desc _ _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem fromGlued_injective : Function.Injective 𝒰.fromGlued := by intro x y h obtain ⟨i, x, rfl⟩ := 𝒰.gluedCover.ι_jointly_surjective x @@ -387,6 +393,7 @@ instance (x : 𝒰.gluedCover.glued.carrier) : rw [this] infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem isOpenMap_fromGlued : IsOpenMap 𝒰.fromGlued := by intro U hU @@ -408,6 +415,7 @@ theorem isOpenMap_fromGlued : IsOpenMap 𝒰.fromGlued := by theorem isOpenEmbedding_fromGlued : IsOpenEmbedding 𝒰.fromGlued := .of_continuous_injective_isOpenMap (by fun_prop) 𝒰.fromGlued_injective 𝒰.isOpenMap_fromGlued +set_option backward.isDefEq.respectTransparency.types false in instance : Epi 𝒰.fromGlued.base := by rw [TopCat.epi_iff_surjective] intro x @@ -428,6 +436,7 @@ instance : IsIso 𝒰.fromGlued := apply PresheafedSpace.IsOpenImmersion.to_iso isIso_of_reflects_iso _ F +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given an open cover of `X`, and a morphism `𝒰.X x ⟶ Y` for each open subscheme in the cover, such that these morphisms are compatible in the intersection (pullback), we may glue the morphisms @@ -616,6 +625,7 @@ def tAux (i j : J) : (V F i j).toScheme ⟶ F.obj j := dsimp [Scheme.Opens.iSupOpenCover] apply fst_inv_eq_snd_inv F +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma homOfLE_tAux (i j : J) {k : J} (fi : k ⟶ i) (fj : k ⟶ j) : (F.obj i).homOfLE (le_iSup_of_le ⟨k, fi, fj⟩ le_rfl) ≫ @@ -699,6 +709,7 @@ def glueData : Scheme.GlueData where ← Iso.inv_comp_eq, Scheme.Hom.isoOpensRange_inv_comp] exact (Scheme.homOfLE_ι _ _).symm +set_option backward.isDefEq.respectTransparency.types false in lemma glueDataι_naturality {i j : Shrink.{u} J} (f : ↓i ⟶ ↓j) : F.map f ≫ (glueData F).ι j = (glueData F).ι i := by have : IsIso (V F ↓i ↓j).ι := by @@ -714,6 +725,7 @@ lemma glueDataι_naturality {i j : Shrink.{u} J} (f : ↓i ⟶ ↓j) : convert! Category.id_comp _ simp [← cancel_mono (Opens.ι _), V] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- (Implementation detail) The cocone associated to a locally directed diagram. @@ -810,6 +822,7 @@ def openCover : (colimit F).OpenCover := change colimit.ι F i = _ ≫ (glueData F).ι (equivShrink J i) ≫ _ simp [← Category.assoc, ← Iso.comp_inv_eq, cocone] +set_option backward.isDefEq.respectTransparency.types false in instance (i) : IsOpenImmersion (colimit.ι F i) := inferInstanceAs (IsOpenImmersion ((openCover F).f i)) diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean index 8f8e1018f242ab..f8b70f4687f63a 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Basic.lean @@ -387,6 +387,7 @@ lemma support_antitone : Antitone (support (X := X)) := by J.coe_support_eq_eq_iInter_zeroLocus] exact Set.iInter_mono fun U ↦ X.zeroLocus_mono (h U) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma support_eq_bot_iff : support I = ⊥ ↔ I = ⊤ := by refine ⟨fun H ↦ top_le_iff.mp fun U ↦ ?_, by simp +contextual⟩ @@ -769,6 +770,7 @@ lemma Hom.range_subset_ker_support (f : X ⟶ Y) : lemma Hom.ker_eq_top_iff_isEmpty (f : X.Hom Y) : f.ker = ⊤ ↔ IsEmpty X := ⟨fun H ↦ by simpa [H] using f.range_subset_ker_support, fun _ ↦ ker_eq_top_of_isEmpty f⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma Hom.iInf_ker_openCover_map_comp_apply (f : X.Hom Y) [QuasiCompact f] (𝒰 : X.OpenCover) (U : Y.affineOpens) : ⨅ i, (𝒰.f i ≫ f).ker.ideal U = f.ker.ideal U := by @@ -839,6 +841,7 @@ lemma ker_ideal_of_isPullback_of_isOpenImmersion {X Y U V : Scheme.{u}} ← CommRingCat.hom_comp, this] simpa using (map_eq_zero_iff _ (ConcreteCategory.bijective_of_isIso e.inv).1).symm +set_option backward.isDefEq.respectTransparency.types false in lemma Hom.support_ker (f : X ⟶ Y) [QuasiCompact f] : f.ker.support = closure (Set.range f) := by apply subset_antisymm diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Functorial.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Functorial.lean index 19f0c8c31c1002..c2ba4d50739f43 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Functorial.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Functorial.lean @@ -100,6 +100,7 @@ lemma _root_.AlgebraicGeometry.isPullback_of_isClosedImmersion def map (I : X.IdealSheafData) (f : X ⟶ Y) : Y.IdealSheafData := (I.subschemeι ≫ f).ker +set_option backward.isDefEq.respectTransparency.types false in lemma le_map_iff_comap_le {I : X.IdealSheafData} {f : X ⟶ Y} {J : Y.IdealSheafData} : J ≤ I.map f ↔ J.comap f ≤ I := by constructor diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean index 275e08d6618fed..4b2d66c3015a88 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean @@ -59,10 +59,12 @@ instance (U : X.affineOpens) : IsPreimmersion (I.glueDataObjι U) := (RingHom.surjectiveOnStalks_of_surjective Ideal.Quotient.mk_surjective) .comp _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma glueDataObjι_ι (U : X.affineOpens) : I.glueDataObjι U ≫ U.1.ι = Spec.map (CommRingCat.ofHom (Ideal.Quotient.mk _)) ≫ U.2.fromSpec := by rw [glueDataObjι, Category.assoc]; rfl +set_option backward.isDefEq.respectTransparency.types false in lemma ker_glueDataObjι_appTop (U : X.affineOpens) : RingHom.ker (I.glueDataObjι U).appTop.hom = (I.ideal U).comap U.1.topIso.hom.hom := by let φ : Γ(X, U) ⟶ CommRingCat.of (Γ(X, U) ⧸ I.ideal U) := @@ -78,6 +80,7 @@ lemma ker_glueDataObjι_appTop (U : X.affineOpens) : rw [← Scheme.Hom.appTop, U.2.isoSpec_inv_appTop, Category.assoc, Iso.inv_hom_id_assoc] simp only [Scheme.Opens.topIso_hom] +set_option backward.isDefEq.respectTransparency.types false in open scoped Set.Notation in lemma range_glueDataObjι (U : X.affineOpens) : Set.range (I.glueDataObjι U) = @@ -88,6 +91,7 @@ lemma range_glueDataObjι (U : X.affineOpens) : simp rfl +set_option backward.isDefEq.respectTransparency.types false in lemma range_glueDataObjι_ι (U : X.affineOpens) : Set.range (I.glueDataObjι U ≫ U.1.ι) = X.zeroLocus (U := U) (I.ideal U) ∩ U := by simp only [Scheme.Hom.comp_base, TopCat.coe_comp, Set.range_comp, range_glueDataObjι] @@ -333,6 +337,7 @@ private lemma ι_gluedTo (U : X.affineOpens) : I.glueData.ι U ≫ I.gluedTo = I.glueDataObjι U ≫ U.1.ι := Multicoequalizer.π_desc _ _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] private lemma glueDataObjMap_ι (U V : X.affineOpens) (h : U ≤ V) : @@ -384,6 +389,7 @@ lemma range_glueDataObjι_ι_eq_support_inter (U : X.affineOpens) : Set.range (I.glueDataObjι U ≫ U.1.ι) = (I.support : Set X) ∩ U := (I.range_glueDataObjι_ι U).trans (I.coe_support_inter U).symm +set_option backward.isDefEq.respectTransparency.types false in lemma range_gluedTo : Set.range I.gluedTo = I.support := by refine subset_antisymm (Set.range_subset_iff.mpr fun x ↦ ?_) ?_ · obtain ⟨ix, x : I.glueDataObj ix, rfl⟩ := @@ -427,6 +433,7 @@ private lemma glueDataObjIso_hom_restrict (U : X.affineOpens) : (I.glueDataObjIso U).hom ≫ I.gluedTo ∣_ ↑U = I.glueDataObjι U := by rw [← cancel_mono U.1.ι]; simp +set_option backward.isDefEq.respectTransparency.types false in instance : IsPreimmersion I.gluedTo := by rw [IsZariskiLocalAtTarget.iff_of_iSup_eq_top (P := @IsPreimmersion) _ (iSup_affineOpens_eq_top X)] @@ -460,6 +467,7 @@ def subschemeIso : I.subscheme ≅ I.glueData.glued := letI := IsOpenImmersion.isIso F asIso F +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion from the subscheme associated to an ideal sheaf. -/ noncomputable def subschemeι : I.subscheme ⟶ X := @@ -486,6 +494,7 @@ instance : QuasiCompact I.subschemeι := by lemma range_subschemeι : Set.range I.subschemeι = I.support := by simp [← range_gluedTo, I.subschemeι_def, Set.range_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in private lemma opensRange_glueData_ι_subschemeIso_inv (U : X.affineOpens) : (I.glueData.ι U ≫ I.subschemeIso.inv).opensRange = I.subschemeι ⁻¹ᵁ U := by @@ -507,6 +516,7 @@ def subschemeCover : I.subscheme.AffineOpenCover where (X.openCoverOfIsOpenCover _ (iSup_affineOpens_eq_top X)).covers x.1 exact (I.opensRange_glueData_ι_subschemeIso_inv U).ge hy +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma opensRange_subschemeCover_map (U : X.affineOpens) : (I.subschemeCover.f U).opensRange = I.subschemeι ⁻¹ᵁ U := @@ -619,6 +629,7 @@ lemma inclusion_subschemeι {I J : IdealSheafData X} (h : I ≤ J) : inclusion h ≫ I.subschemeι = J.subschemeι := J.subschemeCover.openCover.hom_ext _ _ fun _ ↦ by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp, reassoc] lemma inclusion_id (I : IdealSheafData X) : @@ -631,6 +642,7 @@ lemma inclusion_comp {I J K : IdealSheafData X} (h₁ : I ≤ J) (h₂ : J ≤ K inclusion h₂ ≫ inclusion h₁ = inclusion (h₁.trans h₂) := K.subschemeCover.openCover.hom_ext _ _ fun _ ↦ by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor taking an ideal sheaf to its associated subscheme. -/ @[simps] @@ -764,6 +776,7 @@ def kerAdjunction (Y : Scheme.{u}) : (subschemeFunctor Y).rightOp ⊣ Y.kerFunct counit.naturality _ _ _ := Quiver.Hom.unop_inj (by ext1; simp [← cancel_mono (subschemeι _)]) left_triangle_components I := Quiver.Hom.unop_inj (by ext1; simp [← cancel_mono (subschemeι _)]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : (IdealSheafData.subschemeFunctor Y).Full := have : IsIso Y.kerAdjunction.rightOp.counit := by diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index 1c72fd31fb288e..fe1f9c51de271e 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -232,6 +232,7 @@ noncomputable instance [Small.{u} σ] : CoproductsOfShapeDisjoint Scheme.{u} σ instance : HasFiniteCoproducts Scheme.{u} where out := inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance : MonoCoprod Scheme.{u} := .mk' fun X Y ↦ ⟨.mk coprod.inl coprod.inr, coprodIsCoprod X Y, inferInstanceAs <| Mono coprod.inl⟩ diff --git a/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean b/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean index 32ec8d0dc0624f..3f59592d592126 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean @@ -178,10 +178,12 @@ lemma pushforward_obj_presheaf_map {U V : Y.Opens} (i : U ⟶ V) : lemma pushforward_map_app (φ : M ⟶ N) (U : Y.Opens) : ((pushforward f).map φ).app U = φ.app (f ⁻¹ᵁ U) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The pullback functor for categories of sheaves of modules over schemes. -/ def pullback : Y.Modules ⥤ X.Modules := SheafOfModules.pullback f.toRingCatSheafHom +set_option backward.isDefEq.respectTransparency.types false in /-- The pullback functor for categories of sheaves of modules over schemes is left adjoint to the pushforward functor. -/ def pullbackPushforwardAdjunction : pullback f ⊣ pushforward f := @@ -192,9 +194,11 @@ section attribute [local instance] preservesBinaryBiproducts_of_preservesBinaryCoproducts preservesBinaryBiproducts_of_preservesBinaryProducts +set_option backward.isDefEq.respectTransparency.types false in instance : (pullback f).IsLeftAdjoint := (pullbackPushforwardAdjunction f).isLeftAdjoint instance : (pushforward f).IsRightAdjoint := (pullbackPushforwardAdjunction f).isRightAdjoint instance : (pushforward f).Additive := Functor.additive_of_preservesBinaryBiproducts _ +set_option backward.isDefEq.respectTransparency.types false in instance : (pullback f).Additive := Functor.additive_of_preservesBinaryBiproducts _ end @@ -208,12 +212,14 @@ def pushforwardId : pushforward (𝟙 X) ≅ 𝟭 _ := @[simp] lemma pushforwardId_hom_app_app : ((pushforwardId X).hom.app M).app U = 𝟙 _ := rfl @[simp] lemma pushforwardId_inv_app_app : ((pushforwardId X).inv.app M).app U = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in variable (X) in /-- The pullback of sheaves of modules by the identity morphism identifies to the identity functor. -/ def pullbackId : pullback (𝟙 X) ≅ 𝟭 _ := SheafOfModules.pullbackId _ +set_option backward.isDefEq.respectTransparency.types false in variable (X) in lemma conjugateEquiv_pullbackId_hom : conjugateEquiv .id (pullbackPushforwardAdjunction (𝟙 X)) (pullbackId X).hom = @@ -229,27 +235,33 @@ def pushforwardComp : @[simp] lemma pushforwardComp_hom_app_app (U) : ((pushforwardComp f g).hom.app M).app U = 𝟙 _ := rfl @[simp] lemma pushforwardComp_inv_app_app (U) : ((pushforwardComp f g).inv.app M).app U = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of two pullback functors for sheaves of modules on schemes identify to the pullback for the composition. -/ def pullbackComp : pullback g ⋙ pullback f ≅ pullback (f ≫ g) := SheafOfModules.pullbackComp _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- Pushforwards along equal morphisms are isomorphic. -/ def pushforwardCongr {f g : X ⟶ Y} (hf : f = g) : pushforward f ≅ pushforward g := pushforwardNatIso _ (Opens.mapIso _ _ (hf ▸ rfl)) ≪≫ SheafOfModules.pushforwardCongr (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma pushforwardCongr_hom_app_app {f g : X ⟶ Y} (hf : f = g) (U : Y.Opens) : ((pushforwardCongr hf).hom.app M).app U = M.presheaf.map (eqToHom (hf ▸ rfl)).op := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma pushforwardCongr_inv_app_app {f g : X ⟶ Y} (hf : f = g) (U : Y.Opens) : ((pushforwardCongr hf).inv.app M).app U = M.presheaf.map (eqToHom (hf ▸ rfl)).op := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Inverse images along equal morphisms are isomorphic. -/ def pullbackCongr {f g : X ⟶ Y} (hf : f = g) : pullback f ≅ pullback g := eqToIso (hf ▸ rfl) +set_option backward.isDefEq.respectTransparency.types false in lemma conjugateEquiv_pullbackComp_inv : conjugateEquiv ((pullbackPushforwardAdjunction g).comp (pullbackPushforwardAdjunction f)) (pullbackPushforwardAdjunction (f ≫ g)) (pullbackComp f g).inv = @@ -436,10 +448,12 @@ lemma restrictAdjunction_counit_app_app (M : X.Modules) (U : X.Opens) : ((restrictAdjunction f).counit.app M).app U = M.presheaf.map (eqToHom (f.preimage_image_eq U).symm).op := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Restriction is naturally isomorphic to the inverse image. -/ def restrictFunctorIsoPullback : restrictFunctor f ≅ pullback f := (restrictAdjunction f).leftAdjointUniq (pullbackPushforwardAdjunction f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restriction along the identity is isomorphic to the identity. -/ def restrictFunctorId : restrictFunctor (𝟙 X) ≅ 𝟭 _ := @@ -458,6 +472,7 @@ lemma restrictFunctorId_inv_app_app : (restrictFunctorId.inv.app M).app U = M.presheaf.map (eqToHom (show 𝟙 X ''ᵁ U = U by simp)).op := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restriction along the composition is isomorphic to the composition of restrictions. -/ def restrictFunctorComp : restrictFunctor (f ≫ g) ≅ restrictFunctor g ⋙ restrictFunctor f := @@ -476,6 +491,7 @@ lemma restrictFunctorComp_hom_app_app (M : Z.Modules) : lemma restrictFunctorComp_inv_app_app (M : Z.Modules) : ((restrictFunctorComp f g).inv.app M).app U = M.presheaf.map (eqToHom (by simp)).op := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restriction along equal morphisms are isomorphic. -/ def restrictFunctorCongr {f g : X ⟶ Y} (hf : f = g) [IsOpenImmersion f] [IsOpenImmersion g] : diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index f63ea0d48789dd..dee5b8e11d1da1 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -37,6 +37,7 @@ namespace AlgebraicGeometry open _root_.PrimeSpectrum +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from `𝒪_{Spec R}` modules to sheaves of `R`-modules. -/ def modulesSpecToSheaf : (Spec R).Modules ⥤ TopCat.Sheaf (ModuleCat R) (Spec R) := @@ -103,6 +104,7 @@ lemma map_smul_Spec (hUV : .op V ⟶ .op U) (f : R) (x : Γ(M, V)) : dsimp% M.presheaf.map hUV (f • x) = f • M.presheaf.map hUV x := ((modulesSpecToSheaf.obj M).obj.map hUV).hom.map_smul f x +set_option backward.isDefEq.respectTransparency.types false in lemma isUnit_algebraMap_end_of_le_basicOpen (f : R) (hf : U ≤ PrimeSpectrum.basicOpen f) : IsUnit (algebraMap R (Module.End R Γ(M, U)) f) := by rw [Module.End.isUnit_iff] @@ -168,6 +170,7 @@ def modulesSpecToSheafIso : def toOpen (U : (Spec R).Opens) : M ⟶ (modulesSpecToSheaf.obj (tilde M)).presheaf.obj (.op U) := ModuleCat.ofHom (StructureSheaf.toOpenₗ R M U) ≫ ((modulesSpecToSheafIso M).app _).inv +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem toOpen_res (U V : Opens (PrimeSpectrum.Top R)) (i : V ⟶ U) : toOpen M U ≫ (modulesSpecToSheaf.obj (tilde M)).presheaf.map i.op = toOpen M V := @@ -189,21 +192,25 @@ noncomputable def toStalk (x : PrimeSpectrum.Top R) : ModuleCat.of R M ⟶ ModuleCat.of R ((tilde M).presheaf.stalk x) := ModuleCat.ofHom (StructureSheaf.toStalkₗ ..) +set_option backward.isDefEq.respectTransparency.types false in instance (x : PrimeSpectrum.Top R) : IsLocalizedModule x.asIdeal.primeCompl (toStalk M x).hom := inferInstanceAs (IsLocalizedModule x.asIdeal.primeCompl (StructureSheaf.toStalkₗ ..)) +set_option backward.isDefEq.respectTransparency.types false in /-- The tilde construction is functorial. -/ protected noncomputable def map {M N : ModuleCat R} (f : M ⟶ N) : tilde M ⟶ tilde N := SpecModulesToSheafFullyFaithful.preimage ⟨(modulesSpecToSheafIso M).hom ≫ { app U := ModuleCat.ofHom (StructureSheaf.comapₗ f.hom _ _ .rfl) } ≫ (modulesSpecToSheafIso N).inv⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] protected lemma map_id {M : ModuleCat R} : tilde.map (𝟙 M) = 𝟙 _ := by ext p x exact Subtype.ext (funext fun y ↦ DFunLike.congr_fun (LocalizedModule.map_id _) _) +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] protected lemma map_comp {M N P : ModuleCat R} (f : M ⟶ N) (g : N ⟶ P) : tilde.map (f ≫ g) = tilde.map f ≫ tilde.map g := by @@ -214,6 +221,7 @@ protected lemma map_comp {M N P : ModuleCat R} (f : M ⟶ N) (g : N ⟶ P) : (LocalizedModule.mkLinearMap y.1.asIdeal.primeCompl N) (LocalizedModule.mkLinearMap y.1.asIdeal.primeCompl P) _ _) _) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma toOpen_map_app {M N : ModuleCat R} (f : M ⟶ N) (U : TopologicalSpace.Opens (PrimeSpectrum R)) : @@ -229,6 +237,7 @@ variable (R) in obj := tilde map := tilde.map +set_option backward.isDefEq.respectTransparency.types false in instance isIso_toOpen_top {M : ModuleCat R} : IsIso (toOpen M ⊤) := by rw [toOpen, isIso_comp_right_iff, ConcreteCategory.isIso_iff_bijective] exact StructureSheaf.toOpenₗ_top_bijective @@ -291,8 +300,8 @@ lemma Scheme.Modules.toOpen_fromTildeΓ_app (M : (Spec (.of R)).Modules) (U) : NatTrans.naturality, ← Category.assoc, this, ← Functor.map_comp, ← op_comp, homOfLE_comp] simp subst hU - simp only [fromTildeΓ, - homOfLE_leOfHom, Functor.FullyFaithful.map_preimage, TopCat.Sheaf.extend_hom_app] + simp only [fromTildeΓ, inducedFunctor_obj, homOfLE_leOfHom, Functor.FullyFaithful.map_preimage, + TopCat.Sheaf.extend_hom_app] ext x refine (IsLocalizedModule.lift_apply (.powers (M := R) 1) (tilde.toOpen _ (PrimeSpectrum.basicOpen (R := R) 1)).hom @@ -361,6 +370,7 @@ def tilde.adjunction : tilde.functor R ⊣ moduleSpecΓFunctor where rw [toOpen_fromTildeΓ_app] exact (modulesSpecToSheaf.obj M).obj.map_id _ +set_option backward.isDefEq.respectTransparency.types false in instance : IsIso (tilde.adjunction (R := R)).unit := by dsimp [tilde.adjunction]; infer_instance @@ -383,17 +393,21 @@ variable {M N : ModuleCat R} (f g : M ⟶ N) @[simp] lemma tilde.map_zero : tilde.map (0 : M ⟶ N) = 0 := (tilde.functor R).map_zero _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tilde.map_add : tilde.map (f + g) = tilde.map f + tilde.map g := (tilde.functor R).map_add +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tilde.map_sub : tilde.map (f - g) = tilde.map f - tilde.map g := (tilde.functor R).map_sub +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tilde.map_neg : tilde.map (-f) = - tilde.map f := (tilde.functor R).map_neg end +set_option backward.isDefEq.respectTransparency.types false in lemma isIso_fromTildeΓ_iff {M : (Spec R).Modules} : IsIso M.fromTildeΓ ↔ (tilde.functor R).essImage M := tilde.adjunction.isIso_counit_app_iff_mem_essImage @@ -478,6 +492,7 @@ from `M(⊤)` to `M(D(f))` is localization with respect to `f`. -/ abbrev IsLocalizing (M : TopCat.Sheaf (ModuleCat R) (Spec R)) : Prop := ∀ f : R, IsLocalizedModule (.powers f) (M.obj.map (basicOpen f).leTop.op).hom +set_option backward.isDefEq.respectTransparency.types false in theorem isLocalizing_of_iso {M N : TopCat.Sheaf (ModuleCat R) (Spec R)} (φ : M ≅ N) (hM : IsLocalizing M) : IsLocalizing N := by @@ -605,6 +620,7 @@ lemma Scheme.Modules.exists_isOpenCover_presentation {X : Scheme.{u}} (M : X.Mod · intro j exact hsub _ j.2.2 +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Modules.exists_affineOpenCover_presentation {X : Scheme.{u}} (M : X.Modules) [M.IsQuasicoherent] : ∃ (𝒰 : Scheme.AffineOpenCover.{u} X), @@ -618,6 +634,7 @@ namespace QuasicoherentTilde variable (M : (Spec R).Modules) +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary structure used in the proof of `Scheme.Modules.isIso_fromTildeΓ_of_isQuasicoherent`. These are conditions d1) and d2) from [Theoreme 1.4.1, grothendieck-1971]. -/ -- TODO: Generalise this to a general scheme, replacing `f : R` by sections over a suitable set. diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean index 3339ee558dc2ef..dc5989e94cd4b3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean @@ -168,6 +168,7 @@ instance : HasAffineProperty @IsAffineHom fun X _ _ _ ↦ IsAffine X where Subtype.forall, isAffineHom_iff] rfl +set_option backward.isDefEq.respectTransparency.types false in instance isAffineHom_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsAffineHom := by apply HasAffineProperty.isStableUnderBaseChange @@ -176,12 +177,15 @@ instance isAffineHom_isStableUnderBaseChange : introv X hX H infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance (priority := 100) isAffineHom_of_isAffine [IsAffine X] [IsAffine Y] : IsAffineHom f := (HasAffineProperty.iff_of_isAffine (P := @IsAffineHom)).mpr inferInstance +set_option backward.isDefEq.respectTransparency.types false in lemma isAffine_of_isAffineHom [IsAffineHom f] [IsAffine Y] : IsAffine X := (HasAffineProperty.iff_of_isAffine (P := @IsAffineHom) (f := f)).mp inferInstance +set_option backward.isDefEq.respectTransparency.types false in lemma isAffineHom_of_forall_exists_isAffineOpen (H : ∀ x : Y, ∃ U : Y.Opens, x ∈ U ∧ IsAffineOpen U ∧ IsAffineOpen (f ⁻¹ᵁ U)) : IsAffineHom f := by @@ -190,11 +194,13 @@ lemma isAffineHom_of_forall_exists_isAffineOpen · exact hfU · exact top_le_iff.mp (fun x _ ↦ by simpa using ⟨x, hxU x⟩) +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [IsAffineHom f] [IsAffine Y] : IsAffine (pullback f g) := letI : IsAffineHom (pullback.snd f g) := MorphismProperty.pullback_snd _ _ ‹_› isAffine_of_isAffineHom (pullback.snd f g) +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [IsAffineHom g] [IsAffine X] : IsAffine (pullback f g) := letI : IsAffineHom (pullback.fst f g) := MorphismProperty.pullback_fst _ _ ‹_› @@ -288,6 +294,7 @@ lemma isIso_morphismRestrict_iff_isIso_app [IsAffineHom f] {U : Y.Opens} (hU : I simp only [morphismRestrict_app', TopologicalSpace.Opens.map_top] congr! <;> simp [Scheme.Opens.toScheme_presheaf_obj] +set_option backward.isDefEq.respectTransparency.types false in theorem diagonal_isAffine_iff_forall_isAffineOpen_inf [IsAffine Y] (f : X ⟶ Y) : AffineTargetMorphismProperty.diagonal (fun X _ _ _ ↦ IsAffine X) f ↔ ∀ (U V : X.Opens), IsAffineOpen U → IsAffineOpen V → IsAffineOpen (U ⊓ V) := by @@ -308,6 +315,7 @@ theorem diagonal_isAffine_iff_forall_isAffineOpen_inf [IsAffine Y] (f : X ⟶ Y) change IsAffine _ at this exact .of_isIso (pullback.fst f₁ f₂ ≫ f₁).isoOpensRange.hom +set_option backward.isDefEq.respectTransparency.types false in theorem isAffineHom_diagonal_iff {f : X ⟶ Y} : IsAffineHom (pullback.diagonal f) ↔ ∀ (U : Y.Opens), IsAffineOpen U → ∀ V₁ ≤ f ⁻¹ᵁ U, ∀ V₂ ≤ f ⁻¹ᵁ U, diff --git a/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean b/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean index a1a71e44c80c3d..f9e91c26168ce7 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/AffineAnd.lean @@ -243,6 +243,7 @@ lemma HasAffineProperty.affineAnd_iff (P : MorphismProperty Scheme.{u}) rw [targetAffineLocally_affineAnd_iff hQi, h f] aesop +set_option backward.isDefEq.respectTransparency.types false in lemma HasAffineProperty.affineAnd_le_isAffineHom (P : MorphismProperty Scheme.{u}) (hA : HasAffineProperty P (affineAnd Q)) : P ≤ @IsAffineHom := by intro X Y f hf diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean index caf16cd0d2b9e6..c6b52396620529 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean @@ -142,6 +142,7 @@ lemma of_isPullback {UX UY : Scheme.{u}} {iY : UY ⟶ Y} [IsOpenImmersion iY] theorem restrict (hf : P f) (U : Y.Opens) : P (f ∣_ U) := of_isPullback (isPullback_morphismRestrict f U).flip hf +set_option backward.isDefEq.respectTransparency.types false in lemma of_iSup_eq_top {ι} (U : ι → Y.Opens) (hU : iSup U = ⊤) (H : ∀ i, P (f ∣_ U i)) : P f := by refine (P.iff_of_zeroHypercover_target @@ -287,6 +288,7 @@ variable (f) in lemma of_isOpenImmersion [P.ContainsIdentities] [IsOpenImmersion f] : P f := Category.comp_id f ▸ comp (P.id_mem Y) f +set_option backward.isDefEq.respectTransparency.types false in lemma isZariskiLocalAtTarget [P.IsMultiplicative] (hP : ∀ {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) [IsOpenImmersion g], P (f ≫ g) → P f) : IsZariskiLocalAtTarget P := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index 611c7195607cc3..a0f4c4bad5e6a1 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -81,6 +81,7 @@ instance : MorphismProperty.IsMultiplicative @IsClosedImmersion where id_mem _ := inferInstance comp_mem f g _ _ := ⟨g.isClosedEmbedding.comp f.isClosedEmbedding⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Composition of closed immersions is a closed immersion. -/ instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsClosedImmersion f] [IsClosedImmersion g] : IsClosedImmersion (f ≫ g) := @@ -93,6 +94,7 @@ instance respectsIso : MorphismProperty.RespectsIso @IsClosedImmersion := by instance {X : Scheme} (I : X.IdealSheafData) : IsClosedImmersion I.subschemeι := .of_isPreimmersion _ (I.range_subschemeι ▸ I.support.isClosed) +set_option backward.isDefEq.respectTransparency.types false in /-- Given two commutative rings `R S : CommRingCat` and a surjective morphism `f : R ⟶ S`, the induced scheme morphism `specObj S ⟶ specObj R` is a closed immersion. -/ @@ -170,6 +172,7 @@ instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsClosedImmersion f] : (f := f.toImage.base) f.toImage.isEmbedding.isInducing X.presheaf x exact ((ConcreteCategory.isIso_iff_bijective _).mp this).1 +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of closed subschemes is contravariantly equivalent to the lattice of ideal sheaves. -/ @@ -214,6 +217,7 @@ lemma lift_fac {X Y Z : Scheme.{u}} nth_rw 2 [← f.toImage_imageι] simp [lift, -Scheme.Hom.toImage_imageι, g.toImage_imageι] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isIso_of_ker_eq {Z₁ Z₂ X : Scheme.{u}} (i₁ : Z₁ ⟶ X) (i₂ : Z₂ ⟶ X) [IsClosedImmersion i₁] [IsClosedImmersion i₂] (f : Z₁ ⟶ Z₂) @@ -238,6 +242,7 @@ variable {X Y : Scheme.{u}} [IsAffine Y] {f : X ⟶ Y} open IsClosedImmersion LocallyRingedSpace +set_option backward.isDefEq.respectTransparency.types false in /-- If `f : X ⟶ Y` is a morphism of schemes with quasi-compact source and affine target, `f` induces an injection on global sections, then `f` is dominant. -/ lemma isDominant_of_of_appTop_injective [CompactSpace X] @@ -253,6 +258,7 @@ instance [CompactSpace X] : IsDominant X.toSpecΓ := simpa only [Scheme.toSpecΓ_appTop] using (ConcreteCategory.bijective_of_isIso (Scheme.ΓSpecIso Γ(X, ⊤)).hom).1) +set_option backward.isDefEq.respectTransparency.types false in /-- If `f : X ⟶ Y` is open, injective, `X` is quasi-compact and `Y` is affine, then `f` is stalkwise injective if it is injective on global sections. -/ lemma stalkMap_injective_of_isOpenMap_of_injective [CompactSpace X] @@ -297,6 +303,7 @@ lemma stalkMap_injective_of_isOpenMap_of_injective [CompactSpace X] namespace IsClosedImmersion +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` is a closed immersion with affine target such that the induced map on global sections is injective, `f` is an isomorphism. -/ theorem isIso_of_injective_of_isAffine [IsClosedImmersion f] @@ -319,6 +326,7 @@ theorem isAffine_surjective_of_isAffine [IsClosedImmersion f] : exact (ConcreteCategory.bijective_of_isIso _).2.comp ((ConcreteCategory.bijective_of_isIso _).2.comp Ideal.Quotient.mk_surjective) +set_option backward.isDefEq.respectTransparency.types false in lemma Spec_iff {R : CommRingCat} {f : X ⟶ Spec R} : IsClosedImmersion f ↔ ∃ I : Ideal R, ∃ e : X ≅ Spec (.of <| R ⧸ I), f = e.hom ≫ Spec.map (CommRingCat.ofHom (Ideal.Quotient.mk I)) := by @@ -345,10 +353,12 @@ end Affine variable {X Y Z : Scheme.{u}} +set_option backward.isDefEq.respectTransparency.types false in /-- Being a closed immersion is local at the target. -/ instance IsClosedImmersion.isZariskiLocalAtTarget : IsZariskiLocalAtTarget @IsClosedImmersion := eq_inf ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in /-- On morphisms with affine target, being a closed immersion is precisely having affine source and being surjective on global sections. -/ instance IsClosedImmersion.hasAffineProperty : HasAffineProperty @IsClosedImmersion @@ -356,6 +366,7 @@ instance IsClosedImmersion.hasAffineProperty : HasAffineProperty @IsClosedImmers convert! HasAffineProperty.of_isZariskiLocalAtTarget @IsClosedImmersion refine ⟨fun ⟨h₁, h₂⟩ ↦ of_surjective_of_isAffine _ h₂, by apply isAffine_surjective_of_isAffine⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma isClosedImmersion_iff_isAffineHom {f : X ⟶ Y} : IsClosedImmersion f ↔ IsAffineHom f ∧ ∀ U : Y.Opens, IsAffineOpen U → Function.Surjective (f.app U) := by @@ -366,6 +377,7 @@ lemma Scheme.Hom.app_surjective (f : X ⟶ Y) (U : Y.Opens) (hU : IsAffineOpen U [IsClosedImmersion f] : Function.Surjective (f.app U) := (isClosedImmersion_iff_isAffineHom.mp ‹_›).2 U hU +set_option backward.isDefEq.respectTransparency.types false in /-- Being a closed immersion is stable under base change. -/ instance IsClosedImmersion.isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsClosedImmersion := by @@ -376,10 +388,12 @@ instance IsClosedImmersion.isStableUnderBaseChange : exact ⟨inferInstance, RingHom.surjective_isStableUnderBaseChange.pullback_fst_appTop _ RingHom.surjective_respectsIso f _ hsurj⟩ +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [IsClosedImmersion g] : IsClosedImmersion (Limits.pullback.fst f g) := MorphismProperty.pullback_fst _ _ ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [IsClosedImmersion f] : IsClosedImmersion (Limits.pullback.snd f g) := MorphismProperty.pullback_snd _ _ ‹_› @@ -388,6 +402,7 @@ instance (f : X ⟶ Y) (V : Y.Opens) [IsClosedImmersion f] : IsClosedImmersion (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V +set_option backward.isDefEq.respectTransparency.types false in /-- Closed immersions are locally of finite type. -/ instance (priority := 900) {X Y : Scheme.{u}} (f : X ⟶ Y) [h : IsClosedImmersion f] : LocallyOfFiniteType f := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean index c04919f3ce1fe3..246bce9e26dbd9 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean @@ -93,6 +93,7 @@ theorem HasAffineProperty.diagonal_of_openCover (P) {Q} [HasAffineProperty P Q] convert! h𝒰' i j k ext1 <;> simp [Scheme.Cover.pullbackHom] +set_option backward.isDefEq.respectTransparency.types false in theorem HasAffineProperty.diagonal_of_openCover_diagonal (P) {Q} [HasAffineProperty P Q] {X Y : Scheme.{u}} (f : X ⟶ Y) (𝒰 : Scheme.OpenCover Y) [∀ i, IsAffine (𝒰.X i)] @@ -118,6 +119,7 @@ theorem HasAffineProperty.diagonal_of_diagonal_of_isPullback · infer_instance · infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem HasAffineProperty.diagonal_iff (P) {Q} [HasAffineProperty P Q] {X Y : Scheme.{u}} {f : X ⟶ Y} [IsAffine Y] : @@ -152,6 +154,7 @@ theorem AffineTargetMorphismProperty.diagonal_of_openCover_source rw [← Q.cancel_left_of_respectsIso this.isoPullback.hom, IsPullback.isoPullback_hom_snd] exact h𝒰 _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance HasAffineProperty.diagonal_affineProperty_isLocal {Q : AffineTargetMorphismProperty} [Q.IsLocal] : @@ -227,6 +230,7 @@ theorem universally_isZariskiLocalAtTarget (P : MorphismProperty Scheme) · rw [← cancel_mono (Scheme.Opens.ι _)] simp [morphismRestrict_ι_assoc, h.1.1] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma universally_isZariskiLocalAtSource (P : MorphismProperty Scheme) [IsZariskiLocalAtSource P] : IsZariskiLocalAtSource P.universally := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Descent.lean b/Mathlib/AlgebraicGeometry/Morphisms/Descent.lean index e66b740b2661f0..897c5f708aa982 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Descent.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Descent.lean @@ -129,6 +129,7 @@ variable (H₁ : (@IsLocalIso ⊓ @Surjective : MorphismProperty Scheme) ≤ P') (H₂ : ∀ {R S : CommRingCat.{u}} {f : R ⟶ S}, P' (Spec.map f) → Q' f.hom) +set_option backward.isDefEq.respectTransparency.types false in include H₁ in lemma IsZariskiLocalAtTarget.descendsAlong_inf_quasiCompact [IsZariskiLocalAtTarget P] (H : ∀ {R S : CommRingCat.{u}} {Y : Scheme.{u}} (φ : R ⟶ S) (g : Y ⟶ Spec R), diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean b/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean index 0b4f6f16974b8b..9ee458543ba4af 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Etale.lean @@ -64,6 +64,7 @@ instance : MorphismProperty.IsMultiplicative @Etale := HasRingHomProperty.isMultiplicative RingHom.Etale.stableUnderComposition RingHom.Etale.containsIdentities +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of étale morphisms is étale. -/ instance etale_comp {Z : Scheme.{u}} (g : Y ⟶ Z) [Etale f] [Etale g] : Etale (f ≫ g) := @@ -77,14 +78,17 @@ instance etale_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChang instance (priority := 900) [IsOpenImmersion f] : Etale f := HasRingHomProperty.of_isOpenImmersion RingHom.Etale.containsIdentities +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [Etale g] : Etale (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [Etale f] : Etale (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [Etale f] : Etale (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -115,6 +119,7 @@ instance (priority := 900) [Etale f] : FormallyUnramified f where formallyUnramified_appLE {_} hU {_} hV e := (f.etale_appLE hU hV e).formallyUnramified +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.HasOfPostcompProperty @Etale (@LocallyOfFiniteType ⊓ @FormallyUnramified) := by rw [MorphismProperty.hasOfPostcompProperty_iff_le_diagonal] @@ -147,6 +152,7 @@ end Etale namespace Scheme +set_option backward.isDefEq.respectTransparency.types false in /-- The category `Etale X` is the category of schemes étale over `X`. -/ protected def Etale (X : Scheme.{u}) : Type _ := MorphismProperty.Over @Etale ⊤ X deriving Category, HasPullbacks, HasFiniteLimits @@ -156,14 +162,17 @@ variable (X : Scheme.{u}) set_option backward.defeqAttrib.useBackward true in instance (Y : X.Etale) : dsimp% Etale Y.hom := Y.prop +set_option backward.isDefEq.respectTransparency.types false in instance {X : Scheme.{u}} {Z Y : X.Etale} (f : Z ⟶ Y) : Etale f.left := by have : Etale (f.left ≫ Y.hom) := by rw [CategoryTheory.Over.w]; infer_instance exact Etale.of_comp f.left Y.hom +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from schemes étale over `X` to schemes over `X`. -/ def Etale.forget : X.Etale ⥤ Over X := MorphismProperty.Over.forget @Etale ⊤ X +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from schemes étale over `X` to schemes over `X` is fully faithful. -/ def Etale.forgetFullyFaithful : (Etale.forget X).FullyFaithful := MorphismProperty.Comma.forgetFullyFaithful _ _ _ @@ -205,6 +214,7 @@ def Etale.rec {motive : X.Etale → Sort*} motive T := mk _ _ T.prop +set_option backward.isDefEq.respectTransparency.types false in instance : PreservesFiniteLimits (Etale.forget X) := inferInstanceAs (PreservesFiniteLimits (MorphismProperty.Over.forget _ ⊤ X)) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean b/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean index 5c22386c082a28..cf6826b55377d3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Finite.lean @@ -43,6 +43,7 @@ alias Scheme.Hom.finite_app := IsFinite.finite_app namespace IsFinite +set_option backward.isDefEq.respectTransparency.types false in instance : HasAffineProperty @IsFinite (fun X _ f _ ↦ IsAffine X ∧ RingHom.Finite (f.appTop).hom) := by change HasAffineProperty @IsFinite (affineAnd RingHom.Finite) @@ -50,20 +51,24 @@ instance : HasAffineProperty @IsFinite RingHom.finite_localizationPreserves.away RingHom.finite_ofLocalizationSpan] simp [isFinite_iff] +set_option backward.isDefEq.respectTransparency.types false in instance : IsStableUnderComposition @IsFinite := HasAffineProperty.affineAnd_isStableUnderComposition inferInstance RingHom.finite_stableUnderComposition +set_option backward.isDefEq.respectTransparency.types false in instance : IsStableUnderBaseChange @IsFinite := HasAffineProperty.affineAnd_isStableUnderBaseChange inferInstance RingHom.finite_respectsIso RingHom.finite_isStableUnderBaseChange +set_option backward.isDefEq.respectTransparency.types false in instance : ContainsIdentities @IsFinite := HasAffineProperty.affineAnd_containsIdentities inferInstance RingHom.finite_respectsIso RingHom.finite_containsIdentities instance : IsMultiplicative @IsFinite where +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma SpecMap_iff {R S : CommRingCat.{u}} (f : R ⟶ S) : IsFinite (Spec.map f) ↔ f.hom.Finite := by @@ -72,20 +77,26 @@ lemma SpecMap_iff {R S : CommRingCat.{u}} (f : R ⟶ S) : variable {X Y Z : Scheme.{u}} (f : X ⟶ Y) +set_option backward.isDefEq.respectTransparency.types false in instance (priority := 900) [IsIso f] : IsFinite f := of_isIso @IsFinite f +set_option backward.isDefEq.respectTransparency.types false in instance {Z : Scheme.{u}} (g : Y ⟶ Z) [IsFinite f] [IsFinite g] : IsFinite (f ≫ g) := IsStableUnderComposition.comp_mem f g ‹IsFinite f› ‹IsFinite g› +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [IsFinite g] : IsFinite (Limits.pullback.fst f g) := MorphismProperty.pullback_fst _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [IsFinite f] : IsFinite (Limits.pullback.snd f g) := MorphismProperty.pullback_snd _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [IsFinite f] : IsFinite (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V +set_option backward.isDefEq.respectTransparency.types false in lemma iff_isIntegralHom_and_locallyOfFiniteType : IsFinite f ↔ IsIntegralHom f ∧ LocallyOfFiniteType f := by wlog hY : IsAffine Y @@ -144,6 +155,7 @@ lemma comp_iff {f : X ⟶ Y} {g : Y ⟶ Z} [IsFinite g] : IsFinite (f ≫ g) ↔ IsFinite f := ⟨fun _ ↦ .of_comp f g, fun _ ↦ inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in instance {U V X : Scheme.{u}} (f : U ⟶ X) (g : V ⟶ X) [IsFinite f] [IsFinite g] : IsFinite (Limits.coprod.desc f g) := by refine HasAffineProperty.coprodDesc_affineAnd inferInstance RingHom.finite_respectsIso @@ -154,10 +166,12 @@ instance {U V X : Scheme.{u}} (f : U ⟶ X) (g : V ⟶ X) [IsFinite f] [IsFinite end IsFinite +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Hom.finite_appTop {X Y : Scheme.{u}} (f : X ⟶ Y) [IsAffine Y] [IsFinite f] : f.appTop.hom.Finite := (HasAffineProperty.iff_of_isAffine (P := @IsFinite).mp inferInstance).2 +set_option backward.isDefEq.respectTransparency.types false in /-- If `X` is a Jacobson scheme and `k` is a field, `Spec(k) ⟶ X` is finite iff it is (locally) of finite type. (The statement is more general to allow the empty scheme as well) -/ @@ -202,6 +216,7 @@ lemma Scheme.Hom.closePoints_subset_preimage_closedPoints simpa [Set.range_comp, Scheme.range_fromSpecResidueField] using (X.fromSpecResidueField x ≫ f).isClosedMap.isClosed_range +set_option backward.isDefEq.respectTransparency.types false in @[stacks 01TB "(1) => (2)"] lemma isClosed_singleton_iff_locallyOfFiniteType {X : Scheme.{u}} [JacobsonSpace X] {x : X} : IsClosed {x} ↔ LocallyOfFiniteType (X.fromSpecResidueField x) := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean b/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean index ad50cc03d03afb..253bbf756c95b1 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean @@ -86,14 +86,17 @@ instance locallyOfFinitePresentation_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @LocallyOfFinitePresentation := HasRingHomProperty.isStableUnderBaseChange RingHom.finitePresentation_isStableUnderBaseChange +set_option backward.isDefEq.respectTransparency.types false in instance {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) [LocallyOfFinitePresentation g] : LocallyOfFinitePresentation (Limits.pullback.fst f g) := MorphismProperty.pullback_fst _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) [LocallyOfFinitePresentation f] : LocallyOfFinitePresentation (Limits.pullback.snd f g) := MorphismProperty.pullback_snd _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [LocallyOfFinitePresentation f] : LocallyOfFinitePresentation (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean index 044bb9779a91e1..b4babad0160370 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean @@ -81,14 +81,17 @@ instance locallyOfFiniteType_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @LocallyOfFiniteType := HasRingHomProperty.isStableUnderBaseChange RingHom.finiteType_isStableUnderBaseChange +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [LocallyOfFiniteType g] : LocallyOfFiniteType (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [LocallyOfFiniteType f] : LocallyOfFiniteType (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [LocallyOfFiniteType f] : LocallyOfFiniteType (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -110,6 +113,7 @@ instance {R} [CommRing R] [IsJacobsonRing R] : JacobsonSpace <| Spec <| .of R := instance {R : CommRingCat} [IsJacobsonRing R] : JacobsonSpace (Spec R) := inferInstanceAs (JacobsonSpace (PrimeSpectrum R)) +set_option backward.isDefEq.respectTransparency.types false in nonrec lemma LocallyOfFiniteType.jacobsonSpace (f : X ⟶ Y) [LocallyOfFiniteType f] [JacobsonSpace Y] : JacobsonSpace X := by wlog hY : ∃ S, Y = Spec S diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean index 0430d1d66511fe..0f95fcba4fad0f 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean @@ -71,6 +71,7 @@ instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [hf : Flat f] [hg : Flat g] : Flat (f ≫ g) := MorphismProperty.comp_mem _ f g hf hg +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.Respects @Flat @IsOpenImmersion where postcomp _ _ _ _ := inferInstance @@ -80,12 +81,15 @@ instance : MorphismProperty.IsMultiplicative @Flat where instance isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @Flat := HasRingHomProperty.isStableUnderBaseChange RingHom.Flat.isStableUnderBaseChange +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [Flat g] : Flat (pullback.fst f g) := MorphismProperty.pullback_fst _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [Flat f] : Flat (pullback.snd f g) := MorphismProperty.pullback_snd _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [Flat f] : Flat (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -102,6 +106,7 @@ lemma stalkMap [Flat f] (x : X) : (f.stalkMap x).hom.Flat := lemma iff_flat_stalkMap : Flat f ↔ ∀ x, (f.stalkMap x).hom.Flat := ⟨fun _ ↦ stalkMap f, fun H ↦ of_stalkMap f H⟩ +set_option backward.isDefEq.respectTransparency.types false in instance {X : Scheme.{u}} {ι : Type v} [Small.{u} ι] {Y : ι → Scheme.{u}} {f : ∀ i, Y i ⟶ X} [∀ i, Flat (f i)] : Flat (Sigma.desc f) := IsZariskiLocalAtSource.sigmaDesc (fun _ ↦ inferInstance) @@ -146,6 +151,7 @@ lemma isQuotientMap_of_surjective {X Y : Scheme.{u}} (f : X ⟶ Y) [Flat f] [Qua · apply RingHom.Flat.generalizingMap_comap rwa [← HasRingHomProperty.Spec_iff (P := @Flat)] +set_option backward.isDefEq.respectTransparency.types false in /-- A flat surjective morphism of schemes is an epimorphism in the category of schemes. -/ @[stacks 02VW] lemma epi_of_flat_of_surjective (f : X ⟶ Y) [Flat f] [Surjective f] : Epi f := by @@ -160,6 +166,7 @@ lemma epi_of_flat_of_surjective (f : X ⟶ Y) [Flat f] [Surjective f] : Epi f := (Flat.stalkMap f x) (f.toLRSHom.prop x) exact ‹RingHom.FaithfullyFlat _›.injective +set_option backward.isDefEq.respectTransparency.types false in lemma flat_and_surjective_iff_faithfullyFlat_of_isAffine [IsAffine X] [IsAffine Y] : Flat f ∧ Surjective f ↔ f.appTop.hom.FaithfullyFlat := by rw [RingHom.FaithfullyFlat.iff_flat_and_comap_surjective, diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FlatDescent.lean b/Mathlib/AlgebraicGeometry/Morphisms/FlatDescent.lean index 84083edb0322c1..754666351a96d0 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FlatDescent.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FlatDescent.lean @@ -36,11 +36,13 @@ open CategoryTheory Limits MorphismProperty namespace AlgebraicGeometry +set_option backward.isDefEq.respectTransparency.types false in /-- Surjective satisfies fpqc descent. -/ instance Flat.surjective_descendsAlong_surjective_inf_flat_inf_quasicompact : DescendsAlong @Surjective (@Surjective ⊓ @Flat ⊓ @QuasiCompact) := .of_le (Q := @Surjective) (le_of_inf_eq' (by grind)) +set_option backward.isDefEq.respectTransparency.types false in /-- Universally closed satisfies fpqc descent. -/ @[stacks 02KS] instance descendsAlong_universallyClosed_surjective_inf_flat_inf_quasicompact : @@ -58,6 +60,7 @@ instance descendsAlong_universallyClosed_surjective_inf_flat_inf_quasicompact : exact p.isClosedMap _ (hs.preimage r.continuous) rwa [(Flat.isQuotientMap_of_surjective _).isClosed_preimage] at this +set_option backward.isDefEq.respectTransparency.types false in /-- Universally open satisfies fpqc descent. -/ @[stacks 02KT] instance descendsAlong_universallyOpen_surjective_inf_flat_inf_quasicompact : @@ -76,6 +79,7 @@ instance descendsAlong_universallyOpen_surjective_inf_flat_inf_quasicompact : exact p.isOpenMap _ (hs.preimage r.continuous) rwa [(Flat.isQuotientMap_of_surjective _).isOpen_preimage] at this +set_option backward.isDefEq.respectTransparency.types false in /-- Universally injective satisfies fpqc descent. -/ @[stacks 02KW] instance descendsAlong_universallyInjective_surjective_inf_flat_inf_quasicompact : @@ -83,6 +87,7 @@ instance descendsAlong_universallyInjective_surjective_inf_flat_inf_quasicompact rw [universallyInjective_eq_diagonal] infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- Being an isomorphism satisfies fpqc descent. -/ @[stacks 02L4] instance descendsAlong_isomorphisms_surjective_inf_flat_inf_quasicompact : @@ -122,6 +127,7 @@ instance descendsAlong_isomorphisms_surjective_inf_flat_inf_quasicompact : rwa [← flat_and_surjective_SpecMap_iff, and_comm] · simp_rw [← isIso_SpecMap_iff, implies_true] +set_option backward.isDefEq.respectTransparency.types false in /-- Being an open immersion satisfies fpqc descent. -/ @[stacks 02L3] instance descendsAlong_isOpenImmersion_surjective_inf_flat_inf_quasicompact' : @@ -153,6 +159,7 @@ instance descendsAlong_isOpenImmersion_surjective_inf_flat_inf_quasicompact' : rw [← IsOpenImmersion.lift_fac U.ι g (by simp [U])] infer_instance +set_option backward.isDefEq.respectTransparency.types false in lemma HasRingHomProperty.descendsAlong_flat {P : MorphismProperty Scheme.{u}} [P.IsStableUnderBaseChange] {Q : ∀ {R S : Type u} [CommRing R] [CommRing S], (R →+* S) → Prop} [HasRingHomProperty P Q] (h : RingHom.CodescendsAlong Q RingHom.FaithfullyFlat) : @@ -166,6 +173,7 @@ lemma HasRingHomProperty.descendsAlong_flat {P : MorphismProperty Scheme.{u}} refine ⟨?_, (Spec.map f).surjective⟩ rwa [HasRingHomProperty.Spec_iff (P := @Flat)] at hf₂ +set_option backward.isDefEq.respectTransparency.types false in /-- fpqc descent implies fppf descent -/ instance (P : MorphismProperty Scheme) [P.DescendsAlong (@Surjective ⊓ @Flat ⊓ @QuasiCompact)] [IsZariskiLocalAtTarget P] : @@ -180,12 +188,14 @@ instance (P : MorphismProperty Scheme) [P.DescendsAlong (@Surjective ⊓ @Flat · exact ⟨fun x ↦ have ⟨y, hyV, e⟩ := e.ge (Set.mem_univ x); ⟨⟨y, hyV⟩, e⟩⟩ · exact IsZariskiLocalAtTarget.of_isPullback (.flip <| .of_hasPullback _ _) H +set_option backward.isDefEq.respectTransparency.types false in instance {X Y : Scheme} (f : X ⟶ Y) [Surjective f] [Flat f] [QuasiCompact f] : (Over.pullback f).Faithful := MorphismProperty.faithful_overPullback_of_isomorphisms_descendAlong (P := @Surjective ⊓ @Flat ⊓ @QuasiCompact) ⟨⟨inferInstance, inferInstance⟩, inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in instance {X Y : Scheme} (f : X ⟶ Y) [Surjective f] [Flat f] [LocallyOfFinitePresentation f] : (Over.pullback f).Faithful := MorphismProperty.faithful_overPullback_of_isomorphisms_descendAlong diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FlatMono.lean b/Mathlib/AlgebraicGeometry/Morphisms/FlatMono.lean index 7c7f220e5a7d57..87b4f5fc10f7a3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FlatMono.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FlatMono.lean @@ -29,6 +29,7 @@ lemma Flat.isIso_of_surjective_of_mono {X Y : Scheme.{u}} (f : X ⟶ Y) [Flat f] · tauto · exact inferInstanceAs <| IsIso (pullback.fst f f) +set_option backward.isDefEq.respectTransparency.types false in /-- Flat monomorphisms that are locally of finite presentation are open immersions. In particular, every smooth monomorphism is an open immersion. diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean b/Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean index 48f37a653d471f..1a9a0a36dcdeeb 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FlatRank.lean @@ -112,6 +112,7 @@ private lemma Scheme.Hom.finrank_eq_of_isAffine [IsAffine S] [Flat f] [IsFinite rw [show s = (𝟙 S : S ⟶ S) s from rfl, finrank_eq_finrank_snd_of_isAffine, IsAffine.finrank_snd] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Scheme.Hom.finrank_SpecMap_eq_finrank {R S : CommRingCat.{u}} {f : R ⟶ S} (hf₁ : f.hom.Finite) (hf₂ : f.hom.Flat) : @@ -171,6 +172,7 @@ lemma Scheme.Hom.finrank_pullback_fst {Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ finrank (pullback.fst g f) y = finrank f (g y) := finrank_of_isPullback (pullback.snd g f) _ _ _ (.flip <| .of_hasPullback _ _) y +set_option backward.isDefEq.respectTransparency.types false in nonrec lemma Scheme.Hom.one_le_finrank_map (x : X) : 1 ≤ finrank f (f x) := by wlog hY : ∃ R, Y = Spec R · obtain ⟨R, g, hg, y, hy⟩ := Y.exists_Spec_apply_eq (f x) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean index e946dfff6dcb03..fb76c100ace2b3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean @@ -72,6 +72,7 @@ instance : HasRingHomProperty @FormallyUnramified RingHom.FormallyUnramified whe instance : MorphismProperty.IsStableUnderComposition @FormallyUnramified := HasRingHomProperty.stableUnderComposition RingHom.FormallyUnramified.stableUnderComposition +set_option backward.isDefEq.respectTransparency.types false in /-- `f : X ⟶ S` is formally unramified if `X ⟶ X ×ₛ X` is an open immersion. In particular, monomorphisms (e.g. immersions) are formally unramified. The converse is true if `f` is locally of finite type. -/ @@ -119,6 +120,7 @@ instance : MorphismProperty.IsMultiplicative @FormallyUnramified where instance : MorphismProperty.IsStableUnderBaseChange @FormallyUnramified := HasRingHomProperty.isStableUnderBaseChange RingHom.FormallyUnramified.isStableUnderBaseChange +set_option backward.isDefEq.respectTransparency.types false in open MorphismProperty in /-- The diagonal of a formally unramified morphism of finite type is an open immersion. -/ instance isOpenImmersion_diagonal [FormallyUnramified f] [LocallyOfFiniteType f] : @@ -175,6 +177,7 @@ instance [FormallyUnramified f] [LocallyOfFiniteType f] (x : X) : exact stalkMap f x infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- Given any commuting diagram ``` diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Immersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/Immersion.lean index 4bcef5bbce97af..9c338e8307024f 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Immersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Immersion.lean @@ -107,6 +107,7 @@ lemma isImmersion_eq_inf : @IsImmersion = (@IsPreimmersion ⊓ namespace IsImmersion +set_option backward.isDefEq.respectTransparency.types false in instance : IsZariskiLocalAtTarget @IsImmersion := by suffices IsZariskiLocalAtTarget (topologically fun {X Y} _ _ f ↦ IsLocallyClosed (Set.range f)) from @@ -141,6 +142,7 @@ instance : MorphismProperty.IsMultiplicative @IsImmersion where simp only [Scheme.Hom.comp_base, TopCat.coe_comp, Set.range_comp] exact f.isLocallyClosed_range.image g.isEmbedding.isInducing g.isLocallyClosed_range +set_option backward.isDefEq.respectTransparency.types false in instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsImmersion f] [IsImmersion g] : IsImmersion (f ≫ g) := MorphismProperty.IsStableUnderComposition.comp_mem f g inferInstance inferInstance @@ -170,9 +172,11 @@ instance isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsI (by simpa using H.w.symm)] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [IsImmersion g] : IsImmersion (Limits.pullback.fst f g) := MorphismProperty.pullback_fst _ _ ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [IsImmersion f] : IsImmersion (Limits.pullback.snd f g) := MorphismProperty.pullback_snd _ _ ‹_› @@ -187,6 +191,7 @@ instance (priority := 900) (f : X ⟶ Y) [IsImmersion f] : LocallyOfFiniteType f rw [← f.liftCoborder_ι] infer_instance +set_option backward.isDefEq.respectTransparency.types false in open Limits Scheme.Pullback in /-- The diagonal morphism is always an immersion. -/ @[stacks 01KJ] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Integral.lean b/Mathlib/AlgebraicGeometry/Morphisms/Integral.lean index 925ae38a2fc25b..e7c548a462bfb0 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Integral.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Integral.lean @@ -41,6 +41,7 @@ namespace IsIntegralHom variable {X Y Z S : Scheme.{u}} +set_option backward.isDefEq.respectTransparency.types false in instance hasAffineProperty : HasAffineProperty @IsIntegralHom fun X _ f _ ↦ IsAffine X ∧ RingHom.IsIntegral (f.app ⊤).hom := by change HasAffineProperty @IsIntegralHom (affineAnd RingHom.IsIntegral) @@ -66,12 +67,15 @@ instance : IsMultiplicative @IsIntegralHom where instance (f : X ⟶ Y) (g : Y ⟶ Z) [IsIntegralHom f] [IsIntegralHom g] : IsIntegralHom (f ≫ g) := MorphismProperty.comp_mem _ _ _ ‹_› ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ S) (g : Y ⟶ S) [IsIntegralHom g] : IsIntegralHom (Limits.pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ S) (g : Y ⟶ S) [IsIntegralHom f] : IsIntegralHom (Limits.pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [IsIntegralHom f] : IsIntegralHom (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -86,6 +90,7 @@ lemma comp_iff {f : X ⟶ Y} {g : Y ⟶ Z} [IsIntegralHom g] : IsIntegralHom (f ≫ g) ↔ IsIntegralHom f := ⟨fun _ ↦ .of_comp f g, fun _ ↦ inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma SpecMap_iff {R S : CommRingCat} {φ : R ⟶ S} : IsIntegralHom (Spec.map φ) ↔ φ.hom.IsIntegral := by have := RingHom.toMorphismProperty_respectsIso_iff.mp RingHom.isIntegral_respectsIso @@ -93,6 +98,7 @@ lemma SpecMap_iff {R S : CommRingCat} {φ : R ⟶ S} : exacts [MorphismProperty.arrow_mk_iso_iff (RingHom.toMorphismProperty RingHom.IsIntegral) (arrowIsoΓSpecOfIsAffine φ).symm, inferInstance] +set_option backward.isDefEq.respectTransparency.types false in instance : IsMultiplicative @IsIntegralHom where instance {U V X : Scheme.{u}} (f : U ⟶ X) (g : V ⟶ X) [IsIntegralHom f] [IsIntegralHom g] : @@ -102,6 +108,7 @@ instance {U V X : Scheme.{u}} (f : U ⟶ X) (g : V ⟶ X) [IsIntegralHom f] [IsI algebraize [f, g] refine algebraMap_isIntegral_iff.mpr inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (priority := 100) (f : X ⟶ Y) [IsIntegralHom f] : UniversallyClosed f := by revert X Y f ‹IsIntegralHom f› @@ -124,6 +131,7 @@ instance (priority := 100) (f : X ⟶ Y) [IsIntegralHom f] : rw [SpecMap_iff] exact PrimeSpectrum.isClosedMap_comap_of_isIntegral _ +set_option backward.isDefEq.respectTransparency.types false in lemma iff_universallyClosed_and_isAffineHom {X Y : Scheme.{u}} {f : X ⟶ Y} : IsIntegralHom f ↔ UniversallyClosed f ∧ IsAffineHom f := by refine ⟨fun _ ↦ ⟨inferInstance, inferInstance⟩, fun ⟨H₁, H₂⟩ ↦ ?_⟩ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/LocalClosure.lean b/Mathlib/AlgebraicGeometry/Morphisms/LocalClosure.lean index b9723381479471..1a7ea1168020ea 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/LocalClosure.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/LocalClosure.lean @@ -59,6 +59,7 @@ lemma iff_forall_exists [P.RespectsIso] {f : X ⟶ Y} : variable [W.IsStableUnderBaseChange] [Scheme.IsJointlySurjectivePreserving W] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [P.RespectsLeft Q] [Q.IsStableUnderBaseChange] : (sourceLocalClosure W P).RespectsLeft Q := by @@ -73,6 +74,7 @@ instance [P.RespectsRight Q] : (sourceLocalClosure W P).RespectsRight Q := by instance [P.RespectsIso] : (sourceLocalClosure W P).RespectsIso where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [P.RespectsIso] [P.RespectsLeft @IsOpenImmersion] : IsZariskiLocalAtSource (sourceLocalClosure IsOpenImmersion P) := by @@ -83,6 +85,7 @@ instance [P.RespectsIso] [P.RespectsLeft @IsOpenImmersion] : · choose 𝒱 h𝒱 using h exact ⟨(Scheme.Cover.ulift 𝒰).bind (fun i ↦ Scheme.Cover.ulift (𝒱 _)), fun i ↦ h𝒱 _ _⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [P.IsStableUnderBaseChange] : (sourceLocalClosure W P).IsStableUnderBaseChange := by refine .mk' fun X Y S f g _ ⟨𝒰, hg⟩ ↦ ⟨𝒰.pullback₁ (pullback.snd f g), fun i ↦ ?_⟩ @@ -93,6 +96,7 @@ instance [W.ContainsIdentities] [P.ContainsIdentities] : (sourceLocalClosure W P).ContainsIdentities := ⟨fun X ↦ ⟨X.coverOfIsIso (𝟙 X), fun _ ↦ P.id_mem _⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [W.IsStableUnderComposition] [P.IsStableUnderBaseChange] [P.IsStableUnderComposition] : (sourceLocalClosure W P).IsStableUnderComposition := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean index 9344fdf1b8f994..074c35b69a40ba 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean @@ -45,6 +45,7 @@ lemma isPreimmersion_eq_inf : namespace IsPreimmersion +set_option backward.isDefEq.respectTransparency.types false in instance : IsZariskiLocalAtTarget @IsPreimmersion := isPreimmersion_eq_inf ▸ inferInstance @@ -56,6 +57,7 @@ instance : MorphismProperty.IsMultiplicative @IsPreimmersion where id_mem _ := inferInstance comp_mem f g _ _ := ⟨g.isEmbedding.comp f.isEmbedding⟩ +set_option backward.isDefEq.respectTransparency.types false in instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsPreimmersion f] [IsPreimmersion g] : IsPreimmersion (f ≫ g) := MorphismProperty.IsStableUnderComposition.comp_mem f g inferInstance inferInstance @@ -95,6 +97,7 @@ lemma of_isLocalization {R S : Type u} [CommRing R] (M : Submonoid R) [CommRing (PrimeSpectrum.localization_comap_isEmbedding (R := R) S M) (RingHom.surjectiveOnStalks_of_isLocalization (M := M) S) +set_option backward.isDefEq.respectTransparency.types false in open Limits MorphismProperty in instance : IsStableUnderBaseChange @IsPreimmersion := by refine .mk' fun X Y Z f g _ _ ↦ ?_ @@ -110,9 +113,11 @@ instance : IsStableUnderBaseChange @IsPreimmersion := by variable {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) +set_option backward.isDefEq.respectTransparency.types false in instance [IsPreimmersion g] : IsPreimmersion (Limits.pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance [IsPreimmersion f] : IsPreimmersion (Limits.pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean b/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean index 615fdaa507af14..30481d9a0154cb 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean @@ -49,14 +49,17 @@ lemma isProper_eq : @IsProper = namespace IsProper +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.RespectsIso @IsProper := by rw [isProper_eq] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance stableUnderComposition : MorphismProperty.IsStableUnderComposition @IsProper := by rw [isProper_eq] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.IsMultiplicative @IsProper := by rw [isProper_eq] infer_instance @@ -65,10 +68,12 @@ instance [IsProper f] [IsProper g] : IsProper (f ≫ g) where instance (priority := 900) [IsFinite f] : IsProper f where +set_option backward.isDefEq.respectTransparency.types false in instance isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsProper := by rw [isProper_eq] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : IsZariskiLocalAtTarget @IsProper := by rw [isProper_eq] infer_instance @@ -81,6 +86,7 @@ instance (f : X ⟶ Y) (V : Y.Opens) [IsProper f] : IsProper (f ∣_ V) where end IsProper +set_option backward.isDefEq.respectTransparency.types false in lemma IsFinite.eq_isProper_inf_isAffineHom : @IsFinite = (@IsProper ⊓ @IsAffineHom : MorphismProperty _) := by have : (@IsAffineHom ⊓ @IsSeparated : MorphismProperty _) = @IsAffineHom := @@ -126,6 +132,7 @@ section GlobalSection variable (K : Type u) [Field K] +set_option backward.isDefEq.respectTransparency.types false in /-- If `f : X ⟶ Y` is universally closed and `Y` is affine, then the map on global sections is integral. -/ theorem isIntegral_appTop_of_universallyClosed (f : X ⟶ Y) [UniversallyClosed f] [IsAffine Y] : diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean index 058dc8c2279df7..f47849c2e62a5a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean @@ -133,10 +133,12 @@ instance : HasAffineProperty @QuasiCompact (fun X _ _ _ ↦ CompactSpace X) wher Opens.iSup_mk, Opens.coe_mk] exact isCompact_iUnion fun i => isCompact_iff_compactSpace.mpr (hS' i) +set_option backward.isDefEq.respectTransparency.types false in theorem compactSpace_iff_quasiCompact (X : Scheme) : CompactSpace X ↔ QuasiCompact (terminal.from X) := by rw [HasAffineProperty.iff_of_isAffine (P := @QuasiCompact)] +set_option backward.isDefEq.respectTransparency.types false in instance {X : Scheme} [CompactSpace X] : QuasiCompact X.toSpecΓ := HasAffineProperty.iff_of_isAffine.mpr ‹_› @@ -173,12 +175,15 @@ instance quasiCompact_isStableUnderBaseChange : variable {Z : Scheme.{u}} +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [QuasiCompact g] : QuasiCompact (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Z) (g : Y ⟶ Z) [QuasiCompact f] : QuasiCompact (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [QuasiCompact f] : QuasiCompact (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -205,6 +210,7 @@ lemma isCompact_iff_exists {U : X.Opens} : simp only [Set.image_univ, Scheme.Opens.range_ι] rwa [← Set.range_comp, ← TopCat.coe_comp, ← Scheme.Hom.comp_base, IsOpenImmersion.lift_fac] +set_option backward.isDefEq.respectTransparency.types false in @[stacks 01K9] nonrec lemma isClosedMap_iff_specializingMap (f : X ⟶ Y) [QuasiCompact f] : IsClosedMap f ↔ SpecializingMap f := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean index 2e85b370116bd2..00c0dccd3930ed 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiFinite.lean @@ -86,6 +86,7 @@ instance {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [LocallyQuasiFinite f] [LocallyQuasiFinite g] : LocallyQuasiFinite (f ≫ g) := MorphismProperty.comp_mem _ f g ‹_› ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (priority := low) [IsFinite f] : LocallyQuasiFinite f := by rw [HasAffineProperty.eq_targetAffineLocally @IsFinite] at ‹IsFinite f› rw [HasRingHomProperty.eq_affineLocally @LocallyQuasiFinite] @@ -114,14 +115,17 @@ instance : MorphismProperty.IsMultiplicative @LocallyQuasiFinite where instance : MorphismProperty.IsStableUnderBaseChange @LocallyQuasiFinite := HasRingHomProperty.isStableUnderBaseChange RingHom.QuasiFinite.isStableUnderBaseChange +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [LocallyQuasiFinite g] : LocallyQuasiFinite (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [LocallyQuasiFinite f] : LocallyQuasiFinite (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (V : Y.Opens) [LocallyQuasiFinite f] : LocallyQuasiFinite (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -182,6 +186,7 @@ lemma Scheme.Hom.tendsto_cofinite_cofinite [LocallyQuasiFinite f] [QuasiCompact Filter.Tendsto f .cofinite .cofinite := .cofinite_of_finite_preimage_singleton f.finite_preimage_singleton +set_option backward.isDefEq.respectTransparency.types false in nonrec lemma IsFinite.of_locallyQuasiFinite (f : X ⟶ Y) [LocallyQuasiFinite f] [QuasiCompact f] [IsLocallyArtinian Y] : IsFinite f := by change id _ -- avoid typeclass synthesis from getting stuck on the wlog hypothesis. @@ -267,6 +272,7 @@ instance (priority := low) [IsPreimmersion f] : LocallyQuasiFinite f := by .of_isPreimmersion (pullback.snd _ _) (isClosed_discrete _) infer_instance +set_option backward.isDefEq.respectTransparency.types false in nonrec lemma locallyQuasiFinite_iff_isDiscrete_preimage_singleton {f : X ⟶ Y} [LocallyOfFiniteType f] : LocallyQuasiFinite f ↔ ∀ x, IsDiscrete (f ⁻¹' {x}) := by @@ -293,6 +299,7 @@ nonrec lemma locallyQuasiFinite_iff_isDiscrete_preimage_singleton exact (Algebra.QuasiFinite.iff_finite_comap_preimage_singleton).mpr fun x ↦ ((Spec.map φ).isCompact_preimage_singleton _).finite (H _) +set_option backward.isDefEq.respectTransparency.types false in nonrec lemma LocallyQuasiFinite.of_finite_preimage_singleton [LocallyOfFiniteType f] (hf : ∀ x, (f ⁻¹' {x}).Finite) : LocallyQuasiFinite f := by change id _ -- avoid typeclass synthesis from getting stuck on the wlog hypothesis. @@ -332,6 +339,7 @@ if the stalk map `𝒪_{X, x} ⟶ 𝒪_{Y, f x}` is quasi-finite. -/ def Scheme.Hom.QuasiFiniteAt (x : X) : Prop := (f.stalkMap x).hom.QuasiFinite variable {f} in +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Hom.QuasiFiniteAt.quasiFiniteAt {x : X} (hx : f.QuasiFiniteAt x) {V : X.Opens} (hV : IsAffineOpen V) {U : Y.Opens} (hU : IsAffineOpen U) (hVU : V ≤ f ⁻¹ᵁ U) (hxV : x ∈ V.1) : diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean index f590788e7494fa..c50d910e8795f8 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean @@ -103,6 +103,7 @@ theorem quasiCompact_affineProperty_iff_quasiSeparatedSpace [IsAffine Y] (f : X theorem quasiSeparated_eq_diagonal_is_quasiCompact : @QuasiSeparated = MorphismProperty.diagonal @QuasiCompact := by ext; exact quasiSeparated_iff _ +set_option backward.isDefEq.respectTransparency.types false in instance : HasAffineProperty @QuasiSeparated (fun X _ _ _ ↦ QuasiSeparatedSpace X) where __ := HasAffineProperty.copy quasiSeparated_eq_diagonal_is_quasiCompact.symm @@ -111,6 +112,7 @@ instance : HasAffineProperty @QuasiSeparated (fun X _ _ _ ↦ QuasiSeparatedSpac instance (priority := 900) (f : X ⟶ Y) [Mono f] : QuasiSeparated f where +set_option backward.isDefEq.respectTransparency.types false in instance quasiSeparated_isStableUnderComposition : MorphismProperty.IsStableUnderComposition @QuasiSeparated := quasiSeparated_eq_diagonal_is_quasiCompact.symm ▸ inferInstance @@ -118,6 +120,7 @@ instance quasiSeparated_isStableUnderComposition : instance : MorphismProperty.IsMultiplicative @QuasiSeparated where id_mem _ := inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance quasiSeparated_isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @QuasiSeparated := quasiSeparated_eq_diagonal_is_quasiCompact.symm ▸ inferInstance @@ -126,18 +129,22 @@ instance quasiSeparated_comp (f : X ⟶ Y) (g : Y ⟶ Z) [QuasiSeparated f] [QuasiSeparated g] : QuasiSeparated (f ≫ g) := MorphismProperty.comp_mem _ f g inferInstance inferInstance +set_option backward.isDefEq.respectTransparency.types false in theorem quasiSeparatedSpace_iff_quasiSeparated (X : Scheme) : QuasiSeparatedSpace X ↔ QuasiSeparated (terminal.from X) := (HasAffineProperty.iff_of_isAffine (P := @QuasiSeparated)).symm +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [QuasiSeparated g] : QuasiSeparated (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [QuasiSeparated f] : QuasiSeparated (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [QuasiSeparated f] : QuasiSeparated (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -165,6 +172,7 @@ theorem IsAffineOpen.isQuasiSeparated {U : X.Opens} (hU : IsAffineOpen U) : rw [isQuasiSeparated_iff_quasiSeparatedSpace] exacts [@AlgebraicGeometry.quasiSeparatedSpace_of_isAffine _ hU, U.isOpen] +set_option backward.isDefEq.respectTransparency.types false in instance [QuasiSeparatedSpace X] : QuasiSeparated X.toSpecΓ := HasAffineProperty.iff_of_isAffine.mpr ‹_› @@ -221,6 +229,7 @@ theorem QuasiSeparated.of_comp (f : X ⟶ Y) (g : Y ⟶ Z) [QuasiSeparated (f (pullbackRightPullbackFstIso g (Z.affineCover.f i) f).hom · exact inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (priority := low) QuasiSeparated.of_quasiSeparatedSpace (f : X ⟶ Y) [QuasiSeparatedSpace X] : QuasiSeparated f := have : QuasiSeparated (f ≫ Y.toSpecΓ) := @@ -242,6 +251,7 @@ lemma QuasiCompact.of_comp (f : X ⟶ Y) (g : Y ⟶ Z) [QuasiCompact (f ≫ g)] QuasiCompact f := MorphismProperty.of_postcomp _ _ g ‹_› ‹_› +set_option backward.isDefEq.respectTransparency.types false in instance (priority := low) quasiCompact_of_compactSpace {X Y : Scheme} (f : X ⟶ Y) [CompactSpace X] [QuasiSeparatedSpace Y] : QuasiCompact f := have : QuasiCompact (f ≫ Y.toSpecΓ) := HasAffineProperty.iff_of_isAffine.mpr ‹_› diff --git a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean index 496276ab0b9e2d..072da19404b28a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean @@ -110,6 +110,7 @@ Also see `affineLocally_iff_affineOpens_le`. -/ abbrev affineLocally : MorphismProperty Scheme.{u} := targetAffineLocally (sourceAffineLocally P) +set_option backward.isDefEq.respectTransparency.types false in theorem sourceAffineLocally_respectsIso (h₁ : RingHom.RespectsIso P) : (sourceAffineLocally P).toProperty.RespectsIso := by apply AffineTargetMorphismProperty.respectsIso_mk @@ -128,6 +129,7 @@ theorem affineLocally_respectsIso (h : RingHom.RespectsIso P) : (affineLocally P letI := sourceAffineLocally_respectsIso P h inferInstance +set_option backward.isDefEq.respectTransparency.types false in open Scheme in theorem sourceAffineLocally_morphismRestrict {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (hU : IsAffineOpen U) : @@ -189,6 +191,7 @@ open RingHom variable {X Y : Scheme.{u}} {f : X ⟶ Y} +set_option backward.isDefEq.respectTransparency.types false in /-- If `P` holds for `f` over affine opens `U₂` of `Y` and `V₂` of `X` and `U₁` (resp. `V₁`) are open affine neighborhoods of `x` (resp. `f.base x`), then `P` also holds for `f` over some basic open of `U₁` (resp. `V₁`). -/ @@ -477,6 +480,7 @@ lemma stalkwise {P} (hP : RingHom.RespectsIso P) : S _ _ φ exact (stalkwise_SpecMap_iff hP (CommRingCat.ofHom φ)).symm +set_option backward.isDefEq.respectTransparency.types false in lemma stableUnderComposition (hP : RingHom.StableUnderComposition Q) : P.IsStableUnderComposition where comp_mem {X Y Z} f g hf hg := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean index ec6d7babd6592f..8f38f401c09c4e 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean @@ -60,12 +60,14 @@ theorem isSeparated_eq_diagonal_isClosedImmersion : /-- Monomorphisms are separated. -/ instance (priority := 900) isSeparated_of_mono [Mono f] : IsSeparated f where +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.RespectsIso @IsSeparated := by rw [isSeparated_eq_diagonal_isClosedImmersion] infer_instance instance (priority := 900) [IsSeparated f] : QuasiSeparated f where +set_option backward.isDefEq.respectTransparency.types false in instance stableUnderComposition : MorphismProperty.IsStableUnderComposition @IsSeparated := by rw [isSeparated_eq_diagonal_isClosedImmersion] infer_instance @@ -76,18 +78,22 @@ instance [IsSeparated f] [IsSeparated g] : IsSeparated (f ≫ g) := instance : MorphismProperty.IsMultiplicative @IsSeparated where id_mem _ := inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @IsSeparated := by rw [isSeparated_eq_diagonal_isClosedImmersion] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : IsZariskiLocalAtTarget @IsSeparated := by rw [isSeparated_eq_diagonal_isClosedImmersion] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [IsSeparated g] : IsSeparated (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [IsSeparated f] : IsSeparated (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance @@ -108,6 +114,7 @@ instance (R S : CommRingCat.{u}) (f : R ⟶ S) : IsSeparated (Spec.map f) := by exact .spec_of_surjective _ fun x ↦ ⟨.tmul R 1 x, (Algebra.TensorProduct.lmul'_apply_tmul (R := R) (S := S) 1 x).trans (one_mul x)⟩ +set_option backward.isDefEq.respectTransparency.types false in @[instance 100] lemma of_isAffineHom [h : IsAffineHom f] : IsSeparated f := by wlog hY : IsAffine Y @@ -197,6 +204,7 @@ lemma Scheme.Pullback.range_diagonal_subset_diagonalCoverDiagonalRange : congr 5 apply pullback.hom_ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in lemma isClosedImmersion_diagonal_restrict_diagonalCoverDiagonalRange [∀ i, IsAffine (𝒰.X i)] [∀ i j, IsAffine ((𝒱 i).X j)] : IsClosedImmersion (pullback.diagonal f ∣_ diagonalCoverDiagonalRange f 𝒰 𝒱) := by @@ -358,6 +366,7 @@ instance (f g : X ⟶ Y) [Y.IsSeparated] : IsClosedImmersion (Limits.equalizer. end Scheme +set_option backward.isDefEq.respectTransparency.types false in instance IsSeparated.hasAffineProperty : HasAffineProperty @IsSeparated fun X _ _ _ ↦ X.IsSeparated := by convert! HasAffineProperty.of_isZariskiLocalAtTarget @IsSeparated with X Y f hY diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean b/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean index e20cdadb21aa32..ccb5e910949c0a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean @@ -183,14 +183,17 @@ instance (priority := 900) [IsOpenImmersion f] : SmoothOfRelativeDimension 0 f : instance (priority := 900) [IsOpenImmersion f] : Smooth f := SmoothOfRelativeDimension.smooth 0 f +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [Smooth g] : Smooth (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [Smooth f] : Smooth (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance (f : X ⟶ Y) (V : Y.Opens) [Smooth f] : Smooth (f ∣_ V) := IsZariskiLocalAtTarget.restrict ‹_› V @@ -318,6 +321,7 @@ lemma Scheme.Hom.smoothLocus_eq_top (f : X ⟶ Y) [Smooth f] : rw [Scheme.Hom.mem_smoothLocus, formallySmooth_stalkMap_iff U hU V hV hVU hxV] exact inferInstanceAs (Algebra.IsSmoothAt _ _) +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Hom.smoothLocus_eq_top_iff {f : X ⟶ Y} [LocallyOfFinitePresentation f] : f.smoothLocus = ⊤ ↔ Smooth f := by refine ⟨fun H ↦ ?_, fun _ ↦ f.smoothLocus_eq_top⟩ @@ -358,6 +362,7 @@ lemma Scheme.Hom.genericPoint_mem_smoothLocus_of_perfectField (L := (Spec.structureSheaf K).presheaf.stalk (f (genericPoint X))) exact Algebra.FormallySmooth.of_perfectField +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Hom.dense_smoothLocus_of_perfectField {K : Type u} [Field K] [PerfectField K] [IsReduced X] (f : X ⟶ Spec (.of K)) [LocallyOfFinitePresentation f] : Dense (f.smoothLocus : Set X) := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean b/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean index 730acfea42a4df..1164abb4b6a5dc 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean @@ -54,6 +54,7 @@ instance : MorphismProperty.IsMultiplicative @SurjectiveOnStalks where rw [Scheme.Hom.stalkMap_comp] exact (f.stalkMap_surjective x).comp (g.stalkMap_surjective (f x)) +set_option backward.isDefEq.respectTransparency.types false in instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [SurjectiveOnStalks f] [SurjectiveOnStalks g] : SurjectiveOnStalks (f ≫ g) := MorphismProperty.IsStableUnderComposition.comp_mem f g inferInstance inferInstance diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean index 64b3f6a6381810..17057304c2db66 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean @@ -239,6 +239,7 @@ lemma IsDominant.of_comp [H : IsDominant (f ≫ g)] : IsDominant g := by lemma IsDominant.comp_iff [IsDominant f] : IsDominant (f ≫ g) ↔ IsDominant g := ⟨fun _ ↦ of_comp f g, fun _ ↦ inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in instance IsDominant.respectsIso : MorphismProperty.RespectsIso @IsDominant := MorphismProperty.respectsIso_of_isStableUnderComposition fun _ _ f (_ : IsIso f) ↦ inferInstance @@ -282,6 +283,7 @@ instance specializingMap_respectsIso : (topologically @SpecializingMap).Respects · introv hf hg exact hf.comp hg +set_option backward.isDefEq.respectTransparency.types false in instance specializingMap_isZariskiLocalAtTarget : IsZariskiLocalAtTarget (topologically @SpecializingMap) := by apply topologically_isZariskiLocalAtTarget diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean index 6d72007e6c9e16..bee804f020a50e 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean @@ -74,6 +74,7 @@ instance universallyClosed_isStableUnderComposition : rw [universallyClosed_eq] infer_instance +set_option backward.isDefEq.respectTransparency.types false in lemma UniversallyClosed.of_comp_surjective {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [UniversallyClosed (f ≫ g)] [Surjective f] : UniversallyClosed g := by constructor @@ -90,10 +91,12 @@ instance universallyClosedTypeComp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) instance : MorphismProperty.IsMultiplicative @UniversallyClosed where id_mem _ := inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance universallyClosed_fst {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) [hg : UniversallyClosed g] : UniversallyClosed (pullback.fst f g) := MorphismProperty.pullback_fst f g hg +set_option backward.isDefEq.respectTransparency.types false in instance universallyClosed_snd {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) [hf : UniversallyClosed f] : UniversallyClosed (pullback.snd f g) := MorphismProperty.pullback_snd f g hf @@ -164,6 +167,7 @@ lemma Scheme.Hom.isProperMap (f : X ⟶ Y) [UniversallyClosed f] : IsProperMap f instance (priority := 900) [UniversallyClosed f] : QuasiCompact f where isCompact_preimage _ _ := f.isProperMap.isCompact_preimage +set_option backward.isDefEq.respectTransparency.types false in lemma universallyClosed_eq_universallySpecializing : @UniversallyClosed = (topologically @SpecializingMap).universally ⊓ @QuasiCompact := by rw [← universally_eq_iff (P := @QuasiCompact).mpr inferInstance, ← universally_inf] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean index b4814531acfe3d..33afd04ba94e1d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean @@ -55,6 +55,7 @@ theorem universallyInjective_eq : @UniversallyInjective = universally (topologically (Injective ·)) := by ext X Y f; rw [universallyInjective_iff] +set_option backward.isDefEq.respectTransparency.types false in theorem universallyInjective_eq_diagonal : @UniversallyInjective = diagonal @Surjective := by apply le_antisymm @@ -79,9 +80,11 @@ instance (priority := 900) [Mono f] : UniversallyInjective f := have := (pullback.isIso_diagonal_iff f).mpr inferInstance (UniversallyInjective.iff_diagonal f).mpr inferInstance +set_option backward.isDefEq.respectTransparency.types false in theorem UniversallyInjective.respectsIso : RespectsIso @UniversallyInjective := universallyInjective_eq_diagonal.symm ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance UniversallyInjective.isStableUnderBaseChange : IsStableUnderBaseChange @UniversallyInjective := universallyInjective_eq_diagonal.symm ▸ inferInstance @@ -93,10 +96,12 @@ instance universallyInjective_isStableUnderComposition : instance : MorphismProperty.IsMultiplicative @UniversallyInjective where id_mem _ := inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance universallyInjective_isZariskiLocalAtTarget : IsZariskiLocalAtTarget @UniversallyInjective := universallyInjective_eq_diagonal.symm ▸ inferInstance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[stacks 01S4] theorem tfae_universallyInjective : diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean index c87624354c4ce1..9205e33a255bf4 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean @@ -79,10 +79,12 @@ instance {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) instance : MorphismProperty.IsMultiplicative @UniversallyOpen where id_mem _ := inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance fst {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) [hg : UniversallyOpen g] : UniversallyOpen (pullback.fst f g) := MorphismProperty.pullback_fst f g hg +set_option backward.isDefEq.respectTransparency.types false in instance snd {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) [hf : UniversallyOpen f] : UniversallyOpen (pullback.snd f g) := MorphismProperty.pullback_snd f g hf diff --git a/Mathlib/AlgebraicGeometry/Morphisms/WeaklyEtale.lean b/Mathlib/AlgebraicGeometry/Morphisms/WeaklyEtale.lean index 7059637e1bc0c2..61553f74a0f14f 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/WeaklyEtale.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/WeaklyEtale.lean @@ -57,33 +57,41 @@ theorem weaklyEtale_eq_flat_inf_diagonal_flat : /-- Etale morphisms are weakly étale. -/ instance (priority := 900) [Etale f] : WeaklyEtale f where +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.RespectsIso @WeaklyEtale := by rw [weaklyEtale_eq_flat_inf_diagonal_flat] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.IsMultiplicative @WeaklyEtale := by rw [weaklyEtale_eq_flat_inf_diagonal_flat] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance [WeaklyEtale f] [WeaklyEtale g] : WeaklyEtale (f ≫ g) := MorphismProperty.comp_mem _ f g inferInstance inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance : MorphismProperty.IsStableUnderBaseChange @WeaklyEtale := by rw [weaklyEtale_eq_flat_inf_diagonal_flat] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : IsZariskiLocalAtSource @WeaklyEtale := by rw [weaklyEtale_eq_flat_inf_diagonal_flat] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : IsZariskiLocalAtTarget @WeaklyEtale := by rw [weaklyEtale_eq_flat_inf_diagonal_flat] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [WeaklyEtale g] : WeaklyEtale (pullback.fst f g) := MorphismProperty.pullback_fst f g inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y S : Scheme} (f : X ⟶ S) (g : Y ⟶ S) [WeaklyEtale f] : WeaklyEtale (pullback.snd f g) := MorphismProperty.pullback_snd f g inferInstance @@ -99,6 +107,7 @@ instance (f : X ⟶ Y) (U : X.Opens) (V : Y.Opens) (e) [WeaklyEtale f] : `IsImmersion (diagonal f) → Mono (diagonal f) → IsIso (diagonal (diagonal f))`. -/ instance (f : X ⟶ Y) [WeaklyEtale f] : WeaklyEtale (pullback.diagonal f) where +set_option backward.isDefEq.respectTransparency.types false in @[stacks 0951] instance : MorphismProperty.HasOfPostcompProperty @WeaklyEtale @WeaklyEtale := by rw [MorphismProperty.hasOfPostcompProperty_iff_le_diagonal] diff --git a/Mathlib/AlgebraicGeometry/Noetherian.lean b/Mathlib/AlgebraicGeometry/Noetherian.lean index 9e57b460d25af5..69e87d81797b35 100644 --- a/Mathlib/AlgebraicGeometry/Noetherian.lean +++ b/Mathlib/AlgebraicGeometry/Noetherian.lean @@ -161,6 +161,7 @@ instance {U : X.Opens} [IsLocallyNoetherian X] : IsLocallyNoetherian U := instance {U : X.OpenCover} (i) [IsLocallyNoetherian X] : IsLocallyNoetherian (U.X i) := isLocallyNoetherian_of_isOpenImmersion (U.f i) +set_option backward.isDefEq.respectTransparency.types false in /-- If `𝒰` is an open cover of a scheme `X`, then `X` is locally Noetherian if and only if `𝒰.X i` are all locally Noetherian. -/ theorem isLocallyNoetherian_iff_openCover (𝒰 : Scheme.OpenCover X) : @@ -214,6 +215,7 @@ instance (priority := 100) {Z : Scheme} [IsLocallyNoetherian X] · exact Set.inter_subset_left · exact Set.inter_subset_right +set_option backward.isDefEq.respectTransparency.types false in /-- A locally Noetherian scheme is quasi-separated. -/ @[stacks 01OY] instance (priority := 100) IsLocallyNoetherian.quasiSeparatedSpace [IsLocallyNoetherian X] : @@ -312,6 +314,7 @@ theorem isNoetherian_iff_of_finite_affine_openCover {𝒰 : Scheme.OpenCover.{v, · exact (isLocallyNoetherian_iff_of_affine_openCover _).mpr hNoeth · exact Scheme.OpenCover.compactSpace 𝒰 +set_option backward.isDefEq.respectTransparency.types false in /-- A Noetherian scheme has a Noetherian underlying topological space. -/ @[stacks 01OZ] instance (priority := 100) IsNoetherian.noetherianSpace [IsNoetherian X] : diff --git a/Mathlib/AlgebraicGeometry/Normalization.lean b/Mathlib/AlgebraicGeometry/Normalization.lean index bba3c77eb14d13..8cc726c24bdf72 100644 --- a/Mathlib/AlgebraicGeometry/Normalization.lean +++ b/Mathlib/AlgebraicGeometry/Normalization.lean @@ -155,6 +155,7 @@ def toNormalization : X ⟶ f.normalization := rw [← Spec.map_comp_assoc] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma ι_toNormalization (U : Y.affineOpens) : @@ -179,6 +180,7 @@ lemma ι_fromNormalization (U : Y.affineOpens) : Spec.map (f.normalizationDiagramMap.app (.op U.1)) ≫ U.2.fromSpec := colimit.ι_desc _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma fromNormalization_preimage (U : Y.affineOpens) : f.fromNormalization ⁻¹ᵁ U = (f.normalizationOpenCover.f U).opensRange := by simpa using! f.normalizationGlueData.toBase_preimage_eq_opensRange_ι U @@ -211,6 +213,7 @@ instance : IsIntegralHom f.fromNormalization := by rw [← cancel_mono U.2.fromSpec] simp [IsAffineOpen.isoSpec_hom, e, ι_fromNormalization] +set_option backward.isDefEq.respectTransparency.types false in /-- The sections of the relative normalization on the preimage of an affine open is isomorphic to the integral closure. -/ noncomputable @@ -340,6 +343,7 @@ instance : IsDominant f.toNormalization := by rw [IdealSheafData.support_bot, Scheme.Hom.support_ker, TopologicalSpace.Closeds.coe_top] at this exact ⟨dense_iff_closure_eq.mpr this⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[stacks 0AXN] instance [IsReduced X] : IsReduced f.normalization := diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index 1f2c719581f96d..bfe8038c5d0f9d 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -221,16 +221,19 @@ lemma isIso_app (V : Y.Opens) (hV : V ≤ f.opensRange) : IsIso (f.app V) := by rw [show V = f ''ᵁ f ⁻¹ᵁ V from Opens.ext (Set.image_preimage_eq_of_subset hV).symm] infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism `Γ(Y, f(U)) ≅ Γ(X, U)` induced by an open immersion `f : X ⟶ Y`. -/ def appIso (U) : Γ(Y, f ''ᵁ U) ≅ Γ(X, U) := (asIso <| LocallyRingedSpace.IsOpenImmersion.invApp f.toLRSHom U).symm +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem appIso_inv_naturality {U V : X.Opens} (i : op U ⟶ op V) : X.presheaf.map i ≫ (f.appIso V).inv = (f.appIso U).inv ≫ Y.presheaf.map (f.opensFunctor.op.map i) := PresheafedSpace.IsOpenImmersion.inv_naturality _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem appIso_hom (U) : (f.appIso U).hom = f.app (f ''ᵁ U) ≫ X.presheaf.map (eqToHom (preimage_image_eq f U).symm).op := @@ -248,12 +251,14 @@ lemma appIso_hom_naturality {U V : X.Opens} (i : op U ⟶ op V) : (f.appIso U).hom ≫ X.presheaf.map i := by simp [← cancel_mono (f.appIso V).inv] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem app_appIso_inv (U) : f.app U ≫ (f.appIso (f ⁻¹ᵁ U)).inv = Y.presheaf.map (homOfLE (Set.image_preimage_subset f U.1)).op := PresheafedSpace.IsOpenImmersion.app_invApp _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `app_invApp` that gives an `eqToHom` instead of `homOfLE`. -/ @[reassoc] theorem app_invApp' (U) (hU : U ≤ f.opensRange) : @@ -267,6 +272,7 @@ theorem appIso_inv_app (U) : (f.appIso U).inv ≫ f.app (f ''ᵁ U) = X.presheaf.map (eqToHom (preimage_image_eq f U)).op := (PresheafedSpace.IsOpenImmersion.invApp_app _ _).trans (by rw [eqToHom_op]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp), elementwise nosimp] lemma appLE_appIso_inv {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] {U : Y.Opens} @@ -299,6 +305,7 @@ lemma id_appIso (U : X.Opens) : (𝟙 X :).appIso U = X.presheaf.mapIso (eqToIso (by simp)).op := by ext; simp [appIso_hom] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma comp_appIso {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) [IsOpenImmersion f] [IsOpenImmersion g] (U : X.Opens) : @@ -330,6 +337,7 @@ instance {R} [CommRing R] (f : R) : IsOpenImmersion (Spec.map (CommRingCat.ofHom (algebraMap R (Localization.Away f)))) := isOpenImmersion_SpecMap_localizationAway (R := .of R) f +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Hom.opensRange_localizationAway {R : CommRingCat.{u}} (g : R) : (Spec.map <| CommRingCat.ofHom <| algebraMap R (Localization.Away g)).opensRange = @@ -450,6 +458,7 @@ lemma Scheme.ofRestrict_appLE (V W e) : dsimp [Hom.appLE] exact (X.presheaf.map_comp _ _).symm +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Scheme.ofRestrict_appIso (U) : (X.ofRestrict h).appIso U = Iso.refl _ := by @@ -483,6 +492,7 @@ theorem of_isIso_stalkMap {X Y : Scheme.{u}} (f : X ⟶ Y) (hf : IsOpenEmbedding have (x : X) : IsIso (f.toShHom.hom.stalkMap x) := inferInstanceAs (IsIso (f.stalkMap x)) SheafedSpace.IsOpenImmersion.of_stalk_iso f.toShHom hf +set_option backward.isDefEq.respectTransparency.types false in instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] (x : X) : IsIso (f.stalkMap x) := inferInstanceAs <| IsIso (f.toLRSHom.stalkMap x) @@ -562,6 +572,7 @@ instance hasLimit_cospan_forget_of_right' : HasLimit (cospan ((cospan g f ⋙ forget).map Hom.inl) ((cospan g f ⋙ forget).map Hom.inr)) := show HasLimit (cospan ((forget).map g) ((forget).map f)) from inferInstance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance forgetCreatesPullbackOfLeft : CreatesLimit (cospan f g) forget := createsLimitOfFullyFaithfulOfIso @@ -597,6 +608,7 @@ instance : IsOpenImmersion (pullback.fst g f) := by rw [← pullbackSymmetry_hom_comp_snd] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance [IsOpenImmersion g] : IsOpenImmersion (limit.π (cospan f g) WalkingCospan.one) := by rw [← limit.w (cospan f g) WalkingCospan.Hom.inl] @@ -855,6 +867,7 @@ lemma image_zeroLocus {U : X.Opens} (s : Set Γ(X, U)) : · simp only [Set.mem_inter_iff, hx, and_false, iff_false] exact fun H ↦ hx (Set.image_subset_range _ _ H) +set_option backward.isDefEq.respectTransparency.types false in /-- If ``` P --fst--> X diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean index 20efeb92e9c7e6..90bdc38383456e 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Basic.lean @@ -140,6 +140,7 @@ noncomputable def basicOpenToSpec : (basicOpen 𝒜 f).toScheme ⟶ Spec (.of <| Away 𝒜 f) := (basicOpen 𝒜 f).toSpecΓ ≫ Spec.map (awayToSection 𝒜 f) +set_option backward.isDefEq.respectTransparency.types false in lemma basicOpenToSpec_app_top : (basicOpenToSpec 𝒜 f).app ⊤ = (Scheme.ΓSpecIso _).hom ≫ awayToSection 𝒜 f ≫ (basicOpen 𝒜 f).topIso.inv := by @@ -348,6 +349,7 @@ end basicOpen section stalk +set_option backward.isDefEq.respectTransparency.types false in /-- The stalk of `Proj A` at `x` is the degree `0` part of the localization of `A` at `x`. -/ noncomputable def stalkIso (x : Proj 𝒜) : @@ -374,6 +376,7 @@ def toBasicOpenOfGlobalSections (H : f t = x) (h0d : 0 < d) (hd : t ∈ 𝒜 d) · rw [← Submonoid.map_le_iff_le_comap, Submonoid.map_powers] simp [H] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma homOfLE_toBasicOpenOfGlobalSections_ι {H : f t = x} {h0d : 0 < d} {hd : t ∈ 𝒜 d} {H' : f t' = x'} {h0d' : 0 < d'} {hd' : t' ∈ 𝒜 d'} @@ -405,6 +408,7 @@ lemma homOfLE_toBasicOpenOfGlobalSections_ι variable (f : A →+* Γ(X, ⊤)) (hf : (HomogeneousIdeal.irrelevant 𝒜).toIdeal.map f = ⊤) +set_option backward.isDefEq.respectTransparency false in /-- Given a graded ring `A` and a map `f : A →+* Γ(X, ⊤)` such that the image of the irrelevant ideal under `f` generates the whole ring, the set of `D(f(r))` for homogeneous `r` of positive degree forms an open cover on `X`. -/ @@ -432,6 +436,7 @@ def openCoverOfMapIrrelevantEqTop : X.OpenCover := rw [← Scheme.zeroLocus_span, Set.range_comp', ← Ideal.map_span, H, hf] simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a graded ring `A` and a map `f : A →+* Γ(X, ⊤)` such that the image of the irrelevant ideal under `f` generates the whole ring, we can construct a map `X ⟶ Proj 𝒜`. -/ @@ -487,6 +492,7 @@ lemma fromOfGlobalSections_preimage_basicOpen {r : A} {n : ℕ} (hn : 0 < n) (hr ← Scheme.Hom.comp_apply, fromOfGlobalSections] simp +set_option backward.isDefEq.respectTransparency.types false in lemma fromOfGlobalSections_morphismRestrict {r : A} {n : ℕ} (hn : 0 < n) (hr : r ∈ 𝒜 n) : (fromOfGlobalSections 𝒜 f hf) ∣_ (basicOpen 𝒜 r) = (Scheme.isoOfEq _ (fromOfGlobalSections_preimage_basicOpen _ _ _ hn hr)).hom ≫ diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Functor.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Functor.lean index e087a6d8ef7445..19b55940cfcc83 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Functor.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Functor.lean @@ -95,6 +95,7 @@ variable {A B C σ τ ψ : Type u} [CommRing A] [SetLike σ A] [AddSubgroupClass {𝒜 : ℕ → σ} {ℬ : ℕ → τ} {𝒞 : ℕ → ψ} [GradedRing 𝒜] [GradedRing ℬ] [GradedRing 𝒞] (f : 𝒜 →+*ᵍ ℬ) (g : ℬ →+*ᵍ 𝒞) (hf : ℬ₊ ≤ 𝒜₊.map f) (hg : 𝒞₊ ≤ ℬ₊.map g) +set_option backward.isDefEq.respectTransparency.types false in /-- The underlying map of `Proj ℬ ⟶ Proj 𝒜` on the level of sheafed spaces. -/ @[simps! (isSimp := false)] noncomputable def sheafedSpaceMap : Proj.toSheafedSpace ℬ ⟶ Proj.toSheafedSpace 𝒜 where @@ -102,6 +103,7 @@ variable {A B C σ τ ψ : Type u} [CommRing A] [SetLike σ A] [AddSubgroupClass { base := TopCat.ofHom <| comap f hf c := { app U := CommRingCat.ofHom <| comapStructureSheaf f hf _ _ Set.Subset.rfl } } +set_option backward.isDefEq.respectTransparency.types false in lemma germ_map_sectionInBasicOpen {p : ProjectiveSpectrum ℬ} (c : NumDenSameDeg 𝒜 (p.comap f hf).1.toIdeal.primeCompl) : (toSheafedSpace ℬ).presheaf.germ @@ -112,12 +114,14 @@ lemma germ_map_sectionInBasicOpen {p : ProjectiveSpectrum ℬ} (sectionInBasicOpen ℬ p (c.map _ le_rfl)) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma val_sectionInBasicOpen_apply (p : ProjectiveSpectrum.top 𝒜) (c : NumDenSameDeg 𝒜 p.1.toIdeal.primeCompl) (q : ProjectiveSpectrum.basicOpen 𝒜 c.den) : ((sectionInBasicOpen 𝒜 p c).val q).val = .mk c.num ⟨c.den, q.2⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[elementwise] theorem localRingHom_comp_stalkIso (p : ProjectiveSpectrum ℬ) : (stalkIso 𝒜 (ProjectiveSpectrum.comap f hf p)).hom ≫ CommRingCat.ofHom (localRingHom f _ _ rfl) ≫ @@ -156,9 +160,11 @@ noncomputable def map : Proj ℬ ⟶ Proj 𝒜 where @[simp] theorem map_preimage_basicOpen (s : A) : map f hf ⁻¹ᵁ basicOpen 𝒜 s = basicOpen ℬ (f s) := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem ι_comp_map (s : A) : (basicOpen ℬ (f s)).ι ≫ map f hf = (map f hf).resLE _ _ le_rfl ≫ (basicOpen 𝒜 s).ι := by simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma awayToSection_comp_appLE {i : ℕ} {s : A} (hs : s ∈ 𝒜 i) : awayToSection 𝒜 s ≫ Scheme.Hom.appLE (map f hf) (basicOpen 𝒜 s) (basicOpen ℬ (f s)) (by rfl) = diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean index 421865fdbc6e94..f578b1e1712af9 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Proper.lean @@ -125,6 +125,7 @@ instance isSeparated : IsSeparated (toSpecZero 𝒜) := by exact DFunLike.congr_fun (Algebra.TensorProduct.lift_comp_includeRight (awayMapₐ 𝒜 j.2.2 rfl) (awayMapₐ 𝒜 i.2.2 (mul_comm _ _)) (fun _ _ ↦ .all _ _)).symm x +set_option backward.isDefEq.respectTransparency.types false in @[stacks 01MC] instance : Scheme.IsSeparated (Proj 𝒜) := (HasAffineProperty.iff_of_isAffine (P := @IsSeparated)).mp (isSeparated 𝒜) @@ -133,6 +134,7 @@ end IsSeparated section LocallyOfFiniteType +set_option backward.isDefEq.respectTransparency.types false in instance [Algebra.FiniteType (𝒜 0) A] : LocallyOfFiniteType (Proj.toSpecZero 𝒜) := by obtain ⟨x, hx, hx'⟩ := GradedAlgebra.exists_finset_adjoin_eq_top_and_homogeneous_ne_zero 𝒜 choose d hd hxd using hx' @@ -148,6 +150,7 @@ end LocallyOfFiniteType section QuasiCompact +set_option backward.isDefEq.respectTransparency.types false in instance [Algebra.FiniteType (𝒜 0) A] : QuasiCompact (Proj.toSpecZero 𝒜) := by rw [HasAffineProperty.iff_of_isAffine (P := @QuasiCompact)] obtain ⟨x, hx, hx'⟩ := GradedAlgebra.exists_finset_adjoin_eq_top_and_homogeneous_ne_zero 𝒜 @@ -309,6 +312,7 @@ theorem valuativeCriterion_existence_aux Finset.univ.prod_erase_mul d (h := Finset.mem_univ _), mul_comm _ a, mul_right_comm] +set_option backward.isDefEq.respectTransparency.types false in @[stacks 01MF] lemma valuativeCriterion_existence [Algebra.FiniteType (𝒜 0) A] : ValuativeCriterion.Existence (Proj.toSpecZero 𝒜) := by diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index b5584e1c408462..86ddc99037b082 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -174,6 +174,7 @@ def carrier : Ideal (A⁰_ f) := Ideal.comap (algebraMap (A⁰_ f) (Away f)) (x.val.asHomogeneousIdeal.toIdeal.map (algebraMap A (Away f))) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mk_mem_carrier (z : HomogeneousLocalization.NumDenSameDeg 𝒜 (.powers f)) : HomogeneousLocalization.mk z ∈ carrier x ↔ z.num.1 ∈ x.1.asHomogeneousIdeal := by @@ -186,6 +187,7 @@ theorem mk_mem_carrier (z : HomogeneousLocalization.NumDenSameDeg 𝒜 (.powers · exact (disjoint_powers_iff_notMem_of_isPrime _).mpr x.2 · exact isUnit_of_invertible _ +set_option backward.isDefEq.respectTransparency.types false in theorem isPrime_carrier : Ideal.IsPrime (carrier x) := by refine Ideal.IsPrime.comap _ (hK := ?_) exact IsLocalization.isPrime_of_isPrime_disjoint @@ -307,6 +309,7 @@ theorem mem_carrier_iff_of_mem (hm : 0 < m) (q : Spec.T A⁰_ f) (a : A) {n} (hn HomogeneousLocalization.val_mk, Localization.mk_zero, HomogeneousLocalization.val_zero] · simp only [proj_apply, decompose_of_mem_same _ hn] +set_option backward.isDefEq.respectTransparency.types false in theorem mem_carrier_iff_of_mem_mul (hm : 0 < m) (q : Spec.T A⁰_ f) (a : A) {n} (hn : a ∈ 𝒜 (n * m)) : a ∈ carrier f_deg q ↔ (HomogeneousLocalization.mk ⟨m * n, ⟨a, mul_comm n m ▸ hn⟩, @@ -613,6 +616,7 @@ lemma awayToSection_germ (f x hx) : apply (Proj.stalkIso' 𝒜 x).eq_symm_apply.mpr apply Proj.stalkIso'_germ +set_option backward.isDefEq.respectTransparency.types false in lemma awayToSection_apply (f : A) (x p) : (((ProjectiveSpectrum.Proj.awayToSection 𝒜 f).1 x).val p).val = IsLocalization.map (M := Submonoid.powers f) (T := p.1.1.toIdeal.primeCompl) _ @@ -667,6 +671,7 @@ lemma toSpec_base_apply_eq_comap {f} (x : Proj| pbo f) : (HomogeneousLocalization.AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) _ _ ((Proj| pbo f).presheaf.stalk x) _ _ _ (isLocalHom_of_isIso _))) +set_option backward.isDefEq.respectTransparency.types false in lemma toSpec_base_apply_eq {f} (x : Proj| pbo f) : (toSpec 𝒜 f).base x = ProjIsoSpecTopComponent.toSpec 𝒜 f x := toSpec_base_apply_eq_comap 𝒜 x |>.trans <| PrimeSpectrum.ext <| Ideal.ext fun z => @@ -689,6 +694,7 @@ lemma mk_mem_toSpec_base_apply {f} (x : Proj| pbo f) z.num.1 ∈ x.1.asHomogeneousIdeal := (toSpec_base_apply_eq 𝒜 x).symm ▸ ProjIsoSpecTopComponent.ToSpec.mk_mem_carrier _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma toSpec_preimage_basicOpen {f} (t : NumDenSameDeg 𝒜 (.powers f)) : (Opens.map (toSpec 𝒜 f).base).obj (sbo (HomogeneousLocalization.mk t)) = @@ -697,6 +703,9 @@ lemma toSpec_preimage_basicOpen {f} convert! (ProjIsoSpecTopComponent.ToSpec.preimage_basicOpen f t) exact funext fun _ => toSpec_base_apply_eq _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma toOpen_toSpec_val_c_app (f) (U) : (Scheme.ΓSpecIso _).inv ≫ (Spec A⁰_ f).presheaf.map (homOfLE le_top).op ≫ @@ -774,6 +783,7 @@ lemma isLocalization_atPrime (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 rw [mul_left_comm, mul_left_comm y.den.1, ← tsub_add_cancel_of_le (show 1 ≤ m from hm), pow_succ, mul_assoc, mul_assoc, e] +set_option backward.isDefEq.respectTransparency.types false in /-- For an element `f ∈ A` with positive degree and a homogeneous ideal in `D(f)`, we have that the stalk of `Spec A⁰_ f` at `y` is isomorphic to `A⁰ₓ` where `y` is the point in `Proj` corresponding @@ -791,6 +801,7 @@ def specStalkEquiv (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x)) (Q := AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal)).toRingEquiv.toCommRingCatIso +set_option backward.isDefEq.respectTransparency.types false in lemma toStalk_specStalkEquiv (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : StructureSheaf.toStalk (A⁰_ f) ((toSpec 𝒜 f).base x) ≫ (specStalkEquiv 𝒜 f x f_deg hm).hom = CommRingCat.ofHom (mapId _ <| Submonoid.powers_le.mpr x.2) := @@ -803,6 +814,7 @@ lemma toStalk_specStalkEquiv (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x)) (Q := AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal)).toAlgHom.comp_algebraMap +set_option backward.isDefEq.respectTransparency.types false in lemma stalkMap_toSpec (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : (toSpec 𝒜 f).stalkMap x = (specStalkEquiv 𝒜 f x f_deg hm).hom ≫ (Proj.stalkIso' 𝒜 x.1).toCommRingCatIso.inv ≫ @@ -836,6 +848,7 @@ def projIsoSpec (f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : (Proj| pbo f) ≅ (Spec (A⁰_ f)) := @asIso _ _ _ _ (f := toSpec 𝒜 f) (isIso_toSpec 𝒜 f f_deg hm) +set_option backward.isDefEq.respectTransparency false in /-- This is the scheme `Proj(A)` for any `ℕ`-graded ring `A`. -/ diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean index 90159f71e32c95..af6d17878b20f6 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean @@ -68,6 +68,7 @@ local notation3 "at " x => namespace ProjectiveSpectrum.StructureSheaf +set_option backward.isDefEq.respectTransparency.types false in variable {𝒜} in /-- The predicate saying that a dependent function on an open `U` is realised as a fixed fraction `r / s` of *same grading* in each of the stalks (which are localizations at various prime ideals). @@ -75,6 +76,7 @@ variable {𝒜} in def IsFraction {U : Opens (ProjectiveSpectrum.top 𝒜)} (f : ∀ x : U, at x.1) : Prop := ∃ (i : ℕ) (r s : 𝒜 i) (s_nin : ∀ x : U, s.1 ∉ x.1.asHomogeneousIdeal), ∀ x : U, f x = .mk ⟨i, r, s, s_nin x⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The predicate `IsFraction` is "prelocal", in the sense that if it holds on `U` it holds on any open subset `V` of `U`. @@ -83,6 +85,7 @@ def isFractionPrelocal : PrelocalPredicate fun x : ProjectiveSpectrum.top 𝒜 = pred f := IsFraction f res := by rintro V U i f ⟨j, r, s, h, w⟩; exact ⟨j, r, s, (h <| i ·), (w <| i ·)⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- We will define the structure sheaf as the subsheaf of all dependent functions in `Π x : U, HomogeneousLocalization 𝒜 x` consisting of those functions which can locally be expressed as a ratio of `A` of same grading. -/ @@ -95,14 +98,17 @@ variable {𝒜} open Submodule SetLike.GradedMonoid HomogeneousLocalization +set_option backward.isDefEq.respectTransparency.types false in theorem zero_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) : (isLocallyFraction 𝒜).pred (0 : ∀ x : U.unop, at x.1) := fun x => ⟨unop U, x.2, 𝟙 (unop U), ⟨0, ⟨0, zero_mem _⟩, ⟨1, one_mem_graded _⟩, _, fun _ => rfl⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem one_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) : (isLocallyFraction 𝒜).pred (1 : ∀ x : U.unop, at x.1) := fun x => ⟨unop U, x.2, 𝟙 (unop U), ⟨0, ⟨1, one_mem_graded _⟩, ⟨1, one_mem_graded _⟩, _, fun _ => rfl⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem add_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) (a b : ∀ x : U.unop, at x.1) (ha : (isLocallyFraction 𝒜).pred a) (hb : (isLocallyFraction 𝒜).pred b) : (isLocallyFraction 𝒜).pred (a + b) := fun x => by @@ -119,6 +125,7 @@ theorem add_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) (a b : ∀ x simp only [Subtype.forall, Opens.apply_mk] at wa wb simp [wa y hy.1, wb y hy.2, ext_iff_val, add_mk, add_comm (sa * rb)] +set_option backward.isDefEq.respectTransparency.types false in theorem neg_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) (a : ∀ x : U.unop, at x.1) (ha : (isLocallyFraction 𝒜).pred a) : (isLocallyFraction 𝒜).pred (-a) := fun x => by rcases ha x with ⟨V, m, i, j, ⟨r, r_mem⟩, ⟨s, s_mem⟩, nin, hy⟩ @@ -126,6 +133,7 @@ theorem neg_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) (a : ∀ x : simp only [ext_iff_val, val_mk] at hy simp only [Pi.neg_apply, ext_iff_val, val_neg, hy, val_mk, neg_mk] +set_option backward.isDefEq.respectTransparency.types false in theorem mul_mem' (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) (a b : ∀ x : U.unop, at x.1) (ha : (isLocallyFraction 𝒜).pred a) (hb : (isLocallyFraction 𝒜).pred b) : (isLocallyFraction 𝒜).pred (a * b) := fun x => by @@ -148,6 +156,7 @@ open SectionSubring variable {𝒜} +set_option backward.isDefEq.respectTransparency.types false in /-- The functions satisfying `isLocallyFraction` form a subring of all dependent functions `Π x : U, HomogeneousLocalization 𝒜 x`. -/ def sectionsSubring (U : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ) : @@ -206,7 +215,7 @@ end ProjectiveSpectrum section -open ProjectiveSpectrum ProjectiveSpectrum.StructureSheaf Opens +open AlgebraicGeometry.ProjectiveSpectrum ProjectiveSpectrum.StructureSheaf Opens section variable {U V : (Opens (ProjectiveSpectrum.top 𝒜))ᵒᵖ} (i : V ⟶ U) @@ -231,6 +240,7 @@ def Proj.toSheafedSpace : SheafedSpace CommRingCat where presheaf := (Proj.structureSheaf 𝒜).1 IsSheaf := (Proj.structureSheaf 𝒜).2 +set_option backward.isDefEq.respectTransparency.types false in /-- The ring homomorphism that takes a section of the structure sheaf of `Proj` on the open set `U`, implemented as a subtype of dependent functions to localizations at homogeneous prime ideals, and evaluates the section on the point corresponding to a given homogeneous prime ideal. -/ @@ -243,6 +253,7 @@ def openToLocalization (U : Opens (ProjectiveSpectrum.top 𝒜)) (x : Projective map_zero' := rfl map_add' _ _ := rfl } +set_option backward.isDefEq.respectTransparency.types false in /-- The ring homomorphism from the stalk of the structure sheaf of `Proj` at a point corresponding to a homogeneous prime ideal `x` to the *homogeneous localization* at `x`, formed by gluing the `openToLocalization` maps. -/ @@ -274,6 +285,7 @@ theorem mem_basicOpen_den (x : ProjectiveSpectrum.top 𝒜) rw [ProjectiveSpectrum.mem_basicOpen] exact f.den_mem +set_option backward.isDefEq.respectTransparency.types false in /-- Given a point `x` corresponding to a homogeneous prime ideal, there is a (dependent) function such that, for any `f` in the homogeneous localization at `x`, it returns the obvious section in the basic open set `D(f.den)`. -/ @@ -285,6 +297,7 @@ def sectionInBasicOpen (x : ProjectiveSpectrum.top 𝒜) : ⟨ProjectiveSpectrum.basicOpen 𝒜 f.den, y.2, ⟨𝟙 _, ⟨f.deg, ⟨f.num, f.den, _, fun _ => rfl⟩⟩⟩⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in open HomogeneousLocalization in /-- Given any point `x` and `f` in the homogeneous localization at `x`, there is an element in the stalk at `x` obtained by `sectionInBasicOpen`. This is the inverse of `stalkToFiberRingHom`. @@ -328,12 +341,14 @@ lemma homogeneousLocalizationToStalk_stalkToFiberRingHom (x z) : rw [Proj.res_apply, Proj.res_apply] simp [sectionInBasicOpen, HomogeneousLocalization.val_mk, Localization.mk_eq_mk', e t ht] +set_option backward.isDefEq.respectTransparency.types false in lemma stalkToFiberRingHom_homogeneousLocalizationToStalk (x z) : stalkToFiberRingHom 𝒜 x (homogeneousLocalizationToStalk 𝒜 x z) = z := by obtain ⟨z, rfl⟩ := Quotient.mk''_surjective z rw [homogeneousLocalizationToStalk, Quotient.liftOn'_mk'', stalkToFiberRingHom_germ, sectionInBasicOpen] +set_option backward.isDefEq.respectTransparency.types false in /-- Using `homogeneousLocalizationToStalk`, we construct a ring isomorphism between stalk at `x` and homogeneous localization at `x` for any point `x` in `Proj`. -/ def Proj.stalkIso' (x : ProjectiveSpectrum.top 𝒜) : @@ -354,6 +369,7 @@ theorem Proj.stalkIso'_symm_mk (x) (f) : (Proj.stalkIso' 𝒜 x).symm (.mk f) = (Proj.structureSheaf 𝒜).presheaf.germ _ x (mem_basicOpen_den _ x f) (sectionInBasicOpen _ x f) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `Proj` of a graded ring as a `LocallyRingedSpace` -/ def Proj.toLocallyRingedSpace : LocallyRingedSpace := { Proj.toSheafedSpace 𝒜 with diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean index 8f5630f669eab2..911ffad935d36b 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean @@ -126,6 +126,7 @@ theorem gc_ideal : (fun I => zeroLocus 𝒜 I) fun t => (vanishingIdeal t).toIdeal := fun I t => subset_zeroLocus_iff_le_vanishingIdeal t I +set_option backward.isDefEq.respectTransparency.types false in /-- `zeroLocus` and `vanishingIdeal` form a Galois connection. -/ theorem gc_set : @GaloisConnection (Set A) (Set (ProjectiveSpectrum 𝒜))ᵒᵈ _ _ diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index 760c2610436a9c..638debbb876ee6 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -110,6 +110,7 @@ instance {𝒰 : X.OpenCover} [IsReduced X] (i : 𝒰.I₀) : IsReduced (𝒰.X instance : ObjectProperty.IsClosedUnderIsomorphisms (C := Scheme) (IsReduced ·) := ⟨fun e _ ↦ isReduced_of_isOpenImmersion e.inv⟩ +set_option backward.isDefEq.respectTransparency.types false in instance {R : CommRingCat.{u}} [H : _root_.IsReduced R] : IsReduced (Spec R) := by apply +allowSynthFailures isReduced_of_isReduced_stalk intro x @@ -213,6 +214,7 @@ theorem basicOpen_eq_bot_iff {X : Scheme} [IsReduced X] {U : X.Opens} rintro rfl simp +set_option backward.isDefEq.respectTransparency.types false in /-- If `X` is reduced and has finitely many irreducible components, then the stalks at the generic points of the irreducible components are fields. -/ lemma isField_stalk_of_closure_mem_irreducibleComponents @@ -360,6 +362,7 @@ open IrreducibleCloseds Set in lemma coheight_eq_of_isOpenImmersion {U X : Scheme} {x : U} (f : U ⟶ X) [IsOpenImmersion f] : Order.coheight (f.base x) = Order.coheight x := f.isOpenEmbedding.coheight_eq +set_option backward.isDefEq.respectTransparency.types false in open Order in lemma idealHeight_eq_coheight (R : CommRingCat) (x : Spec R) : x.asIdeal.height = coheight x := by @@ -367,6 +370,7 @@ lemma idealHeight_eq_coheight (R : CommRingCat) (x : Spec R) : ← Order.coheight_orderIso (specOrderIsoPrimeSpectrum R), ← height_ofDual, specOrderIsoPrimeSpectrum_apply, OrderDual.ofDual_toDual] +set_option backward.isDefEq.respectTransparency.types false in open Order in @[stacks 02IZ] lemma ringKrullDim_stalk_eq_coheight {X : Scheme} (x : X) : diff --git a/Mathlib/AlgebraicGeometry/PullbackCarrier.lean b/Mathlib/AlgebraicGeometry/PullbackCarrier.lean index 011991bfa3ae35..a527a4636647ec 100644 --- a/Mathlib/AlgebraicGeometry/PullbackCarrier.lean +++ b/Mathlib/AlgebraicGeometry/PullbackCarrier.lean @@ -183,6 +183,7 @@ lemma ofPoint_SpecTensorTo (T : Triplet f g) (p : Spec T.tensor) : end Triplet +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma residueFieldCongr_inv_residueFieldMap_ofPoint (t : ↑(pullback f g)) : ((S.residueFieldCongr (Triplet.ofPoint t).hx).inv ≫ f.residueFieldMap (Triplet.ofPoint t).x) ≫ @@ -219,6 +220,7 @@ point of `Spec κ(s)` in `Spec κ(x) ⊗[κ(s)] κ(y)`. -/ def SpecOfPoint (t : ↑(pullback f g)) : Spec (Triplet.ofPoint t).tensor := Spec.map (ofPointTensor t) (⊥ : PrimeSpectrum _) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma SpecTensorTo_SpecOfPoint (t : ↑(pullback f g)) : (Triplet.ofPoint t).SpecTensorTo (SpecOfPoint t) = t := by @@ -254,6 +256,7 @@ lemma carrierEquiv_eq_iff {T₁ T₂ : Σ T : Triplet f g, Spec T.tensor} : rintro ⟨rfl : T = T', e⟩ simpa [e] +set_option backward.isDefEq.respectTransparency.types false in /-- The points of the underlying topological space of `X ×[S] Y` bijectively correspond to pairs of triples `x : X`, `y : Y`, `s : S` with `f x = s = f y` and prime ideals of @@ -274,11 +277,13 @@ def carrierEquiv : ↑(pullback f g) ≃ Σ T : Triplet f g, Spec T.tensor where ← Scheme.Hom.comp_apply] simp [Triplet.Spec_ofPointTensor_SpecTensorTo] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma carrierEquiv_symm_fst (T : Triplet f g) (p : Spec T.tensor) : pullback.fst f g (carrierEquiv.symm ⟨T, p⟩) = T.x := by simp [carrierEquiv] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma carrierEquiv_symm_snd (T : Triplet f g) (p : Spec T.tensor) : pullback.snd f g (carrierEquiv.symm ⟨T, p⟩) = T.y := by @@ -434,10 +439,12 @@ instance : MorphismProperty.IsStableUnderBaseChange @Surjective := by simp only [surjective_iff, ← Set.range_eq_univ, Scheme.Pullback.range_fst] at hg ⊢ rw [hg, Set.preimage_univ] +set_option backward.isDefEq.respectTransparency.types false in instance {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) [Surjective g] : Surjective (pullback.fst f g) := MorphismProperty.pullback_fst _ _ inferInstance +set_option backward.isDefEq.respectTransparency.types false in instance {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) [Surjective f] : Surjective (pullback.snd f g) := MorphismProperty.pullback_snd _ _ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Pullbacks.lean b/Mathlib/AlgebraicGeometry/Pullbacks.lean index 1a38ac3c192834..2f852a88ce9af7 100644 --- a/Mathlib/AlgebraicGeometry/Pullbacks.lean +++ b/Mathlib/AlgebraicGeometry/Pullbacks.lean @@ -43,7 +43,7 @@ variable {X Y Z : Scheme.{u}} (𝒰 : OpenCover.{u} X) (f : X ⟶ Z) (g : Y ⟶ variable [∀ i, HasPullback (𝒰.f i ≫ f) g] /-- The intersection of `Uᵢ ×[Z] Y` and `Uⱼ ×[Z] Y` is given by (Uᵢ ×[Z] Y) ×[X] Uⱼ -/ -@[implicit_reducible] +@[instance_reducible] def v (i j : 𝒰.I₀) : Scheme := pullback ((pullback.fst (𝒰.f i ≫ f) g) ≫ 𝒰.f i) (𝒰.f j) @@ -219,12 +219,14 @@ def gluing : Scheme.GlueData.{u} where lemma gluing_ι (j : 𝒰.I₀) : (gluing 𝒰 f g).ι j = Multicoequalizer.π (gluing 𝒰 f g).diagram j := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The first projection from the glued scheme into `X`. -/ def p1 : (gluing 𝒰 f g).glued ⟶ X := by apply Multicoequalizer.desc (gluing 𝒰 f g).diagram _ fun i ↦ pullback.fst _ _ ≫ 𝒰.f i simp [t_fst_fst_assoc, ← pullback.condition] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The second projection from the glued scheme into `Y`. -/ def p2 : (gluing 𝒰 f g).glued ⟶ Y := by @@ -318,6 +320,7 @@ theorem gluedLift_p2 : gluedLift 𝒰 f g s ≫ p2 𝒰 f g = s.snd := by simp_rw [(Cover.ι_glueMorphisms <| 𝒰.pullback₁ s.fst)] simp [p2] +set_option backward.isDefEq.respectTransparency.types false in /-- (Implementation) The canonical map `(W ×[X] Uᵢ) ×[W] (Uⱼ ×[Z] Y) ⟶ (Uⱼ ×[Z] Y) ×[X] Uᵢ = V j i` where `W` is the glued fibred product. @@ -397,11 +400,13 @@ theorem pullbackP1Iso_hom_snd (i : 𝒰.I₀) : (pullbackP1Iso 𝒰 f g i).hom ≫ pullback.snd _ _ = pullback.fst _ _ ≫ p2 𝒰 f g := by simp_rw [pullbackP1Iso, pullback.lift_snd] +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] theorem pullbackP1Iso_inv_fst (i : 𝒰.I₀) : (pullbackP1Iso 𝒰 f g i).inv ≫ pullback.fst _ _ = (gluing 𝒰 f g).ι i := by simp_rw [pullbackP1Iso, pullback.lift_fst] +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] theorem pullbackP1Iso_inv_snd (i : 𝒰.I₀) : (pullbackP1Iso 𝒰 f g i).inv ≫ pullback.snd _ _ = pullback.fst _ _ := by @@ -473,6 +478,7 @@ instance left_affine_comp_pullback_hasPullback {X Y Z : Scheme} (f : X ⟶ Z) (g simpa [pullback.condition] using hasPullback_assoc_symm f (Z.affineCover.f i) (Z.affineCover.f i) g +set_option backward.isDefEq.respectTransparency.types false in instance {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) : HasPullback f g := hasPullback_of_cover (Z.affineCover.pullback₁ f) f g @@ -635,6 +641,7 @@ def diagonalCover : (pullback.diagonalObj f).OpenCover := (openCoverOfBase 𝒰 f f).bind fun i ↦ openCoverOfLeftRight (𝒱 i) (𝒱 i) (𝒰.pullbackHom _ _) (𝒰.pullbackHom _ _) +set_option backward.isDefEq.respectTransparency.types false in /-- The image of `𝒱 i j₁ ×[𝒰 i] 𝒱 i j₂` in `diagonalCover` with `j₁ = j₂` -/ noncomputable def diagonalCoverDiagonalRange : (pullback.diagonalObj f).Opens := diff --git a/Mathlib/AlgebraicGeometry/QuasiAffine.lean b/Mathlib/AlgebraicGeometry/QuasiAffine.lean index cd803f6d086d64..0c42bb0714541a 100644 --- a/Mathlib/AlgebraicGeometry/QuasiAffine.lean +++ b/Mathlib/AlgebraicGeometry/QuasiAffine.lean @@ -56,6 +56,7 @@ lemma IsQuasiAffine.of_isImmersion have : IsImmersion X.toSpecΓ := .of_comp _ (Spec.map f.appTop) constructor +set_option backward.isDefEq.respectTransparency.types false in lemma IsQuasiAffine.isBasis_basicOpen (X : Scheme.{u}) [IsQuasiAffine X] : Opens.IsBasis { X.basicOpen r | (r : Γ(X, ⊤)) (_ : IsAffineOpen (X.basicOpen r)) } := by refine Opens.isBasis_iff_nbhd.mpr fun {U x} hxU ↦ ?_ diff --git a/Mathlib/AlgebraicGeometry/RelativeGluing.lean b/Mathlib/AlgebraicGeometry/RelativeGluing.lean index f57a778499b2d8..2b3df3cc638701 100644 --- a/Mathlib/AlgebraicGeometry/RelativeGluing.lean +++ b/Mathlib/AlgebraicGeometry/RelativeGluing.lean @@ -25,7 +25,6 @@ open CategoryTheory Limits namespace AlgebraicGeometry set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma Scheme.isLocallyDirected_of_equifibered_of_injective {J : Type*} [Category J] {F G : J ⥤ Scheme.{u}} (s : F ⟶ G) [Quiver.IsThin J] (hs : s.Equifibered) (H : ∀ {i j} (hij : i ⟶ j), Function.Injective (F.map hij)) @@ -117,6 +116,9 @@ noncomputable def toBase : d.glued ⟶ S := { pt := S ι := d.natTrans ≫ 𝒰.functorOfLocallyDirectedHomBase } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma ι_toBase (i : 𝒰.I₀) : diff --git a/Mathlib/AlgebraicGeometry/ResidueField.lean b/Mathlib/AlgebraicGeometry/ResidueField.lean index 20c400e69b5ca9..03e0ecd5489e78 100644 --- a/Mathlib/AlgebraicGeometry/ResidueField.lean +++ b/Mathlib/AlgebraicGeometry/ResidueField.lean @@ -295,6 +295,7 @@ section Spec variable (R : CommRingCat) (x : Spec R) +set_option backward.isDefEq.respectTransparency.types false in /-- The residue fields of `Spec R` are isomorphic to `Ideal.ResidueField`. -/ noncomputable def Spec.residueFieldIso : @@ -302,6 +303,7 @@ def Spec.residueFieldIso : (IsLocalRing.ResidueField.mapEquiv (Spec.stalkIso R x).commRingCatIsoToRingEquiv).toCommRingCatIso +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma Spec.algebraMap_residueFieldIso_inv : CommRingCat.ofHom (algebraMap R _) ≫ (residueFieldIso R x).inv = @@ -313,6 +315,7 @@ lemma Spec.residue_residueFieldIso_hom : (Spec R).residue x ≫ (residueFieldIso R x).hom = (Spec.stalkIso R x).hom ≫ CommRingCat.ofHom (algebraMap _ _) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma Spec.map_residueFieldIso_inv_eq_fromSpecResidueField : Spec.map (residueFieldIso _ _).inv ≫ @@ -336,6 +339,7 @@ lemma SpecToEquivOfField_eq_iff {K : Type*} [Field K] {X : Scheme} rintro ⟨(rfl : f = g), h⟩ simpa +set_option backward.isDefEq.respectTransparency.types false in /-- For a field `K` and a scheme `X`, the morphisms `Spec K ⟶ X` bijectively correspond to pairs of points `x` of `X` and embeddings `κ(x) ⟶ K`. -/ @[simps] @@ -354,6 +358,7 @@ def SpecToEquivOfField (K : Type u) [Field K] (X : Scheme.{u}) : Scheme.fromSpecResidueField_apply, Scheme.residueFieldCongr_fromSpecResidueField] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma descResidueField_stalkClosedPointTo_comp {K : Type u} [Field K] (g : Spec (.of K) ⟶ X) : dsimp% descResidueField (stalkClosedPointTo (g ≫ f)) = diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index 6e9b51c80d71e1..8c0d8521df947e 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -164,6 +164,7 @@ lemma germ_stalkIso_inv {X : Scheme.{u}} (U : X.Opens) (V : U.toScheme.Opens) (x (U.stalkIso x).inv = U.toScheme.presheaf.germ V x hx := PresheafedSpace.restrictStalkIso_inv_eq_germ X.toPresheafedSpace U.isOpenEmbedding V x hx +set_option backward.isDefEq.respectTransparency.types false in lemma stalkIso_inv {X : Scheme.{u}} (U : X.Opens) (x : U) : (U.stalkIso x).inv = U.ι.stalkMap x := by rw [← Category.comp_id (U.stalkIso x).inv, Iso.inv_comp_eq] @@ -192,6 +193,9 @@ def Scheme.openCoverOfIsOpenCover {s : Type*} (X : Scheme.{u}) (U : s → X.Open use i simpa +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The open sets of an open subscheme corresponds to the open sets containing in the subset. -/ @[simps!] def opensRestrict : @@ -268,6 +272,7 @@ theorem Scheme.homOfLE_apply {U V : X.Opens} (e : U ≤ V) (x : U) : (X.homOfLE e x).1 = x := by rw [Scheme.homOfLE_apply'] +set_option backward.isDefEq.respectTransparency.types false in theorem Scheme.ι_image_homOfLE_eq_ι_image_inf {U V : X.Opens} (e : U ≤ V) (W : Opens V) : U.ι ''ᵁ X.homOfLE e ⁻¹ᵁ W = V.ι ''ᵁ W ⊓ U := by ext x @@ -510,6 +515,7 @@ lemma Scheme.Opens.isoOfLE_inv_ι {X : Scheme.{u}} {U V : X.Opens} (hUV : U ≤ (isoOfLE hUV).inv ≫ (V.ι ⁻¹ᵁ U).ι ≫ V.ι = U.ι := by simp [isoOfLE] +set_option backward.isDefEq.respectTransparency.types false in /-- For `f : R`, `D(f)` as an open subscheme of `Spec R` is isomorphic to `Spec R[1/f]`. -/ def basicOpenIsoSpecAway {R : CommRingCat.{u}} (f : R) : Scheme.Opens.toScheme (X := Spec R) (PrimeSpectrum.basicOpen f) ≅ @@ -582,6 +588,7 @@ theorem isPullback_morphismRestrict {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Open apply IsOpenImmersion.isPullback <;> simp +set_option backward.isDefEq.respectTransparency.types false in lemma isPullback_opens_inf_le {X : Scheme} {U V W : X.Opens} (hU : U ≤ W) (hV : V ≤ W) : IsPullback (X.homOfLE inf_le_left) (X.homOfLE inf_le_right) (X.homOfLE hU) (X.homOfLE hV) := by refine (isPullback_morphismRestrict (X.homOfLE hV) (W.ι ⁻¹ᵁ U)).of_iso (V.ι.isoImage _ ≪≫ @@ -591,6 +598,7 @@ lemma isPullback_opens_inf_le {X : Scheme} {U V W : X.Opens} (hU : U ≤ W) (hV · exact (W.functor_map_eq_inf U).trans (by simpa) all_goals { simp [← cancel_mono (Scheme.Opens.ι _)] } +set_option backward.isDefEq.respectTransparency.types false in lemma isPullback_opens_inf {X : Scheme} (U V : X.Opens) : IsPullback (X.homOfLE inf_le_left) (X.homOfLE inf_le_right) U.ι V.ι := (isPullback_morphismRestrict V.ι U).of_iso (V.ι.isoImage _ ≪≫ X.isoOfEq @@ -787,11 +795,13 @@ lemma resLE_comp_resLE {Z : Scheme.{u}} (g : Y ⟶ Z) {W : Z.Opens} (e') : (e.trans ((Opens.map f.base).map (homOfLE e')).le) := by simp [← cancel_mono W.ι] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma map_resLE (i : V' ≤ V) : X.homOfLE i ≫ f.resLE U V e = f.resLE U V' (i.trans e) := by simp_rw [← resLE_id, resLE_comp_resLE, Category.id_comp] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma resLE_map (i : U ≤ U') : f.resLE U V e ≫ Y.homOfLE i = @@ -826,6 +836,7 @@ lemma resLE_appLE {U : Y.Opens} {V : X.Opens} (e : V ≤ f ⁻¹ᵁ U) rw [← X.presheaf.map_comp, ← X.presheaf.map_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma coe_resLE_apply (x : V) : (f.resLE U V e x).1 = f x := by simp [resLE, morphismRestrict_base] @@ -853,6 +864,7 @@ noncomputable def arrowResLEAppIso (f : X ⟶ Y) (U : Y.Opens) (V : X.Opens) (e simp only [Scheme.Opens.topIso_hom, eqToHom_op, Arrow.mk_hom, Scheme.Hom.map_appLE] rw [Scheme.Hom.appTop, ← Scheme.Hom.appLE_eq_app, Scheme.Hom.resLE_appLE, Scheme.Hom.appLE_map] +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Hom.isPullback_resLE {X Y S T : Scheme.{u}} {f : T ⟶ S} {g : Y ⟶ X} {iX : X ⟶ S} {iY : Y ⟶ T} (H : IsPullback g iY iX f) diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 20bb3f23a28425..6691e0a71a671d 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -237,6 +237,7 @@ lemma appLE_congr (e : V ≤ f ⁻¹ᵁ U) (e₁ : U = U') (e₂ : V = V') def stalkMap (x : X) : Y.presheaf.stalk (f x) ⟶ X.presheaf.stalk x := f.toLRSHom.stalkMap x +set_option backward.isDefEq.respectTransparency.types false in protected lemma ext {f g : X ⟶ Y} (h_base : f.base = g.base) (h_app : ∀ U, f.app U ≫ X.presheaf.map (eqToHom congr((Opens.map $h_base.symm).obj U)).op = g.app U) : f = g := by @@ -399,6 +400,7 @@ theorem appLE_comp_appLE {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (U V W e rw [Category.assoc, f.naturality_assoc, ← Functor.map_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] -- reassoc lemma does not need `simp` theorem comp_appLE {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (U V e) : (f ≫ g).appLE U V e = g.app U ≫ f.appLE _ V e := by @@ -503,6 +505,7 @@ def Spec.map {R S : CommRingCat} (f : R ⟶ S) : Spec S ⟶ Spec R := theorem Spec.map_id (R : CommRingCat) : Spec.map (𝟙 R) = 𝟙 (Spec R) := Scheme.Hom.ext' <| Spec.locallyRingedSpaceMap_id R +set_option backward.isDefEq.respectTransparency.types false in @[reassoc, simp] theorem Spec.map_comp {R S T : CommRingCat} (f : R ⟶ S) (g : S ⟶ T) : Spec.map (f ≫ g) = Spec.map g ≫ Spec.map f := @@ -634,9 +637,11 @@ lemma ΓSpecIso_naturality {R S : CommRingCat.{u}} (f : R ⟶ S) : lemma ΓSpecIso_inv_naturality {R S : CommRingCat.{u}} (f : R ⟶ S) : f ≫ (ΓSpecIso S).inv = (ΓSpecIso R).inv ≫ (Spec.map f).appTop := SpecΓIdentity.inv.naturality f +set_option backward.isDefEq.respectTransparency.types false in -- This is not marked simp to respect the abstraction lemma ΓSpecIso_inv : (ΓSpecIso R).inv = CommRingCat.ofHom (algebraMap _ _) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma toOpen_eq (U) : CommRingCat.ofHom (algebraMap R <| (Spec.structureSheaf R).presheaf.obj (.op U)) = (ΓSpecIso R).inv ≫ (Spec R).presheaf.map (homOfLE le_top).op := rfl @@ -850,6 +855,7 @@ end ZeroLocus end Scheme +set_option backward.isDefEq.respectTransparency.types false in theorem basicOpen_eq_of_affine {R : CommRingCat} (f : R) : (Spec R).basicOpen ((Scheme.ΓSpecIso R).inv f) = PrimeSpectrum.basicOpen f := by ext x @@ -859,6 +865,7 @@ theorem basicOpen_eq_of_affine {R : CommRingCat} (f : R) : rw [← isUnit_map_iff (StructureSheaf.stalkIso R x).symm, AlgEquiv.commutes] exact IsLocalization.AtPrime.isUnit_to_map_iff _ (PrimeSpectrum.asIdeal x) f +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem basicOpen_eq_of_affine' {R : CommRingCat} (f : Γ(Spec R, ⊤)) : (Spec R).basicOpen f = PrimeSpectrum.basicOpen ((Scheme.ΓSpecIso R).hom f) := by @@ -904,6 +911,7 @@ lemma Scheme.inv_hom_apply {X Y : Scheme.{u}} (e : X ≅ Y) (y : Y) : change (e.inv ≫ e.hom) y = 𝟙 Y.toPresheafedSpace y simp +set_option backward.isDefEq.respectTransparency.types false in theorem Spec_zeroLocus_eq_zeroLocus {R : CommRingCat} (s : Set R) : (Spec R).zeroLocus ((Scheme.ΓSpecIso R).inv '' s) = PrimeSpectrum.zeroLocus s := by ext x @@ -998,6 +1006,7 @@ lemma germ_stalkMap_apply (U : Y.Opens) (x : X) (hx : f x ∈ U) (y) : X.presheaf.germ (f ⁻¹ᵁ U) x hx (f.app U y) := PresheafedSpace.stalkMap_germ_apply f.toPshHom U x hx y +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `x = y`, the stalk maps are isomorphic. -/ noncomputable def arrowStalkMapIsoOfEq {x y : X} diff --git a/Mathlib/AlgebraicGeometry/Sites/Affine.lean b/Mathlib/AlgebraicGeometry/Sites/Affine.lean index 6b79504bd91ac5..9a74f26e631f1b 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Affine.lean @@ -45,6 +45,7 @@ noncomputable def affineOverMk {P : MorphismProperty Scheme.{u}} {R : CommRingCa variable (P : MorphismProperty Scheme.{u}) [P.IsMultiplicative] [IsZariskiLocalAtSource P] [P.IsStableUnderBaseChange] [P.HasOfPostcompProperty P] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The `Spec` functor from affine `P`-schemes over `S` to `P`-schemes over `S` is dense if `P` is local at the source. -/ @@ -64,6 +65,7 @@ instance isCoverDense_toOver_Spec : CostructuredArrow.homMk (𝟙 _) ⟨⟩ rfl, Over.homMk (𝒰.f i) (by simp) trivial, by cat_disch⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in instance isOneHypercoverDense_toOver_Spec : Functor.IsOneHypercoverDense.{u} (CostructuredArrow.toOver P Scheme.Spec S) ((CostructuredArrow.toOver P Scheme.Spec S).inducedTopology (S.smallGrothendieckTopology P)) diff --git a/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean b/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean index d3776df6d083a6..20c0df38e30469 100644 --- a/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean +++ b/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean @@ -39,6 +39,7 @@ namespace AlgebraicGeometry.Scheme variable {S : Scheme.{u}} +set_option backward.isDefEq.respectTransparency.types false in /-- The small affine étale site: The category of affine schemes étale over `S`, whose objects are commutative rings `R` with an étale structure morphism `Spec R ⟶ S`. -/ def AffineEtale (S : Scheme.{u}) : Type (u + 1) := @@ -57,12 +58,15 @@ protected def mk {R : CommRingCat.{u}} (f : Spec R ⟶ S) [Etale f] : AffineEtal protected def Spec (S : Scheme.{u}) : S.AffineEtale ⥤ S.Etale := MorphismProperty.CostructuredArrow.toOver _ _ _ +set_option backward.isDefEq.respectTransparency.types false in instance : (AffineEtale.Spec S).Faithful := inferInstanceAs <| (MorphismProperty.CostructuredArrow.toOver _ _ _).Faithful +set_option backward.isDefEq.respectTransparency.types false in instance : (AffineEtale.Spec S).Full := inferInstanceAs <| (MorphismProperty.CostructuredArrow.toOver _ _ _).Full +set_option backward.isDefEq.respectTransparency.types false in instance : (AffineEtale.Spec S).IsCoverDense S.smallEtaleTopology := inferInstanceAs <| (MorphismProperty.CostructuredArrow.toOver _ _ _).IsCoverDense (S.smallGrothendieckTopology _) @@ -77,10 +81,12 @@ instance : Functor.IsDenseSubsite (topology S) S.smallEtaleTopology (AffineEtale dsimp [topology] infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : Functor.IsOneHypercoverDense.{u} (AffineEtale.Spec S) (topology S) S.smallEtaleTopology := isOneHypercoverDense_toOver_Spec _ +set_option backward.isDefEq.respectTransparency.types false in instance : EssentiallySmall.{u} S.AffineEtale := essentiallySmall_costructuredArrow_Spec _ fun _ _ _ _ ↦ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean b/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean index 71924db7f69809..8e41ce3c456aae 100644 --- a/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean +++ b/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean @@ -53,6 +53,7 @@ abbrev zariskiTopology : GrothendieckTopology Scheme.{u} := lemma zariskiTopology_eq : zariskiTopology.{u} = zariskiPretopology.toGrothendieck := Precoverage.toGrothendieck_toPretopology_eq_toGrothendieck.symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance subcanonical_zariskiTopology : zariskiTopology.Subcanonical := by apply GrothendieckTopology.Subcanonical.of_isSheaf_yoneda_obj @@ -87,6 +88,7 @@ instance : Scheme.forgetToTop.{u}.IsContinuous zariskiTopology TopCat.grothendie · rw [MorphismProperty.comap_precoverage] exact MorphismProperty.precoverage_monotone fun X Y f hf ↦ f.isOpenEmbedding +set_option backward.isDefEq.respectTransparency.types false in /-- A Zariski-`1`-hypercover of a scheme where all components are affine. -/ @[simps! toPreOneHypercover_toPreZeroHypercover] noncomputable diff --git a/Mathlib/AlgebraicGeometry/Sites/ConstantSheaf.lean b/Mathlib/AlgebraicGeometry/Sites/ConstantSheaf.lean index 3417017aa374a8..3b1513855cd314 100644 --- a/Mathlib/AlgebraicGeometry/Sites/ConstantSheaf.lean +++ b/Mathlib/AlgebraicGeometry/Sites/ConstantSheaf.lean @@ -84,6 +84,7 @@ lemma isSheaf_fpqcTopology_continuousMapPresheaf : · intro y hy rwa [← ContinuousMap.cancel_right (Spec.map f).surjective, Topology.IsQuotientMap.lift_comp] +set_option backward.isDefEq.respectTransparency.types false in /-- `continuousMapPresheaf` is `U ↦ C(ConnectedComponents U, T)` if `T` is totally disconnected. -/ def continuousMapPresheafEquivOfTotallyDisconnectedSpace [TotallyDisconnectedSpace T] diff --git a/Mathlib/AlgebraicGeometry/Sites/Etale.lean b/Mathlib/AlgebraicGeometry/Sites/Etale.lean index 357b3376c30b20..9b790dbf9b3e6b 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Etale.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Etale.lean @@ -45,11 +45,13 @@ lemma zariskiTopology_le_etaleTopology : zariskiTopology ≤ etaleTopology := by intro X Y f hf infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- The small étale site of a scheme is the Grothendieck topology on the category of schemes étale over `X` induced from the étale topology on `Scheme.{u}`. -/ def smallEtaleTopology (X : Scheme.{u}) : GrothendieckTopology X.Etale := X.smallGrothendieckTopology (P := @Etale) +set_option backward.isDefEq.respectTransparency.types false in /-- The pretopology generating the small étale site. -/ def smallEtalePretopology (X : Scheme.{u}) : Pretopology X.Etale := X.smallPretopology (Q := @Etale) (P := @Etale) diff --git a/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean b/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean index 46192dcbf7394a..080431e447073f 100644 --- a/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean +++ b/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean @@ -34,6 +34,7 @@ namespace AlgebraicGeometry.Scheme variable {S : Scheme.{u}} {Ω : Type u} [Field Ω] [IsSepClosed Ω] (s : Spec (.of Ω) ⟶ S) +set_option backward.isDefEq.respectTransparency.types false in lemma exists_fac_of_etale_of_isSepClosed {X S : Scheme.{u}} (f : X ⟶ S) [Etale f] {Ω : Type u} [Field Ω] [IsSepClosed Ω] (s : Spec (.of Ω) ⟶ S) (x : X) (hx : f x = s default) : @@ -56,6 +57,7 @@ lemma exists_fac_of_etale_of_isSepClosed {X S : Scheme.{u}} (f : X ⟶ S) [Etale instance : IsCofiltered (Etale.forget S ⋙ coyoneda.obj (op (Over.mk s))).Elements := Functor.isCofiltered_elements _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A morphism `s : Spec (.of Ω) ⟶ S` where `Ω` is a separably closed field defines a point for the small étale site of `S`. -/ @@ -120,7 +122,6 @@ lemma pointSmallEtaleFiberObjToPreimage_surjective (X : S.Etale) : (X.hom.fiberToSpecResidueField _) (Spec.map a) y (by subsingleton) refine ⟨Over.homMk (l ≫ X.hom.fiberι t) ?_, rfl⟩ simp [X.hom.fiber_fac, reassoc_of% hl] - rfl set_option backward.isDefEq.respectTransparency false in lemma isConservative_pointSmallEtale diff --git a/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean b/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean index 77045d93db95c8..7dbc07064ae2a5 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Fpqc.lean @@ -34,6 +34,7 @@ open CategoryTheory namespace AlgebraicGeometry.Scheme +set_option backward.isDefEq.respectTransparency.types false in /-- The fppf precoverage on the category of schemes. The covering families are jointly-surjective families of flat morphisms, locally of finite presentation. -/ def fppfPrecoverage : Precoverage Scheme.{u} := @@ -52,6 +53,7 @@ lemma fppfPrecoverage_eq_inf : abbrev fppfTopology : GrothendieckTopology Scheme.{u} := fppfPrecoverage.toGrothendieck +set_option backward.isDefEq.respectTransparency.types false in /-- The fpqc precoverage on the category of schemes is the quasi-compact precoverage on flat morphisms. The covering families are jointly-surjective, quasi-compact families of flat morphisms. -/ @@ -60,6 +62,7 @@ def fpqcPrecoverage : Precoverage Scheme.{u} := deriving Precoverage.HasIsos, Precoverage.IsStableUnderBaseChange, Precoverage.IsStableUnderComposition +set_option backward.isDefEq.respectTransparency.types false in lemma fppfPrecoverage_le_fpqcPrecoverage : fppfPrecoverage ≤ fpqcPrecoverage := by rw [fpqcPrecoverage, propQCPrecoverage, le_inf_iff] refine ⟨?_, precoverage_mono fun X Y f ⟨hf, _⟩ ↦ inferInstance⟩ @@ -80,6 +83,7 @@ lemma zariskiTopology_le_fpqcTopology : zariskiTopology ≤ fpqcTopology := lemma fppfTopology_le_fpqcTopology : fppfTopology ≤ fpqcTopology := Precoverage.toGrothendieck_mono fppfPrecoverage_le_fpqcPrecoverage +set_option backward.isDefEq.respectTransparency.types false in instance : fpqcTopology.Subcanonical := by refine GrothendieckTopology.Subcanonical.of_isSheaf_yoneda_obj _ fun X ↦ ?_ rw [fpqcTopology_eq_propQCTopology, isSheaf_type_propQCTopology_iff] diff --git a/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean b/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean index db8609d3765cc5..27c1fe8dbd31b9 100644 --- a/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean +++ b/Mathlib/AlgebraicGeometry/Sites/MorphismProperty.lean @@ -55,6 +55,7 @@ lemma IsJointlySurjectivePreserving.exists_preimage_snd_triplet_of_prop use (pullbackSymmetry f g).inv a rwa [← Scheme.Hom.comp_apply, pullbackSymmetry_inv_comp_snd] +set_option backward.isDefEq.respectTransparency.types false in instance : IsJointlySurjectivePreserving @IsOpenImmersion where exists_preimage_fst_triplet_of_prop {X Y S f g} _ hg x y h := by rw [← show _ = (pullback.fst _ _ : pullback f g ⟶ _).base from diff --git a/Mathlib/AlgebraicGeometry/Sites/Proetale.lean b/Mathlib/AlgebraicGeometry/Sites/Proetale.lean index 8d8acd68952362..41cf4f37ae08b0 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Proetale.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Proetale.lean @@ -43,6 +43,7 @@ open CategoryTheory MorphismProperty Limits namespace AlgebraicGeometry.Scheme +set_option backward.isDefEq.respectTransparency.types false in /-- Big pro-étale site: the pro-étale precoverage on the category of schemes given by fpqc covers of weakly étale morphisms. @@ -67,6 +68,7 @@ abbrev proetaleTopology : GrothendieckTopology Scheme.{u} := lemma proetaleTopology_eq_propQCTopology : proetaleTopology = propQCTopology @WeaklyEtale := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma etalePrecoverage_le_proetalePrecoverage : etalePrecoverage ≤ proetalePrecoverage := by rw [proetalePrecoverage, propQCPrecoverage, etalePrecoverage, le_inf_iff] refine ⟨precoverage_le_qcPrecoverage_of_isOpenMap fun X Y f hf ↦ f.isOpenMap, ?_⟩ @@ -87,6 +89,7 @@ instance {S : Scheme.{u}} (𝒰 : S.Cover (precoverage @WeaklyEtale)) (i : 𝒰. WeaklyEtale (𝒰.f i) := 𝒰.map_prop i +set_option backward.isDefEq.respectTransparency.types false in /-- The (small) pro-étale site of a scheme `S`: Its objects are the schemes weakly étale over `S`. We prefer to work with weakly étale morphisms instead of pro-étale morphisms, since the property @@ -111,54 +114,68 @@ variable {S} in protected def mk {X : Scheme.{u}} (f : X ⟶ S) [WeaklyEtale f] : S.ProEt := MorphismProperty.Over.mk _ f ‹_› +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor the pro-étale site of `S` to schemes over `S`. -/ @[simps!] protected def forget : S.ProEt ⥤ Over S := MorphismProperty.Over.forget @WeaklyEtale ⊤ S +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from the pro-étale site of `S` to schemes over `S` is fully faithful. -/ def forgetFullyFaithful : (ProEt.forget S).FullyFaithful := MorphismProperty.Comma.forgetFullyFaithful _ _ _ +set_option backward.isDefEq.respectTransparency.types false in instance : (ProEt.forget S).Full := inferInstanceAs <| (MorphismProperty.Over.forget _ _ _).Full +set_option backward.isDefEq.respectTransparency.types false in instance : (ProEt.forget S).Faithful := inferInstanceAs <| (MorphismProperty.Over.forget _ _ _).Faithful +set_option backward.isDefEq.respectTransparency.types false in instance : PreservesFiniteLimits (ProEt.forget S) := inferInstanceAs <| PreservesFiniteLimits (MorphismProperty.Over.forget _ _ _) +set_option backward.isDefEq.respectTransparency.types false in instance : RepresentablyFlat (ProEt.forget S) := flat_of_preservesFiniteLimits _ +set_option backward.isDefEq.respectTransparency.types false in instance : (ProEt.forget S).LocallyCoverDense (proetaleTopology.over S) := by apply MorphismProperty.locallyCoverDense_forget_of_le exact proetalePrecoverage_le_precoverage_weaklyEtale +set_option backward.isDefEq.respectTransparency.types false in /-- The pro-étale precoverage on the small pro-étale site. -/ def precoverage : Precoverage S.ProEt := proetalePrecoverage.comap (ProEt.forget S ⋙ Over.forget S) +set_option backward.isDefEq.respectTransparency.types false in /-- The pro-étale topology on the small pro-étale site. -/ abbrev topology : GrothendieckTopology S.ProEt := (precoverage S).toGrothendieck +set_option backward.isDefEq.respectTransparency.types false in instance : (ProEt.forget S).IsContinuous (topology S) (proetaleTopology.over S) := by rw [Functor.isContinuous_iff_coverPreserving] exact coverPreserving_comap_forget _ proetalePrecoverage_le_precoverage_weaklyEtale +set_option backward.isDefEq.respectTransparency.types false in lemma topology_eq_inducedTopology : topology S = (ProEt.forget S).inducedTopology (proetaleTopology.over S) := MorphismProperty.toGrothendieck_comap_forget_eq_inducedTopology _ proetalePrecoverage_le_precoverage_weaklyEtale +set_option backward.isDefEq.respectTransparency.types false in instance : (ProEt.forget S ⋙ Over.forget S).IsContinuous (ProEt.topology S) proetaleTopology := Functor.isContinuous_comp _ _ _ (proetaleTopology.over S) _ +set_option backward.isDefEq.respectTransparency.types false in instance : (topology S).Subcanonical := GrothendieckTopology.subcanonical_of_full_of_faithful (ProEt.forget S) _ (proetaleTopology.over S) +set_option backward.isDefEq.respectTransparency.types false in /-- If `S` is the empty scheme, the pro-étale site over `S` is a point. -/ noncomputable def equivOfIsEmpty [IsEmpty S] : S.ProEt ≌ Discrete PUnit := MorphismProperty.overEquivOfIsInitial _ _ _ isInitialOfIsEmpty @@ -171,6 +188,7 @@ lemma bot_mem_topology (X : S.ProEt) [IsEmpty X.left] : ⊥ ∈ topology S X := refine Precoverage.generate_mem_toGrothendieck ?_ simp [precoverage, proetalePrecoverage, bot_mem_propQCPrecoverage] +set_option backward.isDefEq.respectTransparency.types false in lemma topology_eq_top_of_isEmpty [IsEmpty S] : topology S = ⊤ := by rw [GrothendieckTopology.eq_top_iff] intro X diff --git a/Mathlib/AlgebraicGeometry/Sites/Representability.lean b/Mathlib/AlgebraicGeometry/Sites/Representability.lean index 6a61e1324e0cec..a4c7b35fa395f7 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Representability.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Representability.lean @@ -87,6 +87,7 @@ noncomputable def glueData : GlueData where noncomputable def toGlued (i : ι) : X i ⟶ (glueData hf).glued := (glueData hf).ι i +set_option backward.isDefEq.respectTransparency.types false in instance : IsOpenImmersion (toGlued hf i) := inferInstanceAs (IsOpenImmersion ((glueData hf).ι i)) @@ -115,13 +116,13 @@ lemma yoneda_toGlued_yonedaGluedToSheaf (i : ι) : NatTrans.comp_app_apply, yoneda_map_app] simpa using! GlueData.sheafValGluedMk_val _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma yonedaGluedToSheaf_app_toGlued {i : ι} : dsimp% (yonedaGluedToSheaf hf).hom.app _ (toGlued hf i) = yonedaEquiv (f i) := by rw [← yoneda_toGlued_yonedaGluedToSheaf hf i, yonedaEquiv_comp, yonedaEquiv_yoneda_map] - rfl set_option backward.defeqAttrib.useBackward true in @[simp] @@ -137,6 +138,7 @@ instance [Presheaf.IsLocallySurjective Scheme.zariskiTopology (Sigma.desc f)] : (show Sigma.desc (fun i ↦ yoneda.map (toGlued hf i)) ≫ (yonedaGluedToSheaf hf).hom = Sigma.desc f by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma comp_toGlued_eq {U : Scheme} {i j : ι} (a : U ⟶ X i) (b : U ⟶ X j) (h : yoneda.map a ≫ f i = yoneda.map b ≫ f j) : @@ -149,6 +151,7 @@ lemma comp_toGlued_eq {U : Scheme} {i j : ι} (a : U ⟶ X i) (b : U ⟶ X j) @[simp] lemma glueData_openCover_map : (glueData hf).openCover.f j = toGlued hf j := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Sheaf.IsLocallyInjective (yonedaGluedToSheaf hf) where equalizerSieve_mem := by diff --git a/Mathlib/AlgebraicGeometry/Sites/Small.lean b/Mathlib/AlgebraicGeometry/Sites/Small.lean index 137bcc660f4a02..b257f5528f2c03 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Small.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Small.lean @@ -47,6 +47,7 @@ def Cover.toPresieveOver {X : Over S} (𝒰 : Cover.{u} (precoverage P) X.left) Presieve X := Presieve.ofArrows (fun i ↦ (𝒰.X i).asOver S) (fun i ↦ (𝒰.f i).asOver S) +set_option backward.isDefEq.respectTransparency.types false in /-- The presieve defined by a `P`-cover of `S`-schemes with `Q`. -/ def Cover.toPresieveOverProp {X : Q.Over ⊤ S} (𝒰 : Cover.{u} (precoverage P) X.left) [𝒰.Over S] (h : ∀ j, Q (𝒰.X j ↘ S)) : Presieve X := @@ -229,6 +230,7 @@ alias smallGrothendieckTopologyOfLE_eq_toGrothendieck_smallPretopology := variable {P Q} +set_option backward.isDefEq.respectTransparency.types false in lemma mem_toGrothendieck_smallPretopology (X : Q.Over ⊤ S) (R : Sieve X) : R ∈ (S.smallPretopology P Q).toGrothendieck X ↔ ∀ x : X.left, ∃ (Y : Q.Over ⊤ S) (f : Y ⟶ X) (y : Y.left), @@ -257,6 +259,7 @@ lemma mem_toGrothendieck_smallPretopology (X : Q.Over ⊤ S) (R : Sieve X) : · rintro - - ⟨i⟩ exact hf i +set_option backward.isDefEq.respectTransparency.types false in lemma mem_smallGrothendieckTopology [P.HasOfPostcompProperty P] (X : P.Over ⊤ S) (R : Sieve X) : R ∈ S.smallGrothendieckTopology P X ↔ ∃ (𝒰 : Cover.{u} (precoverage P) X.left) (_ : 𝒰.Over S) (h : ∀ j, P (𝒰.X j ↘ S)), diff --git a/Mathlib/AlgebraicGeometry/Sites/SmallAffineZariski.lean b/Mathlib/AlgebraicGeometry/Sites/SmallAffineZariski.lean index 8b07f852c49337..18e6d20b657ac6 100644 --- a/Mathlib/AlgebraicGeometry/Sites/SmallAffineZariski.lean +++ b/Mathlib/AlgebraicGeometry/Sites/SmallAffineZariski.lean @@ -255,6 +255,7 @@ This is closely related to the notion of quasi-coherent `𝒪ₓ`-algebras, and together once the theory of quasi-coherent `𝒪ₓ`-algebras are developed. -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (X) in /-- `X` is the colimit of its affine opens. See `isColimit_cocone` below. -/ @@ -292,6 +293,7 @@ lemma coequifibered_iff_forall_isLocalizationAway {F : X.AffineZariskiSiteᵒᵖ @[deprecated (since := "2026-02-01")] alias PreservesLocalization := NatTrans.Coequifibered +set_option backward.isDefEq.respectTransparency.types false in /-- The relative gluing data associated to a quasi-coherent `𝒪ₓ` algebra. -/ def relativeGluingData {F : X.AffineZariskiSiteᵒᵖ ⥤ CommRingCat} {α : (AffineZariskiSite.toOpensFunctor X).op ⋙ X.presheaf ⟶ F} @@ -329,6 +331,7 @@ lemma opensRange_relativeGluingData_map (F : X.AffineZariskiSiteᵒᵖ ⥤ CommR @[deprecated (since := "2026-02-01")] alias PreservesLocalization.opensRange_map := opensRange_relativeGluingData_map +set_option backward.isDefEq.respectTransparency.types false in @[deprecated Cover.RelativeGluingData.toBase_preimage_eq_opensRange_ι (since := "2026-02-01")] lemma PreservesLocalization.colimitDesc_preimage (F : X.AffineZariskiSiteᵒᵖ ⥤ CommRingCat) (α : (AffineZariskiSite.toOpensFunctor X).op ⋙ X.presheaf ⟶ F) diff --git a/Mathlib/AlgebraicGeometry/Spec.lean b/Mathlib/AlgebraicGeometry/Spec.lean index bec88d3a9cca81..6d84a46dcd2f59 100644 --- a/Mathlib/AlgebraicGeometry/Spec.lean +++ b/Mathlib/AlgebraicGeometry/Spec.lean @@ -92,6 +92,7 @@ def Spec.sheafedSpaceObj (R : CommRingCat.{u}) : SheafedSpace CommRingCat where presheaf := (structureSheaf R).1 IsSheaf := (structureSheaf R).2 +set_option backward.isDefEq.respectTransparency.types false in /-- The induced map of a ring homomorphism on the ring spectra, as a morphism of sheafed spaces. -/ @[simps hom_base hom_c_app] @@ -157,10 +158,12 @@ theorem Spec.toPresheafedSpace_map (R S : CommRingCat.{u}ᵒᵖ) (f : R ⟶ S) : Spec.toPresheafedSpace.map f = (Spec.sheafedSpaceMap f.unop).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem Spec.toPresheafedSpace_map_op (R S : CommRingCat.{u}) (f : R ⟶ S) : Spec.toPresheafedSpace.map f.op = (Spec.sheafedSpaceMap f).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem Spec.basicOpen_hom_ext {X : RingedSpace.{u}} {R : CommRingCat.{u}} {α β : X ⟶ Spec.sheafedSpaceObj R} (w : α.hom.base = β.hom.base) (h : ∀ r : R, @@ -177,6 +180,7 @@ theorem Spec.basicOpen_hom_ext {X : RingedSpace.{u}} {R : CommRingCat.{u}} apply (StructureSheaf.to_basicOpen_epi R r).1 simpa using! h r +set_option backward.isDefEq.respectTransparency.types false in -- `simps!` generates some garbage lemmas, so choose manually, -- if more is needed, add them here /-- The spectrum of a commutative ring, as a `LocallyRingedSpace`. -/ @@ -202,6 +206,7 @@ lemma Spec.locallyRingedSpaceObj_presheaf_map' (R : Type u) [CommRing R] {U V} ( (Spec.locallyRingedSpaceObj <| CommRingCat.of R).presheaf.map i = (structureSheaf R).1.map i := rfl +set_option backward.isDefEq.respectTransparency.types false in @[elementwise] theorem stalkMap_toStalk {R S : CommRingCat.{u}} (f : R ⟶ S) (p : PrimeSpectrum S) : toStalk R (PrimeSpectrum.comap f.hom p) ≫ (Spec.sheafedSpaceMap f).hom.stalkMap p = @@ -272,13 +277,16 @@ section SpecΓ open AlgebraicGeometry.LocallyRingedSpace +set_option backward.isDefEq.respectTransparency.types false in /-- The counit morphism `R ⟶ Γ(Spec R)` given by `AlgebraicGeometry.StructureSheaf.toOpen`. -/ def toSpecΓ (R : CommRingCat.{u}) : R ⟶ Γ.obj (op (Spec.toLocallyRingedSpace.obj (op R))) := CommRingCat.ofHom (algebraMap _ _) +set_option backward.isDefEq.respectTransparency.types false in instance isIso_toSpecΓ (R : CommRingCat.{u}) : IsIso (toSpecΓ R) := (ConcreteCategory.isIso_iff_bijective _).mpr algebraMap_obj_top_bijective +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] theorem Spec_Γ_naturality {R S : CommRingCat.{u}} (f : R ⟶ S) : f ≫ toSpecΓ S = toSpecΓ R ≫ Γ.map (Spec.toLocallyRingedSpace.map f.op).op := by @@ -288,6 +296,9 @@ theorem Spec_Γ_naturality {R S : CommRingCat.{u}} (f : R ⟶ S) : erw [comap_apply] apply Localization.localRingHom_to_map +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The counit (`SpecΓIdentity.inv.op`) of the adjunction `Γ ⊣ Spec` is an isomorphism. -/ @[simps! hom_app inv_app] def LocallyRingedSpace.SpecΓIdentity : Spec.toLocallyRingedSpace.rightOp ⋙ Γ ≅ 𝟭 _ := @@ -318,6 +329,7 @@ namespace StructureSheaf variable {R S : CommRingCat.{u}} (f : R ⟶ S) (p : PrimeSpectrum R) +set_option backward.isDefEq.respectTransparency.types false in /-- For an algebra `f : R →+* S`, this is the ring homomorphism `S →+* (f∗ 𝒪ₛ)ₚ` for a `p : Spec R`. This is shown to be the localization at `p` in `isLocalizedModule_toPushforwardStalkAlgHom`. -/ @@ -345,6 +357,7 @@ theorem algebraMap_pushforward_stalk : variable (R S) variable [Algebra R S] +set_option backward.isDefEq.respectTransparency.types false in /-- This is the `AlgHom` version of `toPushforwardStalk`, which is the map `S ⟶ (f∗ 𝒪ₛ)ₚ` for some algebra `R ⟶ S` and some `p : Spec R`. @@ -355,6 +368,7 @@ def toPushforwardStalkAlgHom : { (StructureSheaf.toPushforwardStalk (CommRingCat.ofHom (algebraMap R S)) p).hom with commutes' := fun _ => rfl } +set_option backward.isDefEq.respectTransparency.types false in theorem isLocalizedModule_toPushforwardStalkAlgHom_aux (y) : ∃ x : S × p.asIdeal.primeCompl, x.2 • y = toPushforwardStalkAlgHom R S p x.1 := by obtain ⟨U, hp, s, e⟩ := TopCat.Presheaf.exists_germ_eq _ y @@ -387,6 +401,7 @@ theorem isLocalizedModule_toPushforwardStalkAlgHom_aux (y) : rw [← map_pow (algebraMap R S)] at hsn congr 1 +set_option backward.isDefEq.respectTransparency.types false in instance isLocalizedModule_toPushforwardStalkAlgHom : IsLocalizedModule p.asIdeal.primeCompl (toPushforwardStalkAlgHom R S p).toLinearMap := by apply IsLocalizedModule.mkOfAlgebra diff --git a/Mathlib/AlgebraicGeometry/SpreadingOut.lean b/Mathlib/AlgebraicGeometry/SpreadingOut.lean index e9a6e69c450d7c..1b373aec689924 100644 --- a/Mathlib/AlgebraicGeometry/SpreadingOut.lean +++ b/Mathlib/AlgebraicGeometry/SpreadingOut.lean @@ -87,6 +87,7 @@ lemma Scheme.exists_le_and_germ_injective (X : Scheme.{u}) (x : X) [X.IsGermInje obtain ⟨f, hf, hxf⟩ := hU.exists_basicOpen_le ⟨x, hxV⟩ hx exact ⟨X.basicOpen f, hxf, hU.basicOpen f, hf, injective_germ_basicOpen U hU x hx f hxf H⟩ +set_option backward.isDefEq.respectTransparency.types false in instance (x : X) [X.IsGermInjectiveAt x] [IsOpenImmersion f] : Y.IsGermInjectiveAt (f x) := by obtain ⟨U, hxU, hU, H⟩ := X.exists_germ_injective x @@ -97,6 +98,7 @@ instance (x : X) [X.IsGermInjectiveAt x] [IsOpenImmersion f] : (f.appIso U).inv _).mp ?_ simpa +set_option backward.isDefEq.respectTransparency.types false in variable {f} in lemma isGermInjectiveAt_iff_of_isOpenImmersion {x : X} [IsOpenImmersion f] : Y.IsGermInjectiveAt (f x) ↔ X.IsGermInjectiveAt x := by @@ -164,6 +166,7 @@ instance (priority := 100) [IsIntegral X] : X.IsGermInjective := by exact @IsLocalization.injective _ _ _ _ _ (show _ from _) this (Ideal.primeCompl_le_nonZeroDivisors _) +set_option backward.isDefEq.respectTransparency.types false in instance (priority := 100) [IsLocallyNoetherian X] : X.IsGermInjective := by suffices ∀ (R : CommRingCat.{u}) (_ : IsNoetherianRing R), (Spec R).IsGermInjective by refine @Scheme.IsGermInjective.of_openCover _ (X.affineOpenCover.openCover) (fun i ↦ this _ ?_) @@ -187,6 +190,7 @@ instance (priority := 100) [IsLocallyNoetherian X] : X.IsGermInjective := by rw [Submodule.mem_annihilator_span_singleton, smul_eq_mul] exact hf i _ +set_option backward.isDefEq.respectTransparency.types false in /-- Let `x : X` and `f g : X ⟶ Y` be two morphisms such that `f x = g x`. If `f` and `g` agree on the stalk of `x`, then they agree on an open neighborhood of `x`, @@ -223,6 +227,7 @@ lemma spread_out_unique_of_isGermInjective {x : X} [X.IsGermInjectiveAt x] simp only [Scheme.Hom.appLE, Category.assoc, X.presheaf.germ_res', ← Scheme.Hom.germ_stalkMap, H] simp only [TopCat.Presheaf.germ_stalkSpecializes_assoc, Scheme.Hom.germ_stalkMap] +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `spread_out_unique_of_isGermInjective` whose condition is an equality of scheme morphisms instead of ring homomorphisms. @@ -302,6 +307,7 @@ lemma exists_lift_of_germInjective {x : X} [X.IsGermInjectiveAt x] {U : X.Opens} rw [TopCat.Presheaf.germ_res_apply, ‹φRA ≫ φ = _›] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Given `S`-schemes `X Y` and points `x : X` `y : Y` over `s : S`. Suppose we have the following diagram of `S`-schemes @@ -356,6 +362,7 @@ lemma spread_out_of_isGermInjective [LocallyOfFiniteType sY] {x : X} [X.IsGermIn ← Scheme.Hom.appLE, ← hW.isoSpec_hom, IsAffineOpen.SpecMap_appLE_fromSpec sX hU hW i, ← Iso.eq_inv_comp, IsAffineOpen.isoSpec_inv_ι_assoc] +set_option backward.isDefEq.respectTransparency.types false in /-- Given `S`-schemes `X Y`, a point `x : X`, and an `S`-morphism `φ : Spec 𝒪_{X, x} ⟶ Y`, we may spread it out to an `S`-morphism `f : U ⟶ Y` diff --git a/Mathlib/AlgebraicGeometry/Stalk.lean b/Mathlib/AlgebraicGeometry/Stalk.lean index d5819c24cc2007..e66a3ddf2552c3 100644 --- a/Mathlib/AlgebraicGeometry/Stalk.lean +++ b/Mathlib/AlgebraicGeometry/Stalk.lean @@ -89,6 +89,7 @@ instance IsAffineOpen.fromSpecStalk_isPreimmersion {X : Scheme.{u}} {U : Opens X instance {X : Scheme.{u}} (x : X) : IsPreimmersion (X.fromSpecStalk x) := IsAffineOpen.fromSpecStalk_isPreimmersion _ _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma IsAffineOpen.fromSpecStalk_closedPoint {U : Opens X} (hU : IsAffineOpen U) {x : X} (hxU : x ∈ U) : hU.fromSpecStalk hxU (closedPoint (X.presheaf.stalk x)) = x := by @@ -121,6 +122,7 @@ lemma fromSpecStalk_appTop {x : X} : (Spec (X.presheaf.stalk x)).presheaf.map (homOfLE le_top).op := fromSpecStalk_app .. +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma SpecMap_stalkSpecializes_fromSpecStalk {x y : X} (h : x ⤳ y) : Spec.map (X.presheaf.stalkSpecializes h) ≫ X.fromSpecStalk y = X.fromSpecStalk x := by @@ -133,6 +135,7 @@ lemma SpecMap_stalkSpecializes_fromSpecStalk {x y : X} (h : x ⤳ y) : instance {x y : X} (h : x ⤳ y) : (Spec.map (X.presheaf.stalkSpecializes h)).IsOver X where +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma SpecMap_stalkMap_fromSpecStalk {x} : Spec.map (f.stalkMap x) ≫ Y.fromSpecStalk _ = X.fromSpecStalk x ≫ f := by @@ -168,6 +171,7 @@ def Opens.fromSpecStalkOfMem {X : Scheme.{u}} (U : X.Opens) (x : X) (hxU : x ∈ Spec (X.presheaf.stalk x) ⟶ U := Spec.map (inv (U.ι.stalkMap ⟨x, hxU⟩)) ≫ U.toScheme.fromSpecStalk ⟨x, hxU⟩ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma Opens.fromSpecStalkOfMem_ι {X : Scheme.{u}} (U : X.Opens) (x : X) (hxU : x ∈ U) : U.fromSpecStalkOfMem x hxU ≫ U.ι = X.fromSpecStalk x := by @@ -202,6 +206,7 @@ section Spec variable (R : CommRingCat) (x) +set_option backward.isDefEq.respectTransparency.types false in lemma Spec.fromSpecStalk_eq : (Spec R).fromSpecStalk x = Spec.map ((Scheme.ΓSpecIso R).inv ≫ (Spec R).presheaf.germ ⊤ x trivial) := by @@ -233,11 +238,13 @@ def stalkClosedPointIso : Spec.stalkIso _ _ ≪≫ (IsLocalization.atUnits R (closedPoint R).asIdeal.primeCompl fun _ ↦ not_not.mp).toRingEquiv.toCommRingCatIso.symm +set_option backward.isDefEq.respectTransparency.types false in lemma stalkClosedPointIso_inv : (stalkClosedPointIso R).inv = StructureSheaf.toStalk R _ := by ext x exact (StructureSheaf.stalkIso _ _).commutes _ +set_option backward.isDefEq.respectTransparency.types false in lemma ΓSpecIso_hom_stalkClosedPointIso_inv : (Scheme.ΓSpecIso R).hom ≫ (stalkClosedPointIso R).inv = (Spec R).presheaf.germ ⊤ (closedPoint _) trivial := by @@ -274,6 +281,7 @@ def stalkClosedPointTo : X.presheaf.stalk (f (closedPoint R)) ⟶ R := f.stalkMap (closedPoint R) ≫ (stalkClosedPointIso R).hom +set_option backward.isDefEq.respectTransparency.types false in instance isLocalHom_stalkClosedPointTo : IsLocalHom (stalkClosedPointTo f).hom := inferInstanceAs <| IsLocalHom (f.stalkMap (closedPoint R) ≫ (stalkClosedPointIso R).hom).hom @@ -291,6 +299,7 @@ lemma preimage_eq_top_of_closedPoint_mem {U : Opens X} (hU : f (closedPoint R) ∈ U) : f ⁻¹ᵁ U = ⊤ := IsLocalRing.closed_point_mem_iff.mp hU +set_option backward.isDefEq.respectTransparency.types false in lemma stalkClosedPointTo_comp (g : X ⟶ Y) : stalkClosedPointTo (f ≫ g) = g.stalkMap _ ≫ stalkClosedPointTo f := by rw [stalkClosedPointTo, Scheme.Hom.stalkMap_comp] @@ -305,6 +314,7 @@ lemma germ_stalkClosedPointTo_Spec {R S : CommRingCat} [IsLocalRing S] (φ : R simp_rw [Opens.map_top] rw [germ_stalkClosedPointIso_hom, Iso.inv_hom_id, Category.comp_id] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma germ_stalkClosedPointTo (U : Opens X) (hU : f (closedPoint R) ∈ U) : X.presheaf.germ U _ hU ≫ stalkClosedPointTo f = f.app U ≫ @@ -331,6 +341,7 @@ lemma germ_stalkClosedPointTo_Spec_fromSpecStalk simp_rw [← Opens.map_top (Spec.map f).base] rw [← (Spec.map f).app_eq_appLE, ΓSpecIso_naturality, Iso.inv_hom_id_assoc] +set_option backward.isDefEq.respectTransparency.types false in lemma stalkClosedPointTo_fromSpecStalk (x : X) : stalkClosedPointTo (X.fromSpecStalk x) = (X.presheaf.stalkCongr (by rw [fromSpecStalk_closedPoint]; rfl)).hom := by @@ -339,6 +350,7 @@ lemma stalkClosedPointTo_fromSpecStalk (x : X) : have : X.fromSpecStalk x = Spec.map (𝟙 (X.presheaf.stalk x)) ≫ X.fromSpecStalk x := by simp convert! germ_stalkClosedPointTo_Spec_fromSpecStalk (𝟙 (X.presheaf.stalk x)) U hxU +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Spec_stalkClosedPointTo_fromSpecStalk : Spec.map (stalkClosedPointTo f) ≫ X.fromSpecStalk _ = f := by @@ -373,6 +385,7 @@ lemma SpecToEquivOfLocalRing_eq_iff variable (X R) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a local ring `R` and scheme `X`, morphisms `Spec R ⟶ X` corresponds to pairs `(x, f)` where `x : X` and `f : 𝒪_{X, x} ⟶ R` is a local ring homomorphism. diff --git a/Mathlib/AlgebraicGeometry/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/StructureSheaf.lean index 72c6d227ac68a8..9cded788235d69 100644 --- a/Mathlib/AlgebraicGeometry/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/StructureSheaf.lean @@ -72,6 +72,7 @@ namespace StructureSheaf variable {P : PrimeSpectrum.Top R} +set_option backward.isDefEq.respectTransparency.types false in variable (M P) in /-- The type family over `PrimeSpectrum R` consisting of the localization over each point. -/ abbrev Localizations : Type u := LocalizedModule P.asIdeal.primeCompl M @@ -112,6 +113,7 @@ so we replace his circumlocution about functions into a disjoint union with def isLocallyFraction : LocalPredicate (Localizations (R := R) M) := (isFractionPrelocal R M).sheafify +set_option backward.isDefEq.respectTransparency.types false in variable (M) in /-- The functions satisfying `isLocallyFraction` form a submodule. -/ def sectionsSubmodule (U : (Opens (PrimeSpectrum.Top R))) : @@ -131,6 +133,7 @@ def sectionsSubmodule (U : (Opens (PrimeSpectrum.Top R))) : exact ⟨V, m, i, r • ra, sa, fun x ↦ ⟨(wa x).1, congr(r • $((wa x).2)).trans (LocalizedModule.smul'_mk ..)⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in variable (A) in /-- The functions satisfying `isLocallyFraction` form a subalgebra. -/ def sectionsSubalgebra (U : (Opens (PrimeSpectrum.Top R))) : @@ -257,7 +260,6 @@ def structurePresheafCompForget : open TopCat.Presheaf -open PrimeSpectrum open TopCat.Presheaf @@ -275,6 +277,7 @@ def const (f : M) (g : R) (U : Opens (PrimeSpectrum.Top R)) Γ(M, U) := ⟨fun x => .mk f ⟨g, hu x.2⟩, fun x ↦ ⟨U, x.2, 𝟙 _, f, g, fun y ↦ ⟨hu y.2, rfl⟩⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem const_apply (f : M) (g : R) (U : Opens (PrimeSpectrum.Top R)) (hu : ∀ x ∈ U, g ∈ (x : PrimeSpectrum.Top R).asIdeal.primeCompl) (x : U) : @@ -302,6 +305,7 @@ theorem res_const (f : M) (g : R) (U hu V hv i) : (structureSheafInType R M).1.map i (const f g U hu) = const f g V hv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem const_zero (f : R) (U hu) : const (0 : M) f U hu = 0 := Subtype.ext <| funext fun x ↦ by simp; rfl @@ -355,6 +359,7 @@ theorem const_mul_cancel' (f g₁ g₂ : R) (U hu₁ hu₂) : const g₁ g₂ U hu₂ * const f g₁ U hu₁ = const f g₂ U hu₂ := by rw [mul_comm, const_mul_cancel] +set_option backward.isDefEq.respectTransparency.types false in theorem const_eq_const_of_smul_eq_smul (f₁ f₂ : M) (g₁ g₂ : R) (U hu₁ hu₂) (H : g₁ • f₂ = g₂ • f₁) : const f₁ g₁ U hu₁ = const f₂ g₂ U hu₂ := Subtype.ext (funext fun x ↦ by @@ -409,6 +414,7 @@ def toBasicOpenₗ (f : R) : exact Submonoid.powers_le (P := (IsUnit.submonoid _).comap (algebraMap R _)).mpr (isUnit_basicOpen_end ..) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toBasicOpenₗ_mk (s : R) (f : M) (g : Submonoid.powers s) : toBasicOpenₗ R M s (.mk f g) = const f g.1 (basicOpen s) (by @@ -511,6 +517,7 @@ theorem toBasicOpenₗ_surjective (f : R) : Function.Surjective (toBasicOpenₗ simp_rw [one_smul, Finset.smul_sum, Submonoid.smul_def, smul_comm (b i), hab _ i, ← smul_assoc, ← Finset.sum_smul, hc] +set_option backward.isDefEq.respectTransparency.types false in public instance (f : R) : IsLocalizedModule.Away f (toOpenₗ R M (basicOpen f)) := by convert! IsLocalizedModule.of_linearEquiv (.powers f) (LocalizedModule.mkLinearMap (.powers f) M) @@ -551,6 +558,9 @@ the stalk of `structureSheaf R` at `x`. -/ CommRingCat.of R ⟶ (structurePresheafInCommRingCat R).stalk x := CommRingCat.ofHom (algebraMap _ _) ≫ (structurePresheafInCommRingCat R).germ ⊤ x trivial +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[elementwise, reassoc] public lemma algebraMap_germ (U : Opens (PrimeSpectrum.Top R)) (x : PrimeSpectrum.Top R) (hxU : x ∈ U) : @@ -588,6 +598,7 @@ instance (x : PrimeSpectrum.Top R) : ↑(TopCat.Presheaf.stalk (moduleStructurePresheaf R M).presheaf x) := .of_algebraMap_smul fun _ _ ↦ rfl +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in def modulePresheafStalkIso (x : PrimeSpectrum.Top R) : ↑(TopCat.Presheaf.stalk (moduleStructurePresheaf R M).presheaf x) ≃ₗ[R] @@ -659,6 +670,7 @@ theorem isUnit_toStalkₗ' (x : PrimeSpectrum.Top R) (f : R) (hf : x ∈ basicOp simp only [Module.algebraMap_end_apply] rw [toStalk_smul] +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in /-- The canonical ring homomorphism from the localization of `R` at `p` to the stalk of the structure sheaf at the point `p`. -/ @@ -683,6 +695,7 @@ theorem localizationtoStalkₗ_mk (x : PrimeSpectrum.Top R) (f : M) (s) : congr 1 exact const_eq_const_of_smul_eq_smul (H := by simp) .. +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in /-- The ring homomorphism that takes a section of the structure sheaf of `R` on the open set `U`, implemented as a subtype of dependent functions to localizations at prime ideals, and evaluates @@ -695,6 +708,7 @@ def openToLocalizationₗ (U : Opens (PrimeSpectrum.Top R)) (x : PrimeSpectrum.T map_smul' _ _ := rfl map_add' _ _ := rfl } +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in /-- The ring homomorphism from the stalk of the structure sheaf of `R` at a point corresponding to a prime ideal `p` to the localization of `R` at `p`, @@ -768,6 +782,7 @@ theorem localizationToStalk_stalkToFiberRingHom (x : PrimeSpectrum.Top R) : localizationtoStalkₗ R M x ≫ stalkToLocalizationₗ R M x = 𝟙 _ := (stalkIsoₗ R M x).inv_hom_id +set_option backward.isDefEq.respectTransparency.types false in instance (x : PrimeSpectrum.Top R) : IsLocalizedModule x.asIdeal.primeCompl (toStalkₗ' R M x).hom := by convert! @@ -796,6 +811,7 @@ def toStalkₗ (x : PrimeSpectrum.Top R) : congr 1 exact (IsScalarTower.algebraMap_smul Γ(R, _) (M := Γ(M, _)) _ _).symm +set_option backward.isDefEq.respectTransparency.types false in public instance (x : PrimeSpectrum.Top R) : IsLocalizedModule x.asIdeal.primeCompl (toStalkₗ R M x) := by convert! @@ -814,6 +830,7 @@ instance (x : PrimeSpectrum.Top R) : IsLocalizedModule x.asIdeal.primeCompl (toS Limits.colimit.isoColimitCocone_ι_hom (C := Ab) .. exact congr($this _) +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- The stalk of `Spec R` at `x` is isomorphic to the stalk of `R^~` at `x`. -/ @[expose] public @@ -847,6 +864,7 @@ def commRingCatStalkEquivModuleStalk (x : PrimeSpectrum.Top R) : rfl · exact congr($this _).symm +set_option backward.isDefEq.respectTransparency.types false in public instance (x : PrimeSpectrum.Top R) : IsLocalization.AtPrime ((structurePresheafInCommRingCat R).stalk x) x.asIdeal := by refine (isLocalizedModule_iff_isLocalization' _ _).mp ?_ @@ -871,6 +889,7 @@ public instance (x : PrimeSpectrum.Top R) : exact (((structurePresheafInCommRingCat R).germ ⊤ x (by simp)).hom.comp (algebraMap R Γ(R, _))).map_one.symm +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- The stalk of `Spec R` at `x` is isomorphic to `Rₚ`, where `p` is the prime corresponding to `x`. -/ @@ -916,19 +935,23 @@ theorem stalkAlgebra_map (p : PrimeSpectrum R) (r : R) : algebraMap R ((structureSheaf R).presheaf.stalk p) r = toStalk R p r := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Stalk of the structure sheaf at a prime p as localization of R -/ instance IsLocalization.to_stalk (p : PrimeSpectrum R) : IsLocalization.AtPrime ((structureSheaf R).presheaf.stalk p) p.asIdeal := inferInstanceAs (IsLocalization.AtPrime ((structurePresheafInCommRingCat R).stalk p) p.asIdeal) +set_option backward.isDefEq.respectTransparency.types false in instance openAlgebra (U : (Opens (PrimeSpectrum R))ᵒᵖ) : Algebra R ((structureSheaf R).obj.obj U) := inferInstanceAs (Algebra R ((structureSheafInType R R).presheaf.obj _)) +set_option backward.isDefEq.respectTransparency.types false in /-- Sections of the structure sheaf of Spec R on a basic open as localization of R -/ instance IsLocalization.to_basicOpen (r : R) : IsLocalization.Away r ((structureSheaf R).obj.obj (op <| basicOpen r)) := inferInstanceAs (IsLocalization.Away r Γ(R, basicOpen r)) +set_option backward.isDefEq.respectTransparency.types false in instance to_basicOpen_epi (r : R) : Epi (CommRingCat.ofHom <| algebraMap R ((structureSheaf R).obj.obj (op <| basicOpen r))) := @@ -1034,6 +1057,7 @@ theorem isLocallyFraction_comapFun (U : Opens (PrimeSpectrum.Top R)) rw [H] simp +set_option backward.isDefEq.respectTransparency.types false in /-- For a ring homomorphism `f : R →+* S` and open sets `U` and `V` of the prime spectra of `R` and `S` such that `V ⊆ (comap f) ⁻¹ U`, the induced ring homomorphism from the structure sheaf of `R` at `U` to the structure sheaf of `S` at `V`. @@ -1081,6 +1105,7 @@ theorem comapₗ_eq_localRingHom (f : R →+* S) (U : Opens (PrimeSpectrum.Top R convert_to! Localization.mk _ _ = Localization.localRingHom _ _ _ _ (Localization.mk _ _) simp [Localization.mk_eq_mk'] +set_option backward.isDefEq.respectTransparency.types false in /-- For a ring homomorphism `f : R →+* S` and open sets `U` and `V` of the prime spectra of `R` and `S` such that `V ⊆ (comap f) ⁻¹ U`, the induced ring homomorphism from the structure sheaf of `R` at `U` to the structure sheaf of `S` at `V`. @@ -1106,6 +1131,7 @@ def comap (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) (V : Opens (PrimeSpe simp only [comapₗ_eq_localRingHom, PrimeSpectrum.comap_asIdeal] exact (Localization.localRingHom ..).map_zero +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem comap_apply (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1) @@ -1126,6 +1152,7 @@ theorem comap_const (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) convert_to! Localization.localRingHom _ _ _ _ (Localization.mk _ _) = Localization.mk _ _ simp [Localization.mk_eq_mk'] +set_option backward.isDefEq.respectTransparency.types false in /-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf. @@ -1166,6 +1193,7 @@ theorem comap_comp (f : R →+* S) (g : S →+* P) (U : Opens (PrimeSpectrum.Top rw [comap_apply, Localization.localRingHom_comp _ (PrimeSpectrum.comap g p.1).asIdeal] <;> simp +set_option backward.isDefEq.respectTransparency.types false in @[elementwise, reassoc] theorem toOpen_comp_comap (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) : CommRingCat.ofHom (algebraMap _ _) ≫ @@ -1177,6 +1205,7 @@ theorem toOpen_comp_comap (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) : rw [comap_apply] exact Localization.localRingHom_to_map _ _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma comap_basicOpen (f : R →+* S) (x : R) : comap f (PrimeSpectrum.basicOpen x) (PrimeSpectrum.basicOpen (f x)) (PrimeSpectrum.comap_basicOpen f x).le = diff --git a/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean b/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean index 36739968f748a9..cc7d95565e8a3e 100644 --- a/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean +++ b/Mathlib/AlgebraicGeometry/ValuativeCriterion.lean @@ -110,6 +110,7 @@ namespace ValuativeCriterion.Existence open IsLocalRing +set_option backward.isDefEq.respectTransparency.types false in @[stacks 01KE] lemma specializingMap (H : ValuativeCriterion.Existence f) : SpecializingMap f := by @@ -323,6 +324,7 @@ lemma IsSeparated.eq_valuativeCriterion : end Uniqueness +set_option backward.isDefEq.respectTransparency.types false in /-- The **valuative criterion** for proper morphisms. -/ @[stacks 0BX5] lemma IsProper.eq_valuativeCriterion : diff --git a/Mathlib/AlgebraicGeometry/ZariskisMainTheorem.lean b/Mathlib/AlgebraicGeometry/ZariskisMainTheorem.lean index 0448888c13e6d0..1879be52c37a82 100644 --- a/Mathlib/AlgebraicGeometry/ZariskisMainTheorem.lean +++ b/Mathlib/AlgebraicGeometry/ZariskisMainTheorem.lean @@ -188,6 +188,7 @@ lemma Scheme.Hom.exists_mem_and_isIso_morphismRestrict_toNormalization (Q := @Surjective ⊓ @Flat ⊓ @LocallyOfFinitePresentation) this ⟨⟨‹_›, inferInstance⟩, inferInstance⟩ ‹_› +set_option backward.isDefEq.respectTransparency.types false in /-- **Zariski's main theorem** @@ -287,6 +288,7 @@ lemma Scheme.Hom.exists_isIso_morphismRestrict_toNormalization rw [← RingHom.algebraMap_toAlgebra (X.presheaf.germ _ _ _).hom, @RingHom.quasiFinite_algebraMap] exact .of_isLocalization (hr.primeIdealOf ⟨x, hxV⟩).asIdeal.primeCompl +set_option backward.isDefEq.respectTransparency.types false in lemma Scheme.Hom.isOpen_quasiFiniteAt [LocallyOfFiniteType f] : IsOpen { x | f.QuasiFiniteAt x } := by wlog H : IsAffineHom f @@ -399,6 +401,7 @@ lemma IsClosedImmersion.eq_proper_inf_monomorphisms : ext exact IsClosedImmersion.iff_isProper_and_mono .. +set_option backward.isDefEq.respectTransparency.types false in @[stacks 02UP] lemma exists_isFinite_morphismRestrict_of_finite_preimage_singleton [IsProper f] (y : Y) (hx : (f ⁻¹' {y}).Finite) : diff --git a/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean b/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean index 7e6761fa8ed7d9..967618574f0171 100644 --- a/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean +++ b/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean @@ -120,6 +120,7 @@ theorem d_squared (n : ℕ) : objD X (n + 1) ≫ objD X n = 0 := by /-- The alternating face map complex, on objects -/ +@[implicit_reducible] def obj : ChainComplex C ℕ := ChainComplex.of (fun n => X _⦋n⦌) (objD X) (d_squared X) @@ -155,6 +156,7 @@ end AlternatingFaceMapComplex variable (C : Type*) [Category* C] [Preadditive C] /-- The alternating face map complex, as a functor -/ +@[implicit_reducible] def alternatingFaceMapComplex : SimplicialObject C ⥤ ChainComplex C ℕ where obj := AlternatingFaceMapComplex.obj map f := AlternatingFaceMapComplex.map f @@ -261,6 +263,7 @@ end AlternatingFaceMapComplex variable {A : Type*} [Category* A] [Abelian A] +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion map of the Moore complex in the alternating face map complex -/ def inclusionOfMooreComplexMap (X : SimplicialObject A) : (normalizedMooreComplex A).obj X ⟶ (alternatingFaceMapComplex A).obj X := @@ -290,6 +293,7 @@ theorem inclusionOfMooreComplexMap_f (X : SimplicialObject A) (n : ℕ) : variable (A) set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion map of the Moore complex in the alternating face map complex, as a natural transformation -/ @[simps] diff --git a/Mathlib/AlgebraicTopology/CechNerve.lean b/Mathlib/AlgebraicTopology/CechNerve.lean index 9b9f4f0b1aff3e..c0299606cfaf62 100644 --- a/Mathlib/AlgebraicTopology/CechNerve.lean +++ b/Mathlib/AlgebraicTopology/CechNerve.lean @@ -52,7 +52,7 @@ variable [∀ n : ℕ, HasWidePullback.{0} f.right (fun _ : Fin (n + 1) => f.lef set_option backward.isDefEq.respectTransparency false in /-- The Čech nerve associated to an arrow. -/ -@[simps] +@[simps, implicit_reducible] def cechNerve : SimplicialObject C where obj n := widePullback.{0} f.right (fun _ : Fin (n.unop.len + 1) => f.left) fun _ => f.hom map g := WidePullback.lift (WidePullback.base _) @@ -114,6 +114,7 @@ def augmentedCechNerve : Arrow C ⥤ SimplicialObject.Augmented C where obj f := f.augmentedCechNerve map F := Arrow.mapAugmentedCechNerve F +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A helper function used in defining the Čech adjunction. -/ @[simps] @@ -254,6 +255,7 @@ def augmentedCechConerve : Arrow C ⥤ CosimplicialObject.Augmented C where obj f := f.augmentedCechConerve map F := Arrow.mapAugmentedCechConerve F +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A helper function used in defining the Čech conerve adjunction. -/ @[simps!] @@ -344,6 +346,7 @@ namespace CechNerveTerminalFrom variable [HasTerminal C] (ι : Type w) /-- The diagram `Option ι ⥤ C` sending `none` to the terminal object and `some j` to `X`. -/ +@[implicit_reducible] def wideCospan (X : C) : WidePullbackShape ι ⥤ C := WidePullbackShape.wideCospan (terminal C) (fun _ : ι => X) fun _ => terminal.from X @@ -405,6 +408,7 @@ lemma wideCospan.limitIsoPi_inv_comp_pi [Finite ι] (X : C) (j : ι) : (wideCospan.limitIsoPi ι X).inv ≫ WidePullback.π _ j = Pi.π _ j := IsLimit.conePointUniqueUpToIso_inv_comp _ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma wideCospan.limitIsoPi_hom_comp_pi [Finite ι] (X : C) (j : ι) : (wideCospan.limitIsoPi ι X).hom ≫ Pi.π _ j = WidePullback.π _ j := by diff --git a/Mathlib/AlgebraicTopology/DoldKan/Compatibility.lean b/Mathlib/AlgebraicTopology/DoldKan/Compatibility.lean index 5d64c0bc3c4a4b..967dd761693aea 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/Compatibility.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/Compatibility.lean @@ -85,6 +85,7 @@ def equivalence₁CounitIso : (e'.inverse ⋙ eA.inverse) ⋙ F ≅ 𝟭 B' := _ ≅ e'.inverse ⋙ e'.functor := isoWhiskerLeft _ (leftUnitor _) _ ≅ 𝟭 B' := e'.counitIso +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem equivalence₁CounitIso_eq : (equivalence₁ hF).counitIso = equivalence₁CounitIso hF := by ext Y @@ -103,6 +104,7 @@ def equivalence₁UnitIso : 𝟭 A ≅ F ⋙ e'.inverse ⋙ eA.inverse := _ ≅ (eA.functor ⋙ e'.functor) ⋙ e'.inverse ⋙ eA.inverse := (associator _ _ _).symm _ ≅ F ⋙ e'.inverse ⋙ eA.inverse := isoWhiskerRight hF _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem equivalence₁UnitIso_eq : (equivalence₁ hF).unitIso = equivalence₁UnitIso hF := by ext X @@ -154,6 +156,7 @@ def equivalence₂UnitIso : 𝟭 A ≅ (F ⋙ eB.inverse) ⋙ eB.functor ⋙ e'. _ ≅ (F ⋙ eB.inverse) ⋙ eB.functor ⋙ e'.inverse ⋙ eA.inverse := associator _ _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem equivalence₂UnitIso_eq : (equivalence₂ eB hF).unitIso = equivalence₂UnitIso eB hF := by ext X @@ -269,6 +272,7 @@ def equivalenceUnitIso : 𝟭 A ≅ (F ⋙ eB.inverse) ⋙ G := variable {ε hF hG} +set_option backward.isDefEq.respectTransparency.types false in theorem equivalenceUnitIso_eq (hε : υ hF = ε) : (equivalence hF hG).unitIso = equivalenceUnitIso hG ε := by ext1; apply NatTrans.ext; ext X diff --git a/Mathlib/AlgebraicTopology/DoldKan/Equivalence.lean b/Mathlib/AlgebraicTopology/DoldKan/Equivalence.lean index 97716a6dda8fd9..167190b4130955 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/Equivalence.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/Equivalence.lean @@ -146,6 +146,9 @@ def N : SimplicialObject A ⥤ ChainComplex A ℕ := def Γ : ChainComplex A ℕ ⥤ SimplicialObject A := Idempotents.DoldKan.Γ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The comparison isomorphism between `normalizedMooreComplex A` and the functor `Idempotents.DoldKan.N` from the pseudoabelian case -/ @[simps!] diff --git a/Mathlib/AlgebraicTopology/DoldKan/EquivalencePseudoabelian.lean b/Mathlib/AlgebraicTopology/DoldKan/EquivalencePseudoabelian.lean index 1e7257e5e2d02f..e9a248efa40fd4 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/EquivalencePseudoabelian.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/EquivalencePseudoabelian.lean @@ -113,6 +113,9 @@ theorem hη : simp only [Compatibility.τ₀_hom_app, Compatibility.τ₁_hom_app] exact (N₂Γ₂_compatible_with_N₁Γ₀ K).trans (by simp) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The counit isomorphism induced by `N₁Γ₀` -/ @[simps!] def η : Γ ⋙ N ≅ 𝟭 (ChainComplex C ℕ) := diff --git a/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean index f6a735cfaa3bd1..cffd8bd19436ea 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean @@ -327,6 +327,7 @@ for any additive category `C`. -/ def Γ₂ : Karoubi (ChainComplex C ℕ) ⥤ Karoubi (SimplicialObject C) := (CategoryTheory.Idempotents.functorExtension₂ _ _).obj Γ₀ +set_option backward.isDefEq.respectTransparency.types false in theorem HigherFacesVanish.on_Γ₀_summand_id (K : ChainComplex C ℕ) (n : ℕ) : @HigherFacesVanish C _ _ (Γ₀.obj K) _ n (n + 1) (((Γ₀.splitting K).cofan _).inj (Splitting.IndexSet.id (op ⦋n + 1⦌))) := by diff --git a/Mathlib/AlgebraicTopology/DoldKan/FunctorN.lean b/Mathlib/AlgebraicTopology/DoldKan/FunctorN.lean index cbfd75b4f86e11..019657de331b8d 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/FunctorN.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/FunctorN.lean @@ -48,7 +48,7 @@ variable {C : Type*} [Category* C] [Preadditive C] set_option backward.isDefEq.respectTransparency false in /-- The functor `SimplicialObject C ⥤ Karoubi (ChainComplex C ℕ)` which maps `X` to the formal direct factor of `K[X]` defined by `PInfty`. -/ -@[simps] +@[simps, implicit_reducible] def N₁ : SimplicialObject C ⥤ Karoubi (ChainComplex C ℕ) where obj X := { X := AlternatingFaceMapComplex.obj X diff --git a/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean b/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean index 544576f07024a4..07504406f1a7d9 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean @@ -140,6 +140,7 @@ theorem Hσ_eq_zero (q : ℕ) : (Hσ q : K[X] ⟶ K[X]).f 0 = 0 := by simp · rw [hσ'_eq_zero (Nat.succ_pos q) (c_mk 1 0 rfl), zero_comp] +set_option backward.isDefEq.respectTransparency.types false in /-- The maps `hσ' q n m hnm` are natural on the simplicial object -/ theorem hσ'_naturality (q : ℕ) (n m : ℕ) (hnm : c.Rel m n) {X Y : SimplicialObject C} (f : X ⟶ Y) : f.app (op ⦋n⦌) ≫ hσ' q n m hnm = hσ' q n m hnm ≫ f.app (op ⦋m⦌) := by diff --git a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean index 393d22a1a83f6e..0a02699f9ca211 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean @@ -217,7 +217,6 @@ theorem identity_N₂_objectwise (P : Karoubi (SimplicialObject C)) : eq₁, eq₂, PInfty_f_naturality_assoc, app_idem, PInfty_f_idem_assoc] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem identity_N₂ : (𝟙 (N₂ : Karoubi (SimplicialObject C) ⥤ _) ◫ N₂Γ₂.inv) ≫ (Functor.associator _ _ _).inv ≫ Γ₂N₂.natTrans ◫ 𝟙 (@N₂ C _ _) = 𝟙 N₂ := by @@ -226,7 +225,6 @@ theorem identity_N₂ : NatTrans.id_app, Functor.comp_obj] rw [Γ₂.map_id, N₂.map_id, comp_id, id_comp, id_comp, identity_N₂_objectwise P] -set_option backward.isDefEq.respectTransparency false in instance : IsIso (Γ₂N₂.natTrans : (N₂ : Karoubi (SimplicialObject C) ⥤ _) ⋙ _ ⟶ _) := by have : ∀ P : Karoubi (SimplicialObject C), IsIso (Γ₂N₂.natTrans.app P) := by intro P @@ -239,7 +237,6 @@ instance : IsIso (Γ₂N₂.natTrans : (N₂ : Karoubi (SimplicialObject C) ⥤ exact isIso_of_reflects_iso _ N₂ apply NatIso.isIso_of_isIso_app -set_option backward.isDefEq.respectTransparency false in instance : IsIso (Γ₂N₁.natTrans : (N₁ : SimplicialObject C ⥤ _) ⋙ _ ⟶ _) := by have : ∀ X : SimplicialObject C, IsIso (Γ₂N₁.natTrans.app X) := by intro X diff --git a/Mathlib/AlgebraicTopology/DoldKan/Normalized.lean b/Mathlib/AlgebraicTopology/DoldKan/Normalized.lean index 43c7aa64499ae2..ae8275f4163c33 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/Normalized.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/Normalized.lean @@ -73,6 +73,7 @@ def PInftyToNormalizedMooreComplex (X : SimplicialObject A) : K[X] ⟶ N[X] := ← alternatingFaceMapComplex_obj_d] exact PInfty.comm (n + 1) n +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] theorem PInftyToNormalizedMooreComplex_comp_inclusionOfMooreComplexMap (X : SimplicialObject A) : diff --git a/Mathlib/AlgebraicTopology/DoldKan/PInfty.lean b/Mathlib/AlgebraicTopology/DoldKan/PInfty.lean index c5263655e2e9b3..0e8a6b63273eaf 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/PInfty.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/PInfty.lean @@ -73,11 +73,17 @@ theorem QInfty_f_0 : (QInfty.f 0 : X _⦋0⦌ ⟶ X _⦋0⦌) = 0 := by theorem QInfty_f (n : ℕ) : (QInfty.f n : X _⦋n⦌ ⟶ X _⦋n⦌) = (Q n).f n := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem PInfty_f_naturality (n : ℕ) {X Y : SimplicialObject C} (f : X ⟶ Y) : f.app (op ⦋n⦌) ≫ PInfty.f n = PInfty.f n ≫ f.app (op ⦋n⦌) := P_f_naturality n n f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem QInfty_f_naturality (n : ℕ) {X Y : SimplicialObject C} (f : X ⟶ Y) : f.app (op ⦋n⦌) ≫ QInfty.f n = QInfty.f n ≫ f.app (op ⦋n⦌) := diff --git a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean index f91f096b7b636f..dda65810f8dbe1 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean @@ -226,6 +226,7 @@ noncomputable def toKaroubiNondegComplexIsoN₁ : simp only [πSummand_comp_cofan_inj_id_comp_PInfty_eq_PInfty, Karoubi.comp_f, HomologicalComplex.comp_f, N₁_obj_p, Karoubi.id_f] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma toKaroubiNondegComplexIsoN₁_hom_f_PInfty : @@ -259,23 +260,27 @@ noncomputable def fromNondegComplex : s.nondegComplex ⟶ K[X] := (fullyFaithfulToKaroubi _).preimage (s.toKaroubiNondegComplexIsoN₁.hom ≫ { f := PInfty }) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma PInfty_toNondegComplex : PInfty ≫ s.toNondegComplex = s.toNondegComplex := (toKaroubi _).map_injective (by simp [toNondegComplex]) +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma fromNondegComplex_toNondegComplex : s.fromNondegComplex ≫ s.toNondegComplex = 𝟙 _ := (toKaroubi _).map_injective (by simp [toNondegComplex, fromNondegComplex]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma toNondegComplex_f (n : ℕ) : s.toNondegComplex.f n = PInfty.f n ≫ s.toKaroubiNondegComplexIsoN₁.inv.f.f n := by simp [toNondegComplex, fullyFaithfulToKaroubi] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma fromNondegComplex_f (n : ℕ) : diff --git a/Mathlib/AlgebraicTopology/EilenbergSteenrod.lean b/Mathlib/AlgebraicTopology/EilenbergSteenrod.lean index f85f273ea327e1..a75255d889501c 100644 --- a/Mathlib/AlgebraicTopology/EilenbergSteenrod.lean +++ b/Mathlib/AlgebraicTopology/EilenbergSteenrod.lean @@ -77,12 +77,18 @@ instance : Category (HomologyPretheory.{u} C c) where variable {HP HP' : HomologyPretheory.{u} C c} -- TODO: generate this with `@[to_app]` +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Hom.iso_comm_app (f : HP ⟶ HP') (i : ι) (X : TopCat.{u}) : (HP.iso i).hom.app X ≫ (f.homₚ i).app (ofTopCat X) = (f.hom i).app X ≫ (HP'.iso i).hom.app X := congr($(f.iso_comm _).app _) -- TODO: generate this with `@[to_app]` +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Hom.w_app (f : HP ⟶ HP') (i j : ι) (X : TopPair.{u}) : (HP.δ i j).app X ≫ (f.hom j).app X.left = (f.homₚ i).app X ≫ (HP'.δ i j).app X := @@ -93,6 +99,9 @@ lemma iso_homₚ_inv_hom (f : HP ⟶ HP') (i : ι) : (HP.iso i).hom ≫ incl.whiskerLeft (f.homₚ i) ≫ (HP'.iso i).inv = f.hom i := by simp -- TODO: generate this with `@[to_app]` +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma iso_homₚ_inv_hom_app (f : HP ⟶ HP') (i : ι) (X : TopCat.{u}) : (HP.iso i).hom.app X ≫ (f.homₚ i).app (ofTopCat X) ≫ (HP'.iso i).inv.app X = (f.hom i).app X := diff --git a/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean b/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean index a383cecb67724a..65104bd02e1fc4 100644 --- a/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean +++ b/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean @@ -87,6 +87,7 @@ namespace ExtraDegeneracy attribute [reassoc] s₀_comp_δ₁ s_comp_δ s_comp_σ attribute [reassoc (attr := simp)] s'_comp_ε s_comp_δ₀ +set_option backward.isDefEq.respectTransparency.types false in attribute [local simp←] Functor.map_comp in attribute [local simp] s₀_comp_δ₁ s_comp_δ s_comp_σ in /-- If `ed` is an extra degeneracy for `X : SimplicialObject.Augmented C` and @@ -105,9 +106,9 @@ def ofIso {X Y : SimplicialObject.Augmented C} (e : X ≅ Y) (ed : ExtraDegenera s' := (point.mapIso e).inv ≫ ed.s' ≫ (drop.mapIso e).hom.app (op ⦋0⦌) s n := (drop.mapIso e).inv.app (op ⦋n⦌) ≫ ed.s n ≫ (drop.mapIso e).hom.app (op ⦋n + 1⦌) s'_comp_ε := by - simpa [dsimp% w₀] using dsimp% (point.mapIso e).inv_hom_id + simpa [w₀] using dsimp% (point.mapIso e).inv_hom_id s₀_comp_δ₁ := by - simp [← SimplicialObject.δ_naturality, s₀_comp_δ₁_assoc, dsimp% w₀_assoc] + simp [← SimplicialObject.δ_naturality, s₀_comp_δ₁_assoc, w₀_assoc] s_comp_δ₀ n := by simpa [← SimplicialObject.δ_naturality] using congr_app (drop.mapIso e).inv_hom_id (op ⦋n⦌) diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean index 6c130502676bbd..e5321c6dd5aac3 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean @@ -99,6 +99,7 @@ theorem transReflReparamAux_zero : transReflReparamAux 0 = 0 := by theorem transReflReparamAux_one : transReflReparamAux 1 = 1 := by norm_num [transReflReparamAux] +set_option backward.isDefEq.respectTransparency.types false in theorem trans_refl_reparam (p : Path x₀ x₁) : p.trans (Path.refl x₁) = p.reparam (fun t => ⟨transReflReparamAux t, transReflReparamAux_mem_I t⟩) (by fun_prop) diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean index c22a0cb1c11ea3..b5f417f6d8ac27 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean @@ -150,7 +150,6 @@ include hfg `f(p)` and `g(p)` are the same as well, despite having a priori different types -/ theorem heq_path_of_eq_image : (πₘ (TopCat.ofHom f)).map ⟦p⟧ ≍ (πₘ (TopCat.ofHom g)).map ⟦q⟧ := by - simp only [map_eq] apply Path.Homotopic.hpath_hext exact hfg diff --git a/Mathlib/AlgebraicTopology/ModelCategory/Basic.lean b/Mathlib/AlgebraicTopology/ModelCategory/Basic.lean index ec18683c46f7ff..5206244cd8631f 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/Basic.lean @@ -123,7 +123,7 @@ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- Constructor for `ModelCategory C` which assumes a formulation of axioms using weak factorization systems. -/ -@[implicit_reducible] +@[instance_reducible] def mk' [CategoryWithFibrations C] [CategoryWithCofibrations C] [CategoryWithWeakEquivalences C] [HasFiniteLimits C] [HasFiniteColimits C] [(weakEquivalences C).HasTwoOutOfThreeProperty] diff --git a/Mathlib/AlgebraicTopology/ModelCategory/BifibrantObjectHomotopy.lean b/Mathlib/AlgebraicTopology/ModelCategory/BifibrantObjectHomotopy.lean index 38eb10e6e53d71..25bc6b6e4ab78c 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/BifibrantObjectHomotopy.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/BifibrantObjectHomotopy.lean @@ -66,6 +66,7 @@ abbrev HoCat := Quotient (BifibrantObject.homRel C) /-- The quotient functor from the category of bifibrant objects to its homotopy category. -/ +@[implicit_reducible] def toHoCat : BifibrantObject C ⥤ HoCat C := Quotient.functor _ lemma toHoCat_obj_surjective : Function.Surjective (toHoCat (C := C)).obj := @@ -141,6 +142,7 @@ section variable {X Y : C} [IsCofibrant X] [IsCofibrant Y] [IsFibrant X] [IsFibrant Y] +set_option backward.isDefEq.respectTransparency.types false in /-- Right homotopy classes of maps between bifibrant objects identify to morphisms in the homotopy category `BifibrantObject.HoCat`. -/ def HoCat.homEquivRight : @@ -170,12 +172,14 @@ lemma HoCat.homEquivLeft_apply (f : X ⟶ Y) : HoCat.homEquivLeft (.mk f) = toHoCat.map (homMk f) := by simp [homEquivLeft] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma HoCat.homEquivLeft_symm_apply (f : X ⟶ Y) : HoCat.homEquivRight.symm (toHoCat.map (homMk f)) = .mk f := rfl end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inclusion functor `BifibrantObject.HoCat C ⥤ FibrantObject.HoCat C`. -/ def HoCat.ιFibrantObject : HoCat C ⥤ FibrantObject.HoCat C := @@ -202,8 +206,10 @@ def toHoCatCompιFibrantObject : toHoCat (C := C) ⋙ HoCat.ιFibrantObject ≅ ιFibrantObject ⋙ FibrantObject.toHoCat := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inclusion functor `BifibrantObject.HoCat C ⥤ CofibrantObject.HoCat C`. -/ +@[implicit_reducible] def HoCat.ιCofibrantObject : HoCat C ⥤ CofibrantObject.HoCat C := CategoryTheory.Quotient.lift _ (BifibrantObject.ιCofibrantObject ⋙ CofibrantObject.toHoCat) (fun _ _ _ _ h ↦ by @@ -286,6 +292,9 @@ noncomputable def bifibrantResolutionMap {X₁ X₂ : CofibrantObject C} (f : X bifibrantResolutionObj X₁ ⟶ bifibrantResolutionObj X₂ := (exists_bifibrant_map f).choose +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma bifibrantResolutionMap_fac {X₁ X₂ : CofibrantObject C} (f : X₁ ⟶ X₂) : iBifibrantResolutionObj X₁ ≫ homMk (bifibrantResolutionMap f).hom = @@ -301,6 +310,9 @@ instance {X₁ X₂ : CofibrantObject C} (f : X₁ ⟶ X₂) [WeakEquivalence f] bifibrantResolutionMap_fac, weakEquivalence_precomp_iff] infer_instance +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma bifibrantResolutionMap_fac' {X₁ X₂ : CofibrantObject C} (f : X₁ ⟶ X₂) : toHoCat.map X₁.iBifibrantResolutionObj ≫ @@ -308,6 +320,7 @@ lemma bifibrantResolutionMap_fac' {X₁ X₂ : CofibrantObject C} (f : X₁ ⟶ toHoCat.map f ≫ toHoCat.map X₂.iBifibrantResolutionObj := toHoCat.congr_map (bifibrantResolutionMap_fac f) +set_option backward.isDefEq.respectTransparency.types false in lemma bifibrantResolutionObj_hom_ext {X : CofibrantObject C} {Y : BifibrantObject.HoCat C} {f g : BifibrantObject.toHoCat.obj (bifibrantResolutionObj X) ⟶ Y} @@ -334,7 +347,7 @@ lemma bifibrantResolutionObj_hom_ext set_option backward.isDefEq.respectTransparency false in /-- The bifibrant resolution functor from the category of cofibrant objects to the homotopy category of bifibrant objects. -/ -@[simps] +@[simps, implicit_reducible] noncomputable def HoCat.bifibrantResolution' : CofibrantObject C ⥤ BifibrantObject.HoCat C where obj X := BifibrantObject.toHoCat.obj (bifibrantResolutionObj X) map f := BifibrantObject.toHoCat.map (bifibrantResolutionMap f) @@ -345,6 +358,7 @@ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- The bifibrant resolution functor from the homotopy category of cofibrant objects to the homotopy category of bifibrant objects. -/ +@[implicit_reducible] noncomputable def HoCat.bifibrantResolution : CofibrantObject.HoCat C ⥤ BifibrantObject.HoCat C := CategoryTheory.Quotient.lift _ CofibrantObject.HoCat.bifibrantResolution' (by @@ -422,7 +436,6 @@ lemma HoCat.adjCounitIso_inv_app (X : BifibrantObject C) : BifibrantObject.toHoCat.map (BifibrantObject.homMk ((iBifibrantResolutionObj (.mk X.obj))).hom) := rfl -set_option backward.isDefEq.respectTransparency false in /-- The adjunction between the category `CofibrantObject.HoCat C` and `BifibrantObject.HoCat C`. -/ noncomputable def HoCat.adj : HoCat.bifibrantResolution (C := C) ⊣ BifibrantObject.HoCat.ιCofibrantObject where @@ -434,8 +447,7 @@ noncomputable def HoCat.adj : rw [comp_hom_eq_id]; push inv apply bifibrantResolutionObj_hom_ext dsimp - simp only [HoCat.adjCounitIso_inv_app, - BifibrantObject.HoCat.ιCofibrantObject_map_toHoCat_map, ObjectProperty.homMk_hom] + simp only [HoCat.adjCounitIso_inv_app] apply bifibrantResolutionMap_fac' right_triangle_components X := by obtain ⟨X, rfl⟩ := BifibrantObject.toHoCat_obj_surjective X @@ -452,13 +464,11 @@ instance : (BifibrantObject.HoCat.ιCofibrantObject (C := C)).Full := instance : (BifibrantObject.HoCat.ιCofibrantObject (C := C)).Faithful := HoCat.adj.fullyFaithfulROfIsIsoCounit.faithful -set_option backward.isDefEq.respectTransparency false in instance (X : CofibrantObject.HoCat C) : WeakEquivalence (HoCat.adj.unit.app X) := by obtain ⟨X, rfl⟩ := toHoCat_obj_surjective X dsimp [HoCat.adj] infer_instance -set_option backward.isDefEq.respectTransparency false in instance : HoCat.bifibrantResolution.IsLocalization (weakEquivalences (HoCat C)) := HoCat.adj.isLocalization_leftAdjoint _ (by intro X Y f hf diff --git a/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean b/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean index 45df5f45b78450..0e842de11a775a 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean @@ -56,6 +56,7 @@ abbrev HoCat := Quotient (CofibrantObject.homRel C) /-- The quotient functor from the category of cofibrant objects to its homotopy category. -/ +@[implicit_reducible] def toHoCat : CofibrantObject C ⥤ HoCat C := Quotient.functor _ lemma toHoCat_obj_surjective : Function.Surjective (toHoCat (C := C)).obj := diff --git a/Mathlib/AlgebraicTopology/ModelCategory/Cylinder.lean b/Mathlib/AlgebraicTopology/ModelCategory/Cylinder.lean index 98846e7d8c1fe7..26f56e880dc38c 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/Cylinder.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/Cylinder.lean @@ -200,6 +200,7 @@ instance : IsCofibrant P.I := end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [HasBinaryCoproducts C] [CategoryWithCofibrations C] [P.IsGood] [(cofibrations C).RespectsIso] : P.symm.IsGood where diff --git a/Mathlib/AlgebraicTopology/ModelCategory/Transport.lean b/Mathlib/AlgebraicTopology/ModelCategory/Transport.lean index b644d80c29d975..0d9ae1b0ab77ac 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/Transport.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/Transport.lean @@ -35,7 +35,7 @@ with a `CategoryWithFibrations` instance (and similarly for cofibrations and wea equivalences), and that the three properties of morphisms (fibrations, cofibrations, weak equivalences) in `C` coincide with the inverse images by `e.functor : C ⥤ D` of the corresponding properties of morphisms in `D`. -/ -@[implicit_reducible] +@[instance_reducible] def ModelCategory.transport {C D : Type*} [Category* C] [Category* D] [ModelCategory D] [CategoryWithCofibrations C] [CategoryWithFibrations C] diff --git a/Mathlib/AlgebraicTopology/MooreComplex.lean b/Mathlib/AlgebraicTopology/MooreComplex.lean index f020476c6b2c50..d8a3344110ada6 100644 --- a/Mathlib/AlgebraicTopology/MooreComplex.lean +++ b/Mathlib/AlgebraicTopology/MooreComplex.lean @@ -120,6 +120,7 @@ def obj (X : SimplicialObject C) : ChainComplex C ℕ := variable {X} {Y : SimplicialObject C} (f : X ⟶ Y) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The normalized Moore complex functor, on morphisms. -/ @@ -140,6 +141,7 @@ end NormalizedMooreComplex open NormalizedMooreComplex +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (C) in /-- The (normalized) Moore complex of a simplicial object `X` in an abelian category `C`. @@ -155,6 +157,7 @@ def normalizedMooreComplex : SimplicialObject C ⥤ ChainComplex C ℕ where obj := obj map f := map f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- Not `@[simp]` as `simp` can prove this. theorem normalizedMooreComplex_objD (X : SimplicialObject C) (n : ℕ) : diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Augmented/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Augmented/Basic.lean index 36b6c070d9cc76..15ca70d93b0ece 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Augmented/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Augmented/Basic.lean @@ -54,6 +54,9 @@ def equivAugmentedCosimplicialObject : (AugmentedSimplexCategory ⥤ C) ≌ CosimplicialObject.Augmented C := WithInitial.equivComma +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Through the equivalence `(AugmentedSimplexCategory ⥤ C) ≌ CosimplicialObject.Augmented C`, dropping the augmentation corresponds to precomposition with `inclusion : SimplexCategory ⥤ AugmentedSimplexCategory`. -/ @@ -63,6 +66,9 @@ def equivAugmentedCosimplicialObjectFunctorCompDropIso : (Functor.whiskeringLeft _ _ C).obj inclusion := .refl _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Through the equivalence `(AugmentedSimplexCategory ⥤ C) ≌ CosimplicialObject.Augmented C`, taking the point of the augmentation corresponds to evaluation at the initial object. -/ @[simps!] @@ -81,6 +87,9 @@ def equivAugmentedCosimplicialObjectFunctorCompToArrowIso : (evaluation _ _ |>.obj <| .mk <| WithInitial.homTo <| .mk 0) := .refl _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence between functors out of `AugmentedSimplexCategory` and augmented simplicial objects. -/ @[simps!] diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 32e553ab4ed331..eef257f5abbe4e 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -176,6 +176,7 @@ def subinterval {n} (j l : ℕ) (hjl : j + l ≤ n) : monotone' := fun i i' hii' => by simpa only [Fin.mk_le_mk, add_le_add_iff_right] using! hii' } +set_option backward.isDefEq.respectTransparency.types false in lemma const_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) (i : Fin (l + 1)) : ⦋0⦌.const ⦋l⦌ i ≫ subinterval j l hjl = ⦋0⦌.const ⦋n⦌ ⟨j + i.1, lt_add_of_lt_add_right (Nat.add_lt_add_left i.2 j) hjl⟩ := by @@ -185,6 +186,7 @@ lemma const_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) (i : Fin (l + 1)) dsimp [subinterval] rw [add_comm] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mkOfSucc_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) (i : Fin l) : mkOfSucc i ≫ subinterval j l hjl = @@ -193,6 +195,7 @@ lemma mkOfSucc_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) (i : Fin l) : ext (i : Fin 2) match i with | 0 | 1 => simp; lia +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma diag_subinterval_eq {n} (j l : ℕ) (hjl : j + l ≤ n) : diag l ≫ subinterval j l hjl = intervalEdge j l hjl := by diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean b/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean index e32acc183430c2..0d4397d323b424 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean @@ -126,6 +126,7 @@ lemma σ₀Iter_coe_eq_of_lt (i : ℕ) {n m : ℕ} dsimp% (σ₀Iter i hi j).val = 0 := by simp [σ₀Iter, Hom.mk, ConcreteCategory.hom, Hom.toOrderHom, if_pos hj] +set_option backward.isDefEq.respectTransparency.types false in lemma σ₀Iter_coe_eq_of_ge (i : ℕ) {n m : ℕ} (j : Fin (m + 1)) (hi : n + i = m := by lia) (hj : i ≤ j.val := by grind) : dsimp% (σ₀Iter i hi j).val = j.val - i := by diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean index 7a80d72802d63e..2504a8f2b88e73 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean @@ -23,6 +23,7 @@ open CategoryTheory namespace SimplexCategory +set_option backward.isDefEq.respectTransparency.types false in /-- The covariant involution `rev : SimplexCategory ⥤ SimplexCategory` which, via the equivalence between the simplex category and the category of nonempty finite linearly ordered types, corresponds to @@ -74,6 +75,7 @@ lemma rev_map_rev_map {n m : SimplexCategory} (f : n ⟶ m) : rev.map (rev.map f) = f := by aesop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory` as an equivalence of category. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialNerve.lean b/Mathlib/AlgebraicTopology/SimplicialNerve.lean index e09a994f76df67..0b3ef7c8929fd3 100644 --- a/Mathlib/AlgebraicTopology/SimplicialNerve.lean +++ b/Mathlib/AlgebraicTopology/SimplicialNerve.lean @@ -116,6 +116,7 @@ def compFunctor {J : Type*} [LinearOrder J] obj x := x.1 ≫ x.2 map f := ⟨⟨⟨Set.union_subset_union f.1.1.1.1 f.2.1.1.1⟩⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local ext (iff := false)] Functor.ext in attribute [local simp] types_tensorObj_def in @@ -128,6 +129,7 @@ instance (J : Type*) [LinearOrder J] : fun _ _ _ ↦ by simp; rfl⟩ homEquiv {i j} := nerveEquiv.symm.trans (SSet.unitHomEquiv (nerve (i ⟶ j))).symm +set_option backward.isDefEq.respectTransparency.types false in attribute [local simp] SimplicialThickening.Hom_def /-- Auxiliary definition for `SimplicialThickening.functor` -/ @@ -144,6 +146,7 @@ alias orderHom := functorMap attribute [local simp] nerveMap_app +set_option backward.isDefEq.respectTransparency.types false in attribute [local simp] types_tensorObj_def in /-- The simplicial thickening defines a functor from the category of linear orders to the category of @@ -181,6 +184,7 @@ lemma functor_comp {J K L : Type u} [LinearOrder J] [LinearOrder K] end SimplicialThickening +set_option backward.isDefEq.respectTransparency.types false in /-- The simplicial nerve of a simplicial category `C` is defined as the simplicial set whose `n`-simplices are given by the set of simplicial functors from the simplicial thickening of diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean index 61aa8aa0257dbf..93b27ce11c54fe 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean @@ -331,14 +331,12 @@ noncomputable def coskAdj : truncation (C := C) n ⊣ Truncated.cosk n := ranAdjunction _ _ set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance : ((sk n).obj X).IsLeftKanExtension ((skAdj n).unit.app _) := by dsimp [sk, skAdj] rw [lanAdjunction_unit] infer_instance set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance : ((cosk n).obj X).IsRightKanExtension ((coskAdj n).counit.app _) := by dsimp [cosk, coskAdj] rw [ranAdjunction_counit] @@ -395,6 +393,7 @@ abbrev const : C ⥤ SimplicialObject C := CategoryTheory.Functor.const _ /-- The category of augmented simplicial objects, defined as a comma category. -/ +@[implicit_reducible] def Augmented := Comma (𝟭 (SimplicialObject C)) (const C) @@ -412,15 +411,18 @@ lemma hom_ext {X Y : Augmented C} (f g : X ⟶ Y) (h₁ : f.left = g.left) (h₂ Comma.hom_ext _ _ h₁ h₂ /-- Drop the augmentation. -/ -@[simps!] +@[simps!, implicit_reducible] def drop : Augmented C ⥤ SimplicialObject C := Comma.fst _ _ /-- The point of the augmentation. -/ -@[simps!] +@[simps!, implicit_reducible] def point : Augmented C ⥤ C := Comma.snd _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma w_app {X Y : Augmented C} (f : X ⟶ Y) (n : SimplexCategoryᵒᵖ) : dsimp% f.left.app n ≫ Y.hom.app n = X.hom.app n ≫ f.right := @@ -439,6 +441,9 @@ def toArrow : Augmented C ⥤ Arrow C where right := point.map η w := by simp [w_app] } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The compatibility of a morphism with the augmentation, on 0-simplices -/ @[reassoc] theorem w₀ {X Y : Augmented C} (f : X ⟶ Y) : @@ -462,6 +467,7 @@ def whiskeringObj (D : Type*) [Category* D] (F : C ⥤ D) : Augmented C ⥤ Augm right := F.map η.right w := by ext; simp [← Functor.map_comp, w_app] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functor composition induces a functor on augmented simplicial objects. -/ @[simps] @@ -510,6 +516,7 @@ def augment (X : SimplicialObject C) (X₀ : C) (f : X _⦋0⦌ ⟶ X₀) simpa only [← X.map_comp, ← Category.assoc, Category.comp_id, ← op_comp] using w _ _ _ } -- Not `@[simp]` since `simp` can prove this. +set_option backward.isDefEq.respectTransparency.types false in theorem augment_hom_zero (X : SimplicialObject C) (X₀ : C) (f : X _⦋0⦌ ⟶ X₀) (w) : (X.augment X₀ f w).hom.app (op ⦋0⦌) = f := by simp @@ -582,6 +589,7 @@ def σ {n} (i : Fin (n + 1)) : X ^⦋n + 1⦌ ⟶ X ^⦋n⦌ := def eqToIso {n m : ℕ} (h : n = m) : X ^⦋n⦌ ≅ X ^⦋m⦌ := X.mapIso (CategoryTheory.eqToIso (by rw [h])) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem eqToIso_refl {n : ℕ} (h : n = n) : X.eqToIso h = Iso.refl _ := by simp [eqToIso] @@ -793,6 +801,9 @@ def drop : Augmented C ⥤ CosimplicialObject C := def point : Augmented C ⥤ C := Comma.fst _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma w_app {X Y : Augmented C} {η : X ⟶ Y} {n : SimplexCategory} : dsimp% η.left ≫ Y.hom.app n = X.hom.app n ≫ η.right.app n := @@ -813,6 +824,7 @@ def toArrow : Augmented C ⥤ Arrow C where variable (C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functor composition induces a functor on augmented cosimplicial objects. -/ @[simp] @@ -830,6 +842,7 @@ def whiskeringObj (D : Type*) [Category* D] (F : C ⥤ D) : Augmented C ⥤ Augm rw [Category.id_comp, Category.id_comp, ← F.map_comp, ← F.map_comp] simp [w_app, map_comp] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functor composition induces a functor on augmented cosimplicial objects. -/ @[simps] @@ -878,6 +891,7 @@ def augment (X : CosimplicialObject C) (X₀ : C) (f : X₀ ⟶ X.obj ⦋0⦌) rw [Category.id_comp, Category.assoc, ← X.map_comp, w] } -- Not `@[simp]` since `simp` can prove this. +set_option backward.isDefEq.respectTransparency.types false in theorem augment_hom_zero (X : CosimplicialObject C) (X₀ : C) (f : X₀ ⟶ X.obj ⦋0⦌) (w) : (X.augment X₀ f w).hom.app ⦋0⦌ = f := by simp @@ -923,6 +937,7 @@ def CosimplicialObject.Augmented.leftOp (X : CosimplicialObject.Augmented Cᵒ right := X.left.unop hom := NatTrans.leftOp X.hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Converting an augmented simplicial object to an augmented cosimplicial object and back is isomorphic to the given object. -/ @@ -931,6 +946,7 @@ def SimplicialObject.Augmented.rightOpLeftOpIso (X : SimplicialObject.Augmented X.rightOp.leftOp ≅ X := Comma.isoMk X.left.rightOpLeftOpIso (CategoryTheory.eqToIso <| by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Converting an augmented cosimplicial object to an augmented simplicial object and back is isomorphic to the given object. -/ @@ -941,6 +957,7 @@ def CosimplicialObject.Augmented.leftOpRightOpIso (X : CosimplicialObject.Augmen variable (C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functorial version of `SimplicialObject.Augmented.rightOp`. -/ @[simps] @@ -957,6 +974,7 @@ def simplicialToCosimplicialAugmented : congr 1 exact (congr_app f.unop.w (op x)).symm } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functorial version of `Cosimplicial_object.Augmented.leftOp`. -/ @[simps] @@ -974,6 +992,7 @@ def cosimplicialToSimplicialAugmented : congr 1 exact (congr_app f.w (unop x)).symm } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The contravariant categorical equivalence between augmented simplicial objects and augmented cosimplicial objects in the opposite category. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Coskeletal.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Coskeletal.lean index 4ffcae6cd95442..8d1b785fcd2c07 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Coskeletal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Coskeletal.lean @@ -82,7 +82,6 @@ instance [X.IsCoskeletal n] : IsIso ((coskAdj n).unit.app X) := by rw [← isCoskeletal_iff_isIso] infer_instance -set_option backward.isDefEq.respectTransparency false in /-- The canonical isomorphism `X ≅ (cosk n).obj X` defined when `X` is coskeletal and the `n`-coskeleton functor exists. -/ @[simps! hom] diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/DeltaZeroIter.lean b/Mathlib/AlgebraicTopology/SimplicialObject/DeltaZeroIter.lean index 2ab142cda6f1ae..6ca1ad01718f6d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/DeltaZeroIter.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/DeltaZeroIter.lean @@ -153,13 +153,15 @@ set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma δ₀Iter_hom_app {n m : ℕ} (i : ℕ) (hi : n + i = m := by lia) : dsimp% Y.left.δ₀Iter i hi ≫ Y.hom.app (op ⦋n⦌) = Y.hom.app (op ⦋m⦌) := by - simpa using! Y.hom.naturality (SimplexCategory.δ₀Iter i hi).op + simpa only [Functor.id_obj, Functor.const_obj_obj, Functor.const_obj_map, Category.comp_id] using! + Y.hom.naturality (SimplexCategory.δ₀Iter i hi).op set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma σ₀Iter_hom_app {n m : ℕ} (i : ℕ) (hi : n + i = m := by lia) : dsimp% Y.left.σ₀Iter i hi ≫ Y.hom.app (op ⦋m⦌) = Y.hom.app (op ⦋n⦌) := by - simpa using! Y.hom.naturality (SimplexCategory.σ₀Iter i hi).op + simpa only [Functor.id_obj, Functor.const_obj_obj, Functor.const_obj_map, Category.comp_id] using! + Y.hom.naturality (SimplexCategory.σ₀Iter i hi).op end Augmented diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean index a773994633dab2..338e1a8be37c03 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean @@ -70,12 +70,14 @@ def opFunctorCompOpFunctorIso : opFunctor (C := C) ⋙ opFunctor ≅ 𝟭 _ := ((Functor.opHom _ _).mapIso (SimplexCategory.revCompRevIso).symm.op) ≪≫ Functor.whiskeringLeftObjIdIso +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctorCompOpFunctorIso_hom_app_app (X : SimplicialObject C) (n : SimplexCategoryᵒᵖ) : (opFunctorCompOpFunctorIso.hom.app X).app n = opObjIso.hom ≫ opObjIso.hom := by simp [opFunctorCompOpFunctorIso, opObjIso, opFunctor] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctorCompOpFunctorIso_inv_app_app (X : SimplicialObject C) (n : SimplexCategoryᵒᵖ) : diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean index ec40d99b4bf5e3..bcb3f887424779 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean @@ -74,6 +74,7 @@ instance : Epi A.e := theorem ext' : A = ⟨A.1, ⟨A.e, A.2.2⟩⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem ext (A₁ A₂ : IndexSet Δ) (h₁ : A₁.1 = A₂.1) (h₂ : A₁.e ≫ eqToHom (by rw [h₁]) = A₂.e) : A₁ = A₂ := by rcases A₁ with ⟨Δ₁, ⟨α₁, hα₁⟩⟩ @@ -179,6 +180,9 @@ of `θ.unop ≫ A.e`. -/ def pull : IndexSet Δ' := mk (factorThruImage (θ.unop ≫ A.e)) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] theorem fac_pull : (A.pull θ).e ≫ image.ι (θ.unop ≫ A.e) = θ.unop ≫ A.e := image.fac _ @@ -221,6 +225,7 @@ namespace Splitting variable {X Y : SimplicialObject C} (s : Splitting X) /-- The cofan for `summand s.N Δ` induced by a splitting of a simplicial object. -/ +@[implicit_reducible] def cofan (Δ : SimplexCategoryᵒᵖ) : Cofan (summand s.N Δ) := Cofan.mk (X.obj Δ) (fun A => s.ι A.1.unop.len ≫ X.map A.e.op) @@ -231,6 +236,7 @@ def isColimit (Δ : SimplexCategoryᵒᵖ) : IsColimit (s.cofan Δ) := s.isColim theorem cofan_inj_eq {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) : (s.cofan Δ).inj A = s.ι A.1.unop.len ≫ X.map A.e.op := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem cofan_inj_id (n : ℕ) : (s.cofan _).inj (IndexSet.id (op ⦋n⦌)) = s.ι n := by simp [IndexSet.id, IndexSet.e, cofan_inj_eq] @@ -272,6 +278,7 @@ theorem ι_desc {Z : C} (Δ : SimplexCategoryᵒᵖ) (F : ∀ A : IndexSet Δ, s (A : IndexSet Δ) : (s.cofan Δ).inj A ≫ s.desc Δ F = F A := by apply Cofan.IsColimit.fac +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A simplicial object that is isomorphic to a split simplicial object is split. -/ @[simps] @@ -281,6 +288,7 @@ def ofIso (e : X ≅ Y) : Splitting Y where isColimit' Δ := IsColimit.ofIsoColimit (s.isColimit Δ) (Cofan.ext (e.app Δ) (fun A => by simp [cofan, cofan'])) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem cofan_inj_epi_naturality {Δ₁ Δ₂ : SimplexCategoryᵒᵖ} (A : IndexSet Δ₁) (p : Δ₁ ⟶ Δ₂) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean index b97a31e1cea2e8..d243a920ba8759 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean @@ -104,6 +104,7 @@ lemma unique (f : ⦋d⦌ ⟶ ⦋d + 1⦌) [Mono f] end +set_option backward.isDefEq.respectTransparency.types false in include hxy in lemma op : (S.opEquiv.symm x).IsUniquelyCodimOneFace (S.opEquiv.symm y) := by obtain ⟨d, x, rfl⟩ := x.mk_surjective diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Op.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Op.lean index 724526cc37f81d..d1ba23806c652e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Op.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Op.lean @@ -41,6 +41,7 @@ lemma op_p (x : P.II) : dsimp% P.op.p ⟨Subcomplex.N.opEquiv.symm x.1, x.2⟩ = ⟨Subcomplex.N.opEquiv.symm (P.p x), by simp⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma op_ancestralRel_iff (x y : P.II) : P.op.AncestralRel ⟨Subcomplex.N.opEquiv.symm x.1, x.2⟩ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean index 15671c74117544..e0ec27cc094f6d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -175,6 +175,7 @@ lemma ofIso_p (x : P.II) : change e'.symm (P.p ⟨e' (e'.symm x), _⟩) = e'.symm (P.p x) simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma ofIso_ancestralRel_iff (x y : P.II) : (P.ofIso e hA).AncestralRel @@ -201,6 +202,7 @@ instance [P.IsRegular] : (P.ofIso e hA).IsRegular where refine hP.false ⟨fun n ↦ ⟨_, (f n).2⟩, fun n ↦ ?_⟩ simpa [← P.ofIso_ancestralRel_iff e hA] using hf n +set_option backward.isDefEq.respectTransparency false in @[simp] lemma ofIso_index (x : P.II) {d : ℕ} (hd : x.1.dim = d) [P.IsProper] : ((P.ofIso e hA).isUniquelyCodimOneFace ⟨(N.orderIsoOfIso e hA).symm x, by simp⟩).index hd = diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean index da4a742a4ae441..e6ddb50e19d83d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean @@ -248,6 +248,7 @@ is regular. -/ class IsRegular (h : A.PairingCore) extends h.IsProper where wf (h) : WellFounded h.AncestralRel +set_option backward.isDefEq.respectTransparency.types false in instance [h.IsRegular] : h.pairing.IsRegular where wf := by have := IsRegular.wf h diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean index 28299b8bd37ccd..a2b0af5074e5d8 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean @@ -81,6 +81,7 @@ variable {P α} [WellFoundedLT α] [P.IsProper] (f : P.WeakRankFunction α) include f +set_option backward.isDefEq.respectTransparency.types false in lemma wf_ancestralRel : WellFounded P.AncestralRel := by rw [wellFounded_iff_isEmpty_descending_chain] refine ⟨fun ⟨g, hg⟩ ↦ ?_⟩ @@ -128,6 +129,7 @@ structure WeakRankFunction where rank : h.ι → α lt {x y : h.ι} : h.AncestralRel x y → h.dim x = h.dim y → rank x < rank y +set_option backward.isDefEq.respectTransparency.types false in /-- Rank functions for `h : A.PairingCore` correspond to rank functions for `h.pairing : A.Pairing`. -/ noncomputable def rankFunctionEquiv : @@ -147,6 +149,7 @@ noncomputable def rankFunctionEquiv : left_inv _ := by simp right_inv _ := by simp +set_option backward.isDefEq.respectTransparency.types false in /-- Weak rank functions for `h : A.PairingCore` correspond to weak rank functions for `h.pairing : A.Pairing`. -/ noncomputable def weakRankFunctionEquiv : diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index fb29355165b900..631b2617f66bcb 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -79,6 +79,7 @@ abbrev map : Δ[c.dim + 1] ⟶ X := yonedaEquiv.symm ((P.p c.s).val.cast (P.isUniquelyCodimOneFace c.s).dim_eq).simplex +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma range_map : Subcomplex.range c.map = (P.p c.s).val.subcomplex := by @@ -91,6 +92,7 @@ lemma map_app_objEquiv_symm_δ_index : c.s.val.simplex := (P.isUniquelyCodimOneFace c.s).δ_index rfl +set_option backward.isDefEq.respectTransparency.types false in lemma subcomplex_not_le_image_horn : ¬ c.s.val.subcomplex ≤ c.horn.image c.map := by intro h simp only [Subfunctor.ofSection_le_iff, image_obj, Set.mem_image] at h @@ -379,7 +381,7 @@ noncomputable def t (j : ι) : f.sigmaHorn j ⟶ f.filtration j := variable {f} in @[reassoc (attr := simp)] lemma Cell.ι_t {j : ι} (c : f.Cell j) : c.ιSigmaHorn ≫ f.t j = c.mapHorn := by - simp [t, Sigma.ι_desc] + simp [t] variable {f} in @[reassoc (attr := simp), elementwise (attr := simp)] @@ -387,6 +389,7 @@ lemma Cell.ι_t_app {j : ι} (c : f.Cell j) (x : SimplexCategoryᵒᵖ) : c.ιSigmaHorn.app x ≫ (f.t j).app x = c.mapHorn.app x := NatTrans.congr_app c.ι_t x +set_option backward.isDefEq.respectTransparency.types false in /-- Given a rank `j` cell `c` for a rank function `f` for a proper pairing of a subcomplex of a simplicial set, this is the nondegenerate simplex in `f.sigmaStdSimplex j` @@ -406,6 +409,7 @@ noncomputable def Cell.type₁ {j : ι} (c : f.Cell j) : (Subcomplex.range (f.m obtain ⟨rfl, rfl⟩ := hy exact objEquiv_symm_notMem_horn_of_isIso _ _ hy' +set_option backward.isDefEq.respectTransparency.types false in /-- Given a rank `j` cell `c` for a rank function `f` for a proper pairing of a subcomplex of a simplicial set, this is the nondegenerate simplex in `f.sigmaStdSimplex j` @@ -457,7 +461,7 @@ noncomputable def b (j : ι) : f.sigmaStdSimplex j ⟶ f.filtration (Order.succ variable {f} in @[reassoc (attr := simp)] lemma Cell.ι_b {j : ι} (c : f.Cell j) : c.ιSigmaStdSimplex ≫ f.b j = c.mapToSucc := by - simp [b, Sigma.ι_desc] + simp [b] variable {f} in @[reassoc (attr := simp), elementwise (attr := simp)] @@ -521,6 +525,7 @@ corresponding to an element in `(Subcomplex.range (f.m j)).N`. -/ noncomputable def mapN {j : ι} (x : (Subcomplex.range (f.m j)).N) : X.S := S.mk ((f.b j).app _ x.simplex).val +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapN_type₁ {j : ι} (c : f.Cell j) : f.mapN c.type₁ = S.mk (P.p c.s).val.simplex := by dsimp only [Cell.type₁, mapN] diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean index bc80e1fabc6544..b394809fc33e3d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean @@ -65,10 +65,16 @@ namespace prodStdSimplex variable {m : ℕ} {k : Fin (m + 1)} {n : ℕ} (x : (Subcomplex.unionProd.{u} Λ[m + 1, k.castSucc] ∂Δ[n]).N) {d : ℕ} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma objEquiv_apply_fst' (hd : x.dim = d) (i : Fin (d + 1)) : dsimp% ((objEquiv (x.cast hd).simplex) i).1 = (x.cast hd).simplex.1 i := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma objEquiv_apply_snd' (hd : x.dim = d) (i : Fin (d + 1)) : dsimp% ((objEquiv (x.cast hd).simplex) i).2 = (x.cast hd).simplex.2 i := rfl @@ -138,6 +144,7 @@ does not belong to `Λ[m + 1, k.castSucc].unionProd ∂Δ[n]`. This is the smallest `l : Fin (d + 1)` such that `x l` is of the form `(k.succ, _)`. -/ noncomputable def min : Fin (d + 1) := (finset x hd).min' (nonempty_finset x hd) +set_option backward.isDefEq.respectTransparency.types false in lemma simplex_fst_min : dsimp% (x.cast hd).simplex.1 (min x hd) = k.succ := by rw [← mem_finset_iff] apply Finset.min'_mem @@ -210,6 +217,7 @@ variable {x} {hd : x.dim = d + 1} {l : Fin (d + 1)} (hl : IsIndex x hd l.succ) include hl +set_option backward.isDefEq.respectTransparency.types false in /-- The type (II) simplex obtained as a face of a type (I) simplex. -/ @[simps -isSimp] noncomputable abbrev δ : @@ -327,6 +335,7 @@ lemma φ_of_gt (i : Fin (d + 2)) (hi : (min x hd).castSucc < i) : φ x hd i = objEquiv (x.cast hd).simplex (i.pred (by aesop)) := by rw [φ_of_ne _ _ _ hi.ne', Fin.predAbove_of_castSucc_lt _ _ hi] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma φ_succ_snd : (φ x hd (min x hd).succ).2 = (φ x hd (min x hd).castSucc).2 := by @@ -408,6 +417,7 @@ lemma notMem_simplex : exact (Subcomplex.unionProd.{u} Λ[m + 1, k.castSucc] ∂Δ[n]).map (SimplexCategory.δ (min x hd).castSucc).op h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The type (I) simplex reconstructed from a type (II) simplex. -/ @[simps] @@ -428,6 +438,7 @@ variable {hd : x.dim = d + 1} {l : Fin (d + 1)} (hl : IsIndex x hd l.succ) include hl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma min_δ : min (d := d) hl.δ rfl = l := by refine le_antisymm (Finset.min'_le _ _ ?_) @@ -442,6 +453,7 @@ lemma min_δ : min (d := d) hl.δ rfl = l := by rw [Fin.succAbove_of_castSucc_lt _ _ (by grind)] at hy grind [(hl.succ_le_simplex_fst_iff y.castSucc).1 hy.symm.le] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isType₂_δ : IsType₂ hl.δ := by intro _ rfl t ht @@ -454,6 +466,7 @@ lemma isType₂_δ : IsType₂ hl.δ := by dsimp [stdSimplex.δ_apply] at hl ht ⊢ aesop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {x} in lemma eq_of_isType₂_δ {u : (Subcomplex.unionProd.{u} Λ[m + 1, k.castSucc] ∂Δ[n]).N} @@ -482,6 +495,7 @@ lemma eq_of_isType₂_δ {u : (Subcomplex.unionProd.{u} Λ[m + 1, k.castSucc] end IsIndex +set_option backward.isDefEq.respectTransparency.types false in lemma IsType₂.type₁_eq_of_δ_eq {t : (Subcomplex.unionProd.{u} Λ[m + 1, k.castSucc] ∂Δ[n]).N} (ht : IsType₂ t) (s : Type₁.{u} k n) (hst : s.δ = t) {d : ℕ} (hd : t.dim = d) : @@ -581,6 +595,7 @@ lemma type₁_pairingCore {m : ℕ} (k : Fin (m + 1)) {n : ℕ} (pairingCore k n).type₁ s = s.x := Subcomplex.N.cast_eq_self _ s.hd +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A weak rank function for `pairingCore k n`. -/ noncomputable def weakRankFunction {m : ℕ} (k : Fin (m + 1)) (n : ℕ) : @@ -676,6 +691,7 @@ lemma pairing_castSucc {m : ℕ} (k : Fin (m + 1)) (n : ℕ) : pairing.{u} k.castSucc n = (pairingCore.{u} k n).pairing := dif_neg (by grind) +set_option backward.isDefEq.respectTransparency.types false in instance {m : ℕ} (k : Fin (m + 2)) (n : ℕ) : (pairing.{u} k n).IsRegular := by by_cases! hk : k = Fin.last (m + 1) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean b/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean index 506e6a780ce410..fbd4a6e3f73cbc 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean @@ -81,6 +81,7 @@ protected def rec : ∀ a, motive a end induction +set_option backward.isDefEq.respectTransparency false in /-- From an isomorphism in a category, we can build a functor out of `WalkingIso` to that category. -/ def fromIso {X Y : C} (e : X ≅ Y) : WalkingIso.{w} ⥤ C where @@ -113,6 +114,7 @@ lemma fromIso_map_one_one (f : one ⟶ one) : (fromIso.{w} e).map f = 𝟙 Y := end +set_option backward.isDefEq.respectTransparency false in /-- An equivalence between the type of `WalkingIso`s in `C` and the type of isomorphisms in `C`. -/ @[simps] def equiv : (WalkingIso.{w} ⥤ C) ≃ Σ (X : C) (Y : C), (X ≅ Y) where diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Coskeletal.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Coskeletal.lean index c348e34404fd67..c4f373a953e81e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Coskeletal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Coskeletal.lean @@ -84,6 +84,7 @@ noncomputable def lift {X : SSet.{u}} (sx : StrictSegal X) {n} (Quiver.Hom.unop_inj (by ext x; fin_cases x; rfl)) exact ConcreteCategory.congr_hom (s.w φ) x } +set_option backward.isDefEq.respectTransparency.types false in lemma fac_aux₁ {n : ℕ} (s : Cone (proj (op ⦋n⦌) (Truncated.inclusion 2).op ⋙ (Truncated.inclusion 2).op ⋙ X)) (x : s.pt) (i : ℕ) (hi : i < n) : @@ -178,6 +179,7 @@ end isPointwiseRightKanExtensionAt open Truncated +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open isPointwiseRightKanExtensionAt in /-- A strict Segal simplicial set is 2-coskeletal. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/FiniteProd.lean b/Mathlib/AlgebraicTopology/SimplicialSet/FiniteProd.lean index e536c0c9497b10..6f4a1f0fa0d3ca 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/FiniteProd.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/FiniteProd.lean @@ -27,6 +27,7 @@ namespace SSet variable {X₁ X₂ X₃ X₄ : SSet.{u}} +set_option backward.isDefEq.respectTransparency.types false in variable (X₁ X₂) in lemma iSup_subcomplexOfSimplex_prod_eq_top : ⨆ (x₁ : X₁.N) (x₂ : X₂.N), diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/HoFunctorMonoidal.lean b/Mathlib/AlgebraicTopology/SimplicialSet/HoFunctorMonoidal.lean index c4bb0adfc057e5..54f7d1cf19b280 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/HoFunctorMonoidal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/HoFunctorMonoidal.lean @@ -139,6 +139,7 @@ lemma functor_map {x₀ x₁ : X _⦋0⦌₂} (e : Edge x₀ x₁) {y₀ y₁ : Y _⦋0⦌₂} (e' : Edge y₀ y₁) : (functor X Y).map (homMk (e.tensor e')) = (homMk e, homMk e') := rfl +set_option backward.isDefEq.respectTransparency.types false in variable (X Y) in /-- The functor `X.HomotopyCategory ⥤ Y.HomotopyCategory ⥤ (X ⊗ Y).HomotopyCategory` when `X` and `Y` are `2`-truncated simplicial sets. -/ @@ -152,28 +153,34 @@ def curriedInverse : X.HomotopyCategory ⥤ Y.HomotopyCategory ⥤ (X ⊗ Y).Hom obtain ⟨y, rfl⟩ := mk_surjective y simpa using homMk_comp_homMk (h.tensor (.idCompId y))) +set_option backward.isDefEq.respectTransparency.types false in variable (X Y) in /-- The functor `X.HomotopyCategory × Y.HomotopyCategory ⥤ (X ⊗ Y).HomotopyCategory` when `X` and `Y` are `2`-truncated simplicial sets. -/ def inverse : X.HomotopyCategory × Y.HomotopyCategory ⥤ (X ⊗ Y).HomotopyCategory := Functor.uncurry.obj (curriedInverse X Y) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inverse_obj (x : X _⦋0⦌₂) (y : Y _⦋0⦌₂) : (inverse X Y).obj (mk x, mk y) = mk (x, y) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inverse_map_mkHom_homMk_id {x₀ x₁ : X _⦋0⦌₂} (e : Edge x₀ x₁) (y : Y _⦋0⦌₂) : (inverse X Y).map (Prod.mkHom (homMk e) (𝟙 (mk y))) = homMk (e.tensor (.id y)) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inverse_map_mkHom_id_homMk (x : X _⦋0⦌₂) {y₀ y₁ : Y _⦋0⦌₂} (e : Edge y₀ y₁) : (inverse X Y).map (Prod.mkHom (𝟙 (mk x)) (homMk e)) = homMk ((Edge.id x).tensor e) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma inverse_map_mkHom_homMk_homMk {x₀ x₁ : X _⦋0⦌₂} (e : Edge x₀ x₁) {y₀ y₁ : Y _⦋0⦌₂} (e' : Edge y₀ y₁) : (inverse X Y).map (Prod.mkHom (homMk e) (homMk e')) = homMk (e.tensor e') := homMk_comp_homMk ((Edge.CompStruct.compId e).tensor (Edge.CompStruct.idComp e')) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (X Y) in /-- Auxiliary definition for `equivalence`. -/ @@ -184,14 +191,17 @@ def functorCompInverseIso : functor X Y ⋙ inverse X Y ≅ 𝟭 _ := dsimp rw [Category.comp_id, Category.id_comp, inverse_map_mkHom_homMk_homMk]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma functorCompInverseIso_hom_app (x : X _⦋0⦌₂) (y : Y _⦋0⦌₂) : (functorCompInverseIso X Y).hom.app (mk (x, y)) = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma functorCompInverseIso_inv_app (x : X _⦋0⦌₂) (y : Y _⦋0⦌₂) : (functorCompInverseIso X Y).inv.app (mk (x, y)) = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in variable (X Y) in /-- Auxiliary definition for `equivalence`. -/ def inverseCompFunctorIso : inverse X Y ⋙ functor X Y ≅ 𝟭 _ := @@ -202,22 +212,27 @@ def inverseCompFunctorIso : inverse X Y ⋙ functor X Y ≅ 𝟭 _ := obtain ⟨y, rfl⟩ := y.mk_surjective cat_disch)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inverseCompFunctorIso_hom_app (x : X _⦋0⦌₂) (y : Y _⦋0⦌₂) : (inverseCompFunctorIso X Y).hom.app (mk x, mk y) = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inverseCompFunctorIso_inv_app (x : X _⦋0⦌₂) (y : Y _⦋0⦌₂) : (inverseCompFunctorIso X Y).inv.app (mk x, mk y) = 𝟙 _ := rfl variable (X Y) +set_option backward.isDefEq.respectTransparency.types false in lemma functor_comp_inverse : functor X Y ⋙ inverse X Y = 𝟭 _ := Functor.ext_of_iso (functorCompInverseIso X Y) (fun _ ↦ rfl) +set_option backward.isDefEq.respectTransparency.types false in lemma inverse_comp_functor : inverse X Y ⋙ functor X Y = 𝟭 _ := Functor.ext_of_iso (inverseCompFunctorIso X Y) (fun _ ↦ rfl) +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence `(X ⊗ Y).HomotopyCategory ≌ X.HomotopyCategory ⥤ Y.HomotopyCategory` when `X` and `Y` are `2`-truncated simplicial sets. -/ def equivalence : @@ -227,6 +242,7 @@ def equivalence : unitIso := (functorCompInverseIso X Y).symm counitIso := inverseCompFunctorIso X Y +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism of categories between `(X ⊗ Y).HomotopyCategory` and `X.HomotopyCategory ⥤ Y.HomotopyCategory`. -/ @[simps] @@ -237,6 +253,7 @@ def iso : hom_inv_id := by ext; exact functor_comp_inverse X Y inv_hom_id := by ext; exact inverse_comp_functor X Y +set_option backward.isDefEq.respectTransparency.types false in variable {X} in /-- The naturality of `HomotopyCategory.BinaryProduct.inverse` with respect to the first variable. -/ @@ -250,6 +267,7 @@ def mapHomotopyCategoryProdIdCompInverseIso (f : X ⟶ X') : simp rfl)) +set_option backward.isDefEq.respectTransparency.types false in variable {Y} in /-- The naturality of `HomotopyCategory.BinaryProduct.inverse` with respect to the second variable. -/ @@ -263,12 +281,14 @@ def idProdMapHomotopyCategoryCompInverseIso (g : Y ⟶ Y') : simp rfl)) +set_option backward.isDefEq.respectTransparency.types false in variable {X} in lemma mapHomotopyCategory_prod_id_comp_inverse (f : X ⟶ X') : (mapHomotopyCategory f).prod (𝟭 _) ⋙ inverse X' Y = inverse X Y ⋙ mapHomotopyCategory (f ▷ Y) := Functor.ext_of_iso (mapHomotopyCategoryProdIdCompInverseIso _ _) (fun _ ↦ rfl) +set_option backward.isDefEq.respectTransparency.types false in variable {Y} in lemma id_prod_mapHomotopyCategory_comp_inverse (g : Y ⟶ Y') : Functor.prod (𝟭 _) (mapHomotopyCategory g) ⋙ inverse X Y' = @@ -290,6 +310,7 @@ def inverseCompMapHomotopyCategoryFstIso : obtain ⟨y, rfl⟩ := y.mk_surjective simp)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The compatibility of `HomotopyCategory.BinaryProduct.inverse` with respect to the second projection. -/ @@ -303,10 +324,12 @@ def inverseCompMapHomotopyCategorySndIso : simp only [Category.comp_id] exact homMk_id y)) +set_option backward.isDefEq.respectTransparency.types false in lemma inverse_comp_mapHomotopyCategory_fst : inverse X Y ⋙ mapHomotopyCategory (fst _ _) = CategoryTheory.Prod.fst _ _ := Functor.ext_of_iso (inverseCompMapHomotopyCategoryFstIso _ _) (fun _ ↦ rfl) +set_option backward.isDefEq.respectTransparency.types false in lemma inverse_comp_mapHomotopyCategory_snd : inverse X Y ⋙ mapHomotopyCategory (snd _ _) = CategoryTheory.Prod.snd _ _ := Functor.ext_of_iso (inverseCompMapHomotopyCategorySndIso _ _) (fun _ ↦ rfl) @@ -356,6 +379,7 @@ def associativity'Iso : simp only [Category.comp_id, Category.id_comp, ← prod_id', CategoryTheory.Functor.map_id, inverse_obj, inverse_map_mkHom_homMk_id])) +set_option backward.isDefEq.respectTransparency.types false in variable {X Y Z} in lemma associativity'Iso_hom_app (xyz) : (associativity'Iso X Y Z).hom.app xyz = 𝟙 _ := by @@ -363,6 +387,7 @@ lemma associativity'Iso_hom_app (xyz) : rw [Category.id_comp, Category.comp_id] rfl +set_option backward.isDefEq.respectTransparency.types false in open Functor in /-- The compatibility of `HomotopyCategory.BinaryProduct.inverse` with respect to associators. -/ @@ -386,6 +411,7 @@ lemma associativityIso_hom_app (xyz) : Category.comp_id, ← prod_id, CategoryTheory.Functor.map_id, CategoryTheory.Functor.map_id] +set_option backward.isDefEq.respectTransparency.types false in lemma associativity : (inverse X Y).prod (𝟭 _) ⋙ inverse (X ⊗ Y) Z ⋙ mapHomotopyCategory (α_ _ _ _).hom = (prod.associativity _ _ _).functor ⋙ Functor.prod (𝟭 _) (inverse Y Z) ⋙ @@ -396,6 +422,7 @@ end BinaryProduct end HomotopyCategory +set_option backward.isDefEq.respectTransparency.types false in open HomotopyCategory.BinaryProduct in instance : hoFunctor₂.{u}.Monoidal := Functor.CoreMonoidal.toMonoidal @@ -407,6 +434,7 @@ instance : hoFunctor₂.{u}.Monoidal := right_unitality X := by ext; apply right_unitality associativity _ _ _ := by ext; apply associativity } +set_option backward.isDefEq.respectTransparency.types false in /-- The homotopy category functor `hoFunctor : SSet.{u} ⥤ Cat.{u, u}` is (cartesian) monoidal. -/ instance hoFunctor.monoidal : hoFunctor.{u}.Monoidal := inferInstanceAs (truncation 2 ⋙ hoFunctor₂).Monoidal @@ -420,6 +448,7 @@ def hoFunctor.unitHomEquiv (X : SSet.{u}) : (SSet.unitHomEquiv X).trans <| (hoFunctor.obj.equiv.{u} X).symm.trans Cat.fromChosenTerminalEquiv.symm +set_option backward.isDefEq.respectTransparency.types false in theorem hoFunctor.unitHomEquiv_eq (X : SSet.{u}) (x : 𝟙_ SSet ⟶ X) : hoFunctor.unitHomEquiv X x = (Functor.LaxMonoidal.ε hoFunctor.{u}).toFunctor ⋙ (hoFunctor.map x).toFunctor := diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Basic.lean index 281e2ca237fd8f..a4cd4c1af907e0 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Basic.lean @@ -37,6 +37,7 @@ It computes the simplicial homology of a simplicial sets with coefficients in `R`. One can recover the ordinary simplicial chain complex when `C := Ab` and `X := ℤ`. -/ +@[implicit_reducible] noncomputable def chainComplexFunctor : C ⥤ SSet.{w} ⥤ ChainComplex C ℕ := (Functor.postcompose₂.obj (AlgebraicTopology.alternatingFaceMapComplex _)).obj (sigmaConst ⋙ SimplicialObject.whiskering _ _) @@ -100,7 +101,7 @@ lemma ι_chainComplexMap_f {n : ℕ} (x : X _⦋n⦌) : Y.ιChainComplex (f.app _ x) := by dsimp [chainComplexMap, chainComplexFunctor, ιChainComplex, Sigma.map', chainComplex, chainComplexFunctor] - simp [Sigma.ι_desc] + simp /-- The colimit cofan which defines the simplicial `n`-chains `(X.chainComplex R).X n`. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Nondegenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Nondegenerate.lean index 73defd1e949bc6..7ea7c52e504668 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Nondegenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Homology/Nondegenerate.lean @@ -118,13 +118,15 @@ lemma ιNormalizedChainComplex_d {n : ℕ} (x : X _⦋n + 1⦌) : simp [ιNormalizedChainComplex, Preadditive.sum_comp, -ιChainComplex_toNormalizedChainComplex_f] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma ιNormalizedChainComplex_fromNormalizedChainComplex_f (x : X _⦋n⦌) : X.ιNormalizedChainComplex x ≫ (X.fromNormalizedChainComplex R).f n = X.ιChainComplex x ≫ (PInfty).f n := by dsimp [ιNormalizedChainComplex] rw [Category.assoc, toNormalizedChainComplex_f_fromNormalizedChainComplex_f] - rfl set_option backward.isDefEq.respectTransparency false in lemma ιNormalizedChainComplex_eq_zero (x : X _⦋n⦌) (hx : x ∈ X.degenerate n) : diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean index 06e3c23bef6591..03f7788618fba1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/HomotopyCat.lean @@ -64,6 +64,7 @@ lemma hom_ext (h : f.edge = g.edge) : f = g := Truncated.Edge.ext h +set_option backward.isDefEq.respectTransparency.types false in /-- The prefunctor on refl quivers `OneTruncation₂` induced by a morphism of `2`-truncated simplicial sets. -/ @[simps] @@ -122,6 +123,7 @@ def ofNerve₂ (C : Type u) [Category.{u} C] : ReflQuiv.isoOfEquiv.{u, u} OneTruncation₂.nerveEquiv (fun _ _ ↦ OneTruncation₂.nerveHomEquiv) nerveHomEquiv_id +set_option backward.isDefEq.respectTransparency.types false in lemma nerve_hom_ext {X : (SSet.Truncated 2)} {C : Type u} [Category.{u} C] {F G : X ⟶ ((truncation 2).obj (nerve C))} (h : OneTruncation₂.map F = OneTruncation₂.map G) : F = G := @@ -287,6 +289,7 @@ lemma congr_arrowMk_homMk {x₀ x₁ : V _⦋0⦌₂} (e : Edge x₀ x₁) obtain rfl : e = e' := by aesop rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma homMk_id (x : V _⦋0⦌₂) : homMk (.id x) = 𝟙 (mk x) := by @@ -357,6 +360,7 @@ variable (obj : V _⦋0⦌₂ → D) (map : ∀ {x y : V _⦋0⦌₂}, Edge x y {e₀₁ : Edge x₀ x₁} {e₁₂ : Edge x₁ x₂} {e₀₂ : Edge x₀ x₂} (_ : Edge.CompStruct e₀₁ e₁₂ e₀₂), map e₀₁ ≫ map e₁₂ = map e₀₂) +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for functors from the homotopy category. -/ def lift : V.HomotopyCategory ⥤ D := CategoryTheory.Quotient.lift _ @@ -365,9 +369,11 @@ def lift : V.HomotopyCategory ⥤ D := simp only [Functor.map_comp] convert! map_comp h <;> apply Cat.FreeRefl.lift'_map) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_obj_mk (x : V _⦋0⦌₂) : (lift obj map map_id map_comp).obj (mk x) = obj x := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_map_homMk {x y : V _⦋0⦌₂} (e : Edge x y) : (lift obj map map_id map_comp).map (homMk e) = map e := @@ -383,6 +389,7 @@ variable (φ : ∀ (x : V _⦋0⦌₂), F.obj (mk x) ⟶ G.obj (mk x)) (hφ : ∀ ⦃x y : V _⦋0⦌₂⦄ (e : Edge x y), F.map (homMk e) ≫ φ y = φ x ≫ G.map (homMk e) := by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- Constructor for natural transformations between functors from `V.HomotopyCategory`. -/ def mkNatTrans : F ⟶ G where @@ -392,6 +399,7 @@ def mkNatTrans : F ⟶ G where morphismProperty_eq_top (fun e ↦ hφ e) exact this.symm.le f (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in @[simp] lemma mkNatTrans_app_mk (v : V _⦋0⦌₂) : @@ -405,16 +413,19 @@ variable (iso : ∀ (x : V _⦋0⦌₂), F.obj (mk x) ≅ G.obj (mk x)) (hiso : ∀ ⦃x y : V _⦋0⦌₂⦄ (e : Edge x y), F.map (homMk e) ≫ (iso y).hom = (iso x).hom ≫ G.map (homMk e) := by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- Constructor for natural isomorphisms between functors from `V.HomotopyCategory`. -/ def mkNatIso : F ≅ G := NatIso.ofComponents (fun _ ↦ iso _) (fun f ↦ (mkNatTrans _ hiso).naturality f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in @[simp] lemma mkNatIso_hom_app_mk (v : V _⦋0⦌₂) : (mkNatIso iso hiso).hom.app (mk v) = (iso v).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in @[simp] lemma mkNatIso_inv_app_mk (v : V _⦋0⦌₂) : @@ -422,6 +433,7 @@ lemma mkNatIso_inv_app_mk (v : V _⦋0⦌₂) : end +set_option backward.isDefEq.respectTransparency.types false in lemma functor_ext {F G : V.HomotopyCategory ⥤ D} (h₁ : ∀ (x : V _⦋0⦌₂), F.obj (mk x) = G.obj (mk x)) (h₂ : ∀ ⦃x y : V _⦋0⦌₂⦄ (e : Edge x y), @@ -440,6 +452,7 @@ instance (X : Truncated.{u} 2) [Subsingleton (X _⦋0⦌₂)] : obtain rfl := Subsingleton.elim x y rfl +set_option backward.isDefEq.respectTransparency.types false in instance subsingleton_hom (X : Truncated.{u} 2) [Unique (X _⦋0⦌₂)] [Subsingleton (X _⦋1⦌₂)] (x y : X.HomotopyCategory) : Subsingleton (x ⟶ y) := @@ -485,6 +498,7 @@ lemma mapHomotopyCategory_homMk {x y : V _⦋0⦌₂} (e : Edge x y) : end +set_option backward.isDefEq.respectTransparency.types false in /-- The functor that takes a 2-truncated simplicial set to its homotopy category. -/ def hoFunctor₂ : SSet.Truncated.{u} 2 ⥤ Cat.{u, u} where obj V := Cat.of V.HomotopyCategory @@ -536,6 +550,7 @@ instance (x y : OneTruncation₂ ((truncation 2).obj Δ[0])) : Unique (x ⟶ y) instance : Unique ((truncation.{u} 2).obj Δ[0]).HomotopyCategory := inferInstanceAs (Unique <| CategoryTheory.Quotient _) +set_option backward.isDefEq.respectTransparency.types false in instance : IsDiscrete ((truncation.{u} 2).obj Δ[0]).HomotopyCategory where subsingleton x y := inferInstanceAs (Subsingleton ((_ : CategoryTheory.Quotient _) ⟶ _)) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/HornColimits.lean b/Mathlib/AlgebraicTopology/SimplicialSet/HornColimits.lean index 2da056980cb8ea..6c176df7bec3e9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/HornColimits.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/HornColimits.lean @@ -153,6 +153,7 @@ noncomputable def isColimit (i : Fin (n + 1)) : variable {X : SSet.{u}} +set_option backward.isDefEq.respectTransparency.types false in lemma hom_ext' {i : Fin (n + 2)} {f g : (Λ[n + 1, i] : SSet) ⟶ X} (h : ∀ (j : Fin (n + 2)) (hj : j ≠ i), horn.ι i j hj ≫ f = horn.ι i j hj ≫ g) : f = g := by @@ -206,6 +207,7 @@ lemma δ_pred_comp {i : Fin (n + 3)} {f : ∀ (j : Fin (n + 3)) (_ : j ≠ i), ( variable {i : Fin (n + 2)} {f : ∀ (j : Fin (n + 2)) (_ : j ≠ i), (Δ[n] : SSet) ⟶ X} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open stdSimplex in /-- Auxiliary definition for `horn.IsCompatible.desc`. -/ @@ -223,6 +225,7 @@ private def multicofork (hf : horn.IsCompatible f) : homOfLE_faceSingletonComplIso_inv_eq_facePairComplIso_inv_δ_castPred_assoc _ _ hab, hf.δ_pred_comp ..]) +set_option backward.isDefEq.respectTransparency.types false in lemma exists_desc (hf : horn.IsCompatible f) : ∃ (φ : (Λ[n + 1, i] : SSet) ⟶ X), ∀ (j : Fin (n + 2)) (hj : j ≠ i), horn.ι i j hj ≫ φ = f j hj := diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean index d52431c39482d5..6941c3e697d3a6 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean @@ -303,6 +303,7 @@ lemma isPushout : IsPushout (S.ι ▷ (T : SSet)) ((S : SSet) ◁ T.ι) (prodIso _ _ ≪≫ whiskerLeftIso _ (topIso Y)) (Iso.refl _) rfl rfl rfl rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma preimage_β_hom : (unionProd S T).preimage (β_ _ _).hom = unionProd T S := by ext n ⟨x, y⟩ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean index b8867db3e13b61..cac6d90cf6c128 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean @@ -81,6 +81,7 @@ def nerveEquiv {C : Type u} [Category.{v} C] : ComposableArrows C 0 ≃ C where namespace nerve +set_option backward.isDefEq.respectTransparency.types false in /-- Nerves of finite non-empty ordinals are representable functors. -/ def representableBy {n : ℕ} (α : Type u) [Preorder α] (e : α ≃o Fin (n + 1)) : (nerve α).RepresentableBy ⦋n⦌ where @@ -103,6 +104,7 @@ lemma σ_obj {n : ℕ} (i : Fin (n + 1)) (x : ComposableArrows C n) (j : Fin (n lemma δ₀_eq {x : ComposableArrows C (n + 1)} : (nerve C).δ (0 : Fin (n + 2)) x = x.δ₀ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma σ₀_mk₀_eq (x : C) : (nerve C).σ (0 : Fin 1) (.mk₀ x) = .mk₁ (𝟙 x) := ComposableArrows.ext₁ rfl rfl (by simp; rfl) @@ -159,6 +161,7 @@ section attribute [local ext (iff := false)] ComposableArrows.ext₀ ComposableArrows.ext₁ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Bijection between edges in the nerve of category and morphisms in the category. -/ @[simps -isSimp] @@ -169,6 +172,7 @@ def homEquiv {x y : ComposableArrows C 0} : left_inv e := by cat_disch right_inv f := by simp +set_option backward.isDefEq.respectTransparency.types false in lemma mk₁_homEquiv_apply {x y : ComposableArrows C 0} (e : (nerve C).Edge x y) : ComposableArrows.mk₁ (homEquiv e) = ComposableArrows.mk₁ e.edge.hom := by simp [homEquiv, ComposableArrows.mk₁_eqToHom_comp, ComposableArrows.mk₁_comp_eqToHom] diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NerveAdjunction.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NerveAdjunction.lean index ec2aa812866e1f..06955c8d97cf2c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NerveAdjunction.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NerveAdjunction.lean @@ -83,11 +83,13 @@ lemma spineEquiv_f₂_arrow_one (x : X _⦋2⦌₂) : ((hY.spineEquiv 2) (f₂ f₀ f₁ hδ₁ hδ₀ hY x)).arrow 1 = f₁ (X.map (δ₂ 0).op x) := by simp [f₂] +set_option backward.isDefEq.respectTransparency.types false in lemma hδ'₀ (x : X _⦋2⦌₂) : f₁ (X.map (δ₂ 0).op x) = Y.map (δ₂ 0).op (f₂ f₀ f₁ hδ₁ hδ₀ hY x) := by simp [← spineEquiv_f₂_arrow_one f₀ f₁ hδ₁ hδ₀ hY, StrictSegal.spineEquiv, SimplexCategory.mkOfSucc_one_eq_δ] +set_option backward.isDefEq.respectTransparency.types false in lemma hδ'₂ (x : X _⦋2⦌₂) : f₁ (X.map (δ₂ 2).op x) = Y.map (δ₂ 2).op (f₂ f₀ f₁ hδ₁ hδ₀ hY x) := by simp [← spineEquiv_f₂_arrow_zero f₀ f₁ hδ₁ hδ₀ hY, StrictSegal.spineEquiv, @@ -98,6 +100,7 @@ lemma hδ'₁ (x : X _⦋2⦌₂) : f₁ (X.map (δ₂ 1).op x) = Y.map (δ₂ 1).op (f₂ f₀ f₁ hδ₁ hδ₀ hY x) := H x (f₂ f₀ f₁ hδ₁ hδ₀ hY x) (hδ'₂ f₀ f₁ hδ₁ hδ₀ hY x) (hδ'₀ f₀ f₁ hδ₁ hδ₀ hY x) +set_option backward.isDefEq.respectTransparency.types false in include hσ in lemma hσ'₀ (x : X _⦋1⦌₂) : f₂ f₀ f₁ hδ₁ hδ₀ hY (X.map (σ₂ 0).op x) = Y.map (σ₂ 0).op (f₁ x) := by @@ -116,6 +119,7 @@ lemma hσ'₀ (x : X _⦋1⦌₂) : simp [StrictSegal.spineEquiv, SimplexCategory.mkOfSucc_one_eq_δ, ← Functor.map_comp_apply, ← op_comp] +set_option backward.isDefEq.respectTransparency.types false in include hσ in lemma hσ'₁ (x : X _⦋1⦌₂) : f₂ f₀ f₁ hδ₁ hδ₀ hY (X.map (σ₂ 1).op x) = Y.map (σ₂ 1).op (f₁ x) := by @@ -213,12 +217,14 @@ lemma descOfTruncation_map_homMk (φ : X ⟶ (truncation 2).obj (nerve C)) (descOfTruncation φ).map (homMk e) = nerve.homEquiv (e.map φ) := Category.id_comp _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma descOfTruncation_comp {X' : Truncated.{u} 2} (ψ : X ⟶ X') (φ : X' ⟶ (truncation 2).obj (nerve C)) : descOfTruncation (ψ ≫ φ) = mapHomotopyCategory ψ ⋙ descOfTruncation φ := functor_ext (fun _ ↦ by simp) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a `2`-truncated simplicial set `X` and a category `C`, this is the morphism `X ⟶ (truncation 2).obj (nerve C)` corresponding @@ -334,6 +340,7 @@ namespace nerve variable {C D : Type u} [SmallCategory C] [SmallCategory D] +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `C ⥤ D` that is reconstructed for a morphism between the `2`-truncated nerves. -/ @[simps] @@ -348,6 +355,7 @@ def functorOfNerveMap (φ : nerveFunctor₂.obj (.of C) ⟶ nerveFunctor₂.obj obtain ⟨h⟩ := (nerve.nonempty_compStruct_iff f g (f ≫ g)).2 rfl exact (nerve.homEquiv_comp (h.toTruncated.map φ)).symm +set_option backward.isDefEq.respectTransparency.types false in lemma nerveFunctor₂_map_functorOfNerveMap (φ : nerveFunctor₂.obj (.of C) ⟶ nerveFunctor₂.obj (.of D)) : nerveFunctor₂.map (functorOfNerveMap φ).toCatHom = φ := @@ -356,10 +364,12 @@ lemma nerveFunctor₂_map_functorOfNerveMap exact (nerveMap_app_mk₁ _ _).trans ((nerve.mk₁_homEquiv_apply _).trans (ComposableArrows.mk₁_hom _))) +set_option backward.isDefEq.respectTransparency.types false in lemma functorOfNerveMap_nerveFunctor₂_map (F : C ⥤ D) : functorOfNerveMap ((SSet.truncation 2).map (nerveMap F)) = F := Functor.ext (fun x ↦ by cat_disch) (fun x y f ↦ by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in /-- The `2`-truncated nerve functor is fully faithful. -/ def fullyFaithfulNerveFunctor₂ : nerveFunctor₂.{u, u}.FullyFaithful where preimage φ := (functorOfNerveMap φ).toCatHom diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean index 0ed7c0c1e50436..9d5146b0968cd7 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean @@ -27,6 +27,7 @@ namespace PartialOrder variable {X : Type*} [PartialOrder X] {n : ℕ} +set_option backward.isDefEq.respectTransparency.types false in lemma mem_range_nerve_σ_iff (s : (nerve X) _⦋n + 1⦌) (i : Fin (n + 1)) : s ∈ Set.range ((nerve X).σ i) ↔ s.obj i.castSucc = s.obj i.succ := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean index f2c473ade6dfe4..210c120d4df70c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean @@ -55,6 +55,7 @@ lemma multicoequalizerDiagram : variable {X} +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `SSet.isColimitCoconeN`. -/ noncomputable abbrev desc (s : Cocone X.functorN) : X ⟶ s.pt := @@ -76,6 +77,7 @@ noncomputable abbrev desc (s : Cocone X.functorN) : X ⟶ s.pt := exact (Subfunctor.mem_equalizer_iff (x := ⟨_, hz⟩) ..).mpr ((H x (N.mk _ z.prop) hz.1).trans (H y (N.mk _ z.prop) hz.2).symm)) +set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma fac (s : Cocone X.functorN) (x : X.N) : x.subcomplex.ι ≫ desc s = s.ι.app x := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean index 15635797ca2175..319b40edc98f78 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean @@ -51,6 +51,7 @@ end N noncomputable abbrev functorN' : X.N ⥤ SSet.{u} := N.toSemiSimplexCategory X ⋙ SemiSimplexCategory.toSimplexCategory ⋙ SSet.stdSimplex +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism `X.functorN' ≅ X.functorN` for a nonsingular simplicial set `X`. -/ noncomputable def functorN'Iso : X.functorN' ≅ X.functorN := diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplexOne.lean b/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplexOne.lean index ed5e8a53a6602c..f9b37a3a15fb59 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplexOne.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplexOne.lean @@ -29,6 +29,7 @@ namespace prodStdSimplex variable {p : ℕ} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open stdSimplex in /-- This is an enumeration of the `p + 1` nondegenerate dimension-`(p + 1)` @@ -73,11 +74,13 @@ noncomputable def nonDegenerateEquiv₁ : Fin.coe_ofNat_eq_mod, Nat.zero_mod, add_zero] at this lia) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma nonDegenerateEquiv₁_fst (i : Fin (p + 1)) : dsimp% (nonDegenerateEquiv₁ i).1.1 = (stdSimplex.objEquiv (m := op ⦋p + 1⦌)).symm (SimplexCategory.σ i) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma nonDegenerateEquiv₁_snd (i : Fin (p + 1)) : dsimp% (nonDegenerateEquiv₁ i).1.2 = diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean b/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean index fa376a2784977d..8b49df9fca50d9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/PushoutProduct.lean @@ -29,6 +29,9 @@ namespace Subcomplex namespace unionProd +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inclusion `(S.unionProd T).toSSet ⟶ X ⊗ Y` is isomorphic to the pushout-product `S.ι □ T.ι`. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/RelativeMorphism.lean b/Mathlib/AlgebraicTopology/SimplicialSet/RelativeMorphism.lean index 5dcfb52ffb256d..228519c125ab4f 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/RelativeMorphism.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/RelativeMorphism.lean @@ -71,6 +71,7 @@ lemma map_coe {n : SimplexCategoryᵒᵖ} (a : A.obj n) : f.map.app n a = φ.app n a := map_eq_of_mem _ _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma image_le : A.image f.map ≤ B := by rintro n _ ⟨a, ha, rfl⟩ have := f.map_coe ⟨a, ha⟩ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Skeleton.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Skeleton.lean index 3a63d8d2710023..7cabb413bfb544 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Skeleton.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Skeleton.lean @@ -70,6 +70,7 @@ lemma ofSimplex_le_skeleton {i : ℕ} (x : X _⦋i⦌) {n : ℕ} (hi : i < n) : Subcomplex.ofSimplex x ≤ X.skeleton n := by simpa using X.mem_skeleton x hi +set_option backward.isDefEq.respectTransparency.types false in lemma mem_skeleton_obj_iff_of_nonDegenerate {d : ℕ} (x : X.nonDegenerate d) (n : ℕ) : x.1 ∈ (X.skeleton n).obj _ ↔ d < n := by @@ -82,6 +83,7 @@ lemma mem_skeleton_obj_iff_of_nonDegenerate have : d ≤ i := SimplexCategory.len_le_of_mono f lia +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma skeleton_zero : X.skeleton 0 = ⊥ := by simp [skeleton] @@ -94,6 +96,7 @@ lemma iSup_skeleton : simp only [Subfunctor.iSup_obj, Set.mem_iUnion] exact ⟨n + 1, mem_skeleton _ _ (by lia)⟩) +set_option backward.isDefEq.respectTransparency.types false in lemma skeleton_succ (n : ℕ) : X.skeleton (n + 1) = X.skeleton n ⊔ ⨆ (x : X.nonDegenerate n), Subcomplex.ofSimplex x.1 := by @@ -132,6 +135,7 @@ section lemma skeleton_le_skeletonOfMono (n : ℕ) : Y.skeleton n ≤ skeletonOfMono i n := le_sup_right +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma skeletonOfMono_zero : skeletonOfMono i 0 = Subcomplex.range i := by @@ -144,6 +148,7 @@ lemma iSup_skeletonOfMono : intro n exact le_trans (skeleton_le_skeletonOfMono i n) (le_iSup _ n) +set_option backward.isDefEq.respectTransparency.types false in lemma mem_skeletonOfMono_obj_iff_of_nonDegenerate {d : ℕ} (x : Y.nonDegenerate d) (n : ℕ) : x.1 ∈ (skeletonOfMono i n).obj _ ↔ @@ -155,6 +160,7 @@ lemma skeletonOfMono_obj_eq_top {d n : ℕ} (h : d < n) : rw [← top_le_iff, ← Y.skeleton_obj_eq_top h] exact le_sup_right +set_option backward.isDefEq.respectTransparency.types false in lemma skeletonOfMono_succ (n : ℕ) : skeletonOfMono i (n + 1) = skeletonOfMono i n ⊔ ⨆ (x : Y.nonDegenerate n) @@ -237,6 +243,7 @@ noncomputable abbrev ιSigmaBoundary : (∂Δ[d] : SSet) ⟶ sigmaBoundary i d : of `Y` not in the range of `i`, this is the corresponding morphism `Δ[d] ⟶ Y`. -/ abbrev map : Δ[d] ⟶ Y := yonedaEquiv.symm c.simplex +set_option backward.isDefEq.respectTransparency.types false in lemma mem_skeletonOfMono_obj_iff {d' : ℕ} : c.simplex ∈ (skeletonOfMono i d').obj _ ↔ c.simplex ∈ Set.range (i.app _) ∨ d < d' := by @@ -290,7 +297,7 @@ abbrev r : (skeletonOfMono i d : SSet) ⟶ skeletonOfMono i (d + 1) := @[reassoc] lemma w : t i d ≫ r i d = l i d ≫ b i d := by ext c : 1 - simp [← cancel_mono (Subcomplex.ι _), Sigma.ι_desc_assoc] + simp [← cancel_mono (Subcomplex.ι _)] namespace Cell @@ -300,16 +307,25 @@ variable {i d} lemma ι_t_ι_eq_ι_l_b_ι (c : Cell i d) : c.ιSigmaBoundary ≫ t i d ≫ Subcomplex.ι _ = ∂Δ[d].ι ≫ c.ιSigmaStdSimplex ≫ b i d ≫ Subcomplex.ι _ := by - simp [Sigma.ι_desc_assoc] + simp @[reassoc] lemma ι_l (c : Cell i d) : c.ιSigmaBoundary ≫ l i d = ∂Δ[d].ι ≫ c.ιSigmaStdSimplex := by simp -@[reassoc (attr := simp)] +#adaptation_note +/-- +Now that `Cofan.mk` and `Discrete.functor` are implicit-reducible and +`backward.isDefEq.implicitBump` is enabled, the simp lemma `colimit.ι_desc_assoc` is applicable. +Previously, we had to use `by simp [Sigma.ι_desc_assoc]`, now `by simp` suffices. +The `simp` annotation on this lemma was removed because it would be redundant now, triggering the +`simpNF` linter. +-/ +@[reassoc] lemma ι_b_ι (c : Cell i d) : c.ιSigmaStdSimplex ≫ b i d ≫ Subcomplex.ι _ = c.map := by - simp [Sigma.ι_desc_assoc] + simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma b_app_ι_app_objEquiv_symm_val (c : Cell i d) {n : SimplexCategory} (f : n ⟶ ⦋d⦌) : dsimp% ((b i d).app _ (c.ιSigmaStdSimplex.app _ (stdSimplex.objEquiv.symm f))).val = @@ -319,6 +335,7 @@ lemma b_app_ι_app_objEquiv_symm_val (c : Cell i d) {n : SimplexCategory} (f : n end Cell +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isPullback : IsPullback (t i d) (l i d) (r i d) (b i d) where w := w i d diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index ba21e62be40308..d6a94c66f7f9c4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -631,6 +631,7 @@ lemma nonDegenerateEquiv'_iff {n d : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate unfold nonDegenerateEquiv' simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `x` is a nondegenerate `d`-simplex of `Δ[n]`, this is the order isomorphism between `Fin (d + 1)` and the corresponding subset of `Fin (n + 1)` of cardinality `d + 1`. -/ @@ -786,6 +787,7 @@ end Examples namespace Augmented +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor which sends `⦋n⦌` to the simplicial set `Δ[n]` equipped by the obvious augmentation towards the terminal object of the category of sets. -/ @@ -819,6 +821,7 @@ lemma yonedaEquiv_toOfSimplex : yonedaEquiv (toOfSimplex x) = ⟨x, mem_ofSimplex_obj x⟩ := yonedaEquiv.symm.injective (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Epi (toOfSimplex x) := by rw [← range_eq_top_iff] diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StrictSegal.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StrictSegal.lean index c690fffbc253ec..8d3db78f46eb3a 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StrictSegal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StrictSegal.lean @@ -159,6 +159,7 @@ theorem spineToSimplex_arrow (i : Fin m) (f : Path X m) : X.map (tr (mkOfSucc i)).op (sx.spineToSimplex m h f) = f.arrow i := by rw [← spine_arrow, spine_spineToSimplex_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem spineToSimplex_interval (f : Path X m) (j l : ℕ) (hjl : j + l ≤ m) : X.map (tr (subinterval j l hjl)).op (sx.spineToSimplex m h f) = @@ -178,6 +179,7 @@ theorem spineToSimplex_edge (f : Path X m) (j l : ℕ) (hjl : j + l ≤ m) : end spineToSimplex +set_option backward.isDefEq.respectTransparency.types false in /-- For any `σ : X ⟶ Y` between `n + 1`-truncated `StrictSegal` simplicial sets, `spineToSimplex` commutes with `Path.map`. -/ lemma spineToSimplex_map {X Y : SSet.Truncated.{u} (n + 1)} (sx : StrictSegal X) @@ -346,6 +348,7 @@ section interval variable (f : Path X n) (j l : ℕ) (hjl : j + l ≤ n) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem spineToSimplex_interval : X.map (subinterval j l hjl).op (sx.spineToSimplex f) = @@ -364,6 +367,7 @@ theorem spineToSimplex_edge : end interval +set_option backward.isDefEq.respectTransparency.types false in /-- For any `σ : X ⟶ Y` between `StrictSegal` simplicial sets, `spineToSimplex` commutes with `Path.map`. -/ lemma spineToSimplex_map {X Y : SSet.{u}} (sx : StrictSegal X) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean index 73e0f05739aea2..a7eb9ac446a547 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean @@ -258,6 +258,7 @@ lemma preimage_id (A : X.Subcomplex) : A.preimage (𝟙 X) = A := rfl lemma preimage_comp {Z : SSet.{u}} (A : Z.Subcomplex) (f : X ⟶ Y) (g : Y ⟶ Z) : A.preimage (f ≫ g) = (A.preimage g).preimage f := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma preimage_ι (A : X.Subcomplex) : A.preimage A.ι = ⊤ := by aesop diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexColimits.lean b/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexColimits.lean index 757394006e77a6..a431362cbad119 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexColimits.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexColimits.lean @@ -60,6 +60,7 @@ noncomputable def isColimit : exact (Multicofork.isColimitMapEquiv _ _).2 (Types.isColimitOfMulticoequalizerDiagram h')) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A colimit multicofork attached to a `MulticoequalizerDiagram` structure in the complete lattice of subcomplexes of a simplicial set. diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subdivision.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subdivision.lean index 9bfd8d64387c42..3446352d88f2f7 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subdivision.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subdivision.lean @@ -41,6 +41,7 @@ noncomputable def SimplexCategory.sd : SimplexCategory ⥤ SSet.{u} := namespace SSet +set_option backward.isDefEq.respectTransparency.types false in /-- The subdivision functor on simplicial sets. -/ noncomputable def sd : SSet.{u} ⥤ SSet.{u} := stdSimplex.leftKanExtension SimplexCategory.sd @@ -62,12 +63,14 @@ instance : ex.{u}.IsRightAdjoint := sdExAdjunction.isRightAdjoint namespace stdSimplex +set_option backward.isDefEq.respectTransparency.types false in /-- The natural isomorphism `stdSimplex ⋙ sd ≅ SimplexCategory.sd`. -/ noncomputable def sdIso : stdSimplex.{u} ⋙ sd ≅ SimplexCategory.sd := Presheaf.isExtensionAlongULiftYoneda _ end stdSimplex +set_option backward.isDefEq.respectTransparency.types false in instance : sd.{u}.IsLeftKanExtension stdSimplex.sdIso.inv := inferInstanceAs (Functor.IsLeftKanExtension _ (SSet.stdSimplex.leftKanExtensionUnit SimplexCategory.sd.{u})) diff --git a/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean b/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean index 67a2ba669291b6..c4adbbf61b5c9b 100644 --- a/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean +++ b/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean @@ -68,6 +68,7 @@ def singularChainComplexFunctorAdjunction : (Functor.postcompose₂.obj (eval _ ((SSet.chainComplexFunctorAdjunction C n).comp (sSetTopAdj.whiskerLeft _)).ofNatIsoRight ((evaluation TopCat C).mapIso (SSet.toTopSimplex.app _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma singularChainComplexFunctorAdjunction_unit_app (R : C) : (singularChainComplexFunctorAdjunction C n).unit.app R = diff --git a/Mathlib/AlgebraicTopology/SingularSet.lean b/Mathlib/AlgebraicTopology/SingularSet.lean index f681694a1d8b48..abe8924cc53a0b 100644 --- a/Mathlib/AlgebraicTopology/SingularSet.lean +++ b/Mathlib/AlgebraicTopology/SingularSet.lean @@ -62,6 +62,7 @@ noncomputable def TopCat.toSSetObjEquiv (X : TopCat.{u}) (n : SimplexCategoryᵒ Equiv.ulift.{0}.trans (ConcreteCategory.homEquiv.trans (Homeomorph.ulift.continuousMapCongr (.refl _))) +set_option backward.isDefEq.respectTransparency.types false in /-- The *geometric realization functor* is the left Kan extension of `SimplexCategory.toTop` along the Yoneda embedding. @@ -82,16 +83,19 @@ noncomputable def sSetTopAdj : SSet.toTop.{u} ⊣ TopCat.toSSet.{u} := instance : SSet.toTop.{u}.IsLeftAdjoint := sSetTopAdj.isLeftAdjoint instance : TopCat.toSSet.{u}.IsRightAdjoint := sSetTopAdj.isRightAdjoint +set_option backward.isDefEq.respectTransparency.types false in /-- The geometric realization of the representable simplicial sets agree with the usual topological simplices. -/ noncomputable def SSet.toTopSimplex : SSet.stdSimplex.{u} ⋙ SSet.toTop ≅ SimplexCategory.toTop := Presheaf.isExtensionAlongULiftYoneda _ +set_option backward.isDefEq.respectTransparency.types false in instance : SSet.toTop.{u}.IsLeftKanExtension SSet.toTopSimplex.inv := inferInstanceAs (Functor.IsLeftKanExtension _ (SSet.stdSimplex.{u}.leftKanExtensionUnit SimplexCategory.toTop.{u})) +set_option backward.isDefEq.respectTransparency.types false in lemma sSetTopAdj_unit_app_app_down (S : SSet) (m : SimplexCategoryᵒᵖ) (a : S.obj m) : ((sSetTopAdj.unit.app S).app m a).down = SSet.toTopSimplex.inv.app _ ≫ SSet.toTop.map (SSet.yonedaEquiv.symm a) := by @@ -104,6 +108,9 @@ noncomputable def TopCat.toSSetIsoConst (X : TopCat.{u}) [TotallyDisconnectedSpa ((TotallyDisconnectedSpace.continuousMapEquivOfConnectedSpace _ X).symm.trans (X.toSSetObjEquiv n).symm))).symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical map `Δ[n] ⟶ Simp(Δₜ[n])` (where `Δₜ[n]` is the topological `n`-simplex). -/ @[simps! -isSimp] noncomputable def SSet.stdSimplexToTop : SSet.stdSimplex.{u} ⟶ SimplexCategory.toTop ⋙ TopCat.toSSet := diff --git a/Mathlib/Analysis/Analytic/Composition.lean b/Mathlib/Analysis/Analytic/Composition.lean index a2d67c703fbb11..b775c5c5de2c22 100644 --- a/Mathlib/Analysis/Analytic/Composition.lean +++ b/Mathlib/Analysis/Analytic/Composition.lean @@ -401,6 +401,7 @@ theorem comp_id (p : FormalMultilinearSeries 𝕜 E F) (x : E) : p.comp (id 𝕜 rw [id_apply_of_one_lt _ _ _ A, _root_.zero_apply] · simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem id_comp (p : FormalMultilinearSeries 𝕜 E F) (v0 : Fin 0 → E) : (id 𝕜 F (p 0 v0)).comp p = p := by @@ -1083,6 +1084,7 @@ theorem length_gather (a : Composition n) (b : Composition a.length) : show (map List.sum (a.blocks.splitWrtComposition b)).length = b.blocks.length by rw [length_map, length_splitWrtComposition] +set_option backward.isDefEq.respectTransparency false in /-- An auxiliary function used in the definition of `sigmaEquivSigmaPi` below, associating to two compositions `a` of `n` and `b` of `a.length`, and an index `i` bounded by the length of `a.gather b`, the subcomposition of `a` made of those blocks belonging to the `i`-th block of diff --git a/Mathlib/Analysis/Analytic/Inverse.lean b/Mathlib/Analysis/Analytic/Inverse.lean index 884a476bf78ade..dc7900b521cfec 100644 --- a/Mathlib/Analysis/Analytic/Inverse.lean +++ b/Mathlib/Analysis/Analytic/Inverse.lean @@ -182,6 +182,7 @@ theorem rightInv_coeff_zero (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[ theorem rightInv_coeff_one (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (x : E) : p.rightInv i x 1 = (continuousMultilinearCurryFin1 𝕜 F E).symm i.symm := by rw [rightInv] +set_option backward.isDefEq.respectTransparency false in /-- The right inverse does not depend on the zeroth coefficient of a formal multilinear series. -/ theorem rightInv_removeZero (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (x : E) : @@ -238,6 +239,7 @@ theorem comp_rightInv_aux2 (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[ simp [← Composition.ne_single_iff N, Composition.eq_single_iff_length, ne_of_gt hc] simp [applyComposition, this] +set_option backward.isDefEq.respectTransparency false in /-- The right inverse to a formal multilinear series is indeed a right inverse, provided its linear term is invertible and its constant term vanishes. -/ theorem comp_rightInv (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (x : E) @@ -257,6 +259,7 @@ theorem comp_rightInv (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F have N : 0 < n + 2 := by simp simp [comp_rightInv_aux1 N, h, rightInv, comp_rightInv_aux2, -Set.toFinset_setOf] +set_option backward.isDefEq.respectTransparency false in theorem rightInv_coeff (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (x : E) (n : ℕ) (hn : 2 ≤ n) : p.rightInv i x n = diff --git a/Mathlib/Analysis/Analytic/IteratedFDeriv.lean b/Mathlib/Analysis/Analytic/IteratedFDeriv.lean index 2d519981981421..e21e14a41788a9 100644 --- a/Mathlib/Analysis/Analytic/IteratedFDeriv.lean +++ b/Mathlib/Analysis/Analytic/IteratedFDeriv.lean @@ -128,6 +128,7 @@ lemma ContinuousMultilinearMap.iteratedFDeriv_comp_diagonal obtain ⟨y, rfl⟩ := σ.equivOfFiniteSelfEmbedding.surjective i simp [Function.Embedding.equivOfFiniteSelfEmbedding, g] +set_option backward.isDefEq.respectTransparency false in private lemma HasFPowerSeriesWithinOnBall.iteratedFDerivWithin_eq_sum_of_subset (h : HasFPowerSeriesWithinOnBall f p s x r) (h' : AnalyticOn 𝕜 f s) (hs : UniqueDiffOn 𝕜 s) (hx : x ∈ s) diff --git a/Mathlib/Analysis/AperiodicOrder/Delone/Basic.lean b/Mathlib/Analysis/AperiodicOrder/Delone/Basic.lean index f3f33a2615c0b3..f95b8a2e839f36 100644 --- a/Mathlib/Analysis/AperiodicOrder/Delone/Basic.lean +++ b/Mathlib/Analysis/AperiodicOrder/Delone/Basic.lean @@ -155,10 +155,12 @@ noncomputable def mapBilipschitz (f : X ≃ Y) (K₁ K₂ : ℝ≥0) (hK₁ : 0 coveringRadius_pos := mul_pos hK₂ D.coveringRadius_pos isCover_coveringRadius := D.isCover_coveringRadius.image_lipschitz_of_surjective hf₂ f.surjective +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mapBilipschitz_refl (D : DeloneSet X) (hK1 hK2 hA hL) : D.mapBilipschitz (.refl X) 1 1 hK1 hK2 hA hL = D := by ext <;> simp only [mapBilipschitz, Equiv.refl_apply, Set.image_id', div_one, one_mul] +set_option backward.isDefEq.respectTransparency false in lemma mapBilipschitz_trans {Z : Type*} [MetricSpace Z] (D : DeloneSet X) (f : X ≃ Y) (g : Y ≃ Z) (K₁f K₂f K₁g K₂g : ℝ≥0) (hf₁_pos : 0 < K₁f) (hf₂_pos : 0 < K₂f) @@ -176,6 +178,7 @@ lemma mapBilipschitz_trans {Z : Type*} [MetricSpace Z] (D : DeloneSet X) · simp only [mapBilipschitz_packingRadius, NNReal.coe_div, div_div] · simp only [mapBilipschitz_coveringRadius, NNReal.coe_mul, mul_assoc] +set_option backward.isDefEq.respectTransparency false in /-- The image of a Delone set under an isometry. This is a specialization of `DeloneSet.mapBilipschitz` where the packing and covering radii are preserved because the Lipschitz constants are both 1. -/ @@ -190,6 +193,7 @@ noncomputable def mapIsometry (f : X ≃ᵢ Y) : DeloneSet X ≃ DeloneSet Y whe left_inv D := by ext <;> simp [copy_eq] right_inv D := by ext <;> simp [copy_eq] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mapIsometry_refl (D : DeloneSet X) : D.mapIsometry (.refl X) = D := by ext <;> simp [mapIsometry, IsometryEquiv.refl, DeloneSet.copy] diff --git a/Mathlib/Analysis/BoxIntegral/DivergenceTheorem.lean b/Mathlib/Analysis/BoxIntegral/DivergenceTheorem.lean index 116249ba98ace2..e449db0449a718 100644 --- a/Mathlib/Analysis/BoxIntegral/DivergenceTheorem.lean +++ b/Mathlib/Analysis/BoxIntegral/DivergenceTheorem.lean @@ -137,6 +137,7 @@ theorem norm_volume_sub_integral_face_upper_sub_lower_smul_le {f : (Fin (n + 1) ← I.volume_face_mul i] ac_rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `f : ℝⁿ⁺¹ → E` is differentiable on a closed rectangular box `I` with derivative `f'`, then the partial derivative `fun x ↦ f' x (Pi.single i 1)` is Henstock-Kurzweil integrable with integral diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean index 0824afe45602b0..e4f9829f93ca68 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean @@ -352,6 +352,7 @@ theorem biUnion_assoc (πi : ∀ J, Prepartition J) (πi' : Box ι → ∀ J : B refine ⟨J₂, hJ₂, J₁, hJ₁, ?_⟩ rwa [π.biUnionIndex_of_mem hJ₂ hJ₁] at hJ +set_option backward.isDefEq.respectTransparency false in /-- Create a `BoxIntegral.Prepartition` from a collection of possibly empty boxes by filtering out the empty one if it exists. -/ def ofWithBot (boxes : Finset (WithBot (Box ι))) @@ -371,6 +372,7 @@ theorem mem_ofWithBot {boxes : Finset (WithBot (Box ι))} {h₁ h₂} : J ∈ (ofWithBot boxes h₁ h₂ : Prepartition I) ↔ (J : WithBot (Box ι)) ∈ boxes := mem_eraseNone +set_option backward.isDefEq.respectTransparency false in @[simp] theorem iUnion_ofWithBot (boxes : Finset (WithBot (Box ι))) (le_of_mem : ∀ J ∈ boxes, (J : WithBot (Box ι)) ≤ I) @@ -381,6 +383,7 @@ theorem iUnion_ofWithBot (boxes : Finset (WithBot (Box ι))) simp only [← Box.biUnion_coe_eq_coe, @iUnion_comm _ _ (Box ι), @iUnion_comm _ _ (@Eq _ _ _), iUnion_iUnion_eq_right] +set_option backward.isDefEq.respectTransparency false in theorem ofWithBot_le {boxes : Finset (WithBot (Box ι))} {le_of_mem : ∀ J ∈ boxes, (J : WithBot (Box ι)) ≤ I} {pairwise_disjoint : Set.Pairwise (boxes : Set (WithBot (Box ι))) Disjoint} @@ -449,6 +452,7 @@ theorem restrict_mono {π₁ π₂ : Prepartition I} (Hle : π₁ ≤ π₂) : theorem monotone_restrict : Monotone fun π : Prepartition I => restrict π J := fun _ _ => restrict_mono +set_option backward.isDefEq.respectTransparency false in /-- Restricting to a larger box does not change the set of boxes. We cannot claim equality of prepartitions because they have different types. -/ theorem restrict_boxes_of_le (π : Prepartition I) (h : I ≤ J) : (π.restrict J).boxes = π.boxes := by diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean b/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean index 9bd1813fa24e48..b211a19341e72f 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean @@ -365,6 +365,7 @@ protected theorem MemBaseSet.unionComplToSubordinate (hπ₁ : l.MemBaseSet I c variable {r : (ι → ℝ) → Ioi (0 : ℝ)} +set_option backward.isDefEq.respectTransparency false in protected theorem MemBaseSet.filter (hπ : l.MemBaseSet I c r π) (p : Box ι → Prop) : l.MemBaseSet I c r (π.filter p) := by classical diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Split.lean b/Mathlib/Analysis/BoxIntegral/Partition/Split.lean index b02d5ddc5dbe5d..796c691bb8e383 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Split.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Split.lean @@ -178,6 +178,7 @@ theorem iUnion_split (I : Box ι) (i : ι) (x : ℝ) : (split I i x).iUnion = I theorem isPartitionSplit (I : Box ι) (i : ι) (x : ℝ) : IsPartition (split I i x) := isPartition_iff_iUnion_eq.2 <| iUnion_split I i x +set_option backward.isDefEq.respectTransparency false in theorem sum_split_boxes {M : Type*} [AddCommMonoid M] (I : Box ι) (i : ι) (x : ℝ) (f : Box ι → M) : (∑ J ∈ (split I i x).boxes, f J) = (I.splitLower i x).elim' 0 f + (I.splitUpper i x).elim' 0 f := by diff --git a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean index 2caace409304a7..91bc19a0f3d949 100644 --- a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean +++ b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean @@ -243,6 +243,7 @@ def prepartition (B : Box ι) : TaggedPrepartition B where · simp_rw [dif_neg hI] exact Box.coe_subset_Icc B.exists_mem.choose_spec +set_option backward.isDefEq.respectTransparency.types false in variable {n} in @[simp] theorem mem_prepartition_iff {B I : Box ι} : diff --git a/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean b/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean index 3efc1706d31ec5..9d2e533204f3b5 100644 --- a/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean +++ b/Mathlib/Analysis/CStarAlgebra/CStarMatrix.lean @@ -389,6 +389,7 @@ lemma ofMatrix_eq_ofMatrixStarAlgEquiv [Fintype n] [SMul ℂ A] [Semiring A] [St (ofMatrix : Matrix n n A → CStarMatrix n n A) = (ofMatrixStarAlgEquiv : Matrix n n A → CStarMatrix n n A) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable (R) (A) in /-- The natural map that reindexes a matrix's rows and columns with equivalent types is an equivalence. -/ @@ -403,6 +404,7 @@ lemma reindexₗ_apply {l o : Type*} [Semiring R] [AddCommMonoid A] [Module R A] {eₘ : m ≃ l} {eₙ : n ≃ o} {M : CStarMatrix m n A} {i : l} {j : o} : reindexₗ R A eₘ eₙ M i j = Matrix.reindex eₘ eₙ M i j := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The natural map that reindexes a matrix's rows and columns with equivalent types is an equivalence. -/ def reindexₐ (R) (A) [Fintype m] [Fintype n] [Semiring R] [AddCommMonoid A] [Mul A] [Module R A] @@ -422,20 +424,24 @@ def reindexₐ (R) (A) [Fintype m] [Fintype n] [Semiring R] [AddCommMonoid A] [M rw [star_apply, star_apply] simp [Matrix.submatrix_apply] } +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma reindexₐ_apply [Fintype m] [Fintype n] [Semiring R] [AddCommMonoid A] [Mul A] [Star A] [Module R A] {e : m ≃ n} {M : CStarMatrix m m A} {i : n} {j : n} : reindexₐ R A e M i j = Matrix.reindex e e M i j := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma mapₗ_reindexₐ [Fintype m] [Fintype n] [Semiring R] [AddCommMonoid A] [Mul A] [Module R A] [Star A] [AddCommMonoid B] [Mul B] [Module R B] [Star B] {e : m ≃ n} {M : CStarMatrix m m A} (φ : A →ₗ[R] B) : reindexₐ R B e (M.mapₗ φ) = ((reindexₐ R A e M).mapₗ φ) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma reindexₐ_symm [Fintype m] [Fintype n] [Semiring R] [AddCommMonoid A] [Mul A] [Module R A] [Star A] {e : m ≃ n} : reindexₐ R A e.symm = (reindexₐ R A e).symm := by simp [reindexₐ, reindexₗ] +set_option backward.isDefEq.respectTransparency.types false in /-- Applying a non-unital ⋆-algebra homomorphism to every entry of a matrix is itself a ⋆-algebra homomorphism on matrices. -/ @[simps] @@ -457,6 +463,7 @@ theorem algebraMap_apply [Fintype n] [DecidableEq n] [CommSemiring R] [Semiring [Algebra R A] {r : R} {i j : n} : (algebraMap R (CStarMatrix n n A) r) i j = if i = j then algebraMap R A r else 0 := rfl +set_option backward.isDefEq.respectTransparency.types false in variable (n) (R) (A) in /-- The ⋆-algebra equivalence between `A` and 1×1 matrices with its entry in `A`. -/ def toOneByOne [Unique n] [Semiring R] [AddCommMonoid A] [Mul A] [Star A] [Module R A] : @@ -557,6 +564,7 @@ lemma mul_entry_mul_eq_inner_toCLM [Fintype n] [DecidableEq m] [DecidableEq n] variable [Fintype n] +set_option backward.isDefEq.respectTransparency.types false in open WithCStarModule in lemma inner_toCLM_conjTranspose_left {M : CStarMatrix m n A} {v : C⋆ᵐᵒᵈ(A, n → A)} {w : C⋆ᵐᵒᵈ(A, m → A)} : ⟪toCLM Mᴴ v, w⟫_A = ⟪v, toCLM M w⟫_A := by @@ -565,6 +573,7 @@ lemma inner_toCLM_conjTranspose_left {M : CStarMatrix m n A} {v : C⋆ᵐᵒᵈ( rw [Finset.sum_comm] simp_rw [mul_assoc] +set_option backward.isDefEq.respectTransparency.types false in lemma inner_toCLM_conjTranspose_right {M : CStarMatrix m n A} {v : C⋆ᵐᵒᵈ(A, m → A)} {w : C⋆ᵐᵒᵈ(A, n → A)} : ⟪v, toCLM Mᴴ w⟫_A = ⟪toCLM M v, w⟫_A := by apply Eq.symm @@ -636,7 +645,7 @@ private noncomputable local instance normedAddCommGroupAux : NormedAddCommGroup (CStarMatrix m n A) := .ofCore CStarMatrix.normedSpaceCore -@[implicit_reducible] +@[instance_reducible] private noncomputable def normedSpaceAux : NormedSpace ℂ (CStarMatrix m n A) := .ofCore CStarMatrix.normedSpaceCore diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean index d720af78d8eec5..56caf8a9da64e3 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Isometric.lean @@ -180,6 +180,7 @@ variable [Algebra R S] [Algebra R A] [IsScalarTower R S A] [StarModule R S] [Con variable [MetricSpace A] [IsometricContinuousFunctionalCalculus S A q] variable [CompleteSpace R] [ContinuousMap.UniqueHom R A] +set_option backward.isDefEq.respectTransparency.types false in open scoped ContinuousFunctionalCalculus in protected theorem isometric_cfc (f : C(S, R)) (halg : Isometry (algebraMap R S)) (h0 : p 0) (h : ∀ a, p a ↔ q a ∧ SpectrumRestricts a f) : @@ -257,6 +258,7 @@ lemma nnnorm_cfcₙHom (a : A) (f : C(σₙ 𝕜 a, 𝕜)₀) (ha : p a := by cf ‖cfcₙHom (show p a from ha) f‖₊ = ‖f‖₊ := Subtype.ext <| norm_cfcₙHom a f ha +set_option backward.isDefEq.respectTransparency.types false in lemma IsGreatest.norm_cfcₙ (f : 𝕜 → 𝕜) (a : A) (hf : ContinuousOn f (σₙ 𝕜 a) := by cfc_cont_tac) (hf₀ : f 0 = 0 := by cfc_zero_tac) (ha : p a := by cfc_tac) : IsGreatest ((fun x ↦ ‖f x‖) '' σₙ 𝕜 a) ‖cfcₙ f a‖ := by @@ -370,6 +372,7 @@ variable [IsScalarTower R A A] [SMulCommClass R A A] variable [MetricSpace A] [NonUnitalIsometricContinuousFunctionalCalculus S A q] variable [CompleteSpace R] [ContinuousMapZero.UniqueHom R A] +set_option backward.isDefEq.respectTransparency.types false in open scoped NonUnitalContinuousFunctionalCalculus in protected theorem isometric_cfc (f : C(S, R)) (halg : Isometry (algebraMap R S)) (h0 : p 0) (h : ∀ a, p a ↔ q a ∧ QuasispectrumRestricts a f) : diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index 31c5d13ffeeb7c..09286ec3c9466e 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -164,6 +164,7 @@ lemma cfcₙHom_eq_of_continuous_of_map_id [UniqueHom R A] (cfcₙHom ha).ext_continuousMap a φ (cfcₙHom_continuous ha) hφ₁ <| by rw [cfcₙHom_id ha, hφ₂] +set_option backward.isDefEq.respectTransparency false in theorem cfcₙHom_comp [UniqueHom R A] (f : C(σₙ R a, R)₀) (f' : C(σₙ R a, σₙ R (cfcₙHom ha f))₀) (hff' : ∀ x, f x = f' x) (g : C(σₙ R (cfcₙHom ha f), R)₀) : @@ -249,6 +250,7 @@ lemma cfcₙ_apply_of_not_map_zero {f : R → R} (a : A) (hf : ¬ f 0 = 0) : cfcₙ f a = 0 := by rw [cfcₙ_def, dif_neg (not_and_of_not_right _ (not_and_of_not_right _ hf))] +set_option backward.isDefEq.respectTransparency false in lemma cfcₙHom_eq_cfcₙ_extend {a : A} (g : R → R) (ha : p a) (f : C(σₙ R a, R)₀) : cfcₙHom ha f = cfcₙ (Function.extend Subtype.val f g) a := by have h : f = (σₙ R a).restrict (Function.extend Subtype.val f g) := by @@ -311,6 +313,7 @@ variable (R) in include ha in lemma cfcₙ_id' : cfcₙ (fun x : R ↦ x) a = a := cfcₙ_id R a +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in include ha hf hf0 in /-- The **spectral mapping theorem** for the non-unital continuous functional calculus. -/ @@ -383,6 +386,7 @@ lemma cfcₙ_add : cfcₙ (fun x ↦ f x + g x) a = cfcₙ f a + cfcₙ g a := b congr · simp [cfcₙ_apply_of_not_predicate a ha] +set_option backward.isDefEq.respectTransparency false in open Finset in lemma cfcₙ_sum {ι : Type*} (f : ι → R → R) (a : A) (s : Finset ι) (hf : ∀ i ∈ s, ContinuousOn (f i) (σₙ R a) := by cfc_cont_tac) @@ -463,6 +467,7 @@ section Comp variable [UniqueHom R A] +set_option backward.isDefEq.respectTransparency false in lemma cfcₙ_comp (g f : R → R) (a : A) (hg : ContinuousOn g (f '' σₙ R a) := by cfc_cont_tac) (hg0 : g 0 = 0 := by cfc_zero_tac) (hf : ContinuousOn f (σₙ R a) := by cfc_cont_tac) (hf0 : f 0 = 0 := by cfc_zero_tac) @@ -637,7 +642,7 @@ lemma cfcₙ_nonneg_iff [NonnegSpectrumClass R A] (f : R → R) (a : A) (h0 : f 0 = 0 := by cfc_zero_tac) (ha : p a := by cfc_tac) : 0 ≤ cfcₙ f a ↔ ∀ x ∈ σₙ R a, 0 ≤ f x := by rw [cfcₙ_apply .., cfcₙHom_nonneg_iff, ContinuousMapZero.le_def] - simp only [ContinuousMapZero.coe_mk, ContinuousMap.coe_mk, Set.restrict_apply, Subtype.forall] + simp only [Subtype.forall] congr! lemma StarOrderedRing.nonneg_iff_quasispectrum_nonneg [NonnegSpectrumClass R A] (a : A) @@ -680,6 +685,7 @@ lemma cfcₙHom_le_iff {a : A} (ha : p a) {f g : C(σₙ R a, R)₀} : cfcₙHom ha f ≤ cfcₙHom ha g ↔ f ≤ g := by rw [← sub_nonneg, ← map_sub, cfcₙHom_nonneg_iff, sub_nonneg] +set_option backward.isDefEq.respectTransparency false in lemma cfcₙ_le_iff (f g : R → R) (a : A) (hf : ContinuousOn f (σₙ R a) := by cfc_cont_tac) (hg : ContinuousOn g (σₙ R a) := by cfc_cont_tac) (hf0 : f 0 = 0 := by cfc_zero_tac) (hg0 : g 0 = 0 := by cfc_zero_tac) (ha : p a := by cfc_tac) : diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean index ae98b71f0e4926..4a7c32ad3921fc 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean @@ -50,6 +50,7 @@ lemma compactSpace {R S A : Type*} [Semifield R] [Semifield S] [Ring A] universe u v w +set_option backward.isDefEq.respectTransparency.types false in /-- If the spectrum of an element restricts to a smaller scalar ring, then a continuous functional calculus over the larger scalar ring descends to the smaller one. -/ @[simps!] @@ -109,6 +110,7 @@ lemma isClosedEmbedding_starAlgHom {a : A} {φ : C(spectrum S a, S) →⋆ₐ[S] (ContinuousMap.isUniformEmbedding_comp _ halg) (UniformEquiv.arrowCongr h.homeomorph.symm (.refl _) |>.isUniformEmbedding) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a `ContinuousFunctionalCalculus S A q`. If we form the predicate `p` for `a : A` characterized by: `q a` and the spectrum of `a` restricts to the scalar subring `R` via `f : C(S, R)`, then we can get a restricted functional calculus @@ -153,6 +155,7 @@ lemma cfcHom_eq_restrict (f : C(S, R)) {a : A} (hpa : p a) (hqa : q a) (h : Spec · exact h.continuous_starAlgHom (cfcHom_continuous hqa) · exact h.starAlgHom_id (cfcHom_id hqa) +set_option backward.isDefEq.respectTransparency.types false in lemma cfc_eq_restrict (f : C(S, R)) (halg : IsClosedEmbedding (algebraMap R S)) {a : A} (hpa : p a) (hqa : q a) (h : SpectrumRestricts a f) (g : R → R) : cfc g a = cfc (fun x ↦ algebraMap R S (g (f x))) a := by @@ -212,6 +215,7 @@ def homeomorph {R S A : Type*} [Semifield R] [Field S] [NonUnitalRing A] universe u v w open ContinuousMapZero +set_option backward.isDefEq.respectTransparency.types false in /-- If the quasispectrum of an element restricts to a smaller scalar ring, then a non-unital continuous functional calculus over the larger scalar ring descends to the smaller one. -/ @[simps!] @@ -277,6 +281,7 @@ lemma isClosedEmbedding_nonUnitalStarAlgHom {a : A} {φ : C(σₙ S a, S)₀ → variable [IsScalarTower R A A] [SMulCommClass R A A] +set_option backward.isDefEq.respectTransparency.types false in /-- Given a `NonUnitalContinuousFunctionalCalculus S A q`. If we form the predicate `p` for `a : A` characterized by: `q a` and the quasispectrum of `a` restricts to the scalar subring `R` via `f : C(S, R)`, then we can get a restricted functional calculus @@ -320,6 +325,7 @@ lemma cfcₙHom_eq_restrict (f : C(S, R)) {a : A} (hpa : p a) (hqa : q a) · exact h.continuous_nonUnitalStarAlgHom (cfcₙHom_continuous hqa) · exact h.nonUnitalStarAlgHom_id (cfcₙHom_id hqa) +set_option backward.isDefEq.respectTransparency.types false in lemma cfcₙ_eq_restrict (f : C(S, R)) (halg : IsClosedEmbedding (algebraMap R S)) {a : A} (hpa : p a) (hqa : q a) (h : QuasispectrumRestricts a f) (g : R → R) : cfcₙ g a = cfcₙ (fun x ↦ algebraMap R S (g (f x))) a := by diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean index 035cce82a04c39..d6c19e91ac41c8 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean @@ -284,6 +284,7 @@ section IsTopologicalRing variable [TopologicalSpace A] [IsSemitopologicalRing A] +set_option backward.isDefEq.respectTransparency false in /-- Given a non-unital star `ℝ≥0`-algebra homomorphism `φ` from `C(X, ℝ≥0)₀` into a non-unital `ℝ`-algebra `A`, this is the unique extension of `φ` from `C(X, ℝ)₀` to `A` as a non-unital star `ℝ`-algebra homomorphism. -/ @@ -328,6 +329,7 @@ lemma continuous_realContinuousMapZeroOfNNReal (φ : C(X, ℝ≥0)₀ →⋆ₙ end IsTopologicalRing +set_option backward.isDefEq.respectTransparency false in @[simp high] lemma realContinuousMapZeroOfNNReal_apply_comp_toReal (φ : C(X, ℝ≥0)₀ →⋆ₙₐ[ℝ≥0] A) (f : C(X, ℝ≥0)₀) : @@ -351,6 +353,7 @@ end NonUnitalStarAlgHom open ContinuousMapZero +set_option backward.isDefEq.respectTransparency false in instance NNReal.instContinuousMapZero.UniqueHom [TopologicalSpace A] [IsSemitopologicalRing A] [IsScalarTower ℝ A A] [SMulCommClass ℝ A A] [T2Space A] : @@ -456,6 +459,7 @@ variable {F R S A B : Type*} {p : A → Prop} {q : B → Prop} [ContinuousMap.UniqueHom R B] [FunLike F A B] [AlgHomClass F S A B] [StarHomClass F A B] +set_option backward.isDefEq.respectTransparency false in include S in /-- Star algebra homomorphisms commute with the continuous functional calculus. -/ lemma StarAlgHomClass.map_cfc (φ : F) (f : R → R) (a : A) diff --git a/Mathlib/Analysis/CStarAlgebra/Matrix.lean b/Mathlib/Analysis/CStarAlgebra/Matrix.lean index c304aa4b11eae3..8f7d0060050db6 100644 --- a/Mathlib/Analysis/CStarAlgebra/Matrix.lean +++ b/Mathlib/Analysis/CStarAlgebra/Matrix.lean @@ -135,7 +135,7 @@ lemma inner_toEuclideanCLM (A : Matrix n n ℝ) (x y : EuclideanSpace ℝ n) : /-- An auxiliary definition used only to construct the true `NormedAddCommGroup` (and `Metric`) structure provided by `Matrix.instMetricSpaceL2Op` and `Matrix.instNormedAddCommGroupL2Op`. -/ -@[implicit_reducible] +@[instance_reducible] def l2OpNormedAddCommGroupAux : NormedAddCommGroup (Matrix m n 𝕜) := @NormedAddCommGroup.induced ((Matrix m n 𝕜) ≃ₗ[𝕜] (EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 m)) _ _ _ _ ContinuousLinearMap.toNormedAddCommGroup.toNormedAddGroup _ _ <| @@ -143,7 +143,7 @@ def l2OpNormedAddCommGroupAux : NormedAddCommGroup (Matrix m n 𝕜) := /-- An auxiliary definition used only to construct the true `NormedRing` (and `Metric`) structure provided by `Matrix.instMetricSpaceL2Op` and `Matrix.instNormedRingL2Op`. -/ -@[implicit_reducible] +@[instance_reducible] def l2OpNormedRingAux : NormedRing (Matrix n n 𝕜) := @NormedRing.induced ((Matrix n n 𝕜) ≃⋆ₐ[𝕜] (EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 n)) _ _ _ _ ContinuousLinearMap.toNormedRing _ _ toEuclideanCLM.injective diff --git a/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean b/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean index 3087a60b83ef44..d5dee87f586507 100644 --- a/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean +++ b/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean @@ -168,7 +168,7 @@ local notation "⟪" x ", " y "⟫" => inner A x y open scoped InnerProductSpace in /-- The norm associated with a Hilbert C⋆-module. It is not registered as a norm, since a type might already have a norm defined on it. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def norm (A : Type*) {E : Type*} [Norm A] [Inner A E] : Norm E where norm x := √‖⟪x, x⟫_A‖ diff --git a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean index d821cfa99d5166..2977be3ed121bd 100644 --- a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean +++ b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean @@ -265,6 +265,7 @@ variable [FunLike F A B] [NonUnitalAlgHomClass F ℂ A B] [StarHomClass F A B] open Unitization +set_option backward.isDefEq.respectTransparency.types false in /-- A non-unital star algebra homomorphism of complex C⋆-algebras is norm contractive. -/ lemma nnnorm_apply_le (φ : F) (a : A) : ‖φ a‖₊ ≤ ‖a‖₊ := by have h (ψ : Unitization ℂ A →⋆ₐ[ℂ] Unitization ℂ B) (x : Unitization ℂ A) : diff --git a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean index 6f001f355ec0b0..3b531908c14d70 100644 --- a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean +++ b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean @@ -215,7 +215,7 @@ lemma Unitary.norm_expUnitary_smul_argSelfAdjoint_sub_one_le (u : unitary A) lemma Unitary.continuousOn_argSelfAdjoint : ContinuousOn (argSelfAdjoint : unitary A → selfAdjoint A) (ball (1 : unitary A) 2) := by rw [Topology.IsInducing.subtypeVal.continuousOn_iff] - simp only [SetLike.coe_sort_coe, Function.comp_def, argSelfAdjoint_coe] + simp only [Function.comp_def, argSelfAdjoint_coe] rw [isOpen_ball.continuousOn_iff] intro u (hu : dist u 1 < 2) obtain ⟨ε, huε, hε2⟩ := exists_between (sq_lt_sq₀ (by positivity) (by positivity) |>.mpr hu) diff --git a/Mathlib/Analysis/CStarAlgebra/Unitary/Maps.lean b/Mathlib/Analysis/CStarAlgebra/Unitary/Maps.lean index 01160e3b901cb7..5054a58e23e5a3 100644 --- a/Mathlib/Analysis/CStarAlgebra/Unitary/Maps.lean +++ b/Mathlib/Analysis/CStarAlgebra/Unitary/Maps.lean @@ -19,6 +19,7 @@ variable {R A : Type*} [NormedRing A] [StarRing A] [CStarRing A] [Ring R] [Modul section mulLeft variable [SMulCommClass R A A] +set_option backward.isDefEq.respectTransparency false in variable (R A) in /-- Left multiplication by a unitary as a linear isometric equivalence. -/ noncomputable def mulLeft : unitary A →* A ≃ₗᵢ[R] A where diff --git a/Mathlib/Analysis/CStarAlgebra/Unitization.lean b/Mathlib/Analysis/CStarAlgebra/Unitization.lean index 3e1ef0b0d4f8ca..7416f4df111b5b 100644 --- a/Mathlib/Analysis/CStarAlgebra/Unitization.lean +++ b/Mathlib/Analysis/CStarAlgebra/Unitization.lean @@ -56,6 +56,7 @@ variable [DenselyNormedField 𝕜] [NonUnitalNormedRing E] [StarRing E] [CStarRi variable [NormedSpace 𝕜 E] [IsScalarTower 𝕜 E E] [SMulCommClass 𝕜 E E] variable (E) +set_option backward.isDefEq.respectTransparency false in /-- A C⋆-algebra over a densely normed field is a regular normed algebra. -/ instance CStarRing.instRegularNormedAlgebra : RegularNormedAlgebra 𝕜 E where isometry_mul' := AddMonoidHomClass.isometry_of_norm (mul 𝕜 E) fun a => NNReal.eq_iff.mp <| diff --git a/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean b/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean index de7602ee46e29c..80260d9ce95518 100644 --- a/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean +++ b/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean @@ -42,6 +42,7 @@ namespace AffineMap variable {𝕜 V : Type*} [NontriviallyNormedField 𝕜] variable [NormedAddCommGroup V] [NormedSpace 𝕜 V] +set_option backward.isDefEq.respectTransparency.types false in /-- `AffineMap.lineMap` is smooth in all three arguments. -/ @[fun_prop] theorem contDiff_lineMap_uncurry {n : WithTop ℕ∞} : @@ -49,6 +50,7 @@ theorem contDiff_lineMap_uncurry {n : WithTop ℕ∞} : simp only [AffineMap.lineMap_apply_module] fun_prop +set_option backward.isDefEq.respectTransparency.types false in /-- `AffineMap.lineMap` is smooth as a function `𝕜 → V`. -/ theorem contDiff_lineMap (p₀ p₁ : V) {n : WithTop ℕ∞} : ContDiff 𝕜 n (AffineMap.lineMap p₀ p₁ : 𝕜 → V) := by @@ -63,6 +65,7 @@ variable [NormedAddCommGroup V] [NormedSpace 𝕜 V] variable [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {f₁ f₂ : E → V} {g : E → 𝕜} {s : Set E} {x : E} {n : WithTop ℕ∞} +set_option backward.isDefEq.respectTransparency.types false in @[fun_prop] theorem ContDiffWithinAt.lineMap (h₁ : ContDiffWithinAt 𝕜 n f₁ s x) (h₂ : ContDiffWithinAt 𝕜 n f₂ s x) (hg : ContDiffWithinAt 𝕜 n g s x) : @@ -70,16 +73,19 @@ theorem ContDiffWithinAt.lineMap (h₁ : ContDiffWithinAt 𝕜 n f₁ s x) simp only [AffineMap.lineMap_apply_module] fun_prop +set_option backward.isDefEq.respectTransparency.types false in theorem ContDiffAt.lineMap (h₁ : ContDiffAt 𝕜 n f₁ x) (h₂ : ContDiffAt 𝕜 n f₂ x) (hg : ContDiffAt 𝕜 n g x) : ContDiffAt 𝕜 n (fun x ↦ AffineMap.lineMap (f₁ x) (f₂ x) (g x)) x := by fun_prop +set_option backward.isDefEq.respectTransparency.types false in theorem ContDiffOn.lineMap (h₁ : ContDiffOn 𝕜 n f₁ s) (h₂ : ContDiffOn 𝕜 n f₂ s) (hg : ContDiffOn 𝕜 n g s) : ContDiffOn 𝕜 n (fun x ↦ AffineMap.lineMap (f₁ x) (f₂ x) (g x)) s := by fun_prop +set_option backward.isDefEq.respectTransparency.types false in theorem ContDiff.lineMap (h₁ : ContDiff 𝕜 n f₁) (h₂ : ContDiff 𝕜 n f₂) (hg : ContDiff 𝕜 n g) : ContDiff 𝕜 n (fun x ↦ AffineMap.lineMap (f₁ x) (f₂ x) (g x)) := by diff --git a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean index 1b47d10f546325..fdc4223dfb61b4 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean @@ -351,6 +351,7 @@ theorem ContinuousLinearEquiv.comp_contDiff_iff (e : F ≃L[𝕜] G) : ContDiff 𝕜 n (e ∘ f) ↔ ContDiff 𝕜 n f := by simp only [← contDiffOn_univ, e.comp_contDiffOn_iff] +set_option backward.isDefEq.respectTransparency false in /-- If `f` admits a Taylor series `p` in a set `s`, and `g` is affine, then `f ∘ g` admits a Taylor series in `g ⁻¹' s`, whose `k`-th term at `x` is given by `p (g x) k (g.contLinear v₁, ..., g.contLinear vₖ)` . -/ diff --git a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean index 44b818599812a4..570b0ff650c60e 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean @@ -442,6 +442,7 @@ lemma index_extendMiddle_zero (c : OrderedFinpartition n) (i : Fin c.length) : contrapose! this exact (c.extendMiddle i).emb_ne_emb_of_ne (Ne.symm this) +set_option backward.isDefEq.respectTransparency false in lemma range_emb_extendMiddle_ne_singleton_zero (c : OrderedFinpartition n) (i j : Fin c.length) : range ((c.extendMiddle i).emb j) ≠ {0} := by intro h diff --git a/Mathlib/Analysis/Calculus/Deriv/AffineMap.lean b/Mathlib/Analysis/Calculus/Deriv/AffineMap.lean index 516a5ea02b5dd0..4cedcd6de95acb 100644 --- a/Mathlib/Analysis/Calculus/Deriv/AffineMap.lean +++ b/Mathlib/Analysis/Calculus/Deriv/AffineMap.lean @@ -62,12 +62,15 @@ In this section we specialize some lemmas to `AffineMap.lineMap` because this ma deduce higher-dimensional lemmas from one-dimensional versions. -/ +set_option backward.isDefEq.respectTransparency false in theorem hasStrictDerivAt_lineMap : HasStrictDerivAt (lineMap a b) (b - a) x := by simpa using (lineMap a b : 𝕜 →ᵃ[𝕜] E).hasStrictDerivAt +set_option backward.isDefEq.respectTransparency false in theorem hasDerivAt_lineMap : HasDerivAt (lineMap a b) (b - a) x := hasStrictDerivAt_lineMap.hasDerivAt +set_option backward.isDefEq.respectTransparency false in theorem hasDerivWithinAt_lineMap : HasDerivWithinAt (lineMap a b) (b - a) s x := hasDerivAt_lineMap.hasDerivWithinAt diff --git a/Mathlib/Analysis/Calculus/Deriv/Basic.lean b/Mathlib/Analysis/Calculus/Deriv/Basic.lean index 7689253f3a151d..99b29818181159 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Basic.lean @@ -912,6 +912,7 @@ variable {σ σ' : RingHom 𝕜 𝕜} [RingHomIsometric σ] [RingHomInvPair σ variable (σ') +set_option backward.isDefEq.respectTransparency false in /-- If `L` is a `σ`-semilinear map, and `f` has Fréchet derivative `f'` at `x`, then `L ∘ f ∘ σ⁻¹` has Fréchet derivative `L ∘ f'` at `σ x`. -/ lemma HasDerivAt.comp_semilinear (hf : HasDerivAt f f' x) : diff --git a/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean b/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean index bb2d7794ab3b86..06e0420d287d97 100644 --- a/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean +++ b/Mathlib/Analysis/Calculus/Deriv/MeanValue.lean @@ -510,6 +510,7 @@ lemma antitone_of_hasDerivAt_nonpos {f f' : ℝ → ℝ} (hf : ∀ x, HasDerivAt variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] +set_option backward.isDefEq.respectTransparency false in /-- Lagrange's **Mean Value Theorem**, applied to convex domains. -/ theorem domain_mvt {f : E → ℝ} {s : Set E} {x y : E} {f' : E → StrongDual ℝ E} (hf : ∀ x ∈ s, HasFDerivWithinAt f (f' x) s x) (hs : Convex ℝ s) (xs : x ∈ s) (ys : y ∈ s) : diff --git a/Mathlib/Analysis/Calculus/Deriv/Star.lean b/Mathlib/Analysis/Calculus/Deriv/Star.lean index 1d0a0f93e6b796..d59765b95981d2 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Star.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Star.lean @@ -34,6 +34,7 @@ section TrivialStar variable [TrivialStar 𝕜] {s : Set 𝕜} {L : Filter (𝕜 × 𝕜)} +set_option backward.isDefEq.respectTransparency.types false in protected theorem HasDerivAtFilter.star (h : HasDerivAtFilter f f' L) : HasDerivAtFilter (fun x => star (f x)) (star f') L := by simpa using h.hasFDerivAtFilter.star.hasDerivAtFilter diff --git a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean index d20869f14aab26..b2d8e8918e7cd9 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean @@ -735,6 +735,7 @@ private lemma _root_.Equiv.succ_embeddingFinSucc_fst_symm_apply {ι : Type*} [De simp_rw [this] simp [-Equiv.embeddingFinSucc_fst] +set_option backward.isDefEq.respectTransparency false in /-- A continuous multilinear function `f` admits a Taylor series, whose successive terms are given by `f.iteratedFDeriv n`. This is the point of the definition of `f.iteratedFDeriv`. -/ theorem hasFTaylorSeriesUpTo_iteratedFDeriv : diff --git a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean index 7c50f225daf795..63fbce1a282eff 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean @@ -212,6 +212,7 @@ variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddComm section include s_conv hf xs hx +set_option backward.isDefEq.respectTransparency false in /-- Assume that `f` is differentiable inside a convex set `s`, and that its derivative `f'` is differentiable at a point `x`. Then, given two vectors `v` and `w` pointing inside `s`, one can Taylor-expand to order two the function `f` on the segment `[x + h v, x + h (v + w)]`, giving a @@ -390,6 +391,7 @@ theorem Convex.second_derivative_within_at_symmetric_of_mem_interior {v w : E} end +set_option backward.isDefEq.respectTransparency false in /-- If a function is differentiable inside a convex set with nonempty interior, and has a second derivative at a point of this convex set, then this second derivative is symmetric. -/ theorem Convex.second_derivative_within_at_symmetric {s : Set E} (s_conv : Convex ℝ s) @@ -457,6 +459,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E F : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup F] [NormedSpace 𝕜 F] {s : Set E} {f : E → F} {x : E} +set_option backward.isDefEq.respectTransparency false in theorem second_derivative_symmetric_of_eventually [IsRCLikeNormedField 𝕜] {f' : E → E →L[𝕜] F} {x : E} {f'' : E →L[𝕜] E →L[𝕜] F} (hf : ∀ᶠ y in 𝓝 x, HasFDerivAt f (f' y) y) diff --git a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean index c868edf4a29c29..316f25b6c87d18 100644 --- a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean +++ b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean @@ -279,6 +279,7 @@ theorem order_zero : (0 : FormalMultilinearSeries 𝕜 E F).order = 0 := by simp theorem ne_zero_of_order_ne_zero (hp : p.order ≠ 0) : p ≠ 0 := fun h => by simp [h] at hp +set_option backward.isDefEq.respectTransparency false in theorem order_eq_find [DecidablePred fun n => p n ≠ 0] (hp : ∃ n, p n ≠ 0) : p.order = Nat.find hp := by convert! Nat.sInf_def hp diff --git a/Mathlib/Analysis/Calculus/Implicit.lean b/Mathlib/Analysis/Calculus/Implicit.lean index c0f66598909a91..53c79482aee0fd 100644 --- a/Mathlib/Analysis/Calculus/Implicit.lean +++ b/Mathlib/Analysis/Calculus/Implicit.lean @@ -419,6 +419,7 @@ theorem implicitFunctionOfComplemented_apply_image (hf : HasStrictFDerivAt f f' (hf.implicitToOpenPartialHomeomorphOfComplemented f f' hf' hker).left_inv (hf.mem_implicitToOpenPartialHomeomorphOfComplemented_source hf' hker) +set_option backward.isDefEq.respectTransparency.types false in theorem to_implicitFunctionOfComplemented (hf : HasStrictFDerivAt f f' a) (hf' : f'.range = ⊤) (hker : f'.ker.ClosedComplemented) : HasStrictFDerivAt (hf.implicitFunctionOfComplemented f f' hf' hker (f a)) diff --git a/Mathlib/Analysis/Calculus/MeanValue.lean b/Mathlib/Analysis/Calculus/MeanValue.lean index de2f76a7db82e1..0cb69990a3dea0 100644 --- a/Mathlib/Analysis/Calculus/MeanValue.lean +++ b/Mathlib/Analysis/Calculus/MeanValue.lean @@ -418,6 +418,7 @@ instance (priority := 100) : PathConnectedSpace 𝕜 := by let : RCLike 𝕜 := IsRCLikeNormedField.rclike 𝕜 infer_instance +set_option backward.isDefEq.respectTransparency false in /-- The mean value theorem on a convex set: if the derivative of a function is bounded by `C`, then the function is `C`-Lipschitz. Version with `HasFDerivWithinAt`. -/ theorem norm_image_sub_le_of_norm_hasFDerivWithin_le diff --git a/Mathlib/Analysis/Complex/AbsMax.lean b/Mathlib/Analysis/Complex/AbsMax.lean index 91fc12726b6e26..469ed7e35a22c3 100644 --- a/Mathlib/Analysis/Complex/AbsMax.lean +++ b/Mathlib/Analysis/Complex/AbsMax.lean @@ -177,6 +177,7 @@ If we do not assume that the codomain is a strictly convex space, then we can on Finally, we generalize the theorem from a disk in `ℂ` to a closed ball in any normed space. -/ +set_option backward.isDefEq.respectTransparency.types false in /-- **Maximum modulus principle** on a closed ball: if `f : E → F` is continuous on a closed ball, is complex differentiable on the corresponding open ball, and the norm `‖f w‖` takes its maximum value on the open ball at its center, then the norm `‖f w‖` is constant on the closed ball. -/ @@ -395,6 +396,7 @@ theorem exists_mem_frontier_isMaxOn_norm [FiniteDimensional ℂ E] {f : E → F} rw [dist_comm, ← hzw] exact ball_infDist_compl_subset.trans interior_subset +set_option backward.isDefEq.respectTransparency.types false in /-- **Maximum modulus principle**: if `f : E → F` is complex differentiable on a bounded set `U` and `‖f z‖ ≤ C` for any `z ∈ frontier U`, then the same is true for any `z ∈ closure U`. -/ theorem norm_le_of_forall_mem_frontier_norm_le {f : E → F} {U : Set E} (hU : IsBounded U) diff --git a/Mathlib/Analysis/Complex/Circle.lean b/Mathlib/Analysis/Complex/Circle.lean index bd8604c8b56d59..86571cd5e4bc74 100644 --- a/Mathlib/Analysis/Complex/Circle.lean +++ b/Mathlib/Analysis/Complex/Circle.lean @@ -69,6 +69,7 @@ lemma coe_inj : (x : ℂ) = y ↔ x = y := coe_injective.eq_iff lemma norm_coe (z : Circle) : ‖(z : ℂ)‖ = 1 := mem_sphere_zero_iff_norm.1 z.2 +set_option backward.isDefEq.respectTransparency false in @[simp] lemma normSq_coe (z : Circle) : normSq z = 1 := by simp [normSq_eq_norm_sq] @[simp] lemma coe_ne_zero (z : Circle) : (z : ℂ) ≠ 0 := ne_zero_of_mem_unit_sphere z @[simp, norm_cast] lemma coe_one : ↑(1 : Circle) = (1 : ℂ) := rfl @@ -154,6 +155,7 @@ lemma exp_pi_ne_one : Circle.exp Real.pi ≠ 1 := by variable {e : AddChar ℝ Circle} +set_option backward.isDefEq.respectTransparency false in @[simp] lemma star_addChar (x : ℝ) : star ((e x) : ℂ) = e (-x) := by have h := Circle.coe_inv_eq_conj ⟨e x, ?_⟩ @@ -192,6 +194,7 @@ instance instContinuousSMul [TopologicalSpace α] [MulAction ℂ α] [Continuous ContinuousSMul Circle α := inferInstanceAs <| ContinuousSMul (Submonoid.unitSphere _) α +set_option backward.isDefEq.respectTransparency false in @[simp] protected lemma norm_smul {E : Type*} [SeminormedAddCommGroup E] [NormedSpace ℂ E] (u : Circle) (v : E) : diff --git a/Mathlib/Analysis/Complex/CoveringMap.lean b/Mathlib/Analysis/Complex/CoveringMap.lean index 2d5b9fa2902f01..120ed764c6945d 100644 --- a/Mathlib/Analysis/Complex/CoveringMap.lean +++ b/Mathlib/Analysis/Complex/CoveringMap.lean @@ -75,6 +75,7 @@ theorem isCoveringMap_npow (n : ℕ) (hn : (n : 𝕜) ≠ 0) : (.setCongr (s := {x | x ≠ 0}) _) using 1 ext; simp [show n ≠ 0 by aesop] +set_option backward.isDefEq.respectTransparency false in /-- `(· ^ n) : 𝕜 \ {0} → 𝕜 \ {0}` is a covering map (if `n ≠ 0` in `𝕜`). -/ theorem isCoveringMap_zpow (n : ℤ) (hn : (n : 𝕜) ≠ 0) : IsCoveringMap fun x : {x : 𝕜 // x ≠ 0} ↦ (⟨x ^ n, zpow_ne_zero n x.2⟩ : {x : 𝕜 // x ≠ 0}) := by diff --git a/Mathlib/Analysis/Complex/Exponential.lean b/Mathlib/Analysis/Complex/Exponential.lean index 1bf61e0671053f..b5c9a8950bdd3d 100644 --- a/Mathlib/Analysis/Complex/Exponential.lean +++ b/Mathlib/Analysis/Complex/Exponential.lean @@ -91,6 +91,7 @@ namespace Complex variable (x y : ℂ) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem exp_zero : exp 0 = 1 := by rw [exp] @@ -106,6 +107,7 @@ theorem exp_zero : exp 0 = 1 := by simp only [sum_range_succ, pow_succ] simp +set_option backward.isDefEq.respectTransparency false in theorem exp_add : exp (x + y) = exp x * exp y := by have hj : ∀ j : ℕ, (∑ m ∈ range j, (x + y) ^ m / m.factorial) = ∑ i ∈ range j, ∑ k ∈ range (i + 1), x ^ k / k.factorial * diff --git a/Mathlib/Analysis/Complex/Hadamard.lean b/Mathlib/Analysis/Complex/Hadamard.lean index 1e1878d2c7da4f..edd044f8b102af 100644 --- a/Mathlib/Analysis/Complex/Hadamard.lean +++ b/Mathlib/Analysis/Complex/Hadamard.lean @@ -147,6 +147,7 @@ lemma norm_lt_sSupNormIm_eps (f : ℂ → E) (ε : ℝ) (hε : ε > 0) (z : ℂ) variable [NormedSpace ℂ E] +set_option backward.isDefEq.respectTransparency.types false in /-- When the function `f` is bounded above on a vertical strip, then so is `F`. -/ lemma F_BddAbove (f : ℂ → E) (ε : ℝ) (hε : ε > 0) (hB : BddAbove ((norm ∘ f) '' verticalClosedStrip 0 1)) : diff --git a/Mathlib/Analysis/Complex/Isometry.lean b/Mathlib/Analysis/Complex/Isometry.lean index 8deafc5101dd26..7255b9f218c94c 100644 --- a/Mathlib/Analysis/Complex/Isometry.lean +++ b/Mathlib/Analysis/Complex/Isometry.lean @@ -43,6 +43,7 @@ open ComplexConjugate local notation "|" x "|" => Complex.abs x +set_option backward.isDefEq.respectTransparency.types false in /-- An element of the unit circle defines a `LinearIsometryEquiv` from `ℂ` to itself, by rotation. -/ def rotation : Circle →* ℂ ≃ₗᵢ[ℝ] ℂ where @@ -80,6 +81,7 @@ unit circle. -/ def rotationOf (e : ℂ ≃ₗᵢ[ℝ] ℂ) : Circle := ⟨e 1 / ‖e 1‖, by simp [Submonoid.unitSphere]⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem rotationOf_rotation (a : Circle) : rotationOf (rotation a) = a := Subtype.ext <| by simp @@ -125,6 +127,7 @@ theorem linear_isometry_complex_aux {f : ℂ ≃ₗᵢ[ℝ] ℂ} (h : f 1 = 1) : intro i fin_cases i <;> simp [h, h'] +set_option backward.isDefEq.respectTransparency false in theorem linear_isometry_complex (f : ℂ ≃ₗᵢ[ℝ] ℂ) : ∃ a : Circle, f = rotation a ∨ f = conjLIE.trans (rotation a) := by let a : Circle := ⟨f 1, by simp [Submonoid.unitSphere, f.norm_map]⟩ diff --git a/Mathlib/Analysis/Complex/JensenFormula.lean b/Mathlib/Analysis/Complex/JensenFormula.lean index cf6c3caf6b36d5..2a77d6e24c4392 100644 --- a/Mathlib/Analysis/Complex/JensenFormula.lean +++ b/Mathlib/Analysis/Complex/JensenFormula.lean @@ -267,6 +267,7 @@ lemma AnalyticOnNhd.circleAverage_log_norm_of_ne_zero {R : ℝ} {c : ℂ} {g : circleAverage (Real.log ‖g ·‖) c R = Real.log ‖g c‖ := HarmonicOnNhd.circleAverage_eq (fun x hx ↦ (h₁g x hx).harmonicAt_log_norm (h₂g x hx)) +set_option backward.isDefEq.respectTransparency.types false in /-- Reformulation of a finsum that appears in Jensen's formula and in the definition of the counting function of Value Distribution Theory, as discussed in diff --git a/Mathlib/Analysis/Complex/Norm.lean b/Mathlib/Analysis/Complex/Norm.lean index 7c04b44f1a7d9e..0898fb3ad035a8 100644 --- a/Mathlib/Analysis/Complex/Norm.lean +++ b/Mathlib/Analysis/Complex/Norm.lean @@ -338,6 +338,7 @@ theorem isCauSeq_conj (f : CauSeq ℂ (‖·‖)) : noncomputable def cauSeqConj (f : CauSeq ℂ (‖·‖)) : CauSeq ℂ (‖·‖) := ⟨_, isCauSeq_conj f⟩ +set_option backward.isDefEq.respectTransparency false in theorem lim_conj (f : CauSeq ℂ (‖·‖)) : lim (cauSeqConj f) = conj (lim f) := Complex.ext (by simp [cauSeqConj, (lim_re _).symm, cauSeqRe]) (by simp [cauSeqConj, (lim_im _).symm, cauSeqIm, (lim_neg _).symm]; rfl) diff --git a/Mathlib/Analysis/Complex/OpenMapping.lean b/Mathlib/Analysis/Complex/OpenMapping.lean index bf2e6ef5658fbf..1b5b168f78ab24 100644 --- a/Mathlib/Analysis/Complex/OpenMapping.lean +++ b/Mathlib/Analysis/Complex/OpenMapping.lean @@ -264,6 +264,7 @@ theorem isOpenQuotientMap_pow_compl_zero (n : ℕ) [NeZero n] : isOpenMap := (IsOpen.isOpenEmbedding_subtypeVal isClosed_singleton.1).isOpenMap_iff.mpr <| (isOpenQuotientMap_pow n).isOpenMap.comp isClosed_singleton.1.isOpenMap_subtype_val +set_option backward.isDefEq.respectTransparency.types false in theorem isOpenQuotientMap_zpow_compl_zero (n : ℤ) [NeZero n] : IsOpenQuotientMap fun z : {z : ℂ // z ≠ 0} ↦ (⟨z ^ n, zpow_ne_zero n z.2⟩ : {z : ℂ // z ≠ 0}) := by diff --git a/Mathlib/Analysis/Complex/Schwarz.lean b/Mathlib/Analysis/Complex/Schwarz.lean index 075078ce6ae7c6..a6d138a4634249 100644 --- a/Mathlib/Analysis/Complex/Schwarz.lean +++ b/Mathlib/Analysis/Complex/Schwarz.lean @@ -133,6 +133,7 @@ variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] [NormedAddCommGroup F] [NormedSpace ℂ F] {R R₁ R₂ : ℝ} {f : E → F} {c z : E} +set_option backward.isDefEq.respectTransparency.types false in open AffineMap in /-- Let `f : E → F` be a complex analytic map sending an open ball of radius `R₁` to a closed ball of radius `R₂`. diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/FunctionsBoundedAtInfty.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/FunctionsBoundedAtInfty.lean index 8ff78c4ba9a762..80937009c27d53 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/FunctionsBoundedAtInfty.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/FunctionsBoundedAtInfty.lean @@ -75,6 +75,7 @@ theorem IsZeroAtImInfty.isBoundedAtImInfty {α : Type*} [SeminormedAddGroup α] (hf : IsZeroAtImInfty f) : IsBoundedAtImInfty f := hf.boundedAtFilter +set_option backward.isDefEq.respectTransparency false in lemma tendsto_comap_im_ofComplex : Tendsto ofComplex (comap Complex.im atTop) atImInfty := by simp only [atImInfty, tendsto_comap_iff, Function.comp_def] diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean index aaa307340c876b..2a6802881c52d1 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Metric.lean @@ -109,7 +109,7 @@ theorem dist_le_dist_coe_div_sqrt (z w : ℍ) : dist z w ≤ dist (z : ℂ) w / /-- An auxiliary `MetricSpace` instance on the upper half-plane. This instance has bad projection to `TopologicalSpace`. We replace it later. -/ -@[implicit_reducible] +@[instance_reducible] def metricSpaceAux : MetricSpace ℍ where dist := dist dist_self z := by rw [dist_eq, dist_self, zero_div, arsinh_zero, mul_zero] diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean index 91ed0eb715979c..64c4be3caf4e8a 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean @@ -107,6 +107,7 @@ lemma σ_num (g h : GL (Fin 2) ℝ) (z : ℂ) : σ g (num h z) = num h (σ g z) lemma σ_denom (g h : GL (Fin 2) ℝ) (z : ℂ) : σ g (denom h z) = denom h (σ g z) := by simp [denom] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma σ_neg (g : GL (Fin 2) ℝ) : σ (-g) = σ g := by simp [σ, det_neg] @@ -205,6 +206,7 @@ lemma glPos_smul_def {g : GL (Fin 2) ℝ} (hg : 0 < g.det.val) (z : ℍ) : section GLAction variable (g : GL (Fin 2) ℝ) (z : ℍ) +set_option backward.isDefEq.respectTransparency false in theorem re_smul : (g • z).re = (num g z / denom g z).re := by change (smulAux' g z).re = _ simp +contextual [smulAux', σ, DFunLike.ite_apply, apply_ite, Complex.div_re] @@ -314,6 +316,7 @@ theorem modular_T_zpow_smul (z : ℍ) (n : ℤ) : ModularGroup.T ^ n • z = (n theorem modular_T_smul (z : ℍ) : ModularGroup.T • z = (1 : ℝ) +ᵥ z := by simpa only [zpow_one, Int.cast_one] using modular_T_zpow_smul z 1 +set_option backward.isDefEq.respectTransparency false in theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : g 1 0 = 0) : ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc @@ -322,6 +325,7 @@ theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : g 1 suffices ↑a * z * a + b * a = b * a + a * a * z by simpa [specialLinearGroup_apply, add_mul] ring +set_option backward.isDefEq.respectTransparency false in theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : g 1 0 ≠ 0) : ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ), (g • · : ℍ → ℍ) = @@ -472,6 +476,7 @@ theorem im_smul_eq_div_normSq : (g • z).im = z.im / Complex.normSq (denom g z) theorem denom_apply : denom g z = g 1 0 * z + g 1 1 := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma denom_S : denom S z = z := by simp [S, denom_apply] end SLModularAction diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/ProperAction.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/ProperAction.lean index aa9604b24b4f2c..bbedde98d9180b 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/ProperAction.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/ProperAction.lean @@ -32,6 +32,7 @@ theorem num_continuous : Continuous ↿num := by unfold num; fun_prop @[fun_prop] theorem denom_continuous : Continuous ↿denom := by unfold denom; fun_prop +set_option backward.isDefEq.respectTransparency.types false in lemma continuous_toSL2R : Continuous toSL2R := by apply continuous_induced_rng.mpr simp only [Function.comp_def, coe_toSL2R] diff --git a/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean b/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean index a4a7141a25b97c..d51c71156612ef 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean @@ -58,6 +58,7 @@ lemma characteristic_sub_characteristic_inv (h : Meromorphic f) : _ = circleAverage (log ‖f ·‖) 0 - (divisor f Set.univ).logCounting := by rw [← ValueDistribution.log_counting_zero_sub_logCounting_top] +set_option backward.isDefEq.respectTransparency.types false in /-- Helper lemma for the first part of the First Main Theorem: Away from zero, the difference between the characteristic functions of `f` and `f⁻¹` equals `log ‖meromorphicTrailingCoeffAt f 0‖`. diff --git a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean index 14f6c3a5f03b14..6c1d5ecc89d496 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean @@ -101,6 +101,7 @@ variable ## Logarithmic Counting Functions for the Poles of a Meromorphic Function -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A meromorphic function has only removable singularities if and only if the logarithmic counting function for its pole divisor is asymptotically bounded. diff --git a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean index 23e9f3735672a1..3700500be779d7 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Basic.lean @@ -59,6 +59,7 @@ noncomputable def toClosedBall (r : ℝ) : apply restrictMonoidHom tauto +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toClosedBall_eval_within {r : ℝ} {z : E} (f : locallyFinsupp E ℤ) (ha : z ∈ closedBall 0 |r|) : @@ -66,11 +67,13 @@ lemma toClosedBall_eval_within {r : ℝ} {z : E} (f : locallyFinsupp E ℤ) unfold toClosedBall simp_all [restrict_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toClosedBall_divisor {r : ℝ} {f : ℂ → ℂ} (h : Meromorphic f) : (divisor f (closedBall 0 |r|)) = (locallyFinsuppWithin.toClosedBall r) (divisor f univ) := by simp_all [locallyFinsuppWithin.toClosedBall] +set_option backward.isDefEq.respectTransparency.types false in lemma toClosedBall_support_subset_closedBall {E : Type*} [NormedAddCommGroup E] {r : ℝ} (f : locallyFinsupp E ℤ) : (toClosedBall r f).support ⊆ closedBall 0 |r| := by @@ -124,6 +127,7 @@ Evaluation of the logarithmic counting function at zero yields zero. logCounting D 0 = 0 := by simp [logCounting] +set_option backward.isDefEq.respectTransparency.types false in /-- The logarithmic counting function of a singleton indicator is asymptotically equal to `log · - log ‖e‖`. @@ -147,6 +151,7 @@ The logarithmic counting function of a singleton indicator is asymptotically equ ### Elementary Properties of Logarithmic Counting Functions -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The logarithmic counting function is even. -/ diff --git a/Mathlib/Analysis/Convex/Basic.lean b/Mathlib/Analysis/Convex/Basic.lean index 14ef4e4268b6b4..17234e3fd906d0 100644 --- a/Mathlib/Analysis/Convex/Basic.lean +++ b/Mathlib/Analysis/Convex/Basic.lean @@ -477,10 +477,12 @@ theorem Convex.smul_mem_of_zero_mem (hs : Convex 𝕜 s) {x : E} (zero_mem : (0 {t : 𝕜} (ht : t ∈ Icc (0 : 𝕜) 1) : t • x ∈ s := by simpa using hs.add_smul_mem zero_mem (by simpa using hx) ht +set_option backward.isDefEq.respectTransparency false in theorem Convex.mapsTo_lineMap (h : Convex 𝕜 s) {x y : E} (hx : x ∈ s) (hy : y ∈ s) : MapsTo (AffineMap.lineMap x y) (Icc (0 : 𝕜) 1) s := by simpa only [mapsTo_iff_image_subset, segment_eq_image_lineMap] using h.segment_subset hx hy +set_option backward.isDefEq.respectTransparency false in theorem Convex.lineMap_mem (h : Convex 𝕜 s) {x y : E} (hx : x ∈ s) (hy : y ∈ s) {t : 𝕜} (ht : t ∈ Icc 0 1) : AffineMap.lineMap x y t ∈ s := h.mapsTo_lineMap hx hy ht diff --git a/Mathlib/Analysis/Convex/Between.lean b/Mathlib/Analysis/Convex/Between.lean index 644e30e935d809..a35ca6cd637a24 100644 --- a/Mathlib/Analysis/Convex/Between.lean +++ b/Mathlib/Analysis/Convex/Between.lean @@ -34,6 +34,7 @@ open AffineEquiv AffineMap Module section OrderedRing +set_option backward.isDefEq.respectTransparency false in /-- The segment of points weakly between `x` and `y`. When convexity is refactored to support abstract affine combination spaces, this will no longer need to be a separate definition from `segment`. However, lemmas involving `+ᵥ` or `-ᵥ` will still be relevant after such a @@ -350,6 +351,7 @@ theorem Sbtw.ne_right {x y z : P} (h : Sbtw R x y z) : y ≠ z := theorem Sbtw.right_ne {x y z : P} (h : Sbtw R x y z) : z ≠ y := h.2.2.symm +set_option backward.isDefEq.respectTransparency false in theorem Sbtw.mem_image_Ioo {x y z : P} (h : Sbtw R x y z) : y ∈ lineMap x z '' Set.Ioo (0 : R) 1 := by rcases h with ⟨⟨t, ht, rfl⟩, hyx, hyz⟩ @@ -378,6 +380,7 @@ theorem wbtw_self_left (x y : P) : Wbtw R x x y := theorem wbtw_self_right (x y : P) : Wbtw R x y y := right_mem_affineSegment _ _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem wbtw_self_iff {x y : P} : Wbtw R x y x ↔ y = x := by refine ⟨fun h => ?_, fun h => ?_⟩ @@ -478,6 +481,7 @@ theorem Wbtw.trans_right {w x y z : P} (h₁ : Wbtw R w x z) (h₂ : Wbtw R x y section IsTorsionFree variable [IsDomain R] [IsTorsionFree R V] {w x y z : P} {r : R} +set_option backward.isDefEq.respectTransparency false in theorem sbtw_iff_mem_image_Ioo_and_ne : Sbtw R x y z ↔ y ∈ lineMap x z '' Set.Ioo (0 : R) 1 ∧ x ≠ z := by refine ⟨fun h => ⟨h.mem_image_Ioo, h.left_ne_right⟩, fun h => ?_⟩ @@ -536,6 +540,7 @@ theorem Sbtw.not_swap_right (h : Sbtw R x y z) : ¬Wbtw R x z y := fun hs => theorem Sbtw.not_rotate (h : Sbtw R x y z) : ¬Wbtw R z x y := fun hs => h.left_ne (h.wbtw.rotate_iff.1 hs) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem wbtw_lineMap_iff : Wbtw R x (lineMap x y r) y ↔ x = y ∨ r ∈ Set.Icc (0 : R) 1 := by @@ -544,6 +549,7 @@ theorem wbtw_lineMap_iff : simp rw [or_iff_right hxy, Wbtw, affineSegment, (lineMap_injective R hxy).mem_set_image] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem sbtw_lineMap_iff : Sbtw R x (lineMap x y r) y ↔ x ≠ y ∧ r ∈ Set.Ioo (0 : R) 1 := by @@ -672,6 +678,7 @@ lemma mem_closedInterior_face_iff_wbtw {n : ℕ} (s : Simplex R P n) {p : P} {i p ∈ (s.face (Finset.card_pair h)).closedInterior ↔ Wbtw R (s.points i) p (s.points j) := by rw [s.closedInterior_face_eq_affineSegment h, Wbtw] +set_option backward.isDefEq.respectTransparency false in /-- The interior of a 1-simplex is a segment between its vertices. -/ lemma interior_eq_image_Ioo (s : Simplex R P 1) : s.interior = AffineMap.lineMap (s.points 0) (s.points 1) '' Set.Ioo (0 : R) 1 := by @@ -845,6 +852,7 @@ lemma Wbtw.of_le_of_le {x y z : R} (hxy : x ≤ y) (hyz : y ≤ z) : Wbtw R x y lemma Sbtw.of_lt_of_lt {x y z : R} (hxy : x < y) (hyz : y < z) : Sbtw R x y z := ⟨.of_le_of_le hxy.le hyz.le, hxy.ne', hyz.ne⟩ +set_option backward.isDefEq.respectTransparency false in theorem wbtw_iff_left_eq_or_right_mem_image_Ici {x y z : P} : Wbtw R x y z ↔ x = y ∨ z ∈ lineMap x y '' Set.Ici (1 : R) := by refine ⟨fun h => ?_, fun h => ?_⟩ @@ -862,6 +870,7 @@ theorem wbtw_iff_left_eq_or_right_mem_image_Ici {x y z : P} : simp only [lineMap_apply, smul_smul, vadd_vsub] rw [inv_mul_cancel₀ (one_pos.trans_le hr).ne', one_smul, vsub_vadd] +set_option backward.isDefEq.respectTransparency false in theorem Wbtw.right_mem_image_Ici_of_left_ne {x y z : P} (h : Wbtw R x y z) (hne : x ≠ y) : z ∈ lineMap x y '' Set.Ici (1 : R) := (wbtw_iff_left_eq_or_right_mem_image_Ici.1 h).resolve_left hne @@ -871,6 +880,7 @@ theorem Wbtw.right_mem_affineSpan_of_left_ne {x y z : P} (h : Wbtw R x y z) (hne rcases h.right_mem_image_Ici_of_left_ne hne with ⟨r, ⟨-, rfl⟩⟩ exact lineMap_mem_affineSpan_pair _ _ _ +set_option backward.isDefEq.respectTransparency false in theorem sbtw_iff_left_ne_and_right_mem_image_Ioi {x y z : P} : Sbtw R x y z ↔ x ≠ y ∧ z ∈ lineMap x y '' Set.Ioi (1 : R) := by refine ⟨fun h => ⟨h.left_ne, ?_⟩, fun h => ?_⟩ @@ -890,6 +900,7 @@ theorem sbtw_iff_left_ne_and_right_mem_image_Ioi {x y z : P} : rw [← sub_smul, smul_ne_zero_iff, vsub_ne_zero, sub_ne_zero] exact ⟨hr.ne, hne.symm⟩ +set_option backward.isDefEq.respectTransparency false in theorem Sbtw.right_mem_image_Ioi {x y z : P} (h : Sbtw R x y z) : z ∈ lineMap x y '' Set.Ioi (1 : R) := (sbtw_iff_left_ne_and_right_mem_image_Ioi.1 h).2 @@ -897,10 +908,12 @@ theorem Sbtw.right_mem_image_Ioi {x y z : P} (h : Sbtw R x y z) : theorem Sbtw.right_mem_affineSpan {x y z : P} (h : Sbtw R x y z) : z ∈ line[R, x, y] := h.wbtw.right_mem_affineSpan_of_left_ne h.left_ne +set_option backward.isDefEq.respectTransparency false in theorem wbtw_iff_right_eq_or_left_mem_image_Ici {x y z : P} : Wbtw R x y z ↔ z = y ∨ x ∈ lineMap z y '' Set.Ici (1 : R) := by rw [wbtw_comm, wbtw_iff_left_eq_or_right_mem_image_Ici] +set_option backward.isDefEq.respectTransparency false in theorem Wbtw.left_mem_image_Ici_of_right_ne {x y z : P} (h : Wbtw R x y z) (hne : z ≠ y) : x ∈ lineMap z y '' Set.Ici (1 : R) := h.symm.right_mem_image_Ici_of_left_ne hne @@ -909,10 +922,12 @@ theorem Wbtw.left_mem_affineSpan_of_right_ne {x y z : P} (h : Wbtw R x y z) (hne x ∈ line[R, z, y] := h.symm.right_mem_affineSpan_of_left_ne hne +set_option backward.isDefEq.respectTransparency false in theorem sbtw_iff_right_ne_and_left_mem_image_Ioi {x y z : P} : Sbtw R x y z ↔ z ≠ y ∧ x ∈ lineMap z y '' Set.Ioi (1 : R) := by rw [sbtw_comm, sbtw_iff_left_ne_and_right_mem_image_Ioi] +set_option backward.isDefEq.respectTransparency false in theorem Sbtw.left_mem_image_Ioi {x y z : P} (h : Sbtw R x y z) : x ∈ lineMap z y '' Set.Ioi (1 : R) := h.symm.right_mem_image_Ioi diff --git a/Mathlib/Analysis/Convex/BetweenList.lean b/Mathlib/Analysis/Convex/BetweenList.lean index a25c94db1e5dc7..29a4d496154948 100644 --- a/Mathlib/Analysis/Convex/BetweenList.lean +++ b/Mathlib/Analysis/Convex/BetweenList.lean @@ -187,6 +187,7 @@ lemma SortedLE.wbtw {l : List R} (h : l.SortedLE) : l.Wbtw R := by lemma SortedLT.sbtw {l : List R} (h : l.SortedLT) : l.Sbtw R := ⟨h.sortedLE.wbtw, h.nodup⟩ +set_option backward.isDefEq.respectTransparency false in lemma exists_map_eq_of_sorted_nonempty_iff_wbtw {l : List P} (hl : l ≠ []) : (∃ l' : List R, l'.SortedLE ∧ l'.map (lineMap (l.head hl) (l.getLast hl)) = l) ↔ l.Wbtw R := by @@ -236,6 +237,7 @@ lemma exists_map_eq_of_sorted_nonempty_iff_wbtw {l : List P} (hl : l ≠ []) : ring_nf simp +set_option backward.isDefEq.respectTransparency false in lemma exists_map_eq_of_sorted_iff_wbtw {l : List P} : (∃ p₁ p₂ : P, ∃ l' : List R, l'.SortedLE ∧ l'.map (lineMap p₁ p₂) = l) ↔ l.Wbtw R := by refine ⟨fun ⟨p₁, p₂, l', hl's, hl'l⟩ ↦ ?_, fun h ↦ ?_⟩ @@ -246,6 +248,7 @@ lemma exists_map_eq_of_sorted_iff_wbtw {l : List P} : simp [hl, sortedLE_iff_pairwise]⟩ · exact ⟨l.head hl, l.getLast hl, (exists_map_eq_of_sorted_nonempty_iff_wbtw hl).2 h⟩ +set_option backward.isDefEq.respectTransparency false in lemma exists_map_eq_of_sorted_nonempty_iff_sbtw {l : List P} (hl : l ≠ []) : (∃ l' : List R, l'.SortedLT ∧ l'.map (lineMap (l.head hl) (l.getLast hl)) = l ∧ (l.length = 1 ∨ l.head hl ≠ l.getLast hl)) ↔ l.Sbtw R := by @@ -275,6 +278,7 @@ lemma exists_map_eq_of_sorted_nonempty_iff_sbtw {l : List P} (hl : l ≠ []) : refine hp.1 ((head :: head2 :: tail).getLast hl) ?_ simp +set_option backward.isDefEq.respectTransparency false in lemma exists_map_eq_of_sorted_iff_sbtw [Nontrivial P] {l : List P} : (∃ p₁ p₂ : P, p₁ ≠ p₂ ∧ ∃ l' : List R, l'.SortedLT ∧ l'.map (lineMap p₁ p₂) = l) ↔ l.Sbtw R := by diff --git a/Mathlib/Analysis/Convex/Birkhoff.lean b/Mathlib/Analysis/Convex/Birkhoff.lean index 50306eb9c6a471..da7a700e58d1ac 100644 --- a/Mathlib/Analysis/Convex/Birkhoff.lean +++ b/Mathlib/Analysis/Convex/Birkhoff.lean @@ -44,6 +44,7 @@ section LinearOrderedSemifield variable [Semifield R] [LinearOrder R] [IsStrictOrderedRing R] {M : Matrix n n R} +set_option backward.isDefEq.respectTransparency.types false in /-- If M is a positive scalar multiple of a doubly stochastic matrix, then there is a permutation matrix whose support is contained in the support of M. diff --git a/Mathlib/Analysis/Convex/Cone/Extension.lean b/Mathlib/Analysis/Convex/Cone/Extension.lean index 234e879eb8eb5a..7e8d5664f4e685 100644 --- a/Mathlib/Analysis/Convex/Cone/Extension.lean +++ b/Mathlib/Analysis/Convex/Cone/Extension.lean @@ -152,6 +152,7 @@ theorem riesz_extension (s : PointedCone ℝ E) (f : E →ₗ.[ℝ] ℝ) · exact fun x => (hfg rfl).symm · exact fun x hx => hgs ⟨x, _⟩ hx +set_option backward.isDefEq.respectTransparency false in /-- **Hahn-Banach theorem**: if `N : E → ℝ` is a sublinear map, `f` is a linear map defined on a subspace of `E`, and `f x ≤ N x` for all `x` in the domain of `f`, then `f` can be extended to the whole space to a linear map `g` such that `g x ≤ N x` diff --git a/Mathlib/Analysis/Convex/Cone/TensorProduct.lean b/Mathlib/Analysis/Convex/Cone/TensorProduct.lean index b3b1cc6bb9d9c6..aac863151f7f11 100644 --- a/Mathlib/Analysis/Convex/Cone/TensorProduct.lean +++ b/Mathlib/Analysis/Convex/Cone/TensorProduct.lean @@ -81,6 +81,7 @@ variable [FiniteDimensional ℝ F] [ContinuousSMul ℝ F] [LocallyConvexSpace open TensorProduct Module +set_option backward.isDefEq.respectTransparency false in /-- If `C₁` is a simplicial and generating cone and `C₂` is a proper cone, then their minimal and maximal tensor products are equal. -/ theorem minTensorProduct_eq_max_of_simplicial_generating_left (C₁ : PointedCone ℝ E) diff --git a/Mathlib/Analysis/Convex/Hull.lean b/Mathlib/Analysis/Convex/Hull.lean index e2371780e052f8..ba9b983894e36a 100644 --- a/Mathlib/Analysis/Convex/Hull.lean +++ b/Mathlib/Analysis/Convex/Hull.lean @@ -52,6 +52,7 @@ theorem subset_convexHull : s ⊆ convexHull 𝕜 s := theorem convex_convexHull : Convex 𝕜 (convexHull 𝕜 s) := (convexHull 𝕜).isClosed_closure s +set_option backward.isDefEq.respectTransparency false in theorem convexHull_eq_iInter : convexHull 𝕜 s = ⋂ (t : Set E) (_ : s ⊆ t) (_ : Convex 𝕜 t), t := by simp [convexHull, iInter_subtype, iInter_and] diff --git a/Mathlib/Analysis/Convex/Independent.lean b/Mathlib/Analysis/Convex/Independent.lean index 3d6cb5cfb16e1a..c6e5858a1e69b2 100644 --- a/Mathlib/Analysis/Convex/Independent.lean +++ b/Mathlib/Analysis/Convex/Independent.lean @@ -87,6 +87,7 @@ protected theorem ConvexIndependent.subtype {p : ι → E} (hc : ConvexIndepende ConvexIndependent 𝕜 fun i : s => p i := hc.comp_embedding (Embedding.subtype _) +set_option backward.isDefEq.respectTransparency false in /-- If an indexed family of points is convex independent, so is the corresponding set of points. -/ protected theorem ConvexIndependent.range {p : ι → E} (hc : ConvexIndependent 𝕜 p) : ConvexIndependent 𝕜 ((↑) : Set.range p → E) := by diff --git a/Mathlib/Analysis/Convex/Intrinsic.lean b/Mathlib/Analysis/Convex/Intrinsic.lean index d57a8c3d9b594a..479217a8826312 100644 --- a/Mathlib/Analysis/Convex/Intrinsic.lean +++ b/Mathlib/Analysis/Convex/Intrinsic.lean @@ -232,6 +232,7 @@ section ImageOfHomeomorphAffineSpan variable [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace Q] [AddTorsor W Q] {f : P → Q} {s : Set P} +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` agrees with a homeomorphism between the affine spans of `s` and `f '' s`, then pulling `f '' s` back to the affine span of `s` recovers `s` itself. -/ private theorem preimage_image_eq_of_homeomorph_affineSpan diff --git a/Mathlib/Analysis/Convex/NNReal.lean b/Mathlib/Analysis/Convex/NNReal.lean index 269ce781e9c774..47a6a01e75b3fd 100644 --- a/Mathlib/Analysis/Convex/NNReal.lean +++ b/Mathlib/Analysis/Convex/NNReal.lean @@ -35,6 +35,7 @@ protected lemma segment_eq_uIcc {x y : ℝ≥0} : segment ℝ≥0 x y = uIcc x y := Nonneg.segment_eq_uIcc +set_option backward.isDefEq.respectTransparency false in protected lemma convex_iff {M : Type*} [AddCommMonoid M] [Module ℝ M] {s : Set M} : Convex ℝ≥0 s ↔ Convex ℝ s := by refine ⟨fun H ↦ ?_, Convex.lift ℝ≥0⟩ diff --git a/Mathlib/Analysis/Convex/PathConnected.lean b/Mathlib/Analysis/Convex/PathConnected.lean index d42bac5955b2e9..dbd84861469cb4 100644 --- a/Mathlib/Analysis/Convex/PathConnected.lean +++ b/Mathlib/Analysis/Convex/PathConnected.lean @@ -30,6 +30,7 @@ variable {E : Type*} [AddCommGroup E] [Module ℝ E] namespace Path +set_option backward.isDefEq.respectTransparency false in /-- The path from `a` to `b` going along a straight line segment -/ @[simps] protected def segment (a b : E) : Path a b where @@ -61,6 +62,7 @@ theorem cast_segment {a b c d : E} (hac : c = a) (hbd : d = b) : (Path.segment a b).cast hac hbd = .segment c d := by subst_vars; rfl +set_option backward.isDefEq.respectTransparency false in theorem eqOn_extend_segment (a b : E) : EqOn (Path.segment a b).extend (AffineMap.lineMap a b) I := by intro t ht @@ -119,12 +121,14 @@ theorem isPathConnected_compl_of_isPathConnected_compl_zero {p q : Submodule ℝ section Real +set_option backward.isDefEq.respectTransparency.types false in theorem segment_image_Ico {x y : ℝ} (h : x < y) : (Path.segment x y) '' Ico 0 1 = Ico x y := by simp_rw [Path.segment_apply, ← image_image _ Subtype.val (Ico 0 1)] simp only [lineMap_apply, vsub_eq_sub, smul_eq_mul, vadd_eq_add, image_subtype_val_Ico, Icc.coe_zero, Icc.coe_one] convert! image_affine_Ico (sub_pos_of_lt h) x 0 1 using 2 <;> ring +set_option backward.isDefEq.respectTransparency.types false in theorem segment_image_Ioc {x y : ℝ} (h : x < y) : (Path.segment x y) '' Ioc 0 1 = Ioc x y := by simp_rw [Path.segment_apply, ← image_image _ Subtype.val (Ioc 0 1)] simp only [lineMap_apply, vsub_eq_sub, smul_eq_mul, vadd_eq_add, image_subtype_val_Ioc, diff --git a/Mathlib/Analysis/Convex/Segment.lean b/Mathlib/Analysis/Convex/Segment.lean index 59bbbd65c0192f..e80914f1504ac1 100644 --- a/Mathlib/Analysis/Convex/Segment.lean +++ b/Mathlib/Analysis/Convex/Segment.lean @@ -216,20 +216,24 @@ theorem openSegment_eq_image' (x y : E) : simp only [smul_sub, sub_smul, one_smul] abel +set_option backward.isDefEq.respectTransparency false in theorem segment_eq_image_lineMap (x y : E) : [x -[𝕜] y] = AffineMap.lineMap x y '' Icc (0 : 𝕜) 1 := by convert segment_eq_image 𝕜 x y exact AffineMap.lineMap_apply_module _ _ _ +set_option backward.isDefEq.respectTransparency false in theorem openSegment_eq_image_lineMap (x y : E) : openSegment 𝕜 x y = AffineMap.lineMap x y '' Ioo (0 : 𝕜) 1 := by convert openSegment_eq_image 𝕜 x y exact AffineMap.lineMap_apply_module _ _ _ +set_option backward.isDefEq.respectTransparency false in theorem lineMap_mem_openSegment (a b : E) {t : 𝕜} (ht : t ∈ Ioo 0 1) : AffineMap.lineMap a b t ∈ openSegment 𝕜 a b := openSegment_eq_image_lineMap 𝕜 a b ▸ mem_image_of_mem _ ht +set_option backward.isDefEq.respectTransparency.types false in theorem lineMap_mem_segment (a b : E) {t : 𝕜} (ht : t ∈ Icc 0 1) : AffineMap.lineMap a b t ∈ [a -[𝕜] b] := segment_eq_image_lineMap 𝕜 a b ▸ mem_image_of_mem _ ht @@ -417,6 +421,7 @@ theorem mem_segment_iff_sameRay : x ∈ [y -[𝕜] z] ↔ SameRay 𝕜 (x - y) ( open AffineMap +set_option backward.isDefEq.respectTransparency false in /-- If `z = lineMap x y c` is a point on the line passing through `x` and `y`, then the open segment `openSegment 𝕜 x y` is included in the union of the open segments `openSegment 𝕜 x z`, `openSegment 𝕜 z y`, and the point `z`. Informally, `(x, y) ⊆ {z} ∪ (x, z) ∪ (z, y)`. -/ diff --git a/Mathlib/Analysis/Convex/Side.lean b/Mathlib/Analysis/Convex/Side.lean index 3a8f2fc1e56e81..93871abdbfb71a 100644 --- a/Mathlib/Analysis/Convex/Side.lean +++ b/Mathlib/Analysis/Convex/Side.lean @@ -286,10 +286,12 @@ theorem wSameSide_smul_vsub_vadd_right {s : AffineSubspace R P} {p₁ p₂ : P} (hp₂ : p₂ ∈ s) {t : R} (ht : 0 ≤ t) : s.WSameSide x (t • (x -ᵥ p₁) +ᵥ p₂) := (wSameSide_smul_vsub_vadd_left x hp₁ hp₂ ht).symm +set_option backward.isDefEq.respectTransparency false in theorem wSameSide_lineMap_left {s : AffineSubspace R P} {x : P} (y : P) (h : x ∈ s) {t : R} (ht : 0 ≤ t) : s.WSameSide (lineMap x y t) y := wSameSide_smul_vsub_vadd_left y h h ht +set_option backward.isDefEq.respectTransparency false in theorem wSameSide_lineMap_right {s : AffineSubspace R P} {x : P} (y : P) (h : x ∈ s) {t : R} (ht : 0 ≤ t) : s.WSameSide y (lineMap x y t) := (wSameSide_lineMap_left y h ht).symm @@ -304,10 +306,12 @@ theorem wOppSide_smul_vsub_vadd_right {s : AffineSubspace R P} {p₁ p₂ : P} ( (hp₂ : p₂ ∈ s) {t : R} (ht : t ≤ 0) : s.WOppSide x (t • (x -ᵥ p₁) +ᵥ p₂) := (wOppSide_smul_vsub_vadd_left x hp₁ hp₂ ht).symm +set_option backward.isDefEq.respectTransparency false in theorem wOppSide_lineMap_left {s : AffineSubspace R P} {x : P} (y : P) (h : x ∈ s) {t : R} (ht : t ≤ 0) : s.WOppSide (lineMap x y t) y := wOppSide_smul_vsub_vadd_left y h h ht +set_option backward.isDefEq.respectTransparency false in theorem wOppSide_lineMap_right {s : AffineSubspace R P} {x : P} (y : P) (h : x ∈ s) {t : R} (ht : t ≤ 0) : s.WOppSide y (lineMap x y t) := (wOppSide_lineMap_left y h ht).symm @@ -611,6 +615,7 @@ theorem SOppSide.not_sSameSide {s : AffineSubspace R P} {x y : P} (h : s.SOppSid ¬s.SSameSide x y := fun hs => h.not_wSameSide hs.1 +set_option backward.isDefEq.respectTransparency false in theorem wOppSide_iff_exists_wbtw {s : AffineSubspace R P} {x y : P} : s.WOppSide x y ↔ ∃ p ∈ s, Wbtw R x p y := by refine ⟨fun h => ?_, fun ⟨p, hp, h⟩ => h.wOppSide₁₃ hp⟩ @@ -665,10 +670,12 @@ theorem sSameSide_smul_vsub_vadd_right {s : AffineSubspace R P} {x p₁ p₂ : P (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) {t : R} (ht : 0 < t) : s.SSameSide x (t • (x -ᵥ p₁) +ᵥ p₂) := (sSameSide_smul_vsub_vadd_left hx hp₁ hp₂ ht).symm +set_option backward.isDefEq.respectTransparency false in theorem sSameSide_lineMap_left {s : AffineSubspace R P} {x y : P} (hx : x ∈ s) (hy : y ∉ s) {t : R} (ht : 0 < t) : s.SSameSide (lineMap x y t) y := sSameSide_smul_vsub_vadd_left hy hx hx ht +set_option backward.isDefEq.respectTransparency false in theorem sSameSide_lineMap_right {s : AffineSubspace R P} {x y : P} (hx : x ∈ s) (hy : y ∉ s) {t : R} (ht : 0 < t) : s.SSameSide y (lineMap x y t) := (sSameSide_lineMap_left hx hy ht).symm @@ -683,10 +690,12 @@ theorem sOppSide_smul_vsub_vadd_right {s : AffineSubspace R P} {x p₁ p₂ : P} (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) {t : R} (ht : t < 0) : s.SOppSide x (t • (x -ᵥ p₁) +ᵥ p₂) := (sOppSide_smul_vsub_vadd_left hx hp₁ hp₂ ht).symm +set_option backward.isDefEq.respectTransparency false in theorem sOppSide_lineMap_left {s : AffineSubspace R P} {x y : P} (hx : x ∈ s) (hy : y ∉ s) {t : R} (ht : t < 0) : s.SOppSide (lineMap x y t) y := sOppSide_smul_vsub_vadd_left hy hx hx ht +set_option backward.isDefEq.respectTransparency false in theorem sOppSide_lineMap_right {s : AffineSubspace R P} {x y : P} (hx : x ∈ s) (hy : y ∉ s) {t : R} (ht : t < 0) : s.SOppSide y (lineMap x y t) := (sOppSide_lineMap_left hx hy ht).symm @@ -870,6 +879,7 @@ open AffineSubspace variable [Field R] [LinearOrder R] [IsStrictOrderedRing R] [AddCommGroup V] [Module R V] variable [AddTorsor V P] {n : ℕ} [NeZero n] (s : Simplex R P n) +set_option backward.isDefEq.respectTransparency false in lemma sSameSide_affineSpan_faceOpposite_of_sign_eq {w₁ w₂ : Fin (n + 1) → R} (hw₁ : ∑ j, w₁ j = 1) (hw₂ : ∑ j, w₂ j = 1) {i : Fin (n + 1)} (hs : SignType.sign (w₁ i) = SignType.sign (w₂ i)) (h0 : w₁ i ≠ 0) : @@ -900,6 +910,7 @@ lemma sSameSide_affineSpan_faceOpposite_of_sign_eq {w₁ w₂ : Fin (n + 1) → · rw [sign_pos h, eq_comm, sign_eq_one_iff] at hs positivity +set_option backward.isDefEq.respectTransparency false in lemma sOppSide_affineSpan_faceOpposite_of_pos_of_neg {w₁ w₂ : Fin (n + 1) → R} (hw₁ : ∑ j, w₁ j = 1) (hw₂ : ∑ j, w₂ j = 1) {i : Fin (n + 1)} (hs₁ : 0 < w₁ i) (hs₂ : w₂ i < 0) : diff --git a/Mathlib/Analysis/Convex/StrictConvexBetween.lean b/Mathlib/Analysis/Convex/StrictConvexBetween.lean index 139a6b8534b7ef..43ca1ad16da523 100644 --- a/Mathlib/Analysis/Convex/StrictConvexBetween.lean +++ b/Mathlib/Analysis/Convex/StrictConvexBetween.lean @@ -111,6 +111,7 @@ variable {E F PE PF : Type*} [NormedAddCommGroup E] [NormedAddCommGroup F] [Norm [NormedSpace ℝ F] [StrictConvexSpace ℝ E] [MetricSpace PE] [MetricSpace PF] [NormedAddTorsor E PE] [NormedAddTorsor F PF] {r : ℝ} {f : PF → PE} {x y z : PE} +set_option backward.isDefEq.respectTransparency false in lemma eq_lineMap_of_dist_eq_mul_of_dist_eq_mul (hxy : dist x y = r * dist x z) (hyz : dist y z = (1 - r) * dist x z) : y = AffineMap.lineMap x z r := by have : y -ᵥ x ∈ [(0 : E) -[ℝ] z -ᵥ x] := by diff --git a/Mathlib/Analysis/Convex/Topology.lean b/Mathlib/Analysis/Convex/Topology.lean index dd7f46f360e724..07962ce9a65c4a 100644 --- a/Mathlib/Analysis/Convex/Topology.lean +++ b/Mathlib/Analysis/Convex/Topology.lean @@ -220,6 +220,7 @@ variable [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] open AffineMap +set_option backward.isDefEq.respectTransparency false in /-- A convex set `s` is strictly convex provided that for any two distinct points of `s \ interior s`, the line passing through these points has nonempty intersection with `interior s`. -/ @@ -514,6 +515,7 @@ variable {𝕜 V P : Type*} [Module 𝕜 V] [ContinuousSMul 𝕜 V] [AddTorsor V P] [TopologicalSpace P] [IsTopologicalAddTorsor P] +set_option backward.isDefEq.respectTransparency false in /-- The closed interior of a simplex is compact. -/ theorem isCompact_closedInterior {n : ℕ} (s : Simplex 𝕜 P n) : IsCompact s.closedInterior := by suffices IsCompact ((AffineEquiv.vaddConst 𝕜 (s.points 0)).symm.toAffineMap '' diff --git a/Mathlib/Analysis/Convex/Visible.lean b/Mathlib/Analysis/Convex/Visible.lean index 9d475f297a2126..9a078867d40442 100644 --- a/Mathlib/Analysis/Convex/Visible.lean +++ b/Mathlib/Analysis/Convex/Visible.lean @@ -57,6 +57,7 @@ omit [IsOrderedRing 𝕜] in lemma IsVisible.mono (hst : s ⊆ t) (ht : IsVisible 𝕜 t x y) : IsVisible 𝕜 s x y := fun _z hz ↦ ht <| hst hz +set_option backward.isDefEq.respectTransparency false in lemma isVisible_iff_lineMap (hxy : x ≠ y) : IsVisible 𝕜 s x y ↔ ∀ δ ∈ Set.Ioo (0 : 𝕜) 1, lineMap x y δ ∉ s := by simp [IsVisible, sbtw_iff_mem_image_Ioo_and_ne, hxy] @@ -68,6 +69,7 @@ section Module variable [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] [AddCommGroup V] [Module 𝕜 V] {s : Set V} {x y z : V} +set_option backward.isDefEq.respectTransparency false in /-- If a point `x` sees a convex combination of points of a set `s` through `convexHull ℝ s ∌ x`, then it sees all terms of that combination. @@ -119,6 +121,7 @@ lemma IsVisible.of_convexHull_of_pos {ι : Type*} {t : Finset ι} {a : ι → V} variable [TopologicalSpace 𝕜] [OrderTopology 𝕜] [TopologicalSpace V] [IsTopologicalAddGroup V] [ContinuousSMul 𝕜 V] +set_option backward.isDefEq.respectTransparency false in /-- One cannot see any point in the interior of a set. -/ lemma IsVisible.eq_of_mem_interior (hsxy : IsVisible 𝕜 s x y) (hy : y ∈ interior s) : x = y := by @@ -155,6 +158,7 @@ lemma IsVisible.mem_convexHull_isVisible (hx : x ∉ convexHull ℝ s) (hy : y variable [TopologicalSpace V] [IsTopologicalAddGroup V] [ContinuousSMul ℝ V] +set_option backward.isDefEq.respectTransparency false in /-- If `s` is a closed set, then any point `x` sees some point of `s` in any direction where there is something to see. -/ lemma IsClosed.exists_wbtw_isVisible (hs : IsClosed s) (hy : y ∈ s) (x : V) : diff --git a/Mathlib/Analysis/Distribution/TestFunction.lean b/Mathlib/Analysis/Distribution/TestFunction.lean index 1069c26c593bde..93e58459dfd467 100644 --- a/Mathlib/Analysis/Distribution/TestFunction.lean +++ b/Mathlib/Analysis/Distribution/TestFunction.lean @@ -257,7 +257,7 @@ limit of the `𝓓^{n}_{K}(E, F)`s **in the category of topological spaces**. Note that this has no reason to be a locally convex (or even vector space) topology. For this reason, we actually endow `𝓓^{n}(Ω, F)` with another topology, namely the finest locally convex topology which is coarser than this original topology. See `TestFunction.topologicalSpace`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def originalTop : TopologicalSpace 𝓓^{n}(Ω, F) := ⨆ (K : Compacts E) (K_sub_Ω : (K : Set E) ⊆ Ω), coinduced (ofSupportedIn K_sub_Ω) ContDiffMapSupportedIn.topologicalSpace @@ -410,6 +410,7 @@ lemma toBoundedContinuousFunctionCLM_eq_of_scalars [Algebra ℝ 𝕜] [IsScalarT (toBoundedContinuousFunctionCLM 𝕜 : 𝓓^{n}(Ω, F) → _) = toBoundedContinuousFunctionCLM 𝕜' := rfl +set_option backward.isDefEq.respectTransparency false in variable (𝕜) in theorem injective_toBoundedContinuousFunctionCLM [Algebra ℝ 𝕜] [IsScalarTower ℝ 𝕜 F] : Function.Injective (toBoundedContinuousFunctionCLM 𝕜 : 𝓓^{n}(Ω, F) →L[𝕜] E →ᵇ F) := @@ -456,6 +457,7 @@ section Monotone variable [Algebra ℝ 𝕜] [IsScalarTower ℝ 𝕜 F] +set_option backward.isDefEq.respectTransparency false in variable (𝕜) in /-- If `n₁ ≥ n₂` and `Ω₁ ⊆ Ω₂`, `monoCLM 𝕜` is the continuous `𝕜`-linear inclusion of `𝓓^{n₁}(Ω₁, F)` inside `𝓓^{n₂}(Ω₂, F)`. Otherwise, this is the zero map. @@ -500,6 +502,7 @@ section FDerivCLM variable [Algebra ℝ 𝕜] [IsScalarTower ℝ 𝕜 F] +set_option backward.isDefEq.respectTransparency false in variable (𝕜 n k) in /-- `fderivCLM 𝕜 n k` is the continuous `𝕜`-linear-map sending `f : 𝓓^{n}_{K}(E, F)` to its derivative as an element of `𝓓^{k}_{K}(E, E →L[ℝ] F)`. diff --git a/Mathlib/Analysis/Fourier/AddCircle.lean b/Mathlib/Analysis/Fourier/AddCircle.lean index 7a045982cec4ca..3f5c6ed72797f5 100644 --- a/Mathlib/Analysis/Fourier/AddCircle.lean +++ b/Mathlib/Analysis/Fourier/AddCircle.lean @@ -225,6 +225,7 @@ theorem fourierSubalgebra_coe : variable [hT : Fact (0 < T)] +set_option backward.isDefEq.respectTransparency.types false in /-- The subalgebra of `C(AddCircle T, ℂ)` generated by `fourier n` for `n ∈ ℤ` separates points. -/ theorem fourierSubalgebra_separatesPoints : (@fourierSubalgebra T).SeparatesPoints := by diff --git a/Mathlib/Analysis/Fourier/AddCircleMulti.lean b/Mathlib/Analysis/Fourier/AddCircleMulti.lean index 545f515ec4278c..08ab569e1977c4 100644 --- a/Mathlib/Analysis/Fourier/AddCircleMulti.lean +++ b/Mathlib/Analysis/Fourier/AddCircleMulti.lean @@ -111,6 +111,7 @@ theorem mFourierSubalgebra_coe : simp only [mFourier, Pi.add_apply, fourier_apply, fourier_add', Finset.prod_mul_distrib, ContinuousMap.coe_mk, ContinuousMap.mul_apply] +set_option backward.isDefEq.respectTransparency.types false in /-- The subalgebra of `C(UnitAddTorus d, ℂ)` generated by `mFourier n` for `n ∈ ℤᵈ` separates points. -/ theorem mFourierSubalgebra_separatesPoints : (mFourierSubalgebra d).SeparatesPoints := by diff --git a/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean b/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean index 4a05c33c3b103a..508771150864a1 100644 --- a/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean +++ b/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean @@ -48,6 +48,7 @@ variable {V W : Type*} [AddCommGroup V] [Module ℝ V] [TopologicalSpace V] {e : AddChar ℝ Circle} {L : V →ₗ[ℝ] W →ₗ[ℝ] ℝ} {he : Continuous e} {hL : Continuous fun p : V × W ↦ L p.1 p.2} +set_option backward.isDefEq.respectTransparency false in /-- The bounded continuous mapping `fun v ↦ e (L v w)` from `V` to `ℂ`. -/ noncomputable def char (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) (w : W) : V →ᵇ ℂ where @@ -106,6 +107,7 @@ noncomputable def charMonoidHom (he : Continuous e) (hL : Continuous fun p : V map_one' := char_zero_eq_one map_mul' := char_add_eq_mul (he := he) (hL := hL) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma charMonoidHom_apply (w : Multiplicative W) (v : V) : charMonoidHom he hL w v = e (L v w.toAdd) := by simp [charMonoidHom] @@ -122,6 +124,7 @@ lemma charAlgHom_apply (w : AddMonoidAlgebra ℂ W) (v : V) : simp [charAlgHom, charMonoidHom, char, AddMonoidAlgebra.lift_apply] simp [Finsupp.sum] +set_option backward.isDefEq.respectTransparency false in /-- The family of `ℂ`-linear combinations of `char he hL w, w : W`, is closed under `star`. -/ lemma star_mem_range_charAlgHom (he : Continuous e) (hL : Continuous fun p : V × W ↦ L p.1 p.2) {x : V →ᵇ ℂ} (hx : x ∈ (charAlgHom he hL).range) : diff --git a/Mathlib/Analysis/Fourier/PoissonSummation.lean b/Mathlib/Analysis/Fourier/PoissonSummation.lean index 67d7184c603604..0f6216336f57dc 100644 --- a/Mathlib/Analysis/Fourier/PoissonSummation.lean +++ b/Mathlib/Analysis/Fourier/PoissonSummation.lean @@ -46,6 +46,7 @@ open scoped Real Filter FourierTransform open ContinuousMap +set_option backward.isDefEq.respectTransparency.types false in /-- The key lemma for Poisson summation: the `m`-th Fourier coefficient of the periodic function `∑' n : ℤ, f (x + n)` is the value at `m` of the Fourier transform of `f`. -/ theorem Real.fourierCoeff_tsum_comp_add {f : C(ℝ, ℂ)} diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index 8cf730c18282a2..d9ed9660d2ea58 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -170,7 +170,10 @@ theorem _root_.LinearMap.IsSymmetric.clm_adjoint_eq {A : E →L[𝕜] E} (hA : A A† = A := by rwa [eq_comm, eq_adjoint_iff A A] +set_option backward.isDefEq.respectTransparency.types false in lemma adjoint_id : (.id 𝕜 E)† = .id 𝕜 E := by simp + +set_option backward.isDefEq.respectTransparency.types false in lemma adjoint_one : (1 : E →L[𝕜] E)† = 1 := by simp theorem _root_.Submodule.adjoint_subtypeL (U : Submodule 𝕜 E) [CompleteSpace U] : @@ -416,6 +419,7 @@ but with stronger type class assumptions (i.e., `CompleteSpace`). -/ theorem IsStarNormal.orthogonal_range (hT : IsStarNormal T) : T.rangeᗮ = T.ker := T.orthogonal_range ▸ hT.ker_adjoint_eq_ker +set_option backward.isDefEq.respectTransparency false in /- TODO: As we have a more general result of this for elements in non-unital C⋆-algebras (see `Mathlib/Analysis/CStarAlgebra/Projection.lean`), we will want to simplify the proof by using the complexification of an inner product space over `𝕜`. -/ @@ -900,6 +904,7 @@ theorem conjStarAlgEquiv_trans {G : Type*} [NormedAddCommGroup G] [InnerProductS [CompleteSpace G] (e : H ≃ₗᵢ[𝕜] K) (f : K ≃ₗᵢ[𝕜] G) : (e.trans f).conjStarAlgEquiv = e.conjStarAlgEquiv.trans f.conjStarAlgEquiv := rfl +set_option backward.isDefEq.respectTransparency false in open ContinuousLinearEquiv ContinuousLinearMap in theorem conjStarAlgEquiv_ext_iff (f g : H ≃ₗᵢ[𝕜] K) : f.conjStarAlgEquiv = g.conjStarAlgEquiv ↔ ∃ α : unitary 𝕜, f = α • g := by diff --git a/Mathlib/Analysis/InnerProductSpace/Affine.lean b/Mathlib/Analysis/InnerProductSpace/Affine.lean index e621f5659fc205..99ffb7cb2a45bd 100644 --- a/Mathlib/Analysis/InnerProductSpace/Affine.lean +++ b/Mathlib/Analysis/InnerProductSpace/Affine.lean @@ -62,6 +62,7 @@ theorem inner_vsub_vsub_right_eq_dist_sq_right_iff {a b c : P} : ⟪a -ᵥ c, b -ᵥ c⟫ = dist b c ^ 2 ↔ ⟪a -ᵥ b, b -ᵥ c⟫ = 0 := by rw [real_inner_comm, inner_vsub_vsub_right_eq_dist_sq_left_iff, real_inner_comm] +set_option backward.isDefEq.respectTransparency false in /-- Squared distance between two points on lines from a common origin, given orthogonality of the direction vectors. -/ theorem dist_sq_lineMap_lineMap_of_inner_eq_zero {a b c : P} (t₁ t₂ : ℝ) @@ -75,6 +76,7 @@ theorem dist_sq_lineMap_lineMap_of_inner_eq_zero {a b c : P} (t₁ t₂ : ℝ) Real.norm_eq_abs, Real.norm_eq_abs, inner_smul_left, inner_smul_right, h_inner] simp only [mul_zero, sub_zero, mul_pow, sq_abs, ← dist_eq_norm_vsub' V] +set_option backward.isDefEq.respectTransparency false in /-- Squared distance from `p` to a point on the line from `a` to `b`, given that `p -ᵥ a` is orthogonal to `b -ᵥ a`. -/ theorem dist_sq_lineMap_of_inner_eq_zero {a b p : P} (t : ℝ) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index cc210a09b4d727..df294ad3a92695 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -928,7 +928,7 @@ local notation "⟪" x ", " y "⟫" => inner 𝕜 x y /-- A general inner product implies a real inner product. This is not registered as an instance since `𝕜` does not appear in the return type `Inner ℝ E`. -/ -@[implicit_reducible] +@[instance_reducible] def Inner.rclikeToReal : Inner ℝ E where inner x y := re ⟪x, y⟫ /-- A general inner product space structure implies a real inner product structure. @@ -967,7 +967,7 @@ theorem real_inner_I_smul_self (x : E) : /-- A complex inner product implies a real inner product. This cannot be an instance since it creates a diamond with `PiLp.innerProductSpace` because `re (sum i, ⟪x i, y i⟫)` and `sum i, re ⟪x i, y i⟫` are not defeq. -/ -@[implicit_reducible] +@[instance_reducible] def InnerProductSpace.complexToReal [SeminormedAddCommGroup G] [InnerProductSpace ℂ G] : InnerProductSpace ℝ G := InnerProductSpace.rclikeToReal ℂ G diff --git a/Mathlib/Analysis/InnerProductSpace/Defs.lean b/Mathlib/Analysis/InnerProductSpace/Defs.lean index 7c03c08f0564e5..2d3af1339eb534 100644 --- a/Mathlib/Analysis/InnerProductSpace/Defs.lean +++ b/Mathlib/Analysis/InnerProductSpace/Defs.lean @@ -171,7 +171,7 @@ instance (𝕜 : Type*) (F : Type*) [RCLike 𝕜] [AddCommGroup F] `PreInnerProductSpace.Core` for `PreInnerProductSpace`s. Note that the `Seminorm` instance provided by `PreInnerProductSpace.Core.norm` is propositionally but not definitionally equal to the original norm. -/ -@[implicit_reducible] +@[instance_reducible] def PreInnerProductSpace.toCore [SeminormedAddCommGroup E] [c : InnerProductSpace 𝕜 E] : PreInnerProductSpace.Core 𝕜 E where __ := c @@ -181,7 +181,7 @@ def PreInnerProductSpace.toCore [SeminormedAddCommGroup E] [c : InnerProductSpac `InnerProductSpace.Core` for `InnerProductSpace`s. Note that the `Norm` instance provided by `InnerProductSpace.Core.norm` is propositionally but not definitionally equal to the original norm. -/ -@[implicit_reducible] +@[instance_reducible] def InnerProductSpace.toCore [NormedAddCommGroup E] [c : InnerProductSpace 𝕜 E] : InnerProductSpace.Core 𝕜 E := { c with @@ -413,7 +413,7 @@ attribute [local instance] toSeminormedAddCommGroup /-- Normed space (which is actually a seminorm in general) structure constructed from a `PreInnerProductSpace.Core` structure -/ -@[implicit_reducible] +@[instance_reducible] def toNormedSpace : NormedSpace 𝕜 F where norm_smul_le r x := by rw [norm_eq_sqrt_re_inner, inner_smul_left, inner_smul_right, ← mul_assoc] @@ -565,7 +565,7 @@ attribute [local instance] InnerProductSpace.Core.toSeminormedAddCommGroup the space into a pre-inner product space (i.e., `SeminormedAddCommGroup` and `InnerProductSpace`). The `SeminormedAddCommGroup` structure is expected to already be defined with `InnerProductSpace.ofCore.toSeminormedAddCommGroup`. -/ -@[implicit_reducible] +@[instance_reducible] def InnerProductSpace.ofCore [AddCommGroup F] [Module 𝕜 F] (cd : PreInnerProductSpace.Core 𝕜 F) : InnerProductSpace 𝕜 F := letI : NormedSpace 𝕜 F := InnerProductSpace.Core.toNormedSpace @@ -580,7 +580,7 @@ end /-- Given an `InnerProductSpace.Core` structure on a space with a topology, one can use it to turn the space into an inner product space. The `NormedAddCommGroup` structure is expected to already be defined with `InnerProductSpace.ofCore.toNormedAddCommGroupOfTopology`. -/ -@[implicit_reducible] +@[instance_reducible] def InnerProductSpace.ofCoreOfTopology [AddCommGroup F] [hF : Module 𝕜 F] [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousConstSMul 𝕜 F] (cd : InnerProductSpace.Core 𝕜 F) diff --git a/Mathlib/Analysis/InnerProductSpace/LinearMap.lean b/Mathlib/Analysis/InnerProductSpace/LinearMap.lean index 79f8dfa984ef81..16e5a58b1a8fe4 100644 --- a/Mathlib/Analysis/InnerProductSpace/LinearMap.lean +++ b/Mathlib/Analysis/InnerProductSpace/LinearMap.lean @@ -49,6 +49,7 @@ section Complex_Seminormed variable {V : Type*} [SeminormedAddCommGroup V] [InnerProductSpace ℂ V] +set_option backward.isDefEq.respectTransparency false in /-- A complex polarization identity, with a linear map. -/ theorem inner_map_polarization (T : V →ₗ[ℂ] V) (x y : V) : ⟪T y, x⟫_ℂ = @@ -61,6 +62,7 @@ theorem inner_map_polarization (T : V →ₗ[ℂ] V) (x y : V) : mul_add, ← mul_assoc, mul_neg, neg_neg, one_mul, neg_one_mul, mul_sub, sub_sub] ring +set_option backward.isDefEq.respectTransparency false in theorem inner_map_polarization' (T : V →ₗ[ℂ] V) (x y : V) : ⟪T x, y⟫_ℂ = (⟪T (x + y), x + y⟫_ℂ - ⟪T (x - y), x - y⟫_ℂ - @@ -107,6 +109,7 @@ variable {ι : Type*} {ι' : Type*} {ι'' : Type*} variable {E' : Type*} [SeminormedAddCommGroup E'] [InnerProductSpace 𝕜 E'] variable {E'' : Type*} [SeminormedAddCommGroup E''] [InnerProductSpace 𝕜 E''] +set_option backward.isDefEq.respectTransparency false in /-- A linear isometry preserves the inner product. -/ @[simp] theorem LinearIsometry.inner_map_map (f : E →ₗᵢ[𝕜] E') (x y : E) : ⟪f x, f y⟫ = ⟪x, y⟫ := by @@ -278,6 +281,7 @@ theorem ContinuousLinearMap.reApplyInnerSelf_continuous (T : E →L[𝕜] E) : Continuous T.reApplyInnerSelf := reCLM.continuous.comp <| T.continuous.inner continuous_id +set_option backward.isDefEq.respectTransparency false in theorem ContinuousLinearMap.reApplyInnerSelf_smul (T : E →L[𝕜] E) (x : E) {c : 𝕜} : T.reApplyInnerSelf (c • x) = ‖c‖ ^ 2 * T.reApplyInnerSelf x := by simp only [map_smul, ContinuousLinearMap.reApplyInnerSelf_apply, inner_smul_left, @@ -356,6 +360,7 @@ variable {F H : Type*} [NormedAddCommGroup F] [InnerProductSpace 𝕜 F] lemma rankOne_ne_zero {x : E} {y : F} (hx : x ≠ 0) (hy : y ≠ 0) : rankOne 𝕜 x y ≠ 0 := by grind [rankOne_eq_zero] +set_option backward.isDefEq.respectTransparency false in theorem isIdempotentElem_rankOne_self_iff {x : F} (hx : x ≠ 0) : IsIdempotentElem (rankOne 𝕜 x x) ↔ ‖x‖ = 1 := by refine ⟨?_, isIdempotentElem_rankOne_self⟩ diff --git a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean index da112f39df47a6..31ca1a91cbfd0c 100644 --- a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean +++ b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean @@ -169,6 +169,7 @@ theorem mem_adjoint_domain_of_exists (y : F) (h : ∃ w : E, ∀ x : T.domain, convert this exact funext fun x => (hw x).symm +set_option backward.isDefEq.respectTransparency false in theorem adjoint_apply_of_not_dense (hT : ¬Dense (T.domain : Set E)) (y : T†.domain) : T† y = 0 := by classical change (if hT : Dense (T.domain : Set E) then adjointAux hT else 0) y = _ @@ -206,6 +207,7 @@ namespace ContinuousLinearMap variable [CompleteSpace E] [CompleteSpace F] variable (A : E →L[𝕜] F) {p : Submodule 𝕜 E} +set_option backward.isDefEq.respectTransparency false in /-- Restricting `A` to a dense submodule and taking the `LinearPMap.adjoint` is the same as taking the `ContinuousLinearMap.adjoint` interpreted as a `LinearPMap`. -/ theorem toPMap_adjoint_eq_adjoint_toPMap_of_dense (hp : Dense (p : Set E)) : diff --git a/Mathlib/Analysis/InnerProductSpace/OfNorm.lean b/Mathlib/Analysis/InnerProductSpace/OfNorm.lean index aca1a98baa557c..b68ffaac404059 100644 --- a/Mathlib/Analysis/InnerProductSpace/OfNorm.lean +++ b/Mathlib/Analysis/InnerProductSpace/OfNorm.lean @@ -203,7 +203,7 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- **Fréchet–von Neumann–Jordan Theorem**. A normed space `E` whose norm satisfies the parallelogram identity can be given a compatible inner product. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def InnerProductSpace.ofNorm (h : ∀ x y : E, ‖x + y‖ * ‖x + y‖ + ‖x - y‖ * ‖x - y‖ = 2 * (‖x‖ * ‖x‖ + ‖y‖ * ‖y‖)) : InnerProductSpace 𝕜 E := diff --git a/Mathlib/Analysis/InnerProductSpace/Orientation.lean b/Mathlib/Analysis/InnerProductSpace/Orientation.lean index 8dcdff2be957b9..84c7293803a8d9 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orientation.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orientation.lean @@ -181,6 +181,7 @@ theorem volumeForm_zero_pos [_i : Fact (finrank ℝ E = 0)] : AlternatingMap.constLinearEquivOfIsEmpty 1 := by simp [volumeForm, Or.by_cases] +set_option backward.isDefEq.respectTransparency.types false in theorem volumeForm_zero_neg [_i : Fact (finrank ℝ E = 0)] : Orientation.volumeForm (-positiveOrientation : Orientation ℝ E (Fin 0)) = -AlternatingMap.constLinearEquivOfIsEmpty 1 := by diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index bf7f2c14dd78e5..bda2a2fcf4d0f0 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -403,6 +403,7 @@ theorem repr_injective : cases g congr +set_option backward.isDefEq.respectTransparency false in /-- `b i` is the `i`th basis vector. -/ instance instFunLike : FunLike (OrthonormalBasis ι 𝕜 E) ι E where coe b i := by classical exact b.repr.symm (EuclideanSpace.single i (1 : 𝕜)) @@ -854,6 +855,7 @@ lemma equiv_self_rfl : b.equiv b (.refl ι) = .refl 𝕜 E := by apply b.toBasis.ext_linearIsometryEquiv simp +set_option backward.isDefEq.respectTransparency false in lemma equiv_apply (x : E) : b.equiv b' e x = ∑ i, b.repr x i • b' (e i) := by nth_rw 1 [← b.sum_repr x, map_sum] simp_rw [map_smul, equiv_apply_basis] @@ -1314,6 +1316,7 @@ theorem InnerProductSpace.toMatrix_rankOne {𝕜 E F ι ι' : Type*} [RCLike Basis.coe_singleton, Matrix.vecMulVec_one, OrthonormalBasis.coe_singleton, star_one, Matrix.one_vecMulVec, Matrix.vecMulVec_eq Unit] +set_option backward.isDefEq.respectTransparency false in open Matrix LinearMap EuclideanSpace in theorem InnerProductSpace.symm_toEuclideanLin_rankOne {𝕜 m n : Type*} [RCLike 𝕜] [Fintype m] [Fintype n] [DecidableEq n] (x : EuclideanSpace 𝕜 m) (y : EuclideanSpace 𝕜 n) : diff --git a/Mathlib/Analysis/InnerProductSpace/Positive.lean b/Mathlib/Analysis/InnerProductSpace/Positive.lean index d1897b0d8e8c05..578903d5970774 100644 --- a/Mathlib/Analysis/InnerProductSpace/Positive.lean +++ b/Mathlib/Analysis/InnerProductSpace/Positive.lean @@ -199,6 +199,7 @@ theorem isPositive_linearIsometryEquiv_conj_iff {T : E →ₗ[𝕜] E} (f : E Function.comp_apply, LinearIsometryEquiv.inner_map_eq_flip] exact fun _ => ⟨fun h x => by simpa using h (f x), fun h x => h _⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- `A.toEuclideanLin` is positive if and only if `A` is positive semi-definite. -/ @[simp] theorem _root_.Matrix.isPositive_toEuclideanLin_iff {n : Type*} [Fintype n] [DecidableEq n] {A : Matrix n n 𝕜} : A.toEuclideanLin.IsPositive ↔ A.PosSemidef := by diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean b/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean index cfa7199aec6241..ea6dcd1f2fa6d0 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/FiniteDimensional.lean @@ -308,6 +308,7 @@ theorem OrthogonalFamily.projection_directSum_coeAddHom [DecidableEq ι] {V : ι simp_rw [map_add] exact congr_arg₂ (· + ·) hx hy +set_option backward.isDefEq.respectTransparency false in /-- If a family of submodules is orthogonal and they span the whole space, then the orthogonal projection provides a means to decompose the space into its submodules. diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean index 84a98a95f9bd85..926a3377f845b4 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Reflection.lean @@ -39,6 +39,7 @@ def reflectionLinearEquiv : E ≃ₗ[𝕜] E := (2 • (K.starProjection.toLinearMap) - LinearMap.id) fun x => by simp [two_smul, starProjection_eq_self_iff.mpr] +set_option backward.isDefEq.respectTransparency false in /-- Reflection in a complete subspace of an inner product space. The word "reflection" is sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes more generally to cover operations such as reflection in a point. The definition here, of diff --git a/Mathlib/Analysis/InnerProductSpace/Reproducing.lean b/Mathlib/Analysis/InnerProductSpace/Reproducing.lean index afe6444ebe321c..1591e3e66d5f6e 100644 --- a/Mathlib/Analysis/InnerProductSpace/Reproducing.lean +++ b/Mathlib/Analysis/InnerProductSpace/Reproducing.lean @@ -150,6 +150,7 @@ bounded by `‖f‖` times the square root of the kernel diagonal `‖kernel H x lemma norm_apply_le (f : H) (x : X) : ‖f x‖ ≤ ‖f‖ * √‖kernel H x x‖ := by grw [← adjoint_kerFun, le_opNorm, norm_map, norm_kerFun_eq_sqrt_norm_kernel, mul_comm] +set_option backward.isDefEq.respectTransparency.types false in /-- The span of the kernel functions is dense. -/ theorem kerFun_dense : topologicalClosure (span 𝕜 {kerFun H x v | (x) (v)}) = ⊤ := by refine (orthogonal_eq_bot_iff.mp ((Submodule.eq_bot_iff _).mpr fun f fin ↦ DFunLike.ext f 0 ?_)) diff --git a/Mathlib/Analysis/InnerProductSpace/Subspace.lean b/Mathlib/Analysis/InnerProductSpace/Subspace.lean index 573d4c57e659df..7b76274671b706 100644 --- a/Mathlib/Analysis/InnerProductSpace/Subspace.lean +++ b/Mathlib/Analysis/InnerProductSpace/Subspace.lean @@ -99,6 +99,7 @@ theorem OrthogonalFamily.eq_ite [DecidableEq ι] {i j : ι} (v : G i) (w : G j) · rfl · exact hV h v w +set_option backward.isDefEq.respectTransparency false in theorem OrthogonalFamily.inner_right_dfinsupp [∀ (i) (x : G i), Decidable (x ≠ 0)] [DecidableEq ι] (l : ⨁ i, G i) (i : ι) (v : G i) : ⟪V i v, l.sum fun j => V j⟫ = ⟪v, l i⟫ := diff --git a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean index 4509f6fb9bcfd1..b24cdba2128f95 100644 --- a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean +++ b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean @@ -195,6 +195,7 @@ theorem isSymmetric_iff_inner_map_self_real (T : V →ₗ[ℂ] V) : end Complex +set_option backward.isDefEq.respectTransparency false in /-- Polarization identity for symmetric linear maps. See `inner_map_polarization` for the complex version without the symmetric assumption. -/ theorem IsSymmetric.inner_map_polarization {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) (x y : E) : diff --git a/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean b/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean index e2360e5c1d9801..2bd4bbe4e721e8 100644 --- a/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean +++ b/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean @@ -642,11 +642,13 @@ theorem _root_.ContinuousLinearMap.lTensor_eq_mapL (g : G →L[𝕜] H) : apply ContinuousLinearMap.coe_inj.mp <| ext' ?_ simp [TensorProduct.ext_iff_inner_right, ContinuousLinearMap.adjoint_inner_left] +set_option backward.isDefEq.respectTransparency.types false in variable (G) in @[simp] theorem _root_.ContinuousLinearMap.adjoint_rTensor [CompleteSpace E] [CompleteSpace G] [CompleteSpace (E ⊗[𝕜] G)] [CompleteSpace (F ⊗[𝕜] G)] [CompleteSpace F] (f : E →L[𝕜] F) : (f.rTensor G).adjoint = f.adjoint.rTensor G := by simp [ContinuousLinearMap.rTensor_eq_mapL] +set_option backward.isDefEq.respectTransparency.types false in variable (E) in @[simp] theorem _root_.ContinuousLinearMap.adjoint_lTensor [CompleteSpace E] [CompleteSpace G] [CompleteSpace (E ⊗[𝕜] H)] [CompleteSpace (E ⊗[𝕜] G)] [CompleteSpace H] (g : G →L[𝕜] H) : diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvex.lean b/Mathlib/Analysis/LocallyConvex/AbsConvex.lean index ef85705131fd43..5b78057dd8b372 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvex.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvex.lean @@ -93,6 +93,7 @@ theorem balanced_absConvexHull : Balanced 𝕜 (absConvexHull 𝕜 s) := theorem convex_absConvexHull : Convex 𝕜 (absConvexHull 𝕜 s) := absConvex_absConvexHull.2 +set_option backward.isDefEq.respectTransparency false in variable (𝕜 s) in theorem absConvexHull_eq_iInter : absConvexHull 𝕜 s = ⋂ (t : Set E) (_ : s ⊆ t) (_ : AbsConvex 𝕜 t), t := by diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean index 3ea3c4d5852ae0..a8472f4900e4e3 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean @@ -105,6 +105,7 @@ theorem gaugeSeminormFamily_ball (s : AbsConvexOpenSets 𝕜 E) : variable [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] variable [LocallyConvexSpace 𝕜 E] +set_option backward.isDefEq.respectTransparency false in /-- The topology of a locally convex space is induced by the gauge seminorm family. -/ theorem with_gaugeSeminormFamily : WithSeminorms (gaugeSeminormFamily 𝕜 E) := by refine SeminormFamily.withSeminorms_of_hasBasis _ ?_ diff --git a/Mathlib/Analysis/LocallyConvex/HahnBanach.lean b/Mathlib/Analysis/LocallyConvex/HahnBanach.lean index 7036a95558e333..68e578dee6b1fa 100644 --- a/Mathlib/Analysis/LocallyConvex/HahnBanach.lean +++ b/Mathlib/Analysis/LocallyConvex/HahnBanach.lean @@ -100,6 +100,7 @@ theorem StrongDual.exists_extension {𝕜} [NontriviallyNormedField 𝕜] [IsRCL variable {F : Type*} [AddCommGroup F] [TopologicalSpace F] [IsTopologicalAddGroup F] [Module 𝕜 F] [ContinuousSMul 𝕜 F] [T2Space F] +set_option backward.isDefEq.respectTransparency.types false in /-- Corollary of the polynormable **Hahn-Banach theorem**: if `f : S → F` is a continuous linear map with finite-dimensional range, then `f` extends to a continuous linear map on the whole space. -/ diff --git a/Mathlib/Analysis/LocallyConvex/Separation.lean b/Mathlib/Analysis/LocallyConvex/Separation.lean index 042f0b08b8fb9c..459bdf9224b652 100644 --- a/Mathlib/Analysis/LocallyConvex/Separation.lean +++ b/Mathlib/Analysis/LocallyConvex/Separation.lean @@ -48,6 +48,7 @@ open scoped Pointwise variable {𝕜 E : Type*} +set_option backward.isDefEq.respectTransparency false in /-- Given a set `s` which is a convex neighbourhood of `0` and a point `x₀` outside of it, there is a continuous linear functional `f` separating `x₀` and `s`, in the sense that it sends `x₀` to 1 and all of `s` to values strictly below `1`. -/ diff --git a/Mathlib/Analysis/LocallyConvex/WeakSpace.lean b/Mathlib/Analysis/LocallyConvex/WeakSpace.lean index f9a6c9e251bbe5..68ebb3cbd5cf74 100644 --- a/Mathlib/Analysis/LocallyConvex/WeakSpace.lean +++ b/Mathlib/Analysis/LocallyConvex/WeakSpace.lean @@ -30,6 +30,7 @@ variable [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] variable [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [LocallyConvexSpace ℝ F] +set_option backward.isDefEq.respectTransparency.types false in variable (𝕜) in /-- If `E` is a locally convex space over `𝕜` (with `RCLike 𝕜`), and `s : Set E` is `ℝ`-convex, then the closure of `s` and the weak closure of `s` coincide. More precisely, the topological closure diff --git a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean index ff1bccfc3716c5..5ec717a849a8a9 100644 --- a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean +++ b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean @@ -138,7 +138,7 @@ theorem basisSets_neg (U) (hU' : U ∈ p.basisSets) : exact ⟨U, hU', Eq.subset hU⟩ /-- The `addGroupFilterBasis` induced by the filter basis `Seminorm.basisSets`. -/ -@[implicit_reducible] +@[instance_reducible] protected def addGroupFilterBasis : AddGroupFilterBasis E := addGroupFilterBasisOfComm p.basisSets p.basisSets_nonempty p.basisSets_intersect p.basisSets_zero p.basisSets_add p.basisSets_neg diff --git a/Mathlib/Analysis/Matrix/Normed.lean b/Mathlib/Analysis/Matrix/Normed.lean index 6e9886a3553119..13c36e28c2c4e7 100644 --- a/Mathlib/Analysis/Matrix/Normed.lean +++ b/Mathlib/Analysis/Matrix/Normed.lean @@ -600,6 +600,7 @@ lemma frobenius_norm_replicateCol (v : n → α) : ‖replicateCol ι v‖ = ‖ lemma frobenius_nnnorm_replicateCol (v : n → α) : ‖replicateCol ι v‖₊ = ‖toLp 2 v‖₊ := Subtype.ext <| frobenius_norm_replicateCol v +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma frobenius_nnnorm_diagonal [DecidableEq n] (v : n → α) : ‖diagonal v‖₊ = ‖toLp 2 v‖₊ := by simp_rw [frobenius_nnnorm_def, ← Finset.sum_product', Finset.univ_product_univ, diff --git a/Mathlib/Analysis/Matrix/Order.lean b/Mathlib/Analysis/Matrix/Order.lean index 3325a479995e3d..21204c2912b36f 100644 --- a/Mathlib/Analysis/Matrix/Order.lean +++ b/Mathlib/Analysis/Matrix/Order.lean @@ -305,7 +305,7 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- A positive definite matrix `M` induces a norm on `Matrix n n 𝕜` `‖x‖ = sqrt (x * M * xᴴ).trace`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def toMatrixSeminormedAddCommGroup (M : Matrix n n 𝕜) (hM : M.PosSemidef) : SeminormedAddCommGroup (Matrix n n 𝕜) := @InnerProductSpace.Core.toSeminormedAddCommGroup _ _ _ _ _ hM.matrixPreInnerProductSpace @@ -314,7 +314,7 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- A positive definite matrix `M` induces a norm on `Matrix n n 𝕜`: `‖x‖ = sqrt (x * M * xᴴ).trace`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def toMatrixNormedAddCommGroup (M : Matrix n n 𝕜) (hM : M.PosDef) : NormedAddCommGroup (Matrix n n 𝕜) := letI : InnerProductSpace.Core 𝕜 (Matrix n n 𝕜) := @@ -332,7 +332,7 @@ noncomputable def toMatrixNormedAddCommGroup (M : Matrix n n 𝕜) (hM : M.PosDe /-- A positive semi-definite matrix `M` induces an inner product on `Matrix n n 𝕜`: `⟪x, y⟫ = (y * M * xᴴ).trace`. -/ -@[implicit_reducible] +@[instance_reducible] def toMatrixInnerProductSpace (M : Matrix n n 𝕜) (hM : M.PosSemidef) : letI : SeminormedAddCommGroup (Matrix n n 𝕜) := M.toMatrixSeminormedAddCommGroup hM InnerProductSpace 𝕜 (Matrix n n 𝕜) := diff --git a/Mathlib/Analysis/Matrix/PosDef.lean b/Mathlib/Analysis/Matrix/PosDef.lean index 0931c1b8e8bfe3..a9e7fd020b3fd7 100644 --- a/Mathlib/Analysis/Matrix/PosDef.lean +++ b/Mathlib/Analysis/Matrix/PosDef.lean @@ -94,7 +94,7 @@ set_option backward.privateInPublic true in /-- The pre-inner product space structure implementation. Only an auxiliary for `Matrix.toSeminormedAddCommGroup`, `Matrix.toNormedAddCommGroup`, and `Matrix.toInnerProductSpace`. -/ -@[implicit_reducible] +@[instance_reducible] private def PosSemidef.preInnerProductSpace {M : Matrix n n 𝕜} (hM : M.PosSemidef) : PreInnerProductSpace.Core 𝕜 (n → 𝕜) where inner x y := (M *ᵥ y) ⬝ᵥ star x @@ -124,7 +124,7 @@ noncomputable abbrev toNormedAddCommGroup (M : Matrix n n 𝕜) (hM : M.PosDef) simpa [hx, lt_irrefl, dotProduct_comm] using hM.re_dotProduct_pos h } /-- A positive semi-definite matrix `M` induces an inner product `⟪x, y⟫ = xᴴMy`. -/ -@[implicit_reducible] +@[instance_reducible] def toInnerProductSpace (M : Matrix n n 𝕜) (hM : M.PosSemidef) : @InnerProductSpace 𝕜 (n → 𝕜) _ (M.toSeminormedAddCommGroup hM) := InnerProductSpace.ofCore _ diff --git a/Mathlib/Analysis/Matrix/Spectrum.lean b/Mathlib/Analysis/Matrix/Spectrum.lean index f44c74e2756a28..9d663107693060 100644 --- a/Mathlib/Analysis/Matrix/Spectrum.lean +++ b/Mathlib/Analysis/Matrix/Spectrum.lean @@ -162,6 +162,7 @@ lemma roots_charpoly_eq_eigenvalues : · simp · simp [Finset.prod_ne_zero_iff, Polynomial.X_sub_C_ne_zero] +set_option backward.isDefEq.respectTransparency.types false in lemma roots_charpoly_eq_eigenvalues₀ : A.charpoly.roots = Multiset.map (RCLike.ofReal ∘ hA.eigenvalues₀) Finset.univ.val := by rw [hA.roots_charpoly_eq_eigenvalues] diff --git a/Mathlib/Analysis/MeanInequalities.lean b/Mathlib/Analysis/MeanInequalities.lean index b6aba130f375d6..f63056583fc640 100644 --- a/Mathlib/Analysis/MeanInequalities.lean +++ b/Mathlib/Analysis/MeanInequalities.lean @@ -884,6 +884,7 @@ theorem inner_le_Lp_mul_Lq (hpq : HolderConjugate p q) : refine le_trans (sum_le_sum fun i _ ↦ ?_) (by simpa using Lr_rpow_le_Lp_mul_Lq s f g hpq) simp only [← abs_mul, le_abs_self] +set_option backward.isDefEq.respectTransparency false in /-- For `1 ≤ p`, the `p`-th power of the sum of `f i` is bounded above by a constant times the sum of the `p`-th powers of `f i`. Version for sums over finite sets, with `ℝ`-valued functions. -/ theorem rpow_sum_le_const_mul_sum_rpow (hp : 1 ≤ p) : diff --git a/Mathlib/Analysis/Meromorphic/FactorizedRational.lean b/Mathlib/Analysis/Meromorphic/FactorizedRational.lean index 941471adbf470c..22febde0bebfcc 100644 --- a/Mathlib/Analysis/Meromorphic/FactorizedRational.lean +++ b/Mathlib/Analysis/Meromorphic/FactorizedRational.lean @@ -60,6 +60,7 @@ lemma mulSupport (d : 𝕜 → ℤ) : use u simp_all [zero_zpow_eq_one₀] +set_option backward.isDefEq.respectTransparency false in /-- Helper Lemma: If the support of `d` is finite, then evaluation of functions commutes with finprod, and the function `∏ᶠ u, (· - u) ^ d u` equals `fun x ↦ ∏ᶠ u, (x - u) ^ d u`. @@ -100,6 +101,7 @@ theorem ne_zero {d : 𝕜 → ℤ} {x : 𝕜} (h : d x = 0) : by_cases h₂ : x = z <;> simp_all [zpow_ne_zero, sub_ne_zero] · simp [finprod_of_infinite_mulSupport h₁] +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- Helper Lemma for Computations: Extract one factor out of a factorized rational function. @@ -191,6 +193,7 @@ private lemma mulSupport_update {d : 𝕜 → ℤ} {x : 𝕜} simp · simp_all +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- Compute the trailing coefficient of the factorized rational function associated with `d : 𝕜 → ℤ`. @@ -214,6 +217,7 @@ theorem meromorphicTrailingCoeffAt_factorizedRational {d : 𝕜 → ℤ} {x : simp_all · grind [meromorphicTrailingCoeffAt_id_sub_const] +set_option backward.isDefEq.respectTransparency false in /-- Variant of `meromorphicTrailingCoeffAt_factorizedRational`: Compute the trailing coefficient of the factorized rational function associated with `d : 𝕜 → ℤ` at points outside the support of `d`. @@ -235,6 +239,7 @@ theorem meromorphicTrailingCoeffAt_factorizedRational_off_support {d : 𝕜 → by_contra hCon simp_all +set_option backward.isDefEq.respectTransparency false in /-- Variant of `meromorphicTrailingCoeffAt_factorizedRational`: Compute log of the norm of the trailing coefficient. The convention that `log 0 = 0` gives a closed formula easier than the one in diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsor.lean b/Mathlib/Analysis/Normed/Affine/AddTorsor.lean index 0beb28f923ee47..217cd410576753 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsor.lean @@ -56,6 +56,7 @@ theorem nndist_homothety_center (p₁ p₂ : P) (c : 𝕜) : nndist (homothety p₁ c p₂) p₁ = ‖c‖₊ * nndist p₁ p₂ := NNReal.eq <| dist_homothety_center _ _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem dist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) : dist (lineMap p₁ p₂ c₁) (lineMap p₁ p₂ c₂) = dist c₁ c₂ * dist p₁ p₂ := by @@ -63,47 +64,57 @@ theorem dist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) : simp only [lineMap_apply, dist_eq_norm_vsub, vadd_vsub_vadd_cancel_right, ← sub_smul, norm_smul, vsub_eq_sub] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem nndist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) : nndist (lineMap p₁ p₂ c₁) (lineMap p₁ p₂ c₂) = nndist c₁ c₂ * nndist p₁ p₂ := NNReal.eq <| dist_lineMap_lineMap _ _ _ _ +set_option backward.isDefEq.respectTransparency false in theorem lipschitzWith_lineMap (p₁ p₂ : P) : LipschitzWith (nndist p₁ p₂) (lineMap p₁ p₂ : 𝕜 → P) := LipschitzWith.of_dist_le_mul fun c₁ c₂ => ((dist_lineMap_lineMap p₁ p₂ c₁ c₂).trans (mul_comm _ _)).le +set_option backward.isDefEq.respectTransparency false in @[simp] theorem dist_lineMap_left (p₁ p₂ : P) (c : 𝕜) : dist (lineMap p₁ p₂ c) p₁ = ‖c‖ * dist p₁ p₂ := by simpa only [lineMap_apply_zero, dist_zero_right] using dist_lineMap_lineMap p₁ p₂ c 0 +set_option backward.isDefEq.respectTransparency false in @[simp] theorem nndist_lineMap_left (p₁ p₂ : P) (c : 𝕜) : nndist (lineMap p₁ p₂ c) p₁ = ‖c‖₊ * nndist p₁ p₂ := NNReal.eq <| dist_lineMap_left _ _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem dist_left_lineMap (p₁ p₂ : P) (c : 𝕜) : dist p₁ (lineMap p₁ p₂ c) = ‖c‖ * dist p₁ p₂ := (dist_comm _ _).trans (dist_lineMap_left _ _ _) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem nndist_left_lineMap (p₁ p₂ : P) (c : 𝕜) : nndist p₁ (lineMap p₁ p₂ c) = ‖c‖₊ * nndist p₁ p₂ := NNReal.eq <| dist_left_lineMap _ _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem dist_lineMap_right (p₁ p₂ : P) (c : 𝕜) : dist (lineMap p₁ p₂ c) p₂ = ‖1 - c‖ * dist p₁ p₂ := by simpa only [lineMap_apply_one, dist_eq_norm'] using dist_lineMap_lineMap p₁ p₂ c 1 +set_option backward.isDefEq.respectTransparency false in @[simp] theorem nndist_lineMap_right (p₁ p₂ : P) (c : 𝕜) : nndist (lineMap p₁ p₂ c) p₂ = ‖1 - c‖₊ * nndist p₁ p₂ := NNReal.eq <| dist_lineMap_right _ _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem dist_right_lineMap (p₁ p₂ : P) (c : 𝕜) : dist p₂ (lineMap p₁ p₂ c) = ‖1 - c‖ * dist p₁ p₂ := (dist_comm _ _).trans (dist_lineMap_right _ _ _) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem nndist_right_lineMap (p₁ p₂ : P) (c : 𝕜) : nndist p₂ (lineMap p₁ p₂ c) = ‖1 - c‖₊ * nndist p₁ p₂ := @@ -206,6 +217,7 @@ theorem dist_right_pointReflection (p q : P) : dist q (Equiv.pointReflection p q) = ‖(2 : 𝕜)‖ * dist p q := (dist_comm _ _).trans (dist_pointReflection_right 𝕜 _ _) +set_option backward.isDefEq.respectTransparency false in theorem antilipschitzWith_lineMap {p₁ p₂ : Q} (h : p₁ ≠ p₂) : AntilipschitzWith (nndist p₁ p₂)⁻¹ (lineMap p₁ p₂ : 𝕜 → Q) := AntilipschitzWith.of_le_mul_dist fun c₁ c₂ => by diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean index 559c5ad9cf6dd6..e9f8c9d346fd3f 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean @@ -77,6 +77,7 @@ variable {V P : Type*} [NormedAddCommGroup V] [NormedSpace ℝ V] [MetricSpace P open AffineMap +set_option backward.isDefEq.respectTransparency false in /-- Given a set `s` of affine-independent points belonging to an open set `u`, we may extend `s` to an affine basis, all of whose elements belong to `u`. -/ theorem IsOpen.exists_between_affineIndependent_span_eq_top {s u : Set P} (hu : IsOpen u) diff --git a/Mathlib/Analysis/Normed/Algebra/Exponential.lean b/Mathlib/Analysis/Normed/Algebra/Exponential.lean index 899c00549cd086..4c210b5cb05db4 100644 --- a/Mathlib/Analysis/Normed/Algebra/Exponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/Exponential.lean @@ -352,7 +352,7 @@ theorem exp_add_of_commute_of_mem_ball [CharZero 𝕂] {x y : 𝔸} (hxy : Commu field_simp [n.factorial_ne_zero] /-- `NormedSpace.exp x` has explicit two-sided inverse `NormedSpace.exp (-x)`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def invertibleExpOfMemBall [CharZero 𝕂] {x : 𝔸} (hx : x ∈ Metric.eball (0 : 𝔸) (expSeries 𝕂 𝔸).radius) : Invertible (exp x) where @@ -522,7 +522,7 @@ theorem exp_add_of_commute {x y : 𝔸} (hxy : Commute x y) : exp (x + y) = exp ((expSeries_radius_eq_top ℚ 𝔸).symm ▸ edist_lt_top _ _) /-- `NormedSpace.exp x` has explicit two-sided inverse `NormedSpace.exp (-x)`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def invertibleExp (x : 𝔸) : Invertible (exp x) := invertibleExpOfMemBall <| (expSeries_radius_eq_top ℚ 𝔸).symm ▸ edist_lt_top _ _ @@ -553,6 +553,7 @@ lemma _root_.SemiconjBy.exp_neg_mul_mul_exp_eq_self {x a b : 𝔸} (h : Semiconj let := invertibleExp b simpa [← invOf_exp, mul_assoc, invOf_mul_eq_iff_eq_mul_left] using! h.exp_right +set_option backward.isDefEq.respectTransparency false in open scoped Function in -- required for scoped `on` notation /-- In a Banach-algebra `𝔸` over `𝕂 = ℝ` or `𝕂 = ℂ`, if a family of elements `f i` mutually commute then `NormedSpace.exp (∑ i, f i) = ∏ i, NormedSpace.exp (f i)`. -/ diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index 3e85035d51555c..3c0dbc98fa36ae 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -491,6 +491,7 @@ section NormedField variable [NormedField 𝕜] [NormedAlgebra 𝕜 A] [instSMulMem : SMulMemClass SA 𝕜 A] variable (S : SA) [hS : IsClosed (S : Set A)] (x : S) +set_option backward.isDefEq.respectTransparency.types false in open SubalgebraClass in include instSMulMem in /-- Let `S` be a closed subalgebra of a Banach algebra `A`. If `a : S` is invertible in `A`, diff --git a/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean b/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean index cebb8451450c51..8872a65a751f61 100644 --- a/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean +++ b/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean @@ -208,6 +208,7 @@ example : (TrivSqZeroExt.instUniformSpace : UniformSpace (tsze R M)) = PseudoMetricSpace.toUniformSpace := rfl +set_option backward.isDefEq.respectTransparency false in theorem norm_def (x : tsze R M) : ‖x‖ = ‖fst x‖ + ‖snd x‖ := by erw [WithLp.norm_seminormedAddCommGroupToProd] rw [WithLp.prod_norm_eq_add (by norm_num)] @@ -227,6 +228,7 @@ theorem nnnorm_def (x : tsze R M) : ‖x‖₊ = ‖fst x‖₊ + ‖snd x‖₊ variable [Module R M] [IsBoundedSMul R M] [Module Rᵐᵒᵖ M] [IsBoundedSMul Rᵐᵒᵖ M] [SMulCommClass R Rᵐᵒᵖ M] +set_option backward.isDefEq.respectTransparency false in instance instL1SeminormedRing : SeminormedRing (tsze R M) where norm_mul_le | ⟨r₁, m₁⟩, ⟨r₂, m₂⟩ => by diff --git a/Mathlib/Analysis/Normed/Field/Basic.lean b/Mathlib/Analysis/Normed/Field/Basic.lean index 5b987828d26609..0a67e1d1eb0b62 100644 --- a/Mathlib/Analysis/Normed/Field/Basic.lean +++ b/Mathlib/Analysis/Normed/Field/Basic.lean @@ -286,7 +286,7 @@ end NormedField /-- A normed field is nontrivially normed provided that the norm of some nonzero element is not one. -/ -@[implicit_reducible] +@[instance_reducible] def NontriviallyNormedField.ofNormNeOne {𝕜 : Type*} [h' : NormedField 𝕜] (h : ∃ x : 𝕜, x ≠ 0 ∧ ‖x‖ ≠ 1) : NontriviallyNormedField 𝕜 where toNormedField := h' @@ -361,7 +361,7 @@ end SubfieldClass namespace AbsoluteValue /-- A real absolute value on a field determines a `NormedField` structure. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def toNormedField {K : Type*} [Field K] (v : AbsoluteValue K ℝ) : NormedField K where toField := inferInstanceAs (Field K) __ := v.toNormedRing diff --git a/Mathlib/Analysis/Normed/Field/UnitBall.lean b/Mathlib/Analysis/Normed/Field/UnitBall.lean index 16d2e409f1cf80..f5f16fc9d9090e 100644 --- a/Mathlib/Analysis/Normed/Field/UnitBall.lean +++ b/Mathlib/Analysis/Normed/Field/UnitBall.lean @@ -141,6 +141,7 @@ def Submonoid.unitClosedBall (𝕜 : Type*) [SeminormedRing 𝕜] [NormOneClass carrier := closedBall 0 1 one_mem' := mem_closedBall_zero_iff.2 norm_one.le } +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Submonoid.mem_unitClosedBall (𝕜 : Type*) [SeminormedRing 𝕜] [NormOneClass 𝕜] {x : 𝕜} : x ∈ Submonoid.unitClosedBall 𝕜 ↔ ‖x‖ ≤ 1 := by simp [Submonoid.unitClosedBall] diff --git a/Mathlib/Analysis/Normed/Group/AddTorsor.lean b/Mathlib/Analysis/Normed/Group/AddTorsor.lean index 4d5acfaea1fa28..00b071a37e83f4 100644 --- a/Mathlib/Analysis/Normed/Group/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Group/AddTorsor.lean @@ -181,7 +181,7 @@ theorem edist_vsub_vsub_le (p₁ p₂ p₃ p₄ : P) : /-- The pseudodistance defines a pseudometric space structure on the torsor. This is not an instance because it depends on `V` to define a `MetricSpace P`. -/ -@[implicit_reducible] +@[instance_reducible] def pseudoMetricSpaceOfNormedAddCommGroupOfAddTorsor (V P : Type*) [SeminormedAddCommGroup V] [AddTorsor V P] : PseudoMetricSpace P where dist x y := ‖(x -ᵥ y : V)‖ @@ -193,7 +193,7 @@ def pseudoMetricSpaceOfNormedAddCommGroupOfAddTorsor (V P : Type*) [SeminormedAd /-- The distance defines a metric space structure on the torsor. This is not an instance because it depends on `V` to define a `MetricSpace P`. -/ -@[implicit_reducible] +@[instance_reducible] def metricSpaceOfNormedAddCommGroupOfAddTorsor (V P : Type*) [NormedAddCommGroup V] [AddTorsor V P] : MetricSpace P where dist x y := ‖(x -ᵥ y : V)‖ diff --git a/Mathlib/Analysis/Normed/Group/FunctionSeries.lean b/Mathlib/Analysis/Normed/Group/FunctionSeries.lean index b730d84a5c9bf6..b9f9b140a7685f 100644 --- a/Mathlib/Analysis/Normed/Group/FunctionSeries.lean +++ b/Mathlib/Analysis/Normed/Group/FunctionSeries.lean @@ -51,6 +51,7 @@ theorem tendstoUniformlyOn_tsum_nat {f : ℕ → β → F} {u : ℕ → ℝ} (hu s := fun v hv => tendsto_finset_range.eventually (tendstoUniformlyOn_tsum hu hfu v hv) +set_option backward.isDefEq.respectTransparency false in /-- An infinite sum of functions with eventually summable sup norm is the uniform limit of its partial sums. Version relative to a set, with general index set. -/ theorem tendstoUniformlyOn_tsum_of_cofinite_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} diff --git a/Mathlib/Analysis/Normed/Group/Quotient.lean b/Mathlib/Analysis/Normed/Group/Quotient.lean index a2be9239e6f3e8..f6b40a8b9e5163 100644 --- a/Mathlib/Analysis/Normed/Group/Quotient.lean +++ b/Mathlib/Analysis/Normed/Group/Quotient.lean @@ -300,6 +300,7 @@ theorem ker_normedMk (S : AddSubgroup M) : S.normedMk.ker = S := theorem norm_normedMk_le (S : AddSubgroup M) : ‖S.normedMk‖ ≤ 1 := NormedAddGroupHom.opNorm_le_bound _ zero_le_one fun m => by simp [norm_mk_le_norm] +set_option backward.isDefEq.respectTransparency.types false in theorem _root_.QuotientAddGroup.norm_lift_apply_le {S : AddSubgroup M} (f : NormedAddGroupHom M N) (hf : ∀ x ∈ S, f x = 0) (x : M ⧸ S) : ‖lift S f.toAddMonoidHom hf x‖ ≤ ‖f‖ * ‖x‖ := by cases (norm_nonneg f).eq_or_lt' with diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean index 08d6de288e36bb..e67ed17e4b177a 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean @@ -36,6 +36,7 @@ namespace SemiNormedGrp₁ noncomputable section +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `HasCokernels SemiNormedGrp₁`. -/ def cokernelCocone {X Y : SemiNormedGrp₁.{u}} (f : X ⟶ Y) : Cofork f 0 := Cofork.ofπ @@ -48,6 +49,7 @@ def cokernelCocone {X Y : SemiNormedGrp₁.{u}} (f : X ⟶ Y) : Cofork f 0 := f.hom.1.mem_range] use x) +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `HasCokernels SemiNormedGrp₁`. -/ def cokernelLift {X Y : SemiNormedGrp₁.{u}} (f : X ⟶ Y) (s : CokernelCofork f) : (cokernelCocone f).pt ⟶ s.pt := by @@ -60,6 +62,7 @@ def cokernelLift {X Y : SemiNormedGrp₁.{u}} (f : X ⟶ Y) (s : CokernelCofork -- The lift has norm at most one: exact NormedAddGroupHom.lift_normNoninc _ _ _ s.π.2 +set_option backward.isDefEq.respectTransparency.types false in instance : HasCokernels SemiNormedGrp₁.{u} where has_colimit f := HasColimit.mk @@ -211,6 +214,7 @@ theorem explicitCokernelπ_desc_apply {X Y Z : SemiNormedGrp.{u}} {f : X ⟶ Y} {cond : f ≫ g = 0} (x : Y) : explicitCokernelDesc cond (explicitCokernelπ f x) = g x := show (explicitCokernelπ f ≫ explicitCokernelDesc cond) x = g x by rw [explicitCokernelπ_desc] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem explicitCokernelDesc_unique {X Y Z : SemiNormedGrp.{u}} {f : X ⟶ Y} {g : Y ⟶ Z} (w : f ≫ g = 0) (e : explicitCokernel f ⟶ Z) (he : explicitCokernelπ f ≫ e = g) : diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 4be115938cf607..6961e020117a12 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -417,6 +417,7 @@ def pseudoEmetricAux : PseudoEMetricSpace (PiLp p β) where attribute [local instance] PiLp.pseudoEmetricAux +set_option backward.isDefEq.respectTransparency false in /-- An auxiliary lemma used twice in the proof of `PiLp.pseudoMetricAux` below. Not intended for use outside this file. -/ theorem iSup_edist_ne_top_aux {ι : Type*} [Finite ι] {α : ι → Type*} @@ -753,6 +754,7 @@ theorem norm_eq_of_nat {p : ℝ≥0∞} [Fact (1 ≤ p)] {β : ι → Type*} section L1 variable {β} [∀ i, SeminormedAddCommGroup (β i)] +set_option backward.isDefEq.respectTransparency false in theorem norm_eq_of_L1 (x : PiLp 1 β) : ‖x‖ = ∑ i : ι, ‖x i‖ := by simp [norm_eq_sum] @@ -765,6 +767,7 @@ theorem dist_eq_of_L1 (x y : PiLp 1 β) : dist x y = ∑ i, dist (x i) (y i) := theorem nndist_eq_of_L1 (x y : PiLp 1 β) : nndist x y = ∑ i, nndist (x i) (y i) := NNReal.eq <| by push_cast; exact dist_eq_of_L1 _ _ +set_option backward.isDefEq.respectTransparency false in theorem edist_eq_of_L1 (x y : PiLp 1 β) : edist x y = ∑ i, edist (x i) (y i) := by simp [PiLp.edist_eq_sum] diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 727ee0cd33c50b..29f1a202217f7f 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -769,6 +769,7 @@ theorem prod_nnnorm_eq_sup (f : WithLp ∞ (α × β)) : ‖f‖₊ = ‖f.fst section L1 +set_option backward.isDefEq.respectTransparency false in theorem prod_norm_eq_of_L1 (x : WithLp 1 (α × β)) : ‖x‖ = ‖x.fst‖ + ‖x.snd‖ := by simp [prod_norm_eq_add] @@ -789,6 +790,7 @@ theorem prod_nndist_eq_of_L1 (x y : WithLp 1 (α × β)) : push_cast exact prod_dist_eq_of_L1 _ _ +set_option backward.isDefEq.respectTransparency false in theorem prod_edist_eq_of_L1 (x y : WithLp 1 (α × β)) : edist x y = edist x.fst y.fst + edist x.snd y.snd := by simp [prod_edist_eq_add] diff --git a/Mathlib/Analysis/Normed/Lp/lpHolder.lean b/Mathlib/Analysis/Normed/Lp/lpHolder.lean index fd83f5c572f27b..ea088b54aaea79 100644 --- a/Mathlib/Analysis/Normed/Lp/lpHolder.lean +++ b/Mathlib/Analysis/Normed/Lp/lpHolder.lean @@ -38,6 +38,7 @@ variable [∀ i, NormedAddCommGroup (E i)] [∀ i, NormedSpace 𝕜 (E i)] [∀ i, NormedAddCommGroup (F i)] [∀ i, NormedSpace 𝕜 (F i)] variable {p q r : ℝ≥0∞} +set_option backward.isDefEq.respectTransparency.types false in /-- A uniformly bounded family of continuous linear maps, as a continuous linear map on the `lp` space. -/ @[simps!] diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index 65fc57d804ecf6..2cb4f541a38745 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -737,6 +737,7 @@ section Sum variable {E : Type*} [NormedAddCommGroup E] +set_option backward.isDefEq.respectTransparency false in lemma norm_tsum_le (f : ℓ¹(α, E)) : ‖∑' i, f i‖ ≤ ‖f‖ := calc ‖∑' i, f i‖ ≤ ∑' i, ‖f i‖ := norm_tsum_le_tsum_norm (.of_norm (by simpa using f.2.summable)) @@ -1079,6 +1080,7 @@ noncomputable def zeroBasis : Module.Basis α 𝕜 ℓ⁰(α, 𝕜) where left_inv _ := rfl right_inv _ := Finsupp.ext fun _ ↦ rfl } +set_option backward.isDefEq.respectTransparency false in lemma zeroBasis_apply (i : α) : zeroBasis i = lp.single 0 i (1 : 𝕜) := by ext; simp [zeroBasis, Finsupp.single_apply, Pi.single, Function.update, eq_comm] @@ -1274,6 +1276,7 @@ open Filter open scoped Topology uniformity +set_option backward.isDefEq.respectTransparency false in /-- The coercion from `lp E p` to `∀ i, E i` is uniformly continuous. -/ theorem uniformContinuous_coe [_i : Fact (1 ≤ p)] : UniformContinuous (α := lp E p) ((↑) : lp E p → ∀ i, E i) := diff --git a/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean b/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean index 5ad16d9f22a7b3..45b7a67aea8a76 100644 --- a/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean +++ b/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean @@ -139,6 +139,7 @@ theorem ball_subset_univBall_target (c : P) (r : ℝ) : ball c r ⊆ (univBall c · rw [univBall, dif_neg hr] exact subset_univ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem univBall_apply_zero (c : P) (r : ℝ) : univBall c r 0 = c := by unfold univBall; split_ifs <;> simp diff --git a/Mathlib/Analysis/Normed/Module/Bases.lean b/Mathlib/Analysis/Normed/Module/Bases.lean index 8a0fb89ad36437..c84d8fb24ec193 100644 --- a/Mathlib/Analysis/Normed/Module/Bases.lean +++ b/Mathlib/Analysis/Normed/Module/Bases.lean @@ -181,6 +181,7 @@ theorem range_proj_eq_span (A : Finset β) : use b i rw [ContinuousLinearMap.coe_coe, proj_apply_basis_mem, if_pos (Finset.mem_coe.mp hi)] +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- Composition of projections: `proj A (proj B x) = proj (A ∩ B) x`. -/ theorem proj_comp (A B : Finset β) (x : X) : b.proj A (b.proj B x) = b.proj (A ∩ B) x := by diff --git a/Mathlib/Analysis/Normed/Module/Basic.lean b/Mathlib/Analysis/Normed/Module/Basic.lean index 430def7cd51eb1..0511218ab75a62 100644 --- a/Mathlib/Analysis/Normed/Module/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Basic.lean @@ -469,7 +469,7 @@ inferred, and because it is likely to create instance diamonds. See Note [reducible non-instances]. -/ -@[implicit_reducible] +@[instance_reducible] def NormedSpace.restrictScalars : NormedSpace 𝕜 E := { Module.restrictScalars 𝕜 𝕜' E with norm_smul_le := fun c x => @@ -491,7 +491,7 @@ instance RestrictScalars.normedSpace : NormedSpace 𝕜 (RestrictScalars 𝕜 /-- The action of the original `NormedField` on `RestrictScalars 𝕜 𝕜' E`. This is not an instance as it would be contrary to the purpose of `RestrictScalars`. -/ -@[implicit_reducible] +@[instance_reducible] def Module.RestrictScalars.normedSpaceOrig {𝕜 : Type*} {𝕜' : Type*} {E : Type*} [NormedField 𝕜'] [SeminormedAddCommGroup E] [I : NormedSpace 𝕜' E] : NormedSpace 𝕜' (RestrictScalars 𝕜 𝕜' E) := I @@ -513,7 +513,7 @@ inferred, and because it is likely to create instance diamonds. See Note [reducible non-instances]. -/ -@[implicit_reducible] +@[instance_reducible] def NormedAlgebra.restrictScalars : NormedAlgebra 𝕜 E := { NormedSpace.restrictScalars 𝕜 𝕜' E, Algebra.restrictScalars 𝕜 𝕜' E with } @@ -527,7 +527,7 @@ instance RestrictScalars.normedAlgebra : NormedAlgebra 𝕜 (RestrictScalars /-- The action of the original `NormedField` on `RestrictScalars 𝕜 𝕜' E`. This is not an instance as it would be contrary to the purpose of `RestrictScalars`. -/ -@[implicit_reducible] +@[instance_reducible] def Module.RestrictScalars.normedAlgebraOrig {𝕜 : Type*} {𝕜' : Type*} {E : Type*} [NormedField 𝕜'] [SeminormedRing E] [I : NormedAlgebra 𝕜' E] : NormedAlgebra 𝕜' (RestrictScalars 𝕜 𝕜' E) := I diff --git a/Mathlib/Analysis/Normed/Module/ContinuousInverse.lean b/Mathlib/Analysis/Normed/Module/ContinuousInverse.lean index ef344f29e422d6..e5026bb3b44a2f 100644 --- a/Mathlib/Analysis/Normed/Module/ContinuousInverse.lean +++ b/Mathlib/Analysis/Normed/Module/ContinuousInverse.lean @@ -202,6 +202,7 @@ variable {R E E' F F' G : Type*} [Ring R] [TopologicalSpace E] [AddCommGroup E] [Module R E] [TopologicalSpace F] [AddCommGroup F] [Module R F] {f : E →L[R] F} +set_option backward.isDefEq.respectTransparency false in /-- If `f` has a continuous left inverse, its range admits a closed complement. -/ lemma closedComplemented_range (hf : f.HasLeftInverse) : Submodule.ClosedComplemented f.range := by -- Idea of proof: let g be a left inverse for f. Then ker g is a closed subspace of F, diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index e0dfb1aab6f191..07ae61a5444d89 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -354,6 +354,7 @@ theorem isOpen_setOf_affineIndependent {ι : Type*} [Finite ι] : namespace Module.Basis +set_option backward.isDefEq.respectTransparency false in theorem opNNNorm_le {ι : Type*} [Fintype ι] (v : Basis ι 𝕜 E) {u : E →L[𝕜] F} (M : ℝ≥0) (hu : ∀ i, ‖u (v i)‖₊ ≤ M) : ‖u‖₊ ≤ Fintype.card ι • ‖v.equivFunL.toContinuousLinearMap‖₊ * M := u.opNNNorm_le_bound _ fun e => by diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean index 39bf5c820a5533..8bd303b8226d75 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean @@ -924,6 +924,7 @@ theorem norm_compContinuousMultilinearMap_le (g : G →L[𝕜] G') (f : Continuo ‖g (f m)‖ ≤ ‖g‖ * (‖f‖ * ∏ i, ‖m i‖) := g.le_opNorm_of_le <| f.le_opNorm _ _ = _ := (mul_assoc _ _ _).symm +set_option backward.isDefEq.respectTransparency false in /-- Flip arguments in `f : G →L[𝕜] ContinuousMultilinearMap 𝕜 E G'` to get `ContinuousMultilinearMap 𝕜 E (G →L[𝕜] G')` -/ @[simps! apply_apply] diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean index 14e5230d77ab1b..6e759e7d578086 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean @@ -137,6 +137,7 @@ theorem ContinuousMultilinearMap.uncurry_curryLeft (f : ContinuousMultilinearMap variable (𝕜 Ei G) +set_option backward.isDefEq.respectTransparency false in /-- The space of continuous multilinear maps on `Π(i : Fin (n+1)), E i` is canonically isomorphic to the space of continuous linear maps from `E 0` to the space of continuous multilinear maps on `Π(i : Fin n), E i.succ`, by separating the first variable. We register this isomorphism in @@ -204,6 +205,7 @@ theorem ContinuousMultilinearMap.uncurryRight_apply (m : ∀ i, Ei i) : f.uncurryRight m = f (init m) (m (last n)) := rfl +set_option backward.isDefEq.respectTransparency false in /-- Given a continuous multilinear map `f` in `n+1` variables, split the last variable to obtain a continuous multilinear map in `n` variables into continuous linear maps, given by `m ↦ (x ↦ f (snoc m x))`. -/ @@ -244,6 +246,7 @@ theorem ContinuousMultilinearMap.uncurry_curryRight (f : ContinuousMultilinearMa variable (𝕜 Ei G) +set_option backward.isDefEq.respectTransparency false in /-- The space of continuous multilinear maps on `Π(i : Fin (n+1)), Ei i` is canonically isomorphic to the space of continuous multilinear maps on `Π(i : Fin n), Ei <| castSucc i` with values in the @@ -362,6 +365,7 @@ theorem ContinuousMultilinearMap.uncurryMid_curryMid (p : Fin (n + 1)) variable (𝕜 Ei G) +set_option backward.isDefEq.respectTransparency false in /-- `ContinuousMultilinearMap.curryMid` as a linear isometry equivalence. -/ @[simps! apply symm_apply] def ContinuousMultilinearMap.curryMidEquiv (p : Fin (n + 1)) : @@ -576,6 +580,7 @@ theorem uncurrySum_apply (f : ContinuousMultilinearMap 𝕜 (fun _ : ι => G) variable (𝕜 ι ι' G G') +set_option backward.isDefEq.respectTransparency false in /-- Linear isometric equivalence between the space of continuous multilinear maps with variables indexed by `ι ⊕ ι'` and the space of continuous multilinear maps with variables indexed by `ι` taking values in the space of continuous multilinear maps with variables indexed by `ι'`. diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean index 85d108520eaa5c..c8ae7ff3aa3e1a 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean @@ -101,6 +101,7 @@ theorem injectiveSeminorm_apply (x : ⨂[𝕜] i, E i) : simpa only [injectiveSeminorm, Set.coe_setOf, Set.mem_setOf_eq] using Seminorm.sSup_apply dualSeminorms_bounded +set_option backward.isDefEq.respectTransparency false in attribute [-instance] instSeminormedAddCommGroup in @[deprecated "`injectiveSeminorm` is deprecated in favor of the extensionally equal `projectiveSeminorm`" diff --git a/Mathlib/Analysis/Normed/Module/WeakDual.lean b/Mathlib/Analysis/Normed/Module/WeakDual.lean index 99aeca6008b7bf..f455dd7bd7e1aa 100644 --- a/Mathlib/Analysis/Normed/Module/WeakDual.lean +++ b/Mathlib/Analysis/Normed/Module/WeakDual.lean @@ -169,6 +169,7 @@ map. -/ def continuousLinearMapToWeakDual : StrongDual 𝕜 E →L[𝕜] WeakDual 𝕜 E := { StrongDual.toWeakDual with } +set_option backward.isDefEq.respectTransparency false in /-- The weak-star topology is coarser than the dual-norm topology. -/ theorem dual_norm_topology_le_weak_dual_topology : (UniformSpace.toTopologicalSpace : TopologicalSpace (StrongDual 𝕜 E)) ≤ diff --git a/Mathlib/Analysis/Normed/Operator/Banach.lean b/Mathlib/Analysis/Normed/Operator/Banach.lean index 26a7925b5d0952..7f1baee565d4b2 100644 --- a/Mathlib/Analysis/Normed/Operator/Banach.lean +++ b/Mathlib/Analysis/Normed/Operator/Banach.lean @@ -364,6 +364,7 @@ lemma equivRange_symm_toLinearEquiv (hinj : Injective f) (hclo : IsClosed (range (f.equivRange hinj hclo).toLinearEquiv.symm = (LinearEquiv.ofInjective f.toLinearMap hinj).symm := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma equivRange_symm_apply (hinj : Injective f) (hclo : IsClosed (range f)) (x : E) : (f.equivRange hinj hclo).symm ⟨f x, by simp⟩ = x := by diff --git a/Mathlib/Analysis/Normed/Operator/Compact/FredholmAlternative.lean b/Mathlib/Analysis/Normed/Operator/Compact/FredholmAlternative.lean index 4382d12b0f2880..690de19e3fd622 100644 --- a/Mathlib/Analysis/Normed/Operator/Compact/FredholmAlternative.lean +++ b/Mathlib/Analysis/Normed/Operator/Compact/FredholmAlternative.lean @@ -115,6 +115,7 @@ theorem antilipschitz_of_not_hasEigenvalue (hT : IsCompactOperator T) (hμ : μ -- which is a contradiction. exact hasEigenvalue_of_hasEigenvector this +set_option backward.isDefEq.respectTransparency.types false in /-- Given an endomorphism `S` of a normed space that's a closed embedding but not surjective, we can find a sequence of vectors `f n`, living inside a shell, such that `f n` is in the diff --git a/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean b/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean index a91bff2098caad..1f7c54af7551f6 100644 --- a/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean +++ b/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean @@ -34,6 +34,7 @@ variable {𝕜 V W : Type*} [NontriviallyNormedField 𝕜] [SeminormedAddCommGro [SeminormedAddCommGroup W] [NormedSpace 𝕜 V] [NormedSpace 𝕜 W] [SeparatingDual 𝕜 V] [SeparatingDual 𝕜 W] +set_option backward.isDefEq.respectTransparency.types false in /-- This is the continuous version of `AlgEquiv.eq_linearEquivConjAlgEquiv`. -/ public theorem ContinuousAlgEquiv.eq_continuousLinearEquivConjContinuousAlgEquiv (f : (V →L[𝕜] V) ≃A[𝕜] (W →L[𝕜] W)) : @@ -151,6 +152,7 @@ end auxiliaryDefs open ComplexOrder +set_option backward.isDefEq.respectTransparency.types false in /-- The ⋆-algebra equivalence version of `ContinuousAlgEquiv.eq_continuousLinearEquivConjContinuousAlgEquiv`. diff --git a/Mathlib/Analysis/Normed/Operator/Extend.lean b/Mathlib/Analysis/Normed/Operator/Extend.lean index 69a0fdf95e9e18..993ea9b00be8ad 100644 --- a/Mathlib/Analysis/Normed/Operator/Extend.lean +++ b/Mathlib/Analysis/Normed/Operator/Extend.lean @@ -246,6 +246,7 @@ variable [NormedDivisionRing 𝕜] [NormedDivisionRing 𝕜₂] variable {σ₁₂ : 𝕜 →+* 𝕜₂} {σ₂₁ : 𝕜₂ →+* 𝕜} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] variable (f : E ≃ₛₗ[σ₁₂] F) (e₁ : E →ₗ[𝕜] Eₗ) (e₂ : F →ₗ[𝕜₂] Fₗ) +set_option backward.isDefEq.respectTransparency false in /-- Extension of a linear equivalence `f : E ≃ₛₗ[σ₁₂] F` to a continuous linear equivalence `Eₗ ≃SL[σ₁₂] Fₗ`, where `E` and `F` are normed spaces and `Eₗ` and `Fₗ` are Banach spaces, using dense maps `e₁ : E →ₗ[𝕜₁] Eₗ` and `e₂ : F →ₗ[𝕜₂] F₂` together with bounds diff --git a/Mathlib/Analysis/Normed/Ring/Basic.lean b/Mathlib/Analysis/Normed/Ring/Basic.lean index 5ffd65f31cb975..910282eec4b844 100644 --- a/Mathlib/Analysis/Normed/Ring/Basic.lean +++ b/Mathlib/Analysis/Normed/Ring/Basic.lean @@ -924,7 +924,7 @@ end SubringClass namespace AbsoluteValue /-- A real absolute value on a ring determines a `NormedRing` structure. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def toNormedRing {R : Type*} [Ring R] (v : AbsoluteValue R ℝ) : NormedRing R where norm := v dist x y := v (-x + y) diff --git a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean index 466d40538cf042..34ff6715a2ebae 100644 --- a/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean +++ b/Mathlib/Analysis/Normed/Unbundled/FiniteExtension.lean @@ -97,6 +97,7 @@ theorem norm_isNonarchimedean (hna : IsNonarchimedean (Norm.norm : K → ℝ)) : · exact le_max_of_le_left (le_trans hx (norm_repr_le_norm B ixy)) · exact le_max_of_le_right (le_trans hy (norm_repr_le_norm B ixy)) +set_option backward.isDefEq.respectTransparency false in /-- For any `K`-basis of `L`, `B.norm` is bounded with respect to multiplication. That is, `∃ (c : ℝ), c > 0` such that ` ∀ (x y : L), B.norm (x * y) ≤ c * B.norm x * B.norm y`. -/ theorem norm_mul_le_const_mul_norm {i : ι} (hBi : B i = (1 : L)) diff --git a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean index be9786239df23c..0c1f2dffc5eb86 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean @@ -286,6 +286,7 @@ theorem norm_root_le_spectralValue {f : AlgebraNorm K L} (hf_pm : IsPowMul f) open Multiset +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` is a nonarchimedean, power-multiplicative `K`-algebra norm on `L`, then the spectral value of a polynomial `p : K[X]` that decomposes into linear factors in `L` is equal to the maximum of the norms of the roots. See [S. Bosch, U. Güntzer, R. Remmert, *Non-Archimedean Analysis* @@ -690,6 +691,8 @@ universe u v variable {K : Type u} [NontriviallyNormedField K] {L : Type v} [Field L] [Algebra K L] [Algebra.IsAlgebraic K L] [hu : IsUltrametricDist K] +set_option allowUnsafeReducibility true + /-- If `K` is a field complete with respect to a nontrivial nonarchimedean multiplicative norm and `L/K` is an algebraic extension, then any power-multiplicative `K`-algebra norm on `L` coincides with the spectral norm. -/ @@ -847,7 +850,7 @@ namespace spectralNorm variable (K L) /-- `L` with the spectral norm is a `NormedField`. -/ -@[implicit_reducible] +@[instance_reducible] def normedField : NormedField L := { (inferInstance : Field L) with norm x := (spectralNorm K L x : ℝ) @@ -866,7 +869,7 @@ def normedField : NormedField L := edist_dist x y := by rw [ENNReal.ofReal_eq_coe_nnreal] } /-- `L` with the spectral norm is a `NontriviallyNormedField`. -/ -@[implicit_reducible] +@[instance_reducible] def nontriviallyNormedField : NontriviallyNormedField L where __ := spectralNorm.normedField K L non_trivial := @@ -874,25 +877,25 @@ def nontriviallyNormedField : NontriviallyNormedField L where ⟨algebraMap K L x, hx.trans_eq <| (spectralNorm_extends _).symm⟩ /-- `L` with the spectral norm is a `SeminormedRing`. -/ -@[implicit_reducible] +@[instance_reducible] def seminormedRing : SeminormedRing L := by letI : NormedField L := normedField K L infer_instance /-- `L` with the spectral norm is a `NormedAddCommGroup`. -/ -@[implicit_reducible] +@[instance_reducible] def normedAddCommGroup : NormedAddCommGroup L := by haveI : NormedField L := normedField K L infer_instance /-- `L` with the spectral norm is a `SeminormedAddCommGroup`. -/ -@[implicit_reducible] +@[instance_reducible] def seminormedAddCommGroup : SeminormedAddCommGroup L := by have : NormedField L := normedField K L infer_instance /-- `L` with the spectral norm is a `NormedSpace` over `K`. -/ -@[implicit_reducible] +@[instance_reducible] def normedSpace : @NormedSpace K L _ (seminormedAddCommGroup K L) := letI _ := seminormedAddCommGroup K L { (inferInstance : Module K L) with @@ -901,7 +904,7 @@ def normedSpace : @NormedSpace K L _ (seminormedAddCommGroup K L) := exact le_of_eq (map_smul_eq_mul _ _ _) } /-- `L` with the spectral norm is a `NormedAlgebra` over `K`. -/ -@[implicit_reducible] +@[instance_reducible] def normedAlgebra : @NormedAlgebra K L _ (seminormedRing K L) := letI _ := normedField K L @@ -909,7 +912,7 @@ def normedAlgebra : /-- `L` with the spectral norm is a `NormedAlgebra` over any intermediate `E` that is a normed algebra over `K`. -/ -@[implicit_reducible] +@[instance_reducible] def normedAlgebra' (E L : Type*) [Field L] [Algebra K L] [Algebra.IsAlgebraic K L] [NormedField E] [NormedAlgebra K E] [Algebra E L] [IsScalarTower K E L] : @NormedAlgebra E L _ (seminormedRing K L) := @@ -924,11 +927,11 @@ def normedAlgebra' (E L : Type*) [Field L] [Algebra K L] [Algebra.IsAlgebraic K exact Or.inl <| (spectralNorm.eq_of_tower _).symm } /-- The metric space structure on `L` induced by the spectral norm. -/ -@[implicit_reducible] +@[instance_reducible] def metricSpace : MetricSpace L := (normedField K L).toMetricSpace /-- The uniform space structure on `L` induced by the spectral norm. -/ -@[implicit_reducible] +@[instance_reducible] def uniformSpace : UniformSpace L := (metricSpace K L).toUniformSpace /-- If `L/K` is finite dimensional, then `L` is a complete space with respect to topology induced diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 1c6678f62c54ab..cdc2a71a64edb5 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -1301,7 +1301,7 @@ instance (priority := 100) (𝕜 : Type*) [h : RCLike 𝕜] : IsRCLikeNormedFiel /-- A copy of an `RCLike` field in which the `NormedField` field is adjusted to be become defeq to a propeq one. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def RCLike.copy_of_normedField {𝕜 : Type*} (h : RCLike 𝕜) (hk : NormedField 𝕜) (h'' : hk = h.toNormedField) : RCLike 𝕜 where __ := hk @@ -1345,7 +1345,7 @@ noncomputable def RCLike.copy_of_normedField {𝕜 : Type*} (h : RCLike 𝕜) (h /-- Given a normed field `𝕜` satisfying `IsRCLikeNormedField 𝕜`, build an associated `RCLike 𝕜` structure on `𝕜` which is definitionally compatible with the given normed field structure. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def IsRCLikeNormedField.rclike (𝕜 : Type*) [hk : NormedField 𝕜] [h : IsRCLikeNormedField 𝕜] : RCLike 𝕜 := by choose p hp using h.out @@ -1378,6 +1378,7 @@ theorem symm_smul_apply (e : V ≃ₗᵢ[𝕜] W) (α : unitary 𝕜) (x : W) : @[simp] theorem toContinuousLinearEquiv_smul (e : G ≃ₗᵢ[𝕜] W) (α : unitary 𝕜) : (α • e).toContinuousLinearEquiv = Unitary.toUnits α • e.toContinuousLinearEquiv := rfl +set_option backward.isDefEq.respectTransparency false in theorem smul_trans (α : unitary 𝕜) (e : V ≃ₗᵢ[𝕜] G) (f : G ≃ₗᵢ[𝕜] W) : (α • e).trans f = α • (e.trans f) := by ext; simp diff --git a/Mathlib/Analysis/RCLike/BoundedContinuous.lean b/Mathlib/Analysis/RCLike/BoundedContinuous.lean index 1dc8f44d0cbef7..5e6dfd73891ac4 100644 --- a/Mathlib/Analysis/RCLike/BoundedContinuous.lean +++ b/Mathlib/Analysis/RCLike/BoundedContinuous.lean @@ -22,6 +22,7 @@ variable (𝕜 E : Type*) [RCLike 𝕜] [PseudoEMetricSpace E] namespace RCLike +set_option backward.isDefEq.respectTransparency false in /-- On a star subalgebra of bounded continuous functions, the operations "restrict scalars to ℝ" and "forget that a bounded continuous function is a bounded" commute. -/ theorem restrict_toContinuousMap_eq_toContinuousMapStar_restrict diff --git a/Mathlib/Analysis/RCLike/ContinuousMap.lean b/Mathlib/Analysis/RCLike/ContinuousMap.lean index 707ecca8a0a459..0ccede3a32df44 100644 --- a/Mathlib/Analysis/RCLike/ContinuousMap.lean +++ b/Mathlib/Analysis/RCLike/ContinuousMap.lean @@ -32,6 +32,7 @@ variable {X : Type*} (𝕜 : Type*) [TopologicalSpace X] [RCLike 𝕜] open ComplexOrder +set_option backward.isDefEq.respectTransparency.types false in variable (X) in /-- `ContinuousMap.realToRCLike` as an order embedding. -/ @[simps] def realToRCLikeOrderEmbedding : C(X, ℝ) ↪o C(X, 𝕜) where diff --git a/Mathlib/Analysis/RCLike/Sqrt.lean b/Mathlib/Analysis/RCLike/Sqrt.lean index 9d7020a0061a07..020ba6d6ebe0bd 100644 --- a/Mathlib/Analysis/RCLike/Sqrt.lean +++ b/Mathlib/Analysis/RCLike/Sqrt.lean @@ -82,6 +82,7 @@ theorem RCLike.re_sqrt_ofReal {a : ℝ} : @[simp] theorem RCLike.sqrt_complex {a : ℂ} : sqrt a = a.sqrt := by simp [sqrt] +set_option backward.isDefEq.respectTransparency false in theorem Complex.sqrt_of_nonneg {a : ℂ} (ha : 0 ≤ a) : a.sqrt = √a.re := by obtain ⟨α : ℝ, hα, rfl⟩ := RCLike.nonneg_iff_exists_ofReal.mp ha diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean index 33a581fdc10383..47d2ab09a82a81 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean @@ -225,6 +225,7 @@ lemma coe_path (x y : Circle) : (path x y : _ → _) = ext t rw [path_apply, comp_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma path_self (x : Circle) : path x x = Path.refl x := by ext a diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/CircleAddChar.lean b/Mathlib/Analysis/SpecialFunctions/Complex/CircleAddChar.lean index 4f8e207c7027df..c547e9ed5e1b90 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/CircleAddChar.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/CircleAddChar.lean @@ -82,6 +82,7 @@ lemma injective_toCircle : Injective (toCircle : ZMod N → Circle) := /-- The additive character from `ZMod N` to `ℂ`, sending `j mod N` to `exp (2 * π * I * j / N)`. -/ noncomputable def stdAddChar : AddChar (ZMod N) ℂ := Circle.coeHom.compAddChar toCircle +set_option backward.isDefEq.respectTransparency.types false in lemma stdAddChar_coe (j : ℤ) : stdAddChar (j : ZMod N) = exp (2 * π * I * j / N) := by simp [stdAddChar, toCircle_intCast] diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/ConjSqrt.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/ConjSqrt.lean index b9c6cf68f86e3b..e131ea82eab34b 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/ConjSqrt.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/ConjSqrt.lean @@ -27,25 +27,31 @@ variable {A : Type*} [PartialOrder A] [Ring A] [StarRing A] [TopologicalSpace A] [StarOrderedRing A] [Algebra ℝ A] [ContinuousFunctionalCalculus ℝ A IsSelfAdjoint] [NonnegSpectrumClass ℝ A] [SeparatelyContinuousMul A] +set_option backward.isDefEq.respectTransparency.types false in /-- Conjugation by the square root of an element, i.e. `sqrt c * a * sqrt c`. -/ @[expose] noncomputable def conjSqrt (c : A) : A →L[ℝ] A where toLinearMap := .mulLeftRight ℝ (sqrt c, sqrt c) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toLinearMap_conjSqrt (c : A) : (conjSqrt c).toLinearMap = .mulLeftRight ℝ (sqrt c, sqrt c) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma conjSqrt_apply {c a : A} : conjSqrt c a = sqrt c * a * sqrt c := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma conjSqrt_of_not_nonneg {c a : A} (hc : ¬0 ≤ c) : conjSqrt c a = 0 := by simp [conjSqrt_apply, sqrt_of_not_nonneg hc] +set_option backward.isDefEq.respectTransparency.types false in lemma conjSqrt_monotone {c : A} : Monotone (conjSqrt c) := by intro a b hab by_cases hc : 0 ≤ c · exact IsSelfAdjoint.conjugate_le_conjugate hab (by cfc_tac) · simp [conjSqrt_of_not_nonneg hc] +set_option backward.isDefEq.respectTransparency.types false in @[gcongr] lemma conjSqrt_le_conjSqrt {c a b : A} (h : a ≤ b) : conjSqrt c a ≤ conjSqrt c b := conjSqrt_monotone h @@ -61,6 +67,7 @@ lemma isStrictlyPositive_conjSqrt_iff (c a : A) (hc : IsStrictlyPositive c := by rw [conjSqrt_apply] by_cases ha : IsSelfAdjoint a <;> grind +set_option backward.isDefEq.respectTransparency.types false in @[grind _=_] lemma ringInverse_conjSqrt (c a : A) (hc : IsStrictlyPositive c := by cfc_tac) : (conjSqrt c a)⁻¹ʳ = conjSqrt c⁻¹ʳ a⁻¹ʳ := by @@ -69,6 +76,7 @@ lemma ringInverse_conjSqrt (c a : A) (hc : IsStrictlyPositive c := by cfc_tac) : · have : ¬IsUnit (conjSqrt c a) := by grind [conjSqrt_apply, IsUnit.mul_left_iff] simp [inverse_non_unit a ha, inverse_non_unit _ this] +set_option backward.isDefEq.respectTransparency.types false in @[grind =] lemma conjSqrt_ringInverse_conjSqrt (c a : A) (hc : IsStrictlyPositive c := by cfc_tac) : conjSqrt c⁻¹ʳ (conjSqrt c a) = a := by @@ -78,15 +86,18 @@ lemma conjSqrt_ringInverse_conjSqrt (c a : A) (hc : IsStrictlyPositive c := by c have : Commute (sqrt c) (sqrt c⁻¹ʳ) finish +set_option backward.isDefEq.respectTransparency.types false in @[grind =] lemma conjSqrt_conjSqrt_ringInverse (c a : A) (hc : IsStrictlyPositive c := by cfc_tac) : conjSqrt c (conjSqrt c⁻¹ʳ a) = a := by grind [conjSqrt_ringInverse_conjSqrt _ _ hc.ringInverse] +set_option backward.isDefEq.respectTransparency.types false in @[grind =] lemma conjSqrt_one (c : A) (hc : 0 ≤ c := by cfc_tac) : conjSqrt c 1 = c := by rw [conjSqrt_apply, mul_one, sqrt_mul_sqrt_self _] +set_option backward.isDefEq.respectTransparency.types false in @[grind =] lemma conjSqrt_ringInverse_self (c : A) (hc : IsStrictlyPositive c := by cfc_tac) : conjSqrt c⁻¹ʳ c = 1 := by diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/RingInverseOrder.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/RingInverseOrder.lean index 5a8472a75f3e13..e4d1cd71be4cf9 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/RingInverseOrder.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow/RingInverseOrder.lean @@ -99,6 +99,7 @@ public lemma convexOn_ringInverse : _ = _ := by rw [← ringInverse_conjSqrt _ _ xpos, conjSqrt_conjSqrt_ringInverse _ _ xpos] +set_option backward.isDefEq.respectTransparency.types false in public lemma convexOn_ringInverse_algebraMap_add {t : ℝ} (ht : 0 < t) : ConvexOn ℝ (Ici (0 : A)) (fun x : A => Ring.inverse (algebraMap ℝ A t + x)) := by have : ∀ x ∈ Ici (0 : A), IsStrictlyPositive (algebraMap ℝ A t + x) := by grind diff --git a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean index c8788f4428e684..59061499ba94c8 100644 --- a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean +++ b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean @@ -649,6 +649,7 @@ lemma coeff_weierstrassPExceptSeries (l₀ x : ℂ) (i : ℕ) : simp [h₁, tsum_mul_left, sumInvPow, add_assoc, one_add_one_eq_two, ← zpow_natCast, -neg_add_rev] +set_option backward.isDefEq.respectTransparency.types false in /-- In the power series expansion of `℘(z) = ∑ᵢ aᵢ (z - x)ⁱ` at some `x ∉ L`, each `aᵢ` can be written as a sum over `l ∈ L`, i.e. diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean index 858c9750c8c623..e66f719517bc84 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean @@ -325,6 +325,7 @@ theorem integral_cexp_neg_mul_sq_norm (hb : 0 < b.re) : ∫ v : V, cexp (-b * ‖v‖ ^ 2) = (π / b) ^ (Module.finrank ℝ V / 2 : ℂ) := by simpa using integral_cexp_neg_mul_sq_norm_add hb 0 (0 : V) +set_option backward.isDefEq.respectTransparency.types false in theorem integral_rexp_neg_mul_sq_norm {b : ℝ} (hb : 0 < b) : ∫ v : V, rexp (-b * ‖v‖ ^ 2) = (π / b) ^ (Module.finrank ℝ V / 2 : ℝ) := by rw [← ofReal_inj] diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index fe745c1c5d5d34..a35cf9821d420d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -52,6 +52,7 @@ theorem log_of_pos (hx : 0 < x) : log x = expOrderIso.symm ⟨x, hx⟩ := by congr exact abs_of_pos hx +set_option backward.isDefEq.respectTransparency false in theorem exp_log_eq_abs (hx : x ≠ 0) : exp (log x) = |x| := by rw [log_of_ne_zero hx, ← coe_expOrderIso_apply, OrderIso.apply_symm_apply, Subtype.coe_mk] diff --git a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean index f1733727682ffd..fc408708586741 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean @@ -72,6 +72,7 @@ end Exp namespace ENNReal section OrderIso +set_option backward.isDefEq.respectTransparency false in /-- `ENNReal.log` and its inverse `EReal.exp` are an order isomorphism between `ℝ≥0∞` and `EReal`. -/ noncomputable diff --git a/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean b/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean index 81e3ca5316d90c..b63e62a9fc7146 100644 --- a/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean +++ b/Mathlib/Analysis/SpecialFunctions/Sigmoid.lean @@ -252,6 +252,7 @@ lemma sigmoid_neg (x : ℝ) : sigmoid (-x) = σ (sigmoid x) := by ext exact Real.sigmoid_neg x +set_option backward.isDefEq.respectTransparency false in open Set in lemma range_sigmoid : range unitInterval.sigmoid = Ioo 0 1 := by rw [sigmoid, Subtype.range_coind, Real.range_sigmoid] diff --git a/Mathlib/Analysis/SumOverResidueClass.lean b/Mathlib/Analysis/SumOverResidueClass.lean index bdc7e0dec25275..a48038cf114a6e 100644 --- a/Mathlib/Analysis/SumOverResidueClass.lean +++ b/Mathlib/Analysis/SumOverResidueClass.lean @@ -28,6 +28,7 @@ lemma Finset.sum_indicator_mod {R : Type*} [AddCommMonoid R] (m : ℕ) [NeZero m simp only [Finset.sum_apply, Set.indicator_apply, Set.mem_setOf_eq, Finset.sum_ite_eq, Finset.mem_univ, ↓reduceIte] +set_option backward.isDefEq.respectTransparency false in open Set in /-- A sequence `f` with values in an additive topological group `R` is summable on the residue class of `k` mod `m` if and only if `f (m*n + k)` is summable. -/ @@ -99,6 +100,7 @@ lemma summable_indicator_mod_iff {m : ℕ} [NeZero m] {f : ℕ → ℝ} (hf : An open ZMod +set_option backward.isDefEq.respectTransparency false in /-- If `f` is a summable function on `ℕ`, and `0 < N`, then we may compute `∑' n : ℕ, f n` by summing each residue class mod `N` separately. -/ lemma Nat.sumByResidueClasses {R : Type*} [AddCommGroup R] [UniformSpace R] [IsUniformAddGroup R] diff --git a/Mathlib/CategoryTheory/Abelian/Basic.lean b/Mathlib/CategoryTheory/Abelian/Basic.lean index 095d0d9648ba61..416bd08699705d 100644 --- a/Mathlib/CategoryTheory/Abelian/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/Basic.lean @@ -256,7 +256,7 @@ in which the coimage-image comparison morphism is always an isomorphism, is an abelian category. -/ @[stacks 0109 "The Stacks project uses this characterisation at the definition of an abelian category.", - implicit_reducible] + instance_reducible] def ofCoimageImageComparisonIsIso : Abelian C where end CategoryTheory.Abelian @@ -817,7 +817,7 @@ namespace CategoryTheory.NonPreadditiveAbelian variable (C : Type u) [Category.{v} C] [NonPreadditiveAbelian C] /-- Every `NonPreadditiveAbelian` category can be promoted to an abelian category. -/ -@[implicit_reducible] +@[instance_reducible] def abelian : Abelian C where toPreadditive := NonPreadditiveAbelian.preadditive normalMonoOfMono := fun f _ ↦ ⟨normalMonoOfMono f⟩ @@ -866,7 +866,7 @@ preadditive, has finite products, and that any morphism `f : X ⟶ Y` has a kernel `i : K ⟶ X`, a cokernel `p : Y ⟶ Q` such that `f` factors as `f = π ≫ ι` where `π : X ⟶ I` is a cokernel of `i` and `ι : I ⟶ Y` is a kernel of `p`. This assumption is packaged in a structure `AbelianStruct f`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def mk' [HasFiniteProducts C] (h : ∀ ⦃X Y : C⦄ (f : X ⟶ Y), Nonempty (AbelianStruct f)) : Abelian C where diff --git a/Mathlib/CategoryTheory/Abelian/DiagramLemmas/KernelCokernelComp.lean b/Mathlib/CategoryTheory/Abelian/DiagramLemmas/KernelCokernelComp.lean index 6d2596c97b8ef8..cd7cb28b52c50d 100644 --- a/Mathlib/CategoryTheory/Abelian/DiagramLemmas/KernelCokernelComp.lean +++ b/Mathlib/CategoryTheory/Abelian/DiagramLemmas/KernelCokernelComp.lean @@ -185,6 +185,7 @@ noncomputable def snakeInput : ShortComplex.SnakeInput C where is the connecting homomorphism `kernel g ⟶ cokernel f`. -/ noncomputable def δ : kernel g ⟶ cokernel f := (snakeInput f g).δ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma δ_fac : δ f g = - kernel.ι g ≫ cokernel.π f := by simpa using! (snakeInput f g).δ_eq (𝟙 _) (kernel.ι g ≫ biprod.inr) (-kernel.ι g) @@ -204,6 +205,7 @@ noncomputable abbrev kernelCokernelCompSequence : ComposableArrows C 5 := (cokernel.map f (f ≫ g) (𝟙 _) g (by simp)) (cokernel.map (f ≫ g) g f (𝟙 _) (by simp)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Mono ((kernelCokernelCompSequence f g).map' 0 1) := by dsimp; infer_instance diff --git a/Mathlib/CategoryTheory/Abelian/EpiWithInjectiveKernel.lean b/Mathlib/CategoryTheory/Abelian/EpiWithInjectiveKernel.lean index 5cdc78c8ab2bc6..d3d1385e919fc1 100644 --- a/Mathlib/CategoryTheory/Abelian/EpiWithInjectiveKernel.lean +++ b/Mathlib/CategoryTheory/Abelian/EpiWithInjectiveKernel.lean @@ -108,7 +108,7 @@ instance : (epiWithInjectiveKernel (C := C)).IsStableUnderRetracts where let r' : Retract (kernel f') (kernel f) := { i := kernel.map _ _ r.i.left r.i.right (Arrow.w r.i).symm r := kernel.map _ _ r.r.left r.r.right (Arrow.w r.r).symm - retract := by ext; simp [dsimp% r.left.retract] } + retract := by ext; simp } exact ⟨inferInstance, r'.injective⟩ lemma epiWithInjectiveKernel.hasLiftingProperty diff --git a/Mathlib/CategoryTheory/Abelian/Ext.lean b/Mathlib/CategoryTheory/Abelian/Ext.lean index ba7d7de4b56f41..a294b6680886fd 100644 --- a/Mathlib/CategoryTheory/Abelian/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Ext.lean @@ -49,6 +49,9 @@ open ZeroObject variable {R C} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a chain complex `X` and an object `Y`, this is the cochain complex which in degree `i` consists of the module of morphisms `X.X i ⟶ Y`. -/ @[simps! X d] diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean index 3de366e5bce4db..228b07fe83c06f 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckAxioms/Basic.lean @@ -53,7 +53,7 @@ public section namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor attribute [instance] comp_preservesFiniteLimits comp_preservesFiniteColimits @@ -100,6 +100,7 @@ lemma HasExactColimitsOfShape.domain_of_functor {D : Type*} (J : Type*) [Categor exact Cone.ext ((preservesColimitNatIso F).symm.app _) fun i ↦ (preservesColimitNatIso F).inv.naturality _ } } } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {C} in /-- @@ -517,7 +518,6 @@ lemma CountableAB4Star.of_hasExactLimitsOfShape_nat_and_finite [HasCountableProd section EpiMono -open Functor section diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ColimCoyoneda.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ColimCoyoneda.lean index 572ecc4ef21122..4a3849a233aba5 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ColimCoyoneda.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ColimCoyoneda.lean @@ -86,6 +86,7 @@ lemma hf (j : Under j₀) : colimit.ι (kernel (g y)) j ≫ f y = (kernel.ι (g y)).app j := (IsColimit.ι_map _ _ _ _).trans (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {y} in include hc hy in diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean index 74d39579f9e6ac..fa4de714fb932a 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean @@ -242,6 +242,7 @@ instance : (functor hG A₀ J).IsWellOrderContinuous where simp only [Subobject.mk_arrow] exact transfiniteIterate_limit (largerSubobject hG) A₀ m hm⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {J} in /-- For any `j`, the map `(functor hG A₀ J).map (homOfLE bot_le : ⊥ ⟶ j)` diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ModuleEmbedding/GabrielPopescu.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ModuleEmbedding/GabrielPopescu.lean index 3a26d2a81604f7..d9634c52c52c08 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ModuleEmbedding/GabrielPopescu.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/ModuleEmbedding/GabrielPopescu.lean @@ -73,6 +73,7 @@ theorem ι_d {G A : C} {M : ModuleCat (End G)ᵐᵒᵖ} (g : M ⟶ ModuleCat.of Sigma.ι _ m ≫ d g = g.hom m := by simp [d] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local instance] IsFiltered.isConnected in /-- This is the "Lemma" in [mitchell1981]. -/ diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean index b1353b7fcfb467..fa1da99e06830e 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean @@ -267,6 +267,7 @@ lemma injectiveDimension_eq_of_iso {X Y : C} (e : X ≅ Y) : exact ⟨fun h ↦ hasInjectiveDimensionLT_of_iso e _, fun h ↦ hasInjectiveDimensionLT_of_iso e.symm _⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma Retract.injectiveDimension_le {X Y : C} (h : Retract X Y) : injectiveDimension X ≤ injectiveDimension Y := sInf_le_sInf_of_subset_insert_top (fun n hn ↦ by diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 5b9c4a72c80294..7599ce0994e666 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -214,7 +214,6 @@ lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : by simpa [R.cochainComplex_d _ _ _ _ rfl rfl, ← cancel_mono (R.cochainComplexXIso m m rfl).inv] using hf, by simp [extMk]⟩ -set_option backward.isDefEq.respectTransparency false in lemma mk₀_comp_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) (hf : f ≫ R.cocomplex.d n m = 0) {X' : C} (g : X' ⟶ X) : (Ext.mk₀ g).comp (R.extMk f m hm hf) (zero_add _) = @@ -231,7 +230,6 @@ lemma mk₀_comp_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + ← ShiftedHom.comp_assoc _ _ _ (add_zero _) (add_zero (n : ℤ)) (by simp)] simp -set_option backward.isDefEq.respectTransparency false in variable {R} in lemma extMk_comp_mk₀ {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) (hf : f ≫ R.cocomplex.d n m = 0) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Resolution.lean b/Mathlib/CategoryTheory/Abelian/Injective/Resolution.lean index 0bc98d1925ba10..d703736b323876 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Resolution.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Resolution.lean @@ -96,6 +96,7 @@ def desc {Y Z : C} (f : Z ⟶ Y) (I : InjectiveResolution Y) (J : InjectiveResol CochainComplex.mkHom _ _ (descFZero f _ _) (descFOne f _ _) (descFOne_zero_comm f I J).symm fun n ⟨g, g', w⟩ => ⟨(descFSucc I J n g g' w.symm).1, (descFSucc I J n g g' w.symm).2.symm⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The resolution maps intertwine the descent of a morphism and that morphism. -/ @[reassoc (attr := simp)] theorem desc_commutes {Y Z : C} (f : Z ⟶ Y) (I : InjectiveResolution Y) @@ -295,15 +296,18 @@ variable [Abelian C] [EnoughInjectives C] (Z : C) -- The construction of the injective resolution `of` would be very, very slow -- if it were not broken into separate definitions and lemmas +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `InjectiveResolution.of`. -/ def ofCocomplex : CochainComplex C ℕ := CochainComplex.mk' (Injective.under Z) (Injective.syzygies (Injective.ι Z)) (Injective.d (Injective.ι Z)) fun f => ⟨_, Injective.d f, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma ofCocomplex_d_0_1 : (ofCocomplex Z).d 0 1 = d (Injective.ι Z) := by simp [ofCocomplex] +set_option backward.isDefEq.respectTransparency.types false in lemma ofCocomplex_exactAt_succ (n : ℕ) : (ofCocomplex Z).ExactAt (n + 1) := by rw [HomologicalComplex.exactAt_iff' _ n (n + 1) (n + 1 + 1) (by simp) (by simp)] @@ -315,6 +319,7 @@ lemma ofCocomplex_exactAt_succ (n : ℕ) : | n + 1 => apply exact_f_d ((CochainComplex.mkAux _ _ _ (d (Injective.ι Z)) (d (d (Injective.ι Z))) _ _ (n + 1)).f) +set_option backward.isDefEq.respectTransparency.types false in instance (n : ℕ) : Injective ((ofCocomplex Z).X n) := by obtain (_ | _ | _ | n) := n <;> apply Injective.injective_under diff --git a/Mathlib/CategoryTheory/Abelian/LeftDerived.lean b/Mathlib/CategoryTheory/Abelian/LeftDerived.lean index cabbc9289b31e8..a954ba0af652d5 100644 --- a/Mathlib/CategoryTheory/Abelian/LeftDerived.lean +++ b/Mathlib/CategoryTheory/Abelian/LeftDerived.lean @@ -90,7 +90,6 @@ lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_inv_naturality erw [(F.mapHomotopyCategoryFactors (ComplexShape.down ℕ)).inv.naturality_assoc] rfl -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_hom_naturality {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y) @@ -118,8 +117,8 @@ noncomputable def ProjectiveResolution.isoLeftDerivedObj {X : C} (P : Projective (P.isoLeftDerivedToHomotopyCategoryObj F) ≪≫ (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).app _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma ProjectiveResolution.isoLeftDerivedObj_hom_naturality {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y) @@ -135,7 +134,6 @@ lemma ProjectiveResolution.isoLeftDerivedObj_hom_naturality erw [(HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.naturality] rfl -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma ProjectiveResolution.isoLeftDerivedObj_inv_naturality {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y) @@ -265,6 +263,7 @@ noncomputable def fromLeftDerivedZero' {X : C} dsimp rw [← F.map_comp, complex_d_comp_π_f_zero, F.map_zero]) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma pOpcycles_comp_fromLeftDerivedZero' {C} [Category* C] [Abelian C] {X : C} (P : ProjectiveResolution X) (F : C ⥤ D) [F.Additive] : @@ -334,6 +333,7 @@ lemma ProjectiveResolution.fromLeftDerivedZero_eq erw [← NatTrans.naturality_assoc] rfl +set_option backward.isDefEq.respectTransparency.types false in instance (F : C ⥤ D) [F.Additive] (X : C) [Projective X] : IsIso (F.fromLeftDerivedZero.app X) := by rw [(ProjectiveResolution.self X).fromLeftDerivedZero_eq F] @@ -343,6 +343,7 @@ section variable (F : C ⥤ D) [F.Additive] [PreservesFiniteColimits F] +set_option backward.isDefEq.respectTransparency.types false in instance {X : C} (P : ProjectiveResolution X) : IsIso (P.fromLeftDerivedZero' F) := by dsimp [ProjectiveResolution.fromLeftDerivedZero'] diff --git a/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean b/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean index 9c61dd118dcb4e..621ba4af76bcff 100644 --- a/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean +++ b/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean @@ -220,6 +220,7 @@ abbrev r (A : C) : A ⟶ cokernel (diag A) := instance mono_Δ {A : C} : Mono (diag A) := mono_of_mono_fac <| prod.lift_fst _ _ +set_option backward.isDefEq.respectTransparency.types false in instance mono_r {A : C} : Mono (r A) := by let hl : IsLimit (KernelFork.ofι (diag A) (cokernel.condition (diag A))) := monoIsKernelOfCokernel _ (colimit.isColimit _) @@ -409,7 +410,7 @@ theorem add_comp (X Y Z : C) (f g : X ⟶ Y) (h : Y ⟶ Z) : (f + g) ≫ h = f rw [add_def, sub_comp, neg_def, sub_comp, zero_comp, add_def, neg_def] /-- Every `NonPreadditiveAbelian` category is preadditive. -/ -@[implicit_reducible] +@[instance_reducible] def preadditive : Preadditive C where homGroup X Y := { add_assoc := add_assoc diff --git a/Mathlib/CategoryTheory/Abelian/Opposite.lean b/Mathlib/CategoryTheory/Abelian/Opposite.lean index 253a4f004a512b..719ff615478d30 100644 --- a/Mathlib/CategoryTheory/Abelian/Opposite.lean +++ b/Mathlib/CategoryTheory/Abelian/Opposite.lean @@ -105,10 +105,12 @@ def cokernelOpOp : cokernel f.op ≅ Opposite.op (kernel f) := def kernelUnopUnop : kernel g.unop ≅ (cokernel g).unop := (kernelUnopOp g).unop.symm +set_option backward.isDefEq.respectTransparency.types false in theorem kernel.ι_unop : (kernel.ι g.unop).op = eqToHom (Opposite.op_unop _) ≫ cokernel.π g ≫ (kernelUnopOp g).inv := by simp +set_option backward.isDefEq.respectTransparency.types false in theorem cokernel.π_unop : (cokernel.π g.unop).op = (cokernelUnopOp g).hom ≫ kernel.ι g ≫ eqToHom (Opposite.op_unop _).symm := by diff --git a/Mathlib/CategoryTheory/Abelian/Preradical/Basic.lean b/Mathlib/CategoryTheory/Abelian/Preradical/Basic.lean index 7a083fdc2642c8..ac0ae859b41888 100644 --- a/Mathlib/CategoryTheory/Abelian/Preradical/Basic.lean +++ b/Mathlib/CategoryTheory/Abelian/Preradical/Basic.lean @@ -53,7 +53,6 @@ abbrev r : C ⥤ C := Φ.obj.left /-- The structure morphism `Φ.r ⟶ 𝟭 C` of a preradical `Φ`. -/ abbrev ι : Φ.r ⟶ 𝟭 C := Φ.obj.hom -set_option backward.isDefEq.respectTransparency false in @[simp] lemma r_map_ι_app (X : C) : Φ.r.map (Φ.ι.app X) = Φ.ι.app (Φ.r.obj X) := by rw [← cancel_mono (Φ.ι.app X)] @@ -69,14 +68,12 @@ instance [Φ.IsIdempotent] (X : C) : IsIso (Φ.ι.app (Φ.r.obj X)) := inferInstanceAs (IsIso ((Functor.whiskerLeft Φ.r Φ.ι).app X)) -set_option backward.isDefEq.respectTransparency false in instance [Φ.IsIdempotent] (X : C) : IsIso (Φ.r.map (Φ.ι.app X)) := by rw [r_map_ι_app] infer_instance set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance {D : Type*} [Category* D] (F : D ⥤ C) : Mono (Functor.whiskerLeft F Φ.ι) := by rw [NatTrans.mono_iff_mono_app] diff --git a/Mathlib/CategoryTheory/Abelian/Preradical/Colon.lean b/Mathlib/CategoryTheory/Abelian/Preradical/Colon.lean index cef74be9f4b386..795465e33722de 100644 --- a/Mathlib/CategoryTheory/Abelian/Preradical/Colon.lean +++ b/Mathlib/CategoryTheory/Abelian/Preradical/Colon.lean @@ -89,12 +89,10 @@ of the canonical projection `Φ.π : 𝟭 C ⟶ Φ.quotient`. -/ noncomputable def isLimitKernelFork : IsLimit (KernelFork.ofι _ Φ.ι_π) := Φ.shortExact_shortComplex.fIsKernel -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma ι_π_app (X : C) : Φ.ι.app X ≫ Φ.π.app X = 0 := by simp [← NatTrans.comp_app] -set_option backward.isDefEq.respectTransparency false in /-- For `X : C`, the short complex `Φ.r.obj X ⟶ X ⟶ Φ.quotient.obj X` obtained by evaluating `Φ.shortComplex` at `X`. -/ @[simps] @@ -102,10 +100,8 @@ noncomputable def shortComplexObj (X : C) : ShortComplex C where f := Φ.ι.app X g := Φ.π.app X -set_option backward.isDefEq.respectTransparency false in instance (X : C) : Mono (Φ.shortComplexObj X).f := by dsimp; infer_instance -set_option backward.isDefEq.respectTransparency false in instance (X : C) : Epi (Φ.shortComplexObj X).g := by dsimp; infer_instance lemma shortExact_shortComplexObj (X : C) : (Φ.shortComplexObj X).ShortExact where @@ -123,7 +119,7 @@ noncomputable def isColimitCokernelCoforkObj (X : C) : IsColimit (CokernelCofork.ofπ _ (Φ.ι_π_app X)) := (Φ.shortExact_shortComplexObj X).gIsCokernel -open Functor +open CategoryTheory.Functor /-- The colon preradical from Stenström, defined as the pullback of `Φ.π : 𝟭 C ⟶ Φ.quotient` along `Φ.quotient.whiskerLeft Ψ.ι ≫ Φ.quotient.rightUnitor.hom : Φ.quotient ⋙ Ψ.r ⟶ Φ.quotient` -/ @@ -159,6 +155,7 @@ via `Φ.ι : Φ.r X ⟶ 𝟭 C` and the zero morphism `Φ.r ⟶ Φ.quotient ⋙ noncomputable def toColon : Φ ⟶ Φ.colon Ψ := MonoOver.homMk ((isPullback_colon Φ Ψ).lift Φ.ι 0 (by simp)) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma toColon_hom_left_colonπ : (toColon Φ Ψ).hom.left ≫ colonπ Φ Ψ = 0 := by diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean index 8c4f17c08fec88..f52a1ca97fb834 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean @@ -272,6 +272,7 @@ lemma projectiveDimension_eq_of_iso {X Y : C} (e : X ≅ Y) : exact ⟨fun h ↦ hasProjectiveDimensionLT_of_iso e _, fun h ↦ hasProjectiveDimensionLT_of_iso e.symm _⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma Retract.projectiveDimension_le {X Y : C} (h : Retract X Y) : projectiveDimension X ≤ projectiveDimension Y := sInf_le_sInf_of_subset_insert_top (fun n hn ↦ by diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean index 61394bc8585750..25dc4129ee8309 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -183,7 +183,6 @@ lemma extMk_zero {n : ℕ} (m : ℕ) (hm : n + 1 = m) : R.extMk (0 : R.complex.X n ⟶ Y) m hm (by simp) = 0 := by simp [extMk] -set_option backward.isDefEq.respectTransparency false in lemma extMk_hom [HasDerivedCategory C] {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) (hf : R.complex.d m n ≫ f = 0) : @@ -222,7 +221,6 @@ lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : rw [← cancel_epi (R.cochainComplexXIso (-m) m rfl).hom] simpa [R.cochainComplex_d _ _ _ _ rfl rfl] using hf -set_option backward.isDefEq.respectTransparency false in lemma extMk_comp_mk₀ {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) (hf : R.complex.d m n ≫ f = 0) {Y' : C} (g : Y ⟶ Y') : (R.extMk f m hm hf).comp (Ext.mk₀ g) (add_zero _) = @@ -243,7 +241,6 @@ lemma extMk_comp_mk₀ {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 ShiftedHom.mk₀_comp_mk₀, ShiftedHom.mk₀_comp_mk₀, ← NatTrans.naturality] dsimp -set_option backward.isDefEq.respectTransparency false in variable {R} in lemma mk₀_comp_extMk {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) (hf : R.complex.d m n ≫ f = 0) diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Resolution.lean b/Mathlib/CategoryTheory/Abelian/Projective/Resolution.lean index 2cfbd81ba9a38a..92d4216d0d58d1 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Resolution.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Resolution.lean @@ -94,6 +94,7 @@ def lift {Y Z : C} (f : Y ⟶ Z) (P : ProjectiveResolution Y) (Q : ProjectiveRes ChainComplex.mkHom _ _ (liftFZero f _ _) (liftFOne f _ _) (liftFOne_zero_comm f P Q) fun n ⟨g, g', w⟩ => ⟨(liftFSucc P Q n g g' w).1, (liftFSucc P Q n g g' w).2⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The resolution maps intertwine the lift of a morphism and that morphism. -/ @[reassoc (attr := simp)] theorem lift_commutes {Y Z : C} (f : Y ⟶ Z) (P : ProjectiveResolution Y) @@ -288,6 +289,7 @@ variable (Z : C) -- The construction of the projective resolution `of` would be very, very slow -- if it were not broken into separate definitions and lemmas +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `ProjectiveResolution.of`. -/ def ofComplex : ChainComplex C ℕ := ChainComplex.mk' (Projective.over Z) (Projective.syzygies (Projective.π Z)) @@ -297,6 +299,7 @@ lemma ofComplex_d_1_0 : (ofComplex Z).d 1 0 = d (Projective.π Z) := by simp [ofComplex] +set_option backward.isDefEq.respectTransparency.types false in lemma ofComplex_exactAt_succ (n : ℕ) : (ofComplex Z).ExactAt (n + 1) := by rw [HomologicalComplex.exactAt_iff' _ (n + 1 + 1) (n + 1) n (by simp) (by simp)] @@ -307,6 +310,7 @@ lemma ofComplex_exactAt_succ (n : ℕ) : | 0 => apply exact_d_f | n + 1 => apply exact_d_f +set_option backward.isDefEq.respectTransparency.types false in instance (n : ℕ) : Projective ((ofComplex Z).X n) := by obtain (_ | _ | _ | n) := n <;> apply Projective.projective_over diff --git a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean index 69fd41dc0feb2c..716f26610dea46 100644 --- a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean +++ b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean @@ -241,7 +241,6 @@ theorem pseudoZero_iff {P : C} (a : Over P) : a = (0 : P) ↔ a.hom = 0 := by end Zero -open Pseudoelement set_option backward.defeqAttrib.useBackward true in /-- Morphisms map the zero pseudoelement to the zero pseudoelement. -/ @@ -268,6 +267,7 @@ theorem zero_morphism_ext' {P Q : C} (f : P ⟶ Q) : (∀ a, f a = 0) → 0 = f theorem eq_zero_iff {P Q : C} (f : P ⟶ Q) : f = 0 ↔ ∀ a, f a = 0 := ⟨fun h a => by simp [h], zero_morphism_ext _⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- A monomorphism is injective on pseudoelements. -/ theorem pseudo_injective_of_mono {P Q : C} (f : P ⟶ Q) [Mono f] : Function.Injective f := by intro abar abar' diff --git a/Mathlib/CategoryTheory/Abelian/RightDerived.lean b/Mathlib/CategoryTheory/Abelian/RightDerived.lean index 90e1176860be05..56e37f1f3afd5e 100644 --- a/Mathlib/CategoryTheory/Abelian/RightDerived.lean +++ b/Mathlib/CategoryTheory/Abelian/RightDerived.lean @@ -120,8 +120,8 @@ noncomputable def InjectiveResolution.isoRightDerivedObj {X : C} (I : InjectiveR (I.isoRightDerivedToHomotopyCategoryObj F) ≪≫ (HomotopyCategory.homologyFunctorFactors D (ComplexShape.up ℕ) n).app _ -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma InjectiveResolution.isoRightDerivedObj_hom_naturality {X Y : C} (f : X ⟶ Y) (I : InjectiveResolution X) (J : InjectiveResolution Y) @@ -137,7 +137,6 @@ lemma InjectiveResolution.isoRightDerivedObj_hom_naturality erw [(HomotopyCategory.homologyFunctorFactors D (ComplexShape.up ℕ) n).hom.naturality] rfl -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma InjectiveResolution.isoRightDerivedObj_inv_naturality {X Y : C} (f : X ⟶ Y) (I : InjectiveResolution X) (J : InjectiveResolution Y) @@ -269,6 +268,7 @@ noncomputable def toRightDerivedZero' {X : C} rw [← F.map_comp, HomologicalComplex.Hom.comm, HomologicalComplex.single_obj_d, zero_comp, F.map_zero]) +set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma toRightDerivedZero'_comp_iCycles {C} [Category* C] [Abelian C] {X : C} (P : InjectiveResolution X) (F : C ⥤ D) [F.Additive] : @@ -343,6 +343,7 @@ lemma InjectiveResolution.toRightDerivedZero_eq erw [← NatTrans.naturality] rfl +set_option backward.isDefEq.respectTransparency.types false in instance (F : C ⥤ D) [F.Additive] (X : C) [Injective X] : IsIso (F.toRightDerivedZero.app X) := by rw [(InjectiveResolution.self X).toRightDerivedZero_eq F] @@ -352,6 +353,7 @@ section variable (F : C ⥤ D) [F.Additive] [PreservesFiniteLimits F] +set_option backward.isDefEq.respectTransparency.types false in instance {X : C} (P : InjectiveResolution X) : IsIso (P.toRightDerivedZero' F) := by dsimp [InjectiveResolution.toRightDerivedZero'] diff --git a/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean b/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean index a2f3aa0b411a9e..3ed59362bd5912 100644 --- a/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean +++ b/Mathlib/CategoryTheory/Abelian/SerreClass/Localization.lean @@ -417,7 +417,7 @@ Note that we assume that `D` has already been equipped with a preadditive struct and that `L` is additive. Otherwise, see the results in the file `Mathlib/CategoryTheory/Localization/CalculusOfFractions/Preadditive.lean` which applies because `P.isoModSerre` has a calculus of left and right fractions. -/ -@[stacks 02MS, implicit_reducible] +@[stacks 02MS, instance_reducible] def abelian : Abelian D := by have := hasFiniteProducts L P have := hasKernels L P diff --git a/Mathlib/CategoryTheory/Abelian/ShortExact.lean b/Mathlib/CategoryTheory/Abelian/ShortExact.lean index 1ef8125dca2717..97508cddff397c 100644 --- a/Mathlib/CategoryTheory/Abelian/ShortExact.lean +++ b/Mathlib/CategoryTheory/Abelian/ShortExact.lean @@ -20,7 +20,7 @@ namespace CategoryTheory.ShortExact universe v₁ v₂ u₁ u₂ -open CategoryTheory Limits Preadditive Functor +open CategoryTheory Limits Preadditive CategoryTheory.Functor variable {C : Type u₁} [Category.{v₁} C] [Abelian C] variable {D : Type u₂} [Category.{v₂} D] [Abelian D] diff --git a/Mathlib/CategoryTheory/Abelian/Subobject.lean b/Mathlib/CategoryTheory/Abelian/Subobject.lean index b76a0ae170dbff..08831cebcccffe 100644 --- a/Mathlib/CategoryTheory/Abelian/Subobject.lean +++ b/Mathlib/CategoryTheory/Abelian/Subobject.lean @@ -26,6 +26,7 @@ namespace CategoryTheory.Abelian variable {C : Type u} [Category.{v} C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- In an abelian category, the subobjects and quotient objects of an object `X` are order-isomorphic via taking kernels and cokernels. diff --git a/Mathlib/CategoryTheory/Abelian/Transfer.lean b/Mathlib/CategoryTheory/Abelian/Transfer.lean index 5bba283bc30c19..a9d01611a809f6 100644 --- a/Mathlib/CategoryTheory/Abelian/Transfer.lean +++ b/Mathlib/CategoryTheory/Abelian/Transfer.lean @@ -84,7 +84,7 @@ we have `F : C ⥤ D` `G : D ⥤ C` (with `G` preserving zero morphisms), `G` is left exact (that is, preserves finite limits), and further we have `adj : G ⊣ F` and `i : F ⋙ G ≅ 𝟭 C`, then `C` is also abelian. -/ -@[stacks 03A3, implicit_reducible] +@[stacks 03A3, instance_reducible] def abelianOfAdjunction {C : Type u₁} [Category.{v₁} C] [Preadditive C] [HasFiniteProducts C] {D : Type u₂} [Category.{v₂} D] [Abelian D] (F : C ⥤ D) (G : D ⥤ C) [Functor.PreservesZeroMorphisms G] [PreservesFiniteLimits G] (i : F ⋙ G ≅ 𝟭 C) @@ -108,7 +108,7 @@ def abelianOfAdjunction {C : Type u₁} [Category.{v₁} C] [Preadditive C] [Has via a functor that preserves zero morphisms, then `C` is also abelian. -/ -@[implicit_reducible] +@[instance_reducible] def abelianOfEquivalence {C : Type u₁} [Category.{v₁} C] [Preadditive C] [HasFiniteProducts C] {D : Type u₂} [Category.{v₂} D] [Abelian D] (F : C ⥤ D) [F.IsEquivalence] : Abelian C := diff --git a/Mathlib/CategoryTheory/Action.lean b/Mathlib/CategoryTheory/Action.lean index 940eafb9f2f4b9..fbee9da997609e 100644 --- a/Mathlib/CategoryTheory/Action.lean +++ b/Mathlib/CategoryTheory/Action.lean @@ -100,6 +100,7 @@ instance [Nonempty X] : Nonempty (ActionCategory M X) := variable {X} (x : X) +set_option backward.isDefEq.respectTransparency.types false in /-- The stabilizer of a point is isomorphic to the endomorphism monoid at the corresponding point. In fact they are definitionally equivalent. -/ def stabilizerIsoEnd : stabilizerSubmonoid M x ≃* @End (ActionCategory M X) _ x := @@ -110,6 +111,7 @@ theorem stabilizerIsoEnd_apply (f : stabilizerSubmonoid M x) : (stabilizerIsoEnd M x) f = f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp 1100] theorem stabilizerIsoEnd_symm_apply (f : End _) : (stabilizerIsoEnd M x).symm f = f := rfl @@ -137,6 +139,7 @@ variable {G : Type*} [Group G] [MulAction G X] instance : Groupoid (ActionCategory G X) := CategoryTheory.groupoidOfElements _ +set_option backward.isDefEq.respectTransparency.types false in /-- Any subgroup of `G` is a vertex group in its action groupoid. -/ def endMulEquivSubgroup (H : Subgroup G) : End (objEquiv G (G ⧸ H) ↑(1 : G)) ≃* H := MulEquiv.trans (stabilizerIsoEnd G ((1 : G) : G ⧸ H)).symm @@ -184,6 +187,7 @@ def curry (F : ActionCategory G X ⥤ SingleObj H) : G →* (X → H) ⋊[mulAut · exact F_map_eq.symm.trans (F.map_comp (homOfPair (g⁻¹ • b) h) (homOfPair b g)) rfl } +set_option backward.isDefEq.respectTransparency.types false in /-- Given `G` acting on `X`, a group homomorphism `φ : G →* (X → H) ⋊ G` can be uncurried to a functor from the action groupoid to `H`, provided that `φ g = (_, g)` for all `g`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Action/Basic.lean b/Mathlib/CategoryTheory/Action/Basic.lean index c9790e8778fab0..50d5d7853f9447 100644 --- a/Mathlib/CategoryTheory/Action/Basic.lean +++ b/Mathlib/CategoryTheory/Action/Basic.lean @@ -51,6 +51,7 @@ namespace Action variable {V} +set_option backward.isDefEq.respectTransparency.types false in theorem ρ_one {G : Type*} [Monoid G] (A : Action V G) : A.ρ 1 = 𝟙 A.V := by simp /-- When a group acts, we can lift the action to the group of automorphisms. -/ @@ -96,6 +97,7 @@ namespace Hom attribute [reassoc] comm attribute [local simp] comm comm_assoc +set_option backward.isDefEq.respectTransparency.types false in /-- The identity morphism on an `Action V G`. -/ @[simps] def id (M : Action V G) : Action.Hom M M where hom := 𝟙 M.V @@ -103,11 +105,15 @@ def id (M : Action V G) : Action.Hom M M where hom := 𝟙 M.V instance (M : Action V G) : Inhabited (Action.Hom M M) := ⟨id M⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of two `Action V G` homomorphisms is the composition of the underlying maps. -/ @[simps] def comp {M N K : Action V G} (p : Action.Hom M N) (q : Action.Hom N K) : Action.Hom M K where hom := p.hom ≫ q.hom + comm := by + intro g + simp_all only [comm_assoc, comm, Category.assoc] end Hom @@ -123,10 +129,12 @@ lemma hom_injective {M N : Action V G} : Function.Injective (Hom.hom : (M ⟶ N) lemma hom_ext {M N : Action V G} (φ₁ φ₂ : M ⟶ N) (h : φ₁.hom = φ₂.hom) : φ₁ = φ₂ := Hom.ext h +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem id_hom (M : Action V G) : (𝟙 M : Hom M M).hom = 𝟙 M.V := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] theorem comp_hom {M N K : Action V G} (f : M ⟶ N) (g : N ⟶ K) : (f ≫ g : Hom M K).hom = f.hom ≫ g.hom := @@ -142,6 +150,7 @@ theorem inv_hom_hom {M N : Action V G} (f : M ≅ N) : f.inv.hom ≫ f.hom.hom = 𝟙 N.V := by rw [← comp_hom, Iso.inv_hom_id, id_hom] +set_option backward.isDefEq.respectTransparency.types false in /-- Construct an isomorphism of `G` actions/representations from an isomorphism of the underlying objects, where the forward direction commutes with the group action. -/ @@ -155,9 +164,11 @@ def mkIso {M N : Action V G} (f : M.V ≅ N.V) { hom := f.inv comm := fun g => by have w := comm g =≫ f.inv; simp at w; simp [w] } +set_option backward.isDefEq.respectTransparency.types false in instance (priority := 100) isIso_of_hom_isIso {M N : Action V G} (f : M ⟶ N) [IsIso f.hom] : IsIso f := (mkIso (asIso f.hom) f.comm).isIso_hom +set_option backward.isDefEq.respectTransparency.types false in instance isIso_hom_mk {M N : Action V G} (f : M.V ⟶ N.V) [IsIso f] (w) : @IsIso _ _ M N (Hom.mk f w) := (mkIso (asIso f) w).isIso_hom @@ -170,6 +181,7 @@ instance {M N : Action V G} (f : M ≅ N) : IsIso f.inv.hom where namespace FunctorCategoryEquivalence +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `functorCategoryEquivalence`. -/ @[simps] def functor : Action V G ⥤ SingleObj G ⥤ V where @@ -182,6 +194,7 @@ def functor : Action V G ⥤ SingleObj G ⥤ V where { app := fun _ => f.hom naturality := fun _ _ g => f.comm g } +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `functorCategoryEquivalence`. -/ @[simps] def inverse : (SingleObj G ⥤ V) ⥤ Action V G where @@ -195,6 +208,7 @@ def inverse : (SingleObj G ⥤ V) ⥤ Action V G where { hom := f.app PUnit.unit comm := fun g => f.naturality g } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `functorCategoryEquivalence`. -/ @[simps!] @@ -215,6 +229,7 @@ open FunctorCategoryEquivalence variable (V G) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of actions of `G` in the category `V` is equivalent to the functor category `SingleObj G ⥤ V`. @@ -226,9 +241,11 @@ def functorCategoryEquivalence : Action V G ≌ SingleObj G ⥤ V where unitIso := unitIso counitIso := counitIso +set_option backward.isDefEq.respectTransparency.types false in instance : (FunctorCategoryEquivalence.functor (V := V) (G := G)).IsEquivalence := (functorCategoryEquivalence V G).isEquivalence_functor +set_option backward.isDefEq.respectTransparency.types false in instance : (FunctorCategoryEquivalence.inverse (V := V) (G := G)).IsEquivalence := (functorCategoryEquivalence V G).isEquivalence_inverse @@ -238,6 +255,7 @@ section Forget variable (V G) +set_option backward.isDefEq.respectTransparency.types false in /-- (implementation) The forgetful functor from bundled actions to the underlying objects. Use the `CategoryTheory.forget` API provided by the `ConcreteCategory` instance below, @@ -262,6 +280,7 @@ instance {FV : V → V → Type*} {CV : V → Type*} [∀ X Y, FunLike (FV X Y) coe f := f.1 coe_injective _ _ h := Subtype.ext (DFunLike.coe_injective h) +set_option backward.isDefEq.respectTransparency.types false in instance {FV : V → V → Type*} {CV : V → Type*} [∀ X Y, FunLike (FV X Y) (CV X) (CV Y)] [ConcreteCategory V FV] : ConcreteCategory (Action V G) (HomSubtype V G) where hom f := ⟨ConcreteCategory.hom (C := V) f.1, fun g => by @@ -274,19 +293,23 @@ instance {FV : V → V → Type*} {CV : V → Type*} [∀ X Y, FunLike (FV X Y) id_apply := ConcreteCategory.id_apply (C := V) comp_apply _ _ := ConcreteCategory.comp_apply (C := V) _ _ +set_option backward.isDefEq.respectTransparency.types false in instance hasForgetToV {FV : V → V → Type*} {CV : V → Type*} [∀ X Y, FunLike (FV X Y) (CV X) (CV Y)] [ConcreteCategory V FV] : HasForget₂ (Action V G) V where forget₂ := forget V G +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor is intertwined by `functorCategoryEquivalence` with evaluation at `PUnit.star`. -/ def functorCategoryEquivalenceCompEvaluation : (functorCategoryEquivalence V G).functor ⋙ (evaluation _ _).obj PUnit.unit ≅ forget V G := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance preservesLimits_forget [HasLimits V] : PreservesLimits (forget V G) := Limits.preservesLimits_of_natIso (Action.functorCategoryEquivalenceCompEvaluation V G) +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance preservesColimits_forget [HasColimits V] : PreservesColimits (forget V G) := preservesColimits_of_natIso (Action.functorCategoryEquivalenceCompEvaluation V G) @@ -318,6 +341,7 @@ def actionPUnitEquivalence : Action V PUnit ≌ V where variable (V) +set_option backward.isDefEq.respectTransparency.types false in /-- The "restriction" functor along a monoid homomorphism `f : G →* H`, taking actions of `H` to actions of `G`. @@ -332,6 +356,7 @@ def res {G H : Type*} [Monoid G] [Monoid H] (f : G →* H) : Action V H ⥤ Acti { hom := p.hom comm := fun g => p.comm (f g) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism from restriction along the identity homomorphism to the identity functor on `Action V G`. @@ -340,6 +365,7 @@ the identity functor on `Action V G`. def resId {G : Type*} [Monoid G] : res V (MonoidHom.id G) ≅ 𝟭 (Action V G) := NatIso.ofComponents fun M => mkIso (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism from the composition of restrictions along homomorphisms to the restriction along the composition of homomorphism. @@ -349,12 +375,14 @@ def resComp {G H K : Type*} [Monoid G] [Monoid H] [Monoid K] (f : G →* H) (g : H →* K) : res V g ⋙ res V f ≅ res V (g.comp f) := NatIso.ofComponents fun M => mkIso (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in /-- Restricting scalars along equal maps is naturally isomorphic. -/ @[simps! hom inv] def resCongr {G H : Type*} [Monoid G] [Monoid H] {f f' : G →* H} (h : f = f') : Action.res V f ≅ Action.res V f' := NatIso.ofComponents (fun _ ↦ Action.mkIso (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restricting scalars along a monoid isomorphism induces an equivalence of categories. -/ @[simps! functor inverse] @@ -398,6 +426,7 @@ namespace CategoryTheory.Functor variable {V} {W : Type*} [Category* W] +set_option backward.isDefEq.respectTransparency.types false in /-- A functor between categories induces a functor between the categories of `G`-actions within those categories. -/ @[simps] @@ -416,12 +445,14 @@ def mapAction (F : V ⥤ W) (G : Type*) [Monoid G] : Action V G ⥤ Action W G w map_id M := by ext; simp only [Action.id_hom, F.map_id] map_comp f g := by ext; simp only [Action.comp_hom, F.map_comp] +set_option backward.isDefEq.respectTransparency.types false in instance (F : V ⥤ W) (G : Type*) [Monoid G] [F.Faithful] : (F.mapAction G).Faithful where map_injective eq := by ext apply_fun (fun f ↦ f.hom) at eq exact F.map_injective eq +set_option backward.isDefEq.respectTransparency.types false in /-- A fully faithful functor between categories induces a fully faithful functor between the categories of `G`-actions within those categories. -/ @@ -437,6 +468,7 @@ instance (F : V ⥤ W) (G : Type*) [Monoid G] [F.Faithful] [F.Full] : (F.mapActi variable (G : Type*) [Monoid G] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Functor.mapAction` is functorial in the functor. -/ @[simps! hom inv] @@ -454,6 +486,7 @@ def mapActionCongr {F F' : V ⥤ W} (e : F ≅ F') : end Functor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories induces an equivalence of the categories of `G`-actions within those categories. -/ diff --git a/Mathlib/CategoryTheory/Action/Concrete.lean b/Mathlib/CategoryTheory/Action/Concrete.lean index 7ae60de334657c..d4dc11016ad5eb 100644 --- a/Mathlib/CategoryTheory/Action/Concrete.lean +++ b/Mathlib/CategoryTheory/Action/Concrete.lean @@ -70,6 +70,7 @@ theorem ofMulAction_apply {G : Type*} {H : Type*} [Monoid G] [MulAction G H] (g (ofMulAction G H).ρ g x = (g • x : H) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Given a family `F` of types with `G`-actions, this is the limit cone demonstrating that the product of `F` as types is a product in the category of `G`-sets. -/ def ofMulActionLimitCone {ι : Type v} (G : Type max v u) [Monoid G] (F : ι → Type max v u) @@ -132,6 +133,7 @@ notation:10 G:10 " ⧸ₐ " H:10 => Action.FintypeCat.ofMulAction G (FintypeCat. variable {G : Type*} [Group G] (H N : Subgroup G) [Fintype (G ⧸ N)] +set_option backward.isDefEq.respectTransparency.types false in /-- If `N` is a normal subgroup of `G`, then this is the group homomorphism sending an element `g` of `G` to the `G`-endomorphism of `G ⧸ₐ N` given by multiplication with `g⁻¹` on the right. -/ @@ -161,9 +163,11 @@ def toEndHom [N.Normal] : G →* End (G ⧸ₐ N) where change ⟦x * (σ * τ)⁻¹⟧ = ⟦x * τ⁻¹ * σ⁻¹⟧ rw [mul_inv_rev, mul_assoc] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toEndHom_apply [N.Normal] (g h : G) : (toEndHom N g).hom ⟦h⟧ = ⟦h * g⁻¹⟧ := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {N} in lemma toEndHom_trivial_of_mem [N.Normal] {n : G} (hn : n ∈ N) : toEndHom N n = 𝟙 (G ⧸ₐ N) := by apply Action.hom_ext @@ -177,6 +181,7 @@ def quotientToEndHom [N.Normal] : H ⧸ Subgroup.subgroupOf N H →* End (G ⧸ QuotientGroup.lift (Subgroup.subgroupOf N H) ((toEndHom N).comp H.subtype) <| fun _ uinU' ↦ toEndHom_trivial_of_mem uinU' +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma quotientToEndHom_mk [N.Normal] (x : H) (g : G) : (quotientToEndHom H N ⟦x⟧).hom ⟦g⟧ = ⟦g * x⁻¹⟧ := diff --git a/Mathlib/CategoryTheory/Action/Continuous.lean b/Mathlib/CategoryTheory/Action/Continuous.lean index b5da64b91f2320..cf638edfcdc5a3 100644 --- a/Mathlib/CategoryTheory/Action/Continuous.lean +++ b/Mathlib/CategoryTheory/Action/Continuous.lean @@ -40,6 +40,7 @@ namespace Action instance : HasForget₂ (Action V G) TopCat := HasForget₂.trans (Action V G) V TopCat +set_option backward.isDefEq.respectTransparency.types false in instance (X : Action V G) : MulAction G ((CategoryTheory.forget₂ _ TopCat).obj X) where smul g x := ((CategoryTheory.forget₂ _ TopCat).map (X.ρ g)) x one_smul x := by @@ -107,6 +108,7 @@ def res (f : G →ₜ* H) : ContAction V H ⥤ ContAction V G := change Continuous (u ∘ v) fun_prop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restricting scalars along a composition is naturally isomorphic to restricting scalars twice. -/ @[simps! hom inv] @@ -115,6 +117,7 @@ def resComp {K : Type*} [Monoid K] [TopologicalSpace K] ContAction.res V (h.comp f) ≅ ContAction.res V h ⋙ ContAction.res V f := NatIso.ofComponents (fun _ ↦ Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `f = f'`, restriction of scalars along `f` and `f'` is the same. -/ @[simps! hom inv] @@ -122,6 +125,7 @@ def resCongr (f f' : G →ₜ* H) (h : f = f') : ContAction.res V f ≅ ContActi NatIso.ofComponents (fun _ ↦ ObjectProperty.isoMk _ (Action.mkIso (Iso.refl _) (by subst h; simp))) fun f ↦ ObjectProperty.hom_ext _ (Action.Hom.ext (by simp)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restriction of scalars along a topological monoid isomorphism induces an equivalence of categories. -/ @@ -138,6 +142,7 @@ end ContAction open ContAction +set_option backward.isDefEq.respectTransparency.types false in /-- The subcategory of `ContAction V G` where the topology is discrete. -/ def DiscreteContAction : Type _ := ObjectProperty.FullSubcategory (IsDiscrete (V := V) (G := G)) deriving Category, ConcreteCategory @@ -145,14 +150,17 @@ deriving Category, ConcreteCategory namespace DiscreteContAction +set_option backward.isDefEq.respectTransparency.types false in instance : HasForget₂ (DiscreteContAction V G) (ContAction V G) := inferInstanceAs <| HasForget₂ (ObjectProperty.FullSubcategory _) _ +set_option backward.isDefEq.respectTransparency.types false in instance : HasForget₂ (DiscreteContAction V G) TopCat := HasForget₂.trans (DiscreteContAction V G) (ContAction V G) TopCat variable {V G} +set_option backward.isDefEq.respectTransparency.types false in instance (X : DiscreteContAction V G) : DiscreteTopology ((CategoryTheory.forget₂ _ TopCat).obj X) := X.property @@ -176,6 +184,7 @@ def mapContAction (F : V ⥤ W) (H : ∀ X : ContAction V G, ((F.mapAction G).ob ContAction V G ⥤ ContAction W G := ObjectProperty.lift _ (ObjectProperty.ι _ ⋙ F.mapAction G) H +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Continuous version of `Functor.mapActionComp`. -/ @[simps! hom inv] @@ -201,6 +210,7 @@ def mapContActionCongr end Functor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Continuous version of `Equivalence.mapAction`. -/ @[simps functor inverse] diff --git a/Mathlib/CategoryTheory/Action/Monoidal.lean b/Mathlib/CategoryTheory/Action/Monoidal.lean index f40d55a4232f9a..21b1a4ccd94ba0 100644 --- a/Mathlib/CategoryTheory/Action/Monoidal.lean +++ b/Mathlib/CategoryTheory/Action/Monoidal.lean @@ -64,6 +64,7 @@ def tensorUnitIso {X : V} (f : 𝟙_ V ≅ X) : 𝟙_ (Action V G) ≅ Action.mk variable (V G) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : (Action.forget V G).Monoidal := Functor.CoreMonoidal.toMonoidal @@ -72,12 +73,16 @@ instance : (Action.forget V G).Monoidal := open Functor.LaxMonoidal Functor.OplaxMonoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_ε : ε (Action.forget V G) = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_η : η (Action.forget V G) = 𝟙 _ := rfl variable {V G} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_μ (X Y : Action V G) : μ (Action.forget V G) X Y = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_δ (X Y : Action V G) : δ (Action.forget V G) X Y = 𝟙 _ := rfl variable (V G) @@ -86,6 +91,7 @@ section variable [BraidedCategory V] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : BraidedCategory (Action V G) := .ofFaithful (Action.forget V G) fun X Y ↦ mkIso (β_ _ _) fun g ↦ by simp @@ -96,12 +102,14 @@ theorem β_hom_hom {X Y : Action V G} : (β_ X Y).hom.hom = (β_ X.V Y.V).hom := @[simp] theorem β_inv_hom {X Y : Action V G} : (β_ X Y).inv.hom = (β_ X.V Y.V).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When `V` is braided the forgetful functor `Action V G` to `V` is braided. -/ instance : (Action.forget V G).Braided where end +set_option backward.isDefEq.respectTransparency.types false in instance [SymmetricCategory V] : SymmetricCategory (Action V G) := .ofFaithful (Action.forget V G) @@ -111,10 +119,12 @@ variable [Preadditive V] [MonoidalPreadditive V] attribute [local simp] MonoidalPreadditive.whiskerLeft_add MonoidalPreadditive.add_whiskerRight +set_option backward.isDefEq.respectTransparency.types false in instance : MonoidalPreadditive (Action V G) where variable {R : Type*} [Semiring R] [Linear R V] [MonoidalLinear R V] +set_option backward.isDefEq.respectTransparency.types false in instance : MonoidalLinear R (Action V G) where end @@ -218,6 +228,7 @@ noncomputable def diagonalSuccIsoTensorDiagonal [Monoid G] (n : ℕ) : variable [Group G] +set_option backward.isDefEq.respectTransparency.types false in /-- Given `X : Action (Type u) G` for `G` a group, then `G × X` (with `G` acting as left multiplication on the first factor and by `X.ρ` on the second) is isomorphic as a `G`-set to `G × X` (with `G` acting as left multiplication on the first factor and trivially on the second). @@ -253,6 +264,7 @@ noncomputable def diagonalSuccIsoTensorTrivial : variable {G} +set_option backward.isDefEq.respectTransparency false in @[simp] theorem diagonalSuccIsoTensorTrivial_hom_hom_apply {n : ℕ} (f : Fin (n + 1) → G) : dsimp% (diagonalSuccIsoTensorTrivial G n).hom.hom f = @@ -316,9 +328,11 @@ instance [F.LaxMonoidal] : (F.mapAction G).LaxMonoidal where left_unitality _ := by ext; simp right_unitality _ := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapAction_ε_hom [F.LaxMonoidal] : (ε (F.mapAction G)).hom = ε F := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapAction_μ_hom [F.LaxMonoidal] (X Y : Action V G) : (μ (F.mapAction G) X Y).hom = μ F X.V Y.V := rfl @@ -342,13 +356,16 @@ instance [F.OplaxMonoidal] : (F.mapAction G).OplaxMonoidal where oplax_left_unitality _ := by ext; simp oplax_right_unitality _ := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapAction_η_hom [F.OplaxMonoidal] : (η (F.mapAction G)).hom = η F := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapAction_δ_hom [F.OplaxMonoidal] (X Y : Action V G) : (δ (F.mapAction G) X Y).hom = δ F X.V Y.V := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A monoidal functor induces a monoidal functor between the categories of `G`-actions within those categories. -/ diff --git a/Mathlib/CategoryTheory/Adjunction/Additive.lean b/Mathlib/CategoryTheory/Adjunction/Additive.lean index 0e1315e3d70d54..1352d0890f413a 100644 --- a/Mathlib/CategoryTheory/Adjunction/Additive.lean +++ b/Mathlib/CategoryTheory/Adjunction/Additive.lean @@ -28,7 +28,7 @@ namespace CategoryTheory namespace Adjunction -open CategoryTheory Category Functor +open CategoryTheory Category CategoryTheory.Functor variable {C : Type u₁} {D : Type u₂} [Category.{v₁} C] [Category.{v₂} D] [Preadditive C] [Preadditive D] {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) diff --git a/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean b/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean index 72811180047770..3a66f3169349e0 100644 --- a/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean +++ b/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean @@ -67,7 +67,6 @@ section GeneralAdjointFunctorTheorem variable {D : Type u₁} [Category.{v₁} D] variable (G : D ⥤ C) -set_option backward.isDefEq.respectTransparency false in /-- If `G : D ⥤ C` is a right adjoint it satisfies the solution set condition. -/ theorem solutionSetCondition_of_isRightAdjoint [G.IsRightAdjoint] : SolutionSetCondition.{w} G := by intro A diff --git a/Mathlib/CategoryTheory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Adjunction/Basic.lean index f48f325c75ef09..f0e132087a6b1f 100644 --- a/Mathlib/CategoryTheory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Adjunction/Basic.lean @@ -85,7 +85,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor -- declare the `v`'s first; see `CategoryTheory.Category` for an explanation universe w v₁ v₂ v₃ u₁ u₂ u₃ @@ -158,7 +158,6 @@ namespace Adjunction attribute [reassoc (attr := simp)] left_triangle_components right_triangle_components -set_option backward.isDefEq.respectTransparency false in /-- The hom set equivalence associated to an adjunction. -/ @[to_dual none, simps (attr := to_dual none) -isSimp] def homEquiv {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) (X : C) (Y : D) : @@ -184,7 +183,6 @@ def homEquiv {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) (X : C) (Y : D) : -- it may be advisable to add a local simp attribute to these lemmas. attribute [local simp] Adjunction.homEquiv_unit Adjunction.homEquiv_counit -set_option backward.isDefEq.respectTransparency false in set_option linter.existingAttributeWarning false in @[ext, to_dual ext_counit] lemma ext {F : C ⥤ D} {G : D ⥤ C} {adj adj' : F ⊣ G} @@ -215,7 +213,6 @@ theorem homEquiv_id (X : C) : adj.homEquiv X _ (𝟙 _) = adj.unit.app X := by s @[to_dual none] theorem homEquiv_symm_id (X : D) : (adj.homEquiv _ X).symm (𝟙 _) = adj.counit.app X := by simp -set_option backward.isDefEq.respectTransparency false in @[simp, to_dual none] lemma homEquiv_symm_unit (X : C) : dsimp% (adj.homEquiv _ _).symm (adj.unit.app X) = 𝟙 _ := by simp @@ -310,7 +307,6 @@ theorem eq_homEquiv_apply {A : C} {B : D} (f : F.obj A ⟶ B) (g : A ⟶ G.obj B g = adj.homEquiv A B f ↔ (adj.homEquiv A B).symm g = f := eq_unit_comp_map_iff adj f g -set_option backward.isDefEq.respectTransparency false in /-- If `adj : F ⊣ G`, and `X : C`, then `F.obj X` corepresents `Y ↦ (X ⟶ G.obj Y)`. -/ @[simps] def corepresentableBy (X : C) : @@ -410,7 +406,6 @@ variable {F : C ⥤ D} {G : D ⥤ C} attribute [local simp] CoreHomEquivUnitCounit.homEquiv_unit CoreHomEquivUnitCounit.homEquiv_counit -set_option backward.isDefEq.respectTransparency false in /-- Construct an adjunction from the data of a `CoreHomEquivUnitCounit`, i.e. a hom set equivalence, unit and counit natural transformations together with proofs of the equalities @@ -427,7 +422,6 @@ def mk' (adj : CoreHomEquivUnitCounit F G) : F ⊣ G where rw [← adj.homEquiv_unit, ← (adj.homEquiv _ _).eq_symm_apply, adj.homEquiv_counit] simp -set_option backward.isDefEq.respectTransparency false in lemma mk'_homEquiv (adj : CoreHomEquivUnitCounit F G) : (mk' adj).homEquiv = adj.homEquiv := by ext rw [homEquiv_unit, adj.homEquiv_unit, mk'_unit] @@ -500,7 +494,6 @@ def equivHomsetRightOfNatIso {G G' : D ⥤ C} (iso : G ≅ G') {X : C} {Y : D} : left_inv f := by simp right_inv g := by simp -set_option backward.isDefEq.respectTransparency false in /-- Transport an adjunction along a natural isomorphism on the left. -/ @[simps] def ofNatIsoLeft {F G : C ⥤ D} {H : D ⥤ C} (adj : F ⊣ H) (iso : F ≅ G) : G ⊣ H where @@ -545,6 +538,7 @@ lemma homEquiv_ofNatIsoRight_symm_apply {F : C ⥤ D} {G H : D ⥤ C} (adj : F (adj.homEquiv _ _).symm (f ≫ iso.inv.app _) := by simp +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism which an adjunction `F ⊣ G` induces on `G ⋙ yoneda`. This states that `Adjunction.homEquiv` is natural in both arguments. -/ @[simps!] @@ -553,6 +547,7 @@ def compYonedaIso {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category. G ⋙ yoneda ≅ yoneda ⋙ (whiskeringLeft _ _ _).obj F.op := NatIso.ofComponents fun X => NatIso.ofComponents fun Y => (adj.homEquiv Y.unop X).toIso.symm +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism which an adjunction `F ⊣ G` induces on `F.op ⋙ coyoneda`. This states that `Adjunction.homEquiv` is natural in both arguments. -/ @[simps!] @@ -561,6 +556,7 @@ def compCoyonedaIso {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Categor F.op ⋙ coyoneda ≅ coyoneda ⋙ (whiskeringLeft _ _ _).obj G := NatIso.ofComponents fun X => NatIso.ofComponents fun Y => (adj.homEquiv X.unop Y).toIso +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism which an adjunction `F ⊣ G` induces on `F.op ⋙ uliftCoyoneda`. This states that `Adjunction.homEquiv` is natural in both arguments. -/ @[simps!] @@ -576,7 +572,6 @@ section variable {E : Type u₃} [Category.{v₃} E] {F : C ⥤ D} {G : D ⥤ C} {H : D ⥤ E} {I : E ⥤ D} (adj₁ : F ⊣ G) (adj₂ : H ⊣ I) -set_option backward.isDefEq.respectTransparency false in /-- Composition of adjunctions. -/ @[to_dual self (reorder := C E, 2 6, F I, G H, adj₁ adj₂), simps! -isSimp unit counit, stacks 0DV0] def comp : F ⋙ H ⊣ I ⋙ G := diff --git a/Mathlib/CategoryTheory/Adjunction/CompositionIso.lean b/Mathlib/CategoryTheory/Adjunction/CompositionIso.lean index c7cba9675bfa63..20396d5bb9efe6 100644 --- a/Mathlib/CategoryTheory/Adjunction/CompositionIso.lean +++ b/Mathlib/CategoryTheory/Adjunction/CompositionIso.lean @@ -30,7 +30,7 @@ namespace CategoryTheory variable {C₀ C₁ C₂ C₃ : Type*} [Category* C₀] [Category* C₁] [Category* C₂] [Category* C₃] -open Functor +open CategoryTheory.Functor namespace Adjunction diff --git a/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean b/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean index 8eacd340ada3c5..6daef9890ee004 100644 --- a/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean +++ b/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean @@ -40,7 +40,7 @@ namespace CategoryTheory.Adjunction universe v₁ v₂ u₁ u₂ -open Category Functor +open Category CategoryTheory.Functor open Opposite @@ -130,7 +130,6 @@ lemma faithful_L_of_mono_unit_app [∀ X, Mono (h.unit.app X)] : L.Faithful wher apply (h.homEquiv X (L.obj Y)).symm.injective simpa using hfg -set_option backward.isDefEq.respectTransparency false in /-- If each component of the unit is a split epimorphism, then the left adjoint is full. -/ lemma full_L_of_isSplitEpi_unit_app [∀ X, IsSplitEpi (h.unit.app X)] : L.Full where map_surjective {X Y} f := by @@ -140,7 +139,6 @@ lemma full_L_of_isSplitEpi_unit_app [∀ X, IsSplitEpi (h.unit.app X)] : L.Full simp only [Functor.id_obj, ← h.left_triangle_components Y, ← assoc, ← Functor.map_comp, IsSplitEpi.id, Functor.map_id, id_comp] -set_option backward.isDefEq.respectTransparency false in /-- If the unit is an isomorphism, then the left adjoint is fully faithful. -/ noncomputable def fullyFaithfulLOfIsIsoUnit [IsIso h.unit] : L.FullyFaithful where preimage {_ Y} f := h.homEquiv _ (L.obj Y) f ≫ inv (h.unit.app Y) @@ -153,7 +151,6 @@ lemma faithful_R_of_epi_counit_app [∀ X, Epi (h.counit.app X)] : R.Faithful wh apply (h.homEquiv (R.obj X) Y).injective simpa using hfg -set_option backward.isDefEq.respectTransparency false in /-- If each component of the counit is a split monomorphism, then the right adjoint is full. -/ lemma full_R_of_isSplitMono_counit_app [∀ X, IsSplitMono (h.counit.app X)] : R.Full where map_surjective {X Y} f := by @@ -163,7 +160,6 @@ lemma full_R_of_isSplitMono_counit_app [∀ X, IsSplitMono (h.counit.app X)] : R simp only [Functor.id_obj, ← h.right_triangle_components X, assoc, ← Functor.map_comp, IsSplitMono.id, Functor.map_id, comp_id] -set_option backward.isDefEq.respectTransparency false in /-- If the counit is an isomorphism, then the right adjoint is fully faithful. -/ noncomputable def fullyFaithfulROfIsIsoCounit [IsIso h.counit] : R.FullyFaithful where preimage {X Y} f := inv (h.counit.app X) ≫ (h.homEquiv (R.obj X) Y).symm f @@ -197,15 +193,12 @@ instance whiskerRight_unit_iso_of_R_fully_faithful [R.Full] [R.Faithful] : rw [this] infer_instance -set_option backward.isDefEq.respectTransparency false in instance [L.Faithful] [L.Full] {Y : C} : IsIso (h.counit.app (L.obj Y)) := isIso_of_hom_comp_eq_id _ (h.left_triangle_components Y) -set_option backward.isDefEq.respectTransparency false in instance [L.Faithful] [L.Full] {Y : D} : IsIso (R.map (h.counit.app Y)) := isIso_of_hom_comp_eq_id _ (h.right_triangle_components Y) -set_option backward.isDefEq.respectTransparency false in lemma isIso_counit_app_iff_mem_essImage [L.Faithful] [L.Full] {X : D} : IsIso (h.counit.app X) ↔ L.essImage X := by constructor @@ -215,7 +208,6 @@ lemma isIso_counit_app_iff_mem_essImage [L.Faithful] [L.Full] {X : D} : rw [NatTrans.isIso_app_iff_of_iso _ i.symm] infer_instance -set_option backward.isDefEq.respectTransparency false in lemma mem_essImage_of_counit_isIso (A : D) [IsIso (h.counit.app A)] : L.essImage A := ⟨R.obj A, ⟨asIso (h.counit.app A)⟩⟩ @@ -224,11 +216,9 @@ lemma isIso_counit_app_of_iso [L.Faithful] [L.Full] {X : D} {Y : C} (e : X ≅ L IsIso (h.counit.app X) := (isIso_counit_app_iff_mem_essImage h).mpr ⟨Y, ⟨e.symm⟩⟩ -set_option backward.isDefEq.respectTransparency false in instance [R.Faithful] [R.Full] {Y : D} : IsIso (h.unit.app (R.obj Y)) := isIso_of_comp_hom_eq_id _ (h.right_triangle_components Y) -set_option backward.isDefEq.respectTransparency false in instance [R.Faithful] [R.Full] {X : C} : IsIso (L.map (h.unit.app X)) := isIso_of_comp_hom_eq_id _ (h.left_triangle_components X) @@ -273,7 +263,6 @@ instance [R.IsEquivalence] : IsIso h.counit := by infer_instance set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem isIso_map_unit_of_isLeftAdjoint_comp {E : Type*} [Category* E] {T : C ⥤ E} {S : E ⥤ D} {X : C} (adj2 : T ⊣ S ⋙ R) [R.Faithful] [R.Full] : IsIso (T.map (h.unit.app X)) := by diff --git a/Mathlib/CategoryTheory/Adjunction/FullyFaithfulLimits.lean b/Mathlib/CategoryTheory/Adjunction/FullyFaithfulLimits.lean index aa1dbd06e3e89a..640c25af746d45 100644 --- a/Mathlib/CategoryTheory/Adjunction/FullyFaithfulLimits.lean +++ b/Mathlib/CategoryTheory/Adjunction/FullyFaithfulLimits.lean @@ -35,6 +35,7 @@ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] include adj +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma preservesColimitsOfShape_iff (J : Type u) [Category.{v} J] [HasColimitsOfShape J C] [G.Full] [G.Faithful] : diff --git a/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean b/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean index 10369154600ecf..af99f6c40e178d 100644 --- a/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean +++ b/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean @@ -107,7 +107,6 @@ def otherMap (X) : F'.obj (U.obj (F.obj (U.obj X))) ⟶ F'.obj (U.obj X) := F'.map (U.map (F.map (adj₂.unit.app _) ≫ adj₁.counit.app _)) ≫ adj₂.counit.app _ set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- `(F'Uε_X, otherMap X)` is a reflexive pair: in particular if `A` has reflexive coequalizers then this pair has a coequalizer. -/ @@ -130,7 +129,9 @@ variable [HasReflexiveCoequalizers A] noncomputable def constructLeftAdjointObj (Y : B) : A := coequalizer (F'.map (U.map (adj₁.counit.app Y))) (otherMap _ _ adj₁ adj₂ Y) -set_option backward.isDefEq.respectTransparency false in +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The homset equivalence which helps show that `R` is a right adjoint. -/ @[simps!] noncomputable def constructLeftAdjointEquiv (h : ∀ X : B, RegularEpi (adj₁.counit.app X)) (Y : A) diff --git a/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean b/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean index 162175cb9d23c4..f9a271ef766af5 100644 --- a/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean +++ b/Mathlib/CategoryTheory/Adjunction/Lifting/Right.lean @@ -108,7 +108,6 @@ We will show that this equalizer exists and that it forms the object map for a r def otherMap (X : B) : U'.obj (F.obj X) ⟶ U'.obj (F.obj (U.obj (F.obj X))) := adj₂.unit.app _ ≫ U'.map (F.map (adj₁.unit.app _ ≫ (U.map (adj₂.counit.app _)))) -set_option backward.isDefEq.respectTransparency false in /-- `(U'Fη_X, otherMap X)` is a coreflexive pair: in particular if `C` has coreflexive equalizers then this pair has an equalizer. -/ diff --git a/Mathlib/CategoryTheory/Adjunction/Limits.lean b/Mathlib/CategoryTheory/Adjunction/Limits.lean index 234647223f903f..1ae2d977ec2dc7 100644 --- a/Mathlib/CategoryTheory/Adjunction/Limits.lean +++ b/Mathlib/CategoryTheory/Adjunction/Limits.lean @@ -33,7 +33,7 @@ open Opposite namespace CategoryTheory -open Functor Limits +open CategoryTheory.Functor Limits universe v u v₁ v₂ v₀ u₁ u₂ @@ -58,6 +58,7 @@ def functorialityRightAdjoint : Cocone (K ⋙ F) ⥤ Cocone K := attribute [local simp] functorialityRightAdjoint +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit for the adjunction for `Cocone.functoriality K F : Cocone K ⥤ Cocone (K ⋙ F)`. @@ -68,6 +69,7 @@ def functorialityUnit : 𝟭 (Cocone K) ⟶ Cocone.functoriality _ F ⋙ functorialityRightAdjoint adj K where app c := { hom := adj.unit.app c.pt } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit for the adjunction for `Cocone.functoriality K F : Cocone K ⥤ Cocone (K ⋙ F)`. @@ -171,6 +173,7 @@ def functorialityLeftAdjoint : Cone (K ⋙ G) ⥤ Cone K := attribute [local simp] functorialityLeftAdjoint +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit for the adjunction for `Cone.functoriality K G : Cone K ⥤ Cone (K ⋙ G)`. @@ -181,6 +184,7 @@ def functorialityUnit' : 𝟭 (Cone (K ⋙ G)) ⟶ functorialityLeftAdjoint adj K ⋙ Cone.functoriality _ G where app c := { hom := adj.unit.app c.pt } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit for the adjunction for `Cone.functoriality K G : Cone K ⥤ Cone (K ⋙ G)`. @@ -312,6 +316,7 @@ variable {C : Type u₁} [Category.{v₀} C] {D : Type u₂} [Category.{v₀} D] attribute [local simp] homEquiv_unit homEquiv_counit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- Note: this is natural in K, but we do not yet have the tools to formulate that. /-- When `F ⊣ G`, @@ -325,6 +330,7 @@ def coconesIso {J : Type u} [Category.{v} J] {K : J ⥤ C} : { hom := ↾(coconesIsoComponentHom adj Y) inv := ↾(coconesIsoComponentInv adj Y) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- Note: this is natural in K, but we do not yet have the tools to formulate that. /-- When `F ⊣ G`, diff --git a/Mathlib/CategoryTheory/Adjunction/Mates.lean b/Mathlib/CategoryTheory/Adjunction/Mates.lean index 4e9e887d029919..a46895413dd9e3 100644 --- a/Mathlib/CategoryTheory/Adjunction/Mates.lean +++ b/Mathlib/CategoryTheory/Adjunction/Mates.lean @@ -48,7 +48,7 @@ set_option backward.defeqAttrib.useBackward true universe v₁ v₂ v₃ v₄ v₅ v₆ v₇ v₈ v₉ u₁ u₂ u₃ u₄ u₅ u₆ u₇ u₈ u₉ namespace CategoryTheory -open Category Functor Adjunction NatTrans TwoSquare +open Category CategoryTheory.Functor Adjunction NatTrans TwoSquare section mateEquiv @@ -58,7 +58,6 @@ variable {G : C ⥤ E} {H : D ⥤ F} {L₁ : C ⥤ D} {R₁ : D ⥤ C} {L₂ : E variable (adj₁ : L₁ ⊣ R₁) (adj₂ : L₂ ⊣ R₂) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and `L₂ ⊣ R₂` respectively). @@ -133,7 +132,6 @@ theorem mateEquiv_counit_symm (α : TwoSquare R₁ H G R₂) (d : D) : exact (mateEquiv_counit adj₁ adj₂ ((mateEquiv adj₁ adj₂).symm α) d) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /- A component of a transposed version of the mates correspondence. -/ theorem unit_mateEquiv (α : TwoSquare G L₁ L₂ H) (c : C) : G.map (adj₁.unit.app c) ≫ (mateEquiv adj₁ adj₂ α).app _ = @@ -168,7 +166,6 @@ variable {L₁ : A ⥤ B} {R₁ : B ⥤ A} {L₂ : C ⥤ D} {R₂ : D ⥤ C} {L variable (adj₁ : L₁ ⊣ R₁) (adj₂ : L₂ ⊣ R₂) (adj₃ : L₃ ⊣ R₃) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The mates equivalence commutes with vertical composition. -/ theorem mateEquiv_vcomp (α : TwoSquare G₁ L₁ L₂ H₁) (β : TwoSquare G₂ L₂ L₃ H₂) : (mateEquiv adj₁ adj₃) (α ≫ₕ β) = (mateEquiv adj₁ adj₂ α) ≫ᵥ (mateEquiv adj₂ adj₃ β) := by @@ -208,7 +205,6 @@ variable {L₃ : B ⥤ C} {R₃ : C ⥤ B} {L₄ : E ⥤ F} {R₄ : F ⥤ E} variable (adj₁ : L₁ ⊣ R₁) (adj₂ : L₂ ⊣ R₂) (adj₃ : L₃ ⊣ R₃) (adj₄ : L₄ ⊣ R₄) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The mates equivalence commutes with horizontal composition of squares. -/ theorem mateEquiv_hcomp (α : TwoSquare G L₁ L₂ H) (β : TwoSquare H L₃ L₄ K) : (mateEquiv (adj₁.comp adj₃) (adj₂.comp adj₄)) (α ≫ᵥ β) = @@ -298,6 +294,7 @@ theorem conjugateEquiv_counit_symm (α : R₁ ⟶ R₂) (d : D) : conv_lhs => rw [← (conjugateEquiv adj₁ adj₂).right_inv α] exact (conjugateEquiv_counit adj₁ adj₂ ((conjugateEquiv adj₁ adj₂).symm α) d) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A component of a transposed form of the conjugation definition. -/ theorem unit_conjugateEquiv (α : L₂ ⟶ L₁) (c : C) : @@ -333,6 +330,7 @@ theorem conjugateEquiv_adjunction_id {L R : C ⥤ C} (adj : L ⊣ R) (α : 𝟭 (conjugateEquiv adj Adjunction.id α).app c = α.app (R.obj c) ≫ adj.counit.app c := by simp [conjugateEquiv, mateEquiv, Adjunction.id] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem conjugateEquiv_adjunction_id_symm {L R : C ⥤ C} (adj : L ⊣ R) (α : R ⟶ 𝟭 C) (c : C) : ((conjugateEquiv adj Adjunction.id).symm α).app c = adj.unit.app c ≫ α.app (L.obj c) := by @@ -346,6 +344,7 @@ variable [Category.{v₁} C] [Category.{v₂} D] variable {L₁ L₂ L₃ : C ⥤ D} {R₁ R₂ R₃ : D ⥤ C} variable (adj₁ : L₁ ⊣ R₁) (adj₂ : L₂ ⊣ R₂) (adj₃ : L₃ ⊣ R₃) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] theorem conjugateEquiv_comp (α : L₂ ⟶ L₁) (β : L₃ ⟶ L₂) : @@ -446,6 +445,7 @@ variable {F₁ : A ⥤ C} {U₁ : C ⥤ A} {F₂ : B ⥤ D} {U₂ : D ⥤ B} variable {L₁ : A ⥤ B} {R₁ : B ⥤ A} {L₂ : C ⥤ D} {R₂ : D ⥤ C} variable (adj₁ : L₁ ⊣ R₁) (adj₂ : L₂ ⊣ R₂) (adj₃ : F₁ ⊣ U₁) (adj₄ : F₂ ⊣ U₂) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When all four functors in a square are left adjoints, the mates operation can be iterated: @@ -467,6 +467,7 @@ theorem iterated_mateEquiv_conjugateEquiv (α : TwoSquare F₁ L₁ L₂ F₂) : ext d simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem iterated_mateEquiv_conjugateEquiv_symm (α : TwoSquare U₂ R₂ R₁ U₁) : (mateEquiv adj₁ adj₂).symm ((mateEquiv adj₄ adj₃).symm α) = @@ -479,6 +480,7 @@ end IteratedmateEquiv variable {G : A ⥤ C} {H : B ⥤ D} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The mates equivalence commutes with this composition, essentially by `mateEquiv_vcomp`. -/ theorem mateEquiv_conjugateEquiv_vcomp {L₁ : A ⥤ B} {R₁ : B ⥤ A} {L₂ : C ⥤ D} {R₂ : D ⥤ C} @@ -497,6 +499,7 @@ theorem mateEquiv_conjugateEquiv_vcomp {L₁ : A ⥤ B} {R₁ : B ⥤ A} {L₂ : comp_id] at vcompb simpa [mateEquiv] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The mates equivalence commutes with this composition, essentially by `mateEquiv_vcomp`. -/ theorem conjugateEquiv_mateEquiv_vcomp {L₁ : A ⥤ B} {R₁ : B ⥤ A} {L₂ : A ⥤ B} {R₂ : B ⥤ A} diff --git a/Mathlib/CategoryTheory/Adjunction/Opposites.lean b/Mathlib/CategoryTheory/Adjunction/Opposites.lean index 8652dac88e7b4a..d73b423a1566c6 100644 --- a/Mathlib/CategoryTheory/Adjunction/Opposites.lean +++ b/Mathlib/CategoryTheory/Adjunction/Opposites.lean @@ -66,11 +66,13 @@ def rightOp {F : Cᵒᵖ ⥤ D} {G : Dᵒᵖ ⥤ C} (a : F.rightOp ⊣ G) : G.ri left_triangle_components X := congr($(a.right_triangle_components (.op X)).op) right_triangle_components X := congr($(a.left_triangle_components X.unop).unop) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma leftOp_eq {F : C ⥤ Dᵒᵖ} {G : D ⥤ Cᵒᵖ} (a : F ⊣ G.leftOp) : a.leftOp = (opOpEquivalence D).symm.toAdjunction.comp a.op := by ext X; simp [Equivalence.unit] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma rightOp_eq {F : Cᵒᵖ ⥤ D} {G : Dᵒᵖ ⥤ C} (a : F.rightOp ⊣ G) : a.rightOp = (opOpEquivalence D).symm.toAdjunction.comp a.op := by diff --git a/Mathlib/CategoryTheory/Adjunction/Parametrized.lean b/Mathlib/CategoryTheory/Adjunction/Parametrized.lean index d99940649cabd0..6f498c88b51beb 100644 --- a/Mathlib/CategoryTheory/Adjunction/Parametrized.lean +++ b/Mathlib/CategoryTheory/Adjunction/Parametrized.lean @@ -41,7 +41,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open Opposite Functor +open Opposite CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} {C₃ : Type u₃} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} C₃] diff --git a/Mathlib/CategoryTheory/Adjunction/Quadruple.lean b/Mathlib/CategoryTheory/Adjunction/Quadruple.lean index bc7e4a20e916e5..f7c4fc4116ab98 100644 --- a/Mathlib/CategoryTheory/Adjunction/Quadruple.lean +++ b/Mathlib/CategoryTheory/Adjunction/Quadruple.lean @@ -84,6 +84,7 @@ section RightFullyFaithful variable [F.Full] [F.Faithful] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For an adjoint quadruple `L ⊣ F ⊣ G ⊣ R` where `F` (and hence also `R`) is fully faithful, all components of the natural transformation `G ⟶ L` are epimorphisms iff all components of the natural diff --git a/Mathlib/CategoryTheory/Adjunction/Reflective.lean b/Mathlib/CategoryTheory/Adjunction/Reflective.lean index 71c357b1d7d589..ca642c5a708a44 100644 --- a/Mathlib/CategoryTheory/Adjunction/Reflective.lean +++ b/Mathlib/CategoryTheory/Adjunction/Reflective.lean @@ -57,7 +57,6 @@ instance [Reflective i] : (reflector i).IsLeftAdjoint := ⟨_, ⟨reflectorAdjun def Functor.fullyFaithfulOfReflective [Reflective i] : i.FullyFaithful := (reflectorAdjunction i).fullyFaithfulROfIsIsoCounit -set_option backward.isDefEq.respectTransparency false in -- TODO: This holds more generally for idempotent adjunctions, not just reflective adjunctions. /-- For a reflective functor `i` (with left adjoint `L`), with unit `η`, we have `η_iL = iL η`. -/ @@ -89,7 +88,6 @@ theorem Functor.essImage.unit_isIso [Reflective i] {A : C} (h : i.essImage A) : IsIso ((reflectorAdjunction i).unit.app A) := by rwa [isIso_unit_app_iff_mem_essImage] -set_option backward.isDefEq.respectTransparency false in /-- If `η_A` is a split monomorphism, then `A` is in the reflective subcategory. -/ theorem mem_essImage_of_unit_isSplitMono [Reflective i] {A : C} [IsSplitMono ((reflectorAdjunction i).unit.app A)] : i.essImage A := by @@ -161,8 +159,8 @@ instance [Reflective i] (X : Functor.EssImageSubcategory i) : IsIso (NatTrans.app (reflectorAdjunction i).unit X.obj) := Functor.essImage.unit_isIso X.property +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -- These attributes are necessary to make automation work in `equivEssImageOfReflective`. -- Making them global doesn't break anything elsewhere, but this is enough for now. -- TODO: investigate further. @@ -204,7 +202,6 @@ instance [Coreflective j] : (coreflector j).IsRightAdjoint := ⟨_, ⟨coreflect def Functor.fullyFaithfulOfCoreflective [Coreflective j] : j.FullyFaithful := (coreflectorAdjunction j).fullyFaithfulLOfIsIsoUnit -set_option backward.isDefEq.respectTransparency false in lemma counit_obj_eq_map_counit [Coreflective j] (X : D) : (coreflectorAdjunction j).counit.app (j.obj ((coreflector j).obj X)) = j.map ((coreflector j).map ((coreflectorAdjunction j).counit.app X)) := by @@ -221,7 +218,6 @@ lemma Functor.essImage.counit_isIso [Coreflective j] {A : D} (h : j.essImage A) IsIso ((coreflectorAdjunction j).counit.app A) := by rwa [isIso_counit_app_iff_mem_essImage] -set_option backward.isDefEq.respectTransparency false in lemma mem_essImage_of_counit_isSplitEpi [Coreflective j] {A : D} [IsSplitEpi ((coreflectorAdjunction j).counit.app A)] : j.essImage A := by let ε : coreflector j ⋙ j ⟶ 𝟭 D := (coreflectorAdjunction j).counit diff --git a/Mathlib/CategoryTheory/Adjunction/Restrict.lean b/Mathlib/CategoryTheory/Adjunction/Restrict.lean index 416187d5e84c72..7c12c376217b32 100644 --- a/Mathlib/CategoryTheory/Adjunction/Restrict.lean +++ b/Mathlib/CategoryTheory/Adjunction/Restrict.lean @@ -33,7 +33,6 @@ variable {iC : C ⥤ C'} {iD : D ⥤ D'} attribute [local simp] homEquiv_unit homEquiv_counit -set_option backward.isDefEq.respectTransparency false in /-- If `C` is a full subcategory of `C'` and `D` is a full subcategory of `D'`, then we can restrict an adjunction `L' ⊣ R'` where `L' : C' ⥤ D'` and `R' : D' ⥤ C'` to `C` and `D`. The construction here is slightly more general, in that `C` is required only to have a full and @@ -74,7 +73,6 @@ lemma map_restrictFullyFaithful_counit_app (X : D) : dsimp [restrictFullyFaithful] simp -set_option backward.isDefEq.respectTransparency false in lemma restrictFullyFaithful_homEquiv_apply {X : C} {Y : D} (f : L.obj X ⟶ Y) : (adj.restrictFullyFaithful hiC hiD comm1 comm2).homEquiv X Y f = hiC.preimage (adj.unit.app (iC.obj X) ≫ R'.map (comm1.hom.app X) ≫ diff --git a/Mathlib/CategoryTheory/Adjunction/Triple.lean b/Mathlib/CategoryTheory/Adjunction/Triple.lean index 952f2a5bf6b9b6..d7ce48d3c66372 100644 --- a/Mathlib/CategoryTheory/Adjunction/Triple.lean +++ b/Mathlib/CategoryTheory/Adjunction/Triple.lean @@ -127,7 +127,6 @@ lemma map_rightToLeft_app (X : C) : congr_app t.whiskerRight_rightToLeft X set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The natural transformation `H ⟶ F` for an adjoint triple `F ⊣ G ⊣ H` with `G` fully faithful is also equal to the whiskered unit `H ⟶ F ⋙ G ⋙ H` of the first adjunction followed by the inverse of the whiskered unit `F ⟶ F ⋙ G ⋙ H` of the second. -/ @@ -137,7 +136,6 @@ lemma rightToLeft_eq_units : ext X; apply G.map_injective; simp [rightToLeft] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The natural transformation `H ⟶ F` for an adjoint triple `F ⊣ G ⊣ H` with `G` fully faithful is also equal to the inverse of the whiskered counit `H ⋙ G ⋙ F ⟶ H` of the first adjunction followed by the whiskered counit `H ⋙ G ⋙ F ⟶ F` of the second. -/ @@ -146,18 +144,17 @@ lemma rightToLeft_eq_counits : (Functor.associator _ _ _).inv ≫ whiskerRight t.adj₂.counit F ≫ F.leftUnitor.hom := by ext X; apply G.map_injective; simp [rightToLeft] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma adj₁_counit_app_rightToLeft_app (X : C) : t.adj₁.counit.app (H.obj X) ≫ t.rightToLeft.app X = F.map (t.adj₂.counit.app X) := G.map_injective (by simp [← cancel_epi (t.adj₁.unit.app _)]) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma rightToLeft_app_adj₂_unit_app (X : C) : t.rightToLeft.app X ≫ t.adj₂.unit.app (F.obj X) = H.map (t.adj₁.unit.app X) := G.map_injective (by simp [← cancel_mono (t.adj₂.counit.app _)]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For an adjoint triple `F ⊣ G ⊣ H` where `G` is fully faithful, the natural transformation `F.op ⟶ H.op` obtained from the dual adjoint triple `H.op ⊣ G.op ⊣ F.op` is dual to the natural @@ -168,21 +165,18 @@ lemma op_rightToLeft : t.op.rightToLeft = NatTrans.op t.rightToLeft := by rw [rightToLeft_eq_units, rightToLeft_eq_counits] simp -set_option backward.isDefEq.respectTransparency false in /-- For an adjoint triple `F ⊣ G ⊣ H` where `G` is fully faithful, the natural transformation `H ⟶ F` is epic at `X` iff the image of the unit of the adjunction `F ⊣ G` under `H` is. -/ lemma epi_rightToLeft_app_iff_epi_map_adj₁_unit_app {X : C} : Epi (t.rightToLeft.app X) ↔ Epi (H.map (t.adj₁.unit.app X)) := by rw [← epi_comp_iff_of_isIso _ (t.adj₂.unit.app (F.obj X)), rightToLeft_app_adj₂_unit_app] -set_option backward.isDefEq.respectTransparency false in /-- For an adjoint triple `F ⊣ G ⊣ H` where `G` is fully faithful, the natural transformation `H ⟶ F` is epic at `X` iff the image of the counit of the adjunction `G ⊣ H` under `F` is. -/ lemma epi_rightToLeft_app_iff_epi_map_adj₂_counit_app {X : C} : Epi (t.rightToLeft.app X) ↔ Epi (F.map (t.adj₂.counit.app X)) := by rw [← epi_comp_iff_of_epi (t.adj₁.counit.app (H.obj X)), adj₁_counit_app_rightToLeft_app] -set_option backward.isDefEq.respectTransparency false in /-- For an adjoint triple `F ⊣ G ⊣ H` where `G` is fully faithful and `H` preserves epimorphisms (which is for example the case if `H` has a further right adjoint), the components of the natural transformation `H ⟶ F` are epic iff the respective components of the natural transformation @@ -208,14 +202,12 @@ noncomputable def leftToRight : F ⟶ H := inv (whiskerRight t.adj₁.unit H) ≫ H.leftUnitor.hom set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in omit [H.Full] [H.Faithful] in lemma leftToRight_app {X : C} : t.leftToRight.app X = t.adj₂.unit.app (F.obj X) ≫ inv (H.map (t.adj₁.unit.app X)) := by simp [leftToRight] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The natural transformation `F ⟶ H` for an adjoint triple `F ⊣ G ⊣ H` with `F` and `H` fully faithful is also equal to the inverse of the whiskered counit `H ⋙ G ⋙ F ⟶ F` of the second adjunction followed by the whiskered counit `H ⋙ G ⋙ F ⟶ H` of the first. -/ @@ -230,7 +222,6 @@ lemma leftToRight_eq_counits : ← (asIso _).comp_hom_eq_id.1 <| t.adj₂.left_triangle_components (F.obj X)] simp -set_option backward.isDefEq.respectTransparency false in omit [H.Full] [H.Faithful] in /-- For an adjoint triple `F ⊣ G ⊣ H` where `F` and `H` are fully faithful, the components of the natural transformation `F ⟶ H` at `G` are precisely the components of the natural transformation @@ -265,6 +256,7 @@ lemma leftToRight_app_map_adj₁_unit_app (X : C) : t.leftToRight.app X ≫ H.map (t.adj₁.unit.app X) = t.adj₂.unit.app (F.obj X) := by simp [leftToRight_app] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For an adjoint triple `F ⊣ G ⊣ H` where `F` and `H` are fully faithful, the natural transformation `H.op ⟶ F.op` obtained from the dual adjoint triple `H.op ⊣ G.op ⊣ F.op` is @@ -275,7 +267,6 @@ lemma leftToRight_op : t.op.leftToRight = NatTrans.op t.leftToRight := by rw [leftToRight, leftToRight_eq_counits] simp -set_option backward.isDefEq.respectTransparency false in omit [H.Full] [H.Faithful] in /-- For an adjoint triple `F ⊣ G ⊣ H` where `F` and `H` are fully faithful, the natural transformation `F ⟶ H` is monic at `X` iff the unit of the adjunction `G ⊣ H` is monic @@ -284,7 +275,6 @@ lemma mono_leftToRight_app_iff_mono_adj₂_unit_app {X : C} : Mono (t.leftToRight.app X) ↔ Mono (t.adj₂.unit.app (F.obj X)) := by rw [← leftToRight_app_map_adj₁_unit_app, mono_comp_iff_of_mono] -set_option backward.isDefEq.respectTransparency false in /-- For an adjoint triple `F ⊣ G ⊣ H` where `F` and `H` are fully faithful, the natural transformation `F ⟶ H` is monic at `X` iff the counit of the adjunction `F ⊣ G` is monic at `H.obj X`. -/ @@ -292,7 +282,6 @@ lemma mono_leftToRight_app_iff_mono_adj₁_counit_app {X : C} : Mono (t.leftToRight.app X) ↔ Mono (t.adj₁.counit.app (H.obj X)) := by rw [← map_adj₂_counit_app_leftToRight_app, mono_comp_iff_of_isIso] -set_option backward.isDefEq.respectTransparency false in omit [H.Full] [H.Faithful] in /-- For an adjoint triple `F ⊣ G ⊣ H` where `F` and `H` are fully faithful, the natural transformation `F ⟶ H` is componentwise monic iff the natural transformation `G ⋙ F ⟶ G ⋙ H` diff --git a/Mathlib/CategoryTheory/Adjunction/Unique.lean b/Mathlib/CategoryTheory/Adjunction/Unique.lean index 0cd61c22d58863..582f63ba5b1cf0 100644 --- a/Mathlib/CategoryTheory/Adjunction/Unique.lean +++ b/Mathlib/CategoryTheory/Adjunction/Unique.lean @@ -117,7 +117,6 @@ theorem unit_rightAdjointUniq_hom_app {F : C ⥤ D} {G G' : D ⥤ C} (adj1 : F rw [← adj2.unit_naturality_assoc, ← G'.map_comp] simp -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem unit_rightAdjointUniq_hom {F : C ⥤ D} {G G' : D ⥤ C} (adj1 : F ⊣ G) (adj2 : F ⊣ G') : adj1.unit ≫ whiskerLeft F (rightAdjointUniq adj1 adj2).hom = adj2.unit := by @@ -130,7 +129,6 @@ theorem rightAdjointUniq_hom_app_counit {F : C ⥤ D} {G G' : D ⥤ C} (adj1 : F F.map ((rightAdjointUniq adj1 adj2).hom.app x) ≫ adj2.counit.app x = adj1.counit.app x := by simp [rightAdjointUniq] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem rightAdjointUniq_hom_counit {F : C ⥤ D} {G G' : D ⥤ C} (adj1 : F ⊣ G) (adj2 : F ⊣ G') : whiskerRight (rightAdjointUniq adj1 adj2).hom F ≫ adj2.counit = adj1.counit := by diff --git a/Mathlib/CategoryTheory/Adjunction/Whiskering.lean b/Mathlib/CategoryTheory/Adjunction/Whiskering.lean index eb7c9f90b6b336..077be1045c8a7c 100644 --- a/Mathlib/CategoryTheory/Adjunction/Whiskering.lean +++ b/Mathlib/CategoryTheory/Adjunction/Whiskering.lean @@ -21,7 +21,7 @@ and the functor categories `E ⥤ C` and `D ⥤ C`. namespace CategoryTheory.Adjunction -open CategoryTheory Functor +open CategoryTheory CategoryTheory.Functor variable (C : Type*) {D E : Type*} [Category* C] [Category* D] [Category* E] {F : D ⥤ E} {G : E ⥤ D} diff --git a/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean b/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean index c6b07f45d5f632..d74b5d71269c72 100644 --- a/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean +++ b/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean @@ -80,6 +80,7 @@ lemma Adjunction.ofCat_id (C : Cat.{v, u}) : Adjunction.ofCat (Adjunction.id C) = CategoryTheory.Adjunction.id := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma Adjunction.ofCat_comp {C D E : Cat.{v, u}} {F : C ⟶ D} {G : D ⟶ C} (adj : F ⊣ G) @@ -88,6 +89,7 @@ lemma Adjunction.ofCat_comp {C D E : Cat.{v, u}} ext simp [bicategoricalComp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma toNatTrans_mateEquiv {C D E F : Cat} {G : C ⟶ E} {H : D ⟶ F} {L₁ : C ⟶ D} {R₁ : D ⟶ C} {L₂ : E ⟶ F} {R₂ : F ⟶ E} @@ -129,12 +131,18 @@ lemma right_triangle_components (X : C₂.obj) : 𝟙 (α.r.toFunctor.obj X) := (Adjunction.ofCat α.adj).right_triangle_components _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma unit_naturality {X Y : C₁.obj} (f : X ⟶ Y) : α.adj.unit.toNatTrans.app X ≫ α.r.toFunctor.map (α.l.toFunctor.map f) = f ≫ α.adj.unit.toNatTrans.app Y := (Adjunction.ofCat α.adj).unit_naturality f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma counit_naturality {X Y : C₂.obj} (f : X ⟶ Y) : α.l.toFunctor.map (α.r.toFunctor.map f) ≫ α.adj.counit.toNatTrans.app Y = diff --git a/Mathlib/CategoryTheory/Bicategory/CatEnriched.lean b/Mathlib/CategoryTheory/Bicategory/CatEnriched.lean index 977186d57550e6..bfa43a5a0228e4 100644 --- a/Mathlib/CategoryTheory/Bicategory/CatEnriched.lean +++ b/Mathlib/CategoryTheory/Bicategory/CatEnriched.lean @@ -101,6 +101,7 @@ instance : EnrichedOrdinaryCategory Cat (CatEnriched C) where homEquiv_id _ := ((Cat.Hom.equivFunctor _ _).trans Cat.fromChosenTerminalEquiv).symm_apply_eq.mpr rfl +set_option backward.isDefEq.respectTransparency.types false in theorem id_hComp_heq {a b : CatEnriched C} {f f' : a ⟶ b} (η : f ⟶ f') : HEq (hComp (𝟙 (𝟙 a)) η) η := by rw [id_eq, ← Functor.map_id] @@ -110,6 +111,7 @@ theorem id_hComp {a b : CatEnriched C} {f f' : a ⟶ b} (η : f ⟶ f') : hComp (𝟙 (𝟙 a)) η = eqToHom (id_comp f) ≫ η ≫ eqToHom (id_comp f').symm := by simp [← heq_eq_eq, id_hComp_heq] +set_option backward.isDefEq.respectTransparency.types false in theorem hComp_id_heq {a b : CatEnriched C} {f f' : a ⟶ b} (η : f ⟶ f') : HEq (hComp η (𝟙 (𝟙 b))) η := by rw [id_eq, ← Functor.map_id] @@ -315,6 +317,7 @@ theorem hComp_assoc_heq {a b c d : CatEnrichedOrdinary C} {f f' : a ⟶ b} {g g' : b ⟶ c} {h h' : c ⟶ d} (η : f ⟶ f') (θ : g ⟶ g') (κ : h ⟶ h') : HEq (hComp (hComp η θ) κ) (hComp η (hComp θ κ)) := by simp [hComp_assoc] +set_option backward.isDefEq.respectTransparency.types false in instance : Bicategory (CatEnrichedOrdinary C) where homCategory := inferInstance whiskerLeft {_ _ _} f {_ _} η := hComp (𝟙 f) η diff --git a/Mathlib/CategoryTheory/Bicategory/Coherence.lean b/Mathlib/CategoryTheory/Bicategory/Coherence.lean index 66e63499463521..e9cc202d5bb63e 100644 --- a/Mathlib/CategoryTheory/Bicategory/Coherence.lean +++ b/Mathlib/CategoryTheory/Bicategory/Coherence.lean @@ -72,6 +72,7 @@ bicategory. def inclusionPath (a b : B) : Discrete (Path.{v} a b) ⥤ Hom a b := Discrete.functor inclusionPathAux +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion from the locally discrete bicategory on the path category into the free bicategory as a prelax functor. This will be promoted to a pseudofunctor after proving the coherence theorem. See `inclusion`. @@ -86,6 +87,7 @@ def preinclusion (B : Type u) [Quiver.{v} B] : theorem preinclusion_obj (a : B) : (preinclusion B).obj ⟨a⟩ = a := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem preinclusion_map₂ {a b : B} (f g : Discrete (Path.{v} a b)) (η : f ⟶ g) : (preinclusion B).map₂ η = eqToHom (congr_arg _ (Discrete.ext (Discrete.eq_of_hom η))) := @@ -121,6 +123,7 @@ example {a b c : B} (p : Path a b) (f : Hom b c) : case comp _ _ _ _ _ ihf ihg => rw [normalizeAux, ihf, ihg]; apply comp_assoc ``` -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A 2-isomorphism between a partially-normalized 1-morphism in the free bicategory to the fully-normalized 1-morphism. -/ @@ -144,12 +147,14 @@ def normalizeIso {a : B} : @[simp] theorem normalizeAux_id {a : B} {b : FreeBicategory B} (p : Path a b) : normalizeAux p (𝟙 b) = p := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem normalizeIso_comp {a : B} {b c d : FreeBicategory B} (p : Path a b) (f : b ⟶ c) (g : c ⟶ d) : normalizeIso p (f ≫ g) = (α_ _ _ _).symm ≪≫ whiskerRightIso (normalizeIso p f) g ≪≫ normalizeIso (normalizeAux p f) g := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem normalizeIso_id {a : B} {b : FreeBicategory B} (p : Path a b) : normalizeIso p (𝟙 b) = ρ_ _ := rfl @@ -214,6 +219,7 @@ def normalize (B : Type u) [Quiver.{v} B] : mapId _ := eqToIso <| Discrete.ext rfl mapComp f g := eqToIso <| Discrete.ext <| normalizeAux_nil_comp f g +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `normalizeEquiv`. -/ def normalizeUnitIso (a b : FreeBicategory B) : 𝟭 (a ⟶ b) ≅ (normalize B).mapFunctor a b ⋙ @inclusionPath B _ a b := @@ -224,6 +230,7 @@ def normalizeUnitIso (a b : FreeBicategory B) : congr 1 exact normalize_naturality nil η) +set_option backward.isDefEq.respectTransparency.types false in /-- Normalization as an equivalence of categories. -/ def normalizeEquiv (a b : B) : Hom a b ≌ Discrete (Path.{v} a b) := Equivalence.mk ((normalize _).mapFunctor a b) (inclusionPath a b) (normalizeUnitIso a b) @@ -237,11 +244,13 @@ def normalizeEquiv (a b : B) : Hom a b ≌ Discrete (Path.{v} a b) := conv_rhs => rw [← ih] rfl)) +set_option backward.isDefEq.respectTransparency.types false in /-- The coherence theorem for bicategories. -/ instance locally_thin {a b : FreeBicategory B} : Quiver.IsThin (a ⟶ b) := fun _ _ => ⟨fun _ _ => (@normalizeEquiv B _ a b).functor.map_injective (Subsingleton.elim _ _)⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `inclusion`. -/ def inclusionMapCompAux {a b : B} : ∀ {c : B} (f : Path a b) (g : Path b c), @@ -249,6 +258,7 @@ def inclusionMapCompAux {a b : B} : | _, f, nil => (ρ_ ((preinclusion _).map ⟨f⟩)).symm | _, f, cons g₁ g₂ => whiskerRightIso (inclusionMapCompAux f g₁) (Hom.of g₂) ≪≫ α_ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion pseudofunctor from the locally discrete bicategory on the path category into the free bicategory. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Extension.lean b/Mathlib/CategoryTheory/Bicategory/Extension.lean index 7efdf3ee502023..e24dd40fab8f03 100644 --- a/Mathlib/CategoryTheory/Bicategory/Extension.lean +++ b/Mathlib/CategoryTheory/Bicategory/Extension.lean @@ -139,6 +139,7 @@ def whiskerHom (i : s ⟶ t) {x : B} (h : c ⟶ x) : _ = unit t ▷ h := congrArg (· ▷ h) (LeftExtension.w i) _ = _ := by simp +set_option backward.isDefEq.respectTransparency.types false in /-- Construct an isomorphism between whiskered extensions. -/ def whiskerIso (i : s ≅ t) {x : B} (h : c ⟶ x) : s.whisker h ≅ t.whisker h := @@ -262,6 +263,7 @@ def whiskerHom (i : s ⟶ t) {x : B} (h : x ⟶ c) : _ = h ◁ unit t := congrArg (h ◁ ·) (LeftLift.w i) _ = _ := by simp +set_option backward.isDefEq.respectTransparency.types false in /-- Construct an isomorphism between whiskered lifts. -/ def whiskerIso (i : s ≅ t) {x : B} (h : x ⟶ c) : s.whisker h ≅ t.whisker h := @@ -443,6 +445,7 @@ def whiskerIso (i : s ≅ t) {x : B} (h : x ⟶ c) : _ = h ◁ (i.inv ≫ i.hom).left := by simp [-Iso.inv_hom_id] _ = 𝟙 _ := by simp [Iso.inv_hom_id]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between right lifts induced by a left unitor. -/ @[simps! hom_left inv_left] diff --git a/Mathlib/CategoryTheory/Bicategory/Free.lean b/Mathlib/CategoryTheory/Bicategory/Free.lean index c07d7406b13fa8..db951b2a5fbf5d 100644 --- a/Mathlib/CategoryTheory/Bicategory/Free.lean +++ b/Mathlib/CategoryTheory/Bicategory/Free.lean @@ -317,6 +317,7 @@ def liftHom₂ : ∀ {a b : FreeBicategory B} {f g : a ⟶ b}, Hom₂ f g → (l | _, _, _, _, Hom₂.whisker_left f η => liftHom F f ◁ liftHom₂ η | _, _, _, _, Hom₂.whisker_right h η => liftHom₂ η ▷ liftHom F h +set_option backward.isDefEq.respectTransparency.types false in attribute [local simp] whisker_exchange in theorem liftHom₂_congr {a b : FreeBicategory B} {f g : a ⟶ b} {η θ : Hom₂ f g} (H : Rel η θ) : liftHom₂ F η = liftHom₂ F θ := by induction H <;> (dsimp [liftHom₂]; cat_disch) diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Cat.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Cat.lean index 57eccfb5487dfc..ff6986108d65a8 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Cat.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Cat.lean @@ -35,12 +35,18 @@ section variable (f : b₀ ⟶ b₀) (hf : f = 𝟙 b₀) (a : X ⟶ Y) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma mapId'_hom_naturality : (F.map f).toFunctor.map a ≫ (F.mapId' f hf).hom.toNatTrans.app Y = (F.mapId' f hf).hom.toNatTrans.app X ≫ a := (F.mapId' f hf).hom.toNatTrans.naturality a +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma mapId'_inv_naturality : (F.mapId' f hf).inv.toNatTrans.app X ≫ (F.map f).toFunctor.map a = @@ -54,6 +60,9 @@ section variable (f : b₀ ⟶ b₁) (g : b₁ ⟶ b₂) (fg : b₀ ⟶ b₂) (hfg : f ≫ g = fg) (a : X ⟶ Y) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma mapComp'_hom_naturality : (F.map fg).toFunctor.map a ≫ (F.mapComp' f g fg hfg).hom.toNatTrans.app Y = diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean index b80e37fdab65af..c409350fa4e9c0 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean @@ -121,6 +121,7 @@ lemma mapComp_inv_app {X Y Z : B} (f : X ⟶ Y) (g : Y ⟶ Z) (M : P.Obj X) : (P.mapComp f g).inv.app M = ObjectProperty.homMk ((F.mapComp f g).inv.toNatTrans.app M.obj) := rfl +set_option backward.isDefEq.respectTransparency false in /-- Given a property of objects `P` for a pseudofunctor from `B` to `Cat`, this is the induced pseudofunctor which sends `X : B` to the full subcategory of `F.obj X` consisting of objects satisfying `P`. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Lax.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Lax.lean index 9538fa3c7be722..c5e0d792102595 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Lax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Lax.lean @@ -97,6 +97,9 @@ variable {B : Type u₁} [Bicategory.{w₁, v₁} B] {C : Type u₂} [Bicategory attribute [to_app (attr := reassoc (attr := simp))] mapComp_naturality_left mapComp_naturality_right map₂_associator +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in attribute [simp, to_app (attr := reassoc)] map₂_leftUnitor map₂_rightUnitor /-- The underlying prelax functor. -/ @@ -118,12 +121,18 @@ lemma mapComp_assoc_right {a b c d : B} (f : a ⟶ b) (g : b ⟶ c) (h : c ⟶ d F.mapComp (f ≫ g) h ≫ F.map₂ (α_ f g h).hom := by simp only [map₂_associator, Iso.inv_hom_id_assoc] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma map₂_leftUnitor_hom {a b : B} (f : a ⟶ b) : (λ_ (F.map f)).hom = F.mapId a ▷ F.map f ≫ F.mapComp (𝟙 a) f ≫ F.map₂ (λ_ f).hom := by rw [← PrelaxFunctor.map₂Iso_hom, ← assoc, ← Iso.comp_inv_eq, ← Iso.eq_inv_comp] simp only [Functor.mapIso_inv, PrelaxFunctor.mapFunctor_map, map₂_leftUnitor] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma map₂_rightUnitor_hom {a b : B} (f : a ⟶ b) : (ρ_ (F.map f)).hom = F.map f ◁ F.mapId b ≫ F.mapComp f (𝟙 b) ≫ F.map₂ (ρ_ f).hom := by diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Oplax.lean index 7bf794a660a427..f043a3f61dacc2 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Oplax.lean @@ -96,6 +96,9 @@ namespace OplaxFunctor attribute [to_app (attr := reassoc (attr := simp))] mapComp_naturality_left mapComp_naturality_right map₂_associator +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in attribute [simp, to_app (attr := reassoc)] map₂_leftUnitor map₂_rightUnitor section diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean index 97c74eaebb645b..c65bcdfe25a8be 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean @@ -90,6 +90,9 @@ initialize_simps_projections Pseudofunctor (+toPrelaxFunctor, -obj, -map, -map namespace Pseudofunctor +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in attribute [simp, to_app (attr := reassoc)] map₂_whisker_left map₂_whisker_right map₂_associator map₂_left_unitor map₂_right_unitor @@ -190,6 +193,9 @@ lemma mapComp_assoc_left_inv {c d : B} (f : a ⟶ b) (g : b ⟶ c) (h : c ⟶ d) (F.mapComp f (g ≫ h)).inv ≫ F.map₂ (α_ f g h).inv := F.toLax.mapComp_assoc_left _ _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp_id_left_hom (f : a ⟶ b) : (F.mapComp (𝟙 a) f).hom = F.map₂ (λ_ f).hom ≫ (λ_ (F.map f)).inv ≫ (F.mapId a).inv ▷ F.map f := by @@ -199,6 +205,9 @@ lemma mapComp_id_left (f : a ⟶ b) : (F.mapComp (𝟙 a) f) = F.map₂Iso (λ_ (λ_ (F.map f)).symm ≪≫ (whiskerRightIso (F.mapId a) (F.map f)).symm := Iso.ext <| F.mapComp_id_left_hom f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp_id_left_inv (f : a ⟶ b) : (F.mapComp (𝟙 a) f).inv = (F.mapId a).hom ▷ F.map f ≫ (λ_ (F.map f)).hom ≫ F.map₂ (λ_ f).inv := by @@ -208,16 +217,25 @@ lemma whiskerRightIso_mapId (f : a ⟶ b) : whiskerRightIso (F.mapId a) (F.map f (F.mapComp (𝟙 a) f).symm ≪≫ F.map₂Iso (λ_ f) ≪≫ (λ_ (F.map f)).symm := by simp [mapComp_id_left] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma whiskerRight_mapId_hom (f : a ⟶ b) : (F.mapId a).hom ▷ F.map f = (F.mapComp (𝟙 a) f).inv ≫ F.map₂ (λ_ f).hom ≫ (λ_ (F.map f)).inv := by simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma whiskerRight_mapId_inv (f : a ⟶ b) : (F.mapId a).inv ▷ F.map f = (λ_ (F.map f)).hom ≫ F.map₂ (λ_ f).inv ≫ (F.mapComp (𝟙 a) f).hom := by simpa using congrArg (·.inv) (F.whiskerRightIso_mapId f) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp_id_right_hom (f : a ⟶ b) : (F.mapComp f (𝟙 b)).hom = F.map₂ (ρ_ f).hom ≫ (ρ_ (F.map f)).inv ≫ F.map f ◁ (F.mapId b).inv := by @@ -227,6 +245,9 @@ lemma mapComp_id_right (f : a ⟶ b) : (F.mapComp f (𝟙 b)) = F.map₂Iso (ρ_ (ρ_ (F.map f)).symm ≪≫ (whiskerLeftIso (F.map f) (F.mapId b)).symm := Iso.ext <| F.mapComp_id_right_hom f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp_id_right_inv (f : a ⟶ b) : (F.mapComp f (𝟙 b)).inv = F.map f ◁ (F.mapId b).hom ≫ (ρ_ (F.map f)).hom ≫ F.map₂ (ρ_ f).inv := by @@ -236,11 +257,17 @@ lemma whiskerLeftIso_mapId (f : a ⟶ b) : whiskerLeftIso (F.map f) (F.mapId b) (F.mapComp f (𝟙 b)).symm ≪≫ F.map₂Iso (ρ_ f) ≪≫ (ρ_ (F.map f)).symm := by simp [mapComp_id_right] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma whiskerLeft_mapId_hom (f : a ⟶ b) : F.map f ◁ (F.mapId b).hom = (F.mapComp f (𝟙 b)).inv ≫ F.map₂ (ρ_ f).hom ≫ (ρ_ (F.map f)).inv := by simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma whiskerLeft_mapId_inv (f : a ⟶ b) : F.map f ◁ (F.mapId b).inv = (ρ_ (F.map f)).hom ≫ F.map₂ (ρ_ f).inv ≫ (F.mapComp f (𝟙 b)).hom := by diff --git a/Mathlib/CategoryTheory/Bicategory/FunctorBicategory/Pseudo.lean b/Mathlib/CategoryTheory/Bicategory/FunctorBicategory/Pseudo.lean index a02d89864b0886..9278706dd3226b 100644 --- a/Mathlib/CategoryTheory/Bicategory/FunctorBicategory/Pseudo.lean +++ b/Mathlib/CategoryTheory/Bicategory/FunctorBicategory/Pseudo.lean @@ -77,6 +77,7 @@ abbrev rightUnitor (η : F ⟶ G) : η ≫ 𝟙 G ≅ η := variable (B C) +set_option backward.isDefEq.respectTransparency.types false in /-- A bicategory structure on pseudofunctors, with strong transformations as 1-morphisms. Note that this instance is scoped to the `Pseudofunctor.StrongTrans` namespace. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Grothendieck.lean b/Mathlib/CategoryTheory/Bicategory/Grothendieck.lean index 7be4c39c547b71..9140e751976f41 100644 --- a/Mathlib/CategoryTheory/Bicategory/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Bicategory/Grothendieck.lean @@ -67,7 +67,7 @@ namespace CategoryTheory.Pseudofunctor universe w v₁ v₂ v₃ u₁ u₂ u₃ -open Functor Category Opposite Discrete Bicategory StrongTrans +open CategoryTheory.Functor Category Opposite Discrete Bicategory StrongTrans variable {𝒮 : Type u₁} [Category.{v₁} 𝒮] @@ -352,11 +352,11 @@ def map (α : F ⟶ G) : ∫ᶜ F ⥤ ∫ᶜ G where · dsimp · simp only [categoryStruct_comp_base, op_comp, Quiver.Hom.comp_toLoc, categoryStruct_comp_fiber, Cat.Hom.comp_toFunctor, map_comp, naturality_comp_hom_app, assoc, - eqToHom_refl, comp_id, id_comp] + eqToHom_refl, comp_id] slice_lhs 2 4 => simp [← Cat.Hom.toNatIso_inv, Cat.Hom.comp_toFunctor, ← Cat.Hom.toNatIso_hom, ← map_comp, Iso.inv_hom_id_app, comp_obj, map_id, comp_id] simp only [assoc, ← reassoc_of% Cat.Hom.comp_map, - (α.naturality f.base.op.toLoc).hom.toNatTrans.naturality_assoc] + Cat.Hom.comp_toFunctor, Functor.comp_obj, NatTrans.naturality_assoc] set_option backward.isDefEq.respectTransparency false in @[simp] diff --git a/Mathlib/CategoryTheory/Bicategory/Kan/Adjunction.lean b/Mathlib/CategoryTheory/Bicategory/Kan/Adjunction.lean index e5feabb27e393c..97929ad437a9e5 100644 --- a/Mathlib/CategoryTheory/Bicategory/Kan/Adjunction.lean +++ b/Mathlib/CategoryTheory/Bicategory/Kan/Adjunction.lean @@ -43,6 +43,7 @@ section LeftExtension open LeftExtension +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For an adjunction `f ⊣ u`, `u` is an absolute left Kan extension of the identity along `f`. The unit of this Kan extension is given by the unit of the adjunction. -/ @@ -75,6 +76,7 @@ def Adjunction.isAbsoluteLeftKan {f : a ⟶ b} {u : b ⟶ a} (adj : f ⊣ u) : _ = _ := by rw [hτ]; dsimp only [StructuredArrow.homMk_right] +set_option backward.isDefEq.respectTransparency.types false in /-- A left Kan extension `t` of the identity along `f` that commutes with `f`, in the sense that `t.whisker f` is a left Kan extension, is a right adjoint to `f`. The unit of this adjoint is given by the unit of the Kan extension. -/ @@ -125,6 +127,7 @@ section LeftLift open LeftLift +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For an adjunction `f ⊣ u`, `f` is an absolute left Kan lift of the identity along `u`. The unit of this Kan lift is given by the unit of the adjunction. -/ @@ -156,6 +159,7 @@ def Adjunction.isAbsoluteLeftKanLift {f : a ⟶ b} {u : b ⟶ a} (adj : f ⊣ u) _ = _ := by rw [hτ]; dsimp only [StructuredArrow.homMk_right] +set_option backward.isDefEq.respectTransparency.types false in /-- A left Kan lift `t` of the identity along `u` that commutes with `u`, in the sense that `t.whisker u` is a left Kan lift, is a left adjoint to `u`. The unit of this adjoint is given by the unit of the Kan lift. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean b/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean index 5e4fae35cb8c5f..3bbac00b2f138c 100644 --- a/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean +++ b/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean @@ -77,7 +77,7 @@ instance {a : B} : Comonad (𝟙 a) := ComonObj.instTensorUnit (a ⟶ a) /-- An oplax functor from the trivial bicategory to `B` defines a comonad in `B`. -/ -@[implicit_reducible] +@[instance_reducible] def ofOplaxFromUnit (F : LocallyDiscrete (Discrete Unit) ⥤ᵒᵖᴸ B) : Comonad (F.map (𝟙 ⟨⟨Unit.unit⟩⟩)) where comul := F.map₂ (ρ_ _).inv ≫ F.mapComp _ _ diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Lax.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Lax.lean index cfb48778c17698..e81ca7a1c784f7 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Lax.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Lax.lean @@ -395,6 +395,9 @@ instance : Inhabited (StrongTrans F F) := variable {F} {G H : B ⥤ᴸ C} (η : StrongTrans F G) (θ : StrongTrans G H) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Vertical composition of strong natural transformations. -/ @[simps!] def vComp : StrongTrans F H := diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean index c8d3eada8f4805..8e3733d258c56b 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean @@ -389,6 +389,9 @@ instance : Inhabited (StrongTrans F F) := variable {F} {G H : B ⥤ᵒᵖᴸ C} (η : StrongTrans F G) (θ : StrongTrans G H) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Vertical composition of strong natural transformations. -/ @[simps!] def vcomp : StrongTrans F H := @@ -442,12 +445,18 @@ theorem whiskerRight_naturality_comp (f : a ⟶ b) (g : b ⟶ c) (h : G.obj c (η.naturality f).hom ▷ G.map g ▷ h ≫ (α_ _ _ _).hom ▷ h ≫ (α_ _ _ _).hom := η.toOplax.whiskerRight_naturality_comp _ _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp), to_app] theorem whiskerLeft_naturality_id (f : a' ⟶ G.obj a) : f ◁ (θ.naturality (𝟙 a)).hom ≫ f ◁ θ.app a ◁ H.mapId a = f ◁ G.mapId a ▷ θ.app a ≫ f ◁ (λ_ (θ.app a)).hom ≫ f ◁ (ρ_ (θ.app a)).inv := θ.toOplax.whiskerLeft_naturality_id _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp), to_app] theorem whiskerRight_naturality_id (f : G.obj a ⟶ a') : (η.naturality (𝟙 a)).hom ▷ f ≫ (α_ _ _ _).hom ≫ η.app a ◁ G.mapId a ▷ f = diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Pseudo.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Pseudo.lean index 9a14a4bb255ac5..2325f05df848ee 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Pseudo.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Pseudo.lean @@ -120,6 +120,9 @@ variable {H : B ⥤ᵖ C} def vcomp (η : StrongTrans F G) (θ : StrongTrans G H) : StrongTrans F H := mkOfOplax (Oplax.StrongTrans.vcomp η.toOplax θ.toOplax) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- `CategoryStruct` on `B ⥤ᵖ C` where the (1-)morphisms are given by strong transformations. -/ @[simps! id_app id_naturality_hom id_naturality_inv comp_naturality_hom @@ -178,12 +181,18 @@ theorem whiskerRight_naturality_comp (f : a ⟶ b) (g : b ⟶ c) (h : G.obj c (η.naturality f).hom ▷ G.map g ▷ h ≫ (α_ _ _ _).hom ▷ h ≫ (α_ _ _ _).hom := η.toOplax.whiskerRight_naturality_comp _ _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp), to_app] theorem whiskerLeft_naturality_id (f : a' ⟶ G.obj a) : f ◁ (θ.naturality (𝟙 a)).hom ≫ f ◁ θ.app a ◁ (H.mapId a).hom = f ◁ (G.mapId a).hom ▷ θ.app a ≫ f ◁ (λ_ (θ.app a)).hom ≫ f ◁ (ρ_ (θ.app a)).inv := θ.toOplax.whiskerLeft_naturality_id _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp), to_app] theorem whiskerRight_naturality_id (f : G.obj a ⟶ a') : (η.naturality (𝟙 a)).hom ▷ f ≫ (α_ _ _ _).hom ≫ η.app a ◁ (G.mapId a).hom ▷ f = @@ -191,6 +200,9 @@ theorem whiskerRight_naturality_id (f : G.obj a ⟶ a') : (α_ _ _ _).hom := η.toOplax.whiskerRight_naturality_id _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma naturality_id_hom (α : F ⟶ G) (a : B) : (α.naturality (𝟙 a)).hom = (F.mapId a).hom ▷ α.app a ≫ @@ -203,6 +215,9 @@ lemma naturality_id_iso (α : F ⟶ G) (a : B) : ext simp [naturality_id_hom] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma naturality_id_inv (α : F ⟶ G) (a : B) : (α.naturality (𝟙 a)).inv = α.app a ◁ (G.mapId a).hom ≫ (ρ_ (α.app a)).hom ≫ @@ -215,6 +230,7 @@ lemma naturality_naturality_hom (α : F ⟶ G) {a b : B} {f g : a ⟶ b} (η : f (F.map₂ η.inv) ▷ α.app b ≫ (α.naturality f).hom ≫ α.app a ◁ G.map₂ η.hom := by simp [← IsIso.inv_comp_eq, ← G.map₂_inv η.inv] +set_option backward.isDefEq.respectTransparency.types false in lemma naturality_naturality_iso (α : F ⟶ G) {a b : B} {f g : a ⟶ b} (η : f ≅ g) : α.naturality g = whiskerRightIso (F.map₂Iso η.symm) (α.app b) ≪≫ (α.naturality f) ≪≫ whiskerLeftIso (α.app a) (G.map₂Iso η) := by @@ -222,6 +238,7 @@ lemma naturality_naturality_iso (α : F ⟶ G) {a b : B} {f g : a ⟶ b} (η : f rw [naturality_naturality_hom α η] simp +set_option backward.isDefEq.respectTransparency.types false in lemma naturality_naturality_inv (α : F ⟶ G) {a b : B} {f g : a ⟶ b} (η : f ≅ g) : (α.naturality g).inv = α.app a ◁ G.map₂ η.inv ≫ (α.naturality f).inv ≫ F.map₂ η.hom ▷ α.app b := by diff --git a/Mathlib/CategoryTheory/Bicategory/Opposites.lean b/Mathlib/CategoryTheory/Bicategory/Opposites.lean index 9858eebf9c5f0e..befc467ec2c718 100644 --- a/Mathlib/CategoryTheory/Bicategory/Opposites.lean +++ b/Mathlib/CategoryTheory/Bicategory/Opposites.lean @@ -143,6 +143,7 @@ open Hom2 variable {B : Type u} [Bicategory.{w, v} B] +set_option backward.isDefEq.respectTransparency.types false in /-- The 1-cell dual bicategory `Bᵒᵖ`. It is defined as follows. diff --git a/Mathlib/CategoryTheory/Bicategory/Product.lean b/Mathlib/CategoryTheory/Bicategory/Product.lean index 0e9218cabd7bbd..ca72acf81bab39 100644 --- a/Mathlib/CategoryTheory/Bicategory/Product.lean +++ b/Mathlib/CategoryTheory/Bicategory/Product.lean @@ -25,7 +25,7 @@ We define: namespace CategoryTheory.Bicategory -open Prod +open CategoryTheory.Prod universe w₁ w₂ v₁ v₂ u₁ u₂ diff --git a/Mathlib/CategoryTheory/Bicategory/Strict/Pseudofunctor.lean b/Mathlib/CategoryTheory/Bicategory/Strict/Pseudofunctor.lean index fab1365331ae1b..c9b923dca13a74 100644 --- a/Mathlib/CategoryTheory/Bicategory/Strict/Pseudofunctor.lean +++ b/Mathlib/CategoryTheory/Bicategory/Strict/Pseudofunctor.lean @@ -47,11 +47,17 @@ lemma mapComp'_comp_id {b₀ b₁ : B} (f : b₀ ⟶ b₁) : ← F.map₂_comp_assoc, eqToHom_trans, eqToHom_refl, PrelaxFunctor.map₂_id, Category.id_comp] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp'_comp_id_hom {b₀ b₁ : B} (f : b₀ ⟶ b₁) : (F.mapComp' f (𝟙 b₁) f).hom = (ρ_ _).inv ≫ _ ◁ (F.mapId b₁).inv := by simp [mapComp'_comp_id] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp'_comp_id_inv {b₀ b₁ : B} (f : b₀ ⟶ b₁) : (F.mapComp' f (𝟙 b₁) f).inv = _ ◁ (F.mapId b₁).hom ≫ (ρ_ _).hom := by @@ -67,11 +73,17 @@ lemma mapComp'_id_comp {b₀ b₁ : B} (f : b₀ ⟶ b₁) : ← F.map₂_comp_assoc, eqToHom_trans, eqToHom_refl, PrelaxFunctor.map₂_id, Category.id_comp] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp'_id_comp_hom {b₀ b₁ : B} (f : b₀ ⟶ b₁) : (F.mapComp' (𝟙 b₀) f f).hom = (λ_ _).inv ≫ (F.mapId b₀).inv ▷ _ := by simp [mapComp'_id_comp] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_app (attr := reassoc)] lemma mapComp'_id_comp_inv {b₀ b₁ : B} (f : b₀ ⟶ b₁) : (F.mapComp' (𝟙 b₀) f f).inv = (F.mapId b₀).hom ▷ _ ≫ (λ_ _).hom := by diff --git a/Mathlib/CategoryTheory/Bicategory/Yoneda.lean b/Mathlib/CategoryTheory/Bicategory/Yoneda.lean index c8612bfa8dd5cd..a1cf9167555dd0 100644 --- a/Mathlib/CategoryTheory/Bicategory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Bicategory/Yoneda.lean @@ -19,7 +19,7 @@ In this file we define the bicategorical Yoneda embedding. namespace CategoryTheory -open Bicategory Bicategory.Opposite Opposite Pseudofunctor StrongTrans +open Bicategory.Opposite Opposite Pseudofunctor StrongTrans universe w v u @@ -46,6 +46,7 @@ set_option backward.defeqAttrib.useBackward true in def leftUnitorNatIsoCat (a b : B) : (precomposingCat _ _ b).obj (𝟙 a) ≅ 𝟙 (Cat.of (a ⟶ b)) := Cat.Hom.isoMk <| NatIso.ofComponents (λ_ ·) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Right component of the associator as a 2-isomorphism in `Cat`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/CatCommSq.lean b/Mathlib/CategoryTheory/CatCommSq.lean index cb8bcbad6a61e8..2aa290e8bb83b0 100644 --- a/Mathlib/CategoryTheory/CatCommSq.lean +++ b/Mathlib/CategoryTheory/CatCommSq.lean @@ -27,7 +27,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor variable {C₁ C₂ C₃ C₄ C₅ C₆ : Type*} [Category* C₁] [Category* C₂] [Category* C₃] [Category* C₄] [Category* C₅] [Category* C₆] @@ -51,7 +51,7 @@ def vId : CatCommSq T (𝟭 C₁) (𝟭 C₂) T where iso := Functor.rightUnitor _ ≪≫ (Functor.leftUnitor _).symm /-- The horizontal identity `CatCommSq` -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def hId : CatCommSq (𝟭 C₁) L L (𝟭 C₃) where iso := Functor.leftUnitor _ ≪≫ (Functor.rightUnitor _).symm @@ -66,7 +66,7 @@ lemma iso_inv_naturality [h : CatCommSq T L R B] {x y : C₁} (f : x ⟶ y) : (iso T L R B).inv.naturality f /-- Horizontal composition of 2-commutative squares -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def hComp (T₁ : C₁ ⥤ C₂) (T₂ : C₂ ⥤ C₃) (V₁ : C₁ ⥤ C₄) (V₂ : C₂ ⥤ C₅) (V₃ : C₃ ⥤ C₆) (B₁ : C₄ ⥤ C₅) (B₂ : C₅ ⥤ C₆) [CatCommSq T₁ V₁ V₂ B₁] [CatCommSq T₂ V₂ V₃ B₂] : CatCommSq (T₁ ⋙ T₂) V₁ V₃ (B₁ ⋙ B₂) where @@ -83,7 +83,7 @@ abbrev hComp' {T₁ : C₁ ⥤ C₂} {T₂ : C₂ ⥤ C₃} {V₁ : C₁ ⥤ C hComp _ _ _ V₂ _ _ _ /-- Vertical composition of 2-commutative squares -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def vComp (L₁ : C₁ ⥤ C₂) (L₂ : C₂ ⥤ C₃) (H₁ : C₁ ⥤ C₄) (H₂ : C₂ ⥤ C₅) (H₃ : C₃ ⥤ C₆) (R₁ : C₄ ⥤ C₅) (R₂ : C₅ ⥤ C₆) [CatCommSq H₁ L₁ R₁ H₂] [CatCommSq H₂ L₂ R₂ H₃] : CatCommSq H₁ (L₁ ⋙ L₂) (R₁ ⋙ R₂) H₃ where @@ -104,7 +104,7 @@ section variable (T : C₁ ≌ C₂) (L : C₁ ⥤ C₃) (R : C₂ ⥤ C₄) (B : C₃ ≌ C₄) /-- Horizontal inverse of a 2-commutative square -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def hInv (_ : CatCommSq T.functor L R B.functor) : CatCommSq T.inverse R L B.inverse where iso := isoWhiskerLeft _ (L.rightUnitor.symm ≪≫ isoWhiskerLeft L B.unitIso ≪≫ (associator _ _ _).symm ≪≫ @@ -145,7 +145,7 @@ section variable (T : C₁ ⥤ C₂) (L : C₁ ≌ C₃) (R : C₂ ≌ C₄) (B : C₃ ⥤ C₄) /-- Vertical inverse of a 2-commutative square -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def vInv (_ : CatCommSq T L.functor R.functor B) : CatCommSq B L.inverse R.inverse T where iso := isoWhiskerRight (B.leftUnitor.symm ≪≫ isoWhiskerRight L.counitIso.symm B ≪≫ associator _ _ _ ≪≫ @@ -154,7 +154,7 @@ def vInv (_ : CatCommSq T L.functor R.functor B) : CatCommSq B L.inverse R.inver (associator _ _ _).symm ≪≫ isoWhiskerLeft _ R.unitIso.symm ≪≫ rightUnitor _ -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in lemma vInv_vInv (h : CatCommSq T L.functor R.functor B) : vInv B L.symm R.symm T (vInv T L R B h) = h := by ext X diff --git a/Mathlib/CategoryTheory/Category/Bipointed.lean b/Mathlib/CategoryTheory/Category/Bipointed.lean index b794d883e3fbf7..9c8125e8a25ea1 100644 --- a/Mathlib/CategoryTheory/Category/Bipointed.lean +++ b/Mathlib/CategoryTheory/Category/Bipointed.lean @@ -97,6 +97,9 @@ def swap : Bipointed ⥤ Bipointed where obj X := ⟨X, X.toProd.swap⟩ map f := ⟨f.toFun, f.map_snd, f.map_fst⟩ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence between `Bipointed` and itself induced by `Prod.swap` both ways. -/ @[simps!] def swapEquiv : Bipointed ≌ Bipointed where diff --git a/Mathlib/CategoryTheory/Category/Cat.lean b/Mathlib/CategoryTheory/Category/Cat.lean index d2b24eb2228105..a488c7055afc16 100644 --- a/Mathlib/CategoryTheory/Category/Cat.lean +++ b/Mathlib/CategoryTheory/Category/Cat.lean @@ -28,11 +28,12 @@ universe v u namespace CategoryTheory -open Bicategory Functor +open Bicategory CategoryTheory.Functor -- intended to be used with explicit universe parameters set_option linter.checkUnivs false in /-- Category of categories. -/ +@[implicit_reducible] def Cat := Bundled Category.{v, u} @@ -71,7 +72,7 @@ instance : Quiver (Cat.{v, u}) where Hom C D := Hom C D /-- The 1-morphism in `Cat` corresponding to a functor. -/ -@[simps] +@[simps, implicit_reducible] def _root_.CategoryTheory.Functor.toCatHom {C D : Type u} [Category.{v} C] [Category.{v} D] (F : C ⥤ D) : Cat.of C ⟶ Cat.of D where toFunctor := F @@ -301,10 +302,12 @@ lemma leftUnitor_hom_toNatTrans {B C : Cat.{v, u}} (F : B ⟶ C) : lemma leftUnitor_inv_toNatTrans {B C : Cat.{v, u}} (F : B ⟶ C) : (λ_ F).inv.toNatTrans = (F.toFunctor.leftUnitor).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma leftUnitor_hom_app {B C : Cat} (F : B ⟶ C) (X : B) : (λ_ F).hom.toNatTrans.app X = eqToHom (by simp) := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma leftUnitor_inv_app {B C : Cat} (F : B ⟶ C) (X : B) : (λ_ F).inv.toNatTrans.app X = eqToHom (by simp) := by simp @@ -321,10 +324,12 @@ lemma rightUnitor_hom_toNatTrans {B C : Cat.{v, u}} (F : B ⟶ C) : lemma rightUnitor_inv_toNatTrans {B C : Cat.{v, u}} (F : B ⟶ C) : (ρ_ F).inv.toNatTrans = (F.toFunctor.rightUnitor).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma rightUnitor_hom_app {B C : Cat.{v, u}} (F : B ⟶ C) (X : B) : (ρ_ F).hom.toNatTrans.app X = eqToHom (by simp) := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma rightUnitor_inv_app {B C : Cat.{v, u}} (F : B ⟶ C) (X : B) : (ρ_ F).inv.toNatTrans.app X = eqToHom (by simp) := by simp @@ -341,10 +346,12 @@ lemma associator_hom_toNatTrans {B C D E : Cat.{v, u}} (F : B ⟶ C) (G : C ⟶ lemma associator_inv_toNatTrans {B C D E : Cat.{v, u}} (F : B ⟶ C) (G : C ⟶ D) (H : D ⟶ E) : (α_ F G H).inv.toNatTrans = (Functor.associator F.toFunctor G.toFunctor H.toFunctor).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma associator_hom_app {B C D E : Cat} (F : B ⟶ C) (G : C ⟶ D) (H : D ⟶ E) (X : B) : (α_ F G H).hom.toNatTrans.app X = eqToHom (by simp) := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma associator_inv_app {B C D E : Cat} (F : B ⟶ C) (G : C ⟶ D) (H : D ⟶ E) (X : B) : (α_ F G H).inv.toNatTrans.app X = eqToHom (by simp) := by simp @@ -373,6 +380,7 @@ section attribute [local simp] eqToHom_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism in `Cat` induces an equivalence of the underlying categories. -/ def equivOfIso {C D : Cat} (γ : C ≅ D) : C ≌ D where @@ -400,6 +408,7 @@ end end Cat +set_option backward.isDefEq.respectTransparency.types false in /-- Embedding `Type` into `Cat` as discrete categories. This ought to be modelled as a 2-functor! diff --git a/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean b/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean index d7c20dd499c2c1..98bebda8bf3477 100644 --- a/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean +++ b/Mathlib/CategoryTheory/Category/Cat/Adjunction.lean @@ -39,11 +39,13 @@ private def typeToCatObjectsAdjHomEquiv : (typeToCat.obj X ⟶ C) ≃ (X ⟶ Cat obtain rfl := Discrete.eq_of_hom f simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in private def typeToCatObjectsAdjCounitApp : (Cat.objects ⋙ typeToCat).obj C ⥤ C where obj := Discrete.as map := eqToHom ∘ Discrete.eq_of_hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- `typeToCat : Type ⥤ Cat` is left adjoint to `Cat.objects : Cat ⥤ Type` -/ diff --git a/Mathlib/CategoryTheory/Category/Cat/CartesianClosed.lean b/Mathlib/CategoryTheory/Category/Cat/CartesianClosed.lean index d3aec57b5fb6d6..a98edf73f873e9 100644 --- a/Mathlib/CategoryTheory/Category/Cat/CartesianClosed.lean +++ b/Mathlib/CategoryTheory/Category/Cat/CartesianClosed.lean @@ -30,7 +30,7 @@ universe v u v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory -open Functor Cat +open CategoryTheory.Functor Cat namespace Cat diff --git a/Mathlib/CategoryTheory/Category/Cat/Limit.lean b/Mathlib/CategoryTheory/Category/Cat/Limit.lean index 623bb8e47b117e..e0a7d484822e23 100644 --- a/Mathlib/CategoryTheory/Category/Cat/Limit.lean +++ b/Mathlib/CategoryTheory/Category/Cat/Limit.lean @@ -85,6 +85,7 @@ instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects) :) where @[simps] def limitConeX (F : J ⥤ Cat.{v, v}) : Cat.{v, v} where α := limit (F ⋙ Cat.objects) +set_option backward.isDefEq.respectTransparency.types false in attribute [-simp] homDiagram_obj in /-- Auxiliary definition: the cone over the limit category. -/ @[simps] @@ -125,6 +126,7 @@ def limitConeLift (F : J ⥤ Cat.{v, v}) (s : Cone F) : s.pt ⟶ limitConeX F := rw [Functor.congr_hom this f] simp } +set_option backward.isDefEq.respectTransparency.types false in theorem limit_π_homDiagram_eqToHom {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) (j : J) (h : X = Y) : limit.π (homDiagram X Y) j (eqToHom h) = @@ -160,6 +162,7 @@ instance : HasLimits Cat.{v, v} where has_limits_of_shape _ := { has_limit := fun F => ⟨⟨⟨HasLimits.limitCone F, HasLimits.limitConeIsLimit F⟩⟩⟩ } +set_option backward.isDefEq.respectTransparency.types false in instance : PreservesLimits Cat.objects.{v, v} where preservesLimitsOfShape := { preservesLimit := fun {F} => diff --git a/Mathlib/CategoryTheory/Category/Factorisation.lean b/Mathlib/CategoryTheory/Category/Factorisation.lean index 66f0470aeb0784..85aa1852e7eb92 100644 --- a/Mathlib/CategoryTheory/Category/Factorisation.lean +++ b/Mathlib/CategoryTheory/Category/Factorisation.lean @@ -86,6 +86,7 @@ protected def initialHom (d : Factorisation f) : Factorisation.Hom (Factorisation.initial : Factorisation f) d where h := d.ι +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Unique ((Factorisation.initial : Factorisation f) ⟶ d) where default := Factorisation.initialHom d @@ -105,6 +106,7 @@ protected def terminalHom (d : Factorisation f) : Factorisation.Hom d (Factorisation.terminal : Factorisation f) where h := d.π +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Unique (d ⟶ (Factorisation.terminal : Factorisation f)) where default := Factorisation.terminalHom d diff --git a/Mathlib/CategoryTheory/Category/KleisliCat.lean b/Mathlib/CategoryTheory/Category/KleisliCat.lean index f33b82e8203ecc..2c183c5f786b5f 100644 --- a/Mathlib/CategoryTheory/Category/KleisliCat.lean +++ b/Mathlib/CategoryTheory/Category/KleisliCat.lean @@ -48,6 +48,7 @@ instance KleisliCat.categoryStruct {m} [Monad.{u, v} m] : theorem KleisliCat.ext {m} [Monad.{u, v} m] (α β : KleisliCat m) (f g : α ⟶ β) (h : ∀ x, f x = g x) : f = g := funext h +set_option backward.isDefEq.respectTransparency false in instance KleisliCat.category {m} [Monad.{u, v} m] [LawfulMonad m] : Category (KleisliCat m) := by refine { id_comp := ?_, comp_id := ?_, assoc := ?_ } <;> intros <;> ext <;> diff --git a/Mathlib/CategoryTheory/Category/PartialFun.lean b/Mathlib/CategoryTheory/Category/PartialFun.lean index d544ff514b4e8e..32d4750ef2b00f 100644 --- a/Mathlib/CategoryTheory/Category/PartialFun.lean +++ b/Mathlib/CategoryTheory/Category/PartialFun.lean @@ -50,11 +50,13 @@ instance : Inhabited PartialFun.{u} := ⟨PartialFun.of PUnit⟩ -- TODO: wrap morphisms in this category into a one-field `PFun.Hom` structure +set_option backward.isDefEq.respectTransparency.types false in instance largeCategory : LargeCategory.{u} PartialFun where Hom X Y := PFun X Y id X := PFun.id X comp f g := g.comp f +set_option backward.isDefEq.respectTransparency.types false in /-- Constructs a partial function isomorphism between types from an equivalence between them. -/ @[simps] def Iso.mk {α β : PartialFun.{u}} (e : α ≃ β) : α ≅ β where @@ -69,12 +71,14 @@ def Iso.mk {α β : PartialFun.{u}} (e : α ≃ β) : α ≅ β where end PartialFun +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from `Type` to `PartialFun` which forgets that the maps are total. -/ def typeToPartialFun : Type u ⥤ PartialFun where obj := id map f := PFun.lift (f : _ → _) map_comp _ _ := PFun.coe_comp _ _ +set_option backward.isDefEq.respectTransparency.types false in instance : typeToPartialFun.Faithful where map_injective h := by ext x diff --git a/Mathlib/CategoryTheory/Category/Quiv.lean b/Mathlib/CategoryTheory/Category/Quiv.lean index 0cdcf0680ed8c8..6a596cc8c720c2 100644 --- a/Mathlib/CategoryTheory/Category/Quiv.lean +++ b/Mathlib/CategoryTheory/Category/Quiv.lean @@ -85,6 +85,7 @@ def freeMap {V W : Type*} [Quiver V] [Quiver W] (F : V ⥤q W) : Paths V ⥤ Pat map := F.mapPath map_comp f g := F.mapPath_comp f g +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `free : Quiv ⥤ Cat` preserves identities up to natural isomorphism and in fact up to equality. -/ @@ -92,10 +93,12 @@ to equality. -/ def freeMapIdIso (V : Type*) [Quiver V] : freeMap (𝟭q V) ≅ 𝟭 _ := NatIso.ofComponents (fun _ ↦ Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in theorem freeMap_id (V : Type*) [Quiver V] : freeMap (𝟭q V) = 𝟭 _ := Functor.ext_of_iso (freeMapIdIso V) (fun _ ↦ rfl) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `free : Quiv ⥤ Cat` preserves composition up to natural isomorphism and in fact up to equality. -/ @@ -107,6 +110,7 @@ def freeMapCompIso {V₁ : Type u₁} {V₂ : Type u₂} {V₃ : Type u₃} dsimp simp only [Category.comp_id, Category.id_comp, Prefunctor.mapPath_comp_apply]) +set_option backward.isDefEq.respectTransparency.types false in theorem freeMap_comp {V₁ : Type u₁} {V₂ : Type u₂} {V₃ : Type u₃} [Quiver.{v₁} V₁] [Quiver.{v₂} V₂] [Quiver.{v₃} V₃] (F : V₁ ⥤q V₂) (G : V₂ ⥤q V₃) : @@ -199,6 +203,7 @@ def lift {V : Type u} [Quiver.{v} V] {C : Type u₁} [Category.{v₁} C] obj X := F.obj X map f := composePath (F.mapPath f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Naturality of `pathComposition`. -/ def pathCompositionNaturality {C : Type u} {D : Type u₁} @@ -206,6 +211,7 @@ def pathCompositionNaturality {C : Type u} {D : Type u₁} Cat.freeMap (F.toPrefunctor) ⋙ pathComposition D ≅ pathComposition C ⋙ F := Paths.liftNatIso (fun _ ↦ Iso.refl _) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Naturality of `pathComposition`, which defines a natural transformation `Quiv.forget ⋙ Cat.free ⟶ 𝟭 _`. -/ @@ -220,12 +226,14 @@ lemma pathsOf_freeMap_toPrefunctor {V : Type u} {W : Type u₁} [Quiver.{v} V] [Quiver.{v₁} W] (F : V ⥤q W) : Paths.of V ⋙q (Cat.freeMap F).toPrefunctor = F ⋙q Paths.of W := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The left triangle identity of `Cat.free ⊣ Quiv.forget` as a natural isomorphism -/ def freeMapPathsOfCompPathCompositionIso (V : Type u) [Quiver.{v} V] : Cat.freeMap (Paths.of V) ⋙ pathComposition (Paths V) ≅ 𝟭 (Paths V) := Paths.liftNatIso (fun v ↦ Iso.refl _) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma freeMap_pathsOf_pathComposition (V : Type u) [Quiver.{v} V] : Cat.freeMap (Paths.of (V := V)) ⋙ pathComposition (Paths V) = 𝟭 (Paths V) := diff --git a/Mathlib/CategoryTheory/Category/ReflQuiv.lean b/Mathlib/CategoryTheory/Category/ReflQuiv.lean index 649de3f73a0344..e820d6675d47d7 100644 --- a/Mathlib/CategoryTheory/Category/ReflQuiv.lean +++ b/Mathlib/CategoryTheory/Category/ReflQuiv.lean @@ -150,6 +150,7 @@ namespace FreeRefl variable {V} +set_option backward.isDefEq.respectTransparency.types false in instance : Category (FreeRefl V) := inferInstanceAs (Category (Quotient _)) @@ -239,6 +240,7 @@ section variable {D : Type*} [Category* D] (F : V ⥤rq D) +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for functors from `FreeRefl`. (See also `lift'` for which the data is unbundled.) -/ def lift : FreeRefl V ⥤ D := @@ -246,9 +248,11 @@ def lift : FreeRefl V ⥤ D := rintro _ _ _ _ ⟨h⟩ simp) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_obj (v : V) : (lift F).obj (mk v) = F.obj v := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_map {v w : V} (f : v ⟶ w) : (lift F).map (homMk f) = F.map f := Category.id_comp _ @@ -261,15 +265,18 @@ variable {D : Type*} [Category* D] (obj : V → D) (map : ∀ {v w : V}, (v ⟶ w) → (obj v ⟶ obj w)) (map_id : ∀ (v : V), map (𝟙rq v) = 𝟙 _) +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for functors from `FreeRefl`. (See also `lift` for which the data is bundled.) -/ def lift' : FreeRefl V ⥤ D := lift { obj := obj, map := map, map_id := map_id } +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift'_obj (v : V) : (lift' obj map map_id).obj (mk v) = obj v := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift'_map {v w : V} (f : v ⟶ w) : (lift' obj map map_id).map (homMk f) = map f := by @@ -295,9 +302,11 @@ lemma quotientFunctor_map_id (V) [ReflQuiver V] (X : V) : (FreeRefl.quotientFunctor V).map (𝟙rq X).toPath = 𝟙 _ := Quotient.sound _ .mk +set_option backward.isDefEq.respectTransparency.types false in instance (V : Type*) [ReflQuiver V] [Unique V] : Unique (FreeRefl V) := inferInstanceAs (Unique (Quotient _)) +set_option backward.isDefEq.respectTransparency.types false in instance (V : Type*) [ReflQuiver V] [Unique V] [∀ (x y : V), Unique (x ⟶ y)] (x y : FreeRefl V) : Unique (x ⟶ y) where @@ -327,6 +336,7 @@ def toFreeRefl : V ⥤rq FreeRefl V where obj := .mk map := FreeRefl.homMk +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.toReflPrefunctor in variable {V} in @@ -336,19 +346,23 @@ lemma FreeRefl.lift_spec {D : Type*} [Category* D] (F : V ⥤rq D) : ReflPrefunctor.ext (fun v ↦ by simp) (by simp) variable {V} {W : Type*} [ReflQuiver W] (F : V ⥤rq W) +set_option backward.isDefEq.respectTransparency.types false in /-- A refl prefunctor `V ⥤rq W` induces a functor `FreeRefl V ⥤ FreeRefl W` defined using `freeMap` and the quotient functor. -/ def freeReflMap : FreeRefl V ⥤ FreeRefl W := FreeRefl.lift' (fun v ↦ .mk (F.obj v)) (fun f ↦ FreeRefl.homMk (F.map f)) (fun v ↦ by simp) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma freeReflMap_obj (v : V) : (freeReflMap F).obj (.mk v) = .mk (F.obj v) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma freeReflMap_map {v w : V} (f : v ⟶ w) : (freeReflMap F).map (FreeRefl.homMk f) = FreeRefl.homMk (F.map f) := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem freeReflMap_naturality {V W : Type*} [ReflQuiver.{v₁} V] [ReflQuiver.{v₂} W] (F : V ⥤rq W) : FreeRefl.quotientFunctor V ⋙ freeReflMap F = @@ -366,6 +380,7 @@ def freeRefl : ReflQuiv.{v, u} ⥤ Cat.{max u v, u} where map_id X := by ext1; exact FreeRefl.functor_ext (by simp) (by simp) map_comp {X Y Z} f g := by ext1; exact FreeRefl.functor_ext (by simp) (by simp) +set_option backward.isDefEq.respectTransparency.types false in /-- We will make use of the natural quotient map from the free category on the underlying quiver of a refl quiver to the free category on the reflexive quiver. -/ def freeReflNatTrans : ReflQuiv.forgetToQuiv ⋙ Cat.free ⟶ freeRefl where @@ -376,7 +391,7 @@ def freeReflNatTrans : ReflQuiv.forgetToQuiv ⋙ Cat.free ⟶ freeRefl where end Cat namespace ReflQuiv -open Category Functor +open Category namespace adj diff --git a/Mathlib/CategoryTheory/Category/RelCat.lean b/Mathlib/CategoryTheory/Category/RelCat.lean index 72c463e23550e3..e5452fe7af7df8 100644 --- a/Mathlib/CategoryTheory/Category/RelCat.lean +++ b/Mathlib/CategoryTheory/Category/RelCat.lean @@ -46,6 +46,7 @@ structure Hom (X Y : RelCat.{u}) : Type u where initialize_simps_projections Hom (as_prefix rel) +set_option backward.isDefEq.respectTransparency.types false in /-- The category of types with binary relations as morphisms. -/ instance instLargeCategory : LargeCategory RelCat where Hom := Hom @@ -54,18 +55,24 @@ instance instLargeCategory : LargeCategory RelCat where namespace Hom +set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma ext (f g : X ⟶ Y) (h : f.rel = g.rel) : f = g := by cases f; cases g; congr +set_option backward.isDefEq.respectTransparency.types false in @[simp] protected lemma rel_id (X : RelCat.{u}) : rel (𝟙 X) = .id := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] protected lemma rel_comp (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).rel = f.rel.comp g.rel := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem rel_id_apply₂ (x y : X) : x ~[rel (𝟙 X)] y ↔ x = y := .rfl +set_option backward.isDefEq.respectTransparency.types false in theorem rel_comp_apply₂ (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) (z : Z) : x ~[(f ≫ g).rel] z ↔ ∃ y, x ~[f.rel] y ∧ y ~[g.rel] z := .rfl end Hom +set_option backward.isDefEq.respectTransparency.types false in /-- The essentially surjective faithful embedding from the category of types and functions into the category of types and relations. -/ @[simps obj map_rel] @@ -73,11 +80,13 @@ def graphFunctor : Type u ⥤ RelCat.{u} where obj X := X map f := .ofRel (f : _ → _).graph +set_option backward.isDefEq.respectTransparency.types false in instance graphFunctor_faithful : graphFunctor.Faithful where map_injective h := by ext simp [Function.graph_injective congr(($h).rel)] +set_option backward.isDefEq.respectTransparency.types false in instance graphFunctor_essSurj : graphFunctor.EssSurj := graphFunctor.essSurj_of_surj Function.surjective_id @@ -111,19 +120,23 @@ theorem rel_iso_iff {X Y : RelCat} (r : X ⟶ Y) : section Opposite open Opposite +set_option backward.isDefEq.respectTransparency.types false in /-- The argument-swap isomorphism from `RelCat` to its opposite. -/ def opFunctor : RelCat ⥤ RelCatᵒᵖ where obj X := op X map {_ _} r := .op <| .ofRel r.rel.inv +set_option backward.isDefEq.respectTransparency.types false in /-- The other direction of `opFunctor`. -/ def unopFunctor : RelCatᵒᵖ ⥤ RelCat where obj X := unop X map {_ _} r := .ofRel r.unop.rel.inv +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem opFunctor_comp_unopFunctor_eq : Functor.comp opFunctor unopFunctor = Functor.id _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem unopFunctor_comp_opFunctor_eq : Functor.comp unopFunctor opFunctor = Functor.id _ := rfl @@ -137,10 +150,12 @@ def opEquivalence : RelCat ≌ RelCatᵒᵖ where unitIso := Iso.refl _ counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in instance : opFunctor.IsEquivalence := by change opEquivalence.functor.IsEquivalence infer_instance +set_option backward.isDefEq.respectTransparency.types false in instance : unopFunctor.IsEquivalence := by change opEquivalence.inverse.IsEquivalence infer_instance diff --git a/Mathlib/CategoryTheory/Category/TwoP.lean b/Mathlib/CategoryTheory/Category/TwoP.lean index 73b90dfe53bed5..4dafafe70a39b8 100644 --- a/Mathlib/CategoryTheory/Category/TwoP.lean +++ b/Mathlib/CategoryTheory/Category/TwoP.lean @@ -65,10 +65,12 @@ theorem coe_toBipointed (X : TwoP) : ↥X.toBipointed = ↥X := noncomputable instance largeCategory : LargeCategory TwoP := inferInstanceAs <| Category (InducedCategory _ toBipointed) +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance concreteCategory : ConcreteCategory TwoP (fun X Y => Bipointed.HomSubtype X.toBipointed Y.toBipointed) := inferInstanceAs <| ConcreteCategory (InducedCategory _ toBipointed) _ +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance hasForgetToBipointed : HasForget₂ TwoP Bipointed := inferInstanceAs <| HasForget₂ (InducedCategory _ toBipointed) _ @@ -86,6 +88,9 @@ noncomputable def swap : TwoP ⥤ TwoP where map_fst := f.hom.map_snd map_snd := f.hom.map_fst } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence between `TwoP` and itself induced by `Prod.swap` both ways. -/ @[simps!] noncomputable def swapEquiv : TwoP ≌ TwoP where @@ -100,6 +105,7 @@ theorem swapEquiv_symm : swapEquiv.symm = swapEquiv := end TwoP +set_option backward.isDefEq.respectTransparency.types false in @[simp, nolint simpNF] -- mathlib builds without this simp attribute theorem TwoP_swap_comp_forget_to_Bipointed : TwoP.swap ⋙ forget₂ TwoP Bipointed = forget₂ TwoP Bipointed ⋙ Bipointed.swap := @@ -131,16 +137,19 @@ theorem pointedToTwoPFst_comp_swap : pointedToTwoPFst ⋙ TwoP.swap = pointedToT theorem pointedToTwoPSnd_comp_swap : pointedToTwoPSnd ⋙ TwoP.swap = pointedToTwoPFst := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp, nolint simpNF] -- mathlib builds without this simp attribute theorem pointedToTwoPFst_comp_forget_to_bipointed : pointedToTwoPFst ⋙ forget₂ TwoP Bipointed = pointedToBipointedFst := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp, nolint simpNF] -- mathlib builds without this simp attribute theorem pointedToTwoPSnd_comp_forget_to_bipointed : pointedToTwoPSnd ⋙ forget₂ TwoP Bipointed = pointedToBipointedSnd := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Adding a second point is left adjoint to forgetting the second point. -/ noncomputable def pointedToTwoPFstForgetCompBipointedToPointedFstAdjunction : pointedToTwoPFst ⊣ forget₂ TwoP Bipointed ⋙ bipointedToPointedFst := @@ -154,6 +163,7 @@ noncomputable def pointedToTwoPFstForgetCompBipointedToPointedFstAdjunction : · rfl } homEquiv_naturality_left_symm := fun f g => by ext (_ | _) : 4 <;> rfl } +set_option backward.isDefEq.respectTransparency.types false in /-- Adding a first point is left adjoint to forgetting the first point. -/ noncomputable def pointedToTwoPSndForgetCompBipointedToPointedSndAdjunction : pointedToTwoPSnd ⊣ forget₂ TwoP Bipointed ⋙ bipointedToPointedSnd := diff --git a/Mathlib/CategoryTheory/Category/ULift.lean b/Mathlib/CategoryTheory/Category/ULift.lean index f8aa46c9974cb4..b4ced550df606f 100644 --- a/Mathlib/CategoryTheory/Category/ULift.lean +++ b/Mathlib/CategoryTheory/Category/ULift.lean @@ -125,6 +125,7 @@ def ULiftHom.down : ULiftHom C ⥤ C where obj := ULiftHom.objDown map f := f.down +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence between `C` and `ULiftHom C`. -/ def ULiftHom.equiv : C ≌ ULiftHom C where diff --git a/Mathlib/CategoryTheory/Center/Linear.lean b/Mathlib/CategoryTheory/Center/Linear.lean index efebe39a3869c2..0608254d424364 100644 --- a/Mathlib/CategoryTheory/Center/Linear.lean +++ b/Mathlib/CategoryTheory/Center/Linear.lean @@ -53,7 +53,7 @@ variable (φ : R →+* CatCenter C) (X Y : C) /-- The scalar multiplication by `R` on the type `X ⟶ Y` of morphisms in a category `C` equipped with a ring morphism `R →+* CatCenter C`. -/ -@[implicit_reducible] +@[instance_reducible] def smulOfRingMorphism : SMul R (X ⟶ Y) where smul a f := (φ a).app X ≫ f @@ -75,7 +75,7 @@ variable (X Y) set_option backward.isDefEq.respectTransparency false in /-- The `R`-module structure on the type `X ⟶ Y` of morphisms in a category `C` equipped with a ring morphism `R →+* CatCenter C`. -/ -@[implicit_reducible] +@[instance_reducible] def homModuleOfRingMorphism : Module R (X ⟶ Y) := by letI := smulOfRingMorphism φ X Y exact @@ -97,7 +97,7 @@ def homModuleOfRingMorphism : Module R (X ⟶ Y) := by /-- The `R`-linear structure on a preadditive category `C` equipped with a ring morphism `R →+* CatCenter C`. -/ -@[implicit_reducible] +@[instance_reducible] def ofRingMorphism : Linear R C := by letI := homModuleOfRingMorphism φ exact diff --git a/Mathlib/CategoryTheory/CofilteredSystem.lean b/Mathlib/CategoryTheory/CofilteredSystem.lean index f6e31d4a2d6347..f3e071edeab660 100644 --- a/Mathlib/CategoryTheory/CofilteredSystem.lean +++ b/Mathlib/CategoryTheory/CofilteredSystem.lean @@ -94,7 +94,7 @@ theorem nonempty_sections_of_finite_cofiltered_system {J : Type u} [Category.{w} use fun j => (u ⟨j⟩).down intro j j' f have h := @hu (⟨j⟩ : J') (⟨j'⟩ : J') (ULift.up f) - simp only [F', down, AsSmall.down, Functor.comp_map, uliftFunctor_map] at h + simp only [F', down, AsSmall.down] at h simp_rw [← h] rfl @@ -307,6 +307,7 @@ variable [∀ j : J, Nonempty (F.obj j)] [∀ j : J, Finite (F.obj j)] (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)) include Fsur +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem eval_section_surjective_of_surjective (i : J) : (fun s : F.sections => s.val i).Surjective := fun x => by diff --git a/Mathlib/CategoryTheory/Comma/Arrow.lean b/Mathlib/CategoryTheory/Comma/Arrow.lean index 5ea218a8f31358..427bbfe7da06cb 100644 --- a/Mathlib/CategoryTheory/Comma/Arrow.lean +++ b/Mathlib/CategoryTheory/Comma/Arrow.lean @@ -72,7 +72,7 @@ theorem comp_left {X Y Z : Arrow T} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).left = f.left ≫ g.left := rfl /-- An object in the arrow category is simply a morphism in `T`. -/ -@[simps, to_dual self] +@[simps, to_dual self, implicit_reducible] def mk {X Y : T} (f : X ⟶ Y) : Arrow T where left := X right := Y @@ -147,12 +147,14 @@ lemma ext {f g : Arrow T} (h₃ : f.hom = eqToHom h₁ ≫ g.hom ≫ eqToHom h₂.symm) : f = g := (mk_eq_mk_iff _ _).2 (by simp_all) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma arrow_mk_comp_eqToHom {X Y Y' : T} (f : X ⟶ Y) (h : Y = Y') : Arrow.mk (f ≫ eqToHom h) = Arrow.mk f := ext rfl h.symm (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma arrow_mk_eqToHom_comp {X' X Y : T} (f : X ⟶ Y) (h : X' = X) : @@ -286,6 +288,7 @@ theorem left_hom_inv_right [IsIso sq] : sq.left ≫ g.hom ≫ inv sq.right = f.h theorem inv_left_hom_right [IsIso sq] : inv sq.left ≫ f.hom ≫ sq.right = g.hom := by simp only [w, IsIso.inv_comp_eq] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[to_dual epi_right] instance mono_left [Mono sq] : Mono sq.left where @@ -311,6 +314,7 @@ lemma inv_hom_id_left (e : f ≅ g) : e.inv.left ≫ e.hom.left = 𝟙 _ := by end +set_option backward.isDefEq.respectTransparency.types false in /-- Given a square from an arrow `i` to an isomorphism `p`, express the source part of `sq` in terms of the inverse of `p`. -/ @[simp] @@ -318,14 +322,16 @@ theorem square_to_iso_invert (i : Arrow T) {X Y : T} (p : X ≅ Y) (sq : i ⟶ A i.hom ≫ sq.right ≫ p.inv = sq.left := by simpa only [mk_right, Category.assoc] using! (Iso.comp_inv_eq p).mpr (Arrow.w_mk_right sq).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Given a square from an isomorphism `i` to an arrow `p`, express the target part of `sq` in terms of the inverse of `i`. -/ theorem square_from_iso_invert {X Y : T} (i : X ≅ Y) (p : Arrow T) (sq : Arrow.mk i.hom ⟶ p) : i.inv ≫ sq.left ≫ p.hom = sq.right := by - simp [Arrow.w_mk_left] + simp variable {C : Type u} [Category.{v} C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A helper construction: given a square between `i` and `f ≫ g`, produce a square between `i` and `g`, whose top leg uses `f`: @@ -347,6 +353,7 @@ def squareToSnd {X Y Z : C} {i : Arrow C} {f : X ⟶ Y} {g : Y ⟶ Z} (sq : i def leftFunc : Arrow C ⥤ C := Comma.fst _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural transformation from `leftFunc` to `rightFunc`, given by the arrow itself. -/ @[simps] @@ -371,6 +378,7 @@ attribute [to_dual self (reorder := X Y)] mapArrow_map variable (C D) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `(C ⥤ D) ⥤ (Arrow C ⥤ Arrow D)` which sends a functor `F : C ⥤ D` to `F.mapArrow`. -/ @@ -383,6 +391,7 @@ attribute [to_dual self (reorder := X Y)] mapArrowFunctor_map_app variable {C D} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories `Arrow C ≌ Arrow D` induced by an equivalence `C ≌ D`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index 91525e9f3baeb6..70748bb0d45d38 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -157,7 +157,7 @@ variable (L) (R) set_option linter.translate.warnInvalid false in /-- The functor sending an object `X` in the comma category to `X.left`. -/ -@[to_dual (reorder := L R) (attr := simps) +@[to_dual (reorder := L R) (attr := simps, implicit_reducible) /-- The functor sending an object `X` in the comma category to `X.right`. -/] def fst : Comma L R ⥤ A where obj X := X.left @@ -242,10 +242,10 @@ variable {L' : A' ⥤ T'} {R' : B' ⥤ T'} {F₁ : A ⥤ A'} {F₂ : B ⥤ B'} {F : T ⥤ T'} (α : F₁ ⋙ L' ⟶ L ⋙ F) (β : R ⋙ F ⟶ F₂ ⋙ R') -set_option backward.isDefEq.respectTransparency false in /-- The functor `Comma L R ⥤ Comma L' R'` induced by three functors `F₁`, `F₂`, `F` and two natural transformations `F₁ ⋙ L' ⟶ L ⋙ F` and `R ⋙ F ⟶ F₂ ⋙ R'`. -/ -@[simps, to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β)] +@[simps, implicit_reducible, + to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β)] def map : Comma L R ⥤ Comma L' R' where obj X := { left := F₁.obj X.left @@ -335,7 +335,7 @@ end set_option linter.translate.warnInvalid false in /-- A natural transformation `L₁ ⟶ L₂` induces a functor `Comma L₂ R ⥤ Comma L₁ R`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := simps, implicit_reducible) /-- A natural transformation `R₁ ⟶ R₂` induces a functor `Comma L R₁ ⥤ Comma L R₂`. -/] def mapLeft (l : L₁ ⟶ L₂) : Comma L₂ R ⥤ Comma L₁ R where obj X := @@ -349,6 +349,7 @@ def mapLeft (l : L₁ ⟶ L₂) : Comma L₂ R ⥤ Comma L₁ R where attribute [to_dual existing] mapLeft_map_left attribute [to_dual existing] mapLeft_map_right +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- The functor `Comma L R ⥤ Comma L R` induced by the identity natural transformation on `L` is @@ -359,6 +360,7 @@ naturally isomorphic to the identity functor. -/] def mapLeftId : mapLeft R (𝟙 L) ≅ 𝟭 _ := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- The functor `Comma L₁ R ⥤ Comma L₃ R` induced by the composition of two natural transformations @@ -381,11 +383,12 @@ set_option linter.translate.warnInvalid false in def mapLeftEq (l l' : L₁ ⟶ L₂) (h : l = l') : mapLeft R l ≅ mapLeft R l' := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- A natural isomorphism `L₁ ≅ L₂` induces an equivalence of categories `Comma L₁ R ≌ Comma L₂ R`. -/ -@[to_dual (attr := simps!) +@[to_dual (attr := simps!, implicit_reducible) /-- A natural isomorphism `R₁ ≅ R₂` induces an equivalence of categories `Comma L R₁ ≌ Comma L R₂`. -/] def mapLeftIso (i : L₁ ≅ L₂) : Comma L₁ R ≌ Comma L₂ R where @@ -402,7 +405,8 @@ variable {C : Type u₄} [Category.{v₄} C] set_option linter.translate.warnInvalid false in /-- The functor `(F ⋙ L, R) ⥤ (L, R)` -/ -@[to_dual (attr := simps) (reorder := F L R) /-- The functor `(L, F ⋙ R) ⥤ (L, R)` -/] +@[to_dual (attr := simps, + implicit_reducible) (reorder := F L R) /-- The functor `(L, F ⋙ R) ⥤ (L, R)` -/] def preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : Comma (F ⋙ L) R ⥤ Comma L R where obj X := { left := F.obj X.left @@ -413,6 +417,7 @@ def preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : Comma (F ⋙ L) R ⥤ Co right := f.right w := by simpa using! f.w } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Comma.preLeft` is a particular case of `Comma.map`, but with better definitional properties. -/ @@ -456,6 +461,7 @@ def post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : Comma L R ⥤ Comma (L ⋙ attribute [to_dual existing] post_obj_left attribute [to_dual self] post_obj_hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Comma.post` is a particular case of `Comma.map`, but with better definitional properties. -/ @[to_dual self] @@ -493,6 +499,7 @@ def fromProd (L : A ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : { left := f.1 right := f.2 } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Taking the comma category of two functors into `Discrete PUnit` results in something is equivalent to their product. -/ @@ -504,24 +511,28 @@ def equivProd (L : A ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : unitIso := Iso.refl _ counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- Taking the comma category of a functor into `A ⥤ Discrete PUnit` and the identity `Discrete PUnit ⥤ Discrete PUnit` results in a category equivalent to `A`. -/ def toPUnitIdEquiv (L : A ⥤ Discrete PUnit) (R : Discrete PUnit ⥤ Discrete PUnit) : Comma L R ≌ A := (equivProd L _).trans (prod.rightUnitorEquivalence A) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toPUnitIdEquiv_functor_iso {L : A ⥤ Discrete PUnit} {R : Discrete PUnit ⥤ Discrete PUnit} : (toPUnitIdEquiv L R).functor = fst L R := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Taking the comma category of the identity `Discrete PUnit ⥤ Discrete PUnit` and a functor `B ⥤ Discrete PUnit` results in a category equivalent to `B`. -/ def toIdPUnitEquiv (L : Discrete PUnit ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : Comma L R ≌ B := (equivProd _ R).trans (prod.leftUnitorEquivalence B) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toIdPUnitEquiv_functor_iso {L : Discrete PUnit ⥤ Discrete PUnit} {R : B ⥤ Discrete PUnit} : diff --git a/Mathlib/CategoryTheory/Comma/CardinalArrow.lean b/Mathlib/CategoryTheory/Comma/CardinalArrow.lean index b1f67c4c554b52..27f8412c6ab65a 100644 --- a/Mathlib/CategoryTheory/Comma/CardinalArrow.lean +++ b/Mathlib/CategoryTheory/Comma/CardinalArrow.lean @@ -86,6 +86,7 @@ noncomputable def Arrow.shrinkHomsEquiv (C : Type u) [Category.{v} C] [LocallySm left_inv _ := by simp right_inv _ := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The bijection `Arrow (Shrink C) ≃ Arrow C`. -/ noncomputable def Arrow.shrinkEquiv (C : Type u) [Category.{v} C] [Small.{w} C] : diff --git a/Mathlib/CategoryTheory/Comma/Final.lean b/Mathlib/CategoryTheory/Comma/Final.lean index c1c46db052aa44..90335c5ada1754 100644 --- a/Mathlib/CategoryTheory/Comma/Final.lean +++ b/Mathlib/CategoryTheory/Comma/Final.lean @@ -35,7 +35,7 @@ namespace CategoryTheory namespace Comma -open Limits Functor CostructuredArrow +open Limits CategoryTheory.Functor CostructuredArrow variable {A : Type u₁} [Category.{v₁} A] variable {B : Type u₂} [Category.{v₂} B] @@ -190,6 +190,7 @@ lemma isCofiltered_of_initial [IsCofiltered A] [IsCofiltered B] [L.Initial] : have := L.initial_iff_isCofiltered_costructuredArrow.mp inferInstance exact isCofiltered_of_isCofiltered_costructuredArrow L R +set_option backward.isDefEq.respectTransparency.types false in /-- Let `A` and `B` be filtered categories, `R : B ⥤ T` be final and `R : A ⥤ T`. Then, the projection `snd L R : Comma L R ⥤ B` is final. -/ instance final_snd [IsFiltered A] [IsFiltered B] [R.Final] : (snd L R).Final := by diff --git a/Mathlib/CategoryTheory/Comma/Over/Basic.lean b/Mathlib/CategoryTheory/Comma/Over/Basic.lean index 930b487f42e385..ade71fe2cc76df 100644 --- a/Mathlib/CategoryTheory/Comma/Over/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Over/Basic.lean @@ -35,7 +35,7 @@ variable {D : Type u₂} [Category.{v₂} D] /-- The over category has as objects arrows in `T` with codomain `X` and as morphisms commutative triangles. -/ -@[stacks 001G] +@[stacks 001G, implicit_reducible] def Over (X : T) := CostructuredArrow (𝟭 T) X @@ -95,7 +95,7 @@ theorem comp_left (a b c : Over X) (f : a ⟶ b) (g : b ⟶ c) : (f ≫ g).left rfl /-- To give an object in the over category, it suffices to give a morphism with codomain `X`. -/ -@[simps! left hom] +@[simps! left hom, implicit_reducible] def mk {X Y : T} (f : Y ⟶ X) : Over X := CostructuredArrow.mk f @@ -195,7 +195,7 @@ def forgetCocone (X : T) : Limits.Cocone (forget X) := ι := { app := Comma.hom } } /-- A morphism `f : X ⟶ Y` induces a functor `Over X ⥤ Over Y` in the obvious way. -/ -@[stacks 001G] +@[stacks 001G, implicit_reducible] def map {Y : T} (f : X ⟶ Y) : Over X ⥤ Over Y := Comma.mapRight _ <| Discrete.natTrans fun _ => f @@ -239,11 +239,13 @@ better computational properties, when used, for instance, in developing the theory of Beck-Chevalley transformations. -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The natural isomorphism arising from `mapForget_eq`. -/ @[simps!] def mapId (Y : T) : map (𝟙 Y) ≅ 𝟭 _ := NatIso.ofComponents (fun _ ↦ isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Mapping by the identity morphism is just the identity functor. -/ theorem mapId_eq (Y : T) : map (𝟙 Y) = 𝟭 _ := @@ -258,6 +260,7 @@ theorem mapForget_eq {X Y : T} (f : X ⟶ Y) : def mapForget {X Y : T} (f : X ⟶ Y) : (map f) ⋙ (forget Y) ≅ (forget X) := eqToIso (mapForget_eq f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism arising from `mapComp_eq`. -/ @[simps!] @@ -265,6 +268,7 @@ def mapComp {X Y Z : T} (f : X ⟶ Y) (g : Y ⟶ Z) : map (f ≫ g) ≅ map f ⋙ map g := NatIso.ofComponents (fun _ ↦ isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Mapping by the composite morphism `f ≫ g` is the same as mapping by `f` then by `g`. -/ theorem mapComp_eq {X Y Z : T} (f : X ⟶ Y) (g : Y ⟶ Z) : @@ -273,12 +277,14 @@ theorem mapComp_eq {X Y Z : T} (f : X ⟶ Y) (g : Y ⟶ Z) : (fun _ ↦ by simp [map, Comma.mapRight]) (fun _ ↦ by ext; simp [eqToHom_left]) +set_option backward.isDefEq.respectTransparency.types false in /-- If `f = g`, then `map f` is naturally isomorphic to `map g`. -/ @[simps!] def mapCongr {X Y : T} (f g : X ⟶ Y) (h : f = g) : map f ≅ map g := NatIso.ofComponents (fun _ ↦ isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapCongr_rfl {X Y : T} (f : X ⟶ Y) : mapCongr f f rfl = Iso.refl _ := rfl @@ -369,6 +375,7 @@ theorem iteratedSliceBackward_forget (f : Over X) : iteratedSliceBackward f ⋙ Over.forget f = Over.map f.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given f : Y ⟶ X, we have an equivalence between (T/X)/f and T/Y -/ @[simps] @@ -394,6 +401,7 @@ def iteratedSliceForwardNaturalityIso {g : Over X} (p : f ⟶ g) : iteratedSliceForward f ⋙ Over.map p.left ≅ Over.map p ⋙ iteratedSliceForward g := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism relating the functor `Over.map p` to the functor `Over.map p.left`, mediated by the underlying functor of the iterated slice equivalence. @@ -424,6 +432,7 @@ lemma post_forget_eq_forget_comp (F : T ⥤ D) (X : T) : post F ⋙ forget (F.obj X) = forget X ⋙ F := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `post (F ⋙ G)` is isomorphic (actually equal) to `post F ⋙ post G`. -/ @[simps!] @@ -434,6 +443,7 @@ def postComp {E : Type*} [Category* E] (F : T ⥤ D) (G : D ⥤ E) : dsimp only [Iso.refl_hom, Over.comp_left, Over.id_left] simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural transformation `F ⟶ G` induces a natural transformation on `Over X` up to `Over.map`. -/ @@ -441,6 +451,7 @@ set_option backward.defeqAttrib.useBackward true in def postMap {F G : T ⥤ D} (e : F ⟶ G) : post F ⋙ map (e.app X) ⟶ post G where app Y := Over.homMk (e.app Y.left) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` and `G` are naturally isomorphic, then `Over.post F` and `Over.post G` are also naturally isomorphic up to `Over.map` -/ @@ -470,12 +481,14 @@ instance [F.Full] [F.EssSurj] : (Over.post (X := X) F).EssSurj where instance [F.IsEquivalence] : (Over.post (X := X) F).IsEquivalence where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` is fully faithful, then so is `Over.post F`. -/ def _root_.CategoryTheory.Functor.FullyFaithful.over (h : F.FullyFaithful) : (post (X := X) F).FullyFaithful where preimage {A B} f := Over.homMk (h.preimage f.left) <| h.map_injective (by simpa using Over.w f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `G` is a right adjoint, then so is `post G : Over Y ⥤ Over (G Y)`. @@ -497,6 +510,7 @@ instance isRightAdjoint_post {Y : D} {G : D ⥤ T} [G.IsRightAdjoint] : (post (X := Y) G).IsRightAdjoint := let ⟨F, ⟨a⟩⟩ := ‹G.IsRightAdjoint›; ⟨_, ⟨postAdjunctionRight a⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories induces an equivalence on over categories. -/ @[simps] @@ -515,6 +529,7 @@ def iteratedSliceForwardIsoPost (f : Over X) : open Limits +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {X} in /-- If `X : T` is terminal, then the over category of `X` is equivalent to `T`. -/ @@ -532,8 +547,9 @@ For the converse direction see `CategoryTheory.WithTerminal.commaFromOver`. -/ protected def lift {J : Type*} [Category* J] (D : J ⥤ T) {X : T} (s : D ⟶ (Functor.const J).obj X) : J ⥤ Over X where obj j := mk (s.app j) - map f := homMk (D.map f) (by simpa using s.naturality f) + map f := homMk (D.map f) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The induced cone on `Over X` on the lifted functor. -/ @[simps] @@ -543,6 +559,7 @@ def liftCone {J : Type*} [Category* J] (D : J ⥤ T) {X : T} (s : D ⟶ (Functor pt := mk p π.app j := homMk (c.π.app j) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The lifted cone on `Over X` is a limit cone if the original cone was limiting and `J` is nonempty. -/ @@ -564,6 +581,7 @@ def isLimitLiftCone {J : Type*} [Category* J] [Nonempty J] end Over +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restrict a cone to the diagram over `j`. This preserves being limiting if the forgetful functor @@ -602,6 +620,7 @@ namespace costructuredArrowToOverEquivalence variable (F : D ⥤ T) {X : T} (Y : Over X) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `costructuredArrowToOverEquivalence`. -/ @[simps] @@ -623,6 +642,7 @@ def inverse : CostructuredArrow F Y.left ⥤ CostructuredArrow (toOver F X) Y wh end costructuredArrowToOverEquivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A category of costructured arrows for a functor `toOver F X` identifies to a category of costructured arrows for `F`. -/ @@ -818,11 +838,13 @@ demonstrate, for instance, that under categories assemble into a functor `mapFunctor : Tᵒᵖ ⥤ Cat`. -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Mapping by the identity morphism is just the identity functor. -/ @[simps!] def mapId (Y : T) : map (𝟙 Y) ≅ 𝟭 _ := NatIso.ofComponents (fun _ ↦ isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Mapping by the identity morphism is just the identity functor. -/ theorem mapId_eq (Y : T) : map (𝟙 Y) = 𝟭 _ := @@ -837,6 +859,7 @@ theorem mapForget_eq {X Y : T} (f : X ⟶ Y) : def mapForget {X Y : T} (f : X ⟶ Y) : (map f) ⋙ (forget X) ≅ (forget Y) := eqToIso (mapForget_eq f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Mapping by the composite morphism `f ≫ g` is the same as mapping by `f` then by `g`. -/ theorem mapComp_eq {X Y Z : T} (f : X ⟶ Y) (g : Y ⟶ Z) : @@ -936,6 +959,7 @@ lemma post_forget_eq_forget_comp (F : T ⥤ D) (X : T) : post F ⋙ forget (F.obj X) = forget X ⋙ F := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `post (F ⋙ G)` is isomorphic (actually equal) to `post F ⋙ post G`. -/ @[simps!] @@ -946,6 +970,7 @@ def postComp {E : Type*} [Category* E] (F : T ⥤ D) (G : D ⥤ E) : dsimp only [Iso.refl_hom, Under.comp_right, Under.id_right] simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural transformation `F ⟶ G` induces a natural transformation on `Under X` up to `Under.map`. -/ @@ -953,6 +978,7 @@ set_option backward.defeqAttrib.useBackward true in def postMap {F G : T ⥤ D} (e : F ⟶ G) : post (X := X) F ⟶ post G ⋙ map (e.app X) where app Y := Under.homMk (e.app Y.right) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` and `G` are naturally isomorphic, then `Under.post F` and `Under.post G` are also naturally isomorphic up to `Under.map` -/ @@ -982,12 +1008,14 @@ instance [F.Full] [F.EssSurj] : (Under.post (X := X) F).EssSurj where instance [F.IsEquivalence] : (Under.post (X := X) F).IsEquivalence where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` is fully faithful, then so is `Under.post F`. -/ def _root_.CategoryTheory.Functor.FullyFaithful.under (h : F.FullyFaithful) : (post (X := X) F).FullyFaithful where preimage {A B} f := Under.homMk (h.preimage f.right) <| h.map_injective (by simpa using Under.w f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` is a left adjoint, then so is `post F : Under X ⥤ Under (F X)`. @@ -1014,6 +1042,7 @@ def postAdjunctionLeft {X : T} {F : T ⥤ D} {G : D ⥤ T} (a : F ⊣ G) : instance isLeftAdjoint_post [F.IsLeftAdjoint] : (post (X := X) F).IsLeftAdjoint := let ⟨G, ⟨a⟩⟩ := ‹F.IsLeftAdjoint›; ⟨_, ⟨postAdjunctionLeft a⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories induces an equivalence on under categories. -/ @[simps] @@ -1025,6 +1054,7 @@ def postEquiv (F : T ≌ D) : Under X ≌ Under (F.functor.obj X) where open Limits +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {X} in /-- If `X : T` is initial, then the under category of `X` is equivalent to `T`. -/ @@ -1043,6 +1073,7 @@ protected def lift {J : Type*} [Category* J] (D : J ⥤ T) {X : T} (s : (Functor obj j := .mk (s.app j) map f := Under.homMk (D.map f) (by simpa using (s.naturality f).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The induced cocone on `Under X` from on the lifted functor. -/ @[simps] @@ -1052,6 +1083,7 @@ def liftCocone {J : Type*} [Category* J] (D : J ⥤ T) {X : T} (s : (Functor.con pt := mk p ι.app j := homMk (c.ι.app j) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The lifted cocone on `Under X` is a colimit cocone if the original cocone was colimiting and `J` is nonempty. -/ @@ -1073,6 +1105,7 @@ def isColimitLiftCocone {J : Type*} [Category* J] [Nonempty J] end Under +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restrict a cocone to the diagram under `j`. This preserves being colimiting if the forgetful functor @@ -1182,6 +1215,7 @@ end Functor namespace StructuredArrow +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor from the structured arrow category on the projection functor for any structured arrow category. -/ @@ -1193,6 +1227,7 @@ def ofStructuredArrowProjEquivalence.functor (F : D ⥤ T) (Y : T) (X : D) : (fun g => by exact g.hom) (fun m => by have := m.w; cat_disch)) _ _ (fun f => f.right.hom) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor of `ofStructuredArrowProjEquivalence.functor`. -/ @[simps!] @@ -1203,6 +1238,7 @@ def ofStructuredArrowProjEquivalence.inverse (F : D ⥤ T) (Y : T) (X : D) : (fun g => by exact g.hom) (fun m => by have := m.w; cat_disch)) _ _ (fun f => f.right.hom) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Characterization of the structured arrow category on the projection functor of any structured arrow category. -/ @@ -1213,6 +1249,7 @@ def ofStructuredArrowProjEquivalence (F : D ⥤ T) (Y : T) (X : D) : unitIso := NatIso.ofComponents (fun _ => Iso.refl _) (by simp) counitIso := NatIso.ofComponents (fun _ => Iso.refl _) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical functor from the structured arrow category on the diagonal functor `T ⥤ T × T` to the structured arrow category on `Under.forget`. -/ @@ -1224,6 +1261,7 @@ def ofDiagEquivalence.functor (X : T × T) : (fun f ↦ f.hom.1) (fun g ↦ by simp [← w g])) _ _ (fun f ↦ f.hom.2) (fun g ↦ by simp [← w g]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor of `ofDiagEquivalence.functor`. -/ @[simps!] @@ -1232,6 +1270,7 @@ def ofDiagEquivalence.inverse (X : T × T) : Functor.toStructuredArrow (StructuredArrow.proj _ _ ⋙ Under.forget _) _ _ (fun f => (f.right.hom, f.hom)) (fun m => by have := m.w; cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Characterization of the structured arrow category on the diagonal functor `T ⥤ T × T`. -/ def ofDiagEquivalence (X : T × T) : @@ -1253,6 +1292,7 @@ section CommaFst variable {C : Type u₃} [Category.{v₃} C] (F : C ⥤ T) (G : D ⥤ T) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor used to define the equivalence `ofCommaSndEquivalence`. -/ @[simps] @@ -1269,6 +1309,7 @@ def ofCommaSndEquivalenceInverse (c : C) : Functor.toStructuredArrow (Comma.preLeft (Under.forget c) F G) _ _ (fun Y => Y.left.hom) (fun _ => by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- There is a canonical equivalence between the structured arrow category with domain `c` on the functor `Comma.fst F G : Comma F G ⥤ F` and the comma category over @@ -1287,6 +1328,7 @@ end StructuredArrow namespace CostructuredArrow +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor from the costructured arrow category on the projection functor for any costructured arrow category. -/ @@ -1298,6 +1340,7 @@ def ofCostructuredArrowProjEquivalence.functor (F : T ⥤ D) (Y : D) (X : T) : (fun g => by exact g.hom) (fun m => by have := m.w; cat_disch)) _ _ (fun f => f.left.hom) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor of `ofCostructuredArrowProjEquivalence.functor`. -/ @[simps!] @@ -1308,6 +1351,7 @@ def ofCostructuredArrowProjEquivalence.inverse (F : T ⥤ D) (Y : D) (X : T) : (fun g => by exact g.hom) (fun m => by have := m.w; cat_disch)) _ _ (fun f => f.left.hom) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Characterization of the costructured arrow category on the projection functor of any costructured arrow category. -/ @@ -1319,6 +1363,7 @@ def ofCostructuredArrowProjEquivalence (F : T ⥤ D) (Y : D) (X : T) : unitIso := NatIso.ofComponents (fun _ => Iso.refl _) (by simp) counitIso := NatIso.ofComponents (fun _ => Iso.refl _) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical functor from the costructured arrow category on the diagonal functor `T ⥤ T × T` to the costructured arrow category on `Under.forget`. -/ @@ -1331,6 +1376,7 @@ def ofDiagEquivalence.functor (X : T × T) : _ _ (fun f => f.hom.2) (fun m => by have := congrArg (·.2) m.w; cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor of `ofDiagEquivalence.functor`. -/ @[simps!] @@ -1339,6 +1385,7 @@ def ofDiagEquivalence.inverse (X : T × T) : Functor.toCostructuredArrow (CostructuredArrow.proj _ _ ⋙ Over.forget _) _ X (fun f => (f.left.hom, f.hom)) (fun m => by have := m.w; cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Characterization of the costructured arrow category on the diagonal functor `T ⥤ T × T`. -/ def ofDiagEquivalence (X : T × T) : @@ -1361,6 +1408,7 @@ section CommaFst variable {C : Type u₃} [Category.{v₃} C] (F : C ⥤ T) (G : D ⥤ T) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor used to define the equivalence `ofCommaFstEquivalence`. -/ @[simps] @@ -1377,6 +1425,7 @@ def ofCommaFstEquivalenceInverse (c : C) : Functor.toCostructuredArrow (Comma.preLeft (Over.forget c) F G) _ _ (fun Y => Y.left.hom) (fun _ => by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- There is a canonical equivalence between the costructured arrow category with codomain `c` on the functor `Comma.fst F G : Comma F G ⥤ F` and the comma category over diff --git a/Mathlib/CategoryTheory/Comma/Over/OverClass.lean b/Mathlib/CategoryTheory/Comma/Over/OverClass.lean index 0252308ec07e47..a3d88519658425 100644 --- a/Mathlib/CategoryTheory/Comma/Over/OverClass.lean +++ b/Mathlib/CategoryTheory/Comma/Over/OverClass.lean @@ -173,6 +173,7 @@ instance {f : X ⟶ Y} [IsIso f] [HomIsOver f S] : HomIsOver (inv f) S where end OverClass +set_option backward.isDefEq.respectTransparency.types false in /-- Reinterpret an isomorphism over an object `S` into an isomorphism in the category over `S`. -/ @[simps] def Iso.asOver (e : X ≅ Y) [HomIsOver e.hom S] : OverClass.asOver X S ≅ OverClass.asOver Y S where diff --git a/Mathlib/CategoryTheory/Comma/Over/Pullback.lean b/Mathlib/CategoryTheory/Comma/Over/Pullback.lean index 45e64ac8d25c1c..295637b7548964 100644 --- a/Mathlib/CategoryTheory/Comma/Over/Pullback.lean +++ b/Mathlib/CategoryTheory/Comma/Over/Pullback.lean @@ -59,7 +59,7 @@ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- In a category with pullbacks, a morphism `f : X ⟶ Y` induces a functor `Over Y ⥤ Over X`, by pulling back a morphism along `f`. -/ -@[simps! +simpRhs obj_left obj_hom map_left] +@[simps! +simpRhs obj_left obj_hom map_left, implicit_reducible] def pullback {X Y : C} (f : X ⟶ Y) [HasPullbacksAlong f] : Over Y ⥤ Over X where obj g := Over.mk (pullback.snd g.hom f) @@ -164,11 +164,13 @@ Note that the binary products assumption is necessary: the existence of a right -/ def forgetAdjStar : forget X ⊣ star X := (coalgebraEquivOver X).symm.toAdjunction.comp (adj _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma forgetAdjStar_counit_app (X Y : C) : (Over.forgetAdjStar X).counit.app Y = prod.snd := by simp [Over.forgetAdjStar, CategoryTheory.coalgebraEquivOver] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma forgetAdjStar_unit_app_left (X : C) (Y : Over X) : diff --git a/Mathlib/CategoryTheory/Comma/Over/StrictInitial.lean b/Mathlib/CategoryTheory/Comma/Over/StrictInitial.lean index 9d8dc2d9944a0d..37e29b9f99feb3 100644 --- a/Mathlib/CategoryTheory/Comma/Over/StrictInitial.lean +++ b/Mathlib/CategoryTheory/Comma/Over/StrictInitial.lean @@ -41,6 +41,7 @@ def overEquivOfIsInitial [HasStrictInitialObjects C] (X : C) (h : IsInitial X) : Over.isoMk (asIso A.hom) counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `C` has strict terminal objects and `X` is a terminal object, the category `Under X` is equivalent to a point. -/ diff --git a/Mathlib/CategoryTheory/Comma/Presheaf/Basic.lean b/Mathlib/CategoryTheory/Comma/Presheaf/Basic.lean index a9f07aef2afcbb..bd4442781a0edf 100644 --- a/Mathlib/CategoryTheory/Comma/Presheaf/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Presheaf/Basic.lean @@ -206,6 +206,7 @@ def restrictedYonedaObj {F : Cᵒᵖ ⥤ Type v} (η : F ⟶ A) : obj s := OverArrows η s.unop.hom map f := ↾fun u ↦ u.map₂ f.unop.left f.unop.w +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functoriality of `restrictedYonedaObj η` in `η`. -/ @[simps] @@ -213,6 +214,7 @@ def restrictedYonedaObjMap₁ {F G : Cᵒᵖ ⥤ Type v} {η : F ⟶ A} {μ : G (hε : ε ≫ μ = η) : restrictedYonedaObj η ⟶ restrictedYonedaObj μ where app _ := ↾fun u ↦ u.map₁ ε hε +set_option backward.isDefEq.respectTransparency.types false in /-- This is basically just `yoneda : Over A ⥤ (Over A)ᵒᵖ ⥤ Type (max u v)` restricted in the second argument along the forgetful functor `CostructuredArrow yoneda A ⥤ Over A`, but done in a way @@ -389,6 +391,7 @@ def yonedaCollectionPresheaf (A : Cᵒᵖ ⥤ Type v) (F : (CostructuredArrow yo obj X := YonedaCollection F X.unop map f := ↾(YonedaCollection.map₂ F f.unop) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functoriality of `yonedaCollectionPresheaf A F` in `F`. -/ @[simps] @@ -414,6 +417,7 @@ def yonedaCollectionPresheafToA (F : (CostructuredArrow yoneda A)ᵒᵖ ⥤ Type yonedaCollectionPresheaf A F ⟶ A where app _ := ↾(YonedaCollection.yonedaEquivFst) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- This is the reverse direction of the equivalence we're constructing. -/ @[simps! obj map] @@ -485,12 +489,14 @@ def unitAuxAux {F : Cᵒᵖ ⥤ Type v} (η : F ⟶ A) : yonedaCollectionPresheaf A (restrictedYonedaObj η) ≅ F := NatIso.ofComponents (fun X => unitAuxAuxAux η X.unop) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Intermediate stage of assembling the unit. -/ @[simps! hom_left] def unitAux (η : Over A) : (restrictedYoneda A ⋙ costructuredArrowPresheafToOver A).obj η ≅ η := Over.isoMk (unitAuxAux η.hom) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit of the equivalence we're constructing. -/ def unit (A : Cᵒᵖ ⥤ Type v) : 𝟭 (Over A) ≅ restrictedYoneda A ⋙ costructuredArrowPresheafToOver A := @@ -504,11 +510,13 @@ section counit variable {F : (CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v} {X : C} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma OverArrows.yonedaCollectionPresheafToA_val_fst (s : yoneda.obj X ⟶ A) (p : OverArrows (yonedaCollectionPresheafToA F) s) : p.val.fst = s := by simpa [YonedaCollection.yonedaEquivFst_eq] using p.app_val +set_option backward.isDefEq.respectTransparency.types false in /-- Forward direction of the counit. -/ def counitForward (F : (CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v) (s : CostructuredArrow yoneda A) : @@ -581,6 +589,7 @@ def counitAux (F : (CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v) : F ≅ restrictedYonedaObj (yonedaCollectionPresheafToA F) := NatIso.ofComponents (fun s => counitAuxAux F s.unop) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit of the equivalence we're constructing. -/ def counit (A : Cᵒᵖ ⥤ Type v) : @@ -593,6 +602,7 @@ end OverPresheafAux open OverPresheafAux +set_option backward.isDefEq.respectTransparency.types false in /-- If `A : Cᵒᵖ ⥤ Type v` is a presheaf, then we have an equivalence between presheaves lying over `A` and the category of presheaves on `CostructuredArrow yoneda A`. There is a quasicommutative @@ -614,6 +624,7 @@ def CostructuredArrow.toOverCompOverEquivPresheafCostructuredArrow (A : Cᵒᵖ CostructuredArrow.toOver yoneda A ⋙ (overEquivPresheafCostructuredArrow A).functor ≅ yoneda := toOverYonedaCompRestrictedYoneda A +set_option backward.isDefEq.respectTransparency.types false in /-- This isomorphism says that hom-sets in the category `Over A` for a presheaf `A` where the domain is of the form `(CostructuredArrow.toOver yoneda A).obj X` can instead be interpreted as hom-sets in the category `(CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v` where the domain is of the diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean index 5e5e0000dd8dcf..47a17cef8b2174 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow/Basic.lean @@ -37,10 +37,12 @@ and morphisms `C`-morphisms `Y ⟶ Y'` making the obvious triangle commute. -/ -- We explicitly come from `PUnit.{1}` here to obtain the correct universe for morphisms of -- structured arrows. +@[implicit_reducible] def StructuredArrow (S : D) (T : C ⥤ D) := Comma (Functor.fromPUnit.{0} S) T /-- The type of morphisms in the category `StructuredArrow`. -/ +@[implicit_reducible] protected def StructuredArrow.Hom {S : D} {T : C ⥤ D} (f g : StructuredArrow S T) : Type v₁ := CommaMorphism f g @@ -92,6 +94,7 @@ theorem hom_eq_iff {X Y : StructuredArrow S T} (f g : X ⟶ Y) : f = g ↔ f.rig ⟨fun h ↦ by rw [h], hom_ext _ _⟩ /-- Construct a structured arrow from a morphism. -/ +@[implicit_reducible] def mk (f : S ⟶ T.obj Y) : StructuredArrow S T := ⟨⟨⟨⟩⟩, Y, f⟩ @@ -128,7 +131,7 @@ set_option backward.defeqAttrib.useBackward true in we need a morphism of the objects underlying the target, and to check that the triangle commutes. -/ -@[simps right] +@[simps right, implicit_reducible] def homMk {f f' : StructuredArrow S T} (g : f.right ⟶ f'.right) (w : f.hom ≫ T.map g = f'.hom := by cat_disch) : f ⟶ f' where left := 𝟙 f.left @@ -146,12 +149,14 @@ def homMk' (f : StructuredArrow S T) (g : f.right ⟶ Y') : f ⟶ mk (f.hom ≫ left := 𝟙 _ right := g +set_option backward.isDefEq.respectTransparency.types false in lemma homMk'_id (f : StructuredArrow S T) : homMk' f (𝟙 f.right) = eqToHom (by cat_disch) := by simp [eqToHom_right] lemma homMk'_mk_id (f : S ⟶ T.obj Y) : homMk' (mk f) (𝟙 Y) = eqToHom (by simp) := homMk'_id _ +set_option backward.isDefEq.respectTransparency.types false in lemma homMk'_comp (f : StructuredArrow S T) (g : f.right ⟶ Y') (g' : Y' ⟶ Y'') : homMk' f (g ≫ g') = homMk' f g ≫ homMk' (mk (f.hom ≫ T.map g)) g' ≫ eqToHom (by simp) := by simp [eqToHom_right] @@ -166,7 +171,9 @@ def mkPostcomp (f : S ⟶ T.obj Y) (g : Y ⟶ Y') : mk f ⟶ mk (f ≫ T.map g) left := 𝟙 _ right := g +set_option backward.isDefEq.respectTransparency.types false in lemma mkPostcomp_id (f : S ⟶ T.obj Y) : mkPostcomp f (𝟙 Y) = eqToHom (by simp) := by simp +set_option backward.isDefEq.respectTransparency.types false in lemma mkPostcomp_comp (f : S ⟶ T.obj Y) (g : Y ⟶ Y') (g' : Y' ⟶ Y'') : mkPostcomp f (g ≫ g') = mkPostcomp f g ≫ mkPostcomp (f ≫ T.map g) g' ≫ eqToHom (by simp) := by simp @@ -235,7 +242,7 @@ Ideally this would be described as a 2-functor from `D` (promoted to a 2-category with equations as 2-morphisms) to `Cat`. -/ -@[simps!] +@[simps!, implicit_reducible] def map (f : S ⟶ S') : StructuredArrow S' T ⥤ StructuredArrow S T := Comma.mapLeft _ ((Functor.const _).map f) @@ -254,23 +261,28 @@ theorem map_comp {f : S ⟶ S'} {f' : S' ⟶ S''} {h : StructuredArrow S'' T} : rw [eq_mk h] simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An isomorphism `S ≅ S'` induces an equivalence `StructuredArrow S T ≌ StructuredArrow S' T`. -/ -@[simps!] +@[simps!, implicit_reducible] def mapIso (i : S ≅ S') : StructuredArrow S T ≌ StructuredArrow S' T := Comma.mapLeftIso _ ((Functor.const _).mapIso i) /-- A natural isomorphism `T ≅ T'` induces an equivalence `StructuredArrow S T ≌ StructuredArrow S T'`. -/ -@[simps!] +@[simps!, implicit_reducible] def mapNatIso (i : T ≅ T') : StructuredArrow S T ≌ StructuredArrow S T' := Comma.mapRightIso _ i +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance proj_reflectsIsomorphisms : (proj S T).ReflectsIsomorphisms where reflects f t := ⟨StructuredArrow.homMk (inv ((proj S T).map f) :), by simp⟩ open CategoryTheory.Limits +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The identity structured arrow is initial. -/ noncomputable def mkIdInitial [T.Full] [T.Faithful] : IsInitial (mk (𝟙 (T.obj Y))) where @@ -284,7 +296,7 @@ noncomputable def mkIdInitial [T.Full] [T.Faithful] : IsInitial (mk (𝟙 (T.obj variable {A : Type u₃} [Category.{v₃} A] {B : Type u₄} [Category.{v₄} B] /-- The functor `(S, F ⋙ G) ⥤ (S, G)`. -/ -@[simps!] +@[simps!, implicit_reducible] def pre (S : D) (F : B ⥤ C) (G : C ⥤ D) : StructuredArrow S (F ⋙ G) ⥤ StructuredArrow S G := Comma.preRight _ F G @@ -314,6 +326,7 @@ set_option backward.defeqAttrib.useBackward true in instance (S : C) (F : B ⥤ C) (G : C ⥤ D) : (post S F G).Faithful where map_injective {_ _} _ _ h := by simpa [ext_iff] using h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance (S : C) (F : B ⥤ C) (G : C ⥤ D) [G.Faithful] : (post S F G).Full where map_surjective f := ⟨homMk f.right (G.map_injective (by simpa using f.w)), by simp⟩ @@ -333,33 +346,31 @@ variable {L : D} {R : C ⥤ D} {L' : B} {R' : A ⥤ B} {F : C ⥤ A} {G : D ⥤ /-- The functor `StructuredArrow L R ⥤ StructuredArrow L' R'` that is deduced from a natural transformation `R ⋙ G ⟶ F ⋙ R'` and a morphism `L' ⟶ G.obj L.` -/ -@[simps!] +@[simps!, implicit_reducible] def map₂ : StructuredArrow L R ⥤ StructuredArrow L' R' := Comma.map (F₁ := 𝟭 (Discrete PUnit)) (Discrete.natTrans (fun _ => α)) β instance faithful_map₂ [F.Faithful] : (map₂ α β).Faithful := by apply Comma.faithful_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance full_map₂ [G.Faithful] [F.Full] [IsIso α] [IsIso β] : (map₂ α β).Full := by - apply +allowSynthFailures Comma.full_map - rw [NatTrans.isIso_iff_isIso_app] - intro; dsimp; infer_instance + apply Comma.full_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance essSurj_map₂ [F.EssSurj] [G.Full] [IsIso α] [IsIso β] : (map₂ α β).EssSurj := by - apply +allowSynthFailures Comma.essSurj_map - rw [NatTrans.isIso_iff_isIso_app] - intro; dsimp; infer_instance + apply Comma.essSurj_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in noncomputable instance isEquivalenceMap₂ [F.IsEquivalence] [G.Faithful] [G.Full] [IsIso α] [IsIso β] : (map₂ α β).IsEquivalence := by - apply +allowSynthFailures Comma.isEquivalenceMap - rw [NatTrans.isIso_iff_isIso_app] - intro; dsimp; infer_instance + apply Comma.isEquivalenceMap +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The composition of two applications of `map₂` is naturally isomorphic to a single such one. -/ @[simps!] @@ -434,17 +445,20 @@ where finally end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `StructuredArrow.post` is a special case of `StructuredArrow.map₂` up to natural isomorphism. -/ def postIsoMap₂ (S : C) (F : B ⥤ C) (G : C ⥤ D) : post S F G ≅ map₂ (F := 𝟭 _) (𝟙 _) (𝟙 (F ⋙ G)) := NatIso.ofComponents fun _ => isoMk <| Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `StructuredArrow.map` is a special case of `StructuredArrow.map₂` up to natural isomorphism. -/ def mapIsoMap₂ {S S' : D} (f : S ⟶ S') : map (T := T) f ≅ map₂ (F := 𝟭 _) (G := 𝟭 _) f (𝟙 T) := NatIso.ofComponents fun _ => isoMk <| Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `StructuredArrow.pre` is a special case of `StructuredArrow.map₂` up to natural isomorphism. -/ def preIsoMap₂ (S : D) (F : B ⥤ C) (G : C ⥤ D) : @@ -496,6 +510,7 @@ and morphisms `C`-morphisms `Y ⟶ Y'` making the obvious triangle commute. -/ -- We explicitly come from `PUnit.{1}` here to obtain the correct universe for morphisms of -- costructured arrows. +@[implicit_reducible] def CostructuredArrow (S : C ⥤ D) (T : D) := Comma S (Functor.fromPUnit.{0} T) @@ -526,10 +541,14 @@ variable {X Y : CostructuredArrow S T} (f : X ⟶ Y) /-- The morphism that is part of a morphism of costructured arrows. -/ abbrev Hom.left : X.left ⟶ Y.left := CommaMorphism.left f -set_option backward.defeqAttrib.useBackward true in -@[reassoc (attr := simp)] +#adaptation_note +/-- +The combination of `implicitBump` and making `Functor.const` implicit-reducible makes this former +`simp` lemma redundant, so no `simp` annotation. +-/ +@[reassoc] theorem w (f : X ⟶ Y) : S.map f.left ≫ Y.hom = X.hom := by - simpa using CommaMorphism.w f + simp @[reassoc] theorem Hom.w (f : X ⟶ Y) : S.map f.left ≫ Y.hom = X.hom := CostructuredArrow.w f @@ -553,6 +572,7 @@ theorem hom_eq_iff {X Y : CostructuredArrow S T} (f g : X ⟶ Y) : f = g ↔ f.l ⟨fun h ↦ by rw [h], hom_ext _ _⟩ /-- Construct a costructured arrow from a morphism. -/ +@[implicit_reducible] def mk (f : S.obj Y ⟶ T) : CostructuredArrow S T := ⟨Y, ⟨⟨⟩⟩, f⟩ @@ -607,12 +627,14 @@ def homMk' (f : CostructuredArrow S T) (g : Y' ⟶ f.left) : mk (S.map g ≫ f.h left := g right := 𝟙 _ +set_option backward.isDefEq.respectTransparency.types false in lemma homMk'_id (f : CostructuredArrow S T) : homMk' f (𝟙 f.left) = eqToHom (by cat_disch) := by simp [eqToHom_left] lemma homMk'_mk_id (f : S.obj Y ⟶ T) : homMk' (mk f) (𝟙 Y) = eqToHom (by simp) := homMk'_id _ +set_option backward.isDefEq.respectTransparency.types false in lemma homMk'_comp (f : CostructuredArrow S T) (g : Y' ⟶ f.left) (g' : Y'' ⟶ Y') : homMk' f (g' ≫ g) = eqToHom (by simp) ≫ homMk' (mk (S.map g ≫ f.hom)) g' ≫ homMk' f g := by simp [eqToHom_left] @@ -627,7 +649,9 @@ def mkPrecomp (f : S.obj Y ⟶ T) (g : Y' ⟶ Y) : mk (S.map g ≫ f) ⟶ mk f w left := g right := 𝟙 _ +set_option backward.isDefEq.respectTransparency.types false in lemma mkPrecomp_id (f : S.obj Y ⟶ T) : mkPrecomp f (𝟙 Y) = eqToHom (by simp) := by simp +set_option backward.isDefEq.respectTransparency.types false in lemma mkPrecomp_comp (f : S.obj Y ⟶ T) (g : Y' ⟶ Y) (g' : Y'' ⟶ Y') : mkPrecomp f (g' ≫ g) = eqToHom (by simp) ≫ mkPrecomp (S.map g ≫ f) g' ≫ mkPrecomp f g := by simp @@ -694,7 +718,7 @@ Ideally this would be described as a 2-functor from `D` (promoted to a 2-category with equations as 2-morphisms) to `Cat`. -/ -@[simps!] +@[simps!, implicit_reducible] def map (f : T ⟶ T') : CostructuredArrow S T ⥤ CostructuredArrow S T' := Comma.mapRight _ ((Functor.const _).map f) @@ -713,24 +737,29 @@ theorem map_comp {f : T ⟶ T'} {f' : T' ⟶ T''} {h : CostructuredArrow S T} : rw [eq_mk h] simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An isomorphism `T ≅ T'` induces an equivalence `CostructuredArrow S T ≌ CostructuredArrow S T'`. -/ -@[simps!] +@[simps!, implicit_reducible] def mapIso (i : T ≅ T') : CostructuredArrow S T ≌ CostructuredArrow S T' := Comma.mapRightIso _ ((Functor.const _).mapIso i) /-- A natural isomorphism `S ≅ S'` induces an equivalence `CostrucutredArrow S T ≌ CostructuredArrow S' T`. -/ -@[simps!] +@[simps!, implicit_reducible] def mapNatIso (i : S ≅ S') : CostructuredArrow S T ≌ CostructuredArrow S' T := Comma.mapLeftIso _ i +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance proj_reflectsIsomorphisms : (proj S T).ReflectsIsomorphisms where reflects f t := ⟨CostructuredArrow.homMk (inv ((proj S T).map f) :), by simp⟩ open CategoryTheory.Limits +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The identity costructured arrow is terminal. -/ noncomputable def mkIdTerminal [S.Full] [S.Faithful] : IsTerminal (mk (𝟙 (S.obj Y))) where @@ -744,7 +773,7 @@ noncomputable def mkIdTerminal [S.Full] [S.Faithful] : IsTerminal (mk (𝟙 (S.o variable {A : Type u₃} [Category.{v₃} A] {B : Type u₄} [Category.{v₄} B] /-- The functor `(F ⋙ G, S) ⥤ (G, S)`. -/ -@[simps!] +@[simps!, implicit_reducible] def pre (F : B ⥤ C) (G : C ⥤ D) (S : D) : CostructuredArrow (F ⋙ G) S ⥤ CostructuredArrow G S := Comma.preLeft F G _ @@ -774,6 +803,7 @@ set_option backward.defeqAttrib.useBackward true in instance (F : B ⥤ C) (G : C ⥤ D) (S : C) : (post F G S).Faithful where map_injective {_ _} _ _ h := by simpa [ext_iff] using h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance (F : B ⥤ C) (G : C ⥤ D) (S : C) [G.Faithful] : (post F G S).Full where map_surjective f := ⟨homMk f.left (G.map_injective (by simpa using f.w)), by simp⟩ @@ -793,32 +823,23 @@ variable {U : A ⥤ B} {V : B} {F : C ⥤ A} {G : D ⥤ B} /-- The functor `CostructuredArrow S T ⥤ CostructuredArrow U V` that is deduced from a natural transformation `F ⋙ U ⟶ S ⋙ G` and a morphism `G.obj T ⟶ V` -/ -@[simps!] +@[simps!, implicit_reducible] def map₂ : CostructuredArrow S T ⥤ CostructuredArrow U V := Comma.map (F₂ := 𝟭 (Discrete PUnit)) α (Discrete.natTrans (fun _ => β)) instance faithful_map₂ [F.Faithful] : (map₂ α β).Faithful := by apply Comma.faithful_map -set_option backward.defeqAttrib.useBackward true in instance full_map₂ [G.Faithful] [F.Full] [IsIso α] [IsIso β] : (map₂ α β).Full := by - apply +allowSynthFailures Comma.full_map - rw [NatTrans.isIso_iff_isIso_app] - intro; dsimp; infer_instance + apply Comma.full_map -set_option backward.defeqAttrib.useBackward true in instance essSurj_map₂ [F.EssSurj] [G.Full] [IsIso α] [IsIso β] : (map₂ α β).EssSurj := by - apply +allowSynthFailures Comma.essSurj_map - rw [NatTrans.isIso_iff_isIso_app] - intro; dsimp; infer_instance + apply Comma.essSurj_map -set_option backward.defeqAttrib.useBackward true in noncomputable instance isEquivalenceMap₂ [F.IsEquivalence] [G.Faithful] [G.Full] [IsIso α] [IsIso β] : (map₂ α β).IsEquivalence := by - apply +allowSynthFailures Comma.isEquivalenceMap - rw [NatTrans.isIso_iff_isIso_app] - intro; dsimp; infer_instance + apply Comma.isEquivalenceMap set_option backward.defeqAttrib.useBackward true in /-- The composition of two applications of `map₂` is naturally isomorphic to a single such one. -/ @@ -892,6 +913,7 @@ where finally end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `CostructuredArrow.post` is a special case of `CostructuredArrow.map₂` up to natural isomorphism. -/ @@ -998,6 +1020,7 @@ open Opposite namespace StructuredArrow +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a functor `F : C ⥤ D` and an object `d : D`, we obtain a contravariant functor from the category of structured arrows `d ⟶ F.obj c` to the category of costructured arrows @@ -1009,6 +1032,7 @@ def toCostructuredArrow (F : C ⥤ D) (d : D) : obj X := CostructuredArrow.mk (Y := op X.unop.right) X.unop.hom.op map f := CostructuredArrow.homMk f.unop.right.op (by simp [← op_comp]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a functor `F : C ⥤ D` and an object `d : D`, we obtain a contravariant functor from the category of structured arrows `op d ⟶ F.op.obj c` to the category of costructured arrows @@ -1026,6 +1050,7 @@ end StructuredArrow namespace CostructuredArrow +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a functor `F : C ⥤ D` and an object `d : D`, we obtain a contravariant functor from the category of costructured arrows `F.obj c ⟶ d` to the category of structured arrows @@ -1037,6 +1062,7 @@ def toStructuredArrow (F : C ⥤ D) (d : D) : obj X := StructuredArrow.mk (Y := op X.unop.left) X.unop.hom.op map f := StructuredArrow.homMk f.unop.left.op (by simp [← op_comp]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a functor `F : C ⥤ D` and an object `d : D`, we obtain a contravariant functor from the category of costructured arrows `F.op.obj c ⟶ op d` to the category of structured arrows @@ -1052,6 +1078,7 @@ def toStructuredArrow' (F : C ⥤ D) (d : D) : end CostructuredArrow +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a functor `F : C ⥤ D` and an object `d : D`, the category of structured arrows `d ⟶ F.obj c` is contravariantly equivalent to the category of costructured arrows `F.op.obj c ⟶ op d`. @@ -1069,6 +1096,7 @@ def structuredArrowOpEquivalence (F : C ⥤ D) (d : D) : counitIso := NatIso.ofComponents (fun X => CostructuredArrow.isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a functor `F : C ⥤ D` and an object `d : D`, the category of costructured arrows `F.obj c ⟶ d` is contravariantly equivalent to the category of structured arrows @@ -1091,6 +1119,7 @@ section Pre variable {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) {G : D ⥤ E} {e : E} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor establishing the equivalence `StructuredArrow.preEquivalence`. -/ @[simps!] @@ -1101,6 +1130,7 @@ def StructuredArrow.preEquivalenceFunctor (f : StructuredArrow e G) : rw [← w φ, comp_right] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor establishing the equivalence `StructuredArrow.preEquivalence`. -/ @[simps!] @@ -1114,6 +1144,7 @@ def StructuredArrow.preEquivalenceInverse (f : StructuredArrow e G) : simp only [Functor.comp_obj, mk_right, mk_hom_eq_self, Functor.comp_map, Category.assoc, ← w φ, Functor.map_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A structured arrow category on a `StructuredArrow.pre e F G` functor is equivalent to the structured arrow category on F -/ @@ -1122,9 +1153,10 @@ def StructuredArrow.preEquivalence (f : StructuredArrow e G) : StructuredArrow f (pre e F G) ≌ StructuredArrow f.right F where functor := preEquivalenceFunctor F f inverse := preEquivalenceInverse F f - unitIso := NatIso.ofComponents (fun X => isoMk (isoMk (Iso.refl _) (by simpa using X.hom.w.symm))) + unitIso := NatIso.ofComponents (fun X => isoMk (isoMk (Iso.refl _) (by simp))) counitIso := NatIso.ofComponents (fun _ => isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `StructuredArrow d T ⥤ StructuredArrow e (T ⋙ S)` that `u : e ⟶ S.obj d` induces via `StructuredArrow.map₂` can be expressed up to isomorphism by @@ -1135,6 +1167,7 @@ def StructuredArrow.map₂IsoPreEquivalenceInverseCompProj {T : C ⥤ D} {S : D map₂ (F := 𝟭 _) (G := 𝟭 _) (𝟙 _) α := NatIso.ofComponents fun _ => isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor establishing the equivalence `CostructuredArrow.preEquivalence`. -/ @[simps!] @@ -1145,6 +1178,7 @@ def CostructuredArrow.preEquivalence.functor (f : CostructuredArrow G e) : rw [← w φ, comp_left] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor establishing the equivalence `CostructuredArrow.preEquivalence`. -/ @[simps!] @@ -1155,6 +1189,7 @@ def CostructuredArrow.preEquivalence.inverse (f : CostructuredArrow G e) : simp only [Functor.comp_obj, mk_left, Functor.comp_map, mk_hom_eq_self, ← w φ, Functor.map_comp, Category.assoc] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A costructured arrow category on a `CostructuredArrow.pre F G e` functor is equivalent to the costructured arrow category on F -/ @@ -1164,9 +1199,10 @@ def CostructuredArrow.preEquivalence (f : CostructuredArrow G e) : functor := preEquivalence.functor F f inverse := preEquivalence.inverse F f unitIso := NatIso.ofComponents (fun X => isoMk (isoMk (Iso.refl _) - (by simpa using X.hom.w))) + (by simp))) counitIso := NatIso.ofComponents (fun _ => isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `CostructuredArrow T d ⥤ CostructuredArrow (T ⋙ S) e` that `u : S.obj d ⟶ e` induces via `CostructuredArrow.map₂` can be expressed up to isomorphism by @@ -1196,15 +1232,15 @@ theorem StructuredArrow.w_prod_snd {X Y : StructuredArrow (S, S') (T.prod T')} (f : X ⟶ Y) : X.hom.2 ≫ T'.map f.right.2 = Y.hom.2 := congr_arg _root_.Prod.snd (StructuredArrow.w f) -set_option backward.defeqAttrib.useBackward true in /-- Implementation; see `StructuredArrow.prodEquivalence`. -/ @[simps] def StructuredArrow.prodFunctor : StructuredArrow (S, S') (T.prod T') ⥤ StructuredArrow S T × StructuredArrow S' T' where obj f := ⟨.mk f.hom.1, .mk f.hom.2⟩ - map η := ⟨StructuredArrow.homMk η.right.1 (by simp [← η.w]), - StructuredArrow.homMk η.right.2 (by simp [← η.w])⟩ + map η := ⟨StructuredArrow.homMk η.right.1 (by simp), + StructuredArrow.homMk η.right.2 (by simp)⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Implementation; see `StructuredArrow.prodEquivalence`. -/ @[simps] @@ -1213,6 +1249,7 @@ def StructuredArrow.prodInverse : obj f := .mk (Y := (f.1.right, f.2.right)) ⟨f.1.hom, f.2.hom⟩ map η := StructuredArrow.homMk ⟨η.1.right, η.2.right⟩ (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural equivalence `StructuredArrow (S, S') (T.prod T') ≌ StructuredArrow S T × StructuredArrow S' T'`. -/ @@ -1241,6 +1278,7 @@ theorem CostructuredArrow.w_prod_snd {A B : CostructuredArrow (S.prod S') (T, T' S'.map f.left.2 ≫ B.hom.2 = A.hom.2 := congr_arg _root_.Prod.snd (CostructuredArrow.w f) +set_option backward.isDefEq.respectTransparency.types false in /-- Implementation; see `CostructuredArrow.prodEquivalence`. -/ @[simps] def CostructuredArrow.prodFunctor : @@ -1249,6 +1287,7 @@ def CostructuredArrow.prodFunctor : map η := ⟨CostructuredArrow.homMk η.left.1 (by simp), CostructuredArrow.homMk η.left.2 (by simp)⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Implementation; see `CostructuredArrow.prodEquivalence`. -/ @[simps] @@ -1257,6 +1296,7 @@ def CostructuredArrow.prodInverse : obj f := .mk (Y := (f.1.left, f.2.left)) ⟨f.1.hom, f.2.hom⟩ map η := CostructuredArrow.homMk ⟨η.1.left, η.2.left⟩ (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural equivalence `CostructuredArrow (S.prod S') (T, T') ≌ CostructuredArrow S T × CostructuredArrow S' T'`. -/ @@ -1298,6 +1338,7 @@ def costructuredArrowSndInclusion (b : B) : obj X := ⟨⟨X.left, b, X.hom⟩, ⟨⟨⟩⟩, 𝟙 b⟩ map f := CostructuredArrow.homMk ⟨f.left, 𝟙 b, by simp⟩ (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `costructuredArrowSndProj` is left adjoint to `costructuredArrowSndInclusion`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow/CommaMap.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow/CommaMap.lean index 0ff4b7db2e53f7..c7108cdeb389e5 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow/CommaMap.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow/CommaMap.lean @@ -30,9 +30,10 @@ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] [Category.{v₆} T'] {L' : C' ⥤ T'} {R' : D' ⥤ T'} {F₁ : C ⥤ C'} {F₂ : D ⥤ D'} {F : T ⥤ T'} (α : F₁ ⋙ L' ⟶ L ⋙ F) (β : R ⋙ F ⟶ F₂ ⋙ R') +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor establishing the equivalence `StructuredArrow.commaMapEquivalence`. -/ -@[simps] +@[simps, implicit_reducible] def commaMapEquivalenceFunctor [IsIso β] (X : Comma L' R') : StructuredArrow X (Comma.map α β) ⥤ Comma (map₂ (𝟙 _) α) (map₂ X.hom (inv β)) where obj Y := ⟨mk Y.hom.left, mk Y.hom.right, @@ -47,6 +48,7 @@ def commaMapEquivalenceFunctor [IsIso β] (X : Comma L' R') : by simp only [map₂_obj_right, mk_right, hom_eq_iff, comp_right, map₂_map_right, homMk_right, CommaMorphism.w] ⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor establishing the equivalence `StructuredArrow.commaMapEquivalence`. -/ @[simps] @@ -75,6 +77,7 @@ def commaMapEquivalenceCounitIso [IsIso β] (X : Comma L' R') : 𝟭 (Comma (map₂ (𝟙 (L'.obj X.left)) α) (map₂ X.hom (inv β))) := NatIso.ofComponents (fun _ => Comma.isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The structured arrow category on the functor `Comma.map α β`, with `β` a natural isomorphism, is equivalent to a comma category on two instances of `StructuredArrow.map₂`. -/ diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow/Final.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow/Final.lean index 93d84e213fda2a..4675397aec5644 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow/Final.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow/Final.lean @@ -24,7 +24,7 @@ namespace CategoryTheory namespace Functor -open Limits Functor CostructuredArrow +open Limits CostructuredArrow section Small diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow/Functor.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow/Functor.lean index 969bc68484c381..7194aa7d12d68d 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow/Functor.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow/Functor.lean @@ -109,12 +109,18 @@ costructured arrows. -/ def grothendieckProj : Grothendieck (functor L) ⥤ C := grothendieckPrecompFunctorToComma L (𝟭 _) ⋙ Comma.fst _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Fibers of `grothendieckProj L` are isomorphic to the projection `proj L X`. -/ @[simps!] def ιCompGrothendieckProj (X : D) : Grothendieck.ι (functor L) X ⋙ grothendieckProj L ≅ proj L X := ιCompGrothendieckPrecompFunctorToCommaCompFst L (𝟭 _) X +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Functors between costructured arrow categories induced by morphisms in the base category composed with fibers of `grothendieckProj L` are isomorphic to the projection `proj L X`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index 03e8c22e8eb212..01d8be8e292ec4 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -302,11 +302,13 @@ lemma mk₁_comp_eqToHom {X₀ X₁ X₁' : C} (f : X₀ ⟶ X₁) (h : X₁ = X ComposableArrows.mk₁ (f ≫ eqToHom h) = ComposableArrows.mk₁ f := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma mk₁_hom (X : ComposableArrows C 1) : mk₁ X.hom = X := ext₁ rfl rfl (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The bijection between `ComposableArrows C 1` and `Arrow C`. -/ @[simps] @@ -437,21 +439,35 @@ variable {X₀ X₁ X₂ X₃ X₄ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) /-! These examples are meant to test the good definitional properties of `precomp`, and that `dsimp` can see through. -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in example : map' (mk₂ f g) 0 1 = f := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₂ f g) 1 2 = g := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₂ f g) 0 2 = f ≫ g := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : (mk₂ f g).hom = f ≫ g := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₂ f g) 0 0 = 𝟙 _ := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₂ f g) 1 1 = 𝟙 _ := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₂ f g) 2 2 = 𝟙 _ := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₃ f g h) 0 1 = f := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₃ f g h) 1 2 = g := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₃ f g h) 2 3 = h := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₃ f g h) 0 3 = f ≫ g ≫ h := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : (mk₃ f g h).hom = f ≫ g ≫ h := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₃ f g h) 0 2 = f ≫ g := by dsimp +set_option backward.isDefEq.respectTransparency.types false in example : map' (mk₃ f g h) 1 3 = g ≫ h := by dsimp end @@ -602,6 +618,7 @@ lemma ext_succ {F G : ComposableArrows C (n + 1)} (h₀ : F.obj' 0 = G.obj' 0) rw [eqToHom_app, assoc, assoc, eqToHom_trans, eqToHom_refl, comp_id])) this (by rintro ⟨_ | _, hi⟩ <;> simp) +set_option backward.isDefEq.respectTransparency.types false in lemma precomp_surjective (F : ComposableArrows C (n + 1)) : ∃ (F₀ : ComposableArrows C n) (X₀ : C) (f₀ : X₀ ⟶ F₀.left), F = F₀.precomp f₀ := ⟨F.δ₀, _, F.map' 0 1, ext_succ rfl (by simp) (by simp)⟩ @@ -666,6 +683,7 @@ lemma ext₂ {f g : ComposableArrows C 2} (w₁ : f.map' 1 2 = eqToHom h₁ ≫ g.map' 1 2 ≫ eqToHom h₂.symm) : f = g := ext_succ h₀ (ext₁ h₁ h₂ w₁) w₀ +set_option backward.isDefEq.respectTransparency.types false in lemma mk₂_surjective (X : ComposableArrows C 2) : ∃ (X₀ X₁ X₂ : C) (f₀ : X₀ ⟶ X₁) (f₁ : X₁ ⟶ X₂), X = mk₂ f₀ f₁ := ⟨_, _, _, X.map' 0 1, X.map' 1 2, ext₂ rfl rfl rfl (by simp) (by simp)⟩ @@ -748,6 +766,7 @@ lemma ext₃ {f g : ComposableArrows C 3} (w₂ : f.map' 2 3 = eqToHom h₂ ≫ g.map' 2 3 ≫ eqToHom h₃.symm) : f = g := ext_succ h₀ (ext₂ h₁ h₂ h₃ w₁ w₂) w₀ +set_option backward.isDefEq.respectTransparency.types false in lemma mk₃_surjective (X : ComposableArrows C 3) : ∃ (X₀ X₁ X₂ X₃ : C) (f₀ : X₀ ⟶ X₁) (f₁ : X₁ ⟶ X₂) (f₂ : X₂ ⟶ X₃), X = mk₃ f₀ f₁ f₂ := ⟨_, _, _, _, X.map' 0 1, X.map' 1 2, X.map' 2 3, @@ -833,6 +852,7 @@ lemma ext₄ {f g : ComposableArrows C 4} f = g := ext_succ h₀ (ext₃ h₁ h₂ h₃ h₄ w₁ w₂ w₃) w₀ +set_option backward.isDefEq.respectTransparency.types false in lemma mk₄_surjective (X : ComposableArrows C 4) : ∃ (X₀ X₁ X₂ X₃ X₄ : C) (f₀ : X₀ ⟶ X₁) (f₁ : X₁ ⟶ X₂) (f₂ : X₂ ⟶ X₃) (f₃ : X₃ ⟶ X₄), X = mk₄ f₀ f₁ f₂ f₃ := @@ -922,6 +942,7 @@ lemma ext₅ {f g : ComposableArrows C 5} f = g := ext_succ h₀ (ext₄ h₁ h₂ h₃ h₄ h₅ w₁ w₂ w₃ w₄) w₀ +set_option backward.isDefEq.respectTransparency.types false in lemma mk₅_surjective (X : ComposableArrows C 5) : ∃ (X₀ X₁ X₂ X₃ X₄ X₅ : C) (f₀ : X₀ ⟶ X₁) (f₁ : X₁ ⟶ X₂) (f₂ : X₂ ⟶ X₃) (f₃ : X₃ ⟶ X₄) (f₄ : X₄ ⟶ X₅), X = mk₅ f₀ f₁ f₂ f₃ f₄ := @@ -973,6 +994,9 @@ lemma mkOfObjOfMapSucc_arrow (i : ℕ) (hi : i < n := by valid) : end mkOfObjOfMapSucc +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in suppress_compilation in variable (C n) in /-- The equivalence `(ComposableArrows C n)ᵒᵖ ≌ ComposableArrows Cᵒᵖ n` obtained @@ -1005,6 +1029,7 @@ def Functor.mapComposableArrowsObjMk₁Iso {X Y : C} (f : X ⟶ Y) : (G.mapComposableArrows 1).obj (.mk₁ f) ≅ .mk₁ (G.map f) := isoMk₁ (Iso.refl _) (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism between `(G.mapComposableArrows 2).obj (.mk₂ f g)` and `.mk₂ (G.map f) (G.map g)`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/ComposableArrows/One.lean b/Mathlib/CategoryTheory/ComposableArrows/One.lean index 93765c80565cd0..ecbbcfe9d856b0 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/One.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/One.lean @@ -31,6 +31,7 @@ def functorArrows (i j n : ℕ) (hij : i ≤ j := by lia) (hj : j ≤ n := by li obj S := mk₁ (S.map' i j) map {S S'} φ := homMk₁ (φ.app _) (φ.app _) (φ.naturality _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural transformation `functorArrows C i j n ⟶ functorArrows C i' j' n` when `i ≤ i'` and `j ≤ j'`. -/ diff --git a/Mathlib/CategoryTheory/ComposableArrows/Three.lean b/Mathlib/CategoryTheory/ComposableArrows/Three.lean index b3774d77cca6a8..79d3818029f61e 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Three.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Three.lean @@ -35,6 +35,7 @@ variable {C : Type u} [Category.{v} C] {i j k l : C} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) (f₁₂ : i ⟶ k) (f₂₃ : j ⟶ l) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The morphism `mk₂ f₁ f₂ ⟶ mk₂ f₁ f₂₃` when `f₂ ≫ f₃ = f₂₃`. -/ def threeδ₃Toδ₂ (h₂₃ : f₂ ≫ f₃ = f₂₃ := by cat_disch) : @@ -55,14 +56,17 @@ def threeδ₁Toδ₀ (h₁₂ : f₁ ≫ f₂ = f₁₂ := by cat_disch) : variable (h₁₂ : f₁ ≫ f₂ = f₁₂) (h₂₃ : f₂ ≫ f₃ = f₂₃) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma threeδ₃Toδ₂_app_zero : (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃).app 0 = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma threeδ₃Toδ₂_app_one : (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃).app 1 = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma threeδ₃Toδ₂_app_two : (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃).app 2 = f₃ := rfl @@ -98,6 +102,7 @@ section variable {ι : Type*} [Preorder ι] (i₀ i₁ i₂ i₃ : ι) (hi₀₁ : i₀ ≤ i₁) (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) +set_option backward.isDefEq.respectTransparency.types false in /-- Variant of `threeδ₃Toδ₂` for preorders. -/ abbrev threeδ₃Toδ₂' : mk₂ (homOfLE hi₀₁) (homOfLE hi₁₂) ⟶ diff --git a/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean b/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean index 0b12ec2dff0fbe..d8efda3cc6f004 100644 --- a/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean +++ b/Mathlib/CategoryTheory/ConcreteCategory/Basic.lean @@ -185,6 +185,7 @@ theorem hom_comp {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g : ToType X open ConcreteCategory +set_option backward.isDefEq.respectTransparency false in instance InducedCategory.concreteCategory {C : Type u} {D : Type u'} [Category.{v'} D] {FD : D → D → Type*} {CD : D → Type w} [∀ X Y, FunLike (FD X Y) (CD X) (CD Y)] [ConcreteCategory.{w} D FD] (f : C → D) : diff --git a/Mathlib/CategoryTheory/ConcreteCategory/Forget.lean b/Mathlib/CategoryTheory/ConcreteCategory/Forget.lean index 106e3ee8090230..99adc805c705ae 100644 --- a/Mathlib/CategoryTheory/ConcreteCategory/Forget.lean +++ b/Mathlib/CategoryTheory/ConcreteCategory/Forget.lean @@ -106,6 +106,7 @@ lemma forget₂_comp_apply [HasForget₂ C D] {X Y Z : C} instance forget₂_faithful [HasForget₂ C D] : (forget₂ C D).Faithful := HasForget₂.forget_comp.faithful_of_comp +set_option backward.isDefEq.respectTransparency.types false in instance InducedCategory.hasForget₂ (f : C → D) : HasForget₂ (InducedCategory D f) D where forget₂ := inducedFunctor f forget_comp := rfl @@ -121,7 +122,7 @@ instance ObjectProperty.FullSubcategory.hasForget₂ (P : ObjectProperty C) : /-- In order to construct a “partially forgetting” functor, we do not need to verify functor laws; it suffices to ensure that compositions agree with `forget₂ C D ⋙ forget D = forget C`. -/ -@[implicit_reducible] +@[instance_reducible] def HasForget₂.mk' (obj : C → D) (h_obj : ∀ X, (forget D).obj (obj X) = (forget C).obj X) (map : ∀ {X Y}, (X ⟶ Y) → (obj X ⟶ obj Y)) (h_map : ∀ {X Y} {f : X ⟶ Y}, (forget D).map (map f) ≍ (forget C).map f) : diff --git a/Mathlib/CategoryTheory/Conj.lean b/Mathlib/CategoryTheory/Conj.lean index 66fe66d2ac21db..3bc802cc1ac426 100644 --- a/Mathlib/CategoryTheory/Conj.lean +++ b/Mathlib/CategoryTheory/Conj.lean @@ -51,6 +51,7 @@ theorem conj_comp (f g : End X) : α.conj (f ≫ g) = α.conj f ≫ α.conj g := theorem conj_id : α.conj (𝟙 X) = 𝟙 Y := map_one α.conj +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem refl_conj (f : End X) : (Iso.refl X).conj f = f := by rw [conj_apply, Iso.refl_inv, Iso.refl_hom, Category.id_comp, Category.comp_id] @@ -82,6 +83,7 @@ theorem conjAut_apply (f : Aut X) : α.conjAut f = α.symm ≪≫ f ≪≫ α := theorem conjAut_hom (f : Aut X) : (α.conjAut f).hom = α.conj f.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem trans_conjAut {Z : C} (β : Y ≅ Z) (f : Aut X) : (α ≪≫ β).conjAut f = β.conjAut (α.conjAut f) := by @@ -115,6 +117,7 @@ theorem map_conj {X Y : C} (α : X ≅ Y) (f : End X) : F.map (α.conj f) = (F.mapIso α).conj (F.map f) := map_homCongr F α α f +set_option backward.isDefEq.respectTransparency.types false in theorem map_conjAut (F : C ⥤ D) {X Y : C} (α : X ≅ Y) (f : Aut X) : F.mapIso (α.conjAut f) = (F.mapIso α).conjAut (F.mapIso f) := by ext; simp only [mapIso_hom, Iso.conjAut_hom, F.map_conj] diff --git a/Mathlib/CategoryTheory/Core.lean b/Mathlib/CategoryTheory/Core.lean index 87b752bd35da86..7eed2cc0944a74 100644 --- a/Mathlib/CategoryTheory/Core.lean +++ b/Mathlib/CategoryTheory/Core.lean @@ -29,7 +29,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open Functor +open CategoryTheory.Functor universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ @@ -150,38 +150,46 @@ namespace Iso variable {D : Type u₂} [Category.{v₂} D] +set_option backward.isDefEq.respectTransparency.types false in /-- A natural isomorphism of functors induces a natural isomorphism between their cores. -/ @[simps!] def core {F G : C ⥤ D} (α : F ≅ G) : F.core ≅ G.core := NatIso.ofComponents (fun x ↦ Groupoid.isoEquivHom _ _ |>.symm <| .mk <| α.app x.of) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma coreComp {F G H : C ⥤ D} (α : F ≅ G) (β : G ≅ H) : (α ≪≫ β).core = α.core ≪≫ β.core := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma coreId {F : C ⥤ D} : (Iso.refl F).core = Iso.refl F.core := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma coreWhiskerLeft {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) {G H : D ⥤ E} (η : G ≅ H) : (isoWhiskerLeft F η).core = F.coreComp G ≪≫ isoWhiskerLeft F.core η.core ≪≫ (F.coreComp H).symm := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in lemma coreWhiskerRight {E : Type u₃} [Category.{v₃} E] {F G : C ⥤ D} (η : F ≅ G) (H : D ⥤ E) : (isoWhiskerRight η H).core = F.coreComp H ≪≫ isoWhiskerRight η.core H.core ≪≫ (G.coreComp H).symm := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in lemma coreLeftUnitor {F : C ⥤ D} : F.leftUnitor.core = (𝟭 C).coreComp F ≪≫ isoWhiskerRight (Functor.coreId C) _ ≪≫ F.core.leftUnitor := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in lemma coreRightUnitor {F : C ⥤ D} : F.rightUnitor.core = (F).coreComp (𝟭 D) ≪≫ isoWhiskerLeft _ (Functor.coreId D) ≪≫ F.core.rightUnitor := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in lemma coreAssociator {E : Type u₃} [Category.{v₃} E] {E' : Type u₄} [Category.{v₄} E'] (F : C ⥤ D) (G : D ⥤ E) (H : E ⥤ E') : (Functor.associator F G H).core = @@ -196,11 +204,13 @@ namespace Core variable {G : Type u₂} [Groupoid.{v₂} G] +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `functorToCore (F ⋙ H)` factors through `functorToCore H`. -/ def functorToCoreCompLeftIso {G' : Type u₃} [Groupoid.{v₃} G'] (H : G ⥤ C) (F : G' ⥤ G) : functorToCore (F ⋙ H) ≅ F ⋙ functorToCore H := NatIso.ofComponents (fun _ ↦ Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in lemma functorToCore_comp_left {G' : Type u₃} [Groupoid.{v₃} G'] (H : G ⥤ C) (F : G' ⥤ G) : functorToCore (F ⋙ H) = F ⋙ functorToCore H := Functor.ext_of_iso (functorToCoreCompLeftIso H F) (by cat_disch) @@ -214,10 +224,12 @@ lemma functorToCore_comp_right {C' : Type u₄} [Category.{v₄} C'] (H : G ⥤ functorToCore (H ⋙ F) = functorToCore H ⋙ F.core := Functor.ext_of_iso (functorToCoreCompRightIso H F) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `functorToCore (𝟭 G)` is a section of `inclusion G`. -/ def inclusionCompFunctorToCoreIso : inclusion G ⋙ functorToCore (𝟭 G) ≅ 𝟭 (Core G) := NatIso.ofComponents (fun _ ↦ Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in theorem inclusion_comp_functorToCore : inclusion G ⋙ functorToCore (𝟭 G) = 𝟭 (Core G) := Functor.ext_of_iso inclusionCompFunctorToCoreIso (by cat_disch) @@ -234,6 +246,7 @@ variable (D : Type u₂) [Category.{v₂} D] namespace Equivalence +set_option backward.isDefEq.respectTransparency.types false in variable {D} in /-- Equivalent categories have equivalent cores. -/ @[simps!] @@ -245,6 +258,7 @@ def core (E : C ≌ D) : Core C ≌ Core D where end Equivalence +set_option backward.isDefEq.respectTransparency.types false in variable (C) in /-- Taking the core of a functor is functorial if we discard non-invertible natural transformations. -/ diff --git a/Mathlib/CategoryTheory/Dialectica/Monoidal.lean b/Mathlib/CategoryTheory/Dialectica/Monoidal.lean index 405909fa3637e6..b00e8e5ad890a5 100644 --- a/Mathlib/CategoryTheory/Dialectica/Monoidal.lean +++ b/Mathlib/CategoryTheory/Dialectica/Monoidal.lean @@ -82,6 +82,9 @@ def associatorImpl (X Y Z : Dial C) : isoMk (prod.associator ..) (prod.associator ..) <| by simp [Subobject.inf_pullback, ← Subobject.pullback_comp, inf_assoc] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[simps!] instance : MonoidalCategoryStruct (Dial C) where tensorUnit := tensorUnitImpl diff --git a/Mathlib/CategoryTheory/DifferentialObject.lean b/Mathlib/CategoryTheory/DifferentialObject.lean index dfe23791629b2a..99c3a45631b8a8 100644 --- a/Mathlib/CategoryTheory/DifferentialObject.lean +++ b/Mathlib/CategoryTheory/DifferentialObject.lean @@ -276,7 +276,6 @@ def shiftFunctor (n : S) : DifferentialObject S C ⥤ DifferentialObject S C whe map_comp f g := by ext1; dsimp; rw [Functor.map_comp] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The shift functor on `DifferentialObject S C` is additive. -/ @[simps!] nonrec def shiftFunctorAdd (m n : S) : @@ -294,8 +293,8 @@ nonrec def shiftFunctorAdd (m n : S) : section +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The shift by zero is naturally isomorphic to the identity. -/ @[simps!] def shiftZero : shiftFunctor C (0 : S) ≅ 𝟭 (DifferentialObject S C) := by diff --git a/Mathlib/CategoryTheory/Discrete/Basic.lean b/Mathlib/CategoryTheory/Discrete/Basic.lean index 3f7a993158e56e..faa9a2b0150429 100644 --- a/Mathlib/CategoryTheory/Discrete/Basic.lean +++ b/Mathlib/CategoryTheory/Discrete/Basic.lean @@ -163,6 +163,7 @@ attribute [local aesop safe tactic (rule_sets := [CategoryTheory])] CategoryTheory.Discrete.discreteCases /-- Any function `I → C` gives a functor `Discrete I ⥤ C`. -/ +@[implicit_reducible] def functor {I : Type u₁} (F : I → C) : Discrete I ⥤ C where obj := F ∘ Discrete.as map {X Y} f := by @@ -194,6 +195,7 @@ lemma functor_ext {I : Type u₁} {G F : Discrete I ⥤ C} (h : (i : I) → G.ob · intro I; rw [h] · intro ⟨X⟩ ⟨Y⟩ ⟨⟨p⟩⟩; simp only at p; induction p; simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The discrete functor induced by a composition of maps can be written as a composition of two discrete functors. @@ -207,7 +209,7 @@ def functorComp {I : Type u₁} {J : Type u₁'} (f : J → C) (g : I → J) : a natural transformation is just a collection of maps, as the naturality squares are trivial. -/ -@[simps] +@[simps, implicit_reducible] def natTrans {I : Type u₁} {F G : Discrete I ⥤ C} (f : ∀ i : Discrete I, F.obj i ⟶ G.obj i) : F ⟶ G where app := f @@ -299,18 +301,21 @@ theorem functor_map_id (F : Discrete J ⥤ C) {j : Discrete J} (f : j ⟶ j) : end Discrete +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Discrete.forall {α : Type*} {p : Discrete α → Prop} : (∀ (a : Discrete α), p a) ↔ ∀ (a' : α), p ⟨a'⟩ := by rw [iff_iff_eq, discreteEquiv.forall_congr_left] - simp [discreteEquiv] + simp only [discreteEquiv, Equiv.symm_mk, Equiv.coe_fn_mk] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Discrete.exists {α : Type*} {p : Discrete α → Prop} : (∃ (a : Discrete α), p a) ↔ ∃ (a' : α), p ⟨a'⟩ := by rw [iff_iff_eq, discreteEquiv.exists_congr_left] simp [discreteEquiv] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories `(J → C) ≌ (Discrete J ⥤ C)`. -/ @[simps] @@ -330,6 +335,7 @@ def piEquivalenceFunctorDiscrete (J : Type u₂) (C : Type u₁) [Category.{v₁ obtain rfl : f = 𝟙 _ := rfl simp))) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `piEquivalenceFunctorDiscrete` is compatible with `evaluation`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Discrete/StructuredArrow.lean b/Mathlib/CategoryTheory/Discrete/StructuredArrow.lean index 5e9489732e0fff..8865504532b23f 100644 --- a/Mathlib/CategoryTheory/Discrete/StructuredArrow.lean +++ b/Mathlib/CategoryTheory/Discrete/StructuredArrow.lean @@ -28,6 +28,7 @@ variable {C : Type u} [Category.{v} C] {T : Type w} namespace Discrete +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ Discrete T` is a functor with `T` containing a unique element `t`, then this is the equivalence @@ -41,6 +42,7 @@ def structuredArrowEquivalenceOfUnique unitIso := NatIso.ofComponents (fun _ ↦ StructuredArrow.isoMk (Iso.refl _)) counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ Discrete T` is a functor with `T` containing a unique element `t`, then this is the equivalence diff --git a/Mathlib/CategoryTheory/Discrete/SumsProducts.lean b/Mathlib/CategoryTheory/Discrete/SumsProducts.lean index 103bf203bac7eb..b93555a84d5d34 100644 --- a/Mathlib/CategoryTheory/Discrete/SumsProducts.lean +++ b/Mathlib/CategoryTheory/Discrete/SumsProducts.lean @@ -43,6 +43,9 @@ def productEquiv {J K : Type*} : Discrete (J × K) ≌ Discrete J × Discrete K unitIso := NatIso.ofComponents (fun _ ↦ Iso.refl _) counitIso := NatIso.ofComponents (fun _ ↦ Iso.refl _) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The discrete category on a sum is equivalent to the sum of the discrete categories. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Distributive/Monoidal.lean b/Mathlib/CategoryTheory/Distributive/Monoidal.lean index c741b6b5e05727..ae266b653feab5 100644 --- a/Mathlib/CategoryTheory/Distributive/Monoidal.lean +++ b/Mathlib/CategoryTheory/Distributive/Monoidal.lean @@ -212,6 +212,7 @@ lemma coprodComparison_tensorLeft_braiding_hom [BraidedCategory C] {X Y Z : C} : (coprod.map (β_ X Y).hom (β_ X Z).hom) ≫ (coprodComparison (tensorRight X) Y Z) := by simp [coprodComparison] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- In a symmetric monoidal category, the right distributivity is equal to the left distributivity up to braiding isomorphisms. -/ diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Coproduct.lean b/Mathlib/CategoryTheory/EffectiveEpi/Coproduct.lean index 2e30e726eaeb93..de5b0880c1b052 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Coproduct.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Coproduct.lean @@ -41,6 +41,7 @@ def effectiveEpiStructIsColimitDescOfEffectiveEpiFamily {B : C} {α : Type*} (X uniq e _ m hm := EffectiveEpiFamily.uniq X π (fun a ↦ c.ι.app ⟨a⟩ ≫ e) (fun _ _ _ _ hg ↦ (by simp [← hm, reassoc_of% hg])) m (fun _ ↦ (by simp [← hm])) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {B : C} {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B)) [HasCoproduct X] [EffectiveEpiFamily X π] : EffectiveEpi (Sigma.desc π) := by diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean b/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean index d4d07cc3c27cfe..9cb3742fecb660 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean @@ -63,7 +63,6 @@ noncomputable def effectiveEpiOver (X : D) : F.effectiveEpiOverObj X ⟶ X := instance (X : D) : EffectiveEpi (F.effectiveEpiOver X) := (EffectivelyEnough.presentation X).some.effectiveEpi -set_option backward.isDefEq.respectTransparency false in /-- An effective presentation of an object with respect to an equivalence of categories. -/ def equivalenceEffectivePresentation (e : C ≌ D) (X : D) : EffectivePresentation e.functor X where diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Preserves.lean b/Mathlib/CategoryTheory/EffectiveEpi/Preserves.lean index 22b8d036f7a3f8..aeabe987f46556 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Preserves.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Preserves.lean @@ -36,7 +36,6 @@ variable {D : Type*} [Category* D] (e : C ≌ D) {B : C} variable {α : Type*} (X : α → C) (π : (a : α) → (X a ⟶ B)) -set_option backward.isDefEq.respectTransparency false in theorem effectiveEpiFamilyStructOfEquivalence_aux {W : D} (ε : (a : α) → e.functor.obj (X a) ⟶ W) (h : ∀ {Z : D} (a₁ a₂ : α) (g₁ : Z ⟶ e.functor.obj (X a₁)) (g₂ : Z ⟶ e.functor.obj (X a₂)), g₁ ≫ e.functor.map (π a₁) = g₂ ≫ e.functor.map (π a₂) → g₁ ≫ ε a₁ = g₂ ≫ ε a₂) @@ -49,7 +48,6 @@ theorem effectiveEpiFamilyStructOfEquivalence_aux {W : D} (ε : (a : α) → e.f variable [EffectiveEpiFamily X π] -set_option backward.isDefEq.respectTransparency false in /-- Equivalences preserve effective epimorphic families -/ def effectiveEpiFamilyStructOfEquivalence : EffectiveEpiFamilyStruct (fun a ↦ e.functor.obj (X a)) (fun a ↦ e.functor.map (π a)) where @@ -63,7 +61,9 @@ def effectiveEpiFamilyStructOfEquivalence : EffectiveEpiFamilyStruct (fun a ↦ (EffectiveEpiFamily.fac X π (fun a ↦ e.unit.app _ ≫ e.inverse.map (ε a)) (effectiveEpiFamilyStructOfEquivalence_aux e X π ε h) a) simp only [Functor.id_obj, Function.comp_apply, Functor.map_comp, - Category.assoc, Equivalence.fun_inv_map, Iso.inv_hom_id_app, Category.comp_id] at this + Category.assoc, Equivalence.fun_inv_map, + Equivalence.counitIso_inv_hom_id_app, Category.comp_id, + Equivalence.functor_unit_comp_assoc] at this simp [this] uniq ε h m hm := by simp only [Adjunction.homEquiv_counit, @@ -110,6 +110,7 @@ instance [IsRegularEpiCategory D] (F : C ⥤ D) [F.PreservesEpimorphisms] [Limit rw [← isRegularEpi_iff_effectiveEpi] apply IsRegularEpiCategory.regularEpiOfEpi +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Applying a functor which preserves pullbacks and effective epimorphisms to a regular epi diagram diff --git a/Mathlib/CategoryTheory/Elements.lean b/Mathlib/CategoryTheory/Elements.lean index 2548dd3b2a4c39..a53cdc94674112 100644 --- a/Mathlib/CategoryTheory/Elements.lean +++ b/Mathlib/CategoryTheory/Elements.lean @@ -51,6 +51,7 @@ def Functor.Elements (F : C ⥤ Type w) := /-- Constructor for the type `F.Elements` when `F` is a functor to types. -/ abbrev Functor.elementsMk (F : C ⥤ Type w) (X : C) (x : F.obj X) : F.Elements := ⟨X, x⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma Functor.Elements.ext {F : C ⥤ Type w} (x y : F.Elements) (h₁ : x.fst = y.fst) (h₂ : F.map (eqToHom h₁) x.snd = y.snd) : x = y := by cases x @@ -198,6 +199,7 @@ theorem fromStructuredArrow_map {X Y} (f : X ⟶ Y) : ⟨f.right, by simp [ConcreteCategory.congr_hom f.w.symm PUnit.unit]; rfl⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence between the category of elements `F.Elements` and the comma category `(*, F)`. -/ @[simps] @@ -209,6 +211,7 @@ def structuredArrowEquivalence : F.Elements ≌ StructuredArrow PUnit F where open Opposite +set_option backward.isDefEq.respectTransparency.types false in /-- The forward direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`, given by `CategoryTheory.yonedaEquiv`. -/ @@ -235,6 +238,7 @@ theorem fromCostructuredArrow_obj_mk (F : Cᵒᵖ ⥤ Type v) {X : C} (f : yoned (fromCostructuredArrow F).obj (op (CostructuredArrow.mk f)) = ⟨op X, yonedaEquiv.1 f⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)` given by yoneda lemma. -/ @[simps] @@ -252,6 +256,7 @@ def costructuredArrowYonedaEquivalence (F : Cᵒᵖ ⥤ Type v) : simpa only [Functor.map_id, Category.id_comp] using! (yonedaEquiv.symm_apply_apply X.hom).symm)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `(-.Elements)ᵒᵖ ≅ (yoneda, -)` of is actually a natural isomorphism of functors. -/ diff --git a/Mathlib/CategoryTheory/Endofunctor/Algebra.lean b/Mathlib/CategoryTheory/Endofunctor/Algebra.lean index 970b1e52b57094..2b4f30d41b21ae 100644 --- a/Mathlib/CategoryTheory/Endofunctor/Algebra.lean +++ b/Mathlib/CategoryTheory/Endofunctor/Algebra.lean @@ -159,12 +159,14 @@ def functorOfNatTrans {F G : C ⥤ C} (α : G ⟶ F) : Algebra F ⥤ Algebra G w str := α.app _ ≫ A.str } map f := { f := f.1 } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The identity transformation induces the identity endofunctor on the category of algebras. -/ @[simps!] def functorOfNatTransId : functorOfNatTrans (𝟙 F) ≅ 𝟭 _ := NatIso.ofComponents fun X => isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A composition of natural transformations gives the composition of corresponding functors. -/ @[simps!] @@ -172,6 +174,7 @@ def functorOfNatTransComp {F₀ F₁ F₂ : C ⥤ C} (α : F₀ ⟶ F₁) (β : functorOfNatTrans (α ≫ β) ≅ functorOfNatTrans β ⋙ functorOfNatTrans α := NatIso.ofComponents fun X => isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in /-- If `α` and `β` are two equal natural transformations, then the functors of algebras induced by them are isomorphic. @@ -354,12 +357,14 @@ def functorOfNatTrans {F G : C ⥤ C} (α : F ⟶ G) : Coalgebra F ⥤ Coalgebra { f := f.1 h := by rw [Category.assoc, ← α.naturality, ← Category.assoc, f.h, Category.assoc] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The identity transformation induces the identity endofunctor on the category of coalgebras. -/ @[simps!] def functorOfNatTransId : functorOfNatTrans (𝟙 F) ≅ 𝟭 _ := NatIso.ofComponents fun X => isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A composition of natural transformations gives the composition of corresponding functors. -/ @[simps!] @@ -367,6 +372,7 @@ def functorOfNatTransComp {F₀ F₁ F₂ : C ⥤ C} (α : F₀ ⟶ F₁) (β : functorOfNatTrans (α ≫ β) ≅ functorOfNatTrans α ⋙ functorOfNatTrans β := NatIso.ofComponents fun X => isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in /-- If `α` and `β` are two equal natural transformations, then the functors of coalgebras induced by them are isomorphic. We define it like this as opposed to using `eq_to_iso` so that the components are nicer to prove diff --git a/Mathlib/CategoryTheory/Endomorphism.lean b/Mathlib/CategoryTheory/Endomorphism.lean index 0494615ecaa92a..55ce568f6f2a85 100644 --- a/Mathlib/CategoryTheory/Endomorphism.lean +++ b/Mathlib/CategoryTheory/Endomorphism.lean @@ -29,6 +29,7 @@ namespace CategoryTheory /-- Endomorphisms of an object in a category. Arguments order in multiplication agrees with `Function.comp`, not with `CategoryTheory.CategoryStruct.comp`. -/ +@[implicit_reducible] def End {C : Type u} [CategoryStruct.{v} C] (X : C) := X ⟶ X namespace End @@ -105,6 +106,7 @@ instance group {C : Type u} [Groupoid.{v} C] (X : C) : Group (End X) where end End +set_option backward.isDefEq.respectTransparency.types false in theorem isUnit_iff_isIso {C : Type u} [Category.{v} C] {X : C} (f : End X) : IsUnit (f : End X) ↔ IsIso f := ⟨fun h => { out := ⟨h.unit.inv, ⟨h.unit.inv_val, h.unit.val_inv⟩⟩ }, fun h => @@ -152,6 +154,7 @@ def unitsEndEquivAut : (End X)ˣ ≃* Aut X where @[simps!] def toEnd (X : C) : Aut X →* End X := (Units.coeHom (End X)).comp (Aut.unitsEndEquivAut X).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Isomorphisms induce isomorphisms of the automorphism group -/ def autMulEquivOfIso {X Y : C} (h : X ≅ Y) : Aut X ≃* Aut Y where toFun x := { hom := h.inv ≫ x.hom ≫ h.hom, inv := h.inv ≫ x.inv ≫ h.hom } diff --git a/Mathlib/CategoryTheory/Enriched/Basic.lean b/Mathlib/CategoryTheory/Enriched/Basic.lean index 08c4ff97b3253a..b8df8021b4d734 100644 --- a/Mathlib/CategoryTheory/Enriched/Basic.lean +++ b/Mathlib/CategoryTheory/Enriched/Basic.lean @@ -119,6 +119,7 @@ variable (F : V ⥤ W) [F.LaxMonoidal] open Functor.LaxMonoidal +set_option backward.isDefEq.respectTransparency.types false in instance : EnrichedCategory W (TransportEnrichment F C) where Hom := fun X Y : C => F.obj (X ⟶[V] Y) id := fun X : C => ε F ≫ F.map (eId V X) @@ -142,10 +143,12 @@ instance : EnrichedCategory W (TransportEnrichment F C) where F.map_comp, MonoidalCategory.whiskerLeft_comp, Category.assoc, Functor.LaxMonoidal.μ_natural_right_assoc] +set_option backward.isDefEq.respectTransparency.types false in lemma TransportEnrichment.eId_eq (X : TransportEnrichment F C) : eId W X = ε F ≫ F.map (eId (C := C) V X) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma TransportEnrichment.eComp_eq (X Y Z : TransportEnrichment F C) : eComp W X Y Z = μ F _ _ ≫ F.map (eComp V _ _ _) := rfl @@ -167,7 +170,7 @@ def categoryOfEnrichedCategoryType (C : Type u₁) [𝒞 : EnrichedCategory (Typ attribute [local simp] types_tensorObj_def in /-- Construct a `Type v`-enriched category from an honest category. -/ -@[implicit_reducible] +@[instance_reducible] def enrichedCategoryTypeOfCategory (C : Type u₁) [𝒞 : Category.{v} C] : EnrichedCategory (Type v) C where Hom X Y := 𝒞.Hom X Y @@ -176,6 +179,7 @@ def enrichedCategoryTypeOfCategory (C : Type u₁) [𝒞 : Category.{v} C] : /-- We verify that an enriched category in `Type u` is just the same thing as an honest category. -/ +@[implicit_reducible] def enrichedCategoryTypeEquivCategory (C : Type u₁) : EnrichedCategory (Type v) C ≃ Category.{v} C where toFun _ := categoryOfEnrichedCategoryType C @@ -210,10 +214,12 @@ def ForgetEnrichment (W : Type v) [Category.{w} W] [MonoidalCategory W] (C : Typ variable (W) /-- Typecheck an object of `C` as an object of `ForgetEnrichment W C`. -/ +@[implicit_reducible] def ForgetEnrichment.of (X : C) : ForgetEnrichment W C := X /-- Typecheck an object of `ForgetEnrichment W C` as an object of `C`. -/ +@[implicit_reducible] def ForgetEnrichment.to (X : ForgetEnrichment W C) : C := X @@ -226,6 +232,7 @@ theorem ForgetEnrichment.of_to (X : ForgetEnrichment W C) : ForgetEnrichment.of W (ForgetEnrichment.to W X) = X := rfl +set_option backward.isDefEq.respectTransparency.types false in instance categoryForgetEnrichment : Category (ForgetEnrichment W C) := enrichedCategoryTypeEquivCategory C (inferInstanceAs (EnrichedCategory (Type w) (TransportEnrichment (coyoneda.obj (op (𝟙_ W))) C))) @@ -256,23 +263,27 @@ theorem ForgetEnrichment.homOf_homTo {X Y : ForgetEnrichment W C} (f : X ⟶ Y) ForgetEnrichment.homOf W (ForgetEnrichment.homTo W f) = f := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The identity in the "underlying" category of an enriched category. -/ @[simp] theorem ForgetEnrichment.homTo_id (X : ForgetEnrichment W C) : ForgetEnrichment.homTo W (𝟙 X) = eId W (ForgetEnrichment.to W X : C) := Category.id_comp _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem ForgetEnrichment.homOf_eId (X : C) : ForgetEnrichment.homOf W (eId W X) = 𝟙 (of W X : C) := (homTo_id W (ForgetEnrichment.of W X)).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Composition in the "underlying" category of an enriched category. -/ @[simp] theorem ForgetEnrichment.homTo_comp {X Y Z : ForgetEnrichment W C} (f : X ⟶ Y) (g : Y ⟶ Z) : homTo W (f ≫ g) = ((λ_ (𝟙_ W)).inv ≫ (homTo W f ⊗ₘ homTo W g)) ≫ eComp W _ _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem ForgetEnrichment.homOf_comp {X Y Z : C} (f : 𝟙_ W ⟶ (X ⟶[W] Y)) (g : 𝟙_ W ⟶ (Y ⟶[W] Z)) : homOf W ((λ_ _).inv ≫ (f ⊗ₘ g) ≫ eComp W ..) = homOf W f ≫ homOf W g := by @@ -341,7 +352,7 @@ set_option backward.isDefEq.respectTransparency false in /-- An enriched functor induces an honest functor of the underlying categories, by mapping the `(𝟙_ W)`-shaped morphisms. -/ -@[simps] +@[simps, implicit_reducible] def forget (F : EnrichedFunctor W C D) : ForgetEnrichment W C ⥤ ForgetEnrichment W D where obj X := ForgetEnrichment.of W (F.obj (ForgetEnrichment.to W X)) @@ -349,7 +360,6 @@ def forget (F : EnrichedFunctor W C D) : ForgetEnrichment.homOf W (ForgetEnrichment.homTo W f ≫ F.map (ForgetEnrichment.to W _) (ForgetEnrichment.to W _)) map_comp f g := by - dsimp apply_fun ForgetEnrichment.homTo W · simp only [Iso.cancel_iso_inv_left, Category.assoc, ← tensorHom_comp_tensorHom, ForgetEnrichment.homTo_homOf, EnrichedFunctor.map_comp, ForgetEnrichment.homTo_comp] @@ -478,6 +488,7 @@ variable [BraidedCategory V] open BraidedCategory +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A presheaf isomorphic to the Yoneda embedding of the `V`-object of natural transformations from `F` to `G`. @@ -520,6 +531,7 @@ def enrichedFunctorTypeEquivFunctor {C : Type u₁} [𝒞 : EnrichedCategory (Ty map_id := fun X => by ext ⟨⟩; exact F.map_id X map_comp := fun X Y Z => by ext ⟨f, g⟩; exact F.map_comp f g } +set_option backward.isDefEq.respectTransparency.types false in /-- We verify that the presheaf representing natural transformations between `Type v`-enriched functors is actually represented by the usual type of natural transformations! diff --git a/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean b/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean index d695c105155b68..1d8c3502773af1 100644 --- a/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean +++ b/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean @@ -93,6 +93,7 @@ def associator (F : EnrichedFunctor V C D) (G : EnrichedFunctor V D E) Functor.isoWhiskerLeft _ (G.forgetComp H).symm ≪≫ (F.forgetComp _).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma comp_whiskerRight {F G H : EnrichedFunctor V C D} (α : F ⟶ G) (β : G ⟶ H) (I : EnrichedFunctor V D E) : @@ -102,6 +103,7 @@ lemma comp_whiskerRight {F G H : EnrichedFunctor V C D} (α : F ⟶ G) EnrichedFunctor.forget, EnrichedFunctor.comp_obj, EnrichedFunctor.comp_map] simp [← ForgetEnrichment.homOf_comp] +set_option backward.isDefEq.respectTransparency.types false in lemma whisker_exchange {F G : EnrichedFunctor V C D} {H I : EnrichedFunctor V D E} (α : F ⟶ G) (β : H ⟶ I) : whiskerLeft F β ≫ whiskerRight α I = whiskerRight α H ≫ whiskerLeft G β := by @@ -111,6 +113,7 @@ lemma whisker_exchange {F G : EnrichedFunctor V C D} {H I : EnrichedFunctor V D whiskerRight_out_app] exact (β.out.naturality (α.out.app (ForgetEnrichment.of V X))).symm +set_option backward.isDefEq.respectTransparency.types false in /-- The bicategory structure on `EnrichedCat V` for a monoidal category `V`. -/ instance bicategory : Bicategory (EnrichedCat.{w, v, u} V) where Hom C D := EnrichedFunctor V C D diff --git a/Mathlib/CategoryTheory/Enriched/FunctorCategory.lean b/Mathlib/CategoryTheory/Enriched/FunctorCategory.lean index c7581dea793a07..20b5698789186b 100644 --- a/Mathlib/CategoryTheory/Enriched/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Enriched/FunctorCategory.lean @@ -36,7 +36,7 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory.Enriched.FunctorCategory -open Category MonoidalCategory Limits Functor +open Category MonoidalCategory Limits CategoryTheory.Functor variable (V : Type u₁) [Category.{v₁} V] [MonoidalCategory V] {C : Type u₂} [Category.{v₂} C] {J : Type u₃} [Category.{v₃} J] @@ -136,6 +136,7 @@ section variable [HasEnrichedHom V F₁ F₂] [HasEnrichedHom V F₂ F₃] [HasEnrichedHom V F₁ F₃] +set_option backward.isDefEq.respectTransparency.types false in /-- The composition for the `V`-enrichment of the category `J ⥤ C`. -/ noncomputable def enrichedComp : enrichedHom V F₁ F₂ ⊗ enrichedHom V F₂ F₃ ⟶ enrichedHom V F₁ F₃ := end_.lift (fun j ↦ (end_.π _ j ⊗ₘ end_.π _ j) ≫ eComp V _ _ _) (fun i j f ↦ by @@ -236,7 +237,7 @@ variable (J C) /-- If `C` is a `V`-enriched ordinary category, and `C` has suitable limits, then `J ⥤ C` is also a `V`-enriched ordinary category. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def enrichedOrdinaryCategory [∀ (F₁ F₂ : J ⥤ C), HasEnrichedHom V F₁ F₂] : EnrichedOrdinaryCategory V (J ⥤ C) where Hom F₁ F₂ := enrichedHom V F₁ F₂ @@ -253,7 +254,6 @@ section variable (G : K ⥤ J) [HasEnrichedHom V F₁ F₂] -set_option backward.isDefEq.respectTransparency false in variable {F₁ F₂} in /-- If `F₁` and `F₂` are functors `J ⥤ C`, `G : K ⥤ J`, and `F₁'` and `F₂'` are functors `K ⥤ C` that are respectively diff --git a/Mathlib/CategoryTheory/Enriched/Ordinary/Basic.lean b/Mathlib/CategoryTheory/Enriched/Ordinary/Basic.lean index a52d606f8d7f4e..1db6c840d9af88 100644 --- a/Mathlib/CategoryTheory/Enriched/Ordinary/Basic.lean +++ b/Mathlib/CategoryTheory/Enriched/Ordinary/Basic.lean @@ -233,7 +233,7 @@ set_option backward.isDefEq.respectTransparency false in `(𝟙_ V ⟶ v) → (𝟙_ W ⟶ F.obj v)` is bijective, and `C` is an enriched ordinary category on `V`, then `F` induces the structure of a `W`-enriched ordinary category on `TransportEnrichment F C`, i.e. on the same underlying category `C`. -/ -@[implicit_reducible] +@[instance_reducible] def TransportEnrichment.enrichedOrdinaryCategory (e : ∀ v : V, (𝟙_ V ⟶ v) ≃ (𝟙_ W ⟶ F.obj v)) (h : ∀ v : V, ∀ f : 𝟙_ V ⟶ v, e v f = Functor.LaxMonoidal.ε F ≫ F.map f) : @@ -342,7 +342,7 @@ instance (P : ObjectProperty C) : rw [← eHomEquiv_id] rfl homEquiv_comp f g := by - simp only [ObjectProperty.ι_obj, Equiv.trans_apply] + simp only [ObjectProperty.ι_obj] change (eHomEquiv V) (P.ι.map (f ≫ g)) = _ rw [Functor.map_comp, eHomEquiv_comp] rfl diff --git a/Mathlib/CategoryTheory/EpiMono.lean b/Mathlib/CategoryTheory/EpiMono.lean index 91afde3592136e..5679b8476d9fc7 100644 --- a/Mathlib/CategoryTheory/EpiMono.lean +++ b/Mathlib/CategoryTheory/EpiMono.lean @@ -150,7 +150,7 @@ theorem IsIso.of_epi_section {X Y : C} (f : X ⟶ Y) [hf : IsSplitEpi f] [hf' : -- FIXME this has unnecessarily become noncomputable! /-- A category where every morphism has a `Trunc` retraction is computably a groupoid. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Groupoid.ofTruncSplitMono (all_split_mono : ∀ {X Y : C} (f : X ⟶ Y), Trunc (IsSplitMono f)) : Groupoid.{v₁} C := by apply Groupoid.ofIsIso diff --git a/Mathlib/CategoryTheory/EqToHom.lean b/Mathlib/CategoryTheory/EqToHom.lean index 84483ea2b59654..8af05f699ff947 100644 --- a/Mathlib/CategoryTheory/EqToHom.lean +++ b/Mathlib/CategoryTheory/EqToHom.lean @@ -390,6 +390,7 @@ lemma ObjectProperty.eqToHom_hom {C : Type*} [Category C] {P : ObjectProperty C} subst h rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `T ≃ D` is a bijection and `D` is a category, then `InducedCategory D e` is equivalent to `D`. -/ diff --git a/Mathlib/CategoryTheory/Equivalence.lean b/Mathlib/CategoryTheory/Equivalence.lean index 977bf5da0969a4..24f7948bf55643 100644 --- a/Mathlib/CategoryTheory/Equivalence.lean +++ b/Mathlib/CategoryTheory/Equivalence.lean @@ -57,8 +57,8 @@ if it is full, faithful and essentially surjective. We write `C ≌ D` (`\backcong`, not to be confused with `≅`/`\cong`) for a bundled equivalence. -/ - set_option backward.defeqAttrib.useBackward true +set_option backward.isDefEq.respectTransparency.types false @[expose] public section @@ -109,6 +109,7 @@ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] namespace Equivalence +set_option backward.isDefEq.respectTransparency false in @[to_dual existing functor_unitIso_comp] theorem counitIso_functor_comp (e : C ≌ D) (X : C) : dsimp% e.counitIso.inv.app (e.functor.obj X) ≫ e.functor.map (e.unitIso.inv.app X) = @@ -116,6 +117,7 @@ theorem counitIso_functor_comp (e : C ≌ D) (X : C) : simpa [functor_unitIso_comp] using Iso.inv_eq_inv (e.functor.mapIso (e.unitIso.app X) ≪≫ e.counitIso.app (e.functor.obj X)) (Iso.refl _) +set_option backward.isDefEq.respectTransparency false in /-- `Equivalence.mk'` is the dual of `Equivalence.mk`, which we need for `to_dual`. Please avoid using this directly. -/ @[to_dual existing mk'] @@ -142,25 +144,25 @@ abbrev unit (e : C ≌ D) : 𝟭 C ⟶ e.functor ⋙ e.inverse := abbrev counit (e : C ≌ D) : e.inverse ⋙ e.functor ⟶ 𝟭 D := e.counitIso.hom -@[reassoc +to_dual (attr := simp)] +@[reassoc +to_dual] lemma unitIso_hom_inv_id_app (e : C ≌ D) (X : C) : - dsimp% e.unit.app X ≫ e.unitInv.app X = 𝟙 X := - e.unitIso.hom_inv_id_app X + dsimp% e.unit.app X ≫ e.unitInv.app X = 𝟙 X := by + simp -@[reassoc +to_dual (attr := simp)] +@[reassoc +to_dual] lemma unitIso_inv_hom_id_app (e : C ≌ D) (X : C) : - dsimp% e.unitInv.app X ≫ e.unit.app X = 𝟙 _ := - e.unitIso.inv_hom_id_app X + dsimp% e.unitInv.app X ≫ e.unit.app X = 𝟙 _ := by + simp -@[reassoc +to_dual (attr := simp)] +@[reassoc +to_dual] lemma counitIso_hom_inv_id_app (e : C ≌ D) (Y : D) : - dsimp% e.counit.app Y ≫ e.counitInv.app Y = 𝟙 _ := - e.counitIso.hom_inv_id_app Y + dsimp% e.counit.app Y ≫ e.counitInv.app Y = 𝟙 _ := by + simp -@[reassoc +to_dual (attr := simp)] +@[reassoc +to_dual] lemma counitIso_inv_hom_id_app (e : C ≌ D) (Y : D) : - dsimp% e.counitInv.app Y ≫ e.counit.app Y = 𝟙 Y := - e.counitIso.inv_hom_id_app Y + dsimp% e.counitInv.app Y ≫ e.counit.app Y = 𝟙 Y := by + simp section CategoryStructure @@ -263,12 +265,12 @@ theorem functor_unit_comp (e : C ≌ D) (X : C) : dsimp% e.functor.map (e.unit.app X) ≫ e.counit.app (e.functor.obj X) = 𝟙 (e.functor.obj X) := e.functor_unitIso_comp X +set_option backward.isDefEq.respectTransparency false in @[to_dual counitInv_app_functor] theorem counit_app_functor (e : C ≌ D) (X : C) : e.counit.app (e.functor.obj X) = e.functor.map (e.unitInv.app X) := by simpa using Iso.hom_comp_eq_id (e.functor.mapIso (e.unitIso.app X)) (f := e.counit.app _) -set_option backward.isDefEq.respectTransparency false in /-- The other triangle equality. The proof follows the following proof in Globular: http://globular.science/1905.001 -/ @[to_dual (attr := reassoc (attr := simp)) inverse_counitInv_comp] @@ -304,6 +306,7 @@ theorem unit_inverse_comp (e : C ≌ D) (Y : D) : rw [← map_comp e.inverse, e.counitInv_naturality, e.counitIso.hom_inv_id_app] simp +set_option backward.isDefEq.respectTransparency false in @[to_dual unitInv_app_inverse] theorem unit_app_inverse (e : C ≌ D) (Y : D) : e.unit.app (e.inverse.obj Y) = e.inverse.map (e.counitInv.app Y) := by @@ -337,6 +340,7 @@ def adjointifyη : 𝟭 C ≅ F ⋙ G := by _ ≅ 𝟭 C ⋙ F ⋙ G := isoWhiskerRight η.symm (F ⋙ G) _ ≅ F ⋙ G := leftUnitor (F ⋙ G) +set_option backward.isDefEq.respectTransparency false in @[reassoc] theorem adjointify_η_ε (X : C) : F.map ((adjointifyη η ε).hom.app X) ≫ ε.hom.app (F.obj X) = 𝟙 (F.obj X) := by @@ -380,7 +384,6 @@ lemma symm_unit (e : C ≌ D) : e.symm.unit = e.counitInv := rfl variable {E : Type u₃} [Category.{v₃} E] -set_option backward.isDefEq.respectTransparency false in /-- Equivalence of categories is transitive. -/ @[trans, simps] def trans (e : C ≌ D) (f : D ≌ E) : C ≌ E where @@ -456,51 +459,50 @@ section CancellationLemmas variable (e : C ≌ D) -set_option backward.isDefEq.respectTransparency false in /- We need special forms of `cancel_natIso_hom_right(_assoc)` and `cancel_natIso_inv_right(_assoc)` for units and counits, because neither `simp` or `rw` will apply those lemmas in this setting without providing `e.unitIso` (or similar) as an explicit argument. We also provide the lemmas for length four compositions, since they're occasionally useful. -(e.g. in proving that equivalences take monos to monos) -/ -@[to_dual (attr := simp) cancel_unitInv_left] +(e.g. in proving that equivalences take monos to monos) + +`cancel_unitInv_left` is not a `simp` lemma because it would be redundant. +-/ +@[to_dual cancel_unitInv_left, simp] theorem cancel_unit_right {X Y : C} (f f' : X ⟶ Y) : f ≫ e.unit.app Y = f' ≫ e.unit.app Y ↔ f = f' := by simp only [cancel_mono] -set_option backward.isDefEq.respectTransparency false in @[to_dual (attr := simp) cancel_unit_left] theorem cancel_unitInv_right {X Y : C} (f f' : X ⟶ e.inverse.obj (e.functor.obj Y)) : f ≫ e.unitInv.app Y = f' ≫ e.unitInv.app Y ↔ f = f' := by simp only [cancel_mono] -set_option backward.isDefEq.respectTransparency false in @[to_dual (attr := simp) cancel_counitInv_left] theorem cancel_counit_right {X Y : D} (f f' : X ⟶ e.functor.obj (e.inverse.obj Y)) : f ≫ e.counit.app Y = f' ≫ e.counit.app Y ↔ f = f' := by simp only [cancel_mono] +/- +`cancel_counit_left` is not a `simp` lemma because it would be redundant. +-/ set_option backward.isDefEq.respectTransparency false in -@[to_dual (attr := simp) cancel_counit_left] +@[to_dual cancel_counit_left, simp] theorem cancel_counitInv_right {X Y : D} (f f' : X ⟶ Y) : f ≫ e.counitInv.app Y = f' ≫ e.counitInv.app Y ↔ f = f' := by simp only [cancel_mono] -set_option backward.isDefEq.respectTransparency false in @[simp, to_dual none] theorem cancel_unit_right_assoc {W X X' Y : C} (f : W ⟶ X) (g : X ⟶ Y) (f' : W ⟶ X') (g' : X' ⟶ Y) : f ≫ g ≫ e.unit.app Y = f' ≫ g' ≫ e.unit.app Y ↔ f ≫ g = f' ≫ g' := by simp only [← Category.assoc, cancel_mono] -set_option backward.isDefEq.respectTransparency false in @[simp, to_dual none] theorem cancel_counitInv_right_assoc {W X X' Y : D} (f : W ⟶ X) (g : X ⟶ Y) (f' : W ⟶ X') (g' : X' ⟶ Y) : f ≫ g ≫ e.counitInv.app Y = f' ≫ g' ≫ e.counitInv.app Y ↔ f ≫ g = f' ≫ g' := by simp only [← Category.assoc, cancel_mono] -set_option backward.isDefEq.respectTransparency false in @[simp, to_dual none] theorem cancel_unit_right_assoc' {W X X' Y Y' Z : C} (f : W ⟶ X) (g : X ⟶ Y) (h : Y ⟶ Z) (f' : W ⟶ X') (g' : X' ⟶ Y') (h' : Y' ⟶ Z) : f ≫ g ≫ h ≫ e.unit.app Z = f' ≫ g' ≫ h' ≫ e.unit.app Z ↔ f ≫ g ≫ h = f' ≫ g' ≫ h' := by simp only [← Category.assoc, cancel_mono] -set_option backward.isDefEq.respectTransparency false in @[simp, to_dual none] theorem cancel_counitInv_right_assoc' {W X X' Y Y' Z : D} (f : W ⟶ X) (g : X ⟶ Y) (h : Y ⟶ Z) (f' : W ⟶ X') (g' : X' ⟶ Y') (h' : Y' ⟶ Z) : diff --git a/Mathlib/CategoryTheory/Equivalence/Symmetry.lean b/Mathlib/CategoryTheory/Equivalence/Symmetry.lean index f93fc316d7903a..dfa49661d16e16 100644 --- a/Mathlib/CategoryTheory/Equivalence/Symmetry.lean +++ b/Mathlib/CategoryTheory/Equivalence/Symmetry.lean @@ -37,6 +37,7 @@ namespace Equivalence variable (C : Type*) [Category* C] (D : Type*) [Category* D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The forward functor of the equivalence `(C ≌ D) ≌ (D ≌ C)ᵒᵖ`. -/ @[simps] @@ -45,6 +46,7 @@ def symmEquivFunctor : (C ≌ D) ⥤ (D ≌ C)ᵒᵖ where map {e f} α := (mkHom <| conjugateEquiv f.toAdjunction e.toAdjunction <| asNatTrans α).op map_comp _ _ := Quiver.Hom.unop_inj (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inverse functor of the equivalence `(C ≌ D) ≌ (D ≌ C)ᵒᵖ`. -/ @[simps!] @@ -73,6 +75,9 @@ def symmEquiv : (C ≌ D) ≌ (D ≌ C)ᵒᵖ where functor_unitIso_comp X := by simp [symm, symmEquivInverse] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The `inverse` functor that sends a functor to its inverse. -/ @[simps!] def inverseFunctor : (C ≌ D) ⥤ (D ⥤ C)ᵒᵖ := @@ -80,11 +85,13 @@ def inverseFunctor : (C ≌ D) ⥤ (D ⥤ C)ᵒᵖ := variable {C D} +set_option backward.isDefEq.respectTransparency.types false in /-- The `inverse` functor sends an equivalence to its inverse. -/ @[simps!] def inverseFunctorObjIso (e : C ≌ D) : (inverseFunctor C D).obj e ≅ Opposite.op e.inverse := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- We can compare the way we obtain a natural isomorphism `e.inverse ≅ f.inverse` from an isomorphism `e ≌ f` via `inverseFunctor` with the way we get one through `Iso.isoInverseOfIsoFunctor`. -/ @@ -93,12 +100,14 @@ lemma inverseFunctorMapIso_symm_eq_isoInverseOfIsoFunctor {e f : C ≌ D} (α : Iso.isoInverseOfIsoFunctor ((functorFunctor _ _).mapIso α) := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- An "unopped" version of the equivalence `inverseFunctorObj'`. -/ @[simps!] def inverseFunctorObj' (e : C ≌ D) : Opposite.unop ((inverseFunctor C D).obj e) ≅ e.inverse := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in variable (C D) in /-- Promoting `Equivalence.congrLeft` to a functor. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Extensive.lean b/Mathlib/CategoryTheory/Extensive.lean index 7b6f27b595f43c..e1d2ab84770354 100644 --- a/Mathlib/CategoryTheory/Extensive.lean +++ b/Mathlib/CategoryTheory/Extensive.lean @@ -207,6 +207,7 @@ theorem finitaryExtensive_iff_of_isTerminal (C : Type u) [Category.{v} C] [HasFi obtain ⟨hl, hr⟩ := (H c (HT.from _) (HT.from _) d hd.symm hd'.symm).mp ⟨hc⟩ rw [hl.paste_vert_iff hX.symm, hr.paste_vert_iff hY.symm] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance types.finitaryExtensive : FinitaryExtensive (Type u) := by classical @@ -308,6 +309,7 @@ noncomputable def finitaryExtensiveTopCatAux (Z : TopCat.{u}) convert! f.hom.2.1 _ isOpen_range_inr · convert! Set.isCompl_range_inl_range_inr.preimage f +set_option backward.isDefEq.respectTransparency.types false in instance finitaryExtensive_TopCat : FinitaryExtensive TopCat.{u} := by rw [finitaryExtensive_iff_of_isTerminal TopCat.{u} _ TopCat.isTerminalPUnit _ (TopCat.binaryCofanIsColimit _ _)] @@ -551,6 +553,7 @@ instance FinitaryPreExtensive.hasPullbacks_of_inclusions [FinitaryPreExtensive C apply FinitaryPreExtensive.hasPullbacks_of_is_coproduct (c := Cofan.mk Z i) exact @IsColimit.ofPointIso (t := Cofan.mk Z i) (P := _) (i := hi) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma FinitaryPreExtensive.isIso_sigmaDesc_fst [FinitaryPreExtensive C] {α : Type} [Finite α] {X : C} {Z : α → C} (π : (a : α) → Z a ⟶ X) {Y : C} (f : Y ⟶ X) (hπ : IsIso (Sigma.desc π)) : diff --git a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean index 0f0df6df1fc83e..974a5231129dca 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean @@ -32,7 +32,7 @@ universe v₅ u₅ v₄ u₄ v₃ u₃ v₂ u₂ v₁ u₁ namespace CategoryTheory -open Functor Category NatTrans IsHomLift +open CategoryTheory.Functor Category NatTrans IsHomLift variable {𝒮 : Type u₁} [Category.{v₁} 𝒮] @@ -281,6 +281,7 @@ instance : Category (BasedCategory.{v₂, u₂} 𝒮) where id := id comp := comp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The bicategory of based categories. -/ instance bicategory : Bicategory (BasedCategory.{v₂, u₂} 𝒮) where @@ -294,6 +295,7 @@ instance bicategory : Bicategory (BasedCategory.{v₂, u₂} 𝒮) where leftUnitor {_ _} F := BasedNatIso.id F rightUnitor {_ _} F := BasedNatIso.id F +set_option backward.isDefEq.respectTransparency.types false in /-- The bicategory structure on `BasedCategory.{v₂, u₂} 𝒮` is strict. -/ instance : Bicategory.Strict (BasedCategory.{v₂, u₂} 𝒮) where diff --git a/Mathlib/CategoryTheory/FiberedCategory/Fiber.lean b/Mathlib/CategoryTheory/FiberedCategory/Fiber.lean index 760a03fef90c0c..5bfd8f4da589af 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/Fiber.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/Fiber.lean @@ -63,6 +63,7 @@ instance : (fiberInclusion : Fiber p S ⥤ _).Faithful where lemma fiberInclusion_obj_inj : (fiberInclusion : Fiber p S ⥤ _).obj.Injective := fun _ _ f ↦ Subtype.val_inj.1 f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For fixed `S : 𝒮` this is the natural isomorphism between `fiberInclusion ⋙ p` and the constant function valued at `S`. -/ diff --git a/Mathlib/CategoryTheory/FiberedCategory/Fibered.lean b/Mathlib/CategoryTheory/FiberedCategory/Fibered.lean index 513d2d7ff5b38d..3cd8f10f308f4a 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/Fibered.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/Fibered.lean @@ -45,7 +45,7 @@ universe v₁ v₂ u₁ u₂ namespace CategoryTheory -open Functor Category IsHomLift +open CategoryTheory.Functor Category IsHomLift variable {𝒮 : Type u₁} {𝒳 : Type u₂} [Category.{v₁} 𝒮] [Category.{v₂} 𝒳] @@ -95,7 +95,7 @@ end Functor.IsPreFibered namespace Functor.IsFibered -open IsCartesian IsPreFibered +open IsCartesian Functor.IsPreFibered /-- In a fibered category, any Cartesian morphism is strongly Cartesian. -/ instance isStronglyCartesian_of_isCartesian (p : 𝒳 ⥤ 𝒮) [p.IsFibered] {R S : 𝒮} (f : R ⟶ S) diff --git a/Mathlib/CategoryTheory/FiberedCategory/Grothendieck.lean b/Mathlib/CategoryTheory/FiberedCategory/Grothendieck.lean index 842c34c53cde56..eb29037f64eab6 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/Grothendieck.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/Grothendieck.lean @@ -27,7 +27,7 @@ Angelo Vistoli namespace CategoryTheory.Pseudofunctor.CoGrothendieck -open Functor Opposite Bicategory Fiber +open CategoryTheory.Functor Opposite Bicategory Fiber variable {𝒮 : Type*} [Category* 𝒮] {F : LocallyDiscrete 𝒮ᵒᵖ ⥤ᵖ Cat} @@ -44,6 +44,7 @@ abbrev cartesianLift : domainCartesianLift a f ⟶ ⟨S, a⟩ := ⟨f, 𝟙 _⟩ instance isHomLift_cartesianLift : IsHomLift (forget F) f (cartesianLift a f) := IsHomLift.map (forget F) (cartesianLift a f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {a} in /-- Given some lift `φ'` of `g ≫ f`, the canonical map from the domain of `φ'` to the domain of @@ -55,6 +56,7 @@ abbrev homCartesianLift {a' : ∫ᶜ F} (g : a'.1 ⟶ R) (φ' : a' ⟶ ⟨S, a have : φ'.base = g ≫ f := by simpa using IsHomLift.fac' (forget F) (g ≫ f) φ' φ'.fiber ≫ eqToHom (by simp [this]) ≫ (F.mapComp f.op.toLoc g.op.toLoc).hom.toNatTrans.app a +set_option backward.isDefEq.respectTransparency.types false in instance isHomLift_homCartesianLift {a' : ∫ᶜ F} {φ' : a' ⟶ ⟨S, a⟩} {g : a'.1 ⟶ R} [IsHomLift (forget F) (g ≫ f) φ'] : IsHomLift (forget F) g (homCartesianLift f g φ') := IsHomLift.map (forget F) (homCartesianLift f g φ') @@ -93,6 +95,9 @@ def ι : F.obj ⟨op S⟩ ⥤ ∫ᶜ F where · simp [← (F.mapId ⟨op S⟩).inv.toNatTrans.naturality_assoc ψ, F.whiskerRight_mapId_inv_app, Strict.leftUnitor_eqToIso, ← Cat.Hom₂.comp_app] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The natural isomorphism encoding `comp_const`. -/ @[simps!] def compIso : (ι F S) ⋙ forget F ≅ (const (F.obj ⟨op S⟩)).obj S := diff --git a/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean b/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean index 18d798ebab7cd3..424a4bd3cbe677 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/HasFibers.lean @@ -78,7 +78,7 @@ class HasFibers (p : 𝒳 ⥤ 𝒮) where namespace HasFibers /-- The `HasFibers` on `p : 𝒳 ⥤ 𝒮` given by the fibers of `p` -/ -@[implicit_reducible] +@[instance_reducible] def canonical (p : 𝒳 ⥤ 𝒮) : HasFibers p where Fib := Fiber p ι S := fiberInclusion @@ -124,6 +124,7 @@ def projMap {R S : 𝒮} {a : Fib p R} {b : Fib p S} (φ : (ι R).obj a ⟶ (ι S).obj b) : R ⟶ S := eqToHom (proj_eq a).symm ≫ (p.map φ) ≫ eqToHom (proj_eq b) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For any homomorphism `φ` in a fiber `Fib S`, its image under `ι S` lies over `𝟙 S`. -/ instance homLift {S : 𝒮} {a b : Fib p S} (φ : a ⟶ b) : IsHomLift p (𝟙 S) ((ι S).map φ) := by diff --git a/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean b/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean index eca167cd40f154..b4d3226a77c27f 100644 --- a/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean +++ b/Mathlib/CategoryTheory/Filtered/CostructuredArrow.lean @@ -27,7 +27,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor section Small diff --git a/Mathlib/CategoryTheory/Filtered/Final.lean b/Mathlib/CategoryTheory/Filtered/Final.lean index 506f1e8bc02c20..e95e325f1a0c1e 100644 --- a/Mathlib/CategoryTheory/Filtered/Final.lean +++ b/Mathlib/CategoryTheory/Filtered/Final.lean @@ -212,6 +212,7 @@ instance IsCofiltered.over [IsCofilteredOrEmpty C] (c : C) : IsCofiltered (Over isCofiltered_costructuredArrow_of_isCofiltered_of_exists _ c ⟨c, ⟨𝟙 _⟩⟩ (fun s s' => IsCofilteredOrEmpty.cone_maps s s') +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The forgetful functor of the under category on any filtered or empty category is final. -/ instance Under.final_forget [IsFilteredOrEmpty C] (c : C) : Final (Under.forget c) := @@ -223,6 +224,7 @@ instance Under.final_forget [IsFilteredOrEmpty C] (c : C) : Final (Under.forget simp only [forget_obj, mk_right, forget_map, homMk_right] rw [IsFiltered.coeq_condition]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The forgetful functor of the over category on any cofiltered or empty category is initial. -/ instance Over.initial_forget [IsCofilteredOrEmpty C] (c : C) : Initial (Over.forget c) := @@ -239,7 +241,6 @@ section LocallySmall variable {C : Type v₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₁} D] (F : C ⥤ D) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Implementation; use `Functor.Final.exists_coeq instead`. -/ theorem Functor.Final.exists_coeq_of_locally_small [IsFilteredOrEmpty C] [Final F] {d : D} {c : C} (s s' : d ⟶ F.obj c) : ∃ (c' : C) (t : c ⟶ c'), s ≫ F.map t = s' ≫ F.map t := by @@ -254,6 +255,7 @@ theorem Functor.Final.exists_coeq_of_locally_small [IsFilteredOrEmpty C] [Final end LocallySmall +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `C` is filtered, then we can give an explicit condition for a functor `F : C ⥤ D` to be final. -/ @@ -377,7 +379,6 @@ instance CostructuredArrow.initial_proj_of_isCofiltered [IsCofilteredOrEmpty C] rw [isConnected_iff_of_equivalence (ofCostructuredArrowProjEquivalence T Y X)] exact (initial_comp (Over.forget X) T).out _ -set_option backward.isDefEq.respectTransparency false in /-- The functor `StructuredArrow d T ⥤ StructuredArrow e (T ⋙ S)` that `u : e ⟶ S.obj d` induces via `StructuredArrow.map₂` is final, if `T` and `S` are final and the domain of `T` is filtered. -/ @@ -389,7 +390,6 @@ instance StructuredArrow.final_map₂_id [IsFiltered C] {E : Type u₃} [Categor (T ⋙ S).final_iff_isFiltered_structuredArrow.mp inferInstance e apply final_of_natIso (map₂IsoPreEquivalenceInverseCompProj d e u α).symm -set_option backward.isDefEq.respectTransparency false in /-- `StructuredArrow.map` is final if the functor `T` is final and its domain is filtered. -/ instance StructuredArrow.final_map [IsFiltered C] {S S' : D} (f : S ⟶ S') (T : C ⥤ D) [T.Final] : Final (map (T := T) f) := by @@ -404,6 +404,7 @@ instance StructuredArrow.final_post [IsFiltered C] {E : Type u₃} [Category.{v (T : C ⥤ D) [T.Final] (S : D ⥤ E) [S.Final] : Final (post X T S) := by apply final_of_natIso (postIsoMap₂ X T S).symm +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `CostructuredArrow T d ⥤ CostructuredArrow (T ⋙ S) e` that `u : S.obj d ⟶ e` induces via `CostructuredArrow.map₂` is initial, if `T` and `S` are initial and the domain of `T` is filtered. -/ diff --git a/Mathlib/CategoryTheory/Filtered/Grothendieck.lean b/Mathlib/CategoryTheory/Filtered/Grothendieck.lean index 1653fc92955552..8f5691181d4e67 100644 --- a/Mathlib/CategoryTheory/Filtered/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Filtered/Grothendieck.lean @@ -25,6 +25,7 @@ variable {C : Type u} [Category.{v} C] (F : C ⥤ Cat) open IsFiltered +set_option backward.isDefEq.respectTransparency.types false in instance [IsFilteredOrEmpty C] [∀ c, IsFilteredOrEmpty (F.obj c)] : IsFilteredOrEmpty (Grothendieck F) := by refine ⟨?_, ?_⟩ @@ -38,7 +39,8 @@ instance [IsFilteredOrEmpty C] [∀ c, IsFilteredOrEmpty (F.obj c)] : ⟨coeqHom u v, coeqHom _ _⟩, ?_⟩ · conv_rhs => rw [← Cat.Hom.comp_obj, ← F.map_comp, coeq_condition, F.map_comp, Cat.Hom.comp_obj] - · apply Grothendieck.ext _ _ (coeq_condition u v) + · set_option backward.isDefEq.respectTransparency.types false in + apply Grothendieck.ext _ _ (coeq_condition u v) refine Eq.trans ?_ (eqToHom _ ≫= coeq_condition _ _) simp diff --git a/Mathlib/CategoryTheory/FinCategory/AsType.lean b/Mathlib/CategoryTheory/FinCategory/AsType.lean index 5fe1e4c0b6fcfa..a6e164203eb44c 100644 --- a/Mathlib/CategoryTheory/FinCategory/AsType.lean +++ b/Mathlib/CategoryTheory/FinCategory/AsType.lean @@ -41,6 +41,7 @@ noncomputable def objAsTypeEquiv : ObjAsType α ≌ α := abbrev AsType : Type := Fin (Fintype.card α) +set_option backward.isDefEq.respectTransparency.types false in @[simps -isSimp id comp] noncomputable instance categoryAsType : SmallCategory (AsType α) where Hom i j := Fin (Fintype.card (@Quiver.Hom (ObjAsType α) _ i j)) @@ -49,6 +50,7 @@ noncomputable instance categoryAsType : SmallCategory (AsType α) where attribute [local simp] categoryAsType_id categoryAsType_comp +set_option backward.isDefEq.respectTransparency.types false in /-- The "identity" functor from `AsType α` to `ObjAsType α`. -/ @[simps] noncomputable def asTypeToObjAsType : AsType α ⥤ ObjAsType α where diff --git a/Mathlib/CategoryTheory/FintypeCat.lean b/Mathlib/CategoryTheory/FintypeCat.lean index ff92984006e916..4fa0b1cc0a68c6 100644 --- a/Mathlib/CategoryTheory/FintypeCat.lean +++ b/Mathlib/CategoryTheory/FintypeCat.lean @@ -47,7 +47,7 @@ instance {X : FintypeCat} : Finite X := /-- A `Fintype` instance on objects on `FintypeCat`, that should be turned on as needed. Prefer the `Finite` instance if possible. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintype {X : FintypeCat} : Fintype X := Fintype.ofFinite X.obj @@ -215,6 +215,7 @@ instance : incl.Faithful where map_injective h := by simpa using TypeCat.homEquiv.symm.injective (InducedCategory.homEquiv.symm.injective h) +set_option backward.isDefEq.respectTransparency.types false in instance : incl.EssSurj := Functor.EssSurj.mk fun X => letI := X.fintype @@ -286,7 +287,6 @@ lemma uSwitch_map_uSwitch_map {X Y : FintypeCat.{u}} (f : X ⟶ Y) : Y.uSwitchEquiv)).inv := rfl set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in attribute [local simp] uSwitch_map_uSwitch_map in /-- `uSwitch.{u, v}` is an equivalence of categories with quasi-inverse `uSwitch.{v, u}`. -/ noncomputable def uSwitchEquivalence : FintypeCat.{u} ≌ FintypeCat.{v} where diff --git a/Mathlib/CategoryTheory/Functor/Basic.lean b/Mathlib/CategoryTheory/Functor/Basic.lean index 9031718383e63f..593211de97c933 100644 --- a/Mathlib/CategoryTheory/Functor/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/Basic.lean @@ -78,6 +78,7 @@ initialize_simps_projections Functor -- We don't use `@[simps]` here because we want `C` implicit for the simp lemmas. /-- `𝟭 C` is the identity functor on a category `C`. -/ +@[implicit_reducible] protected def id : C ⥤ C where obj X := X map f := f @@ -114,7 +115,7 @@ theorem congr_map (F : C ⥤ D) {X Y : C} {f g : X ⟶ Y} /-- `F ⋙ G` is the composition of a functor `F` and a functor `G` (`F` first, then `G`). -/ -@[simps (attr := grind =) obj] +@[simps (attr := grind =) obj, implicit_reducible] def comp (F : C ⥤ D) (G : D ⥤ E) : C ⥤ E where obj X := G.obj (F.obj X) map f := G.map (F.map f) diff --git a/Mathlib/CategoryTheory/Functor/Const.lean b/Mathlib/CategoryTheory/Functor/Const.lean index bda33f17f1d728..e530356200e8e9 100644 --- a/Mathlib/CategoryTheory/Functor/Const.lean +++ b/Mathlib/CategoryTheory/Functor/Const.lean @@ -32,7 +32,7 @@ variable {C : Type u₂} [Category.{v₂} C] /-- The functor sending `X : C` to the constant functor `J ⥤ C` sending everything to `X`. -/ -@[simps] +@[simps, implicit_reducible] def const : C ⥤ J ⥤ C where obj X := { obj := fun _ => X @@ -98,6 +98,7 @@ def constComp (X : C) (F : C ⥤ D) : (const J).obj X ⋙ F ≅ (const J).obj (F instance [Nonempty J] : Faithful (const J : C ⥤ J ⥤ C) where map_injective e := NatTrans.congr_app e (Classical.arbitrary J) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism `F ⋙ Functor.const J ≅ Functor.const F ⋙ (whiskeringRight J _ _).obj L`. -/ @@ -108,6 +109,7 @@ def compConstIso (F : C ⥤ D) : (fun X => NatIso.ofComponents (fun _ => Iso.refl _) (by simp)) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism `const D ⋙ (whiskeringLeft J _ _).obj F ≅ const J` -/ diff --git a/Mathlib/CategoryTheory/Functor/Currying.lean b/Mathlib/CategoryTheory/Functor/Currying.lean index 3ba90b52b22a85..d003000bce6b9b 100644 --- a/Mathlib/CategoryTheory/Functor/Currying.lean +++ b/Mathlib/CategoryTheory/Functor/Currying.lean @@ -25,7 +25,7 @@ namespace CategoryTheory namespace Functor -open scoped Prod +open scoped CategoryTheory.Prod universe v₁ v₂ v₃ v₄ v₅ u₁ u₂ u₃ u₄ u₅ @@ -34,7 +34,7 @@ variable {B : Type u₁} [Category.{v₁} B] {C : Type u₂} [Category.{v₂} C] /-- The uncurrying functor, taking a functor `C ⥤ (D ⥤ E)` and producing a functor `(C × D) ⥤ E`. -/ -@[simps] +@[simps, implicit_reducible] def uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E where obj F := { obj := fun X => (F.obj X.1).obj X.2 @@ -81,6 +81,7 @@ def curry : (C × D ⥤ E) ⥤ C ⥤ D ⥤ E where ext; dsimp [curryObj] rw [NatTrans.naturality] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- create projection simp lemmas even though this isn't a `{ .. }`. /-- The equivalence of functor categories given by currying/uncurrying. @@ -97,6 +98,7 @@ def currying : C ⥤ D ⥤ E ≌ C × D ⥤ E where dsimp at f₁ f₂ ⊢ simp only [← F.map_comp, prod_comp, Category.comp_id, Category.id_comp])) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of functor categories given by flipping. -/ @[simps!] @@ -108,10 +110,12 @@ def flipping : C ⥤ D ⥤ E ≌ D ⥤ C ⥤ E where counitIso := NatIso.ofComponents (fun _ ↦ NatIso.ofComponents (fun _ ↦ NatIso.ofComponents (fun _ ↦ Iso.refl _))) +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E` is fully faithful. -/ def fullyFaithfulUncurry : (uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E).FullyFaithful := currying.fullyFaithfulFunctor +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `curry : (C × D ⥤ E) ⥤ C ⥤ D ⥤ E` is fully faithful. -/ def fullyFaithfulCurry : (curry : (C × D ⥤ E) ⥤ C ⥤ D ⥤ E).FullyFaithful := currying.fullyFaithfulInverse @@ -128,6 +132,7 @@ instance : (uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E).Full := instance : (uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E).Faithful := fullyFaithfulUncurry.faithful +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given functors `F₁ : C ⥤ D`, `F₂ : C' ⥤ D'` and `G : D × D' ⥤ E`, this is the isomorphism between `curry.obj ((F₁.prod F₂).comp G)` and @@ -139,6 +144,7 @@ def curryObjProdComp {C' D' : Type*} [Category* C'] [Category* D'] F₁ ⋙ curry.obj G ⋙ (whiskeringLeft C' D' E).obj F₂ := NatIso.ofComponents (fun X₁ ↦ NatIso.ofComponents (fun X₂ ↦ Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `F.flip` is isomorphic to uncurrying `F`, swapping the variables, and currying. -/ @[simps!] @@ -154,6 +160,9 @@ def uncurryObjFlip (F : C ⥤ D ⥤ E) : uncurry.obj F.flip ≅ Prod.swap _ _ variable (B C D E) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A version of `CategoryTheory.whiskeringRight` for bifunctors, obtained by uncurrying, applying `whiskeringRight` and currying back -/ @@ -164,6 +173,7 @@ def whiskeringRight₂ : (C ⥤ D ⥤ E) ⥤ (B ⥤ C) ⥤ (B ⥤ D) ⥤ B ⥤ E variable {B C D E} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma uncurry_obj_curry_obj (F : B × C ⥤ D) : uncurry.obj (curry.obj F) = F := Functor.ext (by simp) (fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ ⟨f₁, f₂⟩ => by @@ -174,6 +184,7 @@ lemma curry_obj_injective {F₁ F₂ : C × D ⥤ E} (h : curry.obj F₁ = curry F₁ = F₂ := by rw [← uncurry_obj_curry_obj F₁, ← uncurry_obj_curry_obj F₂, h] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma curry_obj_uncurry_obj (F : B ⥤ C ⥤ D) : curry.obj (uncurry.obj F) = F := Functor.ext (fun _ => Functor.ext (by simp) (by simp)) (by cat_disch) @@ -188,6 +199,7 @@ lemma flip_injective {F₁ F₂ : B ⥤ C ⥤ D} (h : F₁.flip = F₂.flip) : F₁ = F₂ := by rw [← flip_flip F₁, ← flip_flip F₂, h] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma uncurry_obj_curry_obj_flip_flip (F₁ : B ⥤ C) (F₂ : D ⥤ E) (G : C × E ⥤ H) : uncurry.obj (F₂ ⋙ (F₁ ⋙ curry.obj G).flip).flip = (F₁.prod F₂) ⋙ G := @@ -195,6 +207,7 @@ lemma uncurry_obj_curry_obj_flip_flip (F₁ : B ⥤ C) (F₂ : D ⥤ E) (G : C dsimp simp only [Category.id_comp, Category.comp_id, ← G.map_comp, prod_comp]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma uncurry_obj_curry_obj_flip_flip' (F₁ : B ⥤ C) (F₂ : D ⥤ E) (G : C × E ⥤ H) : uncurry.obj (F₁ ⋙ (F₂ ⋙ (curry.obj G).flip).flip) = (F₁.prod F₂) ⋙ G := diff --git a/Mathlib/CategoryTheory/Functor/CurryingThree.lean b/Mathlib/CategoryTheory/Functor/CurryingThree.lean index 163a4d1426d871..9cf3402b9c0115 100644 --- a/Mathlib/CategoryTheory/Functor/CurryingThree.lean +++ b/Mathlib/CategoryTheory/Functor/CurryingThree.lean @@ -80,6 +80,7 @@ lemma curry₃_map_app_app_app {F G : C₁ × C₂ × C₃ ⥤ E} (f : F ⟶ G) (X₁ : C₁) (X₂ : C₂) (X₃ : C₃) : (((curry₃.map f).app X₁).app X₂).app X₃ = f.app ⟨X₁, X₂, X₃⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma currying₃_unitIso_hom_app_app_app_app (F : C₁ ⥤ C₂ ⥤ C₃ ⥤ E) @@ -87,6 +88,7 @@ lemma currying₃_unitIso_hom_app_app_app_app (F : C₁ ⥤ C₂ ⥤ C₃ ⥤ E) (((currying₃.unitIso.hom.app F).app X₁).app X₂).app X₃ = 𝟙 _ := by simp [currying₃, Equivalence.unit] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma currying₃_unitIso_inv_app_app_app_app (F : C₁ ⥤ C₂ ⥤ C₃ ⥤ E) @@ -108,6 +110,7 @@ def curry₃ObjProdComp (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) (F₃ : C (fun X₁ ↦ NatIso.ofComponents (fun X₂ ↦ NatIso.ofComponents (fun X₃ ↦ Iso.refl _))) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `bifunctorComp₁₂` can be described in terms of the curryfication of functors. -/ @[simps!] @@ -115,6 +118,7 @@ def bifunctorComp₁₂Iso (F₁₂ : C₁ ⥤ C₂ ⥤ C₁₂) (G : C₁₂ bifunctorComp₁₂ F₁₂ G ≅ curry.obj (uncurry.obj F₁₂ ⋙ G) := NatIso.ofComponents (fun _ => NatIso.ofComponents (fun _ => Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `bifunctorComp₂₃` can be described in terms of the curryfication of functors. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Functor/Derived/Adjunction.lean b/Mathlib/CategoryTheory/Functor/Derived/Adjunction.lean index 2221068716b42e..4dcd66278ba5eb 100644 --- a/Mathlib/CategoryTheory/Functor/Derived/Adjunction.lean +++ b/Mathlib/CategoryTheory/Functor/Derived/Adjunction.lean @@ -44,10 +44,9 @@ variable {C₁ C₂ D₁ D₂ : Type*} [Category* C₁] [Category* C₂] [Catego namespace Adjunction -open Functor +open CategoryTheory.Functor set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `Adjunction.derived`. -/ @[simps] def derived' [G'.IsLeftDerivedFunctor α W₁] [F'.IsRightDerivedFunctor β W₂] @@ -133,7 +132,6 @@ lemma derivedε_fac_app (X₂ : C₂) : end -set_option backward.isDefEq.respectTransparency false in /-- An adjunction between functors induces an adjunction between the corresponding left/right derived functors, when these derived functors are *absolute*, i.e. they remain derived functors diff --git a/Mathlib/CategoryTheory/Functor/Derived/PointwiseLeftDerived.lean b/Mathlib/CategoryTheory/Functor/Derived/PointwiseLeftDerived.lean index e422f7ccbd9d05..aca955efbca848 100644 --- a/Mathlib/CategoryTheory/Functor/Derived/PointwiseLeftDerived.lean +++ b/Mathlib/CategoryTheory/Functor/Derived/PointwiseLeftDerived.lean @@ -108,8 +108,8 @@ section variable {F L} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- If `L : C ⥤ D` is a localization functor for `W` and `e : F ≅ L ⋙ G` is an isomorphism, then `e.inv` makes `G` a pointwise right Kan extension of `F` along `L` at `L.obj Y` for any `Y : C`. -/ diff --git a/Mathlib/CategoryTheory/Functor/Derived/PointwiseRightDerived.lean b/Mathlib/CategoryTheory/Functor/Derived/PointwiseRightDerived.lean index 4dd2501b6893be..936b5f033d9fa9 100644 --- a/Mathlib/CategoryTheory/Functor/Derived/PointwiseRightDerived.lean +++ b/Mathlib/CategoryTheory/Functor/Derived/PointwiseRightDerived.lean @@ -107,8 +107,8 @@ section variable {F L} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- If `L : C ⥤ D` is a localization functor for `W` and `e : F ≅ L ⋙ G` is an isomorphism, then `e.hom` makes `G` a pointwise left Kan extension of `F` along `L` at `L.obj Y` for any `Y : C`. -/ diff --git a/Mathlib/CategoryTheory/Functor/EpiMono.lean b/Mathlib/CategoryTheory/Functor/EpiMono.lean index 8d1d05f730cb25..7908da42e8d1bc 100644 --- a/Mathlib/CategoryTheory/Functor/EpiMono.lean +++ b/Mathlib/CategoryTheory/Functor/EpiMono.lean @@ -67,14 +67,12 @@ theorem epi_of_epi_map (F : C ⥤ D) [ReflectsEpimorphisms F] {X Y : C} {f : X (h : Epi (F.map f)) : Epi f := ReflectsEpimorphisms.reflects f h -set_option backward.isDefEq.respectTransparency false in instance preservesMonomorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesMonomorphisms F] [PreservesMonomorphisms G] : PreservesMonomorphisms (F ⋙ G) where preserves f h := by rw [comp_map] exact inferInstance -set_option backward.isDefEq.respectTransparency false in instance preservesEpimorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesEpimorphisms F] [PreservesEpimorphisms G] : PreservesEpimorphisms (F ⋙ G) where preserves f h := by diff --git a/Mathlib/CategoryTheory/Functor/Flat.lean b/Mathlib/CategoryTheory/Functor/Flat.lean index 99352559888677..fc6017432cd147 100644 --- a/Mathlib/CategoryTheory/Functor/Flat.lean +++ b/Mathlib/CategoryTheory/Functor/Flat.lean @@ -180,6 +180,7 @@ open StructuredArrow variable {J : Type v₁} [SmallCategory J] [FinCategory J] {K : J ⥤ C} variable (F : C ⥤ D) [RepresentablyFlat F] {c : Cone K} (hc : IsLimit c) (s : Cone (K ⋙ F)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- (Implementation). Given a limit cone `c : cone K` and a cone `s : cone (K ⋙ F)` with `F` representably flat, diff --git a/Mathlib/CategoryTheory/Functor/FullyFaithful.lean b/Mathlib/CategoryTheory/Functor/FullyFaithful.lean index df388bbf5931f1..d7b7098026f9a8 100644 --- a/Mathlib/CategoryTheory/Functor/FullyFaithful.lean +++ b/Mathlib/CategoryTheory/Functor/FullyFaithful.lean @@ -217,6 +217,7 @@ def isoEquiv {X Y : C} : (X ≅ Y) ≃ (F.obj X ≅ F.obj Y) where left_inv := by cat_disch right_inv := by cat_disch +set_option backward.isDefEq.respectTransparency false in /-- Fully faithful functors are stable by composition. -/ @[simps] def comp {G : D ⥤ E} (hG : G.FullyFaithful) : (F ⋙ G).FullyFaithful where @@ -350,6 +351,7 @@ theorem Faithful.div_faithful (F : C ⥤ E) [F.Faithful] (G : D ⥤ E) [G.Faithf Functor.Faithful (Faithful.div F G obj @h_obj @map @h_map) := (Faithful.div_comp F G _ h_obj _ @h_map).faithful_of_comp +set_option backward.isDefEq.respectTransparency false in instance Full.comp [Full F] [Full G] : Full (F ⋙ G) where map_surjective f := ⟨F.preimage (G.preimage f), by simp⟩ @@ -363,6 +365,7 @@ lemma Full.of_comp_faithful_iso {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} [Full have := Full.of_iso h.symm exact Full.of_comp_faithful F G +set_option backward.isDefEq.respectTransparency false in /-- Given a natural isomorphism between `F ⋙ H` and `G ⋙ H` for a fully faithful functor `H`, we can 'cancel' it to give a natural iso between `F` and `G`. -/ diff --git a/Mathlib/CategoryTheory/Functor/FunctorHom.lean b/Mathlib/CategoryTheory/Functor/FunctorHom.lean index 29e13d9da2b210..711689e7153c6a 100644 --- a/Mathlib/CategoryTheory/Functor/FunctorHom.lean +++ b/Mathlib/CategoryTheory/Functor/FunctorHom.lean @@ -201,6 +201,7 @@ lemma associator_hom_apply (K L M N : C ⥤ D) {X : C} dsimp% (α_ ((K.functorHom L).obj X) ((L.functorHom M).obj X) ((M.functorHom N).obj X)).hom x = ⟨x.1.1, x.1.2, x.2⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in attribute [local simp] functorHom types_tensorObj_def in instance : EnrichedCategory (C ⥤ Type (max v' v u)) (C ⥤ D) where Hom := functorHom diff --git a/Mathlib/CategoryTheory/Functor/Functorial.lean b/Mathlib/CategoryTheory/Functor/Functorial.lean index 0ccf44c8d7bd1d..cd38c5e2c1ef84 100644 --- a/Mathlib/CategoryTheory/Functor/Functorial.lean +++ b/Mathlib/CategoryTheory/Functor/Functorial.lean @@ -65,7 +65,7 @@ variable {E : Type u₃} [Category.{v₃} E] -- Will this be a problem? /-- `G ∘ F` is a functorial if both `F` and `G` are. -/ -@[implicit_reducible] +@[instance_reducible] def functorial_comp (F : C → D) [Functorial.{v₁, v₂} F] (G : D → E) [Functorial.{v₂, v₃} G] : Functorial.{v₁, v₃} (G ∘ F) := { Functor.of F ⋙ Functor.of G with map := fun f => map G (map F f) } diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/Adjunction.lean b/Mathlib/CategoryTheory/Functor/KanExtension/Adjunction.lean index dabb7a27d6ecab..d1666bfb12ba47 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/Adjunction.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/Adjunction.lean @@ -242,6 +242,7 @@ lemma ι_colimitIsoColimitGrothendieck_inv (X : Grothendieck (CostructuredArrow. colimit.ι G ((CostructuredArrow.proj L X.base).obj X.fiber) := by simp [colimitIsoColimitGrothendieck] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ι_colimitIsoColimitGrothendieck_hom (X : C) : colimit.ι G X ≫ (colimitIsoColimitGrothendieck L G).hom = @@ -305,7 +306,6 @@ instance (F : C ⥤ H) : (L.ran.obj F).IsRightKanExtension (L.ranCounit.app F) : dsimp [ran, ranCounit] infer_instance -set_option backward.isDefEq.respectTransparency false in /-- If there exists a pointwise right Kan extension of `F` along `L`, then `L.ran.obj G` is a pointwise right Kan extension of `F`. -/ noncomputable def isPointwiseRightKanExtensionRanCounit diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean b/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean index ddda48b185e5df..1d8ed3b224af14 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean @@ -38,7 +38,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open Category Limits Functor +open Category Limits namespace Functor @@ -319,7 +319,7 @@ variable {L : C ⥤ D} {L' : C ⥤ D'} (G : D ⥤ D') /-- The functor `LeftExtension L' F ⥤ LeftExtension L F` induced by a natural transformation `L' ⟶ L ⋙ G'`. -/ -@[simps!] +@[simps!, implicit_reducible] def LeftExtension.postcomp₁ (f : L' ⟶ L ⋙ G) (F : C ⥤ H) : LeftExtension L' F ⥤ LeftExtension L F := StructuredArrow.map₂ (F := (whiskeringLeft D D' H).obj G) (G := 𝟭 _) (𝟙 _) @@ -327,7 +327,7 @@ def LeftExtension.postcomp₁ (f : L' ⟶ L ⋙ G) (F : C ⥤ H) : /-- The functor `RightExtension L' F ⥤ RightExtension L F` induced by a natural transformation `L ⋙ G ⟶ L'`. -/ -@[simps!] +@[simps!, implicit_reducible] def RightExtension.postcomp₁ (f : L ⋙ G ⟶ L') (F : C ⥤ H) : RightExtension L' F ⥤ RightExtension L F := CostructuredArrow.map₂ (F := (whiskeringLeft D D' H).obj G) (G := 𝟭 _) @@ -371,6 +371,7 @@ noncomputable def RightExtension.isUniversalPostcomp₁Equiv (ex : RightExtensio variable {F F'} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isLeftKanExtension_iff_postcomp₁ (α : F ⟶ L' ⋙ F') : F'.IsLeftKanExtension α ↔ (G ⋙ F').IsLeftKanExtension @@ -384,6 +385,7 @@ lemma isLeftKanExtension_iff_postcomp₁ (α : F ⟶ L' ⋙ F') : · exact fun _ => ⟨⟨eq (isUniversalOfIsLeftKanExtension _ _)⟩⟩ · exact fun _ => ⟨⟨eq.symm (isUniversalOfIsLeftKanExtension _ _)⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isRightKanExtension_iff_postcomp₁ (α : L' ⋙ F' ⟶ F) : F'.IsRightKanExtension α ↔ (G ⋙ F').IsRightKanExtension @@ -407,7 +409,7 @@ set_option backward.defeqAttrib.useBackward true in /-- Given a left extension `E` of `F : C ⥤ H` along `L : C ⥤ D` and a functor `G : H ⥤ D'`, `E.postcompose₂ G` is the extension of `F ⋙ G` along `L` obtained by whiskering by `G` on the right. -/ -@[simps!] +@[simps!, implicit_reducible] def LeftExtension.postcompose₂ : LeftExtension L F ⥤ LeftExtension L (F ⋙ G) := StructuredArrow.map₂ (F := (whiskeringRight _ _ _).obj G) @@ -418,7 +420,7 @@ set_option backward.defeqAttrib.useBackward true in /-- Given a right extension `E` of `F : C ⥤ H` along `L : C ⥤ D` and a functor `G : H ⥤ D'`, `E.postcompose₂ G` is the extension of `F ⋙ G` along `L` obtained by whiskering by `G` on the right. -/ -@[simps!] +@[simps!, implicit_reducible] def RightExtension.postcompose₂ : RightExtension L F ⥤ RightExtension L (F ⋙ G) := CostructuredArrow.map₂ (F := (whiskeringRight _ _ _).obj G) @@ -426,6 +428,7 @@ def RightExtension.postcompose₂ : RightExtension L F ⥤ RightExtension L (F ({ app _ := associator _ _ _ |>.inv }) (𝟙 _) variable {L F} {F' : D ⥤ H} +set_option backward.isDefEq.respectTransparency.types false in /-- An isomorphism to describe the action of `LeftExtension.postcompose₂` on terms of the form `LeftExtension.mk _ α`. -/ @[simps!] @@ -434,6 +437,7 @@ def LeftExtension.postcompose₂ObjMkIso (α : F ⟶ L ⋙ F') : .mk (F' ⋙ G) <| whiskerRight α G ≫ (associator _ _ _).hom := StructuredArrow.isoMk (.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An isomorphism to describe the action of `RightExtension.postcompose₂` on terms of the form `RightExtension.mk _ α`. -/ @@ -451,13 +455,13 @@ variable (L : C ⥤ D) (F : C ⥤ H) (F' : D ⥤ H) (G : C' ⥤ C) /-- The functor `LeftExtension L F ⥤ LeftExtension (G ⋙ L) (G ⋙ F)` obtained by precomposition. -/ -@[simps!] +@[simps!, implicit_reducible] def LeftExtension.precomp : LeftExtension L F ⥤ LeftExtension (G ⋙ L) (G ⋙ F) := StructuredArrow.map₂ (F := 𝟭 _) (G := (whiskeringLeft C' C H).obj G) (𝟙 _) (𝟙 _) /-- The functor `RightExtension L F ⥤ RightExtension (G ⋙ L) (G ⋙ F)` obtained by precomposition. -/ -@[simps!] +@[simps!, implicit_reducible] def RightExtension.precomp : RightExtension L F ⥤ RightExtension (G ⋙ L) (G ⋙ F) := CostructuredArrow.map₂ (F := 𝟭 _) (G := (whiskeringLeft C' C H).obj G) (𝟙 _) (𝟙 _) @@ -485,6 +489,7 @@ noncomputable def RightExtension.isUniversalPrecompEquiv (e : RightExtension L F variable {F L} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isLeftKanExtension_iff_precomp (α : F ⟶ L ⋙ F') : F'.IsLeftKanExtension α ↔ F'.IsLeftKanExtension @@ -497,6 +502,7 @@ lemma isLeftKanExtension_iff_precomp (α : F ⟶ L ⋙ F') : · exact fun _ => ⟨⟨eq (isUniversalOfIsLeftKanExtension _ _)⟩⟩ · exact fun _ => ⟨⟨eq.symm (isUniversalOfIsLeftKanExtension _ _)⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isRightKanExtension_iff_precomp (α : L ⋙ F' ⟶ F) : F'.IsRightKanExtension α ↔ @@ -517,6 +523,7 @@ variable {L L' : C ⥤ D} (iso₁ : L ≅ L') (F : C ⥤ H) /-- The equivalence `RightExtension L F ≌ RightExtension L' F` induced by a natural isomorphism `L ≅ L'`. -/ +-- TODO: Should this be `@[simps!]` too? def rightExtensionEquivalenceOfIso₁ : RightExtension L F ≌ RightExtension L' F := CostructuredArrow.mapNatIso ((whiskeringLeft C D H).mapIso iso₁) @@ -524,9 +531,12 @@ include iso₁ in lemma hasRightExtension_iff_of_iso₁ : HasRightKanExtension L F ↔ HasRightKanExtension L' F := (rightExtensionEquivalenceOfIso₁ iso₁ F).hasTerminal_iff +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence `LeftExtension L F ≌ LeftExtension L' F` induced by a natural isomorphism `L ≅ L'`. -/ -@[simps!] +@[simps!, implicit_reducible] def leftExtensionEquivalenceOfIso₁ : LeftExtension L F ≌ LeftExtension L' F := StructuredArrow.mapNatIso ((whiskeringLeft C D H).mapIso iso₁) @@ -586,6 +596,7 @@ lemma isLeftKanExtension_iff_of_iso₂ {F₁' F₂' : D ⥤ H} (α₁ : F₁ ⟶ · exact fun _ => ⟨⟨eq.1 (isUniversalOfIsLeftKanExtension F₁' α₁)⟩⟩ · exact fun _ => ⟨⟨eq.2 (isUniversalOfIsLeftKanExtension F₂' α₂)⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- When two right extensions `α₁ : RightExtension L F₁` and `α₂ : RightExtension L F₂` are essentially the same via an isomorphism of functors `F₁ ≅ F₂`, then `α₁` is universal iff `α₂` is. -/ @@ -672,6 +683,7 @@ def LeftExtension.isUniversalPrecomp₂ simp [← a_w_t, hb_fac_app, u, hα_fac_app] apply IsInitial.ofUnique +set_option backward.isDefEq.respectTransparency.types false in /-- If the left extension defined by `α : F₀ ⟶ L ⋙ F₁` is universal, then for every `L' : D ⥤ D'`, `F₁ : D ⥤ H`, if an extension `b : L'.LeftExtension F₁` is such that the "pasted" extension @@ -716,7 +728,7 @@ def LeftExtension.isUniversalPrecomp₂Equiv right_inv x := by subsingleton -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in theorem isLeftKanExtension_iff_postcompose [F₁.IsLeftKanExtension α] {F₂ : D' ⥤ H} (L'' : C ⥤ D') (e : L ⋙ L' ≅ L'') (β : F₁ ⟶ L' ⋙ F₂) (γ : F₀ ⟶ L'' ⋙ F₂) @@ -807,7 +819,7 @@ variable (F' : D ⥤ H) {L : C ⥤ D} {F : C ⥤ H} (α : L ⋙ F' ⟶ F) [F'.Is /-- Construct a cone for a right Kan extension `F' : D ⥤ H` of `F : C ⥤ H` along a functor `L : C ⥤ D` given a cone for `F`. -/ -@[simps] +@[simps, implicit_reducible] noncomputable def coneOfIsRightKanExtension (c : Cone F) : Cone F' where pt := c.pt π := F'.liftOfIsRightKanExtension α _ c.π @@ -839,7 +851,6 @@ noncomputable def limitIsoOfIsRightKanExtension : limit F' ≅ limit F := IsLimit.conePointUniqueUpToIso (limit.isLimit F') (F'.isLimitConeOfIsRightKanExtension α (limit.isLimit F)) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma limitIsoOfIsRightKanExtension_inv_π (i : C) : (F'.limitIsoOfIsRightKanExtension α).inv ≫ limit.π F' (L.obj i) ≫ α.app i = limit.π F i := by @@ -864,7 +875,7 @@ variable (F₀) in instance isRightKanExtensionId : F₀.IsRightKanExtension F₀.leftUnitor.hom where nonempty_isUniversal := ⟨CostructuredArrow.mkIdTerminal⟩ -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in instance isLeftKanExtensionAlongEquivalence (α : F₀ ≅ L.functor ⋙ F₁) : F₁.IsLeftKanExtension α.hom := by refine ⟨⟨?_⟩⟩ diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean b/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean index fc2769652643b5..a84e75222efb3f 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/DenseAt.lean @@ -62,6 +62,7 @@ if `Y` and `Y'` are isomorphic. -/ def DenseAt.ofIso {Y' : D} (e : Y ≅ Y') : F.DenseAt Y' := LeftExtension.isPointwiseLeftKanExtensionAtOfIso' _ hY e +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ D` is dense at `Y : D`, and `G` is a functor that is isomorphic to `F`, then `G` is also dense at `Y`. -/ @@ -87,6 +88,7 @@ noncomputable def DenseAt.precompOfFinal (G ⋙ F).DenseAt Y := (DenseAt.precompEquivOfFinal G).symm hY +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ D` is dense at `Y : D` and `G : D ⥤ D'` is an equivalence, then `F ⋙ G` is dense at `G.obj Y`. -/ diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/Pointwise.lean b/Mathlib/CategoryTheory/Functor/KanExtension/Pointwise.lean index 03ca3a94b8c6e4..eca4f781a97fc9 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/Pointwise.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/Pointwise.lean @@ -220,7 +220,6 @@ variable {F L} variable (E : LeftExtension L F) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The cocone for `CostructuredArrow.proj L Y ⋙ F` attached to `E : LeftExtension L F`. The point of this cocone is `E.right.obj Y` -/ @[simps] @@ -234,6 +233,7 @@ def coconeAt (Y : D) : Cocone (CostructuredArrow.proj L Y ⋙ F) where simp only [NatTrans.naturality_assoc, Functor.comp_map, Functor.map_comp, comp_id] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (L F) in /-- The cocones for `CostructuredArrow.proj L Y ⋙ F`, as a functor from `LeftExtension L F`. -/ @@ -258,12 +258,14 @@ lemma IsPointwiseLeftKanExtensionAt.hasPointwiseLeftKanExtensionAt {Y : D} (h : E.IsPointwiseLeftKanExtensionAt Y) : HasPointwiseLeftKanExtensionAt L F Y := ⟨_, h⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma IsPointwiseLeftKanExtensionAt.isIso_hom_app {X : C} (h : E.IsPointwiseLeftKanExtensionAt (L.obj X)) [L.Full] [L.Faithful] : IsIso (E.hom.app X) := by simpa using h.isIso_ι_app_of_isTerminal _ CostructuredArrow.mkIdTerminal +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The condition of being a pointwise left Kan extension at an object `Y` is unchanged by replacing `Y` by an isomorphic object `Y'`. -/ @@ -273,6 +275,7 @@ def isPointwiseLeftKanExtensionAtOfIso' IsColimit.ofIsoColimit (hY.whiskerEquivalence (CostructuredArrow.mapIso e.symm)) (Cocone.ext (E.right.mapIso e)) +set_option backward.isDefEq.respectTransparency.types false in /-- The condition of being a pointwise left Kan extension at an object `Y` is unchanged by replacing `Y` by an isomorphic object `Y'`. -/ def isPointwiseLeftKanExtensionAtEquivOfIso' {Y Y' : D} (e : Y ≅ Y') : @@ -286,6 +289,7 @@ namespace IsPointwiseLeftKanExtensionAt variable {E} {Y : D} (h : E.IsPointwiseLeftKanExtensionAt Y) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in include h in lemma hom_ext' {T : H} {f g : E.right.obj Y ⟶ T} @@ -293,6 +297,7 @@ lemma hom_ext' {T : H} {f g : E.right.obj Y ⟶ T} E.hom.app X ≫ E.right.map φ ≫ f = E.hom.app X ≫ E.right.map φ ≫ g) : f = g := h.hom_ext (fun j ↦ by simpa using hfg j.hom) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma comp_homEquiv_symm {Z : H} @@ -314,6 +319,7 @@ lemma ι_isoColimit_inv (g : CostructuredArrow L Y) : colimit.ι _ g ≫ h.isoColimit.inv = E.hom.app g.left ≫ E.right.map g.hom := IsColimit.comp_coconePointUniqueUpToIso_inv _ _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma ι_isoColimit_hom (g : CostructuredArrow L Y) : @@ -372,6 +378,7 @@ def IsPointwiseLeftKanExtension.homFrom (G : LeftExtension L F) : E ⟶ G := ext X simpa using (h (L.obj X)).fac (LeftExtension.coconeAt G _) (CostructuredArrow.mk (𝟙 _))) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma IsPointwiseLeftKanExtension.hom_ext {G : LeftExtension L F} {f₁ f₂ : E ⟶ G} : f₁ = f₂ := by @@ -453,6 +460,7 @@ lemma IsPointwiseRightKanExtensionAt.isIso_hom_app IsIso (E.hom.app X) := by simpa using h.isIso_π_app_of_isInitial _ StructuredArrow.mkIdInitial +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The condition of being a pointwise right Kan extension at an object `Y` is unchanged by replacing `Y` by an isomorphic object `Y'`. -/ @@ -462,6 +470,7 @@ def isPointwiseRightKanExtensionAtOfIso' IsLimit.ofIsoLimit (hY.whiskerEquivalence (StructuredArrow.mapIso e.symm)) (Cone.ext (E.left.mapIso e)) +set_option backward.isDefEq.respectTransparency.types false in /-- The condition of being a pointwise right Kan extension at an object `Y` is unchanged by replacing `Y` by an isomorphic object `Y'`. -/ def isPointwiseRightKanExtensionAtEquivOfIso' {Y Y' : D} (e : Y ≅ Y') : @@ -651,7 +660,6 @@ instance : HasLeftKanExtension L F := HasLeftKanExtension.mk _ (pointwiseLeftKanExtensionUnit L F) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- An auxiliary cocone used in the lemma `pointwiseLeftKanExtension_desc_app` -/ @[simps] def costructuredArrowMapCocone (G : D ⥤ H) (α : F ⟶ L ⋙ G) (Y : D) : @@ -759,7 +767,6 @@ instance : HasRightKanExtension L F := HasRightKanExtension.mk _ (pointwiseRightKanExtensionCounit L F) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- An auxiliary cocone used in the lemma `pointwiseRightKanExtension_lift_app` -/ @[simps] def structuredArrowMapCone (G : D ⥤ H) (α : L ⋙ G ⟶ F) (Y : D) : diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/Preserves.lean b/Mathlib/CategoryTheory/Functor/KanExtension/Preserves.lean index 15e4a2f66dcc41..45b4a5d2bc31f5 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/Preserves.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/Preserves.lean @@ -51,7 +51,6 @@ lemma PreservesLeftKanExtension.mk' ⟨⟨Limits.IsInitial.equivOfIso (LeftExtension.postcompose₂ObjMkIso _ _) <| (preserves h.nonempty_isUniversal.some).some⟩⟩ -set_option backward.isDefEq.respectTransparency false in /-- Show that `G` preserves left Kan extensions if it maps some left Kan extension to a left Kan extension. -/ lemma PreservesLeftKanExtension.mk_of_preserves_isLeftKanExtension @@ -107,6 +106,7 @@ def LeftExtension.IsPointwiseLeftKanExtension.postcompose LeftExtension.postcompose₂ L F G |>.obj E |>.IsPointwiseLeftKanExtension := fun c ↦ (hE c).postcompose G +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The cocone at a point of the whiskering right by `G` of an extension is isomorphic to the action of `G` on the cocone at that point for the original extension. -/ @@ -237,6 +237,7 @@ lemma pointwiseLeftKanExtensionCompIsoOfPreserves_hom_fac : (α := whiskerRight (L.pointwiseLeftKanExtensionUnit F) G ≫ (Functor.associator _ _ _).hom) (β := L.pointwiseLeftKanExtensionUnit <| F ⋙ G) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma pointwiseLeftKanExtensionCompIsoOfPreserves_hom_fac_app (a : A) : @@ -274,7 +275,6 @@ abbrev PreservesPointwiseLeftKanExtensions := ∀ (F : A ⥤ B), G.PreservesPointwiseLeftKanExtension F L set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Commuting a functor that preserves left Kan extensions with the `lan` functor. -/ @[simps!] def lanCompIsoOfPreserves [G.PreservesLeftKanExtensions L] @@ -367,6 +367,7 @@ def RightExtension.IsPointwiseRightKanExtension.postcompose RightExtension.postcompose₂ L F G |>.obj E |>.IsPointwiseRightKanExtension := fun c ↦ (hE c).postcompose G +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The cone at a point of the whiskering right by `G` of an extension is isomorphic to the action of `G` on the cone at that point for the original extension. -/ @@ -421,7 +422,6 @@ lemma rightKanExtensionCompIsoOfPreserves_hom_fac : (Functor.associator _ _ _).inv ≫ whiskerRight (L.rightKanExtensionCounit F) G := by simp [rightKanExtensionCompIsoOfPreserves] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma rightKanExtensionCompIsoOfPreserves_hom_fac_app (a : A) : (G.rightKanExtensionCompIsoOfPreserves F L).hom.app (L.obj a) ≫ diff --git a/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean b/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean index b317846095c902..a6814f53b75531 100644 --- a/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/ReflectsIso/Basic.lean @@ -23,7 +23,7 @@ public section namespace CategoryTheory -open Functor +open CategoryTheory.Functor variable {C : Type*} [Category* C] {D : Type*} [Category* D] diff --git a/Mathlib/CategoryTheory/Functor/ReflectsIso/Jointly.lean b/Mathlib/CategoryTheory/Functor/ReflectsIso/Jointly.lean index 7bff77c9a45407..06cef52b9c490a 100644 --- a/Mathlib/CategoryTheory/Functor/ReflectsIso/Jointly.lean +++ b/Mathlib/CategoryTheory/Functor/ReflectsIso/Jointly.lean @@ -50,6 +50,7 @@ structure JointlyFaithful (F : ∀ i, C ⥤ D i) : Prop where variable {F : ∀ i, C ⥤ D i} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma JointlyFaithful.of_jointly_reflects_isIso_of_mono [HasEqualizers C] [∀ i, PreservesLimitsOfShape WalkingParallelPair (F i)] diff --git a/Mathlib/CategoryTheory/Functor/ReflectsIso/Limits.lean b/Mathlib/CategoryTheory/Functor/ReflectsIso/Limits.lean index ecabd9af3b0829..5766047aca3247 100644 --- a/Mathlib/CategoryTheory/Functor/ReflectsIso/Limits.lean +++ b/Mathlib/CategoryTheory/Functor/ReflectsIso/Limits.lean @@ -26,6 +26,7 @@ variable {C : Type*} [Category C] {I : Type*} {D : I → Type*} [∀ i, Category {F : ∀ i, C ⥤ D i} (hF : JointlyReflectIsomorphisms F) {J : Type*} [Category* J] {G : J ⥤ C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `Fᵢ : C ⥤ Dᵢ` is a conservative family of functors which also preserve the (existing) limit of a functor `G : J ⥤ C`, then a cone @@ -51,6 +52,7 @@ noncomputable def jointlyReflectsLimit rw [← this] infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `Fᵢ : C ⥤ Dᵢ` is a conservative family of functors which also preserve the (existing) colimit of a functor `G : J ⥤ C`, then a cocone diff --git a/Mathlib/CategoryTheory/Functor/RegularEpi.lean b/Mathlib/CategoryTheory/Functor/RegularEpi.lean index ee15857c11b944..96ebe576a8c3af 100644 --- a/Mathlib/CategoryTheory/Functor/RegularEpi.lean +++ b/Mathlib/CategoryTheory/Functor/RegularEpi.lean @@ -27,6 +27,7 @@ open Limits variable {C D : Type*} [Category C] [Category D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [∀ {F G : D} (f : F ⟶ G) [Epi f], HasPullback f f] [HasPushouts D] [IsRegularEpiCategory D] : diff --git a/Mathlib/CategoryTheory/Functor/Trifunctor.lean b/Mathlib/CategoryTheory/Functor/Trifunctor.lean index 1409aea4f3d58d..d2fe02db515ba6 100644 --- a/Mathlib/CategoryTheory/Functor/Trifunctor.lean +++ b/Mathlib/CategoryTheory/Functor/Trifunctor.lean @@ -54,6 +54,7 @@ def bifunctorComp₁₂ (F₁₂ : C₁ ⥤ C₂ ⥤ C₁₂) (G : C₁₂ ⥤ C simp only [← NatTrans.comp_app, ← G.map_comp, NatTrans.naturality] } set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `bifunctorComp₁₂Functor`. -/ @[simps] def bifunctorComp₁₂FunctorObj (F₁₂ : C₁ ⥤ C₂ ⥤ C₁₂) : @@ -73,6 +74,7 @@ def bifunctorComp₁₂FunctorObj (F₁₂ : C₁ ⥤ C₂ ⥤ C₁₂) : simp only [← NatTrans.comp_app, NatTrans.naturality] } set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `bifunctorComp₁₂Functor`. -/ @[simps] def bifunctorComp₁₂FunctorMap {F₁₂ F₁₂' : C₁ ⥤ C₂ ⥤ C₁₂} (φ : F₁₂ ⟶ F₁₂') : @@ -130,6 +132,7 @@ def bifunctorComp₂₃ (F : C₁ ⥤ C₂₃ ⥤ C₄) (G₂₃ : C₂ ⥤ C₃ { app := fun X₃ => (F.map φ).app ((G₂₃.obj X₂).obj X₃) } } set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `bifunctorComp₂₃Functor`. -/ @[simps] def bifunctorComp₂₃FunctorObj (F : C₁ ⥤ C₂₃ ⥤ C₄) : @@ -148,6 +151,7 @@ def bifunctorComp₂₃FunctorObj (F : C₁ ⥤ C₂₃ ⥤ C₄) : simp only [← NatTrans.comp_app, ← Functor.map_comp, NatTrans.naturality] } } set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `bifunctorComp₂₃Functor`. -/ @[simps] def bifunctorComp₂₃FunctorMap {F F' : C₁ ⥤ C₂₃ ⥤ C₄} (φ : F ⟶ F') : diff --git a/Mathlib/CategoryTheory/Functor/TwoSquare.lean b/Mathlib/CategoryTheory/Functor/TwoSquare.lean index 5d3bae08382f06..866509a6363160 100644 --- a/Mathlib/CategoryTheory/Functor/TwoSquare.lean +++ b/Mathlib/CategoryTheory/Functor/TwoSquare.lean @@ -38,7 +38,7 @@ universe v₁ v₂ v₃ v₄ v₅ v₆ v₇ v₈ v₉ u₁ u₂ u₃ u₄ u₅ u namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} {C₃ : Type u₃} {C₄ : Type u₄} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} C₃] [Category.{v₄} C₄] @@ -150,7 +150,6 @@ section Interchange variable {C₉ : Type u₉} [Category.{v₉} C₉] {R₃ : C₆ ⥤ C₉} {B₃ : C₈ ⥤ C₉} set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- When composing 2-squares which form a diagram of grid, composing horizontally first yields the same result as composing vertically first. -/ lemma hCompVCompHComp (w₁ : TwoSquare T L R B) (w₂ : TwoSquare T' R R' B') diff --git a/Mathlib/CategoryTheory/Galois/Action.lean b/Mathlib/CategoryTheory/Galois/Action.lean index 7984a7fab63ff5..13464c99149288 100644 --- a/Mathlib/CategoryTheory/Galois/Action.lean +++ b/Mathlib/CategoryTheory/Galois/Action.lean @@ -28,7 +28,7 @@ namespace CategoryTheory namespace PreGaloisCategory -open Limits Functor +open Limits CategoryTheory.Functor variable {C : Type*} [Category* C] (F : C ⥤ FintypeCat.{u}) diff --git a/Mathlib/CategoryTheory/Galois/Basic.lean b/Mathlib/CategoryTheory/Galois/Basic.lean index a09a71f7f31d2c..caa99925ca4147 100644 --- a/Mathlib/CategoryTheory/Galois/Basic.lean +++ b/Mathlib/CategoryTheory/Galois/Basic.lean @@ -51,7 +51,7 @@ universe u₁ u₂ v₁ v₂ w t namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor /-! A category `C` is a PreGalois category if it satisfies all properties @@ -249,7 +249,7 @@ noncomputable def fiberEqualizerEquiv {X Y : C} (f g : X ⟶ Y) : lemma fiberEqualizerEquiv_symm_ι_apply {X Y : C} {f g : X ⟶ Y} (x : F.obj X) (h : F.map f x = F.map g x) : F.map (equalizer.ι f g) ((fiberEqualizerEquiv F f g).symm ⟨x, h⟩) = x := by - simp only [fiberEqualizerEquiv, Functor.comp_map, Iso.toEquiv_comp] + simp only [fiberEqualizerEquiv, Functor.comp_map] change ((Types.equalizerIso _ _).inv ≫ _ ≫ (F ⋙ FintypeCat.incl).map (equalizer.ι f g)) _ = _ erw [PreservesEqualizer.iso_inv_ι, Types.equalizerIso_inv_comp_ι] rfl @@ -264,8 +264,7 @@ noncomputable def fiberPullbackEquiv {X A B : C} (f : A ⟶ X) (g : B ⟶ X) : lemma fiberPullbackEquiv_symm_fst_apply {X A B : C} {f : A ⟶ X} {g : B ⟶ X} (a : F.obj A) (b : F.obj B) (h : F.map f a = F.map g b) : F.map (pullback.fst f g) ((fiberPullbackEquiv F f g).symm ⟨(a, b), h⟩) = a := by - simp only [fiberPullbackEquiv, Functor.comp_map, Iso.toEquiv_comp, - Equiv.symm_trans_apply, Iso.toEquiv_symm_fun] + simp only [fiberPullbackEquiv, Functor.comp_map, Iso.toEquiv_symm_fun] change ((Types.pullbackIsoPullback _ _).inv ≫ _ ≫ (F ⋙ FintypeCat.incl).map (pullback.fst f g)) _ = _ erw [PreservesPullback.iso_inv_fst, Types.pullbackIsoPullback_inv_fst] @@ -275,8 +274,7 @@ lemma fiberPullbackEquiv_symm_fst_apply {X A B : C} {f : A ⟶ X} {g : B ⟶ X} lemma fiberPullbackEquiv_symm_snd_apply {X A B : C} {f : A ⟶ X} {g : B ⟶ X} (a : F.obj A) (b : F.obj B) (h : F.map f a = F.map g b) : F.map (pullback.snd f g) ((fiberPullbackEquiv F f g).symm ⟨(a, b), h⟩) = b := by - simp only [fiberPullbackEquiv, Functor.comp_map, Iso.toEquiv_comp, - Equiv.symm_trans_apply, Iso.toEquiv_symm_fun] + simp only [fiberPullbackEquiv, Functor.comp_map, Iso.toEquiv_symm_fun] change ((Types.pullbackIsoPullback _ _).inv ≫ _ ≫ (F ⋙ FintypeCat.incl).map (pullback.snd f g)) _ = _ erw [PreservesPullback.iso_inv_snd, Types.pullbackIsoPullback_inv_snd] @@ -291,7 +289,7 @@ noncomputable def fiberBinaryProductEquiv (X Y : C) : @[simp] lemma fiberBinaryProductEquiv_symm_fst_apply {X Y : C} (x : F.obj X) (y : F.obj Y) : F.map prod.fst ((fiberBinaryProductEquiv F X Y).symm (x, y)) = x := by - simp only [fiberBinaryProductEquiv, Iso.toEquiv_comp] + simp only [fiberBinaryProductEquiv] change ((Types.binaryProductIso _ _).inv ≫ _ ≫ (F ⋙ FintypeCat.incl).map prod.fst) _ = _ erw [PreservesLimitPair.iso_inv_fst, Types.binaryProductIso_inv_comp_fst] rfl @@ -299,7 +297,7 @@ lemma fiberBinaryProductEquiv_symm_fst_apply {X Y : C} (x : F.obj X) (y : F.obj @[simp] lemma fiberBinaryProductEquiv_symm_snd_apply {X Y : C} (x : F.obj X) (y : F.obj Y) : F.map prod.snd ((fiberBinaryProductEquiv F X Y).symm (x, y)) = y := by - simp only [fiberBinaryProductEquiv, Iso.toEquiv_comp] + simp only [fiberBinaryProductEquiv] change ((Types.binaryProductIso _ _).inv ≫ _ ≫ (F ⋙ FintypeCat.incl).map prod.snd) _ = _ erw [PreservesLimitPair.iso_inv_snd, Types.binaryProductIso_inv_comp_snd] rfl diff --git a/Mathlib/CategoryTheory/Galois/Decomposition.lean b/Mathlib/CategoryTheory/Galois/Decomposition.lean index 5dde41f88e87c5..1734191c3ed3d5 100644 --- a/Mathlib/CategoryTheory/Galois/Decomposition.lean +++ b/Mathlib/CategoryTheory/Galois/Decomposition.lean @@ -39,7 +39,7 @@ universe u₁ u₂ w namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor variable {C : Type u₁} [Category.{u₂} C] @@ -58,6 +58,7 @@ non-trivial subobjects which have strictly smaller fiber and conclude by the ind -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The trivial case if `X` is connected. -/ private lemma has_decomp_connected_components_aux_conn (X : C) [IsConnected X] : @@ -243,9 +244,11 @@ set_option backward.privateInPublic true in private noncomputable def selfProdPermIncl (b : F.obj A) : A ⟶ selfProd F X := u ≫ (Pi.whiskerEquiv (fiberPerm h b) (fun _ => Iso.refl X)).inv +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in private instance [Mono u] (b : F.obj A) : Mono (selfProdPermIncl h b) := mono_comp _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- Key technical lemma: the twisted inclusion `selfProdPermIncl h b` maps `a` to `F.map u b`. -/ private lemma selfProdTermIncl_fib_eq (b : F.obj A) : diff --git a/Mathlib/CategoryTheory/Galois/Equivalence.lean b/Mathlib/CategoryTheory/Galois/Equivalence.lean index e9629f623eefa8..b9a93390813563 100644 --- a/Mathlib/CategoryTheory/Galois/Equivalence.lean +++ b/Mathlib/CategoryTheory/Galois/Equivalence.lean @@ -40,9 +40,11 @@ variable (F) in def functorToContAction : C ⥤ ContAction FintypeCat (Aut F) := ObjectProperty.lift _ (functorToAction F) (fun X ↦ continuousSMul_aut_fiber F X) +set_option backward.isDefEq.respectTransparency.types false in instance : (functorToContAction F).Faithful := inferInstanceAs <| (ObjectProperty.lift _ _ _).Faithful +set_option backward.isDefEq.respectTransparency.types false in instance : (functorToContAction F).Full := inferInstanceAs <| (ObjectProperty.lift _ _ _).Full diff --git a/Mathlib/CategoryTheory/Galois/EssSurj.lean b/Mathlib/CategoryTheory/Galois/EssSurj.lean index 70857ca5969333..046b2cc7be48ca 100644 --- a/Mathlib/CategoryTheory/Galois/EssSurj.lean +++ b/Mathlib/CategoryTheory/Galois/EssSurj.lean @@ -49,7 +49,7 @@ namespace PreGaloisCategory variable {C : Type u₁} [Category.{u₂} C] {F : C ⥤ FintypeCat.{u₁}} -open Limits Functor +open Limits CategoryTheory.Functor variable [GaloisCategory C] [FiberFunctor F] diff --git a/Mathlib/CategoryTheory/Galois/Examples.lean b/Mathlib/CategoryTheory/Galois/Examples.lean index 63002611a87534..7894942aacce32 100644 --- a/Mathlib/CategoryTheory/Galois/Examples.lean +++ b/Mathlib/CategoryTheory/Galois/Examples.lean @@ -25,7 +25,7 @@ universe u v w namespace CategoryTheory -open Limits Functor PreGaloisCategory +open Limits CategoryTheory.Functor PreGaloisCategory namespace FintypeCat diff --git a/Mathlib/CategoryTheory/Galois/Full.lean b/Mathlib/CategoryTheory/Galois/Full.lean index e63bb1a322bde5..d5d4dca3bf12c9 100644 --- a/Mathlib/CategoryTheory/Galois/Full.lean +++ b/Mathlib/CategoryTheory/Galois/Full.lean @@ -36,7 +36,7 @@ namespace CategoryTheory namespace PreGaloisCategory -open Limits Functor +open Limits CategoryTheory.Functor variable {C : Type*} [Category* C] (F : C ⥤ FintypeCat.{u}) [GaloisCategory C] [FiberFunctor F] diff --git a/Mathlib/CategoryTheory/Galois/GaloisObjects.lean b/Mathlib/CategoryTheory/Galois/GaloisObjects.lean index d6bddab93e3d71..ce474a0bd36806 100644 --- a/Mathlib/CategoryTheory/Galois/GaloisObjects.lean +++ b/Mathlib/CategoryTheory/Galois/GaloisObjects.lean @@ -35,7 +35,7 @@ namespace CategoryTheory namespace PreGaloisCategory -open Limits Functor +open Limits CategoryTheory.Functor noncomputable instance {G : Type v} [Group G] [Finite G] : PreservesColimitsOfShape (SingleObj G) FintypeCat.incl.{w} := by @@ -195,6 +195,7 @@ lemma autMap_surjective_of_isGalois {A B : C} [IsGalois A] [IsGalois B] (f : A apply evaluation_aut_injective_of_isConnected F B (F.map f a) simp [hτ, ha'] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma autMap_apply_mul {A B : C} [IsConnected A] [IsGalois B] (f : A ⟶ B) (σ τ : Aut A) : autMap f (σ * τ) = autMap f σ * autMap f τ := by diff --git a/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean b/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean index 5cdcfb7e782300..6da799592e2563 100644 --- a/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean +++ b/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean @@ -56,7 +56,7 @@ namespace CategoryTheory namespace PreGaloisCategory -open Limits Functor +open Limits variable {C : Type u₁} [Category.{u₂} C] (F : C ⥤ FintypeCat.{w}) @@ -132,6 +132,7 @@ lemma toAut_continuous [TopologicalSpace G] [IsTopologicalGroup G] variable {G} +set_option backward.isDefEq.respectTransparency.types false in lemma action_ext_of_isGalois {t : F ⟶ F} {X : C} [IsGalois X] {g : G} (x : F.obj X) (hg : g • x = t.app X x) (y : F.obj X) : g • y = t.app X y := by obtain ⟨φ, (rfl : F.map φ.hom y = x)⟩ := MulAction.exists_smul_eq (Aut X) y x diff --git a/Mathlib/CategoryTheory/Galois/Prorepresentability.lean b/Mathlib/CategoryTheory/Galois/Prorepresentability.lean index 753fe0ed691300..79832d7f2c2d82 100644 --- a/Mathlib/CategoryTheory/Galois/Prorepresentability.lean +++ b/Mathlib/CategoryTheory/Galois/Prorepresentability.lean @@ -63,7 +63,7 @@ namespace CategoryTheory namespace PreGaloisCategory -open Limits Functor +open Limits CategoryTheory.Functor variable {C : Type u₁} [Category.{u₂} C] [GaloisCategory C] @@ -354,6 +354,7 @@ lemma endEquivAutGalois_π (f : End F) (A : PointedGaloisObject F) : simp only [endEquivSectionsFibers_π] erw [evaluationEquivOfIsGalois_symm_fiber] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem endEquivAutGalois_mul (f g : End F) : (endEquivAutGalois F) (g ≫ f) = (endEquivAutGalois F g) * (endEquivAutGalois F f) := by @@ -394,10 +395,11 @@ noncomputable def autMulEquivAutGalois : Aut F ≃* (AutGalois F)ᵐᵒᵖ where MulEquiv.symm_apply_apply] exact Aut.ext rfl right_inv t := by - simp only [MonoidHom.coe_comp, MonoidHom.coe_coe, Function.comp_apply, Aut.toEnd_apply] + simp only [MonoidHom.coe_comp, MonoidHom.coe_coe] exact (MulEquiv.eq_symm_apply (endMulEquivAutGalois F)).mp rfl map_mul' := by simp [map_mul] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma autMulEquivAutGalois_π (f : Aut F) (A : C) [IsGalois A] (a : F.obj A) : F.map (AutGalois.π F { obj := A, pt := a } (autMulEquivAutGalois F f).unop).hom a = @@ -406,6 +408,7 @@ lemma autMulEquivAutGalois_π (f : Aut F) (A : C) [IsGalois A] (a : F.obj A) : rw [endEquivAutGalois_π] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma autMulEquivAutGalois_symm_app (x : AutGalois F) (A : C) [IsGalois A] (a : F.obj A) : ((autMulEquivAutGalois F).symm ⟨x⟩).hom.app A a = @@ -447,6 +450,7 @@ section General variable (F : C ⥤ FintypeCat.{w}) [FiberFunctor F] +set_option backward.isDefEq.respectTransparency.types false in /-- The `Aut F` action on the fiber of a connected object is transitive. -/ instance FiberFunctor.isPretransitive_of_isConnected (X : C) [IsConnected X] : MulAction.IsPretransitive (Aut F) (F.obj X) where diff --git a/Mathlib/CategoryTheory/Galois/Topology.lean b/Mathlib/CategoryTheory/Galois/Topology.lean index 8cea1acfba7216..b31abecc3adaed 100644 --- a/Mathlib/CategoryTheory/Galois/Topology.lean +++ b/Mathlib/CategoryTheory/Galois/Topology.lean @@ -34,7 +34,7 @@ namespace CategoryTheory namespace PreGaloisCategory -open Functor +open CategoryTheory.Functor variable {C : Type u₁} [Category.{u₂} C] (F : C ⥤ FintypeCat.{w}) @@ -47,6 +47,7 @@ def autEmbedding : Aut F →* ∀ X, Aut (F.obj X) := lemma autEmbedding_apply (σ : Aut F) (X : C) : autEmbedding F σ X = σ.app X := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma autEmbedding_injective : Function.Injective (autEmbedding F) := by intro σ τ h ext X x @@ -86,6 +87,7 @@ instance : TopologicalSpace (Aut F) := · use NatIso.ofComponents a (fun {X Y} f ↦ h ⟨X, Y, f⟩) rfl-/ +set_option backward.isDefEq.respectTransparency.types false in /-- The image of `Aut F` in `∀ X, Aut (F.obj X)` are precisely the compatible families of automorphisms. -/ lemma autEmbedding_range : diff --git a/Mathlib/CategoryTheory/Generator/Basic.lean b/Mathlib/CategoryTheory/Generator/Basic.lean index 734040759580d7..ac0615c38f9d73 100644 --- a/Mathlib/CategoryTheory/Generator/Basic.lean +++ b/Mathlib/CategoryTheory/Generator/Basic.lean @@ -105,7 +105,6 @@ section Equivalence variable {P} -set_option backward.isDefEq.respectTransparency false in lemma IsSeparating.of_equivalence (h : IsSeparating P) {D : Type*} [Category* D] (α : C ≌ D) : IsSeparating (P.strictMap α.functor) := fun X Y f g H => @@ -737,6 +736,7 @@ lemma isCoseparator_of_isLimit_fan {β : Type w} {f : β → C} obtain ⟨b⟩ := h classical simpa using huv (hc.lift (Fan.mk _ (Pi.single b g))) =≫ c.proj b +set_option backward.isDefEq.respectTransparency.types false in lemma isCoseparator_iff_of_isLimit_fan {β : Type w} {f : β → C} {c : Fan f} (hc : IsLimit c) : IsCoseparator c.pt ↔ ObjectProperty.IsCoseparating (.ofObj f) := by diff --git a/Mathlib/CategoryTheory/Generator/Presheaf.lean b/Mathlib/CategoryTheory/Generator/Presheaf.lean index d3cde1d92e3c50..e3d84aef069223 100644 --- a/Mathlib/CategoryTheory/Generator/Presheaf.lean +++ b/Mathlib/CategoryTheory/Generator/Presheaf.lean @@ -51,6 +51,7 @@ noncomputable def freeYonedaHomEquiv {X : C} {M : A} {F : Cᵒᵖ ⥤ A} : simpa using (Sigma.ι _ (𝟙 _) ≫= f.naturality φ.op).symm right_inv g := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma freeYonedaHomEquiv_comp {X : C} {M : A} {F G : Cᵒᵖ ⥤ A} diff --git a/Mathlib/CategoryTheory/GlueData.lean b/Mathlib/CategoryTheory/GlueData.lean index 1b3505e7579b55..d18b4505c3aa82 100644 --- a/Mathlib/CategoryTheory/GlueData.lean +++ b/Mathlib/CategoryTheory/GlueData.lean @@ -190,6 +190,7 @@ end theorem types_π_surjective (D : GlueData Type*) : Function.Surjective D.π := (epi_iff_surjective _).mp inferInstance +set_option backward.isDefEq.respectTransparency.types false in theorem types_ι_jointly_surjective (D : GlueData (Type v)) (x : D.glued) : ∃ (i : _) (y : D.U i), D.ι i y = x := by delta CategoryTheory.GlueData.ι @@ -327,6 +328,7 @@ def vPullbackConeIsLimitOfMap (i j : D.J) [ReflectsLimit (cospan (D.ι i) (D.ι rintro (_ | _ | _) all_goals simp [e]; rfl +set_option backward.isDefEq.respectTransparency.types false in /-- If there is a forgetful functor into `Type` that preserves enough (co)limits, then `D.ι` will be jointly surjective. -/ theorem ι_jointly_surjective (F : C ⥤ Type v) [PreservesColimit D.diagram.multispan F] diff --git a/Mathlib/CategoryTheory/GradedObject.lean b/Mathlib/CategoryTheory/GradedObject.lean index 03ef00b947be24..097e1ec4ae9fc9 100644 --- a/Mathlib/CategoryTheory/GradedObject.lean +++ b/Mathlib/CategoryTheory/GradedObject.lean @@ -40,6 +40,7 @@ open Category Limits universe w v u /-- A type synonym for `β → C`, used for `β`-graded objects in a category `C`. -/ +@[implicit_reducible] def GradedObject (β : Type w) (C : Type u) : Type max w u := β → C @@ -79,6 +80,7 @@ section variable {β : Type*} (X Y : GradedObject β C) +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for isomorphisms in `GradedObject` -/ @[simps] def isoMk (e : ∀ i, X i ≅ Y i) : X ≅ Y where @@ -88,6 +90,7 @@ def isoMk (e : ∀ i, X i ≅ Y i) : X ≅ Y where variable {X Y} -- this lemma is not an instance as it may create a loop with `isIso_apply_of_isIso` +set_option backward.isDefEq.respectTransparency.types false in lemma isIso_of_isIso_apply (f : X ⟶ Y) [hf : ∀ i, IsIso (f i)] : IsIso f := by change IsIso (isoMk X Y (fun i => asIso (f i))).hom @@ -106,24 +109,28 @@ namespace Iso variable {C D E J : Type*} [Category* C] [Category* D] [Category* E] {X Y : GradedObject J C} +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma hom_inv_id_eval (e : X ≅ Y) (j : J) : e.hom j ≫ e.inv j = 𝟙 _ := by rw [← GradedObject.categoryOfGradedObjects_comp, e.hom_inv_id, GradedObject.categoryOfGradedObjects_id] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma inv_hom_id_eval (e : X ≅ Y) (j : J) : e.inv j ≫ e.hom j = 𝟙 _ := by rw [← GradedObject.categoryOfGradedObjects_comp, e.inv_hom_id, GradedObject.categoryOfGradedObjects_id] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma map_hom_inv_id_eval (e : X ≅ Y) (F : C ⥤ D) (j : J) : F.map (e.hom j) ≫ F.map (e.inv j) = 𝟙 _ := by rw [← F.map_comp, ← GradedObject.categoryOfGradedObjects_comp, e.hom_inv_id, GradedObject.categoryOfGradedObjects_id, Functor.map_id] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma map_inv_hom_id_eval (e : X ≅ Y) (F : C ⥤ D) (j : J) : F.map (e.inv j) ≫ F.map (e.hom j) = 𝟙 _ := by @@ -162,6 +169,7 @@ theorem eqToHom_proj {I : Type*} {x x' : GradedObject I C} (h : x = x') (i : I) subst h rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The natural isomorphism comparing between pulling back along two propositionally equal functions. -/ @@ -173,6 +181,7 @@ def comapEq {β γ : Type w} {f g : β → γ} (h : f = g) : comap C f ≅ comap theorem comapEq_symm {β γ : Type w} {f g : β → γ} (h : f = g) : comapEq C h.symm = (comapEq C h).symm := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in theorem comapEq_trans {β γ : Type w} {f g h : β → γ} (k : f = g) (l : g = h) : comapEq C (k.trans l) = comapEq C k ≪≫ comapEq C l := by cat_disch @@ -196,6 +205,7 @@ def comapEquiv {β γ : Type w} (e : β ≃ γ) : GradedObject β C ≌ GradedOb end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance hasShift {β : Type*} [AddCommGroup β] (s : β) : HasShift (GradedObjectWithShift s C) ℤ := hasShiftMk _ _ @@ -204,11 +214,13 @@ instance hasShift {β : Type*} [AddCommGroup β] (s : β) : HasShift (GradedObje add := fun m n => comapEq C (by ext; dsimp; rw [add_comm m n, add_zsmul, add_assoc]) ≪≫ (Pi.comapComp _ _ _).symm } +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem shiftFunctor_obj_apply {β : Type*} [AddCommGroup β] (s : β) (X : β → C) (t : β) (n : ℤ) : (shiftFunctor (GradedObjectWithShift s C) n).obj X t = X (t + n • s) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem shiftFunctor_map_apply {β : Type*} [AddCommGroup β] (s : β) {X Y : GradedObjectWithShift s C} (f : X ⟶ Y) (t : β) (n : ℤ) : @@ -223,6 +235,7 @@ theorem zero_apply [HasZeroMorphisms C] (β : Type w) (X Y : GradedObject β C) (0 : X ⟶ Y) b = 0 := rfl +set_option backward.isDefEq.respectTransparency.types false in instance hasZeroMorphisms [HasZeroMorphisms C] (β : Type w) : HasZeroMorphisms.{max w v} (GradedObject β C) where @@ -250,6 +263,7 @@ variable [HasCoproducts.{0} C] section +set_option backward.isDefEq.respectTransparency.types false in /-- The total object of a graded object is the coproduct of the graded components. -/ noncomputable def total : GradedObject β C ⥤ C where @@ -260,6 +274,7 @@ end variable [HasZeroMorphisms C] +set_option backward.isDefEq.respectTransparency.types false in /-- The `total` functor taking a graded object to the coproduct of its graded components is faithful. To prove this, we need to know that the coprojections into the coproduct are monomorphisms, @@ -396,14 +411,17 @@ lemma congr_mapMap (φ₁ φ₂ : X ⟶ Y) (h : φ₁ = φ₂) : mapMap φ₁ p variable (X) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapMap_id : mapMap (𝟙 X) p = 𝟙 _ := by cat_disch variable {X Z} +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc] lemma mapMap_comp [Z.HasMap p] : mapMap (φ ≫ ψ) p = mapMap φ p ≫ mapMap ψ p := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism of `J`-graded objects `X.mapObj p ≅ Y.mapObj p` induced by an isomorphism `X ≅ Y` of graded objects and a map `p : I → J`. -/ @[simps] @@ -442,6 +460,7 @@ def cofanMapObjComp : X.CofanMapObjFun r k := (c (p i) (by rw [hpqr, hi])).inj ⟨i, rfl⟩ ≫ c'.inj (⟨p i, by rw [Set.mem_preimage, Set.mem_singleton_iff, hpqr, hi]⟩)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given maps `p : I → J`, `q : J → K` and `r : I → K` such that `q.comp p = r`, `X : GradedObject I C`, `k : K`, the cofan constructed by `cofanMapObjComp` is a colimit. diff --git a/Mathlib/CategoryTheory/GradedObject/Bifunctor.lean b/Mathlib/CategoryTheory/GradedObject/Bifunctor.lean index bf8bdd713a6a2a..dbb3693887f67c 100644 --- a/Mathlib/CategoryTheory/GradedObject/Bifunctor.lean +++ b/Mathlib/CategoryTheory/GradedObject/Bifunctor.lean @@ -32,15 +32,18 @@ variable {C₁ C₂ C₃ : Type*} [Category* C₁] [Category* C₂] [Category* C namespace GradedObject +set_option backward.isDefEq.respectTransparency.types false in /-- Given a bifunctor `F : C₁ ⥤ C₂ ⥤ C₃` and types `I` and `J`, this is the obvious functor `GradedObject I C₁ ⥤ GradedObject J C₂ ⥤ GradedObject (I × J) C₃`. -/ @[simps] def mapBifunctor (I J : Type*) : GradedObject I C₁ ⥤ GradedObject J C₂ ⥤ GradedObject (I × J) C₃ where obj X := + set_option backward.isDefEq.respectTransparency.types false in { obj := fun Y ij => (F.obj (X ij.1)).obj (Y ij.2) map := fun φ ij => (F.obj (X ij.1)).map (φ ij.2) } map φ := + set_option backward.isDefEq.respectTransparency.types false in { app := fun Y ij => (F.map (φ ij.1)).app (Y ij.2) } section @@ -119,6 +122,7 @@ variable {X₁ X₂ : GradedObject I C₁} {Y₁ Y₂ : GradedObject J C₂} [HasMap (((mapBifunctor F I J).obj X₁).obj Y₁) p] [HasMap (((mapBifunctor F I J).obj X₂).obj Y₂) p] +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism `mapBifunctorMapObj F p X₁ Y₁ ≅ mapBifunctorMapObj F p X₂ Y₂` induced by isomorphisms `X₁ ≅ X₂` and `Y₁ ≅ Y₂`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/GradedObject/Braiding.lean b/Mathlib/CategoryTheory/GradedObject/Braiding.lean index b3e8f4b487f204..890134c479fbb7 100644 --- a/Mathlib/CategoryTheory/GradedObject/Braiding.lean +++ b/Mathlib/CategoryTheory/GradedObject/Braiding.lean @@ -38,6 +38,7 @@ section Braided variable [BraidedCategory C] +set_option backward.isDefEq.respectTransparency.types false in /-- The braiding `tensorObj X Y ≅ tensorObj Y X` when `X` and `Y` are graded objects indexed by a commutative additive monoid. -/ noncomputable def braiding [HasTensor X Y] [HasTensor Y X] : tensorObj X Y ≅ tensorObj Y X where @@ -46,6 +47,7 @@ noncomputable def braiding [HasTensor X Y] [HasTensor Y X] : tensorObj X Y ≅ t inv k := tensorObjDesc (fun i j hij => (β_ _ _).inv ≫ ιTensorObj X Y j i k (by simpa only [add_comm j i] using hij)) +set_option backward.isDefEq.respectTransparency.types false in variable {Y Z} in lemma braiding_naturality_right [HasTensor X Y] [HasTensor Y X] [HasTensor X Z] [HasTensor Z X] (f : Y ⟶ Z) : @@ -53,6 +55,7 @@ lemma braiding_naturality_right [HasTensor X Y] [HasTensor Y X] [HasTensor X Z] dsimp [braiding] cat_disch +set_option backward.isDefEq.respectTransparency.types false in variable {X Y} in lemma braiding_naturality_left [HasTensor Y Z] [HasTensor Z Y] [HasTensor X Z] [HasTensor Z X] (f : X ⟶ Y) : @@ -60,6 +63,7 @@ lemma braiding_naturality_left [HasTensor Y Z] [HasTensor Z Y] [HasTensor X Z] [ dsimp [braiding] cat_disch +set_option backward.isDefEq.respectTransparency.types false in lemma hexagon_forward [HasTensor X Y] [HasTensor Y X] [HasTensor Y Z] [HasTensor Z X] [HasTensor X Z] [HasTensor (tensorObj X Y) Z] [HasTensor X (tensorObj Y Z)] @@ -98,6 +102,7 @@ lemma hexagon_forward [HasTensor X Y] [HasTensor Y X] [HasTensor Y Z] ← ιTensorObj₃_eq Y Z X i₂ i₃ i₁ k (by rw [add_comm _ i₁, ← add_assoc, h]) (i₁ + i₃) (add_comm _ _)] +set_option backward.isDefEq.respectTransparency.types false in lemma hexagon_reverse [HasTensor X Y] [HasTensor Y Z] [HasTensor Z X] [HasTensor Z Y] [HasTensor X Z] [HasTensor (tensorObj X Y) Z] [HasTensor X (tensorObj Y Z)] @@ -136,6 +141,7 @@ lemma hexagon_reverse [HasTensor X Y] [HasTensor Y Z] [HasTensor Z X] end Braided +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma symmetry [SymmetricCategory C] [HasTensor X Y] [HasTensor Y X] : (braiding X Y).hom ≫ (braiding Y X).hom = 𝟙 _ := by diff --git a/Mathlib/CategoryTheory/GradedObject/Monoidal.lean b/Mathlib/CategoryTheory/GradedObject/Monoidal.lean index a00bb81d325d9a..738eb3784df137 100644 --- a/Mathlib/CategoryTheory/GradedObject/Monoidal.lean +++ b/Mathlib/CategoryTheory/GradedObject/Monoidal.lean @@ -123,6 +123,7 @@ lemma id_tensorHom_id (X Y : GradedObject I C) [HasTensor X Y] : simp only [Functor.map_id, NatTrans.id_app, comp_id, mapMap_id] rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma tensorHom_comp_tensorHom {X₁ X₂ X₃ Y₁ Y₂ Y₃ : GradedObject I C} (f₁ : X₁ ⟶ X₂) (f₂ : X₂ ⟶ X₃) (g₁ : Y₁ ⟶ Y₂) (g₂ : Y₂ ⟶ Y₃) [HasTensor X₁ Y₁] [HasTensor X₂ Y₂] [HasTensor X₃ Y₃] : @@ -307,6 +308,7 @@ lemma ιTensorObj₃_associator_inv variable {X₁ X₂ X₃} +set_option backward.isDefEq.respectTransparency.types false in variable [HasTensor Y₁ Y₂] [HasTensor (tensorObj Y₁ Y₂) Y₃] [HasTensor Y₂ Y₃] [HasTensor Y₁ (tensorObj Y₂ Y₃)] in lemma associator_naturality (f₁ : X₁ ⟶ Y₁) (f₂ : X₂ ⟶ Y₂) (f₃ : X₃ ⟶ Y₃) @@ -415,6 +417,7 @@ variable (X₁ X₂ X₃ X₄ : GradedObject I C) [HasGoodTensorTensor₂₃ X₁ X₂ (tensorObj X₃ X₄)] [HasTensor₄ObjExt X₁ X₂ X₃ X₄] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma pentagon_inv : tensorHom (𝟙 X₁) (associator X₂ X₃ X₄).inv ≫ (associator X₁ (tensorObj X₂ X₃) X₄).inv ≫ @@ -606,6 +609,7 @@ instance (n : ℕ) : Finite ((fun (i : ℕ × ℕ) => i.1 + i.2) ⁻¹' {n}) := rintro ⟨⟨_, _⟩, _⟩ ⟨⟨_, _⟩, _⟩ h simpa using h +set_option backward.isDefEq.respectTransparency.types false in instance (n : ℕ) : Finite ({ i : (ℕ × ℕ × ℕ) | i.1 + i.2.1 + i.2.2 = n }) := by refine Finite.of_injective (fun ⟨⟨i₁, i₂, i₃⟩, (hi : i₁ + i₂ + i₃ = n)⟩ => (⟨⟨i₁, by lia⟩, ⟨i₂, by lia⟩, ⟨i₃, by lia⟩⟩ : diff --git a/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean b/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean index 8caa9cdb3add5a..0f62907d31a21f 100644 --- a/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean +++ b/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean @@ -40,6 +40,7 @@ section variable (F F' : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₄) +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `mapTrifunctor`. -/ @[simps] def mapTrifunctorObj {I₁ : Type*} (X₁ : GradedObject I₁ C₁) (I₂ I₃ : Type*) : @@ -50,6 +51,7 @@ def mapTrifunctorObj {I₁ : Type*} (X₁ : GradedObject I₁ C₁) (I₂ I₃ : map {X₂ Y₂} φ := { app := fun X₃ x => ((F.obj (X₁ x.1)).map (φ x.2.1)).app (X₃ x.2.2) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a trifunctor `F : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₄` and types `I₁`, `I₂`, `I₃`, this is the obvious functor @@ -75,6 +77,7 @@ section variable {F F' : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₄} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural transformation `mapTrifunctor F I₁ I₂ I₃ ⟶ mapTrifunctor F' I₁ I₂ I₃` induced by a natural transformation `F ⟶ F'` of trifunctors. -/ @@ -93,6 +96,7 @@ def mapTrifunctorMapNatTrans (α : F ⟶ F') (I₁ I₂ I₃ : Type*) : dsimp simp only [← NatTrans.comp_app, NatTrans.naturality] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism `mapTrifunctor F I₁ I₂ I₃ ≅ mapTrifunctor F' I₁ I₂ I₃` induced by a natural isomorphism `F ≅ F'` of trifunctors. -/ @@ -117,6 +121,7 @@ section variable (F : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₄) variable {I₁ I₂ I₃ J : Type*} (p : I₁ × I₂ × I₃ → J) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a trifunctor `F : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₃`, graded objects `X₁ : GradedObject I₁ C₁`, `X₂ : GradedObject I₂ C₂`, `X₃ : GradedObject I₃ C₃`, and a map `p : I₁ × I₂ × I₃ → J`, this is the `J`-graded object sending `j` to the coproduct of @@ -127,6 +132,7 @@ noncomputable def mapTrifunctorMapObj (X₁ : GradedObject I₁ C₁) (X₂ : Gr GradedObject J C₄ := ((((mapTrifunctor F I₁ I₂ I₃).obj X₁).obj X₂).obj X₃).mapObj p +set_option backward.isDefEq.respectTransparency.types false in /-- The obvious inclusion `((F.obj (X₁ i₁)).obj (X₂ i₂)).obj (X₃ i₃) ⟶ mapTrifunctorMapObj F p X₁ X₂ X₃ j` when `p ⟨i₁, i₂, i₃⟩ = j`. -/ @@ -136,6 +142,7 @@ noncomputable def ιMapTrifunctorMapObj (X₁ : GradedObject I₁ C₁) (X₂ : ((F.obj (X₁ i₁)).obj (X₂ i₂)).obj (X₃ i₃) ⟶ mapTrifunctorMapObj F p X₁ X₂ X₃ j := ((((mapTrifunctor F I₁ I₂ I₃).obj X₁).obj X₂).obj X₃).ιMapObj p ⟨i₁, i₂, i₃⟩ j h +set_option backward.isDefEq.respectTransparency.types false in /-- The maps `mapTrifunctorMapObj F p X₁ X₂ X₃ ⟶ mapTrifunctorMapObj F p Y₁ Y₂ Y₃` which express the functoriality of `mapTrifunctorMapObj`, see `mapTrifunctorMap` -/ noncomputable def mapTrifunctorMapMap {X₁ Y₁ : GradedObject I₁ C₁} (f₁ : X₁ ⟶ Y₁) @@ -183,6 +190,7 @@ instance (X₁ : GradedObject I₁ C₁) (X₂ : GradedObject I₂ C₂) (X₃ : [h : HasMap ((((mapTrifunctor F I₁ I₂ I₃).obj X₁).obj X₂).obj X₃) p] : HasMap (((mapTrifunctorObj F X₁ I₂ I₃).obj X₂).obj X₃) p := h +set_option backward.isDefEq.respectTransparency.types false in /-- Given a trifunctor `F : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₄`, a map `p : I₁ × I₂ × I₃ → J`, and graded objects `X₁ : GradedObject I₁ C₁`, `X₂ : GradedObject I₂ C₂` and `X₃ : GradedObject I₃ C₃`, this is the `J`-graded object sending `j` to the coproduct of @@ -220,6 +228,7 @@ noncomputable def mapTrifunctorMapFunctorObj (X₁ : GradedObject I₁ C₁) NatTrans.id_app, categoryOfGradedObjects_comp, Functor.map_comp, NatTrans.comp_app, id_comp, assoc, ι_mapTrifunctorMapMap_assoc] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a trifunctor `F : C₁ ⥤ C₂ ⥤ C₃ ⥤ C₄` and a map `p : I₁ × I₂ × I₃ → J`, this is the functor @@ -376,6 +385,7 @@ noncomputable def mapBifunctorComp₁₂MapObjIso : isoMk _ _ (fun j => (CofanMapObjFun.iso (isColimitCofan₃MapBifunctor₁₂BifunctorMapObj F₁₂ G ρ₁₂ X₁ X₂ X₃ j)).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma ι_mapBifunctorComp₁₂MapObjIso_hom (i₁ : I₁) (i₂ : I₂) (i₃ : I₃) (j : J) @@ -556,6 +566,7 @@ noncomputable def mapBifunctorComp₂₃MapObjIso : isoMk _ _ (fun j => (CofanMapObjFun.iso (isColimitCofan₃MapBifunctorBifunctor₂₃MapObj F G₂₃ ρ₂₃ X₁ X₂ X₃ j)).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma ι_mapBifunctorComp₂₃MapObjIso_hom (i₁ : I₁) (i₂ : I₂) (i₃ : I₃) (j : J) diff --git a/Mathlib/CategoryTheory/GradedObject/Unitor.lean b/Mathlib/CategoryTheory/GradedObject/Unitor.lean index 9806cd65f5b742..376bf2745aec44 100644 --- a/Mathlib/CategoryTheory/GradedObject/Unitor.lean +++ b/Mathlib/CategoryTheory/GradedObject/Unitor.lean @@ -65,6 +65,7 @@ noncomputable def mapBifunctorLeftUnitorCofan (hp : ∀ (j : J), p ⟨0, j⟩ = else (mapBifunctorObjSingle₀ObjIsInitial F X Y a ha).to _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp, reassoc] lemma mapBifunctorLeftUnitorCofan_inj (j : J) : @@ -105,8 +106,8 @@ noncomputable def mapBifunctorLeftUnitor : mapBifunctorMapObj F p ((single₀ I) isoMk _ _ (fun j => (CofanMapObjFun.iso (mapBifunctorLeftUnitorCofanIsColimit F X e p hp Y j)).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma ι_mapBifunctorLeftUnitor_hom_apply (j : J) : ιMapBifunctorMapObj F p ((single₀ I).obj X) Y 0 j j (hp j) ≫ @@ -123,7 +124,6 @@ lemma mapBifunctorLeftUnitor_inv_apply (j : J) : variable {Y Y'} -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma mapBifunctorLeftUnitor_inv_naturality : φ ≫ (mapBifunctorLeftUnitor F X e p hp Y').inv = @@ -182,6 +182,7 @@ noncomputable def mapBifunctorRightUnitorCofan (hp : ∀ (j : J), p ⟨j, 0⟩ = else (mapBifunctorObjObjSingle₀IsInitial F Y X a ha).to _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp, reassoc] lemma mapBifunctorRightUnitorCofan_inj (j : J) : @@ -225,8 +226,8 @@ noncomputable def mapBifunctorRightUnitor : mapBifunctorMapObj F p X ((single₀ isoMk _ _ (fun j => (CofanMapObjFun.iso (mapBifunctorRightUnitorCofanIsColimit F Y e p hp X j)).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma ι_mapBifunctorRightUnitor_hom_apply (j : J) : ιMapBifunctorMapObj F p X ((single₀ I).obj Y) j 0 j (hp j) ≫ diff --git a/Mathlib/CategoryTheory/Grothendieck.lean b/Mathlib/CategoryTheory/Grothendieck.lean index 478a3af7012396..bbc0352e9bc569 100644 --- a/Mathlib/CategoryTheory/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Grothendieck.lean @@ -56,7 +56,7 @@ universe w u v u₁ v₁ u₂ v₂ namespace CategoryTheory -open Functor +open CategoryTheory.Functor variable {C : Type u} [Category.{v} C] variable {D : Type u₁} [Category.{v₁} D] @@ -115,6 +115,7 @@ def comp {X Y Z : Grothendieck F} (f : Hom X Y) (g : Hom Y Z) : Hom X Z where attribute [local simp] eqToHom_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : Category (Grothendieck F) where Hom X Y := Grothendieck.Hom X Y @@ -193,6 +194,7 @@ If `F : C ⥤ Cat` is a functor and `t : c ⟶ d` is a morphism in `C`, then `tr def toTransport (x : Grothendieck F) {c : C} (t : x.base ⟶ c) : x ⟶ x.transport t := ⟨t, 𝟙 _⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Construct an isomorphism in a Grothendieck construction from isomorphisms in its base and fiber. @@ -209,6 +211,9 @@ def isoMk {X Y : Grothendieck F} (e₁ : X.base ≅ Y.base) have := Functor.congr_hom congr($((F.mapIso e₁).inv_hom_id).toFunctor) e₂.inv simp_all) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- If `F : C ⥤ Cat` and `x : Grothendieck F`, then every `C`-isomorphism `α : x.base ≅ c` induces an isomorphism between `x` and its transport along `α` @@ -234,6 +239,7 @@ section variable {G : C ⥤ Cat} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The Grothendieck construction is functorial: a natural transformation `α : F ⟶ G` induces a functor `Grothendieck.map : Grothendieck F ⥤ Grothendieck G`. @@ -255,6 +261,7 @@ def map (α : F ⟶ G) : Grothendieck F ⥤ Grothendieck G where simp +set_option backward.isDefEq.respectTransparency.types false in theorem map_obj {α : F ⟶ G} (X : Grothendieck F) : (Grothendieck.map α).obj X = ⟨X.base, (α.app X.base).toFunctor.obj X.fiber⟩ := rfl @@ -265,6 +272,7 @@ theorem map_map {α : F ⟶ G} {X Y : Grothendieck F} {f : X ⟶ Y} : (α.app Y.base).toFunctor.map f.fiber⟩ := by apply Grothendieck.ext _ _ (by simp) (by simp) +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `Grothendieck.map α : Grothendieck F ⥤ Grothendieck G` lies over `C`. -/ theorem functor_comp_forget {α : F ⟶ G} : Grothendieck.map α ⋙ Grothendieck.forget G = Grothendieck.forget F := rfl @@ -279,6 +287,7 @@ theorem map_id_eq : map (𝟙 F) = Functor.id (Grothendieck <| F) := by simp [map_map] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Making the equality of functors into an isomorphism. Note: we should avoid equality of functors if possible, and we should prefer `mapIdIso` to `map_id_eq` whenever we can. -/ def mapIdIso : (map (𝟙 F)).toCatHom ≅ 𝟙 (Cat.of <| Grothendieck <| F) := @@ -298,6 +307,7 @@ theorem map_comp_eq (α : F ⟶ G) (β : G ⟶ H) : comp_obj, Cat.Hom₂.eqToHom_toNatTrans, eqToHom_app, Functor.comp_map, eqToHom_refl, map_comp, eqToHom_map, eqToHom_trans_assoc, Category.comp_id, Category.id_comp] +set_option backward.isDefEq.respectTransparency.types false in /-- Making the equality of functors into an isomorphism. Note: we should avoid equality of functors if possible, and we should prefer `map_comp_iso` to `map_comp_eq` whenever we can. -/ def mapCompIso (α : F ⟶ G) (β : G ⟶ H) : map (α ≫ β) ≅ map α ⋙ map β := eqToIso (map_comp_eq α β) @@ -368,6 +378,7 @@ def mapWhiskerRightAsSmallFunctor (α : F ⟶ G) : end +set_option backward.isDefEq.respectTransparency.types false in /-- The Grothendieck construction as a functor from the functor category `E ⥤ Cat` to the over category `Over E`. -/ def functor {E : Cat.{v, u}} : (E ⥤ Cat.{v, u}) ⥤ Over (T := Cat.{v, u}) E where @@ -436,7 +447,7 @@ variable (F) set_option backward.isDefEq.respectTransparency false in /-- Applying a functor `G : D ⥤ C` to the base of the Grothendieck construction induces a functor `Grothendieck (G ⋙ F) ⥤ Grothendieck F`. -/ -@[simps] +@[simps, implicit_reducible] def pre (G : D ⥤ C) : Grothendieck (G ⋙ F) ⥤ Grothendieck F where obj X := ⟨G.obj X.base, X.fiber⟩ map f := ⟨G.map f.base, f.fiber⟩ @@ -459,16 +470,19 @@ def preNatIso {G H : D ⥤ C} (α : G ≅ H) : (fun X => (transportIso ⟨G.obj X.base, X.fiber⟩ (α.app X.base)).symm) (fun f => by fapply Grothendieck.ext <;> simp) +set_option backward.isDefEq.respectTransparency.types false in /-- Given an equivalence of categories `G`, `preInv _ G` is the (weak) inverse of the `pre _ G.functor`. -/ def preInv (G : D ≌ C) : Grothendieck F ⥤ Grothendieck (G.functor ⋙ F) := map (whiskerRight G.counitInv F) ⋙ Grothendieck.pre (G.functor ⋙ F) G.inverse +set_option backward.isDefEq.respectTransparency.types false in variable {F} in lemma pre_comp_map (G : D ⥤ C) {H : C ⥤ Cat} (α : F ⟶ H) : pre F G ⋙ map α = map (whiskerLeft G α) ⋙ pre H G := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {F} in lemma pre_comp_map_assoc (G : D ⥤ C) {H : C ⥤ Cat} (α : F ⟶ H) {E : Type*} [Category* E] (K : Grothendieck H ⥤ E) : pre F G ⋙ map α ⋙ K = map (whiskerLeft G α) ⋙ pre H G ⋙ K := rfl @@ -477,6 +491,7 @@ variable {E : Type*} [Category* E] in @[simp] lemma pre_comp (G : D ⥤ C) (H : E ⥤ D) : pre F (H ⋙ G) = pre (G ⋙ F) H ⋙ pre F G := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Let `G` be an equivalence of categories. The functor induced via `pre` by `G.functor ⋙ G.inverse` is naturally isomorphic to the functor induced via `map` by a whiskered version of `G`'s inverse @@ -514,6 +529,7 @@ def preEquivalence (G : D ≌ C) : Grothendieck (G.functor ⋙ F) ≌ Grothendie Iso.trans_hom, eqToIso.hom, eqToHom_app, eqToHom_refl, isoWhiskerLeft_hom, NatTrans.comp_app] fapply Grothendieck.ext <;> simp [preNatIso, transportIso] +set_option backward.isDefEq.respectTransparency.types false in variable {F} in /-- Let `F, F' : C ⥤ Cat` be functor, `G : D ≌ C` an equivalence and `α : F ⟶ F'` a natural @@ -538,6 +554,7 @@ section FunctorFrom variable {E : Type*} [Category* E] +set_option backward.isDefEq.respectTransparency.types false in variable (F) in /-- The inclusion of a fiber `F.obj c` of a functor `F : C ⥤ Cat` into its Grothendieck construction. -/ @@ -557,6 +574,7 @@ def ι (c : C) : F.obj c ⥤ Grothendieck F where simp only [eqToHom_comp_iff, Category.assoc, eqToHom_trans_assoc] apply Functor.congr_hom congr($(F.map_id _).toFunctor).symm +set_option backward.isDefEq.respectTransparency.types false in instance faithful_ι (c : C) : (ι F c).Faithful where map_injective f := by injection f with _ f @@ -579,7 +597,7 @@ variable (hom_id : ∀ c, hom (𝟙 c) = eqToHom (by simp only [Functor.map_id]; variable (hom_comp : ∀ c₁ c₂ c₃ (f : c₁ ⟶ c₂) (g : c₂ ⟶ c₃), hom (f ≫ g) = hom f ≫ whiskerLeft (F.map f).toFunctor (hom g) ≫ eqToHom (by simp only [Functor.map_comp]; rfl)) -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- Construct a functor from `Grothendieck F` to another category `E` by providing a family of functors on the fibers of `Grothendieck F`, a family of natural transformations on morphisms in the base of `Grothendieck F` and coherence data for this family of natural transformations. -/ diff --git a/Mathlib/CategoryTheory/Groupoid.lean b/Mathlib/CategoryTheory/Groupoid.lean index 1c6dd4771e7431..281bed2c90a8f8 100644 --- a/Mathlib/CategoryTheory/Groupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid.lean @@ -126,19 +126,19 @@ noncomputable instance {C : Type u} [Groupoid.{v} C] : IsGroupoid C where variable {C : Type u} [Category.{v} C] /-- Promote (noncomputably) an `IsGroupoid` to a `Groupoid` structure. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Groupoid.ofIsGroupoid [IsGroupoid C] : Groupoid.{v} C where inv := fun f => CategoryTheory.inv f /-- A category where every morphism `IsIso` is a groupoid. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Groupoid.ofIsIso (all_is_iso : ∀ {X Y : C} (f : X ⟶ Y), IsIso f) : Groupoid.{v} C where inv := fun f => CategoryTheory.inv f /-- A category with a unique morphism between any two objects is a groupoid -/ -@[implicit_reducible] +@[instance_reducible] def Groupoid.ofHomUnique (all_unique : ∀ {X Y : C}, Unique (X ⟶ Y)) : Groupoid.{v} C where inv _ := all_unique.default @@ -150,7 +150,7 @@ lemma isGroupoid_of_reflects_iso {C D : Type*} [Category* C] [Category* D] all_isIso _ := isIso_of_reflects_iso _ F /-- A category equipped with a fully faithful functor to a groupoid is fully faithful -/ -@[implicit_reducible] +@[instance_reducible] def Groupoid.ofFullyFaithfulToGroupoid {C : Type*} [𝒞 : Category C] {D : Type u} [Groupoid.{v} D] (F : C ⥤ D) (h : F.FullyFaithful) : Groupoid C := { 𝒞 with diff --git a/Mathlib/CategoryTheory/Groupoid/FreeGroupoid.lean b/Mathlib/CategoryTheory/Groupoid/FreeGroupoid.lean index 4e1115b66d2287..ac3d3b0965540c 100644 --- a/Mathlib/CategoryTheory/Groupoid/FreeGroupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid/FreeGroupoid.lean @@ -82,6 +82,7 @@ theorem congr_reverse {X Y : Paths <| Quiver.Symmetrify V} (p q : X ⟶ Y) : Quiver.Path.reverse_comp, Quiver.reverse_reverse, Quiver.Path.reverse_toPath, Quiver.Path.comp_assoc] using this +set_option backward.isDefEq.respectTransparency.types false in open Relation in theorem congr_comp_reverse {X Y : Paths <| Quiver.Symmetrify V} (p : X ⟶ Y) : Quot.mk (@HomRel.CompClosure _ _ redStep _ _) (p ≫ p.reverse) = @@ -158,6 +159,7 @@ theorem lift_spec (φ : V ⥤q V') : of V ⋙q (lift φ).toPrefunctor = φ := by dsimp [lift] rw [Quotient.lift_spec, Paths.lift_spec, Quiver.Symmetrify.lift_spec] +set_option backward.isDefEq.respectTransparency.types false in theorem lift_unique (φ : V ⥤q V') (Φ : Quiver.FreeGroupoid V ⥤ V') (hΦ : of V ⋙q Φ.toPrefunctor = φ) : Φ = lift φ := by apply Quotient.lift_unique diff --git a/Mathlib/CategoryTheory/Groupoid/FreeGroupoidOfCategory.lean b/Mathlib/CategoryTheory/Groupoid/FreeGroupoidOfCategory.lean index 21aa8897944a83..601d9ef3b8e403 100644 --- a/Mathlib/CategoryTheory/Groupoid/FreeGroupoidOfCategory.lean +++ b/Mathlib/CategoryTheory/Groupoid/FreeGroupoidOfCategory.lean @@ -119,6 +119,7 @@ theorem lift_spec (φ : C ⥤ G) : of C ⋙ lift φ = φ := lemma lift_obj_mk {E : Type u₂} [Groupoid.{v₂} E] (φ : C ⥤ E) (X : C) : (lift φ).obj (mk X) = φ.obj X := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma lift_map_homMk {E : Type u₂} [Groupoid.{v₂} E] (φ : C ⥤ E) {X Y : C} (f : X ⟶ Y) : diff --git a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean index d27f71fc9cc941..725485d6a3f191 100644 --- a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean @@ -127,7 +127,7 @@ theorem id_mem_of_tgt {c d : C} {f : c ⟶ d} (h : f ∈ S.arrows c d) : 𝟙 d id_mem_of_nonempty_isotropy S d (mem_objs_of_tgt S h) /-- A subgroupoid seen as a quiver on vertex set `C` -/ -@[implicit_reducible] +@[instance_reducible] def asWideQuiver : Quiver C := ⟨fun c d => S.arrows c d⟩ @@ -250,6 +250,7 @@ theorem inclusion_inj_on_objects {S T : Subgroupoid C} (h : S ≤ T) : Function.Injective (inclusion h).obj := fun ⟨s, hs⟩ ⟨t, ht⟩ => by simpa only [inclusion, Subtype.mk_eq_mk] using id +set_option backward.isDefEq.respectTransparency.types false in theorem inclusion_faithful {S T : Subgroupoid C} (h : S ≤ T) (s t : S.objs) : Function.Injective fun f : s ⟶ t => (inclusion h).map f := fun ⟨f, hf⟩ ⟨g, hg⟩ => by -- Porting note: was `...; simpa only [Subtype.mk_eq_mk] using id` diff --git a/Mathlib/CategoryTheory/GuitartExact/Basic.lean b/Mathlib/CategoryTheory/GuitartExact/Basic.lean index 6e12df64c4f545..63177795ecc9f2 100644 --- a/Mathlib/CategoryTheory/GuitartExact/Basic.lean +++ b/Mathlib/CategoryTheory/GuitartExact/Basic.lean @@ -114,6 +114,7 @@ abbrev StructuredArrowRightwards.mk (comm : R.map a ≫ w.app X₁ ≫ B.map b = w.StructuredArrowRightwards g := StructuredArrow.mk (Y := CostructuredArrow.mk b) (CostructuredArrow.homMk a comm) +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for objects in `w.CostructuredArrowDownwards g`. -/ abbrev CostructuredArrowDownwards.mk (comm : R.map a ≫ w.app X₁ ≫ B.map b = g) : w.CostructuredArrowDownwards g := @@ -122,6 +123,7 @@ abbrev CostructuredArrowDownwards.mk (comm : R.map a ≫ w.app X₁ ≫ B.map b variable {w g} +set_option backward.isDefEq.respectTransparency.types false in lemma StructuredArrowRightwards.mk_surjective (f : w.StructuredArrowRightwards g) : ∃ (X₁ : C₁) (a : X₂ ⟶ T.obj X₁) (b : L.obj X₁ ⟶ X₃) @@ -131,6 +133,7 @@ lemma StructuredArrowRightwards.mk_surjective obtain ⟨a, ha, rfl⟩ := CostructuredArrow.homMk_surjective φ exact ⟨X₁, a, b, by simpa using ha, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma CostructuredArrowDownwards.mk_surjective (f : w.CostructuredArrowDownwards g) : ∃ (X₁ : C₁) (a : X₂ ⟶ T.obj X₁) (b : L.obj X₁ ⟶ X₃) @@ -144,6 +147,7 @@ end namespace EquivalenceJ +set_option backward.isDefEq.respectTransparency.types false in /-- Given `w : TwoSquare T L R B` and a morphism `g : R.obj X₂ ⟶ B.obj X₃`, this is the obvious functor `w.StructuredArrowRightwards g ⥤ w.CostructuredArrowDownwards g`. -/ @[simps] @@ -157,6 +161,7 @@ def functor : w.StructuredArrowRightwards g ⥤ w.CostructuredArrowDownwards g w map_id _ := rfl map_comp _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Given `w : TwoSquare T L R B` and a morphism `g : R.obj X₂ ⟶ B.obj X₃`, this is the obvious functor `w.CostructuredArrowDownwards g ⥤ w.StructuredArrowRightwards g`. -/ @[simps] @@ -172,6 +177,7 @@ def inverse : w.CostructuredArrowDownwards g ⥤ w.StructuredArrowRightwards g w end EquivalenceJ +set_option backward.isDefEq.respectTransparency.types false in /-- Given `w : TwoSquare T L R B` and a morphism `g : R.obj X₂ ⟶ B.obj X₃`, this is the obvious equivalence of categories `w.StructuredArrowRightwards g ≌ w.CostructuredArrowDownwards g`. -/ @@ -190,6 +196,7 @@ end section +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `w.CostructuredArrowDownwards g ⥤ w.CostructuredArrowDownwards g'` induced by a morphism `γ` such that `R.map γ ≫ g = g'`. -/ @[simps] @@ -243,6 +250,7 @@ instance [hw : w.GuitartExact] {X₂ : C₂} (g : StructuredArrow (R.obj X₂) B rw [guitartExact_iff_isConnected_downwards] at hw apply hw +set_option backward.isDefEq.respectTransparency.types false in lemma costructuredArrowRightwards_final_iff_of_iso {X₃ X₃' : C₃} (e : X₃ ≅ X₃') : (w.costructuredArrowRightwards X₃).Final ↔ (w.costructuredArrowRightwards X₃').Final := by @@ -260,6 +268,7 @@ instance [hw : w.GuitartExact] (X₃ : C₃) : rw [guitartExact_iff_final] at hw apply hw +set_option backward.isDefEq.respectTransparency.types false in lemma structuredArrowDownwards_initial_iff_of_iso {X₂ X₂' : C₂} (e : X₂ ≅ X₂') : (w.structuredArrowDownwards X₂).Initial ↔ (w.structuredArrowDownwards X₂').Initial := by diff --git a/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean b/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean index a18813f8de3f54..4ae05225baa88e 100644 --- a/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean +++ b/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean @@ -40,6 +40,7 @@ def whiskerHorizontal (α : T' ⟶ T) (β : B ⟶ B') : namespace GuitartExact +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A 2-square stays Guitart exact if we replace the top and bottom functors by isomorphic functors. See also `whiskerHorizontal_iff`. -/ @@ -86,6 +87,7 @@ def hComp' {T₁₂ : C₁ ⥤ C₃} {B₁₂ : D₁ ⥤ D₃} (eT : T₁ ⋙ T namespace GuitartExact +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance hComp [w.GuitartExact] [w'.GuitartExact] : (w ≫ₕ w').GuitartExact := by @@ -100,6 +102,7 @@ instance hComp' {T₁₂ : C₁ ⥤ C₃} {B₁₂ : D₁ ⥤ D₃} (eT : T₁ dsimp only [TwoSquare.hComp'] infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism between `w.costructuredArrowRightwards Y₁ ⋙ w'.costructuredArrowRightwards (B₁.obj Y₁)` and @@ -136,6 +139,7 @@ lemma hComp'_iff_of_essSurj (w.hComp' w' eT eB).GuitartExact ↔ w'.GuitartExact := ⟨fun _ ↦ of_hComp' w w' eT eB, fun _ ↦ inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma hComp_iff_of_equivalences (eT : C₂ ≌ C₃) (eB : D₂ ≌ D₃) (w' : eT.functor ⋙ V₃ ≅ V₂ ⋙ eB.functor) : @@ -146,6 +150,7 @@ lemma hComp_iff_of_equivalences (eT : C₂ ≌ C₃) (eB : D₂ ≌ D₃) ← vComp_iff_of_equivalences _ _ _ w'', this] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma hComp'_iff_of_equivalences (E : C₂ ≌ C₃) (E' : D₂ ≌ D₃) (w' : E.functor ⋙ V₃ ≅ V₂ ⋙ E'.functor) {T₁₂ : C₁ ⥤ C₃} {B₁₂ : D₁ ⥤ D₃} (eT : T₁ ⋙ E.functor ≅ T₁₂) diff --git a/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean b/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean index 6237c66e5d64f0..7901a0beb775e5 100644 --- a/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean +++ b/Mathlib/CategoryTheory/GuitartExact/KanExtension.lean @@ -61,7 +61,9 @@ abbrev compTwoSquare (w : TwoSquare T L R B) : L.LeftExtension (T ⋙ F) := (whiskerLeft _ E.hom ≫ (associator _ _ _).inv ≫ whiskerRight w.natTrans _ ≫ (associator _ _ _).hom) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- If `w : TwoSquare T L R B` is a Guitart exact square, and `E` is a left extension of `F` along `R`, then `E` is a pointwise left Kan extension of `F` along `R` at `B.obj X₃` iff `E.compTwoSquare w` is a pointwise left Kan extension @@ -153,7 +155,7 @@ lemma hasLeftKanExtension [w.GuitartExact] section -open Functor +open CategoryTheory.Functor section @@ -178,15 +180,14 @@ noncomputable def lanBaseChange : have := R.lanUnit.naturality_app (T.obj X) τ simp [reassoc_of% this] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma isIso_lanBaseChange_app_iff (F : C₂ ⥤ D) : IsIso (w.lanBaseChange.app F) ↔ IsLeftKanExtension _ ((LeftExtension.mk _ (R.lanUnit.app F)).compTwoSquare w).hom := by rw [lanBaseChange_app, isIso_lanAdjunction_homEquiv_symm_iff] simp -set_option backward.isDefEq.respectTransparency false in instance isIso_lanBaseChange_app (F : C₂ ⥤ D) [R.HasPointwiseLeftKanExtension F] [w.GuitartExact] : IsIso (w.lanBaseChange.app F) := by diff --git a/Mathlib/CategoryTheory/GuitartExact/Quotient.lean b/Mathlib/CategoryTheory/GuitartExact/Quotient.lean index 3a92213979db7c..e4be0bc0edf69b 100644 --- a/Mathlib/CategoryTheory/GuitartExact/Quotient.lean +++ b/Mathlib/CategoryTheory/GuitartExact/Quotient.lean @@ -85,6 +85,7 @@ lemma quotient_of_nonempty_leftHomotopy (e : T ⋙ R ≅ L ⋙ B) CostructuredArrow.homMk (StructuredArrow.homMk P.i₁) (by simp [Z, Z', dsimp% h.h₁]) Zigzag (Z s₁) A₁ := .of_hom f₁ +set_option backward.isDefEq.respectTransparency.types false in lemma quotient_of_nonempty_rightHomotopy (e : T ⋙ R ≅ L ⋙ B) (he : ∀ ⦃X : C⦄ ⦃Y₀ : C₀⦄ (f₀ f₁ : X ⟶ L.obj Y₀) (_ : B.map f₀ = B.map f₁), ∃ (P : PrepathObject Y₀), T.map P.p₀ = T.map P.p₁ ∧ diff --git a/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean b/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean index f4b2708127ba9e..350495b9b9ae7d 100644 --- a/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean +++ b/Mathlib/CategoryTheory/GuitartExact/VerticalComposition.lean @@ -43,6 +43,7 @@ def whiskerVertical (α : L ⟶ L') (β : R' ⟶ R) : namespace GuitartExact +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A 2-square stays Guitart exact if we replace the left and right functors by isomorphic functors. See also `whiskerVertical_iff`. -/ @@ -90,6 +91,7 @@ variable {H₁ : C₁ ⥤ D₁} {L₁ : C₁ ⥤ C₂} {R₁ : D₁ ⥤ D₂} {H {L₂ : C₂ ⥤ C₃} {R₂ : D₂ ⥤ D₃} {H₃ : C₃ ⥤ D₃} (w' : TwoSquare H₂ L₂ R₂ H₃) +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical isomorphism between `w.structuredArrowDownwards Y₁ ⋙ w'.structuredArrowDownwards (R₁.obj Y₁)` and `(w ≫ᵥ w').structuredArrowDownwards Y₁.` -/ @@ -107,7 +109,6 @@ def vComp' {L₁₂ : C₁ ⥤ C₃} {R₁₂ : D₁ ⥤ D₃} (eL : L₁ ⋙ L namespace GuitartExact -set_option backward.isDefEq.respectTransparency false in instance vComp [hw : w.GuitartExact] [hw' : w'.GuitartExact] : (w ≫ᵥ w').GuitartExact := by simp only [TwoSquare.guitartExact_iff_initial] @@ -121,7 +122,6 @@ instance vComp' [GuitartExact w] [GuitartExact w'] {L₁₂ : C₁ ⥤ C₃} dsimp only [TwoSquare.vComp'] infer_instance -set_option backward.isDefEq.respectTransparency false in lemma of_vComp [R₁.EssSurj] [w.GuitartExact] [(w ≫ᵥ w').GuitartExact] : w'.GuitartExact := by rw [guitartExact_iff_initial] @@ -178,6 +178,7 @@ lemma vComp_iff_of_equivalences (eL : C₂ ≌ C₃) (eR : D₂ ≌ D₃) · intro exact vComp w w'.hom +set_option backward.isDefEq.respectTransparency.types false in lemma vComp'_iff_of_equivalences (E : C₂ ≌ C₃) (E' : D₂ ≌ D₃) (w' : H₂ ⋙ E'.functor ≅ E.functor ⋙ H₃) {L₁₂ : C₁ ⥤ C₃} {R₁₂ : D₁ ⥤ D₃} (eL : L₁ ⋙ E.functor ≅ L₁₂) diff --git a/Mathlib/CategoryTheory/Idempotents/Basic.lean b/Mathlib/CategoryTheory/Idempotents/Basic.lean index 634afd5e7ed2d0..501aa8122530fb 100644 --- a/Mathlib/CategoryTheory/Idempotents/Basic.lean +++ b/Mathlib/CategoryTheory/Idempotents/Basic.lean @@ -140,7 +140,6 @@ theorem split_iff_of_iso {X X' : C} (φ : X ≅ X') (p : X ⟶ X) (p' : X' ⟶ X slice_rhs 2 3 => rw [hpp'] simp -set_option backward.isDefEq.respectTransparency false in theorem Equivalence.isIdempotentComplete {D : Type*} [Category* D] (ε : C ≌ D) (h : IsIdempotentComplete C) : IsIdempotentComplete D := by refine ⟨?_⟩ diff --git a/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean b/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean index 113db5b6ae5b34..4e6ec289e32ad4 100644 --- a/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean +++ b/Mathlib/CategoryTheory/Idempotents/FunctorCategories.lean @@ -87,6 +87,7 @@ namespace KaroubiFunctorCategoryEmbedding variable {J C} +set_option backward.isDefEq.respectTransparency.types false in /-- On objects, the functor which sends a formal direct factor `P` of a functor `F : J ⥤ C` to the functor `J ⥤ Karoubi C` which sends `(j : J)` to the corresponding direct factor of `F.obj j`. -/ @@ -101,6 +102,7 @@ def obj (P : Karoubi (J ⥤ C)) : J ⥤ Karoubi C where rw [NatTrans.comp_app] at h rw [reassoc_of% h, reassoc_of% h] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Tautological action on maps of the functor `Karoubi (J ⥤ C) ⥤ (J ⥤ Karoubi C)`. -/ @[simps] @@ -138,6 +140,7 @@ instance : (karoubiFunctorCategoryEmbedding J C).Faithful where ext j exact hom_ext_iff.mp (congr_app h j) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The composition of `(J ⥤ C) ⥤ Karoubi (J ⥤ C)` and `Karoubi (J ⥤ C) ⥤ (J ⥤ Karoubi C)` equals the functor `(J ⥤ C) ⥤ (J ⥤ Karoubi C)` given by the composition with diff --git a/Mathlib/CategoryTheory/Idempotents/FunctorExtension.lean b/Mathlib/CategoryTheory/Idempotents/FunctorExtension.lean index 0a33a4a315ebd3..0858e0fcbbe486 100644 --- a/Mathlib/CategoryTheory/Idempotents/FunctorExtension.lean +++ b/Mathlib/CategoryTheory/Idempotents/FunctorExtension.lean @@ -28,10 +28,11 @@ namespace CategoryTheory namespace Idempotents -open Category Karoubi Functor +open Category Karoubi CategoryTheory.Functor variable {C D E : Type*} [Category* C] [Category* D] [Category* E] +set_option backward.isDefEq.respectTransparency.types false in /-- A natural transformation between functors `Karoubi C ⥤ D` is determined by its value on objects coming from `C`. -/ theorem natTrans_eq {F G : Karoubi C ⥤ D} (φ : F ⟶ G) (P : Karoubi C) : @@ -100,6 +101,7 @@ def functorExtension₁ : (C ⥤ Karoubi D) ⥤ Karoubi C ⥤ Karoubi D where slice_rhs 1 2 => rw [h'] simp only [assoc] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism expressing that functors `Karoubi C ⥤ Karoubi D` obtained using `functorExtension₁` actually extend the original functors `C ⥤ Karoubi D`. -/ @@ -155,6 +157,7 @@ def KaroubiUniversal₁.counitIso : attribute [simps!] KaroubiUniversal₁.counitIso +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories `(C ⥤ Karoubi D) ≌ (Karoubi C ⥤ Karoubi D)`. -/ @[simps] @@ -168,6 +171,7 @@ def karoubiUniversal₁ : C ⥤ Karoubi D ≌ Karoubi C ⥤ Karoubi D where dsimp rw [comp_p, ← comp_f, ← F.map_comp, P.idem] +set_option backward.isDefEq.respectTransparency.types false in /-- Compatibility isomorphisms of `functorExtension₁` with respect to the composition of functors. -/ def functorExtension₁Comp (F : C ⥤ Karoubi D) (G : D ⥤ Karoubi E) : @@ -175,11 +179,13 @@ def functorExtension₁Comp (F : C ⥤ Karoubi D) (G : D ⥤ Karoubi E) : (functorExtension₁ C D).obj F ⋙ (functorExtension₁ D E).obj G := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical functor `(C ⥤ D) ⥤ (Karoubi C ⥤ Karoubi D)` -/ @[simps!] def functorExtension₂ : (C ⥤ D) ⥤ Karoubi C ⥤ Karoubi D := (whiskeringRight C D (Karoubi D)).obj (toKaroubi D) ⋙ functorExtension₁ C D +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism expressing that functors `Karoubi C ⥤ Karoubi D` obtained using `functorExtension₂` actually extend the original functors `C ⥤ D`. -/ @@ -243,6 +249,7 @@ instance : ((whiskeringLeft C (Karoubi C) D).obj (toKaroubi C)).IsEquivalence := variable {C D} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem whiskeringLeft_obj_preimage_app {F G : Karoubi C ⥤ D} (τ : toKaroubi _ ⋙ F ⟶ toKaroubi _ ⋙ G) (P : Karoubi C) : diff --git a/Mathlib/CategoryTheory/Idempotents/HomologicalComplex.lean b/Mathlib/CategoryTheory/Idempotents/HomologicalComplex.lean index e841b869bd8244..4c8ad12de08c5a 100644 --- a/Mathlib/CategoryTheory/Idempotents/HomologicalComplex.lean +++ b/Mathlib/CategoryTheory/Idempotents/HomologicalComplex.lean @@ -123,6 +123,7 @@ def inverse : HomologicalComplex (Karoubi C) c ⥤ Karoubi (HomologicalComplex C map f := Inverse.map f set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- The counit isomorphism of the equivalence `Karoubi (HomologicalComplex C c) ≌ HomologicalComplex (Karoubi C) c`. -/ @[simps!] @@ -180,6 +181,7 @@ end KaroubiHomologicalComplexEquivalence variable (C) (c) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Karoubi (HomologicalComplex C c) ≌ HomologicalComplex (Karoubi C) c`. -/ @[simps] @@ -192,11 +194,13 @@ def karoubiHomologicalComplexEquivalence : variable (α : Type*) [AddRightCancelSemigroup α] [One α] +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence `Karoubi (ChainComplex C α) ≌ ChainComplex (Karoubi C) α`. -/ @[simps!] def karoubiChainComplexEquivalence : Karoubi (ChainComplex C α) ≌ ChainComplex (Karoubi C) α := karoubiHomologicalComplexEquivalence C (ComplexShape.down α) +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence `Karoubi (CochainComplex C α) ≌ CochainComplex (Karoubi C) α`. -/ @[simps!] def karoubiCochainComplexEquivalence : diff --git a/Mathlib/CategoryTheory/Idempotents/Karoubi.lean b/Mathlib/CategoryTheory/Idempotents/Karoubi.lean index ccd3388c1f67ac..d15d8a1322996c 100644 --- a/Mathlib/CategoryTheory/Idempotents/Karoubi.lean +++ b/Mathlib/CategoryTheory/Idempotents/Karoubi.lean @@ -135,7 +135,7 @@ end Karoubi /-- The obvious fully faithful functor `toKaroubi` sends an object `X : C` to the obvious formal direct factor of `X` given by `𝟙 X`. -/ -@[simps] +@[simps, implicit_reducible] def toKaroubi : C ⥤ Karoubi C where obj X := ⟨X, 𝟙 X, by rw [comp_id]⟩ map f := ⟨f, by simp only [comp_id, id_comp]⟩ @@ -261,6 +261,7 @@ theorem decompId (P : Karoubi C) : 𝟙 P = decompId_i P ≫ decompId_p P := by ext simp only [comp_f, id_f, P.idem, decompId_i, decompId_p] +set_option backward.isDefEq.respectTransparency.types false in theorem decomp_p (P : Karoubi C) : (toKaroubi C).map P.p = decompId_p P ≫ decompId_i P := by ext simp only [comp_f, decompId_p_f, decompId_i_f, P.idem, toKaroubi_map_f] diff --git a/Mathlib/CategoryTheory/Idempotents/KaroubiKaroubi.lean b/Mathlib/CategoryTheory/Idempotents/KaroubiKaroubi.lean index d8eba8e94090b2..3e7183ed572ea1 100644 --- a/Mathlib/CategoryTheory/Idempotents/KaroubiKaroubi.lean +++ b/Mathlib/CategoryTheory/Idempotents/KaroubiKaroubi.lean @@ -30,28 +30,34 @@ namespace KaroubiKaroubi variable (C : Type*) [Category* C] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma idem_f (P : Karoubi (Karoubi C)) : P.p.f ≫ P.p.f = P.p.f := by simpa only [hom_ext_iff, comp_f] using P.idem +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma p_comm_f {P Q : Karoubi (Karoubi C)} (f : P ⟶ Q) : P.p.f ≫ f.f.f = f.f.f ≫ Q.p.f := by simpa only [hom_ext_iff, comp_f] using p_comm f +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical functor `Karoubi (Karoubi C) ⥤ Karoubi C` -/ @[simps] def inverse : Karoubi (Karoubi C) ⥤ Karoubi C where obj P := ⟨P.X.X, P.p.f, by simpa only [hom_ext_iff] using! P.idem⟩ map f := ⟨f.f.f, by simpa only [hom_ext_iff] using! f.comm⟩ +set_option backward.isDefEq.respectTransparency.types false in instance [Preadditive C] : Functor.Additive (inverse C) where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit isomorphism of the equivalence -/ @[simps!] def unitIso : 𝟭 (Karoubi C) ≅ toKaroubi (Karoubi C) ⋙ inverse C := eqToIso (Functor.ext (by cat_disch) (by simp)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] p_comm_f in /-- The counit isomorphism of the equivalence -/ @@ -60,6 +66,7 @@ def counitIso : inverse C ⋙ toKaroubi (Karoubi C) ≅ 𝟭 (Karoubi (Karoubi C hom := { app := fun P => { f := { f := P.p.1 } } } inv := { app := fun P => { f := { f := P.p.1 } } } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Karoubi C ≌ Karoubi (Karoubi C)` -/ @[simps] @@ -69,9 +76,11 @@ def equivalence : Karoubi C ≌ Karoubi (Karoubi C) where unitIso := KaroubiKaroubi.unitIso C counitIso := KaroubiKaroubi.counitIso C +set_option backward.isDefEq.respectTransparency.types false in instance equivalence.additive_functor [Preadditive C] : Functor.Additive (equivalence C).functor where +set_option backward.isDefEq.respectTransparency.types false in instance equivalence.additive_inverse [Preadditive C] : Functor.Additive (equivalence C).inverse where diff --git a/Mathlib/CategoryTheory/InducedCategory.lean b/Mathlib/CategoryTheory/InducedCategory.lean index ab5713f5ed3bcb..6d2d67871f9655 100644 --- a/Mathlib/CategoryTheory/InducedCategory.lean +++ b/Mathlib/CategoryTheory/InducedCategory.lean @@ -42,7 +42,7 @@ variable (F : C → D) which provides a category structure so that the morphisms `X ⟶ Y` are the morphisms in `D` from `F X` to `F Y`. -/ -@[nolint unusedArguments] +@[nolint unusedArguments, implicit_reducible] def InducedCategory (_F : C → D) : Type u₁ := C @@ -97,7 +97,7 @@ end InducedCategory /-- The forgetful functor from an induced category to the original category, forgetting the extra data. -/ -@[simps] +@[simps, implicit_reducible] def inducedFunctor : InducedCategory D F ⥤ D where obj := F map f := f.hom diff --git a/Mathlib/CategoryTheory/IsConnected.lean b/Mathlib/CategoryTheory/IsConnected.lean index 9ba6de15ee9e52..e35b960ff12f34 100644 --- a/Mathlib/CategoryTheory/IsConnected.lean +++ b/Mathlib/CategoryTheory/IsConnected.lean @@ -371,7 +371,7 @@ theorem Zigzag.of_inv_inv {j₁ j₂ j₃ : J} (f₂₁ : j₂ ⟶ j₁) (f₃ /-- The setoid given by the equivalence relation `Zigzag`. A quotient for this setoid is a connected component of the category. -/ -@[implicit_reducible] +@[instance_reducible] def Zigzag.setoid (J : Type u₂) [Category.{v₁} J] : Setoid J where r := Zigzag iseqv := zigzag_equivalence @@ -473,6 +473,7 @@ def discreteIsConnectedEquivPUnit {α : Type u₁} [IsConnected (Discrete α)] : variable {C : Type w₂} [Category.{w₁} C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For objects `X Y : C`, any natural transformation `α : const X ⟶ const Y` from a connected category must be constant. diff --git a/Mathlib/CategoryTheory/IsoCat.lean b/Mathlib/CategoryTheory/IsoCat.lean index 7ea4f5f75f0571..b1bb84307ce055 100644 --- a/Mathlib/CategoryTheory/IsoCat.lean +++ b/Mathlib/CategoryTheory/IsoCat.lean @@ -31,7 +31,7 @@ to be preferred. namespace CategoryTheory -open Functor NatIso Category +open CategoryTheory.Functor NatIso Category variable {C : Type*} {D : Type*} {E : Type*} [Category* C] [Category* D] [Category* E] variable (F : C ⥤ D) (G : D ⥤ E) @@ -124,6 +124,7 @@ noncomputable def strictInv : D ⥤ C where map f := F.preimage (eqToHom (by simp) ≫ f ≫ eqToHom (by simp)) map_comp _ _ := by simp [← preimage_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor that is an isomorphism of categories assembles into an `IsoCat`, with `Functor.strictInv` as its inverse. -/ diff --git a/Mathlib/CategoryTheory/Join/Basic.lean b/Mathlib/CategoryTheory/Join/Basic.lean index cdb00e70c5b904..ed78b9c51f150e 100644 --- a/Mathlib/CategoryTheory/Join/Basic.lean +++ b/Mathlib/CategoryTheory/Join/Basic.lean @@ -41,7 +41,7 @@ universe v₁ v₂ v₃ v₄ v₅ v₆ u₁ u₂ u₃ u₄ u₅ u₆ namespace CategoryTheory -open Functor +open CategoryTheory.Functor /-- Elements of `Join C D` are either elements of `C` or elements of `D`. -/ -- Impl. : We are not defining it as a type alias for `C ⊕ D` so that we can have @@ -268,6 +268,7 @@ lemma mkFunctor_map_inclRight {d d' : D} (f : d ⟶ d') : (mkFunctor F G α).map ((inclRight C D).map f) = G.map f := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering `mkFunctor F G α` with the universal transformation gives back `α`. -/ @[simp] @@ -344,7 +345,6 @@ lemma eq_mkNatTrans {F F' : C ⋆ D ⥤ E} (α : F ⟶ F') : section -set_option backward.isDefEq.respectTransparency false in /-- `mkNatTrans` respects vertical composition. -/ lemma mkNatTransComp {F F' F'' : C ⋆ D ⥤ E} @@ -409,6 +409,7 @@ def mapPairRight : inclRight _ _ ⋙ mapPair Fₗ Fᵣ ≅ Fᵣ ⋙ inclRight _ end mapPair +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Any functor out of a join is naturally isomorphic to a functor of the form `mkFunctor F G α`. -/ @[simps!] @@ -446,6 +447,7 @@ section mapPairComp variable (Fₗ : C ⥤ E) (Fᵣ : D ⥤ E') (Gₗ : E ⥤ J) (Gᵣ : E' ⥤ K) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma mapPairComp_hom_app_left (c : C) : @@ -453,6 +455,7 @@ lemma mapPairComp_hom_app_left (c : C) : dsimp [mapPairComp] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma mapPairComp_hom_app_right (d : D) : @@ -485,6 +488,9 @@ variable {E : Type u₃} [Category.{v₃} E] variable {C D} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A natural transformation `Fₗ ⟶ Gₗ` induces a natural transformation `mapPair Fₗ H ⟶ mapPair Gₗ H` for every `H : D ⥤ E'`. -/ @[simps!] @@ -494,6 +500,7 @@ def mapWhiskerRight {Fₗ : C ⥤ E} {Gₗ : C ⥤ E} (α : Fₗ ⟶ Gₗ) (H : ((mapPairLeft Fₗ H).hom ≫ whiskerRight α (inclLeft E E') ≫ (mapPairLeft Gₗ H).inv) ((mapPairRight Fₗ H).hom ≫ whiskerRight (𝟙 H) (inclRight E E') ≫ (mapPairRight Gₗ H).inv) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma mapWhiskerRight_comp {Fₗ : C ⥤ E} {Gₗ : C ⥤ E} {Hₗ : C ⥤ E} @@ -507,6 +514,9 @@ lemma mapWhiskerRight_id (Fₗ : C ⥤ E) (H : D ⥤ E') : mapWhiskerRight (𝟙 Fₗ) H = 𝟙 _ := by cat_disch +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A natural transformation `Fᵣ ⟶ Gᵣ` induces a natural transformation `mapPair H Fᵣ ⟶ mapPair H Gᵣ` for every `H : C ⥤ E`. -/ @[simps!] @@ -516,6 +526,7 @@ def mapWhiskerLeft (H : C ⥤ E) {Fᵣ : D ⥤ E'} {Gᵣ : D ⥤ E'} (α : Fᵣ ((mapPairLeft H Fᵣ).hom ≫ whiskerRight (𝟙 H) (inclLeft E E') ≫ (mapPairLeft H Gᵣ).inv) ((mapPairRight H Fᵣ).hom ≫ whiskerRight α (inclRight E E') ≫ (mapPairRight H Gᵣ).inv) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma mapWhiskerLeft_comp {Fᵣ : D ⥤ E'} {Gᵣ : D ⥤ E'} {Hᵣ : D ⥤ E'} @@ -529,6 +540,15 @@ lemma mapWhiskerLeft_id (H : C ⥤ E) (Fᵣ : D ⥤ E') : mapWhiskerLeft H (𝟙 Fᵣ) = 𝟙 _ := by cat_disch +#adaptation_note +/-- +The statement of `mapWhiskerLeft_app` and `mapWhiskerRight_app` was determined using `simp` with +`respectTransparency.types false`. In order to apply these, we need a matching normal form. +We achieve this using `respectTransparency.types false` on this lemma, too. +Probable fix: Figure out what the intended statement of `mapWhiskerLeft_app` and +`mapWhiskerRight_app` is, and only then fix this lemma. +-/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- One can exchange `mapWhiskerLeft` and `mapWhiskerRight`. -/ lemma mapWhisker_exchange (Fₗ : C ⥤ E) (Gₗ : C ⥤ E) (Fᵣ : D ⥤ E') (Gᵣ : D ⥤ E') @@ -538,6 +558,9 @@ lemma mapWhisker_exchange (Fₗ : C ⥤ E) (Gₗ : C ⥤ E) (Fᵣ : D ⥤ E') (G ext cat_disch +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A natural isomorphism `Fᵣ ≅ Gᵣ` induces a natural isomorphism `mapPair H Fᵣ ≅ mapPair H Gᵣ` for every `H : C ⥤ E`. -/ @[simps!] @@ -547,6 +570,9 @@ def mapIsoWhiskerLeft (H : C ⥤ E) {Fᵣ : D ⥤ E'} {Gᵣ : D ⥤ E'} (α : F (mapPairLeft H Fᵣ ≪≫ isoWhiskerRight (Iso.refl H) (inclLeft _ _) ≪≫ (mapPairLeft H Gᵣ).symm) (mapPairRight H Fᵣ ≪≫ isoWhiskerRight α (inclRight E E') ≪≫ (mapPairRight H Gᵣ).symm) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A natural isomorphism `Fᵣ ≅ Gᵣ` induces a natural isomorphism `mapPair Fₗ H ≅ mapPair Gₗ H` for every `H : C ⥤ E`. -/ @[simps!] @@ -559,6 +585,15 @@ def mapIsoWhiskerRight {Fₗ : C ⥤ E} {Gₗ : C ⥤ E} (α : Fₗ ≅ Gₗ) (H lemma mapIsoWhiskerRight_hom {Fₗ : C ⥤ E} {Gₗ : C ⥤ E} (α : Fₗ ≅ Gₗ) (H : D ⥤ E') : (mapIsoWhiskerRight α H).hom = mapWhiskerRight α.hom H := rfl +#adaptation_note +/-- +The statement of `mapWhiskerLeft_app` and `mapWhiskerRight_app` was determined using `simp` with +`respectTransparency.types false`. In order to apply these, we need a matching normal form. +We achieve this using `respectTransparency.types false` on this lemma, too. +Probable fix: Figure out what the intended statement of `mapWhiskerLeft_app` and +`mapWhiskerRight_app` is, and only then fix this lemma. +-/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma mapIsoWhiskerRight_inv {Fₗ : C ⥤ E} {Gₗ : C ⥤ E} (α : Fₗ ≅ Gₗ) (H : D ⥤ E') : (mapIsoWhiskerRight α H).inv = mapWhiskerRight α.inv H := by @@ -568,6 +603,15 @@ lemma mapIsoWhiskerRight_inv {Fₗ : C ⥤ E} {Gₗ : C ⥤ E} (α : Fₗ ≅ G lemma mapIsoWhiskerLeft_hom (H : C ⥤ E) {Fᵣ : D ⥤ E'} {Gᵣ : D ⥤ E'} (α : Fᵣ ≅ Gᵣ) : (mapIsoWhiskerLeft H α).hom = mapWhiskerLeft H α.hom := rfl +#adaptation_note +/-- +The statement of `mapWhiskerLeft_app` and `mapWhiskerRight_app` was determined using `simp` with +`respectTransparency.types false`. In order to apply these, we need a matching normal form. +We achieve this using `respectTransparency.types false` on this lemma, too. +Probable fix: Figure out what the intended statement of `mapWhiskerLeft_app` and +`mapWhiskerRight_app` is, and only then fix this lemma. +-/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma mapIsoWhiskerLeft_inv (H : C ⥤ E) {Fᵣ : D ⥤ E'} {Gᵣ : D ⥤ E'} (α : Fᵣ ≅ Gᵣ) : (mapIsoWhiskerLeft H α).inv = mapWhiskerLeft H α.inv := by diff --git a/Mathlib/CategoryTheory/Join/Final.lean b/Mathlib/CategoryTheory/Join/Final.lean index aadf77e3d8e6d0..99ab2a8b108822 100644 --- a/Mathlib/CategoryTheory/Join/Final.lean +++ b/Mathlib/CategoryTheory/Join/Final.lean @@ -23,6 +23,7 @@ namespace CategoryTheory.Join variable (C D : Type*) [Category* C] [Category* D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of `Join.inclLeft C D`-costructured arrows with target `right d` is equivalent to `C`. -/ @@ -34,6 +35,7 @@ def costructuredArrowEquiv (d : D) : CostructuredArrow (inclLeft C D) (right d) unitIso := NatIso.ofComponents (fun _ ↦ CostructuredArrow.isoMk (Iso.refl _)) counitIso := NatIso.ofComponents (fun _ ↦ Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of `Join.inclRight C D`-structured arrows with source `left c` is equivalent to `D`. -/ diff --git a/Mathlib/CategoryTheory/Join/Opposites.lean b/Mathlib/CategoryTheory/Join/Opposites.lean index a97fd3398380b2..6ee3caddab811a 100644 --- a/Mathlib/CategoryTheory/Join/Opposites.lean +++ b/Mathlib/CategoryTheory/Join/Opposites.lean @@ -19,12 +19,13 @@ This equivalence is characterized in both directions. @[expose] public section namespace CategoryTheory.Join -open Opposite Functor +open Opposite CategoryTheory.Functor universe v₁ v₂ u₁ u₂ variable (C : Type u₁) (D : Type u₂) [Category.{v₁} C] [Category.{v₂} D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `(C ⋆ D)ᵒᵖ ≌ Dᵒᵖ ⋆ Cᵒᵖ` induced by `Join.opEquivFunctor` and `Join.opEquivInverse`. -/ @@ -48,105 +49,123 @@ def opEquiv : (C ⋆ D)ᵒᵖ ≌ Dᵒᵖ ⋆ Cᵒᵖ where | op (left _) => by cat_disch | op (right _) => by cat_disch +set_option backward.isDefEq.respectTransparency.types false in variable {C} in @[simp] lemma opEquiv_functor_obj_op_left (c : C) : (opEquiv C D).functor.obj (op <| left c) = right (op c) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma opEquiv_functor_obj_op_right (d : D) : (opEquiv C D).functor.obj (op <| right d) = left (op d) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {C} in @[simp] lemma opEquiv_functor_map_op_inclLeft {c c' : C} (f : c ⟶ c') : (opEquiv C D).functor.map (op <| (inclLeft C D).map f) = (inclRight _ _).map (op f) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma opEquiv_functor_map_op_inclRight {d d' : D} (f : d ⟶ d') : (opEquiv C D).functor.map (op <| (inclRight C D).map f) = (inclLeft _ _).map (op f) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {C D} in lemma opEquiv_functor_map_op_edge (c : C) (d : D) : (opEquiv C D).functor.map (op <| edge c d) = edge (op d) (op c) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize (up to a rightOp) the action of the left inclusion on `Join.opEquivFunctor`. -/ @[simps!] def InclLeftCompRightOpOpEquivFunctor : inclLeft C D ⋙ (opEquiv C D).functor.rightOp ≅ (inclRight _ _).rightOp := isoWhiskerLeft _ (leftOpRightOpIso _) ≪≫ mkFunctorLeft _ _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize (up to a rightOp) the action of the right inclusion on `Join.opEquivFunctor`. -/ @[simps!] def InclRightCompRightOpOpEquivFunctor : inclRight C D ⋙ (opEquiv C D).functor.rightOp ≅ (inclLeft _ _).rightOp := isoWhiskerLeft _ (leftOpRightOpIso _) ≪≫ mkFunctorRight _ _ _ +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma opEquiv_inverse_obj_left_op (d : D) : (opEquiv C D).inverse.obj (left <| op d) = op (right d) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {C} in @[simp] lemma opEquiv_inverse_obj_right_op (c : C) : (opEquiv C D).inverse.obj (right <| op c) = op (left c) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma opEquiv_inverse_map_inclLeft_op {d d' : D} (f : d ⟶ d') : (opEquiv C D).inverse.map ((inclLeft Dᵒᵖ Cᵒᵖ).map f.op) = op ((inclRight _ _).map f) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma opEquiv_inverse_map_inclRight_op {c c' : C} (f : c ⟶ c') : (opEquiv C D).inverse.map ((inclRight Dᵒᵖ Cᵒᵖ).map f.op) = op ((inclLeft _ _).map f) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {C D} in @[simp] lemma opEquiv_inverse_map_edge_op (c : C) (d : D) : (opEquiv C D).inverse.map (edge (op d) (op c)) = op (edge c d) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize `Join.opEquivInverse` with respect to the left inclusion -/ def inclLeftCompOpEquivInverse : Join.inclLeft Dᵒᵖ Cᵒᵖ ⋙ (opEquiv C D).inverse ≅ (inclRight _ _).op := Join.mkFunctorLeft _ _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize `Join.opEquivInverse` with respect to the right inclusion -/ def inclRightCompOpEquivInverse : Join.inclRight Dᵒᵖ Cᵒᵖ ⋙ (opEquiv C D).inverse ≅ (inclLeft _ _).op := Join.mkFunctorRight _ _ _ +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma inclLeftCompOpEquivInverse_hom_app_op (d : D) : (inclLeftCompOpEquivInverse C D).hom.app (op d) = 𝟙 (op <| right d) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {C} in @[simp] lemma inclRightCompOpEquivInverse_hom_app_op (c : C) : (inclRightCompOpEquivInverse C D).hom.app (op c) = 𝟙 (op <| left c) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {D} in @[simp] lemma inclLeftCompOpEquivInverse_inv_app_op (d : D) : (inclLeftCompOpEquivInverse C D).inv.app (op d) = 𝟙 (op <| right d) := rfl +set_option backward.isDefEq.respectTransparency.types false in variable {C} in @[simp] lemma inclRightCompOpEquivInverse_inv_app_op (c : C) : diff --git a/Mathlib/CategoryTheory/Join/Pseudofunctor.lean b/Mathlib/CategoryTheory/Join/Pseudofunctor.lean index 33acdb874981e0..0750fec1200523 100644 --- a/Mathlib/CategoryTheory/Join/Pseudofunctor.lean +++ b/Mathlib/CategoryTheory/Join/Pseudofunctor.lean @@ -23,7 +23,7 @@ universe v₁ v₂ u₁ u₂ namespace CategoryTheory.Join -open Bicategory Functor +open Bicategory CategoryTheory.Functor -- The proof gets too slow if we put it in a single `pseudofunctor` constructor, -- so we break down the component proofs for the pseudofunctors over several lemmas. @@ -44,6 +44,15 @@ def mapCompLeft (F : A ⥤ B) (G : B ⥤ C) : mapPair (F ⋙ G) (𝟭 D) ≅ mapPair F (𝟭 D) ⋙ mapPair G (𝟭 D) := mapIsoWhiskerLeft _ (Functor.leftUnitor _).symm ≪≫ mapPairComp F (𝟭 D) G (𝟭 D) +#adaptation_note +/-- +`mapIsoWhiskerRight`'s `simps` theorems were formulated in simp normal form under +`respectTransparency.types true`. We use `respectTransparency.types false` here because these +lemmas fail to match without this annotation. +Suggested way forward: Decide what the correct signatures of the `mapIsoWhiskerRight` lemmas +are, then update this proof accordingly. +-/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (A) in @[reassoc] @@ -53,6 +62,15 @@ lemma mapWhiskerLeft_whiskerLeft (F : B ⥤ C) {G H : C ⥤ D} (η : G ⟶ H) : (mapCompRight A F H).inv := by apply natTrans_ext <;> ext <;> simp [mapCompRight] +#adaptation_note +/-- +`mapIsoWhiskerLeft`'s `simps` theorems were formulated in simp normal form under +`respectTransparency.types true`. We use `respectTransparency.types false` here because these +lemmas fail to match without this annotation. +Suggested way forward: Decide what the correct signatures of the `mapIsoWhiskerLeft` lemmas +are, then update this proof accordingly. +-/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (D) in @[reassoc] @@ -137,6 +155,9 @@ lemma mapWhiskerRight_rightUnitor_hom (F : A ⥤ B) : end +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The pseudofunctor sending `D` to `C ⋆ D`. -/ @[simps!] def pseudofunctorRight (C : Type u₁) [Category.{v₁} C] : @@ -152,6 +173,9 @@ def pseudofunctorRight (C : Type u₁) [Category.{v₁} C] : map₂_left_unitor := by intros; exact congr($(mapWhiskerLeft_leftUnitor_hom C _).toCatHom₂) map₂_right_unitor := by intros; exact congr($(mapWhiskerLeft_rightUnitor_hom C _).toCatHom₂) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The pseudofunctor sending `C` to `C ⋆ D`. -/ @[simps!] def pseudofunctorLeft (D : Type u₂) [Category.{v₂} D] : diff --git a/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean b/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean index b9ea0cdb10db0d..96817d254b26d4 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean @@ -35,7 +35,6 @@ section variable {A B : C} {X Y : D} {i : A ⟶ B} {p : X ⟶ Y} {u : G.obj A ⟶ X} {v : G.obj B ⟶ Y} -set_option backward.isDefEq.respectTransparency false in /-- When we have an adjunction `G ⊣ F`, any commutative square where the left map is of the form `G.map i` and the right map is `p` has an "adjoint" commutative square whose left map is `i` and whose right map is `F.map p`. -/ diff --git a/Mathlib/CategoryTheory/LiftingProperties/Over.lean b/Mathlib/CategoryTheory/LiftingProperties/Over.lean index 9b7e311cf01bb8..f719b440634a55 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/Over.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/Over.lean @@ -47,6 +47,7 @@ end CommSq.HasLift namespace HasLiftingProperty +set_option backward.isDefEq.respectTransparency.types false in lemma over {A B X Y : Over S} (i : A ⟶ B) (p : X ⟶ Y) [HasLiftingProperty i.left p.left] : HasLiftingProperty i p := ⟨fun _ ↦ .over⟩ diff --git a/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean b/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean index 6f6fecc53e31cd..20ce9d791e2126 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/PushoutProduct.lean @@ -28,7 +28,7 @@ universe v u namespace CategoryTheory -open Limits MonoidalCategory Functor PushoutObjObj +open Limits MonoidalCategory CategoryTheory.Functor PushoutObjObj variable {C : Type u} [Category.{v} C] diff --git a/Mathlib/CategoryTheory/Limits/Chosen/End.lean b/Mathlib/CategoryTheory/Limits/Chosen/End.lean index 6e01480689f9b9..96f3eb2749d6aa 100644 --- a/Mathlib/CategoryTheory/Limits/Chosen/End.lean +++ b/Mathlib/CategoryTheory/Limits/Chosen/End.lean @@ -53,6 +53,7 @@ lemma chosenCoend.condition {i j : J} (f : i ⟶ j) : variable {F} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Morphisms out of the chosen coend are determined by their composites with `chosenCoend.ι`. -/ @[ext] diff --git a/Mathlib/CategoryTheory/Limits/ColimitLimit.lean b/Mathlib/CategoryTheory/Limits/ColimitLimit.lean index 16ac33f00c7c5e..efe2c1aef55f3e 100644 --- a/Mathlib/CategoryTheory/Limits/ColimitLimit.lean +++ b/Mathlib/CategoryTheory/Limits/ColimitLimit.lean @@ -38,7 +38,7 @@ variable {J : Type u₁} {K : Type u₂} [Category.{v₁} J] [Category.{v₂} K] variable {C : Type u} [Category.{v} C] variable (F : J × K ⥤ C) -open CategoryTheory.prod Prod +open CategoryTheory.prod CategoryTheory.Prod theorem map_id_left_eq_curry_map {j : J} {k k' : K} {f : k ⟶ k'} : F.map (𝟙 j ×ₘ f) = ((curry.obj F).obj j).map f := diff --git a/Mathlib/CategoryTheory/Limits/Comma.lean b/Mathlib/CategoryTheory/Limits/Comma.lean index a8fdbc1630c0d0..533ff3d5c66815 100644 --- a/Mathlib/CategoryTheory/Limits/Comma.lean +++ b/Mathlib/CategoryTheory/Limits/Comma.lean @@ -29,7 +29,7 @@ The duals of all the above are also given. namespace CategoryTheory -open Category Limits Functor +open Category Limits CategoryTheory.Functor universe w' w v₁ v₂ v₃ u₁ u₂ u₃ diff --git a/Mathlib/CategoryTheory/Limits/ConeCategory.lean b/Mathlib/CategoryTheory/Limits/ConeCategory.lean index 749f8389b77406..3021e131c513ae 100644 --- a/Mathlib/CategoryTheory/Limits/ConeCategory.lean +++ b/Mathlib/CategoryTheory/Limits/ConeCategory.lean @@ -38,14 +38,14 @@ variable {C : Type u₃} [Category.{v₃} C] {D : Type u₄} [Category.{v₄} D] /-- Given a cone `c` over `F`, we can interpret the legs of `c` as structured arrows `c.pt ⟶ F.obj -`. -/ -@[simps] +@[simps, implicit_reducible] def Cone.toStructuredArrow {F : J ⥤ C} (c : Cone F) : J ⥤ StructuredArrow c.pt F where obj j := StructuredArrow.mk (c.π.app j) map f := StructuredArrow.homMk f /-- If `F` has a limit, then the limit projections can be interpreted as structured arrows `limit F ⟶ F.obj -`. -/ -@[simps] +@[simps, implicit_reducible] noncomputable def limit.toStructuredArrow (F : J ⥤ C) [HasLimit F] : J ⥤ StructuredArrow (limit F) F where obj j := StructuredArrow.mk (limit.π F j) @@ -90,6 +90,7 @@ lemma Cone.toStructuredArrow_comp_toUnder_comp_forget {F : J ⥤ C} (c : Cone F) c.toStructuredArrow ⋙ StructuredArrow.toUnder _ _ ⋙ Under.forget _ = F := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A cone `c` on `F : J ⥤ C` lifts to a cone in `Over c.pt` with cone point `𝟙 c.pt`. -/ @[simps] @@ -98,6 +99,7 @@ def Cone.toUnder {F : J ⥤ C} (c : Cone F) : pt := Under.mk (𝟙 c.pt) π := { app := fun j => Under.homMk (c.π.app j) (by simp) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The limit cone for `F : J ⥤ C` lifts to a cocone in `Under (limit F)` with cone point `𝟙 (limit F)`. This is automatically also a limit cone. -/ @@ -106,6 +108,7 @@ noncomputable def limit.toUnder (F : J ⥤ C) [HasLimit F] : pt := Under.mk (𝟙 (limit F)) π := { app := fun j => Under.homMk (limit.π F j) (by simp) } +set_option backward.isDefEq.respectTransparency.types false in /-- `c.toUnder` is a lift of `c` under the forgetful functor. -/ @[simps!] def Cone.mapConeToUnder {F : J ⥤ C} (c : Cone F) : (Under.forget c.pt).mapCone c.toUnder ≅ c := @@ -119,6 +122,7 @@ def Cone.fromStructuredArrow (F : C ⥤ D) {X : D} (G : J ⥤ StructuredArrow X pt := X π := { app := fun j => (G.obj j).hom } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a cone `c : Cone K` and a map `f : X ⟶ F.obj c.X`, we can construct a cone of structured arrows over `X` with `f` as the cone point. @@ -149,6 +153,7 @@ def Cone.fromCostructuredArrow (F : J ⥤ C) : CostructuredArrow (const J) F ⥤ convert! congr_fun (congr_arg NatTrans.app f.w) j simp } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of cones on `F` is just the comma category `(Δ ↓ F)`, where `Δ` is the constant functor. -/ @@ -217,11 +222,13 @@ noncomputable def colimit.toCostructuredArrow (F : J ⥤ C) [HasColimit F] : obj j := CostructuredArrow.mk (colimit.ι F j) map f := CostructuredArrow.homMk f +set_option backward.isDefEq.respectTransparency.types false in /-- `Cocone.toCostructuredArrow` can be expressed in terms of `Functor.toCostructuredArrow`. -/ def Cocone.toCostructuredArrowIsoToCostructuredArrow {F : J ⥤ C} (c : Cocone F) : c.toCostructuredArrow ≅ (𝟭 J).toCostructuredArrow F c.pt c.ι.app (by simp) := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Functor.toCostructuredArrow` can be expressed in terms of `Cocone.toCostructuredArrow`. -/ def _root_.CategoryTheory.Functor.toCostructuredArrowIsoToCostructuredArrow (G : J ⥤ K) @@ -231,6 +238,7 @@ def _root_.CategoryTheory.Functor.toCostructuredArrowIsoToCostructuredArrow (G : (Cocone.mk X ⟨f, by simp [h]⟩).toCostructuredArrow ⋙ CostructuredArrow.pre _ _ _ := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- Interpreting the legs of a cocone as a costructured arrow and then forgetting the arrow again does nothing. -/ @[simps!] @@ -238,11 +246,13 @@ def Cocone.toCostructuredArrowCompProj {F : J ⥤ C} (c : Cocone F) : c.toCostructuredArrow ⋙ CostructuredArrow.proj _ _ ≅ 𝟭 J := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Cocone.toCostructuredArrow_comp_proj {F : J ⥤ C} (c : Cocone F) : c.toCostructuredArrow ⋙ CostructuredArrow.proj _ _ = 𝟭 J := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Interpreting the legs of a cocone as a costructured arrow, interpreting this arrow as an arrow over the cocone point, and finally forgetting the arrow is the same as just applying the functor the cocone was over. -/ @@ -251,11 +261,13 @@ def Cocone.toCostructuredArrowCompToOverCompForget {F : J ⥤ C} (c : Cocone F) c.toCostructuredArrow ⋙ CostructuredArrow.toOver _ _ ⋙ Over.forget _ ≅ F := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Cocone.toCostructuredArrow_comp_toOver_comp_forget {F : J ⥤ C} (c : Cocone F) : c.toCostructuredArrow ⋙ CostructuredArrow.toOver _ _ ⋙ Over.forget _ = F := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A cocone `c` on `F : J ⥤ C` lifts to a cocone in `Over c.pt` with cone point `𝟙 c.pt`. -/ @[simps] @@ -264,6 +276,7 @@ def Cocone.toOver {F : J ⥤ C} (c : Cocone F) : pt := Over.mk (𝟙 c.pt) ι := { app := fun j => Over.homMk (c.ι.app j) (by simp) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The colimit cocone for `F : J ⥤ C` lifts to a cocone in `Over (colimit F)` with cone point `𝟙 (colimit F)`. This is automatically also a colimit cocone. -/ @@ -273,11 +286,13 @@ noncomputable def colimit.toOver (F : J ⥤ C) [HasColimit F] : pt := Over.mk (𝟙 (colimit F)) ι := { app := fun j => Over.homMk (colimit.ι F j) (by simp) } +set_option backward.isDefEq.respectTransparency.types false in /-- `c.toOver` is a lift of `c` under the forgetful functor. -/ @[simps!] def Cocone.mapCoconeToOver {F : J ⥤ C} (c : Cocone F) : (Over.forget c.pt).mapCocone c.toOver ≅ c := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a diagram `CostructuredArrow F X`s, we may obtain a cocone with cone point `X`. -/ @[simps!] @@ -286,6 +301,7 @@ def Cocone.fromCostructuredArrow (F : C ⥤ D) {X : D} (G : J ⥤ CostructuredAr pt := X ι := { app := fun j => (G.obj j).hom } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a cocone `c : Cocone K` and a map `f : F.obj c.X ⟶ X`, we can construct a cocone of costructured arrows over `X` with `f` as the cone point. -/ @@ -314,6 +330,7 @@ def Cocone.fromStructuredArrow (F : J ⥤ C) : StructuredArrow F (const J) ⥤ C { hom := f.right w j := by simp [dsimp% congr_app f.w j] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of cocones on `F` is just the comma category `(F ↓ Δ)`, where `Δ` is the constant functor. -/ diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 6870f7db907606..209218a4748d90 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -150,12 +150,29 @@ instance inhabitedCone (F : Discrete PUnit ⥤ C) : Inhabited (Cone F) := } }⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -@[to_dual (attr := reassoc (attr := simp), elementwise)] +@[to_dual (attr := reassoc), elementwise] theorem Cone.w {F : J ⥤ C} (c : Cone F) {j j' : J} (f : j ⟶ j') : dsimp% c.π.app j ≫ F.map f = c.π.app j' := by simpa using (c.π.naturality f).symm +attribute [simp] Cone.w Cone.w_assoc -- `Cocone.w` and `Cocone.w_assoc` are redundant + +#adaptation_note +/-- +This lemma can be derived by `simp`, so `[elementwise]` does errors out. +For symmetry reasons, it seems good to have the dual of `Cone.w_apply`, though, +so we provide it by hand now. +-/ +theorem Cocone.w_apply.{uF, w} {F : J ⥤ C} (c : Cocone F) {j j' : J} (f : j' ⟶ j) + {F' : C → C → Type uF} {carrier : C → Type w} + {instFunLike : (X Y : C) → FunLike (F' X Y) (carrier X) (carrier Y)} + [inst : ConcreteCategory C F'] (x : carrier (F.obj j')) : + (ConcreteCategory.hom (c.ι.app j)) ((ConcreteCategory.hom (F.map f)) x) = + (ConcreteCategory.hom (c.ι.app j')) x := by + simp + end variable {F : J ⥤ C} @@ -245,10 +262,12 @@ structure CoconeMorphism (A B : Cocone F) where attribute [reassoc (attr := simp)] ConeMorphism.w CoconeMorphism.w attribute [to_dual existing] ConeMorphism.casesOn +set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance inhabitedConeMorphism (A : Cone F) : Inhabited (ConeMorphism A A) := ⟨{ hom := 𝟙 _ }⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The category of cones on a given diagram. -/ @[to_dual (attr := simps) /-- The category of cocones on a given diagram. -/] instance Cone.category : Category (Cone F) where @@ -256,9 +275,7 @@ instance Cone.category : Category (Cone F) where comp f g := { hom := f.hom ≫ g.hom } id B := { hom := 𝟙 B.pt } -/-- We do not want `simps` automatically generate the lemma for simplifying the -hom field of a category. So we need to write the `ext` lemma in terms of the -categorical morphism, rather than the underlying structure. -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := ext) /- We do not want `simps` automatically generate the lemma for simplifying the hom field of a category. So we need to write the `ext` lemma in terms of the @@ -268,20 +285,25 @@ theorem ConeMorphism.ext {c c' : Cone F} (f g : c ⟶ c') (w : f.hom = g.hom) : cases g congr +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp))] lemma ConeMorphism.hom_inv_id {c d : Cone F} (f : c ≅ d) : f.hom.hom ≫ f.inv.hom = 𝟙 _ := by simp [← Cone.category_comp_hom] +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp))] lemma ConeMorphism.inv_hom_id {c d : Cone F} (f : c ≅ d) : f.inv.hom ≫ f.hom.hom = 𝟙 _ := by simp [← Cone.category_comp_hom] +set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance {c d : Cone F} (f : c ≅ d) : IsIso f.hom.hom := ⟨f.inv.hom, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance {c d : Cone F} (f : c ≅ d) : IsIso f.inv.hom := ⟨f.hom.hom, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp))] lemma ConeMorphism.map_w {c c' : Cone F} (f : c ⟶ c') (G : C ⥤ D) (j : J) : G.map f.hom ≫ G.map (c'.π.app j) = G.map (c.π.app j) := by @@ -289,6 +311,7 @@ lemma ConeMorphism.map_w {c c' : Cone F} (f : c ⟶ c') (G : C ⥤ D) (j : J) : namespace Cone +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ @@ -305,6 +328,7 @@ def ext {c c' : Cone F} (φ : c.pt ≅ c'.pt) attribute [to_dual existing extInv_inv_hom] ext_hom_hom attribute [to_dual existing extInv_hom_hom] ext_inv_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ @@ -320,6 +344,7 @@ attribute [to_dual existing ext_inv_hom] extInv_hom_hom attribute [aesop apply safe (rule_sets := [CategoryTheory])] Limits.Cone.ext Limits.Cocone.ext +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Eta rule for cones. -/ @[to_dual (attr := simps!) /-- Eta rule for cocones. -/] @@ -340,11 +365,13 @@ theorem cone_iso_of_hom_iso {K : J ⥤ C} {c d : Cone K} (f : c ⟶ d) [i : IsIs ⟨⟨{ hom := inv f.hom w := fun j => (asIso f.hom).inv_comp_eq.2 (f.w j).symm }, by cat_disch⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- There is a morphism from an extended cone to the original cone. -/ @[to_dual (attr := simps) /-- There is a morphism from a cocone to its extension. -/] def extendHom (s : Cone F) {X : C} (f : X ⟶ s.pt) : s.extend f ⟶ s where hom := f +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Extending a cone by the identity does nothing. -/ @[to_dual (attr := simps!) /-- Extending a cocone by the identity does nothing. -/] @@ -354,6 +381,7 @@ def extendId (s : Cone F) : s.extend (𝟙 s.pt) ≅ s := attribute [to_dual existing extendId_inv_hom] extendId_hom_hom attribute [to_dual existing extendId_hom_hom] extendId_inv_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Extending a cone by a composition is the same as extending the cone twice. -/ @[to_dual (attr := simps!) (reorder := f g) @@ -365,6 +393,7 @@ def extendComp (s : Cone F) {X Y : C} (f : X ⟶ Y) (g : Y ⟶ s.pt) : attribute [to_dual existing extendComp_inv_hom] extendComp_hom_hom attribute [to_dual existing extendComp_hom_hom] extendComp_inv_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- A cone extended by an isomorphism is isomorphic to the original cone. -/ @[to_dual (attr := simps) @@ -380,6 +409,7 @@ attribute [to_dual existing extendIso_hom_hom] extendIso_inv_hom instance {s : Cone F} {X : C} (f : X ⟶ s.pt) [IsIso f] : IsIso (s.extendHom f) := ⟨(extendIso s (asIso' f)).hom, by cat_disch⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Functorially postcompose a cone for `F` by a natural transformation `F ⟶ G` to give a cone for `G`. -/ @@ -392,6 +422,7 @@ def postcompose {G : J ⥤ C} (α : F ⟶ G) : Cone F ⥤ Cone G where π := c.π ≫ α } map f := { hom := f.hom } +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Postcomposing a cone by the composite natural transformation `α ≫ β` is the same as postcomposing by `α` and then by `β`. -/ @@ -405,6 +436,7 @@ def postcomposeComp {G H : J ⥤ C} (α : F ⟶ G) (β : G ⟶ H) : attribute [to_dual existing precomposeComp_inv_app_hom] postcomposeComp_hom_app_hom attribute [to_dual existing precomposeComp_hom_app_hom] postcomposeComp_inv_app_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Postcomposing by the identity does not change the cone up to isomorphism. -/ @[to_dual (attr := simps!) @@ -415,6 +447,7 @@ def postcomposeId : postcompose (𝟙 F) ≅ 𝟭 (Cone F) := attribute [to_dual existing precomposeId_inv_app_hom] postcomposeId_hom_app_hom attribute [to_dual existing precomposeId_hom_app_hom] postcomposeId_inv_app_hom +set_option backward.isDefEq.respectTransparency.types false in /-- If `F` and `G` are naturally isomorphic functors, then they have equivalent categories of cones. -/ @@ -437,6 +470,7 @@ def whiskering (E : K ⥤ J) : Cone F ⥤ Cone (E ⋙ F) where obj c := c.whisker E map f := { hom := f.hom } +set_option backward.isDefEq.respectTransparency.types false in /-- Whiskering by an equivalence gives an equivalence between categories of cones. -/ @[to_dual (attr := simps) @@ -476,6 +510,7 @@ def forget : Cone F ⥤ C where variable (G : C ⥤ D) +set_option backward.isDefEq.respectTransparency.types false in /-- A functor `G : C ⥤ D` sends cones over `F` to cones over `F ⋙ G` functorially. -/ @[to_dual (attr := simps) /-- A functor `G : C ⥤ D` sends cocones over `F` to cocones over `F ⋙ G` functorially. -/] @@ -489,12 +524,14 @@ def functoriality : Cone F ⥤ Cone (F ⋙ G) where { hom := G.map f.hom w := ConeMorphism.map_w f G } +set_option backward.isDefEq.respectTransparency.types false in /-- Functoriality is functorial. -/ @[to_dual /-- Functoriality is functorial. -/] def functorialityCompFunctoriality (H : D ⥤ E) : functoriality F G ⋙ functoriality (F ⋙ G) H ≅ functoriality F (G ⋙ H) := NatIso.ofComponents (fun _ ↦ Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance functoriality_full [G.Full] [G.Faithful] : (functoriality F G).Full where map_surjective t := @@ -506,6 +543,7 @@ instance functoriality_faithful [G.Faithful] : (functoriality F G).Faithful wher map_injective {_X} {_Y} f g h := ConeMorphism.ext f g <| G.map_injective <| congr_arg ConeMorphism.hom h +set_option backward.isDefEq.respectTransparency.types false in /-- If `e : C ≌ D` is an equivalence of categories, then `functoriality F e.functor` induces an equivalence between cones over `F` and cones over `F ⋙ e.functor`. -/ @@ -559,6 +597,7 @@ namespace Cones @[deprecated (since := "2026-03-06")] alias equivalenceOfReindexing := Cone.equivalenceOfReindexing @[deprecated (since := "2026-03-06")] alias forget := Cone.forget @[deprecated (since := "2026-03-06")] alias functoriality := Cone.functoriality +set_option backward.isDefEq.respectTransparency.types false in @[deprecated (since := "2026-03-06")] alias functorialityCompFunctoriality := Cone.functorialityCompFunctoriality @[deprecated (since := "2026-03-06")] alias functoriality_full := Cone.functoriality_full @@ -589,6 +628,7 @@ namespace Cocones alias equivalenceOfReindexing := Cocone.equivalenceOfReindexing @[deprecated (since := "2026-03-06")] alias forget := Cocone.forget @[deprecated (since := "2026-03-06")] alias functoriality := Cocone.functoriality +set_option backward.isDefEq.respectTransparency.types false in @[deprecated (since := "2026-03-06")] alias functorialityCompFunctoriality := Cocone.functorialityCompFunctoriality @[deprecated (since := "2026-03-06")] alias functoriality_full := Cocone.functoriality_full @@ -614,6 +654,7 @@ open CategoryTheory.Limits def mapCone (c : Cone F) : Cone (F ⋙ H) := (Cone.functoriality F H).obj c +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- The construction `mapCone` respects functor composition. -/ @[to_dual (attr := simps!) @@ -652,6 +693,7 @@ noncomputable def mapConeInvMapCone {F : J ⥤ D} (H : D ⥤ C) [IsEquivalence H mapConeInv H (mapCone H c) ≅ c := (Limits.Cone.functorialityEquivalence F (asEquivalence H)).unitIso.symm.app c +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `functoriality F _ ⋙ postcompose (whisker_left F _)` simplifies to `functoriality F _`. -/ @[to_dual (attr := simps!) @@ -665,6 +707,7 @@ attribute [to_dual existing functorialityCompPrecompose_inv_app_hom] attribute [to_dual existing functorialityCompPrecompose_hom_app_hom] functorialityCompPostcompose_inv_app_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- For `F : J ⥤ C`, given a cone `c : Cone F`, and a natural isomorphism `α : H ≅ H'` for functors `H H' : C ⥤ D`, the postcomposition of the cone `H.mapCone` using the isomorphism `α` is @@ -685,6 +728,7 @@ attribute [to_dual existing precomposeWhiskerLeftMapCocone_inv_hom] attribute [to_dual existing precomposeWhiskerLeftMapCocone_hom_hom] postcomposeWhiskerLeftMapCone_inv_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `postcompose`. In particular, for `F : J ⥤ C`, given a cone `c : Cone F`, a @@ -704,6 +748,7 @@ def mapConePostcompose {α : F ⟶ G} {c} : attribute [to_dual existing mapCoconePrecompose_inv_hom] mapConePostcompose_hom_hom attribute [to_dual existing mapCoconePrecompose_hom_hom] mapConePostcompose_inv_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `postcomposeEquivalence` -/ @[to_dual (attr := simps!) /-- `mapCocone` commutes with `precomposeEquivalence` -/] @@ -717,6 +762,7 @@ attribute [to_dual existing mapCoconePrecomposeEquivalenceFunctor_inv_hom] attribute [to_dual existing mapCoconePrecomposeEquivalenceFunctor_hom_hom] mapConePostcomposeEquivalenceFunctor_inv_hom +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `whisker` -/ @[to_dual (attr := simps!) /-- `mapCocone` commutes with `whisker` -/] @@ -777,6 +823,7 @@ def coconeEquivalenceOpConeOp : Cocone F ≌ (Cone F.op)ᵒᵖ where unitIso := Iso.refl _ counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : J ⥤ C` are equivalent to cocones on `F.op : Jᵒᵖ ⥤ Cᵒᵖ`. -/ @[to_dual (attr := simps) /-- Cocones on `F : J ⥤ C` are equivalent to cones on `F.op : Jᵒᵖ ⥤ Cᵒᵖ`. -/] @@ -808,6 +855,7 @@ def coconeLeftOpOfCone (c : Cone F) : Cocone F.leftOp where pt := unop c.pt ι := NatTrans.leftOp c.π +set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : J ⥤ Cᵒᵖ` are equivalent to cocones on `F.leftOp : Jᵒᵖ ⥤ C`. -/ @[to_dual (attr := simps) /-- Cocones on `F : J ⥤ Cᵒᵖ` are equivalent to cones on `F.leftOp : Jᵒᵖ ⥤ C`. -/] @@ -839,6 +887,7 @@ def coconeRightOpOfCone (c : Cone F) : Cocone F.rightOp where pt := op c.pt ι := NatTrans.rightOp c.π +set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : Jᵒᵖ ⥤ C` are equivalent to cocones on `F.rightOp : J ⥤ Cᵒᵖ`. -/ @[to_dual (attr := simps) /-- Cocones on `F : Jᵒᵖ ⥤ C` are equivalent to cones on `F.rightOp : J ⥤ Cᵒᵖ`. -/] @@ -870,6 +919,7 @@ def coconeUnopOfCone (c : Cone F) : Cocone F.unop where pt := unop c.pt ι := NatTrans.unop c.π +set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : Jᵒᵖ ⥤ Cᵒᵖ` are equivalent to cocones on `F.unop : J ⥤ C`. -/ @[to_dual (attr := simps) /-- Cocones on `F : Jᵒᵖ ⥤ Cᵒᵖ` are equivalent to cones on `F.unop : J ⥤ C`. -/] @@ -891,6 +941,7 @@ open CategoryTheory.Limits variable {F : J ⥤ C} (G : C ⥤ D) +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- The opposite cocone of the image of a cone is the image of the opposite cocone. -/ @[to_dual (attr := simps!) diff --git a/Mathlib/CategoryTheory/Limits/Connected.lean b/Mathlib/CategoryTheory/Limits/Connected.lean index a58824cacfe172..3dfcc0fede6b6d 100644 --- a/Mathlib/CategoryTheory/Limits/Connected.lean +++ b/Mathlib/CategoryTheory/Limits/Connected.lean @@ -63,6 +63,7 @@ def constCocone : Cocone ((Functor.const J).obj X) where variable [IsConnected J] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When `J` is a connected category, the limit of a constant functor `J ⥤ C` with value `X : C` identifies to `X`. -/ @@ -75,6 +76,7 @@ def isLimitConstCone : IsLimit (constCone J X) where (fun _ _ f ↦ by simpa using s.w f) _ _ uniq s m hm := by simpa using hm (Classical.arbitrary _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When `J` is a connected category, the colimit of a constant functor `J ⥤ C` with value `X : C` identifies to `X`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Constructions/EventuallyConstant.lean b/Mathlib/CategoryTheory/Limits/Constructions/EventuallyConstant.lean index c307ece418a386..d2ceef978b60a7 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/EventuallyConstant.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/EventuallyConstant.lean @@ -116,7 +116,9 @@ noncomputable def cone : Cone F where let β : i ⟶ j := IsCofiltered.minToRight _ _ rw [h.coneπApp_eq j _ α β, assoc, h.coneπApp_eq j' _ α (β ≫ φ), map_comp] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- When `h : F.IsEventuallyConstantTo i₀`, the limit of `F` exists and is `F.obj i₀`. -/ noncomputable def isLimitCone : IsLimit h.cone where lift s := s.π.app i₀ @@ -128,7 +130,9 @@ noncomputable def isLimitCone : IsLimit h.cone where lemma hasLimit : HasLimit F := ⟨_, h.isLimitCone⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in lemma isIso_π_of_isLimit {c : Cone F} (hc : IsLimit c) : IsIso (c.π.app i₀) := by simp only [← IsLimit.conePointUniqueUpToIso_hom_comp hc h.isLimitCone i₀, diff --git a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean index dea563fee68bb1..6519554b70f0d9 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean @@ -119,6 +119,7 @@ variable [PreservesLimitsOfShape (Discrete WalkingPair) F] variable [PreservesLimitsOfShape (Discrete.{0} PEmpty) F] variable [HasFiniteProducts.{v} C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` preserves the terminal object and binary products, then it preserves products indexed by `Fin n` for any `n`. @@ -244,6 +245,7 @@ variable [PreservesColimitsOfShape (Discrete WalkingPair) F] variable [PreservesColimitsOfShape (Discrete.{0} PEmpty) F] variable [HasFiniteCoproducts.{v} C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by `Fin n` for any `n`. diff --git a/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean b/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean index 4306b75fe86e82..8bf1e8969d7a73 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean @@ -226,7 +226,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating limits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsLimitsOfShapeOfCreatesEqualizersAndProducts : CreatesLimitsOfShape J G where CreatesLimit {K} := @@ -247,7 +247,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating limits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsFiniteLimitsOfCreatesEqualizersAndFiniteProducts [HasEqualizers D] [HasFiniteProducts D] (G : C ⥤ D) [G.ReflectsIsomorphisms] [CreatesLimitsOfShape WalkingParallelPair G] @@ -260,7 +260,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating limits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsLimitsOfSizeOfCreatesEqualizersAndProducts [HasEqualizers D] [HasProducts.{w} D] (G : C ⥤ D) [G.ReflectsIsomorphisms] [CreatesLimitsOfShape WalkingParallelPair G] [∀ J, CreatesLimitsOfShape (Discrete.{w} J) G] : @@ -294,7 +294,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating limits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsFiniteLimitsOfCreatesTerminalAndPullbacks [HasTerminal D] [HasPullbacks D] (G : C ⥤ D) [G.ReflectsIsomorphisms] [CreatesLimitsOfShape (Discrete.{0} PEmpty) G] [CreatesLimitsOfShape WalkingCospan G] : @@ -401,6 +401,7 @@ noncomputable def colimitQuotientCoproduct [HasColimitsOfSize.{w, w} C] (F : J have := hasFiniteColimits_of_hasColimitsOfSize C coequalizer.π _ _ ≫ (colimit.isoColimitCocone (colimitCoconeOfCoequalizerAndCoproduct F)).inv +set_option backward.isDefEq.respectTransparency.types false in instance colimitQuotientCoproduct_epi [HasColimitsOfSize.{w, w} C] (F : J ⥤ C) : Epi (colimitQuotientCoproduct F) := epi_comp _ _ @@ -502,7 +503,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating colimits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsColimitsOfShapeOfCreatesCoequalizersAndCoproducts : CreatesColimitsOfShape J G where CreatesColimit {K} := @@ -523,7 +524,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating colimits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsFiniteColimitsOfCreatesCoequalizersAndFiniteCoproducts [HasCoequalizers D] [HasFiniteCoproducts D] (G : C ⥤ D) [G.ReflectsIsomorphisms] [CreatesColimitsOfShape WalkingParallelPair G] @@ -536,7 +537,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating colimits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsColimitsOfSizeOfCreatesCoequalizersAndCoproducts [HasCoequalizers D] [HasCoproducts.{w} D] (G : C ⥤ D) [G.ReflectsIsomorphisms] [CreatesColimitsOfShape WalkingParallelPair G] @@ -572,7 +573,7 @@ We additionally require the rather strong condition that the functor reflects is unclear whether the statement remains true without this condition. There are various definitions of "creating colimits" in the literature, and whether or not the condition can be dropped seems to depend on the specific definition that is used. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def createsFiniteColimitsOfCreatesInitialAndPushouts [HasInitial D] [HasPushouts D] (G : C ⥤ D) [G.ReflectsIsomorphisms] [CreatesColimitsOfShape (Discrete.{0} PEmpty) G] [CreatesColimitsOfShape WalkingSpan G] : diff --git a/Mathlib/CategoryTheory/Limits/Constructions/Over/Connected.lean b/Mathlib/CategoryTheory/Limits/Constructions/Over/Connected.lean index 5408ed6c593fbd..5c22914bd8ccc1 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/Over/Connected.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/Over/Connected.lean @@ -46,6 +46,7 @@ def natTransInCostructuredArrow {B : D} (F : J ⥤ CostructuredArrow K B) : F ⋙ CostructuredArrow.proj K B ⋙ K ⟶ (CategoryTheory.Functor.const J).obj B where app j := (F.obj j).hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- (Implementation) Given a cone in the base category, raise it to a cone in `CostructuredArrow K B`. Note this is where the connected assumption is used. @@ -157,6 +158,7 @@ instance hasLimitsOfShape_of_isConnected {B : C} [IsConnected J] [HasLimitsOfSha HasLimitsOfShape J (Over B) where has_limit F := hasLimit_of_created F (forget B) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor taking a cone over `F` to a cone over `Over.post F : Over i ⥤ Over (F.obj i)`. This takes limit cones to limit cones when `J` is cofiltered. See `isLimitConePost` -/ @@ -165,12 +167,14 @@ def conePost (F : J ⥤ C) (i : J) : Cone F ⥤ Cone (Over.post (X := i) F) wher obj c := { pt := Over.mk (c.π.app i), π := { app X := Over.homMk (c.π.app X.left) } } map f := { hom := Over.homMk f.hom } +set_option backward.isDefEq.respectTransparency.types false in /-- `conePost` is compatible with the forgetful functors on over categories. -/ @[simps!] def conePostIso (F : J ⥤ C) (i : J) : conePost F i ⋙ Cone.functoriality _ (Over.forget (F.obj i)) ≅ Cone.whiskering (Over.forget _) := .refl _ +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] IsCofiltered.isConnected in /-- The functor taking a cone over `F` to a cone over `Over.post F : Over i ⥤ Over (F.obj i)` preserves limit cones -/ diff --git a/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean b/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean index 61217eb65f3f2a..41d85225189a37 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean @@ -94,7 +94,9 @@ def IsLimit.pullbackConeEquivBinaryFanFunctor {c : PullbackCone f g} (hc : IsLim · simpa using! congr(($e₁).left) · simpa using! congr(($e₂).left) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- A pullback cone to `X` is a limit if its corresponding binary fan in `Over X` is a limit. -/ -- This could also be `(IsLimit.ofConeEquiv pullbackConeEquivBinaryFan.symm).symm hc`, but possibly -- bad defeqs? @@ -183,6 +185,7 @@ variable {X : C} {Y Z : Over X} open Limits +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isPullback_of_binaryFan_isLimit (c : BinaryFan Y Z) (hc : IsLimit c) : IsPullback c.fst.left c.snd.left Y.hom Z.hom := @@ -292,7 +295,9 @@ def conesEquivFunctor (B : C) {J : Type w} (F : Discrete J ⥤ Over B) : -- attribute [local aesop safe cases (rule_sets := [CategoryTheory])] WidePullbackShape -- If this worked we could avoid the `rintro` in `conesEquivUnitIso`. +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- (Impl) A preliminary definition to avoid timeouts. -/ @[simps!] def conesEquivUnitIso (B : C) (F : Discrete J ⥤ Over B) : @@ -303,6 +308,7 @@ def conesEquivUnitIso (B : C) (F : Discrete J ⥤ Over B) : inv := 𝟙 _ } (by rintro (j | j) <;> cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- TODO: Can we add `:= by aesop` to the second arguments of `NatIso.ofComponents` and -- `Cone.ext`? @@ -314,6 +320,7 @@ def conesEquivCounitIso (B : C) (F : Discrete J ⥤ Over B) : { hom := Over.homMk (𝟙 _) inv := Over.homMk (𝟙 _) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- (Impl) Establish an equivalence between the category of cones for `F` and for the "grown" `F`. -/ @@ -354,6 +361,7 @@ theorem over_finiteProducts_of_finiteWidePullbacks [HasFiniteWidePullbacks C] {B end ConstructProducts +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Construct terminal object in the over category. This isn't an instance as it's not typically the way we want to define terminal objects. diff --git a/Mathlib/CategoryTheory/Limits/Constructions/ZeroObjects.lean b/Mathlib/CategoryTheory/Limits/Constructions/ZeroObjects.lean index fbbd4ce92ff73e..b9878e04e8a121 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/ZeroObjects.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/ZeroObjects.lean @@ -34,6 +34,7 @@ open ZeroObject def binaryFanZeroLeft (X : C) : BinaryFan (0 : C) X := BinaryFan.mk 0 (𝟙 X) +set_option backward.isDefEq.respectTransparency.types false in /-- The limit cone for the product with a zero object is limiting. -/ def binaryFanZeroLeftIsLimit (X : C) : IsLimit (binaryFanZeroLeft X) := BinaryFan.isLimitMk (fun s => BinaryFan.snd s) (by cat_disch) (by simp) @@ -60,6 +61,7 @@ theorem zeroProdIso_inv_snd (X : C) : (zeroProdIso X).inv ≫ prod.snd = 𝟙 X def binaryFanZeroRight (X : C) : BinaryFan X (0 : C) := BinaryFan.mk (𝟙 X) 0 +set_option backward.isDefEq.respectTransparency.types false in /-- The limit cone for the product with a zero object is limiting. -/ def binaryFanZeroRightIsLimit (X : C) : IsLimit (binaryFanZeroRight X) := BinaryFan.isLimitMk (fun s => BinaryFan.fst s) (by simp) (by cat_disch) @@ -86,6 +88,7 @@ theorem prodZeroIso_iso_inv_snd (X : C) : (prodZeroIso X).inv ≫ prod.fst = def binaryCofanZeroLeft (X : C) : BinaryCofan (0 : C) X := BinaryCofan.mk 0 (𝟙 X) +set_option backward.isDefEq.respectTransparency.types false in /-- The colimit cocone for the coproduct with a zero object is colimiting. -/ def binaryCofanZeroLeftIsColimit (X : C) : IsColimit (binaryCofanZeroLeft X) := BinaryCofan.isColimitMk (fun s => BinaryCofan.inr s) (by cat_disch) (by simp) @@ -112,6 +115,7 @@ theorem zeroCoprodIso_inv (X : C) : (zeroCoprodIso X).inv = coprod.inr := def binaryCofanZeroRight (X : C) : BinaryCofan X (0 : C) := BinaryCofan.mk (𝟙 X) 0 +set_option backward.isDefEq.respectTransparency.types false in /-- The colimit cocone for the coproduct with a zero object is colimiting. -/ def binaryCofanZeroRightIsColimit (X : C) : IsColimit (binaryCofanZeroRight X) := BinaryCofan.isColimitMk (fun s => BinaryCofan.inl s) (by simp) (by cat_disch) diff --git a/Mathlib/CategoryTheory/Limits/Creates.lean b/Mathlib/CategoryTheory/Limits/Creates.lean index 553b495bb93180..4bac045fc48f16 100644 --- a/Mathlib/CategoryTheory/Limits/Creates.lean +++ b/Mathlib/CategoryTheory/Limits/Creates.lean @@ -252,11 +252,12 @@ structure LiftsToColimit (K : J ⥤ C) (F : C ⥤ D) (c : Cocone (K ⋙ F)) (t : /-- the lifted cocone is colimit -/ makesColimit : IsColimit liftedCocone +set_option backward.isDefEq.respectTransparency.types false in /-- If `F` reflects isomorphisms and we can lift any limit cone to a limit cone, then `F` creates limits. In particular here we don't need to assume that F reflects limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfReflectsIso {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphisms] (h : ∀ c t, LiftsToLimit K F c t) : CreatesLimit K F where lifts c t := (h c t).toLiftableCone @@ -278,7 +279,7 @@ def createsLimitOfReflectsIso {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphism /-- If `F` reflects isomorphisms and we can lift a single limit cone to a limit cone, then `F` creates limits. Note that unlike `createsLimitOfReflectsIso`, to apply this result it is necessary to know that `K ⋙ F` actually has a limit. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfReflectsIso' {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphisms] {c : Cone (K ⋙ F)} (hc : IsLimit c) (h : LiftsToLimit K F c hc) : CreatesLimit K F := createsLimitOfReflectsIso fun _ t => @@ -288,7 +289,7 @@ def createsLimitOfReflectsIso' {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphis /-- If `F` reflects isomorphisms, and we already know that the limit exists in the source and `F` preserves it, then `F` creates that limit. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfReflectsIsomorphismsOfPreserves {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphisms] [HasLimit K] [PreservesLimit K F] : CreatesLimit K F := createsLimitOfReflectsIso' (isLimitOfPreserves F (limit.isLimit _)) @@ -301,7 +302,7 @@ def createsLimitOfReflectsIsomorphismsOfPreserves {K : J ⥤ C} {F : C ⥤ D} [F When `F` is fully faithful, to show that `F` creates the limit for `K` it suffices to exhibit a lift of a limit cone for `K ⋙ F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfFullyFaithfulOfLift' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] {l : Cone (K ⋙ F)} (hl : IsLimit l) (c : Cone K) (i : F.mapCone c ≅ l) : CreatesLimit K F := @@ -313,7 +314,7 @@ def createsLimitOfFullyFaithfulOfLift' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.F /-- When `F` is fully faithful, and `HasLimit (K ⋙ F)`, to show that `F` creates the limit for `K` it suffices to exhibit a lift of the chosen limit cone for `K ⋙ F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfFullyFaithfulOfLift {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] [HasLimit (K ⋙ F)] (c : Cone K) (i : F.mapCone c ≅ limit.cone (K ⋙ F)) : CreatesLimit K F := @@ -328,7 +329,7 @@ set_option backward.isDefEq.respectTransparency false in When `F` is fully faithful, to show that `F` creates the limit for `K` it suffices to show that a limit point is in the essential image of `F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfFullyFaithfulOfIso' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] {l : Cone (K ⋙ F)} (hl : IsLimit l) (X : C) (i : F.obj X ≅ l.pt) : CreatesLimit K F := createsLimitOfFullyFaithfulOfLift' hl @@ -346,13 +347,13 @@ def createsLimitOfFullyFaithfulOfIso' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Fa /-- When `F` is fully faithful, and `HasLimit (K ⋙ F)`, to show that `F` creates the limit for `K` it suffices to show that the chosen limit point is in the essential image of `F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfFullyFaithfulOfIso {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] [HasLimit (K ⋙ F)] (X : C) (i : F.obj X ≅ limit (K ⋙ F)) : CreatesLimit K F := createsLimitOfFullyFaithfulOfIso' (limit.isLimit _) X i /-- A fully faithful functor that preserves a limit that exists also creates the limit. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfFullyFaithfulOfPreserves {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] [HasLimit K] [PreservesLimit K F] : CreatesLimit K F := createsLimitOfFullyFaithfulOfLift' (isLimitOfPreserves _ (limit.isLimit K)) _ (Iso.refl _) @@ -376,11 +377,12 @@ instance (priority := 100) preservesLimits_of_createsLimits_and_hasLimits (F : C [CreatesLimitsOfSize.{w, w'} F] [HasLimitsOfSize.{w, w'} D] : PreservesLimitsOfSize.{w, w'} F where +set_option backward.isDefEq.respectTransparency.types false in /-- If `F` reflects isomorphisms and we can lift any colimit cocone to a colimit cocone, then `F` creates colimits. In particular here we don't need to assume that F reflects colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfReflectsIso {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphisms] (h : ∀ c t, LiftsToColimit K F c t) : CreatesColimit K F where lifts c t := (h c t).toLiftableCocone @@ -402,7 +404,7 @@ def createsColimitOfReflectsIso {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphi /-- If `F` reflects isomorphisms and we can lift a single colimit cocone to a colimit cocone, then `F` creates limits. Note that unlike `createsColimitOfReflectsIso`, to apply this result it is necessary to know that `K ⋙ F` actually has a colimit. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfReflectsIso' {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphisms] {c : Cocone (K ⋙ F)} (hc : IsColimit c) (h : LiftsToColimit K F c hc) : CreatesColimit K F := createsColimitOfReflectsIso fun _ t => @@ -412,7 +414,7 @@ def createsColimitOfReflectsIso' {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorph /-- If `F` reflects isomorphisms, and we already know that the colimit exists in the source and `F` preserves it, then `F` creates that colimit. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfReflectsIsomorphismsOfPreserves {K : J ⥤ C} {F : C ⥤ D} [F.ReflectsIsomorphisms] [HasColimit K] [PreservesColimit K F] : CreatesColimit K F := createsColimitOfReflectsIso' (isColimitOfPreserves F (colimit.isColimit _)) @@ -425,7 +427,7 @@ def createsColimitOfReflectsIsomorphismsOfPreserves {K : J ⥤ C} {F : C ⥤ D} When `F` is fully faithful, to show that `F` creates the colimit for `K` it suffices to exhibit a lift of a colimit cocone for `K ⋙ F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfFullyFaithfulOfLift' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] {l : Cocone (K ⋙ F)} (hl : IsColimit l) (c : Cocone K) (i : F.mapCocone c ≅ l) : CreatesColimit K F := @@ -438,7 +440,7 @@ def createsColimitOfFullyFaithfulOfLift' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F When `F` is fully faithful, and `HasColimit (K ⋙ F)`, to show that `F` creates the colimit for `K` it suffices to exhibit a lift of the chosen colimit cocone for `K ⋙ F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfFullyFaithfulOfLift {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] [HasColimit (K ⋙ F)] (c : Cocone K) (i : F.mapCocone c ≅ colimit.cocone (K ⋙ F)) : CreatesColimit K F := @@ -452,7 +454,7 @@ set_option backward.defeqAttrib.useBackward true in When `F` is fully faithful, to show that `F` creates the colimit for `K` it suffices to show that a colimit point is in the essential image of `F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfFullyFaithfulOfIso' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] {l : Cocone (K ⋙ F)} (hl : IsColimit l) (X : C) (i : F.obj X ≅ l.pt) : CreatesColimit K F := createsColimitOfFullyFaithfulOfLift' hl @@ -471,7 +473,7 @@ def createsColimitOfFullyFaithfulOfIso' {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F. When `F` is fully faithful, and `HasColimit (K ⋙ F)`, to show that `F` creates the colimit for `K` it suffices to show that the chosen colimit point is in the essential image of `F`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfFullyFaithfulOfIso {K : J ⥤ C} {F : C ⥤ D} [F.Full] [F.Faithful] [HasColimit (K ⋙ F)] (X : C) (i : F.obj X ≅ colimit (K ⋙ F)) : CreatesColimit K F := createsColimitOfFullyFaithfulOfIso' (colimit.isColimit _) X i @@ -500,7 +502,7 @@ instance (priority := 100) preservesColimits_of_createsColimits_and_hasColimits set_option backward.defeqAttrib.useBackward true in /-- Transfer creation of limits along a natural isomorphism in the diagram. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfIsoDiagram {K₁ K₂ : J ⥤ C} (F : C ⥤ D) (h : K₁ ≅ K₂) [CreatesLimit K₁ F] : CreatesLimit K₂ F := { reflectsLimit_of_iso_diagram F h with @@ -516,7 +518,7 @@ def createsLimitOfIsoDiagram {K₁ K₂ : J ⥤ C} (F : C ⥤ D) (h : K₁ ≅ K simp } } /-- If `F` creates the limit of `K` and `F ≅ G`, then `G` creates the limit of `K`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesLimit K F] : CreatesLimit K G where lifts c t := { liftedCone := liftLimit ((IsLimit.postcomposeInvEquiv (isoWhiskerLeft K h :) c).symm t) @@ -527,19 +529,19 @@ def createsLimitOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesLimit K F] : Crea toReflectsLimit := reflectsLimit_of_natIso _ h /-- If `F` creates limits of shape `J` and `F ≅ G`, then `G` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesLimitsOfShape J F] : CreatesLimitsOfShape J G where CreatesLimit := createsLimitOfNatIso h /-- If `F` creates limits and `F ≅ G`, then `G` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesLimitsOfSize.{w, w'} F] : CreatesLimitsOfSize.{w, w'} G where CreatesLimitsOfShape := createsLimitsOfShapeOfNatIso h set_option backward.defeqAttrib.useBackward true in /-- If `F` creates limits of shape `J` and `J ≌ J'`, then `F` creates limits of shape `J'`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfEquiv {J' : Type w₁} [Category.{w'₁} J'] (e : J ≌ J') (F : C ⥤ D) [CreatesLimitsOfShape J F] : CreatesLimitsOfShape J' F where CreatesLimit {K} := @@ -554,7 +556,7 @@ def createsLimitsOfShapeOfEquiv {J' : Type w₁} [Category.{w'₁} J'] (e : J set_option backward.defeqAttrib.useBackward true in /-- Transfer creation of colimits along a natural isomorphism in the diagram. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfIsoDiagram {K₁ K₂ : J ⥤ C} (F : C ⥤ D) (h : K₁ ≅ K₂) [CreatesColimit K₁ F] : CreatesColimit K₂ F := { reflectsColimit_of_iso_diagram F h with @@ -571,7 +573,7 @@ def createsColimitOfIsoDiagram {K₁ K₂ : J ⥤ C} (F : C ⥤ D) (h : K₁ ≅ simp } } /-- If `F` creates the colimit of `K` and `F ≅ G`, then `G` creates the colimit of `K`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesColimit K F] : CreatesColimit K G where lifts c t := { liftedCocone := liftColimit ((IsColimit.precomposeHomEquiv (isoWhiskerLeft K h :) c).symm t) @@ -582,19 +584,19 @@ def createsColimitOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesColimit K F] : toReflectsColimit := reflectsColimit_of_natIso _ h /-- If `F` creates colimits of shape `J` and `F ≅ G`, then `G` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesColimitsOfShape J F] : CreatesColimitsOfShape J G where CreatesColimit := createsColimitOfNatIso h /-- If `F` creates colimits and `F ≅ G`, then `G` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfNatIso {F G : C ⥤ D} (h : F ≅ G) [CreatesColimitsOfSize.{w, w'} F] : CreatesColimitsOfSize.{w, w'} G where CreatesColimitsOfShape := createsColimitsOfShapeOfNatIso h set_option backward.defeqAttrib.useBackward true in /-- If `F` creates colimits of shape `J` and `J ≌ J'`, then `F` creates colimits of shape `J'`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfEquiv {J' : Type w₁} [Category.{w'₁} J'] (e : J ≌ J') (F : C ⥤ D) [CreatesColimitsOfShape J F] : CreatesColimitsOfShape J' F where CreatesColimit {K} := diff --git a/Mathlib/CategoryTheory/Limits/Elements.lean b/Mathlib/CategoryTheory/Limits/Elements.lean index db7788ec4db95d..4648d35aba364c 100644 --- a/Mathlib/CategoryTheory/Limits/Elements.lean +++ b/Mathlib/CategoryTheory/Limits/Elements.lean @@ -84,6 +84,7 @@ lemma map_π_liftedConeElement (i : I) : (preservesLimitIso_inv_π A (F ⋙ π A) i) (liftedConeElement' F) simp [liftedConeElement, ← comp_apply] +set_option backward.isDefEq.respectTransparency.types false in /-- (implementation) The constructed limit cone. -/ @[simps] noncomputable def liftedCone : Cone F where @@ -92,6 +93,7 @@ noncomputable def liftedCone : Cone F where { app := fun i => ⟨limit.π (F ⋙ π A) i, by simpa using! map_π_liftedConeElement _ _⟩ naturality := fun i i' f => by ext; simpa using! (limit.w _ _).symm } +set_option backward.isDefEq.respectTransparency.types false in /-- (implementation) The constructed limit cone is a lift of the limit cone in `C`. -/ noncomputable def isValidLift : (π A).mapCone (liftedCone F) ≅ limit.cone (F ⋙ π A) := Iso.refl _ diff --git a/Mathlib/CategoryTheory/Limits/ExactFunctor.lean b/Mathlib/CategoryTheory/Limits/ExactFunctor.lean index 1c7031acf93d9f..bd16ea83d7f0cd 100644 --- a/Mathlib/CategoryTheory/Limits/ExactFunctor.lean +++ b/Mathlib/CategoryTheory/Limits/ExactFunctor.lean @@ -234,6 +234,7 @@ section variable (C D E) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering a left exact functor by a left exact functor yields a left exact functor. -/ @[simps! obj_obj_obj obj_map map_app] @@ -243,6 +244,7 @@ def LeftExactFunctor.whiskeringLeft : (C ⥤ₗ D) ⥤ (D ⥤ₗ E) ⥤ (C ⥤ map {F G} η := { app H := ObjectProperty.homMk (((Functor.whiskeringLeft C D E).map η.hom).app H.obj) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering a left exact functor by a left exact functor yields a left exact functor. -/ @[simps! obj_obj_obj obj_map map_app] @@ -252,6 +254,7 @@ def LeftExactFunctor.whiskeringRight : (D ⥤ₗ E) ⥤ (C ⥤ₗ D) ⥤ (C ⥤ map {F G} η := { app H := ObjectProperty.homMk (((Functor.whiskeringRight C D E).map η.hom).app H.obj) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering a right exact functor by a right exact functor yields a right exact functor. -/ @[simps! obj_obj_obj obj_map map_app] @@ -261,6 +264,7 @@ def RightExactFunctor.whiskeringLeft : (C ⥤ᵣ D) ⥤ (D ⥤ᵣ E) ⥤ (C ⥤ map {F G} η := { app H := ObjectProperty.homMk (((Functor.whiskeringLeft C D E).map η.hom).app H.obj) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering a right exact functor by a right exact functor yields a right exact functor. -/ @[simps! obj_obj_obj obj_map map_app] @@ -270,6 +274,7 @@ def RightExactFunctor.whiskeringRight : (D ⥤ᵣ E) ⥤ (C ⥤ᵣ D) ⥤ (C ⥤ map {F G} η := { app H := ObjectProperty.homMk (((Functor.whiskeringRight C D E).map η.hom).app H.obj) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering an exact functor by an exact functor yields an exact functor. -/ @[simps! obj_obj_obj obj_map map_app] @@ -280,6 +285,7 @@ def ExactFunctor.whiskeringLeft : (C ⥤ₑ D) ⥤ (D ⥤ₑ E) ⥤ (C ⥤ₑ E) map {F G} η := { app H := ObjectProperty.homMk (((Functor.whiskeringLeft C D E).map η.hom).app H.obj) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Whiskering an exact functor by an exact functor yields an exact functor. -/ @[simps! obj_obj_obj obj_map map_app] diff --git a/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesFiniteLimit.lean b/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesFiniteLimit.lean index 34abf0b2e626e0..c646a7f6be2d05 100644 --- a/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesFiniteLimit.lean +++ b/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesFiniteLimit.lean @@ -54,7 +54,7 @@ is just a variant of `limit_ext'`. -/ variable (F : J × K ⥤ Type v) -open Prod +open CategoryTheory.Prod variable [IsFiltered K] @@ -67,8 +67,7 @@ only that there are finitely many objects. variable [Finite J] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- This follows the proof from * Borceux, Handbook of categorical algebra 1, Theorem 2.13.4 -/ @@ -90,7 +89,7 @@ theorem colimitLimitToLimitColimit_injective : ((limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j) x) = (colimit.ι ((curry.obj F).obj j) ky) ((limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j) y) := by - simpa [-comp_obj] using! ConcreteCategory.congr_arg (limit.π (curry.obj F ⋙ colim) j) h + simpa using! ConcreteCategory.congr_arg (limit.π (curry.obj F ⋙ colim) j) h -- and they are equations in a filtered colimit, -- so for each `j` we have some place `k j` to the right of both `kx` and `ky` simp only [colimit_eq_iff] at h diff --git a/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesProduct.lean b/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesProduct.lean index 420628156e8366..c34b88df2c6606 100644 --- a/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesProduct.lean +++ b/Mathlib/CategoryTheory/Limits/FilteredColimitCommutesProduct.lean @@ -61,6 +61,7 @@ maps `k : ∀ i, I i` to `∏ᶜ fun (s : α) => (F s).obj (k s)`. -/ noncomputable abbrev pointwiseProduct : (∀ i, I i) ⥤ C := Functor.pi F ⋙ Pi.functor α +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.pi in /-- `pointwiseProduct` is invariant under re-indexing. -/ @@ -82,6 +83,7 @@ noncomputable def coconePointwiseProduct (c : ∀ i, Cocone (F i)) : pt := ∏ᶜ fun i ↦ (c i).pt ι := Functor.whiskerRight (NatTrans.pi fun i ↦ (c i).ι) _ ≫ (Pi.constCompPiIsoConst _).hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `coconePointwiseProduct` is invariant under isomorphisms of cocones. -/ noncomputable def coconePointwiseProductIso {c c' : ∀ i, Cocone (F i)} (e : ∀ i, c i ≅ c' i) : @@ -129,6 +131,7 @@ noncomputable def pointwiseProductCompEvaluation (d : D) : NatIso.ofComponents (fun k => piObjIso _ _) (fun f => Pi.hom_ext _ _ (by simp [Functor.pi, ← NatTrans.comp_app])) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- In a functor category, `coconePointwiseProduct` commutes with evaluation. -/ noncomputable def evaluationCoconePointwiseProductIso (X : D) (c : ∀ i, Cocone (F i)) : @@ -203,6 +206,7 @@ lemma IsIPCOfShape.of_isIso obtain ⟨_, h⟩ := H J F rwa [IsColimit.nonempty_isColimit_iff_isIso_desc (colimit.isColimit _)] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.pi in lemma IsIPCOfShape.of_equiv {ι' : Type*} [HasProductsOfShape ι' C] [IsIPCOfShape.{w} ι C] diff --git a/Mathlib/CategoryTheory/Limits/Final.lean b/Mathlib/CategoryTheory/Limits/Final.lean index 7083e202e084c2..d0229bbc749c38 100644 --- a/Mathlib/CategoryTheory/Limits/Final.lean +++ b/Mathlib/CategoryTheory/Limits/Final.lean @@ -333,6 +333,7 @@ instance (priority := 100) compCreatesColimit {B : Type u₄} [Category.{v₄} B let i := liftedColimitMapsToOriginal ((isColimitExtendCoconeEquiv F (G := G ⋙ H) _).symm hc) exact (Cocone.whiskering F).mapIso i ≪≫ ((coconesEquiv F (G ⋙ H)).unitIso.app _).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance colimit_pre_isIso [HasColimit G] : IsIso (colimit.pre G F) := by simp only [colimit.pre_eq (colimitCoconeComp F (getColimitCocone G)) (getColimitCocone G), @@ -360,7 +361,6 @@ theorem ι_colimitIso_inv [HasColimit G] (X : C) : simp [colimitIso] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- A pointfree version of `colimitIso`, stating that whiskering by `F` followed by taking the colimit is isomorphic to taking the colimit on the codomain of `F`. -/ def colimIso [HasColimitsOfShape D E] [HasColimitsOfShape C E] : @@ -392,6 +392,7 @@ lemma hasColimit_comp_iff : HasColimit (F ⋙ G) ↔ HasColimit G := ⟨fun _ ↦ Functor.Final.hasColimit_of_comp F, fun _ ↦ inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem preservesColimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} [PreservesColimit (F ⋙ G) H] : PreservesColimit G H where @@ -400,6 +401,7 @@ theorem preservesColimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ let hc' := isColimitOfPreserves H ((isColimitWhiskerEquiv F _).symm hc) exact IsColimit.ofIsoColimit hc' (Cocone.ext (Iso.refl _) (by simp)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem reflectsColimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} [ReflectsColimit (F ⋙ G) H] : ReflectsColimit G H where @@ -410,7 +412,7 @@ theorem reflectsColimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B set_option backward.defeqAttrib.useBackward true in /-- If `F` is final and `F ⋙ G` creates colimits of `H`, then so does `G`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfComp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} [CreatesColimit (F ⋙ G) H] : CreatesColimit G H where reflects := (reflectsColimit_of_comp F).reflects @@ -437,7 +439,7 @@ theorem reflectsColimitsOfShape_of_final {B : Type u₄} [Category.{v₄} B] (H include F in /-- If `H` creates colimits of shape `C` and `F : C ⥤ D` is final, then `H` creates colimits of shape `D`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfFinal {B : Type u₄} [Category.{v₄} B] (H : E ⥤ B) [CreatesColimitsOfShape C H] : CreatesColimitsOfShape D H where CreatesColimit := createsColimitOfComp F @@ -692,6 +694,7 @@ instance (priority := 100) compCreatesLimit {B : Type u₄} [Category.{v₄} B] let i := liftedLimitMapsToOriginal ((isLimitExtendConeEquiv F (G := G ⋙ H) _).symm hc) exact (Cone.whiskering F).mapIso i ≪≫ ((conesEquiv F (G ⋙ H)).unitIso.app _).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance limit_pre_isIso [HasLimit G] : IsIso (limit.pre G F) := by rw [limit.pre_eq (limitConeComp F (getLimitCone G)) (getLimitCone G)] @@ -710,7 +713,6 @@ def limitIso [HasLimit G] : limit (F ⋙ G) ≅ limit G := (asIso (limit.pre G F)).symm set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- A pointfree version of `limitIso`, stating that whiskering by `F` followed by taking the limit is isomorphic to taking the limit on the codomain of `F`. -/ def limIso [HasLimitsOfShape D E] [HasLimitsOfShape C E] : @@ -741,6 +743,7 @@ lemma hasLimit_comp_iff : HasLimit (F ⋙ G) ↔ HasLimit G := ⟨fun _ ↦ Functor.Initial.hasLimit_of_comp F, fun _ ↦ inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem preservesLimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} [PreservesLimit (F ⋙ G) H] : PreservesLimit G H where @@ -749,6 +752,7 @@ theorem preservesLimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} let hc' := isLimitOfPreserves H ((isLimitWhiskerEquiv F _).symm hc) exact IsLimit.ofIsoLimit hc' (Cone.ext (Iso.refl _) (by simp)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem reflectsLimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} [ReflectsLimit (F ⋙ G) H] : ReflectsLimit G H where @@ -759,7 +763,7 @@ theorem reflectsLimit_of_comp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} set_option backward.defeqAttrib.useBackward true in /-- If `F` is initial and `F ⋙ G` creates limits of `H`, then so does `G`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfComp {B : Type u₄} [Category.{v₄} B] {H : E ⥤ B} [CreatesLimit (F ⋙ G) H] : CreatesLimit G H where reflects := (reflectsLimit_of_comp F).reflects @@ -786,7 +790,7 @@ theorem reflectsLimitsOfShape_of_initial {B : Type u₄} [Category.{v₄} B] (H include F in /-- If `H` creates limits of shape `C` and `F : C ⥤ D` is initial, then `H` creates limits of shape `D`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfInitial {B : Type u₄} [Category.{v₄} B] (H : E ⥤ B) [CreatesLimitsOfShape C H] : CreatesLimitsOfShape D H where CreatesLimit := createsLimitOfComp F @@ -850,7 +854,6 @@ theorem initial_iff_comp_equivalence [IsEquivalence G] : Initial F ↔ Initial ( theorem initial_iff_equivalence_comp [IsEquivalence F] : Initial G ↔ Initial (F ⋙ G) := ⟨fun _ => initial_equivalence_comp _ _, fun _ => initial_of_equivalence_comp F _⟩ -set_option backward.isDefEq.respectTransparency false in instance final_comp [hF : Final F] [hG : Final G] : Final (F ⋙ G) := by let s₁ : C ≌ AsSmall.{max u₁ v₁ u₂ v₂ u₃ v₃} C := AsSmall.equiv let s₂ : D ≌ AsSmall.{max u₁ v₁ u₂ v₂ u₃ v₃} D := AsSmall.equiv @@ -872,7 +875,6 @@ instance initial_comp [Initial F] [Initial G] : Initial (F ⋙ G) := by suffices Final (F ⋙ G).op from initial_of_final_op _ exact final_comp F.op G.op -set_option backward.isDefEq.respectTransparency false in theorem final_of_final_comp [hF : Final F] [hFG : Final (F ⋙ G)] : Final G := by let s₁ : C ≌ AsSmall.{max u₁ v₁ u₂ v₂ u₃ v₃} C := AsSmall.equiv let s₂ : D ≌ AsSmall.{max u₁ v₁ u₂ v₂ u₃ v₃} D := AsSmall.equiv @@ -982,7 +984,7 @@ end end Functor section Filtered -open Functor +open CategoryTheory.Functor variable {C : Type u₁} [Category.{v₁} C] variable {D : Type u₂} [Category.{v₂} D] @@ -1053,7 +1055,7 @@ variable {C : Type u₁} [Category.{v₁} C] variable {D : Type u₂} [Category.{v₂} D] variable {E : Type u₃} [Category.{v₃} E] -open Functor +open CategoryTheory.Functor /-- The functor `StructuredArrow.pre X T S` is final if `T` is final. -/ instance StructuredArrow.final_pre (T : C ⥤ D) [Final T] (S : D ⥤ E) (X : E) : @@ -1077,7 +1079,7 @@ variable {C : Type u₁} [Category.{v₁} C] variable {D : Type u₂} [Category.{v₂} D] variable (F : D ⥤ Cat) (G : C ⥤ D) -open Functor +open CategoryTheory.Functor set_option backward.isDefEq.respectTransparency false in /-- A prefunctor mapping structured arrows on `G` to structured arrows on `pre F G` with their @@ -1200,6 +1202,7 @@ end Prod namespace ObjectProperty +set_option backward.isDefEq.respectTransparency.types false in /-- For the full subcategory induced by an object property `P` on `C`, to show initiality of the inclusion functor it is enough to consider arrows to objects outside of the subcategory. -/ theorem initial_ι {C : Type u₁} [Category.{v₁} C] (P : ObjectProperty C) @@ -1219,6 +1222,7 @@ section Restriction variable {J C : Type*} [Category* J] [Category* C] {D : J ⥤ C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `Over j ⥤ J` is initial, restricting a limit cone to the diagram above `j`, preserves the limit. -/ @@ -1234,6 +1238,7 @@ noncomputable def Limits.IsLimit.overPost {c : Cone D} (hc : IsLimit c) (j : J) · exact NatIso.ofComponents (fun k ↦ CategoryTheory.Over.isoMk (Iso.refl _)) · exact Cone.ext (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `Over j ⥤ J` is final, restricting a colimit cocone to the diagram below `j`, preserves the limit. -/ diff --git a/Mathlib/CategoryTheory/Limits/FintypeCat.lean b/Mathlib/CategoryTheory/Limits/FintypeCat.lean index dfe06de57ac525..88aad086995fb1 100644 --- a/Mathlib/CategoryTheory/Limits/FintypeCat.lean +++ b/Mathlib/CategoryTheory/Limits/FintypeCat.lean @@ -81,6 +81,7 @@ noncomputable def productEquiv {ι : Type*} [Finite ι] (X : ι → FintypeCat.{ let e : (∀ i, X i) ≃ Shrink.{u} (∀ i, X i) := equivShrink _ (equivEquivIso.symm is₁).trans ((equivEquivIso.symm is₂).trans e.symm) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma productEquiv_apply {ι : Type*} [Finite ι] (X : ι → FintypeCat.{u}) (x : (∏ᶜ X : FintypeCat)) (i : ι) : productEquiv X x i = Pi.π X i x := by diff --git a/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean b/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean index 2c1324ea862275..fb082778bdde9a 100644 --- a/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/FormalCoproducts/Basic.lean @@ -232,6 +232,7 @@ lemma fromIncl_comp_cofanPtIsoSelf_inv (i : X.I) : ∐ X.toFun ≅ X := coproductIsoCofanPt _ _ ≪≫ cofanPtIsoSelf X +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma ι_comp_coproductIsoSelf_hom (i : X.I) : Sigma.ι _ i ≫ (coproductIsoSelf X).hom = .fromIncl i (𝟙 (X.obj i)) := by simp [coproductIsoSelf] diff --git a/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean b/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean index a16d707d3c7fac..da98aa840ed219 100644 --- a/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean +++ b/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean @@ -61,6 +61,7 @@ lemma cechIsoCechNerveApp_hom_π (n : SimplexCategoryᵒᵖ) (i : ToType n.unop) WidePullback.π (fun _ ↦ (isTerminalIncl T hT).from U) i = U.powerπ i := IsLimit.conePointUniqueUpToIso_hom_comp _ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma cechIsoCechNerveApp_inv_π (n : SimplexCategoryᵒᵖ) (i : ToType n.unop) : (U.cechIsoCechNerveApp hT n).inv ≫ U.powerπ i = diff --git a/Mathlib/CategoryTheory/Limits/Fubini.lean b/Mathlib/CategoryTheory/Limits/Fubini.lean index 3e2809883fd7ec..704051a5a2940d 100644 --- a/Mathlib/CategoryTheory/Limits/Fubini.lean +++ b/Mathlib/CategoryTheory/Limits/Fubini.lean @@ -129,7 +129,7 @@ def coneOfConeCurry {D : DiagramOfCones (curry.obj G)} (Q : ∀ j, IsLimit (D.ob set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in -open scoped Prod in +open scoped CategoryTheory.Prod in /-- Given a diagram `D` of colimit cocones over the `F.obj j`, and a cocone over `uncurry.obj F`, we can construct a cocone over the diagram consisting of the cocone points from `D`. -/ @@ -526,6 +526,7 @@ theorem colimitUncurryIsoColimitCompColim_ι_ι_inv {j} {k} : IsColimit.uniqueUpToIso] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp, reassoc] theorem colimitUncurryIsoColimitCompColim_ι_hom {j} {k} : diff --git a/Mathlib/CategoryTheory/Limits/FullSubcategory.lean b/Mathlib/CategoryTheory/Limits/FullSubcategory.lean index 8d1bf11de6ae6f..9711f59107d5e7 100644 --- a/Mathlib/CategoryTheory/Limits/FullSubcategory.lean +++ b/Mathlib/CategoryTheory/Limits/FullSubcategory.lean @@ -34,7 +34,7 @@ variable {J : Type w} [Category.{w'} J] {C : Type u} [Category.{v} C] {P : Objec /-- If a `J`-shaped diagram in `FullSubcategory P` has a limit cone in `C` whose cone point lives in the full subcategory, then this defines a limit in the full subcategory. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitFullSubcategoryInclusion' (F : J ⥤ P.FullSubcategory) {c : Cone (F ⋙ P.ι)} (hc : IsLimit c) (h : P c.pt) : CreatesLimit F P.ι := @@ -42,7 +42,7 @@ def createsLimitFullSubcategoryInclusion' (F : J ⥤ P.FullSubcategory) /-- If a `J`-shaped diagram in `FullSubcategory P` has a limit in `C` whose cone point lives in the full subcategory, then this defines a limit in the full subcategory. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitFullSubcategoryInclusion (F : J ⥤ P.FullSubcategory) [HasLimit (F ⋙ P.ι)] (h : P (limit (F ⋙ P.ι))) : CreatesLimit F P.ι := @@ -50,7 +50,7 @@ def createsLimitFullSubcategoryInclusion (F : J ⥤ P.FullSubcategory) /-- If a `J`-shaped diagram in `FullSubcategory P` has a colimit cocone in `C` whose cocone point lives in the full subcategory, then this defines a colimit in the full subcategory. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitFullSubcategoryInclusion' (F : J ⥤ P.FullSubcategory) {c : Cocone (F ⋙ P.ι)} (hc : IsColimit c) (h : P c.pt) : CreatesColimit F P.ι := @@ -58,7 +58,7 @@ def createsColimitFullSubcategoryInclusion' (F : J ⥤ P.FullSubcategory) /-- If a `J`-shaped diagram in `FullSubcategory P` has a colimit in `C` whose cocone point lives in the full subcategory, then this defines a colimit in the full subcategory. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitFullSubcategoryInclusion (F : J ⥤ P.FullSubcategory) [HasColimit (F ⋙ P.ι)] (h : P (colimit (F ⋙ P.ι))) : @@ -68,7 +68,7 @@ def createsColimitFullSubcategoryInclusion (F : J ⥤ P.FullSubcategory) variable (P J) /-- If `P` is closed under limits of shape `J`, then the inclusion creates such limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitFullSubcategoryInclusionOfClosed [P.IsClosedUnderLimitsOfShape J] (F : J ⥤ P.FullSubcategory) [HasLimit (F ⋙ P.ι)] : CreatesLimit F P.ι := @@ -90,7 +90,7 @@ instance hasLimitsOfShape_of_closedUnderLimits [P.IsClosedUnderLimitsOfShape J] { has_limit := fun F => hasLimit_of_closedUnderLimits J P F } /-- If `P` is closed under colimits of shape `J`, then the inclusion creates such colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitFullSubcategoryInclusionOfClosed [P.IsClosedUnderColimitsOfShape J] (F : J ⥤ P.FullSubcategory) [HasColimit (F ⋙ P.ι)] : CreatesColimit F P.ι := diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean index 0b2f7286adab7e..a2508b593e8003 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean @@ -85,12 +85,14 @@ def combineCones (F : J ⥤ K ⥤ C) (c : ∀ k : K, LimitCone (F.flip.obj k)) : { app := fun j => { app := fun k => (c k).cone.π.app j } naturality := fun j₁ j₂ g => by ext k; exact (c k).cone.π.naturality g } +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- The stitched together cones each project down to the original given cones (up to iso). -/ def evaluateCombinedCones (F : J ⥤ K ⥤ C) (c : ∀ k : K, LimitCone (F.flip.obj k)) (k : K) : ((evaluation K C).obj k).mapCone (combineCones F c) ≅ (c k).cone := Cone.ext (Iso.refl _) +set_option backward.isDefEq.respectTransparency false in /-- Stitching together limiting cones gives a limiting cone. -/ def combinedIsLimit (F : J ⥤ K ⥤ C) (c : ∀ k : K, LimitCone (F.flip.obj k)) : IsLimit (combineCones F c) := @@ -140,12 +142,14 @@ def combineCocones (F : J ⥤ K ⥤ C) (c : ∀ k : K, ColimitCocone (F.flip.obj { app := fun j => { app := fun k => (c k).cocone.ι.app j } naturality := fun j₁ j₂ g => by ext k; exact (c k).cocone.ι.naturality g } +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- The stitched together cocones each project down to the original given cocones (up to iso). -/ def evaluateCombinedCocones (F : J ⥤ K ⥤ C) (c : ∀ k : K, ColimitCocone (F.flip.obj k)) (k : K) : ((evaluation K C).obj k).mapCocone (combineCocones F c) ≅ (c k).cocone := Cocone.ext (Iso.refl _) +set_option backward.isDefEq.respectTransparency false in /-- Stitching together colimiting cocones gives a colimiting cocone. -/ def combinedIsColimit (F : J ⥤ K ⥤ C) (c : ∀ k : K, ColimitCocone (F.flip.obj k)) : IsColimit (combineCocones F c) := @@ -170,6 +174,7 @@ noncomputable def pointwiseCocone [HasColimitsOfShape J C] (F : J ⥤ K ⥤ C) : change (F.flip.obj x).map f ≫ _ = _ rw [colimit.w] } +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- `pointwiseCocone` is indeed a colimit cocone. -/ noncomputable def pointwiseIsColimit [HasColimitsOfShape J C] (F : J ⥤ K ⥤ C) : @@ -291,6 +296,7 @@ theorem limitCompWhiskeringLeftIsoCompLimit_hom_whiskerLeft_π (F : J ⥤ K ⥤ ext d simp [limitCompWhiskeringLeftIsoCompLimit] +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] theorem limitCompWhiskeringLeftIsoCompLimit_inv_π (F : J ⥤ K ⥤ C) (G : D ⥤ K) diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/BinaryBiproducts.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/BinaryBiproducts.lean index ec966799567d7c..13fe145fc458bf 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/BinaryBiproducts.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/BinaryBiproducts.lean @@ -37,6 +37,7 @@ def pointwiseBinaryBicone : BinaryBicone F G where inl := { app X := biprod.inl } inr := { app X := biprod.inr } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The bicone associated with `F` and `G` is a bilimit bicone. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/EpiMono.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/EpiMono.lean index 51d258bb6b2e6b..06e2c33f88fd31 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/EpiMono.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/EpiMono.lean @@ -24,7 +24,7 @@ universe v v' v'' u u' u'' namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor variable {K : Type u} [Category.{v} K] {C : Type u'} [Category.{v'} C] {D : Type u''} [Category.{v''} D] {F G : K ⥤ C} (f : F ⟶ G) diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Images.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Images.lean index 395dc3c8619b4a..6f6b0d91c4f3dc 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Images.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Images.lean @@ -32,6 +32,7 @@ def monoFactorisation {F G : C ⥤ Type u} (f : F ⟶ G) : MonoFactorisation f w m := (Subfunctor.range f).ι e := Subfunctor.toRange f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The image of a natural transformation between type-valued functors satisfies the universal property of images -/ diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Pullbacks.lean index 9e5e5613067e7f..5bb966e41855bd 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Pullbacks.lean @@ -42,6 +42,7 @@ def PullbackCone.combine (f : F ⟶ H) (g : G ⟶ H) (c : ∀ X, PullbackCone (f { app X := (c X).snd } (by ext; simp [(c _).condition]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The pullback cone `combinePullbackCones` is limiting. diff --git a/Mathlib/CategoryTheory/Limits/HasLimits.lean b/Mathlib/CategoryTheory/Limits/HasLimits.lean index 167bdd3d91ff3f..daf22dcd488b58 100644 --- a/Mathlib/CategoryTheory/Limits/HasLimits.lean +++ b/Mathlib/CategoryTheory/Limits/HasLimits.lean @@ -137,6 +137,7 @@ def limit.cone (F : J ⥤ C) [HasLimit F] : Cone F := (getLimitCone F).cone /-- An arbitrary choice of limit object of a functor. -/ +@[implicit_reducible] def limit (F : J ⥤ C) [HasLimit F] := (limit.cone F).pt @@ -437,7 +438,6 @@ theorem limit.post_post {E : Type u''} [Category.{v''} E] (H : D ⥤ E) [h : Has end Post -set_option backward.isDefEq.respectTransparency false in theorem limit.pre_post {D : Type u'} [Category.{v'} D] (E : K ⥤ J) (F : J ⥤ C) (G : C ⥤ D) [HasLimit F] [HasLimit (E ⋙ F)] [HasLimit (F ⋙ G)] [h : HasLimit ((E ⋙ F) ⋙ G)] : -- G (limit F) ⟶ G (limit (E ⋙ F)) ⟶ limit ((E ⋙ F) ⋙ G) vs @@ -476,7 +476,7 @@ variable [HasLimitsOfShape J C] section /-- `limit F` is functorial in `F`, when `C` has all limits of shape `J`. -/ -@[simps] +@[simps, implicit_reducible] def lim : (J ⥤ C) ⥤ C where obj F := limit F map α := limMap α @@ -510,11 +510,9 @@ theorem limit.map_pre' [HasLimitsOfShape K C] (F : J ⥤ C) {E₁ E₂ : K ⥤ J limit.pre F E₂ = limit.pre F E₁ ≫ lim.map (whiskerRight α F) := by ext1; simp -set_option backward.isDefEq.respectTransparency false in theorem limit.id_pre (F : J ⥤ C) : limit.pre F (𝟭 _) = lim.map (Functor.leftUnitor F).inv := by cat_disch -set_option backward.isDefEq.respectTransparency false in theorem limit.map_post {D : Type u'} [Category.{v'} D] [HasLimitsOfShape J D] (H : C ⥤ D) : /- H (limit F) ⟶ H (limit G) ⟶ limit (G ⋙ H) vs H (limit F) ⟶ limit (F ⋙ H) ⟶ limit (G ⋙ H) -/ @@ -522,6 +520,7 @@ theorem limit.map_post {D : Type u'} [Category.{v'} D] [HasLimitsOfShape J D] (H ext simp only [whiskerRight_app, limMap_π, assoc, limit.post_π_assoc, limit.post_π, ← H.map_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between morphisms from `W` to the cone point of the limit cone for `F` @@ -576,7 +575,6 @@ noncomputable def coneOfAdj (F : J ⥤ C) : Cone F where π := adj.counit.app F set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The cones defined by `coneOfAdj` are limit cones. -/ @[simps] def isLimitConeOfAdj (F : J ⥤ C) : @@ -701,6 +699,7 @@ def colimit.cocone (F : J ⥤ C) [HasColimit F] : Cocone F := (getColimitCocone F).cocone /-- An arbitrary choice of colimit object of a functor. -/ +@[implicit_reducible] def colimit (F : J ⥤ C) [HasColimit F] := (colimit.cocone F).pt @@ -953,7 +952,6 @@ set_option backward.isDefEq.respectTransparency false in theorem colimit.ι_pre (k : K) : colimit.ι (E ⋙ F) k ≫ colimit.pre F E = colimit.ι F (E.obj k) := by simp [colimit.pre] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem colimit.ι_inv_pre [IsIso (pre F E)] (k : K) : colimit.ι F (E.obj k) ≫ inv (colimit.pre F E) = colimit.ι (E ⋙ F) k := by @@ -969,7 +967,6 @@ theorem colimit.pre_desc (c : Cocone F) : variable {L : Type u₃} [Category.{v₃} L] variable (D : L ⥤ K) -set_option backward.isDefEq.respectTransparency false in @[simp] theorem colimit.pre_pre [h : HasColimit (D ⋙ E ⋙ F)] : haveI : HasColimit ((D ⋙ E) ⋙ F) := h @@ -1020,7 +1017,6 @@ theorem colimit.post_desc (c : Cocone F) : rw [← assoc, colimit.ι_post, ← G.map_comp, colimit.ι_desc, colimit.ι_desc] rfl -set_option backward.isDefEq.respectTransparency false in @[simp] theorem colimit.post_post {E : Type u''} [Category.{v''} E] (H : D ⥤ E) -- H G (colimit F) ⟶ H (colimit (F ⋙ G)) ⟶ colimit ((F ⋙ G) ⋙ H) equals @@ -1034,7 +1030,6 @@ theorem colimit.post_post {E : Type u''} [Category.{v''} E] (H : D ⥤ E) end Post -set_option backward.isDefEq.respectTransparency false in theorem colimit.pre_post {D : Type u'} [Category.{v'} D] (E : K ⥤ J) (F : J ⥤ C) (G : C ⥤ D) [HasColimit F] [HasColimit (E ⋙ F)] [HasColimit (F ⋙ G)] [h : HasColimit ((E ⋙ F) ⋙ G)] : -- G (colimit F) ⟶ G (colimit (E ⋙ F)) ⟶ colimit ((E ⋙ F) ⋙ G) vs @@ -1074,7 +1069,7 @@ variable [HasColimitsOfShape J C] section /-- `colimit F` is functorial in `F`, when `C` has all colimits of shape `J`. -/ -@[simps] +@[simps, implicit_reducible] def colim : (J ⥤ C) ⥤ C where obj F := colimit F map α := colimMap α @@ -1116,7 +1111,6 @@ theorem colimit.pre_map' [HasColimitsOfShape K C] (F : J ⥤ C) {E₁ E₂ : K simp set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem colimit.pre_id (F : J ⥤ C) : colimit.pre F (𝟭 _) = colim.map (Functor.leftUnitor F).hom := by cat_disch @@ -1132,6 +1126,7 @@ theorem colimit.map_post {D : Type u'} [Category.{v'} D] [HasColimitsOfShape J D rw [← assoc, colimit.ι_map, assoc, colimit.ι_post] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between morphisms from the cone point of the colimit cocone for `F` to `W` @@ -1215,6 +1210,7 @@ end Colimit section Opposite +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `t : Cone F` is a limit cone, then `t.op : Cocone F.op` is a colimit cocone. -/ @@ -1230,6 +1226,7 @@ def IsLimit.op {t : Cone F} (P : IsLimit t) : IsColimit t.op where rw [← w] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `t : Cocone F` is a colimit cocone, then `t.op : Cone F.op` is a limit cone. -/ diff --git a/Mathlib/CategoryTheory/Limits/IndYoneda.lean b/Mathlib/CategoryTheory/Limits/IndYoneda.lean index 62e7486874499a..4cafd6af6dbe9f 100644 --- a/Mathlib/CategoryTheory/Limits/IndYoneda.lean +++ b/Mathlib/CategoryTheory/Limits/IndYoneda.lean @@ -71,6 +71,7 @@ noncomputable def colimitHomIsoLimitYoneda (colimit F ⟶ A) ≅ limit (F.op ⋙ yoneda.obj A) := (coyonedaOpColimitIsoLimitCoyoneda F).app A ≪≫ limitObjIsoLimitCompEvaluation _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma colimitHomIsoLimitYoneda_hom_comp_π [HasLimitsOfShape Iᵒᵖ (Type u₂)] (A : C) (i : I) : (colimitHomIsoLimitYoneda F A).hom ≫ limit.π (F.op ⋙ yoneda.obj A) ⟨i⟩ = @@ -80,6 +81,7 @@ lemma colimitHomIsoLimitYoneda_hom_comp_π [HasLimitsOfShape Iᵒᵖ (Type u₂) change ((coyonedaOpColimitIsoLimitCoyoneda F).hom ≫ _).app A = _ rw [coyonedaOpColimitIsoLimitCoyoneda_hom_comp_π, Functor.flip_map_app] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma colimitHomIsoLimitYoneda_inv_comp_π [HasLimitsOfShape Iᵒᵖ (Type u₂)] (A : C) (i : I) : @@ -121,6 +123,7 @@ noncomputable def colimitHomIsoLimitYoneda' [HasLimitsOfShape I (Type u₂)] (A (colimit F ⟶ A) ≅ limit (F.rightOp ⋙ yoneda.obj A) := (coyonedaOpColimitIsoLimitCoyoneda' F).app A ≪≫ limitObjIsoLimitCompEvaluation _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma colimitHomIsoLimitYoneda'_hom_comp_π [HasLimitsOfShape I (Type u₂)] (A : C) (i : I) : (colimitHomIsoLimitYoneda' F A).hom ≫ limit.π (F.rightOp ⋙ yoneda.obj A) i = @@ -131,6 +134,7 @@ lemma colimitHomIsoLimitYoneda'_hom_comp_π [HasLimitsOfShape I (Type u₂)] (A change ((coyonedaOpColimitIsoLimitCoyoneda' F).hom ≫ _).app A = _ rw [coyonedaOpColimitIsoLimitCoyoneda'_hom_comp_π, Functor.flip_map_app] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma colimitHomIsoLimitYoneda'_inv_comp_π [HasLimitsOfShape I (Type u₂)] (A : C) (i : I) : @@ -154,6 +158,7 @@ noncomputable def colimitCoyonedaHomIsoLimit : colimitHomIsoLimitYoneda _ F ≪≫ HasLimit.isoOfNatIso (Functor.isoWhiskerLeft (D ⋙ Prod.sectL C F) (coyonedaLemma C)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma colimitCoyonedaHomIsoLimit_π_apply (f : colimit (D.rightOp ⋙ coyoneda) ⟶ F) (i : I) : dsimp% limit.π (D ⋙ F ⋙ uliftFunctor.{u₁}) (op i) ((colimitCoyonedaHomIsoLimit D F).hom f) = @@ -207,6 +212,7 @@ noncomputable def colimitYonedaHomIsoLimit : colimitHomIsoLimitYoneda _ _ ≪≫ HasLimit.isoOfNatIso (Functor.isoWhiskerLeft (D ⋙ Prod.sectL _ _) (yonedaLemma C)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma colimitYonedaHomIsoLimit_π_apply (f : colimit (D.unop ⋙ yoneda) ⟶ F) (i : Iᵒᵖ) : dsimp% limit.π (D ⋙ F ⋙ uliftFunctor.{u₁}) i ((colimitYonedaHomIsoLimit D F).hom f) = @@ -258,6 +264,7 @@ noncomputable def colimitCoyonedaHomIsoLimit' : colimitHomIsoLimitYoneda' _ F ≪≫ HasLimit.isoOfNatIso (Functor.isoWhiskerLeft (D ⋙ Prod.sectL C F) (coyonedaLemma C)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma colimitCoyonedaHomIsoLimit'_π_apply (f : colimit (D.op ⋙ coyoneda) ⟶ F) (i : I) : dsimp% limit.π (D ⋙ F ⋙ uliftFunctor.{u₁}) i ((colimitCoyonedaHomIsoLimit' D F).hom f) = @@ -308,6 +315,7 @@ noncomputable def colimitYonedaHomIsoLimit' : colimitHomIsoLimitYoneda' _ F ≪≫ HasLimit.isoOfNatIso (Functor.isoWhiskerLeft (D ⋙ Prod.sectL _ _) (yonedaLemma C)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma colimitYonedaHomIsoLimit'_π_apply (f : colimit (D.leftOp ⋙ yoneda) ⟶ F) (i : I) : dsimp% limit.π (D ⋙ F ⋙ uliftFunctor.{u₁}) i ((colimitYonedaHomIsoLimit' D F).hom f) = diff --git a/Mathlib/CategoryTheory/Limits/Indization/Category.lean b/Mathlib/CategoryTheory/Limits/Indization/Category.lean index 30937a6d5a8a6a..e867a01caa2aec 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/Category.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/Category.lean @@ -62,7 +62,7 @@ universe w v u namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor variable {C : Type u} [Category.{v} C] @@ -285,6 +285,7 @@ instance [HasColimitsOfShape WalkingParallelPair C] : instance [HasFiniteColimits C] : HasColimits (Ind C) := has_colimits_of_hasCoequalizers_and_coproducts +set_option backward.isDefEq.respectTransparency.types false in /-- A way to understand morphisms in `Ind C`: every morphism is induced by a natural transformation of diagrams. -/ theorem Ind.exists_nonempty_arrow_mk_iso_ind_lim {A B : Ind C} {f : A ⟶ B} : diff --git a/Mathlib/CategoryTheory/Limits/Indization/FilteredColimits.lean b/Mathlib/CategoryTheory/Limits/Indization/FilteredColimits.lean index 072d7f628f9c68..21218a6eb4bcb1 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/FilteredColimits.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/FilteredColimits.lean @@ -89,7 +89,7 @@ theorem exists_nonempty_limit_obj_of_isColimit [IsFiltered K] {c : Cocone H} (hc end Interchange -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in theorem isFiltered [IsFiltered I] (hF : ∀ i, IsIndObject (F.obj i)) : IsFiltered (CostructuredArrow yoneda (colimit F)) := by -- It suffices to show that for any functor `G : J ⥤ CostructuredArrow yoneda (colimit F)` with diff --git a/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean b/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean index 1b8116de11dfdd..61c8d9282a93dd 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean @@ -103,6 +103,9 @@ noncomputable def extend {A B : Cᵒᵖ ⥤ Type v} (P : IndObjectPresentation A [IsIso η] : IndObjectPresentation B := .ofCocone (P.cocone.extend η) (P.coconeIsColimit.extendIso η) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical comparison functor between the indexing category of the presentation and the comma category `CostructuredArrow yoneda A`. This functor is always final. -/ @[simps! obj_left obj_right_as obj_hom map_left] diff --git a/Mathlib/CategoryTheory/Limits/Indization/LocallySmall.lean b/Mathlib/CategoryTheory/Limits/Indization/LocallySmall.lean index 1b9a19d571a67a..954da6cfcfe329 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/LocallySmall.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/LocallySmall.lean @@ -61,7 +61,7 @@ theorem colimitYonedaHomEquiv_π_apply (η : colimit (F ⋙ yoneda) ⟶ G) (i : dsimp% limit.π (F.op ⋙ G) i (colimitYonedaHomEquiv F G η) = η.app (op (F.obj i.unop)) ((colimit.ι (F ⋙ yoneda) i.unop).app _ (𝟙 _)) := by simp only [colimitYonedaHomEquiv, Iso.toEquiv, uliftFunctor_obj, - Iso.trans_def, Iso.trans_assoc, Iso.trans_hom, Iso.symm_hom, Iso.trans_inv, Iso.symm_inv, + Iso.trans_def, Iso.trans_assoc, Iso.trans_hom, Iso.trans_inv, Category.assoc, Equiv.symm_trans_apply, Equiv.symm_symm, Equiv.coe_fn_mk, comp_apply, Equiv.ulift_apply] have (a : limit ((F.op ⋙ G) ⋙ uliftFunctor.{u, v})) := congrArg ULift.down @@ -70,7 +70,6 @@ theorem colimitYonedaHomEquiv_π_apply (η : colimit (F ⋙ yoneda) ⟶ G) (i : rw [HasLimit.isoOfNatIso_hom_π_apply] dsimp erw [colimitYonedaHomIsoLimitOp_π_apply] - rfl instance : Small.{v} (colimit (F ⋙ yoneda) ⟶ G) where equiv_small := ⟨_, ⟨colimitYonedaHomEquiv F G⟩⟩ diff --git a/Mathlib/CategoryTheory/Limits/Indization/ParallelPair.lean b/Mathlib/CategoryTheory/Limits/Indization/ParallelPair.lean index 6e50564c2e8a72..78d47dca90065f 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/ParallelPair.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/ParallelPair.lean @@ -27,7 +27,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor variable {C : Type u₁} [Category.{v₁} C] diff --git a/Mathlib/CategoryTheory/Limits/IsLimit.lean b/Mathlib/CategoryTheory/Limits/IsLimit.lean index fb192345963e50..76d8b75138b394 100644 --- a/Mathlib/CategoryTheory/Limits/IsLimit.lean +++ b/Mathlib/CategoryTheory/Limits/IsLimit.lean @@ -87,14 +87,15 @@ instance subsingleton {t : Cone F} : Subsingleton (IsLimit t) := /-- Given a natural transformation `α : F ⟶ G`, we give a morphism from the cone point of any cone over `F` to the cone point of a limit cone over `G`. -/ -@[to_dual (reorder := s P t) +@[implicit_reducible, to_dual (reorder := s P t) /-- Given a natural transformation `α : F ⟶ G`, we give a morphism from the cocone point of a colimit cocone over `F` to the cocone point of any cocone over `G`. -/] def map {F G : J ⥤ C} (s : Cone F) {t : Cone G} (P : IsLimit t) (α : F ⟶ G) : s.pt ⟶ t.pt := P.lift ((Cone.postcompose α).obj s) --- The `set_option` is needed to make reassoc generate the right theorem -set_option backward.isDefEq.respectTransparency false in +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) (reorder := c hd d) ι_map] theorem map_π {F G : J ⥤ C} (c : Cone F) {d : Cone G} (hd : IsLimit d) (α : F ⟶ G) (j : J) : hd.map c α ≫ d.π.app j = c.π.app j ≫ α.app j := @@ -177,11 +178,13 @@ theorem conePointUniqueUpToIso_inv_comp {s t : Cone F} (P : IsLimit s) (Q : IsLi (conePointUniqueUpToIso P Q).inv ≫ s.π.app j = t.π.app j := (uniqueUpToIso P Q).inv.w _ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) coconePointUniqueUpToIso_inv_desc] theorem lift_comp_conePointUniqueUpToIso_hom {r s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : P.lift r ≫ (conePointUniqueUpToIso P Q).hom = Q.lift r := Q.uniq _ _ (by simp) +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) coconePointUniqueUpToIso_hom_desc] theorem lift_comp_conePointUniqueUpToIso_inv {r s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : Q.lift r ≫ (conePointUniqueUpToIso P Q).inv = P.lift r := @@ -233,12 +236,14 @@ def ofPointIso {r t : Cone F} (P : IsLimit r) [i : IsIso (P.lift t)] : IsLimit t variable {t : Cone F} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[to_dual] theorem hom_lift (h : IsLimit t) {W : C} (m : W ⟶ t.pt) : m = h.lift { pt := W, π := { app := fun b => m ≫ t.π.app b } } := h.uniq { pt := W, π := { app := fun b => m ≫ t.π.app b } } m fun _ => rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Two morphisms into a limit are equal if their compositions with each cone morphism are equal. -/ @[to_dual /-- Two morphisms out of a colimit are equal if their compositions with @@ -248,6 +253,7 @@ theorem hom_ext (h : IsLimit t) {W : C} {f f' : W ⟶ t.pt} f = f' := by rw [h.hom_lift f, h.hom_lift f']; congr; exact funext w +set_option backward.isDefEq.respectTransparency.types false in @[to_dual] lemma nonempty_isLimit_iff_isIso_lift {s t : Cone F} (hs : IsLimit s) : Nonempty (IsLimit t) ↔ IsIso (hs.lift t) := @@ -360,24 +366,28 @@ def conePointsIsoOfNatIso {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit attribute [to_dual existing coconePointsIsoOfNatIso_inv] conePointsIsoOfNatIso_hom attribute [to_dual existing coconePointsIsoOfNatIso_hom] conePointsIsoOfNatIso_inv +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_inv] theorem conePointsIsoOfNatIso_hom_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) (j : J) : (conePointsIsoOfNatIso P Q w).hom ≫ t.π.app j = s.π.app j ≫ w.hom.app j := by simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_hom] theorem conePointsIsoOfNatIso_inv_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) (j : J) : (conePointsIsoOfNatIso P Q w).inv ≫ s.π.app j = t.π.app j ≫ w.inv.app j := by simp -set_option backward.defeqAttrib.useBackward true in @[to_dual (attr := reassoc) coconePointsIsoOfNatIso_inv_desc] theorem lift_comp_conePointsIsoOfNatIso_hom {F G : J ⥤ C} {r s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) : P.lift r ≫ (conePointsIsoOfNatIso P Q w).hom = Q.map r w.hom := Q.hom_ext (by simp) -set_option backward.defeqAttrib.useBackward true in @[to_dual (attr := reassoc) coconePointsIsoOfNatIso_hom_desc] theorem lift_comp_conePointsIsoOfNatIso_inv {F G : J ⥤ C} {r s : Cone G} {t : Cone F} (P : IsLimit t) (Q : IsLimit s) (w : F ≅ G) : @@ -489,6 +499,7 @@ def homEquiv (h : IsLimit t) {W : C} : (W ⟶ t.pt) ≃ ((Functor.const J).obj W left_inv f := h.hom_ext (by simp) right_inv π := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) ι_app_homEquiv_symm] lemma homEquiv_symm_π_app (h : IsLimit t) {W : C} (f : (const J).obj W ⟶ F) (j : J) : @@ -630,6 +641,7 @@ section open OfNatIso +set_option backward.isDefEq.respectTransparency.types false in /-- If `F.cones` is representable, then the cone corresponding to the identity morphism on the representing object is a limit cone. -/ @@ -757,6 +769,7 @@ section open OfNatIso +set_option backward.isDefEq.respectTransparency.types false in /-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on the representing object is a colimit cocone. -/ diff --git a/Mathlib/CategoryTheory/Limits/MonoCoprod.lean b/Mathlib/CategoryTheory/Limits/MonoCoprod.lean index 3229ffa052a6a5..6aab3b53b4072d 100644 --- a/Mathlib/CategoryTheory/Limits/MonoCoprod.lean +++ b/Mathlib/CategoryTheory/Limits/MonoCoprod.lean @@ -215,6 +215,7 @@ section variable [MonoCoprod C] {I : Type*} (X : I → C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma mono_inj (c : Cofan X) (h : IsColimit c) (i : I) [HasCoproduct (fun (k : ((Set.range (fun _ : Unit ↦ i))ᶜ : Set I)) => X k.1)] : @@ -231,7 +232,7 @@ instance mono_ι [HasCoproduct X] (i : I) end -open Functor +open CategoryTheory.Functor section Preservation diff --git a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean index 8016311053c3b0..86d0ea91e6630c 100644 --- a/Mathlib/CategoryTheory/Limits/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/Limits/MorphismProperty.lean @@ -28,7 +28,7 @@ variable (D : J ⥤ P.Comma L R ⊤ ⊤) /-- If `P` is closed under limits of shape `J` in `Comma L R`, then when `D` has a limit in `Comma L R`, the forgetful functor creates this limit. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def forgetCreatesLimitOfClosed [(P.commaObj L R).IsClosedUnderLimitsOfShape J] [HasLimit (D ⋙ forget L R P ⊤ ⊤)] : @@ -40,7 +40,7 @@ noncomputable def forgetCreatesLimitOfClosed /-- If `Comma L R` has limits of shape `J` and `Comma L R` is closed under limits of shape `J`, then `forget L R P ⊤ ⊤` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def forgetCreatesLimitsOfShapeOfClosed [HasLimitsOfShape J (Comma L R)] [ObjectProperty.IsClosedUnderLimitsOfShape (P.commaObj L R) J] : CreatesLimitsOfShape J (forget L R P ⊤ ⊤) where @@ -60,7 +60,7 @@ instance hasLimitsOfShape_of_closedUnderLimitsOfShape [HasLimitsOfShape J (Comma /-- If `P` is closed under colimits of shape `J` in `Comma L R`, then when `D` has a colimit in `Comma L R`, the forgetful functor creates this colimit. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def forgetCreatesColimitOfClosed [(P.commaObj L R).IsClosedUnderColimitsOfShape J] [HasColimit (D ⋙ forget L R P ⊤ ⊤)] : @@ -72,7 +72,7 @@ noncomputable def forgetCreatesColimitOfClosed variable (J) in /-- If `Comma L R` has colimits of shape `J` and `Comma L R` is closed under colimits of shape `J`, then `forget L R P ⊤ ⊤` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def forgetCreatesColimitsOfShapeOfClosed [HasColimitsOfShape J (Comma L R)] [(P.commaObj L R).IsClosedUnderColimitsOfShape J] : CreatesColimitsOfShape J (forget L R P ⊤ ⊤) where @@ -263,6 +263,7 @@ noncomputable instance [P.ContainsIdentities] [P.RespectsIso] : · exact inferInstanceAs (HasLimitsOfShape _ (Over X)) · apply Over.closedUnderLimitsOfShape_discrete_empty _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {X} in instance [P.ContainsIdentities] (Y : P.Over ⊤ X) : diff --git a/Mathlib/CategoryTheory/Limits/Over.lean b/Mathlib/CategoryTheory/Limits/Over.lean index ebf513ada46641..c00d072a5fd721 100644 --- a/Mathlib/CategoryTheory/Limits/Over.lean +++ b/Mathlib/CategoryTheory/Limits/Over.lean @@ -86,6 +86,7 @@ def _root_.CategoryTheory.Limits.colimit.isColimitToOver (F : J ⥤ C) [HasColim IsColimit (colimit.toOver F) := Over.isColimitToOver (colimit.isColimit F) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given an arrow `c.pt ⟶ X`, the diagram `J ⥤ C` can be lifted to `Over X ⥤ C`, and the cocone `c` also lifts to the diagram on `Over`. -/ @@ -147,6 +148,7 @@ def _root_.CategoryTheory.Limits.limit.isLimitToOver (F : J ⥤ C) [HasLimit F] IsLimit (limit.toUnder F) := Under.isLimitToUnder (limit.isLimit F) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given an arrow `X ⟶ c.pt`, the diagram `J ⥤ C` can be lifted to `Under X ⥤ C`, and the cone `c` also lifts to the diagram on `Under`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Preorder.lean b/Mathlib/CategoryTheory/Limits/Preorder.lean index a4da980b0331aa..2b37701616879f 100644 --- a/Mathlib/CategoryTheory/Limits/Preorder.lean +++ b/Mathlib/CategoryTheory/Limits/Preorder.lean @@ -105,13 +105,13 @@ section variable [Preorder C] /-- A terminal object in a preorder `C` is top element for `C`. -/ -@[implicit_reducible] +@[instance_reducible] def _root_.CategoryTheory.Limits.IsTerminal.orderTop {X : C} (t : IsTerminal X) : OrderTop C where top := X le_top Y := leOfHom (t.from Y) /-- A preorder with a terminal object has a greatest element. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def orderTopOfHasTerminal [HasTerminal C] : OrderTop C := IsTerminal.orderTop terminalIsTerminal @@ -122,13 +122,13 @@ def isTerminalTop [OrderTop C] : IsTerminal (⊤ : C) := IsTerminal.ofUnique _ instance (priority := low) [OrderTop C] : HasTerminal C := hasTerminal_of_unique ⊤ /-- An initial object in a preorder `C` is bottom element for `C`. -/ -@[implicit_reducible] +@[instance_reducible] def _root_.CategoryTheory.Limits.IsInitial.orderBot {X : C} (t : IsInitial X) : OrderBot C where bot := X bot_le Y := leOfHom (t.to Y) /-- A preorder with an initial object has a least element. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def orderBotOfHasInitial [HasInitial C] : OrderBot C := IsInitial.orderBot initialIsInitial @@ -147,7 +147,7 @@ variable [PartialOrder C] /-- A family of limiting binary fans on a partial order induces an inf-semilattice structure on it. -/ -@[implicit_reducible] +@[instance_reducible] def semilatticeInfOfIsLimitBinaryFan (c : ∀ (X Y : C), BinaryFan X Y) (h : (X Y : C) → IsLimit (c X Y)) : SemilatticeInf C where inf X Y := (c X Y).pt @@ -157,7 +157,7 @@ def semilatticeInfOfIsLimitBinaryFan variable (C) in /-- If a partial order has binary products, then it is an inf-semilattice -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def semilatticeInfOfHasBinaryProducts [HasBinaryProducts C] : SemilatticeInf C := semilatticeInfOfIsLimitBinaryFan (fun _ _ ↦ BinaryFan.mk prod.fst prod.snd) (fun X Y ↦ prodIsProd X Y) @@ -165,7 +165,7 @@ noncomputable def semilatticeInfOfHasBinaryProducts [HasBinaryProducts C] : Semi /-- A family of colimiting binary cofans on a partial order induces a sup-semilattice structure on it. -/ -@[implicit_reducible] +@[instance_reducible] def semilatticeSupOfIsColimitBinaryCofan (c : ∀ (X Y : C), BinaryCofan X Y) (h : (X Y : C) → IsColimit (c X Y)) : SemilatticeSup C where sup X Y := (c X Y).pt @@ -175,7 +175,7 @@ def semilatticeSupOfIsColimitBinaryCofan variable (C) in /-- If a partial order has binary coproducts, then it is a sup-semilattice -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def semilatticeSupOfHasBinaryCoproducts [HasBinaryCoproducts C] : SemilatticeSup C := semilatticeSupOfIsColimitBinaryCofan (fun _ _ ↦ BinaryCofan.mk coprod.inl coprod.inr) (fun X Y ↦ coprodIsCoprod X Y) diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean index 36706e0f7f9b90..bad773fc08527b 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean @@ -263,6 +263,7 @@ lemma preservesLimitsOfSize_iff_of_natIso {F G : C ⥤ D} (h : F ≅ G) : PreservesLimitsOfSize.{w, w'} F ↔ PreservesLimitsOfSize.{w, w'} G := ⟨fun _ ↦ preservesLimits_of_natIso h, fun _ ↦ preservesLimits_of_natIso h.symm⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Transfer preservation of limits along an equivalence in the shape. -/ lemma preservesLimitsOfShape_of_equiv {J' : Type w₂} [Category.{w₂'} J'] (e : J ≌ J') (F : C ⥤ D) @@ -345,6 +346,7 @@ lemma preservesColimitsOfSize_iff_of_natIso {F G : C ⥤ D} (h : F ≅ G) : PreservesColimitsOfSize.{w, w'} F ↔ PreservesColimitsOfSize.{w, w'} G := ⟨fun _ ↦ preservesColimits_of_natIso h, fun _ ↦ preservesColimits_of_natIso h.symm⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Transfer preservation of colimits along an equivalence in the shape. -/ lemma preservesColimitsOfShape_of_equiv {J' : Type w₂} [Category.{w₂'} J'] (e : J ≌ J') (F : C ⥤ D) @@ -766,7 +768,7 @@ end section -open Functor +open CategoryTheory.Functor set_option backward.defeqAttrib.useBackward true in lemma isIso_app_coconePt_of_preservesColimit @@ -787,6 +789,7 @@ end variable (F : C ⥤ D) +set_option backward.isDefEq.respectTransparency.types false in /-- A fully faithful functor reflects limits. -/ instance fullyFaithful_reflectsLimits [F.Full] [F.Faithful] : ReflectsLimitsOfSize.{w, w'} F where reflectsLimitsOfShape {J} 𝒥₁ := @@ -798,6 +801,7 @@ instance fullyFaithful_reflectsLimits [F.Full] [F.Faithful] : ReflectsLimitsOfSi intro s m rw [Functor.map_preimage] apply t.uniq_cone_morphism⟩ } } +set_option backward.isDefEq.respectTransparency.types false in /-- A fully faithful functor reflects colimits. -/ instance fullyFaithful_reflectsColimits [F.Full] [F.Faithful] : ReflectsColimitsOfSize.{w, w'} F where diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean b/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean index 2e76a7699b92dc..eaf7416c604e4b 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Bifunctor.lean @@ -25,7 +25,7 @@ out of this typeclass. namespace CategoryTheory -open Category Limits Functor +open Category Limits CategoryTheory.Functor variable {J₁ J₂ : Type*} [Category* J₁] [Category* J₂] {C₁ C₂ C : Type*} [Category* C₁] [Category* C₂] [Category* C] @@ -146,7 +146,7 @@ variable {c₁ : Cocone K₁} (hc₁ : IsColimit c₁) {c₃ : Cocone <| uncurry.obj (whiskeringLeft₂ C |>.obj K₁ |>.obj K₂ |>.obj G)} (hc₃ : IsColimit c₃) -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize the inverse direction of the isomorphism `PreservesColimit₂.isoObjCoconePointsOfIsColimit` w.r.t. the canonical maps to the colimit. -/ @[reassoc (attr := simp)] @@ -184,6 +184,9 @@ noncomputable def isoColimitUncurryWhiskeringLeft₂ : isoObjCoconePointsOfIsColimit G (colimit.isColimit _) (colimit.isColimit _) (colimit.isColimit _) |>.symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize the forward direction of the isomorphism `PreservesColimit₂.isoColimitUncurryWhiskeringLeft₂` w.r.t. the canonical maps to the colimit. -/ @[reassoc (attr := simp)] @@ -238,6 +241,7 @@ instance of_preservesColimits_in_each_variable ⟨IsColimit.ofCoconeUncurry P <| IsColimit.precomposeHomEquiv E₀ _ <| IsColimit.ofIsoColimit (isColimitOfPreserves _ hc₁) E₁.symm⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem of_preservesColimit₂_flip : PreservesColimit₂ K₂ K₁ G.flip where nonempty_isColimit_mapCocone₂ {c₁} hc₁ {c₂} hc₂ := by @@ -315,6 +319,9 @@ noncomputable def isoLimitUncurryWhiskeringLeft₂ : isoObjConePointsOfIsLimit G (limit.isLimit _) (limit.isLimit _) (limit.isLimit _) |>.symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Characterize the inverse direction of the isomorphism `PreservesLimit₂.isoLimitUncurryWhiskeringLeft₂` w.r.t. the canonical maps to the limit. -/ @[reassoc (attr := simp)] @@ -337,6 +344,7 @@ lemma isoLimitUncurryWhiskeringLeft₂_hom_comp_map_π (j : J₁ × J₂) : end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If a bifunctor preserves separately limits of `K₁` in the first variable and limits of `K₂` in the second variable, then it preserves colimit of the pair of cones `K₁, K₂`. -/ @@ -369,6 +377,7 @@ instance of_preservesLimits_in_each_variable ⟨IsLimit.ofConeOfConeUncurry P <| IsLimit.postcomposeHomEquiv E₀ _ <| IsLimit.ofIsoLimit (isLimitOfPreserves _ hc₁) E₁.symm⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem of_preservesLimit₂_flip : PreservesLimit₂ K₂ K₁ G.flip where nonempty_isLimit_mapCone₂ {c₁} hc₁ {c₂} hc₂ := by diff --git a/Mathlib/CategoryTheory/Limits/Preserves/BifunctorCokernel.lean b/Mathlib/CategoryTheory/Limits/Preserves/BifunctorCokernel.lean index 27ea2512e32ed1..98a48c79708bbe 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/BifunctorCokernel.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/BifunctorCokernel.lean @@ -87,6 +87,7 @@ end isColimitMapBifunctor variable [HasBinaryCoproduct ((F.obj X₁).obj Y₂) ((F.obj Y₁).obj X₂)] [PreservesColimit (parallelPair f₁ 0) (F.flip.obj X₂)] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open isColimitMapBifunctor in /-- Let `c₁` (resp. `c₂`) be a colimit cokernel cofork for a morphism `f₁ : X₁ ⟶ Y₁` diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Creates/Finite.lean b/Mathlib/CategoryTheory/Limits/Preserves/Creates/Finite.lean index 67d93ec1b09e3f..ba47912dc78d69 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Creates/Finite.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Creates/Finite.lean @@ -46,7 +46,7 @@ instance (priority := 100) createsLimitsOfShapeOfCreatesFiniteLimits (F : C ⥤ -- Cannot be an instance because of unbound universe variables. /-- If `F` creates limits of any size, it creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def CreatesLimitsOfSize.createsFiniteLimits (F : C ⥤ D) [CreatesLimitsOfSize.{w, w'} F] : CreatesFiniteLimits F where createsFiniteLimits J _ _ := createsLimitsOfShapeOfEquiv @@ -62,7 +62,7 @@ instance (priority := 100) CreatesLimits.createsFiniteLimits (F : C ⥤ D) attribute [local instance] uliftCategory in /-- If `F` creates finite limits in any universe, then it creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOfCreatesFiniteLimitsOfSize (F : C ⥤ D) (h : ∀ (J : Type w) {_ : SmallCategory J} (_ : FinCategory J), CreatesLimitsOfShape J F) : CreatesFiniteLimits F where @@ -75,7 +75,7 @@ instance compCreatesFiniteLimits (F : C ⥤ D) (G : D ⥤ E) [CreatesFiniteLimit createsFiniteLimits _ _ _ := compCreatesLimitsOfShape F G /-- Transfer creation of finite limits along a natural isomorphism in the functor. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOfNatIso {F G : C ⥤ D} {h : F ≅ G} [CreatesFiniteLimits F] : CreatesFiniteLimits G where createsFiniteLimits _ _ _ := createsLimitsOfShapeOfNatIso h @@ -103,7 +103,7 @@ noncomputable section /-- The condition of `CreatesFiniteProducts` can be checked for finite types in an arbitrary universe. -/ -@[implicit_reducible] +@[instance_reducible] def CreatesFiniteProducts.mk' (F : C ⥤ D) (H : ∀ (J : Type w) [Fintype J], CreatesLimitsOfShape (Discrete J) F) : CreatesFiniteProducts F where @@ -119,7 +119,7 @@ instance compCreatesFiniteProducts (F : C ⥤ D) (G : D ⥤ E) [CreatesFinitePro creates _ _ := compCreatesLimitsOfShape _ _ /-- Transfer creation of finite products along a natural isomorphism in the functor. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteProductsOfNatIso {F G : C ⥤ D} {h : F ≅ G} [CreatesFiniteProducts F] : CreatesFiniteProducts G where creates _ _ := createsLimitsOfShapeOfNatIso h @@ -147,7 +147,7 @@ instance (priority := 100) createsColimitsOfShapeOfCreatesFiniteColimits (F : C -- Cannot be an instance because of unbound universe variables. /-- If `F` creates colimits of any size, it creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def CreatesColimitsOfSize.createsFiniteColimits (F : C ⥤ D) [CreatesColimitsOfSize.{w, w'} F] : CreatesFiniteColimits F where createsFiniteColimits J _ _ := createsColimitsOfShapeOfEquiv @@ -163,7 +163,7 @@ instance (priority := 100) CreatesColimits.createsFiniteColimits (F : C ⥤ D) attribute [local instance] uliftCategory in /-- If `F` creates finite colimits in any universe, then it creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOfCreatesFiniteColimitsOfSize (F : C ⥤ D) (h : ∀ (J : Type w) {_ : SmallCategory J} (_ : FinCategory J), CreatesColimitsOfShape J F) : CreatesFiniteColimits F where @@ -176,7 +176,7 @@ instance compCreatesFiniteColimits (F : C ⥤ D) (G : D ⥤ E) [CreatesFiniteCol createsFiniteColimits _ _ _ := compCreatesColimitsOfShape F G /-- Transfer creation of finite colimits along a natural isomorphism in the functor. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOfNatIso {F G : C ⥤ D} {h : F ≅ G} [CreatesFiniteColimits F] : CreatesFiniteColimits G where createsFiniteColimits _ _ _ := createsColimitsOfShapeOfNatIso h @@ -212,7 +212,7 @@ instance compCreatesFiniteCoproducts (F : C ⥤ D) (G : D ⥤ E) [CreatesFiniteC creates _ _ := compCreatesColimitsOfShape _ _ /-- Transfer creation of finite limits along a natural isomorphism in the functor. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteCoproductsOfNatIso {F G : C ⥤ D} {h : F ≅ G} [CreatesFiniteCoproducts F] : CreatesFiniteCoproducts G where creates _ _ := createsColimitsOfShapeOfNatIso h diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean b/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean index 418b03cf97fa36..04f7847409478a 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean @@ -33,7 +33,7 @@ namespace Limits /-- If `F : C ⥤ D` creates colimits of `K.leftOp : Jᵒᵖ ⥤ C`, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ D) [CreatesColimit K.leftOp F] : CreatesLimit K F.op where __ := reflectsLimit_op _ _ @@ -44,7 +44,7 @@ def createsLimitOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ D) [CreatesColimit K.leftOp F] /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F : C ⥤ D` creates limits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfOp (K : J ⥤ C) (F : C ⥤ D) [CreatesColimit K.op F.op] : CreatesLimit K F where __ := reflectsLimit_of_op _ _ @@ -55,7 +55,7 @@ def createsLimitOfOp (K : J ⥤ C) (F : C ⥤ D) [CreatesColimit K.op F.op] : /-- If `F : C ⥤ Dᵒᵖ` creates colimits of `K.leftOp : Jᵒᵖ ⥤ C`, then `F.leftOp : Cᵒᵖ ⥤ D` creates limits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitLeftOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ Dᵒᵖ) [CreatesColimit K.leftOp F] : CreatesLimit K F.leftOp where __ := reflectsLimit_leftOp _ _ @@ -66,7 +66,7 @@ def createsLimitLeftOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ Dᵒᵖ) [CreatesColimit K /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates colimits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F : C ⥤ Dᵒᵖ` creates limits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfLeftOp (K : J ⥤ C) (F : C ⥤ Dᵒᵖ) [CreatesColimit K.op F.leftOp] : CreatesLimit K F where __ := reflectsLimit_of_leftOp _ _ @@ -78,7 +78,7 @@ def createsLimitOfLeftOp (K : J ⥤ C) (F : C ⥤ Dᵒᵖ) [CreatesColimit K.op /-- If `F : Cᵒᵖ ⥤ D` creates colimits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F.rightOp : C ⥤ Dᵒᵖ` creates limits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitRightOp (K : J ⥤ C) (F : Cᵒᵖ ⥤ D) [CreatesColimit K.op F] : CreatesLimit K F.rightOp where __ := reflectsLimit_rightOp _ _ @@ -90,7 +90,7 @@ def createsLimitRightOp (K : J ⥤ C) (F : Cᵒᵖ ⥤ D) [CreatesColimit K.op F /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates colimits of `K.leftOp : Jᵒᵖ ⥤ Cᵒᵖ`, then `F : Cᵒᵖ ⥤ D` creates limits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfRightOp (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ D) [CreatesColimit K.leftOp F.rightOp] : CreatesLimit K F where __ := reflectsLimit_of_rightOp _ _ @@ -101,7 +101,7 @@ def createsLimitOfRightOp (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ D) [CreatesColimi /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F.unop : C ⥤ D` creates limits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitUnop (K : J ⥤ C) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimit K.op F] : CreatesLimit K F.unop where __ := reflectsLimit_unop _ _ @@ -112,7 +112,7 @@ def createsLimitUnop (K : J ⥤ C) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimit K.o /-- If `F.unop : C ⥤ D` creates colimits of `K.leftOp : Jᵒᵖ ⥤ C`, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitOfUnop (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimit K.leftOp F.unop] : CreatesLimit K F where __ := reflectsLimit_of_unop _ _ @@ -124,7 +124,7 @@ def createsLimitOfUnop (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesCol /-- If `F : C ⥤ D` creates limits of `K.leftOp : Jᵒᵖ ⥤ C`, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ D) [CreatesLimit K.leftOp F] : CreatesColimit K F.op where __ := reflectsColimit_op _ _ @@ -136,7 +136,7 @@ def createsColimitOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ D) [CreatesLimit K.leftOp F] /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F : C ⥤ D` creates colimits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfOp (K : J ⥤ C) (F : C ⥤ D) [CreatesLimit K.op F.op] : CreatesColimit K F where __ := reflectsColimit_of_op _ _ @@ -147,7 +147,7 @@ def createsColimitOfOp (K : J ⥤ C) (F : C ⥤ D) [CreatesLimit K.op F.op] : /-- If `F : C ⥤ Dᵒᵖ` creates limits of `K.leftOp : Jᵒᵖ ⥤ C`, then `F.leftOp : Cᵒᵖ ⥤ D` creates colimits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitLeftOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ Dᵒᵖ) [CreatesLimit K.leftOp F] : CreatesColimit K F.leftOp where __ := reflectsColimit_leftOp _ _ @@ -158,7 +158,7 @@ def createsColimitLeftOp (K : J ⥤ Cᵒᵖ) (F : C ⥤ Dᵒᵖ) [CreatesLimit K /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates limits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F : C ⥤ Dᵒᵖ` creates colimits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfLeftOp (K : J ⥤ C) (F : C ⥤ Dᵒᵖ) [CreatesLimit K.op F.leftOp] : CreatesColimit K F where __ := reflectsColimit_of_leftOp _ _ @@ -170,7 +170,7 @@ def createsColimitOfLeftOp (K : J ⥤ C) (F : C ⥤ Dᵒᵖ) [CreatesLimit K.op /-- If `F : Cᵒᵖ ⥤ D` creates limits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F.rightOp : C ⥤ Dᵒᵖ` creates colimits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitRightOp (K : J ⥤ C) (F : Cᵒᵖ ⥤ D) [CreatesLimit K.op F] : CreatesColimit K F.rightOp where __ := reflectsColimit_rightOp _ _ @@ -182,7 +182,7 @@ def createsColimitRightOp (K : J ⥤ C) (F : Cᵒᵖ ⥤ D) [CreatesLimit K.op F /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates limits of `K.leftOp : Jᵒᵖ ⥤ Cᵒᵖ`, then `F : Cᵒᵖ ⥤ D` creates colimits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfRightOp (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ D) [CreatesLimit K.leftOp F.rightOp] : CreatesColimit K F where __ := reflectsColimit_of_rightOp _ _ @@ -193,7 +193,7 @@ def createsColimitOfRightOp (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ D) [CreatesLimi /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of `K.op : Jᵒᵖ ⥤ Cᵒᵖ`, then `F.unop : C ⥤ D` creates colimits of `K : J ⥤ C`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitUnop (K : J ⥤ C) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimit K.op F] : CreatesColimit K F.unop where __ := reflectsColimit_unop _ _ @@ -204,7 +204,7 @@ def createsColimitUnop (K : J ⥤ C) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimit K.o /-- If `F.unop : C ⥤ D` creates limits of `K.op : Jᵒᵖ ⥤ C`, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of `K : J ⥤ Cᵒᵖ`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfUnop (K : J ⥤ Cᵒᵖ) (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimit K.leftOp F.unop] : CreatesColimit K F where __ := reflectsColimit_of_unop _ _ @@ -220,194 +220,194 @@ variable (J) /-- If `F : C ⥤ D` creates colimits of shape `Jᵒᵖ`, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOp (F : C ⥤ D) [CreatesColimitsOfShape Jᵒᵖ F] : CreatesLimitsOfShape J F.op where CreatesLimit {K} := createsLimitOp K F /-- If `F : C ⥤ Dᵒᵖ` creates colimits of shape `Jᵒᵖ`, then `F.leftOp : Cᵒᵖ ⥤ D` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeLeftOp (F : C ⥤ Dᵒᵖ) [CreatesColimitsOfShape Jᵒᵖ F] : CreatesLimitsOfShape J F.leftOp where CreatesLimit {K} := createsLimitLeftOp K F /-- If `F : Cᵒᵖ ⥤ D` creates colimits of shape `Jᵒᵖ`, then `F.rightOp : C ⥤ Dᵒᵖ` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeRightOp (F : Cᵒᵖ ⥤ D) [CreatesColimitsOfShape Jᵒᵖ F] : CreatesLimitsOfShape J F.rightOp where CreatesLimit {K} := createsLimitRightOp K F /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of shape `Jᵒᵖ`, then `F.unop : C ⥤ D` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimitsOfShape Jᵒᵖ F] : CreatesLimitsOfShape J F.unop where CreatesLimit {K} := createsLimitUnop K F /-- If `F : C ⥤ D` creates limits of shape `Jᵒᵖ`, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOp (F : C ⥤ D) [CreatesLimitsOfShape Jᵒᵖ F] : CreatesColimitsOfShape J F.op where CreatesColimit {K} := createsColimitOp K F /-- If `F : C ⥤ Dᵒᵖ` creates limits of shape `Jᵒᵖ`, then `F.leftOp : Cᵒᵖ ⥤ D` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeLeftOp (F : C ⥤ Dᵒᵖ) [CreatesLimitsOfShape Jᵒᵖ F] : CreatesColimitsOfShape J F.leftOp where CreatesColimit {K} := createsColimitLeftOp K F /-- If `F : Cᵒᵖ ⥤ D` creates limits of shape `Jᵒᵖ`, then `F.rightOp : C ⥤ Dᵒᵖ` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeRightOp (F : Cᵒᵖ ⥤ D) [CreatesLimitsOfShape Jᵒᵖ F] : CreatesColimitsOfShape J F.rightOp where CreatesColimit {K} := createsColimitRightOp K F /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of shape `Jᵒᵖ`, then `F.unop : C ⥤ D` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimitsOfShape Jᵒᵖ F] : CreatesColimitsOfShape J F.unop where CreatesColimit {K} := createsColimitUnop K F /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of shape `Jᵒᵖ`, then `F : C ⥤ D` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfOp (F : C ⥤ D) [CreatesColimitsOfShape Jᵒᵖ F.op] : CreatesLimitsOfShape J F where CreatesLimit {K} := createsLimitOfOp K F /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates colimits of shape `Jᵒᵖ`, then `F : C ⥤ Dᵒᵖ` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfLeftOp (F : C ⥤ Dᵒᵖ) [CreatesColimitsOfShape Jᵒᵖ F.leftOp] : CreatesLimitsOfShape J F where CreatesLimit {K} := createsLimitOfLeftOp K F /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates colimits of shape `Jᵒᵖ`, then `F : Cᵒᵖ ⥤ D` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfRightOp (F : Cᵒᵖ ⥤ D) [CreatesColimitsOfShape Jᵒᵖ F.rightOp] : CreatesLimitsOfShape J F where CreatesLimit {K} := createsLimitOfRightOp K F /-- If `F.unop : C ⥤ D` creates colimits of shape `Jᵒᵖ`, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfShapeOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimitsOfShape Jᵒᵖ F.unop] : CreatesLimitsOfShape J F where CreatesLimit {K} := createsLimitOfUnop K F /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates limits of shape `Jᵒᵖ`, then `F : C ⥤ D` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfOp (F : C ⥤ D) [CreatesLimitsOfShape Jᵒᵖ F.op] : CreatesColimitsOfShape J F where CreatesColimit {K} := createsColimitOfOp K F /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates limits of shape `Jᵒᵖ`, then `F : C ⥤ Dᵒᵖ` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfLeftOp (F : C ⥤ Dᵒᵖ) [CreatesLimitsOfShape Jᵒᵖ F.leftOp] : CreatesColimitsOfShape J F where CreatesColimit {K} := createsColimitOfLeftOp K F /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates limits of shape `Jᵒᵖ`, then `F : Cᵒᵖ ⥤ D` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfRightOp (F : Cᵒᵖ ⥤ D) [CreatesLimitsOfShape Jᵒᵖ F.rightOp] : CreatesColimitsOfShape J F where CreatesColimit {K} := createsColimitOfRightOp K F /-- If `F.unop : C ⥤ D` creates limits of shape `Jᵒᵖ`, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits of shape `J`. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfShapeOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimitsOfShape Jᵒᵖ F.unop] : CreatesColimitsOfShape J F where CreatesColimit {K} := createsColimitOfUnop K F end /-- If `F : C ⥤ D` creates colimits, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeOp (F : C ⥤ D) [CreatesColimitsOfSize.{w, w'} F] : CreatesLimitsOfSize.{w, w'} F.op where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeOp _ _ /-- If `F : C ⥤ Dᵒᵖ` creates colimits, then `F.leftOp : Cᵒᵖ ⥤ D` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeLeftOp (F : C ⥤ Dᵒᵖ) [CreatesColimitsOfSize.{w, w'} F] : CreatesLimitsOfSize.{w, w'} F.leftOp where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeLeftOp _ _ /-- If `F : Cᵒᵖ ⥤ D` creates colimits, then `F.rightOp : C ⥤ Dᵒᵖ` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeRightOp (F : Cᵒᵖ ⥤ D) [CreatesColimitsOfSize.{w, w'} F] : CreatesLimitsOfSize.{w, w'} F.rightOp where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeRightOp _ _ /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits, then `F.unop : C ⥤ D` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimitsOfSize.{w, w'} F] : CreatesLimitsOfSize.{w, w'} F.unop where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeUnop _ _ /-- If `F : C ⥤ D` creates limits, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeOp (F : C ⥤ D) [CreatesLimitsOfSize.{w, w'} F] : CreatesColimitsOfSize.{w, w'} F.op where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeOp _ _ /-- If `F : C ⥤ Dᵒᵖ` creates limits, then `F.leftOp : Cᵒᵖ ⥤ D` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeLeftOp (F : C ⥤ Dᵒᵖ) [CreatesLimitsOfSize.{w, w'} F] : CreatesColimitsOfSize.{w, w'} F.leftOp where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeLeftOp _ _ /-- If `F : Cᵒᵖ ⥤ D` creates limits, then `F.rightOp : C ⥤ Dᵒᵖ` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeRightOp (F : Cᵒᵖ ⥤ D) [CreatesLimitsOfSize.{w, w'} F] : CreatesColimitsOfSize.{w, w'} F.rightOp where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeRightOp _ _ /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates limits, then `F.unop : C ⥤ D` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimitsOfSize.{w, w'} F] : CreatesColimitsOfSize.{w, w'} F.unop where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeUnop _ _ /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits, then `F : C ⥤ D` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeOfOp (F : C ⥤ D) [CreatesColimitsOfSize.{w, w'} F.op] : CreatesLimitsOfSize.{w, w'} F where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeOfOp _ _ /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates colimits, then `F : C ⥤ Dᵒᵖ` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeOfLeftOp (F : C ⥤ Dᵒᵖ) [CreatesColimitsOfSize.{w, w'} F.leftOp] : CreatesLimitsOfSize.{w, w'} F where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeOfLeftOp _ _ /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates colimits, then `F : Cᵒᵖ ⥤ D` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeOfRightOp (F : Cᵒᵖ ⥤ D) [CreatesColimitsOfSize.{w, w'} F.rightOp] : CreatesLimitsOfSize.{w, w'} F where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeOfRightOp _ _ /-- If `F.unop : C ⥤ D` creates colimits, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsLimitsOfSizeOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesColimitsOfSize.{w, w'} F.unop] : CreatesLimitsOfSize.{w, w'} F where CreatesLimitsOfShape {_} _ := createsLimitsOfShapeOfUnop _ _ /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates limits, then `F : C ⥤ D` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeOfOp (F : C ⥤ D) [CreatesLimitsOfSize.{w, w'} F.op] : CreatesColimitsOfSize.{w, w'} F where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeOfOp _ _ /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates limits, then `F : C ⥤ Dᵒᵖ` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeOfLeftOp (F : C ⥤ Dᵒᵖ) [CreatesLimitsOfSize.{w, w'} F.leftOp] : CreatesColimitsOfSize.{w, w'} F where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeOfLeftOp _ _ /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates limits, then `F : Cᵒᵖ ⥤ D` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeOfRightOp (F : Cᵒᵖ ⥤ D) [CreatesLimitsOfSize.{w, w'} F.rightOp] : CreatesColimitsOfSize.{w, w'} F where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeOfRightOp _ _ /-- If `F.unop : C ⥤ D` creates limits, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitsOfSizeOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimitsOfSize.{w, w'} F.unop] : CreatesColimitsOfSize.{w, w'} F where CreatesColimitsOfShape {_} _ := createsColimitsOfShapeOfUnop _ _ @@ -478,115 +478,115 @@ abbrev createsColimitsOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesLimits F.unop] : /-- If `F : C ⥤ D` creates finite colimits, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOp (F : C ⥤ D) [CreatesFiniteColimits F] : CreatesFiniteLimits F.op where createsFiniteLimits J _ _ := createsLimitsOfShapeOp J F /-- If `F : C ⥤ Dᵒᵖ` creates finite colimits, then `F.leftOp : Cᵒᵖ ⥤ D` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteColimits F] : CreatesFiniteLimits F.leftOp where createsFiniteLimits J _ _ := createsLimitsOfShapeLeftOp J F /-- If `F : Cᵒᵖ ⥤ D` creates finite colimits, then `F.rightOp : C ⥤ Dᵒᵖ` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteColimits F] : CreatesFiniteLimits F.rightOp where createsFiniteLimits J _ _ := createsLimitsOfShapeRightOp J F /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates finite colimits, then `F.unop : C ⥤ D` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteColimits F] : CreatesFiniteLimits F.unop where createsFiniteLimits J _ _ := createsLimitsOfShapeUnop J F /-- If `F : C ⥤ D` creates finite limits, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOp (F : C ⥤ D) [CreatesFiniteLimits F] : CreatesFiniteColimits F.op where createsFiniteColimits J _ _ := createsColimitsOfShapeOp J F /-- If `F : C ⥤ Dᵒᵖ` creates finite limits, then `F.leftOp : Cᵒᵖ ⥤ D` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteLimits F] : CreatesFiniteColimits F.leftOp where createsFiniteColimits J _ _ := createsColimitsOfShapeLeftOp J F /-- If `F : Cᵒᵖ ⥤ D` creates finite limits, then `F.rightOp : C ⥤ Dᵒᵖ` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteLimits F] : CreatesFiniteColimits F.rightOp where createsFiniteColimits J _ _ := createsColimitsOfShapeRightOp J F /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates finite limits, then `F.unop : C ⥤ D` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteLimits F] : CreatesFiniteColimits F.unop where createsFiniteColimits J _ _ := createsColimitsOfShapeUnop J F /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates finite colimits, then `F : C ⥤ D` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOfOp (F : C ⥤ D) [CreatesFiniteColimits F.op] : CreatesFiniteLimits F where createsFiniteLimits J _ _ := createsLimitsOfShapeOfOp J F /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates finite colimits, then `F : C ⥤ Dᵒᵖ` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOfLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteColimits F.leftOp] : CreatesFiniteLimits F where createsFiniteLimits J _ _ := createsLimitsOfShapeOfLeftOp J F /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates finite colimits, then `F : Cᵒᵖ ⥤ D` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOfRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteColimits F.rightOp] : CreatesFiniteLimits F where createsFiniteLimits J _ _ := createsLimitsOfShapeOfRightOp J F /-- If `F.unop : C ⥤ D` creates finite colimits, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates finite limits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteLimitsOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteColimits F.unop] : CreatesFiniteLimits F where createsFiniteLimits J _ _ := createsLimitsOfShapeOfUnop J F /-- If `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates finite limits, then `F : C ⥤ D` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOfOp (F : C ⥤ D) [CreatesFiniteLimits F.op] : CreatesFiniteColimits F where createsFiniteColimits J _ _ := createsColimitsOfShapeOfOp J F /-- If `F.leftOp : Cᵒᵖ ⥤ D` creates finite limits, then `F : C ⥤ Dᵒᵖ` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOfLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteLimits F.leftOp] : CreatesFiniteColimits F where createsFiniteColimits J _ _ := createsColimitsOfShapeOfLeftOp J F /-- If `F.rightOp : C ⥤ Dᵒᵖ` creates finite limits, then `F : Cᵒᵖ ⥤ D` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOfRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteLimits F.rightOp] : CreatesFiniteColimits F where createsFiniteColimits J _ _ := createsColimitsOfShapeOfRightOp J F /-- If `F.unop : C ⥤ D` creates finite limits, then `F : Cᵒᵖ ⥤ Dᵒᵖ` creates finite colimits. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteColimitsOfUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteLimits F.unop] : CreatesFiniteColimits F where createsFiniteColimits J _ _ := createsColimitsOfShapeOfUnop J F /-- If `F : C ⥤ D` creates finite coproducts, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates finite products. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteProductsOp (F : C ⥤ D) [CreatesFiniteCoproducts F] : CreatesFiniteProducts F.op where creates _ _ := by @@ -595,7 +595,7 @@ def createsFiniteProductsOp (F : C ⥤ D) [CreatesFiniteCoproducts F] : /-- If `F : C ⥤ Dᵒᵖ` creates finite coproducts, then `F.leftOp : Cᵒᵖ ⥤ D` creates finite products. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteProductsLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteCoproducts F] : CreatesFiniteProducts F.leftOp where creates _ _ := by @@ -604,7 +604,7 @@ def createsFiniteProductsLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteCoproducts F] /-- If `F : Cᵒᵖ ⥤ D` creates finite coproducts, then `F.rightOp : C ⥤ Dᵒᵖ` creates finite products. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteProductsRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteCoproducts F] : CreatesFiniteProducts F.rightOp where creates _ _ := by @@ -613,7 +613,7 @@ def createsFiniteProductsRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteCoproducts F] /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates finite coproducts, then `F.unop : C ⥤ D` creates finite products. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteProductsUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteCoproducts F] : CreatesFiniteProducts F.unop where creates _ _ := by @@ -622,7 +622,7 @@ def createsFiniteProductsUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteCoproducts /-- If `F : C ⥤ D` creates finite products, then `F.op : Cᵒᵖ ⥤ Dᵒᵖ` creates finite coproducts. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteCoproductsOp (F : C ⥤ D) [CreatesFiniteProducts F] : CreatesFiniteCoproducts F.op where creates _ _ := by @@ -631,7 +631,7 @@ def createsFiniteCoproductsOp (F : C ⥤ D) [CreatesFiniteProducts F] : /-- If `F : C ⥤ Dᵒᵖ` creates finite products, then `F.leftOp : Cᵒᵖ ⥤ D` creates finite coproducts. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteCoproductsLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteProducts F] : CreatesFiniteCoproducts F.leftOp where creates _ _ := by @@ -640,7 +640,7 @@ def createsFiniteCoproductsLeftOp (F : C ⥤ Dᵒᵖ) [CreatesFiniteProducts F] /-- If `F : Cᵒᵖ ⥤ D` creates finite products, then `F.rightOp : C ⥤ Dᵒᵖ` creates finite coproducts. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteCoproductsRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteProducts F] : CreatesFiniteCoproducts F.rightOp where creates _ _ := by @@ -649,7 +649,7 @@ def createsFiniteCoproductsRightOp (F : Cᵒᵖ ⥤ D) [CreatesFiniteProducts F] /-- If `F : Cᵒᵖ ⥤ Dᵒᵖ` creates finite products, then `F.unop : C ⥤ D` creates finite coproducts. -/ -@[implicit_reducible] +@[instance_reducible] def createsFiniteCoproductsUnop (F : Cᵒᵖ ⥤ Dᵒᵖ) [CreatesFiniteProducts F] : CreatesFiniteCoproducts F.unop where creates _ _ := by diff --git a/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean b/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean index 359e764250e1af..3bef2a22985416 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/FunctorCategory.lean @@ -39,7 +39,7 @@ noncomputable section namespace CategoryTheory -open Category Limits Functor +open Category Limits CategoryTheory.Functor section diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean b/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean index 62183f262e47b8..eb3e4dbcdefa84 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Grothendieck.lean @@ -22,7 +22,7 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory -open Functor +open CategoryTheory.Functor namespace Limits diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Limits.lean b/Mathlib/CategoryTheory/Limits/Preserves/Limits.lean index 302e003ef3cb2b..06a814b3522412 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Limits.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Limits.lean @@ -78,7 +78,6 @@ instance : IsIso (limit.post F G) := variable [PreservesLimitsOfShape J G] [HasLimitsOfShape J D] [HasLimitsOfShape J C] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- If `C, D` has all limits of shape `J`, and `G` preserves them, then `preservesLimitsIso` is functorial w.r.t. `F`. -/ @[simps!] @@ -149,7 +148,6 @@ instance : IsIso (colimit.post F G) := variable [PreservesColimitsOfShape J G] [HasColimitsOfShape J D] [HasColimitsOfShape J C] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- If `C, D` has all colimits of shape `J`, and `G` preserves them, then `preservesColimitIso` is functorial w.r.t. `F`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Over.lean b/Mathlib/CategoryTheory/Limits/Preserves/Over.lean index 824f27713a9e47..58dbcbc92298e0 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Over.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Over.lean @@ -24,6 +24,7 @@ variable {C : Type*} [Category* C] attribute [local instance] IsFiltered.nonempty IsCofiltered.nonempty +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {X : C} : PreservesCofilteredLimitsOfSize (Over.forget X) := by refine ⟨fun J hJ hJ' ↦ ⟨fun {F} ↦ ⟨fun {c} hc ↦ ⟨.ofExistsUnique fun s ↦ ?_⟩⟩⟩⟩ @@ -38,6 +39,7 @@ instance {X : C} : PreservesCofilteredLimitsOfSize (Over.forget X) := by exact congr($(hc.uniq s' (Over.homMk f (by simp [s', ← hf])) fun j ↦ Over.OverMorphism.ext (hf j)).left) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {X : C} : PreservesFilteredColimitsOfSize (Under.forget X) := by refine ⟨fun J hJ hJ' ↦ ⟨fun {F} ↦ ⟨fun {c} hc ↦ ⟨.ofExistsUnique fun s ↦ ?_⟩⟩⟩⟩ diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Presheaf.lean b/Mathlib/CategoryTheory/Limits/Preserves/Presheaf.lean index 8a346a9ab9ef04..bed2f053f6c963 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Presheaf.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Presheaf.lean @@ -86,6 +86,9 @@ def functorToInterchangeIso : functorToInterchange A K ≅ K ⋙ coyoneda ⋙ (whiskeringLeft _ _ _).obj (CostructuredArrow.proj _ _) := Iso.refl _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- (Implementation) One way to express the flipped version of our functor. We choose this association because the type of `Presheaf.tautologicalCocone` is `Cocone (CostructuredArrow.proj yoneda P ⋙ yoneda)`, so this association will show up in the diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/BinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/BinaryProducts.lean index de09cda06c9444..43c2555108a207 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/BinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/BinaryProducts.lean @@ -37,6 +37,7 @@ section variable {P X Y Z : C} (f : P ⟶ X) (g : P ⟶ Y) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a binary fan is a limit iff the fork consisting of the mapped morphisms is a limit. This @@ -131,6 +132,7 @@ section variable {P X Y Z : C} (f : X ⟶ P) (g : Y ⟶ P) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a binary cofan is a colimit iff the cofork consisting of the mapped morphisms is a colimit. diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean index 648b8b55d7e5d8..9493a0f1f150a3 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Biproducts.lean @@ -167,6 +167,7 @@ class PreservesBinaryBiproducts (F : C ⥤ D) [PreservesZeroMorphisms F] : Prop attribute [inherit_doc PreservesBinaryBiproducts] PreservesBinaryBiproducts.preserves +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor that preserves biproducts of a pair preserves binary biproducts. -/ lemma preservesBinaryBiproduct_of_preservesBiproduct (F : C ⥤ D) diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean index a4e859af2ebd2e..9c06a84724fe6b 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Equalizers.lean @@ -38,6 +38,7 @@ section Equalizers variable {X Y Z : C} {f g : X ⟶ Y} {h : Z ⟶ X} (w : h ≫ f = h ≫ g) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a fork is a limit iff the fork consisting of the mapped morphisms is a limit. This essentially lets us commute `Fork.ofι` with `Functor.mapCone`. @@ -114,6 +115,7 @@ section Coequalizers variable {X Y Z : C} {f g : X ⟶ Y} {h : Y ⟶ Z} (w : f ≫ h = g ≫ h) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a cofork is a colimit iff the cofork consisting of the mapped morphisms is a colimit. This essentially lets us commute `Cofork.ofπ` with `Functor.mapCocone`. diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean index ef1f44c142b9dd..75b13392e5de1a 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean @@ -304,6 +304,7 @@ instance preservesKernel_zero : refine IsLimit.ofIsoLimit (KernelFork.IsLimit.ofId _ (G.map_zero _ _)) ?_ exact (Fork.ext (G.mapIso (asIso (Fork.ι c))).symm (by simp))⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in noncomputable instance preservesCokernel_zero : PreservesColimit (parallelPair (0 : X ⟶ Y) 0) G where @@ -333,6 +334,7 @@ variable [HasZeroObject C] [HasZeroObject D] variable {X Y : C} (f : X ⟶ Y) +set_option backward.isDefEq.respectTransparency.types false in /-- Mapping a `zeroKernelFork` of `f : X ⟶ Y` along a functor `G` that preserves zero morphisms is isomorphic to the `zeroKernelFork` of `G.map f`. -/ def mapZeroKernelFork : diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Multiequalizer.lean index 917fe90b332fd1..32bf5b80085a2b 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Multiequalizer.lean @@ -67,6 +67,7 @@ def Multifork.map : Multifork (d.map F) := dsimp rw [← F.map_comp, ← F.map_comp, condition]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `d : MulticospanIndex J C`, `c : Multifork d` and `F : C ⥤ D`, the cone `F.mapCone c` is limiting iff the multifork `c.map F` is. -/ @@ -120,6 +121,7 @@ def Multicofork.map : Multicofork (d.map F) := dsimp rw [← F.map_comp, ← F.map_comp, condition]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `d : MultispanIndex J C`, `c : Multicofork d` and `F : C ⥤ D`, the cocone `F.mapCocone c` is colimit iff the multicofork `c.map F` is. -/ diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Over.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Over.lean index f198d3f479106d..d6896c7d9c75e5 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Over.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Over.lean @@ -35,6 +35,7 @@ instance PreservesLimitsOfShape.ofWidePullbacks {J : Type*} PreservesLimitsOfShape (WithTerminal <| Discrete J) F := preservesLimitsOfShape_of_equiv WithTerminal.widePullbackShapeEquiv F +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open WithTerminal in instance PreservesLimitsOfShape.overPost [PreservesLimitsOfShape (WithTerminal J) F] : @@ -51,6 +52,7 @@ instance PreservesFiniteLimits.overPost [PreservesFiniteLimits F] : instance PreservesLimitsOfSize.overPost [PreservesLimitsOfSize.{w', w} F] : PreservesLimitsOfSize.{w', w} (Over.post F (X := X)) where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open WithInitial in instance PreservesColimitsOfShape.underPost [PreservesColimitsOfShape (WithInitial J) F] : diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Products.lean index 21d4b9c830d66e..b82cb3b18b5a96 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Products.lean @@ -35,6 +35,7 @@ namespace CategoryTheory.Limits variable {J : Type w} (f : J → C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a fan is a limit iff the fan consisting of the mapped morphisms is a limit. This essentially lets us commute `Fan.mk` with `Functor.mapCone`. @@ -110,6 +111,7 @@ instance {I : Type*} [Category* I] [IsGroupoid I] (F : C ⥤ D) [PreservesLimits end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a cofan is a colimit iff the cofan consisting of the mapped morphisms is a colimit. This essentially lets us commute `Cofan.mk` with `Functor.mapCocone`. diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean index db670cce839bd2..6d106c1119e8f5 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Pullbacks.lean @@ -52,6 +52,7 @@ abbrev map : PullbackCone (G.map f) (G.map g) := PullbackCone.mk (G.map c.fst) (G.map c.snd) (by simpa using G.congr_map c.condition) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map (as a cone) of a pullback cone is limit iff the map (as a pullback cone) is limit. -/ @@ -180,6 +181,7 @@ variable {W X Y : C} {f : W ⟶ X} {g : W ⟶ Y} (c : PushoutCocone f g) (G : C abbrev map : PushoutCocone (G.map f) (G.map g) := PushoutCocone.mk (G.map c.inl) (G.map c.inr) (by simpa using G.congr_map c.condition) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map (as a cocone) of a pushout cocone is colimit iff the map (as a pushout cocone) is limit. -/ @@ -198,6 +200,7 @@ end PushoutCocone variable (G : C ⥤ D) variable {W X Y Z : C} {h : X ⟶ Z} {k : Y ⟶ Z} {f : W ⟶ X} {g : W ⟶ Y} (comm : f ≫ h = g ≫ k) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The map of a pushout cocone is a colimit iff the cofork consisting of the mapped morphisms is a colimit. This essentially lets us commute `PushoutCocone.mk` with `Functor.mapCocone`. -/ @@ -333,7 +336,9 @@ instance : IsIso (pushoutComparison G f g) := by rw [← PreservesPushout.iso_hom] infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- A pushout cocone in `C` is colimit iff it becomes limit after the application of `yoneda.obj X` for all `X : C`. -/ def PushoutCocone.isColimitYonedaEquiv (c : PushoutCocone f g) : diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Square.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Square.lean index 936ca34053ffae..3884edcc451d55 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Square.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Square.lean @@ -91,6 +91,7 @@ variable {sq₁ : Square (Type v)} {sq₂ : Square (Type u)} (comm₃₄ : e₄ ∘ sq₁.f₃₄ = sq₂.f₃₄ ∘ e₃) include comm₁₂ comm₁₃ comm₂₄ comm₃₄ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (sq₁ sq₂) in lemma IsPullback.iff_of_equiv : sq₁.IsPullback ↔ sq₂.IsPullback := by diff --git a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean index 43d27f6f02903d..2a327c9b543094 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean @@ -67,14 +67,14 @@ variable {α β : Type*} (f : α → β) open scoped Classical in /-- A colimit cokernel cofork for the map `∐ fun (_ : α) ↦ R ⟶ ∐ fun (_ : β) ↦ R` induced by a map `f : α → β`. -/ -@[simps! pt] +@[simps! pt, implicit_reducible] noncomputable def sigmaConstCokernelCofork : CokernelCofork (Sigma.map' (f := fun (_ : α) ↦ R) (g := fun (_ : β) ↦ R) f (fun _ ↦ 𝟙 R)) := CokernelCofork.ofπ (Z := ∐ fun (_ : ((Set.range f)ᶜ : Set _)) ↦ R) (Sigma.desc (fun b ↦ if hb : b ∈ (Set.range f)ᶜ then Sigma.ι (fun _ ↦ R) ⟨b, hb⟩ else 0)) - (by ext; simp [Sigma.ι_desc]) + (by ext; simp) set_option backward.defeqAttrib.useBackward true in @[reassoc] diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Yoneda.lean b/Mathlib/CategoryTheory/Limits/Preserves/Yoneda.lean index 8d81e477ad00a5..ac357d66adfcd7 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Yoneda.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Yoneda.lean @@ -35,7 +35,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open CategoryTheory.Limits Opposite Functor +open CategoryTheory.Limits Opposite CategoryTheory.Functor variable {C : Type u₁} [Category.{v₁} C] diff --git a/Mathlib/CategoryTheory/Limits/Presheaf.lean b/Mathlib/CategoryTheory/Limits/Presheaf.lean index f833f6546eea73..633837c26d94b1 100644 --- a/Mathlib/CategoryTheory/Limits/Presheaf.lean +++ b/Mathlib/CategoryTheory/Limits/Presheaf.lean @@ -195,6 +195,7 @@ noncomputable def uliftYonedaAdjunction : L ⊣ restrictedULiftYoneda.{max w v simp [restrictedULiftYonedaHomEquiv, restrictedULiftYonedaHomEquiv'_symm_naturality_right, this] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma uliftYonedaAdjunction_homEquiv_app {P : Cᵒᵖ ⥤ Type max w v₁ v₂} @@ -204,8 +205,8 @@ lemma uliftYonedaAdjunction_homEquiv_app {P : Cᵒᵖ ⥤ Type max w v₁ v₂} simp [uliftYonedaAdjunction, restrictedULiftYonedaHomEquiv, restrictedULiftYonedaHomEquiv', IsColimit.homEquiv] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] lemma uliftYonedaAdjunction_unit_app_app (P : Cᵒᵖ ⥤ Type max w v₁ v₂) {Z : Cᵒᵖ} (z : P.obj Z) : @@ -331,6 +332,7 @@ variable (L : (Cᵒᵖ ⥤ Type max w v₁ v₂) ⥤ ℰ) (α : A ⟶ uliftYoned instance [L.IsLeftKanExtension α] : IsIso α := (Functor.isPointwiseLeftKanExtensionOfIsLeftKanExtension L α).isIso_hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isLeftKanExtension_along_uliftYoneda_iff : L.IsLeftKanExtension α ↔ @@ -576,7 +578,6 @@ noncomputable def natTrans : F.op.lan ⟶ G where rw [Functor.descOfIsLeftKanExtension_fac_assoc, ← reassoc_of% eq, Functor.descOfIsLeftKanExtension_fac, presheafHom_naturality] -set_option backward.isDefEq.respectTransparency false in lemma natTrans_app_uliftYoneda_obj (X : C) : (natTrans.{w} φ).app (uliftYoneda.{max w v₂}.obj X) = (compULiftYonedaIsoULiftYonedaCompLan.{w} F).inv.app X ≫ φ.app X := by @@ -592,7 +593,6 @@ end variable [∀ (P : Cᵒᵖ ⥤ Type max w v₁ v₂), F.op.HasLeftKanExtension P] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given a functor `F : C ⥤ D`, this definition is part of the verification that `Functor.LeftExtension.mk F.op.lan (compULiftYonedaIsoULiftYonedaCompLan F).hom` is universal, i.e. that `F.op.lan : (Cᵒᵖ ⥤ Type max w v₁ v₂) ⥤ Dᵒᵖ ⥤ Type max w v₁ v₂` @@ -648,6 +648,7 @@ instance : F.op.lan.IsLeftKanExtension (compULiftYonedaIsoULiftYonedaCompLan.{w} end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a presheaf `P`, consider the forgetful functor from the category of representable presheaves over `P` to the category of presheaves. There is a tautological cocone over this @@ -672,6 +673,7 @@ def isColimitTautologicalCocone' (P : Cᵒᵖ ⥤ Type max w v₁) : (colimitOfRepresentable.{w} P) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- For a presheaf `P`, consider the forgetful functor from the category of representable presheaves over `P` to the category of presheaves. There is a tautological cocone over this diff --git a/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean index 826fb2246a1b91..4f994d6b66d739 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean @@ -141,6 +141,7 @@ def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) where winl := by simp [-BinaryBiconeMorphism.winl, ← f.winl] winr := by simp [-BinaryBiconeMorphism.winr, ← f.winr] } +set_option backward.isDefEq.respectTransparency.types false in instance functoriality_full [F.Full] [F.Faithful] : (functoriality P Q F).Full where map_surjective t := ⟨{ hom := F.preimage t.hom @@ -298,6 +299,7 @@ def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone abbrev toBinaryBicone {X Y : C} (b : Bicone (pairFunction X Y)) : BinaryBicone X Y := toBinaryBiconeFunctor.obj b +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A bicone over a pair is a limit cone if and only if the corresponding binary bicone is a limit cone. -/ @@ -305,6 +307,7 @@ def toBinaryBiconeIsLimit {X Y : C} (b : Bicone (pairFunction X Y)) : IsLimit b.toBinaryBicone.toCone ≃ IsLimit b.toCone := IsLimit.equivIsoLimit <| Cone.ext (Iso.refl _) fun j => by rcases j with ⟨⟨⟩⟩ <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A bicone over a pair is a colimit cocone if and only if the corresponding binary bicone is a colimit cocone. -/ @@ -322,6 +325,7 @@ structure BinaryBicone.IsBilimit {P Q : C} (b : BinaryBicone P Q) where attribute [inherit_doc BinaryBicone.IsBilimit] BinaryBicone.IsBilimit.isLimit BinaryBicone.IsBilimit.isColimit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If a binary bicone for `P` and `Q` is bilimit, then the binary bicone for `P'` and `Q'` obtained using isomorphisms `P ≅ P'` and `Q ≅ Q'` is also bilimit. -/ @@ -722,6 +726,7 @@ theorem biprod.conePointUniqueUpToIso_inv (X Y : C) [HasBinaryBiproduct X Y] {b rcases j with ⟨⟨⟩⟩ all_goals simp +set_option backward.isDefEq.respectTransparency.types false in /-- Binary biproducts are unique up to isomorphism. This already follows because bilimits are limits, but in the case of biproducts we can give an isomorphism with particularly nice definitional properties, namely that `biprod.lift b.fst b.snd` and `biprod.desc b.inl b.inr` @@ -906,6 +911,7 @@ section variable (P Q) [HasBinaryBiproduct P Q] +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism `op (P ⊞ Q) ≅ op P ⊞ op Q`. -/ def biprod.opIso : op (P ⊞ Q) ≅ op P ⊞ op Q := biprod.uniqueUpToIso _ _ (getBinaryBiproductData P Q).op.isBilimit diff --git a/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean index 7db0c83b454432..66cabc2b31f1de 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean @@ -289,7 +289,7 @@ attribute [local aesop safe cases (rule_sets := [CategoryTheory])] Eq set_option backward.defeqAttrib.useBackward true in /-- A binary fan with vertex `P` consists of the two projections `π₁ : P ⟶ X` and `π₂ : P ⟶ Y`. -/ -@[simps pt] +@[simps pt, implicit_reducible] def BinaryFan.mk {P : C} (π₁ : P ⟶ X) (π₂ : P ⟶ Y) : BinaryFan X Y where pt := P π := { app := fun | { as := j } => match j with | left => π₁ | right => π₂ } @@ -319,11 +319,13 @@ theorem BinaryCofan.mk_inl {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : (Binary theorem BinaryCofan.mk_inr {P : C} (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : (BinaryCofan.mk ι₁ ι₂).inr = ι₂ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/ def isoBinaryFanMk {X Y : C} (c : BinaryFan X Y) : c ≅ BinaryFan.mk c.fst c.snd := Cone.ext (Iso.refl _) fun ⟨l⟩ => by cases l; repeat simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Every `BinaryFan` is isomorphic to an application of `BinaryFan.mk`. -/ def isoBinaryCofanMk {X Y : C} (c : BinaryCofan X Y) : c ≅ BinaryCofan.mk c.inl c.inr := @@ -556,6 +558,7 @@ noncomputable abbrev coprod.inl {X Y : C} [HasBinaryCoproduct X Y] : X ⟶ X ⨿ noncomputable abbrev coprod.inr {X Y : C} [HasBinaryCoproduct X Y] : Y ⟶ X ⨿ Y := colimit.ι (pair X Y) ⟨WalkingPair.right⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The binary fan constructed from the projection maps is a limit. -/ noncomputable def prodIsProd (X Y : C) [HasBinaryProduct X Y] : @@ -566,6 +569,7 @@ noncomputable def prodIsProd (X Y : C) [HasBinaryProduct X Y] : · simp [Category.id_comp] )) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The binary cofan constructed from the coprojection maps is a colimit. -/ noncomputable def coprodIsCoprod (X Y : C) [HasBinaryCoproduct X Y] : @@ -1144,6 +1148,7 @@ lemma BinaryCofan.map_inl {X Y : C} (s : BinaryCofan X Y) : (s.map F).inl = F.ma @[simp] lemma BinaryCofan.map_inr {X Y : C} (s : BinaryCofan X Y) : (s.map F).inr = F.map s.inr := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `F.mapCone s` being limiting is the same as the induced binary fan being limiting. -/ def BinaryFan.isLimitMapConeEquiv {X Y : C} {s : BinaryFan X Y} : @@ -1151,6 +1156,7 @@ def BinaryFan.isLimitMapConeEquiv {X Y : C} {s : BinaryFan X Y} : IsLimit.equivOfNatIsoOfIso (diagramIsoPair _) _ _ <| ext (Iso.refl _) (by simp [fst]) (by simp [snd]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `F.mapCocone s` being colimiting is the same as the induced binary cofan being colimiting. -/ def BinaryCofan.isColimitMapConeEquiv {X Y : C} {s : BinaryCofan X Y} : @@ -1339,6 +1345,7 @@ namespace CategoryTheory variable {C : Type u} [Category.{v} C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `Over.coprod`. -/ @[simps] @@ -1348,6 +1355,7 @@ noncomputable def Over.coprodObj [HasBinaryCoproducts C] {A : C} : { obj := fun g => Over.mk (coprod.desc f.hom g.hom) map := fun k => Over.homMk (coprod.map (𝟙 _) k.left) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A category with binary coproducts has a functorial `sup` operation on over categories. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 86513d565ea1a3..a8a145aa2c543e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -141,6 +141,7 @@ def functoriality (G : C ⥤ D) [Functor.PreservesZeroMorphisms G] : variable (G : C ⥤ D) +set_option backward.isDefEq.respectTransparency.types false in instance functoriality_full [G.PreservesZeroMorphisms] [G.Full] [G.Faithful] : (functoriality F G).Full where map_surjective t := @@ -274,6 +275,7 @@ def whisker {f : J → C} (c : Bicone f) (g : K ≃ J) : Bicone (f ∘ g) where simp only [c.ι_π] split_ifs with h h' h' <;> simp [Equiv.apply_eq_iff_eq g] at h h' <;> tauto +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Taking the cone of a whiskered bicone results in a cone isomorphic to one gained by whiskering the cone and postcomposing with a suitable isomorphism. -/ @@ -283,6 +285,7 @@ def whiskerToCone {f : J → C} (c : Bicone f) (g : K ≃ J) : (c.toCone.whisker (Discrete.functor (Discrete.mk ∘ g))) := Cone.ext (Iso.refl _) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Taking the cocone of a whiskered bicone results in a cone isomorphic to one gained by whiskering the cocone and precomposing with a suitable isomorphism. -/ @@ -690,6 +693,7 @@ lemma biproduct.whiskerEquiv_inv_eq_lift {f : J → C} {g : K → C} (e : J ≃ · rintro rfl simp at h +set_option backward.isDefEq.respectTransparency.types false in attribute [local simp] Sigma.forall in instance {ι} (f : ι → Type*) (g : (i : ι) → (f i) → C) [∀ i, HasBiproduct (g i)] [HasBiproduct fun i => ⨁ g i] : @@ -1043,6 +1047,7 @@ theorem biproduct.conePointUniqueUpToIso_inv (f : J → C) [HasBiproduct f] {b : rw [Category.assoc, IsLimit.conePointUniqueUpToIso_inv_comp, Bicone.toCone_π_app, biproduct.bicone_π, biproduct.ι_desc, biproduct.ι_π, b.toCone_π_app, b.ι_π] +set_option backward.isDefEq.respectTransparency.types false in /-- Biproducts are unique up to isomorphism. This already follows because bilimits are limits, but in the case of biproducts we can give an isomorphism with particularly nice definitional properties, namely that `biproduct.lift b.π` and `biproduct.desc b.ι` are inverses of each diff --git a/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean b/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean index f540463ca772bf..8e73dfee39fa9e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean @@ -102,7 +102,7 @@ variable [ConcreteCategory.{w} C FC] /-- If `forget C` preserves terminals and `X` is terminal, then `ToType X` is a singleton. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def uniqueOfTerminalOfPreserves [PreservesLimit (Functor.empty.{0} C) (forget C)] (X : C) (h : IsTerminal X) : Unique (ToType X) := Types.isTerminalEquivUnique (ToType X) <| IsTerminal.isTerminalObj (forget C) X h diff --git a/Mathlib/CategoryTheory/Limits/Shapes/End.lean b/Mathlib/CategoryTheory/Limits/Shapes/End.lean index f7174f9f0f898a..9e41ad3b004267 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/End.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/End.lean @@ -104,6 +104,9 @@ lemma mk_ι (j : J) : (mk pt π hπ).ι j = π j := rfl end Constructor +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma condition (c : Wedge F) {i j : J} (f : i ⟶ j) : c.ι i ≫ (F.obj (op i)).map f = c.ι j ≫ (F.map f.op).app j := @@ -143,6 +146,7 @@ namespace Cowedge variable {F} +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `CategoryTheory.Limits.Cocone.ext` specialized to produce isomorphisms of cowedges. -/ @[simps!] @@ -167,6 +171,9 @@ lemma mk_π (j : J) : (mk pt ι hι).π j = ι j := rfl end Constructor +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma condition (c : Cowedge F) {i j : J} (f : i ⟶ j) : (F.map f.op).app i ≫ c.π i = (F.obj (op j)).map f ≫ c.π j := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean index a788f7f375946a..350bffea6953f0 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean @@ -135,6 +135,7 @@ theorem walkingParallelPairOp_left : theorem walkingParallelPairOp_right : walkingParallelPairOp.map right = @Quiver.Hom.op _ _ zero one right := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `WalkingParallelPair ⥤ WalkingParallelPairᵒᵖ` sending left to left and right to @@ -273,6 +274,7 @@ theorem parallelPair_map_right (f g : X ⟶ Y) : (parallelPair f g).map right = theorem parallelPair_functor_obj {F : WalkingParallelPair ⥤ C} (j : WalkingParallelPair) : (parallelPair (F.map left) (F.map right)).obj j = F.obj j := by cases j <;> rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Every functor indexing a (co)equalizer is naturally isomorphic (actually, equal) to a `parallelPair` -/ @[simps!] @@ -395,7 +397,7 @@ theorem Cofork.app_zero_eq_comp_π_right (s : Cofork f g) : s.ι.app zero = g set_option backward.defeqAttrib.useBackward true in /-- A fork on `f g : X ⟶ Y` is determined by the morphism `ι : P ⟶ X` satisfying `ι ≫ f = ι ≫ g`. -/ -@[simps] +@[simps, implicit_reducible] def Fork.ofι {P : C} (ι : P ⟶ X) (w : ι ≫ f = ι ≫ g) : Fork f g where pt := P π := @@ -409,7 +411,7 @@ def Fork.ofι {P : C} (ι : P ⟶ X) (w : ι ≫ f = ι ≫ g) : Fork f g where set_option backward.defeqAttrib.useBackward true in /-- A cofork on `f g : X ⟶ Y` is determined by the morphism `π : Y ⟶ P` satisfying `f ≫ π = g ≫ π`. -/ -@[simps] +@[simps, implicit_reducible] def Cofork.ofπ {P : C} (π : Y ⟶ P) (w : f ≫ π = g ≫ π) : Cofork f g where pt := P ι := @@ -622,6 +624,7 @@ def Cone.ofFork {F : WalkingParallelPair ⥤ C} (t : Fork (F.map left) (F.map ri { app := fun X => t.π.app X ≫ eqToHom (by simp) naturality := by rintro _ _ (_ | _ | _) <;> simp [t.condition] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- This is a helper construction that can be useful when verifying that a category has all coequalizers. Given `F : WalkingParallelPair ⥤ C`, which is really the same as @@ -655,6 +658,7 @@ def Fork.ofCone {F : WalkingParallelPair ⥤ C} (t : Cone F) : Fork (F.map left) π := { app := fun X => t.π.app X ≫ eqToHom (by simp) naturality := by rintro _ _ (_ | _ | _) <;> simp } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `F : WalkingParallelPair ⥤ C`, which is really the same as `parallelPair (F.map left) (F.map right)` and a cocone on `F`, we get a cofork on @@ -933,12 +937,14 @@ variable {f g} def idFork (h : f = g) : Fork f g := Fork.ofι (𝟙 X) <| h ▸ rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The identity on `X` is an equalizer of `(f, g)`, if `f = g`. -/ def isLimitIdFork (h : f = g) : IsLimit (idFork h) := Fork.IsLimit.mk _ (fun s => Fork.ι s) (fun _ => Category.comp_id _) fun s m h => by convert! h exact (Category.comp_id _).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Every equalizer of `(f, g)`, where `f = g`, is an isomorphism. -/ theorem isIso_limit_cone_parallelPair_of_eq (h₀ : f = g) {c : Fork f g} (h : IsLimit c) : IsIso c.ι := @@ -1151,12 +1157,14 @@ variable {f g} def idCofork (h : f = g) : Cofork f g := Cofork.ofπ (𝟙 Y) <| h ▸ rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The identity on `Y` is a coequalizer of `(f, g)`, where `f = g`. -/ def isColimitIdCofork (h : f = g) : IsColimit (idCofork h) := Cofork.IsColimit.mk _ (fun s => Cofork.π s) (fun _ => Category.id_comp _) fun s m h => by convert! h exact (Category.id_comp _).symm +set_option backward.isDefEq.respectTransparency.types false in /-- Every coequalizer of `(f, g)`, where `f = g`, is an isomorphism. -/ theorem isIso_colimit_cocone_parallelPair_of_eq (h₀ : f = g) {c : Cofork f g} (h : IsColimit c) : IsIso c.π := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/FiniteMultiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/FiniteMultiequalizer.lean index c91fcb8a76cec2..c353168634b236 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/FiniteMultiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/FiniteMultiequalizer.lean @@ -24,6 +24,7 @@ variable {J : MulticospanShape} [Fintype J.L] [Fintype J.R] instance : Fintype (WalkingMulticospan J) := .ofEquiv _ (proxy_equiv% (WalkingMulticospan J)) +set_option backward.isDefEq.respectTransparency.types false in instance [DecidableEq J.L] [DecidableEq J.R] : FinCategory (WalkingMulticospan J) where fintypeHom | .left a, .left b => ⟨if e : a = b then {eqToHom (e ▸ rfl)} else ∅, by rintro ⟨⟩; simp⟩ @@ -51,6 +52,7 @@ variable {J : MultispanShape} [Fintype J.L] [Fintype J.R] instance : Fintype (WalkingMultispan J) := .ofEquiv _ (proxy_equiv% (WalkingMultispan J)) +set_option backward.isDefEq.respectTransparency.types false in instance [DecidableEq J.L] [DecidableEq J.R] : FinCategory (WalkingMultispan J) where fintypeHom | .left a, .left b => ⟨if e : a = b then {eqToHom (e ▸ rfl)} else ∅, by rintro ⟨⟩; simp⟩ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/FunctorToTypes.lean b/Mathlib/CategoryTheory/Limits/Shapes/FunctorToTypes.lean index 358803ff0ee2ce..389802cb63ad81 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/FunctorToTypes.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/FunctorToTypes.lean @@ -50,6 +50,7 @@ def prod.fst : prod F G ⟶ F where def prod.snd : prod F G ⟶ G where app _ := ↾fun a ↦ a.2 +set_option backward.isDefEq.respectTransparency.types false in /-- Given natural transformations `F ⟶ F₁` and `F ⟶ F₂`, construct a natural transformation `F ⟶ prod F₁ F₂`. -/ @[simps] @@ -57,10 +58,12 @@ def prod.lift {F₁ F₂ : C ⥤ Type w} (τ₁ : F ⟶ F₁) (τ₂ : F ⟶ F F ⟶ prod F₁ F₂ where app x := ↾fun y ↦ ⟨τ₁.app x y, τ₂.app x y⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod.lift_fst {F₁ F₂ : C ⥤ Type w} (τ₁ : F ⟶ F₁) (τ₂ : F ⟶ F₂) : prod.lift τ₁ τ₂ ≫ prod.fst = τ₁ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod.lift_snd {F₁ F₂ : C ⥤ Type w} (τ₁ : F ⟶ F₁) (τ₂ : F ⟶ F₂) : prod.lift τ₁ τ₂ ≫ prod.snd = τ₂ := rfl @@ -72,6 +75,7 @@ variable (F G) def binaryProductCone : BinaryFan F G := BinaryFan.mk prod.fst prod.snd +set_option backward.isDefEq.respectTransparency.types false in /-- `prod F G` is a limit cone. -/ @[simps] def binaryProductLimit : IsLimit (binaryProductCone F G) where @@ -81,6 +85,7 @@ def binaryProductLimit : IsLimit (binaryProductCone F G) where simp only [← h ⟨WalkingPair.right⟩, ← h ⟨WalkingPair.left⟩] congr +set_option backward.isDefEq.respectTransparency.types false in /-- `prod F G` is a binary product for `F` and `G`. -/ def binaryProductLimitCone : Limits.LimitCone (pair F G) := ⟨_, binaryProductLimit F G⟩ @@ -89,10 +94,12 @@ def binaryProductLimitCone : Limits.LimitCone (pair F G) := noncomputable def binaryProductIso : F ⨯ G ≅ prod F G := limit.isoLimitCone (binaryProductLimitCone F G) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma binaryProductIso_hom_comp_fst : (binaryProductIso F G).hom ≫ prod.fst = Limits.prod.fst := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma binaryProductIso_hom_comp_snd : (binaryProductIso F G).hom ≫ prod.snd = Limits.prod.snd := rfl @@ -127,11 +134,13 @@ noncomputable def prodMk {a : C} (x : F.obj a) (y : G.obj a) : (F ⨯ G).obj a := ((binaryProductIso F G).inv).app a ⟨x, y⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prodMk_fst {a : C} (x : F.obj a) (y : G.obj a) : (Limits.prod.fst (X := F)).app a (prodMk x y) = x := by simp [prodMk] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prodMk_snd {a : C} (x : F.obj a) (y : G.obj a) : (Limits.prod.snd (X := F)).app a (prodMk x y) = y := by @@ -143,6 +152,7 @@ lemma prod_ext {a : C} (z w : (prod F G).obj a) (h1 : z.1 = w.1) (h2 : z.2 = w.2 variable (F G) +set_option backward.isDefEq.respectTransparency.types false in /-- `(F ⨯ G).obj a` is in bijection with the product of `F.obj a` and `G.obj a`. -/ @[simps] noncomputable @@ -152,6 +162,7 @@ def binaryProductEquiv (a : C) : (F ⨯ G).obj a ≃ (F.obj a) × (G.obj a) wher left_inv _ := by simp [-prod_obj, prodMk] right_inv _ := by simp [-prod_obj, prodMk] +set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma prod_ext' (a : C) (z w : (F ⨯ G).obj a) (h1 : (Limits.prod.fst (X := F)).app a z = (Limits.prod.fst (X := F)).app a w) @@ -208,6 +219,7 @@ variable (F G) def binaryCoproductCocone : BinaryCofan F G := BinaryCofan.mk coprod.inl coprod.inr +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `coprod F G` is a colimit cocone. -/ @[simps] @@ -280,6 +292,7 @@ abbrev coprodInr {a : C} (x : G.obj a) : (F ⨿ G).obj a := variable (F G) +set_option backward.isDefEq.respectTransparency.types false in /-- `(F ⨿ G).obj a` is in bijection with disjoint union of `F.obj a` and `G.obj a`. -/ @[simps] noncomputable diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean b/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean index aca1b0a3a32c72..4b389bdf1f7049 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Grothendieck.lean @@ -28,7 +28,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open Functor +open CategoryTheory.Functor namespace Limits diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Images.lean b/Mathlib/CategoryTheory/Limits/Shapes/Images.lean index db0925d48b3637..6723da2e597c96 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Images.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Images.lean @@ -208,6 +208,7 @@ theorem fac_lift {F : MonoFactorisation f} (hF : IsImage F) (F' : MonoFactorisat variable (f) +set_option backward.isDefEq.respectTransparency.types false in /-- The trivial factorisation of a monomorphism satisfies the universal property. -/ @[simps] def self [Mono f] : IsImage (MonoFactorisation.self f) where lift F' := F'.e @@ -249,6 +250,7 @@ def ofArrowIso {f g : Arrow C} {F : MonoFactorisation f.hom} (hF : IsImage F) (s simpa only [MonoFactorisation.ofArrowIso_m, Arrow.inv_right, ← Category.assoc, IsIso.comp_inv_eq] using hF.lift_fac (F'.ofArrowIso (inv sq)) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a mono factorisation `X ⟶ I ⟶ Y` of an arrow `f` that is an image and an isomorphism `I ≅ I'`, the induced mono factorisation by the isomorphism is also an image. @@ -351,6 +353,7 @@ def Image.isImage : IsImage (Image.monoFactorisation f) := (Image.imageFactorisation f).isImage /-- The categorical image of a morphism. -/ +@[implicit_reducible] def image : C := (Image.monoFactorisation f).I diff --git a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean index 2336b2f854393f..2d149581f8a085 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean @@ -37,13 +37,19 @@ namespace CategoryTheory.Limits variable {C : Type u₁} [Category.{v₁} C] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Construct a cone for the empty diagram given an object. -/ -@[simps] +@[simps, implicit_reducible] def asEmptyCone (X : C) : Cone (Functor.empty.{0} C) := { pt := X π := { app := by cat_disch } } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Construct a cocone for the empty diagram given an object. -/ @[simps] def asEmptyCocone (X : C) : Cocone (Functor.empty.{0} C) := @@ -92,6 +98,7 @@ def IsTerminal.ofUniqueHom {Y : C} (h : ∀ X : C, X ⟶ Y) (uniq : ∀ (X : C) def isTerminalTop {α : Type*} [Preorder α] [OrderTop α] : IsTerminal (⊤ : α) := IsTerminal.ofUnique _ +set_option backward.isDefEq.respectTransparency.types false in /-- Transport a term of type `IsTerminal` across an isomorphism. -/ def IsTerminal.ofIso {Y Z : C} (hY : IsTerminal Y) (i : Y ≅ Z) : IsTerminal Z := IsLimit.ofIsoLimit hY @@ -136,6 +143,7 @@ def IsInitial.ofUniqueHom {X : C} (h : ∀ Y : C, X ⟶ Y) (uniq : ∀ (Y : C) ( def isInitialBot {α : Type*} [Preorder α] [OrderBot α] : IsInitial (⊥ : α) := IsInitial.ofUnique _ +set_option backward.isDefEq.respectTransparency.types false in /-- Transport a term of type `IsInitial` across an isomorphism. -/ def IsInitial.ofIso {X Y : C} (hX : IsInitial X) (i : X ≅ Y) : IsInitial Y := IsColimit.ofIsoColimit hX @@ -348,6 +356,7 @@ def coneOfDiagramInitial {X : J} (tX : IsInitial X) (F : J ⥤ C) : Cone F where dsimp rw [← F.map_comp, Category.id_comp, tX.hom_ext (tX.to j ≫ k) (tX.to j')] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given an initial object of `J`, show the cone `coneOfDiagramInitial` is a limit. -/ @@ -376,6 +385,7 @@ def coneOfDiagramTerminal {X : J} (hX : IsTerminal X) (F : J ⥤ C) simp only [IsIso.eq_inv_comp, IsIso.comp_inv_eq, Category.id_comp, ← F.map_comp, hX.hom_ext (hX.from i) (f ≫ hX.from j)] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given a terminal object of `J` and that the morphisms in the diagram are isomorphisms, show the cone `coneOfDiagramTerminal` is a limit. -/ @@ -395,6 +405,7 @@ def coconeOfDiagramTerminal {X : J} (tX : IsTerminal X) (F : J ⥤ C) : Cocone F dsimp rw [← F.map_comp, Category.comp_id, tX.hom_ext (k ≫ tX.from j') (tX.from j)] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given a terminal object of `J`, show the cocone `coconeOfDiagramTerminal` is a colimit. -/ @@ -426,6 +437,7 @@ def coconeOfDiagramInitial {X : J} (hX : IsInitial X) (F : J ⥤ C) simp only [IsIso.eq_inv_comp, IsIso.comp_inv_eq, Category.comp_id, ← F.map_comp, hX.hom_ext (hX.to i ≫ f) (hX.to j)] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given an initial object of `J` and that the morphisms in the diagram are isomorphisms, show the cone `coconeOfDiagramInitial` is a colimit. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/KernelPair.lean b/Mathlib/CategoryTheory/Limits/Shapes/KernelPair.lean index ce65d956ac1222..8680dd87f44c4e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/KernelPair.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/KernelPair.lean @@ -209,6 +209,7 @@ theorem mono_of_eq_fst_snd' (h : IsKernelPair f a a) : Mono f := theorem mono_of_eq_fst_snd (h : IsKernelPair f a b) (e : a = b) : Mono f := by induction e; exact h.mono_of_eq_fst_snd' +set_option backward.isDefEq.respectTransparency.types false in theorem isIso_of_mono (h : IsKernelPair f a b) [Mono f] : IsIso a := by rw [← show _ = a from diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean index a76ecb17ce0a6b..b4f0d7bd9ae593 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean @@ -106,6 +106,7 @@ set_option backward.defeqAttrib.useBackward true in def isoOfι (s : Fork f 0) : s ≅ Fork.ofι (Fork.ι s) (Fork.condition s) := Cone.ext (Iso.refl _) <| by aesop +set_option backward.isDefEq.respectTransparency.types false in /-- If `ι = ι'`, then `fork.ofι ι _` and `fork.ofι ι' _` are isomorphic. -/ def ofιCongr {P : C} {ι ι' : P ⟶ X} {w : ι ≫ f = 0} (h : ι = ι') : KernelFork.ofι ι w ≅ KernelFork.ofι ι' (by rw [← h, w]) := @@ -246,6 +247,9 @@ def mapOfIsLimit (kf : KernelFork f) {kf' : KernelFork f'} (hf' : IsLimit kf') (φ : Arrow.mk f ⟶ Arrow.mk f') : kf.pt ⟶ kf'.pt := hf'.lift (KernelFork.ofι (kf.ι ≫ φ.left) (by simp)) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma mapOfIsLimit_ι (kf : KernelFork f) {kf' : KernelFork f'} (hf' : IsLimit kf') (φ : Arrow.mk f ⟶ Arrow.mk f') : @@ -526,7 +530,9 @@ end HasZeroObject section Transport +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in /-- Transport an `IsKernel` across isomorphisms. -/ def IsKernel.ofIso {X' Y' : C} {f' : X' ⟶ Y'} {s : KernelFork f} (hs : IsLimit s) (s' : KernelFork f') (eX : X ≅ X') (eY : Y ≅ Y') (e : s.pt ≅ s'.pt) @@ -610,6 +616,7 @@ set_option backward.defeqAttrib.useBackward true in def isoOfπ (s : Cofork f 0) : s ≅ Cofork.ofπ (Cofork.π s) (Cofork.condition s) := Cocone.ext (Iso.refl _) fun j => by cases j <;> cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- If `π = π'`, then `CokernelCofork.of_π π _` and `CokernelCofork.of_π π' _` are isomorphic. -/ def ofπCongr {P : C} {π π' : Y ⟶ P} {w : f ≫ π = 0} (h : π = π') : CokernelCofork.ofπ π w ≅ CokernelCofork.ofπ π' (by rw [← h, w]) := @@ -752,6 +759,9 @@ def mapOfIsColimit {cc : CokernelCofork f} (hf : IsColimit cc) (cc' : CokernelCo hf.desc (CokernelCofork.ofπ (φ.right ≫ cc'.π) (by erw [← Arrow.w_assoc φ, condition, comp_zero])) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma π_mapOfIsColimit {cc : CokernelCofork f} (hf : IsColimit cc) (cc' : CokernelCofork f') (φ : Arrow.mk f ⟶ Arrow.mk f') : @@ -1172,6 +1182,7 @@ def IsCokernel.cokernelIso {Z : C} (l : Y ⟶ Z) {s : CokernelCofork f} (hs : Is · dsimp; rw [← h]; simp · exact h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Transport an `IsCokernel` across isomorphisms. -/ def IsCokernel.ofIso {X' Y' : C} {f' : X' ⟶ Y'} {s : CokernelCofork f} (hs : IsColimit s) @@ -1288,10 +1299,12 @@ noncomputable def ker : Arrow C ⥤ C where obj f := kernel f.hom map {f g} u := kernel.lift _ (kernel.ι _ ≫ u.left) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The kernel inclusion is natural. -/ @[simps] def ker.ι : ker (C := C) ⟶ Arrow.leftFunc where app f := kernel.ι _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma ker.condition : ι C ≫ Arrow.leftToRight = 0 := by cat_disch @@ -1306,10 +1319,12 @@ noncomputable def coker : Arrow C ⥤ C where obj f := cokernel f.hom map {f g} u := cokernel.desc _ (u.right ≫ cokernel.π _) (by simp [← Arrow.w_assoc u]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The cokernel projection is natural. -/ @[simps] def coker.π : Arrow.rightFunc ⟶ coker (C := C) where app f := cokernel.π _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma coker.condition : Arrow.leftToRight ≫ π C = 0 := by cat_disch diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index fd787fbeca2559..801dd86f5f1777 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -162,6 +162,7 @@ def functorExt {C : Type*} [Category* C] {F G : WalkingMulticospan J ⥤ C} NatIso.ofComponents (fun j ↦ match j with | .left i => left i | .right i => right i) <| by rintro _ _ ⟨_⟩ <;> simp [wl, wr] +set_option backward.isDefEq.respectTransparency.types false in lemma functor_ext {C : Type*} [Category* C] {F G : WalkingMulticospan J ⥤ C} (left : ∀ i, F.obj (.left i) = G.obj (.left i)) (right : ∀ i, F.obj (.right i) = G.obj (.right i)) @@ -541,6 +542,7 @@ theorem app_right_eq_ι_comp_snd (b) : theorem hom_comp_ι (K₁ K₂ : Multifork I) (f : K₁ ⟶ K₂) (j : J.L) : f.hom ≫ K₂.ι j = K₁.ι j := f.w _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Construct a multifork using a collection `ι` of morphisms. -/ @[simps] @@ -626,12 +628,14 @@ lemma IsLimit.hom_ext (hK : IsLimit K) {T : C} {f g : T ⟶ K.pt} · dsimp rw [app_right_eq_ι_comp_fst, reassoc_of% h] +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for morphisms to the point of a limit multifork. -/ def IsLimit.lift (hK : IsLimit K) {T : C} (k : ∀ a, T ⟶ I.left a) (hk : ∀ b, k (J.fst b) ≫ I.fst b = k (J.snd b) ≫ I.snd b) : T ⟶ K.pt := hK.lift (Multifork.ofι _ _ k hk) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma IsLimit.fac (hK : IsLimit K) {T : C} (k : ∀ a, T ⟶ I.left a) (hk : ∀ b, k (J.fst b) ≫ I.fst b = k (J.snd b) ≫ I.snd b) (a : J.L) : @@ -739,6 +743,7 @@ def ofPiForkFunctor : { hom := f.hom w := by rintro (_ | _) <;> simp } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of multiforks is equivalent to the category of forks over `∏ᶜ I.left ⇉ ∏ᶜ I.right`. It then follows from `CategoryTheory.IsLimit.ofPreservesConeTerminal` (or `reflects`) that it @@ -759,6 +764,7 @@ def multiforkEquivPiForkOfIsLimit : variable [HasProduct I.left] [HasProduct I.right] +set_option backward.isDefEq.respectTransparency.types false in /-- The category of multiforks is equivalent to the category of forks over `∏ᶜ I.left ⇉ ∏ᶜ I.right`. It then follows from `CategoryTheory.IsLimit.ofPreservesConeTerminal` (or `reflects`) that it preserves and reflects limit cones. @@ -794,6 +800,7 @@ def multiforkOfParallelHomsEquivFork (J : MulticospanShape) [Unique J.L] [Unique Category.comp_id, sndPiMapOfIsLimit_proj] simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma multiforkOfParallelHomsEquivFork_functor_obj_ι (J : MulticospanShape) [Unique J.L] [Unique J.R] {X Y : C} (f g : X ⟶ Y) (c : Multifork (ofParallelHoms J f g)) : @@ -999,6 +1006,7 @@ noncomputable def ofSigmaCoforkFunctor : { hom := f.hom w := by rintro (_ | _) <;> simp } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`. @@ -1020,6 +1028,7 @@ noncomputable def multicoforkEquivSigmaCoforkOfIsColimit : variable [HasCoproduct I.left] [HasCoproduct I.right] +set_option backward.isDefEq.respectTransparency.types false in /-- The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`. It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that @@ -1101,6 +1110,7 @@ variable [HasProduct I.left] [HasProduct I.right] instance : HasEqualizer I.fstPiMap I.sndPiMap := ⟨⟨⟨_, IsLimit.ofPreservesConeTerminal I.multiforkEquivPiFork.functor (limit.isLimit _)⟩⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The multiequalizer is isomorphic to the equalizer of `∏ᶜ I.left ⇉ ∏ᶜ I.right`. -/ def isoEqualizer : multiequalizer I ≅ equalizer I.fstPiMap I.sndPiMap := limit.isoLimitCone @@ -1181,6 +1191,7 @@ instance : HasCoequalizer I.fstSigmaMap I.sndSigmaMap := IsColimit.ofPreservesCoconeInitial I.multicoforkEquivSigmaCofork.functor (colimit.isColimit _)⟩⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The multicoequalizer is isomorphic to the coequalizer of `∐ I.left ⇉ ∐ I.right`. -/ def isoCoequalizer : multicoequalizer I ≅ coequalizer I.fstSigmaMap I.sndSigmaMap := colimit.isoColimitCocone @@ -1244,6 +1255,7 @@ def toLinearOrder : MultispanIndex (.ofLinearOrder ι) C where fst j := I.fst j.1 snd j := I.snd j.1 +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a linearly ordered type `ι` and `I : MultispanIndex (.prod ι) C`, this is the isomorphism of functors between diff --git a/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean index 2fa2ad31bce3b6..69fba1ee5846ef 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Basic.lean @@ -54,9 +54,10 @@ attribute [inherit_doc NormalMono] NormalMono.Z NormalMono.g NormalMono.w Normal section +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` is an equivalence and `F.map f` is a normal mono, then `f` is a normal mono. -/ -@[implicit_reducible] +@[instance_reducible] def equivalenceReflectsNormalMono {D : Type u₂} [Category.{v₁} D] [HasZeroMorphisms D] (F : C ⥤ D) [F.IsEquivalence] {X Y : C} {f : X ⟶ Y} (hf : NormalMono (F.map f)) : NormalMono f where Z := F.objPreimage hf.Z @@ -93,7 +94,7 @@ def NormalMono.lift' {W : C} (f : X ⟶ Y) [hf : NormalMono f] (k : W ⟶ Y) (h See also `pullback.sndOfMono` for the basic monomorphism version, and `normalOfIsPullbackFstOfNormal` for the flipped version. -/ -@[implicit_reducible] +@[instance_reducible] def normalOfIsPullbackSndOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S} [hn : NormalMono h] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) : NormalMono g where @@ -113,7 +114,7 @@ def normalOfIsPullbackSndOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : See also `pullback.fstOfMono` for the basic monomorphism version, and `normalOfIsPullbackSndOfNormal` for the flipped version. -/ -@[implicit_reducible] +@[instance_reducible] def normalOfIsPullbackFstOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S} [NormalMono k] (comm : f ≫ h = g ≫ k) (t : IsLimit (PullbackCone.mk _ _ comm)) : NormalMono f := @@ -122,7 +123,7 @@ def normalOfIsPullbackFstOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- Transport a `NormalMono` structure via an isomorphism of arrows. -/ -@[implicit_reducible] +@[instance_reducible] def NormalMono.ofArrowIso {X Y : C} {f : X ⟶ Y} (hf : NormalMono f) {X' Y' : C} {f' : X' ⟶ Y'} (e : Arrow.mk f ≅ Arrow.mk f') : NormalMono f' where @@ -151,7 +152,7 @@ end /-- In a category in which every monomorphism is normal, we can express every monomorphism as a kernel. This is not an instance because it would create an instance loop. -/ -@[implicit_reducible] +@[instance_reducible] def normalMonoOfMono [IsNormalMonoCategory C] (f : X ⟶ Y) [Mono f] : NormalMono f := (IsNormalMonoCategory.normalMonoOfMono _).some @@ -178,9 +179,10 @@ attribute [inherit_doc NormalEpi] NormalEpi.W NormalEpi.g NormalEpi.w NormalEpi. section +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F` is an equivalence and `F.map f` is a normal epi, then `f` is a normal epi. -/ -@[implicit_reducible] +@[instance_reducible] def equivalenceReflectsNormalEpi {D : Type u₂} [Category.{v₁} D] [HasZeroMorphisms D] (F : C ⥤ D) [F.IsEquivalence] {X Y : C} {f : X ⟶ Y} (hf : NormalEpi (F.map f)) : NormalEpi f where W := F.objPreimage hf.W @@ -214,7 +216,7 @@ def NormalEpi.desc' {W : C} (f : X ⟶ Y) [nef : NormalEpi f] (k : X ⟶ W) (h : See also `pushout.sndOfEpi` for the basic epimorphism version, and `normalOfIsPushoutFstOfNormal` for the flipped version. -/ -@[implicit_reducible] +@[instance_reducible] def normalOfIsPushoutSndOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S} [gn : NormalEpi g] (comm : f ≫ h = g ≫ k) (t : IsColimit (PushoutCocone.mk _ _ comm)) : NormalEpi h where @@ -234,7 +236,7 @@ def normalOfIsPushoutSndOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : See also `pushout.fstOfEpi` for the basic epimorphism version, and `normalOfIsPushoutSndOfNormal` for the flipped version. -/ -@[implicit_reducible] +@[instance_reducible] def normalOfIsPushoutFstOfNormal {P Q R S : C} {f : P ⟶ Q} {g : P ⟶ R} {h : Q ⟶ S} {k : R ⟶ S} [NormalEpi f] (comm : f ≫ h = g ≫ k) (t : IsColimit (PushoutCocone.mk _ _ comm)) : NormalEpi k := @@ -249,7 +251,7 @@ variable [HasZeroMorphisms C] set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- Transport a `NormalEpi` structure via an isomorphism of arrows. -/ -@[implicit_reducible] +@[instance_reducible] def NormalEpi.ofArrowIso {X Y : C} {f : X ⟶ Y} (hf : NormalEpi f) {X' Y' : C} {f' : X' ⟶ Y'} (e : Arrow.mk f ≅ Arrow.mk f') : NormalEpi f' where @@ -267,7 +269,7 @@ def NormalEpi.ofArrowIso {X Y : C} {f : X ⟶ Y} set_option backward.defeqAttrib.useBackward true in /-- A normal mono becomes a normal epi in the opposite category. -/ -@[implicit_reducible] +@[instance_reducible] def normalEpiOfNormalMonoUnop {X Y : Cᵒᵖ} (f : X ⟶ Y) (m : NormalMono f.unop) : NormalEpi f where W := op m.Z g := m.g.op @@ -287,7 +289,7 @@ def normalEpiOfNormalMonoUnop {X Y : Cᵒᵖ} (f : X ⟶ Y) (m : NormalMono f.un set_option backward.defeqAttrib.useBackward true in /-- A normal epi becomes a normal mono in the opposite category. -/ -@[implicit_reducible] +@[instance_reducible] def normalMonoOfNormalEpiUnop {X Y : Cᵒᵖ} (f : X ⟶ Y) (m : NormalEpi f.unop) : NormalMono f where Z := op m.W g := m.g.op @@ -319,7 +321,7 @@ end /-- In a category in which every epimorphism is normal, we can express every epimorphism as a kernel. This is not an instance because it would create an instance loop. -/ -@[implicit_reducible] +@[instance_reducible] def normalEpiOfEpi [IsNormalEpiCategory C] (f : X ⟶ Y) [Epi f] : NormalEpi f := (IsNormalEpiCategory.normalEpiOfEpi _).some diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean index fee3e3f67f5143..4e914f6ec37245 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Equalizers.lean @@ -80,24 +80,28 @@ def opParallelPairIso {X Y : C} (f g : X ⟶ Y) : _ ≅ walkingParallelPairOpEquiv.inverse ⋙ parallelPair f.op g.op := isoWhiskerLeft _ (parallelPairOpIso f g).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma opParallelPairIso_hom_app_zero {X Y : C} (f g : X ⟶ Y) : (opParallelPairIso f g).hom.app (op WalkingParallelPair.zero) = 𝟙 _ := by simp [opParallelPairIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma opParallelPairIso_hom_app_one {X Y : C} (f g : X ⟶ Y) : (opParallelPairIso f g).hom.app (op WalkingParallelPair.one) = 𝟙 _ := by simp [opParallelPairIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma opParallelPairIso_inv_app_zero {X Y : C} (f g : X ⟶ Y) : (opParallelPairIso f g).inv.app (op WalkingParallelPair.zero) = 𝟙 _ := by simp [opParallelPairIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma opParallelPairIso_inv_app_one {X Y : C} (f g : X ⟶ Y) : @@ -130,16 +134,19 @@ def op {X Y : C} {f g : X ⟶ Y} (c : Cofork f g) : Fork f.op g.op := (Cone.postcompose (parallelPairOpIso f g).symm.hom).obj (Cone.whisker walkingParallelPairOpEquiv.functor (Cocone.op c)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma op_π_app_one {X Y : C} {f g : X ⟶ Y} (c : Cofork f g) : c.op.π.app .one = Quiver.Hom.op (c.ι.app .zero) := by simp [op] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma op_π_app_zero {X Y : C} {f g : X ⟶ Y} (c : Cofork f g) : c.op.π.app .zero = Quiver.Hom.op (c.ι.app .one) := by simp [op] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem op_ι {X Y : C} {f g : X ⟶ Y} (c : Cofork f g) : c.op.ι = c.π.op := by simp [Cofork.op, Fork.ι] @@ -153,16 +160,19 @@ def unop {X Y : Cᵒᵖ} {f g : X ⟶ Y} (c : Fork f g) : Cofork f.unop g.unop : Cone.unop ((Cone.postcompose (opParallelPairIso f.unop g.unop).symm.hom).obj (Cone.whisker walkingParallelPairOpEquiv.inverse c)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma unop_ι_app_one {X Y : Cᵒᵖ} {f g : X ⟶ Y} (c : Fork f g) : c.unop.ι.app .one = Quiver.Hom.unop (c.π.app .zero) := by simp [unop] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma unop_ι_app_zero {X Y : Cᵒᵖ} {f g : X ⟶ Y} (c : Fork f g) : c.unop.ι.app .zero = Quiver.Hom.unop (c.π.app .one) := by simp [unop] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem unop_π {X Y : Cᵒᵖ} {f g : X ⟶ Y} (c : Fork f g) : c.unop.π = c.ι.unop := by simp [Fork.unop, Cofork.π] @@ -338,6 +348,7 @@ end Fork namespace Cofork +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Cofork.ofπ f pullback.condition` is a colimit cocone if and only if `Fork.ofι f.op pushout.condition` in the opposite category is a limit cone. -/ @@ -354,6 +365,7 @@ def isColimitCoforkPushoutEquivIsColimitForkOpPullback left_inv := by cat_disch right_inv := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Cofork.ofπ f pullback.condition` is a colimit cocone in `Cᵒᵖ` if and only if `Fork.ofι f.unop pushout.condition` in `C` is a limit cone. -/ @@ -375,6 +387,7 @@ end Cofork namespace Fork +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Fork.ofι f pushout.condition` is a limit cone if and only if `Cofork.ofπ f.op pullback.condition` in the opposite category is a colimit cocone. -/ @@ -396,6 +409,7 @@ def isLimitForkPushoutEquivIsColimitForkOpPullback left_inv := by cat_disch right_inv := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Fork.ofι f pushout.condition` is a limit cone in `Cᵒᵖ` if and only if `Cofork.ofπ f.op pullback.condition` in `C` is a colimit cocone. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean index 0ffb967cc20582..f1a5f844d2429d 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Products.lean @@ -99,9 +99,10 @@ instance : HasProduct (op <| Z ·) := hasLimit_of_iso Discrete.functor (op <| Z ·)) /-- A `Cofan` gives a `Fan` in the opposite category. -/ -@[simp] +@[simp, implicit_reducible] def Cofan.op (c : Cofan Z) : Fan (op <| Z ·) := Fan.mk _ (fun a ↦ (c.inj a).op) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If a `Cofan` is colimit, then its opposite is limit. -/ -- noncomputability is just for performance (compilation takes a while) @@ -182,6 +183,7 @@ theorem desc_op_comp_opCoproductIsoProduct'_hom {c : Cofan Z} {f : Fan (op <| Z erw [opCoproductIsoProduct'_inv_comp_inj, IsLimit.fac] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem desc_op_comp_opCoproductIsoProduct_hom [HasCoproduct Z] {X : C} (π : (a : α) → Z a ⟶ X) : (Sigma.desc π).op ≫ (opCoproductIsoProduct Z).hom = Pi.lift (fun a ↦ (π a).op) := by @@ -189,7 +191,7 @@ theorem desc_op_comp_opCoproductIsoProduct_hom [HasCoproduct Z] {X : C} (π : (a desc_op_comp_opCoproductIsoProduct'_hom (coproductIsCoproduct Z) (productIsProduct (op <| Z ·)) (Cofan.mk _ π) · simp [Sigma.desc, coproductIsCoproduct] - · simp [Pi.lift, productIsProduct] + · simp [productIsProduct] end OppositeCoproducts @@ -214,6 +216,7 @@ instance : HasCoproduct (op <| Z ·) := hasColimit_of_iso @[simp] def Fan.op (f : Fan Z) : Cofan (op <| Z ·) := Cofan.mk _ (fun a ↦ (f.proj a).op) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If a `Fan` is limit, then its opposite is colimit. -/ -- noncomputability is just for performance (compilation takes a while) @@ -281,6 +284,7 @@ theorem opProductIsoCoproduct'_inv_comp_lift {f : Fan Z} {c : Cofan (op <| Z ·) erw [← Category.assoc, proj_comp_opProductIsoCoproduct'_hom, IsColimit.fac] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem opProductIsoCoproduct_inv_comp_lift [HasProduct Z] {X : C} (π : (a : α) → X ⟶ Z a) : (opProductIsoCoproduct Z).inv ≫ (Pi.lift π).op = Sigma.desc (fun a ↦ (π a).op) := by @@ -288,7 +292,7 @@ theorem opProductIsoCoproduct_inv_comp_lift [HasProduct Z] {X : C} (π : (a : α opProductIsoCoproduct'_inv_comp_lift (productIsProduct Z) (coproductIsCoproduct (op <| Z ·)) (Fan.mk _ π) · simp [Pi.lift, productIsProduct] - · simp [Sigma.desc, coproductIsCoproduct] + · simp [coproductIsCoproduct] end OppositeProducts diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean index d24b7e08387847..30626a151ed93e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Opposites/Pullbacks.lean @@ -42,6 +42,7 @@ instance hasPushouts_opposite [HasPullbacks C] : HasPushouts Cᵒᵖ := by hasLimitsOfShape_of_equivalence walkingSpanOpEquiv.symm infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism relating `Span f.op g.op` and `(Cospan f g).op` -/ @[simps!] @@ -53,6 +54,7 @@ def spanOp {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) : | .right => .refl _) (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism relating `span f.unop g.unop` and `(cospan f g).leftOp` -/ @[simps!] @@ -76,6 +78,7 @@ def opCospan {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) : Functor.associator _ _ _ _ ≅ walkingCospanOpEquiv.functor ⋙ span f.op g.op := isoWhiskerLeft _ (spanOp f g).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/ @[simps!] @@ -87,6 +90,7 @@ def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) : | .right => .refl _) (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism relating `cospan f.unop g.unop` and `(span f g).leftOp` -/ @[simps!] @@ -119,9 +123,11 @@ def unop {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : Cocone.unop ((Cocone.precompose (opCospan f.unop g.unop).hom).obj (Cocone.whisker walkingCospanOpEquiv.functor c)) +set_option backward.isDefEq.respectTransparency.types false in theorem unop_fst {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.unop.fst = c.inl.unop := by simp +set_option backward.isDefEq.respectTransparency.types false in theorem unop_snd {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.unop.snd = c.inr.unop := by simp @@ -131,9 +137,11 @@ def op {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : Pullbac (Cone.postcompose (cospanOp f g).symm.hom).obj (Cone.whisker walkingSpanOpEquiv.inverse (Cocone.op c)) +set_option backward.isDefEq.respectTransparency.types false in theorem op_fst {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.fst = c.inl.op := by simp +set_option backward.isDefEq.respectTransparency.types false in theorem op_snd {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.snd = c.inr.op := by simp @@ -141,6 +149,9 @@ end PushoutCocone namespace PullbackCone +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The obvious map `PullbackCone f g → PushoutCocone f.unop g.unop` -/ @[simps!] def unop {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : @@ -149,9 +160,11 @@ def unop {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : ((Cone.postcompose (opSpan f.unop g.unop).symm.hom).obj (Cone.whisker walkingSpanOpEquiv.functor c)) +set_option backward.isDefEq.respectTransparency.types false in theorem unop_inl {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.unop.inl = c.fst.unop := by simp +set_option backward.isDefEq.respectTransparency.types false in theorem unop_inr {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.unop.inr = c.snd.unop := by simp @@ -161,17 +174,21 @@ def op {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : PushoutC (Cocone.precompose (spanOp f g).hom).obj (Cocone.whisker walkingCospanOpEquiv.inverse (Cone.op c)) +set_option backward.isDefEq.respectTransparency.types false in theorem op_inl {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.inl = c.fst.op := by simp +set_option backward.isDefEq.respectTransparency.types false in theorem op_inr {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.inr = c.snd.op := by simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `c` is a pullback cone, then `c.op.unop` is isomorphic to `c`. -/ def opUnopIso {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.unop ≅ c := PullbackCone.ext (Iso.refl _) (by simp) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `c` is a pullback cone in `Cᵒᵖ`, then `c.unop.op` is isomorphic to `c`. -/ def unopOpIso {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.unop.op ≅ c := @@ -181,11 +198,13 @@ end PullbackCone namespace PushoutCocone +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `c` is a pushout cocone, then `c.op.unop` is isomorphic to `c`. -/ def opUnopIso {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.unop ≅ c := PushoutCocone.ext (Iso.refl _) (by simp) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `c` is a pushout cocone in `Cᵒᵖ`, then `c.unop.op` is isomorphic to `c`. -/ def unopOpIso {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.unop.op ≅ c := @@ -266,11 +285,13 @@ noncomputable def pullbackIsoUnopPushout {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) IsLimit.conePointUniqueUpToIso (@limit.isLimit _ _ _ _ _ h) ((PushoutCocone.isColimitEquivIsLimitUnop _) (colimit.isColimit (span f.op g.op))) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pullbackIsoUnopPushout_inv_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] : (pullbackIsoUnopPushout f g).inv ≫ pullback.fst f g = (pushout.inl f.op g.op).unop := (IsLimit.conePointUniqueUpToIso_inv_comp _ _ _).trans (by simp [unop_id (X := { unop := X })]) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pullbackIsoUnopPushout_inv_snd {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] : (pullbackIsoUnopPushout f g).inv ≫ pullback.snd f g = (pushout.inr f.op g.op).unop := @@ -293,11 +314,13 @@ noncomputable def pullbackIsoOpPushout {X Y Z : Cᵒᵖ} (f : X ⟶ Z) (g : Y IsLimit.conePointUniqueUpToIso (@limit.isLimit _ _ _ _ _ h) ((PushoutCocone.isColimitEquivIsLimitOp _) (colimit.isColimit (span f.unop g.unop))) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pullbackIsoOpPushout_inv_fst {X Y Z : Cᵒᵖ} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] : (pullbackIsoOpPushout f g).inv ≫ pullback.fst f g = (pushout.inl f.unop g.unop).op := (IsLimit.conePointUniqueUpToIso_inv_comp _ _ _).trans (by simp) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pullbackIsoOpPushout_inv_snd {X Y Z : Cᵒᵖ} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] : (pullbackIsoOpPushout f g).inv ≫ pullback.snd f g = (pushout.inr f.unop g.unop).op := @@ -342,11 +365,13 @@ noncomputable def pushoutIsoUnopPullback {X Y Z : C} (f : X ⟶ Z) (g : X ⟶ Y) IsColimit.coconePointUniqueUpToIso (@colimit.isColimit _ _ _ _ _ h) ((PullbackCone.isLimitEquivIsColimitUnop _) (limit.isLimit (cospan f.op g.op))) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pushoutIsoUnopPullback_inl_hom {X Y Z : C} (f : X ⟶ Z) (g : X ⟶ Y) [HasPushout f g] : pushout.inl _ _ ≫ (pushoutIsoUnopPullback f g).hom = (pullback.fst f.op g.op).unop := (IsColimit.comp_coconePointUniqueUpToIso_hom _ _ _).trans (by simp) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pushoutIsoUnopPullback_inr_hom {X Y Z : C} (f : X ⟶ Z) (g : X ⟶ Y) [HasPushout f g] : pushout.inr _ _ ≫ (pushoutIsoUnopPullback f g).hom = (pullback.snd f.op g.op).unop := @@ -369,11 +394,13 @@ noncomputable def pushoutIsoOpPullback {X Y Z : Cᵒᵖ} (f : X ⟶ Z) (g : X IsColimit.coconePointUniqueUpToIso (@colimit.isColimit _ _ _ _ _ h) ((PullbackCone.isLimitEquivIsColimitOp _) (limit.isLimit (cospan f.unop g.unop))) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pushoutIsoOpPullback_inl_hom {X Y Z : Cᵒᵖ} (f : X ⟶ Z) (g : X ⟶ Y) [HasPushout f g] : pushout.inl _ _ ≫ (pushoutIsoOpPullback f g).hom = (pullback.fst f.unop g.unop).op := (IsColimit.comp_coconePointUniqueUpToIso_hom _ _ _).trans (by simp) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem pushoutIsoOpPullback_inr_hom {X Y Z : Cᵒᵖ} (f : X ⟶ Z) (g : X ⟶ Y) [HasPushout f g] : pushout.inr _ _ ≫ (pushoutIsoOpPullback f g).hom = (pullback.snd f.unop g.unop).op := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Preorder/PrincipalSeg.lean b/Mathlib/CategoryTheory/Limits/Shapes/Preorder/PrincipalSeg.lean index 9ac4858d6d39f8..66ebbd32f0ee95 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Preorder/PrincipalSeg.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Preorder/PrincipalSeg.lean @@ -22,6 +22,7 @@ the point of which is `F.obj f.top`. open CategoryTheory Category Limits +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When `f : α p X.as) /-- A cofan over `f : β → C` consists of a collection of maps from every `f b` to an object `P`. -/ -@[simps! pt ι_app] +@[simps! pt ι_app, implicit_reducible] def Cofan.mk {f : β → C} (P : C) (p : ∀ b, f b ⟶ P) : Cofan f where pt := P ι := Discrete.natTrans (fun X => p X.as) @@ -233,6 +233,7 @@ set_option backward.defeqAttrib.useBackward true in def productIsProduct (f : β → C) [HasProduct f] : IsLimit (Fan.mk _ (Pi.π f)) := IsLimit.ofIsoLimit (limit.isLimit (Discrete.functor f)) (Cone.ext (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The cofan constructed of the inclusions from the coproduct is colimiting. -/ def coproductIsCoproduct (f : β → C) [HasCoproduct f] : IsColimit (Cofan.mk _ (Sigma.ι f)) := @@ -312,6 +313,7 @@ lemma Cofan.nonempty_isColimit_iff_isIso_sigmaDesc {f : β → C} [HasCoproduct @[deprecated (since := "2026-01-21")] alias Cofan.isColimit_iff_isIso_sigmaDesc := Cofan.nonempty_isColimit_iff_isIso_sigmaDesc +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A coproduct of coproducts is a coproduct -/ def Cofan.isColimitTrans {X : α → C} (c : Cofan X) (hc : IsColimit c) @@ -350,6 +352,7 @@ lemma Pi.map_comp_map {f g h : α → C} [HasProduct f] [HasProduct g] [HasProdu Pi.map q ≫ Pi.map q' = Pi.map (fun a => q a ≫ q' a) := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance Pi.map_mono {f g : β → C} [HasProduct f] [HasProduct g] (p : ∀ b, f b ⟶ g b) [∀ i, Mono (p i)] : Mono <| Pi.map p := @@ -483,6 +486,7 @@ lemma Sigma.map_comp_map {f g h : α → C} [HasCoproduct f] [HasCoproduct g] [H Sigma.map q ≫ Sigma.map q' = Sigma.map (fun a => q a ≫ q' a) := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance Sigma.map_epi {f g : β → C} [HasCoproduct f] [HasCoproduct g] (p : ∀ b, f b ⟶ g b) [∀ i, Epi (p i)] : Epi <| Sigma.map p := @@ -701,6 +705,7 @@ theorem sigmaComparison_map_desc [HasCoproduct f] [HasCoproduct fun b => G.obj ( ext j simp only [ι_comp_sigmaComparison_assoc, ← G.map_comp, colimit.ι_desc, Cofan.mk_ι_app] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `F.mapCone c` being limiting is the same as the induced fan being limiting. -/ def Fan.isLimitMapConeEquiv (F : C ⥤ D) {ι : Type*} (X : ι → C) (c : Fan X) : @@ -708,6 +713,7 @@ def Fan.isLimitMapConeEquiv (F : C ⥤ D) {ι : Type*} (X : ι → C) (c : Fan X (IsLimit.postcomposeHomEquiv Discrete.natIsoFunctor (F.mapCone c)).symm.trans <| IsLimit.equivIsoLimit (Cone.ext (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `F.mapCocone c` being colimiting is the same as the induced cofan being colimiting. -/ def Cofan.isColimitMapCoconeEquiv (F : C ⥤ D) {ι : Type*} (X : ι → C) (c : Cofan X) : @@ -802,6 +808,7 @@ def sigmaConstAdj [Limits.HasCoproducts.{v} C] (X : C) : section Unique +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The limit cone for the product over an index type with exactly one term. -/ @[simps] @@ -841,6 +848,7 @@ lemma productUniqueIso_inv_π [Unique β] (f : β → C) (b : β) : @[deprecated (since := "2026-06-30")] alias productUniqueIso_inv := productUniqueIso_inv_π +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism is the projection from a single object product. -/ def Fan.isLimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : @@ -850,6 +858,7 @@ def Fan.isLimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : simp · simpa [← cancel_mono e.hom] using hm default +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The colimit cocone for the coproduct over an index type with exactly one term. -/ @[simps] @@ -891,6 +900,7 @@ lemma ι_coproductUniqueIso_hom [Unique β] (f : β → C) (b : β) : @[deprecated (since := "2026-06-30")] alias coproductUniqueIso_hom := ι_coproductUniqueIso_hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism is the projection from a single object product. -/ def Cofan.isColimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : @@ -1016,6 +1026,7 @@ section Fubini variable {ι ι' : Type*} {X : ι → ι' → C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A product over products is a product indexed by a product. -/ def Fan.IsLimit.prod (c : ∀ i : ι, Fan (fun j : ι' ↦ X i j)) (hc : ∀ i : ι, IsLimit (c i)) @@ -1027,6 +1038,7 @@ def Fan.IsLimit.prod (c : ∀ i : ι, Fan (fun j : ι' ↦ X i j)) (hc : ∀ i : · refine Fan.IsLimit.hom_ext hc' _ _ fun i ↦ ?_ exact Fan.IsLimit.hom_ext (hc i) _ _ fun j ↦ (by simpa using hm (i, j)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A coproduct over coproducts is a coproduct indexed by a product. -/ def Cofan.IsColimit.prod (c : ∀ i : ι, Cofan (fun j : ι' ↦ X i j)) (hc : ∀ i : ι, IsColimit (c i)) @@ -1062,6 +1074,7 @@ def piEquivalenceFunctorDiscreteCompLim [HasProductsOfShape α C] : (piEquivalenceFunctorDiscrete α C).functor ⋙ lim ≅ Pi.functor _ := NatIso.ofComponents fun _ ↦ Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma piEquivalenceFunctorDiscreteCompLim_comp_functorπ [HasProductsOfShape α C] (a : α) : @@ -1104,6 +1117,7 @@ def piEquivalenceFunctorDiscreteCompColim [HasCoproductsOfShape α C] : (piEquivalenceFunctorDiscrete α C).functor ⋙ colim ≅ Sigma.functor _ := NatIso.ofComponents fun _ ↦ Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma piEquivalenceFunctorDiscreteCompColim_comp_functorι [HasCoproductsOfShape α C] (a : α) : diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean index 2e0766dd0ebf84..f8beea8ae6d7ad 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean @@ -197,7 +197,7 @@ end section -open Functor +open CategoryTheory.Functor variable (X : Type u₄) [Category.{v₄} X] @@ -326,7 +326,6 @@ def toCatCommSqOver : (X ⥤ F ⊡ G) ⥤ CatCommSqOver F G X where map_id := by intros; ext <;> simp map_comp := by intros; ext <;> simp -set_option backward.isDefEq.respectTransparency false in /-- Interpret a `CatCommSqOver` as a functor to the categorical pullback. -/ @[simps!] def CatCommSqOver.toFunctorToCategoricalPullback : @@ -346,6 +345,7 @@ def CatCommSqOver.toFunctorToCategoricalPullback : map_id := by intros; ext <;> simp map_comp := by intros; ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The universal property of categorical pullbacks, stated as an equivalence of categories between functors `X ⥤ (F ⊡ G)` and categorical commutative squares @@ -411,6 +411,7 @@ section variable {J K : X ⥤ F ⊡ G} (e₁ : J ⋙ π₁ F G ≅ K ⋙ π₁ F G) (e₂ : J ⋙ π₂ F G ≅ K ⋙ π₂ F G) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toCatCommSqOver_mapIso_mkNatIso_eq_mkIso (coh : @@ -456,7 +457,7 @@ end section Bifunctoriality namespace CatCommSqOver -open Functor +open CategoryTheory.Functor section transform @@ -465,7 +466,6 @@ variable {A₁ : Type u₄} {B₁ : Type u₅} {C₁ : Type u₆} {F₁ : A₁ ⥤ B₁} {G₁ : C₁ ⥤ B₁} set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Functorially transform a `CatCommSqOver F G X` by whiskering it with a `CatCospanTransform`. -/ @[simps!] @@ -608,7 +608,6 @@ variable [Category.{v₄} X] [Category.{v₅} Y] [Category.{v₆} Z] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- A functor `U : X ⥤ Y` (functorially) induces a functor `CatCommSqOver F G Y ⥤ CatCommSqOver F G X` by whiskering left the underlying categorical commutative square by U. -/ @@ -635,6 +634,7 @@ def precompose : map_id := by intros; ext <;> simp map_comp := by intros; ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (X) in /-- The construction `precompose` respects functor identities. -/ @@ -644,6 +644,7 @@ def precomposeObjId : NatIso.ofComponents fun _ => CatCommSqOver.mkIso (Functor.leftUnitor _) (Functor.leftUnitor _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The construction `precompose` respects functor composition. -/ @[simps!] @@ -655,6 +656,7 @@ def precomposeObjComp (U : X ⥤ Y) (V : Y ⥤ Z) : (Functor.associator _ _ _) (Functor.associator _ _ _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma precompose_map_whiskerLeft (U : X ⥤ Y) {V W : Y ⥤ Z} (α : V ⟶ W) : (precompose F G).map (whiskerLeft U α) = @@ -663,6 +665,7 @@ lemma precompose_map_whiskerLeft (U : X ⥤ Y) {V W : Y ⥤ Z} (α : V ⟶ W) : (precomposeObjComp F G U W).inv := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma precompose_map_whiskerRight {U V : X ⥤ Y} (α : U ⟶ V) (W : Y ⥤ Z) : (precompose F G).map (whiskerRight α W) = @@ -671,6 +674,7 @@ lemma precompose_map_whiskerRight {U V : X ⥤ Y} (α : U ⟶ V) (W : Y ⥤ Z) : (precomposeObjComp F G V W).inv := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma precompose_map_associator {T : Type u₇} [Category.{v₇} T] (U : X ⥤ Y) (V : Y ⥤ Z) (W : Z ⥤ T) : @@ -682,6 +686,7 @@ lemma precompose_map_associator {T : Type u₇} [Category.{v₇} T] (precomposeObjComp F G _ _).inv := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma precompose_map_leftUnitor (U : X ⥤ Y) : (precompose F G).map U.leftUnitor.hom = @@ -690,6 +695,7 @@ lemma precompose_map_leftUnitor (U : X ⥤ Y) : (Functor.rightUnitor _).hom := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma precompose_map_rightUnitor (U : X ⥤ Y) : (precompose F G).map U.rightUnitor.hom = @@ -706,6 +712,7 @@ variable {A₁ : Type u₄} {B₁ : Type u₅} {C₁ : Type u₆} [Category.{v₄} A₁] [Category.{v₅} B₁] [Category.{v₆} C₁] {F₁ : A₁ ⥤ B₁} {G₁ : C₁ ⥤ B₁} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical compatibility square between (the object components of) `precompose` and `transform`. @@ -742,6 +749,7 @@ lemma precomposeObjTransformObjSquare_iso_hom_naturality₂ whiskerLeft (transform Y |>.obj ψ) (precompose F₁ G₁ |>.map α) := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The square `precomposeObjTransformOBjSquare` respects identities. -/ lemma precomposeObjTransformObjSquare_iso_hom_id @@ -753,6 +761,7 @@ lemma precomposeObjTransformObjSquare_iso_hom_id (Functor.leftUnitor _).hom ≫ (Functor.rightUnitor _).inv := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The square `precomposeTransformSquare` respects compositions. -/ lemma precomposeObjTransformObjSquare_iso_hom_comp @@ -773,6 +782,7 @@ lemma precomposeObjTransformObjSquare_iso_hom_comp (Functor.associator _ _ _).hom := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical compatibility square between (the object components of) `transform` and `precompose`. @@ -796,6 +806,7 @@ instance transformObjPrecomposeObjSquare -- Compare the next 3 lemmas with the components of a strong natural transform -- of pseudofunctors +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The square `transformObjPrecomposeObjSquare` is itself natural. -/ lemma transformObjPrecomposeObjSquare_iso_hom_naturality₂ @@ -807,6 +818,7 @@ lemma transformObjPrecomposeObjSquare_iso_hom_naturality₂ whiskerLeft (precompose F G |>.obj U) (transform X |>.map η) := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The square `transformObjPrecomposeObjSquare` respects identities. -/ lemma transformObjPrecomposeObjSquare_iso_hom_id @@ -820,6 +832,7 @@ lemma transformObjPrecomposeObjSquare_iso_hom_id (precompose F G |>.obj U).rightUnitor.inv := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The square `transformPrecomposeSquare` respects compositions. -/ lemma transformPrecomposeObjSquare_iso_hom_comp diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/CatCospanTransform.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/CatCospanTransform.lean index 045bbdaf50a484..8aca996e37195e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/CatCospanTransform.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/CatCospanTransform.lean @@ -304,6 +304,7 @@ def baseIso : ψ.base ≅ ψ'.base where hom_inv_id := by simp [← category_comp_base] inv_hom_id := by simp [← category_comp_base] +set_option backward.isDefEq.respectTransparency.types false in omit [IsIso f] in lemma isIso_iff : IsIso f ↔ IsIso f.left ∧ IsIso f.base ∧ IsIso f.right where mp h := ⟨inferInstance, inferInstance, inferInstance⟩ @@ -376,6 +377,7 @@ lemma whisker_exchange : ψ ◁ θ ≫ η ▷ φ' = η ▷ φ ≫ ψ' ◁ θ := @[simp] lemma id_whiskerRight : 𝟙 ψ ▷ φ = 𝟙 _ := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma whiskerRight_id : η ▷ (.id _ _) = (ρ_ _).hom ≫ η ≫ (ρ_ _).inv := by cat_disch @@ -383,6 +385,7 @@ lemma whiskerRight_id : η ▷ (.id _ _) = (ρ_ _).hom ≫ η ≫ (ρ_ _).inv := @[simp, reassoc] lemma comp_whiskerRight : (η ≫ η') ▷ φ = η ▷ φ ≫ η' ▷ φ := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma whiskerRight_comp : @@ -392,6 +395,7 @@ lemma whiskerRight_comp : @[simp] lemma whiskerleft_id : ψ ◁ 𝟙 φ = 𝟙 _ := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma id_whiskerLeft : (.id _ _) ◁ η = (λ_ _).hom ≫ η ≫ (λ_ _).inv := by cat_disch @@ -399,12 +403,14 @@ lemma id_whiskerLeft : (.id _ _) ◁ η = (λ_ _).hom ≫ η ≫ (λ_ _).inv := @[simp, reassoc] lemma whiskerLeft_comp : ψ ◁ (θ ≫ θ') = (ψ ◁ θ) ≫ (ψ ◁ θ') := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma comp_whiskerLeft : (ψ.comp φ) ◁ γ = (α_ _ _ _).hom ≫ (ψ ◁ (φ ◁ γ)) ≫ (α_ _ _ _).inv := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma pentagon @@ -416,12 +422,14 @@ lemma pentagon (α_ (ψ.comp φ) τ σ).hom ≫ (α_ ψ φ (τ.comp σ)).hom := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma triangle : (α_ ψ (.id _ _) φ).hom ≫ ψ ◁ (λ_ φ).hom = (ρ_ ψ).hom ▷ φ := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma triangle_inv : diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Cospan.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Cospan.lean index 2cb2fbbda18ed7..5a20ba7ef6dfd1 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Cospan.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Cospan.lean @@ -170,11 +170,13 @@ def WalkingSpan.ext {F : WalkingSpan ⥤ C} {s t : Cocone F} (i : s.pt ≅ t.pt) · exact w₂ /-- `cospan f g` is the functor from the walking cospan hitting `f` and `g`. -/ +@[implicit_reducible] def cospan {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) : WalkingCospan ⥤ C := WidePullbackShape.wideCospan Z (fun j => WalkingPair.casesOn j X Y) fun j => WalkingPair.casesOn j f g /-- `span f g` is the functor from the walking span hitting `f` and `g`. -/ +@[implicit_reducible] def span {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) : WalkingSpan ⥤ C := WidePushoutShape.wideSpan X (fun j => WalkingPair.casesOn j Y Z) fun j => WalkingPair.casesOn j f g @@ -225,6 +227,7 @@ theorem cospan_map_id {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) (w : WalkingCospan theorem span_map_id {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) (w : WalkingSpan) : (span f g).map (WalkingSpan.Hom.id w) = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Every diagram indexing a pullback is naturally isomorphic (actually, equal) to a `cospan` -/ @[simps (rhsMd := default)] def diagramIsoCospan (F : WalkingCospan ⥤ C) : F ≅ cospan (F.map inl) (F.map inr) := @@ -232,6 +235,7 @@ def diagramIsoCospan (F : WalkingCospan ⥤ C) : F ≅ cospan (F.map inl) (F.map (fun j => eqToIso (by rcases j with (⟨⟩ | ⟨⟨⟩⟩) <;> rfl)) (by rintro (⟨⟩ | ⟨⟨⟩⟩) (⟨⟩ | ⟨⟨⟩⟩) f <;> cases f <;> simp) +set_option backward.isDefEq.respectTransparency.types false in /-- Every diagram indexing a pushout is naturally isomorphic (actually, equal) to a `span` -/ @[simps (rhsMd := default)] def diagramIsoSpan (F : WalkingSpan ⥤ C) : F ≅ span (F.map fst) (F.map snd) := @@ -241,6 +245,7 @@ def diagramIsoSpan (F : WalkingSpan ⥤ C) : F ≅ span (F.map fst) (F.map snd) variable {D : Type u₂} [Category.{v₂} D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor applied to a cospan is a cospan. -/ def cospanCompIso (F : C ⥤ D) {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) : @@ -286,6 +291,7 @@ theorem cospanCompIso_inv_app_one : (cospanCompIso F f g).inv.app WalkingCospan. end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor applied to a span is a span. -/ def spanCompIso (F : C ⥤ D) {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) : @@ -332,6 +338,7 @@ variable {X Y Z X' Y' Z' : C} (iX : X ≅ X') (iY : Y ≅ Y') (iZ : Z ≅ Z') section +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for natural transformations between cospans. -/ @[simps] def cospanHomMk {F G : WalkingCospan ⥤ C} @@ -342,6 +349,7 @@ def cospanHomMk {F G : WalkingCospan ⥤ C} app := by rintro (_ | _ | _); exacts [z, l, r] naturality := by rintro (_ | _ | _) (_ | _ | _) (_ | _); all_goals cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for natural isomorphisms between cospans. -/ @[simps!] def cospanIsoMk {F G : WalkingCospan ⥤ C} @@ -398,6 +406,7 @@ end section +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for natural transformations between spans. -/ @[simps] def spanHomMk {F G : WalkingSpan ⥤ C} @@ -408,6 +417,7 @@ def spanHomMk {F G : WalkingSpan ⥤ C} app := by rintro (_ | _ | _); exacts [z, l, r] naturality := by rintro (_ | _ | _) (_ | _ | _) (_ | _); all_goals cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for natural isomorphisms between spans. -/ @[simps!] def spanIsoMk {F G : WalkingSpan ⥤ C} diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/EquifiberedLimits.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/EquifiberedLimits.lean index 1a0d5a6aef30dd..ef8fb4ff40d08f 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/EquifiberedLimits.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/EquifiberedLimits.lean @@ -20,7 +20,7 @@ public section namespace CategoryTheory.NatTrans -open Limits Functor ObjectProperty +open Limits CategoryTheory.Functor ObjectProperty variable {J K C D ι : Type*} [Category* J] [Category* C] [Category* K] [Category* D] @@ -58,6 +58,7 @@ instance (F : C ⥤ D) [∀ a b : C, HasCoproductsOfShape (a ⟶ b) D] : simp [← NatTrans.naturality, reassoc_of% hm₁] · simpa [← NatTrans.comp_app] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open Over in instance (F : C ⥤ D) [∀ a b : C, HasProductsOfShape (a ⟶ b) D] : diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean index 842a249e0832c2..77f75ccb000cbe 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean @@ -35,6 +35,7 @@ namespace IsPullback variable {P X Y Z : C} {fst : P ⟶ X} {snd : P ⟶ Y} {f : X ⟶ Z} {g : Y ⟶ Z} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `c` is a limiting binary product cone, and we have a terminal object, then we have `IsPullback c.fst c.snd 0 0` @@ -429,6 +430,7 @@ namespace IsPushout variable {Z X Y P : C} {f : Z ⟶ X} {g : Z ⟶ Y} {inl : X ⟶ P} {inr : Y ⟶ P} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `c` is a colimiting binary coproduct cocone, and we have an initial object, then we have `IsPushout 0 0 c.inl c.inr` diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean index 31af169e54f790..a00b81356f4a30 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean @@ -162,6 +162,7 @@ variable (f : X ⟶ Z) (i : Z ⟶ W) [Mono i] instance hasPullback_of_right_factors_mono : HasPullback i (f ≫ i) := by simpa only [Category.id_comp] using hasPullback_of_comp_mono (𝟙 Z) f i +set_option backward.isDefEq.respectTransparency.types false in instance pullback_snd_iso_of_right_factors_mono : IsIso (pullback.snd i (f ≫ i)) := by have := limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono (𝟙 _) f i⟩ WalkingCospan.right @@ -174,6 +175,7 @@ attribute [local instance] hasPullback_of_right_iso instance hasPullback_of_left_factors_mono : HasPullback (f ≫ i) i := by simpa only [Category.id_comp] using hasPullback_of_comp_mono f (𝟙 Z) i +set_option backward.isDefEq.respectTransparency.types false in instance pullback_snd_iso_of_left_factors_mono : IsIso (pullback.fst (f ≫ i) i) := by have := limit.isoLimitCone_hom_π ⟨_, pullbackIsPullbackOfCompMono f (𝟙 _) i⟩ WalkingCospan.left diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Pasting.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Pasting.lean index df7be2d7bf6cf9..3c3806af27e6e2 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Pasting.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Pasting.lean @@ -76,6 +76,7 @@ local notation "f₁" => t₁.snd variable {t₁} {t₂} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given ``` @@ -105,6 +106,7 @@ def pasteHorizIsPullback (H : IsLimit t₂) (H' : IsLimit t₁) : IsLimit (t₂. variable (t₁) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given ``` @@ -267,6 +269,7 @@ local notation "i₃" => t₂.inr variable {t₁} {t₂} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given ``` @@ -297,6 +300,7 @@ def pasteHorizIsPushout (H : IsColimit t₁) (H' : IsColimit t₂) : variable (t₂) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackCone.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackCone.lean index a8488b4764950a..84ea2502d317f9 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackCone.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackCone.lean @@ -104,12 +104,14 @@ theorem π_app_left (c : PullbackCone f g) : c.π.app WalkingCospan.left = c.fst theorem π_app_right (c : PullbackCone f g) : c.π.app WalkingCospan.right = c.snd := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem condition_one (t : PullbackCone f g) : t.π.app WalkingCospan.one = t.fst ≫ f := by have w := t.π.naturality WalkingCospan.Hom.inl dsimp at w; simpa using w +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A pullback cone on `f` and `g` is determined by morphisms `fst : W ⟶ X` and `snd : W ⟶ Y` such that `fst ≫ f = snd ≫ g`. -/ @@ -291,6 +293,7 @@ def PullbackCone.ofCone {F : WalkingCospan ⥤ C} (t : Cone F) : pt := t.pt π := t.π ≫ (diagramIsoCospan F).hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A diagram `WalkingCospan ⥤ C` is isomorphic to some `PullbackCone.mk` after composing with `diagramIsoCospan`. -/ @@ -325,12 +328,14 @@ theorem ι_app_left (c : PushoutCocone f g) : c.ι.app WalkingSpan.left = c.inl -- This cannot be `@[simp]` because `c.inr` is reducibly defeq to the LHS. theorem ι_app_right (c : PushoutCocone f g) : c.ι.app WalkingSpan.right = c.inr := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem condition_zero (t : PushoutCocone f g) : t.ι.app WalkingSpan.zero = f ≫ t.inl := by have w := t.ι.naturality WalkingSpan.Hom.fst dsimp at w; simpa using w.symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A pushout cocone on `f` and `g` is determined by morphisms `inl : Y ⟶ W` and `inr : Z ⟶ W` such that `f ≫ inl = g ↠ inr`. -/ @@ -381,6 +386,7 @@ def ext {s t : PushoutCocone f g} (i : s.pt ≅ t.pt) (w₁ : s.inl ≫ i.hom = (w₂ : s.inr ≫ i.hom = t.inr := by cat_disch) : s ≅ t := WalkingSpan.ext i w₁ w₂ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism between a pushout cocone and the corresponding pushout cocone reconstructed using `PushoutCocone.mk`. -/ @@ -388,6 +394,7 @@ reconstructed using `PushoutCocone.mk`. -/ def eta (t : PushoutCocone f g) : t ≅ mk t.inl t.inr t.condition := PushoutCocone.ext (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- This is a slightly more convenient method to verify that a pushout cocone is a colimit cocone. It only asks for a proof of facts that carry any mathematical content -/ @@ -427,11 +434,13 @@ def IsColimit.desc {t : PushoutCocone f g} (ht : IsColimit t) {W : C} (h : Y ⟶ (w : f ≫ h = g ≫ k) : t.pt ⟶ W := ht.desc (PushoutCocone.mk _ _ w) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma IsColimit.inl_desc {t : PushoutCocone f g} (ht : IsColimit t) {W : C} (h : Y ⟶ W) (k : Z ⟶ W) (w : f ≫ h = g ≫ k) : inl t ≫ IsColimit.desc ht h k w = h := ht.fac _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma IsColimit.inr_desc {t : PushoutCocone f g} (ht : IsColimit t) {W : C} (h : Y ⟶ W) (k : Z ⟶ W) (w : f ≫ h = g ≫ k) : inr t ≫ IsColimit.desc ht h k w = k := @@ -444,6 +453,7 @@ def IsColimit.desc' {t : PushoutCocone f g} (ht : IsColimit t) {W : C} (h : Y (w : f ≫ h = g ≫ k) : { l : t.pt ⟶ W // inl t ≫ l = h ∧ inr t ≫ l = k } := ⟨IsColimit.desc ht h k w, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- This is a more convenient formulation to show that a `PushoutCocone` constructed using `PushoutCocone.mk` is a colimit cocone. -/ @@ -514,6 +524,7 @@ def PushoutCocone.ofCocone {F : WalkingSpan ⥤ C} (t : Cocone F) : pt := t.pt ι := (diagramIsoSpan F).inv ≫ t.ι +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A diagram `WalkingSpan ⥤ C` is isomorphic to some `PushoutCocone.mk` after composing with `diagramIsoSpan`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean index d6dffd0357608d..15de41ae028357 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/PullbackObjObj.lean @@ -293,6 +293,7 @@ end PushoutObjObj end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a bifunctor `F : C₁ ⥤ C₂ ⥤ C₃` to a category `C₃` which has pushouts, the Leibniz pushout (pushout-product) of `f₁ : X₁ ⟶ Y₁` in `C₁` and `f₂ : X₂ ⟶ Y₂` in `C₂` is the map @@ -521,6 +522,7 @@ end PullbackObjObj end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a bifunctor `G : C₁ᵒᵖ ⥤ C₃ ⥤ C₂` to a category `C₂` which has pullbacks, the Leibniz pullback (pullback-power) of `f₁ : X₁ ⟶ Y₁` in `C₁` and `f₃ : X₃ ⟶ Y₃` in `C₃` is the map diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean index 1b283d8e6d6d7b..3d27e96c8e7bf8 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean @@ -131,7 +131,6 @@ theorem IsCoreflexivePair.swap [IsCoreflexivePair f g] : IsCoreflexivePair g f : variable {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) -set_option backward.isDefEq.respectTransparency false in /-- For an adjunction `F ⊣ G` with counit `ε`, the pair `(FGε_B, ε_FGB)` is reflexive. -/ instance (B : D) : IsReflexivePair (F.map (G.map (adj.counit.app B))) (adj.counit.app (F.obj (G.obj B))) := @@ -538,6 +537,9 @@ open WalkingReflexivePair WalkingReflexivePair.Hom variable (F : WalkingReflexivePair ⥤ C) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Forgetting the reflexion yields an equivalence between cocones over a bundled reflexive pair and coforks on the underlying parallel pair. -/ @[simps! functor_obj_pt inverse_obj_pt] @@ -546,6 +548,7 @@ def reflexiveCoforkEquivCofork : (Functor.Final.coconesEquiv _ F).symm.trans (Cocone.precomposeEquivalence (diagramIsoParallelPair (WalkingParallelPair.inclusionWalkingReflexivePair ⋙ F))) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma reflexiveCoforkEquivCofork_functor_obj_π (G : ReflexiveCofork F) : @@ -554,6 +557,7 @@ lemma reflexiveCoforkEquivCofork_functor_obj_π (G : ReflexiveCofork F) : rw [ReflexiveCofork.π, Cofork.π] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma reflexiveCoforkEquivCofork_inverse_obj_π @@ -565,6 +569,7 @@ lemma reflexiveCoforkEquivCofork_inverse_obj_π rw [Functor.Final.extendCocone_obj_ι_app' (Y := .one) (f := 𝟙 zero)] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence between reflexive coforks and coforks sends a reflexive cofork to its underlying cofork. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean b/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean index c0db8284a35a4c..fcc1a31a1736ff 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/RegularMono.lean @@ -72,6 +72,7 @@ attribute [reassoc] RegularMono.w lemma RegularMono.mono {f : X ⟶ Y} (h : RegularMono f) : Mono f := mono_of_isLimit_fork h.isLimit +set_option backward.isDefEq.respectTransparency.types false in /-- Every isomorphism is a regular monomorphism. -/ def RegularMono.ofIso (e : X ≅ Y) : RegularMono e.hom where Z := Y @@ -322,6 +323,7 @@ attribute [reassoc] RegularEpi.w lemma RegularEpi.epi (f : X ⟶ Y) (h : RegularEpi f) : Epi f := epi_of_isColimit_cofork h.isColimit +set_option backward.isDefEq.respectTransparency.types false in /-- Every isomorphism is a regular epimorphism. -/ def RegularEpi.ofIso (e : X ≅ Y) : RegularEpi e.hom where W := X @@ -558,6 +560,7 @@ def RegularEpi.desc' {W : C} {f : X ⟶ Y} (hf : RegularEpi f) (k : X ⟶ W) { l : Y ⟶ W // f ≫ l = k } := Cofork.IsColimit.desc' hf.isColimit _ h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The second leg of a pushout cocone is a regular epimorphism if the right component is too. diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean b/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean index ec42ce0eba4518..187326f85d5f6c 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean @@ -219,6 +219,7 @@ variable [HasZeroMorphisms C] [HasFiniteBiproducts C] [∀ n, Epi (f n)] attribute [local instance] hasBinaryBiproducts_of_finite_biproducts +set_option backward.isDefEq.respectTransparency.types false in lemma functorMap_epi (n : ℕ) : Epi (functorMap f n) := by rw [functorMap, Pi.map_eq_prod_map (P := fun m : ℕ ↦ m < n + 1)] apply +allowSynthFailures epi_comp diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean b/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean index 7dc12966097b37..d433e7fe2cf4a2 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean @@ -98,6 +98,9 @@ def colimitTypeRelEquivOrbitRelQuotient : left_inv := fun x => Quot.inductionOn x (fun _ ↦ rfl) right_inv := fun x => Quot.inductionOn x (fun _ ↦ rfl) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The colimit of `J : SingleObj G ⥤ Type u` is equivalent to the quotient of `J.obj (SingleObj.star G)` by the induced action. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SplitCoequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/SplitCoequalizer.lean index dbda39cafb53e1..b25248d27debf8 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SplitCoequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SplitCoequalizer.lean @@ -107,6 +107,7 @@ def IsSplitCoequalizer.asCofork {Z : C} {h : Y ⟶ Z} (t : IsSplitCoequalizer f theorem IsSplitCoequalizer.asCofork_π {Z : C} {h : Y ⟶ Z} (t : IsSplitCoequalizer f g h) : t.asCofork.π = h := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The cofork induced by a split coequalizer is a coequalizer, justifying the name. In some cases it diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean index e9605bfa71774f..3a77c274e2eb22 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SplitEqualizer.lean @@ -111,6 +111,7 @@ def IsSplitEqualizer.asFork {W : C} {h : W ⟶ X} (t : IsSplitEqualizer f g h) : theorem IsSplitEqualizer.asFork_ι {W : C} {h : W ⟶ X} (t : IsSplitEqualizer f g h) : t.asFork.ι = h := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The fork induced by a split equalizer is an equalizer, justifying the name. In some cases it diff --git a/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean index 45ca235dc15ccc..51580dfccb2e3c 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean @@ -149,6 +149,7 @@ theorem parallelFamily_obj_one : (parallelFamily f).obj one = Y := theorem parallelFamily_map_left {j : J} : (parallelFamily f).map (line j) = f j := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Every functor indexing a wide (co)equalizer is naturally isomorphic (actually, equal) to a `parallelFamily` -/ @[simps!] @@ -250,10 +251,16 @@ theorem Cotrident.π_ofπ [Nonempty J] {P : C} (π : Y ⟶ P) (w : ∀ j₁ j₂ (Cotrident.ofπ π w).π = π := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] theorem Trident.condition (j₁ j₂ : J) (t : Trident f) : t.ι ≫ f j₁ = t.ι ≫ f j₂ := by rw [t.app_zero, t.app_zero] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] theorem Cotrident.condition (j₁ j₂ : J) (t : Cotrident f) : f j₁ ≫ t.π = f j₂ ≫ t.π := by rw [t.app_one, t.app_one] @@ -441,6 +448,7 @@ def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> cat_disch) naturality := by rintro _ _ (_ | _) <;> cat_disch } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on @@ -630,6 +638,7 @@ theorem wideCoequalizer.condition (j₁ j₂ : J) : f j₁ ≫ wideCoequalizer.π f = f j₂ ≫ wideCoequalizer.π f := Cotrident.condition j₁ j₂ <| colimit.cocone <| parallelFamily f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The cotrident built from `wideCoequalizer.π f` is colimiting. -/ def wideCoequalizerIsWideCoequalizer [Nonempty J] : diff --git a/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean b/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean index 803363327cbac3..d0f46c1e71d578 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean @@ -36,12 +36,14 @@ namespace CategoryTheory.Limits variable (J : Type w) /-- A wide pullback shape for any type `J` can be written simply as `Option J`. -/ +@[implicit_reducible] def WidePullbackShape := Option J instance : Inhabited (WidePullbackShape J) where default := none /-- A wide pushout shape for any type `J` can be written simply as `Option J`. -/ +@[implicit_reducible] def WidePushoutShape := Option J instance : Inhabited (WidePushoutShape J) where @@ -85,6 +87,7 @@ meta def evalCasesBash : TacticM Unit := do attribute [local aesop safe tactic (rule_sets := [CategoryTheory])] evalCasesBash +set_option backward.isDefEq.respectTransparency.types false in instance subsingleton_hom : Quiver.IsThin (WidePullbackShape J) := fun _ _ => by constructor intro a b @@ -102,6 +105,7 @@ theorem hom_id (X : WidePullbackShape J) : Hom.id X = 𝟙 X := variable {C : Type u} [Category.{v} C] +set_option backward.isDefEq.respectTransparency.types false in /-- Construct a functor out of the wide pullback shape given a J-indexed collection of arrows to a fixed object. -/ @@ -113,12 +117,14 @@ def wideCospan (B : C) (objs : J → C) (arrows : ∀ j : J, objs j ⟶ B) : Wid · apply 𝟙 _ · exact arrows j +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Every diagram is naturally isomorphic (actually, equal) to a `wideCospan` -/ def diagramIsoWideCospan (F : WidePullbackShape J ⥤ C) : F ≅ wideCospan (F.obj none) (fun j => F.obj (some j)) fun j => F.map (Hom.term j) := NatIso.ofComponents fun j => eqToIso <| by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Construct a cone over a wide cospan. -/ @[simps] @@ -133,6 +139,7 @@ def mkCone {F : WidePullbackShape J ⥤ C} {X : C} (f : X ⟶ F.obj none) (π : naturality := fun j j' f => by cases j <;> cases j' <;> cases f <;> simp [w] } } +set_option backward.isDefEq.respectTransparency.types false in /-- Wide pullback diagrams of equivalent index types are equivalent. -/ def equivalenceOfEquiv (J' : Type w') (h : J ≃ J') : WidePullbackShape J ≌ WidePullbackShape J' where @@ -212,6 +219,7 @@ meta def evalCasesBash' : TacticM Unit := do attribute [local aesop safe tactic (rule_sets := [CategoryTheory])] evalCasesBash' +set_option backward.isDefEq.respectTransparency.types false in instance subsingleton_hom : Quiver.IsThin (WidePushoutShape J) := fun _ _ => by constructor intro a b @@ -243,12 +251,14 @@ def wideSpan (B : C) (objs : J → C) (arrows : ∀ j : J, B ⟶ objs j) : WideP · cases g simp only [hom_id, Category.comp_id]; congr +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Every diagram is naturally isomorphic (actually, equal) to a `wideSpan` -/ def diagramIsoWideSpan (F : WidePushoutShape J ⥤ C) : F ≅ wideSpan (F.obj none) (fun j => F.obj (some j)) fun j => F.map (Hom.init j) := NatIso.ofComponents fun j => eqToIso <| by cases j; repeat rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Construct a cocone over a wide span. -/ @[simps] @@ -263,6 +273,7 @@ def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : naturality := fun j j' f => by cases j <;> cases j' <;> cases f <;> simp [w] } } +set_option backward.isDefEq.respectTransparency.types false in /-- Wide pushout diagrams of equivalent index types are equivalent. -/ def equivalenceOfEquiv (J' : Type w') (h : J ≃ J') : WidePushoutShape J ≌ WidePushoutShape J' where functor := wideSpan none (fun j => some (h j)) fun j => Hom.init (h j) @@ -389,6 +400,7 @@ def π (s : WidePullbackCone f) (i : ι) : s.pt ⟶ Y i := def base (s : WidePullbackCone f) : s.pt ⟶ X := (Cone.π s).app none +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma condition (s : WidePullbackCone f) (i : ι) : s.π i ≫ f i = s.base := by diff --git a/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean b/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean index 19cba70e5635d5..e0edf1ada4cfeb 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean @@ -226,7 +226,7 @@ morphisms for some other reason, for example from additivity. Library code that the `HasZeroMorphisms` instances will not be definitionally equal. For this reason library code should generally ask for an instance of `HasZeroMorphisms` separately, even if it already asks for an instance of `HasZeroObject`. -/ -@[implicit_reducible] +@[instance_reducible] def IsZero.hasZeroMorphisms {O : C} (hO : IsZero O) : HasZeroMorphisms C where zero X Y := { zero := hO.from_ X ≫ hO.to_ Y } zero_comp X {Y Z} f := by @@ -254,7 +254,7 @@ morphisms for some other reason, for example from additivity. Library code that the `HasZeroMorphisms` instances will not be definitionally equal. For this reason library code should generally ask for an instance of `HasZeroMorphisms` separately, even if it already asks for an instance of `HasZeroObject`. -/ -@[implicit_reducible] +@[instance_reducible] def zeroMorphismsOfZeroObject : HasZeroMorphisms C where zero X _ := { zero := (default : X ⟶ 0) ≫ default } zero_comp X {Y Z} f := by @@ -547,6 +547,7 @@ def imageZero {X Y : C} : image (0 : X ⟶ Y) ≅ 0 := def imageZero' {X Y : C} {f : X ⟶ Y} (h : f = 0) [HasImage f] : image f ≅ 0 := image.eqToIso h ≪≫ imageZero +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem image.ι_zero {X Y : C} [HasImage (0 : X ⟶ Y)] : image.ι (0 : X ⟶ Y) = 0 := by diff --git a/Mathlib/CategoryTheory/Limits/Sifted.lean b/Mathlib/CategoryTheory/Limits/Sifted.lean index e8151ee9fabd95..7def6ebd69f2af 100644 --- a/Mathlib/CategoryTheory/Limits/Sifted.lean +++ b/Mathlib/CategoryTheory/Limits/Sifted.lean @@ -41,7 +41,7 @@ universe w v v₁ v₂ u u₁ u₂ namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor section @@ -98,8 +98,8 @@ instance [IsSifted C] : IsConnected C := · simpa using Zag.of_inv X.hom.snd · rfl) -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- A category with binary coproducts is sifted or empty. -/ instance [HasBinaryCoproducts C] : IsSiftedOrEmpty C := by constructor @@ -162,8 +162,8 @@ open scoped MonoidalCategory.ExternalProduct variable (X Y : C ⥤ Type u) -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- Through the isomorphisms `PreservesColimit₂.isoColimitUncurryWhiskeringLeft₂` and `externalProductCompDiagIso`, the comparison map `colimit.pre (X ⊠ Y) (diag C)` identifies with the product comparison map for the colimit functor. -/ diff --git a/Mathlib/CategoryTheory/Limits/Types/ColimitType.lean b/Mathlib/CategoryTheory/Limits/Types/ColimitType.lean index 54238b85ff83cf..609ed2effeac3b 100644 --- a/Mathlib/CategoryTheory/Limits/Types/ColimitType.lean +++ b/Mathlib/CategoryTheory/Limits/Types/ColimitType.lean @@ -89,7 +89,6 @@ def precompose (c : CoconeTypes.{w₁} F) {G : J ⥤ Type w₀'} (app : ∀ j, G rw [Function.comp_assoc, naturality, ← Function.comp_assoc, ι_naturality] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given `F : J ⥤ w₀`, `c : F.CoconeTypes` and `G : J' ⥤ J`, this is the induced cocone in `(G ⋙ F).CoconeTypes`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/Types/Filtered.lean b/Mathlib/CategoryTheory/Limits/Types/Filtered.lean index 2d406b4c347a5b..f3bc8cce5ba357 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Filtered.lean @@ -83,6 +83,14 @@ noncomputable def isColimitOf (t : Cocone F) (hsurj : ∀ x : t.pt, ∃ i xi, x variable [IsFilteredOrEmpty J] +#adaptation_note +/-- +Note that the body of `isColimitOf'` locally enables `respectTransparency true` for a subterm. +The underlying reason is that there is one corner case where `respectTransparency true` unfolds +*more*, and we need that here. +The intended fix is to get rid of the outer `respectTransparency false`. After that, the inner +`respectTransparency true` is redundant and can be removed, too. +-/ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- Recognizing filtered colimits of types. The injectivity condition here is @@ -92,7 +100,8 @@ noncomputable def isColimitOf' (t : Cocone F) (hsurj : ∀ x : t.pt, ∃ i xi, x IsColimit t := isColimitOf _ _ hsurj (fun i j xi xj h ↦ by obtain ⟨k, g, hg⟩ := hinj (IsFiltered.max i j) (F.map (IsFiltered.leftToMax i j) xi) - (F.map (IsFiltered.rightToMax i j) xj) (by simp_all [Cocone.w_apply]) + (F.map (IsFiltered.rightToMax i j) xj) + (by set_option backward.isDefEq.respectTransparency true in simp_all) exact ⟨k, IsFiltered.leftToMax i j ≫ g, IsFiltered.rightToMax i j ≫ g, by simpa using hg⟩) protected theorem rel_equiv : _root_.Equivalence (FilteredColimit.Rel.{v, u} F) where diff --git a/Mathlib/CategoryTheory/Limits/Types/Limits.lean b/Mathlib/CategoryTheory/Limits/Types/Limits.lean index ebf1171a01a58c..e1fa0e1bf43cd9 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Limits.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Limits.lean @@ -112,6 +112,7 @@ noncomputable def limitCone : Cone F where π := { app j := ↾fun u => ((equivShrink F.sections).symm u).val j } +set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma limitCone_pt_ext {x y : (limitCone F).pt} (w : (equivShrink F.sections).symm x = (equivShrink F.sections).symm y) : x = y := by diff --git a/Mathlib/CategoryTheory/Limits/Types/Multicoequalizer.lean b/Mathlib/CategoryTheory/Limits/Types/Multicoequalizer.lean index ce78a0adc36eeb..11c376d34aa76d 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Multicoequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Multicoequalizer.lean @@ -35,6 +35,7 @@ namespace CategoryTheory.Functor.CoconeTypes open Limits +set_option backward.isDefEq.respectTransparency.types false in lemma isMulticoequalizer_iff {J : MultispanShape.{w, w'}} {d : MultispanIndex J (Type u)} (c : d.multispan.CoconeTypes) : c.IsColimit ↔ @@ -98,6 +99,7 @@ noncomputable def isColimitOfMulticoequalizerDiagram obtain ⟨i, hi⟩ := hx exact ⟨i, ⟨x, hi⟩, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Let `X : Type u`, `A : Set X`, `U : ι → Set X` and `V : ι → ι → Set X` such that `MulticoequalizerDiagram A U V` holds, then in the category of types, diff --git a/Mathlib/CategoryTheory/Limits/Types/Products.lean b/Mathlib/CategoryTheory/Limits/Types/Products.lean index 84825a5671be74..812c6398819220 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Products.lean @@ -217,6 +217,7 @@ namespace Small variable {J : Type v} (F : J → Type u) [Small.{u} J] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A variant of `productLimitCone` using a `Small` hypothesis rather than a function to `Type`. @@ -233,18 +234,21 @@ noncomputable def productLimitCone : uniq := fun s m w => ConcreteCategory.hom_ext _ _ fun x => Shrink.ext (funext fun j => by simpa using! ConcreteCategory.congr_hom (w ⟨j⟩) x) } +set_option backward.isDefEq.respectTransparency.types false in /-- The categorical product in `Type u` indexed in `Type v` is the type-theoretic product `Π j, F j`, after shrinking back to `Type u`. -/ noncomputable def productIso : (∏ᶜ F : Type u) ≅ Shrink (∀ j, F j) := limit.isoLimitCone (productLimitCone.{v, u} F) +set_option backward.isDefEq.respectTransparency.types false in @[elementwise (attr := simp)] theorem productIso_hom_comp_eval (j : J) : (productIso.{v, u} F).hom ≫ (↾fun f => (equivShrink (∀ j, F j)).symm f j) = Pi.π F j := limit.isoLimitCone_hom_π (productLimitCone.{v, u} F) ⟨j⟩ +set_option backward.isDefEq.respectTransparency.types false in @[elementwise (attr := simp)] theorem productIso_inv_comp_π (j : J) : (productIso.{v, u} F).inv ≫ Pi.π F j = diff --git a/Mathlib/CategoryTheory/Limits/Types/Yoneda.lean b/Mathlib/CategoryTheory/Limits/Types/Yoneda.lean index 09e4f33ecaf439..085443559d8249 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Yoneda.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Yoneda.lean @@ -22,7 +22,7 @@ universe v u namespace CategoryTheory.Limits -open Functor Opposite +open CategoryTheory.Functor Opposite section @@ -89,9 +89,9 @@ noncomputable def limitCompCoyonedaIsoCone (F : J ⥤ C) (X : C) : inv := ↾fun t ↦ limit.lift _ (Types.coneOfSection (s := t.app) <| by simp [Functor.sections, ← t.naturality]) ⟨⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp←] comp_apply in -set_option backward.isDefEq.respectTransparency false in variable (J) (C) in /-- A cone on `F` with cone point `X` is the same as an element of `lim Hom(X, F·)`, naturally in `F` and `X`. -/ diff --git a/Mathlib/CategoryTheory/Limits/VanKampen.lean b/Mathlib/CategoryTheory/Limits/VanKampen.lean index 2e0f4a851ceddb..877f75e8f1c146 100644 --- a/Mathlib/CategoryTheory/Limits/VanKampen.lean +++ b/Mathlib/CategoryTheory/Limits/VanKampen.lean @@ -419,6 +419,7 @@ end reflective section Initial +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem hasStrictInitial_of_isUniversal [HasInitial C] (H : IsUniversalColimit (BinaryCofan.mk (𝟙 (⊥_ C)) (𝟙 (⊥_ C)))) : HasStrictInitialObjects C := @@ -524,6 +525,7 @@ theorem BinaryCofan.isVanKampen_mk {X Y : C} (c : BinaryCofan X Y) exact (BinaryCofan.mk _ _).isColimitCompRightIso e₂.hom ((BinaryCofan.mk _ _).isColimitCompLeftIso e₁.hom (h₂ f)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem BinaryCofan.mono_inr_of_isVanKampen [HasInitial C] {X Y : C} {c : BinaryCofan X Y} (h : IsVanKampenColimit c) : Mono c.inr := by @@ -535,6 +537,7 @@ theorem BinaryCofan.mono_inr_of_isVanKampen [HasInitial C] {X Y : C} {c : Binary dsimp infer_instance)).some +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem BinaryCofan.isPullback_initial_to_of_isVanKampen [HasInitial C] {c : BinaryCofan X Y} (h : IsVanKampenColimit c) : IsPullback (initial.to _) (initial.to _) c.inl c.inr := by @@ -681,6 +684,7 @@ theorem isVanKampenColimit_extendCofan {n : ℕ} (f : Fin (n + 1) → C) BinaryCofan.ι_app_right, BinaryCofan.mk_inr, colimit.ι_desc, Discrete.natTrans_app] using! t₁'.paste_horiz (t₂' ⟨WalkingPair.right⟩) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem isPullback_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {X : ι → C} {c : Cofan X} (hc : IsVanKampenColimit c) (i j : ι) [DecidableEq ι] : @@ -748,6 +752,7 @@ variable {ι ι' : Type*} {S : C} variable {B : C} {X : ι → C} {a : Cofan X} (hau : IsUniversalColimit a) (f : ∀ i, X i ⟶ S) (u : a.pt ⟶ S) (v : B ⟶ S) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in include hau in /-- Pullbacks distribute over universal coproducts on the left: This is the isomorphism @@ -812,6 +817,7 @@ lemma IsUniversalColimit.isPullback_of_isColimit_left {d : Cofan P} (hd : IsColi end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in include hau in /-- Pullbacks distribute over universal coproducts on the right: This is the isomorphism diff --git a/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean b/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean index d5a8ae9fbe39b0..e82cdda773d0ae 100644 --- a/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean +++ b/Mathlib/CategoryTheory/Limits/Weighted/HasWeightedLimit.lean @@ -177,7 +177,7 @@ noncomputable def isLimitWeightedLimCone : (W.weightedLimCone F).IsLimit := limit.isLimit _ -@[reassoc (attr := simp)] +@[reassoc, simp] -- `simp` can prove the `reassoc` version lemma isLimitWeightedLimCone_fac {Z} (π) (hπ) ⦃j : J⦄ (x : W.obj j) : (W.isLimitWeightedLimCone F).lift (Z := Z) π hπ ≫ W.weightedLimObjObjπ F x = π x := (W.isLimitWeightedLimCone F).fac .. diff --git a/Mathlib/CategoryTheory/Limits/Yoneda.lean b/Mathlib/CategoryTheory/Limits/Yoneda.lean index 37f1d7b5e99e13..7bdb06f5b49654 100644 --- a/Mathlib/CategoryTheory/Limits/Yoneda.lean +++ b/Mathlib/CategoryTheory/Limits/Yoneda.lean @@ -33,6 +33,9 @@ namespace Coyoneda variable {C : Type u} [Category.{v} C] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The colimit cocone over `coyoneda.obj X`, with cocone point `PUnit`. -/ @[simps] @@ -77,7 +80,6 @@ section variable {J : Type w} [Category.{t} J] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The cone of `F` corresponding to an element in `(F ⋙ yoneda.obj X).sections`. -/ @[simps] def Limits.coneOfSectionCompYoneda (F : J ⥤ Cᵒᵖ) (X : C) @@ -126,7 +128,6 @@ noncomputable def Limits.Cocone.isColimitYonedaEquiv {F : J ⥤ C} (c : Cocone F right_inv _ := by ext; apply Subsingleton.elim set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The cone of `F` corresponding to an element in `(F ⋙ coyoneda.obj X).sections`. -/ @[simps] def Limits.coneOfSectionCompCoyoneda (F : J ⥤ C) (X : Cᵒᵖ) diff --git a/Mathlib/CategoryTheory/Localization/Adjunction.lean b/Mathlib/CategoryTheory/Localization/Adjunction.lean index 9c6875b1f54b96..4e534d7f79f0a9 100644 --- a/Mathlib/CategoryTheory/Localization/Adjunction.lean +++ b/Mathlib/CategoryTheory/Localization/Adjunction.lean @@ -27,7 +27,7 @@ induced adjunction `Adjunction.localization L₁ W₁ L₂ W₂ G' F' : G' ⊣ F namespace CategoryTheory -open Localization Category Functor +open Localization Category CategoryTheory.Functor namespace Adjunction @@ -68,7 +68,6 @@ noncomputable def η : F' ⋙ G' ⟶ 𝟭 D₂ := by Lifting.mk (CatCommSq.hComp F G L₂ L₁ L₂ F' G').iso.symm exact liftNatTrans L₂ W₂ ((F ⋙ G) ⋙ L₂) L₂ (F' ⋙ G') (𝟭 D₂) (whiskerRight adj.counit L₂) -set_option backward.isDefEq.respectTransparency false in lemma η_app (X₂ : C₂) : (η adj L₁ L₂ W₂ G' F').app (L₂.obj X₂) = G'.map ((CatCommSq.iso F L₂ L₁ F').inv.app X₂) ≫ @@ -81,7 +80,6 @@ lemma η_app (X₂ : C₂) : end Localization -set_option backward.isDefEq.respectTransparency false in /-- If `adj : G ⊣ F` is an adjunction between two categories `C₁` and `C₂` that are equipped with localization functors `L₁ : C₁ ⥤ D₁` and `L₂ : C₂ ⥤ D₂` with respect to `W₁ : MorphismProperty C₁` and `W₂ : MorphismProperty C₂`, and that @@ -133,7 +131,6 @@ lemma localization_counit_app (X₂ : C₂) : end -set_option backward.isDefEq.respectTransparency false in include adj in lemma isLocalization [F.Full] [F.Faithful] : G.IsLocalization ((MorphismProperty.isomorphisms C₂).inverseImage G) := by diff --git a/Mathlib/CategoryTheory/Localization/Bifunctor.lean b/Mathlib/CategoryTheory/Localization/Bifunctor.lean index 4eba690853dd4f..931054baa53fff 100644 --- a/Mathlib/CategoryTheory/Localization/Bifunctor.lean +++ b/Mathlib/CategoryTheory/Localization/Bifunctor.lean @@ -33,7 +33,7 @@ which lifts `F`. namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor variable {C₁ C₂ D₁ D₂ E E' : Type*} [Category* C₁] [Category* C₂] [Category* D₁] [Category* D₂] [Category* E] [Category* E'] @@ -69,7 +69,7 @@ variable (W₁ : MorphismProperty C₁) (W₂ : MorphismProperty C₂) /-- If `Lifting₂ L₁ L₂ W₁ W₂ F F'` holds, then `Lifting L₂ W₂ (F.obj X₁) (F'.obj (L₁.obj X₁))` holds for any `X₁ : C₁`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Lifting₂.fst (X₁ : C₁) : Lifting L₂ W₂ (F.obj X₁) (F'.obj (L₁.obj X₁)) where iso := ((evaluation _ _).obj X₁).mapIso (Lifting₂.iso L₁ L₂ W₁ W₂ F F') @@ -79,7 +79,7 @@ noncomputable instance Lifting₂.flip : Lifting₂ L₂ L₁ W₂ W₁ F.flip F /-- If `Lifting₂ L₁ L₂ W₁ W₂ F F'` holds, then `Lifting L₁ W₁ (F.flip.obj X₂) (F'.flip.obj (L₂.obj X₂))` holds for any `X₂ : C₂`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Lifting₂.snd (X₂ : C₂) : Lifting L₁ W₁ (F.flip.obj X₂) (F'.flip.obj (L₂.obj X₂)) := Lifting₂.fst L₂ L₁ W₂ W₁ F.flip F'.flip X₂ @@ -164,6 +164,7 @@ noncomputable def lift₂NatTrans (τ : F₁ ⟶ F₂) : F₁' ⟶ F₂' := (liftNatTrans (L₁.prod L₂) (W₁.prod W₂) (uncurry.obj F₁) (uncurry.obj F₂) (uncurry.obj F₁') (uncurry.obj F₂') (uncurry.map τ)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem lift₂NatTrans_app_app (τ : F₁ ⟶ F₂) (X₁ : C₁) (X₂ : C₂) : diff --git a/Mathlib/CategoryTheory/Localization/Bousfield.lean b/Mathlib/CategoryTheory/Localization/Bousfield.lean index 83b745e18c0edf..71692352be9d6a 100644 --- a/Mathlib/CategoryTheory/Localization/Bousfield.lean +++ b/Mathlib/CategoryTheory/Localization/Bousfield.lean @@ -213,6 +213,7 @@ section variable {F : C ⥤ D} {G : D ⥤ C} (adj : G ⊣ F) [F.Full] [F.Faithful] include adj +set_option backward.isDefEq.respectTransparency.types false in lemma isLocal_adj_unit_app (X : D) : isLocal (· ∈ Set.range F.obj) (adj.unit.app X) := by rintro _ ⟨Y, rfl⟩ convert! @@ -221,7 +222,6 @@ lemma isLocal_adj_unit_app (X : D) : isLocal (· ∈ Set.range F.obj) (adj.unit. dsimp [Adjunction.homEquiv] aesop -set_option backward.isDefEq.respectTransparency false in lemma isLocal_iff_isIso_map {X Y : D} (f : X ⟶ Y) : isLocal (· ∈ Set.range F.obj) f ↔ IsIso (G.map f) := by have := adj.unit.naturality f @@ -248,6 +248,7 @@ section variable {F : C ⥤ D} {G : D ⥤ C} (adj : G ⊣ F) [G.Full] [G.Faithful] include adj +set_option backward.isDefEq.respectTransparency.types false in lemma isColocal_adj_counit_app (X : C) : isColocal (· ∈ Set.range G.obj) (adj.counit.app X) := by rintro _ ⟨Y, rfl⟩ convert! @@ -256,7 +257,6 @@ lemma isColocal_adj_counit_app (X : C) : isColocal (· ∈ Set.range G.obj) (adj dsimp [Adjunction.homEquiv] cat_disch -set_option backward.isDefEq.respectTransparency false in lemma isColocal_iff_isIso_map {X Y : C} (f : X ⟶ Y) : isColocal (· ∈ Set.range G.obj) f ↔ IsIso (F.map f) := by have := adj.counit.naturality f diff --git a/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean b/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean index 964a49b51ab50c..45dceb45b26cac 100644 --- a/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean +++ b/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean @@ -528,6 +528,7 @@ which belongs to `W`. -/ noncomputable def Qinv {X Y : C} (s : X ⟶ Y) (hs : W s) : (Q W).obj Y ⟶ (Q W).obj X := homMk (ofInv s hs) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma Q_map_comp_Qinv {X Y Y' : C} (f : X ⟶ Y') (s : Y ⟶ Y') (hs : W s) : (Q W).map f ≫ Qinv s hs = homMk (mk f s hs) := by @@ -691,7 +692,6 @@ lemma map_eq {W} {X Y : C} (φ : W.LeftFraction X Y) (L : C ⥤ D) [L.IsLocaliza φ.map L (Localization.inverts L W) = L.map φ.f ≫ (Localization.isoOfHom L W φ.s φ.hs).inv := rfl -set_option backward.isDefEq.respectTransparency false in lemma map_compatibility {W} {X Y : C} (φ : W.LeftFraction X Y) {E : Type*} [Category* E] (L₁ : C ⥤ D) (L₂ : C ⥤ E) [L₁.IsLocalization W] [L₂.IsLocalization W] : @@ -962,6 +962,7 @@ section variable [W.HasRightCalculusOfFractions] +set_option backward.isDefEq.respectTransparency.types false in lemma Localization.exists_rightFraction {X Y : C} (f : L.obj X ⟶ L.obj Y) : ∃ (φ : W.RightFraction X Y), f = φ.map L (Localization.inverts L W) := by obtain ⟨φ, eq⟩ := Localization.exists_leftFraction L.op W.op f.op diff --git a/Mathlib/CategoryTheory/Localization/CalculusOfFractions/OfAdjunction.lean b/Mathlib/CategoryTheory/Localization/CalculusOfFractions/OfAdjunction.lean index 5f5427b56138ea..b93da96222bea9 100644 --- a/Mathlib/CategoryTheory/Localization/CalculusOfFractions/OfAdjunction.lean +++ b/Mathlib/CategoryTheory/Localization/CalculusOfFractions/OfAdjunction.lean @@ -36,7 +36,6 @@ namespace Adjunction variable {C₁ C₂ : Type*} [Category* C₁] [Category* C₂] {G : C₁ ⥤ C₂} {F : C₂ ⥤ C₁} -set_option backward.isDefEq.respectTransparency false in lemma hasLeftCalculusOfFractions (adj : G ⊣ F) (W : MorphismProperty C₁) [W.IsMultiplicative] (hW : W.IsInvertedBy G) (hW' : (W.functorCategory C₁) adj.unit) : W.HasLeftCalculusOfFractions where @@ -91,14 +90,12 @@ lemma isLocalization_rightAdjoint G.IsLocalization W := by simpa using isLocalization_leftAdjoint adj.op W.op hW.op (fun X ↦ hW' X.unop) -set_option backward.isDefEq.respectTransparency false in lemma functorCategory_inverseImage_isomorphisms_unit (adj : G ⊣ F) : ((isomorphisms C₂).inverseImage G).functorCategory C₁ adj.unit := by intro simp only [Functor.id_obj, inverseImage_iff, isomorphisms.iff] infer_instance -set_option backward.isDefEq.respectTransparency false in lemma functorCategory_inverseImage_isomorphisms_counit (adj : F ⊣ G) : ((isomorphisms C₂).inverseImage G).functorCategory C₁ adj.counit := by intro diff --git a/Mathlib/CategoryTheory/Localization/CalculusOfFractions/Preadditive.lean b/Mathlib/CategoryTheory/Localization/CalculusOfFractions/Preadditive.lean index 41552d8b556bad..275b7e171ff691 100644 --- a/Mathlib/CategoryTheory/Localization/CalculusOfFractions/Preadditive.lean +++ b/Mathlib/CategoryTheory/Localization/CalculusOfFractions/Preadditive.lean @@ -220,7 +220,7 @@ variable (L X Y) /-- The abelian group structure on `L.obj X ⟶ L.obj Y` when `L : C ⥤ D` is a localization functor, `C` is preadditive and there is a left calculus of fractions. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def addCommGroup' : AddCommGroup (L.obj X ⟶ L.obj Y) := by letI : Zero (L.obj X ⟶ L.obj Y) := ⟨L.map 0⟩ letI : Add (L.obj X ⟶ L.obj Y) := ⟨add' W⟩ @@ -277,7 +277,7 @@ lemma add_eq_add {X'' Y'' : C} (eX' : L.obj X'' ≅ X') (eY' : L.obj Y'' ≅ Y') variable (L X' Y') in /-- The abelian group structure on morphisms in `D`, when `L : C ⥤ D` is a localization functor, `C` is preadditive and there is a left calculus of fractions. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def addCommGroup : AddCommGroup (X' ⟶ Y') := by have := Localization.essSurj L W letI := addCommGroup' L W (L.objPreimage X') (L.objPreimage Y') @@ -304,7 +304,7 @@ variable [W.HasLeftCalculusOfFractions] /-- The preadditive structure on `D`, when `L : C ⥤ D` is a localization functor, `C` is preadditive and there is a left calculus of fractions. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def preadditive : Preadditive D where homGroup := Preadditive.addCommGroup L W add_comp _ _ _ _ _ _ := by apply Preadditive.add_comp diff --git a/Mathlib/CategoryTheory/Localization/Construction.lean b/Mathlib/CategoryTheory/Localization/Construction.lean index 639507424e0f57..aa720fc4abdd79 100644 --- a/Mathlib/CategoryTheory/Localization/Construction.lean +++ b/Mathlib/CategoryTheory/Localization/Construction.lean @@ -329,6 +329,7 @@ def inverse : W.FunctorsInverting D ⥤ W.Localization ⥤ D where natTransExtension_app, NatTransExtension.app_eq] rfl) +set_option backward.isDefEq.respectTransparency.types false in /-- The unit isomorphism of the equivalence of categories `whiskeringLeftEquivalence W D`. -/ @[simps!] def unitIso : 𝟭 (W.Localization ⥤ D) ≅ functor W D ⋙ inverse W D := @@ -361,7 +362,6 @@ def counitIso : inverse W D ⋙ functor W D ≅ 𝟭 (W.FunctorsInverting D) := end WhiskeringLeftEquivalence -set_option backward.isDefEq.respectTransparency false in /-- The equivalence of categories `(W.Localization ⥤ D) ≌ (W.FunctorsInverting D)` induced by the composition with `W.Q : C ⥤ W.Localization`. -/ def whiskeringLeftEquivalence : W.Localization ⥤ D ≌ W.FunctorsInverting D where diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Basic.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Basic.lean index 13c66f60c61a50..3a66f423f99a0c 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Basic.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Basic.lean @@ -60,7 +60,7 @@ universe v₁ v₂ u₁ u₂ namespace CategoryTheory -open Category Localization Functor +open Category Localization CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} [Category.{v₁} C₁] [Category.{v₂} C₂] {W₁ : MorphismProperty C₁} {W₂ : MorphismProperty C₂} @@ -85,8 +85,8 @@ attribute [instance] IsRightDerivabilityStructure.hasRightResolutions variable {D₁ D₂ : Type*} [Category* D₁] [Category* D₂] (L₁ : C₁ ⥤ D₁) (L₂ : C₂ ⥤ D₂) [L₁.IsLocalization W₁] [L₂.IsLocalization W₂] (F : D₁ ⥤ D₂) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma isRightDerivabilityStructure_iff [Φ.HasRightResolutions] (e : Φ.functor ⋙ L₂ ≅ L₁ ⋙ F) : Φ.IsRightDerivabilityStructure ↔ TwoSquare.GuitartExact e.hom := by have : Φ.IsRightDerivabilityStructure ↔ diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Constructor.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Constructor.lean index 31e6933b2bb383..8775726b371273 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Constructor.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Constructor.lean @@ -56,6 +56,7 @@ namespace Constructor variable {D : Type*} [Category* D] (L : C₂ ⥤ D) [L.IsLocalization W₂] {X₂ : C₂} {X₃ : D} (y : L.obj X₂ ⟶ X₃) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `Φ : LocalizerMorphism W₁ W₂`, `L : C₂ ⥤ D` a localization functor for `W₂` and a morphism `y : L.obj X₂ ⟶ X₃`, this is the functor which sends `R : Φ.RightResolution d` to @@ -107,6 +108,7 @@ lemma isConnected : end Constructor +set_option backward.isDefEq.respectTransparency.types false in /-- If a localizer morphism `Φ` is a localized equivalence, then it is a right derivability structure if the categories of right resolutions are connected and the categories of right resolutions of arrows are nonempty. -/ diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean index a9539a1d84d6dc..675aec54995d6a 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean @@ -77,7 +77,6 @@ lemma isIso_of_isRightDerivedFunctor (X₁ : C₁) [RF.IsRightDerivedFunctor α @[deprecated (since := "2026-06-22")] alias isIso := isIso_of_isRightDerivedFunctor set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma isRightDerivedFunctor_of_isIso (hα : ∀ (X₁ : C₁), IsIso (α.app (Φ.functor.obj X₁))) : RF.IsRightDerivedFunctor α W₂ := by have := h.hasPointwiseRightDerivedFunctor diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfFunctorialResolutions.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfFunctorialResolutions.lean index b9d26c86ef8a86..9c4622d8eab3d5 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfFunctorialResolutions.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfFunctorialResolutions.lean @@ -42,11 +42,10 @@ lemma hasRightResolutions_arrow_of_functorial_resolutions : hw := ⟨hi _, hi _⟩ }⟩ namespace functorialRightResolutions -open Functor +open CategoryTheory.Functor variable {Φ i} -set_option backward.isDefEq.respectTransparency false in /-- If `Φ : LocalizerMorphism W₁ W₂` corresponds to a class `W₁` that is the inverse image of `W₂` by the functor `Φ.functor` and that we have functorial right resolutions, then this is a morphism of localizers @@ -81,7 +80,6 @@ lemma Φ_functor_map_ι_app (X₁ : C₁) : NatTrans.congr_app (((whiskeringRight C₁ C₁ C₂).obj Φ.functor).map_preimage (X := 𝟭 C₁) (Y := Φ.functor ⋙ ρ) (whiskerLeft Φ.functor i)) X₁ -set_option backward.isDefEq.respectTransparency false in include hW₁ hi in lemma W₁_ι_app (X₁ : C₁) : W₁ ((ι i).app X₁) := by simpa [hW₁] using hi (Φ.functor.obj X₁) @@ -100,7 +98,6 @@ lemma isLocalizedEquivalence_of_functorial_right_resolutions : variable [W₂.IsMultiplicative] -set_option backward.isDefEq.respectTransparency false in lemma isConnected_rightResolution_of_functorial_resolutions (X₂ : C₂) : letI : W₁.IsMultiplicative := by rw [hW₁]; infer_instance IsConnected (Φ.RightResolution X₂) := by diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean index 0cc96c9149d8a3..e07c30c9f46539 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/OfLocalizedEquivalences.lean @@ -83,6 +83,7 @@ lemma isLeftDerivabilityStructure_of_isLocalizedEquivalence rw [B.isLeftDerivabilityStructure_iff W₁'.Q W₂'.Q F e'] apply TwoSquare.GuitartExact.of_hComp iso.inv +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isLeftDerivabilityStructure_iff_of_isLocalizedEquivalence [L.functor.EssSurj] [R.functor.Full] [R.IsInduced] @@ -115,6 +116,7 @@ lemma isLeftDerivabilityStructure_iff_of_isLocalizedEquivalence (R.functor ⋙ W₂'.Q) F e, ← this] infer_instance +set_option backward.isDefEq.respectTransparency.types false in lemma isRightDerivabilityStructure_of_isLocalizedEquivalence [T.IsRightDerivabilityStructure] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) @@ -126,6 +128,7 @@ lemma isRightDerivabilityStructure_of_isLocalizedEquivalence inferInstanceAs (TwoSquare.op iso.hom).GuitartExact exact isLeftDerivabilityStructure_of_isLocalizedEquivalence iso' +set_option backward.isDefEq.respectTransparency.types false in lemma isRightDerivabilityStructure_iff_of_isLocalizedEquivalence [L.functor.EssSurj] [R.functor.Full] [R.IsInduced] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) @@ -143,6 +146,7 @@ variable [W₁'.RespectsIso] [W₂'.RespectsIso] [L.IsInduced] [L.functor.IsEqui [R.IsInduced] [R.functor.IsEquivalence] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) +set_option backward.isDefEq.respectTransparency.types false in lemma isLeftDerivabilityStructure_of_equivalences [T.IsLeftDerivabilityStructure] (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) : @@ -151,7 +155,7 @@ lemma isLeftDerivabilityStructure_of_equivalences have := R.isLocalizedEquivalence_of_isInduced exact isLeftDerivabilityStructure_of_isLocalizedEquivalence iso -open Functor in +open CategoryTheory.Functor in lemma isLeftDerivabilityStructure_iff_of_equivalences (iso : T.functor ⋙ R.functor ≅ L.functor ⋙ B.functor) : T.IsLeftDerivabilityStructure ↔ B.IsLeftDerivabilityStructure := diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean index 5e500b0d9b2c30..c614f856bf80e0 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean @@ -38,7 +38,7 @@ universe v₁ v₂ v₃ v₄ v₅ u₁ u₂ u₃ u₄ u₅ namespace CategoryTheory -open Limits Category Functor +open Limits Category CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} {H : Type u₃} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} H] @@ -84,6 +84,7 @@ lemma rightDerivedFunctorComparison_fac_app (X : C₁) : variable [Φ.IsRightDerivabilityStructure] +set_option backward.isDefEq.respectTransparency.types false in lemma hasPointwiseRightDerivedFunctorAt_iff_of_isRightDerivabilityStructure (X : C₁) : (Φ.functor ⋙ F).HasPointwiseRightDerivedFunctorAt W₁ X ↔ F.HasPointwiseRightDerivedFunctorAt W₂ (Φ.functor.obj X) := by @@ -120,7 +121,6 @@ instance : IsIso (Φ.rightDerivedFunctorComparison L₁ L₂ F F₁ α₁ F₂ exact ((F₂.isPointwiseLeftKanExtensionOfHasPointwiseRightDerivedFunctor α₂ W₂).compTwoSquare ((Φ.catCommSq L₁ L₂).iso).hom).isLeftKanExtension -set_option backward.isDefEq.respectTransparency false in lemma isIso_iff_of_isRightDerivabilityStructure (X : C₁) : IsIso (α₁.app X) ↔ IsIso (α₂.app (Φ.functor.obj X)) := by rw [← isIso_comp_right_iff (α₁.app X) diff --git a/Mathlib/CategoryTheory/Localization/FiniteProducts.lean b/Mathlib/CategoryTheory/Localization/FiniteProducts.lean index f96ce11aa5b0a3..22b7ff546f325b 100644 --- a/Mathlib/CategoryTheory/Localization/FiniteProducts.lean +++ b/Mathlib/CategoryTheory/Localization/FiniteProducts.lean @@ -27,7 +27,7 @@ universe v₁ v₂ u₁ u₂ namespace CategoryTheory -open Limits Functor +open Limits CategoryTheory.Functor namespace Localization @@ -80,6 +80,7 @@ lemma adj_counit_app (F : Discrete J ⥤ C) : whiskerRight (constLimAdj.counit.app F) L := by apply constLimAdj.localization_counit_app +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `Localization.preservesProductsOfShape`. -/ noncomputable def isLimitMapCone (F : Discrete J ⥤ C) : diff --git a/Mathlib/CategoryTheory/Localization/HasLocalization.lean b/Mathlib/CategoryTheory/Localization/HasLocalization.lean index 34b69ea761aad9..0a71d8a2e23cfd 100644 --- a/Mathlib/CategoryTheory/Localization/HasLocalization.lean +++ b/Mathlib/CategoryTheory/Localization/HasLocalization.lean @@ -75,7 +75,7 @@ def Q' : C ⥤ W.Localization' := HasLocalization.L instance : W.Q'.IsLocalization W := HasLocalization.hL /-- The constructed localized category. -/ -@[implicit_reducible] +@[instance_reducible] def HasLocalization.standard : HasLocalization.{max u v} W where L := W.Q diff --git a/Mathlib/CategoryTheory/Localization/HomEquiv.lean b/Mathlib/CategoryTheory/Localization/HomEquiv.lean index 6a6c9df9dff9ae..e6cb351eb6ef9d 100644 --- a/Mathlib/CategoryTheory/Localization/HomEquiv.lean +++ b/Mathlib/CategoryTheory/Localization/HomEquiv.lean @@ -51,7 +51,6 @@ noncomputable def homMap (f : L₁.obj X ⟶ L₁.obj Y) : Iso.homCongr ((CatCommSq.iso _ _ _ _).symm.app _) ((CatCommSq.iso _ _ _ _).symm.app _) ((Φ.localizedFunctor L₁ L₂).map f) -set_option backward.isDefEq.respectTransparency false in @[simp] lemma homMap_map (f : X ⟶ Y) : Φ.homMap L₁ L₂ (L₁.map f) = L₂.map (Φ.functor.map f) := by @@ -64,13 +63,11 @@ lemma homMap_id : Φ.homMap L₁ L₂ (𝟙 (L₁.obj X)) = 𝟙 (L₂.obj (Φ.functor.obj X)) := by simpa using Φ.homMap_map L₁ L₂ (𝟙 X) -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma homMap_comp (f : L₁.obj X ⟶ L₁.obj Y) (g : L₁.obj Y ⟶ L₁.obj Z) : Φ.homMap L₁ L₂ (f ≫ g) = Φ.homMap L₁ L₂ f ≫ Φ.homMap L₁ L₂ g := by simp [homMap] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma homMap_apply (G : D₁ ⥤ D₂) (e : Φ.functor ⋙ L₂ ≅ L₁ ⋙ G) (f : L₁.obj X ⟶ L₁.obj Y) : Φ.homMap L₁ L₂ f = e.hom.app X ≫ G.map f ≫ e.inv.app Y := by @@ -144,6 +141,7 @@ lemma homEquiv_refl (f : L₁.obj X ⟶ L₁.obj Y) : homEquiv W L₁ L₁ f = f := by apply LocalizerMorphism.id_homMap +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma homEquiv_trans (f : L₁.obj X ⟶ L₁.obj Y) : homEquiv W L₂ L₃ (homEquiv W L₁ L₂ f) = homEquiv W L₁ L₃ f := by diff --git a/Mathlib/CategoryTheory/Localization/Linear.lean b/Mathlib/CategoryTheory/Localization/Linear.lean index f190e5f4ede621..39cd314b2b651d 100644 --- a/Mathlib/CategoryTheory/Localization/Linear.lean +++ b/Mathlib/CategoryTheory/Localization/Linear.lean @@ -34,7 +34,7 @@ variable (R : Type w) [Ring R] {C : Type u₁} [Category.{v₁} C] {D : Type u /-- If `L : C ⥤ D` is a localization functor and `C` is `R`-linear, then `D` is `R`-linear if we already know that `D` is preadditive and `L` is additive. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def linear : Linear R D := Linear.ofRingMorphism ((CatCenter.localizationRingHom L W).comp (Linear.toCatCenter R C)) diff --git a/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean b/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean index c169d37975d6ba..ba882509e9a2af 100644 --- a/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean +++ b/Mathlib/CategoryTheory/Localization/LocalizerMorphism.lean @@ -33,7 +33,7 @@ universe v₁ v₂ v₃ v₄ v₄' v₅ v₅' v₆ u₁ u₂ u₃ u₄ u₄' u namespace CategoryTheory -open Localization Functor +open Localization CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} {C₃ : Type u₃} {D₁ : Type u₄} {D₂ : Type u₅} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} C₃] [Category.{v₄} D₁] [Category.{v₅} D₂] @@ -384,6 +384,7 @@ section variable [Φ.functor.IsEquivalence] [Φ.IsInduced] [W₂.RespectsIso] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.asEquivalence_counitIso_hom_app Functor.asEquivalence_counitIso_inv_app in @@ -405,6 +406,7 @@ instance : Φ.inv.functor.IsEquivalence := by dsimp infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.asEquivalence_inverse Functor.asEquivalence_counitIso_hom_app Functor.asEquivalence_counitIso_inv_app in diff --git a/Mathlib/CategoryTheory/Localization/LocallySmall.lean b/Mathlib/CategoryTheory/Localization/LocallySmall.lean index bac83aa39df13b..7f8ea9097f8f74 100644 --- a/Mathlib/CategoryTheory/Localization/LocallySmall.lean +++ b/Mathlib/CategoryTheory/Localization/LocallySmall.lean @@ -33,7 +33,7 @@ variable {C : Type u₁} [Category.{v₁} C] (W : MorphismProperty C) a `HasLocalization.{w} W` instance by shrinking the morphisms in `D`. (This version assumes that the types of objects of the categories `C` and `D` are in the same universe.) -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def hasLocalizationOfLocallySmall {D : Type u₁} [Category.{v₂} D] [LocallySmall.{w} D] (L : C ⥤ D) [L.IsLocalization W] : @@ -41,7 +41,7 @@ noncomputable def hasLocalizationOfLocallySmall D := ShrinkHoms D L := L ⋙ (ShrinkHoms.equivalence D).functor --- adding `@[implicit_reducible]` causes downstream breakage +-- adding `@[instance_reducible]` causes downstream breakage set_option warn.classDefReducibility false in /-- If `L : C ⥤ D` is a localization functor for a class of morphisms `W : MorphismProperty C`, and `D` is locally `w`-small, we may obtain diff --git a/Mathlib/CategoryTheory/Localization/Monoidal/Basic.lean b/Mathlib/CategoryTheory/Localization/Monoidal/Basic.lean index 2c047c74c9aebf..6a8a731485dda9 100644 --- a/Mathlib/CategoryTheory/Localization/Monoidal/Basic.lean +++ b/Mathlib/CategoryTheory/Localization/Monoidal/Basic.lean @@ -234,6 +234,7 @@ lemma rightUnitor_hom_app (X : C) : change _ ≫ (μ L W ε _ _).hom ≫ _ ≫ 𝟙 _ ≫ 𝟙 _ = _ simp only [comp_id] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma associator_hom_app (X₁ X₂ X₃ : C) : (α_ ((L').obj X₁) ((L').obj X₂) ((L').obj X₃)).hom = @@ -286,6 +287,7 @@ lemma whisker_exchange {Q X Y Z : LocalizedMonoidal L W ε} (f : Q ⟶ X) (g : Y Q ◁ g ≫ f ▷ Z = f ▷ Y ≫ X ◁ g := by simp only [← id_tensorHom, ← tensorHom_id, ← tensor_comp, id_comp, comp_id] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma associator_naturality {X₁ X₂ X₃ Y₁ Y₂ Y₃ : LocalizedMonoidal L W ε} @@ -374,7 +376,6 @@ lemma pentagon (Y₁ Y₂ Y₃ Y₄ : LocalizedMonoidal L W ε) : Iso.inv_hom_id, whiskerRight_id, ← whiskerLeft_comp, whiskerLeft_id] -set_option backward.isDefEq.respectTransparency false in lemma leftUnitor_naturality {X Y : LocalizedMonoidal L W ε} (f : X ⟶ Y) : 𝟙_ (LocalizedMonoidal L W ε) ◁ f ≫ (λ_ Y).hom = (λ_ X).hom ≫ f := by simp +instances [monoidalCategoryStruct] @@ -391,6 +392,7 @@ lemma triangle_aux₁ {X₁ X₂ X₃ Y₁ Y₂ Y₃ : LocalizedMonoidal L W ε} simp only [associator_naturality_assoc, ← tensor_comp, Iso.hom_inv_id, id_tensorHom, whiskerLeft_id, comp_id] +set_option backward.isDefEq.respectTransparency.types false in lemma triangle_aux₂ {X Y : LocalizedMonoidal L W ε} {X' Y' : C} (e₁ : (L').obj X' ≅ X) (e₂ : (L').obj Y' ≅ Y) : e₁.hom ⊗ₘ (ε.hom ⊗ₘ e₂.hom) ≫ (λ_ Y).hom = @@ -413,6 +415,7 @@ lemma triangle_aux₃ {X Y : LocalizedMonoidal L W ε} {X' Y' : C} ← rightUnitor_naturality, rightUnitor_hom_app, ← tensorHom_id, ← id_tensorHom, ← tensor_comp_assoc, comp_id, id_comp] +set_option backward.isDefEq.respectTransparency.types false in variable {L W ε} in lemma triangle (X Y : LocalizedMonoidal L W ε) : (α_ X (𝟙_ _) Y).hom ≫ X ◁ (λ_ Y).hom = (ρ_ X).hom ▷ Y := by @@ -441,7 +444,6 @@ lemma triangle (X Y : LocalizedMonoidal L W ε) : · exact triangle_aux₂ _ _ _ e₁ e₂ · exact triangle_aux₃ _ _ _ e₁ e₂ -set_option backward.isDefEq.respectTransparency false in noncomputable instance : MonoidalCategory (LocalizedMonoidal L W ε) where tensorHom_def := by intros; simp +instances [monoidalCategoryStruct] diff --git a/Mathlib/CategoryTheory/Localization/Monoidal/Braided.lean b/Mathlib/CategoryTheory/Localization/Monoidal/Braided.lean index 44e1a7c75839e1..869e63ec605c67 100644 --- a/Mathlib/CategoryTheory/Localization/Monoidal/Braided.lean +++ b/Mathlib/CategoryTheory/Localization/Monoidal/Braided.lean @@ -62,6 +62,9 @@ lemma braidingNatIso_hom_app (X Y : C) : simp [braidingNatIso, lift₂NatIso] rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma braidingNatIso_hom_app_naturality_μ_left (X Y Z : C) : ((braidingNatIso L W ε).hom.app ((L').obj X)).app ((L').obj Y ⊗ (L').obj Z) ≫ @@ -70,6 +73,9 @@ lemma braidingNatIso_hom_app_naturality_μ_left (X Y Z : C) : ((braidingNatIso L W ε).hom.app ((L').obj X)).app ((L').obj (Y ⊗ Z)) := (((braidingNatIso L W ε).hom.app ((L').obj X)).naturality ((Functor.LaxMonoidal.μ (L') Y Z))).symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma braidingNatIso_hom_app_naturality_μ_right (X Y Z : C) : ((braidingNatIso L W ε).hom.app ((L').obj X ⊗ (L').obj Y)).app ((L').obj Z) ≫ @@ -138,6 +144,7 @@ section Symmetric variable [SymmetricCategory C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in noncomputable instance : SymmetricCategory (LocalizedMonoidal L W ε) := by refine .ofCurried (natTrans₂_ext (L') (L') W W fun X Y ↦ ?_) diff --git a/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean index 5c493fa695cb7c..2f0436ef44117d 100644 --- a/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Localization/Monoidal/Functor.lean @@ -27,7 +27,8 @@ universe u namespace CategoryTheory -open CategoryTheory MonoidalCategory Functor Monoidal LaxMonoidal OplaxMonoidal +open CategoryTheory MonoidalCategory CategoryTheory.Functor MonoidalCategory.Functor Monoidal +open LaxMonoidal OplaxMonoidal namespace Localization.Monoidal @@ -55,6 +56,7 @@ noncomputable def curriedTensorPreIsoPost : curriedTensorPre F ≅ curriedTensor lift₂NatIso L L W W (curriedTensorPre G) (curriedTensorPost G) _ _ (Functor.curriedTensorPreIsoPost G) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma curriedTensorPreIsoPost_hom_app_app (X₁ X₂ : C) : @@ -83,7 +85,7 @@ lemma curriedTensorPreIsoPost_hom_app_app' {X₁ X₂ : C} {Y₁ Y₂ : D} tensorHom_comp_tensorHom, Iso.inv_hom_id, Iso.inv_hom_id, tensorHom_id, id_whiskerRight, Category.comp_id] -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- Monoidal structure on `F`, given that `F` lifts along `L` to a monoidal functor `G`, where `L` is a monoidal localization functor. @@ -130,7 +132,7 @@ noncomputable def functorCoreMonoidalOfComp : F.CoreMonoidal := by Monoidal structure on `F`, given that `F` lifts along `L` to a monoidal functor `G`, where `L` is a monoidal localization functor. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def functorMonoidalOfComp : F.Monoidal := (functorCoreMonoidalOfComp L W F G).toMonoidal @@ -147,7 +149,6 @@ lemma functorMonoidalOfComp_μ (X Y : C) : letI := functorMonoidalOfComp L W F G F.map (δ L _ _) := by simp [Functor.CoreMonoidal.toLaxMonoidal_μ, curriedTensorPreIsoPost_hom_app_app] -set_option backward.isDefEq.respectTransparency false in /-- When `F` is given the monoidal structure `functorMonoidalOfComp` that is obtained by lifting along a monoidal localization functor `L`, then the lifting isomorphism is a monoidal natural diff --git a/Mathlib/CategoryTheory/Localization/Predicate.lean b/Mathlib/CategoryTheory/Localization/Predicate.lean index 312e74a3cf0c8f..573923a404148a 100644 --- a/Mathlib/CategoryTheory/Localization/Predicate.lean +++ b/Mathlib/CategoryTheory/Localization/Predicate.lean @@ -39,7 +39,7 @@ noncomputable section namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor variable {C D : Type*} [Category* C] [Category* D] (L : C ⥤ D) (W : MorphismProperty C) (E : Type*) [Category* E] @@ -335,7 +335,6 @@ theorem liftNatTrans_app (F₁ F₂ : C ⥤ E) (F₁' F₂' : D ⥤ E) [Lifting (Lifting.iso L W F₁ F₁').hom.app X ≫ τ.app X ≫ (Lifting.iso L W F₂ F₂').inv.app X := congr_app (Functor.map_preimage (whiskeringLeftFunctor' L W E) _) X -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem comp_liftNatTrans (F₁ F₂ F₃ : C ⥤ E) (F₁' F₂' F₃' : D ⥤ E) [h₁ : Lifting L W F₁ F₁'] [h₂ : Lifting L W F₂ F₂'] [h₃ : Lifting L W F₃ F₃'] (τ : F₁ ⟶ F₂) (τ' : F₂ ⟶ F₃) : @@ -377,7 +376,7 @@ instance compLeft (F : D ⥤ E) : Localization.Lifting L W (L ⋙ F) F := ⟨Iso /-- Given a localization functor `L : C ⥤ D` for `W : MorphismProperty C`, if `F₁' : D ⥤ E` lifts a functor `F₁ : C ⥤ D`, then a functor `F₂'` which is isomorphic to `F₁'` also lifts a functor `F₂` that is isomorphic to `F₁`. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def ofIsos {F₁ F₂ : C ⥤ E} {F₁' F₂' : D ⥤ E} (e : F₁ ≅ F₂) (e' : F₁' ≅ F₂') [Lifting L W F₁ F₁'] : Lifting L W F₂ F₂' := ⟨isoWhiskerLeft L e'.symm ≪≫ iso L W F₁ F₁' ≪≫ e⟩ @@ -439,6 +438,7 @@ same `MorphismProperty C`, this is an equivalence of categories `D₁ ≌ D₂`. def uniq : D₁ ≌ D₂ := (equivalenceFromModel L₁ W').symm.trans (equivalenceFromModel L₂ W') +set_option backward.isDefEq.respectTransparency.types false in lemma uniq_symm : (uniq L₁ L₂ W').symm = uniq L₂ L₁ W' := by dsimp [uniq, Equivalence.trans] ext <;> aesop @@ -469,7 +469,6 @@ def isoUniqFunctor (F : D₁ ⥤ D₂) (e : L₁ ⋙ F ≅ L₂) : liftNatIso L₁ W' L₂ L₂ F (uniq L₁ L₂ W').functor (Iso.refl L₂) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma morphismProperty_eq_top [L.IsLocalization W] (P : MorphismProperty D) [P.RespectsIso] [P.IsMultiplicative] (h₁ : ∀ ⦃X Y : C⦄ (f : X ⟶ Y), P (L.map f)) (h₂ : ∀ ⦃X Y : C⦄ (f : X ⟶ Y) (hf : W f), P (isoOfHom L W f hf).inv) : diff --git a/Mathlib/CategoryTheory/Localization/Prod.lean b/Mathlib/CategoryTheory/Localization/Prod.lean index f4835488c1efec..1e06dd914a1fe0 100644 --- a/Mathlib/CategoryTheory/Localization/Prod.lean +++ b/Mathlib/CategoryTheory/Localization/Prod.lean @@ -33,7 +33,7 @@ universe v₁ v₂ v₃ v₄ v₅ u₁ u₂ u₃ u₄ u₅ namespace CategoryTheory -open Functor +open CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} {D₁ : Type u₃} {D₂ : Type u₄} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} D₁] [Category.{v₄} D₂] diff --git a/Mathlib/CategoryTheory/Localization/Resolution.lean b/Mathlib/CategoryTheory/Localization/Resolution.lean index 33c4e815e81fc6..a67f603a91dd16 100644 --- a/Mathlib/CategoryTheory/Localization/Resolution.lean +++ b/Mathlib/CategoryTheory/Localization/Resolution.lean @@ -255,6 +255,7 @@ def RightResolution.unopFunctor (X₂ : C₂ᵒᵖ) : { f := φ.unop.f.unop comm := Quiver.Hom.op_inj φ.unop.comm } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories `(Φ.LeftResolution X₂)ᵒᵖ ≌ Φ.op.RightResolution (Opposite.op X₂)`. -/ diff --git a/Mathlib/CategoryTheory/Localization/SmallHom.lean b/Mathlib/CategoryTheory/Localization/SmallHom.lean index dac9d35fa0eb80..ed52c439185b43 100644 --- a/Mathlib/CategoryTheory/Localization/SmallHom.lean +++ b/Mathlib/CategoryTheory/Localization/SmallHom.lean @@ -264,7 +264,6 @@ noncomputable def smallHomMap (f : SmallHom.{w} W₁ X Y) : ((Φ.localizedFunctor W₁.Q W₂.Q).map ((SmallHom.equiv W₁ W₁.Q) f))) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma equiv_smallHomMap (G : D₁ ⥤ D₂) (e : Φ.functor ⋙ L₂ ≅ L₁ ⋙ G) (f : SmallHom.{w} W₁ X Y) : (SmallHom.equiv W₂ L₂) (Φ.smallHomMap f) = @@ -297,7 +296,6 @@ lemma equiv_smallHomMap (G : D₁ ⥤ D₂) (e : Φ.functor ⋙ L₂ ≅ L₁ Functor.map_id, id_comp, Iso.hom_inv_id_app_assoc, Iso.hom_inv_id_app, Functor.comp_obj, comp_id] -set_option backward.isDefEq.respectTransparency false in @[simp] lemma smallHomMap_mk (f : X ⟶ Y) : Φ.smallHomMap (SmallHom.mk _ f) = @@ -317,7 +315,6 @@ variable [HasSmallLocalizedHom.{w} W₁ X Y] [HasSmallLocalizedHom.{w} W₁ Y Z] [HasSmallLocalizedHom.{w'} W₂ (Φ.functor.obj Y) (Φ.functor.obj Z)] [HasSmallLocalizedHom.{w'} W₂ (Φ.functor.obj X) (Φ.functor.obj Z)] -set_option backward.isDefEq.respectTransparency false in lemma smallHomMap_comp (f : SmallHom.{w} W₁ X Y) (g : SmallHom.{w} W₁ Y Z) : Φ.smallHomMap (f.comp g) = (Φ.smallHomMap f).comp (Φ.smallHomMap g) := by apply (SmallHom.equiv W₂ W₂.Q).injective diff --git a/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean b/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean index dbba273b2b692a..72105faa2ccb7a 100644 --- a/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean +++ b/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean @@ -194,8 +194,8 @@ lemma equiv_apply [HasSmallLocalizedShiftedHom.{w} W M X Y] {m : M} section variable [W.IsCompatibleWithShift M] -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in lemma equiv_shift' {a : M} [HasSmallLocalizedShiftedHom.{w} W M X Y] [HasSmallLocalizedShiftedHom.{w} W M Y Y] (f : SmallShiftedHom.{w} W X Y a) (n a' : M) (h : a + n = a') : @@ -234,7 +234,6 @@ lemma equiv_comp [HasSmallLocalizedShiftedHom.{w} W M X Y] end set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] lemma equiv_mk [HasSmallLocalizedShiftedHom.{w} W M X Y] {m : M} (f : ShiftedHom X Y m) : equiv W L (.mk _ f) = f.map L := @@ -419,7 +418,6 @@ noncomputable def smallShiftedHomMap {m : M} (f : SmallShiftedHom.{w} W₁ X₁ Φ.smallHomMap' eX ((Φ.functor.commShiftIso m).app Y₁ ≪≫ (shiftFunctor _ _).mapIso eY) f set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma equiv_smallShiftedHomMap (G : D₁ ⥤ D₂) [G.CommShift M] (e : Φ.functor ⋙ L₂ ≅ L₁ ⋙ G) [NatTrans.CommShift e.hom M] {m : M} (f : SmallShiftedHom.{w} W₁ X₁ Y₁ m) : @@ -444,7 +442,6 @@ lemma equiv_smallShiftedHomMap (G : D₁ ⥤ D₂) [G.CommShift M] variable [W₁.IsCompatibleWithShift M] [W₂.IsCompatibleWithShift M] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] lemma smallShiftedHomMap_mk {m : M} (f : ShiftedHom X₁ Y₁ m) : Φ.smallShiftedHomMap eX eY (.mk _ f) = @@ -466,7 +463,6 @@ lemma smallShiftedHomMap_mk₀ (m₀ : M) (hm₀ : m₀ = 0) (f : X₁ ⟶ Y₁) simp [SmallShiftedHom.mk₀] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma smallShiftedHomMap_comp [HasSmallLocalizedShiftedHom.{w} W₁ M Y₁ Z₁] [HasSmallLocalizedShiftedHom.{w''} W₂ M Z₂ Z₂] [HasSmallLocalizedShiftedHom.{w''} W₂ M Y₂ Z₂] [HasSmallLocalizedShiftedHom.{w} W₁ M X₁ Z₁] diff --git a/Mathlib/CategoryTheory/Localization/Triangulated.lean b/Mathlib/CategoryTheory/Localization/Triangulated.lean index 7074b0ad91d595..b5b025da4f9cdd 100644 --- a/Mathlib/CategoryTheory/Localization/Triangulated.lean +++ b/Mathlib/CategoryTheory/Localization/Triangulated.lean @@ -195,7 +195,7 @@ lemma complete_distinguished_triangle_morphism (T₁ T₂ : Triangle D) variable [HasZeroObject D] [Preadditive D] [∀ (n : ℤ), (shiftFunctor D n).Additive] [L.Additive] /-- The pretriangulated structure on the localized category. -/ -@[implicit_reducible] +@[instance_reducible] def pretriangulated : Pretriangulated D where distinguishedTriangles := L.essImageDistTriang isomorphic_distinguished _ hT₁ _ e := L.essImageDistTriang_mem_of_iso e hT₁ diff --git a/Mathlib/CategoryTheory/Localization/Trifunctor.lean b/Mathlib/CategoryTheory/Localization/Trifunctor.lean index a06b4cdf7efff0..9704e7bd73eaf2 100644 --- a/Mathlib/CategoryTheory/Localization/Trifunctor.lean +++ b/Mathlib/CategoryTheory/Localization/Trifunctor.lean @@ -24,7 +24,7 @@ The main result in this file is that we can localize "associator" isomorphisms namespace CategoryTheory -open Functor +open CategoryTheory.Functor variable {C₁ C₂ C₃ C₁₂ C₂₃ D₁ D₂ D₃ D₁₂ D₂₃ C D E : Type*} [Category* C₁] [Category* C₂] [Category* C₃] [Category* D₁] [Category* D₂] [Category* D₃] @@ -171,7 +171,7 @@ variable /-- The construction `bifunctorComp₁₂` of a trifunctor by composition of bifunctors is compatible with localization. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Lifting₃.bifunctorComp₁₂ : Lifting₃ L₁ L₂ L₃ W₁ W₂ W₃ ((Functor.postcompose₃.obj L).obj (bifunctorComp₁₂ F₁₂ G)) @@ -186,7 +186,7 @@ noncomputable def Lifting₃.bifunctorComp₁₂ : /-- The construction `bifunctorComp₂₃` of a trifunctor by composition of bifunctors is compatible with localization. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Lifting₃.bifunctorComp₂₃ : Lifting₃ L₁ L₂ L₃ W₁ W₂ W₃ ((Functor.postcompose₃.obj L).obj (bifunctorComp₂₃ F G₂₃)) @@ -205,6 +205,7 @@ noncomputable def associator : bifunctorComp₁₂ F₁₂' G' ≅ bifunctorComp letI := Lifting₃.bifunctorComp₂₃ L₁ L₂ L₃ L₂₃ L W₁ W₂ W₃ W₂₃ F G₂₃ F' G₂₃' lift₃NatIso L₁ L₂ L₃ W₁ W₂ W₃ _ _ _ _ ((Functor.postcompose₃.obj L).mapIso iso) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma associator_hom_app_app_app (X₁ : C₁) (X₂ : C₂) (X₃ : C₃) : (((associator L₁ L₂ L₃ L₁₂ L₂₃ L W₁ W₂ W₃ W₁₂ W₂₃ iso F₁₂' G' F' G₂₃').hom.app (L₁.obj X₁)).app diff --git a/Mathlib/CategoryTheory/LocallyCartesianClosed/ChosenPullbacksAlong.lean b/Mathlib/CategoryTheory/LocallyCartesianClosed/ChosenPullbacksAlong.lean index e214b96aba1360..6fc0787e9abec0 100644 --- a/Mathlib/CategoryTheory/LocallyCartesianClosed/ChosenPullbacksAlong.lean +++ b/Mathlib/CategoryTheory/LocallyCartesianClosed/ChosenPullbacksAlong.lean @@ -60,14 +60,14 @@ abbrev ChosenPullbacks := Π {X Y : C} (f : Y ⟶ X), ChosenPullbacksAlong f namespace ChosenPullbacksAlong /-- Relating the existing noncomputable `HasPullbacksAlong` typeclass to `ChosenPullbacksAlong`. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] noncomputable def ofHasPullbacksAlong {Y X : C} (f : Y ⟶ X) [HasPullbacksAlong f] : ChosenPullbacksAlong f where pullback := Over.pullback f mapPullbackAdj := Over.mapPullbackAdj f /-- The identity morphism has a functorial choice of pullbacks. -/ -@[implicit_reducible] +@[instance_reducible] def id (X : C) : ChosenPullbacksAlong (𝟙 X) where pullback := 𝟭 _ mapPullbackAdj := (Adjunction.id).ofNatIsoLeft (Over.mapId _).symm @@ -99,7 +99,7 @@ theorem pullbackId_hom_counit (X : C) [ChosenPullbacksAlong (𝟙 X)] : set_option backward.defeqAttrib.useBackward true in /-- Every isomorphism has a functorial choice of pullbacks. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def iso {Y X : C} (f : Y ≅ X) : ChosenPullbacksAlong f.hom where pullback.obj Z := Over.mk (Z.hom ≫ f.inv) pullback.map {Y Z} g := Over.homMk (g.left) @@ -107,11 +107,11 @@ def iso {Y X : C} (f : Y ≅ X) : ChosenPullbacksAlong f.hom where mapPullbackAdj.counit.app U := Over.homMk (𝟙 _) /-- The inverse of an isomorphism has a functorial choice of pullbacks. -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def isoInv {Y X : C} (f : Y ≅ X) : ChosenPullbacksAlong f.inv := iso f.symm /-- The composition of morphisms with chosen pullbacks has a chosen pullback. -/ -@[implicit_reducible] +@[instance_reducible] def comp {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [ChosenPullbacksAlong f] [ChosenPullbacksAlong g] : ChosenPullbacksAlong (f ≫ g) where pullback := pullback g ⋙ pullback f @@ -154,7 +154,7 @@ def cartesianMonoidalCategoryToUnit [CartesianMonoidalCategory C] {X : C} (f : X set_option backward.defeqAttrib.useBackward true in /-- In cartesian monoidal categories, the first product projections `fst` have a functorial choice of pullbacks. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def cartesianMonoidalCategoryFst [CartesianMonoidalCategory C] (X Y : C) : ChosenPullbacksAlong (fst X Y : X ⊗ Y ⟶ X) where pullback.obj Z := Over.mk (Z.hom ▷ Y) @@ -165,7 +165,7 @@ def cartesianMonoidalCategoryFst [CartesianMonoidalCategory C] (X Y : C) : set_option backward.defeqAttrib.useBackward true in /-- In cartesian monoidal categories, the second product projections `snd` have a functorial choice of pullbacks. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def cartesianMonoidalCategorySnd [CartesianMonoidalCategory C] (X Y : C) : ChosenPullbacksAlong (snd X Y : X ⊗ Y ⟶ Y) where pullback.obj Z := Over.mk (X ◁ Z.hom) @@ -331,7 +331,7 @@ theorem isPullback : IsPullback (fst f g) (snd f g) f g where set_option backward.defeqAttrib.useBackward true in attribute [local simp] condition in /-- If `g` has a chosen pullback, then `Over.ChosenPullbacksAlong.fst f g` has a chosen pullback. -/ -@[implicit_reducible] +@[instance_reducible] def chosenPullbacksAlongFst : ChosenPullbacksAlong (fst f g) where pullback.obj W := Over.mk (pullbackMap _ _ _ _ W.hom (𝟙 _) (𝟙 _)) pullback.map {W' W} k := Over.homMk (lift (fst _ g ≫ k.left) (snd _ g)) _ diff --git a/Mathlib/CategoryTheory/LocallyCartesianClosed/ExponentiableMorphism.lean b/Mathlib/CategoryTheory/LocallyCartesianClosed/ExponentiableMorphism.lean index 3bc6492b8b0313..f0671391b2836a 100644 --- a/Mathlib/CategoryTheory/LocallyCartesianClosed/ExponentiableMorphism.lean +++ b/Mathlib/CategoryTheory/LocallyCartesianClosed/ExponentiableMorphism.lean @@ -32,7 +32,7 @@ universe v u namespace CategoryTheory -open Category MonoidalCategory Functor Adjunction +open Category MonoidalCategory CategoryTheory.Functor Adjunction open ChosenPullbacksAlong @@ -145,7 +145,7 @@ end section /-- The identity morphisms `𝟙 _` are exponentiable. -/ -@[implicit_reducible] +@[instance_reducible] def id (I : C) [ChosenPullbacksAlong (𝟙 I)] : ExponentiableMorphism (𝟙 I) := ⟨𝟭 _, ofNatIsoLeft (F := 𝟭 _) Adjunction.id (pullbackId I).symm⟩ @@ -174,7 +174,7 @@ theorem pushforwardId_hom_counit (I : C) [ChosenPullbacksAlong (𝟙 I)] rw [pushforwardId, Adjunction.rightAdjointUniq_hom_counit] /-- The composition of exponentiable morphisms is exponentiable. -/ -@[implicit_reducible] +@[instance_reducible] def comp {I J K : C} (f : I ⟶ J) (g : J ⟶ K) [ChosenPullbacksAlong f] [ChosenPullbacksAlong g] [ChosenPullbacksAlong (f ≫ g)] [ExponentiableMorphism f] [ExponentiableMorphism g] : diff --git a/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean b/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean index 6f3bd6085f89cf..22dd9890c2cb22 100644 --- a/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean +++ b/Mathlib/CategoryTheory/LocallyCartesianClosed/Over.lean @@ -67,6 +67,7 @@ abbrev binaryFan [ChosenPullbacksAlong Z.hom] : BinaryFan Y Z := BinaryFan.mk (P := (pullback Z.hom ⋙ Over.map Z.hom).obj (Over.mk Y.hom)) (fst' Y.hom Z.hom) (snd' Y.hom Z.hom) +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- The binary fan provided by `fst'` and `snd'` is a binary product in `Over X`. -/ def binaryFanIsBinaryProduct [ChosenPullbacksAlong Z.hom] : @@ -81,6 +82,7 @@ def binaryFanIsBinaryProduct [ChosenPullbacksAlong Z.hom] : end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A computable instance of `CartesianMonoidalCategory` for `Over X` when `C` has chosen pullbacks. Contrast this with the noncomputable instance provided by @@ -135,12 +137,18 @@ lemma lift_left {W Y Z : Over X} (f : W ⟶ Y) (g : W ⟶ Z) : @[simp] lemma toUnit_left {Z : Over X} : (toUnit Z).left = Z.hom := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_fst (R S T : Over X) : (α_ R S T).hom.left ≫ fst R.hom (snd S.hom T.hom ≫ T.hom) = fst (R ⊗ S).hom T.hom ≫ fst R.hom S.hom := congr_arg CommaMorphism.left (associator_hom_fst R S T) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_snd_fst (R S T : Over X) : (α_ R S T).hom.left ≫ snd R.hom (snd S.hom T.hom ≫ T.hom) ≫ fst S.hom T.hom = @@ -159,12 +167,18 @@ lemma associator_inv_left_fst_fst (R S T : Over X) : fst R.hom (S ⊗ T).hom := congr_arg CommaMorphism.left (associator_inv_fst_fst R S T) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_fst_snd (R S T : Over X) : (α_ R S T).inv.left ≫ fst (snd R.hom S.hom ≫ S.hom) T.hom ≫ snd R.hom S.hom = snd R.hom (S ⊗ T).hom ≫ fst S.hom T.hom := congr_arg CommaMorphism.left (associator_inv_fst_snd R S T) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_snd (R S T : Over X) : (α_ R S T).inv.left ≫ snd (snd R.hom S.hom ≫ S.hom) T.hom = @@ -208,6 +222,9 @@ lemma whiskerLeft_left_fst {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left ≫ fst R.hom T.hom = fst R.hom S.hom := congr_arg CommaMorphism.left (whiskerLeft_fst R f) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerLeft_left_snd {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left ≫ snd R.hom T.hom = snd R.hom S.hom ≫ f.left := @@ -217,6 +234,9 @@ lemma whiskerRight_left {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left = pullbackMap T.hom R.hom S.hom R.hom f.left (𝟙 _) (𝟙 _) := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerRight_left_fst {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left ≫ fst T.hom R.hom = fst S.hom R.hom ≫ f.left := @@ -231,11 +251,17 @@ lemma tensorHom_left {R S T U : Over X} (f : R ⟶ S) (g : T ⟶ U) : (f ⊗ₘ g).left = pullbackMap S.hom U.hom R.hom T.hom f.left g.left (𝟙 _) := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma tensorHom_left_fst {R S T U : Over X} (f : R ⟶ S) (g : T ⟶ U) : (f ⊗ₘ g).left ≫ fst S.hom U.hom = fst R.hom T.hom ≫ f.left := congr_arg CommaMorphism.left (tensorHom_fst f g) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma tensorHom_left_snd {R S T U : Over X} (f : R ⟶ S) (g : T ⟶ U) : (f ⊗ₘ g).left ≫ snd S.hom U.hom = snd R.hom T.hom ≫ g.left := @@ -273,6 +299,7 @@ def toOverUnit : C ⥤ Over (𝟙_ C) where obj X := Over.mk <| toUnit X map f := Over.homMk f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The slice category over the terminal unit object is equivalent to the original category. -/ @[simps] @@ -286,6 +313,7 @@ variable {C} attribute [local instance] ChosenPullbacksAlong.cartesianMonoidalCategoryToUnit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism of functors `toOverUnit C ⋙ ChosenPullbacksAlong.pullback (toUnit X)` and `toOver X`. -/ @@ -294,6 +322,7 @@ def toOverUnitPullback (X : C) : toOverUnit C ⋙ pullback (toUnit X) ≅ toOver X := NatIso.ofComponents fun X => Iso.refl _ +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- The functor `toOver X` is the right adjoint to the functor `Over.forget X`. -/ @[simps! unit_app counit_app] @@ -306,11 +335,15 @@ theorem forgetAdjToOver.homEquiv_symm {X : C} (Z : Over X) (A : C) (f : Z ⟶ (t rw [Adjunction.homEquiv_counit, forgetAdjToOver_counit_app] simp +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism of functors `toOver (𝟙_ C)` and `toOverUnit C`. -/ @[simps!] def toOverIsoToOverUnit : toOver (𝟙_ C) ≅ toOverUnit C := (forgetAdjToOver (𝟙_ C)).rightAdjointUniq (equivToOverUnit C |>.toAdjunction) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A natural isomorphism between the functors `toOver Y` and `toOver X ⋙ pullback f` for any morphism `f : X ⟶ Y`. -/ @[simps!] @@ -321,6 +354,7 @@ def toOverPullbackIsoToOver {X Y : C} (f : Y ⟶ X) [ChosenPullbacksAlong f] : attribute [local instance] cartesianMonoidalCategoryOver +set_option backward.isDefEq.respectTransparency.types false in omit [CartesianMonoidalCategory C] in /-- The functor `pullback f : Over X ⥤ Over Y` is naturally isomorphic to `toOver : Over X ⥤ Over (Over.mk f)` post-composed with the diff --git a/Mathlib/CategoryTheory/LocallyCartesianClosed/Sections.lean b/Mathlib/CategoryTheory/LocallyCartesianClosed/Sections.lean index 51dcd3f759ba86..2035bec0252126 100644 --- a/Mathlib/CategoryTheory/LocallyCartesianClosed/Sections.lean +++ b/Mathlib/CategoryTheory/LocallyCartesianClosed/Sections.lean @@ -104,6 +104,7 @@ def sectionsUncurry {X : Over I} {A : C} (v : A ⟶ (sections I).obj X) : dsimp [uncurry] at * rw [Category.assoc, ← w', whiskerLeft_toUnit_comp_rightUnitor_hom, braiding_hom_fst]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem sectionsCurry_sectionUncurry {X : Over I} {A : C} {v : A ⟶ (sections I).obj X} : @@ -111,6 +112,7 @@ theorem sectionsCurry_sectionUncurry {X : Over I} {A : C} {v : A ⟶ (sections I dsimp [sectionsCurry, sectionsUncurry] cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem sectionsUncurry_sectionsCurry {X : Over I} {A : C} {u : (toOver I).obj A ⟶ X} : @@ -147,6 +149,9 @@ def coreHomEquivToOverSections : CoreHomEquiv (toOver I) (sections I) where · simp [← curry_natural_right] · simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The adjunction between the toOver functor and the sections functor. -/ @[simps! unit_app counit_app] def toOverSectionsAdj : toOver I ⊣ sections I := diff --git a/Mathlib/CategoryTheory/LocallyDirected.lean b/Mathlib/CategoryTheory/LocallyDirected.lean index 816b7e293aba30..d23d13d21f714c 100644 --- a/Mathlib/CategoryTheory/LocallyDirected.lean +++ b/Mathlib/CategoryTheory/LocallyDirected.lean @@ -55,6 +55,7 @@ instance (F : Discrete J ⥤ Type*) : F.IsLocallyDirected := by rintro ⟨i⟩ ⟨j⟩ ⟨k⟩ ⟨⟨⟨⟩⟩⟩ ⟨⟨⟨⟩⟩⟩ simpa using fun x ↦ ⟨i, 𝟙 _, 𝟙 _, x, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in instance (F : WidePushoutShape J ⥤ Type*) [∀ i, Mono (F.map (.init i))] : F.IsLocallyDirected := by constructor diff --git a/Mathlib/CategoryTheory/Monad/Adjunction.lean b/Mathlib/CategoryTheory/Monad/Adjunction.lean index 82dcbaca3c9afe..31b91523497914 100644 --- a/Mathlib/CategoryTheory/Monad/Adjunction.lean +++ b/Mathlib/CategoryTheory/Monad/Adjunction.lean @@ -31,7 +31,7 @@ Finally we prove that reflective functors are `MonadicRightAdjoint` and coreflec namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor universe v₁ v₂ u₁ u₂ @@ -77,18 +77,21 @@ def toComonad (h : L ⊣ R) : Comonad D where rw [← L.map_comp] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The monad induced by the Eilenberg-Moore adjunction is the original monad. -/ @[simps!] def adjToMonadIso (T : Monad C) : T.adj.toMonad ≅ T := MonadIso.mk (NatIso.ofComponents fun _ => Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The comonad induced by the Eilenberg-Moore adjunction is the original comonad. -/ @[simps!] def adjToComonadIso (G : Comonad C) : G.adj.toComonad ≅ G := ComonadIso.mk (NatIso.ofComponents fun _ => Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in /-- Given an adjunction `L ⊣ R`, if `L ⋙ R` is abstractly isomorphic to the identity functor, then the unit is an isomorphism. @@ -106,6 +109,7 @@ def unitAsIsoOfIso (adj : L ⊣ R) (i : L ⋙ R ≅ 𝟭 C) : 𝟭 C ≅ L ⋙ R ext X exact (adj.toMonad.transport i).right_unit X +set_option backward.isDefEq.respectTransparency.types false in lemma isIso_unit_of_iso (adj : L ⊣ R) (i : L ⋙ R ≅ 𝟭 C) : IsIso adj.unit := (inferInstanceAs (IsIso (unitAsIsoOfIso adj i).hom)) @@ -186,6 +190,7 @@ instance [R.Faithful] (h : L ⊣ R) : (Monad.comparison h).Faithful where instance (T : Monad C) : (Monad.comparison T.adj).Full where map_surjective {_ _} f := ⟨⟨f.f, by simpa using! f.h⟩, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance (T : Monad C) : (Monad.comparison T.adj).EssSurj where mem_essImage X := @@ -235,6 +240,7 @@ instance Comonad.comparison_faithful_of_faithful [L.Faithful] (h : L ⊣ R) : instance (G : Comonad C) : (Comonad.comparison G.adj).Full where map_surjective f := ⟨⟨f.f, by simpa using! f.h⟩, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance (G : Comonad C) : (Comonad.comparison G.adj).EssSurj where mem_essImage X := @@ -308,14 +314,12 @@ noncomputable instance (G : Comonad C) : ComonadicLeftAdjoint G.forget where eqv := { } set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in -- TODO: This holds more generally for idempotent adjunctions, not just reflective adjunctions. instance μ_iso_of_reflective [Reflective R] : IsIso (reflectorAdjunction R).toMonad.μ := by dsimp infer_instance set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance δ_iso_of_coreflective [Coreflective R] : IsIso (coreflectorAdjunction R).toComonad.δ := by dsimp infer_instance @@ -325,8 +329,8 @@ attribute [instance] ComonadicLeftAdjoint.eqv namespace Reflective +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance [Reflective R] (X : (reflectorAdjunction R).toMonad.Algebra) : IsIso ((reflectorAdjunction R).unit.app X.A) := ⟨⟨X.a, @@ -354,6 +358,7 @@ instance comparison_essSurj [Reflective R] : Adjunction.right_triangle_components, comp_id] apply (X.unit_assoc _).symm +set_option backward.isDefEq.respectTransparency.types false in lemma comparison_full [R.Full] {L : C ⥤ D} (adj : L ⊣ R) : (Monad.comparison adj).Full where map_surjective f := ⟨R.preimage f.f, by cat_disch⟩ @@ -362,8 +367,8 @@ end Reflective namespace Coreflective +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance [Coreflective R] (X : (coreflectorAdjunction R).toComonad.Coalgebra) : IsIso ((coreflectorAdjunction R).counit.app X.A) := ⟨⟨X.a, @@ -386,6 +391,7 @@ instance comparison_essSurj [Coreflective R] : assoc] simpa using (coreflectorAdjunction R).counit.app X.A ≫= X.counit.symm +set_option backward.isDefEq.respectTransparency.types false in lemma comparison_full [R.Full] {L : C ⥤ D} (adj : R ⊣ L) : (Comonad.comparison adj).Full where map_surjective f := ⟨R.preimage f.f, by cat_disch⟩ diff --git a/Mathlib/CategoryTheory/Monad/Algebra.lean b/Mathlib/CategoryTheory/Monad/Algebra.lean index 3849a7c0dc307c..9985aeab6b9e77 100644 --- a/Mathlib/CategoryTheory/Monad/Algebra.lean +++ b/Mathlib/CategoryTheory/Monad/Algebra.lean @@ -132,7 +132,6 @@ def forget : Algebra T ⥤ C where obj A := A.A map f := f.f -set_option backward.isDefEq.respectTransparency false in /-- The free functor from the Eilenberg-Moore category, constructing an algebra for any object. -/ @[simps] def free : C ⥤ Algebra T where @@ -192,7 +191,6 @@ theorem algebra_mono_of_mono {X Y : Algebra T} (f : X ⟶ Y) [h : Mono f.f] : Mo instance : T.forget.IsRightAdjoint := ⟨T.free, ⟨T.adj⟩⟩ -set_option backward.isDefEq.respectTransparency false in /-- Given a monad morphism from `T₂` to `T₁`, we get a functor from the algebras of `T₁` to algebras of `T₂`. @@ -206,6 +204,7 @@ def algebraFunctorOfMonadHom {T₁ T₂ : Monad C} (h : T₂ ⟶ T₁) : Algebra assoc := by simp [A.assoc] } map f := { f := f.f } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The identity monad morphism induces the identity functor from the category of algebras to itself. @@ -214,6 +213,7 @@ The identity monad morphism induces the identity functor from the category of al def algebraFunctorOfMonadHomId {T₁ : Monad C} : algebraFunctorOfMonadHom (𝟙 T₁) ≅ 𝟭 _ := NatIso.ofComponents fun X => Algebra.isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A composition of monad morphisms gives the composition of corresponding functors. -/ @@ -222,6 +222,7 @@ def algebraFunctorOfMonadHomComp {T₁ T₂ T₃ : Monad C} (f : T₁ ⟶ T₂) algebraFunctorOfMonadHom (f ≫ g) ≅ algebraFunctorOfMonadHom g ⋙ algebraFunctorOfMonadHom f := NatIso.ofComponents fun X => Algebra.isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` and `g` are two equal morphisms of monads, then the functors of algebras induced by them are isomorphic. We define it like this as opposed to using `eqToIso` so that the components are nicer to prove @@ -232,6 +233,7 @@ def algebraFunctorOfMonadHomEq {T₁ T₂ : Monad C} {f g : T₁ ⟶ T₂} (h : algebraFunctorOfMonadHom f ≅ algebraFunctorOfMonadHom g := NatIso.ofComponents fun X => Algebra.isoMk (Iso.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Isomorphic monads give equivalent categories of algebras. Furthermore, they are equivalent as categories over `C`, that is, we have `algebraEquivOfIsoMonads h ⋙ forget = forget`. @@ -348,7 +350,6 @@ def forget : Coalgebra G ⥤ C where obj A := A.A map f := f.f -set_option backward.isDefEq.respectTransparency false in /-- The cofree functor from the Eilenberg-Moore category, constructing a coalgebra for any object. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Monad/Basic.lean b/Mathlib/CategoryTheory/Monad/Basic.lean index 163e1239fb486c..65a682c9735af0 100644 --- a/Mathlib/CategoryTheory/Monad/Basic.lean +++ b/Mathlib/CategoryTheory/Monad/Basic.lean @@ -135,7 +135,6 @@ lemma MonadHom.ext' {T₁ T₂ : Monad C} (f g : T₁ ⟶ T₂) (h : f.app = g.a lemma ComonadHom.ext' {T₁ T₂ : Comonad C} (f g : T₁ ⟶ T₂) (h : f.app = g.app) : f = g := ComonadHom.ext h -set_option backward.isDefEq.respectTransparency false in instance : Category (Monad C) where id M := { toNatTrans := 𝟙 (M : C ⥤ C) } comp f g := @@ -144,7 +143,6 @@ instance : Category (Monad C) where naturality := fun X Y h => by rw [assoc, f.1.naturality_assoc, g.1.naturality] } } set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance : Category (Comonad C) where id M := { toNatTrans := 𝟙 (M : C ⥤ C) } comp f g := @@ -176,7 +174,6 @@ theorem comp_toNatTrans {T₁ T₂ T₃ : Comonad C} (f : T₁ ⟶ T₂) (g : T (f ≫ g).toNatTrans = ((f.toNatTrans : _ ⟶ (T₂ : C ⥤ C)) ≫ g.toNatTrans : (T₁ : C ⥤ C) ⟶ T₃) := rfl -set_option backward.isDefEq.respectTransparency false in /-- Construct a monad isomorphism from a natural isomorphism of functors where the forward direction is a monad morphism. -/ @[simps] @@ -197,7 +194,6 @@ def MonadIso.mk {M N : Monad C} (f : (M : C ⥤ C) ≅ N) NatTrans.naturality_assoc, Iso.inv_hom_id_app_assoc, ← Functor.map_comp_assoc] simp } -set_option backward.isDefEq.respectTransparency false in /-- Construct a comonad isomorphism from a natural isomorphism of functors where the forward direction is a comonad morphism. -/ @[simps] @@ -301,14 +297,13 @@ instance : Inhabited (Comonad C) := end Comonad -open Iso Functor +open Iso CategoryTheory.Functor variable {C} namespace Monad set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Transport a monad structure on a functor along an isomorphism of functors. -/ def transport {F : C ⥤ C} (T : Monad C) (i : (T : C ⥤ C) ≅ F) : Monad C where toFunctor := F @@ -341,7 +336,6 @@ end Monad namespace Comonad -set_option backward.isDefEq.respectTransparency false in /-- Transport a comonad structure on a functor along an isomorphism of functors. -/ def transport {F : C ⥤ C} (T : Comonad C) (i : (T : C ⥤ C) ≅ F) : Comonad C where toFunctor := F @@ -368,12 +362,10 @@ end Comonad namespace Monad -set_option backward.isDefEq.respectTransparency false in lemma map_unit_app (T : Monad C) (X : C) [IsIso T.μ] : T.map (T.η.app X) = T.η.app (T.obj X) := by simp [← cancel_mono (T.μ.app _)] -set_option backward.isDefEq.respectTransparency false in lemma isSplitMono_iff_isIso_unit (T : Monad C) (X : C) [IsIso T.μ] : IsSplitMono (T.η.app X) ↔ IsIso (T.η.app X) := by refine ⟨fun _ ↦ ⟨retraction (T.η.app X), by simp, ?_⟩, fun _ ↦ inferInstance⟩ @@ -384,12 +376,10 @@ end Monad namespace Comonad -set_option backward.isDefEq.respectTransparency false in lemma map_counit_app (T : Comonad C) (X : C) [IsIso T.δ] : T.map (T.ε.app X) = T.ε.app (T.obj X) := by simp [← cancel_epi (T.δ.app _)] -set_option backward.isDefEq.respectTransparency false in lemma isSplitEpi_iff_isIso_counit (T : Comonad C) (X : C) [IsIso T.δ] : IsSplitEpi (T.ε.app X) ↔ IsIso (T.ε.app X) := by refine ⟨fun _ ↦ ⟨section_ (T.ε.app X), ?_, by simp⟩, fun _ ↦ inferInstance⟩ diff --git a/Mathlib/CategoryTheory/Monad/Coequalizer.lean b/Mathlib/CategoryTheory/Monad/Coequalizer.lean index 2db91d3044d8a7..acc41037f2d9bd 100644 --- a/Mathlib/CategoryTheory/Monad/Coequalizer.lean +++ b/Mathlib/CategoryTheory/Monad/Coequalizer.lean @@ -67,7 +67,6 @@ theorem FreeCoequalizer.condition : Algebra.Hom.ext X.assoc.symm set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by apply IsReflexivePair.mk' _ _ _ · apply (free T).map (T.η.app X.A) diff --git a/Mathlib/CategoryTheory/Monad/Comonadicity.lean b/Mathlib/CategoryTheory/Monad/Comonadicity.lean index d609e4248e6660..f6db31119b588c 100644 --- a/Mathlib/CategoryTheory/Monad/Comonadicity.lean +++ b/Mathlib/CategoryTheory/Monad/Comonadicity.lean @@ -127,6 +127,9 @@ def rightAdjointComparison apply equalizer.hom_ext simp [Adjunction.homEquiv_unit] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Provided we have the appropriate equalizers, we have an adjunction to the comparison functor. -/ @[simps! counit] @@ -146,6 +149,7 @@ theorem comparisonAdjunction_counit_f_aux (adj.homEquiv _ A.A).symm (equalizer.ι (G.map A.a) (adj.unit.app (G.obj A.A))) := congr_arg (adj.homEquiv _ _).symm (Category.id_comp _) +set_option backward.isDefEq.respectTransparency.types false in /-- This is a fork which is helpful for establishing comonadicity: the morphism from this fork to the Beck equalizer is the counit for the adjunction on the comparison functor. -/ @@ -181,6 +185,7 @@ def unitFork (B : C) : (adj.unit.app (G.obj (F.obj B))) := Fork.ofι (adj.unit.app B) (adj.unit_naturality _) +set_option backward.isDefEq.respectTransparency.types false in variable {adj} in /-- The counit fork is a limit provided `F` preserves it. -/ def counitLimitOfPreservesEqualizer (A : adj.toComonad.Coalgebra) @@ -230,7 +235,7 @@ variable (G) in If `F` is comonadic, it creates limits of `F`-cosplit pairs. This is the "boring" direction of Beck's comonadicity theorem, the converse is given in `comonadicOfCreatesFSplitEqualizers`. -/ -@[implicit_reducible] +@[instance_reducible] def createsFSplitEqualizersOfComonadic [ComonadicLeftAdjoint F] ⦃A B⦄ (f g : A ⟶ B) [F.IsCosplitPair f g] : CreatesLimit (parallelPair f g) F := by apply +allowSynthFailures comonadicCreatesLimitOfPreservesLimit @@ -276,10 +281,11 @@ instance [ReflectsLimitOfIsCosplitPair F] : ∀ (A : Coalgebra adj.toComonad), (NatTrans.app adj.unit (G.obj A.A))) F := fun _ => ReflectsLimitOfIsCosplitPair.out _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- To show `F` is a comonadic left adjoint, we can show it preserves and reflects `F`-split equalizers, and `C` has them. -/ -@[implicit_reducible] +@[instance_reducible] def comonadicOfHasPreservesReflectsFSplitEqualizers [HasEqualizerOfIsCosplitPair F] [PreservesLimitOfIsCosplitPair F] [ReflectsLimitOfIsCosplitPair F] : ComonadicLeftAdjoint F where @@ -327,7 +333,7 @@ Beck's comonadicity theorem. If `F` has a right adjoint and creates equalizers o then it is comonadic. This is the converse of `createsFSplitEqualizersOfComonadic`. -/ -@[implicit_reducible] +@[instance_reducible] def comonadicOfCreatesFSplitEqualizers [CreatesLimitOfIsCosplitPair F] : ComonadicLeftAdjoint F := by have I {A B} (f g : A ⟶ B) [F.IsCosplitPair f g] : HasLimit (parallelPair f g ⋙ F) := by @@ -341,7 +347,7 @@ def comonadicOfCreatesFSplitEqualizers [CreatesLimitOfIsCosplitPair F] : /-- An alternate version of Beck's comonadicity theorem. If `F` reflects isomorphisms, preserves equalizers of `F`-cosplit pairs and `C` has equalizers of `F`-cosplit pairs, then it is comonadic. -/ -@[implicit_reducible] +@[instance_reducible] def comonadicOfHasPreservesFSplitEqualizersOfReflectsIsomorphisms [F.ReflectsIsomorphisms] [HasEqualizerOfIsCosplitPair F] [PreservesLimitOfIsCosplitPair F] : ComonadicLeftAdjoint F := by @@ -371,11 +377,11 @@ instance [PreservesLimitOfIsCoreflexivePair F] : ∀ X : Coalgebra adj.toComonad variable [PreservesLimitOfIsCoreflexivePair F] -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- Coreflexive (crude) comonadicity theorem. If `F` has a right adjoint, `C` has and `F` preserves coreflexive equalizers and `F` reflects isomorphisms, then `F` is comonadic. -/ -@[implicit_reducible] +@[instance_reducible] def comonadicOfHasPreservesCoreflexiveEqualizersOfReflectsIsomorphisms : ComonadicLeftAdjoint F where R := G diff --git a/Mathlib/CategoryTheory/Monad/Equalizer.lean b/Mathlib/CategoryTheory/Monad/Equalizer.lean index 750f66a84e9648..5d4b2c26fb2ff8 100644 --- a/Mathlib/CategoryTheory/Monad/Equalizer.lean +++ b/Mathlib/CategoryTheory/Monad/Equalizer.lean @@ -68,7 +68,6 @@ theorem CofreeEqualizer.condition : Coalgebra.Hom.ext X.coassoc.symm set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance : IsCoreflexivePair (CofreeEqualizer.topMap X) (CofreeEqualizer.bottomMap X) := by apply IsCoreflexivePair.mk' _ _ _ · apply (cofree T).map (T.ε.app X.A) diff --git a/Mathlib/CategoryTheory/Monad/EquivMon.lean b/Mathlib/CategoryTheory/Monad/EquivMon.lean index 3152297d85940c..b2d10f686c5525 100644 --- a/Mathlib/CategoryTheory/Monad/EquivMon.lean +++ b/Mathlib/CategoryTheory/Monad/EquivMon.lean @@ -39,7 +39,6 @@ namespace Monad attribute [local instance] endofunctorMonoidalCategory -set_option backward.isDefEq.respectTransparency false in @[simps] instance (M : Monad C) : MonObj (M : C ⥤ C) where one := M.η diff --git a/Mathlib/CategoryTheory/Monad/Kleisli.lean b/Mathlib/CategoryTheory/Monad/Kleisli.lean index def5ecb1be5216..c5f61f501f6e40 100644 --- a/Mathlib/CategoryTheory/Monad/Kleisli.lean +++ b/Mathlib/CategoryTheory/Monad/Kleisli.lean @@ -53,7 +53,6 @@ instance [Inhabited C] (T : Monad C) : Inhabited (Kleisli T) := ⟨.mk T default variable (T) -set_option backward.isDefEq.respectTransparency false in attribute [local ext] Hom in /-- The Kleisli category on a monad `T`. cf Definition 5.2.9 in [Riehl][riehl2017]. -/ @@ -78,7 +77,6 @@ lemma hom_ext {x y : Kleisli T} {f g : x ⟶ y} (h : f.of = g.of) : f = g := namespace Adjunction -set_option backward.isDefEq.respectTransparency false in /-- The left adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/ @[simps] def toKleisli : C ⥤ Kleisli T where @@ -88,7 +86,6 @@ def toKleisli : C ⥤ Kleisli T where unfold_projs simp [← T.η.naturality g] -set_option backward.isDefEq.respectTransparency false in /-- The right adjoint of the adjunction which induces the monad `(T, η_ T, μ_ T)`. -/ @[simps] def fromKleisli : Kleisli T ⥤ C where @@ -110,7 +107,6 @@ def adj : toKleisli T ⊣ fromKleisli T := simp [← T.η.naturality_assoc g] } set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The composition of the adjunction gives the original functor. -/ def toKleisliCompFromKleisliIsoSelf : toKleisli T ⋙ fromKleisli T ≅ T := NatIso.ofComponents fun _ => Iso.refl _ @@ -142,7 +138,6 @@ structure Hom (c c' : Cokleisli U) where instance [Inhabited C] (U : Comonad C) : Inhabited (Cokleisli U) := ⟨.mk U default⟩ -set_option backward.isDefEq.respectTransparency false in /-- The co-Kleisli category on a comonad `U`. -/ @[simps!] instance category : Category (Cokleisli U) where @@ -158,14 +153,12 @@ lemma hom_ext {x y : Cokleisli U} {f g : x ⟶ y} (h : f.of = g.of) : f = g := namespace Adjunction -set_option backward.isDefEq.respectTransparency false in /-- The right adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/ @[simps] def toCokleisli : C ⥤ Cokleisli U where obj X := .mk U X map {X} {_} f := .mk (U.ε.app X ≫ f) -set_option backward.isDefEq.respectTransparency false in /-- The left adjoint of the adjunction which induces the comonad `(U, ε_ U, δ_ U)`. -/ @[simps] def fromCokleisli : Cokleisli U ⥤ C where @@ -173,8 +166,8 @@ def fromCokleisli : Cokleisli U ⥤ C where map {X} {_} f := U.δ.app X.of ≫ U.map f.of map_id _ := U.right_counit _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The co-Kleisli adjunction which gives rise to the comonad `(U, ε_ U, δ_ U)`. -/ def adj : fromCokleisli U ⊣ toCokleisli U := Adjunction.mkOfHomEquiv diff --git a/Mathlib/CategoryTheory/Monad/Limits.lean b/Mathlib/CategoryTheory/Monad/Limits.lean index 06482610e5a70a..2106b464eefd3d 100644 --- a/Mathlib/CategoryTheory/Monad/Limits.lean +++ b/Mathlib/CategoryTheory/Monad/Limits.lean @@ -32,7 +32,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor open CategoryTheory.Limits @@ -194,6 +194,7 @@ noncomputable def coconePoint : Algebra T where Functor.map_comp_assoc, commuting, Functor.map_comp, Category.assoc, commuting] apply (D.obj j).assoc_assoc _ +set_option backward.isDefEq.respectTransparency.types false in /-- (Impl) Construct the lifted cocone in `Algebra T` which will be colimiting. -/ @[simps] noncomputable def liftedCocone : Cocone D where @@ -230,6 +231,7 @@ end ForgetCreatesColimits open ForgetCreatesColimits -- TODO: the converse of this is true as well +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from the Eilenberg-Moore category for a monad creates any colimit which the monad itself preserves. -/ @@ -277,7 +279,7 @@ instance comp_comparison_hasLimit (F : J ⥤ D) (R : D ⥤ C) [MonadicRightAdjoi Monad.hasLimit_of_comp_forget_hasLimit (F ⋙ Monad.comparison (monadicAdjunction R)) /-- Any monadic functor creates limits. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monadicCreatesLimits (R : D ⥤ C) [MonadicRightAdjoint R] : CreatesLimitsOfSize.{v, u} R := createsLimitsOfNatIso (Monad.comparisonForget (monadicAdjunction R)) @@ -285,7 +287,7 @@ noncomputable def monadicCreatesLimits (R : D ⥤ C) [MonadicRightAdjoint R] : /-- The forgetful functor from the Eilenberg-Moore category for a monad creates any colimit which the monad itself preserves. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monadicCreatesColimitOfPreservesColimit (R : D ⥤ C) (K : J ⥤ D) [MonadicRightAdjoint R] [PreservesColimit (K ⋙ R) (monadicLeftAdjoint R ⋙ R)] [PreservesColimit ((K ⋙ R) ⋙ monadicLeftAdjoint R ⋙ R) (monadicLeftAdjoint R ⋙ R)] : @@ -314,7 +316,7 @@ noncomputable def monadicCreatesColimitOfPreservesColimit (R : D ⥤ C) (K : J apply createsColimitOfNatIso e /-- A monadic functor creates any colimits of shapes it preserves. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monadicCreatesColimitsOfShapeOfPreservesColimitsOfShape (R : D ⥤ C) [MonadicRightAdjoint R] [PreservesColimitsOfShape J R] : CreatesColimitsOfShape J R := letI : PreservesColimitsOfShape J (monadicLeftAdjoint R) := by @@ -324,7 +326,7 @@ noncomputable def monadicCreatesColimitsOfShapeOfPreservesColimitsOfShape (R : D ⟨monadicCreatesColimitOfPreservesColimit _ _⟩ /-- A monadic functor creates colimits if it preserves colimits. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monadicCreatesColimitsOfPreservesColimits (R : D ⥤ C) [MonadicRightAdjoint R] [PreservesColimitsOfSize.{v, u} R] : CreatesColimitsOfSize.{v, u} R where CreatesColimitsOfShape := @@ -527,6 +529,7 @@ noncomputable def conePoint : Coalgebra T where simp only [Functor.comp_obj, forget_obj, Functor.const_obj_obj, assoc] rw [(D.obj j).coassoc, ← assoc, ← assoc, commuting] +set_option backward.isDefEq.respectTransparency.types false in /-- (Impl) Construct the lifted cone in `Coalgebra T` which will be limiting. -/ @[simps] noncomputable def liftedCone : Cone D where @@ -564,6 +567,7 @@ end ForgetCreatesLimits' open ForgetCreatesLimits' -- TODO: the converse of this is true as well +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from the Eilenberg-Moore category for a comonad creates any limit which the comonad itself preserves. -/ @@ -608,7 +612,7 @@ instance comp_comparison_hasColimit (F : J ⥤ D) (R : D ⥤ C) [ComonadicLeftAd Comonad.hasColimit_of_comp_forget_hasColimit (F ⋙ Comonad.comparison (comonadicAdjunction R)) /-- Any comonadic functor creates colimits. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def comonadicCreatesColimits (R : D ⥤ C) [ComonadicLeftAdjoint R] : CreatesColimitsOfSize.{v, u} R := createsColimitsOfNatIso (Comonad.comparisonForget (comonadicAdjunction R)) @@ -616,7 +620,7 @@ noncomputable def comonadicCreatesColimits (R : D ⥤ C) [ComonadicLeftAdjoint R /-- The forgetful functor from the Eilenberg-Moore category for a comonad creates any limit which the comonad itself preserves. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def comonadicCreatesLimitOfPreservesLimit (R : D ⥤ C) (K : J ⥤ D) [ComonadicLeftAdjoint R] [PreservesLimit (K ⋙ R) (comonadicRightAdjoint R ⋙ R)] [PreservesLimit ((K ⋙ R) ⋙ comonadicRightAdjoint R ⋙ R) (comonadicRightAdjoint R ⋙ R)] : @@ -643,7 +647,7 @@ noncomputable def comonadicCreatesLimitOfPreservesLimit (R : D ⥤ C) (K : J ⥤ apply createsLimitOfNatIso e /-- A comonadic functor creates any limits of shapes it preserves. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def comonadicCreatesLimitsOfShapeOfPreservesLimitsOfShape (R : D ⥤ C) [ComonadicLeftAdjoint R] [PreservesLimitsOfShape J R] : CreatesLimitsOfShape J R := letI : PreservesLimitsOfShape J (comonadicRightAdjoint R) := by @@ -653,7 +657,7 @@ noncomputable def comonadicCreatesLimitsOfShapeOfPreservesLimitsOfShape (R : D ⟨comonadicCreatesLimitOfPreservesLimit _ _⟩ /-- A comonadic functor creates limits if it preserves limits. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def comonadicCreatesLimitsOfPreservesLimits (R : D ⥤ C) [ComonadicLeftAdjoint R] [PreservesLimitsOfSize.{v, u} R] : CreatesLimitsOfSize.{v, u} R where CreatesLimitsOfShape := diff --git a/Mathlib/CategoryTheory/Monad/Monadicity.lean b/Mathlib/CategoryTheory/Monad/Monadicity.lean index 1c7aa77231f9a3..e701666087cc8b 100644 --- a/Mathlib/CategoryTheory/Monad/Monadicity.lean +++ b/Mathlib/CategoryTheory/Monad/Monadicity.lean @@ -84,6 +84,7 @@ def comparisonLeftAdjointObj (A : adj.toMonad.Algebra) [HasCoequalizer (F.map A.a) (adj.counit.app _)] : D := coequalizer (F.map A.a) (adj.counit.app _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- We have a bijection of homsets which will be used to construct the left adjoint to the comparison @@ -146,6 +147,7 @@ theorem comparisonAdjunction_unit_f_aux (coequalizer.π (F.map A.a) (adj.counit.app (F.obj A.A))) := congr_arg (adj.homEquiv _ _) (Category.comp_id _) +set_option backward.isDefEq.respectTransparency.types false in /-- This is a cofork which is helpful for establishing monadicity: the morphism from the Beck coequalizer to this cofork is the unit for the adjunction on the comparison functor. -/ @@ -156,6 +158,7 @@ def unitCofork (A : adj.toMonad.Algebra) Cofork.ofπ (G.map (coequalizer.π (F.map A.a) (adj.counit.app (F.obj A.A)))) (by rw [← G.map_comp, coequalizer.condition, G.map_comp]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem unitCofork_π (A : adj.toMonad.Algebra) [HasCoequalizer (F.map A.a) (adj.counit.app (F.obj A.A))] : @@ -186,6 +189,7 @@ def counitCofork (B : D) : (adj.counit.app (F.obj (G.obj B))) := Cofork.ofπ (adj.counit.app B) (adj.counit_naturality _) +set_option backward.isDefEq.respectTransparency.types false in variable {adj} in /-- The unit cofork is a colimit provided `G` preserves it. -/ def unitColimitOfPreservesCoequalizer (A : adj.toMonad.Algebra) @@ -234,7 +238,7 @@ variable (G) in If `G` is monadic, it creates colimits of `G`-split pairs. This is the "boring" direction of Beck's monadicity theorem, the converse is given in `monadicOfCreatesGSplitCoequalizers`. -/ -@[implicit_reducible] +@[instance_reducible] def createsGSplitCoequalizersOfMonadic [MonadicRightAdjoint G] ⦃A B⦄ (f g : A ⟶ B) [G.IsSplitPair f g] : CreatesColimit (parallelPair f g) G := by apply +allowSynthFailures monadicCreatesColimitOfPreservesColimit @@ -291,10 +295,11 @@ instance [ReflectsColimitOfIsSplitPair G] : ∀ (A : Algebra adj.toMonad), (NatTrans.app adj.counit (F.obj A.A))) G := fun _ => ReflectsColimitOfIsSplitPair.out _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- To show `G` is a monadic right adjoint, we can show it preserves and reflects `G`-split coequalizers, and `D` has them. -/ -@[implicit_reducible] +@[instance_reducible] def monadicOfHasPreservesReflectsGSplitCoequalizers [HasCoequalizerOfIsSplitPair G] [PreservesColimitOfIsSplitPair G] [ReflectsColimitOfIsSplitPair G] : MonadicRightAdjoint G where @@ -347,7 +352,7 @@ instance [CreatesColimitOfIsSplitPair G] : ∀ (A : Algebra adj.toMonad), pairs, then it is monadic. This is the converse of `createsGSplitCoequalizersOfMonadic`. -/ -@[implicit_reducible] +@[instance_reducible] def monadicOfCreatesGSplitCoequalizers [CreatesColimitOfIsSplitPair G] : MonadicRightAdjoint G := by have I {A B} (f g : A ⟶ B) [G.IsSplitPair f g] : HasColimit (parallelPair f g ⋙ G) := by @@ -361,7 +366,7 @@ def monadicOfCreatesGSplitCoequalizers [CreatesColimitOfIsSplitPair G] : /-- An alternate version of **Beck's monadicity theorem**: if `G` reflects isomorphisms, preserves coequalizers of `G`-split pairs and `C` has coequalizers of `G`-split pairs, then it is monadic. -/ -@[implicit_reducible] +@[instance_reducible] def monadicOfHasPreservesGSplitCoequalizersOfReflectsIsomorphisms [G.ReflectsIsomorphisms] [HasCoequalizerOfIsSplitPair G] [PreservesColimitOfIsSplitPair G] : MonadicRightAdjoint G := by @@ -393,10 +398,11 @@ instance [PreservesColimitOfIsReflexivePair G] : ∀ X : Algebra adj.toMonad, variable [PreservesColimitOfIsReflexivePair G] +set_option backward.isDefEq.respectTransparency.types false in /-- Reflexive (crude) monadicity theorem. If `G` has a right adjoint, `D` has and `G` preserves reflexive coequalizers and `G` reflects isomorphisms, then `G` is monadic. -/ -@[implicit_reducible] +@[instance_reducible] def monadicOfHasPreservesReflexiveCoequalizersOfReflectsIsomorphisms : MonadicRightAdjoint G where L := F adj := adj diff --git a/Mathlib/CategoryTheory/Monad/Products.lean b/Mathlib/CategoryTheory/Monad/Products.lean index b8629121ee0805..7bc8dacc6f0815 100644 --- a/Mathlib/CategoryTheory/Monad/Products.lean +++ b/Mathlib/CategoryTheory/Monad/Products.lean @@ -86,7 +86,6 @@ end section -open Monad variable [HasBinaryCoproducts C] @@ -98,6 +97,7 @@ def coprodMonad : Monad C where η := { app := fun _ => coprod.inr } μ := { app := fun _ => coprod.desc coprod.inl (𝟙 _) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The forward direction of the equivalence from algebras for the coproduct monad to the under category. diff --git a/Mathlib/CategoryTheory/Monoidal/Action/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Action/Basic.lean index 6b0534d4b0818e..7f08186e10469e 100644 --- a/Mathlib/CategoryTheory/Monoidal/Action/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Action/Basic.lean @@ -338,6 +338,7 @@ variable {D} in /-- Bundle `c ↦ c ⊙ₗ d` as a functor. -/ abbrev actionRight (d : D) : C ⥤ D := curriedAction C D |>.flip.obj d +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Bundle `αₗ _ _ _` as an isomorphism of trifunctors. -/ @[simps!] @@ -649,6 +650,7 @@ variable {D} in /-- Bundle `c ↦ d ⊙ᵣ c` as a functor. -/ abbrev actionLeft (d : D) : C ⥤ D := curriedAction C D |>.flip.obj d +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Bundle `αᵣ _ _ _` as an isomorphism of trifunctors. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Monoidal/Action/End.lean b/Mathlib/CategoryTheory/Monoidal/Action/End.lean index 838a81c229eab7..62c6253e6d5036 100644 --- a/Mathlib/CategoryTheory/Monoidal/Action/End.lean +++ b/Mathlib/CategoryTheory/Monoidal/Action/End.lean @@ -92,10 +92,9 @@ end variable {C D} -set_option backward.isDefEq.respectTransparency false in /-- A monoidal functor `F : C ⥤ (D ⥤ D)ᴹᵒᵖ` can be thought of as a left action of `C` on `D`. -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def actionOfMonoidalFunctorToEndofunctorMop (F : C ⥤ (D ⥤ D)ᴹᵒᵖ) [F.Monoidal] : MonoidalLeftAction C D where actionObj c d := (F.obj c).unmop.obj d @@ -182,10 +181,9 @@ instance curriedActionMonoidal [MonoidalRightAction C D] : simpa [-actionHom_leftUnitor] using t ⊴ᵣ (λ_ x).inv ≫= actionHom_leftUnitor x t -set_option backward.isDefEq.respectTransparency false in /-- A monoidal functor `F : C ⥤ D ⥤ D` can be thought of as a right action of `C` on `D`. -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def actionOfMonoidalFunctorToEndofunctor (F : C ⥤ D ⥤ D) [F.Monoidal] : MonoidalRightAction C D where actionObj d c := (F.obj c).obj d diff --git a/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean b/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean index b71d35582b3161..49162b8e1875f6 100644 --- a/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean +++ b/Mathlib/CategoryTheory/Monoidal/Action/Opposites.lean @@ -41,7 +41,7 @@ open MonoidalOpposite /-- Define a left action of `C` on `D` from a right action of `Cᴹᵒᵖ` on `D` via the formula `c ⊙ₗ d := d ⊙ᵣ (mop c)`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def leftActionOfMonoidalOppositeRightAction [MonoidalRightAction Cᴹᵒᵖ D] : MonoidalLeftAction C D where actionObj c d := d ⊙ᵣ mop c @@ -257,7 +257,7 @@ open MonoidalOpposite /-- Define a right action of `C` on `D` from a left action of `Cᴹᵒᵖ` on `D` via the formula `d ⊙ᵣ c := (mop c) ⊙ₗ d`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def rightActionOfMonoidalOppositeLeftAction [MonoidalLeftAction Cᴹᵒᵖ D] : MonoidalRightAction C D where actionObj d c := mop c ⊙ₗ d diff --git a/Mathlib/CategoryTheory/Monoidal/Arrow.lean b/Mathlib/CategoryTheory/Monoidal/Arrow.lean index 1ade744d18a540..1085b581d495da 100644 --- a/Mathlib/CategoryTheory/Monoidal/Arrow.lean +++ b/Mathlib/CategoryTheory/Monoidal/Arrow.lean @@ -27,7 +27,7 @@ universe v u namespace CategoryTheory -open Limits MonoidalCategory Functor PushoutObjObj +open Limits MonoidalCategory CategoryTheory.Functor PushoutObjObj variable {C : Type u} [Category.{v} C] @@ -52,6 +52,7 @@ scoped instance [HasPushouts C] [HasInitial C] [CartesianMonoidalCategory C] [Mo variable [HasPushouts C] [HasInitial C] [CartesianMonoidalCategory C] [MonoidalClosed C] [BraidedCategory C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma tensorHom_comp_tensorHom {X₁ Y₁ Z₁ X₂ Y₂ Z₂ : Arrow C} (f₁ : X₁ ⟶ Y₁) (f₂ : X₂ ⟶ Y₂) (g₁ : Y₁ ⟶ Z₁) (g₂ : Y₂ ⟶ Z₂) : @@ -114,6 +115,7 @@ lemma triangle (X Y : Arrow C) : exact initialIsInitial.ofIso (zeroMul initialIsInitial).symm · simp [← comp_whiskerRight_assoc] +set_option backward.isDefEq.respectTransparency.types false in /-- The monoidal category instance induced by the pushout-product. -/ scoped instance : MonoidalCategory (Arrow C) where tensorHom_comp_tensorHom := tensorHom_comp_tensorHom diff --git a/Mathlib/CategoryTheory/Monoidal/Bimod.lean b/Mathlib/CategoryTheory/Monoidal/Bimod.lean index ee60388b5f483c..f97cef76e94937 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimod.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimod.lean @@ -626,6 +626,7 @@ noncomputable def hom : TensorBimod.X (regular R) P ⟶ P.X := noncomputable def inv : P.X ⟶ TensorBimod.X (regular R) P := (λ_ P.X).inv ≫ (η[R.X] ▷ _) ≫ coequalizer.π _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem hom_inv_id : hom P ≫ inv P = 𝟙 _ := by dsimp only [hom, inv, TensorBimod.X] @@ -688,6 +689,7 @@ noncomputable def hom : TensorBimod.X P (regular S) ⟶ P.X := noncomputable def inv : P.X ⟶ TensorBimod.X P (regular S) := (ρ_ P.X).inv ≫ (_ ◁ η[S.X]) ≫ coequalizer.π _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem hom_inv_id : hom P ≫ inv P = 𝟙 _ := by dsimp only [hom, inv, TensorBimod.X] @@ -1014,7 +1016,7 @@ theorem triangle_bimod {X Y Z : Mon C} (M : Bimod X Y) (N : Bimod Y Z) : simp only [Category.assoc] /-- The bicategory of algebras (monoids) and bimodules, all internal to some monoidal category. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monBicategory : Bicategory (Mon C) where Hom X Y := Bimod X Y homCategory X Y := (inferInstance : Category (Bimod X Y)) diff --git a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean index 299305871404f6..7bc7af9e4b071a 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean @@ -109,6 +109,7 @@ def toMonComonObj (M : Bimon C) : Mon (Comon C) where mon.mul.hom := μ[M.X.X] mon.mul.isComonHom_hom.hom_comul := by simp +set_option backward.isDefEq.respectTransparency.types false in /-- The forward direction of `Comon (Mon C) ≌ Mon (Comon C)` -/ @[simps] def toMonComon : Bimon C ⥤ Mon (Comon C) where @@ -141,6 +142,7 @@ def ofMonComonObj (M : Mon (Comon C)) : Bimon C where comon.counit := .mk' ε[M.X.X] comon.comul := .mk' Δ[M.X.X] +set_option backward.isDefEq.respectTransparency.types false in variable (C) in /-- The backward direction of `Comon (Mon C) ≌ Mon (Comon C)` -/ @[simps] @@ -148,16 +150,19 @@ def ofMonComon : Mon (Comon C) ⥤ Bimon C where obj := ofMonComonObj map f := .mk' ((Comon.forget C).mapMon.map f) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toMonComon_ofMonComon_obj_one (M : Bimon C) : η[((toMonComon C ⋙ ofMonComon C).obj M).X.X] = 𝟙 _ ≫ η[M.X.X] := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toMonComon_ofMonComon_obj_mul (M : Bimon C) : μ[((toMonComon C ⋙ ofMonComon C).obj M).X.X] = 𝟙 _ ≫ μ[M.X.X] := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `equivMonComonUnitIsoApp`. -/ @[simps!] def equivMonComonUnitIsoAppXAux (M : Bimon C) : @@ -193,6 +198,9 @@ theorem ofMonComon_toMonComon_obj_comul (M : Mon (Comon C)) : Δ[((ofMonComon C ⋙ toMonComon C).obj M).X.X] = Δ[M.X.X] ≫ 𝟙 _ := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `equivMonComonCounitIsoApp`. -/ @[simps!] def equivMonComonCounitIsoAppXAux (M : Mon (Comon C)) : @@ -202,6 +210,9 @@ def equivMonComonCounitIsoAppXAux (M : Mon (Comon C)) : set_option backward.isDefEq.respectTransparency false in instance (M : Mon (Comon C)) : IsComonHom (equivMonComonCounitIsoAppXAux M).hom where +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `equivMonComonCounitIsoApp`. -/ @[simps!] def equivMonComonCounitIsoAppX (M : Mon (Comon C)) : @@ -218,6 +229,7 @@ def equivMonComonCounitIsoApp (M : Mon (Comon C)) : (ofMonComon C ⋙ toMonComon C).obj M ≅ M := Mon.mkIso <| (equivMonComonCounitIsoAppX M) +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence `Comon (Mon C) ≌ Mon (Comon C)` -/ def equivMonComon : Bimon C ≌ Mon (Comon C) where functor := toMonComon C @@ -232,11 +244,13 @@ variable (C) in @[simps!] def trivial : Bimon C := Comon.trivial (Mon C) +set_option backward.isDefEq.respectTransparency.types false in /-- The bimonoid morphism from the trivial bimonoid to any bimonoid. -/ @[simps] def trivialTo (A : Bimon C) : trivial C ⟶ A := .mk' (default : Mon.trivial C ⟶ A.X) +set_option backward.isDefEq.respectTransparency.types false in /-- The bimonoid morphism from any bimonoid to the trivial bimonoid. -/ @[simps!] def toTrivial (A : Bimon C) : A ⟶ trivial C := @@ -244,10 +258,12 @@ def toTrivial (A : Bimon C) : A ⟶ trivial C := /-! ### Additional lemmas -/ +set_option backward.isDefEq.respectTransparency.types false in theorem BimonObjAux_counit (M : Bimon C) : ε[((toComon C).obj M).X] = ε[M.X].hom := Category.comp_id _ +set_option backward.isDefEq.respectTransparency.types false in theorem BimonObjAux_comul (M : Bimon C) : Δ[((toComon C).obj M).X] = Δ[M.X].hom := Category.comp_id _ diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean index 4d9cdeef1e52ad..c89297f69b8036 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean @@ -147,6 +147,7 @@ def tensorLeftIsoTensorRight (X : C) : hom := { app Y := (β_ X Y).hom } inv := { app Y := (β_ X Y).inv } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (C) in /-- The braiding isomorphism as a natural isomorphism of bifunctors `C ⥤ C ⥤ C`. -/ @@ -208,7 +209,7 @@ end BraidedCategory Verifying the axioms for a braiding by checking that the candidate braiding is sent to a braiding by a faithful monoidal functor. -/ -@[implicit_reducible] +@[instance_reducible] def BraidedCategory.ofFaithful {C D : Type*} [Category* C] [Category* D] [MonoidalCategory C] [MonoidalCategory D] (F : C ⥤ D) [F.Monoidal] [F.Faithful] [BraidedCategory D] (β : ∀ X Y : C, X ⊗ Y ≅ Y ⊗ X) @@ -252,7 +253,7 @@ def BraidedCategory.ofFaithful {C D : Type*} [Category* C] [Category* D] [Monoid braiding_naturality_left_assoc, Functor.LaxMonoidal.associativity_inv, hexagon_reverse_assoc] /-- Pull back a braiding along a fully faithful monoidal functor. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def BraidedCategory.ofFullyFaithful {C D : Type*} [Category* C] [Category* D] [MonoidalCategory C] [MonoidalCategory D] (F : C ⥤ D) [F.Monoidal] [F.Full] [F.Faithful] [BraidedCategory D] : BraidedCategory C := @@ -405,7 +406,7 @@ instance (F : C ⥤ D) (G : D ⥤ E) [F.LaxBraided] [G.LaxBraided] : /-- Given two lax monoidal, monoidally isomorphic functors, if one is lax braided, so is the other. -/ -@[implicit_reducible] +@[instance_reducible] def ofNatIso {F G : C ⥤ D} (i : F ≅ G) [F.LaxBraided] [G.LaxMonoidal] [NatTrans.IsMonoidal i.hom] : G.LaxBraided where braided X Y := by @@ -473,6 +474,7 @@ set_option backward.isDefEq.respectTransparency false in def homMk {F G : LaxBraidedFunctor C D} (f : F.toFunctor ⟶ G.toFunctor) [NatTrans.IsMonoidal f] : F ⟶ G := ⟨f, inferInstance⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Constructor for isomorphisms in the category `LaxBraidedFunctor C D`. -/ @[simps] def isoMk {F G : LaxBraidedFunctor C D} (e : F.toFunctor ≅ G.toFunctor) @@ -538,14 +540,14 @@ lemma Functor.map_braiding (F : C ⥤ D) (X Y : C) [F.Braided] : /-- A braided category with a faithful braided functor to a symmetric category is itself symmetric. -/ -@[implicit_reducible] +@[instance_reducible] def SymmetricCategory.ofFaithful {C D : Type*} [Category* C] [Category* D] [MonoidalCategory C] [MonoidalCategory D] [BraidedCategory C] [SymmetricCategory D] (F : C ⥤ D) [F.Braided] [F.Faithful] : SymmetricCategory C where symmetry X Y := F.map_injective (by simp) /-- Pull back a symmetric braiding along a fully faithful monoidal functor. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def SymmetricCategory.ofFullyFaithful {C D : Type*} [Category* C] [Category* D] [MonoidalCategory C] [MonoidalCategory D] (F : C ⥤ D) [F.Monoidal] [F.Full] [F.Faithful] [SymmetricCategory D] : SymmetricCategory C := @@ -901,7 +903,7 @@ lemma SymmetricCategory.reverseBraiding_eq (C : Type u₁) [Category.{v₁} C] /-- The identity functor from `C` to `C`, where the codomain is given the reversed braiding, upgraded to a braided functor. -/ -@[implicit_reducible] +@[instance_reducible] def SymmetricCategory.equivReverseBraiding (C : Type u₁) [Category.{v₁} C] [MonoidalCategory C] [SymmetricCategory C] := @Functor.Braided.mk C _ _ _ C _ _ (reverseBraiding C) (𝟭 C) _ <| by diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Multifunctor.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Multifunctor.lean index 0b8ec4dbf448c4..c04b8a6fb302d1 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Multifunctor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Multifunctor.lean @@ -27,7 +27,7 @@ namespace CategoryTheory variable {C : Type*} [Category* C] [MonoidalCategory C] -open MonoidalCategory Functor +open MonoidalCategory CategoryTheory.Functor namespace BraidedCategory @@ -131,6 +131,9 @@ variable (C) in def firstMap₃ : functor₂₃₁ C ⟶ functor₂₃₁' C where app _ := { app _ := { app _ := (α_ _ _ _).hom } } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The top right map in the forward hexagon identity. -/ @[simps!] def secondMap₁ (β : curriedTensor C ≅ (curriedTensor C).flip) : functor₁₂₃ C ⟶ functor₂₁₃ C := @@ -142,6 +145,9 @@ variable (C) in def secondMap₂ : functor₂₁₃ C ⟶ functor₂₁₃' C where app _ := { app _ := { app _ := (α_ _ _ _).hom } } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The bottom right map in the forward hexagon identity. -/ @[simps!] def secondMap₃ (β : curriedTensor C ≅ (curriedTensor C).flip) : functor₂₁₃' C ⟶ functor₂₃₁' C := @@ -176,6 +182,9 @@ firstMap₂ | |secondMap₂ | | ``` -/ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The middle left map in the reverse hexagon identity. -/ @[simps!] def firstMap₂ (β : curriedTensor C ≅ (curriedTensor C).flip) : functor₁₂₃ C ⟶ functor₃₁₂' C := @@ -188,6 +197,9 @@ variable (C) in def firstMap₃ : functor₃₁₂' C ⟶ functor₃₁₂ C := flip₂₃Functor.map ((flipFunctor _ _ _).map (curriedAssociatorNatIso C).inv) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The top right map in the reverse hexagon identity. -/ @[simps!] def secondMap₁ (β : curriedTensor C ≅ (curriedTensor C).flip) : functor₁₂₃' C ⟶ functor₁₃₂' C := @@ -199,6 +211,9 @@ variable (C) in def secondMap₂ : functor₁₃₂' C ⟶ functor₁₃₂ C where app _ := { app _ := { app _ := (α_ _ _ _).inv } } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The bottom right map in the reverse hexagon identity. -/ @[simps!] def secondMap₃ (β : curriedTensor C ≅ (curriedTensor C).flip) : functor₁₃₂ C ⟶ functor₃₁₂ C := @@ -223,7 +238,7 @@ Given a braiding `β : curriedTensor C ≅ (curriedTensor C).flip` as a natural bifunctors, and the two equalities `hexagon_forward` and `hexagon_reverse` of natural transformations between trifunctors, we obtain a braided category structure. -/ -@[implicit_reducible] +@[instance_reducible] def ofBifunctor : BraidedCategory C where braiding X Y := (β.app X).app Y braiding_naturality_right _ _ _ _ := (β.app _).hom.naturality _ @@ -241,7 +256,7 @@ open BraidedCategory Alternative constructor for symmetric categories, where the symmetry of the braiding is phrased as an equality of natural transformation of bifunctors. -/ -@[implicit_reducible] +@[instance_reducible] def SymmetricCategory.ofCurried [BraidedCategory C] (h : (curriedBraidingNatIso C).hom ≫ (flipFunctor _ _ _).map (curriedBraidingNatIso C).hom = 𝟙 _) : diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Reflection.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Reflection.lean index b7501b5b3e9eae..925363617de2a8 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Reflection.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Reflection.lean @@ -32,7 +32,7 @@ apply Day's reflection theorem to prove that `C` is also closed monoidal. namespace CategoryTheory.Monoidal.Reflective -open Category MonoidalCategory MonoidalClosed BraidedCategory Functor +open Category MonoidalCategory MonoidalClosed BraidedCategory CategoryTheory.Functor variable {C D : Type*} [Category* C] [Category* D] @@ -41,7 +41,6 @@ variable [MonoidalCategory D] [SymmetricCategory D] [MonoidalClosed D] section variable {R : C ⥤ D} [R.Faithful] [R.Full] {L : D ⥤ C} (adj : L ⊣ R) -set_option backward.isDefEq.respectTransparency false in /-- The uncurried retraction of the unit in the proof of `4 → 1` in `isIso_tfae` below. -/ private noncomputable def adjRetractionAux (c : C) (d : D) [IsIso (L.map (adj.unit.app ((ihom d).obj (R.obj c)) ⊗ₘ adj.unit.app d))] : @@ -56,7 +55,6 @@ private noncomputable def adjRetraction (c : C) (d : D) (L ⋙ R).obj ((ihom d).obj (R.obj c)) ⟶ ((ihom d).obj (R.obj c)) := curry <| adjRetractionAux adj c d -set_option backward.isDefEq.respectTransparency false in private lemma adjRetraction_is_retraction (c : C) (d : D) [IsIso (L.map (adj.unit.app ((ihom d).obj (R.obj c)) ⊗ₘ adj.unit.app d))] : adj.unit.app ((ihom d).obj (R.obj c)) ≫ adjRetraction adj c d = 𝟙 _ := by @@ -220,7 +218,7 @@ instance (c : C) (d : D) : IsIso (adj.unit.app ((ihom d).obj (R.obj c))) := by set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `monoidalClosed`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def closed (c : C) : Closed c where rightAdj := R ⋙ (ihom (R.obj c)) ⋙ L adj := by @@ -240,7 +238,7 @@ noncomputable def closed (c : C) : Closed c where Given a reflective functor `R : C ⥤ D` with a monoidal left adjoint, such that `D` is symmetric monoidal closed, then `C` is monoidal closed. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monoidalClosed : MonoidalClosed C where closed c := closed adj c diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean index 198b65045a1c60..5c0fb0d708fde4 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Basic.lean @@ -474,7 +474,7 @@ instance (priority := low) toSymmetricCategory : SymmetricCategory C where /-- `CartesianMonoidalCategory` implies `BraidedCategory`. This is not an instance to prevent diamonds. -/ -@[implicit_reducible] +@[instance_reducible] def _root_.CategoryTheory.BraidedCategory.ofCartesianMonoidalCategory : BraidedCategory C where braiding X Y := { hom := lift (snd _ _) (fst _ _), inv := lift (snd _ _) (fst _ _) } @@ -679,6 +679,7 @@ def prodComparisonBifunctorNatTrans : variable {E : Type u₂} [Category.{v₂} E] [CartesianMonoidalCategory E] (G : D ⥤ E) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem prodComparisonBifunctorNatTrans_comp : prodComparisonBifunctorNatTrans (F ⋙ G) = Functor.whiskerRight @@ -801,6 +802,7 @@ open Limits variable {P : ObjectProperty C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- TODO: Introduce `ClosedUnderFiniteProducts`? /-- The restriction of a Cartesian-monoidal category along an object property that's closed under @@ -919,7 +921,6 @@ lemma μ_snd (X Y : C) : μ F X Y ≫ F.map (snd X Y) = snd (F.obj X) (F.obj Y) (cancel_epi (μIso _ _ _).inv).1 (by simp) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in attribute [-instance] Functor.LaxMonoidal.comp Functor.Monoidal.instComp in @[reassoc] lemma μ_comp [(F ⋙ G).Monoidal] (X Y : C) : μ (F ⋙ G) X Y = μ G _ _ ≫ G.map (μ F X Y) := by @@ -988,16 +989,21 @@ end Braided namespace EssImageSubcategory variable [F.Full] [F.Faithful] [PreservesFiniteProducts F] {T X Y Z : F.EssImageSubcategory} +set_option backward.isDefEq.respectTransparency.types false in lemma tensor_obj (X Y : F.EssImageSubcategory) : (X ⊗ Y).obj = X.obj ⊗ Y.obj := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma lift_def (f : T ⟶ X) (g : T ⟶ Y) : lift f g = ObjectProperty.homMk (lift f.hom g.hom) := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma associator_hom_def (X Y Z : F.EssImageSubcategory) : (α_ X Y Z).hom = ObjectProperty.homMk (α_ X.obj Y.obj Z.obj).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma associator_inv_def (X Y Z : F.EssImageSubcategory) : (α_ X Y Z).inv = ObjectProperty.homMk (α_ X.obj Y.obj Z.obj).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma toUnit_def (X : F.EssImageSubcategory) : toUnit X = ObjectProperty.homMk (toUnit X.obj) := rfl diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Cat.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Cat.lean index fe020f0ea6ccd3..1e7689bea5f4a3 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Cat.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Cat.lean @@ -50,6 +50,7 @@ def fromChosenTerminalEquiv {C : Type u} [Category.{v} C] : Cat.chosenTerminal def prodCone (C D : Cat.{v, u}) : BinaryFan C D := .mk (P := .of (C × D)) (Prod.fst _ _).toCatHom (Prod.snd _ _).toCatHom +set_option backward.isDefEq.respectTransparency.types false in /-- The product cone in `Cat` is indeed a product. -/ def isLimitProdCone (X Y : Cat) : IsLimit (prodCone X Y) := BinaryFan.isLimitMk (fun S => (S.fst.toFunctor.prod' S.snd.toFunctor).toCatHom) (fun _ => rfl) diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/CommGrp_.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/CommGrp_.lean index 275e6483a968e2..dc5467926bc884 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/CommGrp_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/CommGrp_.lean @@ -30,7 +30,7 @@ class abbrev CommGrpObj := GrpObj X, IsCommMonObj X variable (X) in /-- If `X` represents a presheaf of commutative groups, then `X` is a commutative group object. -/ -@[implicit_reducible] +@[instance_reducible] def CommGrpObj.ofRepresentableBy (F : Cᵒᵖ ⥤ CommGrpCat.{w}) (α : (F ⋙ forget _).RepresentableBy X) : CommGrpObj X where __ := GrpObj.ofRepresentableBy X (F ⋙ forget₂ CommGrpCat GrpCat) α diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean index 29c9809982535a..7f1644c9620694 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/FunctorCategory.lean @@ -29,6 +29,7 @@ variable {J C D E : Type*} [Category* J] [Category* C] [Category* D] [Category* namespace Functor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance cartesianMonoidalCategory : CartesianMonoidalCategory (J ⥤ C) where fst X Y := { app _ := CartesianMonoidalCategory.fst _ _ } diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean index 243c2fd46acf72..e941bb97c780d6 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Grp.lean @@ -30,7 +30,7 @@ variable {C : Type u} [Category.{v} C] [CartesianMonoidalCategory C] variable (X) in /-- If `X` represents a presheaf of monoids, then `X` is a monoid object. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If `X` represents a presheaf of additive monoids, then `X` is an additive monoid object. -/] def GrpObj.ofRepresentableBy (F : Cᵒᵖ ⥤ GrpCat.{w}) (α : (F ⋙ forget _).RepresentableBy X) : GrpObj X where @@ -91,6 +91,9 @@ lemma GrpObj.ofRepresentableBy_yonedaGrpObjRepresentableBy : ofRepresentableBy G _ (yonedaGrpObjRepresentableBy G) = ‹GrpObj G› := by ext; change lift (fst G G) (snd G G) ≫ μ = μ; rw [lift_fst_snd, Category.id_comp] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in variable (X) in /-- If `X` represents a presheaf of groups `F`, then `Hom(-, X)` is isomorphic to `F` as a presheaf of groups. -/ @@ -116,6 +119,9 @@ def yonedaGrp : Grp C ⥤ Cᵒᵖ ⥤ GrpCat.{v} where obj G := yonedaGrpObj G.X map {G H} ψ := { app Y := GrpCat.ofHom ((yonedaMon.map ψ.hom).app Y).hom } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_additive (attr := reassoc)] lemma yonedaGrp_naturality (α : yonedaGrpObj G ⟶ yonedaGrpObj H) (f : X ⟶ Y) (g : Y ⟶ G) : α.app _ (f ≫ g) = f ≫ α.app _ g := congr($(α.naturality f.op) g) diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/GrpLimits.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/GrpLimits.lean index c5d09eb5c2c1e6..b163f406611294 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/GrpLimits.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/GrpLimits.lean @@ -20,7 +20,7 @@ We show that `Grp C` has limits. namespace CategoryTheory -open Functor Grp Limits MonObj +open CategoryTheory.Functor Grp Limits MonObj universe w v diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean index 6e548c09b5da89..25bad74200f4f0 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Mon.lean @@ -176,7 +176,7 @@ end Mon variable (X) in /-- If `X` represents a presheaf of monoids, then `X` is a monoid object. -/ -@[to_additive (attr := simps, implicit_reducible) +@[to_additive (attr := simps, instance_reducible) /-- If `X` represents a presheaf of additive monoids, then `X` is an additive monoid object. -/] def MonObj.ofRepresentableBy (F : Cᵒᵖ ⥤ MonCat.{w}) (α : (F ⋙ forget _).RepresentableBy X) : MonObj X where @@ -360,6 +360,9 @@ def yonedaMon : Mon C ⥤ Cᵒᵖ ⥤ MonCat.{v} where map_id _ := NatTrans.ext <| funext fun _ ↦ MonCat.hom_ext <| IsMonHom.monoidHom_id map_comp _ _ := NatTrans.ext <| funext fun _ ↦ MonCat.hom_ext <| IsMonHom.monoidHom_comp _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_additive (attr := reassoc)] lemma yonedaMon_naturality (α : yonedaMonObj M ⟶ yonedaMonObj N) (f : X ⟶ Y) (g : Y ⟶ M) : α.app _ (f ≫ g) = f ≫ α.app _ g := congr($(α.naturality f.op) g) @@ -456,6 +459,9 @@ lemma MonObj.mul_eq_mul : μ = fst M M * snd _ _ := namespace Hom +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- If `M` and `N` are isomorphic as monoid objects, then `X ⟶ M` and `X ⟶ N` are isomorphic monoids. -/ @[to_additive (attr := simps!) diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean index aa334a5b7de085..1ce1ae1ce8b305 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean @@ -25,10 +25,11 @@ public noncomputable section namespace CategoryTheory.Over -open Functor Limits CartesianMonoidalCategory +open CategoryTheory.Functor Limits CartesianMonoidalCategory variable {C : Type*} [Category* C] [HasPullbacks C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A choice of finite products of `Over X` given by `Limits.pullback`. -/ abbrev cartesianMonoidalCategory (X : C) : CartesianMonoidalCategory (Over X) := @@ -40,6 +41,7 @@ abbrev cartesianMonoidalCategory (X : C) : CartesianMonoidalCategory (Over X) := attribute [local instance] cartesianMonoidalCategory +set_option backward.isDefEq.respectTransparency.types false in /-- `Over X` is braided w.r.t. the Cartesian monoidal structure given by `Limits.pullback`. -/ abbrev braidedCategory (X : C) : BraidedCategory (Over X) := .ofCartesianMonoidalCategory @@ -50,154 +52,188 @@ open MonoidalCategory variable {X : C} +set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma tensorObj_ext {R : C} {S T : Over X} (f₁ f₂ : R ⟶ (S ⊗ T).left) (e₁ : f₁ ≫ pullback.fst _ _ = f₂ ≫ pullback.fst _ _) (e₂ : f₁ ≫ pullback.snd _ _ = f₂ ≫ pullback.snd _ _) : f₁ = f₂ := pullback.hom_ext e₁ e₂ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorObj_left (R S : Over X) : (R ⊗ S).left = Limits.pullback R.hom S.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorObj_hom (R S : Over X) : (R ⊗ S).hom = pullback.fst R.hom S.hom ≫ R.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorUnit_left : (𝟙_ (Over X)).left = X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorUnit_hom : (𝟙_ (Over X)).hom = 𝟙 X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_left {R S T : Over X} (f : R ⟶ S) (g : R ⟶ T) : (lift f g).left = pullback.lift f.left g.left (f.w.trans g.w.symm) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma fst_left {R S : Over X} : (fst R S).left = pullback.fst _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma snd_left {R S : Over X} : (snd R S).left = pullback.snd _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toUnit_left {R : Over X} : (toUnit R).left = R.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_fst (R S T : Over X) : (α_ R S T).hom.left ≫ pullback.fst _ (pullback.fst _ _ ≫ _) = pullback.fst _ _ ≫ pullback.fst _ _ := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_snd_fst (R S T : Over X) : (α_ R S T).hom.left ≫ pullback.snd _ (pullback.fst _ _ ≫ _) ≫ pullback.fst _ _ = pullback.fst _ _ ≫ pullback.snd _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_snd_snd (R S T : Over X) : (α_ R S T).hom.left ≫ pullback.snd _ (pullback.fst _ _ ≫ _) ≫ pullback.snd _ _ = pullback.snd _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_fst_fst (R S T : Over X) : (α_ R S T).inv.left ≫ pullback.fst (pullback.fst _ _ ≫ _) _ ≫ pullback.fst _ _ = pullback.fst _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_fst_snd (R S T : Over X) : (α_ R S T).inv.left ≫ pullback.fst (pullback.fst _ _ ≫ _) _ ≫ pullback.snd _ _ = pullback.snd _ _ ≫ pullback.fst _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_snd (R S T : Over X) : (α_ R S T).inv.left ≫ pullback.snd (pullback.fst _ _ ≫ _) _ = pullback.snd _ _ ≫ pullback.snd _ _ := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma leftUnitor_hom_left (Y : Over X) : (λ_ Y).hom.left = pullback.snd _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma leftUnitor_inv_left_fst (Y : Over X) : (λ_ Y).inv.left ≫ pullback.fst (𝟙 X) _ = Y.hom := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma leftUnitor_inv_left_snd (Y : Over X) : (λ_ Y).inv.left ≫ pullback.snd (𝟙 X) _ = 𝟙 Y.left := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma rightUnitor_hom_left (Y : Over X) : (ρ_ Y).hom.left = pullback.fst _ (𝟙 X) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma rightUnitor_inv_left_fst (Y : Over X) : (ρ_ Y).inv.left ≫ pullback.fst _ (𝟙 X) = 𝟙 _ := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma rightUnitor_inv_left_snd (Y : Over X) : (ρ_ Y).inv.left ≫ pullback.snd _ (𝟙 X) = Y.hom := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma whiskerLeft_left {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left = pullback.map _ _ _ _ (𝟙 _) f.left (𝟙 _) (by simp) (by simp) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerLeft_left_fst {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left ≫ pullback.fst _ _ = pullback.fst _ _ := (limit.lift_π _ _).trans (Category.comp_id _) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerLeft_left_snd {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left ≫ pullback.snd _ _ = pullback.snd _ _ ≫ f.left := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma whiskerRight_left {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left = pullback.map _ _ _ _ f.left (𝟙 _) (𝟙 _) (by simp) (by simp) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerRight_left_fst {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left ≫ pullback.fst _ _ = pullback.fst _ _ ≫ f.left := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerRight_left_snd {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left ≫ pullback.snd _ _ = pullback.snd _ _ := (limit.lift_π _ _).trans (Category.comp_id _) +set_option backward.isDefEq.respectTransparency.types false in lemma tensorHom_left {R S T U : Over X} (f : R ⟶ S) (g : T ⟶ U) : (f ⊗ₘ g).left = pullback.map _ _ _ _ f.left g.left (𝟙 _) (by simp) (by simp) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma tensorHom_left_fst {S U : C} {R T : Over X} (fS : S ⟶ X) (fU : U ⟶ X) (f : R ⟶ mk fS) (g : T ⟶ mk fU) : (f ⊗ₘ g).left ≫ pullback.fst fS fU = pullback.fst R.hom T.hom ≫ f.left := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma tensorHom_left_snd {S U : C} {R T : Over X} (fS : S ⟶ X) (fU : U ⟶ X) (f : R ⟶ mk fS) (g : T ⟶ mk fU) : (f ⊗ₘ g).left ≫ pullback.snd fS fU = pullback.snd R.hom T.hom ≫ g.left := limit.lift_π _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma braiding_hom_left {R S : Over X} : (β_ R S).hom.left = (pullbackSymmetry _ _).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma braiding_inv_left {R S : Over X} : (β_ R S).inv.left = (pullbackSymmetry _ _).hom := rfl variable {A B R S Y Z : C} {f : R ⟶ X} {g : S ⟶ X} +set_option backward.isDefEq.respectTransparency.types false in instance : (Over.pullback f).Braided := .ofChosenFiniteProducts _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma η_pullback_left : (OplaxMonoidal.η (Over.pullback f)).left = (pullback.snd (𝟙 _) f) := rfl @@ -236,6 +272,7 @@ lemma μ_pullback_left_snd (R S : Over X) : ← Over.comp_left_assoc, Iso.hom_inv_id] simp [CartesianMonoidalCategory.prodComparison] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma μ_pullback_left_fst_fst' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : (LaxMonoidal.μ (Over.pullback f) (.mk g₁) (.mk g₂)).left ≫ @@ -243,6 +280,7 @@ lemma μ_pullback_left_fst_fst' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : pullback.fst _ _ ≫ pullback.fst _ _ := μ_pullback_left_fst_fst .. +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma μ_pullback_left_fst_snd' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : (LaxMonoidal.μ (Over.pullback f) (.mk g₁) (.mk g₂)).left ≫ @@ -250,6 +288,7 @@ lemma μ_pullback_left_fst_snd' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : pullback.snd _ _ ≫ pullback.fst _ _ := μ_pullback_left_fst_snd .. +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma μ_pullback_left_snd' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : (LaxMonoidal.μ (Over.pullback f) (.mk g₁) (.mk g₂)).left ≫ @@ -274,6 +313,7 @@ lemma prodComparisonIso_pullback_inv_left_fst_fst (f : X ⟶ Y) (A B : Over Y) : Over.hom_left_inv_left_assoc] simp [CartesianMonoidalCategory.prodComparison, fst] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prodComparisonIso_pullback_Spec_inv_left_fst_fst' (f : X ⟶ Y) (gA : A ⟶ Y) (gB : B ⟶ Y) : (prodComparisonIso (Over.pullback f) (.mk gA) (.mk gB)).inv.left ≫ @@ -301,6 +341,7 @@ lemma prodComparisonIso_pullback_inv_left_snd' (f : X ⟶ Y) (gA : A ⟶ Y) (gB Over.hom_left_inv_left_assoc] simp [CartesianMonoidalCategory.prodComparison] +set_option backward.isDefEq.respectTransparency.types false in /-- The pullback of a monoid object is a monoid object. -/ @[simps! -isSimp mul one] abbrev monObjMkPullbackSnd [MonObj (Over.mk f)] : MonObj (Over.mk <| pullback.snd f g) := @@ -308,10 +349,12 @@ abbrev monObjMkPullbackSnd [MonObj (Over.mk f)] : MonObj (Over.mk <| pullback.sn attribute [local instance] monObjMkPullbackSnd +set_option backward.isDefEq.respectTransparency.types false in instance isCommMonObj_mk_pullbackSnd [MonObj (Over.mk f)] [IsCommMonObj (Over.mk f)] : IsCommMonObj (Over.mk <| pullback.snd f g) := ((Over.pullback g).mapCommMon.obj <| .mk <| .mk f).comm +set_option backward.isDefEq.respectTransparency.types false in /-- The pullback of a monoid object is a monoid object. -/ @[simps! -isSimp mul one] abbrev grpObjMkPullbackSnd [GrpObj (Over.mk f)] : GrpObj (Over.mk (pullback.snd f g)) := diff --git a/Mathlib/CategoryTheory/Monoidal/Category.lean b/Mathlib/CategoryTheory/Monoidal/Category.lean index 5fc09229d4c2ae..d0e018d986daca 100644 --- a/Mathlib/CategoryTheory/Monoidal/Category.lean +++ b/Mathlib/CategoryTheory/Monoidal/Category.lean @@ -786,7 +786,7 @@ variable (C) attribute [local simp] whisker_exchange /-- The tensor product expressed as a functor. -/ -@[simps] +@[simps, implicit_reducible] def tensor : C × C ⥤ C where obj X := X.1 ⊗ X.2 map {X Y : C × C} (f : X ⟶ Y) := f.1 ⊗ₘ f.2 @@ -820,7 +820,7 @@ theorem rightAssocTensor_map {X Y} (f : X ⟶ Y) : rfl /-- The tensor product bifunctor `C ⥤ C ⥤ C` of a monoidal category. -/ -@[simps] +@[simps, implicit_reducible] def curriedTensor : C ⥤ C ⥤ C where obj X := { obj := fun Y => X ⊗ Y @@ -863,6 +863,7 @@ set_option backward.defeqAttrib.useBackward true in def rightUnitorNatIso : tensorUnitRight C ≅ 𝟭 C := NatIso.ofComponents MonoidalCategory.rightUnitor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The associator as a natural isomorphism between trifunctors `C ⥤ C ⥤ C ⥤ C`. -/ @[simps!] @@ -888,6 +889,7 @@ theorem tensorLeftTensor_hom_app (X Y Z : C) : (tensorLeftTensor X Y).hom.app Z = (associator X Y Z).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorLeftTensor_inv_app (X Y Z : C) : (tensorLeftTensor X Y).inv.app Z = (associator X Y Z).inv := by simp [tensorLeftTensor] @@ -933,6 +935,7 @@ theorem tensorRightTensor_hom_app (X Y Z : C) : (tensorRightTensor X Y).hom.app Z = (associator Z X Y).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorRightTensor_inv_app (X Y Z : C) : (tensorRightTensor X Y).inv.app Z = (associator Z X Y).hom := by simp [tensorRightTensor] @@ -945,7 +948,7 @@ section universe v₁ v₂ u₁ u₂ -open Prod +open CategoryTheory.Prod variable (C₁ : Type u₁) [Category.{v₁} C₁] [MonoidalCategory.{v₁} C₁] variable (C₂ : Type u₂) [Category.{v₂} C₂] [MonoidalCategory.{v₂} C₂] @@ -997,6 +1000,7 @@ section ObjectProperty open ObjectProperty +set_option backward.isDefEq.respectTransparency.types false in /-- The restriction of a monoidal category along an object property that's closed under the monoidal structure. -/ -- See note [reducible non-instances] diff --git a/Mathlib/CategoryTheory/Monoidal/Center.lean b/Mathlib/CategoryTheory/Monoidal/Center.lean index 664b5d5387ad06..82371dfe7ded2c 100644 --- a/Mathlib/CategoryTheory/Monoidal/Center.lean +++ b/Mathlib/CategoryTheory/Monoidal/Center.lean @@ -153,6 +153,9 @@ def tensorObj (X Y : Center C) : Center C := rw [HalfBraiding.naturality]; monoidal _ = _ := by rw [HalfBraiding.naturality]; monoidal }⟩ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem whiskerLeft_comm (X : Center C) {Y₁ Y₂ : Center C} (f : Y₁ ⟶ Y₂) (U : C) : @@ -217,16 +220,19 @@ section def tensorUnit : Center C := ⟨𝟙_ C, { β := fun U => λ_ U ≪≫ (ρ_ U).symm }⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for the `MonoidalCategory` instance on `Center C`. -/ def associator (X Y Z : Center C) : tensorObj (tensorObj X Y) Z ≅ tensorObj X (tensorObj Y Z) := isoMk ⟨(α_ X.1 Y.1 Z.1).hom, fun U => by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for the `MonoidalCategory` instance on `Center C`. -/ def leftUnitor (X : Center C) : tensorObj tensorUnit X ≅ X := isoMk ⟨(λ_ X.1).hom, fun U => by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for the `MonoidalCategory` instance on `Center C`. -/ def rightUnitor (X : Center C) : tensorObj X tensorUnit ≅ X := @@ -242,6 +248,7 @@ attribute [local simp] Center.associator Center.leftUnitor Center.rightUnitor attribute [local simp] Center.whiskerLeft Center.whiskerRight Center.tensorHom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : MonoidalCategory (Center C) where tensorObj X Y := tensorObj X Y @@ -254,10 +261,12 @@ instance : MonoidalCategory (Center C) where leftUnitor := leftUnitor rightUnitor := rightUnitor +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensor_fst (X Y : Center C) : (X ⊗ Y).1 = X.1 ⊗ Y.1 := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensor_β (X Y : Center C) (U : C) : (X ⊗ Y).2.β U = @@ -266,44 +275,54 @@ theorem tensor_β (X Y : Center C) (U : C) : (whiskerRightIso (X.2.β U) Y.1) ≪≫ α_ _ _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem whiskerLeft_f (X : Center C) {Y₁ Y₂ : Center C} (f : Y₁ ⟶ Y₂) : (X ◁ f).f = X.1 ◁ f.f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem whiskerRight_f {X₁ X₂ : Center C} (f : X₁ ⟶ X₂) (Y : Center C) : (f ▷ Y).f = f.f ▷ Y.1 := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensor_f {X₁ Y₁ X₂ Y₂ : Center C} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂) : (f ⊗ₘ g).f = f.f ⊗ₘ g.f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorUnit_β (U : C) : (𝟙_ (Center C)).2.β U = λ_ U ≪≫ (ρ_ U).symm := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem associator_hom_f (X Y Z : Center C) : Hom.f (α_ X Y Z).hom = (α_ X.1 Y.1 Z.1).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem associator_inv_f (X Y Z : Center C) : Hom.f (α_ X Y Z).inv = (α_ X.1 Y.1 Z.1).inv := by apply Iso.inv_ext' -- Porting note (https://github.com/leanprover-community/mathlib4/issues/11041): Originally `ext` rw [← associator_hom_f, ← comp_f, Iso.hom_inv_id]; rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem leftUnitor_hom_f (X : Center C) : Hom.f (λ_ X).hom = (λ_ X.1).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem leftUnitor_inv_f (X : Center C) : Hom.f (λ_ X).inv = (λ_ X.1).inv := by apply Iso.inv_ext' -- Porting note (https://github.com/leanprover-community/mathlib4/issues/11041): Originally `ext` rw [← leftUnitor_hom_f, ← comp_f, Iso.hom_inv_id]; rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem rightUnitor_hom_f (X : Center C) : Hom.f (ρ_ X).hom = (ρ_ X.1).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem rightUnitor_inv_f (X : Center C) : Hom.f (ρ_ X).inv = (ρ_ X.1).inv := by apply Iso.inv_ext' -- Porting note (https://github.com/leanprover-community/mathlib4/issues/11041): Originally `ext` @@ -327,12 +346,16 @@ instance : (forget C).Monoidal := { εIso := Iso.refl _ μIso := fun _ _ ↦ Iso.refl _ } +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_ε : ε (forget C) = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_η : η (forget C) = 𝟙 _ := rfl variable {C} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_μ (X Y : Center C) : μ (forget C) X Y = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma forget_δ (X Y : Center C) : δ (forget C) X Y = 𝟙 _ := rfl set_option backward.defeqAttrib.useBackward true in @@ -341,6 +364,7 @@ instance : (forget C).ReflectsIsomorphisms where end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for the `BraidedCategory` instance on `Center C`. -/ @[simps!] @@ -353,6 +377,7 @@ def braiding (X Y : Center C) : X ⊗ Y ≅ Y ⊗ X := ← HalfBraiding.naturality_assoc, HalfBraiding.monoidal] simp⟩ +set_option backward.isDefEq.respectTransparency.types false in instance braidedCategoryCenter : BraidedCategory (Center C) where braiding := braiding @@ -390,12 +415,16 @@ instance : (ofBraided C).Monoidal := { hom := { f := 𝟙 _ } inv := { f := 𝟙 _ } } } +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma ofBraided_ε_f : (ε (ofBraided C)).f = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma ofBraided_η_f : (η (ofBraided C)).f = 𝟙 _ := rfl variable {C} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma ofBraided_μ_f (X Y : C) : (μ (ofBraided C) X Y).f = 𝟙 _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma ofBraided_δ_f (X Y : C) : (δ (ofBraided C) X Y).f = 𝟙 _ := rfl end diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Basic.lean index d2923897430d0f..57dd533860e4be 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Basic.lean @@ -54,7 +54,7 @@ variable {C : Type u} [Category.{v} C] [MonoidalCategory.{v} C] This isn't an instance because it's not usually how we want to construct internal homs, we'll usually prove all objects are closed uniformly. -/ -@[implicit_reducible] +@[instance_reducible] def tensorClosed {X Y : C} (hX : Closed X) (hY : Closed Y) : Closed (X ⊗ Y) where rightAdj := Closed.rightAdj X ⋙ Closed.rightAdj Y adj := (hY.adj.comp hX.adj).ofNatIsoLeft (MonoidalCategory.tensorLeftTensor X Y).symm @@ -63,7 +63,7 @@ def tensorClosed {X Y : C} (hX : Closed X) (hY : Closed Y) : Closed (X ⊗ Y) wh This isn't an instance because most of the time we'll prove closedness for all objects at once, rather than just for this one. -/ -@[implicit_reducible] +@[instance_reducible] def unitClosed : Closed (𝟙_ C) where rightAdj := 𝟭 C adj := Adjunction.id.ofNatIsoLeft (MonoidalCategory.leftUnitorNatIso C).symm @@ -110,6 +110,9 @@ theorem ev_naturality {X Y : C} (f : X ⟶ Y) : A ◁ (ihom A).map f ≫ (ev A).app Y = (ev A).app X ≫ f := (ev A).naturality f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem coev_naturality {X Y : C} (f : X ⟶ Y) : f ≫ (coev A).app Y = (coev A).app X ≫ (ihom A).map (A ◁ f) := @@ -202,6 +205,7 @@ theorem uncurry_injective : Function.Injective (uncurry : (Y ⟶ A ⟶[C] X) → variable (A X) +set_option backward.isDefEq.respectTransparency.types false in theorem uncurry_id_eq_ev : uncurry (𝟙 (A ⟶[C] X)) = (ihom.ev A).app X := by simp [uncurry_eq] @@ -211,7 +215,6 @@ theorem curry_id_eq_coev : curry (𝟙 _) = (ihom.coev A).app X := by apply comp_id set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma whiskerLeft_curry_ihom_ev_app (g : A ⊗ Y ⟶ X) : A ◁ curry g ≫ (ihom.ev A).app X = g := by @@ -247,13 +250,11 @@ theorem id_tensor_pre_app_comp_ev (f : B ⟶ A) (X : C) : B ◁ (pre f).app X ≫ (ihom.ev B).app X = f ▷ (A ⟶[C] X) ≫ (ihom.ev A).app X := conjugateEquiv_counit _ _ ((tensoringLeft C).map f) X -set_option backward.isDefEq.respectTransparency false in @[simp] theorem uncurry_pre (f : B ⟶ A) (X : C) : MonoidalClosed.uncurry ((pre f).app X) = f ▷ _ ≫ (ihom.ev A).app X := by simp [uncurry_eq] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma curry_pre_app (f : B ⟶ A) {X Y : C} (g : A ⊗ Y ⟶ X) : curry g ≫ (pre f).app X = curry (f ▷ _ ≫ g) := uncurry_injective (by @@ -313,7 +314,7 @@ variable (F : C ⥤ D) {G : D ⥤ C} (adj : F ⊣ G) [F.Monoidal] [F.IsEquivalence] [MonoidalClosed D] /-- Transport the property of being monoidal closed across a monoidal equivalence of categories -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofEquiv : MonoidalClosed C where closed X := { rightAdj := F ⋙ ihom (F.obj X) ⋙ G @@ -321,6 +322,7 @@ noncomputable def ofEquiv : MonoidalClosed C where adj.toEquivalence.symm.toAdjunction)).ofNatIsoLeft (Iso.compInverseIso (H := adj.toEquivalence) (Functor.Monoidal.commTensorLeft F X)) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Suppose we have a monoidal equivalence `F : C ≌ D`, with `D` monoidal closed. We can pull the monoidal closed instance back along the equivalence. For `X, Y, Z : C`, this lemma describes the @@ -342,6 +344,7 @@ theorem ofEquiv_curry_def {X Y Z : C} (f : X ⊗ Y ⟶ Z) : rw [Adjunction.comp_homEquiv, Adjunction.comp_homEquiv] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Suppose we have a monoidal equivalence `F : C ≌ D`, with `D` monoidal closed. We can pull the monoidal closed instance back along the equivalence. For `X, Y, Z : C`, this lemma describes the @@ -496,7 +499,6 @@ lemma curry'_id (X : C) [Closed X] : curry' (𝟙 X) = id X := by rw [Category.comp_id] rfl -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma whiskerLeft_curry'_ihom_ev_app {X Y : C} [Closed X] (f : X ⟶ Y) : X ◁ curry' f ≫ (ihom.ev X).app Y = (ρ_ _).hom ≫ f := by diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean index b4a9f62541f33a..a0bf19ed3d3a5a 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Cartesian.lean @@ -134,7 +134,7 @@ variable [CartesianMonoidalCategory D] Note we didn't require any coherence between the choice of finite products here, since we transport along the `prodComparison` isomorphism. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def cartesianClosedOfEquiv (e : C ≌ D) [MonoidalClosed C] : MonoidalClosed D := letI : e.inverse.Monoidal := .ofChosenFiniteProducts _ MonoidalClosed.ofEquiv e.inverse e.symm.toAdjunction diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Functor.lean index c6366d48f9f306..3e13a002da89e8 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Functor.lean @@ -62,7 +62,6 @@ def frobeniusMorphism (h : L ⊣ F) (A : C) : TwoSquare (tensorLeft (F.obj A)) L prodComparisonNatTrans L (F.obj A) ≫ Functor.whiskerLeft _ ((curriedTensor C).map (h.counit.app _)) -set_option backward.isDefEq.respectTransparency false in /-- If `F` is full and faithful and has a left adjoint `L` which preserves binary products, then the Frobenius morphism is an isomorphism. -/ @@ -99,7 +98,6 @@ theorem coev_expComparison (A B : C) : apply IsIso.inv_eq_of_hom_inv_id -- Porting note (https://github.com/leanprover-community/mathlib4/issues/11041): was `ext` simp -set_option backward.isDefEq.respectTransparency false in theorem uncurry_expComparison (A B : C) : MonoidalClosed.uncurry ((expComparison F A).natTrans.app B) = inv (prodComparison F _ _) ≫ F.map ((ihom.ev _).app _) := by @@ -136,6 +134,7 @@ class MonoidalClosedFunctor : Prop where attribute [instance] MonoidalClosedFunctor.comparison_iso +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem frobeniusMorphism_mate (h : L ⊣ F) (A : C) : conjugateEquiv (h.comp (ihom.adjunction A)) ((ihom.adjunction (F.obj A)).comp h) diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Basic.lean index 239885c4c240b7..6f3c9a844bc5f9 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Basic.lean @@ -89,6 +89,7 @@ noncomputable def homEquiv : (F₁ ⊗ F₂ ⟶ F₃) ≃ (F₂ ⟶ functorEnric congr simp +set_option backward.isDefEq.respectTransparency.types false in lemma homEquiv_naturality_two_symm (f₂ : F₂ ⟶ F₂') (g : F₂' ⟶ functorEnrichedHom C F₁ F₃) : homEquiv.symm (f₂ ≫ g) = F₁ ◁ f₂ ≫ homEquiv.symm g := by dsimp [homEquiv] @@ -134,7 +135,7 @@ noncomputable def adj (F : J ⥤ C) : /-- When `C` is monoidal closed and has suitable limits, then for any `F : J ⥤ C`, `tensorLeft F` has a right adjoint. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def closed (F : J ⥤ C) : Closed F where rightAdj := (eHomFunctor _ _).obj ⟨F⟩ adj := adj F diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Complete.lean b/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Complete.lean index 31f5754c824cca..29d8214edef9f6 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Complete.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Complete.lean @@ -68,7 +68,7 @@ instance (F : I ⥤ C) : IsLeftAdjoint (tensorLeft (incl I ⋙ F)) := set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Auxiliary definition for `functorCategoryMonoidalClosed` -/ -@[implicit_reducible] +@[instance_reducible] def functorCategoryClosed (F : I ⥤ C) : Closed F := have := (ihom.adjunction (incl I ⋙ F)).isLeftAdjoint have := isLeftAdjoint_square_lift_comonadic (tensorLeft F) ((whiskeringLeft _ _ C).obj (incl I)) @@ -83,7 +83,7 @@ monoidal closed category. Note: this is defined completely abstractly, and does not have any good definitional properties. See the TODO in the module docstring. -/ -@[implicit_reducible] +@[instance_reducible] def functorCategoryMonoidalClosed : MonoidalClosed (I ⥤ C) where closed F := functorCategoryClosed I C F diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Groupoid.lean b/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Groupoid.lean index dfa65b5f408c4e..c213deb0339ed2 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Groupoid.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/FunctorCategory/Groupoid.lean @@ -30,6 +30,9 @@ namespace CategoryTheory.Functor variable {D : Type u} {C : Type*} [Groupoid.{v} D] [Category* C] [MonoidalCategory C] [MonoidalClosed C] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `CategoryTheory.Functor.closed`. The internal hom functor `F ⟶[C] -` -/ @[simps!] @@ -53,8 +56,8 @@ def closedUnit (F : D ⥤ C) : 𝟭 (D ⥤ C) ⟶ tensorLeft F ⋙ closedIhom F rw [coev_app_comp_pre_app_assoc, ← Functor.map_comp, tensorHom_def] simp } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `CategoryTheory.Functor.closed`. The counit for the adjunction `(tensorLeft F) ⊣ (ihom F)`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean index 70d9ed282599c7..b85d7de5f231fd 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Ideal.lean @@ -201,7 +201,7 @@ takes in an explicit choice of lift of the essential image of `i` to `D`, in the `l : i.EssImageSubcategory ⥤ D` and natural isomorphism `φ : l ⋙ i ≅ i.essImage.ι`. When `l ⋙ i` is defeq to `i.essImage.ι`, images of exponential objects in `D` under `i` will be defeq to the respective exponential objects in `C`. -/ -@[implicit_reducible] +@[instance_reducible] def cartesianClosedOfReflective' (l : i.EssImageSubcategory ⥤ D) (φ : l ⋙ i ≅ i.essImage.ι) : MonoidalClosed D where closed := fun B => @@ -228,7 +228,7 @@ Unlike `cartesianClosedOfReflective'` this construction lifts exponential object exponential objects in `D` by applying the reflector to them, even though they already lie in the essential image of `i`; if you need better control over definitional equality, use `cartesianClosedOfReflective'` instead. -/ -@[implicit_reducible] +@[instance_reducible] def cartesianClosedOfReflective : MonoidalClosed D := cartesianClosedOfReflective' i (i.essImage.ι ⋙ reflector i) (NatIso.ofComponents (fun X ↦ @@ -292,7 +292,6 @@ theorem bijection_symm_apply_id (A B : C) : apply (reflectorAdjunction i).unit.naturality set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem bijection_natural (A B : C) (X X' : D) (f : (reflector i).obj (A ⊗ B) ⟶ X) (g : X ⟶ X') : bijection i _ _ _ (f ≫ g) = bijection i _ _ _ f ≫ g := by dsimp [bijection] diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Types.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Types.lean index 4f67893fef4153..1e3a030a37164f 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Types.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Types.lean @@ -58,7 +58,7 @@ instance {C : Type v₁} [SmallCategory C] : MonoidalClosed (C ⥤ Type v₁) := attribute [local instance] uliftCategory in /-- This is not a good instance because of the universe levels. Below is the instance where the target category is `Type (max u₁ v₁)`. -/ -@[implicit_reducible] +@[instance_reducible] def cartesianClosedFunctorToTypes {C : Type u₁} [Category.{v₁} C] : MonoidalClosed (C ⥤ Type (max u₁ v₁ u₂)) := let e : (ULiftHom.{max u₁ v₁ u₂} (ULift.{max u₁ v₁ u₂} C)) ⥤ Type (max u₁ v₁ u₂) ≌ diff --git a/Mathlib/CategoryTheory/Monoidal/Closed/Zero.lean b/Mathlib/CategoryTheory/Monoidal/Closed/Zero.lean index 360ccf0f4c1fe6..0f18cb59aba382 100644 --- a/Mathlib/CategoryTheory/Monoidal/Closed/Zero.lean +++ b/Mathlib/CategoryTheory/Monoidal/Closed/Zero.lean @@ -40,7 +40,7 @@ open scoped CartesianClosed /-- If a Cartesian closed category has an initial object which is isomorphic to the terminal object, then each homset has exactly one element. -/ -@[implicit_reducible] +@[instance_reducible] def uniqueHomsetOfInitialIsoUnit [HasInitial C] (i : ⊥_ C ≅ 𝟙_ C) (X Y : C) : Unique (X ⟶ Y) := Equiv.unique <| calc diff --git a/Mathlib/CategoryTheory/Monoidal/CommComon_.lean b/Mathlib/CategoryTheory/Monoidal/CommComon_.lean index 7df8792ebb35ed..cdba05b9adbe48 100644 --- a/Mathlib/CategoryTheory/Monoidal/CommComon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/CommComon_.lean @@ -29,7 +29,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ u namespace CategoryTheory -open MonoidalCategory ComonObj Functor +open MonoidalCategory ComonObj variable {C : Type u₁} [Category.{v₁} C] [MonoidalCategory.{v₁} C] [BraidedCategory.{v₁} C] diff --git a/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean b/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean index eb242b0aee7340..11e0f8c921a1ad 100644 --- a/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean +++ b/Mathlib/CategoryTheory/Monoidal/CommGrp_.lean @@ -209,6 +209,7 @@ protected instance Faithful.mapCommGrp [F.Faithful] : F.mapCommGrp.Faithful wher map_injective hfg := (CommGrp.forget _ ⋙ F).map_injective ((CommGrp.forget _).congr_map hfg) +set_option backward.isDefEq.respectTransparency.types false in /-- If `F : C ⥤ D` is a fully faithful monoidal functor, then `CommGrpCat(F) : CommGrpCat C ⥤ CommGrpCat D` is fully faithful too. -/ @[simps] @@ -251,6 +252,7 @@ set_option backward.isDefEq.respectTransparency false in def mapCommGrpCompIso : (F ⋙ G).mapCommGrp ≅ F.mapCommGrp ⋙ G.mapCommGrp := NatIso.ofComponents fun X ↦ CommGrp.mkIso (.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Natural transformations between functors lift to commutative group objects. -/ @[simps!] @@ -272,11 +274,12 @@ noncomputable def mapCommGrpFunctor : (C ⥤ₗ D) ⥤ CommGrp C ⥤ CommGrp D w end Functor -open Functor +open CategoryTheory.Functor namespace Adjunction variable {F : C ⥤ D} {G : D ⥤ C} (a : F ⊣ G) [F.Braided] [G.Braided] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An adjunction of braided functors lifts to an adjunction of their lifts to commutative group objects. -/ diff --git a/Mathlib/CategoryTheory/Monoidal/CommMon_.lean b/Mathlib/CategoryTheory/Monoidal/CommMon_.lean index 4ae398fd5d8307..bd4df3d1f6e239 100644 --- a/Mathlib/CategoryTheory/Monoidal/CommMon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/CommMon_.lean @@ -242,6 +242,7 @@ end LaxBraided section Braided variable [F.Braided] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ D` is a fully faithful monoidal functor, then `CommMonCat(F) : CommMonCat C ⥤ CommMonCat D` is fully faithful too. -/ @@ -256,7 +257,7 @@ end Braided end Functor -open Functor +open CategoryTheory.Functor namespace Adjunction variable {F : C ⥤ D} {G : D ⥤ C} (a : F ⊣ G) [F.Braided] [G.LaxBraided] [a.IsMonoidal] @@ -365,6 +366,7 @@ end EquivLaxBraidedFunctorPUnit open EquivLaxBraidedFunctorPUnit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Commutative monoid objects in `C` are "just" braided lax monoidal functors from the trivial braided monoidal category to `C`. diff --git a/Mathlib/CategoryTheory/Monoidal/Comon_.lean b/Mathlib/CategoryTheory/Monoidal/Comon_.lean index 84b8ef3122b5b9..6a88e04c79a9a1 100644 --- a/Mathlib/CategoryTheory/Monoidal/Comon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Comon_.lean @@ -325,6 +325,9 @@ def Comon_EquivMon_OpOp : Comon C ≌ (Mon Cᵒᵖ)ᵒᵖ where the simpNF linter complains about `monoidal_tensorObj_comon_counit` being `@[simp]`. So we spell out all the other ones. -/ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Comonoid objects in a braided category form a monoidal category. diff --git a/Mathlib/CategoryTheory/Monoidal/Conv.lean b/Mathlib/CategoryTheory/Monoidal/Conv.lean index 4a3662c33bd208..0de8ea26455f6d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Conv.lean +++ b/Mathlib/CategoryTheory/Monoidal/Conv.lean @@ -40,6 +40,7 @@ instance : Mul (Conv M N) where theorem mul_eq (f g : Conv M N) : f * g = Δ[M] ≫ f ▷ M ≫ N ◁ g ≫ μ[N] := rfl +set_option backward.isDefEq.respectTransparency.types false in instance : Monoid (Conv M N) where one_mul f := by simp [one_eq, mul_eq, ← whisker_exchange_assoc] mul_one f := by simp [one_eq, mul_eq, ← whisker_exchange_assoc] diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean index c5771c09092832..cfe5235d953222 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution.lean @@ -76,7 +76,7 @@ class DayConvolution (F G : C ⥤ V) where namespace DayConvolution -open scoped Prod +open scoped CategoryTheory.Prod section @@ -112,6 +112,9 @@ section unit variable {x x' y y' : C} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma unit_naturality (f : x ⟶ x') (g : y ⟶ y') : @@ -121,13 +124,16 @@ lemma unit_naturality (f : x ⟶ x') (g : y ⟶ y') : set_option backward.defeqAttrib.useBackward true in variable (y) in -set_option backward.isDefEq.respectTransparency false in -- Needed in DayConvolution.lean +set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma whiskerRight_comp_unit_app (f : x ⟶ x') : F.map f ▷ G.obj y ≫ (unit F G).app (x', y) = (unit F G).app (x, y) ≫ (F ⊛ G).map (f ▷ y) := by simpa [tensorHom_def] using (unit F G).naturality (f ×ₘ 𝟙 _) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (x) in @[reassoc (attr := simp)] @@ -176,6 +182,7 @@ def corepresentableBy : homEquiv := Functor.homEquivOfIsLeftKanExtension _ (unit F G) _ homEquiv_comp := by aesop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Use the fact that `(F ⊛ G).obj c` is a colimit to characterize morphisms out of it at a point. -/ @@ -187,7 +194,7 @@ theorem convolution_hom_ext_at (c : C) {v : V} {f g : (F ⊛ G).obj c ⟶ v} section associator -open Functor +open CategoryTheory.Functor variable (H : C ⥤ V) [DayConvolution G H] [DayConvolution F (G ⊛ H)] [DayConvolution (F ⊛ G) H] [∀ (v : V) (d : C), Limits.PreservesColimitsOfShape @@ -237,6 +244,9 @@ def corepresentableBy₂' : Functor.homEquivOfIsLeftKanExtension _ (extensionUnitLeft (F ⊛ G) (unit F G) H) _ homEquiv_comp := by aesop +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism of functors between `((F ⊠ G) ⊠ H ⟶ (tensor C).prod (𝟭 C) ⋙ tensor C ⋙ -)` and @@ -358,6 +368,7 @@ variable [∀ (v : V) (d : C × C), Limits.PreservesColimitsOfShape (CostructuredArrow ((tensor C).prod (𝟭 C)) d) (tensorRight v)] set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in lemma pentagon (H K : C ⥤ V) [DayConvolution G H] [DayConvolution (F ⊛ G) H] [DayConvolution F (G ⊛ H)] [DayConvolution H K] [DayConvolution G (H ⊛ K)] [DayConvolution (G ⊛ H) K] @@ -434,7 +445,7 @@ namespace DayConvolutionUnit variable (U : C ⥤ V) [DayConvolutionUnit U] open scoped DayConvolution -open ExternalProduct Functor +open ExternalProduct CategoryTheory.Functor /-- A shorthand for the natural transformation of functors out of PUnit defined by the canonical morphism `𝟙_ V ⟶ U.obj (𝟙_ C)` when `U` is a unit for Day convolution. -/ @@ -490,6 +501,9 @@ def corepresentableByRight [DayConvolution F U] : Functor.homEquivOfIsLeftKanExtension _ (extensionUnitRight U (φ U) F) _ homEquiv_comp := by aesop +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism of corepresentable functors that defines the left unitor for Day convolution. -/ @[simps! +dsimpLhs] @@ -518,6 +532,9 @@ def leftUnitorCorepresentingIso : isoWhiskerRight ((whiskeringLeft _ _ _).mapIso <| NatIso.ofComponents fun _ ↦ λ_ _) _ _ ≅ _ := coyoneda.mapIso <| Iso.op <| NatIso.ofComponents fun _ ↦ (λ_ _).symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism of corepresentable functors that defines the right unitor for Day convolution. -/ @[simps! +dsimpLhs] @@ -917,7 +934,7 @@ open DayConvolution DayConvolutionUnit in /-- We can promote a `LawfulDayConvolutionMonoidalCategoryStruct` to a monoidal category, note that every non-prop data is already here, so this is just about showing that they satisfy the axioms of a monoidal category. -/ -@[implicit_reducible] +@[instance_reducible] def monoidalOfLawfulDayConvolutionMonoidalCategoryStruct (D : Type u₃) [Category.{v₃} D] [MonoidalCategoryStruct D] @@ -1206,7 +1223,7 @@ lemma ι_map_tensorHom_eq {d₁ d₁' d₂ d₂' : D} (f : d₁ ⟶ d₂) (f' : set_option backward.isDefEq.respectTransparency false in /-- The monoidal category struct constructed in `DayConvolution.mkMonoidalCategoryStruct` extends to a `LawfulDayConvolutionMonoidalCategoryStruct`. -/ -@[implicit_reducible] +@[instance_reducible] def mkLawfulDayConvolutionMonoidalCategoryStruct : letI : MonoidalCategoryStruct D := mkMonoidalCategoryStruct C V D LawfulDayConvolutionMonoidalCategoryStruct C V D := @@ -1253,7 +1270,7 @@ variable {C V} in `ι.obj d` and `ι.obj d'` such that the convolution remains in the essential image of `ι`, construct an `InducedLawfulDayConvolutionMonoidalCategoryStructCore` by letting all other data be the generic ones from the `HasPointwiseLeftKanExtension` API. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofHasDayConvolutions {D : Type u₃} [Category.{v₃} D] (ι : D ⥤ C ⥤ V) @@ -1332,7 +1349,7 @@ variable {C V} of relevant colimits by the tensor product of `V`, we can define a `MonoidalCategory D` from the data of a fully faithful functor `ι : D ⥤ C ⥤ V` whose essential image contains a Day convolution unit and is stable under binary Day convolutions. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def monoidalOfHasDayConvolutions : MonoidalCategory D := letI induced : InducedLawfulDayConvolutionMonoidalCategoryStructCore C V D := .ofHasDayConvolutions ι ffι essImageDayConvolution essImageDayConvolutionUnit @@ -1344,7 +1361,7 @@ noncomputable def monoidalOfHasDayConvolutions : MonoidalCategory D := open InducedLawfulDayConvolutionMonoidalCategoryStructCore in /-- The monoidal category constructed via `monoidalOfHasDayConvolutions` has a canonical `LawfulDayConvolutionMonoidalCategoryStruct C V D`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def lawfulDayConvolutionMonoidalCategoryStructOfHasDayConvolutions : letI := monoidalOfHasDayConvolutions ι ffι essImageDayConvolution essImageDayConvolutionUnit diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution/Closed.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution/Closed.lean index dfffa0613168fb..4a3ec0de41702a 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution/Closed.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution/Closed.lean @@ -148,7 +148,6 @@ section ev variable [DayConvolution F H] (ℌ : DayConvolutionInternalHom F G H) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given `ℌ : DayConvolutionInternalHom F H`, if we think of `H.obj G` as the internal hom `[F, G]`, then this is the transformation corresponding to the component at `G` of the "evaluation" natural morphism diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean index d921d186640088..6393251ae27328 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean @@ -177,6 +177,7 @@ def isoPointwiseLeftKanExtension (F G : C ⊛⥤ V) : (F ⊗ G).functor (η F G) _ ((tensor C).pointwiseLeftKanExtensionUnit (F.functor ⊠ G.functor)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma η_comp_isoPointwiseLeftKanExtension_hom (F G : C ⊛⥤ V) (x y : C) : (η F G).app (x, y) ≫ (isoPointwiseLeftKanExtension F G).hom.app (x ⊗ y) = diff --git a/Mathlib/CategoryTheory/Monoidal/End.lean b/Mathlib/CategoryTheory/Monoidal/End.lean index 463706a399c184..bc7583cdb9501f 100644 --- a/Mathlib/CategoryTheory/Monoidal/End.lean +++ b/Mathlib/CategoryTheory/Monoidal/End.lean @@ -102,6 +102,7 @@ namespace MonoidalCategory variable [MonoidalCategory C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Tensoring on the right gives a monoidal functor from `C` into endofunctors of `C`. -/ @@ -111,15 +112,19 @@ instance : (tensoringRight C).Monoidal := μIso := fun X Y => (Functor.isoWhiskerRight (curriedAssociatorNatIso C) ((evaluation C (C ⥤ C)).obj X ⋙ (evaluation C C).obj Y)) } +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensoringRight_ε : ε (tensoringRight C) = (rightUnitorNatIso C).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensoringRight_η : η (tensoringRight C) = (rightUnitorNatIso C).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensoringRight_μ (X Y : C) (Z : C) : (μ (tensoringRight C) X Y).app Z = (α_ Z X Y).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensoringRight_δ (X Y : C) (Z : C) : (δ (tensoringRight C) X Y).app Z = (α_ Z X Y).inv := rfl @@ -161,7 +166,6 @@ theorem μ_naturality {m n : M} {X Y : C} (f : X ⟶ Y) [F.LaxMonoidal] : (F.obj n).map ((F.obj m).map f) ≫ (μ F m n).app Y = (μ F m n).app X ≫ (F.obj _).map f := (μ F m n).naturality f -set_option backward.isDefEq.respectTransparency false in -- This is a simp lemma in the reverse direction via `NatTrans.naturality`. @[reassoc] theorem δ_naturality {m n : M} {X Y : C} (f : X ⟶ Y) [F.OplaxMonoidal] : @@ -208,7 +212,6 @@ theorem left_unitality_app (n : M) (X : C) [F.LaxMonoidal] : (F.obj n).map ((ε F).app X) ≫ (μ F (𝟙_ M) n).app X ≫ (F.map (λ_ n).hom).app X = 𝟙 _ := congr_app (left_unitality F n).symm X -set_option backward.isDefEq.respectTransparency false in @[simp, reassoc] theorem obj_ε_app (n : M) (X : C) [F.Monoidal] : (F.obj n).map ((ε F).app X) = (F.map (λ_ n).inv).app X ≫ (δ F (𝟙_ M) n).app X := by @@ -217,7 +220,6 @@ theorem obj_ε_app (n : M) (X : C) [F.Monoidal] : simp only [Category.id_comp, Category.assoc, μ_δ_app, endofunctorMonoidalCategory_tensorObj_obj, Category.comp_id] -set_option backward.isDefEq.respectTransparency false in @[simp, reassoc] theorem obj_η_app (n : M) (X : C) [F.Monoidal] : (F.obj n).map ((η F).app X) = (μ F (𝟙_ M) n).app X ≫ (F.map (λ_ n).hom).app X := by @@ -229,7 +231,6 @@ theorem right_unitality_app (n : M) (X : C) [F.Monoidal] : (ε F).app ((F.obj n).obj X) ≫ (μ F n (𝟙_ M)).app X ≫ (F.map (ρ_ n).hom).app X = 𝟙 _ := congr_app (Functor.LaxMonoidal.right_unitality F n).symm X -set_option backward.isDefEq.respectTransparency false in @[simp] theorem ε_app_obj (n : M) (X : C) [F.Monoidal] : (ε F).app ((F.obj n).obj X) = (F.map (ρ_ n).inv).app X ≫ (δ F n (𝟙_ M)).app X := by @@ -238,7 +239,6 @@ theorem ε_app_obj (n : M) (X : C) [F.Monoidal] : simp only [Category.id_comp, Category.assoc, μ_δ_app, endofunctorMonoidalCategory_tensorObj_obj, Category.comp_id] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem η_app_obj (n : M) (X : C) [F.Monoidal] : (η F).app ((F.obj n).obj X) = (μ F n (𝟙_ M)).app X ≫ (F.map (ρ_ n).hom).app X := by @@ -256,7 +256,6 @@ theorem associativity_app (m₁ m₂ m₃ : M) (X : C) [F.LaxMonoidal] : dsimp at this simpa using this -set_option backward.isDefEq.respectTransparency false in @[simp, reassoc] theorem obj_μ_app (m₁ m₂ m₃ : M) (X : C) [F.Monoidal] : (F.obj m₃).map ((μ F m₁ m₂).app X) = @@ -266,7 +265,6 @@ theorem obj_μ_app (m₁ m₂ m₃ : M) (X : C) [F.Monoidal] : rw [← associativity_app_assoc] simp -set_option backward.isDefEq.respectTransparency false in @[simp, reassoc] theorem obj_μ_inv_app (m₁ m₂ m₃ : M) (X : C) [F.Monoidal] : (F.obj m₃).map ((δ F m₁ m₂).app X) = @@ -278,7 +276,6 @@ theorem obj_μ_inv_app (m₁ m₂ m₃ : M) (X : C) [F.Monoidal] : simp only [Category.id_comp, Category.assoc, μ_δ_app_assoc, μ_δ_app, endofunctorMonoidalCategory_tensorObj_obj, Category.comp_id] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem obj_zero_map_μ_app {m : M} {X Y : C} (f : X ⟶ (F.obj m).obj Y) [F.Monoidal] : (F.obj (𝟙_ M)).map f ≫ (μ F m (𝟙_ M)).app _ = @@ -286,7 +283,6 @@ theorem obj_zero_map_μ_app {m : M} {X Y : C} (f : X ⟶ (F.obj m).obj Y) [F.Mon rw [← cancel_epi ((ε F).app _), ← cancel_mono ((δ F _ _).app _)] simp -set_option backward.isDefEq.respectTransparency false in @[simp] theorem obj_μ_zero_app (m₁ m₂ : M) (X : C) [F.Monoidal] : (μ F (𝟙_ M) m₂).app ((F.obj m₁).obj X) ≫ (μ F m₁ (𝟙_ M ⊗ m₂)).app X ≫ @@ -302,7 +298,6 @@ noncomputable def unitOfTensorIsoUnit (m n : M) (h : m ⊗ n ≅ 𝟙_ M) [F.Mon F.obj m ⋙ F.obj n ≅ 𝟭 C := μIso F m n ≪≫ F.mapIso h ≪≫ (εIso F).symm -set_option backward.isDefEq.respectTransparency false in /-- If `m ⊗ n ≅ 𝟙_M` and `n ⊗ m ≅ 𝟙_M` (subject to some commuting constraints), then `F.obj m` and `F.obj n` forms a self-equivalence of `C`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Monoidal/ExternalProduct/Basic.lean b/Mathlib/CategoryTheory/Monoidal/ExternalProduct/Basic.lean index 2acf8e046924da..957068fb0fa73c 100644 --- a/Mathlib/CategoryTheory/Monoidal/ExternalProduct/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/ExternalProduct/Basic.lean @@ -21,20 +21,20 @@ The notation `- ⊠ -` is scoped to `MonoidalCategory.ExternalProduct`. universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory.MonoidalCategory -open Functor +open CategoryTheory.Functor variable (J₁ : Type u₁) (J₂ : Type u₂) (C : Type u₃) [Category.{v₁} J₁] [Category.{v₂} J₂] [Category.{v₃} C] [MonoidalCategory C] /-- The (curried version of the) external product bifunctor: given diagrams `K₁ : J₁ ⥤ C` and `K₂ : J₂ ⥤ C`, this is the bifunctor `j₁ ↦ j₂ ↦ K₁ j₁ ⊗ K₂ j₂`. -/ -@[simps!] +@[simps!, implicit_reducible] def externalProductBifunctorCurried : (J₁ ⥤ C) ⥤ (J₂ ⥤ C) ⥤ J₁ ⥤ J₂ ⥤ C := (Functor.postcompose₂.obj <| (evaluation _ _).obj <| curriedTensor C).obj <| whiskeringLeft₂ C /-- The external product bifunctor: given diagrams `K₁ : J₁ ⥤ C` and `K₂ : J₂ ⥤ C`, this is the bifunctor `(j₁, j₂) ↦ K₁ j₁ ⊗ K₂ j₂`. -/ -@[simps!] +@[simps!, implicit_reducible] def externalProductBifunctor : ((J₁ ⥤ C) × (J₂ ⥤ C)) ⥤ J₁ × J₂ ⥤ C := uncurry.obj <| (Functor.postcompose₂.obj <| uncurry).obj <| externalProductBifunctorCurried J₁ J₂ C @@ -56,6 +56,7 @@ open scoped ExternalProduct variable (J₁ J₂ C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When both diagrams have the same source category, composing the external product with the diagonal gives the pointwise functor tensor product. @@ -69,6 +70,7 @@ def externalProductCompDiagIso : (fun _ ↦ NatIso.ofComponents (fun _ ↦ Iso.refl _) (by simp [tensorHom_def])) (fun _ ↦ by ext; simp [tensorHom_def]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When `C` is braided, there is an isomorphism `Prod.swap _ _ ⋙ F₁ ⊠ F₂ ≅ F₂ ⊠ F₁`, natural in both `F₁` and `F₂`. @@ -82,6 +84,7 @@ def externalProductSwap [BraidedCategory C] : (fun _ ↦ NatIso.ofComponents (fun _ ↦ β_ _ _) (by simp [whisker_exchange])) (fun _ ↦ by ext; simp [whisker_exchange]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A version of `externalProductSwap` phrased in terms of the curried functors. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean b/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean index 8e95ecf5431765..34ffbcdf106c97 100644 --- a/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean +++ b/Mathlib/CategoryTheory/Monoidal/ExternalProduct/KanExtension.lean @@ -28,7 +28,7 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory.MonoidalCategory.ExternalProduct noncomputable section -open scoped Prod +open scoped CategoryTheory.Prod variable {V : Type u₁} [Category.{v₁} V] [MonoidalCategory V] {D : Type u₂} {D' : Type u₃} {E : Type u₄} @@ -45,6 +45,7 @@ abbrev extensionUnitLeft : H ⊠ K ⟶ L.prod (𝟭 E) ⋙ H' ⊠ K := abbrev extensionUnitRight : K ⊠ H ⟶ (𝟭 E).prod L ⋙ K ⊠ H' := (externalProductBifunctor E D V).map (K.leftUnitor.inv ×ₘ α) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `H' : D' ⥤ V` is a pointwise left Kan extension along `L : D ⥤ D'` at `(d : D')` and if tensoring right with an object preserves colimits in `V`, @@ -92,6 +93,7 @@ def isPointwiseLeftKanExtensionExtensionUnitLeft Functor.LeftExtension.mk (H' ⊠ K) (extensionUnitLeft H' α K) |>.IsPointwiseLeftKanExtension := fun ⟨d, e⟩ ↦ isPointwiseLeftKanExtensionAtExtensionUnitLeft H' α K d (P d) e +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `H' : D' ⥤ V` is a pointwise left Kan extension along `L : D ⥤ D'` at `d : D'` and if tensoring left with an object preserves colimits in `V`, diff --git a/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean b/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean index 3d2e6fc3eec498..2dab1fd750dc0d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean +++ b/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean @@ -41,7 +41,7 @@ universe u namespace CategoryTheory -open MonoidalCategory Functor +open MonoidalCategory CategoryTheory.Functor namespace FreeMonoidalCategory @@ -225,6 +225,7 @@ theorem normalizeIsoApp_tensor (X Y : F C) (n : N C) : theorem normalizeIsoApp_unitor (n : N C) : normalizeIsoApp C (𝟙_ (F C)) n = ρ_ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `normalizeIso`. -/ @[simps!] def normalizeIsoAux (X : F C) : (tensorFunc C).obj X ≅ (normalize' C).obj X := @@ -255,6 +256,7 @@ theorem normalizeObj_congr (n : NormalMonoidalObject C) {X Y : F C} (f : X ⟶ Y simp [congr_fun ih₁ n, congr_fun ih₂ (normalizeObj Y n)] | _ => funext; rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem normalize_naturality (n : NormalMonoidalObject C) {X Y : F C} (f : X ⟶ Y) : inclusionObj n ◁ f ≫ (normalizeIsoApp' C Y n).hom = @@ -280,6 +282,7 @@ theorem normalize_naturality (n : NormalMonoidalObject C) {X Y : F C} (f : X ⟶ end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between `n ⊗ X` and `normalize X n` is natural (in both `X` and `n`, but naturality in `n` is trivial and was "proved" in `normalizeIsoAux`). This is the real heart @@ -291,6 +294,7 @@ def normalizeIso : tensorFunc C ≅ normalize' C := convert! normalize_naturality n f using 1 any_goals dsimp; rw [normalizeIsoApp_eq] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between an object and its normal form is natural. -/ def fullNormalizeIso : 𝟭 (F C) ≅ fullNormalize C ⋙ inclusion := diff --git a/Mathlib/CategoryTheory/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Functor.lean index 582806b4b8ef6b..5875946f44a1fa 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor.lean @@ -45,7 +45,7 @@ universe v₁ v₂ v₃ v₁' u₁ u₂ u₃ u₁' namespace CategoryTheory -open Category Functor MonoidalCategory +open Category CategoryTheory.Functor MonoidalCategory variable {C : Type u₁} [Category.{v₁} C] [MonoidalCategory.{v₁} C] {D : Type u₂} [Category.{v₂} D] [MonoidalCategory.{v₂} D] @@ -198,7 +198,7 @@ set_option backward.privateInPublic true in A constructor for lax monoidal functors whose axioms are described by `tensorHom` instead of `whiskerLeft` and `whiskerRight`. -/ -@[implicit_reducible] +@[instance_reducible] def ofTensorHom : F.LaxMonoidal where ε := ε μ := μ @@ -692,7 +692,7 @@ def mk' (εIso : 𝟙_ D ≅ F.obj (𝟙_ C)) variable (h : F.CoreMonoidal) /-- The lax monoidal functor structure induced by a `Functor.CoreMonoidal` structure. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def toLaxMonoidal : F.LaxMonoidal where ε := h.εIso.hom μ X Y := (h.μIso X Y).hom @@ -700,7 +700,7 @@ def toLaxMonoidal : F.LaxMonoidal where right_unitality := h.right_unitality /-- The oplax monoidal functor structure induced by a `Functor.CoreMonoidal` structure. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def toOplaxMonoidal : F.OplaxMonoidal where η := h.εIso.inv δ X Y := (h.μIso X Y).inv @@ -723,7 +723,7 @@ def toOplaxMonoidal : F.OplaxMonoidal where attribute [local simp] toLaxMonoidal_ε toLaxMonoidal_μ toOplaxMonoidal_η toOplaxMonoidal_δ in /-- The monoidal functor structure induced by a `Functor.CoreMonoidal` structure. -/ -@[simps! toLaxMonoidal toOplaxMonoidal, implicit_reducible] +@[simps! toLaxMonoidal toOplaxMonoidal, instance_reducible] def toMonoidal : F.Monoidal where toLaxMonoidal := h.toLaxMonoidal toOplaxMonoidal := h.toOplaxMonoidal @@ -753,21 +753,21 @@ end CoreMonoidal /-- The `Functor.Monoidal` structure given by a lax monoidal functor such that `ε` and `μ` are isomorphisms. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Monoidal.ofLaxMonoidal [F.LaxMonoidal] [IsIso (ε F)] [∀ X Y, IsIso (μ F X Y)] := (CoreMonoidal.ofLaxMonoidal F).toMonoidal /-- The `Functor.Monoidal` structure given by an oplax monoidal functor such that `η` and `δ` are isomorphisms. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Monoidal.ofOplaxMonoidal [F.OplaxMonoidal] [IsIso (η F)] [∀ X Y, IsIso (δ F X Y)] := (CoreMonoidal.ofOplaxMonoidal F).toMonoidal section Prod -open scoped Prod +open scoped CategoryTheory.Prod variable (F : C ⥤ D) (G : E ⥤ C') [MonoidalCategory C'] @@ -789,7 +789,6 @@ end section -open scoped Prod variable [F.OplaxMonoidal] [G.OplaxMonoidal] @@ -836,21 +835,25 @@ variable [F.LaxMonoidal] [G.LaxMonoidal] instance LaxMonoidal.prod' : (prod' F G).LaxMonoidal := inferInstanceAs (diag C ⋙ prod F G).LaxMonoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_ε_fst : (ε (prod' F G)).1 = ε F := by change _ ≫ F.map (𝟙 _) = _ rw [Functor.map_id, Category.comp_id] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_ε_snd : (ε (prod' F G)).2 = ε G := by change _ ≫ G.map (𝟙 _) = _ rw [Functor.map_id, Category.comp_id] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_μ_fst (X Y : C) : (μ (prod' F G) X Y).1 = μ F X Y := by change _ ≫ F.map (𝟙 _) = _ rw [Functor.map_id, Category.comp_id] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_μ_snd (X Y : C) : (μ (prod' F G) X Y).2 = μ G X Y := by change _ ≫ G.map (𝟙 _) = _ rw [Functor.map_id, Category.comp_id] @@ -866,21 +869,25 @@ variable [F.OplaxMonoidal] [G.OplaxMonoidal] instance OplaxMonoidal.prod' : (prod' F G).OplaxMonoidal := inferInstanceAs (diag C ⋙ prod F G).OplaxMonoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_η_fst : (η (prod' F G)).1 = η F := by change F.map (𝟙 _) ≫ _ = _ rw [Functor.map_id, Category.id_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_η_snd : (η (prod' F G)).2 = η G := by change G.map (𝟙 _) ≫ _ = _ rw [Functor.map_id, Category.id_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_δ_fst (X Y : C) : (δ (prod' F G) X Y).1 = δ F X Y := by change F.map (𝟙 _) ≫ _ = _ rw [Functor.map_id, Category.id_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prod'_δ_snd (X Y : C) : (δ (prod' F G) X Y).2 = δ G X Y := by change G.map (𝟙 _) ≫ _ = _ rw [Functor.map_id, Category.id_comp] @@ -935,9 +942,8 @@ section LaxMonoidal variable [F.OplaxMonoidal] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The right adjoint of an oplax monoidal functor is lax monoidal. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def rightAdjointLaxMonoidal : G.LaxMonoidal where ε := adj.homEquiv _ _ (η F) μ X Y := adj.homEquiv _ _ (δ F _ _ ≫ (adj.counit.app X ⊗ₘ adj.counit.app Y)) @@ -1053,9 +1059,8 @@ section OplaxMonoidal variable [G.LaxMonoidal] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The left adjoint of a lax monoidal functor is oplax monoidal. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def leftAdjointOplaxMonoidal : F.OplaxMonoidal where η := (adj.homEquiv _ _).symm (ε G) δ X Y := (adj.homEquiv _ _).symm ((adj.unit.app X ⊗ₘ adj.unit.app Y) ≫ μ G _ _) @@ -1153,9 +1158,8 @@ variable (e : C ≌ D) instance [e.inverse.Monoidal] : e.symm.functor.Monoidal := inferInstanceAs (e.inverse.Monoidal) instance [e.functor.Monoidal] : e.symm.inverse.Monoidal := inferInstanceAs (e.functor.Monoidal) -set_option backward.isDefEq.respectTransparency false in /-- If a monoidal functor `F` is an equivalence of categories then its inverse is also monoidal. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def inverseMonoidal [e.functor.Monoidal] : e.inverse.Monoidal := by letI := e.toAdjunction.rightAdjointLaxMonoidal have : IsIso (LaxMonoidal.ε e.inverse) := by @@ -1199,7 +1203,6 @@ lemma functor_map_μ_inverse_comp_counitIso_hom_app_tensor (X Y : D) : δ e.functor _ _ ≫ (e.counitIso.hom.app X ⊗ₘ e.counitIso.hom.app Y) := e.toAdjunction.map_μ_comp_counit_app_tensor X Y -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma counitIso_inv_app_comp_functor_map_η_inverse : e.counitIso.inv.app (𝟙_ D) ≫ e.functor.map (η e.inverse) = ε e.functor := by @@ -1207,7 +1210,6 @@ lemma counitIso_inv_app_comp_functor_map_η_inverse : Category.assoc, Iso.hom_inv_id_app_assoc, Monoidal.map_ε_η] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma counitIso_inv_app_tensor_comp_functor_map_δ_inverse (X Y : C) : e.counitIso.inv.app (e.functor.obj X ⊗ e.functor.obj Y) ≫ @@ -1240,7 +1242,6 @@ lemma functor_map_μ_inverse_comp_counit_app_tensor (X Y : D) : δ e.functor _ _ ≫ (e.counit.app X ⊗ₘ e.counit.app Y) := e.toAdjunction.map_μ_comp_counit_app_tensor X Y -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma counitInv_app_comp_functor_map_η_inverse : e.counitInv.app (𝟙_ D) ≫ e.functor.map (η e.inverse) = ε e.functor := by @@ -1371,7 +1372,7 @@ def coreMonoidalTransport {F G : C ⥤ D} [F.Monoidal] (i : F ≅ G) : G.CoreMon /-- Transport the structure of a monoidal functor along a natural isomorphism of functors. -/ -@[implicit_reducible] +@[instance_reducible] def transport {F G : C ⥤ D} [F.Monoidal] (i : F ≅ G) : G.Monoidal := (coreMonoidalTransport i).toMonoidal @@ -1406,7 +1407,7 @@ variable {C D} Given a functor `F` and an equivalence of categories `e` such that `e.inverse` and `e.functor ⋙ F` are monoidal functors, `F` is monoidal as well. -/ -@[implicit_reducible] +@[instance_reducible] def monoidalOfPrecompFunctor (e : C ≌ D) (F : D ⥤ E) {F' : C ⥤ E} (i : e.functor ⋙ F ≅ F') [e.inverse.Monoidal] [F'.Monoidal] : F.Monoidal := letI : (e.functor ⋙ F).Monoidal := .transport i.symm @@ -1416,7 +1417,7 @@ def monoidalOfPrecompFunctor (e : C ≌ D) (F : D ⥤ E) {F' : C ⥤ E} (i : e.f Given a functor `F` and an equivalence of categories `e` such that `e.functor` and `e.inverse ⋙ F` are monoidal functors, `F` is monoidal as well. -/ -@[implicit_reducible] +@[instance_reducible] def monoidalOfPrecompInverse (e : C ≌ D) (F : C ⥤ E) {F' : D ⥤ E} (i : e.inverse ⋙ F ≅ F') [e.functor.Monoidal] [F'.Monoidal] : F.Monoidal := e.symm.monoidalOfPrecompFunctor F i @@ -1425,7 +1426,7 @@ def monoidalOfPrecompInverse (e : C ≌ D) (F : C ⥤ E) {F' : D ⥤ E} (i : e.i Given a functor `F` and an equivalence of categories `e` such that `e.functor` and `F ⋙ e.inverse` are monoidal functors, `F` is monoidal as well. -/ -@[implicit_reducible] +@[instance_reducible] def monoidalOfPostcompInverse (e : C ≌ D) (F : E ⥤ D) {F' : E ⥤ C} (i : F ⋙ e.inverse ≅ F') [e.functor.Monoidal] [F'.Monoidal] : F.Monoidal := .transport (Functor.isoWhiskerRight i.symm e.functor ≪≫ Functor.associator _ _ _ ≪≫ @@ -1435,7 +1436,7 @@ def monoidalOfPostcompInverse (e : C ≌ D) (F : E ⥤ D) {F' : E ⥤ C} (i : F Given a functor `F` and an equivalence of categories `e` such that `e.inverse` and `F ⋙ e.functor` are monoidal functors, `F` is monoidal as well. -/ -@[implicit_reducible] +@[instance_reducible] def monoidalOfPostcompFunctor (e : C ≌ D) (F : E ⥤ C) {F' : E ⥤ D} (i : F ⋙ e.functor ≅ F') [e.inverse.Monoidal] [F'.Monoidal] : F.Monoidal := e.symm.monoidalOfPostcompInverse _ i diff --git a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean index b08457cd1cb678..2ae6910a8af7a3 100644 --- a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean @@ -167,6 +167,7 @@ open CategoryTheory.BraidedCategory variable [BraidedCategory.{v₂} D] +set_option backward.isDefEq.respectTransparency.types false in /-- When `C` is any category, and `D` is a braided monoidal category, the natural pointwise monoidal structure on the functor category `C ⥤ D` is also braided. @@ -176,6 +177,7 @@ instance functorCategoryBraided : BraidedCategory (C ⥤ D) where hexagon_forward F G H := by ext X; apply hexagon_forward hexagon_reverse F G H := by ext X; apply hexagon_reverse +set_option backward.isDefEq.respectTransparency.types false in example : BraidedCategory (C ⥤ D) := CategoryTheory.Monoidal.functorCategoryBraided @@ -187,6 +189,7 @@ open CategoryTheory.SymmetricCategory variable [SymmetricCategory.{v₂} D] +set_option backward.isDefEq.respectTransparency.types false in /-- When `C` is any category, and `D` is a symmetric monoidal category, the natural pointwise monoidal structure on the functor category `C ⥤ D` is also symmetric. @@ -218,11 +221,13 @@ instance Functor.OplaxMonoidal.whiskeringRight oplax_left_unitality := by aesop oplax_right_unitality := by aesop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {C D E : Type*} [Category* C] [Category* D] [Category* E] [MonoidalCategory D] [MonoidalCategory E] (L : D ⥤ E) [L.Monoidal] : ((Functor.whiskeringRight C D E).obj L).Monoidal where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps!] instance Functor.Monoidal.whiskeringLeft diff --git a/Mathlib/CategoryTheory/Monoidal/Grp.lean b/Mathlib/CategoryTheory/Monoidal/Grp.lean index 3340a51f486750..49c32b81ddf394 100644 --- a/Mathlib/CategoryTheory/Monoidal/Grp.lean +++ b/Mathlib/CategoryTheory/Monoidal/Grp.lean @@ -345,7 +345,7 @@ lemma ext {X : C} (h₁ h₂ : GrpObj X) (H : h₁.toMonObj = h₂.toMonObj) : h -- Note: `Invertible` has no additive variant /-- A monoid object with invertible homs is a group object. -/ -@[implicit_reducible] +@[instance_reducible] def ofInvertible (G : C) [MonObj G] (h : ∀ X (f : X ⟶ G), Invertible f) : GrpObj G where inv := Yoneda.fullyFaithful.preimage ⟨fun X ↦ ↾fun f ↦ (h X.unop f).invOf, fun X Y f ↦ by @@ -530,6 +530,7 @@ instance instMonoidalCategory : MonoidalCategory (Grp C) where tensorHom_def := by intros; ext; simp [tensorHom_def] triangle _ _ := by ext; exact triangle _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[to_additive] instance instCartesianMonoidalCategory : CartesianMonoidalCategory (Grp C) where @@ -558,6 +559,7 @@ instance : (forget₂Mon C).Monoidal where «η» := 𝟙 _ δ G H := 𝟙 _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] MonObj.tensorObj.mul_def mul_eq_mul comp_mul in @[to_additive] @@ -617,6 +619,7 @@ protected instance Faithful.mapGrp [F.Faithful] : F.mapGrp.Faithful where (Grp.forget₂Mon _).map_injective (F.mapMon.map_injective ((Grp.forget₂Mon _).congr_map hfg)) +set_option backward.isDefEq.respectTransparency.types false in /-- If `F : C ⥤ D` is a fully faithful monoidal functor, then `F.mapGrp : Grp C ⥤ Grp D` is fully faithful too. -/ @[to_additive /-- If `F : C ⥤ D` is a fully faithful monoidal functor, then @@ -624,6 +627,7 @@ protected instance Faithful.mapGrp [F.Faithful] : F.mapGrp.Faithful where protected def FullyFaithful.mapGrp (hF : F.FullyFaithful) : F.mapGrp.FullyFaithful where preimage f := Grp.homMk' (hF.mapMon.preimage f.hom) +set_option backward.isDefEq.respectTransparency.types false in @[to_additive] protected instance Full.mapGrp [F.Full] [F.Faithful] : F.mapGrp.Full := ((FullyFaithful.ofFullyFaithful F).mapGrp).full @@ -662,6 +666,7 @@ set_option backward.isDefEq.respectTransparency false in def mapGrpCompIso : (F ⋙ G).mapGrp ≅ F.mapGrp ⋙ G.mapGrp := NatIso.ofComponents fun X ↦ Grp.mkIso (.refl _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Natural transformations between functors lift to group objects. -/ @[to_additive (attr := simps!) @@ -669,6 +674,7 @@ set_option backward.defeqAttrib.useBackward true in def mapGrpNatTrans (f : F ⟶ F') : F.mapGrp ⟶ F'.mapGrp where app X := Grp.homMk' ((mapMonNatTrans f).app X.toMon) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Natural isomorphisms between functors lift to group objects. -/ @[to_additive (attr := simps!) @@ -676,6 +682,7 @@ set_option backward.defeqAttrib.useBackward true in def mapGrpNatIso (e : F ≅ F') : F.mapGrp ≅ F'.mapGrp := NatIso.ofComponents fun X ↦ Grp.mkIso (e.app _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local instance] Monoidal.ofChosenFiniteProducts in /-- `mapGrp` is functorial in the left-exact functor. -/ @@ -744,11 +751,12 @@ noncomputable instance mapGrp.instBraided : F.mapGrp.Braided where end Braided end Functor -open Functor +open CategoryTheory.Functor namespace Adjunction variable {F : C ⥤ D} {G : D ⥤ C} (a : F ⊣ G) [F.Monoidal] [G.Monoidal] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An adjunction of monoidal functors lifts to an adjunction of their lifts to group objects. -/ @[to_additive (attr := simps) @@ -763,6 +771,7 @@ end Adjunction namespace Equivalence variable (e : C ≌ D) [e.functor.Monoidal] [e.inverse.Monoidal] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories lifts to an equivalence of their group objects. -/ @[to_additive (attr := simps) diff --git a/Mathlib/CategoryTheory/Monoidal/Hopf_.lean b/Mathlib/CategoryTheory/Monoidal/Hopf_.lean index 90d793bd1f497f..f0d268a1ff1cf1 100644 --- a/Mathlib/CategoryTheory/Monoidal/Hopf_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Hopf_.lean @@ -82,6 +82,7 @@ namespace HopfObj variable {C} +set_option backward.isDefEq.respectTransparency.types false in /-- Morphisms of Hopf monoids intertwine the antipodes. -/ theorem hom_antipode {A B : C} [HopfObj A] [HopfObj B] (f : A ⟶ B) [IsBimonHom f] : f ≫ 𝒮 = 𝒮 ≫ f := by @@ -255,6 +256,7 @@ theorem antipode_comul₂ (A : C) [HopfObj A] : rw [rightUnitor_inv_naturality_assoc, tensorHom_def] monoidal +set_option backward.isDefEq.respectTransparency.types false in theorem antipode_comul (A : C) [HopfObj A] : 𝒮[A] ≫ Δ[A] = Δ[A] ≫ (β_ _ _).hom ≫ (𝒮[A] ⊗ₘ 𝒮[A]) := by -- Again, it is a "left inverse equals right inverse" argument in the convolution monoid. @@ -418,6 +420,7 @@ theorem mul_antipode₂ (A : C) [HopfObj A] : rw [rightUnitor_naturality] monoidal +set_option backward.isDefEq.respectTransparency.types false in theorem mul_antipode (A : C) [HopfObj A] : μ[A] ≫ 𝒮[A] = (𝒮[A] ⊗ₘ 𝒮[A]) ≫ (β_ _ _).hom ≫ μ[A] := by -- Again, it is a "left inverse equals right inverse" argument in the convolution monoid. @@ -440,6 +443,7 @@ theorem mul_antipode (A : C) [HopfObj A] : simp only [Category.assoc, pentagon_hom_inv_inv_inv_inv_assoc] exact mul_antipode₂ A +set_option backward.isDefEq.respectTransparency.types false in /-- In a commutative Hopf algebra, the antipode squares to the identity. -/ diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean index dd8986022e18a3..d431bfb4973bd9 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean @@ -71,6 +71,7 @@ def functorObj (A : C ⥤ D) [MonObj A] : C ⥤ Mon D where map_id X := by ext; dsimp; rw [CategoryTheory.Functor.map_id] map_comp f g := by ext; dsimp; rw [Functor.map_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functor translating a monoid object in a functor category to a functor into the category of monoid objects. @@ -106,6 +107,7 @@ def inverse : (C ⥤ Mon D) ⥤ Mon (C ⥤ D) where { app := fun X => (α.app X).hom naturality := fun _ _ f => congr_arg Mon.Hom.hom (α.naturality f) } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit for the equivalence `Mon (C ⥤ D) ≌ C ⥤ Mon D`. -/ @@ -127,6 +129,7 @@ end MonFunctorCategoryEquivalence open MonFunctorCategoryEquivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- When `D` is a monoidal category, monoid objects in `C ⥤ D` are the same thing @@ -170,6 +173,7 @@ def functorObj (A : (C ⥤ D)) [ComonObj A] : C ⥤ Comon D where map_id X := by ext; dsimp; rw [CategoryTheory.Functor.map_id] map_comp f g := by ext; dsimp; rw [Functor.map_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option backward.privateInPublic true in /-- Functor translating a comonoid object in a functor category @@ -209,6 +213,7 @@ private def inverse : (C ⥤ Comon D) ⥤ Comon (C ⥤ D) where isComonHom_hom.hom_counit := by ext x; dsimp; rw [IsComonHom.hom_counit (α.app x).hom] isComonHom_hom.hom_comul := by ext x; dsimp; rw [IsComonHom.hom_comul (α.app x).hom] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option backward.privateInPublic true in /-- The unit for the equivalence `Comon (C ⥤ D) ≌ C ⥤ Comon D`. @@ -234,6 +239,7 @@ end ComonFunctorCategoryEquivalence open ComonFunctorCategoryEquivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in @@ -254,6 +260,7 @@ namespace CommMonFunctorCategoryEquivalence variable {C D} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functor translating a commutative monoid object in a functor category to a functor into the category of commutative monoid objects. @@ -281,12 +288,14 @@ def inverse : (C ⥤ CommMon D) ⥤ CommMon (C ⥤ D) where map α := CommMon.homMk ((monFunctorCategoryEquivalence C D).inverse.map (Functor.whiskerRight α _)) +set_option backward.isDefEq.respectTransparency.types false in /-- The unit for the equivalence `CommMon (C ⥤ D) ≌ C ⥤ CommMon D`. -/ @[simps!] def unitIso : 𝟭 (CommMon (C ⥤ D)) ≅ functor ⋙ inverse := NatIso.ofComponents (fun A => CommMon.mkIso (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in /-- The counit for the equivalence `CommMon (C ⥤ D) ≌ C ⥤ CommMon D`. -/ @[simps!] @@ -297,6 +306,7 @@ end CommMonFunctorCategoryEquivalence open CommMonFunctorCategoryEquivalence +set_option backward.isDefEq.respectTransparency.types false in /-- When `D` is a braided monoidal category, commutative monoid objects in `C ⥤ D` are the same thing as functors from `C` into the commutative monoid objects of `D`. diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/Limits.lean b/Mathlib/CategoryTheory/Monoidal/Internal/Limits.lean index 9dc3052ee9af33..e010c5e1544de0 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/Limits.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/Limits.lean @@ -70,6 +70,7 @@ def limitCone (F : J ⥤ Mon C) (c : Cone (F ⋙ Mon.forget C)) (hc : IsLimit c) π.app j := .mk' (c.π.app j) π.naturality j j' f := Hom.ext' (c.π.naturality f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The image of the proposed limit cone for `F : J ⥤ Mon C` under the forgetful functor `forget C : Mon C ⥤ C` is isomorphic to the limit cone of `F ⋙ forget C`. diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean b/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean index 99fff9f427fd49..07c5bb599e70ba 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean @@ -43,7 +43,7 @@ namespace MonModuleEquivalenceAlgebra /-- The ring structure on a monoid object. This instance is dangerous as it doesn't round trip from a ring to a monoid object and then back to a ring, since the `npow` field is lost in the middle. Therefore, it is scoped. -/ -@[implicit_reducible] +@[instance_reducible] def MonObj.toRing (A : ModuleCat.{u} R) [MonObj A] : Ring A := { (inferInstance : AddCommGroup A) with one := η[A] (1 : R) diff --git a/Mathlib/CategoryTheory/Monoidal/Limits/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Limits/Basic.lean index 65793bb2bff1a2..001b7dce9bec1c 100644 --- a/Mathlib/CategoryTheory/Monoidal/Limits/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Limits/Basic.lean @@ -92,6 +92,9 @@ instance : (lim (J := J) (C := C)).LaxMonoidal := erw [limit.lift_π] rw [whiskerLeft_id, Category.id_comp])) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma lim_ε_π (j : J) : ε (lim (J := J) (C := C)) ≫ limit.π _ j = 𝟙 _ := limit.lift_π _ _ diff --git a/Mathlib/CategoryTheory/Monoidal/Limits/Colimits.lean b/Mathlib/CategoryTheory/Monoidal/Limits/Colimits.lean index 3324ebe6a1f8f0..b742cc966611e7 100644 --- a/Mathlib/CategoryTheory/Monoidal/Limits/Colimits.lean +++ b/Mathlib/CategoryTheory/Monoidal/Limits/Colimits.lean @@ -67,6 +67,7 @@ def Cocone.tensor : Cocone (F₁ ⊗ F₂) where pt := c₁.pt ⊗ c₂.pt ι.app j := c₁.ι.app j ⊗ₘ c₂.ι.app j +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in attribute [local simp] tensorHom_def in /-- The tensor product of colimit cocones for functors `F₁ : J ⥤ C` diff --git a/Mathlib/CategoryTheory/Monoidal/Mod.lean b/Mathlib/CategoryTheory/Monoidal/Mod.lean index 730450bcc5b85f..ad5fd4500728f5 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mod.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mod.lean @@ -356,7 +356,7 @@ open MonoidalLeftAction in /-- When `M` is a `B`-module in `D` and `f : A ⟶ B` is a morphism of internal monoid objects, `M` inherits an `A`-module structure via "restriction of scalars", i.e `γ[A, M] = f ⊵ₗ M ≫ γ[B, M]`. -/ -@[to_additive (attr := simps!, implicit_reducible) +@[to_additive (attr := simps!, instance_reducible) /-- When `M` is a `B`-additive module in `D` and `f : A ⟶ B` is a morphism of internal additive monoid objects, `M` inherits an `A`-additive module structure via "restriction of scalars", i.e `δ[A, M] = f ⊵ₗ M ≫ δ[B, M]`. -/] diff --git a/Mathlib/CategoryTheory/Monoidal/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Mon.lean index 5974028edb9ff5..8042a141f58ab5 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon.lean @@ -107,7 +107,7 @@ attribute [to_additive existing (attr := reassoc (attr := simp))] one_mul mul_on /-- Transfer `MonObj` along an isomorphism. -/ -- Note: The simps lemmas are not tagged simp because their `#discr_tree_simp_key` are too generic. -@[to_additive (attr := simps! -isSimp, implicit_reducible) +@[to_additive (attr := simps! -isSimp, instance_reducible) /-- Transfer `AddMonObj` along an isomorphism. -/] def ofIso (e : M ≅ X) : MonObj X where one := η[M] ≫ e.hom @@ -909,6 +909,7 @@ set_option backward.defeqAttrib.useBackward true in def mapMonNatTrans (f : F ⟶ F') [NatTrans.IsMonoidal f] : F.mapMon ⟶ F'.mapMon where app X := .mk' (f.app _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Natural isomorphisms between functors lift to monoid objects. -/ @[to_additive (attr := simps!) @@ -1058,7 +1059,7 @@ def mapMonFunctor : LaxMonoidalFunctor C D ⥤ Mon C ⥤ Mon D where end Functor -open Functor +open CategoryTheory.Functor namespace Adjunction variable {F : C ⥤ D} {G : D ⥤ C} (a : F ⊣ G) [F.Monoidal] [G.LaxMonoidal] [a.IsMonoidal] @@ -1076,6 +1077,7 @@ end Adjunction namespace Equivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories lifts to an equivalence of their monoid objects. -/ @[to_additive (attr := simps) @@ -1147,6 +1149,9 @@ def unitIso : NatIso.ofComponents (fun F ↦ LaxMonoidalFunctor.isoOfComponents (fun _ ↦ F.mapIso (eqToIso (by ext)))) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `counitIso`. -/ @[to_additive (attr := simps!) /-- Auxiliary definition for `counitIso`. -/] def counitIsoAux (F : Mon C) : @@ -1185,6 +1190,7 @@ open EquivLaxMonoidalFunctorPUnit attribute [local simp] eqToIso_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Monoid objects in `C` are "just" lax monoidal functors from the trivial monoidal category to `C`. diff --git a/Mathlib/CategoryTheory/Monoidal/Multifunctor.lean b/Mathlib/CategoryTheory/Monoidal/Multifunctor.lean index 1b3f4711c10904..943f90481cec04 100644 --- a/Mathlib/CategoryTheory/Monoidal/Multifunctor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Multifunctor.lean @@ -29,7 +29,7 @@ variable {C : Type*} [Category* C] [MonoidalCategory C] namespace MonoidalCategory -open Functor +open CategoryTheory.Functor /-- The bifunctor `(F -) ⊗ -`. -/ abbrev curriedTensorInsertFunctor₁ (F : C ⥤ D) : C ⥤ D ⥤ D := @@ -71,6 +71,7 @@ abbrev curriedTensorPostPost (F : C ⥤ D) : C ⥤ C ⥤ C ⥤ D := abbrev curriedTensorPostPost' (F : C ⥤ D) : C ⥤ C ⥤ C ⥤ D := bifunctorComp₂₃ (curriedTensorPost F) (curriedTensor C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism of bifunctors `F - ⊗ F - ≅ F (- ⊗ -)`, given a monoidal functor `F`. -/ @[simps!] @@ -168,6 +169,9 @@ The bottom left map in the associativity hexagon. def firstMap₃ (F : C ⥤ D) : curriedTensorPostPost F ⟶ curriedTensorPostPost' F := (postcompose₃.obj _).map (curriedAssociatorNatIso _).hom +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of the left maps in the associativity hexagon. -/ @@ -199,6 +203,9 @@ def secondMap₃ {F : C ⥤ D} (μ : curriedTensorPre F ⟶ curriedTensorPost F) curriedTensorPrePost F ⟶ curriedTensorPostPost' F := (bifunctorComp₂₃Functor.map μ).app _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of the right maps in the associativity hexagon. -/ @@ -273,7 +280,7 @@ variable {F : C ⥤ D} `μ : F - ⊗ F - ⟶ F (- ⊗ -)` as a natural transformation between bifunctors, satisfying the relevant compatibilities. -/ -@[implicit_reducible] +@[instance_reducible] def ofBifunctor : F.LaxMonoidal where ε := ε μ X Y := (μ.app X).app Y @@ -355,6 +362,9 @@ The bottom left map in the oplax associativity hexagon. def firstMap₃ (F : C ⥤ D) : curriedTensorPrePre F ⟶ curriedTensorPrePre' F := ((((whiskeringLeft₃ D).obj F).obj F).obj F).map (curriedAssociatorNatIso D).hom +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of the three left maps in the oplax associativity hexagon. -/ @@ -386,6 +396,9 @@ def secondMap₃ {F : C ⥤ D} (δ : curriedTensorPost F ⟶ curriedTensorPre F) curriedTensorPrePost F ⟶ curriedTensorPrePre' F := (bifunctorComp₂₃Functor.obj (curriedTensorInsertFunctor₁ F)).map δ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of the three right maps in the oplax associativity hexagon. -/ @@ -460,7 +473,7 @@ variable {F : C ⥤ D} `δ : F (- ⊗ -) ⟶ F - ⊗ F -` as a natural transformation between bifunctors, satisfying the relevant compatibilities. -/ -@[implicit_reducible] +@[instance_reducible] def ofBifunctor : F.OplaxMonoidal where η := η δ X Y := (δ.app X).app Y @@ -507,7 +520,7 @@ variable {F : C ⥤ D} `μ / δ : F - ⊗ F - ↔ F (- ⊗ -)` as natural transformations between bifunctors, satisfying the relevant compatibilities. -/ -@[implicit_reducible] +@[instance_reducible] def ofBifunctor (ε_η : ε ≫ η = 𝟙 _) (η_ε : η ≫ ε = 𝟙 _) (μ_δ : μ ≫ δ = 𝟙 _) (δ_μ : δ ≫ μ = 𝟙 _) : F.Monoidal where toLaxMonoidal := .ofBifunctor ε μ associativity left_unitality right_unitality diff --git a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean index 9ac6d9c937c4a6..af13ecb1b3fd67 100644 --- a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean +++ b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean @@ -137,7 +137,6 @@ namespace IsMonoidal variable [F.Monoidal] [G.LaxMonoidal] [adj.IsMonoidal] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance : NatTrans.IsMonoidal adj.unit where unit := by dsimp @@ -148,7 +147,6 @@ instance : NatTrans.IsMonoidal adj.unit where dsimp rw [← unit_app_tensor_comp_map_δ_assoc, id_comp, Monoidal.map_δ_μ, comp_id] -set_option backward.isDefEq.respectTransparency false in instance : NatTrans.IsMonoidal adj.counit where unit := by dsimp diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index f0fec6b9d06d37..cd9918c98651db 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -132,7 +132,7 @@ open MonoidalCategory set_option backward.isDefEq.respectTransparency false in /-- The monoidal structure coming from finite coproducts is symmetric. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def symmetricOfHasFiniteCoproducts [HasInitial C] [HasBinaryCoproducts C] : SymmetricCategory C where braiding := Limits.coprod.braiding diff --git a/Mathlib/CategoryTheory/Monoidal/Opposite.lean b/Mathlib/CategoryTheory/Monoidal/Opposite.lean index 88d5cf98f15d49..ecab72a1736ade 100644 --- a/Mathlib/CategoryTheory/Monoidal/Opposite.lean +++ b/Mathlib/CategoryTheory/Monoidal/Opposite.lean @@ -157,7 +157,7 @@ end IsIso variable [MonoidalCategory.{v₁} C] -open Opposite MonoidalCategory Functor LaxMonoidal OplaxMonoidal +open Opposite MonoidalCategory CategoryTheory.Functor LaxMonoidal OplaxMonoidal set_option backward.defeqAttrib.useBackward true in instance monoidalCategoryOp : MonoidalCategory Cᵒᵖ where @@ -240,6 +240,7 @@ theorem op_tensor_op {W X Y Z : C} (f : W ⟶ X) (g : Y ⟶ Z) : f.op ⊗ₘ g.o theorem unop_tensor_unop {W X Y Z : Cᵒᵖ} (f : W ⟶ X) (g : Y ⟶ Z) : f.unop ⊗ₘ g.unop = (f ⊗ₘ g).unop := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where tensorObj X Y := mop (unmop Y ⊗ unmop X) @@ -261,58 +262,86 @@ instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where -- it would be nice if we could autogenerate all of these somehow section MonoidalOppositeLemmas +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_tensorObj (X Y : C) : mop (X ⊗ Y) = mop Y ⊗ mop X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_tensorObj (X Y : Cᴹᵒᵖ) : unmop (X ⊗ Y) = unmop Y ⊗ unmop X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_tensorUnit : mop (𝟙_ C) = 𝟙_ Cᴹᵒᵖ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_tensorUnit : unmop (𝟙_ Cᴹᵒᵖ) = 𝟙_ C := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_tensorHom {X₁ Y₁ X₂ Y₂ : C} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂) : (f ⊗ₘ g).mop = g.mop ⊗ₘ f.mop := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_tensorHom {X₁ Y₁ X₂ Y₂ : Cᴹᵒᵖ} (f : X₁ ⟶ Y₁) (g : X₂ ⟶ Y₂) : (f ⊗ₘ g).unmop = g.unmop ⊗ₘ f.unmop := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_whiskerLeft (X : C) {Y Z : C} (f : Y ⟶ Z) : (X ◁ f).mop = f.mop ▷ mop X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_whiskerLeft (X : Cᴹᵒᵖ) {Y Z : Cᴹᵒᵖ} (f : Y ⟶ Z) : (X ◁ f).unmop = f.unmop ▷ unmop X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_whiskerRight {X Y : C} (f : X ⟶ Y) (Z : C) : (f ▷ Z).mop = mop Z ◁ f.mop := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_whiskerRight {X Y : Cᴹᵒᵖ} (f : X ⟶ Y) (Z : Cᴹᵒᵖ) : (f ▷ Z).unmop = unmop Z ◁ f.unmop := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_associator (X Y Z : C) : (α_ X Y Z).mop = (α_ (mop Z) (mop Y) (mop X)).symm := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_associator (X Y Z : Cᴹᵒᵖ) : (α_ X Y Z).unmop = (α_ (unmop Z) (unmop Y) (unmop X)).symm := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_hom_associator (X Y Z : C) : (α_ X Y Z).hom.mop = (α_ (mop Z) (mop Y) (mop X)).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_hom_associator (X Y Z : Cᴹᵒᵖ) : (α_ X Y Z).hom.unmop = (α_ (unmop Z) (unmop Y) (unmop X)).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_inv_associator (X Y Z : C) : (α_ X Y Z).inv.mop = (α_ (mop Z) (mop Y) (mop X)).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_inv_associator (X Y Z : Cᴹᵒᵖ) : (α_ X Y Z).inv.unmop = (α_ (unmop Z) (unmop Y) (unmop X)).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_leftUnitor (X : C) : (λ_ X).mop = (ρ_ (mop X)) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_leftUnitor (X : Cᴹᵒᵖ) : (λ_ X).unmop = ρ_ (unmop X) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_hom_leftUnitor (X : C) : (λ_ X).hom.mop = (ρ_ (mop X)).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_hom_leftUnitor (X : Cᴹᵒᵖ) : (λ_ X).hom.unmop = (ρ_ (unmop X)).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_inv_leftUnitor (X : C) : (λ_ X).inv.mop = (ρ_ (mop X)).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_inv_leftUnitor (X : Cᴹᵒᵖ) : (λ_ X).inv.unmop = (ρ_ (unmop X)).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_rightUnitor (X : C) : (ρ_ X).mop = (λ_ (mop X)) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_rightUnitor (X : Cᴹᵒᵖ) : (ρ_ X).unmop = λ_ (unmop X) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_hom_rightUnitor (X : C) : (ρ_ X).hom.mop = (λ_ (mop X)).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_hom_rightUnitor (X : Cᴹᵒᵖ) : (ρ_ X).hom.unmop = (λ_ (unmop X)).hom := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mop_inv_rightUnitor (X : C) : (ρ_ X).inv.mop = (λ_ (mop X)).inv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma unmop_inv_rightUnitor (X : Cᴹᵒᵖ) : (ρ_ X).inv.unmop = (λ_ (unmop X)).inv := rfl end MonoidalOppositeLemmas @@ -331,10 +360,14 @@ set_option linter.style.whitespace false in -- manual alignment is not recognise /-- The (identity) equivalence between `Cᴹᵒᵖ` and `C`. -/ @[simps!] def MonoidalOpposite.unmopEquiv : Cᴹᵒᵖ ≌ C := (mopEquiv C).symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence between `C` and its monoidal opposite's monoidal opposite. -/ @[simps!] def MonoidalOpposite.mopMopEquivalence : Cᴹᵒᵖᴹᵒᵖ ≌ C := .trans (MonoidalOpposite.unmopEquiv Cᴹᵒᵖ) (MonoidalOpposite.unmopEquiv C) +set_option backward.isDefEq.respectTransparency.types false in @[simps!] instance MonoidalOpposite.mopMopEquivalenceFunctorMonoidal : (MonoidalOpposite.mopMopEquivalence C).functor.Monoidal where @@ -360,12 +393,14 @@ instance MonoidalOpposite.mopMopEquivalenceInverseMonoidal : μ_δ X Y := Category.comp_id _ δ_μ X Y := Category.comp_id _ +set_option backward.isDefEq.respectTransparency.types false in instance : (mopMopEquivalence C).IsMonoidal where leftAdjoint_ε := by simp [ε, η, mopMopEquivalence, Equivalence.trans, unmopEquiv, ε] leftAdjoint_μ X Y := by simp [μ, δ, mopMopEquivalence, Equivalence.trans, unmopEquiv, μ] +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `mop X ⊗ mop Y = mop (Y ⊗ X)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorIso : @@ -375,36 +410,42 @@ def MonoidalOpposite.tensorIso : variable {C} +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `X ⊗ - = mop (- ⊗ unmop X)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorLeftIso (X : Cᴹᵒᵖ) : tensorLeft X ≅ unmopFunctor C ⋙ tensorRight (unmop X) ⋙ mopFunctor C := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `mop X ⊗ - = mop (- ⊗ X)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorLeftMopIso (X : C) : tensorLeft (mop X) ≅ unmopFunctor C ⋙ tensorRight X ⋙ mopFunctor C := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `unmop X ⊗ - = unmop (mop - ⊗ X)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorLeftUnmopIso (X : Cᴹᵒᵖ) : tensorLeft (unmop X) ≅ mopFunctor C ⋙ tensorRight X ⋙ unmopFunctor C := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `- ⊗ X = mop (unmop X ⊗ -)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorRightIso (X : Cᴹᵒᵖ) : tensorRight X ≅ unmopFunctor C ⋙ tensorLeft (unmop X) ⋙ mopFunctor C := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `- ⊗ mop X = mop (- ⊗ unmop X)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorRightMopIso (X : C) : tensorRight (mop X) ≅ unmopFunctor C ⋙ tensorLeft X ⋙ mopFunctor C := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The identification `- ⊗ unmop X = unmop (X ⊗ mop -)` as a natural isomorphism. -/ @[simps!] def MonoidalOpposite.tensorRightUnmopIso (X : Cᴹᵒᵖ) : @@ -436,6 +477,7 @@ instance monoidalUnopUnop : (unopUnop C).Monoidal where instance : (opOpEquivalence C).functor.Monoidal := monoidalUnopUnop instance : (opOpEquivalence C).inverse.Monoidal := monoidalOpOp +set_option backward.isDefEq.respectTransparency.types false in instance : (opOpEquivalence C).IsMonoidal where leftAdjoint_ε := by simp [opOpEquivalence] leftAdjoint_μ := by simp [opOpEquivalence] diff --git a/Mathlib/CategoryTheory/Monoidal/Opposite/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Opposite/Mon.lean index 1d7abf4c324fbe..337f37627e5503 100644 --- a/Mathlib/CategoryTheory/Monoidal/Opposite/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Opposite/Mon.lean @@ -89,6 +89,7 @@ instance unmop_isMonHom {N : Cᴹᵒᵖ} [MonObj N] end unmop +set_option backward.isDefEq.respectTransparency.types false in variable (C) in /-- The equivalence of categories between monoids internal to `C` and monoids internal to the monoidal opposite of `C`. -/ @@ -103,6 +104,7 @@ def mopEquiv : Mon C ≌ Mon Cᴹᵒᵖ where unitIso := .refl _ counitIso := .refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence of categories between monoids internal to `C` and monoids internal to the monoidal opposite of `C` lies over the equivalence `C ≌ Cᴹᵒᵖ` via the forgetful functors. -/ diff --git a/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean b/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean index 6ace1b822076ef..76e2bc666573ea 100644 --- a/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean +++ b/Mathlib/CategoryTheory/Monoidal/PushoutProduct.lean @@ -47,7 +47,7 @@ universe v v' u u' namespace CategoryTheory -open Limits MonoidalCategory Functor PushoutObjObj +open Limits MonoidalCategory CategoryTheory.Functor PushoutObjObj variable {C : Type u} [Category.{v} C] @@ -103,8 +103,8 @@ section Monoidal variable [MonoidalCategory C] (X₁ X₂ X₃ : Arrow C) {W : C} -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- Left-whiskering the pushout-product of `X₁` and `X₂` with `W : C` is isomorphic to the pushout-product of `W ◁ X₁` and `X₂`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Monoidal/Rigid/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Rigid/Basic.lean index 6d421fa4f6a11c..86f33962bc4482 100644 --- a/Mathlib/CategoryTheory/Monoidal/Rigid/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Rigid/Basic.lean @@ -427,22 +427,26 @@ def tensorRightHomEquiv (X Y Y' Z : C) [ExactPairing Y Y'] : (X ⊗ Y ⟶ Z) ≃ _ = f := by rw [coevaluation_evaluation'']; monoidal +set_option backward.isDefEq.respectTransparency.types false in theorem tensorLeftHomEquiv_naturality {X Y Y' Z Z' : C} [ExactPairing Y Y'] (f : Y' ⊗ X ⟶ Z) (g : Z ⟶ Z') : (tensorLeftHomEquiv X Y Y' Z') (f ≫ g) = (tensorLeftHomEquiv X Y Y' Z) f ≫ Y ◁ g := by simp [tensorLeftHomEquiv] +set_option backward.isDefEq.respectTransparency.types false in theorem tensorLeftHomEquiv_symm_naturality {X X' Y Y' Z : C} [ExactPairing Y Y'] (f : X ⟶ X') (g : X' ⟶ Y ⊗ Z) : (tensorLeftHomEquiv X Y Y' Z).symm (f ≫ g) = _ ◁ f ≫ (tensorLeftHomEquiv X' Y Y' Z).symm g := by simp [tensorLeftHomEquiv] +set_option backward.isDefEq.respectTransparency.types false in theorem tensorRightHomEquiv_naturality {X Y Y' Z Z' : C} [ExactPairing Y Y'] (f : X ⊗ Y ⟶ Z) (g : Z ⟶ Z') : (tensorRightHomEquiv X Y Y' Z') (f ≫ g) = (tensorRightHomEquiv X Y Y' Z) f ≫ g ▷ Y' := by simp [tensorRightHomEquiv] +set_option backward.isDefEq.respectTransparency.types false in theorem tensorRightHomEquiv_symm_naturality {X X' Y Y' Z : C} [ExactPairing Y Y'] (f : X ⟶ X') (g : X' ⟶ Z ⊗ Y') : (tensorRightHomEquiv X Y Y' Z).symm (f ≫ g) = @@ -478,11 +482,12 @@ structure shouldn't come from `HasLeftDual` (e.g. in the category `FinVect k`, i convenient to define the internal hom as `Y →ₗ[k] X` rather than `ᘁY ⊗ X` even though these are naturally isomorphic). -/ -@[implicit_reducible] +@[instance_reducible] def closedOfHasLeftDual (Y : C) [HasLeftDual Y] : Closed Y where rightAdj := tensorLeft (ᘁY) adj := tensorLeftAdjunction (ᘁY) Y +set_option backward.isDefEq.respectTransparency.types false in /-- `tensorLeftHomEquiv` commutes with tensoring on the right -/ theorem tensorLeftHomEquiv_tensor {X X' Y Y' Z Z' : C} [ExactPairing Y Y'] (f : X ⟶ Y ⊗ Z) (g : X' ⟶ Z') : @@ -490,6 +495,7 @@ theorem tensorLeftHomEquiv_tensor {X X' Y Y' Z Z' : C} [ExactPairing Y Y'] (f : (α_ _ _ _).inv ≫ ((tensorLeftHomEquiv X Y Y' Z).symm f ⊗ₘ g) := by simp [tensorLeftHomEquiv, tensorHom_def'] +set_option backward.isDefEq.respectTransparency.types false in /-- `tensorRightHomEquiv` commutes with tensoring on the left -/ theorem tensorRightHomEquiv_tensor {X X' Y Y' Z Z' : C} [ExactPairing Y Y'] (f : X ⟶ Z ⊗ Y') (g : X' ⟶ Z') : @@ -497,6 +503,7 @@ theorem tensorRightHomEquiv_tensor {X X' Y Y' Z Z' : C} [ExactPairing Y Y'] (f : (α_ _ _ _).hom ≫ (g ⊗ₘ (tensorRightHomEquiv X Y Y' Z).symm f) := by simp [tensorRightHomEquiv, tensorHom_def] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorLeftHomEquiv_symm_coevaluation_comp_whiskerLeft {Y Y' Z : C} [ExactPairing Y Y'] (f : Y' ⟶ Z) : (tensorLeftHomEquiv _ _ _ _).symm (η_ _ _ ≫ Y ◁ f) = (ρ_ _).hom ≫ f := by @@ -507,6 +514,7 @@ theorem tensorLeftHomEquiv_symm_coevaluation_comp_whiskerLeft {Y Y' Z : C} [Exac rw [whisker_exchange]; monoidal _ = _ := by rw [coevaluation_evaluation'']; monoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorLeftHomEquiv_symm_coevaluation_comp_whiskerRight {X Y : C} [HasRightDual X] [HasRightDual Y] (f : X ⟶ Y) : @@ -514,6 +522,7 @@ theorem tensorLeftHomEquiv_symm_coevaluation_comp_whiskerRight {X Y : C} [HasRig dsimp [tensorLeftHomEquiv, rightAdjointMate] simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorRightHomEquiv_symm_coevaluation_comp_whiskerLeft {X Y : C} [HasLeftDual X] [HasLeftDual Y] (f : X ⟶ Y) : @@ -521,6 +530,7 @@ theorem tensorRightHomEquiv_symm_coevaluation_comp_whiskerLeft {X Y : C} [HasLef dsimp [tensorRightHomEquiv, leftAdjointMate] simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorRightHomEquiv_symm_coevaluation_comp_whiskerRight {Y Y' Z : C} [ExactPairing Y Y'] (f : Y ⟶ Z) : (tensorRightHomEquiv _ Y _ _).symm (η_ Y Y' ≫ f ▷ Y') = (λ_ _).hom ≫ f := @@ -532,6 +542,7 @@ theorem tensorRightHomEquiv_symm_coevaluation_comp_whiskerRight {Y Y' Z : C} [Ex _ = _ := by rw [evaluation_coevaluation'']; monoidal +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorLeftHomEquiv_whiskerLeft_comp_evaluation {Y Z : C} [HasLeftDual Z] (f : Y ⟶ ᘁZ) : (tensorLeftHomEquiv _ _ _ _) (Z ◁ f ≫ ε_ _ _) = f ≫ (ρ_ _).inv := @@ -555,6 +566,7 @@ theorem tensorRightHomEquiv_whiskerLeft_comp_evaluation {X Y : C} [HasRightDual dsimp [tensorRightHomEquiv, rightAdjointMate] simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorRightHomEquiv_whiskerRight_comp_evaluation {X Y : C} [HasRightDual X] (f : Y ⟶ Xᘁ) : (tensorRightHomEquiv _ _ _ _) (f ▷ X ≫ ε_ X (Xᘁ)) = f ≫ (λ_ _).inv := @@ -592,7 +604,7 @@ theorem rightAdjointMate_comp_evaluation {X Y : C} [HasRightDual X] [HasRightDua simp /-- Transport an exact pairing across an isomorphism in the first argument. -/ -@[implicit_reducible] +@[instance_reducible] def exactPairingCongrLeft {X X' Y : C} [ExactPairing X' Y] (i : X ≅ X') : ExactPairing X Y where evaluation' := Y ◁ i.hom ≫ ε_ _ _ coevaluation' := η_ _ _ ≫ i.inv ▷ Y @@ -621,7 +633,7 @@ def exactPairingCongrLeft {X X' Y : C} [ExactPairing X' Y] (i : X ≅ X') : Exac simp /-- Transport an exact pairing across an isomorphism in the second argument. -/ -@[implicit_reducible] +@[instance_reducible] def exactPairingCongrRight {X Y Y' : C} [ExactPairing X Y'] (i : Y ≅ Y') : ExactPairing X Y where evaluation' := i.hom ▷ X ≫ ε_ _ _ coevaluation' := η_ _ _ ≫ X ◁ i.inv @@ -650,7 +662,7 @@ def exactPairingCongrRight {X Y Y' : C} [ExactPairing X Y'] (i : Y ≅ Y') : Exa monoidal /-- Transport an exact pairing across isomorphisms. -/ -@[implicit_reducible] +@[instance_reducible] def exactPairingCongr {X X' Y Y' : C} [ExactPairing X' Y'] (i : X ≅ X') (j : Y ≅ Y') : ExactPairing X Y := haveI : ExactPairing X' Y := exactPairingCongrRight j @@ -723,7 +735,7 @@ often a more useful definition of the internal hom object than `ᘁY ⊗ X`, in closed structure shouldn't come the rigid structure (e.g. in the category `FinVect k`, it is more convenient to define the internal hom as `Y →ₗ[k] X` rather than `ᘁY ⊗ X` even though these are naturally isomorphic). -/ -@[implicit_reducible] +@[instance_reducible] def monoidalClosedOfLeftRigidCategory (C : Type u) [Category.{v} C] [MonoidalCategory.{v} C] [LeftRigidCategory C] : MonoidalClosed C where closed X := closedOfHasLeftDual X diff --git a/Mathlib/CategoryTheory/Monoidal/Rigid/Braided.lean b/Mathlib/CategoryTheory/Monoidal/Rigid/Braided.lean index 8631273bd73480..88bc6e2f1e289e 100644 --- a/Mathlib/CategoryTheory/Monoidal/Rigid/Braided.lean +++ b/Mathlib/CategoryTheory/Monoidal/Rigid/Braided.lean @@ -77,7 +77,7 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- If `X` and `Y` forms an exact pairing in a braided category, then so does `Y` and `X` by composing the coevaluation and evaluation morphisms with associators. -/ -@[implicit_reducible] +@[instance_reducible] def exactPairing_swap (X Y : C) [ExactPairing X Y] : ExactPairing Y X where coevaluation' := η_ X Y ≫ (β_ Y X).inv evaluation' := (β_ X Y).hom ≫ ε_ X Y @@ -85,39 +85,39 @@ def exactPairing_swap (X Y : C) [ExactPairing X Y] : ExactPairing Y X where evaluation_coevaluation' := evaluation_coevaluation_braided' /-- If `X` has a right dual in a braided category, then it has a left dual. -/ -@[implicit_reducible] +@[instance_reducible] def hasLeftDualOfHasRightDual [HasRightDual X] : HasLeftDual X where leftDual := Xᘁ exact := exactPairing_swap X Xᘁ /-- If `X` has a left dual in a braided category, then it has a right dual. -/ -@[implicit_reducible] +@[instance_reducible] def hasRightDualOfHasLeftDual [HasLeftDual X] : HasRightDual X where rightDual := ᘁX exact := exactPairing_swap ᘁX X /-- If a braided category is right-rigid, then it is left-rigid. Not registered as an instance as this is not canonical enough. -/ -@[implicit_reducible] +@[instance_reducible] def leftRigidCategoryOfRightRigidCategory [RightRigidCategory C] : LeftRigidCategory C where leftDual X := hasLeftDualOfHasRightDual (X := X) /-- If a braided category is left-rigid, then it is right-rigid. Not registered as an instance as this is not canonical enough. -/ -@[implicit_reducible] +@[instance_reducible] def rightRigidCategoryOfLeftRigidCategory [LeftRigidCategory C] : RightRigidCategory C where rightDual X := hasRightDualOfHasLeftDual (X := X) /-- If `C` is a braided and right rigid category, then it is a rigid category. Not registered as an instance as this is not canonical enough. -/ -@[implicit_reducible] +@[instance_reducible] def rigidCategoryOfRightRigidCategory [RightRigidCategory C] : RigidCategory C where rightDual := inferInstance leftDual X := hasLeftDualOfHasRightDual (X := X) /-- If `C` is a braided and left rigid category, then it is a rigid category. Not registered as an instance as this is not canonical enough. -/ -@[implicit_reducible] +@[instance_reducible] def rigidCategoryOfLeftRigidCategory [LeftRigidCategory C] : RigidCategory C where rightDual X := hasRightDualOfHasLeftDual (X := X) leftDual := inferInstance diff --git a/Mathlib/CategoryTheory/Monoidal/Rigid/OfEquivalence.lean b/Mathlib/CategoryTheory/Monoidal/Rigid/OfEquivalence.lean index 9c528fb2adaefa..d7eadc75a0e32d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Rigid/OfEquivalence.lean +++ b/Mathlib/CategoryTheory/Monoidal/Rigid/OfEquivalence.lean @@ -24,7 +24,7 @@ variable {C D : Type*} [Category* C] [Category* D] [MonoidalCategory C] [Monoida /-- Given candidate data for an exact pairing, which is sent by a faithful monoidal functor to an exact pairing, the equations holds automatically. -/ -@[implicit_reducible] +@[instance_reducible] def ExactPairing.ofFaithful [F.Faithful] {X Y : C} (eval : Y ⊗ X ⟶ 𝟙_ C) (coeval : 𝟙_ C ⟶ X ⊗ Y) [ExactPairing (F.obj X) (F.obj Y)] (map_eval : F.map eval = (δ F _ _) ≫ ε_ _ _ ≫ ε F) @@ -43,7 +43,7 @@ def ExactPairing.ofFaithful [F.Faithful] {X Y : C} (eval : Y ⊗ X ⟶ 𝟙_ C) /-- Given a pair of objects which are sent by a fully faithful functor to a pair of objects with an exact pairing, we get an exact pairing. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ExactPairing.ofFullyFaithful [F.Full] [F.Faithful] (X Y : C) [ExactPairing (F.obj X) (F.obj Y)] : ExactPairing X Y := .ofFaithful F (F.preimage (δ F _ _ ≫ ε_ _ _ ≫ (ε F))) @@ -55,7 +55,7 @@ variable {G : D ⥤ C} (adj : F ⊣ G) [F.IsEquivalence] noncomputable section /-- Pull back a left dual along an equivalence. -/ -@[implicit_reducible] +@[instance_reducible] def hasLeftDualOfEquivalence (X : C) [HasLeftDual (F.obj X)] : HasLeftDual X where leftDual := G.obj (ᘁ(F.obj X)) @@ -65,7 +65,7 @@ def hasLeftDualOfEquivalence (X : C) [HasLeftDual (F.obj X)] : apply ExactPairing.ofFullyFaithful F /-- Pull back a right dual along an equivalence. -/ -@[implicit_reducible] +@[instance_reducible] def hasRightDualOfEquivalence (X : C) [HasRightDual (F.obj X)] : HasRightDual X where rightDual := G.obj ((F.obj X)ᘁ) @@ -75,17 +75,17 @@ def hasRightDualOfEquivalence (X : C) [HasRightDual (F.obj X)] : apply ExactPairing.ofFullyFaithful F /-- Pull back a left rigid structure along an equivalence. -/ -@[implicit_reducible] +@[instance_reducible] def leftRigidCategoryOfEquivalence [LeftRigidCategory D] : LeftRigidCategory C where leftDual X := hasLeftDualOfEquivalence adj X /-- Pull back a right rigid structure along an equivalence. -/ -@[implicit_reducible] +@[instance_reducible] def rightRigidCategoryOfEquivalence [RightRigidCategory D] : RightRigidCategory C where rightDual X := hasRightDualOfEquivalence adj X /-- Pull back a rigid structure along an equivalence. -/ -@[implicit_reducible] +@[instance_reducible] def rigidCategoryOfEquivalence [RigidCategory D] : RigidCategory C where leftDual X := hasLeftDualOfEquivalence adj X rightDual X := hasRightDualOfEquivalence adj X diff --git a/Mathlib/CategoryTheory/Monoidal/Skeleton.lean b/Mathlib/CategoryTheory/Monoidal/Skeleton.lean index 48b70fb3d13672..cdb91a9224e08c 100644 --- a/Mathlib/CategoryTheory/Monoidal/Skeleton.lean +++ b/Mathlib/CategoryTheory/Monoidal/Skeleton.lean @@ -82,7 +82,7 @@ noncomputable instance instCommMonoid [BraidedCategory C] : CommMonoid (Skeleton end Skeleton -open Functor +open CategoryTheory.Functor noncomputable instance : (skeletonEquivalence C).functor.Monoidal := inferInstanceAs (Monoidal.equivalenceTransported (skeletonEquivalence C).symm).inverse.Monoidal diff --git a/Mathlib/CategoryTheory/Monoidal/Subcategory.lean b/Mathlib/CategoryTheory/Monoidal/Subcategory.lean index 0f31e48949a973..00354053441695 100644 --- a/Mathlib/CategoryTheory/Monoidal/Subcategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Subcategory.lean @@ -128,6 +128,7 @@ section variable {P} {P' : ObjectProperty C} [P'.IsMonoidal] (h : P ≤ P') +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An inequality `P ≤ P'` between monoidal properties of objects induces a monoidal functor between full monoidal subcategories. -/ @@ -159,6 +160,7 @@ instance : P.ι.Braided where variable {P} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An inequality `P ≤ P'` between monoidal properties of objects induces a braided functor between full braided subcategories. -/ diff --git a/Mathlib/CategoryTheory/Monoidal/Transport.lean b/Mathlib/CategoryTheory/Monoidal/Transport.lean index bde842e597be2a..dde3a9c25f5661 100644 --- a/Mathlib/CategoryTheory/Monoidal/Transport.lean +++ b/Mathlib/CategoryTheory/Monoidal/Transport.lean @@ -81,7 +81,7 @@ where the operations are already defined on the destination type `D`. The functor `F` must preserve all the data parts of the monoidal structure between the two categories. -/ -@[implicit_reducible] +@[instance_reducible] def induced [MonoidalCategoryStruct D] (F : D ⥤ C) [F.Faithful] (fData : InducingFunctorData F) : MonoidalCategory.{v₂} D where @@ -134,7 +134,7 @@ instance fromInducedMonoidal [MonoidalCategoryStruct D] (F : D ⥤ C) [F.Faithfu /-- Transport a monoidal structure along an equivalence of (plain) categories. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def transportStruct (e : C ≌ D) : MonoidalCategoryStruct.{v₂} D where tensorObj X Y := e.functor.obj (e.inverse.obj X ⊗ e.inverse.obj Y) whiskerLeft X _ _ f := e.functor.map (e.inverse.obj X ◁ e.inverse.map f) @@ -158,7 +158,7 @@ the fields `whiskerLeft_eq` and following were all filled by the `cat_disch` aut attribute [local simp] transportStruct in /-- Transport a monoidal structure along an equivalence of (plain) categories. -/ -@[implicit_reducible] +@[instance_reducible] def transport (e : C ≌ D) : MonoidalCategory.{v₂} D := letI : MonoidalCategoryStruct.{v₂} D := transportStruct e induced e.inverse diff --git a/Mathlib/CategoryTheory/MorphismProperty/Basic.lean b/Mathlib/CategoryTheory/MorphismProperty/Basic.lean index d27c680a517aaa..51e5d15f28b55d 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Basic.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Basic.lean @@ -73,6 +73,7 @@ lemma of_eq_top {P : MorphismProperty C} (h : P = ⊤) {X Y : C} (f : X ⟶ Y) : lemma sup_iff (W W' : MorphismProperty C) {X Y : C} (f : X ⟶ Y) : (W ⊔ W') f ↔ W f ∨ W' f := Iff.rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma sSup_iff (S : Set (MorphismProperty C)) {X Y : C} (f : X ⟶ Y) : sSup S f ↔ ∃ W ∈ S, W f := by @@ -87,6 +88,7 @@ lemma iSup_iff {ι : Sort*} (W : ι → MorphismProperty C) {X Y : C} (f : X ⟶ lemma inf_iff (W W' : MorphismProperty C) {X Y : C} (f : X ⟶ Y) : (W ⊓ W') f ↔ W f ∧ W' f := Iff.rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma sInf_iff (S : Set (MorphismProperty C)) {X Y : C} (f : X ⟶ Y) : sInf S f ↔ ∀ W ∈ S, W f := by diff --git a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean index b942cab0ba82c2..6161d19aa842b9 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean @@ -378,6 +378,7 @@ def mapLeft (l : L₁ ⟶ L₂) (hl : ∀ X : P.Comma L₂ R Q W, P (l.app X.lef lift (forget _ _ _ _ _ ⋙ CategoryTheory.Comma.mapLeft R l) hl (fun f ↦ f.prop_hom_left) (fun f ↦ f.prop_hom_right) +set_option backward.isDefEq.respectTransparency.types false in variable (L R) in /-- The functor `P.Comma L R Q W ⥤ P.Comma L R Q W` induced by the identity natural transformation on `L` is naturally isomorphic to the identity functor. -/ @@ -386,6 +387,7 @@ def mapLeftId [Q.RespectsIso] [W.RespectsIso] : mapLeft (P := P) (Q := Q) (W := W) R (𝟙 L) (fun X ↦ by simpa using X.prop) ≅ 𝟭 _ := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- The functor `P.Comma L₁ R Q W ⥤ P.Comma L₃ R Q W` induced by the composition of two natural transformations `l : L₁ ⟶ L₂` and `l' : L₂ ⟶ L₃` is naturally isomorphic to the composition of the @@ -399,6 +401,7 @@ def mapLeftComp [Q.RespectsIso] [W.RespectsIso] (l : L₁ ⟶ L₂) (l' : L₂ mapLeft R l' hl' ⋙ mapLeft R l hl := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- Two equal natural transformations `L₁ ⟶ L₂` yield naturally isomorphic functors `P.Comma L₁ R Q W ⥤ P.Comma L₂ R Q W`. -/ @@ -408,6 +411,7 @@ def mapLeftEq [Q.RespectsIso] [W.RespectsIso] (l l' : L₁ ⟶ L₂) (h : l = l' mapLeft R l hl ≅ mapLeft R l' (h ▸ hl) := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- A natural isomorphism `L₁ ≅ L₂` induces an equivalence of categories `P.Comma L₁ R Q W ≌ P.Comma L₂ R Q W`. -/ @@ -440,6 +444,7 @@ def mapRight (r : R₁ ⟶ R₂) (hr : ∀ X : P.Comma L R₁ Q W, P (X.hom ≫ lift (forget _ _ _ _ _ ⋙ CategoryTheory.Comma.mapRight L r) hr (fun f ↦ f.prop_hom_left) (fun f ↦ f.prop_hom_right) +set_option backward.isDefEq.respectTransparency.types false in variable (L R) in /-- The functor `P.Comma L R Q W ⥤ P.Comma L R Q W` induced by the identity natural transformation on `R` is naturally isomorphic to the identity functor. -/ @@ -448,6 +453,7 @@ def mapRightId [Q.RespectsIso] [W.RespectsIso] : mapRight (P := P) (Q := Q) (W := W) L (𝟙 R) (fun X ↦ by simpa using X.prop) ≅ 𝟭 _ := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in variable (L) in /-- The functor `P.Comma L R₁ Q W ⥤ P.Comma L R₃ Q W` induced by the composition of the natural transformations `r : R₁ ⟶ R₂` and `r' : R₂ ⟶ R₃` is naturally isomorphic to the composition of the @@ -461,6 +467,7 @@ def mapRightComp [Q.RespectsIso] [W.RespectsIso] (r : R₁ ⟶ R₂) (r' : R₂ mapRight L r hr ⋙ mapRight L r' hr' := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in variable (L) in /-- Two equal natural transformations `R₁ ⟶ R₂` yield naturally isomorphic functors `P.Comma L R₁ Q W ⥤ P.Comma L R₂ Q W`. -/ @@ -470,6 +477,7 @@ def mapRightEq [Q.RespectsIso] [W.RespectsIso] (r r' : R₁ ⟶ R₂) (h : r = r mapRight L r hr ≅ mapRight L r' (h ▸ hr) := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in variable (L) in /-- A natural isomorphism `R₁ ≅ R₂` induces an equivalence of categories `P.Comma L R₁ Q W ≌ P.Comma L R₂ Q W`. -/ @@ -651,12 +659,14 @@ protected def Over.isoMk [Q.RespectsIso] {A B : P.Over Q X} (f : A.left ≅ B.le (w : f.hom ≫ B.hom = A.hom := by cat_disch) : A ≅ B := Comma.isoMk f (Discrete.eqToIso' rfl) +set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma Over.Hom.ext {A B : P.Over Q X} {f g : A ⟶ B} (h : f.left = g.left) : f = g := by ext · exact h · simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Over.w {A B : P.Over Q X} (f : A ⟶ B) : f.left ≫ B.hom = A.hom := by @@ -737,12 +747,14 @@ protected def Under.isoMk [Q.RespectsIso] {A B : P.Under Q X} (f : A.right ≅ B (w : A.hom ≫ f.hom = B.hom := by cat_disch) : A ≅ B := Comma.isoMk (Discrete.eqToIso' rfl) f +set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma Under.Hom.ext {A B : P.Under Q X} {f g : A ⟶ B} (h : f.right = g.right) : f = g := by ext · simp · exact h +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma Under.w {A B : P.Under Q X} (f : A ⟶ B) : A.hom ≫ f.right = B.hom := by @@ -783,6 +795,7 @@ def CostructuredArrow.homMk {A B : P.CostructuredArrow Q F X} (f : A.left ⟶ B. prop_hom_left := hf prop_hom_right := trivial +set_option backward.isDefEq.respectTransparency.types false in variable {P Q F X} in @[ext] lemma CostructuredArrow.Hom.ext {A B : P.CostructuredArrow Q F X} {f g : A ⟶ B} @@ -817,6 +830,7 @@ instance [F.Faithful] : (CostructuredArrow.toOver P F X).Faithful := by ext exact F.map_injective congr($(hfg).left) +set_option backward.isDefEq.respectTransparency.types false in instance [F.Full] : (CostructuredArrow.toOver P F X).Full := by constructor intro A B f @@ -826,6 +840,7 @@ instance [F.Full] : (CostructuredArrow.toOver P F X).Full := by end CostructuredArrow +set_option backward.isDefEq.respectTransparency.types false in instance HasFactorization.over {C : Type*} [Category* C] (W₁ W₂ : MorphismProperty C) [W₁.HasFactorization W₂] (S : C) : diff --git a/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean b/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean index 083328e2b51d15..1890aabc2c4718 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean @@ -114,6 +114,7 @@ end ConcreteCategory open ConcreteCategory +set_option backward.isDefEq.respectTransparency.types false in /-- In the category of types, any map can be functorially factored as a surjective map followed by an injective map. -/ def functorialSurjectiveInjectiveFactorizationData : diff --git a/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean b/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean index 6c864a3443bd19..ea1c25213b2f8c 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Factorization.lean @@ -176,11 +176,17 @@ functoriality of the intermediate objects of the factorizations for `φ : Arrow.mk f ⟶ Arrow.mk g`. -/ def mapZ : (data.factorizationData f).Z ⟶ (data.factorizationData g).Z := data.Z.map φ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma i_mapZ : (data.factorizationData f).i ≫ data.mapZ φ = φ.left ≫ (data.factorizationData g).i := (data.i.naturality φ).symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma mapZ_p : data.mapZ φ ≫ (data.factorizationData g).p = (data.factorizationData f).p ≫ φ.right := @@ -202,6 +208,7 @@ section variable (J : Type*) [Category* J] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `FunctorialFactorizationData.functorCategory`. -/ @[simps] @@ -233,6 +240,7 @@ def functorCategory.Z : Arrow (J ⥤ C) ⥤ J ⥤ C where rw [← data.mapZ_comp] congr 1 +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functorial factorization in the category `C` extends to the functor category `J ⥤ C`. -/ def functorCategory : diff --git a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean index c9cab609ae86aa..a496ceeadf8bef 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean @@ -669,6 +669,7 @@ lemma coproducts_of_small {X Y : C} (f : X ⟶ Y) {J : Type w'} refine ⟨Shrink J, ?_⟩ rwa [← W.colimitsOfShape_eq_of_equivalence (Discrete.equivalence (equivShrink.{w} J))] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in lemma le_colimitsOfShape_punit : W ≤ W.colimitsOfShape (Discrete PUnit.{w + 1}) := by diff --git a/Mathlib/CategoryTheory/MorphismProperty/Local.lean b/Mathlib/CategoryTheory/MorphismProperty/Local.lean index 60a80b23c863ab..a17ee36c5d3e2e 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Local.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Local.lean @@ -229,6 +229,7 @@ alias iff_of_zeroHypercover_source := IsLocalAtSource.iff_of_zeroHypercover end MorphismProperty +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Let `J` be a precoverage for which isomorphisms are local at the target. Let diff --git a/Mathlib/CategoryTheory/MorphismProperty/OverAdjunction.lean b/Mathlib/CategoryTheory/MorphismProperty/OverAdjunction.lean index 536698b9fb6302..753f434064e3c5 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/OverAdjunction.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/OverAdjunction.lean @@ -42,6 +42,7 @@ this is the functor `P.Over Q X ⥤ P.Over Q Y` given by composing with `f`. -/ def Over.map {f : X ⟶ Y} (hPf : P f) : P.Over Q X ⥤ P.Over Q Y := Comma.mapRight _ (Discrete.natTrans fun _ ↦ f) <| fun X ↦ P.comp_mem _ _ X.prop hPf +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma Over.map_comp {f : X ⟶ Y} (hf : P f) {g : Y ⟶ Z} (hg : P g) : map Q (P.comp_mem f g hf hg) = map Q hf ⋙ map Q hg := by @@ -51,12 +52,14 @@ lemma Over.map_comp {f : X ⟶ Y} (hf : P f) {g : Y ⟶ Z} (hg : P g) : ext simp +set_option backward.isDefEq.respectTransparency.types false in /-- Promote an equality to an isomorphism of `Over.map` functors. -/ @[simps!] def Over.mapCongr [Q.RespectsIso] {X Y : T} {f g : X ⟶ Y} (hfg : f = g) (hf : P f) : Over.map Q hf ≅ Over.map (f := g) Q (by cat_disch) := NatIso.ofComponents (fun Y ↦ Over.isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option linter.overlappingInstances false in /-- `Over.map` preserves identities. -/ @@ -66,6 +69,7 @@ def Over.mapId [P.IsMultiplicative] [Q.RespectsIso] (X : T) (f : X ⟶ X := 𝟙 Over.map (f := f) (P := P) Q (by subst hf; exact P.id_mem X) ≅ 𝟭 _ := NatIso.ofComponents (fun Y ↦ Over.isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Over.map` commutes with composition. -/ @[simps! hom_app_left inv_app_left] @@ -89,8 +93,8 @@ instance {X Y Z} (f : X ⟶ Y) (g : Y ⟶ Z) HasPullbacksAlong.hasPullback (pullback.snd A.hom g) (IsStableUnderBaseChangeAlong.of_isPullback (IsPullback.of_hasPullback A.hom g) A.prop) -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- If `P` and `Q` are stable under base change and pullbacks along `f` exist for morphisms in `P`, this is the functor `P.Over Q Y ⥤ P.Over Q X` given by base change along `f`. -/ @[simps! obj_left obj_hom map_left] @@ -105,8 +109,8 @@ noncomputable def Over.pullback (f : X ⟶ Y) [P.HasPullbacksAlong f] variable {P} {Q} -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- `Over.pullback` commutes with composition. -/ @[simps! hom_app_left inv_app_left] noncomputable def Over.pullbackComp (f : X ⟶ Y) (g : Y ⟶ Z) @@ -129,8 +133,8 @@ lemma Over.pullbackComp_left_fst_fst (f : X ⟶ Y) (g : Y ⟶ Z) [P.IsStableUnde pullback.fst A.hom g = pullback.fst A.hom (f ≫ g) := by simp -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- If `f = g`, then base change along `f` is naturally isomorphic to base change along `g`. -/ noncomputable def Over.pullbackCongr {f : X ⟶ Y} [P.HasPullbacksAlong f] [P.IsStableUnderBaseChangeAlong f] [Q.IsStableUnderBaseChange] {g : X ⟶ Y} (h : f = g) : @@ -142,6 +146,7 @@ noncomputable def Over.pullbackCongr {f : X ⟶ Y} [P.HasPullbacksAlong f] haveI : HasPullback X.hom g := HasPullbacksAlong.hasPullback _ X.prop Over.isoMk (pullback.congrHom rfl h) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma Over.pullbackCongr_hom_app_left_fst {f : X ⟶ Y} [P.HasPullbacksAlong f] {g : X ⟶ Y} @@ -151,8 +156,8 @@ lemma Over.pullbackCongr_hom_app_left_fst {f : X ⟶ Y} [P.HasPullbacksAlong f] subst h simp [pullbackCongr] -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- The natural map between pullback functors induced by `pullback.map`. -/ @[simps] noncomputable def Over.pullbackMapHomPullback [P.IsStableUnderComposition] @@ -182,8 +187,8 @@ section Adjunction variable [P.IsStableUnderComposition] [Q.IsStableUnderBaseChange] -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- `P.Over.map` is left adjoint to `P.Over.pullback` if pullbacks of morphisms satisfying `P` exist along `f` and are also in `P`, and `f` is in both `P` and `Q`. -/ @[simps! unit_app counit_app] @@ -222,6 +227,7 @@ this is the functor `P.Under Q Y ⥤ P.Under Q X` given by composing with `f`. - def Under.map {f : X ⟶ Y} (hPf : P f) : P.Under Q Y ⥤ P.Under Q X := Comma.mapLeft _ (Discrete.natTrans fun _ ↦ f) <| fun X ↦ P.comp_mem _ _ hPf X.prop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma Under.map_comp {f : X ⟶ Y} (hf : P f) {g : Y ⟶ Z} (hg : P g) : map Q (P.comp_mem f g hf hg) = map Q hg ⋙ map Q hf := by @@ -231,12 +237,14 @@ lemma Under.map_comp {f : X ⟶ Y} (hf : P f) {g : Y ⟶ Z} (hg : P g) : ext simp +set_option backward.isDefEq.respectTransparency.types false in /-- Promote an equality to an isomorphism of `Under.map` functors. -/ @[simps!] def Under.mapCongr [Q.RespectsIso] {X Y : T} {f g : X ⟶ Y} (hfg : f = g) (hf : P f) : Under.map Q hf ≅ Under.map (f := g) Q (by cat_disch) := NatIso.ofComponents (fun Y ↦ Under.isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option linter.overlappingInstances false in /-- `Under.map` preserves identities. -/ @@ -246,6 +254,7 @@ def Under.mapId [P.IsMultiplicative] [Q.RespectsIso] (X : T) (f : X ⟶ X := Under.map (f := f) (P := P) Q (by subst hf; exact P.id_mem X) ≅ 𝟭 _ := NatIso.ofComponents (fun Y ↦ Under.isoMk (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Under.map` commutes with composition. -/ @[simps! hom_app_left] @@ -285,8 +294,8 @@ noncomputable def Under.pushout (f : X ⟶ Y) [P.HasPushoutsAlong f] variable {P} {Q} -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- `Under.pushout` commutes with composition. -/ @[simps! hom_app_right inv_app_right] noncomputable def Under.pushoutComp (f : X ⟶ Y) (g : Y ⟶ Z) @@ -301,8 +310,8 @@ noncomputable def Under.pushoutComp (f : X ⟶ Y) (g : Y ⟶ Z) haveI : HasPushout X.hom fg := HasPushoutsAlong.hasPushout _ X.prop Under.isoMk (pushout.congrHom rfl hfg ≪≫ (pushoutLeftPushoutInrIso X.hom f g).symm) (by simp) -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- If `f = g`, then cobase change along `f` is naturally isomorphic to cobase change along `g`. -/ noncomputable def Under.pushoutCongr {f : X ⟶ Y} [P.HasPushoutsAlong f] [P.IsStableUnderCobaseChangeAlong f] [Q.IsStableUnderCobaseChange] {g : X ⟶ Y} (h : f = g) : @@ -314,6 +323,7 @@ noncomputable def Under.pushoutCongr {f : X ⟶ Y} [P.HasPushoutsAlong f] haveI : HasPushout X.hom g := HasPushoutsAlong.hasPushout _ X.prop Under.isoMk (pushout.congrHom rfl h) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma Under.pushoutCongr_hom_app_left_fst {f : X ⟶ Y} [P.HasPushoutsAlong f] {g : X ⟶ Y} @@ -339,9 +349,9 @@ section Adjunction variable [P.IsStableUnderComposition] [Q.IsStableUnderCobaseChange] +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in attribute [local instance] hasPushouts_symmetry_of_hasPushoutsAlong in -set_option backward.isDefEq.respectTransparency false in /-- `P.Under.pushout` is left adjoint to `P.Under.map` if pushouts of morphisms satisfying `P` exist along `f` and are also in `P`, and `f` is in both `P` and `Q`. -/ @[simps! unit_app counit_app] diff --git a/Mathlib/CategoryTheory/MorphismProperty/Representable.lean b/Mathlib/CategoryTheory/MorphismProperty/Representable.lean index 72a06cb7ab00ec..5c187fb55aa8e7 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Representable.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Representable.lean @@ -213,10 +213,12 @@ case when the cone point is in the image of `F.obj`. -/ noncomputable def lift [Full F] : c ⟶ hf.pullback g := F.preimage <| PullbackCone.IsLimit.lift (hf.isPullback g).isLimit _ _ hi +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma lift_fst [Full F] : F.map (hf.lift i h hi) ≫ hf.fst g = i := by simpa [lift] using! PullbackCone.IsLimit.lift_fst _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma lift_snd [Full F] [Faithful F] : hf.lift i h hi ≫ hf.snd g = h := F.map_injective <| by simpa [lift] using! PullbackCone.IsLimit.lift_snd _ _ _ _ @@ -499,6 +501,7 @@ noncomputable def pullback₃.π : F.obj (pullback₃ hf₁ f₂ f₃) ⟶ X := lemma pullback₃.map_p₁_comp : F.map (p₁ hf₁ f₂ f₃) ≫ f₁ = π _ _ _ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma pullback₃.map_p₂_comp : F.map (p₂ hf₁ f₂ f₃) ≫ f₂ = π _ _ _ := by simp [π, p₁, p₂, ← hf₁.w f₂] @@ -550,6 +553,7 @@ lemma pullback₃.snd_fst'_eq_p₁ : pullback.snd (hf₁.fst' f₂) (hf₁.fst' f₃) ≫ hf₁.fst' f₃ = pullback₃.p₁ hf₁ f₂ f₃ := pullback.condition.symm +set_option backward.isDefEq.respectTransparency.types false in variable {hf₁ f₂ f₃} in @[ext] lemma pullback₃.hom_ext [Faithful F] {Z : C} {φ φ' : Z ⟶ pullback₃ hf₁ f₂ f₃} diff --git a/Mathlib/CategoryTheory/NatTrans.lean b/Mathlib/CategoryTheory/NatTrans.lean index d5cd9410c7cb75..59483ebf883559 100644 --- a/Mathlib/CategoryTheory/NatTrans.lean +++ b/Mathlib/CategoryTheory/NatTrans.lean @@ -80,6 +80,7 @@ theorem congr_app {F G : C ⥤ D} {α β : NatTrans F G} (h : α = β) (X : C) : namespace NatTrans /-- `NatTrans.id F` is the identity natural transformation on a functor `F`. -/ +@[implicit_reducible] protected def id (F : C ⥤ D) : NatTrans F F where app X := 𝟙 (F.obj X) @[simp] diff --git a/Mathlib/CategoryTheory/ObjectProperty/Equivalence.lean b/Mathlib/CategoryTheory/ObjectProperty/Equivalence.lean index 6f7f16339d34d2..e500fecbfd2073 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Equivalence.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Equivalence.lean @@ -48,6 +48,7 @@ def topEquivalence : ObjectProperty.FullSubcategory (C := C) ⊤ ≌ C where inverse := ObjectProperty.lift _ (𝟭 _) (by simp) unitIso := Iso.refl _ counitIso := Iso.refl _ + functor_unitIso_comp := by cat_disch end CategoryTheory.ObjectProperty diff --git a/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean index e27291f6378e69..f4f09f48ab2830 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean @@ -62,6 +62,7 @@ instance (priority := 100) [P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] P.Nonempty := nonempty_of_prop P.prop_terminal +set_option backward.isDefEq.respectTransparency.types false in lemma IsClosedUnderBinaryProducts.closedUnderIsomorphisms [HasTerminal C] [P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] [P.IsClosedUnderBinaryProducts] : P.IsClosedUnderIsomorphisms where @@ -165,6 +166,7 @@ instance (priority := 100) [P.IsClosedUnderColimitsOfShape (Discrete.{0} PEmpty) P.Nonempty := nonempty_of_prop P.prop_initial +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma IsClosedUnderBinaryCoproducts.closedUnderIsomorphisms [HasInitial C] [P.IsClosedUnderColimitsOfShape (Discrete.{0} PEmpty)] [P.IsClosedUnderBinaryCoproducts] : diff --git a/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean b/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean index d355bce2f7dbbf..b0ed1b84240d53 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean @@ -55,6 +55,7 @@ lemma hom_ext {X Y : P.FullSubcategory} {f g : X ⟶ Y} (h : f.hom = g.hom) : f /-- The forgetful functor from a full subcategory into the original category ("forgetting" the condition). -/ +@[implicit_reducible] def ι : P.FullSubcategory ⥤ C := inducedFunctor FullSubcategory.obj @@ -78,7 +79,7 @@ lemma FullSubcategory.comp_hom {X Y Z : P.FullSubcategory} (f : X ⟶ Y) (g : Y variable {P} in /-- Constructor for morphisms in a full subcategory. -/ -@[simps] +@[simps, implicit_reducible] def homMk {X Y : P.FullSubcategory} (f : X.obj ⟶ Y.obj) : X ⟶ Y where hom := f @@ -128,7 +129,7 @@ variable {P' : ObjectProperty C} /-- If `P` and `P'` are properties of objects such that `P ≤ P'`, there is an induced functor `P.FullSubcategory ⥤ P'.FullSubcategory`. -/ -@[simps] +@[simps, implicit_reducible] def ιOfLE (h : P ≤ P') : P.FullSubcategory ⥤ P'.FullSubcategory where obj X := ⟨X.1, h _ X.2⟩ map f := homMk f.hom @@ -154,7 +155,7 @@ variable {D : Type u'} [Category.{v'} D] (P Q : ObjectProperty D) /-- A functor which maps objects to objects satisfying a certain property induces a lift through the full subcategory of objects satisfying that property. -/ -@[simps] +@[simps, implicit_reducible] def lift : C ⥤ FullSubcategory P where obj X := ⟨F.obj X, hF X⟩ map f := homMk (F.map f) diff --git a/Mathlib/CategoryTheory/ObjectProperty/LimitsClosure.lean b/Mathlib/CategoryTheory/ObjectProperty/LimitsClosure.lean index 985cbd93dd332b..59ac50ca9775ec 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/LimitsClosure.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/LimitsClosure.lean @@ -151,6 +151,7 @@ lemma strictLimitsClosureIter_le_limitsClosure (b : β) : intro c hc exact hb' _ hc +set_option backward.isDefEq.respectTransparency.types false in instance [ObjectProperty.Small.{w} P] [LocallySmall.{w} C] [Small.{w} α] [∀ a, Small.{w} (J a)] [∀ a, LocallySmall.{w} (J a)] (b : β) [hb₀ : Small.{w} (Set.Iio b)] : diff --git a/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean b/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean index 757761c8d2c7cf..75ddb590f7b117 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean @@ -110,6 +110,7 @@ noncomputable def reindex {X : C} (h : P.LimitOfShape J X) (G : J' ⥤ J) [G.Ini toLimitPresentation := h.toLimitPresentation.reindex G prop_diag_obj _ := h.prop_diag_obj _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `P : ObjectProperty C`, and a presentation `P.LimitOfShape J X` of an object `X : C`, this is the induced functor `J ⥤ StructuredArrow P.ι X`. -/ diff --git a/Mathlib/CategoryTheory/ObjectProperty/Opposite.lean b/Mathlib/CategoryTheory/ObjectProperty/Opposite.lean index 72bfb9eb14b469..1804573630a362 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Opposite.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Opposite.lean @@ -137,6 +137,7 @@ lemma unop_isoClosure (P : ObjectProperty Cᵒᵖ) : P.isoClosure.unop = P.unop.isoClosure := by rw [← op_injective_iff, P.unop.op_isoClosure, op_unop, op_unop] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `P : ObjectProperty C`, this is the equivalence between `P.op.FullSubcategory` and `P.FullSubcategoryᵒᵖ`. -/ diff --git a/Mathlib/CategoryTheory/Opposites.lean b/Mathlib/CategoryTheory/Opposites.lean index 8c0b06b3b0882b..3433aa65b65f55 100644 --- a/Mathlib/CategoryTheory/Opposites.lean +++ b/Mathlib/CategoryTheory/Opposites.lean @@ -106,7 +106,7 @@ theorem op_comp_unop {X Y Z : Cᵒᵖ} (f : X ⟶ Y) (g : Y ⟶ Z) : (g.unop ≫ end -open Functor +open CategoryTheory.Functor variable [Category.{v₁} C] @@ -205,7 +205,7 @@ variable {D : Type u₂} [Category.{v₂} D] /-- The opposite of a functor, i.e. considering a functor `F : C ⥤ D` as a functor `Cᵒᵖ ⥤ Dᵒᵖ`. In informal mathematics no distinction is made between these. -/ -@[simps] +@[simps, implicit_reducible] protected def op (F : C ⥤ D) : Cᵒᵖ ⥤ Dᵒᵖ where obj X := op (F.obj (unop X)) map f := (F.map f.unop).op @@ -213,7 +213,7 @@ protected def op (F : C ⥤ D) : Cᵒᵖ ⥤ Dᵒᵖ where /-- Given a functor `F : Cᵒᵖ ⥤ Dᵒᵖ` we can take the "unopposite" functor `F : C ⥤ D`. In informal mathematics no distinction is made between these. -/ -@[simps] +@[simps, implicit_reducible] protected def unop (F : Cᵒᵖ ⥤ Dᵒᵖ) : C ⥤ D where obj X := unop (F.obj (op X)) map f := (F.map f.op).unop @@ -298,6 +298,7 @@ protected def rightOp (F : Cᵒᵖ ⥤ D) : C ⥤ Dᵒᵖ where lemma rightOp_map_unop {F : Cᵒᵖ ⥤ D} {X Y} (f : X ⟶ Y) : (F.rightOp.map f).unop = F.map f.op := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {F : C ⥤ D} [Full F] : Full F.op where map_surjective f := ⟨(F.preimage f.unop).op, by simp⟩ @@ -324,10 +325,12 @@ instance rightOp_faithful {F : Cᵒᵖ ⥤ D} [Faithful F] : Faithful F.rightOp instance leftOp_faithful {F : C ⥤ Dᵒᵖ} [Faithful F] : Faithful F.leftOp where map_injective h := Quiver.Hom.unop_inj (map_injective F (Quiver.Hom.unop_inj h)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance rightOp_full {F : Cᵒᵖ ⥤ D} [Full F] : Full F.rightOp where map_surjective f := ⟨(F.preimage f.unop).unop, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance leftOp_full {F : C ⥤ Dᵒᵖ} [Full F] : Full F.leftOp where map_surjective f := ⟨(F.preimage f.op).op, by simp⟩ @@ -820,9 +823,15 @@ def unop (e : Cᵒᵖ ≌ Dᵒᵖ) : C ≌ D where apply Quiver.Hom.op_inj simp +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An equivalence between `C` and `Dᵒᵖ` gives an equivalence between `Cᵒᵖ` and `D`. -/ @[simps!] def leftOp (e : C ≌ Dᵒᵖ) : Cᵒᵖ ≌ D := e.op.trans (opOpEquivalence D) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An equivalence between `Cᵒᵖ` and `D` gives an equivalence between `C` and `Dᵒᵖ`. -/ @[simps!] def rightOp (e : Cᵒᵖ ≌ D) : C ≌ Dᵒᵖ := (opOpEquivalence C).symm.trans e.op @@ -872,6 +881,7 @@ namespace Functor variable (C) variable (D : Type u₂) [Category.{v₂} D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of functor categories induced by `op` and `unop`. -/ diff --git a/Mathlib/CategoryTheory/PUnit.lean b/Mathlib/CategoryTheory/PUnit.lean index 489efd80680371..8c36011ac33af2 100644 --- a/Mathlib/CategoryTheory/PUnit.lean +++ b/Mathlib/CategoryTheory/PUnit.lean @@ -47,6 +47,7 @@ theorem punit_ext' (F G : C ⥤ Discrete PUnit.{w + 1}) : F = G := abbrev fromPUnit (X : C) : Discrete PUnit.{w + 1} ⥤ C := (Functor.const _).obj X +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Functors from `Discrete PUnit` are equivalent to the category itself. -/ @[simps] diff --git a/Mathlib/CategoryTheory/PathCategory/Basic.lean b/Mathlib/CategoryTheory/PathCategory/Basic.lean index 335601a33bc996..b879b688c383b6 100644 --- a/Mathlib/CategoryTheory/PathCategory/Basic.lean +++ b/Mathlib/CategoryTheory/PathCategory/Basic.lean @@ -39,11 +39,13 @@ variable (V : Type u₁) [Quiver.{v₁} V] namespace Paths +set_option backward.isDefEq.respectTransparency.types false in instance categoryPaths : Category.{max u₁ v₁} (Paths V) where Hom := fun X Y : V => Quiver.Path X Y id _ := Quiver.Path.nil comp f g := Quiver.Path.comp f g +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion of a quiver `V` into its path category, as a prefunctor. -/ @[simps] @@ -53,6 +55,7 @@ def of : V ⥤q Paths V where variable {V} +set_option backward.isDefEq.respectTransparency.types false in /-- To prove a property on morphisms of a path category with given source `a`, it suffices to prove it for the identity and prove that the property is preserved under composition on the right with length 1 paths. -/ @@ -83,6 +86,7 @@ lemma induction_fixed_target {b : Paths V} (P : ∀ {a : Paths V}, (a ⟶ b) → obtain ⟨c, f, q, hq, rfl⟩ := f.eq_toPath_comp_of_length_eq_succ h exact comp _ _ (h' _ hq) +set_option backward.isDefEq.respectTransparency.types false in /-- To prove a property on morphisms of a path category, it suffices to prove it for the identity and prove that the property is preserved under composition on the right with length 1 paths. -/ lemma induction (P : ∀ {a b : Paths V}, (a ⟶ b) → Prop) @@ -92,6 +96,7 @@ lemma induction (P : ∀ {a b : Paths V}, (a ⟶ b) → Prop) ∀ {a b : Paths V} (f : a ⟶ b), P f := fun {_} ↦ induction_fixed_source _ id comp +set_option backward.isDefEq.respectTransparency.types false in /-- To prove a property on morphisms of a path category, it suffices to prove it for the identity and prove that the property is preserved under composition on the left with length 1 paths. -/ lemma induction' (P : ∀ {a b : Paths V}, (a ⟶ b) → Prop) @@ -124,20 +129,24 @@ def lift {C} [Category* C] (φ : V ⥤q C) : Paths V ⥤ C where simp only at ih ⊢ rw [ih, Category.assoc] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem lift_nil {C} [Category* C] (φ : V ⥤q C) (X : V) : (lift φ).map Quiver.Path.nil = 𝟙 (φ.obj X) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem lift_cons {C} [Category* C] (φ : V ⥤q C) {X Y Z : V} (p : Quiver.Path X Y) (f : Y ⟶ Z) : (lift φ).map (p.cons f) = (lift φ).map p ≫ φ.map f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem lift_toPath {C} [Category* C] (φ : V ⥤q C) {X Y : V} (f : X ⟶ Y) : (lift φ).map f.toPath = φ.map f := by dsimp [Quiver.Hom.toPath, lift] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem lift_spec {C} [Category* C] (φ : V ⥤q C) : of V ⋙q (lift φ).toPrefunctor = φ := by fapply Prefunctor.ext @@ -170,6 +179,7 @@ theorem lift_unique {C} [Category* C] (φ : V ⥤q C) (Φ : Paths V ⥤ C) convert! Functor.map_comp Φ p (Quiver.Hom.toPath f') rw [this, ih] +set_option backward.isDefEq.respectTransparency.types false in /-- Two functors out of a path category are equal when they agree on singleton paths. -/ @[ext (iff := false)] theorem ext_functor {C} [Category* C] {F G : Paths V ⥤ C} (h_obj : F.obj = G.obj) @@ -191,6 +201,7 @@ end Paths variable (W : Type u₂) [Quiver.{v₂} W] -- A restatement of `Prefunctor.mapPath_comp` using `f ≫ g` instead of `f.comp g`. +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem Prefunctor.mapPath_comp' (F : V ⥤q W) {X Y Z : Paths V} (f : X ⟶ Y) (g : Y ⟶ Z) : F.mapPath (f ≫ g) = (F.mapPath f).comp (F.mapPath g) := @@ -227,10 +238,12 @@ theorem composePath_comp {X Y Z : C} (f : Path X Y) (g : Path Y Z) : | nil => simp | cons g e ih => simp [ih] +set_option backward.isDefEq.respectTransparency.types false in @[simp] -- TODO get rid of `(id X : C)` somehow? theorem composePath_id {X : Paths C} : composePath (𝟙 X) = 𝟙 (show C from X) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem composePath_comp' {X Y Z : Paths C} (f : X ⟶ Y) (g : Y ⟶ Z) : composePath (f ≫ g) = composePath f ≫ composePath g := @@ -238,6 +251,7 @@ theorem composePath_comp' {X Y Z : Paths C} (f : X ⟶ Y) (g : Y ⟶ Z) : variable (C) +set_option backward.isDefEq.respectTransparency.types false in /-- Composition of paths as functor from the path category of a category to the category. -/ @[simps] def pathComposition : Paths C ⥤ C where @@ -258,6 +272,7 @@ def pathsHomRel : HomRel (Paths C) := fun _ _ p q => Assistance investigating this would be appreciated. -/ attribute [nolint simpNF] pathsHomRel.eq_1 +set_option backward.isDefEq.respectTransparency.types false in /-- The functor from a category to the canonical quotient of its path category. -/ @[simps] def toQuotientPaths : C ⥤ Quotient (pathsHomRel C) where @@ -266,12 +281,14 @@ def toQuotientPaths : C ⥤ Quotient (pathsHomRel C) where map_id X := Quot.sound (HomRel.CompClosure.of (by simp)) map_comp f g := Quot.sound (HomRel.CompClosure.of (by simp)) +set_option backward.isDefEq.respectTransparency.types false in /-- The functor from the canonical quotient of a path category of a category to the original category. -/ @[simps!] def quotientPathsTo : Quotient (pathsHomRel C) ⥤ C := Quotient.lift _ (pathComposition C) fun _ _ _ _ w => w +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical quotient of the path category of a category is equivalent to the original category. -/ diff --git a/Mathlib/CategoryTheory/PathCategory/MorphismProperty.lean b/Mathlib/CategoryTheory/PathCategory/MorphismProperty.lean index a9052c1bdc66c8..b3f9ecc646335e 100644 --- a/Mathlib/CategoryTheory/PathCategory/MorphismProperty.lean +++ b/Mathlib/CategoryTheory/PathCategory/MorphismProperty.lean @@ -59,6 +59,7 @@ section variable {C : Type*} [Category* C] {V : Type u₁} [Quiver.{v₁} V] +set_option backward.isDefEq.respectTransparency.types false in /-- A natural transformation between `F G : Paths V ⥤ C` is defined by its components and its unary naturality squares. -/ @[simps] @@ -169,11 +170,13 @@ lemma paths_le_inverseImage (W : MorphismProperty C) [W.IsMultiplicative] : W.paths ≤ W.inverseImage (pathComposition C) := fun _ _ _ ↦ W.composePath_mem +set_option backward.isDefEq.respectTransparency.types false in instance (W : MorphismProperty C) : IsMultiplicative (W.paths.strictMap (pathComposition C)) where id_mem X := W.paths.map_mem_strictMap (pathComposition C) _ (W.paths.id_mem X) comp_mem := fun _ _ ⟨hp⟩ ⟨hq⟩ ↦ by simpa using! W.paths.map_mem_strictMap (pathComposition C) _ <| W.paths.comp_mem _ _ hp hq +set_option backward.isDefEq.respectTransparency.types false in lemma multiplicativeClosure_eq_strictMap_paths (W : MorphismProperty C) : W.multiplicativeClosure = W.paths.strictMap (pathComposition C) := by refine le_antisymm ?_ fun _ _ _ ⟨h⟩ ↦ ?_ diff --git a/Mathlib/CategoryTheory/Pi/Basic.lean b/Mathlib/CategoryTheory/Pi/Basic.lean index 36bd5d7834a9fd..daf4524812e220 100644 --- a/Mathlib/CategoryTheory/Pi/Basic.lean +++ b/Mathlib/CategoryTheory/Pi/Basic.lean @@ -21,7 +21,7 @@ We define the pointwise category structure on indexed families of objects in a c namespace CategoryTheory -open Functor +open CategoryTheory.Functor universe w₀ w₁ w₂ v₁ v₂ v₃ u₁ u₂ u₃ @@ -67,7 +67,7 @@ instance (f : J → I) : (j : J) → Category ((C ∘ f) j) := /-- Pull back an `I`-indexed family of objects to a `J`-indexed family, along a function `J → I`. -/ -@[simps] +@[simps, implicit_reducible] def comap (h : J → I) : (∀ i, C i) ⥤ (∀ j, C (h j)) where obj f i := f (h i) map α i := α (h i) @@ -239,6 +239,7 @@ variable {C} variable {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] variable {F G : ∀ i, C i ⥤ D i} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Assemble an `I`-indexed family of natural transformations into a single natural transformation. -/ @@ -264,6 +265,7 @@ variable {C} variable {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] variable {F G : ∀ i, C i ⥤ D i} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Assemble an `I`-indexed family of natural isomorphisms into a single natural isomorphism. -/ @@ -316,6 +318,7 @@ def Pi.eqToEquivalenceFunctorIso (f : J → I) {i' j' : J} (h : i' = j') : attribute [local simp] eqToHom_map +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Reindexing a family of categories gives equivalent `Pi` categories. -/ @[simps] @@ -334,6 +337,7 @@ noncomputable def Pi.equivalenceOfEquiv (e : J ≃ I) : Pi.evalCompEqToEquivalenceFunctor C (e.apply_symm_apply i) ≪≫ (leftUnitor _).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A product of categories indexed by `Option J` identifies to a binary product. -/ @[simps] @@ -354,6 +358,7 @@ namespace Equivalence variable {C} variable {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Assemble an `I`-indexed family of equivalences of categories into a single equivalence. -/ diff --git a/Mathlib/CategoryTheory/Pi/Monoidal.lean b/Mathlib/CategoryTheory/Pi/Monoidal.lean index c4430bd112df35..f36f35ef354a9f 100644 --- a/Mathlib/CategoryTheory/Pi/Monoidal.lean +++ b/Mathlib/CategoryTheory/Pi/Monoidal.lean @@ -174,6 +174,7 @@ instance (i : I) : (Pi.eval C i).Monoidal where set_option backward.defeqAttrib.useBackward true in instance [∀ i, BraidedCategory (C i)] (i : I) : (Pi.eval C i).Braided where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps] instance laxMonoidalPi' {D : Type*} [Category* D] [MonoidalCategory D] (F : ∀ i : I, D ⥤ C i) @@ -182,6 +183,7 @@ instance laxMonoidalPi' {D : Type*} [Category* D] [MonoidalCategory D] (F : ∀ ε := fun i ↦ Functor.LaxMonoidal.ε (F i) μ X Y := fun i ↦ Functor.LaxMonoidal.μ (F i) X Y +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps] instance opLaxMonoidalPi' {D : Type*} [Category* D] [MonoidalCategory D] @@ -193,6 +195,7 @@ instance opLaxMonoidalPi' {D : Type*} [Category* D] [MonoidalCategory D] oplax_left_unitality X := by ext; simp oplax_right_unitality X := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps!] instance monoidalPi' {D : Type*} [Category* D] [MonoidalCategory D] @@ -210,6 +213,7 @@ instance [∀ i, BraidedCategory (C i)] (F : ∀ i : I, D ⥤ C i) [∀ i, (F i).Braided] : (Functor.pi' F).Braided where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps] instance laxMonoidalPi {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] @@ -219,6 +223,7 @@ instance laxMonoidalPi {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] ε := fun i ↦ Functor.LaxMonoidal.ε (F i) μ X Y := fun i ↦ Functor.LaxMonoidal.μ (F i) (X i) (Y i) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps] instance opLaxMonoidalPi {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] @@ -230,6 +235,7 @@ instance opLaxMonoidalPi {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] oplax_left_unitality X := by ext; simp oplax_right_unitality X := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps!] instance monoidalPi {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] @@ -259,6 +265,7 @@ instance {D : Type*} [Category* D] [MonoidalCategory D] unit := by ext i; simpa using NatTrans.IsMonoidal.unit (τ := τ i) tensor X Y := by ext i; simpa using NatTrans.IsMonoidal.tensor _ _ (τ := τ i) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance {D : I → Type u₂} [∀ i, Category.{v₂} (D i)] [∀ i, MonoidalCategory (D i)] diff --git a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean index 63564f4d54522e..a799508ba79409 100644 --- a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean +++ b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean @@ -147,6 +147,7 @@ def isBilimitOfIsLimit {f : J → C} (t : Bicone f) (ht : IsLimit t.toCone) : t. cases j simp [sum_comp, t.ι_π, comp_dite] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- We can turn any limit cone over a pair into a bilimit bicone. -/ def biconeIsBilimitOfLimitConeOfIsLimit {f : J → C} {t : Cone (Discrete.functor f)} @@ -165,6 +166,7 @@ def isBilimitOfIsColimit {f : J → C} (t : Bicone f) (ht : IsColimit t.toCocone simp_rw [Bicone.toCocone_ι_app, comp_sum, ← Category.assoc, t.ι_π, dite_comp] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- We can turn any limit cone over a pair into a bilimit bicone. -/ def biconeIsBilimitOfColimitCoconeOfIsColimit {f : J → C} {t : Cocone (Discrete.functor f)} @@ -301,6 +303,7 @@ def biproduct.reindex {β γ : Type} [Finite β] (ε : β ≃ γ) simp [Preadditive.sum_comp, biproduct.lift_desc, biproduct.ι_π, comp_dite, Equiv.apply_eq_iff_eq_symm_apply, h] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- In a preadditive category, we can construct a binary biproduct for `X Y : C` from any binary bicone `b` satisfying `total : b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.X`. @@ -419,6 +422,7 @@ def isBinaryBilimitOfIsColimit {X Y : C} (t : BinaryBicone X Y) (ht : IsColimit isBinaryBilimitOfTotal _ <| by refine BinaryCofan.IsColimit.hom_ext ht ?_ ?_ <;> simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- We can turn any colimit cocone over a pair into a bilimit bicone. -/ def binaryBiconeIsBilimitOfColimitCoconeOfIsColimit {X Y : C} {t : Cocone (pair X Y)} @@ -874,6 +878,7 @@ section Finite variable {J : Type*} [Finite J] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) finite biproducts preserves finite products. -/ @@ -898,6 +903,7 @@ lemma preservesProductsOfShape_of_preservesBiproductsOfShape [PreservesBiproduct end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) finite products preserves finite biproducts. -/ @@ -947,6 +953,7 @@ lemma preservesBiproductsOfShape_of_preservesProductsOfShape PreservesBiproductsOfShape J F where preserves {_} := preservesBiproduct_of_preservesProduct F +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) finite biproducts preserves finite coproducts. -/ @@ -971,6 +978,7 @@ lemma preservesCoproductsOfShape_of_preservesBiproductsOfShape [PreservesBiprodu end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) finite coproducts preserves finite biproducts. -/ @@ -994,6 +1002,7 @@ lemma preservesBiproductsOfShape_of_preservesCoproductsOfShape end Finite +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) binary biproducts preserves binary products. -/ @@ -1018,6 +1027,7 @@ lemma preservesBinaryProducts_of_preservesBinaryBiproducts [PreservesBinaryBipro end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) binary products preserves binary biproducts. -/ @@ -1062,6 +1072,7 @@ lemma preservesBinaryBiproducts_of_preservesBinaryProducts [PreservesLimitsOfShape (Discrete WalkingPair) F] : PreservesBinaryBiproducts F where preserves {_} {_} := preservesBinaryBiproduct_of_preservesBinaryProduct F +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) binary biproducts preserves binary coproducts. -/ @@ -1088,6 +1099,7 @@ lemma preservesBinaryCoproducts_of_preservesBinaryBiproducts [PreservesBinaryBip end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories that preserves (zero morphisms and) binary coproducts preserves binary biproducts. -/ diff --git a/Mathlib/CategoryTheory/Preadditive/CommGrp_.lean b/Mathlib/CategoryTheory/Preadditive/CommGrp_.lean index 190a83e50c9b3c..2259a0a8b96c64 100644 --- a/Mathlib/CategoryTheory/Preadditive/CommGrp_.lean +++ b/Mathlib/CategoryTheory/Preadditive/CommGrp_.lean @@ -81,6 +81,7 @@ def commGrpEquivalenceAux : CommGrp.forget C ⋙ toCommGrp C ≅ · infer_instance · cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An additive category is equivalent to its category of commutative group objects. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean index b4447e823ae67e..0deeb6c92c94ed 100644 --- a/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean @@ -276,7 +276,6 @@ namespace Adjunction variable {D : Type*} [Category* D] {F : C ⥤ D} {G : D ⥤ C} -set_option backward.isDefEq.respectTransparency false in theorem map_injective (adj : F ⊣ G) [F.PreservesMonomorphisms] (I : D) (hI : Injective I) : Injective (G.obj I) := ⟨fun {X} {Y} f g => by @@ -286,7 +285,6 @@ theorem map_injective (adj : F ⊣ G) [F.PreservesMonomorphisms] (I : D) (hI : I rw [← unit_naturality_assoc, ← G.map_comp, h] simp⟩ -set_option backward.isDefEq.respectTransparency false in theorem injective_of_map_injective (adj : F ⊣ G) [G.Full] [G.Faithful] (I : D) (hI : Injective (G.obj I)) : Injective I := ⟨fun {X} {Y} f g => by diff --git a/Mathlib/CategoryTheory/Preadditive/Injective/Preserves.lean b/Mathlib/CategoryTheory/Preadditive/Injective/Preserves.lean index bdc4ebbddc8322..6204335698acea 100644 --- a/Mathlib/CategoryTheory/Preadditive/Injective/Preserves.lean +++ b/Mathlib/CategoryTheory/Preadditive/Injective/Preserves.lean @@ -56,7 +56,6 @@ instance (priority := low) Functor.preservesInjectiveObjects_of_isEquivalence {F preservesInjectiveObjects_of_adjunction_of_preservesMonomorphisms F.asEquivalence.symm.toAdjunction -set_option backward.isDefEq.respectTransparency false in theorem Functor.preservesMonomorphisms_of_adjunction_of_preservesInjectiveObjects [EnoughInjectives D] {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) [G.PreservesInjectiveObjects] : F.PreservesMonomorphisms where diff --git a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean index afead0faa8e030..a8a8a8320303ec 100644 --- a/Mathlib/CategoryTheory/Preadditive/LeftExact.lean +++ b/Mathlib/CategoryTheory/Preadditive/LeftExact.lean @@ -163,6 +163,7 @@ attribute [local instance] preservesBinaryCoproducts_of_preservesCokernels variable [HasBinaryBiproducts C] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor between preadditive categories preserves the coequalizer of two morphisms if it preserves all cokernels. -/ diff --git a/Mathlib/CategoryTheory/Preadditive/Mat.lean b/Mathlib/CategoryTheory/Preadditive/Mat.lean index f3e1f860fbef1d..c85d04a5409a1a 100644 --- a/Mathlib/CategoryTheory/Preadditive/Mat.lean +++ b/Mathlib/CategoryTheory/Preadditive/Mat.lean @@ -98,6 +98,7 @@ section attribute [local simp] Hom.id Hom.comp +set_option backward.isDefEq.respectTransparency.types false in instance : Category.{v₁} (Mat_ C) where Hom := Hom id := Hom.id @@ -280,6 +281,7 @@ end Functor namespace Mat_ +set_option backward.isDefEq.respectTransparency.types false in /-- The embedding of `C` into `Mat_ C` as one-by-one matrices. (We index the summands by `PUnit`.) -/ @[simps] @@ -355,6 +357,7 @@ def additiveObjIsoBiproduct (F : Mat_ C ⥤ D) [Functor.Additive F] (M : Mat_ C) F.obj M ≅ ⨁ fun i => F.obj ((embedding C).obj (M.X i)) := F.mapIso (isoBiproductEmbedding M) ≪≫ F.mapBiproduct _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma additiveObjIsoBiproduct_hom_π (F : Mat_ C ⥤ D) [Functor.Additive F] (M : Mat_ C) (i : M.ι) : @@ -421,6 +424,7 @@ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in instance lift_additive (F : C ⥤ D) [Functor.Additive F] : Functor.Additive (lift F) where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An additive functor `C ⥤ D` factors through its lift to `Mat_ C ⥤ D`. -/ @[simps!] @@ -430,8 +434,8 @@ def embeddingLiftIso (F : C ⥤ D) [Functor.Additive F] : embedding C ⋙ lift F { hom := biproduct.desc fun _ => 𝟙 (F.obj X) inv := biproduct.lift fun _ => 𝟙 (F.obj X) }) -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`. -/ def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L] @@ -512,6 +516,7 @@ instance (R : Type u) : CoeSort (Mat R) (Type u) := open Matrix +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] FintypeCat.fintype in open scoped Classical in instance (R : Type u) [Semiring R] : Category (Mat R) where @@ -547,11 +552,13 @@ theorem id_apply_self (M : Mat R) (i : M) : (𝟙 M : Matrix M M R) i i = 1 := b theorem id_apply_of_ne (M : Mat R) (i j : M) (h : i ≠ j) : (𝟙 M : Matrix M M R) i j = 0 := by simp [id_apply, h] +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] FintypeCat.fintype in theorem comp_def {M N K : Mat R} (f : M ⟶ N) (g : N ⟶ K) : f ≫ g = fun i k => ∑ j : N, f i j * g j k := rfl +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] FintypeCat.fintype in @[simp] theorem comp_apply {M N K : Mat R} (f : M ⟶ N) (g : N ⟶ K) (i k) : @@ -567,6 +574,7 @@ variable (R : Type) [Ring R] open Opposite +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/ @[simps] def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where @@ -591,6 +599,7 @@ instance : (equivalenceSingleObjInverse R).Faithful where instance : (equivalenceSingleObjInverse R).Full where map_surjective f := ⟨fun i j => MulOpposite.op (f i j), rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] FintypeCat.fintype in instance : (equivalenceSingleObjInverse R).EssSurj where mem_essImage X := diff --git a/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean index 99fbffc078481d..c849ffe3e685c9 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective/Basic.lean @@ -210,7 +210,6 @@ theorem map_projective (adj : F ⊣ G) [G.PreservesEpimorphisms] (P : C) (hP : P rw [Category.assoc, ← Adjunction.counit_naturality, ← Category.assoc, ← F.map_comp, hf'] simp -set_option backward.isDefEq.respectTransparency false in theorem projective_of_map_projective (adj : F ⊣ G) [F.Full] [F.Faithful] (P : C) (hP : Projective (F.obj P)) : Projective P where factors f g _ := by @@ -249,7 +248,6 @@ variable {D : Type u'} [Category.{v'} D] (F : C ≌ D) theorem map_projective_iff (P : C) : Projective (F.functor.obj P) ↔ Projective P := ⟨F.toAdjunction.projective_of_map_projective P, F.toAdjunction.map_projective P⟩ -set_option backward.isDefEq.respectTransparency false in /-- Given an equivalence of categories `F`, a projective presentation of `F(X)` induces a projective presentation of `X.` -/ def projectivePresentationOfMapProjectivePresentation (X : C) diff --git a/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean b/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean index 69d8b6ebb8671c..8bd387dfa40524 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean @@ -55,7 +55,6 @@ instance (priority := low) Functor.preservesProjectiveObjects_of_isEquivalence { [IsEquivalence F] : F.PreservesProjectiveObjects := preservesProjectiveObjects_of_adjunction_of_preservesEpimorphisms F.asEquivalence.toAdjunction -set_option backward.isDefEq.respectTransparency false in theorem Functor.preservesEpimorphisms_of_adjunction_of_preservesProjectiveObjects [EnoughProjectives C] {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) [F.PreservesProjectiveObjects] : G.PreservesEpimorphisms where diff --git a/Mathlib/CategoryTheory/Preadditive/Projective/Resolution.lean b/Mathlib/CategoryTheory/Preadditive/Projective/Resolution.lean index 20e1988d960d66..42041701fed348 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective/Resolution.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective/Resolution.lean @@ -103,6 +103,7 @@ theorem complex_d_succ_comp (n : ℕ) : noncomputable def cokernelCofork : CokernelCofork (P.complex.d 1 0) := CokernelCofork.ofπ _ P.complex_d_comp_π_f_zero +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Z` is the cokernel of `P.complex.X 1 ⟶ P.complex.X 0` when `P : ProjectiveResolution Z`. -/ noncomputable def isColimitCokernelCofork : IsColimit (P.cokernelCofork) := by @@ -167,7 +168,6 @@ open Limits variable {C : Type u} [Category* C] [HasZeroObject C] [Preadditive C] {D : Type u'} [Category.{v'} D] [HasZeroObject D] [Preadditive D] [CategoryWithHomology D] -set_option backward.isDefEq.respectTransparency false in /-- An additive functor `F` which preserves homology and sends projective objects to projective objects sends a projective resolution of `Z` to a projective resolution of `F.obj Z`. -/ @[simps complex π] diff --git a/Mathlib/CategoryTheory/Preadditive/Schur.lean b/Mathlib/CategoryTheory/Preadditive/Schur.lean index 99e8ea153c16f2..3a6560d8584eb1 100644 --- a/Mathlib/CategoryTheory/Preadditive/Schur.lean +++ b/Mathlib/CategoryTheory/Preadditive/Schur.lean @@ -136,7 +136,7 @@ theorem endomorphism_simple_eq_smul_id {X : C} [Simple X] [FiniteDimensional /-- Endomorphisms of a simple object form a field if they are finite dimensional. This can't be an instance as `𝕜` would be undetermined. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fieldEndOfFiniteDimensional (X : C) [Simple X] [I : FiniteDimensional 𝕜 (X ⟶ X)] : Field (End X) := by exact diff --git a/Mathlib/CategoryTheory/Preadditive/Transfer.lean b/Mathlib/CategoryTheory/Preadditive/Transfer.lean index e8431d4fcbd61a..54fccf66bc08c1 100644 --- a/Mathlib/CategoryTheory/Preadditive/Transfer.lean +++ b/Mathlib/CategoryTheory/Preadditive/Transfer.lean @@ -31,7 +31,7 @@ namespace Preadditive /-- If `D` is a preadditive category, any fully faithful functor `F : C ⥤ D` induces a preadditive structure on `C`. -/ -@[implicit_reducible] +@[instance_reducible] def ofFullyFaithful : Preadditive C where homGroup P Q := hF.homEquiv.addCommGroup add_comp P Q R f f' g := hF.map_injective (by simp [Equiv.add_def]) diff --git a/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean index 5eb4bc6ac67db5..2baa6b876e4e03 100644 --- a/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean @@ -76,6 +76,7 @@ def preadditiveCoyonedaObj (X : C) : C ⥤ ModuleCat.{v} (End X)ᵐᵒᵖ where map_add' := fun _ _ => add_comp _ _ _ _ _ _ map_smul' := fun _ _ => Category.assoc _ _ _ } +set_option backward.isDefEq.respectTransparency.types false in /-- The Yoneda embedding for preadditive categories sends an object `X` to the copresheaf sending an object `Y` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End X`-module structure, see `preadditiveCoyonedaObj`. @@ -98,6 +99,7 @@ instance additive_yonedaObj' (X : C) : Functor.Additive (preadditiveYoneda.obj X instance additive_coyonedaObj (X : C) : Functor.Additive (preadditiveCoyonedaObj X) where +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance additive_coyonedaObj' (X : Cᵒᵖ) : Functor.Additive (preadditiveCoyoneda.obj X) where @@ -111,6 +113,7 @@ theorem whiskering_preadditiveYoneda : yoneda := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Composing the preadditive yoneda embedding with the forgetful functor yields the regular Yoneda embedding. -/ @@ -128,6 +131,7 @@ instance full_preadditiveYoneda : (preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddComm Functor.Full.of_comp_faithful preadditiveYoneda ((whiskeringRight Cᵒᵖ AddCommGrpCat (Type v)).obj (forget AddCommGrpCat)) +set_option backward.isDefEq.respectTransparency.types false in instance full_preadditiveCoyoneda : (preadditiveCoyoneda : Cᵒᵖ ⥤ C ⥤ AddCommGrpCat).Full := let _ : Functor.Full (preadditiveCoyoneda ⋙ (whiskeringRight C AddCommGrpCat (Type v)).obj (forget AddCommGrpCat)) := @@ -157,6 +161,7 @@ def preadditiveYonedaMap (X : C) : end +set_option backward.isDefEq.respectTransparency.types false in /-- The preadditive coyoneda functor for the category `AddCommGrpCat` agrees with `AddCommGrpCat.coyoneda`. -/ def _root_.AddCommGrpCat.preadditiveCoyonedaIso : preadditiveCoyoneda ≅ AddCommGrpCat.coyoneda := diff --git a/Mathlib/CategoryTheory/Presentable/Adjunction.lean b/Mathlib/CategoryTheory/Presentable/Adjunction.lean index 3669dc677fcf2f..19947f141c87fa 100644 --- a/Mathlib/CategoryTheory/Presentable/Adjunction.lean +++ b/Mathlib/CategoryTheory/Presentable/Adjunction.lean @@ -45,7 +45,6 @@ lemma isCardinalPresentable_leftAdjoint_obj (X : C) [IsCardinalPresentable X κ] exact Functor.isCardinalAccessible_of_natIso (show G ⋙ _ ≅ _ from (Adjunction.compUliftCoyonedaIso.{0} adj).symm.app (op X)) κ -set_option backward.isDefEq.respectTransparency false in variable {κ} in lemma isCardinalFilteredGenerator {P : ObjectProperty C} (hP : P.IsCardinalFilteredGenerator κ) diff --git a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean index 47ac60b78f5665..4be69fc9b42ae8 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean @@ -284,6 +284,7 @@ instance (S : Subtype (J.PropSetWithTop κ')) : HasTerminal S := instance (S : Subtype (J.PropSetWithTop κ')) : IsCardinalFiltered S κ := isCardinalFiltered_of_hasTerminal _ _ +set_option backward.isDefEq.respectTransparency.types false in instance : IsCardinalFiltered (Subtype (J.PropSetWithTop κ')) κ' := isCardinalFiltered_preorder _ _ (fun K α hK ↦ by rw [← hasCardinalLT_iff_cardinal_mk_lt] at hK @@ -308,6 +309,7 @@ lemma propSetWithTop_pair (j : J.obj) : J.PropSetWithTop κ' {WithTop.some j, ⟨hasCardinalLT_of_finite _ _ (Cardinal.IsRegular.aleph0_le Fact.out), Set.mem_insert_of_mem _ (by simp)⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma exists_mem_propSetWithTop (a : J.withTop.obj) : ∃ S, J.PropSetWithTop κ' S ∧ a ∈ S := by induction a with @@ -320,6 +322,7 @@ colimit of its subsets that are of cardinality `< κ'` and contain `⊤`. -/ abbrev coconeWithTop : Cocone (functorOfPredicateSet (J.PropSetWithTop κ')) := coconeOfPredicateSet (PropSetWithTop J κ') +set_option backward.isDefEq.respectTransparency.types false in /-- If `J : CardinalDirectedPoset κ` and `κ'` is any regular cardinal, then `J.withTop` is the `κ'`-filtered colimit of its subsets that are of cardinality `< κ'` and contain `⊤`. -/ diff --git a/Mathlib/CategoryTheory/Presentable/Dense.lean b/Mathlib/CategoryTheory/Presentable/Dense.lean index b69f5f34a7eed0..b6164e9c28df67 100644 --- a/Mathlib/CategoryTheory/Presentable/Dense.lean +++ b/Mathlib/CategoryTheory/Presentable/Dense.lean @@ -55,6 +55,7 @@ instance final_toCostructuredArrow g₁.left.hom g₂.left.hom ((CostructuredArrow.w g₁).trans (CostructuredArrow.w g₂).symm) exact ⟨k, a, by cat_disch⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [IsCardinalAccessibleCategory C κ] : (isCardinalPresentable C κ).ι.IsDense where diff --git a/Mathlib/CategoryTheory/Presentable/IsCardinalFiltered.lean b/Mathlib/CategoryTheory/Presentable/IsCardinalFiltered.lean index 8be9d46f911933..3a10e3281f0c93 100644 --- a/Mathlib/CategoryTheory/Presentable/IsCardinalFiltered.lean +++ b/Mathlib/CategoryTheory/Presentable/IsCardinalFiltered.lean @@ -184,6 +184,7 @@ lemma isCardinalFiltered_preorder (J : Type w) [Preorder J] { app a := homOfLE (hj a) naturality _ _ _ := rfl }⟩ +set_option backward.isDefEq.respectTransparency.types false in instance (κ : Cardinal.{w}) [hκ : Fact κ.IsRegular] : IsCardinalFiltered κ.ord.ToType κ := isCardinalFiltered_preorder _ _ (fun ι f hs ↦ by @@ -196,6 +197,7 @@ instance (κ : Cardinal.{w}) [hκ : Fact κ.IsRegular] : open IsCardinalFiltered +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance isCardinalFiltered_under (J : Type u) [Category.{v} J] (κ : Cardinal.{w}) [Fact κ.IsRegular] @@ -217,6 +219,7 @@ instance isCardinalFiltered_under dsimp at this ⊢ simp only [reassoc_of% this, Category.comp_id] } }⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance isCardinalFiltered_prod (J₁ : Type u) (J₂ : Type u') [Category.{v} J₁] [Category.{v'} J₂] (κ : Cardinal.{w}) [Fact κ.IsRegular] @@ -233,6 +236,7 @@ instance isCardinalFiltered_prod (J₁ : Type u) (J₂ : Type u') · simpa using c₁.w f · simpa using c₂.w f }⟩ +set_option backward.isDefEq.respectTransparency.types false in instance isCardinalFiltered_pi {ι : Type u'} (J : ι → Type u) [∀ i, Category.{v} (J i)] (κ : Cardinal.{w}) [Fact κ.IsRegular] [∀ i, IsCardinalFiltered (J i) κ] : IsCardinalFiltered (∀ i, J i) κ where diff --git a/Mathlib/CategoryTheory/Presentable/Type.lean b/Mathlib/CategoryTheory/Presentable/Type.lean index e7b611774ca7f3..ed0a4b7f7a2fcd 100644 --- a/Mathlib/CategoryTheory/Presentable/Type.lean +++ b/Mathlib/CategoryTheory/Presentable/Type.lean @@ -29,7 +29,6 @@ namespace HasCardinalLT variable (X : Type u) (κ : Cardinal.{u}) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in variable {X κ} in lemma isCardinalPresentable (hX : HasCardinalLT X κ) [Fact κ.IsRegular] : IsCardinalPresentable X κ where @@ -99,6 +98,7 @@ def cocone : Cocone (Set.functor X κ) where pt := X ι.app _ := ↾(Subtype.val) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Any type `X` is the (filtered) colimit of its subsets of cardinality `< κ` when `κ` is an infinite cardinal. (This colimit is `κ`-filtered when `κ` is diff --git a/Mathlib/CategoryTheory/Products/Associator.lean b/Mathlib/CategoryTheory/Products/Associator.lean index 422d178b9af840..b164f5a1083691 100644 --- a/Mathlib/CategoryTheory/Products/Associator.lean +++ b/Mathlib/CategoryTheory/Products/Associator.lean @@ -19,7 +19,7 @@ open CategoryTheory namespace CategoryTheory.prod -open scoped Prod +open scoped CategoryTheory.Prod variable (C : Type u₁) [Category.{v₁} C] (D : Type u₂) [Category.{v₂} D] (E : Type u₃) [Category.{v₃} E] @@ -76,6 +76,9 @@ def functorProdToProdFunctorAssociator : (associativity _ _ _).functor := Iso.refl _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The equivalence swapping the second and third categories in `(A × C) × (D × E)`. This follows the definition of `MonoidalCategory.tensorμ`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Products/Basic.lean b/Mathlib/CategoryTheory/Products/Basic.lean index 9a7be595b0f794..67dcaa8d157946 100644 --- a/Mathlib/CategoryTheory/Products/Basic.lean +++ b/Mathlib/CategoryTheory/Products/Basic.lean @@ -31,7 +31,7 @@ and products of functors and natural transformations, written `F.prod G` and `α namespace CategoryTheory -open Functor +open CategoryTheory.Functor -- declare the `v`'s first; see `CategoryTheory.Category` for an explanation universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ @@ -71,7 +71,7 @@ lemma mkHom_eq {X₁ X₂ : C} {Y₁ Y₂ : D} (f f' : X₁ ⟶ X₂) (g g' : Y end Prod -open Prod +open CategoryTheory.Prod /-! Two rfl lemmas that cannot be generated by `@[simps]`. -/ @@ -99,7 +99,7 @@ theorem eqToHom_snd {X Y : C × D} (h : X = Y) : end -open Prod +open CategoryTheory.Prod section @@ -232,7 +232,7 @@ variable (C : Type u₁) [Category.{v₁} C] (D : Type u₂) [Category.{v₂} D] `(evaluation.obj X).obj F = F.obj X`, which is functorial in both `X` and `F`. -/ -@[simps] +@[simps, implicit_reducible] def evaluation : C ⥤ (C ⥤ D) ⥤ D where obj X := { obj := fun F => F.obj X @@ -264,7 +264,7 @@ variable {A : Type u₁} [Category.{v₁} A] {B : Type u₂} [Category.{v₂} B] namespace Functor /-- The Cartesian product of two functors. -/ -@[simps] +@[simps, implicit_reducible] def prod (F : A ⥤ B) (G : C ⥤ D) : A × C ⥤ B × D where obj X := (F.obj X.1, G.obj X.2) map f := F.map f.1 ×ₘ G.map f.2 @@ -330,6 +330,7 @@ def prodFunctor : (A ⥤ B) × (C ⥤ D) ⥤ A × C ⥤ B × D where namespace NatIso +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The Cartesian product of two natural isomorphisms. -/ @[simps] @@ -342,6 +343,7 @@ end NatIso namespace Equivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The Cartesian product of two equivalences of categories. -/ @[simps] @@ -411,6 +413,7 @@ def functorProdToProdFunctor : (A ⥤ B × C) ⥤ (A ⥤ B) × (A ⥤ C) where obj F := ⟨F ⋙ CategoryTheory.Prod.fst B C, F ⋙ CategoryTheory.Prod.snd B C⟩ map α := whiskerRight α _ ×ₘ whiskerRight α _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit isomorphism for `functorProdFunctorEquiv` -/ @[simps!] @@ -420,6 +423,7 @@ def functorProdFunctorEquivUnitIso : Functor.prod'CompFst F.fst F.snd |>.prod (Functor.prod'CompSnd F.fst F.snd) |>.trans (prod.etaIso F) |>.symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit isomorphism for `functorProdFunctorEquiv` -/ @[simps!] @@ -427,6 +431,7 @@ def functorProdFunctorEquivCounitIso : functorProdToProdFunctor A B C ⋙ prodFunctorToFunctorProd A B C ≅ 𝟭 _ := NatIso.ofComponents fun F => NatIso.ofComponents fun X => prod.etaIso (F.obj X) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/ @[simps] diff --git a/Mathlib/CategoryTheory/Products/Bifunctor.lean b/Mathlib/CategoryTheory/Products/Bifunctor.lean index 44f5adeeacdb93..b9d3a221c1e794 100644 --- a/Mathlib/CategoryTheory/Products/Bifunctor.lean +++ b/Mathlib/CategoryTheory/Products/Bifunctor.lean @@ -23,7 +23,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ variable {C : Type u₁} {D : Type u₂} {E : Type u₃} variable [Category.{v₁} C] [Category.{v₂} D] [Category.{v₃} E] -open scoped Prod +open scoped CategoryTheory.Prod @[simp] theorem map_id (F : C × D ⥤ E) (X : C) (Y : D) : diff --git a/Mathlib/CategoryTheory/Products/Unitor.lean b/Mathlib/CategoryTheory/Products/Unitor.lean index ee894ca8a7b9ee..85cbadc8a03771 100644 --- a/Mathlib/CategoryTheory/Products/Unitor.lean +++ b/Mathlib/CategoryTheory/Products/Unitor.lean @@ -20,7 +20,7 @@ open CategoryTheory namespace CategoryTheory.prod -open scoped Prod +open scoped CategoryTheory.Prod variable (C : Type u) [Category.{v} C] diff --git a/Mathlib/CategoryTheory/Quotient.lean b/Mathlib/CategoryTheory/Quotient.lean index 7ef7d22c73abf6..8f728aacf3478a 100644 --- a/Mathlib/CategoryTheory/Quotient.lean +++ b/Mathlib/CategoryTheory/Quotient.lean @@ -28,7 +28,7 @@ deriving Inhabited namespace CategoryTheory -open Functor +open CategoryTheory.Functor section @@ -147,6 +147,7 @@ theorem comp_mk {a b c : Quotient r} (f : a.as ⟶ b.as) (g : b.as ⟶ c.as) : comp r (Quot.mk _ f) (Quot.mk _ g) = Quot.mk _ (f ≫ g) := rfl +set_option backward.isDefEq.respectTransparency.types false in instance category : Category (Quotient r) where Hom := Hom r id a := Quot.mk _ (𝟙 a.as) @@ -177,6 +178,7 @@ theorem inv_mk {X Y : Quotient r} (f : X.as ⟶ Y.as) : Quotient.inv r (Quot.mk _ f) = Quot.mk _ (Groupoid.inv f) := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The quotient of a groupoid is a groupoid. -/ instance groupoid : Groupoid (Quotient r) where inv f := Quotient.inv r f @@ -186,10 +188,12 @@ instance groupoid : Groupoid (Quotient r) where end /-- The functor from a category to its quotient. -/ +@[implicit_reducible] def functor : C ⥤ Quotient r where obj a := { as := a } map f := Quot.mk _ f +set_option backward.isDefEq.respectTransparency.types false in instance full_functor : (functor r).Full where map_surjective f := ⟨Quot.out f, by simp [functor]⟩ @@ -223,6 +227,7 @@ theorem functor_homRel_eq_compClosure_eqvGen {X Y : C} (f g : X ⟶ Y) : (functor r).homRel f g ↔ Relation.EqvGen (@HomRel.CompClosure C _ r X Y) f g := Quot.eq +set_option backward.isDefEq.respectTransparency.types false in theorem compClosure.congruence : Congruence fun X Y => Relation.EqvGen (@HomRel.CompClosure C _ r X Y) := by convert! (inferInstance : Congruence (functor r).homRel) @@ -232,6 +237,7 @@ theorem compClosure.congruence : variable {D : Type _} [Category* D] (F : C ⥤ D) /-- The induced functor on the quotient category. -/ +@[implicit_reducible] def lift (H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂) : Quotient r ⥤ D where obj a := F.obj a.as map hf := diff --git a/Mathlib/CategoryTheory/Quotient/Linear.lean b/Mathlib/CategoryTheory/Quotient/Linear.lean index 25882519774864..fb01cde02e97d1 100644 --- a/Mathlib/CategoryTheory/Quotient/Linear.lean +++ b/Mathlib/CategoryTheory/Quotient/Linear.lean @@ -33,7 +33,7 @@ variable {R C : Type*} [Semiring R] [Category* C] [Preadditive C] [Linear R C] namespace Linear /-- The scalar multiplications on morphisms in `Quotient R`. -/ -@[implicit_reducible] +@[instance_reducible] def smul (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ f₂), r (a • f₁) (a • f₂)) (X Y : Quotient r) : SMul R (X ⟶ Y) where smul a := Quot.lift (fun g => Quot.mk _ (a • g)) (fun f₁ f₂ h₁₂ => by @@ -50,7 +50,7 @@ lemma smul_eq (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ /-- Auxiliary definition for `Quotient.Linear.module`. -/ -@[implicit_reducible] +@[instance_reducible] def module' (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ f₂), r (a • f₁) (a • f₂)) [Preadditive (Quotient r)] [(functor r).Additive] (X Y : C) : Module R ((functor r).obj X ⟶ (functor r).obj Y) := @@ -80,7 +80,7 @@ def module' (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ f rw [add_smul, Functor.map_add] } /-- Auxiliary definition for `Quotient.linear`. -/ -@[implicit_reducible] +@[instance_reducible] def module (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ f₂), r (a • f₁) (a • f₂)) [Preadditive (Quotient r)] [(functor r).Additive] (X Y : Quotient r) : Module R (X ⟶ Y) := module' r hr X.as Y.as @@ -94,7 +94,7 @@ set_option backward.isDefEq.respectTransparency false in such that `functor r : C ⥤ Quotient r` is additive, and that `C` has an `R`-linear category structure compatible with `r`, this is the induced `R`-linear category structure on `Quotient r`. -/ -@[implicit_reducible] +@[instance_reducible] def linear (hr : ∀ (a : R) ⦃X Y : C⦄ (f₁ f₂ : X ⟶ Y) (_ : r f₁ f₂), r (a • f₁) (a • f₂)) [Preadditive (Quotient r)] [(functor r).Additive] : Linear R (Quotient r) := by letI := Linear.module r hr diff --git a/Mathlib/CategoryTheory/Quotient/Preadditive.lean b/Mathlib/CategoryTheory/Quotient/Preadditive.lean index 633b61c185ff24..2114c2bd04d4d7 100644 --- a/Mathlib/CategoryTheory/Quotient/Preadditive.lean +++ b/Mathlib/CategoryTheory/Quotient/Preadditive.lean @@ -57,7 +57,7 @@ end Preadditive /-- The preadditive structure on the category `Quotient r` when `r` is compatible with the addition. -/ -@[implicit_reducible] +@[instance_reducible] def preadditive (hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y) (_ : r f₁ f₂) (_ : r g₁ g₂), r (f₁ + g₁) (f₂ + g₂)) : Preadditive (Quotient r) where diff --git a/Mathlib/CategoryTheory/Retract.lean b/Mathlib/CategoryTheory/Retract.lean index d3cba593ccdf19..2a5352165d44f8 100644 --- a/Mathlib/CategoryTheory/Retract.lean +++ b/Mathlib/CategoryTheory/Retract.lean @@ -118,9 +118,15 @@ set_option backward.isDefEq.respectTransparency false in -- This is needed for ` @[to_dual none, reassoc] lemma i_w : h.i.left ≫ g = f ≫ h.i.right := h.i.w +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[to_dual none, reassoc] lemma r_w : h.r.left ≫ f = g ≫ h.r.right := h.r.w +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- The top of a retract diagram of morphisms determines a retract of objects. -/ @[to_dual (attr := simps!) diff --git a/Mathlib/CategoryTheory/Shift/Adjunction.lean b/Mathlib/CategoryTheory/Shift/Adjunction.lean index ba1a8caa4a0e1b..1628ddc03a929e 100644 --- a/Mathlib/CategoryTheory/Shift/Adjunction.lean +++ b/Mathlib/CategoryTheory/Shift/Adjunction.lean @@ -83,7 +83,6 @@ abbrev CompatibilityCounit := ∀ (Y : D), adj.counit.app (Y⟦a⟧) = F.map (e₂.hom.app Y) ≫ e₁.hom.app _ ≫ (adj.counit.app Y)⟦a⟧' set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given an adjunction `adj : F ⊣ G`, `a` in `A` and commutation isomorphisms `e₁ : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a` and `e₂ : shiftFunctor D a ⋙ G ≅ G ⋙ shiftFunctor C a`, compatibility of `e₁` and `e₂` with the @@ -106,7 +105,6 @@ lemma compatibilityCounit_of_compatibilityUnit (h : CompatibilityUnit adj e₁ e Iso.hom_inv_id_app, Functor.comp_obj] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given an adjunction `adj : F ⊣ G`, `a` in `A` and commutation isomorphisms `e₁ : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a` and `e₂ : shiftFunctor D a ⋙ G ≅ G ⋙ shiftFunctor C a`, if `e₁` and `e₂` are compatible with the @@ -123,7 +121,6 @@ lemma compatibilityUnit_right (h : CompatibilityUnit adj e₁ e₂) (Y : D) : ← (shiftFunctor C a).map_comp, right_triangle_components, Functor.map_id] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given an adjunction `adj : F ⊣ G`, `a` in `A` and commutation isomorphisms `e₁ : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a` and `e₂ : shiftFunctor D a ⋙ G ≅ G ⋙ shiftFunctor C a`, if `e₁` and `e₂` are compatible with the @@ -162,7 +159,6 @@ lemma compatibilityUnit_unique_left (h : CompatibilityUnit adj e₁ e₂) compatibilityCounit_left adj e₁' e₂ (compatibilityCounit_of_compatibilityUnit adj _ _ h')] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The isomorphisms `Functor.CommShift.isoZero F` and `Functor.CommShift.isoZero G` are compatible with the unit of an adjunction `F ⊣ G`. @@ -176,7 +172,6 @@ lemma compatibilityUnit_isoZero : CompatibilityUnit adj (Functor.CommShift.isoZe Functor.id_obj, Functor.map_id, id_comp, NatTrans.naturality, Functor.id_map, assoc, comp_id] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given an adjunction `adj : F ⊣ G`, `a, b` in `A` and commutation isomorphisms between shifts by `a` (resp. `b`) and `F` and `G`, if these commutation isomorphisms are compatible with the unit of `adj`, then so are the commutation isomorphisms between shifts @@ -224,7 +219,6 @@ lemma unit_app_commShiftIso_hom_app [adj.CommShift A] (a : A) (X : C) : simpa using (NatTrans.shift_app_comm adj.unit a X).symm set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma unit_app_shift_commShiftIso_inv_app [adj.CommShift A] (a : A) (X : C) : (adj.unit.app X)⟦a⟧' ≫ ((F ⋙ G).commShiftIso a).inv.app X = adj.unit.app (X⟦a⟧) := by @@ -236,7 +230,6 @@ lemma commShiftIso_hom_app_counit_app_shift [adj.CommShift A] (a : A) (Y : D) : ((G ⋙ F).commShiftIso a).hom.app Y ≫ (adj.counit.app Y)⟦a⟧' = adj.counit.app (Y⟦a⟧) := by simpa using (NatTrans.shift_app_comm adj.counit a Y) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma commShiftIso_inv_app_counit_app [adj.CommShift A] (a : A) (Y : D) : ((G ⋙ F).commShiftIso a).inv.app Y ≫ adj.counit.app (Y⟦a⟧) = (adj.counit.app Y)⟦a⟧' := by @@ -293,7 +286,6 @@ lemma shift_unit_app [adj.CommShift A] (a : A) (X : C) : simpa [Functor.commShiftIso_comp_hom_app] using NatTrans.shift_app_comm adj.unit a X set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shift_counit_app [adj.CommShift A] (a : A) (Y : D) : (adj.counit.app Y)⟦a⟧' = @@ -342,7 +334,6 @@ lemma iso_hom_app (X : D) : simp [iso, iso', shiftEquiv'] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma iso_inv_app (Y : D) : (iso adj a).inv.app Y = @@ -365,7 +356,6 @@ lemma iso_inv_app (Y : D) : simp only [Functor.comp_obj, Functor.map_id, id_comp, assoc] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The commutation isomorphisms of `Adjunction.RightAdjointCommShift.iso` are compatible with the unit of the adjunction. @@ -394,7 +384,7 @@ open RightAdjointCommShift in Given an adjunction `F ⊣ G` and a `CommShift` structure on `F`, this constructs the unique compatible `CommShift` structure on `G`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] noncomputable def rightAdjointCommShift [F.CommShift A] : G.CommShift A where commShiftIso a := iso adj a commShiftIso_zero := by @@ -459,7 +449,6 @@ lemma iso_inv_app (Y : C) : simp [iso, iso', shiftEquiv'] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The commutation isomorphisms of `Adjunction.LeftAdjointCommShift.iso` are compatible with the unit of the adjunction. @@ -483,7 +472,7 @@ open LeftAdjointCommShift in Given an adjunction `F ⊣ G` and a `CommShift` structure on `G`, this constructs the unique compatible `CommShift` structure on `F`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] noncomputable def leftAdjointCommShift [G.CommShift A] : F.CommShift A where commShiftIso a := iso adj a commShiftIso_zero := by @@ -613,7 +602,7 @@ variable (A : Type*) [AddGroup A] [HasShift C A] [HasShift D A] If `E : C ≌ D` is an equivalence and we have a `CommShift` structure on `E.functor`, this constructs the unique compatible `CommShift` structure on `E.inverse`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def commShiftInverse [E.functor.CommShift A] : E.inverse.CommShift A := E.toAdjunction.rightAdjointCommShift A @@ -627,7 +616,7 @@ lemma commShift_of_functor [E.functor.CommShift A] : If `E : C ≌ D` is an equivalence and we have a `CommShift` structure on `E.inverse`, this constructs the unique compatible `CommShift` structure on `E.functor`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def commShiftFunctor [E.inverse.CommShift A] : E.functor.CommShift A := E.symm.toAdjunction.rightAdjointCommShift A diff --git a/Mathlib/CategoryTheory/Shift/Basic.lean b/Mathlib/CategoryTheory/Shift/Basic.lean index 9b80634563f384..d4706c712e0393 100644 --- a/Mathlib/CategoryTheory/Shift/Basic.lean +++ b/Mathlib/CategoryTheory/Shift/Basic.lean @@ -43,7 +43,7 @@ which are stated in lemmas like `shiftFunctorAdd'_assoc`, `shiftFunctorAdd'_zero namespace CategoryTheory -open Functor +open CategoryTheory.Functor noncomputable section @@ -93,7 +93,6 @@ variable {C A} attribute [reassoc] assoc_hom_app -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma assoc_inv_app (h : ShiftMkCore C A) (m₁ m₂ m₃ : A) (X : C) : (h.F m₃).map ((h.add m₁ m₂).inv.app X) ≫ (h.add (m₁ + m₂) m₃).inv.app X = @@ -105,7 +104,6 @@ lemma assoc_inv_app (h : ShiftMkCore C A) (m₁ m₂ m₃ : A) (X : C) : Category.id_comp, Iso.inv_hom_id_app_assoc, Iso.inv_hom_id_app] rfl -set_option backward.isDefEq.respectTransparency false in lemma zero_add_inv_app (h : ShiftMkCore C A) (n : A) (X : C) : (h.add 0 n).inv.app X = (h.F n).map (h.zero.hom.app X) ≫ eqToHom (by dsimp; rw [zero_add]) := by @@ -113,7 +111,6 @@ lemma zero_add_inv_app (h : ShiftMkCore C A) (n : A) (X : C) : Category.assoc, ← Functor.map_comp_assoc, Iso.inv_hom_id_app, Functor.map_id, Category.id_comp, eqToHom_trans, eqToHom_refl] -set_option backward.isDefEq.respectTransparency false in lemma add_zero_inv_app (h : ShiftMkCore C A) (n : A) (X : C) : (h.add n 0).inv.app X = h.zero.hom.app ((h.F n).obj X) ≫ eqToHom (by dsimp; rw [add_zero]) := by @@ -126,7 +123,6 @@ section attribute [local simp] eqToHom_map -set_option backward.isDefEq.respectTransparency false in instance (h : ShiftMkCore C A) : (Discrete.functor h.F).Monoidal := Functor.CoreMonoidal.toMonoidal { εIso := h.zero.symm @@ -153,7 +149,7 @@ instance (h : ShiftMkCore C A) : (Discrete.functor h.F).Monoidal := simp [h.add_zero_inv_app] } /-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/ -@[implicit_reducible] +@[instance_reducible] def hasShiftMk (h : ShiftMkCore C A) : HasShift C A where shift := Discrete.functor h.F @@ -163,6 +159,7 @@ section variable [HasShift C A] /-- The monoidal functor from `A` to `C ⥤ C` given a `HasShift` instance. -/ +@[implicit_reducible] def shiftMonoidalFunctor : Discrete A ⥤ C ⥤ C := HasShift.shift @@ -173,6 +170,7 @@ variable {A} open Functor.Monoidal /-- The shift autoequivalence, moving objects and morphisms 'up'. -/ +@[implicit_reducible] def shiftFunctor (i : A) : C ⥤ C := (shiftMonoidalFunctor C A).obj ⟨i⟩ @@ -228,7 +226,6 @@ variable (C) variable [HasShift C A] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorAdd'_zero_add (a : A) : shiftFunctorAdd' C 0 a a (zero_add a) = (leftUnitor _).symm ≪≫ isoWhiskerRight (shiftFunctorZero C A).symm (shiftFunctor C a) := by @@ -238,6 +235,7 @@ lemma shiftFunctorAdd'_zero_add (a : A) : eqToHom_map, Category.id_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma shiftFunctorAdd'_add_zero (a : A) : shiftFunctorAdd' C a 0 a (add_zero a) = (rightUnitor _).symm ≪≫ @@ -249,7 +247,6 @@ lemma shiftFunctorAdd'_add_zero (a : A) : rfl set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorAdd'_assoc (a₁ a₂ a₃ a₁₂ a₂₃ a₁₂₃ : A) (h₁₂ : a₁ + a₂ = a₁₂) (h₂₃ : a₂ + a₃ = a₂₃) (h₁₂₃ : a₁ + a₂ + a₃ = a₁₂₃) : shiftFunctorAdd' C a₁₂ a₃ a₁₂₃ (by rw [← h₁₂, h₁₂₃]) ≪≫ @@ -286,7 +283,6 @@ lemma shiftFunctorAdd'_zero_add_hom_app (a : A) (X : C) : ((shiftFunctorZero C A).inv.app X)⟦a⟧' := by simpa using NatTrans.congr_app (congr_arg Iso.hom (shiftFunctorAdd'_zero_add C a)) X -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorAdd_zero_add_hom_app (a : A) (X : C) : (shiftFunctorAdd C 0 a).hom.app X = eqToHom (by dsimp; rw [zero_add]) ≫ ((shiftFunctorZero C A).inv.app X)⟦a⟧' := by @@ -298,7 +294,6 @@ lemma shiftFunctorAdd'_zero_add_inv_app (a : A) (X : C) : ((shiftFunctorZero C A).hom.app X)⟦a⟧' := by simpa using NatTrans.congr_app (congr_arg Iso.inv (shiftFunctorAdd'_zero_add C a)) X -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorAdd_zero_add_inv_app (a : A) (X : C) : (shiftFunctorAdd C 0 a).inv.app X = ((shiftFunctorZero C A).hom.app X)⟦a⟧' ≫ eqToHom (by dsimp; rw [zero_add]) := by simp [← shiftFunctorAdd'_zero_add_inv_app, shiftFunctorAdd'] @@ -379,7 +374,6 @@ variable [AddMonoid A] [HasShift C A] (X Y : C) (f : X ⟶ Y) abbrev shiftAdd (i j : A) : X⟦i + j⟧ ≅ X⟦i⟧⟦j⟧ := (shiftFunctorAdd C i j).app _ -set_option backward.isDefEq.respectTransparency false in theorem shift_shift' (i j : A) : f⟦i⟧'⟦j⟧' = (shiftAdd X i j).inv ≫ f⟦i + j⟧' ≫ (shiftAdd Y i j).hom := by simp @@ -410,7 +404,6 @@ variable (C) variable [AddGroup A] [HasShift C A] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Shifting by `i` and shifting by `j` forms an equivalence when `i + j = 0`. -/ @[simps] def shiftEquiv' (i j : A) (h : i + j = 0) : C ≌ C where @@ -477,7 +470,6 @@ theorem shift_equiv_triangle (n : A) (X : C) : section set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem shift_shiftFunctorCompIsoId_hom_app (n m : A) (h : n + m = 0) (X : C) : ((shiftFunctorCompIsoId C n m h).hom.app X)⟦n⟧' = (shiftFunctorCompIsoId C m n @@ -488,7 +480,6 @@ theorem shift_shiftFunctorCompIsoId_hom_app (n m : A) (h : n + m = 0) (X : C) : using shiftFunctorAdd'_assoc_inv_app n m n 0 0 n h (by rw [← neg_eq_of_add_eq_zero_left h, add_neg_cancel]) (by rw [h, zero_add]) X -set_option backward.isDefEq.respectTransparency false in theorem shift_shiftFunctorCompIsoId_inv_app (n m : A) (h : n + m = 0) (X : C) : ((shiftFunctorCompIsoId C n m h).inv.app X)⟦n⟧' = ((shiftFunctorCompIsoId C m n @@ -544,7 +535,6 @@ variable (m n p m' n' p' : A) (hm : m' + m = 0) (hn : n' + n = 0) (hp : p' + p = (h : m + n = p) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorCompIsoId_add'_inv_app : (shiftFunctorCompIsoId C p' p hp).inv.app X = (shiftFunctorCompIsoId C n' n hn).inv.app X ≫ @@ -570,7 +560,6 @@ lemma shiftFunctorCompIsoId_add'_inv_app : Functor.map_id, Category.id_comp, Iso.hom_inv_id_app] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorCompIsoId_add'_hom_app : (shiftFunctorCompIsoId C p' p hp).hom.app X = ((shiftFunctorAdd' C n' m' p' @@ -643,7 +632,6 @@ theorem shiftComm_symm (i j : A) : (shiftComm X i j).symm = shiftComm X j i := b variable {X Y} set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- When shifts are indexed by an additive commutative monoid, then shifts commute. -/ theorem shiftComm' (i j : A) : f⟦i⟧'⟦j⟧' = (shiftComm _ _ _).hom ≫ f⟦j⟧'⟦i⟧' ≫ (shiftComm _ _ _).hom := by @@ -657,7 +645,6 @@ theorem shiftComm_hom_comp (i j : A) : rw [shiftComm', ← shiftComm_symm, Iso.symm_hom, Iso.inv_hom_id_assoc] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorZero_hom_app_shift (n : A) : (shiftFunctorZero C A).hom.app (X⟦n⟧) = (shiftFunctorComm C n 0).hom.app X ≫ ((shiftFunctorZero C A).hom.app X)⟦n⟧' := by @@ -665,7 +652,6 @@ lemma shiftFunctorZero_hom_app_shift (n : A) : dsimp rw [Category.assoc, Iso.hom_inv_id_app, Category.comp_id, shiftFunctorAdd'_add_zero_inv_app] -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorZero_inv_app_shift (n : A) : (shiftFunctorZero C A).inv.app (X⟦n⟧) = ((shiftFunctorZero C A).inv.app X)⟦n⟧' ≫ (shiftFunctorComm C n 0).inv.app X := by @@ -676,7 +662,6 @@ lemma shiftFunctorZero_inv_app_shift (n : A) : rw [Functor.map_id] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma shiftFunctorComm_zero_hom_app (a : A) : (shiftFunctorComm C a 0).hom.app X = (shiftFunctorZero C A).hom.app (X⟦a⟧) ≫ ((shiftFunctorZero C A).inv.app X)⟦a⟧' := by @@ -684,7 +669,6 @@ lemma shiftFunctorComm_zero_hom_app (a : A) : Iso.hom_inv_id_app, Functor.map_id, Functor.comp_obj, Category.comp_id] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shiftFunctorComm_hom_app_comp_shift_shiftFunctorAdd_hom_app (m₁ m₂ m₃ : A) (X : C) : (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫ @@ -710,7 +694,6 @@ lemma shiftFunctorComm_hom_app_comp_shift_shiftFunctorAdd_hom_app (m₁ m₂ m shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ (m₁ + m₂) (m₂ + m₃) (m₁ + (m₂ + m₃)) rfl rfl (add_assoc _ _ _) X] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shiftFunctorComm_hom_app_of_add_eq_zero (m n : A) (hmn : m + n = 0) (X : C) : (shiftFunctorComm C m n).hom.app X = @@ -718,7 +701,6 @@ lemma shiftFunctorComm_hom_app_of_add_eq_zero (m n : A) (hmn : m + n = 0) (X : C (shiftFunctorCompIsoId C n m (by rw [add_comm, hmn])).inv.app X := by simp [shiftFunctorCompIsoId, shiftFunctorComm_eq C m n 0 hmn] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shiftFunctorComm_inv_app_of_add_eq_zero (m n : A) (hmn : m + n = 0) (X : C) : (shiftFunctorComm C m n).inv.app X = @@ -741,6 +723,7 @@ def zero : s 0 ≅ 𝟭 C := (hF.whiskeringRight C).preimageIso ((i 0) ≪≫ isoWhiskerLeft F (shiftFunctorZero D A) ≪≫ rightUnitor _ ≪≫ (leftUnitor _).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma map_zero_hom_app (X : C) : @@ -748,6 +731,7 @@ lemma map_zero_hom_app (X : C) : (i 0).hom.app X ≫ (shiftFunctorZero D A).hom.app (F.obj X) := by simp [zero] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma map_zero_inv_app (X : C) : @@ -762,6 +746,7 @@ def add (a b : A) : s (a + b) ≅ s a ⋙ s b := associator _ _ _ ≪≫ (isoWhiskerLeft _ (i b).symm) ≪≫ (associator _ _ _).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma map_add_hom_app (a b : A) (X : C) : @@ -771,6 +756,7 @@ lemma map_add_hom_app (a b : A) (X : C) : dsimp [add] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma map_add_inv_app (a b : A) (X : C) : @@ -783,11 +769,10 @@ lemma map_add_inv_app (a b : A) (X : C) : end hasShift set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in open hasShift in /-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D` with shift functors on `D`, we can promote that family to shift functors on `C`. -/ -@[implicit_reducible] +@[instance_reducible] def hasShift : HasShift C A := hasShiftMk C A diff --git a/Mathlib/CategoryTheory/Shift/CommShift.lean b/Mathlib/CategoryTheory/Shift/CommShift.lean index c36d2531705d21..9c27f57edb3039 100644 --- a/Mathlib/CategoryTheory/Shift/CommShift.lean +++ b/Mathlib/CategoryTheory/Shift/CommShift.lean @@ -87,7 +87,6 @@ noncomputable def isoAdd {a b : A} shiftFunctor C (a + b) ⋙ F ≅ F ⋙ shiftFunctor D (a + b) := CommShift.isoAdd' rfl e₁ e₂ -set_option backward.isDefEq.respectTransparency false in @[simp] lemma isoAdd_hom_app {a b : A} (e₁ : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) @@ -97,7 +96,6 @@ lemma isoAdd_hom_app {a b : A} (shiftFunctor D b).map (e₁.hom.app X) ≫ (shiftFunctorAdd D a b).inv.app (F.obj X) := by simp only [isoAdd, isoAdd'_hom_app, shiftFunctorAdd'_eq_shiftFunctorAdd] -set_option backward.isDefEq.respectTransparency false in @[simp] lemma isoAdd_inv_app {a b : A} (e₁ : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) @@ -107,7 +105,6 @@ lemma isoAdd_inv_app {a b : A} F.map ((shiftFunctorAdd C a b).inv.app X) := by simp only [isoAdd, isoAdd'_inv_app, shiftFunctorAdd'_eq_shiftFunctorAdd] -set_option backward.isDefEq.respectTransparency false in lemma isoAdd'_isoZero {a : A} (e : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) : isoAdd' (add_zero a) e (isoZero F A) = e := by @@ -115,7 +112,6 @@ lemma isoAdd'_isoZero {a : A} simp [shiftFunctorAdd'_add_zero_hom_app, ← Functor.map_comp_assoc, shiftFunctorAdd'_add_zero_inv_app] -set_option backward.isDefEq.respectTransparency false in lemma isoZero_isoAdd'_ {a : A} (e : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) : isoAdd' (zero_add a) (isoZero F A) e = e := by @@ -126,7 +122,6 @@ lemma isoZero_isoAdd'_ {a : A} shiftFunctorAdd'_zero_add_inv_app, ← map_comp, reassoc_of% this] -set_option backward.isDefEq.respectTransparency false in lemma isoAdd'_assoc {a b c ab bc abc : A} (ea : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) (eb : shiftFunctor C b ⋙ F ≅ F ⋙ shiftFunctor D b) @@ -196,13 +191,11 @@ end namespace CommShift -set_option backward.isDefEq.respectTransparency false in variable (C) in @[simps! -isSimp commShiftIso_hom_app commShiftIso_inv_app] instance id : CommShift (𝟭 C) A where commShiftIso := fun _ => rightUnitor _ ≪≫ (leftUnitor _).symm -set_option backward.isDefEq.respectTransparency false in @[simps! -isSimp commShiftIso_hom_app commShiftIso_inv_app] instance comp [F.CommShift A] [G.CommShift A] : (F ⋙ G).CommShift A where commShiftIso a := (Functor.associator _ _ _).symm ≪≫ isoWhiskerRight (F.commShiftIso a) _ ≪≫ @@ -232,7 +225,6 @@ attribute [simp] commShiftIso_id_hom_app commShiftIso_id_inv_app variable {B} -set_option backward.isDefEq.respectTransparency false in lemma map_shiftFunctorComm_hom_app [F.CommShift B] (X : C) (a b : B) : F.map ((shiftFunctorComm C a b).hom.app X) = (F.commShiftIso b).hom.app (X⟦a⟧) ≫ ((F.commShiftIso a).hom.app X)⟦b⟧' ≫ (shiftFunctorComm D a b).hom.app (F.obj X) ≫ @@ -252,7 +244,6 @@ lemma map_shiftFunctorComm_hom_app [F.CommShift B] (X : C) (a b : B) : ← Functor.map_comp_assoc, Iso.hom_inv_id_app, Functor.map_id, Category.id_comp, comp_obj, Category.comp_id] -set_option backward.isDefEq.respectTransparency false in @[simp, reassoc] lemma map_shiftFunctorCompIsoId_hom_app [F.CommShift A] (X : C) (a b : A) (h : a + b = 0) : F.map ((shiftFunctorCompIsoId C a b h).hom.app X) = @@ -266,7 +257,6 @@ lemma map_shiftFunctorCompIsoId_hom_app [F.CommShift A] (X : C) (a b : A) (h : a simp only [Iso.inv_hom_id_app, id_obj, Category.comp_id, ← F.map_comp_assoc, Iso.hom_inv_id_app, F.map_id, Category.id_comp] -set_option backward.isDefEq.respectTransparency false in @[simp, reassoc] lemma map_shiftFunctorCompIsoId_inv_app [F.CommShift A] (X : C) (a b : A) (h : a + b = 0) : F.map ((shiftFunctorCompIsoId C a b h).inv.app X) = @@ -313,14 +303,12 @@ lemma shift_app_comm (X : C) : τ.app (X⟦a⟧) ≫ (F₂.commShiftIso a).hom.app X := congr_app hτ.shift_comm X -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shift_app (X : C) : (τ.app X)⟦a⟧' = (F₁.commShiftIso a).inv.app X ≫ τ.app (X⟦a⟧) ≫ (F₂.commShiftIso a).hom.app X := by rw [← hτ.shift_app_comm, Iso.inv_hom_id_app_assoc] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma app_shift (X : C) : τ.app (X⟦a⟧) = (F₁.commShiftIso a).hom.app X ≫ (τ.app X)⟦a⟧' ≫ @@ -331,7 +319,6 @@ end variable {τ} -set_option backward.isDefEq.respectTransparency false in lemma zero : CommShiftCore τ (0 : A) where shift_comm := by ext X @@ -339,7 +326,6 @@ lemma zero : CommShiftCore τ (0 : A) where variable {A} -set_option backward.isDefEq.respectTransparency false in lemma add {a b : A} (ha : CommShiftCore τ a) (hb : CommShiftCore τ b) : CommShiftCore τ (a + b) where shift_comm := by @@ -384,14 +370,12 @@ lemma shift_app_comm (a : A) (X : C) : τ.app (X⟦a⟧) ≫ (F₂.commShiftIso a).hom.app X := congr_app (shift_comm τ a) X -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shift_app (a : A) (X : C) : (τ.app X)⟦a⟧' = (F₁.commShiftIso a).inv.app X ≫ τ.app (X⟦a⟧) ≫ (F₂.commShiftIso a).hom.app X := by rw [← shift_app_comm, Iso.inv_hom_id_app_assoc] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma app_shift (a : A) (X : C) : τ.app (X⟦a⟧) = (F₁.commShiftIso a).hom.app X ≫ (τ.app X)⟦a⟧' ≫ @@ -424,11 +408,9 @@ instance id : NatTrans.CommShift (𝟙 F₁) A where attribute [local simp] Functor.commShiftIso_comp_hom_app shift_app_comm shift_app_comm_assoc -set_option backward.isDefEq.respectTransparency false in instance comp [NatTrans.CommShift τ A] [NatTrans.CommShift τ' A] : NatTrans.CommShift (τ ≫ τ') A where -set_option backward.isDefEq.respectTransparency false in instance whiskerRight [NatTrans.CommShift τ A] : NatTrans.CommShift (Functor.whiskerRight τ G) A := ⟨fun a => by ext X @@ -437,7 +419,6 @@ instance whiskerRight [NatTrans.CommShift τ A] : Functor.associator_inv_app, comp_id, id_comp, assoc, ← Functor.commShiftIso_hom_naturality, ← G.map_comp_assoc, shift_app_comm, Functor.whiskerLeft_app]⟩ -set_option backward.isDefEq.respectTransparency false in instance whiskerLeft [NatTrans.CommShift τ'' A] : NatTrans.CommShift (Functor.whiskerLeft F₁ τ'') A where @@ -460,10 +441,9 @@ variable {C D E : Type*} [Category* C] [Category* D] (A : Type*) [AddMonoid A] [HasShift C A] [HasShift D A] [F.CommShift A] -set_option backward.isDefEq.respectTransparency false in /-- If `e : F ≅ G` is an isomorphism of functors and if `F` commutes with the shift, then `G` also commutes with the shift. -/ -@[simps! -isSimp commShiftIso_hom_app commShiftIso_inv_app, implicit_reducible] +@[simps! -isSimp commShiftIso_hom_app commShiftIso_inv_app, instance_reducible] def ofIso : G.CommShift A where commShiftIso a := isoWhiskerLeft _ e.symm ≪≫ F.commShiftIso a ≪≫ isoWhiskerRight e _ commShiftIso_zero := by @@ -504,7 +484,7 @@ set_option backward.isDefEq.respectTransparency false in /-- If `F : C ⥤ D` is a fully faithful functor which is used to construct a shift by `A` on `C` from a shift on `D`, then the functor `F` itself commutes with the shift by `A`. -/ -@[implicit_reducible] +@[instance_reducible] def ofHasShiftOfFullyFaithful : letI := hF.hasShift s i; F.CommShift A := by letI := hF.hasShift s i @@ -577,10 +557,9 @@ attribute [irreducible] iso end OfComp -set_option backward.isDefEq.respectTransparency false in /-- Given an isomorphism `e : F ⋙ G ≅ H` where `G` is fully faithful, the functor `F` commutes with shifts by `A` if `G` and `H` do. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofComp : F.CommShift A where commShiftIso := OfComp.iso e commShiftIso_zero := by @@ -598,7 +577,6 @@ noncomputable def ofComp : F.CommShift A where congr 4 simp -set_option backward.isDefEq.respectTransparency false in lemma ofComp_compatibility : letI := ofComp e NatTrans.CommShift e.hom A := by diff --git a/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean b/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean index 52607c03e7b794..f9a6e802698e2e 100644 --- a/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean +++ b/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean @@ -133,6 +133,7 @@ instance precomp₁ {M : Type*} [AddCommMonoid M] [HasShift C₁ M] [HasShift C rw [NatTrans.shift_app (G.map ((F.commShiftIso m).hom.app X₁')) n X₂] simp [this] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option backward.inferInstanceAs.wrap false in instance precomp₂ {M : Type*} [AddCommMonoid M] [HasShift C₁ M] [HasShift C₂' M] @@ -186,6 +187,7 @@ instance : CommShift₂ (𝟙 G₁) h where simp only [flipApp, flipFunctor_obj, Functor.map_id, id_app] infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [CommShift₂ τ h] [CommShift₂ τ' h] : CommShift₂ (τ ≫ τ') h where commShift_app _ := by dsimp; infer_instance diff --git a/Mathlib/CategoryTheory/Shift/Induced.lean b/Mathlib/CategoryTheory/Shift/Induced.lean index c6eff67b0a7bf6..f5464048c63f3b 100644 --- a/Mathlib/CategoryTheory/Shift/Induced.lean +++ b/Mathlib/CategoryTheory/Shift/Induced.lean @@ -29,7 +29,7 @@ used for both quotient and localized shifts. namespace CategoryTheory -open Functor +open CategoryTheory.Functor variable {C D : Type _} [Category* C] [Category* D] (F : C ⥤ D) {A : Type _} [AddMonoid A] [HasShift C A] @@ -96,10 +96,9 @@ end Induced variable (A) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- When `F : C ⥤ D` is a functor satisfying suitable technical assumptions, this is the induced term of type `HasShift D A` deduced from `[HasShift C A]`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def induced : HasShift D A := hasShiftMk D A { F := s @@ -174,6 +173,7 @@ lemma shiftFunctor_of_induced (a : A) : variable (A) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctorZero_hom_app_obj_of_induced (X : C) : letI := HasShift.induced F A s i @@ -181,6 +181,7 @@ lemma shiftFunctorZero_hom_app_obj_of_induced (X : C) : (i 0).hom.app X ≫ F.map ((shiftFunctorZero C A).hom.app X) := by simp only [ShiftMkCore.shiftFunctorZero_eq, HasShift.Induced.zero_hom_app_obj] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctorZero_inv_app_obj_of_induced (X : C) : letI := HasShift.induced F A s i @@ -190,6 +191,7 @@ lemma shiftFunctorZero_inv_app_obj_of_induced (X : C) : variable {A} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctorAdd_hom_app_obj_of_induced (a b : A) (X : C) : letI := HasShift.induced F A s i @@ -200,6 +202,7 @@ lemma shiftFunctorAdd_hom_app_obj_of_induced (a b : A) (X : C) : (s b).map ((i a).inv.app X) := by simp only [ShiftMkCore.shiftFunctorAdd_eq, HasShift.Induced.add_hom_app_obj] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma shiftFunctorAdd_inv_app_obj_of_induced (a b : A) (X : C) : letI := HasShift.induced F A s i @@ -217,7 +220,7 @@ set_option backward.isDefEq.respectTransparency false in /-- When the target category of a functor `F : C ⥤ D` is equipped with the induced shift, this is the compatibility of `F` with the shifts on the categories `C` and `D`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Functor.CommShift.ofInduced : letI := HasShift.induced F A s i F.CommShift A := by diff --git a/Mathlib/CategoryTheory/Shift/InducedShiftSequence.lean b/Mathlib/CategoryTheory/Shift/InducedShiftSequence.lean index fb53dc2a94bbb5..4ae2e02c11d3c7 100644 --- a/Mathlib/CategoryTheory/Shift/InducedShiftSequence.lean +++ b/Mathlib/CategoryTheory/Shift/InducedShiftSequence.lean @@ -80,13 +80,12 @@ end induced variable [HasShift D M] [L.CommShift M] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given an isomorphism of functors `e : L ⋙ F ≅ G` relating functors `L : C ⥤ D`, `F : D ⥤ A` and `G : C ⥤ A`, an additive monoid `M`, a family of functors `F' : M → D ⥤ A` equipped with isomorphisms `e' : ∀ m, L ⋙ F' m ≅ G.shift m`, this is the shift sequence induced on `F` induced by a shift sequence for the functor `G`, provided that the functor `(whiskeringLeft C D A).obj L` of precomposition by `L` is fully faithful. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def induced : F.ShiftSequence M where sequence := F' isoZero := induced.isoZero e M F' e' diff --git a/Mathlib/CategoryTheory/Shift/Localization.lean b/Mathlib/CategoryTheory/Shift/Localization.lean index c98abdc19b2de0..ef40cb4541e3a3 100644 --- a/Mathlib/CategoryTheory/Shift/Localization.lean +++ b/Mathlib/CategoryTheory/Shift/Localization.lean @@ -76,7 +76,7 @@ variable [W.IsCompatibleWithShift A] /-- When `L : C ⥤ D` is a localization functor with respect to a morphism property `W` that is compatible with the shift by a monoid `A` on `C`, this is the induced shift on the category `D`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def HasShift.localized : HasShift D A := have := Localization.full_whiskeringLeft L W D have := Localization.faithful_whiskeringLeft L W D @@ -86,7 +86,7 @@ noncomputable def HasShift.localized : HasShift D A := (fun _ => Localization.fac _ _ _) /-- The localization functor `L : C ⥤ D` is compatible with the shift. -/ -@[nolint unusedHavesSuffices, implicit_reducible] +@[nolint unusedHavesSuffices, instance_reducible] noncomputable def Functor.CommShift.localized : @Functor.CommShift _ _ _ _ L A _ _ (HasShift.localized L W A) := have := Localization.full_whiskeringLeft L W D @@ -171,11 +171,10 @@ lemma iso_inv_app (a : A) (X : C) : end commShiftOfLocalization set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- In the context of localization of categories, if a functor is induced by a functor which commutes with the shift, then this functor commutes with the shift. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def commShiftOfLocalization : F'.CommShift A where commShiftIso := commShiftOfLocalization.iso L W F F' commShiftIso_zero := by @@ -237,7 +236,6 @@ lemma commShiftOfLocalization_iso_inv_app (a : A) (X : C) : end Functor set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance NatTrans.commShift_iso_hom_of_localization : letI := Functor.commShiftOfLocalization L W A F F' NatTrans.CommShift (Lifting.iso L W F F').hom A := by @@ -275,7 +273,7 @@ variable (M) in `e : Φ.functor ⋙ L₂ ≅ L₁ ⋙ G` is an isomorphism, `Φ` is a localizer morphism and `L₁` is a localization functor. We assume that all categories involved are equipped with shifts and that `L₁`, `L₂` and `Φ.functor` commute to them. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def commShift : G.CommShift M := by letI : Localization.Lifting L₁ W₁ (Φ.functor ⋙ L₂) G := ⟨e.symm⟩ exact Functor.commShiftOfLocalization L₁ W₁ M (Φ.functor ⋙ L₂) G @@ -303,7 +301,6 @@ lemma commShift_iso_inv_app (m : M) (X : C₁) : Functor.commShiftIso_comp_inv_app] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma natTransCommShift_hom : letI := Φ.commShift M L₁ L₂ G e NatTrans.CommShift e.hom M := by diff --git a/Mathlib/CategoryTheory/Shift/Opposite.lean b/Mathlib/CategoryTheory/Shift/Opposite.lean index 3652157eeee896..29ebb9140f113b 100644 --- a/Mathlib/CategoryTheory/Shift/Opposite.lean +++ b/Mathlib/CategoryTheory/Shift/Opposite.lean @@ -129,12 +129,14 @@ lemma oppositeShiftFunctorAdd_hom_app : Iso.hom_inv_id_app, op_id] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma oppositeShiftFunctorAdd'_inv_app : (shiftFunctorAdd' (OppositeShift C A) a b c h).inv.app X = ((shiftFunctorAdd' C a b c h).hom.app X.unop).op := by subst h simp only [shiftFunctorAdd'_eq_shiftFunctorAdd, oppositeShiftFunctorAdd_inv_app] +set_option backward.isDefEq.respectTransparency.types false in lemma oppositeShiftFunctorAdd'_hom_app : (shiftFunctorAdd' (OppositeShift C A) a b c h).hom.app X = ((shiftFunctorAdd' C a b c h).inv.app X.unop).op := by @@ -165,6 +167,7 @@ def OppositeShift.natTrans {G : C ⥤ D} (τ : F ⟶ G) : namespace Functor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a `CommShift` structure on `F`, this is the corresponding `CommShift` structure on @@ -188,6 +191,7 @@ instance commShiftOp [CommShift F A] : erw [oppositeShiftFunctorAdd_inv_app, oppositeShiftFunctorAdd_hom_app] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma commShiftOp_iso_eq [CommShift F A] (a : A) : (OppositeShift.functor A F).commShiftIso a = (NatIso.op (F.commShiftIso a)).symm := rfl @@ -196,7 +200,7 @@ set_option backward.isDefEq.respectTransparency false in Given a `CommShift` structure on `OppositeShift.functor F` (for the naive shifts on the opposite categories), this is the corresponding `CommShift` structure on `F`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def commShiftUnop [CommShift (OppositeShift.functor A F) A] : CommShift F A where commShiftIso a := NatIso.removeOp ((OppositeShift.functor A F).commShiftIso a).symm @@ -229,9 +233,8 @@ instance commShift_op (τ : F ⟶ G) [NatTrans.CommShift τ A] : ext rw [← cancel_mono (((OppositeShift.functor A F).commShiftIso _).inv.app _), ← cancel_epi (((OppositeShift.functor A G).commShiftIso _).inv.app _)] - dsimp - simp only [assoc, Iso.inv_hom_id_app_assoc, Iso.hom_inv_id_app, - comp_id] + simp only [Functor.comp_obj, comp_app, Functor.whiskerRight_app, assoc, + Iso.inv_hom_id_app_assoc, Functor.whiskerLeft_app, Iso.hom_inv_id_app, comp_id] exact (op_inj_iff _ _).mpr (NatTrans.shift_app_comm τ _ (unop _)) end NatTrans diff --git a/Mathlib/CategoryTheory/Shift/Pullback.lean b/Mathlib/CategoryTheory/Shift/Pullback.lean index fbe6cea8ac976e..72ce1bc491b9cc 100644 --- a/Mathlib/CategoryTheory/Shift/Pullback.lean +++ b/Mathlib/CategoryTheory/Shift/Pullback.lean @@ -109,6 +109,7 @@ lemma pullbackShiftFunctorZero'_hom_app : pullbackShiftFunctorZero'_inv_app, assoc, Iso.inv_hom_id_app_assoc, Iso.inv_hom_id_app] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma pullbackShiftFunctorAdd'_inv_app : (shiftFunctorAdd' _ a₁ a₂ a₃ h).inv.app X = (shiftFunctor (PullbackShift C φ) a₂).map ((pullbackShiftIso C φ a₁ b₁ h₁).hom.app X) ≫ @@ -212,7 +213,7 @@ namespace NatTrans variable {F} {G : C ⥤ D} [G.CommShift B] set_option backward.isDefEq.respectTransparency false in -open Functor in +open CategoryTheory.Functor in instance commShiftPullback (τ : F ⟶ G) [NatTrans.CommShift τ B] : NatTrans.CommShift (PullbackShift.natTrans φ τ) A where shift_comm _ := by @@ -261,7 +262,7 @@ composition of `CommShift` structures by `B` on `F` and `G`), and that on `PullbackShift.functor F φ ⋙ PullbackShift.functor G φ` (i.e. the one coming from the composition of the pulled back `CommShift` structures on `F` and `G`). -/ -open Functor in +open CategoryTheory.Functor in instance : NatTrans.CommShift (PullbackShift.natIsoComp φ F G).hom A where shift_comm _ := by ext diff --git a/Mathlib/CategoryTheory/Shift/ShiftSequence.lean b/Mathlib/CategoryTheory/Shift/ShiftSequence.lean index a94a1a3ff4b091..2d374fec789837 100644 --- a/Mathlib/CategoryTheory/Shift/ShiftSequence.lean +++ b/Mathlib/CategoryTheory/Shift/ShiftSequence.lean @@ -61,7 +61,7 @@ class ShiftSequence where set_option backward.defeqAttrib.useBackward true in /-- The tautological shift sequence on a functor. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ShiftSequence.tautological : ShiftSequence F M where sequence n := shiftFunctor C n ⋙ F isoZero := isoWhiskerRight (shiftFunctorZero C M) F ≪≫ F.leftUnitor @@ -99,7 +99,6 @@ lemma shiftIso_hom_naturality {X Y : C} (n a a' : M) (ha' : n + a = a') (f : X (shiftIso F n a a' ha').hom.app X ≫ (shift F a').map f := (F.shiftIso n a a' ha').hom.naturality f -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shiftIso_inv_naturality {X Y : C} (n a a' : M) (ha' : n + a = a') (f : X ⟶ Y) : (shift F a').map f ≫ (shiftIso F n a a' ha').inv.app Y = @@ -195,7 +194,6 @@ lemma shiftIso_add'_inv_app (n m mn : M) (hnm : m + n = mn) (a a' a'' : M) (shift F a).map ((shiftFunctorAdd' C m n mn hnm).inv.app X) := by simp [F.shiftIso_add' n m mn hnm a a' a'' ha' ha''] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma shiftIso_hom_app_comp (n m mn : M) (hnm : m + n = mn) (a a' a'' : M) (ha' : n + a = a') (ha'' : m + a' = a'') (X : C) : @@ -223,7 +221,6 @@ lemma shiftMap_comp' {X Y Z : C} {n : M} (f : X ⟶ Y) (g : Y ⟶ Z⟦n⟧) (a a F.shiftMap (f ≫ g) a a' ha' = (F.shift a).map f ≫ F.shiftMap g a a' ha' := by simp [shiftMap] -set_option backward.isDefEq.respectTransparency false in /-- When `f : X ⟶ Y⟦m⟧`, `m + n = mn`, `n + a = a'` and `ha'' : m + a' = a''`, this lemma relates the two morphisms `F.shiftMap f a' a'' ha''` and `(F.shift a).map (f⟦n⟧')`. Indeed, @@ -239,7 +236,6 @@ lemma shiftIso_hom_app_comp_shiftMap {X Y : C} {m : M} (f : X ⟶ Y⟦m⟧) (n m ← Functor.map_comp_assoc, Iso.inv_hom_id_app, Functor.map_id, id_comp, comp_obj, shiftIso_hom_naturality_assoc, shiftMap] -set_option backward.isDefEq.respectTransparency false in /-- If `f : X ⟶ Y⟦m⟧`, `n + m = 0` and `ha' : m + a = a'`, this lemma relates the two morphisms `F.shiftMap f a a' ha'` and `(F.shift a').map (f⟦n⟧')`. Indeed, diff --git a/Mathlib/CategoryTheory/Shift/ShiftedHom.lean b/Mathlib/CategoryTheory/Shift/ShiftedHom.lean index 4209be6dba03bc..b622d7160712e4 100644 --- a/Mathlib/CategoryTheory/Shift/ShiftedHom.lean +++ b/Mathlib/CategoryTheory/Shift/ShiftedHom.lean @@ -41,7 +41,6 @@ noncomputable def comp {a b c : M} (f : ShiftedHom X Y a) (g : ShiftedHom Y Z b) ShiftedHom X Z c := f ≫ g⟦a⟧' ≫ (shiftFunctorAdd' C b a c h).inv.app _ -set_option backward.isDefEq.respectTransparency false in lemma comp_assoc {a₁ a₂ a₃ a₁₂ a₂₃ a : M} (α : ShiftedHom X Y a₁) (β : ShiftedHom Y Z a₂) (γ : ShiftedHom Z T a₃) (h₁₂ : a₂ + a₁ = a₁₂) (h₂₃ : a₃ + a₂ = a₂₃) (h : a₃ + a₂ + a₁ = a) : @@ -59,7 +58,6 @@ apply this with `M := ℤ` and `m₀` the coercion of `0 : ℕ`. -/ noncomputable def mk₀ (m₀ : M) (hm₀ : m₀ = 0) (f : X ⟶ Y) : ShiftedHom X Y m₀ := f ≫ (shiftFunctorZero' C m₀ hm₀).inv.app Y -set_option backward.isDefEq.respectTransparency false in /-- The bijection `(X ⟶ Y) ≃ ShiftedHom X Y m₀` when `m₀ = 0`. -/ @[simps apply] noncomputable def homEquiv (m₀ : M) (hm₀ : m₀ = 0) : (X ⟶ Y) ≃ ShiftedHom X Y m₀ where @@ -68,7 +66,6 @@ noncomputable def homEquiv (m₀ : M) (hm₀ : m₀ = 0) : (X ⟶ Y) ≃ Shifted left_inv f := by simp [mk₀] right_inv g := by simp [mk₀] -set_option backward.isDefEq.respectTransparency false in lemma mk₀_comp (m₀ : M) (hm₀ : m₀ = 0) (f : X ⟶ Y) {a : M} (g : ShiftedHom Y Z a) : (mk₀ m₀ hm₀ f).comp g (by rw [hm₀, add_zero]) = f ≫ g := by subst hm₀ @@ -79,7 +76,6 @@ lemma mk₀_id_comp (m₀ : M) (hm₀ : m₀ = 0) {a : M} (f : ShiftedHom X Y a) (mk₀ m₀ hm₀ (𝟙 X)).comp f (by rw [hm₀, add_zero]) = f := by simp [mk₀_comp] -set_option backward.isDefEq.respectTransparency false in lemma comp_mk₀ {a : M} (f : ShiftedHom X Y a) (m₀ : M) (hm₀ : m₀ = 0) (g : Y ⟶ Z) : f.comp (mk₀ m₀ hm₀ g) (by rw [hm₀, zero_add]) = f ≫ g⟦a⟧' := by subst hm₀ @@ -170,7 +166,6 @@ def map {a : M} (f : ShiftedHom X Y a) (F : C ⥤ D) [F.CommShift M] : ShiftedHom (F.obj X) (F.obj Y) a := F.map f ≫ (F.commShiftIso a).hom.app Y -set_option backward.isDefEq.respectTransparency false in @[simp] lemma map_mk₀ (m₀ : M) (hm₀ : m₀ = 0) (f : X ⟶ Y) (F : C ⥤ D) [F.CommShift M] : (ShiftedHom.mk₀ m₀ hm₀ f).map F = .mk₀ _ hm₀ (F.map f) := by @@ -186,7 +181,6 @@ lemma comp_map {a : M} (f : ShiftedHom X Y a) (F : C ⥤ D) [F.CommShift M] (G : D ⥤ E) [G.CommShift M] : f.map (F ⋙ G) = (f.map F).map G := by simp [map, Functor.commShiftIso_comp_hom_app] -set_option backward.isDefEq.respectTransparency false in lemma map_naturality {a : M} (f : ShiftedHom X Y a) {F G : C ⥤ D} (τ : F ⟶ G) [F.CommShift M] [G.CommShift M] [NatTrans.CommShift τ M] : (f.map F).comp (mk₀ 0 rfl (τ.app Y)) (zero_add _) = @@ -211,7 +205,6 @@ lemma map_naturality_2 map_naturality_1 f e.symm set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma map_comp {a b c : M} (f : ShiftedHom X Y a) (g : ShiftedHom Y Z b) (h : b + a = c) (F : C ⥤ D) [F.CommShift M] : (f.comp g h).map F = (f.map F).comp (g.map F) h := by diff --git a/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean b/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean index dd3bb2617960dc..61651b032da238 100644 --- a/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean +++ b/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean @@ -56,7 +56,6 @@ lemma opEquiv_symm_apply_comp {X Y : C} {a : ℤ} simp only [assoc, Functor.map_comp] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma opEquiv_symm_comp {a b : ℤ} (f : ShiftedHom (Opposite.op Z) (Opposite.op Y) a) (g : ShiftedHom (Opposite.op Y) (Opposite.op X) b) @@ -117,7 +116,6 @@ lemma opEquiv'_symm_comp (f : Y ⟶ X) {n a : ℤ} (x : Opposite.op (Z⟦a⟧) Quiver.Hom.op_inj (by simp [opEquiv'_symm_apply, opEquiv_symm_apply]) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma opEquiv'_zero_add_symm (a : ℤ) (f : Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦(0 : ℤ)⟧) : (opEquiv' 0 a a (zero_add a)).symm f = ((shiftFunctorZero Cᵒᵖ ℤ).hom.app _).unop ≫ f.unop := by diff --git a/Mathlib/CategoryTheory/Shift/SingleFunctors.lean b/Mathlib/CategoryTheory/Shift/SingleFunctors.lean index e9d6a3cd7dd39b..0de03eaa98655d 100644 --- a/Mathlib/CategoryTheory/Shift/SingleFunctors.lean +++ b/Mathlib/CategoryTheory/Shift/SingleFunctors.lean @@ -203,7 +203,6 @@ instance (f : F ⟶ G) [IsIso f] (n : A) : IsIso (f.hom n) := variable (F) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given `F : SingleFunctors C D A`, and a functor `G : D ⥤ E` which commutes with the shift by `A`, this is the "composition" of `F` and `G` in `SingleFunctors C E A`. -/ @[simps! functor shiftIso_hom_app shiftIso_inv_app] @@ -230,7 +229,6 @@ def postcomp (G : D ⥤ E) [G.CommShift A] : variable (C A) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The functor `SingleFunctors C D A ⥤ SingleFunctors C E A` given by the postcomposition by a functor `G : D ⥤ E` which commutes with the shift. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean b/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean index e73a7581854002..2317272d033edb 100644 --- a/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean +++ b/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean @@ -24,7 +24,7 @@ we lift `F` in `SingleFunctor C D A`. namespace CategoryTheory -open Category Functor +open Category CategoryTheory.Functor variable {C D E : Type*} [Category C] [Category D] [Category E] {A : Type*} [AddMonoid A] [HasShift D A] [HasShift E A] @@ -56,7 +56,6 @@ private lemma map_shiftIso_hom_app (n a a' : A) (h : n + a = a') (X : C) : end lift set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Let `C`, `D` and `E` be categories. Let `A` be an additive monoid. Assume that `D` and `E` have shifts by `A` and that we have a fully faithful functor `G : D ⥤ A` which commutes with shifts. @@ -89,7 +88,6 @@ lemma map_lift_shiftIso_hom_app (n a a' : A) (h : n + a = a') (X : C) : lift.map_shiftIso_hom_app .. set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- After postcomposition with the fully faithful functor `G`, `lift F G Φ hΦ` becomes isomorphic to `F`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/ShrinkYoneda.lean b/Mathlib/CategoryTheory/ShrinkYoneda.lean index 40a9ffa06c34ff..e73c03841d3008 100644 --- a/Mathlib/CategoryTheory/ShrinkYoneda.lean +++ b/Mathlib/CategoryTheory/ShrinkYoneda.lean @@ -75,6 +75,7 @@ set_option backward.defeqAttrib.useBackward true in instance (X : C) : FunctorToTypes.Small.{w} (yoneda.obj X) := fun _ ↦ by dsimp; infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- The Yoneda embedding `C ⥤ Cᵒᵖ ⥤ Type w` for a locally `w`-small category `C`. -/ @[simps -isSimp obj map, pp_with_univ] noncomputable def shrinkYoneda : @@ -82,6 +83,7 @@ noncomputable def shrinkYoneda : obj X := FunctorToTypes.shrink (yoneda.obj X) map f := FunctorToTypes.shrinkMap (yoneda.map f) +set_option backward.isDefEq.respectTransparency.types false in /-- The type `(shrinkYoneda.obj X).obj Y` is equivalent to `Y.unop ⟶ X`. -/ noncomputable def shrinkYonedaObjObjEquiv {X : C} {Y : Cᵒᵖ} : ((shrinkYoneda.{w}.obj X).obj Y) ≃ (Y.unop ⟶ X) := @@ -158,6 +160,7 @@ lemma shrinkYonedaEquiv_shrinkYoneda_map {X Y : C} (f : X ⟶ Y) : shrinkYonedaEquiv (shrinkYoneda.{w}.map f) = shrinkYonedaObjObjEquiv.symm f := by simp [shrinkYonedaEquiv, shrinkYoneda, shrinkYonedaObjObjEquiv] +set_option backward.isDefEq.respectTransparency.types false in lemma shrinkYonedaEquiv_comp {X : C} {P Q : Cᵒᵖ ⥤ Type w} (α : shrinkYoneda.obj X ⟶ P) (β : P ⟶ Q) : shrinkYonedaEquiv (α ≫ β) = β.app _ (shrinkYonedaEquiv α) := by @@ -186,6 +189,7 @@ lemma shrinkYonedaEquiv_symm_app_shrinkYonedaObjObjEquiv_symm {X : C} {P : Cᵒ obtain ⟨g, rfl⟩ := shrinkYonedaEquiv.surjective s simp [map_shrinkYonedaEquiv] +set_option backward.isDefEq.respectTransparency.types false in variable (C) in /-- The functor `shrinkYoneda : C ⥤ Cᵒᵖ ⥤ Type w` for a locally `w`-small category `C` is fully faithful. -/ @@ -211,6 +215,7 @@ def shrinkYonedaIsoYoneda : shrinkYoneda.{v} ≅ yoneda (C := C) := (by intros; ext; simp [shrinkYonedaObjObjEquiv_obj_map])) (by intros; ext; simp [shrinkYonedaObjObjEquiv_map_app]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `shrinkYoneda` is compatible with `uliftFunctor`. -/ noncomputable @@ -342,6 +347,7 @@ lemma shrinkCoyonedaEquiv_shrinkCoyoneda_map {X Y : Cᵒᵖ} (f : X ⟶ Y) : shrinkCoyonedaEquiv (shrinkCoyoneda.{w}.map f) = shrinkCoyonedaObjObjEquiv.symm f.unop := by simp [shrinkCoyonedaEquiv, shrinkYoneda, shrinkYonedaObjObjEquiv] +set_option backward.isDefEq.respectTransparency.types false in lemma shrinkCoyonedaEquiv_comp {X : Cᵒᵖ} {P Q : C ⥤ Type w} (α : shrinkCoyoneda.obj X ⟶ P) (β : P ⟶ Q) : shrinkCoyonedaEquiv (α ≫ β) = β.app _ (shrinkCoyonedaEquiv α) := by @@ -385,6 +391,7 @@ instance : (shrinkCoyoneda.{w} (C := C)).Faithful := (fullyFaithfulShrinkCoyoned instance : (shrinkCoyoneda.{w} (C := C)).Full := (fullyFaithfulShrinkCoyoneda C).full +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `shrinkCoyoneda` at the morphism universe level is `coyoneda`. -/ @[simps! hom_app inv_app] @@ -395,6 +402,7 @@ def shrinkCoyonedaIsoCoyoneda : shrinkCoyoneda.{v} ≅ coyoneda (C := C) := (by intros; ext; simp [shrinkYonedaObjObjEquiv_map_app])) (by intros; ext; simp [shrinkYonedaObjObjEquiv_obj_map]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `shrinkCoyoneda` is compatible with `uliftFunctor`. -/ noncomputable diff --git a/Mathlib/CategoryTheory/Sigma/Basic.lean b/Mathlib/CategoryTheory/Sigma/Basic.lean index 974fd93ce08269..fcb1a4951fe3a7 100644 --- a/Mathlib/CategoryTheory/Sigma/Basic.lean +++ b/Mathlib/CategoryTheory/Sigma/Basic.lean @@ -211,6 +211,9 @@ def mapId : map C (id : I → I) ≅ 𝟭 (Σ i, C i) := variable {I} {K : Type w₃} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `Sigma.map` applied to a composition is a composition of functors. -/ @[simps!] def mapComp (f : K → J) (g : J → I) : map (fun x ↦ C (g x)) f ⋙ (map C g :) ≅ map C (g ∘ f) := diff --git a/Mathlib/CategoryTheory/SingleObj.lean b/Mathlib/CategoryTheory/SingleObj.lean index 654702d8b0fb55..5380231ec5266f 100644 --- a/Mathlib/CategoryTheory/SingleObj.lean +++ b/Mathlib/CategoryTheory/SingleObj.lean @@ -133,6 +133,7 @@ theorem mapHom_comp (f : M →* N) {P : Type w} [Monoid P] (g : N →* P) : variable {C : Type v} [Category.{w} C] +set_option backward.isDefEq.respectTransparency.types false in /-- Given a function `f : C → G` from a category to a group, we get a functor `C ⥤ G` sending any morphism `x ⟶ y` to `f y * (f x)⁻¹`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Sites/Adjunction.lean b/Mathlib/CategoryTheory/Sites/Adjunction.lean index a325ec54ea1d9a..fd39db4c085316 100644 --- a/Mathlib/CategoryTheory/Sites/Adjunction.lean +++ b/Mathlib/CategoryTheory/Sites/Adjunction.lean @@ -21,7 +21,7 @@ categories of sheaves. We also show that `G` preserves sheafification. namespace CategoryTheory -open GrothendieckTopology Limits Opposite Functor +open GrothendieckTopology Limits Opposite CategoryTheory.Functor universe v₁ v₂ u₁ u₂ diff --git a/Mathlib/CategoryTheory/Sites/Canonical.lean b/Mathlib/CategoryTheory/Sites/Canonical.lean index d28cdafc3cf167..3f974a705f1b99 100644 --- a/Mathlib/CategoryTheory/Sites/Canonical.lean +++ b/Mathlib/CategoryTheory/Sites/Canonical.lean @@ -164,7 +164,7 @@ variable (J : GrothendieckTopology C) If `J` is subcanonical, we obtain a "Yoneda" functor from the defining site into the sheaf category. -/ -@[simps! obj_obj map_hom] +@[simps! obj_obj map_hom, implicit_reducible] def yoneda [J.Subcanonical] : C ⥤ Sheaf J (Type v) := ObjectProperty.lift _ CategoryTheory.yoneda <| fun X ↦ by rw [isSheaf_iff_isSheaf_of_type] @@ -176,6 +176,9 @@ for the category of types. -/ def uliftYoneda [J.Subcanonical] : C ⥤ Sheaf J (Type (max v w)) := J.yoneda ⋙ sheafCompose J uliftFunctor.{w} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- If `C` is a category with `[Category.{max w v} C]`, this is the isomorphism `uliftYoneda.{w} (C := C) ≅ yoneda`. -/ @[simps!] @@ -195,6 +198,9 @@ def yonedaCompSheafToPresheaf : J.yoneda ⋙ sheafToPresheaf J (Type v) ≅ CategoryTheory.yoneda := Iso.refl _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `yonedaCompSheafToPresheaf` with a raise in the universe level. -/ @[simps! +dsimpLhs] def uliftYonedaCompSheafToPresheaf : diff --git a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean index 8a134df66a9f58..c2f2db39b8ff80 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean @@ -35,7 +35,7 @@ open Limits variable {C D E : Type*} [Category* C] [Category* D] [Category* E] -open Opposite Presieve Functor +open Opposite Presieve CategoryTheory.Functor /-- A presieve is *regular* if it consists of a single effective epimorphism. -/ class Presieve.regular {X : C} (R : Presieve X) : Prop where @@ -214,6 +214,7 @@ theorem parallelPair_pullback_initial {X B : C} (π : X ⟶ B) refine ⟨Quiver.Hom.op (ObjectProperty.homMk (Over.homMk ij)), ?_, ?_⟩ all_goals congr; aesop +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given a limiting pullback cone, the fork in `SingleEqualizerCondition` is limiting iff the diagram diff --git a/Mathlib/CategoryTheory/Sites/Coherent/SheafComparison.lean b/Mathlib/CategoryTheory/Sites/Coherent/SheafComparison.lean index 0b2dc999b2717d..713869b38535c3 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/SheafComparison.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/SheafComparison.lean @@ -36,7 +36,7 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory -open Limits Functor regularTopology +open Limits CategoryTheory.Functor regularTopology variable {C D : Type*} [Category* C] [Category* D] (F : C ⥤ D) @@ -258,6 +258,7 @@ theorem isSheaf_iff_extensiveSheaf_of_projective [Preregular C] [FinitaryExtensi IsSheaf (coherentTopology C) F ↔ IsSheaf (extensiveTopology C) F := by rw [isSheaf_iff_preservesFiniteProducts_of_projective, isSheaf_iff_preservesFiniteProducts] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The categories of coherent sheaves and extensive sheaves on `C` are equivalent if `C` is diff --git a/Mathlib/CategoryTheory/Sites/CompatiblePlus.lean b/Mathlib/CategoryTheory/Sites/CompatiblePlus.lean index 51a03ad69b9c5d..73b8d8e69aed2b 100644 --- a/Mathlib/CategoryTheory/Sites/CompatiblePlus.lean +++ b/Mathlib/CategoryTheory/Sites/CompatiblePlus.lean @@ -24,7 +24,7 @@ noncomputable section namespace CategoryTheory.GrothendieckTopology -open CategoryTheory Limits Opposite Functor +open CategoryTheory Limits Opposite CategoryTheory.Functor universe v u diff --git a/Mathlib/CategoryTheory/Sites/CompatibleSheafification.lean b/Mathlib/CategoryTheory/Sites/CompatibleSheafification.lean index 5595a48e173681..3b1c7aa0361a0f 100644 --- a/Mathlib/CategoryTheory/Sites/CompatibleSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/CompatibleSheafification.lean @@ -63,6 +63,7 @@ noncomputable def sheafificationWhiskerLeftIso (P : Cᵒᵖ ⥤ D) refine isoWhiskerRight ?_ _ exact J.plusFunctorWhiskerLeftIso _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem sheafificationWhiskerLeftIso_hom_app (P : Cᵒᵖ ⥤ D) (F : D ⥤ E) @@ -73,6 +74,7 @@ theorem sheafificationWhiskerLeftIso_hom_app (P : Cᵒᵖ ⥤ D) (F : D ⥤ E) dsimp [sheafificationWhiskerLeftIso, sheafifyCompIso] simp only [sheafify, Category.comp_id] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem sheafificationWhiskerLeftIso_inv_app (P : Cᵒᵖ ⥤ D) (F : D ⥤ E) @@ -94,6 +96,7 @@ noncomputable def sheafificationWhiskerRightIso : refine (associator _ _ _).symm ≪≫ ?_ exact isoWhiskerRight (J.plusFunctorWhiskerRightIso _) (J.plusFunctor E) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem sheafificationWhiskerRightIso_hom_app : @@ -101,6 +104,7 @@ theorem sheafificationWhiskerRightIso_hom_app : dsimp [sheafificationWhiskerRightIso, sheafifyCompIso] simp only [sheafify, Category.id_comp, Category.comp_id] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem sheafificationWhiskerRightIso_inv_app : @@ -108,6 +112,7 @@ theorem sheafificationWhiskerRightIso_inv_app : dsimp [sheafificationWhiskerRightIso, sheafifyCompIso] simp only [sheafify, Category.id_comp, Category.comp_id] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp, reassoc] theorem whiskerRight_toSheafify_sheafifyCompIso_hom : diff --git a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean index 577e18af7001ad..45cebad46fc564 100644 --- a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean @@ -117,6 +117,7 @@ theorem equiv_apply {X : C} {P : Cᵒᵖ ⥤ D} {S : J.Cover X} [HasMultiequaliz equiv P S x I = Multiequalizer.ι (S.index P) I x := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem equiv_symm_eq_apply {X : C} {P : Cᵒᵖ ⥤ D} {S : J.Cover X} [HasMultiequalizer (S.index P)] (x : Meq P S) (I : S.Arrow) : -- We can hint `ConcreteCategory.hom (Y := P.obj (op I.Y))` below to put it into `simp`-normal @@ -203,6 +204,7 @@ theorem toPlus_eq_mk {X : C} {P : Cᵒᵖ ⥤ D} (x : ToType (P.obj (op X))) : variable [∀ X : C, PreservesColimitsOfShape (J.Cover X)ᵒᵖ (forget D)] +set_option backward.isDefEq.respectTransparency.types false in theorem exists_rep {X : C} {P : Cᵒᵖ ⥤ D} (x : ToType ((J.plusObj P).obj (op X))) : ∃ (S : J.Cover X) (y : Meq P S), x = mk y := by obtain ⟨S, y, h⟩ := Concrete.colimit_exists_rep (J.diagram P X) x @@ -239,6 +241,7 @@ theorem eq_mk_iff_exists {X : C} {P : Cᵒᵖ ⥤ D} {S T : J.Cover X} (x : Meq erw [Meq.equiv_symm_eq_apply] cases i; rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `P⁺` is always separated. -/ theorem sep {X : C} (P : Cᵒᵖ ⥤ D) (S : J.Cover X) (x y : ToType ((J.plusObj P).obj (op X))) (h : ∀ I : S.Arrow, (J.plusObj P).map I.f.op x = (J.plusObj P).map I.f.op y) : x = y := by @@ -285,6 +288,7 @@ theorem sep {X : C} (P : Cᵒᵖ ⥤ D) (S : J.Cover X) (x y : ToType ((J.plusOb · exact x.congr_apply I.middle_spec.symm _ · exact y.congr_apply I.middle_spec.symm _ +set_option backward.isDefEq.respectTransparency.types false in theorem inj_of_sep (P : Cᵒᵖ ⥤ D) (hsep : ∀ (X : C) (S : J.Cover X) (x y : ToType (P.obj (op X))), @@ -519,6 +523,7 @@ theorem toSheafify_sheafifyLift {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (hQ : Presh dsimp only [sheafifyLift, toSheafify] simp +set_option backward.isDefEq.respectTransparency.types false in theorem sheafifyLift_unique {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (hQ : Presheaf.IsSheaf J Q) (γ : J.sheafify P ⟶ Q) : J.toSheafify P ≫ γ = η → γ = sheafifyLift J η hQ := by intro h @@ -533,6 +538,7 @@ theorem isoSheafify_inv {P : Cᵒᵖ ⥤ D} (hP : Presheaf.IsSheaf J P) : apply J.sheafifyLift_unique simp [Iso.comp_inv_eq] +set_option backward.isDefEq.respectTransparency.types false in theorem sheafify_hom_ext {P Q : Cᵒᵖ ⥤ D} (η γ : J.sheafify P ⟶ Q) (hQ : Presheaf.IsSheaf J Q) (h : J.toSheafify P ≫ η = J.toSheafify P ≫ γ) : η = γ := by apply J.plus_hom_ext _ _ hQ diff --git a/Mathlib/CategoryTheory/Sites/ConstantSheaf.lean b/Mathlib/CategoryTheory/Sites/ConstantSheaf.lean index f7b3ccdc91aa3b..bc580cbb21f045 100644 --- a/Mathlib/CategoryTheory/Sites/ConstantSheaf.lean +++ b/Mathlib/CategoryTheory/Sites/ConstantSheaf.lean @@ -35,7 +35,7 @@ essential image of the constant sheaf functor. namespace CategoryTheory -open Limits Opposite Category Functor Sheaf Adjunction +open Limits Opposite Category CategoryTheory.Functor Sheaf Adjunction variable {C : Type*} [Category* C] (J : GrothendieckTopology C) variable (D : Type*) [Category* D] @@ -97,7 +97,6 @@ lemma isConstant_iff_mem_essImage {L : D ⥤ Sheaf J D} {T : C} (hT : IsTerminal rw [essImage_eq_of_natIso (adj.leftAdjointUniq (constantSheafAdj J D hT))] exact ⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩ -set_option backward.isDefEq.respectTransparency false in lemma isConstant_of_isIso_counit_app (F : Sheaf J D) [HasTerminal C] [IsIso <| (constantSheafAdj J D terminalIsTerminal).counit.app F] : IsConstant J F where mem_essImage := ⟨_, ⟨asIso <| (constantSheafAdj J D terminalIsTerminal).counit.app F⟩⟩ @@ -108,7 +107,6 @@ instance [(constantSheaf J D).Faithful] [(constantSheaf J D).Full] (F : Sheaf J rw [isIso_counit_app_iff_mem_essImage] exact F.mem_essImage_of_isConstant -set_option backward.isDefEq.respectTransparency false in /-- If the constant sheaf functor is fully faithful, then a sheaf is constant if and only if the counit of the constant sheaf adjunction applied to it is an isomorphism. diff --git a/Mathlib/CategoryTheory/Sites/Continuous.lean b/Mathlib/CategoryTheory/Sites/Continuous.lean index 48d970342868c4..753ade51d66758 100644 --- a/Mathlib/CategoryTheory/Sites/Continuous.lean +++ b/Mathlib/CategoryTheory/Sites/Continuous.lean @@ -94,6 +94,7 @@ section variable {E} {W : C} {i₁ i₂ : E.I₀} (p₁ : W ⟶ E.X i₁) (p₂ : W ⟶ E.X i₂) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma functorPushforward_sieve₁_map_le : Sieve.functorPushforward F (E.sieve₁ p₁ p₂) ≤ (E.map F).sieve₁ (F.map p₁) (F.map p₂) := by @@ -237,7 +238,6 @@ private lemma isSheaf_of_isContinuous_aux (F : C ⥤ D) [Functor.IsContinuous F Iso.trans_hom, Iso.symm_hom, Functor.mapIso_inv, Iso.app_inv, Category.assoc] rw [← Functor.map_comp_assoc, ← dsimp% e.inv.naturality, ← Functor.map_comp_assoc, Sieve.shrinkFunctorUliftFunctorIso_inv_ι] - rfl rw [K.W.arrow_mk_iso_iff iso] apply GrothendieckTopology.W_of_preservesSheafification exact F.W_map_of_adjunction_of_isContinuous_aux J K H adj @@ -385,6 +385,7 @@ def sheafPushforwardContinuousComp [IsContinuous G K L] : sheafPushforwardContinuous G A K L ⋙ sheafPushforwardContinuous F A J K ≅ sheafPushforwardContinuous (F ⋙ G) A J L := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {F F'} in /-- The action of a natural transformation on pushforward functors of sheaves. -/ @@ -393,6 +394,7 @@ def sheafPushforwardContinuousNatTrans [IsContinuous F' J K] : sheafPushforwardContinuous F' A J K ⟶ sheafPushforwardContinuous F A J K where app M := ⟨whiskerRight (NatTrans.op τ) _⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {F F'} in /-- The action of a natural isomorphism on pushforward functors of sheaves. -/ @@ -404,6 +406,7 @@ def sheafPushforwardContinuousIso [IsContinuous F' J K] : hom_inv_id := by ext; simp [← Functor.map_comp, ← op_comp] inv_hom_id := by ext; simp [← Functor.map_comp, ← op_comp] +set_option backward.isDefEq.respectTransparency.types false in /-- If a continuous functor between sites is isomorphic to the identity functor, then the corresponding pushforward functor on sheaves identifies to the identity functor. -/ @@ -412,6 +415,7 @@ def sheafPushforwardContinuousId' [IsContinuous F'' J J] : sheafPushforwardContinuous F'' A J J ≅ 𝟭 _ := sheafPushforwardContinuousIso eF'' _ _ _ ≪≫ sheafPushforwardContinuousId _ _ +set_option backward.isDefEq.respectTransparency.types false in variable {F G} in /-- When we have an isomorphism `F ⋙ G ≅ FG` between continuous functors between sites, the composition of the pushforward functors for @@ -426,6 +430,7 @@ def sheafPushforwardContinuousComp' end Functor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F ⊣ G` is an adjunction between continuous functors, the associated pushforwards on sheaves are adjoint. -/ diff --git a/Mathlib/CategoryTheory/Sites/CoverLifting.lean b/Mathlib/CategoryTheory/Sites/CoverLifting.lean index 7590a8bf0ece84..d316ae967e06ef 100644 --- a/Mathlib/CategoryTheory/Sites/CoverLifting.lean +++ b/Mathlib/CategoryTheory/Sites/CoverLifting.lean @@ -113,7 +113,6 @@ section variable {F : C ⥤ D} {G : D ⥤ C} -set_option backward.isDefEq.respectTransparency false in lemma Adjunction.isCocontinuous_iff_coverPreserving (adj : F ⊣ G) : F.IsCocontinuous J K ↔ CoverPreserving K J G := by refine ⟨fun h ↦ ⟨?_⟩, fun h ↦ ⟨?_⟩⟩ @@ -185,6 +184,7 @@ def liftAux {Y : C} (f : G.obj Y ⟶ X) : s.pt ⟶ F.obj (op Y) := r.w := by simpa using G.congr_map w =≫ f .. }) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma liftAux_map {Y : C} (f : G.obj Y ⟶ X) {W : C} (g : W ⟶ Y) (i : S.Arrow) (h : G.obj W ⟶ i.Y) (w : h ≫ i.f = G.map g ≫ f) : @@ -233,6 +233,7 @@ lemma fac' (j : StructuredArrow (op X) G.op) : lift hF hR s ≫ R.map j.hom ≫ α.app j.right = liftAux hF α s j.hom.unop := by apply IsLimit.fac +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma fac (i : S.Arrow) : lift hF hR s ≫ R.map i.f.op = s.ι i := by diff --git a/Mathlib/CategoryTheory/Sites/CoverPreserving.lean b/Mathlib/CategoryTheory/Sites/CoverPreserving.lean index 0808b26a514328..97b2bfd29f694b 100644 --- a/Mathlib/CategoryTheory/Sites/CoverPreserving.lean +++ b/Mathlib/CategoryTheory/Sites/CoverPreserving.lean @@ -192,6 +192,7 @@ lemma Functor.isContinuous_iff_coverPreserving [RepresentablyFlat F] : refine ⟨fun h ↦ .of_isContinuous _ _ _, fun h ↦ ?_⟩ apply Functor.isContinuous_of_coverPreserving (compatiblePreservingOfFlat _ _) h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `C` has pullbacks and `F : C ⥤ D` preserves pullbacks, any cover preserving functor preserves all `1`-hypercovers. -/ diff --git a/Mathlib/CategoryTheory/Sites/DenseSubsite/Basic.lean b/Mathlib/CategoryTheory/Sites/DenseSubsite/Basic.lean index 9e0d7e8ac1d319..f838527c4d703d 100644 --- a/Mathlib/CategoryTheory/Sites/DenseSubsite/Basic.lean +++ b/Mathlib/CategoryTheory/Sites/DenseSubsite/Basic.lean @@ -175,6 +175,9 @@ theorem naturality_apply [G.IsLocallyFull K] {X Y : C} (i : G.obj X ⟶ G.obj Y) refine IsLocallyFull.ext G _ i fun V iVX iVY e ↦ ?_ simp only [← Functor.map_comp_apply, ← op_comp, ← e, this] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] theorem naturality [G.IsLocallyFull K] {X Y : C} (i : G.obj X ⟶ G.obj Y) : α.app _ ≫ ℱ'.1.map i.op = ℱ.map i.op ≫ α.app _ := by ext; exact naturality_apply α i _ @@ -302,7 +305,7 @@ noncomputable def sheafIso {ℱ ℱ' : Sheaf K (Type v)} (i : G.op ⋙ ℱ.obj end Types -open Types +open IsCoverDense.Types variable [G.IsCoverDense K] [G.IsLocallyFull K] {ℱ : Dᵒᵖ ⥤ A} {ℱ' : Sheaf K A} @@ -506,6 +509,7 @@ instance full_sheafPushforwardContinuous [G.IsContinuous J K] : Full (G.sheafPushforwardContinuous A J K) where map_surjective α := ⟨⟨sheafHom α.hom⟩, Sheaf.hom_ext <| sheafHom_restrict_eq α.hom⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance faithful_sheafPushforwardContinuous [G.IsContinuous J K] : Faithful (G.sheafPushforwardContinuous A J K) where @@ -706,6 +710,7 @@ noncomputable def sheafifyHomEquivOfIsEquivalence ((G.sheafPushforwardContinuous A J K).asEquivalence.symm.toAdjunction.homEquiv _ _).trans (((sheafificationAdjunction J A).homEquiv _ _).trans IsCoverDense.restrictHomEquivHom) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma sheafifyHomEquivOfIsEquivalence_naturality_left {P₁ P₂ : Dᵒᵖ ⥤ A} (f : P₁ ⟶ P₂) {Q : Sheaf K A} @@ -728,6 +733,7 @@ lemma sheafifyHomEquivOfIsEquivalence_naturality_left apply adj₁.homEquiv_naturality_left · apply adj₂.homEquiv_naturality_left +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma sheafifyHomEquivOfIsEquivalence_naturality_right {P : Dᵒᵖ ⥤ A} {Q₁ Q₂ : Sheaf K A} diff --git a/Mathlib/CategoryTheory/Sites/DenseSubsite/OneHypercoverDense.lean b/Mathlib/CategoryTheory/Sites/DenseSubsite/OneHypercoverDense.lean index 17fa80dbcdf032..e74f7a05039cb4 100644 --- a/Mathlib/CategoryTheory/Sites/DenseSubsite/OneHypercoverDense.lean +++ b/Mathlib/CategoryTheory/Sites/DenseSubsite/OneHypercoverDense.lean @@ -97,6 +97,7 @@ def multicospanIndex (P : C₀ᵒᵖ ⥤ A) : MulticospanIndex data.multicospanS fst j := P.map ((data.p₁ j.2).op) snd j := P.map ((data.p₂ j.2).op) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functoriality of the diagrams attached to `data : F.PreOneHypercoverDenseData X` with respect to morphisms in `C₀ᵒᵖ ⥤ A`. -/ @@ -213,6 +214,7 @@ section variable {X : C} (data : OneHypercoverDenseData.{w} F J₀ J X) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma mem₁ (i₁ i₂ : data.I₀) {W : C} (p₁ : W ⟶ F.obj (data.X i₁)) (p₂ : W ⟶ F.obj (data.X i₂)) (w : p₁ ≫ data.f i₁ = p₂ ≫ data.f i₂) : data.toPreOneHypercover.sieve₁ p₁ p₂ ∈ J W := by @@ -340,6 +342,7 @@ private lemma liftAux_fac {i : (data X).I₀} {W₀ : C₀} (a : W₀ ⟶ (data liftAux hG₀ s i ≫ G.map (F.map a).op = s.ι ⟨_, F.map a ≫ (data X).f i, ha⟩ := hG₀.amalgamate_map _ _ _ ⟨W₀, a, ha⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for the lemma `OneHypercoverDenseData.isSheaf_iff`. -/ private noncomputable def lift : s.pt ⟶ G.obj (op X) := @@ -359,6 +362,7 @@ private noncomputable def lift : s.pt ⟶ G.obj (op X) := congr 2 rw [map_comp_assoc, map_comp_assoc, (data X).w j]) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] private lemma lift_map (i : (data X).I₀) : lift hG₀ hG s ≫ G.map ((data X).f i).op = liftAux hG₀ s i := @@ -553,6 +557,7 @@ noncomputable def restriction {X : C} {X₀ : C₀} (f : F.obj X₀ ⟶ X) : apply presheafObj_mapPreimage_condition simp only [assoc, h₁.fac, h₂.fac, ← Functor.map_comp_assoc, w]) +set_option backward.isDefEq.respectTransparency.types false in lemma restriction_map {X : C} {X₀ : C₀} (f : F.obj X₀ ⟶ X) {Y₀ : C₀} (g : Y₀ ⟶ X₀) {i : (data X).I₀} (p : F.obj Y₀ ⟶ F.obj ((data X).X i)) (fac : p ≫ (data X).f i = F.map g ≫ f) : @@ -571,6 +576,7 @@ lemma restriction_eq_of_fac {X : C} {X₀ : C₀} (f : F.obj X₀ ⟶ X) presheafObjπ data G₀ X i ≫ IsDenseSubsite.mapPreimage J F G₀ p := by simpa using restriction_map data G₀ f (𝟙 _) p (by simpa using fac) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `OneHypercoverDenseData.essSurj.presheaf`. -/ noncomputable def presheafMap {X Y : C} (f : X ⟶ Y) : @@ -587,6 +593,7 @@ noncomputable def presheafMap {X Y : C} (f : X ⟶ Y) : rw [restriction_map (p := p), restriction_map (p := p)] all_goals simp_all) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma presheafMap_π {X Y : C} (f : X ⟶ Y) (i : (data X).I₀) : presheafMap data G₀ f ≫ presheafObjπ data G₀ X i = @@ -646,7 +653,7 @@ lemma presheafMap_comp {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : be a family. Let `G₀` be a sheaf on `C₀`. This is a presheaf on `C` which extends `G₀` (see `OneHypercoverDenseData.essSurj.compPresheafIso`) and it is a sheaf (see `OneHypercoverDenseData.essSurj.isSheaf`). -/ -@[simps] +@[simps, implicit_reducible] noncomputable def presheaf : Cᵒᵖ ⥤ A where obj X := presheafObj data G₀ X.unop map f := presheafMap data G₀ f.unop @@ -677,6 +684,9 @@ noncomputable def hom : (presheaf data G₀).obj (op (F.obj X₀)) ⟶ G₀.obj. variable {X₀} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma hom_map {W₀ : C₀} (a : W₀ ⟶ X₀) {i : (data (F.obj X₀)).I₀} (p : F.obj W₀ ⟶ F.obj ((data (F.obj X₀)).X i)) @@ -689,6 +699,7 @@ lemma hom_map {W₀ : C₀} (a : W₀ ⟶ X₀) {i : (data (F.obj X₀)).I₀} (presheafObj_mapPreimage_condition _ _ _ _ _ _ _ ((Sieve.ofArrows.fac ha).trans fac.symm)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma hom_mapPreimage {W₀ : C₀} (a : F.obj W₀ ⟶ F.obj X₀) {i : (data (F.obj X₀)).I₀} @@ -706,6 +717,7 @@ lemma hom_mapPreimage {W₀ : C₀} (a : F.obj W₀ ⟶ F.obj X₀) {i : (data ( variable (X₀) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `OneHypercoverDenseData.essSurj.presheafObjObjIso`. -/ noncomputable def inv : G₀.obj.obj (op X₀) ⟶ (presheaf data G₀).obj (op (F.obj X₀)) := @@ -783,11 +795,13 @@ lemma presheafObjObjIso_inv_naturality {X₀ Y₀ : C₀} (f : X₀ ⟶ Y₀) : simp [presheafObjObjIso, IsDenseSubsite.mapPreimage_comp] +set_option backward.isDefEq.respectTransparency.types false in /-- The presheaf `presheaf data G₀` extends `G₀`. -/ noncomputable def compPresheafIso : F.op ⋙ presheaf data G₀ ≅ G₀.obj := (NatIso.ofComponents (fun _ ↦ (presheafObjObjIso data G₀ _).symm) (fun f ↦ presheafObjObjIso_inv_naturality data G₀ f.unop)).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isSheaf : Presheaf.IsSheaf J (presheaf data G₀) := by rw [isSheaf_iff data] diff --git a/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean b/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean index 25a9d3550f1cc0..ae3a87b0b79b43 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/DescentData.lean @@ -162,7 +162,7 @@ def isoMk {D₁ D₂ : F.DescentData f} (e : ∀ (i : ι), D₁.obj i ≅ D₂.o end DescentData -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `F.obj (.mk (op S)) ⥤ F.DescentData f`. -/ @[simps] def toDescentData : F.obj (.mk (op S)) ⥤ F.DescentData f where @@ -334,6 +334,7 @@ def pullFunctorIdIso : rw [pullFunctorObjHom_eq_assoc _ _ _ _ _ q f₁ f₂ rfl] simp [mapComp'_id_comp_inv_app_assoc, mapComp'_id_comp_hom_app, ← Functor.map_comp])) +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of two functors `pullFunctor` is isomorphic to `pullFunctor` applied to the compositions. -/ @[simps!] @@ -557,6 +558,7 @@ lemma bijective_toDescentData_map_iff (M N : F.obj (.mk (op S))) : ext φ : 1 apply DescentData.subtypeCompatibleHomEquiv_toCompatible_presheafHomObjHomEquiv +set_option backward.isDefEq.respectTransparency.types false in lemma isPrestackFor_iff_isSheafFor {S : C} (R : Sieve S) : F.IsPrestackFor R.arrows ↔ ∀ (M N : F.obj (.mk (op S))), Presieve.IsSheafFor (P := F.presheafHom M N) @@ -573,6 +575,7 @@ lemma isPrestackFor_iff_isSheafFor {S : C} (R : Sieve S) : · rintro _ _ ⟨_, h⟩ exact h +set_option backward.isDefEq.respectTransparency.types false in lemma isPrestackFor_iff_isSheafFor' {S : C} (R : Sieve S) : F.IsPrestackFor R.arrows ↔ ∀ ⦃S₀ : C⦄ (M N : F.obj (.mk (op S₀))) (a : S ⟶ S₀), Presieve.IsSheafFor (F.presheafHom M N) ((Sieve.overEquiv (Over.mk a)).symm R).arrows := by @@ -606,6 +609,7 @@ lemma IsPrestackFor.isSheafFor' variable {J : GrothendieckTopology C} +set_option backward.isDefEq.respectTransparency.types false in /-- If `F` is a prestack for a Grothendieck topology `J`, and `f` is a covering family of morphisms, then the functor `F.toDescentData f` is fully faithful. -/ noncomputable def fullyFaithfulToDescentData [F.IsPrestack J] (hf : Sieve.ofArrows _ f ∈ J S) : diff --git a/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean b/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean index 5b0e89099de81c..151bea4e7600cb 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean @@ -76,6 +76,9 @@ structure DescentDataAsCoalgebra namespace DescentDataAsCoalgebra +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in attribute [reassoc (attr := simp)] counit coassoc section diff --git a/Mathlib/CategoryTheory/Sites/Descent/DescentDataPrime.lean b/Mathlib/CategoryTheory/Sites/Descent/DescentDataPrime.lean index 66f62c5b424931..5a4f9c26deb728 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/DescentDataPrime.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/DescentDataPrime.lean @@ -318,6 +318,7 @@ noncomputable def fromDescentDataFunctor : F.DescentData f ⥤ F.DescentData' sq obj D := .ofDescentData _ _ D map φ := { hom := φ.hom } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `F.DescentData' sq sq₃ ≌ F.DescentData f`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Sites/Descent/IsPrestack.lean b/Mathlib/CategoryTheory/Sites/Descent/IsPrestack.lean index 5b6a94384c8388..642d77d87deb22 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/IsPrestack.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/IsPrestack.lean @@ -121,7 +121,7 @@ variable (F) {S : C} (M N : F.obj (.mk (op S))) `F.obj (.mk (op S))`, this is the presheaf of morphisms from `M` to `N`: it sends an object `T : Over S` corresponding to a morphism `p : X ⟶ S` to the type of morphisms $p^* M ⟶ p^* N$. -/ -@[simps] +@[simps, implicit_reducible] def presheafHom : (Over S)ᵒᵖ ⥤ Type v' where obj T := (F.map (.toLoc T.unop.hom.op)).toFunctor.obj M ⟶ (F.map (.toLoc T.unop.hom.op)).toFunctor.obj N diff --git a/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean b/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean index 79b9cb7a7cedaf..15eccbed1bfd6d 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/Precoverage.lean @@ -198,6 +198,7 @@ lemma mor_unique ⦃i : ι⦄ {Z : C} (q : Z ⟶ X i) rw [mor_eq _ _ _ _ _ _ _ rfl rfl, mor_eq _ _ _ _ _ _ _ rfl rfl, this] simp +set_option backward.isDefEq.respectTransparency.types false in /-- Given two family of morphisms `f : X i ⟶ S` and `f' : X' j ⟶ S`, two objects `D₁ D₂ : F.DescentData f`, a morphism `φ` between the images in `F.DescentData f'` of `D₁` and `D₂` by a functor `pullFunctor`. This is @@ -212,6 +213,7 @@ noncomputable def familyOfElements (i : ι) : ext simpa using (Over.w q).symm)) +set_option backward.isDefEq.respectTransparency.types false in lemma familyOfElements_eq {i : ι} {Z : Over (X i)} (g : Z ⟶ Over.mk (𝟙 (X i))) ⦃j : ι'⦄ (a : Z.left ⟶ X' j) (fac : a ≫ f' j = Z.hom ≫ f i := by cat_disch) : familyOfElements w φ i g (by @@ -299,6 +301,7 @@ end full_pullFunctor public section +set_option backward.isDefEq.respectTransparency.types false in open full_pullFunctor in include w hf' in lemma full_pullFunctor : @@ -378,6 +381,7 @@ section variable {F} [HasPullbacks C] {J : Precoverage C} [J.HasIsos] [J.IsStableUnderBaseChange] [J.IsStableUnderComposition] +set_option backward.isDefEq.respectTransparency.types false in /-- If a precoverage satisfies `HasIsos`, `IsStableUnderBaseChange` and `IsStableUnderComposition` (which is a slightly stronger condition as compared to pretopologies), then in order to check that a pseudofunctor is a prestack diff --git a/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean b/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean index 7f49ecb19f8495..d5388f489c1627 100644 --- a/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean +++ b/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean @@ -81,6 +81,7 @@ lemma Presieve.EffectiveEpimorphic.isSheafFor_of_isRepresentable {X : C} {R : Pr rw [isSheafFor_comp_uliftFunctor_iff] exact hR _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Implementation: This is a construction which will be used in the proof that @@ -195,6 +196,7 @@ lemma Sieve.generateFamily_eq {B : C} {α : Type*} (X : α → C) (π : (a : α) · rintro ⟨a, g, rfl⟩ exact ⟨_, g, π a, ⟨a⟩, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Implementation: This is a construction which will be used in the proof that diff --git a/Mathlib/CategoryTheory/Sites/EpiMono.lean b/Mathlib/CategoryTheory/Sites/EpiMono.lean index a4411fc6f553a6..4ef669812474ff 100644 --- a/Mathlib/CategoryTheory/Sites/EpiMono.lean +++ b/Mathlib/CategoryTheory/Sites/EpiMono.lean @@ -27,7 +27,7 @@ universe w v' u' v u namespace CategoryTheory -open Category ConcreteCategory Functor +open Category ConcreteCategory CategoryTheory.Functor variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) (A : Type u') [Category.{v'} A] {FA : A → A → Type*} {CA : A → Type w} diff --git a/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean b/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean index 120b4161042a90..b71f4dbd6b4d2f 100644 --- a/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean +++ b/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean @@ -68,6 +68,7 @@ lemma FirstObj.ext (z₁ z₂ : FirstObj P R) (h : ∀ (Y : C) (f : Y ⟶ X) variable (P R) +set_option backward.isDefEq.respectTransparency.types false in /-- Show that `FirstObj` is isomorphic to `FamilyOfElements`. -/ @[simps] def firstObjEqFamily : FirstObj P R ≅ (R.FamilyOfElements P) where @@ -148,6 +149,7 @@ theorem compatible_iff (x : FirstObj P S.arrows) : rw [Types.limit_ext_iff'] at t simpa [firstMap, secondMap] using t ⟨⟨Y, Z, g, f, hf⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- `P` is a sheaf for `S`, iff the fork given by `w` is an equalizer. -/ theorem equalizer_sheaf_condition : Presieve.IsSheafFor P (S : Presieve X) ↔ Nonempty (IsLimit (Fork.ofι _ (w P S))) := by @@ -235,6 +237,7 @@ theorem compatible_iff (x : FirstObj P R) : rw [Types.limit_ext_iff'] at t simpa [firstMap, secondMap] using t ⟨⟨⟨Y, f, hf⟩, Z, g, hg⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- `P` is a sheaf for `R`, iff the fork given by `w` is an equalizer. -/ @[stacks 00VM] theorem sheaf_condition : R.IsSheafFor P ↔ Nonempty (IsLimit (Fork.ofι _ (w P R))) := by @@ -352,6 +355,7 @@ lemma compatible_iff_of_small (x : FirstObj P X) : · apply_fun Pi.π (fun (ij : I × I) ↦ P.obj (op (pullback (π ij.1) (π ij.2)))) ⟨i, j⟩ at t simpa [firstMap, secondMap] using t +set_option backward.isDefEq.respectTransparency.types false in /-- `P` is a sheaf for `Presieve.ofArrows X π`, iff the fork given by `w` is an equalizer. -/ @[stacks 00VM] theorem sheaf_condition : (Presieve.ofArrows X π).IsSheafFor P ↔ diff --git a/Mathlib/CategoryTheory/Sites/Equivalence.lean b/Mathlib/CategoryTheory/Sites/Equivalence.lean index 5925f220ae84e9..221c0f27a6c64e 100644 --- a/Mathlib/CategoryTheory/Sites/Equivalence.lean +++ b/Mathlib/CategoryTheory/Sites/Equivalence.lean @@ -44,7 +44,7 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ w namespace CategoryTheory -open Functor Limits GrothendieckTopology +open CategoryTheory.Functor Limits GrothendieckTopology variable {C : Type u₁} [Category.{v₁} C] (J : GrothendieckTopology C) variable {D : Type u₂} [Category.{v₂} D] (K : GrothendieckTopology D) (e : C ≌ D) (G : D ⥤ C) @@ -63,7 +63,6 @@ instance (priority := 900) [G.IsEquivalence] : IsCoverDense G J where replace := Sieve.downward_closed _ this (e.unit.app Y) simpa [g] using! this -set_option backward.isDefEq.respectTransparency false in instance : e.functor.IsDenseSubsite J (e.inverse.inducedTopology J) := by have : J = e.functor.inducedTopology (e.inverse.inducedTopology J) := by ext @@ -119,6 +118,7 @@ def sheafCongr.inverse : Sheaf K A ⥤ Sheaf J A := (sheafToPresheaf _ _ ⋙ (Functor.whiskeringLeft _ _ _).obj e.functor.op) (e.functor.op_comp_isSheaf _ _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The unit iso in the equivalence of sheaf categories. -/ @[simps!] @@ -126,6 +126,7 @@ def sheafCongr.unitIso : 𝟭 (Sheaf J A) ≅ functor J K e A ⋙ inverse J K e NatIso.ofComponents (fun F ↦ ObjectProperty.isoMk _ (isoWhiskerRight e.op.unitIso F.obj)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit iso in the equivalence of sheaf categories. -/ @[simps!] @@ -133,6 +134,7 @@ def sheafCongr.counitIso : inverse J K e A ⋙ functor J K e A ≅ 𝟭 (Sheaf _ NatIso.ofComponents (fun F ↦ ObjectProperty.isoMk _ (isoWhiskerRight e.op.counitIso F.obj)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of sheaf categories. -/ @[simps] @@ -152,6 +154,7 @@ noncomputable def transportAndSheafify : (Cᵒᵖ ⥤ A) ⥤ Sheaf J A := e.op.congrLeft.functor ⋙ presheafToSheaf _ _ ⋙ (e.sheafCongr J K A).inverse +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An auxiliary definition for the sheafification adjunction. -/ noncomputable diff --git a/Mathlib/CategoryTheory/Sites/GlobalSections.lean b/Mathlib/CategoryTheory/Sites/GlobalSections.lean index 8f4dc66c773516..9d1bb0ed58be3f 100644 --- a/Mathlib/CategoryTheory/Sites/GlobalSections.lean +++ b/Mathlib/CategoryTheory/Sites/GlobalSections.lean @@ -138,6 +138,7 @@ noncomputable def Sheaf.coneΓ [HasGlobalSectionsFunctor J A] (F : Sheaf J A) : pt := (Γ J A).obj F π := ΓHomEquiv.symm (𝟙 _) +set_option backward.isDefEq.respectTransparency.types false in /-- The global sections cone `Sheaf.coneΓ` is limiting - that is, global sections are limits even when not all limits of shape `Cᵒᵖ` exist in `A`. -/ noncomputable def Sheaf.isLimitConeΓ [HasGlobalSectionsFunctor J A] (F : Sheaf J A) : diff --git a/Mathlib/CategoryTheory/Sites/Grothendieck.lean b/Mathlib/CategoryTheory/Sites/Grothendieck.lean index 17ed2107ce3116..f9fd39dca663b8 100644 --- a/Mathlib/CategoryTheory/Sites/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/Grothendieck.lean @@ -486,6 +486,7 @@ corresponding to `g ≫ I.f`. -/ def Arrow.precomp {S : J.Cover X} (I : S.Arrow) {Z : C} (g : Z ⟶ I.Y) : S.Arrow := ⟨Z, g ≫ I.f, S.1.downward_closed I.hf g⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Given `I : S.Arrow` and a morphism `g : Z ⟶ I.Y`, this is the obvious relation from `I.precomp g` to `I`. -/ @[simps] @@ -630,6 +631,7 @@ def index {D : Type u₁} [Category.{v₁} D] (S : J.Cover X) (P : Cᵒᵖ ⥤ D fst I := P.map I.r.g₁.op snd I := P.map I.r.g₂.op +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural multifork associated to `S : J.Cover X` for a presheaf `P`. Saying that this multifork is a limit is essentially equivalent to the sheaf condition at the diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/Homotopy.lean b/Mathlib/CategoryTheory/Sites/Hypercover/Homotopy.lean index 8a9f7185d7359a..6179996d2c6fd0 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/Homotopy.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/Homotopy.lean @@ -251,6 +251,7 @@ namespace OneHypercover variable {S : C} {E : OneHypercover.{w} J S} {F : OneHypercover.{w'} J S} variable [HasPullbacks C] +set_option backward.isDefEq.respectTransparency.types false in /-- Given two refinement morphism `f, g : E ⟶ F`, this is a `1`-hypercover `W` that admits a morphism `h : W ⟶ E` such that `h ≫ f` and `h ≫ g` are homotopic. Hence they become equal after quotienting out by homotopy. -/ diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/IsSheaf.lean b/Mathlib/CategoryTheory/Sites/Hypercover/IsSheaf.lean index 7ee4e8c72b323a..c8d33c74b19e5a 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/IsSheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/IsSheaf.lean @@ -154,6 +154,7 @@ end OneHypercoverFamily abbrev IsGeneratedByOneHypercovers : Prop := OneHypercoverFamily.IsGenerating.{w} (J := J) ⊤ +set_option backward.isDefEq.respectTransparency.types false in instance : IsGeneratedByOneHypercovers.{max u v} J where le S hS := ⟨Cover.oneHypercover ⟨S, hS⟩, by simp, by simp⟩ diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/One.lean b/Mathlib/CategoryTheory/Sites/Hypercover/One.lean index 34dc55c02f00b1..623ec9b6aef1a3 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/One.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/One.lean @@ -146,6 +146,7 @@ def multicospanIndex (F : Cᵒᵖ ⥤ A) : MulticospanIndex E.multicospanShape A fst j := F.map ((E.p₁ j.2).op) snd j := F.map ((E.p₂ j.2).op) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The multifork attached to a presheaf `F : Cᵒᵖ ⥤ A`, `S : C` and `E : PreOneHypercover S`. -/ def multifork (F : Cᵒᵖ ⥤ A) : @@ -171,6 +172,7 @@ def forkOfIsColimit {c : Cofan E.X} (hc : IsColimit c) {d : Cofan E.Y'} (hd : Is congr 2 exact Cofan.IsColimit.hom_ext hd _ _ (by simp [E.w]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma forkOfIsColimit_ι_map_inj {c : Cofan E.X} (hc : IsColimit c) {d : Cofan E.Y'} @@ -265,6 +267,7 @@ def isLimitSigmaOfIsColimitEquiv {c : Cofan E.X} (hc : IsColimit c) {d : Cofan E · exact fun _ ↦ .refl _ all_goals cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The trivial pre-`1`-hypercover of `S` with a single component `S`. -/ @[simps toPreZeroHypercover I₁ Y p₁ p₂] @@ -276,15 +279,18 @@ def trivial (S : C) : PreOneHypercover.{w} S where p₂ _ _ _ := 𝟙 _ w _ _ _ := by simp +set_option backward.isDefEq.respectTransparency.types false in lemma sieve₀_trivial (S : C) : (trivial S).sieve₀ = ⊤ := by rw [PreZeroHypercover.sieve₀, Sieve.ofArrows, ← PreZeroHypercover.presieve₀] simp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma sieve₁_trivial {S : C} {W : C} {p : W ⟶ S} : (trivial S).sieve₁ (i₁ := ⟨⟩) (i₂ := ⟨⟩) p p = ⊤ := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in instance : Nonempty (PreOneHypercover.{w} S) := ⟨trivial S⟩ section @@ -389,6 +395,7 @@ def Hom.comp (f : E.Hom F) (g : F.Hom G) : E.Hom G where def Hom.s₁' (f : E.Hom F) (k : E.I₁') : F.I₁' := ⟨⟨f.s₀ k.1.1, f.s₀ k.1.2⟩, f.s₁ k.2⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps! id_s₀ id_s₁ id_h₀ id_h₁ comp_s₀ comp_s₁ comp_h₀ comp_h₁] instance : Category (PreOneHypercover S) where @@ -396,12 +403,14 @@ instance : Category (PreOneHypercover S) where id E := Hom.id E comp f g := f.comp g +set_option backward.isDefEq.respectTransparency.types false in /-- The forgetful functor from pre-`1`-hypercovers to pre-`0`-hypercovers. -/ @[simps] def oneToZero : PreOneHypercover.{w} S ⥤ PreZeroHypercover.{w} S where obj f := f.1 map f := f.1 +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A refinement morphism `E ⟶ F` induces a morphism on associated multiequalizers. -/ def Hom.mapMultiforkOfIsLimit (f : E.Hom F) (P : Cᵒᵖ ⥤ A) {c : Multifork (E.multicospanIndex P)} @@ -526,18 +535,21 @@ lemma congrIndexOneOfEqIso_refl {i j : E.I₀} (k : E.I₁ i j) : E.congrIndexOneOfEqIso rfl rfl k = Iso.refl _ := by simp [congrIndexOneOfEqIso] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma congrIndexOneOfEqIso_hom_p₁ (k : E.I₁ i j) : (E.congrIndexOneOfEqIso hii' hjj' k).hom ≫ E.p₁ _ = E.p₁ _ ≫ eqToHom (by rw [hii']) := by subst hii' hjj' simp [congrIndexOneOfEqIso, congrIndexOneOfEq] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma congrIndexOneOfEqIso_inv_p₁ (k : E.I₁ i j) : (E.congrIndexOneOfEqIso hii' hjj' k).inv ≫ E.p₁ _ = E.p₁ k ≫ eqToHom (by rw [hii']) := by subst hii' hjj' simp [congrIndexOneOfEqIso, congrIndexOneOfEq] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma congrIndexOneOfEqIso_inv_p₂ (k : E.I₁ i j) : (E.congrIndexOneOfEqIso hii' hjj' k).inv ≫ E.p₂ _ = E.p₂ k ≫ eqToHom (by rw [hjj']) := by @@ -549,6 +561,7 @@ variable {i i' j j' : E.I₀} (u₀ : E.I₀ → F.I₀) (z : ∀ i j (k : E.I₁ i j), E.Y k ⟶ F.Y (u₁ i j k)) (hii' : i = i') (hjj' : j = j') (k : E.I₁ i j) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma congrIndexOneOfEqIso_hom_naturality : (E.congrIndexOneOfEqIso hii' hjj' k).hom ≫ @@ -558,6 +571,7 @@ lemma congrIndexOneOfEqIso_hom_naturality : subst hii' hjj' simp [congrIndexOneOfEqIso, congrIndexOneOfEq] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma congrIndexOneOfEqIso_inv_naturality : (E.congrIndexOneOfEqIso hii' hjj' k).inv ≫ @@ -697,38 +711,45 @@ section variable {S : C} {E F : PreOneHypercover.{w} S} (e : E ≅ F) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma hom_inv_s₀_apply (i : E.I₀) : e.inv.s₀ (e.hom.s₀ i) = i := congr($(e.hom_inv_id).s₀ i) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inv_hom_s₀_apply (i : F.I₀) : e.hom.s₀ (e.inv.s₀ i) = i := congr($(e.inv_hom_id).s₀ i) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma hom_inv_s₁_apply {i j : E.I₀} (k : E.I₁ i j) : e.inv.s₁ (e.hom.s₁ k) = E.congrIndexOneOfEq (by simp) (by simp) k := by obtain ⟨hs₀, hh₀, hs₁, hh₁⟩ := PreOneHypercover.Hom.ext'_iff.mp e.hom_inv_id simpa using! hs₁ i j k +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma inv_hom_s₁_apply {i j : F.I₀} (k : F.I₁ i j) : e.hom.s₁ (e.inv.s₁ k) = F.congrIndexOneOfEq (by simp) (by simp) k := by obtain ⟨hs₀, hh₀, hs₁, hh₁⟩ := PreOneHypercover.Hom.ext'_iff.mp e.inv_hom_id simpa using! hs₁ i j k +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma hom_inv_h₀ (i : E.I₀) : e.hom.h₀ i ≫ e.inv.h₀ (e.hom.s₀ i) = eqToHom (by simp) := by obtain ⟨hs, hh, _⟩ := Hom.ext'_iff.mp e.hom_inv_id simpa using hh i +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma inv_hom_h₀ (i : F.I₀) : e.inv.h₀ i ≫ e.hom.h₀ (e.inv.s₀ i) = eqToHom (by simp) := by obtain ⟨hs, hh, _⟩ := Hom.ext'_iff.mp e.inv_hom_id simpa using hh i +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma hom_inv_h₁ {i j : E.I₀} (k : E.I₁ i j) : @@ -738,6 +759,7 @@ lemma hom_inv_h₁ {i j : E.I₀} (k : E.I₁ i j) : obtain ⟨hs, _, _, hh⟩ := Hom.ext'_iff.mp e.hom_inv_id simpa using hh i j k +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma inv_hom_h₁ {i j : F.I₀} (k : F.I₁ i j) : @@ -747,15 +769,18 @@ lemma inv_hom_h₁ {i j : F.I₀} (k : F.I₁ i j) : obtain ⟨hs, _, _, hh⟩ := Hom.ext'_iff.mp e.inv_hom_id simpa using hh i j k +set_option backward.isDefEq.respectTransparency.types false in instance (i : E.I₀) : IsIso (e.hom.h₀ i) := by use e.inv.h₀ (e.hom.s₀ i) ≫ eqToHom (by simp) rw [PreOneHypercover.hom_inv_h₀_assoc, eqToHom_trans, eqToHom_refl, Category.assoc, ← eqToHom_naturality _ (by simp), PreOneHypercover.inv_hom_h₀_assoc] simp +set_option backward.isDefEq.respectTransparency.types false in instance (i : F.I₀) : IsIso (e.inv.h₀ i) := .of_isIso_fac_right (PreOneHypercover.inv_hom_h₀ e i) +set_option backward.isDefEq.respectTransparency.types false in instance {i j : E.I₀} (k : E.I₁ i j) : IsIso (e.hom.h₁ k) := by use e.inv.h₁ _ ≫ eqToHom (by congr 1; simp) ≫ (E.congrIndexOneOfEqIso (by simp) (by simp) k).hom simp only [PreOneHypercover.hom_inv_h₁_assoc, eqToHom_trans_assoc, eqToHom_refl, Category.id_comp, @@ -763,6 +788,7 @@ instance {i j : E.I₀} (k : E.I₁ i j) : IsIso (e.hom.h₁ k) := by rw [← eqToHom_naturality_assoc _ (by simp)] simp +set_option backward.isDefEq.respectTransparency.types false in instance {i j : F.I₀} (k : F.I₁ i j) : IsIso (e.inv.h₁ k) := .of_isIso_fac_right (PreOneHypercover.inv_hom_h₁ e k) @@ -770,6 +796,7 @@ end section +set_option backward.isDefEq.respectTransparency.types false in /-- A refinement morphism `E ⟶ F` induces a functor between the multifork indexing categories. -/ @[simps] def Hom.mapMulticospan {E : PreOneHypercover.{w} S} {F : PreOneHypercover.{w'} S} (f : E.Hom F) : @@ -930,6 +957,7 @@ section variable {E F} variable (c : Multifork (E.multicospanIndex F.obj)) +set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition of `isLimitMultifork`. -/ noncomputable def multiforkLift : c.pt ⟶ F.obj.obj (Opposite.op S) := F.property.amalgamateOfArrows _ E.mem₀ c.ι (fun W i₁ i₂ p₁ p₂ w => by @@ -940,12 +968,14 @@ noncomputable def multiforkLift : c.pt ⟶ F.obj.obj (Opposite.op S) := simp only [op_comp, Functor.map_comp] simpa using! c.condition ⟨⟨i₁, i₂⟩, j⟩ =≫ F.obj.map h.op) +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma multiforkLift_map (i₀ : E.I₀) : multiforkLift c ≫ F.obj.map (E.f i₀).op = c.ι i₀ := by simp [multiforkLift] end +set_option backward.isDefEq.respectTransparency.types false in /-- If `E : J.OneHypercover S` and `F : Sheaf J A`, then `F.obj (op S)` is a multiequalizer of suitable maps `F.obj (op (E.X i)) ⟶ F.obj (op (E.Y j))` induced by `E.p₁ j` and `E.p₂ j`. -/ @@ -985,6 +1015,7 @@ def trivial (S : C) : OneHypercover.{w} J S where instance (S : C) : Nonempty (J.OneHypercover S) := ⟨trivial J S⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Intersection of two `1`-hypercovers. -/ @[simps toPreOneHypercover] noncomputable @@ -1010,6 +1041,7 @@ variable {S : C} {E : OneHypercover.{w} J S} {F : OneHypercover.{w'} J S} abbrev Hom (E : OneHypercover.{w} J S) (F : OneHypercover.{w'} J S) := E.toPreOneHypercover.Hom F.toPreOneHypercover +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps! id_s₀ id_s₁ id_h₀ id_h₁ comp_s₀ comp_s₁ comp_h₀ comp_h₁] instance : Category (J.OneHypercover S) where @@ -1017,6 +1049,7 @@ instance : Category (J.OneHypercover S) where id E := PreOneHypercover.Hom.id E.toPreOneHypercover comp f g := f.comp g +set_option backward.isDefEq.respectTransparency.types false in /-- An isomorphism of `1`-hypercovers is an isomorphism of pre-`1`-hypercovers. -/ @[simps] def isoMk {E F : J.OneHypercover S} (f : E.toPreOneHypercover ≅ F.toPreOneHypercover) : @@ -1061,6 +1094,7 @@ lemma preOneHypercover_sieve₁ (f₁ f₂ : S.Arrow) {W : C} (p₁ : W ⟶ f₁ simp only [Sieve.top_apply, iff_true] exact ⟨{ w := w, .. }, f, rfl, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The tautological 1-hypercover induced by `S : J.Cover X`. Its index type `I₀` is given by `S.Arrow` (i.e. all the morphisms in the sieve `S`), while `I₁` is given by all possible pullback cones. -/ @@ -1099,6 +1133,7 @@ instance {S : C} (E : PreZeroHypercover S) [E.HasPullbacks] : dsimp infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma sieve₁'_toPreOneHypercover_eq_top {S : C} (E : PreZeroHypercover S) [E.HasPullbacks] @@ -1110,6 +1145,7 @@ lemma sieve₁'_toPreOneHypercover_eq_top {S : C} (E : PreZeroHypercover S) [E.H refine Presieve.ofArrows.mk' ⟨⟩ rfl ?_ apply pullback.hom_ext <;> simp [PreOneHypercover.toPullback] +set_option backward.isDefEq.respectTransparency.types false in /-- If the pairwise pullbacks exist, this is the pre-`1`-hypercover where the covers by the pullbacks are given by the pullbacks themselves. -/ @[simps! toPreOneHypercover] diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/Saturate.lean b/Mathlib/CategoryTheory/Sites/Hypercover/Saturate.lean index 7ba01ed3e2b1e1..f863c5d421daba 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/Saturate.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/Saturate.lean @@ -68,6 +68,7 @@ lemma isLimit_saturate_type_iff {S : C} (E : PreZeroHypercover S) (F : Cᵒᵖ ← Function.Bijective.of_comp_iff' (E.sectionsSaturateEquiv F).symm.bijective] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `E` has pairwise pullbacks, this is the canonical map from the minimal `1`-hypercover to the saturation. -/ @@ -94,6 +95,7 @@ def fromSaturateOfHasPullbacks {S : C} (E : PreZeroHypercover S) variable {S : C} (E : PreZeroHypercover S) [E.HasPullbacks] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The identity of the minimal pre-`1`-hypercover when `E` has pairwise pullbacks is homotopic to itself. -/ @@ -108,6 +110,7 @@ def toPreOneHypercoverHomotopy {S : C} (E : PreZeroHypercover S) variable {S : C} (E : PreZeroHypercover S) [E.HasPullbacks] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma toSaturateOfHasPullbacks_fromSaturateOfHasPullbacks : diff --git a/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean b/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean index 78d156f96d8089..012029bb10ca77 100644 --- a/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean +++ b/Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean @@ -176,6 +176,9 @@ def reindex (E : PreZeroHypercover.{w} T) {ι : Type w'} (e : ι ≃ E.I₀) : lemma presieve₀_reindex {ι : Type w'} (e : ι ≃ E.I₀) : (E.reindex e).presieve₀ = E.presieve₀ := by simp [reindex] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Pairwise intersection of two pre-`0`-hypercovers. -/ @[simps!] noncomputable @@ -231,12 +234,13 @@ def add (E : PreZeroHypercover.{w} S) {T : C} (f : T ⟶ S) : PreZeroHypercover. @[simp] lemma add_f_nome {T : C} (f : T ⟶ S) : (E.add f).f none = f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma presieve₀_add {T : C} (f : T ⟶ S) : (E.add f).presieve₀ = E.presieve₀ ⊔ .singleton f := by simp [add, presieve₀_reindex, presieve₀_sum] /-- The single object pre-`0`-hypercover obtained from taking the coproduct of the components. -/ -@[simps I₀ X, simps -isSimp f] +@[simps I₀ X, simps -isSimp f, implicit_reducible] def sigmaOfIsColimit (E : PreZeroHypercover.{w} S) {c : Cofan E.X} (hc : IsColimit c) : PreZeroHypercover.{w} S where I₀ := PUnit @@ -284,6 +288,7 @@ def Hom.comp (f : E.Hom F) (g : F.Hom G) : E.Hom G where s₀ := g.s₀ ∘ f.s₀ h₀ i := f.h₀ i ≫ g.h₀ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps! id_s₀ id_h₀ comp_s₀ comp_h₀] instance : Category (PreZeroHypercover S) where @@ -497,6 +502,7 @@ def sumLift (f : E.Hom G) (g : F.Hom G) : (E.sum F).Hom G where variable [∀ (i : E.I₀) (j : F.I₀), HasPullback (E.f i) (F.f j)] +set_option backward.isDefEq.respectTransparency.types false in /-- First projection from the intersection of two pre-`0`-hypercovers. -/ @[simps] noncomputable @@ -525,6 +531,7 @@ def interLift (f : G.Hom E) (g : G.Hom F) : s₀ i := ⟨f.s₀ i, g.s₀ i⟩ h₀ i := pullback.lift (f.h₀ i) (g.h₀ i) (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The refinement given by restricting the indexing type. -/ @[simps] @@ -735,6 +742,7 @@ def bind [J.IsStableUnderComposition] (E : ZeroHypercover.{w} J T) mem₀ := comp_mem_coverings (f := E.f) (g := fun i j ↦ (F i).f j) E.mem₀ (fun i ↦ (F i).mem₀) +set_option backward.isDefEq.respectTransparency.types false in /-- Pairwise intersection of two `0`-hypercovers. -/ @[simps toPreZeroHypercover] noncomputable @@ -805,6 +813,7 @@ variable (J) in abbrev Hom (E : ZeroHypercover.{w} J S) (F : ZeroHypercover.{w'} J S) := E.toPreZeroHypercover.Hom F.toPreZeroHypercover +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simps! id_s₀ id_h₀ comp_s₀ comp_h₀] instance : Category (ZeroHypercover.{w} J S) where @@ -812,6 +821,7 @@ instance : Category (ZeroHypercover.{w} J S) where id _ := PreZeroHypercover.Hom.id _ comp := PreZeroHypercover.Hom.comp +set_option backward.isDefEq.respectTransparency.types false in /-- An isomorphism in `0`-hypercovers is an isomorphism of the underlying pre-`0`-hypercovers. -/ @[simps] def isoMk {E F : ZeroHypercover.{w} J S} (e : E.toPreZeroHypercover ≅ F.toPreZeroHypercover) : @@ -888,6 +898,7 @@ def restrictIndexOfSmall (E : ZeroHypercover.{w} J S) [ZeroHypercover.Small.{w'} __ := E.toPreZeroHypercover.restrictIndex (Small.restrictFun E) mem₀ := Small.mem₀ E +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance (E : ZeroHypercover.{w} J S) [ZeroHypercover.Small.{w'} E] {T : C} (f : T ⟶ S) [IsStableUnderBaseChange J] [∀ (i : E.I₀), HasPullback f (E.f i)] : @@ -933,6 +944,7 @@ instance {D : Type*} [Category* D] {F : C ⥤ D} (J : Precoverage D) [Small.{w} refine ⟨(E.map F le_rfl).restrictIndexOfSmall.I₀, ZeroHypercover.Small.restrictFun _, ?_⟩ simpa using! (E.map F le_rfl).restrictIndexOfSmall.mem₀ +set_option backward.isDefEq.respectTransparency.types false in lemma Small.inf {J K : Precoverage C} [Small.{w} J] (of_le : ∀ ⦃X : C⦄ ⦃R S : Presieve X⦄, R ≤ S → S ∈ K X → R ∈ K X) : Small.{w} (J ⊓ K) where diff --git a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean index 0fb018ee82765d..297bc3a8b72207 100644 --- a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean +++ b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean @@ -750,6 +750,7 @@ lemma IsSeparatedFor.of_mono (f : P ⟶ Q) [Mono f] (h : R.IsSeparatedFor Q) : intro x t₁ t₂ ht₁ ht₂ exact injective_of_mono _ <| h (x.map f) _ _ (ht₁.map f) (ht₂.map f) +set_option backward.isDefEq.respectTransparency.types false in /-- If a presieve `R` on `X` has a subsieve `S` such that: * `P` is a sheaf for `S`. @@ -874,6 +875,7 @@ theorem isSheafFor_ofArrows_iff_bijective_toCompabible : subst hy exact ⟨y, fun _ ↦ rfl, fun y' hy' ↦ h.1 (by ext; apply hy')⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma isSheafFor_pullback_iff (P : Cᵒᵖ ⥤ Type w) {X : C} (R : Sieve X) {Y : C} (f : Y ⟶ X) [IsIso f] : @@ -927,6 +929,7 @@ lemma isSheafFor_over_map_op_comp_ofArrows_iff ← e.bijective.of_comp_iff'] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma isSheafFor_over_map_op_comp_iff {B B' : C} (p : B ⟶ B') (P : (Over B')ᵒᵖ ⥤ Type w) {X : Over B} (R : Sieve X) {X' : Over B'} diff --git a/Mathlib/CategoryTheory/Sites/Limits.lean b/Mathlib/CategoryTheory/Sites/Limits.lean index c2b2220ff983ff..7e4240b60ec600 100644 --- a/Mathlib/CategoryTheory/Sites/Limits.lean +++ b/Mathlib/CategoryTheory/Sites/Limits.lean @@ -53,6 +53,7 @@ noncomputable section section +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An auxiliary definition to be used below. @@ -235,7 +236,7 @@ creates colimits of the diagram. Note: this almost never holds in sheaf categories in general, but it does for the extensive topology (see `Mathlib/CategoryTheory/Sites/Coherent/ExtensiveColimits.lean`). -/ -@[implicit_reducible] +@[instance_reducible] def createsColimitOfIsSheaf (F : K ⥤ Sheaf J D) (h : ∀ (c : Cocone (F ⋙ sheafToPresheaf J D)) (_ : IsColimit c), Presheaf.IsSheaf J c.pt) : CreatesColimit F (sheafToPresheaf J D) := diff --git a/Mathlib/CategoryTheory/Sites/LocalSite.lean b/Mathlib/CategoryTheory/Sites/LocalSite.lean index 5deba23c853f0a..426891151e19c6 100644 --- a/Mathlib/CategoryTheory/Sites/LocalSite.lean +++ b/Mathlib/CategoryTheory/Sites/LocalSite.lean @@ -98,6 +98,7 @@ noncomputable def coconstantSheaf [HasProducts.{w} A] : A ⥤ Sheaf J A := variable [HasColimitsOfSize.{w, w} A] +set_option backward.isDefEq.respectTransparency.types false in variable {A} in /-- The fibre of any presheaf `P : Cᵒᵖ ⥤ A` at `point J` is just `P` evaluated at the terminal object. -/ diff --git a/Mathlib/CategoryTheory/Sites/Monoidal.lean b/Mathlib/CategoryTheory/Sites/Monoidal.lean index 2d2a8d0bfba4ce..64b111b39f9f44 100644 --- a/Mathlib/CategoryTheory/Sites/Monoidal.lean +++ b/Mathlib/CategoryTheory/Sites/Monoidal.lean @@ -174,7 +174,7 @@ attribute [local instance] monoidalCategory /-- The monoidal category structure on `Sheaf J A` obtained in `Sheaf.monoidalCategory` is braided when `A` is braided. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def braidedCategory [(J.W (A := A)).IsMonoidal] [HasWeakSheafify J A] [BraidedCategory A] : BraidedCategory (Sheaf J A) := inferInstanceAs (BraidedCategory @@ -182,7 +182,7 @@ noncomputable def braidedCategory [(J.W (A := A)).IsMonoidal] [HasWeakSheafify J /-- The monoidal category structure on `Sheaf J A` obtained in `Sheaf.monoidalCategory` is symmetric when `A` is symmetric. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def symmetricCategory [(J.W (A := A)).IsMonoidal] [HasWeakSheafify J A] [SymmetricCategory A] : SymmetricCategory (Sheaf J A) := diff --git a/Mathlib/CategoryTheory/Sites/Over.lean b/Mathlib/CategoryTheory/Sites/Over.lean index 19c03ba87acf1c..af5fca81a2c900 100644 --- a/Mathlib/CategoryTheory/Sites/Over.lean +++ b/Mathlib/CategoryTheory/Sites/Over.lean @@ -35,6 +35,7 @@ variable {C : Type u} [Category.{v} C] namespace Presieve +set_option backward.isDefEq.respectTransparency false in @[simp] lemma functorPullback_map_overForget {X : C} {Y : Over X} (S : Presieve Y) : (S.map (Over.forget X)).functorPullback (Over.forget X) = S := by @@ -52,6 +53,8 @@ lemma map_functorPullback_overForget {X : C} {Y : Over X} (R : Presieve Y.left) le_antisymm (map_functorPullback _) fun Z g hg ↦ map.of (u := (Over.homMk g : Over.mk (g ≫ Y.hom) ⟶ Y)) hg +set_option backward.isDefEq.respectTransparency.types false in +set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Presieve Y ≃ Presieve Y.left` for all `Y : Over X`. -/ @[simps] def overEquiv {X : C} (Y : Over X) : Presieve Y ≃o Presieve Y.left where @@ -78,12 +81,15 @@ lemma functorPullback_functorPushforward_overForget {X : C} {Y : Over X} (S : Si apply arrows_ext simp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma functorPushforward_functorPullback_overForget {X : C} {Y : Over X} (S : Sieve Y.left) : (S.functorPullback (Over.forget X)).functorPushforward (Over.forget X) = S := by apply arrows_ext simp [← arrows_generate_map_eq_functorPushforward] +set_option backward.isDefEq.respectTransparency.types false in +set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Sieve Y ≃ Sieve Y.left` for all `Y : Over X`. -/ @[simps -isSimp] -- working with `overEquiv` is useful enough that we don't want `simp` unfolding it def overEquiv {X : C} (Y : Over X) : Sieve Y ≃o Sieve Y.left where @@ -102,6 +108,7 @@ def overEquiv {X : C} (Y : Over X) : Sieve Y ≃o Sieve Y.left where @[deprecated (since := "2026-07-08")] alias overEquiv_symm_bot := map_bot @[deprecated (since := "2026-07-08")] alias overEquiv_le_overEquiv_iff := RelIso.map_rel_iff +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma overEquiv_pullback {X : C} {Y₁ Y₂ : Over X} (f : Y₁ ⟶ Y₂) (S : Sieve Y₂) : overEquiv _ (S.pullback f) = (overEquiv _ S).pullback f.left := by @@ -128,16 +135,19 @@ lemma overEquiv_symm_iff {X : C} {Y : Over X} (S : Sieve Y.left) {Z : Over X} (f rfl set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in lemma overEquiv_iff {X : C} {Y : Over X} (S : Sieve Y) {Z : C} (f : Z ⟶ Y.left) : overEquiv Y S f ↔ S (Over.homMk f : Over.mk (f ≫ Y.hom) ⟶ Y) := by obtain ⟨S, rfl⟩ := (overEquiv Y).symm.surjective S simp +set_option backward.isDefEq.respectTransparency.types false in lemma overEquiv_ofArrows {X : C} {Y : Over X} {I : Type*} (Z : I → Over X) (g : ∀ i, Z i ⟶ Y) : overEquiv Y (ofArrows Z g) = ofArrows (fun i => (Z i).left) (fun i => (g i).left) := by simp [Sieve.overEquiv, functorPushforward_ofArrows] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in lemma overEquiv_preOneHypercover_sieve₁ {X : C} {Y : Over X} (E : PreOneHypercover.{w} Y) {i₁ i₂ : E.I₀} {W : Over X} (p₁ : W ⟶ E.X i₁) (p₂ : W ⟶ E.X i₂) : overEquiv W (E.sieve₁ p₁ p₂) = @@ -148,6 +158,7 @@ lemma overEquiv_preOneHypercover_sieve₁ {X : C} {Y : Over X} (E : PreOneHyperc intro ⟨k, b, hb₁, hb₂⟩ exact ⟨k, Over.homMk b (by simpa using (hb₁ =≫ (E.X i₁).hom).symm), by cat_disch, by cat_disch⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma overEquiv_generate {X : C} {Y : Over X} (R : Presieve Y) : overEquiv Y (.generate R) = .generate (Presieve.functorPushforward (Over.forget X) R) := by refine le_antisymm (fun Z g hg ↦ ?_) ?_ @@ -172,6 +183,7 @@ lemma overEquiv_symm_generate {X : C} {Y : Over X} (R : Presieve Y.left) : exact fun Z g hg ↦ le_generate _ _ _ hg set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma functorPushforward_over_map {X Y : C} (f : X ⟶ Y) (Z : Over X) (S : Sieve Z.left) : Sieve.functorPushforward (Over.map f) ((Sieve.overEquiv Z).symm S) = @@ -255,6 +267,7 @@ lemma over_forget_coverPreserving (X : C) : CoverPreserving (J.over X) J (Over.forget X) where cover_preserve hS := hS +set_option backward.isDefEq.respectTransparency.types false in lemma over_forget_compatiblePreserving (X : C) : CompatiblePreserving J (Over.forget X) where compatible {_ Z _ _ hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by @@ -335,6 +348,7 @@ lemma _root_.CategoryTheory.CoverPreserving.overPost {D : Type*} [Category* D] exact h.cover_preserve hS set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in instance {J : GrothendieckTopology C} (X : C) : (Over.forget X).PreservesOneHypercovers (J.over _) J := by intro Y E @@ -350,6 +364,7 @@ instance {J : GrothendieckTopology C} (X : C) : rwa [GrothendieckTopology.mem_over_iff, Sieve.overEquiv_preOneHypercover_sieve₁] at this set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency.types false in instance {D : Type*} [Category* D] {J : GrothendieckTopology C} {K : GrothendieckTopology D} (F : C ⥤ D) (X : C) [Functor.PreservesOneHypercovers.{w} F J K] : Functor.PreservesOneHypercovers.{w} (Over.post F) (J.over X) (K.over _) := by @@ -525,6 +540,7 @@ section variable (K : Precoverage C) [K.HasPullbacks] [K.IsStableUnderBaseChange] +set_option backward.isDefEq.respectTransparency.types false in /-- The Grothendieck topology on `Over X`, obtained from localizing the topology generated by the precoverage `K`, is generated by the preimage of `K`. -/ lemma over_toGrothendieck_eq_toGrothendieck_comap_forget (X : C) : diff --git a/Mathlib/CategoryTheory/Sites/Point/Basic.lean b/Mathlib/CategoryTheory/Sites/Point/Basic.lean index 2ed8ce616fc0d4..3db7855888e5d4 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Basic.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Basic.lean @@ -308,7 +308,7 @@ noncomputable def isTerminalFiberObj (T : C) (hT : IsTerminal T) : IsTerminal.isTerminalObj _ _ hT /-- The fiber of the terminal object contains a unique element. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def uniqueFiberObj (T : C) (hT : IsTerminal T) : Unique (Φ.fiber.obj T) := Types.isTerminalEquivUnique _ (Φ.isTerminalFiberObj T hT) diff --git a/Mathlib/CategoryTheory/Sites/Point/Comap.lean b/Mathlib/CategoryTheory/Sites/Point/Comap.lean index f4718c92d6acc6..d5e1779e7638d0 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Comap.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Comap.lean @@ -35,7 +35,6 @@ variable {C D : Type*} [Category* C] [Category* D] [InitiallySmall (F ⋙ Φ.fiber).Elements] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- If `F : C ⥤ D` is a representably flat and cover preserving functor between sites, then any point on `D` induces a point on `C` by precomposing the fiber functor with `F`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Sites/Point/Conservative.lean b/Mathlib/CategoryTheory/Sites/Point/Conservative.lean index d55823a91f7ae0..f14ad594ddb2d7 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Conservative.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Conservative.lean @@ -138,7 +138,6 @@ lemma jointly_reflect_isLocallySurjective end set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma jointly_reflect_ofArrows_mem [HasSheafify J (Type w)] [J.WEqualsLocallyBijective (Type w)] (hP : P.IsConservativeFamilyOfPoints) @@ -180,7 +179,6 @@ lemma jointly_reflect_ofArrows_mem_of_small exact fun Φ x ↦ ⟨_, _, hy ⟨Φ, x⟩⟩ set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in private lemma mk'.isLocallySurjective (hP : ∀ ⦃X : C⦄ (S : Sieve X) (_ : ∀ (Φ : P.FullSubcategory) (x : Φ.obj.fiber.obj X), ∃ (Y : C) (g : Y ⟶ X) (_ : S g) (y : Φ.obj.fiber.obj Y), Φ.obj.fiber.map g y = x), diff --git a/Mathlib/CategoryTheory/Sites/Point/Map.lean b/Mathlib/CategoryTheory/Sites/Point/Map.lean index 77d4a858bddb5e..99eb6541bdadcf 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Map.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Map.lean @@ -35,6 +35,7 @@ variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] {J : GrothendieckTopology C} (Φ : Point.{w} J) (F : C ⥤ D) (K : GrothendieckTopology D) [F.IsCocontinuous J K] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma map_aux ⦃X : D⦄ (R : Sieve X) (hR : R ∈ K X) ⦃u : Φ.fiber.Elements⦄ (f : (CategoryOfElements.π Φ.fiber ⋙ F).obj u ⟶ X) : diff --git a/Mathlib/CategoryTheory/Sites/Point/Monoidal.lean b/Mathlib/CategoryTheory/Sites/Point/Monoidal.lean index d2d14cd0b3e9c0..6f757ed411e61f 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Monoidal.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Monoidal.lean @@ -26,7 +26,7 @@ universe w w' v v' u u' namespace CategoryTheory.GrothendieckTopology.Point -open Limits MonoidalCategory Functor +open Limits MonoidalCategory CategoryTheory.Functor variable {C : Type u} [Category.{v} C] {J : GrothendieckTopology C} (Φ : Point.{w} J) {A : Type u'} [Category.{v'} A] [MonoidalCategory A] [HasColimitsOfSize.{w, w} A] diff --git a/Mathlib/CategoryTheory/Sites/Point/OfIsCofiltered.lean b/Mathlib/CategoryTheory/Sites/Point/OfIsCofiltered.lean index 3253ac0bd272ad..d98198dfd1f6c8 100644 --- a/Mathlib/CategoryTheory/Sites/Point/OfIsCofiltered.lean +++ b/Mathlib/CategoryTheory/Sites/Point/OfIsCofiltered.lean @@ -163,6 +163,7 @@ lemma toPresheafFiberOfIsCofiltered_w {V U : N} (f : V ⟶ U) (P : Cᵒᵖ ⥤ A toPresheafFiberOfIsCofiltered p hp U P := by simp [toPresheafFiberOfIsCofiltered] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma toPresheafFiberOfIsCofiltered_naturality {P Q : Cᵒᵖ ⥤ A} (g : P ⟶ Q) (U : N) : toPresheafFiberOfIsCofiltered p hp U P ≫ diff --git a/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean b/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean index d6e557e769855b..eaa17a2a44b981 100644 --- a/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean +++ b/Mathlib/CategoryTheory/Sites/Point/Skyscraper.lean @@ -65,6 +65,9 @@ noncomputable def skyscraperPresheafHomEquiv : left_inv f := by cat_disch right_inv g := by cat_disch +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma toPresheafFiber_skyscraperPresheafHomEquiv_symm (g : P ⟶ Φ.skyscraperPresheaf M) (X : C) (x : Φ.fiber.obj X) : @@ -72,6 +75,7 @@ lemma toPresheafFiber_skyscraperPresheafHomEquiv_symm g.app (op X) ≫ Pi.π _ x := by simp [skyscraperPresheafHomEquiv_symm_apply] +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma skyscraperPresheafHomEquiv_naturality_left_symm (f : P ⟶ Q) (g : Q ⟶ Φ.skyscraperPresheaf M) : @@ -178,6 +182,7 @@ private lemma isSheaf_skyscraperPresheaf_aux simpa [hz₁, hz₂, φ₁, φ₂] using! (Cone.w s φ₂.op =≫ Pi.π _ z).trans (Cone.w s φ₁.op =≫ Pi.π _ z).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isSheaf_skyscraperPresheaf (M : A) : Presheaf.IsSheaf J (Φ.skyscraperPresheaf M) := by @@ -232,6 +237,7 @@ instance : (Φ.sheafFiber (A := A)).IsLeftAdjoint := instance : (Φ.skyscraperSheafFunctor (A := A)).IsRightAdjoint := Φ.skyscraperSheafAdjunction.isRightAdjoint +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma skyscraperSheafAdjunction_homEquiv_apply_hom {F : Sheaf J A} {M : A} @@ -245,6 +251,7 @@ lemma skyscraperSheafAdjunction_homEquiv_apply_hom {F : Sheaf J A} {M : A} alias skyscraperSheafAdjunction_homEquiv_apply_val := skyscraperSheafAdjunction_homEquiv_apply_hom +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma skyscraperSheafAdjunction_homEquiv_symm_apply {F : Sheaf J A} {M : A} diff --git a/Mathlib/CategoryTheory/Sites/Precoverage.lean b/Mathlib/CategoryTheory/Sites/Precoverage.lean index 6055d8aa89b92e..5a2d8da2b24ad8 100644 --- a/Mathlib/CategoryTheory/Sites/Precoverage.lean +++ b/Mathlib/CategoryTheory/Sites/Precoverage.lean @@ -126,6 +126,7 @@ alias mem_coverings_of_isIso := HasIsos.mem_coverings_of_isIso alias sup_mem_coverings := IsStableUnderSup.sup_mem_coverings alias hasPullbacks_of_mem := HasPullbacks.hasPullbacks_of_mem +set_option backward.isDefEq.respectTransparency.types false in set_option warning.simp.varHead false in attribute [local simp] Presieve.ofArrows.obj_idx Presieve.ofArrows.hom_idx in lemma mem_coverings_of_isPullback {J : Precoverage C} [IsStableUnderBaseChange J] @@ -147,6 +148,7 @@ lemma mem_coverings_of_isPullback {J : Precoverage C} [IsStableUnderBaseChange J refine le_antisymm (fun Z g ⟨i⟩ ↦ .mk _) fun Z g hg ↦ ?_ exact .mk' (Sum.inl ⟨⟨_, _⟩, hg⟩) (by cat_disch) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option warning.simp.varHead false in attribute [local simp] Presieve.ofArrows.obj_idx Presieve.ofArrows.hom_idx in lemma comp_mem_coverings {J : Precoverage C} [IsStableUnderComposition J] {ι : Type w} @@ -233,14 +235,12 @@ lemma mem_comap_iff {X : C} {R : Presieve X} : lemma comap_inf : (J ⊓ K).comap F = J.comap F ⊓ K.comap F := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] lemma comap_id (K : Precoverage C) : K.comap (𝟭 C) = K := by ext simp set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma comap_comp {E : Type*} [Category* E] (F : C ⥤ D) (G : D ⥤ E) (J : Precoverage E) : J.comap (F ⋙ G) = (J.comap G).comap F := by ext X R diff --git a/Mathlib/CategoryTheory/Sites/Preserves.lean b/Mathlib/CategoryTheory/Sites/Preserves.lean index 35b9d4e04988fe..5fdcd16571ec3c 100644 --- a/Mathlib/CategoryTheory/Sites/Preserves.lean +++ b/Mathlib/CategoryTheory/Sites/Preserves.lean @@ -80,6 +80,7 @@ variable (hI : IsInitial I) -- This is the data of a particular disjoint coproduct in `C`. variable {α : Type*} [Small.{w} α] {X : α → C} (c : Cofan X) (hc : IsColimit c) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem piComparison_fac : have : HasCoproduct X := ⟨⟨c, hc⟩⟩ diff --git a/Mathlib/CategoryTheory/Sites/PreservesLocallyBijective.lean b/Mathlib/CategoryTheory/Sites/PreservesLocallyBijective.lean index 1c5b83f21cbdf5..d4b3af02fc1c8a 100644 --- a/Mathlib/CategoryTheory/Sites/PreservesLocallyBijective.lean +++ b/Mathlib/CategoryTheory/Sites/PreservesLocallyBijective.lean @@ -36,6 +36,7 @@ lemma isLocallyInjective_whisker [H.IsCocontinuous J K] [IsLocallyInjective K f] IsLocallyInjective J (whiskerLeft H.op f) where equalizerSieve_mem x y h := H.cover_lift J K (equalizerSieve_mem K f x y h) +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in lemma isLocallyInjective_of_whisker (hH : CoverPreserving J K H) [H.IsCoverDense K] [IsLocallyInjective J (whiskerLeft H.op f)] : IsLocallyInjective K f where diff --git a/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean b/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean index 0a3ec627c0cba3..70890814c1975e 100644 --- a/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean @@ -47,7 +47,7 @@ universe v u namespace CategoryTheory -open Category Limits Functor +open Category Limits CategoryTheory.Functor variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) {A B : Type*} [Category* A] [Category* B] (F : A ⥤ B) @@ -131,7 +131,6 @@ variable {G₁ : (Cᵒᵖ ⥤ A) ⥤ Sheaf J A} (adj₁ : G₁ ⊣ sheafToPreshe {G₂ : (Cᵒᵖ ⥤ B) ⥤ Sheaf J B} set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma GrothendieckTopology.preservesSheafification_iff_of_adjunctions (adj₂ : G₂ ⊣ sheafToPresheaf J B) : J.PreservesSheafification F ↔ ∀ (P : Cᵒᵖ ⥤ A), @@ -157,6 +156,7 @@ section HasSheafCompose variable (adj₂ : G₂ ⊣ sheafToPresheaf J B) [J.HasSheafCompose F] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical natural transformation `(whiskeringRight Cᵒᵖ A B).obj F ⋙ G₂ ⟶ G₁ ⋙ sheafCompose J F` @@ -183,14 +183,13 @@ lemma sheafComposeNatTrans_fac (P : Cᵒᵖ ⥤ A) : simp [sheafComposeNatTrans, -ObjectProperty.ι_obj, -ObjectProperty.ι_map, Adjunction.homEquiv_counit] -set_option backward.isDefEq.respectTransparency false in lemma sheafComposeNatTrans_app_uniq (P : Cᵒᵖ ⥤ A) (α : G₂.obj (P ⋙ F) ⟶ (sheafCompose J F).obj (G₁.obj P)) (hα : adj₂.unit.app (P ⋙ F) ≫ (sheafToPresheaf J B).map α = whiskerRight (adj₁.unit.app P) F) : α = (sheafComposeNatTrans J F adj₁ adj₂).app P := by apply (adj₂.homEquiv _ _).injective - dsimp [sheafComposeNatTrans] + dsimp [ObjectProperty.ι_obj, sheafComposeNatTrans, id_obj] erw [Equiv.apply_symm_apply] rw [← hα] apply adj₂.homEquiv_unit @@ -286,6 +285,7 @@ lemma sheafToPresheaf_map_sheafComposeNatTrans_eq_sheafifyCompIso_inv (P : Cᵒ dsimp [plusPlusAdjunction] simp +set_option backward.isDefEq.respectTransparency.types false in instance (P : Cᵒᵖ ⥤ D) : IsIso ((sheafComposeNatTrans J F (plusPlusAdjunction J D) (plusPlusAdjunction J E)).app P) := by rw [← isIso_iff_of_reflects_iso _ (sheafToPresheaf J E), diff --git a/Mathlib/CategoryTheory/Sites/PseudofunctorSheafOver.lean b/Mathlib/CategoryTheory/Sites/PseudofunctorSheafOver.lean index f112008fcd2b6e..d1beef96ed74f0 100644 --- a/Mathlib/CategoryTheory/Sites/PseudofunctorSheafOver.lean +++ b/Mathlib/CategoryTheory/Sites/PseudofunctorSheafOver.lean @@ -30,6 +30,7 @@ namespace GrothendieckTopology variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) (A : Type u') [Category.{v'} A] +set_option backward.isDefEq.respectTransparency.types false in /-- Given a Grothendieck topology `J` on a category `C` and a category `A`, this is the pseudofunctor which sends `X : C` to the categories of sheaves on `Over X` with values in `A`. -/ diff --git a/Mathlib/CategoryTheory/Sites/Sheaf.lean b/Mathlib/CategoryTheory/Sites/Sheaf.lean index c9003c0cae617f..d247c155dd0f59 100644 --- a/Mathlib/CategoryTheory/Sites/Sheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Sheaf.lean @@ -91,8 +91,8 @@ open Presieve Presieve.FamilyOfElements Limits variable (P : Cᵒᵖ ⥤ A) {X : C} (S : Sieve X) (R : Presieve X) (E : Aᵒᵖ) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Given a sieve `S` on `X : C`, a presheaf `P : Cᵒᵖ ⥤ A`, and an object `E` of `A`, the cones over the natural diagram `S.arrows.diagram.op ⋙ P` associated to `S` and `P` with cone point `E` are in 1-1 correspondence with `SieveCompatible` family of elements @@ -349,6 +349,9 @@ variable {J A} abbrev Sheaf.homEquiv {X Y : Sheaf J A} : (X ⟶ Y) ≃ (X.obj ⟶ Y.obj) := (fullyFaithfulSheafToPresheaf J A).homEquiv +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- `Sheaf.homEquiv` as a natural isomorphism. -/ @[simps! +dsimpLhs] def sheafToPresheafCompYonedaCompWhiskeringLeftSheafToPresheaf : @@ -363,6 +366,9 @@ lemma sheafToPresheafCompYonedaCompWhiskeringLeftSheafToPresheaf_app_app {X Y : Sheaf.homEquiv.symm.toIso := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- `Sheaf.homEquiv` as a natural isomorphism, using coyoneda. -/ @[simps! +dsimpLhs] def sheafToPresheafCompCoyonedaCompWhiskeringLeftSheafToPresheaf : @@ -388,8 +394,8 @@ theorem Sheaf.Hom.mono_of_presheaf_mono {F G : Sheaf J A} (f : F ⟶ G) [h : Mon instance Sheaf.Hom.epi_of_presheaf_epi {F G : Sheaf J A} (f : F ⟶ G) [h : Epi f.1] : Epi f := (sheafToPresheaf J A).epi_of_epi_map h +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem isSheaf_iff_isSheaf_of_type (P : Cᵒᵖ ⥤ Type w) : Presheaf.IsSheaf J P ↔ Presieve.IsSheaf J P := by constructor @@ -439,6 +445,7 @@ lemma Presheaf.IsSheaf.of_le {K : GrothendieckTopology C} {F : Cᵒᵖ ⥤ A} (h Presheaf.IsSheaf J F := fun _ _ _ hS ↦ h _ _ (hle _ hS) +set_option backward.isDefEq.respectTransparency.types false in /-- The category of sheaves on the bottom (trivial) Grothendieck topology is equivalent to the category of presheaves. @@ -522,6 +529,7 @@ variable (P : Cᵒᵖ ⥤ A) (P' : Cᵒᵖ ⥤ A') section MultiequalizerConditions +set_option backward.isDefEq.respectTransparency.types false in /-- When `P` is a sheaf and `S` is a cover, the associated multifork is a limit. -/ def isLimitOfIsSheaf {X : C} (S : J.Cover X) (hP : IsSheaf J P) : IsLimit (S.multifork P) where lift := fun E : Multifork _ => hP.amalgamate S (fun _ => E.ι _) @@ -541,6 +549,7 @@ def isLimitOfIsSheaf {X : C} (S : J.Cover X) (hP : IsSheaf J P) : IsLimit (S.mul symm apply hP.amalgamate_map +set_option backward.isDefEq.respectTransparency.types false in theorem isSheaf_iff_multifork : IsSheaf J P ↔ ∀ (X : C) (S : J.Cover X), Nonempty (IsLimit (S.multifork P)) := by refine ⟨fun hP X S => ⟨isLimitOfIsSheaf _ _ _ hP⟩, ?_⟩ diff --git a/Mathlib/CategoryTheory/Sites/SheafHom.lean b/Mathlib/CategoryTheory/Sites/SheafHom.lean index 5598ac0240a6fe..6d67c6d68bc8d1 100644 --- a/Mathlib/CategoryTheory/Sites/SheafHom.lean +++ b/Mathlib/CategoryTheory/Sites/SheafHom.lean @@ -39,6 +39,7 @@ variable {C : Type u} [Category.{v} C] {J : GrothendieckTopology C} variable (F G : Cᵒᵖ ⥤ A) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given two presheaves `F` and `G` on a category `C` with values in a category `A`, this `presheafHom F G` is the presheaf of types which sends an object `X : C` @@ -78,6 +79,7 @@ lemma presheafHom_map_app_op_mk_id {X Y : C} (g : Y ⟶ X) variable (F G) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The sections of the presheaf `presheafHom F G` identify to morphisms `F ⟶ G`. -/ def presheafHomSectionsEquiv : (presheafHom F G).sections ≃ (F ⟶ G) where @@ -132,6 +134,7 @@ namespace PresheafHom.IsSheafFor variable (x : Presieve.FamilyOfElements (presheafHom F G) S.arrows) {Y : C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in include hG in lemma exists_app (hx : x.Compatible) (g : Y ⟶ X) : @@ -243,12 +246,14 @@ def sheafHom (F G : Sheaf J A) : Sheaf J (Type _) where obj := sheafHom' F G property := (Presheaf.isSheaf_of_iso_iff (sheafHom'Iso F G)).2 (G.2.hom F.1) +set_option backward.isDefEq.respectTransparency.types false in /-- The sections of the sheaf `sheafHom F G` identify to morphisms `F ⟶ G`. -/ def sheafHomSectionsEquiv (F G : Sheaf J A) : (sheafHom F G).1.sections ≃ (F ⟶ G) := ((Functor.sectionsFunctor Cᵒᵖ).mapIso (sheafHom'Iso F G)).toEquiv.trans ((presheafHomSectionsEquiv F.1 G.1).trans Sheaf.homEquiv.symm) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma sheafHomSectionsEquiv_symm_apply_coe_apply {F G : Sheaf J A} (φ : F ⟶ G) (X : Cᵒᵖ) : ((sheafHomSectionsEquiv F G).symm φ).1 X = (J.overPullback A X.unop).map φ := (rfl) diff --git a/Mathlib/CategoryTheory/Sites/SheafOfTypes.lean b/Mathlib/CategoryTheory/Sites/SheafOfTypes.lean index 598488b38db4a9..b68870933f5077 100644 --- a/Mathlib/CategoryTheory/Sites/SheafOfTypes.lean +++ b/Mathlib/CategoryTheory/Sites/SheafOfTypes.lean @@ -202,6 +202,7 @@ open Presieve variable {C : Type u} [Category.{v} C] variable {X : C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem yonedaFamily_fromCocone_compatible (S : Sieve X) (s : Cocone (diagram S.arrows)) : FamilyOfElements.Compatible <| yonedaFamilyOfElements_fromCocone S.arrows s := by diff --git a/Mathlib/CategoryTheory/Sites/Sheafification.lean b/Mathlib/CategoryTheory/Sites/Sheafification.lean index 0c9873755a9646..231e46274c7217 100644 --- a/Mathlib/CategoryTheory/Sites/Sheafification.lean +++ b/Mathlib/CategoryTheory/Sites/Sheafification.lean @@ -146,6 +146,7 @@ theorem toSheafification_app (P : Cᵒᵖ ⥤ D) : (toSheafification J D).app P variable {D} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem isIso_toSheafify {P : Cᵒᵖ ⥤ D} (hP : Presheaf.IsSheaf J P) : IsIso (toSheafify J P) := by refine ⟨(sheafificationAdjunction J D |>.counit.app ⟨P, hP⟩).hom, ?_, ?_⟩ @@ -170,6 +171,7 @@ noncomputable def sheafifyLift {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (hQ : Preshe sheafify J P ⟶ Q := (sheafificationAdjunction J D).homEquiv P ⟨Q, hQ⟩ |>.symm η |>.hom +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem sheafificationAdjunction_counit_app_val (P : Sheaf J D) : ((sheafificationAdjunction J D).counit.app P).hom = sheafifyLift J (𝟙 P.obj) P.property := by @@ -177,7 +179,6 @@ theorem sheafificationAdjunction_counit_app_val (P : Sheaf J D) : rw [Adjunction.homEquiv_counit] simp -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem toSheafify_sheafifyLift {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (hQ : Presheaf.IsSheaf J Q) : toSheafify J P ≫ sheafifyLift J η hQ = η := by @@ -189,6 +190,7 @@ theorem toSheafify_sheafifyLift {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (hQ : Presh rw [sheafificationAdjunction J D |>.right_triangle_components (Y := ⟨Q, hQ⟩)] simp +set_option backward.isDefEq.respectTransparency.types false in theorem sheafifyLift_unique {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (hQ : Presheaf.IsSheaf J Q) (γ : sheafify J P ⟶ Q) : toSheafify J P ≫ γ = η → γ = sheafifyLift J η hQ := by intro h diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 3af74da41626a2..35db11657d0a28 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -38,6 +38,7 @@ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] variable {X Y Z : C} (f : Y ⟶ X) /-- A predicate on arrows with codomain `X`. -/ +@[implicit_reducible] def Presieve (X : C) := ∀ ⦃Y⦄, (Y ⟶ X) → Prop deriving CompleteLattice, Inhabited @@ -566,6 +567,7 @@ def uncurry : Set (Σ Y, Y ⟶ X) := · rintro ⟨i⟩; exact ⟨_, rfl, HEq.refl _⟩ · rintro ⟨i, rfl, h⟩; rw [← eq_of_heq h]; exact ⟨i⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma ofArrows_eq_ofArrows_uncurry {ι : Type*} {S : C} {X : ι → C} (f : ∀ i, X i ⟶ S) : ofArrows X f = ofArrows _ (fun i : (Presieve.ofArrows X f).uncurry ↦ f i.2.idx) := by refine le_antisymm (fun Z g hg ↦ ?_) fun Z g ⟨i⟩ ↦ .mk _ @@ -1257,12 +1259,10 @@ lemma mem_functorPushforward_inverse {X : D} {S : Sieve X} {e : C ≌ D} {f : Y variable (e : C ≌ D) -set_option backward.isDefEq.respectTransparency false in lemma functorPushforward_equivalence_eq_pullback {U : C} (S : Sieve U) : Sieve.functorPushforward e.inverse (Sieve.functorPushforward e.functor S) = Sieve.pullback (e.unitInv.app U) S := by ext; simp -set_option backward.isDefEq.respectTransparency false in lemma pullback_functorPushforward_equivalence_eq {X : C} (S : Sieve X) : Sieve.pullback (e.unit.app X) (Sieve.functorPushforward e.inverse (Sieve.functorPushforward e.functor S)) = S := by ext; simp @@ -1310,6 +1310,7 @@ def natTransOfLe {S T : Sieve X} (h : S ≤ T) : S.functor ⟶ T.functor where def functorInclusion (S : Sieve X) : S.functor ⟶ yoneda.obj X where app _ := ↾fun f ↦ f.1 +set_option backward.isDefEq.respectTransparency.types false in /-- Any component `f : Y ⟶ X` of the sieve `S` induces a natural transformation from `yoneda.obj Y` to the presheaf induced by `S`. -/ @[simps] @@ -1322,6 +1323,7 @@ theorem natTransOfLe_comm {S T : Sieve X} (h : S ≤ T) : open ConcreteCategory +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The presheaf induced by a sieve is a subobject of the yoneda embedding. -/ instance functorInclusion_is_mono : Mono S.functorInclusion := @@ -1369,6 +1371,7 @@ def uliftFunctorInclusion (S : Sieve X) : S.uliftFunctor ⟶ uliftYoneda.{w}.obj X := Functor.whiskerRight S.functorInclusion CategoryTheory.uliftFunctor +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `Sieve.toFunctor` with universe lifting. -/ @[simps] def toUliftFunctor (S : Sieve X) {Y : C} (f : Y ⟶ X) (hf : S f) : @@ -1379,6 +1382,7 @@ theorem uliftNatTransOfLe_comm {S T : Sieve X} (h : S ≤ T) : uliftNatTransOfLe.{w} h ≫ uliftFunctorInclusion.{w} _ = uliftFunctorInclusion.{w} _ := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The presheaf induced by a sieve is a subobject of the yoneda embedding. -/ instance uliftFunctorInclusion_is_mono (S : Sieve X) : @@ -1428,6 +1432,7 @@ def shrinkFunctor [LocallySmall.{w} C] {X : C} (S : Sieve X) : map {Y Z} g f hf := by simpa [shrinkYonedaObjObjEquiv_obj_map] using S.downward_closed hf _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (S) in /-- `Sieve.shrinkFunctor` is compatible with universe lifting. -/ @@ -1447,6 +1452,7 @@ def shrinkFunctorUliftFunctorIso [LocallySmall.{w} C] [LocallySmall.{max w' w} C rw [shrinkYonedaObjObjEquiv_obj_map, shrinkYonedaObjObjEquiv_symm_comp] simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma shrinkFunctorUliftFunctorIso_inv_ι [LocallySmall.{w} C] [LocallySmall.{max w' w} C] : (shrinkFunctorUliftFunctorIso.{w, w'} S).inv ≫ @@ -1455,6 +1461,7 @@ lemma shrinkFunctorUliftFunctorIso_inv_ι [LocallySmall.{w} C] [LocallySmall.{ma shrinkYonedaUliftFunctorIso.{w, w'}.inv.app X := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (S) in /-- Shrinking does nothing for the same universe level. -/ @@ -1493,3 +1500,6 @@ lemma Presieve.functorPushforward_overForget (Sieve.arrows_generate_map_eq_functorPushforward (Over.forget S)).symm end CategoryTheory + +-- pushed over the edge in `nightly-testing`, should be split after landing on master +set_option linter.style.longFile 1600 diff --git a/Mathlib/CategoryTheory/Sites/Subcanonical.lean b/Mathlib/CategoryTheory/Sites/Subcanonical.lean index 925ca1dc8fe2db..945cedc632a365 100644 --- a/Mathlib/CategoryTheory/Sites/Subcanonical.lean +++ b/Mathlib/CategoryTheory/Sites/Subcanonical.lean @@ -24,7 +24,7 @@ universe v' v u namespace CategoryTheory.GrothendieckTopology -open Opposite Functor +open Opposite CategoryTheory.Functor variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C) [Subcanonical J] @@ -44,6 +44,7 @@ theorem yonedaEquiv_symm_app_apply {X : C} {F : Sheaf J (Type v)} (x : F.obj.obj (Y : Cᵒᵖ) (f : Y.unop ⟶ X) : dsimp% (J.yonedaEquiv.symm x).hom.app Y f = F.obj.map f.op x := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- See also `yonedaEquiv_naturality'` for a more general version. -/ lemma yonedaEquiv_naturality {X Y : C} {F : Sheaf J (Type v)} (f : J.yoneda.obj X ⟶ F) @@ -113,6 +114,9 @@ lemma hom_ext_yoneda {P Q : Sheaf J (Type v)} {f g : P ⟶ Q} simpa only [yonedaEquiv_comp, Equiv.apply_symm_apply] using! congr_arg (J.yonedaEquiv) (h _ (J.yonedaEquiv.symm x)) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The Yoneda lemma for sheaves. -/ @[simps! +dsimpLhs hom_app_app_hom_apply_down inv_app_app] def yonedaOpCompCoyoneda : @@ -211,6 +215,9 @@ lemma hom_ext_uliftYoneda {P Q : Sheaf J (Type (max v v'))} {f g : P ⟶ Q} simpa only [uliftYonedaEquiv_comp, Equiv.apply_symm_apply] using! congr_arg (J.uliftYonedaEquiv) (h _ (J.uliftYonedaEquiv.symm x)) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of the Yoneda lemma for sheaves with a raise in the universe level. -/ @[simps! +dsimpLhs -isSimp] def uliftYonedaOpCompCoyoneda : diff --git a/Mathlib/CategoryTheory/Sites/Subsheaf.lean b/Mathlib/CategoryTheory/Sites/Subsheaf.lean index cb834133ebf691..2d6fd0e03447e8 100644 --- a/Mathlib/CategoryTheory/Sites/Subsheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Subsheaf.lean @@ -131,6 +131,7 @@ theorem Subfunctor.sheafify_sheafify (h : Presieve.IsSheaf J F) : (G.sheafify J).sheafify J = G.sheafify J := ((Subfunctor.eq_sheafify_iff _ h).mpr <| G.sheafify_isSheaf h).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The lift of a presheaf morphism onto the sheafification subpresheaf. -/ noncomputable def Subfunctor.sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve.IsSheaf J F') : @@ -154,6 +155,7 @@ noncomputable def Subfunctor.sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve · dsimp [Presieve.FamilyOfElements.map] at hj ⊢ rwa [Functor.map_comp, comp_apply] +set_option backward.isDefEq.respectTransparency.types false in theorem Subfunctor.to_sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve.IsSheaf J F') : Subfunctor.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by ext U s @@ -163,6 +165,7 @@ theorem Subfunctor.to_sheafifyLift (f : G.toFunctor ⟶ F') (h : Presieve.IsShea exact (Presieve.IsSheafFor.valid_glue (h _ ((homOfLe (_ : _ ≤ sheafify _ _)).app _ _).2) ((G.family_of_elements_compatible _).map _) _ _).trans (this _ _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem Subfunctor.to_sheafify_lift_unique (h : Presieve.IsSheaf J F') (l₁ l₂ : (G.sheafify J).toFunctor ⟶ F') @@ -175,6 +178,7 @@ theorem Subfunctor.to_sheafify_lift_unique (h : Presieve.IsSheaf J F') rw [← dsimp% l₁.naturality_apply, ← dsimp% l₂.naturality_apply] exact ConcreteCategory.congr_hom (congr_app e <| op V) ⟨_, hi⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem Subfunctor.sheafify_le (h : G ≤ G') (hF : Presieve.IsSheaf J F) (hG' : Presieve.IsSheaf J G'.toFunctor) : G.sheafify J ≤ G' := by intro U x hx @@ -231,6 +235,7 @@ instance {F F' : Sheaf J (Type w)} (f : F ⟶ F') : Mono (Sheaf.imageι f) := dsimp infer_instance) +set_option backward.isDefEq.respectTransparency.types false in instance {F F' : Sheaf J (Type w)} (f : F ⟶ F') : Epi (Sheaf.toImage f) := by refine ⟨@fun G' g₁ g₂ e => ?_⟩ ext U ⟨s, hx⟩ @@ -252,6 +257,7 @@ def imageMonoFactorization {F F' : Sheaf J (Type w)} (f : F ⟶ F') : m := Sheaf.imageι f e := Sheaf.toImage f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The mono factorization given by `image_sheaf` for a morphism is an image. -/ noncomputable def imageFactorization {F F' : Sheaf J (Type (max v u))} (f : F ⟶ F') : diff --git a/Mathlib/CategoryTheory/Sites/Whiskering.lean b/Mathlib/CategoryTheory/Sites/Whiskering.lean index bbb916c0ca3f13..f61b46c2fa0f12 100644 --- a/Mathlib/CategoryTheory/Sites/Whiskering.lean +++ b/Mathlib/CategoryTheory/Sites/Whiskering.lean @@ -28,7 +28,7 @@ Given a natural transformation `η : F ⟶ G`, we obtain a natural transformatio namespace CategoryTheory -open CategoryTheory.Limits Functor +open CategoryTheory.Limits CategoryTheory.Functor universe v₁ v₂ v₃ u₁ u₂ u₃ @@ -87,6 +87,7 @@ instance [F.ReflectsIsomorphisms] : (sheafCompose J F).ReflectsIsomorphisms wher variable {F G} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `η : F ⟶ G` is a natural transformation then we obtain a morphism of functors @@ -107,6 +108,7 @@ namespace GrothendieckTopology.Cover variable (F G) {J} variable (P : Cᵒᵖ ⥤ A) {X : C} (S : J.Cover X) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The multicospan associated to a cover `S : J.Cover X` and a presheaf of the form `P ⋙ F` is isomorphic to the composition of the multicospan associated to `S` and `P`, @@ -122,6 +124,7 @@ def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospa rintro (a | b) (a | b) (f | f | f) all_goals cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Mapping the multifork associated to a cover `S : J.Cover X` and a presheaf `P` with respect to a functor `F` is isomorphic (upto a natural isomorphism of the underlying functors) diff --git a/Mathlib/CategoryTheory/Skeletal.lean b/Mathlib/CategoryTheory/Skeletal.lean index 84f6112dac9815..24898f3d4a4e80 100644 --- a/Mathlib/CategoryTheory/Skeletal.lean +++ b/Mathlib/CategoryTheory/Skeletal.lean @@ -118,6 +118,7 @@ lemma Skeleton.comp_hom {X Y Z : Skeleton C} (f : X ⟶ Y) (g : Y ⟶ Z) : variable (C) +set_option backward.isDefEq.respectTransparency.types false in /-- An inverse to `fromSkeleton C` that forms an equivalence with it. -/ @[simps] noncomputable def toSkeletonFunctor : C ⥤ Skeleton C where obj := toSkeleton @@ -126,6 +127,7 @@ variable (C) map_id _ := by aesop map_comp _ _ := InducedCategory.hom_ext (by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence between the skeleton and the category itself. -/ @[simps] noncomputable def skeletonEquivalence : Skeleton C ≌ C where @@ -137,6 +139,7 @@ set_option backward.defeqAttrib.useBackward true in counitIso := NatIso.ofComponents fromSkeletonToSkeletonIso functor_unitIso_comp _ := Iso.inv_hom_id _ +set_option backward.isDefEq.respectTransparency.types false in theorem skeleton_skeletal : Skeletal (Skeleton C) := by rintro X Y ⟨h⟩ have : X.out ≈ Y.out := ⟨(fromSkeleton C).mapIso h⟩ @@ -175,6 +178,7 @@ noncomputable def mapSkeleton (F : C ⥤ D) : Skeleton C ⥤ Skeleton D := variable (F : C ⥤ D) +set_option backward.isDefEq.respectTransparency.types false in lemma mapSkeleton_obj_toSkeleton (X : C) : F.mapSkeleton.obj (toSkeleton X) = toSkeleton (F.obj X) := congr_toSkeleton_of_iso <| F.mapIso <| fromSkeletonToSkeletonIso X @@ -219,6 +223,7 @@ variable (C D) preorder with nice definitional properties, but is only really appropriate for thin categories. If your original category is not thin, you probably want to be using `Skeleton` instead of this. -/ +@[implicit_reducible] def ThinSkeleton : Type u₁ := Quotient (isIsomorphicSetoid C) @@ -245,7 +250,7 @@ instance ThinSkeleton.preorder : Preorder (ThinSkeleton C) where le_trans a b c := Quotient.inductionOn₃ a b c fun _ _ _ => Nonempty.map2 (· ≫ ·) /-- The functor from a category to its thin skeleton. -/ -@[simps] +@[simps, implicit_reducible] def toThinSkeleton : C ⥤ ThinSkeleton C where obj := ThinSkeleton.mk map f := homOfLE (Nonempty.intro f) @@ -266,6 +271,7 @@ instance thin : Quiver.IsThin (ThinSkeleton C) := fun _ _ => variable {C} {D} +set_option backward.isDefEq.respectTransparency.types false in /-- A functor `C ⥤ D` computably lowers to a functor `ThinSkeleton C ⥤ ThinSkeleton D`. -/ @[simps] def map (F : C ⥤ D) : ThinSkeleton C ⥤ ThinSkeleton D where diff --git a/Mathlib/CategoryTheory/SmallObject/Construction.lean b/Mathlib/CategoryTheory/SmallObject/Construction.lean index 6d1538ec667877..04289fcf7563ac 100644 --- a/Mathlib/CategoryTheory/SmallObject/Construction.lean +++ b/Mathlib/CategoryTheory/SmallObject/Construction.lean @@ -322,8 +322,8 @@ end variable [HasPushouts C] [∀ {X S : C} (πX : X ⟶ S), HasColimitsOfShape (Discrete (FunctorObjIndex f πX)) C] -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in /-- The functor `Arrow C ⥤ Arrow C` that is constructed in order to apply the small object argument to a family of morphisms `f i : A i ⟶ B i`, see the introduction of the file `Mathlib/CategoryTheory/SmallObject/Construction.lean` -/ @@ -348,6 +348,7 @@ noncomputable def functor : Arrow C ⥤ Arrow C where (t ≫ (τ ≫ τ').left) (by simp)] · dsimp +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical natural transformation `𝟭 (Arrow C) ⟶ functor f`. -/ @[simps app] diff --git a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean index cafe1921428c54..97112b1dcfecac 100644 --- a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean +++ b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean @@ -133,6 +133,7 @@ noncomputable def succStruct : SuccStruct (Arrow C ⥤ Arrow C) := haveI := hasPushouts I κ SuccStruct.ofNatTrans (ε I.homFamily) +set_option backward.isDefEq.respectTransparency.types false in /-- For the successor structure `succStruct I κ` on `Arrow C ⥤ Arrow C`, the morphism from an object to its successor induces morphisms in `C` which consists in attaching `I`-cells. -/ @@ -154,6 +155,7 @@ isomorphisms on the right side. -/ def propArrow : MorphismProperty (Arrow C) := fun _ _ f ↦ (coproducts.{w} I).pushouts f.left ∧ (isomorphisms C) f.right +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma succStruct_prop_le_propArrow : (succStruct I κ).prop ≤ (propArrow.{w} I).functorCategory (Arrow C) := by @@ -217,7 +219,6 @@ instance {j₁ j₂ : κ.ord.ToType} (φ : j₁ ⟶ j₂) (f : Arrow C) : IsIso (((iterationFunctor I κ).map φ).app f).right := inferInstanceAs (IsIso ((transfiniteCompositionOfShapeιIterationAppRight I κ f).F.map φ)) -set_option backward.isDefEq.respectTransparency false in /-- For any `f : Arrow C`, the object `((iteration I κ).obj f).right` identifies to `f.right`. -/ @[simps! hom] @@ -233,6 +234,7 @@ noncomputable def iterationFunctorObjObjRightIso (f : Arrow C) (j : κ.ord.ToTyp asIso ((transfiniteCompositionOfShapeιIterationAppRight I κ f).incl.app j) ≪≫ (iterationObjRightIso I κ f).symm +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma iterationFunctorObjObjRightIso_ιIteration_app_right (f : Arrow C) (j : κ.ord.ToType) : @@ -301,6 +303,7 @@ the small object argument. -/ noncomputable def πObj : obj I κ f ⟶ Y := ((iteration I κ).obj (Arrow.mk f)).hom ≫ inv ((ιIteration I κ).app f).right +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma πObj_ιIteration_app_right : πObj I κ f ≫ ((ιIteration I κ).app f).right = @@ -449,6 +452,7 @@ lemma πObj_naturality {f g : Arrow C} (φ : f ⟶ g) : rw [← assoc] apply comp_id +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functorial factorization `ιObj I κ f ≫ πObj I κ f.hom = f` with `ιObj I κ f` in `I.rlp.llp` and `πObj I κ f.hom` in `I.rlp`. -/ diff --git a/Mathlib/CategoryTheory/SmallObject/Iteration/Basic.lean b/Mathlib/CategoryTheory/SmallObject/Iteration/Basic.lean index ac5a0ee0e8329a..73df1b0563b163 100644 --- a/Mathlib/CategoryTheory/SmallObject/Iteration/Basic.lean +++ b/Mathlib/CategoryTheory/SmallObject/Iteration/Basic.lean @@ -92,6 +92,7 @@ def restrictionLT : Set.Iio i ⥤ C := lemma restrictionLT_obj (k : J) (hk : k < i) : (restrictionLT F hi).obj ⟨k, hk⟩ = F.obj ⟨k, hk.le.trans hi⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrictionLT_map {k₁ k₂ : Set.Iio i} (φ : k₁ ⟶ k₂) : (restrictionLT F hi).map φ = F.map (homOfLE (by simpa using leOfHom φ)) := rfl @@ -361,6 +362,7 @@ lemma ext (h : ∀ (k₁ k₂ : K) (h₁₂ : k₁ ≤ k₂) (h₂ : k₂ ≤ x) end subsingleton +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open subsingleton in instance subsingleton : Subsingleton (Φ.Iteration j) where diff --git a/Mathlib/CategoryTheory/SmallObject/Iteration/Nonempty.lean b/Mathlib/CategoryTheory/SmallObject/Iteration/Nonempty.lean index 74249097eeffaf..ae93620935c8b4 100644 --- a/Mathlib/CategoryTheory/SmallObject/Iteration/Nonempty.lean +++ b/Mathlib/CategoryTheory/SmallObject/Iteration/Nonempty.lean @@ -48,7 +48,6 @@ variable {Φ} set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in -open Functor in /-- When `j : J` is not maximal, this is the extension in `Φ.Iteration (Order.succ j)` of any `iter : Φ.Iteration j`. -/ noncomputable def mkOfSucc {j : J} (hj : ¬IsMax j) (iter : Φ.Iteration j) : @@ -75,7 +74,6 @@ noncomputable def mkOfSucc {j : J} (hj : ¬IsMax j) (iter : Φ.Iteration j) : namespace mkOfLimit -open Functor variable {j : J} (hj : Order.IsSuccLimit j) (iter : ∀ (i : J), i < j → Φ.Iteration i) @@ -114,6 +112,7 @@ lemma arrowMap_functor_to_top (i : J) (hi : i < j) : end mkOfLimit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in open mkOfLimit in /-- When `j` is a limit element, this is the element in `Φ.Iteration j` diff --git a/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean b/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean index 5082529effdf28..21335c3648a1f7 100644 --- a/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean +++ b/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean @@ -169,6 +169,7 @@ lemma liftHom_fac (i : J) (hi : i < j) : F.map (homOfLE hi.le) ≫ liftHom hj s = (s.1 ⟨⟨i, hi⟩⟩).f' := (F.isColimitOfIsWellOrderContinuous j hj).fac _ ⟨i, hi⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Auxiliary definition for `transfiniteComposition.wellOrderInductionData`. -/ @[simps] @@ -185,6 +186,7 @@ noncomputable def lift : (sqFunctor c p f g).obj (Opposite.op j) where dsimp at this ⊢ rw [liftHom_fac_assoc _ _ _ hij, this, Cocone.w_assoc]) +set_option backward.isDefEq.respectTransparency.types false in lemma map_lift {i : J} (hij : i < j) : (lift hj s).map (homOfLE hij.le) = s.1 ⟨⟨i, hij⟩⟩ := by ext diff --git a/Mathlib/CategoryTheory/SmallObject/TransfiniteIteration.lean b/Mathlib/CategoryTheory/SmallObject/TransfiniteIteration.lean index eb3361f312a56a..92f03356cb32ef 100644 --- a/Mathlib/CategoryTheory/SmallObject/TransfiniteIteration.lean +++ b/Mathlib/CategoryTheory/SmallObject/TransfiniteIteration.lean @@ -36,6 +36,7 @@ variable {J} in this is the unique element in `Φ.Iteration j`. -/ noncomputable def iter (j : J) : Φ.Iteration j := Classical.arbitrary _ +set_option backward.isDefEq.respectTransparency.types false in /-- Given `Φ : SuccStruct C` and a well-ordered type `J`, this is the functor `J ⥤ C` which gives the iterations of `Φ` indexed by `J`. -/ noncomputable def iterationFunctor : J ⥤ C where @@ -61,10 +62,12 @@ noncomputable def isColimitIterationCocone : IsColimit (Φ.iterationCocone J) := variable {J} +set_option backward.isDefEq.respectTransparency.types false in lemma iterationFunctor_obj (i : J) {j : J} (iter : Φ.Iteration j) (hi : i ≤ j) : (Φ.iterationFunctor J).obj i = iter.F.obj ⟨i, hi⟩ := Iteration.congr_obj (Φ.iter i) iter i (by simp) hi +set_option backward.isDefEq.respectTransparency.types false in lemma arrowMk_iterationFunctor_map (i₁ i₂ : J) (h₁₂ : i₁ ≤ i₂) {j : J} (iter : Φ.Iteration j) (hj : i₂ ≤ j) : Arrow.mk ((Φ.iterationFunctor J).map (homOfLE h₁₂)) = @@ -76,6 +79,7 @@ lemma arrowMk_iterationFunctor_map (i₁ i₂ : J) (h₁₂ : i₁ ≤ i₂) variable (J) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : (Φ.iterationFunctor J).IsWellOrderContinuous where nonempty_isColimit i hi := ⟨by @@ -92,6 +96,7 @@ instance : (Φ.iterationFunctor J).IsWellOrderContinuous where apply Arrow.mk_injective simp [Φ.arrowMk_iterationFunctor_map k i hk.le (Φ.iter i) (by simp), e]⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism `(Φ.iterationFunctor J).obj ⊥ ≅ Φ.X₀`. -/ noncomputable def iterationFunctorObjBotIso : (Φ.iterationFunctor J).obj ⊥ ≅ Φ.X₀ := eqToIso (Φ.iter ⊥).obj_bot diff --git a/Mathlib/CategoryTheory/SmallObject/WellOrderInductionData.lean b/Mathlib/CategoryTheory/SmallObject/WellOrderInductionData.lean index 407d2a955eb81f..827828705ea903 100644 --- a/Mathlib/CategoryTheory/SmallObject/WellOrderInductionData.lean +++ b/Mathlib/CategoryTheory/SmallObject/WellOrderInductionData.lean @@ -209,6 +209,7 @@ def succ {j : J} (e : d.Extension val₀ j) (hj : ¬IsMax j) : variable [WellFoundedLT J] +set_option backward.isDefEq.respectTransparency.types false in /-- When `j` is a limit element, this is the extension to `d.Extension val₀ j` of a family of elements in `d.Extension val₀ i` for all `i < j`. -/ def limit (j : J) (hj : Order.IsSuccLimit j) diff --git a/Mathlib/CategoryTheory/SmallRepresentatives.lean b/Mathlib/CategoryTheory/SmallRepresentatives.lean index 9c0f318dc1c217..e608101c8b730b 100644 --- a/Mathlib/CategoryTheory/SmallRepresentatives.lean +++ b/Mathlib/CategoryTheory/SmallRepresentatives.lean @@ -95,6 +95,7 @@ def smallCategoryOfSet : SmallCategoryOfSet Ω where id X := h.homEquiv.symm (𝟙 _) comp f g := h.homEquiv.symm (h.homEquiv f ≫ h.homEquiv g) +set_option backward.isDefEq.respectTransparency.types false in /-- Given `h : CoreSmallCategoryOfSet Ω C`, this is the obvious functor `h.smallCategoryOfSet.obj ⥤ C`. -/ @[simps!] @@ -104,11 +105,13 @@ def functor : h.smallCategoryOfSet.obj ⥤ C where map_id _ := by rw [SmallCategoryOfSet.id_def]; simp map_comp _ _ := by rw [SmallCategoryOfSet.comp_def]; simp +set_option backward.isDefEq.respectTransparency.types false in /-- Given `h : CoreSmallCategoryOfSet Ω C`, the obvious functor `h.smallCategoryOfSet.obj ⥤ C` is fully faithful. -/ def fullyFaithfulFunctor : h.functor.FullyFaithful where preimage := h.homEquiv.symm +set_option backward.isDefEq.respectTransparency.types false in instance : h.functor.IsEquivalence where faithful := h.fullyFaithfulFunctor.faithful full := h.fullyFaithfulFunctor.full @@ -121,6 +124,7 @@ the obvious functor `h.smallCategoryOfSet.obj ⥤ C` is an equivalence. -/ noncomputable def equivalence : h.smallCategoryOfSet.obj ≌ C := h.functor.asEquivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Given `h : CoreSmallCategoryOfSet Ω C`, the equivalence of categories `h.smallCategoryOfSet.obj ≌ C` is actually an isomorphism: it induces diff --git a/Mathlib/CategoryTheory/Square.lean b/Mathlib/CategoryTheory/Square.lean index 01242d1c7c953d..3c1080dde4f6f7 100644 --- a/Mathlib/CategoryTheory/Square.lean +++ b/Mathlib/CategoryTheory/Square.lean @@ -168,6 +168,7 @@ def flipFunctor : Square C ⥤ Square C where τ₃ := φ.τ₂ τ₄ := φ.τ₄ } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Flipping commutative squares is an auto-equivalence. -/ @[simps] @@ -177,6 +178,7 @@ def flipEquivalence : Square C ≌ Square C where unitIso := Iso.refl _ counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `Square C ⥤ Arrow (Arrow C)` which sends a commutative square `sq` to the obvious arrow from the left morphism of `sq` @@ -203,6 +205,7 @@ def fromArrowArrowFunctor : Arrow (Arrow C) ⥤ Square C where comm₂₄ := φ.right.w.symm comm₃₄ := Arrow.rightFunc.congr_map φ.w.symm } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Square C ≌ Arrow (Arrow C)` which sends a commutative square `sq` to the obvious arrow from the left morphism of `sq` @@ -214,6 +217,7 @@ def arrowArrowEquivalence : Square C ≌ Arrow (Arrow C) where unitIso := Iso.refl _ counitIso := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The functor `Square C ⥤ Arrow (Arrow C)` which sends a commutative square `sq` to the obvious arrow from the top morphism of `sq` @@ -240,6 +244,7 @@ def fromArrowArrowFunctor' : Arrow (Arrow C) ⥤ Square C where comm₂₄ := Arrow.rightFunc.congr_map φ.w.symm comm₃₄ := φ.right.w.symm } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Square C ≌ Arrow (Arrow C)` which sends a commutative square `sq` to the obvious arrow from the top morphism of `sq` @@ -363,6 +368,7 @@ def mapSquare (F : C ⥤ D) : Square C ⥤ Square D where end Functor +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The natural transformation `F.mapSquare ⟶ G.mapSquare` induces by a natural transformation `F ⟶ G`. -/ @@ -375,6 +381,7 @@ def NatTrans.mapSquare {F G : C ⥤ D} (τ : F ⟶ G) : τ₃ := τ.app _ τ₄ := τ.app _ } +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `(C ⥤ D) ⥤ Square C ⥤ Square D`. -/ @[simps] def Square.mapFunctor : (C ⥤ D) ⥤ Square C ⥤ Square D where diff --git a/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean b/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean index 71b89df27f1ac2..e22f8db9518de2 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean @@ -48,10 +48,12 @@ lemma equalizer_le : Subfunctor.equalizer f g ≤ A := @[simp] lemma equalizer_self : Subfunctor.equalizer f f = A := by aesop +set_option backward.isDefEq.respectTransparency.types false in lemma mem_equalizer_iff {i : C} (x : A.toFunctor.obj i) : x.1 ∈ (Subfunctor.equalizer f g).obj i ↔ f.app i x = g.app i x := by simp +set_option backward.isDefEq.respectTransparency.types false in lemma range_le_equalizer_iff {G : C ⥤ Type w} (φ : G ⟶ A.toFunctor) : range (φ ≫ A.ι) ≤ Subfunctor.equalizer f g ↔ φ ≫ f = φ ≫ g := by rw [NatTrans.ext_iff] @@ -116,6 +118,7 @@ def equalizer.fork : Limits.Fork f g := lemma equalizer.fork_ι : (equalizer.fork f g).ι = equalizer.ι f g := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `(Subfunctor.equalizer f g).toFunctor` is the equalizer of `f` and `g`. -/ def equalizer.forkIsLimit : Limits.IsLimit (equalizer.fork f g) := diff --git a/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean b/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean index 87d219e5158e06..eca77b33d8bab6 100644 --- a/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean +++ b/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean @@ -154,6 +154,7 @@ lemma comap_id : comap (𝟙 M) ⊤ = ⊤ := rfl @[simp] lemma comap_comp (p' : M' ⟶ M'') : S''.comap (p ≫ p') = (S''.comap p').comap p := by rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma image_comap_ι : image S.ι (comap S.ι S) = S := by aesop diff --git a/Mathlib/CategoryTheory/Subobject/ArtinianObject.lean b/Mathlib/CategoryTheory/Subobject/ArtinianObject.lean index ca98d7c0d4f556..60d30eaa66f18f 100644 --- a/Mathlib/CategoryTheory/Subobject/ArtinianObject.lean +++ b/Mathlib/CategoryTheory/Subobject/ArtinianObject.lean @@ -86,6 +86,7 @@ lemma not_strictAnti_of_isArtinianObject ¬ StrictAnti f := (isArtinianObject_iff_not_strictAnti X).1 inferInstance f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isArtinianObject_iff_isEventuallyConstant : IsArtinianObject X ↔ ∀ (F : ℕ ⥤ (MonoOver X)ᵒᵖ), diff --git a/Mathlib/CategoryTheory/Subobject/Basic.lean b/Mathlib/CategoryTheory/Subobject/Basic.lean index 7fea3ab1d23c74..0c963cfc550f26 100644 --- a/Mathlib/CategoryTheory/Subobject/Basic.lean +++ b/Mathlib/CategoryTheory/Subobject/Basic.lean @@ -99,6 +99,7 @@ with morphisms becoming inequalities, and isomorphisms becoming equations. /-- The category of subobjects of `X : C`, defined as isomorphism classes of monomorphisms into `X`. -/ +@[implicit_reducible] def Subobject (X : C) := ThinSkeleton (MonoOver X) @@ -110,6 +111,7 @@ namespace Subobject lemma skeletal (X : C) : Skeletal (Subobject X) := ThinSkeleton.skeletal /-- Convenience constructor for a subobject. -/ +@[implicit_reducible] def mk {X A : C} (f : A ⟶ X) [Mono f] : Subobject X := (toThinSkeleton _).obj (MonoOver.mk f) @@ -486,6 +488,7 @@ namespace Subobject /-- Any functor `MonoOver X ⥤ MonoOver Y` descends to a functor `Subobject X ⥤ Subobject Y`, because `MonoOver Y` is thin. -/ +@[implicit_reducible] def lower {Y : D} (F : MonoOver X ⥤ MonoOver Y) : Subobject X ⥤ Subobject Y := ThinSkeleton.map F @@ -518,6 +521,7 @@ def lowerAdjunction {A : C} {B : D} {L : MonoOver A ⥤ MonoOver B} {R : MonoOve (h : L ⊣ R) : lower L ⊣ lower R := ThinSkeleton.lowerAdjunction _ _ h +set_option backward.isDefEq.respectTransparency.types false in /-- An equivalence between `MonoOver A` and `MonoOver B` gives an equivalence between `Subobject A` and `Subobject B`. -/ @[simps] @@ -663,6 +667,7 @@ lemma map_obj_injective {X Y : C} (f : X ⟶ Y) [Mono f] : def mapIso {A B : C} (e : A ≅ B) : Subobject A ≌ Subobject B := lowerEquivalence (MonoOver.mapIso e) +set_option backward.isDefEq.respectTransparency.types false in /-- In fact, there's a type level bijection between the subobjects of isomorphic objects, which preserves the order. -/ @[simps] @@ -755,6 +760,9 @@ def existsIsoImage (f : X ⟶ Y) (x : Subobject X) : ((«exists» f).obj x : C) ≅ Limits.image (x.arrow ≫ f) := (MonoOver.forget Y ⋙ Over.forget Y).mapIso <| (existsCompRepresentativeIso f).app x +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a subobject `x`, the `ImageFactorisation` of `x.arrow ≫ f` through `(exists f).obj x`. -/ @[simps! F_I F_m] def imageFactorisation (f : X ⟶ Y) (x : Subobject X) : diff --git a/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean b/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean index 4f7658e683f1a0..54459eda41eeb3 100644 --- a/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean +++ b/Mathlib/CategoryTheory/Subobject/Classifier/Defs.lean @@ -59,7 +59,7 @@ universe v v₀ u u₀ namespace CategoryTheory -open Category Limits Functor IsPullback +open Category Limits CategoryTheory.Functor IsPullback variable {C : Type u} [Category.{v} C] @@ -151,7 +151,7 @@ alias _root_.CategoryTheory.Classifier.isTerminalFrom_eq_χ₀ := isTerminalFrom end Subobject.Classifier -open Subobject +open CategoryTheory.Subobject /-- A category `C` has a subobject classifier if there is at least one subobject classifier. -/ class HasSubobjectClassifier (C : Type u) [Category.{v} C] : Prop where /-- There is some classifier. -/ @@ -410,6 +410,7 @@ alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.homEquiv_eq := ho @[deprecated (since := "2026-03-06")] alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.homEquiv_eq := homEquiv_eq +set_option backward.isDefEq.respectTransparency.types false in /-- For any subobject `x`, the pullback of `h.Ω₀` along the characteristic map of `x` given by `h.homEquiv` is `x` itself. -/ lemma pullback_homEquiv_symm_obj_Ω₀ {X : C} (x : Subobject X) : @@ -485,6 +486,9 @@ alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_left_π : @[deprecated (since := "2026-03-06")] alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.iso_inv_left_π := iso_inv_left_π +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma iso_inv_hom_left_comp : (h.iso m).inv.hom.left ≫ m = @@ -514,6 +518,7 @@ alias _root.CategoryTheory.Classifier.SubobjectRepresentableBy.isPullback := isP alias _root_.CategoryTheory.Classifier.SubobjectRepresentableBy.isPullback := isPullback variable {m} +set_option backward.isDefEq.respectTransparency.types false in lemma uniq {χ' : X ⟶ Ω} {π : U ⟶ h.Ω₀} (sq : IsPullback m π χ' h.Ω₀.arrow) : χ' = h.χ m := by apply h.homEquiv.injective @@ -698,7 +703,6 @@ section Equivalence variable {D : Type*} [Category* D] -set_option backward.isDefEq.respectTransparency false in /-- The image of a subobject classifier under an equivalence of categories is a subobject classifier. -/ diff --git a/Mathlib/CategoryTheory/Subobject/Comma.lean b/Mathlib/CategoryTheory/Subobject/Comma.lean index c5bd4589e1434d..fed0c00a4cd14a 100644 --- a/Mathlib/CategoryTheory/Subobject/Comma.lean +++ b/Mathlib/CategoryTheory/Subobject/Comma.lean @@ -146,6 +146,7 @@ theorem projectQuotient_mk [HasFiniteColimits C] [PreservesFiniteColimits S] projectQuotient (Subobject.mk f) = Subobject.mk f.unop.left.op := rfl +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in theorem projectQuotient_factors [HasFiniteColimits C] [PreservesFiniteColimits S] {A : CostructuredArrow S T} : diff --git a/Mathlib/CategoryTheory/Subobject/FactorThru.lean b/Mathlib/CategoryTheory/Subobject/FactorThru.lean index f0166d43fd21d1..0b54ef34f7fb92 100644 --- a/Mathlib/CategoryTheory/Subobject/FactorThru.lean +++ b/Mathlib/CategoryTheory/Subobject/FactorThru.lean @@ -96,6 +96,7 @@ set_option backward.isDefEq.respectTransparency false in theorem factors_zero [HasZeroMorphisms C] {X Y : C} {P : Subobject Y} : P.Factors (0 : X ⟶ Y) := (factors_iff _ _).mpr ⟨0, by simp⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem factors_of_le {Y Z : C} {P Q : Subobject Y} (f : Z ⟶ Y) (h : P ≤ Q) : P.Factors f → Q.Factors f := by simp only [factors_iff] diff --git a/Mathlib/CategoryTheory/Subobject/Lattice.lean b/Mathlib/CategoryTheory/Subobject/Lattice.lean index 25010ffedb4569..f89923ac380ce7 100644 --- a/Mathlib/CategoryTheory/Subobject/Lattice.lean +++ b/Mathlib/CategoryTheory/Subobject/Lattice.lean @@ -173,18 +173,21 @@ and which on `Subobject A` will induce a `SemilatticeSup`. -/ def sup {A : C} : MonoOver A ⥤ MonoOver A ⥤ MonoOver A := Functor.curryObj ((forget A).prod (forget A) ⋙ Functor.uncurry.obj Over.coprod ⋙ image) +set_option backward.isDefEq.respectTransparency.types false in /-- A morphism version of `le_sup_left`. -/ def leSupLeft {A : C} (f g : MonoOver A) : f ⟶ (sup.obj f).obj g := by refine homMk (coprod.inl ≫ factorThruImage _) ?_ erw [Category.assoc, image.fac, coprod.inl_desc] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- A morphism version of `le_sup_right`. -/ def leSupRight {A : C} (f g : MonoOver A) : g ⟶ (sup.obj f).obj g := by refine homMk (coprod.inr ≫ factorThruImage _) ?_ erw [Category.assoc, image.fac, coprod.inr_desc] rfl +set_option backward.isDefEq.respectTransparency false in set_option backward.defeqAttrib.useBackward true in /-- A morphism version of `sup_le`. -/ def supLe {A : C} (f g h : MonoOver A) : (f ⟶ h) → (g ⟶ h) → ((sup.obj f).obj g ⟶ h) := by @@ -216,10 +219,12 @@ instance {X : C} : Inhabited (Subobject X) := theorem top_eq_id (B : C) : (⊤ : Subobject B) = Subobject.mk (𝟙 B) := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem underlyingIso_top_hom {B : C} : (underlyingIso (𝟙 B)).hom = (⊤ : Subobject B).arrow := by convert! underlyingIso_hom_comp_eq_mk (𝟙 B) simp only [comp_id] +set_option backward.isDefEq.respectTransparency.types false in instance top_arrow_isIso {B : C} : IsIso (⊤ : Subobject B).arrow := by rw [← underlyingIso_top_hom] infer_instance @@ -725,6 +730,7 @@ end ZeroObject section SubobjectSubobject +set_option backward.isDefEq.respectTransparency.types false in /-- The subobject lattice of a subobject `Y` is order isomorphic to the interval `Set.Iic Y`. -/ def subobjectOrderIso {X : C} (Y : Subobject X) : Subobject (Y : C) ≃o Set.Iic Y where toFun Z := diff --git a/Mathlib/CategoryTheory/Subobject/Limits.lean b/Mathlib/CategoryTheory/Subobject/Limits.lean index 5039f77ffc8108..c06870c1d8a379 100644 --- a/Mathlib/CategoryTheory/Subobject/Limits.lean +++ b/Mathlib/CategoryTheory/Subobject/Limits.lean @@ -178,6 +178,9 @@ def kernelSubobjectMap (sq : Arrow.mk f ⟶ Arrow.mk f') : Subobject.factorThru _ ((kernelSubobject f).arrow ≫ sq.left) (kernelSubobject_factors _ _ (by simp)) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp), elementwise (attr := simp)] theorem kernelSubobjectMap_arrow (sq : Arrow.mk f ⟶ Arrow.mk f') : @@ -449,6 +452,9 @@ def imageSubobjectMap {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z} [Ha (imageSubobject f : C) ⟶ (imageSubobject g : C) := (imageSubobjectIso f).hom ≫ image.map sq ≫ (imageSubobjectIso g).inv +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] theorem imageSubobjectMap_arrow {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z} [HasImage g] diff --git a/Mathlib/CategoryTheory/Subobject/MonoOver.lean b/Mathlib/CategoryTheory/Subobject/MonoOver.lean index e026bebecc1bae..b4f26117d52af2 100644 --- a/Mathlib/CategoryTheory/Subobject/MonoOver.lean +++ b/Mathlib/CategoryTheory/Subobject/MonoOver.lean @@ -351,6 +351,7 @@ theorem map_obj_left (f : X ⟶ Y) [Mono f] (g : MonoOver X) : ((map f).obj g : theorem map_obj_arrow (f : X ⟶ Y) [Mono f] (g : MonoOver X) : ((map f).obj g).arrow = g.arrow ≫ f := rfl +set_option backward.isDefEq.respectTransparency.types false in instance full_map (f : X ⟶ Y) [Mono f] : Functor.Full (map f) where map_surjective {g h} e := by refine ⟨homMk e.hom.left ?_, rfl⟩ @@ -372,6 +373,7 @@ section variable (X) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories `e` between `C` and `D` induces an equivalence between `MonoOver X` and `MonoOver (e.functor.obj X)` whenever `X` is an object of `C`. -/ diff --git a/Mathlib/CategoryTheory/Subobject/NoetherianObject.lean b/Mathlib/CategoryTheory/Subobject/NoetherianObject.lean index 6cf3d8e3bfbecc..48e935f72d0493 100644 --- a/Mathlib/CategoryTheory/Subobject/NoetherianObject.lean +++ b/Mathlib/CategoryTheory/Subobject/NoetherianObject.lean @@ -84,6 +84,7 @@ lemma not_strictMono_of_isNoetherianObject ¬ StrictMono f := (isNoetherianObject_iff_not_strictMono X).1 inferInstance f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isNoetherianObject_iff_isEventuallyConstant : IsNoetherianObject X ↔ ∀ (F : ℕ ⥤ MonoOver X), diff --git a/Mathlib/CategoryTheory/Sums/Associator.lean b/Mathlib/CategoryTheory/Sums/Associator.lean index acc651d121bfbf..46e3a84bca7561 100644 --- a/Mathlib/CategoryTheory/Sums/Associator.lean +++ b/Mathlib/CategoryTheory/Sums/Associator.lean @@ -48,12 +48,14 @@ theorem associator_map_inl_inl {X Y : C} (f : X ⟶ Y) : (associator C D E).map ((inl_ _ _).map ((inl_ _ _).map f)) = (inl_ _ _).map f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem associator_map_inl_inr {X Y : D} (f : X ⟶ Y) : (associator C D E).map ((inl_ _ _).map ((inr_ _ _).map f)) = (inr_ _ _).map ((inl_ _ _).map f) := by simp [associator] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem associator_map_inr {X Y : E} (f : X ⟶ Y) : (associator C D E).map ((inr_ _ _).map f) = (inr_ _ _).map ((inr_ _ _).map f) := by @@ -99,11 +101,13 @@ theorem inverseAssociator_obj_inr_inl (X) : theorem inverseAssociator_obj_inr_inr (X) : (inverseAssociator C D E).obj (inr (inr X)) = inr X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem inverseAssociator_map_inl {X Y : C} (f : X ⟶ Y) : (inverseAssociator C D E).map ((inl_ _ _).map f) = (inl_ _ _).map ((inl_ _ _).map f) := by simp [inverseAssociator] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem inverseAssociator_map_inr_inl {X Y : D} (f : X ⟶ Y) : (inverseAssociator C D E).map ((inr_ _ _).map ((inl_ _ _).map f)) = @@ -142,6 +146,7 @@ def inrCompInrCompInverseAssociator : inr_ D E ⋙ inr_ C (D ⊕ E) ⋙ inverseAssociator C D E ≅ inr_ (C ⊕ D) E := isoWhiskerLeft (inr_ _ _) (inrCompInverseAssociator C D E) ≪≫ Functor.inrCompSum' _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories expressing associativity of sums of categories. -/ diff --git a/Mathlib/CategoryTheory/Sums/Basic.lean b/Mathlib/CategoryTheory/Sums/Basic.lean index bb2d9adb72a603..3f184091e52835 100644 --- a/Mathlib/CategoryTheory/Sums/Basic.lean +++ b/Mathlib/CategoryTheory/Sums/Basic.lean @@ -43,7 +43,7 @@ namespace CategoryTheory universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ -- morphism levels before object levels. See note [category_theory universes]. -open Sum Functor +open Sum CategoryTheory.Functor section @@ -187,11 +187,13 @@ theorem sum_obj_inl (F : A ⥤ B) (G : C ⥤ D) (a : A) : (F.sum G).obj (inl a) theorem sum_obj_inr (F : A ⥤ B) (G : C ⥤ D) (c : C) : (F.sum G).obj (inr c) = inr (G.obj c) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem sum_map_inl (F : A ⥤ B) (G : C ⥤ D) {a a' : A} (f : a ⟶ a') : (F.sum G).map ((Sum.inl_ _ _).map f) = (Sum.inl_ _ _).map (F.map f) := by simp [sum] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem sum_map_inr (F : A ⥤ B) (G : C ⥤ D) {c c' : C} (f : c ⟶ c') : (F.sum G).map ((Sum.inr_ _ _).map f) = (Sum.inr_ _ _).map (G.map f) := by diff --git a/Mathlib/CategoryTheory/Sums/Products.lean b/Mathlib/CategoryTheory/Sums/Products.lean index f8ec716ab7d39a..389df2bdfa2a43 100644 --- a/Mathlib/CategoryTheory/Sums/Products.lean +++ b/Mathlib/CategoryTheory/Sums/Products.lean @@ -22,9 +22,9 @@ the product side. namespace CategoryTheory -open Functor +open CategoryTheory.Functor -open scoped Prod +open scoped CategoryTheory.Prod universe v u @@ -105,6 +105,9 @@ def functorEquivInverseCompWhiskeringLeftInrIso : Prod.snd (A ⥤ B) (A' ⥤ B) := NatIso.ofComponents (fun _ ↦ Functor.inrCompSum' _ _) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A consequence of `functorEquiv`: we can construct a natural transformation of functors `A ⊕ A' ⥤ B` from the data of natural transformations of their whiskering with `inl_` and `inr_`. -/ @[simps!] @@ -115,12 +118,14 @@ def natTransOfWhiskerLeftInlInr {F G : A ⊕ A' ⥤ B} (Sum.functorEquiv A A' B).inverse.map ((η₁, η₂) :) ≫ (Sum.functorEquiv A A' B).unitInv.app G +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma natTransOfWhiskerLeftInlInr_id {F : A ⊕ A' ⥤ B} : natTransOfWhiskerLeftInlInr (𝟙 (Sum.inl_ A A' ⋙ F)) (𝟙 (Sum.inr_ A A' ⋙ F)) = 𝟙 F := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] lemma natTransOfWhiskerLeftInlInr_comp {F G H : A ⊕ A' ⥤ B} @@ -167,6 +172,7 @@ section CompatibilityWithProductAssociator variable (T : Type*) [Category* T] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence `Sum.functorEquiv` sends associativity of sums to associativity of products -/ @[simps! hom_app_fst hom_app_snd_fst hom_app_snd_snd inv_app_fst inv_app_snd_fst inv_app_snd_snd] diff --git a/Mathlib/CategoryTheory/Thin.lean b/Mathlib/CategoryTheory/Thin.lean index 5a37064b6da206..a998a79741ece9 100644 --- a/Mathlib/CategoryTheory/Thin.lean +++ b/Mathlib/CategoryTheory/Thin.lean @@ -36,7 +36,7 @@ variable [CategoryStruct.{v₁} C] [Quiver.IsThin C] /-- Construct a category instance from a `CategoryStruct`, using the fact that hom spaces are subsingletons to prove the axioms. -/ -@[implicit_reducible] +@[instance_reducible] def thin_category : Category C where end diff --git a/Mathlib/CategoryTheory/Topos/Sheaf.lean b/Mathlib/CategoryTheory/Topos/Sheaf.lean index 3260f5e1bd332a..880bd477bc5268 100644 --- a/Mathlib/CategoryTheory/Topos/Sheaf.lean +++ b/Mathlib/CategoryTheory/Topos/Sheaf.lean @@ -73,6 +73,7 @@ def Presheaf.χ (m : F ⟶ G) : G ⟶ Functor.sieves C where use F.map g.op a simp [ha, NatTrans.naturality_apply]⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma Presheaf.comp_χ_eq (m : F ⟶ G) : m ≫ Presheaf.χ m = (Functor.isTerminalConst _ Types.isTerminalPUnit).from F ≫ Presheaf.truth C := by ext @@ -135,6 +136,7 @@ end presheaf variable {J : GrothendieckTopology C} +set_option backward.isDefEq.respectTransparency.types false in open Presheaf in lemma GrothendieckTopology.isClosed_χ_app_apply_of_isSheaf_of_isSeparated {F G : Cᵒᵖ ⥤ Type (max u v)} (m : F ⟶ G) [Mono m] (hF : Presieve.IsSheaf J F) @@ -153,7 +155,7 @@ lemma GrothendieckTopology.isClosed_χ_app_apply_of_isSheaf_of_isSeparated op_comp, Functor.map_comp_apply] namespace Sheaf -open Functor +open CategoryTheory.Functor variable {F G : Sheaf J (Type max u v)} /-- The sheaf of closed sieves w/r/t `J`. See also `Functor.closedSieves` and `Sheaf.classifier` -/ @@ -164,6 +166,7 @@ def Ω (J : GrothendieckTopology C) : Sheaf J (Type max u v) where rw [CategoryTheory.isSheaf_iff_isSheaf_of_type] exact CategoryTheory.classifier_isSheaf J +set_option backward.isDefEq.respectTransparency.types false in /-- The morphism `t : 1 ⟶ Ω` which picks out the maximal sieve -/ @[simps] def truth (J : GrothendieckTopology C) : @@ -184,6 +187,7 @@ def χ (m : F ⟶ G) [Mono m] : G ⟶ Sheaf.Ω J where ((isSheaf_iff_isSheaf_of_type _ _).mp F.property) ((isSheaf_iff_isSheaf_of_type _ _).mp G.property).isSeparated _) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma isPullback_χ_truth (m : F ⟶ G) [Mono m] : IsPullback m ((isTerminalTerminal J _).from F) (Sheaf.χ m) (Sheaf.truth J) := by diff --git a/Mathlib/CategoryTheory/Triangulated/Adjunction.lean b/Mathlib/CategoryTheory/Triangulated/Adjunction.lean index f54281b54f7c25..bab4852725ca1f 100644 --- a/Mathlib/CategoryTheory/Triangulated/Adjunction.lean +++ b/Mathlib/CategoryTheory/Triangulated/Adjunction.lean @@ -131,7 +131,7 @@ lemma isTriangulated_rightAdjoint [F.IsTriangulated] : G.IsTriangulated where ← Functor.map_comp, right_triangle_components, Functor.map_id, comp_id] include adj in -open Pretriangulated.Opposite Functor in +open Pretriangulated.Opposite in /-- The left adjoint of a triangulated functor is triangulated. -/ diff --git a/Mathlib/CategoryTheory/Triangulated/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Basic.lean index f19199686ad02f..5437331252b7a0 100644 --- a/Mathlib/CategoryTheory/Triangulated/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Basic.lean @@ -471,7 +471,7 @@ end section -open Functor +open CategoryTheory.Functor variable {J : Type*} [Category* J] diff --git a/Mathlib/CategoryTheory/Triangulated/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Functor.lean index 369cfb722c445f..0a1bc6c116ae3d 100644 --- a/Mathlib/CategoryTheory/Triangulated/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Functor.lean @@ -60,8 +60,8 @@ instance [Faithful F] : Faithful F.mapTriangle where · exact congr_arg TriangleMorphism.hom₂ h · exact congr_arg TriangleMorphism.hom₃ h -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in instance [Full F] [Faithful F] : Full F.mapTriangle where map_surjective {X Y} f := ⟨{hom₁ := F.preimage f.hom₁ @@ -101,6 +101,7 @@ attribute [local simp] map_zsmul comp_zsmul zsmul_comp commShiftIso_zero commShiftIso_add commShiftIso_comp_hom_app shiftFunctorAdd'_eq_shiftFunctorAdd +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -- Split out from the following instance for faster elaboration. set_option backward.privateInPublic true in @@ -143,6 +144,7 @@ noncomputable def mapTriangleInvRotateIso : (by simp) (by simp) (by simp)) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable (C) in /-- The canonical isomorphism `(𝟭 C).mapTriangle ≅ 𝟭 (Triangle C)`. -/ @@ -150,14 +152,15 @@ variable (C) in def mapTriangleIdIso : (𝟭 C).mapTriangle ≅ 𝟭 _ := NatIso.ofComponents (fun T ↦ Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The canonical isomorphism `(F ⋙ G).mapTriangle ≅ F.mapTriangle ⋙ G.mapTriangle`. -/ @[simps!] def mapTriangleCompIso : (F ⋙ G).mapTriangle ≅ F.mapTriangle ⋙ G.mapTriangle := NatIso.ofComponents (fun T => Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) (Iso.refl _)) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Two isomorphic functors `F₁` and `F₂` induce isomorphic functors `F₁.mapTriangle` and `F₂.mapTriangle` if the isomorphism `F₁ ≅ F₂` is compatible with the shifts. -/ @@ -363,7 +366,6 @@ lemma isTriangulated_of_essSurj_mapComposableArrows_two (H := (someOctahedron rfl h₁₂' h₂₃' h₁₃').map F) ..⟩ set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma IsTriangulated.of_fully_faithful_triangulated_functor (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] [IsTriangulated D] : diff --git a/Mathlib/CategoryTheory/Triangulated/HomologicalFunctor.lean b/Mathlib/CategoryTheory/Triangulated/HomologicalFunctor.lean index 198d712223bef8..4f32afbacdae79 100644 --- a/Mathlib/CategoryTheory/Triangulated/HomologicalFunctor.lean +++ b/Mathlib/CategoryTheory/Triangulated/HomologicalFunctor.lean @@ -127,6 +127,7 @@ instance : F.homologicalKernel.IsTriangulated where end +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in noncomputable instance (priority := 100) [F.IsHomological] : PreservesLimitsOfShape (Discrete WalkingPair) F := by @@ -212,8 +213,8 @@ lemma homologySequence_comp : attribute [local simp] smul_smul +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma homologySequence_exact₂ : (ShortComplex.mk _ _ (F.homologySequence_comp T hT n₀)).Exact := by refine ShortComplex.exact_of_iso ?_ (F.map_distinguished_exact _ diff --git a/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean b/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean index dc0576d7f7409a..77d6d0e9276d00 100644 --- a/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/LocalizingSubcategory.lean @@ -157,7 +157,7 @@ and `B : ObjectProperty C`, this is the inclusion functor `A.ι : A.FullSubcategory ⥤ C`, considered as a localizer morphism, where `C` is equipped with the property of morphisms `B.trW` and `A.FullSubcategory` with the property of morphisms `(B.inverseImage A.ι).trW`. -/ -@[implicit_reducible] +@[instance_reducible] def triangulatedLocalizerMorphism [A.IsTriangulated] : LocalizerMorphism (B.inverseImage A.ι).trW B.trW where functor := A.ι @@ -174,6 +174,7 @@ instance [A.IsTriangulated] : (triangulatedLocalizerMorphism A B).functor.IsTriangulated := inferInstanceAs A.ι.IsTriangulated +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma trW_inverseImage_ι_iff [A.IsTriangulated] {X Y : A.FullSubcategory} (f : X ⟶ Y) : (B.inverseImage A.ι).trW f ↔ (A ⊓ B).trW f.hom := by @@ -190,6 +191,7 @@ lemma trW_inverseImage_ι_iff [A.IsTriangulated] {X Y : A.FullSubcategory} (f : · cat_disch · simp [dsimp% (A.ι.commShiftIso (1 : ℤ)).inv_hom_id_app X] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma inverseImage_opEquivalence_inverse_trW_inverseImage_ι_op [A.IsTriangulated] [B.IsTriangulated] [B.IsClosedUnderIsomorphisms] : @@ -206,6 +208,7 @@ variable [A.IsVerdierRightLocalizing B] (L₁ : A.FullSubcategory ⥤ D₁) (L₂ : C ⥤ D₂) [L₁.IsLocalization (B.inverseImage A.ι).trW] [L₂.IsLocalization B.trW] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : ((A.triangulatedLocalizerMorphism B).localizedFunctor L₁ L₂).Full := by let F := (A.triangulatedLocalizerMorphism B).localizedFunctor L₁ L₂ @@ -239,6 +242,7 @@ instance [Preadditive D₁] [Preadditive D₂] [L₁.Additive] [L₂.Additive] : (A.triangulatedLocalizerMorphism B).functor L₁ L₂ F exact Functor.additive_of_iso e +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : ((A.triangulatedLocalizerMorphism B).localizedFunctor L₁ L₂).Faithful := by let := Localization.preadditive L₁ (B.inverseImage A.ι).trW diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean index 03d775d4886f77..b46ca5fddbdf7b 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite/Basic.lean @@ -70,7 +70,7 @@ instance [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] (n : ℤ) end Opposite -open Opposite +open Pretriangulated.Opposite /-- The shift functor on the opposite category identifies to the opposite functor of a shift functor on the original category. -/ @@ -94,6 +94,7 @@ lemma shiftFunctorZero_op_inv_app (X : Cᵒᵖ) : shiftFunctorZero_op_hom_app, assoc, ← op_comp_assoc, Iso.hom_inv_id_app, op_id, id_comp, Iso.hom_inv_id_app] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma shiftFunctorAdd'_op_hom_app (X : Cᵒᵖ) (a₁ a₂ a₃ : ℤ) (h : a₁ + a₂ = a₃) (b₁ b₂ b₃ : ℤ) (h₁ : a₁ + b₁ = 0) (h₂ : a₂ + b₂ = 0) (h₃ : a₃ + b₃ = 0) : @@ -127,14 +128,14 @@ lemma shiftFunctor_op_map {K L : Cᵒᵖ} (φ : K ⟶ L) (n m : ℤ) (hnm : n + (shiftFunctorOpIso C n m hnm).inv.app L := (NatIso.naturality_2 (shiftFunctorOpIso C n m hnm) φ).symm -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in variable (C) in /-- The autoequivalence `Cᵒᵖ ≌ Cᵒᵖ` whose functor is `shiftFunctor Cᵒᵖ n` and whose inverse functor is `(shiftFunctor C n).op`. In most cases, it is not necessary to unfold the definitions of the unit and counit isomorphisms: the compatibilities they satisfy are stated as separate lemmas. -/ -@[simps functor inverse] +@[simps functor inverse, implicit_reducible] def opShiftFunctorEquivalence (n : ℤ) : Cᵒᵖ ≌ Cᵒᵖ where functor := shiftFunctor Cᵒᵖ n inverse := (shiftFunctor C n).op @@ -149,6 +150,9 @@ def opShiftFunctorEquivalence (n : ℤ) : Cᵒᵖ ≌ Cᵒᵖ where ((shiftFunctorCompIsoId C (-n) n (neg_add_cancel n)).hom.app X.unop)⟦-n⟧' = 𝟙 _ rw [shift_shiftFunctorCompIsoId_neg_add_cancel_hom_app n X.unop, Iso.inv_hom_id_app]) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma opShiftFunctorEquivalence_unitIso_hom_app (X : Cᵒᵖ) (n m : ℤ) (hnm : n + m = 0 := by lia) : (opShiftFunctorEquivalence C n).unitIso.hom.app X = @@ -157,6 +161,9 @@ lemma opShiftFunctorEquivalence_unitIso_hom_app (X : Cᵒᵖ) (n m : ℤ) (hnm : obtain rfl : m = -n := by lia rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma opShiftFunctorEquivalence_unitIso_inv_app (X : Cᵒᵖ) (n m : ℤ) (hnm : n + m = 0 := by lia) : (opShiftFunctorEquivalence C n).unitIso.inv.app X = @@ -165,6 +172,9 @@ lemma opShiftFunctorEquivalence_unitIso_inv_app (X : Cᵒᵖ) (n m : ℤ) (hnm : obtain rfl : m = -n := by lia rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma opShiftFunctorEquivalence_counitIso_hom_app (X : Cᵒᵖ) (n m : ℤ) (hnm : n + m = 0 := by lia) : (opShiftFunctorEquivalence C n).counitIso.hom.app X = @@ -174,6 +184,9 @@ lemma opShiftFunctorEquivalence_counitIso_hom_app (X : Cᵒᵖ) (n m : ℤ) (hnm obtain rfl : m = -n := by lia rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma opShiftFunctorEquivalence_counitIso_inv_app (X : Cᵒᵖ) (n m : ℤ) (hnm : n + m = 0 := by lia) : (opShiftFunctorEquivalence C n).counitIso.inv.app X = @@ -185,18 +198,27 @@ lemma opShiftFunctorEquivalence_counitIso_inv_app (X : Cᵒᵖ) (n m : ℤ) (hnm /-! The naturality of the unit and counit isomorphisms are restated in the following lemmas so as to mitigate the need for `erw`. -/ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma opShiftFunctorEquivalence_unitIso_hom_naturality (n : ℤ) {X Y : Cᵒᵖ} (f : X ⟶ Y) : f ≫ (opShiftFunctorEquivalence C n).unitIso.hom.app Y = (opShiftFunctorEquivalence C n).unitIso.hom.app X ≫ (f⟦n⟧').unop⟦n⟧'.op := (opShiftFunctorEquivalence C n).unitIso.hom.naturality f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma opShiftFunctorEquivalence_unitIso_inv_naturality (n : ℤ) {X Y : Cᵒᵖ} (f : X ⟶ Y) : (f⟦n⟧').unop⟦n⟧'.op ≫ (opShiftFunctorEquivalence C n).unitIso.inv.app Y = (opShiftFunctorEquivalence C n).unitIso.inv.app X ≫ f := (opShiftFunctorEquivalence C n).unitIso.inv.naturality f +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma opShiftFunctorEquivalence_counitIso_hom_naturality (n : ℤ) {X Y : Cᵒᵖ} (f : X ⟶ Y) : f.unop⟦n⟧'.op⟦n⟧' ≫ (opShiftFunctorEquivalence C n).counitIso.hom.app Y = @@ -210,8 +232,8 @@ lemma opShiftFunctorEquivalence_counitIso_inv_naturality (n : ℤ) {X Y : Cᵒ (opShiftFunctorEquivalence C n).counitIso.inv.app X ≫ f.unop⟦n⟧'.op⟦n⟧' := (opShiftFunctorEquivalence C n).counitIso.inv.naturality f -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in lemma opShiftFunctorEquivalence_zero_unitIso_hom_app (X : Cᵒᵖ) : (opShiftFunctorEquivalence C 0).unitIso.hom.app X = ((shiftFunctorZero C ℤ).hom.app X.unop).op ≫ diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Opposite/Functor.lean index a19b7a7a5fce3c..91417f9cf616e2 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite/Functor.lean @@ -95,6 +95,9 @@ lemma op_commShiftIso_inv_app (X : Cᵒᵖ) (n m : ℤ) (h : n + m = 0) : op_commShiftIso_hom_app _ X n m h, assoc, assoc] simp [← op_comp, ← F.map_comp] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma shift_map_op {X Y : C} (f : X ⟶ Y) (n : ℤ) : (F.map f).op⟦n⟧' = (F.op.commShiftIso n).inv.app _ ≫ @@ -191,6 +194,7 @@ noncomputable def mapTriangleOpCompTriangleOpEquivalenceFunctorApp (T : Triangle Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) (Iso.refl _) (by simp) (by simp) (by simp [shift_map_op, map_opShiftFunctorEquivalence_counitIso_inv_app_unop]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `F : C ⥤ D` commutes with shifts, this expresses the compatibility of `F.mapTriangle` @@ -236,7 +240,7 @@ end Functor namespace Pretriangulated.Opposite -open Functor in +open CategoryTheory.Functor in /-- If `F` is triangulated, so is `F.op`. -/ scoped instance functor_isTriangulated_op [F.IsTriangulated] : F.op.IsTriangulated where diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite/Pretriangulated.lean b/Mathlib/CategoryTheory/Triangulated/Opposite/Pretriangulated.lean index d1fb447df2ef62..791c3709cd01e5 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite/Pretriangulated.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite/Pretriangulated.lean @@ -49,7 +49,7 @@ variable (C : Type*) [Category* C] [HasShift C ℤ] [HasZeroObject C] [Preadditi namespace Pretriangulated -open Opposite +open Pretriangulated.Opposite namespace Opposite diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite/Triangle.lean b/Mathlib/CategoryTheory/Triangulated/Opposite/Triangle.lean index 75654096379349..20d6904dd93966 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite/Triangle.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite/Triangle.lean @@ -29,7 +29,7 @@ between `(Triangle C)ᵒᵖ` and `Triangle Cᵒᵖ`, called namespace CategoryTheory.Pretriangulated -open Category Limits Preadditive ZeroObject Opposite +open Category Limits Preadditive ZeroObject Pretriangulated.Opposite variable (C : Type*) [Category* C] [HasShift C ℤ] @@ -108,6 +108,7 @@ noncomputable def counitIso : inverse C ⋙ functor C ≅ 𝟭 _ := end TriangleOpEquivalence +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- An anti-equivalence between the categories of triangles in `C` and in `Cᵒᵖ`. A triangle in `Cᵒᵖ` shall be distinguished iff it corresponds to a distinguished diff --git a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean index 6c4dcfcabba059..bc7ac991508b45 100644 --- a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean +++ b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean @@ -169,8 +169,8 @@ lemma distinguished_cocone_triangle₁ {Y Z : C} (g : Y ⟶ Z) : obtain ⟨X', f', g', mem⟩ := distinguished_cocone_triangle g exact ⟨_, _, _, inv_rot_of_distTriang _ mem⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Any morphism `Z ⟶ X⟦1⟧` is part of a distinguished triangle `X ⟶ Y ⟶ Z ⟶ X⟦1⟧` -/ lemma distinguished_cocone_triangle₂ {Z X : C} (h : Z ⟶ X⟦(1 : ℤ)⟧) : ∃ (Y : C) (f : X ⟶ Y) (g : Y ⟶ Z), Triangle.mk f g h ∈ distTriang C := by @@ -182,6 +182,7 @@ lemma distinguished_cocone_triangle₂ {Z X : C} (h : Z ⟶ X⟦(1 : ℤ)⟧) : (by cat_disch) (by cat_disch) (by dsimp; simp only [shift_shiftFunctorCompIsoId_inv_app, id_comp]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A commutative square involving the morphisms `mor₂` of two distinguished triangles can be extended as morphism of triangles -/ @@ -242,6 +243,7 @@ namespace Triangle variable (T : Triangle C) (hT : T ∈ distTriang C) include hT +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma yoneda_exact₂ {X : C} (f : T.obj₂ ⟶ X) (hf : T.mor₁ ≫ f = 0) : ∃ (g : T.obj₃ ⟶ X), f = T.mor₂ ≫ g := by @@ -253,6 +255,7 @@ lemma yoneda_exact₃ {X : C} (f : T.obj₃ ⟶ X) (hf : T.mor₂ ≫ f = 0) : ∃ (g : T.obj₁⟦(1 : ℤ)⟧ ⟶ X), f = T.mor₃ ≫ g := yoneda_exact₂ _ (rot_of_distTriang _ hT) f hf +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma coyoneda_exact₂ {X : C} (f : X ⟶ T.obj₂) (hf : f ≫ T.mor₂ = 0) : ∃ (g : X ⟶ T.obj₁), f = g ≫ T.mor₁ := by diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index c8872e1255dff6..457c1cf42eb057 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -90,6 +90,7 @@ lemma ext_of_isTriangulatedClosed₃' (h₁ : P T.obj₁) (h₂ : P T.obj₂) : P.isoClosure T.obj₃ := IsTriangulatedClosed₃.ext₃' T hT h₁ h₂ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in protected lemma distinguished_cocone_triangle [P.IsTriangulatedClosed₃] {X Y : C} (a : X ⟶ Y) (hX : P X) (hY : P Y) : @@ -99,6 +100,7 @@ protected lemma distinguished_cocone_triangle [P.IsTriangulatedClosed₃] exact ⟨Z', hZ', b ≫ e.hom, e.inv ≫ c, isomorphic_distinguished _ h _ (Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) e.symm )⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in protected lemma distinguished_cocone_triangle₁ [P.IsTriangulatedClosed₁] {Y Z : C} (b : Y ⟶ Z) (hY : P Y) (hZ : P Z) : @@ -108,6 +110,7 @@ protected lemma distinguished_cocone_triangle₁ [P.IsTriangulatedClosed₁] exact ⟨X', hX', e.inv ≫ a, c ≫ e.hom⟦1⟧', isomorphic_distinguished _ h _ (Triangle.isoMk _ _ e.symm (Iso.refl _) (Iso.refl _))⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in protected lemma distinguished_cocone_triangle₂ [P.IsTriangulatedClosed₂] {X Z : C} (c : Z ⟶ X⟦(1 : ℤ)⟧) (hX : P X) (hZ : P Z) : @@ -636,6 +639,7 @@ instance [IsTriangulated C] [P.IsTriangulated] : P.trW.HasRightCalculusOfFractio dsimp at eq rw [← sub_eq_zero, ← comp_sub, hq, reassoc_of% eq, zero_comp] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance [IsTriangulated C] [P.IsTriangulated] : P.trW.IsCompatibleWithTriangulation := ⟨by rintro T₁ T₃ mem₁ mem₃ a b ⟨Z₅, g₅, h₅, mem₅, mem₅'⟩ ⟨Z₄, g₄, h₄, mem₄, mem₄'⟩ comm @@ -719,7 +723,6 @@ instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := IsTriangulated.of_fully_faithful_triangulated_functor P.ι set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] : F.essImage.IsTriangulated where isStableUnderShiftBy n := diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/AbelianSubcategory.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/AbelianSubcategory.lean index 4cf10b27ede892..a7e8cbc21860a7 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/AbelianSubcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/AbelianSubcategory.lean @@ -304,7 +304,7 @@ is abelian if the following conditions are satisfied: we complete `ι.obj f₁` in a distinguished triangle `ι.obj X₁ ⟶ ι.obj X₂ ⟶ X₃ ⟶ (ι.obj X₁)⟦1⟧`, there exists objects `K` and `Q`, and a distinguished triangle `(ι.obj K)⟦1⟧ ⟶ X₃ ⟶ (ι.obj Q) ⟶ ...`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def abelian [IsTriangulated C] : Abelian A := Abelian.mk' (fun X₁ X₂ f₁ ↦ by obtain ⟨X₃, f₂, f₃, hT⟩ := distinguished_cocone_triangle (ι.map f₁) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean index dfea1ee2660993..f0c00f382b1fd8 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean @@ -74,6 +74,7 @@ attribute [instance] le_isClosedUnderIsomorphisms ge_isClosedUnderIsomorphisms variable {C} variable (t : TStructure C) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma exists_triangle (A : C) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) : ∃ (X Y : C) (_ : t.le n₀ X) (_ : t.ge n₁ Y) (f : X ⟶ A) (g : A ⟶ Y) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index d098e1ecf37b55..338a974c1cef51 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -33,6 +33,7 @@ namespace TStructure variable (t : TStructure C) +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `EInt ⥤ C ⥤ C` which sends `⊥` to the zero functor, `n : ℤ` to `t.truncLT n` and `⊤` to `𝟭 C`. -/ noncomputable def eTruncLT : EInt ⥤ C ⥤ C where @@ -78,6 +79,7 @@ instance (i : EInt) : (t.eTruncLT.obj i).Additive := by induction i using WithBotTop.rec all_goals dsimp; infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- The functor `EInt ⥤ C ⥤ C` which sends `⊥` to `𝟭 C`, `n : ℤ` to `t.truncGE n` and `⊤` to the zero functor. -/ noncomputable def eTruncGE : EInt ⥤ C ⥤ C where @@ -321,7 +323,6 @@ lemma isIso_eTruncLT_obj_map_truncLTπ_app (a b : EInt) (h : a ≤ b) (X : C) : instance (a : EInt) (X : C) : IsIso ((t.eTruncLT.obj a).map ((t.eTruncLTι a).app X)) := isIso_eTruncLT_obj_map_truncLTπ_app t a a (by rfl) X -set_option backward.isDefEq.respectTransparency false in instance (a : EInt) (X : C) : IsIso ((t.eTruncLTι a).app ((t.eTruncLT.obj a).obj X)) := by rw [← eTruncLT_obj_map_eTruncLTι_app] infer_instance @@ -419,7 +420,6 @@ lemma eTruncLTLTIsoLT_inv_hom_id_app (X : C) : (t.eTruncLT.obj b).map ((t.eTruncLTι a).app X) = 𝟙 _ := by simpa using (t.eTruncLTLTIsoLT a b hab).inv_hom_id_app X -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma eTruncLTLTIsoLT_inv_hom_id_app_eTruncLT_obj (X : C) : (t.eTruncLTLTIsoLT a b hab).inv.app ((t.eTruncLT.obj a).obj X) ≫ @@ -516,7 +516,6 @@ lemma eTruncLTGEIsoGELT_hom_app_fac (a b : EInt) (X : C) : (t.eTruncLTι b).app ((t.eTruncGE.obj a).obj ((t.eTruncLT.obj b).obj X)) := by simp [eTruncLTGEIsoGELT] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma eTruncLTGEIsoGELT_hom_app_fac' (a b : EInt) (X : C) : (t.eTruncLTGEIsoGELT a b).hom.app X ≫ (t.eTruncGE.obj a).map ((t.eTruncLTι b).app X) = diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Heart.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Heart.lean index 0c258022806f56..7ee75dc56b1af7 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Heart.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Heart.lean @@ -65,7 +65,7 @@ class Heart where /-- Unless a better candidate category is available, the full subcategory of objects satisfying `t.heart` can be chosen as the heart of a t-structure `t`. -/ -@[implicit_reducible] +@[instance_reducible] def hasHeartFullSubcategory : t.Heart t.heart.FullSubcategory where ι := t.heart.ι essImage_eq_heart := by diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean index bb5805e3d402c9..84a8b2c28faf3b 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean @@ -59,7 +59,7 @@ section variable (a b c : EInt) (hab : a ≤ b) (hbc : b ≤ c) -open Functor in +open CategoryTheory.Functor in /-- The connecting homomorphism (as a natural transformation) for the spectral objects attached to the objects of a triangulated equipped with a t-structure. -/ @[simps!] @@ -99,7 +99,6 @@ noncomputable def triangleω₁δ : C ⥤ Triangle C := (t.ω₁.map (twoδ₁Toδ₀' a b c hab hbc)) (t.ω₁δ a b c hab hbc) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The triangle `(t.triangleω₁δ a b c hab hbc).obj X` is isomorphic to the (distinguished) triangle obtained by applying the functor `t.eTriangleLTGE.obj b` to the object `(t.eTruncGE.obj a).obj ((t.eTruncLT.obj c).obj X)`. -/ diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean index adf345f4437820..ff4866917ac5e7 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean @@ -94,6 +94,7 @@ lemma truncLEIsoTruncLT_hom_ι_app (a b : ℤ) (h : a + 1 = b) (X : C) : (t.truncLEIsoTruncLT a b h).hom.app X ≫ (t.truncLTι b).app X = (t.truncLEι a).app X := congr_app (t.truncLEIsoTruncLT_hom_ι a b h) X +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma truncLEIsoTruncLT_inv_ι (a b : ℤ) (h : a + 1 = b) : @@ -118,7 +119,6 @@ lemma natTransTruncLEOfLE_ι_app (n₀ n₁ : ℤ) (h : n₀ ≤ n₁) (X : C) : (t.truncLEι n₀).app X := t.natTransTruncLTOfLE_ι_app _ _ _ _ -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma natTransTruncLEOfLE_ι (a b : ℤ) (h : a ≤ b) : t.natTransTruncLEOfLE a b h ≫ t.truncLEι b = t.truncLEι a := by cat_disch @@ -162,6 +162,7 @@ lemma π_truncGTIsoTruncGE_hom_ι_app (a b : ℤ) (h : a + 1 = b) (X : C) : (t.truncGTπ a).app X ≫ (t.truncGTIsoTruncGE a b h).hom.app X = (t.truncGEπ b).app X := congr_app (t.π_truncGTIsoTruncGE_hom a b h) X +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma π_truncGTIsoTruncGE_inv (a b : ℤ) (h : a + 1 = b) : @@ -188,8 +189,8 @@ category `C` and `a + 1 = b`. -/ noncomputable def triangleLEGE (a b : ℤ) (h : a + 1 = b) : C ⥤ Triangle C := Triangle.functorMk (t.truncLEι a) (t.truncGEπ b) (t.truncGEδLE a b h) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The natural isomorphism of triangles `t.triangleLEGE a b h ≅ t.triangleLTGE b` when `a + 1 = b`. -/ noncomputable def triangleLEGEIsoTriangleLTGE (a b : ℤ) (h : a + 1 = b) : @@ -220,8 +221,8 @@ category `C` and `n : ℤ`. -/ noncomputable def triangleLEGT (n : ℤ) : C ⥤ Triangle C := Triangle.functorMk (t.truncLEι n) (t.truncGTπ n) (t.truncGTδLE n) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The natural isomorphism `t.triangleLEGT a ≅ t.triangleLEGE a b h` when `a + 1 = b`. -/ noncomputable def triangleLEGTIsoTriangleLEGE (a b : ℤ) (h : a + 1 = b) : @@ -268,7 +269,6 @@ lemma isZero_truncLE_obj_of_isGE (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) rw [← t.isGE_iff_isZero_truncLE_obj _ _ h X] infer_instance -set_option backward.isDefEq.respectTransparency false in lemma to_truncLE_obj_ext {n : ℤ} {Y : C} {X : C} {f₁ f₂ : Y ⟶ (t.truncLE n).obj X} (h : f₁ ≫ (t.truncLEι n).app X = f₂ ≫ (t.truncLEι n).app X) [t.IsLE Y n] : diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean index c6b767d4e658c6..7135a04b31317b 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean @@ -196,6 +196,7 @@ noncomputable def triangleFunctorNatTransOfLE (a b : ℤ) (h : a ≤ b) : lemma triangleFunctorNatTransOfLE_app_hom₂ (a b : ℤ) (h : a ≤ b) (X : C) : ((triangleFunctorNatTransOfLE t a b h).app X).hom₂ = 𝟙 X := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma triangleFunctorNatTransOfLE_trans (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) : triangleFunctorNatTransOfLE t a b hab ≫ triangleFunctorNatTransOfLE t b c hbc = @@ -324,18 +325,15 @@ lemma truncGEδLT_comp_truncLTι_app (n : ℤ) (X : C) : (t.truncGEδLT n).app X ≫ ((t.truncLTι n).app X)⟦(1 : ℤ)⟧' = 0 := comp_distTriang_mor_zero₃₁ _ (t.triangleLTGE_distinguished n X) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma truncLTι_comp_truncGEπ (n : ℤ) : t.truncLTι n ≫ t.truncGEπ n = 0 := by cat_disch -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma truncGEπ_comp_truncGEδLT (n : ℤ) : t.truncGEπ n ≫ t.truncGEδLT n = 0 := by cat_disch -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma truncGEδLT_comp_truncLTι (n : ℤ) : t.truncGEδLT n ≫ Functor.whiskerRight (t.truncLTι n) (shiftFunctor C (1 : ℤ)) = 0 := by @@ -351,18 +349,19 @@ noncomputable def natTransTruncGEOfLE (a b : ℤ) (h : a ≤ b) : t.truncGE a ⟶ t.truncGE b := Functor.whiskerRight (TruncAux.triangleFunctorNatTransOfLE t a b h) Triangle.π₃ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma natTransTruncLTOfLE_ι_app (a b : ℤ) (h : a ≤ b) (X : C) : (t.natTransTruncLTOfLE a b h).app X ≫ (t.truncLTι b).app X = (t.truncLTι a).app X := by simpa using! ((TruncAux.triangleFunctorNatTransOfLE t a b h).app X).comm₁.symm -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma natTransTruncLTOfLE_ι (a b : ℤ) (h : a ≤ b) : t.natTransTruncLTOfLE a b h ≫ t.truncLTι b = t.truncLTι a := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma π_natTransTruncGEOfLE_app (a b : ℤ) (h : a ≤ b) (X : C) : @@ -384,7 +383,6 @@ lemma truncGEδLT_comp_whiskerRight_natTransTruncLTOfLE (a b : ℤ) (h : a ≤ b ext X exact t.truncGEδLT_comp_natTransTruncLTOfLE_app a b h X -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma π_natTransTruncGEOfLE (a b : ℤ) (h : a ≤ b) : t.truncGEπ a ≫ t.natTransTruncGEOfLE a b h = t.truncGEπ b := by @@ -555,13 +553,11 @@ lemma to_truncLT_obj_ext {n : ℤ} {Y : C} {X : C} (by dsimp; apply (t.isGE_shift _ n (-1) (n + 1) (by lia))) rw [hg, hg', zero_comp] -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma truncLT_map_truncLTι_app (n : ℤ) (X : C) : (t.truncLT n).map ((t.truncLTι n).app X) = (t.truncLTι n).app ((t.truncLT n).obj X) := t.to_truncLT_obj_ext (by simp) -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma truncGE_map_truncGEπ_app (n : ℤ) (X : C) : (t.truncGE n).map ((t.truncGEπ n).app X) = (t.truncGEπ n).app ((t.truncGE n).obj X) := @@ -700,7 +696,6 @@ instance (X : C) (a b : ℤ) [t.IsLE X b] : t.IsLE ((t.truncLT a).obj X) b := by · have := (t.isLE_iff_isIso_truncLTι_app (a - 1) a (by lia) X).1 (t.isLE_of_le _ b _ (by lia)) exact t.isLE_of_iso (show X ≅ _ from (asIso ((t.truncLTι a).app X)).symm) _ -set_option backward.isDefEq.respectTransparency false in instance (X : C) (a b : ℤ) [t.IsGE X a] : t.IsGE ((t.truncGE b).obj X) a := by by_cases h : a ≤ b · exact t.isGE_truncGE_obj .. @@ -751,7 +746,6 @@ lemma isIso₂_truncGE_map_of_isLE (T : Triangle C) (hT : T ∈ distTriang C) exact t.isLE_of_shift X n₀ 1 (n₀ - 1) (by lia) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance (X : C) (a b : ℤ) [t.IsGE X a] : t.IsGE ((t.truncLT b).obj X) a := by rw [t.isGE_iff_isZero_truncLT_obj] @@ -762,7 +756,6 @@ instance (X : C) (a b : ℤ) [t.IsGE X a] : rwa [← isGE_iff_isZero_truncLT_obj] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance (X : C) (a b : ℤ) [t.IsLE X b] : t.IsLE ((t.truncGE a).obj X) b := by rw [t.isLE_iff_isZero_truncGE_obj b (b + 1) rfl] have := t.isIso₂_truncGE_map_of_isLE _ (t.triangleLTGE_distinguished a X) b _ rfl @@ -802,7 +795,6 @@ instance (a b : ℤ) (X : C) : rw [← t.isLE_iff_isIso_truncLTι_app (b - 1) b (by lia)] infer_instance -set_option backward.isDefEq.respectTransparency false in /-- The natural transformation `t.truncGELT a b ⟶ t.truncLTGE a b` (which is an isomorphism, see `truncGELTIsoLTGE`.) -/ noncomputable def truncGELTToLTGE (a b : ℤ) : @@ -812,14 +804,12 @@ noncomputable def truncGELTToLTGE (a b : ℤ) : naturality _ _ _ := t.to_truncLT_obj_ext (by dsimp; exact t.from_truncGE_obj_ext (by simp)) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma truncGELTToLTGE_app_pentagon (a b : ℤ) (X : C) : (t.truncGEπ a).app _ ≫ (t.truncGELTToLTGE a b).app X ≫ (t.truncLTι b).app _ = (t.truncLTι b).app X ≫ (t.truncGEπ a).app X := by simp [truncGELTToLTGE] -set_option backward.isDefEq.respectTransparency false in lemma truncGELTToLTGE_app_pentagon_uniqueness {a b : ℤ} {X : C} (φ : (t.truncGELT a b).obj X ⟶ (t.truncLTGE a b).obj X) (hφ : (t.truncGEπ a).app _ ≫ φ ≫ (t.truncLTι b).app _ = @@ -827,7 +817,6 @@ lemma truncGELTToLTGE_app_pentagon_uniqueness {a b : ℤ} {X : C} (t.truncGELTToLTGE a b).app X = φ := t.to_truncLT_obj_ext (by dsimp; exact t.from_truncGE_obj_ext (by cat_disch)) -set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma truncLT_map_truncGE_map_truncLTι_app_fac (a b : ℤ) (X : C) : (t.truncLTι b).app ((t.truncGE a).obj ((t.truncLT b).obj X)) ≫ @@ -855,7 +844,6 @@ noncomputable def triangleLTLTGELT (a b : ℤ) (h : a ≤ b) : C ⥤ Triangle C (Functor.whiskerLeft (t.truncLT b) (t.truncGEπ a)) (t.truncGELTδLT a b) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in lemma triangleLTLTGELT_distinguished (a b : ℤ) (h : a ≤ b) (X : C) : (t.triangleLTLTGELT a b h).obj X ∈ distTriang C := by have := t.isIso_truncLT_map_truncLTι_app a b h X @@ -867,7 +855,6 @@ lemma triangleLTLTGELT_distinguished (a b : ℤ) (h : a ≤ b) (X : C) : exact t.to_truncLT_obj_ext (by simp) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance (a b : ℤ) : IsIso (t.truncGELTToLTGE a b) := by rw [NatTrans.isIso_iff_isIso_app] intro X @@ -893,7 +880,6 @@ instance (a b : ℤ) : IsIso (t.truncGELTToLTGE a b) := by refine ⟨0, ?_, ?_⟩ all_goals exact IsZero.eq_of_src (t.isZero _ (b-1) a (by lia)) _ _ -set_option backward.isDefEq.respectTransparency false in instance (a b : ℤ) (X : C) : IsIso ((t.truncLT b).map ((t.truncGE a).map ((t.truncLTι b).app X))) := by rw [← t.truncLT_map_truncGE_map_truncLTι_app_fac a b X] diff --git a/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean b/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean index 07fe07961a8c2f..2cc1fdefd9845c 100644 --- a/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean +++ b/Mathlib/CategoryTheory/Triangulated/TriangleShift.lean @@ -158,8 +158,8 @@ noncomputable def invRotateIsoRotateRotateShiftFunctorNegOne : namespace Triangle -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in noncomputable instance : HasShift (Triangle C) ℤ := hasShiftMk (Triangle C) ℤ { F := Triangle.shiftFunctor C diff --git a/Mathlib/CategoryTheory/Triangulated/Yoneda.lean b/Mathlib/CategoryTheory/Triangulated/Yoneda.lean index ecefc73618f020..c37aa096149e65 100644 --- a/Mathlib/CategoryTheory/Triangulated/Yoneda.lean +++ b/Mathlib/CategoryTheory/Triangulated/Yoneda.lean @@ -94,6 +94,7 @@ lemma preadditiveYoneda_shiftMap_apply (B : C) {X Y : Cᵒᵖ} (n : ℤ) (f : X symm apply ShiftedHom.opEquiv_symm_apply_comp +set_option backward.isDefEq.respectTransparency.types false in lemma preadditiveYoneda_homologySequenceδ_apply (T : Triangle C) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) {B : C} (x : T.obj₁ ⟶ B⟦n₀⟧) : (preadditiveYoneda.obj B).homologySequenceδ diff --git a/Mathlib/CategoryTheory/Whiskering.lean b/Mathlib/CategoryTheory/Whiskering.lean index db8c41289954fc..2398d24cc69cda 100644 --- a/Mathlib/CategoryTheory/Whiskering.lean +++ b/Mathlib/CategoryTheory/Whiskering.lean @@ -41,7 +41,6 @@ section variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] {E : Type u₃} [Category.{v₃} E] -set_option backward.isDefEq.respectTransparency false in /-- If `α : G ⟶ H` then `whiskerLeft F α : F ⋙ G ⟶ F ⋙ H` has components `α.app (F.obj X)`. -/ @[to_dual self, simps (attr := to_dual self)] def whiskerLeft (F : C ⥤ D) {G H : D ⥤ E} (α : G ⟶ H) : @@ -55,7 +54,6 @@ lemma id_hcomp (F : C ⥤ D) {G H : D ⥤ E} (α : G ⟶ H) : 𝟙 F ◫ α = wh ext simp -set_option backward.isDefEq.respectTransparency false in /-- If `α : G ⟶ H` then `whiskerRight α F : G ⋙ F ⟶ H ⋙ F` has components `F.map (α.app X)`. -/ @[to_dual self, simps (attr := to_dual self)] def whiskerRight {G H : C ⥤ D} (α : G ⟶ H) (F : D ⥤ E) : @@ -78,7 +76,7 @@ set_option backward.defeqAttrib.useBackward true in `(whiskeringLeft.obj F).obj G` is `F ⋙ G`, and `(whiskeringLeft.obj F).map α` is `whiskerLeft F α`. -/ -@[simps] +@[simps, implicit_reducible] def whiskeringLeft : (C ⥤ D) ⥤ (D ⥤ E) ⥤ C ⥤ E where obj F := { obj := fun G => F ⋙ G @@ -95,7 +93,7 @@ set_option backward.defeqAttrib.useBackward true in `(whiskeringRight.obj H).obj F` is `F ⋙ H`, and `(whiskeringRight.obj H).map α` is `whiskerRight α H`. -/ -@[simps] +@[simps, implicit_reducible] def whiskeringRight : (D ⥤ E) ⥤ (C ⥤ D) ⥤ C ⥤ E where obj H := { obj := fun F => F ⋙ H @@ -114,6 +112,7 @@ instance faithful_whiskeringRight_obj {F : D ⥤ E} [F.Faithful] : ext X exact F.map_injective <| congr_fun (congr_arg NatTrans.app hαβ) X +set_option backward.isDefEq.respectTransparency false in /-- If `F : D ⥤ E` is fully faithful, then so is `(whiskeringRight C D E).obj F : (C ⥤ D) ⥤ C ⥤ E`. -/ @[simps] @@ -396,8 +395,9 @@ variable {C₁ C₂ C₃ D₁ D₂ D₃ : Type*} [Category* C₁] [Category* C [Category* D₁] [Category* D₂] [Category* D₃] (E : Type*) [Category* E] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- The obvious functor `(C₁ ⥤ D₁) ⥤ (C₂ ⥤ D₂) ⥤ (D₁ ⥤ D₂ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ E)`. -/ -@[simps!] +@[simps!, implicit_reducible] def whiskeringLeft₂ : (C₁ ⥤ D₁) ⥤ (C₂ ⥤ D₂) ⥤ (D₁ ⥤ D₂ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ E) where obj F₁ := @@ -417,6 +417,7 @@ def whiskeringLeft₃ObjObjObj (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) (F (whiskeringLeft C₁ D₁ _).obj F₁ set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `whiskeringLeft₃`. -/ @[simps] def whiskeringLeft₃ObjObjMap (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) {F₃ F₃' : C₃ ⥤ D₃} (τ₃ : F₃ ⟶ F₃') : @@ -424,6 +425,7 @@ def whiskeringLeft₃ObjObjMap (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) {F whiskeringLeft₃ObjObjObj E F₁ F₂ F₃' where app F := whiskerLeft _ (whiskerLeft _ (((whiskeringLeft₂ E).obj F₂).map τ₃)) +set_option backward.isDefEq.respectTransparency false in variable (C₃ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ @[simps] @@ -433,6 +435,7 @@ def whiskeringLeft₃ObjObj (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) : map τ₃ := whiskeringLeft₃ObjObjMap E F₁ F₂ τ₃ set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in variable (C₃ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ @[simps] @@ -449,6 +452,7 @@ def whiskeringLeft₃Obj (F₁ : C₁ ⥤ D₁) : map τ₂ := whiskeringLeft₃ObjMap C₃ D₃ E F₁ τ₂ set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in variable (C₂ C₃ D₂ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ @[simps] @@ -458,7 +462,7 @@ def whiskeringLeft₃Map {F₁ F₁' : C₁ ⥤ D₁} (τ₁ : F₁ ⟶ F₁') : /-- The obvious functor `(C₁ ⥤ D₁) ⥤ (C₂ ⥤ D₂) ⥤ (C₃ ⥤ D₃) ⥤ (D₁ ⥤ D₂ ⥤ D₃ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ C₃ ⥤ E)`. -/ -@[simps!] +@[simps!, implicit_reducible] def whiskeringLeft₃ : (C₁ ⥤ D₁) ⥤ (C₂ ⥤ D₂) ⥤ (C₃ ⥤ D₃) ⥤ (D₁ ⥤ D₂ ⥤ D₃ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ C₃ ⥤ E) where obj F₁ := whiskeringLeft₃Obj C₂ C₃ D₂ D₃ E F₁ @@ -468,14 +472,14 @@ variable {E} /-- The "postcomposition" with a functor `E ⥤ E'` gives a functor `(E ⥤ E') ⥤ (C₁ ⥤ C₂ ⥤ E) ⥤ C₁ ⥤ C₂ ⥤ E'`. -/ -@[simps!] +@[simps!, implicit_reducible] def postcompose₂ {E' : Type*} [Category* E'] : (E ⥤ E') ⥤ (C₁ ⥤ C₂ ⥤ E) ⥤ C₁ ⥤ C₂ ⥤ E' := whiskeringRight C₂ _ _ ⋙ whiskeringRight C₁ _ _ /-- The "postcomposition" with a functor `E ⥤ E'` gives a functor `(E ⥤ E') ⥤ (C₁ ⥤ C₂ ⥤ C₃ ⥤ E) ⥤ C₁ ⥤ C₂ ⥤ C₃ ⥤ E'`. -/ -@[simps!] +@[simps!, implicit_reducible] def postcompose₃ {E' : Type*} [Category* E'] : (E ⥤ E') ⥤ (C₁ ⥤ C₂ ⥤ C₃ ⥤ E) ⥤ C₁ ⥤ C₂ ⥤ C₃ ⥤ E' := whiskeringRight C₃ _ _ ⋙ whiskeringRight C₂ _ _ ⋙ whiskeringRight C₁ _ _ diff --git a/Mathlib/CategoryTheory/WithTerminal/Basic.lean b/Mathlib/CategoryTheory/WithTerminal/Basic.lean index f4986a2e85a677..548a8a17b3a371 100644 --- a/Mathlib/CategoryTheory/WithTerminal/Basic.lean +++ b/Mathlib/CategoryTheory/WithTerminal/Basic.lean @@ -98,32 +98,41 @@ attribute [nolint simpNF] comp.eq_2 comp.eq_4 @[aesop safe destruct (rule_sets := [CategoryTheory])] lemma false_of_from_star' {X : C} (f : Hom star (of X)) : False := (f : PEmpty).elim +set_option backward.isDefEq.respectTransparency.types false in instance : Category.{v} (WithTerminal C) where Hom X Y := Hom X Y id _ := id _ comp := comp +set_option backward.isDefEq.respectTransparency.types false in /-- Helper function for typechecking. -/ def down {X Y : C} (f : of X ⟶ of Y) : X ⟶ Y := f +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma down_id {X : C} : down (𝟙 (of X)) = 𝟙 X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma down_comp {X Y Z : C} (f : of X ⟶ of Y) (g : of Y ⟶ of Z) : down (f ≫ g) = down f ≫ down g := rfl +set_option backward.isDefEq.respectTransparency.types false in @[aesop safe destruct (rule_sets := [CategoryTheory])] lemma false_of_from_star {X : C} (f : star ⟶ of X) : False := (f : PEmpty).elim +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion from `C` into `WithTerminal C`. -/ def incl : C ⥤ WithTerminal C where obj := of map f := f +set_option backward.isDefEq.respectTransparency.types false in instance : (incl : C ⥤ _).Full where map_surjective f := ⟨f, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in instance : (incl : C ⥤ _).Faithful where +set_option backward.isDefEq.respectTransparency.types false in /-- Map `WithTerminal` with respect to a functor `F : C ⥤ D`. -/ @[simps] def map {D : Type*} [Category* D] (F : C ⥤ D) : WithTerminal C ⥤ WithTerminal D where @@ -137,6 +146,7 @@ def map {D : Type*} [Category* D] (F : C ⥤ D) : WithTerminal C ⥤ WithTermina | of _, star, _ => PUnit.unit | star, star, _ => PUnit.unit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural isomorphism between the functor `map (𝟭 C)` and `𝟭 (WithTerminal C)`. -/ @[simps!] @@ -145,6 +155,7 @@ def mapId (C : Type*) [Category* C] : map (𝟭 C) ≅ 𝟭 (WithTerminal C) := | of _ => Iso.refl _ | star => Iso.refl _) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural isomorphism between the functor `map (F ⋙ G) ` and `map F ⋙ map G `. -/ @[simps!] @@ -154,6 +165,7 @@ def mapComp {D E : Type*} [Category* D] [Category* E] (F : C ⥤ D) (G : D ⥤ E | of _ => Iso.refl _ | star => Iso.refl _) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in /-- From a natural transformation of functors `C ⥤ D`, the induced natural transformation of functors `WithTerminal C ⥤ WithTerminal D`. -/ @[simps] @@ -169,6 +181,7 @@ def map₂ {D : Type*} [Category* D] {F G : C ⥤ D} (η : F ⟶ G) : map F ⟶ | star, star, _ => rfl -- Note: ... +set_option backward.isDefEq.respectTransparency.types false in /-- The prelax functor from `Cat` to `Cat` defined with `WithTerminal`. -/ @[simps] def prelaxfunctor : PrelaxFunctor Cat Cat where @@ -225,6 +238,7 @@ def pseudofunctor : Pseudofunctor Cat Cat where · simpa using! (refl _) · rfl +set_option backward.isDefEq.respectTransparency.types false in instance {X : WithTerminal C} : Unique (X ⟶ star) where default := match X with @@ -232,10 +246,12 @@ instance {X : WithTerminal C} : Unique (X ⟶ star) where | star => PUnit.unit uniq := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- `WithTerminal.star` is terminal. -/ def starTerminal : Limits.IsTerminal (star : WithTerminal C) := Limits.IsTerminal.ofUnique _ +set_option backward.isDefEq.respectTransparency.types false in instance : Limits.HasTerminal (WithTerminal C) := Limits.hasTerminal_of_unique star /-- The isomorphism between star and an abstract terminal object of `WithTerminal C` -/ @@ -243,6 +259,7 @@ instance : Limits.HasTerminal (WithTerminal C) := Limits.hasTerminal_of_unique s noncomputable def starIsoTerminal : star ≅ ⊤_ (WithTerminal C) := starTerminal.uniqueUpToIso (Limits.terminalIsTerminal) +set_option backward.isDefEq.respectTransparency.types false in /-- Lift a functor `F : C ⥤ D` to `WithTerminal C ⥤ D`. -/ @[simps] def lift {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.obj x ⟶ Z) @@ -265,6 +282,7 @@ def inclLift {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.o hom := { app := fun _ => 𝟙 _ } inv := { app := fun _ => 𝟙 _ } +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism between `(lift F _ _).obj WithTerminal.star` with `Z`. -/ @[simps!] def liftStar {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.obj x ⟶ Z) @@ -280,6 +298,7 @@ theorem lift_map_liftStar {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : simp rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The uniqueness of `lift`. -/ @[simp] def liftUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.obj x ⟶ Z) @@ -303,18 +322,21 @@ def liftUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F change G.map (𝟙 _) ≫ hG.hom = hG.hom ≫ 𝟙 _ simp) +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `lift` with `Z` a terminal object. -/ @[simps!] def liftToTerminal {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : Limits.IsTerminal Z) : WithTerminal C ⥤ D := lift F (fun _x => hZ.from _) fun _x _y _f => hZ.hom_ext _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `incl_lift` with `Z` a terminal object. -/ @[simps!] def inclLiftToTerminal {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : Limits.IsTerminal Z) : incl ⋙ liftToTerminal F hZ ≅ F := inclLift _ _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `lift_unique` with `Z` a terminal object. -/ @[simps!] def liftToTerminalUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : Limits.IsTerminal Z) @@ -322,11 +344,13 @@ def liftToTerminalUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : L liftUnique F (fun _z => hZ.from _) (fun _x _y _f => hZ.hom_ext _ _) G h hG fun _x => hZ.hom_ext _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- Constructs a morphism to `star` from `of X`. -/ @[simp] def homFrom (X : C) : incl.obj X ⟶ star := starTerminal.from _ +set_option backward.isDefEq.respectTransparency.types false in instance isIso_of_from_star {X : WithTerminal C} (f : star ⟶ X) : IsIso f := match X with | of _X => f.elim @@ -336,6 +360,7 @@ section variable {D : Type*} [Category* D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor `WithTerminal C ⥤ D` can be seen as an element of the comma category `Comma (𝟭 (C ⥤ D)) (const C)`. -/ @@ -350,6 +375,7 @@ def mkCommaObject (F : WithTerminal C ⥤ D) : Comma (𝟭 (C ⥤ D)) (Functor.c rw [Category.comp_id, ← F.map_comp] congr 1 } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A morphism of functors `WithTerminal C ⥤ D` gives a morphism between the associated comma objects. -/ @@ -366,6 +392,7 @@ functor `WithTerminal C ⥤ D`. -/ def ofCommaObject (c : Comma (𝟭 (C ⥤ D)) (Functor.const C)) : WithTerminal C ⥤ D := lift (Z := c.right) c.left (fun x ↦ c.hom.app x) (fun x y f ↦ by simp) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A morphism in `Comma (𝟭 (C ⥤ D)) (Functor.const C)` gives a morphism between the associated functors `WithTerminal C ⥤ D`. -/ @@ -426,6 +453,7 @@ instance subsingleton_hom {J : Type*} : Quiver.IsThin (WithTerminal (Discrete J) · rfl · rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- Implementation detail for `widePullbackShapeEquiv`. -/ @[simps apply] @@ -510,32 +538,41 @@ attribute [nolint simpNF] comp.eq_3 @[aesop safe destruct (rule_sets := [CategoryTheory])] lemma false_of_to_star' {X : C} (f : Hom (of X) star) : False := (f : PEmpty).elim +set_option backward.isDefEq.respectTransparency.types false in instance : Category.{v} (WithInitial C) where Hom X Y := Hom X Y id X := id X comp f g := comp f g +set_option backward.isDefEq.respectTransparency.types false in /-- Helper function for typechecking. -/ def down {X Y : C} (f : of X ⟶ of Y) : X ⟶ Y := f +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma down_id {X : C} : down (𝟙 (of X)) = 𝟙 X := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma down_comp {X Y Z : C} (f : of X ⟶ of Y) (g : of Y ⟶ of Z) : down (f ≫ g) = down f ≫ down g := rfl +set_option backward.isDefEq.respectTransparency.types false in @[aesop safe destruct (rule_sets := [CategoryTheory])] lemma false_of_to_star {X : C} (f : of X ⟶ star) : False := (f : PEmpty).elim +set_option backward.isDefEq.respectTransparency.types false in /-- The inclusion of `C` into `WithInitial C`. -/ def incl : C ⥤ WithInitial C where obj := of map f := f +set_option backward.isDefEq.respectTransparency.types false in instance : (incl : C ⥤ _).Full where map_surjective f := ⟨f, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in instance : (incl : C ⥤ _).Faithful where +set_option backward.isDefEq.respectTransparency.types false in /-- Map `WithInitial` with respect to a functor `F : C ⥤ D`. -/ @[simps] def map {D : Type*} [Category* D] (F : C ⥤ D) : WithInitial C ⥤ WithInitial D where @@ -549,6 +586,7 @@ def map {D : Type*} [Category* D] (F : C ⥤ D) : WithInitial C ⥤ WithInitial | star, of _, _ => PUnit.unit | star, star, _ => PUnit.unit +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural isomorphism between the functor `map (𝟭 C)` and `𝟭 (WithInitial C)`. -/ @[simps!] @@ -557,6 +595,7 @@ def mapId (C : Type*) [Category* C] : map (𝟭 C) ≅ 𝟭 (WithInitial C) := | of _ => Iso.refl _ | star => Iso.refl _) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A natural isomorphism between the functor `map (F ⋙ G) ` and `map F ⋙ map G `. -/ @[simps!] @@ -566,6 +605,7 @@ def mapComp {D E : Type*} [Category* D] [Category* E] (F : C ⥤ D) (G : D ⥤ E | of _ => Iso.refl _ | star => Iso.refl _) (by cat_disch) +set_option backward.isDefEq.respectTransparency.types false in /-- From a natural transformation of functors `C ⥤ D`, the induced natural transformation of functors `WithInitial C ⥤ WithInitial D`. -/ @[simps] @@ -580,6 +620,7 @@ def map₂ {D : Type*} [Category* D] {F G : C ⥤ D} (η : F ⟶ G) : map F ⟶ | star, of x, _ => rfl | star, star, _ => rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The prelax functor from `Cat` to `Cat` defined with `WithInitial`. -/ @[simps] def prelaxfunctor : PrelaxFunctor Cat Cat where @@ -635,6 +676,7 @@ def pseudofunctor : Pseudofunctor Cat Cat where · simpa using! (refl _) · rfl +set_option backward.isDefEq.respectTransparency.types false in instance {X : WithInitial C} : Unique (star ⟶ X) where default := match X with @@ -642,10 +684,12 @@ instance {X : WithInitial C} : Unique (star ⟶ X) where | star => PUnit.unit uniq := by cat_disch +set_option backward.isDefEq.respectTransparency.types false in /-- `WithInitial.star` is initial. -/ def starInitial : Limits.IsInitial (star : WithInitial C) := Limits.IsInitial.ofUnique _ +set_option backward.isDefEq.respectTransparency.types false in instance : Limits.HasInitial (WithInitial C) := Limits.hasInitial_of_unique star /-- The isomorphism between star and an abstract initial object of `WithInitial C` -/ @@ -653,6 +697,7 @@ instance : Limits.HasInitial (WithInitial C) := Limits.hasInitial_of_unique star noncomputable def starIsoInitial : star ≅ ⊥_ (WithInitial C) := starInitial.uniqueUpToIso (Limits.initialIsInitial) +set_option backward.isDefEq.respectTransparency.types false in /-- Lift a functor `F : C ⥤ D` to `WithInitial C ⥤ D`. -/ @[simps] def lift {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z ⟶ F.obj x) @@ -675,12 +720,14 @@ def inclLift {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z hom := { app := fun _ => 𝟙 _ } inv := { app := fun _ => 𝟙 _ } +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism between `(lift F _ _).obj WithInitial.star` with `Z`. -/ @[simps!] def liftStar {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z ⟶ F.obj x) (hM : ∀ (x y : C) (f : x ⟶ y), M x ≫ F.map f = M y) : (lift F M hM).obj star ≅ Z := eqToIso rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem liftStar_lift_map {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z ⟶ F.obj x) (hM : ∀ (x y : C) (f : x ⟶ y), M x ≫ F.map f = M y) (x : C) : @@ -688,7 +735,7 @@ theorem liftStar_lift_map {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : M x ≫ (inclLift F M hM).hom.app x := by simp [incl] -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /-- The uniqueness of `lift`. -/ @[simp] def liftUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z ⟶ F.obj x) @@ -715,29 +762,34 @@ def liftUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z change G.map (𝟙 _) ≫ hG.hom = hG.hom ≫ 𝟙 _ simp) +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `lift` with `Z` an initial object. -/ @[simps!] def liftToInitial {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : Limits.IsInitial Z) : WithInitial C ⥤ D := lift F (fun _x => hZ.to _) fun _x _y _f => hZ.hom_ext _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `incl_lift` with `Z` an initial object. -/ @[simps!] def inclLiftToInitial {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : Limits.IsInitial Z) : incl ⋙ liftToInitial F hZ ≅ F := inclLift _ _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- A variant of `lift_unique` with `Z` an initial object. -/ @[simps!] def liftToInitialUnique {D : Type*} [Category* D] {Z : D} (F : C ⥤ D) (hZ : Limits.IsInitial Z) (G : WithInitial C ⥤ D) (h : incl ⋙ G ≅ F) (hG : G.obj star ≅ Z) : G ≅ liftToInitial F hZ := liftUnique F (fun _z => hZ.to _) (fun _x _y _f => hZ.hom_ext _ _) G h hG fun _x => hZ.hom_ext _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- Constructs a morphism from `star` to `of X`. -/ @[simp] def homTo (X : C) : star ⟶ incl.obj X := starInitial.to _ +set_option backward.isDefEq.respectTransparency.types false in instance isIso_of_to_star {X : WithInitial C} (f : X ⟶ star) : IsIso f := match X with | of _ => f.elim @@ -747,6 +799,7 @@ section variable {D : Type*} [Category* D] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A functor `WithInitial C ⥤ D` can be seen as an element of the comma category `Comma (const C) (𝟭 (C ⥤ D))`. -/ @@ -761,6 +814,7 @@ def mkCommaObject (F : WithInitial C ⥤ D) : Comma (Functor.const C) (𝟭 (C rw [Category.id_comp, ← F.map_comp] congr 1 } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- A morphism of functors `WithInitial C ⥤ D` gives a morphism between the associated comma objects. -/ diff --git a/Mathlib/CategoryTheory/WithTerminal/Cone.lean b/Mathlib/CategoryTheory/WithTerminal/Cone.lean index f654502bc2cc63..51c743ce794f03 100644 --- a/Mathlib/CategoryTheory/WithTerminal/Cone.lean +++ b/Mathlib/CategoryTheory/WithTerminal/Cone.lean @@ -55,6 +55,7 @@ def commaFromOver : (J ⥤ Over X) ⥤ Comma (𝟭 (J ⥤ C)) (Functor.const J) @[simps!] def liftFromOver : (J ⥤ Over X) ⥤ WithTerminal J ⥤ C := commaFromOver ⋙ equivComma.inverse +set_option backward.isDefEq.respectTransparency.types false in /-- The extension of a functor to over categories behaves well with compositions. -/ @[simps] def liftFromOverComp : liftFromOver.obj (K ⋙ Over.post F) ≅ liftFromOver.obj K ⋙ F where @@ -85,6 +86,7 @@ private def coneLift : Cone K ⥤ Cone (liftFromOver.obj K) where | of a => by simp [← Comma.comp_left] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- This is the inverse of the previous construction: a cone of an extended functor `liftFromOver.obj K : WithTerminal J ⥤ C` consists of an object of `C`, together @@ -99,6 +101,7 @@ private def coneBack : Cone (liftFromOver.obj K) ⥤ Cone K where { hom := Over.homMk f.hom (by simp [dsimp% f.w star] ) w j := by ext; simp [dsimp% f.w (of j)] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Given a functor `K : J ⥤ Over X` and its extension `liftFromOver K : WithTerminal J ⥤ C`, @@ -122,6 +125,9 @@ lemma coneEquiv_functor_obj_π_app_star : (coneEquiv.functor.obj t).π.app star lemma coneEquiv_functor_obj_π_app_of (Y : J) : (coneEquiv.functor.obj t).π.app (of Y) = (t.π.app Y).left := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A cone `t` of `K : J ⥤ Over X` is a limit if and only if the corresponding cone `coneLift t` of `liftFromOver.obj K : WithTerminal K ⥤ C` is a limit. -/ @[simps!] @@ -167,6 +173,7 @@ def commaFromUnder : (J ⥤ Under X) ⥤ Comma (Functor.const J) (𝟭 (J ⥤ C) @[simps!] def liftFromUnder : (J ⥤ Under X) ⥤ WithInitial J ⥤ C := commaFromUnder ⋙ equivComma.inverse +set_option backward.isDefEq.respectTransparency.types false in /-- The extension of a functor to under categories behaves well with compositions. -/ @[simps] def liftFromUnderComp : liftFromUnder.obj (K ⋙ Under.post F) ≅ liftFromUnder.obj K ⋙ F where @@ -197,6 +204,7 @@ private def coconeLift : Cocone K ⥤ Cocone (liftFromUnder.obj K) where | of a => by simp [← Comma.comp_right] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in /-- This is the inverse of the previous construction: a cocone of an extended functor `liftFromUnder.obj K : WithInitial J ⥤ C` consists of an object of `C`, together @@ -211,6 +219,7 @@ private def coconeBack : Cocone (liftFromUnder.obj K) ⥤ Cocone K where { hom := Under.homMk f.hom (f.w .star) w j := by ext; simp [dsimp% f.w (of j)] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Given a functor `K : J ⥤ Under X` and its extension `liftFromUnder K : WithInitial J ⥤ C`, @@ -234,6 +243,9 @@ lemma coconeEquiv_functor_obj_ι_app_star : (coconeEquiv.functor.obj t).ι.app s lemma coconeEquiv_functor_obj_ι_app_of (Y : J) : (coconeEquiv.functor.obj t).ι.app (of Y) = (t.ι.app Y).right := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A cocone `t` of `K : J ⥤ Under X` is a colimit if and only if the corresponding cocone `coconeLift t` of `liftFromUnder.obj K : WithInitial K ⥤ C` is a colimit. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Yoneda.lean b/Mathlib/CategoryTheory/Yoneda.lean index ee8bda56ccf243..43e3c2454267f4 100644 --- a/Mathlib/CategoryTheory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Yoneda.lean @@ -31,7 +31,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open Opposite Functor +open Opposite CategoryTheory.Functor universe w v v₁ v₂ u₁ u₂ @@ -762,6 +762,7 @@ lemma yonedaEquiv_yoneda_map {X Y : C} (f : X ⟶ Y) : yonedaEquiv (yoneda.map f rw [yonedaEquiv_apply] simp +set_option backward.isDefEq.respectTransparency.types false in lemma yonedaEquiv_symm_naturality_left {X X' : C} (f : X' ⟶ X) (F : Cᵒᵖ ⥤ Type v₁) (x : F.obj ⟨X⟩) : yoneda.map f ≫ yonedaEquiv.symm x = yonedaEquiv.symm ((F.map f.op) x) := by apply yonedaEquiv.injective @@ -845,6 +846,7 @@ def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C := variable {C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /- Porting note: this used to be two calls to `tidy` -/ /-- The curried version of yoneda lemma when `C` is small. -/ @@ -856,6 +858,7 @@ def curriedYonedaLemma {C : Type u₁} [SmallCategory C] : ext a b simp [yonedaEquiv, ← NatTrans.naturality_apply]) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The curried version of the Yoneda lemma. -/ def largeCurriedYonedaLemma {C : Type u₁} [Category.{v₁} C] : @@ -878,6 +881,7 @@ def yonedaOpCompYonedaObj {C : Type u₁} [Category.{v₁} C] (P : Cᵒᵖ ⥤ T yoneda.op ⋙ yoneda.obj P ≅ P ⋙ uliftFunctor.{u₁} := isoWhiskerRight largeCurriedYonedaLemma ((evaluation _ _).obj P) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The curried version of yoneda lemma when `C` is small. -/ def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] : @@ -1084,6 +1088,7 @@ def coyonedaLemma : coyonedaPairing C ≅ coyonedaEvaluation C := variable {C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /- Porting note: this used to be two calls to `tidy` -/ /-- The curried version of coyoneda lemma when `C` is small. -/ @@ -1119,6 +1124,7 @@ def coyonedaCompYonedaObj {C : Type u₁} [Category.{v₁} C] (P : C ⥤ Type v coyoneda.rightOp ⋙ yoneda.obj P ≅ P ⋙ uliftFunctor.{u₁} := isoWhiskerRight largeCurriedCoyonedaLemma ((evaluation _ _).obj P) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The curried version of coyoneda lemma when `C` is small. -/ def curriedCoyonedaLemma' {C : Type u₁} [SmallCategory C] : @@ -1148,6 +1154,7 @@ lemma isIso_iff_isIso_coyoneda_map {X Y : C} (f : X ⟶ Y) : rw [isIso_iff_coyoneda_map_bijective] exact forall_congr' fun _ ↦ bijective_iff_isIso_ofHom _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Coyoneda's lemma as a bijection `(uliftCoyoneda.{w}.obj X ⟶ F) ≃ F.obj (op X)` for any presheaf of type `F : Cᵒᵖ ⥤ Type (max w v₁)` for some @@ -1164,6 +1171,7 @@ def uliftCoyonedaEquiv {X : Cᵒᵖ} {F : C ⥤ Type (max w v₁)} : attribute [simp] uliftCoyonedaEquiv_symm_apply_app +set_option backward.isDefEq.respectTransparency.types false in lemma uliftCoyonedaEquiv_naturality {X Y : C} {F : C ⥤ Type max w v₁} (f : uliftCoyoneda.{w}.obj (op X) ⟶ F) (g : X ⟶ Y) : F.map g (uliftCoyonedaEquiv.{w} f) = uliftCoyonedaEquiv.{w} (uliftCoyoneda.map g.op ≫ f) := by @@ -1190,6 +1198,7 @@ lemma uliftCoyonedaEquiv_uliftCoyoneda_map {X Y : Cᵒᵖ} (f : X ⟶ Y) : uliftCoyonedaEquiv.{w} (uliftCoyoneda.map f) = ULift.up f.unop := by simp [uliftCoyonedaEquiv, uliftYoneda] +set_option backward.isDefEq.respectTransparency.types false in /-- Two morphisms of presheaves of types `P ⟶ Q` coincide if the precompositions with morphisms `uliftCoyoneda.obj X ⟶ P` agree. -/ lemma hom_ext_uliftCoyoneda {P Q : C ⥤ Type (max w v₁)} {f g : P ⟶ Q} @@ -1257,6 +1266,7 @@ section variable {C : Type u₁} [Category.{v₁} C] +set_option backward.isDefEq.respectTransparency.types false in /-- A type-level equivalence between sections of a functor and morphisms from a terminal functor to it. We use the constant functor on a given singleton type here as a specific choice of terminal functor. -/ @@ -1299,6 +1309,7 @@ namespace Functor.FullyFaithful variable {C : Type u₁} [Category.{v₁} C] +set_option backward.isDefEq.respectTransparency.types false in /-- `FullyFaithful.homEquiv` as a natural isomorphism. -/ @[simps! hom_app inv_app] def homNatIso {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} (hF : F.FullyFaithful) (X : C) : @@ -1307,6 +1318,7 @@ def homNatIso {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} (hF : F.FullyFai (fun Y => Equiv.toIso (Equiv.ulift.trans <| hF.homEquiv.symm.trans Equiv.ulift.symm)) (fun f => by ext; exact Equiv.ulift.injective (hF.map_injective (by simp))) +set_option backward.isDefEq.respectTransparency.types false in /-- `FullyFaithful.homEquiv` as a natural isomorphism. -/ @[simps! +dsimpLhs] def compUliftYonedaCompWhiskeringLeft {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} @@ -1315,6 +1327,7 @@ def compUliftYonedaCompWhiskeringLeft {D : Type u₂} [Category.{v₂} D] {F : C NatIso.ofComponents (fun X => hF.homNatIso _) fun f => by ext; exact Equiv.ulift.injective (hF.map_injective (by simp)) +set_option backward.isDefEq.respectTransparency.types false in /-- `FullyFaithful.homEquiv` as a natural isomorphism, using coyoneda. -/ @[simps! hom_app inv_app] def homNatIso' {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} (hF : F.FullyFaithful) (X : C) : @@ -1323,6 +1336,7 @@ def homNatIso' {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} (hF : F.FullyFa (fun Y => Equiv.toIso (Equiv.ulift.trans <| hF.homEquiv.symm.trans Equiv.ulift.symm)) (fun f => by ext; exact Equiv.ulift.injective (hF.map_injective (by simp))) +set_option backward.isDefEq.respectTransparency.types false in /-- `FullyFaithful.homEquiv` as a natural isomorphism, using coyoneda. -/ @[simps! +dsimpLhs] def compUliftCoyonedaCompWhiskeringLeft {D : Type u₂} [Category.{v₂} D] {F : C ⥤ D} diff --git a/Mathlib/Combinatorics/Additive/Corner/Roth.lean b/Mathlib/Combinatorics/Additive/Corner/Roth.lean index b012b8b6a77b39..01e8bbd6bd6ef1 100644 --- a/Mathlib/Combinatorics/Additive/Corner/Roth.lean +++ b/Mathlib/Combinatorics/Additive/Corner/Roth.lean @@ -37,8 +37,7 @@ private def triangleIndices (A : Finset (G × G)) : Finset (G × G × G) := @[simp] private lemma mk_mem_triangleIndices : (a, b, c) ∈ triangleIndices A ↔ (a, b) ∈ A ∧ c = a + b := by - simp only [triangleIndices, Prod.ext_iff, mem_map, Embedding.coeFn_mk, Prod.exists, - eq_comm] + simp only [triangleIndices, Prod.ext_iff, mem_map, Prod.exists, eq_comm] refine ⟨?_, fun h ↦ ⟨_, _, h.1, rfl, rfl, h.2⟩⟩ rintro ⟨_, _, h₁, rfl, rfl, h₂⟩ exact ⟨h₁, h₂⟩ diff --git a/Mathlib/Combinatorics/Additive/Energy.lean b/Mathlib/Combinatorics/Additive/Energy.lean index ee0c970e97de9b..a4b9928c9edebd 100644 --- a/Mathlib/Combinatorics/Additive/Energy.lean +++ b/Mathlib/Combinatorics/Additive/Energy.lean @@ -123,6 +123,7 @@ variable {s t} Eₘ[s, t] = #{x ∈ ((s ×ˢ t) ×ˢ s ×ˢ t) | x.1.1 * x.1.2 = x.2.1 * x.2.2} := card_equiv (.prodProdProdComm _ _ _ _) (by simp [and_and_and_comm]) +set_option backward.isDefEq.respectTransparency false in @[to_additive] lemma mulEnergy_eq_sum_sq' (s t : Finset α) : Eₘ[s, t] = ∑ a ∈ s * t, #{xy ∈ s ×ˢ t | xy.1 * xy.2 = a} ^ 2 := by simp_rw [mulEnergy_eq_card_filter, sq, ← card_product] diff --git a/Mathlib/Combinatorics/Colex.lean b/Mathlib/Combinatorics/Colex.lean index f9ef6177af7229..d7b22c09091017 100644 --- a/Mathlib/Combinatorics/Colex.lean +++ b/Mathlib/Combinatorics/Colex.lean @@ -455,6 +455,7 @@ lemma isInitSeg_initSeg : IsInitSeg (initSeg s) #s := by rw [mem_initSeg] at ht₁ exact ht₂.1.le.trans ht₁.2 +set_option backward.isDefEq.respectTransparency false in lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) : ∃ s : Finset α, #s = r ∧ 𝒜 = initSeg s := by have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex diff --git a/Mathlib/Combinatorics/Configuration.lean b/Mathlib/Combinatorics/Configuration.lean index 10a17ddcfae1a2..c95d2b06ce5024 100644 --- a/Mathlib/Combinatorics/Configuration.lean +++ b/Mathlib/Combinatorics/Configuration.lean @@ -282,7 +282,7 @@ theorem HasPoints.lineCount_eq_pointCount [HasPoints P L] [Fintype P] [Fintype L /-- If a nondegenerate configuration has a unique line through any two points, and if `|P| = |L|`, then there is a unique point on any two lines. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def HasLines.hasPoints [HasLines P L] [Fintype P] [Fintype L] (h : Fintype.card P = Fintype.card L) : HasPoints P L := let : ∀ l₁ l₂ : L, l₁ ≠ l₂ → ∃ p : P, p ∈ l₁ ∧ p ∈ l₂ := fun l₁ l₂ hl => by @@ -317,7 +317,7 @@ noncomputable def HasLines.hasPoints [HasLines P L] [Fintype P] [Fintype L] /-- If a nondegenerate configuration has a unique point on any two lines, and if `|P| = |L|`, then there is a unique line through any two points. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def HasPoints.hasLines [HasPoints P L] [Fintype P] [Fintype L] (h : Fintype.card P = Fintype.card L) : HasLines P L := let := @HasLines.hasPoints (Dual L) (Dual P) _ _ _ _ h.symm diff --git a/Mathlib/Combinatorics/Derangements/Basic.lean b/Mathlib/Combinatorics/Derangements/Basic.lean index 87cad0b77a04a2..eea016bcb1b1b2 100644 --- a/Mathlib/Combinatorics/Derangements/Basic.lean +++ b/Mathlib/Combinatorics/Derangements/Basic.lean @@ -49,6 +49,7 @@ def Equiv.derangementsCongr (e : α ≃ β) : derangements α ≃ derangements namespace derangements +set_option backward.isDefEq.respectTransparency false in /-- Derangements on a subtype are equivalent to permutations on the original type where points are fixed iff they are not in the subtype. -/ protected def subtypeEquiv (p : α → Prop) [DecidablePred p] : @@ -115,6 +116,7 @@ variable [DecidableEq α] def RemoveNone.fiber (a : Option α) : Set (Perm α) := { f : Perm α | (a, f) ∈ Equiv.Perm.decomposeOption '' derangements (Option α) } +set_option backward.isDefEq.respectTransparency false in theorem RemoveNone.mem_fiber (a : Option α) (f : Perm α) : f ∈ RemoveNone.fiber a ↔ ∃ F : Perm (Option α), F ∈ derangements (Option α) ∧ F none = a ∧ removeNone F = f := by diff --git a/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean b/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean index 2bdc3a2e175c21..8419d0ff3d0138 100644 --- a/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean +++ b/Mathlib/Combinatorics/Enumerative/Catalan/Tree.lean @@ -61,6 +61,7 @@ theorem treesOfNumNodesEq_succ (n : ℕ) : ext simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mem_treesOfNumNodesEq {x : BinaryTree Unit} {n : ℕ} : x ∈ treesOfNumNodesEq n ↔ x.numNodes = n := by diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index c5be665c6a8b7c..201e4ae0e6eefd 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -468,6 +468,7 @@ theorem ones_length (n : ℕ) : (ones n).length = n := theorem ones_blocks (n : ℕ) : (ones n).blocks = replicate n (1 : ℕ) := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ones_blocksFun (n : ℕ) (i : Fin (ones n).length) : (ones n).blocksFun i = 1 := by simp only [blocksFun, ones, get_eq_getElem, getElem_replicate] @@ -535,10 +536,12 @@ theorem single_length {n : ℕ} (h : 0 < n) : (single n h).length = 1 := theorem single_blocks {n : ℕ} (h : 0 < n) : (single n h).blocks = [n] := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem single_blocksFun {n : ℕ} (h : 0 < n) (i : Fin (single n h).length) : (single n h).blocksFun i = n := by simp [blocksFun, single] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem single_embedding {n : ℕ} (h : 0 < n) (i : Fin n) : ((single n h).embedding (0 : Fin 1)) i = i := by @@ -558,6 +561,7 @@ theorem eq_single_iff_length {n : ℕ} (h : 0 < n) {c : Composition n} : rw [eq_cons_of_length_one A] at B ⊢ simpa [single_blocks] using B +set_option backward.isDefEq.respectTransparency false in theorem ne_single_iff {n : ℕ} (hn : 0 < n) {c : Composition n} : c ≠ single n hn ↔ ∀ i, c.blocksFun i < n := by contrapose! @@ -808,6 +812,7 @@ Combinatorial viewpoints on compositions, seen as finite subsets of `Fin (n+1)` -/ +set_option backward.isDefEq.respectTransparency false in /-- Bijection between compositions of `n` and subsets of `{0, ..., n-2}`, defined by considering the restriction of the subset to `{1, ..., n-1}` and shifting to the left by one. -/ def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1)) where @@ -911,6 +916,7 @@ def blocks (c : CompositionAsSet n) : List ℕ := theorem blocks_length : c.blocks.length = c.length := length_ofFn +set_option backward.isDefEq.respectTransparency false in theorem blocks_partial_sum {i : ℕ} (h : i < c.boundaries.card) : (c.blocks.take i).sum = c.boundary ⟨i, h⟩ := by induction i with diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index b4462eda3c50f6..c5938308747cc5 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -277,6 +277,7 @@ lemma firstReturn_lt_length : p.firstReturn < p.toList.length := by exact ⟨by lia, by rw [Nat.sub_add_cancel lp, take_of_length_le (le_refl _), p.count_U_eq_count_D]⟩ +set_option backward.isDefEq.respectTransparency false in include h in lemma count_take_firstReturn_add_one : (p.toList.take (p.firstReturn + 1)).count U = (p.toList.take (p.firstReturn + 1)).count D := by @@ -374,6 +375,7 @@ lemma outsidePart_nest : p.nest.outsidePart = 0 := by rw [DyckWord.ext_iff]; apply drop_of_length_le simp_rw [nest, length_append, length_singleton]; lia +set_option backward.isDefEq.respectTransparency false in include h in @[simp] theorem nest_insidePart_add_outsidePart : p.insidePart.nest + p.outsidePart = p := by diff --git a/Mathlib/Combinatorics/Enumerative/InclusionExclusion.lean b/Mathlib/Combinatorics/Enumerative/InclusionExclusion.lean index 6758df6efd0420..a9fd63c4e30b3c 100644 --- a/Mathlib/Combinatorics/Enumerative/InclusionExclusion.lean +++ b/Mathlib/Combinatorics/Enumerative/InclusionExclusion.lean @@ -108,6 +108,7 @@ lemma prod_indicator_biUnion_finset_sub_indicator (hs : s.Nonempty) (S : ι → convert! prod_indicator_biUnion_sub_indicator hs (fun i ↦ S i) a simp +set_option backward.isDefEq.respectTransparency false in /-- **Inclusion-exclusion principle** for the sum of a function over a union. The sum of a function `f` over the union of the `S i` over `i ∈ s` is the alternating sum of the diff --git a/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean b/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean index 935de73ea4c4a9..b74f24de3e3a53 100644 --- a/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean +++ b/Mathlib/Combinatorics/Enumerative/Partition/Basic.lean @@ -165,6 +165,7 @@ def indiscrete (n : ℕ) : Partition n := ofSums n {n} rfl instance {n : ℕ} : Inhabited (Partition n) := ⟨indiscrete n⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] lemma indiscrete_parts {n : ℕ} (hn : n ≠ 0) : (indiscrete n).parts = {n} := by simp [indiscrete, filter_eq_self, hn] diff --git a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean index 74801a7646491f..10052b591711b1 100644 --- a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean +++ b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean @@ -127,6 +127,7 @@ private def triangleIndices (s : Finset α) : Finset (α × α × α) := obtain rfl := add_right_injective _ h.2.1 rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in @[simp] private lemma mem_triangleIndices : x ∈ triangleIndices s ↔ ∃ y, ∃ a ∈ s, (y, y + a, y + 2 * a) = x := by simp [triangleIndices] diff --git a/Mathlib/Combinatorics/Hall/Basic.lean b/Mathlib/Combinatorics/Hall/Basic.lean index df8abd2574ee75..6708a7f770bca0 100644 --- a/Mathlib/Combinatorics/Hall/Basic.lean +++ b/Mathlib/Combinatorics/Hall/Basic.lean @@ -151,6 +151,7 @@ theorem Finset.all_card_le_biUnion_card_iff_exists_injective {ι : Type u} {α : apply Finset.card_le_card grind +set_option backward.isDefEq.respectTransparency.types false in /-- Given a relation such that the image of every singleton set is finite, then the image of every finite set is finite. -/ instance {α : Type u} {β : Type v} [DecidableEq β] (R : SetRel α β) @@ -161,6 +162,7 @@ instance {α : Type u} {β : Type v} [DecidableEq β] (R : SetRel α β) rw [h] apply FinsetCoe.fintype +set_option backward.isDefEq.respectTransparency.types false in /-- This is a version of **Hall's Marriage Theorem** in terms of a relation between types `α` and `β` such that `α` is finite and the image of each `x : α` is finite (it suffices for `β` to be finite; see diff --git a/Mathlib/Combinatorics/Hall/Finite.lean b/Mathlib/Combinatorics/Hall/Finite.lean index 12bc02d8426363..6b8db6870fd34b 100644 --- a/Mathlib/Combinatorics/Hall/Finite.lean +++ b/Mathlib/Combinatorics/Hall/Finite.lean @@ -72,6 +72,7 @@ theorem hall_cond_of_erase {x : ι} (a : α) · subst s' simp +set_option backward.isDefEq.respectTransparency false in /-- First case of the inductive step: assuming that `∀ (s : Finset ι), s.Nonempty → s ≠ univ → #s < #(s.biUnion t)` and that the statement of **Hall's Marriage Theorem** is true for all diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index 1faeeab5012304..6c3e6555f5bc2a 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -49,7 +49,7 @@ Ramsey theory, ultrafilter open Filter /-- Multiplication of ultrafilters given by `∀ᶠ m in U*V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m*m')`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Addition of ultrafilters given by `∀ᶠ m in U+V, p m ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m+m')`. -/] def Ultrafilter.mul {M} [Mul M] : Mul (Ultrafilter M) where mul U V := (· * ·) <$> U <*> V @@ -63,7 +63,7 @@ theorem Ultrafilter.eventually_mul {M} [Mul M] (U V : Ultrafilter M) (p : M → Iff.rfl /-- Semigroup structure on `Ultrafilter M` induced by a semigroup structure on `M`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Additive semigroup structure on `Ultrafilter M` induced by an additive semigroup structure on `M`. -/] def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) := diff --git a/Mathlib/Combinatorics/KatonaCircle.lean b/Mathlib/Combinatorics/KatonaCircle.lean index 64a5fba43c6194..ad645eee2a5545 100644 --- a/Mathlib/Combinatorics/KatonaCircle.lean +++ b/Mathlib/Combinatorics/KatonaCircle.lean @@ -49,6 +49,7 @@ def prefixed (s : Finset X) : Finset (Numbering X) := {f | IsPrefix f s} @[simp] lemma mem_prefixed : f ∈ prefixed s ↔ IsPrefix f s := by simp [prefixed] +set_option backward.isDefEq.respectTransparency false in /-- Decompose a numbering of which `s` is a prefix into a numbering of `s` and a numbering on `sᶜ`. -/ def prefixedEquiv (s : Finset X) : prefixed s ≃ Numbering s × Numbering ↑(sᶜ) where diff --git a/Mathlib/Combinatorics/Matroid/Basic.lean b/Mathlib/Combinatorics/Matroid/Basic.lean index 00acd4dc34c9d2..3c13de17e8d724 100644 --- a/Mathlib/Combinatorics/Matroid/Basic.lean +++ b/Mathlib/Combinatorics/Matroid/Basic.lean @@ -533,6 +533,7 @@ variable {B B' I J D X : Set α} {e f : α} theorem indep_iff : M.Indep I ↔ ∃ B, M.IsBase B ∧ I ⊆ B := M.indep_iff' (I := I) +set_option backward.isDefEq.respectTransparency false in theorem setOf_indep_eq (M : Matroid α) : {I | M.Indep I} = lowerClosure ({B | M.IsBase B}) := by simp_rw [indep_iff, lowerClosure, LowerSet.coe_mk, mem_setOf] diff --git a/Mathlib/Combinatorics/Matroid/IndepAxioms.lean b/Mathlib/Combinatorics/Matroid/IndepAxioms.lean index e1c915a06ae2e9..f7db37bf5cfac3 100644 --- a/Mathlib/Combinatorics/Matroid/IndepAxioms.lean +++ b/Mathlib/Combinatorics/Matroid/IndepAxioms.lean @@ -444,9 +444,10 @@ protected def ofFinset [DecidableEq α] (E : Set α) (Indep : Finset α → Prop @[simp] theorem ofFinset_indep [DecidableEq α] (E : Set α) Indep indep_empty indep_subset indep_aug subset_ground {I : Finset α} : (IndepMatroid.ofFinset E Indep indep_empty indep_subset indep_aug subset_ground).Indep I ↔ Indep I := by - simp only [IndepMatroid.ofFinset, ofFinitaryCardAugment_indep, Finset.coe_subset] + simp only [IndepMatroid.ofFinset] exact ⟨fun h ↦ h _ Subset.rfl, fun h J hJI ↦ indep_subset h hJI⟩ +set_option backward.isDefEq.respectTransparency false in /-- This can't be `@[simp]`, because it would cause the more useful `Matroid.ofIndepFinset_apply` not to be in simp normal form. -/ theorem ofFinset_indep' [DecidableEq α] (E : Set α) Indep indep_empty indep_subset indep_aug diff --git a/Mathlib/Combinatorics/Matroid/Map.lean b/Mathlib/Combinatorics/Matroid/Map.lean index 826d4ae508088f..09be193481e7b0 100644 --- a/Mathlib/Combinatorics/Matroid/Map.lean +++ b/Mathlib/Combinatorics/Matroid/Map.lean @@ -436,6 +436,7 @@ lemma map_isBasis_iff' {I X : Set β} {hf} : rintro ⟨I, X, hIX, rfl, rfl⟩ exact hIX.map hf +set_option backward.isDefEq.respectTransparency false in @[simp] lemma map_dual {hf} : (M.map f hf)✶ = M✶.map f hf := by apply ext_isBase (by simp) simp only [dual_ground, map_ground, subset_image_iff, forall_exists_index, and_imp, @@ -457,6 +458,7 @@ lemma map_isBasis_iff' {I X : Set β} {hf} : @[simp] lemma map_id : M.map id (injOn_id M.E) = M := by simp [ext_iff_indep] +set_option backward.isDefEq.respectTransparency false in lemma map_comap {f : α → β} (h_range : N.E ⊆ range f) (hf : InjOn f (f ⁻¹' N.E)) : (N.comap f).map f hf = N := by refine ext_indep (by simpa [image_preimage_eq_iff]) ?_ @@ -497,6 +499,7 @@ end map section mapSetEquiv +set_option backward.isDefEq.respectTransparency false in /-- Map `M : Matroid α` to a `Matroid β` with ground set `E` using an equivalence `M.E ≃ E`. Defined using `Matroid.ofExistsMatroid` for better defeq. -/ def mapSetEquiv (M : Matroid α) {E : Set β} (e : M.E ≃ E) : Matroid β := @@ -682,6 +685,7 @@ lemma eq_of_restrictSubtype_eq {N : Matroid α} (hM : M.E = E) (hN : N.E = E) lemma restrictSubtype_dual' (hM : M.E = E) : (M.restrictSubtype E)✶ = M✶.restrictSubtype E := by rw [← hM, restrictSubtype_dual] +set_option backward.isDefEq.respectTransparency false in /-- `M.restrictSubtype X` is isomorphic to `M ↾ X`. -/ @[simp] lemma map_val_restrictSubtype_eq (M : Matroid α) (X : Set α) : (M.restrictSubtype X).map (↑) Subtype.val_injective.injOn = M ↾ X := by diff --git a/Mathlib/Combinatorics/Matroid/Sum.lean b/Mathlib/Combinatorics/Matroid/Sum.lean index 644283fb75de1c..3e1b3761c15556 100644 --- a/Mathlib/Combinatorics/Matroid/Sum.lean +++ b/Mathlib/Combinatorics/Matroid/Sum.lean @@ -164,6 +164,7 @@ protected def sum' (M : ι → Matroid α) : Matroid (ι × α) := ext simp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma sum'_ground_eq (M : ι → Matroid α) : (Matroid.sum' M).E = ⋃ i, Prod.mk i '' (M i).E := by ext diff --git a/Mathlib/Combinatorics/Quiver/Arborescence.lean b/Mathlib/Combinatorics/Quiver/Arborescence.lean index 233ee59ef5cca2..063ffb6f43e888 100644 --- a/Mathlib/Combinatorics/Quiver/Arborescence.lean +++ b/Mathlib/Combinatorics/Quiver/Arborescence.lean @@ -57,7 +57,7 @@ instance {V : Type u} [Quiver V] [Arborescence V] (b : V) : Unique (Path (root V lower vertex to a higher vertex, - show that every vertex has at most one arrow to it, and - show that every vertex other than `r` has an arrow to it. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def arborescenceMk {V : Type u} [Quiver V] (r : V) (height : V → ℕ) (height_lt : ∀ ⦃a b⦄, (a ⟶ b) → height a < height b) (unique_arrow : ∀ ⦃a b c : V⦄ (e : a ⟶ c) (f : b ⟶ c), a = b ∧ e ≍ f) @@ -116,6 +116,7 @@ theorem shortest_path_spec {a : V} (p : Path r a) : (shortestPath r a).length def geodesicSubtree : WideSubquiver V := fun a b => { e | ∃ p : Path r a, shortestPath r b = p.cons e } +set_option backward.isDefEq.respectTransparency false in noncomputable instance geodesicArborescence : Arborescence (geodesicSubtree r) := arborescenceMk r (fun a => (shortestPath r a).length) (by diff --git a/Mathlib/Combinatorics/Quiver/ConnectedComponent.lean b/Mathlib/Combinatorics/Quiver/ConnectedComponent.lean index 487b77e3ca3e42..3653855a39d4a0 100644 --- a/Mathlib/Combinatorics/Quiver/ConnectedComponent.lean +++ b/Mathlib/Combinatorics/Quiver/ConnectedComponent.lean @@ -36,7 +36,7 @@ variable (V : Type*) [Quiver.{u} V] /-- Two vertices are related in the zigzag setoid if there is a zigzag of arrows from one to the other. -/ -@[implicit_reducible] +@[instance_reducible] def zigzagSetoid : Setoid V := ⟨fun a b ↦ Nonempty (@Path (Symmetrify V) _ a b), fun _ ↦ ⟨Path.nil⟩, fun ⟨p⟩ ↦ ⟨p.reverse⟩, fun ⟨p⟩ ⟨q⟩ ↦ ⟨p.comp q⟩⟩ @@ -115,7 +115,7 @@ lemma IsSStronglyConnected.isStronglyConnected intro i j; obtain ⟨p, _⟩ := h i j; exact ⟨p⟩ /-- Equivalence relation identifying vertices connected by directed paths in both directions. -/ -@[implicit_reducible] +@[instance_reducible] def stronglyConnectedSetoid : Setoid V := ⟨fun a b => (Nonempty (Path a b)) ∧ (Nonempty (Path b a)), fun _ => ⟨⟨Path.nil⟩, ⟨Path.nil⟩⟩, fun ⟨hab, hba⟩ => ⟨hba, hab⟩, fun ⟨hab, hba⟩ ⟨hbc, hcb⟩ => diff --git a/Mathlib/Combinatorics/Quiver/Push.lean b/Mathlib/Combinatorics/Quiver/Push.lean index bce18e536a9aad..b98888d22d291c 100644 --- a/Mathlib/Combinatorics/Quiver/Push.lean +++ b/Mathlib/Combinatorics/Quiver/Push.lean @@ -65,6 +65,7 @@ noncomputable def lift : Push σ ⥤q W' where theorem lift_obj : (lift σ φ τ h).obj = τ := rfl +set_option backward.isDefEq.respectTransparency false in theorem lift_comp : (of σ ⋙q lift σ φ τ h) = φ := by fapply Prefunctor.ext · rintro X diff --git a/Mathlib/Combinatorics/Quiver/SingleObj.lean b/Mathlib/Combinatorics/Quiver/SingleObj.lean index a9b435ed8a35a1..d395fc74343415 100644 --- a/Mathlib/Combinatorics/Quiver/SingleObj.lean +++ b/Mathlib/Combinatorics/Quiver/SingleObj.lean @@ -28,7 +28,7 @@ itself using `pathEquivList`. namespace Quiver /-- Type tag on `Unit` used to define single-object quivers. -/ -@[nolint unusedArguments] +@[nolint unusedArguments, implicit_reducible] def SingleObj (_ : Type*) : Type := Unit deriving Unique diff --git a/Mathlib/Combinatorics/Schnirelmann.lean b/Mathlib/Combinatorics/Schnirelmann.lean index 46773c1f916759..b94c8323ae7098 100644 --- a/Mathlib/Combinatorics/Schnirelmann.lean +++ b/Mathlib/Combinatorics/Schnirelmann.lean @@ -220,6 +220,7 @@ lemma schnirelmannDensity_setOf_even : schnirelmannDensity (setOf Even) = 0 := lemma schnirelmannDensity_setOf_prime : schnirelmannDensity (setOf Nat.Prime) = 0 := schnirelmannDensity_eq_zero_of_one_notMem <| by simp [Nat.not_prime_one] +set_option backward.isDefEq.respectTransparency false in /-- The Schnirelmann density of the set of naturals which are `1 mod m` is `m⁻¹`, for any `m ≠ 1`. diff --git a/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean b/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean index e1010540aa8921..60c7e4948c2f05 100644 --- a/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean +++ b/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean @@ -77,6 +77,7 @@ private lemma binomial_sum_eq (h : n < m) : have : (m.choose i : ℚ) ≠ 0 := cast_ne_zero.2 (choose_pos h₂.le).ne' simp [field, *] +set_option backward.isDefEq.respectTransparency false in private lemma Fintype.sum_div_mul_card_choose_card : ∑ s : Finset α, (card α / ((card α - #s) * (card α).choose #s) : ℚ) = card α * ∑ k ∈ range (card α), (↑k)⁻¹ + 1 := by diff --git a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean index 4faef45cf644f4..210d4d8c7d6d7e 100644 --- a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean +++ b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean @@ -296,6 +296,7 @@ section DistribLattice variable [DistribLattice α] [CommSemiring β] [LinearOrder β] [IsStrictOrderedRing β] [ExistsAddOfLE β] (f f₁ f₂ f₃ f₄ g μ : α → β) +set_option backward.isDefEq.respectTransparency false in /-- The **Four Functions Theorem**, aka **Ahlswede-Daykin Inequality**. -/ lemma four_functions_theorem [DecidableEq α] (h₁ : 0 ≤ f₁) (h₂ : 0 ≤ f₂) (h₃ : 0 ≤ f₃) (h₄ : 0 ≤ f₄) (h : ∀ a b, f₁ a * f₂ b ≤ f₃ (a ⊓ b) * f₄ (a ⊔ b)) (s t : Finset α) : diff --git a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean index 080e8e056f9e95..af8a25d6895dde 100644 --- a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean +++ b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean @@ -119,7 +119,7 @@ protected lemma IsInitSeg.shadow [Finite α] (h₁ : IsInitSeg 𝒜 r) : IsInitS end Colex -open Colex UV +open Finset.Colex UV open scoped FinsetFamily variable {α : Type*} [LinearOrder α] {s U V : Finset α} {n : ℕ} diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index c89e7cc9a208a4..47fd0de04d4595 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -133,6 +133,7 @@ theorem exists_maximal_isAcyclic_of_le_isAcyclic · grind [sSup_le_iff] · exact isAcyclic_sSup_of_isAcyclic_directedOn c (by grind) hc.directedOn +set_option backward.isDefEq.respectTransparency.types false in /-- A connected component of an acyclic graph is a tree. -/ lemma IsAcyclic.isTree_connectedComponent (h : G.IsAcyclic) (c : G.ConnectedComponent) : c.toSimpleGraph.IsTree where @@ -293,6 +294,7 @@ theorem IsAcyclic.isPath_iff_isTrail (hG : G.IsAcyclic) {v w : V} (p : G.Walk v p.IsPath ↔ p.IsTrail := ⟨IsPath.isTrail, fun h ↦ hG.isPath_iff_isChain p |>.mpr <| p.isTrail_def.mp h |>.isChain⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma IsTree.card_edgeFinset [Fintype V] [Fintype G.edgeSet] (hG : G.IsTree) : Finset.card G.edgeFinset + 1 = Fintype.card V := by have := hG.connected.nonempty @@ -477,6 +479,7 @@ lemma Connected.card_vert_le_card_edgeSet_add_one (h : G.Connected) : Nat.card_eq_fintype_card, ← edgeFinset_card] exact Finset.card_mono <| by simpa +set_option backward.isDefEq.respectTransparency.types false in lemma isTree_iff_connected_and_card [Finite V] : G.IsTree ↔ G.Connected ∧ Nat.card G.edgeSet + 1 = Nat.card V := by have := Fintype.ofFinite V diff --git a/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean b/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean index b5187d9f000eeb..e3f9ae59fd486b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean +++ b/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean @@ -109,6 +109,7 @@ def toGraph [MulZeroOneClass α] [Nontrivial α] (h : IsAdjMatrix A) : SimpleGra Adj i j := A i j = 1 symm.symm i j hij := by rwa [h.symm.apply i j] +set_option backward.isDefEq.respectTransparency.types false in instance [MulZeroOneClass α] [Nontrivial α] [DecidableEq α] (h : IsAdjMatrix A) : DecidableRel h.toGraph.Adj := by simp only [toGraph] @@ -417,7 +418,7 @@ theorem adjMatrix_pow_apply_eq_card_walk [DecidableEq V] [Semiring α] (n : ℕ) · rintro ⟨x, hx⟩ - ⟨y, hy⟩ - hxy rw [Function.onFun, disjoint_iff_inf_le] intro p hp - simp only [inf_eq_inter, mem_inter, mem_map, Function.Embedding.coeFn_mk] at hp + simp only [inf_eq_inter, mem_inter, mem_map] at hp obtain ⟨⟨px, _, rfl⟩, ⟨py, hpy, hp⟩⟩ := hp cases hp simp at hxy diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 4bf986b7af7616..f0d556b1218da8 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -98,6 +98,7 @@ structure SimpleGraph (V : Type u) where initialize_simps_projections SimpleGraph (Adj → adj) +set_option backward.isDefEq.respectTransparency false in /-- Constructor for simple graphs using a symmetric irreflexive Boolean function. -/ @[simps] def SimpleGraph.mk' {V : Type u} : diff --git a/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean b/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean index db6aebddef53e0..4809d9d772754b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean @@ -322,6 +322,7 @@ section Copy variable {α β : Type*} [Fintype α] [Fintype β] +set_option backward.isDefEq.respectTransparency.types false in /-- A "left" subset of `card α` vertices and a "right" subset of `card β` vertices such that every vertex in the "left" subset is adjacent to every vertex in the "right" subset gives rise to a copy of a complete bipartite graph. -/ @@ -541,6 +542,7 @@ theorem bipartiteDoubleCover_le : G.bipartiteDoubleCover ≤ completeBipartiteGr | .inl _, .inr _ | .inr _, .inl _ => by simp | .inl _, .inl _ | .inr _, .inr _ => by simp at hadj +set_option backward.isDefEq.respectTransparency.types false in /-- The bipartite double cover of `G` has twice the number of edges as `G`. -/ theorem card_edgeFinset_bipartiteDoubleCover [Fintype V] [DecidableRel G.Adj] : #G.bipartiteDoubleCover.edgeFinset = 2 * #G.edgeFinset := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Clique.lean b/Mathlib/Combinatorics/SimpleGraph/Clique.lean index b3863017dc3f63..1d5fb21740d941 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Clique.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Clique.lean @@ -339,6 +339,7 @@ theorem is3Clique_iff_exists_cycle_length_three : ⟨(fun ⟨_, a, _, _, hab, hac, hbc, _⟩ => ⟨a, cons hab (cons hbc (cons hac.symm nil)), by aesop⟩), (fun ⟨_, .cons hab (.cons hbc (.cons hca nil)), _, _⟩ => ⟨_, _, _, _, hab, hca.symm, hbc, rfl⟩)⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- If a set of vertices `A` is an `n`-clique in subgraph of `G` induced by a superset of `A`, its embedding is an `n`-clique in `G`. -/ theorem IsNClique.of_induce {S : Subgraph G} {F : Set α} {s : Finset { x // x ∈ F }} {n : ℕ} @@ -476,6 +477,7 @@ namespace completeMultipartiteGraph variable {ι : Type*} (V : ι → Type*) +set_option backward.isDefEq.respectTransparency.types false in /-- Embedding of the complete graph on `ι` into `completeMultipartiteGraph` on `ι` nonempty parts -/ @[simps] def topEmbedding (f : ∀ (i : ι), V i) : @@ -882,6 +884,7 @@ theorem isIndepSet_neighborSet_of_triangleFree (h : G.CliqueFree 3) (v : α) : obtain ⟨j, avj, k, avk, _, ajk⟩ := nind exact h {v, j, k} (is3Clique_triple_iff.mpr (by simp [avj, avk, ajk])) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The embedding of an independent set of an induced subgraph of the subgraph `G` is an independent set in `G` and vice versa. -/ diff --git a/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean b/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean index 57c4eb22faeac3..e79416b5755efb 100644 --- a/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/CompleteMultipartite.lean @@ -73,7 +73,7 @@ protected lemma IsCompleteMultipartite.induce (hG : G.IsCompleteMultipartite) : (G.induce s).IsCompleteMultipartite where trans _u _v _w := hG.trans _ _ _ /-- The setoid given by non-adjacency -/ -@[implicit_reducible] +@[instance_reducible] def IsCompleteMultipartite.setoid (h : G.IsCompleteMultipartite) : Setoid α := ⟨(¬ G.Adj · ·), ⟨G.loopless.irrefl, fun h' ↦ by rwa [adj_comm] at h', h.trans _ _ _⟩⟩ @@ -81,6 +81,7 @@ lemma completeMultipartiteGraph.isCompleteMultipartite {ι : Type*} (V : ι → (completeMultipartiteGraph V).IsCompleteMultipartite := ⟨by simp_all⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The graph isomorphism from a graph `G` that `IsCompleteMultipartite` to the corresponding `completeMultipartiteGraph` (see also `isCompleteMultipartite_iff`) -/ def IsCompleteMultipartite.iso (h : G.IsCompleteMultipartite) : @@ -226,6 +227,7 @@ def completeEquipartiteGraph.completeMultipartiteGraph : completeEquipartiteGraph r t ≃g completeMultipartiteGraph (const (Fin r) (Fin t)) := { (Equiv.sigmaEquivProd (Fin r) (Fin t)).symm with map_rel_iff' := by simp } +set_option backward.isDefEq.respectTransparency.types false in /-- A `completeEquipartiteGraph` is isomorphic to a corresponding `turanGraph`. The difference is that the former vertices are a product type whereas the latter vertices are @@ -372,10 +374,12 @@ theorem disjoint : (K.parts : Set (Finset V)).Pairwise Disjoint := /-- The finset of vertices in a complete equipartite subgraph. -/ def verts : Finset V := K.parts.disjiUnion id K.disjoint +set_option backward.isDefEq.respectTransparency.types false in open scoped Classical in /-- The finset of vertices in a complete equipartite subgraph as a `biUnion`. -/ lemma verts_eq_biUnion : K.verts = K.parts.biUnion id := by rw [verts, disjiUnion_eq_biUnion] +set_option backward.isDefEq.respectTransparency.types false in /-- There are `r * t` vertices in a complete equipartite subgraph with `r` parts of size `t`. -/ theorem card_verts : #K.verts = r * t := by simp_rw [verts, card_disjiUnion, id_eq, sum_congr rfl fun _ ↦ K.card_mem_parts, sum_const, @@ -410,6 +414,7 @@ noncomputable def toCopy : Copy (completeEquipartiteGraph r t) G := by refine K.isCompleteBetween (fᵣ _).prop (fᵣ _).prop ?_ (fₜ _ _).prop (fₜ _ _).prop exact Subtype.ext_iff.ne.mp <| fᵣ.injective.ne hne +set_option backward.isDefEq.respectTransparency.types false in /-- A copy of a complete equipartite graph identifies a complete equipartite subgraph. -/ def ofCopy (f : Copy (completeEquipartiteGraph r t) G) : G.CompleteEquipartiteSubgraph r t := by by_cases ht : t = 0 diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean index d0cabb0db4a0e8..53affe3aef7695 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean @@ -221,7 +221,7 @@ lemma not_reachable_of_right_degree_zero {G : SimpleGraph V} {u v : V} [Fintype exact not_reachable_of_left_degree_zero huv.symm hu /-- The equivalence relation on vertices given by `SimpleGraph.Reachable`. -/ -@[implicit_reducible] +@[instance_reducible] def reachableSetoid : Setoid V := Setoid.mk _ G.reachable_is_equivalence /-- A graph is preconnected if every pair of vertices is reachable from one another. -/ diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean index 0c265c4bdd44f5..83a7a8ec794002 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean @@ -70,6 +70,7 @@ instance instDecidableMemSupp (c : G.ConnectedComponent) (v : V) : Decidable (v c.recOn (fun w ↦ decidable_of_iff (G.Reachable v w) <| by simp) (fun _ _ _ _ ↦ Subsingleton.elim _ _) +set_option backward.isDefEq.respectTransparency.types false in variable {G} in lemma disjiUnion_supp_toFinset_eq_supp_toFinset {G' : SimpleGraph V} (h : G ≤ G') (c' : ConnectedComponent G') [Fintype c'.supp] @@ -85,6 +86,7 @@ end Fintype infinite components. -/ abbrev oddComponents : Set G.ConnectedComponent := {c : G.ConnectedComponent | Odd c.supp.ncard} +set_option backward.isDefEq.respectTransparency.types false in lemma ConnectedComponent.odd_oddComponents_ncard_subset_supp [Finite V] {G'} (h : G ≤ G') (c' : ConnectedComponent G') : Odd {c ∈ G.oddComponents | c.supp ⊆ c'.supp}.ncard ↔ Odd c'.supp.ncard := by @@ -110,6 +112,7 @@ lemma odd_ncard_oddComponents [Finite V] : Odd G.oddComponents.ncard ↔ Odd (Na simp_rw [← Set.ncard_eq_toFinset_card', ← Finset.coe_filter_univ, Set.ncard_coe_finset] exact (Finset.odd_sum_iff_odd_card_odd (fun x : G.ConnectedComponent ↦ x.supp.ncard)).symm +set_option backward.isDefEq.respectTransparency.types false in lemma ncard_oddComponents_mono [Finite V] {G' : SimpleGraph V} (h : G ≤ G') : G'.oddComponents.ncard ≤ G.oddComponents.ncard := by have aux (c : G'.ConnectedComponent) (hc : Odd c.supp.ncard) : diff --git a/Mathlib/Combinatorics/SimpleGraph/Copy.lean b/Mathlib/Combinatorics/SimpleGraph/Copy.lean index 79ec4ae0442ef6..5669976ebb964b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Copy.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Copy.lean @@ -636,6 +636,7 @@ protected lemma Free.killCopies_eq_left (hHG : H.Free G) : G.killCopies H = G := · exact killCopies_bot _ · exact (killCopies_eq_left hH).2 hHG +set_option backward.isDefEq.respectTransparency false in /-- Removing an edge from `G` for each subgraph isomorphic to `H` results in a graph that doesn't contain `H`. -/ lemma free_killCopies (hH : H ≠ ⊥) : H.Free (G.killCopies H) := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Dart.lean b/Mathlib/Combinatorics/SimpleGraph/Dart.lean index e494a16ae80f01..0b169a136f7fce 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Dart.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Dart.lean @@ -96,6 +96,7 @@ theorem Dart.symm_involutive : Function.Involutive (Dart.symm : G.Dart → G.Dar theorem Dart.symm_ne (d : G.Dart) : d.symm ≠ d := ne_of_apply_ne (Prod.snd ∘ Dart.toProd) d.adj.ne +set_option backward.isDefEq.respectTransparency false in theorem dart_edge_eq_iff : ∀ d₁ d₂ : G.Dart, d₁.edge = d₂.edge ↔ d₁ = d₂ ∨ d₁ = d₂.symm := by rintro ⟨p, hp⟩ ⟨q, hq⟩ simp diff --git a/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean b/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean index ea9dd77576bfa3..b80d0ee12f580f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean @@ -185,6 +185,7 @@ theorem hom_refl (C : G.ComponentCompl L) : C.hom (subset_refl L) = C := by change C.map _ = C rw [induceHom_id G Lᶜ, ConnectedComponent.map_id] +set_option backward.isDefEq.respectTransparency.types false in theorem hom_trans (C : G.ComponentCompl L) (h : K ⊆ L) (h' : M ⊆ K) : C.hom (h'.trans h) = (C.hom h).hom h' := by change C.map _ = (C.map _).map _ @@ -251,6 +252,7 @@ variable (G) open CategoryTheory +set_option backward.isDefEq.respectTransparency.types false in /-- The functor assigning, to a finite set in `V`, the set of connected components in its complement. -/ diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean index c6a8ba732b41ba..d3a02d29b42b8f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean @@ -58,6 +58,7 @@ lemma le_card_edgeFinset_between_verts : exact sum_le_sum (fun v hv ↦ sub_le_iff_le_add.mpr <| mod_cast (G.minDegree_le_degree v).trans (degree_le_between_add hv)) +set_option backward.isDefEq.respectTransparency.types false in /-- For `v ∈ K.vertsᶜ \ ErdosStone.filter`, since `v` is adjacent to fewer than `t` vertices in at least one part of the complete equipartite subgraph, it follows that `v` is adjacent to fewer than `#K.verts - (t' - t)` vertices in `K.verts`. @@ -188,6 +189,7 @@ theorem filter.pi.exists_le_card_fiber (hr_pos : 0 < r) (ht'_pos : 0 < t') end ErdosStone +set_option backward.isDefEq.respectTransparency.types false in /-- If `G` has a minimal degree of at least `(1 - 1 / r + o(1)) * n`, then `G` contains a copy of a `completeEquipartiteGraph` in `r + 1` parts each of size `t`. diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/Turan.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/Turan.lean index 40c4919868ec5d..d6055ddcc3e125 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/Turan.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/Turan.lean @@ -164,7 +164,7 @@ theorem equivalence_not_adj : Equivalence (¬G.Adj · ·) where /-- The non-adjacency setoid over the vertices of a Turán-maximal graph induced by `equivalence_not_adj`. -/ -@[implicit_reducible] +@[instance_reducible] def setoid : Setoid V := ⟨_, h.equivalence_not_adj⟩ instance : DecidableRel h.setoid.r := @@ -247,6 +247,7 @@ theorem card_parts [DecidableEq V] : #h.finpartition.parts = min (card V) r := b convert! G.card_edgeFinset_sup_edge _ hn rwa [h.not_adj_iff_part_eq] +set_option backward.isDefEq.respectTransparency.types false in /-- **Turán's theorem**, forward direction. Any `r + 1`-cliquefree Turán-maximal graph on `n` vertices is isomorphic to `turanGraph n r`. -/ @@ -344,6 +345,7 @@ private lemma sum_ne_add_mod_eq_sub_one {c : ℕ} : rw [Nat.add_mod_mod, ← add_assoc, ← one_add_mul, show 1 + (r - 1) = r by lia, Nat.mul_add_mod_self_left] +set_option backward.isDefEq.respectTransparency.types false in lemma card_edgeFinset_turanGraph_add : #(turanGraph (n + r) r).edgeFinset = #(turanGraph n r).edgeFinset + n * (r - 1) + r.choose 2 := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean b/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean index 968ebff9b9be06..55db378c1b866e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean @@ -65,7 +65,7 @@ theorem IsHamiltonian.of_subsingleton [Subsingleton α] : p.IsHamiltonian := by rw [nil_iff_support_eq.mp p.nil_of_subsingleton, Subsingleton.elim v a, List.count_singleton_self] /-- If a path `p` is Hamiltonian then the graph has finitely many vertices. -/ -@[implicit_reducible] +@[instance_reducible] protected def IsHamiltonian.fintype (hp : p.IsHamiltonian) : Fintype α where elems := p.support.toFinset complete x := List.mem_toFinset.mpr (mem_support hp x) diff --git a/Mathlib/Combinatorics/SimpleGraph/IncMatrix.lean b/Mathlib/Combinatorics/SimpleGraph/IncMatrix.lean index b95034f8a5fc9c..291b1a484c6463 100644 --- a/Mathlib/Combinatorics/SimpleGraph/IncMatrix.lean +++ b/Mathlib/Combinatorics/SimpleGraph/IncMatrix.lean @@ -108,6 +108,7 @@ theorem sum_incMatrix_apply [Fintype (Sym2 α)] [Fintype (neighborSet G a)] : ∑ e, G.incMatrix R a e = G.degree a := by simp [incMatrix_apply', sum_boole, Set.filter_mem_univ_eq_toFinset, card_incidenceSet_eq_degree] +set_option backward.isDefEq.respectTransparency false in theorem incMatrix_mul_transpose_diag [Fintype (Sym2 α)] [Fintype (neighborSet G a)] : (G.incMatrix R * (G.incMatrix R)ᵀ) a a = G.degree a := by rw [← sum_incMatrix_apply] diff --git a/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean b/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean index ee5bd217f3925c..c7b9d842835dd3 100644 --- a/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean +++ b/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean @@ -196,6 +196,7 @@ lemma linearIndependent_lapMatrix_ker_basis_aux : obtain ⟨i, h'⟩ : ∃ i : V, G.connectedComponentMk i = c := Quot.exists_rep c exact h' ▸ congrFun h0 i +set_option backward.isDefEq.respectTransparency.types false in lemma top_le_span_range_lapMatrix_ker_basis_aux : ⊤ ≤ Submodule.span ℝ (Set.range (lapMatrix_ker_basis_aux G)) := by intro x _ diff --git a/Mathlib/Combinatorics/SimpleGraph/LineGraph.lean b/Mathlib/Combinatorics/SimpleGraph/LineGraph.lean index f03bc2de4bdb10..d527b964b0a1c3 100644 --- a/Mathlib/Combinatorics/SimpleGraph/LineGraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/LineGraph.lean @@ -41,6 +41,7 @@ lemma lineGraph_adj_iff_exists {e₁ e₂ : G.edgeSet} : @[simp] lemma lineGraph_bot : (⊥ : SimpleGraph V).lineGraph = ⊥ := by aesop (add simp lineGraph) +set_option backward.isDefEq.respectTransparency false in /-- Lift a copy between graphs to an embedding between their line graphs -/ def Copy.toLineGraphEmbedding (f : Copy G G') : G.lineGraph ↪g G'.lineGraph where toFun e := ⟨e.val.map f, by rcases e with ⟨⟨⟩, h⟩; exact f.toHom.map_adj h⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index c2497a1dacb10b..79ab2b98e6486c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -608,6 +608,7 @@ def induceHomOfLE (h : s ≤ s') : G.induce s ↪g G.induce s' where @[simp] lemma induceHomOfLE_apply (v : s) : (G.induceHomOfLE h) v = Set.inclusion h v := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma induceHomOfLE_toHom : (G.induceHomOfLE h).toHom = induceHom (.id : G →g G) ((Set.mapsTo_id s).mono_right h) := by ext; simp @@ -792,6 +793,7 @@ theorem neighborSet_map_equiv (e : V ≃ W) (w : W) : (G.map e).neighborSet w = e.symm ⁻¹' G.neighborSet (e.symm w) := Iso.map e G |>.symm.toEmbedding.preimage_neighborSet w |>.symm +set_option backward.isDefEq.respectTransparency false in /-- The graph induced on `Set.univ` is isomorphic to the original graph. -/ @[simps!] def induceUnivIso (G : SimpleGraph V) : G.induce Set.univ ≃g G where diff --git a/Mathlib/Combinatorics/SimpleGraph/Matching.lean b/Mathlib/Combinatorics/SimpleGraph/Matching.lean index 393f79de9a5d99..7c54148c2b2dc7 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Matching.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Matching.lean @@ -70,6 +70,7 @@ def IsMatching (M : Subgraph G) : Prop := ∀ ⦃v⦄, v ∈ M.verts → ∃! w, noncomputable def IsMatching.toEdge (h : M.IsMatching) (v : M.verts) : M.edgeSet := ⟨s(v, (h v.property).choose), (h v.property).choose_spec.1⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem IsMatching.toEdge_eq_of_adj (h : M.IsMatching) (hvw : M.Adj v w) : h.toEdge ⟨v, hvw.fst_mem⟩ = ⟨s(v, w), hvw⟩ := by rw [IsMatching.toEdge, Subtype.mk_eq_mk, ← h hvw.fst_mem |>.choose_spec.right w hvw] @@ -78,6 +79,7 @@ theorem IsMatching.toEdge.surjective (h : M.IsMatching) : Surjective h.toEdge := rintro ⟨⟨x, y⟩, he⟩ exact ⟨⟨x, M.edge_vert he⟩, h.toEdge_eq_of_adj he⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem IsMatching.toEdge_eq_toEdge_of_adj (h : M.IsMatching) (ha : M.Adj v w) : h.toEdge ⟨v, ha.fst_mem⟩ = h.toEdge ⟨w, ha.snd_mem⟩ := by rw [h.toEdge_eq_of_adj ha, h.toEdge_eq_of_adj ha.symm, Subtype.mk_eq_mk, Sym2.eq_swap] @@ -86,6 +88,7 @@ theorem IsMatching.mem_coe_toEdge (h : M.IsMatching) {v : V} (hv : v ∈ M.verts v ∈ (h.toEdge ⟨v, hv⟩ : Sym2 V) := ⟨h hv |>.choose, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem IsMatching.toEdge_preimage_singleton (h : M.IsMatching) (huv : M.Adj u v) : h.toEdge ⁻¹' {⟨s(u, v), huv⟩} = {⟨u, huv.fst_mem⟩, ⟨v, huv.snd_mem⟩} := by refine Set.ext fun w ↦ ⟨fun hw ↦ ?_, fun hw ↦ ?_⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index ada1da35a5daf0..07c8dbd584a538 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -1105,6 +1105,7 @@ namespace Walk variable {G} {u v : V} {H : SimpleGraph V} variable {p : G.Walk u v} +set_option backward.isDefEq.respectTransparency.types false in protected theorem IsPath.transfer (hp) (pp : p.IsPath) : (p.transfer H hp).IsPath := by induction p with @@ -1113,6 +1114,7 @@ protected theorem IsPath.transfer (hp) (pp : p.IsPath) : simp only [Walk.transfer, cons_isPath_iff, support_transfer _] at pp ⊢ exact ⟨ih _ pp.1, pp.2⟩ +set_option backward.isDefEq.respectTransparency.types false in protected theorem IsCycle.transfer {q : G.Walk u u} (qc : q.IsCycle) (hq) : (q.transfer H hq).IsCycle := by cases q with diff --git a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean index c4e84e9b3d8ae7..f982dd2b27d756 100644 --- a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean +++ b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -95,6 +95,7 @@ theorem IsSRGWith.top : of_adj _ _ := card_commonNeighbors_top of_not_adj v w h h' := (h' ((top_adj v w).2 h)).elim +set_option backward.isDefEq.respectTransparency.types false in theorem IsSRGWith.card_neighborFinset_union_eq {v w : V} (h : G.IsSRGWith n k ℓ μ) : #(G.neighborFinset v ∪ G.neighborFinset w) = 2 * k - Fintype.card (G.commonNeighbors v w) := by @@ -201,6 +202,7 @@ theorem IsSRGWith.param_eq ← Set.toFinset_card] congr! +set_option backward.isDefEq.respectTransparency.types false in /-- Let `A` and `C` be the adjacency matrices of a strongly regular graph with parameters `n k ℓ μ` and its complement respectively and `I` be the identity matrix, then `A ^ 2 = k • I + ℓ • A + μ • C`. `C` is equivalent to the expression `J - I - A` diff --git a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean index bc9ccfecd07846..62efb7fbfc8f5d 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean @@ -467,7 +467,7 @@ instance : BoundedOrder (Subgraph G) where bot_le _ := ⟨Set.empty_subset _, fun _ _ => False.elim⟩ /-- Note that subgraphs do not form a Boolean algebra, because of `verts`. -/ -@[implicit_reducible] +@[instance_reducible] def completelyDistribLatticeMinimalAxioms : CompletelyDistribLattice.MinimalAxioms G.Subgraph where le_top G' := ⟨Set.subset_univ _, fun _ _ => G'.adj_sub⟩ bot_le _ := ⟨Set.empty_subset _, fun _ _ => False.elim⟩ @@ -772,7 +772,7 @@ instance finiteAt {G' : Subgraph G} (v : G'.verts) [DecidableRel G'.Adj] /-- If a subgraph is locally finite at a vertex, then so are subgraphs of that subgraph. This is not an instance because `G''` cannot be inferred. -/ -@[implicit_reducible] +@[instance_reducible] def finiteAtOfSubgraph {G' G'' : Subgraph G} [DecidableRel G'.Adj] (h : G' ≤ G'') (v : G'.verts) [Fintype (G''.neighborSet v)] : Fintype (G'.neighborSet v) := Set.fintypeSubset (G''.neighborSet v) (neighborSet_subset_of_subgraph h v) @@ -1105,6 +1105,7 @@ theorem deleteEdges_spanningCoe_eq : ext simp +set_option backward.isDefEq.respectTransparency false in theorem deleteEdges_coe_eq (s : Set (Sym2 G'.verts)) : G'.coe.deleteEdges s = (G'.deleteEdges (Sym2.map (↑) '' s)).coe := by ext ⟨v, hv⟩ ⟨w, hw⟩ @@ -1121,6 +1122,7 @@ theorem deleteEdges_coe_eq (s : Set (Sym2 G'.verts)) : · intro h' hs exact h' _ hs rfl +set_option backward.isDefEq.respectTransparency false in theorem coe_deleteEdges_eq (s : Set (Sym2 V)) : (G'.deleteEdges s).coe = G'.coe.deleteEdges (Sym2.map (↑) ⁻¹' s) := by ext ⟨v, hv⟩ ⟨w, hw⟩ @@ -1145,6 +1147,7 @@ theorem deleteEdges_inter_edgeSet_right_eq : G'.deleteEdges (s ∩ G'.edgeSet) = G'.deleteEdges s := by ext <;> simp +contextual [imp_false] +set_option backward.isDefEq.respectTransparency false in theorem coe_deleteEdges_le : (G'.deleteEdges s).coe ≤ (G'.coe : SimpleGraph G'.verts) := by intro v w simp +contextual @@ -1172,6 +1175,7 @@ def induce (G' : G.Subgraph) (s : Set V) : G.Subgraph where edge_vert h := h.1 symm.symm _ _ h := ⟨h.2.1, h.1, h.2.2.symm⟩ +set_option backward.isDefEq.respectTransparency false in theorem _root_.SimpleGraph.induce_eq_coe_induce_top (s : Set V) : G.induce s = ((⊤ : G.Subgraph).induce s).coe := by ext @@ -1309,6 +1313,7 @@ theorem deleteVerts_mono {G' G'' : G.Subgraph} (h : G' ≤ G'') : G'.deleteVerts s ≤ G''.deleteVerts s := induce_mono h (Set.sdiff_subset_sdiff_left h.1) +set_option backward.isDefEq.respectTransparency false in @[mono] lemma deleteVerts_mono' {G' : SimpleGraph V} (u : Set V) (h : G ≤ G') : ((⊤ : Subgraph G).deleteVerts u).coe ≤ ((⊤ : Subgraph G').deleteVerts u).coe := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Sum.lean b/Mathlib/Combinatorics/SimpleGraph/Sum.lean index 349388d30ddf97..81957e86c027c1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Sum.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Sum.lean @@ -62,6 +62,7 @@ def Iso.sumAssoc : (G ⊕g H) ⊕g I ≃g G ⊕g (H ⊕g I) where toEquiv := .sumAssoc .. map_rel_iff' := by rintro ((u | u) | u) ((v | v) | v) <;> simp +set_option backward.isDefEq.respectTransparency.types false in /-- The embedding of `G` into `G ⊕g H`. -/ @[simps] def Embedding.sumInl : G ↪g G ⊕g H where @@ -69,6 +70,7 @@ def Embedding.sumInl : G ↪g G ⊕g H where inj' u v := by simp map_rel_iff' := by simp +set_option backward.isDefEq.respectTransparency.types false in /-- The embedding of `H` into `G ⊕g H`. -/ @[simps] def Embedding.sumInr : H ↪g G ⊕g H where @@ -91,6 +93,7 @@ lemma Hom.sum_sum_comp_sumAssoc (f : G →g G') (g : H →g H') (h : I →g I') comp (sum f (sum g h)) Iso.sumAssoc.toHom = comp Iso.sumAssoc.toHom (sum (sum f g) h) := by ext ((v | w) | u) <;> simp +set_option backward.isDefEq.respectTransparency.types false in /-- Given embeddings `f : G ↪g G'` and `g : H ↪g H'`, returns an embedding from `G ⊕g H` to `G' ⊕g H'` that applies `f` to the left component and `g` to the right component. -/ @[simps] @@ -132,6 +135,7 @@ lemma Iso.sumAssoc_comp_sumCongr (f : G ≃g G') (g : H ≃g H') (h : I ≃g I') comp sumAssoc (sumCongr (sumCongr f g) h) = comp (sumCongr f (sumCongr g h)) sumAssoc := by ext ((v | w) | u) <;> simp +set_option backward.isDefEq.respectTransparency.types false in /-- The edges of the disjoint sum of `G` and `H` are in bijection with the disjoint sum of the edges of `G` and the edges of `H` -/ def edgeSetSumEquiv : (G ⊕g H).edgeSet ≃ G.edgeSet ⊕ H.edgeSet where diff --git a/Mathlib/Combinatorics/SimpleGraph/Trails.lean b/Mathlib/Combinatorics/SimpleGraph/Trails.lean index d2e877fc573e22..08dda36f3a113d 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Trails.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Trails.lean @@ -91,8 +91,9 @@ theorem IsEulerian.mem_edges_iff {u v : V} {p : G.Walk u v} (h : p.IsEulerian) { ⟨fun h => p.edges_subset_edgeSet h, fun he => by simpa [Nat.succ_le_iff] using (h e he).ge⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- The edge set of an Eulerian graph is finite. -/ -@[implicit_reducible] +@[instance_reducible] def IsEulerian.fintypeEdgeSet {u v : V} {p : G.Walk u v} (h : p.IsEulerian) : Fintype G.edgeSet := Fintype.ofFinset h.isTrail.edgesFinset fun e => by @@ -119,6 +120,7 @@ theorem IsEulerian.edgeSet_eq {u v : V} {p : G.Walk u v} (h : p.IsEulerian) : p.edgeSet = G.edgeSet := by rwa [← h.isTrail.isEulerian_iff] +set_option backward.isDefEq.respectTransparency.types false in theorem IsEulerian.edgesFinset_eq [Fintype G.edgeSet] {u v : V} {p : G.Walk u v} (h : p.IsEulerian) : h.isTrail.edgesFinset = G.edgeFinset := by ext e diff --git a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean index 364bd1268ef4c1..a0720c1d874ab0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Tutte.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Tutte.lean @@ -264,6 +264,7 @@ private theorem tutte_exists_isPerfectMatching_of_near_matchings {x a b c : V} exact tutte_exists_isAlternating_isCycles p hp hcalt (hnM2 _ hnbc) hpac hnpxb hM2ac hab.symm hnbc hxa.ne.symm hle (aux (by simp)) +set_option backward.isDefEq.respectTransparency.types false in /-- From a graph on an even number of vertices with no perfect matching, we can remove an odd number of vertices such that there are more odd components in the resulting graph than vertices we removed. diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean index 9a5207b816f60d..bf05e097bb608e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean @@ -463,6 +463,7 @@ theorem ofSupport_cons_cons {l : List V} (hchain : u :: v :: l |>.IsChain G.Adj) .cons hchain.rel (.ofSupport (v :: l) (l.cons_ne_nil v) hchain.of_cons) := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem support_ofSupport {l : List V} (hne : l ≠ []) (hchain : l.IsChain G.Adj) : (ofSupport l hne hchain).support = l := by @@ -498,6 +499,7 @@ theorem ofDarts_cons_cons {d₁ d₂ : G.Dart} {l : List G.Dart} .cons (hchain.rel ▸ d₁.adj) (ofDarts (d₂ :: l) (l.cons_ne_nil d₂) hchain.of_cons) := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem darts_ofDarts {l : List G.Dart} (hne : l ≠ []) (hchain : l.IsChain G.DartAdj) : (ofDarts l hne hchain).darts = l := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean index be97836049dd3c..515384b6880def 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean @@ -69,6 +69,7 @@ section LocallyFinite variable [DecidableEq V] [LocallyFinite G] +set_option backward.isDefEq.respectTransparency.types false in /-- The `Finset` of length-`n` walks from `u` to `v`. This is used to give `{p : G.walk u v | p.length = n}` a `Fintype` instance, and it can also be useful as a recursive description of this set when `V` is finite. @@ -111,6 +112,7 @@ def finsetWalkLengthLT (n : ℕ) (u v : V) : Finset (G.Walk u v) := have hl' : p.length = l' := mem_finsetWalkLength_iff.mp (hsl' hp) False.elim <| hne <| hl.symm.trans hl') +set_option backward.isDefEq.respectTransparency.types false in open Finset in theorem coe_finsetWalkLengthLT_eq (n : ℕ) (u v : V) : (G.finsetWalkLengthLT n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length < n} := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean index 3f7de4a62040bf..818eeb1e01be55 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean @@ -58,6 +58,7 @@ lemma takeUntil_first (p : G.Walk u v) : lemma nil_takeUntil (p : G.Walk u v) (hwp : w ∈ p.support) : (p.takeUntil w hwp).Nil ↔ u = w := ⟨Nil.eq, (by cases ·; simp)⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma takeUntil_eq_take (p : G.Walk u v) (h : w ∈ p.support) : p.takeUntil w h = (p.take <| p.support.idxOf w).copy rfl (p.getVert_support_idxOf h) := by apply ext_support @@ -105,6 +106,7 @@ lemma dropUntil_first (p : G.Walk u v) (h : u ∈ p.support) : p.dropUntil u h = unfold dropUntil split <;> simp +set_option backward.isDefEq.respectTransparency.types false in lemma dropUntil_eq_drop (p : G.Walk u v) (h : w ∈ p.support) : p.dropUntil w h = (p.drop <| p.support.idxOf w).copy (p.getVert_support_idxOf h) rfl := by apply ext_support diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean index c7c8b3304435ae..bfb974927be9d2 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean @@ -159,6 +159,7 @@ variable {H : SimpleGraph V} theorem transfer_eq_map_ofLE (hp) (GH : G ≤ H) : p.transfer H hp = p.map (.ofLE GH) := by induction p <;> simp [*] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem edges_transfer (hp) : (p.transfer H hp).edges = p.edges := by induction p <;> simp [*] @@ -166,10 +167,12 @@ theorem edges_transfer (hp) : (p.transfer H hp).edges = p.edges := by @[simp] theorem edgeSet_transfer (hp) : (p.transfer H hp).edgeSet = p.edgeSet := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem support_transfer (hp) : (p.transfer H hp).support = p.support := by induction p <;> simp [*] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem length_transfer (hp) : (p.transfer H hp).length = p.length := by induction p <;> simp [*] @@ -179,6 +182,7 @@ theorem transfer_transfer (hp) {K : SimpleGraph V} (hp') : (p.transfer H hp).transfer K hp' = p.transfer K (p.edges_transfer hp ▸ hp') := by induction p <;> simp [*] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transfer_append {w : V} (q : G.Walk v w) (hpq) : (p.append q).transfer H hpq = @@ -186,6 +190,7 @@ theorem transfer_append {w : V} (q : G.Walk v w) (hpq) : (q.transfer H fun e he => hpq _ (by simp [he])) := by induction p <;> simp [*] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem reverse_transfer (hp) : (p.transfer H hp).reverse = @@ -219,6 +224,7 @@ protected def induce {u v : V} : | .nil, hw => rfl | .cons (v := u') huu' w, hw => by simp [map_induce] +set_option backward.isDefEq.respectTransparency.types false in lemma map_induce_induceHomOfLE (hs : s ⊆ s') {u v : V} : ∀ (w : G.Walk u v) (hw), (w.induce s hw).map (G.induceHomOfLE hs).toHom = w.induce s' (subset_trans hw hs) | .nil, hw => rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean index 8a40f9af75b4fa..aea91e0f61c68b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean @@ -282,6 +282,7 @@ def concatRec {u v : V} (p : G.Walk u v) : motive u v p := theorem concatRec_nil (u : V) : @concatRec _ _ motive @Hnil @Hconcat _ _ (nil : G.Walk u u) = Hnil := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem concatRec_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) : @concatRec _ _ motive @Hnil @Hconcat _ _ (p.concat h) = @@ -291,7 +292,7 @@ theorem concatRec_concat {u v w : V} (p : G.Walk u v) (h : G.Adj v w) : trans concatRecAux @Hnil @Hconcat (cons h.symm p.reverse) · congr simp - · rw [concatRecAux, eqRec_heq_iff_heq] + · rw [concatRecAux, eqRec_heq_iff] congr <;> simp end ConcatRec @@ -413,6 +414,7 @@ theorem coe_support_append' [DecidableEq V] {u v w : V} (p : G.Walk u v) (p' : G simp_rw [support_append, ← Multiset.coe_add, coe_support, add_comm ({v} : Multiset V), ← add_assoc, add_tsub_cancel_right] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ofSupport_support {u v : V} (p : G.Walk u v) : ofSupport _ p.support_ne_nil p.isChain_adj_support = p.copy (by simp) (by simp) := by @@ -448,6 +450,7 @@ theorem darts_reverse {u v : V} (p : G.Walk u v) : theorem mem_darts_reverse {u v : V} {d : G.Dart} {p : G.Walk u v} : d ∈ p.reverse.darts ↔ d.symm ∈ p.darts := by simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ofDarts_darts {u v : V} {p : G.Walk u v} (hp : ¬p.Nil) : ofDarts _ (darts_eq_nil.not.mpr hp) p.isChain_dartAdj_darts = p.copy (by simp) (by simp) := by @@ -538,6 +541,7 @@ lemma Nil.append {p : G.Walk u v} {q : G.Walk v w} (hp : p.Nil) (hq : q.Nil) : lemma nil_reverse {p : G.Walk v w} : p.reverse.Nil ↔ p.Nil := by cases p <;> simp +set_option backward.isDefEq.respectTransparency.types false in /-- The walk obtained by removing the first `n` darts of a walk. -/ def drop {u v : V} (p : G.Walk u v) (n : ℕ) : G.Walk (p.getVert n) v := match p, n with @@ -580,6 +584,7 @@ lemma darts_drop (p : G.Walk u v) (n : ℕ) : (p.drop n).darts = p.darts.drop n lemma edges_drop (p : G.Walk u v) (n : ℕ) : (p.drop n).edges = p.edges.drop n := by induction p generalizing n <;> cases n <;> simp [*, drop] +set_option backward.isDefEq.respectTransparency.types false in /-- The walk obtained by taking the first `n` darts of a walk. -/ def take {u v : V} (p : G.Walk u v) (n : ℕ) : G.Walk u (p.getVert n) := match p, n with @@ -721,10 +726,12 @@ lemma dropLast_concat {t u v} (p : G.Walk u v) (h : G.Adj v t) : · rw! [concat_cons, dropLast_cons_of_not_nil] <;> simp [*, ← length_eq_zero_iff] +set_option backward.isDefEq.respectTransparency.types false in lemma cons_tail_eq (p : G.Walk u v) (hp : ¬ p.Nil) : cons (p.adj_snd hp) p.tail = p := by cases p <;> simp at hp ⊢ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma concat_dropLast {p : G.Walk u v} (hp : G.Adj p.penultimate v) : p.dropLast.concat hp = p := by induction p with diff --git a/Mathlib/Combinatorics/Young/YoungDiagram.lean b/Mathlib/Combinatorics/Young/YoungDiagram.lean index 1cd2854a0ba10b..3b7180b0fd6aac 100644 --- a/Mathlib/Combinatorics/Young/YoungDiagram.lean +++ b/Mathlib/Combinatorics/Young/YoungDiagram.lean @@ -229,6 +229,7 @@ theorem transpose_le_iff {μ ν : YoungDiagram} : μ.transpose ≤ ν.transpose protected theorem transpose_mono {μ ν : YoungDiagram} (h_le : μ ≤ ν) : μ.transpose ≤ ν.transpose := transpose_le_iff.mpr h_le +set_option backward.isDefEq.respectTransparency false in /-- Transposing Young diagrams is an `OrderIso`. -/ @[simps] def transposeOrderIso : YoungDiagram ≃o YoungDiagram := @@ -259,6 +260,7 @@ theorem mem_row_iff {μ : YoungDiagram} {i : ℕ} {c : ℕ × ℕ} : c ∈ μ.ro theorem mk_mem_row_iff {μ : YoungDiagram} {i j : ℕ} : (i, j) ∈ μ.row i ↔ (i, j) ∈ μ := by simp [row] +set_option backward.isDefEq.respectTransparency false in protected theorem exists_notMem_row (μ : YoungDiagram) (i : ℕ) : ∃ j, (i, j) ∉ μ := by obtain ⟨j, hj⟩ := Infinite.exists_notMem_finset diff --git a/Mathlib/Computability/Ackermann.lean b/Mathlib/Computability/Ackermann.lean index d100c4f3290f01..ab7886f873d6e0 100644 --- a/Mathlib/Computability/Ackermann.lean +++ b/Mathlib/Computability/Ackermann.lean @@ -358,10 +358,12 @@ lemma primrec_pappAck_step : Primrec pappAck.step := by [Code.primrec₂_curry.comp, Code.primrec₂_prec.comp, Code.primrec₂_comp.comp, _root_.Primrec.id, Primrec.const] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma eval_pappAck_step_zero (c : Code) : (pappAck.step c).eval 0 = c.eval 1 := by simp [pappAck.step, Code.eval] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma eval_pappAck_step_succ (c : Code) (n) : (pappAck.step c).eval (n + 1) = ((pappAck.step c).eval n).bind c.eval := by @@ -372,6 +374,7 @@ lemma primrec_pappAck : Primrec pappAck := by convert! this using 2 with n; induction n <;> simp [pappAck, *] apply_rules [Primrec.nat_rec₁, primrec_pappAck_step.comp, Primrec.snd] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma eval_pappAck (m n) : (pappAck m).eval n = Part.some (ack m n) := by induction m, n using ack.induct with diff --git a/Mathlib/Computability/ContextFreeGrammar.lean b/Mathlib/Computability/ContextFreeGrammar.lean index afc77c897f18a9..d1e1f2ca738942 100644 --- a/Mathlib/Computability/ContextFreeGrammar.lean +++ b/Mathlib/Computability/ContextFreeGrammar.lean @@ -318,6 +318,7 @@ protected lemma Derives.reverse (hg : g.Derives u v) : g.reverse.Derives u.rever | tail _ orig ih => exact ih.trans_produces orig.reverse set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in lemma derives_reverse : g.reverse.Derives u.reverse v.reverse ↔ g.Derives u v := ⟨fun h ↦ by convert! h.reverse <;> simp, .reverse⟩ diff --git a/Mathlib/Computability/DFA.lean b/Mathlib/Computability/DFA.lean index ccaa5475694f7f..d4c2d06f5c3e19 100644 --- a/Mathlib/Computability/DFA.lean +++ b/Mathlib/Computability/DFA.lean @@ -262,6 +262,7 @@ theorem accepts_reindex (g : σ ≃ σ') : (reindex g M).accepts = M.accepts := ext x simp [mem_accepts] +set_option backward.isDefEq.respectTransparency false in theorem comap_reindex (f : α' → α) (g : σ ≃ σ') : (reindex g M).comap f = reindex g (M.comap f) := by simp [comap, reindex] diff --git a/Mathlib/Computability/Encoding.lean b/Mathlib/Computability/Encoding.lean index 4cd65ae2e2275e..0b0068dc8658f7 100644 --- a/Mathlib/Computability/Encoding.lean +++ b/Mathlib/Computability/Encoding.lean @@ -193,6 +193,7 @@ def encodingList (α : Type) : Encoding (List α) α where decode := Option.some decode_encode _ := rfl +set_option backward.isDefEq.respectTransparency false in /-- Given an `Encoding` of `α` and `β`, constructs an `Encoding` of `α × β` by concatenating the encodings, diff --git a/Mathlib/Computability/Language.lean b/Mathlib/Computability/Language.lean index 292d3d1a7d69e1..49edd72146e8c3 100644 --- a/Mathlib/Computability/Language.lean +++ b/Mathlib/Computability/Language.lean @@ -157,6 +157,7 @@ theorem nil_mem_kstar (l : Language α) : [] ∈ l∗ := instance : OrderedSub (Language α) where tsub_le_iff_right _ _ _ := sdiff_le_iff' +set_option backward.isDefEq.respectTransparency false in instance instSemiring : Semiring (Language α) where add_assoc := union_assoc zero_add := empty_union @@ -186,9 +187,11 @@ def map (f : α → β) : Language α →+* Language β where map_add' := image_union _ map_mul' _ _ := image_image2_distrib <| fun _ _ => map_append +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_id (l : Language α) : map id l = l := by simp [map] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_map (g : β → γ) (f : α → β) (l : Language α) : map g (map f l) = map (g ∘ f) l := by simp [map, image_image] @@ -363,6 +366,7 @@ lemma reverse_reverse (l : Language α) : l.reverse.reverse = l := reverse_invol @[simp] lemma reverse_add (l m : Language α) : (l + m).reverse = l.reverse + m.reverse := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma reverse_mul (l m : Language α) : (l * m).reverse = m.reverse * l.reverse := by simp only [mul_def, reverse_eq_image, image2_image_left, image2_image_right, image_image2, diff --git a/Mathlib/Computability/NFA.lean b/Mathlib/Computability/NFA.lean index f8f4b2a794a18a..4a01150be85432 100644 --- a/Mathlib/Computability/NFA.lean +++ b/Mathlib/Computability/NFA.lean @@ -209,6 +209,7 @@ theorem acceptsFrom_iUnion {ι : Sort*} (s : ι → Set σ) : simp only [acceptsFrom, evalFrom_iUnion, mem_iUnion] simp_rw [↑mem_iUnion, ↑mem_setOf_eq]; tauto +set_option backward.isDefEq.respectTransparency false in variable (M) in theorem acceptsFrom_iUnion₂ {ι : Sort*} {κ : ι → Sort*} (f : ∀ i, κ i → Set σ) : M.acceptsFrom (⋃ (i) (j), f i j) = ⋃ (i) (j), M.acceptsFrom (f i j) := by diff --git a/Mathlib/Computability/Partrec.lean b/Mathlib/Computability/Partrec.lean index 0e6f71a84e1bc8..7d6f5466e870aa 100644 --- a/Mathlib/Computability/Partrec.lean +++ b/Mathlib/Computability/Partrec.lean @@ -179,6 +179,7 @@ theorem of_eq_tot {f : ℕ →. ℕ} {g : ℕ → ℕ} (hf : Nat.Partrec f) (H : Nat.Partrec g := hf.of_eq fun n => eq_some_iff.2 (H n) +set_option backward.isDefEq.respectTransparency false in theorem of_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) : Nat.Partrec f := by induction hf with | zero => exact zero @@ -202,6 +203,7 @@ theorem of_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) : Nat.Partrec f := by protected theorem some : Nat.Partrec some := of_primrec Primrec.id +set_option backward.isDefEq.respectTransparency false in theorem none : Nat.Partrec fun _ => none := (of_primrec (Nat.Primrec.const 1)).rfind.of_eq fun _ => eq_none_iff.2 fun _ ⟨h, _⟩ => by simp at h @@ -212,6 +214,7 @@ theorem prec' {f g h} (hf : Nat.Partrec f) (hg : Nat.Partrec g) (hh : Nat.Partre ((prec hg hh).comp (pair Partrec.some hf)).of_eq fun a => ext fun s => by simp [Seq.seq] +set_option backward.isDefEq.respectTransparency false in theorem ppred : Nat.Partrec fun n => ppred n := have : Primrec₂ fun n m => if n = Nat.succ m then 0 else 1 := (Primrec.ite @@ -399,6 +402,7 @@ theorem const' (s : Part σ) : Partrec fun _ : α => s := haveI := Classical.dec s.Dom Decidable.Partrec.const' s +set_option backward.isDefEq.respectTransparency false in protected theorem bind {f : α →. β} {g : α → β →. σ} (hf : Partrec f) (hg : Partrec₂ g) : Partrec fun a => (f a).bind (g a) := (hg.comp (Nat.Partrec.some.pair hf)).of_eq fun n => by @@ -492,6 +496,7 @@ variable {α : Type*} {σ : Type*} [Primcodable α] [Primcodable σ] open Computable +set_option backward.isDefEq.respectTransparency false in theorem rfind {p : α → ℕ →. Bool} (hp : Partrec₂ p) : Partrec fun a => Nat.rfind (p a) := (Nat.Partrec.rfind <| hp.map ((Primrec.dom_bool fun b => cond b 0 1).comp Primrec.snd).to₂.to_comp).of_eq @@ -553,6 +558,7 @@ variable [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable σ] theorem option_some_iff {f : α → σ} : (Computable fun a => Option.some (f a)) ↔ Computable f := ⟨fun h => encode_iff.1 <| Primrec.pred.to_comp.comp <| encode_iff.2 h, option_some.comp⟩ +set_option backward.isDefEq.respectTransparency false in theorem bind_decode_iff {f : α → β → Option σ} : (Computable₂ fun a n => (decode (α := β) n).bind (f a)) ↔ Computable₂ f := ⟨fun hf => @@ -678,6 +684,7 @@ theorem option_some_iff {f : α →. σ} : (Partrec fun a => (f a).map Option.so ⟨fun h => (Nat.Partrec.ppred.comp h).of_eq fun n => by simp [Part.bind_assoc, bind_some_eq_map], fun hf => hf.map (option_some.comp snd).to₂⟩ +set_option backward.isDefEq.respectTransparency false in theorem optionCasesOn_right {o : α → Option β} {f : α → σ} {g : α → β →. σ} (ho : Computable o) (hf : Computable f) (hg : Partrec₂ g) : @Partrec _ σ _ _ fun a => Option.casesOn (o a) (Part.some (f a)) (g a) := @@ -759,6 +766,7 @@ theorem fix_aux {α σ} (f : α →. σ ⊕ α) (a : α) (b : σ) : clear_value F grind +set_option backward.isDefEq.respectTransparency false in theorem fix {f : α →. σ ⊕ α} (hf : Partrec f) : Partrec (PFun.fix f) := by let F : α → ℕ →. σ ⊕ α := fun a n => n.rec (some (Sum.inr a)) fun _ IH => IH.bind fun s => Sum.casesOn s (fun _ => Part.some s) f diff --git a/Mathlib/Computability/PartrecBasis.lean b/Mathlib/Computability/PartrecBasis.lean index b8ac24de132123..34aa815b8880be 100644 --- a/Mathlib/Computability/PartrecBasis.lean +++ b/Mathlib/Computability/PartrecBasis.lean @@ -39,7 +39,7 @@ end Nat namespace Nat.Partrec' -open List.Vector Partrec Computable +open List.Vector Computable open Nat.Partrec' @@ -64,11 +64,13 @@ theorem of_prim {n} {f : List.Vector ℕ n → ℕ} (hf : Primrec f) : @Partrec' theorem head {n : ℕ} : @Partrec' n.succ (@head ℕ n) := prim Nat.Primrec'.head +set_option backward.isDefEq.respectTransparency.types false in theorem tail {n f} (hf : @Partrec' n f) : @Partrec' n.succ fun v => f v.tail := (hf.comp _ fun i => @prim _ _ <| Nat.Primrec'.get i.succ).of_eq fun v => by rw [← ofFn_get v.tail, funext (get_tail_succ v)] simp +set_option backward.isDefEq.respectTransparency.types false in protected theorem bind {n f g} (hf : @Partrec' n f) (hg : @Partrec' (n + 1) g) : @Partrec' n fun v => (f v).bind fun a => g (a ::ᵥ v) := (@comp n (n + 1) g (Fin.cases f (fun i v => some (v.get i))) hg <| @@ -95,6 +97,7 @@ protected theorem cons {n m} {f : List.Vector ℕ n → ℕ} {g} (hf : @Partrec' theorem idv {n} : @Vec n n id := Vec.prim Nat.Primrec'.idv +set_option backward.isDefEq.respectTransparency.types false in theorem comp' {n m f g} (hf : @Partrec' m f) (hg : @Vec n m g) : Partrec' fun v => f (g v) := (hf.comp _ hg).of_eq fun v => by simp diff --git a/Mathlib/Computability/PartrecCode.lean b/Mathlib/Computability/PartrecCode.lean index 28d51e727e65df..9b69165e860e1a 100644 --- a/Mathlib/Computability/PartrecCode.lean +++ b/Mathlib/Computability/PartrecCode.lean @@ -493,6 +493,7 @@ theorem eval_prec_succ (cf cg : Code) (a k : ℕ) : instance : Membership (ℕ →. ℕ) Code := ⟨fun c f => eval c = f⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem eval_const : ∀ n m, eval (Code.const n) m = Part.some n | 0, _ => rfl @@ -501,6 +502,7 @@ theorem eval_const : ∀ n m, eval (Code.const n) m = Part.some n @[simp] theorem eval_id (n) : eval Code.id n = Part.some n := by simp! [Seq.seq, Code.id] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem eval_curry (c n x) : eval (curry c n) x = eval c (Nat.pair n x) := by simp! [Seq.seq, curry] @@ -528,6 +530,7 @@ theorem smn : ∃ f : Code → ℕ → Code, Computable₂ f ∧ ∀ c n x, eval (f c n) x = eval c (Nat.pair n x) := ⟨curry, Primrec₂.to_comp primrec₂_curry, eval_curry⟩ +set_option backward.isDefEq.respectTransparency false in /-- A function is partial recursive if and only if there is a code implementing it. Therefore, `eval` is a **universal partial recursive function**. -/ theorem exists_code {f : ℕ →. ℕ} : Nat.Partrec f ↔ ∃ c : Code, eval c = f := by @@ -647,6 +650,7 @@ theorem evaln_mono : ∀ {k₁ k₂ c n x}, k₁ ≤ k₂ → x ∈ evaln k₁ c by_cases x0 : x = 0 <;> simp [x0] exact evaln_mono hl' +set_option backward.isDefEq.respectTransparency false in set_option linter.flexible false in -- TODO: revisit this after #13791 is merged theorem evaln_sound : ∀ {k c n x}, x ∈ evaln k c n → x ∈ eval c n | 0, _, n, x, h => by simp [evaln] at h @@ -686,6 +690,7 @@ theorem evaln_sound : ∀ {k c n x}, x ∈ evaln k c n → x ∈ eval c n · rcases hy₂ (Nat.lt_of_succ_lt_succ im) with ⟨z, hz, z0⟩ exact ⟨z, by simpa [add_comm, add_left_comm] using hz, z0⟩ +set_option backward.isDefEq.respectTransparency false in set_option linter.flexible false in -- TODO: revisit this after #13791 is merged theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n := by refine ⟨fun h => ?_, fun ⟨k, h⟩ => evaln_sound h⟩ @@ -761,8 +766,6 @@ theorem evaln_complete {c n x} : x ∈ eval c n ↔ ∃ k, x ∈ evaln k c n := section -open Primrec - private def lup (L : List (List (Option ℕ))) (p : ℕ × Code) (n : ℕ) := do let l ← L[encode p]? let o ← l[n]? @@ -984,7 +987,7 @@ end section -open Partrec Computable +open Computable theorem eval_eq_rfindOpt (c n) : eval c n = Nat.rfindOpt fun k => evaln k c n := Part.ext fun x => by @@ -1031,6 +1034,7 @@ instance : Countable {f : ℕ →. ℕ // Partrec f} := by apply Function.Surjective.countable (f := fun c => ⟨eval c, eval_part.comp (.const c) .id⟩) intro ⟨f, hf⟩; simpa using! exists_code.1 hf +set_option backward.isDefEq.respectTransparency false in /-- There are only countably many computable functions `ℕ → ℕ`. -/ instance : Countable {f : ℕ → ℕ // Computable f} := @Function.Injective.countable {f : ℕ → ℕ // Computable f} {f : ℕ →. ℕ // Partrec f} _ diff --git a/Mathlib/Computability/Primrec/Basic.lean b/Mathlib/Computability/Primrec/Basic.lean index 54aec2d4fd1113..70faf1d6eb86cd 100644 --- a/Mathlib/Computability/Primrec/Basic.lean +++ b/Mathlib/Computability/Primrec/Basic.lean @@ -140,7 +140,7 @@ instance (priority := 10) ofDenumerable (α) [Denumerable α] : Primcodable α : ⟨Nat.Primrec.succ.of_eq <| by simp⟩ /-- Builds a `Primcodable` instance from an equivalence to a `Primcodable` type. -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv (α) {β} [Primcodable α] (e : β ≃ α) : Primcodable β := { __ := Encodable.ofEquiv α e prim := (Primcodable.prim α).of_eq fun n => by @@ -810,7 +810,7 @@ variable {α : Type*} [Primcodable α] open Primrec /-- A subtype of a primitive recursive predicate is `Primcodable`. -/ -@[implicit_reducible] +@[instance_reducible] def subtype {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) : Primcodable (Subtype p) := ⟨have : Primrec fun n => (@decode α _ n).bind fun a => Option.guard p a := option_bind .decode (option_guard (hp.comp snd).primrecRel snd) diff --git a/Mathlib/Computability/Primrec/List.lean b/Mathlib/Computability/Primrec/List.lean index 1149e4f5cb9e22..2ca0e9dd7b8ba4 100644 --- a/Mathlib/Computability/Primrec/List.lean +++ b/Mathlib/Computability/Primrec/List.lean @@ -35,7 +35,7 @@ variable (H : Nat.Primrec fun n => Encodable.encode (@decode (List β) _ n)) open Primrec set_option backward.privateInPublic true in -@[implicit_reducible] +@[instance_reducible] private def prim : Primcodable (List β) := ⟨H⟩ private theorem list_casesOn' {f : α → List β} {g : α → σ} {h : α → β × List β → σ} @@ -608,7 +608,7 @@ end Nat namespace Nat.Primrec' -open List.Vector Primrec +open List.Vector theorem to_prim {n f} (pf : @Nat.Primrec' n f) : Primrec f := by induction pf with diff --git a/Mathlib/Computability/RE.lean b/Mathlib/Computability/RE.lean index 57421b1b04ab98..16aebb86bd055e 100644 --- a/Mathlib/Computability/RE.lean +++ b/Mathlib/Computability/RE.lean @@ -171,6 +171,7 @@ theorem ComputablePred.of_eq {α} [Primcodable α] {p q : α → Prop} (hp : Com namespace Computable +set_option backward.isDefEq.respectTransparency.types false in /-- If `P` is computable, and if for every `x` there exists an `n` such that `P x n` holds, then the function mapping `x` to the minimal such `n` (using `Nat.find`) is computable. This formally bridges `Partrec.rfind` with total unbounded search. -/ diff --git a/Mathlib/Computability/Reduce.lean b/Mathlib/Computability/Reduce.lean index c7f16ff4f494d8..57283d7201ffe4 100644 --- a/Mathlib/Computability/Reduce.lean +++ b/Mathlib/Computability/Reduce.lean @@ -369,10 +369,12 @@ instance instLE : LE ManyOneDegree := theorem of_le_of {p : α → Prop} {q : β → Prop} : of p ≤ of q ↔ p ≤₀ q := manyOneReducible_toNat_toNat +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in private theorem le_refl (d : ManyOneDegree) : d ≤ d := by induction d using ManyOneDegree.ind_on; simp; rfl +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in private theorem le_antisymm {d₁ d₂ : ManyOneDegree} : d₁ ≤ d₂ → d₂ ≤ d₁ → d₁ = d₂ := by induction d₁ using ManyOneDegree.ind_on @@ -417,6 +419,7 @@ theorem add_of (p : Set α) (q : Set β) : of (p ⊕' q) = of p + of q := (toNat_manyOneReducible.trans OneOneReducible.disjoin_left.to_many_one) (toNat_manyOneReducible.trans OneOneReducible.disjoin_right.to_many_one)⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] protected theorem add_le {d₁ d₂ d₃ : ManyOneDegree} : d₁ + d₂ ≤ d₃ ↔ d₁ ≤ d₃ ∧ d₂ ≤ d₃ := by induction d₁ using ManyOneDegree.ind_on diff --git a/Mathlib/Computability/TuringMachine/Config.lean b/Mathlib/Computability/TuringMachine/Config.lean index 71099a475e9c7f..7e3cbccc14e442 100644 --- a/Mathlib/Computability/TuringMachine/Config.lean +++ b/Mathlib/Computability/TuringMachine/Config.lean @@ -124,24 +124,30 @@ def Code.eval : Code → List ℕ →. List ℕ namespace Code +set_option backward.isDefEq.respectTransparency false in @[simp] theorem zero'_eval : zero'.eval = fun v => pure (0 :: v) := by simp [eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem succ_eval : succ.eval = fun v => pure [v.headI.succ] := by simp [eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem tail_eval : tail.eval = fun v => pure v.tail := by simp [eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem cons_eval (f fs) : (cons f fs).eval = fun v => do { let n ← Code.eval f v let ns ← Code.eval fs v pure (n.headI :: ns) } := by simp [eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem comp_eval (f g) : (comp f g).eval = fun v => g.eval v >>= f.eval := by simp [eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem case_eval (f g) : (case f g).eval = fun v => v.headI.rec (f.eval v.tail) fun y _ => g.eval (y::v.tail) := by @@ -237,6 +243,7 @@ def prec (f g : Code) : Code := attribute [-simp] Part.bind_eq_bind Part.map_eq_map Part.pure_eq_some +set_option backward.isDefEq.respectTransparency false in theorem exists_code.comp {m n} {f : List.Vector ℕ n →. ℕ} {g : Fin n → List.Vector ℕ m →. ℕ} (hf : ∃ c : Code, ∀ v : List.Vector ℕ n, c.eval v.1 = pure <$> f v) (hg : ∀ i, ∃ c : Code, ∀ v : List.Vector ℕ m, c.eval v.1 = pure <$> g i v) : @@ -517,6 +524,7 @@ def Cont.then : Cont → Cont → Cont | Cont.comp f k => fun k' => Cont.comp f (k.then k') | Cont.fix f k => fun k' => Cont.fix f (k.then k') +set_option backward.isDefEq.respectTransparency false in theorem Cont.then_eval {k k' : Cont} {v} : (k.then k').eval v = k.eval v >>= k'.eval := by induction k generalizing v with | halt => simp only [Cont.eval, Cont.then, pure_bind] @@ -664,6 +672,7 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : rw [stepRet, if_neg h] exact IH v₁.tail ((Part.mem_map_iff _).2 ⟨_, he₁, if_neg h⟩) +set_option backward.isDefEq.respectTransparency false in theorem code_is_ok (c) : Code.Ok c := by induction c with (intro k v; rw [stepNormal]) | cons f fs IHf IHfs => @@ -689,6 +698,7 @@ theorem code_is_ok (c) : Code.Ok c := by theorem stepNormal_eval (c v) : eval step (stepNormal c Cont.halt v) = Cfg.halt <$> c.eval v := (code_is_ok c).zero +set_option backward.isDefEq.respectTransparency false in theorem stepRet_eval {k v} : eval step (stepRet k v) = Cfg.halt <$> k.eval v := by induction k generalizing v with | halt => diff --git a/Mathlib/Computability/TuringMachine/StackTuringMachine.lean b/Mathlib/Computability/TuringMachine/StackTuringMachine.lean index b1d70fe140e99a..916694942a3bfe 100644 --- a/Mathlib/Computability/TuringMachine/StackTuringMachine.lean +++ b/Mathlib/Computability/TuringMachine/StackTuringMachine.lean @@ -383,10 +383,12 @@ theorem addBottom_nth_snd (L : ListBlank (∀ k, Option (Γ k))) (n : ℕ) : ((addBottom L).nth n).2 = L.nth n := by conv => rhs; rw [← addBottom_map L, ListBlank.nth_map] +set_option backward.isDefEq.respectTransparency false in theorem addBottom_nth_succ_fst (L : ListBlank (∀ k, Option (Γ k))) (n : ℕ) : ((addBottom L).nth (n + 1)).1 = false := by rw [ListBlank.nth_succ, addBottom, ListBlank.tail_cons, ListBlank.nth_map] +set_option backward.isDefEq.respectTransparency false in theorem addBottom_head_fst (L : ListBlank (∀ k, Option (Γ k))) : (addBottom L).head.1 = true := by rw [addBottom, ListBlank.head_cons] @@ -580,7 +582,7 @@ theorem tr_respects_aux₂ [DecidableEq K] {k : K} {q : TM1.Stmt (Γ' K Γ) (Λ' | pop f => rcases e : S k with - | ⟨hd, tl⟩ · simp only [Tape.mk'_head, ListBlank.head_cons, Tape.move_left_mk', List.length, - Tape.write_mk', List.head?, iterate_zero_apply, List.tail_nil] + List.head?, iterate_zero_apply, List.tail_nil] rw [← e, Function.update_eq_self] exact ⟨L, hL, by rw [addBottom_head_fst, cond]⟩ · refine @@ -704,6 +706,7 @@ theorem tr_respects : Respects (TM2.step M) (TM1.step (tr M)) TrCfg := by section variable [Inhabited Λ] [Inhabited σ] +set_option backward.isDefEq.respectTransparency false in theorem trCfg_init (k) (L : List (Γ k)) : TrCfg (TM2.init k L) (TM1.init (trInit k L) : TM1.Cfg (Γ' K Γ) (Λ' K Γ Λ σ) σ) := by rw [(_ : TM1.init _ = _)] diff --git a/Mathlib/Computability/TuringMachine/Tape.lean b/Mathlib/Computability/TuringMachine/Tape.lean index 22ad98a2f1fb51..6263e04e12114b 100644 --- a/Mathlib/Computability/TuringMachine/Tape.lean +++ b/Mathlib/Computability/TuringMachine/Tape.lean @@ -115,7 +115,7 @@ theorem BlankRel.equivalence (Γ) [Inhabited Γ] : Equivalence (@BlankRel Γ _) ⟨BlankRel.refl, @BlankRel.symm _ _, @BlankRel.trans _ _⟩ /-- Construct a setoid instance for `BlankRel`. -/ -@[implicit_reducible] +@[instance_reducible] def BlankRel.setoid (Γ) [Inhabited Γ] : Setoid (List Γ) := ⟨_, BlankRel.equivalence _⟩ diff --git a/Mathlib/Computability/TuringMachine/ToPartrec.lean b/Mathlib/Computability/TuringMachine/ToPartrec.lean index 161c480fb874ac..b4854519e3bd01 100644 --- a/Mathlib/Computability/TuringMachine/ToPartrec.lean +++ b/Mathlib/Computability/TuringMachine/ToPartrec.lean @@ -154,6 +154,7 @@ section open ToPartrec +set_option backward.isDefEq.respectTransparency false in /-- The alphabet for the stacks in the program. `bit0` and `bit1` are used to represent `ℕ` values as lists of binary digits, `cons` is used to separate `List ℕ` values, and `consₗ` is used to separate `List (List ℕ)` values. See the section documentation. -/ @@ -663,6 +664,7 @@ theorem clear_ok {p k q s L₁ o L₂} {S : K' → List Γ'} (e : splitAtPred p simp only [List.head?_cons, e₂, List.tail_cons, cond_false] convert! @IH _ (update S k Sk) _ using 2 <;> simp [e₃] +set_option backward.isDefEq.respectTransparency false in theorem copy_ok (q s a b c d) : Reaches₁ (TM2.step tr) ⟨some (Λ'.copy q), s, K'.elim a b c d⟩ ⟨some q, none, K'.elim (List.reverseAux b a) [] c (List.reverseAux b d)⟩ := by @@ -751,6 +753,7 @@ theorem head_stack_ok {q s L₁ L₂ L₃} : convert! unrev_ok using 2 simp [List.reverseAux_eq] +set_option backward.isDefEq.respectTransparency false in theorem succ_ok {q s n} {c d : List Γ'} : Reaches₁ (TM2.step tr) ⟨some (Λ'.succ q), s, K'.elim (trList [n]) [] c d⟩ ⟨some q, none, K'.elim (trList [n.succ]) [] c d⟩ := by @@ -787,6 +790,7 @@ theorem succ_ok {q s n} {c d : List Γ'} : elim_rev, elim_update_rev, Function.update_self, Option.mem_def, Option.some.injEq] rfl +set_option backward.isDefEq.respectTransparency false in theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s', Reaches₁ (TM2.step tr) ⟨some (Λ'.pred q₁ q₂), s, K'.elim (trList v) [] c d⟩ (v.headI.rec ⟨some q₁, s', K'.elim (trList v.tail) [] c d⟩ fun n _ => @@ -833,6 +837,7 @@ theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s', Option.getD, -natEnd] rfl +set_option backward.isDefEq.respectTransparency false in theorem trNormal_respects (c k v s) : ∃ b₂, TrCfg (stepNormal c k v) b₂ ∧ diff --git a/Mathlib/Condensed/Discrete/Colimit.lean b/Mathlib/Condensed/Discrete/Colimit.lean index 789a1ec6e5c50d..7579e7ecc282d2 100644 --- a/Mathlib/Condensed/Discrete/Colimit.lean +++ b/Mathlib/Condensed/Discrete/Colimit.lean @@ -37,6 +37,11 @@ variable {I : Type u} [Category.{u} I] [IsCofiltered I] {F : I ⥤ FintypeCat.{u abbrev locallyConstantPresheaf : Profinite.{u}ᵒᵖ ⥤ Type (u + 1) := CompHausLike.LocallyConstant.functorToPresheaves.{u, u + 1}.obj X +#adaptation_note +/-- +In this declaration and `isColimitLocallyConstantPresheaf`, `coe_comp` interferes with rewriting via +`Cone.w`, so we needed to manualy exclude it. +-/ set_option backward.defeqAttrib.useBackward true in /-- The functor `locallyConstantPresheaf` takes cofiltered limits of finite sets with surjective @@ -59,10 +64,10 @@ noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi change fi ((c.π.app k ≫ (F ⋙ toProfinite).map _) x) = fj ((c.π.app k ≫ (F ⋙ toProfinite).map _) x) have h := LocallyConstant.congr_fun h x - dsimp + dsimp [- CompHausLike.coe_comp] -- `coe_comp` prevents rewriting with `c.w` rwa [dsimp% c.w, dsimp% c.w] -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi (c.π.app i)] (s : Cocone ((F ⋙ toProfinite).op ⋙ locallyConstantPresheaf X)) @@ -72,7 +77,6 @@ lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi ( change ((((locallyConstantPresheaf X).mapCocone c.op).ι.app ⟨i⟩) ≫ (isColimitLocallyConstantPresheaf c X hc).desc s) _ = _ rw [(isColimitLocallyConstantPresheaf c X hc).fac] - rfl /-- `isColimitLocallyConstantPresheaf` in the case of `S.asLimit`. -/ noncomputable def isColimitLocallyConstantPresheafDiagram (S : Profinite) : @@ -130,6 +134,7 @@ variable {S : Profinite.{u}} {F : Profinite.{u}ᵒᵖ ⥤ Type (u + 1)} instance : Final <| Profinite.Extend.functorOp S.asLimitCone := Profinite.Extend.functorOp_final S.asLimitCone S.asLimit +set_option backward.isDefEq.respectTransparency.types false in /-- A presheaf, which takes a profinite set written as a cofiltered limit to the corresponding colimit, agrees with the left Kan extension of its restriction. @@ -153,6 +158,7 @@ def lanPresheafNatIso (hF : ∀ S : Profinite, IsColimit <| F.mapCocone S.asLimi NatIso.ofComponents (fun ⟨S⟩ ↦ (lanPresheafIso (hF S))) fun _ ↦ (by simpa using colimit.hom_ext fun _ ↦ (by simp)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lanPresheafNatIso_hom_app (hF : ∀ S : Profinite, IsColimit <| F.mapCocone S.asLimitCone.op) (S : Profiniteᵒᵖ) : (lanPresheafNatIso hF).hom.app S = @@ -247,6 +253,7 @@ lemma isoFinYonedaComponents_inv_comp {X Y : Profinite.{u}} [Finite X] [Finite Y attribute [local simp] toProfinite_obj +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The restriction of a finite-product-preserving presheaf `F` on `Profinite` to the category of @@ -347,10 +354,10 @@ noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi change fi ((c.π.app k ≫ (F ⋙ toLightProfinite).map _) x) = fj ((c.π.app k ≫ (F ⋙ toLightProfinite).map _) x) have h := LocallyConstant.congr_fun h x - dsimp + dsimp [- CompHausLike.coe_comp] -- `coe_comp` prevents rewriting with `c.w` rwa [dsimp% c.w, dsimp% c.w] -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi (c.π.app i)] (s : Cocone ((F ⋙ toLightProfinite).op ⋙ locallyConstantPresheaf X)) @@ -360,7 +367,6 @@ lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi ( change ((((locallyConstantPresheaf X).mapCocone c.op).ι.app ⟨n⟩) ≫ (isColimitLocallyConstantPresheaf c X hc).desc s) _ = _ rw [(isColimitLocallyConstantPresheaf c X hc).fac] - rfl /-- `isColimitLocallyConstantPresheaf` in the case of `S.asLimit`. -/ noncomputable def isColimitLocallyConstantPresheafDiagram (S : LightProfinite) : @@ -368,7 +374,7 @@ noncomputable def isColimitLocallyConstantPresheafDiagram (S : LightProfinite) : (Functor.Final.isColimitWhiskerEquiv (opOpEquivalence ℕ).inverse _).symm (isColimitLocallyConstantPresheaf _ _ S.asLimit) -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma isColimitLocallyConstantPresheafDiagram_desc_apply (S : LightProfinite) (s : Cocone (S.diagram.rightOp ⋙ locallyConstantPresheaf X)) @@ -378,7 +384,6 @@ lemma isColimitLocallyConstantPresheafDiagram_desc_apply (S : LightProfinite) change ((((locallyConstantPresheaf X).mapCocone (coconeRightOpOfCone S.asLimitCone)).ι.app n) ≫ (isColimitLocallyConstantPresheafDiagram X S).desc s) _ = _ rw [(isColimitLocallyConstantPresheafDiagram X S).fac] - rfl end LocallyConstantAsColimit @@ -427,6 +432,7 @@ variable {S : LightProfinite.{u}} {F : LightProfinite.{u}ᵒᵖ ⥤ Type u} instance : Final <| LightProfinite.Extend.functorOp S.asLimitCone := LightProfinite.Extend.functorOp_final S.asLimitCone S.asLimit +set_option backward.isDefEq.respectTransparency.types false in /-- A presheaf, which takes a light profinite set written as a sequential limit to the corresponding colimit, agrees with the left Kan extension of its restriction. @@ -454,6 +460,7 @@ def lanPresheafNatIso lanPresheafIso_hom, Opposite.op_unop] exact colimit.hom_ext fun _ ↦ (by simp) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lanPresheafNatIso_hom_app (hF : ∀ S : LightProfinite, IsColimit <| F.mapCocone (coconeRightOpOfCone S.asLimitCone)) @@ -539,6 +546,7 @@ lemma isoFinYonedaComponents_inv_comp {X Y : LightProfinite.{u}} [Finite X] [Fin attribute [local simp] toLightProfinite_obj +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The restriction of a finite-product-preserving presheaf `F` on `Profinite` to the category of diff --git a/Mathlib/Condensed/Discrete/LocallyConstant.lean b/Mathlib/Condensed/Discrete/LocallyConstant.lean index 243892767a9913..e30e86dab9c30e 100644 --- a/Mathlib/Condensed/Discrete/LocallyConstant.lean +++ b/Mathlib/Condensed/Discrete/LocallyConstant.lean @@ -201,6 +201,7 @@ lemma incl_comap {S T : (CompHausLike P)ᵒᵖ} (sigmaIncl f _).op ≫ (componentHom f g.unop a).op := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The counit is natural in `S : CompHausLike P` -/ @[simps! app] @@ -311,6 +312,7 @@ noncomputable def unitIso : 𝟭 (Type (max u w)) ≅ functor.{u, w} P hs ⋙ hom := unit P hs inv := { app _ := ↾fun f ↦ f.toFun PUnit.unit } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma adjunction_left_triangle [HasExplicitFiniteCoproducts.{u} P] (X : Type (max u w)) : functorToPresheaves.{u, w}.map ((unit P hs).app X) ≫ @@ -334,6 +336,7 @@ lemma adjunction_left_triangle [HasExplicitFiniteCoproducts.{u} P] erw [← map_eq_image _ a x] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `CompHausLike.LocallyConstant.functor` is left adjoint to the forgetful functor. -/ diff --git a/Mathlib/Condensed/Light/Functors.lean b/Mathlib/Condensed/Light/Functors.lean index 89af9f8e80c9ab..33e8b2d440f636 100644 --- a/Mathlib/Condensed/Light/Functors.lean +++ b/Mathlib/Condensed/Light/Functors.lean @@ -48,6 +48,7 @@ instance : lightProfiniteToLightCondSet.Full := instance : lightProfiniteToLightCondSet.Faithful := inferInstanceAs ((coherentTopology LightProfinite).yoneda).Faithful +set_option backward.isDefEq.respectTransparency.types false in /-- The functor from `LightProfinite` to `LightCondSet` factors through `TopCat`. -/ diff --git a/Mathlib/Condensed/Light/InternallyProjective.lean b/Mathlib/Condensed/Light/InternallyProjective.lean index cd447dc9d07552..91b0b495e70836 100644 --- a/Mathlib/Condensed/Light/InternallyProjective.lean +++ b/Mathlib/Condensed/Light/InternallyProjective.lean @@ -157,7 +157,6 @@ lemma internallyProjective_iff_tensor_condition' (P : LightCondMod R) : Internal refine ⟨S', π, hπ, (β_ _ _).hom ≫ g', ?_⟩ simp [← hh] -set_option backward.isDefEq.respectTransparency false in /-- Given a `P : LightCondSet`, the light free light condensed module `R[P]` is internally projective if and only if, for all `A B : LightCondMod R`, for all epimorphisms `e : A ⟶ B`, for all diff --git a/Mathlib/Condensed/Light/Small.lean b/Mathlib/Condensed/Light/Small.lean index d76fa6a788764a..bcb82788ab4460 100644 --- a/Mathlib/Condensed/Light/Small.lean +++ b/Mathlib/Condensed/Light/Small.lean @@ -39,6 +39,7 @@ instance (X Y : LightCondensed.{u} C) : Small.{max u v} (X ⟶ Y) where ⟨(equivSmall C).functor.obj X ⟶ (equivSmall C).functor.obj Y, ⟨(equivSmall C).fullyFaithfulFunctor.homEquiv⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Sheafifying is preserved under conjugating with the equivalence between light condensed objects diff --git a/Mathlib/Condensed/Light/TopCatAdjunction.lean b/Mathlib/Condensed/Light/TopCatAdjunction.lean index af443af3c6f7c4..729cc4bed72ad9 100644 --- a/Mathlib/Condensed/Light/TopCatAdjunction.lean +++ b/Mathlib/Condensed/Light/TopCatAdjunction.lean @@ -81,6 +81,7 @@ def _root_.lightCondSetToTopCat : LightCondSet.{u} ⥤ TopCat.{u} where obj X := X.toTopCat map f := toTopCatMap f +set_option backward.isDefEq.respectTransparency.types false in /-- The counit of the adjunction `lightCondSetToTopCat ⊣ topCatToLightCondSet` -/ noncomputable def topCatAdjunctionCounit (X : TopCat.{u}) : X.toLightCondSet.toTopCat ⟶ X := TopCat.ofHom @@ -89,6 +90,7 @@ noncomputable def topCatAdjunctionCounit (X : TopCat.{u}) : X.toLightCondSet.toT rw [continuous_coinduced_dom] continuity } +set_option backward.isDefEq.respectTransparency.types false in /-- The counit of the adjunction `lightCondSetToTopCat ⊣ topCatToLightCondSet` is always bijective, but not an isomorphism in general (the inverse isn't continuous unless `X` is sequential). -/ @@ -100,6 +102,7 @@ lemma topCatAdjunctionCounit_bijective (X : TopCat.{u}) : Function.Bijective (topCatAdjunctionCounit X) := (topCatAdjunctionCounitEquiv X).bijective +set_option backward.isDefEq.respectTransparency.types false in /-- The unit of the adjunction `lightCondSetToTopCat ⊣ topCatToLightCondSet` -/ @[simps hom_app] noncomputable def topCatAdjunctionUnit (X : LightCondSet.{u}) : X ⟶ X.toTopCat.toLightCondSet where @@ -129,6 +132,7 @@ noncomputable def topCatAdjunction : lightCondSetToTopCat.{u} ⊣ topCatToLightC change Y.obj.map (𝟙 _) _ = _ simp +set_option backward.isDefEq.respectTransparency.types false in instance (X : TopCat) : Epi (topCatAdjunction.counit.app X) := by rw [TopCat.epi_iff_surjective] exact (topCatAdjunctionCounit_bijective _).2 diff --git a/Mathlib/Condensed/TopCatAdjunction.lean b/Mathlib/Condensed/TopCatAdjunction.lean index bff73e2c99cbb5..e5935ba3873401 100644 --- a/Mathlib/Condensed/TopCatAdjunction.lean +++ b/Mathlib/Condensed/TopCatAdjunction.lean @@ -82,6 +82,7 @@ def condensedSetToTopCat : CondensedSet.{u} ⥤ TopCat.{u + 1} where namespace CondensedSet +set_option backward.isDefEq.respectTransparency.types false in /-- The counit of the adjunction `condensedSetToTopCat ⊣ topCatToCondensedSet` -/ noncomputable def topCatAdjunctionCounit (X : TopCat.{u + 1}) : X.toCondensedSet.toTopCat ⟶ X := TopCat.ofHom @@ -90,6 +91,7 @@ noncomputable def topCatAdjunctionCounit (X : TopCat.{u + 1}) : X.toCondensedSet rw [continuous_coinduced_dom] continuity } +set_option backward.isDefEq.respectTransparency.types false in /-- `simp`-normal form of the lemma that `@[simps]` would generate. -/ @[simp] lemma topCatAdjunctionCounit_hom_apply (X : TopCat) (x) : -- We have to specify here to not infer the `TopologicalSpace` instance on `C(PUnit, X)`, @@ -98,6 +100,7 @@ noncomputable def topCatAdjunctionCounit (X : TopCat.{u + 1}) : X.toCondensedSet (TopCat.Hom.hom (topCatAdjunctionCounit X)) x = x PUnit.unit := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The counit of the adjunction `condensedSetToTopCat ⊣ topCatToCondensedSet` is always bijective, but not an isomorphism in general (the inverse isn't continuous unless `X` is compactly generated). -/ @@ -110,6 +113,7 @@ lemma topCatAdjunctionCounit_bijective (X : TopCat.{u + 1}) : Function.Bijective (topCatAdjunctionCounit X) := (topCatAdjunctionCounitEquiv X).bijective +set_option backward.isDefEq.respectTransparency.types false in /-- The unit of the adjunction `condensedSetToTopCat ⊣ topCatToCondensedSet` -/ @[simps hom_app] noncomputable def topCatAdjunctionUnit (X : CondensedSet.{u}) : X ⟶ X.toTopCat.toCondensedSet where @@ -139,6 +143,7 @@ noncomputable def topCatAdjunction : condensedSetToTopCat.{u} ⊣ topCatToConden change Y.obj.map (𝟙 _) _ = _ simp +set_option backward.isDefEq.respectTransparency.types false in instance (X : TopCat) : Epi (topCatAdjunction.counit.app X) := by rw [TopCat.epi_iff_surjective] exact (topCatAdjunctionCounit_bijective _).2 diff --git a/Mathlib/Control/Applicative.lean b/Mathlib/Control/Applicative.lean index e2441e2eeb7c3d..344c7abf37345a 100644 --- a/Mathlib/Control/Applicative.lean +++ b/Mathlib/Control/Applicative.lean @@ -120,6 +120,7 @@ theorem applicative_comp_id {F} [AF : Applicative F] [LawfulApplicative F] : open CommApplicative +set_option backward.isDefEq.respectTransparency false in instance {f : Type u → Type w} {g : Type v → Type u} [Applicative f] [Applicative g] [CommApplicative f] [CommApplicative g] : CommApplicative (Comp f g) where commutative_prod _ _ := by @@ -152,6 +153,7 @@ instance {α} [One α] [Mul α] : Applicative (Const α) where -- Porting note: `(· <*> ·)` needed to change to `Seq.seq` in the `simp`. -- Also, `simp` didn't close `refl` goals. +set_option backward.isDefEq.respectTransparency false in instance {α} [Monoid α] : LawfulApplicative (Const α) where map_pure _ _ := rfl seq_pure _ _ := by simp [Const.map, map, Seq.seq, pure, mul_one] @@ -164,6 +166,7 @@ instance {α} [Zero α] [Add α] : Applicative (AddConst α) where pure _ := (0 : α) seq f x := (show α from f) + (show α from x Unit.unit) +set_option backward.isDefEq.respectTransparency false in instance {α} [AddMonoid α] : LawfulApplicative (AddConst α) where map_pure _ _ := rfl seq_pure _ _ := by simp [Const.map, map, Seq.seq, pure, add_zero] diff --git a/Mathlib/Control/Bifunctor.lean b/Mathlib/Control/Bifunctor.lean index 3082728a59b19c..b23610b989ced6 100644 --- a/Mathlib/Control/Bifunctor.lean +++ b/Mathlib/Control/Bifunctor.lean @@ -114,6 +114,7 @@ instance LawfulBifunctor.const : LawfulBifunctor Const where instance Bifunctor.flip : Bifunctor (flip F) where bimap {_α α' _β β'} f f' x := (bimap f' f x : F β' α') +set_option backward.isDefEq.respectTransparency false in instance LawfulBifunctor.flip [LawfulBifunctor F] : LawfulBifunctor (flip F) where id_bimap := by simp [bimap, functor_norm] bimap_bimap := by simp [bimap, functor_norm] @@ -141,6 +142,7 @@ variable (G : Type* → Type u₀) (H : Type* → Type u₁) [Functor G] [Functo instance Function.bicompl.bifunctor : Bifunctor (bicompl F G H) where bimap {_α α' _β β'} f f' x := (bimap (map f) (map f') x : F (G α') (H β')) +set_option backward.isDefEq.respectTransparency false in instance Function.bicompl.lawfulBifunctor [LawfulFunctor G] [LawfulFunctor H] [LawfulBifunctor F] : LawfulBifunctor (bicompl F G H) := by constructor <;> intros <;> simp [bimap, map_id, map_comp_map, functor_norm] @@ -154,6 +156,7 @@ variable (G : Type u₂ → Type*) [Functor G] instance Function.bicompr.bifunctor : Bifunctor (bicompr G F) where bimap {_α α' _β β'} f f' x := (map (bimap f f') x : G (F α' β')) +set_option backward.isDefEq.respectTransparency false in instance Function.bicompr.lawfulBifunctor [LawfulFunctor G] [LawfulBifunctor F] : LawfulBifunctor (bicompr G F) := by constructor <;> intros <;> simp [bimap, functor_norm] diff --git a/Mathlib/Control/EquivFunctor.lean b/Mathlib/Control/EquivFunctor.lean index 2f8a214334db27..0700a48ebb99db 100644 --- a/Mathlib/Control/EquivFunctor.lean +++ b/Mathlib/Control/EquivFunctor.lean @@ -72,6 +72,7 @@ theorem mapEquiv_refl (α) : mapEquiv f (Equiv.refl α) = Equiv.refl (f α) := b theorem mapEquiv_symm : (mapEquiv f e).symm = mapEquiv f e.symm := Equiv.ext <| mapEquiv_symm_apply f e +set_option backward.isDefEq.respectTransparency false in /-- The composition of `mapEquiv`s is carried over the `EquivFunctor`. For plain `Functor`s, this lemma is named `map_map` when applied or `map_comp_map` when not applied. diff --git a/Mathlib/Control/Fold.lean b/Mathlib/Control/Fold.lean index 13a306db3fc76f..8bdf8e17fddb73 100644 --- a/Mathlib/Control/Fold.lean +++ b/Mathlib/Control/Fold.lean @@ -234,6 +234,7 @@ variable {α β γ : Type u} open Function hiding const +set_option backward.isDefEq.respectTransparency.types false in def mapFold [Monoid α] [Monoid β] (f : α →* β) : ApplicativeTransformation (Const α) (Const β) where app _ := f preserves_seq' := by intros; simp only [Seq.seq, map_mul] @@ -286,6 +287,7 @@ theorem foldr.ofFreeMonoid_comp_of (f : β → α → α) : Foldr.ofFreeMonoid f ∘ FreeMonoid.of = Foldr.mk ∘ f := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem foldlm.ofFreeMonoid_comp_of {m} [Monad m] [LawfulMonad m] (f : α → β → m α) : foldlM.ofFreeMonoid f ∘ FreeMonoid.of = foldlM.mk ∘ flip f := by @@ -295,6 +297,7 @@ theorem foldlm.ofFreeMonoid_comp_of {m} [Monad m] [LawfulMonad m] (f : α → β foldlM.mk, op_inj] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem foldrm.ofFreeMonoid_comp_of {m} [Monad m] [LawfulMonad m] (f : β → α → m α) : foldrM.ofFreeMonoid f ∘ FreeMonoid.of = foldrM.mk ∘ f := by @@ -317,6 +320,7 @@ theorem toList_spec (xs : t α) : toList xs = FreeMonoid.toList (foldMap FreeMon simp only [toList, foldl, Foldl.get, foldl.ofFreeMonoid_comp_of, Function.comp_apply] +set_option backward.isDefEq.respectTransparency.types false in theorem foldMap_map [Monoid γ] (f : α → β) (g : β → γ) (xs : t α) : foldMap g (f <$> xs) = foldMap (g ∘ f) xs := by simp only [foldMap, traverse_map, Function.comp_def] diff --git a/Mathlib/Control/Functor.lean b/Mathlib/Control/Functor.lean index f428d9e905aa0c..59d944a66186ec 100644 --- a/Mathlib/Control/Functor.lean +++ b/Mathlib/Control/Functor.lean @@ -173,9 +173,11 @@ protected theorem run_map {α β} (h : α → β) (x : Comp F G α) : variable [LawfulFunctor F] [LawfulFunctor G] variable {α β γ : Type v} +set_option backward.isDefEq.respectTransparency false in protected theorem id_map : ∀ x : Comp F G α, Comp.map id x = x | Comp.mk x => by simp only [Comp.map, id_map, id_map']; rfl +set_option backward.isDefEq.respectTransparency false in protected theorem comp_map (g' : α → β) (h : β → γ) : ∀ x : Comp F G α, Comp.map (h ∘ g') x = Comp.map h (Comp.map g' x) | Comp.mk x => by simp [Comp.map, Comp.mk, functor_norm, Function.comp_def] diff --git a/Mathlib/Control/Functor/Multivariate.lean b/Mathlib/Control/Functor/Multivariate.lean index 493f39fa6c8857..e0cf9fa0535114 100644 --- a/Mathlib/Control/Functor/Multivariate.lean +++ b/Mathlib/Control/Functor/Multivariate.lean @@ -121,9 +121,11 @@ theorem exists_iff_exists_of_mono {P : F α → Prop} {q : F β → Prop} rw [h₁] simp only [MvFunctor.map_map, h₀, LawfulMvFunctor.id_map, h₂] +set_option backward.isDefEq.respectTransparency false in theorem LiftP_def (x : F α) : LiftP' P x ↔ ∃ u : F (Subtype_ P), subtypeVal P <$$> u = x := exists_iff_exists_of_mono F _ _ (toSubtype_of_subtype P) (by simp [MvFunctor.map_map]) +set_option backward.isDefEq.respectTransparency false in theorem LiftR_def (x y : F α) : LiftR' R x y ↔ ∃ u : F (Subtype_ R), @@ -154,6 +156,7 @@ private def f : ⟨x.val, cast (by grind [PredLast]) x.property⟩ | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ +set_option backward.isDefEq.respectTransparency false in private def g : ∀ n α, (fun i : Fin2 (n + 1) => { p_1 : (α ::: β) i // PredLast α pp p_1 }) ⟹ fun i : Fin2 (n + 1) => @@ -162,6 +165,7 @@ private def g : ⟨x.val, cast (by simp only [PredLast]; erw [const_iff_true]) x.property⟩ | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ +set_option backward.isDefEq.respectTransparency false in theorem LiftP_PredLast_iff {β} (P : β → Prop) (x : F (α ::: β)) : LiftP' (PredLast' _ P) x ↔ LiftP (PredLast _ P) x := by dsimp only [LiftP, LiftP'] @@ -197,6 +201,7 @@ private def g' : ⟨x.val, cast (by simp only [RelLast]; erw [repeatEq_iff_eq]) x.property⟩ | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ +set_option backward.isDefEq.respectTransparency false in theorem LiftR_RelLast_iff (x y : F (α ::: β)) : LiftR' (RelLast' _ rr) x y ↔ LiftR (RelLast _ rr) x y := by dsimp only [LiftR, LiftR'] @@ -211,7 +216,7 @@ theorem LiftR_RelLast_iff (x y : F (α ::: β)) : end LiftPLastPredIff /-- Any type function that is (extensionally) equivalent to a functor, is itself a functor -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv {F F' : TypeVec.{u} n → Type*} [MvFunctor F'] (eqv : ∀ α, F α ≃ F' α) : MvFunctor F where map f x := (eqv _).symm <| f <$$> eqv _ x diff --git a/Mathlib/Control/LawfulFix.lean b/Mathlib/Control/LawfulFix.lean index 50d9cce922d7ac..b317ee778a5774 100644 --- a/Mathlib/Control/LawfulFix.lean +++ b/Mathlib/Control/LawfulFix.lean @@ -113,7 +113,7 @@ theorem approx_mem_approxChain {i} : approx f i ∈ approxChain f := end Fix -open Fix +open Part.Fix variable {α : Type*} variable (f : ((a : _) → Part <| β a) →o (a : _) → Part <| β a) diff --git a/Mathlib/Control/Monad/Writer.lean b/Mathlib/Control/Monad/Writer.lean index bf1fa7e748b7b7..8a879a7109098a 100644 --- a/Mathlib/Control/Monad/Writer.lean +++ b/Mathlib/Control/Monad/Writer.lean @@ -110,7 +110,7 @@ theorem run_bind (empty : ω) (append : ω → ω → ω) rfl /-- Lift an `M` to a `WriterT ω M`, using the given `empty` as the monoid unit. -/ -@[inline, implicit_reducible] +@[inline, instance_reducible] protected def liftTell (empty : ω) : MonadLift M (WriterT ω M) where monadLift := fun cmd ↦ WriterT.mk <| (fun a ↦ (a, empty)) <$> cmd diff --git a/Mathlib/Control/Traversable/Equiv.lean b/Mathlib/Control/Traversable/Equiv.lean index bd4e588afce6ab..1f6550e5e8f7a7 100644 --- a/Mathlib/Control/Traversable/Equiv.lean +++ b/Mathlib/Control/Traversable/Equiv.lean @@ -50,7 +50,7 @@ protected def map {α β : Type u} (f : α → β) (x : t' α) : t' β := /-- The function `Equiv.map` transfers the functoriality of `t` to `t'` using the equivalences `eqv`. -/ -@[implicit_reducible] +@[instance_reducible] protected def functor : Functor t' where map := Equiv.map eqv variable [LawfulFunctor t] @@ -103,7 +103,7 @@ theorem traverse_def (f : α → m β) (x : t' α) : /-- The function `Equiv.traverse` transfers a traversable functor instance across the equivalences `eqv`. -/ -@[implicit_reducible] +@[instance_reducible] protected def traversable : Traversable t' where toFunctor := Equiv.functor eqv traverse := Equiv.traverse eqv diff --git a/Mathlib/Control/ULiftable.lean b/Mathlib/Control/ULiftable.lean index 95571f205712d2..c08919f44a86fd 100644 --- a/Mathlib/Control/ULiftable.lean +++ b/Mathlib/Control/ULiftable.lean @@ -121,7 +121,7 @@ instance instULiftableId : ULiftable Id Id where congr F := F /-- for specific state types, this function helps to create a uliftable instance -/ -@[implicit_reducible] +@[instance_reducible] def StateT.uliftable' {m : Type u₀ → Type v₀} {m' : Type u₁ → Type v₁} [ULiftable m m'] (F : s ≃ s') : ULiftable (StateT s m) (StateT s' m') where congr G := @@ -135,7 +135,7 @@ instance StateT.instULiftableULiftULift {m m'} [ULiftable m m'] : StateT.uliftable' <| Equiv.ulift.trans Equiv.ulift.symm /-- for specific reader monads, this function helps to create a uliftable instance -/ -@[implicit_reducible] +@[instance_reducible] def ReaderT.uliftable' {m m'} [ULiftable m m'] (F : s ≃ s') : ULiftable (ReaderT s m) (ReaderT s' m') where congr G := ReaderT.equiv <| Equiv.piCongr F fun _ => ULiftable.congr G @@ -148,7 +148,7 @@ instance ReaderT.instULiftableULiftULift {m m'} [ULiftable m m'] : ReaderT.uliftable' <| Equiv.ulift.trans Equiv.ulift.symm /-- for specific continuation passing monads, this function helps to create a uliftable instance -/ -@[implicit_reducible] +@[instance_reducible] def ContT.uliftable' {m m'} [ULiftable m m'] (F : r ≃ r') : ULiftable (ContT r m) (ContT r' m') where congr := ContT.equiv (ULiftable.congr F) @@ -161,7 +161,7 @@ instance ContT.instULiftableULiftULift {m m'} [ULiftable m m'] : ContT.uliftable' <| Equiv.ulift.trans Equiv.ulift.symm /-- for specific writer monads, this function helps to create a uliftable instance -/ -@[implicit_reducible] +@[instance_reducible] def WriterT.uliftable' {m m'} [ULiftable m m'] (F : w ≃ w') : ULiftable (WriterT w m) (WriterT w' m') where congr G := WriterT.equiv <| ULiftable.congr <| Equiv.prodCongr G F diff --git a/Mathlib/Data/Analysis/Filter.lean b/Mathlib/Data/Analysis/Filter.lean index f3c51a4bcfeff2..a910e67c688d7b 100644 --- a/Mathlib/Data/Analysis/Filter.lean +++ b/Mathlib/Data/Analysis/Filter.lean @@ -214,6 +214,7 @@ protected def comap (m : α → β) {f : Filter β} (F : f.Realizer) : (comap m exact ⟨fun ⟨s, h⟩ ↦ ⟨_, ⟨s, Subset.refl _⟩, h⟩, fun ⟨_, ⟨s, h⟩, h₂⟩ ↦ ⟨s, Subset.trans (preimage_mono h) h₂⟩⟩⟩ +set_option backward.isDefEq.respectTransparency false in /-- Construct a realizer for the sup of two filters -/ protected def sup {f g : Filter α} (F : f.Realizer) (G : g.Realizer) : (f ⊔ g).Realizer := ⟨F.σ × G.σ, @@ -242,6 +243,7 @@ protected def inf {f g : Filter α} (F : f.Realizer) (G : g.Realizer) : (f ⊓ g · rintro ⟨_, ⟨a, ha⟩, _, ⟨b, hb⟩, rfl⟩ exact ⟨a, b, inter_subset_inter ha hb⟩⟩ +set_option backward.isDefEq.respectTransparency false in /-- Construct a realizer for the cofinite filter -/ protected def cofinite [DecidableEq α] : (@cofinite α).Realizer := ⟨Finset α, diff --git a/Mathlib/Data/Analysis/Topology.lean b/Mathlib/Data/Analysis/Topology.lean index bb9c59b9a76c52..bda10b905e4496 100644 --- a/Mathlib/Data/Analysis/Topology.lean +++ b/Mathlib/Data/Analysis/Topology.lean @@ -80,7 +80,7 @@ theorem ofEquiv_val (E : σ ≃ τ) (F : Ctop α σ) (a : τ) : F.ofEquiv E a = end /-- Every `Ctop` is a topological space. -/ -@[implicit_reducible] +@[instance_reducible] def toTopsp (F : Ctop α σ) : TopologicalSpace α := TopologicalSpace.generateFrom (Set.range F.f) theorem toTopsp_isTopologicalBasis (F : Ctop α σ) : diff --git a/Mathlib/Data/Complex/Basic.lean b/Mathlib/Data/Complex/Basic.lean index 12f58340718e32..751a401d26700f 100644 --- a/Mathlib/Data/Complex/Basic.lean +++ b/Mathlib/Data/Complex/Basic.lean @@ -78,7 +78,7 @@ theorem range_im : range im = univ := im_surjective.range_eq /-- The natural inclusion of the real numbers into the complex numbers. -/ -@[coe, implicit_reducible] +@[coe, instance_reducible] def ofReal (r : ℝ) : ℂ := ⟨r, 0⟩ instance : Coe ℝ ℂ := @@ -271,6 +271,7 @@ theorem I_mul_re (z : ℂ) : (I * z).re = -z.im := by simp theorem I_mul_im (z : ℂ) : (I * z).im = z.re := by simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem equivRealProd_symm_apply (p : ℝ × ℝ) : equivRealProd.symm p = p.1 + p.2 * I := by ext <;> simp [Complex.equivRealProd, ofReal] @@ -304,7 +305,7 @@ scoped instance instSMulRealComplex {R : Type*} [SMul R ℝ] : SMul R ℂ where end SMul -open scoped SMul +open scoped Complex.SMul section SMul @@ -588,7 +589,7 @@ theorem add_conj (z : ℂ) : z + conj z = (2 * z.re : ℝ) := Complex.ext_iff.2 <| by simp [two_mul, ofReal] /-- The coercion `ℝ → ℂ` as a `RingHom`. -/ -@[implicit_reducible] +@[instance_reducible] def ofRealHom : ℝ →+* ℂ where toFun x := (x : ℂ) map_one' := ofReal_one diff --git a/Mathlib/Data/DFinsupp/BigOperators.lean b/Mathlib/Data/DFinsupp/BigOperators.lean index 1bd602a76093f9..d367aacfd43097 100644 --- a/Mathlib/Data/DFinsupp/BigOperators.lean +++ b/Mathlib/Data/DFinsupp/BigOperators.lean @@ -285,6 +285,7 @@ theorem sumZeroHom_single [∀ i, Zero (β i)] [AddCommMonoid γ] (φ : ∀ i, Z dsimp [sumZeroHom, single, Trunc.lift_mk] rw [Multiset.toFinset_singleton, Finset.sum_singleton, Pi.single_eq_same] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem sumZeroHom_piSingle [∀ i, Zero (β i)] [AddCommMonoid γ] (i) (φ : ZeroHom (β i) γ) : sumZeroHom (Pi.single i φ) = φ.comp { toFun := (· i), map_zero' := rfl } := by @@ -308,6 +309,7 @@ theorem sumZeroHom_apply [∀ i, AddZeroClass (β i)] [∀ (i) (x : β i), Decid · rfl · rw [not_not.mp h, map_zero] +set_option backward.isDefEq.respectTransparency false in /-- When summing over an `AddMonoidHom`, the decidability assumption is not needed, and the result is also an `AddMonoidHom`. diff --git a/Mathlib/Data/DFinsupp/Defs.lean b/Mathlib/Data/DFinsupp/Defs.lean index eeb6c9478f63da..849a45ceefdb56 100644 --- a/Mathlib/Data/DFinsupp/Defs.lean +++ b/Mathlib/Data/DFinsupp/Defs.lean @@ -926,6 +926,7 @@ theorem mapRange_injective (f : ∀ i, β₁ i → β₂ i) (hf : ∀ i, f i 0 = classical exact ⟨fun h i x y eq ↦ single_injective (@h (single i x) (single i y) <| by simpa using congr_arg _ eq), fun h _ _ eq ↦ DFinsupp.ext fun i ↦ h i congr($eq i)⟩ +set_option backward.isDefEq.respectTransparency false in omit [DecidableEq ι] in theorem mapRange_surjective (f : ∀ i, β₁ i → β₂ i) (hf : ∀ i, f i 0 = 0) : Function.Surjective (mapRange f hf) ↔ ∀ i, Function.Surjective (f i) := by @@ -1104,6 +1105,7 @@ theorem comapDomain'_single [DecidableEq ι] [DecidableEq κ] [∀ i, Zero (β i comapDomain' h hh' (single (h k) x) = single k x := by grind +set_option backward.isDefEq.respectTransparency false in /-- Reindexing terms of a dfinsupp. This is the dfinsupp version of `Equiv.piCongrLeft'`. -/ diff --git a/Mathlib/Data/DFinsupp/Lex.lean b/Mathlib/Data/DFinsupp/Lex.lean index ba2d11f0f070ae..3f40309df9b05d 100644 --- a/Mathlib/Data/DFinsupp/Lex.lean +++ b/Mathlib/Data/DFinsupp/Lex.lean @@ -50,10 +50,12 @@ instance [LT ι] [∀ i, LT (α i)] : LT (Lex (Π₀ i, α i)) := instance [LT ι] [∀ i, LT (α i)] : LT (Colex (Π₀ i, α i)) := ⟨fun f g ↦ DFinsupp.Lex (· > ·) (fun _ ↦ (· < ·)) (ofColex f) (ofColex g)⟩ +set_option backward.isDefEq.respectTransparency false in theorem Lex.lt_iff [LT ι] [∀ i, LT (α i)] {a b : Lex (Π₀ i, α i)} : a < b ↔ ∃ i, (∀ j, j < i → a j = b j) ∧ a i < b i := .rfl +set_option backward.isDefEq.respectTransparency false in theorem Colex.lt_iff [LT ι] [∀ i, LT (α i)] {a b : Colex (Π₀ i, α i)} : a < b ↔ ∃ i, (∀ j, i < j → a j = b j) ∧ a i < b i := .rfl @@ -76,10 +78,12 @@ theorem lex_iff_of_unique [Unique ι] [∀ i, LT (α i)] {r} [Std.Irrefl r] {x y DFinsupp.Lex r (fun _ ↦ (· < ·)) x y ↔ x default < y default := Pi.lex_iff_of_unique +set_option backward.isDefEq.respectTransparency false in theorem Lex.lt_iff_of_unique [Unique ι] [∀ i, LT (α i)] [Preorder ι] {x y : Lex (Π₀ i, α i)} : x < y ↔ x default < y default := lex_iff_of_unique +set_option backward.isDefEq.respectTransparency false in theorem colex_lt_iff_of_unique [Unique ι] [∀ i, LT (α i)] [Preorder ι] {x y : Colex (Π₀ i, α i)} : x < y ↔ x default < y default := lex_iff_of_unique @@ -91,6 +95,7 @@ instance Lex.isStrictOrder [∀ i, PartialOrder (α i)] : irrefl _ := lt_irrefl (α := Lex (∀ i, α i)) _ trans _ _ _ := lt_trans (α := Lex (∀ i, α i)) +set_option backward.isDefEq.respectTransparency false in instance Colex.isStrictOrder [∀ i, PartialOrder (α i)] : IsStrictOrder (Colex (Π₀ i, α i)) (· < ·) := Lex.isStrictOrder (ι := ιᵒᵈ) @@ -111,10 +116,12 @@ instance Colex.partialOrder [∀ i, PartialOrder (α i)] : PartialOrder (Colex ( __ := PartialOrder.lift (fun x : Colex (Π₀ i, α i) ↦ toColex (⇑(ofColex x))) (DFunLike.coe_injective (F := DFinsupp α)) +set_option backward.isDefEq.respectTransparency false in theorem Lex.le_iff_of_unique [Unique ι] [∀ i, PartialOrder (α i)] {x y : Lex (Π₀ i, α i)} : x ≤ y ↔ x default ≤ y default := Pi.lex_le_iff_of_unique +set_option backward.isDefEq.respectTransparency false in theorem Colex.le_iff_of_unique [Unique ι] [∀ i, PartialOrder (α i)] {x y : Colex (Π₀ i, α i)} : x ≤ y ↔ x default ≤ y default := Lex.le_iff_of_unique (ι := ιᵒᵈ) @@ -141,6 +148,7 @@ private def lt_trichotomy_rec {P : Lex (Π₀ i, α i) → Lex (Π₀ i, α i) instance Lex.total_le : @Std.Total (Lex (Π₀ i, α i)) (· ≤ ·) where total := lt_trichotomy_rec (fun h ↦ Or.inl h.le) (fun h ↦ Or.inl h.le) fun h ↦ Or.inr h.le +set_option backward.isDefEq.respectTransparency false in instance Colex.total_le : @Std.Total (Colex (Π₀ i, α i)) (· ≤ ·) := Lex.total_le (ι := ιᵒᵈ) @@ -152,6 +160,7 @@ instance Lex.decidableLE : DecidableLE (Lex (Π₀ i, α i)) := (fun h ↦ isTrue <| Or.inl <| congr_arg _ h) fun h ↦ isFalse fun h' ↦ lt_irrefl _ (h.trans_le h') +set_option backward.isDefEq.respectTransparency false in /-- The less-or-equal relation for the colexicographic ordering is decidable. -/ instance Colex.decidableLE : DecidableLE (Colex (Π₀ i, α i)) := Lex.decidableLE (ι := ιᵒᵈ) @@ -162,6 +171,7 @@ set_option backward.privateInPublic.warn false in instance Lex.decidableLT : DecidableLT (Lex (Π₀ i, α i)) := lt_trichotomy_rec (fun h ↦ isTrue h) (fun h ↦ isFalse h.not_lt) fun h ↦ isFalse h.asymm +set_option backward.isDefEq.respectTransparency false in /-- The less-than relation for the colexicographic ordering is decidable. -/ instance Colex.decidableLT : DecidableLT (Colex (Π₀ i, α i)) := Lex.decidableLT (ι := ιᵒᵈ) @@ -190,6 +200,7 @@ theorem toLex_monotone : Monotone (@toLex (Π₀ i, α i)) := by fun j hj ↦ notMem_neLocus.1 fun h ↦ (Finset.min'_le _ _ h).not_gt hj, (h _).lt_of_ne (mem_neLocus.1 <| Finset.min'_mem _ _)⟩ +set_option backward.isDefEq.respectTransparency false in theorem toColex_monotone : Monotone (@toColex (Π₀ i, α i)) := toLex_monotone (ι := ιᵒᵈ) @@ -212,6 +223,7 @@ set_option backward.defeqAttrib.useBackward true in instance Lex.addLeftStrictMono : AddLeftStrictMono (Lex (Π₀ i, α i)) := ⟨fun _ _ _ ⟨a, lta, ha⟩ ↦ ⟨a, fun j ja ↦ congr_arg _ (lta j ja), by dsimp; gcongr⟩⟩ +set_option backward.isDefEq.respectTransparency false in instance Colex.addLeftStrictMono : AddLeftStrictMono (Colex (Π₀ i, α i)) := Lex.addLeftStrictMono (ι := ιᵒᵈ) @@ -219,6 +231,7 @@ set_option backward.isDefEq.respectTransparency false in instance Lex.addLeftMono : AddLeftMono (Lex (Π₀ i, α i)) := addLeftMono_of_addLeftStrictMono _ +set_option backward.isDefEq.respectTransparency false in instance Colex.addLeftMono : AddLeftMono (Colex (Π₀ i, α i)) := Lex.addLeftMono (ι := ιᵒᵈ) @@ -233,6 +246,7 @@ instance Lex.addRightStrictMono : AddRightStrictMono (Lex (Π₀ i, α i)) := ⟨fun f _ _ ⟨a, lta, ha⟩ ↦ ⟨a, fun j ja ↦ congr_arg (· + ofLex f j) (lta j ja), by dsimp; gcongr⟩⟩ +set_option backward.isDefEq.respectTransparency false in instance Colex.addRightStrictMono : AddRightStrictMono (Colex (Π₀ i, α i)) := Lex.addRightStrictMono (ι := ιᵒᵈ) @@ -240,6 +254,7 @@ set_option backward.isDefEq.respectTransparency false in instance Lex.addRightMono : AddRightMono (Lex (Π₀ i, α i)) := addRightMono_of_addRightStrictMono _ +set_option backward.isDefEq.respectTransparency false in instance Colex.addRightMono : AddRightMono (Colex (Π₀ i, α i)) := Lex.addRightMono (ι := ιᵒᵈ) @@ -279,6 +294,7 @@ instance Lex.isOrderedCancelAddMonoid [∀ i, AddCommMonoid (α i)] [∀ i, Part add_le_add_left _ _ h _ := add_le_add_left (α := Lex (∀ i, α i)) h _ le_of_add_le_add_left _ _ _ := le_of_add_le_add_left (α := Lex (∀ i, α i)) +set_option backward.isDefEq.respectTransparency false in instance Colex.isOrderedCancelAddMonoid [∀ i, AddCommMonoid (α i)] [∀ i, PartialOrder (α i)] [∀ i, IsOrderedCancelAddMonoid (α i)] : IsOrderedCancelAddMonoid (Colex (Π₀ i, α i)) := @@ -289,6 +305,7 @@ instance Lex.isOrderedAddMonoid [∀ i, AddCommGroup (α i)] [∀ i, PartialOrde IsOrderedAddMonoid (Lex (Π₀ i, α i)) where add_le_add_left _ _ := add_le_add_left +set_option backward.isDefEq.respectTransparency false in instance Colex.isOrderedAddMonoid [∀ i, AddCommGroup (α i)] [∀ i, PartialOrder (α i)] [∀ i, IsOrderedAddMonoid (α i)] : IsOrderedAddMonoid (Colex (Π₀ i, α i)) := diff --git a/Mathlib/Data/DFinsupp/Multiset.lean b/Mathlib/Data/DFinsupp/Multiset.lean index 311952cbde2959..d63838359e132c 100644 --- a/Mathlib/Data/DFinsupp/Multiset.lean +++ b/Mathlib/Data/DFinsupp/Multiset.lean @@ -60,6 +60,7 @@ theorem toDFinsupp_apply (s : Multiset α) (a : α) : Multiset.toDFinsupp s a = theorem toDFinsupp_support (s : Multiset α) : s.toDFinsupp.support = s.toFinset := Finset.filter_true_of_mem fun _ hx ↦ count_ne_zero.mpr <| Multiset.mem_toFinset.1 hx +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toDFinsupp_replicate (a : α) (n : ℕ) : toDFinsupp (Multiset.replicate n a) = DFinsupp.single a n := by diff --git a/Mathlib/Data/DFinsupp/WellFounded.lean b/Mathlib/Data/DFinsupp/WellFounded.lean index 811b6320f24fe2..70a91e478f5c98 100644 --- a/Mathlib/Data/DFinsupp/WellFounded.lean +++ b/Mathlib/Data/DFinsupp/WellFounded.lean @@ -60,6 +60,7 @@ section Zero variable [∀ i, Zero (α i)] (r : ι → ι → Prop) (s : ∀ i, α i → α i → Prop) +set_option backward.isDefEq.respectTransparency false in /-- This key lemma says that if a finitely supported dependent function `x₀` is obtained by merging two such functions `x₁` and `x₂`, and if we evolve `x₀` down the `DFinsupp.Lex` relation one step and get `x`, we can always evolve one of `x₁` and `x₂` down the `DFinsupp.Lex` relation @@ -173,6 +174,7 @@ instance Lex.wellFoundedLT [LT ι] [@Std.Trichotomous ι (· < ·)] [hι : WellF WellFoundedLT (Lex (Π₀ i, α i)) := ⟨Lex.wellFounded' (fun _ _ => not_lt_zero) (fun i => (hα i).wf) hι.wf⟩ +set_option backward.isDefEq.respectTransparency false in instance Colex.wellFoundedLT [LT ι] [@Std.Trichotomous ι (· < ·)] [WellFoundedLT ι] [∀ i, AddMonoid (α i)] [∀ i, PartialOrder (α i)] [∀ i, IsBotZeroClass (α i)] [∀ i, WellFoundedLT (α i)] : @@ -198,6 +200,7 @@ instance Pi.Lex.wellFoundedLT [LinearOrder ι] [Finite ι] [∀ i, LT (α i)] [hwf : ∀ i, WellFoundedLT (α i)] : WellFoundedLT (Lex (∀ i, α i)) := ⟨Pi.Lex.wellFounded (· < ·) fun i => (hwf i).1⟩ +set_option backward.isDefEq.respectTransparency false in instance Pi.Colex.wellFoundedLT [LinearOrder ι] [Finite ι] [∀ i, LT (α i)] [∀ i, WellFoundedLT (α i)] : WellFoundedLT (Colex (∀ i, α i)) := Pi.Lex.wellFoundedLT (ι := ιᵒᵈ) @@ -215,6 +218,7 @@ instance DFinsupp.Lex.wellFoundedLT_of_finite [LinearOrder ι] [Finite ι] [∀ [∀ i, LT (α i)] [hwf : ∀ i, WellFoundedLT (α i)] : WellFoundedLT (Lex (Π₀ i, α i)) := ⟨DFinsupp.Lex.wellFounded_of_finite (· < ·) fun i => (hwf i).1⟩ +set_option backward.isDefEq.respectTransparency false in instance DFinsupp.Colex.wellFoundedLT_of_finite [LinearOrder ι] [Finite ι] [∀ i, Zero (α i)] [∀ i, LT (α i)] [hwf : ∀ i, WellFoundedLT (α i)] : WellFoundedLT (Colex (Π₀ i, α i)) := DFinsupp.Lex.wellFoundedLT_of_finite (ι := ιᵒᵈ) diff --git a/Mathlib/Data/ENNReal/Action.lean b/Mathlib/Data/ENNReal/Action.lean index 1e33eddb4bed6d..3210f20daccfa1 100644 --- a/Mathlib/Data/ENNReal/Action.lean +++ b/Mathlib/Data/ENNReal/Action.lean @@ -58,6 +58,7 @@ noncomputable instance {M : Type*} [AddMonoid M] [DistribMulAction ℝ≥0∞ M] noncomputable instance {M : Type*} [AddCommMonoid M] [Module ℝ≥0∞ M] : Module ℝ≥0 M := fast_instance% Module.compHom M ofNNRealHom +set_option backward.isDefEq.respectTransparency false in /-- An `Algebra` over `ℝ≥0∞` restricts to an `Algebra` over `ℝ≥0`. -/ noncomputable instance {A : Type*} [Semiring A] [Algebra ℝ≥0∞ A] : Algebra ℝ≥0 A where commutes' r x := by simp [Algebra.commutes] diff --git a/Mathlib/Data/ENNReal/Inv.lean b/Mathlib/Data/ENNReal/Inv.lean index 5793d3e229d2bb..972e97e91e6a0c 100644 --- a/Mathlib/Data/ENNReal/Inv.lean +++ b/Mathlib/Data/ENNReal/Inv.lean @@ -599,6 +599,7 @@ lemma le_mul_of_forall_lt {a b c : ℝ≥0∞} (h₁ : a ≠ 0 ∨ b ≠ ∞) (h (h _ (ENNReal.lt_inv_iff_lt_inv.1 ha') _ (ENNReal.lt_inv_iff_lt_inv.1 hb')).trans_eq (ENNReal.mul_inv (Or.inr hb'.ne_top) (Or.inl ha'.ne_top)).symm +set_option backward.isDefEq.respectTransparency false in /-- The birational order isomorphism between `ℝ≥0∞` and the unit interval `Set.Iic (1 : ℝ≥0∞)`. -/ @[simps! apply_coe] def orderIsoIicOneBirational : ℝ≥0∞ ≃o Iic (1 : ℝ≥0∞) := by @@ -614,6 +615,7 @@ theorem orderIsoIicOneBirational_symm_apply (x : Iic (1 : ℝ≥0∞)) : orderIsoIicOneBirational.symm x = (x.1⁻¹ - 1)⁻¹ := rfl +set_option backward.isDefEq.respectTransparency false in /-- Order isomorphism between an initial interval in `ℝ≥0∞` and an initial interval in `ℝ≥0`. -/ @[simps! apply_coe] def orderIsoIicCoe (a : ℝ≥0) : Iic (a : ℝ≥0∞) ≃o Iic a := diff --git a/Mathlib/Data/ENNReal/Operations.lean b/Mathlib/Data/ENNReal/Operations.lean index 188771aeb1a05e..8d551aae3f5dfb 100644 --- a/Mathlib/Data/ENNReal/Operations.lean +++ b/Mathlib/Data/ENNReal/Operations.lean @@ -518,6 +518,7 @@ theorem toNNReal_sInf (s : Set ℝ≥0∞) (hs : ∀ r ∈ s, r ≠ ∞) : theorem toReal_iInf (hf : ∀ i, f i ≠ ∞) : (iInf f).toReal = ⨅ i, (f i).toReal := by simp only [ENNReal.toReal, toNNReal_iInf hf, NNReal.coe_iInf] +set_option backward.isDefEq.respectTransparency false in theorem toReal_sInf (s : Set ℝ≥0∞) (hf : ∀ r ∈ s, r ≠ ∞) : (sInf s).toReal = sInf (ENNReal.toReal '' s) := by simp only [ENNReal.toReal, toNNReal_sInf s hf, NNReal.coe_sInf, Set.image_image] @@ -617,6 +618,7 @@ theorem toNNReal_sSup (s : Set ℝ≥0∞) (hs : ∀ r ∈ s, r ≠ ∞) : theorem toReal_iSup (hf : ∀ i, f i ≠ ∞) : (iSup f).toReal = ⨆ i, (f i).toReal := by simp only [ENNReal.toReal, toNNReal_iSup hf, NNReal.coe_iSup] +set_option backward.isDefEq.respectTransparency false in theorem toReal_sSup (s : Set ℝ≥0∞) (hf : ∀ r ∈ s, r ≠ ∞) : (sSup s).toReal = sSup (ENNReal.toReal '' s) := by simp only [ENNReal.toReal, toNNReal_sSup s hf, NNReal.coe_sSup, Set.image_image] diff --git a/Mathlib/Data/EReal/Inv.lean b/Mathlib/Data/EReal/Inv.lean index 20f2c4bbc6a20c..487d3f4fd09112 100644 --- a/Mathlib/Data/EReal/Inv.lean +++ b/Mathlib/Data/EReal/Inv.lean @@ -87,6 +87,7 @@ theorem sign_top : sign (⊤ : EReal) = 1 := rfl theorem sign_bot : sign (⊥ : EReal) = -1 := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem sign_coe (x : ℝ) : sign (x : EReal) = sign x := by simp only [sign, OrderHom.coe_mk, EReal.coe_pos, EReal.coe_neg'] diff --git a/Mathlib/Data/EReal/Operations.lean b/Mathlib/Data/EReal/Operations.lean index da8c1992221660..ffd3ada1959d11 100644 --- a/Mathlib/Data/EReal/Operations.lean +++ b/Mathlib/Data/EReal/Operations.lean @@ -516,11 +516,13 @@ lemma sub_lt_sub_of_le_of_gt {x y z t : EReal} (h : x ≤ y) (h' : z < t) /-! ### Addition and order -/ +set_option backward.isDefEq.respectTransparency false in lemma le_of_forall_lt_iff_le {x y : EReal} : (∀ z : ℝ, x < z → y ≤ z) ↔ y ≤ x := by refine ⟨fun h ↦ WithBot.le_of_forall_lt_iff_le.1 ?_, fun h _ x_z ↦ h.trans x_z.le⟩ rw [WithTop.forall] aesop +set_option backward.isDefEq.respectTransparency false in lemma ge_of_forall_gt_iff_ge {x y : EReal} : (∀ z : ℝ, z < y → z ≤ x) ↔ y ≤ x := by refine ⟨fun h ↦ WithBot.ge_of_forall_gt_iff_ge.1 ?_, fun h _ x_z ↦ x_z.le.trans h⟩ rw [WithTop.forall] diff --git a/Mathlib/Data/Fin/Fin2.lean b/Mathlib/Data/Fin/Fin2.lean index 067362c5e5cdb8..6fdea26246ae97 100644 --- a/Mathlib/Data/Fin/Fin2.lean +++ b/Mathlib/Data/Fin/Fin2.lean @@ -149,6 +149,7 @@ theorem rev_involutive {n} : Function.Involutive (@rev n) := rev_rev instance : Inhabited (Fin2 1) := ⟨fz⟩ +set_option backward.isDefEq.respectTransparency false in set_option linter.style.whitespace false in -- manual alignment is not recognised instance instFintype : ∀ n, Fintype (Fin2 n) | 0 => ⟨∅, Fin2.elim0⟩ diff --git a/Mathlib/Data/Fin/Tuple/Basic.lean b/Mathlib/Data/Fin/Tuple/Basic.lean index 4ec26a5bfc822b..6d18a6513dea9c 100644 --- a/Mathlib/Data/Fin/Tuple/Basic.lean +++ b/Mathlib/Data/Fin/Tuple/Basic.lean @@ -408,6 +408,7 @@ theorem append_comp_sumElim {xs : Fin m → α} {ys : Fin n → α} : Fin.append xs ys ∘ Sum.elim (Fin.castAdd _) (Fin.natAdd _) = Sum.elim xs ys := by ext (i | j) <;> simp +set_option backward.isDefEq.respectTransparency false in theorem append_injective_iff {xs : Fin m → α} {ys : Fin n → α} : Function.Injective (Fin.append xs ys) ↔ Function.Injective xs ∧ Function.Injective ys ∧ ∀ i j, xs i ≠ ys j := by @@ -664,6 +665,7 @@ theorem append_right_cons {n m} {α : Sort*} (xs : Fin n → α) (y : α) (ys : Fin.append (Fin.snoc xs y) ys ∘ Fin.cast (Nat.succ_add_eq_add_succ ..).symm := by rw [append_left_snoc]; rfl +set_option backward.isDefEq.respectTransparency false in theorem append_cons {α : Sort*} (a : α) (as : Fin n → α) (bs : Fin m → α) : Fin.append (cons a as) bs = cons a (Fin.append as bs) ∘ (Fin.cast <| Nat.add_right_comm n 1 m) := by @@ -678,6 +680,7 @@ theorem append_cons {α : Sort*} (a : α) (as : Fin n → α) (bs : Fin m → α · have : ¬i < n := Nat.not_le_of_gt <| Nat.le_of_lt_succ <| Nat.gt_of_not_le h simp [addCases, this] +set_option backward.isDefEq.respectTransparency false in theorem append_snoc {α : Sort*} (as : Fin n → α) (bs : Fin m → α) (b : α) : Fin.append as (snoc bs b) = snoc (Fin.append as bs) b := by funext i @@ -715,6 +718,7 @@ def snocCases {motive : (∀ i : Fin n.succ, α i) → Sort*} (x : ∀ i : Fin n.succ, α i) : motive x := _root_.cast (by rw [Fin.snoc_init_self]) <| snoc (Fin.init x) (x <| Fin.last _) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma snocCases_snoc {motive : (∀ i : Fin (n + 1), α i) → Sort*} (snoc : ∀ x x₀, motive (Fin.snoc x x₀)) (x : ∀ i : Fin n, (Fin.init α) i) (x₀ : α (Fin.last _)) : diff --git a/Mathlib/Data/Fin/Tuple/Embedding.lean b/Mathlib/Data/Fin/Tuple/Embedding.lean index 663ec83b9a0a30..832da015637320 100644 --- a/Mathlib/Data/Fin/Tuple/Embedding.lean +++ b/Mathlib/Data/Fin/Tuple/Embedding.lean @@ -93,6 +93,7 @@ namespace Function.Embedding variable {α : Type*} +set_option backward.isDefEq.respectTransparency false in /-- The natural equivalence of `Fin 2 ↪ α` with pairs `(a, b)` of distinct elements of `α`. -/ def twoEmbeddingEquiv : (Fin 2 ↪ α) ≃ {(a, b) : α × α | a ≠ b} where toFun e := ⟨(e 0, e 1), by diff --git a/Mathlib/Data/Fin/Tuple/Sort.lean b/Mathlib/Data/Fin/Tuple/Sort.lean index fc5b8b090beaa8..72c8d02bf9c1e2 100644 --- a/Mathlib/Data/Fin/Tuple/Sort.lean +++ b/Mathlib/Data/Fin/Tuple/Sort.lean @@ -56,6 +56,7 @@ theorem graph.card (f : Fin n → α) : (graph f).card = n := by rw [Prod.ext_iff] simp +set_option backward.isDefEq.respectTransparency false in /-- `graphEquiv₁ f` is the natural equivalence between `Fin n` and `graph f`, mapping `i` to `(f i, i)`. -/ def graphEquiv₁ (f : Fin n → α) : Fin n ≃ graph f where diff --git a/Mathlib/Data/Fin/Tuple/Take.lean b/Mathlib/Data/Fin/Tuple/Take.lean index c311b581f4204f..f542aea28f6e86 100644 --- a/Mathlib/Data/Fin/Tuple/Take.lean +++ b/Mathlib/Data/Fin/Tuple/Take.lean @@ -66,6 +66,7 @@ theorem take_repeat {α : Type*} {n' : ℕ} (m : ℕ) (h : m ≤ n) (a : Fin n' ext i simp only [take, repeat_apply, modNat, val_castLE] +set_option backward.isDefEq.respectTransparency false in /-- Taking `m + 1` elements is equal to taking `m` elements and adding the `(m + 1)`th one. -/ theorem take_succ_eq_snoc (m : ℕ) (h : m < n) (v : (i : Fin n) → α i) : take m.succ h v = snoc (take m h.le v) (v ⟨m, h⟩) := by diff --git a/Mathlib/Data/FinEnum.lean b/Mathlib/Data/FinEnum.lean index 09265e1c0735ac..ec344f04cf535b 100644 --- a/Mathlib/Data/FinEnum.lean +++ b/Mathlib/Data/FinEnum.lean @@ -40,14 +40,14 @@ namespace FinEnum variable {α : Type u} {β : α → Type v} /-- transport a `FinEnum` instance across an equivalence -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv (α) {β} [FinEnum α] (h : β ≃ α) : FinEnum β where card := card α equiv := h.trans (equiv) decEq := (h.trans (equiv)).decidableEq /-- create a `FinEnum` instance from an exhaustive list without duplicates -/ -@[implicit_reducible] +@[instance_reducible] def ofNodupList [DecidableEq α] (xs : List α) (h : ∀ x : α, x ∈ xs) (h' : List.Nodup xs) : FinEnum α where card := xs.length @@ -56,7 +56,7 @@ def ofNodupList [DecidableEq α] (xs : List α) (h : ∀ x : α, x ∈ xs) (h' : fun i => by ext; simp [h'.idxOf_getElem]⟩ /-- create a `FinEnum` instance from an exhaustive list; duplicates are removed -/ -@[implicit_reducible] +@[instance_reducible] def ofList [DecidableEq α] (xs : List α) (h : ∀ x : α, x ∈ xs) : FinEnum α := ofNodupList xs.dedup (by simp [*]) (List.nodup_dedup _) @@ -78,12 +78,12 @@ theorem nodup_toList [FinEnum α] : List.Nodup (toList α) := by simp only [toList]; apply List.Nodup.map <;> [apply Equiv.injective; apply List.nodup_finRange] /-- create a `FinEnum` instance using a surjection -/ -@[implicit_reducible] +@[instance_reducible] def ofSurjective {β} (f : β → α) [DecidableEq α] [FinEnum β] (h : Surjective f) : FinEnum α := ofList ((toList β).map f) (by intro; simpa using h _) /-- create a `FinEnum` instance using an injection -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofInjective {α β} (f : α → β) [DecidableEq α] [FinEnum β] (h : Injective f) : FinEnum α := ofList ((toList β).filterMap (partialInv f)) @@ -242,7 +242,7 @@ instance [IsEmpty α] : Unique (FinEnum α) where /-- An empty type has a trivial enumeration. Not registered as an instance, to make sure that there aren't two definitionally differing instances around. -/ -@[implicit_reducible] +@[instance_reducible] def ofIsEmpty [IsEmpty α] : FinEnum α := default instance [Unique α] : Unique (FinEnum α) where @@ -257,7 +257,7 @@ instance [Unique α] : Unique (FinEnum α) where /-- A type with unique inhabitant has a trivial enumeration. Not registered as an instance, to make sure that there aren't two definitionally differing instances around. -/ -@[implicit_reducible] +@[instance_reducible] def ofUnique [Unique α] : FinEnum α := default instance : FinEnum UInt8 where diff --git a/Mathlib/Data/FinEnum/Option.lean b/Mathlib/Data/FinEnum/Option.lean index 41be5993f77b7c..e4011c9e70fa35 100644 --- a/Mathlib/Data/FinEnum/Option.lean +++ b/Mathlib/Data/FinEnum/Option.lean @@ -24,7 +24,7 @@ namespace FinEnum universe u v /-- Inserting an `Option.none` anywhere in an enumeration yields another enumeration. -/ -@[implicit_reducible] +@[instance_reducible] def insertNone (α : Type u) [FinEnum α] (i : Fin (card α + 1)) : FinEnum (Option α) where card := card α + 1 equiv := equiv.optionCongr.trans <| finSuccEquiv' i |>.symm diff --git a/Mathlib/Data/Finmap.lean b/Mathlib/Data/Finmap.lean index ec4dbcdbc01e22..3d003bd90f79d9 100644 --- a/Mathlib/Data/Finmap.lean +++ b/Mathlib/Data/Finmap.lean @@ -80,6 +80,7 @@ def AList.toFinmap (s : AList β) : Finmap β := -- for `Quotient.mk` local notation:arg "⟦" a "⟧" => AList.toFinmap a +set_option backward.isDefEq.respectTransparency false in theorem AList.toFinmap_eq {s₁ s₂ : AList β} : toFinmap s₁ = toFinmap s₂ ↔ s₁.entries ~ s₂.entries := by cases s₁ diff --git a/Mathlib/Data/Finset/Defs.lean b/Mathlib/Data/Finset/Defs.lean index 4421e55d0a0215..6b47b346bb4689 100644 --- a/Mathlib/Data/Finset/Defs.lean +++ b/Mathlib/Data/Finset/Defs.lean @@ -315,6 +315,7 @@ section DecidablePiExists variable {s : Finset α} +set_option backward.isDefEq.respectTransparency false in instance decidableDforallFinset {p : ∀ a ∈ s, Prop} [_hp : ∀ (a) (h : a ∈ s), Decidable (p a h)] : Decidable (∀ (a) (h : a ∈ s), p a h) := Multiset.decidableDforallMultiset @@ -331,6 +332,7 @@ instance instDecidableLE [DecidableEq α] : DecidableLE (Finset α) := instance instDecidableLT [DecidableEq α] : DecidableLT (Finset α) := instDecidableRelSSubset +set_option backward.isDefEq.respectTransparency false in instance decidableDExistsFinset {p : ∀ a ∈ s, Prop} [_hp : ∀ (a) (h : a ∈ s), Decidable (p a h)] : Decidable (∃ (a : _) (h : a ∈ s), p a h) := Multiset.decidableDexistsMultiset diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index ecfc861c076427..f9c4beb141464d 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -178,6 +178,7 @@ lemma map_filter' (p : α → Prop) [DecidablePred p] (f : α ↪ β) (s : Finse (s.filter p).map f = (s.map f).filter fun b => ∃ a, p a ∧ f a = b := by simp [filter_map] +set_option backward.isDefEq.respectTransparency false in lemma filter_attach' [DecidableEq α] (s : Finset α) (p : s → Prop) [DecidablePred p] : s.attach.filter p = (s.filter fun x => ∃ h, p ⟨x, h⟩).attach.map @@ -263,6 +264,7 @@ noncomputable def equivMap : s ≃ s.map f := end Map +set_option backward.isDefEq.respectTransparency false in theorem range_add_one' (n : ℕ) : range (n + 1) = insert 0 ((range n).map ⟨fun i => i + 1, fun i j => by simp⟩) := by ext (⟨⟩ | ⟨n⟩) <;> simp [Nat.zero_lt_succ n] @@ -308,6 +310,7 @@ theorem mem_image_const : c ∈ s.image (const α b) ↔ s.Nonempty ∧ b = c := theorem mem_image_const_self : b ∈ s.image (const α b) ↔ s.Nonempty := mem_image_const.trans <| and_iff_left rfl +set_option backward.isDefEq.respectTransparency false in instance canLift (c) (p) [CanLift β α c p] : CanLift (Finset β) (Finset α) (image c) fun s => ∀ x ∈ s, p x where prf := by @@ -542,6 +545,7 @@ set_option backward.isDefEq.respectTransparency false in theorem attach_image_val [DecidableEq α] {s : Finset α} : s.attach.image Subtype.val = s := eq_of_veq <| by rw [image_val, attach_val, Multiset.attach_map_val, dedup_eq_self] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma attach_cons (a : α) (s : Finset α) (ha) : attach (cons a s ha) = @@ -635,6 +639,7 @@ protected def subtype {α} (p : α → Prop) [DecidablePred p] (s : Finset α) : ⟨fun x => ⟨x.1, by simpa using (Finset.mem_filter.1 x.2).2⟩, fun _ _ H => Subtype.ext <| Subtype.mk.inj H⟩ +set_option backward.isDefEq.respectTransparency false in @[simp, grind =] theorem mem_subtype {p : α → Prop} [DecidablePred p] {s : Finset α} : ∀ {a : Subtype p}, a ∈ s.subtype p ↔ (a : α) ∈ s @@ -765,6 +770,7 @@ theorem finsetCongr_toEmbedding (e : α ≃ β) : e.finsetCongr.toEmbedding = (Finset.mapEmbedding e.toEmbedding).toEmbedding := rfl +set_option backward.isDefEq.respectTransparency false in /-- Given a predicate `p : α → Prop`, produces an equivalence between `Finset {a : α // p a}` and `{s : Finset α // ∀ a ∈ s, p a}`. -/ @[simps] diff --git a/Mathlib/Data/Finset/Insert.lean b/Mathlib/Data/Finset/Insert.lean index fbaa3b4dc10377..5b7fe9bc395c8d 100644 --- a/Mathlib/Data/Finset/Insert.lean +++ b/Mathlib/Data/Finset/Insert.lean @@ -285,6 +285,7 @@ theorem cons_nonempty (h : a ∉ s) : (cons a s h).Nonempty := @[simp] theorem cons_ne_empty (h : a ∉ s) : cons a s h ≠ ∅ := (cons_nonempty _).ne_empty +set_option backward.isDefEq.respectTransparency false in @[simp] theorem nonempty_mk {m : Multiset α} {hm} : (⟨m, hm⟩ : Finset α).Nonempty ↔ m ≠ 0 := by induction m using Multiset.induction_on <;> simp diff --git a/Mathlib/Data/Finset/Lattice/Prod.lean b/Mathlib/Data/Finset/Lattice/Prod.lean index 0b9096a0ef3882..0511defb7b136e 100644 --- a/Mathlib/Data/Finset/Lattice/Prod.lean +++ b/Mathlib/Data/Finset/Lattice/Prod.lean @@ -90,6 +90,7 @@ theorem sup'_product_right {t : Finset γ} (h : (s ×ˢ t).Nonempty) (f : β × section Prod variable {ι κ α β : Type*} [SemilatticeSup α] [SemilatticeSup β] {s : Finset ι} {t : Finset κ} +set_option backward.isDefEq.respectTransparency false in /-- See also `Finset.sup'_prodMap`. -/ @[to_dual /-- See also `Finset.inf'_prodMap`. -/] lemma prodMk_sup'_sup' (hs : s.Nonempty) (ht : t.Nonempty) (f : ι → α) (g : κ → β) : diff --git a/Mathlib/Data/Finset/NatAntidiagonal.lean b/Mathlib/Data/Finset/NatAntidiagonal.lean index 9bfb92c051c2aa..aaca416e0d4605 100644 --- a/Mathlib/Data/Finset/NatAntidiagonal.lean +++ b/Mathlib/Data/Finset/NatAntidiagonal.lean @@ -50,10 +50,12 @@ lemma antidiagonal_eq_map' (n : ℕ) : (range (n + 1)).map ⟨fun i ↦ (n - i, i), fun _ _ h ↦ (Prod.ext_iff.1 h).2⟩ := by rw [← map_swap_antidiagonal, antidiagonal_eq_map, map_map]; rfl +set_option backward.isDefEq.respectTransparency false in lemma antidiagonal_eq_image (n : ℕ) : antidiagonal n = (range (n + 1)).image fun i ↦ (i, n - i) := by simp only [antidiagonal_eq_map, map_eq_image, Function.Embedding.coeFn_mk] +set_option backward.isDefEq.respectTransparency false in lemma antidiagonal_eq_image' (n : ℕ) : antidiagonal n = (range (n + 1)).image fun i ↦ (n - i, i) := by simp only [antidiagonal_eq_map', map_eq_image, Function.Embedding.coeFn_mk] @@ -149,7 +151,8 @@ theorem antidiagonal.snd_lt {n : ℕ} {kl : ℕ × ℕ} (hlk : kl ∈ antidiagon ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j := fun i j ↦ by rw [exists_comm]; exact exists₂_congr (fun a b ↦ by rw [add_comm]) rw [← map_prodComm_antidiagonal] - simp_rw [aux₁, ← map_filter, antidiagonal_filter_le_fst_of_le h, map_map] + simp_rw [aux₁, ← map_filter, antidiagonal_filter_le_fst_of_le h, + map_map] ext ⟨i, j⟩ simpa using aux₂ i j diff --git a/Mathlib/Data/Finset/NoncommProd.lean b/Mathlib/Data/Finset/NoncommProd.lean index f24979578a0875..08af78bf0a4589 100644 --- a/Mathlib/Data/Finset/NoncommProd.lean +++ b/Mathlib/Data/Finset/NoncommProd.lean @@ -82,6 +82,7 @@ def noncommFold (s : Multiset α) (comm : { x | x ∈ s }.Pairwise fun x y => op α → α := noncommFoldr op s fun x hx y hy h b => by rw [← assoc.assoc, comm hx hy h, assoc.assoc] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem noncommFold_coe (l : List α) (comm) (a : α) : noncommFold op (l : Multiset α) comm a = l.foldr op a := by simp [noncommFold] @@ -112,6 +113,7 @@ on all elements `x ∈ s`. -/ def noncommProd (s : Multiset α) (comm : { x | x ∈ s }.Pairwise Commute) : α := s.noncommFold (· * ·) comm 1 +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem noncommProd_coe (l : List α) (comm) : noncommProd (l : Multiset α) comm = l.prod := by rw [noncommProd] @@ -289,6 +291,7 @@ theorem noncommProd_cons' (s : Finset α) (a : α) (f : α → β) noncommProd s f (comm.mono fun _ => Finset.mem_cons.2 ∘ .inr) * f a := by simp_rw [noncommProd, Finset.cons_val, Multiset.map_cons, Multiset.noncommProd_cons'] +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem noncommProd_insert_of_notMem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm) (ha : a ∉ s) : @@ -296,6 +299,7 @@ theorem noncommProd_insert_of_notMem [DecidableEq α] (s : Finset α) (a : α) ( f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) := by simp only [← cons_eq_insert _ _ ha, noncommProd_cons] +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem noncommProd_insert_of_notMem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm) (ha : a ∉ s) : @@ -349,6 +353,7 @@ theorem noncommProd_erase_mul [DecidableEq α] (s : Finset α) {a : α} (h : a simpa only [← Multiset.map_erase_of_mem _ _ h] using! Multiset.noncommProd_erase_mul (s.1.map f) (Multiset.mem_map_of_mem f h) _ +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem noncommProd_eq_prod {β : Type*} [CommMonoid β] (s : Finset α) (f : α → β) : (noncommProd s f fun _ _ _ _ _ => Commute.all _ _) = s.prod f := by @@ -381,6 +386,7 @@ theorem noncommProd_mul_distrib_aux {s : Finset α} {f : α → β} {g : α → · exact comm_gf hx hy h · exact comm_gg.of_refl hx hy +set_option backward.isDefEq.respectTransparency false in /-- The non-commutative version of `Finset.prod_mul_distrib` -/ @[to_additive /-- The non-commutative version of `Finset.sum_add_distrib` -/] theorem noncommProd_mul_distrib {s : Finset α} (f : α → β) (g : α → β) (comm_ff comm_gg comm_gf) : @@ -399,6 +405,7 @@ section FinitePi variable {M : ι → Type*} [∀ i, Monoid (M i)] +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem noncommProd_mulSingle [Fintype ι] [DecidableEq ι] (x : ∀ i, M i) : (univ.noncommProd (fun i => Pi.mulSingle i (x i)) fun i _ j _ _ => @@ -418,6 +425,7 @@ theorem noncommProd_mulSingle [Fintype ι] [DecidableEq ι] (x : ∀ i, M i) : · simp only [Pi.mulSingle_eq_same] · simpa using fun _ a ↦ Pi.mulSingle_eq_of_ne (a ·.symm) _ +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem _root_.MonoidHom.pi_ext [Finite ι] [DecidableEq ι] {f g : (∀ i, M i) →* γ} (h : ∀ i x, f (Pi.mulSingle i x) = g (Pi.mulSingle i x)) : f = g := by diff --git a/Mathlib/Data/Finset/PImage.lean b/Mathlib/Data/Finset/PImage.lean index 2fbaff8f420f9f..590697e155001f 100644 --- a/Mathlib/Data/Finset/PImage.lean +++ b/Mathlib/Data/Finset/PImage.lean @@ -66,6 +66,7 @@ theorem mem_pimage : b ∈ s.pimage f ↔ ∃ a ∈ s, b ∈ f a := by theorem coe_pimage : (s.pimage f : Set β) = f.image s := Set.ext fun _ => mem_pimage +set_option backward.isDefEq.respectTransparency false in @[simp] theorem pimage_some (s : Finset α) (f : α → β) [∀ x, Decidable (Part.some <| f x).Dom] : (s.pimage fun x => Part.some (f x)) = s.image f := by diff --git a/Mathlib/Data/Finset/Powerset.lean b/Mathlib/Data/Finset/Powerset.lean index c5fd6473412e54..75086695fa134b 100644 --- a/Mathlib/Data/Finset/Powerset.lean +++ b/Mathlib/Data/Finset/Powerset.lean @@ -301,6 +301,7 @@ theorem pairwise_disjoint_powersetCard (s : Finset α) : Finset.disjoint_left.mpr fun _x hi hj => hij <| (mem_powersetCard.mp hi).2.symm.trans (mem_powersetCard.mp hj).2 +set_option backward.isDefEq.respectTransparency false in theorem powerset_card_disjiUnion (s : Finset α) : Finset.powerset s = (range (s.card + 1)).disjiUnion (fun i => powersetCard i s) @@ -313,6 +314,7 @@ theorem powerset_card_disjiUnion (s : Finset α) : · rcases mem_disjiUnion.mp ha with ⟨i, _hi, ha⟩ exact mem_powerset.mpr (mem_powersetCard.mp ha).1 +set_option backward.isDefEq.respectTransparency false in theorem powerset_card_biUnion [DecidableEq (Finset α)] (s : Finset α) : Finset.powerset s = (range (s.card + 1)).biUnion fun i => powersetCard i s := by simpa only [disjiUnion_eq_biUnion] using powerset_card_disjiUnion s diff --git a/Mathlib/Data/Finset/Preimage.lean b/Mathlib/Data/Finset/Preimage.lean index b84ccb84d821d5..32b93863e9fc1e 100644 --- a/Mathlib/Data/Finset/Preimage.lean +++ b/Mathlib/Data/Finset/Preimage.lean @@ -55,6 +55,7 @@ theorem disjoint_preimage {f : α → β} {s t : Finset β} Disjoint (s.preimage f hs) (t.preimage f ht) := by grind [not_disjoint_iff, mem_preimage] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem preimage_inter [DecidableEq α] [DecidableEq β] {f : α → β} {s t : Finset β} (hs : Set.InjOn f (f ⁻¹' ↑s)) (ht : Set.InjOn f (f ⁻¹' ↑t)) : @@ -63,6 +64,7 @@ theorem preimage_inter [DecidableEq α] [DecidableEq β] {f : α → β} {s t : preimage s f hs ∩ preimage t f ht := Finset.coe_injective (by simp) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem preimage_union [DecidableEq α] [DecidableEq β] {f : α → β} {s t : Finset β} (hst) : preimage (s ∪ t) f hst = diff --git a/Mathlib/Data/Finset/Sum.lean b/Mathlib/Data/Finset/Sum.lean index c5da1287f1d90f..047def625ffb40 100644 --- a/Mathlib/Data/Finset/Sum.lean +++ b/Mathlib/Data/Finset/Sum.lean @@ -224,6 +224,7 @@ lemma toRight_sdiff : (u \ v).toRight = u.toRight \ v.toRight := by ext x; simp end +set_option backward.isDefEq.respectTransparency false in /-- Finsets on sum types are equivalent to pairs of finsets on each summand. -/ @[simps apply_fst apply_snd] def sumEquiv {α β : Type*} : Finset (α ⊕ β) ≃o Finset α × Finset β where diff --git a/Mathlib/Data/Finset/Union.lean b/Mathlib/Data/Finset/Union.lean index 21b266200ee19b..00913b1f297c02 100644 --- a/Mathlib/Data/Finset/Union.lean +++ b/Mathlib/Data/Finset/Union.lean @@ -146,11 +146,13 @@ theorem filter_disjiUnion (s : Finset α) (f : α → Finset β) (h) (p : β → (s.disjiUnion f h).filter p = s.disjiUnion (fun a ↦ (f a).filter p) (pairwiseDisjoint_filter h p) := by grind +set_option backward.isDefEq.respectTransparency false in theorem disjiUnion_singleton {f : α → β} (hf : f.Injective) : s.disjiUnion (fun a ↦ {f a}) (fun _ _ _ _ ↦ disjoint_singleton.mpr ∘ hf.ne) = s.map ⟨f, hf⟩ := by ext; simp [eq_comm] +set_option backward.isDefEq.respectTransparency false in lemma disjoint_disjiUnion_left (s : Finset α) (f : α → Finset β) (hf : Set.PairwiseDisjoint s f) (t : Finset β) : Disjoint (s.disjiUnion f hf) t ↔ ∀ i ∈ s, Disjoint (f i) t := by diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 66515acfcfe193..eafda164c1daa8 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -81,6 +81,7 @@ theorem apply_eq_of_mem_graph {a : α} {m : M} {f : α →₀ M} (h : (a, m) ∈ theorem notMem_graph_snd_zero (a : α) (f : α →₀ M) : (a, (0 : M)) ∉ f.graph := fun h => (mem_graph_iff.1 h).2.irrefl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem image_fst_graph [DecidableEq α] (f : α →₀ M) : f.graph.image Prod.fst = f.support := by classical @@ -1213,6 +1214,9 @@ theorem subtypeDomain_not_piecewise (f : Subtype P →₀ M) (g : {a // ¬ P a} subtypeDomain (¬P ·) (f.piecewise g) = g := Finsupp.ext fun a => dif_neg a.prop +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Extend the domain of a `Finsupp` by using `0` where `P x` does not hold. -/ @[simps! (attr := grind =) support apply] def extendDomain (f : Subtype P →₀ M) : α →₀ M := piecewise f 0 @@ -1261,6 +1265,7 @@ the type of finitely supported functions from `s`. -/ letI := Classical.decPred (· ∈ s); Subtype.ext <| extendDomain_subtypeDomain f.1 f.prop right_inv _ := letI := Classical.decPred (· ∈ s); subtypeDomain_extendDomain _ +set_option backward.isDefEq.respectTransparency false in @[simp] lemma restrictSupportEquiv_symm_apply_coe (s : Set α) (M : Type*) [AddCommMonoid M] [DecidablePred (· ∈ s)] (f : s →₀ M) : (restrictSupportEquiv s M).symm f = f.extendDomain := by @@ -1324,6 +1329,7 @@ This is the `Finsupp` version of `Sigma.curry`. def split (i : ι) : αs i →₀ M := l.comapDomain (Sigma.mk i) fun _ _ _ _ hx => heq_iff_eq.1 (Sigma.mk.inj hx).2 +set_option backward.isDefEq.respectTransparency false in theorem split_apply (i : ι) (x : αs i) : split l i x = l ⟨i, x⟩ := by rw [split, comapDomain_apply] @@ -1333,6 +1339,7 @@ def splitSupport (l : (Σ i, αs i) →₀ M) : Finset ι := haveI := Classical.decEq ι l.support.image Sigma.fst +set_option backward.isDefEq.respectTransparency false in theorem mem_splitSupport_iff_nonzero (i : ι) : i ∈ splitSupport l ↔ split l i ≠ 0 := by classical rw [splitSupport, mem_image, Ne, ← support_eq_empty, ← Ne, ← Finset.nonempty_iff_ne_empty, split, comapDomain, Finset.Nonempty] @@ -1350,6 +1357,7 @@ def splitComp [Zero N] (g : ∀ i, (αs i →₀ M) → N) (hg : ∀ i x, x = 0 intro i rw [mem_splitSupport_iff_nonzero, not_iff_not, hg] +set_option backward.isDefEq.respectTransparency false in theorem sigma_support : l.support = l.splitSupport.sigma fun i => (l.split i).support := by simp_rw [Finset.ext_iff, splitSupport, split, comapDomain, Sigma.forall, mem_sigma, mem_image, mem_preimage] @@ -1361,6 +1369,7 @@ theorem sigma_sum [AddCommMonoid N] (f : (Σ i : ι, αs i) → M → N) : variable {η : Type*} [Fintype η] {ιs : η → Type*} [Zero α] +set_option backward.isDefEq.respectTransparency false in /-- On a `Fintype η`, `Finsupp.split` is an equivalence between `(Σ (j : η), ιs j) →₀ α` and `Π j, (ιs j →₀ α)`. diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 149e198bc4b4dc..6faed13e4264fd 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -384,6 +384,7 @@ def mapRange.equiv (e : M ≃ N) (hf : e 0 = 0) : (ι →₀ M) ≃ (ι →₀ N left_inv x := by ext; simp right_inv x := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mapRange.equiv_refl : mapRange.equiv (.refl M) rfl = .refl (ι →₀ M) := by ext; simp lemma mapRange.equiv_trans (e : M ≃ N) (hf) (f₂ : N ≃ O) (hf₂) : diff --git a/Mathlib/Data/Finsupp/Lex.lean b/Mathlib/Data/Finsupp/Lex.lean index de5c7b88193acb..9780189ab05644 100644 --- a/Mathlib/Data/Finsupp/Lex.lean +++ b/Mathlib/Data/Finsupp/Lex.lean @@ -52,10 +52,12 @@ instance [LT α] [LT N] : LT (Lex (α →₀ N)) := instance [LT α] [LT N] : LT (Colex (α →₀ N)) := ⟨fun f g ↦ Finsupp.Lex (· > ·) (· < ·) (ofColex f) (ofColex g)⟩ +set_option backward.isDefEq.respectTransparency false in theorem Lex.lt_iff [LT α] [LT N] {a b : Lex (α →₀ N)} : a < b ↔ ∃ i, (∀ j, j < i → a j = b j) ∧ a i < b i := .rfl +set_option backward.isDefEq.respectTransparency false in theorem Colex.lt_iff [LT α] [LT N] {a b : Colex (α →₀ N)} : a < b ↔ ∃ i, (∀ j, i < j → a j = b j) ∧ a i < b i := .rfl @@ -72,10 +74,12 @@ theorem lex_iff_of_unique [Unique α] [LT N] {r} [Std.Irrefl r] {x y : α →₀ Finsupp.Lex r (· < ·) x y ↔ x default < y default := Pi.lex_iff_of_unique +set_option backward.isDefEq.respectTransparency false in theorem Lex.lt_iff_of_unique [Unique α] [LT N] [Preorder α] {x y : Lex (α →₀ N)} : x < y ↔ x default < y default := lex_iff_of_unique +set_option backward.isDefEq.respectTransparency false in theorem Colex.lt_iff_of_unique [Unique α] [LT N] [Preorder α] {x y : Colex (α →₀ N)} : x < y ↔ x default < y default := Lex.lt_iff_of_unique (α := αᵒᵈ) @@ -116,10 +120,12 @@ instance Colex.linearOrder [LinearOrder N] : LinearOrder (Colex (α →₀ N)) w le := (· ≤ ·) __ := LinearOrder.lift' (toColex ∘ toDFinsupp ∘ ofColex) finsuppEquivDFinsupp.injective +set_option backward.isDefEq.respectTransparency false in theorem Lex.le_iff_of_unique [Unique α] [PartialOrder N] {x y : Lex (α →₀ N)} : x ≤ y ↔ x default ≤ y default := Pi.lex_le_iff_of_unique +set_option backward.isDefEq.respectTransparency false in theorem Colex.le_iff_of_unique [Unique α] [PartialOrder N] {x y : Colex (α →₀ N)} : x ≤ y ↔ x default ≤ y default := Lex.le_iff_of_unique (α := αᵒᵈ) @@ -193,6 +199,7 @@ section Right variable [AddRightStrictMono N] +set_option backward.isDefEq.respectTransparency false in instance Lex.addRightStrictMono : AddRightStrictMono (Lex (α →₀ N)) := ⟨fun f _ _ ⟨a, lta, ha⟩ ↦ ⟨a, fun j ja ↦ congr($(lta j ja) + f j), add_lt_add_left ha _⟩⟩ diff --git a/Mathlib/Data/Finsupp/ToDFinsupp.lean b/Mathlib/Data/Finsupp/ToDFinsupp.lean index 9241f486d17237..8989f05d0f8a00 100644 --- a/Mathlib/Data/Finsupp/ToDFinsupp.lean +++ b/Mathlib/Data/Finsupp/ToDFinsupp.lean @@ -251,6 +251,7 @@ variable {η : ι → Type*} {N : Type*} [Semiring R] open Finsupp +set_option backward.isDefEq.respectTransparency false in /-- `Finsupp.split` is an equivalence between `(Σ i, η i) →₀ N` and `Π₀ i, (η i →₀ N)`. -/ def sigmaFinsuppEquivDFinsupp [Zero N] : ((Σ i, η i) →₀ N) ≃ Π₀ i, η i →₀ N where toFun f := ⟨split f, Trunc.mk ⟨(splitSupport f : Finset ι).val, fun i => by diff --git a/Mathlib/Data/Finsupp/Weight.lean b/Mathlib/Data/Finsupp/Weight.lean index ec47216dd6c7f7..5d35b796e8ce5b 100644 --- a/Mathlib/Data/Finsupp/Weight.lean +++ b/Mathlib/Data/Finsupp/Weight.lean @@ -277,6 +277,7 @@ theorem degree_mapDomain {τ : Type*} (f : σ → τ) [AddCommMonoid M] (x : σ @[deprecated (since := "2026-04-27")] alias degree_mapDomain_eq_of_subsingletonAddUnits := degree_mapDomain +set_option backward.isDefEq.respectTransparency false in theorem degree_comapDomain_le_of_canonicallyOrderedAdd {τ : Type*} {f : σ → τ} [AddCommMonoid M] [PartialOrder M] [CanonicallyOrderedAdd M] {x : τ →₀ M} (hf : Set.InjOn f (f ⁻¹' x.support)) : degree (x.comapDomain f hf) ≤ degree x := by @@ -329,6 +330,7 @@ lemma nsmul_single_one_image {α : Type*} {n : ℕ} {s : Set α} : (show single i 1 ≤ f by simpa [Nat.one_le_iff_ne_zero] using hi) exact ⟨x, by aesop (add simp Set.subset_def), _, ⟨_, f_supp (by simp_all), rfl⟩, hx.symm⟩ +set_option backward.isDefEq.respectTransparency false in open scoped Pointwise in theorem image_pow_eq_finsuppProd_image {α β : Type*} [CommMonoid β] {f : α → β} {n} {s : Set α} : (f '' s) ^ n = (·.prod (f · ^ ·)) '' {x : α →₀ ℕ | x.degree = n ∧ ↑x.support ⊆ s} := by diff --git a/Mathlib/Data/Fintype/Basic.lean b/Mathlib/Data/Fintype/Basic.lean index 67f724a64a660c..dfffdca072f2c3 100644 --- a/Mathlib/Data/Fintype/Basic.lean +++ b/Mathlib/Data/Fintype/Basic.lean @@ -148,12 +148,12 @@ theorem Fintype.univ_bool : @univ Bool _ = {true, false} := rfl /-- Given that `α × β` is a fintype, `α` is also a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def Fintype.prodLeft {α β} [DecidableEq α] [Fintype (α × β)] [Nonempty β] : Fintype α := ⟨(@univ (α × β) _).image Prod.fst, fun a => by simp⟩ /-- Given that `α × β` is a fintype, `β` is also a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def Fintype.prodRight {α β} [DecidableEq β] [Fintype (α × β)] [Nonempty α] : Fintype β := ⟨(@univ (α × β) _).image Prod.snd, fun b => by simp⟩ diff --git a/Mathlib/Data/Fintype/Card.lean b/Mathlib/Data/Fintype/Card.lean index cc275a389de665..b3e4c624bb749c 100644 --- a/Mathlib/Data/Fintype/Card.lean +++ b/Mathlib/Data/Fintype/Card.lean @@ -213,13 +213,13 @@ theorem Fintype.card_subtype_true [Fintype α] {h : Fintype {_a : α // True}} : /-- Given that `α ⊕ β` is a fintype, `α` is also a fintype. This is non-computable as it uses that `Sum.inl` is an injection, but there's no clear inverse if `α` is empty. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Fintype.sumLeft {α β} [Fintype (α ⊕ β)] : Fintype α := Fintype.ofInjective (Sum.inl : α → α ⊕ β) Sum.inl_injective /-- Given that `α ⊕ β` is a fintype, `β` is also a fintype. This is non-computable as it uses that `Sum.inr` is an injection, but there's no clear inverse if `β` is empty. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Fintype.sumRight {α β} [Fintype (α ⊕ β)] : Fintype β := Fintype.ofInjective (Sum.inr : β → α ⊕ β) Sum.inr_injective @@ -270,6 +270,7 @@ theorem card_lt_of_injective_not_surjective (f : α → β) (h : Function.Inject theorem card_le_of_surjective (f : α → β) (h : Function.Surjective f) : card β ≤ card α := card_le_of_injective _ (Function.injective_surjInv h) +set_option backward.isDefEq.respectTransparency false in theorem card_range_le {α β : Type*} (f : α → β) [Fintype α] [Fintype (Set.range f)] : Fintype.card (Set.range f) ≤ Fintype.card α := Fintype.card_le_of_surjective (fun a => ⟨f a, by simp⟩) fun ⟨_, a, ha⟩ => ⟨a, by simpa using ha⟩ diff --git a/Mathlib/Data/Fintype/Defs.lean b/Mathlib/Data/Fintype/Defs.lean index 7fc7c24f360dd6..c9fab2c73ea097 100644 --- a/Mathlib/Data/Fintype/Defs.lean +++ b/Mathlib/Data/Fintype/Defs.lean @@ -262,14 +262,14 @@ instance (α : Type*) : Lean.Meta.FastSubsingleton (Fintype α) := {} /-- Given a predicate that can be represented by a finset, the subtype associated to the predicate is a fintype. -/ -@[implicit_reducible] +@[instance_reducible] protected def subtype {p : α → Prop} (s : Finset α) (H : ∀ x : α, x ∈ s ↔ p x) : Fintype { x // p x } := ⟨⟨s.1.pmap Subtype.mk fun x => (H x).1, s.nodup.pmap fun _ _ _ _ => congr_arg Subtype.val⟩, fun ⟨x, px⟩ => Multiset.mem_pmap.2 ⟨x, (H x).2 px, rfl⟩⟩ /-- Construct a fintype from a finset with the same elements. -/ -@[implicit_reducible] +@[instance_reducible] def ofFinset {p : Set α} (s : Finset α) (H : ∀ x, x ∈ s ↔ x ∈ p) : Fintype p := Fintype.subtype s H diff --git a/Mathlib/Data/Fintype/EquivFin.lean b/Mathlib/Data/Fintype/EquivFin.lean index 00976b3e45105a..da18f6fa261c2e 100644 --- a/Mathlib/Data/Fintype/EquivFin.lean +++ b/Mathlib/Data/Fintype/EquivFin.lean @@ -409,7 +409,7 @@ theorem isEmpty_fintype {α : Type*} : IsEmpty (Fintype α) ↔ Infinite α := ⟨fun ⟨h⟩ => ⟨fun h' => (@nonempty_fintype α h').elim h⟩, fun ⟨h⟩ => ⟨fun h' => h h'.finite⟩⟩ /-- A non-infinite type is a fintype. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfNotInfinite {α : Type*} (h : ¬Infinite α) : Fintype α := @Fintype.ofFinite _ (not_infinite_iff_finite.mp h) @@ -574,7 +574,7 @@ theorem exists_superset_card_eq [Infinite α] (s : Finset α) (n : ℕ) (hn : #s end Infinite /-- If every finset in a type has bounded cardinality, that type is finite. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfFinsetCardLe {ι : Type*} (n : ℕ) (w : ∀ s : Finset ι, #s ≤ n) : Fintype ι := by apply fintypeOfNotInfinite diff --git a/Mathlib/Data/Fintype/OfMap.lean b/Mathlib/Data/Fintype/OfMap.lean index 3ce4dfb8d64892..30f53d2f7f648b 100644 --- a/Mathlib/Data/Fintype/OfMap.lean +++ b/Mathlib/Data/Fintype/OfMap.lean @@ -37,24 +37,24 @@ open Finset namespace Fintype /-- Construct a proof of `Fintype α` from a universal multiset -/ -@[implicit_reducible] +@[instance_reducible] def ofMultiset [DecidableEq α] (s : Multiset α) (H : ∀ x : α, x ∈ s) : Fintype α := ⟨s.toFinset, by simpa using H⟩ /-- Construct a proof of `Fintype α` from a universal list -/ -@[implicit_reducible] +@[instance_reducible] def ofList [DecidableEq α] (l : List α) (H : ∀ x : α, x ∈ l) : Fintype α := ⟨l.toFinset, by simpa using H⟩ /-- If `f : α → β` is a bijection and `α` is a fintype, then `β` is also a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def ofBijective [Fintype α] (f : α → β) (H : Function.Bijective f) : Fintype β := ⟨univ.map ⟨f, H.1⟩, fun b => let ⟨_, e⟩ := H.2 b e ▸ mem_map_of_mem _ (mem_univ _)⟩ /-- If `f : α → β` is a surjection and `α` is a fintype, then `β` is also a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def ofSurjective [DecidableEq β] [Fintype α] (f : α → β) (H : Function.Surjective f) : Fintype β := ⟨univ.image f, fun b => let ⟨_, e⟩ := H b @@ -63,7 +63,7 @@ def ofSurjective [DecidableEq β] [Fintype α] (f : α → β) (H : Function.Sur /-- Given an injective function to a fintype, the domain is also a fintype. This is noncomputable because injectivity alone cannot be used to construct preimages. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofInjective [Fintype β] (f : α → β) (H : Function.Injective f) : Fintype α := letI := Classical.dec if hα : Nonempty α then @@ -72,12 +72,12 @@ noncomputable def ofInjective [Fintype β] (f : α → β) (H : Function.Injecti else ⟨∅, fun x => (hα ⟨x⟩).elim⟩ /-- If `f : α ≃ β` and `α` is a fintype, then `β` is also a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv (α : Type*) [Fintype α] (f : α ≃ β) : Fintype β := ofBijective _ f.bijective /-- Any subsingleton type with a witness is a fintype (with one term). -/ -@[implicit_reducible] +@[instance_reducible] def ofSubsingleton (a : α) [Subsingleton α] : Fintype α := ⟨{a}, fun _ => Finset.mem_singleton.2 (Subsingleton.elim _ _)⟩ @@ -88,7 +88,7 @@ theorem univ_ofSubsingleton (a : α) [Subsingleton α] : @univ _ (ofSubsingleton /-- An empty type is a fintype. Not registered as an instance, to make sure that there aren't two conflicting `Fintype ι` instances around when casing over whether a fintype `ι` is empty or not. -/ -@[implicit_reducible] +@[instance_reducible] def ofIsEmpty [IsEmpty α] : Fintype α := ⟨∅, isEmptyElim⟩ diff --git a/Mathlib/Data/Fintype/Option.lean b/Mathlib/Data/Fintype/Option.lean index 8fc9cd0d1c2da6..9c26723393dcda 100644 --- a/Mathlib/Data/Fintype/Option.lean +++ b/Mathlib/Data/Fintype/Option.lean @@ -42,13 +42,13 @@ theorem Fintype.card_option {α : Type*} [Fintype α] : (Finset.card_cons (by simp)).trans <| congr_arg₂ _ (card_map _) rfl /-- If `Option α` is a `Fintype` then so is `α` -/ -@[implicit_reducible] +@[instance_reducible] def fintypeOfOption {α : Type*} [Fintype (Option α)] : Fintype α := ⟨Finset.eraseNone (Fintype.elems (α := Option α)), fun x => mem_eraseNone.mpr (Fintype.complete (some x))⟩ /-- A type is a `Fintype` if its successor (using `Option`) is a `Fintype`. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeOfOptionEquiv [Fintype α] (f : α ≃ Option β) : Fintype β := haveI := Fintype.ofEquiv _ f fintypeOfOption diff --git a/Mathlib/Data/Fintype/Perm.lean b/Mathlib/Data/Fintype/Perm.lean index a4a737faf41892..49f2a6858afe5e 100644 --- a/Mathlib/Data/Fintype/Perm.lean +++ b/Mathlib/Data/Fintype/Perm.lean @@ -114,6 +114,7 @@ theorem nodup_permsOfList : ∀ {l : List α}, l.Nodup → (permsOfList l).Nodup have hxa : x ≠ g.symm x := fun h => (List.nodup_cons.1 hl).1 (h ▸ hx) exact (List.nodup_cons.1 hl).1 <| mem_of_mem_permsOfList hg.1 (by simpa using hxa) +set_option backward.isDefEq.respectTransparency false in /-- Given a finset, produce the finset of all permutations of its elements. -/ def permsOfFinset (s : Finset α) : Finset (Perm α) := Quotient.hrecOn s.1 (fun l hl => ⟨permsOfList l, nodup_permsOfList hl⟩) @@ -130,7 +131,7 @@ theorem card_perms_of_finset : ∀ s : Finset α, #(permsOfFinset s) = (#s)! := rintro ⟨⟨l⟩, hs⟩; exact length_permsOfList l /-- The collection of permutations of a fintype is a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def fintypePerm [Fintype α] : Fintype (Perm α) := ⟨permsOfFinset (@Finset.univ α _), by simp [mem_perms_of_finset_iff]⟩ diff --git a/Mathlib/Data/Fintype/Quotient.lean b/Mathlib/Data/Fintype/Quotient.lean index 8e49465af83b43..b104847587c83e 100644 --- a/Mathlib/Data/Fintype/Quotient.lean +++ b/Mathlib/Data/Fintype/Quotient.lean @@ -176,7 +176,7 @@ def finRecOn {C : (∀ i, Quotient (S i)) → Sort*} (h : ∀ (a b : ∀ i, α i) (h : ∀ i, a i ≈ b i), Eq.ndrec (f a) (funext fun i ↦ Quotient.sound (h i)) = f b) : C q := - finHRecOn q f (eqRec_heq_iff_heq.mp <| heq_of_eq <| h · · ·) + finHRecOn q f (eqRec_heq_iff.mp <| heq_of_eq <| h · · ·) @[simp] lemma finHRecOn_mk {C : (∀ i, Quotient (S i)) → Sort*} @@ -240,6 +240,7 @@ def finRecOn {C : (∀ i, Trunc (α i)) → Sort*} C q := Quotient.finRecOn q (f ·) (fun _ _ _ ↦ h _ _) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma finRecOn_mk {C : (∀ i, Trunc (α i)) → Sort*} (a : ∀ i, α i) : diff --git a/Mathlib/Data/Fintype/Sets.lean b/Mathlib/Data/Fintype/Sets.lean index caeec87ea8355f..e095956db78eae 100644 --- a/Mathlib/Data/Fintype/Sets.lean +++ b/Mathlib/Data/Fintype/Sets.lean @@ -250,6 +250,7 @@ instance FinsetCoe.fintype (s : Finset α) : Fintype (↑s : Set α) := theorem Finset.attach_eq_univ {s : Finset α} : s.attach = Finset.univ := rfl +set_option backward.isDefEq.respectTransparency false in instance Prop.fintype : Fintype Prop := ⟨⟨{True, False}, by simp⟩, by simpa using em⟩ @@ -261,7 +262,7 @@ instance Subtype.fintype (p : α → Prop) [DecidablePred p] [Fintype α] : Fint Fintype.subtype (univ.filter p) (by simp) /-- A set on a fintype, when coerced to a type, is a fintype. -/ -@[implicit_reducible] +@[instance_reducible] def setFintype [Fintype α] (s : Set α) [DecidablePred (· ∈ s)] : Fintype s := Subtype.fintype fun x => x ∈ s @@ -280,6 +281,7 @@ noncomputable def finsetEquivSet : Finset α ≃ Set α where @[simp] lemma finsetEquivSet_apply (s : Finset α) : finsetEquivSet s = s := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma finsetEquivSet_symm_apply (s : Set α) [Fintype s] : finsetEquivSet.symm s = s.toFinset := by simp [finsetEquivSet] diff --git a/Mathlib/Data/Fintype/Sum.lean b/Mathlib/Data/Fintype/Sum.lean index 8cdff49ee8cfac..f81e74ea2f2cfc 100644 --- a/Mathlib/Data/Fintype/Sum.lean +++ b/Mathlib/Data/Fintype/Sum.lean @@ -65,7 +65,7 @@ theorem Fintype.card_sum [Fintype α] [Fintype β] : card_disjSum _ _ /-- If the subtype of all-but-one elements is a `Fintype` then the type itself is a `Fintype`. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeOfFintypeNe (a : α) (_ : Fintype { b // b ≠ a }) : Fintype α := Fintype.ofBijective (Sum.elim ((↑) : { b // b = a } → α) ((↑) : { b // b ≠ a } → α)) <| by classical exact (Equiv.sumCompl (· = a)).bijective diff --git a/Mathlib/Data/FunLike/Fintype.lean b/Mathlib/Data/FunLike/Fintype.lean index 1934baab8c283f..2435449f1e1318 100644 --- a/Mathlib/Data/FunLike/Fintype.lean +++ b/Mathlib/Data/FunLike/Fintype.lean @@ -41,7 +41,7 @@ This is not an instance because specific `DFunLike` types might have a better-su See also `DFunLike.finite`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def DFunLike.fintype [DecidableEq α] [Fintype α] [∀ i, Fintype (β i)] : Fintype F := Fintype.ofInjective _ DFunLike.coe_injective @@ -50,7 +50,7 @@ noncomputable def DFunLike.fintype [DecidableEq α] [Fintype α] [∀ i, Fintype Non-dependent version of `DFunLike.fintype` that might be easier to infer. This is not an instance because specific `FunLike` types might have a better-suited definition. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def FunLike.fintype [DecidableEq α] [Fintype α] [Fintype γ] : Fintype G := DFunLike.fintype G diff --git a/Mathlib/Data/Holor.lean b/Mathlib/Data/Holor.lean index b7475620ba7423..84cbada413acb0 100644 --- a/Mathlib/Data/Holor.lean +++ b/Mathlib/Data/Holor.lean @@ -144,6 +144,7 @@ def assocRight : Holor α (ds₁ ++ ds₂ ++ ds₃) → Holor α (ds₁ ++ (ds def assocLeft : Holor α (ds₁ ++ (ds₂ ++ ds₃)) → Holor α (ds₁ ++ ds₂ ++ ds₃) := cast (congr_arg (Holor α) (append_assoc ds₁ ds₂ ds₃).symm) +set_option backward.isDefEq.respectTransparency false in theorem mul_assoc0 [Semigroup α] (x : Holor α ds₁) (y : Holor α ds₂) (z : Holor α ds₃) : x ⊗ y ⊗ z = (x ⊗ (y ⊗ z)).assocLeft := funext fun t : HolorIndex (ds₁ ++ ds₂ ++ ds₃) => by @@ -171,6 +172,7 @@ nonrec theorem zero_mul {α : Type} [MulZeroClass α] (x : Holor α ds₂) : (0 nonrec theorem mul_zero {α : Type} [MulZeroClass α] (x : Holor α ds₁) : x ⊗ (0 : Holor α ds₂) = 0 := funext fun t => mul_zero (x (HolorIndex.take t)) +set_option backward.isDefEq.respectTransparency false in theorem mul_scalar_mul [Mul α] (x : Holor α []) (y : Holor α ds) : x ⊗ y = x ⟨[], Forall₂.nil⟩ • y := by simp +unfoldPartialApp [mul, SMul.smul, HolorIndex.take, HolorIndex.drop, @@ -203,6 +205,7 @@ theorem slice_eq (x : Holor α (d :: ds)) (y : Holor α (d :: ds)) (h : slice x _ = slice y i hid ⟨is, hisds⟩ := by rw [h] _ = y ⟨i :: is, _⟩ := congr_arg y (Subtype.ext rfl) +set_option backward.isDefEq.respectTransparency false in theorem slice_unitVec_mul [Semiring α] {i : ℕ} {j : ℕ} (hid : i < d) (x : Holor α ds) : slice (unitVec d j ⊗ x) i hid = if i = j then x else 0 := funext fun t : HolorIndex ds => diff --git a/Mathlib/Data/Int/Cast/Lemmas.lean b/Mathlib/Data/Int/Cast/Lemmas.lean index d489daad0ca412..1134ae91911a61 100644 --- a/Mathlib/Data/Int/Cast/Lemmas.lean +++ b/Mathlib/Data/Int/Cast/Lemmas.lean @@ -81,7 +81,7 @@ variable [NonAssocRing α] variable (α) in /-- `coe : ℤ → α` as a `RingHom`. -/ -@[implicit_reducible] +@[instance_reducible] def castRingHom : ℤ →+* α where toFun := Int.cast map_zero' := cast_zero diff --git a/Mathlib/Data/Int/ConditionallyCompleteOrder.lean b/Mathlib/Data/Int/ConditionallyCompleteOrder.lean index 579381997ebb1b..7b15b462c15526 100644 --- a/Mathlib/Data/Int/ConditionallyCompleteOrder.lean +++ b/Mathlib/Data/Int/ConditionallyCompleteOrder.lean @@ -24,6 +24,7 @@ noncomputable section namespace Int +set_option backward.isDefEq.respectTransparency false in open scoped Classical in instance : ConditionallyCompleteLinearOrder ℤ where __ := instLinearOrder @@ -45,6 +46,7 @@ instance : ConditionallyCompleteLinearOrder ℤ where csSup_of_not_bddAbove := fun s hs ↦ by simp [hs] csInf_of_not_bddBelow := fun s hs ↦ by simp [hs] +set_option backward.isDefEq.respectTransparency false in theorem csSup_eq_greatestOfBdd {s : Set ℤ} [DecidablePred (· ∈ s)] (b : ℤ) (Hb : ∀ z ∈ s, z ≤ b) (Hinh : ∃ z : ℤ, z ∈ s) : sSup s = greatestOfBdd b Hb Hinh := by have : s.Nonempty ∧ BddAbove s := ⟨Hinh, b, Hb⟩ @@ -58,6 +60,7 @@ theorem csSup_empty : sSup (∅ : Set ℤ) = 0 := theorem csSup_of_not_bddAbove {s : Set ℤ} (h : ¬BddAbove s) : sSup s = 0 := dif_neg (by simp [h]) +set_option backward.isDefEq.respectTransparency false in theorem csInf_eq_leastOfBdd {s : Set ℤ} [DecidablePred (· ∈ s)] (b : ℤ) (Hb : ∀ z ∈ s, b ≤ z) (Hinh : ∃ z : ℤ, z ∈ s) : sInf s = leastOfBdd b Hb Hinh := by have : s.Nonempty ∧ BddBelow s := ⟨Hinh, b, Hb⟩ diff --git a/Mathlib/Data/Int/WithZero.lean b/Mathlib/Data/Int/WithZero.lean index 85f9a898ef47b2..7c6b5481f804ef 100644 --- a/Mathlib/Data/Int/WithZero.lean +++ b/Mathlib/Data/Int/WithZero.lean @@ -62,6 +62,7 @@ theorem toNNReal_pos_apply {e : ℝ≥0} (he : e ≠ 0) {x : ℤᵐ⁰} (hx : x toNNReal he x = 0 := by simp [toNNReal, hx] +set_option backward.isDefEq.respectTransparency false in theorem toNNReal_neg_apply {e : ℝ≥0} (he : e ≠ 0) {x : ℤᵐ⁰} (hx : x ≠ 0) : toNNReal he x = e ^ (WithZero.unzero hx).toAdd := by simp [toNNReal, hx] @@ -74,6 +75,7 @@ theorem toNNReal_ne_zero {e : ℝ≥0} {m : ℤᵐ⁰} (he : e ≠ 0) (hm : m theorem toNNReal_pos {e : ℝ≥0} {m : ℤᵐ⁰} (he : e ≠ 0) (hm : m ≠ 0) : 0 < toNNReal he m := (toNNReal_ne_zero he hm).pos +set_option backward.isDefEq.respectTransparency false in /-- The map `toNNReal` is strictly monotone whenever `1 < e`. -/ theorem toNNReal_strictMono {e : ℝ≥0} (he : 1 < e) : StrictMono (toNNReal he.ne_zero) := by diff --git a/Mathlib/Data/List/Cycle.lean b/Mathlib/Data/List/Cycle.lean index 279622cb6c048c..986d0000f82106 100644 --- a/Mathlib/Data/List/Cycle.lean +++ b/Mathlib/Data/List/Cycle.lean @@ -651,6 +651,7 @@ def lists (s : Cycle α) : Multiset (List α) := theorem lists_coe (l : List α) : lists (l : Cycle α) = ↑l.cyclicPermutations := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mem_lists_iff_coe_eq {s : Cycle α} {l : List α} : l ∈ s.lists ↔ (l : Cycle α) = s := Quotient.inductionOn' s fun l => by diff --git a/Mathlib/Data/List/GetD.lean b/Mathlib/Data/List/GetD.lean index b1f7dde5cfbddb..296b75d1659c7e 100644 --- a/Mathlib/Data/List/GetD.lean +++ b/Mathlib/Data/List/GetD.lean @@ -52,7 +52,7 @@ theorem getD_reverse {l : List α} (i) (h : i < length l) : /-- An empty list can always be decidably checked for the presence of an element. Not an instance because it would clash with `DecidableEq α`. -/ -@[implicit_reducible] +@[instance_reducible] def decidableGetDNilNe (a : α) : DecidablePred fun i : ℕ => getD ([] : List α) i a ≠ a := fun _ => isFalse fun H => H getD_nil diff --git a/Mathlib/Data/List/NodupEquivFin.lean b/Mathlib/Data/List/NodupEquivFin.lean index b83f749ef874f6..4f9d7d18d104e9 100644 --- a/Mathlib/Data/List/NodupEquivFin.lean +++ b/Mathlib/Data/List/NodupEquivFin.lean @@ -133,6 +133,7 @@ theorem sublist_of_orderEmbedding_getElem?_eq {l l' : List α} (f : ℕ ↪o ℕ rw [List.singleton_sublist, ← h, l'.getElem_take' _ (Nat.lt_succ_self _)] exact List.getElem_mem _ +set_option backward.isDefEq.respectTransparency.types false in /-- A `l : List α` is `Sublist l l'` for `l' : List α` iff there is `f`, an order-preserving embedding of `ℕ` into `ℕ` such that any element of `l` found at index `ix` can be found at index `f ix` in `l'`. diff --git a/Mathlib/Data/List/Rotate.lean b/Mathlib/Data/List/Rotate.lean index a1d807b280cad2..cccd7bf7284920 100644 --- a/Mathlib/Data/List/Rotate.lean +++ b/Mathlib/Data/List/Rotate.lean @@ -396,7 +396,7 @@ theorem IsRotated.eqv : Equivalence (@IsRotated α) := Equivalence.mk IsRotated.refl IsRotated.symm IsRotated.trans /-- The relation `List.IsRotated l l'` forms a `Setoid` of cycles. -/ -@[implicit_reducible] +@[instance_reducible] def IsRotated.setoid (α : Type*) : Setoid (List α) where r := IsRotated iseqv := IsRotated.eqv diff --git a/Mathlib/Data/Matrix/Basic.lean b/Mathlib/Data/Matrix/Basic.lean index 6511fb8b1a3a9d..54f5e239dbde0d 100644 --- a/Mathlib/Data/Matrix/Basic.lean +++ b/Mathlib/Data/Matrix/Basic.lean @@ -652,6 +652,7 @@ def mopMatrix {α} [Mul α] [AddCommMonoid α] : Matrix m m αᵐᵒᵖ ≃+* (M end RingEquiv +set_option backward.isDefEq.respectTransparency false in instance (α) [MulOne α] [AddCommMonoid α] [IsStablyFiniteRing α] : IsStablyFiniteRing αᵐᵒᵖ where isDedekindFiniteMonoid n := .of_injective (MonoidHom.mk ⟨RingEquiv.mopMatrix, by simp⟩ RingEquiv.mopMatrix.map_mul) (RingEquiv.injective _) diff --git a/Mathlib/Data/Matrix/Basis.lean b/Mathlib/Data/Matrix/Basis.lean index beb390268e28a8..4cf260f92e8301 100644 --- a/Mathlib/Data/Matrix/Basis.lean +++ b/Mathlib/Data/Matrix/Basis.lean @@ -267,6 +267,7 @@ theorem liftLinear_apply (f : m → n → α →ₗ[R] β) (M : Matrix m n α) : simp [liftLinear, map_sum, LinearEquiv.congrLeft] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] theorem liftLinear_single (f : m → n → α →ₗ[R] β) (i : m) (j : n) (a : α) : liftLinear S f (Matrix.single i j a) = f i j a := by diff --git a/Mathlib/Data/Matrix/Block.lean b/Mathlib/Data/Matrix/Block.lean index 2bbc15b78771da..6da760144a3f2b 100644 --- a/Mathlib/Data/Matrix/Block.lean +++ b/Mathlib/Data/Matrix/Block.lean @@ -857,6 +857,7 @@ lemma Matrix.comp_toSquareBlock {b : m → α} variable [Zero R] [DecidableEq m] +set_option backward.isDefEq.respectTransparency false in lemma Matrix.comp_diagonal (d) : comp m m n n R (diagonal d) = (blockDiagonal d).reindex (.prodComm ..) (.prodComm ..) := by diff --git a/Mathlib/Data/Matrix/ColumnRowPartitioned.lean b/Mathlib/Data/Matrix/ColumnRowPartitioned.lean index a8a5d1df9f9d36..b4ef363c5412f2 100644 --- a/Mathlib/Data/Matrix/ColumnRowPartitioned.lean +++ b/Mathlib/Data/Matrix/ColumnRowPartitioned.lean @@ -189,6 +189,7 @@ lemma vecMul_fromCols [Fintype m] (B₁ : Matrix m n₁ R) (B₂ : Matrix m n₂ v ᵥ* fromCols B₁ B₂ = Sum.elim (v ᵥ* B₁) (v ᵥ* B₂) := by ext (_ | _) <;> rfl +set_option backward.isDefEq.respectTransparency false in lemma sumElim_vecMul_fromRows [Fintype m₁] [Fintype m₂] (B₁ : Matrix m₁ n R) (B₂ : Matrix m₂ n R) (v₁ : m₁ → R) (v₂ : m₂ → R) : Sum.elim v₁ v₂ ᵥ* fromRows B₁ B₂ = v₁ ᵥ* B₁ + v₂ ᵥ* B₂ := by diff --git a/Mathlib/Data/Matrix/Composition.lean b/Mathlib/Data/Matrix/Composition.lean index 779704cb57bfd1..ff6cffa09c5c68 100644 --- a/Mathlib/Data/Matrix/Composition.lean +++ b/Mathlib/Data/Matrix/Composition.lean @@ -41,6 +41,7 @@ def comp : Matrix I J (Matrix K L R) ≃ Matrix (I × K) (J × L) R where section Basic variable {R I J K L} +set_option backward.isDefEq.respectTransparency false in theorem comp_one [DecidableEq I] [DecidableEq J] [Zero R] [One R] : comp I I J J R 1 = 1 := by ext; simp only [comp, Equiv.coe_fn_mk, one_apply, apply_ite]; aesop diff --git a/Mathlib/Data/Matrix/Mul.lean b/Mathlib/Data/Matrix/Mul.lean index 19bcf3414eab9c..35e734e219e8e4 100644 --- a/Mathlib/Data/Matrix/Mul.lean +++ b/Mathlib/Data/Matrix/Mul.lean @@ -947,9 +947,11 @@ section NonAssocSemiring variable [NonAssocSemiring α] +set_option backward.isDefEq.respectTransparency false in theorem mulVec_one [Fintype n] (A : Matrix m n α) : A *ᵥ 1 = ∑ j, Aᵀ j := by ext; simp [mulVec, dotProduct] +set_option backward.isDefEq.respectTransparency false in theorem one_vecMul [Fintype m] (A : Matrix m n α) : 1 ᵥ* A = ∑ i, A i := by ext; simp [vecMul, dotProduct] diff --git a/Mathlib/Data/Matrix/PEquiv.lean b/Mathlib/Data/Matrix/PEquiv.lean index 250d3ba13d01a0..dbf7e898046de6 100644 --- a/Mathlib/Data/Matrix/PEquiv.lean +++ b/Mathlib/Data/Matrix/PEquiv.lean @@ -156,6 +156,7 @@ theorem toMatrix_injective [DecidableEq n] [MulZeroOneClass α] [Nontrivial α] · use fi simp [hf.symm, Ne.symm hi] +set_option backward.isDefEq.respectTransparency false in theorem toMatrix_swap [DecidableEq n] [AddGroupWithOne α] (i j : n) : (Equiv.swap i j).toPEquiv.toMatrix = (1 : Matrix n n α) - (single i i).toMatrix - (single j j).toMatrix + (single i j).toMatrix + diff --git a/Mathlib/Data/Matrix/Reflection.lean b/Mathlib/Data/Matrix/Reflection.lean index 2c82f38918ffcc..0b8a9fec8e2d1e 100644 --- a/Mathlib/Data/Matrix/Reflection.lean +++ b/Mathlib/Data/Matrix/Reflection.lean @@ -91,6 +91,7 @@ def transposeᵣ : ∀ {m n}, Matrix (Fin m) (Fin n) α → Matrix (Fin n) (Fin | _, _ + 1, A => of <| vecCons (FinVec.map (fun v : Fin _ → α => v 0) A) (transposeᵣ (A.submatrix id Fin.succ)) +set_option backward.isDefEq.respectTransparency false in /-- This can be used to prove ```lean example (a b c d : α) : transpose !![a, b; c, d] = !![a, c; b, d] := (transposeᵣ_eq _).symm @@ -136,6 +137,7 @@ def mulᵣ [Mul α] [Add α] [Zero α] (A : Matrix (Fin l) (Fin m) α) (B : Matr Matrix (Fin l) (Fin n) α := of <| FinVec.map (fun v₁ => FinVec.map (fun v₂ => dotProductᵣ v₁ v₂) Bᵀ) A +set_option backward.isDefEq.respectTransparency false in /-- This can be used to prove ```lean example [AddCommMonoid α] [Mul α] (a₁₁ a₁₂ a₂₁ a₂₂ b₁₁ b₁₂ b₂₁ b₂₂ : α) : @@ -163,6 +165,7 @@ example [AddCommMonoid α] [Mul α] (a₁₁ a₁₂ a₂₁ a₂₂ b₁₁ b def mulVecᵣ [Mul α] [Add α] [Zero α] (A : Matrix (Fin l) (Fin m) α) (v : Fin m → α) : Fin l → α := FinVec.map (fun a => dotProductᵣ a v) A +set_option backward.isDefEq.respectTransparency false in /-- This can be used to prove ```lean example [NonUnitalNonAssocSemiring α] (a₁₁ a₁₂ a₂₁ a₂₂ b₁ b₂ : α) : @@ -185,6 +188,7 @@ example [NonUnitalNonAssocSemiring α] (a₁₁ a₁₂ a₂₁ a₂₂ b₁ b def vecMulᵣ [Mul α] [Add α] [Zero α] (v : Fin l → α) (A : Matrix (Fin l) (Fin m) α) : Fin m → α := FinVec.map (fun a => dotProductᵣ v a) Aᵀ +set_option backward.isDefEq.respectTransparency false in /-- This can be used to prove ```lean example [NonUnitalNonAssocSemiring α] (a₁₁ a₁₂ a₂₁ a₂₂ b₁ b₂ : α) : diff --git a/Mathlib/Data/Multiset/Bind.lean b/Mathlib/Data/Multiset/Bind.lean index 67847083f94b3d..b35d48970e9f00 100644 --- a/Mathlib/Data/Multiset/Bind.lean +++ b/Mathlib/Data/Multiset/Bind.lean @@ -342,6 +342,7 @@ variable {s t} protected theorem Nodup.product : Nodup s → Nodup t → Nodup (s ×ˢ t) := Quotient.inductionOn₂ s t fun l₁ l₂ d₁ d₂ => by simp [List.Nodup.product d₁ d₂] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma map_swap_product (s : Multiset α) (t : Multiset β) : (s ×ˢ t).map Prod.swap = t ×ˢ s := by induction s using Multiset.induction <;> simp_all diff --git a/Mathlib/Data/Multiset/Filter.lean b/Mathlib/Data/Multiset/Filter.lean index 4cbbb1ef3cc715..b921fe0cd5676c 100644 --- a/Mathlib/Data/Multiset/Filter.lean +++ b/Mathlib/Data/Multiset/Filter.lean @@ -414,11 +414,11 @@ for more discussion. @[simp] theorem map_count_True_eq_filter_card (s : Multiset α) (p : α → Prop) [DecidablePred p] : (s.map p).count True = card (s.filter p) := by - simp only [count_eq_card_filter_eq, filter_map, card_map, Function.id_comp, - eq_true_eq_id, Function.comp_apply] + simp only [count_eq_card_filter_eq, eq_iff_iff, true_iff, filter_map, comp_apply, card_map] section Map +set_option backward.isDefEq.respectTransparency false in lemma filter_attach' (s : Multiset α) (p : {a // a ∈ s} → Prop) [DecidableEq α] [DecidablePred p] : s.attach.filter p = @@ -426,8 +426,8 @@ lemma filter_attach' (s : Multiset α) (p : {a // a ∈ s} → Prop) [DecidableE classical refine Multiset.map_injective Subtype.val_injective ?_ rw [map_filter' _ Subtype.val_injective] - simp only [Function.comp, Subtype.exists, Subtype.map, - exists_and_right, exists_eq_right, attach_map_val, map_map, id] + simp only [Subtype.exists, exists_and_right, exists_eq_right, attach_map_val, Subtype.map, id, + map_map, comp] end Map diff --git a/Mathlib/Data/Multiset/Find.lean b/Mathlib/Data/Multiset/Find.lean index 298c7d93e52245..873d882493e02b 100644 --- a/Mathlib/Data/Multiset/Find.lean +++ b/Mathlib/Data/Multiset/Find.lean @@ -30,7 +30,7 @@ and is like `Multiset.choose`, but `Option`-valued. -/ rw [eqRec_eq_cast, cast_eq_iff_heq] refine Function.hfunext ?_ (fun hp₁ hp₂ _ ↦ heq_of_eq ?_) · congr! - exact Quotient.sound h + exact congrArg _ (Quotient.sound h) refine List.find?_eq_find?_of_perm h ?_ simpa using hp₁ @@ -98,7 +98,8 @@ theorem find?_congr {p₁ p₂ : α → Prop} [DecidablePred p₁] [DecidablePre (hp₁ : {x ∈ s | p₁ x}.Subsingleton) (h : ∀ x ∈ s, p₁ x ↔ p₂ x) : s.find? p₁ hp₁ = s.find? p₂ (by simp_rw +contextual [← exists_prop, ← h, exists_prop, hp₁]) := by - induction s using Quotient.ind with simp +contextual [h] + induction s using Quotient.ind + exact List.find?_congr fun x hx ↦ by simp [h x (by simpa using hx)] theorem find?_eq_choose {s : Multiset α} (hp : ∃! x, x ∈ s ∧ p x) : s.find? p hp.setSubsingleton = some (s.choose p hp) := by diff --git a/Mathlib/Data/Multiset/Fintype.lean b/Mathlib/Data/Multiset/Fintype.lean index 86bbabe5f518f5..eec7d8ce4fb54c 100644 --- a/Mathlib/Data/Multiset/Fintype.lean +++ b/Mathlib/Data/Multiset/Fintype.lean @@ -78,6 +78,7 @@ protected theorem exists_coe (p : m → Prop) : (∃ x : m, p x) ↔ ∃ (x : α) (i : Fin (m.count x)), p ⟨x, i⟩ := Sigma.exists +set_option backward.isDefEq.respectTransparency false in instance : Fintype { p : α × ℕ | p.2 < m.count p.1 } := Fintype.ofFinset (m.toFinset.disjiUnion @@ -194,6 +195,7 @@ theorem map_univ_comp_coe {β : Type*} (m : Multiset α) (f : α → β) : ((Finset.univ : Finset m).val.map (f ∘ (fun x : m ↦ (x : α)))) = m.map f := by rw [← Multiset.map_map, Multiset.map_univ_coe] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_univ {β : Type*} (m : Multiset α) (f : α → β) : ((Finset.univ : Finset m).val.map fun (x : m) ↦ f (x : α)) = m.map f := by @@ -242,6 +244,7 @@ instance : IsEmpty (0 : Multiset α) := Fintype.card_eq_zero_iff.mp (by simp) instance : IsEmpty (∅ : Multiset α) := Fintype.card_eq_zero_iff.mp (by simp) +set_option backward.isDefEq.respectTransparency false in /-- `v ::ₘ m` is equivalent to `Option m` by mapping one `v` to `none` and everything else to `m`. -/ diff --git a/Mathlib/Data/Multiset/Functor.lean b/Mathlib/Data/Multiset/Functor.lean index 8eebd63ab65db1..40e512c34cade4 100644 --- a/Mathlib/Data/Multiset/Functor.lean +++ b/Mathlib/Data/Multiset/Functor.lean @@ -95,6 +95,7 @@ theorem id_traverse {α : Type*} (x : Multiset α) : traverse (pure : α → Id induction x using Quotient.inductionOn simp [traverse] +set_option backward.isDefEq.respectTransparency false in theorem comp_traverse {G H : Type _ → Type _} [Applicative G] [Applicative H] [CommApplicative G] [CommApplicative H] {α β γ : Type _} (g : α → G β) (h : β → H γ) (x : Multiset α) : traverse (Comp.mk ∘ Functor.map h ∘ g) x = diff --git a/Mathlib/Data/Multiset/MapFold.lean b/Mathlib/Data/Multiset/MapFold.lean index 232137c36eb954..163ff154ba8b66 100644 --- a/Mathlib/Data/Multiset/MapFold.lean +++ b/Mathlib/Data/Multiset/MapFold.lean @@ -340,6 +340,7 @@ theorem attach_map_val' (s : Multiset α) (f : α → β) : (s.attach.map fun i theorem attach_map_val (s : Multiset α) : s.attach.map Subtype.val = s := (attach_map_val' _ _).trans s.map_id +set_option backward.isDefEq.respectTransparency false in theorem attach_cons (a : α) (m : Multiset α) : (a ::ₘ m).attach = ⟨a, mem_cons_self a m⟩ ::ₘ m.attach.map fun p => ⟨p.1, mem_cons_of_mem p.2⟩ := diff --git a/Mathlib/Data/Multiset/Powerset.lean b/Mathlib/Data/Multiset/Powerset.lean index b5341d26df26ec..bf6077e2eb5164 100644 --- a/Mathlib/Data/Multiset/Powerset.lean +++ b/Mathlib/Data/Multiset/Powerset.lean @@ -300,6 +300,7 @@ theorem powersetCard_self (s : Multiset α) : powersetCard s.card s = {s} := by | empty => simp | cons _ _ ih => simp [ih] +set_option backward.isDefEq.respectTransparency false in theorem powersetCard_map {β : Type*} (f : α → β) (n : ℕ) (s : Multiset α) : powersetCard n (s.map f) = (powersetCard n s).map (map f) := by induction s using Multiset.induction generalizing n with diff --git a/Mathlib/Data/NNRat/Defs.lean b/Mathlib/Data/NNRat/Defs.lean index 45c0f1a44c6012..776ba33529f3a0 100644 --- a/Mathlib/Data/NNRat/Defs.lean +++ b/Mathlib/Data/NNRat/Defs.lean @@ -253,6 +253,7 @@ theorem toNNRat_zero : toNNRat 0 = 0 := rfl @[simp] theorem toNNRat_one : toNNRat 1 = 1 := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toNNRat_pos : 0 < toNNRat q ↔ 0 < q := by simp [toNNRat, ← coe_lt_coe] @@ -262,10 +263,12 @@ theorem toNNRat_eq_zero : toNNRat q = 0 ↔ q ≤ 0 := by alias ⟨_, toNNRat_of_nonpos⟩ := toNNRat_eq_zero +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toNNRat_le_toNNRat_iff (hp : 0 ≤ p) : toNNRat q ≤ toNNRat p ↔ q ≤ p := by simp [← coe_le_coe, toNNRat, hp] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toNNRat_lt_toNNRat_iff' : toNNRat q < toNNRat p ↔ q < p ∧ 0 < p := by simp [← coe_lt_coe, toNNRat] @@ -276,6 +279,7 @@ theorem toNNRat_lt_toNNRat_iff (h : 0 < p) : toNNRat q < toNNRat p ↔ q < p := theorem toNNRat_lt_toNNRat_iff_of_nonneg (hq : 0 ≤ q) : toNNRat q < toNNRat p ↔ q < p := toNNRat_lt_toNNRat_iff'.trans ⟨And.left, fun h ↦ ⟨h, hq.trans_lt h⟩⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toNNRat_add (hq : 0 ≤ q) (hp : 0 ≤ p) : toNNRat (q + p) = toNNRat q + toNNRat p := NNRat.ext <| by simp [toNNRat, hq, hp, add_nonneg] @@ -299,6 +303,7 @@ theorem toNNRat_lt_iff_lt_coe {p : ℚ≥0} (hq : 0 ≤ q) : toNNRat q < p ↔ q theorem lt_toNNRat_iff_coe_lt {q : ℚ≥0} : q < toNNRat p ↔ ↑q < p := NNRat.gi.gc.lt_iff_lt +set_option backward.isDefEq.respectTransparency false in theorem toNNRat_mul (hp : 0 ≤ p) : toNNRat (p * q) = toNNRat p * toNNRat q := by rcases le_total 0 q with hq | hq · ext; simp [toNNRat, hp, hq, mul_nonneg] diff --git a/Mathlib/Data/Nat/Cast/Basic.lean b/Mathlib/Data/Nat/Cast/Basic.lean index 6e4afd091dc4ba..5a263f821b04ef 100644 --- a/Mathlib/Data/Nat/Cast/Basic.lean +++ b/Mathlib/Data/Nat/Cast/Basic.lean @@ -58,7 +58,7 @@ variable [NonAssocSemiring α] variable (α) in /-- `Nat.cast : ℕ → α` as a `RingHom` -/ -@[implicit_reducible] +@[instance_reducible] def castRingHom : ℕ →+* α := { castAddMonoidHom α with toFun := Nat.cast, map_one' := cast_one, map_mul' := cast_mul } diff --git a/Mathlib/Data/Nat/Choose/Multinomial.lean b/Mathlib/Data/Nat/Choose/Multinomial.lean index 93c5eea8d6b261..c064602ac4840a 100644 --- a/Mathlib/Data/Nat/Choose/Multinomial.lean +++ b/Mathlib/Data/Nat/Choose/Multinomial.lean @@ -264,6 +264,7 @@ variable [Semiring R] open scoped Function -- required for scoped `on` notation +set_option backward.isDefEq.respectTransparency false in -- TODO: Can we prove one of the following two from the other one? /-- The **multinomial theorem**. -/ lemma sum_pow_eq_sum_piAntidiag_of_commute (s : Finset α) (f : α → R) @@ -410,7 +411,6 @@ theorem Finsupp.multinomial_of_support_subset {σ : Type*} {d : σ →₀ ℕ} { namespace List -open Nat lemma toFinsupp_sum {α : Type*} [AddCommMonoid α] [DecidableEq α] (l : List α) : l.toFinsupp.sum (fun _ a ↦ a) = l.sum := by diff --git a/Mathlib/Data/Nat/Factorization/PrimePow.lean b/Mathlib/Data/Nat/Factorization/PrimePow.lean index 50d7b3f79a6823..b8246b11737b65 100644 --- a/Mathlib/Data/Nat/Factorization/PrimePow.lean +++ b/Mathlib/Data/Nat/Factorization/PrimePow.lean @@ -146,6 +146,7 @@ theorem Nat.mul_divisors_filter_prime_pow {a b : ℕ} (hab : a.Coprime b) : and_congr_left_iff, not_false_iff, Nat.mem_divisors, or_self_iff] apply hab.isPrimePow_dvd_mul +set_option backward.isDefEq.respectTransparency false in /-- The canonical equivalence between pairs `(p, k)` with `p` a prime and `k : ℕ` and the set of prime powers given by `(p, k) ↦ p^(k+1)`. -/ def Nat.Primes.prodNatEquiv : Nat.Primes × ℕ ≃ {n : ℕ // IsPrimePow n} where diff --git a/Mathlib/Data/Nat/Nth.lean b/Mathlib/Data/Nat/Nth.lean index 6b7f6d039fd65b..89c38d7c03cd3e 100644 --- a/Mathlib/Data/Nat/Nth.lean +++ b/Mathlib/Data/Nat/Nth.lean @@ -235,6 +235,7 @@ theorem nth_zero : nth p 0 = sInf (setOf p) := by rw [nth_eq_sInf]; simp @[simp] theorem nth_zero_of_zero (h : p 0) : nth p 0 = 0 := by simp [nth_zero, h] +set_option backward.isDefEq.respectTransparency false in theorem nth_zero_of_exists [DecidablePred p] (h : ∃ n, p n) : nth p 0 = Nat.find h := by rw [nth_zero]; convert! Nat.sInf_def h diff --git a/Mathlib/Data/Nat/Totient.lean b/Mathlib/Data/Nat/Totient.lean index 5c3cada18691a7..59083f41358979 100644 --- a/Mathlib/Data/Nat/Totient.lean +++ b/Mathlib/Data/Nat/Totient.lean @@ -55,7 +55,7 @@ theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n { toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using! m.property⟩ invFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using! m.property⟩ left_inv := fun m => by simp only [Subtype.coe_eta] - right_inv := fun m => by simp only [Subtype.coe_eta] } + right_inv := fun m => by simp only } rw [totient_eq_card_coprime, card_congr e, card_eq_fintype_card, Fintype.card_coe] theorem totient_le (n : ℕ) : φ n ≤ n := @@ -235,6 +235,7 @@ theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] : rw [ZMod.card_units_eq_totient p] exact Nat.le_sub_one_of_lt (Nat.totient_lt p hp) +set_option backward.isDefEq.respectTransparency false in theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] : p.Prime ↔ Fintype.card (ZMod p)ˣ = p - 1 := by rcases eq_zero_or_neZero p with rfl | hp diff --git a/Mathlib/Data/Ordmap/Invariants.lean b/Mathlib/Data/Ordmap/Invariants.lean index eaa66d0a90a320..88e8f969e186aa 100644 --- a/Mathlib/Data/Ordmap/Invariants.lean +++ b/Mathlib/Data/Ordmap/Invariants.lean @@ -553,6 +553,7 @@ theorem dual_insert [LE α] [@Std.Total α (· ≤ ·)] [DecidableLE α] (x : α /-! ### `balance` properties -/ +set_option backward.isDefEq.respectTransparency false in theorem balance_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l) (sr : Sized r) : @balance α l x r = balance' l x r := by obtain - | ⟨ls, ll, lx, lr⟩ := l diff --git a/Mathlib/Data/Ordmap/Ordset.lean b/Mathlib/Data/Ordmap/Ordset.lean index b3eef1d9dc8794..0b0671f9574e4a 100644 --- a/Mathlib/Data/Ordmap/Ordset.lean +++ b/Mathlib/Data/Ordmap/Ordset.lean @@ -387,6 +387,7 @@ theorem Valid'.eraseMax_aux {s l x r o₁ o₂} (H : Valid' o₁ (.node s l x r) rw [eraseMax, size_balanceL H.3.2.1 h.3 H.2.2.1 h.2 (Or.inr ⟨_, Or.inr e, H.3.1⟩)] rw [size_node, e]; rfl +set_option backward.isDefEq.respectTransparency false in theorem Valid'.eraseMin_aux {s l} {x : α} {r o₁ o₂} (H : Valid' o₁ (.node s l x r) o₂) : Valid' ↑(findMin' l x) (@eraseMin α (.node' l x r)) o₂ ∧ size (.node' l x r) = size (eraseMin (.node' l x r)) + 1 := by @@ -459,6 +460,7 @@ theorem Valid'.merge_aux₁ {o₁ o₂ ls ll lx lr rs rl rx rr t} · rw [e, add_right_comm]; rintro ⟨⟩ intro _ _; rw [e]; unfold delta at hr₂ ⊢; lia +set_option backward.isDefEq.respectTransparency false in theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂) (sep : l.All fun x => r.All fun y => x < y) : Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by diff --git a/Mathlib/Data/PEquiv.lean b/Mathlib/Data/PEquiv.lean index 3c8682402dec8a..a67bfd518f7b97 100644 --- a/Mathlib/Data/PEquiv.lean +++ b/Mathlib/Data/PEquiv.lean @@ -154,6 +154,7 @@ theorem trans_eq_none (f : α ≃. β) (g : β ≃. γ) (a : α) : theorem refl_trans (f : α ≃. β) : (PEquiv.refl α).trans f = f := by ext; dsimp [PEquiv.trans]; rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem trans_refl (f : α ≃. β) : f.trans (PEquiv.refl β) = f := by ext; dsimp [PEquiv.trans]; simp @@ -234,6 +235,7 @@ end OfSet theorem symm_trans_rev (f : α ≃. β) (g : β ≃. γ) : (f.trans g).symm = g.symm.trans f.symm := rfl +set_option backward.isDefEq.respectTransparency false in theorem self_trans_symm (f : α ≃. β) : f.trans f.symm = ofSet { a | (f a).isSome } := by ext dsimp [PEquiv.trans] diff --git a/Mathlib/Data/PFun.lean b/Mathlib/Data/PFun.lean index ac172bc651d0b5..aa1790226278c8 100644 --- a/Mathlib/Data/PFun.lean +++ b/Mathlib/Data/PFun.lean @@ -156,6 +156,7 @@ def ran (f : α →. β) : Set β := def restrict (f : α →. β) {p : Set α} (H : p ⊆ f.Dom) : α →. β := fun x => (f x).restrict (x ∈ p) (@H x) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mem_restrict {f : α →. β} {s : Set α} (h : s ⊆ f.Dom) (a : α) (b : β) : b ∈ f.restrict h a ↔ a ∈ s ∧ b ∈ f a := by simp [restrict] @@ -164,6 +165,7 @@ theorem mem_restrict {f : α →. β} {s : Set α} (h : s ⊆ f.Dom) (a : α) (b def res (f : α → β) (s : Set α) : α →. β := (PFun.lift f).restrict s.subset_univ +set_option backward.isDefEq.respectTransparency false in theorem mem_res (f : α → β) (s : Set α) (a : α) (b : β) : b ∈ res f s a ↔ a ∈ s ∧ f a = b := by simp [res, @eq_comm _ b] @@ -479,14 +481,17 @@ def comp (f : β →. γ) (g : α →. β) : α →. γ := fun a => (g a).bind f theorem comp_apply (f : β →. γ) (g : α →. β) (a : α) : f.comp g a = (g a).bind f := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem id_comp (f : α →. β) : (PFun.id β).comp f = f := ext fun _ _ => by simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem comp_id (f : α →. β) : f.comp (PFun.id α) = f := ext fun _ _ => by simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem dom_comp (f : β →. γ) (g : α →. β) : (f.comp g).Dom = g.preimage f.Dom := by ext @@ -508,6 +513,7 @@ theorem Part.bind_comp (f : β →. γ) (g : α →. β) (a : Part α) : theorem comp_assoc (f : γ →. δ) (g : β →. γ) (h : α →. β) : (f.comp g).comp h = f.comp (g.comp h) := ext fun _ _ => by simp only [comp_apply, Part.bind_comp] +set_option backward.isDefEq.respectTransparency false in -- This can't be `simp` theorem coe_comp (g : β → γ) (f : α → β) : ((g ∘ f : α → γ) : α →. γ) = (g : β →. γ).comp f := ext fun _ _ => by simp only [coe_val, comp_apply, Function.comp, Part.bind_some] @@ -560,6 +566,7 @@ theorem mem_prodMap {f : α →. γ} {g : β →. δ} {x : α × β} {y : γ × · simp only [prodMap, Part.mem_mk_iff, And.exists, Prod.ext_iff] · simp only [exists_and_left, exists_and_right, Membership.mem, Part.Mem] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem prodLift_fst_comp_snd_comp (f : α →. γ) (g : β →. δ) : prodLift (f.comp ((Prod.fst : α × β → α) : α × β →. α)) diff --git a/Mathlib/Data/PFunctor/Multivariate/Basic.lean b/Mathlib/Data/PFunctor/Multivariate/Basic.lean index 76e39bff9afce8..4264be645cc75a 100644 --- a/Mathlib/Data/PFunctor/Multivariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Multivariate/Basic.lean @@ -137,6 +137,7 @@ theorem comp.get_mk (x : P (fun i => Q i α)) : comp.get (comp.mk x) = x := by theorem comp.mk_get (x : comp P Q α) : comp.mk (comp.get x) = x := by rfl +set_option backward.isDefEq.respectTransparency false in /- lifting predicates and relations -/ @@ -152,6 +153,7 @@ theorem liftP_iff {α : TypeVec n} (p : ∀ ⦃i⦄, α i → Prop) (x : P α) : use ⟨a, fun i j => ⟨f i j, pf i j⟩⟩ rw [xeq]; rfl +set_option backward.isDefEq.respectTransparency false in theorem liftP_iff' {α : TypeVec n} (p : ∀ ⦃i⦄, α i → Prop) (a : P.A) (f : P.B a ⟹ α) : @LiftP.{u} _ P.Obj _ α p ⟨a, f⟩ ↔ ∀ i x, p (f i x) := by simp only [liftP_iff]; constructor diff --git a/Mathlib/Data/PFunctor/Multivariate/M.lean b/Mathlib/Data/PFunctor/Multivariate/M.lean index 18d4c2a48b49c4..c10bcb9c5d9c6a 100644 --- a/Mathlib/Data/PFunctor/Multivariate/M.lean +++ b/Mathlib/Data/PFunctor/Multivariate/M.lean @@ -117,6 +117,7 @@ def castDropB {a a' : P.A} (h : a = a') : P.drop.B a ⟹ P.drop.B a' := fun _i b /-- Proof of type equality as a function -/ def castLastB {a a' : P.A} (h : a = a') : P.last.B a → P.last.B a' := fun b => Eq.recOn h b +set_option backward.isDefEq.respectTransparency false in /-- Using corecursion, construct the contents of an M-type -/ def M.corecContents {α : TypeVec.{u} n} {β : Type v} @@ -191,6 +192,7 @@ theorem M.dest_corec' {α : TypeVec.{u} n} {β : Type v} (g₀ : β → P.A) M.dest P (M.corec' P g₀ g₁ g₂ x) = ⟨g₀ x, splitFun (g₁ x) (M.corec' P g₀ g₁ g₂ ∘ g₂ x)⟩ := rfl +set_option backward.isDefEq.respectTransparency false in theorem M.dest_corec {α : TypeVec n} {β : Type u} (g : β → P (α.append1 β)) (x : β) : M.dest P (M.corec P g x) = appendFun id (M.corec P g) <$$> g x := by trans @@ -200,6 +202,7 @@ theorem M.dest_corec {α : TypeVec n} {β : Type u} (g : β → P (α.append1 β conv_rhs => rw [← split_dropFun_lastFun f, appendFun_comp_splitFun] rfl +set_option backward.isDefEq.respectTransparency false in theorem M.bisim_lemma {α : TypeVec n} {a₁ : (mp P).A} {f₁ : (mp P).B a₁ ⟹ α} {a' : P.A} {f' : (P.B a').drop ⟹ α} {f₁' : (P.B a').last → M P α} (e₁ : M.dest P ⟨a₁, f₁⟩ = ⟨a', splitFun f' f₁'⟩) : @@ -246,6 +249,7 @@ theorem M.bisim {α : TypeVec n} (R : P.M α → P.M α → Prop) | child x a f h' i c p IH => exact IH _ _ (h'' _) +set_option backward.isDefEq.respectTransparency false in theorem M.bisim₀ {α : TypeVec n} (R : P.M α → P.M α → Prop) (h₀ : Equivalence R) (h : ∀ x y, R x y → (id ::: Quot.mk R) <$$> M.dest _ x = (id ::: Quot.mk R) <$$> M.dest _ y) (x y) (r : R x y) : x = y := by diff --git a/Mathlib/Data/PFunctor/Multivariate/W.lean b/Mathlib/Data/PFunctor/Multivariate/W.lean index ad4f0e0c736dd9..fea39e1d7e2610 100644 --- a/Mathlib/Data/PFunctor/Multivariate/W.lean +++ b/Mathlib/Data/PFunctor/Multivariate/W.lean @@ -239,6 +239,7 @@ abbrev objAppend1 {α : TypeVec n} {β : Type u} (a : P.A) (f' : P.drop.B a ⟹ (f : P.last.B a → β) : P (α ::: β) := ⟨a, splitFun f' f⟩ +set_option backward.isDefEq.respectTransparency false in theorem map_objAppend1 {α γ : TypeVec n} (g : α ⟹ γ) (a : P.A) (f' : P.drop.B a ⟹ α) (f : P.last.B a → P.W α) : appendFun g (P.wMap g) <$$> P.objAppend1 a f' f = @@ -260,9 +261,11 @@ def wMk' {α : TypeVec n} : P (α ::: P.W α) → P.W α def wDest' {α : TypeVec.{u} n} : P.W α → P (α.append1 (P.W α)) := P.wRec fun a f' f _ => ⟨a, splitFun f' f⟩ +set_option backward.isDefEq.respectTransparency false in theorem wDest'_wMk {α : TypeVec n} (a : P.A) (f' : P.drop.B a ⟹ α) (f : P.last.B a → P.W α) : P.wDest' (P.wMk a f' f) = ⟨a, splitFun f' f⟩ := by rw [wDest', wRec_eq] +set_option backward.isDefEq.respectTransparency false in theorem wDest'_wMk' {α : TypeVec n} (x : P (α.append1 (P.W α))) : P.wDest' (P.wMk' x) = x := by obtain ⟨a, f⟩ := x; rw [wMk', wDest'_wMk, split_dropFun_lastFun] diff --git a/Mathlib/Data/PFunctor/Univariate/Basic.lean b/Mathlib/Data/PFunctor/Univariate/Basic.lean index a7c35efe92bc64..1c87cac24b1125 100644 --- a/Mathlib/Data/PFunctor/Univariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Univariate/Basic.lean @@ -172,6 +172,7 @@ variable {P : PFunctor.{uA, uB}} open Functor +set_option backward.isDefEq.respectTransparency false in theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) : Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by constructor @@ -184,6 +185,7 @@ theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) : use ⟨a, fun i => ⟨f i, pf i⟩⟩ rw [xeq]; rfl +set_option backward.isDefEq.respectTransparency false in theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) : @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by simp only [liftp_iff]; constructor <;> intro h diff --git a/Mathlib/Data/PFunctor/Univariate/M.lean b/Mathlib/Data/PFunctor/Univariate/M.lean index 5eff067e410d48..f87649e15fbf1d 100644 --- a/Mathlib/Data/PFunctor/Univariate/M.lean +++ b/Mathlib/Data/PFunctor/Univariate/M.lean @@ -413,6 +413,7 @@ theorem head_mk (x : F (M F)) : head (M.mk x) = x.1 := x.1 = (dest (M.mk x)).1 := by rw [dest_mk] _ = head (M.mk x) := rfl +set_option backward.isDefEq.respectTransparency false in theorem children_mk {a} (x : F.B a → M F) (i : F.B (head (M.mk ⟨a, x⟩))) : children (M.mk ⟨a, x⟩) i = x (cast (by rw [head_mk]) i) := by apply ext'; intro n; rfl @@ -511,6 +512,7 @@ structure IsBisimulation : Prop where /-- The tails are equal -/ tail : ∀ {a} {f f' : F.B a → M F}, M.mk ⟨a, f⟩ ~ M.mk ⟨a, f'⟩ → ∀ i : F.B a, f i ~ f' i +set_option backward.isDefEq.respectTransparency false in theorem nth_of_bisim [Inhabited (M F)] [DecidableEq F.A] (bisim : IsBisimulation R) (s₁ s₂) (ps : Path F) : (R s₁ s₂) → @@ -566,6 +568,7 @@ variable {P : PFunctor.{uA, uB}} {α : Type*} theorem dest_corec (g : α → P α) (x : α) : M.dest (M.corec g x) = P.map (M.corec g) (g x) := by rw [corec_def, dest_mk] +set_option backward.isDefEq.respectTransparency false in theorem bisim (R : M P → M P → Prop) (h : ∀ x y, R x y → ∃ a f f', M.dest x = ⟨a, f⟩ ∧ M.dest y = ⟨a, f'⟩ ∧ ∀ i, R (f i) (f' i)) : ∀ x y, R x y → x = y := by diff --git a/Mathlib/Data/PNat/Basic.lean b/Mathlib/Data/PNat/Basic.lean index 285715236d27af..f8e2eee751627e 100644 --- a/Mathlib/Data/PNat/Basic.lean +++ b/Mathlib/Data/PNat/Basic.lean @@ -311,6 +311,7 @@ theorem mod_le (m k : ℕ+) : mod m k ≤ m ∧ mod m k ≤ k := by lia · exact ⟨Nat.mod_le (m : ℕ) (k : ℕ), (Nat.mod_lt (m : ℕ) k.pos).le⟩ +set_option backward.isDefEq.respectTransparency false in theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by constructor <;> intro h · rcases h with ⟨_, rfl⟩ diff --git a/Mathlib/Data/PNat/Factors.lean b/Mathlib/Data/PNat/Factors.lean index 5c553ce6068c32..e35d35233de7c5 100644 --- a/Mathlib/Data/PNat/Factors.lean +++ b/Mathlib/Data/PNat/Factors.lean @@ -116,6 +116,7 @@ theorem coePNat_nat (v : PrimeMultiset) : ((v : Multiset ℕ+) : Multiset ℕ) = def prod (v : PrimeMultiset) : ℕ+ := (v : Multiset PNat).prod +set_option backward.isDefEq.respectTransparency false in theorem coe_prod (v : PrimeMultiset) : (v.prod : ℕ) = (v : Multiset ℕ).prod := by have h : (v.prod : ℕ) = ((v.map (↑) : Multiset ℕ+).map (↑)).prod := PNat.coeMonoidHom.map_multiset_prod v.toPNatMultiset @@ -128,6 +129,7 @@ theorem prod_ofPrime (p : Nat.Primes) : (ofPrime p).prod = (p : ℕ+) := def ofNatMultiset (v : Multiset ℕ) (h : ∀ p : ℕ, p ∈ v → p.Prime) : PrimeMultiset := @Multiset.pmap ℕ Nat.Primes Nat.Prime (fun p hp => ⟨p, hp⟩) v h +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mem_ofNatMultiset {p : ℕ+} {s : Multiset ℕ} (hs) : p ∈ (ofNatMultiset s hs : Multiset ℕ+) ↔ (p : ℕ) ∈ s := by @@ -135,6 +137,7 @@ theorem mem_ofNatMultiset {p : ℕ+} {s : Multiset ℕ} (hs) : ← PNat.coe_inj] simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem to_ofNatMultiset (v : Multiset ℕ) (h) : (ofNatMultiset v h : Multiset ℕ) = v := by dsimp [ofNatMultiset, toNatMultiset] @@ -148,6 +151,7 @@ theorem prod_ofNatMultiset (v : Multiset ℕ) (h) : def ofPNatMultiset (v : Multiset ℕ+) (h : ∀ p : ℕ+, p ∈ v → p.Prime) : PrimeMultiset := @Multiset.pmap ℕ+ Nat.Primes PNat.Prime (fun p hp => ⟨(p : ℕ), hp⟩) v h +set_option backward.isDefEq.respectTransparency false in @[simp] theorem to_ofPNatMultiset (v : Multiset ℕ+) (h) : (ofPNatMultiset v h : Multiset ℕ+) = v := by dsimp [ofPNatMultiset, toPNatMultiset] @@ -167,6 +171,7 @@ about how this interacts with our constructions on multisets. -/ def ofNatList (l : List ℕ) (h : ∀ p : ℕ, p ∈ l → p.Prime) : PrimeMultiset := ofNatMultiset (l : Multiset ℕ) h +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mem_ofNatList {p : ℕ+} {l : List ℕ} (hl) : p ∈ (ofNatList l hl : Multiset ℕ+) ↔ (p : ℕ) ∈ l := by @@ -183,6 +188,7 @@ the coercion from lists to multisets. -/ def ofPNatList (l : List ℕ+) (h : ∀ p : ℕ+, p ∈ l → p.Prime) : PrimeMultiset := ofPNatMultiset (l : Multiset ℕ+) h +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toPNatMultiset_ofPNatList {l : List ℕ+} (hl) : (ofPNatList l hl : Multiset ℕ+) = l := by simp [ofPNatList] @@ -239,6 +245,7 @@ end PNat namespace PrimeMultiset +set_option backward.isDefEq.respectTransparency false in /-- If we start with a multiset of primes, take the product and then factor it, we get back the original multiset. -/ @[simp] diff --git a/Mathlib/Data/PNat/Find.lean b/Mathlib/Data/PNat/Find.lean index 95d8d885c510da..8185ec6de99ec3 100644 --- a/Mathlib/Data/PNat/Find.lean +++ b/Mathlib/Data/PNat/Find.lean @@ -22,6 +22,7 @@ namespace PNat variable {p q : ℕ+ → Prop} [DecidablePred p] [DecidablePred q] (h : ∃ n, p n) +set_option backward.isDefEq.respectTransparency false in instance decidablePredExistsNat : DecidablePred fun n' : ℕ => ∃ (n : ℕ+) (_ : n' = n), p n := fun n' => decidable_of_iff' (∃ h : 0 < n', p ⟨n', h⟩) <| diff --git a/Mathlib/Data/PNat/Interval.lean b/Mathlib/Data/PNat/Interval.lean index cfd0da464606a9..a7c741d2582014 100644 --- a/Mathlib/Data/PNat/Interval.lean +++ b/Mathlib/Data/PNat/Interval.lean @@ -81,18 +81,23 @@ set_option backward.isDefEq.respectTransparency false in theorem card_uIcc : #(uIcc a b) = (b - a : ℤ).natAbs + 1 := by rw [← Nat.card_uIcc, ← map_subtype_embedding_uIcc, card_map] +set_option backward.isDefEq.respectTransparency false in theorem card_fintype_Icc : Fintype.card (Set.Icc a b) = b + 1 - a := by rw [← card_Icc, Fintype.card_ofFinset] +set_option backward.isDefEq.respectTransparency false in theorem card_fintype_Ico : Fintype.card (Set.Ico a b) = b - a := by rw [← card_Ico, Fintype.card_ofFinset] +set_option backward.isDefEq.respectTransparency false in theorem card_fintype_Ioc : Fintype.card (Set.Ioc a b) = b - a := by rw [← card_Ioc, Fintype.card_ofFinset] +set_option backward.isDefEq.respectTransparency false in theorem card_fintype_Ioo : Fintype.card (Set.Ioo a b) = b - a - 1 := by rw [← card_Ioo, Fintype.card_ofFinset] +set_option backward.isDefEq.respectTransparency false in theorem card_fintype_uIcc : Fintype.card (Set.uIcc a b) = (b - a : ℤ).natAbs + 1 := by rw [← card_uIcc, Fintype.card_ofFinset] diff --git a/Mathlib/Data/PNat/Prime.lean b/Mathlib/Data/PNat/Prime.lean index 25d7addd95f1ba..24daab82f83604 100644 --- a/Mathlib/Data/PNat/Prime.lean +++ b/Mathlib/Data/PNat/Prime.lean @@ -143,6 +143,7 @@ theorem Prime.not_dvd_one {p : ℕ+} : p.Prime → ¬p ∣ 1 := fun pp : p.Prime rw [dvd_iff] apply Nat.Prime.not_dvd_one pp +set_option backward.isDefEq.respectTransparency false in theorem exists_prime_and_dvd {n : ℕ+} (hn : n ≠ 1) : ∃ p : ℕ+, p.Prime ∧ p ∣ n := by obtain ⟨p, hp⟩ := Nat.exists_prime_and_dvd (mt coe_eq_one_iff.mp hn) exists (⟨p, Nat.Prime.pos hp.left⟩ : ℕ+); rw [dvd_iff]; apply hp diff --git a/Mathlib/Data/PNat/Xgcd.lean b/Mathlib/Data/PNat/Xgcd.lean index 50e8f38e63f284..2ed35dc2c80789 100644 --- a/Mathlib/Data/PNat/Xgcd.lean +++ b/Mathlib/Data/PNat/Xgcd.lean @@ -135,6 +135,7 @@ def IsSpecial : Prop := def IsSpecial' : Prop := u.w * u.z = succPNat (u.x * u.y) +set_option backward.isDefEq.respectTransparency false in theorem isSpecial_iff : u.IsSpecial ↔ u.IsSpecial' := by dsimp [IsSpecial, IsSpecial'] let ⟨wp, x, y, zp, ap, bp⟩ := u diff --git a/Mathlib/Data/Part.lean b/Mathlib/Data/Part.lean index 51538122d2a904..ef947f903066ed 100644 --- a/Mathlib/Data/Part.lean +++ b/Mathlib/Data/Part.lean @@ -503,10 +503,10 @@ instance : LawfulMonad map_const := by simp [Functor.mapConst, Functor.map] --Porting TODO : In Lean3 these were automatic by a tactic seqLeft_eq x y := ext' - (by simp [SeqLeft.seqLeft, Part.bind, assert, Seq.seq, const, (· <$> ·), and_comm]) + (by simp [SeqLeft.seqLeft, Part.bind, assert, Seq.seq, (· <$> ·), and_comm]) (fun _ _ => rfl) seqRight_eq x y := ext' - (by simp [SeqRight.seqRight, Part.bind, assert, Seq.seq, const, (· <$> ·)]) + (by simp [SeqRight.seqRight, Part.bind, assert, Seq.seq, (· <$> ·)]) (fun _ _ => rfl) pure_seq x y := ext' (by simp [Seq.seq, Part.bind, assert, (· <$> ·), pure]) diff --git a/Mathlib/Data/QPF/Multivariate/Basic.lean b/Mathlib/Data/QPF/Multivariate/Basic.lean index 07695fc6ffe451..1deb05fd27c844 100644 --- a/Mathlib/Data/QPF/Multivariate/Basic.lean +++ b/Mathlib/Data/QPF/Multivariate/Basic.lean @@ -119,6 +119,7 @@ instance (priority := 100) lawfulMvFunctor : LawfulMvFunctor F where id_map := @MvQPF.id_map n F _ comp_map := @comp_map n F _ +set_option backward.isDefEq.respectTransparency false in -- Lifting predicates and relations theorem liftP_iff {α : TypeVec n} (p : ∀ ⦃i⦄, α i → Prop) (x : F α) : LiftP p x ↔ ∃ a f, x = abs ⟨a, f⟩ ∧ ∀ i j, p (f i j) := by @@ -134,6 +135,7 @@ theorem liftP_iff {α : TypeVec n} (p : ∀ ⦃i⦄, α i → Prop) (x : F α) : use abs ⟨a, fun i j => ⟨f i j, h₁ i j⟩⟩ rw [← abs_map, h₀]; rfl +set_option backward.isDefEq.respectTransparency false in theorem liftR_iff {α : TypeVec n} (r : ∀ ⦃i⦄, α i → α i → Prop) (x y : F α) : LiftR r x y ↔ ∃ a f₀ f₁, x = abs ⟨a, f₀⟩ ∧ y = abs ⟨a, f₁⟩ ∧ ∀ i j, r (f₀ i j) (f₁ i j) := by constructor @@ -169,6 +171,7 @@ theorem mem_supp {α : TypeVec n} (x : F α) (i) (u : α i) : theorem supp_eq {α : TypeVec n} {i} (x : F α) : supp x i = { u | ∀ a f, abs ⟨a, f⟩ = x → u ∈ f i '' univ } := by ext; apply mem_supp +set_option backward.isDefEq.respectTransparency false in theorem has_good_supp_iff {α : TypeVec n} (x : F α) : (∀ p, LiftP p x ↔ ∀ (i), ∀ u ∈ supp x i, p i u) ↔ ∃ a f, abs ⟨a, f⟩ = x ∧ ∀ i a' f', abs ⟨a', f'⟩ = x → f i '' univ ⊆ f' i '' univ := by @@ -230,12 +233,14 @@ theorem liftP_iff_of_isUniform (h : q.IsUniform) {α : TypeVec n} (x : F α) (p rw [supp_eq_of_isUniform h] exact ⟨i, mem_univ i, rfl⟩ +set_option backward.isDefEq.respectTransparency false in theorem supp_map (h : q.IsUniform) {α β : TypeVec n} (g : α ⟹ β) (x : F α) (i) : supp (g <$$> x) i = g i '' supp x i := by rw [← abs_repr x]; obtain ⟨a, f⟩ := repr x; rw [← abs_map, MvPFunctor.map_eq] rw [supp_eq_of_isUniform h, supp_eq_of_isUniform h, ← image_comp] rfl +set_option backward.isDefEq.respectTransparency false in theorem suppPreservation_iff_isUniform : q.SuppPreservation ↔ q.IsUniform := by constructor · intro h α a a' f f' h' i @@ -244,6 +249,7 @@ theorem suppPreservation_iff_isUniform : q.SuppPreservation ↔ q.IsUniform := b ext rwa [supp_eq_of_isUniform, MvPFunctor.supp_eq] +set_option backward.isDefEq.respectTransparency false in theorem suppPreservation_iff_liftpPreservation : q.SuppPreservation ↔ q.LiftPPreservation := by constructor <;> intro h · rintro α p ⟨a, f⟩ @@ -264,7 +270,7 @@ theorem liftpPreservation_iff_uniform : q.LiftPPreservation ↔ q.IsUniform := b set_option linter.style.whitespace false in -- manual alignment is not recognised /-- Any type function `F` that is (extensionally) equivalent to a QPF, is itself a QPF, assuming that the functorial map of `F` behaves similar to `MvFunctor.ofEquiv eqv` -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv {F F' : TypeVec.{u} n → Type*} [q : MvQPF F'] [MvFunctor F] (eqv : ∀ α, F α ≃ F' α) (map_eq : ∀ (α β : TypeVec n) (f : α ⟹ β) (a : F α), diff --git a/Mathlib/Data/QPF/Multivariate/Constructions/Cofix.lean b/Mathlib/Data/QPF/Multivariate/Constructions/Cofix.lean index 55f0f8ac5728be..ce814602d36fd3 100644 --- a/Mathlib/Data/QPF/Multivariate/Constructions/Cofix.lean +++ b/Mathlib/Data/QPF/Multivariate/Constructions/Cofix.lean @@ -164,6 +164,7 @@ def Cofix.corec₁ {α : TypeVec n} {β : Type u} (g : ∀ {X}, (Cofix F α → X) → (β → X) → β → F (α ::: X)) (x : β) : Cofix F α := Cofix.corec' (fun x => g Sum.inl Sum.inr x) x +set_option backward.isDefEq.respectTransparency false in theorem Cofix.dest_corec {α : TypeVec n} {β : Type u} (g : β → F (α.append1 β)) (x : β) : Cofix.dest (Cofix.corec g x) = appendFun id (Cofix.corec g) <$$> g x := by conv => @@ -192,6 +193,7 @@ A bisimulation relation `R` for values `x y : Cofix F α`: -/ +set_option backward.isDefEq.respectTransparency false in private theorem Cofix.bisim_aux {α : TypeVec n} (r : Cofix F α → Cofix F α → Prop) (h' : ∀ x, r x x) (h : ∀ x y, r x y → appendFun id (Quot.mk r) <$$> Cofix.dest x = appendFun id (Quot.mk r) <$$> Cofix.dest y) : @@ -397,6 +399,7 @@ end LiftRMap variable {F : TypeVec (n + 1) → Type u} [q : MvQPF F] +set_option backward.isDefEq.respectTransparency false in theorem Cofix.abs_repr {α} (x : Cofix F α) : Quot.mk _ (Cofix.repr x) = x := by let R := fun x y : Cofix F α => abs (repr y) = x refine Cofix.bisim₂ R ?_ _ _ rfl diff --git a/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean b/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean index 94e05c04a5c13e..93bab0b692c8ce 100644 --- a/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean +++ b/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean @@ -71,6 +71,7 @@ theorem get_map (x : Comp F G α) : end +set_option backward.isDefEq.respectTransparency false in instance [MvQPF F] [∀ i, MvQPF <| G i] : MvQPF (Comp F G) where P := MvPFunctor.comp (P F) fun i ↦ P <| G i abs := Comp.mk ∘ (map fun _ ↦ abs) ∘ abs ∘ MvPFunctor.comp.get diff --git a/Mathlib/Data/QPF/Multivariate/Constructions/Fix.lean b/Mathlib/Data/QPF/Multivariate/Constructions/Fix.lean index 9747c992028db5..9426b4aaae015c 100644 --- a/Mathlib/Data/QPF/Multivariate/Constructions/Fix.lean +++ b/Mathlib/Data/QPF/Multivariate/Constructions/Fix.lean @@ -84,6 +84,7 @@ inductive WEquiv {α : TypeVec n} : q.P.W α → q.P.W α → Prop WEquiv (q.P.wMk a₀ f'₀ f₀) (q.P.wMk a₁ f'₁ f₁) | trans (u v w : q.P.W α) : WEquiv u v → WEquiv v w → WEquiv u w +set_option backward.isDefEq.respectTransparency false in theorem recF_eq_of_wEquiv (α : TypeVec n) {β : Type u} (u : F (α.append1 β) → β) (x y : q.P.W α) : WEquiv x y → recF u x = recF u y := by induction x using q.P.wCases @@ -192,6 +193,7 @@ def Fix.mk (x : F (append1 α (Fix F α))) : Fix F α := def Fix.dest : Fix F α → F (append1 α (Fix F α)) := Fix.rec (MvFunctor.map (appendFun id Fix.mk)) +set_option backward.isDefEq.respectTransparency false in theorem Fix.rec_eq {β : Type u} (g : F (append1 α β) → β) (x : F (append1 α (Fix F α))) : Fix.rec g (Fix.mk x) = g (appendFun id (Fix.rec g) <$$> x) := by have : recF g ∘ fixToW = Fix.rec g := by @@ -208,6 +210,7 @@ theorem Fix.rec_eq {β : Type u} (g : F (append1 α β) → β) (x : F (append1 rw [MvPFunctor.map_eq, recF_eq', ← MvPFunctor.map_eq, MvPFunctor.wDest'_wMk'] rw [← MvPFunctor.comp_map, abs_map, ← h, abs_repr, ← appendFun_comp, id_comp, this] +set_option backward.isDefEq.respectTransparency false in theorem Fix.ind_aux (a : q.P.A) (f' : q.P.drop.B a ⟹ α) (f : q.P.last.B a → q.P.W α) : Fix.mk (abs ⟨a, q.P.appendContents f' fun x => ⟦f x⟧⟩) = ⟦q.P.wMk a f' f⟧ := by have : Fix.mk (abs ⟨a, q.P.appendContents f' fun x => ⟦f x⟧⟩) = ⟦wrepr (q.P.wMk a f' f)⟧ := by diff --git a/Mathlib/Data/QPF/Multivariate/Constructions/Quot.lean b/Mathlib/Data/QPF/Multivariate/Constructions/Quot.lean index 3fff9c46592de7..f015577fd3dbe0 100644 --- a/Mathlib/Data/QPF/Multivariate/Constructions/Quot.lean +++ b/Mathlib/Data/QPF/Multivariate/Constructions/Quot.lean @@ -37,7 +37,7 @@ variable {FG_repr : ∀ {α}, G α → F α} /-- If `F` is a QPF then `G` is a QPF as well. Can be used to construct `MvQPF` instances by transporting them across surjective functions -/ -@[implicit_reducible] +@[instance_reducible] def quotientQPF (FG_abs_repr : ∀ {α} (x : G α), FG_abs (FG_repr x) = x) (FG_abs_map : ∀ {α β} (f : α ⟹ β) (x : F α), FG_abs (f <$$> x) = f <$$> FG_abs x) : MvQPF G where @@ -69,7 +69,7 @@ def Quot1.map ⦃α β⦄ (f : α ⟹ β) : Quot1.{u} R α → Quot1.{u} R β := Quot.lift (fun x : F α => Quot.mk _ (f <$$> x : F β)) fun a b h => Quot.sound <| Hfunc a b _ h /-- `mvFunctor` instance for `Quot1` with well-behaved `R` -/ -@[implicit_reducible] +@[instance_reducible] def Quot1.mvFunctor : MvFunctor (Quot1 R) where map := @Quot1.map _ _ R _ Hfunc end @@ -79,7 +79,7 @@ section variable [q : MvQPF F] (Hfunc : ∀ ⦃α β⦄ (a b : F α) (f : α ⟹ β), R a b → R (f <$$> a) (f <$$> b)) /-- `Quot1` is a QPF -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def relQuot : @MvQPF _ (Quot1 R) := @quotientQPF n F q _ (MvQPF.Quot1.mvFunctor R Hfunc) (fun x => Quot.mk _ x) Quot.out (fun _x => Quot.out_eq _) fun _f _x => rfl diff --git a/Mathlib/Data/QPF/Multivariate/Constructions/Sigma.lean b/Mathlib/Data/QPF/Multivariate/Constructions/Sigma.lean index f2a256ebff7647..d7f2fc072a9ec4 100644 --- a/Mathlib/Data/QPF/Multivariate/Constructions/Sigma.lean +++ b/Mathlib/Data/QPF/Multivariate/Constructions/Sigma.lean @@ -91,6 +91,7 @@ protected def abs ⦃α⦄ : Pi.P F α → Pi F α protected def repr ⦃α⦄ : Pi F α → Pi.P F α | f => ⟨fun a => (MvQPF.repr (f a)).1, fun _i a => (MvQPF.repr (f _)).2 _ a.2⟩ +set_option backward.isDefEq.respectTransparency false in instance : MvQPF (Pi F) where P := Pi.P F abs := @Pi.abs _ _ F _ diff --git a/Mathlib/Data/QPF/Univariate/Basic.lean b/Mathlib/Data/QPF/Univariate/Basic.lean index 86ffd37c8f889c..f5dfdfdb724c04 100644 --- a/Mathlib/Data/QPF/Univariate/Basic.lean +++ b/Mathlib/Data/QPF/Univariate/Basic.lean @@ -63,6 +63,7 @@ variable {F : Type u → Type v} [q : QPF F] open Functor (Liftp Liftr) +set_option backward.isDefEq.respectTransparency false in /- Show that every qpf is a lawful functor. @@ -95,6 +96,7 @@ section open Functor +set_option backward.isDefEq.respectTransparency false in theorem liftp_iff {α : Type u} (p : α → Prop) (x : F α) : Liftp p x ↔ ∃ a f, x = abs ⟨a, f⟩ ∧ ∀ i, p (f i) := by constructor @@ -110,6 +112,7 @@ theorem liftp_iff {α : Type u} (p : α → Prop) (x : F α) : use abs ⟨a, fun i => ⟨f i, h₁ i⟩⟩ rw [← abs_map, h₀]; rfl +set_option backward.isDefEq.respectTransparency false in theorem liftp_iff' {α : Type u} (p : α → Prop) (x : F α) : Liftp p x ↔ ∃ u : q.P α, abs u = x ∧ ∀ i, p (u.snd i) := by constructor @@ -126,6 +129,7 @@ theorem liftp_iff' {α : Type u} (p : α → Prop) (x : F α) : use abs ⟨a, fun i => ⟨f i, h₁ i⟩⟩ rw [← abs_map, ← h₀]; rfl +set_option backward.isDefEq.respectTransparency false in theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : F α) : Liftr r x y ↔ ∃ a f₀ f₁, x = abs ⟨a, f₀⟩ ∧ y = abs ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by constructor @@ -174,6 +178,7 @@ inductive Wequiv : q.P.W → q.P.W → Prop abs ⟨a, f⟩ = abs ⟨a', f'⟩ → Wequiv ⟨a, f⟩ ⟨a', f'⟩ | trans (u v w : q.P.W) : Wequiv u v → Wequiv v w → Wequiv u w +set_option backward.isDefEq.respectTransparency false in /-- `recF` is insensitive to the representation -/ theorem recF_eq_of_Wequiv {α : Type u} (u : F α → α) (x y : q.P.W) : Wequiv x y → recF u x = recF u y := by @@ -242,6 +247,7 @@ def Fix.mk (x : F (Fix F)) : Fix F := def Fix.dest : Fix F → F (Fix F) := Fix.rec (Functor.map Fix.mk) +set_option backward.isDefEq.respectTransparency false in theorem Fix.rec_eq {α : Type _} (g : F α → α) (x : F (Fix F)) : Fix.rec g (Fix.mk x) = g (Fix.rec g <$> x) := by have : recF g ∘ fixToW = Fix.rec g := by @@ -257,6 +263,7 @@ theorem Fix.rec_eq {α : Type _} (g : F α → α) (x : F (Fix F)) : rw [PFunctor.map_eq, recF_eq, ← PFunctor.map_eq, PFunctor.W.dest_mk, PFunctor.map_map, abs_map, ← h, abs_repr, this] +set_option backward.isDefEq.respectTransparency false in theorem Fix.ind_aux (a : q.P.A) (f : q.P.B a → q.P.W) : Fix.mk (abs ⟨a, fun x => ⟦f x⟧⟩) = ⟦⟨a, f⟩⟧ := by have : Fix.mk (abs ⟨a, fun x => ⟦f x⟧⟩) = ⟦Wrepr ⟨a, f⟩⟧ := by @@ -268,6 +275,7 @@ theorem Fix.ind_aux (a : q.P.A) (f : q.P.B a → q.P.W) : apply Quot.sound apply Wrepr_equiv +set_option backward.isDefEq.respectTransparency false in theorem Fix.ind_rec {α : Type u} (g₁ g₂ : Fix F → α) (h : ∀ x : F (Fix F), g₁ <$> x = g₂ <$> x → g₁ (Fix.mk x) = g₂ (Fix.mk x)) : ∀ x, g₁ x = g₂ x := by @@ -365,6 +373,7 @@ def Cofix.dest : Cofix F → F (Cofix F) := lhs rw [comp_map, ← abs_map, pr rxy, abs_map, ← comp_map]) +set_option backward.isDefEq.respectTransparency false in theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) : Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by conv => @@ -373,6 +382,7 @@ theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) : dsimp rw [corecF_eq, abs_map, abs_repr, ← comp_map]; rfl +set_option backward.isDefEq.respectTransparency false in private theorem Cofix.bisim_aux (r : Cofix F → Cofix F → Prop) (h' : ∀ x, r x x) (h : ∀ x y, r x y → Quot.mk r <$> Cofix.dest x = Quot.mk r <$> Cofix.dest y) : ∀ x y, r x y → x = y := by @@ -420,6 +430,7 @@ theorem Cofix.bisim_rel (r : Cofix F → Cofix F → Prop) rw [h _ _ r'xy] right; exact rxy +set_option backward.isDefEq.respectTransparency false in theorem Cofix.bisim (r : Cofix F → Cofix F → Prop) (h : ∀ x y, r x y → Liftr r (Cofix.dest x) (Cofix.dest y)) : ∀ x y, r x y → x = y := by apply Cofix.bisim_rel @@ -452,8 +463,9 @@ namespace QPF variable {F₂ : Type u → Type u} [q₂ : QPF F₂] variable {F₁ : Type u → Type u} [q₁ : QPF F₁] +set_option backward.isDefEq.respectTransparency false in /-- composition of qpfs gives another qpf -/ -@[implicit_reducible] +@[instance_reducible] def comp : QPF (Functor.Comp F₂ F₁) where P := PFunctor.comp q₂.P q₁.P abs {α} := by @@ -513,7 +525,7 @@ variable {FG_repr : ∀ {α}, G α → F α} functor `G α`, `G` is a qpf. We can consider `G` a quotient on `F` where elements `x y : F α` are in the same equivalence class if `FG_abs x = FG_abs y`. -/ -@[implicit_reducible] +@[instance_reducible] def quotientQPF (FG_abs_repr : ∀ {α} (x : G α), FG_abs (FG_repr x) = x) (FG_abs_map : ∀ {α β} (f : α → β) (x : F α), FG_abs (f <$> x) = f <$> FG_abs x) : QPF G where P := q.P @@ -614,11 +626,13 @@ theorem liftp_iff_of_isUniform (h : q.IsUniform) {α : Type u} (x : F α) (p : rw [supp_eq_of_isUniform h] exact ⟨i, mem_univ i, rfl⟩ +set_option backward.isDefEq.respectTransparency false in theorem supp_map (h : q.IsUniform) {α β : Type u} (g : α → β) (x : F α) : supp (g <$> x) = g '' supp x := by rw [← abs_repr x]; obtain ⟨a, f⟩ := repr x; rw [← abs_map, PFunctor.map_eq] rw [supp_eq_of_isUniform h, supp_eq_of_isUniform h, image_comp] +set_option backward.isDefEq.respectTransparency false in theorem suppPreservation_iff_uniform : q.SuppPreservation ↔ q.IsUniform := by constructor · intro h α a a' f f' h' @@ -626,6 +640,7 @@ theorem suppPreservation_iff_uniform : q.SuppPreservation ↔ q.IsUniform := by · rintro h α ⟨a, f⟩ rwa [supp_eq_of_isUniform, PFunctor.supp_eq] +set_option backward.isDefEq.respectTransparency false in theorem suppPreservation_iff_liftpPreservation : q.SuppPreservation ↔ q.LiftpPreservation := by constructor <;> intro h · rintro α p ⟨a, f⟩ diff --git a/Mathlib/Data/Quot.lean b/Mathlib/Data/Quot.lean index 6276672bffea6b..6b58acd862e270 100644 --- a/Mathlib/Data/Quot.lean +++ b/Mathlib/Data/Quot.lean @@ -455,7 +455,7 @@ theorem true_equivalence : @Equivalence α fun _ _ ↦ True := /-- Always-true relation as a `Setoid`. Note that in later files the preferred spelling is `⊤ : Setoid α`. -/ -@[implicit_reducible] +@[instance_reducible] def trueSetoid : Setoid α := ⟨_, true_equivalence⟩ diff --git a/Mathlib/Data/Rat/Cast/Defs.lean b/Mathlib/Data/Rat/Cast/Defs.lean index eed0a19f0d8495..1ab80b6d3c4eb9 100644 --- a/Mathlib/Data/Rat/Cast/Defs.lean +++ b/Mathlib/Data/Rat/Cast/Defs.lean @@ -50,6 +50,7 @@ lemma commute_cast (a : α) (q : ℚ≥0) : Commute a q := (cast_commute ..).sym lemma cast_comm (q : ℚ≥0) (a : α) : q * a = a * q := cast_commute _ _ +set_option backward.isDefEq.respectTransparency false in @[norm_cast] lemma cast_divNat_of_ne_zero (a : ℕ) {b : ℕ} (hb : (b : α) ≠ 0) : divNat a b = (a / b : α) := by rcases e : divNat a b with ⟨⟨n, d, h, c⟩, hn⟩ @@ -175,6 +176,7 @@ lemma cast_add_of_ne_zero {q r : ℚ} (hq : (q.den : α) ≠ 0) (hr : (r.den : @[simp, norm_cast] lemma cast_neg (q : ℚ) : ↑(-q) = (-q : α) := by simp [cast_def, neg_div] +set_option backward.isDefEq.respectTransparency false in @[norm_cast] lemma cast_sub_of_ne_zero (hp : (p.den : α) ≠ 0) (hq : (q.den : α) ≠ 0) : ↑(p - q) = (p - q : α) := by simp [sub_eq_add_neg, cast_add_of_ne_zero, hp, hq] diff --git a/Mathlib/Data/Rat/Cast/Lemmas.lean b/Mathlib/Data/Rat/Cast/Lemmas.lean index b74fcebed8f8cf..377b561a9cdc4b 100644 --- a/Mathlib/Data/Rat/Cast/Lemmas.lean +++ b/Mathlib/Data/Rat/Cast/Lemmas.lean @@ -78,6 +78,7 @@ theorem cast_zpow_of_ne_zero {K} [DivisionSemiring K] (q : ℚ≥0) (z : ℤ) (h congr rw [cast_inv_of_ne_zero hq] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem cast_mk {K} [DivisionRing K] (q : ℚ) (h : 0 ≤ q) : (NNRat.cast ⟨q, h⟩ : K) = (q : K) := by diff --git a/Mathlib/Data/Rat/Cast/OfScientific.lean b/Mathlib/Data/Rat/Cast/OfScientific.lean index 5fed7d8bbc9081..bf991855643130 100644 --- a/Mathlib/Data/Rat/Cast/OfScientific.lean +++ b/Mathlib/Data/Rat/Cast/OfScientific.lean @@ -18,6 +18,7 @@ to make this more general, but it's not needed at present. @[expose] public section +set_option backward.isDefEq.respectTransparency false in open Lean.Grind in instance {K : Type*} [_root_.Field K] [CharZero K] : LawfulOfScientific K where ofScientific_def {m s e} := by diff --git a/Mathlib/Data/Rat/Lemmas.lean b/Mathlib/Data/Rat/Lemmas.lean index 0f504d45b2ebdc..e028869fceb28b 100644 --- a/Mathlib/Data/Rat/Lemmas.lean +++ b/Mathlib/Data/Rat/Lemmas.lean @@ -305,6 +305,7 @@ theorem inv_ofNat_num (a : ℕ) [a.AtLeastTwo] : (ofNat(a) : ℚ)⁻¹.num = 1 : change 0 < (a : ℤ) lia +set_option backward.isDefEq.respectTransparency false in theorem inv_intCast_den (a : ℤ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a.natAbs := by simp theorem inv_natCast_den (a : ℕ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a := by simp diff --git a/Mathlib/Data/Semiquot.lean b/Mathlib/Data/Semiquot.lean index efd7d634dc36bb..97f9238f6e2748 100644 --- a/Mathlib/Data/Semiquot.lean +++ b/Mathlib/Data/Semiquot.lean @@ -178,6 +178,7 @@ def IsPure (q : Semiquot α) : Prop := def get (q : Semiquot α) (h : q.IsPure) : α := liftOn q id h +set_option backward.isDefEq.respectTransparency false in theorem get_mem {q : Semiquot α} (p) : get q p ∈ q := by let ⟨a, h⟩ := exists_mem q unfold get; rw [liftOn_ofMem q _ _ a h]; exact h diff --git a/Mathlib/Data/Seq/Basic.lean b/Mathlib/Data/Seq/Basic.lean index 7be37bed43fb01..da942f04c234bf 100644 --- a/Mathlib/Data/Seq/Basic.lean +++ b/Mathlib/Data/Seq/Basic.lean @@ -37,8 +37,10 @@ theorem length'_of_not_terminates {s : Seq α} (h : ¬ s.Terminates) : s.length' = ⊤ := by simp [length', h] +set_option backward.isDefEq.respectTransparency false in @[simp] -theorem length_nil : length (nil : Seq α) terminates_nil = 0 := by simp [length, terminatedAt_nil] +theorem length_nil : length (nil : Seq α) terminates_nil = 0 := + (Nat.find_eq_zero _).mpr terminatedAt_nil @[simp] theorem length'_nil : length' (nil : Seq α) = 0 := by @@ -56,6 +58,7 @@ theorem length'_cons (x : α) (s : Seq α) : · simp [length'_of_terminates h, length'_of_terminates h', length_cons h'] · simp [length'_of_not_terminates h, length'_of_not_terminates h'] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem length_eq_zero {s : Seq α} {h : s.Terminates} : s.length h = 0 ↔ s = nil := by @@ -70,6 +73,7 @@ theorem length'_ne_zero_iff_cons (s : Seq α) : s.length' ≠ 0 ↔ ∃ x s', s = cons x s' := by cases s <;> simp +set_option backward.isDefEq.respectTransparency false in /-- The statement of `length_le_iff'` does not assume that the sequence terminates. For a simpler statement of the theorem where the sequence is known to terminate see `length_le_iff`. -/ theorem length_le_iff' {s : Seq α} {n : ℕ} : @@ -93,6 +97,7 @@ theorem length'_le_iff {s : Seq α} {n : ℕ} : · simpa [length'_of_terminates h] using length_le_iff · simpa [length'_of_not_terminates h] using forall_not_of_not_exists h n +set_option backward.isDefEq.respectTransparency false in /-- The statement of `lt_length_iff'` does not assume that the sequence terminates. For a simpler statement of the theorem where the sequence is known to terminate see `lt_length_iff`. -/ theorem lt_length_iff' {s : Seq α} {n : ℕ} : @@ -132,6 +137,7 @@ end OfStream section OfList +set_option backward.isDefEq.respectTransparency false in theorem terminatedAt_ofList (l : List α) : (ofList l).TerminatedAt l.length := by simp [ofList, TerminatedAt] @@ -203,6 +209,7 @@ theorem length_take_le {s : Seq α} {n : ℕ} : (s.take n).length ≤ n := by obtain ⟨x, r⟩ := v simpa using ih +set_option backward.isDefEq.respectTransparency false in theorem length_take_of_le_length {s : Seq α} {n : ℕ} (hle : ∀ h : s.Terminates, n ≤ s.length h) : (s.take n).length = n := by induction n generalizing s with @@ -230,6 +237,7 @@ theorem length_toList (s : Seq α) (h : s.Terminates) : (toList s h).length = le intro _ exact le_rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem getElem?_toList (s : Seq α) (h : s.Terminates) (n : ℕ) : (toList s h)[n]? = s.get? n := by ext k @@ -239,6 +247,7 @@ theorem getElem?_toList (s : Seq α) (h : s.Terminates) (n : ℕ) : (toList s h) let ⟨a, ha⟩ := ge_stable s hmn h simp [ha] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ofList_toList (s : Seq α) (h : s.Terminates) : ofList (toList s h) = s := by @@ -248,6 +257,7 @@ theorem ofList_toList (s : Seq α) (h : s.Terminates) : theorem toList_ofList (l : List α) : toList (ofList l) (terminates_ofList l) = l := ofList_injective (by simp) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toList_nil : toList (nil : Seq α) ⟨0, terminatedAt_zero_iff.2 rfl⟩ = [] := by ext; simp [nil, toList, const] @@ -423,10 +433,12 @@ section Join theorem join_nil : join nil = (nil : Seq α) := destruct_eq_none rfl +set_option backward.isDefEq.respectTransparency false in -- Not a simp lemmas as `join_cons` is more general theorem join_cons_nil (a : α) (S) : join (cons (a, nil) S) = cons a (join S) := destruct_eq_cons <| by simp [join] +set_option backward.isDefEq.respectTransparency false in -- Not a simp lemmas as `join_cons` is more general theorem join_cons_cons (a b : α) (s S) : join (cons (a, cons b s) S) = cons a (join (cons (b, s) S)) := @@ -451,6 +463,7 @@ theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join · simpa only [BisimO, join_cons_cons, destruct_cons, cons_append, true_and] using Or.inr ⟨_, _, S, rfl, rfl⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem join_append (S T : Seq (Seq1 α)) : join (append S T) = append (join S) (join T) := by apply @@ -637,6 +650,7 @@ end ZipWith section Fold +set_option backward.isDefEq.respectTransparency false in @[simp] theorem fold_nil (init : β) (f : β → α → β) : nil.fold init f = cons init nil := by @@ -663,6 +677,7 @@ section Update variable (hd x : α) (tl : Seq α) (f : α → α) +set_option backward.isDefEq.respectTransparency false in theorem get?_update (s : Seq α) (n : ℕ) (m : ℕ) : (s.update n f).get? m = if m = n then (s.get? m).map f else s.get? m := by simp [update, Function.update] @@ -696,6 +711,7 @@ theorem update_cons_succ (n : ℕ) : (cons hd tl).update (n + 1) f = cons hd (tl theorem set_cons_succ (n : ℕ) : (cons hd tl).set (n + 1) x = cons hd (tl.set n x) := update_cons_succ _ _ _ _ +set_option backward.isDefEq.respectTransparency false in theorem get?_set_of_not_terminatedAt {s : Seq α} {n : ℕ} (h_not_terminated : ¬ s.TerminatedAt n) : (s.set n x).get? n = x := by simpa [set, update, ← Option.ne_none_iff_exists'] using! h_not_terminated @@ -957,6 +973,7 @@ def map (f : α → β) : Seq1 α → Seq1 β theorem map_pair {f : α → β} {a s} : map f (a, s) = (f a, Seq.map f s) := rfl +set_option backward.isDefEq.respectTransparency false in theorem map_id : ∀ s : Seq1 α, map id s = s | ⟨a, s⟩ => by simp [map] @@ -995,16 +1012,19 @@ def bind (s : Seq1 α) (f : α → Seq1 β) : Seq1 β := theorem join_map_ret (s : Seq α) : Seq.join (Seq.map ret s) = s := by apply coinduction2 s; intro s; cases s <;> simp [ret] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem bind_ret (f : α → β) : ∀ s, bind s (ret ∘ f) = map f s | ⟨a, s⟩ => by simp [bind, map, map_comp, ret] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a := by simp only [bind, map, ret.eq_1, map_nil] obtain ⟨a, s⟩ := f a cases s <;> simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) := by apply @@ -1022,10 +1042,12 @@ theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.m | cons _ s => simpa using ⟨s, S, rfl, rfl⟩ · simpa using ⟨nil, S, by simp, by simp⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S) | ((a, s), S) => by cases s <;> simp [map] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem join_join (SS : Seq (Seq1 (Seq1 α))) : Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) := by @@ -1046,6 +1068,7 @@ theorem join_join (SS : Seq (Seq1 (Seq1 α))) : | cons _ s => simpa using ⟨s, SS, rfl, rfl⟩ · simpa using ⟨nil, SS, by simp, by simp⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem bind_assoc (s : Seq1 α) (f : α → Seq1 β) (g : β → Seq1 γ) : bind (bind s f) g = bind s fun x : α => bind (f x) g := by diff --git a/Mathlib/Data/Seq/Defs.lean b/Mathlib/Data/Seq/Defs.lean index a7eae2d1ba2b8f..56e8a9471da48a 100644 --- a/Mathlib/Data/Seq/Defs.lean +++ b/Mathlib/Data/Seq/Defs.lean @@ -307,6 +307,7 @@ def corec (f : β → Option (α × β)) (b : β) : Seq α := by rw [Stream'.corec'_eq (Corec.f f) (Corec.f f o).2, Stream'.corec'_eq (Corec.f f) o] exact IH (Corec.f f o).2 +set_option backward.isDefEq.respectTransparency false in @[simp] theorem corec_eq (f : β → Option (α × β)) (b : β) : destruct (corec f b) = omap (corec f) (f b) := by @@ -327,6 +328,7 @@ theorem corec_nil (f : β → Option (α × β)) (b : β) apply destruct_eq_none simp [h] +set_option backward.isDefEq.respectTransparency false in theorem corec_cons {f : β → Option (α × β)} {b : β} {x : α} {s : β} (h : f b = .some (x, s)) : corec f b = cons x (corec f s) := by apply destruct_eq_cons diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index d3fbeb48451339..ed4397a4baa62c 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -541,6 +541,7 @@ open Notation in lemma encard_preimage_val_le_encard_left (P Q : Set α) : (P ↓∩ Q).encard ≤ P.encard := (Function.Embedding.subtype _).encard_le +set_option backward.isDefEq.respectTransparency false in open Notation in lemma encard_preimage_val_le_encard_right (P Q : Set α) : (P ↓∩ Q).encard ≤ Q.encard := Function.Embedding.encard_le ⟨fun ⟨⟨x, _⟩, hx⟩ ↦ ⟨x, hx⟩, fun _ _ h ↦ by @@ -594,8 +595,6 @@ end Function section ncard -open Nat - /-- A tactic (for use in default params) that applies `Set.toFinite` to synthesize a `Set.Finite` term. -/ syntax "toFinite_tac" : tactic diff --git a/Mathlib/Data/Set/Countable.lean b/Mathlib/Data/Set/Countable.lean index 15939332431531..6fd4b121fdd197 100644 --- a/Mathlib/Data/Set/Countable.lean +++ b/Mathlib/Data/Set/Countable.lean @@ -72,7 +72,7 @@ theorem countable_iff_nonempty_encodable {s : Set α} : s.Countable ↔ Nonempty alias ⟨Countable.nonempty_encodable, _⟩ := countable_iff_nonempty_encodable /-- Convert `Set.Countable s` to `Encodable s` (noncomputable). -/ -@[implicit_reducible] +@[instance_reducible] protected def Countable.toEncodable {s : Set α} (hs : s.Countable) : Encodable s := Classical.choice hs.nonempty_encodable diff --git a/Mathlib/Data/Set/Defs.lean b/Mathlib/Data/Set/Defs.lean index 5f780c4092a23b..8d3e4a504958d1 100644 --- a/Mathlib/Data/Set/Defs.lean +++ b/Mathlib/Data/Set/Defs.lean @@ -62,12 +62,14 @@ But we would like to dualize set intervals such that e.g. `Ico a b` is dual to ` attribute [to_dual_dont_translate] Set /-- Turn a predicate `p : α → Prop` into a set, also written as `{x | p x}` -/ +@[implicit_reducible] def setOf {α : Type u} (p : α → Prop) : Set α := p namespace Set /-- Membership in a set -/ +@[implicit_reducible] protected def Mem (s : Set α) (a : α) : Prop := s a diff --git a/Mathlib/Data/Set/Finite/Basic.lean b/Mathlib/Data/Set/Finite/Basic.lean index 164da8b8cc5640..0b0151b7ea9964 100644 --- a/Mathlib/Data/Set/Finite/Basic.lean +++ b/Mathlib/Data/Set/Finite/Basic.lean @@ -67,7 +67,7 @@ This is the `Fintype` projection for a `Set.Finite`. Note that because `Finite` isn't a typeclass, this definition will not fire if it is made into an instance -/ -@[implicit_reducible] +@[instance_reducible] protected noncomputable def Finite.fintype {s : Set α} (h : s.Finite) : Fintype s := h.nonempty_fintype.some @@ -240,7 +240,7 @@ instance fintypeUniv [Fintype α] : Fintype (@univ α) := instance fintypeTop [Fintype α] : Fintype (⊤ : Set α) := inferInstanceAs (Fintype (univ : Set α)) /-- If `(Set.univ : Set α)` is finite then `α` is a finite type. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfFiniteUniv (H : (univ (α := α)).Finite) : Fintype α := @Fintype.ofEquiv _ (univ : Set α) H.fintype (Equiv.Set.univ _) @@ -267,7 +267,7 @@ instance fintypeInterOfRight (s t : Set α) [Fintype t] [DecidablePred (· ∈ s Fintype.ofFinset {a ∈ t.toFinset | a ∈ s} <| by simp [and_comm] /-- A `Fintype` structure on a set defines a `Fintype` structure on its subset. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeSubset (s : Set α) {t : Set α} [Fintype s] [DecidablePred (· ∈ t)] (h : t ⊆ s) : Fintype t := by rw [← inter_eq_self_of_subset_right h] @@ -294,14 +294,15 @@ instance fintypeInsert (a : α) (s : Set α) [DecidableEq α] [Fintype s] : Fintype (insert a s : Set α) := Fintype.ofFinset (insert a s.toFinset) <| by simp +set_option backward.isDefEq.respectTransparency false in /-- A `Fintype` structure on `insert a s` when inserting a new element. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeInsertOfNotMem {a : α} (s : Set α) [Fintype s] (h : a ∉ s) : Fintype (insert a s : Set α) := Fintype.ofFinset ⟨a ::ₘ s.toFinset.1, s.toFinset.nodup.cons (by simp [h])⟩ <| by simp /-- A `Fintype` structure on `insert a s` when inserting a pre-existing element. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeInsertOfMem {a : α} (s : Set α) [Fintype s] (h : a ∈ s) : Fintype (insert a s : Set α) := Fintype.ofFinset s.toFinset <| by simp [h] @@ -322,7 +323,7 @@ instance fintypeImage [DecidableEq β] (s : Set α) (f : α → β) [Fintype s] /-- If a function `f` has a partial inverse `g` and the image of `s` under `f` is a set with a `Fintype` instance, then `s` has a `Fintype` structure as well. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeOfFintypeImage (s : Set α) {f : α → β} {g} (I : IsPartialInv f g) [Fintype (f '' s)] : Fintype s := Fintype.ofFinset ⟨_, (f '' s).toFinset.2.filterMap g <| injective_of_isPartialInv_right I⟩ @@ -767,6 +768,7 @@ end theorem card_empty : Fintype.card (∅ : Set α) = 0 := rfl +set_option backward.isDefEq.respectTransparency false in theorem card_fintypeInsertOfNotMem {a : α} (s : Set α) [Fintype s] (h : a ∉ s) : @Fintype.card _ (fintypeInsertOfNotMem s h) = Fintype.card s + 1 := by simp [Fintype.card_ofFinset] @@ -907,6 +909,7 @@ theorem infinite_of_injective_forall_mem [Infinite α] {s : Set β} {f : α → rw [← range_subset_iff] at hf exact (infinite_range_of_injective hi).mono hf +set_option backward.isDefEq.respectTransparency false in theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s.Infinite) (h_fin : (f '' s).Finite) : ¬InjOn f s := by have : Finite (f '' s) := finite_coe_iff.mpr h_fin diff --git a/Mathlib/Data/Set/Finite/Lattice.lean b/Mathlib/Data/Set/Finite/Lattice.lean index 1092899d5557cd..e2a5bcaa19b3f3 100644 --- a/Mathlib/Data/Set/Finite/Lattice.lean +++ b/Mathlib/Data/Set/Finite/Lattice.lean @@ -61,7 +61,7 @@ lemma toFinset_iUnion [Fintype β] [DecidableEq α] (f : β → Set α) /-- A union of sets with `Fintype` structure over a set with `Fintype` structure has a `Fintype` structure. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeBiUnion [DecidableEq α] {ι : Type*} (s : Set ι) [Fintype s] (t : ι → Set α) (H : ∀ i ∈ s, Fintype (t i)) : Fintype (⋃ x ∈ s, t x) := haveI : ∀ i : toFinset s, Fintype (t i) := fun i => H i (mem_toFinset.1 i.2) diff --git a/Mathlib/Data/Set/Finite/Monad.lean b/Mathlib/Data/Set/Finite/Monad.lean index 206b0c7e0cc284..69fa3987ab35dd 100644 --- a/Mathlib/Data/Set/Finite/Monad.lean +++ b/Mathlib/Data/Set/Finite/Monad.lean @@ -41,7 +41,7 @@ attribute [local instance] Set.monad /-- If `s : Set α` is a set with `Fintype` instance and `f : α → Set β` is a function such that each `f a`, `a ∈ s`, has a `Fintype` structure, then `s >>= f` has a `Fintype` structure. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeBind {α β} [DecidableEq β] (s : Set α) [Fintype s] (f : α → Set β) (H : ∀ a ∈ s, Fintype (f a)) : Fintype (s >>= f) := Set.fintypeBiUnion s f H diff --git a/Mathlib/Data/Set/NAry.lean b/Mathlib/Data/Set/NAry.lean index cfbdbc69d82da3..0dc5b5f0fd1d07 100644 --- a/Mathlib/Data/Set/NAry.lean +++ b/Mathlib/Data/Set/NAry.lean @@ -78,6 +78,7 @@ lemma image_prod : (fun x : α × β ↦ f x.1 x.2) '' s ×ˢ t = image2 f s t : @[simp] lemma image2_mk_eq_prod : image2 Prod.mk s t = s ×ˢ t := ext <| by simp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma image2_curry (f : α × β → γ) (s : Set α) (t : Set β) : image2 (fun a b ↦ f (a, b)) s t = f '' s ×ˢ t := by diff --git a/Mathlib/Data/Set/Operations.lean b/Mathlib/Data/Set/Operations.lean index e67b3b4273a70a..3eba028815998d 100644 --- a/Mathlib/Data/Set/Operations.lean +++ b/Mathlib/Data/Set/Operations.lean @@ -121,6 +121,7 @@ theorem mem_sdiff_of_mem {s t : Set α} {x : α} (h1 : x ∈ s) (h2 : x ∉ t) : /-- The preimage of `s : Set β` by `f : α → β`, written `f ⁻¹' s`, is the set of `x : α` such that `f x ∈ s`. -/ +@[implicit_reducible] def preimage (f : α → β) (s : Set β) : Set α := {x | f x ∈ s} /-- `f ⁻¹' t` denotes the preimage of `t : Set β` under the function `f : α → β`. -/ diff --git a/Mathlib/Data/Set/Pairwise/Lattice.lean b/Mathlib/Data/Set/Pairwise/Lattice.lean index e80fa1d7dc5aa3..cad752528c219e 100644 --- a/Mathlib/Data/Set/Pairwise/Lattice.lean +++ b/Mathlib/Data/Set/Pairwise/Lattice.lean @@ -151,6 +151,7 @@ lemma coe_biUnionEqSigmaOfDisjoint_symm_apply {α ι : Type*} {s : Set ι} ((Set.biUnionEqSigmaOfDisjoint h).symm x : α) = x.2 := by rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma coe_snd_biUnionEqSigmaOfDisjoint {α ι : Type*} {s : Set ι} {f : ι → Set α} (h : s.PairwiseDisjoint f) (x : ⋃ i ∈ s, f i) : diff --git a/Mathlib/Data/Set/Restrict.lean b/Mathlib/Data/Set/Restrict.lean index 9caa001539aeec..684e2299f861bb 100644 --- a/Mathlib/Data/Set/Restrict.lean +++ b/Mathlib/Data/Set/Restrict.lean @@ -288,6 +288,7 @@ theorem injOn_iff_injective : InjOn f s ↔ Injective (s.restrict f) := alias ⟨InjOn.injective, _⟩ := Set.injOn_iff_injective +set_option backward.isDefEq.respectTransparency false in theorem MapsTo.restrict_inj (h : MapsTo f s t) : Injective (h.restrict f s t) ↔ InjOn f s := by rw [h.restrict_eq_codRestrict, injective_codRestrict, injOn_iff_injective] diff --git a/Mathlib/Data/Setoid/Basic.lean b/Mathlib/Data/Setoid/Basic.lean index 993671add13f70..ac8a272aeece69 100644 --- a/Mathlib/Data/Setoid/Basic.lean +++ b/Mathlib/Data/Setoid/Basic.lean @@ -75,7 +75,7 @@ theorem comm [Setoid α] {x y : α} : x ≈ y ↔ y ≈ x := open scoped Function -- required for scoped `on` notation /-- The kernel of a function is an equivalence relation. -/ -@[implicit_reducible] +@[instance_reducible] def ker (f : α → β) : Setoid α := ⟨(· = ·) on f, eq_equivalence.comap f⟩ @@ -94,7 +94,7 @@ theorem ker_def {f : α → β} {x y : α} : ker f x y ↔ f x = f y := /-- Given types `α`, `β`, the product of two equivalence relations `r` on `α` and `s` on `β`: `(x₁, x₂), (y₁, y₂) ∈ α × β` are related by `r.prod s` iff `x₁` is related to `y₁` by `r` and `x₂` is related to `y₂` by `s`. -/ -@[implicit_reducible] +@[instance_reducible] protected def prod (r : Setoid α) (s : Setoid β) : Setoid (α × β) where r x y := r x.1 y.1 ∧ s x.2 y.2 @@ -405,7 +405,7 @@ variable {r f} /-- Given a function `f : α → β` and equivalence relation `r` on `α`, the equivalence closure of the relation on `f`'s image defined by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` by `r`.' -/ -@[implicit_reducible] +@[instance_reducible] def map (r : Setoid α) (f : α → β) : Setoid β := Relation.EqvGen.setoid (Relation.Map r f f) @@ -427,7 +427,7 @@ theorem coe_map_of_ker_le (r : Setoid α) (f : α → β) (hf : ker f ≤ r) : /-- Given a surjective function f whose kernel is contained in an equivalence relation r, the equivalence relation on f's codomain defined by x ≈ y ↔ the elements of f⁻¹(x) are related to the elements of f⁻¹(y) by r. -/ -@[implicit_reducible] +@[instance_reducible] def mapOfSurjective (r : Setoid α) (f : α → β) (h : ker f ≤ r) (hf : Surjective f) : Setoid β := ⟨Relation.Map r f f, Relation.map_equivalence r.iseqv f hf h⟩ diff --git a/Mathlib/Data/Setoid/Partition.lean b/Mathlib/Data/Setoid/Partition.lean index 97ea7c4d5eb8ee..0bac6f516f6728 100644 --- a/Mathlib/Data/Setoid/Partition.lean +++ b/Mathlib/Data/Setoid/Partition.lean @@ -47,7 +47,7 @@ theorem eq_of_mem_eqv_class {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b (H x).unique ⟨hc, hb⟩ ⟨hc', hb'⟩ /-- Makes an equivalence relation from a set of sets partitioning α. -/ -@[implicit_reducible] +@[instance_reducible] def mkClasses (c : Set (Set α)) (H : ∀ a, ∃! b ∈ c, a ∈ b) : Setoid α where r x y := ∀ s ∈ c, x ∈ s → y ∈ s iseqv.refl := fun _ _ _ hx => hx @@ -143,7 +143,7 @@ theorem eqv_classes_of_disjoint_union {c : Set (Set α)} (hu : Set.sUnion c = @S ExistsUnique.intro b ⟨hc, ha⟩ fun _ hc' => H.elim_set hc'.1 hc _ hc'.2 ha /-- Makes an equivalence relation from a set of disjoints sets covering α. -/ -@[implicit_reducible] +@[instance_reducible] def setoidOfDisjointUnion {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α) (H : c.PairwiseDisjoint id) : Setoid α := Setoid.mkClasses c <| eqv_classes_of_disjoint_union hu H @@ -266,6 +266,7 @@ instance Partition.partialOrder : PartialOrder (Partitions α) where rw [Partitions.ext_iff, ← classes_mkClasses x.toSet x.isPartition, ← classes_mkClasses y.toSet y.isPartition, h] +set_option backward.isDefEq.respectTransparency.types false in variable (α) in /-- The order-preserving bijection between equivalence relations on a type `α`, and partitions of `α` into subsets. -/ @@ -447,7 +448,7 @@ theorem class_of {x : α} : setOf (hs.setoid x) = s (hs.index x) := theorem proj_fiber (x : hs.Quotient) : hs.proj ⁻¹' {x} = s (hs.equivQuotient.symm x) := Quotient.inductionOn' x fun x => by ext y - simp only [Set.mem_preimage, Set.mem_singleton_iff, hs.mem_iff_index_eq] + simp only [Set.mem_preimage, hs.mem_iff_index_eq] exact Quotient.eq'' /-- Combine functions with disjoint domains into a new function. diff --git a/Mathlib/Data/Sign/Basic.lean b/Mathlib/Data/Sign/Basic.lean index 11b5c9810b1f59..b475630e409071 100644 --- a/Mathlib/Data/Sign/Basic.lean +++ b/Mathlib/Data/Sign/Basic.lean @@ -180,6 +180,7 @@ theorem exists_signed_sum [DecidableEq α] (s : Finset α) (f : α → ℤ) : ⟨t, inferInstance, fun b => sgn b, fun b => g b, fun b => hg b, by simp [ht], fun a ha => (sum_attach t fun b ↦ ite (g b = a) (sgn b : ℤ) 0).trans <| hf _ ha⟩ +set_option backward.isDefEq.respectTransparency false in /-- We can decompose a sum of absolute value less than `n` into a sum of at most `n` signs. -/ theorem exists_signed_sum' [Nonempty α] [DecidableEq α] (s : Finset α) (f : α → ℤ) (n : ℕ) (h : (∑ i ∈ s, (f i).natAbs) ≤ n) : diff --git a/Mathlib/Data/Sign/Defs.lean b/Mathlib/Data/Sign/Defs.lean index 4fa45fab9a1170..71820f8607b848 100644 --- a/Mathlib/Data/Sign/Defs.lean +++ b/Mathlib/Data/Sign/Defs.lean @@ -22,6 +22,7 @@ This file defines the type of signs $\{-1, 0, 1\}$ and its basic arithmetic inst @[expose] public section +set_option backward.isDefEq.respectTransparency false in -- Don't generate unnecessary `sizeOf_spec` lemmas which the `simpNF` linter will complain about. set_option genSizeOfSpec false in /-- The type of signs. -/ diff --git a/Mathlib/Data/String/Basic.lean b/Mathlib/Data/String/Basic.lean index e452a26dbf3b4a..4f88876690e5c9 100644 --- a/Mathlib/Data/String/Basic.lean +++ b/Mathlib/Data/String/Basic.lean @@ -53,6 +53,7 @@ def ltb (s₁ s₂ : Legacy.Iterator) : Bool := else base₁ it₁.s it₂.s it₁.i it₂.i h₂ h₁ else base₂ it₁.s it₂.s it₁.i it₂.i h₂ +set_option backward.isDefEq.respectTransparency false in theorem ltb_cons_addChar' (c : Char) (s₁ s₂ : Legacy.Iterator) : ltb ⟨ofList (c :: s₁.s.toList), s₁.i + c⟩ ⟨ofList (c :: s₂.s.toList), s₂.i + c⟩ = ltb s₁ s₂ := by @@ -66,7 +67,7 @@ theorem ltb_cons_addChar' (c : Char) (s₁ s₂ : Legacy.Iterator) : | case2 s₁ s₂ h₁ h₂ h => rw [ltb, Legacy.Iterator.hasNext_cons_addChar, Legacy.Iterator.hasNext_cons_addChar, if_pos (by simpa using h₁), if_pos (by simpa using h₂), if_neg] - · simp only [Legacy.Iterator.curr, get_cons_addChar, ofList_toList, decide_eq_decide] + · simp only [Legacy.Iterator.curr, get_cons_addChar, ofList_toList] · simpa only [Legacy.Iterator.curr, get_cons_addChar, ofList_toList] using h | case3 s₁ s₂ h₁ h₂ => rw [ltb, Legacy.Iterator.hasNext_cons_addChar, Legacy.Iterator.hasNext_cons_addChar, diff --git a/Mathlib/Data/Sum/Basic.lean b/Mathlib/Data/Sum/Basic.lean index df94f81721431c..16c06d49f4f0fd 100644 --- a/Mathlib/Data/Sum/Basic.lean +++ b/Mathlib/Data/Sum/Basic.lean @@ -50,9 +50,11 @@ section get variable {x : α ⊕ β} +set_option backward.isDefEq.respectTransparency false in theorem eq_left_iff_getLeft_eq {a : α} : x = inl a ↔ ∃ h, x.getLeft h = a := by cases x <;> simp +set_option backward.isDefEq.respectTransparency false in theorem eq_right_iff_getRight_eq {b : β} : x = inr b ↔ ∃ h, x.getRight h = b := by cases x <;> simp diff --git a/Mathlib/Data/Sym/Basic.lean b/Mathlib/Data/Sym/Basic.lean index df918acd8a60df..bd3c5d8e2f6dd2 100644 --- a/Mathlib/Data/Sym/Basic.lean +++ b/Mathlib/Data/Sym/Basic.lean @@ -160,10 +160,12 @@ instance decidableMem [DecidableEq α] (a : α) (s : Sym α n) : Decidable (a theorem mem_mk (a : α) (s : Multiset α) (h : Multiset.card s = n) : a ∈ mk s h ↔ a ∈ s := Iff.rfl +set_option backward.isDefEq.respectTransparency false in lemma «forall» {p : Sym α n → Prop} : (∀ s : Sym α n, p s) ↔ ∀ (s : Multiset α) (hs : Multiset.card s = n), p (Sym.mk s hs) := by simp [Sym] +set_option backward.isDefEq.respectTransparency false in lemma «exists» {p : Sym α n → Prop} : (∃ s : Sym α n, p s) ↔ ∃ (s : Multiset α) (hs : Multiset.card s = n), p (Sym.mk s hs) := by simp [Sym] @@ -345,11 +347,13 @@ theorem mem_map {n : ℕ} {f : α → β} {b : β} {l : Sym α n} : b ∈ Sym.map f l ↔ ∃ a, a ∈ l ∧ f a = b := Multiset.mem_map +set_option backward.isDefEq.respectTransparency false in /-- Note: `Sym.map_id` is not simp-normal, as simp ends up unfolding `id` with `Sym.map_congr` -/ @[simp] theorem map_id' {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map (fun x : α => x) s = s := by ext; simp only [map, Multiset.map_id', ← val_eq_coe] +set_option backward.isDefEq.respectTransparency false in theorem map_id {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map id s = s := by ext; simp only [map, id_eq, Multiset.map_id', ← val_eq_coe] @@ -459,6 +463,7 @@ theorem append_inj_right (s : Sym α n) {t t' : Sym α n'} : s.append t = s.appe theorem append_inj_left {s s' : Sym α n} (t : Sym α n') : s.append t = s'.append t ↔ s = s' := Subtype.ext_iff.trans <| (add_left_inj _).trans Subtype.ext_iff.symm +set_option backward.isDefEq.respectTransparency false in theorem append_comm (s : Sym α n') (s' : Sym α n') : s.append s' = Sym.cast (add_comm _ _) (s'.append s) := by simp [append, add_comm] @@ -470,6 +475,7 @@ theorem coe_append (s : Sym α n) (s' : Sym α n') : (s.append s' : Multiset α) theorem mem_append_iff {s' : Sym α m} : a ∈ s.append s' ↔ a ∈ s ∨ a ∈ s' := Multiset.mem_add +set_option backward.isDefEq.respectTransparency false in /-- `a ↦ {a}` as an equivalence between `α` and `Sym α 1`. -/ @[simps apply] def oneEquiv : α ≃ Sym α 1 where diff --git a/Mathlib/Data/Sym/Sym2.lean b/Mathlib/Data/Sym/Sym2.lean index d335f439ab8dd3..de8e76ca24efcc 100644 --- a/Mathlib/Data/Sym/Sym2.lean +++ b/Mathlib/Data/Sym/Sym2.lean @@ -604,6 +604,7 @@ theorem mem_fromRel_comap {r : β → β → Prop} (sym : Std.Symm r) (f : α cases z simp +set_option backward.isDefEq.respectTransparency false in theorem fromRel_bot : fromRel (α := α) (r := ⊥) inferInstance = ∅ := Set.eq_empty_of_forall_notMem <| Sym2.ind <| by simp @@ -613,6 +614,7 @@ theorem fromRel_bot_iff {sym : Std.Symm r} : fromRel sym = ∅ ↔ r = ⊥ := by ext x y simpa [h] using fromRel_prop (sym := sym) +set_option backward.isDefEq.respectTransparency false in theorem fromRel_top : fromRel (α := α) (r := ⊤) inferInstance = .univ := Set.eq_univ_of_forall <| Sym2.ind <| by simp @@ -622,12 +624,14 @@ theorem fromRel_top_iff {sym : Std.Symm r} : fromRel sym = .univ ↔ r = ⊤ := ext x y simpa [h] using fromRel_prop (sym := sym) +set_option backward.isDefEq.respectTransparency false in theorem fromRel_ne : fromRel (α := α) (r := Ne) inferInstance = {z | ¬IsDiag z} := by ext z; exact z.ind (by simp) lemma diagSet_eq_fromRel_eq : diagSet = fromRel (α := α) eq_equivalence.stdSymm := by ext ⟨a, b⟩; simp +set_option backward.isDefEq.respectTransparency false in lemma diagSet_compl_eq_fromRel_ne : diagSetᶜ = fromRel (α := α) (r := Ne) inferInstance := by ext ⟨a, b⟩; simp @@ -739,6 +743,7 @@ variable (α) in def toRelOrderEmbedding : Set (Sym2 α) ↪o (α → α → Prop) := .ofMapLEIff ToRel toRel_mono_iff +set_option backward.isDefEq.respectTransparency false in variable (α) in /-- `fromRel`/`ToRel` induce an order isomorphism between symmetric relations and `Sym2` sets -/ @[simps] diff --git a/Mathlib/Data/TypeVec.lean b/Mathlib/Data/TypeVec.lean index faf2abfe4dfdc1..545b1731af319a 100644 --- a/Mathlib/Data/TypeVec.lean +++ b/Mathlib/Data/TypeVec.lean @@ -453,6 +453,7 @@ def prod.mk : ∀ {n} {α β : TypeVec.{u} n} (i : Fin2 n), α i → β i → ( end +set_option backward.isDefEq.respectTransparency false in @[simp] theorem prod_fst_mk {α β : TypeVec n} (i : Fin2 n) (a : α i) (b : β i) : TypeVec.prod.fst i (prod.mk i a b) = a := by @@ -460,6 +461,7 @@ theorem prod_fst_mk {α β : TypeVec n} (i : Fin2 n) (a : α i) (b : β i) : | fz => simp_all only [prod.fst, prod.mk] | fs _ i_ih => apply i_ih +set_option backward.isDefEq.respectTransparency false in @[simp] theorem prod_snd_mk {α β : TypeVec n} (i : Fin2 n) (a : α i) (b : β i) : TypeVec.prod.snd i (prod.mk i a b) = b := by @@ -555,6 +557,7 @@ theorem subtypeVal_nil {α : TypeVec.{u} 0} (ps : α ⟹ «repeat» 0 Prop) : TypeVec.subtypeVal ps = nilFun := funext <| by rintro ⟨⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem diag_sub_val {n} {α : TypeVec.{u} n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag := by ext i x @@ -641,6 +644,7 @@ theorem dropFun_id {α : TypeVec (n + 1)} : dropFun (@TypeVec.id _ α) = id := @[simp] theorem prod_map_id {α β : TypeVec n} : (@TypeVec.id _ α ⊗' @TypeVec.id _ β) = id := prod_id +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toSubtype_of_subtype {α : TypeVec n} (p : α ⟹ «repeat» n Prop) : toSubtype p ⊚ ofSubtype p = id := by @@ -648,6 +652,7 @@ theorem toSubtype_of_subtype {α : TypeVec n} (p : α ⟹ «repeat» n Prop) : induction i <;> simp only [id, toSubtype, comp, ofSubtype] at * simp [*] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem subtypeVal_toSubtype {α : TypeVec n} (p : α ⟹ «repeat» n Prop) : subtypeVal p ⊚ toSubtype p = fun _ => Subtype.val := by @@ -655,12 +660,14 @@ theorem subtypeVal_toSubtype {α : TypeVec n} (p : α ⟹ «repeat» n Prop) : induction i <;> simp only [toSubtype, comp, subtypeVal] at * simp [*] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toSubtype_of_subtype_assoc {α β : TypeVec n} (p : α ⟹ «repeat» n Prop) (f : β ⟹ Subtype_ p) : @toSubtype n _ p ⊚ ofSubtype _ ⊚ f = f := by rw [← comp_assoc, toSubtype_of_subtype]; simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toSubtype'_of_subtype' {α : TypeVec n} (r : α ⊗ α ⟹ «repeat» n Prop) : toSubtype' r ⊚ ofSubtype' r = id := by diff --git a/Mathlib/Data/Vector/Basic.lean b/Mathlib/Data/Vector/Basic.lean index a056a01b21f9fc..efc2b10a439fc4 100644 --- a/Mathlib/Data/Vector/Basic.lean +++ b/Mathlib/Data/Vector/Basic.lean @@ -149,6 +149,7 @@ theorem get_eq_get_toList (v : Vector α n) (i : Fin n) : theorem get_replicate (a : α) (i : Fin n) : (Vector.replicate n a).get i = a := by apply List.getElem_replicate +set_option backward.isDefEq.respectTransparency false in @[simp] theorem get_map {β : Type*} (v : Vector α n) (f : α → β) (i : Fin n) : (v.map f).get i = f (v.get i) := by @@ -253,6 +254,7 @@ to the `List.reverse` after retrieving a vector's `toList`. -/ theorem toList_reverse {v : Vector α n} : v.reverse.toList = v.toList.reverse := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem reverse_reverse {v : Vector α n} : v.reverse.reverse = v := by cases v @@ -287,6 +289,7 @@ def last (v : Vector α (n + 1)) : α := theorem last_def {v : Vector α (n + 1)} : v.last = v.get (Fin.last n) := rfl +set_option backward.isDefEq.respectTransparency false in /-- The `last` element of a vector is the `head` of the `reverse` vector. -/ theorem reverse_get_zero {v : Vector α (n + 1)} : v.reverse.head = v.last := by rw [← get_zero, last_def, get_eq_get_toList, get_eq_get_toList] @@ -310,6 +313,7 @@ def scanl : Vector β (n + 1) := theorem scanl_nil : scanl f b nil = b ::ᵥ nil := by ext; simp [scanl, get] +set_option backward.isDefEq.respectTransparency false in /-- The recursive step of `scanl` splits a vector `x ::ᵥ v : Vector α (n + 1)` into the provided starting value `b : β` and the recursed `scanl` `f b x : β` as the starting value. @@ -593,10 +597,12 @@ theorem toList_set (v : Vector α n) (i : Fin n) (a : α) : (v.set i a).toList = v.toList.set i a := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem get_set_same (v : Vector α n) (i : Fin n) (a : α) : (v.set i a).get i = a := by cases v; cases i; simp [Vector.set, get_eq_get_toList] +set_option backward.isDefEq.respectTransparency false in theorem get_set_of_ne {v : Vector α n} {i j : Fin n} (h : i ≠ j) (a : α) : (v.set i a).get j = v.get j := by cases v; cases i; cases j @@ -656,6 +662,7 @@ protected theorem traverse_def (f : α → F β) (x : α) : ∀ xs : Vector α n, (x ::ᵥ xs).traverse f = cons <$> f x <*> xs.traverse f := by rintro ⟨xs, rfl⟩; rfl +set_option backward.isDefEq.respectTransparency false in protected theorem id_traverse : ∀ x : Vector α n, x.traverse (pure : _ → Id _) = pure x := by rintro ⟨x, rfl⟩; dsimp [Vector.traverse, cast] induction x with | nil => rfl | cons x xs IH => simp! [IH] @@ -681,6 +688,7 @@ protected theorem comp_traverse (f : β → F γ) (g : α → G β) (x : Vector rw [Vector.traverse_def, ih] simp [functor_norm, Function.comp_def] +set_option backward.isDefEq.respectTransparency false in protected theorem traverse_eq_map_id {α β} (f : α → β) : ∀ x : Vector α n, x.traverse ((pure : _ → Id _) ∘ f) = pure (map f x) := by rintro ⟨x, rfl⟩ @@ -704,6 +712,7 @@ instance : Traversable.{u} (flip Vector n) where traverse := @Vector.traverse n map {α β} := @Vector.map.{u, u} α β n +set_option backward.isDefEq.respectTransparency false in instance : LawfulTraversable.{u} (flip Vector n) where id_traverse := @Vector.id_traverse n comp_traverse := Vector.comp_traverse @@ -732,6 +741,7 @@ theorem get_append_cons_succ {i : Fin (n + m)} {h} : get (x ::ᵥ xs ++ ys) ⟨i+1, h⟩ = get (xs ++ ys) i := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem append_nil : xs ++ (nil : Vector α 0) = xs := by cases xs; simp only [append_def, append_nil] diff --git a/Mathlib/Data/Vector/Defs.lean b/Mathlib/Data/Vector/Defs.lean index 89bab3a49148cd..d8d1e7526b95df 100644 --- a/Mathlib/Data/Vector/Defs.lean +++ b/Mathlib/Data/Vector/Defs.lean @@ -121,6 +121,7 @@ theorem map_nil (f : α → β) : map f nil = nil := theorem map_cons (f : α → β) (a : α) : ∀ v : Vector α n, map f (cons a v) = cons (f a) (map f v) | ⟨_, _⟩ => rfl +set_option backward.isDefEq.respectTransparency false in /-- Map a vector under a partial function. -/ def pmap (f : (a : α) → p a → β) : (v : Vector α n) → (∀ x ∈ v.toList, p x) → Vector β n diff --git a/Mathlib/Data/W/Basic.lean b/Mathlib/Data/W/Basic.lean index b55386b033176f..7e36e862eda898 100644 --- a/Mathlib/Data/W/Basic.lean +++ b/Mathlib/Data/W/Basic.lean @@ -135,7 +135,7 @@ private abbrev WType' {α : Type*} (β : α → Type*) [∀ a : α, Fintype (β variable [∀ a : α, Encodable (β a)] set_option backward.privateInPublic true in -@[implicit_reducible] +@[instance_reducible] private def encodable_zero : Encodable (WType' β 0) := let f : WType' β 0 → Empty := fun ⟨_, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _) let finv : Empty → WType' β 0 := by @@ -160,7 +160,7 @@ private def finv (n : ℕ) : (Σ a : α, β a → WType' β n) → WType' β (n variable [Encodable α] set_option backward.privateInPublic true in -@[implicit_reducible] +@[instance_reducible] private def encodable_succ (n : Nat) (_ : Encodable (WType' β n)) : Encodable (WType' β (n + 1)) := Encodable.ofLeftInverse (f n) (finv n) (by diff --git a/Mathlib/Data/W/Constructions.lean b/Mathlib/Data/W/Constructions.lean index 8dc05293a2f845..2067c3a93ca2df 100644 --- a/Mathlib/Data/W/Constructions.lean +++ b/Mathlib/Data/W/Constructions.lean @@ -148,6 +148,7 @@ def toList : WType (Listβ γ) → List γ | WType.mk Listα.nil _ => [] | WType.mk (Listα.cons hd) f => hd :: (f PUnit.unit).toList +set_option backward.isDefEq.respectTransparency false in theorem leftInverse_list : Function.LeftInverse (ofList γ) (toList _) | WType.mk Listα.nil f => by simp only [toList, ofList, mk.injEq, heq_eq_eq, true_and] diff --git a/Mathlib/Data/WSeq/Basic.lean b/Mathlib/Data/WSeq/Basic.lean index d3fe87d6ca7e15..de21e257ef189d 100644 --- a/Mathlib/Data/WSeq/Basic.lean +++ b/Mathlib/Data/WSeq/Basic.lean @@ -185,10 +185,12 @@ open Computation theorem destruct_nil : destruct (nil : WSeq α) = Computation.pure none := Computation.destruct_eq_pure rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem destruct_cons (a : α) (s) : destruct (cons a s) = Computation.pure (some (a, s)) := Computation.destruct_eq_pure <| by simp [destruct, cons, Computation.rmap] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem destruct_think (s : WSeq α) : destruct (think s) = (destruct s).think := Computation.destruct_eq_think <| by simp [destruct, think, Computation.rmap] @@ -214,6 +216,7 @@ theorem head_cons (a : α) (s) : head (cons a s) = Computation.pure (some a) := @[simp] theorem head_think (s : WSeq α) : head (think s) = (head s).think := by simp [head] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem flatten_pure (s : WSeq α) : flatten (Computation.pure s) = s := by refine Seq.eq_of_bisim (fun s1 s2 => flatten (Computation.pure s2) = s1) ?_ rfl @@ -226,6 +229,7 @@ theorem flatten_pure (s : WSeq α) : flatten (Computation.pure s) = s := by obtain ⟨o, s'⟩ := val simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem flatten_think (c : Computation (WSeq α)) : flatten c.think = think (flatten c) := Seq.destruct_eq_cons <| by simp [flatten] @@ -290,12 +294,14 @@ theorem get?_tail (s : WSeq α) (n) : get? (tail s) n = get? s (n + 1) := theorem join_nil : join nil = (nil : WSeq α) := Seq.join_nil +set_option backward.isDefEq.respectTransparency false in @[simp] theorem join_think (S : WSeq (WSeq α)) : join (think S) = think (join S) := by simp only [join, think] dsimp only [(· <$> ·)] simp [Seq1.ret] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem join_cons (s : WSeq α) (S) : join (cons s S) = think (append s (join S)) := by simp only [join, think] @@ -553,6 +559,7 @@ theorem toList'_nil (l : List α) : | some (some a, s') => Sum.inr (a::l, s')) (l, nil) = Computation.pure l.reverse := destruct_eq_pure rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toList'_cons (l : List α) (s : WSeq α) (a : α) : Computation.corec (fun ⟨l, s⟩ => @@ -567,6 +574,7 @@ theorem toList'_cons (l : List α) (s : WSeq α) (a : α) : | some (some a, s') => Sum.inr (a::l, s')) (a::l, s)).think := destruct_eq_think <| by simp [cons] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toList'_think (l : List α) (s : WSeq α) : Computation.corec (fun ⟨l, s⟩ => @@ -626,6 +634,7 @@ theorem toList_ofList (l : List α) : l ∈ toList (ofList l) := by | nil => simp | cons a l IH => simpa [ret_mem] using! think_mem (Computation.mem_map _ IH) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem destruct_ofSeq (s : Seq α) : destruct (ofSeq s) = Computation.pure (s.head.map fun a => (a, ofSeq s.tail)) := @@ -643,6 +652,7 @@ theorem head_ofSeq (s : Seq α) : head (ofSeq s) = Computation.pure s.head := by simp only [head, Option.map_eq_map, destruct_ofSeq, Computation.map_pure, Option.map_map] cases Seq.head s <;> rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem tail_ofSeq (s : Seq α) : tail (ofSeq s) = ofSeq s.tail := by simp only [tail, destruct_ofSeq, map_pure', flatten_pure] @@ -672,6 +682,7 @@ theorem map_cons (f : α → β) (a s) : map f (cons a s) = cons (f a) (map f s) theorem map_think (f : α → β) (s) : map f (think s) = think (map f s) := Seq.map_cons _ _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_id (s : WSeq α) : map id s = s := by simp [map] @@ -682,6 +693,7 @@ theorem map_ret (f : α → β) (a) : map f (ret a) = ret (f a) := by simp [ret] theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) := Seq.map_append _ _ _ +set_option backward.isDefEq.respectTransparency false in theorem map_comp (f : α → β) (g : β → γ) (s : WSeq α) : map (g ∘ f) s = map g (map f s) := by dsimp [map]; rw [← Seq.map_comp] apply congr_fun; apply congr_arg @@ -787,6 +799,7 @@ theorem destruct_join (S : WSeq (WSeq α)) : case nil | cons => simp case think S => exact Or.inr ⟨S, by simp⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_join (f : α → β) (S) : map f (join S) = join (map (map f) S) := by apply diff --git a/Mathlib/Data/ZMod/Aut.lean b/Mathlib/Data/ZMod/Aut.lean index 6513919ba3f4a4..14e064c9320f45 100644 --- a/Mathlib/Data/ZMod/Aut.lean +++ b/Mathlib/Data/ZMod/Aut.lean @@ -20,6 +20,7 @@ namespace ZMod variable (n : ℕ) +set_option backward.isDefEq.respectTransparency.types false in /-- The automorphism group of `ZMod n` is isomorphic to the group of units of `ZMod n`. -/ @[simps] def AddAutEquivUnits : AddAut (ZMod n) ≃+ Additive (ZMod n)ˣ := diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index d634b3c113afa1..a698c0f0b8cc3c 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -249,6 +249,7 @@ theorem natCast_comp_val [NeZero n] : ((↑) : ℕ → R) ∘ (val : ZMod n → · cases NeZero.ne 0 rfl rfl +set_option backward.isDefEq.respectTransparency false in /-- The coercions are respectively `Int.cast`, `ZMod.cast`, and `ZMod.cast`. -/ @[simp] theorem intCast_comp_cast : ((↑) : ℤ → R) ∘ (cast : ZMod n → ℤ) = cast := by @@ -874,6 +875,7 @@ def unitsEquivCoprime {n : ℕ} [NeZero n] : (ZMod n)ˣ ≃ { x : ZMod n // Nat. left_inv := fun ⟨_, _, _, _⟩ => Units.ext (natCast_zmod_val _) right_inv := fun ⟨_, _⟩ => by simp +set_option backward.isDefEq.respectTransparency false in /-- The **Chinese remainder theorem**. For a pair of coprime natural numbers, `m` and `n`, the rings `ZMod (m * n)` and `ZMod m × ZMod n` are isomorphic. @@ -1110,6 +1112,7 @@ instance subsingleton_ringEquiv [Semiring R] : Subsingleton (ZMod n ≃+* R) := rw [RingEquiv.coe_ringHom_inj_iff] apply RingHom.ext_zmod _ _⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ringHom_map_cast [NonAssocRing R] (f : R →+* ZMod n) (k : ZMod n) : f (cast k) = k := by cases n diff --git a/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean b/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean index a216b78da990f8..bba79bbe89394b 100644 --- a/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean +++ b/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean @@ -193,6 +193,7 @@ theorem units_inv_apply_apply (f : CircleDeg1Liftˣ) (x : ℝ) : theorem units_apply_inv_apply (f : CircleDeg1Liftˣ) (x : ℝ) : f ((f⁻¹ : CircleDeg1Liftˣ) x) = x := by simp only [← mul_apply, f.mul_inv, coe_one, id] +set_option backward.isDefEq.respectTransparency false in /-- If a lift of a circle map is bijective, then it is an order automorphism of the line. -/ def toOrderIso : CircleDeg1Liftˣ →* ℝ ≃o ℝ where toFun f := diff --git a/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean b/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean index 4387e479b994e7..85530fc09bd5a8 100644 --- a/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean +++ b/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean @@ -124,6 +124,7 @@ theorem aeconst_of_dense_aestabilizer_smul (hsm : NullMeasurableSet s μ) aeconst_of_dense_setOf_preimage_smul_ae hsm <| (hd.preimage (isOpenMap_inv _)).mono fun g hg ↦ by simpa only [preimage_smul] using! hg +set_option backward.isDefEq.respectTransparency.types false in /-- If a monoid `M` continuously acts on an R₁ topological space `X`, `g` is an element of `M` such that its integer powers are dense in `M`, and `μ` is a finite inner regular measure on `X` which is ergodic with respect to the action of `M`, diff --git a/Mathlib/Dynamics/Ergodic/AddCircle.lean b/Mathlib/Dynamics/Ergodic/AddCircle.lean index 18cc7d4d865a22..c9104d3a6f682c 100644 --- a/Mathlib/Dynamics/Ergodic/AddCircle.lean +++ b/Mathlib/Dynamics/Ergodic/AddCircle.lean @@ -102,6 +102,7 @@ theorem ae_empty_or_univ_of_forall_vadd_ae_eq_self {s : Set <| AddCircle T} volume_of_add_preimage_eq s _ (u j) d huj (hu₁ j) closedBall_ae_eq_ball, nsmul_eq_mul, ← mul_assoc, this, hI₂] +set_option backward.isDefEq.respectTransparency.types false in theorem ergodic_zsmul {n : ℤ} (hn : 1 < |n|) : Ergodic fun y : AddCircle T => n • y := { measurePreserving_zsmul volume (abs_pos.mp <| lt_trans zero_lt_one hn) with aeconst_set := fun s hs hs' => by diff --git a/Mathlib/Dynamics/Ergodic/Ergodic.lean b/Mathlib/Dynamics/Ergodic/Ergodic.lean index a6f34fde5c1924..53751f0469617b 100644 --- a/Mathlib/Dynamics/Ergodic/Ergodic.lean +++ b/Mathlib/Dynamics/Ergodic/Ergodic.lean @@ -82,6 +82,7 @@ theorem smul_measure {R : Type*} [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ (hf : PreErgodic f μ) (c : R) : PreErgodic f (c • μ) where aeconst_set _s hs hfs := (hf.aeconst_set hs hfs).anti <| ae_smul_measure_le _ +set_option backward.isDefEq.respectTransparency false in theorem zero_measure (f : α → α) : @PreErgodic α m f 0 where aeconst_set _ _ _ := by simp diff --git a/Mathlib/Dynamics/Flow.lean b/Mathlib/Dynamics/Flow.lean index 87698e7d8c728b..61f9826be4b98b 100644 --- a/Mathlib/Dynamics/Flow.lean +++ b/Mathlib/Dynamics/Flow.lean @@ -165,7 +165,7 @@ section AddMonoid variable [AddMonoid τ] (ϕ : Flow τ α) /-- Convert a flow to an additive monoid action. -/ -@[implicit_reducible] +@[instance_reducible] def toAddAction : AddAction τ α where vadd := ϕ add_vadd := ϕ.map_add' diff --git a/Mathlib/FieldTheory/AxGrothendieck.lean b/Mathlib/FieldTheory/AxGrothendieck.lean index 20b6578c37b418..3c5442821041e6 100644 --- a/Mathlib/FieldTheory/AxGrothendieck.lean +++ b/Mathlib/FieldTheory/AxGrothendieck.lean @@ -90,7 +90,7 @@ end namespace FirstOrder -open MvPolynomial FreeCommRing Language Field Ring BoundedFormula +open MvPolynomial FreeCommRing Language FirstOrder.Field FirstOrder.Ring BoundedFormula variable {ι α : Type*} [Finite α] {K : Type*} [Field K] [CompatibleRing K] diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index d21c2965a25f5b..424727a4a73e24 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -280,6 +280,7 @@ lemma eq_bot_of_not_nonempty (hi : ¬ Nonempty (Iio i)) : filtration i = ⊥ := rw [← range_coe] at hi; exact (hi inferInstance).elim · exact bot_unique <| adjoin_le_iff.mpr fun _ ⟨j, hj, _⟩ ↦ (hi ⟨j, coe_lt_coe.mpr hj⟩).elim +set_option backward.isDefEq.respectTransparency.types false in open scoped Classical in /-- If `i` is a limit, the type of embeddings of `E⟮ Polynomial.Splits.X_sub_C _ +set_option backward.isDefEq.respectTransparency.types false in instance isSeparable : Algebra.IsSeparable (FixedPoints.subfield G F) F := by classical exact ⟨fun x => by diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 507a2b42dbd982..e02c00401d25c4 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -277,6 +277,7 @@ noncomputable def intermediateFieldEquivSubgroup [Finite G] : theorem ofDual_intermediateFieldEquivSubgroup_apply [Finite G] {F} : (intermediateFieldEquivSubgroup G K L F).ofDual = fixingSubgroup G (F : Set L) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem intermediateFieldEquivSubgroup_symm_apply [Finite G] {H} : (intermediateFieldEquivSubgroup G K L).symm H = FixedPoints.intermediateField H.ofDual := by obtain ⟨H, rfl⟩ := OrderDual.toDual.surjective H @@ -496,6 +497,7 @@ instance [Finite G] [IsGaloisGroup G K L] : IsGaloisGroup (G ⧸ N) K F := variable (E : IntermediateField K L) [hE : IsGaloisGroup H E L] +set_option backward.isDefEq.respectTransparency false in /-- If `G` is a finite Galois group for `L/K`, `N` is a normal subgroup that is a Galois group for `L/F`, and `H` is a subgroup that is a Galois group for `L/E` with `E ≤ F`, then the image of `H` under the canonical quotient map `G → G ⧸ N` is a Galois group for `F/E`. -/ diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean index 8dd79bbbdeb15e..c9f959ad11ac34 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean @@ -598,7 +598,7 @@ lemma algHomAdjoinIntegralEquiv_symm_apply_gen (h : IsIntegral F α) rw [adjoin.powerBasis_gen, minpoly_gen]; exact (mem_aroots.mp x.2).2 /-- Fintype of algebra homomorphism `F⟮α⟯ →ₐ[F] K` -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfAlgHomAdjoinIntegral (h : IsIntegral F α) : Fintype (F⟮α⟯ →ₐ[F] K) := PowerBasis.AlgHom.fintype (adjoin.powerBasis h) diff --git a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index 4edff2d094433e..345784f10d4501 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -82,6 +82,7 @@ def toSplittingField (s : Finset (Monics k)) : MvPolynomial.aeval fun fi ↦ if hf : fi.1 ∈ s then (finEquivRoots (Monics.splits_finsetProd hf) fi.2).1.1 else 37 +set_option backward.isDefEq.respectTransparency.types false in theorem toSplittingField_coeff {s : Finset (Monics k)} {f} (h : f ∈ s) (n) : toSplittingField s ((subProdXSubC f).coeff n) = 0 := by classical @@ -195,6 +196,7 @@ instance isAlgebraic : Algebra.IsAlgebraic k (AlgebraicClosure k) := erw [eval_C] simp⟩ +set_option backward.isDefEq.respectTransparency.types false in instance : IsAlgClosure k (AlgebraicClosure k) := .of_splits fun f hf _ ↦ by rw [show f = (⟨f, hf⟩ : Monics k) from rfl, Monics.map_eq_prod] exact Splits.prod fun _ _ ↦ (Splits.X_sub_C _).map _ diff --git a/Mathlib/FieldTheory/Isaacs.lean b/Mathlib/FieldTheory/Isaacs.lean index e29985c0cc2fe2..fd073efbf3b5f5 100644 --- a/Mathlib/FieldTheory/Isaacs.lean +++ b/Mathlib/FieldTheory/Isaacs.lean @@ -38,6 +38,7 @@ open Polynomial IntermediateField variable {F E K : Type*} [Field F] [Field E] [Field K] [Algebra F E] [Algebra F K] variable [alg : Algebra.IsAlgebraic F E] +set_option backward.isDefEq.respectTransparency.types false in theorem nonempty_algHom_of_exists_root (h : ∀ x : E, ∃ y : K, aeval y (minpoly F x) = 0) : Nonempty (E →ₐ[F] K) := by refine Lifts.nonempty_algHom_of_exist_lifts_finset fun S ↦ ⟨⟨adjoin F S, ?_⟩, subset_adjoin _ _⟩ diff --git a/Mathlib/FieldTheory/KrullTopology.lean b/Mathlib/FieldTheory/KrullTopology.lean index ce6489c15a827b..f76f89179d1b37 100644 --- a/Mathlib/FieldTheory/KrullTopology.lean +++ b/Mathlib/FieldTheory/KrullTopology.lean @@ -96,7 +96,7 @@ theorem mem_galBasis_iff (K L : Type*) [Field K] [Field L] [Algebra K L] (U : Se /-- For a field extension `L/K`, `galGroupBasis K L` is the group filter basis on `Gal(L/K)` whose sets are `Gal(L/E)` for finite subextensions `E/K`. -/ -@[implicit_reducible] +@[instance_reducible] def galGroupBasis (K L : Type*) [Field K] [Field L] [Algebra K L] : GroupFilterBasis Gal(L/K) where toFilterBasis := galBasis K L diff --git a/Mathlib/FieldTheory/KummerExtension.lean b/Mathlib/FieldTheory/KummerExtension.lean index 72af873d95f851..24c9e2b4b77bf8 100644 --- a/Mathlib/FieldTheory/KummerExtension.lean +++ b/Mathlib/FieldTheory/KummerExtension.lean @@ -218,6 +218,7 @@ def autAdjoinRootXPowSubC : variable {n} +set_option backward.isDefEq.respectTransparency.types false in lemma autAdjoinRootXPowSubC_root (η) : autAdjoinRootXPowSubC n a η (root _) = ((η : Kˣ) : K) • root _ := by dsimp [autAdjoinRootXPowSubC, autAdjoinRootXPowSubCHom, AlgEquiv.algHomUnitsEquiv] diff --git a/Mathlib/FieldTheory/Minpoly/Field.lean b/Mathlib/FieldTheory/Minpoly/Field.lean index f4759385159d6a..47a6d5a318f348 100644 --- a/Mathlib/FieldTheory/Minpoly/Field.lean +++ b/Mathlib/FieldTheory/Minpoly/Field.lean @@ -216,7 +216,7 @@ section AlgHomFintype open scoped Classical in /-- A technical finiteness result. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Fintype.subtypeProd {E : Type*} {X : Set E} (hX : X.Finite) {L : Type*} (F : E → Multiset L) : Fintype (∀ x : X, { l : L // l ∈ F x }) := @Pi.instFintype _ _ _ (Finite.fintype hX) _ diff --git a/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean b/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean index 05bd01e589e60e..2f800421e5c2c9 100644 --- a/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean +++ b/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean @@ -82,7 +82,7 @@ variable (R A) in /-- The setoid structure on `A` defined by the equivalence relation of `IsConjRoot R · ·`. -/ -@[implicit_reducible] +@[instance_reducible] def setoid : Setoid A where r := IsConjRoot R iseqv := ⟨fun _ => refl, symm, trans⟩ diff --git a/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean b/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean index 98287a725d13c4..6a4a871ae1fac2 100644 --- a/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean +++ b/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean @@ -230,6 +230,7 @@ def _root_.Algebra.adjoin.powerBasis' (hx : IsIntegral R x) : theorem _root_.Algebra.adjoin.powerBasis'_dim (hx : IsIntegral R x) : (Algebra.adjoin.powerBasis' hx).dim = (minpoly R x).natDegree := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem _root_.Algebra.adjoin.powerBasis'_gen (hx : IsIntegral R x) : (adjoin.powerBasis' hx).gen = ⟨x, SetLike.mem_coe.1 <| subset_adjoin <| mem_singleton x⟩ := by diff --git a/Mathlib/FieldTheory/Perfect.lean b/Mathlib/FieldTheory/Perfect.lean index f84e7d48620242..da06cd2ce3611e 100644 --- a/Mathlib/FieldTheory/Perfect.lean +++ b/Mathlib/FieldTheory/Perfect.lean @@ -314,6 +314,7 @@ instance ofFinite [Finite K] : PerfectField K := by variable [PerfectField K] +set_option backward.isDefEq.respectTransparency.types false in /-- A perfect field of characteristic `p` (prime) is a perfect ring. -/ instance toPerfectRing (p : ℕ) [hp : ExpChar K p] : PerfectRing K p := by refine PerfectRing.ofSurjective _ _ fun y ↦ ?_ diff --git a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean index b752e99329a38f..ff6b43f8c4c4f2 100644 --- a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean +++ b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean @@ -66,8 +66,9 @@ theorem ext {σ τ : p.Gal} (h : ∀ x ∈ p.rootSet p.SplittingField, σ x = τ ((SetLike.ext_iff.mp ?_ x).mpr Algebra.mem_top) rwa [eq_top_iff, ← SplittingField.adjoin_rootSet, Algebra.adjoin_le_iff] +set_option backward.isDefEq.respectTransparency.types false in /-- If `p` splits in `F` then the `p.gal` is trivial. -/ -@[implicit_reducible] +@[instance_reducible] def uniqueGalOfSplits (h : p.Splits) : Unique p.Gal where default := 1 uniq f := @@ -77,24 +78,31 @@ def uniqueGalOfSplits (h : p.Splits) : Unique p.Gal where ((SetLike.ext_iff.mp ((IsSplittingField.splits_iff _ p).mp h) x).mp Algebra.mem_top) rw [AlgEquiv.commutes, AlgEquiv.commutes] +set_option backward.isDefEq.respectTransparency.types false in instance [h : Fact p.Splits] : Unique p.Gal := uniqueGalOfSplits _ h.1 +set_option backward.isDefEq.respectTransparency.types false in instance uniqueGalZero : Unique (0 : F[X]).Gal := uniqueGalOfSplits _ (by simp) +set_option backward.isDefEq.respectTransparency.types false in instance uniqueGalOne : Unique (1 : F[X]).Gal := uniqueGalOfSplits _ Splits.one +set_option backward.isDefEq.respectTransparency.types false in instance uniqueGalC (x : F) : Unique (C x).Gal := uniqueGalOfSplits _ (by simp) +set_option backward.isDefEq.respectTransparency.types false in instance uniqueGalX : Unique (X : F[X]).Gal := uniqueGalOfSplits _ Splits.X +set_option backward.isDefEq.respectTransparency.types false in instance uniqueGalXSubC (x : F) : Unique (X - C x).Gal := uniqueGalOfSplits _ (Splits.X_sub_C _) +set_option backward.isDefEq.respectTransparency.types false in instance uniqueGalXPow (n : ℕ) : Unique (X ^ n : F[X]).Gal := uniqueGalOfSplits _ (Splits.X_pow _) diff --git a/Mathlib/FieldTheory/PrimitiveElement.lean b/Mathlib/FieldTheory/PrimitiveElement.lean index 7d3989b23c48dd..401ea67e9c9e43 100644 --- a/Mathlib/FieldTheory/PrimitiveElement.lean +++ b/Mathlib/FieldTheory/PrimitiveElement.lean @@ -83,6 +83,7 @@ section PrimitiveElementInf variable {F : Type*} [Field F] [Infinite F] {E : Type*} [Field E] (ϕ : F →+* E) (α β : E) +set_option backward.isDefEq.respectTransparency.types false in theorem primitive_element_inf_aux_exists_c (f g : F[X]) : ∃ c : F, ∀ α' ∈ (f.map ϕ).roots, ∀ β' ∈ (g.map ϕ).roots, -(α' - α) / (β' - β) ≠ ϕ c := by let sf := (f.map ϕ).roots diff --git a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean index 3723fd1cc88636..aa919a1e7c4190 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/Basic.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/Basic.lean @@ -619,6 +619,7 @@ lemma adjoin_eq_of_isAlgebraic_of_isSeparable [Algebra.IsAlgebraic F E] obtain ⟨y, rfl⟩ := IsPurelyInseparable.surjective_algebraMap_of_isSeparable L K x exact y.2 +set_option backward.isDefEq.respectTransparency.types false in /-- If `K / E / F` is a field extension tower, such that `E / F` is algebraic, then `E` adjoin `separableClosure F K` is equal to `separableClosure E K`. -/ theorem adjoin_eq_of_isAlgebraic [Algebra.IsAlgebraic F E] : diff --git a/Mathlib/FieldTheory/RatFunc/Basic.lean b/Mathlib/FieldTheory/RatFunc/Basic.lean index 4425d45880ab37..942da14ed1066c 100644 --- a/Mathlib/FieldTheory/RatFunc/Basic.lean +++ b/Mathlib/FieldTheory/RatFunc/Basic.lean @@ -270,7 +270,7 @@ variable (K) [CommRing K] This is an intermediate step on the way to the full instance `RatFunc.instCommRing`. -/ -@[implicit_reducible] +@[instance_reducible] def instCommMonoid : CommMonoid K⟮X⟯ where mul_assoc := by frac_tac mul_comm := by frac_tac @@ -282,7 +282,7 @@ def instCommMonoid : CommMonoid K⟮X⟯ where This is an intermediate step on the way to the full instance `RatFunc.instCommRing`. -/ -@[implicit_reducible] +@[instance_reducible] def instAddCommGroup : AddCommGroup K⟮X⟯ where add_assoc := by frac_tac add_comm := by frac_tac @@ -361,6 +361,7 @@ theorem map_injective [MonoidHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S Localization.mk_eq_mk_iff, Localization.r_iff_exists, mul_cancel_left_coe_nonZeroDivisors, exists_const, ← map_mul, hf.eq_iff] using h +set_option backward.isDefEq.respectTransparency.types false in /-- Lift a ring homomorphism that maps polynomials `φ : R[X] →+* S[X]` to a `R⟮X⟯ →+* S⟮X⟯`, on the condition that `φ` maps non-zero-divisors to non-zero-divisors, @@ -430,6 +431,7 @@ theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) · rwa [← map_mul, ← map_mul, hφ.eq_iff, mul_comm, mul_comm a'.fst] at this all_goals exact map_ne_zero_of_mem_nonZeroDivisors _ hφ (SetLike.coe_mem _) +set_option backward.isDefEq.respectTransparency.types false in /-- Lift an injective ring homomorphism `R[X] →+* L` to a `R⟮X⟯ →+* L` by mapping both the numerator and denominator and quotienting them. -/ def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : R⟮X⟯ →+* L := @@ -454,10 +456,12 @@ def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : R⟮X⟯ try simp only [← map_mul, ← Submonoid.coe_mul] exact nonZeroDivisors.ne_zero (hφ (SetLike.coe_mem _)) } +set_option backward.isDefEq.respectTransparency.types false in theorem liftRingHom_apply_ofFractionRing_mk (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) (n : R[X]) (d : R[X]⁰) : liftRingHom φ hφ (ofFractionRing (Localization.mk n d)) = φ n / φ d := liftMonoidWithZeroHom_apply_ofFractionRing_mk _ hφ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma liftRingHom_ofFractionRing_algebraMap (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) (x : R[X]) : @@ -465,6 +469,7 @@ lemma liftRingHom_ofFractionRing_algebraMap rw [← Localization.mk_one_eq_algebraMap, liftRingHom_apply_ofFractionRing_mk] simp +set_option backward.isDefEq.respectTransparency.types false in theorem liftRingHom_injective [Nontrivial R] (φ : R[X] →+* L) (hφ : Function.Injective φ) (hφ' : R[X]⁰ ≤ L⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) : Function.Injective (liftRingHom φ hφ') := @@ -588,20 +593,24 @@ theorem liftMonoidWithZeroHom_apply_div' {L : Type*} [CommGroupWithZero L] φ p / φ q := by rw [← map_div₀, liftMonoidWithZeroHom_apply_div] +set_option backward.isDefEq.respectTransparency.types false in theorem liftRingHom_apply_div {L : Type*} [Field L] (φ : K[X] →+* L) (hφ : K[X]⁰ ≤ L⁰.comap φ) (p q : K[X]) : liftRingHom φ hφ (algebraMap _ _ p / algebraMap _ _ q) = φ p / φ q := liftMonoidWithZeroHom_apply_div _ hφ _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem liftRingHom_apply_div' {L : Type*} [Field L] (φ : K[X] →+* L) (hφ : K[X]⁰ ≤ L⁰.comap φ) (p q : K[X]) : liftRingHom φ hφ (algebraMap _ _ p) / liftRingHom φ hφ (algebraMap _ _ q) = φ p / φ q := liftMonoidWithZeroHom_apply_div' _ hφ _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma liftRingHom_algebraMap {L : Type*} [Field L] (φ : K[X] →+* L) (hφ : K[X]⁰ ≤ L⁰.comap φ) (x : K[X]) : liftRingHom φ hφ (algebraMap K[X] _ x) = φ x := by simpa using liftRingHom_apply_div' φ hφ x 1 +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma liftRingHom_comp_algebraMap {L : Type*} [Field L] (φ : K[X] →+* L) (hφ : K[X]⁰ ≤ L⁰.comap φ) : (liftRingHom φ hφ).comp (algebraMap K[X] _) = φ := @@ -638,6 +647,7 @@ theorem coe_mapAlgHom_eq_coe_map (φ : K[X] →ₐ[S] R[X]) (hφ : K[X]⁰ ≤ R (mapAlgHom φ hφ : K⟮X⟯ → R⟮X⟯) = map φ hφ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Lift an injective algebra homomorphism `K[X] →ₐ[S] L` to a `K⟮X⟯ →ₐ[S] L` by mapping both the numerator and denominator and quotienting them. -/ def liftAlgHom : K⟮X⟯ →ₐ[S] L := @@ -646,20 +656,24 @@ def liftAlgHom : K⟮X⟯ →ₐ[S] L := simp_rw [RingHom.toFun_eq_coe, AlgHom.toRingHom_eq_coe, algebraMap_apply r, liftRingHom_apply_div, AlgHom.coe_toRingHom, map_one, div_one, AlgHom.commutes] } +set_option backward.isDefEq.respectTransparency.types false in theorem liftAlgHom_apply_ofFractionRing_mk (n : K[X]) (d : K[X]⁰) : liftAlgHom φ hφ (ofFractionRing (Localization.mk n d)) = φ n / φ d := liftMonoidWithZeroHom_apply_ofFractionRing_mk _ hφ _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem liftAlgHom_injective (φ : K[X] →ₐ[S] L) (hφ : Function.Injective φ) (hφ' : K[X]⁰ ≤ L⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) : Function.Injective (liftAlgHom φ hφ') := liftMonoidWithZeroHom_injective _ hφ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem liftAlgHom_apply_div' (p q : K[X]) : liftAlgHom φ hφ (algebraMap _ _ p) / liftAlgHom φ hφ (algebraMap _ _ q) = φ p / φ q := liftMonoidWithZeroHom_apply_div' _ hφ _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem liftAlgHom_apply_div (p q : K[X]) : liftAlgHom φ hφ (algebraMap _ _ p / algebraMap _ _ q) = φ p / φ q := liftMonoidWithZeroHom_apply_div _ hφ _ _ @@ -721,6 +735,7 @@ theorem mk_eq_mk' (f : Polynomial K) {g : Polynomial K} (hg : g ≠ 0) : ⟨g, mem_nonZeroDivisors_iff_ne_zero.2 hg⟩ := by simp only [mk_eq_div, IsFractionRing.mk'_eq_div] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem ofFractionRing_eq : (ofFractionRing : FractionRing K[X] → K⟮X⟯) = IsLocalization.algEquiv K[X]⁰ _ _ := @@ -729,6 +744,7 @@ theorem ofFractionRing_eq : simp only [Localization.mk_eq_mk'_apply, ofFractionRing_mk', IsLocalization.algEquiv_apply, IsLocalization.map_mk', RingHom.id_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toFractionRing_eq : (toFractionRing : K⟮X⟯ → FractionRing K[X]) = IsLocalization.algEquiv K[X]⁰ _ _ := @@ -737,6 +753,7 @@ theorem toFractionRing_eq : simp only [Localization.mk_eq_mk'_apply, ofFractionRing_mk', IsLocalization.algEquiv_apply, IsLocalization.map_mk', RingHom.id_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toFractionRingRingEquiv_symm_eq : (toFractionRingRingEquiv K).symm = (IsLocalization.algEquiv K[X]⁰ _ _).toRingEquiv := by @@ -1107,10 +1124,12 @@ theorem liftMonoidWithZeroHom_apply {L : Type*} [CommGroupWithZero L] (φ : K[X] liftMonoidWithZeroHom φ hφ f = φ f.num / φ f.denom := by rw [← num_div_denom f, liftMonoidWithZeroHom_apply_div, num_div_denom] +set_option backward.isDefEq.respectTransparency.types false in theorem liftRingHom_apply {L : Type*} [Field L] (φ : K[X] →+* L) (hφ : K[X]⁰ ≤ L⁰.comap φ) (f : K⟮X⟯) : liftRingHom φ hφ f = φ f.num / φ f.denom := liftMonoidWithZeroHom_apply _ hφ _ +set_option backward.isDefEq.respectTransparency.types false in theorem liftAlgHom_apply {L S : Type*} [Field L] [CommSemiring S] [Algebra S K[X]] [Algebra S L] (φ : K[X] →ₐ[S] L) (hφ : K[X]⁰ ≤ L⁰.comap φ) (f : K⟮X⟯) : liftAlgHom φ hφ f = φ f.num / φ f.denom := diff --git a/Mathlib/FieldTheory/RatFunc/IntermediateField.lean b/Mathlib/FieldTheory/RatFunc/IntermediateField.lean index e12687c9a206da..982cfe6db4e079 100644 --- a/Mathlib/FieldTheory/RatFunc/IntermediateField.lean +++ b/Mathlib/FieldTheory/RatFunc/IntermediateField.lean @@ -122,6 +122,7 @@ theorem transcendental_of_ne_C (hf : ¬∃ c, f = C c) : Transcendental K f := b rw [Algebra.transcendental_iff_not_isAlgebraic] at tr exact tr <| Algebra.IsAlgebraic.trans _ _ _ (alg := f.isAlgebraic_adjoin_simple_X' hf) +set_option backward.isDefEq.respectTransparency.types false in theorem irreducible_minpolyX' (hf : ¬∃ c, f = C c) : Irreducible (f.minpolyX K[f]) := by let e := Polynomial.algEquivOfTranscendental K f (f.transcendental_of_ne_C hf) let φ : K[X][X] := f.num.map (algebraMap ..) - diff --git a/Mathlib/FieldTheory/RatFunc/Valuation.lean b/Mathlib/FieldTheory/RatFunc/Valuation.lean index 7f9ec8ae069657..ad340c2f547df2 100644 --- a/Mathlib/FieldTheory/RatFunc/Valuation.lean +++ b/Mathlib/FieldTheory/RatFunc/Valuation.lean @@ -114,7 +114,7 @@ instance : Valuation.IsTrivialOn F (inftyValuation F) := ⟨fun _ hx ↦ by simp [inftyValuation.C _ hx]⟩ /-- The valued field `F(t)` with the valuation at infinity. -/ -@[implicit_reducible] +@[instance_reducible] def inftyValued : Valued (RatFunc F) ℤᵐ⁰ := Valued.mk' <| inftyValuation F diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index e1604a2fc0a54d..083cbcdcb9ea5a 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -307,6 +307,7 @@ lemma exists_isTranscendenceBasis_and_isSeparable_of_linearIndepOn_pow_of_essFin end +set_option backward.isDefEq.respectTransparency.types false in variable (k K) in /-- Any finitely generated extension over perfect fields are separably generated. -/ lemma exists_isTranscendenceBasis_and_isSeparable_of_perfectField diff --git a/Mathlib/Geometry/Convex/Cone/Basic.lean b/Mathlib/Geometry/Convex/Cone/Basic.lean index 71b6c33e5bdce0..8bbf9ddc8b1c07 100644 --- a/Mathlib/Geometry/Convex/Cone/Basic.lean +++ b/Mathlib/Geometry/Convex/Cone/Basic.lean @@ -318,7 +318,7 @@ theorem Blunt.salient : C.Blunt → C.Salient := by exact mt Flat.pointed /-- A pointed convex cone defines a preorder. -/ -@[implicit_reducible] +@[instance_reducible] def toPreorder (C : ConvexCone R G) (h₁ : C.Pointed) : Preorder G where le x y := y - x ∈ C le_refl x := by rw [sub_self x]; exact h₁ diff --git a/Mathlib/Geometry/Convex/Cone/Pointed.lean b/Mathlib/Geometry/Convex/Cone/Pointed.lean index f2370255b2ba01..55ff334f44df7b 100644 --- a/Mathlib/Geometry/Convex/Cone/Pointed.lean +++ b/Mathlib/Geometry/Convex/Cone/Pointed.lean @@ -112,9 +112,11 @@ def toConvexCone (C : PointedCone R E) : ConvexCone R E where instance : Coe (PointedCone R E) (ConvexCone R E) where coe := toConvexCone +set_option backward.isDefEq.respectTransparency false in theorem toConvexCone_injective : Injective ((↑) : PointedCone R E → ConvexCone R E) := fun _ _ => by simp [toConvexCone] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem pointed_toConvexCone (C : PointedCone R E) : (C : ConvexCone R E).Pointed := by simp [toConvexCone, ConvexCone.Pointed] @@ -345,6 +347,7 @@ def lineal (C : PointedCone R E) : Submodule R E where @[simp] theorem support_eq (C : PointedCone R E) : C.support = C.lineal.toAddSubgroup := rfl +set_option backward.isDefEq.respectTransparency false in /-- The lineality space of a cone is the largest submodule contained in the cone. -/ theorem gc_ofSubmodule_lineal : GaloisConnection (α := Submodule R E) ofSubmodule lineal := diff --git a/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean b/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean index 3f491a9e6dc94c..9c3a1ae9760af4 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/AffineSpace.lean @@ -129,6 +129,7 @@ theorem iConvexComb_eq_affineCombination (s : StdSimplex R I) (f : I → P) : s.weights.sum fun x r ↦ r • (f x -ᵥ p) by simpa simp [Finsupp.sum_mapDomain_index, add_smul] +set_option backward.isDefEq.respectTransparency.types false in /-- `convexCombPair` in an affine space is the affine line map. -/ theorem convexCombPair_eq_lineMap (s t : R) (hs : 0 ≤ s) (ht : 0 ≤ t) (h : s + t = 1) (x y : P) : diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean index ac758307cd95a3..80016c836aa999 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean @@ -486,6 +486,7 @@ lemma IsAffineMap.map_convexCombPair {f : M → N} (hf : IsAffineMap R f) f (convexCombPair s t hs ht h x y) = convexCombPair s t hs ht h (f x) (f y) := by simp [hf.map_sConvexComb, convexCombPair] +set_option backward.isDefEq.respectTransparency.types false in /-- Flattening with the outer combination specialized to `convexCombPair`. -/ lemma convexCombPair_iConvexComb_iConvexComb {J₁ : Type u₁} {J₂ : Type u₂} (g₁ : StdSimplex R J₁) (g₂ : StdSimplex R J₂) diff --git a/Mathlib/Geometry/Convex/Hull.lean b/Mathlib/Geometry/Convex/Hull.lean index fb0645560f637d..32d740829cc321 100644 --- a/Mathlib/Geometry/Convex/Hull.lean +++ b/Mathlib/Geometry/Convex/Hull.lean @@ -28,6 +28,7 @@ variable (R) in def convexHull : ClosureOperator (Set X) := .ofCompletePred (IsConvexSet R) (fun _ ↦ .sInter) +set_option backward.isDefEq.respectTransparency.types false in lemma subset_convexHull_iff : t ⊆ convexHull R s ↔ ∀ C, s ⊆ C → IsConvexSet R C → t ⊆ C := by simp [convexHull, iInter_subtype, iInter_and] @@ -36,6 +37,7 @@ lemma subset_convexHull_iff : t ⊆ convexHull R s ↔ ∀ C, s ⊆ C → IsConv protected lemma IsConvexSet.convexHull : IsConvexSet R (convexHull R s) := ClosureOperator.isClosed_closure (.ofCompletePred (IsConvexSet R) _) s +set_option backward.isDefEq.respectTransparency.types false in lemma convexHull_eq_iInter : convexHull R s = ⋂ (t : Set X) (_ : s ⊆ t) (_ : IsConvexSet R t), t := by simp [convexHull, iInter_subtype, iInter_and] diff --git a/Mathlib/Geometry/Convex/Set.lean b/Mathlib/Geometry/Convex/Set.lean index c869531e0edac3..73603706e4de19 100644 --- a/Mathlib/Geometry/Convex/Set.lean +++ b/Mathlib/Geometry/Convex/Set.lean @@ -181,6 +181,7 @@ section Field variable [Field K] [LinearOrder K] [IsStrictOrderedRing K] [ConvexSpace K X] {w : StdSimplex K X} {s t : Set X} {x y : X} +set_option backward.isDefEq.respectTransparency.types false in /-- Convexity of a set can be checked via binary combinations if the scalars form a field. -/ lemma IsConvexSet.of_convexCombPair_mem (hs : ∀ a b : K, ∀ ha hb hab, ∀ x ∈ s, ∀ y ∈ s, convexCombPair a b ha hb hab x y ∈ s) : diff --git a/Mathlib/Geometry/Diffeology/Basic.lean b/Mathlib/Geometry/Diffeology/Basic.lean index 8262d574912185..782b94d1601eed 100644 --- a/Mathlib/Geometry/Diffeology/Basic.lean +++ b/Mathlib/Geometry/Diffeology/Basic.lean @@ -266,7 +266,7 @@ namespace DiffeologicalSpace /-- Replaces the D-topology of a diffeology with another topology equal to it. Useful to construct diffeologies with better definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def replaceDTopology {X : Type*} (d : DiffeologicalSpace X) (t : TopologicalSpace X) (h : @dTopology _ d = t) : DiffeologicalSpace X where dTopology := t @@ -313,7 +313,7 @@ structure CorePlotsOn (X : Type*) where organised in the form of the auxiliary `CorePlotsOn` structure. This is more involved in most regards, but also often makes it quite a lot easier to prove the locality condition. -/ -@[implicit_reducible] +@[instance_reducible] def ofCorePlotsOn {X : Type*} (d : DiffeologicalSpace.CorePlotsOn X) : DiffeologicalSpace X where plots _ := {p | d.isPlot p} @@ -478,7 +478,7 @@ lemma injective_toPlots : Function.Injective (@toPlots X) := fun d d' h ↦ by ext n p; exact Set.ext_iff.1 h ⟨n, p⟩ /-- The diffeology generated by a set `g` of plots. -/ -@[implicit_reducible] +@[instance_reducible] def generateFrom (g : Set ((n : ℕ) × (𝔼ⁿ → X))) : DiffeologicalSpace X where plots n := {p | ∀ (d : DiffeologicalSpace X), g ⊆ d.toPlots → ⟨n, p⟩ ∈ d.toPlots} constant_plots {n} x := fun _ _ ↦ constant_plots x @@ -517,7 +517,7 @@ lemma generateFrom_le_iff {g : Set ((n : ℕ) × (𝔼ⁿ → X))} {d : Diffeolo /-- The diffeology defined by `g`. Same as `generateFrom g`, except that its set of plots is definitionally equal to `g`. -/ -@[implicit_reducible] +@[instance_reducible] protected def mkOfClosure (g : Set ((n : ℕ) × (𝔼ⁿ → X))) (hg : (generateFrom g).toPlots = g) : DiffeologicalSpace X where plots n := {p | ⟨n, p⟩ ∈ g} diff --git a/Mathlib/Geometry/Euclidean/Altitude.lean b/Mathlib/Geometry/Euclidean/Altitude.lean index 25cda183f866e8..6ea4d236ab8b34 100644 --- a/Mathlib/Geometry/Euclidean/Altitude.lean +++ b/Mathlib/Geometry/Euclidean/Altitude.lean @@ -57,6 +57,7 @@ theorem altitude_def {n : ℕ} (s : Simplex ℝ P n) (i : Fin (n + 1)) : affineSpan ℝ (Set.range s.points) := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma altitude_reindex {m n : ℕ} (s : Simplex ℝ P n) (e : Fin (n + 1) ≃ Fin (m + 1)) : (s.reindex e).altitude = s.altitude ∘ e.symm := by ext i diff --git a/Mathlib/Geometry/Euclidean/Incenter.lean b/Mathlib/Geometry/Euclidean/Incenter.lean index 4a8fbcee5d77f2..738d21fb1d5771 100644 --- a/Mathlib/Geometry/Euclidean/Incenter.lean +++ b/Mathlib/Geometry/Euclidean/Incenter.lean @@ -1034,6 +1034,7 @@ lemma touchpoint_empty_notMem_affineSpan_of_ne {i j : Fin (n + 1)} (hne : i ≠ s.touchpoint ∅ i ∉ affineSpan ℝ (Set.range (s.faceOpposite j).points) := s.excenterExists_empty.touchpoint_notMem_affineSpan_of_ne hne +set_option backward.isDefEq.respectTransparency false in variable {s} in lemma ExcenterExists.sign_signedInfDist_lineMap_excenter_touchpoint {signs : Finset (Fin (n + 1))} (h : s.ExcenterExists signs) {i j : Fin (n + 1)} (hne : i ≠ j) {r : ℝ} (hr : r ∈ Set.Icc 0 1) : @@ -1068,6 +1069,7 @@ lemma ExcenterExists.sign_signedInfDist_lineMap_excenter_touchpoint {signs : Fin convert! Set.mem_image_of_mem _ (Set.left_mem_Icc.2 (zero_le_one' ℝ)) simp +set_option backward.isDefEq.respectTransparency false in lemma sign_signedInfDist_lineMap_incenter_touchpoint {i j : Fin (n + 1)} (hne : i ≠ j) {r : ℝ} (hr : r ∈ Set.Icc 0 1) : SignType.sign diff --git a/Mathlib/Geometry/Euclidean/Inversion/Basic.lean b/Mathlib/Geometry/Euclidean/Inversion/Basic.lean index 257a3c57a22969..08b9868f5dffbc 100644 --- a/Mathlib/Geometry/Euclidean/Inversion/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Inversion/Basic.lean @@ -56,6 +56,7 @@ sphere `Metric.sphere c R`. We also prove that the distance to the center of the this inversion is given by `R ^ 2 / dist x c`. -/ +set_option backward.isDefEq.respectTransparency false in theorem inversion_eq_lineMap (c : P) (R : ℝ) (x : P) : inversion c R x = lineMap c x ((R / dist x c) ^ 2) := rfl diff --git a/Mathlib/Geometry/Euclidean/MongePoint.lean b/Mathlib/Geometry/Euclidean/MongePoint.lean index fdda4bdaf6ad67..e8d11808e27dba 100644 --- a/Mathlib/Geometry/Euclidean/MongePoint.lean +++ b/Mathlib/Geometry/Euclidean/MongePoint.lean @@ -93,6 +93,7 @@ theorem mongePoint_eq_smul_vsub_vadd_circumcenter {n : ℕ} (s : Simplex ℝ P n congr 3 convert! Finset.univ.affineCombination_map e.toEmbedding _ _ <;> simp [Function.comp_assoc] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mongePoint_map {V₂ P₂ : Type*} [NormedAddCommGroup V₂] [InnerProductSpace ℝ V₂] [MetricSpace P₂] [NormedAddTorsor V₂ P₂] diff --git a/Mathlib/Geometry/Euclidean/PerpBisector.lean b/Mathlib/Geometry/Euclidean/PerpBisector.lean index edf5f73730f982..1f144b0b6b1bae 100644 --- a/Mathlib/Geometry/Euclidean/PerpBisector.lean +++ b/Mathlib/Geometry/Euclidean/PerpBisector.lean @@ -165,6 +165,7 @@ theorem dist_lt_of_sbtw_of_mem_perpBisector {a b c p : P} rw [right_vsub_midpoint, inner_smul_right, mem_perpBisector_iff_inner_eq_zero.mp hp, invOf_eq_inv, mul_zero] +set_option backward.isDefEq.respectTransparency false in /-- If `p` lies on the perpendicular bisector of `ab` and `b` is weakly between `a` and `c`, then `p` is at least as close to `b` as to `c`. -/ theorem dist_le_of_wbtw_of_mem_perpBisector {a b c p : P} diff --git a/Mathlib/Geometry/Euclidean/SignedDist.lean b/Mathlib/Geometry/Euclidean/SignedDist.lean index 37621c1f735dee..b29055e7d8916c 100644 --- a/Mathlib/Geometry/Euclidean/SignedDist.lean +++ b/Mathlib/Geometry/Euclidean/SignedDist.lean @@ -205,6 +205,7 @@ lemma signedDist_eq_dist_iff_vsub_mem_span : signedDist v p q = dist p q ↔ q - rw [← neg_eq_iff_eq_neg, ← signedDist_neg, neg_vsub_eq_vsub_rev] apply signedDist_vsub_self +set_option backward.isDefEq.respectTransparency false in lemma signedDist_lineMap_lineMap (c₁ c₂ : ℝ) : signedDist v (AffineMap.lineMap p q c₁) (AffineMap.lineMap p q c₂) = (c₂ - c₁) * signedDist v p q := by @@ -212,18 +213,22 @@ lemma signedDist_lineMap_lineMap (c₁ c₂ : ℝ) : · simp [AffineMap.lineMap_apply_ring'] · rw [sub_mul, ← signedDist_anticomm v p, mul_neg, sub_eq_add_neg] +set_option backward.isDefEq.respectTransparency false in lemma signedDist_lineMap_left (c : ℝ) : signedDist v (AffineMap.lineMap p q c) p = -c * signedDist v p q := by simpa using signedDist_lineMap_lineMap v p q c 0 +set_option backward.isDefEq.respectTransparency false in lemma signedDist_left_lineMap (c : ℝ) : signedDist v p (AffineMap.lineMap p q c) = c * signedDist v p q := by simpa using signedDist_lineMap_lineMap v p q 0 c +set_option backward.isDefEq.respectTransparency false in lemma signedDist_lineMap_right (c : ℝ) : signedDist v (AffineMap.lineMap p q c) q = (1 - c) * signedDist v p q := by simpa using signedDist_lineMap_lineMap v p q c 1 +set_option backward.isDefEq.respectTransparency false in lemma signedDist_right_lineMap (c : ℝ) : signedDist v q (AffineMap.lineMap p q c) = (c - 1) * signedDist v p q := by simpa using signedDist_lineMap_lineMap v p q 1 c @@ -299,6 +304,7 @@ trilinear coordinates; in a tetrahedron, they are quadriplanar coordinates. -/ noncomputable def signedInfDist : P →ᴬ[ℝ] ℝ := AffineSubspace.signedInfDist (affineSpan ℝ (s.points '' {i}ᶜ)) (s.points i) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma signedInfDist_reindex {m : ℕ} [NeZero m] (e : Fin (n + 1) ≃ Fin (m + 1)) (j : Fin (m + 1)) : (s.reindex e).signedInfDist j = s.signedInfDist (e.symm j) := by simp_rw [signedInfDist, reindex_points, Set.image_comp, Set.image_compl_eq e.symm.bijective, diff --git a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean index 14bf842b552b13..a817ccaf313279 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean @@ -455,6 +455,7 @@ theorem Sphere.inner_vsub_center_midpoint_vsub {p₁ p₂ : P} {s : Sphere P} (dist_left_midpoint_eq_dist_right_midpoint p₁ p₂) (dist_center_eq_dist_center_of_mem_sphere hp₁ hp₂) +set_option backward.isDefEq.respectTransparency false in /-- The distance from the center of a sphere to any point strictly between two points on the sphere is strictly less than the radius. -/ theorem Sphere.dist_center_lt_radius_of_sbtw {p₁ p₂ p : P} {s : Sphere P} diff --git a/Mathlib/Geometry/Euclidean/Sphere/SecondInter.lean b/Mathlib/Geometry/Euclidean/Sphere/SecondInter.lean index 8b4dbdca401b76..f9a599cc8a6ef8 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/SecondInter.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/SecondInter.lean @@ -43,6 +43,7 @@ the second intersection with the sphere through `p` and with center `s.center`. def Sphere.secondInter (s : Sphere P) (p : P) (v : V) : P := (-2 * ⟪v, p -ᵥ s.center⟫ / ⟪v, v⟫) • v +ᵥ p +set_option backward.isDefEq.respectTransparency false in @[simp] lemma Sphere.secondInter_map (s : Sphere P) (p : P) (v : V) (f : P →ᵃⁱ[ℝ] P₂) : Sphere.secondInter ⟨f s.center, s.radius⟩ (f p) (f.linearIsometry v) = f (s.secondInter p v) := by @@ -144,6 +145,7 @@ theorem Sphere.secondInter_secondInter (s : Sphere P) (p : P) (v : V) : convert! zero_div (G₀ := ℝ) _ ring +set_option backward.isDefEq.respectTransparency false in /-- If the vector passed to `secondInter` is given by a subtraction involving the point in `secondInter`, the result of `secondInter` may be expressed using `lineMap`. -/ theorem Sphere.secondInter_eq_lineMap (s : Sphere P) (p p' : P) : @@ -212,6 +214,7 @@ lemma Sphere.sOppSide_faceOpposite_secondInter_of_mem_interior_faceOpposite {s : attribute [local instance] Nat.AtLeastTwo.neZero_sub_one +set_option backward.isDefEq.respectTransparency false in /-- If the point passed to `secondInter` is a vertex of a simplex, lying on the sphere, and all vertices lie on or inside the sphere, and the vector passed to `secondInter` is given by a subtraction involving that vertex and a point in the interior of the simplex, the given vertex diff --git a/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean b/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean index 44141b8669e0c3..3b20ce9f999210 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean @@ -427,6 +427,7 @@ lemma IsIntTangent.dist_center {s₁ s₂ : Sphere P} (h : s₁.IsIntTangent s rw [← dist_add_dist_eq_iff, mem_sphere'.1 h₁, mem_sphere'.1 h₂] at h simp [← h, dist_comm] +set_option backward.isDefEq.respectTransparency false in lemma isExtTangent_iff_dist_center {s₁ s₂ : Sphere P} : s₁.IsExtTangent s₂ ↔ dist s₁.center s₂.center = s₁.radius + s₂.radius ∧ 0 ≤ s₁.radius ∧ 0 ≤ s₂.radius := by refine ⟨fun h ↦ ⟨h.dist_center, ?_⟩, ?_⟩ @@ -451,6 +452,7 @@ lemma isExtTangent_iff_dist_center {s₁ s₂ : Sphere P} : s₁.IsExtTangent s · rw [div_le_one (by positivity)] linarith +set_option backward.isDefEq.respectTransparency false in lemma isIntTangent_iff_dist_center [Nontrivial V] {s₁ s₂ : Sphere P} : s₁.IsIntTangent s₂ ↔ dist s₁.center s₂.center = s₂.radius - s₁.radius ∧ 0 ≤ s₁.radius ∧ 0 ≤ s₂.radius := by refine ⟨fun h ↦ ⟨h.dist_center, ?_⟩, ?_⟩ diff --git a/Mathlib/Geometry/Manifold/Algebra/LeftInvariantDerivation.lean b/Mathlib/Geometry/Manifold/Algebra/LeftInvariantDerivation.lean index 97ef839a3bc66e..b4b354c630b8bd 100644 --- a/Mathlib/Geometry/Manifold/Algebra/LeftInvariantDerivation.lean +++ b/Mathlib/Geometry/Manifold/Algebra/LeftInvariantDerivation.lean @@ -101,6 +101,7 @@ protected theorem map_neg : X (-f) = -X f := by simp protected theorem map_sub : X (f - f') = X f - X f' := by simp +set_option backward.isDefEq.respectTransparency false in protected theorem map_smul : X (r • f) = r • X f := by simp @[simp] @@ -214,6 +215,7 @@ theorem comp_L : (X f).comp (𝑳 I g) = X (f.comp (𝑳 I g)) := by rw [ContMDiffMap.comp_apply, L_apply, ← evalAt_apply, evalAt_mul, hfdifferential_apply, fdifferential_apply, evalAt_apply] +set_option backward.isDefEq.respectTransparency false in instance : Bracket (LeftInvariantDerivation I G) (LeftInvariantDerivation I G) where bracket X Y := ⟨⁅(X : Derivation 𝕜 C^∞⟮I, G; 𝕜⟯ C^∞⟮I, G; 𝕜⟯), Y⁆, fun g => by @@ -252,6 +254,7 @@ instance : LieRing (LeftInvariantDerivation I G) where simp only [commutator_apply, coe_add, map_sub, Pi.add_apply] ring +set_option backward.isDefEq.respectTransparency false in instance : LieAlgebra 𝕜 (LeftInvariantDerivation I G) where lie_smul r Y Z := by ext1 diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 31e0e7f45ed0db..09085d21806afb 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -286,7 +286,7 @@ alias ChartedSpace.locPathConnectedSpace := ChartedSpace.locallyPathConnectedSpa /-- If `M` is modelled on `H'` and `H'` is itself modelled on `H`, then we can consider `M` as being modelled on `H`. -/ -@[implicit_reducible] +@[instance_reducible] def ChartedSpace.comp (H : Type*) [TopologicalSpace H] (H' : Type*) [TopologicalSpace H'] (M : Type*) [TopologicalSpace M] [ChartedSpace H H'] [ChartedSpace H' M] : ChartedSpace H M where @@ -328,7 +328,7 @@ end section Constructions /-- An empty type is a charted space over any topological space. -/ -@[implicit_reducible] +@[instance_reducible] def ChartedSpace.empty (H : Type*) [TopologicalSpace H] (M : Type*) [TopologicalSpace M] [IsEmpty M] : ChartedSpace H M where atlas := ∅ @@ -495,7 +495,7 @@ variable [TopologicalSpace H] [TopologicalSpace M] [TopologicalSpace M'] /-- The disjoint union of two charted spaces modelled on a non-empty space `H` is a charted space over `H`. -/ -@[implicit_reducible] +@[instance_reducible] def ChartedSpace.sum_of_nonempty [Nonempty H] : ChartedSpace H (M ⊕ M') where atlas := ((fun e ↦ e.lift_openEmbedding IsOpenEmbedding.inl) '' cm.atlas) ∪ ((fun e ↦ e.lift_openEmbedding IsOpenEmbedding.inr) '' cm'.atlas) @@ -575,7 +575,7 @@ variable [TopologicalSpace M] [TopologicalSpace M'] [TopologicalSpace H] [Charte /-- Given a right inverse for a local homeomorphism `f : M → M'`, endow `M'` with a `ChartedSpace` structure by pushing forward the `ChartedSpace` structure from `M`. -/ -@[implicit_reducible] +@[instance_reducible] def IsLocalHomeomorph.chartedSpaceOfRightInverse {f : M → M'} (hf : IsLocalHomeomorph f) {g : M' → M} (hg : Function.RightInverse g f) : ChartedSpace H M' where @@ -588,7 +588,7 @@ def IsLocalHomeomorph.chartedSpaceOfRightInverse /-- Given a surjective local homeomorphism `f : M → M'`, endow `M'` with a `ChartedSpace` structure by pushing forward the `ChartedSpace` structure from `M`. -/ -@[implicit_reducible] +@[instance_reducible] def IsLocalHomeomorph.chartedSpace {f : M → M'} (hf : IsLocalHomeomorph f) (hf' : Function.Surjective f) : ChartedSpace H M' := @@ -628,7 +628,7 @@ namespace ChartedSpaceCore variable [TopologicalSpace H] (c : ChartedSpaceCore H M) {e : PartialEquiv M H} /-- Topology generated by a set of charts on a Type. -/ -@[implicit_reducible] +@[instance_reducible] protected def toTopologicalSpace : TopologicalSpace M := TopologicalSpace.generateFrom <| ⋃ (e : PartialEquiv M H) (_ : e ∈ c.atlas) (s : Set H) (_ : IsOpen s), @@ -683,7 +683,7 @@ protected def openPartialHomeomorph (e : PartialEquiv M H) (he : e ∈ c.atlas) /-- Given a charted space without topology, endow it with a genuine charted space structure with respect to the topology constructed from the atlas. -/ -@[implicit_reducible] +@[instance_reducible] def toChartedSpace : @ChartedSpace H _ M c.toTopologicalSpace := { __ := c.toTopologicalSpace atlas := ⋃ (e : PartialEquiv M H) (he : e ∈ c.atlas), {c.openPartialHomeomorph e he} diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean index ae089b85638df8..3c20bef9a11041 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean @@ -45,6 +45,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section Atlas +set_option backward.isDefEq.respectTransparency false in variable (I) in theorem ModelWithCorners.contMDiff : ContMDiff I 𝓘(𝕜, E) n I := by intro x @@ -52,6 +53,7 @@ theorem ModelWithCorners.contMDiff : ContMDiff I 𝓘(𝕜, E) n I := by simpa using contDiffWithinAt_id.congr (fun y hy ↦ by simp [hy]) (by simp) @[deprecated (since := "2026-06-16")] alias contMDiff_model := ModelWithCorners.contMDiff +set_option backward.isDefEq.respectTransparency false in variable (I) in theorem ModelWithCorners.contMDiffOn_symm : ContMDiffOn 𝓘(𝕜, E) I n I.symm (range I) := by intro x hx diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean index 0e744acc5bf41a..d1b3aac7cfe91b 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean @@ -411,6 +411,7 @@ section variable {e : M → H} (h : IsOpenEmbedding e) {n : ℕ∞ω} +set_option backward.isDefEq.respectTransparency false in /-- If the `ChartedSpace` structure on a manifold `M` is given by an open embedding `e : M → H`, then `e` is `C^n`. -/ lemma contMDiff_isOpenEmbedding [Nonempty M] : @@ -436,6 +437,7 @@ lemma contMDiff_isOpenEmbedding [Nonempty M] : h.toOpenPartialHomeomorph_target] at this exact this +set_option backward.isDefEq.respectTransparency false in /-- If the `ChartedSpace` structure on a manifold `M` is given by an open embedding `e : M → H`, then the inverse of `e` is `C^n`. -/ lemma contMDiffOn_isOpenEmbedding_symm [Nonempty M] : diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index 3e578df2a2dcbe..61d28c5d2fbc46 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -314,6 +314,7 @@ theorem continuousWithinAt_iff_source : simp [this] · simp +set_option backward.isDefEq.respectTransparency false in /-- One can reformulate being `Cⁿ` within a set at a point as being `Cⁿ` in the source space when composing with the extended chart. -/ theorem contMDiffWithinAt_iff_source : @@ -393,6 +394,7 @@ theorem contMDiffWithinAt_iff_of_mem_maximalAtlas (he : e ∈ maximalAtlas I n M ((e.extend I).symm ⁻¹' s ∩ range I) (e.extend I x) := (contDiffWithinAt_localInvariantProp n).liftPropWithinAt_indep_chart he hx he' hy +set_option backward.isDefEq.respectTransparency.types false in /-- An alternative version of `contMDiffWithinAt_iff_of_mem_maximalAtlas` which takes a chart `e'` in the target in the maximal atlas, but uses the preferred chart on the domain. -/ theorem contMDiffWithinAt_iff_of_mem_maximalAtlas' diff --git a/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean b/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean index b2e65680f331a9..fbd11cd84596ac 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean @@ -42,6 +42,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section Module +set_option backward.isDefEq.respectTransparency false in theorem contMDiffWithinAt_iff_contDiffWithinAt {f : E → E'} {s : Set E} {x : E} : ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E') n f s x ↔ ContDiffWithinAt 𝕜 n f s x := by simp +contextual only [ContMDiffWithinAt, liftPropWithinAt_iff', diff --git a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean index 0a011da1035f3d..3ba1ad6ba5b184 100644 --- a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean +++ b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean @@ -142,6 +142,7 @@ lemma mulInvariantVectorField_eq_mpullback (g : G) (V : Π (g : G), TangentSpace simp set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem contMDiff_mulInvariantVectorField (v : GroupLieAlgebra I G) : CMDiff (minSmoothness 𝕜 2) diff --git a/Mathlib/Geometry/Manifold/HasGroupoid.lean b/Mathlib/Geometry/Manifold/HasGroupoid.lean index 49ae315a773ce8..c29f626e9d4923 100644 --- a/Mathlib/Geometry/Manifold/HasGroupoid.lean +++ b/Mathlib/Geometry/Manifold/HasGroupoid.lean @@ -211,7 +211,7 @@ variable (e : OpenPartialHomeomorph α H) whole space `α`, then that open partial homeomorphism induces an `H`-charted space structure on `α`. (This condition is equivalent to `e` being an open embedding of `α` into `H`; see `IsOpenEmbedding.singletonChartedSpace`.) -/ -@[implicit_reducible] +@[instance_reducible] def singletonChartedSpace (h : e.source = Set.univ) : ChartedSpace H α where atlas := {e} chartAt _ := e @@ -253,7 +253,7 @@ variable [Nonempty α] /-- An open embedding of `α` into `H` induces an `H`-charted space structure on `α`. See `OpenPartialHomeomorph.singletonChartedSpace`. -/ -@[implicit_reducible] +@[instance_reducible] def singletonChartedSpace {f : α → H} (h : IsOpenEmbedding f) : ChartedSpace H α := (h.toOpenPartialHomeomorph f).singletonChartedSpace (toOpenPartialHomeomorph_source _ _) diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index 1b80bee02fe21e..b10829aeea42e2 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -638,6 +638,7 @@ lemma congr_iff (hfg : f =ᶠ[𝓝 x] g) : IsImmersionAt I J n f x ↔ IsImmersionAt I J n g x := ⟨fun h ↦ h.congr_of_eventuallyEq hfg, fun h ↦ h.congr_of_eventuallyEq hfg.symm⟩ +set_option backward.isDefEq.respectTransparency false in /- The set of points where `IsImmersionAt` holds is open. -/ lemma _root_.IsOpen.isImmersionAt : IsOpen {x | IsImmersionAt I J n f x} := by diff --git a/Mathlib/Geometry/Manifold/Instances/Icc.lean b/Mathlib/Geometry/Manifold/Instances/Icc.lean index 1db01c146b7d21..3dbdb7fe34c83e 100644 --- a/Mathlib/Geometry/Manifold/Instances/Icc.lean +++ b/Mathlib/Geometry/Manifold/Instances/Icc.lean @@ -107,6 +107,7 @@ lemma contMDiff_subtype_coe_Icc : CMDiff n (fun (z : Icc x y) ↦ (z : ℝ)) := rw [max_eq_left hw, max_eq_left] linarith +set_option backward.isDefEq.respectTransparency false in /-- The projection from `ℝ` to a closed segment is smooth on the segment, in the manifold sense. -/ lemma contMDiffOn_projIcc : CMDiff[Icc x y] n (Set.projIcc x y h.out.le) := by intro z hz diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 0ac71a8e87b7f7..051923a0bb6177 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -309,6 +309,7 @@ end Fact.Manifold open Fact.Manifold +set_option backward.isDefEq.respectTransparency false in lemma IccLeftChart_extend_bot : (IccLeftChart x y).extend (𝓡∂ 1) ⊥ = 0 := by norm_num [IccLeftChart, modelWithCornersEuclideanHalfSpace_zero] congr @@ -366,6 +367,7 @@ def IccRightChart (x y : ℝ) [h : Fact (x < y)] : continuousOn_toFun := by fun_prop continuousOn_invFun := by fun_prop +set_option backward.isDefEq.respectTransparency false in lemma IccRightChart_extend_top : (IccRightChart x y).extend (𝓡∂ 1) ⊤ = 0 := by norm_num [IccRightChart, modelWithCornersEuclideanHalfSpace_zero] @@ -443,6 +445,7 @@ lemma boundary_product [I.Boundaryless] : (I.prod (𝓡∂ 1)).boundary (M × Icc x y) = Set.prod univ {⊥, ⊤} := by rw [I.boundary_of_boundaryless_left, boundary_Icc] +set_option backward.isDefEq.respectTransparency false in /-- The manifold structure on `[x, y]` is smooth. -/ instance instIsManifoldIcc (x y : ℝ) [Fact (x < y)] {n : ℕ∞ω} : IsManifold (𝓡∂ 1) n (Icc x y) := by diff --git a/Mathlib/Geometry/Manifold/Instances/Sphere.lean b/Mathlib/Geometry/Manifold/Instances/Sphere.lean index bd2d69431eba6d..451f9cc567e4f3 100644 --- a/Mathlib/Geometry/Manifold/Instances/Sphere.lean +++ b/Mathlib/Geometry/Manifold/Instances/Sphere.lean @@ -232,6 +232,7 @@ theorem stereo_left_inv (hv : ‖v‖ = 1) {x : sphere (0 : E) 1} (hx : (x : E) · field_simp linear_combination 4 * (a - 1) * pythag +set_option backward.isDefEq.respectTransparency false in theorem stereo_right_inv (hv : ‖v‖ = 1) (w : (ℝ ∙ v)ᗮ) : stereoToFun v (stereoInvFun hv w) = w := by simp only [stereoToFun, stereoInvFun, stereoInvFunAux, smul_add, map_add, map_smul, innerSL_apply_apply, Submodule.orthogonalProjectionOnto_mem_subspace_eq_self] @@ -340,10 +341,12 @@ def stereographic' (n : ℕ) [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) (OrthonormalBasis.fromOrthogonalSpanSingleton n (ne_zero_of_mem_unit_sphere v)).repr.toHomeomorph.toOpenPartialHomeomorph +set_option backward.isDefEq.respectTransparency false in @[simp] theorem stereographic'_source {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : (stereographic' n v).source = {v}ᶜ := by simp [stereographic'] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem stereographic'_target {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : (stereographic' n v).target = Set.univ := by simp [stereographic'] diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 50a22f39400c7e..1edf199297ec0d 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -609,6 +609,7 @@ instance modelWithCornersSelf_boundaryless (𝕜 : Type*) [NontriviallyNormedFie [NormedAddCommGroup E] [NormedSpace 𝕜 E] : (modelWithCornersSelf 𝕜 E).Boundaryless := ⟨by simp⟩ +set_option backward.isDefEq.respectTransparency false in /-- If two model with corners are boundaryless, their product also is -/ instance ModelWithCorners.range_eq_univ_prod {𝕜 : Type u} [NontriviallyNormedField 𝕜] {E : Type v} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type w} [TopologicalSpace H] @@ -739,6 +740,7 @@ theorem symm_trans_mem_contDiffGroupoid (e : OpenPartialHomeomorph M H) : variable {E' H' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] [TopologicalSpace H'] +set_option backward.isDefEq.respectTransparency false in /-- The product of two `C^n` open partial homeomorphisms is `C^n`. -/ theorem contDiffGroupoid_prod {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'} {e : OpenPartialHomeomorph H H} {e' : OpenPartialHomeomorph H' H'} diff --git a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean index 35af7c80c9d15e..01b4fd14994758 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean @@ -801,17 +801,21 @@ The manifold derivative of `f` will just be the derivative of this conjugated fu def writtenInExtChartAt (x : M) (f : M → M') : E → E' := extChartAt I' (f x) ∘ f ∘ (extChartAt I x).symm +set_option backward.isDefEq.respectTransparency false in theorem writtenInExtChartAt_chartAt {x : M} {y : E} (h : y ∈ (extChartAt I x).target) : writtenInExtChartAt I I x (chartAt H x) y = y := by simp_all only [mfld_simps] +set_option backward.isDefEq.respectTransparency false in theorem writtenInExtChartAt_chartAt_symm {x : M} {y : E} (h : y ∈ (extChartAt I x).target) : writtenInExtChartAt I I (chartAt H x x) (chartAt H x).symm y = y := by simp_all only [mfld_simps] +set_option backward.isDefEq.respectTransparency false in theorem writtenInExtChartAt_extChartAt {x : M} {y : E} (h : y ∈ (extChartAt I x).target) : writtenInExtChartAt I 𝓘(𝕜, E) x (extChartAt I x) y = y := by simp_all only [mfld_simps] +set_option backward.isDefEq.respectTransparency false in theorem writtenInExtChartAt_extChartAt_symm {x : M} {y : E} (h : y ∈ (extChartAt I x).target) : writtenInExtChartAt 𝓘(𝕜, E) I (extChartAt I x x) (extChartAt I x).symm y = y := by simp_all only [mfld_simps] @@ -850,6 +854,7 @@ theorem extChartAt_self_eq {x : H} : ⇑(extChartAt I x) = I := theorem extChartAt_self_apply {x y : H} : extChartAt I x y = I y := rfl +set_option backward.isDefEq.respectTransparency false in /-- In the case of the manifold structure on a vector space, the extended charts are just the identity. -/ theorem extChartAt_model_space_eq_id (x : E) : extChartAt 𝓘(𝕜, E) x = PartialEquiv.refl E := by diff --git a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean index 08e68119c83dde..41b394ff59a95d 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean @@ -362,7 +362,7 @@ lemma MDifferentiableAt.isInteriorPoint_of_surjective_mfderiv {f : M → N} {x : let _ : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 E let _ : NormedSpace ℝ E' := NormedSpace.restrictScalars ℝ 𝕜 E' -- Write everything in terms of extended charts around `x` and `f x`. - simp only [mfderiv, hf, ite_true] at hf' + simp only [mfderiv, hf] at hf' have hf'' := hf.differentiableWithinAt_writtenInExtChartAt.differentiableAt <| by simpa [← mem_interior_iff_mem_nhds] using! hx rw [fderivWithin_eq_fderiv (I.uniqueDiffOn _ <| by simp) hf''] at hf' diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index 2b06e0a39ea983..b35e51a090b995 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -285,6 +285,7 @@ lemma mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm {x : M} simp only [Function.comp_def, PartialEquiv.right_inv (extChartAt I x) hz, id_eq] · simp only [Function.comp_def, PartialEquiv.right_inv (extChartAt I x) hy, id_eq] +set_option backward.isDefEq.respectTransparency false in /-- The composition of the derivative of `extChartAt` with the derivative of the inverse of `extChartAt` gives the identity. Version where the basepoint belongs to `(extChartAt I x).source`. -/ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index 04fc8658e10cff..a18a93a99f928b 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -539,10 +539,12 @@ theorem mfderivWithin_univ : mfderivWithin I I' f univ = mfderiv I I' f := by simp only [mfderivWithin, mfderiv, mfld_simps] rw [mdifferentiableWithinAt_univ] +set_option backward.isDefEq.respectTransparency false in theorem mfderivWithin_zero_of_not_mdifferentiableWithinAt (h : ¬MDifferentiableWithinAt I I' f s x) : mfderivWithin I I' f s x = 0 := by simp only [mfderivWithin, h, if_neg, not_false_iff] +set_option backward.isDefEq.respectTransparency false in theorem mfderiv_zero_of_not_mdifferentiableAt (h : ¬MDifferentiableAt I I' f x) : mfderiv I I' f x = 0 := by simp only [mfderiv, h, if_neg, not_false_iff] @@ -612,12 +614,14 @@ theorem hasMFDerivAt_unique (h₀ : HasMFDerivAt I I' f x f₀') (h₁ : HasMFDe rw [← hasMFDerivWithinAt_univ] at h₀ h₁ exact (uniqueMDiffWithinAt_univ I).eq h₀ h₁ +set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivWithinAt_inter' (h : t ∈ 𝓝[s] x) : HasMFDerivWithinAt I I' f (s ∩ t) x f' ↔ HasMFDerivWithinAt I I' f s x f' := by rw [HasMFDerivWithinAt, HasMFDerivWithinAt, extChartAt_preimage_inter_eq, hasFDerivWithinAt_inter', continuousWithinAt_inter' h] exact extChartAt_preimage_mem_nhdsWithin h +set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivWithinAt_inter (h : t ∈ 𝓝 x) : HasMFDerivWithinAt I I' f (s ∩ t) x f' ↔ HasMFDerivWithinAt I I' f s x f' := by rw [HasMFDerivWithinAt, HasMFDerivWithinAt, extChartAt_preimage_inter_eq, hasFDerivWithinAt_inter, @@ -643,7 +647,7 @@ theorem HasMFDerivWithinAt.hasMFDerivAt (h : HasMFDerivWithinAt I I' f s x f') ( theorem MDifferentiableWithinAt.hasMFDerivWithinAt (h : MDifferentiableWithinAt I I' f s x) : HasMFDerivWithinAt I I' f s x (mfderivWithin I I' f s x) := by refine ⟨h.1, ?_⟩ - simp only [mfderivWithin, h, if_pos, mfld_simps] + simp only [mfderivWithin, h, mfld_simps] exact DifferentiableWithinAt.hasFDerivWithinAt h.2 theorem mdifferentiableWithinAt_iff_exists_hasMFDerivWithinAt : @@ -665,6 +669,7 @@ theorem mdifferentiableWithinAt_congr_nhds {t : Set M} (hst : 𝓝[s] x = 𝓝[t MDifferentiableWithinAt I I' f s x ↔ MDifferentiableWithinAt I I' f t x := ⟨fun h => h.congr_nhds hst, fun h => h.congr_nhds hst.symm⟩ +set_option backward.isDefEq.respectTransparency false in protected theorem MDifferentiableWithinAt.mfderivWithin (h : MDifferentiableWithinAt I I' f s x) : mfderivWithin I I' f s x = fderivWithin 𝕜 (writtenInExtChartAt I I' x f :) ((extChartAt I x).symm ⁻¹' s ∩ range I) @@ -674,9 +679,10 @@ protected theorem MDifferentiableWithinAt.mfderivWithin (h : MDifferentiableWith theorem MDifferentiableAt.hasMFDerivAt (h : MDifferentiableAt I I' f x) : HasMFDerivAt I I' f x (mfderiv I I' f x) := by refine ⟨h.continuousAt, ?_⟩ - simp only [mfderiv, h, if_pos, mfld_simps] + simp only [mfderiv, h, mfld_simps] exact DifferentiableWithinAt.hasFDerivWithinAt h.differentiableWithinAt_writtenInExtChartAt +set_option backward.isDefEq.respectTransparency false in protected theorem MDifferentiableAt.mfderiv (h : MDifferentiableAt I I' f x) : mfderiv I I' f x = fderivWithin 𝕜 (writtenInExtChartAt I I' x f :) (range I) ((extChartAt I x) x) := by @@ -978,6 +984,7 @@ theorem HasMFDerivWithinAt.congr_mono (h : HasMFDerivWithinAt I I' f s x f') (ht : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (h₁ : t ⊆ s) : HasMFDerivWithinAt I I' f₁ t x f' := (h.mono h₁).congr_of_eventuallyEq (Filter.mem_inf_of_right ht) hx +set_option backward.isDefEq.respectTransparency false in theorem HasMFDerivAt.congr_of_eventuallyEq (h : HasMFDerivAt I I' f x f') (h₁ : f₁ =ᶠ[𝓝 x] f) : HasMFDerivAt I I' f₁ x f' := by rw [← hasMFDerivWithinAt_univ] at h ⊢ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean index f0d5d10514ba8c..2531fe54145cce 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean @@ -28,6 +28,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCom section MFDerivFDeriv +set_option backward.isDefEq.respectTransparency false in theorem uniqueMDiffWithinAt_iff_uniqueDiffWithinAt : UniqueMDiffAt[s] x ↔ UniqueDiffWithinAt 𝕜 s x := by simp only [UniqueMDiffWithinAt, mfld_simps] @@ -59,6 +60,7 @@ theorem hasMFDerivWithinAt_iff_hasFDerivWithinAt : alias ⟨HasMFDerivWithinAt.hasFDerivWithinAt, HasFDerivWithinAt.hasMFDerivWithinAt⟩ := hasMFDerivWithinAt_iff_hasFDerivWithinAt +set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivAt_iff_hasFDerivAt : HasMFDerivAt% f x f' ↔ HasFDerivAt f f' x := by rw [← hasMFDerivWithinAt_univ, hasMFDerivWithinAt_iff_hasFDerivWithinAt, hasFDerivWithinAt_univ] @@ -100,6 +102,7 @@ theorem mdifferentiable_iff_differentiable : MDiff f ↔ Differentiable 𝕜 f : alias ⟨MDifferentiable.differentiable, Differentiable.mdifferentiable⟩ := mdifferentiable_iff_differentiable +set_option backward.isDefEq.respectTransparency false in /-- For maps between vector spaces, `mfderivWithin` and `fderivWithin` coincide -/ @[simp] theorem mfderivWithin_eq_fderivWithin : diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index bbf7333557df2e..1112728ab1ba4a 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -105,6 +105,7 @@ section extChartAt variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {f : M → F} +set_option backward.isDefEq.respectTransparency.types false in -- TODO: add pre-composition version also theorem MDifferentiableWithinAt.differentiableWithinAt_comp_extChartAt_symm (hf : MDiffAt[s] f x) : letI φ := extChartAt I x diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index ed0716ef31beb2..a3ba6c2a79321c 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -558,7 +558,7 @@ theorem mfderiv_prod_left {x₀ : M} {y₀ : M'} : -- TODO: better error when the type of x is left open theorem tangentMap_prod_left {p : TangentBundle I M} {y₀ : M'} : tangentMap% (fun (x : M) ↦ (x, y₀)) p = ⟨(p.1, y₀), (p.2, 0)⟩ := by - simp only [tangentMap, mfderiv_prod_left, TotalSpace.mk_inj] + simp only [tangentMap, mfderiv_prod_left] rfl set_option backward.isDefEq.respectTransparency false in @@ -570,7 +570,7 @@ theorem mfderiv_prod_right {x₀ : M} {y₀ : M'} : theorem tangentMap_prod_right {p : TangentBundle I' M'} {x₀ : M} : tangentMap% (fun (y : M') ↦ (x₀, y)) p = ⟨(x₀, p.1), (0, p.2)⟩ := by - simp only [tangentMap, mfderiv_prod_right, TotalSpace.mk_inj] + simp only [tangentMap, mfderiv_prod_right] rfl /-- The total derivative of a function in two variables is the sum of the partial derivatives. @@ -604,13 +604,13 @@ theorem mfderiv_prod_eq_add_comp {f : M × M' → M''} {p : M × M'} (hf : MDiff congr · have : (fun z : M × M' ↦ f (z.1, p.2)) = (fun z : M ↦ f (z, p.2)) ∘ Prod.fst := rfl rw [this, mfderiv_comp (I' := I)] - · simp only [mfderiv_fst, id_eq] + · simp only [mfderiv_fst] rfl · exact hf.comp _ (mdifferentiableAt_id.prodMk mdifferentiableAt_const) · exact mdifferentiableAt_fst · have : (fun z : M × M' ↦ f (p.1, z.2)) = (fun z : M' ↦ f (p.1, z)) ∘ Prod.snd := rfl rw [this, mfderiv_comp (I' := I')] - · simp only [mfderiv_snd, id_eq] + · simp only [mfderiv_snd] rfl · exact hf.comp _ (mdifferentiableAt_const.prodMk mdifferentiableAt_id) · exact mdifferentiableAt_snd @@ -715,6 +715,7 @@ theorem hasMFDerivWithinAt_inl : exact (hasFDerivWithinAt_id (extChartAt I q q) _).congr_of_eventuallyEq this (by simp [writtenInExtChartAt, extChartAt]) +set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivAt_inl : HasMFDerivAt% (@Sum.inl M M') q (ContinuousLinearMap.id 𝕜 (TangentSpace% p)) := by simpa [HasMFDerivAt, hasMFDerivWithinAt_univ] using! hasMFDerivWithinAt_inl (s := Set.univ) @@ -728,6 +729,7 @@ theorem hasMFDerivWithinAt_inr {t : Set M'} : exact (hasFDerivWithinAt_id (extChartAt I q' q') _).congr_of_eventuallyEq this (by simp [writtenInExtChartAt, extChartAt]) +set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivAt_inr : HasMFDerivAt% (@Sum.inr M M') q' (ContinuousLinearMap.id 𝕜 (TangentSpace% p)) := by simpa [HasMFDerivAt, hasMFDerivWithinAt_univ] using! hasMFDerivWithinAt_inr (t := Set.univ) @@ -809,6 +811,7 @@ lemma HasMFDerivWithinAt.sum (hf : ∀ i ∈ t, HasMFDerivAt[s] (f i) z (f' i)) | empty => simpa using! hasMFDerivWithinAt_const .. | insert i s hi IH => grind [HasMFDerivWithinAt.add] +set_option backward.isDefEq.respectTransparency false in lemma HasMFDerivAt.sum (hf : ∀ i ∈ t, HasMFDerivAt% (f i) z (f' i)) : HasMFDerivAt% (∑ i ∈ t, f i) z (∑ i ∈ t, f' i) := by simp_all only [← hasMFDerivWithinAt_univ] @@ -860,6 +863,7 @@ theorem HasMFDerivWithinAt.neg {s : Set M} (hf : HasMFDerivAt[s] f z f') : theorem HasMFDerivAt.neg (hf : HasMFDerivAt% f z f') : HasMFDerivAt% (-f) z (-f') := ⟨hf.1.neg, hf.2.neg⟩ +set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivAt_neg : HasMFDerivAt% (-f) z (-f') ↔ HasMFDerivAt% f z f' := ⟨fun hf ↦ by convert! hf.neg <;> rw [neg_neg], fun hf ↦ hf.neg⟩ @@ -1012,6 +1016,7 @@ lemma HasMFDerivWithinAt.prod [DecidableEq ι] rw [t.erase_insert_of_ne (by grind), Finset.prod_insert (by grind)] · simp +set_option backward.isDefEq.respectTransparency false in lemma HasMFDerivAt.prod [DecidableEq ι] (hf : ∀ i ∈ t, HasMFDerivAt I 𝓘(𝕜, F') (f i) z (f' i)) : HasMFDerivAt I 𝓘(𝕜, F') (∏ i ∈ t, f i) z (∑ i ∈ t, (∏ j ∈ t.erase i, f j z) • (f' i)) := by @@ -1099,6 +1104,7 @@ section Field variable {z : M} {F' : Type*} [NormedField F'] [NormedAlgebra 𝕜 F'] {p q : M → F'} {p' q' : TangentSpace% z →L[𝕜] F'} +set_option backward.isDefEq.respectTransparency.types false in lemma HasMFDerivWithinAt.inv (hp : HasMFDerivWithinAt I 𝓘(𝕜, F') p s z p') (hp_ne : p z ≠ 0) : HasMFDerivWithinAt I 𝓘(𝕜, F') (p⁻¹) s z (-(p z ^ 2)⁻¹ • p' : E →L[𝕜] F') := by convert! hp.inv' hp_ne @@ -1110,6 +1116,7 @@ lemma HasMFDerivAt.inv (hp : HasMFDerivAt I 𝓘(𝕜, F') p z p') (hp_ne : p z HasMFDerivAt I 𝓘(𝕜, F') (p⁻¹) z (-(p z ^ 2)⁻¹ • p' : E →L[𝕜] F') := hasMFDerivWithinAt_univ.mp <| hp.hasMFDerivWithinAt.inv hp_ne +set_option backward.isDefEq.respectTransparency.types false in lemma HasMFDerivWithinAt.div (hp : HasMFDerivWithinAt I 𝓘(𝕜, F') p s z p') (hq : HasMFDerivWithinAt I 𝓘(𝕜, F') q s z q') (hq_ne : q z ≠ 0) : HasMFDerivWithinAt I 𝓘(𝕜, F') (p / q) s z diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean index ea2f7fa9b139b9..032c1ba7d91cf1 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean @@ -58,6 +58,7 @@ theorem tangentMap_chart_symm {p : TangentBundle I M} {q : TangentBundle I H} congr exact ((chartAt H (TotalSpace.proj p)).right_inv h).symm +set_option backward.isDefEq.respectTransparency false in lemma mfderiv_chartAt_eq_tangentCoordChange {x y : M} (hsrc : x ∈ (chartAt H y).source) : mfderiv% (chartAt H y) x = tangentCoordChange I x y x := by have := mdifferentiableAt_atlas (I := I) (ChartedSpace.chart_mem_atlas _) hsrc @@ -69,6 +70,7 @@ theorem UniqueMDiffOn.tangentBundle_proj_preimage {s : Set M} (hs : UniqueMDiffO UniqueMDiffOn I.tangent (π E (TangentSpace I) ⁻¹' s) := hs.bundle_preimage _ +set_option backward.isDefEq.respectTransparency false in /-- To write a linear map between tangent spaces in coordinates amounts to precomposing and postcomposing it with derivatives of extended charts. Concrete version of `inTangentCoordinates_eq`. -/ diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index 36b75f9d63a6a5..dd40ee6d8ea5b2 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -418,7 +418,7 @@ theorem mem_extChartAt_ind_source (x : M) (hx : x ∈ s) : fs.mem_extChartAt_source_of_eq_one (fs.apply_ind x hx) /-- The index type of a `SmoothBumpCovering` of a compact manifold is finite. -/ -@[implicit_reducible] +@[instance_reducible] protected def fintype [CompactSpace M] : Fintype ι := fs.locallyFinite.fintypeOfCompact fun i => (fs i).nonempty_support diff --git a/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean b/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean index 31a4874663c1bd..1933e856a715f8 100644 --- a/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean @@ -51,6 +51,7 @@ variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] open AlgebraicGeometry Manifold TopologicalSpace Topology +set_option backward.isDefEq.respectTransparency.types false in /-- The units of the stalk at `x` of the sheaf of smooth functions from `M` to `𝕜`, considered as a sheaf of commutative rings, are the functions whose values at `x` are nonzero. -/ theorem smoothSheafCommRing.isUnit_stalk_iff {x : M} @@ -130,6 +131,7 @@ instance smoothSheafCommRing.instLocalRing_stalk (x : M) : variable (M) /-- A smooth manifold can be considered as a locally ringed space. -/ +@[implicit_reducible] def ChartedSpace.locallyRingedSpace : LocallyRingedSpace where carrier := TopCat.of M presheaf := smoothPresheafCommRing IM 𝓘(𝕜) M 𝕜 @@ -150,6 +152,7 @@ def ChartedSpace.locallyRingedSpaceMapAux (f : M → N) (hf : ContMDiff IM IN base := TopCat.ofHom ⟨f, hf.continuous⟩ c := (hf.smoothSheafCommRingHom _ _ f).hom +set_option backward.isDefEq.respectTransparency.types false in /-- (Implementation): Use `ChartedSpace.stalkMap_locallyRingedSpaceMap_evalHom`. -/ lemma ChartedSpace.stalkMap_locallyRingedSpaceMapAux (f : M → N) (hf : ContMDiff IM IN ∞ f) (x : M) : diff --git a/Mathlib/Geometry/Manifold/Sheaf/Smooth.lean b/Mathlib/Geometry/Manifold/Sheaf/Smooth.lean index 8d6122641d7aeb..58f6e7df3480c9 100644 --- a/Mathlib/Geometry/Manifold/Sheaf/Smooth.lean +++ b/Mathlib/Geometry/Manifold/Sheaf/Smooth.lean @@ -126,6 +126,9 @@ def smoothSheaf.evalAt (x : TopCat.of M) (U : OpenNhds x) (i : (smoothSheaf IM I M N).presheaf.obj (Opposite.op U.val)) : N := i.1 ⟨x, U.2⟩ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc, elementwise] lemma smoothSheaf.ι_evalHom (x : TopCat.of M) (U) : colimit.ι ((OpenNhds.inclusion x).op ⋙ (smoothSheaf IM I M N).obj) U ≫ smoothSheaf.evalHom IM I N x = @@ -153,6 +156,7 @@ lemma smoothSheaf.contMDiff_section {U : (Opens (TopCat.of M))ᵒᵖ} ContMDiff IM I ∞ f := (contDiffWithinAt_localInvariantProp ∞).section_spec _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- A smooth function `f : M → N` induces a morphism of sheaves (of types) `𝒪_N ⟶ f_* 𝒪_M` by pre-composing with `f`. -/ @[simps! -isSimp hom_app_hom] @@ -290,6 +294,7 @@ def smoothPresheafCommRing : TopCat.Presheaf CommRingCat.{u} (TopCat.of M) := /-- The sheaf of smooth functions from `M` to `R`, for `R` a smooth commutative ring, as a sheaf of commutative rings. -/ +@[implicit_reducible] def smoothSheafCommRing : TopCat.Sheaf CommRingCat.{u} (TopCat.of M) where obj := smoothPresheafCommRing IM I M R property := by @@ -315,12 +320,14 @@ def smoothSheafCommRing.forgetStalk (x : TopCat.of M) : (smoothSheaf IM I M R).presheaf.stalk x := preservesColimitIso (forget CommRingCat) _ +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc, elementwise] lemma smoothSheafCommRing.ι_forgetStalk_hom (x : TopCat.of M) (U) : dsimp% ↾(colimit.ι ((OpenNhds.inclusion x).op ⋙ (smoothSheafCommRing IM I M R).presheaf) U).hom ≫ (forgetStalk IM I M R x).hom = colimit.ι ((OpenNhds.inclusion x).op ⋙ (smoothSheaf IM I M R).presheaf) U := ι_preservesColimitIso_hom (forget CommRingCat) _ _ +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc, elementwise] lemma smoothSheafCommRing.ι_forgetStalk_inv (x : TopCat.of M) (U) : colimit.ι ((OpenNhds.inclusion x).op ⋙ (smoothSheaf IM I M R).presheaf) U ≫ (smoothSheafCommRing.forgetStalk IM I M R x).inv = @@ -350,6 +357,9 @@ given by evaluating sections at `x`. -/ def smoothSheafCommRing.eval (x : M) : (smoothSheafCommRing IM I M R).presheaf.stalk x →+* R := (smoothSheafCommRing.evalHom IM I M R x).hom +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[simp, reassoc, elementwise] lemma smoothSheafCommRing.ι_evalHom (x : TopCat.of M) (U) : colimit.ι ((OpenNhds.inclusion x).op ⋙ _) U ≫ smoothSheafCommRing.evalHom IM I M R x = smoothSheafCommRing.evalAt _ _ _ _ _ _ := @@ -400,6 +410,7 @@ variable {IM I M R} = f ⟨x, hx⟩ := smoothSheafCommRing.evalHom_germ IM I M R U x hx f +set_option backward.isDefEq.respectTransparency.types false in /-- A smooth function `f : M → N` induces a morphism of sheaves (of rings) `𝒪_N ⟶ f_* 𝒪_M`, by pre-composing with `f`. -/ @[simps! -isSimp hom_app_hom_apply] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 37737a691ee37e..c0ffd9fd8f281c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -169,7 +169,7 @@ lemma toBasisAt_coe (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) (i : ι) : /-- If `{sᵢ}` is a local frame on a vector bundle, `F` being finite-dimensional implies the indexing set being finite. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfFiniteDimensional [VectorBundle 𝕜 F V] [FiniteDimensional 𝕜 F] (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) : Fintype ι := by have : FiniteDimensional 𝕜 (V x) := by @@ -445,6 +445,7 @@ variable [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] {ι : Type*} (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} {k : ℕ∞ω} {x x' : M} [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle k F V I] +set_option backward.isDefEq.respectTransparency false in /-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% s) x) (i : ι) : @@ -511,6 +512,7 @@ lemma contMDiffOn_baseSet_iff_localFrame_coeff : -- Differentiability of a section can be checked in terms of its local frame coefficients section MDifferentiable +set_option backward.isDefEq.respectTransparency false in /-- If `s` is differentiable at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame near `x` induced by `e` and `b` -/ lemma mdifferentiableAt_localFrame_coeff diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean index 874d00f6b95cd0..1d2881f435b1bf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean @@ -471,6 +471,7 @@ lemma contMDiffWithinAt_vectorSpace_iff_contDiffWithinAt convert! h.contMDiffWithinAt with y simp +set_option backward.isDefEq.respectTransparency false in /-- A vector field on a vector space is `C^n` in the manifold sense iff it is `C^n` in the vector space sense. -/ lemma contMDiffAt_vectorSpace_iff_contDiffAt @@ -486,6 +487,7 @@ lemma contMDiffOn_vectorSpace_iff_contDiffOn CMDiff[s] n (T% V) ↔ ContDiffOn 𝕜 n V s := by simp only [ContMDiffOn, ContDiffOn, contMDiffWithinAt_vectorSpace_iff_contDiffWithinAt] +set_option backward.isDefEq.respectTransparency false in /-- A vector field on a vector space is `C^n` in the manifold sense iff it is `C^n` in the vector space sense. -/ lemma contMDiff_vectorSpace_iff_contDiff {V : Π (x : E), TangentSpace 𝓘(𝕜, E) x} : diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 40c611771099de..2121cd4799ade1 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -327,6 +327,7 @@ lemma mfderiv_extChartAt_inverse_comp_mfderivWithin_extChartAT_symm (Y : Tangent mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (mem_extChartAt_source x)] exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) +set_option backward.isDefEq.respectTransparency false in variable (x W) in private lemma mfderiv_extChart_inverse_comp_aux : letI φ := extChartAt I x @@ -470,6 +471,7 @@ lemma mlieBracket_add_right (hW : MDiffAt (T% W) x) (hW₁ : MDiffAt (T% W₁) x simp only [← mlieBracketWithin_univ] at hW hW₁ ⊢ exact mlieBracketWithin_add_right hW hW₁ (uniqueMDiffWithinAt_univ _) +set_option backward.isDefEq.respectTransparency false in theorem mlieBracketWithin_of_mem_nhdsWithin (st : t ∈ 𝓝[s] x) (hs : UniqueMDiffAt[s] x) (hV : MDiffAt[t] (T% V) x) (hW : MDiffAt[t] (T% W) x) : mlieBracketWithin I V W s x = mlieBracketWithin I V W t x := by @@ -920,6 +922,7 @@ section Leibniz variable [IsManifold I (minSmoothness 𝕜 3) M] [CompleteSpace E] +set_option backward.isDefEq.respectTransparency false in /-- The Lie bracket of vector fields in manifolds satisfies the Leibniz identity `[U, [V, W]] = [[U, V], W] + [V, [U, W]]` (also called Jacobi identity). -/ theorem leibniz_identity_mlieBracketWithin_apply diff --git a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean index 7a44b80b89f725..c241e1f16d5ee5 100644 --- a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean +++ b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean @@ -210,6 +210,7 @@ lemma mpullbackWithin_eq_pullbackWithin {f : E → E'} {V : E' → E'} {s : Set simp only [mpullbackWithin, mfderivWithin_eq_fderivWithin, pullbackWithin] rfl +set_option backward.isDefEq.respectTransparency false in lemma mpullback_eq_pullback {f : E → E'} {V : E' → E'} : mpullback 𝓘(𝕜, E) 𝓘(𝕜, E') f V = pullback 𝕜 f V := by simp only [← mpullbackWithin_univ, ← pullbackWithin_univ, mpullbackWithin_eq_pullbackWithin] @@ -641,6 +642,7 @@ lemma eventually_contMDiffWithinAt_mpullbackWithin_extChartAt_symm simp only [mfld_simps] at hy h'y simp [hy, h'y] +set_option backward.isDefEq.respectTransparency false in omit [CompleteSpace E] in lemma eventuallyEq_mpullback_mpullbackWithin_extChartAt (V : Π (x : M), TangentSpace I x) : V =ᶠ[𝓝[s] x] mpullback I 𝓘(𝕜, E) (extChartAt I x) diff --git a/Mathlib/Geometry/RingedSpace/Basic.lean b/Mathlib/Geometry/RingedSpace/Basic.lean index 9e998ab3534122..079c149c1fbfc4 100644 --- a/Mathlib/Geometry/RingedSpace/Basic.lean +++ b/Mathlib/Geometry/RingedSpace/Basic.lean @@ -69,6 +69,7 @@ lemma exists_res_eq_zero_of_germ_eq_zero (U : Opens X) (f : X.presheaf.obj (op U use V, i, hv simpa using hv4 +set_option backward.isDefEq.respectTransparency.types false in /-- If the germ of a section `f` is a unit in the stalk at `x`, then `f` must be a unit on some small neighborhood around `x`. diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index b5d34121cfec62..854ce371863c3d 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -57,6 +57,7 @@ abbrev toRingedSpace : RingedSpace := X.toSheafedSpace /-- The underlying topological space of a locally ringed space. -/ +@[implicit_reducible] def toTopCat : TopCat := X.1.carrier @@ -385,6 +386,7 @@ lemma stalkSpecializes_stalkMap_apply (x x' : X) (h : x ⤳ x') (y) : (X.presheaf.stalkSpecializes h (f.stalkMap x' y)) := DFunLike.congr_fun (CommRingCat.hom_ext_iff.mp (stalkSpecializes_stalkMap f x x' h)) y +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma stalkMap_congr (f g : X ⟶ Y) (hfg : f = g) (x x' : X) (hxx' : x = x') : f.stalkMap x ≫ X.presheaf.stalkSpecializes (specializes_of_eq hxx'.symm) = @@ -400,6 +402,7 @@ lemma stalkMap_congr_hom (f g : X ⟶ Y) (hfg : f = g) (x : X) : subst hfg simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma stalkMap_congr_point {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x x' : X) (hxx' : x = x') : f.stalkMap x ≫ X.presheaf.stalkSpecializes (specializes_of_eq hxx'.symm) = @@ -407,6 +410,7 @@ lemma stalkMap_congr_point {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x x' : subst hxx' simp +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma stalkMap_hom_inv (e : X ≅ Y) (y : Y) : e.hom.stalkMap (e.inv.base y) ≫ e.inv.stalkMap y = @@ -414,12 +418,14 @@ lemma stalkMap_hom_inv (e : X ≅ Y) (y : Y) : rw [← stalkMap_comp, LocallyRingedSpace.stalkMap_congr_hom (e.inv ≫ e.hom) (𝟙 _) (by simp)] simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma stalkMap_hom_inv_apply (e : X ≅ Y) (y : Y) (z) : e.inv.stalkMap y (e.hom.stalkMap (e.inv.base y) z) = Y.presheaf.stalkSpecializes (specializes_of_eq <| by simp) z := DFunLike.congr_fun (CommRingCat.hom_ext_iff.mp (stalkMap_hom_inv e y)) z +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma stalkMap_inv_hom (e : X ≅ Y) (x : X) : e.inv.stalkMap (e.hom.base x) ≫ e.hom.stalkMap x = @@ -427,6 +433,7 @@ lemma stalkMap_inv_hom (e : X ≅ Y) (x : X) : rw [← stalkMap_comp, LocallyRingedSpace.stalkMap_congr_hom (e.hom ≫ e.inv) (𝟙 _) (by simp)] simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma stalkMap_inv_hom_apply (e : X ≅ Y) (x : X) (y) : e.hom.stalkMap x (e.inv.stalkMap (e.hom.base x) y) = @@ -444,6 +451,7 @@ lemma stalkMap_germ_apply (U : Opens Y) (x : X) (hx : f.base x ∈ U) (y) : X.presheaf.germ ((Opens.map f.base).obj U) x hx (f.c.app (op U) y) := PresheafedSpace.stalkMap_germ_apply f.toHom U x hx y +set_option backward.isDefEq.respectTransparency.types false in theorem preimage_basicOpen {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) {U : Opens Y} (s : Y.presheaf.obj (op U)) : (Opens.map f.base).obj (Y.toRingedSpace.basicOpen s) = diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean index 47476b21365096..cb27b4a3dd40f7 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean @@ -254,6 +254,7 @@ theorem coequalizer_π_stalk_isLocalHom (x : Y) : end HasCoequalizer +set_option backward.isDefEq.respectTransparency.types false in /-- The coequalizer of two locally ringed spaces in the category of sheafed spaces is a locally ringed space. -/ noncomputable def coequalizer : LocallyRingedSpace where diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean index 4175f420b82bb0..c013865e918286 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean @@ -118,6 +118,7 @@ lemma residueFieldMap_id (x : X) : simp only [residueFieldMap, stalkMap_id] apply IsLocalRing.ResidueField.map_id +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma residueFieldMap_comp {Z : LocallyRingedSpace.{u}} (g : Y ⟶ Z) (x : X) : residueFieldMap (f ≫ g) x = residueFieldMap g (f.base x) ≫ residueFieldMap f x := by @@ -125,6 +126,7 @@ lemma residueFieldMap_comp {Z : LocallyRingedSpace.{u}} (g : Y ⟶ Z) (x : X) : simp only [residueFieldMap, stalkMap_comp] apply IsLocalRing.ResidueField.map_comp (Hom.stalkMap g (f.base x)).hom (Hom.stalkMap f x).hom +set_option backward.isDefEq.respectTransparency.types false in @[reassoc] lemma evaluation_naturality {V : Opens Y} (x : (Opens.map f.base).obj V) : Y.evaluation ⟨f.base x, x.property⟩ ≫ residueFieldMap f x.val = diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 66683c5dd8a3e5..cc16fc4c453885 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -194,8 +194,10 @@ theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) : TopCat.Presheaf.pushforward_obj_map] congr 1 +set_option backward.isDefEq.respectTransparency.types false in instance (U : Opens X) : IsIso (invApp f U) := by delta invApp; infer_instance +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem inv_invApp (U : Opens X) : inv (H.invApp _ U) = @@ -248,6 +250,7 @@ instance (priority := 100) ofIsIso {X Y : PresheafedSpace C} (f : X ⟶ Y) [IsIs IsOpenImmersion f := AlgebraicGeometry.PresheafedSpace.IsOpenImmersion.ofIso (asIso f) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance ofRestrict {X : TopCat} (Y : PresheafedSpace C) {f : X ⟶ Y.carrier} (hf : IsOpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) where @@ -367,6 +370,7 @@ def pullbackConeOfLeft : PullbackCone f g := variable (s : PullbackCone f g) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- (Implementation.) Any cone over `cospan f g` indeed factors through the constructed cone. -/ @@ -583,6 +587,7 @@ section ToLocallyRingedSpace variable {X : PresheafedSpace CommRingCat} (Y : LocallyRingedSpace) variable (f : X ⟶ Y.toPresheafedSpace) [H : IsOpenImmersion f] +set_option backward.isDefEq.respectTransparency.types false in /-- If `X ⟶ Y` is an open immersion, and `Y` is a LocallyRingedSpace, then so is `X`. -/ def toLocallyRingedSpace : LocallyRingedSpace where toSheafedSpace := toSheafedSpace Y.toSheafedSpace f @@ -691,6 +696,7 @@ instance forgetCreatesPullbackOfRight : CreatesLimit (cospan g f) forget := (eqToIso (show pullback _ _ = pullback _ _ by congr) ≪≫ HasLimit.isoOfNatIso (diagramIsoCospan _).symm) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance sheafedSpace_forgetPreserves_of_left : PreservesLimit (cospan f g) (SheafedSpace.forget C) := @@ -788,6 +794,9 @@ variable {X Y : SheafedSpace C} (f : X ⟶ Y) [H : IsOpenImmersion f] abbrev opensFunctor : Opens X ⥤ Opens Y := H.base_open.functor +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- An open immersion `f : X ⟶ Y` induces an isomorphism `X ≅ Y|_{f(X)}`. -/ @[simps! hom_hom_c_app] noncomputable def isoRestrict : X ≅ Y.restrict H.base_open := @@ -808,6 +817,9 @@ noncomputable def invApp (U : Opens X) : X.presheaf.obj (op U) ⟶ Y.presheaf.obj (op (opensFunctor f |>.obj U)) := PresheafedSpace.IsOpenImmersion.invApp f.hom U +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) : X.presheaf.map i ≫ H.invApp _ (unop V) = @@ -955,7 +967,6 @@ instance sigma_ι_isOpenImmersion_aux [HasStrictTerminalObjects C] : exact congr_arg PresheafedSpace.Hom.base h₁ set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance sigma_ι_isOpenImmersion {ι : Type w} [Small.{v} ι] (F : Discrete ι ⥤ SheafedSpace.{_, v, v} C) [HasColimit F] (i : Discrete ι) [HasStrictTerminalObjects C] : @@ -1089,6 +1100,7 @@ instance forgetToPresheafedSpacePreservesOpenImmersion : ((LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forgetToPresheafedSpace).map f) := H +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance forgetToTop_preservesPullback_of_left : PreservesLimit (cospan f g) @@ -1222,6 +1234,9 @@ noncomputable def invApp (U : Opens X) : X.presheaf.obj (op U) ⟶ Y.presheaf.obj (op (opensFunctor f |>.obj U)) := PresheafedSpace.IsOpenImmersion.invApp f.1 U +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) : X.presheaf.map i ≫ H.invApp _ (unop V) = diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean index 1371a4be78e12e..9372fc5f92ff06 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean @@ -145,6 +145,7 @@ theorem id_c (X : PresheafedSpace C) : (𝟙 X : X ⟶ X).c = 𝟙 X.presheaf := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem id_c_app (X : PresheafedSpace C) (U) : (𝟙 X : X ⟶ X).c.app U = X.presheaf.map (𝟙 U) := by @@ -177,6 +178,7 @@ theorem comp_c_app {X Y Z : PresheafedSpace C} (α : X ⟶ Y) (β : Y ⟶ Z) (U) (α ≫ β).c.app U = β.c.app U ≫ α.c.app (op ((Opens.map β.base).obj (unop U))) := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem congr_app {X Y : PresheafedSpace C} {α β : X ⟶ Y} (h : α = β) (U) : α.c.app U = β.c.app U ≫ X.presheaf.map (eqToHom (by subst h; rfl)) := by diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean index 5a2d28638f84f4..f73944f0ac5219 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean @@ -462,6 +462,7 @@ theorem π_ιInvApp_π (i j : D.J) (U : Opens (D.U i).carrier) : · have : IsIso (D.t i j).c := by apply c_isIso_of_iso infer_instance +set_option backward.isDefEq.respectTransparency.types false in /-- `ιInvApp` is the inverse of `D.ι i` on `U`. -/ theorem π_ιInvApp_eq_id (i : D.J) (U : Opens (D.U i).carrier) : D.diagramOverOpenπ U i ≫ D.ιInvAppπEqMap U ≫ D.ιInvApp U = 𝟙 _ := by @@ -478,6 +479,7 @@ theorem π_ιInvApp_eq_id (i : D.J) (U : Opens (D.U i).carrier) : rw [Category.id_comp] apply π_ιInvApp_π +set_option backward.isDefEq.respectTransparency.types false in instance componentwise_diagram_π_isIso (i : D.J) (U : Opens (D.U i).carrier) : IsIso (D.diagramOverOpenπ U i) := by use D.ιInvAppπEqMap U ≫ D.ιInvApp U diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean index 9f189b5ed5d928..c9b686ba7e0471 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean @@ -55,6 +55,7 @@ attribute [local simp] eqToHom_map -- attribute [local aesop safe cases (rule_sets := [CategoryTheory])] Opens -- although it doesn't appear to help in this file, in any case. +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem map_id_c_app (F : J ⥤ PresheafedSpace.{_, _, v} C) (j) (U) : @@ -63,6 +64,7 @@ theorem map_id_c_app (F : J ⥤ PresheafedSpace.{_, _, v} C) (j) (U) : (pushforwardEq (by simp) (F.obj j).presheaf).hom.app U := by simp [PresheafedSpace.congr_app (F.map_id j)] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem map_comp_c_app (F : J ⥤ PresheafedSpace.{_, _, v} C) {j₁ j₂ j₃} @@ -273,6 +275,7 @@ def colimitCoconeIsColimit (F : J ⥤ PresheafedSpace.{_, _, v} C) : instance : HasColimitsOfShape J (PresheafedSpace.{_, _, v} C) where has_colimit F := ⟨colimitCocone F, colimitCoconeIsColimit F⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance : PreservesColimitsOfShape J (PresheafedSpace.forget.{v, u, v} C) := ⟨fun {F} => preservesColimit_of_preserves_colimit_cocone (colimitCoconeIsColimit F) <| by diff --git a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean index 87d8e317595398..901fed917b8ea4 100644 --- a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean @@ -237,6 +237,7 @@ variable [PreservesLimits (CategoryTheory.forget C)] variable [PreservesFilteredColimits (CategoryTheory.forget C)] variable [(CategoryTheory.forget C).ReflectsIsomorphisms] +set_option backward.isDefEq.respectTransparency.types false in attribute [local ext] DFunLike.ext in include instCC in lemma hom_stalk_ext {X Y : SheafedSpace C} (f g : X ⟶ Y) (h : f.hom.base = g.hom.base) @@ -266,6 +267,7 @@ lemma mono_of_base_injective_of_stalk_epi {X Y : SheafedSpace C} (f : X ⟶ Y) replace e := congr_arg InducedCategory.Hom.hom e congr 1 +set_option backward.isDefEq.respectTransparency.types false in attribute [local ext] DFunLike.ext in include instCC in lemma epi_of_base_surjective_of_stalk_mono {X Y : SheafedSpace C} (f : X ⟶ Y) diff --git a/Mathlib/Geometry/RingedSpace/Stalks.lean b/Mathlib/Geometry/RingedSpace/Stalks.lean index 9d05d6559c8942..cecbc38fcc906c 100644 --- a/Mathlib/Geometry/RingedSpace/Stalks.lean +++ b/Mathlib/Geometry/RingedSpace/Stalks.lean @@ -83,6 +83,7 @@ theorem restrictStalkIso_inv_eq_germ {U : TopCat.{v}} (X : PresheafedSpace.{_, _ (X.restrict h).presheaf.germ _ x hx := by rw [← restrictStalkIso_hom_eq_germ, Category.assoc, Iso.hom_inv_id, Category.comp_id] +set_option backward.isDefEq.respectTransparency.types false in theorem restrictStalkIso_inv_eq_ofRestrict {U : TopCat.{v}} (X : PresheafedSpace.{_, _, v} C) {f : U ⟶ (X : TopCat.{v})} (h : IsOpenEmbedding f) (x : U) : (X.restrictStalkIso h x).inv = (X.ofRestrict h).stalkMap x := by @@ -98,6 +99,7 @@ theorem restrictStalkIso_inv_eq_ofRestrict {U : TopCat.{v}} (X : PresheafedSpace erw [← X.presheaf.map_comp_assoc] exact (colimit.w ((OpenNhds.inclusion (f x)).op ⋙ X.presheaf) i.op).symm +set_option backward.isDefEq.respectTransparency.types false in instance ofRestrict_stalkMap_isIso {U : TopCat.{v}} (X : PresheafedSpace.{_, _, v} C) {f : U ⟶ (X : TopCat.{v})} (h : IsOpenEmbedding f) (x : U) : IsIso ((X.ofRestrict h).stalkMap x) := by diff --git a/Mathlib/GroupTheory/ArchimedeanDensely.lean b/Mathlib/GroupTheory/ArchimedeanDensely.lean index 5f15004f63addd..aa0dcdb38da470 100644 --- a/Mathlib/GroupTheory/ArchimedeanDensely.lean +++ b/Mathlib/GroupTheory/ArchimedeanDensely.lean @@ -202,6 +202,7 @@ noncomputable def LinearOrderedAddCommGroup.int_orderAddMonoidIso_of_isLeast_pos let f := closure_equiv_closure x (1 : ℤ) (by simp [h.left.ne']) exact ((((e.trans e').trans f).trans g').trans g : G ≃+o ℤ) +set_option backward.isDefEq.respectTransparency false in /-- If an element of a linearly ordered mul-archimedean group is the least element greater than 1, then the whole group is isomorphic (and order-isomorphic) to the multiplicative integers. -/ noncomputable def LinearOrderedCommGroup.multiplicative_int_orderMonoidIso_of_isLeast_one_lt @@ -266,6 +267,7 @@ lemma LinearOrderedAddCommGroup.isAddCyclic_iff_not_denselyOrdered {A : Type*} IsAddCyclic A ↔ ¬ DenselyOrdered A := by rw [← discrete_iff_not_denselyOrdered, isAddCyclic_iff_nonempty_equiv_int] +set_option backward.isDefEq.respectTransparency false in variable (G) in /-- Any linearly ordered mul-archimedean group is either isomorphic (and order-isomorphic) to the multiplicative integers, or is densely ordered. -/ @@ -274,6 +276,7 @@ lemma LinearOrderedCommGroup.discrete_or_denselyOrdered : rw [← OrderAddMonoidIso.toMultiplicativeRight.nonempty_congr] exact LinearOrderedAddCommGroup.discrete_or_denselyOrdered (Additive G) +set_option backward.isDefEq.respectTransparency false in variable (G) in /-- Any linearly ordered mul-archimedean group is either isomorphic (and order-isomorphic) to the multiplicative integers, or is densely ordered, exclusively. @@ -286,6 +289,7 @@ lemma LinearOrderedCommGroup.discrete_iff_not_denselyOrdered : LinearOrderedAddCommGroup.discrete_iff_not_denselyOrdered, denselyOrdered_iff_of_orderIsoClass e] +set_option backward.isDefEq.respectTransparency false in /-- Any non-trivial linearly ordered mul-archimedean group is either cyclic, or densely ordered, exclusively. -/ @[to_additive existing] @@ -304,6 +308,7 @@ lemma LinearOrderedCommGroupWithZero.discrete_or_denselyOrdered (G : Type*) intro ⟨f⟩ exact ⟨OrderMonoidIso.withZeroUnits.symm.trans f.withZero⟩ +set_option backward.isDefEq.respectTransparency false in open WithZero in /-- Any nontrivial (has other than 0 and 1) linearly ordered mul-archimedean group with zero is either isomorphic (and order-isomorphic) to `ℤᵐ⁰`, or is densely ordered, exclusively -/ @@ -373,6 +378,7 @@ lemma LinearOrderedAddCommGroup.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete · intro simp [Function.onFun, neg_le] +set_option backward.isDefEq.respectTransparency false in lemma LinearOrderedCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete {G : Type*} [CommGroup G] [LinearOrder G] [IsOrderedMonoid G] [Nontrivial G] {g : G} : Set.WellFoundedOn {x : G | g ≤ x} (· < ·) ↔ Nonempty (G ≃*o Multiplicative ℤ) := by @@ -392,6 +398,7 @@ lemma LinearOrderedCommGroup.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete · intro simp [Function.onFun, inv_le'] +set_option backward.isDefEq.respectTransparency false in lemma LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete_of_ne_zero {G₀ : Type*} [LinearOrderedCommGroupWithZero G₀] [Nontrivial G₀ˣ] {g : G₀} (hg : g ≠ 0) : Set.WellFoundedOn {x : G₀ | g ≤ x} (· < ·) ↔ Nonempty (G₀ ≃*o ℤᵐ⁰) := by diff --git a/Mathlib/GroupTheory/ClassEquation.lean b/Mathlib/GroupTheory/ClassEquation.lean index 0cb1257151298e..6a4fda33a8de2e 100644 --- a/Mathlib/GroupTheory/ClassEquation.lean +++ b/Mathlib/GroupTheory/ClassEquation.lean @@ -44,6 +44,7 @@ theorem Group.sum_card_conj_classes_eq_card [Finite G] : cases nonempty_fintype G simp [← sum_conjClasses_card_eq_card, finsum_eq_sum_of_fintype] +set_option backward.isDefEq.respectTransparency false in /-- The **class equation** for finite groups. The cardinality of a group is equal to the size of its center plus the sum of the size of all its nontrivial conjugacy classes. -/ theorem Group.nat_card_center_add_sum_card_noncenter_eq_card [Finite G] : diff --git a/Mathlib/GroupTheory/Complement.lean b/Mathlib/GroupTheory/Complement.lean index 3fb2ddd35ed71d..62e639f54c102f 100644 --- a/Mathlib/GroupTheory/Complement.lean +++ b/Mathlib/GroupTheory/Complement.lean @@ -383,12 +383,14 @@ theorem rightCosetEquivalence_equiv_snd (g : G) : -- This used to be `simp [...]` before https://github.com/leanprover/lean4/pull/2644 rw [RightCosetEquivalence, rightCoset_eq_iff, equiv_snd_eq_inv_mul]; simp +set_option backward.isDefEq.respectTransparency false in theorem equiv_fst_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ T) (hg : g ∈ S) : (hST.equiv g).fst = ⟨g, hg⟩ := by have : hST.equiv.symm (⟨g, hg⟩, ⟨1, h1⟩) = g := by rw [equiv, Equiv.ofBijective]; simp conv_lhs => rw [← this, Equiv.apply_symm_apply] +set_option backward.isDefEq.respectTransparency false in theorem equiv_snd_eq_self_of_mem_of_one_mem {g : G} (h1 : 1 ∈ S) (hg : g ∈ T) : (hST.equiv g).snd = ⟨g, hg⟩ := by have : hST.equiv.symm (⟨1, h1⟩, ⟨g, hg⟩) = g := by @@ -430,6 +432,7 @@ theorem equiv_mul_left_of_mem {h g : G} (hh : h ∈ H) : hHT.equiv (h * g) = (⟨h, hh⟩ * (hHT.equiv g).fst, (hHT.equiv g).snd) := equiv_mul_left _ ⟨h, hh⟩ g +set_option backward.isDefEq.respectTransparency false in theorem equiv_one (hs1 : 1 ∈ S) (ht1 : 1 ∈ T) : hST.equiv 1 = (⟨1, hs1⟩, ⟨1, ht1⟩) := by rw [Equiv.apply_eq_iff_eq_symm_apply]; simp [equiv] @@ -635,6 +638,9 @@ theorem IsComplement'.disjoint (h : IsComplement' H K) : Disjoint H K := theorem IsComplement'.index_eq_card (h : IsComplement' H K) : K.index = Nat.card H := h.card_left.symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- If `H` and `K` are complementary with `K` normal, then `G ⧸ K` is isomorphic to `H`. -/ @[simps!] noncomputable def IsComplement'.QuotientMulEquiv [K.Normal] (h : H.IsComplement' K) : diff --git a/Mathlib/GroupTheory/Congruence/Basic.lean b/Mathlib/GroupTheory/Congruence/Basic.lean index ef9728e074efa5..25d07eba219386 100644 --- a/Mathlib/GroupTheory/Congruence/Basic.lean +++ b/Mathlib/GroupTheory/Congruence/Basic.lean @@ -240,6 +240,7 @@ lemma comapQuotientEquivOfSurj_symm_mk (c : Con M) {f : N →* M} (hf) (x : N) : (comapQuotientEquivOfSurj c f hf).symm (f x) = x := (MulEquiv.symm_apply_eq (c.comapQuotientEquivOfSurj f hf)).mpr rfl +set_option backward.isDefEq.respectTransparency false in /-- This version infers the surjectivity of the function from a MulEquiv function -/ @[to_additive (attr := simp) /-- This version infers the surjectivity of the function from a MulEquiv function -/] diff --git a/Mathlib/GroupTheory/Congruence/Hom.lean b/Mathlib/GroupTheory/Congruence/Hom.lean index 0d95b7350e7028..362c11bc32f728 100644 --- a/Mathlib/GroupTheory/Congruence/Hom.lean +++ b/Mathlib/GroupTheory/Congruence/Hom.lean @@ -181,6 +181,7 @@ theorem comap_eq {f : N →* M} : comap f f.map_mul c = ker (c.mk'.comp f) := variable (c) (f : M →* P) +set_option backward.isDefEq.respectTransparency false in /-- The homomorphism on the quotient of a monoid by a congruence relation `c` induced by a homomorphism constant on `c`'s equivalence classes. -/ @[to_additive /-- The homomorphism on the quotient of an `AddMonoid` by an additive congruence diff --git a/Mathlib/GroupTheory/CoprodI.lean b/Mathlib/GroupTheory/CoprodI.lean index 813df471b1eaa8..1419429b37cdd4 100644 --- a/Mathlib/GroupTheory/CoprodI.lean +++ b/Mathlib/GroupTheory/CoprodI.lean @@ -459,6 +459,7 @@ theorem mem_of_mem_equivPair_tail {i j : ι} {w : Word M} (m : M i) : · revert h; cases w.toList <;> simp +contextual set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in theorem equivPair_head {i : ι} {w : Word M} : (equivPair i w).head = if h : ∃ (h : w.toList ≠ []), (w.toList.head h).1 = i @@ -885,6 +886,7 @@ theorem empty_of_word_prod_eq_one {w : Word H} (h : lift f w.prod = 1) : obtain ⟨i, j, w, rfl⟩ := NeWord.of_word w hnotempty exact lift_word_prod_nontrivial_of_not_empty f hcard X hXnonempty hXdisj hpp w h +set_option backward.isDefEq.respectTransparency false in include hcard in /-- The **Ping-Pong-Lemma**. @@ -957,6 +959,7 @@ variable (hXYdisj : ∀ i j, Disjoint (X i) (Y j)) variable (hX : ∀ i, a i • (Y i)ᶜ ⊆ X i) variable (hY : ∀ i, a⁻¹ i • (X i)ᶜ ⊆ Y i) +set_option backward.isDefEq.respectTransparency false in include hXnonempty hXdisj hYdisj hXYdisj hX hY in /-- The Ping-Pong-Lemma. diff --git a/Mathlib/GroupTheory/Coset/Defs.lean b/Mathlib/GroupTheory/Coset/Defs.lean index cc549b53317b5e..2af03b2d5f21d5 100644 --- a/Mathlib/GroupTheory/Coset/Defs.lean +++ b/Mathlib/GroupTheory/Coset/Defs.lean @@ -60,7 +60,7 @@ variable [Group α] (s : Subgroup α) /-- The equivalence relation corresponding to the partition of a group by left cosets of a subgroup. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The equivalence relation corresponding to the partition of a group by left cosets of a subgroup. -/] def leftRel : Setoid α := @@ -100,7 +100,7 @@ instance [DecidablePred (· ∈ s)] : DecidableEq (α ⧸ s) := /-- The equivalence relation corresponding to the partition of a group by right cosets of a subgroup. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The equivalence relation corresponding to the partition of a group by right cosets of a subgroup. -/] def rightRel : Setoid α := diff --git a/Mathlib/GroupTheory/Coxeter/Basic.lean b/Mathlib/GroupTheory/Coxeter/Basic.lean index ec6e35fce15be0..9d635425464da8 100644 --- a/Mathlib/GroupTheory/Coxeter/Basic.lean +++ b/Mathlib/GroupTheory/Coxeter/Basic.lean @@ -199,6 +199,7 @@ theorem _root_.CoxeterMatrix.toCoxeterSystem_simple (M : CoxeterMatrix B) : local prefix:100 "s" => cs.simple +set_option backward.isDefEq.respectTransparency false in @[simp] theorem simple_mul_simple_self (i : B) : s i * s i = 1 := by have : (FreeGroup.of i) * (FreeGroup.of i) ∈ M.relationsSet := ⟨(i, i), by simp [relation]⟩ @@ -222,6 +223,7 @@ theorem simple_mul_simple_cancel_left {w : W} (i : B) : s i * (s i * w) = w := b theorem inv_simple (i : B) : (s i)⁻¹ = s i := (eq_inv_of_mul_eq_one_right (cs.simple_mul_simple_self i)).symm +set_option backward.isDefEq.respectTransparency false in @[simp] theorem simple_mul_simple_pow (i i' : B) : (s i * s i') ^ M i i' = 1 := by have : (FreeGroup.of i * FreeGroup.of i') ^ M i i' ∈ M.relationsSet := ⟨(i, i'), rfl⟩ @@ -314,6 +316,7 @@ private def restrictUnit {G : Type*} [Monoid G] {f : B → G} (hf : IsLiftable M val_inv := pow_one (f i * f i) ▸ M.diagonal i ▸ hf i i inv_val := pow_one (f i * f i) ▸ M.diagonal i ▸ hf i i +set_option backward.isDefEq.respectTransparency false in private theorem toMonoidHom_apply_symm_apply (a : PresentedGroup (M.relationsSet)) : (MulEquiv.toMonoidHom cs.mulEquiv : W →* PresentedGroup (M.relationsSet)) ((MulEquiv.symm cs.mulEquiv) a) = a := calc @@ -349,6 +352,7 @@ def lift {G : Type*} [Monoid G] : {f : B → G // IsLiftable M f} ≃ (W →* G) theorem lift_apply_simple {G : Type*} [Monoid G] {f : B → G} (hf : IsLiftable M f) (i : B) : cs.lift ⟨f, hf⟩ (s i) = f i := congrFun (congrArg Subtype.val (cs.lift.left_inv ⟨f, hf⟩)) i +set_option backward.isDefEq.respectTransparency false in /-- If two Coxeter systems on the same group `W` have the same Coxeter matrix `M : Matrix B B ℕ` and the same simple reflection map `B → W`, then they are identical. -/ theorem simple_determines_coxeterSystem : diff --git a/Mathlib/GroupTheory/Coxeter/Inversion.lean b/Mathlib/GroupTheory/Coxeter/Inversion.lean index 43ab142b541a9a..f6da05161685be 100644 --- a/Mathlib/GroupTheory/Coxeter/Inversion.lean +++ b/Mathlib/GroupTheory/Coxeter/Inversion.lean @@ -220,7 +220,7 @@ theorem rightInvSeq_concat (ω : List B) (i : B) : dsimp [rightInvSeq, concat] rw [ih] simp only [concat_eq_append, wordProd_append, wordProd_cons, wordProd_nil, mul_one, mul_inv_rev, - inv_simple, cons.injEq, and_true] + inv_simple, map_cons, MulAut.conj_apply, cons_append, cons.injEq, and_true] group private theorem leftInvSeq_eq_reverse_rightInvSeq_reverse (ω : List B) : diff --git a/Mathlib/GroupTheory/Coxeter/Matrix.lean b/Mathlib/GroupTheory/Coxeter/Matrix.lean index 48e73a06beccca..24d617230fd3dd 100644 --- a/Mathlib/GroupTheory/Coxeter/Matrix.lean +++ b/Mathlib/GroupTheory/Coxeter/Matrix.lean @@ -171,6 +171,7 @@ protected def I (m : ℕ) : CoxeterMatrix (Fin 2) where @[deprecated (since := "2026-03-25")] alias I₂ₙ := CoxeterMatrix.I +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type E₆. The corresponding Coxeter-Dynkin diagram is: @@ -188,6 +189,7 @@ def E₆ : CoxeterMatrix (Fin 6) where 2, 2, 2, 3, 1, 3; 2, 2, 2, 2, 3, 1] +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type E₇. The corresponding Coxeter-Dynkin diagram is: @@ -206,6 +208,7 @@ def E₇ : CoxeterMatrix (Fin 7) where 2, 2, 2, 2, 3, 1, 3; 2, 2, 2, 2, 2, 3, 1] +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type E₈. The corresponding Coxeter-Dynkin diagram is: @@ -225,6 +228,7 @@ def E₈ : CoxeterMatrix (Fin 8) where 2, 2, 2, 2, 2, 3, 1, 3; 2, 2, 2, 2, 2, 2, 3, 1] +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type F₄. The corresponding Coxeter-Dynkin diagram is: @@ -239,6 +243,7 @@ def F₄ : CoxeterMatrix (Fin 4) where 2, 4, 1, 3; 2, 2, 3, 1] +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type G₂. The corresponding Coxeter-Dynkin diagram is: @@ -251,6 +256,7 @@ def G₂ : CoxeterMatrix (Fin 2) where M := !![1, 6; 6, 1] +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type H₃. The corresponding Coxeter-Dynkin diagram is: @@ -264,6 +270,7 @@ def H₃ : CoxeterMatrix (Fin 3) where 3, 1, 5; 2, 5, 1] +set_option backward.isDefEq.respectTransparency false in /-- The Coxeter matrix of type H₄. The corresponding Coxeter-Dynkin diagram is: diff --git a/Mathlib/GroupTheory/Divisible.lean b/Mathlib/GroupTheory/Divisible.lean index 61a7358f2531b5..aedc67e0134ae6 100644 --- a/Mathlib/GroupTheory/Divisible.lean +++ b/Mathlib/GroupTheory/Divisible.lean @@ -125,7 +125,7 @@ theorem RootableBy.surjective_pow [RootableBy A α] {n : α} (hn : n ≠ 0) : A `Monoid A` is `α`-rootable iff the `pow _ n` function is surjective, i.e. the constructive version implies the textbook approach. -/ -@[to_additive (attr := implicit_reducible) divisibleByOfSMulRightSurj +@[to_additive (attr := instance_reducible) divisibleByOfSMulRightSurj /-- An `AddMonoid A` is `α`-divisible iff `n • _` is a surjective function, i.e. the constructive version implies the textbook approach. -/] noncomputable def rootableByOfPowLeftSurj @@ -185,7 +185,7 @@ theorem smul_top_eq_top_of_divisibleBy_int [DivisibleBy A ℤ] {n : ℤ} (hn : n /-- If for all `n ≠ 0 ∈ ℤ`, `n • A = A`, then `A` is divisible. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def divisibleByIntOfSMulTopEqTop (H : ∀ {n : ℤ} (_hn : n ≠ 0), n • (⊤ : AddSubgroup A) = ⊤) : DivisibleBy A ℤ where div a n := @@ -212,7 +212,7 @@ variable (A : Type*) [Group A] open Int in /-- A group is `ℤ`-rootable if it is `ℕ`-rootable. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive group is `ℤ`-divisible if it is `ℕ`-divisible. -/] def rootableByIntOfRootableByNat [RootableBy A ℕ] : RootableBy A ℤ where root a z := @@ -228,7 +228,7 @@ def rootableByIntOfRootableByNat [RootableBy A ℕ] : RootableBy A ℤ where /-- A group is `ℕ`-rootable if it is `ℤ`-rootable -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive group is `ℕ`-divisible if it `ℤ`-divisible. -/] def rootableByNatOfRootableByInt [RootableBy A ℤ] : RootableBy A ℕ where root a n := RootableBy.root a (n : ℤ) @@ -248,7 +248,7 @@ variable (f : A → B) /-- If `f : A → B` is a surjective homomorphism and `A` is `α`-rootable, then `B` is also `α`-rootable. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If `f : A → B` is a surjective homomorphism and `A` is `α`-divisible, then `B` is also `α`-divisible. -/] noncomputable def Function.Surjective.rootableBy (hf : Function.Surjective f) diff --git a/Mathlib/GroupTheory/DivisibleHull.lean b/Mathlib/GroupTheory/DivisibleHull.lean index 30100ec81adb44..ccf545609caf85 100644 --- a/Mathlib/GroupTheory/DivisibleHull.lean +++ b/Mathlib/GroupTheory/DivisibleHull.lean @@ -196,6 +196,7 @@ theorem qsmul_of_nonpos {a : ℚ} (h : a ≤ 0) (x : DivisibleHull M) : have := h.eq_or_lt aesop (add simp [qsmul_def, abs_of_neg]) +set_option backward.isDefEq.respectTransparency false in theorem qsmul_mk (a : ℚ) (m : M) (s : ℕ+) : a • mk m s = mk (a.num • m) (⟨a.den, a.den_pos⟩ * s) := by obtain h | h := le_total 0 a @@ -209,6 +210,7 @@ theorem qsmul_mk (a : ℚ) (m : M) (s : ℕ+) : simpa using h simp [nnqsmul_mk, this, ← neg_mk] +set_option backward.isDefEq.respectTransparency false in noncomputable instance : Module ℚ (DivisibleHull M) where one_smul x := by @@ -268,6 +270,7 @@ instance : LE (DivisibleHull M) where theorem mk_le_mk {m m' : M} {s s' : ℕ+} : mk m s ≤ mk m' s' ↔ s'.val • m ≤ s.val • m' := by rfl +set_option backward.isDefEq.respectTransparency false in instance : LinearOrder (DivisibleHull M) where le_refl a := by induction a with | mk m s @@ -312,6 +315,7 @@ instance : IsOrderedCancelAddMonoid (DivisibleHull M) := simp_rw [PNat.mul_coe, smul_smul] at this convert! this using 3 <;> ring) +set_option backward.isDefEq.respectTransparency false in instance : IsStrictOrderedModule ℚ≥0 (DivisibleHull M) where smul_lt_smul_of_pos_left a ha b c h := by induction b with | mk mb sb @@ -333,6 +337,7 @@ end LinearOrder section OrderedGroup variable {M : Type*} [AddCommGroup M] [LinearOrder M] [IsOrderedAddMonoid M] +set_option backward.isDefEq.respectTransparency false in instance : IsStrictOrderedModule ℚ (DivisibleHull M) where smul_lt_smul_of_pos_left a ha b c h := by simp_rw [qsmul_of_nonneg ha.le] diff --git a/Mathlib/GroupTheory/DoubleCoset.lean b/Mathlib/GroupTheory/DoubleCoset.lean index 1b34f4dec5c52d..d6e8aeecbd926e 100644 --- a/Mathlib/GroupTheory/DoubleCoset.lean +++ b/Mathlib/GroupTheory/DoubleCoset.lean @@ -71,7 +71,7 @@ lemma eq_of_not_disjoint {H K : Subgroup G} {a b : G} apply doubleCoset_eq_of_mem ha /-- The setoid defined by the `doubleCoset` relation -/ -@[implicit_reducible] +@[instance_reducible] def setoid (H K : Set G) : Setoid G := Setoid.ker fun x => doubleCoset x H K @@ -140,6 +140,7 @@ lemma mk_eq_of_doubleCoset_eq {H K : Subgroup G} {a b : G} rw [eq] exact mem_doubleCoset.mp (h.symm ▸ mem_doubleCoset_self H K b) +set_option backward.isDefEq.respectTransparency false in lemma mem_quotToDoubleCoset_iff {H K : Subgroup G} (i : Quotient (H : Set G) K) (a : G) : a ∈ quotToDoubleCoset H K i ↔ mk H K a = i := by refine ⟨fun hg ↦ by simp [mk_eq_of_doubleCoset_eq (doubleCoset_eq_of_mem hg)], fun hg ↦ ?_⟩ diff --git a/Mathlib/GroupTheory/Exponent.lean b/Mathlib/GroupTheory/Exponent.lean index baa75fb99d4236..f10d903e952b4e 100644 --- a/Mathlib/GroupTheory/Exponent.lean +++ b/Mathlib/GroupTheory/Exponent.lean @@ -84,6 +84,7 @@ theorem _root_.AddMonoid.exponent_additive : theorem exponent_multiplicative {G : Type*} [AddMonoid G] : exponent (Multiplicative G) = AddMonoid.exponent G := rfl +set_option backward.isDefEq.respectTransparency false in open MulOpposite in @[to_additive (attr := simp)] theorem _root_.MulOpposite.exponent : exponent (MulOpposite G) = exponent G := by @@ -99,6 +100,7 @@ theorem ExponentExists.isOfFinOrder (h : ExponentExists G) {g : G} : IsOfFinOrde theorem ExponentExists.orderOf_pos (h : ExponentExists G) (g : G) : 0 < orderOf g := h.isOfFinOrder.orderOf_pos +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem exponent_ne_zero : exponent G ≠ 0 ↔ ExponentExists G := by rw [exponent] @@ -506,6 +508,7 @@ section CancelCommMonoid variable [CancelCommMonoid G] +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem exponent_eq_max'_orderOf [Fintype G] : exponent G = ((@Finset.univ G _).image orderOf).max' ⟨1, by simp⟩ := by diff --git a/Mathlib/GroupTheory/FixedPointFree.lean b/Mathlib/GroupTheory/FixedPointFree.lean index 0667459f420b41..31f2ea235c2006 100644 --- a/Mathlib/GroupTheory/FixedPointFree.lean +++ b/Mathlib/GroupTheory/FixedPointFree.lean @@ -71,7 +71,7 @@ theorem commute_all_of_involutive (hφ : FixedPointFree φ) (h2 : Function.Invol rwa [hφ.coe_eq_inv_of_involutive h2, inv_eq_iff_eq_inv, mul_inv_rev, inv_inv, inv_inv] at key /-- If a finite group admits a fixed-point-free involution, then it is commutative. -/ -@[implicit_reducible] +@[instance_reducible] def commGroupOfInvolutive (hφ : FixedPointFree φ) (h2 : Function.Involutive φ) : CommGroup G := .mk (hφ.commute_all_of_involutive h2) diff --git a/Mathlib/GroupTheory/FreeAbelianGroup.lean b/Mathlib/GroupTheory/FreeAbelianGroup.lean index cabbd53143f759..b9c068cd46ca91 100644 --- a/Mathlib/GroupTheory/FreeAbelianGroup.lean +++ b/Mathlib/GroupTheory/FreeAbelianGroup.lean @@ -190,6 +190,9 @@ theorem lift_add_apply [AddCommGroup G] (f g : α → G) (a : FreeAbelianGroup @[simp] lemma lift_add [AddCommGroup G] (f g : α → G) : lift (f + g) = lift f + lift g := AddMonoidHom.ext <| lift_add_apply _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- `FreeAbelianGroup.lift` as an equivalence of groups. -/ @[simps!] def liftAddEquiv [AddCommGroup G] : (α → G) ≃+ (FreeAbelianGroup α →+ G) := ⟨lift, lift_add⟩ diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 614f4742809c6c..fe01d48e4b619d 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -669,6 +669,7 @@ def Lift.aux : List (α × Bool) → β := fun L => theorem Red.Step.lift {f : α → β} (H : Red.Step L₁ L₂) : Lift.aux f L₁ = Lift.aux f L₂ := by obtain @⟨_, _, _, b⟩ := H; cases b <;> simp [Lift.aux, List.prod_append] +set_option backward.isDefEq.respectTransparency false in /-- If `β` is a group, then any function from `α` to `β` extends uniquely to a group homomorphism from the free group over `α` to `β` -/ @[to_additive (attr := simps symm_apply) @@ -741,6 +742,7 @@ section Map variable {β : Type v} (f : α → β) {x y : FreeGroup α} +set_option backward.isDefEq.respectTransparency false in /-- Any function from `α` to `β` extends uniquely to a group homomorphism from the free group over `α` to the free group over `β`. -/ @[to_additive /-- Any function from `α` to `β` extends uniquely to an additive group homomorphism @@ -964,6 +966,7 @@ def equivIntOfUnique [Unique α] : FreeGroup α ≃ ℤ where | succ x hx => simpa [zpow_add_one] using hx | pred x hx => simpa [zpow_sub_one, ← sub_eq_add_neg] using hx +set_option backward.isDefEq.respectTransparency false in /-- The isomorphism between the free group on a unique type and the integers. -/ def mulEquivIntOfUnique [Unique α] : FreeGroup α ≃* Multiplicative ℤ where toFun := Multiplicative.ofAdd ∘ equivIntOfUnique diff --git a/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean b/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean index 5d530de01f370b..cd6e4d4d04edce 100644 --- a/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean +++ b/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean @@ -114,6 +114,9 @@ lemma isFreeGroup (b : FreeGroupBasis ι G) : IsFreeGroup G := instance (X : Type*) : IsFreeGroup (FreeGroup X) := (ofFreeGroup X).isFreeGroup +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a free group basis of `G` over `ι`, there is a canonical bijection between maps from `ι` to a group `H` and morphisms from `G` to `H`. -/ @[simps!] diff --git a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean index 7f97a7643abb32..039cca2fef9fc9 100644 --- a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean +++ b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean @@ -96,6 +96,7 @@ theorem ext_functor {G} [Groupoid.{v} G] [IsFreeGroupoid G] {X : Type v} [Group let ⟨_, _, u⟩ := @unique_lift G _ _ X _ fun (a b : Generators G) (e : a ⟶ b) => g.map (of e) _root_.trans (u _ h) (u _ fun _ _ _ => rfl).symm +set_option backward.isDefEq.respectTransparency.types false in /-- An action groupoid over a free group is free. More generally, one could show that the groupoid of elements over a free groupoid is free, but this version is easier to prove and suffices for our purposes. @@ -155,6 +156,7 @@ private def root' : G := -- this has to be marked noncomputable, see issue https://github.com/leanprover-community/mathlib4/pull/451. -- It might be nicer to define this in terms of `composePath` +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- A path in the tree gives a hom, by composition. -/ @@ -162,12 +164,14 @@ def homOfPath : ∀ {a : G}, Path (root T) a → (root' T ⟶ a) | _, Path.nil => 𝟙 _ | _, Path.cons p f => homOfPath p ≫ Sum.recOn f.val (fun e => of e) fun e => inv (of e) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- For every vertex `a`, there is a canonical hom from the root, given by the path in the tree. -/ def treeHom (a : G) : root' T ⟶ a := homOfPath T default +set_option backward.isDefEq.respectTransparency.types false in /-- Any path to `a` gives `treeHom T a`, since paths in the tree are unique. -/ theorem treeHom_eq {a : G} (p : Path (root T) a) : treeHom T a = homOfPath T p := by rw [treeHom, Unique.default_eq] @@ -199,6 +203,7 @@ theorem loopOfHom_eq_id {a b : Generators G} (e) (H : e ∈ wideSubquiverSymmetr · rw [treeHom_eq T (Path.cons default ⟨Sum.inr e, H⟩), homOfPath] simp only [IsIso.inv_hom_id, Category.comp_id, Category.assoc, treeHom] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Since a hom gives a loop, any homomorphism from the vertex group at the root @@ -270,6 +275,7 @@ set_option backward.privateInPublic true in /-- Another name for the identity function `G → G`, to help type checking. -/ private def symgen {G : Type u} [Groupoid.{v} G] : G → Symmetrify (Generators G) := id +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- If there exists a morphism `a → b` in a free groupoid, then there also exists a zigzag diff --git a/Mathlib/GroupTheory/GroupAction/CardCommute.lean b/Mathlib/GroupTheory/GroupAction/CardCommute.lean index a3d60864ae084c..d714e5be99c14a 100644 --- a/Mathlib/GroupTheory/GroupAction/CardCommute.lean +++ b/Mathlib/GroupTheory/GroupAction/CardCommute.lean @@ -66,6 +66,7 @@ theorem card_eq_sum_card_group_div_card_stabilizer [Fintype α] [Fintype β] [Fi end MulAction +set_option backward.isDefEq.respectTransparency false in instance instInfiniteProdSubtypeCommute [Mul α] [Infinite α] : Infinite { p : α × α // Commute p.1 p.2 } := Infinite.of_injective (fun a => ⟨⟨a, a⟩, rfl⟩) (by intro; simp) diff --git a/Mathlib/GroupTheory/GroupAction/ConjAct.lean b/Mathlib/GroupTheory/GroupAction/ConjAct.lean index e63abfbcc6fb5f..2c604fc33d14b6 100644 --- a/Mathlib/GroupTheory/GroupAction/ConjAct.lean +++ b/Mathlib/GroupTheory/GroupAction/ConjAct.lean @@ -252,6 +252,7 @@ theorem _root_.MulAut.conjNormal_apply {H : Subgroup G} [H.Normal] (g : G) (h : ↑(MulAut.conjNormal g h) = g * h * g⁻¹ := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem _root_.MulAut.conjNormal_symm_apply {H : Subgroup G} [H.Normal] (g : G) (h : H) : ↑((MulAut.conjNormal g).symm h) = g⁻¹ * h * g := by diff --git a/Mathlib/GroupTheory/GroupAction/Hom.lean b/Mathlib/GroupTheory/GroupAction/Hom.lean index d841820eabda11..73c4aa2d4fe5ab 100644 --- a/Mathlib/GroupTheory/GroupAction/Hom.lean +++ b/Mathlib/GroupTheory/GroupAction/Hom.lean @@ -228,7 +228,7 @@ lemma _root_.FaithfulSMul.of_injective variable {ψ χ} (M N) /-- The identity map as an equivariant map. -/ -@[to_additive (attr := implicit_reducible) /-- The identity map as an equivariant map. -/] +@[to_additive (attr := instance_reducible) /-- The identity map as an equivariant map. -/] protected def id : X →[M] X := ⟨fun x ↦ x, fun _ _ => rfl⟩ @@ -249,7 +249,7 @@ variable {φ ψ χ X Y Z} -- attribute [instance] CompTriple.id_comp CompTriple.comp_id /-- Composition of two equivariant maps. -/ -@[to_additive (attr := implicit_reducible) /-- Composition of two equivariant maps. -/] +@[to_additive (attr := instance_reducible) /-- Composition of two equivariant maps. -/] def comp (g : Y →ₑ[ψ] Z) (f : X →ₑ[φ] Y) [κ : CompTriple φ ψ χ] : X →ₑ[χ] Z := ⟨fun x ↦ g (f x), fun m x => @@ -770,7 +770,7 @@ protected theorem map_smulₑ (f : A →ₑ*[φ] B) (m : M) (x : A) : f (m • x variable (M) /-- The identity map as an equivariant monoid homomorphism. -/ -@[to_additive (dont_translate := M) (attr := implicit_reducible) +@[to_additive (dont_translate := M) (attr := instance_reducible) /-- The identity map as an equivariant additive monoid homomorphism. -/] protected def id : A →*[M] A := ⟨MulActionHom.id _, rfl, fun _ _ => rfl⟩ @@ -812,7 +812,7 @@ instance {A : Type*} [AddMonoid A] [DistribMulAction M A] ⟨0⟩ /-- Composition of two equivariant monoid homomorphisms. -/ -@[to_additive (dont_translate := M N P) (attr := implicit_reducible) +@[to_additive (dont_translate := M N P) (attr := instance_reducible) /-- Composition of two equivariant additive monoid homomorphisms. -/] def comp [κ : MonoidHom.CompTriple φ ψ χ] (g : B →ₑ*[ψ] C) (f : A →ₑ*[φ] B) : A →ₑ*[χ] C := @@ -988,7 +988,7 @@ namespace MulSemiringActionHom variable (M) {R} /-- The identity map as an equivariant ring homomorphism. -/ -@[implicit_reducible] +@[instance_reducible] protected def id : R →+*[M] R := ⟨DistribMulActionHom.id _, rfl, (fun _ _ => rfl)⟩ @@ -1007,7 +1007,7 @@ variable {R S T} variable {φ φ' ψ χ} /-- Composition of two equivariant additive ring homomorphisms. -/ -@[implicit_reducible] +@[instance_reducible] def comp (g : S →ₑ+*[ψ] T) (f : R →ₑ+*[φ] S) [κ : MonoidHom.CompTriple φ ψ χ] : R →ₑ+*[χ] T := { DistribMulActionHom.comp (g : S →ₑ+[ψ] T) (f : R →ₑ+[φ] S), RingHom.comp (g : S →+* T) (f : R →+* S) with } diff --git a/Mathlib/GroupTheory/GroupAction/Jordan.lean b/Mathlib/GroupTheory/GroupAction/Jordan.lean index d0b05c2060d74a..23148d34ad92ff 100644 --- a/Mathlib/GroupTheory/GroupAction/Jordan.lean +++ b/Mathlib/GroupTheory/GroupAction/Jordan.lean @@ -298,7 +298,7 @@ section Subgroups namespace Equiv.Perm -open Equiv Set +open Equiv variable {α : Type*} diff --git a/Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean b/Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean index 4b5b94fee86bf1..0bb856ce1729f3 100644 --- a/Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean +++ b/Mathlib/GroupTheory/GroupAction/SubMulAction/Combination.lean @@ -135,6 +135,7 @@ attribute [to_additive existing] faithfulSMul variable (α G) +set_option backward.isDefEq.respectTransparency false in variable (n) in /-- The equivariant map from embeddings of `Fin n` (aka arrangement) to combinations. -/ @[to_additive /-- The equivariant map from embeddings of `Fin n` diff --git a/Mathlib/GroupTheory/GroupAction/SubMulAction/OfFixingSubgroup.lean b/Mathlib/GroupTheory/GroupAction/SubMulAction/OfFixingSubgroup.lean index 206f4857e73736..43154cd87e9f22 100644 --- a/Mathlib/GroupTheory/GroupAction/SubMulAction/OfFixingSubgroup.lean +++ b/Mathlib/GroupTheory/GroupAction/SubMulAction/OfFixingSubgroup.lean @@ -221,6 +221,7 @@ theorem _root_.Set.conj_mem_fixingSubgroup (hg : g • t = s) {k : M} (hk : k rw [← Set.mem_smul_set_iff_inv_smul_mem, hg] exact hy +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem fixingSubgroup_map_conj_eq (hg : g • t = s) : (fixingSubgroup M t).map (MulAut.conj g).toMonoidHom = fixingSubgroup M s := by @@ -384,6 +385,7 @@ lemma ofFixingSubgroup_of_inclusion_injective {hst : t ⊆ s} : rw [← SetLike.coe_eq_coe] at hxy ⊢ exact hxy +set_option backward.isDefEq.respectTransparency false in variable (M) in /-- The equivariant map between `SubMulAction.ofStabilizer M a` and `ofFixingSubgroup M {a}`. -/ diff --git a/Mathlib/GroupTheory/GroupExtension/Basic.lean b/Mathlib/GroupTheory/GroupExtension/Basic.lean index df1a5fed32cf62..2a43655d815a4c 100644 --- a/Mathlib/GroupTheory/GroupExtension/Basic.lean +++ b/Mathlib/GroupTheory/GroupExtension/Basic.lean @@ -148,6 +148,7 @@ variable (s : S.Splitting) /-- `G` acts on `N` by conjugation. -/ noncomputable def conjAct : G →* MulAut N := S.conjAct.comp s +set_option backward.isDefEq.respectTransparency false in /-- A split group extension is equivalent to the extension associated to a semidirect product. -/ noncomputable def semidirectProductToGroupExtensionEquiv : (SemidirectProduct.toGroupExtension s.conjAct).Equiv S where diff --git a/Mathlib/GroupTheory/HNNExtension.lean b/Mathlib/GroupTheory/HNNExtension.lean index 181ccc15c4e004..1ee783a4c4d63c 100644 --- a/Mathlib/GroupTheory/HNNExtension.lean +++ b/Mathlib/GroupTheory/HNNExtension.lean @@ -118,6 +118,7 @@ theorem hom_ext {f g : HNNExtension G A B φ →* M} (MonoidHom.cancel_right Con.mk'_surjective).mp <| Coprod.hom_ext hg (MonoidHom.ext_mint ht) +set_option backward.isDefEq.respectTransparency false in @[elab_as_elim] theorem induction_on {motive : HNNExtension G A B φ → Prop} (x : HNNExtension G A B φ) (of : ∀ g, motive (of g)) @@ -401,6 +402,7 @@ theorem not_cancels_of_cons_hyp (u : ℤˣ) (w : NormalWord d) rw [hx] at h2 simpa using h2 (-u) rfl hw +set_option backward.isDefEq.respectTransparency false in theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) : Cancels (-u) (unitsSMul φ u w) ↔ ¬ Cancels u w := by by_cases h : Cancels u w @@ -418,12 +420,12 @@ theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) : · simp only [unitsSMul, dif_neg h] simpa [Cancels] using h -set_option backward.defeqAttrib.useBackward true in theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) : unitsSMul φ (-u) (unitsSMul φ u w) = w := by rw [unitsSMul] split_ifs with hcan - · have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan + · set_option backward.isDefEq.respectTransparency false in + have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan unfold unitsSMul simp only [dif_neg hncan] simp [unitsSMulWithCancel, unitsSMulGroup, (d.compl u).equiv_snd_eq_inv_mul, @@ -435,7 +437,7 @@ theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) : | ofGroup => simp [Cancels] at hcan2 | cons g u' w h1 h2 ih => clear ih - simp only [unitsSMulGroup, SetLike.coe_sort_coe, unitsSMulWithCancel, id_eq, consRecOn_cons, + simp only [unitsSMulGroup, SetLike.coe_sort_coe, unitsSMulWithCancel, consRecOn_cons, group_smul_head, mul_inv_rev] cases hcan2.2 @@ -492,14 +494,17 @@ theorem prod_group_smul (g : G) (w : NormalWord d) : (g • w).prod φ = of g * (w.prod φ) := by simp [ReducedWord.prod, mul_assoc] +set_option backward.isDefEq.respectTransparency false in theorem of_smul_eq_smul (g : G) (w : NormalWord d) : (of g : HNNExtension G A B φ) • w = g • w := by simp +instances [instHSMul, SMul.smul, MulAction.toEndHom] +set_option backward.isDefEq.respectTransparency false in theorem t_smul_eq_unitsSMul (w : NormalWord d) : (t : HNNExtension G A B φ) • w = unitsSMul φ 1 w := by simp +instances [instHSMul, SMul.smul, MulAction.toEndHom] +set_option backward.isDefEq.respectTransparency false in theorem t_pow_smul_eq_unitsSMul (u : ℤˣ) (w : NormalWord d) : (t ^ (u : ℤ) : HNNExtension G A B φ) • w = unitsSMul φ u w := by rcases Int.units_eq_one_or u with (rfl | rfl) <;> diff --git a/Mathlib/GroupTheory/Index.lean b/Mathlib/GroupTheory/Index.lean index b3c6fd0d028d22..9e3c08a992a7f8 100644 --- a/Mathlib/GroupTheory/Index.lean +++ b/Mathlib/GroupTheory/Index.lean @@ -531,7 +531,7 @@ theorem index_ne_zero_of_finite [hH : Finite (G ⧸ H)] : H.index ≠ 0 := by exact Nat.card_pos.ne' /-- Finite index implies finite quotient. -/ -@[to_additive (attr := implicit_reducible) /-- Finite index implies finite quotient. -/] +@[to_additive (attr := instance_reducible) /-- Finite index implies finite quotient. -/] noncomputable def fintypeOfIndexNeZero (hH : H.index ≠ 0) : Fintype (G ⧸ H) := @Fintype.ofFinite _ (Nat.finite_of_card_ne_zero hH) @@ -561,6 +561,7 @@ lemma finite_quotient_of_pretransitive_of_index_ne_zero {X : Type*} [MulAction G have := (MulAction.pretransitive_iff_subsingleton_quotient G X).1 inferInstance exact finite_quotient_of_finite_quotient_of_index_ne_zero hi +set_option backward.isDefEq.respectTransparency false in @[to_additive] lemma exists_pow_mem_of_index_ne_zero (h : H.index ≠ 0) (a : G) : ∃ n, 0 < n ∧ n ≤ H.index ∧ a ^ n ∈ H := by @@ -707,7 +708,7 @@ lemma isFiniteRelIndex_top_iff : H.IsFiniteRelIndex ⊤ ↔ H.FiniteIndex := by rw [finiteIndex_iff, isFiniteRelIndex_iff_relIndex_ne_zero, relIndex_top_right] /-- A finite index subgroup has finite quotient. -/ -@[to_additive (attr := implicit_reducible) /-- A finite index subgroup has finite quotient -/] +@[to_additive (attr := instance_reducible) /-- A finite index subgroup has finite quotient -/] noncomputable def fintypeQuotientOfFiniteIndex [FiniteIndex H] : Fintype (G ⧸ H) := fintypeOfIndexNeZero FiniteIndex.index_ne_zero @@ -843,11 +844,13 @@ variable {G H : Type*} [Group H] (h : H) -- NB: `to_additive` does not work to generate the second lemma from the first here, because it -- would need to additivize `G`, but not `H`. +set_option backward.isDefEq.respectTransparency false in lemma Subgroup.relIndex_pointwise_smul [Group G] [MulDistribMulAction H G] (J K : Subgroup G) : (h • J).relIndex (h • K) = J.relIndex K := by rw [pointwise_smul_def K, ← relIndex_comap, pointwise_smul_def, comap_map_eq_self_of_injective (by intro a b; simp)] +set_option backward.isDefEq.respectTransparency false in lemma AddSubgroup.relIndex_pointwise_smul [AddGroup G] [DistribMulAction H G] (J K : AddSubgroup G) : (h • J).relIndex (h • K) = J.relIndex K := by rw [pointwise_smul_def K, ← relIndex_comap, pointwise_smul_def, diff --git a/Mathlib/GroupTheory/MonoidLocalization/GrothendieckGroup.lean b/Mathlib/GroupTheory/MonoidLocalization/GrothendieckGroup.lean index 4fe295b7bccc1a..9cae4988c9d3ad 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/GrothendieckGroup.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/GrothendieckGroup.lean @@ -84,6 +84,7 @@ noncomputable def lift : (M →* G) ≃ (GrothendieckGroup M →* G) where left_inv f := by ext; simp right_inv f := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[to_additive] lemma lift_apply (f : M →* G) (x : GrothendieckGroup M) : lift f x = f ((monoidOf ⊤).sec x).1 / f ((monoidOf ⊤).sec x).2 := by diff --git a/Mathlib/GroupTheory/MonoidLocalization/Maps.lean b/Mathlib/GroupTheory/MonoidLocalization/Maps.lean index c0564258bd4786..12536603c78734 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Maps.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Maps.lean @@ -143,6 +143,7 @@ theorem lift_spec_mul (z w v) : f.lift hg z * w = v ↔ g (f.sec z).1 * w = g (f theorem lift_mk'_spec (x v) (y : S) : f.lift hg (f.mk' x y) = v ↔ g x = g y * v := by rw [f.lift_mk' hg]; exact mul_inv_left hg _ _ _ +set_option backward.isDefEq.respectTransparency false in /-- Given a Localization map `f : M →* N` for a Submonoid `S ⊆ M`, if a `CommMonoid` map `g : M →* P` induces a map `f.lift hg : N →* P` then for all `z : N`, we have `f.lift hg z * g y = g x`, where `x : M, y ∈ S` are such that `z * f y = f x`. -/ @@ -280,6 +281,7 @@ theorem map_eq (x) : f.map hy k (f x) = k (g x) := theorem map_comp : (f.map hy k).comp f.toMonoidHom = k.toMonoidHom.comp g := f.lift_comp fun y ↦ k.map_units ⟨g y, hy y⟩ +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem map_mk' (x) (y : S) : f.map hy k (f.mk' x y) = k.mk' (g x) ⟨g y, hy y⟩ := by rw [map, lift_mk', mul_inv_left] @@ -327,6 +329,7 @@ theorem map_mul_left (z) : k (g (f.sec z).2) * f.map hy k z = k (g (f.sec z).1) theorem map_id (z : N) : f.map (fun y ↦ show MonoidHom.id M y ∈ S from y.2) f z = z := f.lift_id z +set_option backward.isDefEq.respectTransparency false in /-- If `CommMonoid` homs `g : M →* P, l : P →* A` induce maps of localizations, the composition of the induced maps equals the map of localizations induced by `l ∘ g`. -/ @[to_additive diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index bfcad0e7520406..cc26eb161773ef 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -962,7 +962,7 @@ theorem CommGroup.nilpotencyClass_le_one {G : Type*} [CommGroup G] : /-- Groups with nilpotency class at most one are abelian. -/ @[to_additive /-- Additive groups with nilpotency class at most one are abelian. -/, - implicit_reducible] + instance_reducible] def commGroupOfNilpotencyClass [IsNilpotent G] (h : Group.nilpotencyClass G ≤ 1) : CommGroup G := Group.commGroupOfCenterEqTop <| by rw [← upperCentralSeries_one] diff --git a/Mathlib/GroupTheory/NoncommCoprod.lean b/Mathlib/GroupTheory/NoncommCoprod.lean index 164b867def0ad8..caf4e012fe070f 100644 --- a/Mathlib/GroupTheory/NoncommCoprod.lean +++ b/Mathlib/GroupTheory/NoncommCoprod.lean @@ -103,6 +103,7 @@ theorem noncommCoprod_comp_inl : (f.noncommCoprod g comm).comp (inl M N) = f := theorem noncommCoprod_comp_inr : (f.noncommCoprod g comm).comp (inr M N) = g := ext fun x => by simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem noncommCoprod_unique (f : M × N →* P) : (f.comp (inl M N)).noncommCoprod (f.comp (inr M N)) (fun _ _ => (commute_inl_inr _ _).map f) @@ -114,6 +115,7 @@ theorem noncommCoprod_inl_inr {M N : Type*} [Monoid M] [Monoid N] : (inl M N).noncommCoprod (inr M N) commute_inl_inr = id (M × N) := noncommCoprod_unique <| .id (M × N) +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem comp_noncommCoprod {Q : Type*} [Monoid Q] (h : P →* Q) : h.comp (f.noncommCoprod g comm) = diff --git a/Mathlib/GroupTheory/NoncommPiCoprod.lean b/Mathlib/GroupTheory/NoncommPiCoprod.lean index 9ad2c33927ad7e..eaefb0041e3b0b 100644 --- a/Mathlib/GroupTheory/NoncommPiCoprod.lean +++ b/Mathlib/GroupTheory/NoncommPiCoprod.lean @@ -98,6 +98,7 @@ variable (hcomm : Pairwise fun i j => ∀ x y, Commute (ϕ i x) (ϕ j y)) namespace MonoidHom +set_option backward.isDefEq.respectTransparency false in /-- The canonical homomorphism from a family of monoids. -/ @[to_additive /-- The canonical homomorphism from a family of additive monoids. See also `LinearMap.lsum` for a linear version without the commutativity assumption. -/] @@ -114,6 +115,7 @@ def noncommPiCoprod : (∀ i : ι, N i) →* M where variable {hcomm} +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem noncommPiCoprod_mulSingle [DecidableEq ι] (i : ι) (y : N i) : noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by @@ -183,6 +185,7 @@ lemma noncommPiCoprod_apply (h : (i : ι) → N i) : (Pairwise.set_pairwise (fun ⦃i j⦄ a ↦ hcomm a (h i) (h j)) _) := by dsimp only [MonoidHom.noncommPiCoprod, MonoidHom.coe_mk, OneHom.coe_mk] +set_option backward.isDefEq.respectTransparency false in /-- Given monoid morphisms `φᵢ : Nᵢ → M` and `f : M → P`, if we have sufficient commutativity, then `f ∘ (∐ᵢ φᵢ) = ∐ᵢ (f ∘ φᵢ)` -/ @@ -324,6 +327,7 @@ theorem noncommPiCoprod_mulSingle [DecidableEq ι] {hcomm : Pairwise fun i j : ι => ∀ x y : G, x ∈ H i → y ∈ H j → Commute x y} (i : ι) (y : H i) : noncommPiCoprod hcomm (Pi.mulSingle i y) = y := by apply MonoidHom.noncommPiCoprod_mulSingle +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem noncommPiCoprod_range {hcomm : Pairwise fun i j : ι => ∀ x y : G, x ∈ H i → y ∈ H j → Commute x y} : diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index 1ec66ffca4826a..7cd8b8787e1b1c 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -222,6 +222,7 @@ lemma orderOf_zero (M₀ : Type*) [MonoidWithZero M₀] [Nontrivial M₀] : orde rw [orderOf_eq_zero_iff, isOfFinOrder_iff_pow_eq_one] simp +contextual [ne_of_gt] +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem orderOf_eq_iff {n} (h : 0 < n) : orderOf x = n ↔ x ^ n = 1 ∧ ∀ m, m < n → 0 < m → x ^ m ≠ 1 := by @@ -578,6 +579,7 @@ noncomputable def finEquivPowers {x : G} (hx : IsOfFinOrder x) : Fin (orderOf x) lemma finEquivPowers_apply {x : G} (hx : IsOfFinOrder x) {n : Fin (orderOf x)} : finEquivPowers hx n = ⟨x ^ (n : ℕ), n, rfl⟩ := rfl +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma finEquivPowers_symm_apply {x : G} (hx : IsOfFinOrder x) (n : ℕ) : (finEquivPowers hx).symm ⟨x ^ n, _, rfl⟩ = ⟨n % orderOf x, Nat.mod_lt _ hx.orderOf_pos⟩ := by @@ -963,7 +965,7 @@ lemma isOfFinOrder_of_finite (x : G) : IsOfFinOrder x := by by_contra h; exact infinite_not_isOfFinOrder h <| Set.toFinite _ /-- Every finite left cancellative monoid is a group. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Every finite left cancellative additive monoid is an additive group. -/] noncomputable def LeftCancelMonoid.groupOfFinite : Group G where inv x := x ^ (orderOf x - 1) @@ -972,7 +974,7 @@ noncomputable def LeftCancelMonoid.groupOfFinite : Group G where exact (isOfFinOrder_of_finite x).orderOf_pos /-- Every finite right cancellative monoid is a group. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Every finite right cancellative additive monoid is an additive group. -/] noncomputable def RightCancelMonoid.groupOfFinite {H : Type*} [RightCancelMonoid H] [Finite H] : Group H := by diff --git a/Mathlib/GroupTheory/OreLocalization/Basic.lean b/Mathlib/GroupTheory/OreLocalization/Basic.lean index 41d9c575b2b182..3173e53231d26e 100644 --- a/Mathlib/GroupTheory/OreLocalization/Basic.lean +++ b/Mathlib/GroupTheory/OreLocalization/Basic.lean @@ -59,7 +59,7 @@ namespace OreLocalization variable {R : Type*} [Monoid R] (S : Submonoid R) [OreSet S] (X) [MulAction R X] /-- The setoid on `R × S` used for the Ore localization. -/ -@[to_additive (attr := implicit_reducible) AddOreLocalization.oreEqv +@[to_additive (attr := instance_reducible) AddOreLocalization.oreEqv /-- The setoid on `R × S` used for the Ore localization. -/] def oreEqv : Setoid (X × S) where r rs rs' := ∃ (u : S) (v : R), u • rs'.1 = v • rs.1 ∧ u * rs'.2 = v * rs.2 diff --git a/Mathlib/GroupTheory/PGroup.lean b/Mathlib/GroupTheory/PGroup.lean index 51b09b77d3f836..277134ef82a362 100644 --- a/Mathlib/GroupTheory/PGroup.lean +++ b/Mathlib/GroupTheory/PGroup.lean @@ -252,6 +252,7 @@ theorem map {H : Subgroup G} (hH : IsPGroup p H) {K : Type*} [Group K] (ϕ : G rw [← H.range_subtype, MonoidHom.map_range] exact hH.of_surjective (ϕ.restrict H).rangeRestrict (ϕ.restrict H).rangeRestrict_surjective +set_option backward.isDefEq.respectTransparency false in theorem comap_of_ker_isPGroup {H : Subgroup G} (hH : IsPGroup p H) {K : Type*} [Group K] (ϕ : K →* G) (hϕ : IsPGroup p ϕ.ker) : IsPGroup p (H.comap ϕ) := by intro g @@ -378,7 +379,7 @@ theorem isMulCommutative_of_card_eq_prime_sq (hG : Nat.card G = p ^ 2) : IsMulCo /-- A group of order `p ^ 2` is commutative. See also `IsPGroup.commutative_of_card_eq_prime_sq` for just the proof that `∀ a b, a * b = b * a` -/ -@[implicit_reducible] +@[instance_reducible] def commGroupOfCardEqPrimeSq (hG : Nat.card G = p ^ 2) : CommGroup G := let := cyclic_center_quotient_of_card_eq_prime_sq hG commGroupOfCyclicCenterQuotient _ (QuotientGroup.ker_mk' <| center G).le diff --git a/Mathlib/GroupTheory/Perm/Centralizer.lean b/Mathlib/GroupTheory/Perm/Centralizer.lean index 920a838ccbb773..0b7059a02889f2 100644 --- a/Mathlib/GroupTheory/Perm/Centralizer.lean +++ b/Mathlib/GroupTheory/Perm/Centralizer.lean @@ -128,7 +128,7 @@ lemma Subgroup.Centralizer.toConjAct_smul_mem_cycleFactorsFinset {k c : Perm α} /-- The action by conjugation of `Subgroup.centralizer {g}` on the cycles of a given permutation -/ -@[implicit_reducible] +@[instance_reducible] def Subgroup.Centralizer.cycleFactorsFinset_mulAction : MulAction (centralizer {g}) g.cycleFactorsFinset where smul k c := ⟨ConjAct.toConjAct (k : Perm α) • c.val, @@ -345,6 +345,7 @@ theorem ofPermHomFun_one (x : α) : (ofPermHomFun a 1) x = x := by · rw [ofPermHomFun_apply_of_mem_fixedPoints a _ hx] · rw [ofPermHomFun_apply_of_cycleOf_mem a _ hc hm, OneMemClass.coe_one, coe_one, id_eq, hm] +set_option backward.isDefEq.respectTransparency false in /-- Given `a : g.Basis` and a permutation of `g.cycleFactorsFinset` that preserve the lengths of the cycles, a permutation of `α` that moves the `Basis` and commutes with `g` -/ @@ -458,6 +459,7 @@ theorem range_toPermHom_eq_range_toPermHom' : ext τ rw [mem_range_toPermHom_iff, mem_range_toPermHom'_iff] +set_option backward.isDefEq.respectTransparency false in theorem nat_card_range_toPermHom : Nat.card (toPermHom g).range = ∏ n ∈ g.cycleType.toFinset, (g.cycleType.count n)! := by @@ -488,6 +490,7 @@ def kerParam : (Perm (Function.fixedPoints g)) × MonoidHom.noncommCoprod ofSubtype (Subgroup.noncommPiCoprod g.pairwise_commute_of_mem_zpowers) g.commute_ofSubtype_noncommPiCoprod +set_option backward.isDefEq.respectTransparency false in theorem kerParam_apply {u : Perm (Function.fixedPoints g)} {v : (c : g.cycleFactorsFinset) → Subgroup.zpowers c.val} {x : α} : kerParam g (u, v) x = @@ -596,6 +599,7 @@ open Function variable {a : Type*} (g : Perm α) (k : Perm (fixedPoints g)) (v : (c : g.cycleFactorsFinset) → Subgroup.zpowers (c : Perm α)) +set_option backward.isDefEq.respectTransparency false in theorem sign_kerParam_apply_apply : sign (kerParam g ⟨k, v⟩) = sign k * ∏ c, sign (v c).val := by rw [kerParam, MonoidHom.noncommCoprod_apply, ← Prod.fst_mul_snd ⟨k, v⟩, Prod.mk_mul_mk, mul_one, diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index 0cbcee57dc2738..09af6d294f6052 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -78,7 +78,7 @@ theorem SameCycle.equivalence : Equivalence (SameCycle f) := ⟨SameCycle.refl f, SameCycle.symm, SameCycle.trans⟩ /-- The setoid defined by the `SameCycle` relation. -/ -@[implicit_reducible] +@[instance_reducible] def SameCycle.setoid (f : Perm α) : Setoid α where r := f.SameCycle iseqv := SameCycle.equivalence f @@ -319,6 +319,7 @@ variable [Fintype α] theorem IsCycle.two_le_card_support (h : IsCycle f) : 2 ≤ #f.support := two_le_card_support_of_ne_one h.ne_one +set_option backward.isDefEq.respectTransparency false in /-- The subgroup generated by a cycle is in bijection with its support -/ noncomputable def IsCycle.zpowersEquivSupport {σ : Perm α} (hσ : IsCycle σ) : (Subgroup.zpowers σ) ≃ σ.support := @@ -892,6 +893,7 @@ namespace Finset variable {f : Perm α} {s : Finset α} +set_option backward.isDefEq.respectTransparency false in theorem product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) : (range #s : Set ℕ).PairwiseDisjoint fun k => s.map ⟨fun i => (i, (f ^ k) i), fun _ _ => congr_arg Prod.fst⟩ := by @@ -939,6 +941,7 @@ namespace Finset variable [Semiring α] [AddCommMonoid β] [Module α β] {s : Finset ι} {σ : Perm ι} +set_option backward.isDefEq.respectTransparency false in theorem sum_smul_sum_eq_sum_perm (hσ : σ.IsCycleOn s) (f : ι → α) (g : ι → β) : (∑ i ∈ s, f i) • ∑ i ∈ s, g i = ∑ k ∈ range #s, ∑ i ∈ s, f i • g ((σ ^ k) i) := by rw [sum_smul_sum, ← sum_product'] diff --git a/Mathlib/GroupTheory/Perm/Cycle/Concrete.lean b/Mathlib/GroupTheory/Perm/Cycle/Concrete.lean index 8cb2d346aea3a7..14a488c67598bf 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Concrete.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Concrete.lean @@ -138,6 +138,7 @@ def formPerm : ∀ s : Cycle α, Nodup s → Equiv.Perm α := theorem formPerm_coe (l : List α) (hl : l.Nodup) : formPerm (l : Cycle α) hl = l.formPerm := rfl +set_option backward.isDefEq.respectTransparency false in theorem formPerm_subsingleton (s : Cycle α) (h : Subsingleton s) : formPerm s h.nodup = 1 := by obtain ⟨s⟩ := s simp only [formPerm_coe, mk_eq_coe] @@ -159,6 +160,7 @@ theorem support_formPerm [Fintype α] (s : Cycle α) (h : Nodup s) (hn : Nontriv rintro _ rfl simpa [Nat.succ_le_succ_iff] using length_nontrivial hn +set_option backward.isDefEq.respectTransparency.types false in theorem formPerm_eq_self_of_notMem (s : Cycle α) (h : Nodup s) (x : α) (hx : x ∉ s) : formPerm s h x = x := by induction s using Quot.inductionOn @@ -169,11 +171,13 @@ theorem formPerm_apply_mem_eq_next (s : Cycle α) (h : Nodup s) (x : α) (hx : x induction s using Quot.inductionOn simpa using! List.formPerm_apply_mem_eq_next h _ (by simp_all) +set_option backward.isDefEq.respectTransparency.types false in nonrec theorem formPerm_reverse (s : Cycle α) (h : Nodup s) : formPerm s.reverse (nodup_reverse_iff.mpr h) = (formPerm s h)⁻¹ := by induction s using Quot.inductionOn simpa using formPerm_reverse _ +set_option backward.isDefEq.respectTransparency.types false in nonrec theorem formPerm_eq_formPerm_iff {α : Type*} [DecidableEq α] {s s' : Cycle α} {hs : s.Nodup} {hs' : s'.Nodup} : s.formPerm hs = s'.formPerm hs' ↔ s = s' ∨ s.Subsingleton ∧ s'.Subsingleton := by @@ -360,6 +364,7 @@ def toCycle (f : Perm α) (hf : IsCycle f) : Cycle α := have hc : SameCycle f x y := IsCycle.sameCycle hf hx hy exact Quotient.sound' hc.toList_isRotated) +set_option backward.isDefEq.respectTransparency false in theorem toCycle_eq_toList (f : Perm α) (hf : IsCycle f) (x : α) (hx : f x ≠ x) : toCycle f hf = toList f x := by have key : (Finset.univ : Finset α).val = x ::ₘ Finset.univ.val.erase x := by simp @@ -397,6 +402,7 @@ theorem toCycle_next (f : Perm α) (hf : f.IsCycle) (hx : x ∈ toCycle f hf) : simp only [hl, Cycle.mem_coe_iff] at ⊢ hx exact Equiv.Perm.next_toList_eq_apply f l x hx +set_option backward.isDefEq.respectTransparency false in /-- Any cyclic `f : Perm α` is isomorphic to the nontrivial `Cycle α` that corresponds to repeated application of `f`. The forward direction is implemented by `Equiv.Perm.toCycle`. @@ -431,6 +437,7 @@ section Finite variable [Finite α] [DecidableEq α] +set_option backward.isDefEq.respectTransparency false in theorem IsCycle.existsUnique_cycle {f : Perm α} (hf : IsCycle f) : ∃! s : Cycle α, ∃ h : s.Nodup, s.formPerm h = f := by cases nonempty_fintype α diff --git a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean index e03ab1b5aacc3b..b287f6a5a5067e 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean @@ -483,6 +483,7 @@ def cycleFactorsFinset : Finset (Perm α) := list_cycles_perm_list_cycles (hl'.left.symm ▸ hl.left) hl.right.left hl'.right.left hl.right.right hl'.right.right +set_option backward.isDefEq.respectTransparency false in open scoped List in theorem cycleFactorsFinset_eq_list_toFinset {σ : Perm α} {l : List (Perm α)} (hn : l.Nodup) : σ.cycleFactorsFinset = l.toFinset ↔ @@ -505,6 +506,7 @@ theorem cycleFactorsFinset_eq_list_toFinset {σ : Perm α} {l : List (Perm α)} refine list_cycles_perm_list_cycles ?_ hc' hc hd' hd rw [hp, hp'] +set_option backward.isDefEq.respectTransparency false in theorem cycleFactorsFinset_eq_finset {σ : Perm α} {s : Finset (Perm α)} : σ.cycleFactorsFinset = s ↔ (∀ f : Perm α, f ∈ s → f.IsCycle) ∧ @@ -623,6 +625,7 @@ theorem mem_support_iff_mem_support_of_mem_cycleFactorsFinset {g : Equiv.Perm α · rintro ⟨c, hc, hx⟩ exact mem_cycleFactorsFinset_support_le hc hx +set_option backward.isDefEq.respectTransparency.types false in theorem cycleFactorsFinset_eq_empty_iff {f : Perm α} : cycleFactorsFinset f = ∅ ↔ f = 1 := by simpa [cycleFactorsFinset_eq_finset] using eq_comm diff --git a/Mathlib/GroupTheory/Perm/Cycle/Type.lean b/Mathlib/GroupTheory/Perm/Cycle/Type.lean index a86e7903c97fe1..bceb5e928f1b22 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Type.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Type.lean @@ -66,6 +66,7 @@ theorem cycleType_eq' {σ : Perm α} (s : Finset (Perm α)) (h1 : ∀ f : Perm rw [cycleFactorsFinset_eq_finset] exact ⟨h1, h2, h0⟩ +set_option backward.isDefEq.respectTransparency false in theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ) (h1 : ∀ σ : Perm α, σ ∈ l → σ.IsCycle) (h2 : l.Pairwise Disjoint) : σ.cycleType = l.map (Finset.card ∘ support) := by @@ -76,6 +77,7 @@ theorem cycleType_eq {σ : Perm α} (l : List (Perm α)) (h0 : l.prod = σ) · simpa [hl] using h2 · simp [hl, h0] +set_option backward.isDefEq.respectTransparency false in theorem CycleType.count_def {σ : Perm α} (n : ℕ) : σ.cycleType.count n = Fintype.card {c : σ.cycleFactorsFinset // #(c : Perm α).support = n } := by @@ -368,6 +370,7 @@ theorem card_compl_support_modEq [DecidableEq α] {p n : ℕ} [hp : Fact p.Prime exact dvd_pow_self _ fun h => (one_lt_of_mem_cycleType hk).ne <| by rw [h, pow_zero] · exact Finset.card_le_univ _ +set_option backward.isDefEq.respectTransparency false in open Function in /-- The number of fixed points of a `p ^ n`-th root of the identity function over a finite set and the set's cardinality have the same residue modulo `p`, where `p` is a prime. -/ diff --git a/Mathlib/GroupTheory/Perm/Fin.lean b/Mathlib/GroupTheory/Perm/Fin.lean index e13b1af86ec985..229799f3cb3b4a 100644 --- a/Mathlib/GroupTheory/Perm/Fin.lean +++ b/Mathlib/GroupTheory/Perm/Fin.lean @@ -218,6 +218,7 @@ theorem cycleRange_mk_zero (h : 0 < n) : cycleRange ⟨0, h⟩ = 1 := have : NeZero n := .of_pos h cycleRange_zero n +set_option backward.isDefEq.respectTransparency false in @[simp] theorem sign_cycleRange (i : Fin n) : Perm.sign (cycleRange i) = (-1) ^ (i : ℕ) := by simp [cycleRange] @@ -288,6 +289,7 @@ theorem isCycle_cycleRange [NeZero n] (h0 : i ≠ 0) : IsCycle (cycleRange i) := · exact (h0 rfl).elim exact isCycle_finRotate.extendDomain _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem cycleType_cycleRange [NeZero n] (h0 : i ≠ 0) : cycleType (cycleRange i) = {(i + 1 : ℕ)} := by diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index 70b4e3369386a4..c2a32f6f2de91c 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -114,6 +114,7 @@ theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : obtain ⟨y, hy⟩ := h ⟨r, rfl⟩ grind +set_option backward.isDefEq.respectTransparency.types false in theorem mem_sumCongrHom_range_of_perm_mapsTo_inl {m n : Type*} [Finite m] [Finite n] {σ : Perm (m ⊕ n)} (h : Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl)) : σ ∈ (sumCongrHom m n).range := by @@ -155,6 +156,7 @@ theorem Disjoint.extendDomain {p : β → Prop} [DecidablePred p] (f : α ≃ Su · left rw [extendDomain_apply_not_subtype _ _ pb] +set_option backward.isDefEq.respectTransparency false in theorem Disjoint.isConj_mul [Finite α] {σ τ π ρ : Perm α} (hc1 : IsConj σ π) (hc2 : IsConj τ ρ) (hd1 : Disjoint σ τ) (hd2 : Disjoint π ρ) : IsConj (σ * τ) (π * ρ) := by classical diff --git a/Mathlib/GroupTheory/Perm/Sign.lean b/Mathlib/GroupTheory/Perm/Sign.lean index b2c418962507f7..59fb103146af17 100644 --- a/Mathlib/GroupTheory/Perm/Sign.lean +++ b/Mathlib/GroupTheory/Perm/Sign.lean @@ -44,7 +44,7 @@ namespace Equiv.Perm We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition sums up to `0`. -/ -@[implicit_reducible] +@[instance_reducible] def modSwap (i j : α) : Setoid (Perm α) := ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h => Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]), @@ -274,7 +274,7 @@ theorem signAux_swap : ∀ {n : ℕ} {x y : Fin n} (_hxy : x ≠ y), signAux (sw | 0, x, y => by intro; exact Fin.elim0 x | 1, x, y => by dsimp [signAux, swap, swapCore] - simp only [eq_iff_true_of_subsingleton, not_true, ite_true, le_refl, prod_const, + simp only [eq_iff_true_of_subsingleton, not_true, IsEmpty.forall_iff] | n + 2, x, y => fun hxy => by have h2n : 2 ≤ n + 2 := by exact le_add_self @@ -288,6 +288,7 @@ def signAux2 : List α → Perm α → ℤˣ | [], _ => 1 | x::l, f => if x = f x then signAux2 l f else -signAux2 l (swap x (f x) * f) +set_option backward.isDefEq.respectTransparency false in theorem signAux_eq_signAux2 {n : ℕ} : ∀ (l : List α) (f : Perm α) (e : α ≃ Fin n) (_h : ∀ x, f x ≠ x → x ∈ l), signAux ((e.symm.trans f).trans e) = signAux2 l f diff --git a/Mathlib/GroupTheory/Perm/Support.lean b/Mathlib/GroupTheory/Perm/Support.lean index e7734d72ea1103..66877efaa0306f 100644 --- a/Mathlib/GroupTheory/Perm/Support.lean +++ b/Mathlib/GroupTheory/Perm/Support.lean @@ -576,6 +576,7 @@ theorem card_support_swap_mul {f : Perm α} {x : α} (hx : f x ≠ x) : ⟨fun _ hz => (mem_support_swap_mul_imp_mem_support_ne hz).left, fun h => absurd (h (mem_support.2 hx)) (mt mem_support.1 (by simp))⟩ +set_option backward.isDefEq.respectTransparency false in theorem card_support_swap {x y : α} (hxy : x ≠ y) : #(swap x y).support = 2 := show #(swap x y).support = #⟨x ::ₘ y ::ₘ 0, by simp [hxy]⟩ from congr_arg card <| by simp [support_swap hxy, *, Finset.ext_iff] diff --git a/Mathlib/GroupTheory/PushoutI.lean b/Mathlib/GroupTheory/PushoutI.lean index 94331661c9031f..b9ba651e047e3b 100644 --- a/Mathlib/GroupTheory/PushoutI.lean +++ b/Mathlib/GroupTheory/PushoutI.lean @@ -330,6 +330,7 @@ theorem prod_cons {i} (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i) variable [DecidableEq ι] [∀ i, DecidableEq (G i)] +set_option backward.isDefEq.respectTransparency.types false in /-- Given a word in `CoprodI`, if every letter is in the transversal and when we multiply by an element of the base group it still has this property, then the element of the base group we multiplied by was one. -/ @@ -453,6 +454,7 @@ theorem summand_smul_def' {i : ι} (g : G i) (w : NormalWord d) : { equivPair i w with head := g * (equivPair i w).head } := rfl +set_option backward.isDefEq.respectTransparency false in noncomputable instance mulAction : MulAction (PushoutI φ) (NormalWord d) := MulAction.ofEndHom <| lift @@ -517,6 +519,7 @@ noncomputable def consRecOn {motive : NormalWord d → Sort _} (w : NormalWord d (h3 _ _ List.mem_cons_self)] +set_option backward.isDefEq.respectTransparency false in theorem cons_eq_smul {i : ι} (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i) (hgr : g ∉ (φ i).range) : cons g w hmw hgr = of (φ := φ) i g • w := by diff --git a/Mathlib/GroupTheory/QuotientGroup/Basic.lean b/Mathlib/GroupTheory/QuotientGroup/Basic.lean index 8e12e066332e75..c55fca990497cf 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Basic.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Basic.lean @@ -319,6 +319,7 @@ instance map_normal : (M.map (QuotientGroup.mk' N)).Normal := variable (h : N ≤ M) +set_option backward.isDefEq.respectTransparency false in /-- The map from the third isomorphism theorem for groups: `(G / N) / (M / N) → G / M`. -/ @[to_additive /-- The map from the third isomorphism theorem for additive groups: `(A / N) / (M / N) → A / M`. -/] @@ -339,6 +340,7 @@ theorem quotientQuotientEquivQuotientAux_mk_mk (x : G) : quotientQuotientEquivQuotientAux N M h (x : G ⧸ N) = x := QuotientGroup.lift_mk' (M.map (mk' N)) _ x +set_option backward.isDefEq.respectTransparency false in /-- **Noether's third isomorphism theorem** for groups: `(G / N) / (M / N) ≃* G / M`. -/ @[to_additive /-- **Noether's third isomorphism theorem** for additive groups: `(A / N) / (M / N) ≃+ A / M`. -/] diff --git a/Mathlib/GroupTheory/QuotientGroup/Finite.lean b/Mathlib/GroupTheory/QuotientGroup/Finite.lean index 0b1c080b3cbfd0..2289fe7e0bcb28 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Finite.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Finite.lean @@ -27,7 +27,7 @@ namespace Group open scoped Classical in /-- If `F` and `H` are finite such that `ker(G →* H) ≤ im(F →* G)`, then `G` is finite. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If `F` and `H` are finite such that `ker(G →+ H) ≤ im(F →+ G)`, then `G` is finite. -/] noncomputable def fintypeOfKerLeRange (h : g.ker ≤ f.range) : Fintype G := @Fintype.ofEquiv _ _ @@ -36,20 +36,20 @@ noncomputable def fintypeOfKerLeRange (h : g.ker ≤ f.range) : Fintype G := groupEquivQuotientProdSubgroup.symm /-- If `F` and `H` are finite such that `ker(G →* H) = im(F →* G)`, then `G` is finite. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If `F` and `H` are finite such that `ker(G →+ H) = im(F →+ G)`, then `G` is finite. -/] noncomputable def fintypeOfKerEqRange (h : g.ker = f.range) : Fintype G := fintypeOfKerLeRange _ _ h.le /-- If `ker(G →* H)` and `H` are finite, then `G` is finite. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If `ker(G →+ H)` and `H` are finite, then `G` is finite. -/] noncomputable def fintypeOfKerOfCodom [Fintype g.ker] : Fintype G := fintypeOfKerLeRange ((topEquiv : _ ≃* G).toMonoidHom.comp <| inclusion le_top) g fun x hx => ⟨⟨x, hx⟩, rfl⟩ /-- If `F` and `coker(F →* G)` are finite, then `G` is finite. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- If `F` and `coker(F →+ G)` are finite, then `G` is finite. -/] noncomputable def fintypeOfDomOfCoker [Normal f.range] [Fintype <| G ⧸ f.range] : Fintype G := fintypeOfKerLeRange _ (mk' f.range) fun x => (eq_one_iff x).mp diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean index f140de24f68cb0..8f5784f13cef81 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/MaximalSubgroups.lean @@ -268,6 +268,8 @@ theorem isCoatom_stabilizer_of_ncard_lt_ncard_compl {s : Set α} hB.subsingleton_of_stabilizer_lt_of_subset hB_not_le_sc hG hBs -- Step 4 : sᶜ ⊆ B : A block which is not a subsingleton contains `sᶜ`. suffices IsMultiplyPretransitive (↥(alternatingGroup α)) α (s.ncard + 1) by + have : ¬ B ⊆ s := fun h ↦ hB' (hB_not_le_s B hB h) + have : ¬ B ⊆ sᶜ := fun h ↦ hB' (hB_not_le_sc B hB h) apply hB.compl_subset_of_stabilizer_le_of_not_subset_of_not_subset_compl hG.le <;> grind have := isMultiplyPretransitive α diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean index 47abda9765ffbc..1970ffeef55f6f 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean @@ -67,6 +67,7 @@ namespace Equiv.Perm variable {α : Type*} [Finite α] [DecidableEq α] +set_option backward.isDefEq.respectTransparency.types false in /-- The Iwasawa structure of `Perm α` acting on `Set.powersetCard α 2`. -/ def iwasawaStructure_two [∀ s : Set α, DecidablePred fun x ↦ x ∈ s] : IwasawaStructure (Perm α) (Set.powersetCard α 2) where diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean index 7b47b759d095d4..866caf78318751 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean @@ -204,7 +204,7 @@ theorem commutative_of_cyclic_center_quotient [IsCyclic G'] (f : G →* G') (hf f.isMulCommutative_of_isCyclic_of_ker_le_center hf |>.is_comm.comm a b /-- A group is commutative if the quotient by the center is cyclic. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- A group is commutative if the quotient by the center is cyclic. -/] def commGroupOfCyclicCenterQuotient [IsCyclic G'] (f : G →* G') (hf : f.ker ≤ center G) : CommGroup G where @@ -305,6 +305,7 @@ lemma LinearOrderedAddCommGroup.isAddCyclic_iff_nonempty_equiv_int {A : Type*} map_add' := add_zsmul g map_le_map_iff' := zsmul_le_zsmul_iff_left hg' }⟩ +set_option backward.isDefEq.respectTransparency false in /-- A linearly-ordered abelian group is cyclic iff it is isomorphic to `Multiplicative ℤ` as an ordered monoid. -/ lemma LinearOrderedCommGroup.isCyclic_iff_nonempty_equiv_int {G : Type*} @@ -579,6 +580,9 @@ abbrev intCyclicAddEquiv [AddGroup G] [IsAddCyclic G] : ℤ ≃+ G := end Infinite +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in variable (G) in /-- The automorphism group of a cyclic group is isomorphic to the multiplicative group of ZMod. -/ @[simps!] diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean index 77641c60d15f4b..9013dc590bd249 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic/Basic.lean @@ -85,7 +85,7 @@ alias IsCyclic.commutative := IsCyclic.isMulCommutative open scoped IsMulCommutative in /-- A cyclic group is always commutative. This is not an `instance` because often we have a better proof of `CommGroup`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- A cyclic group is always commutative. This is not an `instance` because often we have a better proof of `AddCommGroup`. -/] def IsCyclic.commGroup [Group α] [IsCyclic α] : CommGroup α := diff --git a/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean b/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean index abea98a604b6d9..eaf024520c0f1c 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean @@ -250,6 +250,7 @@ instance : IsKleinFour (DihedralGroup 2) where card_four := DihedralGroup.nat_card exponent_two := DihedralGroup.exponent +set_option backward.isDefEq.respectTransparency false in /-- If n is odd, then the Dihedral group of order $2n$ has $n(n+3)$ pairs (represented as $n + n + n + n*n$) of commuting elements. -/ @[simps] diff --git a/Mathlib/GroupTheory/Subgroup/Center.lean b/Mathlib/GroupTheory/Subgroup/Center.lean index c6451bbeeb125f..07054d4d5c66a7 100644 --- a/Mathlib/GroupTheory/Subgroup/Center.lean +++ b/Mathlib/GroupTheory/Subgroup/Center.lean @@ -88,7 +88,7 @@ theorem center_eq_top [hG : IsMulCommutative G] : center G = ⊤ := /-- A group is commutative if the center is the whole group. -/ @[to_additive /-- An additive group is commutative if the center is the whole group. -/, - implicit_reducible] + instance_reducible] def _root_.Group.commGroupOfCenterEqTop (h : center G = ⊤) : CommGroup G := { ‹Group G› with mul_comm := by @@ -138,6 +138,7 @@ end IsConj namespace ConjClasses +set_option backward.isDefEq.respectTransparency false in theorem mk_bijOn (G : Type*) [Group G] : Set.BijOn ConjClasses.mk (↑(Subgroup.center G)) (noncenter G)ᶜ := by refine ⟨fun g hg ↦ ?_, fun x hx y _ H ↦ ?_, ?_⟩ diff --git a/Mathlib/GroupTheory/Submonoid/Inverses.lean b/Mathlib/GroupTheory/Submonoid/Inverses.lean index d4efa62017f0eb..357273496080f5 100644 --- a/Mathlib/GroupTheory/Submonoid/Inverses.lean +++ b/Mathlib/GroupTheory/Submonoid/Inverses.lean @@ -140,6 +140,7 @@ noncomputable def fromCommLeftInv : S.leftInv →* S where variable (hS : S ≤ IsUnit.submonoid M) +set_option backward.isDefEq.respectTransparency false in /-- The submonoid of pointwise inverse of `S` is `MulEquiv` to `S`. -/ @[to_additive (attr := simps apply) /-- The additive submonoid of pointwise additive inverse of `S` is `AddEquiv` to `S`. -/] diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index 4e16dfabe87cf3..65c85703ec4f78 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -494,6 +494,7 @@ theorem mapSurjective_surjective (p : ℕ) [Fact p.Prime] : end mapSurjective +set_option backward.isDefEq.respectTransparency false in /-- **Frattini's Argument**: If `N` is a normal subgroup of `G`, and if `P` is a Sylow `p`-subgroup of `N`, then `N_G(P) ⊔ N = G`. -/ theorem normalizer_sup_eq_top {p : ℕ} [Fact p.Prime] {N : Subgroup G} [N.Normal] @@ -750,7 +751,7 @@ theorem _root_.Group.card_dvd_prod_orderOf [Fintype G] : Nat.card G ∣ ∏ g : simp [Finset.card_sdiff, ← Nat.card_eq_fintype_card, hH] /-- If `G` has a normal Sylow `p`-subgroup, then it is the only Sylow `p`-subgroup. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def unique_of_normal {p : ℕ} [Fact p.Prime] [Finite (Sylow p G)] (P : Sylow p G) (h : P.Normal) : Unique (Sylow p G) := by refine { uniq := fun Q ↦ ?_ } diff --git a/Mathlib/GroupTheory/Torsion.lean b/Mathlib/GroupTheory/Torsion.lean index e40d032a5c857b..e8bb7939eff18f 100644 --- a/Mathlib/GroupTheory/Torsion.lean +++ b/Mathlib/GroupTheory/Torsion.lean @@ -67,7 +67,7 @@ end Monoid open Monoid /-- Torsion monoids are really groups. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Torsion additive monoids are really additive groups -/] noncomputable def IsTorsion.group [Monoid G] (tG : IsTorsion G) : Group G := { ‹Monoid G› with @@ -195,6 +195,7 @@ lemma torsion_prod : torsion (G × H) = (torsion G).prod (torsion H) := by variable {G} +set_option backward.isDefEq.respectTransparency false in /-- Torsion submonoids are torsion. -/ @[to_additive /-- Additive torsion submonoids are additively torsion. -/] theorem torsion.isTorsion : IsTorsion <| torsion G := fun ⟨x, n, npos, hn⟩ ↦ diff --git a/Mathlib/Lean/PrettyPrinter/Delaborator.lean b/Mathlib/Lean/PrettyPrinter/Delaborator.lean index 3468bd5eb3d0ab..dc24edb67b1598 100644 --- a/Mathlib/Lean/PrettyPrinter/Delaborator.lean +++ b/Mathlib/Lean/PrettyPrinter/Delaborator.lean @@ -16,7 +16,7 @@ public import Lean.PrettyPrinter.Delaborator.Basic namespace Lean.PrettyPrinter.Delaborator -open SubExpr +open Delaborator.SubExpr /-- Assuming the current expression in a lambda or pi, descend into the body using an unused name generated from the binder's name. diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean index 5c600a01296781..ecfbea3c309f8f 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean @@ -136,6 +136,7 @@ theorem toEquiv_inj {e e' : P₁ ≃ᵃ[k] P₂} : e.toEquiv = e'.toEquiv ↔ e theorem coe_mk (e : P₁ ≃ P₂) (e' : V₁ ≃ₗ[k] V₂) (h) : ((⟨e, e', h⟩ : P₁ ≃ᵃ[k] P₂) : P₁ → P₂) = e := rfl +set_option backward.isDefEq.respectTransparency false in /-- Construct an affine equivalence by verifying the relation between the map and its linear part at one base point. Namely, this function takes a map `e : P₁ → P₂`, a linear equivalence `e' : V₁ ≃ₗ[k] V₂`, and a point `p` such that for any other point `p'` we have @@ -309,6 +310,7 @@ theorem self_trans_symm (e : P₁ ≃ᵃ[k] P₂) : e.trans e.symm = refl k P₁ theorem symm_trans_self (e : P₁ ≃ᵃ[k] P₂) : e.symm.trans e = refl k P₂ := ext e.apply_symm_apply +set_option backward.isDefEq.respectTransparency false in @[simp] theorem apply_lineMap (e : P₁ ≃ᵃ[k] P₂) (a b : P₁) (c : k) : e (AffineMap.lineMap a b c) = AffineMap.lineMap (e a) (e b) c := @@ -653,6 +655,7 @@ section arrowCongrₗ variable (e₁ : P₁ ≃ᵃ[R] P₂) (e₂ : V₃ ≃ₗ[R] V₄) +set_option backward.isDefEq.respectTransparency false in /-- An affine isomorphism between the domains and a linear isomorphism between the codomains of two spaces of affine maps give a linear isomorphism between the two function spaces. @@ -747,18 +750,22 @@ namespace AffineMap open AffineEquiv +set_option backward.isDefEq.respectTransparency false in theorem lineMap_vadd (v v' : V₁) (p : P₁) (c : k) : lineMap v v' c +ᵥ p = lineMap (v +ᵥ p) (v' +ᵥ p) c := (vaddConst k p).apply_lineMap v v' c +set_option backward.isDefEq.respectTransparency false in theorem lineMap_vsub (p₁ p₂ p₃ : P₁) (c : k) : lineMap p₁ p₂ c -ᵥ p₃ = lineMap (p₁ -ᵥ p₃) (p₂ -ᵥ p₃) c := (vaddConst k p₃).symm.apply_lineMap p₁ p₂ c +set_option backward.isDefEq.respectTransparency false in theorem vsub_lineMap (p₁ p₂ p₃ : P₁) (c : k) : p₁ -ᵥ lineMap p₂ p₃ c = lineMap (p₁ -ᵥ p₂) (p₁ -ᵥ p₃) c := (constVSub k p₁).apply_lineMap p₂ p₃ c +set_option backward.isDefEq.respectTransparency false in theorem vadd_lineMap (v : V₁) (p₁ p₂ : P₁) (c : k) : v +ᵥ lineMap p₁ p₂ c = lineMap (v +ᵥ p₁) (v +ᵥ p₂) c := (constVAdd k P₁ v).apply_lineMap p₁ p₂ c diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean index 1c0f189998dbf7..47b64b7e55ad81 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean @@ -482,24 +482,31 @@ theorem prodMap_apply (f : P1 →ᵃ[k] P2) (g : P3 →ᵃ[k] P4) (x) : f.prodMa def lineMap (p₀ p₁ : P1) : k →ᵃ[k] P1 := ((LinearMap.id : k →ₗ[k] k).smulRight (p₁ -ᵥ p₀)).toAffineMap +ᵥ const k k p₀ +set_option backward.isDefEq.respectTransparency false in theorem coe_lineMap (p₀ p₁ : P1) : (lineMap p₀ p₁ : k → P1) = fun c => c • (p₁ -ᵥ p₀) +ᵥ p₀ := rfl +set_option backward.isDefEq.respectTransparency false in theorem lineMap_apply (p₀ p₁ : P1) (c : k) : lineMap p₀ p₁ c = c • (p₁ -ᵥ p₀) +ᵥ p₀ := rfl +set_option backward.isDefEq.respectTransparency false in theorem lineMap_apply_module' (p₀ p₁ : V1) (c : k) : lineMap p₀ p₁ c = c • (p₁ - p₀) + p₀ := rfl +set_option backward.isDefEq.respectTransparency false in theorem lineMap_apply_module (p₀ p₁ : V1) (c : k) : lineMap p₀ p₁ c = (1 - c) • p₀ + c • p₁ := by simp [lineMap_apply_module', smul_sub, sub_smul]; abel +set_option backward.isDefEq.respectTransparency false in theorem lineMap_apply_ring' (a b c : k) : lineMap a b c = c * (b - a) + a := rfl +set_option backward.isDefEq.respectTransparency false in theorem lineMap_apply_ring (a b c : k) : lineMap a b c = (1 - c) * a + c * b := lineMap_apply_module a b c +set_option backward.isDefEq.respectTransparency false in theorem lineMap_vadd_apply (p : P1) (v : V1) (c : k) : lineMap p (v +ᵥ p) c = c • v +ᵥ p := by rw [lineMap_apply, vadd_vsub] @@ -508,6 +515,7 @@ theorem lineMap_linear (p₀ p₁ : P1) : (lineMap p₀ p₁ : k →ᵃ[k] P1).linear = LinearMap.id.smulRight (p₁ -ᵥ p₀) := add_zero _ +set_option backward.isDefEq.respectTransparency false in theorem lineMap_same_apply (p : P1) (c : k) : lineMap p p c = p := by simp [lineMap_apply] @@ -515,35 +523,42 @@ theorem lineMap_same_apply (p : P1) (c : k) : lineMap p p c = p := by theorem lineMap_same (p : P1) : lineMap p p = const k k p := ext <| lineMap_same_apply p +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_apply_zero (p₀ p₁ : P1) : lineMap p₀ p₁ (0 : k) = p₀ := by simp [lineMap_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_apply_one (p₀ p₁ : P1) : lineMap p₀ p₁ (1 : k) = p₁ := by simp [lineMap_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_eq_lineMap_iff [IsDomain k] [IsTorsionFree k V1] {p₀ p₁ : P1} {c₁ c₂ : k} : lineMap p₀ p₁ c₁ = lineMap p₀ p₁ c₂ ↔ p₀ = p₁ ∨ c₁ = c₂ := by rw [lineMap_apply, lineMap_apply, ← @vsub_eq_zero_iff_eq V1, vadd_vsub_vadd_cancel_right, ← sub_smul, smul_eq_zero, sub_eq_zero, vsub_eq_zero_iff_eq, or_comm, eq_comm] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_eq_left_iff [IsDomain k] [IsTorsionFree k V1] {p₀ p₁ : P1} {c : k} : lineMap p₀ p₁ c = p₀ ↔ p₀ = p₁ ∨ c = 0 := by rw [← @lineMap_eq_lineMap_iff k V1, lineMap_apply_zero] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_eq_right_iff [IsDomain k] [IsTorsionFree k V1] {p₀ p₁ : P1} {c : k} : lineMap p₀ p₁ c = p₁ ↔ p₀ = p₁ ∨ c = 1 := by rw [← @lineMap_eq_lineMap_iff k V1, lineMap_apply_one] +set_option backward.isDefEq.respectTransparency false in variable (k) in theorem lineMap_injective [IsDomain k] [IsTorsionFree k V1] {p₀ p₁ : P1} (h : p₀ ≠ p₁) : Function.Injective (lineMap p₀ p₁ : k → P1) := fun _c₁ _c₂ hc => (lineMap_eq_lineMap_iff.mp hc).resolve_left h +set_option backward.isDefEq.respectTransparency false in @[simp] theorem apply_lineMap (f : P1 →ᵃ[k] P2) (p₀ p₁ : P1) (c : k) : f (lineMap p₀ p₁ c) = lineMap (f p₀) (f p₁) c := by @@ -554,10 +569,12 @@ theorem comp_lineMap (f : P1 →ᵃ[k] P2) (p₀ p₁ : P1) : f.comp (lineMap p₀ p₁) = lineMap (f p₀) (f p₁) := ext <| f.apply_lineMap p₀ p₁ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem fst_lineMap (p₀ p₁ : P1 × P2) (c : k) : (lineMap p₀ p₁ c).1 = lineMap p₀.1 p₁.1 c := fst.apply_lineMap p₀ p₁ c +set_option backward.isDefEq.respectTransparency false in @[simp] theorem snd_lineMap (p₀ p₁ : P1 × P2) (c : k) : (lineMap p₀ p₁ c).2 = lineMap p₀.2 p₁.2 c := snd.apply_lineMap p₀ p₁ c @@ -566,39 +583,48 @@ theorem lineMap_symm (p₀ p₁ : P1) : lineMap p₀ p₁ = (lineMap p₁ p₀).comp (lineMap (1 : k) (0 : k)) := by simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_apply_one_sub (p₀ p₁ : P1) (c : k) : lineMap p₀ p₁ (1 - c) = lineMap p₁ p₀ c := by rw [lineMap_symm p₀, comp_apply] congr simp [lineMap_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_vsub_left (p₀ p₁ : P1) (c : k) : lineMap p₀ p₁ c -ᵥ p₀ = c • (p₁ -ᵥ p₀) := vadd_vsub _ _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem left_vsub_lineMap (p₀ p₁ : P1) (c : k) : p₀ -ᵥ lineMap p₀ p₁ c = c • (p₀ -ᵥ p₁) := by rw [← neg_vsub_eq_vsub_rev, lineMap_vsub_left, ← smul_neg, neg_vsub_eq_vsub_rev] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lineMap_vsub_right (p₀ p₁ : P1) (c : k) : lineMap p₀ p₁ c -ᵥ p₁ = (1 - c) • (p₀ -ᵥ p₁) := by rw [← lineMap_apply_one_sub, lineMap_vsub_left] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem right_vsub_lineMap (p₀ p₁ : P1) (c : k) : p₁ -ᵥ lineMap p₀ p₁ c = (1 - c) • (p₁ -ᵥ p₀) := by rw [← lineMap_apply_one_sub, left_vsub_lineMap] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_vadd_lineMap (v₁ v₂ : V1) (p₁ p₂ : P1) (c : k) : lineMap v₁ v₂ c +ᵥ lineMap p₁ p₂ c = lineMap (v₁ +ᵥ p₁) (v₂ +ᵥ p₂) c := ((fst : V1 × P1 →ᵃ[k] V1) +ᵥ (snd : V1 × P1 →ᵃ[k] P1)).apply_lineMap (v₁, p₁) (v₂, p₂) c +set_option backward.isDefEq.respectTransparency false in theorem lineMap_vsub_lineMap (p₁ p₂ p₃ p₄ : P1) (c : k) : lineMap p₁ p₂ c -ᵥ lineMap p₃ p₄ c = lineMap (p₁ -ᵥ p₃) (p₂ -ᵥ p₄) c := ((fst : P1 × P1 →ᵃ[k] P1) -ᵥ (snd : P1 × P1 →ᵃ[k] P1)).apply_lineMap (_, _) (_, _) c +set_option backward.isDefEq.respectTransparency false in @[simp] lemma lineMap_lineMap_right (p₀ p₁ : P1) (c d : k) : lineMap p₀ (lineMap p₀ p₁ c) d = lineMap p₀ p₁ (d * c) := by simp [lineMap_apply, mul_smul] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma lineMap_lineMap_left (p₀ p₁ : P1) (c d : k) : lineMap (lineMap p₀ p₁ c) p₁ d = lineMap p₀ p₁ (1 - (1 - d) * (1 - c)) := by simp_rw [lineMap_apply_one_sub, ← lineMap_apply_one_sub p₁, lineMap_lineMap_right] @@ -664,6 +690,7 @@ theorem proj_apply (i : ι) (f : ∀ i, P i) : @proj k _ ι V P _ _ _ i f = f i theorem proj_linear (i : ι) : (@proj k _ ι V P _ _ _ i).linear = @LinearMap.proj k ι _ V _ _ i := rfl +set_option backward.isDefEq.respectTransparency false in theorem pi_lineMap_apply (f g : ∀ i, P i) (c : k) (i : ι) : lineMap f g c i = lineMap (f i) (g i) c := (proj i : (∀ i, P i) →ᵃ[k] P i).apply_lineMap f g c @@ -725,6 +752,7 @@ def toConstProdLinearMap : (V1 →ᵃ[k] V2) ≃ₗ[R] V2 × (V1 →ₗ[k] V2) w end Module +set_option backward.isDefEq.respectTransparency false in /-- Interpolating between affine maps with `lineMap` commutes with evaluation. -/ @[simp] lemma lineMap_apply' [SMulCommClass k k V2] (f g : P1 →ᵃ[k] P2) (c : k) @@ -835,6 +863,7 @@ theorem homothety_apply (c : P1) (r : k) (p : P1) : homothety c r p = r • (p - theorem homothety_linear (c : P1) (r : k) : (homothety c r).linear = r • LinearMap.id := by simp [homothety] +set_option backward.isDefEq.respectTransparency false in theorem homothety_eq_lineMap (c : P1) (r : k) (p : P1) : homothety c r p = lineMap c p r := rfl diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index 9dd892ef26e3a1..8aa500bba2a819 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -113,6 +113,7 @@ theorem coe_subtype (s : AffineSubspace k P) [Nonempty s] : (s.subtype : s → P end AffineSubspace +set_option backward.isDefEq.respectTransparency false in theorem AffineMap.lineMap_mem {k V P : Type*} [Ring k] [AddCommGroup V] [Module k V] [AddTorsor V P] {Q : AffineSubspace k P} {p₀ p₁ : P} (c : k) (h₀ : p₀ ∈ Q) (h₁ : p₁ ∈ Q) : AffineMap.lineMap p₀ p₁ c ∈ Q := by @@ -367,11 +368,13 @@ theorem mem_vectorSpan_pair_rev {p₁ p₂ : P} {v : V} : rw [vectorSpan_pair_rev, Submodule.mem_span_singleton] +set_option backward.isDefEq.respectTransparency false in /-- A combination of two points expressed with `lineMap` lies in their affine span. -/ theorem AffineMap.lineMap_mem_affineSpan_pair (r : k) (p₁ p₂ : P) : AffineMap.lineMap p₁ p₂ r ∈ line[k, p₁, p₂] := AffineMap.lineMap_mem _ (left_mem_affineSpan_pair _ _ _) (right_mem_affineSpan_pair _ _ _) +set_option backward.isDefEq.respectTransparency false in /-- A combination of two points expressed with `lineMap` (with the two points reversed) lies in their affine span. -/ theorem AffineMap.lineMap_rev_mem_affineSpan_pair (r : k) (p₁ p₂ : P) : @@ -404,6 +407,7 @@ theorem vadd_right_mem_affineSpan_pair {p₁ p₂ : P} {v : V} : rw [vadd_mem_iff_mem_direction _ (right_mem_affineSpan_pair _ _ _), direction_affineSpan, mem_vectorSpan_pair] +set_option backward.isDefEq.respectTransparency false in lemma mem_affineSpan_pair_iff_exists_lineMap_eq {p p₁ p₂ : P} : p ∈ line[k, p₁, p₂] ↔ ∃ r : k, AffineMap.lineMap p₁ p₂ r = p := by constructor @@ -415,6 +419,7 @@ lemma mem_affineSpan_pair_iff_exists_lineMap_eq {p p₁ p₂ : P} : · rintro ⟨r, rfl⟩ exact AffineMap.lineMap_mem_affineSpan_pair _ _ _ +set_option backward.isDefEq.respectTransparency false in lemma mem_affineSpan_pair_iff_exists_lineMap_rev_eq {p p₁ p₂ : P} : p ∈ line[k, p₁, p₂] ↔ ∃ r : k, AffineMap.lineMap p₂ p₁ r = p := by rw [Set.pair_comm, mem_affineSpan_pair_iff_exists_lineMap_eq] diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean index 276ee96ba3eb7d..e7ad342de2f8b7 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean @@ -59,6 +59,7 @@ theorem direction_shift (s : AffineSubspace k P) (c : P) (r : k) : have h : Nonempty s := by simpa using! h simp [shift, h] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem shift_top (c : P) (r : k) : shift ⊤ c r = ⊤ := by simp [shift, AffineEquiv.surjective] @@ -230,6 +231,7 @@ private theorem closedInterior_inter_shift_aux {n : ℕ} (i : Fin n) {x : k} (hx intro j by_cases hji : j = i <;> aesop +set_option backward.isDefEq.respectTransparency.types false in /-- A parallel cross-section of a simplex is the image of the base under a homothety. -/ theorem closedInterior_inter_shift_eq_homothety {n : ℕ} [NeZero n] (s : Affine.Simplex k P n) (i : Fin (n + 1)) {x : k} (hx : x ∈ Set.Icc 0 1) : diff --git a/Mathlib/LinearAlgebra/AffineSpace/Ceva.lean b/Mathlib/LinearAlgebra/AffineSpace/Ceva.lean index c91fb216f35797..8a6a2a941315e9 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Ceva.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Ceva.lean @@ -29,6 +29,7 @@ namespace AffineIndependent variable [Ring k] [AddCommGroup V] [Module k V] [AffineSpace V P] +set_option backward.isDefEq.respectTransparency false in /-- Auxiliary lemma for `exists_affineCombination_eq_smul_eq`. -/ private lemma exists_affineCombination_eq_smul_eq_aux {p : ι → P} (hp : AffineIndependent k p) {s : Set ι} (hs : s.Nonempty) {fs : s → Finset ι} (hfs : ∀ i, (i : ι) ∈ fs i) {w : s → ι → k} @@ -131,6 +132,7 @@ section CommRing variable [CommRing k] [NoZeroDivisors k] [AddCommGroup V] [Module k V] [AffineSpace V P] +set_option backward.isDefEq.respectTransparency false in /-- **Ceva's theorem** for a triangle, expressed in terms of multiplying weights. -/ lemma prod_eq_prod_one_sub_of_mem_line_point_lineMap {t : Triangle k P} {r : Fin 3 → k} {p' : P} (hp' : ∀ i : Fin 3, p' ∈ @@ -200,6 +202,7 @@ section Field variable [Field k] [AddCommGroup V] [Module k V] [AffineSpace V P] +set_option backward.isDefEq.respectTransparency false in /-- **Ceva's theorem** for a triangle, expressed using division. -/ lemma prod_div_one_sub_eq_one_of_mem_line_point_lineMap {t : Triangle k P} {r : Fin 3 → k} (hr0 : ∀ i, r i ≠ 0) {p' : P} (hp' : ∀ i : Fin 3, p' ∈ diff --git a/Mathlib/LinearAlgebra/AffineSpace/Combination.lean b/Mathlib/LinearAlgebra/AffineSpace/Combination.lean index 8fdddd24ef2ec4..dc9f0822ea2f1c 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Combination.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Combination.lean @@ -580,6 +580,7 @@ theorem map_affineCombination {V₂ P₂ : Type*} [AddCommGroup V₂] [Module k simp only [weightedVSubOfPoint_apply, RingHom.id_apply, AffineMap.map_vadd, map_smulₛₗ, AffineMap.linearMap_vsub, map_sum, Function.comp_apply] +set_option backward.isDefEq.respectTransparency false in /-- The value of `affineCombination`, where the given points take only two values. -/ lemma affineCombination_apply_eq_lineMap_sum [DecidableEq ι] (w : ι → k) (p : ι → P) (p₁ p₂ : P) (s' : Finset ι) (h : ∑ i ∈ s, w i = 1) (hp₂ : ∀ i ∈ s ∩ s', p i = p₂) @@ -593,6 +594,7 @@ lemma affineCombination_apply_eq_lineMap_sum [DecidableEq ι] (w : ι → k) (p simp [hp₁ i hi] · exact (hp₂ i hi).symm +set_option backward.isDefEq.respectTransparency false in /-- Applying `AffineMap.lineMap` on two `Finset.affineCombination` over the same set of points is equivalent to applying `AffineMap.lineMap` to the weights. -/ theorem lineMap_affineCombination (w₁ : ι → k) (w₂ : ι → k) (r : k) (p : ι → P) : @@ -705,6 +707,7 @@ theorem weightedVSub_weightedVSubVSubWeights [DecidableEq ι] (p : ι → P) {i variable {k} +set_option backward.isDefEq.respectTransparency false in /-- An affine combination with `affineCombinationLineMapWeights` gives the result of `line_map`. -/ @[simp] @@ -716,6 +719,7 @@ theorem affineCombination_affineCombinationLineMapWeights [DecidableEq ι] (p : weightedVSub_const_smul, s.affineCombination_piSingle k p hi, s.weightedVSub_weightedVSubVSubWeights k p hj hi, AffineMap.lineMap_apply] +set_option backward.isDefEq.respectTransparency false in /-- Applying `AffineMap.homothety` on `Finset.affineCombination` towards one of the weighted points is equivalent to moving the weights towards `Finset.affineCombinationSingleWeights`. -/ -- Redeclaring all variables because `AffineMap.homothety` requires `[CommRing k]` @@ -949,6 +953,7 @@ theorem mem_affineSpan_iff_eq_weightedVSubOfPoint_vadd [Nontrivial k] (p : ι variable {k V} +set_option backward.isDefEq.respectTransparency false in /-- Given a set of points, together with a chosen base point in this set, if we affinely transport all other members of the set along the line joining them to this base point, the affine span is unchanged. -/ diff --git a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean index 91d9230991f1a2..8c4107113eca8f 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean @@ -248,6 +248,7 @@ theorem LinearIndependent.affineIndependent variable {k} +set_option backward.isDefEq.respectTransparency false in /-- If we single out one member of an affine-independent family of points and affinely transport all others along the line joining them to this member, the resulting new family of points is affine- independent. @@ -315,6 +316,7 @@ protected theorem AffineIndependent.subtype {p : ι → P} (ha : AffineIndepende AffineIndependent k fun i : s => p i := ha.comp_embedding (Embedding.subtype _) +set_option backward.isDefEq.respectTransparency false in /-- If an indexed family of points is affinely independent, so is the corresponding set of points. -/ protected theorem AffineIndependent.range {p : ι → P} (ha : AffineIndependent k p) : @@ -704,6 +706,7 @@ theorem affineCombination_mem_affineSpan_pair {p : ι → P} (h : AffineIndepend · simp only [Pi.sub_apply, sub_eq_iff_eq_add] · simp_all only [Pi.sub_apply, Finset.sum_sub_distrib, sub_self] +set_option backward.isDefEq.respectTransparency false in /-- Given an affinely independent family of points, an affine combination (with sum of weights 1) equals the line map of two affine combination points if and only if its weights are given pointwise by the line map of the corresponding weights. -/ @@ -724,6 +727,7 @@ section DivisionRing variable {k : Type*} {V : Type*} {P : Type*} [DivisionRing k] [AddCommGroup V] [Module k V] variable [AffineSpace V P] {ι : Type*} +set_option backward.isDefEq.respectTransparency false in /-- An affinely independent set of points can be extended to such a set that spans the whole space. -/ theorem exists_subset_affineIndependent_affineSpan_eq_top {s : Set P} @@ -921,6 +925,7 @@ theorem sign_eq_of_affineCombination_mem_affineSpan_pair {p : ι → P} (h : Aff rcases hs with ⟨r, hr⟩ rw [hr i hi, hr j hj, hi0, hj0, add_zero, add_zero, sub_zero, sub_zero, sign_mul, sign_mul, hij] +set_option backward.isDefEq.respectTransparency false in /-- Given an affinely independent family of points, suppose that an affine combination lies in the span of one point of that family and a combination of another two points of that family given by `lineMap` with coefficient between 0 and 1. Then the coefficients of those two points in the diff --git a/Mathlib/LinearAlgebra/AffineSpace/Midpoint.lean b/Mathlib/LinearAlgebra/AffineSpace/Midpoint.lean index 73715697973e15..418a3f9feaf275 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Midpoint.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Midpoint.lean @@ -42,6 +42,7 @@ section variable (R : Type*) {V V' P P' : Type*} [Ring R] [Invertible (2 : R)] [AddCommGroup V] [Module R V] [AddTorsor V P] [AddCommGroup V'] [Module R V'] [AddTorsor V' P'] +set_option backward.isDefEq.respectTransparency false in /-- `midpoint x y` is the midpoint of the segment `[x, y]`. -/ def midpoint (x y : P) : P := lineMap x y (⅟2 : R) diff --git a/Mathlib/LinearAlgebra/AffineSpace/MidpointZero.lean b/Mathlib/LinearAlgebra/AffineSpace/MidpointZero.lean index 6d6c7e4ad6068b..f30e4644a62930 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/MidpointZero.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/MidpointZero.lean @@ -23,10 +23,12 @@ public section open AffineMap AffineEquiv +set_option backward.isDefEq.respectTransparency false in theorem lineMap_inv_two {R : Type*} {V P : Type*} [DivisionRing R] [CharZero R] [AddCommGroup V] [Module R V] [AddTorsor V P] (a b : P) : lineMap a b (2⁻¹ : R) = midpoint R a b := rfl +set_option backward.isDefEq.respectTransparency false in theorem lineMap_one_half {R : Type*} {V P : Type*} [DivisionRing R] [CharZero R] [AddCommGroup V] [Module R V] [AddTorsor V P] (a b : P) : lineMap a b (1 / 2 : R) = midpoint R a b := by rw [one_div, lineMap_inv_two] diff --git a/Mathlib/LinearAlgebra/AffineSpace/Ordered.lean b/Mathlib/LinearAlgebra/AffineSpace/Ordered.lean index 3a35cf018129fe..48960c7e040b7f 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Ordered.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Ordered.lean @@ -49,29 +49,35 @@ variable [Ring k] [PartialOrder k] [IsOrderedRing k] [AddCommGroup E] [PartialOrder E] [IsOrderedAddMonoid E] [Module k E] [IsStrictOrderedModule k E] variable {a a' b b' : E} {r r' : k} +set_option backward.isDefEq.respectTransparency false in theorem lineMap_mono_left (ha : a ≤ a') (hr : r ≤ 1) : lineMap a b r ≤ lineMap a' b r := by simp only [lineMap_apply_module] gcongr exact sub_nonneg.2 hr +set_option backward.isDefEq.respectTransparency false in theorem lineMap_strict_mono_left (ha : a < a') (hr : r < 1) : lineMap a b r < lineMap a' b r := by simp only [lineMap_apply_module] gcongr exact sub_pos.2 hr +set_option backward.isDefEq.respectTransparency false in omit [IsOrderedRing k] in theorem lineMap_mono_right (hb : b ≤ b') (hr : 0 ≤ r) : lineMap a b r ≤ lineMap a b' r := by simp only [lineMap_apply_module] gcongr +set_option backward.isDefEq.respectTransparency false in omit [IsOrderedRing k] in theorem lineMap_strict_mono_right (hb : b < b') (hr : 0 < r) : lineMap a b r < lineMap a b' r := by simp only [lineMap_apply_module]; gcongr +set_option backward.isDefEq.respectTransparency false in theorem lineMap_mono_endpoints (ha : a ≤ a') (hb : b ≤ b') (h₀ : 0 ≤ r) (h₁ : r ≤ 1) : lineMap a b r ≤ lineMap a' b' r := (lineMap_mono_left ha h₁).trans (lineMap_mono_right hb h₀) +set_option backward.isDefEq.respectTransparency false in theorem lineMap_strict_mono_endpoints (ha : a < a') (hb : b < b') (h₀ : 0 ≤ r) (h₁ : r ≤ 1) : lineMap a b r < lineMap a' b' r := by rcases h₀.eq_or_lt with (rfl | h₀); · simpa @@ -79,20 +85,25 @@ theorem lineMap_strict_mono_endpoints (ha : a < a') (hb : b < b') (h₀ : 0 ≤ variable [PosSMulReflectLT k E] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_lt_lineMap_iff_of_lt (h : r < r') : lineMap a b r < lineMap a b r' ↔ a < b := by simp only [lineMap_apply_module] rw [← lt_sub_iff_add_lt, add_sub_assoc, ← sub_lt_iff_lt_add', ← sub_smul, ← sub_smul, sub_sub_sub_cancel_left, smul_lt_smul_iff_of_pos_left (sub_pos.2 h)] +set_option backward.isDefEq.respectTransparency false in theorem left_lt_lineMap_iff_lt (h : 0 < r) : a < lineMap a b r ↔ a < b := Iff.trans (by rw [lineMap_apply_zero]) (lineMap_lt_lineMap_iff_of_lt h) +set_option backward.isDefEq.respectTransparency false in theorem lineMap_lt_left_iff_lt (h : 0 < r) : lineMap a b r < a ↔ b < a := left_lt_lineMap_iff_lt (E := Eᵒᵈ) h +set_option backward.isDefEq.respectTransparency false in theorem lineMap_lt_right_iff_lt (h : r < 1) : lineMap a b r < b ↔ a < b := Iff.trans (by rw [lineMap_apply_one]) (lineMap_lt_lineMap_iff_of_lt h) +set_option backward.isDefEq.respectTransparency false in theorem right_lt_lineMap_iff_lt (h : r < 1) : b < lineMap a b r ↔ b < a := lineMap_lt_right_iff_lt (E := Eᵒᵈ) h @@ -104,35 +115,45 @@ variable [Ring k] [LinearOrder k] [IsStrictOrderedRing k] [AddCommGroup E] [PartialOrder E] [IsOrderedAddMonoid E] [Module k E] [IsStrictOrderedModule k E] {a a' b b' : E} {r r' : k} +set_option backward.isDefEq.respectTransparency false in theorem lineMap_le_lineMap_iff_of_lt' (h : a < b) : lineMap a b r ≤ lineMap a b r' ↔ r ≤ r' := by simp only [lineMap_apply_module'] rw [add_le_add_iff_right, smul_le_smul_iff_of_pos_right (sub_pos.mpr h)] +set_option backward.isDefEq.respectTransparency false in theorem left_le_lineMap_iff_nonneg (h : a < b) : a ≤ lineMap a b r ↔ 0 ≤ r := by rw [← lineMap_le_lineMap_iff_of_lt' h, lineMap_apply_zero] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_le_left_iff_nonpos (h : a < b) : lineMap a b r ≤ a ↔ r ≤ 0 := by rw [← lineMap_le_lineMap_iff_of_lt' h, lineMap_apply_zero] +set_option backward.isDefEq.respectTransparency false in theorem right_le_lineMap_iff_one_le (h : a < b) : b ≤ lineMap a b r ↔ 1 ≤ r := by rw [← lineMap_le_lineMap_iff_of_lt' h, lineMap_apply_one] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_le_right_iff_le_one (h : a < b) : lineMap a b r ≤ b ↔ r ≤ 1 := by rw [← lineMap_le_lineMap_iff_of_lt' h, lineMap_apply_one] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_lt_lineMap_iff_of_lt' (h : a < b) : lineMap a b r < lineMap a b r' ↔ r < r' := by simp only [lineMap_apply_module'] rw [add_lt_add_iff_right, smul_lt_smul_iff_of_pos_right (sub_pos.mpr h)] +set_option backward.isDefEq.respectTransparency false in theorem left_lt_lineMap_iff_pos (h : a < b) : a < lineMap a b r ↔ 0 < r := by rw [← lineMap_lt_lineMap_iff_of_lt' h, lineMap_apply_zero] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_lt_left_iff_neg (h : a < b) : lineMap a b r < a ↔ r < 0 := by rw [← lineMap_lt_lineMap_iff_of_lt' h, lineMap_apply_zero] +set_option backward.isDefEq.respectTransparency false in theorem right_lt_lineMap_iff_one_lt (h : a < b) : b < lineMap a b r ↔ 1 < r := by rw [← lineMap_lt_lineMap_iff_of_lt' h, lineMap_apply_one] +set_option backward.isDefEq.respectTransparency false in theorem lineMap_lt_right_iff_lt_one (h : a < b) : lineMap a b r < b ↔ r < 1 := by rw [← lineMap_lt_lineMap_iff_of_lt' h, lineMap_apply_one] @@ -152,11 +173,13 @@ section variable {a b : E} {r r' : k} +set_option backward.isDefEq.respectTransparency false in theorem lineMap_le_lineMap_iff_of_lt (h : r < r') : lineMap a b r ≤ lineMap a b r' ↔ a ≤ b := by simp only [lineMap_apply_module] rw [← le_sub_iff_add_le, add_sub_assoc, ← sub_le_iff_le_add', ← sub_smul, ← sub_smul, sub_sub_sub_cancel_left, smul_le_smul_iff_of_pos_left (sub_pos.2 h)] +set_option backward.isDefEq.respectTransparency false in theorem left_le_lineMap_iff_le (h : 0 < r) : a ≤ lineMap a b r ↔ a ≤ b := Iff.trans (by rw [lineMap_apply_zero]) (lineMap_le_lineMap_iff_of_lt h) @@ -164,6 +187,7 @@ theorem left_le_lineMap_iff_le (h : 0 < r) : a ≤ lineMap a b r ↔ a ≤ b := theorem left_le_midpoint : a ≤ midpoint k a b ↔ a ≤ b := left_le_lineMap_iff_le <| inv_pos.2 zero_lt_two +set_option backward.isDefEq.respectTransparency false in theorem lineMap_le_left_iff_le (h : 0 < r) : lineMap a b r ≤ a ↔ b ≤ a := left_le_lineMap_iff_le (E := Eᵒᵈ) h @@ -171,12 +195,14 @@ theorem lineMap_le_left_iff_le (h : 0 < r) : lineMap a b r ≤ a ↔ b ≤ a := theorem midpoint_le_left : midpoint k a b ≤ a ↔ b ≤ a := lineMap_le_left_iff_le <| inv_pos.2 zero_lt_two +set_option backward.isDefEq.respectTransparency false in theorem lineMap_le_right_iff_le (h : r < 1) : lineMap a b r ≤ b ↔ a ≤ b := Iff.trans (by rw [lineMap_apply_one]) (lineMap_le_lineMap_iff_of_lt h) @[simp] theorem midpoint_le_right : midpoint k a b ≤ b ↔ a ≤ b := lineMap_le_right_iff_le two_inv_lt_one +set_option backward.isDefEq.respectTransparency false in theorem right_le_lineMap_iff_le (h : r < 1) : b ≤ lineMap a b r ↔ b ≤ a := lineMap_le_right_iff_le (E := Eᵒᵈ) h @@ -221,6 +247,7 @@ local notation "c" => lineMap a b r section omit [IsStrictOrderedRing k] +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c`, the point `(c, f c)` is non-strictly below the segment `[(a, f a), (b, f b)]` if and only if `slope f a c ≤ slope f a b`. -/ theorem map_le_lineMap_iff_slope_le_slope_left (h : 0 < r * (b - a)) : @@ -232,12 +259,14 @@ theorem map_le_lineMap_iff_slope_le_slope_left (h : 0 < r * (b - a)) : mul_inv_cancel_right₀ (right_ne_zero_of_mul h.ne'), smul_add, smul_inv_smul₀ (left_ne_zero_of_mul h.ne')] +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c`, the point `(c, f c)` is non-strictly above the segment `[(a, f a), (b, f b)]` if and only if `slope f a b ≤ slope f a c`. -/ theorem lineMap_le_map_iff_slope_le_slope_left (h : 0 < r * (b - a)) : lineMap (f a) (f b) r ≤ f c ↔ slope f a b ≤ slope f a c := map_le_lineMap_iff_slope_le_slope_left (E := Eᵒᵈ) (f := f) (a := a) (b := b) (r := r) h +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c`, the point `(c, f c)` is strictly below the segment `[(a, f a), (b, f b)]` if and only if `slope f a c < slope f a b`. -/ theorem map_lt_lineMap_iff_slope_lt_slope_left (h : 0 < r * (b - a)) : @@ -245,12 +274,14 @@ theorem map_lt_lineMap_iff_slope_lt_slope_left (h : 0 < r * (b - a)) : lt_iff_lt_of_le_iff_le' (lineMap_le_map_iff_slope_le_slope_left h) (map_le_lineMap_iff_slope_le_slope_left h) +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c`, the point `(c, f c)` is strictly above the segment `[(a, f a), (b, f b)]` if and only if `slope f a b < slope f a c`. -/ theorem lineMap_lt_map_iff_slope_lt_slope_left (h : 0 < r * (b - a)) : lineMap (f a) (f b) r < f c ↔ slope f a b < slope f a c := map_lt_lineMap_iff_slope_lt_slope_left (E := Eᵒᵈ) (f := f) (a := a) (b := b) (r := r) h +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `c < b`, the point `(c, f c)` is non-strictly below the segment `[(a, f a), (b, f b)]` if and only if `slope f a b ≤ slope f c b`. -/ theorem map_le_lineMap_iff_slope_le_slope_right (h : 0 < (1 - r) * (b - a)) : @@ -263,12 +294,14 @@ theorem map_le_lineMap_iff_slope_le_slope_right (h : 0 < (1 - r) * (b - a)) : smul_neg, neg_add_eq_sub] · exact right_ne_zero_of_mul h.ne' +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `c < b`, the point `(c, f c)` is non-strictly above the segment `[(a, f a), (b, f b)]` if and only if `slope f c b ≤ slope f a b`. -/ theorem lineMap_le_map_iff_slope_le_slope_right (h : 0 < (1 - r) * (b - a)) : lineMap (f a) (f b) r ≤ f c ↔ slope f c b ≤ slope f a b := map_le_lineMap_iff_slope_le_slope_right (E := Eᵒᵈ) (f := f) (a := a) (b := b) (r := r) h +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `c < b`, the point `(c, f c)` is strictly below the segment `[(a, f a), (b, f b)]` if and only if `slope f a b < slope f c b`. -/ theorem map_lt_lineMap_iff_slope_lt_slope_right (h : 0 < (1 - r) * (b - a)) : @@ -276,6 +309,7 @@ theorem map_lt_lineMap_iff_slope_lt_slope_right (h : 0 < (1 - r) * (b - a)) : lt_iff_lt_of_le_iff_le' (lineMap_le_map_iff_slope_le_slope_right h) (map_le_lineMap_iff_slope_le_slope_right h) +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `c < b`, the point `(c, f c)` is strictly above the segment `[(a, f a), (b, f b)]` if and only if `slope f c b < slope f a b`. -/ theorem lineMap_lt_map_iff_slope_lt_slope_right (h : 0 < (1 - r) * (b - a)) : @@ -284,6 +318,7 @@ theorem lineMap_lt_map_iff_slope_lt_slope_right (h : 0 < (1 - r) * (b - a)) : end +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c < b`, the point `(c, f c)` is non-strictly below the segment `[(a, f a), (b, f b)]` if and only if `slope f a c ≤ slope f c b`. -/ theorem map_le_lineMap_iff_slope_le_slope (hab : a < b) (h₀ : 0 < r) (h₁ : r < 1) : @@ -291,12 +326,14 @@ theorem map_le_lineMap_iff_slope_le_slope (hab : a < b) (h₀ : 0 < r) (h₁ : r rw [map_le_lineMap_iff_slope_le_slope_left (mul_pos h₀ (sub_pos.2 hab)), ← lineMap_slope_lineMap_slope_lineMap f a b r, right_le_lineMap_iff_le h₁] +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c < b`, the point `(c, f c)` is non-strictly above the segment `[(a, f a), (b, f b)]` if and only if `slope f c b ≤ slope f a c`. -/ theorem lineMap_le_map_iff_slope_le_slope (hab : a < b) (h₀ : 0 < r) (h₁ : r < 1) : lineMap (f a) (f b) r ≤ f c ↔ slope f c b ≤ slope f a c := map_le_lineMap_iff_slope_le_slope (E := Eᵒᵈ) hab h₀ h₁ +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c < b`, the point `(c, f c)` is strictly below the segment `[(a, f a), (b, f b)]` if and only if `slope f a c < slope f c b`. -/ theorem map_lt_lineMap_iff_slope_lt_slope (hab : a < b) (h₀ : 0 < r) (h₁ : r < 1) : @@ -304,6 +341,7 @@ theorem map_lt_lineMap_iff_slope_lt_slope (hab : a < b) (h₀ : 0 < r) (h₁ : r lt_iff_lt_of_le_iff_le' (lineMap_le_map_iff_slope_le_slope hab h₀ h₁) (map_le_lineMap_iff_slope_le_slope hab h₀ h₁) +set_option backward.isDefEq.respectTransparency false in /-- Given `c = lineMap a b r`, `a < c < b`, the point `(c, f c)` is strictly above the segment `[(a, f a), (b, f b)]` if and only if `slope f c b < slope f a c`. -/ theorem lineMap_lt_map_iff_slope_lt_slope (hab : a < b) (h₀ : 0 < r) (h₁ : r < 1) : diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean index 6e2715dc6104ca..0e94d3104cfb03 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean @@ -275,6 +275,7 @@ theorem reindex_map {m n : ℕ} (s : Simplex k P m) (e : Fin (m + 1) ≃ Fin (n (s.map f hf).reindex e = (s.reindex e).map f hf := rfl +set_option backward.isDefEq.respectTransparency false in lemma range_face_reindex {m n : ℕ} (s : Simplex k P m) (e : Fin (m + 1) ≃ Fin (n + 1)) {fs : Finset (Fin (n + 1))} {n' : ℕ} (h : #fs = n' + 1) : Set.range ((s.reindex e).face h).points = diff --git a/Mathlib/LinearAlgebra/AffineSpace/Slope.lean b/Mathlib/LinearAlgebra/AffineSpace/Slope.lean index e000e52df3486c..842a16bed8502c 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Slope.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Slope.lean @@ -112,6 +112,7 @@ theorem sub_div_sub_smul_slope_add_sub_div_sub_smul_slope (f : k → PE) (a b c smul_inv_smul₀ (sub_ne_zero.2 <| Ne.symm hab), smul_inv_smul₀ (sub_ne_zero.2 <| Ne.symm hbc), vsub_add_vsub_cancel] +set_option backward.isDefEq.respectTransparency false in /-- `slope f a c` is an affine combination of `slope f a b` and `slope f b c`. This version uses `lineMap` to express this property. -/ theorem lineMap_slope_slope_sub_div_sub (f : k → PE) (a b c : k) (h : a ≠ c) : @@ -121,6 +122,7 @@ theorem lineMap_slope_slope_sub_div_sub (f : k → PE) (a b c : k) (h : a ≠ c) match_scalars field [sub_ne_zero.2 h.symm] +set_option backward.isDefEq.respectTransparency false in /-- `slope f a b` is an affine combination of `slope f a (lineMap a b r)` and `slope f (lineMap a b r) b`. We use `lineMap` to express this property. -/ theorem lineMap_slope_lineMap_slope_lineMap (f : k → PE) (a b r : k) : diff --git a/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean b/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean index fb33822f9b1960..59f30001e1db9a 100644 --- a/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean +++ b/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean @@ -198,6 +198,7 @@ theorem MultilinearMap.domCoprod_alternization_coe [DecidableEq ιa] [DecidableE open AlternatingMap +set_option backward.isDefEq.respectTransparency.types false in open Perm in /-- Computing the `MultilinearMap.alternatization` of the `MultilinearMap.domCoprod` is the same as computing the `AlternatingMap.domCoprod` of the `MultilinearMap.alternatization`s. diff --git a/Mathlib/LinearAlgebra/Basis/Basic.lean b/Mathlib/LinearAlgebra/Basis/Basic.lean index 9bf07fec3e2dbe..b0fa1439a882d2 100644 --- a/Mathlib/LinearAlgebra/Basis/Basic.lean +++ b/Mathlib/LinearAlgebra/Basis/Basic.lean @@ -210,6 +210,7 @@ lemma span_neg {R M : Type*} [Ring R] [AddCommGroup M] [Module R M] end Span +set_option backward.isDefEq.respectTransparency false in /-- Any basis is a maximal linear independent set. -/ theorem maximal [Nontrivial R] (b : Basis ι R M) : b.linearIndependent.Maximal := fun w hi h => by @@ -253,10 +254,12 @@ protected def singleton (ι R : Type*) [Unique ι] [Semiring R] : Basis ι R R : map_add' := fun x y => by simp map_smul' := fun c x => by simp } +set_option backward.isDefEq.respectTransparency false in @[simp] theorem singleton_apply (ι R : Type*) [Unique ι] [Semiring R] (i) : Basis.singleton ι R i = 1 := apply_eq_iff.mpr (by simp [Basis.singleton]) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem singleton_repr (ι R : Type*) [Unique ι] [Semiring R] (x i) : (Basis.singleton ι R).repr x i = x := by simp [Basis.singleton, Unique.eq_default i] @@ -284,6 +287,7 @@ end Empty section Module.IsTorsionFree +set_option backward.isDefEq.respectTransparency false in -- Can't be an instance because the basis can't be inferred. protected lemma isTorsionFree (b : Basis ι R M) : Module.IsTorsionFree R M := b.repr.injective.moduleIsTorsionFree _ (by simp) diff --git a/Mathlib/LinearAlgebra/Basis/Bilinear.lean b/Mathlib/LinearAlgebra/Basis/Bilinear.lean index becd3bbcc8bc99..7ef6b390d3a445 100644 --- a/Mathlib/LinearAlgebra/Basis/Bilinear.lean +++ b/Mathlib/LinearAlgebra/Basis/Bilinear.lean @@ -57,6 +57,7 @@ theorem sum_repr_mul_repr_mulₛₗ {B : M →ₛₗ[ρ₁₂] N →ₛₗ[σ₁ conv_rhs => rw [← b₁.linearCombination_repr x, ← b₂.linearCombination_repr y] simp_rw [Finsupp.linearCombination_apply, Finsupp.sum, map_sum₂, map_sum, map_smulₛₗ₂, map_smulₛₗ] +set_option backward.isDefEq.respectTransparency false in /-- Write out `B x y` as a sum over `B (b i) (b j)` if `b` is a basis. Version for bilinear maps, see `sum_repr_mul_repr_mulₛₗ` for the semi-bilinear version. -/ diff --git a/Mathlib/LinearAlgebra/Basis/Cardinality.lean b/Mathlib/LinearAlgebra/Basis/Cardinality.lean index fc1258c2beb978..2e312c3745c929 100644 --- a/Mathlib/LinearAlgebra/Basis/Cardinality.lean +++ b/Mathlib/LinearAlgebra/Basis/Cardinality.lean @@ -63,6 +63,7 @@ section Ring variable [Semiring R] [AddCommMonoid M] [Nontrivial R] [Module R M] +set_option backward.isDefEq.respectTransparency false in -- From [Les familles libres maximales d'un module ont-elles le meme cardinal?][lazarus1973] /-- Over any ring `R`, if `b` is a basis for a module `M`, and `s` is a maximal linearly independent set, diff --git a/Mathlib/LinearAlgebra/Basis/Defs.lean b/Mathlib/LinearAlgebra/Basis/Defs.lean index c4ff6d939ed635..4428deb1f33dff 100644 --- a/Mathlib/LinearAlgebra/Basis/Defs.lean +++ b/Mathlib/LinearAlgebra/Basis/Defs.lean @@ -231,11 +231,12 @@ def Basis.equivFun [Finite ι] (b : Basis ι R M) : M ≃ₗ[R] ι → R := (ι →₀ R) ≃ₗ[R] ι → R) /-- A module over a finite ring that admits a finite basis is finite. -/ -@[implicit_reducible] +@[instance_reducible] def fintypeOfFintype [Fintype ι] (b : Basis ι R M) [Fintype R] : Fintype M := haveI := Classical.decEq ι Fintype.ofEquiv _ b.equivFun.toEquiv.symm +set_option backward.isDefEq.respectTransparency false in /-- Given a basis `v` indexed by `ι`, the canonical linear equivalence between `ι → R` and `M` maps a function `x : ι → R` to the linear combination `∑_i x i • v i`. -/ @[simp] @@ -433,6 +434,7 @@ theorem reindexRange_apply (x : range b) : b.reindexRange x = x := by rcases x with ⟨bi, ⟨i, rfl⟩⟩ exact b.reindexRange_self i +set_option backward.isDefEq.respectTransparency false in theorem reindexRange_repr' (x : M) {bi : M} {i : ι} (h : b i = bi) : b.reindexRange.repr x ⟨bi, ⟨i, h⟩⟩ = b.repr x i := by nontriviality @@ -642,6 +644,7 @@ theorem equiv'_symm_apply (f : M → M') (g : M' → M) (hf hg hgf hfg) (i : ι' (b.equiv' b' f g hf hg hgf hfg).symm (b' i) = g (b' i) := b'.constr_basis R _ _ +set_option backward.isDefEq.respectTransparency false in theorem sum_repr_mul_repr {ι'} [Fintype ι'] (b' : Basis ι' R M) (x : M) (i : ι) : (∑ j : ι', b.repr (b' j) i * b'.repr x j) = b.repr x i := by conv_rhs => rw [← b'.sum_repr x] diff --git a/Mathlib/LinearAlgebra/Basis/Exact.lean b/Mathlib/LinearAlgebra/Basis/Exact.lean index 4ae6e0822aace4..53968a3f0b4680 100644 --- a/Mathlib/LinearAlgebra/Basis/Exact.lean +++ b/Mathlib/LinearAlgebra/Basis/Exact.lean @@ -52,6 +52,7 @@ lemma LinearIndependent.linearIndependent_of_exact_of_retraction simp only [LinearMap.coe_comp, Function.comp_apply, LinearMap.id_coe, id_eq] at hs rw [← hs, hz, map_zero] +set_option backward.isDefEq.respectTransparency false in private lemma top_le_span_of_aux (v : κ ⊕ σ → M) (hg : Function.Surjective g) (hslzero : ∀ i, s (v (.inl i)) = 0) (hli : LinearIndependent R (s ∘ v ∘ .inr)) (hsp : ⊤ ≤ Submodule.span R (Set.range v)) : diff --git a/Mathlib/LinearAlgebra/Basis/Fin.lean b/Mathlib/LinearAlgebra/Basis/Fin.lean index c2cc98a0e87750..1320a0a72144a3 100644 --- a/Mathlib/LinearAlgebra/Basis/Fin.lean +++ b/Mathlib/LinearAlgebra/Basis/Fin.lean @@ -124,10 +124,12 @@ theorem coe_mkFinSnocOfLE {n : ℕ} {N O : Submodule R M} (b : Basis (Fin n) R N protected def finTwoProd (R : Type*) [Semiring R] : Basis (Fin 2) R (R × R) := Basis.ofEquivFun (LinearEquiv.finTwoArrow R R).symm +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem finTwoProd_zero (R : Type*) [Semiring R] : Basis.finTwoProd R 0 = (1, 0) := by simp [Basis.finTwoProd, LinearEquiv.finTwoArrow] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem finTwoProd_one (R : Type*) [Semiring R] : Basis.finTwoProd R 1 = (0, 1) := by simp [Basis.finTwoProd, LinearEquiv.finTwoArrow] diff --git a/Mathlib/LinearAlgebra/Basis/SMul.lean b/Mathlib/LinearAlgebra/Basis/SMul.lean index 091b29649fb93c..d48b6c6be61b07 100644 --- a/Mathlib/LinearAlgebra/Basis/SMul.lean +++ b/Mathlib/LinearAlgebra/Basis/SMul.lean @@ -110,6 +110,7 @@ theorem unitsSMul_apply {v : Basis ι R M} {w : ι → Rˣ} (i : ι) : unitsSMul variable [CommSemiring R₂] [Module R₂ M] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem coord_unitsSMul (e : Basis ι R₂ M) (w : ι → R₂ˣ) (i : ι) : (unitsSMul e w).coord i = (w i)⁻¹ • e.coord i := by diff --git a/Mathlib/LinearAlgebra/Basis/Submodule.lean b/Mathlib/LinearAlgebra/Basis/Submodule.lean index aa9d6ba203ab18..66a6b48206518a 100644 --- a/Mathlib/LinearAlgebra/Basis/Submodule.lean +++ b/Mathlib/LinearAlgebra/Basis/Submodule.lean @@ -37,6 +37,7 @@ theorem mem_submodule_iff {P : Submodule R M} (b : Basis ι R P) {x : M} : ← Finsupp.range_linearCombination] simp [@eq_comm _ x, Function.comp, Finsupp.linearCombination_apply] +set_option backward.isDefEq.respectTransparency false in /-- If the submodule `P` has a finite basis, `x ∈ P` iff it is a linear combination of basis vectors. -/ theorem mem_submodule_iff' [Fintype ι] {P : Submodule R M} (b : Basis ι R P) {x : M} : diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index a98476d639a01b..450f0bb45438a2 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -340,6 +340,7 @@ variable {K : Type*} {V : Type*} [Field K] [AddCommGroup V] [Module K V] variable {f : V →ₗ[K] K} {v : V} +set_option backward.isDefEq.respectTransparency false in /-- In a vector space, given a nonzero linear form `f`, a nonzero vector `v` such that `f v ≠ 0`, there exists a basis `b` with an index `i` @@ -424,7 +425,7 @@ theorem exists_basis_of_pairing_eq_zero · apply b.ext intro i rw [Basis.coord_apply, Basis.repr_self] - simp only [b, Basis.mk_apply] + simp only [b] rcases i with ⟨x, rfl | ⟨x, hx, rfl⟩⟩ · simp [hw] · suffices x ≠ w by simp [this] diff --git a/Mathlib/LinearAlgebra/BilinearForm/Properties.lean b/Mathlib/LinearAlgebra/BilinearForm/Properties.lean index 5f791c917facf3..fa737f807f92ad 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Properties.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Properties.lean @@ -157,6 +157,7 @@ lemma ext_iff_of_isSymm (hB : IsSymm B) (hC : IsSymm C) : end polarization +set_option backward.isDefEq.respectTransparency false in lemma isSymm_iff_basis {ι : Type*} (b : Basis ι R M) : IsSymm B ↔ ∀ i j, B (b i) (b j) = B (b j) (b i) where mp := fun ⟨h⟩ i j ↦ h _ _ diff --git a/Mathlib/LinearAlgebra/BilinearMap.lean b/Mathlib/LinearAlgebra/BilinearMap.lean index 444fe1ed5f8bb4..2e69802b24b089 100644 --- a/Mathlib/LinearAlgebra/BilinearMap.lean +++ b/Mathlib/LinearAlgebra/BilinearMap.lean @@ -569,6 +569,7 @@ noncomputable def restrictScalarsRange : M' →ₗ[S] P' := ((f.restrictScalars S).comp i).codLift k hk hf +set_option backward.isDefEq.respectTransparency false in @[simp] lemma restrictScalarsRange_apply (m : M') : k (restrictScalarsRange i k hk f hf m) = f (i m) := by @@ -608,6 +609,7 @@ noncomputable def restrictScalarsRange₂ : (((LinearMap.restrictScalarsₗ S R _ _ _).comp (B.restrictScalars S)).compl₁₂ i j).codRestrict₂ k hk hB +set_option backward.isDefEq.respectTransparency false in @[simp] lemma restrictScalarsRange₂_apply (m : M') (n : N') : k (restrictScalarsRange₂ i j k hk B hB m n) = B (i m) (j n) := by simp [restrictScalarsRange₂] diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean index 33ca6fe5da724c..677367a9f9ed38 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean @@ -119,6 +119,7 @@ theorem comp_ι_sq_scalar (g : CliffordAlgebra Q →ₐ[R] A) (m : M) : g (ι Q m) * g (ι Q m) = algebraMap _ _ (Q m) := by rw [← map_mul, ι_sq_scalar, AlgHom.commutes] +set_option backward.isDefEq.respectTransparency.types false in variable (Q) in /-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition: `cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean index fedb6cf5ebf965..cc95bd4a21cdfb 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean @@ -343,6 +343,7 @@ theorem ι_mul_ι (r₁ r₂) : ι (0 : QuadraticForm R R) r₁ * ι (0 : Quadra rw [← mul_one r₁, ← mul_one r₂, ← smul_eq_mul r₁, ← smul_eq_mul r₂, map_smul, map_smul, smul_mul_smul_comm, ι_sq_scalar, QuadraticMap.zero_apply, map_zero, smul_zero] +set_option backward.isDefEq.respectTransparency.types false in /-- The clifford algebra over a 1-dimensional vector space with 0 quadratic form is isomorphic to the dual numbers. -/ protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] := @@ -354,11 +355,13 @@ protected def equiv : CliffordAlgebra (0 : QuadraticForm R R) ≃ₐ[R] R[ε] := fun _ => (Algebra.commutes _ _).symm⟩) (by ext : 1; simp) (by ext : 2; simp) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem equiv_ι (r : R) : CliffordAlgebraDualNumber.equiv (ι (R := R) _ r) = r • ε := by dsimp [CliffordAlgebraDualNumber.equiv, AlgEquiv.ofAlgHom] exact (lift_ι_apply _ _ r).trans (inr_eq_smul_eps _) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem equiv_symm_eps : CliffordAlgebraDualNumber.equiv.symm (eps : R[ε]) = ι (0 : QuadraticForm R R) 1 := by diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean index 3a80fba3ee6387..fc30d6145d90b5 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean @@ -106,6 +106,7 @@ end EquivEven open EquivEven +set_option backward.isDefEq.respectTransparency.types false in /-- The embedding from the smaller algebra into the new larger one. -/ def toEven : CliffordAlgebra Q →ₐ[R] CliffordAlgebra.even (Q' Q) := by refine CliffordAlgebra.lift Q ⟨?_, fun m => ?_⟩ @@ -118,6 +119,7 @@ def toEven : CliffordAlgebra Q →ₐ[R] CliffordAlgebra.even (Q' Q) := by rw [LinearMap.codRestrict_apply] simp [← mul_assoc, v_sq_scalar] +set_option backward.isDefEq.respectTransparency.types false in theorem toEven_ι (m : M) : (toEven Q (ι Q m) : CliffordAlgebra (Q' Q)) = e0 Q * v Q m := by simp only [toEven, CliffordAlgebra.lift_ι_apply, ← even_toSubmodule] rw [LinearMap.codRestrict_apply, LinearMap.coe_comp, Function.comp_apply, LinearMap.mulLeft_apply] diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean index 0dce58a81e591e..9b54663a469e51 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Inversion.lean @@ -23,7 +23,7 @@ namespace CliffordAlgebra variable (Q) /-- If the quadratic form of a vector is invertible, then so is that vector. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleιOfInvertible (m : M) [Invertible (Q m)] : Invertible (ι Q m) where invOf := ι Q (⅟(Q m) • m) invOf_mul_self := by @@ -58,7 +58,7 @@ section variable [Invertible (2 : R)] /-- Over a ring where `2` is invertible, `Q m` is invertible whenever `ι Q m`. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfInvertibleι (m : M) [Invertible (ι Q m)] : Invertible (Q m) := ExteriorAlgebra.invertibleAlgebraMapEquiv M (Q m) <| .algebraMapOfInvertibleAlgebraMap (equivExterior Q).toLinearMap (by simp) <| diff --git a/Mathlib/LinearAlgebra/Complex/Module.lean b/Mathlib/LinearAlgebra/Complex/Module.lean index 26fb146affe3e9..ce14d98da1ed4e 100644 --- a/Mathlib/LinearAlgebra/Complex/Module.lean +++ b/Mathlib/LinearAlgebra/Complex/Module.lean @@ -54,7 +54,7 @@ namespace Complex open ComplexConjugate -open scoped SMul +open scoped Complex.SMul variable {R : Type*} {S : Type*} @@ -453,6 +453,7 @@ lemma realPart_comp_subtype_selfAdjoint : realPart.comp (selfAdjoint.submodule ℝ A).subtype = LinearMap.id := selfAdjointPart_comp_subtype_selfAdjoint ℝ +set_option backward.isDefEq.respectTransparency.types false in lemma imaginaryPart_comp_subtype_selfAdjoint : imaginaryPart.comp (selfAdjoint.submodule ℝ A).subtype = 0 := by ext; simp [imaginaryPart] @@ -504,6 +505,7 @@ lemma map_imaginaryPart (f : F) (x : A) : f (ℑ x) = ℑ (f x) := by end StarHomClass +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ker_imaginaryPart : imaginaryPart.ker = selfAdjoint.submodule ℝ A := by ext x diff --git a/Mathlib/LinearAlgebra/Contraction.lean b/Mathlib/LinearAlgebra/Contraction.lean index 228d8e3ba8c286..8fd53145b7cf39 100644 --- a/Mathlib/LinearAlgebra/Contraction.lean +++ b/Mathlib/LinearAlgebra/Contraction.lean @@ -103,6 +103,7 @@ theorem map_dualTensorHom (f : Module.Dual R M) (p : P) (g : Module.Dual R N) (q simp only [compr₂ₛₗ_apply, mk_apply, map_tmul, dualTensorHom_apply, dualDistrib_apply, ← smul_tmul_smul] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem comp_dualTensorHom (f : Module.Dual R M) (n : N) (g : Module.Dual R N) (p : P) : dualTensorHom R N P (g ⊗ₜ[R] p) ∘ₗ dualTensorHom R M N (f ⊗ₜ[R] n) = @@ -111,6 +112,7 @@ theorem comp_dualTensorHom (f : Module.Dual R M) (n : N) (g : Module.Dual R N) ( simp only [coe_comp, Function.comp_apply, dualTensorHom_apply, map_smul, LinearMap.smul_apply] rw [smul_comm] +set_option backward.isDefEq.respectTransparency false in /-- As a matrix, `dualTensorHom` evaluated on a basis element of `M* ⊗ N` is a matrix with a single one and zeros elsewhere -/ theorem toMatrix_dualTensorHom {m : Type*} {n : Type*} [Fintype m] [Finite n] [DecidableEq m] diff --git a/Mathlib/LinearAlgebra/CrossProduct.lean b/Mathlib/LinearAlgebra/CrossProduct.lean index 7a8bae94b922cf..c66be92dbb904e 100644 --- a/Mathlib/LinearAlgebra/CrossProduct.lean +++ b/Mathlib/LinearAlgebra/CrossProduct.lean @@ -100,6 +100,7 @@ theorem triple_product_permutation (u v w : Fin 3 → R) : u ⬝ᵥ v ⨯₃ w = dsimp only [Matrix.cons_val] ring +set_option backward.isDefEq.respectTransparency false in /-- The triple product of `u`, `v`, and `w` is equal to the determinant of the matrix with those vectors as its rows. -/ theorem triple_product_eq_det (u v w : Fin 3 → R) : u ⬝ᵥ v ⨯₃ w = Matrix.det ![u, v, w] := by diff --git a/Mathlib/LinearAlgebra/DFinsupp.lean b/Mathlib/LinearAlgebra/DFinsupp.lean index 0b8fcbbf6a2712..1f226ab346280a 100644 --- a/Mathlib/LinearAlgebra/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/DFinsupp.lean @@ -147,6 +147,7 @@ def linearEquivFunOnFintype [Fintype ι] : (Π₀ i, M i) ≃ₗ[R] (Π i, M i) map_add' _ _ := by ext; rfl map_smul' _ _ := by ext; rfl +set_option backward.isDefEq.respectTransparency false in /-- The `DFinsupp` version of `Finsupp.lsum`. See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/ @@ -210,6 +211,7 @@ section AddCommMonoid variable [∀ i, AddCommMonoid (β i)] [∀ i, AddCommMonoid (β₁ i)] [∀ i, AddCommMonoid (β₂ i)] variable [∀ i, Module R (β i)] [∀ i, Module R (β₁ i)] [∀ i, Module R (β₂ i)] +set_option backward.isDefEq.respectTransparency false in lemma mker_mapRangeAddMonoidHom (f : ∀ i, β₁ i →+ β₂ i) : AddMonoidHom.mker (mapRange.addMonoidHom f) = (AddSubmonoid.pi Set.univ (fun i ↦ AddMonoidHom.mker (f i))).comap coeFnAddMonoidHom := by @@ -245,6 +247,7 @@ def mapRange.linearMap (f : ∀ i, β₁ i →ₗ[R] β₂ i) : (Π₀ i, β₁ toFun := mapRange (fun i x => f i x) fun i => (f i).map_zero map_smul' := fun r => mapRange_smul _ (fun i => (f i).map_zero) _ fun i => (f i).map_smul r } +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mapRange.linearMap_id : (mapRange.linearMap fun i => (LinearMap.id : β₂ i →ₗ[R] _)) = LinearMap.id := by @@ -630,6 +633,7 @@ theorem iSupIndep_iff_dfinsuppSumAddHom_injective (p : ι → AddSubgroup N) : .ofBijective _ ⟨ind.dfinsupp_lsum_injective, by rwa [← LinearMap.range_eq_top, ← Submodule.iSup_eq_range_dfinsupp_lsum]⟩ +set_option backward.isDefEq.respectTransparency false in theorem iSupIndep.linearEquiv_symm_apply {p : ι → Submodule R N} (ind : iSupIndep p) (iSup_top : ⨆ i, p i = ⊤) {i : ι} {x : N} (h : x ∈ p i) : (ind.linearEquiv iSup_top).symm x = .single i ⟨x, h⟩ := by diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 7af851413cdd2a..b0f09a2f994ce0 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -250,6 +250,7 @@ theorem det_comp (f g : M →ₗ[A] M) : theorem det_id : LinearMap.det (LinearMap.id : M →ₗ[A] M) = 1 := LinearMap.det.map_one +set_option backward.isDefEq.respectTransparency false in /-- Multiplying a map by a scalar `c` multiplies its determinant by `c ^ dim M`. -/ @[simp] theorem det_smul [Module.Free A M] (c : A) (f : M →ₗ[A] M) : @@ -342,6 +343,7 @@ theorem finite_of_det_ne_one {f : M →ₗ[R] M} (hf : f.det ≠ 1) : Module.Fin exact Module.Finite.of_basis hs · classical simp [LinearMap.coe_det, H] at hf +set_option backward.isDefEq.respectTransparency false in /-- If the determinant of a map vanishes, then the map is not injective. -/ theorem bot_lt_ker_of_det_eq_zero [IsDomain R] [Free R M] {f : M →ₗ[R] M} (hf : f.det = 0) : ⊥ < ker f := by @@ -596,6 +598,7 @@ theorem LinearMap.associated_det_comp_equiv {N : Type*} [AddCommGroup N] [Module namespace Module.Basis set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- The determinant of a family of vectors with respect to some basis, as an alternating multilinear map. -/ nonrec def det : M [⋀^ι]→ₗ[R] R where @@ -735,6 +738,7 @@ theorem det_map' (b : Basis ι R M) (f : M ≃ₗ[R] M') : end Module.Basis +set_option backward.isDefEq.respectTransparency false in @[simp] theorem Pi.basisFun_det : (Pi.basisFun R ι).det = Matrix.detRowAlternating := by ext M diff --git a/Mathlib/LinearAlgebra/Dimension/Basic.lean b/Mathlib/LinearAlgebra/Dimension/Basic.lean index be686d7a739311..f6e875d4f717fc 100644 --- a/Mathlib/LinearAlgebra/Dimension/Basic.lean +++ b/Mathlib/LinearAlgebra/Dimension/Basic.lean @@ -249,6 +249,7 @@ theorem rank_eq_of_equiv_equiv (i : R → R') (j : M ≃+ M₁) end end Semiring +set_option backward.isDefEq.respectTransparency false in /-- TODO: prove that nontrivial commutative semirings satisfy the strong rank condition, following *Free sets and free subsemimodules in a semimodule* by Yi-Jia Tan, Theorem 3.2. diff --git a/Mathlib/LinearAlgebra/Dimension/Constructions.lean b/Mathlib/LinearAlgebra/Dimension/Constructions.lean index 349ee1030152c1..b3f30440e9fa01 100644 --- a/Mathlib/LinearAlgebra/Dimension/Constructions.lean +++ b/Mathlib/LinearAlgebra/Dimension/Constructions.lean @@ -48,6 +48,7 @@ section Quotient variable [Ring R] [CommRing S] [AddCommGroup M] [AddCommGroup M'] [AddCommGroup M₁] variable [Module R M] +set_option backward.isDefEq.respectTransparency false in theorem LinearIndependent.sumElim_of_quotient {M' : Submodule R M} {ι₁ ι₂} {f : ι₁ → M'} (hf : LinearIndependent R f) (g : ι₂ → M) (hg : LinearIndependent R (Submodule.Quotient.mk (p := M') ∘ g)) : @@ -603,6 +604,7 @@ theorem sumQuot_repr_left (i : m) : (sumQuot bW bQ).repr (bW i) = Finsupp.single (Sum.inl i) 1 := by rw [← Module.Basis.apply_eq_iff, sumQuot_inl] +set_option backward.isDefEq.respectTransparency false in theorem sumQuot_repr_inl (w : W) (i : m) : (sumQuot bW bQ).repr w (Sum.inl i) = bW.repr w i := by classical diff --git a/Mathlib/LinearAlgebra/Dimension/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Finite.lean index cd9d8d184ae78d..955efc96d75ad7 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finite.lean @@ -138,7 +138,7 @@ theorem Module.Basis.nonempty_fintype_index_of_rank_lt_aleph0 {ι : Type*} (b : Cardinal.lt_aleph0_iff_fintype] at h /-- If a module has a finite dimension, all bases are indexed by a finite type. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def Module.Basis.fintypeIndexOfRankLtAleph0 {ι : Type*} (b : Basis ι R M) (h : Module.rank R M < ℵ₀) : Fintype ι := Classical.choice (b.nonempty_fintype_index_of_rank_lt_aleph0 h) @@ -266,7 +266,7 @@ theorem iSupIndep.subtype_ne_bot_le_finrank_aux /-- If `p` is an independent family of submodules of an `R`-finite module `M`, then the number of nontrivial subspaces in the family `p` is finite. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def iSupIndep.fintypeNeBotOfFiniteDimensional {p : ι → Submodule R M} (hp : iSupIndep p) : Fintype { i : ι // p i ≠ ⊥ } := by diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index e12364c8698979..151eb9748caf3b 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -349,6 +349,7 @@ theorem _root_.OrzechProperty.bijective_of_surjective_of_finrank_le variable {R : Type*} [CommSemiring R] [StrongRankCondition R] {M : Type*} [AddCommMonoid M] [Module R M] [Module.Free R M] +set_option backward.isDefEq.respectTransparency false in theorem _root_.LinearMap.existsUnique_eq_smul_id_of_finrank_eq_one (d1 : Module.finrank R M = 1) (u : M →ₗ[R] M) : ∃! c : R, u = c • LinearMap.id := by diff --git a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean index 7f8caec8071cfa..b3575ffeac2e2a 100644 --- a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean +++ b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean @@ -187,6 +187,7 @@ theorem exists_linearIndependent_pair_of_one_lt_rank [IsDomain R] [StrongRankCon rw [this] at hy exact ⟨y, hy⟩ +set_option backward.isDefEq.respectTransparency false in theorem Submodule.exists_smul_notMem_of_rank_lt {N : Submodule R M} (h : Module.rank R N < Module.rank R M) : ∃ m : M, ∀ r : R, r ≠ 0 → r • m ∉ N := by have : Module.rank R (M ⧸ N) ≠ 0 := by diff --git a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean index b08f0a89857777..39ddb80fac1a84 100644 --- a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean @@ -495,7 +495,7 @@ theorem rank_of_bijective_algebraMap {R S : Type*} [CommSemiring R] [Semiring S] rw [rank_eq_one_iff_finrank_eq_one, finrank_of_bijective_algebraMap h] /-- Given a basis of a ring over itself indexed by a type `ι`, then `ι` is `Unique`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def _root_.Module.Basis.unique {ι : Type*} (b : Basis ι R R) : Unique ι := by have : Cardinal.mk ι = ↑(Module.finrank R R) := (Module.mk_finrank_eq_card_basis b).symm have : Subsingleton ι ∧ Nonempty ι := by simpa [Cardinal.eq_one_iff_unique] diff --git a/Mathlib/LinearAlgebra/Dimension/Torsion/Basic.lean b/Mathlib/LinearAlgebra/Dimension/Torsion/Basic.lean index 671ecde465226b..4cb0e2591f8aec 100644 --- a/Mathlib/LinearAlgebra/Dimension/Torsion/Basic.lean +++ b/Mathlib/LinearAlgebra/Dimension/Torsion/Basic.lean @@ -24,6 +24,7 @@ public section open Submodule +set_option backward.isDefEq.respectTransparency false in theorem rank_quotient_eq_of_le_torsion {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] {M' : Submodule R M} (hN : M' ≤ torsion R M) : Module.rank R (M ⧸ M') = Module.rank R M := (rank_quotient_le M').antisymm <| by diff --git a/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean b/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean index f9f45ce304e736..d20ee75742b565 100644 --- a/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean +++ b/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean @@ -124,6 +124,7 @@ lemma finsuppRight_symm_apply_single (i : ι) (m : M) (n : N) : m ⊗ₜ[R] Finsupp.single i n := by simp [LinearEquiv.symm_apply_eq] +set_option backward.isDefEq.respectTransparency false in lemma finsuppLeft_smul' (s : S) (t : (ι →₀ M) ⊗[R] N) : finsuppLeft R S M N ι (s • t) = s • finsuppLeft R S M N ι t := by simp @@ -189,6 +190,7 @@ lemma finsuppScalarRight_symm_apply_single (i : ι) (m : M) : m ⊗ₜ[R] (Finsupp.single i 1) := by simp [finsuppScalarRight, finsuppRight_symm_apply_single] +set_option backward.isDefEq.respectTransparency false in theorem finsuppScalarRight_smul (s : S) (t) : finsuppScalarRight R S M ι (s • t) = s • finsuppScalarRight R S M ι t := by simp diff --git a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean index c881518d4189a0..15174666a8cd4d 100644 --- a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean @@ -92,6 +92,7 @@ theorem directSum_symm_lof_tmul (i₁ : ι₁) (m₁ : M₁ i₁) (i₂ : ι₂) (DirectSum.lof S ι₁ M₁ i₁ m₁ ⊗ₜ DirectSum.lof R ι₂ M₂ i₂ m₂) := by rw [LinearEquiv.symm_apply_eq, directSum_lof_tmul_lof] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem directSumLeft_tmul_lof (i : ι₁) (x : M₁ i) (y : M₂') : directSumLeft R S M₁ M₂' (DirectSum.lof S _ _ i x ⊗ₜ[R] y) = @@ -104,6 +105,7 @@ theorem directSumLeft_symm_lof_tmul (i : ι₁) (x : M₁ i) (y : M₂') : DirectSum.lof S _ _ i x ⊗ₜ[R] y := by rw [LinearEquiv.symm_apply_eq, directSumLeft_tmul_lof] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma directSumLeft_tmul (m : ⨁ i, M₁ i) (n : M₂') (i : ι₁) : directSumLeft R S M₁ M₂' (m ⊗ₜ[R] n) i = (m i) ⊗ₜ[R] n := by @@ -116,6 +118,7 @@ lemma directSumLeft_tmul (m : ⨁ i, M₁ i) (n : M₂') (i : ι₁) : · subst hj; simp · simp [DirectSum.component.of, hj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem directSumRight_tmul_lof (x : M₁') (i : ι₂) (y : M₂ i) : directSumRight R S M₁' M₂ (x ⊗ₜ[R] DirectSum.lof R _ _ i y) = @@ -149,6 +152,7 @@ lemma directSumRight_tmul (m : M₁') (n : ⨁ i, M₂ i) (i : ι₂) : variable (S₀ : Type*) [CommSemiring S₀] [Algebra R S₀] [Algebra S₀ S] [Module S₀ M₁'] [IsScalarTower R S₀ M₁'] [IsScalarTower S₀ S M₁'] +set_option backward.isDefEq.respectTransparency false in lemma restrictScalar_directSumRight : (directSumRight R S M₁' M₂).restrictScalars S₀ = directSumRight R S₀ M₁' M₂ := LinearEquiv.restrictScalars_injective R <| LinearEquiv.toLinearMap_injective <| by ext; simp [lof] diff --git a/Mathlib/LinearAlgebra/Dual/BaseChange.lean b/Mathlib/LinearAlgebra/Dual/BaseChange.lean index 5ef30558e89e42..9375d138441363 100644 --- a/Mathlib/LinearAlgebra/Dual/BaseChange.lean +++ b/Mathlib/LinearAlgebra/Dual/BaseChange.lean @@ -84,6 +84,7 @@ theorem toDual_apply (f : Dual R V) : intro v simp [toDual_comp_apply, Algebra.algebraMap_eq_smul_one] +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in /-- The linear map underlying `IsBaseChange.toDualBaseChangeLinearEquiv`. -/ private noncomputable def toDualBaseChangeAux : @@ -98,6 +99,7 @@ private noncomputable def toDualBaseChangeAux : | add x y hx hy => aesop | tmul b f => simp [TensorProduct.smul_tmul', mul_smul] +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in private theorem toDualBaseChangeAux_tmul (a : A) (f : Dual R V) (v : V) : (ibc.toDualBaseChangeAux (a ⊗ₜ[R] f)) (j v) = a * algebraMap R A (f v) := by @@ -133,6 +135,7 @@ theorem toDualBaseChange_tmul (a : A) (f : Dual R V) (v : V) : (ibc.toDualBaseChange (a ⊗ₜ[R] f)) (j v) = a * algebraMap R A (f v) := toDualBaseChangeAux_tmul ibc a f v +set_option backward.isDefEq.respectTransparency false in theorem dual : IsBaseChange A (ibc.toDual) := by apply of_equiv (toDualBaseChange ibc) intro f diff --git a/Mathlib/LinearAlgebra/Dual/Basis.lean b/Mathlib/LinearAlgebra/Dual/Basis.lean index 101f08ef55c396..e6a38da36a96cf 100644 --- a/Mathlib/LinearAlgebra/Dual/Basis.lean +++ b/Mathlib/LinearAlgebra/Dual/Basis.lean @@ -57,6 +57,7 @@ theorem toDual_apply (i j : ι) : b.toDual (b i) (b j) = if i = j then 1 else 0 rw [toDual, constr_basis b, constr_basis b] simp only [eq_comm] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toDual_linearCombination_left (f : ι →₀ R) (i : ι) : b.toDual (Finsupp.linearCombination R b f) (b i) = f i := by @@ -64,6 +65,7 @@ theorem toDual_linearCombination_left (f : ι →₀ R) (i : ι) : simp_rw [map_smul, LinearMap.smul_apply, toDual_apply, smul_eq_mul, mul_boole, Finset.sum_ite_eq', Finsupp.if_mem_support] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toDual_linearCombination_right (f : ι →₀ R) (i : ι) : b.toDual (b i) (Finsupp.linearCombination R b f) = f i := by diff --git a/Mathlib/LinearAlgebra/Dual/Lemmas.lean b/Mathlib/LinearAlgebra/Dual/Lemmas.lean index 0610a58a9d622e..0d17ea7dce9a3c 100644 --- a/Mathlib/LinearAlgebra/Dual/Lemmas.lean +++ b/Mathlib/LinearAlgebra/Dual/Lemmas.lean @@ -163,7 +163,7 @@ universe uK uV variable {K : Type uK} {V : Type uV} variable [CommSemiring K] [AddCommMonoid V] [Module K V] [Projective K V] -open Module Module.Dual Submodule LinearMap Cardinal Basis Module +open Module Module.Dual Submodule LinearMap Cardinal Module section diff --git a/Mathlib/LinearAlgebra/Eigenspace/Basic.lean b/Mathlib/LinearAlgebra/Eigenspace/Basic.lean index 7f2724cb520182..4fe6b984f308d9 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Basic.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Basic.lean @@ -74,6 +74,7 @@ def genEigenspace (f : End R M) (μ : R) : ℕ∞ →o Submodule R M where toFun k := ⨆ l : ℕ, ⨆ _ : l ≤ k, LinearMap.ker ((f - μ • 1) ^ l) monotone' _ _ hkl := biSup_mono fun _ hi ↦ hi.trans hkl +set_option backward.isDefEq.respectTransparency false in lemma mem_genEigenspace {f : End R M} {μ : R} {k : ℕ∞} {x : M} : x ∈ f.genEigenspace μ k ↔ ∃ l : ℕ, l ≤ k ∧ x ∈ LinearMap.ker ((f - μ • 1) ^ l) := by have : Nonempty {l : ℕ // l ≤ k} := ⟨⟨0, zero_le⟩⟩ @@ -105,6 +106,7 @@ lemma genEigenspace_nat {f : End R M} {μ : R} {k : ℕ} : f.genEigenspace μ k = LinearMap.ker ((f - μ • 1) ^ k) := by ext; simp [mem_genEigenspace_nat] +set_option backward.isDefEq.respectTransparency false in lemma genEigenspace_eq_iSup_genEigenspace_nat (f : End R M) (μ : R) (k : ℕ∞) : f.genEigenspace μ k = ⨆ l : {l : ℕ // l ≤ k}, f.genEigenspace μ l := by simp_rw [genEigenspace_nat, genEigenspace, OrderHom.coe_mk, iSup_subtype] @@ -274,6 +276,7 @@ meaningful. -/ noncomputable def maxUnifEigenspaceIndex (f : End R M) (μ : R) := monotonicSequenceLimitIndex <| (f.genEigenspace μ).comp <| WithTop.coeOrderHom.toOrderHom +set_option backward.isDefEq.respectTransparency false in /-- For an endomorphism of a Noetherian module, the maximal eigenspace is always of the form kernel `(f - μ • id) ^ k` for some `k`. -/ lemma genEigenspace_top_eq_maxUnifEigenspaceIndex [IsNoetherian R M] (f : End R M) (μ : R) : @@ -372,6 +375,7 @@ lemma mapsTo_genEigenspace_of_comm {f g : End R M} (h : Commute f g) (μ : R) (k rw [← LinearMap.comp_apply, ← Module.End.mul_eq_comp, h.eq, Module.End.mul_eq_comp, LinearMap.comp_apply, hx, map_zero] +set_option backward.isDefEq.respectTransparency false in /-- The restriction of `f - μ • 1` to the `k`-fold generalized `μ`-eigenspace is nilpotent. -/ lemma isNilpotent_restrict_genEigenspace_nat (f : End R M) (μ : R) (k : ℕ) (h : MapsTo (f - μ • (1 : End R M)) @@ -624,6 +628,7 @@ lemma isNilpotent_restrict_maxGenEigenspace_sub_algebraMap [IsNoetherian R M] (f _ (isNilpotent_restrict_genEigenspace_nat f μ (maxUnifEigenspaceIndex f μ)) rw [maxGenEigenspace_eq] +set_option backward.isDefEq.respectTransparency false in lemma disjoint_genEigenspace [IsDomain R] [IsTorsionFree R M] (f : End R M) {μ₁ μ₂ : R} (hμ : μ₁ ≠ μ₂) (k l : ℕ∞) : Disjoint (f.genEigenspace μ₁ k) (f.genEigenspace μ₂ l) := by @@ -735,6 +740,7 @@ theorem eigenvectors_linearIndependent [IsDomain R] [IsTorsionFree R M] (h_eigenvec : ∀ μ : μs, f.HasEigenvector μ (xs μ)) : LinearIndependent R xs := f.eigenvectors_linearIndependent' (fun μ : μs ↦ μ) Subtype.coe_injective _ h_eigenvec +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` maps a subspace `p` into itself, then the generalized eigenspace of the restriction of `f` to `p` is the part of the generalized eigenspace of `f` that lies in `p`. -/ theorem genEigenspace_restrict (f : End R M) (p : Submodule R M) (k : ℕ∞) (μ : R) @@ -758,6 +764,7 @@ lemma _root_.Submodule.inf_genEigenspace (f : End R M) (p : Submodule R M) {k : (genEigenspace (LinearMap.restrict f hfp) μ k).map p.subtype := by rw [f.genEigenspace_restrict _ _ _ hfp, Submodule.map_comap_eq, Submodule.range_subtype] +set_option backward.isDefEq.respectTransparency false in lemma mapsTo_restrict_maxGenEigenspace_restrict_of_mapsTo {p : Submodule R M} (f g : End R M) (hf : MapsTo f p p) (hg : MapsTo g p p) {μ₁ μ₂ : R} (h : MapsTo f (g.maxGenEigenspace μ₁) (g.maxGenEigenspace μ₂)) : diff --git a/Mathlib/LinearAlgebra/Eigenspace/Matrix.lean b/Mathlib/LinearAlgebra/Eigenspace/Matrix.lean index 37c5aa544d2144..574408a895bcf3 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Matrix.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Matrix.lean @@ -96,6 +96,7 @@ lemma iSup_eigenspace_toLin'_diagonal_eq_top : ⨆ μ, eigenspace (diagonal d).toLin' μ = ⊤ := iSup_eigenspace_toLin_diagonal_eq_top d <| Pi.basisFun R n +set_option backward.isDefEq.respectTransparency false in @[simp] lemma maxGenEigenspace_toLin_diagonal_eq_eigenspace [IsDomain R] : maxGenEigenspace ((diagonal d).toLin b b) μ = eigenspace ((diagonal d).toLin b b) μ := by diff --git a/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean b/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean index e3e6ed43a718f9..404843b420bb82 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean @@ -97,6 +97,7 @@ theorem hasEigenvalue_iff_isRoot : f.HasEigenvalue μ ↔ (minpoly R f).IsRoot variable (f) +set_option backward.isDefEq.respectTransparency.types false in lemma finite_hasEigenvalue : Set.Finite f.HasEigenvalue := by have h : minpoly R f ≠ 0 := minpoly.ne_zero (Algebra.IsIntegral.isIntegral (R := R) f) convert! (minpoly R f).rootSet_finite R @@ -136,6 +137,7 @@ end Module section FiniteSpectrum +set_option backward.isDefEq.respectTransparency.types false in /-- An endomorphism of a finite-dimensional vector space has a finite spectrum. -/ theorem Module.End.finite_spectrum {K : Type v} {V : Type w} [Field K] [AddCommGroup V] [Module K V] [FiniteDimensional K V] (f : Module.End K V) : diff --git a/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean b/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean index 7f0c89b928c95f..d02e0ae0cfd889 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean @@ -36,6 +36,7 @@ namespace Module.End variable {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] {f g : End R M} +set_option backward.isDefEq.respectTransparency.types false in lemma apply_eq_of_mem_of_comm_of_isFinitelySemisimple_of_isNil {μ : R} {k : ℕ∞} {m : M} (hm : m ∈ f.genEigenspace μ k) (hfg : Commute f g) (hss : g.IsFinitelySemisimple) (hnil : IsNilpotent (f - g)) : diff --git a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean index f37aecde29546a..a7b066ae1089a3 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean @@ -142,6 +142,7 @@ namespace Submodule variable {p : Submodule K V} {f : Module.End K V} +set_option backward.isDefEq.respectTransparency.types false in theorem inf_iSup_genEigenspace [FiniteDimensional K V] (h : ∀ x ∈ p, f x ∈ p) (k : ℕ∞) : p ⊓ ⨆ μ, f.genEigenspace μ k = ⨆ μ, p ⊓ f.genEigenspace μ k := by refine le_antisymm (fun m hm ↦ ?_) diff --git a/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean index ec57052dce2f9a..93b76ac702f0dc 100644 --- a/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean @@ -98,6 +98,9 @@ theorem comp_ι_sq_zero (g : ExteriorAlgebra R M →ₐ[R] A) (m : M) : g (ι R variable (R) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition: `cond : ∀ m : M, f m * f m = 0`, this is the canonical lift of `f` to a morphism of `R`-algebras from `ExteriorAlgebra R M` to `A`. diff --git a/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean b/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean index ee7293cc18b41c..871394de762e87 100644 --- a/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean +++ b/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean @@ -179,6 +179,7 @@ noncomputable def relationsSolutionEquiv {ι : Type*} [DecidableEq ι] {M : Type · simp · simpa using f.map_eq_zero_of_eq v hm hij } +set_option backward.isDefEq.respectTransparency.types false in /-- The universal property of the exterior power. -/ noncomputable def isPresentationCore : (relationsSolutionEquiv.symm (ιMulti R n (M := M))).IsPresentationCore where diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index 3cd133e24fcfad..e6cef9228083a7 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -124,6 +124,7 @@ theorem exists_relation_sum_zero_pos_coefficient_of_finrank_succ_lt_card [Finite end +set_option backward.isDefEq.respectTransparency false in /-- In a vector space with dimension 1, each set `{v}` is a basis for `v ≠ 0`. -/ @[simps repr_apply] noncomputable def basisSingleton (ι : Type*) [Unique ι] (h : finrank K V = 1) (v : V) @@ -147,6 +148,7 @@ noncomputable def basisSingleton (ι : Type*) [Unique ι] (h : finrank K V = 1) RingHom.id_apply, smul_eq_mul, Pi.smul_apply] exact mul_div_cancel_right₀ _ h } +set_option backward.isDefEq.respectTransparency false in @[simp] theorem basisSingleton_apply (ι : Type*) [Unique ι] (h : finrank K V = 1) (v : V) (hv : v ≠ 0) (i : ι) : basisSingleton ι h v hv i = v := by @@ -498,7 +500,7 @@ lemma FiniteDimensional.exists_mul_eq_one (F : Type*) {K : Type*} [Field F] [Rin exact this 1 /-- A domain that is module-finite as an algebra over a field is a division ring. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def divisionRingOfFiniteDimensional (F K : Type*) [Field F] [Ring K] [IsDomain K] [Algebra F K] [FiniteDimensional F K] : DivisionRing K where __ := ‹IsDomain K› @@ -519,7 +521,7 @@ lemma FiniteDimensional.isUnit (F : Type*) {K : Type*} [Field F] [Ring K] [IsDom let _ := divisionRingOfFiniteDimensional F K; H.isUnit /-- An integral domain that is module-finite as an algebra over a field is a field. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fieldOfFiniteDimensional (F K : Type*) [Field F] [h : CommRing K] [IsDomain K] [Algebra F K] [FiniteDimensional F K] : Field K := { divisionRingOfFiniteDimensional F K with diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean index 04ec06610c7c8a..36d8240417d671 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean @@ -108,7 +108,7 @@ theorem _root_.Module.Basis.finiteDimensional_of_finite {ι : Type w} [Finite ι Module.Finite.of_basis h /-- If a vector space is `FiniteDimensional`, all bases are indexed by a finite type -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeBasisIndex {ι : Type*} [FiniteDimensional K V] (b : Basis ι K V) : Fintype ι := @Fintype.ofFinite _ (Module.Finite.finite_basis b) diff --git a/Mathlib/LinearAlgebra/FiniteSpan.lean b/Mathlib/LinearAlgebra/FiniteSpan.lean index 97be471f0fb99c..bf11e98548a74e 100644 --- a/Mathlib/LinearAlgebra/FiniteSpan.lean +++ b/Mathlib/LinearAlgebra/FiniteSpan.lean @@ -20,6 +20,7 @@ public section open Set Function open Submodule (span) +set_option backward.isDefEq.respectTransparency false in /-- A linear equivalence which preserves a finite spanning set must have finite order. -/ lemma LinearEquiv.isOfFinOrder_of_finite_of_span_eq_top_of_mapsTo {R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M] diff --git a/Mathlib/LinearAlgebra/Finsupp/LSum.lean b/Mathlib/LinearAlgebra/Finsupp/LSum.lean index 8c750fbab1c821..d910e7ca703258 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LSum.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LSum.lean @@ -89,6 +89,7 @@ section LSum variable (S) variable [Module S N] [SMulCommClass R₂ S N] +set_option backward.isDefEq.respectTransparency false in /-- Lift a family of linear maps `M →ₗ[R] N` indexed by `x : α` to a linear map from `α →₀ M` to `N` using `Finsupp.sum`. This is an upgraded version of `Finsupp.liftAddHom`. diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index 758052df68067c..23015192aed5a0 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -250,6 +250,7 @@ theorem linearCombinationOn_range (s : Set α) : range_subtype] exact (span_image_eq_map_linearCombination _ _).le +set_option backward.isDefEq.respectTransparency false in theorem linearCombination_restrict (s : Set α) : linearCombination R (s.restrict v) = Submodule.subtype _ ∘ₗ linearCombinationOn α M R v s ∘ₗ (supportedEquivFinsupp s).symm.toLinearMap := by diff --git a/Mathlib/LinearAlgebra/Finsupp/Pi.lean b/Mathlib/LinearAlgebra/Finsupp/Pi.lean index b182855f479a7b..e7b6192a1346f1 100644 --- a/Mathlib/LinearAlgebra/Finsupp/Pi.lean +++ b/Mathlib/LinearAlgebra/Finsupp/Pi.lean @@ -62,6 +62,7 @@ theorem LinearEquiv.finsuppUnique_apply (α : Type*) [Unique α] (f : α →₀ LinearEquiv.finsuppUnique R M α f = f default := rfl +set_option backward.isDefEq.respectTransparency.types false in @[deprecated uniqueLinearEquiv_symm_apply (since := "2026-05-06")] theorem LinearEquiv.finsuppUnique_symm_apply (α : Type*) [Unique α] (m : M) : (LinearEquiv.finsuppUnique R M α).symm m = Finsupp.single default m := by diff --git a/Mathlib/LinearAlgebra/Finsupp/Supported.lean b/Mathlib/LinearAlgebra/Finsupp/Supported.lean index 49591e6219a67a..cf21dbf21d1e89 100644 --- a/Mathlib/LinearAlgebra/Finsupp/Supported.lean +++ b/Mathlib/LinearAlgebra/Finsupp/Supported.lean @@ -190,6 +190,9 @@ lemma codisjoint_supported_supported_iff [Nontrivial M] {s t : Set α} : rw [codisjoint_iff, ← supported_union, eq_top_iff'] at h simpa [Finsupp.mem_supported, Finsupp.support_single _ hx] using h (Finsupp.single a x) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Interpret `Finsupp.restrictSupportEquiv` as a linear equivalence between `supported M R s` and `s →₀ M`. -/ @[simps!] def supportedEquivFinsupp (s : Set α) : supported M R s ≃ₗ[R] s →₀ M := by diff --git a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean index a0d45d69e07794..e41fa3e544a4f6 100644 --- a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean @@ -147,6 +147,7 @@ lemma linearIndependent_single_of_ne_zero [IsDomain R] [Module R M] [IsTorsionFr rw [← linearIndependent_equiv (Equiv.sigmaPUnit ι)] exact linearIndependent_single (f := fun i (_ : Unit) ↦ v i) <| by simp +contextual [hv] +set_option backward.isDefEq.respectTransparency false in lemma lcomapDomain_eq_linearProjOfIsCompl {α β : Type*} {u : α → ι} {v : β → ι} (hu : u.Injective) (h : IsCompl (Set.range u) (Set.range v)) : lcomapDomain u hu = diff --git a/Mathlib/LinearAlgebra/FixedSubmodule.lean b/Mathlib/LinearAlgebra/FixedSubmodule.lean index 7c2f16459b9abf..95824678c59e01 100644 --- a/Mathlib/LinearAlgebra/FixedSubmodule.lean +++ b/Mathlib/LinearAlgebra/FixedSubmodule.lean @@ -104,6 +104,7 @@ theorem map_eq_of_mem_fixingSubgroup (W : Submodule R V) variable {R V : Type*} [Ring R] [AddCommGroup V] [Module R V] +set_option backward.isDefEq.respectTransparency false in /-- When `u : V ≃ₗ[R] V` maps a submodule `W` into itself, this is the induced linear equivalence of `V ⧸ W`, as a group homomorphism. -/ def reduce (W : Submodule R V) : stabilizer (V ≃ₗ[R] V) W →* (V ⧸ W) ≃ₗ[R] (V ⧸ W) where diff --git a/Mathlib/LinearAlgebra/FreeModule/Basic.lean b/Mathlib/LinearAlgebra/FreeModule/Basic.lean index 37d796cf745408..5bfdafe4fd012b 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Basic.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Basic.lean @@ -179,6 +179,7 @@ open Finset variable {S : Type*} [CommRing R] [Ring S] [Algebra R S] +set_option backward.isDefEq.respectTransparency false in variable {R} in /-- If `B` is a basis of the `R`-algebra `S` such that `B i = 1` for some index `i`, then each `r : R` gets represented as `s • B i` as an element of `S`. -/ diff --git a/Mathlib/LinearAlgebra/FreeModule/Finite/CardQuotient.lean b/Mathlib/LinearAlgebra/FreeModule/Finite/CardQuotient.lean index 49c112d32c4a6e..d553504c27f687 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Finite/CardQuotient.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Finite/CardQuotient.lean @@ -110,6 +110,7 @@ theorem AddSubgroup.relIndex_eq_natAbs_det {E : Type*} [AddCommGroup E] rw [relIndex, index_eq_natAbs_det b₂ _ (b₁.map (addSubgroupOfEquivOfLe H).toIntLinearEquiv.symm)] rfl +set_option backward.isDefEq.respectTransparency false in theorem AddSubgroup.relIndex_eq_abs_det {E : Type*} [AddCommGroup E] [Module ℚ E] (L₁ L₂ : AddSubgroup E) (H : L₁ ≤ L₂) {ι : Type*} [DecidableEq ι] [Fintype ι] (b₁ b₂ : Basis ι ℚ E) (h₁ : L₁ = .closure (Set.range b₁)) (h₂ : L₂ = .closure (Set.range b₂)) : diff --git a/Mathlib/LinearAlgebra/FreeModule/Int.lean b/Mathlib/LinearAlgebra/FreeModule/Int.lean index f48d41c34c3581..4edf34a66dda0f 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Int.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Int.lean @@ -26,6 +26,7 @@ namespace Module.Basis.SmithNormalForm variable [Fintype ι] +set_option backward.isDefEq.respectTransparency false in /-- Given a submodule `N` in Smith normal form of a free `R`-module, its index as an additive subgroup is an appropriate power of the cardinality of `R` multiplied by the product of the indexes of the ideals generated by each basis vector. -/ diff --git a/Mathlib/LinearAlgebra/FreeModule/PID.lean b/Mathlib/LinearAlgebra/FreeModule/PID.lean index fc285a3509f0c2..b58768eebeccdd 100644 --- a/Mathlib/LinearAlgebra/FreeModule/PID.lean +++ b/Mathlib/LinearAlgebra/FreeModule/PID.lean @@ -138,6 +138,7 @@ theorem generator_maximal_submoduleImage_dvd {N O : Submodule R M} (hNO : N ≤ variable [IsDomain R] +set_option backward.isDefEq.respectTransparency false in /-- The induction hypothesis of `Submodule.basisOfPid` and `Submodule.smithNormalForm`. Basically, it says: let `N ≤ M` be a pair of submodules, then we can find a pair of @@ -421,6 +422,7 @@ namespace Module.Basis.SmithNormalForm variable {n : ℕ} {N : Submodule R M} (snf : Basis.SmithNormalForm N ι n) (m : N) +set_option backward.isDefEq.respectTransparency false in lemma repr_eq_zero_of_notMem_range {i : ι} (hi : i ∉ Set.range snf.f) : snf.bM.repr m i = 0 := by obtain ⟨m, hm⟩ := m @@ -432,6 +434,7 @@ lemma le_ker_coord_of_notMem_range {i : ι} (hi : i ∉ Set.range snf.f) : N ≤ LinearMap.ker (snf.bM.coord i) := fun m hm ↦ snf.repr_eq_zero_of_notMem_range ⟨m, hm⟩ hi +set_option backward.isDefEq.respectTransparency false in @[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} : snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by obtain ⟨m, hm⟩ := m @@ -447,11 +450,13 @@ lemma le_ker_coord_of_notMem_range {i : ι} (hi : i ∉ Set.range snf.f) : Finsupp.mem_support_iff, ite_not, mul_comm, ite_eq_right_iff] exact fun a ↦ (mul_eq_zero_of_right _ a).symm +set_option backward.isDefEq.respectTransparency false in @[simp] lemma repr_comp_embedding_eq_smul : snf.bM.repr m ∘ snf.f = snf.a • (snf.bN.repr m : Fin n → R) := by ext i simp [Pi.smul_apply (snf.a i)] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma coord_apply_embedding_eq_smul_coord {i : Fin n} : snf.bM.coord (snf.f i) ∘ₗ N.subtype = snf.a i • snf.bN.coord i := by ext m diff --git a/Mathlib/LinearAlgebra/FreeProduct/Basic.lean b/Mathlib/LinearAlgebra/FreeProduct/Basic.lean index 80a143e85978c8..8747934312fe3d 100644 --- a/Mathlib/LinearAlgebra/FreeProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/FreeProduct/Basic.lean @@ -187,6 +187,7 @@ irreducible_def ι (i : I) : A i →ₐ[R] FreeProduct R A := /-- The family of canonical injection maps, with `i` left implicit -/ irreducible_def of {i : I} : A i →ₐ[R] FreeProduct R A := ι R A i +set_option backward.isDefEq.respectTransparency false in /-- Universal property of the free product of algebras: for every `R`-algebra `B`, every family of maps `maps : (i : I) → (A i →ₐ[R] B)` lifts to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. -/ @@ -206,6 +207,7 @@ to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. ext i a simp [ι, ← ι_apply] +set_option backward.isDefEq.respectTransparency false in /-- Universal property of the free product of algebras, property: for every `R`-algebra `B`, every family of maps `maps : (i : I) → (A i →ₐ[R] B)` lifts to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. -/ @@ -216,6 +218,7 @@ to a unique arrow `π` from `FreeProduct R A` such that `π ∘ ι i = maps i`. @[simp↓] theorem lift_algebraMap (r : R) : lift R A maps (algebraMap R _ r) = algebraMap R _ r := by rw [lift_apply, AlgHom.commutes] +set_option backward.isDefEq.respectTransparency false in @[aesop safe destruct] theorem lift_unique (f : FreeProduct R A →ₐ[R] B) (h : ∀ i, f ∘ₐ ι R A i = maps) : f = lift R A maps := by diff --git a/Mathlib/LinearAlgebra/GeneralLinearGroup/AlgEquiv.lean b/Mathlib/LinearAlgebra/GeneralLinearGroup/AlgEquiv.lean index fa47df6f0fe93a..27ba036b5d0b88 100644 --- a/Mathlib/LinearAlgebra/GeneralLinearGroup/AlgEquiv.lean +++ b/Mathlib/LinearAlgebra/GeneralLinearGroup/AlgEquiv.lean @@ -28,6 +28,7 @@ open Module LinearMap LinearEquiv variable {K V W : Type*} [Semifield K] [AddCommMonoid V] [Module K V] [Projective K V] [AddCommMonoid W] [Module K W] [Projective K W] +set_option backward.isDefEq.respectTransparency false in /-- Given an algebra isomorphism `f : End K V ≃ₐ[K] End K W`, there exists a linear isomorphism `T` such that `f` is given by `x ↦ T ∘ₗ x ∘ₗ T.symm`. -/ public theorem AlgEquiv.eq_linearEquivConjAlgEquiv (f : End K V ≃ₐ[K] End K W) : diff --git a/Mathlib/LinearAlgebra/Isomorphisms.lean b/Mathlib/LinearAlgebra/Isomorphisms.lean index 1433a483660ca4..8c444e99302158 100644 --- a/Mathlib/LinearAlgebra/Isomorphisms.lean +++ b/Mathlib/LinearAlgebra/Isomorphisms.lean @@ -157,6 +157,7 @@ namespace Submodule variable (S T : Submodule R M) (h : S ≤ T) +set_option backward.isDefEq.respectTransparency false in /-- The map from the third isomorphism theorem for modules: `(M / S) / (T / S) → M / T`. -/ def quotientQuotientEquivQuotientAux (h : S ≤ T) : (M ⧸ S) ⧸ T.map S.mkQ →ₗ[R] M ⧸ T := liftQ _ (mapQ S T LinearMap.id h) @@ -175,6 +176,7 @@ theorem quotientQuotientEquivQuotientAux_mk (x : M ⧸ S) : theorem quotientQuotientEquivQuotientAux_mk_mk (x : M) : quotientQuotientEquivQuotientAux S T h (Quotient.mk (Quotient.mk x)) = Quotient.mk x := rfl +set_option backward.isDefEq.respectTransparency false in /-- **Noether's third isomorphism theorem** for modules: `(M / S) / (T / S) ≃ M / T`. -/ def quotientQuotientEquivQuotient : ((M ⧸ S) ⧸ T.map S.mkQ) ≃ₗ[R] M ⧸ T := { quotientQuotientEquivQuotientAux S T h with diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean b/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean index fb44bd661aa109..ac10dd3c7f1ea0 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Basic.lean @@ -294,6 +294,7 @@ theorem surjective_of_linearIndependent_of_span [Nontrivial R] (hv : LinearIndep use i' exact hi'.2 +set_option backward.isDefEq.respectTransparency false in theorem eq_of_linearIndepOn_id_of_span_subtype [Nontrivial R] {s t : Set M} (hs : LinearIndepOn R id s) (h : t ⊆ s) (hst : s ⊆ span R t) : s = t := by let f : t ↪ s := diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean index b44f5c5518aaf4..67806c70471732 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean @@ -298,6 +298,7 @@ theorem linearIndependent_iff_finset_linearIndependent : Fintype.linearIndependent_iffₛ.1 (H s) (f ∘ Subtype.val) (g ∘ Subtype.val) (by simpa only [← s.sum_coe_sort] using! eq) ⟨i, hi⟩⟩ +set_option backward.isDefEq.respectTransparency false in lemma linearIndepOn_iff_linearIndepOn_finset : LinearIndepOn R v s ↔ ∀ t : Finset ι, ↑t ⊆ s → LinearIndepOn R v t where mp hv t hts := hv.mono hts @@ -663,6 +664,7 @@ theorem Fintype.not_linearIndependent_iffₒₛ [DecidableEq ι] [Fintype ι] : · refine ⟨tᶜ, f, ?_, i, Finset.mem_compl.2 hi', hfi⟩ simp [heq] +set_option backward.isDefEq.respectTransparency false in lemma linearIndepOn_finset_iffₒₛ [DecidableEq ι] {s : Finset ι} : LinearIndepOn R v s ↔ ∀ t ⊆ s, ∀ (f : ι → R), ∑ i ∈ t, f i • v i = ∑ i ∈ s \ t, f i • v i → ∀ i ∈ s, f i = 0 := by diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean index a9d6c3a893e3fb..300b8a01f365c2 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean @@ -491,6 +491,7 @@ lemma linearIndependent_algHom_toLinearMap' (K M L) [CommRing K] [IsDomain K] LinearIndependent K (AlgHom.toLinearMap : (M →ₐ[K] L) → M →ₗ[K] L) := (linearIndependent_algHom_toLinearMap K M L).restrict_scalars' K +set_option backward.isDefEq.respectTransparency false in lemma LinearMap.injective_of_linearIndependent {N : Type*} [AddCommGroup N] [Module R N] {f : M →ₗ[R] N} {ι : Type*} {v : ι → M} (hv : Submodule.span R (.range v) = ⊤) (hli : LinearIndependent R (f ∘ v)) : diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index 236586e4664d36..b314e097a396a6 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -542,6 +542,7 @@ theorem domain_supSpanSingleton (f : E →ₛₗ.[σ] F) (x : E) (y : F) (hx : x (f.supSpanSingleton x y hx).domain = f.domain ⊔ K ∙ x := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem supSpanSingleton_apply_mk (f : E →ₛₗ.[σ] F) (x : E) (y : F) (hx : x ∉ f.domain) (x' : E) (hx' : x' ∈ f.domain) (c : K) : @@ -565,6 +566,7 @@ theorem supSpanSingleton_apply_self (f : E →ₛₗ.[σ] F) {x : E} (y : F) (hx f.supSpanSingleton x y hx ⟨x, mem_sup_right <| mem_span_singleton_self _⟩ = y := by simpa using supSpanSingleton_apply_smul_self f y hx 1 +set_option backward.isDefEq.respectTransparency.types false in theorem supSpanSingleton_apply_of_mem (f : E →ₛₗ.[σ] F) {x : E} (y : F) (hx : x ∉ f.domain) (x' : (f.supSpanSingleton x y hx).domain) (hx' : (x' : E) ∈ f.domain) : f.supSpanSingleton x y hx x' = f ⟨x', hx'⟩ := by @@ -965,6 +967,7 @@ theorem mem_graph_toLinearPMap {g : Submodule R (E × F)} rw [toLinearPMap_apply_aux hg] exact valFromGraph_mem hg x.2 +set_option backward.isDefEq.respectTransparency false in @[simp] theorem toLinearPMap_graph_eq (g : Submodule R (E × F)) (hg : ∀ (x : E × F) (_hx : x ∈ g) (_hx' : x.fst = 0), x.snd = 0) : diff --git a/Mathlib/LinearAlgebra/Matrix/Basis.lean b/Mathlib/LinearAlgebra/Matrix/Basis.lean index 39fe6645ead7f2..b1078913d0f0b9 100644 --- a/Mathlib/LinearAlgebra/Matrix/Basis.lean +++ b/Mathlib/LinearAlgebra/Matrix/Basis.lean @@ -83,6 +83,7 @@ theorem toMatrix_update [DecidableEq ι'] (x : M) : · rw [h, update_self j x v] · rw [update_of_ne h] +set_option backward.isDefEq.respectTransparency false in /-- The basis constructed by `unitsSMul` has vectors given by a diagonal matrix. -/ @[simp] theorem toMatrix_unitsSMul [DecidableEq ι] (e : Basis ι R₂ M₂) (w : ι → R₂ˣ) : @@ -255,7 +256,7 @@ theorem toMatrix_mul_toMatrix_flip [DecidableEq ι] [Fintype ι'] : b.toMatrix b' * b'.toMatrix b = 1 := by rw [toMatrix_mul_toMatrix, toMatrix_self] /-- A matrix whose columns form a basis `b'`, expressed w.r.t. a basis `b`, is invertible. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleToMatrix [DecidableEq ι] [Fintype ι] (b b' : Basis ι R₂ M₂) : Invertible (b.toMatrix b') := ⟨b'.toMatrix b, toMatrix_mul_toMatrix_flip _ _, toMatrix_mul_toMatrix_flip _ _⟩ diff --git a/Mathlib/LinearAlgebra/Matrix/Block.lean b/Mathlib/LinearAlgebra/Matrix/Block.lean index 8778b6bd5c30d8..b5c4fdb43f8c23 100644 --- a/Mathlib/LinearAlgebra/Matrix/Block.lean +++ b/Mathlib/LinearAlgebra/Matrix/Block.lean @@ -375,7 +375,7 @@ theorem BlockTriangular.inv_toBlock [LinearOrder α] [Invertible M] (hM : BlockT inv_eq_left_inv <| hM.toBlock_inverse_mul_toBlock_eq_one k /-- An upper-left subblock of an invertible block-triangular matrix is invertible. -/ -@[implicit_reducible] +@[instance_reducible] def BlockTriangular.invertibleToBlock [LinearOrder α] [Invertible M] (hM : BlockTriangular M b) (k : α) : Invertible (M.toBlock (fun i => b i < k) fun i => b i < k) := invertibleOfLeftInverse _ ((⅟M).toBlock (fun i => b i < k) fun i => b i < k) <| by diff --git a/Mathlib/LinearAlgebra/Matrix/Cartan.lean b/Mathlib/LinearAlgebra/Matrix/Cartan.lean index deafc0acc08bcd..c0fe19186c6bf3 100644 --- a/Mathlib/LinearAlgebra/Matrix/Cartan.lean +++ b/Mathlib/LinearAlgebra/Matrix/Cartan.lean @@ -272,6 +272,7 @@ proof_wanted E₈_det : E₈.det = 1 def _root_.Matrix.IsSimplyLaced {ι : Type*} (A : Matrix ι ι ℤ) : Prop := Pairwise fun i j ↦ A i j = 0 ∨ A i j = -1 +set_option backward.isDefEq.respectTransparency.types false in instance {ι : Type*} [Fintype ι] [DecidableEq ι] : DecidablePred (Matrix.IsSimplyLaced (ι := ι)) := inferInstanceAs <| DecidablePred fun A : Matrix ι ι ℤ ↦ ∀ ⦃i j : ι⦄, i ≠ j → (fun i j ↦ A i j = 0 ∨ A i j = -1) i j @@ -302,12 +303,15 @@ theorem isSimplyLaced_D (n : ℕ) : IsSimplyLaced (D n) := by simp only [D, of_apply] grind +set_option backward.isDefEq.respectTransparency.types false in theorem isSimplyLaced_E₆ : IsSimplyLaced E₆ := by rw [Matrix.isSimplyLaced_iff_of_linearOrder E₆ E₆_isSymm]; decide +set_option backward.isDefEq.respectTransparency.types false in theorem isSimplyLaced_E₇ : IsSimplyLaced E₇ := by rw [Matrix.isSimplyLaced_iff_of_linearOrder E₇ E₇_isSymm]; decide +set_option backward.isDefEq.respectTransparency.types false in theorem isSimplyLaced_E₈ : IsSimplyLaced E₈ := by rw [Matrix.isSimplyLaced_iff_of_linearOrder E₈ E₈_isSymm]; decide diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean index 5602a769f817b8..1e7c44ff6851be 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean @@ -393,6 +393,7 @@ lemma det_piecewise_one_eq_submatrix_det · simp only [Finset.piecewise, if_neg i.prop, Matrix.one_apply, Subtype.ext_iff] rw [h_blocks, Matrix.det_fromBlocks_zero₂₁, Matrix.det_one, mul_one] +set_option backward.isDefEq.respectTransparency.types false in /-- The k-th coefficient of `det (1 + X • M)` equals the sum of all k×k principal minors of M. This generalizes `coeff_det_one_add_X_smul_one` (the k = 1 case, which gives the trace) and `det_eq_sign_charpoly_coeff` (the k = n case, which gives the determinant). -/ diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean index 40eface05904fd..7a1cfad31cccbe 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean @@ -607,6 +607,7 @@ theorem det_eq_of_forall_col_eq_smul_add_pred {n : ℕ} {A B : Matrix (Fin (n + end DetEq +set_option backward.isDefEq.respectTransparency false in @[simp] theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Matrix n n R) : (blockDiagonal M).det = ∏ k, (M k).det := by @@ -666,6 +667,7 @@ theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Mat rw [blockDiagonal_apply_ne] exact hkx +set_option backward.isDefEq.respectTransparency false in /-- The determinant of a 2×2 block matrix with the lower-left block equal to zero is the product of the determinants of the diagonal blocks. For the generalization to any number of blocks, see `Matrix.det_of_upperTriangular`. -/ diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean index c075db0faa1a25..69de68bcf32c58 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean @@ -22,6 +22,7 @@ namespace Matrix variable {R : Type*} [CommRing R] +set_option backward.isDefEq.respectTransparency false in /-- Let `M` be a `(n+1) × n` matrix whose row sums to zero. Then all the matrices obtained by deleting one row have the same determinant up to a sign. -/ theorem submatrix_succAbove_det_eq_negOnePow_submatrix_succAbove_det {n : ℕ} @@ -52,6 +53,7 @@ theorem submatrix_succAbove_det_eq_negOnePow_submatrix_succAbove_det {n : ℕ} Fin.succAbove_of_succ_le _ _ (Fin.succ_lt_succ_iff.mpr h).le] · rw [Fin.succAbove_succ_of_lt _ _ h, Fin.succAbove_castSucc_of_le _ _ h.le] +set_option backward.isDefEq.respectTransparency false in /-- Let `M` be a `(n+1) × n` matrix whose column sums to zero. Then all the matrices obtained by deleting one column have the same determinant up to a sign. -/ theorem submatrix_succAbove_det_eq_negOnePow_submatrix_succAbove_det' {n : ℕ} @@ -64,6 +66,7 @@ theorem submatrix_succAbove_det_eq_negOnePow_submatrix_succAbove_det' {n : ℕ} ext simp_rw [Finset.sum_apply, transpose_apply, hv, Pi.zero_apply] +set_option backward.isDefEq.respectTransparency false in /-- Let `M` be a `(n+1) × (n+1)` matrix. Assume that all columns, but the `j₀`-column, sums to zero. Then its determinant is, up to sign, the sum of the `j₀`-column times the determinant of the matrix obtained by deleting any row and the `j₀`-column. -/ diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/TotallyUnimodular.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/TotallyUnimodular.lean index 26dda03ca30597..722bcfe58c88a3 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/TotallyUnimodular.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/TotallyUnimodular.lean @@ -102,6 +102,7 @@ lemma reindex_isTotallyUnimodular (A : Matrix m n R) (em : m ≃ m') (en : n ≃ ⟨fun hA => by simpa [Equiv.symm_apply_eq] using hA.reindex em.symm en.symm, fun hA => hA.reindex _ _⟩ +set_option backward.isDefEq.respectTransparency false in /-- If `A` has no rows, then it is totally unimodular. -/ @[simp] lemma emptyRows_isTotallyUnimodular [IsEmpty m] (A : Matrix m n R) : @@ -117,6 +118,7 @@ lemma emptyCols_isTotallyUnimodular [IsEmpty n] (A : Matrix m n R) : A.IsTotallyUnimodular := A.transpose.emptyRows_isTotallyUnimodular.transpose +set_option backward.isDefEq.respectTransparency false in /-- If `A` is totally unimodular and each row of `B` is all zeros except for at most a single `1` or a single `-1` then `fromRows A B` is totally unimodular. -/ lemma IsTotallyUnimodular.fromRows_unitlike [DecidableEq n] {A : Matrix m n R} {B : Matrix m' n R} diff --git a/Mathlib/LinearAlgebra/Matrix/Dual.lean b/Mathlib/LinearAlgebra/Matrix/Dual.lean index 869b2e3ad83f1a..7cca7027e5c97e 100644 --- a/Mathlib/LinearAlgebra/Matrix/Dual.lean +++ b/Mathlib/LinearAlgebra/Matrix/Dual.lean @@ -45,6 +45,7 @@ theorem Matrix.toLin_transpose (M : Matrix ι₁ ι₂ K) : Matrix.toLin B₁.du end Transpose +set_option backward.isDefEq.respectTransparency false in /-- The dot product as a linear equivalence to the dual. -/ @[simps] def dotProductEquiv (R n : Type*) [CommSemiring R] [Fintype n] [DecidableEq n] : (n → R) ≃ₗ[R] Module.Dual R (n → R) where diff --git a/Mathlib/LinearAlgebra/Matrix/DualNumber.lean b/Mathlib/LinearAlgebra/Matrix/DualNumber.lean index 38cf082d72fc1e..ca0f726a52a1e0 100644 --- a/Mathlib/LinearAlgebra/Matrix/DualNumber.lean +++ b/Mathlib/LinearAlgebra/Matrix/DualNumber.lean @@ -22,6 +22,7 @@ variable {R n : Type} [CommSemiring R] [Fintype n] [DecidableEq n] open Matrix TrivSqZeroExt +set_option backward.isDefEq.respectTransparency.types false in /-- Matrices over dual numbers and dual numbers over matrices are isomorphic. -/ @[simps] def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where diff --git a/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean b/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean index 3eae7751699643..8278edc557a2b2 100644 --- a/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean +++ b/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean @@ -51,6 +51,7 @@ lemma smul_def (m : R) (g : SpecialLinearGroup n R) (A : (FixedDetMatrix n R m)) g • A = ⟨g * A.1, by simp only [det_mul, SpecialLinearGroup.det_coe, A.2, one_mul]⟩ := rfl +set_option backward.isDefEq.respectTransparency false in instance (m : R) : MulAction (SpecialLinearGroup n R) (FixedDetMatrix n R m) where one_smul b := by rw [smul_def]; simp only [coe_one, one_mul, Subtype.coe_eta] mul_smul x y b := by simp_rw [smul_def, ← mul_assoc, coe_mul] @@ -164,6 +165,7 @@ noncomputable instance repsFintype (k : ℤ) : Fintype (reps k) := by ext i j simpa only [Subtype.mk.injEq] using congrFun₂ h i j +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma S_smul_four (A : Δ m) : S • S • S • S • A = A := by simp only [smul_def, ← mul_assoc, S_mul_S_eq, neg_mul, one_mul, mul_neg, neg_neg, Subtype.coe_eta] @@ -172,6 +174,7 @@ lemma S_smul_four (A : Δ m) : S • S • S • S • A = A := by lemma T_S_rel_smul (A : Δ m) : S • S • S • T • S • T • S • A = T⁻¹ • A := by simp_rw [← T_S_rel, ← smul_assoc] +set_option backward.isDefEq.respectTransparency false in lemma reduce_mem_reps {m : ℤ} (hm : m ≠ 0) (A : Δ m) : reduce A ∈ reps m := by induction A using reduce_rec with | step A h1 h2 => simpa only [reduce_reduceStep h1] using h2 diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean index d7cc42e2829ffb..5c0491c465b522 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean @@ -121,6 +121,7 @@ lemma toPGL_injective : Function.Injective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := QuotientGroup.injective_lift_iff _ _ _ |>.2 toPGL_ker.symm +set_option backward.isDefEq.respectTransparency.types false in lemma toPGL_surj_of_roots (hR : ∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r) : Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun g ↦ by @@ -197,7 +198,7 @@ theorem lift_comp_mk {f : GL n R →* M} (hf) : (lift f hf).comp mk = f := by /-- Given an action of `GL n R` such that the scalar matrices act trivially, define an action of `PGL n R`. -/ -@[implicit_reducible] +@[instance_reducible] def mulActionOfGL {α : Type*} [MulAction (GL n R) α] (h : ∀ (u : Rˣ) (a : α), GeneralLinearGroup.scalar n u • a = a) : MulAction (PGL(n, R)) α := diff --git a/Mathlib/LinearAlgebra/Matrix/Hadamard.lean b/Mathlib/LinearAlgebra/Matrix/Hadamard.lean index 084efc89a15b7e..2eb9a3e4f0cd1f 100644 --- a/Mathlib/LinearAlgebra/Matrix/Hadamard.lean +++ b/Mathlib/LinearAlgebra/Matrix/Hadamard.lean @@ -193,6 +193,7 @@ variable (R) [NonUnitalSemiring α] theorem sum_hadamard_eq : (∑ i : m, ∑ j : n, (A ⊙ B) i j) = trace (A * Bᵀ) := rfl +set_option backward.isDefEq.respectTransparency false in theorem dotProduct_vecMul_hadamard [DecidableEq m] [DecidableEq n] (v : m → α) (w : n → α) : v ᵥ* (A ⊙ B) ⬝ᵥ w = trace (diagonal v * A * (B * diagonal w)ᵀ) := by rw [← sum_hadamard_eq, Finset.sum_comm] diff --git a/Mathlib/LinearAlgebra/Matrix/InvariantBasisNumber.lean b/Mathlib/LinearAlgebra/Matrix/InvariantBasisNumber.lean index 7fc5956245a24c..ff223f9dc9ef87 100644 --- a/Mathlib/LinearAlgebra/Matrix/InvariantBasisNumber.lean +++ b/Mathlib/LinearAlgebra/Matrix/InvariantBasisNumber.lean @@ -53,6 +53,7 @@ theorem invariantBasisNumber_iff_matrix : InvariantBasisNumber R ↔ ∀ n m h (toLinearEquivRight'OfInv hfg hgf).symm) fun h n m e ↦ h n m (toMatrixRight' e) (toMatrixRight' e.symm) (by simp [← toMatrixRight'_comp]) (by simp [← toMatrixRight'_comp]) +set_option backward.isDefEq.respectTransparency false in /-- The rank condition is left-right symmetric. Note that the strong rank condition is not left-right symmetric, see Remark (1.32) in §1.1D of [lam_1999]. -/ protected theorem MulOpposite.rankCondition_iff : RankCondition Rᵐᵒᵖ ↔ RankCondition R := by @@ -66,6 +67,7 @@ protected theorem MulOpposite.rankCondition_iff : RankCondition Rᵐᵒᵖ ↔ R · ext; simp [map, mul_apply] · simp +set_option backward.isDefEq.respectTransparency false in /-- Invariant basis number is left-right symmetric. -/ protected theorem MulOpposite.invariantBasisNumber_iff : InvariantBasisNumber Rᵐᵒᵖ ↔ InvariantBasisNumber R := by diff --git a/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean index 58c6e2d0a85b46..cfc7d06e3e74c7 100644 --- a/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Irreducible/Defs.lean @@ -73,7 +73,7 @@ variable {n R : Type*} [Ring R] [LinearOrder R] /-- The directed graph (quiver) associated with a matrix `A`, with an edge `i ⟶ j` iff `0 < A i j`. -/ -@[implicit_reducible] +@[instance_reducible] def toQuiver (A : Matrix n n R) : Quiver n := ⟨fun i j => PLift (0 < A i j)⟩ @@ -201,6 +201,7 @@ def transposePath {i j : n} (p : @Quiver.Path n A.toQuiver i j) : exact (@Quiver.Path.comp n (toQuiver Aᵀ) c b i (@Quiver.Hom.toPath n (toQuiver Aᵀ) c b (PLift.up eT)) ih) +set_option backward.isDefEq.respectTransparency false in /-- Irreducibility is invariant under transpose. -/ theorem IsIrreducible.transpose (hA : IsIrreducible A) : IsIrreducible Aᵀ := by have hA_T_nonneg : ∀ i j, 0 ≤ Aᵀ i j := fun i j => by diff --git a/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean b/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean index 3daaf66b9fea83..b3ea61392d1cea 100644 --- a/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/NonsingularInverse.lean @@ -75,7 +75,7 @@ variable [Fintype n] [DecidableEq n] [CommRing α] variable (A : Matrix n n α) (B : Matrix n n α) /-- If `A.det` has a constructive inverse, produce one for `A`. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfDetInvertible [Invertible A.det] : Invertible A where invOf := ⅟A.det • A.adjugate mul_invOf_self := by @@ -88,21 +88,21 @@ theorem invOf_eq [Invertible A.det] [Invertible A] : ⅟A = ⅟A.det • A.adjug convert! (rfl : ⅟A = _) /-- `A.det` is invertible if `A` has a left inverse. -/ -@[implicit_reducible] +@[instance_reducible] def detInvertibleOfLeftInverse (h : B * A = 1) : Invertible A.det where invOf := B.det mul_invOf_self := by rw [mul_comm, ← det_mul, h, det_one] invOf_mul_self := by rw [← det_mul, h, det_one] /-- `A.det` is invertible if `A` has a right inverse. -/ -@[implicit_reducible] +@[instance_reducible] def detInvertibleOfRightInverse (h : A * B = 1) : Invertible A.det where invOf := B.det mul_invOf_self := by rw [← det_mul, h, det_one] invOf_mul_self := by rw [mul_comm, ← det_mul, h, det_one] /-- If `A` has a constructive inverse, produce one for `A.det`. -/ -@[implicit_reducible] +@[instance_reducible] def detInvertibleOfInvertible [Invertible A] : Invertible A.det := detInvertibleOfLeftInverse A (⅟A) (invOf_mul_self _) @@ -439,7 +439,7 @@ theorem isUnit_nonsing_inv_iff {A : Matrix n n α} : IsUnit A⁻¹ ↔ IsUnit A -- `IsUnit.invertible` lifts the proposition `IsUnit A` to a constructive inverse of `A`. /-- A version of `Matrix.invertibleOfDetInvertible` with the inverse defeq to `A⁻¹` that is therefore noncomputable. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def invertibleOfIsUnitDet (h : IsUnit A.det) : Invertible A := ⟨A⁻¹, nonsing_inv_mul A h, mul_nonsing_inv A h⟩ @@ -519,7 +519,7 @@ section Diagonal attribute [local instance] Invertible.map in /-- `diagonal v` is invertible if `v` is -/ -@[implicit_reducible] +@[instance_reducible] def diagonalInvertible {α} [NonAssocSemiring α] (v : n → α) [Invertible v] : Invertible (diagonal v) := inferInstanceAs <| Invertible (diagonalRingHom n α v) @@ -530,7 +530,7 @@ theorem invOf_diagonal_eq {α} [Semiring α] (v : n → α) [Invertible v] [Inve rfl /-- `v` is invertible if `diagonal v` is -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfDiagonalInvertible (v : n → α) [Invertible (diagonal v)] : Invertible v where invOf := diag (⅟(diagonal v)) invOf_mul_self := @@ -678,14 +678,14 @@ variable [Fintype m] variable [DecidableEq m] /-- `A.submatrix e₁ e₂` is invertible if `A` is -/ -@[implicit_reducible] +@[instance_reducible] def submatrixEquivInvertible (A : Matrix m m α) (e₁ e₂ : n ≃ m) [Invertible A] : Invertible (A.submatrix e₁ e₂) := invertibleOfRightInverse _ ((⅟A).submatrix e₂ e₁) <| by rw [Matrix.submatrix_mul_equiv, mul_invOf_self, submatrix_one_equiv] /-- `A` is invertible if `A.submatrix e₁ e₂` is -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfSubmatrixEquivInvertible (A : Matrix m m α) (e₁ e₂ : n ≃ m) [Invertible (A.submatrix e₁ e₂)] : Invertible A := invertibleOfRightInverse _ ((⅟(A.submatrix e₁ e₂)).submatrix e₂.symm e₁.symm) <| by diff --git a/Mathlib/LinearAlgebra/Matrix/Notation.lean b/Mathlib/LinearAlgebra/Matrix/Notation.lean index b941bb86d1476d..d0b88f3a65b8dc 100644 --- a/Mathlib/LinearAlgebra/Matrix/Notation.lean +++ b/Mathlib/LinearAlgebra/Matrix/Notation.lean @@ -231,6 +231,7 @@ variable {ι : Type*} theorem replicateCol_empty (v : Fin 0 → α) : replicateCol ι v = vecEmpty := empty_eq _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem replicateCol_cons (x : α) (u : Fin m → α) : replicateCol ι (vecCons x u) = of (vecCons (fun _ => x) (replicateCol ι u)) := by @@ -257,6 +258,7 @@ theorem transpose_empty_rows (A : Matrix m' (Fin 0) α) : Aᵀ = of ![] := theorem transpose_empty_cols (A : Matrix (Fin 0) m' α) : Aᵀ = of fun _ => ![] := funext fun _ => empty_eq _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem cons_transpose (v : n' → α) (A : Matrix (Fin m) n' α) : (of (vecCons v A))ᵀ = of fun i => vecCons (v i) (Aᵀ i) := by @@ -373,6 +375,7 @@ theorem empty_vecMulVec (v : Fin 0 → α) (w : n' → α) : vecMulVec v w = ![] theorem vecMulVec_empty (v : m' → α) (w : Fin 0 → α) : vecMulVec v w = of fun _ => ![] := funext fun _ => empty_eq _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem cons_vecMulVec (x : α) (v : Fin m → α) (w : n' → α) : vecMulVec (vecCons x v) w = vecCons (x • w) (vecMulVec v w) := by @@ -401,6 +404,7 @@ theorem submatrix_empty (A : Matrix m' n' α) (row : Fin 0 → m') (col : o' → submatrix A row col = ![] := empty_eq _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem submatrix_cons_row (A : Matrix m' n' α) (i : m') (row : Fin m → m') (col : o' → n') : submatrix A (vecCons i row) col = vecCons (fun j => A i (col j)) (submatrix A row col) := by diff --git a/Mathlib/LinearAlgebra/Matrix/PosDef.lean b/Mathlib/LinearAlgebra/Matrix/PosDef.lean index 0333e51feeb5ca..4599e2ec208e7f 100644 --- a/Mathlib/LinearAlgebra/Matrix/PosDef.lean +++ b/Mathlib/LinearAlgebra/Matrix/PosDef.lean @@ -594,7 +594,6 @@ end Matrix namespace QuadraticForm -open QuadraticMap variable {n : Type*} [Fintype n] diff --git a/Mathlib/LinearAlgebra/Matrix/Rank.lean b/Mathlib/LinearAlgebra/Matrix/Rank.lean index 4293b61edb276d..e3213bfcf6fe1c 100644 --- a/Mathlib/LinearAlgebra/Matrix/Rank.lean +++ b/Mathlib/LinearAlgebra/Matrix/Rank.lean @@ -67,6 +67,7 @@ theorem cRank_subsingleton [Subsingleton R] (A : Matrix m n R) : A.cRank = 1 := lemma cRank_toNat_eq_finrank (A : Matrix m n R) : A.cRank.toNat = Module.finrank R (span R (range A.col)) := rfl +set_option backward.isDefEq.respectTransparency false in lemma lift_cRank_submatrix_le (A : Matrix m n R) (r : m₀ → m) (c : n₀ → n) : lift.{um} (A.submatrix r c).cRank ≤ lift.{um₀} A.cRank := by have h : ((A.submatrix r id).submatrix id c).cRank ≤ (A.submatrix r id).cRank := @@ -136,6 +137,7 @@ noncomputable def rank [CommSemiring R] (A : Matrix m n R) : ℕ := theorem rank_subsingleton [CommSemiring R] [Subsingleton R] (A : Matrix m n R) : A.rank = 1 := finrank_subsingleton +set_option backward.isDefEq.respectTransparency false in @[simp] theorem cRank_one [Semiring R] [Nontrivial R] [DecidableEq m] [StrongRankCondition R] : (cRank (1 : Matrix m m R)) = lift.{uR} #m := by @@ -291,6 +293,7 @@ theorem eRank_reindex {m₀ : Type um} {n : Type un} [Semiring R] (A : Matrix m (en : n ≃ n₀) : eRank (A.reindex em en) = eRank A := eRank_submatrix .. +set_option backward.isDefEq.respectTransparency false in /-- The rank of a matrix equals the dimension of the range of the corresponding linear map, and is therefore independent of the choice of bases. -/ theorem rank_eq_finrank_range_toLin [Finite m] [DecidableEq n] {M₁ M₂ : Type*} [CommSemiring R] @@ -380,6 +383,7 @@ theorem exists_rank_normal_form [Fintype m] [DecidableEq m] (M : Matrix m m R) : refine congrArg _ (funext fun i ↦ ?_) split_ifs with hi <;> simp [he, hi] +set_option backward.isDefEq.respectTransparency false in theorem cRank_diagonal [DecidableEq m] (w : m → R) : (diagonal w).cRank = lift.{uR} #{i // (w i) ≠ 0} := by classical diff --git a/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean b/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean index 46694f098cc12e..5badd3a718bd22 100644 --- a/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean +++ b/Mathlib/LinearAlgebra/Matrix/SchurComplement.lean @@ -74,7 +74,7 @@ section Triangular /-- An upper-block-triangular matrix is invertible if its diagonal is. -/ -@[implicit_reducible] +@[instance_reducible] def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α) [Invertible A] [Invertible D] : Invertible (fromBlocks A B 0 D) := invertibleOfLeftInverse _ (fromBlocks (⅟A) (-(⅟A * B * ⅟D)) 0 (⅟D)) <| by @@ -83,7 +83,7 @@ def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : fromBlocks_one] /-- A lower-block-triangular matrix is invertible if its diagonal is. -/ -@[implicit_reducible] +@[instance_reducible] def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α) [Invertible A] [Invertible D] : Invertible (fromBlocks A 0 C D) := invertibleOfLeftInverse _ @@ -229,7 +229,7 @@ section Block /-- A block matrix is invertible if the bottom right corner and the corresponding Schur complement is. -/ -@[implicit_reducible] +@[instance_reducible] def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) [Invertible D] [Invertible (A - B * ⅟D * C)] : Invertible (fromBlocks A B C D) := by @@ -259,7 +259,7 @@ def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matr /-- A block matrix is invertible if the top left corner and the corresponding Schur complement is. -/ -@[implicit_reducible] +@[instance_reducible] def fromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) [Invertible A] [Invertible (D - C * ⅟A * B)] : Invertible (fromBlocks A B C D) := by @@ -294,7 +294,7 @@ theorem invOf_fromBlocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : M /-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding Schur complement. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) [Invertible D] [Invertible (fromBlocks A B C D)] : Invertible (A - B * ⅟D * C) := by @@ -312,7 +312,7 @@ def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n /-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding Schur complement. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) [Invertible A] [Invertible (fromBlocks A B C D)] : Invertible (D - C * ⅟A * B) := by diff --git a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean index 528656d59fcc4c..11b3a0500088fb 100644 --- a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean @@ -11,6 +11,7 @@ public import Mathlib.GroupTheory.Perm.Sign import Mathlib.Algebra.Module.End import Mathlib.GroupTheory.Perm.Option +import Mathlib.LinearAlgebra.Matrix.RowCol /-! # Nonsingular inverses over semirings @@ -184,12 +185,12 @@ theorem mul_adjp_apply_eq : (A * adjp s A) i i = detp s A := by rw [← prod_mul_prod_compl ({i} : Finset n), prod_singleton, (mem_filter.mp hσ).2] theorem mul_adjp_apply_ne (h : i ≠ j) : (A * adjp 1 A) i j = (A * adjp (-1) A) i j := by - let A' : Matrix n n R := of <| Function.update A j (A i) + let A' : Matrix n n R := A.updateRow j (A i) have h' s : (A * adjp s A) i j = (A' * adjp s A') j j := sum_congr rfl fun _ _ ↦ congr_arg₂ (· * ·) (by simp [A']) <| sum_congr rfl fun σ hσ ↦ prod_congr rfl fun _ _ ↦ by aesop simp_rw [h', mul_adjp_apply_eq] apply detp_eq_of_row_eq h - simp [A', h] + simp [A', Matrix.row_apply', h] theorem adjp_mul_apply_eq : (adjp s A * A) i i = detp s A := by rw [← detp_transpose, ← mul_adjp_apply_eq _ _ i, adjp_transpose, ← transpose_mul, transpose_apply] diff --git a/Mathlib/LinearAlgebra/Matrix/SesquilinearForm.lean b/Mathlib/LinearAlgebra/Matrix/SesquilinearForm.lean index 6d74085bad5fd2..36c4d91eaa8ae1 100644 --- a/Mathlib/LinearAlgebra/Matrix/SesquilinearForm.lean +++ b/Mathlib/LinearAlgebra/Matrix/SesquilinearForm.lean @@ -169,6 +169,7 @@ theorem Matrix.toLinearMapₛₗ₂'_aux_eq (M : Matrix n m N₂) : Matrix.toLinearMap₂'Aux σ₁ σ₂ M = Matrix.toLinearMapₛₗ₂' R σ₁ σ₂ M := rfl +set_option backward.isDefEq.respectTransparency false in theorem Matrix.toLinearMapₛₗ₂'_apply (M : Matrix n m N₂) (x : n → R₁) (y : m → R₂) : -- porting note: we don't seem to have `∑ i j` as valid notation yet Matrix.toLinearMapₛₗ₂' R σ₁ σ₂ M x y = ∑ i, ∑ j, σ₁ (x i) • σ₂ (y j) • M i j := by @@ -252,6 +253,7 @@ variable [DecidableEq n] [DecidableEq m] variable [Fintype n'] [Fintype m'] variable [DecidableEq n'] [DecidableEq m'] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem LinearMap.toMatrix₂'_compl₁₂ (B : (n → R) →ₗ[R] (m → R) →ₗ[R] R) (l : (n' → R) →ₗ[R] n → R) (r : (m' → R) →ₗ[R] m → R) : diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index fc99320116a591..70392a20ca0f78 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -263,6 +263,7 @@ theorem mem_center_iff {A : SpecialLinearGroup n R} : · suffices ↑ₘ(B * A) = ↑ₘ(A * B) from Subtype.val_injective this simpa only [coe_mul, ← hr] using! (scalar_commute (n := n) r (Commute.all r) B).symm +set_option backward.isDefEq.respectTransparency false in /-- An equivalence of groups, from the center of the special linear group to the roots of unity. -/ @[simps] def center_equiv_rootsOfUnity' (i : n) : @@ -370,6 +371,7 @@ section SpecialCases open scoped MatrixGroups +set_option backward.isDefEq.respectTransparency false in theorem SL2_inv_expl_det (A : SL(2, R)) : det ![![A.1 1 1, -A.1 0 1], ![-A.1 1 0, A.1 0 0]] = 1 := by simpa [-det_coe, Matrix.det_fin_two, mul_comm] using A.2 @@ -381,6 +383,7 @@ theorem SL2_inv_expl (A : SL(2, R)) : rw [coe_inv, this] simp +set_option backward.isDefEq.respectTransparency false in theorem fin_two_induction (P : SL(2, R) → Prop) (h : ∀ (a b c d : R) (hdet : a * d - b * c = 1), P ⟨!![a, b; c, d], by rwa [det_fin_two_of]⟩) (g : SL(2, R)) : P g := by @@ -388,6 +391,7 @@ theorem fin_two_induction (P : SL(2, R) → Prop) convert! h (m 0 0) (m 0 1) (m 1 0) (m 1 1) (by rwa [det_fin_two] at hm) ext i j; fin_cases i <;> fin_cases j <;> rfl +set_option backward.isDefEq.respectTransparency false in theorem fin_two_exists_eq_mk_of_apply_zero_one_eq_zero {R : Type*} [Field R] (g : SL(2, R)) (hg : g 1 0 = 0) : ∃ (a b : R) (h : a ≠ 0), g = (⟨!![a, b; 0, a⁻¹], by simp [h]⟩ : SL(2, R)) := by @@ -662,6 +666,7 @@ lemma diagonal_neZero (D : ι → F) (hD : det (diagonal D) = 1) (j : ι) : Finset.prod_insert (by grind), h, zero_mul] at hD exact zero_ne_one hD +set_option backward.isDefEq.respectTransparency.types false in lemma diag_commute (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) : (({i | i ≠ i₀} : Finset ι) : Set ι).Pairwise (Function.onFun Commute fun i ↦ if hi : i ≠ i₀ then diag2n hi (D i) (diagonal_neZero D hD i) else 1) := by @@ -670,6 +675,7 @@ lemma diag_commute (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) : simp [apply_dite, diag2n_coe] split_ifs <;> simp [diagonal_apply]; grind +set_option backward.isDefEq.respectTransparency.types false in lemma diag_eq_diag2n_prod (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) : (⟨diagonal D, hD⟩ : SpecialLinearGroup ι F) = Finset.noncommProd {i : ι | i ≠ i₀} (fun i ↦ if hi : i ≠ i₀ then @@ -685,6 +691,7 @@ lemma diag_eq_diag2n_prod (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) rw [← Finset.map_noncommProd _ _ (fun _ _ _ _ _ ↦ Commute.all _ _), Finset.noncommProd_eq_prod] rw [diag_decompose i₀ D hD] +set_option backward.isDefEq.respectTransparency.types false in /-- The `SpecialLinearGroup` analogue of `Matrix.Pivot.exists_list_transvec_mul_diagonal_mul_list_transvec`: every element of `SL(ι, F)` is a product of transvections, diff --git a/Mathlib/LinearAlgebra/Matrix/ToLin.lean b/Mathlib/LinearAlgebra/Matrix/ToLin.lean index 239eaf34325b88..154f6b98d74ac2 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLin.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLin.lean @@ -171,6 +171,7 @@ theorem Matrix.coe_vecMulLinear [Fintype m] (M : Matrix m n R) : variable [Fintype m] +set_option backward.isDefEq.respectTransparency false in theorem range_vecMulLinear (M : Matrix m n R) : LinearMap.range M.vecMulLinear = span R (range M.row) := by let := Classical.decEq m @@ -194,6 +195,7 @@ lemma Matrix.linearIndependent_rows_of_isUnit {A : Matrix m m R} section +set_option backward.isDefEq.respectTransparency false in /-- Linear maps `(m → R) →ₗ[R] (n → R)` are linearly equivalent over `Rᵐᵒᵖ` to `Matrix m n R`, by having matrices act by right multiplication. -/ @@ -476,6 +478,7 @@ theorem LinearMap.toMatrix'_mul [Fintype m] [DecidableEq m] (f g : (m → R) → LinearMap.toMatrix' (f * g) = LinearMap.toMatrix' f * LinearMap.toMatrix' g := LinearMap.toMatrix'_comp f g +set_option backward.isDefEq.respectTransparency false in @[simp] theorem LinearMap.toMatrix'_algebraMap (x : R) : LinearMap.toMatrix' (algebraMap R (Module.End R (n → R)) x) = scalar n x := by @@ -649,6 +652,7 @@ lemma LinearMap.toMatrix_singleton {ι : Type*} [Unique ι] (f : R →ₗ[R] R) theorem Matrix.toLin_one : Matrix.toLin v₁ v₁ 1 = LinearMap.id := by rw [← LinearMap.toMatrix_id v₁, Matrix.toLin_toMatrix] +set_option backward.isDefEq.respectTransparency false in theorem Matrix.toLin_scalar (r : R) : Matrix.toLin v₁ v₁ (scalar n r) = r • LinearMap.id := (LinearMap.toMatrix v₁ v₁).injective (by simp [toMatrix_id, smul_one_eq_diagonal]) @@ -658,6 +662,7 @@ theorem LinearMap.toMatrix_reindexRange [DecidableEq M₁] (f : M₁ →ₗ[R] M LinearMap.toMatrix v₁ v₂ f k i := by simp_rw [LinearMap.toMatrix_apply, Basis.reindexRange_self, Basis.reindexRange_repr] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem LinearMap.toMatrix_algebraMap (x : R) : LinearMap.toMatrix v₁ v₁ (algebraMap R (Module.End R M₁) x) = scalar n x := by @@ -711,6 +716,7 @@ variable {l m n : Type*} [Fintype n] [DecidableEq n] variable {M₁ M₂ : Type*} [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R M₁] [Module R M₂] variable (v₁ : Basis n R M₁) (v₂ : Basis m R M₂) +set_option backward.isDefEq.respectTransparency false in /-- The matrix of `toSpanSingleton R M₂ x` given by bases `v₁` and `v₂` is equal to `vecMulVec (v₂.repr x) v₁`. When `v₁ = Module.Basis.singleton` then this is the column matrix of `v₂.repr x`. -/ @@ -718,6 +724,7 @@ theorem LinearMap.toMatrix_toSpanSingleton [Finite m] (v₁ : Basis n R R) (v₂ (x : M₂) : (toSpanSingleton R M₂ x).toMatrix v₁ v₂ = vecMulVec (v₂.repr x) v₁ := by ext; simp [toMatrix_apply, vecMulVec_apply, mul_comm] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma LinearMap.toMatrix_smulRight [Finite m] (f : M₁ →ₗ[R] R) (x : M₂) : toMatrix v₁ v₂ (f.smulRight x) = vecMulVec (v₂.repr x) (f ∘ v₁) := by @@ -995,6 +1002,7 @@ variable {A M n : Type*} [Fintype n] [DecidableEq n] [CommSemiring A] [AddCommMonoid M] [Module R M] [Module A M] [Algebra R A] [IsScalarTower R A M] (bA : Basis m R A) (bM : Basis n A M) +set_option backward.isDefEq.respectTransparency false in lemma _root_.LinearMap.restrictScalars_toMatrix (f : M →ₗ[A] M) : (f.restrictScalars R).toMatrix (bA.smulTower' bM) (bA.smulTower' bM) = ((f.toMatrix bM bM).map (leftMulMatrix bA)).comp _ _ _ _ _ := by @@ -1010,6 +1018,7 @@ variable [Algebra R S] [Algebra S T] [Algebra R T] [IsScalarTower R S T] variable {m n : Type*} [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n] variable (b : Basis m R S) (c : Basis n S T) +set_option backward.isDefEq.respectTransparency false in theorem smulTower_leftMulMatrix (x) (ik jk) : leftMulMatrix (b.smulTower c) x ik jk = leftMulMatrix b (leftMulMatrix c x ik.2 jk.2) ik.1 jk.1 := by @@ -1129,6 +1138,7 @@ variable (R : Type*) [CommSemiring R] variable (A : Type*) [Semiring A] [Algebra R A] variable (M : Type*) [AddCommMonoid M] [Module R M] [Module A M] [IsScalarTower R A M] +set_option backward.isDefEq.respectTransparency false in /-- Let `M` be an `A`-module. Every `A`-linear map `Mⁿ → Mⁿ` corresponds to a `n×n`-matrix whose entries are `A`-linear maps `M → M`. In another word, we have `End(Mⁿ) ≅ Matₙₓₙ(End(M))` defined by: @@ -1162,6 +1172,7 @@ def endVecRingEquivMatrixEnd : exact congr_arg₂ _ (by aesop) rfl map_add' f g := by ext; simp +set_option backward.isDefEq.respectTransparency false in /-- Let `M` be an `A`-module. Every `A`-linear map `Mⁿ → Mⁿ` corresponds to a `n×n`-matrix whose entries are `R`-linear maps `M → M`. In another word, we have `End(Mⁿ) ≅ Matₙₓₙ(End(M))` defined by: diff --git a/Mathlib/LinearAlgebra/Matrix/Transvection.lean b/Mathlib/LinearAlgebra/Matrix/Transvection.lean index 776e9a631444d5..ea69c434b9e2ca 100644 --- a/Mathlib/LinearAlgebra/Matrix/Transvection.lean +++ b/Mathlib/LinearAlgebra/Matrix/Transvection.lean @@ -330,7 +330,7 @@ namespace Pivot variable {R} {r : ℕ} (M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜) -open Unit Sum Fin TransvectionStruct +open Unit Sum TransvectionStruct /-- A list of transvections such that multiplying on the left with these transvections will replace the last column with zeroes. -/ diff --git a/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean b/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean index c94c0e36a851c3..c246005765dadd 100644 --- a/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean @@ -269,6 +269,7 @@ theorem freeDFinsuppEquiv_def (f : Π₀ (_ : (Π i, κ i) × ι'), R) : (DFinsupp.domLCongr (R := R) (Equiv.sigmaEquivProd _ _).symm) f) := rfl +set_option backward.isDefEq.respectTransparency false in /-- When `freeDFinsuppEquiv` is applied to a map with a single value of one the resulting multilinear map sends inputs to a single value in the codomain, taking a product over images from each diff --git a/Mathlib/LinearAlgebra/Orientation.lean b/Mathlib/LinearAlgebra/Orientation.lean index f6633180871c65..62e2d951868c22 100644 --- a/Mathlib/LinearAlgebra/Orientation.lean +++ b/Mathlib/LinearAlgebra/Orientation.lean @@ -201,6 +201,7 @@ variable {ι : Type*} namespace Orientation +set_option backward.isDefEq.respectTransparency false in /-- A module `M` over a linearly ordered commutative ring has precisely two "orientations" with respect to an empty index type. (Note that these are only orientations of `M` of in the conventional mathematical sense if `M` is zero-dimensional.) -/ diff --git a/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean b/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean index 45a4ac8ce887f9..17729c9f9986c3 100644 --- a/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean +++ b/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean @@ -84,6 +84,7 @@ variable {S M' N' : Type*} [AddCommGroup M'] [Module S M'] [AddCommGroup N'] [Module S N'] (i : M' →ₗ[S] M) (j : N' →ₗ[S] N) +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in private lemma restrictScalars_injective_aux (hi : Injective i) @@ -108,6 +109,7 @@ private lemma restrictScalars_injective_aux ext n simpa using hx n +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in private lemma restrictScalars_surjective_aux (h : ∀ g : Module.Dual S N', ∃ m, diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index ab0e63116f95c1..b5c09907cb69d4 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -459,6 +459,7 @@ variable [(i : ι) → AddCommMonoid (φ i)] [(i : ι) → Module R (φ i)] variable [(i : ι) → AddCommMonoid (ψ i)] [(i : ι) → Module R (ψ i)] variable [(i : ι) → AddCommMonoid (χ i)] [(i : ι) → Module R (χ i)] +set_option backward.isDefEq.respectTransparency false in /-- Combine a family of linear equivalences into a linear equivalence of `pi`-types. This is `Equiv.piCongrRight` as a `LinearEquiv` -/ diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean index 1317cf6074135e..b3986bb327b39f 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean @@ -318,6 +318,7 @@ lemma mem_lifts_iff (x : ⨂[R] i, s i) (p : FreeAddMonoid (R × Π i, s i)) : p ∈ lifts x ↔ List.sum (List.map (fun x ↦ x.1 • ⨂ₜ[R] i, x.2 i) p.toList) = x := by simp only [lifts, Set.mem_setOf_eq, FreeAddMonoid.toPiTensorProduct] +set_option backward.isDefEq.respectTransparency false in /-- Every element of `⨂[R] i, s i` has a lift in `FreeAddMonoid (R × Π i, s i)`. -/ lemma nonempty_lifts (x : ⨂[R] i, s i) : Set.Nonempty (lifts x) := by @@ -643,6 +644,7 @@ theorem piTensorHomMapFun₂_add (φ ψ : ⨂[R] i, s i →ₗ[R] t i →ₗ[R] dsimp [piTensorHomMapFun₂]; ext; simp only [map_add, LinearMap.compMultilinearMap_apply, lift.tprod, add_apply, LinearMap.add_apply] +set_option backward.isDefEq.respectTransparency false in theorem piTensorHomMapFun₂_smul (r : R) (φ : ⨂[R] i, s i →ₗ[R] t i →ₗ[R] t' i) : piTensorHomMapFun₂ (r • φ) = r • piTensorHomMapFun₂ φ := by dsimp [piTensorHomMapFun₂]; ext; simp only [map_smul, LinearMap.compMultilinearMap_apply, @@ -661,6 +663,7 @@ def piTensorHomMap₂ : (⨂[R] i, s i →ₗ[R] t i →ₗ[R] t' i) →ₗ[R] map_add' x y := piTensorHomMapFun₂_add x y map_smul' x y := piTensorHomMapFun₂_smul x y +set_option backward.isDefEq.respectTransparency false in @[simp] lemma piTensorHomMap₂_tprod_tprod_tprod (f : ∀ i, s i →ₗ[R] t i →ₗ[R] t' i) (a : ∀ i, s i) (b : ∀ i, t i) : piTensorHomMap₂ (tprod R f) (tprod R a) (tprod R b) = tprod R (fun i ↦ f i (a i) (b i)) := by @@ -836,6 +839,7 @@ section tmulEquivDep variable (N : ι ⊕ ι₂ → Type*) [∀ i, AddCommMonoid (N i)] [∀ i, Module R (N i)] +set_option backward.isDefEq.respectTransparency false in /-- Equivalence between a `TensorProduct` of `PiTensorProduct`s and a single `PiTensorProduct` indexed by a `Sum` type. If `N` is a constant family of modules, use the non-dependent version `PiTensorProduct.tmulEquiv` instead. -/ diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean index fb60ceae5a3b65..36f51dded9b891 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Generators.lean @@ -60,6 +60,7 @@ lemma equivPiTensorComplSingletonTensor_tprod (i₀ : ι) (m : ∀ i, M i) : (fun i ↦ M ((Equiv.subtypeNeSumPUnit.{0} i₀) i))] exact (LinearEquiv.lTensor_tmul _ _ _ _).trans (by congr; simp) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma equivPiTensorComplSingletonTensor_symm_tmul (i₀ : ι) (m : ∀ (i : ((Set.singleton i₀)ᶜ : Set ι)), M i) (x : M i₀) : @@ -83,6 +84,7 @@ section AddCommMonoid variable [CommSemiring R] [∀ i, AddCommMonoid (M i)] [∀ i, Module R (M i)] [AddCommMonoid N] [Module R N] {g : ⦃i : ι⦄ → (j : γ i) → M i} +set_option backward.isDefEq.respectTransparency.types false in lemma ext_of_span_eq_top (hg : ∀ i, Submodule.span R (Set.range (@g i)) = ⊤) {φ φ' : (⨂[R] i, M i) →ₗ[R] N} diff --git a/Mathlib/LinearAlgebra/Prod.lean b/Mathlib/LinearAlgebra/Prod.lean index d00e8164ac8be6..181a08d693fcda 100644 --- a/Mathlib/LinearAlgebra/Prod.lean +++ b/Mathlib/LinearAlgebra/Prod.lean @@ -90,6 +90,7 @@ theorem fst_surjective : Function.Surjective (fst R M M₂) := fun x => ⟨(x, 0 theorem snd_surjective : Function.Surjective (snd R M M₂) := fun x => ⟨(0, x), rfl⟩ +set_option backward.isDefEq.respectTransparency false in /-- The prod of two linear maps is a linear map. -/ @[simps] def prod (f : M →ₗ[R] M₂) (g : M →ₗ[R] M₃) : M →ₗ[R] M₂ × M₃ where @@ -477,6 +478,7 @@ theorem ker_coprod_of_disjoint_range {M₂ : Type*} [AddCommGroup M₂] [Module rw [this] at h simpa [this] using h +set_option backward.isDefEq.respectTransparency false in /-- Given a linear map `f : E →ₗ[R] F` and a complement `C` of its kernel, we get a linear equivalence between `C` and `range f`. -/ @[simps!] @@ -822,6 +824,7 @@ variable [Semiring R] variable [AddCommMonoid M] [AddCommMonoid M₂] variable [Module R M] [Module R M₂] [Unique M₂] +set_option backward.isDefEq.respectTransparency false in /-- Multiplying by the trivial module from the left does not change the structure. This is the `LinearEquiv` version of `AddEquiv.uniqueProd`. -/ @[simps!] @@ -831,6 +834,7 @@ def uniqueProd : (M₂ × M) ≃ₗ[R] M := lemma coe_uniqueProd : (uniqueProd (R := R) (M := M) (M₂ := M₂) : (M₂ × M) ≃ M) = Equiv.uniqueProd M M₂ := rfl +set_option backward.isDefEq.respectTransparency false in /-- Multiplying by the trivial module from the right does not change the structure. This is the `LinearEquiv` version of `AddEquiv.prodUnique`. -/ @[simps!] diff --git a/Mathlib/LinearAlgebra/Projectivization/Action.lean b/Mathlib/LinearAlgebra/Projectivization/Action.lean index 4b1cbe2b8ea2a1..41629f36bce637 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Action.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Action.lean @@ -39,6 +39,7 @@ section DivisionRing variable {G K V : Type*} [AddCommGroup V] [DivisionRing K] [Module K V] [Group G] [DistribMulAction G V] [SMulCommClass G K V] +set_option backward.isDefEq.respectTransparency false in /-- Any group acting `K`-linearly on `V` (such as the general linear group) acts on `ℙ V`. -/ @[simps -isSimp] instance : MulAction G (ℙ K V) where diff --git a/Mathlib/LinearAlgebra/Projectivization/Basic.lean b/Mathlib/LinearAlgebra/Projectivization/Basic.lean index c691128f5015f6..a9756e01023a8b 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Basic.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Basic.lean @@ -39,7 +39,7 @@ We have three ways to construct terms of `ℙ K V`: variable (K V : Type*) [DivisionRing K] [AddCommGroup V] [Module K V] /-- The setoid whose quotient is the projectivization of `V`. -/ -@[implicit_reducible] +@[instance_reducible] def projectivizationSetoid : Setoid { v : V // v ≠ 0 } := (MulAction.orbitRel Kˣ V).comap (↑) diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index fa61690db36e59..ecbafd2a2f869b 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -573,6 +573,7 @@ section Comp variable [CommSemiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] variable [AddCommMonoid P] [Module R P] +set_option backward.isDefEq.respectTransparency false in /-- Compose the quadratic map with a linear function on the right. -/ def comp (Q : QuadraticMap R N P) (f : M →ₗ[R] N) : QuadraticMap R M P where toFun x := Q (f x) @@ -585,6 +586,7 @@ def comp (Q : QuadraticMap R N P) (f : M →ₗ[R] N) : QuadraticMap R M P where theorem comp_apply (Q : QuadraticMap R N P) (f : M →ₗ[R] N) (x : M) : (Q.comp f) x = Q (f x) := rfl +set_option backward.isDefEq.respectTransparency false in /-- Compose a quadratic map with a linear function on the left. -/ @[simps +simpRhs] def _root_.LinearMap.compQuadraticMap (f : N →ₗ[R] P) (Q : QuadraticMap R M N) : @@ -708,6 +710,7 @@ section Semiring variable [CommSemiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] variable {N' : Type*} [AddCommMonoid N'] [Module R N'] +set_option backward.isDefEq.respectTransparency false in /-- A bilinear map gives a quadratic map by applying the argument twice. -/ def toQuadraticMap (B : BilinMap R M N) : QuadraticMap R M N where toFun x := B x x @@ -1245,7 +1248,7 @@ theorem toMatrix'_comp (Q : QuadraticForm R (m → R)) (f : (n → R) →ₗ[R] end Rn section Basis -open Module QuadraticMap +open Module variable [AddCommGroup N] [Module R N] (b : Basis n R N) (Q : QuadraticForm R N) diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean index 6bd56e82995fa4..5e257c0287067a 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean @@ -91,6 +91,7 @@ theorem toBilin_apply (Q : QuadraticMap R M N) (bm : Basis ι R M) (i j : ι) : if i = j then Q (bm i) else if i < j then polar Q (bm i) (bm j) else 0 := by simp [toBilin] +set_option backward.isDefEq.respectTransparency false in theorem toQuadraticMap_toBilin (Q : QuadraticMap R M N) (bm : Basis ι R M) : (Q.toBilin bm).toQuadraticMap = Q := by ext x diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean b/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean index dd39c1b9923753..fe0a872ae49e73 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean @@ -48,6 +48,7 @@ section Ring variable [CommRing R] [AddCommGroup M] [Module R M] +set_option backward.isDefEq.respectTransparency false in theorem separatingLeft_dualProd : (dualProd R M).SeparatingLeft ↔ Function.Injective (Module.Dual.eval R M) := by rw [separatingLeft_iff_ker_eq_bot, ker_eq_bot] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean b/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean index 0a9dd0e186de8c..5655be1f23683a 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Signature.lean @@ -117,6 +117,7 @@ variable {Q} @[simp] lemma sigNeg_neg : sigNeg (-Q) = sigPos Q := by rw [← sigPos_neg, neg_neg] +set_option backward.isDefEq.respectTransparency false in lemma QuadraticMap.Equivalent.sigPos_eq (h : Equivalent Q Q') : sigPos Q = sigPos Q' := by obtain ⟨e⟩ := h unfold sigPos diff --git a/Mathlib/LinearAlgebra/Quotient/Basic.lean b/Mathlib/LinearAlgebra/Quotient/Basic.lean index 2c4fd2b848e099..f1b61653a489d8 100644 --- a/Mathlib/LinearAlgebra/Quotient/Basic.lean +++ b/Mathlib/LinearAlgebra/Quotient/Basic.lean @@ -188,6 +188,7 @@ theorem mapQ_zero (h : p ≤ q.comap (0 : M →ₛₗ[τ₁₂] M₂) := (by sim ext simp +set_option backward.isDefEq.respectTransparency false in /-- Given submodules `p ⊆ M`, `p₂ ⊆ M₂`, `p₃ ⊆ M₃` and maps `f : M → M₂`, `g : M₂ → M₃` inducing `mapQ f : M ⧸ p → M₂ ⧸ p₂` and `mapQ g : M₂ ⧸ p₂ → M₃ ⧸ p₃` then `mapQ (g ∘ f) = (mapQ g) ∘ (mapQ f)`. -/ @@ -266,6 +267,7 @@ theorem factor_comp_mk (H : p ≤ p') : (factor H).comp (mkQ p) = mkQ p' := by ext x rw [LinearMap.comp_apply, factor_mk] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem factor_comp (H1 : p ≤ p') (H2 : p' ≤ p'') : (factor H2).comp (factor H1) = factor (H1.trans H2) := by diff --git a/Mathlib/LinearAlgebra/Ray.lean b/Mathlib/LinearAlgebra/Ray.lean index 9e85bdedf8806f..fc86889180e2a5 100644 --- a/Mathlib/LinearAlgebra/Ray.lean +++ b/Mathlib/LinearAlgebra/Ray.lean @@ -176,6 +176,7 @@ theorem map (f : M →ₗ[R] N) (h : SameRay R x y) : SameRay R (f x) (f y) := Or.imp (fun hy => by rw [hy, map_zero]) fun ⟨r₁, r₂, hr₁, hr₂, h⟩ => ⟨r₁, r₂, hr₁, hr₂, by rw [← f.map_smul, ← f.map_smul, h]⟩ +set_option backward.isDefEq.respectTransparency false in /-- The images of two vectors under an injective linear map are on the same ray if and only if the original vectors are on the same ray. -/ theorem _root_.Function.Injective.sameRay_map_iff diff --git a/Mathlib/LinearAlgebra/Reflection.lean b/Mathlib/LinearAlgebra/Reflection.lean index fc9dd092b2a985..ba099ca18b8bcb 100644 --- a/Mathlib/LinearAlgebra/Reflection.lean +++ b/Mathlib/LinearAlgebra/Reflection.lean @@ -85,6 +85,7 @@ lemma involutive_preReflection (h : f x = 2) : Involutive (preReflection x f) := fun y ↦ by simp [map_sub, h, two_smul, preReflection_apply] +set_option backward.isDefEq.respectTransparency false in lemma preReflection_preReflection (g : Dual R M) (h : f x = 2) : preReflection (preReflection x f y) (preReflection f (Dual.eval R M x) g) = (preReflection x f) ∘ₗ (preReflection y g) ∘ₗ (preReflection x f) := by @@ -179,6 +180,7 @@ open Int Polynomial.Chebyshev variable {x y : M} {f g : Dual R M} (hf : f x = 2) (hg : g y = 2) +set_option backward.isDefEq.respectTransparency false in /-- A formula for $(r_1 r_2)^m z$, where $m$ is a natural number and $z \in M$. -/ lemma reflection_mul_reflection_pow_apply (m : ℕ) (z : M) (t : R := f y * g x - 2) (ht : t = f y * g x - 2 := by rfl) : @@ -272,6 +274,7 @@ lemma reflection_mul_reflection_zpow (m : ℤ) ext z simpa using reflection_mul_reflection_zpow_apply hf hg m z t ht +set_option backward.isDefEq.respectTransparency false in /-- A formula for $(r_1 r_2)^m x$, where $m$ is an integer. This is the special case of `Module.reflection_mul_reflection_zpow_apply` with $z = x$. -/ lemma reflection_mul_reflection_zpow_apply_self (m : ℤ) @@ -313,6 +316,7 @@ lemma reflection_mul_reflection_pow_apply_self (m : ℕ) ((S R m).eval t + (S R (m - 1)).eval t) • x + ((S R (m - 1)).eval t * -g x) • y := mod_cast reflection_mul_reflection_zpow_apply_self hf hg m t ht +set_option backward.isDefEq.respectTransparency false in /-- A formula for $r_2 (r_1 r_2)^m x$, where $m$ is an integer. -/ lemma reflection_mul_reflection_mul_reflection_zpow_apply_self (m : ℤ) (t : R := f y * g x - 2) (ht : t = f y * g x - 2 := by rfl) : @@ -335,6 +339,7 @@ end /-! ### Lemmas used to prove uniqueness results for root data -/ +set_option backward.isDefEq.respectTransparency false in /-- See also `Module.Dual.eq_of_preReflection_mapsTo'` for a variant of this lemma which applies when `Φ` does not span. @@ -401,6 +406,7 @@ lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [IsDomain R] [IsTorsionFree variable {y} variable {g : Dual R M} +set_option backward.isDefEq.respectTransparency false in /-- Composite of reflections in "parallel" hyperplanes is a shear (special case). -/ lemma reflection_reflection_iterate (hfx : f x = 2) (hgy : g y = 2) (hgxfy : f y * g x = 4) (n : ℕ) : diff --git a/Mathlib/LinearAlgebra/RootSystem/Base.lean b/Mathlib/LinearAlgebra/RootSystem/Base.lean index 314de2a236f0d9..6c7285ca5226ff 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Base.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Base.lean @@ -149,6 +149,7 @@ lemma span_coroot_support : span R (P.coroot '' b.support) = P.corootSpan R := b.flip.span_root_support +set_option backward.isDefEq.respectTransparency.types false in open Finsupp in lemma eq_one_or_neg_one_of_mem_support_of_smul_mem_aux [Finite ι] [IsAddTorsionFree M] [IsAddTorsionFree N] diff --git a/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean b/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean index b72ee38e87d3ff..93819892cef487 100644 --- a/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean +++ b/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean @@ -64,6 +64,7 @@ section SubfieldValued variable [P.IsValuedIn K] +set_option backward.isDefEq.respectTransparency.types false in /-- Restriction of scalars for a root pairing taking values in a subfield. See also `RootPairing.restrictScalars`. -/ @@ -87,6 +88,7 @@ def restrictScalars' : reflectionPerm_coroot i j := by ext; simpa [algebra_compatible_smul L] using P.reflectionPerm_coroot i j +set_option backward.isDefEq.respectTransparency.types false in instance : (P.restrictScalars' K).IsRootSystem where span_root_eq_top := by rw [← span_setOf_mem_eq_top] @@ -99,6 +101,7 @@ instance : (P.restrictScalars' K).IsRootSystem where ext ⟨x, hx⟩ simp [restrictScalars'] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrictScalars_toLinearMap_apply_apply (x : span K (range P.root)) (y : span K (range P.coroot)) : algebraMap K L ((P.restrictScalars' K).toLinearMap x y) = P.toLinearMap x y := by diff --git a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean index 6e4ee701a2c614..6e805b6ecaf288 100644 --- a/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean +++ b/Mathlib/LinearAlgebra/RootSystem/BaseExists.lean @@ -113,6 +113,7 @@ section Field variable [Field R] [CharZero R] [Module R M] [Module R N] (P : RootPairing ι R M N) [P.IsRootSystem] [P.IsCrystallographic] +set_option backward.isDefEq.respectTransparency.types false in lemma linearIndepOn_root_baseOf (f : M →+ ℚ) (hf : ∀ i, f (P.root i) ≠ 0) : LinearIndepOn R P.root (baseOf P.root f) := by let _i : Module ℚ M := Module.compHom M (algebraMap ℚ R) diff --git a/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean b/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean index f3782786f24566..e3e3fa9621ce20 100644 --- a/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean +++ b/Mathlib/LinearAlgebra/RootSystem/CartanMatrix.lean @@ -134,6 +134,7 @@ lemma cartanMatrix_le_zero_of_ne b.cartanMatrix i j ≤ 0 := b.pairingIn_le_zero_of_ne (by rwa [ne_eq, ← Subtype.ext_iff]) i.property j.property +set_option backward.isDefEq.respectTransparency.types false in lemma cartanMatrix_mem_of_ne {i j : b.support} (hij : i ≠ j) : b.cartanMatrix i j ∈ ({-3, -2, -1, 0} : Set ℤ) := by have : Module.IsReflexive R M := .of_isPerfPair P.toLinearMap @@ -263,6 +264,7 @@ lemma induction_on_cartanMatrix [P.IsReduced] [P.IsIrreducible] simp [← hq_mem, IsIrreducible.eq_top_of_invtSubmodule_reflection q hq hq₀] -- TODO Derive from `LinearIndependent.injective` +set_option backward.isDefEq.respectTransparency.types false in open scoped Matrix in lemma injective_pairingIn {P : RootPairing ι R M N} [P.IsRootSystem] [P.IsCrystallographic] (b : P.Base) : @@ -352,6 +354,7 @@ lemma apply_mem_range_root_of_cartanMatrixEq rw [root_reflectionPerm, this, ← hl, ← root_reflectionPerm] exact mem_range_self _ +set_option backward.isDefEq.respectTransparency.types false in /-- A root system is determined by its Cartan matrix. -/ def equivOfCartanMatrixEq [Finite ι₂] [P₂.IsRootSystem] [P₂.IsReduced] (he : ∀ i j, b₂.cartanMatrix (e i) (e j) = b.cartanMatrix i j) : diff --git a/Mathlib/LinearAlgebra/RootSystem/Defs.lean b/Mathlib/LinearAlgebra/RootSystem/Defs.lean index f90abb5db851e2..abb003188e64d6 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Defs.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Defs.lean @@ -209,6 +209,7 @@ lemma pairing_eq_add_of_root_eq_add {i j k l : ι} (h : P.root k = P.root i + P. P.pairing k l = P.pairing i l + P.pairing j l := by simp only [← root_coroot_eq_pairing, h, map_add, LinearMap.add_apply] +set_option backward.isDefEq.respectTransparency false in variable {P} in lemma pairing_eq_add_of_root_eq_smul_add_smul {i j k l : ι} {x y : R} (h : P.root k = x • P.root i + y • P.root l) : @@ -398,9 +399,10 @@ lemma pairing_reflectionPerm_self_right (i j : ι) : rw [pairing, ← reflectionPerm_coroot, root_coroot_eq_pairing, pairing_same, two_smul, sub_add_cancel_left, map_neg, root_coroot_eq_pairing] +set_option backward.isDefEq.respectTransparency false in /-- The indexing set of a root pairing carries an involutive negation, corresponding to the negation of a root / coroot. -/ -@[simps, implicit_reducible] def indexNeg : InvolutiveNeg ι where +@[simps, instance_reducible] def indexNeg : InvolutiveNeg ι where neg i := P.reflectionPerm i i neg_neg i := by apply P.root.injective @@ -522,6 +524,7 @@ lemma reflectionPerm_eq_reflectionPerm_iff_of_isSMulRegular (h2 : IsSMulRegular replace h2 : IsSMulRegular (M → M) 2 := IsSMulRegular.pi fun _ ↦ h2 exact h2 <| P.two_nsmul_reflection_eq_of_perm_eq i j h +set_option backward.isDefEq.respectTransparency false in lemma reflectionPerm_eq_reflectionPerm_iff_of_span : P.reflectionPerm i = P.reflectionPerm j ↔ ∀ x ∈ span R (range P.root), P.reflection i x = P.reflection j x := by @@ -565,6 +568,7 @@ def IsOrthogonal : Prop := pairing P i j = 0 ∧ pairing P j i = 0 lemma isOrthogonal_symm : IsOrthogonal P i j ↔ IsOrthogonal P j i := by simp only [IsOrthogonal, and_comm] +set_option backward.isDefEq.respectTransparency false in lemma isOrthogonal_comm (h : IsOrthogonal P i j) : Commute (P.reflection i) (P.reflection j) := by rw [commute_iff_eq] ext @@ -653,6 +657,7 @@ section Map variable {ι₂ M₂ N₂ : Type*} [AddCommGroup M₂] [Module R M₂] [AddCommGroup N₂] [Module R N₂] +set_option backward.isDefEq.respectTransparency false in /-- Push forward a root pairing along linear equivalences, also reindexing the (co)roots. -/ protected def map (e : ι ≃ ι₂) (f : M ≃ₗ[R] M₂) (g : N ≃ₗ[R] N₂) : RootPairing ι₂ R M₂ N₂ where diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean index 09b07eeb1050dd..34442361bfc523 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean @@ -78,7 +78,7 @@ section IsG2 /-- By making an arbitrary choice of roots pairing to `-3`, we can obtain an embedded `𝔤₂` root system just from the knowledge that such a pairs exists. -/ -@[implicit_reducible] +@[instance_reducible] def IsG2.toEmbeddedG2 [P.IsG2] : P.EmbeddedG2 where long := (IsG2.exists_pairingIn_neg_three (P := P)).choose short := (IsG2.exists_pairingIn_neg_three (P := P)).choose_spec.choose @@ -200,7 +200,7 @@ end IsNotG2 namespace EmbeddedG2 /-- A pair of roots which pair to `+3` are also sufficient to distinguish an embedded `𝔤₂`. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def ofPairingInThree [CharZero R] [P.IsCrystallographic] [P.IsReduced] (long short : ι) (h : P.pairingIn ℤ long short = 3) : P.EmbeddedG2 where long := P.reflectionPerm long long diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean index d28b0e379d952a..27acbc304dfa35 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Lemmas.lean @@ -262,6 +262,7 @@ private lemma chainBotCoeff_mul_chainTopCoeff.aux_1 simp only [P.chainBotCoeff_if_one_zero, hik_mem, him_mem, hjl_mem, hjk_mem] simp [key₁, key₂, key₃, key₄] +set_option backward.isDefEq.respectTransparency.types false in /- An auxiliary result en route to `RootPairing.chainBotCoeff_mul_chainTopCoeff`. -/ open RootPositiveForm in private lemma chainBotCoeff_mul_chainTopCoeff.aux_2 diff --git a/Mathlib/LinearAlgebra/RootSystem/IsValuedIn.lean b/Mathlib/LinearAlgebra/RootSystem/IsValuedIn.lean index f8087ae9fc9cca..60e5282a1b0ebc 100644 --- a/Mathlib/LinearAlgebra/RootSystem/IsValuedIn.lean +++ b/Mathlib/LinearAlgebra/RootSystem/IsValuedIn.lean @@ -201,6 +201,7 @@ def root'In [Module S N] [IsScalarTower S R N] [FaithfulSMul S R] [P.IsValuedIn (FaithfulSMul.algebraMap_injective S R) (P.root' i) (fun m ↦ P.root'_apply_apply_mem_of_mem_span S m.2 i) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma algebraMap_root'In_apply [Module S N] [IsScalarTower S R N] [FaithfulSMul S R] [P.IsValuedIn S] (i : ι) (x : P.corootSpan S) : diff --git a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean index e2474956fc6557..cdd8d752ac42f3 100644 --- a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean +++ b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean @@ -80,6 +80,7 @@ lemma smul_coroot : B x x • coroot B hx = 2 • B x := by lemma coroot_apply_self : coroot B hx x = 2 := hx.regular.left <| by simp [mul_comm _ (B x x)] +set_option backward.isDefEq.respectTransparency false in lemma isOrthogonal_reflection (hSB : LinearMap.IsSymm B) : B.IsOrthogonal (Module.reflection (coroot_apply_self B hx)) := by intro y z diff --git a/Mathlib/LinearAlgebra/RootSystem/RootPositive.lean b/Mathlib/LinearAlgebra/RootSystem/RootPositive.lean index 7a9f6fa2405a7b..e016f9d502c40a 100644 --- a/Mathlib/LinearAlgebra/RootSystem/RootPositive.lean +++ b/Mathlib/LinearAlgebra/RootSystem/RootPositive.lean @@ -139,11 +139,13 @@ def posForm : · simpa · simpa) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma algebraMap_posForm {x y : span S (range P.root)} : algebraMap S R (B.posForm x y) = B.form x y := by change Algebra.linearMap S R _ = _ simp [posForm] +set_option backward.isDefEq.respectTransparency.types false in lemma algebraMap_apply_eq_form_iff {x y : span S (range P.root)} {s : S} : algebraMap S R s = B.form x y ↔ s = B.posForm x y := by simp [RootPositiveForm.posForm] diff --git a/Mathlib/LinearAlgebra/Semisimple.lean b/Mathlib/LinearAlgebra/Semisimple.lean index b1f03b5a9386d0..8c9f85f8544db5 100644 --- a/Mathlib/LinearAlgebra/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Semisimple.lean @@ -75,6 +75,7 @@ lemma isSemisimple_iff : f.IsSemisimple ↔ ∀ p ∈ invtSubmodule f, ∃ q ∈ invtSubmodule f, IsCompl p q := by simp [isSemisimple_iff'] +set_option backward.isDefEq.respectTransparency.types false in lemma isSemisimple_restrict_iff (p) (hp : p ∈ invtSubmodule f) : IsSemisimple (LinearMap.restrict f hp) ↔ ∀ q ∈ f.invtSubmodule, q ≤ p → ∃ r ≤ p, r ∈ f.invtSubmodule ∧ Disjoint q r ∧ q ⊔ r = p := by @@ -129,6 +130,7 @@ lemma eq_zero_of_isNilpotent_isSemisimple (hn : IsNilpotent f) (hs : f.IsSemisim rw [← RingHom.mem_ker, ← AEval.annihilator_eq_ker_aeval (M := M)] at h0 ⊢ exact hs.annihilator_isRadical _ _ ⟨n, h0⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma eq_zero_of_isNilpotent_of_isFinitelySemisimple (hn : IsNilpotent f) (hs : IsFinitelySemisimple f) : f = 0 := by have (p) (hp₁ : p ∈ f.invtSubmodule) (hp₂ : Module.Finite R p) : f.restrict hp₁ = 0 := by diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean index 2bf7edd06ba716..e7b501403596c6 100644 --- a/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Basic.lean @@ -807,6 +807,7 @@ end Nondegenerate namespace BilinForm +set_option backward.isDefEq.respectTransparency false in lemma apply_smul_sub_smul_sub_eq [CommRing R] [AddCommGroup M] [Module R M] (B : LinearMap.BilinForm R M) (x y : M) : B ((B x y) • x - (B x x) • y) ((B x y) • x - (B x x) • y) = @@ -898,6 +899,7 @@ lemma nondegenerate_restrict_iff_disjoint_ker (hs : ∀ x, 0 ≤ B x x) (hB : B. variable [IsTorsionFree R M] +set_option backward.isDefEq.respectTransparency false in /-- Strict **Cauchy-Schwarz** is equivalent to linear independence for positive definite forms. -/ lemma apply_mul_apply_lt_iff_linearIndependent (hp : ∀ x, x ≠ 0 → 0 < B x x) (x y : M) : B x y * B y x < B x x * B y y ↔ LinearIndependent R ![x, y] := by diff --git a/Mathlib/LinearAlgebra/SesquilinearForm/Star.lean b/Mathlib/LinearAlgebra/SesquilinearForm/Star.lean index 44d8d1e7433628..b2fc28e057fb37 100644 --- a/Mathlib/LinearAlgebra/SesquilinearForm/Star.lean +++ b/Mathlib/LinearAlgebra/SesquilinearForm/Star.lean @@ -22,6 +22,7 @@ variable {R M n : Type*} [CommSemiring R] [StarRing R] [AddCommMonoid M] [Module [Fintype n] [DecidableEq n] {B : M →ₗ⋆[R] M →ₗ[R] R} (b : Basis n R M) +set_option backward.isDefEq.respectTransparency false in lemma LinearMap.isSymm_iff_basis {ι : Type*} (b : Basis ι R M) : IsSymm B ↔ ∀ i j, star (B (b i) (b j)) = B (b j) (b i) where mp h i j := h.eq _ _ diff --git a/Mathlib/LinearAlgebra/Span/Defs.lean b/Mathlib/LinearAlgebra/Span/Defs.lean index 311ccc1120f7f8..881ec49d436539 100644 --- a/Mathlib/LinearAlgebra/Span/Defs.lean +++ b/Mathlib/LinearAlgebra/Span/Defs.lean @@ -679,6 +679,7 @@ theorem Module.isPrincipal_submodule_iff {p : Submodule R M} : have ⟨r, hr⟩ := mem_span_singleton.mp (ha.le x.2) exact mem_span_singleton.mpr ⟨r, Subtype.ext hr⟩ +set_option backward.isDefEq.respectTransparency false in theorem Module.IsPrincipal.of_surjective (f : M →ₗ[R] M₂) (hf : Function.Surjective f) [IsPrincipal R M] : IsPrincipal R M₂ where principal := by diff --git a/Mathlib/LinearAlgebra/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/SpecialLinearGroup.lean index c706dc95a45b27..b5c47a967f0dde 100644 --- a/Mathlib/LinearAlgebra/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/SpecialLinearGroup.lean @@ -70,6 +70,7 @@ theorem ext (u v : SpecialLinearGroup R V) : (∀ x, u x = v x) → u = v := section rankOne +set_option backward.isDefEq.respectTransparency.types false in /-- If a free module has `Module.finrank` equal to `1`, then its special linear group is trivial. -/ theorem subsingleton_of_finrank_eq_one [Module.Free R V] (d1 : Module.finrank R V = 1) : Subsingleton (SpecialLinearGroup R V) where @@ -523,6 +524,7 @@ theorem centerEquivRootsOfUnity_apply_of_finrank_le_one apply rootsOfUnity.eq_one rw [Nat.max_eq_right d1] +set_option backward.isDefEq.respectTransparency.types false in theorem centerEquivRootsOfUnity_symm_apply (r : rootsOfUnity (max (Module.finrank R V) 1) R) : (centerEquivRootsOfUnity.symm r : V →ₗ[R] V) = r • LinearMap.id := by diff --git a/Mathlib/LinearAlgebra/StdBasis.lean b/Mathlib/LinearAlgebra/StdBasis.lean index 843555ee5da950..6e83f65a5ce362 100644 --- a/Mathlib/LinearAlgebra/StdBasis.lean +++ b/Mathlib/LinearAlgebra/StdBasis.lean @@ -80,6 +80,7 @@ protected noncomputable def basis (s : ∀ j, Basis (ιs j) R (Ms j)) : ((LinearEquiv.piCongrRight fun j => (s j).repr) ≪≫ₗ (Finsupp.sigmaFinsuppLEquivPiFinsupp R).symm) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem basis_repr_single [DecidableEq η] (s : ∀ j, Basis (ιs j) R (Ms j)) (j i) : (Pi.basis s).repr (Pi.single j (s j i)) = Finsupp.single ⟨j, i⟩ 1 := by diff --git a/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean b/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean index 4a1147d6b0fbc8..69cc0a56e52835 100644 --- a/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/SymmetricAlgebra/Basic.lean @@ -108,6 +108,7 @@ where finally variable (f : M →ₗ[R] A) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_ι_apply (a : M) : lift f (ι R M a) = f a := by simp [lift, ι, algHom, RingCon.liftₐEquiv] diff --git a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean index 0c7432ee0cca7a..bb23779f58df01 100644 --- a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean @@ -119,6 +119,7 @@ theorem ringQuot_mkAlgHom_freeAlgebra_ι_eq_ι (m : M) : rw [ι] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Given a linear map `f : M → A` where `A` is an `R`-algebra, `lift R f` is the unique lift of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`. -/ @@ -158,6 +159,7 @@ theorem lift_ι_apply {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A) conv_rhs => rw [← ι_comp_lift f] rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lift_unique {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A) (g : TensorAlgebra R M →ₐ[R] A) : g.toLinearMap.comp (ι R) = f ↔ g = lift R f := by diff --git a/Mathlib/LinearAlgebra/TensorPower/Basic.lean b/Mathlib/LinearAlgebra/TensorPower/Basic.lean index 8c920d358a1af7..49e1a4518a5e2e 100644 --- a/Mathlib/LinearAlgebra/TensorPower/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorPower/Basic.lean @@ -45,6 +45,7 @@ variable {R : Type*} {M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M] namespace PiTensorProduct +set_option backward.isDefEq.respectTransparency false in /-- Two dependent pairs of tensor products are equal if their index is equal and the contents are equal after a canonical reindexing. -/ @[ext (iff := false)] @@ -133,6 +134,7 @@ theorem cast_eq_cast {i j} (h : i = j) : rw [cast_refl] rfl +set_option backward.isDefEq.respectTransparency false in variable (R) in theorem tprod_mul_tprod {na nb} (a : Fin na → M) (b : Fin nb → M) : tprod R a ₜ* tprod R b = tprod R (Fin.append a b) := by @@ -234,6 +236,7 @@ instance gsemiring : DirectSum.GSemiring fun i => ⨂[R]^i M := example : Semiring (⨁ n : ℕ, ⨂[R]^n M) := by infer_instance +set_option backward.isDefEq.respectTransparency false in /-- The tensor powers form a graded algebra. Note that this instance implies `Algebra R (⨁ n : ℕ, ⨂[R]^n M)` via `DirectSum.Algebra`. -/ diff --git a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean index 4784cba63d32aa..132f843798ef38 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean @@ -308,6 +308,7 @@ variable (R) (A S M N : Type*) [AddCommMonoid M] [AddCommMonoid N] [Module R M] [CommSemiring S] [Module S M] [SMulCommClass R S M] [SMulCommClass A S M] [CompatibleSMul R A M N] +set_option backward.isDefEq.respectTransparency false in /-- If M and N are both R- and A-modules and their actions on them commute, and if the A-action on `M ⊗[R] N` can switch between the two factors, then there is a canonical S-linear map from `M ⊗[A] N` to `M ⊗[R] N`, diff --git a/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean b/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean index f4c22833bc685d..b26fafbc838363 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean @@ -237,6 +237,7 @@ theorem gradedMul_one (x : (⨁ i, 𝒜 i) ⊗[R] (⨁ i, ℬ i)) : simpa only [RingHom.map_one, one_smul] using! gradedMul_algebraMap 𝒜 ℬ x 1 set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in theorem gradedMul_assoc (x y z : DirectSum _ 𝒜 ⊗[R] DirectSum _ ℬ) : gradedMul R 𝒜 ℬ (gradedMul R 𝒜 ℬ x y) z = gradedMul R 𝒜 ℬ x (gradedMul R 𝒜 ℬ y z) := by let mA := gradedMul R 𝒜 ℬ @@ -256,6 +257,7 @@ theorem gradedMul_assoc (x y z : DirectSum _ 𝒜 ⊗[R] DirectSum _ ℬ) : abel set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in theorem gradedComm_gradedMul (x y : DirectSum _ 𝒜 ⊗[R] DirectSum _ ℬ) : gradedComm R 𝒜 ℬ (gradedMul R 𝒜 ℬ x y) = gradedMul R ℬ 𝒜 (gradedComm R 𝒜 ℬ x) (gradedComm R 𝒜 ℬ y) := by diff --git a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean index 99efa2312c3080..781eed9016964a 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean @@ -152,6 +152,7 @@ def piScalarRightInv : (ι → N) →ₗ[S] N ⊗[R] (ι → R) := map_smul' := fun _ _ ↦ rfl } +set_option backward.isDefEq.respectTransparency false in @[simp] private lemma piScalarRightInv_single (x : N) (i : ι) : piScalarRightInv R S N ι (Pi.single i x) = x ⊗ₜ Pi.single i 1 := by diff --git a/Mathlib/LinearAlgebra/TensorProduct/Prod.lean b/Mathlib/LinearAlgebra/TensorProduct/Prod.lean index 09ae19c0dfb30d..ef54c68077180f 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Prod.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Prod.lean @@ -36,6 +36,7 @@ variable [Module R M₁] [Module S M₁] [IsScalarTower R S M₁] [Module R M₂ attribute [ext] TensorProduct.ext +set_option backward.isDefEq.respectTransparency false in /-- Tensor products distribute over a product on the right. -/ def prodRight : M₁ ⊗[R] (M₂ × M₃) ≃ₗ[S] (M₁ ⊗[R] M₂) × (M₁ ⊗[R] M₃) := LinearEquiv.ofLinear diff --git a/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean b/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean index 298b9922c1dc6f..065aa400683b3f 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean @@ -204,6 +204,7 @@ noncomputable def lTensor.toFun (hfg : Exact f g) : rw [LinearMap.range_le_iff_comap, ← LinearMap.ker_comp, ← lTensor_comp, hfg.linearMap_comp_eq_zero, lTensor_zero, ker_zero] +set_option backward.isDefEq.respectTransparency false in /-- The inverse map in `lTensor.equiv_of_rightInverse` (computably, given a right inverse) -/ noncomputable def lTensor.inverse_of_rightInverse {h : P → N} (hfg : Exact f g) (hgh : Function.RightInverse h g) : @@ -311,6 +312,7 @@ noncomputable def rTensor.toFun (hfg : Exact f g) : rw [range_le_iff_comap, ← ker_comp, ← rTensor_comp, hfg.linearMap_comp_eq_zero, rTensor_zero, ker_zero] +set_option backward.isDefEq.respectTransparency false in /-- The inverse map in `rTensor.equiv_of_rightInverse` (computably, given a right inverse) -/ noncomputable def rTensor.inverse_of_rightInverse {h : P → N} (hfg : Exact f g) (hgh : Function.RightInverse h g) : diff --git a/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean b/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean index 174859ad12e7f1..b4f1a8718ed701 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean @@ -129,6 +129,7 @@ namespace Algebra.TensorProduct variable (R S T) +set_option backward.isDefEq.respectTransparency false in /-- Given `R`-algebras `S,T`, there is a natural `R`-linear isomorphism from `S ⊗[R] T` to `S' ⊗[R] T'` where `S',T'` are the images of `S,T` in `S ⊗[R] T` respectively. This is promoted to an `R`-algebra isomorphism `Algebra.TensorProduct.algEquivIncludeRange`. -/ diff --git a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean index c71de9452136f5..1a388d0358d181 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean @@ -519,6 +519,7 @@ section rightComm variable [CommSemiring S] [Module S M] [Module S P] [Algebra S B] [IsScalarTower S B M] [SMulCommClass R S M] [SMulCommClass S R M] +set_option backward.isDefEq.respectTransparency false in variable (S) in /-- A tensor product analogue of `mul_right_comm`. diff --git a/Mathlib/LinearAlgebra/UnitaryGroup.lean b/Mathlib/LinearAlgebra/UnitaryGroup.lean index 22e5dd7e6da820..2bc60a3c9927cd 100644 --- a/Mathlib/LinearAlgebra/UnitaryGroup.lean +++ b/Mathlib/LinearAlgebra/UnitaryGroup.lean @@ -324,6 +324,7 @@ theorem mem_specialOrthogonalGroup_iff : A ∈ specialOrthogonalGroup n R ↔ A ∈ orthogonalGroup n R ∧ A.det = 1 := Iff.rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma of_mem_specialOrthogonalGroup_fin_two_iff {a b c d : R} : !![a, b; c, d] ∈ Matrix.specialOrthogonalGroup (Fin 2) R ↔ diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index e1f659e30a1de0..ebcd43198e0ad1 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -481,7 +481,7 @@ theorem congr_fun_congr_arg {α β γ : Sort*} (f : α → β → γ) {a a' : α theorem rec_heq_of_heq {α β : Sort _} {a b : α} {C : α → Sort*} {x : C a} {y : β} (e : a = b) (h : x ≍ y) : e ▸ x ≍ y := - eqRec_heq_iff_heq.mpr h + eqRec_heq_iff.mpr h @[simp] theorem cast_heq_iff_heq {α β γ : Sort _} (e : α = β) (a : α) (c : γ) : @@ -765,15 +765,15 @@ noncomputable def dec (p : Prop) : Decidable p := by infer_instance variable {α : Sort*} /-- Any predicate `p` is decidable classically. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def decPred (p : α → Prop) : DecidablePred p := by infer_instance /-- Any relation `p` is decidable classically. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def decRel (p : α → α → Prop) : DecidableRel p := by infer_instance /-- Any type `α` has decidable equality classically. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def decEq (α : Sort*) : DecidableEq α := by infer_instance /-- Construct a function from a default value `H0`, and a function to use if there exists a value diff --git a/Mathlib/Logic/Denumerable.lean b/Mathlib/Logic/Denumerable.lean index 5aaaa995d10a59..d581bf2173465a 100644 --- a/Mathlib/Logic/Denumerable.lean +++ b/Mathlib/Logic/Denumerable.lean @@ -76,7 +76,7 @@ instance (priority := 100) : Infinite α := Infinite.of_surjective _ (eqv α).surjective /-- A type equivalent to `ℕ` is denumerable. -/ -@[implicit_reducible] +@[instance_reducible] def mk' {α} (e : α ≃ ℕ) : Denumerable α where encode := e decode := some ∘ e.symm @@ -85,7 +85,7 @@ def mk' {α} (e : α ≃ ℕ) : Denumerable α where /-- Denumerability is conserved by equivalences. This is transitivity of equivalence the denumerable way. -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv (α) {β} [Denumerable α] (e : β ≃ α) : Denumerable β := { Encodable.ofEquiv _ e with decode_inv := fun n => by @@ -297,7 +297,7 @@ private theorem right_inverse_aux : ∀ n, toFunAux (ofNat s n) = n set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Any infinite set of naturals is denumerable. -/ -@[implicit_reducible] +@[instance_reducible] def denumerable (s : Set ℕ) [DecidablePred (· ∈ s)] [Infinite s] : Denumerable s := Denumerable.ofEquiv ℕ { toFun := toFunAux @@ -312,7 +312,7 @@ namespace Denumerable open Encodable /-- An infinite encodable type is denumerable. -/ -@[implicit_reducible] +@[instance_reducible] def ofEncodableOfInfinite (α : Type*) [Encodable α] [Infinite α] : Denumerable α := by letI := @decidableRangeEncode α _ letI : Infinite (Set.range (@encode α _)) := diff --git a/Mathlib/Logic/Embedding/Set.lean b/Mathlib/Logic/Embedding/Set.lean index d0136440aafa1c..ab78cd95916d76 100644 --- a/Mathlib/Logic/Embedding/Set.lean +++ b/Mathlib/Logic/Embedding/Set.lean @@ -45,6 +45,7 @@ namespace Embedding def optionElim {α β} (f : α ↪ β) (x : β) (h : x ∉ Set.range f) : Option α ↪ β := ⟨Option.elim' x f, Option.injective_iff.2 ⟨f.2, h⟩⟩ +set_option backward.isDefEq.respectTransparency false in /-- Equivalence between embeddings of `Option α` and a sigma type over the embeddings of `α`. -/ @[simps] def optionEmbeddingEquiv (α β) : (Option α ↪ β) ≃ Σ f : α ↪ β, ↥(Set.range f)ᶜ where diff --git a/Mathlib/Logic/Encodable/Basic.lean b/Mathlib/Logic/Encodable/Basic.lean index 33da624467b19e..3387a71bde9395 100644 --- a/Mathlib/Logic/Encodable/Basic.lean +++ b/Mathlib/Logic/Encodable/Basic.lean @@ -93,20 +93,20 @@ def decidableEqOfEncodable (α) [Encodable α] : DecidableEq α | _, _ => decidable_of_iff _ encode_inj /-- If `α` is encodable and there is an injection `f : β → α`, then `β` is encodable as well. -/ -@[implicit_reducible] +@[instance_reducible] def ofLeftInjection [Encodable α] (f : β → α) (finv : α → Option β) (linv : ∀ b, finv (f b) = some b) : Encodable β := ⟨fun b => encode (f b), fun n => (decode n).bind finv, fun b => by simp [Encodable.encodek, linv]⟩ /-- If `α` is encodable and `f : β → α` is invertible, then `β` is encodable as well. -/ -@[implicit_reducible] +@[instance_reducible] def ofLeftInverse [Encodable α] (f : β → α) (finv : α → β) (linv : ∀ b, finv (f b) = b) : Encodable β := ofLeftInjection f (some ∘ finv) fun b => congr_arg some (linv b) /-- Encodability is preserved by equivalence. -/ -@[implicit_reducible] +@[instance_reducible] def ofEquiv (α) [Encodable α] (e : β ≃ α) : Encodable β := ofLeftInverse e e.symm e.left_inv @@ -226,7 +226,7 @@ def equivRangeEncode (α : Type*) [Encodable α] : α ≃ Set.range (@encode α right_inv _ := Subtype.ext <| decode₂_isPartialInv.get_eq _ _ /-- A type with unique element is encodable. This is not an instance to avoid diamonds. -/ -@[implicit_reducible] +@[instance_reducible] def _root_.Unique.encodable [Unique α] : Encodable α := ⟨fun _ => 0, fun _ => some default, Unique.forall_iff.2 rfl⟩ @@ -387,12 +387,12 @@ instance _root_.PLift.encodable [Encodable α] : Encodable (PLift α) := ofEquiv _ Equiv.plift /-- If `β` is encodable and there is an injection `f : α → β`, then `α` is encodable as well. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofInj [Encodable β] (f : α → β) (hf : Injective f) : Encodable α := ofLeftInjection f (partialInv f) hf.isPartialInv.eq /-- If `α` is countable, then it has a (non-canonical) `Encodable` structure. -/ -@[no_expose, implicit_reducible] +@[no_expose, instance_reducible] noncomputable def ofCountable (α : Type*) [Countable α] : Encodable α := Nonempty.some <| let ⟨f, hf⟩ := exists_injective_nat α @@ -615,7 +615,7 @@ theorem Quotient.rep_spec (q : Quotient s) : ⟦q.rep⟧ = q := choose_spec (exists_rep q) /-- The quotient of an encodable space by a decidable equivalence relation is encodable. -/ -@[implicit_reducible] +@[instance_reducible] def encodableQuotient : Encodable (Quotient s) := ⟨fun q => encode q.rep, fun n => Quotient.mk'' <$> decode n, by rintro ⟨l⟩; dsimp; rw [encodek]; exact congr_arg some ⟦l⟧.rep_spec⟩ diff --git a/Mathlib/Logic/Equiv/Basic.lean b/Mathlib/Logic/Equiv/Basic.lean index 71f756841ff173..15df8adf560a48 100644 --- a/Mathlib/Logic/Equiv/Basic.lean +++ b/Mathlib/Logic/Equiv/Basic.lean @@ -442,6 +442,7 @@ def sigmaSubtype {α : Type*} {β : α → Type*} (a : α) : section attribute [local simp] Trans.trans sigmaAssoc subtypeSigmaEquiv uniqueSigma eqRec_eq_cast +set_option backward.isDefEq.respectTransparency.types false in /-- A subtype of a dependent triple which pins down both bases is equivalent to the respective fiber. -/ @[simps! +simpRhs apply] @@ -456,6 +457,7 @@ def sigmaSigmaSubtype {α : Type*} {β : α → Type*} {γ : (a : α) → β a _ ≃ γ a b := Equiv.cast <| by rw [← show ⟨⟨a, b⟩, h⟩ = uniq.default from uniq.uniq _] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma sigmaSigmaSubtype_symm_apply {α : Type*} {β : α → Type*} {γ : (a : α) → β a → Type*} (p : (a : α) × β a → Prop) [uniq : Unique {ab // p ab}] @@ -474,6 +476,7 @@ def sigmaSigmaSubtypeEq {α β : Type*} {γ : α → β → Type*} (a : α) (b : sigmaSigmaSubtype (fun ⟨a', b'⟩ ↦ a' = a ∧ b' = b) ⟨rfl, rfl⟩ set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma sigmaSigmaSubtypeEq_apply {α β : Type*} {γ : α → β → Type*} {a : α} {b : β} (s : {s : (a : α) × (b : β) × γ a b // s.1 = a ∧ s.2.1 = b}) : @@ -813,6 +816,7 @@ LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. For we have to explicitly substitute along `e.symm (e a) = a` in the statement of this lemma. -/ add_decl_doc Equiv.piCongrLeft'_symm_apply +set_option backward.isDefEq.respectTransparency.types false in /-- This lemma is impractical to state in the dependent case. -/ @[simp] theorem piCongrLeft'_symm (P : Sort*) (e : α ≃ β) : @@ -825,7 +829,7 @@ around it in the case where `a` is of the form `e.symm b`, so we can use `g b` i @[simp] lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) : (piCongrLeft' P e).symm g (e.symm b) = g b := by - rw [piCongrLeft'_symm_apply, ← heq_iff_eq, eqRec_heq_iff_heq] + rw [piCongrLeft'_symm_apply, ← heq_iff_eq, eqRec_heq_iff] exact congr_arg_heq _ (e.apply_symm_apply _) @[simp] diff --git a/Mathlib/Logic/Equiv/Defs.lean b/Mathlib/Logic/Equiv/Defs.lean index 532d1b9b997f17..54fb7aee272d45 100644 --- a/Mathlib/Logic/Equiv/Defs.lean +++ b/Mathlib/Logic/Equiv/Defs.lean @@ -143,7 +143,7 @@ protected theorem Perm.congr_fun {f g : Equiv.Perm α} (h : f = g) (x : α) : f instance inhabited' : Inhabited (α ≃ α) := ⟨Equiv.refl α⟩ /-- Inverse of an equivalence `e : α ≃ β`. -/ -@[symm] +@[symm, implicit_reducible] protected def symm (e : α ≃ β) : β ≃ α := ⟨e.invFun, e.toFun, e.right_inv, e.left_inv⟩ /-- See Note [custom simps projection] -/ diff --git a/Mathlib/Logic/Equiv/Embedding.lean b/Mathlib/Logic/Equiv/Embedding.lean index 0567b1ccbfbf6b..5c6c7979d37b0b 100644 --- a/Mathlib/Logic/Equiv/Embedding.lean +++ b/Mathlib/Logic/Equiv/Embedding.lean @@ -81,6 +81,7 @@ def sumEmbeddingEquivSigmaEmbeddingRestricted {α β γ : Type*} : Equiv.trans sumEmbeddingEquivProdEmbeddingDisjoint prodEmbeddingDisjointEquivSigmaEmbeddingRestricted +set_option backward.isDefEq.respectTransparency false in /-- Embeddings from a single-member type are equivalent to members of the target type. -/ def uniqueEmbeddingEquivResult {α β : Type*} [Unique α] : (α ↪ β) ≃ β where diff --git a/Mathlib/Logic/Equiv/Fin/Basic.lean b/Mathlib/Logic/Equiv/Fin/Basic.lean index 5bea2e2b9b043e..e6ba761f91e688 100644 --- a/Mathlib/Logic/Equiv/Fin/Basic.lean +++ b/Mathlib/Logic/Equiv/Fin/Basic.lean @@ -29,6 +29,7 @@ variable {m n : ℕ} This is currently not very sorted. PRs welcome! -/ +set_option backward.isDefEq.respectTransparency false in theorem Fin.preimage_apply_01_prod {α : Fin 2 → Type u} (s : Set (α 0)) (t : Set (α 1)) : (fun f : ∀ i, α i => (f 0, f 1)) ⁻¹' s ×ˢ t = Set.pi Set.univ (Fin.cons s <| Fin.cons t finZeroElim) := by @@ -61,6 +62,7 @@ def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n) where left_inv x := Fin.succAboveCases i (by simp) (fun j => by simp) x right_inv x := by cases x <;> simp +set_option backward.isDefEq.respectTransparency false in @[simp] theorem finSuccEquiv'_at (i : Fin (n + 1)) : (finSuccEquiv' i) i = none := by simp [finSuccEquiv'] diff --git a/Mathlib/Logic/Equiv/Fintype.lean b/Mathlib/Logic/Equiv/Fintype.lean index 85d45a2e568841..d7ddb9e5785c79 100644 --- a/Mathlib/Logic/Equiv/Fintype.lean +++ b/Mathlib/Logic/Equiv/Fintype.lean @@ -135,6 +135,7 @@ Note that when `p = q`, `Equiv.Perm.subtypeCongr e (Equiv.refl _)` can be used i noncomputable abbrev extendSubtype (e : { x // p x } ≃ { x // q x }) : Perm α := subtypeCongr e e.toCompl +set_option backward.isDefEq.respectTransparency false in theorem extendSubtype_apply_of_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) : e.extendSubtype x = e ⟨x, hx⟩ := by simp [extendSubtype, subtypeCongr, sumCompl_symm_apply_of_pos hx] @@ -145,8 +146,8 @@ theorem extendSubtype_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) : theorem extendSubtype_apply_of_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) : e.extendSubtype x = e.toCompl ⟨x, hx⟩ := by - simp only [extendSubtype, subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply, - sumCompl_symm_apply_of_neg hx, Sum.map_inr, sumCompl_apply_inr] + simp only [extendSubtype, subtypeCongr, Equiv.trans_apply, + sumCompl_symm_apply_of_neg hx] rfl theorem extendSubtype_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) : diff --git a/Mathlib/Logic/Equiv/List.lean b/Mathlib/Logic/Equiv/List.lean index e0925ea0fd802b..4c6e52c845a488 100644 --- a/Mathlib/Logic/Equiv/List.lean +++ b/Mathlib/Logic/Equiv/List.lean @@ -106,7 +106,7 @@ instance _root_.Finset.countable [Countable α] : Countable (Finset α) := Finset.val_injective.countable /-- A listable type with decidable equality is encodable. -/ -@[implicit_reducible] +@[instance_reducible] def encodableOfList [DecidableEq α] (l : List α) (H : ∀ x, x ∈ l) : Encodable α := ⟨fun a => idxOf a l, (l[·]?), fun _ => getElem?_idxOf (H _)⟩ @@ -119,7 +119,7 @@ def _root_.Fintype.truncEncodable (α : Type*) [DecidableEq α] [Fintype α] : T /-- A noncomputable way to arbitrarily choose an ordering on a finite type. It is not made into a global instance, since it involves an arbitrary choice. This can be locally made into an instance with `attribute [local instance] Fintype.toEncodable`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def _root_.Fintype.toEncodable (α : Type*) [Fintype α] : Encodable α := by classical exact (Fintype.truncEncodable α).out diff --git a/Mathlib/Logic/Equiv/Option.lean b/Mathlib/Logic/Equiv/Option.lean index 6419012cdb2fb3..af0cade210219a 100644 --- a/Mathlib/Logic/Equiv/Option.lean +++ b/Mathlib/Logic/Equiv/Option.lean @@ -151,6 +151,7 @@ end RemoveNone theorem optionCongr_injective : Function.Injective (optionCongr : α ≃ β → Option α ≃ Option β) := Function.LeftInverse.injective removeNone_optionCongr +set_option backward.isDefEq.respectTransparency false in /-- Equivalences between `Option α` and `β` that send `none` to `x` are equivalent to equivalences between `α` and `{y : β // y ≠ x}`. -/ def optionSubtype [DecidableEq β] (x : β) : @@ -204,6 +205,7 @@ theorem coe_optionSubtype_apply_apply (e : { e : Option α ≃ β // e none = x }) (a : α) : ↑(optionSubtype x e a) = (e : Option α ≃ β) a := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem optionSubtype_apply_symm_apply [DecidableEq β] (x : β) @@ -232,6 +234,7 @@ theorem optionSubtype_symm_apply_apply_none (e : α ≃ { y : β // y ≠ x }) : ((optionSubtype x).symm e : Option α ≃ β) none = x := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem optionSubtype_symm_apply_symm_apply [DecidableEq β] (x : β) (e : α ≃ { y : β // y ≠ x }) (b : { y : β // y ≠ x }) : ((optionSubtype x).symm e : Option α ≃ β).symm b = e.symm b := by diff --git a/Mathlib/Logic/Equiv/PartialEquiv.lean b/Mathlib/Logic/Equiv/PartialEquiv.lean index 37cf911ee21e7c..4dc289c751030d 100644 --- a/Mathlib/Logic/Equiv/PartialEquiv.lean +++ b/Mathlib/Logic/Equiv/PartialEquiv.lean @@ -79,7 +79,7 @@ This is in a separate file from `Mathlib/Tactic/Attr/Register.lean` because attr new file to become functional. -/ -namespace Tactic.MfldSetTac +namespace Mathlib.Tactic.MfldSetTac /-- A very basic tactic to show that sets showing up in manifolds coincide or are included in one another. -/ @@ -103,7 +103,7 @@ elab (name := mfldSetTac) "mfld_set_tac" : tactic => withMainContext do attribute [mfld_simps] and_true eq_self_iff_true Function.comp_apply -end Tactic.MfldSetTac +end Mathlib.Tactic.MfldSetTac open Function Set diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index b430f0e1e4d1cf..8989b173d1a22f 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -341,7 +341,7 @@ theorem sumDiffSubset_symm_apply_of_mem {α} {s t : Set α} (h : s ⊆ t) [Decid theorem sumDiffSubset_symm_apply_of_notMem {α} {s t : Set α} (h : s ⊆ t) [DecidablePred (· ∈ s)] {x : t} (hx : x.1 ∉ s) : (Equiv.Set.sumDiffSubset h).symm x = Sum.inr ⟨x, ⟨x.2, hx⟩⟩ := by apply (Equiv.Set.sumDiffSubset h).injective - simp only [apply_symm_apply, sumDiffSubset_apply_inr, Set.inclusion_mk] + simp only [apply_symm_apply, sumDiffSubset_apply_inr] /-- If `s` is a set with decidable membership, then the sum of `s ∪ t` and `s ∩ t` is equivalent to `s ⊕ t`. -/ @@ -362,6 +362,7 @@ protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ { rw [(_ : t \ s ∪ s ∩ t = t)] rw [union_comm, inter_comm, inter_union_sdiff] } +set_option backward.isDefEq.respectTransparency false in /-- Given an equivalence `e₀` between sets `s : Set α` and `t : Set β`, the set of equivalences `e : α ≃ β` such that `e ↑x = ↑(e₀ x)` for each `x : s` is equivalent to the set of equivalences between `sᶜ` and `tᶜ`. -/ @@ -429,6 +430,7 @@ protected theorem image_symm_apply {α β} (f : α → β) (s : Set α) (H : Inj (h : f x ∈ f '' s) : (Set.image f s H).symm ⟨f x, h⟩ = ⟨x, H.mem_set_image.1 h⟩ := (Equiv.symm_apply_eq _).2 rfl +set_option backward.isDefEq.respectTransparency false in theorem image_symm_preimage {α β} {f : α → β} (hf : Injective f) (u s : Set α) : (fun x => (Set.image f s hf).symm x : f '' s → α) ⁻¹' u = Subtype.val ⁻¹' f '' u := by ext ⟨b, a, has, rfl⟩ @@ -581,6 +583,9 @@ def sigmaPreimageEquiv {α β} (f : α → β) : (Σ b, f ⁻¹' {b}) ≃ α := sigmaFiberEquiv f -- See also `Equiv.ofFiberEquiv`. +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A family of equivalences between preimages of points gives an equivalence between domains. -/ @[simps!] def ofPreimageEquiv {α β γ} {f : α → γ} {g : β → γ} (e : ∀ c, f ⁻¹' {c} ≃ g ⁻¹' {c}) : α ≃ β := diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index ee08b2e5be7480..7e91e553f4e893 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -804,7 +804,7 @@ instance : IsEquiv α (EqvGen r) := is_equivalence _ |>.isEquiv The motivation for this definition is that `Quot r` behaves like `Quotient (EqvGen.setoid r)`, see for example `Quot.eqvGen_exact` and `Quot.eqvGen_sound`. -/ -@[implicit_reducible] +@[instance_reducible] def setoid : Setoid α := Setoid.mk _ (EqvGen.is_equivalence r) diff --git a/Mathlib/Logic/Small/Defs.lean b/Mathlib/Logic/Small/Defs.lean index 0699f6fceed2b8..3bea24e2b35134 100644 --- a/Mathlib/Logic/Small/Defs.lean +++ b/Mathlib/Logic/Small/Defs.lean @@ -118,6 +118,7 @@ instance small_sigma {α} (β : α → Type*) [Small.{w} α] [∀ a, Small.{w} ( ⟨⟨Σ a' : Shrink α, Shrink (β ((equivShrink α).symm a')), ⟨Equiv.sigmaCongr (equivShrink α) fun a => by simpa using equivShrink (β a)⟩⟩⟩ +set_option backward.isDefEq.respectTransparency false in theorem not_small_type : ¬Small.{u} (Type max u v) | ⟨⟨S, ⟨e⟩⟩⟩ => @Function.cantor_injective (Σ α, e.symm α) (fun a => ⟨_, cast (e.3 _).symm a⟩) fun a b e => by diff --git a/Mathlib/Logic/Unique.lean b/Mathlib/Logic/Unique.lean index e58e08169f6e71..dae1020bde6485 100644 --- a/Mathlib/Logic/Unique.lean +++ b/Mathlib/Logic/Unique.lean @@ -89,7 +89,7 @@ theorem PUnit.default_eq_unit : (default : PUnit) = PUnit.unit := rfl /-- Every provable proposition is unique, as all proofs are equal. -/ -@[implicit_reducible] +@[instance_reducible] def uniqueProp {p : Prop} (h : p) : Unique.{0} p where default := h uniq _ := rfl @@ -198,18 +198,18 @@ protected theorem Surjective.subsingleton [Subsingleton α] (hf : Surjective f) /-- If the domain of a surjective function is a singleton, then the codomain is a singleton as well. -/ -@[implicit_reducible] +@[instance_reducible] protected def Surjective.unique {α : Sort u} (f : α → β) (hf : Surjective f) [Unique.{u} α] : Unique β := @Unique.mk' _ ⟨f default⟩ hf.subsingleton /-- If `α` is inhabited and admits an injective map to a subsingleton type, then `α` is `Unique`. -/ -@[implicit_reducible] +@[instance_reducible] protected def Injective.unique [Inhabited α] [Subsingleton β] (hf : Injective f) : Unique α := @Unique.mk' _ _ hf.subsingleton /-- If a constant function is surjective, then the codomain is a singleton. -/ -@[implicit_reducible] +@[instance_reducible] def Surjective.uniqueOfSurjectiveConst (α : Type*) {β : Type*} (b : β) (h : Function.Surjective (Function.const α b)) : Unique β := @uniqueOfSubsingleton _ (subsingleton_of_forall_eq b <| h.forall.mpr fun _ ↦ rfl) b diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index 6e103889210543..1167b2f498e1c0 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -47,7 +47,7 @@ variable {α β γ γ₂ δ : Type*} {ι : Sort y} {s t u : Set α} open MeasurableSpace TopologicalSpace /-- `MeasurableSpace` structure generated by `TopologicalSpace`. -/ -@[implicit_reducible] +@[instance_reducible] def borel (α : Type u) [TopologicalSpace α] : MeasurableSpace α := generateFrom { s : Set α | IsOpen s } diff --git a/Mathlib/MeasureTheory/Constructions/Cylinders.lean b/Mathlib/MeasureTheory/Constructions/Cylinders.lean index b112f3470a309c..4b4200b0564466 100644 --- a/Mathlib/MeasureTheory/Constructions/Cylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/Cylinders.lean @@ -398,7 +398,7 @@ variable {α ι : Type*} {X : ι → Type*} {mα : MeasurableSpace α} [m : ∀ /-- The σ-algebra of cylinder events on `Δ`. It is the smallest σ-algebra making the projections on the `i`-th coordinate measurable for all `i ∈ Δ`. -/ -@[implicit_reducible] +@[instance_reducible] def cylinderEvents (Δ : Set ι) : MeasurableSpace (∀ i, X i) := ⨆ i ∈ Δ, (m i).comap fun σ ↦ σ i @[simp] lemma cylinderEvents_univ : cylinderEvents (X := X) univ = MeasurableSpace.pi := by diff --git a/Mathlib/MeasureTheory/Constructions/Pi.lean b/Mathlib/MeasureTheory/Constructions/Pi.lean index 888e669c9737ed..277c9469b38ac7 100644 --- a/Mathlib/MeasureTheory/Constructions/Pi.lean +++ b/Mathlib/MeasureTheory/Constructions/Pi.lean @@ -162,14 +162,14 @@ theorem tprod_tprod (l : List δ) (μ : ∀ i, Measure (X i)) [∀ i, SigmaFinit | nil => simp | cons a l ih => rw [tprod_cons, Set.tprod] - dsimp only [foldr_cons, map_cons, prod_cons] + simp only [foldr_cons, prod_cons, map_cons] rw [prod_prod, ih] end Tprod section Encodable -open List MeasurableEquiv +open List variable [Encodable ι] @@ -924,6 +924,7 @@ theorem volume_preserving_pi {α' β' : ι → Type*} [∀ i, MeasureSpace (α' MeasurePreserving (fun (a : (i : ι) → α' i) (i : ι) ↦ (f i) (a i)) := measurePreserving_pi _ _ hf +set_option backward.isDefEq.respectTransparency.types false in /-- The measurable equiv `(α₁ → β₁) ≃ᵐ (α₂ → β₂)` induced by `α₁ ≃ α₂` and `β₁ ≃ᵐ β₂` is measure preserving. -/ theorem measurePreserving_arrowCongr' {α₁ β₁ α₂ β₂ : Type*} [Fintype α₁] [Fintype α₂] diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index a229c479854842..fe727029a7cca7 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -93,7 +93,7 @@ a compatible Polish topology. Warning: following this with `borelize α` will cause an error. Instead, one can rewrite with `eq_borel_upgradeStandardBorel α`. TODO: fix the corresponding bug in `borelize`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def upgradeStandardBorel [MeasurableSpace α] [h : StandardBorelSpace α] : UpgradedStandardBorel α := by diff --git a/Mathlib/MeasureTheory/Constructions/UnitInterval.lean b/Mathlib/MeasureTheory/Constructions/UnitInterval.lean index 0b39ca13edfa63..abaec30425eeaf 100644 --- a/Mathlib/MeasureTheory/Constructions/UnitInterval.lean +++ b/Mathlib/MeasureTheory/Constructions/UnitInterval.lean @@ -49,6 +49,7 @@ instance : NullSingletonClass (volume : Measure I) where @[fun_prop] theorem measurable_symm : Measurable σ := continuous_symm.measurable +set_option backward.isDefEq.respectTransparency.types false in /-- `unitInterval.symm` bundled as a measurable equivalence. -/ @[simps apply] def symmMeasurableEquiv : I ≃ᵐ I where @@ -57,12 +58,15 @@ def symmMeasurableEquiv : I ≃ᵐ I where left_inv := symm_symm right_inv := symm_symm +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma symm_symmMeasurableEquiv : symmMeasurableEquiv.symm = symmMeasurableEquiv := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma coe_symmMeasurableEquiv : symmMeasurableEquiv = σ := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma measurePreserving_symm : MeasurePreserving symm volume volume where measurable := measurable_symm map_eq := by diff --git a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean index 7fb8db25c9b16e..6dc09757ddf3b1 100644 --- a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean +++ b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean @@ -226,6 +226,7 @@ theorem blimsup_cthickening_mul_ae_eq (p : ℕ → Prop) (s : ℕ → Set α) {M blimsup_congr (Eventually.of_forall h₂)] exact ae_eq_set_union (this (fun i => p i ∧ 0 < r i) hr') (ae_eq_refl _) +set_option backward.isDefEq.respectTransparency.types false in theorem blimsup_cthickening_ae_eq_blimsup_thickening {p : ℕ → Prop} {s : ℕ → Set α} {r : ℕ → ℝ} (hr : Tendsto r atTop (𝓝 0)) (hr' : ∀ᶠ i in atTop, p i → 0 < r i) : (blimsup (fun i => cthickening (r i) (s i)) atTop p : Set α) =ᵐ[μ] diff --git a/Mathlib/MeasureTheory/Function/AEEqFun.lean b/Mathlib/MeasureTheory/Function/AEEqFun.lean index 8a1138969e5bda..546c7a7d4bd733 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun.lean @@ -90,7 +90,7 @@ variable (β) /-- The equivalence relation of being almost everywhere equal for almost everywhere strongly measurable functions. -/ -@[implicit_reducible] +@[instance_reducible] def Measure.aeEqSetoid (μ : Measure α) : Setoid { f : α → β // AEStronglyMeasurable f μ } := ⟨fun f g => (f : α → β) =ᵐ[μ] g, fun {f} => ae_eq_refl f.val, fun {_ _} => ae_eq_symm, fun {_ _ _} => ae_eq_trans⟩ @@ -515,10 +515,12 @@ theorem compMeasurable_toGerm [MeasurableSpace β] [BorelSpace β] [PseudoMetriz (compMeasurable g hg f).toGerm = f.toGerm.map g := induction_on f fun f _ => by simp +set_option backward.isDefEq.respectTransparency false in theorem comp₂_toGerm (g : β → γ → δ) (hg : Continuous (uncurry g)) (f₁ : α →ₘ[μ] β) (f₂ : α →ₘ[μ] γ) : (comp₂ g hg f₁ f₂).toGerm = f₁.toGerm.map₂ g f₂.toGerm := induction_on₂ f₁ f₂ fun f₁ _ f₂ _ => by simp +set_option backward.isDefEq.respectTransparency false in theorem comp₂Measurable_toGerm [PseudoMetrizableSpace β] [MeasurableSpace β] [BorelSpace β] [PseudoMetrizableSpace γ] [SecondCountableTopologyEither β γ] [MeasurableSpace γ] [BorelSpace γ] [PseudoMetrizableSpace δ] [SecondCountableTopology δ] @@ -647,6 +649,7 @@ def const (b : β) : α →ₘ[μ] β := theorem coeFn_const (b : β) : (const α b : α →ₘ[μ] β) =ᵐ[μ] Function.const α b := coeFn_mk _ _ +set_option backward.isDefEq.respectTransparency false in /-- If the measure is nonzero, we can strengthen `coeFn_const` to get an equality. -/ @[simp] theorem coeFn_const_eq [NeZero μ] (b : β) (x : α) : (const α b : α →ₘ[μ] β) x = b := by diff --git a/Mathlib/MeasureTheory/Function/ConvergenceInDistribution.lean b/Mathlib/MeasureTheory/Function/ConvergenceInDistribution.lean index 1b24a1d99ccd27..61c6c61709a4b6 100644 --- a/Mathlib/MeasureTheory/Function/ConvergenceInDistribution.lean +++ b/Mathlib/MeasureTheory/Function/ConvergenceInDistribution.lean @@ -75,6 +75,7 @@ lemma tendstoInDistribution_const [OpensMeasurableSpace E] (hZ : AEMeasurable Z forall_aemeasurable := fun _ ↦ by fun_prop tendsto := tendsto_const_nhds +set_option backward.isDefEq.respectTransparency.types false in lemma tendstoInDistribution_of_identDistrib [OpensMeasurableSpace E] (i : ι) (hX : ∀ j, IdentDistrib (X i) (X j) (μ i) (μ j)) (hZ : IdentDistrib (X i) Z (μ i) μ') : TendstoInDistribution X l Z μ μ' where @@ -84,6 +85,7 @@ lemma tendstoInDistribution_of_identDistrib [OpensMeasurableSpace E] (i : ι) convert! tendsto_const_nhds with j exact (hX j).map_eq.symm.trans hZ.map_eq +set_option backward.isDefEq.respectTransparency.types false in protected lemma TendstoInDistribution.congr [OpensMeasurableSpace E] {T : Ω' → E} (hXY : ∀ i, X i =ᵐ[μ i] Y i) (hZT : Z =ᵐ[μ'] T) (h : TendstoInDistribution X l Z μ μ') : TendstoInDistribution Y l T μ μ' where @@ -113,6 +115,7 @@ lemma tendstoInDistribution_unique [HasOuterApproxClosed E] [BorelSpace E] rw [Subtype.ext_iff] at h_eq simpa using h_eq +set_option backward.isDefEq.respectTransparency.types false in /-- **Continuous mapping theorem**: if `X n` tends to `Z` in distribution and `g` is continuous, then `g ∘ X n` tends to `g ∘ Z` in distribution. -/ theorem TendstoInDistribution.continuous_comp {F : Type*} [OpensMeasurableSpace E] @@ -129,6 +132,7 @@ theorem TendstoInDistribution.continuous_comp {F : Type*} [OpensMeasurableSpace congr rw [AEMeasurable.map_map_of_aemeasurable hg.aemeasurable h.aemeasurable_limit] +set_option backward.isDefEq.respectTransparency.types false in /-- Almost sure convergence implies convergence in distribution. -/ theorem tendstoInDistribution_of_ae_tendsto [l.IsCountablyGenerated] [OpensMeasurableSpace E] {X : ι → Ω' → E} @@ -166,6 +170,7 @@ theorem TendstoInMeasure.tendstoInDistribution [PseudoEMetricSpace E] [BorelSpac variable [SeminormedAddCommGroup E] [SecondCountableTopology E] [BorelSpace E] +set_option backward.isDefEq.respectTransparency.types false in /-- Let `X, Y` be two sequences of measurable functions such that `X n` converges in distribution to `Z`, and `Y n - X n` converges in probability to `0`. Then `Y n` converges in distribution to `Z`. -/ @@ -290,6 +295,7 @@ lemma TendstoInMeasure.tendstoInDistribution_of_aemeasurable [l.IsCountablyGener tendstoInDistribution_of_tendstoInMeasure_sub X Z (tendstoInDistribution_const hZ) (by simpa [tendstoInMeasure_iff_norm] using h) hX +set_option backward.isDefEq.respectTransparency.types false in /-- **Slutsky's theorem**: if `X n` converges in distribution to `Z`, and `Y n` converges in probability to a constant `c`, then the pair `(X n, Y n)` converges in distribution to `(Z, c)`. -/ theorem TendstoInDistribution.prodMk_of_tendstoInMeasure_const diff --git a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean index d13f2470fe04c4..9c0a2c366006b4 100644 --- a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean @@ -661,16 +661,19 @@ theorem MonotoneOn.memLp_isCompact [IsFiniteMeasureOnCompacts μ] (hs : IsCompac · exact hmono.memLp_of_measure_ne_top (hs.isLeast_sInf h) (hs.isGreatest_sSup h) hs.measure_lt_top.ne hs.measurableSet +set_option backward.isDefEq.respectTransparency.types false in theorem AntitoneOn.memLp_top (hanti : AntitoneOn f s) {a b : X} (ha : IsLeast s a) (hb : IsGreatest s b) (h's : MeasurableSet s) : MemLp f ∞ (μ.restrict s) := MonotoneOn.memLp_top (E := Eᵒᵈ) hanti ha hb h's +set_option backward.isDefEq.respectTransparency.types false in theorem AntitoneOn.memLp_of_measure_ne_top (hanti : AntitoneOn f s) {a b : X} (ha : IsLeast s a) (hb : IsGreatest s b) (hs : μ s ≠ ∞) (h's : MeasurableSet s) : MemLp f p (μ.restrict s) := MonotoneOn.memLp_of_measure_ne_top (E := Eᵒᵈ) hanti ha hb hs h's +set_option backward.isDefEq.respectTransparency.types false in theorem AntitoneOn.memLp_isCompact [IsFiniteMeasureOnCompacts μ] (hs : IsCompact s) (hanti : AntitoneOn f s) : MemLp f p (μ.restrict s) := MonotoneOn.memLp_isCompact (E := Eᵒᵈ) hs hanti @@ -705,6 +708,7 @@ theorem Monotone.locallyIntegrable [IsLocallyFiniteMeasure μ] (hmono : Monotone (hmono.monotoneOn _).integrableOn_of_measure_ne_top (isLeast_Icc ab) (isGreatest_Icc ab) ((measure_mono abU).trans_lt h'U).ne measurableSet_Icc +set_option backward.isDefEq.respectTransparency.types false in theorem Antitone.locallyIntegrable [IsLocallyFiniteMeasure μ] (hanti : Antitone f) : LocallyIntegrable f μ := hanti.dual_right.locallyIntegrable diff --git a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean index da03fba965ce30..fec382a50f55dc 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean @@ -111,9 +111,11 @@ theorem toLp_val {f : α → E} (h : MemLp f p μ) : (toLp f h).1 = AEEqFun.mk f theorem coeFn_toLp {f : α → E} (hf : MemLp f p μ) : hf.toLp f =ᵐ[μ] f := AEEqFun.coeFn_mk _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem toLp_congr {f g : α → E} (hf : MemLp f p μ) (hg : MemLp g p μ) (hfg : f =ᵐ[μ] g) : hf.toLp f = hg.toLp g := by simp [toLp, hfg] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toLp_eq_toLp_iff {f g : α → E} (hf : MemLp f p μ) (hg : MemLp g p μ) : hf.toLp f = hg.toLp g ↔ f =ᵐ[μ] g := by simp [toLp] diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index 59ed2d5ebb1fb5..cb2e79885026c6 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -235,6 +235,7 @@ theorem support_indicator [Zero β] {s : Set α} (hs : MeasurableSet s) (f : α Function.support (f.piecewise s hs (SimpleFunc.const α 0)) = s ∩ Function.support f := Set.support_indicator +set_option backward.isDefEq.respectTransparency false in open scoped Classical in theorem range_indicator {s : Set α} (hs : MeasurableSet s) (hs_nonempty : s.Nonempty) (hs_ne_univ : s ≠ univ) (x y : β) : diff --git a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean index f0efda5fe33c7b..277237aff7d8ef 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean @@ -475,6 +475,7 @@ theorem toLp_add (f g : α →ₛ E) (hf : MemLp f p μ) (hg : MemLp g p μ) : theorem toLp_neg (f : α →ₛ E) (hf : MemLp f p μ) : toLp (-f) hf.neg = -toLp f hf := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem toLp_sub (f g : α →ₛ E) (hf : MemLp f p μ) (hg : MemLp g p μ) : toLp (f - g) (hf.sub hg) = toLp f hf - toLp g hg := by simp only [sub_eq_add_neg, ← toLp_neg, ← toLp_add] diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 450d437d3ad961..3353628798b2f4 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -442,6 +442,7 @@ theorem div₀ [GroupWithZero β] [ContinuousMul β] [ContinuousInv₀ β] (hf : ⟨fun n => hf.approx n / hg.approx n, fun x => (hf.tendsto_approx x).div (hg.tendsto_approx x) (h₀ x)⟩ +set_option backward.isDefEq.respectTransparency false in @[fun_prop] theorem div [GroupWithZero β] [ContinuousMul β] [ContinuousInv₀ β] [MetrizableSpace β] (hf : StronglyMeasurable f) (hg : StronglyMeasurable g) : diff --git a/Mathlib/MeasureTheory/Group/AEStabilizer.lean b/Mathlib/MeasureTheory/Group/AEStabilizer.lean index 063144fc54b2bf..dc03765772984f 100644 --- a/Mathlib/MeasureTheory/Group/AEStabilizer.lean +++ b/Mathlib/MeasureTheory/Group/AEStabilizer.lean @@ -38,6 +38,7 @@ variable (G : Type*) {α : Type*} [Group G] [MulAction G α] namespace MulAction +set_option backward.isDefEq.respectTransparency false in /-- A.e. stabilizer of a set under a group action. -/ @[to_additive (attr := simps) /-- A.e. stabilizer of a set under an additive group action. -/] def aestabilizer (s : Set α) : Subgroup G where @@ -53,6 +54,7 @@ variable {g : G} {s t : Set α} @[to_additive (attr := simp)] lemma mem_aestabilizer : g ∈ aestabilizer G μ s ↔ g • s =ᵐ[μ] s := .rfl +set_option backward.isDefEq.respectTransparency false in @[to_additive] lemma stabilizer_le_aestabilizer (s : Set α) : stabilizer G s ≤ aestabilizer G μ s := by intro g hg @@ -64,6 +66,7 @@ lemma aestabilizer_empty : aestabilizer G μ ∅ = ⊤ := top_unique fun _ _ ↦ @[to_additive (attr := simp)] lemma aestabilizer_univ : aestabilizer G μ univ = ⊤ := top_unique fun _ _ ↦ by simp +set_option backward.isDefEq.respectTransparency false in @[to_additive] lemma aestabilizer_congr (h : s =ᵐ[μ] t) : aestabilizer G μ s = aestabilizer G μ t := by ext g diff --git a/Mathlib/MeasureTheory/Group/Action.lean b/Mathlib/MeasureTheory/Group/Action.lean index eeb56066690caa..fb4004ac451151 100644 --- a/Mathlib/MeasureTheory/Group/Action.lean +++ b/Mathlib/MeasureTheory/Group/Action.lean @@ -162,6 +162,7 @@ theorem eventuallyConst_smul_set_ae (c : G) {s : Set α} : theorem smul_set_ae_le (c : G) {s t : Set α} : c • s ≤ᵐ[μ] c • t ↔ s ≤ᵐ[μ] t := by simp only [ae_le_set, ← smul_set_sdiff, measure_smul_eq_zero_iff] +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] theorem smul_set_ae_eq (c : G) {s t : Set α} : c • s =ᵐ[μ] c • t ↔ s =ᵐ[μ] t := by simp only [Filter.eventuallyLE_antisymm_iff, smul_set_ae_le] diff --git a/Mathlib/MeasureTheory/Integral/Average.lean b/Mathlib/MeasureTheory/Integral/Average.lean index f3829d379218fa..48ba3ee5ce1034 100644 --- a/Mathlib/MeasureTheory/Integral/Average.lean +++ b/Mathlib/MeasureTheory/Integral/Average.lean @@ -187,6 +187,7 @@ theorem laverage_union_mem_openSegment (hd : AEDisjoint μ s t) (ht : NullMeasur rw [← ENNReal.add_div, ENNReal.div_self (add_eq_zero.not.2 fun h => hs₀ h.1) (add_ne_top.2 ⟨hsμ, htμ⟩)] +set_option backward.isDefEq.respectTransparency.types false in theorem laverage_union_mem_segment (hd : AEDisjoint μ s t) (ht : NullMeasurableSet t μ) (hsμ : μ s ≠ ∞) (htμ : μ t ≠ ∞) : ⨍⁻ x in s ∪ t, f x ∂μ ∈ [⨍⁻ x in s, f x ∂μ -[ℝ≥0∞] ⨍⁻ x in t, f x ∂μ] := by @@ -400,6 +401,7 @@ theorem average_union_mem_openSegment {f : α → E} {s t : Set α} (hd : AEDisj exact mem_openSegment_iff_div.mpr ⟨μ.real s, μ.real t, hs₀, ht₀, (average_union hd ht hsμ htμ hfs hft).symm⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem average_union_mem_segment {f : α → E} {s t : Set α} (hd : AEDisjoint μ s t) (ht : NullMeasurableSet t μ) (hsμ : μ s ≠ ∞) (htμ : μ t ≠ ∞) (hfs : IntegrableOn f s μ) (hft : IntegrableOn f t μ) : diff --git a/Mathlib/MeasureTheory/Integral/Bochner/L1.lean b/Mathlib/MeasureTheory/Integral/Bochner/L1.lean index f11b2590553452..23161ffcc4fd9a 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/L1.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/L1.lean @@ -511,7 +511,7 @@ end SimpleFuncIntegral end SimpleFunc -open SimpleFunc +open L1.SimpleFunc local notation "Integral" => @integralCLM α E _ _ _ _ _ μ _ diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index f0909f581d93b8..6cba01a49d258a 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -286,12 +286,14 @@ theorem curveIntegral_trans (h₁ : CurveIntegrable ω γab) (h₂ : CurveIntegr simp only [curveIntegral_def] norm_num +set_option backward.isDefEq.respectTransparency.types false in theorem curveIntegralFun_segment [NormedSpace ℝ E] (ω : E → E →L[𝕜] F) (a b : E) {t : ℝ} (ht : t ∈ I) : curveIntegralFun ω (.segment a b) t = ω (lineMap a b t) (b - a) := by have := Path.eqOn_extend_segment a b simp only [curveIntegralFun_def, this ht, derivWithin_congr this (this ht), (hasDerivWithinAt_lineMap ..).derivWithin (uniqueDiffOn_Icc_zero_one t ht)] +set_option backward.isDefEq.respectTransparency.types false in theorem curveIntegrable_segment [NormedSpace ℝ E] : CurveIntegrable ω (.segment a b) ↔ IntervalIntegrable (fun t ↦ ω (lineMap a b t) (b - a)) volume 0 1 := by @@ -299,6 +301,7 @@ theorem curveIntegrable_segment [NormedSpace ℝ E] : rw [uIoc_of_le zero_le_one] exact .mono Ioc_subset_Icc_self fun _t ↦ curveIntegralFun_segment ω a b +set_option backward.isDefEq.respectTransparency.types false in theorem curveIntegral_segment [NormedSpace ℝ E] [NormedSpace ℝ F] (ω : E → E →L[𝕜] F) (a b : E) : ∫ᶜ x in .segment a b, ω x = ∫ t in 0..1, ω (lineMap a b t) (b - a) := by rw [curveIntegral_def] @@ -312,6 +315,7 @@ theorem curveIntegral_segment_const [NormedSpace ℝ E] [CompleteSpace F] (ω : let : NormedSpace ℝ F := .restrictScalars ℝ 𝕜 F simp [curveIntegral_segment] +set_option backward.isDefEq.respectTransparency.types false in /-- If `‖ω z‖ ≤ C` at all points of the segment `[a -[ℝ] b]`, then the curve integral `∫ᶜ x in .segment a b, ω x` has norm at most `C * ‖b - a‖`. -/ theorem norm_curveIntegral_segment_le [NormedSpace ℝ E] {C : ℝ} (h : ∀ z ∈ [a -[ℝ] b], ‖ω z‖ ≤ C) : diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean index a87cb3a0d2a5d2..b19875f82c9ed7 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean @@ -292,6 +292,7 @@ namespace Convex variable [NormedSpace ℝ E] [NormedSpace ℝ F] {a b c : E} {s : Set E} {ω : E → E →L[𝕜] F} {dω : E → E →L[ℝ] E →L[𝕜] F} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `ω` is a closed `1`-form on a convex set, then `∫ᶜ x in Path.segment a b, ω x + ∫ᶜ x in Path.segment b c, ω x = ∫ᶜ x in Path.segment a c, ω x` diff --git a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean index f9151af5679b35..e01402b504d1b8 100644 --- a/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean +++ b/Mathlib/MeasureTheory/Integral/DominatedConvergence.lean @@ -295,6 +295,7 @@ open scoped Interval variable {E X : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [TopologicalSpace X] {a b b₀ b₁ b₂ : ℝ} {μ : Measure ℝ} {f : ℝ → E} +set_option backward.isDefEq.respectTransparency.types false in theorem continuousWithinAt_primitive (hb₀ : μ {b₀} = 0) (h_int : IntervalIntegrable f μ (min a b₁) (max a b₂)) : ContinuousWithinAt (fun b => ∫ x in a..b, f x ∂μ) (Icc b₁ b₂) b₀ := by diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean index e7b07212a97022..fcd72cbb1956e2 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean @@ -528,6 +528,7 @@ theorem MonotoneOn.intervalIntegrable {u : ℝ → E} {a b : ℝ} (hu : Monotone rw [intervalIntegrable_iff] exact (hu.integrableOn_isCompact isCompact_uIcc).mono_set Ioc_subset_Icc_self +set_option backward.isDefEq.respectTransparency.types false in theorem AntitoneOn.intervalIntegrable {u : ℝ → E} {a b : ℝ} (hu : AntitoneOn u (uIcc a b)) : IntervalIntegrable u μ a b := hu.dual_right.intervalIntegrable diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean index 19e966083ae3d0..70dc88473d3dd1 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean @@ -113,6 +113,7 @@ section NormedSpace open AffineMap variable {f : E → F} {a b : E} {C r : ℝ} {s : Set E} +set_option backward.isDefEq.respectTransparency.types false in /-- Consider a function `f : E → F` continuous on a segment `[a, b]` and line differentiable in the direction `b - a` at all points of the open segment `(a, b)`. @@ -142,6 +143,7 @@ lemma norm_sub_le_mul_volume_of_norm_lineDeriv_le · exact fun t ht ↦ (hdg t ht).differentiableAt.differentiableWithinAt · exact hf'.mono fun t ht ht_mem ↦ by simpa only [(hdg t ht_mem).deriv] using ht ht_mem +set_option backward.isDefEq.respectTransparency.types false in /-- Let `f : E → F` be a function differentiable on a set `s` and continuous on its closure. Let `a`, `b` be two points such that the open segment connecting `a` to `b` is a subset of `s`. diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean index ba16fc6a18c571..08e968aeb02179 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean @@ -160,6 +160,7 @@ lemma measurePreserving_equivIoc {a : ℝ} : congr! with hx rw [equivIoc_coe_eq hx] +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] Subtype.measureSpace in /-- The lower integral of a function over `AddCircle T` is equal to the lower integral over an interval $(t, t + T]$ in `ℝ` of its lift to `ℝ`. -/ @@ -182,6 +183,7 @@ protected theorem lintegral_preimage (t : ℝ) (f : AddCircle T → ℝ≥0∞) variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] Subtype.measureSpace in /-- The integral of an almost-everywhere strongly measurable function over `AddCircle T` is equal to the integral over an interval $(t, t + T]$ in `ℝ` of its lift to `ℝ`. -/ diff --git a/Mathlib/MeasureTheory/Integral/Layercake.lean b/Mathlib/MeasureTheory/Integral/Layercake.lean index 59e6abe4dd4696..23684e7b6ec4db 100644 --- a/Mathlib/MeasureTheory/Integral/Layercake.lean +++ b/Mathlib/MeasureTheory/Integral/Layercake.lean @@ -97,6 +97,7 @@ section Layercake variable {α : Type*} [MeasurableSpace α] {f : α → ℝ} {g : ℝ → ℝ} +set_option backward.isDefEq.respectTransparency.types false in /-- An auxiliary version of the layer cake formula (Cavalieri's principle, tail probability formula), with a measurability assumption that would also essentially follow from the integrability assumptions, and a sigma-finiteness assumption. diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean index 8244a70061a28d..7d990bdd1626b7 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean @@ -416,6 +416,7 @@ theorem lintegral_zero_measure {m : MeasurableSpace α} (f : α → ℝ≥0∞) ∫⁻ a, f a ∂(0 : Measure α) = 0 := by simp [lintegral] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lintegral_add_measure (f : α → ℝ≥0∞) (μ ν : Measure α) : ∫⁻ a, f a ∂(μ + ν) = ∫⁻ a, f a ∂μ + ∫⁻ a, f a ∂ν := by diff --git a/Mathlib/MeasureTheory/Integral/Pi.lean b/Mathlib/MeasureTheory/Integral/Pi.lean index be5a1cca66f96d..b3c25bf06d8f65 100644 --- a/Mathlib/MeasureTheory/Integral/Pi.lean +++ b/Mathlib/MeasureTheory/Integral/Pi.lean @@ -42,7 +42,7 @@ theorem fin_nat_prod {n : ℕ} {E : Fin n → Type*} rw [← this.integrable_comp_emb (MeasurableEquiv.measurableEmbedding _)] simp_rw [MeasurableEquiv.piFinSuccAbove_symm_apply, Fin.insertNthEquiv, Fin.prod_univ_succ, Fin.insertNth_zero] - simp only [Fin.zero_succAbove, cast_eq, Function.comp_def] + simp only [Fin.zero_succAbove, Function.comp_def] have : Integrable (fun (x : (j : Fin n) → E (Fin.succ j)) ↦ ∏ j, f (Fin.succ j) (x j)) (Measure.pi (fun i ↦ μ i.succ)) := n_ih (fun i ↦ hf _) diff --git a/Mathlib/MeasureTheory/Integral/Prod.lean b/Mathlib/MeasureTheory/Integral/Prod.lean index a0757cf3a92874..78ec1994b9fa11 100644 --- a/Mathlib/MeasureTheory/Integral/Prod.lean +++ b/Mathlib/MeasureTheory/Integral/Prod.lean @@ -61,6 +61,7 @@ section variable [NormedSpace ℝ E] +set_option backward.isDefEq.respectTransparency.types false in /-- The Bochner integral is measurable. This shows that the integrand of (the right-hand-side of) Fubini's theorem is measurable. This version has `f` in curried form. -/ diff --git a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Basic.lean b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Basic.lean index 0ca50c305d8d76..3a73e6791a7700 100644 --- a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Basic.lean @@ -278,8 +278,9 @@ noncomputable def rieszContent (Λ : C_c(X, ℝ≥0) →ₗ[ℝ≥0] ℝ≥0) : sup_le' := rieszContentAux_sup_le Λ lemma rieszContent_ne_top {K : Compacts X} : rieszContent Λ K ≠ ⊤ := by - simp [rieszContent, ne_eq, ENNReal.coe_ne_top, not_false_eq_true] + simp [rieszContent, ne_eq, not_false_eq_true] +set_option backward.isDefEq.respectTransparency false in lemma contentRegular_rieszContent : (rieszContent Λ).ContentRegular := by intro K simp only [rieszContent, le_antisymm_iff, le_iInf_iff, ENNReal.coe_le_coe, Content.mk_apply] @@ -321,6 +322,7 @@ promoted to a measure. It will be later shown that `∫ (x : X), f x ∂(rieszMeasure Λ hΛ) = Λ f` for all `f : C_c(X, ℝ≥0)`. -/ def rieszMeasure := (rieszContent Λ).measure +set_option backward.isDefEq.respectTransparency false in lemma le_rieszMeasure_of_isCompact_tsupport_subset {f : C_c(X, ℝ≥0)} (hf : ∀ x, f x ≤ 1) {K : Set X} (hK : IsCompact K) (h : tsupport f ⊆ K) : .ofNNReal (Λ f) ≤ rieszMeasure Λ K := by rw [← TopologicalSpace.Compacts.coe_mk K hK] diff --git a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean index 1ce3bc6e7b5db6..3d11c7730c808f 100644 --- a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean +++ b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean @@ -63,6 +63,7 @@ and the `NNReal`-version of `rieszContent`. This is under the namespace `RealRMK `rieszMeasure` without namespace is for `NNReal`-linear `Λ`. -/ noncomputable def rieszMeasure := (rieszContent (toNNRealLinear Λ)).measure +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` assumes values between `0` and `1` and the support is contained in `V`, then `Λ f ≤ rieszMeasure V`. -/ lemma le_rieszMeasure_tsupport_subset {f : C_c(X, ℝ)} (hf : ∀ (x : X), 0 ≤ f x ∧ f x ≤ 1) diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index b01e9957e1dd42..1543712183cc96 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -384,7 +384,7 @@ end SetToL1S end SimpleFunc -open SimpleFunc +open L1.SimpleFunc section SetToL1 diff --git a/Mathlib/MeasureTheory/Integral/TorusIntegral.lean b/Mathlib/MeasureTheory/Integral/TorusIntegral.lean index 02860db94b2dec..ee81f65ffd93be 100644 --- a/Mathlib/MeasureTheory/Integral/TorusIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/TorusIntegral.lean @@ -208,6 +208,7 @@ theorem torusIntegral_dim1 (f : ℂ¹ → E) (c : ℂ¹) (R : ℝ¹) : (MeasurableEquiv.measurableEmbedding _), H₁, H₂] simp [circleMap_zero] +set_option backward.isDefEq.respectTransparency.types false in /-- Recurrent formula for `torusIntegral`, see also `torusIntegral_succ`. -/ theorem torusIntegral_succAbove {f : ℂⁿ⁺¹ → E} {c : ℂⁿ⁺¹} {R : ℝⁿ⁺¹} (hf : TorusIntegrable f c R) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean index b6c6a77ec7f4fb..4a14c61761e216 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean @@ -59,7 +59,7 @@ variable {m m₁ m₂ : MeasurableSpace α} {m' : MeasurableSpace β} {f : α /-- The forward image of a measurable space under a function. `map f m` contains the sets `s : Set β` whose preimage under `f` is measurable. -/ -@[implicit_reducible] +@[instance_reducible] protected def map (f : α → β) (m : MeasurableSpace α) : MeasurableSpace β where MeasurableSet' s := MeasurableSet[m] <| f ⁻¹' s measurableSet_empty := m.measurableSet_empty @@ -78,7 +78,7 @@ theorem map_comp {f : α → β} {g : β → γ} : (m.map f).map g = m.map (g /-- The reverse image of a measurable space under a function. `comap f m` contains the sets `s : Set α` such that `s` is the `f`-preimage of a measurable set in `β`. -/ -@[implicit_reducible] +@[instance_reducible] protected def comap (f : α → β) (m : MeasurableSpace β) : MeasurableSpace α where MeasurableSet' s := ∃ s', MeasurableSet[m] s' ∧ f ⁻¹' s' = s measurableSet_empty := ⟨∅, m.measurableSet_empty, rfl⟩ diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index 9b3c601b13e101..f671811e27257d 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -368,7 +368,7 @@ end Atoms section Prod /-- A `MeasurableSpace` structure on the product of two measurable spaces. -/ -@[implicit_reducible] +@[instance_reducible] def MeasurableSpace.prod {α β} (m₁ : MeasurableSpace α) (m₂ : MeasurableSpace β) : MeasurableSpace (α × β) := m₁.comap Prod.fst ⊔ m₂.comap Prod.snd @@ -772,6 +772,7 @@ theorem measurable_tProd_mk (l : List δ) : Measurable (@TProd.mk δ X l) := by | nil => exact measurable_const | cons i l ih => exact (measurable_pi_apply i).prodMk ih +set_option backward.isDefEq.respectTransparency false in theorem measurable_tProd_elim [DecidableEq δ] : ∀ {l : List δ} {i : δ} (hi : i ∈ l), Measurable fun v : TProd X l => v.elim hi | i::is, j, hj => by diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index ab6c6ea9a1084a..acec91af29c3ec 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -289,7 +289,7 @@ namespace MeasurableSpace /-- Copy of a `MeasurableSpace` with a new `MeasurableSet` equal to the old one. Useful to fix definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] protected def copy (m : MeasurableSpace α) (p : Set α → Prop) (h : ∀ s, p s ↔ MeasurableSet[m] s) : MeasurableSpace α where MeasurableSet' := p @@ -326,7 +326,7 @@ inductive GenerateMeasurable (s : Set (Set α)) : Set α → Prop GenerateMeasurable s (⋃ i, f i) /-- Construct the smallest measure space containing a collection of basic sets -/ -@[implicit_reducible] +@[instance_reducible] def generateFrom (s : Set (Set α)) : MeasurableSpace α where MeasurableSet' := GenerateMeasurable s measurableSet_empty := .empty @@ -373,7 +373,7 @@ theorem forall_generateFrom_mem_iff_mem_iff {S : Set (Set α)} {x y : α} : /-- If `g` is a collection of subsets of `α` such that the `σ`-algebra generated from `g` contains the same sets as `g`, then `g` was already a `σ`-algebra. -/ -@[implicit_reducible] +@[instance_reducible] protected def mkOfClosure (g : Set (Set α)) (hg : { t | MeasurableSet[generateFrom g] t } = g) : MeasurableSpace α := (generateFrom g).copy (· ∈ g) <| Set.ext_iff.1 hg.symm diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 15d886f920a57e..a7728a5abe4265 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -501,6 +501,7 @@ lemma piCongrLeft_apply_apply {ι ι' : Type*} (e : ι ≃ ι') {β : ι' → Ty piCongrLeft (fun i' ↦ β i') e x (e i) = x i := by rw [piCongrLeft, coe_mk, Equiv.piCongrLeft_apply_apply] +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism `(γ → α × β) ≃ (γ → α) × (γ → β)` as a measurable equivalence. -/ def arrowProdEquivProdArrow (α β γ : Type*) [MeasurableSpace α] [MeasurableSpace β] : (γ → α × β) ≃ᵐ (γ → α) × (γ → β) where @@ -638,6 +639,7 @@ def ofInvolutive (f : α → α) (hf : Involutive f) (hf' : Measurable f) : α @[simp] theorem ofInvolutive_symm (f : α → α) (hf : Involutive f) (hf' : Measurable f) : (ofInvolutive f hf hf').symm = ofInvolutive f hf hf' := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `setOf` as a `MeasurableEquiv`. -/ @[simps] protected def setOf {α : Type*} : (α → Prop) ≃ᵐ Set α where @@ -747,6 +749,7 @@ noncomputable def schroederBernstein {f : α → β} {g : β → α} (hf : Measu apply hx exact ⟨y, h, rfl⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] lemma equivRange_apply (hf : MeasurableEmbedding f) (x : α) : hf.equivRange x = ⟨f x, mem_range_self x⟩ := by diff --git a/Mathlib/MeasureTheory/MeasurableSpace/EventuallyMeasurable.lean b/Mathlib/MeasureTheory/MeasurableSpace/EventuallyMeasurable.lean index e199fd48bbffd0..8b3c28066e7e00 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/EventuallyMeasurable.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/EventuallyMeasurable.lean @@ -40,7 +40,7 @@ variable {α : Type*} (m : MeasurableSpace α) {s t : Set α} /-- The `MeasurableSpace` of sets which are measurable with respect to a given σ-algebra `m` on `α`, modulo a given σ-filter `l` on `α`. -/ -@[implicit_reducible] +@[instance_reducible] def eventuallyMeasurableSpace (l : Filter α) [CountableInterFilter l] : MeasurableSpace α where MeasurableSet' s := ∃ t, MeasurableSet t ∧ s =ᶠ[l] t measurableSet_empty := ⟨∅, MeasurableSet.empty, EventuallyEq.refl _ _ ⟩ diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Invariants.lean b/Mathlib/MeasureTheory/MeasurableSpace/Invariants.lean index e734734a824530..0dde46333a71a7 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Invariants.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Invariants.lean @@ -29,7 +29,7 @@ variable {α : Type*} A set `s` is `(invariants f)`-measurable iff it is measurable w.r.t. the canonical σ-algebra on `α` and `f ⁻¹' s = s`. -/ -@[implicit_reducible] +@[instance_reducible] def invariants [m : MeasurableSpace α] (f : α → α) : MeasurableSpace α := { m ⊓ ⟨fun s ↦ f ⁻¹' s = s, by simp, by simp, fun f hf ↦ by simp [hf]⟩ with MeasurableSet' := fun s ↦ MeasurableSet[m] s ∧ f ⁻¹' s = s } diff --git a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean index e4d87c9723190f..435fc3bf5b7714 100644 --- a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/Basic.lean @@ -67,6 +67,7 @@ def innerProbChar (t : E) : E →ᵇ ℂ := lemma innerProbChar_apply (t x : E) : innerProbChar t x = exp (⟪x, t⟫ * I) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma innerProbChar_zero : innerProbChar (0 : E) = 1 := by simp [innerProbChar] @@ -79,6 +80,7 @@ def probCharDual (L : StrongDual ℝ F) : F →ᵇ ℂ := lemma probCharDual_apply (L : StrongDual ℝ F) (x : F) : probCharDual L x = exp (L x * I) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma probCharDual_zero : probCharDual (0 : StrongDual ℝ F) = 1 := by simp [probCharDual] diff --git a/Mathlib/MeasureTheory/Measure/Comap.lean b/Mathlib/MeasureTheory/Measure/Comap.lean index be9da9dd21bcf1..6f8c9b0efe3580 100644 --- a/Mathlib/MeasureTheory/Measure/Comap.lean +++ b/Mathlib/MeasureTheory/Measure/Comap.lean @@ -48,6 +48,7 @@ def comapₗ [MeasurableSpace α] [MeasurableSpace β] (f : α → β) : Measure exact hf.2 s hs else 0 +set_option backward.isDefEq.respectTransparency false in theorem comapₗ_apply {_ : MeasurableSpace α} {_ : MeasurableSpace β} (f : α → β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → MeasurableSet (f '' s)) (μ : Measure β) (hs : MeasurableSet s) : comapₗ f μ s = μ (f '' s) := by @@ -107,6 +108,7 @@ theorem measure_image_eq_zero_of_comap_eq_zero (f : α → β) (μ : Measure β) rw [← nonpos_iff_eq_zero] exact (le_comap_apply f μ hfi hf s).trans hs.le +set_option backward.isDefEq.respectTransparency false in theorem ae_eq_image_of_ae_eq_comap (f : α → β) (μ : Measure β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ) {s t : Set α} (hst : s =ᵐ[comap f μ] t) : f '' s =ᵐ[μ] f '' t := by diff --git a/Mathlib/MeasureTheory/Measure/Complex.lean b/Mathlib/MeasureTheory/Measure/Complex.lean index 1e2398ec74cb9a..5d7316aa466f35 100644 --- a/Mathlib/MeasureTheory/Measure/Complex.lean +++ b/Mathlib/MeasureTheory/Measure/Complex.lean @@ -94,6 +94,7 @@ section variable {R : Type*} [Semiring R] [Module R ℝ] variable [ContinuousConstSMul R ℝ] [ContinuousConstSMul R ℂ] +set_option backward.isDefEq.respectTransparency false in /-- The complex measures form a linear isomorphism to the type of pairs of signed measures. -/ @[simps] def equivSignedMeasureₗ : ComplexMeasure α ≃ₗ[R] SignedMeasure α × SignedMeasure α := @@ -108,6 +109,7 @@ def equivSignedMeasureₗ : ComplexMeasure α ≃ₗ[R] SignedMeasure α × Sign end +set_option backward.isDefEq.respectTransparency false in theorem absolutelyContinuous_ennreal_iff (c : ComplexMeasure α) (μ : VectorMeasure α ℝ≥0∞) : c ≪ᵥ μ ↔ ComplexMeasure.re c ≪ᵥ μ ∧ ComplexMeasure.im c ≪ᵥ μ := by constructor <;> intro h diff --git a/Mathlib/MeasureTheory/Measure/Content.lean b/Mathlib/MeasureTheory/Measure/Content.lean index 7e76aa87c9b382..25223b448f0ae7 100644 --- a/Mathlib/MeasureTheory/Measure/Content.lean +++ b/Mathlib/MeasureTheory/Measure/Content.lean @@ -195,7 +195,7 @@ theorem innerContent_comap (f : G ≃ₜ G) (h : ∀ ⦃K : Compacts G⦄, μ (K (U : Opens G) : μ.innerContent (Opens.comap f U) = μ.innerContent U := by refine (Compacts.equiv f).surjective.iSup_congr _ fun K => iSup_congr_Prop image_subset_iff ?_ intro hK - simp only [Equiv.coe_fn_mk, Compacts.equiv] + simp only [Compacts.equiv] apply h @[to_additive] @@ -243,6 +243,7 @@ theorem outerMeasure_le (U : Opens G) (K : Compacts G) (hUK : (U : Set G) ⊆ K) μ.outerMeasure U ≤ μ K := (μ.outerMeasure_opens U).le.trans <| μ.innerContent_le U K hUK +set_option backward.isDefEq.respectTransparency false in theorem le_outerMeasure_compacts (K : Compacts G) : μ K ≤ μ.outerMeasure K := by rw [Content.outerMeasure, inducedOuterMeasure_eq_iInf] · exact le_iInf fun U => le_iInf fun hU => le_iInf <| μ.le_innerContent K ⟨U, hU⟩ diff --git a/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean b/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean index f89c769332a53e..7433d4c2dd68f6 100644 --- a/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean +++ b/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean @@ -98,6 +98,7 @@ theorem tendsto_measure_symmDiff_preimage_nhds_zero ← hg.measure_preimage hs, ← measure_sdiff_le_iff_le_add hKm hKg.subset_preimage hK'] exact hKμ.le +set_option backward.isDefEq.respectTransparency false in /-- Let `f : Z → C(X, Y)` be a continuous (in the compact open topology) family of continuous measure-preserving maps. Let `t : Set Y` be a null measurable set of finite measure. diff --git a/Mathlib/MeasureTheory/Measure/DiracProba.lean b/Mathlib/MeasureTheory/Measure/DiracProba.lean index ff2bc3cf3fd822..05edb5e0a45be0 100644 --- a/Mathlib/MeasureTheory/Measure/DiracProba.lean +++ b/Mathlib/MeasureTheory/Measure/DiracProba.lean @@ -134,6 +134,7 @@ noncomputable def diracProbaEquiv [T0Space X] : X ≃ range (diracProba (X := X) left_inv x := by apply diracProbaInverse_eq; rfl right_inv μ := Subtype.ext (by simp only [diracProba_diracProbaInverse]) +set_option backward.isDefEq.respectTransparency.types false in /-- The composition of `diracProbaEquiv.symm` and `diracProba` is the subtype inclusion. -/ lemma diracProba_comp_diracProbaEquiv_symm_eq_val [T0Space X] : diracProba ∘ (diracProbaEquiv (X := X)).symm = fun μ ↦ μ.val := by diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean index 76562fe0173c36..5540b54c0eb58a 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean @@ -744,6 +744,7 @@ theorem tendsto_iff_forall_integral_tendsto {γ : Type*} {F : Filter γ} {μs : simp_rw [aux, BoundedContinuousFunction.toReal_lintegral_coe_eq_integral] at tends_pos tends_neg exact Tendsto.sub tends_pos tends_neg +set_option backward.isDefEq.respectTransparency.types false in theorem tendsto_iff_forall_integral_rclike_tendsto {γ : Type*} (𝕜 : Type*) [RCLike 𝕜] {F : Filter γ} {μs : γ → FiniteMeasure Ω} {μ : FiniteMeasure Ω} : Tendsto μs F (𝓝 μ) ↔ diff --git a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean index f58e0dcb245c69..070a704d452ef9 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean @@ -172,6 +172,7 @@ theorem le_index_mul (K₀ : PositiveCompacts G) (K : Compacts G) {V : Set G} rcases this with ⟨_, ⟨g₃, rfl⟩, A, ⟨hg₃, rfl⟩, h2V⟩; rw [mem_preimage, ← mul_assoc] at h2V exact mem_biUnion (Finset.mul_mem_mul hg₃ hg₁) h2V +set_option backward.isDefEq.respectTransparency false in @[to_additive addIndex_pos] theorem index_pos (K : PositiveCompacts G) {V : Set G} (hV : (interior V).Nonempty) : 0 < index (K : Set G) V := by @@ -457,6 +458,7 @@ theorem is_left_invariant_chaar {K₀ : PositiveCompacts G} (g : G) (K : Compact apply is_left_invariant_prehaar; rw [h2U.interior_eq]; exact ⟨1, h3U⟩ · apply continuous_iff_isClosed.mp this; exact isClosed_singleton +set_option backward.isDefEq.respectTransparency false in /-- The function `chaar` interpreted in `ℝ≥0`, as a content -/ @[to_additive /-- additive version of `MeasureTheory.Measure.haar.haarContent` -/] noncomputable def haarContent (K₀ : PositiveCompacts G) : Content G where @@ -475,11 +477,13 @@ theorem haarContent_apply (K₀ : PositiveCompacts G) (K : Compacts G) : haarContent K₀ K = show NNReal from ⟨chaar K₀ K, chaar_nonneg _ _⟩ := rfl +set_option backward.isDefEq.respectTransparency false in /-- The variant of `chaar_self` for `haarContent` -/ @[to_additive /-- The variant of `addCHaar_self` for `addHaarContent`. -/] theorem haarContent_self {K₀ : PositiveCompacts G} : haarContent K₀ K₀.toCompacts = 1 := by simp_rw [← ENNReal.coe_one, haarContent_apply, ENNReal.coe_inj, chaar_self]; rfl +set_option backward.isDefEq.respectTransparency false in /-- The variant of `is_left_invariant_chaar` for `haarContent` -/ @[to_additive /-- The variant of `is_left_invariant_addCHaar` for `addHaarContent` -/] theorem is_left_invariant_haarContent {K₀ : PositiveCompacts G} (g : G) (K : Compacts G) : diff --git a/Mathlib/MeasureTheory/Measure/Haar/Extension.lean b/Mathlib/MeasureTheory/Measure/Haar/Extension.lean index 263f6c3b681fd6..c70206c3b5b12e 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Extension.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Extension.lean @@ -230,6 +230,7 @@ instance isHaarMeasure_inducedMeasure : IsHaarMeasure (inducedMeasure H μA μC) exact (pullback H ⟨f, hf2⟩ _).continuous.integral_pos_of_hasCompactSupport_nonneg_nonzero (pullback H ⟨f, hf2⟩ _).hasCompactSupport (fun x ↦ (hf4 _).1) ha +set_option backward.isDefEq.respectTransparency.types false in /-- If `φ : A →* B` and `ψ : B →* C` define a short exact sequence of topological groups, and if `ψ` is injective on an open set `U`, then the induced measure on `U` is bounded above by `μC Set.univ * μA {1}` (possibly infinite). -/ diff --git a/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean b/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean index 7d99663857af69..7c394e6dd3b6fb 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean @@ -54,6 +54,7 @@ theorem mem_parallelepiped_iff (v : ι → E) (x : E) : x ∈ parallelepiped v ↔ ∃ t ∈ Icc (0 : ι → ℝ) 1, x = ∑ i, t i • v i := by simp [parallelepiped, eq_comm] +set_option backward.isDefEq.respectTransparency false in theorem parallelepiped_basis_eq (b : Basis ι ℝ E) : parallelepiped b = {x | ∀ i, b.repr x i ∈ Set.Icc 0 1} := by classical diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean index ade03081e94b2a..741040d515ebac 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean @@ -204,6 +204,7 @@ lemma eq_prod_of_integral_prod_mul_prod_boundedContinuousFunction {μ : Measure ξ = μ.prod ν := ext_of_integral_prod_mul_prod_boundedContinuousFunction fun f g ↦ by rw [h, ← integral_prod_mul] +set_option backward.isDefEq.respectTransparency.types false in set_option linter.flexible false in -- simp followed by fun_prop lemma ext_of_integral_prod_mul_boundedContinuousFunction {μ ν : Measure ((Π i, X i) × T)} [IsFiniteMeasure μ] [IsFiniteMeasure ν] diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index bb9ef9fe2cb2d7..914dd8efc0b228 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -1076,6 +1076,7 @@ section RealAffine variable [NormedAddCommGroup E] [NormedSpace ℝ E] [MeasurableSpace P] variable [MetricSpace P] [NormedAddTorsor E P] [BorelSpace P] +set_option backward.isDefEq.respectTransparency.types false in /-- Mapping a set of reals along a line segment scales the measure by the length of a segment. This is an auxiliary result used to prove `hausdorffMeasure_affineSegment`. -/ @@ -1087,6 +1088,7 @@ theorem hausdorffMeasure_lineMap_image (x y : P) (s : Set ℝ) : rw [IsometryEquiv.hausdorffMeasure_image, hausdorffMeasure_smul_right_image, nndist_eq_nnnorm_vsub' E] +set_option backward.isDefEq.respectTransparency.types false in /-- The measure of a segment is the distance between its endpoints. -/ @[simp] theorem hausdorffMeasure_affineSegment (x y : P) : μH[1] (affineSegment ℝ x y) = edist x y := by diff --git a/Mathlib/MeasureTheory/Measure/LevyConvergence.lean b/Mathlib/MeasureTheory/Measure/LevyConvergence.lean index debad61a4c309c..0f0d4a48de7217 100644 --- a/Mathlib/MeasureTheory/Measure/LevyConvergence.lean +++ b/Mathlib/MeasureTheory/Measure/LevyConvergence.lean @@ -174,6 +174,7 @@ lemma ProbabilityMeasure.tendsto_of_tight_of_separatesPoints (𝕜 : Type*) [RCL variable {ι : Type*} {𝓕 : Filter ι} {μ₀ : ProbabilityMeasure E} +set_option backward.isDefEq.respectTransparency.types false in omit [FiniteDimensional ℝ E] in lemma ProbabilityMeasure.tendsto_charPoly_of_tendsto_charFun {μ : ι → ProbabilityMeasure E} (h : ∀ t : E, Tendsto (fun n ↦ charFun (μ n) t) 𝓕 (𝓝 (charFun μ₀ t))) diff --git a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean index d3a7b39bf86c01..7eef5b97a235c9 100644 --- a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean +++ b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean @@ -509,7 +509,7 @@ section Levy_Prokhorov_metrizes_convergence_in_distribution /-! ### On separable spaces the Lévy-Prokhorov distance metrizes convergence in distribution -/ -open BoundedContinuousFunction TopologicalSpace +open TopologicalSpace variable {Ω : Type*} [PseudoMetricSpace Ω] variable [MeasurableSpace Ω] [OpensMeasurableSpace Ω] diff --git a/Mathlib/MeasureTheory/Measure/Map.lean b/Mathlib/MeasureTheory/Measure/Map.lean index 33fbe530cb5c90..8c9c5d861fa242 100644 --- a/Mathlib/MeasureTheory/Measure/Map.lean +++ b/Mathlib/MeasureTheory/Measure/Map.lean @@ -77,6 +77,7 @@ def mapₗ [MeasurableSpace α] [MeasurableSpace β] (f : α → β) : Measure le_toOuterMeasure_caratheodory μ _ (hf hs) (f ⁻¹' t) else 0 +set_option backward.isDefEq.respectTransparency false in theorem mapₗ_congr {f g : α → β} (hf : Measurable f) (hg : Measurable g) (h : f =ᵐ[μ] g) : mapₗ f μ = mapₗ g μ := by ext1 s hs diff --git a/Mathlib/MeasureTheory/Measure/OpenPos.lean b/Mathlib/MeasureTheory/Measure/OpenPos.lean index 46c9fb552b916b..cf337d162b0566 100644 --- a/Mathlib/MeasureTheory/Measure/OpenPos.lean +++ b/Mathlib/MeasureTheory/Measure/OpenPos.lean @@ -86,6 +86,7 @@ theorem _root_.IsOpen.ae_eq_empty_iff_eq (hU : IsOpen U) : theorem _root_.IsOpen.eq_empty_of_measure_zero (hU : IsOpen U) (h₀ : μ U = 0) : U = ∅ := (hU.measure_eq_zero_iff μ).mp h₀ +set_option backward.isDefEq.respectTransparency false in theorem _root_.IsClosed.ae_eq_univ_iff_eq (hF : IsClosed F) : F =ᵐ[μ] univ ↔ F = univ := by refine ⟨fun h ↦ ?_, fun h ↦ by rw [h]⟩ diff --git a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean index 6546d9f12b53b9..e6393e4c823ec9 100644 --- a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean @@ -230,6 +230,7 @@ theorem eq_of_forall_apply_eq (μ ν : ProbabilityMeasure Ω) theorem mass_toFiniteMeasure (μ : ProbabilityMeasure Ω) : μ.toFiniteMeasure.mass = 1 := μ.coeFn_univ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma range_toFiniteMeasure : range toFiniteMeasure = {μ : FiniteMeasure Ω | μ.mass = 1} := by ext μ @@ -456,6 +457,7 @@ def normalize : ProbabilityMeasure Ω := rw [← Ne, ← ENNReal.coe_ne_zero, ennreal_mass] at zero exact ENNReal.inv_mul_cancel zero μ.prop.measure_univ_lt_top.ne } +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem self_eq_mass_mul_normalize (s : Set Ω) : μ s = μ.mass * μ.normalize s := by obtain rfl | h := eq_or_ne μ 0 diff --git a/Mathlib/MeasureTheory/Measure/Prokhorov.lean b/Mathlib/MeasureTheory/Measure/Prokhorov.lean index f7b79b06bdbf1e..41ce40cac6a1d7 100644 --- a/Mathlib/MeasureTheory/Measure/Prokhorov.lean +++ b/Mathlib/MeasureTheory/Measure/Prokhorov.lean @@ -64,6 +64,7 @@ open FiniteMeasure variable {E : Type*} [MeasurableSpace E] [TopologicalSpace E] [T2Space E] [BorelSpace E] +set_option backward.isDefEq.respectTransparency.types false in variable (E) in /-- In a compact space, the set of finite measures with mass at most `C` is compact. -/ theorem isCompact_setOf_finiteMeasure_le_of_compactSpace [CompactSpace E] (C : ℝ≥0) : diff --git a/Mathlib/MeasureTheory/Measure/ResolventTransform.lean b/Mathlib/MeasureTheory/Measure/ResolventTransform.lean index 6cf81e33017e89..6fd7d22cf63abf 100644 --- a/Mathlib/MeasureTheory/Measure/ResolventTransform.lean +++ b/Mathlib/MeasureTheory/Measure/ResolventTransform.lean @@ -55,6 +55,7 @@ section resolvent variable [NontriviallyNormedField 𝕜] [MeasurableSpace 𝕜] +set_option backward.isDefEq.respectTransparency.types false in @[fun_prop] theorem measurable_resolvent {a : A} [OpensMeasurableSpace 𝕜] [NormedRing A] [NormedAlgebra 𝕜 A] [CompleteSpace A] [MeasurableSpace A] [BorelSpace A] : diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index 64f7cae76c64bb..6c4f1281f97047 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -53,6 +53,7 @@ theorem restrictₗ_apply {_m0 : MeasurableSpace α} (s : Set α) (μ : Measure restrictₗ s μ = μ.restrict s := rfl +set_option backward.isDefEq.respectTransparency false in /-- This lemma shows that `restrict` and `toOuterMeasure` commute. Note that the LHS has a restrict on measures and the RHS has a restrict on outer measures. -/ theorem restrict_toOuterMeasure_eq_toOuterMeasure_restrict (h : MeasurableSet s) : diff --git a/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean b/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean index 0b8a1675ab1f86..fb16c31c7c1175 100644 --- a/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean @@ -109,6 +109,7 @@ theorem measureDense_measurableSet : μ.MeasureDense {s | MeasurableSet s} where measurable _ h := h approx s hs _ ε ε_pos := ⟨s, hs, by simpa⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem Measure.MeasureDense.completion (h𝒜 : μ.MeasureDense 𝒜) : μ.completion.MeasureDense 𝒜 where measurable s hs := (h𝒜.measurable s hs).nullMeasurableSet approx s hs hμs ε ε_pos := by @@ -262,6 +263,7 @@ theorem Measure.MeasureDense.of_generateFrom_isSetAlgebra_finite [IsFiniteMeasur rcases this.2 ε ε_pos with ⟨t, t_mem, hμst⟩ exact ⟨t, t_mem, (lt_ofReal_iff_toReal_lt (measure_ne_top _ _)).2 hμst⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- If a measure space `X` is generated by an algebra of sets which contains a monotone countable family of sets with finite measure spanning `X` (thus the measure is `σ`-finite), then this algebra of sets is measure-dense. -/ diff --git a/Mathlib/MeasureTheory/Measure/Sub.lean b/Mathlib/MeasureTheory/Measure/Sub.lean index 4a40e904818f3d..230414ee42b84e 100644 --- a/Mathlib/MeasureTheory/Measure/Sub.lean +++ b/Mathlib/MeasureTheory/Measure/Sub.lean @@ -60,6 +60,7 @@ protected theorem zero_sub : 0 - μ = 0 := protected theorem sub_self : μ - μ = 0 := sub_eq_zero_of_le le_rfl +set_option backward.isDefEq.respectTransparency false in @[simp] protected theorem sub_zero : μ - 0 = μ := by rw [sub_def] diff --git a/Mathlib/MeasureTheory/OuterMeasure/AE.lean b/Mathlib/MeasureTheory/OuterMeasure/AE.lean index 2f87f493baf968..009620a9fd0340 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/AE.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/AE.lean @@ -158,10 +158,12 @@ theorem ae_le_set_union {s' t' : Set α} (h : s ≤ᵐ[μ] t) (h' : s' ≤ᵐ[μ (s ∪ s' : Set α) ≤ᵐ[μ] (t ∪ t' : Set α) := h.union h' +set_option backward.isDefEq.respectTransparency false in theorem union_ae_eq_right : (s ∪ t : Set α) =ᵐ[μ] t ↔ μ (s \ t) = 0 := by simp [eventuallyLE_antisymm_iff, ae_le_set, union_sdiff_right, sdiff_eq_empty.2 Set.subset_union_right] +set_option backward.isDefEq.respectTransparency false in theorem sdiff_ae_eq_self : (s \ t : Set α) =ᵐ[μ] s ↔ μ (s ∩ t) = 0 := by simp [eventuallyLE_antisymm_iff, ae_le_set] @@ -172,6 +174,7 @@ theorem sdiff_null_ae_eq_self (ht : μ t = 0) : (s \ t : Set α) =ᵐ[μ] s := @[deprecated (since := "2026-06-03")] alias diff_null_ae_eq_self := sdiff_null_ae_eq_self +set_option backward.isDefEq.respectTransparency false in theorem ae_eq_set {s t : Set α} : s =ᵐ[μ] t ↔ μ (s \ t) = 0 ∧ μ (t \ s) = 0 := by simp [eventuallyLE_antisymm_iff, ae_le_set] @@ -185,6 +188,7 @@ set_option backward.isDefEq.respectTransparency false in theorem ae_eq_set_compl_compl {s t : Set α} : sᶜ =ᵐ[μ] tᶜ ↔ s =ᵐ[μ] t := by simp only [← measure_symmDiff_eq_zero_iff, compl_symmDiff_compl] +set_option backward.isDefEq.respectTransparency false in theorem ae_eq_set_compl {s t : Set α} : sᶜ =ᵐ[μ] t ↔ s =ᵐ[μ] tᶜ := by rw [← ae_eq_set_compl_compl, compl_compl] @@ -207,6 +211,7 @@ theorem ae_eq_set_symmDiff {s' t' : Set α} (h : s =ᵐ[μ] t) (h' : s' =ᵐ[μ] s ∆ s' =ᵐ[μ] t ∆ t' := h.symmDiff h' +set_option backward.isDefEq.respectTransparency false in theorem union_ae_eq_univ_of_ae_eq_univ_left (h : s =ᵐ[μ] univ) : (s ∪ t : Set α) =ᵐ[μ] univ := (ae_eq_set_union h (ae_eq_refl t)).trans <| by rw [univ_union] @@ -250,6 +255,7 @@ theorem ae_eq_set_biUnion {s : Set β} (hs : s.Countable) {t t' : β → Set α} (⋃ b ∈ s, t b : Set α) =ᵐ[μ] (⋃ b ∈ s, t' b : Set α) := .countable_bUnion hs h +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem _root_.Set.mulIndicator_ae_eq_one {M : Type*} [One M] {f : α → M} {s : Set α} : s.mulIndicator f =ᵐ[μ] 1 ↔ μ (s ∩ f.mulSupport) = 0 := by diff --git a/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean b/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean index ce80845f943687..e982e256a5225f 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean @@ -172,7 +172,7 @@ def caratheodoryDynkin : MeasurableSpace.DynkinSystem α where /-- Given an outer measure `μ`, the Carathéodory-measurable space is defined such that `s` is measurable if `∀ t, μ t = μ (t ∩ s) + μ (t \ s)`. -/ -@[implicit_reducible] +@[instance_reducible] protected def caratheodory : MeasurableSpace α := by apply MeasurableSpace.DynkinSystem.toMeasurableSpace (caratheodoryDynkin m) intro s₁ s₂ diff --git a/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean b/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean index 352bb89446eaae..fda8f0b9614032 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/OfAddContent.lean @@ -166,6 +166,7 @@ noncomputable def measure [mα : MeasurableSpace α] (m : AddContent ℝ≥0∞ (m.measureCaratheodory hC m_sigma_subadd).trim <| fun s a ↦ isCaratheodory_inducedOuterMeasure hC m s (hC_gen s a) +set_option backward.isDefEq.respectTransparency false in /-- The measure defined through a sigma-subadditive content on a semiring coincides with the content on the semiring. -/ theorem measure_eq [mα : MeasurableSpace α] (m : AddContent ℝ≥0∞ C) (hC : IsSetSemiring C) diff --git a/Mathlib/MeasureTheory/PiSystem.lean b/Mathlib/MeasureTheory/PiSystem.lean index 180796a19f7fba..914a6bab4d09ca 100644 --- a/Mathlib/MeasureTheory/PiSystem.lean +++ b/Mathlib/MeasureTheory/PiSystem.lean @@ -307,6 +307,7 @@ theorem mem_generatePiSystem_iUnion_elim {α β} {g : β → Set (Set α)} (h_pi · rw [Finset.mem_union] at h_b apply False.elim (h_b.elim hbs hbt) +set_option backward.isDefEq.respectTransparency false in /-- Every element of the π-system generated by an indexed union of a family of π-systems is a finite intersection of elements from the π-systems. For a total union version, see `mem_generatePiSystem_iUnion_elim`. -/ @@ -609,7 +610,7 @@ instance : Inhabited (DynkinSystem α) := ⟨generate univ⟩ /-- If a Dynkin system is closed under binary intersection, then it forms a `σ`-algebra. -/ -@[implicit_reducible] +@[instance_reducible] def toMeasurableSpace (h_inter : ∀ s₁ s₂, d.Has s₁ → d.Has s₂ → d.Has (s₁ ∩ s₂)) : MeasurableSpace α where MeasurableSet' := d.Has diff --git a/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean b/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean index 3fbf1b815c89e3..6cf384cb2e3b6f 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean @@ -85,6 +85,7 @@ def of_additive_of_le_measure open scoped ENNReal +set_option backward.isDefEq.respectTransparency.types false in /-- Consider an additive content on a dense ring of sets. Assume that it is dominated by a finite positive measure. Then it extends to a countably additive vector measure. -/ lemma exists_extension_of_isSetRing_of_le_measure_of_dense [IsFiniteMeasure μ] diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index 462e1339e6b361..fbd4d3298f9852 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -259,7 +259,7 @@ variable {R : Type*} [Semiring R] [DistribMulAction R M] [ContinuousConstSMul R /-- Given a scalar `r` and a vector measure `v`, `smul r v` is the vector measure corresponding to the set function `s : Set α => r • (v s)`. -/ -@[implicit_reducible] +@[instance_reducible] def smul (r : R) (v : VectorMeasure α M) : VectorMeasure α M where measureOf' := r • ⇑v empty' := by rw [Pi.smul_apply, empty, smul_zero] @@ -669,6 +669,7 @@ variable {R : Type*} [Semiring R] [Module R M] [Module R N] variable [ContinuousConstSMul R M] [ContinuousConstSMul R N] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem mapRange_smul {v : VectorMeasure α M} {f : M →ₗ[R] N} (hf : Continuous f) {c : R} : (c • v).mapRange f.toAddMonoidHom hf = c • (v.mapRange f.toAddMonoidHom hf) := by @@ -676,6 +677,7 @@ theorem mapRange_smul {v : VectorMeasure α M} {f : M →ₗ[R] N} (hf : Continu variable [ContinuousAdd M] [ContinuousAdd N] +set_option backward.isDefEq.respectTransparency false in /-- Given a continuous linear map `f : M → N`, `mapRangeₗ` is the linear map mapping the vector measure `v` on `M` to the vector measure `f ∘ v` on `N`. -/ def mapRangeₗ {α : Type*} [MeasurableSpace α] (f : M →ₗ[R] N) (hf : Continuous f) : diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index 421eca9f6d02ef..b52330580af1fb 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -139,9 +139,11 @@ namespace VectorMeasure variable (μ ν : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) {C : E →L[ℝ] F →L[ℝ] G} {f g : X → E} {φ : X → Y} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma transpose_zero : (0 : VectorMeasure X F).transpose B = 0 := by simp [transpose] +set_option backward.isDefEq.respectTransparency.types false in lemma transpose_restrict (s : Set X) : (μ.restrict s).transpose B = (μ.transpose B).restrict s := by by_cases hs : MeasurableSet s @@ -149,12 +151,14 @@ lemma transpose_restrict (s : Set X) : simp [VectorMeasure.restrict_apply, hs, ht, transpose] · simp [restrict_not_measurable _ hs] +set_option backward.isDefEq.respectTransparency.types false in lemma transpose_map : (μ.map φ).transpose B = (μ.transpose B).map φ := by by_cases hφ : Measurable φ; swap · simp [map, hφ] ext s hs simp [transpose, map_apply, hs, hφ] +set_option backward.isDefEq.respectTransparency.types false in lemma transpose_add : (μ + ν).transpose B = μ.transpose B + ν.transpose B := by simp [transpose] @@ -163,11 +167,13 @@ lemma transpose_smul (c : ℝ) : (c • μ).transpose B = c • μ.transpose B := by simp [transpose, mapRange_smul] +set_option backward.isDefEq.respectTransparency.types false in lemma transpose_dirac (x : X) (v : F) : (dirac x v).transpose B = dirac x (B.flip v) := by ext s hs : 1 by_cases hx : x ∈ s <;> simp [transpose, hx, hs] +set_option backward.isDefEq.respectTransparency.types false in lemma variation_transpose_le : (μ.transpose B).variation ≤ ‖B‖₊ • μ.variation := by apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) @@ -185,6 +191,7 @@ instance [IsFiniteMeasure μ.variation] : IsFiniteMeasure (μ.transpose B).variation := isFiniteMeasure_of_le _ (variation_transpose_le μ B) +set_option backward.isDefEq.respectTransparency.types false in lemma variation_transpose_eq_smul [Nontrivial E] {C : ℝ≥0} (hB : ∀ x y, ‖B x y‖₊ = C * ‖x‖₊ * ‖y‖₊) : (μ.transpose B).variation = C • μ.variation := by @@ -302,11 +309,13 @@ theorem transpose_zero_cbm (μ : VectorMeasure X F) : ext simp [transpose] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transpose_add_vectorMeasure (μ ν : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : (μ + ν).transpose B = μ.transpose B + ν.transpose B := by simp [transpose] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transpose_add_cbm (μ : VectorMeasure X F) (B C : E →L[ℝ] F →L[ℝ] G) : μ.transpose (B + C) = μ.transpose B + μ.transpose C := by @@ -330,24 +339,28 @@ theorem transpose_finsetSum_cbm (μ : VectorMeasure X F) (B : ι → E →L[ℝ] | empty => simp | insert i s his ih => simp [Finset.sum_insert, his, ih] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transpose_neg_vectorMeasure (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : (-μ).transpose B = - (μ.transpose B) := by ext simp [transpose] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transpose_neg_cbm (μ : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : μ.transpose (-B) = - (μ.transpose B) := by ext simp [transpose] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transpose_sub_vectorMeasure (μ ν : VectorMeasure X F) (B : E →L[ℝ] F →L[ℝ] G) : (μ - ν).transpose B = μ.transpose B - ν.transpose B := by ext simp [transpose] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem transpose_sub_cbm (μ : VectorMeasure X F) (B C : E →L[ℝ] F →L[ℝ] G) : μ.transpose (B - C) = μ.transpose B - μ.transpose C := by @@ -356,6 +369,7 @@ theorem transpose_sub_cbm (μ : VectorMeasure X F) (B C : E →L[ℝ] F →L[ℝ section Function +set_option backward.isDefEq.respectTransparency.types false in theorem integral_undef (h : ¬ μ.Integrable f) : ∫ᵛ x, f x ∂[B; μ] = 0 := by simp [integral, setToFun_undef _ h] @@ -529,6 +543,7 @@ theorem integral_smul_nnreal_vectorMeasure (f : X → E) (c : ℝ≥0) : ∫ᵛ x, f x ∂[B; c • μ] = c • ∫ᵛ x, f x ∂[B; μ] := integral_smul_vectorMeasure f (c : ℝ) +set_option backward.isDefEq.respectTransparency.types false in theorem integral_add_vectorMeasure (hμ : μ.Integrable f) (hν : ν.Integrable f) : ∫ᵛ x, f x ∂[B; μ + ν] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, f x ∂[B; ν] := setToFun_add_left'' (by simp [transpose]) hμ hν (by grw [variation_add_le]) @@ -545,6 +560,7 @@ theorem integral_finsetSum_vectorMeasure {μ : ι → VectorMeasure X F} Finset.sum_insert] at hf ⊢ rw [integral_add_vectorMeasure hf.1 (Integrable.finsetSum_vectorMeasure hf.2), ih hf.2] +set_option backward.isDefEq.respectTransparency.types false in @[integral_simps] theorem integral_neg_vectorMeasure : ∫ᵛ x, f x ∂[B; -μ] = -∫ᵛ x, f x ∂[B; μ] := by @@ -565,6 +581,7 @@ theorem integral_zero_cbm : ∫ᵛ x, f x ∂[(0 : E →L[ℝ] F →L[ℝ] G); μ] = 0 := by simp [integral, FunLike.coe_zero] +set_option backward.isDefEq.respectTransparency.types false in theorem integral_add_cbm (hB : μ.Integrable f) : ∫ᵛ x, f x ∂[B + C; μ] = ∫ᵛ x, f x ∂[B; μ] + ∫ᵛ x, f x ∂[C; μ] := by refine setToFun_add_left'' (by simp [transpose]) hB hB ?_ @@ -583,6 +600,7 @@ theorem integral_finsetSum_cbm {B : ι → E →L[ℝ] F →L[ℝ] G} simp only [ha, not_false_eq_true, Finset.sum_insert] rw [integral_add_cbm hf, ih] +set_option backward.isDefEq.respectTransparency.types false in @[integral_simps] theorem integral_neg_cbm : ∫ᵛ x, f x ∂[-B; μ] = -∫ᵛ x, f x ∂[B; μ] := by @@ -817,6 +835,7 @@ theorem Integrable.map {β : Type*} [MeasurableSpace β] {φ : X → β} apply ((integrable_map_measure hfm hφ.aemeasurable).2 h).mono_measure apply variation_map_le +set_option backward.isDefEq.respectTransparency.types false in theorem integral_map {β : Type*} [MeasurableSpace β] {φ : X → β} (hφ : Measurable φ) {f : β → E} (hfm : AEStronglyMeasurable f (μ.variation.map φ)) diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean index e4f0a7166d533b..4cdd2a9202ea0e 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Semivariation.lean @@ -66,6 +66,7 @@ lemma semivariation_mono (hst : s ⊆ t) : μ.semivariation s ≤ μ.semivariati apply (measure_mono hst).trans apply le_biSup _ hℓ +set_option backward.isDefEq.respectTransparency.types false in lemma semivariation_le_variation : μ.semivariation s ≤ μ.variation s := by simp only [semivariation, iSup_le_iff] intro ℓ hℓ @@ -75,6 +76,7 @@ lemma semivariation_le_variation : μ.semivariation s ≤ μ.variation s := by apply le_trans ?_ (enorm_measure_le_variation _ _) exact (ContinuousLinearMap.le_opENorm _ _).trans (mul_le_of_le_one_left (by positivity) hℓ) +set_option backward.isDefEq.respectTransparency.types false in lemma enorm_apply_le_semivariation : ‖μ s‖ₑ ≤ μ.semivariation s := by by_cases hs : MeasurableSet s; swap · simp [not_measurable, hs] diff --git a/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean b/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean index 4b87371e6e8109..a04ddceba4e4e0 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/WithDensityVec.lean @@ -93,6 +93,7 @@ lemma variation_WithDensity_le : apply enorm_setIntegral_le_lintegral_enorm_transpose · simp [withDensity, hf, Measure.zero_le ] +set_option backward.isDefEq.respectTransparency.types false in /-- If `‖B x y‖ = ‖B · y‖ * ‖x‖` for all `x, y`, then the variation of a vector measure with density `f` wrt `μ` is the measure with density `‖f‖ₑ` with respect to the variation of `μ`. diff --git a/Mathlib/ModelTheory/Algebra/Field/Basic.lean b/Mathlib/ModelTheory/Algebra/Field/Basic.lean index 328f6c840fac7f..1f48383a3d8b38 100644 --- a/Mathlib/ModelTheory/Algebra/Field/Basic.lean +++ b/Mathlib/ModelTheory/Algebra/Field/Basic.lean @@ -34,7 +34,7 @@ namespace FirstOrder namespace Field -open Language Ring Structure BoundedFormula +open Language FirstOrder.Ring Structure BoundedFormula /-- An indexing type to name each of the field axioms. The theory of fields is defined as the range of a function `FieldAxiom -> diff --git a/Mathlib/ModelTheory/Algebra/Field/CharP.lean b/Mathlib/ModelTheory/Algebra/Field/CharP.lean index 69d6040d887561..63d0379a5263d5 100644 --- a/Mathlib/ModelTheory/Algebra/Field/CharP.lean +++ b/Mathlib/ModelTheory/Algebra/Field/CharP.lean @@ -29,7 +29,7 @@ namespace FirstOrder namespace Field -open Language Ring +open Language FirstOrder.Ring /-- For a given natural number `n`, `eqZero n` is the sentence in the language of rings saying that `n` is zero. -/ diff --git a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean index 7e2c2bc1ec3093..338de145fc0c25 100644 --- a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean +++ b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean @@ -52,7 +52,7 @@ namespace FirstOrder namespace Field -open Ring FreeCommRing Polynomial Language +open FirstOrder.Ring FreeCommRing Polynomial Language /-- A generic monic polynomial of degree `n` as an element of the free commutative ring in `n + 1` variables, with a variable for each @@ -61,6 +61,7 @@ for `X`. -/ noncomputable def genericMonicPoly (n : ℕ) : FreeCommRing (Fin (n + 1)) := of (Fin.last _) ^ n + ∑ i : Fin n, of i.castSucc * of (Fin.last _) ^ (i : ℕ) +set_option backward.isDefEq.respectTransparency.types false in theorem lift_genericMonicPoly [CommRing K] [Nontrivial K] {n : ℕ} (v : Fin (n + 1) → K) : FreeCommRing.lift v (genericMonicPoly n) = (((monicEquivDegreeLT n).trans (degreeLTEquiv K n).toEquiv).symm (v ∘ Fin.castSucc)).1.eval @@ -175,6 +176,7 @@ theorem ACF_isComplete {p : ℕ} (hp : p.Prime ∨ p = 0) : have := isAlgClosed_of_model_ACF p M infer_instance +set_option backward.isDefEq.respectTransparency.types false in theorem finite_ACF_prime_not_realize_of_ACF_zero_realize (φ : Language.ring.Sentence) (h : Theory.ACF 0 ⊨ᵇ φ) : Set.Finite { p : Nat.Primes | ¬ Theory.ACF p ⊨ᵇ φ } := by diff --git a/Mathlib/ModelTheory/Algebra/Ring/FreeCommRing.lean b/Mathlib/ModelTheory/Algebra/Ring/FreeCommRing.lean index 804fbd743e1a2d..7de52dd23340d8 100644 --- a/Mathlib/ModelTheory/Algebra/Ring/FreeCommRing.lean +++ b/Mathlib/ModelTheory/Algebra/Ring/FreeCommRing.lean @@ -54,6 +54,7 @@ noncomputable def termOfFreeCommRing (p : FreeCommRing α) : Language.ring.Term variable {R : Type*} [CommRing R] [CompatibleRing R] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem realize_termOfFreeCommRing (p : FreeCommRing α) (v : α → R) : (termOfFreeCommRing p).realize v = FreeCommRing.lift v p := by diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean index fbd2168261ddf4..04f2a85274936b 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean @@ -109,6 +109,7 @@ lemma term_realize_eq_add_dotProduct [Fintype α] (t : presburger[[A]].Term α) variable [Finite α] +set_option backward.isDefEq.respectTransparency false in lemma isSemilinearSet_boundedFormula_realize {n} (φ : presburger[[A]].BoundedFormula α n) : IsSemilinearSet {v : α ⊕ Fin n → ℕ | φ.Realize (v ∘ Sum.inl) (v ∘ Sum.inr)} := by have := Fintype.ofFinite α diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean index d750166966ec53..72b087b288370b 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean @@ -201,6 +201,7 @@ public theorem Nat.isLinearSet_iff_exists_matrix {s : Set (ι → ℕ)} : refine exists₂_congr fun v n => ⟨fun ⟨f, hf⟩ => ⟨f.toNatLinearMap.toMatrix', ?_⟩, fun ⟨A, hA⟩ => ⟨A.mulVecLin, ?_⟩⟩ <;> ext <;> simp [*, mem_vadd_set] +set_option backward.isDefEq.respectTransparency false in private lemma Nat.isSemilinearSet_preimage_of_isLinearSet [Finite ι] {F : Type*} [FunLike F (ι → ℕ) M] [AddMonoidHomClass F (ι → ℕ) M] {s : Set M} (hs : IsLinearSet s) (f : F) : IsSemilinearSet (f ⁻¹' s) := by @@ -432,6 +433,7 @@ private theorem span_basisSet : span ℚ (toRatVec '' hs.basisSet) = ⊤ := by private noncomputable def basis : Basis hs.basisSet ℚ (ι → ℚ) := Basis.mk hs.linearIndepOn_basisSet (image_eq_range _ _ ▸ top_le_iff.2 hs.span_basisSet) +set_option backward.isDefEq.respectTransparency false in private theorem basis_apply (i) : hs.basis i = toRatVec i.1 := by simp [basis] @@ -548,6 +550,7 @@ private theorem fract_add_of_mem_closure {x y} (hy : y ∈ closure hs.basisSet) rw [map_add, ← sub_add_eq_add_sub] simp [-nsmul_eq_mul, ← hs.basis_apply, Finsupp.single_apply] +set_option backward.isDefEq.respectTransparency false in private theorem fract_mem_fundamentalDomain (x) : hs.fract x ∈ hs.fundamentalDomain := by classical intro i diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean index 3cceccbb2e484a..b2cac15217f2ea 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean @@ -207,6 +207,7 @@ theorem isSemilinearSet_image_iff {F : Type*} [EquivLike F M N] [AddEquivClass F simp [image_image] · exact h.image f +set_option backward.isDefEq.respectTransparency false in /-- Semilinear sets are closed under projection (from `ι ⊕ κ → M` to `ι → M` by taking `Sum.inl` on the index). It is a special case of `IsSemilinearSet.image`. -/ theorem IsSemilinearSet.proj {s : Set (ι ⊕ κ → M)} (hs : IsSemilinearSet s) : diff --git a/Mathlib/ModelTheory/Basic.lean b/Mathlib/ModelTheory/Basic.lean index c1a889021df466..a35bc74f7b8a5e 100644 --- a/Mathlib/ModelTheory/Basic.lean +++ b/Mathlib/ModelTheory/Basic.lean @@ -763,7 +763,7 @@ end SumStructure section Empty /-- Any type can be made uniquely into a structure over the empty language. -/ -@[implicit_reducible] +@[instance_reducible] def emptyStructure : Language.empty.Structure M where instance : Unique (Language.empty.Structure M) := @@ -807,7 +807,7 @@ open FirstOrder FirstOrder.Language FirstOrder.Language.Structure variable {L : Language} {M : Type*} {N : Type*} [L.Structure M] /-- A structure induced by a bijection. -/ -@[simps!, implicit_reducible] +@[simps!, instance_reducible] def inducedStructure (e : M ≃ N) : L.Structure N := ⟨fun f x => e (funMap f (e.symm ∘ x)), fun r x => RelMap r (e.symm ∘ x)⟩ diff --git a/Mathlib/ModelTheory/Definability.lean b/Mathlib/ModelTheory/Definability.lean index 01d99e26babc3a..c03b0cea5ec130 100644 --- a/Mathlib/ModelTheory/Definability.lean +++ b/Mathlib/ModelTheory/Definability.lean @@ -71,7 +71,7 @@ theorem definable_iff_exists_formula_sum : refine exists_congr (fun φ => iff_iff_eq.2 (congr_arg (s = ·) ?_)) ext simp only [BoundedFormula.constantsVarsEquiv, constantsOn, - BoundedFormula.mapTermRelEquiv_symm_apply, mem_setOf_eq, Formula.Realize] + mem_setOf_eq, Formula.Realize] refine BoundedFormula.realize_mapTermRel_id ?_ (fun _ _ _ => rfl) intros simp only [Term.constantsVarsEquivLeft_symm_apply, Term.realize_varsToConstants, diff --git a/Mathlib/ModelTheory/DirectLimit.lean b/Mathlib/ModelTheory/DirectLimit.lean index 1574327f4418e6..e4f84402dfea00 100644 --- a/Mathlib/ModelTheory/DirectLimit.lean +++ b/Mathlib/ModelTheory/DirectLimit.lean @@ -99,6 +99,7 @@ def unify {α : Type*} (x : α → Σˣ f) (i : ι) (h : i ∈ upperBounds (rang variable [DirectedSystem G fun i j h => f i j h] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem unify_sigma_mk_self {α : Type*} {i : ι} {x : α → G i} : (unify f (fun a => .mk f i (x a)) i fun _ ⟨_, hj⟩ => @@ -294,6 +295,7 @@ theorem of_f {i j : ι} {hij : i ≤ j} {x : G i} : of L ι G f j (f i j hij x) refine Setoid.symm ⟨j, hij, refl j, ?_⟩ simp only [DirectedSystem.map_self] +set_option backward.isDefEq.respectTransparency.types false in /-- Every element of the direct limit corresponds to some element in some component of the directed system. -/ theorem exists_of (z : DirectLimit G f) : ∃ i x, of L ι G f i x = z := @@ -309,6 +311,7 @@ theorem iSup_range_of_eq_top : ⨆ i, (of L ι G f i).toHom.range = ⊤ := eq_top_iff.2 (fun x _ ↦ DirectLimit.inductionOn x (fun i _ ↦ le_iSup (fun i ↦ Hom.range (Embedding.toHom (of L ι G f i))) i (mem_range_self _))) +set_option backward.isDefEq.respectTransparency.types false in /-- Every finitely generated substructure of the direct limit corresponds to some substructure in some component of the directed system. -/ theorem exists_fg_substructure_in_Sigma (S : L.Substructure (DirectLimit G f)) (S_fg : S.FG) : @@ -404,6 +407,7 @@ theorem equiv_lift_of {i : ι} (x : G i) : variable {L ι G f} +set_option backward.isDefEq.respectTransparency.types false in /-- The direct limit of countably many countably generated structures is countably generated. -/ theorem cg {ι : Type*} [Countable ι] [Preorder ι] [IsDirectedOrder ι] [Nonempty ι] {G : ι → Type w} [∀ i, L.Structure (G i)] (f : ∀ i j, i ≤ j → G i ↪[L] G j) @@ -450,6 +454,7 @@ theorem liftInclusion_of {i : ι} (x : S i) : (liftInclusion S) (of L ι _ (fun _ _ h ↦ Substructure.inclusion (S.monotone h)) i x) = Substructure.subtype (S i) x := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma rangeLiftInclusion : (liftInclusion S).toHom.range = ⨆ i, S i := by simp_rw [liftInclusion, range_lift, Substructure.range_subtype] diff --git a/Mathlib/ModelTheory/Equivalence.lean b/Mathlib/ModelTheory/Equivalence.lean index 770411c75d26af..c06e80f564f593 100644 --- a/Mathlib/ModelTheory/Equivalence.lean +++ b/Mathlib/ModelTheory/Equivalence.lean @@ -201,7 +201,7 @@ protected theorem imp {φ ψ φ' ψ' : L.BoundedFormula α n} (h : φ ⇔[T] ψ) end Iff /-- Semantic equivalence forms an equivalence relation on formulas. -/ -@[implicit_reducible] +@[instance_reducible] def iffSetoid (T : L.Theory) : Setoid (L.BoundedFormula α n) where r := T.Iff iseqv := ⟨fun _ => refl _, fun {_ _} h => h.symm, fun {_ _ _} h1 h2 => h1.trans h2⟩ diff --git a/Mathlib/ModelTheory/FinitelyGenerated.lean b/Mathlib/ModelTheory/FinitelyGenerated.lean index d5341b1c86ea86..c6ef65e598e357 100644 --- a/Mathlib/ModelTheory/FinitelyGenerated.lean +++ b/Mathlib/ModelTheory/FinitelyGenerated.lean @@ -97,6 +97,7 @@ theorem FG.of_map_embedding {N : Type*} [L.Structure N] (f : M ↪[L] N) {s : L. rw [h] at h' exact Hom.map_le_range h' +set_option backward.isDefEq.respectTransparency false in theorem FG.of_finite {s : L.Substructure M} [h : Finite s] : s.FG := ⟨Set.Finite.toFinset h, by simp only [Finite.coe_toFinset, closure_eq]⟩ diff --git a/Mathlib/ModelTheory/Fraisse.lean b/Mathlib/ModelTheory/Fraisse.lean index 509a109eabc56d..e1b2bb61baf394 100644 --- a/Mathlib/ModelTheory/Fraisse.lean +++ b/Mathlib/ModelTheory/Fraisse.lean @@ -327,6 +327,7 @@ theorem isUltrahomogeneous_iff_IsExtensionPair (M_CG : CG L M) : L.IsUltrahomoge ext rfl +set_option backward.isDefEq.respectTransparency.types false in theorem IsUltrahomogeneous.amalgamation_age (h : L.IsUltrahomogeneous M) : Amalgamation (L.age M) := by rintro N P Q NP NQ ⟨Nfg, ⟨-⟩⟩ ⟨Pfg, ⟨PM⟩⟩ ⟨Qfg, ⟨QM⟩⟩ @@ -404,6 +405,7 @@ end IsFraisseLimit namespace empty +set_option backward.isDefEq.respectTransparency.types false in /-- Any countable infinite structure in the empty language is a Fraïssé limit of the class of finite structures. -/ theorem isFraisseLimit_of_countable_infinite diff --git a/Mathlib/ModelTheory/Graph.lean b/Mathlib/ModelTheory/Graph.lean index deff4b767ccf25..c17ffa3dbd3fba 100644 --- a/Mathlib/ModelTheory/Graph.lean +++ b/Mathlib/ModelTheory/Graph.lean @@ -53,7 +53,7 @@ protected def graph : Language := ⟨fun _ => Empty, graphRel⟩ abbrev adj : Language.graph.Relations 2 := .adj /-- Any simple graph can be thought of as a structure in the language of graphs. -/ -@[implicit_reducible] +@[instance_reducible] def _root_.SimpleGraph.structure (G : SimpleGraph V) : Language.graph.Structure V where RelMap | .adj => (fun x => G.Adj (x 0) (x 1)) diff --git a/Mathlib/ModelTheory/LanguageMap.lean b/Mathlib/ModelTheory/LanguageMap.lean index f6cb5d1463a1e0..b95a9c0830ea6f 100644 --- a/Mathlib/ModelTheory/LanguageMap.lean +++ b/Mathlib/ModelTheory/LanguageMap.lean @@ -65,7 +65,7 @@ namespace LHom variable (ϕ : L →ᴸ L') /-- Pulls a structure back along a language map. -/ -@[implicit_reducible] +@[instance_reducible] def reduct (M : Type*) [L'.Structure M] : L.Structure M where funMap f xs := funMap (ϕ.onFunction f) xs RelMap r xs := RelMap (ϕ.onRelation r) xs @@ -182,7 +182,7 @@ protected structure Injective : Prop where /-- Pulls an `L`-structure along a language map `ϕ : L →ᴸ L'`, and then expands it to an `L'`-structure arbitrarily. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def defaultExpansion (ϕ : L →ᴸ L') [∀ (n) (f : L'.Functions n), Decidable (f ∈ Set.range fun f : L.Functions n => onFunction ϕ f)] [∀ (n) (r : L'.Relations n), Decidable (r ∈ Set.range fun r : L.Relations n => onRelation ϕ r)] @@ -344,7 +344,7 @@ theorem card_constantsOn : (constantsOn α).card = #α := by simp [card_eq_card_functions_add_card_relations, sum_nat_eq_add_sum_succ] /-- Gives a `constantsOn α` structure to a type by assigning each constant a value. -/ -@[implicit_reducible] +@[instance_reducible] def constantsOn.structure (f : α → M) : (constantsOn α).Structure M where funMap := fun {n} c _ => match n, c with diff --git a/Mathlib/ModelTheory/Order.lean b/Mathlib/ModelTheory/Order.lean index 68783ea21debee..9ccd8feb322ebb 100644 --- a/Mathlib/ModelTheory/Order.lean +++ b/Mathlib/ModelTheory/Order.lean @@ -205,7 +205,7 @@ variable (L M) /-- Any linearly-ordered type is naturally a structure in the language `Language.order`. This is not an instance, because sometimes the `Language.order.Structure` is defined first. -/ -@[implicit_reducible] +@[instance_reducible] def orderStructure [LE M] : Language.order.Structure M where RelMap | .le => (fun x => x 0 ≤ x 1) @@ -234,6 +234,7 @@ instance [Language.order.Structure M] [Language.order.OrderedStructure M] variable [L.OrderedStructure M] +set_option backward.isDefEq.respectTransparency.types false in instance [Language.order.Structure M] [Language.order.OrderedStructure M] : LHom.IsExpansionOn (orderLHom L) M where map_onRelation := by simp [order.relation_eq_leSymb] @@ -354,7 +355,7 @@ section structure_to_order variable (L) [IsOrdered L] (M) [L.Structure M] /-- Any structure in an ordered language can be ordered correspondingly. -/ -@[implicit_reducible] +@[instance_reducible] def leOfStructure : LE M where le a b := Structure.RelMap (leSymb : L.Relations 2) ![a, b] @@ -375,7 +376,7 @@ def decidableLEOfStructure DecidableLE M := h /-- Any model of a theory of preorders is a preorder. -/ -@[implicit_reducible] +@[instance_reducible] def preorderOfModels [h : M ⊨ L.preorderTheory] : Preorder M where __ := L.leOfStructure M le_refl := (Relations.realize_reflexive.mp <| @@ -384,14 +385,14 @@ def preorderOfModels [h : M ⊨ L.preorderTheory] : Preorder M where Theory.model_iff _ |>.mp h _ <| by simp [preorderTheory]).trans /-- Any model of a theory of partial orders is a partial order. -/ -@[implicit_reducible] +@[instance_reducible] def partialOrderOfModels [h : M ⊨ L.partialOrderTheory] : PartialOrder M where __ := L.preorderOfModels M le_antisymm := (Relations.realize_antisymmetric.mp <| Theory.model_iff _ |>.mp h _ <| by simp [partialOrderTheory]).antisymm /-- Any model of a theory of linear orders is a linear order. -/ -@[implicit_reducible] +@[instance_reducible] def linearOrderOfModels [h : M ⊨ L.linearOrderTheory] [DecidableRel (fun (a b : M) => Structure.RelMap (leSymb : L.Relations 2) ![a, b])] : LinearOrder M where @@ -408,6 +409,7 @@ variable [Language.order.Structure M] [LE M] [Language.order.OrderedStructure M] {N : Type*} [Language.order.Structure N] [LE N] [Language.order.OrderedStructure N] {F : Type*} +set_option backward.isDefEq.respectTransparency.types false in instance [FunLike F M N] [OrderHomClass F M N] : Language.order.HomClass F M N := ⟨fun _ => isEmptyElim, by simp only [forall_relations, relation_eq_leSymb, relMap_leSymb, Fin.isValue, @@ -415,11 +417,13 @@ instance [FunLike F M N] [OrderHomClass F M N] : Language.order.HomClass F M N : exact fun φ x => map_rel φ⟩ -- If `OrderEmbeddingClass` or `RelEmbeddingClass` is defined, this should be generalized. +set_option backward.isDefEq.respectTransparency.types false in instance : Language.order.StrongHomClass (M ↪o N) M N := ⟨fun _ => isEmptyElim, by simp only [order.forall_relations, order.relation_eq_leSymb, relMap_leSymb, Fin.isValue, Function.comp_apply, RelEmbedding.map_rel_iff, implies_true]⟩ +set_option backward.isDefEq.respectTransparency.types false in instance [EquivLike F M N] [OrderIsoClass F M N] : Language.order.StrongHomClass F M N := ⟨fun _ => isEmptyElim, by simp only [order.forall_relations, order.relation_eq_leSymb, relMap_leSymb, Fin.isValue, diff --git a/Mathlib/ModelTheory/PartialEquiv.lean b/Mathlib/ModelTheory/PartialEquiv.lean index c3aa3c1e79dc8b..f1e0fab3d9f224 100644 --- a/Mathlib/ModelTheory/PartialEquiv.lean +++ b/Mathlib/ModelTheory/PartialEquiv.lean @@ -161,6 +161,7 @@ instance : PartialOrder (M ≃ₚ[L] N) where le_trans := le_trans le_antisymm := private le_antisymm +set_option backward.isDefEq.respectTransparency.types false in @[gcongr] lemma symm_le_symm {f g : M ≃ₚ[L] N} (hfg : f ≤ g) : f.symm ≤ g.symm := by rw [le_iff] refine ⟨cod_le_cod hfg, dom_le_dom hfg, ?_⟩ @@ -367,7 +368,7 @@ end DirectLimit section FGEquiv -open PartialEquiv Set DirectLimit +open PartialEquiv Set Language.DirectLimit variable (M) (N) (L) @@ -440,7 +441,7 @@ theorem isExtensionPair_iff_exists_embedding_closure_singleton_sup : and_self] · ext ⟨x, hx⟩ rw [Embedding.subtype_equivRange] at ff'2 - simp only [← ff'2, Embedding.comp_apply, Substructure.coe_inclusion, inclusion_mk, + simp only [← ff'2, Embedding.comp_apply, Substructure.coe_inclusion, Equiv.coe_toEmbedding, coe_subtype, PartialEquiv.toEmbedding_apply] · obtain ⟨f', eq_f'⟩ := h f.dom f_FG f.toEmbedding m refine ⟨⟨⟨closure L {m} ⊔ f.dom, f'.toHom.range, f'.equivRange⟩, diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index 034c211272d8ae..33f68d521a38ff 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -135,6 +135,7 @@ theorem realize_substFunc [L'.Structure M] {c : {n : ℕ} → L.Functions n → | var => simp | func f ts ih => simp [← ih, ← hc] +set_option backward.isDefEq.respectTransparency false in theorem realize_restrictVar [DecidableEq α] {t : L.Term α} {f : t.varFinset → β} {v : β → M} (v' : α → M) (hv' : ∀ a, v (f a) = v' a) : (t.restrictVar f).realize v = t.realize v' := by @@ -150,6 +151,7 @@ theorem realize_restrictVar' [DecidableEq α] {t : L.Term α} {s : Set α} (h : {v : α → M} : (t.restrictVar (Set.inclusion h)).realize (v ∘ (↑)) = t.realize v := realize_restrictVar _ (by simp) +set_option backward.isDefEq.respectTransparency false in theorem realize_restrictVarLeft [DecidableEq α] {γ : Type*} {t : L.Term (α ⊕ γ)} {f : t.varFinsetLeft → β} {xs : β ⊕ γ → M} (xs' : α → M) (hxs' : ∀ a, xs (Sum.inl (f a)) = xs' a) : @@ -437,6 +439,7 @@ theorem realize_subst {φ : L.BoundedFormula α n} {tf : α → L.Term β} {v : · rfl) (by simp) +set_option backward.isDefEq.respectTransparency false in theorem realize_restrictFreeVar [DecidableEq α] {n : ℕ} {φ : L.BoundedFormula α n} {f : φ.freeVarFinset → β} {v : β → M} {xs : Fin n → M} (v' : α → M) (hv' : ∀ a, v (f a) = v' a) : diff --git a/Mathlib/ModelTheory/Substructures.lean b/Mathlib/ModelTheory/Substructures.lean index 934ce661ade2b7..a481c6ce6b82cc 100644 --- a/Mathlib/ModelTheory/Substructures.lean +++ b/Mathlib/ModelTheory/Substructures.lean @@ -686,6 +686,7 @@ namespace LHom variable {L' : Language} [L'.Structure M] +set_option backward.isDefEq.respectTransparency false in /-- Reduces the language of a substructure along a language hom. -/ def substructureReduct (φ : L →ᴸ L') [φ.IsExpansionOn M] : L'.Substructure M ↪o L.Substructure M where @@ -866,6 +867,7 @@ def domRestrict (f : M ↪[L] N) (p : L.Substructure M) : p ↪[L] N := theorem domRestrict_apply (f : M ↪[L] N) (p : L.Substructure M) (x : p) : f.domRestrict p x = f x := rfl +set_option backward.isDefEq.respectTransparency false in /-- A first-order embedding `f : M → N` whose values lie in a substructure `p ⊆ N` can be restricted to an embedding `M → p`. -/ def codRestrict (p : L.Substructure N) (f : M ↪[L] N) (h : ∀ c, f c ∈ p) : M ↪[L] p where diff --git a/Mathlib/ModelTheory/Syntax.lean b/Mathlib/ModelTheory/Syntax.lean index 3a24b6664bcf24..91e8e540b6891f 100644 --- a/Mathlib/ModelTheory/Syntax.lean +++ b/Mathlib/ModelTheory/Syntax.lean @@ -197,6 +197,7 @@ def varsToConstants : L.Term (γ ⊕ α) → L[[γ]].Term α | var (Sum.inl c) => Constants.term (Sum.inr c) | func f ts => func (Sum.inl f) fun i => (ts i).varsToConstants +set_option backward.isDefEq.respectTransparency false in /-- A bijection between terms with constants and terms with extra variables. -/ @[simps] def constantsVarsEquiv : L[[γ]].Term α ≃ L.Term (γ ⊕ α) := diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean b/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean index 60325c75a83656..d6aa067bbf6b58 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean @@ -187,6 +187,7 @@ instance instAddMonoid : AddMonoid (ArithmeticFunction R) where end AddMonoid +set_option backward.isDefEq.respectTransparency false in instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) where natCast n := ⟨fun x ↦ if x = 1 then (n : R) else 0, by simp⟩ natCast_zero := by ext; simp @@ -260,6 +261,7 @@ theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) : apply sum_nbij' (fun ⟨⟨_i, j⟩, ⟨k, l⟩⟩ ↦ ⟨(k, l * j), (l, j)⟩) (fun ⟨⟨i, _j⟩, ⟨k, l⟩⟩ ↦ ⟨(i * k, l), (i, k)⟩) <;> aesop (add simp mul_assoc) +set_option backward.isDefEq.respectTransparency.types false in theorem one_smul' (b : ArithmeticFunction M) : (1 : ArithmeticFunction R) • b = b := by ext x simp_all [← map_div_right_divisors, sum_eq_single 1] @@ -270,6 +272,7 @@ section Semiring variable [Semiring R] +set_option backward.isDefEq.respectTransparency.types false in instance instMonoid : Monoid (ArithmeticFunction R) where one_mul := one_smul' mul_one f := by @@ -378,6 +381,7 @@ theorem dirichletInverseFun_apply_ne {n : ℕ} (hn0 : n ≠ 0) (hn1 : n ≠ 1) : def dirichletInverse : ArithmeticFunction R := ⟨dirichletInverseFun f hf, dirichletInverseFun_apply_zero f hf⟩ +set_option backward.isDefEq.respectTransparency false in theorem self_mul_dirichletInverse (f : ArithmeticFunction R) (hf : Invertible (f 1)) : f * dirichletInverse f hf = 1 := by ext n diff --git a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean index 3e695d52275674..f617e5bb902565 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean @@ -58,6 +58,7 @@ section CommSemiring variable [CommSemiring R] +set_option backward.isDefEq.respectTransparency.types false in /-- The arithmetic function corresponding to the Dirichlet series `f(q⁻ˢ)`. For example, if `f = 1 + X + X² + ...` and `q = p`, then `f(q⁻ˢ) = 1 + p⁻ˢ + p⁻²ˢ + ...`. @@ -130,6 +131,7 @@ noncomputable def ofPowerSeries (q : ℕ) : PowerSeries R →ₐ[R] ArithmeticFu exact ⟨0, by simp [hn]⟩ · simp +set_option backward.isDefEq.respectTransparency.types false in theorem ofPowerSeries_apply {q : ℕ} (hq : 1 < q) (f : PowerSeries R) (n : ℕ) : ofPowerSeries q f n = Function.extend (q ^ ·) (f.coeff ·) 0 n := by simp [ofPowerSeries, dif_pos hq] @@ -141,6 +143,7 @@ theorem ofPowerSeries_apply_pow {q : ℕ} (hq : 1 < q) (f : PowerSeries R) (k : theorem ofPowerSeries_apply_zero (q : ℕ) (f : PowerSeries R) : ofPowerSeries q f 0 = 0 := by simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] -- note that `ofPowerSeries_apply_one` relies on the junk value `f.constantCoeff`. theorem ofPowerSeries_apply_one (q : ℕ) (f : PowerSeries R) : diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean b/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean index 3ec37887bb0a1e..9e6355da4e175f 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean @@ -203,6 +203,7 @@ theorem inv_zetaUnit : ((zetaUnit⁻¹ : (ArithmeticFunction R)ˣ) : ArithmeticF end CommRing +set_option backward.isDefEq.respectTransparency false in /-- Möbius inversion for functions to an `AddCommGroup`. -/ theorem sum_eq_iff_sum_smul_moebius_eq [AddCommGroup R] {f g : ℕ → R} : (∀ n > 0, ∑ i ∈ n.divisors, f i = g n) ↔ diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean index 3c7e3486d06ac2..86f4dffaaa4e92 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean @@ -52,10 +52,12 @@ theorem zeta_apply {x : ℕ} : ζ x = if x = 0 then 0 else 1 := theorem zeta_apply_ne {x : ℕ} (h : x ≠ 0) : ζ x = 1 := if_neg h +set_option backward.isDefEq.respectTransparency false in theorem zeta_eq_zero {x : ℕ} : ζ x = 0 ↔ x = 0 := by simp [zeta] theorem zeta_pos {x : ℕ} : 0 < ζ x ↔ 0 < x := by simp [pos_iff_ne_zero] +set_option backward.isDefEq.respectTransparency false in theorem coe_zeta_smul_apply {M} [Semiring R] [AddCommMonoid M] [MulAction R M] {f : ArithmeticFunction M} {x : ℕ} : ((↑ζ : ArithmeticFunction R) • f) x = ∑ i ∈ divisors x, f i := by @@ -83,6 +85,7 @@ theorem coe_zeta_mul_apply [Semiring R] {f : ArithmeticFunction R} {x : ℕ} : (ζ * f) x = ∑ i ∈ divisors x, f i := coe_zeta_smul_apply +set_option backward.isDefEq.respectTransparency false in theorem coe_mul_zeta_apply [Semiring R] {f : ArithmeticFunction R} {x : ℕ} : (f * ζ) x = ∑ i ∈ divisors x, f i := by rw [← coe_zeta_mul_comm, coe_zeta_mul_apply] @@ -141,6 +144,7 @@ open scoped zeta def ppow (f : ArithmeticFunction R) (k : ℕ) : ArithmeticFunction R := if h0 : k = 0 then ζ else ⟨fun x ↦ f x ^ k, by simp_rw [map_zero, zero_pow h0]⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ppow_zero {f : ArithmeticFunction R} : f.ppow 0 = ζ := by rw [ppow, dif_pos rfl] @@ -148,6 +152,7 @@ theorem ppow_zero {f : ArithmeticFunction R} : f.ppow 0 = ζ := by rw [ppow, dif theorem ppow_one {f : ArithmeticFunction R} : f.ppow 1 = f := by ext; simp [ppow] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ppow_apply {f : ArithmeticFunction R} {k x : ℕ} (kpos : 0 < k) : f.ppow k x = f x ^ k := by rw [ppow, dif_neg (Nat.ne_of_gt kpos), coe_mk] diff --git a/Mathlib/NumberTheory/Chebyshev.lean b/Mathlib/NumberTheory/Chebyshev.lean index f11b8f7ec00db4..f128de3719d2e3 100644 --- a/Mathlib/NumberTheory/Chebyshev.lean +++ b/Mathlib/NumberTheory/Chebyshev.lean @@ -632,6 +632,7 @@ theorem integrableOn_theta_div_id_mul_log_sq (x : ℝ) : have : x * log x ^ 2 ≠ 0 := mul_ne_zero this <| by simp; grind fun_prop +set_option backward.isDefEq.respectTransparency.types false in /-- Expresses the prime counting function `π` in terms of `θ` by using Abel summation. -/ theorem primeCounting_eq_theta_div_log_add_integral {x : ℝ} (hx : 2 ≤ x) : π ⌊x⌋₊ = θ x / log x + ∫ t in 2..x, θ t / (t * log t ^ 2) := by @@ -669,6 +670,7 @@ theorem primeCounting_eq_theta_div_log_add_integral {x : ℝ} (hx : 2 ≤ x) : refine pow_ne_zero 2 <| log_ne_zero_of_pos_of_ne_one ?_ ?_ <;> linarith exact ContinuousAt.continuousWithinAt <| by fun_prop +set_option backward.isDefEq.respectTransparency.types false in /-- Expresses the Chebyshev theta function `ϑ` in terms of `π` by using Abel summation. -/ theorem theta_eq_primeCounting_mul_log_sub_integral {x : ℝ} (hx : 2 ≤ x) : θ x = π ⌊x⌋₊ * log x - ∫ t in 2..x, π ⌊t⌋₊ / t := by diff --git a/Mathlib/NumberTheory/ClassNumber/Finite.lean b/Mathlib/NumberTheory/ClassNumber/Finite.lean index c1baf8148b4a8f..9dc1ed8c70ff59 100644 --- a/Mathlib/NumberTheory/ClassNumber/Finite.lean +++ b/Mathlib/NumberTheory/ClassNumber/Finite.lean @@ -185,6 +185,7 @@ open Real attribute [-instance] Real.decidableEq +set_option backward.isDefEq.respectTransparency.types false in /-- We can approximate `a / b : L` with `q / r`, where `r` has finitely many options for `L`. -/ theorem exists_mem_finsetApprox (a : S) {b} (hb : b ≠ (0 : R)) : ∃ q : S, @@ -326,7 +327,7 @@ algebraic extension `L` is finite if there is an admissible absolute value. See also `ClassGroup.fintypeOfAdmissibleOfFinite` where `L` is a finite extension of `K = Frac(R)`, supplying most of the required assumptions automatically. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfAdmissibleOfAlgebraic [IsDedekindDomain S] [Algebra.IsAlgebraic R S] : Fintype (ClassGroup S) := @Fintype.ofSurjective _ _ _ @@ -348,7 +349,7 @@ absolute value. See also `ClassGroup.fintypeOfAdmissibleOfAlgebraic` where `L` is an algebraic extension of `R`, that includes some extra assumptions. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfAdmissibleOfFinite [IsIntegralClosure S R L] : Fintype (ClassGroup S) := by letI := Classical.decEq L diff --git a/Mathlib/NumberTheory/Dioph.lean b/Mathlib/NumberTheory/Dioph.lean index 585cda8b56ae2d..00b5e723a5fbca 100644 --- a/Mathlib/NumberTheory/Dioph.lean +++ b/Mathlib/NumberTheory/Dioph.lean @@ -443,6 +443,7 @@ theorem diophFn_vec (f : Vector3 ℕ n → ℕ) : DiophFn f ↔ Dioph {v | f (v theorem diophPFun_vec (f : Vector3 ℕ n →. ℕ) : DiophPFun f ↔ Dioph {v | (v ∘ fs, v fz) ∈ f.graph} := ⟨reindex_dioph _ (fz ::ₒ fs), reindex_dioph _ (none::some)⟩ +set_option backward.isDefEq.respectTransparency false in theorem diophFn_compn : ∀ {n} {S : Set (α ⊕ (Fin2 n) → ℕ)} (_ : Dioph S) {f : Vector3 ((α → ℕ) → ℕ) n} (_ : VectorAllP DiophFn f), Dioph {v : α → ℕ | (v ⊗ fun i => f i v) ∈ S} @@ -476,6 +477,7 @@ theorem dioph_comp {S : Set (Vector3 ℕ n)} (d : Dioph S) (f : Vector3 ((α → (df : VectorAllP DiophFn f) : Dioph {v | (fun i => f i v) ∈ S} := diophFn_compn (reindex_dioph _ inr d) df +set_option backward.isDefEq.respectTransparency false in theorem diophFn_comp {f : Vector3 ℕ n → ℕ} (df : DiophFn f) (g : Vector3 ((α → ℕ) → ℕ) n) (dg : VectorAllP DiophFn g) : DiophFn fun v => f fun i => g i v := dioph_comp ((diophFn_vec _).1 df) ((fun v ↦ v none) :: fun i v ↦ g i (v ∘ some)) <| by diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index d78798242b1b1d..442b660cf4ab74 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -361,6 +361,7 @@ theorem image_snd_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.snd rw [← map_swap_divisorsAntidiagonal, map_eq_image, image_image] exact image_fst_divisorsAntidiagonal +set_option backward.isDefEq.respectTransparency false in theorem map_div_right_divisors : n.divisors.map ⟨fun d => (d, n / d), fun _ _ => congr_arg Prod.fst⟩ = n.divisorsAntidiagonal := by @@ -374,6 +375,7 @@ theorem map_div_right_divisors : · rintro ⟨rfl, hn⟩ exact ⟨⟨dvd_mul_right _ _, hn⟩, Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt⟩ +set_option backward.isDefEq.respectTransparency false in theorem map_div_left_divisors : n.divisors.map ⟨fun d => (n / d, d), fun _ _ => congr_arg Prod.snd⟩ = n.divisorsAntidiagonal := by diff --git a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean index 903184cf97c479..46f260fc0add57 100644 --- a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean +++ b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean @@ -184,7 +184,7 @@ lemma DirichletCharacter.LSeries_changeLevel {M N : ℕ} [NeZero N] · exact multipliable_subtype_iff_mulIndicator.mp Multipliable.of_finite · congr 1 with p simp only [Set.mulIndicator_apply, Set.mem_setOf_eq, Finset.mem_coe, Nat.mem_primeFactors, - ne_eq, mul_ite, ite_mul, one_mul, mul_one] + ne_eq, mul_ite, mul_one] by_cases h : p.Prime; swap · simp only [h, false_and, if_false] simp only [h, true_and, if_true] diff --git a/Mathlib/NumberTheory/EulerProduct/ExpLog.lean b/Mathlib/NumberTheory/EulerProduct/ExpLog.lean index ac23af5df1ea45..1b4c7927bf8b3c 100644 --- a/Mathlib/NumberTheory/EulerProduct/ExpLog.lean +++ b/Mathlib/NumberTheory/EulerProduct/ExpLog.lean @@ -35,6 +35,7 @@ lemma Summable.clog_one_sub {α : Type*} {f : α → ℂ} (hsum : Summable f) : namespace EulerProduct +set_option backward.isDefEq.respectTransparency false in /-- A variant of the Euler Product formula in terms of the exponential of a sum of logarithms. -/ theorem exp_tsum_primes_log_eq_tsum {f : ℕ →*₀ ℂ} (hsum : Summable (‖f ·‖)) : exp (∑' p : Nat.Primes, -log (1 - f p)) = ∑' n : ℕ, f n := by diff --git a/Mathlib/NumberTheory/Height/NumberField.lean b/Mathlib/NumberTheory/Height/NumberField.lean index 852c8132ed30e9..ed5f89a4f27a54 100644 --- a/Mathlib/NumberTheory/Height/NumberField.lean +++ b/Mathlib/NumberTheory/Height/NumberField.lean @@ -63,6 +63,7 @@ lemma count_multisetInfinitePlace_eq_mult [DecidableEq (AbsoluteValue K ℝ)] (v simpa only [multisetInfinitePlace, Multiset.count_bind, Finset.sum_map_val, Multiset.count_replicate, ← Subtype.ext_iff] using Fintype.sum_ite_eq' v .. +set_option backward.isDefEq.respectTransparency.types false in -- For the user-facing version, see `prod_archAbsVal_eq` below. private lemma prod_multisetInfinitePlace_eq {M : Type*} [CommMonoid M] (f : AbsoluteValue K ℝ → M) : ((multisetInfinitePlace K).map f).prod = ∏ v : InfinitePlace K, f v.val ^ v.mult := by @@ -90,6 +91,7 @@ lemma prod_nonarchAbsVal_eq {M : Type*} [CommMonoid M] (f : AbsoluteValue K ℝ (∏ᶠ v : nonarchAbsVal, f v.val) = ∏ᶠ v : FinitePlace K, f v.val := rfl +set_option backward.isDefEq.respectTransparency.types false in open Finset Multiset in lemma sum_archAbsVal_eq {M : Type*} [AddCommMonoid M] (f : AbsoluteValue K ℝ → M) : (archAbsVal.map f).sum = ∑ v : InfinitePlace K, v.mult • f v.val := by @@ -175,7 +177,7 @@ private lemma absNorm_mul_finprod_finitePlace_eq_one_aux [Nonempty ι] (hx : ∀ exact apply_mul_absNorm_pow_eq_one v (hx i) -- TODO: Generalize the following to integral closures of `ℤ` in `K` in place of `𝓞 K`. -open Ideal RingOfIntegers in +open Ideal in /-- This statement is equivalent to the fact that the "finite part" of the multiplicative height of a (non-zero) tuple `x` is the inverse of the absolute norm of the ideal generated by the values of `x`. We state it in a way that avoids taking an inverse. -/ diff --git a/Mathlib/NumberTheory/KummerDedekind.lean b/Mathlib/NumberTheory/KummerDedekind.lean index 4099b722cfa7a6..a224752c352e88 100644 --- a/Mathlib/NumberTheory/KummerDedekind.lean +++ b/Mathlib/NumberTheory/KummerDedekind.lean @@ -205,6 +205,7 @@ theorem Ideal.irreducible_map_of_irreducible_minpoly (hI : IsMaximal I) (hI' : I rw [Multiset.attach_map_val, Multiset.map_singleton, Subtype.coe_mk] exact normalizedFactors_irreducible hf +set_option backward.isDefEq.respectTransparency.types false in open Set Classical in /-- Let `Q` be a lift of factor of the minimal polynomial of `x`, a generator of `S` over `R`, taken `mod I`. Then (the reduction of) `Q` corresponds via diff --git a/Mathlib/NumberTheory/LSeries/Convolution.lean b/Mathlib/NumberTheory/LSeries/Convolution.lean index 8a6c97a19d2c94..10963919cba3d5 100644 --- a/Mathlib/NumberTheory/LSeries/Convolution.lean +++ b/Mathlib/NumberTheory/LSeries/Convolution.lean @@ -41,12 +41,14 @@ def toArithmeticFunction {R : Type*} [Zero R] (f : ℕ → R) : ArithmeticFuncti toFun n := if n = 0 then 0 else f n map_zero' := rfl +set_option backward.isDefEq.respectTransparency false in lemma toArithmeticFunction_congr {R : Type*} [Zero R] {f f' : ℕ → R} (h : ∀ {n}, n ≠ 0 → f n = f' n) : toArithmeticFunction f = toArithmeticFunction f' := by ext simp_all [toArithmeticFunction] +set_option backward.isDefEq.respectTransparency false in /-- If we consider an arithmetic function just as a function and turn it back into an arithmetic function, it is the same as before. -/ @[simp] @@ -78,6 +80,7 @@ lemma ArithmeticFunction.coe_mul {R : Type*} [Semiring R] (f g : ArithmeticFunct namespace LSeries +set_option backward.isDefEq.respectTransparency false in lemma convolution_def {R : Type*} [Semiring R] (f g : ℕ → R) : f ⍟ g = fun n ↦ ∑ p ∈ n.divisorsAntidiagonal, f p.1 * g p.2 := by ext n diff --git a/Mathlib/NumberTheory/LSeries/Dirichlet.lean b/Mathlib/NumberTheory/LSeries/Dirichlet.lean index adc4d5b6a96f5f..b520ffa4266f26 100644 --- a/Mathlib/NumberTheory/LSeries/Dirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/Dirichlet.lean @@ -59,6 +59,7 @@ open scoped Moebius open LSeries Nat Complex +set_option backward.isDefEq.respectTransparency.types false in lemma not_LSeriesSummable_moebius_at_one : ¬ LSeriesSummable ↗μ 1 := by refine fun h ↦ not_summable_one_div_on_primes <| summable_ofReal.mp <| .of_neg ?_ refine (h.indicator {n | n.Prime}).congr fun n ↦ ?_ @@ -170,6 +171,7 @@ lemma modOne_eq_one {R : Type*} [CommMonoidWithZero R] {χ : DirichletCharacter lemma LSeries_modOne_eq : L ↗χ₁ = L 1 := congr_arg L modOne_eq_one +set_option backward.isDefEq.respectTransparency.types false in /-- The L-series of a Dirichlet character mod `N > 0` does not converge absolutely at `s = 1`. -/ lemma not_LSeriesSummable_at_one {N : ℕ} (hN : N ≠ 0) (χ : DirichletCharacter ℂ N) : ¬ LSeriesSummable ↗χ 1 := by diff --git a/Mathlib/NumberTheory/LSeries/Injectivity.lean b/Mathlib/NumberTheory/LSeries/Injectivity.lean index 029dc04d8f0a10..ce52398f832e09 100644 --- a/Mathlib/NumberTheory/LSeries/Injectivity.lean +++ b/Mathlib/NumberTheory/LSeries/Injectivity.lean @@ -50,6 +50,7 @@ lemma cpow_mul_div_cpow_eq_div_div_cpow (m n : ℕ) (z : ℂ) (x : ℝ) : rw [← cpow_neg, show (-x : ℂ) = (-1 : ℝ) * x by simp, cpow_mul_ofReal_nonneg Hn, Real.rpow_neg_one, inv_inv] +set_option backward.isDefEq.respectTransparency false in open Filter Real in /-- If the coefficients `f m` of an L-series are zero for `m ≤ n` and the L-series converges at some point, then `f (n+1)` is the limit of `(n+1)^x * LSeries f x` as `x → ∞`. -/ diff --git a/Mathlib/NumberTheory/LSeries/Nonvanishing.lean b/Mathlib/NumberTheory/LSeries/Nonvanishing.lean index ddcc011f4f95d2..610bd56365d49c 100644 --- a/Mathlib/NumberTheory/LSeries/Nonvanishing.lean +++ b/Mathlib/NumberTheory/LSeries/Nonvanishing.lean @@ -86,6 +86,7 @@ lemma LSeriesSummable_zetaMul (χ : DirichletCharacter ℂ N) {s : ℂ} (hs : 1 simpa only [toArithmeticFunction, coe_mk, hn, ↓reduceIte] using norm_le_one χ _ +set_option backward.isDefEq.respectTransparency.types false in lemma zetaMul_prime_pow_nonneg {χ : DirichletCharacter ℂ N} (hχ : χ ^ 2 = 1) {p : ℕ} (hp : p.Prime) (k : ℕ) : 0 ≤ zetaMul χ (p ^ k) := by diff --git a/Mathlib/NumberTheory/LucasLehmer.lean b/Mathlib/NumberTheory/LucasLehmer.lean index afc09ce76a8afc..314677e515db97 100644 --- a/Mathlib/NumberTheory/LucasLehmer.lean +++ b/Mathlib/NumberTheory/LucasLehmer.lean @@ -353,6 +353,7 @@ def ω : X q := (2, 1) /-- We define `ωb = 2 - √3`, which is the inverse of `ω`. -/ def ωb : X q := (2, -1) +set_option backward.isDefEq.respectTransparency.types false in theorem ω_mul_ωb : (ω : X q) * ωb = 1 := by dsimp [ω, ωb] ext <;> simp; ring @@ -360,6 +361,7 @@ theorem ω_mul_ωb : (ω : X q) * ωb = 1 := by theorem ωb_mul_ω : (ωb : X q) * ω = 1 := by rw [mul_comm, ω_mul_ωb] +set_option backward.isDefEq.respectTransparency.types false in /-- A closed form for the recurrence relation. -/ theorem closed_form (i : ℕ) : (s i : X q) = (ω : X q) ^ 2 ^ i + (ωb : X q) ^ 2 ^ i := by induction i with @@ -379,9 +381,11 @@ theorem closed_form (i : ℕ) : (s i : X q) = (ω : X q) ^ 2 ^ i + (ωb : X q) ^ /-- We define `α = √3`. -/ def α : X q := (0, 1) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma α_sq : (α ^ 2 : X q) = 3 := by ext <;> simp [α, sq] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma one_add_α_sq : ((1 + α) ^ 2 : X q) = 2 * ω := by ext <;> simp [α, ω, sq] <;> norm_num @@ -510,9 +514,9 @@ theorem ω_pow_formula (p' : ℕ) (h : lucasLehmerResidue (p' + 2) = 0) : have : 1 ≤ 2 ^ (p' + 2) := Nat.one_le_pow _ _ (by decide) exact mod_cast h -set_option backward.isDefEq.respectTransparency false in -- TODO: fix non-terminal simp (acting on two goals with different simp sets) set_option linter.flexible false in +set_option backward.isDefEq.respectTransparency false in /-- `q` is the minimum factor of `mersenne p`, so `M p = 0` in `X q`. -/ theorem mersenne_coe_X (p : ℕ) : (mersenne p : X (q p)) = 0 := by ext <;> simp [mersenne, q, ZMod.natCast_eq_zero_iff, -pow_pos] diff --git a/Mathlib/NumberTheory/Modular.lean b/Mathlib/NumberTheory/Modular.lean index b12c549aac5970..8bacfaaf39e077 100644 --- a/Mathlib/NumberTheory/Modular.lean +++ b/Mathlib/NumberTheory/Modular.lean @@ -184,6 +184,7 @@ def lcRow0Extend {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) : rw [neg_sq] exact hcd.sq_add_sq_ne_zero, LinearEquiv.refl ℝ (Fin 2 → ℝ)] +set_option backward.isDefEq.respectTransparency false in /-- The map `lcRow0` is proper, that is, preimages of cocompact sets are finite in `[[* , *], [c, d]]`. -/ theorem tendsto_lcRow0 {cd : Fin 2 → ℤ} (hcd : IsCoprime (cd 0) (cd 1)) : @@ -653,6 +654,7 @@ private lemma case_c_one_d_neg_one (hz : z ∈ 𝒟) (hg : g • z ∈ 𝒟) (hg rw [← Int.cast_one, ← Int.cast_neg, Int.cast_le] at this grind +set_option backward.isDefEq.respectTransparency false in private lemma serreTheorem_im_eq (hz : z ∈ 𝒟) (hg : g • z ∈ 𝒟) : (g • z).im = z.im := by wlog hden : z.im ≤ (g • z).im · rw [← this (g := g⁻¹) hg (by simpa using hz) (by simpa using le_of_not_ge hden)] diff --git a/Mathlib/NumberTheory/ModularForms/Bounds.lean b/Mathlib/NumberTheory/ModularForms/Bounds.lean index e890fa454354eb..98e86ddf4c42ff 100644 --- a/Mathlib/NumberTheory/ModularForms/Bounds.lean +++ b/Mathlib/NumberTheory/ModularForms/Bounds.lean @@ -120,7 +120,7 @@ lemma exists_bound_of_subgroup_invariant_of_isBigO exact ⟨g⁻¹ * h, hgh, (mul_inv_cancel_left g h).symm⟩ simp [-sl_moeb, hj', mul_smul, hf_inv j⁻¹ (inv_mem hj)] have hf'_cont γ : Continuous (f' · γ) := QuotientGroup.induction_on γ fun g ↦ by - simp only [sl_moeb, Quotient.lift_mk, f'] + simp only [sl_moeb, f'] fun_prop have hf'_inv τ (g : SL(2, ℤ)) γ : f' (g • τ) (g • γ) = f' τ γ := by induction γ using QuotientGroup.induction_on diff --git a/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean b/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean index beb3d1992c98bb..b90c346505bcef 100644 --- a/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean +++ b/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean @@ -73,6 +73,7 @@ lemma ModularGroup_T_pow_mem_Gamma (N M : ℤ) (hNM : N ∣ M) : instance instFiniteIndexGamma [NeZero N] : (Gamma N).FiniteIndex := Subgroup.finiteIndex_ker _ +set_option backward.isDefEq.respectTransparency.types false in /-- The congruence subgroup of `SL(2, ℤ)` of matrices whose lower left-hand entry reduces to zero modulo `N`. -/ def Gamma0 : Subgroup SL(2, ℤ) where diff --git a/Mathlib/NumberTheory/ModularForms/Cusps.lean b/Mathlib/NumberTheory/ModularForms/Cusps.lean index 3e572abd435718..a6b26045153f1e 100644 --- a/Mathlib/NumberTheory/ModularForms/Cusps.lean +++ b/Mathlib/NumberTheory/ModularForms/Cusps.lean @@ -433,18 +433,22 @@ open Subgroup namespace CongruenceSubgroup +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma strictPeriods_Gamma0 (N : ℕ) : strictPeriods (Gamma0 N : Subgroup (GL (Fin 2) ℝ)) = AddSubgroup.zmultiples 1 := strictPeriods_eq_zmultiples_one_of_T_mem <| by simp [ModularGroup.T] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma strictPeriods_Gamma1 (N : ℕ) : strictPeriods (Gamma1 N : Subgroup (GL (Fin 2) ℝ)) = AddSubgroup.zmultiples 1 := strictPeriods_eq_zmultiples_one_of_T_mem <| by simp [ModularGroup.T] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma strictWidthInfty_Gamma0 (N : ℕ) : strictWidthInfty (Gamma0 N : Subgroup (GL (Fin 2) ℝ)) = 1 := strictWidthInfty_eq_one_of_T_mem <| by simp [ModularGroup.T] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma strictWidthInfty_Gamma1 (N : ℕ) : strictWidthInfty (Gamma1 N : Subgroup (GL (Fin 2) ℝ)) = 1 := strictWidthInfty_eq_one_of_T_mem <| by simp [ModularGroup.T] diff --git a/Mathlib/NumberTheory/ModularForms/Discriminant.lean b/Mathlib/NumberTheory/ModularForms/Discriminant.lean index 910454dce5a432..7d1e6283ff3946 100644 --- a/Mathlib/NumberTheory/ModularForms/Discriminant.lean +++ b/Mathlib/NumberTheory/ModularForms/Discriminant.lean @@ -123,6 +123,7 @@ lemma discriminant_eq_q_prod (z : ℍ) : Δ z = 𝕢 1 z * ∏' n, (1 - eta_q n lemma discriminant_ne_zero (z : ℍ) : Δ z ≠ 0 := by simpa [discriminant] using eta_ne_zero z.2 +set_option backward.isDefEq.respectTransparency.types false in /-- The discriminant is invariant under `T : z ↦ z + 1`, i.e., `Δ(z + 1) = Δ(z)`. -/ lemma discriminant_T_invariant : (Δ ∣[(12 : ℤ)] ModularGroup.T) = Δ := by ext z @@ -138,6 +139,7 @@ lemma eta_comp_eq_csqrt_I_inv : upperHalfPlaneSet.EqOn have h3 : η I = z * sqrt I * η I := by simpa [← mul_assoc] using h (show I ∈ _ by simp) grind [sqrt, eta_ne_zero (show 0 < I.im by simp)] +set_option backward.isDefEq.respectTransparency.types false in /-- The discriminant satisfies the modular transformation for `S : z ↦ -1 / z`: we have `Δ(-1 / z) = z ^ 12 · Δ(z)`. -/ lemma discriminant_S_invariant : (Δ ∣[(12 : ℤ)] ModularGroup.S) = Δ := by diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Defs.lean index 6aeb4fd7759199..833b05a3c81309 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Defs.lean @@ -98,6 +98,7 @@ lemma D2_T : D2 ModularGroup.T = 0 := by ext z simp [D2, ModularGroup.T] +set_option backward.isDefEq.respectTransparency.types false in lemma D2_S (z : ℍ) : D2 ModularGroup.S z = 2 * π * I / z := by simp [D2, ModularGroup.S, ModularGroup.denom_apply] diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Transform.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Transform.lean index f8f56c73da9b4a..bc4a77977e1f31 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Transform.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2/Transform.lean @@ -189,6 +189,7 @@ lemma G2_S_transform (z : ℍ) : G2 z = ((z : ℂ) ^ 2)⁻¹ * G2 (S • z) - -2 rw [G2_S_action_eq_tsum_G2Term, G2_eq_tsum_G2Term z, ← tsum_G2Term_eq_tsum', tsum_G2Term_eq_tsum] +set_option backward.isDefEq.respectTransparency.types false in lemma G2_T_transform : G2 ∣[(2 : ℤ)] T = G2 := by ext z simp_rw [SL_slash_def, modular_T_smul z] diff --git a/Mathlib/NumberTheory/ModularForms/Identities.lean b/Mathlib/NumberTheory/ModularForms/Identities.lean index cb7050cefd69fd..891340fa358862 100644 --- a/Mathlib/NumberTheory/ModularForms/Identities.lean +++ b/Mathlib/NumberTheory/ModularForms/Identities.lean @@ -44,6 +44,7 @@ theorem T_zpow_width_invariant (N : ℕ) (k n : ℤ) (f : SlashInvariantForm (Ga rw [modular_T_zpow_smul z (N * n)] simpa only [Int.cast_mul, Int.cast_natCast] using vAdd_width_periodic N k n f z +set_option backward.isDefEq.respectTransparency.types false in lemma slash_S_apply (f : ℍ → ℂ) (k : ℤ) (z : ℍ) : (f ∣[k] ModularGroup.S) z = f (.mk _ z.im_inv_neg_coe_pos) * z ^ (-k) := by rw [SL_slash_apply, modular_S_smul] diff --git a/Mathlib/NumberTheory/ModularForms/SlashActions.lean b/Mathlib/NumberTheory/ModularForms/SlashActions.lean index 8a70bf98a4e524..dc666c4dae75c6 100644 --- a/Mathlib/NumberTheory/ModularForms/SlashActions.lean +++ b/Mathlib/NumberTheory/ModularForms/SlashActions.lean @@ -61,7 +61,7 @@ attribute [simp] SlashAction.zero_slash SlashAction.slash_one SlashAction.add_sl | insert i t hi IH => simp [hi, IH] /-- `SlashAction` induced by a monoid homomorphism. -/ -@[implicit_reducible] +@[instance_reducible] def monoidHomSlashAction {β G H α : Type*} [Monoid G] [AddMonoid α] [Monoid H] [SlashAction β G α] (h : H →* G) : SlashAction β H α where map k g := SlashAction.map k (h g) diff --git a/Mathlib/NumberTheory/NumberField/Basic.lean b/Mathlib/NumberTheory/NumberField/Basic.lean index 250a8d6db21c0b..8d7e89242bb11a 100644 --- a/Mathlib/NumberTheory/NumberField/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Basic.lean @@ -173,6 +173,7 @@ lemma mk_eq_mk (x y : K) (hx hy) : (⟨x, hx⟩ : 𝓞 K) = ⟨y, hy⟩ ↔ x = @[simp] lemma neg_mk (x : K) (hx) : (-⟨x, hx⟩ : 𝓞 K) = ⟨-x, neg_mem hx⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The ring homomorphism `(𝓞 K) →+* (𝓞 L)` given by restricting a ring homomorphism `f : K →+* L` to `𝓞 K`. -/ def mapRingHom {K L : Type*} [Field K] [Field L] (f : K →+* L) : (𝓞 K) →+* (𝓞 L) where diff --git a/Mathlib/NumberTheory/NumberField/CMField.lean b/Mathlib/NumberTheory/NumberField/CMField.lean index 2e648b6a6623ec..0e67085517ab75 100644 --- a/Mathlib/NumberTheory/NumberField/CMField.lean +++ b/Mathlib/NumberTheory/NumberField/CMField.lean @@ -204,6 +204,7 @@ theorem complexConj_eq_self_iff (x : K) : · rw [IsGalois.fixedField_top, IntermediateField.mem_bot] aesop +set_option backward.isDefEq.respectTransparency.types false in protected theorem RingOfIntegers.complexConj_eq_self_iff (x : 𝓞 K) : complexConj K x = x ↔ ∃ y : 𝓞 K⁺, algebraMap (𝓞 K⁺) K y = x := by rw [complexConj_eq_self_iff] @@ -256,7 +257,7 @@ end complexConj section units -open Units +open NumberField.Units /-- The complex conjugation as an isomorphism of the units of `K`. -/ diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index 1acd6f2757fe81..d2dd850a19dc0a 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -160,6 +160,7 @@ theorem mem_rat_span_latticeBasis [NumberField K] (x : K) : rw [← latticeBasis_apply] exact Set.mem_range_self i +set_option backward.isDefEq.respectTransparency.types false in theorem integralBasis_repr_apply [NumberField K] (x : K) (i : Free.ChooseBasisIndex ℤ (𝓞 K)) : (latticeBasis K).repr (canonicalEmbedding K x) i = (integralBasis K).repr x i := by rw [← Basis.restrictScalars_repr_apply ℚ _ ⟨_, mem_rat_span_latticeBasis K x⟩, eq_ratCast, @@ -241,6 +242,7 @@ instance : NullSingletonClass (volume : Measure (mixedSpace K)) := by pi_nullSingletonClass ⟨w, not_isReal_iff_isComplex.mp hw⟩ exact prod.instNullSingletonClass_snd +set_option backward.isDefEq.respectTransparency.types false in variable {K} in open scoped Classical in /-- The set of points in the mixedSpace that are equal to `0` at a fixed (real) place has @@ -695,6 +697,7 @@ theorem mem_rat_span_latticeBasis (x : K) : rw [← latticeBasis_apply] exact Set.mem_range_self i +set_option backward.isDefEq.respectTransparency.types false in theorem latticeBasis_repr_apply (x : K) (i : ChooseBasisIndex ℤ (𝓞 K)) : (latticeBasis K).repr (mixedEmbedding K x) i = (integralBasis K).repr x i := by rw [← Basis.restrictScalars_repr_apply ℚ _ ⟨_, mem_rat_span_latticeBasis K x⟩, eq_ratCast, @@ -1103,6 +1106,7 @@ abbrev realSpace := InfinitePlace K → ℝ variable {K} +set_option backward.isDefEq.respectTransparency.types false in /-- The set of points in the `realSpace` that are equal to `0` at a fixed place has volume zero. -/ theorem realSpace.volume_eq_zero [NumberField K] (w : InfinitePlace K) : volume ({x : realSpace K | x w = 0}) = 0 := by diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean index 9958e44ebcd81e..5564cd540dfc55 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean @@ -225,6 +225,7 @@ theorem smul_mem_iff_mem (hc : c ≠ 0) : convert! smul_mem_of_mem h (inv_ne_zero hc) rw [eq_inv_smul_iff₀ hc] +set_option backward.isDefEq.respectTransparency.types false in theorem exists_unit_smul_mem (hx : mixedEmbedding.norm x ≠ 0) : ∃ u : (𝓞 K)ˣ, u • x ∈ fundamentalCone K := by classical @@ -479,6 +480,7 @@ the integral ideal `J`. -/ def idealSet : Set (mixedSpace K) := fundamentalCone K ∩ (mixedEmbedding.idealLattice K (FractionalIdeal.mk0 K J)) +set_option backward.isDefEq.respectTransparency.types false in variable {K J} in theorem mem_idealSet : x ∈ idealSet K J ↔ x ∈ fundamentalCone K ∧ ∃ a : (𝓞 K), (a : 𝓞 K) ∈ (J : Set (𝓞 K)) ∧ @@ -520,6 +522,7 @@ variable {K J} theorem idealSetEquiv_apply (a : idealSet K J) : (idealSetEquiv K J a : mixedSpace K) = a := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem idealSetEquiv_symm_apply (a : {a : integerSet K // (preimageOfMemIntegerSet a : 𝓞 K) ∈ (J : Set (𝓞 K)) }) : ((idealSetEquiv K J).symm a : mixedSpace K) = a := by diff --git a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean index 2d4baf22f6d9b5..3f1ea6c64af1be 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean @@ -252,6 +252,7 @@ end HeightOneSpectrum open HeightOneSpectrum Valuation.IsRankOneDiscrete +set_option backward.isDefEq.respectTransparency.types false in /-- The norm of an element in the `v`-adic completion of `K`. See `FinitePlace.norm_embedding` for the equality involving `‖embedding v x‖` on the LHS. -/ theorem FinitePlace.norm_def (x : v.adicCompletion K) : diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index aeffd5753b9329..065b78c17a6c67 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -233,6 +233,7 @@ theorem integralPowerBasisOfPrimePow_dim [hcycl : IsCyclotomicExtension {p ^ k} simp [integralPowerBasisOfPrimePow, ← cyclotomic_eq_minpoly hζ (NeZero.pos _), natDegree_cyclotomic] +set_option backward.isDefEq.respectTransparency.types false in /-- The integral `PowerBasis` of `𝓞 K` given by `ζ - 1`, where `K` is a `p ^ k` cyclotomic extension of `ℚ`. -/ noncomputable def subOneIntegralPowerBasisOfPrimePow [IsCyclotomicExtension {p ^ k} ℚ K] @@ -243,6 +244,7 @@ noncomputable def subOneIntegralPowerBasisOfPrimePow [IsCyclotomicExtension {p ^ convert! Subalgebra.add_mem _ (self_mem_adjoin_singleton ℤ _) (Subalgebra.one_mem _) simp [RingOfIntegers.ext_iff, integralPowerBasisOfPrimePow_gen, toInteger]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem subOneIntegralPowerBasisOfPrimePow_gen [IsCyclotomicExtension {p ^ k} ℚ K] (hζ : IsPrimitiveRoot ζ (p ^ k)) : @@ -250,6 +252,7 @@ theorem subOneIntegralPowerBasisOfPrimePow_gen [IsCyclotomicExtension {p ^ k} ⟨ζ - 1, Subalgebra.sub_mem _ (hζ.isIntegral (NeZero.pos _)) (Subalgebra.one_mem _)⟩ := by simp [subOneIntegralPowerBasisOfPrimePow] +set_option backward.isDefEq.respectTransparency.types false in /-- `ζ - 1` is prime if `p ≠ 2` and `ζ` is a primitive `p ^ (k + 1)`-th root of unity. See `zeta_sub_one_prime` for a general statement. -/ theorem zeta_sub_one_prime_of_ne_two [IsCyclotomicExtension {p ^ (k + 1)} ℚ K] @@ -268,6 +271,7 @@ theorem zeta_sub_one_prime_of_ne_two [IsCyclotomicExtension {p ^ (k + 1)} ℚ K] simp only [algebraMap_int_eq, map_natCast] exact hζ.norm_sub_one_of_prime_ne_two (Polynomial.cyclotomic.irreducible_rat (NeZero.pos _)) hodd +set_option backward.isDefEq.respectTransparency.types false in /-- `ζ - 1` is prime if `ζ` is a primitive `2 ^ (k + 1)`-th root of unity. See `zeta_sub_one_prime` for a general statement. -/ theorem zeta_sub_one_prime_of_two_pow [IsCyclotomicExtension {2 ^ (k + 1)} ℚ K] @@ -313,6 +317,7 @@ theorem subOneIntegralPowerBasisOfPrimePow_gen_prime [IsCyclotomicExtension {p ^ Prime hζ.subOneIntegralPowerBasisOfPrimePow.gen := by simpa only [subOneIntegralPowerBasisOfPrimePow_gen] using! hζ.zeta_sub_one_prime +set_option backward.isDefEq.respectTransparency.types false in /-- The norm, relative to `ℤ`, of `ζ - 1` in an `n`-th cyclotomic extension of `ℚ` where `n` is not a power of a prime number is `1`. @@ -328,6 +333,7 @@ theorem norm_toInteger_sub_one_eq_one {n : ℕ} [IsCyclotomicExtension {n} ℚ K sub_one_norm_eq_eval_cyclotomic hζ h₁ (cyclotomic.irreducible_rat (NeZero.pos _)), eval_one_cyclotomic_not_prime_pow h₂, Int.cast_one] +set_option backward.isDefEq.respectTransparency.types false in /-- The norm, relative to `ℤ`, of `ζ ^ p ^ s - 1` in a `p ^ (k + 1)`-th cyclotomic extension of `ℚ` is `p ^ p ^ s` if `s ≤ k` and `p ^ (k - s + 1) ≠ 2`. -/ lemma norm_toInteger_pow_sub_one_of_prime_pow_ne_two [IsCyclotomicExtension {p ^ (k + 1)} ℚ K] @@ -337,6 +343,7 @@ lemma norm_toInteger_pow_sub_one_of_prime_pow_ne_two [IsCyclotomicExtension {p ^ rw [Algebra.norm_eq_iff ℤ (Sₘ := K) (Rₘ := ℚ) le_rfl] simp [hζ.norm_pow_sub_one_of_prime_pow_ne_two (cyclotomic.irreducible_rat (NeZero.pos _)) hs htwo] +set_option backward.isDefEq.respectTransparency.types false in /-- The norm, relative to `ℤ`, of `ζ ^ 2 ^ k - 1` in a `2 ^ (k + 1)`-th cyclotomic extension of `ℚ` is `(-2) ^ 2 ^ k`. -/ lemma norm_toInteger_pow_sub_one_of_two [IsCyclotomicExtension {2 ^ (k + 1)} ℚ K] @@ -355,6 +362,7 @@ lemma norm_toInteger_pow_sub_one_of_prime_ne_two [IsCyclotomicExtension {p ^ (k apply eq_of_prime_pow_eq hp.out.prime Nat.prime_two.prime (k - s).succ_pos rwa [pow_one] +set_option backward.isDefEq.respectTransparency.types false in /-- The norm, relative to `ℤ`, of `ζ - 1` in a `2 ^ (k + 2)`-th cyclotomic extension of `ℚ` is `2`. -/ @@ -537,6 +545,7 @@ lemma toInteger_sub_one_not_dvd_two [IsCyclotomicExtension {p ^ (k + 1)} ℚ K] · rw [hζ.norm_toInteger_sub_one_of_prime_ne_two hodd] exact Nat.prime_iff_prime_int.1 hp.1 +set_option backward.isDefEq.respectTransparency.types false in open IntermediateField in /-- Let `ζ` be a primitive root of unity of order `n` with `2 ≤ n`. Any prime number that divides the @@ -789,6 +798,7 @@ theorem adjoin_singleton_eq_top [hK : IsCyclotomicExtension {n} ℚ K] exact isCyclotomicExtension_eq {n₁ * n₂} ℚ K _ _ exact adjoin_singleton_eq_top_aux K ℚ⟮ζ ^ n₂⟯ ℚ⟮ζ ^ n₁⟯ hζ₁ hK₁ hζ₂ hK₂ h h_top hζ +set_option backward.isDefEq.respectTransparency.types false in open Algebra in theorem isIntegralClosure_adjoin_singleton {ζ : K} [hcycl : IsCyclotomicExtension {n} ℚ K] (hζ : IsPrimitiveRoot ζ n) : @@ -856,6 +866,7 @@ theorem integralPowerBasis_dim [IsCyclotomicExtension {n} ℚ K] (hζ : IsPrimit hζ.integralPowerBasis.dim = φ n := by simp [integralPowerBasis, ← cyclotomic_eq_minpoly hζ (NeZero.pos _), natDegree_cyclotomic] +set_option backward.isDefEq.respectTransparency.types false in /-- The integral `PowerBasis` of `𝓞 K` given by `ζ - 1`, where `K` is a cyclotomic extension of `ℚ`. -/ noncomputable def subOneIntegralPowerBasis [IsCyclotomicExtension {n} ℚ K] @@ -866,6 +877,7 @@ noncomputable def subOneIntegralPowerBasis [IsCyclotomicExtension {n} ℚ K] convert! Subalgebra.add_mem _ (self_mem_adjoin_singleton ℤ _) (Subalgebra.one_mem _) simp [RingOfIntegers.ext_iff, integralPowerBasis_gen, toInteger]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem subOneIntegralPowerBasis_gen [IsCyclotomicExtension {n} ℚ K] (hζ : IsPrimitiveRoot ζ n) : diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index 32b1942b836d64..f60bf3daf50e2a 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -287,6 +287,7 @@ open NumberField.Ideal Polynomial variable {m} [NeZero m] [hK : IsCyclotomicExtension {m} ℚ K] +set_option backward.isDefEq.respectTransparency.types false in theorem inertiaDeg_eq_of_not_dvd (hm : ¬ p ∣ m) : inertiaDeg P ℤ = orderOf (p : ZMod m) := by replace hm : p.Coprime m := hp.out.coprime_iff_not_dvd.mpr hm diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean index 6f903bf65bab97..05905ab52395a3 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Three.lean @@ -78,19 +78,22 @@ theorem Units.mem [NumberField K] [IsCyclotomicExtension {3} ℚ K] : · right; ext; exact h fin_cases hr <;> rcases hru with h | h <;> simp [h] +set_option backward.isDefEq.respectTransparency.types false in /-- We have that `λ ^ 2 = -3 * η`. -/ private lemma lambda_sq : λ ^ 2 = -3 * η := by ext calc (λ ^ 2 : K) = η ^ 2 + η + 1 - 3 * η := by - simp only [RingOfIntegers.map_mk, IsUnit.unit_spec]; ring + simp only [IsUnit.unit_spec]; ring _ = 0 - 3 * η := by simpa using hζ.isRoot_cyclotomic (by decide) _ = -3 * η := by ring +set_option backward.isDefEq.respectTransparency.types false in /-- We have that `η ^ 2 = -η - 1`. -/ lemma eta_sq : (η ^ 2 : 𝓞 K) = -η - 1 := by rw [← neg_add', ← add_eq_zero_iff_eq_neg, ← add_assoc] ext; simpa using hζ.isRoot_cyclotomic (by decide) +set_option backward.isDefEq.respectTransparency.types false in /-- If a unit `u` is congruent to an integer modulo `λ ^ 2`, then `u = 1` or `u = -1`. This is a special case of the so-called *Kummer's lemma*. -/ diff --git a/Mathlib/NumberTheory/NumberField/House.lean b/Mathlib/NumberTheory/NumberField/House.lean index 8ed34de1dd6c14..fb4d16456eef9d 100644 --- a/Mathlib/NumberTheory/NumberField/House.lean +++ b/Mathlib/NumberTheory/NumberField/House.lean @@ -84,6 +84,7 @@ lemma norm_embedding_le_house (α : K) (σ : K →+* ℂ) : ‖σ α‖ ≤ hous rw [house_eq_sup'] exact Finset.le_sup' (f := (‖· α‖₊)) (Finset.mem_univ σ) +set_option backward.isDefEq.respectTransparency.types false in lemma one_le_house_of_isIntegral {α : K} (hα : IsIntegral ℤ α) (hα0 : α ≠ 0) : 1 ≤ house α := by have ⟨σ, hσ⟩ : ∃ σ : K →+* ℂ, 1 ≤ ‖σ α‖ := by diff --git a/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean b/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean index e149e1a95598ba..4cb403cfcf37e5 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean @@ -34,7 +34,8 @@ namespace NumberField.Ideal open scoped nonZeroDivisors Real -open Filter InfinitePlace mixedEmbedding euclidean fundamentalCone Submodule Topology Units +open Filter InfinitePlace mixedEmbedding euclidean fundamentalCone Submodule Topology +open NumberField.Units variable {C : ClassGroup (𝓞 K)} {J : (Ideal (𝓞 K))⁰} {s : ℝ} diff --git a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean index 201f7b98bb32dc..6c9eaa54edb42f 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/KummerDedekind.lean @@ -183,6 +183,7 @@ theorem primesOverSpanEquivMonicFactorsMod_symm_apply (hp : ¬ p ∣ exponent θ rw [← primesOverSpanEquivMonicFactorsModAux_symm_apply] exact ((primesOverSpanEquivMonicFactorsModAux _).symm ⟨Q, hQ⟩).prop⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The ideal corresponding to the class of `Q ∈ ℤ[X]` modulo `p` via `NumberField.Ideal.primesOverSpanEquivMonicFactorsMod` is spanned by `p` and `Q(θ)`. diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index 1f0acba649f289..6ba3d66943e5d1 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -340,6 +340,7 @@ theorem sum_mult_eq [NumberField K] : exact Finset.sum_congr rfl (fun _ _ => by rw [Finset.sum_const, smul_eq_mul, mul_one, card_filter_mk_eq]) +set_option backward.isDefEq.respectTransparency.types false in /-- The map from real embeddings to real infinite places as an equiv -/ noncomputable def mkReal : { φ : K →+* ℂ // ComplexEmbedding.IsReal φ } ≃ { w : InfinitePlace K // IsReal w } := by @@ -451,6 +452,7 @@ theorem card_eq_nrRealPlaces_add_nrComplexPlaces : (disjoint_isReal_isComplex K) using 1 exact (Fintype.card_of_subtype _ (fun w ↦ ⟨fun _ ↦ isReal_or_isComplex w, fun _ ↦ by simp⟩)).symm +set_option backward.isDefEq.respectTransparency.types false in open scoped Classical in theorem card_complex_embeddings : card { φ : K →+* ℂ // ¬ComplexEmbedding.IsReal φ } = 2 * nrComplexPlaces K := by @@ -571,16 +573,19 @@ namespace NumberField.InfinitePlace variable {K : Type*} [Field K] {v w : InfinitePlace K} +set_option backward.isDefEq.respectTransparency.types false in @[simp] protected theorem map_ratCast (v : InfinitePlace K) (x : ℚ) : v x = ‖x‖ := by rcases v with ⟨_, _⟩ aesop (add simp [coe_apply]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] protected theorem map_natCast (v : InfinitePlace K) (n : ℕ) : v n = n := by rcases v with ⟨_, _⟩ aesop (add simp [coe_apply]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] protected theorem map_intCast (v : InfinitePlace K) (z : ℤ) : v z = ‖z‖ := by rcases v with ⟨_, _⟩ diff --git a/Mathlib/NumberTheory/NumberField/Norm.lean b/Mathlib/NumberTheory/NumberField/Norm.lean index 62f3cb41da6f02..01580e7d942efc 100644 --- a/Mathlib/NumberTheory/NumberField/Norm.lean +++ b/Mathlib/NumberTheory/NumberField/Norm.lean @@ -70,6 +70,7 @@ theorem norm_algebraMap (x : 𝓞 K) : norm K (algebraMap (𝓞 K) (𝓞 L) x) = RingOfIntegers.algebraMap_norm_algebraMap, Algebra.norm_algebraMap, RingOfIntegers.coe_eq_algebraMap, map_pow] +set_option backward.isDefEq.respectTransparency.types false in /-- If `L/K` is a finite Galois extension of fields, then, for all `(x : 𝓞 L)` we have that `x ∣ algebraMap (𝓞 K) (𝓞 L) (norm K x)`. -/ theorem dvd_norm [FiniteDimensional K L] [IsGalois K L] (x : 𝓞 L) : diff --git a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean index c9a4d626332a35..17ea502ed382a8 100644 --- a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean +++ b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean @@ -140,6 +140,7 @@ theorem logEmbedding_component_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h : simp_rw [Pi.norm_def, NNReal.coe_le_coe, Finset.sup_le_iff, ← NNReal.coe_le_coe] at h exact h w (mem_univ _) +set_option backward.isDefEq.respectTransparency.types false in open scoped Classical in theorem log_le_of_logEmbedding_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h : ‖logEmbedding K (Additive.ofMul x)‖ ≤ r) (w : InfinitePlace K) : @@ -313,6 +314,7 @@ theorem exists_unit (w₁ : InfinitePlace K) : rw [Set.mem_setOf_eq, Ideal.absNorm_span_singleton] exact seq_norm_le K w₁ hB n +set_option backward.isDefEq.respectTransparency.types false in theorem unitLattice_span_eq_top : Submodule.span ℝ (unitLattice K : Set (logSpace K)) = ⊤ := by classical @@ -408,6 +410,7 @@ theorem logEmbeddingQuot_injective : Function.comp_apply, EmbeddingLike.apply_eq_iff_eq] at h exact (EmbeddingLike.apply_eq_iff_eq _).mp <| (QuotientGroup.kerLift_injective _).eq_iff.mp h +set_option backward.isDefEq.respectTransparency.types false in /-- The linear equivalence between `(𝓞 K)ˣ ⧸ (torsion K)` as an additive `ℤ`-module and `unitLattice` . -/ def logEmbeddingEquiv : diff --git a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean index cc10d171d392fa..20df063ec2fef7 100644 --- a/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean +++ b/Mathlib/NumberTheory/Padics/HeightOneSpectrum.lean @@ -124,6 +124,7 @@ noncomputable def primesEquiv : HeightOneSpectrum R ≃ Nat.Primes where simp [Ideal.map_comap_of_surjective _ (IsIntegralClosure.intEquiv R).surjective, Int.associated_iff_natAbs.1 (Submodule.IsPrincipal.associated_generator_span_self _)] +set_option backward.isDefEq.respectTransparency.types false in theorem valuation_equiv_padicValuation (v : HeightOneSpectrum R) : (v.valuation ℚ).IsEquiv (padicValuation (primesEquiv v)) := by simp [primesEquiv, Valuation.isEquiv_iff_val_le_one, valuation_le_one_iff_den, @@ -234,6 +235,7 @@ noncomputable def adicCompletionIntegersEquiv (p : Nat.Primes) : apply (ContinuousAlgEquiv.cast (primesEquiv.apply_symm_apply p).symm).trans (adicCompletionIntegers.padicIntEquiv (primesEquiv.symm p)).symm +set_option backward.isDefEq.respectTransparency.types false in /-- The diagram ``` ℤ_[p] --------> (primesEquiv.symm p).adicCompletionIntegers ℚ @@ -253,6 +255,7 @@ theorem coe_adicCompletionIntegersEquiv_apply (p : Nat.Primes) (x : ℤ_[p]) : (by rw [primesEquiv.apply_symm_apply])] exact cast_heq _ _ +set_option backward.isDefEq.respectTransparency.types false in /-- The diagram ``` ℤ_[p] <-------- (primesEquiv.symm p).adicCompletionIntegers ℚ diff --git a/Mathlib/NumberTheory/Padics/Hensel.lean b/Mathlib/NumberTheory/Padics/Hensel.lean index 9031f81aa319ec..01e13cb45fdcb2 100644 --- a/Mathlib/NumberTheory/Padics/Hensel.lean +++ b/Mathlib/NumberTheory/Padics/Hensel.lean @@ -208,6 +208,7 @@ private theorem calc_deriv_dist {z z' z1 : ℤ_[p]} (hz' : z' = z - z1) (T_pow' hnorm _) +set_option backward.isDefEq.respectTransparency false in private def calc_eval_z' {z z' z1 : ℤ_[p]} (hz' : z' = z - z1) {n} (hz : ih n z) (h1 : ‖(↑(F.aeval z) : ℚ_[p]) / ↑(F.derivative.aeval z)‖ ≤ 1) (hzeq : z1 = ⟨_, h1⟩) : { q : ℤ_[p] // F.aeval z' = q * z1 ^ 2 } := by @@ -280,6 +281,7 @@ private theorem newton_seq_norm_le (n : ℕ) : ‖F.aeval (newton_seq n)‖ ≤ ‖F.derivative.aeval a‖ ^ 2 * T ^ 2 ^ n := (newton_seq_aux hnorm n).2.2 +set_option backward.isDefEq.respectTransparency false in private theorem newton_seq_norm_eq (n : ℕ) : ‖newton_seq (n + 1) - newton_seq n‖ = ‖F.aeval (newton_seq n)‖ / ‖F.derivative.aeval (newton_seq n)‖ := by @@ -400,6 +402,7 @@ private theorem newton_seq_succ_dist_weak (n : ℕ) : apply mul_div_mul_left apply deriv_norm_ne_zero; assumption +set_option backward.isDefEq.respectTransparency false in private theorem newton_seq_dist_to_a : ∀ n : ℕ, 0 < n → ‖newton_seq n - a‖ = ‖F.aeval a‖ / ‖F.derivative.aeval a‖ | 1, _h => by simp [sub_eq_add_neg, add_assoc, newton_seq_gen, newton_seq_aux, ih_n] diff --git a/Mathlib/NumberTheory/Padics/MahlerBasis.lean b/Mathlib/NumberTheory/Padics/MahlerBasis.lean index 6761863dcfab02..e993aea0275587 100644 --- a/Mathlib/NumberTheory/Padics/MahlerBasis.lean +++ b/Mathlib/NumberTheory/Padics/MahlerBasis.lean @@ -348,6 +348,7 @@ lemma hasSum_mahler (f : C(ℤ_[p], E)) : HasSum (fun n ↦ mahlerTerm (Δ_[1]^[ simpa [mahlerSeries_apply_nat (fwdDiff_tendsto_zero f) le_rfl] using shift_eq_sum_fwdDiff_iter 1 f n 0 +set_option backward.isDefEq.respectTransparency false in variable (E) in /-- The isometric equivalence from `C(ℤ_[p], E)` to the space of sequences in `E` tending to `0` given diff --git a/Mathlib/NumberTheory/Padics/PadicIntegers.lean b/Mathlib/NumberTheory/Padics/PadicIntegers.lean index e2c1898445b28f..d4a8e052267511 100644 --- a/Mathlib/NumberTheory/Padics/PadicIntegers.lean +++ b/Mathlib/NumberTheory/Padics/PadicIntegers.lean @@ -132,8 +132,10 @@ def Coe.ringHom : ℤ_[p] →+* ℚ_[p] := (subring p).subtype @[simp, norm_cast] theorem coe_pow (x : ℤ_[p]) (n : ℕ) : (↑(x ^ n) : ℚ_[p]) = (↑x : ℚ_[p]) ^ n := rfl +set_option backward.isDefEq.respectTransparency false in theorem mk_coe (k : ℤ_[p]) : (⟨k, k.2⟩ : ℤ_[p]) = k := by simp +set_option backward.isDefEq.respectTransparency false in @[simp] lemma coe_sum {α : Type*} (s : Finset α) (f : α → ℤ_[p]) : (((∑ z ∈ s, f z) : ℤ_[p]) : ℚ_[p]) = ∑ z ∈ s, (f z : ℚ_[p]) := by @@ -158,6 +160,7 @@ instance : CharZero ℤ_[p] where @[norm_cast] theorem intCast_eq (z1 z2 : ℤ) : (z1 : ℤ_[p]) = z2 ↔ z1 = z2 := by simp +set_option backward.isDefEq.respectTransparency false in /-- A sequence of integers that is Cauchy with respect to the `p`-adic norm converges to a `p`-adic integer. -/ def ofIntSeq (seq : ℕ → ℤ) (h : IsCauSeq (padicNorm p) fun n => seq n) : ℤ_[p] := @@ -351,6 +354,7 @@ section Units /-! ### Units of `ℤ_[p]` -/ +set_option backward.isDefEq.respectTransparency false in theorem mul_inv : ∀ {z : ℤ_[p]}, ‖z‖ = 1 → z * z.inv = 1 | ⟨k, _⟩, h => by have hk : k ≠ 0 := fun h' => zero_ne_one' ℚ_[p] (by simp [h'] at h) @@ -561,6 +565,7 @@ instance algebra : Algebra ℤ_[p] ℚ_[p] := theorem algebraMap_apply (x : ℤ_[p]) : algebraMap ℤ_[p] ℚ_[p] x = x := rfl +set_option backward.isDefEq.respectTransparency false in instance isFractionRing : IsFractionRing ℤ_[p] ℚ_[p] where map_units := fun ⟨x, hx⟩ => by rwa [algebraMap_apply, isUnit_iff_ne_zero, PadicInt.coe_ne_zero, ← diff --git a/Mathlib/NumberTheory/Padics/RingHoms.lean b/Mathlib/NumberTheory/Padics/RingHoms.lean index 9556b01b05ac21..9066b53cf70704 100644 --- a/Mathlib/NumberTheory/Padics/RingHoms.lean +++ b/Mathlib/NumberTheory/Padics/RingHoms.lean @@ -99,6 +99,7 @@ theorem norm_sub_modPart_aux (r : ℚ) (h : ‖(r : ℚ_[p])‖ ≤ 1) : rw [← isUnit_iff] exact isUnit_den r h +set_option backward.isDefEq.respectTransparency false in theorem norm_sub_modPart (h : ‖(r : ℚ_[p])‖ ≤ 1) : ‖(⟨r, h⟩ - modPart p r : ℤ_[p])‖ < 1 := by let n := modPart p r rw [norm_lt_one_iff_dvd, ← (isUnit_den r h).dvd_mul_right] @@ -143,6 +144,7 @@ theorem zmod_congr_of_sub_mem_max_ideal (x : ℤ_[p]) (m n : ℕ) (hm : x - m variable (x : ℤ_[p]) +set_option backward.isDefEq.respectTransparency.types false in theorem exists_mem_range : ∃ n : ℕ, n < p ∧ x - n ∈ maximalIdeal ℤ_[p] := by simp only [maximalIdeal_eq_span_p, Ideal.mem_span_singleton, ← norm_lt_one_iff_dvd] obtain ⟨r, hr⟩ := rat_dense p (x : ℚ_[p]) zero_lt_one @@ -574,6 +576,7 @@ The `n`th value of the sequence is `((f n r).val : ℚ)`. def nthHomSeq (r : R) : PadicSeq p := ⟨fun n => nthHom f r n, isCauSeq_nthHom f_compat r⟩ +set_option backward.isDefEq.respectTransparency false in -- this lemma ran into issues after changing to `NeZero` and I'm not sure why. theorem nthHomSeq_one : nthHomSeq f_compat 1 ≈ 1 := by intro ε hε @@ -584,6 +587,7 @@ theorem nthHomSeq_one : nthHomSeq f_compat 1 ≈ 1 := by suffices (ZMod.cast (1 : ZMod (p ^ j)) : ℚ) = 1 by simp [nthHomSeq, nthHom, this, hε] rw [ZMod.cast_eq_val, ZMod.val_one, Nat.cast_one] +set_option backward.isDefEq.respectTransparency false in theorem nthHomSeq_add (r s : R) : nthHomSeq f_compat (r + s) ≈ nthHomSeq f_compat r + nthHomSeq f_compat s := by intro ε hε @@ -599,6 +603,7 @@ theorem nthHomSeq_add (r s : R) : rw [ZMod.cast_add (show p ^ n ∣ p ^ j from pow_dvd_pow _ hj)] simp only [sub_self] +set_option backward.isDefEq.respectTransparency false in theorem nthHomSeq_mul (r s : R) : nthHomSeq f_compat (r * s) ≈ nthHomSeq f_compat r * nthHomSeq f_compat s := by intro ε hε diff --git a/Mathlib/NumberTheory/Padics/WithVal.lean b/Mathlib/NumberTheory/Padics/WithVal.lean index 6a48f60d4d30c2..617294b265bb17 100644 --- a/Mathlib/NumberTheory/Padics/WithVal.lean +++ b/Mathlib/NumberTheory/Padics/WithVal.lean @@ -35,6 +35,7 @@ variable {p : ℕ} [Fact p.Prime] open NNReal WithZero UniformSpace +set_option backward.isDefEq.respectTransparency.types false in open MonoidWithZeroHom.ValueGroup₀ in lemma isUniformInducing_cast_withVal : IsUniformInducing ((Rat.castHom ℚ_[p]).comp (WithVal.equiv (Rat.padicValuation p)).toRingHom) := by diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 115003eb952bc6..34f7097773c5ca 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -363,6 +363,7 @@ theorem quotientToQuotientRangePowQuotSucc_mk {i : ℕ} {a : S} (a_mem : a ∈ P Submodule.Quotient.mk ⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_right x _ a_mem)⟩ := quotientToQuotientRangePowQuotSuccAux_mk p P a_mem x +set_option backward.isDefEq.respectTransparency.types false in theorem quotientToQuotientRangePowQuotSucc_injective [IsDedekindDomain S] [P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i) (a_notMem : a ∉ P ^ (i + 1)) : Function.Injective (quotientToQuotientRangePowQuotSucc p P a_mem) := fun x => diff --git a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean index d964166091eeef..440edccf428699 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean @@ -68,6 +68,7 @@ noncomputable def ramificationIdx' : ℕ := sSup {n | map f p ≤ P ^ n} variable {p P} +set_option backward.isDefEq.respectTransparency.types false in theorem ramificationIdx'_eq_find [DecidablePred fun n ↦ ∀ (k : ℕ), map f p ≤ P ^ k → k ≤ n] (h : ∃ n, ∀ k, map f p ≤ P ^ k → k ≤ n) : ramificationIdx' p P = Nat.find h := by @@ -302,6 +303,7 @@ theorem ramificationIdx'_ne_zero_of_liesOver [IsDomain R] [IsTorsionFree R S] @[deprecated (since := "2026-07-01")] alias ramificationIdx_ne_zero_of_liesOver := ramificationIdx'_ne_zero_of_liesOver +set_option backward.isDefEq.respectTransparency.types false in open IsLocalRing in lemma ramificationIdx'_eq_one_iff {p : Ideal R} {P : Ideal S} [P.IsPrime] diff --git a/Mathlib/NumberTheory/SmoothNumbers.lean b/Mathlib/NumberTheory/SmoothNumbers.lean index 3ba37f37cc32d1..9cb5e4937eafa6 100644 --- a/Mathlib/NumberTheory/SmoothNumbers.lean +++ b/Mathlib/NumberTheory/SmoothNumbers.lean @@ -189,6 +189,7 @@ lemma factoredNumbers.map_prime_pow_mul {F : Type*} [Mul F] {f : ℕ → F} f (p ^ e * m) = f (p ^ e) * f m := hmul <| Coprime.pow_left _ <| hp.factoredNumbers_coprime hs <| Subtype.mem m +set_option backward.isDefEq.respectTransparency false in open List Perm in /-- We establish the bijection from `ℕ × factoredNumbers s` to `factoredNumbers (s ∪ {p})` given by `(e, n) ↦ p^e * n` when `p ∉ s` is a prime. See `Nat.factoredNumbers_insert` for diff --git a/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean index 5209a666978415..6122184f814e7a 100644 --- a/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean @@ -43,6 +43,7 @@ lemma divisorsAntidiagonalFactors_one (x : Nat.divisorsAntidiagonal 1) : simp only [mul_eq_one, ne_eq, one_ne_zero, not_false_eq_true, and_true] at h simp [divisorsAntidiagonalFactors, h.1, h.2] +set_option backward.isDefEq.respectTransparency false in /-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a, b)`. -/ def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where diff --git a/Mathlib/NumberTheory/WellApproximable.lean b/Mathlib/NumberTheory/WellApproximable.lean index cc134902446249..e5218583626eca 100644 --- a/Mathlib/NumberTheory/WellApproximable.lean +++ b/Mathlib/NumberTheory/WellApproximable.lean @@ -187,6 +187,7 @@ local notation a "∣∣" b => a ∣ b ∧ (a * a)∤b local notation "𝕊" => AddCircle T +set_option backward.isDefEq.respectTransparency.types false in /-- **Gallagher's ergodic theorem** on Diophantine approximation. -/ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto δ atTop (𝓝 0)) : (∀ᵐ x, ¬addWellApproximable 𝕊 δ x) ∨ ∀ᵐ x, addWellApproximable 𝕊 δ x := by diff --git a/Mathlib/Order/Antisymmetrization.lean b/Mathlib/Order/Antisymmetrization.lean index a6aa08a2ef52d8..fcde5d6095818e 100644 --- a/Mathlib/Order/Antisymmetrization.lean +++ b/Mathlib/Order/Antisymmetrization.lean @@ -116,7 +116,7 @@ section IsPreorder variable (α) (r : α → α → Prop) [IsPreorder α r] /-- The antisymmetrization relation as an equivalence relation. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def AntisymmRel.setoid : Setoid α := ⟨AntisymmRel r, .refl r, .symm, .trans⟩ @@ -299,6 +299,7 @@ instance [WellFoundedLT α] : WellFoundedLT (Antisymmetrization α (· ≤ ·)) instance [WellFoundedGT α] : WellFoundedGT (Antisymmetrization α (· ≤ ·)) := wellFoundedGT_antisymmetrization_iff.mpr ‹_› +set_option backward.isDefEq.respectTransparency false in instance [DecidableLE α] [DecidableLT α] [@Std.Total α (· ≤ ·)] : LinearOrder (Antisymmetrization α (· ≤ ·)) := { instPartialOrderAntisymmetrization with diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index af99908a4d15f6..f82253b6da7c7d 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -701,6 +701,7 @@ lemma eq_setOf_le_sSup_and_isAtom {α} [CompleteAtomicBooleanAlgebra α] {S : Se · simpa using hatom.1 assumption +set_option backward.isDefEq.respectTransparency false in /-- Representation theorem for complete atomic boolean algebras: For a complete atomic Boolean algebra `α`, `toSetOfIsAtom` is an order isomorphism @@ -759,7 +760,7 @@ instance OrderDual.instIsSimpleOrder {α} [LE α] [BoundedOrder α] [IsSimpleOrd IsSimpleOrder αᵒᵈ := isSimpleOrder_iff_isSimpleOrder_orderDual.1 (by infer_instance) /-- A simple `BoundedOrder` induces a preorder. This is not an instance to prevent loops. -/ -@[implicit_reducible] +@[instance_reducible] protected def IsSimpleOrder.preorder {α} [LE α] [BoundedOrder α] [IsSimpleOrder α] : Preorder α where le_refl a := by rcases eq_bot_or_eq_top a with (rfl | rfl) <;> simp @@ -772,7 +773,7 @@ protected def IsSimpleOrder.preorder {α} [LE α] [BoundedOrder α] [IsSimpleOrd /-- A simple partial ordered `BoundedOrder` induces a linear order. This is not an instance to prevent loops. -/ -@[implicit_reducible] +@[instance_reducible] protected def IsSimpleOrder.linearOrder [DecidableEq α] : LinearOrder α := { (inferInstance : PartialOrder α) with le_total := fun a b => by rcases eq_bot_or_eq_top a with (rfl | rfl) <;> simp @@ -829,14 +830,14 @@ variable [Lattice α] [BoundedOrder α] [IsSimpleOrder α] /-- A simple partial ordered `BoundedOrder` induces a lattice. This is not an instance to prevent loops -/ -@[implicit_reducible] +@[instance_reducible] protected def lattice {α} [DecidableEq α] [PartialOrder α] [BoundedOrder α] [IsSimpleOrder α] : Lattice α := @LinearOrder.toLattice α IsSimpleOrder.linearOrder /-- A lattice that is a `BoundedOrder` is a distributive lattice. This is not an instance to prevent loops -/ -@[implicit_reducible] +@[instance_reducible] protected def distribLattice : DistribLattice α := { (inferInstance : Lattice α) with le_sup_inf := fun x y z => by rcases eq_bot_or_eq_top x with (rfl | rfl) <;> simp } @@ -875,7 +876,7 @@ def orderIsoBool : α ≃o Bool := · simp } /-- A simple `BoundedOrder` is also a `BooleanAlgebra`. -/ -@[implicit_reducible] +@[instance_reducible] protected def booleanAlgebra {α} [DecidableEq α] [Lattice α] [BoundedOrder α] [IsSimpleOrder α] : BooleanAlgebra α := { (inferInstance : BoundedOrder α), IsSimpleOrder.distribLattice with @@ -895,7 +896,7 @@ variable [Lattice α] [BoundedOrder α] [IsSimpleOrder α] open scoped Classical in /-- A simple `BoundedOrder` is also complete. -/ -@[implicit_reducible] +@[instance_reducible] protected noncomputable def completeLattice : CompleteLattice α := { (inferInstance : Lattice α), (inferInstance : BoundedOrder α) with @@ -924,7 +925,7 @@ protected noncomputable def completeLattice : CompleteLattice α := open scoped Classical in /-- A simple `BoundedOrder` is also a `CompleteBooleanAlgebra`. -/ -@[implicit_reducible] +@[instance_reducible] protected noncomputable def completeBooleanAlgebra : CompleteBooleanAlgebra α := { __ := IsSimpleOrder.completeLattice __ := IsSimpleOrder.booleanAlgebra } @@ -1172,6 +1173,7 @@ theorem isAtomic_iff_isCoatomic : IsAtomic α ↔ IsCoatomic α := ⟨fun _ => isCoatomic_of_isAtomic_of_complementedLattice_of_isModular, fun _ => isAtomic_of_isCoatomic_of_complementedLattice_of_isModular⟩ +set_option backward.isDefEq.respectTransparency false in /-- A complemented modular atomic lattice is strongly atomic. Not an instance to prevent loops. -/ theorem ComplementedLattice.isStronglyAtomic [IsAtomic α] : IsStronglyAtomic α where diff --git a/Mathlib/Order/Birkhoff.lean b/Mathlib/Order/Birkhoff.lean index 695f6178b8b6b3..f43fcfb6751abf 100644 --- a/Mathlib/Order/Birkhoff.lean +++ b/Mathlib/Order/Birkhoff.lean @@ -105,6 +105,7 @@ end LowerSet namespace OrderEmbedding +set_option backward.isDefEq.respectTransparency false in /-- The **Birkhoff Embedding** of a finite partial order as sup-irreducible elements in its lattice of lower sets. -/ def supIrredLowerSet : α ↪o {s : LowerSet α // SupIrred s} where @@ -112,6 +113,7 @@ def supIrredLowerSet : α ↪o {s : LowerSet α // SupIrred s} where inj' _ := by simp map_rel_iff' := by simp +set_option backward.isDefEq.respectTransparency false in /-- The **Birkhoff Embedding** of a finite partial order as inf-irreducible elements in its lattice of lower sets. -/ def infIrredUpperSet : α ↪o {s : UpperSet α // InfIrred s} where @@ -155,6 +157,7 @@ namespace OrderIso section SemilatticeSup variable [SemilatticeSup α] [OrderBot α] [Finite α] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma supIrredLowerSet_symm_apply (s : {s : LowerSet α // SupIrred s}) [Fintype s] : supIrredLowerSet.symm s = (s.1 : Set α).toFinset.sup id := by classical @@ -169,6 +172,7 @@ end SemilatticeSup section SemilatticeInf variable [SemilatticeInf α] [OrderTop α] [Finite α] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma infIrredUpperSet_symm_apply (s : {s : UpperSet α // InfIrred s}) [Fintype s] : infIrredUpperSet.symm s = (s.1 : Set α).toFinset.inf id := by classical diff --git a/Mathlib/Order/BooleanAlgebra/Defs.lean b/Mathlib/Order/BooleanAlgebra/Defs.lean index 07301aafade5a2..be7f6b1654a89b 100644 --- a/Mathlib/Order/BooleanAlgebra/Defs.lean +++ b/Mathlib/Order/BooleanAlgebra/Defs.lean @@ -161,7 +161,7 @@ a distributive lattice that is complemented is a Boolean algebra. This is not an instance, because it creates data using choice. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def booleanAlgebraOfComplemented [BoundedOrder α] [ComplementedLattice α] : BooleanAlgebra α where __ := ((inferInstance : BoundedOrder α)) diff --git a/Mathlib/Order/BooleanGenerators.lean b/Mathlib/Order/BooleanGenerators.lean index 63bd704640ce36..f9eb50e0efb6f3 100644 --- a/Mathlib/Order/BooleanGenerators.lean +++ b/Mathlib/Order/BooleanGenerators.lean @@ -139,7 +139,7 @@ lemma sSup_inter (hS : BooleanGenerators S) {T₁ T₂ : Set α} (hT₁ : T₁ · exact (_root_.le_sSup hI).trans (hX'.ge.trans inf_le_right) /-- A lattice generated by Boolean generators is a distributive lattice. -/ -@[implicit_reducible] +@[instance_reducible] def distribLattice_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S = ⊤) : DistribLattice α where le_sup_inf a b c := by @@ -160,7 +160,7 @@ lemma complementedLattice_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S apply complementedLattice_of_isAtomistic /-- A compactly generated complete lattice generated by Boolean generators is a Boolean algebra. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def booleanAlgebra_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S = ⊤) : BooleanAlgebra α := let _i := hS.distribLattice_of_sSup_eq_top h diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index c50f1b1e109a3b..f516384e666df1 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -902,7 +902,7 @@ instance Nat.instDecidableIsLeast (p : ℕ → Prop) (n : ℕ) [DecidablePred p] simp [mem_lowerBounds, @imp_not_comm _ (p _)] /-- An alternative constructor for `SemilatticeSup` using `IsLUB`. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- An alternative constructor for `SemilatticeInf` using `IsGLB`. -/] def SemilatticeSup.ofIsLUB [PartialOrder α] (sup : α → α → α) (isLUB_pair : ∀ a b, IsLUB {a, b} (sup a b)) : @@ -913,7 +913,7 @@ def SemilatticeSup.ofIsLUB [PartialOrder α] (sup : α → α → α) sup_le a b _ hac hbc := (isLUB_pair a b).2 (forall_insert_of_forall (forall_eq.mpr hbc) hac) /-- An alternative constructor for `Lattice` using `IsLUB` and `IsGLB`. -/ -@[implicit_reducible, to_dual self (reorder := 3 4, 5 6)] +@[instance_reducible, to_dual self (reorder := 3 4, 5 6)] def Lattice.ofIsLUBofIsGLB [PartialOrder α] (sup inf : α → α → α) (isLUB_pair : ∀ a b, IsLUB {a, b} (sup a b)) (isGLB_pair : ∀ a b, IsGLB {a, b} (inf a b)) : Lattice α where diff --git a/Mathlib/Order/BourbakiWitt.lean b/Mathlib/Order/BourbakiWitt.lean index 6cb54b5b0b60f3..9e3c206ec7afef 100644 --- a/Mathlib/Order/BourbakiWitt.lean +++ b/Mathlib/Order/BourbakiWitt.lean @@ -251,6 +251,15 @@ lemma ωScottContinuous.sup (hf : ωScottContinuous f) (hg : ωScottContinuous g apply ωScottContinuous.sSup rintro f (rfl | rfl | _) <;> assumption +#adaptation_note +/-- +Why `respectTransparency.types false` here? +The proof of this lemma involves a very subtle form of abuse of definitional equality. +`monotone_const` is only applicable if `Top.top` (`⊤`) can be unfolded to see that it's constant. +However, `Top.top` is semireducible. +This mismatch is problematic because `simp` works at implicit transparency. +-/ +set_option backward.isDefEq.respectTransparency.types false in lemma ωScottContinuous.top : ωScottContinuous (⊤ : α → β) := ωScottContinuous.of_monotone_map_ωSup ⟨monotone_const, fun c ↦ eq_of_forall_ge_iff fun a ↦ by simp⟩ diff --git a/Mathlib/Order/Category/NonemptyFinLinOrd.lean b/Mathlib/Order/Category/NonemptyFinLinOrd.lean index 6b06b384126d25..06094177458cbd 100644 --- a/Mathlib/Order/Category/NonemptyFinLinOrd.lean +++ b/Mathlib/Order/Category/NonemptyFinLinOrd.lean @@ -136,6 +136,7 @@ theorem mono_iff_injective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) : rw [cancel_mono] at eq rw [eq] +set_option backward.isDefEq.respectTransparency.types false in theorem epi_iff_surjective {A B : NonemptyFinLinOrd.{u}} (f : A ⟶ B) : Epi f ↔ Function.Surjective f := by constructor diff --git a/Mathlib/Order/Category/PartOrdEmb.lean b/Mathlib/Order/Category/PartOrdEmb.lean index eb57745a930180..fb1b2bcb849f6c 100644 --- a/Mathlib/Order/Category/PartOrdEmb.lean +++ b/Mathlib/Order/Category/PartOrdEmb.lean @@ -260,7 +260,6 @@ instance : PartialOrder (CoconePt hc) where ((congr_arg (c.ι.app l) (h₃.symm.trans (h₇.trans h₅))).trans ((ConcreteCategory.congr_hom (c.w a) y₁).trans hy₁))) -set_option backward.isDefEq.respectTransparency false in /-- The colimit cocone for a functor `F : J ⥤ PartOrdEmb` from a filtered category that is constructed from a colimit cocone for `F ⋙ forget _`. -/ @[simps] diff --git a/Mathlib/Order/CompactlyGenerated/Intervals.lean b/Mathlib/Order/CompactlyGenerated/Intervals.lean index 8f74c0d3c20efe..bdfb6023b0d61d 100644 --- a/Mathlib/Order/CompactlyGenerated/Intervals.lean +++ b/Mathlib/Order/CompactlyGenerated/Intervals.lean @@ -27,6 +27,7 @@ theorem isCompactElement {a : α} {b : Iic a} (h : IsCompactElement (b : α)) : obtain ⟨t, ht⟩ := h ι ((↑) ∘ s) hb exact ⟨t, (by simpa using ht : (b : α) ≤ _)⟩ +set_option backward.isDefEq.respectTransparency false in instance instIsCompactlyGenerated [IsCompactlyGenerated α] {a : α} : IsCompactlyGenerated (Iic a) := by refine ⟨fun ⟨x, (hx : x ≤ a)⟩ ↦ ?_⟩ diff --git a/Mathlib/Order/Comparable.lean b/Mathlib/Order/Comparable.lean index 7566e190e3ba45..1af998bfe0bce5 100644 --- a/Mathlib/Order/Comparable.lean +++ b/Mathlib/Order/Comparable.lean @@ -174,7 +174,7 @@ theorem AntisymmRel.compRel_congr_right (h : AntisymmRel (· ≤ ·) b c) : end Preorder /-- A partial order where any two elements are comparable is a linear order. -/ -@[implicit_reducible] +@[instance_reducible] def Relation.linearOrderOfSymmGen [PartialOrder α] [decLE : DecidableLE α] [decLT : DecidableLT α] [decEq : DecidableEq α] (h : ∀ a b : α, Relation.SymmGen (· ≤ ·) a b) : LinearOrder α where @@ -184,7 +184,7 @@ def Relation.linearOrderOfSymmGen [PartialOrder α] toDecidableLT := decLT /-- A partial order where any two elements are comparable is a linear order. -/ -@[deprecated linearOrderOfSymmGen (since := "2026-01-25"), implicit_reducible] +@[deprecated linearOrderOfSymmGen (since := "2026-01-25"), instance_reducible] def linearOrderOfComprel [PartialOrder α] [decLE : DecidableLE α] [decLT : DecidableLT α] [decEq : DecidableEq α] (h : ∀ a b : α, CompRel (· ≤ ·) a b) : LinearOrder α := diff --git a/Mathlib/Order/Compare.lean b/Mathlib/Order/Compare.lean index 29da3037a99a1f..de59b5764b6096 100644 --- a/Mathlib/Order/Compare.lean +++ b/Mathlib/Order/Compare.lean @@ -148,7 +148,7 @@ theorem cmp_ofDual [LT α] [DecidableLT α] (x y : αᵒᵈ) : cmp (ofDual x) (o rfl /-- Generate a linear order structure from a preorder and `cmp` function. -/ -@[implicit_reducible] +@[instance_reducible] def linearOrderOfCompares [Preorder α] (cmp : α → α → Ordering) (h : ∀ a b, (cmp a b).Compares a b) : LinearOrder α := let H : DecidableLE α := fun a b => decidable_of_iff _ (h a b).ne_gt diff --git a/Mathlib/Order/CompleteBooleanAlgebra.lean b/Mathlib/Order/CompleteBooleanAlgebra.lean index 686e989f975c90..f79cc154081879 100644 --- a/Mathlib/Order/CompleteBooleanAlgebra.lean +++ b/Mathlib/Order/CompleteBooleanAlgebra.lean @@ -159,7 +159,7 @@ lemma inf_iSup₂_eq {f : ∀ i, κ i → α} (a : α) : (a ⊓ ⨆ i, ⨆ j, f simp only [inf_iSup_eq] /-- The `Order.Frame.MinimalAxioms` element corresponding to a frame. -/ -@[implicit_reducible] +@[instance_reducible] def of [Frame α] : MinimalAxioms α where __ := ‹Frame α› inf_sSup_le_iSup_inf a s := _root_.inf_sSup_eq.le @@ -199,7 +199,7 @@ lemma sup_iInf₂_eq {f : ∀ i, κ i → α} (a : α) : (a ⊔ ⨅ i, ⨅ j, f simp only [sup_iInf_eq] /-- The `Order.Coframe.MinimalAxioms` element corresponding to a frame. -/ -@[implicit_reducible] +@[instance_reducible] def of [Coframe α] : MinimalAxioms α where __ := ‹Coframe α› iInf_sup_le_sup_sInf a s := _root_.sup_sInf_eq.ge @@ -225,7 +225,7 @@ variable (minAx : MinimalAxioms α) /-- The `CompleteDistribLattice.MinimalAxioms` element corresponding to a complete distrib lattice. -/ -@[implicit_reducible] +@[instance_reducible] def of [CompleteDistribLattice α] : MinimalAxioms α where __ := ‹CompleteDistribLattice α› inf_sSup_le_iSup_inf a s := inf_sSup_eq.le @@ -310,7 +310,7 @@ abbrev toCompleteDistribLattice : CompleteDistribLattice.MinimalAxioms α where _ = _ := by simp [sInf_eq_iInf', iInf_unique, iSup_bool_eq] /-- The `CompletelyDistribLattice.MinimalAxioms` element corresponding to a frame. -/ -@[implicit_reducible] +@[instance_reducible] def of [CompletelyDistribLattice α] : MinimalAxioms α := { ‹CompletelyDistribLattice α› with } end MinimalAxioms diff --git a/Mathlib/Order/CompleteLattice/Defs.lean b/Mathlib/Order/CompleteLattice/Defs.lean index 0752929adea1bf..18741feeb3b5e3 100644 --- a/Mathlib/Order/CompleteLattice/Defs.lean +++ b/Mathlib/Order/CompleteLattice/Defs.lean @@ -162,7 +162,7 @@ instance : CompleteLattice my_T where __ := completeLatticeOfInf my_T _ ``` -/ -@[implicit_reducible] +@[instance_reducible] def completeLatticeOfInf (α : Type*) [H1 : PartialOrder α] [H2 : InfSet α] (isGLB_sInf : ∀ s : Set α, IsGLB s (sInf s)) : CompleteLattice α where __ := H1; __ := H2 @@ -189,7 +189,7 @@ def completeLatticeOfInf (α : Type*) [H1 : PartialOrder α] [H2 : InfSet α] Note that this construction has bad definitional properties: see the doc-string on `completeLatticeOfInf`. -/ -@[implicit_reducible] +@[instance_reducible] def completeLatticeOfCompleteSemilatticeInf (α : Type*) [CompleteSemilatticeInf α] : CompleteLattice α := completeLatticeOfInf α fun s => isGLB_sInf s @@ -209,7 +209,7 @@ instance : CompleteLattice my_T where __ := completeLatticeOfSup my_T _ ``` -/ -@[implicit_reducible] +@[instance_reducible] def completeLatticeOfSup (α : Type*) [H1 : PartialOrder α] [H2 : SupSet α] (isLUB_sSup : ∀ s : Set α, IsLUB s (sSup s)) : CompleteLattice α where __ := H1; __ := H2 @@ -234,7 +234,7 @@ def completeLatticeOfSup (α : Type*) [H1 : PartialOrder α] [H2 : SupSet α] Note that this construction has bad definitional properties: see the doc-string on `completeLatticeOfSup`. -/ -@[implicit_reducible] +@[instance_reducible] def completeLatticeOfCompleteSemilatticeSup (α : Type*) [CompleteSemilatticeSup α] : CompleteLattice α := completeLatticeOfSup α fun s => isLUB_sSup s diff --git a/Mathlib/Order/CompleteLattice/PiLex.lean b/Mathlib/Order/CompleteLattice/PiLex.lean index a19760b411479a..df0503f3078abd 100644 --- a/Mathlib/Order/CompleteLattice/PiLex.lean +++ b/Mathlib/Order/CompleteLattice/PiLex.lean @@ -105,36 +105,44 @@ end Lex namespace Colex variable [WellFoundedGT ι] +set_option backward.isDefEq.respectTransparency false in @[no_expose] instance : InfSet (Colex ((i : ι) → α i)) where sInf s := sInf (α := Πₗ i : ιᵒᵈ, α i) s +set_option backward.isDefEq.respectTransparency false in theorem sInf_apply (s : Set (Colex ((i : ι) → α i))) (i : ι) : sInf s i = ⨅ e : {e ∈ s | ∀ j > i, e j = sInf s j}, e.1 i := Lex.sInf_apply (ι := ιᵒᵈ) s i +set_option backward.isDefEq.respectTransparency false in theorem sInf_apply_le {s : Set (Colex ((i : ι) → α i))} {i : ι} {e : Colex ((i : ι) → α i)} (he : e ∈ s) (h : ∀ j > i, e j = sInf s j) : sInf s i ≤ e i := Lex.sInf_apply_le (ι := ιᵒᵈ) he h +set_option backward.isDefEq.respectTransparency false in theorem le_sInf_apply {s : Set (Colex ((i : ι) → α i))} {i : ι} {e : Colex ((i : ι) → α i)} (h : ∀ f ∈ s, (∀ j > i, f j = sInf s j) → e i ≤ f i) : e i ≤ sInf s i := Lex.le_sInf_apply (ι := ιᵒᵈ) h -- TODO: figure out how to use `to_dual` here +set_option backward.isDefEq.respectTransparency false in @[no_expose] instance : SupSet (Colex ((i : ι) → α i)) where sSup s := sSup (α := Πₗ i : ιᵒᵈ, α i) s +set_option backward.isDefEq.respectTransparency false in theorem sSup_apply (s : Set (Colex ((i : ι) → α i))) (i : ι) : sSup s i = ⨆ e : {e ∈ s | ∀ j > i, e j = sSup s j}, e.1 i := Lex.sSup_apply (ι := ιᵒᵈ) s i +set_option backward.isDefEq.respectTransparency false in theorem le_sSup_apply {s : Set (Colex ((i : ι) → α i))} {i : ι} {e : Colex ((i : ι) → α i)} (he : e ∈ s) (h : ∀ j > i, e j = sSup s j) : e i ≤ sSup s i := Lex.le_sSup_apply (ι := ιᵒᵈ) he h +set_option backward.isDefEq.respectTransparency false in theorem sSup_apply_le {s : Set (Colex ((i : ι) → α i))} {i : ι} {e : Colex ((i : ι) → α i)} (h : ∀ f ∈ s, (∀ j > i, f j = sSup s j) → f i ≤ e i) : sSup s i ≤ e i := Lex.sSup_apply_le (ι := ιᵒᵈ) h diff --git a/Mathlib/Order/Completion.lean b/Mathlib/Order/Completion.lean index bdfbcfccf21973..8d26975da93972 100644 --- a/Mathlib/Order/Completion.lean +++ b/Mathlib/Order/Completion.lean @@ -189,6 +189,7 @@ theorem principalEmbedding_trans_factorEmbedding (f : β ↪o α) : principalEmbedding.trans (factorEmbedding f) = f := by ext; simp +set_option backward.isDefEq.respectTransparency false in /-- `DedekindCut.principal` as an `OrderIso`. This provides the second half of the **fundamental theorem of concept lattices**: every complete @@ -202,6 +203,7 @@ def principalIso : α ≃o DedekindCut α where right_inv x := by simp [factorEmbedding] __ := principalEmbedding +set_option backward.isDefEq.respectTransparency false in theorem principalIso_symm_apply (A : DedekindCut α) : principalIso.symm A = sSup A.left := (factorEmbedding_apply ..).trans <| by simp diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean b/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean index d6858e8a17a9bf..57b7624b40b3e7 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean @@ -112,7 +112,7 @@ instance : ConditionallyCompleteLattice my_T where __ := conditionallyCompleteLatticeOfsSup my_T ... ``` -/ -@[to_dual (attr := implicit_reducible) (reorder := 4 5) +@[to_dual (attr := instance_reducible) (reorder := 4 5) /-- Create a `ConditionallyCompleteLattice` from a `PartialOrder` and `sInf` function that returns the greatest lower bound of a nonempty set which is bounded below. Usually this constructor provides poor definitional equalities. If other fields are known explicitly, they @@ -145,7 +145,7 @@ def conditionallyCompleteLatticeOfsSup (α : Type*) [H1 : PartialOrder α] [H2 : /-- A version of `conditionallyCompleteLatticeOfsSup` when we already know that `α` is a lattice. This should only be used when it is both hard and unnecessary to provide `sInf` explicitly. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- A version of `conditionallyCompleteLatticeOfsInf` when we already know that `α` is a lattice. This should only be used when it is both hard and unnecessary to provide `sSup` explicitly. -/] diff --git a/Mathlib/Order/Copy.lean b/Mathlib/Order/Copy.lean index a84a6fcf7de773..d4925479a59fe9 100644 --- a/Mathlib/Order/Copy.lean +++ b/Mathlib/Order/Copy.lean @@ -26,7 +26,7 @@ variable {α : Type u} /-- A function to create a provable equal copy of a top order with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def OrderTop.copy {h : LE α} {h' : LE α} (c : @OrderTop α h') (top : α) (eq_top : top = (by infer_instance : Top α).top) (le_eq : ∀ x y : α, (@LE.le α h) x y ↔ x ≤ y) : @OrderTop α h := @@ -34,7 +34,7 @@ def OrderTop.copy {h : LE α} {h' : LE α} (c : @OrderTop α h') /-- A function to create a provable equal copy of a bottom order with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def OrderBot.copy {h : LE α} {h' : LE α} (c : @OrderBot α h') (bot : α) (eq_bot : bot = (by infer_instance : Bot α).bot) (le_eq : ∀ x y : α, (@LE.le α h) x y ↔ x ≤ y) : @OrderBot α h := @@ -42,7 +42,7 @@ def OrderBot.copy {h : LE α} {h' : LE α} (c : @OrderBot α h') /-- A function to create a provable equal copy of a bounded order with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def BoundedOrder.copy {h : LE α} {h' : LE α} (c : @BoundedOrder α h') (top : α) (eq_top : top = (by infer_instance : Top α).top) (bot : α) (eq_bot : bot = (by infer_instance : Bot α).bot) @@ -52,7 +52,7 @@ def BoundedOrder.copy {h : LE α} {h' : LE α} (c : @BoundedOrder α h') /-- A function to create a provable equal copy of a lattice with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def Lattice.copy (c : Lattice α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (sup : α → α → α) (eq_sup : sup = (by infer_instance : Max α).max) @@ -73,7 +73,7 @@ def Lattice.copy (c : Lattice α) /-- A function to create a provable equal copy of a distributive lattice with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def DistribLattice.copy (c : DistribLattice α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (sup : α → α → α) (eq_sup : sup = (by infer_instance : Max α).max) @@ -83,7 +83,7 @@ def DistribLattice.copy (c : DistribLattice α) /-- A function to create a provable equal copy of a generalised heyting algebra with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def GeneralizedHeytingAlgebra.copy (c : GeneralizedHeytingAlgebra α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) @@ -99,7 +99,7 @@ def GeneralizedHeytingAlgebra.copy (c : GeneralizedHeytingAlgebra α) /-- A function to create a provable equal copy of a generalised co-Heyting algebra with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def GeneralizedCoheytingAlgebra.copy (c : GeneralizedCoheytingAlgebra α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (bot : α) (eq_bot : bot = (by infer_instance : Bot α).bot) @@ -115,7 +115,7 @@ def GeneralizedCoheytingAlgebra.copy (c : GeneralizedCoheytingAlgebra α) /-- A function to create a provable equal copy of a heyting algebra with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def HeytingAlgebra.copy (c : HeytingAlgebra α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) @@ -135,7 +135,7 @@ def HeytingAlgebra.copy (c : HeytingAlgebra α) /-- A function to create a provable equal copy of a co-Heyting algebra with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def CoheytingAlgebra.copy (c : CoheytingAlgebra α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) @@ -155,7 +155,7 @@ def CoheytingAlgebra.copy (c : CoheytingAlgebra α) /-- A function to create a provable equal copy of a bi-Heyting algebra with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def BiheytingAlgebra.copy (c : BiheytingAlgebra α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) @@ -174,7 +174,7 @@ def BiheytingAlgebra.copy (c : BiheytingAlgebra α) /-- A function to create a provable equal copy of a complete lattice with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def CompleteLattice.copy (c : CompleteLattice α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) @@ -196,7 +196,7 @@ def CompleteLattice.copy (c : CompleteLattice α) /-- A function to create a provable equal copy of a frame with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def Frame.copy (c : Frame α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) (bot : α) (eq_bot : bot = (by infer_instance : Bot α).bot) @@ -213,7 +213,7 @@ def Frame.copy (c : Frame α) (le : α → α → Prop) (eq_le : le = (by infer_ /-- A function to create a provable equal copy of a coframe with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def Coframe.copy (c : Coframe α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) (bot : α) (eq_bot : bot = (by infer_instance : Bot α).bot) @@ -230,7 +230,7 @@ def Coframe.copy (c : Coframe α) (le : α → α → Prop) (eq_le : le = (by in /-- A function to create a provable equal copy of a complete distributive lattice with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def CompleteDistribLattice.copy (c : CompleteDistribLattice α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (top : α) (eq_top : top = (by infer_instance : Top α).top) @@ -251,7 +251,7 @@ def CompleteDistribLattice.copy (c : CompleteDistribLattice α) /-- A function to create a provable equal copy of a conditionally complete lattice with possibly different definitional equalities. -/ -@[implicit_reducible] +@[instance_reducible] def ConditionallyCompleteLattice.copy (c : ConditionallyCompleteLattice α) (le : α → α → Prop) (eq_le : le = (by infer_instance : LE α).le) (sup : α → α → α) (eq_sup : sup = (by infer_instance : Max α).max) diff --git a/Mathlib/Order/CountableDenseLinearOrder.lean b/Mathlib/Order/CountableDenseLinearOrder.lean index 58be73b2115c5e..9f4e719a729e61 100644 --- a/Mathlib/Order/CountableDenseLinearOrder.lean +++ b/Mathlib/Order/CountableDenseLinearOrder.lean @@ -65,6 +65,7 @@ theorem exists_between_finsets [DenselyOrdered α] [NoMinOrder α] nonem.elim fun m ↦ ⟨m, fun x hx ↦ (nlo ⟨x, hx⟩).elim, fun y hy ↦ (nhi ⟨y, hy⟩).elim⟩ +set_option backward.isDefEq.respectTransparency false in lemma exists_orderEmbedding_insert [DenselyOrdered β] [NoMinOrder β] [NoMaxOrder β] [nonem : Nonempty β] (S : Finset α) (f : S ↪o β) (a : α) : ∃ (g : (insert a S : Finset α) ↪o β), diff --git a/Mathlib/Order/Defs/PartialOrder.lean b/Mathlib/Order/Defs/PartialOrder.lean index 01d0d4d600790b..f458bbaa1d5ae4 100644 --- a/Mathlib/Order/Defs/PartialOrder.lean +++ b/Mathlib/Order/Defs/PartialOrder.lean @@ -139,7 +139,7 @@ instance instTransGTGE : @Trans α α α GT.gt GE.ge GT.gt := ⟨lt_of_lt_of_le' instance instTransGEGT : @Trans α α α GE.ge GT.gt GT.gt := ⟨lt_of_le_of_lt'⟩ /-- `<` is decidable if `≤` is. -/ -@[implicit_reducible] +@[instance_reducible] def decidableLTOfDecidableLE [DecidableLE α] : DecidableLT α := fun _ _ => decidable_of_iff _ lt_iff_le_not_ge.symm diff --git a/Mathlib/Order/DirectedInverseSystem.lean b/Mathlib/Order/DirectedInverseSystem.lean index 76c35452acdb11..a4de9836e43c4a 100644 --- a/Mathlib/Order/DirectedInverseSystem.lean +++ b/Mathlib/Order/DirectedInverseSystem.lean @@ -96,7 +96,7 @@ open DirectedSystem variable [IsDirectedOrder ι] /-- The setoid on the sigma type defining the direct limit. -/ -@[implicit_reducible] +@[instance_reducible] def setoid : Setoid (Σ i, F i) where r x y := ∃ᵉ (i) (hx : x.1 ≤ i) (hy : y.1 ≤ i), f _ _ hx x.2 = f _ _ hy y.2 iseqv := ⟨fun x ↦ ⟨x.1, le_rfl, le_rfl, rfl⟩, fun ⟨i, hx, hy, eq⟩ ↦ ⟨i, hy, hx, eq.symm⟩, @@ -325,6 +325,7 @@ def piSplitLE : piLT X i × X i ≃ ∀ j : Iic i, X j where left_inv f := by ext j; exacts [dif_neg j.2.ne, dif_pos rfl] right_inv f := by grind +set_option backward.isDefEq.respectTransparency false in @[simp] theorem piSplitLE_eq {f : piLT X i × X i} : piSplitLE f ⟨i, le_rfl⟩ = f.2 := by simp [piSplitLE] @@ -354,6 +355,8 @@ theorem piEquivSucc_self {x} : simp [piEquivSucc] variable {equiv e} + +set_option backward.isDefEq.respectTransparency.types false in theorem isNatEquiv_piEquivSucc [InverseSystem f] (H : ∀ x, (e x).1 = f (le_succ i) x) (nat : IsNatEquiv f equiv) : IsNatEquiv f (piEquivSucc equiv e hi) := fun j k hj hk h x ↦ by have lt_succ {j} := (lt_succ_iff_of_not_isMax (b := j) hi).mpr @@ -449,6 +452,7 @@ theorem pEquivOn_apply_eq (h : IsLowerSet (s ∩ t)) (e₂.restrict inter_subset_right).equiv ⟨i, his, hit⟩ from congr_fun (congr_arg _ <| unique_pEquivOn h) _ +set_option backward.isDefEq.respectTransparency.types false in /-- Extend a partial family of bijections by one step. -/ def pEquivOnSucc [InverseSystem f] (hi : ¬IsMax i) (e : PEquivOn f equivSucc (Iic i)) (H : ∀ ⦃i⦄ (hi : ¬ IsMax i) x, (equivSucc hi x).1 = f (le_succ i) x) : diff --git a/Mathlib/Order/Disjointed.lean b/Mathlib/Order/Disjointed.lean index d91009ae59eaf2..9b50a1305c087e 100644 --- a/Mathlib/Order/Disjointed.lean +++ b/Mathlib/Order/Disjointed.lean @@ -211,6 +211,7 @@ theorem disjointed_unique' {f d : ι → α} (hdisj : Pairwise (Disjoint on d)) (hsups : partialSups d = partialSups f) : d = disjointed f := disjointed_unique (fun hij ↦ hdisj hij.ne) hsups +set_option backward.isDefEq.respectTransparency false in omit [GeneralizedBooleanAlgebra α] in lemma Finset.disjiUnion_Iic_disjointed [DecidableEq α] (n : ι) (t : ι → Finset α) : (Iic n).disjiUnion (disjointed t) ((disjoint_disjointed t).set_pairwise _) = diff --git a/Mathlib/Order/Extension/Well.lean b/Mathlib/Order/Extension/Well.lean index ad30f3594daafe..b4f0871f829686 100644 --- a/Mathlib/Order/Extension/Well.lean +++ b/Mathlib/Order/Extension/Well.lean @@ -56,7 +56,7 @@ By taking the lexicographic product of the two, we get both properties, so we ca get a well-order that extend our original order `r`. Another way to view this is that we choose an arbitrary well-order to serve as a tiebreak between two elements of same rank. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def wellOrderExtension : LinearOrder α := @LinearOrder.lift' α (Ordinal ×ₗ Cardinal) _ (fun a : α => (rank r a, embeddingToCardinal a)) fun _ _ h => embeddingToCardinal.injective <| congr_arg Prod.snd h diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 255ea53e9fd563..9dd612296fb2c7 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -1233,6 +1233,7 @@ theorem set_eventuallyLE_iff_inf_principal_le {s t : Set α} {l : Filter α} : set_eventuallyLE_iff_mem_inf_principal.trans <| by simp only [le_inf_iff, inf_le_left, true_and, le_principal_iff] +set_option backward.isDefEq.respectTransparency false in theorem set_eventuallyEq_iff_inf_principal {s t : Set α} {l : Filter α} : s =ᶠ[l] t ↔ l ⊓ 𝓟 s = l ⊓ 𝓟 t := by simp only [eventuallyLE_antisymm_iff, le_antisymm_iff, set_eventuallyLE_iff_inf_principal_le] diff --git a/Mathlib/Order/Filter/CountableInter.lean b/Mathlib/Order/Filter/CountableInter.lean index c4c652eb3a619d..ca1c030a088a15 100644 --- a/Mathlib/Order/Filter/CountableInter.lean +++ b/Mathlib/Order/Filter/CountableInter.lean @@ -259,6 +259,7 @@ inductive CountableGenerateSets : Set α → Prop | sInter {S : Set (Set α)} : S.Countable → (∀ s ∈ S, CountableGenerateSets s) → CountableGenerateSets (⋂₀ S) +set_option backward.isDefEq.respectTransparency false in /-- `Filter.countableGenerate g` is the greatest `countableInterFilter` containing `g`. -/ def countableGenerate : Filter α := ofCountableInter (CountableGenerateSets g) (fun _ => CountableGenerateSets.sInter) fun _ _ => diff --git a/Mathlib/Order/Filter/Finite.lean b/Mathlib/Order/Filter/Finite.lean index 23abbf5698b21a..3c34527e21e043 100644 --- a/Mathlib/Order/Filter/Finite.lean +++ b/Mathlib/Order/Filter/Finite.lean @@ -83,6 +83,7 @@ theorem mem_iInf_of_iInter {ι} {s : ι → Filter α} {U : Set α} {I : Set ι} refine mem_of_superset (iInter_mem.2 fun i => ?_) hU exact mem_iInf_of_mem (i : ι) (hV _) +set_option backward.isDefEq.respectTransparency false in theorem mem_iInf {ι} {s : ι → Filter α} {U : Set α} : (U ∈ ⨅ i, s i) ↔ ∃ I : Set ι, I.Finite ∧ ∃ V : I → Set α, (∀ (i : I), V i ∈ s i) ∧ U = ⋂ i, V i := by @@ -132,6 +133,7 @@ theorem mem_iInf_of_finite {ι : Sort*} [Finite ι] {α : Type*} {f : ι → Fil rintro ⟨t, ht, rfl⟩ exact iInter_mem.2 fun i => mem_iInf_of_mem i (ht i) +set_option backward.isDefEq.respectTransparency false in theorem mem_biInf_principal {ι : Type*} {p : ι → Prop} {s : ι → Set α} {t : Set α} : t ∈ ⨅ (i : ι) (_ : p i), 𝓟 (s i) ↔ ∃ I : Set ι, I.Finite ∧ (∀ i ∈ I, p i) ∧ ⋂ i ∈ I, s i ⊆ t := by diff --git a/Mathlib/Order/Filter/Germ/Basic.lean b/Mathlib/Order/Filter/Germ/Basic.lean index 8e4bdba81b88d5..8f71d1dce1e9b6 100644 --- a/Mathlib/Order/Filter/Germ/Basic.lean +++ b/Mathlib/Order/Filter/Germ/Basic.lean @@ -70,7 +70,7 @@ theorem const_eventuallyEq' [NeBot l] {a b : β} : (∀ᶠ _ in l, a = b) ↔ a @const_eventuallyEq' _ _ _ _ a b /-- Setoid used to define the space of germs. -/ -@[implicit_reducible] +@[instance_reducible] def germSetoid (l : Filter α) (β : Type*) : Setoid (α → β) where r := EventuallyEq l iseqv := ⟨EventuallyEq.refl _, EventuallyEq.symm, EventuallyEq.trans⟩ @@ -81,7 +81,7 @@ def Germ (l : Filter α) (β : Type*) : Type _ := /-- Setoid used to define the filter product. This is a dependent version of `Filter.germSetoid`. -/ -@[implicit_reducible] +@[instance_reducible] def productSetoid (l : Filter α) (ε : α → Type*) : Setoid ((a : _) → ε a) where r f g := ∀ᶠ a in l, f a = g a iseqv := diff --git a/Mathlib/Order/Filter/Partial.lean b/Mathlib/Order/Filter/Partial.lean index 1b50ff84afc531..f77074f13693f2 100644 --- a/Mathlib/Order/Filter/Partial.lean +++ b/Mathlib/Order/Filter/Partial.lean @@ -122,6 +122,7 @@ theorem rcomap_compose (r : SetRel α β) (s : SetRel β γ) : rcomap r ∘ rcomap s = rcomap (r.comp s) := funext <| rcomap_rcomap _ _ +set_option backward.isDefEq.respectTransparency false in theorem rtendsto_iff_le_rcomap (r : SetRel α β) (l₁ : Filter α) (l₂ : Filter β) : RTendsto r l₁ l₂ ↔ l₁ ≤ l₂.rcomap r := by rw [rtendsto_def] @@ -175,6 +176,7 @@ theorem rcomap'_compose (r : SetRel α β) (s : SetRel β γ) : def RTendsto' (r : SetRel α β) (l₁ : Filter α) (l₂ : Filter β) := l₁ ≤ l₂.rcomap' r +set_option backward.isDefEq.respectTransparency false in theorem rtendsto'_def (r : SetRel α β) (l₁ : Filter α) (l₂ : Filter β) : RTendsto' r l₁ l₂ ↔ ∀ s ∈ l₂, r.preimage s ∈ l₁ := by unfold RTendsto' rcomap'; constructor diff --git a/Mathlib/Order/Filter/Pointwise.lean b/Mathlib/Order/Filter/Pointwise.lean index bfe4f7a6c88cfa..436fb1c429bdfa 100644 --- a/Mathlib/Order/Filter/Pointwise.lean +++ b/Mathlib/Order/Filter/Pointwise.lean @@ -78,7 +78,7 @@ section One variable [One α] {f : Filter α} {s : Set α} /-- `1 : Filter α` is defined as the filter of sets containing `1 : α` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `0 : Filter α` is defined as the filter of sets containing `0 : α` in scope `Pointwise`. -/] protected def instOne : One (Filter α) := ⟨pure 1⟩ @@ -170,7 +170,7 @@ section Inv variable [Inv α] {f g : Filter α} {s : Set α} {a : α} /-- The inverse of a filter is the pointwise preimage under `⁻¹` of its sets. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The negation of a filter is the pointwise preimage under `-` of its sets. -/] def instInv : Inv (Filter α) := ⟨map Inv.inv⟩ @@ -236,7 +236,7 @@ protected theorem HasBasis.inv {ι : Sort*} {p : ι → Prop} {s : ι → Set α simpa using h.map Inv.inv /-- Inversion is involutive on `Filter α` if it is on `α`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- Negation is involutive on `Filter α` if it is on `α`. -/] protected def instInvolutiveInv : InvolutiveInv (Filter α) := { Filter.instInv with @@ -269,7 +269,7 @@ section Mul variable [Mul α] [Mul β] {f f₁ f₂ g g₁ g₂ h : Filter α} {s t : Set α} {a b : α} /-- The filter `f * g` is generated by `{s * t | s ∈ f, t ∈ g}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The filter `f + g` is generated by `{s + t | s ∈ f, t ∈ g}` in scope `Pointwise`. -/] protected def instMul : Mul (Filter α) := ⟨/- This is defeq to `map₂ (· * ·) f g`, but the hypothesis unfolds to `t₁ * t₂ ⊆ s` rather @@ -379,7 +379,7 @@ section Div variable [Div α] {f f₁ f₂ g g₁ g₂ h : Filter α} {s t : Set α} {a b : α} /-- The filter `f / g` is generated by `{s / t | s ∈ f, t ∈ g}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The filter `f - g` is generated by `{s - t | s ∈ f, t ∈ g}` in scope `Pointwise`. -/] protected def instDiv : Div (Filter α) := ⟨/- This is defeq to `map₂ (· / ·) f g`, but the hypothesis unfolds to `t₁ / t₂ ⊆ s` @@ -496,13 +496,13 @@ scoped[Pointwise] attribute [instance] Filter.instNSMul Filter.instNPow Filter.instZSMul Filter.instZPow /-- `Filter α` is a `Semigroup` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Filter α` is an `AddSemigroup` under pointwise operations if `α` is. -/] protected def semigroup [Semigroup α] : Semigroup (Filter α) where mul_assoc _ _ _ := map₂_assoc mul_assoc /-- `Filter α` is a `CommSemigroup` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Filter α` is an `AddCommSemigroup` under pointwise operations if `α` is. -/] protected def commSemigroup [CommSemigroup α] : CommSemigroup (Filter α) := { Filter.semigroup with mul_comm := fun _ _ => map₂_comm mul_comm } @@ -512,7 +512,7 @@ section MulOneClass variable [MulOneClass α] [MulOneClass β] /-- `Filter α` is a `MulOneClass` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Filter α` is an `AddZeroClass` under pointwise operations if `α` is. -/] protected def mulOneClass : MulOneClass (Filter α) where one_mul := map₂_left_identity one_mul @@ -564,7 +564,7 @@ section Monoid variable [Monoid α] {f g : Filter α} {s : Set α} {a : α} {m n : ℕ} /-- `Filter α` is a `Monoid` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Filter α` is an `AddMonoid` under pointwise operations if `α` is. -/] protected def monoid : Monoid (Filter α) := { Filter.mulOneClass, Filter.semigroup, @Filter.instNPow α _ _ with } @@ -615,7 +615,7 @@ protected theorem _root_.IsUnit.filter : IsUnit a → IsUnit (pure a : Filter α end Monoid /-- `Filter α` is a `CommMonoid` under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Filter α` is an `AddCommMonoid` under pointwise operations if `α` is. -/] protected def commMonoid [CommMonoid α] : CommMonoid (Filter α) := { Filter.mulOneClass, Filter.commSemigroup with } @@ -638,7 +638,7 @@ protected theorem mul_eq_one_iff : f * g = 1 ↔ ∃ a b, f = pure a ∧ g = pur rw [pure_mul_pure, h, pure_one] /-- `Filter α` is a division monoid under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `Filter α` is a subtraction monoid under pointwise operations if `α` is. -/] protected def divisionMonoid : DivisionMonoid (Filter α) := { Filter.monoid, Filter.instInvolutiveInv, Filter.instDiv, Filter.instZPow (α := α) with @@ -662,7 +662,7 @@ theorem isUnit_iff : IsUnit f ↔ ∃ a, f = pure a ∧ IsUnit a := by end DivisionMonoid /-- `Filter α` is a commutative division monoid under pointwise operations if `α` is. -/ -@[to_additive (attr := implicit_reducible) subtractionCommMonoid +@[to_additive (attr := instance_reducible) subtractionCommMonoid /-- `Filter α` is a commutative subtraction monoid under pointwise operations if `α` is. -/] protected def divisionCommMonoid [DivisionCommMonoid α] : DivisionCommMonoid (Filter α) := { Filter.divisionMonoid, Filter.commSemigroup with } @@ -788,7 +788,7 @@ variable [SMul α β] {f f₁ f₂ : Filter α} {g g₁ g₂ h : Filter β} {s : {b : β} /-- The filter `f • g` is generated by `{s • t | s ∈ f, t ∈ g}` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The filter `f +ᵥ g` is generated by `{s +ᵥ t | s ∈ f, t ∈ g}` in locale `Pointwise`. -/] protected def instSMul : SMul (Filter α) (Filter β) := @@ -971,7 +971,7 @@ section SMul variable [SMul α β] {f f₁ f₂ : Filter β} {s : Set β} {a : α} /-- `a • f` is the map of `f` under `a •` in scope `Pointwise`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `a +ᵥ f` is the map of `f` under `a +ᵥ` in scope `Pointwise`. -/] protected def instSMulFilter : SMul α (Filter β) := ⟨fun a => map (a • ·)⟩ @@ -1076,7 +1076,7 @@ instance isCentralScalar [SMul α β] [SMul αᵐᵒᵖ β] [IsCentralScalar α /-- A multiplicative action of a monoid `α` on a type `β` gives a multiplicative action of `Filter α` on `Filter β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive action of an additive monoid `α` on a type `β` gives an additive action of `Filter α` on `Filter β`. -/] protected def mulAction [Monoid α] [MulAction α β] : MulAction (Filter α) (Filter β) where @@ -1085,7 +1085,7 @@ protected def mulAction [Monoid α] [MulAction α β] : MulAction (Filter α) (F /-- A multiplicative action of a monoid on a type `β` gives a multiplicative action on `Filter β`. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- An additive action of an additive monoid on a type `β` gives an additive action on `Filter β`. -/] protected def mulActionFilter [Monoid α] [MulAction α β] : MulAction α (Filter β) where diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index e51ef5e2b5bcf6..15aa32cf1cfa23 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -110,6 +110,7 @@ theorem sup_prod (f₁ f₂ : Filter α) (g : Filter β) : (f₁ ⊔ f₂) ×ˢ theorem prod_sup (f : Filter α) (g₁ g₂ : Filter β) : f ×ˢ (g₁ ⊔ g₂) = (f ×ˢ g₁) ⊔ (f ×ˢ g₂) := by simp only [prod_eq_inf, comap_sup, inf_sup_left] +set_option backward.isDefEq.respectTransparency false in theorem eventually_prod_iff {p : α × β → Prop} : (∀ᶠ x in f ×ˢ g, p x) ↔ ∃ pa : α → Prop, (∀ᶠ x in f, pa x) ∧ ∃ pb : β → Prop, (∀ᶠ y in g, pb y) ∧ diff --git a/Mathlib/Order/Filter/Ultrafilter/Basic.lean b/Mathlib/Order/Filter/Ultrafilter/Basic.lean index 43971b62f5fbe5..be4726c37ad990 100644 --- a/Mathlib/Order/Filter/Ultrafilter/Basic.lean +++ b/Mathlib/Order/Filter/Ultrafilter/Basic.lean @@ -39,6 +39,7 @@ theorem finite_biUnion_mem_iff {is : Set β} {s : β → Set α} (his : is.Finit (⋃ i ∈ is, s i) ∈ f ↔ ∃ i ∈ is, s i ∈ f := by simp only [← sUnion_image, finite_sUnion_mem_iff (his.image s), exists_mem_image] +set_option backward.isDefEq.respectTransparency false in lemma eventually_exists_mem_iff {is : Set β} {P : β → α → Prop} (his : is.Finite) : (∀ᶠ i in f, ∃ a ∈ is, P a i) ↔ ∃ a ∈ is, ∀ᶠ i in f, P a i := by simp only [Filter.Eventually, Ultrafilter.mem_coe] diff --git a/Mathlib/Order/Fin/Tuple.lean b/Mathlib/Order/Fin/Tuple.lean index 3c596a6acf48a0..488e6c08581a3e 100644 --- a/Mathlib/Order/Fin/Tuple.lean +++ b/Mathlib/Order/Fin/Tuple.lean @@ -179,6 +179,7 @@ lemma finSuccAboveOrderIso_symm_apply_ne_last {p : Fin (n + 1)} (h : p ≠ Fin.l rw [← Option.some_inj] simpa [finSuccAboveEquiv, OrderIso.symm] using finSuccEquiv'_ne_last_apply h x.property +set_option backward.isDefEq.respectTransparency false in /-- Promote a `Fin n` into a larger `Fin m`, as a subtype where the underlying values are retained. This is the `OrderIso` version of `Fin.castLE`. -/ @[simps apply symm_apply] diff --git a/Mathlib/Order/GaloisConnection/Defs.lean b/Mathlib/Order/GaloisConnection/Defs.lean index 41dc65626f235d..4ab966280e4dd1 100644 --- a/Mathlib/Order/GaloisConnection/Defs.lean +++ b/Mathlib/Order/GaloisConnection/Defs.lean @@ -248,7 +248,7 @@ def GaloisConnection.toGaloisInsertion {α β : Type*} [Preorder α] [Preorder choice_eq := fun _ _ => rfl } /-- Lift the bottom along a Galois connection -/ -@[to_dual (attr := implicit_reducible) /-- Lift the top along a Galois connection -/] +@[to_dual (attr := instance_reducible) /-- Lift the top along a Galois connection -/] def GaloisConnection.liftOrderBot {α β : Type*} [Preorder α] [OrderBot α] [PartialOrder β] {l : α → β} {u : β → α} (gc : GaloisConnection l u) : OrderBot β where diff --git a/Mathlib/Order/Height.lean b/Mathlib/Order/Height.lean index a3730fbc6acb25..296f501975e07b 100644 --- a/Mathlib/Order/Height.lean +++ b/Mathlib/Order/Height.lean @@ -159,6 +159,7 @@ theorem chainHeight_eq_of_relIso (e : r ≃r r') : (e '' s).chainHeight r' = s.c end Rel +set_option backward.isDefEq.respectTransparency false in @[simp] theorem chainHeight_coe_univ : (@Set.univ ↑s).chainHeight (r ↑· ↑·) = s.chainHeight r := by have hc := Set.chainHeight_eq_of_relEmbedding univ <| Subtype.relEmbedding (r · ·) (· ∈ s) diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 351b640014edbf..da7e91b478e0b7 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -316,6 +316,7 @@ theorem mk_le_mk {f g : α → β} {hf hg} : mk f hf ≤ mk g hg ↔ f ≤ g := theorem apply_mono {f g : α →o β} {x y : α} (h₁ : f ≤ g) (h₂ : x ≤ y) : f x ≤ g y := (h₁ x).trans <| g.mono h₂ +set_option backward.isDefEq.respectTransparency false in /-- Curry/uncurry as an order isomorphism between `α × β →o γ` and `α →o β →o γ`. -/ def curry : (α × β →o γ) ≃o (α →o β →o γ) where toFun f := ⟨fun x ↦ ⟨Function.curry f x, fun _ _ h ↦ f.mono ⟨le_rfl, h⟩⟩, fun _ _ h _ => @@ -911,6 +912,7 @@ theorem trans_assoc (f : α ≃o β) (g : β ≃o γ) (h : γ ≃o δ) : (f.trans g).trans h = f.trans (g.trans h) := rfl +set_option backward.isDefEq.respectTransparency false in /-- An order isomorphism between the domains and codomains of two prosets of order homomorphisms gives an order isomorphism between the two function prosets. -/ @[simps apply symm_apply] @@ -988,6 +990,7 @@ def prodComm : α × β ≃o β × α where toEquiv := Equiv.prodComm α β map_rel_iff' := Prod.swap_le_swap +set_option backward.isDefEq.respectTransparency false in /-- `Equiv.prodAssoc` promoted to an order isomorphism. -/ @[simps! (attr := grind =)] def prodAssoc (α β γ : Type*) [LE α] [LE β] [LE γ] : diff --git a/Mathlib/Order/Hom/CompleteLattice.lean b/Mathlib/Order/Hom/CompleteLattice.lean index 985d41c9809745..1f617bc4e24f46 100644 --- a/Mathlib/Order/Hom/CompleteLattice.lean +++ b/Mathlib/Order/Hom/CompleteLattice.lean @@ -652,6 +652,7 @@ def sSupHom.setImage (f : α → β) : sSupHom (Set α) (Set β) where toFun := image f map_sSup' := Set.image_sSup +set_option backward.isDefEq.respectTransparency false in /-- An equivalence of types yields an order isomorphism between their lattices of subsets. -/ @[simps] def Equiv.toOrderIsoSet (e : α ≃ β) : Set α ≃o Set β where diff --git a/Mathlib/Order/Hom/Lex.lean b/Mathlib/Order/Hom/Lex.lean index 6b647e3087261a..57057ea3f5713a 100644 --- a/Mathlib/Order/Hom/Lex.lean +++ b/Mathlib/Order/Hom/Lex.lean @@ -150,6 +150,7 @@ end OrderIso namespace Prod.Lex variable (α β : Type*) +set_option backward.isDefEq.respectTransparency.types false in /-- Lexicographic product type with `Unique` type on the right is `OrderIso` to the left. -/ def prodUnique [PartialOrder α] [Preorder β] [Unique β] : α ×ₗ β ≃o α where toFun x := (ofLex x).1 @@ -164,6 +165,7 @@ variable {α β} in theorem prodUnique_apply [PartialOrder α] [Preorder β] [Unique β] (x : α ×ₗ β) : prodUnique α β x = (ofLex x).1 := rfl +set_option backward.isDefEq.respectTransparency false in /-- Lexicographic product type with `Unique` type on the left is `OrderIso` to the right. -/ def uniqueProd [Preorder α] [Unique α] [LE β] : α ×ₗ β ≃o β where toFun x := (ofLex x).2 diff --git a/Mathlib/Order/Hom/PowersetCard.lean b/Mathlib/Order/Hom/PowersetCard.lean index 4ebe7ddeb2b7b4..217cf1333e2c2a 100644 --- a/Mathlib/Order/Hom/PowersetCard.lean +++ b/Mathlib/Order/Hom/PowersetCard.lean @@ -32,6 +32,7 @@ section order variable {n : ℕ} {I : Type*} [LinearOrder I] +set_option backward.isDefEq.respectTransparency false in /-- The isomorphism of `OrderEmbedding`s from `Fin n` into `I` with `Set.powersetCard I n` when `I` is linearly ordered. -/ def ofFinEmbEquiv : (Fin n ↪o I) ≃ powersetCard I n where @@ -52,6 +53,7 @@ lemma mem_ofFinEmbEquiv_iff_mem_range (f : Fin n ↪o I) (i : I) : i ∈ ofFinEmbEquiv f ↔ i ∈ range f := by simp [ofFinEmbEquiv_apply] +set_option backward.isDefEq.respectTransparency false in lemma mem_range_ofFinEmbEquiv_symm_iff_mem (s : powersetCard I n) (i : I) : i ∈ range (ofFinEmbEquiv.symm s) ↔ i ∈ s := by simp [ofFinEmbEquiv_symm_apply] diff --git a/Mathlib/Order/Hom/Set.lean b/Mathlib/Order/Hom/Set.lean index f5ee2e213809b7..697e985d89be04 100644 --- a/Mathlib/Order/Hom/Set.lean +++ b/Mathlib/Order/Hom/Set.lean @@ -24,6 +24,7 @@ variable {α β γ : Type*} namespace Set +set_option backward.isDefEq.respectTransparency false in /-- Sets on sum types are order-equivalent to pairs of sets on each summand. -/ @[simps apply] def sumEquiv : Set (α ⊕ β) ≃o Set α × Set β where @@ -192,6 +193,7 @@ instance subsingleton_of_wellFoundedGT' [LinearOrder β] [WellFoundedGT β] [Pre instance unique_of_wellFoundedGT [LinearOrder α] [WellFoundedGT α] : Unique (α ≃o α) := Unique.mk' _ +set_option backward.isDefEq.respectTransparency false in /-- An order isomorphism between lattices induces an order isomorphism between corresponding interval sublattices. -/ protected def Iic [Lattice α] [Lattice β] (e : α ≃o β) (x : α) : @@ -202,6 +204,7 @@ protected def Iic [Lattice α] [Lattice β] (e : α ≃o β) (x : α) : right_inv y := by simp map_rel_iff' := by simp +set_option backward.isDefEq.respectTransparency false in /-- An order isomorphism between lattices induces an order isomorphism between corresponding interval sublattices. -/ protected def Ici [Lattice α] [Lattice β] (e : α ≃o β) (x : α) : @@ -212,6 +215,7 @@ protected def Ici [Lattice α] [Lattice β] (e : α ≃o β) (x : α) : right_inv y := by simp map_rel_iff' := by simp +set_option backward.isDefEq.respectTransparency false in /-- An order isomorphism between lattices induces an order isomorphism between corresponding interval sublattices. -/ protected def Icc [Lattice α] [Lattice β] (e : α ≃o β) (x y : α) : diff --git a/Mathlib/Order/Interval/Finset/Basic.lean b/Mathlib/Order/Interval/Finset/Basic.lean index 5e3c90433fdc34..5ace55c79a47d7 100644 --- a/Mathlib/Order/Interval/Finset/Basic.lean +++ b/Mathlib/Order/Interval/Finset/Basic.lean @@ -264,7 +264,7 @@ theorem Ioo_self : Ioo a a = ∅ := variable {a} /-- A set with upper and lower bounds in a locally finite order is a fintype -/ -@[implicit_reducible] +@[instance_reducible] def _root_.Set.fintypeOfMemBounds {s : Set α} [DecidablePred (· ∈ s)] (ha : a ∈ lowerBounds s) (hb : b ∈ upperBounds s) : Fintype s := Set.fintypeSubset (Set.Icc a b) fun _ hx => ⟨ha hx, hb hx⟩ diff --git a/Mathlib/Order/Interval/Finset/Defs.lean b/Mathlib/Order/Interval/Finset/Defs.lean index 6d15eb06998abd..85288571b4b9b3 100644 --- a/Mathlib/Order/Interval/Finset/Defs.lean +++ b/Mathlib/Order/Interval/Finset/Defs.lean @@ -169,7 +169,7 @@ class LocallyFiniteOrderBot (α : Type*) [Preorder α] where /-- A constructor from a definition of `Finset.Icc` alone, the other ones being derived by removing the ends. As opposed to `LocallyFiniteOrder.ofIcc`, this one requires `DecidableLE` but only `Preorder`. -/ -@[implicit_reducible] +@[instance_reducible] def LocallyFiniteOrder.ofIcc' (α : Type*) [Preorder α] [DecidableLE α] (finsetIcc : α → α → Finset α) (mem_Icc : ∀ a b x, x ∈ finsetIcc a b ↔ a ≤ x ∧ x ≤ b) : LocallyFiniteOrder α where @@ -186,7 +186,7 @@ def LocallyFiniteOrder.ofIcc' (α : Type*) [Preorder α] [DecidableLE α] /-- A constructor from a definition of `Finset.Icc` alone, the other ones being derived by removing the ends. As opposed to `LocallyFiniteOrder.ofIcc'`, this one requires `PartialOrder` but only `DecidableEq`. -/ -@[implicit_reducible] +@[instance_reducible] def LocallyFiniteOrder.ofIcc (α : Type*) [PartialOrder α] [DecidableEq α] (finsetIcc : α → α → Finset α) (mem_Icc : ∀ a b x, x ∈ finsetIcc a b ↔ a ≤ x ∧ x ≤ b) : LocallyFiniteOrder α where @@ -203,7 +203,7 @@ def LocallyFiniteOrder.ofIcc (α : Type*) [PartialOrder α] [DecidableEq α] /-- A constructor from a definition of `Finset.Ici` alone, the other ones being derived by removing the ends. As opposed to `LocallyFiniteOrderTop.ofIci`, this one requires `DecidableLE` but only `Preorder`. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- A constructor from a definition of `Finset.Iic` alone, the other ones being derived by removing the ends. As opposed to `LocallyFiniteOrderBot.ofIic`, this one requires `DecidableLE` but only `Preorder`. -/] @@ -218,7 +218,7 @@ def LocallyFiniteOrderTop.ofIci' (α : Type*) [Preorder α] [DecidableLE α] /-- A constructor from a definition of `Finset.Ici` alone, the other ones being derived by removing the ends. As opposed to `LocallyFiniteOrderTop.ofIci'`, this one requires `PartialOrder` but only `DecidableEq`. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- A constructor from a definition of `Finset.Iic` alone, the other ones being derived by removing the ends. As opposed to `LocallyFiniteOrderBot.ofIic'`, this one requires `PartialOrder` but only `DecidableEq`. -/] @@ -558,7 +558,7 @@ section Preorder variable [Preorder α] [Preorder β] /-- A noncomputable constructor from the finiteness of all closed intervals. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def LocallyFiniteOrder.ofFiniteIcc (h : ∀ a b : α, (Set.Icc a b).Finite) : LocallyFiniteOrder α := @LocallyFiniteOrder.ofIcc' α _ (Classical.decRel _) (fun a b => (h a b).toFinset) fun a b x => by @@ -615,7 +615,7 @@ instance : Subsingleton (LocallyFiniteOrderTop α) := -- Should this be called `LocallyFiniteOrder.lift`? /-- Given an order embedding `α ↪o β`, pulls back the `LocallyFiniteOrder` on `β` to `α`. -/ -@[implicit_reducible] +@[instance_reducible] protected noncomputable def OrderEmbedding.locallyFiniteOrder [LocallyFiniteOrder β] (f : α ↪o β) : LocallyFiniteOrder α where finsetIcc a b := (Icc (f a) (f b)).preimage f f.toEmbedding.injective.injOn diff --git a/Mathlib/Order/Interval/Finset/Fin.lean b/Mathlib/Order/Interval/Finset/Fin.lean index 9e0e5d705b0a65..83637368d55007 100644 --- a/Mathlib/Order/Interval/Finset/Fin.lean +++ b/Mathlib/Order/Interval/Finset/Fin.lean @@ -393,46 +393,55 @@ theorem finsetImage_cast_Iio (h : n = m) (i : Fin n) : ### `Finset.map` along `finCongr` -/ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Icc (h : n = m) (i j : Fin n) : (Icc i j).map (finCongr h).toEmbedding = Icc (i.cast h) (j.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Ico (h : n = m) (i j : Fin n) : (Ico i j).map (finCongr h).toEmbedding = Ico (i.cast h) (j.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Ioc (h : n = m) (i j : Fin n) : (Ioc i j).map (finCongr h).toEmbedding = Ioc (i.cast h) (j.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Ioo (h : n = m) (i j : Fin n) : (Ioo i j).map (finCongr h).toEmbedding = Ioo (i.cast h) (j.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_uIcc (h : n = m) (i j : Fin n) : (uIcc i j).map (finCongr h).toEmbedding = uIcc (i.cast h) (j.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Ici (h : n = m) (i : Fin n) : (Ici i).map (finCongr h).toEmbedding = Ici (i.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Ioi (h : n = m) (i : Fin n) : (Ioi i).map (finCongr h).toEmbedding = Ioi (i.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Iic (h : n = m) (i : Fin n) : (Iic i).map (finCongr h).toEmbedding = Iic (i.cast h) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_finCongr_Iio (h : n = m) (i : Fin n) : (Iio i).map (finCongr h).toEmbedding = Iio (i.cast h) := by @@ -577,35 +586,42 @@ theorem finsetImage_natAdd_Ioi (m) (i : Fin n) : (Ioi i).image (natAdd m) = Ioi ### `Finset.map` along `Fin.natAddEmb` -/ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_Icc (m) (i j : Fin n) : (Icc i j).map (natAddEmb m) = Icc (natAdd m i) (natAdd m j) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_Ico (m) (i j : Fin n) : (Ico i j).map (natAddEmb m) = Ico (natAdd m i) (natAdd m j) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_Ioc (m) (i j : Fin n) : (Ioc i j).map (natAddEmb m) = Ioc (natAdd m i) (natAdd m j) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_Ioo (m) (i j : Fin n) : (Ioo i j).map (natAddEmb m) = Ioo (natAdd m i) (natAdd m j) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_uIcc (m) (i j : Fin n) : (uIcc i j).map (natAddEmb m) = uIcc (natAdd m i) (natAdd m j) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_Ici (m) (i : Fin n) : (Ici i).map (natAddEmb m) = Ici (natAdd m i) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_natAddEmb_Ioi (m) (i : Fin n) : (Ioi i).map (natAddEmb m) = Ioi (natAdd m i) := by simp [← coe_inj] @@ -655,35 +671,42 @@ theorem finsetImage_addNat_Ioi (m) (i : Fin n) : (Ioi i).image (addNat · m) = I ### `Finset.map` along `Fin.addNatEmb` -/ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_Icc (m) (i j : Fin n) : (Icc i j).map (addNatEmb m) = Icc (i.addNat m) (j.addNat m) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_Ico (m) (i j : Fin n) : (Ico i j).map (addNatEmb m) = Ico (i.addNat m) (j.addNat m) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_Ioc (m) (i j : Fin n) : (Ioc i j).map (addNatEmb m) = Ioc (i.addNat m) (j.addNat m) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_Ioo (m) (i j : Fin n) : (Ioo i j).map (addNatEmb m) = Ioo (i.addNat m) (j.addNat m) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_uIcc (m) (i j : Fin n) : (uIcc i j).map (addNatEmb m) = uIcc (i.addNat m) (j.addNat m) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_Ici (m) (i : Fin n) : (Ici i).map (addNatEmb m) = Ici (i.addNat m) := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_addNatEmb_Ioi (m) (i : Fin n) : (Ioi i).map (addNatEmb m) = Ioi (i.addNat m) := by simp [← coe_inj] @@ -816,38 +839,47 @@ theorem finsetImage_rev_Iio (i : Fin n) : (Iio i).image rev = Ioi i.rev := by si ### `Finset.map` along `revPerm` -/ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Icc (i j : Fin n) : (Icc i j).map revPerm.toEmbedding = Icc j.rev i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Ico (i j : Fin n) : (Ico i j).map revPerm.toEmbedding = Ioc j.rev i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Ioc (i j : Fin n) : (Ioc i j).map revPerm.toEmbedding = Ico j.rev i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Ioo (i j : Fin n) : (Ioo i j).map revPerm.toEmbedding = Ioo j.rev i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_uIcc (i j : Fin n) : (uIcc i j).map revPerm.toEmbedding = uIcc i.rev j.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Ici (i : Fin n) : (Ici i).map revPerm.toEmbedding = Iic i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Ioi (i : Fin n) : (Ioi i).map revPerm.toEmbedding = Iio i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Iic (i : Fin n) : (Iic i).map revPerm.toEmbedding = Ici i.rev := by simp [← coe_inj] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_revPerm_Iio (i : Fin n) : (Iio i).map revPerm.toEmbedding = Ioi i.rev := by simp [← coe_inj] diff --git a/Mathlib/Order/Interval/Finset/Gaps.lean b/Mathlib/Order/Interval/Finset/Gaps.lean index 921d06491ca0b7..b08c7057fcf6e9 100644 --- a/Mathlib/Order/Interval/Finset/Gaps.lean +++ b/Mathlib/Order/Interval/Finset/Gaps.lean @@ -100,7 +100,7 @@ theorem intervalGapsWithin_mapsTo : (Set.Iio k).MapsTo intro j hj rw [mem_Iio] at hj simp only [intervalGapsWithin_snd_of_lt, intervalGapsWithin_succ_fst_of_lt, - Prod.mk.eta, SetLike.mem_coe, hj] + SetLike.mem_coe, hj] convert! F.orderEmbOfFin_mem h ⟨j, hj⟩ using 1 theorem intervalGapsWithin_injOn : (Set.Iio k).InjOn diff --git a/Mathlib/Order/Interval/Finset/Nat.lean b/Mathlib/Order/Interval/Finset/Nat.lean index 700ddec86f1b7e..1cd6946de1e635 100644 --- a/Mathlib/Order/Interval/Finset/Nat.lean +++ b/Mathlib/Order/Interval/Finset/Nat.lean @@ -30,6 +30,7 @@ variable (a b c : ℕ) namespace Nat +set_option backward.isDefEq.respectTransparency false in instance instLocallyFiniteOrder : LocallyFiniteOrder ℕ where finsetIcc a b := ⟨List.range' a (b + 1 - a), List.nodup_range'⟩ finsetIco a b := ⟨List.range' a (b - a), List.nodup_range'⟩ diff --git a/Mathlib/Order/Interval/Set/InitialSeg.lean b/Mathlib/Order/Interval/Set/InitialSeg.lean index 5c92457ef9835a..df412c57cd4758 100644 --- a/Mathlib/Order/Interval/Set/InitialSeg.lean +++ b/Mathlib/Order/Interval/Set/InitialSeg.lean @@ -20,6 +20,7 @@ namespace Set variable {α : Type*} [Preorder α] {i j : α} +set_option backward.isDefEq.respectTransparency false in /-- `Iic j` is an initial segment. -/ @[simps] def initialSegIic (j : α) : Iic j ≤i α where @@ -44,6 +45,7 @@ lemma principalSegIio_apply (k : Iio j) : principalSegIio j k = k.1 := @[deprecated (since := "2026-04-12")] alias principalSegIio_toRelEmbedding := principalSegIio_apply +set_option backward.isDefEq.respectTransparency false in /-- If `i ≤ j`, then `Iic i` is an initial segment of `Iic j`. -/ @[simps] def initialSegIicIicOfLE (h : i ≤ j) : Iic i ≤i Iic j where @@ -52,6 +54,7 @@ def initialSegIicIicOfLE (h : i ≤ j) : Iic i ≤i Iic j where map_rel_iff' := by aesop mem_range_of_rel' x k h := ⟨⟨k.1, (Subtype.coe_le_coe.2 h.le).trans x.2⟩, rfl⟩ +set_option backward.isDefEq.respectTransparency false in /-- If `i ≤ j`, then `Iio i` is a principal segment of `Iic j`. -/ @[simps top] def principalSegIioIicOfLE (h : i ≤ j) : Iio i simp [*, s.last_mem] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem snoc_eraseLast_last {s : CompositionSeries X} (h : IsMaximal s.eraseLast.last s.last) : s.eraseLast.snoc s.last h = s := @@ -409,6 +412,7 @@ theorem eq_of_head_eq_head_of_last_eq_last_of_length_eq_zero {s₁ s₂ : Compos ext simp [*] +set_option backward.isDefEq.respectTransparency false in /-- Given a `CompositionSeries`, `s`, and an element `x` such that `x` is maximal inside `s.last` there is a series, `t`, such that `t.last = x`, `t.head = s.head` diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index d556aec4547114..ebc60f5c915fb6 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -137,6 +137,7 @@ lemma coheight_le_iff {a : α} {n : ℕ∞} : coheight a ≤ n ↔ ∀ ⦃p : LTSeries α⦄, a ≤ p.head → p.length ≤ n := by rw [coheight_eq, iSup₂_le_iff] +set_option backward.isDefEq.respectTransparency false in lemma height_le {a : α} {n : ℕ∞} (h : ∀ (p : LTSeries α), p.last = a → p.length ≤ n) : height a ≤ n := by apply height_le_iff.mpr @@ -192,6 +193,7 @@ lemma coheight_le {a : α} {n : ℕ∞} (h : ∀ (p : LTSeries α), p.head = a coheight a ≤ n := coheight_le_iff'.mpr h +set_option backward.isDefEq.respectTransparency false in lemma length_le_height {p : LTSeries α} {x : α} (hlast : p.last ≤ x) : p.length ≤ height x := by by_cases hlen0 : p.length ≠ 0 @@ -1005,6 +1007,7 @@ lemma coheight_int (n : ℤ) : coheight n = ⊤ := coheight_of_noMaxOrder .. lemma krullDim_int : krullDim ℤ = ⊤ := krullDim_of_noMaxOrder .. +set_option backward.isDefEq.respectTransparency false in @[simp] lemma height_coe_withBot (x : α) : height (x : WithBot α) = height x + 1 := by apply le_antisymm · apply height_le diff --git a/Mathlib/Order/Lattice.lean b/Mathlib/Order/Lattice.lean index c2254941159d90..f700ba1a0d8ffa 100644 --- a/Mathlib/Order/Lattice.lean +++ b/Mathlib/Order/Lattice.lean @@ -100,7 +100,7 @@ join-semilattice. The partial order is defined so that `a ≤ b` unfolds to `a ⊔ b = b`; cf. `sup_eq_right`. -/ -@[implicit_reducible] +@[instance_reducible] def SemilatticeSup.mk' {α : Type*} [Max α] (sup_comm : ∀ a b : α, a ⊔ b = b ⊔ a) (sup_assoc : ∀ a b c : α, a ⊔ b ⊔ c = a ⊔ (b ⊔ c)) (sup_idem : ∀ a : α, a ⊔ a = a) : SemilatticeSup α where @@ -119,7 +119,7 @@ meet-semilattice. The partial order is defined so that `a ≤ b` unfolds to `b ⊓ a = a`; cf. `inf_eq_right`. -/ -@[implicit_reducible] +@[instance_reducible] def SemilatticeInf.mk' {α : Type*} [Min α] (inf_comm : ∀ a b : α, a ⊓ b = b ⊓ a) (inf_assoc : ∀ a b c : α, a ⊓ b ⊓ c = a ⊓ (b ⊓ c)) (inf_idem : ∀ a : α, a ⊓ a = a) : SemilatticeInf α where @@ -373,7 +373,7 @@ laws relating the two operations has the structure of a lattice. The partial order is defined so that `a ≤ b` unfolds to `a ⊔ b = b`; cf. `sup_eq_right`. -/ -@[implicit_reducible] +@[instance_reducible] def Lattice.mk' {α : Type*} [Max α] [Min α] (sup_comm : ∀ a b : α, a ⊔ b = b ⊔ a) (sup_assoc : ∀ a b c : α, a ⊔ b ⊔ c = a ⊔ (b ⊔ c)) (inf_comm : ∀ a b : α, a ⊓ b = b ⊓ a) (inf_assoc : ∀ a b c : α, a ⊓ b ⊓ c = a ⊓ (b ⊓ c)) (sup_inf_self : ∀ a b : α, a ⊔ a ⊓ b = a) diff --git a/Mathlib/Order/Lattice/Nat.lean b/Mathlib/Order/Lattice/Nat.lean index 1c215c142aa6ef..a16dcb6fe4b5cf 100644 --- a/Mathlib/Order/Lattice/Nat.lean +++ b/Mathlib/Order/Lattice/Nat.lean @@ -53,6 +53,7 @@ theorem sSup_of_not_bddAbove {s : Set ℕ} (h : ¬BddAbove s) : sSup s = 0 := lemma iSup_of_not_bddAbove {ι : Sort*} {f : ι → ℕ} (h : ¬ BddAbove (Set.range f)) : (⨆ i, f i : ℕ) = 0 := Nat.sSup_of_not_bddAbove h +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem sInf_eq_zero {s : Set ℕ} : sInf s = 0 ↔ 0 ∈ s ∨ s = ∅ := by cases eq_empty_or_nonempty s with diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index cdae22417057be..e8c6c6f0732f19 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -444,6 +444,7 @@ theorem bliminf_congr' {f : Filter β} {p q : β → Prop} {u : β → α} (h : ∀ᶠ x in f, u x ≠ ⊤ → (p x ↔ q x)) : bliminf u f p = bliminf u f q := blimsup_congr' (α := αᵒᵈ) h +set_option backward.isDefEq.respectTransparency false in lemma HasBasis.blimsup_eq_iInf_iSup {p : ι → Prop} {s : ι → Set β} {f : Filter β} {u : β → α} (hf : f.HasBasis p s) {q : β → Prop} : blimsup u f q = ⨅ (i) (_ : p i), ⨆ a ∈ s i, ⨆ (_ : q a), u a := by diff --git a/Mathlib/Order/ModularLattice.lean b/Mathlib/Order/ModularLattice.lean index 1173bc3a3f8e7e..26c414b0e8ba09 100644 --- a/Mathlib/Order/ModularLattice.lean +++ b/Mathlib/Order/ModularLattice.lean @@ -220,6 +220,7 @@ theorem wellFounded_gt_exact_sequence {β γ : Type*} [Preorder β] [Preorder γ wellFounded_lt_exact_sequence (α := αᵒᵈ) (β := γᵒᵈ) (γ := βᵒᵈ) K g₁ g₂ f₁ f₂ gi.dual gci.dual hg hf +set_option backward.isDefEq.respectTransparency false in /-- The diamond isomorphism between the closed intervals `[a ⊓ b, a]` and `[b, a ⊔ b]` -/ @[simps] def infIccOrderIsoIccSup (a b : α) : Icc (a ⊓ b) a ≃o Icc b (a ⊔ b) where @@ -243,6 +244,7 @@ def infIccOrderIsoIccSup (a b : α) : Icc (a ⊓ b) a ≃o Icc b (a ⊔ b) where sup_eq_right.2 y.prop.1, inf_sup_assoc_of_le _ y.prop.2, sup_comm b] exact inf_le_inf_left _ h +set_option backward.isDefEq.respectTransparency false in /-- The diamond isomorphism between the closed intervals `[a ⊓ b, b]` and `[a, a ⊔ b]` -/ @[simps!] def infIccOrderIsoIccSup' (a b : α) : Icc (a ⊓ b) b ≃o Icc a (a ⊔ b) := @@ -255,6 +257,7 @@ theorem inf_strictMonoOn_Icc_sup {a b : α} : StrictMonoOn (fun c => a ⊓ c) (I theorem sup_strictMonoOn_Icc_inf {a b : α} : StrictMonoOn (fun c => c ⊔ b) (Icc (a ⊓ b) a) := StrictMono.of_restrict (infIccOrderIsoIccSup a b).strictMono +set_option backward.isDefEq.respectTransparency false in /-- The diamond isomorphism between the open intervals `(a ⊓ b, a)` and `(b, a ⊔ b)`. -/ @[simps] def infIooOrderIsoIooSup (a b : α) : Ioo (a ⊓ b) a ≃o Ioo b (a ⊔ b) where @@ -280,6 +283,7 @@ def infIooOrderIsoIooSup (a b : α) : Ioo (a ⊓ b) a ≃o Ioo b (a ⊔ b) where @OrderIso.le_iff_le _ _ _ _ (infIccOrderIsoIccSup _ _) ⟨c.1, Ioo_subset_Icc_self c.2⟩ ⟨d.1, Ioo_subset_Icc_self d.2⟩ +set_option backward.isDefEq.respectTransparency false in /-- The diamond isomorphism between the open intervals `(a ⊓ b, b)` and `(a, a ⊔ b)`. -/ @[simps!] def infIooOrderIsoIooSup' (a b : α) : Ioo (a ⊓ b) b ≃o Ioo a (a ⊔ b) := diff --git a/Mathlib/Order/Monotone/Basic.lean b/Mathlib/Order/Monotone/Basic.lean index 28ca5109531328..6f5f7842929426 100644 --- a/Mathlib/Order/Monotone/Basic.lean +++ b/Mathlib/Order/Monotone/Basic.lean @@ -144,9 +144,11 @@ theorem monotone_dual_iff : Monotone (toDual ∘ f ∘ ofDual : αᵒᵈ → β theorem antitone_dual_iff : Antitone (toDual ∘ f ∘ ofDual : αᵒᵈ → βᵒᵈ) ↔ Antitone f := by rw [antitone_toDual_comp_iff, monotone_comp_ofDual_iff] +set_option backward.isDefEq.respectTransparency false in theorem monotoneOn_dual_iff : MonotoneOn (toDual ∘ f ∘ ofDual : αᵒᵈ → βᵒᵈ) s ↔ MonotoneOn f s := by rw [monotoneOn_toDual_comp_iff, antitoneOn_comp_ofDual_iff] +set_option backward.isDefEq.respectTransparency false in theorem antitoneOn_dual_iff : AntitoneOn (toDual ∘ f ∘ ofDual : αᵒᵈ → βᵒᵈ) s ↔ AntitoneOn f s := by rw [antitoneOn_toDual_comp_iff, monotoneOn_comp_ofDual_iff] @@ -156,10 +158,12 @@ theorem strictMono_dual_iff : StrictMono (toDual ∘ f ∘ ofDual : αᵒᵈ → theorem strictAnti_dual_iff : StrictAnti (toDual ∘ f ∘ ofDual : αᵒᵈ → βᵒᵈ) ↔ StrictAnti f := by rw [strictAnti_toDual_comp_iff, strictMono_comp_ofDual_iff] +set_option backward.isDefEq.respectTransparency false in theorem strictMonoOn_dual_iff : StrictMonoOn (toDual ∘ f ∘ ofDual : αᵒᵈ → βᵒᵈ) s ↔ StrictMonoOn f s := by rw [strictMonoOn_toDual_comp_iff, strictAntiOn_comp_ofDual_iff] +set_option backward.isDefEq.respectTransparency false in theorem strictAntiOn_dual_iff : StrictAntiOn (toDual ∘ f ∘ ofDual : αᵒᵈ → βᵒᵈ) s ↔ StrictAntiOn f s := by rw [strictAntiOn_toDual_comp_iff, strictMonoOn_comp_ofDual_iff] diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index d5913f103a73f3..f8d1f866cd8bf2 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -244,7 +244,7 @@ lemma ωSup_eq_of_isLUB {c : Chain α} {a : α} (h : IsLUB (Set.range c) a) : a /-- A subset `p : α → Prop` of the type closed under `ωSup` induces an `OmegaCompletePartialOrder` on the subtype `{a : α // p a}`. -/ -@[implicit_reducible] +@[instance_reducible] def subtype {α : Type*} [OmegaCompletePartialOrder α] (p : α → Prop) (hp : ∀ c : Chain α, (∀ i ∈ c, p i) → p (ωSup c)) : OmegaCompletePartialOrder (Subtype p) := OmegaCompletePartialOrder.lift (OrderHom.Subtype.val p) diff --git a/Mathlib/Order/OrderDual.lean b/Mathlib/Order/OrderDual.lean index 5526530a62c3c4..b54748e384550d 100644 --- a/Mathlib/Order/OrderDual.lean +++ b/Mathlib/Order/OrderDual.lean @@ -85,6 +85,7 @@ instance (α : Type*) [LT α] [h : DecidableLT α] : DecidableLT (αᵒᵈ) := instance (α : Type*) [LE α] [h : DecidableLE α] : DecidableLE (αᵒᵈ) := fun a b ↦ h b a +set_option backward.isDefEq.respectTransparency false in instance (α : Type*) [LinearOrder α] : LinearOrder αᵒᵈ where le_total a b := le_total (α := α) b a min_def := max_def' (α := α) @@ -99,7 +100,7 @@ instance (α : Type*) [LinearOrder α] : LinearOrder αᵒᵈ where set_option linter.style.setOption false in set_option backward.inferInstanceAs.wrap.reuseSubInstances false in -- otherwise we get an identity! /-- The opposite linear order to a given linear order -/ -@[implicit_reducible, deprecated "This declaration shouldn't have existed" (since := "2026-04-08")] +@[instance_reducible, deprecated "This declaration shouldn't have existed" (since := "2026-04-08")] def _root_.LinearOrder.swap (α : Type*) (_ : LinearOrder α) : LinearOrder α := inferInstanceAs <| LinearOrder (OrderDual α) diff --git a/Mathlib/Order/OrderIsoNat.lean b/Mathlib/Order/OrderIsoNat.lean index 3c1aefd5c22cd3..51c1dcdaa3349b 100644 --- a/Mathlib/Order/OrderIsoNat.lean +++ b/Mathlib/Order/OrderIsoNat.lean @@ -121,6 +121,7 @@ theorem orderEmbeddingOfSet_apply [DecidablePred (· ∈ s)] {n : ℕ} : orderEmbeddingOfSet s n = Subtype.ofNat s n := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem Subtype.orderIsoOfNat_apply [dP : DecidablePred (· ∈ s)] {n : ℕ} : Subtype.orderIsoOfNat s n = Subtype.ofNat s n := by diff --git a/Mathlib/Order/PartialSups.lean b/Mathlib/Order/PartialSups.lean index 817e11e1524383..a0efb70ce9a1f0 100644 --- a/Mathlib/Order/PartialSups.lean +++ b/Mathlib/Order/PartialSups.lean @@ -131,6 +131,7 @@ protected lemma Pi.partialSups_apply {τ : Type*} {π : τ → Type*} [∀ t, Se partialSups f i t = partialSups (f · t) i := by simp only [partialSups_apply, Finset.sup'_apply] +set_option backward.isDefEq.respectTransparency false in lemma comp_partialSups {F : Type*} [FunLike F α β] [SupHomClass F α β] (f : ι → α) (g : F) : partialSups (g ∘ f) = g ∘ partialSups f := by funext _; simp [partialSups] diff --git a/Mathlib/Order/Partition/Finpartition.lean b/Mathlib/Order/Partition/Finpartition.lean index 5cd94e49929259..cdb5395c257e88 100644 --- a/Mathlib/Order/Partition/Finpartition.lean +++ b/Mathlib/Order/Partition/Finpartition.lean @@ -751,6 +751,7 @@ def equivSigmaParts : s ≃ Σ t : P.parts, t.1 where rw [P.part_eq_of_mem mp mf] · simp +set_option backward.isDefEq.respectTransparency false in lemma exists_enumeration : ∃ f : s ≃ Σ t : P.parts, Fin #t.1, ∀ a b : s, P.part a = P.part b ↔ (f a).1 = (f b).1 := by use P.equivSigmaParts.trans ((Equiv.refl _).sigmaCongr (fun t ↦ t.1.equivFin)) diff --git a/Mathlib/Order/PiLex.lean b/Mathlib/Order/PiLex.lean index 225f65c937542d..1d2a72aece1d7e 100644 --- a/Mathlib/Order/PiLex.lean +++ b/Mathlib/Order/PiLex.lean @@ -75,7 +75,7 @@ theorem trichotomous_lex [∀ i, Std.Trichotomous (α := β i) s] (wf : WellFoun by_contra! h rw [Function.ne_iff] at h let i := wf.min {i | a i ≠ b i} h - have hri j (hr : r j i) : a j = b j := not_not.mp (wf.not_lt_min _ · hr) + have hri j (hr : r j i) : a j = b j := not_not.mp (fun h => wf.not_lt_min _ (by grind) hr) have := Std.Trichotomous.trichotomous (a i) (b i) (hab ⟨i, hri, ·⟩) exact hba ⟨i, (hri · · |>.symm), Not.imp_symm this <| wf.min_mem {i | a i ≠ b i} h⟩ } @@ -120,6 +120,7 @@ instance Lex.isStrictOrder [LinearOrder ι] [∀ a, PartialOrder (β a)] : ⟨N₁, fun j hj => (lt_N₁ _ hj).trans (lt_N₂ _ hj), a_lt_b.trans b_lt_c⟩, ⟨N₂, fun j hj => (lt_N₁ _ (hj.trans H)).trans (lt_N₂ _ hj), (lt_N₁ _ H).symm ▸ b_lt_c⟩] +set_option backward.isDefEq.respectTransparency.types false in instance Colex.isStrictOrder [LinearOrder ι] [∀ a, PartialOrder (β a)] : IsStrictOrder (Colex (∀ i, β i)) (· < ·) := Lex.isStrictOrder (ι := ιᵒᵈ) @@ -136,6 +137,7 @@ noncomputable instance Lex.linearOrder [LinearOrder ι] [WellFoundedLT ι] @linearOrderOfSTO (Πₗ i, β i) (· < ·) { trichotomous := (trichotomous_lex _ _ IsWellFounded.wf).1 } (Classical.decRel _) +set_option backward.isDefEq.respectTransparency.types false in /-- `Colex (∀ i, α i)` is a linear order if the original order has well-founded `>`. -/ noncomputable instance Colex.linearOrder [LinearOrder ι] [WellFoundedGT ι] [∀ a, LinearOrder (β a)] : LinearOrder (Colex (∀ i, β i)) := @@ -213,24 +215,30 @@ end Lex section Colex variable [WellFoundedGT ι] +set_option backward.isDefEq.respectTransparency.types false in theorem toColex_monotone : Monotone (@toColex (∀ i, β i)) := toLex_monotone (ι := ιᵒᵈ) +set_option backward.isDefEq.respectTransparency.types false in theorem toColex_strictMono : StrictMono (@toColex (∀ i, β i)) := toLex_strictMono (ι := ιᵒᵈ) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem lt_toColex_update_self_iff : toColex x < toColex (update x i a) ↔ x i < a := lt_toLex_update_self_iff (ι := ιᵒᵈ) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toColex_update_lt_self_iff : toColex (update x i a) < toColex x ↔ a < x i := toLex_update_lt_self_iff (ι := ιᵒᵈ) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem le_toColex_update_self_iff : toColex x ≤ toColex (update x i a) ↔ x i ≤ a := le_toLex_update_self_iff (ι := ιᵒᵈ) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toColex_update_le_self_iff : toColex (update x i a) ≤ toColex x ↔ a ≤ x i := toLex_update_le_self_iff (ι := ιᵒᵈ) @@ -290,6 +298,7 @@ instance [LinearOrder ι] [WellFoundedLT ι] [∀ a, PartialOrder (β a)] instance [LinearOrder ι] [WellFoundedGT ι] [∀ a, PartialOrder (β a)] [∀ a, BoundedOrder (β a)] : BoundedOrder (Colex (∀ a, β a)) where +set_option backward.isDefEq.respectTransparency.types false in instance [Preorder ι] [∀ i, LT (β i)] [∀ i, DenselyOrdered (β i)] : DenselyOrdered (Lex (∀ i, β i)) := ⟨by @@ -304,10 +313,12 @@ instance [Preorder ι] [∀ i, LT (β i)] [∀ i, DenselyOrdered (β i)] : · rw [Function.update_of_ne hj.ne a] · rwa [Function.update_self i a]⟩ +set_option backward.isDefEq.respectTransparency.types false in instance [Preorder ι] [∀ i, LT (β i)] [∀ i, DenselyOrdered (β i)] : DenselyOrdered (Colex (∀ i, β i)) := inferInstanceAs (DenselyOrdered (Lex (∀ i : ιᵒᵈ, β (OrderDual.toDual i)))) +set_option backward.isDefEq.respectTransparency.types false in theorem Lex.noMaxOrder' [Preorder ι] [∀ i, LT (β i)] (i : ι) [NoMaxOrder (β i)] : NoMaxOrder (Lex (∀ i, β i)) := ⟨fun a => by @@ -316,6 +327,7 @@ theorem Lex.noMaxOrder' [Preorder ι] [∀ i, LT (β i)] (i : ι) [NoMaxOrder ( exact ⟨Function.update a i b, i, fun j hj => (Function.update_of_ne hj.ne b a).symm, by rwa [Function.update_self i b]⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem Colex.noMaxOrder' [Preorder ι] [∀ i, LT (β i)] (i : ι) [NoMaxOrder (β i)] : NoMaxOrder (Colex (∀ i, β i)) := Lex.noMaxOrder' (ι := ιᵒᵈ) i @@ -326,6 +338,7 @@ instance [LinearOrder ι] [WellFoundedLT ι] [Nonempty ι] [∀ i, PartialOrder let ⟨_, hb⟩ := exists_gt (ofLex a) ⟨_, toLex_strictMono hb⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in instance [LinearOrder ι] [WellFoundedGT ι] [Nonempty ι] [∀ i, PartialOrder (β i)] [∀ i, NoMaxOrder (β i)] : NoMaxOrder (Colex (∀ i, β i)) := inferInstanceAs (NoMaxOrder (Lex (∀ i : ιᵒᵈ, β (OrderDual.toDual i)))) @@ -336,6 +349,7 @@ instance [LinearOrder ι] [WellFoundedLT ι] [Nonempty ι] [∀ i, PartialOrder let ⟨_, hb⟩ := exists_lt (ofLex a) ⟨_, toLex_strictMono hb⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in instance [LinearOrder ι] [WellFoundedGT ι] [Nonempty ι] [∀ i, PartialOrder (β i)] [∀ i, NoMinOrder (β i)] : NoMinOrder (Colex (∀ i, β i)) := inferInstanceAs (NoMinOrder (Lex (∀ i : ιᵒᵈ, β (OrderDual.toDual i)))) diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index 6df98882f1c222..ffdfdd4ad82556 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -312,7 +312,7 @@ theorem fix_eq {motive : α → Sort*} (ind : ∀ x : α, (∀ y : α, y < x → IsWellFounded.fix_eq _ ind /-- Derive a `WellFoundedRelation` instance from a `WellFoundedLT` instance. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- Derive a `WellFoundedRelation` instance from a `WellFoundedGT` instance. -/] def toWellFoundedRelation : WellFoundedRelation α := IsWellFounded.toWellFoundedRelation (· < ·) @@ -321,7 +321,7 @@ end WellFoundedLT open scoped Classical in /-- Construct a decidable linear order from a well-founded linear order. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def IsWellOrder.linearOrder (r : α → α → Prop) [IsWellOrder α r] : LinearOrder α := linearOrderOfSTO r diff --git a/Mathlib/Order/RelSeries.lean b/Mathlib/Order/RelSeries.lean index 8feefa3b54c09a..81e19339502fb4 100644 --- a/Mathlib/Order/RelSeries.lean +++ b/Mathlib/Order/RelSeries.lean @@ -120,6 +120,7 @@ def fromListIsChain (x : List α) (x_ne_nil : x ≠ []) (hx : x.IsChain (· ~[r] toFun i := x[Fin.cast (Nat.succ_pred_eq_of_pos <| List.length_pos_iff.mpr x_ne_nil) i] step i := List.isChain_iff_getElem.mp hx i _ +set_option backward.isDefEq.respectTransparency false in /-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively corresponds to each other. -/ protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.IsChain (· ~[r] ·)} where @@ -263,6 +264,7 @@ lemma toList_fromListIsChain (l : List α) (l_ne_nil : l ≠ []) (hl : l.IsChain (fromListIsChain l l_ne_nil hl).toList = l := Subtype.ext_iff.mp <| RelSeries.Equiv.right_inv ⟨l, ⟨l_ne_nil, hl⟩⟩ +set_option backward.isDefEq.respectTransparency false in @[simp] lemma head_fromListIsChain (l : List α) (l_ne_nil : l ≠ []) (hl : l.IsChain (· ~[r] ·)) : (fromListIsChain l l_ne_nil hl).head = l.head l_ne_nil := by @@ -333,6 +335,7 @@ lemma append_apply_right (p q : RelSeries r) (connect : p.last ~[r] q.head) append_apply_left p q connect 0 set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma last_append (p q : RelSeries r) (connect : p.last ~[r] q.head) : (p.append q connect).last = q.last := by delta last @@ -341,6 +344,7 @@ set_option backward.defeqAttrib.useBackward true in dsimp lia +set_option backward.isDefEq.respectTransparency false in lemma append_assoc (p q w : RelSeries r) (hpq : p.last ~[r] q.head) (hqw : q.last ~[r] w.head) : (p.append q hpq).append w (by simpa) = p.append (q.append w hqw) (by simpa) := by ext @@ -349,6 +353,7 @@ lemma append_assoc (p q w : RelSeries r) (hpq : p.last ~[r] q.head) (hqw : q.las · simp [append, Fin.append_assoc] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma toList_append (p q : RelSeries r) (connect : p.last ~[r] q.head) : (p.append q connect).toList = p.toList ++ q.toList := by @@ -373,6 +378,7 @@ def map (p : RelSeries r) (f : r.Hom s) : RelSeries s where @[simp] lemma last_map (p : RelSeries r) (f : r.Hom s) : (p.map f).last = f p.last := rfl +set_option backward.isDefEq.respectTransparency false in /-- If `a₀ -r→ a₁ -r→ ... -r→ aₙ` is an `r`-series and `a` is such that `aᵢ -r→ a -r→ a_ᵢ₊₁`, then @@ -461,6 +467,7 @@ set_option backward.isDefEq.respectTransparency false in simp [RelSeries.last, RelSeries.head] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma reverse_reverse {r : SetRel α α} (p : RelSeries r) : p.reverse.reverse = p := by ext <;> simp @@ -475,11 +482,13 @@ def cons (p : RelSeries r) (newHead : α) (rel : newHead ~[r] p.head) : RelSerie @[simp] lemma head_cons (p : RelSeries r) (newHead : α) (rel : newHead ~[r] p.head) : (p.cons newHead rel).head = newHead := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma last_cons (p : RelSeries r) (newHead : α) (rel : newHead ~[r] p.head) : (p.cons newHead rel).last = p.last := by delta cons rw [last_append] +set_option backward.isDefEq.respectTransparency false in lemma cons_cast_succ (s : RelSeries r) (a : α) (h : a ~[r] s.head) (i : Fin (s.length + 1)) : (s.cons a h) (.cast (by simp) (.succ i)) = s i := by simp [cons, Fin.append, Fin.addCases, Fin.subNat] @@ -489,6 +498,7 @@ lemma append_singleton_left (p : RelSeries r) (x : α) (hx : x ~[r] p.head) : (singleton r x).append p hx = p.cons x hx := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma toList_cons (p : RelSeries r) (x : α) (hx : x ~[r] p.head) : (p.cons x hx).toList = x :: p.toList := by @@ -502,6 +512,7 @@ lemma fromListIsChain_cons (l : List α) (l_ne_nil : l ≠ []) apply toList_injective simp +set_option backward.isDefEq.respectTransparency false in lemma append_cons {p q : RelSeries r} {x : α} (hx : x ~[r] p.head) (hq : p.last ~[r] q.head) : (p.cons x hx).append q (by simpa) = (p.append q hq).cons x (by simpa) := by simp only [cons] @@ -515,6 +526,7 @@ a series of length `n+1`: `a₀ -r→ a₁ -r→ ... -r→ aₙ -r→ a`. def snoc (p : RelSeries r) (newLast : α) (rel : p.last ~[r] newLast) : RelSeries r := p.append (singleton r newLast) rel +set_option backward.isDefEq.respectTransparency false in @[simp] lemma head_snoc (p : RelSeries r) (newLast : α) (rel : p.last ~[r] newLast) : (p.snoc newLast rel).head = p.head := by delta snoc; rw [head_append] @@ -536,6 +548,7 @@ lemma snoc_cast_castSucc (s : RelSeries r) (a : α) (h : s.last ~[r] a) (i : Fin (i : Fin (s.length + 1)) : snoc s a connect (Fin.castSucc i) = s i := Fin.append_left _ _ i +set_option backward.isDefEq.respectTransparency false in lemma mem_snoc {p : RelSeries r} {newLast : α} {rel : p.last ~[r] newLast} {x : α} : x ∈ p.snoc newLast rel ↔ x ∈ p ∨ x = newLast := by simp only [snoc, append, mem_def, Set.mem_range] @@ -571,10 +584,11 @@ def tail (p : RelSeries r) (len_pos : p.length ≠ 0) : RelSeries r where change p _ = p _ congr ext - simp only [tail_length, Fin.val_succ, Fin.val_cast, Fin.val_last] + simp only [Fin.val_succ, Fin.val_last] exact Nat.succ_pred_eq_of_pos (by simpa [Nat.pos_iff_ne_zero] using len_pos) set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma toList_tail {p : RelSeries r} (hp : p.length ≠ 0) : (p.tail hp).toList = p.toList.tail := by refine List.ext_getElem ?_ fun i h1 h2 ↦ ?_ @@ -593,6 +607,7 @@ lemma cons_self_tail {p : RelSeries r} (hp : p.length ≠ 0) : apply toList_injective simp [← head_toList] +set_option backward.isDefEq.respectTransparency false in /-- To show a proposition `p` for `xs : RelSeries r` it suffices to show it for all singletons and to show that when `p` holds for `xs` it also holds for `xs` prepended with one element. @@ -622,6 +637,7 @@ def inductionOn (motive : RelSeries r → Sort*) exact (p.cons_self_tail (heq ▸ d.zero_ne_add_one.symm)).symm exact this rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma toList_snoc (p : RelSeries r) (newLast : α) (rel : p.last ~[r] newLast) : (p.snoc newLast rel).toList = p.toList ++ [newLast] := by @@ -641,6 +657,7 @@ def eraseLast (p : RelSeries r) : RelSeries r where @[simp] lemma last_eraseLast (p : RelSeries r) : p.eraseLast.last = p ⟨p.length.pred, Nat.lt_succ_iff.2 (Nat.pred_le _)⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- In a non-trivial series `p`, the last element of `p.eraseLast` is related to `p.last` -/ lemma eraseLast_last_rel_last (p : RelSeries r) (h : p.length ≠ 0) : p.eraseLast.last ~[r] p.last := by @@ -648,6 +665,7 @@ lemma eraseLast_last_rel_last (p : RelSeries r) (h : p.length ≠ 0) : convert! p.step ⟨p.length - 1, by lia⟩ simp only [Fin.succ_mk]; lia +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toList_eraseLast (p : RelSeries r) (hp : p.length ≠ 0) : p.eraseLast.toList = p.toList.dropLast := by @@ -661,6 +679,7 @@ lemma snoc_self_eraseLast (p : RelSeries r) (h : p.length ≠ 0) : apply toList_injective rw [toList_snoc, ← getLast_toList, toList_eraseLast _ h, List.dropLast_append_getLast] +set_option backward.isDefEq.respectTransparency false in /-- To show a proposition `p` for `xs : RelSeries r` it suffices to show it for all singletons and to show that when `p` holds for `xs` it also holds for `xs` appended with one element. @@ -903,6 +922,7 @@ def mk (length : ℕ) (toFun : Fin (length + 1) → α) (strictMono : StrictMono step i := strictMono <| lt_add_one i.1 set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- An injection from the type of strictly monotone functions with limited length to `LTSeries`. -/ def injStrictMono (n : ℕ) : {f : (l : Fin n) × (Fin (l + 1) → α) // StrictMono f.2} ↪ LTSeries α where @@ -992,6 +1012,7 @@ theorem exists_relSeries_covBy simp [RelSeries.smash_castLE] all_goals simp [Fin.snoc, Fin.castPred_zero, hi₁] +set_option backward.isDefEq.respectTransparency false in theorem exists_relSeries_covBy_and_head_eq_bot_and_last_eq_bot {α} [PartialOrder α] [BoundedOrder α] [WellFoundedLT α] [WellFoundedGT α] (s : LTSeries α) : ∃ (t : RelSeries {(a, b) : α × α | a ⋖ b}) (i : Fin (s.length + 1) ↪ Fin (t.length + 1)), diff --git a/Mathlib/Order/SetDissipate.lean b/Mathlib/Order/SetDissipate.lean index e163c53144fcf5..29453d4a84db2b 100644 --- a/Mathlib/Order/SetDissipate.lean +++ b/Mathlib/Order/SetDissipate.lean @@ -74,8 +74,6 @@ lemma dissipate_bot [PartialOrder α] [OrderBot α] (s : α → Set β) : dissip lemma dissipate_zero_nat (s : ℕ → Set β) : dissipate s 0 = s 0 := by simp [dissipate_def] -open Nat - @[simp] theorem dissipate_succ (s : ℕ → Set α) (n : ℕ) : dissipate s (n + 1) = (dissipate s n) ∩ s (n + 1) := by diff --git a/Mathlib/Order/Sublocale.lean b/Mathlib/Order/Sublocale.lean index 584be74fce998a..02ae6cdf9f8cc3 100644 --- a/Mathlib/Order/Sublocale.lean +++ b/Mathlib/Order/Sublocale.lean @@ -121,6 +121,7 @@ private def restrictAux (S : Sublocale X) (a : X) : S := sInf {s : S | a ≤ s} private lemma le_restrictAux : a ≤ S.restrictAux a := by simp +contextual [restrictAux] +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in /-- See `Sublocale.giRestrict` for the public-facing version. -/ private def giAux (S : Sublocale X) : GaloisInsertion S.restrictAux Subtype.val where @@ -214,6 +215,7 @@ lemma mem_toSublocale {n : Nucleus X} {x : X} : x ∈ n.toSublocale ↔ ∃ y, n end Nucleus +set_option backward.isDefEq.respectTransparency false in /-- The nuclei on a frame corresponds exactly to the sublocales on this frame. The sublocales are ordered dually to the nuclei. -/ def nucleusIsoSublocale : (Nucleus X)ᵒᵈ ≃o Sublocale X where @@ -230,6 +232,7 @@ lemma nucleusIsoSublocale.symm_eq_toNucleus : instance Sublocale.instCompleteLattice : CompleteLattice (Sublocale X) := nucleusIsoSublocale.toGaloisInsertion.liftCompleteLattice +set_option backward.isDefEq.respectTransparency false in instance Sublocale.instCoframeMinimalAxioms : Order.Coframe.MinimalAxioms (Sublocale X) where iInf_sup_le_sup_sInf a s := by simp [← toNucleus_le_toNucleus, nucleusIsoSublocale.symm_eq_toNucleus, nucleusIsoSublocale.symm.map_sup, diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 0a973b0fb5742a..169c6c0dcfdd70 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -81,7 +81,7 @@ section Preorder variable [Preorder α] /-- A constructor for `SuccOrder α` usable when `α` has no maximal element. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- A constructor for `PredOrder α` usable when `α` has no minimal element. -/] def SuccOrder.ofSuccLeIff (succ : α → α) (hsucc_le_iff : ∀ {a b}, succ a ≤ b ↔ a < b) : SuccOrder α where @@ -97,7 +97,7 @@ section LinearOrder variable [LinearOrder α] /-- A constructor for `SuccOrder α` for `α` a linear order. -/ -@[to_dual (attr := simps, implicit_reducible) +@[to_dual (attr := simps, instance_reducible) /-- A constructor for `PredOrder α` for `α` a linear order. -/] def SuccOrder.ofCore (succ : α → α) (hn : ∀ {a}, ¬IsMax a → ∀ b, a < b ↔ succ a ≤ b) (hm : ∀ a, IsMax a → succ a = a) : SuccOrder α where @@ -108,9 +108,10 @@ def SuccOrder.ofCore (succ : α → α) (hn : ∀ {a}, ¬IsMax a → ∀ b, a < variable (α) +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- A well-order is a `SuccOrder`. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- A linear order with well-founded greater-than relation is a `PredOrder`. -/] noncomputable def SuccOrder.ofLinearWellFoundedLT [WellFoundedLT α] : SuccOrder α := ofCore (fun a ↦ if h : (Ioi a).Nonempty then wellFounded_lt.min _ h else a) @@ -893,12 +894,14 @@ noncomputable instance Set.OrdConnected.succOrder [SuccOrder α] : letI : PredOrder sᵒᵈ := inferInstanceAs (PredOrder (OrderDual.ofDual ⁻¹' s)) inferInstanceAs (SuccOrder sᵒᵈᵒᵈ) +set_option backward.isDefEq.respectTransparency false in @[simp, norm_cast] lemma coe_succ_of_mem [SuccOrder α] {a : s} (h : succ ↑a ∈ s) : (succ a).1 = succ ↑a := by classical change Subtype.val (dite ..) = _ split_ifs <;> trivial +set_option backward.isDefEq.respectTransparency false in lemma isMax_of_succ_notMem [SuccOrder α] {a : s} (h : succ ↑a ∉ s) : IsMax a := by classical rw [← succ_eq_iff_isMax] diff --git a/Mathlib/Order/SuccPred/CompleteLinearOrder.lean b/Mathlib/Order/SuccPred/CompleteLinearOrder.lean index 10c2c2e1f76a4b..a795a20ac12fef 100644 --- a/Mathlib/Order/SuccPred/CompleteLinearOrder.lean +++ b/Mathlib/Order/SuccPred/CompleteLinearOrder.lean @@ -81,7 +81,7 @@ lemma IsGLB.exists_of_nonempty_of_not_isPredPrelimit /-- Every conditionally complete linear order with well-founded `<` is a successor order, by setting the successor of an element to be the infimum of all larger elements. -/ -@[implicit_reducible, deprecated SuccOrder.ofLinearWellFoundedLT (since := "2026-04-12")] +@[instance_reducible, deprecated SuccOrder.ofLinearWellFoundedLT (since := "2026-04-12")] noncomputable def ConditionallyCompleteLinearOrder.toSuccOrder [WellFoundedLT α] : SuccOrder α := .ofLinearWellFoundedLT _ diff --git a/Mathlib/Order/SuccPred/LinearLocallyFinite.lean b/Mathlib/Order/SuccPred/LinearLocallyFinite.lean index c4ff141f244e3d..20c07a049918b8 100644 --- a/Mathlib/Order/SuccPred/LinearLocallyFinite.lean +++ b/Mathlib/Order/SuccPred/LinearLocallyFinite.lean @@ -148,7 +148,7 @@ variable (ι) in /-- A locally finite order is a `SuccOrder`. This is not an instance, because its `succ` field conflicts with computable `SuccOrder` structures on `ℕ` and `ℤ`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def succOrder [LocallyFiniteOrder ι] : SuccOrder ι where succ := succFn le_succ := le_succFn @@ -159,7 +159,7 @@ variable (ι) in /-- A locally finite order is a `PredOrder`. This is not an instance, because its `succ` field conflicts with computable `PredOrder` structures on `ℕ` and `ℤ`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def predOrder [LocallyFiniteOrder ι] : PredOrder ι := letI := succOrder (ι := ιᵒᵈ) inferInstanceAs (PredOrder ιᵒᵈᵒᵈ) @@ -339,6 +339,7 @@ section OrderIso variable [SuccOrder ι] [PredOrder ι] [IsSuccArchimedean ι] +set_option backward.isDefEq.respectTransparency.types false in /-- `toZ` defines an `OrderIso` between `ι` and its range. -/ noncomputable def orderIsoRangeToZOfLinearSuccPredArch [hι : Nonempty ι] : ι ≃o Set.range (toZ hι.some) where @@ -350,6 +351,7 @@ instance (priority := 100) countable_of_linear_succ_pred_arch : Countable ι := · infer_instance · exact Countable.of_equiv _ orderIsoRangeToZOfLinearSuccPredArch.symm.toEquiv +set_option backward.isDefEq.respectTransparency.types false in /-- If the order has neither bot nor top, `toZ` defines an `OrderIso` between `ι` and `ℤ`. -/ noncomputable def orderIsoIntOfLinearSuccPredArch [NoMaxOrder ι] [NoMinOrder ι] [hι : Nonempty ι] : ι ≃o ℤ where @@ -373,6 +375,7 @@ noncomputable def orderIsoIntOfLinearSuccPredArch [NoMaxOrder ι] [NoMinOrder ι simp only [hn.le, Int.toNat_of_nonneg, Int.neg_nonneg_of_nonpos, Int.neg_neg] map_rel_iff' := by simp +set_option backward.isDefEq.respectTransparency false in /-- If the order has a bot but no top, `toZ` defines an `OrderIso` between `ι` and `ℕ`. -/ def orderIsoNatOfLinearSuccPredArch [NoMaxOrder ι] [OrderBot ι] : ι ≃o ℕ where toFun i := (toZ ⊥ i).toNat @@ -389,6 +392,7 @@ def orderIsoNatOfLinearSuccPredArch [NoMaxOrder ι] [OrderBot ι] : ι ≃o ℕ simp only [Equiv.coe_fn_mk, Int.toNat_le] rw [← toZ_le_toZ (i0 := (⊥ : ι)), Int.toNat_of_nonneg (toZ_nonneg bot_le)] +set_option backward.isDefEq.respectTransparency false in /-- If the order has both a bot and a top, `toZ` gives an `OrderIso` between `ι` and `Finset.range n` for some `n`. -/ def orderIsoRangeOfLinearSuccPredArch [OrderBot ι] [OrderTop ι] : diff --git a/Mathlib/Order/SupClosed.lean b/Mathlib/Order/SupClosed.lean index 2502a90f5c994e..9b61fd1be774f6 100644 --- a/Mathlib/Order/SupClosed.lean +++ b/Mathlib/Order/SupClosed.lean @@ -359,6 +359,7 @@ lemma image_latticeClosure (s : Set α) (f : α → β) · rintro _ - _ - ⟨a, ha, rfl⟩ ⟨b, hb, rfl⟩ exact ⟨a ⊓ b, isSublattice_latticeClosure.infClosed ha hb, map_inf ..⟩ +set_option backward.isDefEq.respectTransparency false in lemma ofDual_preimage_latticeClosure (s : Set α) : ofDual ⁻¹' latticeClosure s = latticeClosure (ofDual ⁻¹' s) := by ext @@ -400,7 +401,7 @@ end DistribLattice /-- A join-semilattice where every sup-closed set has a least upper bound is automatically complete. -/ -@[to_dual (attr := implicit_reducible) /-- +@[to_dual (attr := instance_reducible) /-- A meet-semilattice where every inf-closed set has a greatest lower bound is automatically complete. -/] def SemilatticeSup.toCompleteSemilatticeSup [SemilatticeSup α] (sSup : Set α → α) diff --git a/Mathlib/Order/Types/Defs.lean b/Mathlib/Order/Types/Defs.lean index f0e7316273439b..1e46789757f661 100644 --- a/Mathlib/Order/Types/Defs.lean +++ b/Mathlib/Order/Types/Defs.lean @@ -49,7 +49,7 @@ variable {α β : Type u} [LinearOrder α] [LinearOrder β] {δ : Sort v} /-- Equivalence relation on linear orders on arbitrary types in universe `u`, given by order isomorphism. -/ -@[implicit_reducible] +@[instance_reducible] def OrderType.instSetoid : Setoid LinOrd where r := fun lin_ord₁ lin_ord₂ ↦ Nonempty (lin_ord₁ ≃o lin_ord₂) iseqv := ⟨fun _ ↦ ⟨.refl _⟩, fun ⟨e⟩ ↦ ⟨e.symm⟩, fun ⟨e₁⟩ ⟨e₂⟩ ↦ ⟨e₁.trans e₂⟩⟩ diff --git a/Mathlib/Order/UpperLower/Closure.lean b/Mathlib/Order/UpperLower/Closure.lean index 3e8ab41c0077bc..7f860e316b7797 100644 --- a/Mathlib/Order/UpperLower/Closure.lean +++ b/Mathlib/Order/UpperLower/Closure.lean @@ -193,7 +193,7 @@ variable [PartialOrder α] {s : Set α} {x : α} lemma IsAntichain.minimal_mem_upperClosure_iff_mem (hs : IsAntichain (· ≤ ·) s) : Minimal (· ∈ upperClosure s) x ↔ x ∈ s := by - simp only [upperClosure, UpperSet.mem_mk, mem_setOf_eq] + simp only [upperClosure] refine ⟨fun h ↦ ?_, fun h ↦ ⟨⟨x, h, rfl.le⟩, fun b ⟨a, has, hab⟩ hbx ↦ ?_⟩⟩ · obtain ⟨a, has, hax⟩ := h.prop rwa [h.eq_of_ge ⟨a, has, rfl.le⟩ hax] diff --git a/Mathlib/Order/UpperLower/CompleteLattice.lean b/Mathlib/Order/UpperLower/CompleteLattice.lean index d5cd26deb4789c..1c0cbbbe629193 100644 --- a/Mathlib/Order/UpperLower/CompleteLattice.lean +++ b/Mathlib/Order/UpperLower/CompleteLattice.lean @@ -341,6 +341,7 @@ theorem coe_map_apply (f : α ≃o β) (s : UpperSet α) : map f s = f '' s := r @[to_dual (attr := simp)] theorem coe_map_symm_apply (f : α ≃o β) (s : UpperSet β) : (map f).symm s = f ⁻¹' s := rfl +set_option backward.isDefEq.respectTransparency false in @[to_dual (attr := simp)] theorem symm_map (f : α ≃o β) : (map f).symm = map f.symm := by ext; simp [map, OrderIso.symm_apply_eq] diff --git a/Mathlib/Order/WellFounded.lean b/Mathlib/Order/WellFounded.lean index b3bae400954623..9aec1f0dfcf2a0 100644 --- a/Mathlib/Order/WellFounded.lean +++ b/Mathlib/Order/WellFounded.lean @@ -374,7 +374,7 @@ theorem WellFounded.induction_bot {α} {r : α → α → Prop} (hwf : WellFound end Induction /-- A nonempty linear order with well-founded `<` has a bottom element. -/ -@[to_dual (attr := implicit_reducible) +@[to_dual (attr := instance_reducible) /-- A nonempty linear order with well-founded `>` has a top element. -/] noncomputable def WellFoundedLT.toOrderBot (α) [LinearOrder α] [Nonempty α] [h : WellFoundedLT α] : OrderBot α where diff --git a/Mathlib/Probability/Distributions/Binomial.lean b/Mathlib/Probability/Distributions/Binomial.lean index 6f56aa6595d3fc..29b4531403e147 100644 --- a/Mathlib/Probability/Distributions/Binomial.lean +++ b/Mathlib/Probability/Distributions/Binomial.lean @@ -127,6 +127,7 @@ lemma binomial_real_self (n : ℕ) (p : I) : lemma map_cast_binomial_real_self [MeasurableSingletonClass R] [CharZero R] (n : ℕ) (p : I) : Bin(R, n, p).real {(n : R)} = p ^ n := by simp [map_cast_binomial_real_singleton] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma binomial_one_eq_bernoulliMeasure (p : I) : Bin(1, p) = Ber(1, 0, p) := by diff --git a/Mathlib/Probability/Distributions/Fernique.lean b/Mathlib/Probability/Distributions/Fernique.lean index 609d9a2a1324c1..4e842b77879f78 100644 --- a/Mathlib/Probability/Distributions/Fernique.lean +++ b/Mathlib/Probability/Distributions/Fernique.lean @@ -377,6 +377,7 @@ lemma lintegral_closedBall_sdiff_exp_logRatio_mul_sq_le [IsProbabilityMeasure μ alias lintegral_closedBall_diff_exp_logRatio_mul_sq_le := lintegral_closedBall_sdiff_exp_logRatio_mul_sq_le +set_option backward.isDefEq.respectTransparency.types false in open Metric in lemma lintegral_exp_mul_sq_norm_le_mul [IsProbabilityMeasure μ] (h_rot : (μ.prod μ).map (ContinuousLinearMap.rotation (-(π / 4))) = μ.prod μ) diff --git a/Mathlib/Probability/Distributions/Gaussian/CharFun.lean b/Mathlib/Probability/Distributions/Gaussian/CharFun.lean index ae1c907ba4b830..82d54b8d6c3a54 100644 --- a/Mathlib/Probability/Distributions/Gaussian/CharFun.lean +++ b/Mathlib/Probability/Distributions/Gaussian/CharFun.lean @@ -141,6 +141,7 @@ lemma IsGaussian.charFun_eq' [IsGaussian μ] (t : E) : · exact IsGaussian.integrable_id · exact IsGaussian.memLp_two_id +set_option backward.isDefEq.respectTransparency.types false in /-- The measure `μ` is Gaussian if and only if there exist `m : E` and `f : E →L[ℝ] E →L[ℝ] ℝ` satisfying `f.toBilinForm.IsPosSemidef` and `charFun μ t = exp (⟪t, m⟫ * I - f t t / 2)`. -/ @@ -162,6 +163,7 @@ lemma isGaussian_iff_gaussian_charFun [IsFiniteMeasure μ] : · simp [charFun_eq_charFunDual_toDualMap, h, -InnerProductSpace.toContinuousLinearMap_toDualMap] · simp [← charFun_toDual_symm_eq_charFunDual, h] +set_option backward.isDefEq.respectTransparency.types false in /-- If the characteristic function of `μ` takes the form of a gaussian characteristic function, then the parameters have to be the expectation and the covariance bilinear form. -/ lemma gaussian_charFun_congr [IsFiniteMeasure μ] (m : E) (f : E →L[ℝ] E →L[ℝ] ℝ) diff --git a/Mathlib/Probability/Distributions/Gaussian/Real.lean b/Mathlib/Probability/Distributions/Gaussian/Real.lean index 89ef930b8563ac..f6c73c3aa20c46 100644 --- a/Mathlib/Probability/Distributions/Gaussian/Real.lean +++ b/Mathlib/Probability/Distributions/Gaussian/Real.lean @@ -325,6 +325,7 @@ lemma gaussianReal_map_const_add (y : ℝ) : simp_rw [add_comm y] exact gaussianReal_map_add_const y +set_option backward.isDefEq.respectTransparency.types false in /-- The map of a Gaussian distribution by multiplication by a constant is a Gaussian. -/ lemma gaussianReal_map_const_mul (c : ℝ) : (gaussianReal μ v).map (c * ·) = gaussianReal (c * μ) (.mk (c ^ 2) (sq_nonneg _) * v) := by diff --git a/Mathlib/Probability/Distributions/Uniform.lean b/Mathlib/Probability/Distributions/Uniform.lean index 9afe5ff77bc9fc..ab9a9ec0f78a7b 100644 --- a/Mathlib/Probability/Distributions/Uniform.lean +++ b/Mathlib/Probability/Distributions/Uniform.lean @@ -236,6 +236,7 @@ theorem uniformOfFinset_apply_of_mem (ha : a ∈ s) : uniformOfFinset s hs a = ( theorem uniformOfFinset_apply_of_notMem (ha : a ∉ s) : uniformOfFinset s hs a = 0 := by simp [ha] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem support_uniformOfFinset : (uniformOfFinset s hs).support = s := Set.ext diff --git a/Mathlib/Probability/Kernel/Composition/CompProd.lean b/Mathlib/Probability/Kernel/Composition/CompProd.lean index 962c306e3292a8..286cb1d90bfe6f 100644 --- a/Mathlib/Probability/Kernel/Composition/CompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/CompProd.lean @@ -86,6 +86,7 @@ theorem compProd_of_not_isSFiniteKernel_right (κ : Kernel α β) (η : Kernel ( κ ⊗ₖ η = 0 := by simp [compProd, h] +set_option backward.isDefEq.respectTransparency false in theorem compProd_apply (hs : MeasurableSet s) (κ : Kernel α β) [IsSFiniteKernel κ] (η : Kernel (α × β) γ) [IsSFiniteKernel η] (a : α) : (κ ⊗ₖ η) a s = ∫⁻ b, η (a, b) (Prod.mk b ⁻¹' s) ∂κ a := by diff --git a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean index 9f51f0ecb5e416..ddc1b92a3a98a3 100644 --- a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean +++ b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean @@ -191,6 +191,7 @@ lemma tendsto_defaultRatCDF_atBot : Tendsto defaultRatCDF atBot (𝓝 0) := by refine ⟨-1, fun q hq => (if_pos (hq.trans_lt ?_)).symm⟩ linarith +set_option backward.isDefEq.respectTransparency false in lemma iInf_rat_gt_defaultRatCDF (t : ℚ) : ⨅ r : Ioi t, defaultRatCDF r = defaultRatCDF t := by simp only [defaultRatCDF] @@ -290,6 +291,7 @@ lemma IsMeasurableRatCDF.stieltjesFunctionAux_unit_prod {f : α → ℚ → ℝ} variable {f : α → ℚ → ℝ} [MeasurableSpace α] (hf : IsMeasurableRatCDF f) include hf +set_option backward.isDefEq.respectTransparency false in lemma IsMeasurableRatCDF.stieltjesFunctionAux_eq (a : α) (r : ℚ) : IsMeasurableRatCDF.stieltjesFunctionAux f a r = f a r := by rw [← hf.iInf_rat_gt_eq a r, IsMeasurableRatCDF.stieltjesFunctionAux] diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean b/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean index 83efa31050eeba..b0c4f3a7f4d977 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean @@ -89,6 +89,7 @@ lemma measurable_IicProdIoc {m n : ι} : Measurable (IicProdIoc (X := X) m n) := namespace MeasurableEquiv +set_option backward.isDefEq.respectTransparency false in /-- Gluing `Iic a` and `Ioc a b` into `Iic b`. This version requires `a ≤ b` to get a measurable equivalence. -/ def IicProdIoc {a b : ι} (hab : a ≤ b) : @@ -115,6 +116,7 @@ lemma coe_IicProdIoc_symm {a b : ι} (hab : a ≤ b) : ⇑(IicProdIoc (X := X) hab).symm = fun x ↦ (frestrictLe₂ hab x, restrict₂ Ioc_subset_Iic_self x) := rfl +set_option backward.isDefEq.respectTransparency false in /-- Gluing `Iic a` and `Ioi a` into `ℕ`, version as a measurable equivalence on dependent functions. -/ def IicProdIoi (a : ι) : @@ -142,6 +144,7 @@ section Nat variable {X : ℕ → Type*} [∀ n, MeasurableSpace (X n)] +set_option backward.isDefEq.respectTransparency false in /-- Identifying `{a + 1}` with `Ioc a (a + 1)`, as a measurable equiv on dependent functions. -/ def MeasurableEquiv.piSingleton (a : ℕ) : X (a + 1) ≃ᵐ Π i : Ioc a (a + 1), X i where toFun x i := (Nat.mem_Ioc_succ.1 i.2).symm ▸ x diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean b/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean index 2d475d5db00468..d54033daae9218 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean @@ -243,6 +243,7 @@ lemma partialTraj_eq_prod [∀ n, IsSFiniteKernel (κ n)] (a b : ℕ) : variable [∀ n, IsMarkovKernel (κ n)] +set_option backward.isDefEq.respectTransparency false in /-- The pushforward of `partialTraj κ a (a + 1)` along the the point at time `a + 1` is `κ a`. -/ lemma map_partialTraj_succ_self (a : ℕ) : (partialTraj κ a (a + 1)).map (fun x ↦ x ⟨a + 1, mem_Iic.2 le_rfl⟩) = κ a := by @@ -346,7 +347,7 @@ lemma lmarginalPartialTraj_succ [∀ n, IsSFiniteKernel (κ n)] (a : ℕ) rw [lmarginalPartialTraj, partialTraj_succ_self, lintegral_map, lintegral_id_prod, lintegral_map] · congrm ∫⁻ x, f (fun i ↦ ?_) ∂_ simp only [updateFinset, mem_Iic, IicProdIoc_def, frestrictLe_apply, piSingleton, - MeasurableEquiv.coe_mk, Equiv.coe_fn_mk, update] + MeasurableEquiv.coe_mk, update] split_ifs with h1 h2 h3 <;> try rfl all_goals lia all_goals fun_prop diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean b/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean index acb68911b7da96..a122983ba7a04b 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean @@ -594,6 +594,7 @@ theorem traj_eq_prod (a : ℕ) : all_goals fun_prop all_goals fun_prop +set_option backward.isDefEq.respectTransparency.types false in theorem traj_map_updateFinset {n : ℕ} (x : Π i : Iic n, X i) : (traj κ n x).map (updateFinset · (Iic n) x) = traj κ n x := by nth_rw 2 [traj_eq_prod] diff --git a/Mathlib/Probability/Kernel/MeasurableIntegral.lean b/Mathlib/Probability/Kernel/MeasurableIntegral.lean index 894cf3fd1c0365..7d83e00f2feddc 100644 --- a/Mathlib/Probability/Kernel/MeasurableIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableIntegral.lean @@ -50,6 +50,7 @@ namespace MeasureTheory variable [NormedSpace ℝ E] +set_option backward.isDefEq.respectTransparency.types false in omit [IsSFiniteKernel κ] in @[fun_prop] theorem StronglyMeasurable.integral_kernel ⦃f : β → E⦄ @@ -74,6 +75,7 @@ theorem StronglyMeasurable.integral_kernel ⦃f : β → E⦄ exact subset_rfl · simp [f', hfx, integral_undef] +set_option backward.isDefEq.respectTransparency.types false in theorem StronglyMeasurable.integral_kernel_prod_right ⦃f : α → β → E⦄ (hf : StronglyMeasurable (uncurry f)) : StronglyMeasurable fun x => ∫ y, f x y ∂κ x := by classical diff --git a/Mathlib/Probability/Martingale/OptionalStopping.lean b/Mathlib/Probability/Martingale/OptionalStopping.lean index ffd7a0c4fa5013..e340024219f05b 100644 --- a/Mathlib/Probability/Martingale/OptionalStopping.lean +++ b/Mathlib/Probability/Martingale/OptionalStopping.lean @@ -37,6 +37,7 @@ namespace MeasureTheory variable {Ω : Type*} {m0 : MeasurableSpace Ω} {μ : Measure Ω} {𝒢 : Filtration ℕ m0} {f : ℕ → Ω → ℝ} {τ π : Ω → ℕ∞} +set_option backward.isDefEq.respectTransparency.types false in /-- Given a submartingale `f` and bounded stopping times `τ` and `π` such that `τ ≤ π`, the expectation of `stoppedValue f τ` is less than or equal to the expectation of `stoppedValue f π`. This is the forward direction of the optional stopping theorem. -/ diff --git a/Mathlib/Probability/Moments/ComplexMGF.lean b/Mathlib/Probability/Moments/ComplexMGF.lean index e779d0be17f9b7..9a48e888c2ecc6 100644 --- a/Mathlib/Probability/Moments/ComplexMGF.lean +++ b/Mathlib/Probability/Moments/ComplexMGF.lean @@ -313,6 +313,7 @@ section ext variable {Ω' : Type*} {mΩ' : MeasurableSpace Ω'} {Y : Ω' → ℝ} {μ' : Measure Ω'} +set_option backward.isDefEq.respectTransparency.types false in /-- If the complex moment-generating functions of two random variables `X` and `Y` with respect to the finite measures `μ`, `μ'`, respectively, coincide, then `μ.map X = μ'.map Y`. In other words, complex moment-generating functions separate the distributions of random variables. -/ diff --git a/Mathlib/Probability/Moments/CovarianceBilin.lean b/Mathlib/Probability/Moments/CovarianceBilin.lean index 96ba36fdb87bff..a3271bda1e0f02 100644 --- a/Mathlib/Probability/Moments/CovarianceBilin.lean +++ b/Mathlib/Probability/Moments/CovarianceBilin.lean @@ -51,6 +51,7 @@ def covarianceBilin (μ : Measure E) : E →L[ℝ] E →L[ℝ] ℝ := ContinuousLinearMap.bilinearComp (covarianceBilinDual μ) (toDualMap ℝ E).toContinuousLinearMap (toDualMap ℝ E).toContinuousLinearMap +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma covarianceBilin_zero : covarianceBilin (0 : Measure E) = 0 := by rw [covarianceBilin] @@ -65,6 +66,7 @@ lemma covarianceBilin_of_not_memLp (h : ¬MemLp id 2 μ) : ext simp [covarianceBilin_eq_covarianceBilinDual, h] +set_option backward.isDefEq.respectTransparency.types false in lemma covarianceBilin_apply [CompleteSpace E] [IsFiniteMeasure μ] (h : MemLp id 2 μ) (x y : E) : covarianceBilin μ x y = ∫ z, ⟪x, z - μ[id]⟫ * ⟪y, z - μ[id]⟫ ∂μ := by simp [covarianceBilin, covarianceBilinDual_apply' h] @@ -97,6 +99,7 @@ lemma covarianceBilin_real_self {μ : Measure ℝ} [IsFiniteMeasure μ] (x : ℝ covarianceBilin μ x x = x ^ 2 * Var[id; μ] := by rw [covarianceBilin_real, pow_two] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma covarianceBilin_self_nonneg (x : E) : 0 ≤ covarianceBilin μ x x := by @@ -193,10 +196,12 @@ noncomputable def covarianceOperator (μ : Measure E) : E →L[ℝ] E := continuousLinearMapOfBilin <| ContinuousLinearMap.bilinearComp (uncenteredCovarianceBilinDual μ) (toDualMap ℝ E).toContinuousLinearMap (toDualMap ℝ E).toContinuousLinearMap +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma covarianceOperator_zero : covarianceOperator (0 : Measure E) = 0 := by simp [covarianceOperator] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma covarianceOperator_of_not_memLp (hμ : ¬MemLp id 2 μ) : covarianceOperator μ = 0 := by @@ -204,6 +209,7 @@ lemma covarianceOperator_of_not_memLp (hμ : ¬MemLp id 2 μ) : refine (unique_continuousLinearMapOfBilin _ fun y ↦ ?_).symm simp [hμ, uncenteredCovarianceBilinDual_of_not_memLp] +set_option backward.isDefEq.respectTransparency.types false in lemma covarianceOperator_inner (hμ : MemLp id 2 μ) (x y : E) : ⟪covarianceOperator μ x, y⟫ = ∫ z, ⟪x, z⟫ * ⟪y, z⟫ ∂μ := by simp [covarianceOperator, uncenteredCovarianceBilinDual_apply hμ] diff --git a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean index 13abad136fb9ac..75f5e5ef6a3576 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean @@ -243,6 +243,7 @@ theorem pure_bindOnSupport (a : α) (f : ∀ (a' : α) (_ : a' ∈ (pure a).supp theorem bindOnSupport_pure (p : PMF α) : (p.bindOnSupport fun a _ => pure a) = p := by simp only [PMF.bind_pure, PMF.bindOnSupport_eq_bind] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem bindOnSupport_bindOnSupport (p : PMF α) (f : ∀ a ∈ p.support, PMF β) (g : ∀ b ∈ (p.bindOnSupport f).support, PMF γ) : diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index a952ae4571dee0..1acab2920eb875 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -409,6 +409,7 @@ section open MeasurableSpace +set_option backward.isDefEq.respectTransparency.types false in theorem filtrationOfSet_eq_natural [∀ i, MulZeroOneClass (β i)] [∀ i, Nontrivial (β i)] {s : ι → Set Ω} (hsm : ∀ i, MeasurableSet[m] (s i)) : filtrationOfSet hsm = natural (fun i => (s i).indicator (fun _ => 1 : Ω → β i)) fun i => @@ -498,6 +499,7 @@ def piLE : @Filtration (Π i, X i) ι _ pi where variable [LocallyFiniteOrderBot ι] +set_option backward.isDefEq.respectTransparency.types false in lemma piLE_eq_comap_frestrictLe (i : ι) : piLE (X := X) i = pi.comap (frestrictLe i) := by apply le_antisymm · simp_rw [piLE, ← piCongrLeft_comp_frestrictLe, ← MeasurableEquiv.coe_piCongrLeft, ← comap_comp] diff --git a/Mathlib/Probability/Process/Predictable.lean b/Mathlib/Probability/Process/Predictable.lean index 3dcf24abbad8ac..a65eba9fe22b23 100644 --- a/Mathlib/Probability/Process/Predictable.lean +++ b/Mathlib/Probability/Process/Predictable.lean @@ -48,7 +48,7 @@ namespace Filtration /-- Given a filtration `𝓕`, the predictable σ-algebra is the σ-algebra on `ι × Ω` generated by sets of the form `(t, ∞) × A` for `t ∈ ι` and `A ∈ 𝓕 t` and `{⊥} × A` for `A ∈ 𝓕 ⊥`. -/ -@[implicit_reducible] +@[instance_reducible] def predictable [Preorder ι] [OrderBot ι] (𝓕 : Filtration ι m) : MeasurableSpace (ι × Ω) := MeasurableSpace.generateFrom <| {s | ∃ A, MeasurableSet[𝓕 ⊥] A ∧ s = {⊥} ×ˢ A} ∪ diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 6ba494a578c8c6..450cf34ae7d9f0 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -440,7 +440,7 @@ section Preorder variable [Preorder ι] {f : Filtration ι m} {τ π : Ω → WithTop ι} /-- The associated σ-algebra with a stopping time. -/ -@[implicit_reducible] +@[instance_reducible] protected def measurableSpace (hτ : IsStoppingTime f τ) : MeasurableSpace Ω where MeasurableSet' s := MeasurableSet s ∧ ∀ i : ι, MeasurableSet[f i] (s ∩ {ω | τ ω ≤ i}) measurableSet_empty := by simp @@ -1078,6 +1078,7 @@ section StoppedValueOfMemFinset variable [Nonempty ι] {μ : Measure Ω} {τ : Ω → WithTop ι} {E : Type*} {p : ℝ≥0∞} {u : ι → Ω → E} +set_option backward.isDefEq.respectTransparency.types false in theorem stoppedValue_eq_of_mem_finset [AddCommMonoid E] {s : Finset ι} (hbdd : ∀ ω, τ ω ∈ (WithTop.some '' s)) : stoppedValue u τ = ∑ i ∈ s, Set.indicator {ω | τ ω = i} (u i) := by @@ -1299,7 +1300,7 @@ theorem stoppedValue_sub_eq_sum' [AddCommGroup β] (hle : τ ≤ π) {N : ℕ} ( simp only [Finset.sum_apply, Finset.sum_indicator_eq_sum_filter] refine Finset.sum_congr ?_ fun _ _ => rfl ext i - simp only [Finset.mem_filter, Set.mem_setOf_eq, Finset.mem_range, Finset.mem_Ico] + simp only [Set.mem_setOf_eq, Finset.mem_Ico] specialize hbdd ω lift τ ω to ℕ using hτ_top ω with t ht lift π ω to ℕ using hπ_top ω with b hb @@ -1318,9 +1319,10 @@ theorem stoppedValue_eq {N : ℕ} (hbdd : ∀ ω, τ ω ≤ N) : stoppedValue u have h_top : τ ω ≠ ⊤ := fun h_contra ↦ by simp [h_contra] at hbdd lift τ ω to ℕ using h_top with t ht simp only [Nat.cast_le] at hbdd - simp only [ENat.some_eq_coe, Finset.coe_range, Set.mem_image, Set.mem_Iio] + simp only [ENat.some_eq_coe, Finset.coe_range] exact ⟨t, by simpa, Nat.cast_inj.mpr rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem stoppedProcess_eq (n : ℕ) : stoppedProcess u τ n = Set.indicator {a | n ≤ τ a} (u n) + ∑ i ∈ Finset.range n, Set.indicator {ω | τ ω = i} (u i) := by rw [stoppedProcess_eq'' n] diff --git a/Mathlib/Probability/ProductMeasure.lean b/Mathlib/Probability/ProductMeasure.lean index fd74a8110084c3..d794815f67ec67 100644 --- a/Mathlib/Probability/ProductMeasure.lean +++ b/Mathlib/Probability/ProductMeasure.lean @@ -81,6 +81,7 @@ lemma piContent_cylinder {I : Finset ι} {S : Set (Π i : I, X i)} (hS : Measura piContent μ (cylinder I S) = Measure.pi (fun i : I ↦ μ i) S := projectiveFamilyContent_cylinder _ hS +set_option backward.isDefEq.respectTransparency.types false in theorem piContent_eq_measure_pi [Fintype ι] {s : Set (Π i, X i)} (hs : MeasurableSet s) : piContent μ s = Measure.pi μ s := by let e : @Finset.univ ι _ ≃ ι := @@ -257,6 +258,7 @@ lemma Measure.infinitePiNat_map_piCongrLeft (e : ℕ ≃ ι) {s : Set (Π i, X i any_goals fun_prop exact hS.preimage (by fun_prop) +set_option backward.isDefEq.respectTransparency.types false in /-- This is the key theorem to build the product of an arbitrary family of probability measures: the `piContent` of a decreasing sequence of cylinders with empty intersection converges to `0`. diff --git a/Mathlib/RepresentationTheory/Action.lean b/Mathlib/RepresentationTheory/Action.lean index e756bfb73b9521..ae9f47bcb83b96 100644 --- a/Mathlib/RepresentationTheory/Action.lean +++ b/Mathlib/RepresentationTheory/Action.lean @@ -123,7 +123,6 @@ lemma μ_apply_single_single (x : X.V) (y : Y.V) (r s : k) : μ (k := k) X Y (.single x r ⊗ₜ .single y s) = .single (x, y) (r * s) := by ext; simp [← toLinearMap_apply] -open TensorProduct in lemma coeff_μ_tmul (l1 : k[X.V]) (l2 : k[Y.V]) (xy : (X ⊗ Y).V) : (μ X Y (l1 ⊗ₜ l2)).coeff xy = l1.coeff xy.1 * l2.coeff xy.2 := by simp [← toLinearMap_apply, types_tensorObj_def, finsuppTensorFinsupp'_apply_apply _] @@ -226,6 +225,7 @@ end comm end LinearizeMonoidal +set_option backward.isDefEq.respectTransparency.types false in lemma linearizeTrivial_def (X : Type w) (g : G) : linearize k G (Action.trivial _ X) g = LinearMap.id := by ext (x : X) : 2 diff --git a/Mathlib/RepresentationTheory/Basic.lean b/Mathlib/RepresentationTheory/Basic.lean index 4233958ae7607a..aba2c6dd1bd0f4 100644 --- a/Mathlib/RepresentationTheory/Basic.lean +++ b/Mathlib/RepresentationTheory/Basic.lean @@ -224,6 +224,7 @@ we have `Module k[G] (restrictScalars k k[G] M)`. -/ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ofModule_asAlgebraHom_apply_apply (r : k[G]) (m : RestrictScalars k k[G] M) : @@ -309,6 +310,7 @@ section Subrepresentation variable {k G V : Type*} [Semiring k] [Monoid G] [AddCommMonoid V] [Module k V] (ρ : Representation k G V) +set_option backward.isDefEq.respectTransparency false in /-- Given a `k`-linear `G`-representation `(V, ρ)`, this is the representation defined by restricting `ρ` to a `G`-invariant `k`-submodule of `V`. -/ @[simps] @@ -630,6 +632,7 @@ local notation ρV " ⊗ " ρW => tprod ρV ρW theorem tprod_apply (g : G) : (ρV ⊗ ρW) g = TensorProduct.map (ρV g) (ρW g) := rfl +set_option backward.isDefEq.respectTransparency false in theorem smul_tprod_one_asModule (r : k[G]) (x : V) (y : W) : r • (show (ρV.tprod 1).asModule from x ⊗ₜ y) = (r • show ρV.asModule from x) ⊗ₜ y := by change asAlgebraHom (ρV ⊗ 1) _ _ = asAlgebraHom ρV _ _ ⊗ₜ _ @@ -638,6 +641,7 @@ theorem smul_tprod_one_asModule (r : k[G]) (x : V) (y : W) : simp only [Finsupp.sum, TensorProduct.sum_tmul] rfl +set_option backward.isDefEq.respectTransparency false in theorem smul_one_tprod_asModule (r : k[G]) (x : V) (y : W) : r • (show (1 ⊗ ρW).asModule from x ⊗ₜ y) = x ⊗ₜ (r • show ρW.asModule from y) := by change asAlgebraHom (1 ⊗ ρW) _ _ = _ ⊗ₜ asAlgebraHom ρW _ _ diff --git a/Mathlib/RepresentationTheory/Coinduced.lean b/Mathlib/RepresentationTheory/Coinduced.lean index 6ecbcedcf78141..d73469af215556 100644 --- a/Mathlib/RepresentationTheory/Coinduced.lean +++ b/Mathlib/RepresentationTheory/Coinduced.lean @@ -69,6 +69,7 @@ def coindV : Submodule k (H → A) where lemma mem_coindV (f : H → A) : f ∈ coindV φ σ ↔ ∀ (g : G) (h : H), f (φ g * h) = σ g (f h) := Iff.rfl +set_option backward.isDefEq.respectTransparency.types false in /-- If `ρ : Representation k G A` and `φ : G →* H` then `coind φ ρ` is the representation coinduced by `ρ` along `φ`, defined as the following action of `H` on the submodule `coindV φ ρ` @@ -84,6 +85,7 @@ def coind : Representation k H (coindV φ ρ) where map_one' := by ext; simp map_mul' _ _ := by ext; simp [mul_assoc] +set_option backward.isDefEq.respectTransparency.types false in variable {σ ρ} in /-- Given a monoid homomorphism `φ : G →* H` and an intertwining map `f : σ ⟶ ρ`, there is a natural intertwining map `coind φ σ ⟶ coind φ ρ` given by postcomposition by `f`. -/ @@ -154,6 +156,7 @@ instance {G : Type v'} [Group G] (S : Subgroup G) : end Coind section Coind' +set_option backward.isDefEq.respectTransparency.types false in /-- If `φ : G →* H` and `A : Rep k G` then `coind' φ A`, the coinduction of `A` along `φ`, is defined as an `H`-action on `Hom_{k[G]}(k[H], A)`. If `f : k[H] → A` is `G`-equivariant @@ -222,6 +225,7 @@ noncomputable def coindVEquiv : left_inv x := by simp right_inv x := coind'_ext φ fun _ => by simp +set_option backward.isDefEq.respectTransparency.types false in /-- `coind φ A` and `coind' φ A` are isomorphic representations, with the underlying `k`-linear equivalence given by `coindVEquiv`. -/ noncomputable def coindIso : coind φ A ≅ coind' φ A := @@ -240,6 +244,7 @@ end CoindIso noncomputable section Adjunction +set_option backward.isDefEq.respectTransparency.types false in /-- The morphism induced by the adjunction between `res φ` and `coind φ` sending a morphism `f : res φ B ⟶ A` to the morphism `B ⟶ coind φ A` given by the underlying linear map sending `b : B.V` to the function sending `h : H` to `f ((B.ρ h) b)`. -/ @@ -266,6 +271,7 @@ info: _.1 (@DFunLike.coe _ _.1 _ _ (@ConcreteCategory.hom (Rep _ _ _ _) _ _ _ _ attribute [pp_with_univ] Rep coind +set_option backward.isDefEq.respectTransparency.types false in /-- Given a monoid homomorphism `φ : G →* H`, an `H`-representation `B`, and a `G`-representation `A`, there is a `k`-linear equivalence between the `G`-representation morphisms `res φ B ⟶ A` and the `H`-representation morphisms `B ⟶ coind φ A`. diff --git a/Mathlib/RepresentationTheory/Coinvariants.lean b/Mathlib/RepresentationTheory/Coinvariants.lean index 000afd91aa3a59..88834570e1c71c 100644 --- a/Mathlib/RepresentationTheory/Coinvariants.lean +++ b/Mathlib/RepresentationTheory/Coinvariants.lean @@ -248,7 +248,7 @@ end Finsupp section TensorProduct -open TensorProduct Coinvariants Finsupp +open Coinvariants Finsupp variable {k G V W : Type*} [CommRing k] [Group G] [AddCommGroup V] [Module k V] [AddCommGroup W] [Module k W] (ρ : Representation k G V) (τ : Representation k G W) @@ -321,6 +321,7 @@ abbrev toCoinvariantsMkQ : A ⟶ toCoinvariants A S := the coinvariants of `ρ|_S`. -/ abbrev quotientToCoinvariants : Rep k (G ⧸ S) := Rep.ofQuotient (Rep.toCoinvariants A S) S +set_option backward.isDefEq.respectTransparency.types false in /-- Given a normal subgroup `S ≤ G`, a `G`-representation `A` induces a short exact sequence of `G`-representations `0 ⟶ Ker(mk) ⟶ A ⟶ A_S ⟶ 0` where `mk` is the quotient map to the `S`-coinvariants `A_S`. -/ diff --git a/Mathlib/RepresentationTheory/Continuous/TopRep.lean b/Mathlib/RepresentationTheory/Continuous/TopRep.lean index 54963a10aee64a..8a06ab9ed73212 100644 --- a/Mathlib/RepresentationTheory/Continuous/TopRep.lean +++ b/Mathlib/RepresentationTheory/Continuous/TopRep.lean @@ -187,6 +187,7 @@ end Linear section equivAction +set_option backward.isDefEq.respectTransparency.types false in /-- The functor sending a topological representation to the corresponding object in `Action (TopModuleCat k) G`. -/ def toActionTopModFunc : TopRep k G ⥤ Action (TopModuleCat k) G where diff --git a/Mathlib/RepresentationTheory/Equiv.lean b/Mathlib/RepresentationTheory/Equiv.lean index e1ee9239802ab7..66000b74d1eb05 100644 --- a/Mathlib/RepresentationTheory/Equiv.lean +++ b/Mathlib/RepresentationTheory/Equiv.lean @@ -173,6 +173,7 @@ def leftRegularMapEquiv : (leftRegular k G).IntertwiningMap σ ≃ₗ[k] V where left_inv x := by ext; simp [← x.isIntertwining] right_inv v := by simp +set_option backward.isDefEq.respectTransparency false in lemma leftRegularMapEquiv_symm_single (g : G) (v : V) : ((leftRegularMapEquiv σ).symm v) (.single g 1) = σ g v := by simp diff --git a/Mathlib/RepresentationTheory/FDRep.lean b/Mathlib/RepresentationTheory/FDRep.lean index 96c79b0a647ff9..d488acf4232626 100644 --- a/Mathlib/RepresentationTheory/FDRep.lean +++ b/Mathlib/RepresentationTheory/FDRep.lean @@ -107,6 +107,7 @@ lemma hom_hom_action_ρ (V : FDRep R G) (g : G) : (Action.ρ V g).hom.hom = (ρ def isoToLinearEquiv {V W : FDRep R G} (i : V ≅ W) : V ≃ₗ[R] W := FGModuleCat.isoToLinearEquiv ((Action.forget (FGModuleCat R) G).mapIso i) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem Iso.conj_ρ {V W : FDRep R G} (i : V ≅ W) (g : G) : W.ρ g = (FDRep.isoToLinearEquiv i).conj (V.ρ g) := by @@ -166,8 +167,7 @@ def forget₂HomLinearEquiv (X Y : FDRep R G) : (forget₂ (FDRep R G) (Rep R G)).obj Y) ≃ₗ[R] X ⟶ Y where toFun f := ⟨InducedCategory.homMk (ModuleCat.ofHom <| f.hom.toLinearMap), fun g ↦ by ext1 - simp only [FGModuleCat.obj_carrier, ObjectProperty.FullSubcategory.comp_hom, - InducedCategory.homMk_hom, ModuleCat.hom_comp, hom_hom_action_ρ] + simp only [FGModuleCat.obj_carrier] exact f.hom.2 g⟩ map_add' _ _ := rfl map_smul' _ _ := rfl diff --git a/Mathlib/RepresentationTheory/FiniteIndex.lean b/Mathlib/RepresentationTheory/FiniteIndex.lean index 89cf8b2082da03..3d7fc7f106f3e5 100644 --- a/Mathlib/RepresentationTheory/FiniteIndex.lean +++ b/Mathlib/RepresentationTheory/FiniteIndex.lean @@ -99,6 +99,7 @@ lemma indToCoindAux_comm {A B : Rep k S} (f : A ⟶ B) (g₁ g₂ : G) (a : A) : · simp [S.1.smul_def, hom_comm_apply] · simp [indToCoindAux_of_not_rel (h := h)] +set_option backward.isDefEq.respectTransparency.types false in variable (A) in /-- Let `S ≤ G` be a subgroup and `A` a `k`-linear `S`-representation. This is the `k`-linear map `Ind_S^G(A) →ₗ[k] Coind_S^G(A)` sending `(⟦g ⊗ₜ[k] a⟧, sg) ↦ ρ(s)(a)`. -/ @@ -144,6 +145,7 @@ lemma coindToInd_of_support_subset_orbit (g : G) (f : coind S.subtype A) variable (A) +set_option backward.isDefEq.respectTransparency.types false in lemma coindToInd_indToCoind : A.indToCoind ∘ₗ A.coindToInd = LinearMap.id := by ext g a simp only [LinearMap.coe_comp, Function.comp_apply, LinearMap.id_coe, id_eq] @@ -156,6 +158,7 @@ lemma coindToInd_indToCoind : A.indToCoind ∘ₗ A.coindToInd = LinearMap.id := simpa using indToCoindAux_of_not_rel b a (g.1 b) (mt Quotient.sound hb.symm) · simp +set_option backward.isDefEq.respectTransparency.types false in lemma indToCoind_coindToInd : A.coindToInd ∘ₗ A.indToCoind = LinearMap.id := by ext g a simp only [LinearMap.comp_apply, AlgebraTensorModule.curry_apply, @@ -166,6 +169,7 @@ lemma indToCoind_coindToInd : A.coindToInd ∘ₗ A.indToCoind = LinearMap.id := contrapose hx simpa using indToCoindAux_of_not_rel g x a hx +set_option backward.isDefEq.respectTransparency.types false in /-- Let `S ≤ G` be a finite index subgroup, `g₁, ..., gₙ` a set of right coset representatives of `S`, and `A` a `k`-linear `S`-representation. This is an isomorphism `Ind_S^G(A) ≅ Coind_S^G(A)`. The forward map sends `(⟦g ⊗ₜ[k] a⟧, sg) ↦ ρ(s)(a)`, and the inverse sends `f : G → A` to @@ -178,6 +182,7 @@ noncomputable def indCoindIso (A : Rep.{max w u} k S) : variable (k S) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a finite index subgroup `S ≤ G`, this is a natural isomorphism between the `Ind_S^G` and `Coind_G^S` functors `Rep k S ⥤ Rep k G`. -/ @[implicit_reducible, simps! hom_app inv_app] diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean index 8e7e4e8a453839..68446282fd2ffb 100644 --- a/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/Functoriality.lean @@ -59,6 +59,7 @@ lemma resolutionMap_zero (φ : H →ₜ* G) (f : res φ X ⟶ Y) : lemma resolutionMap_succ (φ : H →ₜ* G) (f : res φ X ⟶ Y) (i : ℕ) : resolutionMap φ f (i + 1) = ofHom (coind₁ResMap φ (resolutionMap φ f i).hom) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma resolutionMap_id (X : TopRep k G) (i : ℕ) : resolutionMap (ContinuousMonoidHom.id G) (𝟙 X) i = 𝟙 (resolutionX X i) := by @@ -107,6 +108,7 @@ def cochainsMap (φ : H →ₜ* G) (f : res φ X ⟶ Y) : rw [homogeneousCochains.d_eq, homogeneousCochains.d_eq, ← invariantsResMap_comp, resolutionMap_comp_d, invariantsResMap_map_comp] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma cochainsMap_id (X : TopRep k G) : cochainsMap (ContinuousMonoidHom.id G) (𝟙 X) = 𝟙 (homogeneousCochains X) := by diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/LongExactSequence.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/LongExactSequence.lean index e985879f46703a..174602e2e4367f 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/LongExactSequence.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/LongExactSequence.lean @@ -141,6 +141,7 @@ theorem mem_cocycles₁_of_comp_eq_d₀₁ have := congr($((mapShortComplexH1 (MonoidHom.id G) X.f).comm₂₃.symm) x) simp_all [shortComplexH1, LinearMap.compLeft] +set_option backward.isDefEq.respectTransparency.types false in theorem δ₀_apply -- Let `0 ⟶ X₁ ⟶f X₂ ⟶g X₃ ⟶ 0` be a short exact sequence of `G`-representations. -- Let `z : X₃ᴳ` and `y : X₂` be such that `g(y) = z`. diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/LowDegree.lean index 6329e353639620..c82388589b36cb 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/LowDegree.lean @@ -769,6 +769,7 @@ def cocyclesIso₀ : cocycles A 0 ≅ ModuleCat.of k A.ρ.invariants := ((inhomogeneousCochains A).cyclesIsKernel 0 1 (by simp)) (shortComplexH0_exact A).fIsKernel (dArrowIso₀₁ A) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp), elementwise (attr := simp)] lemma cocyclesIso₀_hom_comp_f : @@ -795,6 +796,9 @@ end cocyclesIso₀ section isoCocycles₁ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The short complex `A --d₀₁--> Fun(G, A) --d₁₂--> Fun(G × G, A)` is isomorphic to the 1st short complex associated to the complex of inhomogeneous cochains of `A`. -/ @[simps! hom inv] @@ -848,6 +852,9 @@ end isoCocycles₁ section isoCocycles₂ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The short complex `Fun(G, A) --d₁₂--> Fun(G × G, A) --dTwo--> Fun(G × G × G, A)` is isomorphic to the 2nd short complex associated to the complex of inhomogeneous cochains of `A`. -/ @[simps! hom inv] diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean index 7367d9ff4f49ff..63cc8f3ef2d6c5 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/Functoriality.lean @@ -320,6 +320,7 @@ theorem mapShortComplexH1_zero : theorem mapShortComplexH1_id : mapShortComplexH1 (MonoidHom.id G) (𝟙 A) = 𝟙 _ := by ext <;> simp [shortComplexH1] +set_option backward.isDefEq.respectTransparency.types false in theorem mapShortComplexH1_comp {G H K : Type u} [Group G] [Group H] [Group K] {A : Rep k G} {B : Rep k H} {C : Rep k K} (f : G →* H) (g : H →* K) (φ : A ⟶ res f B) (ψ : B ⟶ res g C) : @@ -537,6 +538,7 @@ previous assumptions. -/ end OfTrivial +set_option backward.isDefEq.respectTransparency.types false in /-- The short complex `H₁(S, A) ⟶ H₁(G, A) ⟶ H₁(G ⧸ S, A_S)`. The first map is the "corestriction" map induced by the inclusion `ι : S →* G` and the identity on `Res(ι)(A)`, and the second map is the "coinflation" map induced by the quotient maps `G →* G ⧸ S` and `A →ₗ A_S`. -/ @@ -740,6 +742,7 @@ theorem mapShortComplexH2_id : mapShortComplexH2 (MonoidHom.id _) (𝟙 A) = ext simp } +set_option backward.isDefEq.respectTransparency.types false in theorem mapShortComplexH2_comp {G H K : Type u} [Group G] [Group H] [Group K] {A : Rep k G} {B : Rep k H} {C : Rep k K} (f : G →* H) (g : H →* K) (φ : A ⟶ res f B) (ψ : B ⟶ res g C) : diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/LongExactSequence.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/LongExactSequence.lean index 6407ea0c1ce019..d10cf6d45bdfa1 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/LongExactSequence.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/LongExactSequence.lean @@ -131,6 +131,7 @@ theorem δ_apply {i j : ℕ} (hij : j + 1 = i) π X.X₁ j (cyclesMkOfCompEqD hX hx) := by exact (map_chainsFunctor_shortExact hX).δ_apply i j hij z hz y hy x (by simpa using! hx) _ rfl +set_option backward.isDefEq.respectTransparency.types false in theorem δ₀_apply -- Let `0 ⟶ X₁ ⟶f X₂ ⟶g X₃ ⟶ 0` be a short exact sequence of `G`-representations. -- Let `z` by a 1-cycle for `X₃` and `y` a 1-chain for `X₂` such that `g ∘ y = z`. @@ -157,6 +158,7 @@ theorem mem_cycles₁_of_comp_eq_d₂₁ have := congr($((mapShortComplexH1 (MonoidHom.id G) X.f).comm₂₃.symm) x) simp_all [shortComplexH1] +set_option backward.isDefEq.respectTransparency.types false in theorem δ₁_apply -- Let `0 ⟶ X₁ ⟶f X₂ ⟶g X₃ ⟶ 0` be a short exact sequence of `G`-representations. -- Let `z` by a 2-cycle for `X₃` and `y` a 2-chain for `X₂` such that `g ∘ y = z`. diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean index 8c863ab81a5d93..5fda00c63b437f 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean @@ -114,8 +114,8 @@ theorem range_d₁₀_eq_coinvariantsKer : simpa [← hy, add_sub_add_comm, sum_add_index, d₁₀_single (G := G)] using! Submodule.add_mem _ (Coinvariants.mem_ker_of_eq _ _ _ rfl) (h rfl) -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp), elementwise (attr := simp)] lemma d₁₀_comp_coinvariantsMk : d₁₀ A ≫ (coinvariantsMk k G).app A = 0 := by ext @@ -738,6 +738,9 @@ end cyclesIso₀ section isoCycles₁ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The short complex `(G² →₀ A) --d₂₁--> (G →₀ A) --d₁₀--> A` is isomorphic to the 1st short complex associated to the complex of inhomogeneous chains of `A`. -/ @[simps! hom inv] @@ -773,6 +776,7 @@ lemma toCycles_comp_isoCycles₁_hom : simp [← cancel_mono (shortComplexH1 A).moduleCatLeftHomologyData.i, comp_d₂₁_eq, shortComplexH1_f] +set_option backward.isDefEq.respectTransparency.types false in lemma cyclesMk₁_eq (x : cycles₁ A) : cyclesMk 1 0 (by simp) ((chainsIso₁ A).inv x) (by rw [← LinearMap.comp_apply, ← ModuleCat.hom_comp, eq_d₁₀_comp_inv]; simp) = @@ -786,6 +790,9 @@ end isoCycles₁ section isoCycles₂ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The short complex `(G³ →₀ A) --d₃₂--> (G² →₀ A) --d₂₁--> (G →₀ A)` is isomorphic to the 2nd short complex associated to the complex of inhomogeneous chains of `A`. -/ @[simps! hom inv] @@ -821,6 +828,7 @@ lemma toCycles_comp_isoCycles₂_hom : simp [← cancel_mono (shortComplexH2 A).moduleCatLeftHomologyData.i, comp_d₃₂_eq, shortComplexH2_f] +set_option backward.isDefEq.respectTransparency.types false in lemma cyclesMk₂_eq (x : cycles₂ A) : cyclesMk 2 1 (by simp) ((chainsIso₂ A).inv x) (by rw [← LinearMap.comp_apply, ← ModuleCat.hom_comp, eq_d₂₁_comp_inv] diff --git a/Mathlib/RepresentationTheory/Homological/Resolution.lean b/Mathlib/RepresentationTheory/Homological/Resolution.lean index 9685e4a9ea3184..2ee094a14db21e 100644 --- a/Mathlib/RepresentationTheory/Homological/Resolution.lean +++ b/Mathlib/RepresentationTheory/Homological/Resolution.lean @@ -221,6 +221,7 @@ theorem d_eq (n : ℕ) : ((standardComplex k G).d (n + 1) n).hom.toLinearMap = Representation.IntertwiningMap.smul_apply, (Representation.linearizeMap_single), smul_eq_mul, mul_one] +set_option backward.isDefEq.respectTransparency.types false in lemma d_apply {n : ℕ} (f : k[Fin (n + 1 + 1) → G]) : ((standardComplex k G).d (n + 1) n).hom f = d k G (n + 1) f := by rw [← Representation.IntertwiningMap.toLinearMap_apply, d_eq]; rfl @@ -302,7 +303,6 @@ theorem εToSingle₀_comp_eq : ext1 simpa using! (forget₂ToModuleCatHomotopyEquiv_f_0_eq k G).symm -set_option backward.isDefEq.respectTransparency false in theorem quasiIso_forget₂_εToSingle₀ : QuasiIso (((forget₂ _ (ModuleCat.{u} k)).mapHomologicalComplex _).map (εToSingle₀ k G)) := by have h : QuasiIso (forget₂ToModuleCatHomotopyEquiv k G).hom := inferInstance diff --git a/Mathlib/RepresentationTheory/Induced.lean b/Mathlib/RepresentationTheory/Induced.lean index 2dab755849aaad..2677fd901a31d3 100644 --- a/Mathlib/RepresentationTheory/Induced.lean +++ b/Mathlib/RepresentationTheory/Induced.lean @@ -49,7 +49,7 @@ universe t w w' u u' v v' namespace Representation -open Finsupp TensorProduct +open Finsupp variable {k G H : Type*} [CommRing k] [Group G] [Group H] (φ : G →* H) {A B : Type*} [AddCommGroup A] [Module k A] (ρ : Representation k G A) diff --git a/Mathlib/RepresentationTheory/Intertwining.lean b/Mathlib/RepresentationTheory/Intertwining.lean index 94b70397a40b47..428ad6f5719403 100644 --- a/Mathlib/RepresentationTheory/Intertwining.lean +++ b/Mathlib/RepresentationTheory/Intertwining.lean @@ -507,6 +507,7 @@ def equivLinearMapAsModule : left_inv f := rfl right_inv f := rfl +set_option backward.isDefEq.respectTransparency false in /-- Composition of intertwining maps. -/ def llcomp : IntertwiningMap σ τ →ₗ[A] IntertwiningMap ρ σ →ₗ[A] IntertwiningMap ρ τ where toFun f := diff --git a/Mathlib/RepresentationTheory/Invariants.lean b/Mathlib/RepresentationTheory/Invariants.lean index a93460d67982c7..01e7ac188479d7 100644 --- a/Mathlib/RepresentationTheory/Invariants.lean +++ b/Mathlib/RepresentationTheory/Invariants.lean @@ -38,6 +38,7 @@ variable [Fintype G] [Invertible (Fintype.card G : k)] /-- The average of all elements of the group `G`, considered as an element of `k[G]`. -/ noncomputable def average : k[G] := ⅟(Fintype.card G : k) • ∑ g : G, of k G g +set_option backward.isDefEq.respectTransparency.types false in /-- `average k G` is invariant under left multiplication by elements of `G`. -/ @[simp] theorem mul_average_left (g : G) : .single g 1 * average k G = average k G := by @@ -47,6 +48,7 @@ theorem mul_average_left (g : G) : .single g 1 * average k G = average k G := by change ⅟(Fintype.card G : k) • ∑ x : G, f (g * x) = ⅟(Fintype.card G : k) • ∑ x : G, f x rw [Function.Bijective.sum_comp (Group.mulLeft_bijective g) _] +set_option backward.isDefEq.respectTransparency.types false in /-- `average k G` is invariant under right multiplication by elements of `G`. -/ @[simp] diff --git a/Mathlib/RepresentationTheory/Maschke.lean b/Mathlib/RepresentationTheory/Maschke.lean index 1d0474598e46c9..772704d22feeb8 100644 --- a/Mathlib/RepresentationTheory/Maschke.lean +++ b/Mathlib/RepresentationTheory/Maschke.lean @@ -180,6 +180,7 @@ variable {G k V : Type*} [Group G] [Field k] [Finite G] [NeZero (Nat.card G : k) open Representation +set_option backward.isDefEq.respectTransparency false in instance : IsSemisimpleRepresentation ρ := by rw [isSemisimpleRepresentation_iff_isSemisimpleModule_asModule] infer_instance diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index 8a0423b1a09416..25035ac63d0b12 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -483,6 +483,7 @@ section Action variable (k G) +set_option backward.isDefEq.respectTransparency.types false in /-- Every object in `Rep k G` naturally correspond to an object in `Action`. -/ @[simps] def RepToAction : Rep.{w} k G ⥤ Action (ModuleCat.{w} k) G where @@ -1042,6 +1043,7 @@ representation morphisms `Hom(k[G], A)` and `A`. -/ abbrev leftRegularHomEquiv (A : Rep k G) : (leftRegular k G ⟶ A) ≃ₗ[k] A := homLinearEquiv _ _ ≪≫ₗ Representation.leftRegularMapEquiv A.ρ +set_option backward.isDefEq.respectTransparency.types false in theorem leftRegularHomEquiv_symm_single {A : Rep k G} (x : A) (g : G) : ((leftRegularHomEquiv A).symm x).hom (.single g 1) = A.ρ g x := by simp [homEquiv] diff --git a/Mathlib/RepresentationTheory/Rep/Res.lean b/Mathlib/RepresentationTheory/Rep/Res.lean index 008c53a80d3ba4..def1ed7cfe31fb 100644 --- a/Mathlib/RepresentationTheory/Rep/Res.lean +++ b/Mathlib/RepresentationTheory/Rep/Res.lean @@ -118,6 +118,7 @@ lemma res_map_exact {k : Type u} [CommRing k] (S.map (resFunctor f)).Exact ↔ S.Exact := by rw [ShortComplex.exact_map_iff_of_faithful] +set_option backward.isDefEq.respectTransparency.types false in lemma shortExact_res {k : Type u} [CommRing k] (φ : H →* G) {S : ShortComplex (Rep.{w} k G)} : (S.map (resFunctor φ)).ShortExact ↔ S.ShortExact := by constructor diff --git a/Mathlib/RepresentationTheory/Submodule.lean b/Mathlib/RepresentationTheory/Submodule.lean index dae58013ec3545..34683e1791abe2 100644 --- a/Mathlib/RepresentationTheory/Submodule.lean +++ b/Mathlib/RepresentationTheory/Submodule.lean @@ -60,6 +60,7 @@ instance [Nontrivial V] : Nontrivial ρ.invtSubmodule := end invtSubmodule +set_option backward.isDefEq.respectTransparency false in lemma asAlgebraHom_mem_of_forall_mem (p : Submodule k V) (hp : ∀ g, ∀ v ∈ p, ρ g v ∈ p) (v : V) (hv : v ∈ p) (x : k[G]) : ρ.asAlgebraHom x v ∈ p := by diff --git a/Mathlib/RepresentationTheory/Tannaka.lean b/Mathlib/RepresentationTheory/Tannaka.lean index 306c56a5d7996d..de885b665827c6 100644 --- a/Mathlib/RepresentationTheory/Tannaka.lean +++ b/Mathlib/RepresentationTheory/Tannaka.lean @@ -50,6 +50,7 @@ def forget := LaxMonoidalFunctor.of (forget₂ (FDRep k G) (FGModuleCat k)) @[simp] lemma forget_map (X Y : FDRep k G) (f : X ⟶ Y) : (forget k G).map f = f.hom := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Definition of `equivHom g : Aut (forget k G)` by its components. -/ @[simps] def equivApp (g : G) (X : FDRep k G) : X.V ≅ X.V where @@ -62,6 +63,7 @@ def equivApp (g : G) (X : FDRep k G) : X.V ≅ X.V where ext x simp +set_option backward.isDefEq.respectTransparency.types false in variable (k G) in /-- The group homomorphism `G →* Aut (forget k G)` shown to be an isomorphism. -/ @[simps] @@ -213,6 +215,7 @@ lemma toRightFDRepComp_in_rightRegular [IsDomain k] (η : Aut (forget k G)) : congr($hs (leftRegular t⁻¹ (single u 1))) _ = _ := by by_cases u = t * s <;> simp_all +set_option backward.isDefEq.respectTransparency.types false in lemma equivHom_surjective [IsDomain k] : Function.Surjective (equivHom k G) := by intro η obtain ⟨s, h⟩ := toRightFDRepComp_in_rightRegular η diff --git a/Mathlib/RingTheory/AdicCompletion/Algebra.lean b/Mathlib/RingTheory/AdicCompletion/Algebra.lean index b1dbed3ef99474..07afcc4ab70450 100644 --- a/Mathlib/RingTheory/AdicCompletion/Algebra.lean +++ b/Mathlib/RingTheory/AdicCompletion/Algebra.lean @@ -135,14 +135,17 @@ def evalₐ (n : ℕ) : AdicCompletion I R →ₐ[R] R ⧸ I ^ n := (Ideal.quotientEquivAlgOfEq R h) (AlgHom.ofLinearMap (eval I R n) rfl (fun _ _ ↦ rfl)) +set_option backward.isDefEq.respectTransparency false in theorem factor_evalₐ_eq_eval {n : ℕ} (x : AdicCompletion I R) (h : I ^ n ≤ I ^ n • ⊤) : Ideal.Quotient.factor h (evalₐ I n x) = eval I R n x := by simp [evalₐ] +set_option backward.isDefEq.respectTransparency false in theorem factor_eval_eq_evalₐ {n : ℕ} (x : AdicCompletion I R) (h : I ^ n • ⊤ ≤ I ^ n) : factor h (eval I R n x) = evalₐ I n x := by simp [evalₐ] +set_option backward.isDefEq.respectTransparency false in /-- The composition map `R →+* AdicCompletion I R →+* R ⧸ I ^ n` equals to the natural quotient map. -/ @@ -158,6 +161,7 @@ theorem surjective_evalₐ (n : ℕ) : Function.Surjective (evalₐ I n) := by · exact factor_surjective Ideal.mul_le_right · exact eval_surjective I R n +set_option backward.isDefEq.respectTransparency false in @[simp] theorem evalₐ_mk (n : ℕ) (x : AdicCauchySequence I R) : evalₐ I n (mk I R x) = Ideal.Quotient.mk (I ^ n) (x.val n) := by @@ -247,6 +251,7 @@ theorem mul_apply (n : ℕ) (f g : AdicCauchySequence I R) : (f * g) n = f n * g def mkₐ : AdicCauchySequence I R →ₐ[R] AdicCompletion I R := AlgHom.ofLinearMap (mk I R) rfl (fun _ _ ↦ rfl) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem evalₐ_mkₐ (n : ℕ) (x : AdicCauchySequence I R) : evalₐ I n (mkₐ I x) = Ideal.Quotient.mk (I ^ n) (x.val n) := by @@ -299,6 +304,7 @@ instance : IsScalarTower R (R ⧸ (I • ⊤ : Ideal R)) (M ⧸ (I • ⊤ : Sub rw [← Submodule.Quotient.mk_smul, Ideal.Quotient.mk_eq_mk, mk_smul_mk, smul_assoc] rfl +set_option backward.isDefEq.respectTransparency false in instance smul : SMul (AdicCompletion I R) (AdicCompletion I M) where smul r x := { val := fun n ↦ eval I R n r • eval I M n x @@ -342,10 +348,11 @@ example : module I = @Algebra.toModule (AdicCompletion I R) section liftRingHom -open Ideal Quotient +open Quotient variable {R S : Type*} [NonAssocSemiring R] [CommRing S] (I : Ideal S) +set_option backward.isDefEq.respectTransparency false in /-- The universal property of `AdicCompletion` for rings. The lift ring map `R →+* AdicCompletion I S` of a compatible family of @@ -372,10 +379,12 @@ def liftRingHom (f : (n : ℕ) → R →+* S ⧸ I ^ n) variable (f : (n : ℕ) → R →+* S ⧸ I ^ n) (hf : ∀ {m n : ℕ} (hle : m ≤ n), (Ideal.Quotient.factorPow I hle).comp (f n) = f m) +set_option backward.isDefEq.respectTransparency false in theorem factor_eval_liftRingHom (n : ℕ) (x : R) (h : I ^ n • ⊤ ≤ I ^ n) : factor h (eval I S n (liftRingHom I f hf x)) = f n x := by simp [liftRingHom, eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem evalₐ_liftRingHom (n : ℕ) (x : R) : evalₐ I n (liftRingHom I f hf x) = f n x := by @@ -431,21 +440,25 @@ noncomputable def ofAlgEquiv : S ≃ₐ[S] AdicCompletion I S where theorem ofAlgEquiv_apply (x : S) : ofAlgEquiv I x = of I S x := by rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem of_ofAlgEquiv_symm (x : AdicCompletion I S) : of I S ((ofAlgEquiv I).symm x) = x := by simp [ofAlgEquiv] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem ofAlgEquiv_symm_of (x : S) : (ofAlgEquiv I).symm (of I S x) = x := by simp [ofAlgEquiv] +set_option backward.isDefEq.respectTransparency false in theorem mk_smul_top_ofAlgEquiv_symm (n : ℕ) (x : AdicCompletion I S) : Ideal.Quotient.mk (I ^ n • ⊤) ((ofAlgEquiv I).symm x) = eval I S n x := by nth_rw 2 [← of_ofAlgEquiv_symm I x] simp [-of_ofAlgEquiv_symm, eval] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mk_ofAlgEquiv_symm (n : ℕ) (x : AdicCompletion I S) : Ideal.Quotient.mk (I ^ n) ((ofAlgEquiv I).symm x) = evalₐ I n x := by diff --git a/Mathlib/RingTheory/AdicCompletion/Basic.lean b/Mathlib/RingTheory/AdicCompletion/Basic.lean index 321f6e4604b43d..48c570d3a4bad3 100644 --- a/Mathlib/RingTheory/AdicCompletion/Basic.lean +++ b/Mathlib/RingTheory/AdicCompletion/Basic.lean @@ -550,6 +550,7 @@ theorem mk_zero_of (f : AdicCauchySequence I M) ← AdicCauchySequence.mk_eq_mk (show n ≤ m by lia)] simpa using (Submodule.smul_mono_left (Ideal.pow_le_pow_right (by lia))) hl +set_option backward.isDefEq.respectTransparency false in /-- Every element in the adic completion is represented by a Cauchy sequence. -/ theorem mk_surjective : Function.Surjective (mk I M) := by intro x @@ -622,6 +623,7 @@ theorem of_injective [IsHausdorff I M] : Function.Injective (of I M) := theorem of_inj [IsHausdorff I M] {a b : M} : of I M a = of I M b ↔ a = b := (of_injective I M).eq_iff +set_option backward.isDefEq.respectTransparency false in theorem of_surjective_iff : Function.Surjective (of I M) ↔ IsPrecomplete I M := by constructor · refine fun h ↦ ⟨fun f hmn ↦ ?_⟩ @@ -676,12 +678,14 @@ theorem of_ofLinearEquiv_symm (x : AdicCompletion I M) : end Bijective +set_option backward.isDefEq.respectTransparency false in theorem pow_smul_top_le_ker_eval (n : ℕ) : I ^ n • ⊤ ≤ (eval I M n).ker := by simp only [smul_le, mem_top, LinearMap.mem_ker, map_smul, coe_eval, forall_const] intro r r_in x rw [← Submodule.Quotient.mk_out (x.val n), ← Quotient.mk_smul, Quotient.mk_eq_zero] exact smul_mem_smul r_in mem_top +set_option backward.isDefEq.respectTransparency false in lemma val_apply_mem_smul_top_iff {m n : ℕ} {x : AdicCompletion I M} (m_ge : n ≤ m) : x.val m ∈ I ^ n • (⊤ : Submodule R (M ⧸ I ^ m • ⊤)) ↔ x.val n = 0 := by refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ diff --git a/Mathlib/RingTheory/AdicCompletion/Completeness.lean b/Mathlib/RingTheory/AdicCompletion/Completeness.lean index 5f8b5b456c3b61..418dd7fddc696d 100644 --- a/Mathlib/RingTheory/AdicCompletion/Completeness.lean +++ b/Mathlib/RingTheory/AdicCompletion/Completeness.lean @@ -59,6 +59,7 @@ the adic completion of `M`. -/ abbrev ofPowSMul (n : ℕ) : AdicCompletion I ↥(I ^ n • ⊤ : Submodule R M) →ₗ[AdicCompletion I R] AdicCompletion I M := map I (I ^ n • ⊤ : Submodule R M).subtype +set_option backward.isDefEq.respectTransparency.types false in theorem ofPowSMul_val_apply (h : c = b + a) {x : AdicCompletion I ↥(I ^ a • ⊤ : Submodule R M)} : (ofPowSMul I M a x).val c = powSMulQuotInclusion I M h ⊤ (x.val b) := by rw [← x.prop (show b ≤ c by lia), map_val_apply] @@ -148,6 +149,7 @@ private lemma lsum_smul_comp_finsuppLEquivDirectSum_symm {ι : Type*} [Decidable sumEquivOfFintype_apply, sum_lof, map_mk, AdicCauchySequence.map_apply_coe, map_smul] rw [← Ideal.Quotient.algebraMap_eq, algebraMap_smul] +set_option backward.isDefEq.respectTransparency.types false in variable {I} in @[stacks 05GG "(2)"] theorem pow_smul_top_eq_ker_eval {n : ℕ} (h : I.FG) : I ^ n • ⊤ = (eval I M n).ker := by @@ -176,6 +178,7 @@ theorem pow_smul_top_eq_ker_eval {n : ℕ} (h : I.FG) : I ^ n • ⊤ = (eval I rcases map_surjective I this x with ⟨x, rfl⟩ exact ⟨x, by rw [← LinearMap.comp_apply, map_comp, LinearMap.subtype_comp_codRestrict]⟩ +set_option backward.isDefEq.respectTransparency.types false in variable {I} in /-- `AdicCompletion I M` is adic complete when `I` is finitely generated. -/ @[stacks 05GG "(1)"] diff --git a/Mathlib/RingTheory/AdicCompletion/Functoriality.lean b/Mathlib/RingTheory/AdicCompletion/Functoriality.lean index be3e95310e9ebd..fa6e85c52187ef 100644 --- a/Mathlib/RingTheory/AdicCompletion/Functoriality.lean +++ b/Mathlib/RingTheory/AdicCompletion/Functoriality.lean @@ -61,6 +61,7 @@ namespace AdicCompletion open LinearMap +set_option backward.isDefEq.respectTransparency false in theorem transitionMap_comp_reduceModIdeal (f : M →ₗ[R] N) {m n : ℕ} (hmn : m ≤ n) : transitionMap I N hmn ∘ₗ f.reduceModIdeal (I ^ n) = (f.reduceModIdeal (I ^ m) : _ →ₗ[R] _) ∘ₗ transitionMap I M hmn := by @@ -69,6 +70,7 @@ theorem transitionMap_comp_reduceModIdeal (f : M →ₗ[R] N) {m n : ℕ} namespace AdicCauchySequence +set_option backward.isDefEq.respectTransparency false in /-- A linear map induces a linear map on adic Cauchy sequences. -/ @[simps] def map (f : M →ₗ[R] N) : AdicCauchySequence I M →ₗ[R] AdicCauchySequence I N where @@ -357,6 +359,7 @@ open Submodule variable {I} +set_option backward.isDefEq.respectTransparency false in theorem exists_smodEq_pow_add_one_smul {f : M →ₗ[R] N} (h : Function.Surjective (mkQ (I • ⊤) ∘ₗ f)) {y : N} {n : ℕ} (hy : y ∈ (I ^ n • ⊤ : Submodule R N)) : @@ -401,6 +404,7 @@ theorem exists_smodEq_pow_smul_top_and_mkQ_eq {f : M →ₗ[R] N} use x', hxx' rwa [mkQ_apply, hx'y0] +set_option backward.isDefEq.respectTransparency false in theorem map_surjective_of_mkQ_comp_surjective {f : M →ₗ[R] N} (h : Function.Surjective (mkQ (I • ⊤) ∘ₗ f)) : Function.Surjective (map I f) := by intro y diff --git a/Mathlib/RingTheory/Adjoin/FG.lean b/Mathlib/RingTheory/Adjoin/FG.lean index 2b10eab1dc4ab5..d07893b5078e1e 100644 --- a/Mathlib/RingTheory/Adjoin/FG.lean +++ b/Mathlib/RingTheory/Adjoin/FG.lean @@ -141,6 +141,7 @@ theorem FG.map {S : Subalgebra R A} (f : A →ₐ[R] B) (hs : S.FG) : (S.map f). end +set_option backward.isDefEq.respectTransparency false in theorem fg_of_fg_map (S : Subalgebra R A) (f : A →ₐ[R] B) (hf : Function.Injective f) (hs : (S.map f).FG) : S.FG := let ⟨s, hs⟩ := hs diff --git a/Mathlib/RingTheory/Adjoin/PowerBasis.lean b/Mathlib/RingTheory/Adjoin/PowerBasis.lean index 227d1696b5821c..1f34fb03ef14ee 100644 --- a/Mathlib/RingTheory/Adjoin/PowerBasis.lean +++ b/Mathlib/RingTheory/Adjoin/PowerBasis.lean @@ -47,6 +47,7 @@ noncomputable def adjoin.powerBasisAux {x : S} (hx : IsIntegral K x) : ext exact aeval_algebraMap_apply S (⟨x, _⟩ : K[x]) _ +set_option backward.isDefEq.respectTransparency.types false in /-- The power basis `1, x, ..., x ^ (d - 1)` for `K[x]`, where `d` is the degree of the minimal polynomial of `x`. See `Algebra.adjoin.powerBasis'` for a version over a more general base ring. -/ @@ -66,10 +67,12 @@ noncomputable def _root_.PowerBasis.ofAdjoinEqTop {x : S} (hx : IsIntegral K x) (hx' : K[x] = ⊤) : PowerBasis K S := (adjoin.powerBasis hx).map ((Subalgebra.equivOfEq _ _ hx').trans Subalgebra.topEquiv) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem _root_.PowerBasis.ofAdjoinEqTop_gen {x : S} (hx : IsIntegral K x) (hx' : K[x] = ⊤) : (PowerBasis.ofAdjoinEqTop hx hx').gen = x := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem _root_.PowerBasis.ofAdjoinEqTop_dim {x : S} (hx : IsIntegral K x) (hx' : K[x] = ⊤) : diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index ba52f9a5871e15..b863ef2b662ff7 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -337,6 +337,7 @@ theorem aeval_algHom_eq_zero (ϕ : AdjoinRoot f →ₐ[R] S) : aeval (ϕ (root f rw [aeval_def, ← h, ← map_zero ϕ.toRingHom, ← eval₂_root f, hom_eval₂] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem liftAlgHom_eq_algHom (ϕ : AdjoinRoot f →ₐ[R] S) : liftAlgHom f (Algebra.ofId R S) (ϕ (root f)) (aeval_algHom_eq_zero f ϕ) = ϕ := by @@ -427,6 +428,7 @@ lemma mapAlgHom_comp_mapAlghom (f : S →ₐ[R] T) (g : T →ₐ[R] U) (p : S[X] (hg.trans <| by simpa [Polynomial.map_map] using! Polynomial.map_dvd g.toRingHom hf) := by aesop +set_option backward.isDefEq.respectTransparency.types false in /-- `AdjoinRoot.map` as an `AlgEquiv`. -/ def mapAlgEquiv (f : S ≃ₐ[R] T) (p : S[X]) (q : T[X]) (h : Associated (p.map f) q) : AdjoinRoot p ≃ₐ[R] AdjoinRoot q := @@ -624,6 +626,7 @@ theorem powerBasisAux'_repr_apply_to_fun (hg : g.Monic) (f : AdjoinRoot g) (i : (powerBasisAux' hg).repr f i = (modByMonicHom hg f).coeff ↑i := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The power basis `1, root g, ..., root g ^ (d - 1)` for `AdjoinRoot g`, where `g` is a monic polynomial of degree `d`. -/ @[simps] @@ -663,6 +666,7 @@ variable [Field K] {f : K[X]} theorem isIntegral_root (hf : f ≠ 0) : IsIntegral K (root f) := (isAlgebraic_root hf).isIntegral +set_option backward.isDefEq.respectTransparency.types false in theorem minpoly_root (hf : f ≠ 0) : minpoly K (root f) = f * C f.leadingCoeff⁻¹ := by have f'_monic : Monic _ := monic_mul_leadingCoeff_inv hf refine (minpoly.unique K _ f'_monic ?_ ?_).symm @@ -769,6 +773,7 @@ section Equiv' variable [CommRing R] [CommRing S] [Algebra R S] variable (g : R[X]) (pb : PowerBasis R S) +set_option backward.isDefEq.respectTransparency.types false in /-- If `S` is an extension of `R` with power basis `pb` and `g` is a monic polynomial over `R` such that `pb.gen` has a minimal polynomial `g`, then `S` is isomorphic to `AdjoinRoot g`. @@ -789,11 +794,13 @@ def equiv' (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g rw [pb.lift_aeval, aeval_eq, liftAlgHom_mk, Polynomial.aeval_def, Algebra.toRingHom_ofId] -- This lemma should have the simp tag but this causes a lint issue. +set_option backward.isDefEq.respectTransparency.types false in theorem equiv'_toAlgHom (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g = 0) : (equiv' g pb h₁ h₂).toAlgHom = AdjoinRoot.liftAlgHom g _ pb.gen h₂ := rfl -- This lemma should have the simp tag but this causes a lint issue. +set_option backward.isDefEq.respectTransparency.types false in theorem equiv'_symm_toAlgHom (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g = 0) : (equiv' g pb h₁ h₂).symm.toAlgHom = pb.lift (root g) h₁ := rfl @@ -828,6 +835,7 @@ open Ideal DoubleQuot Polynomial variable [CommRing R] (I : Ideal R) (f : R[X]) +set_option backward.isDefEq.respectTransparency.types false in /-- The natural isomorphism `R[α]/(I[α]) ≅ R[α]/((I[x] ⊔ (f)) / (f))` for `α` a root of `f : R[X]` and `I : Ideal R`. @@ -838,9 +846,11 @@ def quotMapOfEquivQuotMapCMapMk : AdjoinRoot f ⧸ (I.map (C : R →+* R[X])).map (AdjoinRoot.mk f) := Ideal.quotEquivOfEq (by rw [of, AdjoinRoot.mk, Ideal.map_map]) +set_option backward.isDefEq.respectTransparency.types false in @[deprecated (since := "2026-03-02")] alias quotMapOfEquivQuotMapCMapSpanMk := quotMapOfEquivQuotMapCMapMk +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem quotMapOfEquivQuotMapCMapMk_mk (x : AdjoinRoot f) : quotMapOfEquivQuotMapCMapMk I f (Ideal.Quotient.mk (I.map (of f)) x) = @@ -850,6 +860,7 @@ theorem quotMapOfEquivQuotMapCMapMk_mk (x : AdjoinRoot f) : alias quotMapOfEquivQuotMapCMapSpanMk_mk := quotMapOfEquivQuotMapCMapMk_mk --this lemma should have the simp tag but this causes a lint issue +set_option backward.isDefEq.respectTransparency.types false in theorem quotMapOfEquivQuotMapCMapMk_symm_mk (x : AdjoinRoot f) : (quotMapOfEquivQuotMapCMapMk I f).symm (Ideal.Quotient.mk ((I.map (C : R →+* R[X])).map (Ideal.Quotient.mk (span {f}))) x) = @@ -928,6 +939,7 @@ def quotAdjoinRootEquivQuotPolynomialQuot : ((Ideal.quotEquivOfEq (by rw [map_span, Set.image_singleton])).trans (Polynomial.quotQuotEquivComm I f).symm)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem quotAdjoinRootEquivQuotPolynomialQuot_mk_of (p : R[X]) : quotAdjoinRootEquivQuotPolynomialQuot I f (Ideal.Quotient.mk (I.map (of f)) (mk f p)) = @@ -1021,6 +1033,7 @@ open AdjoinRoot AlgEquiv variable [CommRing R] [CommRing S] [Algebra R S] +set_option backward.isDefEq.respectTransparency.types false in /-- Let `α` have minimal polynomial `f` over `R` and `I` be an ideal of `R`, then `R[α] / (I) = (R[x] / (f)) / pS = (R/p)[x] / (f mod p)`. -/ @[simps!] @@ -1054,6 +1067,7 @@ theorem quotientEquivQuotientMinpolyMap_apply_mk (pb : PowerBasis R S) (I : Idea AdjoinRoot.aeval_eq, AdjoinRoot.quotEquivQuotMap_apply_mk] -- This lemma should have the simp tag but this causes a lint issue. +set_option backward.isDefEq.respectTransparency.types false in theorem quotientEquivQuotientMinpolyMap_symm_apply_mk (pb : PowerBasis R S) (I : Ideal R) (g : R[X]) : (pb.quotientEquivQuotientMinpolyMap I).symm (Ideal.Quotient.mk (Ideal.span diff --git a/Mathlib/RingTheory/AlgebraTower.lean b/Mathlib/RingTheory/AlgebraTower.lean index 782738cd65f9a0..bb118571dec097 100644 --- a/Mathlib/RingTheory/AlgebraTower.lean +++ b/Mathlib/RingTheory/AlgebraTower.lean @@ -42,7 +42,7 @@ variable [IsScalarTower R S A] [IsScalarTower R S B] /-- Suppose that `R → S → A` is a tower of algebras. If an element `r : R` is invertible in `S`, then it is invertible in `A`. -/ -@[implicit_reducible] +@[instance_reducible] def Invertible.algebraTower (r : R) [Invertible (algebraMap R S r)] : Invertible (algebraMap R A r) := Invertible.copy (Invertible.map (algebraMap S A) (algebraMap R S r)) (algebraMap R A r) @@ -50,7 +50,7 @@ def Invertible.algebraTower (r : R) [Invertible (algebraMap R S r)] : /-- A natural number that is invertible when coerced to `R` is also invertible when coerced to any `R`-algebra. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleAlgebraCoeNat (n : ℕ) [inv : Invertible (n : R)] : Invertible (n : A) := haveI : Invertible (algebraMap ℕ R n) := inv fast_instance% Invertible.algebraTower ℕ R A n diff --git a/Mathlib/RingTheory/Algebraic/Integral.lean b/Mathlib/RingTheory/Algebraic/Integral.lean index 7d74915b28c242..c62601e3593cc1 100644 --- a/Mathlib/RingTheory/Algebraic/Integral.lean +++ b/Mathlib/RingTheory/Algebraic/Integral.lean @@ -245,6 +245,7 @@ theorem restrictScalars_of_isIntegral [int : Algebra.IsIntegral R S] e, ← Algebra.smul_def, mul_comm, mul_smul] exact isIntegral_trans _ (int_s.smul _) +set_option backward.isDefEq.respectTransparency.types false in theorem restrictScalars [Algebra.IsAlgebraic R S] {a : A} (h : IsAlgebraic S a) : IsAlgebraic R a := by have ⟨p, hp, eval0⟩ := h diff --git a/Mathlib/RingTheory/Algebraic/MvPolynomial.lean b/Mathlib/RingTheory/Algebraic/MvPolynomial.lean index 40baac310e5252..a54510681aea0a 100644 --- a/Mathlib/RingTheory/Algebraic/MvPolynomial.lean +++ b/Mathlib/RingTheory/Algebraic/MvPolynomial.lean @@ -26,6 +26,7 @@ namespace MvPolynomial variable {σ : Type*} (R : Type*) [CommRing R] +set_option backward.isDefEq.respectTransparency false in theorem transcendental_supported_polynomial_aeval_X {i : σ} {s : Set σ} (h : i ∉ s) {f : R[X]} (hf : Transcendental R f) : Transcendental (supported R s) (Polynomial.aeval (X i : MvPolynomial σ R) f) := by diff --git a/Mathlib/RingTheory/AlgebraicIndependent/Adjoin.lean b/Mathlib/RingTheory/AlgebraicIndependent/Adjoin.lean index b7bfb4a3f0bd0c..82d1e10c550e61 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/Adjoin.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/Adjoin.lean @@ -35,6 +35,7 @@ variable {ι : Type*} variable {F E : Type*} {x : ι → E} [Field F] [Field E] [Algebra F E] (hx : AlgebraicIndependent F x) include hx +set_option backward.isDefEq.respectTransparency.types false in /-- Canonical isomorphism between rational function field and the intermediate field generated by algebraically independent elements. -/ def aevalEquivField : diff --git a/Mathlib/RingTheory/AlgebraicIndependent/Transcendental.lean b/Mathlib/RingTheory/AlgebraicIndependent/Transcendental.lean index be4a6f564aec3b..89b06b307828aa 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/Transcendental.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/Transcendental.lean @@ -129,6 +129,7 @@ protected theorem AlgebraicIndepOn.insert {s : Set ι} {i : ι} (hs : AlgebraicI exact (insert_iff fun h ↦ hi <| isAlgebraic_algebraMap (⟨_, subset_adjoin ⟨i, h, rfl⟩⟩ : adjoin R (x '' s))).mpr ⟨hs, hi⟩ +set_option backward.isDefEq.respectTransparency false in theorem algebraicIndependent_of_set_of_finite (s : Set ι) (ind : AlgebraicIndependent R fun i : s ↦ x i) (H : ∀ t : Set ι, t.Finite → AlgebraicIndependent R (fun i : t ↦ x i) → diff --git a/Mathlib/RingTheory/Artinian/Module.lean b/Mathlib/RingTheory/Artinian/Module.lean index 87ce8600bf7547..de051dbbad62e5 100644 --- a/Mathlib/RingTheory/Artinian/Module.lean +++ b/Mathlib/RingTheory/Artinian/Module.lean @@ -600,6 +600,9 @@ instance : Finite (PrimeSpectrum R) := (I : MaximalSpectrum R) : Field (R ⧸ I.asIdeal) := Ideal.Quotient.field I.asIdeal +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The quotient of a commutative Artinian ring by its nilradical is isomorphic to a finite product of fields, namely the quotients by the maximal ideals. -/ @[simps!] @@ -609,6 +612,9 @@ noncomputable def quotNilradicalEquivPi : { __ := Ideal.quotientInfRingEquivPiQuotient _ fun I _ ↦ I.isCoprime_of_ne commutes' _ := rfl} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The quotient of a commutative Artinian ring by a power of its nilradical is isomorphic to a finite product of local rings, namely the quotients by the powers of the maximal ideals. -/ @[simps!] diff --git a/Mathlib/RingTheory/Bezout.lean b/Mathlib/RingTheory/Bezout.lean index 5183a733fa7186..3949e86328413b 100644 --- a/Mathlib/RingTheory/Bezout.lean +++ b/Mathlib/RingTheory/Bezout.lean @@ -51,6 +51,7 @@ theorem _root_.Function.Surjective.isBezout {S : Type v} [CommRing S] (f : R → · rw [span_gcd, Ideal.map_span, Set.image_insert_eq, Set.image_singleton] · rw [Ideal.map_span, Set.image_singleton] +set_option backward.isDefEq.respectTransparency false in theorem TFAE [IsBezout R] [IsDomain R] : List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R] := by diff --git a/Mathlib/RingTheory/Bialgebra/Basic.lean b/Mathlib/RingTheory/Bialgebra/Basic.lean index 323f33e19674de..ccd0f9ab6c34f6 100644 --- a/Mathlib/RingTheory/Bialgebra/Basic.lean +++ b/Mathlib/RingTheory/Bialgebra/Basic.lean @@ -103,7 +103,7 @@ is an `R`-algebra with a coalgebra structure, then `Bialgebra.mk'` consumes proofs that the counit and comultiplication preserve the identity and multiplication, and produces a bialgebra structure on `A`. -/ -@[implicit_reducible] +@[instance_reducible] def mk' (R : Type u) (A : Type v) [CommSemiring R] [Semiring A] [Algebra R A] [C : Coalgebra R A] (counit_one : C.counit 1 = 1) (counit_mul : ∀ {a b}, C.counit (a * b) = C.counit a * C.counit b) diff --git a/Mathlib/RingTheory/Bialgebra/Equiv.lean b/Mathlib/RingTheory/Bialgebra/Equiv.lean index 877a4943aae75e..a121f140f1b43c 100644 --- a/Mathlib/RingTheory/Bialgebra/Equiv.lean +++ b/Mathlib/RingTheory/Bialgebra/Equiv.lean @@ -324,6 +324,7 @@ variable [Semiring A] [Semiring B] [Bialgebra R A] [Bialgebra R B] lemma toLinearMap_ofAlgEquiv (f : A ≃ₐ[R] B) (counit_comp map_comp_comul) : (ofAlgEquiv f counit_comp map_comp_comul : A →ₗ[R] B) = f := rfl +set_option backward.isDefEq.respectTransparency false in /-- Promotes a bijective bialgebra homomorphism to a bialgebra equivalence. -/ @[simps! apply] noncomputable def ofBijective (f : A →ₐc[R] B) (hf : Bijective f) : A ≃ₐc[R] B := diff --git a/Mathlib/RingTheory/Bialgebra/Hom.lean b/Mathlib/RingTheory/Bialgebra/Hom.lean index 2e23be000a224b..3f5f5d8f026fe4 100644 --- a/Mathlib/RingTheory/Bialgebra/Hom.lean +++ b/Mathlib/RingTheory/Bialgebra/Hom.lean @@ -65,6 +65,7 @@ variable [CommSemiring R] [Semiring A] [Algebra R A] [Semiring B] [Algebra R B] [CoalgebraStruct R A] [CoalgebraStruct R B] [FunLike F A B] [BialgHomClass F R A B] +set_option backward.isDefEq.respectTransparency false in instance (priority := 100) toAlgHomClass : AlgHomClass F R A B where map_mul := map_mul map_one := map_one diff --git a/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean index fb4f490cda5313..9dbe2b156ccb53 100644 --- a/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean @@ -52,6 +52,7 @@ instance instBialgebra : Bialgebra R A[M] where LinearMap.compl₁₂_apply, LinearMap.coe_sum, Finset.sum_apply, Finset.sum_comm (s := (Coalgebra.Repr.arbitrary R b).index)] +set_option backward.isDefEq.respectTransparency false in -- TODO: Generalise to `A[M] →ₐc[R] A[N]` under `Bialgebra R A` variable (R) [AddMonoid M] [AddMonoid N] in /-- If `f : M → N` is a monoid hom, then `AddMonoidAlgebra.mapDomain f` is a bialgebra hom between @@ -60,6 +61,7 @@ noncomputable def _root_.AddMonoidAlgebra.mapDomainBialgHom (f : M →+ N) : AddMonoidAlgebra R M →ₐc[R] AddMonoidAlgebra R N := .ofAlgHom (AddMonoidAlgebra.mapDomainAlgHom R R f) (by ext; simp) (by ext; simp) +set_option backward.isDefEq.respectTransparency false in -- TODO: Generalise to `A[M] →ₐc[R] A[N]` under `Bialgebra R A` variable (R) in /-- If `f : M → N` is a monoid hom, then `MonoidAlgebra.mapDomain f` is a bialgebra hom between @@ -68,9 +70,11 @@ their monoid algebras. -/ noncomputable def mapDomainBialgHom (f : M →* N) : R[M] →ₐc[R] R[N] := .ofAlgHom (mapDomainAlgHom R R f) (by ext; simp) (by ext; simp) +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapDomainBialgHom_id : mapDomainBialgHom R (.id M) = .id R R[M] := by ext; simp +set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapDomainBialgHom_comp (f : N →* O) (g : M →* N) : mapDomainBialgHom R (f.comp g) = (mapDomainBialgHom R f).comp (mapDomainBialgHom R g) := by diff --git a/Mathlib/RingTheory/ChainOfDivisors.lean b/Mathlib/RingTheory/ChainOfDivisors.lean index 47cb494adcd3e2..908e92259e985d 100644 --- a/Mathlib/RingTheory/ChainOfDivisors.lean +++ b/Mathlib/RingTheory/ChainOfDivisors.lean @@ -244,8 +244,10 @@ variable [UniqueFactorizationMonoid N] [UniqueFactorizationMonoid M] open DivisorChain + set_option linter.overlappingInstances false +set_option backward.isDefEq.respectTransparency false in theorem pow_image_of_prime_by_factor_orderIso_dvd {m p : Associates M} {n : Associates N} (hn : n ≠ 0) (hp : p ∈ normalizedFactors m) (d : Set.Iic m ≃o Set.Iic n) {s : ℕ} (hs' : p ^ s ≤ m) : diff --git a/Mathlib/RingTheory/ClassGroup/Basic.lean b/Mathlib/RingTheory/ClassGroup/Basic.lean index 32988180a9ca09..da61aa42c60676 100644 --- a/Mathlib/RingTheory/ClassGroup/Basic.lean +++ b/Mathlib/RingTheory/ClassGroup/Basic.lean @@ -455,6 +455,9 @@ theorem FractionalIdeal.map_ringEquivOfRingEquiv_toPrincipalIdeal {S L : Type*} ← FractionalIdeal.ringEquivOfRingEquiv_symm_eq, hu] rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A ring isomorphism `R ≃+* R'` induces an isomorphism on their class groups. -/ @[simps!] noncomputable def ClassGroup.mulEquiv {R' : Type*} [CommRing R'] [IsDomain R'] (g : R ≃+* R') : diff --git a/Mathlib/RingTheory/Coalgebra/Equiv.lean b/Mathlib/RingTheory/Coalgebra/Equiv.lean index aba0488b6a5684..660c33828b309f 100644 --- a/Mathlib/RingTheory/Coalgebra/Equiv.lean +++ b/Mathlib/RingTheory/Coalgebra/Equiv.lean @@ -246,6 +246,9 @@ theorem coe_symm_toEquiv : ⇑e.toEquiv.symm = e.symm := variable {e₁₂ : A ≃ₗc[R] B} {e₂₃ : B ≃ₗc[R] C} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Coalgebra equivalences are transitive. -/ @[trans, simps!] def trans (e₁₂ : A ≃ₗc[R] B) (e₂₃ : B ≃ₗc[R] C) : A ≃ₗc[R] C := diff --git a/Mathlib/RingTheory/Congruence/Hom.lean b/Mathlib/RingTheory/Congruence/Hom.lean index a3ad9e08b2f32b..403755222faf72 100644 --- a/Mathlib/RingTheory/Congruence/Hom.lean +++ b/Mathlib/RingTheory/Congruence/Hom.lean @@ -131,6 +131,7 @@ theorem mapGen_apply_apply_of_surjective refine ⟨fun ⟨a, b, h₁, h₂, h₃⟩ ↦ ?_, by grind⟩ exact c.trans (h h₂.symm) <| c.trans h₁ <| h h₃ +set_option backward.isDefEq.respectTransparency false in /-- Given a ring congruence relation `c` on a semiring `M`, the order-preserving bijection between the set of ring congruence relations containing `c` and the ring congruence relations on the quotient of `M` by `c`. -/ @@ -340,6 +341,7 @@ noncomputable def comapQuotientEquivOfSurj (c.comapQuotientEquivOfSurj f hf hcd).symm (f x) = x := by rw [← c.comapQuotientEquivOfSurj_mk hf hcd x, RingEquiv.symm_apply_apply] +set_option backward.isDefEq.respectTransparency false in /-- This version infers the surjectivity of the function from a RingEquiv function -/ @[simp] lemma comapQuotientEquivOfSurj_symm_mk' (c : RingCon M) (f : N ≃+* M) {d : RingCon N} (hcd : d = c.comap f) (x : N) : @@ -452,6 +454,7 @@ variable {R : Type*} [CommSemiring R] variable {c d : RingCon M} {f : M →ₐ[R] P} +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- An isomorphism of algebras `e : M ≃ₐ[R] N` generates an isomorphism between quotient spaces, if it is compatible with the relations. -/ diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index a54d2a53198216..d6bc071f7cafd0 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -232,6 +232,7 @@ theorem intValuation_lt_one_iff_mem (r : R) : v.intValuation r < 1 ↔ r ∈ v.asIdeal := by rw [intValuation_lt_one_iff_dvd, Ideal.dvd_span_singleton] +set_option backward.isDefEq.respectTransparency.types false in /-- The `v`-adic valuation of `r : R` is equal to 1 if and only if `r ∈ vᶜ`. -/ theorem intValuation_eq_one_iff_mem_primeCompl (r : R) : v.intValuation r = 1 ↔ r ∈ v.asIdeal.primeCompl := by @@ -327,12 +328,14 @@ theorem valuation_def (x : K) : v.intValuation.extendToLocalization (fun r hr => Set.mem_compl (v.intValuation_ne_zero' ⟨r, hr⟩)) K x := by rw [valuation] +set_option backward.isDefEq.respectTransparency.types false in /-- The `v`-adic valuation of `r / s : K` is the valuation of `r` divided by the valuation of `s`. -/ theorem valuation_of_mk' {r : R} {s : nonZeroDivisors R} : v.valuation K (IsLocalization.mk' K r s) = v.intValuation r / v.intValuation s := by rw [valuation_def, Valuation.extendToLocalization_mk', div_eq_mul_inv] +set_option backward.isDefEq.respectTransparency.types false in open scoped algebraMap in /-- The `v`-adic valuation on `K` extends the `v`-adic valuation on `R`. -/ theorem valuation_of_algebraMap (r : R) : v.valuation K r = v.intValuation r := by @@ -578,7 +581,7 @@ ring of integers, denoted `v.adicCompletionIntegers`. -/ /-- `K` as a valued field with the `v`-adic valuation. -/ -@[implicit_reducible] +@[instance_reducible] def adicValued : Valued K ℤᵐ⁰ := Valued.mk' (v.valuation K) diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index a09fb58226ff46..630a7421db36a6 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -149,8 +149,7 @@ lemma map_equiv_traceDual [IsDomain A] [IsFractionRing B L] [IsDomain B] traceDual A K (I.map (FractionRing.algEquiv B L).toLinearEquiv.toLinearMap) rw [Submodule.map_equiv_eq_comap_symm, Submodule.map_equiv_eq_comap_symm] ext x - simp only [traceDual, Submodule.mem_comap, - Submodule.mem_mk] + simp only [traceDual, Submodule.mem_comap] apply (FractionRing.algEquiv B L).forall_congr simp only [restrictScalars_mem, LinearEquiv.coe_coe, AlgEquiv.coe_symm_toLinearEquiv, traceForm_apply, mem_one, AlgEquiv.toEquiv_eq_coe, EquivLike.coe_coe, mem_comap, @@ -260,6 +259,7 @@ local notation:max I:max "ᵛ" => Submodule.traceDual A K I variable [IsDedekindDomain B] {I J : FractionalIdeal B⁰ L} +set_option backward.isDefEq.respectTransparency.types false in lemma coe_dual (hI : I ≠ 0) : (dual A K I : Submodule B L) = Iᵛ := by rw [dual, dif_neg hI, coe_mk] @@ -271,12 +271,14 @@ lemma coe_dual_one : rw [← coe_one, coe_dual] exact one_ne_zero +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma dual_zero : dual A K (0 : FractionalIdeal B⁰ L) = 0 := by rw [dual, dif_pos rfl] variable {A K L B} +set_option backward.isDefEq.respectTransparency.types false in lemma mem_dual (hI : I ≠ 0) {x} : x ∈ dual A K I ↔ ∀ a ∈ I, traceForm K L x a ∈ (algebraMap A K).range := by rw [dual, dif_neg hI]; exact forall₂_congr fun _ _ ↦ mem_one @@ -313,6 +315,7 @@ lemma dual_ne_zero_iff : variable (A K) +set_option backward.isDefEq.respectTransparency.types false in lemma le_dual_inv_aux (hI : I ≠ 0) (hIJ : I * J ≤ 1) : J ≤ dual A K I := by rw [dual, dif_neg hI] diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 969f6ebc069e57..6d8557b393a511 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -206,6 +206,7 @@ theorem finprod_heightOneSpectrum_factorization {I : Ideal R} (hI : I ≠ 0) : apply Ideal.finprod_count ⟨J, Ideal.isPrime_of_prime (irreducible_iff_prime.mp hv), Irreducible.ne_zero hv⟩ I hI +set_option backward.isDefEq.respectTransparency.types false in /-- The ideal `I` equals the inf `⨅_v v^(val_v(I))`. -/ theorem iInf_maxPowDividing_eq {I : Ideal R} (h0 : I ≠ 0) : ⨅ i : HeightOneSpectrum R, i.maxPowDividing I = I := by @@ -515,6 +516,7 @@ theorem count_finsuppProd (exps : HeightOneSpectrum R →₀ ℤ) : exps.mem_support_iff, ne_eq, ite_not, ite_eq_right_iff, @eq_comm ℤ 0, imp_self] · exact fun v hv ↦ zpow_ne_zero _ (coeIdeal_ne_zero.mpr v.ne_bot) +set_option backward.isDefEq.respectTransparency.types false in /-- If `exps` is finitely supported, then `val_v(∏_w w^{exps w}) = exps v`. -/ theorem count_finprod (exps : HeightOneSpectrum R → ℤ) (h_exps : ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite, exps v = 0) : diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index 8d27d22e0c4558..1b90cf37833abd 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -589,6 +589,7 @@ def comap (f : R →+* S) (hf : Function.Surjective f) (v : HeightOneSpectrum S) isPrime := v.asIdeal.comap_isPrime f ne_bot := (Ideal.eq_bot_of_comap_eq_bot' hf).mt v.ne_bot +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism between `HeightOneSpectrum`s of isomorphic rings. -/ @[simps] def equivOfRingEquiv (e : R ≃+* S) : (HeightOneSpectrum R) ≃ (HeightOneSpectrum S) where @@ -695,6 +696,7 @@ theorem idealFactorsEquivOfQuotEquiv_symm : @[deprecated (since := "2026-04-16")] alias _root_.idealFactorsEquivOfQuotEquiv_symm := idealFactorsEquivOfQuotEquiv_symm +set_option backward.isDefEq.respectTransparency.types false in theorem idealFactorsEquivOfQuotEquiv_is_dvd_iso {L M : Ideal R} (hL : L ∣ I) (hM : M ∣ I) : (idealFactorsEquivOfQuotEquiv f ⟨L, hL⟩ : Ideal A) ∣ idealFactorsEquivOfQuotEquiv f ⟨M, hM⟩ ↔ L ∣ M := by @@ -755,6 +757,7 @@ theorem normalizedFactorsEquivOfQuotEquiv_symm (hI : I ≠ ⊥) (hJ : J ≠ ⊥) @[deprecated (since := "2026-04-16")] alias _root_.normalizedFactorsEquivOfQuotEquiv_symm := normalizedFactorsEquivOfQuotEquiv_symm +set_option backward.isDefEq.respectTransparency.types false in /-- The map `normalizedFactorsEquivOfQuotEquiv` preserves multiplicities. -/ theorem normalizedFactorsEquivOfQuotEquiv_emultiplicity_eq_emultiplicity (hI : I ≠ ⊥) (hJ : J ≠ ⊥) (L : Ideal R) (hL : L ∈ normalizedFactors I) : @@ -1054,6 +1057,7 @@ alias _root_.emultiplicity_eq_emultiplicity_span := emultiplicity_eq_emultiplici section NormalizationMonoid variable [NormalizationMonoid R] +set_option backward.isDefEq.respectTransparency.types false in /-- The bijection between the (normalized) prime factors of `r` and the (normalized) prime factors of `span {r}` -/ noncomputable def normalizedFactorsEquivSpanNormalizedFactors {r : R} (hr : r ≠ 0) : @@ -1084,6 +1088,7 @@ noncomputable def normalizedFactorsEquivSpanNormalizedFactors {r : R} (hr : r alias _root_.normalizedFactorsEquivSpanNormalizedFactors := normalizedFactorsEquivSpanNormalizedFactors +set_option backward.isDefEq.respectTransparency.types false in /-- The bijection `normalizedFactorsEquivSpanNormalizedFactors` between the set of prime factors of `r` and the set of prime factors of the ideal `⟨r⟩` preserves multiplicities. See `count_normalizedFactorsSpan_eq_count` for the version stated in terms of multisets `count`. -/ diff --git a/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean b/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean index 7f5e41afbd3b09..2a95d81f1d7ff8 100644 --- a/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean +++ b/Mathlib/RingTheory/DedekindDomain/IntegralClosure.lean @@ -57,6 +57,7 @@ variable [Algebra K L] [Algebra A L] [IsScalarTower A K L] variable [Algebra C L] [IsIntegralClosure C A L] [Algebra A C] [IsScalarTower A C L] include K L +set_option backward.isDefEq.respectTransparency.types false in /-- If `L` is an algebraic extension of `K = Frac(A)` and `L` has no zero smul divisors by `A`, then `L` is the localization of the integral closure `C` of `A` in `L` at `A⁰`. -/ theorem IsIntegralClosure.isLocalization [IsDomain A] [Algebra.IsAlgebraic K L] : diff --git a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean index d577397592f4f6..f783414a6c8129 100644 --- a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean +++ b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean @@ -92,6 +92,7 @@ def valuationOfNeZeroToFun (x : Kˣ) : Multiplicative ℤ := (-(Associates.mk v.asIdeal).count (Associates.mk <| Ideal.span {hx.fst}).factors : ℤ) - (-(Associates.mk v.asIdeal).count (Associates.mk <| Ideal.span {(hx.snd : R)}).factors : ℤ) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem valuationOfNeZeroToFun_eq (x : Kˣ) : (v.valuationOfNeZeroToFun x : ℤᵐ⁰) = v.valuation K x := by diff --git a/Mathlib/RingTheory/Derivation/Basic.lean b/Mathlib/RingTheory/Derivation/Basic.lean index e96b31f91bcc44..e0e05c8fe1fa73 100644 --- a/Mathlib/RingTheory/Derivation/Basic.lean +++ b/Mathlib/RingTheory/Derivation/Basic.lean @@ -264,6 +264,7 @@ variable {N : Type*} [AddCommMonoid N] [Module A N] [Module R N] [IsScalarTower variable (f : M →ₗ[A] N) (e : M ≃ₗ[A] N) +set_option backward.isDefEq.respectTransparency false in /-- We can push forward derivations using linear maps, i.e., the composition of a derivation with a linear map is a derivation. Furthermore, this operation is linear on the spaces of derivations. -/ def _root_.LinearMap.compDer : Derivation R A M →ₗ[A] Derivation R A N where @@ -360,6 +361,7 @@ variable [CommSemiring R] [CommRing A] [CommRing M] variable [Algebra R A] [Algebra R M] variable {F : Type*} [FunLike F A M] [AlgHomClass F R A M] +set_option backward.isDefEq.respectTransparency false in /-- Lift a derivation via an algebra homomorphism `f` with a right inverse such that `f(x) = 0 → f(d(x)) = 0`. This gives the derivation `f ∘ d ∘ f⁻¹`. diff --git a/Mathlib/RingTheory/Derivation/Lie.lean b/Mathlib/RingTheory/Derivation/Lie.lean index 429226fca411a9..fc186eeee75297 100644 --- a/Mathlib/RingTheory/Derivation/Lie.lean +++ b/Mathlib/RingTheory/Derivation/Lie.lean @@ -75,6 +75,7 @@ section CompatibleDerivations variable {A' : Type*} [CommRing A'] [Algebra R A'] [Algebra A A'] [IsScalarTower R A A'] attribute [local instance 100] LieRing.ofAssociativeRing +set_option backward.isDefEq.respectTransparency false in variable (R A A') in /-- Let `σ : A → A'` be a an homomorphism. A derivation `d : A → A` and a derivation `d' : A' → A'` are called compatible if `d' ∘ σ = σ ∘ d`. Couples of derivations diff --git a/Mathlib/RingTheory/Derivation/MapCoeffs.lean b/Mathlib/RingTheory/Derivation/MapCoeffs.lean index 6871bfa814a8ed..06b1d3228f45d9 100644 --- a/Mathlib/RingTheory/Derivation/MapCoeffs.lean +++ b/Mathlib/RingTheory/Derivation/MapCoeffs.lean @@ -52,6 +52,7 @@ def mapCoeffs : Derivation R A[X] (PolynomialModule A M) where @[simp] lemma mapCoeffs_apply (p : A[X]) (i) : (d.mapCoeffs p).coeff i = d (coeff p i) := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mapCoeffs_monomial (n : ℕ) (x : A) : d.mapCoeffs (monomial n x) = .single A n (d x) := by @@ -80,6 +81,7 @@ theorem apply_aeval_eq' (d' : Derivation R B M') (f : M →ₗ[A] M') _root_.map_natCast, h] rw [add_comm, ← smul_smul, ← smul_smul, Nat.cast_smul_eq_nsmul] +set_option backward.isDefEq.respectTransparency.types false in theorem apply_aeval_eq [IsScalarTower R A B] [IsScalarTower A B M'] (d : Derivation R B M') (x : B) (p : A[X]) : d (aeval x p) = @@ -109,6 +111,7 @@ def mapCoeffs : Derivation ℤ A[X] A[X] := lemma coeff_mapCoeffs (p : A[X]) (i) : coeff (mapCoeffs p) i = (coeff p i)′ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma mapCoeffs_monomial (n : ℕ) (x : A) : mapCoeffs (monomial n x) = monomial n x′ := by @@ -124,6 +127,7 @@ lemma mapCoeffs_C (x : A) : variable {R : Type*} [CommRing R] [Differential R] [Algebra A R] [DifferentialAlgebra A R] +set_option backward.isDefEq.respectTransparency.types false in theorem deriv_aeval_eq (x : R) (p : A[X]) : (aeval x p)′ = aeval x (mapCoeffs p) + aeval x (derivative p) * x′ := by convert! Derivation.apply_aeval_eq' Differential.deriv _ (Algebra.linearMap A R) .. diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index a3d516d25001d3..3b66c2607c8ad4 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -508,6 +508,7 @@ lemma addVal_eq_iff_associated (x y : R) : variable (R) +set_option backward.isDefEq.respectTransparency.types false in /-- The ideals of a discrete valuation ring are exactly the powers of the maximal ideal. -/ @[simps apply] noncomputable def idealOrderIsoENat : Ideal R ≃o ENatᵒᵈ where @@ -546,6 +547,7 @@ theorem idealOrderIsoENat_symm_apply_coe_of_irreducible (n : ℕ) {ϖ : R} (hϖ (idealOrderIsoENat R).symm n = Ideal.span {ϖ ^ n} := by rw [idealOrderIsoENat_symm_apply_coe, hϖ.maximalIdeal_eq, span_singleton_pow] +set_option backward.isDefEq.respectTransparency.types false in theorem coheight_pow_maximalIdeal (n : ℕ) : Order.coheight (maximalIdeal R ^ n) = n := by simpa only [Order.coheight_toDual, Order.height_enat] using! Order.coheight_orderIso (idealOrderIsoENat R).symm (.toDual n) @@ -617,7 +619,7 @@ variable (R) in only takes two steps to terminate. Given `GCD(x,y)`, if `x ∣ y` then `y%x = 0` so we're done in one step; otherwise `y%x = y` and then `GCD(x,y) = GCD(y,x)` which brings us back to the first case. See `EuclideanDomain.to_principal_ideal_domain` for EuclideanDomain ⇒ PID. -/ -@[implicit_reducible] +@[instance_reducible] def toEuclideanDomain : EuclideanDomain R where quotient := quotient quotient_zero x := by simp [quotient] diff --git a/Mathlib/RingTheory/DividedPowers/Padic.lean b/Mathlib/RingTheory/DividedPowers/Padic.lean index 5b243cdcfd5d1c..53a15185fa2b95 100644 --- a/Mathlib/RingTheory/DividedPowers/Padic.lean +++ b/Mathlib/RingTheory/DividedPowers/Padic.lean @@ -130,6 +130,7 @@ private theorem dpow'_mem {n : ℕ} {x : ℤ_[p]} (hm : n ≠ 0) (hx : x ∈ Ide simp only [cast_one, zpow_neg_one] exact dpow'_norm_le_of_ne_zero p hm hx +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- The family `ℕ → Ideal.span {(p : ℤ_[p])} → ℤ_[p]` given by `dpow n x = x ^ n / n!` is a @@ -149,6 +150,7 @@ noncomputable def dividedPowers : DividedPowers (Ideal.span {(p : ℤ_[p])}) := open Function +set_option backward.isDefEq.respectTransparency false in private lemma dividedPowers_eq (n : ℕ) (x : ℤ_[p]) : (dividedPowers p).dpow n x = open scoped Classical in if hx : x ∈ Ideal.span {(p : ℤ_[p])} then ⟨dpow' p n x, dpow'_int p n hx⟩ else 0 := by @@ -163,6 +165,7 @@ private lemma dividedPowers_eq (n : ℕ) (x : ℤ_[p]) : RatAlgebra.dpow_apply, Submodule.mem_top] using! heq.symm · rfl +set_option backward.isDefEq.respectTransparency false in lemma coe_dpow_eq (n : ℕ) (x : ℤ_[p]) : ((dividedPowers p).dpow n x : ℚ_[p]) = open scoped Classical in if _ : x ∈ Ideal.span {(p : ℤ_[p])} then inverse (n ! : ℚ_[p]) * x ^ n else 0 := by diff --git a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean index 5b6ff9563584bf..8ca315ed1a4528 100644 --- a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean +++ b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean @@ -345,6 +345,7 @@ instance : SupSet (SubDPIdeal hI) := theorem sSup_carrier_def (S : Set (SubDPIdeal hI)) : (sSup S).carrier = sSup ((toIdeal) '' S) := rfl +set_option backward.isDefEq.respectTransparency false in instance : CompleteLattice (SubDPIdeal hI) := by refine Function.Injective.completeLattice (fun J : SubDPIdeal hI ↦ (J : Set.Iic I)) (fun J J' h ↦ by simpa only [SubDPIdeal.ext_iff, Subtype.mk.injEq] using h) diff --git a/Mathlib/RingTheory/Etale/Basic.lean b/Mathlib/RingTheory/Etale/Basic.lean index a871c5bde780f1..9dbcb40ff16f7e 100644 --- a/Mathlib/RingTheory/Etale/Basic.lean +++ b/Mathlib/RingTheory/Etale/Basic.lean @@ -141,7 +141,6 @@ lemma iff_of_surjective section BaseChange -open scoped TensorProduct instance [FormallyEtale R A] : FormallyEtale B (B ⊗[R] A) := .of_formallyUnramified_and_formallySmooth diff --git a/Mathlib/RingTheory/Etale/Kaehler.lean b/Mathlib/RingTheory/Etale/Kaehler.lean index 4fea33431d1202..7831c3c5a67739 100644 --- a/Mathlib/RingTheory/Etale/Kaehler.lean +++ b/Mathlib/RingTheory/Etale/Kaehler.lean @@ -230,6 +230,7 @@ def tensorCotangent [alg : Algebra P.Ring Q.Ring] (halg : algebraMap P.Ring Q.Ri simp only [LinearMap.liftBaseChange_tmul, map_smul] simp [Hom.mapKer, tensorCotangentInvFun_smul_mk] } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `J ≃ Q ⊗ₚ I`, `S → T` is flat and `P → Q` is formally étale, then `T ⊗ H¹(L_P) ≃ H¹(L_Q)`. -/ noncomputable diff --git a/Mathlib/RingTheory/Etale/QuasiFinite.lean b/Mathlib/RingTheory/Etale/QuasiFinite.lean index 39fa3641085e44..c6239cdbe7e8fa 100644 --- a/Mathlib/RingTheory/Etale/QuasiFinite.lean +++ b/Mathlib/RingTheory/Etale/QuasiFinite.lean @@ -45,6 +45,7 @@ def Ideal.fiberIsoOfBijectiveResidueField (PrimeSpectrum.primesOverOrderIsoFiber ..).trans <| (PrimeSpectrum.comapEquiv e.toRingEquiv).trans (PrimeSpectrum.primesOverOrderIsoFiber ..).symm +set_option backward.isDefEq.respectTransparency.types false in lemma Ideal.comap_fiberIsoOfBijectiveResidueField_symm (H : Function.Bijective (Ideal.ResidueField.mapₐ p q (Algebra.ofId _ _) (q.over_def p))) (Q : p.primesOver S) : @@ -163,7 +164,7 @@ lemma Algebra.exists_notMem_and_isIntegral_forall_mem_of_ne_of_liesOver wlog hm0 : 0 < m generalizing m · refine this (m + 1) (by grind) (by simp) have hs₃q : s₃.1 ∉ q := fun h ↦ (show ↑s₂ ^ m * (s₁ * ↑s₂ ^ n) ∉ q from q.primeCompl.mul_mem - (pow_mem hs₂q _) (mul_mem hs₁q (pow_mem hs₂q _))) (hm ▸ Ideal.mul_mem_left _ _ h) + (pow_mem hs₂q _) (mul_mem hs₁q (pow_mem hs₂q _))) (hm ▸ Ideal.mul_mem_left _ _ h) refine ⟨↑s₂ ^ m * ↑s₃, q.primeCompl.mul_mem (pow_mem hs₂q _) hs₃q, (s₂ ^ m * s₃).2, fun q' _ hq'q _ ↦ hm ▸ Ideal.mul_mem_left _ _ (Ideal.mul_mem_right _ _ (hs₁ q' ‹_› hq'q ‹_›)), fun q' _ hq'q _ ↦ ?_⟩ diff --git a/Mathlib/RingTheory/Etale/StandardEtale.lean b/Mathlib/RingTheory/Etale/StandardEtale.lean index 20862b46b49bb7..f7617b61a44784 100644 --- a/Mathlib/RingTheory/Etale/StandardEtale.lean +++ b/Mathlib/RingTheory/Etale/StandardEtale.lean @@ -196,6 +196,7 @@ to not abuse the defeq between the two. -/ def equivPolynomialQuotient : P.Ring ≃ₐ[R] R[X][Y] ⧸ Ideal.span {C P.f, Y * C P.g - 1} := .refl .. +set_option backward.isDefEq.respectTransparency.types false in /-- `R[X][Y]/⟨f, Yg-1⟩ ≃ (R[X]/f)[1/g]` -/ def equivAwayAdjoinRoot : P.Ring ≃ₐ[R] Localization.Away (AdjoinRoot.mk P.f P.g) := by @@ -208,6 +209,7 @@ def equivAwayAdjoinRoot : · ext; simp [Algebra.algHom] · ext; simp +set_option backward.isDefEq.respectTransparency.types false in /-- `R[X][Y]/⟨f, Yg-1⟩ ≃ R[X][1/g]/f` -/ def equivAwayQuotient : P.Ring ≃ₐ[R] Localization.Away P.g ⧸ Ideal.span {algebraMap _ (Localization.Away P.g) P.f} := by @@ -278,6 +280,7 @@ lemma StandardEtalePresentation.equivRing_symm_X : P.equivRing.symm P.X = P.x := lemma StandardEtalePresentation.equivRing_x : P.equivRing P.x = P.X := (P.equivRing.symm_apply_eq.mp P.equivRing_symm_X).symm +set_option backward.isDefEq.respectTransparency.types false in /-- The `Algebra.Presentation` associated to a standard etale presentation. -/ @[simps! relation val] def StandardEtalePresentation.toPresentation : Algebra.Presentation R S (Fin 2) (Fin 2) where @@ -294,6 +297,7 @@ def StandardEtalePresentation.toPresentation : Algebra.Presentation R S (Fin 2) RingHom.ker_comp_of_injective _ (by exact P.equivMvPolynomialQuotient.symm.injective)] simp [Set.pair_comm] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma StandardEtalePresentation.aeval_val_equivMvPolynomial (p : R[X]) : MvPolynomial.aeval P.toPresentation.val (Bivariate.equivMvPolynomial R (.C p)) = p.aeval P.x := by @@ -307,6 +311,7 @@ attribute [local simp] Algebra.PreSubmersivePresentation.jacobian_eq_jacobiMatri Polynomial.Bivariate.pderiv_zero_equivMvPolynomial Polynomial.Bivariate.pderiv_one_equivMvPolynomial +set_option backward.isDefEq.respectTransparency.types false in /-- The `Algebra.SubmersivePresentation` associated to a standard etale presentation. -/ @[simps map toPreSubmersivePresentation_toPresentation] def StandardEtalePresentation.toSubmersivePresentation : @@ -316,10 +321,12 @@ def StandardEtalePresentation.toSubmersivePresentation : map_inj := Function.injective_id jacobian_isUnit := by simp [P.hasMap.2, P.hasMap.isUnit_derivative_f] +set_option backward.isDefEq.respectTransparency.types false in lemma StandardEtalePresentation.toSubmersivePresentation_jacobian : P.toSubmersivePresentation.jacobian = aeval P.x P.f.derivative * aeval P.x P.g := by simp [StandardEtalePresentation.toSubmersivePresentation] +set_option backward.isDefEq.respectTransparency.types false in lemma StandardEtalePresentation.exists_mul_aeval_x_g_pow_eq_aeval_x (x : S) : ∃ p : R[X], ∃ n, x * P.g.aeval P.x ^ n = p.aeval P.x := by obtain ⟨x, rfl⟩ := (P.equivRing.trans P.P.equivAwayAdjoinRoot).symm.surjective x @@ -329,6 +336,7 @@ lemma StandardEtalePresentation.exists_mul_aeval_x_g_pow_eq_aeval_x (x : S) : simpa [← aeval_algHom_apply, StandardEtalePair.equivAwayAdjoinRoot, ← aeval_def] using congr(P.equivAwayAdjoinRoot.symm $e) +set_option backward.isDefEq.respectTransparency.types false in /-- Mapping `StandardEtalePresentation` under `AlgEquiv`s. -/ def StandardEtalePresentation.mapEquiv (e : S ≃ₐ[R] T) : StandardEtalePresentation R T where P := P.P @@ -346,6 +354,7 @@ lemma StandardEtalePresentation.hom_ext {f₁ f₂ : S →ₐ[R] T} (h : f₁ P. open scoped TensorProduct +set_option backward.isDefEq.respectTransparency.types false in /-- The base change of a standard etale algebra is standard etale. -/ noncomputable def StandardEtalePresentation.baseChange : @@ -392,6 +401,7 @@ instance : IsStandardEtale R R := (by ext) (by ext; simp [this]) exact e.bijective⟩⟩⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma IsStandardEtale.of_isLocalizationAway [IsStandardEtale R S] {Sₛ : Type*} [CommRing Sₛ] [Algebra S Sₛ] [Algebra R Sₛ] [IsScalarTower R S Sₛ] (s : S) [IsLocalization.Away s Sₛ] : diff --git a/Mathlib/RingTheory/Etale/Weakly.lean b/Mathlib/RingTheory/Etale/Weakly.lean index a9d2e767e8f96d..eaca184bed284e 100644 --- a/Mathlib/RingTheory/Etale/Weakly.lean +++ b/Mathlib/RingTheory/Etale/Weakly.lean @@ -42,6 +42,7 @@ attribute [instance] WeaklyEtale.flat namespace WeaklyEtale +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] ULift.algebra' in lemma ulift_iff : WeaklyEtale (ULift.{u₁} R) (ULift.{u₂} S) ↔ WeaklyEtale R S := by rw [weaklyEtale_iff, weaklyEtale_iff, Module.Flat.ulift_left_iff, Module.Flat.ulift_right_iff] diff --git a/Mathlib/RingTheory/EuclideanDomain.lean b/Mathlib/RingTheory/EuclideanDomain.lean index 4a4886ca992141..5cb9cba539d06d 100644 --- a/Mathlib/RingTheory/EuclideanDomain.lean +++ b/Mathlib/RingTheory/EuclideanDomain.lean @@ -69,7 +69,7 @@ end GCDMonoid namespace EuclideanDomain /-- Create a `GCDMonoid` whose `GCDMonoid.gcd` matches `EuclideanDomain.gcd`. -/ -@[implicit_reducible] +@[instance_reducible] def gcdMonoid (R) [EuclideanDomain R] [DecidableEq R] : GCDMonoid R where gcd := gcd lcm := lcm diff --git a/Mathlib/RingTheory/Extension/Basic.lean b/Mathlib/RingTheory/Extension/Basic.lean index 46099df0ef9d58..d47b5ad3073e0b 100644 --- a/Mathlib/RingTheory/Extension/Basic.lean +++ b/Mathlib/RingTheory/Extension/Basic.lean @@ -363,6 +363,7 @@ lemma Cotangent.smul_eq_zero_of_mem (p : P.Ring) (hp : p ∈ P.ker) (m : P.ker.C attribute [local simp] RingHom.mem_ker +set_option backward.isDefEq.respectTransparency.types false in noncomputable instance Cotangent.module : Module S P.Cotangent where smul := fun r s ↦ .of (P.σ r • s.val) @@ -391,10 +392,12 @@ instance {R₁ R₂} [CommRing R₁] [CommRing R₂] [Algebra R₁ S] [Algebra R change algebraMap R₂ S (r • s) • m = (algebraMap _ S r) • (algebraMap _ S s) • m rw [Algebra.smul_def, map_mul, mul_smul, ← IsScalarTower.algebraMap_apply] +set_option backward.isDefEq.respectTransparency.types false in /-- The action of `R₀` on `P.Cotangent` for an extension `P → S`, if `S` is an `R₀` algebra. -/ lemma Cotangent.val_smul''' {R₀} [CommRing R₀] [Algebra R₀ S] (r : R₀) (x : P.Cotangent) : (r • x).val = P.σ (algebraMap R₀ S r) • x.val := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- The action of `S` on `P.Cotangent` for an extension `P → S`. -/ @[simp] lemma Cotangent.val_smul (r : S) (x : P.Cotangent) : (r • x).val = P.σ r • x.val := rfl diff --git a/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean b/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean index 15d96abefdd774..a173e7618d6da4 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/BaseChange.lean @@ -67,6 +67,7 @@ def tensorCotangentSpace (P : Extension.{u} R S) (T : Type*) [CommRing T] [Algeb (AlgebraTensorModule.congr (LinearEquiv.refl PT.Ring (T ⊗[R] S)) (KaehlerDifferential.tensorKaehlerEquiv R T P.Ring PT.Ring)).restrictScalars T +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] algebraBaseChange in lemma tensorCotangentSpace_tmul_tmul (t : T) (s : S) (x : Ω[P.Ring⁄R]) : P.tensorCotangentSpace T (t ⊗ₜ (s ⊗ₜ x)) = t ⊗ₜ s ⊗ₜ KaehlerDifferential.map _ _ _ _ x := by @@ -101,6 +102,7 @@ lemma tensorCotangentSpace_tmul (t : T) (x : P.CotangentSpace) : simp [tensorCotangentSpace_tmul_tmul, CotangentSpace.map_tmul_eq_tmul_map, smul_tmul', Algebra.smul_def, RingHom.algebraMap_toAlgebra] +set_option backward.isDefEq.respectTransparency.types false in /-- If `T` is flat over `R`, there is a `T`-linear isomorphism `T ⊗[R] P.Cotangent ≃ₗ[T] (P.baseChange).Cotangent`. -/ noncomputable def tensorCotangentOfFlat [Module.Flat R T] : @@ -110,6 +112,7 @@ noncomputable def tensorCotangentOfFlat [Module.Flat R T] : (Ideal.Cotangent.equivOfEq _ _ (P.ker_baseChange T).symm).restrictScalars T ≪≫ₗ (P.baseChange (T := T)).cotangentEquivCotangentKer.symm.restrictScalars T +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] Algebra.TensorProduct.rightAlgebra in @[simp] lemma tensorCotangentOfFlat_tmul [Module.Flat R T] (t : T) (x : P.Cotangent) : @@ -135,6 +138,7 @@ lemma tensorToH1Cotangent_tmul (t : T) (x : P.H1Cotangent) : (P.tensorToH1Cotangent T (t ⊗ₜ x)).val = t • Cotangent.map (P.toBaseChange T) x.val := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- If `T` is `R`-flat, the canonical map `T ⊗[R] P.H1Cotangent →ₗ[T] (P.baseChange T).H1Cotangent` is bijective. -/ lemma tensorToH1Cotangent_bijective_of_flat [Module.Flat R T] : @@ -201,6 +205,7 @@ noncomputable def tensorH1CotangentOfFlat (T : Type*) [CommRing T] [Algebra R T] ((Generators.self R S).baseChangeToBaseChange T)).restrictScalars T ≪≫ₗ ((Generators.self R S).baseChange (T := T)).equivH1Cotangent.restrictScalars T +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] TensorProduct.rightAlgebra in lemma tensorH1CotangentOfFlat_tmul (T : Type*) [CommRing T] [Algebra R T] [Module.Flat R T] (t : T) (x : H1Cotangent R S) : diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean index 7ca1974ccb3ffb..8662f8397efd44 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean @@ -403,6 +403,7 @@ def H1Cotangent.map (f : Hom P P') : P.H1Cotangent →ₗ[S] P'.H1Cotangent := b rw [hx] exact LinearMap.map_zero _ +set_option backward.isDefEq.respectTransparency.types false in lemma H1Cotangent.map_eq (f g : Hom P P') : map f = map g := by ext x simp only [map_apply_coe] @@ -410,8 +411,10 @@ lemma H1Cotangent.map_eq (f g : Hom P P') : map f = map g := by simp only [LinearMap.coe_comp, Function.comp_apply, LinearMap.map_coe_ker, map_zero, Cotangent.val_zero] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma H1Cotangent.map_id : map (.id P) = LinearMap.id := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in omit [IsScalarTower R S S'] in lemma H1Cotangent.map_comp (f : Hom P P') (g : Hom P' P'') : diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index 10451df60b2326..6a4cc4ce7b839a 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -132,6 +132,7 @@ lemma ker_presLeft_le : D.presLeft.ker ≤ P.ker := by toExtension_algebra₂, algebraMap_apply, Ideal.Quotient.algebraMap_eq, map_zero] using! (algebraMap D.T S).congr_arg hx +set_option backward.isDefEq.respectTransparency.types false in /-- The forward direction of the isomorphism `S ⊗[T] J/J² ≃ₗ[S] I/I²`. -/ def tensorCotangentHom : S ⊗[D.T] D.presLeft.toExtension.Cotangent →ₗ[S] P.toExtension.Cotangent := LinearMap.liftBaseChange _ (Extension.Cotangent.map D.fhom.toExtensionHom) @@ -155,6 +156,7 @@ lemma tensorCotangentInv_apply (i : σ) : D.tensorCotangentInv (b i) = 1 ⊗ₜ Extension.Cotangent.mk (D.kerGen i) := Module.Basis.constr_basis _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma span_range_mk_kerGen : Submodule.span D.T (Set.range fun i ↦ Extension.Cotangent.mk (D.kerGen i)) = ⊤ := by @@ -234,6 +236,7 @@ set_option backward.isDefEq.respectTransparency false in def basisRight : Module.Basis Unit S D.presRight.toExtension.Cotangent := Generators.basisCotangentAway S D.gbar +set_option backward.isDefEq.respectTransparency.types false in /-- The basis on the cotangent space of the constructed presentation. -/ def basis [Nontrivial S] : Module.Basis (Unit ⊕ σ) S D.pres.toExtension.Cotangent := (Module.Basis.prod D.basisRight D.basisLeft).map D.cotangentEquivProd.symm @@ -244,6 +247,7 @@ lemma basis_inl [Nontrivial S] : D.cotangentEquivProd.symm (Generators.cMulXSubOneCotangent S D.gbar, 0) := by simpa [basis] using! Generators.basisCotangentAway_apply _ _ +set_option backward.isDefEq.respectTransparency.types false in lemma basis_inr [Nontrivial S] (i : σ) : D.basis (.inr i) = D.cotangentEquivProd.symm (0, D.basisLeft i) := by simp [basis] diff --git a/Mathlib/RingTheory/Extension/Cotangent/Free.lean b/Mathlib/RingTheory/Extension/Cotangent/Free.lean index 5bcd8bb910806b..4fb3164a872f3b 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Free.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Free.lean @@ -110,6 +110,7 @@ open Generators variable (P : PreSubmersivePresentation R S ι σ) [Finite σ] +set_option backward.isDefEq.respectTransparency.types false in /-- To show a pre-submersive presentation with kernel `I = (fᵢ)` is submersive, it suffices to show that the images of the `fᵢ` form a basis of `I/I²` and that the restricted cotangent complex `I/I² → S ⊗[R] (Ω[R[Xᵢ]⁄R]) = ⊕ᵢ S → ⊕ⱼ S` is bijective. -/ diff --git a/Mathlib/RingTheory/Extension/Cotangent/LocalizationAway.lean b/Mathlib/RingTheory/Extension/Cotangent/LocalizationAway.lean index 49004817c1c0a8..0afd7ec2764651 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/LocalizationAway.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/LocalizationAway.lean @@ -204,6 +204,7 @@ def cotangentCompLocalizationAwayEquiv : (liftBaseChange_injective_of_isLocalizationAway _ P) ⟨cotangentCompAwaySec g P x, map_comp_cotangentCompAwaySec g P hx⟩).1 +set_option backward.isDefEq.respectTransparency.types false in lemma cotangentCompLocalizationAwayEquiv_symm_inr : (cotangentCompLocalizationAwayEquiv g P hx).symm (0, cMulXSubOneCotangent T g) = x := by diff --git a/Mathlib/RingTheory/Extension/ExtendScalars.lean b/Mathlib/RingTheory/Extension/ExtendScalars.lean index 0037ec8ed4ea75..6a2412aac19475 100644 --- a/Mathlib/RingTheory/Extension/ExtendScalars.lean +++ b/Mathlib/RingTheory/Extension/ExtendScalars.lean @@ -125,6 +125,7 @@ def h1CotangentEquivCotangent {R : Type u} {S : Type v} [CommRing R] [CommRing S P.extendScalars.h1CotangentEquivOfSurjective Function.surjective_id ≪≫ₗ P.cotangentExtendScalarsEquiv +set_option backward.isDefEq.respectTransparency.types false in theorem cotangentComplex_comp_h1CotangentEquivCotangent (P : Extension.{w} R S) : P.cotangentComplex.comp P.h1CotangentEquivCotangent.toLinearMap = H1Cotangent.δ R P.Ring S := by @@ -141,6 +142,7 @@ theorem cotangentComplex_comp_h1CotangentEquivCotangent (P : Extension.{w} R S) rw [← Generators.H1Cotangent.δ_C _ _ u.prop] congr +set_option backward.isDefEq.respectTransparency.types false in theorem h1CotangentEquivCotangent_comp_map (P : Extension.{w} R S) : P.h1CotangentEquivCotangent.toLinearMap.comp (Algebra.H1Cotangent.map R P.Ring S S) = h1Cotangentι.comp (H1Cotangent.map P.defaultHom) := by diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index f434a77292e179..861b6e6f8d6686 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -223,6 +223,7 @@ end Localization variable {ι' : Type*} {T} [CommRing T] [Algebra R T] +set_option backward.isDefEq.respectTransparency.types false in /-- Given two families of generators `S[X] → T` and `R[Y] → S`, we may construct the family of generators `R[X, Y] → T`. -/ @[simps val, simps -isSimp σ] @@ -561,6 +562,7 @@ lemma toAlgHom_ofComp_rename (Q : Generators S T ι') (P : Generators R S ι) (p (IsScalarTower.toAlgHom R S Q.Ring).comp (IsScalarTower.toAlgHom R P.Ring S) := by ext; simp DFunLike.congr_fun this p +set_option backward.isDefEq.respectTransparency.types false in lemma toAlgHom_ofComp_surjective (Q : Generators S T ι') (P : Generators R S ι) : Function.Surjective (Q.ofComp P).toAlgHom := by intro p @@ -657,6 +659,7 @@ lemma ker_ofAlgEquiv (P : Generators R S ι) {T : Type*} [CommRing T] [Algebra R AlgHomClass.toRingHom_toAlgHom, AlgHom.ker_coe_equiv, ← RingHom.ker_eq_comap_bot, ← ker_eq_ker_aeval_val] +set_option backward.isDefEq.respectTransparency.types false in lemma map_toComp_ker (Q : Generators S T ι') (P : Generators R S ι) : P.ker.map (Q.toComp P).toAlgHom = RingHom.ker (Q.ofComp P).toAlgHom := by let : DecidableEq (ι' →₀ ℕ) := Classical.decEq _ @@ -748,6 +751,7 @@ def kerCompPreimage (Q : Generators S T ι') (P : Generators R S ι) (x : Q.ker) simp_rw [← IsScalarTower.toAlgHom_apply R, ← comp_aeval, AlgHom.comp_apply, P.aeval_val_σ, coeff] +set_option backward.isDefEq.respectTransparency.types false in lemma ofComp_kerCompPreimage (Q : Generators S T ι') (P : Generators R S ι) (x : Q.ker) : (Q.ofComp P).toAlgHom (kerCompPreimage Q P x) = x := by conv_rhs => rw [← x.1.support_sum_monomial_coeff] diff --git a/Mathlib/RingTheory/Extension/Presentation/Basic.lean b/Mathlib/RingTheory/Extension/Presentation/Basic.lean index 5a74e519600bc1..b0ef38f2f674cc 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Basic.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Basic.lean @@ -357,6 +357,7 @@ noncomputable def compRelationAux (r : σ') : MvPolynomial (ι' ⊕ ι) R := private lemma aux_X (i : ι' ⊕ ι) : (Q.aux P) (X i) = Sum.elim X (C ∘ P.val) i := aeval_X (Sum.elim X (C ∘ P.val)) i +set_option backward.isDefEq.respectTransparency.types false in /-- The pre-images constructed in `compRelationAux` are indeed pre-images under `aux`. -/ private lemma compRelationAux_map (r : σ') : (Q.aux P) (Q.compRelationAux P r) = Q.relation r := by diff --git a/Mathlib/RingTheory/Extension/Presentation/Core.lean b/Mathlib/RingTheory/Extension/Presentation/Core.lean index 14d4919f4ff948..caedd44508860c 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Core.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Core.lean @@ -165,6 +165,7 @@ noncomputable def tensorModelOfHasCoeffsInv : S →ₐ[R] R ⊗[R₀] P.ModelOfH Ideal.Quotient.mk_span_range, tmul_zero]).comp (P.quotientEquiv.restrictScalars R).symm.toAlgHom +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorModelOfHasCoeffsInv_aeval_val (x : MvPolynomial ι R₀) : P.tensorModelOfHasCoeffsInv R₀ (MvPolynomial.aeval P.val x) = @@ -172,6 +173,7 @@ lemma tensorModelOfHasCoeffsInv_aeval_val (x : MvPolynomial ι R₀) : rw [← MvPolynomial.aeval_map_algebraMap R, ← Generators.algebraMap_apply, ← quotientEquiv_mk] simp [tensorModelOfHasCoeffsInv, -quotientEquiv_symm, -quotientEquiv_mk] +set_option backward.isDefEq.respectTransparency.types false in lemma tensorModelOfHasCoeffsHom_comp : (P.tensorModelOfHasCoeffsHom R₀).comp (P.tensorModelOfHasCoeffsInv R₀) = AlgHom.id R S := by have h : Function.Surjective diff --git a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean index ddc93e16ab104e..bfbaa536a17318 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Submersive.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Submersive.lean @@ -348,7 +348,7 @@ private lemma jacobiMatrix_comp_₂₂_det : simp only [Matrix.toBlocks₂₂, AlgHom.mapMatrix_apply, Matrix.map_apply, Matrix.of_apply, RingHom.mapMatrix_apply, Generators.algebraMap_apply, map_aeval, coe_eval₂Hom] rw [jacobiMatrix_comp_inr_inr, ← IsScalarTower.algebraMap_eq] - simp only [aeval, AlgHom.coe_mk, coe_eval₂Hom] + simp only [aeval] generalize P.jacobiMatrix i j = p induction p using MvPolynomial.induction_on with | C a => diff --git a/Mathlib/RingTheory/Filtration.lean b/Mathlib/RingTheory/Filtration.lean index f909cc28ab729a..7c312b1d9c5563 100644 --- a/Mathlib/RingTheory/Filtration.lean +++ b/Mathlib/RingTheory/Filtration.lean @@ -331,6 +331,7 @@ theorem submodule_eq_span_le_iff_stable_ge (n₀ : ℕ) : · rw [PolynomialModule.single_add] exact F'.add_mem hx hy +set_option backward.isDefEq.respectTransparency.types false in /-- If the components of a filtration are finitely generated, then the filtration is stable iff its associated submodule of is finitely generated. -/ theorem submodule_fg_iff_stable (hF' : ∀ i, (F.N i).FG) : F.submodule.FG ↔ F.Stable := by diff --git a/Mathlib/RingTheory/Finiteness/Basic.lean b/Mathlib/RingTheory/Finiteness/Basic.lean index 32a08ddc924b89..48ec5fc228a02c 100644 --- a/Mathlib/RingTheory/Finiteness/Basic.lean +++ b/Mathlib/RingTheory/Finiteness/Basic.lean @@ -93,6 +93,7 @@ theorem FG.map {N : Submodule R M} (hs : N.FG) : (N.map f).FG := rw [LinearMap.range_eq_map] exact Module.Finite.fg_top.map f +set_option backward.isDefEq.respectTransparency false in theorem fg_of_fg_map_injective (hf : Function.Injective f) {N : Submodule R M} (hfn : (N.map f).FG) : N.FG := let ⟨t, ht⟩ := hfn diff --git a/Mathlib/RingTheory/Finiteness/FinitePresentationLocal.lean b/Mathlib/RingTheory/Finiteness/FinitePresentationLocal.lean index 0b759d65bcc3dc..7559dae28ba442 100644 --- a/Mathlib/RingTheory/Finiteness/FinitePresentationLocal.lean +++ b/Mathlib/RingTheory/Finiteness/FinitePresentationLocal.lean @@ -56,6 +56,7 @@ lemma of_span_eq_top_target_aux {A : Type*} [CommRing A] [Algebra R A] universe u +set_option backward.isDefEq.respectTransparency.types false in /-- Finite-presentation can be checked on a standard covering of the target. -/ lemma of_span_eq_top_target (s : Set S) (hs : Ideal.span (s : Set S) = ⊤) (h : ∀ i ∈ s, Algebra.FinitePresentation R (Localization.Away i)) : diff --git a/Mathlib/RingTheory/Flat/Equalizer.lean b/Mathlib/RingTheory/Flat/Equalizer.lean index 07fbc4cd1d5ead..766fec0bfe871c 100644 --- a/Mathlib/RingTheory/Flat/Equalizer.lean +++ b/Mathlib/RingTheory/Flat/Equalizer.lean @@ -109,6 +109,7 @@ def LinearMap.tensorKerInv [Module.Flat R M] : (Module.Flat.lTensor_preserves_injective_linearMap (ker f).subtype (ker f).injective_subtype) (by simp [Module.Flat.ker_lTensor_eq]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] private lemma LinearMap.lTensor_ker_subtype_tensorKerInv [Module.Flat R M] (x : ker (AlgebraTensorModule.lTensor S M f)) : @@ -127,6 +128,7 @@ def LinearMap.tensorEqLocusInv [Module.Flat R M] : (Module.Flat.lTensor_preserves_injective_linearMap (eqLocus f g).subtype (eqLocus f g).injective_subtype) (by simp [Module.Flat.eqLocus_lTensor_eq]) +set_option backward.isDefEq.respectTransparency.types false in @[simp] private lemma LinearMap.lTensor_eqLocus_subtype_tensorEqLocusInv [Module.Flat R M] (x : eqLocus (AlgebraTensorModule.lTensor S M f) (AlgebraTensorModule.lTensor S M g)) : diff --git a/Mathlib/RingTheory/Flat/Localization.lean b/Mathlib/RingTheory/Flat/Localization.lean index 1b54ac43aa720a..7e563a6e72d6a0 100644 --- a/Mathlib/RingTheory/Flat/Localization.lean +++ b/Mathlib/RingTheory/Flat/Localization.lean @@ -32,6 +32,7 @@ variable {R : Type*} (S : Type*) [CommSemiring R] [CommSemiring S] [Algebra R S] variable (p : Submonoid R) [IsLocalization p S] variable (M : Type*) [AddCommMonoid M] [Module R M] [Module S M] [IsScalarTower R S M] +set_option backward.isDefEq.respectTransparency.types false in include p in theorem IsLocalization.flat : Module.Flat R S := by refine Module.Flat.iff_lTensor_injectiveₛ.mpr fun P _ _ N ↦ ?_ diff --git a/Mathlib/RingTheory/FormalGroup/Basic.lean b/Mathlib/RingTheory/FormalGroup/Basic.lean index a397d7a32fbbee..c8411d4a0c4cd3 100644 --- a/Mathlib/RingTheory/FormalGroup/Basic.lean +++ b/Mathlib/RingTheory/FormalGroup/Basic.lean @@ -221,6 +221,7 @@ lemma coeff_one_Xzero : F.Xzero.coeff 1 = 1 := by simp [hd₁] · exact HasSubst.X_zero +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Xzero_subst_Xzero : F.Xzero.subst F.Xzero = F.Xzero := by calc @@ -272,6 +273,7 @@ lemma coeff_one_zeroX : F.zeroX.coeff 1 = 1 := by simp [hd₁] · exact HasSubst.zero_X +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma zeroX_subst_zeroX : F.zeroX.subst F.zeroX = F.zeroX := by calc diff --git a/Mathlib/RingTheory/FractionalIdeal/Basic.lean b/Mathlib/RingTheory/FractionalIdeal/Basic.lean index 25256416bf34ef..dfda75afb5880e 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Basic.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Basic.lean @@ -183,6 +183,7 @@ theorem coe_ext_iff {I J : FractionalIdeal S P} : theorem ext {I J : FractionalIdeal S P} : (∀ x, x ∈ I ↔ x ∈ J) → I = J := SetLike.ext +set_option backward.isDefEq.respectTransparency false in @[simp] theorem equivNum_apply [IsDomain R] [Module.IsTorsionFree R P] [Nontrivial P] {I : FractionalIdeal S P} (h_nz : (I.den : R) ≠ 0) (x : I) : @@ -558,6 +559,7 @@ instance : Mul (FractionalIdeal S P) := theorem mul_eq_mul (I J : FractionalIdeal S P) : mul I J = I * J := rfl +set_option backward.isDefEq.respectTransparency false in theorem mul_def (I J : FractionalIdeal S P) : I * J = ⟨I * J, I.isFractional.mul J.isFractional⟩ := by simp only [← mul_eq_mul, mul_def'] diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index 9f82c47edd5264..67a3cf90c533bf 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -183,6 +183,7 @@ lemma _root_.Units.submodule_isFractional [IsLocalization S P] (I : (Submodule R IsFractional S I.1 := FractionalIdeal.isFractional_of_fg (fg_unit _) +set_option backward.isDefEq.respectTransparency false in /-- If P is a localization of R, invertible R-submodules of P are all fractional (expressed as an isomorphism of groups). -/ def unitsMulEquivSubmodule [IsLocalization S P] : @@ -243,6 +244,7 @@ theorem canonicalEquiv_symm : (canonicalEquiv S P P').symm = canonicalEquiv S P' theorem canonicalEquiv_flip (I) : canonicalEquiv S P P' (canonicalEquiv S P' P I) = I := by rw [← canonicalEquiv_symm, RingEquiv.symm_apply_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem canonicalEquiv_canonicalEquiv (P'' : Type*) [CommRing P''] [Algebra R P''] [IsLocalization S P''] (I : FractionalIdeal S P) : @@ -255,6 +257,7 @@ theorem canonicalEquiv_trans_canonicalEquiv (P'' : Type*) [CommRing P''] [Algebr (canonicalEquiv S P P').trans (canonicalEquiv S P' P'') = canonicalEquiv S P P'' := RingEquiv.ext (canonicalEquiv_canonicalEquiv S P P' P'') +set_option backward.isDefEq.respectTransparency false in @[simp] theorem canonicalEquiv_coeIdeal (I : Ideal R) : canonicalEquiv S P P' I = I := by ext @@ -472,6 +475,7 @@ theorem mul_div_self_cancel_iff {I : FractionalIdeal R₁⁰ K} : I * (1 / I) = variable {K' : Type*} [Field K'] [Algebra R₁ K'] [IsFractionRing R₁ K'] +set_option backward.isDefEq.respectTransparency false in @[simp] protected theorem map_div (I J : FractionalIdeal R₁⁰ K) (h : K ≃ₐ[R₁] K') : (I / J).map (h : K →ₐ[R₁] K') = I.map h / J.map h := by @@ -604,6 +608,7 @@ theorem spanSingleton_eq_spanSingleton [IsDomain R] [Module.IsTorsionFree R P] { rw [← Submodule.span_singleton_eq_span_singleton, spanSingleton, spanSingleton] exact Subtype.mk_eq_mk +set_option backward.isDefEq.respectTransparency false in theorem eq_spanSingleton_of_principal (I : FractionalIdeal S P) [IsPrincipal (I : Submodule R P)] : I = spanSingleton S (generator (I : Submodule R P)) := by -- Porting note: this used to be `coeToSubmodule_injective (span_singleton_generator ↑I).symm` @@ -661,6 +666,7 @@ theorem coeIdeal_span_singleton (x : R) : refine ⟨y' * x, Submodule.mem_span_singleton.mpr ⟨y', rfl⟩, ?_⟩ rw [map_mul, Algebra.smul_def] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem canonicalEquiv_spanSingleton {P'} [CommRing P'] [Algebra R P'] [IsLocalization S P'] (x : P) : @@ -940,6 +946,7 @@ theorem _root_.IsFractional.mapEquiv {I : Submodule R K} (hI : IsFractional R⁰ rw [Algebra.smul_def, ← ringEquivOfRingEquiv_algebraMap f (K := K) (L := L) r, ← map_mul, ← Algebra.smul_def, ← hr', ringEquivOfRingEquiv_algebraMap] +set_option backward.isDefEq.respectTransparency.types false in /-- The equiv `FractionalIdeal R⁰ K ≃+* FractionalIdeal S⁰ L` induced by a ring isomorphism `f : R ≃+* S`. -/ @[simps -isSimp] @@ -968,15 +975,18 @@ noncomputable def ringEquivOfRingEquiv : convert! Submodule.map_id _ ext; simp [semilinearEquivOfRingEquiv, IsLocalization.map_map]} +set_option backward.isDefEq.respectTransparency.types false in lemma ringEquivOfRingEquiv_apply (f : R ≃+* S) (I : FractionalIdeal (nonZeroDivisors R) K) : ringEquivOfRingEquiv K L f I = ⟨Submodule.map (semilinearEquivOfRingEquiv _ _ f).toLinearMap I.val, IsFractional.mapEquiv K L f I.prop⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma ringEquivOfRingEquiv_apply_val (f : R ≃+* S) (I : FractionalIdeal R⁰ K) : (ringEquivOfRingEquiv K L f I).val = I.val.map (semilinearEquivOfRingEquiv _ _ f).toLinearMap := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma ringEquivOfRingEquiv_trans {T : Type*} [CommRing T] [IsDomain T] (M : Type*) [CommRing M] [Algebra T M] [IsFractionRing T M] (f : R ≃+* S) (g : S ≃+* T) : ringEquivOfRingEquiv K M (f.trans g) = @@ -994,6 +1004,7 @@ lemma ringEquivOfRingEquiv_trans_apply {T : Type*} [CommRing T] [IsDomain T] (M ringEquivOfRingEquiv L M g (ringEquivOfRingEquiv K L f I) := by simp [ringEquivOfRingEquiv_trans K L M] +set_option backward.isDefEq.respectTransparency.types false in lemma ringEquivOfRingEquiv_refl : ringEquivOfRingEquiv K K (RingEquiv.refl R) = RingEquiv.refl (FractionalIdeal R⁰ K) := by ext I x @@ -1001,6 +1012,7 @@ lemma ringEquivOfRingEquiv_refl : val_eq_coe, RingEquiv.refl_apply, ← mem_coe] simp [semilinearEquivOfRingEquiv] +set_option backward.isDefEq.respectTransparency.types false in lemma ringEquivOfRingEquiv_spanSingleton (x : K) : FractionalIdeal.ringEquivOfRingEquiv K L f (spanSingleton R⁰ x) = spanSingleton S⁰ (IsFractionRing.ringEquivOfRingEquiv (L := L) f x) := by @@ -1019,6 +1031,7 @@ lemma ringEquivOfRingEquiv_spanSingleton (x : K) : simp only [Algebra.smul_def, semilinearEquivOfRingEquiv_apply, map_mul, map_eq, RingHom.coe_coe, IsFractionRing.ringEquivOfRingEquiv_apply, RingEquiv.apply_symm_apply] +set_option backward.isDefEq.respectTransparency.types false in lemma ringEquivOfRingEquiv_symm_eq : (FractionalIdeal.ringEquivOfRingEquiv K L f).symm = FractionalIdeal.ringEquivOfRingEquiv L K f.symm := by diff --git a/Mathlib/RingTheory/FreeCommRing.lean b/Mathlib/RingTheory/FreeCommRing.lean index 62c7e0e6fd8941..991e7dbbedff95 100644 --- a/Mathlib/RingTheory/FreeCommRing.lean +++ b/Mathlib/RingTheory/FreeCommRing.lean @@ -128,6 +128,7 @@ section lift variable {R : Type v} [CommRing R] (f : α → R) +set_option backward.isDefEq.respectTransparency false in set_option backward.privateInPublic true in /-- A helper to implement `lift`. This is essentially `FreeCommMonoid.lift`, but this does not currently exist. -/ diff --git a/Mathlib/RingTheory/Frobenius.lean b/Mathlib/RingTheory/Frobenius.lean index e0b10ae2bb310e..adc4bf50a7d2eb 100644 --- a/Mathlib/RingTheory/Frobenius.lean +++ b/Mathlib/RingTheory/Frobenius.lean @@ -128,6 +128,7 @@ lemma apply_of_pow_eq_one [IsDomain S] {ζ : S} {m : ℕ} (hζ : ζ ^ m = 1) (hk rw [one_mul, ← pow_add, tsub_add_cancel_of_le (by linarith), pow_add, hζ.1, mul_one] at h₂ rw [h₂, e] +set_option backward.isDefEq.respectTransparency.types false in /-- A Frobenius element at `Q` restricts to an automorphism of `S_Q`. -/ noncomputable def localize [Q.IsPrime] : Localization.AtPrime Q →ₐ[R] Localization.AtPrime Q where @@ -143,6 +144,7 @@ lemma localize_algebraMap [Q.IsPrime] (x : S) : open IsLocalRing nonZeroDivisors +set_option backward.isDefEq.respectTransparency.types false in lemma isArithFrobAt_localize [Q.IsPrime] : H.localize.IsArithFrobAt (maximalIdeal _) := by have h : Nat.card (R ⧸ (maximalIdeal _).comap (algebraMap R (Localization.AtPrime Q))) = Nat.card (R ⧸ Q.under R) := by diff --git a/Mathlib/RingTheory/GradedAlgebra/Basic.lean b/Mathlib/RingTheory/GradedAlgebra/Basic.lean index 44a6e7d096a021..153d00659bf66d 100644 --- a/Mathlib/RingTheory/GradedAlgebra/Basic.lean +++ b/Mathlib/RingTheory/GradedAlgebra/Basic.lean @@ -351,6 +351,7 @@ variable {ι : Type*} [DecidableEq ι] [AddMonoid ι] variable {M : ι → Submodule R A} [SetLike.GradedMonoid M] -- The following lines were given on Zulip by Adam Topaz +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical isomorphism of an internal direct sum with the ambient algebra -/ noncomputable def coeAlgEquiv (hM : DirectSum.IsInternal M) : (DirectSum ι fun i => ↥(M i)) ≃ₐ[R] A := @@ -362,7 +363,7 @@ and satisfying `SetLike.GradedMonoid M` (essentially, is multiplicative) such that `DirectSum.IsInternal M` (`A` is the direct sum of the `M i`), we endow `A` with the structure of a graded algebra. The submodules are the *homogeneous* parts. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def gradedAlgebra (hM : DirectSum.IsInternal M) : GradedAlgebra M := { (inferInstance : SetLike.GradedMonoid M) with decompose' := hM.coeAlgEquiv.symm diff --git a/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean b/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean index 6bb4bfed265a05..fd5440a3dc7696 100644 --- a/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean +++ b/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean @@ -595,6 +595,7 @@ lemma mem_irrelevant_of_mem {x : A} {i : ι} (hi : 0 < i) (hx : x ∈ 𝒜 i) : rw [mem_irrelevant_iff, GradedRing.proj_apply, DirectSum.decompose_of_mem _ hx, DirectSum.of_eq_of_ne _ _ _ (by aesop), ZeroMemClass.coe_zero] +set_option backward.isDefEq.respectTransparency false in /-- `irrelevant 𝒜 = ⨁_{i>0} 𝒜ᵢ` -/ lemma irrelevant_eq_iSup : 𝒜₊.toAddSubmonoid = ⨆ i > 0, .ofClass (𝒜 i) := by refine le_antisymm (fun x hx ↦ ?_) <| iSup₂_le fun i hi x hx ↦ mem_irrelevant_of_mem _ hi hx diff --git a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean index 30c4f373268c3d..488f464e9c2012 100644 --- a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean +++ b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean @@ -663,6 +663,7 @@ open Graded num := f.gradedAddHom _ c.num den_mem := hw c.den_mem +set_option backward.isDefEq.respectTransparency.types false in /-- Let `A, B` be two graded rings with the same indexing set and `g : 𝒜 →+*ᵍ ℬ` be a graded ring homomorphism. Let `P ≤ A` be a submonoid and `Q ≤ B` be a submonoid such that `P ≤ g⁻¹ Q`, then `g` @@ -695,10 +696,12 @@ abbrev mapId {P Q : Submonoid A} (h : P ≤ Q) : HomogeneousLocalization 𝒜 P →+* HomogeneousLocalization 𝒜 Q := map (.id _) h +set_option backward.isDefEq.respectTransparency.types false in lemma map_mk (g : 𝒜 →+*ᵍ ℬ) (comap_le : P ≤ Q.comap g) (x) : map g comap_le (mk x) = mk ⟨x.1, ⟨_, map_mem g x.2.2⟩, ⟨_, map_mem g x.3.2⟩, comap_le x.4⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in variable (𝒜) in @[simp] theorem map_id (P : Submonoid A) : map (.id 𝒜) (P := P) (Q := P) le_rfl = .id _ := by ext x @@ -754,11 +757,13 @@ noncomputable def localRingHom : AtPrime 𝒜 I →+* AtPrime ℬ J := variable {f I J hIJ} +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma val_localRingHom (x : AtPrime 𝒜 I) : (localRingHom f I J hIJ x).val = Localization.localRingHom _ _ f hIJ x.val := by obtain ⟨⟨i, x, s, hs⟩, rfl⟩ := x.mk_surjective simp [localRingHom, map_mk] +set_option backward.isDefEq.respectTransparency.types false in instance : IsLocalHom (localRingHom f I J hIJ) where map_nonunit x hx := by rw [← isUnit_iff_isUnit_val] at hx ⊢ @@ -842,8 +847,7 @@ lemma val_awayMap (a) : (awayMap 𝒜 hg hx a).val = Localization.awayLift (alge lemma awayMap_fromZeroRingHom (a) : awayMap 𝒜 hg hx (fromZeroRingHom 𝒜 _ a) = fromZeroRingHom 𝒜 _ a := by ext - simp only [fromZeroRingHom, RingHom.coe_mk, MonoidHom.coe_mk, OneHom.coe_mk, - val_awayMap, val_mk] + simp only [fromZeroRingHom, val_awayMap] convert! IsLocalization.lift_eq _ _ lemma val_awayMap_mk (n a i hi) : (awayMap 𝒜 hg hx (mk ⟨n, a, ⟨f ^ i, hi⟩, ⟨i, rfl⟩⟩)).val = @@ -934,6 +938,7 @@ end isLocalization section span +set_option backward.isDefEq.respectTransparency.types false in variable [AddSubgroupClass σ A] [AddCommMonoid ι] [DecidableEq ι] {𝒜 : ι → σ} [GradedRing 𝒜] in /-- Let `𝒜` be a graded ring, finitely generated (as an algebra) over `𝒜₀` by `{ vᵢ }`, diff --git a/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean b/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean index 5a6b85e0106a28..c8f973038b6905 100644 --- a/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean +++ b/Mathlib/RingTheory/GradedAlgebra/TensorProduct.lean @@ -33,6 +33,7 @@ variable [CommSemiring R] [CommSemiring S] [Algebra R S] variable [DecidableEq ι] [AddMonoid ι] variable [Semiring A] [Algebra R A] (𝒜 : ι → Submodule R A) [GradedAlgebra 𝒜] +set_option backward.isDefEq.respectTransparency.types false in instance baseChange : GradedAlgebra fun i ↦ (𝒜 i).baseChange S where one_mem := tmul_mem_baseChange_of_mem _ <| one_mem_graded 𝒜 mul_mem i j := by diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index e8381abf4fcd3d..5144dc5f0c44d8 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -158,6 +158,7 @@ lemma addOppositeEquiv_symm_support (x : R⟦Γ⟧ᵃᵒᵖ) : (addOppositeEquiv.symm x).support = x.unop.support := by rw [← addOppositeEquiv_support, AddEquiv.apply_symm_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma addOppositeEquiv_orderTop (x : Rᵃᵒᵖ⟦Γ⟧) : (addOppositeEquiv x).unop.orderTop = x.orderTop := by @@ -173,6 +174,7 @@ lemma addOppositeEquiv_symm_orderTop (x : R⟦Γ⟧ᵃᵒᵖ) : (addOppositeEquiv.symm x).orderTop = x.unop.orderTop := by rw [← addOppositeEquiv_orderTop, AddEquiv.apply_symm_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma addOppositeEquiv_leadingCoeff (x : Rᵃᵒᵖ⟦Γ⟧) : (addOppositeEquiv x).unop.leadingCoeff = x.leadingCoeff.unop := by diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index badf6fc2ae41d1..eb95a35aee1bfb 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -166,6 +166,7 @@ def ofIterate [PartialOrder Γ'] (x : R⟦Γ'⟧⟦Γ⟧) : R⟦Γ ×ₗ Γ'⟧ lemma mk_eq_zero (f : Γ → R) (h) : HahnSeries.mk f h = 0 ↔ f = 0 := by simp_rw [HahnSeries.ext_iff, funext_iff, coeff_zero, Pi.zero_apply] +set_option backward.isDefEq.respectTransparency false in /-- Change a `HahnSeries` on a Lex product to a `HahnSeries` with coefficients in a `HahnSeries`. -/ def toIterate [PartialOrder Γ'] (x : R⟦Γ ×ₗ Γ'⟧) : R⟦Γ'⟧⟦Γ⟧ where coeff := fun g => { diff --git a/Mathlib/RingTheory/HahnSeries/HEval.lean b/Mathlib/RingTheory/HahnSeries/HEval.lean index 1fd494bca65b66..7a543c165c27bc 100644 --- a/Mathlib/RingTheory/HahnSeries/HEval.lean +++ b/Mathlib/RingTheory/HahnSeries/HEval.lean @@ -83,6 +83,7 @@ theorem powerSeriesFamily_smul {x : V⟦Γ⟧} (f : PowerSeries R) (r : R) : ext1 n simp [mul_smul] +set_option backward.isDefEq.respectTransparency false in theorem support_powerSeriesFamily_subset {x : V⟦Γ⟧} (a b : PowerSeries R) (g : Γ) : ((powerSeriesFamily x (a * b)).coeff g).support ⊆ (((powerSeriesFamily x a).mul (powerSeriesFamily x b)).coeff g).support.image diff --git a/Mathlib/RingTheory/HahnSeries/Lex.lean b/Mathlib/RingTheory/HahnSeries/Lex.lean index 8664bb6b893ab8..73d3cff80661fe 100644 --- a/Mathlib/RingTheory/HahnSeries/Lex.lean +++ b/Mathlib/RingTheory/HahnSeries/Lex.lean @@ -292,6 +292,7 @@ noncomputable def finiteArchimedeanClassOrderHomInvLex : exact .inl (by simpa [ha, hb] using! h) · exact OrderHom.monotone _ hle +set_option backward.isDefEq.respectTransparency.types false in variable (Γ R) in /-- The correspondence between finite archimedean classes of `Lex R⟦Γ⟧` and lexicographical pairs of `HahnSeries.orderTop` and the finite archimedean class of diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 29d9385e622d66..0a580f92788457 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -982,7 +982,7 @@ instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where rintro b c hxb - hbc hbc' contrapose! hbc' rwa [eq_comm, eq_comm (a := c), ← add_eq_add_iff_eq_and_eq (order_le_of_coeff_ne_zero hxb) - (Set.IsWF.min_le _ _ hbc'), eq_comm] + (Set.IsWF.min_le this hyz hbc'), eq_comm] · simp +contextual [← and_or_left, ← or_and_right] · simp +contextual [← and_or_left, ← or_and_right] mul_right_cancel_of_ne_zero {x} hx y z hyz := by @@ -1004,7 +1004,8 @@ instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where rintro b c - hxb hbc hbc' contrapose! hbc' rwa [eq_comm, eq_comm (a := c), ← add_eq_add_iff_eq_and_eq - (Set.IsWF.min_le _ _ hbc') (order_le_of_coeff_ne_zero hxb), eq_comm] + (Set.IsWF.min_le this hyz ((Set.mem_setOf (p := fun a => y.coeff a ≠ z.coeff a)).mpr hbc')) + (order_le_of_coeff_ne_zero hxb), eq_comm] · simp +contextual [← or_and_right] · simp +contextual [← or_and_right] diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index ab56f54f4b5965..e650212e940b5e 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -168,6 +168,7 @@ end SMul instance : AddCommMonoid (SummableFamily Γ R α) := fast_instance% DFunLike.coe_injective.addCommMonoid _ coe_zero coe_add (fun _ _ => coe_smul' _ _) +set_option backward.isDefEq.respectTransparency false in /-- The coefficient function of a summable family, as a finsupp on the parameter type. -/ @[simps] def coeff (s : SummableFamily Γ R α) (g : Γ) : α →₀ R where @@ -212,6 +213,7 @@ theorem hsum_add {s t : SummableFamily Γ R α} : (s + t).hsum = s.hsum + t.hsum simp only [coeff_hsum, coeff_add, add_apply] exact finsum_add_distrib (s.finite_co_support _) (t.finite_co_support _) +set_option backward.isDefEq.respectTransparency false in theorem coeff_hsum_eq_sum_of_subset {s : SummableFamily Γ R α} {g : Γ} {t : Finset α} (h : { a | (s a).coeff g ≠ 0 } ⊆ t) : s.hsum.coeff g = ∑ i ∈ t, (s i).coeff g := by simp only [coeff_hsum, finsum_eq_sum _ (s.finite_co_support _)] @@ -464,6 +466,7 @@ theorem coeff_smul {R} {V} [Semiring R] [AddCommMonoid V] [Module R V] Set.mem_setOf_eq, Prod.forall, coeff_support, mem_product] exact hsupp ab.1 ab.2 hab +set_option backward.isDefEq.respectTransparency false in theorem smul_hsum {R} {V} [Semiring R] [AddCommMonoid V] [Module R V] (s : SummableFamily Γ R α) (t : SummableFamily Γ' V β) : (smul s t).hsum = (of R).symm (s.hsum • (of R) (t.hsum)) := by diff --git a/Mathlib/RingTheory/HopfAlgebra/Basic.lean b/Mathlib/RingTheory/HopfAlgebra/Basic.lean index 7d10e13158862c..8383ce9c30b151 100644 --- a/Mathlib/RingTheory/HopfAlgebra/Basic.lean +++ b/Mathlib/RingTheory/HopfAlgebra/Basic.lean @@ -120,6 +120,7 @@ lemma sum_mul_antipode_eq_smul (repr : Repr R a ι) : counit (R := R) a • 1 := by rw [sum_mul_antipode_eq_algebraMap_counit, Algebra.smul_def, mul_one] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma counit_antipode (a : A) : counit (R := R) (antipode R a) = counit a := by calc counit (antipode R a) diff --git a/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean b/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean index 068ce13791c006..4c6e4b8ec8ad18 100644 --- a/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean +++ b/Mathlib/RingTheory/Ideal/AssociatedPrime/Basic.lean @@ -115,6 +115,7 @@ theorem isAssociatedPrime_iff [IsNoetherianRing R] : IsAssociatedPrime I M ↔ I.IsPrime ∧ ∃ x : M, I = colon ⊥ {x} := (⊥ : Submodule R M).isAssociatedPrime_iff +set_option backward.isDefEq.respectTransparency false in theorem IsAssociatedPrime.map_of_injective (h : IsAssociatedPrime I M) (hf : Function.Injective f) : IsAssociatedPrime I M' := by obtain ⟨x, rfl⟩ := h.2 diff --git a/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean b/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean index 1c528dcb354863..54fe0667c85f81 100644 --- a/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean +++ b/Mathlib/RingTheory/Ideal/AssociatedPrime/Localization.lean @@ -123,6 +123,7 @@ lemma preimage_comap_associatedPrimes_eq_associatedPrimes_of_isLocalizedModule fun h ↦ comap_mem_associatedPrimes_of_mem_associatedPrimes_of_isLocalizedModule_of_fg S f p h ((isNoetherianRing_iff_ideal_fg R).mp ‹_› _)⟩ +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in lemma minimalPrimes_annihilator_subset_associatedPrimes [IsNoetherianRing R] [Module.Finite R M] : (Module.annihilator R M).minimalPrimes ⊆ associatedPrimes R M := by diff --git a/Mathlib/RingTheory/Ideal/Basis.lean b/Mathlib/RingTheory/Ideal/Basis.lean index 1b4d72f90a4e7d..2643b71a0214e5 100644 --- a/Mathlib/RingTheory/Ideal/Basis.lean +++ b/Mathlib/RingTheory/Ideal/Basis.lean @@ -35,6 +35,7 @@ noncomputable def basisSpanSingleton (b : Basis ι R S) {x : S} (hx : x ≠ 0) : simp [mem_span_singleton', mul_comm]) ≪≫ₗ (Submodule.restrictScalarsEquiv R S S (Ideal.span ({x} : Set S))).restrictScalars R +set_option backward.isDefEq.respectTransparency false in @[simp] theorem basisSpanSingleton_apply (b : Basis ι R S) {x : S} (hx : x ≠ 0) (i : ι) : (basisSpanSingleton b hx i : S) = x * b i := by diff --git a/Mathlib/RingTheory/Ideal/Cotangent.lean b/Mathlib/RingTheory/Ideal/Cotangent.lean index 038cde5ec87e77..e504ed7d7706b7 100644 --- a/Mathlib/RingTheory/Ideal/Cotangent.lean +++ b/Mathlib/RingTheory/Ideal/Cotangent.lean @@ -167,6 +167,7 @@ theorem cotangentEquivIdeal_symm_apply (x : R) (hx : x ∈ I) : variable {A B : Type*} [CommRing A] [CommRing B] [Algebra R A] [Algebra R B] +set_option backward.isDefEq.respectTransparency.types false in /-- The lift of `f : A →ₐ[R] B` to `A ⧸ J ^ 2 →ₐ[R] B` with `J` being the kernel of `f`. -/ def _root_.AlgHom.kerSquareLift (f : A →ₐ[R] B) : A ⧸ RingHom.ker f.toRingHom ^ 2 →ₐ[R] B := by refine { Ideal.Quotient.lift (RingHom.ker f.toRingHom ^ 2) f.toRingHom ?_ with commutes' := ?_ } @@ -202,6 +203,7 @@ def quotCotangent : (R ⧸ I ^ 2) ⧸ I.cotangentIdeal ≃+* R ⧸ I := by refine (DoubleQuot.quotQuotEquivQuotSup _ _).trans ?_ exact Ideal.quotEquivOfEq (sup_eq_right.mpr <| Ideal.pow_le_self two_ne_zero) +set_option backward.isDefEq.respectTransparency.types false in /-- The map `I/I² → J/J²` if `I ≤ f⁻¹(J)`. -/ def mapCotangent (I₁ : Ideal A) (I₂ : Ideal B) (f : A →ₐ[R] B) (h : I₁ ≤ I₂.comap f) : I₁.Cotangent →ₗ[R] I₂.Cotangent := by @@ -253,6 +255,7 @@ lemma lift_comp_toCotangent (f : I →ₗ[R] M) (hf : ∀ (x y : I), f (x * y) = Cotangent.lift f hf ∘ₗ I.toCotangent = f := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma lift_surjective_iff (f : I →ₗ[R] M) (hf : ∀ (x y : I), f (x * y) = 0) : Function.Surjective (Cotangent.lift f hf) ↔ Function.Surjective f := by refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ @@ -369,6 +372,7 @@ lemma Ideal.mapCotangent_surjective_of_comap_eq (surj : Function.Surjective (alg use J.toCotangent ⟨y', mem⟩ simpa using I.toCotangent.congr_arg (SetCoe.ext hy') +set_option backward.isDefEq.respectTransparency.types false in lemma Ideal.mapCotangent_ker_of_surjective (surj : Function.Surjective (algebraMap A B)) {I : Ideal B} {J : Ideal A} (eq : I.comap (algebraMap A B) = RingHom.ker (algebraMap A B) ⊔ J) : (Ideal.mapCotangent J I (Algebra.ofId A B) (le_of_le_of_eq le_sup_right eq.symm)).ker = diff --git a/Mathlib/RingTheory/Ideal/CotangentBaseChange.lean b/Mathlib/RingTheory/Ideal/CotangentBaseChange.lean index 4d8e34836ce1f6..f7481be783eb09 100644 --- a/Mathlib/RingTheory/Ideal/CotangentBaseChange.lean +++ b/Mathlib/RingTheory/Ideal/CotangentBaseChange.lean @@ -61,6 +61,7 @@ lemma tensorCotangentHom_tmul (t : T) (x : I) : ⟨1 ⊗ₜ x, Ideal.mem_map_of_mem _ x.2⟩ := by rfl +set_option backward.isDefEq.respectTransparency.types false in lemma tensorCotangentHom_surjective : Function.Surjective (I.tensorCotangentHom R T) := by let a : S →+* T ⊗[R] S := Algebra.TensorProduct.includeRight.toRingHom @@ -80,6 +81,7 @@ lemma tensorCotangentHom_surjective : simp [-AlgHom.toRingHom_eq_coe, tensorCotangentHom_tmul, Algebra.smul_def, ← Ideal.Quotient.mk_algebraMap, ← map_mul] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `T` is a flat `R`-module, the canonical map `tensorCotangentHom R T I` is injective. -/ lemma tensorCotangentHom_injective_of_flat [Module.Flat R T] : diff --git a/Mathlib/RingTheory/Ideal/GoingDown.lean b/Mathlib/RingTheory/Ideal/GoingDown.lean index 1337409a5cc4c5..a41d8ed15b1ab8 100644 --- a/Mathlib/RingTheory/Ideal/GoingDown.lean +++ b/Mathlib/RingTheory/Ideal/GoingDown.lean @@ -68,6 +68,7 @@ lemma Ideal.exists_ideal_lt_liesOver_of_lt [Algebra.HasGoingDown R S] subst this simp [P.over_def p, P.over_def q] at hpq +set_option backward.isDefEq.respectTransparency.types false in lemma Ideal.exists_ltSeries_of_hasGoingDown [Algebra.HasGoingDown R S] (l : LTSeries (PrimeSpectrum R)) (P : Ideal S) [P.IsPrime] [lo : P.LiesOver l.last.asIdeal] : ∃ (L : LTSeries (PrimeSpectrum S)), diff --git a/Mathlib/RingTheory/Ideal/Height.lean b/Mathlib/RingTheory/Ideal/Height.lean index c5a46cc9620e2d..64b9a4419ec3fd 100644 --- a/Mathlib/RingTheory/Ideal/Height.lean +++ b/Mathlib/RingTheory/Ideal/Height.lean @@ -36,6 +36,7 @@ private noncomputable def Ideal.primeHeight [hI : I.IsPrime] : ℕ∞ := noncomputable def Ideal.height : ℕ∞ := ⨅ J ∈ I.minimalPrimes, @Ideal.primeHeight _ _ J ‹J ∈ I.minimalPrimes›.isPrime +set_option backward.isDefEq.respectTransparency.types false in /-- For a prime ideal, its height equals its prime height. -/ private lemma Ideal.height_eq_primeHeight [I.IsPrime] : I.height = I.primeHeight := by simp [height, primeHeight, Ideal.minimalPrimes_eq_subsingleton_self] diff --git a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean index beef0a92dab0c1..d4c5ee7f5037c7 100644 --- a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean +++ b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean @@ -56,6 +56,7 @@ lemma IsLocalRing.quotient_artinian_of_mem_minimalPrimes_of_isLocalRing exact hp.eq_of_le ⟨this, .trans (by simp) (Ideal.ker_le_comap _)⟩ (le_maximalIdeal this.1) IsNoetherianRing.isArtinianRing_of_krullDimLE_zero +set_option backward.isDefEq.respectTransparency.types false in lemma Ideal.height_le_one_of_isPrincipal_of_mem_minimalPrimes_of_isLocalRing [IsLocalRing R] (I : Ideal R) [I.IsPrincipal] (hp : (IsLocalRing.maximalIdeal R) ∈ I.minimalPrimes) : diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 135e2a6ff1a219..042bd37972fd1a 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -418,6 +418,9 @@ theorem map_evalRingHom_pi {I : Π i, Ideal (R i)} (i : ι) : rintro ⟨r, hr, rfl⟩ exact hr i +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Ideals in a finite direct product semiring `Πᵢ Rᵢ` are identified with tuples of ideals in the individual semirings, in an order-preserving way. @@ -522,6 +525,7 @@ section Bijective variable (hf : Function.Bijective f) {I : Ideal R} {K : Ideal S} include hf +set_option backward.isDefEq.respectTransparency false in /-- Special case of the correspondence theorem for isomorphic rings -/ def relIsoOfBijective : Ideal S ≃o Ideal R where toFun := comap f @@ -665,6 +669,7 @@ def mapHom : Ideal R →+* Ideal S where protected theorem map_pow (n : ℕ) : map f (I ^ n) = map f I ^ n := map_pow (mapHom f) I n +set_option backward.isDefEq.respectTransparency false in theorem comap_radical : comap f (radical K) = radical (comap f K) := by ext simp [radical] @@ -1249,6 +1254,7 @@ theorem eq_liftOfSurjective (hf : Function.Surjective f) (g : A →+* C) end RingHom +set_option backward.isDefEq.respectTransparency false in /-- Any ring isomorphism induces an order isomorphism of ideals. -/ @[simps apply] def RingEquiv.idealComapOrderIso {R S : Type*} [Semiring R] [Semiring S] (e : R ≃+* S) : diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index 829c6ed62493a2..797eee4c5e494c 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -103,6 +103,7 @@ theorem map_spanIntNorm (I : Ideal S) {T : Type*} [Semiring T] (f : R →+* T) : theorem spanNorm_mono {I J : Ideal S} (h : I ≤ J) : spanNorm R I ≤ spanNorm R J := Ideal.span_mono (Set.monotone_image h) +set_option backward.isDefEq.respectTransparency.types false in theorem spanIntNorm_localization (I : Ideal S) (M : Submonoid R) (hM : M ≤ R⁰) {Rₘ : Type*} (Sₘ : Type*) [CommRing Rₘ] [Algebra R Rₘ] [CommRing Sₘ] [Algebra S Sₘ] [Algebra Rₘ Sₘ] [Algebra R Sₘ] [IsScalarTower R Rₘ Sₘ] [IsScalarTower R S Sₘ] diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 1be8c87af8ceb4..5c0fc693c8946a 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -1310,6 +1310,7 @@ noncomputable def finsuppTotal : (ι →₀ I) →ₗ[R] M := variable {ι M v} set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in theorem finsuppTotal_apply (f : ι →₀ I) : finsuppTotal ι M I v f = f.sum fun i x => (x : R) • v i := by dsimp [finsuppTotal] diff --git a/Mathlib/RingTheory/Ideal/Prod.lean b/Mathlib/RingTheory/Ideal/Prod.lean index afa0e0c1703ebb..97eda3d056ea00 100644 --- a/Mathlib/RingTheory/Ideal/Prod.lean +++ b/Mathlib/RingTheory/Ideal/Prod.lean @@ -96,6 +96,7 @@ theorem map_prodComm_prod : refine Trans.trans (ideal_prod_eq _) ?_ simp [map_map] +set_option backward.isDefEq.respectTransparency false in /-- Ideals of `R × S` are in one-to-one correspondence with pairs of ideals of `R` and ideals of `S`. -/ def idealProdEquiv : Ideal (R × S) ≃o Ideal R × Ideal S where diff --git a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean index 8b928643d7d8e6..cf606703c0e42e 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean @@ -201,6 +201,7 @@ noncomputable def piQuotEquiv [I.IsTwoSided] : ((ι → R) ⧸ pi fun _ ↦ I) exact Ideal.Quotient.eq.2 fun i ↦ Ideal.Quotient.eq.1 (Quotient.out_eq' _) right_inv x := funext fun i ↦ Quotient.out_eq' (x i) +set_option backward.isDefEq.respectTransparency false in /-- If `f : R^n → R^m` is an `R`-linear map and `I ⊆ R` is an ideal, then the image of `I^n` is contained in `I^m`. -/ theorem map_pi [I.IsTwoSided] [Finite ι] (x : ι → R) (hi : ∀ i, x i ∈ I) diff --git a/Mathlib/RingTheory/Ideal/Quotient/ChineseRemainder.lean b/Mathlib/RingTheory/Ideal/Quotient/ChineseRemainder.lean index 366453b7edab6c..7d3aa0d34aceae 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/ChineseRemainder.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/ChineseRemainder.lean @@ -24,6 +24,7 @@ namespace Ideal open TensorProduct LinearMap +set_option backward.isDefEq.respectTransparency.types false in lemma pi_mkQ_rTensor [Fintype ι] [DecidableEq ι] : (LinearMap.pi fun i ↦ (I i).mkQ).rTensor M = (piLeft ..).symm.toLinearMap ∘ₗ .pi (fun i ↦ TensorProduct.mk R (R ⧸ I i) M 1) ∘ₗ TensorProduct.lid R M := by diff --git a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean index b96f1f0e99050a..f576ed3892b35a 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean @@ -139,6 +139,7 @@ theorem map_mk_eq_bot_of_le {I J : Ideal R} [J.IsTwoSided] (h : I ≤ J) : rw [map_eq_bot_iff_le_ker, mk_ker] exact h +set_option backward.isDefEq.respectTransparency false in theorem ker_quotient_lift {I : Ideal R} [I.IsTwoSided] (f : R →+* S) (H : I ≤ ker f) : ker (Ideal.Quotient.lift I f H) = (RingHom.ker f).map (Quotient.mk I) := by @@ -156,6 +157,7 @@ theorem ker_quotient_lift {I : Ideal R} [I.IsTwoSided] (f : R →+* S) rw [mem_ker, ← hy.right, Ideal.Quotient.lift_mk] exact hy.left +set_option backward.isDefEq.respectTransparency false in lemma injective_lift_iff {I : Ideal R} [I.IsTwoSided] {f : R →+* S} (H : ∀ (a : R), a ∈ I → f a = 0) : Injective (Quotient.lift I f H) ↔ ker f = I := by @@ -191,7 +193,7 @@ theorem mem_quotient_iff_mem {I J : Ideal R} [I.IsTwoSided] (hIJ : I ≤ J) {x : rw [mem_quotient_iff_mem_sup, sup_eq_left.mpr hIJ] section ChineseRemainder -open Function Quotient Finset +open Function Ideal.Quotient Finset variable {ι : Type*} @@ -464,6 +466,7 @@ section variable [Semiring B] [Algebra R₁ B] +set_option backward.isDefEq.respectTransparency false in /-- `Ideal.quotient.lift` as an `AlgHom`. -/ def Quotient.liftₐ (I : Ideal A) [I.IsTwoSided] (f : A →ₐ[R₁] B) (hI : ∀ a : A, a ∈ I → f a = 0) : A ⧸ I →ₐ[R₁] B := @@ -561,6 +564,7 @@ def _root_.AlgHom.liftOfSurjective (f : A →ₐ[R] B) (hf : Function.Surjective (g : A →ₐ[R] C) (H : RingHom.ker f.toRingHom ≤ RingHom.ker g.toRingHom) : B →ₐ[R] C := .comp (Ideal.Quotient.liftₐ _ g H) (Ideal.quotientKerAlgEquivOfSurjective hf).symm.toAlgHom +set_option backward.isDefEq.respectTransparency false in @[simp] lemma _root_.AlgHom.liftOfSurjective_apply (f : A →ₐ[R] B) (hf : Function.Surjective f) (g : A →ₐ[R] C) (H : RingHom.ker f.toRingHom ≤ RingHom.ker g.toRingHom) (x) : @@ -611,6 +615,7 @@ theorem quotientMap_comp_mk {J : Ideal R} {I : Ideal S} [I.IsTwoSided] [J.IsTwoS (quotientMap I f H).comp (Quotient.mk J) = (Quotient.mk I).comp f := RingHom.ext fun x => by simp only [Function.comp_apply, RingHom.coe_comp, Ideal.quotientMap_mk] +set_option backward.isDefEq.respectTransparency false in lemma ker_quotientMap_mk {I J : Ideal R} [I.IsTwoSided] [J.IsTwoSided] : RingHom.ker (quotientMap (J.map _) (Quotient.mk I) le_comap_map) = I.map (Quotient.mk J) := by rw [Ideal.quotientMap, Ideal.ker_quotient_lift, ← RingHom.comap_ker, Ideal.mk_ker, @@ -689,6 +694,7 @@ section variable [Ring B] [Algebra R₁ B] {I : Ideal A} (J : Ideal B) [I.IsTwoSided] [J.IsTwoSided] +set_option backward.isDefEq.respectTransparency false in /-- The algebra hom `A/I →+* B/J` induced by an algebra hom `f : A →ₐ[R₁] B` with `I ≤ f⁻¹(J)`. -/ def quotientMapₐ (f : A →ₐ[R₁] B) (hIJ : I ≤ J.comap f) : A ⧸ I →ₐ[R₁] B ⧸ J := @@ -704,6 +710,7 @@ theorem quotient_map_comp_mkₐ (f : A →ₐ[R₁] B) (H : I ≤ J.comap f) : (quotientMapₐ J f H).comp (Quotient.mkₐ R₁ I) = (Quotient.mkₐ R₁ J).comp f := AlgHom.ext fun x => by simp only [quotient_map_mkₐ, Quotient.mkₐ_eq_mk, AlgHom.comp_apply] +set_option backward.isDefEq.respectTransparency false in variable (I) in /-- The algebra equiv `A/I ≃ₐ[R] B/J` induced by an algebra equiv `f : A ≃ₐ[R] B`, where `J = f(I)`. -/ @@ -862,6 +869,7 @@ variable [CommRing R] (I J : Ideal R) def quotLeftToQuotSup : R ⧸ I →+* R ⧸ I ⊔ J := Ideal.Quotient.factor le_sup_left +set_option backward.isDefEq.respectTransparency false in /-- The kernel of `quotLeftToQuotSup` -/ theorem ker_quotLeftToQuotSup : RingHom.ker (quotLeftToQuotSup I J) = J.map (Ideal.Quotient.mk I) := by diff --git a/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean b/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean index 24de176f9eea4d..627c8d4d425f24 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean @@ -54,6 +54,7 @@ lemma Ideal.Quotient.factor_ker (H : I ≤ J) [I.IsTwoSided] [J.IsTwoSided] : · rcases mem_image_of_mem_map_of_surjective _ Ideal.Quotient.mk_surjective h with ⟨r, hr, eq⟩ simpa [← eq, Ideal.Quotient.eq_zero_iff_mem] using hr +set_option backward.isDefEq.respectTransparency false in lemma Submodule.eq_factor_of_eq_factor_succ {p : ℕ → Submodule R M} (hp : Antitone p) (x : (n : ℕ) → M ⧸ (p n)) (h : ∀ m, x m = factor (hp m.le_succ) (x (m + 1))) {m n : ℕ} (g : m ≤ n) : x m = factor (hp g) (x n) := by diff --git a/Mathlib/RingTheory/IdealFilter/Topology.lean b/Mathlib/RingTheory/IdealFilter/Topology.lean index 09c597b7fe4503..2606328390d38f 100644 --- a/Mathlib/RingTheory/IdealFilter/Topology.lean +++ b/Mathlib/RingTheory/IdealFilter/Topology.lean @@ -43,7 +43,7 @@ open scoped Pointwise Topology namespace IdealFilter /-- The additive-group filter basis whose sets are the ideals belonging to the ideal filter `F`. -/ -@[implicit_reducible] +@[instance_reducible] def addGroupFilterBasis {A : Type*} [Ring A] (F : IdealFilter A) : AddGroupFilterBasis A where sets := {(I : Set A) | I ∈ F} nonempty := ⟨_, ⟨_, F.nonempty.choose_spec, rfl⟩⟩ @@ -56,7 +56,7 @@ def addGroupFilterBasis {A : Type*} [Ring A] (F : IdealFilter A) : AddGroupFilte conj' := by aesop /-- Under `[F.IsUniform]`, the ring filter basis obtained from `addGroupFilterBasis`. -/ -@[simps! -isSimp sets, implicit_reducible] +@[simps! -isSimp sets, instance_reducible] def ringFilterBasis {A : Type*} [Ring A] {F : IdealFilter A} [F.IsUniform] : RingFilterBasis A where __ := F.addGroupFilterBasis diff --git a/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean b/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean index fbf6632c550b9b..01f2186bdb222e 100644 --- a/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean +++ b/Mathlib/RingTheory/IntegralClosure/IntegralRestrict.lean @@ -56,6 +56,7 @@ def galRestrict' (f : L →ₐ[K] L₂) : (B →ₐ[A] B₂) := (((f.restrictScalars A).comp (IsScalarTower.toAlgHom A B L)).codRestrict (integralClosure A L₂) (fun x ↦ IsIntegral.map _ (IsIntegralClosure.isIntegral A L x))) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma algebraMap_galRestrict'_apply (σ : L →ₐ[K] L₂) (x : B) : algebraMap B₂ L₂ (galRestrict' A B B₂ σ x) = σ (algebraMap B L x) := by @@ -67,6 +68,7 @@ theorem galRestrict'_id : galRestrict' A B B (.id K L) = .id A B := by apply IsIntegralClosure.algebraMap_injective B A L simp +set_option backward.isDefEq.respectTransparency.types false in theorem galRestrict'_comp (σ : L →ₐ[K] L₂) (σ' : L₂ →ₐ[K] L₃) : galRestrict' A B B₃ (σ'.comp σ) = (galRestrict' A B₂ B₃ σ').comp (galRestrict' A B B₂ σ) := by ext x @@ -121,6 +123,7 @@ theorem galLift_comp [Algebra.IsAlgebraic K L₂] (σ : B →ₐ[A] B₂) (σ' : AlgHom.coe_ringHom_injective <| IsLocalization.ringHom_ext (Algebra.algebraMapSubmonoid B A⁰) <| RingHom.ext fun x ↦ by simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem galLift_galRestrict' (σ : L →ₐ[K] L₂) : galLift K L L₂ (galRestrict' A B B₂ σ) = σ := @@ -321,6 +324,7 @@ open nonZeroDivisors variable [IsDomain Aₘ] [IsIntegrallyClosed Aₘ] [IsDomain Bₘ] [IsIntegrallyClosed Bₘ] variable [IsTorsionFree Aₘ Bₘ] [Module.Finite Aₘ Bₘ] +set_option backward.isDefEq.respectTransparency.types false in include M in lemma Algebra.intTrace_eq_of_isLocalization (x : B) : @@ -472,6 +476,7 @@ lemma Algebra.intNorm_ne_zero [FiniteDimensional (FractionRing A) (FractionRing variable [IsDomain Aₘ] [IsIntegrallyClosed Aₘ] [IsDomain Bₘ] [IsIntegrallyClosed Bₘ] variable [IsTorsionFree Aₘ Bₘ] [Algebra.IsIntegral Aₘ Bₘ] +set_option backward.isDefEq.respectTransparency.types false in include M in lemma Algebra.intNorm_eq_of_isLocalization [FiniteDimensional (FractionRing A) (FractionRing B)] (x : B) : diff --git a/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean b/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean index 1175bf4626029c..e57cea737f87bc 100644 --- a/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean +++ b/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean @@ -375,6 +375,7 @@ section localization variable {R : Type*} (S : Type*) [CommRing R] [CommRing S] [Algebra R S] +set_option backward.isDefEq.respectTransparency.types false in lemma isIntegrallyClosed_of_isLocalization [IsIntegrallyClosed R] [IsDomain R] (M : Submonoid R) (hM : M ≤ R⁰) [IsLocalization M S] : IsIntegrallyClosed S := by let K := FractionRing R diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean index 4321faad608df6..ec145943e0646d 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean @@ -574,6 +574,7 @@ theorem Algebra.IsIntegral.tower_top [Algebra R S] [Algebra R T] [Algebra S T] [ rw [← IsScalarTower.algebraMap_eq R S T] exact h.isIntegral +set_option backward.isDefEq.respectTransparency.types false in theorem RingHom.IsIntegral.quotient {I : Ideal S} (hf : f.IsIntegral) : (Ideal.quotientMap I f le_rfl).IsIntegral := by rintro ⟨x⟩ diff --git a/Mathlib/RingTheory/IntegralDomain.lean b/Mathlib/RingTheory/IntegralDomain.lean index 4e328a55a6da5d..8082b95429a845 100644 --- a/Mathlib/RingTheory/IntegralDomain.lean +++ b/Mathlib/RingTheory/IntegralDomain.lean @@ -51,7 +51,7 @@ theorem mul_left_bijective_of_finite₀ [IsRightCancelMulZero M] {a : M} (ha : a Finite.injective_iff_bijective.1 <| mul_left_injective₀ ha /-- Every finite nontrivial cancellative monoid with zero is a group with zero. -/ -@[implicit_reducible] +@[instance_reducible] def Fintype.groupWithZeroOfCancel (M : Type*) [MonoidWithZero M] [IsLeftCancelMulZero M] [DecidableEq M] [Fintype M] [Nontrivial M] : GroupWithZero M := { ‹Nontrivial M›, @@ -93,7 +93,7 @@ section Ring /-- Every finite domain is a division ring. More generally, they are fields; this can be found in `Mathlib/RingTheory/LittleWedderburn.lean`. -/ -@[implicit_reducible] +@[instance_reducible] def Fintype.divisionRingOfIsDomain (R : Type*) [Ring R] [IsDomain R] [DecidableEq R] [Fintype R] : DivisionRing R where __ := (‹Ring R› :) -- this also works without the `( :)`, but it's slightly slow @@ -105,7 +105,7 @@ def Fintype.divisionRingOfIsDomain (R : Type*) [Ring R] [IsDomain R] [DecidableE /-- Every finite commutative domain is a field. More generally, commutativity is not required: this can be found in `Mathlib/RingTheory/LittleWedderburn.lean`. -/ -@[implicit_reducible] +@[instance_reducible] def Fintype.fieldOfDomain (R) [CommRing R] [IsDomain R] [DecidableEq R] [Fintype R] : Field R := { Fintype.divisionRingOfIsDomain R, ‹CommRing R› with } diff --git a/Mathlib/RingTheory/Invariant/Basic.lean b/Mathlib/RingTheory/Invariant/Basic.lean index 3e5686b1f40541..814721a42c2a4f 100644 --- a/Mathlib/RingTheory/Invariant/Basic.lean +++ b/Mathlib/RingTheory/Invariant/Basic.lean @@ -52,6 +52,7 @@ section Quotient variable {A B : Type*} [CommRing A] [CommRing B] [Algebra A B] variable {G : Type*} [Group G] [MulSemiringAction G B] [SMulCommClass G A B] +set_option backward.isDefEq.respectTransparency.types false in instance (H : Subgroup G) [H.Normal] : MulSemiringAction (G ⧸ H) (FixedPoints.subring B H) where smul := Quotient.lift (fun g x ↦ ⟨g • x, fun h ↦ by @@ -70,10 +71,12 @@ instance (H : Subgroup G) [H.Normal] : MulSemiringAction (G ⧸ H) (FixedPoints.subalgebra A B H) := inferInstanceAs (MulSemiringAction (G ⧸ H) (FixedPoints.subring B H)) +set_option backward.isDefEq.respectTransparency.types false in instance (H : Subgroup G) [H.Normal] : SMulCommClass (G ⧸ H) A (FixedPoints.subalgebra A B H) where smul_comm := Quotient.ind fun g r h ↦ Subtype.ext (smul_comm g r h.1) +set_option backward.isDefEq.respectTransparency.types false in instance (H : Subgroup G) [H.Normal] [Algebra.IsInvariant A B G] : Algebra.IsInvariant A (FixedPoints.subalgebra A B H) (G ⧸ H) where isInvariant x hx := by diff --git a/Mathlib/RingTheory/Invariant/Profinite.lean b/Mathlib/RingTheory/Invariant/Profinite.lean index 4803fa498e96e0..b2d6e9d63bfe0a 100644 --- a/Mathlib/RingTheory/Invariant/Profinite.lean +++ b/Mathlib/RingTheory/Invariant/Profinite.lean @@ -56,6 +56,7 @@ lemma Algebra.IsInvariant.isIntegral_of_profinite ⟨x, fun g ↦ hN g.2⟩ exact this.map (FixedPoints.subalgebra A B N.1.1).val +set_option backward.isDefEq.respectTransparency.types false in /-- `G` acts transitively on the prime ideals of `B` above a given prime ideal of `A`. -/ lemma Algebra.IsInvariant.exists_smul_of_under_eq_of_profinite [Algebra.IsInvariant A B G] (P Q : Ideal B) [P.IsPrime] [Q.IsPrime] diff --git a/Mathlib/RingTheory/IsAdjoinRoot.lean b/Mathlib/RingTheory/IsAdjoinRoot.lean index b6e031fb808da2..4ef8c7a7b19220 100644 --- a/Mathlib/RingTheory/IsAdjoinRoot.lean +++ b/Mathlib/RingTheory/IsAdjoinRoot.lean @@ -317,10 +317,12 @@ theorem coe_liftHom : (h.liftHom x hx' : S →+* T) = h.lift (algebraMap R T) x theorem lift_algebraMap_apply (z : S) : h.lift (algebraMap R T) x hx' z = h.liftHom x hx' z := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem liftHom_map (z : R[X]) : h.liftHom x hx' (h.map z) = aeval x z := by rw [← lift_algebraMap_apply, lift_map, aeval_def] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem liftHom_root : h.liftHom x hx' h.root = x := by rw [← lift_algebraMap_apply, lift_root] @@ -410,6 +412,7 @@ theorem modByMonicHom_root_pow {n : ℕ} (hdeg : n < natDegree f) : theorem modByMonicHom_root (hdeg : 1 < natDegree f) : h.modByMonicHom h.root = X := by simpa using modByMonicHom_root_pow h hdeg +set_option backward.isDefEq.respectTransparency.types false in /-- The basis on `S` generated by powers of `h.root`. Auxiliary definition for `IsAdjoinRootMonic.powerBasis`. -/ @@ -445,6 +448,7 @@ def basis : Basis (Fin (natDegree f)) R S where repr.map_add' := by simp [Finsupp.comapDomain_add_of_injective Fin.val_injective] repr.map_smul' := by simp [Finsupp.comapDomain_smul_of_injective Fin.val_injective] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem basis_apply (i) : h.basis i = h.root ^ (i : ℕ) := Basis.apply_eq_iff.mpr <| by simp [IsAdjoinRootMonic.basis] @@ -465,6 +469,7 @@ def powerBasis : PowerBasis R S where basis := h.basis basis_eq_pow := h.basis_apply +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem basis_repr (x : S) (i : Fin (natDegree f)) : h.basis.repr x i = (h.modByMonicHom x).coeff (i : ℕ) := by @@ -576,6 +581,7 @@ variable (h : IsAdjoinRoot S f) section lift +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem lift_self_apply (x : S) : h.lift (algebraMap R S) h.root h.aeval_root_self x = x := by rw [← h.map_repr x, lift_map, ← aeval_def, h.aeval_root_eq_map] @@ -643,6 +649,7 @@ theorem minpoly_eq [IsDomain R] [IsDomain S] [IsTorsionFree R S] [IsIntegrallyCl (hirr.isUnit_or_isUnit hq).resolve_left <| minpoly.not_isUnit R h.root rw [mul_one] +set_option backward.isDefEq.respectTransparency.types false in /-- If `α` generates `S` as an algebra and `S` is free and finite, then `S` is given by adjoining a root of `minpoly R α`. Does not require that `R` is an integral domain, unlike `mkOfAdjoinEqTop`. -/ diff --git a/Mathlib/RingTheory/IsPrimary.lean b/Mathlib/RingTheory/IsPrimary.lean index ddb0173fd381ee..c69a3f4707ecdb 100644 --- a/Mathlib/RingTheory/IsPrimary.lean +++ b/Mathlib/RingTheory/IsPrimary.lean @@ -114,6 +114,7 @@ section CommRing variable {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] {S : Submodule R M} +set_option backward.isDefEq.respectTransparency false in lemma isPrimary_iff_zero_divisor_quotient_imp_nilpotent_smul : S.IsPrimary ↔ S ≠ ⊤ ∧ ∀ (r : R) (x : M ⧸ S), x ≠ 0 → r • x = 0 → ∃ n : ℕ, r ^ n • (⊤ : Submodule R (M ⧸ S)) = ⊥ := by diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index a01b7253707b93..6d880f1416b26b 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -175,6 +175,7 @@ variable {R S : Type*} [CommSemiring R] [CommSemiring S] [Algebra R S] [Module R M₂₃] [Module S M₂₃] [IsScalarTower R S M₂₃] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- (Implementation): Use the more linear `IsTensorProduct.assoc`. -/ private noncomputable def assocAux (f : M₁ →ₗ[R] M₂ →ₗ[S] M₁₂) (hf : IsTensorProduct (f.restrictScalars₁₂ R R)) @@ -208,6 +209,7 @@ private lemma assocAux_symm_tmul (x₁ : M₁) (x₂ : M₂) (x₃ : M₃) : (IsTensorProduct.assocAux f hf g hg).symm (x₁ ⊗ₜ g x₂ x₃) = f x₁ x₂ ⊗ₜ x₃ := by simp [IsTensorProduct.assocAux] +set_option backward.isDefEq.respectTransparency.types false in @[simp] private lemma assocAux_tmul (x₁ : M₁) (x₂ : M₂) (x₃ : M₃) : IsTensorProduct.assocAux f hf g hg (f x₁ x₂ ⊗ₜ x₃) = x₁ ⊗ₜ g x₂ x₃ := by @@ -215,6 +217,7 @@ private lemma assocAux_tmul (x₁ : M₁) (x₂ : M₂) (x₃ : M₃) : simp [IsTensorProduct.assocAux, this] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- This is the canonical isomorphism `(M₁ ⊗[R] M₂) ⊗[S] M₃ ≃ₗ[T] M₁ ⊗[R] (M₂ ⊗[S] M₃)`. We state this for a general `M₁₂ = M₁ ⊗[R] M₂` and `M₂₃ = M₂ ⊗[R] M₃`. @@ -396,6 +399,7 @@ theorem TensorProduct.isBaseChange : IsBaseChange S (TensorProduct.mk R S M 1) : variable {R M N S} +set_option backward.isDefEq.respectTransparency false in /-- The base change of `M` along `R → S` is linearly equivalent to `S ⊗[R] M`. -/ noncomputable nonrec def IsBaseChange.equiv : S ⊗[R] M ≃ₗ[S] N := { h.equiv with @@ -416,6 +420,7 @@ theorem IsBaseChange.equiv_tmul (s : S) (m : M) : h.equiv (s ⊗ₜ m) = s • f theorem IsBaseChange.equiv_symm_apply (m : M) : h.equiv.symm (f m) = 1 ⊗ₜ m := by rw [h.equiv.symm_apply_eq, h.equiv_tmul, one_smul] +set_option backward.isDefEq.respectTransparency false in lemma IsBaseChange.of_equiv (e : S ⊗[R] M ≃ₗ[S] N) (he : ∀ x, e (1 ⊗ₜ x) = f x) : IsBaseChange S f := by apply IsTensorProduct.of_equiv (e.restrictScalars R) @@ -702,6 +707,7 @@ noncomputable def Algebra.pushoutDesc [H : Algebra.IsPushout R S R' S'] {A : Typ (Algebra.TensorProduct.lift f g hf).comp ((Algebra.IsPushout.equiv R S R' S').symm.toAlgHom.restrictScalars R) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem Algebra.pushoutDesc_left [Algebra.IsPushout R S R' S'] {A : Type*} [Semiring A] [Algebra R A] (f : S →ₐ[R] A) (g : R' →ₐ[R] A) (H) (x : S) : @@ -713,6 +719,7 @@ theorem Algebra.lift_algHom_comp_left [Algebra.IsPushout R S R' S'] {A : Type*} (Algebra.pushoutDesc S' f g H).comp (toAlgHom R S S') = f := AlgHom.ext fun x => (Algebra.pushoutDesc_left S' f g H x :) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem Algebra.pushoutDesc_right [Algebra.IsPushout R S R' S'] {A : Type*} [Semiring A] [Algebra R A] (f : S →ₐ[R] A) (g : R' →ₐ[R] A) (H) (x : R') : @@ -847,6 +854,7 @@ lemma IsPushout.cancelBaseChangeAlg_tmul (c : C) : IsPushout.cancelBaseChangeAlg R S A B C (1 ⊗ₜ c) = 1 ⊗ₜ c := by simp [cancelBaseChangeAlg] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma IsPushout.cancelBaseChangeAlg_symm_tmul (s : S) (c : C) : (IsPushout.cancelBaseChangeAlg R S A B C).symm (s ⊗ₜ c) = algebraMap S B s ⊗ₜ c := by diff --git a/Mathlib/RingTheory/Kaehler/Basic.lean b/Mathlib/RingTheory/Kaehler/Basic.lean index 7ea020e7aa01b1..f8e1406b7db292 100644 --- a/Mathlib/RingTheory/Kaehler/Basic.lean +++ b/Mathlib/RingTheory/Kaehler/Basic.lean @@ -509,6 +509,7 @@ theorem KaehlerDifferential.kerTotal_mkQ_single_smul (r : R) (x y) : (y𝖣r • KaehlerDifferential.kerTotal_mkQ_single_algebraMap, add_zero, ← LinearMap.map_smul_of_tower, Finsupp.smul_single, mul_comm, Algebra.smul_def] +set_option backward.isDefEq.respectTransparency.types false in /-- The (universal) derivation into `(S →₀ S) ⧸ KaehlerDifferential.kerTotal R S`. -/ noncomputable def KaehlerDifferential.derivationQuotKerTotal : Derivation R S ((S →₀ S) ⧸ KaehlerDifferential.kerTotal R S) where diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index 58f83e3c6511f7..ee13f7d06e5376 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -392,6 +392,7 @@ lemma δ_eq (x : Q.toExtension.H1Cotangent) (y) apply SnakeLemma.δ_eq exacts [hy, hz] +set_option backward.isDefEq.respectTransparency.types false in lemma δ_eq_δAux (x : Q.ker) (hx) : δ Q P ⟨.mk x, hx⟩ = δAux R Q x.1 := by let y := Extension.Cotangent.mk (P := (Q.comp P).toExtension) (Q.kerCompPreimage P x) @@ -415,11 +416,13 @@ lemma δ_eq_δAux (x : Q.ker) (hx) : ((Q.comp P).toExtension.cotangentComplex y) rw [CotangentSpace.fst_compEquiv, Extension.CotangentSpace.map_cotangentComplex, hy, hx] +set_option backward.isDefEq.respectTransparency.types false in lemma δ_C {r : S} (hr : C r ∈ Q.ker) : δ Q P ⟨Extension.Cotangent.mk ⟨C r, hr⟩, Extension.Cotangent.mk_C_mem_ker_cotangentComplex ..⟩ = 1 ⊗ₜ[S] D R S r := by rw [δ_eq_δAux, δAux_C] +set_option backward.isDefEq.respectTransparency.types false in lemma δ_eq_δ : δ Q P = δ Q P' := by ext ⟨x, hx⟩ obtain ⟨x, rfl⟩ := Extension.Cotangent.mk_surjective x @@ -461,6 +464,7 @@ lemma exact_map_δ' (f : Hom W Q) : rw [← Extension.H1Cotangent.map_comp, Extension.H1Cotangent.map_eq _ (Q.ofComp P).toExtensionHom] exact exact_map_δ Q P +set_option backward.isDefEq.respectTransparency.types false in open LinearMap in lemma liftBaseChange_range_le : (liftBaseChange T (Extension.H1Cotangent.map (Q.toComp P).toExtensionHom)).range ≤ @@ -475,6 +479,7 @@ lemma liftBaseChange_range_le : x_in, RingHom.map_zero] exact Ideal.zero_mem _ +set_option backward.isDefEq.respectTransparency.types false in private lemma auxMemKer (z : T ⊗[S] P.toExtension.H1Cotangent) : LinearMap.liftBaseChange T (Extension.Cotangent.map (Q.toComp P).toExtensionHom) ((LinearMap.lTensor T Extension.h1Cotangentι) z) ∈ @@ -484,6 +489,7 @@ private lemma auxMemKer (z : T ⊗[S] P.toExtension.H1Cotangent) : | tmul x y => simp [← Extension.CotangentSpace.map_cotangentComplex] | add x y hx hy => simpa using Submodule.add_mem _ hx hy +set_option backward.isDefEq.respectTransparency.types false in open LinearMap in /-- When $T$ is flat over $S$, the left bottom part of the snake lemma diagram used in the construction of the connecting homomorphism `Algebra.Generators.H1Cotangent.δ` diff --git a/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean b/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean index 02ba2e127fcead..6b8f97239bf5b0 100644 --- a/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean +++ b/Mathlib/RingTheory/KrullDimension/NonZeroDivisors.lean @@ -33,6 +33,7 @@ lemma ringKrullDim_quotient (I : Ideal R) : ringKrullDim (R ⧸ I) = Order.krullDim (PrimeSpectrum.zeroLocus (R := R) I) := by rw [ringKrullDim, Order.krullDim_eq_of_orderIso I.primeSpectrumQuotientOrderIsoZeroLocus] +set_option backward.isDefEq.respectTransparency false in lemma ringKrullDim_quotient_succ_le_of_nonZeroDivisor {r : R} (hr : r ∈ R⁰) : ringKrullDim (R ⧸ Ideal.span {r}) + 1 ≤ ringKrullDim R := by diff --git a/Mathlib/RingTheory/KrullDimension/Regular.lean b/Mathlib/RingTheory/KrullDimension/Regular.lean index 28d87d1a5cc7ca..7428318395e51b 100644 --- a/Mathlib/RingTheory/KrullDimension/Regular.lean +++ b/Mathlib/RingTheory/KrullDimension/Regular.lean @@ -30,6 +30,7 @@ variable {R : Type*} [CommRing R] [IsNoetherianRing R] open RingTheory Sequence IsLocalRing Ideal PrimeSpectrum Pointwise +set_option backward.isDefEq.respectTransparency.types false in omit [IsNoetherianRing R] [Module.Finite R M] in lemma exists_ltSeries_support_isMaximal_last_of_ltSeries_support (q : LTSeries (support R M)) : ∃ p : LTSeries (support R M), q.length ≤ p.length ∧ p.last.1.1.IsMaximal := by @@ -73,6 +74,7 @@ theorem supportDim_le_supportDim_quotSMulTop_succ_of_mem_jacobson {x : R} grw [le_tsub_add (b := p.length) (a := 1), Nat.cast_add_one, supportDim, Order.krullDim, ← le_iSup _ q'] +set_option backward.isDefEq.respectTransparency.types false in omit [IsNoetherianRing R] in /-- If `M` is a finite module over a commutative ring `R`, `x ∈ M` is not in any minimal prime of `M`, then `dim M/xM + 1 ≤ dim M`. -/ diff --git a/Mathlib/RingTheory/Lasker.lean b/Mathlib/RingTheory/Lasker.lean index ba48f31b456057..e3daaf80a1bf6b 100644 --- a/Mathlib/RingTheory/Lasker.lean +++ b/Mathlib/RingTheory/Lasker.lean @@ -196,7 +196,7 @@ lemma comap_localized₀_eq_ite simp_rw [mem_localized₀, IsLocalizedModule.mk'_eq_iff, ← LinearMap.map_smul_of_tower] exact ⟨y • x, hy1 (Set.smul_mem_smul_set (Set.mem_univ x)), ⟨y, hy2⟩, rfl⟩ -open LocalizedModule IsLocalizedModule in +open LocalizedModule Submodule.IsLocalizedModule in /-- The second uniqueness theorem for primary decomposition, Theorem 4.10 in Atiyah-Macdonald. -/ lemma comap_localized₀_eq_iInf {t : Finset (Submodule R M)} (ht : N.IsMinimalPrimaryDecomposition t) diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index 0f63f96ec0b8ab..a5167ec91df88e 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -905,6 +905,7 @@ lemma exists_ratFunc_eq_v (x : K⸨X⸩) : ∃ f : K⟮X⟯, Valued.v f = Valued open MonoidWithZeroHom.ValueGroup₀ +set_option backward.isDefEq.respectTransparency.types false in theorem inducing_coe : IsUniformInducing ((↑) : K⟮X⟯ → K⸨X⸩) := by rw [isUniformInducing_iff, Filter.comap] ext S @@ -1069,6 +1070,7 @@ theorem valuation_LaurentSeries_equal_extension : rfl · exact Valued.continuous_valuation_of_surjective (valuation_surjective K) +set_option backward.isDefEq.respectTransparency.types false in theorem tendsto_valuation (a : (idealX K).adicCompletion K⟮X⟯) : Tendsto (Valued.v : K⟮X⟯ → ℤᵐ⁰) (comap (↑) (𝓝 a)) (𝓝 (Valued.v a : ℤᵐ⁰)) := by have := Valued.is_topological_valuation (R := (idealX K).adicCompletion K⟮X⟯) @@ -1098,6 +1100,7 @@ theorem tendsto_valuation (a : (idealX K).adicCompletion K⟮X⟯) : rw [← valuedAdicCompletion_eq_valuation'] exact (Valuation.restrict_inj _).mp <| Valuation.map_eq_of_sub_lt Valued.v.restrict val_y +set_option backward.isDefEq.respectTransparency false in /-- The extension of the `X`-adic valuation from `K⟮X⟯` up to its abstract completion coincides, modulo the isomorphism with `K⸨X⸩`, with the `X`-adic valuation on `K⸨X⸩`. -/ theorem valuation_compare (f : K⸨X⸩) : @@ -1143,6 +1146,7 @@ lemma powerSeriesEquivSubring_coe_apply (f : K⟦X⟧) : (powerSeriesEquivSubring K f : K⸨X⸩) = ofPowerSeries ℤ K f := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Through the isomorphism `LaurentSeriesRingEquiv`, power series land in the unit ball inside the completion of `K⟮X⟯`. -/ theorem mem_integers_of_powerSeries (F : K⟦X⟧) : diff --git a/Mathlib/RingTheory/LittleWedderburn.lean b/Mathlib/RingTheory/LittleWedderburn.lean index a3a327f76cb297..870e6ee37a8b76 100644 --- a/Mathlib/RingTheory/LittleWedderburn.lean +++ b/Mathlib/RingTheory/LittleWedderburn.lean @@ -55,13 +55,14 @@ open Module Polynomial variable {D} -@[implicit_reducible] +@[instance_reducible] private def field (hD : InductionHyp D) {R : Subring D} (hR : R < ⊤) [Fintype D] [DecidableEq D] [DecidablePred (· ∈ R)] : Field R := { show DivisionRing R from Fintype.divisionRingOfIsDomain R with mul_comm := fun x y ↦ Subtype.ext <| hD hR x.2 y.2 } +set_option backward.isDefEq.respectTransparency.types false in /-- We prove that if every subring of `D` is central, then so is `D`. -/ private theorem center_eq_top [Finite D] (hD : InductionHyp D) : Subring.center D = ⊤ := by classical diff --git a/Mathlib/RingTheory/LocalProperties/Basic.lean b/Mathlib/RingTheory/LocalProperties/Basic.lean index 0ad855e9bca672..c5753147bab3af 100644 --- a/Mathlib/RingTheory/LocalProperties/Basic.lean +++ b/Mathlib/RingTheory/LocalProperties/Basic.lean @@ -423,6 +423,7 @@ lemma RingHom.OfLocalizationSpan.ofIsLocalization' exact ⟨Rᵣ, Sᵣ, inferInstance, inferInstance, inferInstance, inferInstance, inferInstance, inferInstance, IsLocalization.Away.map Rᵣ Sᵣ f r, IsLocalization.map_comp _, hf⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma RingHom.OfLocalizationSpanTarget.ofIsLocalization (hP : RingHom.OfLocalizationSpanTarget P) (hP' : RingHom.RespectsIso P) {R S : Type u} [CommRing R] [CommRing S] (f : R →+* S) (s : Set S) (hs : Ideal.span s = ⊤) diff --git a/Mathlib/RingTheory/LocalProperties/Projective.lean b/Mathlib/RingTheory/LocalProperties/Projective.lean index 668948e2ba7be2..d0077f8277ba91 100644 --- a/Mathlib/RingTheory/LocalProperties/Projective.lean +++ b/Mathlib/RingTheory/LocalProperties/Projective.lean @@ -159,6 +159,7 @@ variable [inst : ∀ (P : Ideal R) [P.IsMaximal], IsLocalizedModule P.primeCompl (f P)] set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in attribute [local instance] RingHomInvPair.of_ringEquiv RingHomInvPair.of_ringEquiv_symm in include f in /-- diff --git a/Mathlib/RingTheory/LocalRing/LocalSubring.lean b/Mathlib/RingTheory/LocalRing/LocalSubring.lean index 1d1c24ddd30fdb..eb50662accec03 100644 --- a/Mathlib/RingTheory/LocalRing/LocalSubring.lean +++ b/Mathlib/RingTheory/LocalRing/LocalSubring.lean @@ -83,6 +83,7 @@ section ofPrime variable (A : Subring K) (P : Ideal A) [P.IsPrime] +set_option backward.isDefEq.respectTransparency false in /-- The localization of a subring at a prime, as a local subring. Also see `Localization.subalgebra.ofField` -/ noncomputable @@ -99,6 +100,7 @@ instance : Algebra A (ofPrime A P).toSubring := (Subring.inclusion (le_ofPrime A instance : IsScalarTower A (ofPrime A P).toSubring K := .of_algebraMap_eq (fun _ ↦ rfl) +set_option backward.isDefEq.respectTransparency false in -- see https://github.com/leanprover-community/mathlib4/issues/29041 set_option linter.unusedSimpArgs false in /-- The localization of a subring at a prime is indeed isomorphic to its abstract localization. -/ diff --git a/Mathlib/RingTheory/LocalRing/Module.lean b/Mathlib/RingTheory/LocalRing/Module.lean index 44da2179c9b467..625f2413fff425 100644 --- a/Mathlib/RingTheory/LocalRing/Module.lean +++ b/Mathlib/RingTheory/LocalRing/Module.lean @@ -251,6 +251,7 @@ theorem free_of_maximalIdeal_rTensor_injective [Module.FinitePresentation R M] obtain ⟨_, _, b, _⟩ := exists_basis_of_span_of_maximalIdeal_rTensor_injective H id (by simp) exact Free.of_basis b +set_option backward.isDefEq.respectTransparency.types false in theorem IsLocalRing.linearIndependent_of_flat [Flat R M] {ι : Type u} (v : ι → M) (h : LinearIndependent k (TensorProduct.mk R k M 1 ∘ v)) : LinearIndependent R v := by rw [linearIndependent_iff']; intro s f hfv i hi @@ -288,6 +289,7 @@ theorem IsLocalRing.linearIndependent_of_flat [Flat R M] {ι : Type u} (v : ι intro i hi; rw [ih i hi, zero_mul] · exact ih i hi +set_option backward.isDefEq.respectTransparency.types false in open Finsupp in theorem IsLocalRing.linearCombination_bijective_of_flat [Module.Finite R M] [Flat R M] {ι : Type u} (v : ι → M) (h : Function.Bijective (linearCombination k (TensorProduct.mk R k M 1 ∘ v))) : diff --git a/Mathlib/RingTheory/LocalRing/Pullback.lean b/Mathlib/RingTheory/LocalRing/Pullback.lean index 544f6634a4a90c..261ce986986fe4 100644 --- a/Mathlib/RingTheory/LocalRing/Pullback.lean +++ b/Mathlib/RingTheory/LocalRing/Pullback.lean @@ -63,6 +63,7 @@ theorem pullback_comm_sq (f : R →+* T) (g : S →+* T) : f.comp (f.pullbackFst g) = g.comp (f.pullbackSnd g) := ext fun x ↦ x.prop +set_option backward.isDefEq.respectTransparency.types false in theorem isUnit_pullback_mk_iff (f : R →+* T) (g : S →+* T) {a : R × S} (a_in : a ∈ f.pullback g) : IsUnit (⟨a, a_in⟩ : f.pullback g) ↔ IsUnit a.1 ∧ IsUnit a.2 := by rw [isUnit_eqLocus_mk_iff, Prod.isUnit_iff] diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean index 4922d98f03efa2..f2760376f95147 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Ideal.lean @@ -55,6 +55,7 @@ lemma RingHom.SurjectiveOnStalks.residueFieldMap_bijective exact ⟨RingHom.injective _, Ideal.Quotient.lift_surjective_of_surjective _ _ (Ideal.Quotient.mk_surjective.comp (H J ‹_›))⟩ +set_option backward.isDefEq.respectTransparency false in /-- If `I = f⁻¹(J)`, then there is a canonical embedding `κ(I) ↪ κ(J)`. -/ noncomputable def Ideal.ResidueField.mapₐ (I : Ideal A) [I.IsPrime] (J : Ideal B) [J.IsPrime] @@ -209,6 +210,7 @@ noncomputable def Ideal.ResidueField.lift IsLocalization.lift (M := (R ⧸ I)⁰) (g := Ideal.Quotient.lift I (f := f) hf₁) <| by simpa [Ideal.Quotient.mk_surjective.forall, Ideal.Quotient.eq_zero_iff_mem] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma Ideal.ResidueField.lift_algebraMap (f : R →+* S) (hf₁ : I ≤ RingHom.ker f) (hf₂ : I.primeCompl ≤ (IsUnit.submonoid S).comap f) (r : R) : @@ -244,5 +246,6 @@ lemma Ideal.ResidueField.algHom_ext {I : Ideal A} [I.IsPrime] {f g : I.ResidueFi (H : f.comp (IsScalarTower.toAlgHom R A _) = g.comp (IsScalarTower.toAlgHom R A _)) : f = g := AlgHom.coe_ringHom_injective (ringHom_ext congr($H)) +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Ideal.ResidueField.mapₐ_id (I : Ideal A) [I.IsPrime] : Ideal.ResidueField.mapₐ I I (.id R A) rfl = .id _ _ := by ext; simp diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean index 3fec529a17962f..2d40980d8860d9 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Instances.lean @@ -27,6 +27,7 @@ variable [p.IsMaximal] [q.IsMaximal] [Algebra (Localization.AtPrime p) (Localiza attribute [local instance] Ideal.Quotient.field +set_option backward.isDefEq.respectTransparency.types false in instance [Algebra.IsSeparable (A ⧸ p) (B ⧸ q)] : Algebra.IsSeparable p.ResidueField q.ResidueField := by refine Algebra.IsSeparable.of_equiv_equiv @@ -35,6 +36,7 @@ instance [Algebra.IsSeparable (A ⧸ p) (B ⧸ q)] : ext x simp [RingHom.algebraMap_toAlgebra, ← IsScalarTower.algebraMap_apply] +set_option backward.isDefEq.respectTransparency.types false in instance [Algebra.IsSeparable p.ResidueField q.ResidueField] : Algebra.IsSeparable (A ⧸ p) (B ⧸ q) := by refine Algebra.IsSeparable.of_equiv_equiv @@ -64,6 +66,7 @@ variable [p.IsPrime] [q.IsPrime] [Algebra (Localization.AtPrime p) (Localization instance : Algebra.IsAlgebraic (A ⧸ p) p.ResidueField := IsLocalization.isAlgebraic _ (nonZeroDivisors (A ⧸ p)) +set_option backward.isDefEq.respectTransparency.types false in instance [Algebra.IsIntegral A B] : Algebra.IsAlgebraic p.ResidueField q.ResidueField := by have : Algebra.IsIntegral (A ⧸ p) (B ⧸ q) := diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean index 93440dd039a746..10e950a6ba0884 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean @@ -29,6 +29,7 @@ variable (I : Ideal R) [I.IsPrime] (J : Ideal R[X]) [J.IsPrime] [J.LiesOver I] [Localization.AtPrime.IsLiesOverAlgebra I J] +set_option backward.isDefEq.respectTransparency.types false in /-- `κ(I[X]) ≃ₐ[κ(I)] κ(I)(X)`. -/ noncomputable def residueFieldMapCAlgEquiv (hJ : J = I.map C) : @@ -95,6 +96,7 @@ lemma residueFieldMapCAlgEquiv_symm_X (hJ : J = I.map C) : (residueFieldMapCAlgEquiv I J hJ).symm .X = algebraMap R[X] _ .X := (residueFieldMapCAlgEquiv I J hJ).injective (by simp) +set_option backward.isDefEq.respectTransparency.types false in /-- `κ(p) ⊗[R] (R[X] ⧸ I) = κ(p)[X] / I` -/ noncomputable def fiberEquivQuotient (f : R[X] →ₐ[R] S) (hf : Function.Surjective f) (p : Ideal R) [p.IsPrime] : @@ -118,6 +120,7 @@ def fiberEquivQuotient (f : R[X] →ₐ[R] S) (hf : Function.Surjective f) (p : simpa using aeval_algHom_apply ((Algebra.TensorProduct.includeRight : S →ₐ[_] p.Fiber S).comp f) X x +set_option backward.isDefEq.respectTransparency.types false in lemma fiberEquivQuotient_tmul (f : R[X] →ₐ[R] S) (hf : Function.Surjective f) (p : Ideal R) [p.IsPrime] (a b) : fiberEquivQuotient f hf p (a ⊗ₜ f b) = Ideal.Quotient.mk _ (C a * b.map (algebraMap _ _)) := by diff --git a/Mathlib/RingTheory/Localization/AtPrime/Basic.lean b/Mathlib/RingTheory/Localization/AtPrime/Basic.lean index 429a6fba691abb..235578219a2783 100644 --- a/Mathlib/RingTheory/Localization/AtPrime/Basic.lean +++ b/Mathlib/RingTheory/Localization/AtPrime/Basic.lean @@ -139,6 +139,7 @@ namespace AtPrime variable (I : Ideal R) [hI : I.IsPrime] [IsLocalization.AtPrime S I] +set_option backward.isDefEq.respectTransparency false in /-- The prime ideals in the localization of a commutative ring at a prime ideal I are in order-preserving bijection with the prime ideals contained in I. -/ @[simps!] @@ -359,7 +360,7 @@ variable {A B C : Type*} [CommSemiring A] [CommSemiring B] [Algebra R A] [Algebr /-- If `P` lies over `p`, then `Localization.AtPrime P` is an algebra over `Localization.AtPrime p`. This is not an instance for performance reasons and to avoid diamonds in the situation where the top ring is already an algebra over `Localization.AtPrime p` (e.g., this happens for `Ideal.Fiber`). -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def algebraOfLiesOver (p : Ideal A) [p.IsPrime] (P : Ideal B) [P.IsPrime] [P.LiesOver p] : Algebra (Localization.AtPrime p) (Localization.AtPrime P) := @@ -436,6 +437,9 @@ noncomputable def localAlgHom' (f : S →ₐ[R] P) (h : J = K.comap f) : Localization.AtPrime J →ₐ[Localization.AtPrime I] Localization.AtPrime K := (localAlgHom J K f h).extendScalarsOfIsLocalization (Localization.AtPrime I) I.primeCompl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Isomorphic algebras have isomorphic localizations. See `localAlgEquiv` for a variant where the base ring is not localized. -/ @@ -453,12 +457,14 @@ section variable (q : Ideal R) [q.IsPrime] (M : Submonoid R) {S : Type*} [CommSemiring S] [Algebra R S] [IsLocalization.AtPrime S q] +set_option backward.isDefEq.respectTransparency false in lemma Ideal.isPrime_map_of_isLocalizationAtPrime {p : Ideal R} [p.IsPrime] (hpq : p ≤ q) : (p.map (algebraMap R S)).IsPrime := by have disj : Disjoint (q.primeCompl : Set R) p := by simp [Ideal.primeCompl, ← le_compl_iff_disjoint_left, hpq] apply IsLocalization.isPrime_of_isPrime_disjoint q.primeCompl _ p (by simpa) disj +set_option backward.isDefEq.respectTransparency false in lemma Ideal.under_map_of_isLocalizationAtPrime {p : Ideal R} [p.IsPrime] (hpq : p ≤ q) : (p.map (algebraMap R S)).under R = p := by have disj : Disjoint (q.primeCompl : Set R) p := by @@ -592,6 +598,7 @@ theorem equivQuotMaximalIdeal_symm_apply_mk (x : R) (s : p.primeCompl) : mk'_spec, Ideal.Quotient.mk_algebraMap, equivQuotMaximalIdeal_apply_mk, Ideal.Quotient.mk_algebraMap] +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism `R ⧸ p ^ n ≃ₐ[R] Rₚ ⧸ maximalIdeal Rₚ ^ n`, where `Rₚ` satisfies `IsLocalization.AtPrime Rₚ p`. -/ noncomputable @@ -617,6 +624,7 @@ theorem equivQuotMaximalIdealPow_apply_mk (n : ℕ) (x : R) : Ideal.Quotient.mk _ (algebraMap R Rₚ x) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem equivQuotMaximalIdealPow_symm_apply_mk_mul (n : ℕ) (x : R) (s : p.primeCompl) : (equivQuotMaximalIdealPow p Rₚ n).symm (Ideal.Quotient.mk _ (IsLocalization.mk' Rₚ x s)) * diff --git a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean index 8a0d964af4889c..4838dac25d0f29 100644 --- a/Mathlib/RingTheory/Localization/AtPrime/Extension.lean +++ b/Mathlib/RingTheory/Localization/AtPrime/Extension.lean @@ -207,6 +207,7 @@ open IsLocalization AtPrime variable [IsDomain R] [IsDedekindDomain S] [IsTorsionFree R S] [Algebra R Sₚ] [IsScalarTower R S Sₚ] [IsScalarTower R Rₚ Sₚ] +set_option backward.isDefEq.respectTransparency.types false in /-- For `R ⊆ S` an extension of Dedekind domains and `p` a prime ideal of `R`, the bijection between the primes of `S` over `p` and the primes over the maximal ideal of `Rₚ` in `Sₚ` where diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index fafd44416928b5..91a6038ceb3787 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -246,6 +246,7 @@ instance (x : R) [IsLocalization.Away (algebraMap R A x) Aₚ] : IsLocalization (Algebra.algebraMapSubmonoid A (.powers x)) Aₚ := by simpa +set_option backward.isDefEq.respectTransparency false in /-- Given an algebra map `f : A →ₐ[R] B` and an element `a : A`, we may construct a map `Aₐ →ₐ[R] Bₐ`. -/ noncomputable def mapₐ (f : A →ₐ[R] B) (a : A) [Away a Aₚ] [Away (f a) Bₚ] : Aₚ →ₐ[R] Bₚ := @@ -662,6 +663,7 @@ theorem selfZPow_of_nonpos {n : ℤ} (hn : n ≤ 0) : theorem selfZPow_neg_natCast (d : ℕ) : selfZPow x B (-d) = mk' _ (1 : R) (Submonoid.pow x d) := by simp [selfZPow_of_nonpos _ _ (neg_nonpos.mpr (Int.natCast_nonneg d))] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem selfZPow_sub_natCast {n m : ℕ} : selfZPow x B (n - m) = mk' _ (x ^ n) (Submonoid.pow x m) := by @@ -690,6 +692,7 @@ theorem selfZPow_add {n m : ℤ} : selfZPow x B (n + m) = selfZPow x B n * selfZ ext simp [pow_add] +set_option backward.isDefEq.respectTransparency false in theorem selfZPow_mul_neg (d : ℤ) : selfZPow x B d * selfZPow x B (-d) = 1 := by by_cases! hd : d ≤ 0 · rw [selfZPow_of_nonpos x B hd, selfZPow_of_nonneg, ← map_pow, Int.natAbs_neg, diff --git a/Mathlib/RingTheory/Localization/BaseChange.lean b/Mathlib/RingTheory/Localization/BaseChange.lean index deb3adecb4afca..7f2e4bbf9bcc3d 100644 --- a/Mathlib/RingTheory/Localization/BaseChange.lean +++ b/Mathlib/RingTheory/Localization/BaseChange.lean @@ -316,6 +316,7 @@ theorem tensorLeftAlgEquiv_apply_tmul_one (x : S) : tensorLeftAlgEquiv M S (x ⊗ₜ[R] 1) = algebraMap _ _ x := (tensorLeftAlgEquiv M S).commutes x +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem tensorLeftAlgEquiv_apply_one_tmul (x : Localization M) : tensorLeftAlgEquiv M S (1 ⊗ₜ[R] x) = algebraMap _ _ x := by diff --git a/Mathlib/RingTheory/Localization/Basic.lean b/Mathlib/RingTheory/Localization/Basic.lean index f70e235d540cbd..3ed65e4233f647 100644 --- a/Mathlib/RingTheory/Localization/Basic.lean +++ b/Mathlib/RingTheory/Localization/Basic.lean @@ -130,6 +130,7 @@ section CompatibleSMul variable (N₁ N₂ : Type*) [AddCommMonoid N₁] [AddCommMonoid N₂] [Module R N₁] [Module R N₂] +set_option backward.isDefEq.respectTransparency false in variable (M S) in include M in theorem linearMap_compatibleSMul [Module S N₁] [Module S N₂] @@ -224,6 +225,7 @@ variable {A : Type*} [CommSemiring A] include H set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- If `S`, `Q` are localizations of `R` and `P` at submonoids `M`, `T` respectively, an isomorphism `h : R ≃ₐ[A] P` such that `h(M) = T` induces an isomorphism of localizations `S ≃ₐ[A] Q`. -/ @@ -240,10 +242,12 @@ theorem algEquivOfAlgEquiv_eq_map : map Q (h : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) := rfl +set_option backward.isDefEq.respectTransparency false in theorem algEquivOfAlgEquiv_eq (x : R) : algEquivOfAlgEquiv S Q h H ((algebraMap R S) x) = algebraMap P Q (h x) := by simp +set_option backward.isDefEq.respectTransparency false in set_option linter.docPrime false in theorem algEquivOfAlgEquiv_mk' (x : R) (y : M) : algEquivOfAlgEquiv S Q h H (mk' S x y) = @@ -300,6 +304,7 @@ instance : IsLocalization (Algebra.algebraMapSubmonoid S (IsUnit.submonoid R)) S variable (R M) +set_option backward.isDefEq.respectTransparency false in /-- The localization at a module of units is isomorphic to the ring. -/ noncomputable def atUnits (H : M ≤ IsUnit.submonoid R) : R ≃ₐ[R] S := by refine AlgEquiv.ofBijective (Algebra.ofId R S) ⟨?_, ?_⟩ @@ -453,7 +458,7 @@ noncomputable def algEquiv : Localization M ≃ₐ[R] S := IsLocalization.algEquiv M _ _ /-- The localization of a singleton is a singleton. Cannot be an instance due to metavariables. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def _root_.IsLocalization.unique (R Rₘ) [CommSemiring R] [CommSemiring Rₘ] (M : Submonoid R) [Subsingleton R] [Algebra R Rₘ] [IsLocalization M Rₘ] : Unique Rₘ := have : Inhabited Rₘ := ⟨1⟩ @@ -524,7 +529,7 @@ This instance can be helpful if you define `Sₘ := Localization (Algebra.algebr however we will instead use the hypotheses `[Algebra Rₘ Sₘ] [IsScalarTower R Rₘ Sₘ]` in lemmas since the algebra structure may arise in different ways. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def localizationAlgebra : Algebra Rₘ Sₘ := (map Sₘ (algebraMap R S) (show _ ≤ (Algebra.algebraMapSubmonoid S M).comap _ from M.le_comap_map) : diff --git a/Mathlib/RingTheory/Localization/Defs.lean b/Mathlib/RingTheory/Localization/Defs.lean index f2084b62f2ecf9..c4ee68b3b7f6ed 100644 --- a/Mathlib/RingTheory/Localization/Defs.lean +++ b/Mathlib/RingTheory/Localization/Defs.lean @@ -307,7 +307,7 @@ theorem exists_mk'_eq (z : S) : ∃ (x : R) (y : M), mk' S x y = z := variable (S) in /-- The localization of a `Fintype` is a `Fintype`. Cannot be an instance. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintype' [Fintype R] : Fintype S := have := Classical.propDecidable .ofSurjective (Function.uncurry <| IsLocalization.mk' S) <| mk'_surjective M @@ -315,7 +315,7 @@ noncomputable def fintype' [Fintype R] : Fintype S := variable {M} /-- Localizing at a submonoid with 0 inside it leads to the trivial ring. -/ -@[implicit_reducible] +@[instance_reducible] def uniqueOfZeroMem (h : (0 : R) ∈ M) : Unique S := uniqueOfZeroEqOne <| by simpa using IsLocalization.map_units S ⟨0, h⟩ @@ -463,6 +463,7 @@ theorem mk'_add (x₁ x₂ : R) (y₁ y₂ : M) : simp only [map_add, Submonoid.coe_mul, map_mul] ring) +set_option backward.isDefEq.respectTransparency false in theorem mul_add_inv_left {g : R →+* P} (h : ∀ y : M, IsUnit (g y)) (y : M) (w z₁ z₂ : P) : w * ↑(IsUnit.liftRight (g.toMonoidHom.restrict M) h y)⁻¹ + z₁ = z₂ ↔ w + g y * z₁ = g y * z₂ := by @@ -660,6 +661,7 @@ section variable (S Q) +set_option backward.isDefEq.respectTransparency false in /-- If `S`, `Q` are localizations of `R` and `P` at submonoids `M, T` respectively, an isomorphism `j : R ≃+* P` such that `j(M) = T` induces an isomorphism of localizations `S ≃+* Q`. -/ diff --git a/Mathlib/RingTheory/Localization/Finiteness.lean b/Mathlib/RingTheory/Localization/Finiteness.lean index 47bb4f0edf9e92..789e01c7c2046c 100644 --- a/Mathlib/RingTheory/Localization/Finiteness.lean +++ b/Mathlib/RingTheory/Localization/Finiteness.lean @@ -45,6 +45,7 @@ variable {R S : Type*} [CommSemiring R] [CommSemiring S] (M : Submonoid R) (f : variable (R' S' : Type*) [CommSemiring R'] [CommSemiring S'] variable [Algebra R R'] [Algebra S S'] +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- Let `S` be an `R`-algebra, `M` a submonoid of `R`, and `S' = M⁻¹S`. If the image of some `x : S` falls in the span of some finite `s ⊆ S'` over `R`, @@ -137,6 +138,7 @@ variable {M : Type w} [AddCommMonoid M] [Module R M] variable {Mₚ : Type t} [AddCommMonoid Mₚ] [Module R Mₚ] [Module Rₚ Mₚ] [IsScalarTower R Rₚ Mₚ] variable (f : M →ₗ[R] Mₚ) [IsLocalizedModule S f] +set_option backward.isDefEq.respectTransparency false in lemma of_isLocalization (R S) {Rₚ Sₚ : Type*} [CommSemiring R] [CommSemiring S] [CommSemiring Rₚ] [CommSemiring Sₚ] [Algebra R S] [Algebra R Rₚ] [Algebra R Sₚ] [Algebra S Sₚ] [Algebra Rₚ Sₚ] [IsScalarTower R S Sₚ] [IsScalarTower R Rₚ Sₚ] (M : Submonoid R) diff --git a/Mathlib/RingTheory/Localization/FractionRing.lean b/Mathlib/RingTheory/Localization/FractionRing.lean index c403caf19d5c84..1198a37fc342d4 100644 --- a/Mathlib/RingTheory/Localization/FractionRing.lean +++ b/Mathlib/RingTheory/Localization/FractionRing.lean @@ -433,6 +433,7 @@ fraction rings `K ≃+* L`. -/ noncomputable def ringEquivOfRingEquiv : K ≃+* L := IsLocalization.ringEquivOfRingEquiv K L h (MulEquivClass.map_nonZeroDivisors h) +set_option backward.isDefEq.respectTransparency false in lemma ringEquivOfRingEquiv_algebraMap (a : A) : ringEquivOfRingEquiv h (algebraMap A K a) = algebraMap B L (h a) := by simp @@ -490,17 +491,21 @@ noncomputable def semilinearEquivOfRingEquiv : K ≃ₛₗ[(f : A →+* B)] L := { ringEquivOfRingEquiv f with map_smul' r x := by simp [Algebra.smul_def] } +set_option backward.isDefEq.respectTransparency.types false in lemma semilinearEquivOfRingEquiv_apply (x : K) : (semilinearEquivOfRingEquiv K L f) x = (ringEquivOfRingEquiv f) x := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma semilinearEquivOfRingEquiv_algebraMap (a : A) : semilinearEquivOfRingEquiv K L f (algebraMap A K a) = algebraMap B L (f a) := by simp [semilinearEquivOfRingEquiv, ringEquivOfRingEquiv] +set_option backward.isDefEq.respectTransparency.types false in lemma semilinearEquivOfRingEquiv_symm_apply (x : L) : (semilinearEquivOfRingEquiv K L f).symm x = (ringEquivOfRingEquiv f).symm x := rfl +set_option backward.isDefEq.respectTransparency.types false in lemma semilinearEquivOfRingEquiv_comp {C : Type*} (M : Type*) [CommRing C] [CommRing M] [Algebra C M] [IsFractionRing C M] (g : B ≃+* C) : let : RingHomCompTriple f (g : B →+* C) (f.trans g : A →+* C) := ⟨rfl⟩ @@ -528,6 +533,7 @@ fraction rings `K ≃ₐ[R] L`. -/ noncomputable def algEquivOfAlgEquiv : K ≃ₐ[R] L := IsLocalization.algEquivOfAlgEquiv K L h (MulEquivClass.map_nonZeroDivisors h) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma algEquivOfAlgEquiv_algebraMap (a : A) : algEquivOfAlgEquiv h (algebraMap A K a) = algebraMap B L (h a) := by @@ -647,7 +653,7 @@ variable (G A B K L : Type*) [Group G] [CommRing A] [CommRing B] [MulSemiringAct /-- Given a `MulSemiringAction G B`, extend the action of `G` on `B` to a `MulSemiringAction G L` on the fraction field `L` of `B`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def mulSemiringAction : MulSemiringAction G L := MulSemiringAction.compHom L diff --git a/Mathlib/RingTheory/Localization/Ideal.lean b/Mathlib/RingTheory/Localization/Ideal.lean index 1d231e301dfe06..bff31f90b3274c 100644 --- a/Mathlib/RingTheory/Localization/Ideal.lean +++ b/Mathlib/RingTheory/Localization/Ideal.lean @@ -102,6 +102,7 @@ lemma map_algebraMap_ne_top_iff_disjoint (I : Ideal R) : IsLocalization.algebraMap_mem_map_algebraMap_iff M] simp [Set.disjoint_left] +set_option backward.isDefEq.respectTransparency false in include M in protected theorem map_inf (I J : Ideal R) : (I ⊓ J).map (algebraMap R S) = I.map (algebraMap R S) ⊓ J.map (algebraMap R S) := by @@ -356,6 +357,7 @@ theorem bot_lt_under_prime [IsDomain R] (hM : M ≤ R⁰) (p : Ideal S) [hpp : p @[deprecated (since := "2026-04-09")] alias bot_lt_comap_prime := bot_lt_under_prime +set_option backward.isDefEq.respectTransparency false in variable (R) in lemma _root_.Module.IsTorsionFree.of_isLocalization [IsDomain R] [IsDomain S] {Rₚ Sₚ : Type*} [CommRing Rₚ] [IsDomain Rₚ] [CommRing Sₚ] [Algebra R Rₚ] [Algebra R Sₚ] [Algebra S Sₚ] diff --git a/Mathlib/RingTheory/Localization/Integral.lean b/Mathlib/RingTheory/Localization/Integral.lean index cd0fc56ae9e91a..c50b82868c082b 100644 --- a/Mathlib/RingTheory/Localization/Integral.lean +++ b/Mathlib/RingTheory/Localization/Integral.lean @@ -36,6 +36,7 @@ open Polynomial variable [IsLocalization M S] +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] Polynomial.algebra Polynomial.isLocalization in private theorem exists_integer_polynomial_multiple_and_support_subset (p : S[X]) : ∃ b ∈ M, ∃ (q : R[X]), q.map (algebraMap R S) = b • p ∧ q.support ⊆ p.support := by @@ -312,6 +313,7 @@ lemma IsLocalization.Away.exists_isIntegral_mul_of_isIntegral_mk' convert! (hr.pow n).algebraMap.mul hx exact (mk'_spec'_mk ..).symm +set_option backward.isDefEq.respectTransparency.types false in /-- If `t` is integral over `R[1/t]`, then it is integral over `R`. -/ lemma isIntegral_of_isIntegral_adjoin_of_mul_eq_one (t s : S) (hst : s * t = 1) (ht : IsIntegral (Algebra.adjoin R {s}) t) : diff --git a/Mathlib/RingTheory/Localization/LocalizationLocalization.lean b/Mathlib/RingTheory/Localization/LocalizationLocalization.lean index bfbe023e990663..adfd07f78650dd 100644 --- a/Mathlib/RingTheory/Localization/LocalizationLocalization.lean +++ b/Mathlib/RingTheory/Localization/LocalizationLocalization.lean @@ -256,6 +256,7 @@ variable {R : Type*} [CommRing R] (M : Submonoid R) open IsLocalization +set_option backward.isDefEq.respectTransparency false in theorem isFractionRing_of_isLocalization (S T : Type*) [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] [Algebra S T] [IsScalarTower R S T] [IsLocalization M S] [IsFractionRing R T] (hM : M ≤ nonZeroDivisors R) : IsFractionRing S T := by diff --git a/Mathlib/RingTheory/Localization/Module.lean b/Mathlib/RingTheory/Localization/Module.lean index 5dec9b809fa35c..05e0c8bd548057 100644 --- a/Mathlib/RingTheory/Localization/Module.lean +++ b/Mathlib/RingTheory/Localization/Module.lean @@ -53,6 +53,7 @@ theorem span_eq_top_of_isLocalizedModule {v : Set M} (hv : span R v = ⊤) : rw [← LinearMap.coe_restrictScalars R, ← LinearMap.map_span, hv] exact mem_map_of_mem mem_top +set_option backward.isDefEq.respectTransparency false in theorem LinearIndependent.of_isLocalizedModule {ι : Type*} {v : ι → M} (hv : LinearIndependent R v) : LinearIndependent Rₛ (f ∘ v) := by rw [linearIndependent_iff'ₛ] at hv ⊢ @@ -71,6 +72,7 @@ theorem LinearIndependent.of_isLocalizedModule {ι : Type*} {v : ι → M} simpa only [map_mul, (IsLocalization.map_units Rₛ s).mul_right_inj, hfg.1 ⟨i, hi⟩, hfg.2 ⟨i, hi⟩, Algebra.smul_def, (IsLocalization.map_units Rₛ a).mul_right_inj] using this +set_option backward.isDefEq.respectTransparency false in theorem LinearIndependent.of_isLocalizedModule_of_isRegular {ι : Type*} {v : ι → M} (hv : LinearIndependent R v) (h : ∀ s : S, IsRegular (s : R)) : LinearIndependent R (f ∘ v) := hv.map_injOn _ <| by @@ -87,6 +89,7 @@ theorem LinearIndependent.localization [Module Rₛ M] [IsScalarTower R Rₛ M] have := isLocalizedModule_id S M Rₛ exact hli.of_isLocalizedModule Rₛ S .id +set_option backward.isDefEq.respectTransparency false in include f in lemma IsLocalizedModule.linearIndependent_lift {ι} {v : ι → Mₛ} (hf : LinearIndependent R v) : ∃ w : ι → M, LinearIndependent R w := by diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index a601027c1f34ef..c4ea958b61e5be 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -89,6 +89,7 @@ theorem FiniteMultiplicity.emultiplicity_eq_iff_multiplicity_eq {n : ℕ} (h : FiniteMultiplicity a b) : emultiplicity a b = n ↔ multiplicity a b = n := by simp [h.emultiplicity_eq_multiplicity] +set_option backward.isDefEq.respectTransparency false in theorem emultiplicity_eq_iff_multiplicity_eq_of_ne_one {n : ℕ} (h : n ≠ 1) : emultiplicity a b = n ↔ multiplicity a b = n := by constructor diff --git a/Mathlib/RingTheory/MvPolynomial/Expand.lean b/Mathlib/RingTheory/MvPolynomial/Expand.lean index 6c058b757fef73..00113f476d9e7d 100644 --- a/Mathlib/RingTheory/MvPolynomial/Expand.lean +++ b/Mathlib/RingTheory/MvPolynomial/Expand.lean @@ -22,6 +22,7 @@ namespace MvPolynomial variable {σ R : Type*} [CommSemiring R] (p : ℕ) [ExpChar R p] +set_option backward.isDefEq.respectTransparency.types false in theorem map_frobenius_expand {f : MvPolynomial σ R} : (f.expand p).map (frobenius R p) = f ^ p := f.induction_on' fun _ _ => by simp [monomial_pow, frobenius] diff --git a/Mathlib/RingTheory/MvPolynomial/Ideal.lean b/Mathlib/RingTheory/MvPolynomial/Ideal.lean index b0e4ab8bd6bde9..29de2163423984 100644 --- a/Mathlib/RingTheory/MvPolynomial/Ideal.lean +++ b/Mathlib/RingTheory/MvPolynomial/Ideal.lean @@ -102,6 +102,7 @@ theorem pow_idealOfVars_eq_span (n) : idealOfVars σ R ^ n = image_pow_eq_finsuppProd_image] simp [monomial_eq, Set.preimage, degree] +set_option backward.isDefEq.respectTransparency.types false in theorem mem_pow_idealOfVars_iff (n : ℕ) (p : MvPolynomial σ R) : p ∈ idealOfVars σ R ^ n ↔ ∀ x ∈ p.support, n ≤ degree x := by rw [pow_idealOfVars] @@ -132,6 +133,7 @@ theorem mkₐ_eq_aeval : ext d simp +set_option backward.isDefEq.respectTransparency.types false in theorem mk_eq_eval₂ : (Ideal.Quotient.mk I).toFun = eval₂ (algebraMap A (MvPolynomial σ A ⧸ I)) fun d : σ => Ideal.Quotient.mk I (X d) := by ext d diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean index 592ab3ac4e4d96..23117f70b6d56d 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean @@ -173,6 +173,7 @@ end CommRing end IsSymmetric +set_option backward.isDefEq.respectTransparency false in /-- `MvPolynomial.rename` induces an isomorphism between the symmetric subalgebras. -/ @[simps! apply_coe symm_apply_coe] def renameSymmetricSubalgebra [CommSemiring R] (e : σ ≃ τ) : diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean index 512daafeff3a99..c9e22d066f57d9 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean @@ -341,6 +341,7 @@ noncomputable def esymmAlgEquiv (hn : Fintype.card σ = n) : AlgEquiv.ofBijective (esymmAlgHom σ R n) ⟨esymmAlgHom_injective R hn.ge, esymmAlgHom_surjective R hn.le⟩ +set_option backward.isDefEq.respectTransparency false in lemma esymmAlgEquiv_symm_apply (hn : Fintype.card σ = n) (i : Fin n) : (esymmAlgEquiv σ R hn).symm ⟨esymm σ R (i + 1), esymm_isSymmetric σ R _⟩ = X i := by apply_fun esymmAlgHom σ R n using esymmAlgHom_injective R hn.ge diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean index 7f6d951a470c7c..72e045dbcdd960 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean @@ -161,11 +161,13 @@ private theorem sum_filter_pairs_eq_sum_powersetCard_mem_filter_antidiagonal_sum have : #p.fst ≤ k := by apply le_of_lt; simp_all aesop +set_option backward.isDefEq.respectTransparency false in private lemma filter_pairs_lt (k : ℕ) : (pairs σ k).filter (fun (s, _) ↦ #s < k) = (range k).disjiUnion (powersetCard · univ) ((pairwise_disjoint_powersetCard _).set_pairwise _) ×ˢ univ := by ext; aesop (add unsafe le_of_lt) +set_option backward.isDefEq.respectTransparency false in private theorem sum_filter_pairs_eq_sum_filter_antidiagonal_powersetCard_sum (k : ℕ) (f : Finset σ × σ → MvPolynomial σ R) : ∑ t ∈ pairs σ k with #t.1 < k, f t = diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index 51931d1ddde85e..a52c19555e5012 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -423,6 +423,7 @@ theorem weightedHomogeneousComponent_finsupp : variable (w) +set_option backward.isDefEq.respectTransparency.types false in /-- Every polynomial is the sum of its weighted homogeneous components. -/ theorem sum_weightedHomogeneousComponent : (finsum fun m => weightedHomogeneousComponent w m φ) = φ := by @@ -513,6 +514,7 @@ theorem DirectSum.coeAddMonoidHom_eq_support_sum [DecidableEq σ] [DecidableEq R DFinsupp.sum x (fun _ x => ↑x) := DirectSum.coeLinearMap_eq_dfinsuppSum R w x +set_option backward.isDefEq.respectTransparency false in theorem DirectSum.coeLinearMap_eq_finsum [DecidableEq M] (x : DirectSum M fun i : M => ↥(weightedHomogeneousSubmodule R w i)) : (DirectSum.coeLinearMap fun i : M => weightedHomogeneousSubmodule R w i) x = @@ -521,6 +523,7 @@ theorem DirectSum.coeLinearMap_eq_finsum [DecidableEq M] rw [DirectSum.coeLinearMap_eq_dfinsuppSum, DFinsupp.sum, finsum_eq_sum_of_support_subset] apply DirectSum.support_subset +set_option backward.isDefEq.respectTransparency false in theorem weightedHomogeneousComponent_directSum [DecidableEq M] (x : DirectSum M fun i : M => ↥(weightedHomogeneousSubmodule R w i)) (m : M) : (weightedHomogeneousComponent w m) @@ -646,9 +649,10 @@ theorem decompose'_apply [DecidableEq M] (φ : MvPolynomial σ R) (m : M) : · rw [DirectSum.mk_apply_of_notMem hm, Submodule.coe_zero, weightedHomogeneousComponent_eq_zero_of_notMem w φ m hm] +set_option backward.isDefEq.respectTransparency false in /-- Given a weight `w`, the decomposition of `MvPolynomial σ R` into weighted homogeneous submodules -/ -@[implicit_reducible] +@[instance_reducible] def weightedDecomposition [DecidableEq M] : DirectSum.Decomposition (weightedHomogeneousSubmodule R w) where decompose' := decompose' R w @@ -673,18 +677,20 @@ def weightedDecomposition [DecidableEq M] : set_option linter.style.whitespace false in -- manual alignment is not recognised /-- Given a weight, `MvPolynomial` as a graded algebra -/ -@[implicit_reducible] +@[instance_reducible] def weightedGradedAlgebra [DecidableEq M] : GradedAlgebra (weightedHomogeneousSubmodule R w) where toDecomposition := weightedDecomposition R w toGradedMonoid := WeightedHomogeneousSubmodule.gradedMonoid +set_option backward.isDefEq.respectTransparency.types false in theorem weightedDecomposition.decompose'_eq [DecidableEq M] : (weightedDecomposition R w).decompose' = fun φ : MvPolynomial σ R => DirectSum.mk (fun i : M => ↥(weightedHomogeneousSubmodule R w i)) (Finset.image (weight w) φ.support) fun m => ⟨weightedHomogeneousComponent w m φ, weightedHomogeneousComponent_mem w φ m⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem weightedDecomposition.decompose'_apply [DecidableEq M] (φ : MvPolynomial σ R) (m : M) : ((weightedDecomposition R w).decompose' φ m : MvPolynomial σ R) = diff --git a/Mathlib/RingTheory/MvPowerSeries/Basic.lean b/Mathlib/RingTheory/MvPowerSeries/Basic.lean index 08e0614e76f1b0..f5013b692f5a63 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Basic.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Basic.lean @@ -508,6 +508,7 @@ section Map variable {S T : Type*} [Semiring R] [Semiring S] [Semiring T] variable (f : R →+* S) (g : S →+* T) +set_option backward.isDefEq.respectTransparency false in /-- The map between multivariate formal power series induced by a map on the coefficients. -/ def map : MvPowerSeries σ R →+* MvPowerSeries σ S where toFun φ n := f <| coeff n φ @@ -599,6 +600,7 @@ section Semiring variable [Semiring R] +set_option backward.isDefEq.respectTransparency false in theorem X_pow_dvd_iff {s : σ} {n : ℕ} {φ : MvPowerSeries σ R} : (X s : MvPowerSeries σ R) ^ n ∣ φ ↔ ∀ m : σ →₀ ℕ, m s < n → coeff m φ = 0 := by classical @@ -668,6 +670,7 @@ open Finset.HasAntidiagonal Finset variable {R : Type*} [CommSemiring R] {ι : Type*} +set_option backward.isDefEq.respectTransparency false in /-- Coefficients of a product of power series -/ theorem coeff_prod [DecidableEq ι] [DecidableEq σ] (f : ι → MvPowerSeries σ R) (d : σ →₀ ℕ) (s : Finset ι) : diff --git a/Mathlib/RingTheory/MvPowerSeries/Equiv.lean b/Mathlib/RingTheory/MvPowerSeries/Equiv.lean index 4dc31fa468316c..1f51936fe63f60 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Equiv.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Equiv.lean @@ -99,6 +99,7 @@ theorem coeff_toAdicCompletion_val_apply_out {x : σ →₀ ℕ} {p : MvPowerSer Ideal.Quotient.mk_out] exact hx +set_option backward.isDefEq.respectTransparency.types false in theorem toAdicCompletion_coe (p : MvPolynomial σ R) : toAdicCompletion σ R p = .of (MvPolynomial.idealOfVars σ R) (MvPolynomial σ R) p := by symm; ext n diff --git a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean index c1c8bbd01f5c77..fdd6e317fca4ff 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean @@ -113,6 +113,7 @@ def hasEvalIdeal : Ideal (σ → S) where zero_mem' := HasEval.zero smul_mem' := HasEval.mul_left +set_option backward.isDefEq.respectTransparency false in theorem mem_hasEvalIdeal_iff {a : σ → S} : a ∈ hasEvalIdeal ↔ HasEval a := by simp [hasEvalIdeal] diff --git a/Mathlib/RingTheory/MvPowerSeries/Expand.lean b/Mathlib/RingTheory/MvPowerSeries/Expand.lean index 1f5964443d829b..672cb6c8b550c3 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Expand.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Expand.lean @@ -136,6 +136,7 @@ theorem coeff_expand_of_not_dvd (φ : MvPowerSeries σ R) {m : σ →₀ ℕ} {i contradiction simp [meq] +set_option backward.isDefEq.respectTransparency.types false in theorem support_expand_subset (φ : MvPowerSeries σ R) : (expand p hp φ).support ⊆ φ.support.image (p • ·) := by intro d hd @@ -146,6 +147,7 @@ theorem support_expand_subset (φ : MvPowerSeries σ R) : coeff_apply] at hd exact ⟨m, hd, eq_aux⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem support_expand (φ : MvPowerSeries σ R) : (expand p hp φ).support = φ.support.image (p • ·) := by refine (support_expand_subset p hp φ).antisymm ?_ diff --git a/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean b/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean index ea86ba38fc3528..c90e7635ac50ad 100644 --- a/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean +++ b/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean @@ -33,7 +33,7 @@ variable [LinearOrder σ] [WellFoundedGT σ] noncomputable def lexOrder (φ : MvPowerSeries σ R) : (WithTop (Lex (σ →₀ ℕ))) := by classical exact if h : φ = 0 then ⊤ else by - have ne : Set.Nonempty (toLex '' φ.support) := by simpa + have ne : Set.Nonempty (toLex '' φ.support) := (Function.support_nonempty_iff.mpr h).image _ apply WithTop.some apply WellFounded.min _ (toLex '' φ.support) ne · exact Finsupp.instLTLex.lt @@ -48,7 +48,7 @@ theorem lexOrder_def_of_ne_zero {φ : MvPowerSeries σ R} (hφ : φ ≠ 0) : use ne unfold lexOrder simp only [dif_neg hφ] - simp only [Set.image_nonempty, Function.support_nonempty_iff, ne_eq, hφ, not_false_eq_true] + exact (Function.support_nonempty_iff.mpr hφ).image _ @[simp] theorem lexOrder_eq_top_iff_eq_zero (φ : MvPowerSeries σ R) : @@ -76,7 +76,7 @@ theorem coeff_ne_zero_of_lexOrder {φ : MvPowerSeries σ R} {d : σ →₀ ℕ} rcases hφ' with ⟨ne, hφ'⟩ simp only [← h, WithTop.coe_eq_coe] at hφ' suffices toLex d ∈ toLex '' φ.support by - simp only [Set.mem_image_equiv, toLex_symm_eq, ofLex_toLex, Function.mem_support, ne_eq] at this + simp only [Set.mem_image_equiv, toLex_symm_eq, ofLex_toLex] at this apply this rw [hφ'] apply WellFounded.min_mem diff --git a/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean b/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean index c47f513096cff1..7070eac7e14331 100644 --- a/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean @@ -73,6 +73,7 @@ noncomputable def basis (σ : Type*) (R : Type*) [Ring R] (Jd : TwoSidedIdeal R variable {σ : Type*} {R : Type*} [Ring R] +set_option backward.isDefEq.respectTransparency false in /-- A power series `f` belongs to the two-sided ideal `basis σ R ⟨J, d⟩` if and only if `coeff e f ∈ J` for all `e ≤ d`. -/ theorem mem_basis_iff {f : MvPowerSeries σ R} {Jd : TwoSidedIdeal R × (σ →₀ ℕ)} : @@ -85,6 +86,7 @@ theorem basis_le {Jd Ke : TwoSidedIdeal R × (σ →₀ ℕ)} (hJK : Jd.1 ≤ Ke basis σ R Jd ≤ basis σ R Ke := fun _ ↦ forall_imp (fun _ h hue ↦ hJK (h (le_trans hue hed))) +set_option backward.isDefEq.respectTransparency false in /-- `basis σ R ⟨J, d⟩ ≤ basis σ R ⟨K, e⟩` if and only if `J ≤ K` and `e ≤ d`. -/ theorem basis_le_iff {J K : TwoSidedIdeal R} {d e : σ →₀ ℕ} (hK : K ≠ ⊤) : basis σ R ⟨J, d⟩ ≤ basis σ R ⟨K, e⟩ ↔ J ≤ K ∧ e ≤ d := by diff --git a/Mathlib/RingTheory/MvPowerSeries/Order.lean b/Mathlib/RingTheory/MvPowerSeries/Order.lean index bf7d747a7d0cea..9e2f8dabeae3bb 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Order.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Order.lean @@ -585,6 +585,7 @@ protected theorem IsWeightedHomogeneous.mul {f g : MvPowerSeries σ R} {p q : apply hd rw [← hx, map_add, hp, hq] +set_option backward.isDefEq.respectTransparency false in /-- The weighted homogeneous components of an `MvPowerSeries f`. -/ def weightedHomogeneousComponent (p : ℕ) : MvPowerSeries σ R →ₗ[R] MvPowerSeries σ R where toFun f d := if weight w d = p then coeff d f else 0 diff --git a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean index 6d5da99a6def29..83891fff07bb91 100644 --- a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean @@ -199,7 +199,7 @@ instance {S : Type*} [Semiring S] [TopologicalSpace S] theorem variables_tendsto_zero [Semiring R] : Tendsto (X · : σ → MvPowerSeries σ R) cofinite (nhds 0) := by classical - simp only [tendsto_iff_coeff_tendsto, ← coeff_apply, coeff_X, coeff_zero] + simp only [tendsto_iff_coeff_tendsto, coeff_X, coeff_zero] refine fun d ↦ tendsto_nhds_of_eventually_eq ?_ by_cases! h : ∃ i, d = Finsupp.single i 1 · obtain ⟨i, hi⟩ := h diff --git a/Mathlib/RingTheory/MvPowerSeries/Rename.lean b/Mathlib/RingTheory/MvPowerSeries/Rename.lean index ee1992eff03832..7b7d55d1ad8043 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Rename.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Rename.lean @@ -296,6 +296,7 @@ lemma HasSubst.X_comp : HasSubst (X ∘ f : σ → MvPowerSeries τ R) where (fun i _ ↦ TendstoCofinite.finite_preimage_singleton f i)) (fun x => by contrapose; intro _ _; classical simp_all [coeff_X]) +set_option backward.isDefEq.respectTransparency.types false in theorem rename_eq_subst : rename f p = p.subst (X ∘ f) := by classical ext n diff --git a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean index 1a1728f9cd7f21..809896a14082fd 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean @@ -504,6 +504,7 @@ theorem le_weightedOrder_subst_of_forall_ne_zero refine fun i hi ↦ (weightedOrder_le _ hi).trans ?_ simp [Finsupp.weight_apply, Finsupp.sum, (ne_zero_iff_weightedOrder_finite _).mp (ha0 _)] +set_option backward.isDefEq.respectTransparency.types false in theorem le_order_subst (ha : HasSubst a) (f : MvPowerSeries σ R) : (⨅ i, (a i).order) * f.order ≤ (f.subst a).order := by refine .trans ?_ (MvPowerSeries.le_weightedOrder_subst _ ha _) @@ -542,6 +543,7 @@ theorem truncTotal_subst_eq_truncTotal_subst_truncTotal_of_le (ha : HasSubst a) · exact ha.truncTotal simp_rw [coeff_truncTotal_eq_zero _ (not_lt.mp hd)] +set_option backward.isDefEq.respectTransparency.types false in theorem truncTotal_subst_eq_truncTotal_subst_sum (ha : HasSubst a) (ha₁ : ∀ i, (a i).constantCoeff = 0) : truncTotal k (f.subst a) = @@ -627,6 +629,7 @@ variable {R : Type*} [CommSemiring R] -- To match the `PowerSeries.rescale` API which holds for `CommSemiring`, -- we redo it by hand. +set_option backward.isDefEq.respectTransparency.types false in /-- The ring homomorphism taking a multivariate power series `f(X)` to `f(aX)`. -/ noncomputable def rescale (a : σ → R) : MvPowerSeries σ R →+* MvPowerSeries σ R where toFun f := fun n ↦ (n.prod fun s m ↦ a s ^ m) * f.coeff n @@ -666,11 +669,13 @@ noncomputable def rescale (a : σ → R) : MvPowerSeries σ R →+* MvPowerSerie simp [pow_add] all_goals {simp} +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem coeff_rescale (f : MvPowerSeries σ R) (a : σ → R) (n : σ →₀ ℕ) : coeff n (rescale a f) = (n.prod fun s m ↦ a s ^ m) * f.coeff n := by simp [rescale, coeff_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem rescale_zero : (rescale 0 : MvPowerSeries σ R →+* MvPowerSeries σ R) = C.comp constantCoeff := by @@ -705,6 +710,7 @@ theorem rescale_mul (a b : σ → R) : rescale (a * b) = (rescale b).comp (resca ext simp [← rescale_rescale] +set_option backward.isDefEq.respectTransparency.types false in /-- Rescaling a homogeneous power series -/ lemma rescale_homogeneous_eq_smul {n : ℕ} {r : R} {f : MvPowerSeries σ R} (hf : ∀ d ∈ f.support, d.degree = n) : diff --git a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean index 60f51e1c0260ae..983793e2b78bd6 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean @@ -377,6 +377,7 @@ theorem totalDegree_truncTotal_lt (h : n ≠ 0) : apply (totalDegree_truncFinset p).trans_lt simp [Finset.sup_lt_iff (Nat.lt_of_sub_ne_zero h)] +set_option backward.isDefEq.respectTransparency.types false in theorem truncTotal_coe_eq_self_iff (p : MvPolynomial σ R) (h : n ≠ 0) : truncTotal n p = p ↔ p.totalDegree < n := by rw [truncTotal, truncFinset_coe_eq_self_iff, Set.Finite.subset_toFinset, diff --git a/Mathlib/RingTheory/Nilpotent/Lemmas.lean b/Mathlib/RingTheory/Nilpotent/Lemmas.lean index e5ab03ccb8e511..4cc84dda0850e5 100644 --- a/Mathlib/RingTheory/Nilpotent/Lemmas.lean +++ b/Mathlib/RingTheory/Nilpotent/Lemmas.lean @@ -113,6 +113,7 @@ section variable {M : Type*} [Semiring R] [AddCommMonoid M] [Module R M] +set_option backward.isDefEq.respectTransparency false in lemma isNilpotent_restrict_of_le {f : End R M} {p q : Submodule R M} {hp : MapsTo f p p} {hq : MapsTo f q q} (h : p ≤ q) (hf : IsNilpotent (f.restrict hq)) : IsNilpotent (f.restrict hp) := by @@ -125,6 +126,7 @@ lemma isNilpotent_restrict_of_le {f : End R M} {p q : Submodule R M} ext exact (congr_arg Subtype.val hn :) +set_option backward.isDefEq.respectTransparency false in lemma isNilpotent.restrict {f : M →ₗ[R] M} {p : Submodule R M} (hf : MapsTo f p p) (hnil : IsNilpotent f) : IsNilpotent (f.restrict hf) := by diff --git a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean index 604572a1decf15..6f1cc894d1adac 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean @@ -83,6 +83,7 @@ lemma Ideal.quotOfMul_surjective {a : R} (I : Ideal R) : exact Submodule.factor_surjective <| Submodule.singleton_set_smul I a ▸ Submodule.smul_le_span {a} I +set_option backward.isDefEq.respectTransparency.types false in /-- The sequence `R ⧸ I →ₗ[R] R ⧸ (a • I) →ₗ[R] R ⧸ (Ideal.span {a})` given by multiplication by `a` then quotienting by the ideal generated by `a` is exact. diff --git a/Mathlib/RingTheory/OreLocalization/OreSet.lean b/Mathlib/RingTheory/OreLocalization/OreSet.lean index ab74b4f90def7a..ee5370dc069b2f 100644 --- a/Mathlib/RingTheory/OreLocalization/OreSet.lean +++ b/Mathlib/RingTheory/OreLocalization/OreSet.lean @@ -29,7 +29,7 @@ namespace OreLocalization /-- Cancellability in monoids with zeros can act as a replacement for the `ore_right_cancel` condition of an ore set. -/ -@[implicit_reducible] +@[instance_reducible] def oreSetOfIsCancelMulZero {R : Type*} [MonoidWithZero R] [IsCancelMulZero R] {S : Submonoid R} (oreNum : R → S → R) (oreDenom : R → S → S) (ore_eq : ∀ (r : R) (s : S), oreDenom r s * r = oreNum r s * s) : OreSet S := @@ -42,7 +42,7 @@ def oreSetOfIsCancelMulZero {R : Type*} [MonoidWithZero R] [IsCancelMulZero R] /-- In rings without zero divisors, the first (cancellability) condition is always fulfilled, it suffices to give a proof for the Ore condition itself. -/ -@[implicit_reducible] +@[instance_reducible] def oreSetOfNoZeroDivisors {R : Type*} [Ring R] [NoZeroDivisors R] {S : Submonoid R} (oreNum : R → S → R) (oreDenom : R → S → S) (ore_eq : ∀ (r : R) (s : S), oreDenom r s * r = oreNum r s * s) : OreSet S := diff --git a/Mathlib/RingTheory/Perfection.lean b/Mathlib/RingTheory/Perfection.lean index c841ec2ffa7d45..a37d0ffd9d0d77 100644 --- a/Mathlib/RingTheory/Perfection.lean +++ b/Mathlib/RingTheory/Perfection.lean @@ -149,6 +149,7 @@ theorem coeffMonoidHom_iterate_powMonoidHom' (f : Perfection M p) (n m : ℕ) (h coeffMonoidHom M p n ((powMonoidHom p)^[m] f) = coeffMonoidHom M p (n - m) f := by rw [← coeffMonoidHom_iterate_powMonoidHom f (n - m) m, Nat.sub_add_cancel hmn] +set_option backward.isDefEq.respectTransparency.types false in /-- Given monoids `M` and `N`, with `M` being perfect, any homomorphism `M →+* N` can be lifted uniquely to a homomorphism `M →* Perfection N p`. -/ @[simps! symm_apply] @@ -169,10 +170,12 @@ noncomputable def liftMonoidHom (p : ℕ) (M : Type*) [CommMonoid M] [PerfectRin rw [← coeffMonoidHom_pow_p_pow _ 0 n, ← map_pow, powMulEquiv_symm_pow_p, zero_add] map_mul' _ _ := by ext; simp +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma coeffMonoidHom_zero_liftMonoidHom (p : ℕ) {M N : Type*} [CommMonoid M] [PerfectRing M p] [CommMonoid N] (e : M →* N) (x : M) : coeffMonoidHom N p 0 (liftMonoidHom p M N e x) = e x := by simp [liftMonoidHom] +set_option backward.isDefEq.respectTransparency.types false in /-- A monoid homomorphism `M →* N` induces `Perfection M p →* Perfection N p`. -/ def mapMonoidHom (p : ℕ) {M N : Type*} [CommMonoid M] [CommMonoid N] (φ : M →* N) : Perfection M p →* Perfection N p where diff --git a/Mathlib/RingTheory/PiTensorProduct.lean b/Mathlib/RingTheory/PiTensorProduct.lean index d83268dbd3e17c..298b7534ac89eb 100644 --- a/Mathlib/RingTheory/PiTensorProduct.lean +++ b/Mathlib/RingTheory/PiTensorProduct.lean @@ -76,6 +76,7 @@ nonrec theorem _root_.Commute.tprod {a₁ a₂ : Π i, A i} (ha : Commute a₁ a Commute (tprod R a₁) (tprod R a₂) := ha.tprod +set_option backward.isDefEq.respectTransparency false in lemma smul_tprod_mul_smul_tprod (r s : R) (x y : Π i, A i) : (r • tprod R x) * (s • tprod R y) = (r * s) • tprod R (x * y) := by simp only [mul_def, map_smul, LinearMap.smul_apply, mul_tprod_tprod, mul_comm r s, mul_smul] diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 44a4586f86b575..6b62b5e7dd218b 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -114,6 +114,7 @@ noncomputable def rTensorInv : (P ⊗[R] M →ₗ[R] Q ⊗[R] M) →ₗ[R] (P ((rightCancelEquiv Q e).congrRight ≪≫ₗ (rightCancelEquiv P e).congrLeft _ R) ∘ₗ LinearMap.rTensorHom N +set_option backward.isDefEq.respectTransparency.types false in theorem rTensorInv_leftInverse : Function.LeftInverse (rTensorInv P Q e) (.rTensorHom M) := fun _ ↦ by simp_rw [rTensorInv, LinearEquiv.coe_trans, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap] @@ -131,6 +132,7 @@ of `R`-modules. -/ left_inv := rTensorInv_leftInverse P Q e right_inv _ := rTensorInv_injective P Q e (by rw [LinearMap.toFun_eq_coe, rTensorInv_leftInverse]) +set_option backward.isDefEq.respectTransparency.types false in open LinearMap in /-- If there is an `R`-isomorphism between `M ⊗[R] N` and `R`, the induced map `M → Nᵛ` is an isomorphism. -/ @@ -448,6 +450,7 @@ noncomputable instance : CoeSort (Pic R) (Type u) := ⟨AsModule⟩ noncomputable instance (R) [CommRing R] (M : Pic R) : AddCommGroup M := Module.addCommMonoidToAddCommGroup R +set_option backward.isDefEq.respectTransparency.types false in set_option backward.privateInPublic true in private noncomputable def equivShrinkLinearEquiv (M : (Skeleton <| SemimoduleCat.{u} R)ˣ) : (id <| equivShrink _ M : Pic R) ≃ₗ[R] M := @@ -857,6 +860,9 @@ theorem Submodule.mulExact_unitsToPic_mapAlgebra : Function.MulExact (unitsToPic R A) (mapAlgebra R A) := MonoidHom.mulExact_iff.mpr (range_unitsToPic R A).symm +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in open QuotientGroup in /-- If `A` is a faithful `R`-algebra, the relative Picard group Pic(A/R) is isomorphic to the group of the invertible `R`-submodules in `A` modulo the principal submodules. -/ @@ -865,6 +871,9 @@ the group of the invertible `R`-submodules in `A` modulo the principal submodule (QuotientGroup.congr _ _ (.refl _) ((Subgroup.map_id _).trans (ker_unitsToPic R A).symm)).trans <| (quotientKerEquivRange _).trans <| .subgroupCongr (range_unitsToPic R A) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The class group of a domain is isomorphic to the Picard group. -/ @[simps!] noncomputable def ClassGroup.equivPic (R) [CommRing R] [IsDomain R] : ClassGroup R ≃* Pic R := diff --git a/Mathlib/RingTheory/Polynomial/GaussNorm.lean b/Mathlib/RingTheory/Polynomial/GaussNorm.lean index 4b6d9d9f6afa1a..20399d9bb6064b 100644 --- a/Mathlib/RingTheory/Polynomial/GaussNorm.lean +++ b/Mathlib/RingTheory/Polynomial/GaussNorm.lean @@ -151,6 +151,7 @@ lemma gaussNorm_zero_right : p.gaussNorm v 0 = v (p.coeff 0) := by · aesop (add norm (by simp [gaussNorm, Finset.sup'_le_iff])) · grind [p.le_gaussNorm v (le_refl 0) 0] +set_option backward.isDefEq.respectTransparency false in /-- If `v` is a nonnegative function with `v 0 = 0` and `c` is nonnegative, there exists a minimal index `i` such that the Gauss norm of `p` at `c` is attained at `i`. -/ lemma exists_min_eq_gaussNorm (p : R[X]) (hc : 0 ≤ c) : diff --git a/Mathlib/RingTheory/Polynomial/Quotient.lean b/Mathlib/RingTheory/Polynomial/Quotient.lean index bfa323f1966866..6e72b702e7194c 100644 --- a/Mathlib/RingTheory/Polynomial/Quotient.lean +++ b/Mathlib/RingTheory/Polynomial/Quotient.lean @@ -136,6 +136,7 @@ def polynomialQuotientEquivQuotientPolynomial (I : Ideal R) : coe_eval₂RingHom, map_pow, eval₂_C, RingHom.coe_comp, map_mul, eval₂_X, Function.comp_apply] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem polynomialQuotientEquivQuotientPolynomial_symm_mk (I : Ideal R) (f : R[X]) : I.polynomialQuotientEquivQuotientPolynomial.symm (Quotient.mk _ f) = f.map (Quotient.mk I) := by diff --git a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean index 0752c02e0453a4..a6256ae672e187 100644 --- a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean @@ -400,6 +400,7 @@ theorem resultant_C_left (r : R) : f.resultant (X + C r) m 1 = (-1) ^ m * eval (-r) f := by rw [← resultant_X_sub_C_right f m (-r) hf, map_neg, sub_neg_eq_add] +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` and `g` are monic and splits, then `Res(f, g) = ∏ (α - β)`, where `α` and `β` runs through the roots of `f` and `g` respectively. -/ lemma resultant_eq_prod_roots_sub @@ -472,6 +473,7 @@ lemma resultant_eq_prod_roots_sub · rw [f.modByMonic_add_div, natDegree_divByMonic _ hg, Nat.sub_add_cancel hfg] · simp +set_option backward.isDefEq.respectTransparency.types false in /-- If `f` splits with leading coeff `a` and degree `n`, then `Res(f, g) = aⁿ * ∏ g(α)` where `α` runs through the roots of `f`. -/ nonrec lemma resultant_eq_prod_eval [IsDomain R] @@ -929,6 +931,7 @@ discriminant. -/ noncomputable def discr (f : R[X]) : R := f.sylvesterDeriv.det * (-1) ^ (f.natDegree * (f.natDegree - 1) / 2) +set_option backward.isDefEq.respectTransparency.types false in /-- The discriminant of a constant polynomial is `1`. -/ @[simp] lemma discr_C (r : R) : discr (C r) = 1 := by let e : Fin ((C r).natDegree - 1 + (C r).natDegree) ≃ Fin 0 := finCongr (by simp) diff --git a/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean b/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean index 4641cfdd30c492..3f980764122c22 100644 --- a/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean +++ b/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean @@ -97,7 +97,7 @@ instance (priority := 100) uniqueFactorizationMonoid : UniqueFactorizationMonoid only finitely many monic factors. (Note that its factors up to unit may be more than monic factors.) See also `UniqueFactorizationMonoid.fintypeSubtypeDvd`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeSubtypeMonicDvd (f : D[X]) (hf : f ≠ 0) : Fintype { g : D[X] // g.Monic ∧ g ∣ f } := by set G := { g : D[X] // g.Monic ∧ g ∣ f } diff --git a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean index e7771a1752a12e..a2effb36e2d148 100644 --- a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean +++ b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean @@ -124,6 +124,7 @@ lemma mapEquivMonic_symm_map_algebraMap (IsScalarTower.toAlgHom R S T).comp ((mapEquivMonic R S n).symm p) := by rw [← mapEquivMonic_symm_map, IsScalarTower.coe_toAlgHom] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- In light of the fact that `MonicDegreeEq · n` is representable by `R[X₁,...,Xₙ]`, this is the map `R[X₁,...,Xₘ₊ₖ] → R[X₁,...,Xₘ] ⊗ R[X₁,...,Xₖ]` corresponding to the multiplication @@ -141,6 +142,7 @@ def universalFactorizationMap (hn : n = m + k) : rw [((monic_freeMonic R m).map _).natDegree_mul ((monic_freeMonic R k).map _)] simp_rw [(monic_freeMonic R _).natDegree_map, natDegree_freeMonic, hn]⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma universalFactorizationMap_freeMonic : (freeMonic R n).map (toRingHom <| universalFactorizationMap R n m k hn) = (freeMonic R m).map (algebraMap _ _) * @@ -149,6 +151,7 @@ lemma universalFactorizationMap_freeMonic : simp [universalFactorizationMap] rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in lemma universalFactorizationMap_comp_map : (universalFactorizationMap S n m k hn).toRingHom.comp (map (algebraMap R S)) = @@ -164,6 +167,7 @@ lemma universalFactorizationMap_comp_map : Polynomial.map_map, ← map_map_freeMonic (f := algebraMap R S)] congr 2 <;> ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in /-- Lifts along `universalFactorizationMap` corresponds to factorization of `p` into monic polynomials with fixed degrees. -/ def universalFactorizationMapLiftEquiv (p : MonicDegreeEq S n) : @@ -183,6 +187,7 @@ def universalFactorizationMapLiftEquiv (p : MonicDegreeEq S n) : left_inv f := by ext <;> simp right_inv q := by ext <;> simp +set_option backward.isDefEq.respectTransparency.types false in lemma ker_eval₂Hom_universalFactorizationMap : RingHom.ker (eval₂Hom (S₁ := MvPolynomial (Fin m) R ⊗[R] MvPolynomial (Fin k) R) (universalFactorizationMap R n m k hn) (Sum.elim (.X · ⊗ₜ 1) (1 ⊗ₜ .X ·))) = @@ -239,6 +244,7 @@ set_option backward.isDefEq.respectTransparency false in map := finSumFinEquiv.symm ∘ finCongr hn map_inj := finSumFinEquiv.symm.injective.comp (finCongr hn).injective } +set_option backward.isDefEq.respectTransparency.types false in lemma pderiv_inl_universalFactorizationMap_X (i j) : pderiv (Sum.inl i) (tensorEquivSum R (Fin m) (Fin k) R (universalFactorizationMap R n m k hn (X j))) = @@ -262,6 +268,7 @@ lemma pderiv_inl_universalFactorizationMap_X (i j) : simp [show a ≠ i by lia] · simp [h] +set_option backward.isDefEq.respectTransparency.types false in lemma pderiv_inr_universalFactorizationMap_X (i j) : pderiv (Sum.inr i) (tensorEquivSum R (Fin m) (Fin k) R (universalFactorizationMap R n m k hn (X j))) = @@ -507,6 +514,7 @@ def UniversalFactorizationRing.presentation : letI := ((MvPolynomial.mapEquivMonic R _ n).symm p).toAlgebra (MvPolynomial.universalFactorizationMapPresentation R n m k hn).baseChange _ +set_option backward.isDefEq.respectTransparency.types false in lemma UniversalFactorizationRing.jacobian_resentation : (presentation m k hn p).jacobian = (-1) ^ n * (factor₁ m k hn p).1.resultant (factor₂ m k hn p).1 := by @@ -617,6 +625,7 @@ def UniversalCoprimeFactorizationRing.homEquiv : ext simp +set_option backward.isDefEq.respectTransparency.types false in lemma UniversalCoprimeFactorizationRing.homEquiv_comp_fst {T : Type*} [CommRing T] [Algebra R T] (f : 𝓡' →ₐ[R] S) (g : S →ₐ[R] T) : (homEquiv T m k hn p (g.comp f)).1.1 = (homEquiv S m k hn p f).1.1.map g := by @@ -624,6 +633,7 @@ lemma UniversalCoprimeFactorizationRing.homEquiv_comp_fst {T : Type*} [CommRing simp [homEquiv, UniversalFactorizationRing.homEquiv, Polynomial.map_map] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma UniversalCoprimeFactorizationRing.homEquiv_comp_snd {T : Type*} [CommRing T] [Algebra R T] (f : 𝓡' →ₐ[R] S) (g : S →ₐ[R] T) : (homEquiv T m k hn p (g.comp f)).1.2 = (homEquiv S m k hn p f).1.2.map g := by @@ -631,6 +641,7 @@ lemma UniversalCoprimeFactorizationRing.homEquiv_comp_snd {T : Type*} [CommRing simp [homEquiv, UniversalFactorizationRing.homEquiv, Polynomial.map_map] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- If a monic polynomial `p : R[X]` factors into a product of coprime monic polynomials `p = f * g` in the residue field `κ(P)` of some `P : Spec R`, then there exists `Q : Spec R_univ` in the universal coprime factorization ring lying over `P`, diff --git a/Mathlib/RingTheory/PolynomialLaw/Basic.lean b/Mathlib/RingTheory/PolynomialLaw/Basic.lean index 12a0679ced71f5..8fd6ea554c4401 100644 --- a/Mathlib/RingTheory/PolynomialLaw/Basic.lean +++ b/Mathlib/RingTheory/PolynomialLaw/Basic.lean @@ -419,6 +419,7 @@ theorem factorsThrough_toFunLifted_π : · simp only [hq, hu, ← LinearMap.comp_apply, comp_toLinearMap, rTensor_comp] congr; ext; rfl +set_option backward.isDefEq.respectTransparency.types false in theorem toFun_eq_rTensor_φ_toFun' {t : S ⊗[R] M} {s : Finset S} {p : MvPolynomial (Fin s.card) R ⊗[R] M} (ha : π R M S (⟨s, p⟩ : lifts R M S) = t) : f.toFun S t = (φ R s).toLinearMap.rTensor N (f.toFun' _ p) := by diff --git a/Mathlib/RingTheory/PowerBasis.lean b/Mathlib/RingTheory/PowerBasis.lean index 0b0d5f716d58e2..ace47e3cfb5846 100644 --- a/Mathlib/RingTheory/PowerBasis.lean +++ b/Mathlib/RingTheory/PowerBasis.lean @@ -317,6 +317,9 @@ noncomputable def liftEquiv (pb : PowerBasis A S) : left_inv _ := pb.algHom_ext <| lift_gen _ _ _ right_inv y := Subtype.ext <| lift_gen _ _ y.prop +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- `pb.liftEquiv'` states that elements of the root set of the minimal polynomial of `pb.gen` correspond to maps sending `pb.gen` to that root. -/ @[simps! -fullyApplied] @@ -329,7 +332,7 @@ noncomputable def liftEquiv' [IsDomain B] (pb : PowerBasis A S) : /-- There are finitely many algebra homomorphisms `S →ₐ[A] B` if `S` is of the form `A[x]` and `B` is an integral domain. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def AlgHom.fintype [IsDomain B] (pb : PowerBasis A S) : Fintype (S →ₐ[A] B) := letI := Classical.decEq B Fintype.ofEquiv _ pb.liftEquiv'.symm diff --git a/Mathlib/RingTheory/PowerSeries/Evaluation.lean b/Mathlib/RingTheory/PowerSeries/Evaluation.lean index 8e4a47c6184849..567adf03821269 100644 --- a/Mathlib/RingTheory/PowerSeries/Evaluation.lean +++ b/Mathlib/RingTheory/PowerSeries/Evaluation.lean @@ -115,6 +115,7 @@ def hasEvalIdeal : Ideal S where zero_mem' := HasEval.zero smul_mem' := HasEval.mul_left +set_option backward.isDefEq.respectTransparency false in theorem mem_hasEvalIdeal_iff {a : S} : a ∈ hasEvalIdeal ↔ HasEval a := by simp [hasEvalIdeal] diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index de51fc451d10c5..fc979ae6db2117 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -217,7 +217,7 @@ variable (R) /-- Any Bézout domain is a GCD domain. This is not an instance since `GCDMonoid` contains data, and this might not be how we would like to construct it. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def toGCDDomain [IsBezout R] [IsCancelMulZero R] [DecidableEq R] : GCDMonoid R := gcdMonoidOfGCD (gcd · ·) (gcd_dvd_left · ·) (gcd_dvd_right · ·) dvd_gcd diff --git a/Mathlib/RingTheory/QuasiFinite/Basic.lean b/Mathlib/RingTheory/QuasiFinite/Basic.lean index ebf1858e3a16d6..8bce47952c308f 100644 --- a/Mathlib/RingTheory/QuasiFinite/Basic.lean +++ b/Mathlib/RingTheory/QuasiFinite/Basic.lean @@ -294,6 +294,7 @@ lemma iff_finite_comap_preimage_singleton [FiniteType R S] : exact ⟨Algebra.FiniteType.isNoetherianRing P.ResidueField _, (PrimeSpectrum.discreteTopology_iff_finite_and_krullDimLE_zero.mp inferInstance).right⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma iff_finite_primesOver [FiniteType R S] : QuasiFinite R S ↔ ∀ I : Ideal R, I.IsPrime → (I.primesOver S).Finite := by rw [iff_finite_comap_preimage_singleton, @@ -305,6 +306,7 @@ lemma iff_finite_primesOver [FiniteType R S] : simp [(PrimeSpectrum.equivSubtype S).exists_congr_left, PrimeSpectrum.ext_iff, eq_comm, PrimeSpectrum.equivSubtype, Ideal.primesOver, and_comm, Ideal.liesOver_iff, Ideal.under] +set_option backward.isDefEq.respectTransparency.types false in /-- If `T` is both a finite type `R`-algebra, and the localization of an integral `R`-algebra (away from an element), then `T` is quasi-finite over `R` -/ lemma of_isIntegral_of_finiteType [Algebra.IsIntegral R S] [Algebra.FiniteType R T] diff --git a/Mathlib/RingTheory/QuasiFinite/Polynomial.lean b/Mathlib/RingTheory/QuasiFinite/Polynomial.lean index 3820492b52107c..e23c9320233c23 100644 --- a/Mathlib/RingTheory/QuasiFinite/Polynomial.lean +++ b/Mathlib/RingTheory/QuasiFinite/Polynomial.lean @@ -17,6 +17,7 @@ variable {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] namespace Polynomial +set_option backward.isDefEq.respectTransparency false in attribute [local instance] Algebra.WeaklyQuasiFiniteAt.finite_locoalization in lemma not_weaklyQuasiFiniteAt (P : Ideal R[X]) [P.IsPrime] : ¬ Algebra.WeaklyQuasiFiniteAt R P := by intro H diff --git a/Mathlib/RingTheory/QuasiFinite/Weakly.lean b/Mathlib/RingTheory/QuasiFinite/Weakly.lean index 899aaacb703f7a..32073e6d26b9bb 100644 --- a/Mathlib/RingTheory/QuasiFinite/Weakly.lean +++ b/Mathlib/RingTheory/QuasiFinite/Weakly.lean @@ -50,6 +50,7 @@ See `Algebra.QuasiFiniteAt.of_weaklyQuasiFiniteAt`. -/ abbrev Algebra.WeaklyQuasiFiniteAt := Algebra.QuasiFiniteAt R (q.map (Ideal.Quotient.mk ((q.under R).map (algebraMap R S)))) +set_option backward.isDefEq.respectTransparency.types false in lemma Algebra.weaklyQuasiFiniteAt_iff : Algebra.WeaklyQuasiFiniteAt R q ↔ Algebra.QuasiFinite R (Localization.AtPrime q ⧸ diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index 651541f695bd63..858337d1921ab3 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -252,6 +252,7 @@ theorem ramificationIdx_above_le [r.IsPrime] [r.LiesOver q] [Module.Finite R T] @[deprecated (since := "2026-07-01")] alias ramificationIdx'_above_le := ramificationIdx_above_le +set_option backward.isDefEq.respectTransparency.types false in variable (R) in open Pointwise in @[simp] diff --git a/Mathlib/RingTheory/Regular/IsSMulRegular.lean b/Mathlib/RingTheory/Regular/IsSMulRegular.lean index ce1fd7f8a89024..8729e80c5be865 100644 --- a/Mathlib/RingTheory/Regular/IsSMulRegular.lean +++ b/Mathlib/RingTheory/Regular/IsSMulRegular.lean @@ -168,6 +168,7 @@ lemma smul_top_inf_eq_smul_of_isSMulRegular_on_quot : exact Eq.trans (congrArg (· ⊓ N) (map_top _)) (map_comap_eq _ _).symm -- Who knew this didn't rely on exactness at the right!? +set_option backward.isDefEq.respectTransparency.types false in open Function in lemma QuotSMulTop.map_first_exact_on_four_term_exact_of_isSMulRegular_last {M'''} [AddCommGroup M'''] [Module R M'''] diff --git a/Mathlib/RingTheory/Regular/RegularSequence.lean b/Mathlib/RingTheory/Regular/RegularSequence.lean index 8b2559f6416cda..9b58c8f23e80cf 100644 --- a/Mathlib/RingTheory/Regular/RegularSequence.lean +++ b/Mathlib/RingTheory/Regular/RegularSequence.lean @@ -154,6 +154,7 @@ variable {S M} [CommRing R] [CommRing S] [AddCommGroup M] [AddCommGroup M₂] [Module R M] [Module S M₂] {σ : R →+* S} {σ' : S →+* R} [RingHomInvPair σ σ'] [RingHomInvPair σ' σ] +set_option backward.isDefEq.respectTransparency.types false in open DistribMulAction AddSubgroup in private lemma _root_.AddHom.map_smul_top_toAddSubgroup_of_surjective {f : M →+ M₂} {as : List R} {bs : List S} (hf : Function.Surjective f) @@ -570,6 +571,7 @@ lemma map_first_exact_on_four_term_right_exact_of_isSMulRegular_last section Perm +set_option backward.isDefEq.respectTransparency.types false in open _root_.LinearMap in private lemma IsWeaklyRegular.swap {a b : R} (h1 : IsWeaklyRegular M [a, b]) (h2 : torsionBy R M b = a • torsionBy R M b → torsionBy R M b = ⊥) : diff --git a/Mathlib/RingTheory/RingHom/Locally.lean b/Mathlib/RingTheory/RingHom/Locally.lean index 12c4aefc52ef3c..7102703a45fe72 100644 --- a/Mathlib/RingTheory/RingHom/Locally.lean +++ b/Mathlib/RingTheory/RingHom/Locally.lean @@ -176,6 +176,7 @@ end OfLocalizationSpanTarget section Stability +set_option backward.isDefEq.respectTransparency.types false in /-- If `P` respects isomorphism, so does `Locally P`. -/ lemma locally_respectsIso (hPi : RespectsIso P) : RespectsIso (Locally P) where left {R S T} _ _ _ f e := fun ⟨s, hsone, hs⟩ ↦ by diff --git a/Mathlib/RingTheory/RingHomProperties.lean b/Mathlib/RingTheory/RingHomProperties.lean index 45359262e1ec24..2e55dbc25f0ef4 100644 --- a/Mathlib/RingTheory/RingHomProperties.lean +++ b/Mathlib/RingTheory/RingHomProperties.lean @@ -60,6 +60,7 @@ theorem RespectsIso.cancel_right_isIso (hP : RespectsIso @P) {R S T : CommRingCa simp [← CommRingCat.hom_comp], hP.1 f.hom (asIso g).commRingCatIsoToRingEquiv⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem RespectsIso.isLocalization_away_iff (hP : RingHom.RespectsIso @P) {R S : Type u} (R' S' : Type u) [CommRing R] [CommRing S] [CommRing R'] [CommRing S'] [Algebra R R'] diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index 6392026072d026..d959b463994b1b 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -577,6 +577,7 @@ theorem jacobson_density (f : End (End R M) M) (s : Finset M) : have ⟨r, hr⟩ := mem_span_singleton.mp this ⟨r, fun m hm ↦ by simpa [x] using! congr($hr ⟨m, hm⟩).symm⟩ +set_option backward.isDefEq.respectTransparency false in /-- The Jacobson density theorem for a module finite over its endomorphism ring. -/ protected theorem Module.Finite.toModuleEnd_moduleEnd_surjective [Module.Finite (End R M) M] : Function.Surjective (Module.toModuleEnd (End R M) (S := R) M) := by diff --git a/Mathlib/RingTheory/SimpleModule/Isotypic.lean b/Mathlib/RingTheory/SimpleModule/Isotypic.lean index 2cf4fdeed8a309..ba6f7663184796 100644 --- a/Mathlib/RingTheory/SimpleModule/Isotypic.lean +++ b/Mathlib/RingTheory/SimpleModule/Isotypic.lean @@ -357,6 +357,7 @@ section Equiv variable {ι : Type*} [DecidableEq ι] {N : ι → Submodule R M} (ind : iSupIndep N) (iSup_top : ⨆ i, N i = ⊤) (invar : ∀ i, (N i).IsFullyInvariant) +set_option backward.isDefEq.respectTransparency.types false in /-- If an `R`-module `M` is the direct sum of fully invariant submodules `Nᵢ`, then `End R M` is isomorphic to `Πᵢ End R Nᵢ` as a ring. -/ noncomputable def iSupIndep.ringEquiv : Module.End R M ≃+* Π i, Module.End R (N i) where @@ -465,6 +466,7 @@ form a complete atomic Boolean algebra. -/ exact le_biSup _ (isFullyInvariant_iff_le_imp_isotypicComponent_le.mp m.2 _ le) map_rel_iff' := (GaloisCoinsertion.setIsotypicComponents R M).l_le_l_iff +set_option backward.isDefEq.respectTransparency.types false in theorem isFullyInvariant_iff_sSup_isotypicComponents {m : Submodule R M} : m.IsFullyInvariant ↔ ∃ s ⊆ isotypicComponents R M, m = sSup s := by refine ⟨fun h ↦ ⟨OrderIso.setIsotypicComponents.symm ⟨m, h⟩, ⟨?_, ?_⟩⟩, ?_⟩ diff --git a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean index fe5b1c45c6dc4f..ac49ed1a061fd5 100644 --- a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean +++ b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean @@ -195,6 +195,7 @@ theorem exists_algEquiv_pi_matrix_divisionRing : have ⟨n, S, d, _, hd, ⟨e⟩⟩ := exists_algEquiv_pi_matrix_end_mulOpposite R₀ R classical exact ⟨n, _, d, inferInstance, inferInstance, hd, ⟨e⟩⟩ +set_option backward.isDefEq.respectTransparency false in /-- The **Wedderburn–Artin Theorem**, algebra form, finite case: a finite semisimple algebra is isomorphic to a product of matrix algebras over finite division algebras. -/ theorem exists_algEquiv_pi_matrix_divisionRing_finite [Module.Finite R₀ R] : diff --git a/Mathlib/RingTheory/SimpleRing/Field.lean b/Mathlib/RingTheory/SimpleRing/Field.lean index b53a900f3dcec2..4521c33877efc4 100644 --- a/Mathlib/RingTheory/SimpleRing/Field.lean +++ b/Mathlib/RingTheory/SimpleRing/Field.lean @@ -22,6 +22,7 @@ public section namespace IsSimpleRing +set_option backward.isDefEq.respectTransparency.types false in open TwoSidedIdeal in lemma isField_center (A : Type*) [Ring A] [IsSimpleRing A] : IsField (Subring.center A) where exists_pair_ne := ⟨0, 1, zero_ne_one⟩ diff --git a/Mathlib/RingTheory/Smooth/AdicCompletion.lean b/Mathlib/RingTheory/Smooth/AdicCompletion.lean index 352ee07e40cb7b..73c50d3a4cd36b 100644 --- a/Mathlib/RingTheory/Smooth/AdicCompletion.lean +++ b/Mathlib/RingTheory/Smooth/AdicCompletion.lean @@ -51,6 +51,7 @@ noncomputable def liftAdicCompletionAux : (m : ℕ) → A →ₐ[R] S ⧸ (I ^ m (Ideal.map_quotient_self _) FormallySmooth.lift J ⟨m + 1 + 1, this⟩ q +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma factorₐ_comp_liftAdicCompletionAux (m : ℕ) : (Ideal.Quotient.factorₐ _ (Ideal.pow_le_pow_right m.le_succ)).comp diff --git a/Mathlib/RingTheory/Smooth/Basic.lean b/Mathlib/RingTheory/Smooth/Basic.lean index ae4cdf01a84d7e..696c5eb8786599 100644 --- a/Mathlib/RingTheory/Smooth/Basic.lean +++ b/Mathlib/RingTheory/Smooth/Basic.lean @@ -302,6 +302,7 @@ theorem iff_split_injection simp [LinearMap.ext_iff] · rw [and_iff_right (by exact mapBaseChange_surjective R P A hf)] +set_option backward.isDefEq.respectTransparency.types false in /-- Given a formally smooth `R`-algebra `P` and a surjective algebra homomorphism `f : P →ₐ[R] S` with kernel `I` (typically a presentation `R[X] → S`), @@ -449,12 +450,12 @@ end surjective section BaseChange -open scoped TensorProduct variable {R : Type*} [CommRing R] variable {A : Type*} [CommRing A] [Algebra R A] variable (B : Type*) [CommRing B] [Algebra R B] +set_option backward.isDefEq.respectTransparency.types false in instance [FormallySmooth R A] : FormallySmooth B (B ⊗[R] A) := by refine .of_comp_surjective fun C _ _ I hI f ↦ ?_ let := ((algebraMap B C).comp (algebraMap R B)).toAlgebra @@ -497,6 +498,7 @@ instance [FormallySmooth R A] (M : Submonoid A) : FormallySmooth R (Localization have : FormallySmooth A (Localization M) := of_isLocalization M .comp _ A _ +set_option backward.isDefEq.respectTransparency.types false in theorem localization_base [FormallySmooth R Sₘ] : FormallySmooth Rₘ Sₘ := by refine .of_comp_surjective fun Q _ _ I e f ↦ ?_ let := ((algebraMap Rₘ Q).comp (algebraMap R Rₘ)).toAlgebra diff --git a/Mathlib/RingTheory/Smooth/IntegralClosure.lean b/Mathlib/RingTheory/Smooth/IntegralClosure.lean index 1caf917619c7cc..00e25f5e24c01b 100644 --- a/Mathlib/RingTheory/Smooth/IntegralClosure.lean +++ b/Mathlib/RingTheory/Smooth/IntegralClosure.lean @@ -122,6 +122,7 @@ lemma TensorProduct.toIntegralClosure_bijective_of_isLocalizationAway (AlgHom.id R (integralClosure R B))).toLinearMap) (φ r).toLinearMap (toIntegralClosure R S B).toLinearMap (1 ⊗ₜ x)).1) +set_option backward.isDefEq.respectTransparency.types false in attribute [local instance] MvPolynomial.algebraMvPolynomial in /-- Base changing to `MvPolynomial σ R` preserves integral closure. -/ lemma TensorProduct.toIntegralClosure_mvPolynomial_bijective {σ : Type*} : diff --git a/Mathlib/RingTheory/Smooth/Kaehler.lean b/Mathlib/RingTheory/Smooth/Kaehler.lean index ab6c8d22956433..57ca05e5b42258 100644 --- a/Mathlib/RingTheory/Smooth/Kaehler.lean +++ b/Mathlib/RingTheory/Smooth/Kaehler.lean @@ -112,6 +112,7 @@ def retractionOfSectionOfKerSqZero : S ⊗[P] Ω[P⁄R] →ₗ[P] RingHom.ker (a (IsScalarTower.toAlgHom R P S) hf' g hg).liftKaehlerDifferential (f.liftBaseChange S).restrictScalars P +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma retractionOfSectionOfKerSqZero_tmul_D (s : S) (t : P) : retractionOfSectionOfKerSqZero g hf' hg (s ⊗ₜ .D _ _ t) = diff --git a/Mathlib/RingTheory/Smooth/Pi.lean b/Mathlib/RingTheory/Smooth/Pi.lean index f4799e26092736..095fee93f6b061 100644 --- a/Mathlib/RingTheory/Smooth/Pi.lean +++ b/Mathlib/RingTheory/Smooth/Pi.lean @@ -46,6 +46,7 @@ theorem of_pi [FormallySmooth R (Π i, A i)] (i) : change (Pi.single i x) i = x simp +set_option backward.isDefEq.respectTransparency.types false in theorem pi_iff [Finite I] : FormallySmooth R (Π i, A i) ↔ ∀ i, FormallySmooth R (A i) := by classical diff --git a/Mathlib/RingTheory/Smooth/Quotient.lean b/Mathlib/RingTheory/Smooth/Quotient.lean index fc847cd5f77427..ab8e81d729982e 100644 --- a/Mathlib/RingTheory/Smooth/Quotient.lean +++ b/Mathlib/RingTheory/Smooth/Quotient.lean @@ -94,6 +94,7 @@ private lemma mul_le_ker_of_range_le_mul_of_sq_zero {J I : Ideal R} (sq : I ^ 2 rcases Submodule.mem_map.mp hx with ⟨x', hx', eq⟩ simpa [← eq] using this hx' +set_option backward.isDefEq.respectTransparency.types false in /-- For flat ring homomorphism `f : R →+* S`, `I` an ideal of `R` which is square zero, if `R ⧸ I →+* S ⧸ IS` is formally smooth, so is `f`. -/ @[stacks 031L] diff --git a/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean b/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean index e793f5a4f983c4..35f86bc67ba477 100644 --- a/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean +++ b/Mathlib/RingTheory/Smooth/StandardSmoothCotangent.lean @@ -114,6 +114,7 @@ lemma cotangentComplexAux_injective : Function.Injective P.cotangentComplexAux : simpa using this i · exact P.relation_mem_ker i +set_option backward.isDefEq.respectTransparency.types false in lemma cotangentComplexAux_surjective : Function.Surjective P.cotangentComplexAux := by rw [← LinearMap.range_eq_top, _root_.eq_top_iff, ← P.basisDeriv.span_eq, Submodule.span_le] rintro - ⟨i, rfl⟩ diff --git a/Mathlib/RingTheory/Smooth/StandardSmoothOfFree.lean b/Mathlib/RingTheory/Smooth/StandardSmoothOfFree.lean index 947a78077c3065..e452b9b463428d 100644 --- a/Mathlib/RingTheory/Smooth/StandardSmoothOfFree.lean +++ b/Mathlib/RingTheory/Smooth/StandardSmoothOfFree.lean @@ -44,6 +44,7 @@ open KaehlerDifferential variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] +set_option backward.isDefEq.respectTransparency.types false in /-- If `H¹(S/R) = 0` and `Ω[S⁄R]` is free on `{d sᵢ}ᵢ` for some `sᵢ : S`, then `S` is `R`-standard smooth. -/ theorem IsStandardSmooth.of_basis_kaehlerDifferential [FinitePresentation R S] @@ -96,6 +97,7 @@ theorem Etale.iff_isStandardSmoothOfRelativeDimension_zero : refine ⟨inferInstance, ⟨Empty, Module.Basis.empty Ω[S⁄R], ?_⟩⟩ simp [Set.range_subset_iff] +set_option backward.isDefEq.respectTransparency.types false in variable (R) in /-- If `S` is `R`-smooth at a prime `p`, then `S` is `R`-standard-smooth in a neighbourhood of `p`: there exists a basic open `p ∈ D(f)` of `Spec S` such that `S[1/f]` is standard smooth. -/ diff --git a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean index 040355ebc361fc..03476530bff79e 100644 --- a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean +++ b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean @@ -107,6 +107,7 @@ theorem mapPiLocalization_comp : (mapPiLocalization g hg).comp (mapPiLocalization f hf) := RingHom.ext fun _ ↦ funext fun _ ↦ congr($(Localization.localRingHom_comp _ _ _ _ rfl _ rfl) _) +set_option backward.isDefEq.respectTransparency false in theorem mapPiLocalization_bijective : Function.Bijective (mapPiLocalization f hf) := by let f := RingEquiv.ofBijective f hf let e := RingEquiv.ofRingHom (mapPiLocalization f hf) @@ -147,6 +148,7 @@ theorem finite_of_toPiLocalization_pi_surjective end Pi +set_option backward.isDefEq.respectTransparency false in theorem finite_of_toPiLocalization_surjective (surj : Function.Surjective (toPiLocalization R)) : Finite (MaximalSpectrum R) := by diff --git a/Mathlib/RingTheory/Spectrum/Prime/Basic.lean b/Mathlib/RingTheory/Spectrum/Prime/Basic.lean index 645de1ee070a05..f41869d711d73d 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Basic.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Basic.lean @@ -187,6 +187,7 @@ theorem gc : vanishingIdeal t := fun I t => subset_zeroLocus_iff_le_vanishingIdeal t I +set_option backward.isDefEq.respectTransparency false in /-- `zeroLocus` and `vanishingIdeal` form a Galois connection. -/ theorem gc_set : @GaloisConnection (Set R) (Set (PrimeSpectrum R))ᵒᵈ _ _ (fun s => zeroLocus s) fun t => diff --git a/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean b/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean index 38da79db859b08..2f2f50b93d551e 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/ChevalleyComplexity.lean @@ -272,6 +272,7 @@ private lemma induction_structure (n : ℕ) exact hi h_eq -- TODO: fix non-terminal simp (large simp set) +set_option backward.isDefEq.respectTransparency.types false in set_option linter.flexible false in open IsLocalization in open Submodule hiding comap in diff --git a/Mathlib/RingTheory/Spectrum/Prime/LTSeries.lean b/Mathlib/RingTheory/Spectrum/Prime/LTSeries.lean index 75bb01ce4a37ad..245f792f2fe756 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/LTSeries.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/LTSeries.lean @@ -28,6 +28,7 @@ open Ideal IsLocalRing namespace PrimeSpectrum +set_option backward.isDefEq.respectTransparency.types false in theorem exist_mem_one_of_mem_maximal_ideal [IsLocalRing R] {p₁ p₀ : PrimeSpectrum R} (h₀ : p₀ < p₁) (h₁ : p₁ < closedPoint R) {x : R} (hx : x ∈ 𝔪) : ∃ q : PrimeSpectrum R, x ∈ q.asIdeal ∧ p₀ < q ∧ q.asIdeal < 𝔪 := by @@ -50,6 +51,7 @@ theorem exist_mem_one_of_mem_maximal_ideal [IsLocalRing R] {p₁ p₀ : PrimeSpe refine not_lt_zero (a := (e ⟨p₀, le_refl p₀⟩).1.height) (height_le_iff.mp hph _ inferInstance ?_) simpa using h₀ +set_option backward.isDefEq.respectTransparency.types false in theorem exist_mem_one_of_mem_two {p₁ p₀ p₂ : PrimeSpectrum R} (h₀ : p₀ < p₁) (h₁ : p₁ < p₂) {x : R} (hx : x ∈ p₂.asIdeal) : ∃ q : (PrimeSpectrum R), x ∈ q.asIdeal ∧ p₀ < q ∧ q < p₂ := by diff --git a/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean b/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean index 74a0776d095f5a..1739959541e931 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/RingHom.lean @@ -242,6 +242,7 @@ theorem range_comap_of_surjective (hf : Surjective f) : variable {S} +set_option backward.isDefEq.respectTransparency false in /-- Let `f : R →+* S` be a surjective ring homomorphism, then `Spec S` is order-isomorphic to `Z(I)` where `I = ker f`. -/ noncomputable def Ideal.primeSpectrumOrderIsoZeroLocusOfSurj (hf : Surjective f) {I : Ideal R} diff --git a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean index c7dea1f60d1fa8..813b900ffb3528 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean @@ -157,6 +157,7 @@ theorem isClosed_zeroLocus (s : Set R) : IsClosed (zeroLocus s) := by rw [isClosed_iff_zeroLocus] exact ⟨s, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem zeroLocus_vanishingIdeal_eq_closure (t : Set (PrimeSpectrum R)) : zeroLocus (vanishingIdeal t : Set R) = closure t := by rcases isClosed_iff_zeroLocus (closure t) |>.mp isClosed_closure with ⟨I, hI⟩ @@ -729,6 +730,7 @@ section DiscreteTopology variable (R) [DiscreteTopology (PrimeSpectrum R)] +set_option backward.isDefEq.respectTransparency.types false in theorem toPiLocalization_surjective_of_discreteTopology : Function.Surjective (toPiLocalization R) := fun x ↦ by have (p : PrimeSpectrum R) : ∃ f, (basicOpen f : Set _) = {p} := diff --git a/Mathlib/RingTheory/Support.lean b/Mathlib/RingTheory/Support.lean index 1b61e474aa4729..4a8562f9b7fea7 100644 --- a/Mathlib/RingTheory/Support.lean +++ b/Mathlib/RingTheory/Support.lean @@ -56,6 +56,7 @@ lemma Module.notMem_support_iff : p ∉ Module.support R M ↔ Subsingleton (LocalizedModule p.asIdeal.primeCompl M) := not_nontrivial_iff_subsingleton +set_option backward.isDefEq.respectTransparency.types false in lemma Module.notMem_support_iff' : p ∉ Module.support R M ↔ ∀ m : M, ∃ r ∉ p.asIdeal, r • m = 0 := by simp only [notMem_support_iff, Ideal.primeCompl, LocalizedModule.subsingleton_iff, diff --git a/Mathlib/RingTheory/TensorProduct/Basic.lean b/Mathlib/RingTheory/TensorProduct/Basic.lean index 6a088fd3ee323f..3988c596cff296 100644 --- a/Mathlib/RingTheory/TensorProduct/Basic.lean +++ b/Mathlib/RingTheory/TensorProduct/Basic.lean @@ -543,6 +543,7 @@ lemma closure_range_union_range_eq_top [CommRing R] [Ring A] [Ring B] (Subring.subset_closure (.inr ⟨_, rfl⟩)) | add x y _ _ => exact add_mem ‹_› ‹_› +set_option backward.isDefEq.respectTransparency false in /-- If `s` generates `T` as an `R`-algebra, then `{ 1 ⊗ x | x ∈ s }` generates `A ⊗[R] T` as an `A`-algebra. -/ lemma adjoin_one_tmul_image_eq_top [CommSemiring R] [CommSemiring A] diff --git a/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean b/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean index 1302478a978d9a..4d33b27368036b 100644 --- a/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean +++ b/Mathlib/RingTheory/TensorProduct/DirectLimitFG.lean @@ -61,6 +61,7 @@ instance Submodule.FG.directedSystem : map_self := fun _ _ ↦ rfl map_map := fun _ _ _ _ _ _ ↦ rfl +set_option backward.isDefEq.respectTransparency.types false in variable (R M) in /-- Any module is the direct limit of its finitely generated submodules -/ noncomputable def Submodule.FG.directLimit [DecidableEq {P : Submodule R M // P.FG}] : @@ -117,6 +118,7 @@ noncomputable def Submodule.FG.rTensor.directLimit [DecidableEq {P : Submodule R (fun ⦃P Q⦄ (h : P ≤ Q) ↦ (Submodule.inclusion h).rTensor N) ≃ₗ[R] M ⊗[R] N := (TensorProduct.directLimitLeft _ N).symm.trans ((Submodule.FG.directLimit R M).rTensor N) +set_option backward.isDefEq.respectTransparency.types false in theorem Submodule.FG.rTensor.directLimit_apply [DecidableEq {P : Submodule R M // P.FG}] {P : {P : Submodule R M // P.FG}} (u : P ⊗[R] N) : (Submodule.FG.rTensor.directLimit R M N) @@ -170,6 +172,7 @@ noncomputable def Submodule.FG.lTensor.directLimit [DecidableEq {Q : Submodule R (fun _ _ hPQ ↦ (inclusion hPQ).lTensor M) ≃ₗ[R] M ⊗[R] N := (TensorProduct.directLimitRight _ M).symm.trans ((Submodule.FG.directLimit R N).lTensor M) +set_option backward.isDefEq.respectTransparency.types false in theorem Submodule.FG.lTensor.directLimit_apply [DecidableEq {P : Submodule R N // P.FG}] (Q : {Q : Submodule R N // Q.FG}) (u : M ⊗[R] Q.val) : (Submodule.FG.lTensor.directLimit R M N) diff --git a/Mathlib/RingTheory/TensorProduct/Free.lean b/Mathlib/RingTheory/TensorProduct/Free.lean index 07083ae3549521..629a5e89a87c96 100644 --- a/Mathlib/RingTheory/TensorProduct/Free.lean +++ b/Mathlib/RingTheory/TensorProduct/Free.lean @@ -72,6 +72,7 @@ theorem basis_repr_tmul (a : A) (m : M) : (basis A b).repr (a ⊗ₜ m) = a • Finsupp.mapRange (algebraMap R A) (map_zero _) (b.repr m) := basisAux_tmul b _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem basis_repr_symm_apply (a : A) (i : ι) : (basis A b).repr.symm (Finsupp.single i a) = a ⊗ₜ b.repr.symm (Finsupp.single i 1) := by simp [basis, Equiv.uniqueProd_symm_apply, basisAux] diff --git a/Mathlib/RingTheory/TensorProduct/IsBaseChangeFree.lean b/Mathlib/RingTheory/TensorProduct/IsBaseChangeFree.lean index 38778acd846704..6d345c2ab16b79 100644 --- a/Mathlib/RingTheory/TensorProduct/IsBaseChangeFree.lean +++ b/Mathlib/RingTheory/TensorProduct/IsBaseChangeFree.lean @@ -44,6 +44,7 @@ theorem basis_apply (i) : ibc.basis b i = ε (b i) := by simp [LinearEquiv.symm_apply_eq, IsBaseChange.equiv_tmul] simp [this, IsBaseChange.equiv_tmul] +set_option backward.isDefEq.respectTransparency false in theorem basis_repr_comp_apply (v i) : (ibc.basis b).repr (ε v) i = algebraMap R S (b.repr v i) := by conv_lhs => rw [← b.linearCombination_repr v, Finsupp.linearCombination_apply, diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index 69acc938b4f36a..f0ea4e76927495 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -170,6 +170,7 @@ theorem lift_tmul (f : A →ₐ[S] C) (g : B →ₐ[R] C) (hfg : ∀ x y, Commut lift f g hfg (a ⊗ₜ b) = f a * g b := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem lift_includeLeft_includeRight : lift includeLeft includeRight (fun _ _ => (Commute.one_right _).tmul (Commute.one_left _)) = diff --git a/Mathlib/RingTheory/TensorProduct/Quotient.lean b/Mathlib/RingTheory/TensorProduct/Quotient.lean index 14602fe0fed508..b5f77f73934e8f 100644 --- a/Mathlib/RingTheory/TensorProduct/Quotient.lean +++ b/Mathlib/RingTheory/TensorProduct/Quotient.lean @@ -92,6 +92,7 @@ section variable {R : Type*} (S T A : Type*) [CommRing R] [CommRing S] [Algebra R S] [CommRing T] [Algebra R T] [CommRing A] [Algebra R A] [Algebra S A] [IsScalarTower R S A] +set_option backward.isDefEq.respectTransparency false in /-- The tensor product of an `S`-algebra `A` over `R` with the quotient of `T` by an ideal `I` is isomorphic (as an `S`-algebra) to the quotient of `A ⊗[R] T` by the extended ideal. -/ noncomputable def tensorQuotientEquiv (I : Ideal T) : @@ -184,6 +185,7 @@ lemma Algebra.tensorQuotientTensorEquiv_tmul (e : R' ⊗[R] S) (a : R'') (b : R' Ideal.Quotient.mk _ ((a * algebraMap R' R'' b) ⊗ₜ c) := by simp [Algebra.tensorQuotientTensorEquiv, ← Ideal.Quotient.mk_algebraMap, ← map_mul] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma Algebra.tensorQuotientTensorEquiv_symm_tmul (e : R' ⊗[R] S) (a : R'') (b : S) : (Algebra.tensorQuotientTensorEquiv R'' e).symm (Ideal.Quotient.mk _ (a ⊗ₜ b)) = diff --git a/Mathlib/RingTheory/TotallySplit.lean b/Mathlib/RingTheory/TotallySplit.lean index bc0467f1d9a2cc..6882644da57e3f 100644 --- a/Mathlib/RingTheory/TotallySplit.lean +++ b/Mathlib/RingTheory/TotallySplit.lean @@ -96,6 +96,7 @@ lemma bijective_algebraMap_quotient [IsFiniteSplit k R] (p : Ideal R) [p.IsPrime (Function.surjective_eval _) simpa [← g.symm.toAlgHom.comp_algebraMap] using g.symm.bijective +set_option backward.isDefEq.respectTransparency.types false in variable (k R) in /-- If `R` is finite split over a field `k`, the `k`-rational points of `R` are in one-to-one correspondence with its prime spectrum. -/ diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean index d639148dbd2e69..b9edc7b3236a65 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean @@ -77,7 +77,7 @@ lemma mem_ofRingCon {x : R} {c : RingCon R} : x ∈ ofRingCon c ↔ c x 0 := Iff lemma coe_ofRingCon {c : RingCon R} : (ofRingCon c : Set R) = {x | c x 0} := rfl /-- A deprecated alias for `ofRingCon`. -/ -@[deprecated mk (since := "2026-06-18")] +@[deprecated ofRingCon (since := "2026-06-18")] abbrev mk (c : RingCon R) : TwoSidedIdeal R := ofRingCon c @[deprecated mem_ofRingCon (since := "2026-06-18")] diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Lattice.lean b/Mathlib/RingTheory/TwoSidedIdeal/Lattice.lean index 11406844dcf195..80fa8def42aee5 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Lattice.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Lattice.lean @@ -37,6 +37,7 @@ lemma mem_sup_right {I J : TwoSidedIdeal R} {x : R} (h : x ∈ J) : x ∈ I ⊔ J := (show J ≤ I ⊔ J from le_sup_right) h +set_option backward.isDefEq.respectTransparency false in lemma mem_sup {I J : TwoSidedIdeal R} {x : R} : x ∈ I ⊔ J ↔ ∃ y ∈ I, ∃ z ∈ J, y + z = x := by constructor diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean b/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean index b9eca70f6fb1fa..8a8539e9d6ffcd 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean @@ -121,6 +121,7 @@ lemma map_mono {I J : TwoSidedIdeal R} (h : I ≤ J) : variable [NonUnitalRingHomClass F R S] +set_option backward.isDefEq.respectTransparency false in /-- Preimage of a two-sided ideal, as a two-sided ideal. -/ def comap : TwoSidedIdeal S →o TwoSidedIdeal R where @@ -136,6 +137,7 @@ lemma comap_le_comap {I J : TwoSidedIdeal S} (h : I ≤ J) : comap f I ≤ comap f J := (comap f).monotone h +set_option backward.isDefEq.respectTransparency false in lemma mem_comap {I : TwoSidedIdeal S} {x : R} : x ∈ I.comap f ↔ f x ∈ I := by simp [comap, RingCon.comap, mem_iff] @@ -319,6 +321,7 @@ def fromIdeal : Ideal R →o TwoSidedIdeal R where toFun I := span I monotone' _ _ := span_mono +set_option backward.isDefEq.respectTransparency false in lemma mem_fromIdeal {I : Ideal R} {x : R} : x ∈ fromIdeal I ↔ x ∈ span I := by simp [fromIdeal] @@ -331,10 +334,12 @@ def asIdeal : TwoSidedIdeal R →o Ideal R where smul_mem' := fun r x hx => I.mul_mem_left r x hx } monotone' _ _ h _ h' := h h' +set_option backward.isDefEq.respectTransparency false in @[simp] lemma mem_asIdeal {I : TwoSidedIdeal R} {x : R} : x ∈ asIdeal I ↔ x ∈ I := by simp [asIdeal] +set_option backward.isDefEq.respectTransparency false in lemma gc : GaloisConnection fromIdeal (asIdeal (R := R)) := fun I J => ⟨fun h x hx ↦ h <| mem_span_iff.2 fun _ H ↦ H hx, fun h x hx ↦ by simp only [fromIdeal, OrderHom.coe_mk, mem_span_iff] at hx @@ -414,6 +419,7 @@ instance : CanLift (Ideal R) (TwoSidedIdeal R) TwoSidedIdeal.asIdeal (·.IsTwoSi end Ideal +set_option backward.isDefEq.respectTransparency false in /-- A two-sided ideal is simply a left ideal that is two-sided. -/ @[simps] def TwoSidedIdeal.orderIsoIsTwoSided {R : Type*} [Ring R] : TwoSidedIdeal R ≃o {I : Ideal R // I.IsTwoSided} where diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean index 84f8f56aef002b..07d75588e82137 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Finite.lean @@ -27,7 +27,7 @@ namespace UniqueFactorizationMonoid /-- If `y` is a nonzero element of a unique factorization monoid with finitely many units (e.g. `ℤ`, `Ideal (ring_of_integers K)`), it has finitely many divisors. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeSubtypeDvd {M : Type*} [CommMonoidWithZero M] [UniqueFactorizationMonoid M] [Fintype Mˣ] (y : M) (hy : y ≠ 0) : Fintype { x // x ∣ y } := by haveI : Nontrivial M := ⟨⟨y, 0, hy⟩⟩ diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean index b94e85ead641c8..09ac376a4ea149 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/GCDMonoid.lean @@ -52,7 +52,7 @@ instance (priority := 100) (α) [CommMonoidWithZero α] [UniqueFactorizationMono /-- `toNormalizedGCDMonoid` constructs a GCD monoid out of a normalization on a unique factorization domain. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def UniqueFactorizationMonoid.toNormalizedGCDMonoid (α : Type*) [CommMonoidWithZero α] [UniqueFactorizationMonoid α] [NormalizationMonoid α] : NormalizedGCDMonoid α := diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean index d2973d64244ab3..fda34bb2a0870b 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean @@ -375,7 +375,7 @@ variable [CommMonoidWithZero α] [UniqueFactorizationMonoid α] open scoped Classical in /-- Noncomputably defines a `StrongNormalizationMonoid` structure on a `UniqueFactorizationMonoid`. -/ -@[implicit_reducible] +@[instance_reducible] protected noncomputable def strongNormalizationMonoid : StrongNormalizationMonoid α := strongNormalizationMonoidOfMonoidHomRightInverse { toFun := fun a : Associates α => diff --git a/Mathlib/RingTheory/Unramified/Basic.lean b/Mathlib/RingTheory/Unramified/Basic.lean index 0c33400a02463d..e43c70344a6464 100644 --- a/Mathlib/RingTheory/Unramified/Basic.lean +++ b/Mathlib/RingTheory/Unramified/Basic.lean @@ -268,7 +268,6 @@ end of_surjective section BaseChange -open scoped TensorProduct variable {R : Type*} [CommRing R] variable {A : Type*} [CommRing A] [Algebra R A] diff --git a/Mathlib/RingTheory/Unramified/LocalStructure.lean b/Mathlib/RingTheory/Unramified/LocalStructure.lean index c9aebd3eb22ba5..65e65f19a04fcd 100644 --- a/Mathlib/RingTheory/Unramified/LocalStructure.lean +++ b/Mathlib/RingTheory/Unramified/LocalStructure.lean @@ -205,6 +205,7 @@ private lemma exists_hasStandardEtaleSurjectionOn_of_exists_adjoin_singleton_eq_ obtain ⟨c, hc⟩ := hmp₁ simp_all [hm.dvd_mul, dvd_add_left, pow_two, mul_dvd_mul_iff_left, hm.ne_zero] +set_option backward.isDefEq.respectTransparency.types false in lemma exists_notMem_forall_ne_mem_and_adjoin_eq_top (Q : Ideal S) [Q.IsPrime] [Module.Finite R S] [IsUnramifiedAt R Q] [Algebra (Localization.AtPrime (Q.under R)) (Localization.AtPrime Q)] @@ -379,6 +380,7 @@ lemma IsEtaleAt.exists_isStandardEtale exact .trans (PrimeSpectrum.basicOpen_mul_le_left _ _) h exact ⟨f * g, ‹Q.IsPrime›.mul_notMem hfQ hgQ, (hg.of_dvd (by simp)).isStandardEtale⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Given `S` a finitely presented `R`-algebra, and `p` a prime of `S`. If `S` is smooth over `R` at `p`, then there exists `f ∉ p` such that `R → S[1/f]` factors through some `R[X₁,...,Xₙ]`, and that `S[1/f]` is standard etale over `R[X₁,...,Xₙ]`. -/ diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index f869fcfc62cca4..459a3ef93ff9a0 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -198,7 +198,7 @@ protected theorem map_pow : ∀ (x) (n : ℕ), v (x ^ n) = v x ^ n := -- The following definition is not an instance, because we have more than one `v` on a given `R`. -- In addition, type class inference would not be able to infer `v`. /-- A valuation gives a preorder on the underlying ring. -/ -@[implicit_reducible] +@[instance_reducible] def toPreorder : Preorder R := Preorder.lift v @@ -351,6 +351,7 @@ theorem map_one_sub_of_lt (h : v x < 1) : v (1 - x) = 1 := by rw [sub_eq_add_neg 1 x] simpa only [v.map_one, v.map_neg] using v.map_add_eq_of_lt_left h +set_option backward.isDefEq.respectTransparency false in /-- An ordered monoid isomorphism `Γ₀ ≃ Γ'₀` induces an equivalence `Valuation R Γ₀ ≃ Valuation R Γ'₀`. -/ def congr (f : Γ₀ ≃*o Γ'₀) : Valuation R Γ₀ ≃ Valuation R Γ'₀ where @@ -456,6 +457,7 @@ lemma leAddSubgroup_monotone (v : Valuation R Γ₀) : Monotone v.leAddSubgroup open MonoidWithZeroHom MonoidWithZeroHom.ValueGroup₀ +set_option backward.isDefEq.respectTransparency.types false in /-- The restriction of a valuation so that it takes values in its `valueGroup₀`. -/ def restrict : Valuation R (ValueGroup₀ (.ofClass v)) where __ := restrict₀ (.ofClass v) @@ -476,6 +478,7 @@ lemma restrict_def (x : R) : v.restrict x = restrict₀ (.ofClass v) x := rfl lemma embedding_restrict (x : R) : embedding (v.restrict x) = v x := embedding_restrict₀ x +set_option backward.isDefEq.respectTransparency false in lemma restrict_eq_mk {x : R} (hx : v x ≠ 0) : v.restrict x = (valueGroup.mk (.ofClass v) 1 x (by simp) hx : ValueGroup₀ (.ofClass v)) := by simp [restrict_def, restrict₀_apply, dif_neg hx, valueGroup.mk] @@ -485,11 +488,13 @@ lemma restrict_pos_iff (x : R) : 0 < v.restrict x ↔ 0 < v x := by simp only [restrict_def, restrict₀_apply] split_ifs with h <;> simpa [zero_lt_iff] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrict_lt_iff {x y : R} : v.restrict x < v.restrict y ↔ v x < v y := by simp [restrict_def, restrict₀_apply] split_ifs with hx hy <;> simp_all [zero_lt_iff.mpr, ← Units.val_lt_val] +set_option backward.isDefEq.respectTransparency.types false in theorem isEquiv_restrict : v.IsEquiv v.restrict := by intro x y aesop (add norm [restrict_def, restrict₀_apply]) @@ -518,11 +523,13 @@ lemma restrict_eq_zero_iff {x : R} : v.restrict x = 0 ↔ v x = 0 := by lemma restrict_eq_one_iff {x : R} : v.restrict x = 1 ↔ v x = 1 := by simp [restrict_def, restrict₀_eq_one_iff] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrict_le_iff {x y : R} : v.restrict x ≤ v.restrict y ↔ v x ≤ v y := by simp only [restrict_def, restrict₀_apply, MonoidWithZeroHom.coe_ofClass] split_ifs with hx hy <;> simp_all [← Units.val_le_val] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrict_inj {x y : R} : v.restrict x = v.restrict y ↔ v x = v y := by simp only [restrict_def, restrict₀_apply, MonoidWithZeroHom.coe_ofClass] @@ -807,6 +814,7 @@ noncomputable def valueGroup₀Fun (h : v.IsEquiv w) (x : ValueGroup₀ (.ofClas haveI c := (x.zero_or_exists_mk'.resolve_left hx).choose valueGroup.mk (.ofClass w) c.1.1 c.1.2 (h.eq_zero.ne.mp c.2.1) (h.eq_zero.ne.mp c.2.2) +set_option backward.isDefEq.respectTransparency.types false in theorem valueGroup₀Fun_spec (h : v.IsEquiv w) {r s : R} (hr : v r ≠ 0) (hs : v s ≠ 0) : valueGroup₀Fun h (valueGroup.mk (.ofClass v) r s hr hs) = valueGroup.mk (.ofClass w) r s (h.eq_zero.ne.mp hr) (h.eq_zero.ne.mp hs) := by @@ -818,6 +826,7 @@ theorem valueGroup₀Fun_spec (h : v.IsEquiv w) {r s : R} (hr : v r ≠ 0) (hs : theorem valueGroup₀Fun_zero (h : v.IsEquiv w) : valueGroup₀Fun h 0 = 0 := by simp [valueGroup₀Fun] +set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism between the `ValueGroup₀`'s of two equivalent valuations. -/ noncomputable def orderMonoidIso (h : v.IsEquiv w) : ValueGroup₀ (.ofClass v) ≃*o ValueGroup₀ (.ofClass w) where @@ -878,6 +887,7 @@ theorem orderMonoidIso_symm (h : v.IsEquiv w) (h' : w.IsEquiv v) : h.orderMonoidIso.symm = h'.orderMonoidIso := by rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem orderMonoidIso_eq_refl (h : v.IsEquiv v) : h.orderMonoidIso = .refl _ := by @@ -886,6 +896,7 @@ theorem orderMonoidIso_eq_refl (h : v.IsEquiv v) : · simp · simp [orderMonoidIso, valueGroup₀Fun_spec] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem orderMonoidIso_trans (h : v.IsEquiv w) (h' : w.IsEquiv u) : h.orderMonoidIso.trans h'.orderMonoidIso = (h.trans h').orderMonoidIso := by @@ -1174,7 +1185,7 @@ theorem ext {v₁ v₂ : AddValuation R Γ₀} (h : ∀ r, v₁ r = v₂ r) : v -- The following definition is not an instance, because we have more than one `v` on a given `R`. -- In addition, type class inference would not be able to infer `v`. /-- A valuation gives a preorder on the underlying ring. -/ -@[implicit_reducible] +@[instance_reducible] def toPreorder : Preorder R := Preorder.lift v diff --git a/Mathlib/RingTheory/Valuation/Discrete/Basic.lean b/Mathlib/RingTheory/Valuation/Discrete/Basic.lean index dc93e62bd2767d..7a5fc3d0648d31 100644 --- a/Mathlib/RingTheory/Valuation/Discrete/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Discrete/Basic.lean @@ -134,6 +134,7 @@ instance : IsCyclic <| valueGroup (.ofClass v) := by rw [← generator_zpowers_eq_valueGroup] exact isCyclic_zpowers (generator v) +set_option backward.isDefEq.respectTransparency.types false in instance : v.IsNontrivial := by apply IsNontrivial.mk by_contra! h1 @@ -324,6 +325,7 @@ theorem IsUniformizer.of_associated {π₁ π₂ : K₀} (h1 : IsUniformizer v have : v (u.1 : K) = 1 := (Integers.isUnit_iff_valuation_eq_one <| integer.integers v).mp u.isUnit rwa [IsUniformizer.iff, ← hu, Subring.coe_mul, map_mul, this, mul_one, ← IsUniformizer.iff] +set_option backward.isDefEq.respectTransparency.types false in /-- If two elements of `K₀` are uniformizers, then they are associated. -/ theorem associated_of_isUniformizer {π₁ π₂ : K₀} (h1 : IsUniformizer v π₁) (h2 : IsUniformizer v π₂) : Associated π₁ π₂ := by diff --git a/Mathlib/RingTheory/Valuation/Discrete/IsDiscreteValuationRing.lean b/Mathlib/RingTheory/Valuation/Discrete/IsDiscreteValuationRing.lean index e955dc344da471..79ac7d3a0205c6 100644 --- a/Mathlib/RingTheory/Valuation/Discrete/IsDiscreteValuationRing.lean +++ b/Mathlib/RingTheory/Valuation/Discrete/IsDiscreteValuationRing.lean @@ -117,6 +117,7 @@ lemma mker_valuation_eq_isUnitSubmonoid : · obtain ⟨x, h, rfl⟩ := h simpa [IsDiscreteValuationRing.maximalIdeal] using! h +set_option backward.isDefEq.respectTransparency.types false in theorem associated_of_valuation_eq (x y : K) (h : ((maximalIdeal A).valuation K) x = ((maximalIdeal A).valuation K) y) : ∃ u : Aˣ, u • x = y := by diff --git a/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean b/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean index f685ac92f5a45c..b969772f948a56 100644 --- a/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean +++ b/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean @@ -67,7 +67,7 @@ lemma valueGroup₀_equiv_withZeroMulInt_strictMono : (Left.one_lt_inv_iff.mpr hv.generator'_lt_one)))).lt_iff_lt] /-- A discrete valuation has rank one. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def rankOne {e : ℝ≥0} (he : 1 < e) : v.RankOne where hom' := (toNNReal (ne_of_gt (lt_trans zero_lt_one he))).comp (.ofClass (valueGroup₀_equiv_withZeroMulInt v)) @@ -80,6 +80,7 @@ section WithZeroMulInt variable {v : Valuation R ℤᵐ⁰} [hv : v.IsRankOneDiscrete] +set_option backward.isDefEq.respectTransparency.types false in lemma valueGroup₀_equiv_withZeroMulInt_restrict_apply_of_surjective (hsurj : Function.Surjective v) (x : R) : (valueGroup₀_equiv_withZeroMulInt v) (v.restrict x) = v x := by simp only [Valuation.restrict_def, ValueGroup₀.restrict₀_apply, diff --git a/Mathlib/RingTheory/Valuation/ExtendToLocalization.lean b/Mathlib/RingTheory/Valuation/ExtendToLocalization.lean index def1529b422cb4..80ad75eb17b048 100644 --- a/Mathlib/RingTheory/Valuation/ExtendToLocalization.lean +++ b/Mathlib/RingTheory/Valuation/ExtendToLocalization.lean @@ -50,6 +50,7 @@ noncomputable def Valuation.extendToLocalization : Valuation B Γ := dsimp grw [max_mul_mul_right, v.map_add a b] } +set_option backward.isDefEq.respectTransparency false in @[simp] theorem Valuation.extendToLocalization_mk' (x : A) (y : S) : (v.extendToLocalization hS B) (IsLocalization.mk' _ x y) = diff --git a/Mathlib/RingTheory/Valuation/Integers.lean b/Mathlib/RingTheory/Valuation/Integers.lean index baee5b9d6767c1..19a5dad8322e23 100644 --- a/Mathlib/RingTheory/Valuation/Integers.lean +++ b/Mathlib/RingTheory/Valuation/Integers.lean @@ -247,6 +247,7 @@ lemma isPrincipal_iff_exists_eq_setOf_valuation_le (hv : Integers v O) {I : Idea · simp [hx] · simp [hx, mem_upperBounds] +set_option backward.isDefEq.respectTransparency false in lemma not_denselyOrdered_of_isPrincipalIdealRing [IsPrincipalIdealRing O] (hv : Integers v O) : ¬ DenselyOrdered (range v) := by intro H diff --git a/Mathlib/RingTheory/Valuation/LocalSubring.lean b/Mathlib/RingTheory/Valuation/LocalSubring.lean index 2b3bd4613aba31..de496303057e86 100644 --- a/Mathlib/RingTheory/Valuation/LocalSubring.lean +++ b/Mathlib/RingTheory/Valuation/LocalSubring.lean @@ -91,6 +91,7 @@ lemma ValuationSubring.isMax_toLocalSubring (R : ValuationSubring K) : have : x' = x := by simpa [Subtype.ext_iff, inv_mul_eq_iff_eq_mul₀ hx0] using hx' exact h' (this ▸ x'.2) +set_option backward.isDefEq.respectTransparency.types false in @[stacks 00IB] lemma LocalSubring.exists_valuationRing_of_isMax {R : LocalSubring K} (hR : IsMax R) : ∃ R' : ValuationSubring K, R'.toLocalSubring = R := by @@ -171,6 +172,7 @@ open Polynomial Algebra in exact ⟨V, fun r hr ↦ hV.1 (B.algebraMap_mem ⟨r, hr⟩), (V.inv_mem_nonunits_iff.mp <| hV.2 ⟨_, Ideal.subset_span rfl, rfl⟩).resolve_left hx0⟩ +set_option backward.isDefEq.respectTransparency.types false in open Polynomial Algebra in @[stacks 090P "part (2)"] lemma LocalSubring.exists_le_valuationSubring_of_isIntegrallyClosedIn {x : K} {R : LocalSubring K} (hxR : x ∉ R.toSubring) [IsIntegrallyClosedIn R.toSubring K] : @@ -223,6 +225,7 @@ lemma iInf_valuationSubring_superset {s : Set K} : rw [Subring.integralClosure_subring_le_iff] exact Subring.closure_le.symm +set_option backward.isDefEq.respectTransparency.types false in lemma bijective_rangeRestrict_comp_of_valuationRing [IsDomain R] [ValuationRing R] [IsLocalRing S] [Algebra R K] [IsFractionRing R K] (f : R →+* S) (g : S →+* K) (h : g.comp f = algebraMap R K) [IsLocalHom f] : diff --git a/Mathlib/RingTheory/Valuation/RankOne.lean b/Mathlib/RingTheory/Valuation/RankOne.lean index 9b21884f650ca2..f128dd1b55ff0c 100644 --- a/Mathlib/RingTheory/Valuation/RankOne.lean +++ b/Mathlib/RingTheory/Valuation/RankOne.lean @@ -143,6 +143,7 @@ instance restrict_RankOne : RankOne (v.restrict) where lemma restrict_RankOne_hom_eq : RankOne.hom v.restrict = (RankOne.hom v).comp embedding := rfl +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {K} in theorem exists_val_lt {γ : ℝ≥0} (hγ : γ ≠ 0) : ∃ x ≠ 0, RankOne.hom v (v.restrict x) < γ := by @@ -170,7 +171,7 @@ variable {K : Type*} [DivisionRing K] (v : Valuation K Γ₀) [RankLeOne v] /-- If a valuation has rank at most one and is non trivial, then it has rank one -/ -@[implicit_reducible] +@[instance_reducible] def rankOne_of_exists (H : ∃ x ≠ 0, v x ≠ 1) : RankOne v where exists_val_nontrivial := by by_contra! H' @@ -179,7 +180,7 @@ def rankOne_of_exists (H : ∃ x ≠ 0, v x ≠ 1) : RankOne v where /-- If a valuation has rank at most one and is non trivial, then it has rank one -/ -@[implicit_reducible] +@[instance_reducible] def rankOne_of_nontrivial (H : Nontrivial (ValueGroup₀ (.ofClass v))ˣ) : RankOne v where exists_val_nontrivial := by by_contra! H' @@ -218,7 +219,7 @@ variable {R : Type*} [Ring R] [ValuativeRel R] /-- A valuative relation has a rank one valuation when it is both nontrivial and the rank is at most one. -/ -@[implicit_reducible] +@[instance_reducible] def Valuation.RankOne.ofRankLeOneStruct [ValuativeRel.IsNontrivial R] (e : RankLeOneStruct R) : Valuation.RankOne (valuation R) where hom' := e.emb.comp embedding diff --git a/Mathlib/RingTheory/Valuation/ValuationRing.lean b/Mathlib/RingTheory/Valuation/ValuationRing.lean index 2e3868e351bd39..f3204a6c30622b 100644 --- a/Mathlib/RingTheory/Valuation/ValuationRing.lean +++ b/Mathlib/RingTheory/Valuation/ValuationRing.lean @@ -145,6 +145,7 @@ protected theorem le_total (a b : ValueGroup A K) : a ≤ b ∨ b ≤ a := by field_simp simp only [← map_mul]; congr 1; linear_combination h +set_option backward.isDefEq.respectTransparency false in noncomputable instance linearOrder : LinearOrder (ValueGroup A K) where le_refl := by rintro ⟨⟩; use 1; rw [one_smul] le_trans := by rintro ⟨a⟩ ⟨b⟩ ⟨c⟩ ⟨e, rfl⟩ ⟨f, rfl⟩; use e * f; rw [mul_smul] diff --git a/Mathlib/RingTheory/Valuation/ValuationSubring.lean b/Mathlib/RingTheory/Valuation/ValuationSubring.lean index cf0ce5bbf3e112..d3d43003c384c4 100644 --- a/Mathlib/RingTheory/Valuation/ValuationSubring.lean +++ b/Mathlib/RingTheory/Valuation/ValuationSubring.lean @@ -694,6 +694,7 @@ theorem coe_mem_principalUnitGroup_iff {x : A.unitGroup} : rw [← π.map_one, ← sub_eq_zero, ← π.map_sub, Ideal.Quotient.eq_zero_iff_mem, valuation_lt_one_iff] simp [mem_principalUnitGroup_iff] +set_option backward.isDefEq.respectTransparency.types false in /-- The principal unit group agrees with the kernel of the canonical map from the units of `A` to the units of the residue field of `A`. -/ def principalUnitGroupEquiv : diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 0d694d4572df9c..2fe43093426cbc 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -329,7 +329,7 @@ lemma val_posSubmonoid_ne_zero (x : posSubmonoid R) : (x : R) ≠ 0 := by variable (R) in /-- The setoid used to construct `ValueGroupWithZero R`. -/ -@[implicit_reducible] +@[instance_reducible] def valueSetoid : Setoid (R × posSubmonoid R) where r := fun (x, s) (y, t) => x * t ≤ᵥ y * s ∧ y * s ≤ᵥ x * t iseqv := { @@ -694,7 +694,7 @@ lemma ValueGroupWithZero.mk_eq_div (r : R) (s : posSubmonoid R) : simp [valuation, mk_eq_mk] /-- Construct a valuative relation on a ring using a valuation. -/ -@[implicit_reducible] +@[instance_reducible] def ofValuation {S Γ : Type*} [Ring S] [LinearOrderedCommGroupWithZero Γ] @@ -1149,6 +1149,7 @@ lemma embed_strictMono [v.Compatible] : StrictMono (embed v) := by · simp [restrict₀_apply, embed] · simp [restrict₀_apply, embed] +set_option backward.isDefEq.respectTransparency false in /-- When we have `h : w.IsEquiv v`, the image group (with zero) of `v` is isomorphic to that of `w` via `h.orderMonoidIso`. Then the following diagram is commutative: diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean index 35e6c1e2c7a42e..72194dc66f8f0a 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean @@ -33,7 +33,7 @@ open WithZero /-- The trivial valuative relation on a domain `R`, such that all non-zero elements are related. The domain condition is necessary so that the relation is closed when multiplying. -/ -@[implicit_reducible] +@[instance_reducible] def trivialRel {R : Type} [Semiring R] [DecidableEq R] [IsDomain R] : ValuativeRel R where vle x y := if y = 0 then x = 0 else True vle_total _ _ := by split_ifs <;> simp_all diff --git a/Mathlib/RingTheory/WittVector/FrobeniusFractionField.lean b/Mathlib/RingTheory/WittVector/FrobeniusFractionField.lean index 25380ba5a64305..3a88995cbc799c 100644 --- a/Mathlib/RingTheory/WittVector/FrobeniusFractionField.lean +++ b/Mathlib/RingTheory/WittVector/FrobeniusFractionField.lean @@ -194,6 +194,7 @@ theorem frobeniusRotation_nonzero {a₁ a₂ : 𝕎 k} (ha₁ : a₁.coeff 0 ≠ apply solution_nonzero p ha₁ ha₂ simpa [← h, frobeniusRotation, frobeniusRotationCoeff] using WittVector.zero_coeff p k 0 +set_option backward.isDefEq.respectTransparency.types false in theorem frobenius_frobeniusRotation {a₁ a₂ : 𝕎 k} (ha₁ : a₁.coeff 0 ≠ 0) (ha₂ : a₂.coeff 0 ≠ 0) : frobenius (frobeniusRotation p ha₁ ha₂) * a₁ = frobeniusRotation p ha₁ ha₂ * a₂ := by ext n diff --git a/Mathlib/RingTheory/WittVector/InitTail.lean b/Mathlib/RingTheory/WittVector/InitTail.lean index aa0b1f9d1673fe..76152d1d87779e 100644 --- a/Mathlib/RingTheory/WittVector/InitTail.lean +++ b/Mathlib/RingTheory/WittVector/InitTail.lean @@ -158,7 +158,7 @@ syntax (name := initRing) "init_ring" (" using " term)? : tactic -- Porting note: this tactic requires that we turn hygiene off (note the free `n`). -- TODO: make this tactic hygienic. -open Lean Elab Tactic in +open Lean Elab Elab.Tactic in elab_rules : tactic | `(tactic| init_ring $[ using $a:term]?) => withMainContext <| set_option hygiene false in do evalTactic <|← `(tactic|( diff --git a/Mathlib/RingTheory/WittVector/Isocrystal.lean b/Mathlib/RingTheory/WittVector/Isocrystal.lean index e4f803497f2e1d..cfe4966b0359b5 100644 --- a/Mathlib/RingTheory/WittVector/Isocrystal.lean +++ b/Mathlib/RingTheory/WittVector/Isocrystal.lean @@ -127,11 +127,13 @@ def Isocrystal.frobenius : V ≃ᶠˡ[p, k] V := @[inherit_doc] scoped[Isocrystal] notation "Φ(" p ", " k ")" => WittVector.Isocrystal.frobenius p k +set_option backward.isDefEq.respectTransparency.types false in /-- A homomorphism between isocrystals respects the Frobenius map. Notation `M →ᶠⁱ [p, k]` in the `Isocrystal` namespace. -/ structure IsocrystalHom extends V →ₗ[K(p, k)] V₂ where frob_equivariant : ∀ x : V, Φ(p, k) (toLinearMap x) = toLinearMap (Φ(p, k) x) +set_option backward.isDefEq.respectTransparency.types false in /-- An isomorphism between isocrystals respects the Frobenius map. Notation `M ≃ᶠⁱ [p, k]` in the `Isocrystal` namespace. -/ @@ -168,6 +170,7 @@ instance (m : ℤ) : Isocrystal p k (StandardOneDimIsocrystal p k m) where (FractionRing.frobenius p k).toSemilinearEquiv.trans (LinearEquiv.smulOfNeZero _ _ _ (zpow_ne_zero m (WittVector.FractionRing.p_nonzero p k))) +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem StandardOneDimIsocrystal.frobenius_apply (m : ℤ) (x : StandardOneDimIsocrystal p k m) : Φ(p, k) x = (p : K(p, k)) ^ m • φ(p, k) x := rfl diff --git a/Mathlib/RingTheory/ZariskisMainTheorem.lean b/Mathlib/RingTheory/ZariskisMainTheorem.lean index c0e5a825954c65..f24dbf615d28cc 100644 --- a/Mathlib/RingTheory/ZariskisMainTheorem.lean +++ b/Mathlib/RingTheory/ZariskisMainTheorem.lean @@ -139,6 +139,7 @@ section IsStronglyTranscendental variable (φ : R[X] →ₐ[R] S) (t : S) (p r : R[X]) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a map `φ : R[X] →ₐ[R] S`. Suppose `t = φ r / φ p` is integral over `R[X]` where `p` is monic with `deg p > deg r`, then `t` is also integral over `R`. -/ lemma isIntegral_of_isIntegralElem_of_monic_of_natDegree_lt diff --git a/Mathlib/SetTheory/Cardinal/Arithmetic.lean b/Mathlib/SetTheory/Cardinal/Arithmetic.lean index be12df1074de38..29ab245cadb1d0 100644 --- a/Mathlib/SetTheory/Cardinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Cardinal/Arithmetic.lean @@ -40,6 +40,7 @@ namespace Cardinal /-! ### Properties of `mul` -/ section mul +set_option backward.isDefEq.respectTransparency false in /-- If `α` is an infinite type, then `α × α` and `α` have the same cardinality. -/ theorem mul_eq_self {c : Cardinal} (hc : ℵ₀ ≤ c) : c * c = c := by -- The only nontrivial part is `c * c ≤ c`. We prove it inductively. @@ -543,6 +544,7 @@ end mul_strictMono /-! ### Properties about `power` -/ section power +set_option backward.isDefEq.respectTransparency false in theorem pow_le {κ μ : Cardinal.{u}} (H1 : ℵ₀ ≤ κ) (H2 : μ < ℵ₀) : κ ^ μ ≤ κ := let ⟨n, H3⟩ := lt_aleph0.1 H2 H3.symm ▸ diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index e5c1792351d83c..63ee719ca69174 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -142,6 +142,7 @@ end Cardinal namespace Cardinal +set_option backward.isDefEq.respectTransparency false in instance small_Iic (a : Cardinal.{u}) : Small.{u} (Iic a) := by rw [← mk_out a] apply @small_of_surjective (Set a.out) (Iic #a.out) _ fun x => ⟨#x, mk_set_le x⟩ diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean index ab0ba04bff0862..4b8bd2fdf007f4 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean @@ -251,6 +251,7 @@ theorem le_cof_map_of_isNormal {f} (hf : IsNormal f) (a) : cof a ≤ cof (f a) : @[deprecated (since := "2026-03-19")] alias cof_le_of_isNormal := le_cof_map_of_isNormal +set_option backward.isDefEq.respectTransparency false in theorem sSup_add_one_lt_of_lt_cof {s : Set Ordinal.{u}} {a : Ordinal.{u}} (ha : #s < (lift.{u + 1} a).cof) (hs : ∀ i ∈ s, i < a) : sSup ((· + 1) '' s) < a := by let f := OrderIso.ofRelIsoLT (enum (α := s) (· < ·)) diff --git a/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean b/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean index 99db04260f81fc..d2197340546279 100644 --- a/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean +++ b/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean @@ -168,6 +168,7 @@ lemma hasCardinalLT_subtype_iSup obtain ⟨i, hi⟩ := h exact ⟨⟨i, _, hi⟩, rfl⟩) +set_option backward.isDefEq.respectTransparency false in lemma hasCardinalLT_iUnion {ι : Type*} {X : Type*} (S : ι → Set X) {κ : Cardinal} [Fact κ.IsRegular] (hι : HasCardinalLT ι κ) (hS : ∀ i, HasCardinalLT (S i) κ) : diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index bee5851a6a4934..987184dd48fa8d 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -483,6 +483,7 @@ theorem le_sum {ι : Type u} (f : ι → Cardinal.{max u v}) (i) : f i ≤ sum f theorem iSup_le_sum {ι} (f : ι → Cardinal) : iSup f ≤ sum f := ciSup_le' <| le_sum _ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem sum_add_distrib {ι} (f g : ι → Cardinal) : sum (f + g) = sum f + sum g := by have := mk_congr (Equiv.sigmaSumDistrib (Quotient.out ∘ f) (Quotient.out ∘ g)) diff --git a/Mathlib/SetTheory/Descriptive/Tree.lean b/Mathlib/SetTheory/Descriptive/Tree.lean index 68a0af8b0742a3..d6d510173376bc 100644 --- a/Mathlib/SetTheory/Descriptive/Tree.lean +++ b/Mathlib/SetTheory/Descriptive/Tree.lean @@ -101,9 +101,11 @@ def pullSub : tree A where variable {T x y} +set_option backward.isDefEq.respectTransparency false in lemma mem_pullSub_short (hl : y.length ≤ x.length) : y ∈ pullSub T x ↔ y <+: x ∧ [] ∈ T := by simp [pullSub, List.take_of_length_le hl, List.drop_eq_nil_iff.mpr hl] +set_option backward.isDefEq.respectTransparency false in lemma mem_pullSub_long (hl : x.length ≤ y.length) : y ∈ pullSub T x ↔ ∃ z ∈ T, y = x ++ z where mp := by intro ⟨h1, h2⟩; use y.drop x.length, h2 @@ -136,6 +138,7 @@ lemma pullSub_adjunction (S T : tree A) (x : List A) : pullSub S x ≤ T ↔ S @[simp] lemma pullSub_nil : pullSub T [] = T := by simp [pullSub] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma pullSub_append : pullSub (pullSub T y) x = pullSub T (x ++ y) := by ext z; rcases le_total x.length z.length with hl | hl · by_cases hp : x <+: z diff --git a/Mathlib/SetTheory/Lists.lean b/Mathlib/SetTheory/Lists.lean index 970c56cfded6fc..028bdf0aa6aabb 100644 --- a/Mathlib/SetTheory/Lists.lean +++ b/Mathlib/SetTheory/Lists.lean @@ -175,6 +175,7 @@ theorem subset_nil {l : Lists' α true} : l ⊆ Lists'.nil → l = Lists'.nil := · rfl · rcases cons_subset.1 h with ⟨⟨_, ⟨⟩, _⟩, _⟩ +set_option backward.isDefEq.respectTransparency false in theorem mem_of_subset' {a} : ∀ {l₁ l₂ : Lists' α true} (_ : l₁ ⊆ l₂) (_ : a ∈ l₁.toList), a ∈ l₂ | nil, _, Lists'.Subset.nil, h => by cases h | cons' a0 l0, l₂, s, h => by @@ -225,6 +226,7 @@ theorem isList_toList (l : List (Lists α)) : IsList (ofList l) := theorem to_ofList (l : List (Lists α)) : toList (ofList l) = l := by simp [ofList, of'] +set_option backward.isDefEq.respectTransparency false in theorem of_toList : ∀ {l : Lists α}, IsList l → ofList (toList l) = l | ⟨true, l⟩, _ => by simp_all [ofList, of'] @@ -324,8 +326,9 @@ theorem lt_sizeof_cons' {b} (a : Lists' α b) (l) : variable [DecidableEq α] +set_option backward.isDefEq.respectTransparency false in mutual - @[implicit_reducible] + @[instance_reducible] def Equiv.decidable : ∀ l₁ l₂ : Lists α, Decidable (l₁ ~ l₂) | ⟨false, l₁⟩, ⟨false, l₂⟩ => decidable_of_iff' (l₁ = l₂) <| by @@ -348,7 +351,7 @@ mutual Subset.decidable l₂ l₁ exact decidable_of_iff' _ Equiv.antisymm_iff termination_by x y => sizeOf x + sizeOf y - @[implicit_reducible] + @[instance_reducible] def Subset.decidable : ∀ l₁ l₂ : Lists' α true, Decidable (l₁ ⊆ l₂) | Lists'.nil, _ => isTrue Lists'.Subset.nil | @Lists'.cons' _ b a l₁, l₂ => by @@ -362,7 +365,7 @@ mutual Subset.decidable l₁ l₂ exact decidable_of_iff' _ (@Lists'.cons_subset _ ⟨_, _⟩ _ _) termination_by x y => sizeOf x + sizeOf y - @[implicit_reducible] + @[instance_reducible] def mem.decidable : ∀ (a : Lists α) (l : Lists' α true), Decidable (a ∈ l) | a, Lists'.nil => isFalse <| by rintro ⟨_, ⟨⟩, _⟩ | a, Lists'.cons' b l₂ => by diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index b5bf8f88eb9bf0..efe143abee95af 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -186,6 +186,7 @@ theorem enum_succ_eq_top {o : Ordinal} : enum (α := (succ o).ToType) (· < ·) ⟨o, type_toType _ ▸ lt_succ o⟩ = ⊤ := rfl +set_option backward.isDefEq.respectTransparency false in @[deprecated isSuccPrelimit_type_lt_iff (since := "2026-04-12")] theorem has_succ_of_type_succ_lt {α} {r : α → α → Prop} [wo : IsWellOrder α r] (h : ∀ a < type r, succ a < type r) (x : α) : ∃ y, r x y := by @@ -198,6 +199,7 @@ theorem has_succ_of_type_succ_lt {α} {r : α → α → Prop} [wo : IsWellOrder theorem toType_noMax_of_succ_lt {o : Ordinal} (ho : ∀ a < o, succ a < o) : NoMaxOrder o.ToType := ⟨has_succ_of_type_succ_lt (type_toType _ ▸ ho)⟩ +set_option backward.isDefEq.respectTransparency false in theorem bounded_singleton {r : α → α → Prop} [IsWellOrder α r] (hr : IsSuccLimit (type r)) (x) : Bounded r {x} := by refine ⟨enum r ⟨succ (typein r x), hr.succ_lt (typein_lt_type r x)⟩, ?_⟩ @@ -458,6 +460,7 @@ theorem le_mul_right (a : Ordinal) {b : Ordinal} (hb : 0 < b) : a ≤ b * a := b convert! mul_le_mul_left (one_le_iff_pos.2 hb) a rw [one_mul a] +set_option backward.isDefEq.respectTransparency false in private theorem mul_le_of_limit_aux {α β r s} [IsWellOrder α r] [IsWellOrder β s] {c} (h : IsSuccLimit (type s)) (H : ∀ b' < type s, type r * b' ≤ c) (l : c < type r * type s) : False := by @@ -888,6 +891,7 @@ theorem typein_lt_fin {n : ℕ} (x : Fin n) : typein LT.lt x = x := by rw [← type_Iio_lt, type_fintype, Nat.cast_inj] exact Fintype.card_fin_lt_of_le x.is_le' +set_option backward.isDefEq.respectTransparency false in @[simp] theorem enum_lt_fin {n : ℕ} (x : Fin n) : enum LT.lt ⟨x, by simp⟩ = x := by simp [← typein_inj LT.lt] @@ -903,6 +907,7 @@ theorem natCast_lt_omega0 (n : ℕ) : ↑n < ω := @[deprecated (since := "2026-03-08")] alias nat_lt_omega0 := natCast_lt_omega0 +set_option backward.isDefEq.respectTransparency false in @[simp] theorem enum_lt_nat (x : ℕ) : enum LT.lt ⟨x, by simp⟩ = x := by simp [← typein_inj LT.lt] diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 79a5ed4c70f2d3..dcc77b17305f99 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -514,6 +514,7 @@ theorem enum_zero_le' {o : Ordinal} (h0 : 0 < o) (a : o.ToType) : rw [← not_lt] apply enum_zero_le +set_option backward.isDefEq.respectTransparency false in theorem relIso_enum' {α β : Type u} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s] (f : r ≃r s) (o : Ordinal) : ∀ (hr : o < type r) (hs : o < type s), f (enum r ⟨o, hr⟩) = enum s ⟨o, hs⟩ := by @@ -555,7 +556,7 @@ instance small_Ioo (a b : Ordinal.{u}) : Small.{u} (Ioo a b) := small_subset Ioo instance small_Ioc (a b : Ordinal.{u}) : Small.{u} (Ioc a b) := small_subset Ioc_subset_Iic_self /-- `o.ToType` is an `OrderBot` whenever `o ≠ 0`. -/ -@[implicit_reducible, deprecated WellFoundedLT.toOrderBot (since := "2026-04-12")] +@[instance_reducible, deprecated WellFoundedLT.toOrderBot (since := "2026-04-12")] def toTypeOrderBot {o : Ordinal} (ho : o ≠ 0) : OrderBot o.ToType where bot := (enum (· < ·)) ⟨0, _⟩ bot_le := enum_zero_le' (bot_lt_iff_ne_bot.2 ho) @@ -975,6 +976,7 @@ instance uniqueToTypeOne : Unique (ToType 1) where theorem one_toType_eq (x : ToType 1) : x = enum (· < ·) ⟨0, by simp⟩ := Unique.eq_default x +set_option backward.isDefEq.respectTransparency false in theorem type_lt_mem_range_succ_iff [LinearOrder α] [WellFoundedLT α] : typeLT α ∈ range succ ↔ ∃ x : α, IsMax x := by simp_rw [← isTop_iff_isMax] @@ -1008,6 +1010,7 @@ theorem isSuccPrelimit_type_lt [LinearOrder α] [WellFoundedLT α] [h : NoMaxOrd -- TODO: use `ToType.mk` for lemmas on `ToType` rather than `enum` and `typein`. +set_option backward.isDefEq.respectTransparency false in @[simp] theorem typein_one_toType (x : ToType 1) : typein (α := ToType 1) (· < ·) x = 0 := by rw [one_toType_eq x, typein_enum] @@ -1016,6 +1019,7 @@ theorem typein_le_typein' (o : Ordinal) {x y : o.ToType} : typein (α := o.ToType) (· < ·) x ≤ typein (α := o.ToType) (· < ·) y ↔ x ≤ y := by simp +set_option backward.isDefEq.respectTransparency false in theorem le_enum_succ {o : Ordinal} (a : (succ o).ToType) : a ≤ enum (α := (succ o).ToType) (· < ·) ⟨o, (type_toType _ ▸ lt_succ o)⟩ := by rw [← enum_typein (α := (succ o).ToType) (· < ·) a, enum_le_enum', Subtype.mk_le_mk, diff --git a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean index f34baf3e723b91..0efcdfec0fff1c 100644 --- a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean +++ b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean @@ -176,6 +176,7 @@ Cantor Normal Form (`CNF`) of `o`, for each `e`. -/ def coeff (b o : Ordinal) : Ordinal →₀ Ordinal := lookupFinsupp ⟨_, nodupKeys b o⟩ +set_option backward.isDefEq.respectTransparency false in theorem support_coeff (b o : Ordinal) : (coeff b o).support = ((CNF b o).map Prod.fst).toFinset := by rw [coeff, lookupFinsupp_support, filter_eq_self.2] diff --git a/Mathlib/SetTheory/Ordinal/Family.lean b/Mathlib/SetTheory/Ordinal/Family.lean index 95daef9dcf4029..4a01cac1256798 100644 --- a/Mathlib/SetTheory/Ordinal/Family.lean +++ b/Mathlib/SetTheory/Ordinal/Family.lean @@ -65,6 +65,7 @@ theorem bfamilyOfFamily_typein {ι} (f : ι → α) (i) : bfamilyOfFamily f (typein _ i) (typein_lt_type _ i) = f i := bfamilyOfFamily'_typein _ f i +set_option backward.isDefEq.respectTransparency false in @[deprecated "familyOfBFamily is deprecated" (since := "2026-04-06")] theorem familyOfBFamily'_enum {ι : Type u} (r : ι → ι → Prop) [IsWellOrder ι r] {o} (ho : type r = o) (f : ∀ a < o, α) (i hi) : diff --git a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean index c8a1d6e808134d..e1fbb7a6994b29 100644 --- a/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean +++ b/Mathlib/SetTheory/Ordinal/FundamentalSequence.lean @@ -77,6 +77,7 @@ protected theorem zero (f : Iio 0 → Iio 0) : IsFundamentalSeq f where le_ord_cof := by simp isCofinal_range := .of_isEmpty +set_option backward.isDefEq.respectTransparency false in /-- The length one sequence `(o)` is a fundamental sequence for `o + 1`. -/ protected theorem add_one (o : Ordinal) : @IsFundamentalSeq 1 (o + 1) fun _ ↦ ⟨o, lt_add_one o⟩ where diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index 289dbb07ff7f4e..aee00c41669349 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -147,7 +147,7 @@ namespace Classical open PSet ZFSet /-- All functions are classically definable. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def allZFSetDefinable {n} (F : (Fin n → ZFSet.{u}) → ZFSet.{u}) : Definable n F where out xs := (F (mk <| xs ·)).out @@ -639,6 +639,7 @@ variable {α : Type*} [Small.{u} α] noncomputable def range (f : α → ZFSet.{u}) : ZFSet.{u} := ⟦⟨_, Quotient.out ∘ f ∘ (equivShrink α).symm⟩⟧ +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mem_range {f : α → ZFSet.{u}} {x : ZFSet.{u}} : x ∈ range f ↔ ∃ i, f i = x := Quotient.inductionOn x fun y => by diff --git a/Mathlib/SetTheory/ZFC/Class.lean b/Mathlib/SetTheory/ZFC/Class.lean index 5f0361f21f384d..9e12f70407fb4c 100644 --- a/Mathlib/SetTheory/ZFC/Class.lean +++ b/Mathlib/SetTheory/ZFC/Class.lean @@ -317,6 +317,7 @@ end Class namespace ZFSet +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem map_fval {f : ZFSet.{u} → ZFSet.{u}} [Definable₁ f] {x y : ZFSet.{u}} (h : y ∈ x) : (ZFSet.map f x ′ y : Class.{u}) = f y := diff --git a/Mathlib/SetTheory/ZFC/Ordinal.lean b/Mathlib/SetTheory/ZFC/Ordinal.lean index 4c6cc793d9b0a3..5c8eadb98388f3 100644 --- a/Mathlib/SetTheory/ZFC/Ordinal.lean +++ b/Mathlib/SetTheory/ZFC/Ordinal.lean @@ -396,6 +396,7 @@ theorem isOrdinal_iff_mem_range_toZFSet {x : ZFSet.{u}} : · rintro ⟨a, rfl⟩ exact isOrdinal_toZFSet a +set_option backward.isDefEq.respectTransparency false in /-- `Ordinal` is order-equivalent to the type of von Neumann ordinals. -/ @[simps apply symm_apply] noncomputable def _root_.Ordinal.toZFSetIso : Ordinal ≃o {x // ZFSet.IsOrdinal x} where diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean index 7ebab0b38796a1..c07dd86654fc03 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basic.lean @@ -114,6 +114,7 @@ theorem Multiseries.const_def {basis_hd basis_tl} (c : ℝ) : Multiseries.cons 0 (MultiseriesExpansion.const basis_tl c) .nil := by simp [Multiseries.const] +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem const_toFun' {basis : Basis} {c : ℝ} : (const basis c).toFun = fun _ ↦ c := by match basis with diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean index c8d5ae4f4b1111..75e57d1f301249 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean @@ -65,7 +65,7 @@ Then `f` is friendly iff it is `1`-Lipschitz. namespace Tactic.ComputeAsymptotics.Seq -open Stream' Seq +open Stream' Stream'.Seq open scoped UniformConvergence @@ -83,6 +83,7 @@ noncomputable local instance : MetricSpace (Seq α) := local instance : CompleteSpace (Stream' α) := @PiNat.completeSpace _ (fun _ ↦ ⊥) (fun _ ↦ discreteTopology_bot _) +set_option backward.isDefEq.respectTransparency false in local instance : CompleteSpace (Seq α) := by suffices IsClosed (X := Stream' (Option α)) (fun x ↦ ∀ {n : ℕ}, x n = none → x (n + 1) = none) by @@ -234,6 +235,7 @@ theorem exists_fixed_point_of_contractible (F : (β →ᵤ Seq α) → (β → use f exact hF.fixedPoint_isFixedPt +set_option backward.isDefEq.respectTransparency false in /-- Main theorem of this file. It shows that there exists a function satisfying the corecursive definition of the form `def foo (x : X) := hd x :: op (foo (tlArg x))` where `f` is friendly. -/ theorem FriendlyOperation.exists_fixed_point (F : β → Option (α × γ × β)) (op : γ → Seq α → Seq α) @@ -416,6 +418,7 @@ theorem FriendlyOperation.of_dist_le_pow {op : Seq α → Seq α} obtain ⟨n, hst⟩ := dist_eq_two_inv_pow hst grind +set_option backward.isDefEq.respectTransparency.types false in /-- Coinduction principle for proving that an operation is friendly. -/ theorem FriendlyOperation.coind (motive : (Seq α → Seq α) → Prop) {op : Seq α → Seq α} diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean index 1e332c14282d37..51a86e98978f5e 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean @@ -151,6 +151,7 @@ theorem FriendlyOperationClass.mk' {basis_hd basis_tl} {γ : Type*} suffices Seq.FriendlyOperationClass op by constructor exact ⟨h⟩ +set_option backward.isDefEq.respectTransparency false in private lemma destruct_eq_destruct_map {basis_hd basis_tl} (s : Stream'.Seq (ℝ × MultiseriesExpansion basis_tl)) : s.destruct = (Multiseries.destruct (basis_hd := basis_hd) s).map @@ -158,6 +159,7 @@ private lemma destruct_eq_destruct_map {basis_hd basis_tl} simp only [destruct, Option.map_map] exact Option.map_id_apply.symm +set_option backward.isDefEq.respectTransparency false in theorem FriendlyOperation.coind_comp_friend_left {basis_hd basis_tl} {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} (motive : (Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) → Prop) @@ -175,6 +177,7 @@ theorem FriendlyOperation.coind_comp_friend_left {basis_hd basis_tl} simp rfl +set_option backward.isDefEq.respectTransparency false in theorem FriendlyOperation.coind_comp_friend_right {basis_hd basis_tl} {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} (motive : (Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl) → Prop) @@ -244,6 +247,7 @@ def FriendlyOperation.unfold {basis_hd basis_tl} @Multiseries.FriendlyOperation basis_hd basis_tl)) := Seq.FriendlyOperation.unfold h hd? |>.map (fun ((exp, coef), op') ↦ (exp, coef, op')) +set_option backward.isDefEq.respectTransparency false in theorem FriendlyOperation.destruct_apply_eq_unfold {basis_hd basis_tl} {op : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} (h : FriendlyOperation op) (ms : Multiseries basis_hd basis_tl) : @@ -358,6 +362,7 @@ theorem corec_cons {β : Type*} {basis_hd} {basis_tl} {exp : ℝ} rw [Seq.corec_cons] simpa +set_option backward.isDefEq.respectTransparency false in theorem gcorec_nil {β γ : Type*} {basis_hd} {basis_tl} {F : β → Option (ℝ × MultiseriesExpansion basis_tl × γ × β)} {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} @@ -369,6 +374,7 @@ theorem gcorec_nil {β γ : Type*} {basis_hd} {basis_tl} · simp [nil] · simpa +set_option backward.isDefEq.respectTransparency false in theorem gcorec_some {β γ : Type*} {basis_hd} {basis_tl} {F : β → Option (ℝ × MultiseriesExpansion basis_tl × γ × β)} {op : γ → Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl} @@ -400,6 +406,7 @@ theorem destruct_eq_none {basis_hd : ℝ → ℝ} {basis_tl : Basis} {ms : Multi apply Stream'.Seq.destruct_eq_none simpa [destruct] using h +set_option backward.isDefEq.respectTransparency false in theorem destruct_eq_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {ms : Multiseries basis_hd basis_tl} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} {tl : Multiseries basis_hd basis_tl} (h : destruct ms = some (exp, coef, tl)) : ms = cons exp coef tl := by @@ -412,6 +419,7 @@ theorem head_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} : (nil : Multiseries basis_hd basis_tl).head = none := by simp [head, nil] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem head_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} @@ -419,11 +427,13 @@ theorem head_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ} (cons exp coef tl).head = some (exp, coef) := by simp [head, cons] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem tail_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} : (nil : Multiseries basis_hd basis_tl).tail = nil := by simp [tail, nil] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem tail_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} @@ -431,12 +441,14 @@ theorem tail_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ} (cons exp coef tl).tail = tl := by simp [tail, cons] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_nil {basis_hd basis_tl basis_hd' basis_tl'} (f : ℝ → ℝ) (g : MultiseriesExpansion basis_tl → MultiseriesExpansion basis_tl') : (nil : Multiseries basis_hd basis_tl).map f g = (nil : Multiseries basis_hd' basis_tl') := by simp [map, nil] +set_option backward.isDefEq.respectTransparency false in @[simp] theorem map_cons {basis_hd basis_tl basis_hd' basis_tl'} (f : ℝ → ℝ) (g : MultiseriesExpansion basis_tl → MultiseriesExpansion basis_tl') {exp : ℝ} @@ -450,6 +462,7 @@ theorem map_id {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) : ms.map (fun exp => exp) (fun coef => coef) = ms := Stream'.Seq.map_id ms +set_option backward.isDefEq.respectTransparency false in @[simp← ] theorem map_comp {b₁ b₂ b₃ bs₁ bs₂ bs₃} (f₁ : ℝ → ℝ) (g₁ : MultiseriesExpansion bs₁ → MultiseriesExpansion bs₂) @@ -699,6 +712,7 @@ theorem cons {basis_hd basis_tl} {exp : ℝ} {coef : MultiseriesExpansion basis_ · exact Seq.Pairwise_cons_nil · exact h_tl_tl.cons_cons_of_trans (by simpa [lt_iff_lt] using h_comp) +set_option backward.isDefEq.respectTransparency.types false in /-- If `cons (exp, coef) tl` is `Sorted`, then `coef` and `tl` are `Sorted`, and the leading exponent of `tl` is less than `exp`. -/ theorem elim_cons {basis_hd basis_tl} {exp : ℝ} {coef : MultiseriesExpansion basis_tl} diff --git a/Mathlib/Tactic/Core.lean b/Mathlib/Tactic/Core.lean index b7b23ce9152bfa..8a457013934b06 100644 --- a/Mathlib/Tactic/Core.lean +++ b/Mathlib/Tactic/Core.lean @@ -33,9 +33,9 @@ def toModifiers (nm : Name) (newDoc : Option (TSyntax `Lean.Parser.Command.docCo let env ← getEnv let d ← getConstInfo nm let mods : Modifiers := - { docString? := newDoc.map (·, doc.verso.get (← getOptions)) + { docString? := newDoc visibility := - if isPrivateNameExport nm then + if isPrivateName nm then Visibility.private else Visibility.regular diff --git a/Mathlib/Tactic/FieldSimp.lean b/Mathlib/Tactic/FieldSimp.lean index 9ca4f39b9d0c0a..9622a688c192e9 100644 --- a/Mathlib/Tactic/FieldSimp.lean +++ b/Mathlib/Tactic/FieldSimp.lean @@ -124,6 +124,7 @@ def split (iM : Q(CommGroupWithZero $M)) (l : qNF M) : let r' : ℤ := -r return ⟨t_n, ((r', x), i) :: t_d, (q(NF.cons_eq_div_of_eq_div' $r' $x $pf):)⟩ +set_option backward.isDefEq.respectTransparency false in private def evalPrettyAux (iM : Q(CommGroupWithZero $M)) (l : qNF M) : MetaM (Σ e : Q($M), Q(NF.eval $(l.toNF) = $e)) := match l with diff --git a/Mathlib/Tactic/FieldSimp/Lemmas.lean b/Mathlib/Tactic/FieldSimp/Lemmas.lean index e08407c14b8dfa..a3e0d577a011d8 100644 --- a/Mathlib/Tactic/FieldSimp/Lemmas.lean +++ b/Mathlib/Tactic/FieldSimp/Lemmas.lean @@ -201,6 +201,7 @@ the corresponding `ℤ` term, then multiply them all together. -/ noncomputable def eval [GroupWithZero M] (l : NF M) : M := (l.map (fun (⟨r, x⟩ : ℤ × M) ↦ zpow' x r)).prod +set_option backward.isDefEq.respectTransparency false in @[simp] theorem eval_cons [CommGroupWithZero M] (p : ℤ × M) (l : NF M) : (p ::ᵣ l).eval = l.eval * zpow' p.2 p.1 := by unfold eval cons @@ -314,6 +315,7 @@ theorem cons_zero_eq_div_of_eq_div [CommGroupWithZero M] (e : M) {t t_n t_d : NF instance : Inv (NF M) where inv l := l.map fun (a, x) ↦ (-a, x) +set_option backward.isDefEq.respectTransparency false in theorem eval_inv [CommGroupWithZero M] (l : NF M) : (l⁻¹).eval = l.eval⁻¹ := by simp +instances only [NF.eval, List.map_map, NF.instInv, List.prod_inv] congr! 2 @@ -332,6 +334,7 @@ instance : Pow (NF M) ℤ where @[simp] theorem zpow_apply (r : ℤ) (l : NF M) : l ^ r = l.map fun (a, x) ↦ (r * a, x) := rfl +set_option backward.isDefEq.respectTransparency false in theorem eval_zpow' [CommGroupWithZero M] (l : NF M) (r : ℤ) : (l ^ r).eval = zpow' l.eval r := by unfold NF.eval at ⊢ diff --git a/Mathlib/Tactic/HigherOrder.lean b/Mathlib/Tactic/HigherOrder.lean index b3c031166f20fb..4cc2a51b82ae21 100644 --- a/Mathlib/Tactic/HigherOrder.lean +++ b/Mathlib/Tactic/HigherOrder.lean @@ -32,7 +32,7 @@ syntax (name := higherOrder) "higher_order" (ppSpace ident)? : attr end Lean.Parser.Attr -namespace Tactic +namespace Mathlib.Tactic /-- `mkComp v e` checks whether `e` is a sequence of nested applications `f (g (h v))`, and if so, returns the expression `f ∘ g ∘ h`. If `e = v` it returns `id`. -/ @@ -124,4 +124,4 @@ Syntax: `[higher_order]` or `[higher_order name]`, where the given name is used generated theorem.", getParam := higherOrderGetParam } -end Tactic +end Mathlib.Tactic diff --git a/Mathlib/Tactic/Inhabit.lean b/Mathlib/Tactic/Inhabit.lean index 4fcfbe7af2d1b0..0e3a5d77b7ee38 100644 --- a/Mathlib/Tactic/Inhabit.lean +++ b/Mathlib/Tactic/Inhabit.lean @@ -20,13 +20,13 @@ open Lean.Meta namespace Lean.Elab.Tactic /-- Derives `Inhabited α` from `Nonempty α` with `Classical.choice`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def nonempty_to_inhabited (α : Sort*) (_ : Nonempty α) : Inhabited α := Inhabited.mk (Classical.ofNonempty) /-- Derives `Inhabited α` from `Nonempty α` without `Classical.choice` assuming `α` is of type `Prop`. -/ -@[implicit_reducible] +@[instance_reducible] def nonempty_prop_to_inhabited (α : Prop) (α_nonempty : Nonempty α) : Inhabited α := Inhabited.mk <| Nonempty.elim α_nonempty id diff --git a/Mathlib/Tactic/Module.lean b/Mathlib/Tactic/Module.lean index b894df41611c37..c894df925e9394 100644 --- a/Mathlib/Tactic/Module.lean +++ b/Mathlib/Tactic/Module.lean @@ -138,6 +138,7 @@ theorem sub_eq_eval {R₁ R₂ S₁ S₂ : Type*} [AddCommGroup M] [Ring R] [Mod instance [Neg R] : Neg (NF R M) where neg l := l.map fun (a, x) ↦ (-a, x) +set_option backward.isDefEq.respectTransparency false in theorem eval_neg [AddCommGroup M] [Ring R] [Module R M] (l : NF R M) : (-l).eval = - l.eval := by simp +instances only [NF.eval, List.map_map, List.sum_neg, NF.instNeg] congr @@ -159,6 +160,7 @@ instance [Mul R] : SMul R (NF R M) where @[simp] theorem smul_apply [Mul R] (r : R) (l : NF R M) : r • l = l.map fun (a, x) ↦ (r * a, x) := rfl +set_option backward.isDefEq.respectTransparency false in theorem eval_smul [AddCommMonoid M] [Semiring R] [Module R M] {l : NF R M} {x : M} (h : x = l.eval) (r : R) : (r • l).eval = r • x := by unfold NF.eval at h ⊢ @@ -204,6 +206,7 @@ commutative semiring, by applying to each `S`-component the algebra-map from `S` def algebraMap [CommSemiring S] [Semiring R] [Algebra S R] (l : NF S M) : NF R M := l.map (fun ⟨s, x⟩ ↦ (Algebra.algebraMap S R s, x)) +set_option backward.isDefEq.respectTransparency false in theorem eval_algebraMap [CommSemiring S] [Semiring R] [Algebra S R] [AddMonoid M] [SMul S M] [MulAction R M] [IsScalarTower S R M] (l : NF S M) : (l.algebraMap R).eval = l.eval := by @@ -254,6 +257,7 @@ def onScalar {u₁ u₂ : Level} {R₁ : Q(Type u₁)} {R₂ : Q(Type u₂)} (l qNF R₂ M := l.map fun ((a, x), k) ↦ ((q($f $a), x), k) +set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), construct another such term `l`, which will have the property that in the `$R`-module `$M`, the sum of the "linear combinations" represented by `l₁` and `l₂` is the linear @@ -277,6 +281,7 @@ meta def add (iR : Q(Semiring $R)) : qNF R M → qNF R M → qNF R M else ((a₂, x₂), k₂) ::ᵣ add iR (((a₁, x₁), k₁) ::ᵣ t₁) t₂ +set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), recursively construct a proof that in the `$R`-module `$M`, the sum of the "linear combinations" represented by `l₁` and `l₂` is the linear combination represented by @@ -298,6 +303,7 @@ meta def mkAddProof {iR : Q(Semiring $R)} {iM : Q(AddCommMonoid $M)} (iRM : Q(Mo let pf := mkAddProof iRM (((a₁, x₁), k₁) ::ᵣ t₁) t₂ (q(NF.add_eq_eval₃ ($a₂, $x₂) $pf):) +set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), construct another such term `l`, which will have the property that in the `$R`-module `$M`, the difference of the "linear combinations" represented by `l₁` and `l₂` is the @@ -322,6 +328,7 @@ def sub (iR : Q(Ring $R)) : qNF R M → qNF R M → qNF R M else ((q(-$a₂), x₂), k₂) ::ᵣ sub iR (((a₁, x₁), k₁) ::ᵣ t₁) t₂ +set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), recursively construct a proof that in the `$R`-module `$M`, the difference of the "linear combinations" represented by `l₁` and `l₂` is the linear combination represented by diff --git a/Mathlib/Tactic/NormNum/Basic.lean b/Mathlib/Tactic/NormNum/Basic.lean index 46aa1041bbda80..75d94adc7e7ec4 100644 --- a/Mathlib/Tactic/NormNum/Basic.lean +++ b/Mathlib/Tactic/NormNum/Basic.lean @@ -32,7 +32,7 @@ universe u namespace Mathlib.Meta.NormNum /-- If `b` divides `a` and `a` is invertible, then `b` is invertible. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfMul {α} [Semiring α] (k : ℕ) (b : α) : ∀ (a : α) [Invertible a], a = k * b → Invertible b | _, ⟨c, hc1, hc2⟩, rfl => by @@ -41,7 +41,7 @@ def invertibleOfMul {α} [Semiring α] (k : ℕ) (b : α) : exact ⟨_, hc1, hc2⟩ /-- If `b` divides `a` and `a` is invertible, then `b` is invertible. -/ -@[implicit_reducible] +@[instance_reducible] def invertibleOfMul' {α} [Semiring α] {a k b : ℕ} [Invertible (a : α)] (h : a = k * b) : Invertible (b : α) := invertibleOfMul k (b:α) ↑a (by simp [h]) diff --git a/Mathlib/Tactic/NormNum/GCD.lean b/Mathlib/Tactic/NormNum/GCD.lean index 6d4a00ef67479c..775e91c7b5263a 100644 --- a/Mathlib/Tactic/NormNum/GCD.lean +++ b/Mathlib/Tactic/NormNum/GCD.lean @@ -20,7 +20,7 @@ also indirectly provides a `Nat.coprime` extension. public meta section -namespace Tactic +namespace Mathlib.Meta namespace NormNum @@ -252,4 +252,4 @@ def evalRatDen : NormNumExt where eval {u α} e := do end NormNum -end Tactic +end Mathlib.Meta diff --git a/Mathlib/Tactic/NormNum/Irrational.lean b/Mathlib/Tactic/NormNum/Irrational.lean index e062206ec53c36..e7f8110fa17a6c 100644 --- a/Mathlib/Tactic/NormNum/Irrational.lean +++ b/Mathlib/Tactic/NormNum/Irrational.lean @@ -30,7 +30,7 @@ Disprove `Irrational x` for rational `x`. public meta section -namespace Tactic +namespace Mathlib.Meta namespace NormNum @@ -321,4 +321,4 @@ def evalIrrationalSqrt : NormNumExt where eval {u α} e := do end NormNum -end Tactic +end Mathlib.Meta diff --git a/Mathlib/Tactic/NormNum/IsCoprime.lean b/Mathlib/Tactic/NormNum/IsCoprime.lean index 9bc49945c0696f..fce37c606115d1 100644 --- a/Mathlib/Tactic/NormNum/IsCoprime.lean +++ b/Mathlib/Tactic/NormNum/IsCoprime.lean @@ -18,7 +18,7 @@ it does not correspond to the usual notion of coprime.) public meta section -namespace Tactic +namespace Mathlib.Meta namespace NormNum @@ -64,4 +64,4 @@ def evalIntIsCoprime : NormNumExt where eval {_ _} e := do end NormNum -end Tactic +end Mathlib.Meta diff --git a/Mathlib/Tactic/NormNum/IsSquare.lean b/Mathlib/Tactic/NormNum/IsSquare.lean index 0f08159078c651..b550e8c2c5bae3 100644 --- a/Mathlib/Tactic/NormNum/IsSquare.lean +++ b/Mathlib/Tactic/NormNum/IsSquare.lean @@ -166,12 +166,12 @@ def evalIsSquareRat : NormNumExt where eval {u αP} e := do assertInstancesCommute return .isTrue q(isSquare_of_isNNRat_rat $a $n $d $pn $pd $pa) | .mk false pd => - let ⟨e, he⟩ := Tactic.NormNum.proveNatGCD n d + let ⟨e, he⟩ := proveNatGCD n d have : $e =Q 1 := ⟨⟩ assertInstancesCommute return .isFalse q(not_isSquare_of_isNNRat_rat_of_den $a $n $d $pd $he $pa) | .mk false pn => - let ⟨e, he⟩ := Tactic.NormNum.proveNatGCD n d + let ⟨e, he⟩ := proveNatGCD n d have : $e =Q 1 := ⟨⟩ assertInstancesCommute return .isFalse q(not_isSquare_of_isNNRat_rat_of_num $a $n $d $pn $he $pa) diff --git a/Mathlib/Tactic/NormNum/NatSqrt.lean b/Mathlib/Tactic/NormNum/NatSqrt.lean index ef7ffff4f106d8..5cfe82e272ba61 100644 --- a/Mathlib/Tactic/NormNum/NatSqrt.lean +++ b/Mathlib/Tactic/NormNum/NatSqrt.lean @@ -15,7 +15,7 @@ This module defines a `norm_num` extension for `Nat.sqrt`. public meta section -namespace Tactic +namespace Mathlib.Meta namespace NormNum @@ -56,4 +56,4 @@ def evalNatSqrt : NormNumExt where eval {_ _} e := do end NormNum -end Tactic +end Mathlib.Meta diff --git a/Mathlib/Tactic/NormNum/RealSqrt.lean b/Mathlib/Tactic/NormNum/RealSqrt.lean index f48713f0fd7268..31b68f01548c6c 100644 --- a/Mathlib/Tactic/NormNum/RealSqrt.lean +++ b/Mathlib/Tactic/NormNum/RealSqrt.lean @@ -14,7 +14,7 @@ This module defines a `norm_num` extension for `Real.sqrt` and `NNReal.sqrt`. public meta section -namespace Tactic.NormNum +namespace Mathlib.Meta.NormNum open Qq Lean Lean.Meta Elab.Tactic Mathlib.Meta.NormNum NNReal @@ -124,4 +124,4 @@ def evalNNRealSqrt : NormNumExt where eval {u α} e := do | .isNegNNRat sℝ eq en ed pf => failure | _ => failure -end Tactic.NormNum +end Mathlib.Meta.NormNum diff --git a/Mathlib/Tactic/NormNum/Result.lean b/Mathlib/Tactic/NormNum/Result.lean index 94783351d36226..8583027f5b8b9d 100644 --- a/Mathlib/Tactic/NormNum/Result.lean +++ b/Mathlib/Tactic/NormNum/Result.lean @@ -41,11 +41,11 @@ variable {u : Level} /-- A shortcut (non)instance for `AddMonoidWithOne α` from `Semiring α` to shrink generated proofs. -/ -@[implicit_reducible] +@[instance_reducible] def instAddMonoidWithOne' {α : Type u} [Semiring α] : AddMonoidWithOne α := inferInstance /-- A shortcut (non)instance for `AddMonoidWithOne α` from `Ring α` to shrink generated proofs. -/ -@[implicit_reducible] +@[instance_reducible] def instAddMonoidWithOne {α : Type u} [Ring α] : AddMonoidWithOne α := inferInstance /-- A shortcut (non)instance for `Nat.AtLeastTwo (n + 2)` to shrink generated proofs. -/ diff --git a/Mathlib/Tactic/PNatToNat.lean b/Mathlib/Tactic/PNatToNat.lean index 2d53a471c69325..c4576d1f2c99b4 100644 --- a/Mathlib/Tactic/PNatToNat.lean +++ b/Mathlib/Tactic/PNatToNat.lean @@ -57,6 +57,7 @@ lemma coe_lt_coe (m n : PNat) : m < n ↔ (m : ℕ) < (n : ℕ) := by simp attribute [pnat_to_nat_coe] PNat.add_coe PNat.mul_coe PNat.val_ofNat +set_option backward.isDefEq.respectTransparency false in @[pnat_to_nat_coe] lemma sub_coe (a b : PNat) : ((a - b : PNat) : Nat) = a.val - 1 - b.val + 1 := by cases a diff --git a/Mathlib/Tactic/Ring/RingNF.lean b/Mathlib/Tactic/Ring/RingNF.lean index 6ad2ceb6605583..6d3bbcb1fb6446 100644 --- a/Mathlib/Tactic/Ring/RingNF.lean +++ b/Mathlib/Tactic/Ring/RingNF.lean @@ -26,7 +26,7 @@ namespace Mathlib.Tactic open Lean Meta Qq namespace RingNF -open Ring +open Mathlib.Tactic.Ring /-- The normalization style for `ring_nf`. -/ inductive RingMode where diff --git a/Mathlib/Tactic/Simproc/Divisors.lean b/Mathlib/Tactic/Simproc/Divisors.lean index 5259b06d9c77a9..0b4cfcdeabcbec 100644 --- a/Mathlib/Tactic/Simproc/Divisors.lean +++ b/Mathlib/Tactic/Simproc/Divisors.lean @@ -25,13 +25,13 @@ open Lean Meta Simp Qq numeral. For instance, this simplifies `Nat.divisors 6` to `{1, 2, 3, 6}`. -/ dsimproc_decl Nat.divisors_ofNat (Nat.divisors _) := fun e => do unless e.isAppOfArity `Nat.divisors 1 do return .continue - let some n ← fromExpr? e.appArg! | return .continue + let some n ← Lean.Nat.fromExpr? e.appArg! | return .continue return .done <| mkSetLiteralQ q(Finset ℕ) <| ((unsafe n.divisors.val.unquot).map mkNatLit) /-- The dsimproc `Nat.properDivisors_ofNat` computes the finset `Nat.properDivisors n` when `n` is a numeral. For instance, this simplifies `Nat.properDivisors 12` to `{1, 2, 3, 4, 6}`. -/ dsimproc_decl Nat.properDivisors_ofNat (Nat.properDivisors _) := fun e => do unless e.isAppOfArity `Nat.properDivisors 1 do return .continue - let some n ← fromExpr? e.appArg! | return .continue + let some n ← Lean.Nat.fromExpr? e.appArg! | return .continue return unsafe .done <| mkSetLiteralQ q(Finset ℕ) <| ((unsafe n.properDivisors.val.unquot).map mkNatLit) diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 91bd1091d93821..88d658e5cd3084 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -1022,6 +1022,7 @@ def addProjection (declName : Name) (type lhs rhs : Expr) (args : Array Expr) throwError "simps tried to add lemma{indentD m!"{.ofConstName declName} : {declType}"}\n\ to the environment, but it already exists." trace[simps.verbose] "adding projection {declName}:{indentExpr declType}" + Mathlib.Tactic.warnIfImplicitIllTyped ref declName declType prependError "Failed to add projection lemma {declName}:" do addDecl <| .thmDecl { name := declName diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 01dc430c3cb060..2c7b61fedf3d9f 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -864,9 +864,11 @@ partial def transformDeclRec (t : TranslateData) (cfg : Config) (rootSrc rootTgt def copyInstanceAttribute (src tgt : Name) : CoreM Unit := do if let some prio ← getInstancePriority? src then let attr_kind := (← getInstanceAttrKind? src).getD .global - -- Copy implicit_reducible status before adding instance attribute - if (← getReducibilityStatus src) matches .implicitReducible then - setReducibilityStatus tgt .implicitReducible + -- Copy `instance_reducible` / `instance_reducible` status before adding instance attribute + match (← getReducibilityStatus src) with + | .implicitReducible => setReducibilityStatus tgt .implicitReducible + | .instanceReducible => setReducibilityStatus tgt .instanceReducible + | _ => pure () trace[translate_detail] "Making {tgt} an instance with priority {prio}." addInstance tgt attr_kind prio |>.run' diff --git a/Mathlib/Testing/Plausible/Functions.lean b/Mathlib/Testing/Plausible/Functions.lean index 0362f865d835e6..dea6b1649d102f 100644 --- a/Mathlib/Testing/Plausible/Functions.lean +++ b/Mathlib/Testing/Plausible/Functions.lean @@ -189,9 +189,6 @@ theorem List.applyId_cons [DecidableEq α] (xs : List (α × α)) (x y z : α) : split_ifs <;> rfl open Function -open List - -open Nat theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs[i]? = some x) : @@ -230,7 +227,9 @@ theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs | cons x' xs xs_ih => rcases ys with - | ⟨y, ys⟩ · cases h₃ - dsimp [List.dlookup] at h₃; split_ifs at h₃ with h + simp only [zip_cons_cons, map_cons, Prod.toSigma_mk, dlookup, eq_rec_constant, + dite_eq_ite] at h₃ + split_ifs at h₃ with h · rw [Option.some_inj] at h₃ subst x'; subst val simp only [List.mem_cons, true_or] diff --git a/Mathlib/Topology/Algebra/Affine.lean b/Mathlib/Topology/Algebra/Affine.lean index 34a060b940d312..ba956772db9ebb 100644 --- a/Mathlib/Topology/Algebra/Affine.lean +++ b/Mathlib/Topology/Algebra/Affine.lean @@ -55,6 +55,7 @@ theorem isOpenMap_linear_iff {f : P →ᵃ[R] Q} : IsOpenMap f.linear ↔ IsOpen variable [TopologicalSpace R] [ContinuousSMul R V] +set_option backward.isDefEq.respectTransparency false in /-- The line map is continuous in all arguments. -/ @[continuity, fun_prop] theorem lineMap_continuous_uncurry : @@ -73,6 +74,7 @@ section Tendsto variable {α : Type*} {l : Filter α} +set_option backward.isDefEq.respectTransparency false in theorem _root_.Filter.Tendsto.lineMap {f₁ f₂ : α → P} {g : α → R} {p₁ p₂ : P} {c : R} (h₁ : Tendsto f₁ l (𝓝 p₁)) (h₂ : Tendsto f₂ l (𝓝 p₂)) (hg : Tendsto g l (𝓝 c)) : Tendsto (fun x => AffineMap.lineMap (f₁ x) (f₂ x) (g x)) l (𝓝 <| AffineMap.lineMap p₁ p₂ c) := @@ -87,22 +89,26 @@ end Tendsto variable {X : Type*} [TopologicalSpace X] {f₁ f₂ : X → P} {g : X → R} {s : Set X} {x : X} +set_option backward.isDefEq.respectTransparency false in @[fun_prop] theorem _root_.ContinuousWithinAt.lineMap (h₁ : ContinuousWithinAt f₁ s x) (h₂ : ContinuousWithinAt f₂ s x) (hg : ContinuousWithinAt g s x) : ContinuousWithinAt (fun x ↦ lineMap (f₁ x) (f₂ x) (g x)) s x := Tendsto.lineMap h₁ h₂ hg +set_option backward.isDefEq.respectTransparency false in theorem _root_.ContinuousAt.lineMap (h₁ : ContinuousAt f₁ x) (h₂ : ContinuousAt f₂ x) (hg : ContinuousAt g x) : ContinuousAt (fun x ↦ lineMap (f₁ x) (f₂ x) (g x)) x := by fun_prop +set_option backward.isDefEq.respectTransparency false in theorem _root_.ContinuousOn.lineMap (h₁ : ContinuousOn f₁ s) (h₂ : ContinuousOn f₂ s) (hg : ContinuousOn g s) : ContinuousOn (fun x ↦ lineMap (f₁ x) (f₂ x) (g x)) s := by fun_prop +set_option backward.isDefEq.respectTransparency false in theorem _root_.Continuous.lineMap (h₁ : Continuous f₁) (h₂ : Continuous f₂) (hg : Continuous g) : Continuous (fun x ↦ lineMap (f₁ x) (f₂ x) (g x)) := by diff --git a/Mathlib/Topology/Algebra/AffineSubspace.lean b/Mathlib/Topology/Algebra/AffineSubspace.lean index dc38b016cd6fdb..13729236824ec7 100644 --- a/Mathlib/Topology/Algebra/AffineSubspace.lean +++ b/Mathlib/Topology/Algebra/AffineSubspace.lean @@ -100,6 +100,7 @@ instance {s : AffineSubspace R P} [Nonempty s] : IsTopologicalAddTorsor s where rw [Topology.IsEmbedding.subtypeVal.continuous_iff] fun_prop +set_option backward.isDefEq.respectTransparency false in theorem isClosed_direction_iff [T1Space V] (s : AffineSubspace R P) : IsClosed (s.direction : Set V) ↔ IsClosed (s : Set P) := by rcases s.eq_bot_or_nonempty with (rfl | ⟨x, hx⟩); · simp diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean index d56ec3594c15ff..ae5b2fdd25f03e 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Completion.lean @@ -163,6 +163,7 @@ def lift (f : G ⟶ GrpCat.of P) : completion G ⟶ P := exact this }⟩ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma lift_eta (f : G ⟶ GrpCat.of P) : eta G ≫ (forget₂ _ _).map (lift f) = f := by diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean index e05a25f8247f72..e236cc3e97cd77 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean @@ -152,6 +152,7 @@ noncomputable def isoLimittoFiniteQuotientFunctor (P : ProfiniteGrp.{u}) : P ≅ (limit <| diagram P) := ContinuousMulEquiv.toProfiniteGrpIso (continuousMulEquivLimittoFiniteQuotientFunctor P) +set_option backward.isDefEq.respectTransparency.types false in /-- The projection from `P` to the quotient by an open normal subgroup. -/ @[to_additive /-- The projection from `P` to the quotient by an open normal subgroup. -/] def proj {P : ProfiniteGrp.{u}} (U : OpenNormalSubgroup P) : P ⟶ (diagram P).obj U := @@ -163,12 +164,14 @@ def proj {P : ProfiniteGrp.{u}} (U : OpenNormalSubgroup P) : P ⟶ (diagram P).o fun_prop } +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical cone over `diagram P` with point `P`. -/ @[to_additive (attr := simps) /-- The canonical cone over `diagram P` with point `P`. -/] def cone (P : ProfiniteGrp.{u}) : Limits.Cone (diagram P) where pt := P π := { app := proj } +set_option backward.isDefEq.respectTransparency.types false in /-- The canonical cone over `diagram P` is a limit cone. -/ noncomputable def isLimitCone (P : ProfiniteGrp.{u}) : Limits.IsLimit P.cone := Limits.IsLimit.ofIsoLimit (limitConeIsLimit _) <| .symm <| diff --git a/Mathlib/Topology/Algebra/ContinuousAffineMap.lean b/Mathlib/Topology/Algebra/ContinuousAffineMap.lean index 10e1a5f31ba0f2..f7885d863aba47 100644 --- a/Mathlib/Topology/Algebra/ContinuousAffineMap.lean +++ b/Mathlib/Topology/Algebra/ContinuousAffineMap.lean @@ -149,6 +149,7 @@ theorem comp_id (f : P →ᴬ[R] Q) : f.comp (id R P) = f := theorem id_comp (f : P →ᴬ[R] Q) : (id R Q).comp f = f := ext fun _ => rfl +set_option backward.isDefEq.respectTransparency false in /-- Applying a `ContinuousAffineMap` commutes with `AffineMap.lineMap`. -/ @[simp] theorem apply_lineMap (f : P →ᴬ[R] Q) (p₀ p₁ : P) (c : R) : @@ -165,10 +166,12 @@ def lineMap (p₀ p₁ : P) [TopologicalSpace R] [TopologicalSpace V] [ContinuousSMul R V] [ContinuousVAdd V P] : (lineMap p₀ p₁).toAffineMap = AffineMap.lineMap (k := R) p₀ p₁ := rfl +set_option backward.isDefEq.respectTransparency false in lemma coe_lineMap_eq (p₀ p₁ : P) [TopologicalSpace R] [TopologicalSpace V] [ContinuousSMul R V] [ContinuousVAdd V P] : ⇑(ContinuousAffineMap.lineMap p₀ p₁) = ⇑(AffineMap.lineMap (k := R) p₀ p₁) := rfl +set_option backward.isDefEq.respectTransparency false in /-- Applying a `ContinuousAffineMap` commutes with `ContinuousAffineMap.lineMap`. -/ @[simp] theorem apply_lineMap' [TopologicalSpace R] [TopologicalSpace V] [TopologicalSpace W] @@ -367,6 +370,7 @@ instance : AddTorsor (P →ᴬ[R] W) (P →ᴬ[R] Q) where (f -ᵥ g).toAffineMap = f.toAffineMap -ᵥ g.toAffineMap := rfl +set_option backward.isDefEq.respectTransparency false in /-- Interpolating between `ContinuousAffineMap`s with `AffineMap.lineMap` commutes with evaluation. -/ @[simp] @@ -516,6 +520,7 @@ theorem decompEquiv_symm_apply (p : Q × (V →L[R] W)) (x : V) : (decompEquiv R V Q).symm p x = p.2 x +ᵥ p.1 := rfl +set_option backward.isDefEq.respectTransparency false in @[simp] theorem decompEquiv_symm_contLinear (p : Q × (V →L[R] W)) : ((decompEquiv R V Q).symm p).contLinear = p.2 := by @@ -551,6 +556,7 @@ theorem decompLinearEquiv_symm_apply (p : W × (V →L[R] W)) (x : V) : (decompLinearEquiv R S V W).symm p x = p.2 x + p.1 := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem decompLinearEquiv_symm_contLinear (p : W × (V →L[R] W)) : ((decompLinearEquiv R S V W).symm p).contLinear = p.2 := by diff --git a/Mathlib/Topology/Algebra/Field.lean b/Mathlib/Topology/Algebra/Field.lean index e059ae0495eff6..d845ce19acadad 100644 --- a/Mathlib/Topology/Algebra/Field.lean +++ b/Mathlib/Topology/Algebra/Field.lean @@ -125,24 +125,28 @@ def affineHomeomorph (a b : 𝕜) (h : a ≠ 0) : 𝕜 ≃ₜ 𝕜 where exact mul_div_cancel_left₀ x h right_inv y := by simp [mul_div_cancel₀ _ h] +set_option backward.isDefEq.respectTransparency false in theorem affineHomeomorph_image_Icc {𝕜 : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] [TopologicalSpace 𝕜] [IsTopologicalRing 𝕜] (a b c d : 𝕜) (h : 0 < a) : affineHomeomorph a b h.ne' '' Set.Icc c d = Set.Icc (a * c + b) (a * d + b) := by simp [h] +set_option backward.isDefEq.respectTransparency false in theorem affineHomeomorph_image_Ico {𝕜 : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] [TopologicalSpace 𝕜] [IsTopologicalRing 𝕜] (a b c d : 𝕜) (h : 0 < a) : affineHomeomorph a b h.ne' '' Set.Ico c d = Set.Ico (a * c + b) (a * d + b) := by simp [h] +set_option backward.isDefEq.respectTransparency false in theorem affineHomeomorph_image_Ioc {𝕜 : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] [TopologicalSpace 𝕜] [IsTopologicalRing 𝕜] (a b c d : 𝕜) (h : 0 < a) : affineHomeomorph a b h.ne' '' Set.Ioc c d = Set.Ioc (a * c + b) (a * d + b) := by simp [h] +set_option backward.isDefEq.respectTransparency false in theorem affineHomeomorph_image_Ioo {𝕜 : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] [TopologicalSpace 𝕜] [IsTopologicalRing 𝕜] (a b c d : 𝕜) (h : 0 < a) : diff --git a/Mathlib/Topology/Algebra/FilterBasis.lean b/Mathlib/Topology/Algebra/FilterBasis.lean index 15d529335c60eb..83aeebd4e50250 100644 --- a/Mathlib/Topology/Algebra/FilterBasis.lean +++ b/Mathlib/Topology/Algebra/FilterBasis.lean @@ -67,7 +67,7 @@ class AddGroupFilterBasis (A : Type u) [AddGroup A] extends FilterBasis A where attribute [to_additive] GroupFilterBasis /-- `GroupFilterBasis` constructor in the commutative group case. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- `AddGroupFilterBasis` constructor in the additive commutative group case. -/] def groupFilterBasisOfComm {G : Type*} [CommGroup G] (sets : Set (Set G)) (nonempty : sets.Nonempty) (inter_sets : ∀ x y, x ∈ sets → y ∈ sets → ∃ z ∈ sets, z ⊆ x ∩ y) @@ -138,7 +138,7 @@ protected theorem hasBasis (B : GroupFilterBasis G) (x : G) : HasBasis.map (fun y ↦ x * y) toFilterBasis.hasBasis /-- The topological space structure coming from a group filter basis. -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The topological space structure coming from an additive group filter basis. -/] def topology (B : GroupFilterBasis G) : TopologicalSpace G := TopologicalSpace.mkOfNhds B.N @@ -255,7 +255,7 @@ theorem mul_right (x₀ : R) {U : Set R} (hU : U ∈ B) : ∃ V ∈ B, V ⊆ (fu /-- The topology associated to a ring filter basis. It has the given basis as a basis of neighborhoods of zero. -/ -@[implicit_reducible] +@[instance_reducible] def topology : TopologicalSpace R := B.toAddGroupFilterBasis.topology @@ -337,14 +337,14 @@ instance [DiscreteTopology R] : Inhabited (ModuleFilterBasis R M) := /-- The topology associated to a module filter basis on a module over a topological ring. It has the given basis as a basis of neighborhoods of zero. -/ -@[implicit_reducible] +@[instance_reducible] def topology : TopologicalSpace M := B.toAddGroupFilterBasis.topology /-- The topology associated to a module filter basis on a module over a topological ring. It has the given basis as a basis of neighborhoods of zero. This version gets the ring topology by unification instead of type class inference. -/ -@[implicit_reducible] +@[instance_reducible] def topology' {R M : Type*} [CommRing R] {_ : TopologicalSpace R} [AddCommGroup M] [Module R M] (B : ModuleFilterBasis R M) : TopologicalSpace M := B.toAddGroupFilterBasis.topology diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index c2f23ff8472ca4..e29ceff425043b 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -136,6 +136,7 @@ protected theorem Set.Finite.multipliable {s : Set β} (hs : s.Finite) (f : β have := hs.toFinset.multipliable f rwa [hs.coe_toFinset] at this +set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem multipliable_of_hasFiniteMulSupport [L.HasSupport] (h : HasFiniteMulSupport f) : Multipliable f L := by diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean index 71666b3b22310f..e9c50bd7a3ace2 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean @@ -269,6 +269,7 @@ theorem Finset.hasProd_support (s : Finset β) (f : β → α) (L := uncondition (∏ b ∈ (L.support.toFinset.map <| Embedding.subtype _), f b) L := by simpa [prod_attach] using hasProd_fintype_support (f ∘ Subtype.val) L +set_option backward.isDefEq.respectTransparency false in -- note this is not deduced from `Finset.hasProd_support` to avoid needing `[DecidableEq β]` @[to_additive] protected theorem Finset.hasProd (s : Finset β) (f : β → α) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean index d039ee2321fa1c..5f707e92f90dd6 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean @@ -446,6 +446,7 @@ protected lemma Multipliable.tsum_congr_cofinite₀ [T2Space K] (hc : Multipliab ∏' i, g i = ((∏' i, f i) * ((∏ i ∈ s, g i) / ∏ i ∈ s, f i)) := (hc.hasProd.congr_cofinite₀ hs hs').tprod_eq +set_option backward.isDefEq.respectTransparency false in /-- See also `Multipliable.congr_cofinite`, which does not have a non-vanishing condition, but instead requires the target to be a group under multiplication (and hence fails for infinite products in a diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Nonarchimedean.lean b/Mathlib/Topology/Algebra/InfiniteSum/Nonarchimedean.lean index 24e498da9d49b4..e90641dd9b70c1 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Nonarchimedean.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Nonarchimedean.lean @@ -34,6 +34,7 @@ namespace NonarchimedeanGroup variable {α G : Type*} variable [CommGroup G] [UniformSpace G] [IsUniformGroup G] [NonarchimedeanGroup G] +set_option backward.isDefEq.respectTransparency false in /-- Let `G` be a nonarchimedean multiplicative abelian group, and let `f : α → G` be a function that tends to one on the filter of cofinite sets. For each finite subset of `α`, consider the partial product of `f` on that subset. These partial products form a Cauchy filter. -/ diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean index 7a8ba9da15ddd5..6ef4e005cf55a1 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean @@ -596,7 +596,7 @@ Warning: in general the right and left uniformities do not coincide and so one d `IsUniformGroup` structure. Two important special cases where they _do_ coincide are for commutative groups (see `isUniformGroup_of_commGroup`) and for compact groups (see `IsUniformGroup.of_compactSpace`). -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The right uniformity on a topological additive group (as opposed to the left uniformity). @@ -639,7 +639,7 @@ Warning: in general the right and left uniformities do not coincide and so one d `IsUniformGroup` structure. Two important special cases where they _do_ coincide are for commutative groups (see `isUniformGroup_of_commGroup`) and for compact groups (see `IsUniformGroup.of_compactSpace`). -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The left uniformity on a topological additive group (as opposed to the right uniformity). diff --git a/Mathlib/Topology/Algebra/LinearMapCompletion.lean b/Mathlib/Topology/Algebra/LinearMapCompletion.lean index 65520a2f0cada7..fd01363aa3c3be 100644 --- a/Mathlib/Topology/Algebra/LinearMapCompletion.lean +++ b/Mathlib/Topology/Algebra/LinearMapCompletion.lean @@ -31,6 +31,7 @@ variable {α β : Type*} {R₁ R₂ : Type*} [UniformSpace α] [AddCommGroup α] [AddCommGroup β] [IsUniformAddGroup β] [Module R₂ β] [UniformContinuousConstSMul R₂ β] {σ : R₁ →+* R₂} +set_option backward.isDefEq.respectTransparency false in /-- Lift a continuous semilinear map to a continuous semilinear map between the `UniformSpace.Completion`s of the spaces. This is `UniformSpace.Completion.map` bundled as a diff --git a/Mathlib/Topology/Algebra/LinearTopology.lean b/Mathlib/Topology/Algebra/LinearTopology.lean index 084f5178004d5d..4281badcc5b39e 100644 --- a/Mathlib/Topology/Algebra/LinearTopology.lean +++ b/Mathlib/Topology/Algebra/LinearTopology.lean @@ -292,6 +292,7 @@ theorem hasBasis_right_ideal [IsLinearTopology Rᵐᵒᵖ R] : (𝓝 0).HasBasis (fun I : Submodule Rᵐᵒᵖ R ↦ (I : Set R) ∈ 𝓝 0) (fun I ↦ (I : Set R)) := hasBasis_submodule Rᵐᵒᵖ +set_option backward.isDefEq.respectTransparency false in open Set Pointwise in /-- If a ring `R` is linearly ordered as a left *and* right module over itself, then it has a basis of neighborhoods of zero made of *two-sided* ideals. diff --git a/Mathlib/Topology/Algebra/Module/Complement.lean b/Mathlib/Topology/Algebra/Module/Complement.lean index 68b2429b536667..83cc73d068d982 100644 --- a/Mathlib/Topology/Algebra/Module/Complement.lean +++ b/Mathlib/Topology/Algebra/Module/Complement.lean @@ -385,6 +385,7 @@ theorem _root_.ContinuousLinearMap.closedComplemented_ker_of_rightInverse [Conti f₁.ker.ClosedComplemented := f₂.isTopCompl_range_ker_of_leftInverse f₁ h.leftInverse |>.symm.closedComplemented +set_option backward.isDefEq.respectTransparency.types false in /-- If `p` is a closed complemented submodule, then there exists a submodule `q` and a continuous linear equivalence `M ≃L[R] (p × q)` such that `e (x : p) = (x, 0)`, `e (y : q) = (0, y)`, and `e.symm x = x.1 + x.2`. diff --git a/Mathlib/Topology/Algebra/Module/Equiv.lean b/Mathlib/Topology/Algebra/Module/Equiv.lean index 4e644e96118994..41e0872183e6e0 100644 --- a/Mathlib/Topology/Algebra/Module/Equiv.lean +++ b/Mathlib/Topology/Algebra/Module/Equiv.lean @@ -861,6 +861,7 @@ section AutRing variable (R : Type*) [Semiring R] [TopologicalSpace R] [ContinuousMul R] +set_option backward.isDefEq.respectTransparency false in /-- Continuous linear equivalences `R ≃L[R] R` are enumerated by `Rˣ`. -/ def unitsEquivAut : Rˣ ≃ R ≃L[R] R where toFun u := diff --git a/Mathlib/Topology/Algebra/Module/FiniteDimensionBilinear.lean b/Mathlib/Topology/Algebra/Module/FiniteDimensionBilinear.lean index 28992ed2ec8585..c93784a24e1779 100644 --- a/Mathlib/Topology/Algebra/Module/FiniteDimensionBilinear.lean +++ b/Mathlib/Topology/Algebra/Module/FiniteDimensionBilinear.lean @@ -33,6 +33,7 @@ variable {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] +set_option backward.isDefEq.respectTransparency false in /-- Building continuous bilinear maps from bilinear maps between finite dimensional topological vector spaces over a complete field. -/ def LinearMap.toContinuousBilinearMap (f : E →ₗ[𝕜] F →ₗ[𝕜] G) : E →L[𝕜] F →L[𝕜] G := diff --git a/Mathlib/Topology/Algebra/Module/LinearPMap.lean b/Mathlib/Topology/Algebra/Module/LinearPMap.lean index a7d9549f25f4d5..999f059ebdc1b1 100644 --- a/Mathlib/Topology/Algebra/Module/LinearPMap.lean +++ b/Mathlib/Topology/Algebra/Module/LinearPMap.lean @@ -181,6 +181,7 @@ theorem inverse_closed_iff (hf : LinearMap.ker f.toFun = ⊥) : f.inverse.IsClos variable [ContinuousAdd E] [ContinuousAdd F] variable [TopologicalSpace R] [ContinuousSMul R E] [ContinuousSMul R F] +set_option backward.isDefEq.respectTransparency false in /-- If `f` is invertible and closable as well as its closure being invertible, then the graph of the inverse of the closure is given by the closure of the graph of the inverse. -/ theorem closure_inverse_graph (hf : LinearMap.ker f.toFun = ⊥) (hf' : f.IsClosable) diff --git a/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean b/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean index 1b748f50d456cc..b79ee86f3a79ae 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean @@ -103,6 +103,7 @@ noncomputable def toNonUnitalAlgHom (φ : characterSpace 𝕜 A) : A →ₙₐ[ theorem coe_toNonUnitalAlgHom (φ : characterSpace 𝕜 A) : ⇑(toNonUnitalAlgHom φ) = φ := rfl +set_option backward.isDefEq.respectTransparency false in instance instIsEmpty [Subsingleton A] : IsEmpty (characterSpace 𝕜 A) := ⟨fun φ => φ.prop.1 <| ContinuousLinearMap.ext fun x => by diff --git a/Mathlib/Topology/Algebra/Module/Spaces/PointwiseConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/PointwiseConvergenceCLM.lean index bf240c1165a615..689c6de5aa510d 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/PointwiseConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/PointwiseConvergenceCLM.lean @@ -115,6 +115,9 @@ variable (𝕜 E F) in @[simps!] def coeLM [ContinuousConstSMul 𝕜 F] : (E →Lₚₜ[𝕜] F) →ₗ[𝕜] E →ₗ[𝕜] F := ContinuousLinearMap.coeLM 𝕜 +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in variable (σ F) in /-- The evaluation map `(f : E →SLₚₜ[σ] F) ↦ f a` for `a : E` as a continuous linear map. -/ @[simps!] diff --git a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean index 1a1b414cc74f97..78273f7ecadd37 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean @@ -101,7 +101,7 @@ notation3:25 E' " →Lᵤ[" R ", " 𝔖 "] " F => UniformConvergenceCLM (RingHom namespace UniformConvergenceCLM /-- Reinterpret `f : E →SL[σ] F` as an element of `E →SLᵤ[σ, 𝔖] F`. -/ -@[implicit_reducible] +@[instance_reducible] def ofFun [TopologicalSpace F] (𝔖 : Set (Set E)) : (E →SL[σ] F) ≃ (E →SLᵤ[σ, 𝔖] F) := ⟨fun x => x, fun x => x, fun _ => rfl, fun _ => rfl⟩ @@ -361,6 +361,7 @@ theorem tendsto_iff_tendstoUniformlyOn {ι : Type*} {p : Filter ι} [UniformSpac rw [(isEmbedding_coeFn σ F 𝔖).tendsto_nhds_iff, UniformOnFun.tendsto_iff_tendstoUniformlyOn] rfl +set_option backward.isDefEq.respectTransparency false in variable {F} in theorem isUniformInducing_postcomp [AddCommGroup G] [UniformSpace G] [IsUniformAddGroup G] @@ -481,6 +482,7 @@ variable {𝕜₁ 𝕜₂ 𝕜₃ : Type*} [NormedField 𝕜₁] [NormedField variable (𝔖 : Set (Set E)) (𝔗 : Set (Set F)) +set_option backward.isDefEq.respectTransparency false in variable (G) in /-- Pre-composition by a *fixed* continuous linear map as a continuous linear map for the uniform convergence topology. -/ @@ -504,6 +506,7 @@ alias precomp_uniformConvergenceCLM := precompUniformConvergenceCLM @[deprecated (since := "2026-01-27")] alias precomp_uniformConvergenceCLM_apply := precompUniformConvergenceCLM_apply +set_option backward.isDefEq.respectTransparency false in /-- Post-composition by a *fixed* continuous linear map as a continuous linear map for the uniform convergence topology. -/ @[simps] @@ -542,6 +545,7 @@ variable (𝕜 : Type*) [NormedField 𝕜] {E ι : Type*} (F : ι → Type*) [∀ i, AddCommGroup (F i)] [∀ i, Module 𝕜 (F i)] [∀ i, TopologicalSpace (F i)] [∀ i, IsTopologicalAddGroup (F i)] [∀ i, ContinuousConstSMul 𝕜 (F i)] +set_option backward.isDefEq.respectTransparency.types false in /-- `ContinuousLinearMap.pi`, upgraded to a continuous linear equivalence between `Π i, E →Lᵤ[𝕜, 𝔖] F i` and `E →Lᵤ[𝕜, 𝔖] Π i, F i`. -/ def UniformConvergenceCLM.piEquivL (𝔖 : Set (Set E)) : diff --git a/Mathlib/Topology/Algebra/Module/Star.lean b/Mathlib/Topology/Algebra/Module/Star.lean index 9a3b8b14c78854..0aff3206960564 100644 --- a/Mathlib/Topology/Algebra/Module/Star.lean +++ b/Mathlib/Topology/Algebra/Module/Star.lean @@ -52,6 +52,9 @@ variable [TrivialStar R] -- TODO: this could be replaced with something like `(starL R).restrict_scalarsₛₗ h` if we -- implemented the idea in -- https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there-code-for-X.3F/topic/Star-semilinear.20maps.20are.20semilinear.20when.20star.20is.20trivial/near/359557835 +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- If `A` is a topological module over a commutative `R` with trivial star and compatible actions, then `star` is a continuous linear equivalence. -/ @[simps! apply] @@ -67,6 +70,7 @@ def starL' : A ≃L[R] A := theorem symm_starL' : (starL' R : A ≃L[R] A).symm = starL' R := rfl +set_option backward.isDefEq.respectTransparency.types false in @[deprecated "Use `symm_starL'` and `starL'_apply` instead" (since := "2026-06-03")] theorem starL'_symm_apply (x : A) : (starL' R).symm x = starAddEquiv.symm x := by simp @@ -108,6 +112,9 @@ def skewAdjointPartL [ContinuousSub A] [ContinuousStar A] [ContinuousConstSMul R A →L[R] skewAdjoint A where toLinearMap := skewAdjointPart R +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The decomposition of elements of a star module into their self- and skew-adjoint parts, as a continuous linear equivalence. -/ @[simps!] diff --git a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean index 06ac7590c5fb73..3aa854edeb47be 100644 --- a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean +++ b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean @@ -52,6 +52,7 @@ variable (𝕜 α E H : Type*) {hom : Type*} [NormedField 𝕜] [AddCommGroup H] [ContinuousSMul 𝕜 E] {𝔖 : Set <| Set α} [FunLike hom H (α → E)] [LinearMapClass hom 𝕜 H (α → E)] +set_option backward.isDefEq.respectTransparency false in /-- Let `E` be a topological vector space over a normed field `𝕜`, let `α` be any type. Let `H` be a submodule of `α →ᵤ E` such that the range of each `f ∈ H` is von Neumann bounded. Then `H` is a topological vector space over `𝕜`, diff --git a/Mathlib/Topology/Algebra/MulAction.lean b/Mathlib/Topology/Algebra/MulAction.lean index 0ec40fe17fabd7..a2c24ba7ee7ad6 100644 --- a/Mathlib/Topology/Algebra/MulAction.lean +++ b/Mathlib/Topology/Algebra/MulAction.lean @@ -95,6 +95,7 @@ instance OrderDual.instContinuousSMul_left : ContinuousSMul Mᵒᵈ X where instance (priority := 100) ContinuousSMul.continuousConstSMul : ContinuousConstSMul M X where continuous_const_smul _ := continuous_smul.comp (continuous_const.prodMk continuous_id) +set_option backward.isDefEq.respectTransparency false in theorem ContinuousSMul.induced {R : Type*} {α : Type*} {β : Type*} {F : Type*} [FunLike F α β] [Semiring R] [AddCommMonoid α] [AddCommMonoid β] [Module R α] [Module R β] [TopologicalSpace R] [LinearMapClass F R α β] [tβ : TopologicalSpace β] [ContinuousSMul R β] diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean b/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean index 945815ac73ecce..cff6a588fe8d5c 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/AdicTopology.lean @@ -79,13 +79,13 @@ theorem adic_basis (I : Ideal R) : SubmodulesRingBasis fun n : ℕ => (I ^ n • exact (I ^ n).smul_mem x hb } /-- The adic ring filter basis associated to an ideal `I` is made of powers of `I`. -/ -@[implicit_reducible] +@[instance_reducible] def ringFilterBasis (I : Ideal R) := I.adic_basis.toRing_subgroups_basis.toRingFilterBasis /-- The adic topology associated to an ideal `I`. This topology admits powers of `I` as a basis of neighborhoods of zero. It is compatible with the ring structure and is non-archimedean. -/ -@[implicit_reducible] +@[instance_reducible] def adicTopology (I : Ideal R) : TopologicalSpace R := (adic_basis I).topology @@ -133,7 +133,7 @@ theorem adic_module_basis : /-- The topology on an `R`-module `M` associated to an ideal `M`. Submodules $I^n M$, written `I^n • ⊤` form a basis of neighborhoods of zero. -/ -@[implicit_reducible] +@[instance_reducible] def adicModuleTopology : TopologicalSpace M := @ModuleFilterBasis.topology R M _ I.adic_basis.topology _ _ (I.ringFilterBasis.moduleFilterBasis (I.adic_module_basis M)) @@ -278,7 +278,7 @@ lemma isTopologicallyNilpotent_of_mem {a : R} (ha : a ∈ i) : IsTopologicallyNi /-- The adic topology on an `R` module coming from the ideal `WithIdeal.I`. This cannot be an instance because `R` cannot be inferred from `M`. -/ -@[implicit_reducible] +@[instance_reducible] def topologicalSpaceModule (M : Type*) [AddCommGroup M] [Module R M] : TopologicalSpace M := (i : Ideal R).adicModuleTopology M diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean b/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean index 08e03275544bba..b4c4348ad087b2 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/Bases.lean @@ -63,7 +63,7 @@ theorem of_comm {A ι : Type*} [CommRing A] (B : ι → AddSubgroup A) rightMul := fun x i ↦ (leftMul x i).imp fun j hj ↦ by simpa only [mul_comm] using hj } /-- Every subgroups basis on a ring leads to a ring filter basis. -/ -@[implicit_reducible] +@[instance_reducible] def toRingFilterBasis [Nonempty ι] {B : ι → AddSubgroup A} (hB : RingSubgroupsBasis B) : RingFilterBasis A where sets := { U | ∃ i, U = B i } @@ -133,7 +133,7 @@ theorem mem_addGroupFilterBasis (i) : (B i : Set A) ∈ hB.toRingFilterBasis.toA /-- The topology defined from a subgroups basis, admitting the given subgroups as a basis of neighborhoods of zero. -/ -@[implicit_reducible] +@[instance_reducible] def topology : TopologicalSpace A := hB.toRingFilterBasis.toAddGroupFilterBasis.topology @@ -223,7 +223,7 @@ theorem toRing_subgroups_basis (hB : SubmodulesRingBasis B) : exact hj ⟨b, b_in, rfl⟩ /-- The topology associated to a basis of submodules in an algebra. -/ -@[implicit_reducible] +@[instance_reducible] def topology [Nonempty ι] (hB : SubmodulesRingBasis B) : TopologicalSpace A := hB.toRing_subgroups_basis.topology @@ -303,7 +303,7 @@ def toModuleFilterBasis : ModuleFilterBasis R M where exact hB.smul m₀ i /-- The topology associated to a basis of submodules in a module. -/ -@[implicit_reducible] +@[instance_reducible] def topology : TopologicalSpace M := hB.toModuleFilterBasis.toAddGroupFilterBasis.topology diff --git a/Mathlib/Topology/Algebra/RestrictedProduct/Units.lean b/Mathlib/Topology/Algebra/RestrictedProduct/Units.lean index 0b0b1001a9fc3a..a01704b86194b9 100644 --- a/Mathlib/Topology/Algebra/RestrictedProduct/Units.lean +++ b/Mathlib/Topology/Algebra/RestrictedProduct/Units.lean @@ -68,6 +68,7 @@ theorem isUnit_iff {x : Πʳ i, [R i, B i]_[𝓕]} : def coeUnits : Πʳ i, [R i, B i]_[𝓕]ˣ →* (i : ι) → (R i)ˣ := MulEquiv.piUnits.toMonoidHom.comp <| Units.map coeMonoidHom +set_option backward.isDefEq.respectTransparency false in /-- Constructs a unit in a restricted product `Πʳ i, [R i, B i]_[𝓕]` given an element `x` of the usual product and the condition that `x` is eventually in the units of `B i` along `𝓕`. -/ def mkUnit (x : Π i, (R i)ˣ) (hx : ∀ᶠ i in 𝓕, x i ∈ (Submonoid.ofClass (B i)).units) : diff --git a/Mathlib/Topology/Algebra/Ring/Compact.lean b/Mathlib/Topology/Algebra/Ring/Compact.lean index 29ef1a13c75373..09dbc45255206b 100644 --- a/Mathlib/Topology/Algebra/Ring/Compact.lean +++ b/Mathlib/Topology/Algebra/Ring/Compact.lean @@ -116,6 +116,7 @@ end IsLocalRing section IsDedekindDomain +set_option backward.isDefEq.respectTransparency.types false in lemma IsDedekindDomain.isOpen_of_ne_bot [IsDedekindDomain R] {I : Ideal R} (hI : I ≠ ⊥) : IsOpen (X := R) I := by diff --git a/Mathlib/Topology/Algebra/StarSubalgebra.lean b/Mathlib/Topology/Algebra/StarSubalgebra.lean index 4f3ee1db715c13..403ae5bee60e68 100644 --- a/Mathlib/Topology/Algebra/StarSubalgebra.lean +++ b/Mathlib/Topology/Algebra/StarSubalgebra.lean @@ -257,6 +257,7 @@ theorem induction_on {x y : A} | mul u v hu_mem hv_mem hu hv => exact mul u (subset_closure hu_mem) v (subset_closure hv_mem) (hu hu_mem) (hv hv_mem) +set_option backward.isDefEq.respectTransparency false in theorem starAlgHomClass_ext [T2Space B] {F : Type*} {a : A} [FunLike F (elemental R a) B] [AlgHomClass F R _ B] [StarHomClass F _ B] {φ ψ : F} (hφ : Continuous φ) diff --git a/Mathlib/Topology/Algebra/TopologicallyNilpotent.lean b/Mathlib/Topology/Algebra/TopologicallyNilpotent.lean index d79cf54b70c6d9..6848b8d429421e 100644 --- a/Mathlib/Topology/Algebra/TopologicallyNilpotent.lean +++ b/Mathlib/Topology/Algebra/TopologicallyNilpotent.lean @@ -145,6 +145,7 @@ def _root_.topologicalNilradical : Ideal R where zero_mem' := zero smul_mem' := mul_left +set_option backward.isDefEq.respectTransparency false in theorem mem_topologicalNilradical_iff {a : R} : a ∈ topologicalNilradical R ↔ IsTopologicallyNilpotent a := by simp [topologicalNilradical] diff --git a/Mathlib/Topology/Algebra/UniformFilterBasis.lean b/Mathlib/Topology/Algebra/UniformFilterBasis.lean index 8299736fad5ee2..3982f8ca987b99 100644 --- a/Mathlib/Topology/Algebra/UniformFilterBasis.lean +++ b/Mathlib/Topology/Algebra/UniformFilterBasis.lean @@ -31,7 +31,7 @@ variable {G : Type*} [AddCommGroup G] (B : AddGroupFilterBasis G) /-- The uniform space structure associated to an abelian group filter basis via the associated topological abelian group structure. -/ -@[implicit_reducible] +@[instance_reducible] protected def uniformSpace : UniformSpace G := @IsTopologicalAddGroup.rightUniformSpace G _ B.topology B.isTopologicalAddGroup diff --git a/Mathlib/Topology/Algebra/UniformRing.lean b/Mathlib/Topology/Algebra/UniformRing.lean index b86b231883cd69..1b145627cdb671 100644 --- a/Mathlib/Topology/Algebra/UniformRing.lean +++ b/Mathlib/Topology/Algebra/UniformRing.lean @@ -170,10 +170,14 @@ theorem mapRingHom_comp {γ : Type*} [UniformSpace γ] [Ring γ] [IsUniformAddGr (uniformContinuous_addMonoidHom_of_continuous hg) (uniformContinuous_addMonoidHom_of_continuous hf) +set_option backward.isDefEq.respectTransparency false in @[simp] theorem mapRingHom_id : mapRingHom (.id α) continuous_id = .id (Completion α) := by simp [RingHom.ext_iff, mapRingHom_apply] +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A ring isomorphism `α ≃+* β` between uniform rings, uniformly continuous in both directions, lifts to a ring isomorphism between corresponding uniform space completions. -/ @[simps!] diff --git a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean index 77dc51ef10203c..6d216faa17e70e 100644 --- a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean +++ b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean @@ -185,6 +185,7 @@ theorem hasBasis_nhds_zero : fun γ : (ValueGroup₀ (.ofClass v))ˣ ↦ { x | v.restrict x < γ.val } := by simp [Filter.hasBasis_iff, v.is_topological_valuation] +set_option backward.isDefEq.respectTransparency.types false in /-- The set `{ y : R | v y = v x }` is a neighbourhood of `x`. This does not imply that `v` is locally constant everywhere (since `v ⁻¹' {0}` is not open), but it is equivalent to the restriction of `v` to the complement of its support being @@ -328,6 +329,7 @@ theorem isOpen_closedBall {r : ValueGroup₀ (.ofClass v)} (hr : r ≠ 0) : exact ⟨Units.mk0 _ hr, fun y hy ↦ (sub_add_cancel y x).symm ▸ le_trans (v.restrict.map_add _ _) (max_le (le_of_lt hy) hx)⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- For any valuation `v` compatible with the valuative relation on `R`, the closed `r`-ball around zero `{x | v.restrict x ≤ r}` is closed in the valuative topology. -/ theorem isClosed_closedBall (r : ValueGroup₀ (.ofClass v)) : @@ -346,6 +348,7 @@ theorem isClopen_closedBall {r : ValueGroup₀ (.ofClass v)} (hr : r ≠ 0) : IsClopen {x | v.restrict x ≤ r} := ⟨isClosed_closedBall _, isOpen_closedBall hr⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- For any valuation `v` compatible with the valuative relation on `R`, the sphere of radius `r` around zero `{x | v.restrict x = r}` is clopen in the valuative topology. -/ theorem isClopen_sphere {r : ValueGroup₀ (.ofClass v)} (hr : r ≠ 0) : diff --git a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean index 9c0ceadbc2bc0f..9900a414ab07e1 100644 --- a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean +++ b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean @@ -126,6 +126,7 @@ lemma finite_quotient_maximalIdeal_pow_of_finite_residueField [IsDiscreteValuati open scoped Valued +set_option backward.isDefEq.respectTransparency.types false in lemma totallyBounded_iff_finite_residueField [(Valued.v : Valuation K Γ₀).RankOne] [IsDiscreteValuationRing 𝒪[K]] : TotallyBounded (Set.univ (α := 𝒪[K])) ↔ Finite 𝓀[K] := by diff --git a/Mathlib/Topology/Algebra/Valued/NormedValued.lean b/Mathlib/Topology/Algebra/Valued/NormedValued.lean index cd0ee47f892877..d18ca876b0c5fb 100644 --- a/Mathlib/Topology/Algebra/Valued/NormedValued.lean +++ b/Mathlib/Topology/Algebra/Valued/NormedValued.lean @@ -62,6 +62,7 @@ instance : RankLeOne (valuation (K := K)) where hom' := embedding strictMono' := embedding_strictMono +set_option backward.isDefEq.respectTransparency.types false in /-- The valued field structure on a nonarchimedean normed field `K`, determined by the norm. -/ @[instance_reducible] def toValued : Valued K ℝ≥0 := @@ -123,6 +124,7 @@ theorem norm_def {x : L} : v.norm x = hv.hom _ (v.restrict x) := rfl theorem norm_nonneg (x : L) : 0 ≤ v.norm x := by simp only [norm, NNReal.zero_le_coe] +set_option backward.isDefEq.respectTransparency.types false in theorem norm_add_le (x y : L) : v.norm (x + y) ≤ max (v.norm x) (v.norm y) := by simp only [norm, NNReal.coe_le_coe, le_max_iff, StrictMono.le_iff_le hv.strictMono] exact le_max_iff.mp (Valuation.map_add_le_max' v.restrict _ _) diff --git a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean index fa3472bb477a28..32e92c2d0aaf73 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean @@ -132,7 +132,7 @@ class Valued (R : Type u) [Ring R] (Γ₀ : outParam (Type v)) namespace Valued /-- Alternative `Valued` constructor for use when there is no preferred `UniformSpace` structure. -/ -@[implicit_reducible] +@[instance_reducible] def mk' (v : Valuation R Γ₀) : Valued R Γ₀ := { v toUniformSpace := @IsTopologicalAddGroup.rightUniformSpace R _ v.subgroups_basis.topology _ @@ -178,6 +178,7 @@ theorem mem_nhds_zero {s : Set R} : s ∈ 𝓝 (0 : R) ↔ ∃ γ : (MonoidWithZeroHom.ValueGroup₀ (.ofClass _i.v))ˣ, { x | v.restrict x < γ.1 } ⊆ s := by simp only [mem_nhds, sub_zero] +set_option backward.isDefEq.respectTransparency.types false in /-- The set `{ y : R | v y = v x }` is a neighbourhood of `x`. This does not imply that `v` is locally constant everywhere (since `v ⁻¹' {0}` is not open), but it is equivalent to the restriction of `v` to the complement of its support being @@ -263,6 +264,7 @@ theorem isOpen_closedBall {r : ValueGroup₀ (.ofClass _i.v)} (hr : r ≠ 0) : exact ⟨Units.mk0 _ hr, fun y hy ↦ (sub_add_cancel y x).symm ▸ le_trans (v.restrict.map_add _ _) (max_le (le_of_lt hy) hx)⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- A closed ball centred at the origin in a valued ring is closed. -/ theorem isClosed_closedBall (r : ValueGroup₀ (.ofClass _i.v)) : IsClosed {x | v.restrict x ≤ r} := by @@ -279,6 +281,7 @@ theorem isClopen_closedBall {r : ValueGroup₀ (.ofClass _i.v)} (hr : r ≠ 0) : IsClopen {x | v.restrict x ≤ r} := ⟨isClosed_closedBall _ _, isOpen_closedBall _ hr⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- A sphere centred at the origin in a valued ring is clopen. -/ theorem isClopen_sphere {r : ValueGroup₀ (.ofClass _i.v)} (hr : r ≠ 0) : IsClopen {x | v.restrict x = r} := by diff --git a/Mathlib/Topology/Algebra/Valued/ValuedField.lean b/Mathlib/Topology/Algebra/Valued/ValuedField.lean index 752bb654a6e7a5..a9e2878a6be5ec 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuedField.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuedField.lean @@ -101,6 +101,7 @@ instance (priority := 100) Valued.isTopologicalDivisionRing [Valued K Γ₀] : simp only [mem_setOf_eq, Units.min_val, Units.val_mul] at y_in exact Valuation.inversion_estimate _ x_ne y_in } +set_option backward.isDefEq.respectTransparency.types false in /-- A valued division ring is separated. -/ instance (priority := 100) ValuedRing.separated [Valued K Γ₀] : T0Space K := by suffices T2Space K by infer_instance @@ -135,6 +136,7 @@ theorem Valued.continuous_valuation [hv : Valued K Γ₀] : simp_rw [v.restrict_inj] apply Valued.locally_const (by simpa [restrict₀_apply] using v_ne) +set_option backward.isDefEq.respectTransparency.types false in theorem Valued.continuous_valuation_of_surjective [hv : Valued K Γ₀] (hsurj : Function.Surjective hv.v) : Continuous hv.v := by rw [continuous_iff_continuousAt] @@ -208,6 +210,7 @@ instance (priority := 100) completable : CompletableTopField K := open MonoidWithZeroHom WithZeroTopology +set_option backward.isDefEq.respectTransparency.types false in lemma valuation_isClosedMap : IsClosedMap (v.restrict : K → (ValueGroup₀ (.ofClass hv.v))) := by refine IsClosedMap.of_nonempty ?_ intro U hU hU' @@ -457,6 +460,7 @@ noncomputable def valueGroup₀_hom_extensionValuation : · simpa · simp [extensionValuation_apply_coe, hxy, ← hx, ← hy, hx0, hy0] +set_option backward.isDefEq.respectTransparency.types false in /-- The zero-preserving monoid homomorphism from the `ValueGroup₀` of the valuation on `K` to that of the extension to its completion. -/ noncomputable def valueGroup₀_equiv_extensionValuation : diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index c0c0c2f435209d..d02b53fc6f22cb 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -443,6 +443,7 @@ theorem strictMono_valueGroupEquiv : StrictMono (valueGroupEquiv v) := theorem strictMono_valueGroupEquiv_symm : StrictMono (valueGroupEquiv v).symm := fun _ _ _ ↦ by simpa +set_option backward.isDefEq.respectTransparency.types false in /-- The order-preserving, multiplicative equivalence between the `ValueGroup₀` of the valuation on `WithVal v` and the valuation `v`. -/ @[simps!] @@ -637,6 +638,7 @@ theorem exists_div_eq_of_surjective {K : Type*} [DivisionRing K] {Γ₀ : Type*} obtain ⟨r, hr⟩ := hv γ exact ⟨r, 1, by simp [hr]⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem restrict_exists_div_eq {K : Type*} [DivisionRing K] {Γ₀ : Type*} [LinearOrderedCommGroupWithZero Γ₀] (v : Valuation K Γ₀) (γ : (ValueGroup₀ (.ofClass v))ˣ) : @@ -686,6 +688,9 @@ def withValEquiv (R : Type*) [CommRing R] [Algebra R K] [IsIntegralClosure R ℤ end NumberField.RingOfIntegers +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in open scoped NumberField in /-- The ring of integers of `WithVal v`, when `v` is a valuation on `ℚ`, is equivalent to `ℤ`. -/ diff --git a/Mathlib/Topology/Basic.lean b/Mathlib/Topology/Basic.lean index 3ca95a365474ce..342ef7ab77603e 100644 --- a/Mathlib/Topology/Basic.lean +++ b/Mathlib/Topology/Basic.lean @@ -39,7 +39,7 @@ universe u v /-- A constructor for topologies by specifying the closed sets, and showing that they satisfy the appropriate conditions. -/ -@[implicit_reducible] +@[instance_reducible] def TopologicalSpace.ofClosed {X : Type u} (T : Set (Set X)) (empty_mem : ∅ ∈ T) (sInter_mem : ∀ A, A ⊆ T → ⋂₀ A ∈ T) (union_mem : ∀ A, A ∈ T → ∀ B, B ∈ T → A ∪ B ∈ T) : TopologicalSpace X where diff --git a/Mathlib/Topology/Bornology/Basic.lean b/Mathlib/Topology/Bornology/Basic.lean index 8ca9c42a3f4832..4b142e1d604446 100644 --- a/Mathlib/Topology/Bornology/Basic.lean +++ b/Mathlib/Topology/Bornology/Basic.lean @@ -64,7 +64,7 @@ lemma Bornology.ext (t t' : Bornology α) /-- A constructor for bornologies by specifying the bounded sets, and showing that they satisfy the appropriate conditions. -/ -@[simps, implicit_reducible] +@[simps, instance_reducible] def Bornology.ofBounded {α : Type*} (B : Set (Set α)) (empty_mem : ∅ ∈ B) (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B) @@ -75,7 +75,7 @@ def Bornology.ofBounded {α : Type*} (B : Set (Set α)) /-- A constructor for bornologies by specifying the bounded sets, and showing that they satisfy the appropriate conditions. -/ -@[simps! cobounded, implicit_reducible] +@[simps! cobounded, instance_reducible] def Bornology.ofBounded' {α : Type*} (B : Set (Set α)) (empty_mem : ∅ ∈ B) (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B) diff --git a/Mathlib/Topology/CWComplex/Classical/Basic.lean b/Mathlib/Topology/CWComplex/Classical/Basic.lean index 705253ee4cc7aa..946ba6ba2375eb 100644 --- a/Mathlib/Topology/CWComplex/Classical/Basic.lean +++ b/Mathlib/Topology/CWComplex/Classical/Basic.lean @@ -178,7 +178,7 @@ instance (priority := high) CWComplex.instRelCWComplex {X : Type*} [TopologicalS union' := by simpa only [empty_union] using CWComplex.union' /-- A relative CW complex with an empty base is an absolute CW complex. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def RelCWComplex.toCWComplex {X : Type*} [TopologicalSpace X] (C : Set X) [RelCWComplex C ∅] : CWComplex C where cell := cell C @@ -1075,6 +1075,7 @@ lemma RelCWComplex.disjoint_interior_base_iUnion_closedCell [T2Space X] [RelCWCo simp_rw [disjoint_iff_inter_eq_empty, inter_iUnion, disjoint_interior_base_closedCell.inter_eq, iUnion_empty] +set_option backward.isDefEq.respectTransparency.types false in /-- A closed discrete subset of a space is a CW complex. -/ @[reducible, simps -isSimp] def CWComplex.OfDiscreteClosed (hD : IsDiscrete D) (Dc : IsClosed D) : CWComplex D where diff --git a/Mathlib/Topology/CWComplex/Classical/Finite.lean b/Mathlib/Topology/CWComplex/Classical/Finite.lean index 5ce7bb7d026a8c..610ab27cddceaf 100644 --- a/Mathlib/Topology/CWComplex/Classical/Finite.lean +++ b/Mathlib/Topology/CWComplex/Classical/Finite.lean @@ -73,7 +73,7 @@ end CWComplex /-- If we want to construct a relative CW complex of finite type, we can add the condition `finite_cell` and relax the condition `mapsTo`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def RelCWComplex.mkFiniteType.{u} {X : Type u} [TopologicalSpace X] (C : Set X) (D : outParam (Set X)) (cell : (n : ℕ) → Type u) (map : (n : ℕ) → (i : cell n) → PartialEquiv (Fin n → ℝ) X) @@ -132,7 +132,7 @@ lemma RelCWComplex.finiteType_mkFiniteType.{u} {X : Type u} [TopologicalSpace X] /-- If we want to construct a CW complex of finite type, we can add the condition `finite_cell` and relax the condition `mapsTo`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def CWComplex.mkFiniteType.{u} {X : Type u} [TopologicalSpace X] (C : Set X) (cell : (n : ℕ) → Type u) (map : (n : ℕ) → (i : cell n) → PartialEquiv (Fin n → ℝ) X) (finite_cell : ∀ (n : ℕ), _root_.Finite (cell n)) @@ -184,7 +184,7 @@ lemma CWComplex.finiteType_mkFiniteType.{u} {X : Type u} [TopologicalSpace X] (C /-- If we want to construct a finite relative CW complex we can add the conditions `eventually_isEmpty_cell` and `finite_cell`, relax the condition `mapsTo` and remove the condition `closed'`. -/ -@[simps -isSimp, implicit_reducible] +@[simps -isSimp, instance_reducible] def RelCWComplex.mkFinite.{u} {X : Type u} [TopologicalSpace X] (C : Set X) (D : outParam (Set X)) (cell : (n : ℕ) → Type u) (map : (n : ℕ) → (i : cell n) → PartialEquiv (Fin n → ℝ) X) @@ -259,7 +259,7 @@ lemma RelCWComplex.finite_mkFinite.{u} {X : Type u} [TopologicalSpace X] (C : Se /-- If we want to construct a finite CW complex we can add the conditions `eventually_isEmpty_cell` and `finite_cell`, relax the condition `mapsTo` and remove the condition `closed'`. -/ -@[simps! -isSimp, implicit_reducible] +@[simps! -isSimp, instance_reducible] def CWComplex.mkFinite.{u} {X : Type u} [TopologicalSpace X] (C : Set X) (cell : (n : ℕ) → Type u) (map : (n : ℕ) → (i : cell n) → PartialEquiv (Fin n → ℝ) X) (eventually_isEmpty_cell : ∀ᶠ n in Filter.atTop, IsEmpty (cell n)) diff --git a/Mathlib/Topology/Category/CompHausLike/Basic.lean b/Mathlib/Topology/Category/CompHausLike/Basic.lean index 080d42bdc488e6..822b65506b63c7 100644 --- a/Mathlib/Topology/Category/CompHausLike/Basic.lean +++ b/Mathlib/Topology/Category/CompHausLike/Basic.lean @@ -125,7 +125,7 @@ theorem coe_id (X : CompHausLike P) : (𝟙 X : X → X) = id := @[simp] theorem coe_comp {X Y Z : CompHausLike P} (f : X ⟶ Y) (g : Y ⟶ Z) : - (f ≫ g : X → Z) = g ∘ f := + (f ≫ g : X → Z) = (g ∘ f) := rfl section diff --git a/Mathlib/Topology/Category/CompHausLike/Cartesian.lean b/Mathlib/Topology/Category/CompHausLike/Cartesian.lean index 6fedbf0612828b..b6059b439972c0 100644 --- a/Mathlib/Topology/Category/CompHausLike/Cartesian.lean +++ b/Mathlib/Topology/Category/CompHausLike/Cartesian.lean @@ -59,7 +59,7 @@ This could be an instance but that causes some slowness issues with typeclass se keep it as a def and turn it on as an instance for the explicit examples of `CompHausLike` as needed. -/ -@[implicit_reducible] +@[instance_reducible] def cartesianMonoidalCategory [∀ (X Y : CompHausLike.{u} P), HasProp P (X × Y)] [HasProp P PUnit.{u + 1}] : CartesianMonoidalCategory (CompHausLike.{u} P) := .ofChosenFiniteProducts @@ -79,6 +79,7 @@ type-theoretic sums. def coproductCocone : BinaryCofan X Y := BinaryCofan.mk (P := CompHausLike.of P (X ⊕ Y)) (ofHom _ { toFun := Sum.inl }) (ofHom _ { toFun := Sum.inr }) +set_option backward.isDefEq.respectTransparency.types false in /-- When the predicate `P` is preserved under taking type-theoretic sums, that sum is a category-theoretic coproduct in `CompHausLike P`. diff --git a/Mathlib/Topology/Category/Compactum.lean b/Mathlib/Topology/Category/Compactum.lean index 9eacb2c74d35a2..8f303b5cfb3ccf 100644 --- a/Mathlib/Topology/Category/Compactum.lean +++ b/Mathlib/Topology/Category/Compactum.lean @@ -109,6 +109,7 @@ def adj : free ⊣ forget := instance : CoeSort Compactum Type* := ⟨fun X => X.A⟩ +set_option backward.isDefEq.respectTransparency.types false in instance {X Y : Compactum} : FunLike (X ⟶ Y) X Y where coe f := f.f coe_injective _ _ h := (Monad.forget_faithful β).map_injective (by aesop) @@ -133,12 +134,16 @@ def join (X : Compactum) : Ultrafilter (Ultrafilter X) → Ultrafilter X := def incl (X : Compactum) : X → Ultrafilter X := (β).η.app _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem str_incl (X : Compactum) (x : X) : X.str (X.incl x) = x := by change ((β).η.app _ ≫ X.a) _ = _ rw [Monad.Algebra.unit] rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem str_hom_commute (X Y : Compactum) (f : X ⟶ Y) (xs : Ultrafilter X) : f (X.str xs) = Y.str (map f xs) := by @@ -146,6 +151,7 @@ theorem str_hom_commute (X Y : Compactum) (f : X ⟶ Y) (xs : Ultrafilter X) : rw [← f.h] rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem join_distrib (X : Compactum) (uux : Ultrafilter (Ultrafilter X)) : X.str (X.join uux) = X.str (map X.str uux) := by @@ -365,6 +371,9 @@ theorem cl_eq_closure {X : Compactum} (A : Set X) : cl A = closure A := by · rintro ⟨F, h1, h2⟩ exact ⟨F, h1, str_eq_of_le_nhds _ _ h2⟩ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Any morphism of compacta is continuous. -/ theorem continuous_of_hom {X Y : Compactum} (f : X ⟶ Y) : Continuous f := by rw [continuous_iff_ultrafilter] @@ -374,6 +383,7 @@ theorem continuous_of_hom {X Y : Compactum} (f : X ⟶ Y) : Continuous f := by rw [← str_hom_commute, str_eq_of_le_nhds _ x _] apply h +set_option backward.isDefEq.respectTransparency.types false in /-- Given any compact Hausdorff space, we construct a Compactum. -/ noncomputable def ofTopologicalSpace (X : Type*) [TopologicalSpace X] [CompactSpace X] [T2Space X] : Compactum where @@ -438,6 +448,7 @@ instance faithful : compactumToCompHaus.Faithful where ext simpa using! ConcreteCategory.congr_hom h _ +set_option backward.isDefEq.respectTransparency.types false in /-- This definition is used to prove essential surjectivity of `compactumToCompHaus`. -/ noncomputable def isoOfTopologicalSpace {D : CompHaus} : compactumToCompHaus.obj (Compactum.ofTopologicalSpace D) ≅ D where diff --git a/Mathlib/Topology/Category/Profinite/AsLimit.lean b/Mathlib/Topology/Category/Profinite/AsLimit.lean index 35bdf1848b6462..f3177895c3b2ff 100644 --- a/Mathlib/Topology/Category/Profinite/AsLimit.lean +++ b/Mathlib/Topology/Category/Profinite/AsLimit.lean @@ -58,6 +58,7 @@ def asLimitCone : CategoryTheory.Limits.Cone X.diagram := π := { app := fun S => CompHausLike.ofHom (Y := X.diagram.obj S) _ ⟨S.proj, IsLocallyConstant.continuous (S.proj_isLocallyConstant)⟩ } } +set_option backward.isDefEq.respectTransparency.types false in instance isIso_asLimitCone_lift : IsIso ((limitConeIsLimit.{u, u} X.diagram).lift X.asLimitCone) := CompHausLike.isIso_of_bijective _ (by diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean index fbc475f10b9339..b4813d826e9696 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean @@ -149,17 +149,20 @@ theorem continuous_projRestricts (h : ∀ i, J i → K i) : Continuous (ProjRest theorem surjective_projRestricts (h : ∀ i, J i → K i) : Function.Surjective (ProjRestricts C h) := (Homeomorph.surjective _).comp (Set.surjective_mapsTo_image_restrict _ _) +set_option backward.isDefEq.respectTransparency.types false in variable (J) in theorem projRestricts_eq_id : ProjRestricts C (fun i (h : J i) ↦ h) = id := by ext ⟨x, y, hy, rfl⟩ i simp +contextual only [π, Proj, ProjRestricts_coe, id_eq, if_true] +set_option backward.isDefEq.respectTransparency.types false in theorem projRestricts_eq_comp (hJK : ∀ i, J i → K i) (hKL : ∀ i, K i → L i) : ProjRestricts C hJK ∘ ProjRestricts C hKL = ProjRestricts C (fun i ↦ hKL i ∘ hJK i) := by ext x i simp only [π, Proj, Function.comp_apply, ProjRestricts_coe] simp_all +set_option backward.isDefEq.respectTransparency.types false in theorem projRestricts_comp_projRestrict (h : ∀ i, J i → K i) : ProjRestricts C h ∘ ProjRestrict C K = ProjRestrict C J := by ext x i @@ -396,11 +399,12 @@ theorem eval_eq (l : Products I) (x : C) : dsimp [LocallyConstant.evalMonoidHom, e] simp only [ite_eq_right_iff, one_ne_zero] +set_option backward.isDefEq.respectTransparency.types false in theorem evalFacProp {l : Products I} (J : I → Prop) (h : ∀ a, a ∈ l.val → J a) [∀ j, Decidable (J j)] : l.eval (π C J) ∘ ProjRestrict C J = l.eval C := by ext x - dsimp [ProjRestrict] + dsimp only [ProjRestrict, Function.comp_apply] rw [Products.eval_eq, Products.eval_eq] simp +contextual [h, Proj] diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean index 85b6d679dd112a..a6266639986c86 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean @@ -50,8 +50,7 @@ def πJ : LocallyConstant (π C (· ∈ s)) ℤ →ₗ[ℤ] LocallyConstant C theorem eval_eq_πJ (l : Products I) (hl : l.isGood (π C (· ∈ s))) : l.eval C = πJ C s (l.eval (π C (· ∈ s))) := by ext f - simp only [πJ, LocallyConstant.comapₗ, LinearMap.coe_mk, AddHom.coe_mk, - LocallyConstant.coe_comap, Function.comp_apply] + simp only [πJ, LocallyConstant.comapₗ] exact (congr_fun (Products.evalFacProp C (· ∈ s) (Products.prop_of_isGood C (· ∈ s) hl)) _).symm /-- `π C (· ∈ s)` is finite for a finite set `s`. -/ diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean index 4b2e9628bc9211..9800928e9d2578 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean @@ -233,6 +233,7 @@ theorem C1_projOrd {x : I → Bool} (hx : x ∈ C1 C ho) : SwapTrue o (Proj (ord simp only [not_lt, Bool.not_eq_true, Order.succ_le_iff] at hsC exact (hsC h').symm +set_option backward.isDefEq.respectTransparency.types false in include hC in theorem CC_exact {f : LocallyConstant C ℤ} (hf : Linear_CC' C hsC ho f = 0) : ∃ y, πs C o y = f := by @@ -391,6 +392,7 @@ theorem span_sum : Set.range (eval C) = Set.range (Sum.elim EquivLike.range_comp (e := sum_equiv C hsC ho)] +set_option backward.isDefEq.respectTransparency.types false in theorem square_commutes : SumEval C ho ∘ Sum.inl = ModuleCat.ofHom (πs C o) ∘ eval (π C (ord I · < o)) := by ext l @@ -416,6 +418,7 @@ theorem Products.max_eq_o_cons_tail [Inhabited I] (l : Products I) (hl : l.val rw [← List.cons_head!_tail hl, hlh] simp [Tail] +set_option backward.isDefEq.respectTransparency.types false in theorem Products.max_eq_o_cons_tail' [Inhabited I] (l : Products I) (hl : l.val ≠ []) (hlh : l.val.head! = term I ho) (hlc : List.IsChain (· > ·) (term I ho :: l.Tail.val)) : l = ⟨term I ho :: l.Tail.val, hlc⟩ := by @@ -442,11 +445,13 @@ theorem GoodProducts.max_eq_o_cons_tail (l : MaxProducts C ho) : Products.max_eq_o_cons_tail ho l.val (List.ne_nil_of_mem l.prop.2) (head!_eq_o_of_maxProducts _ hsC ho l) +set_option backward.isDefEq.respectTransparency.types false in theorem Products.evalCons {I} [LinearOrder I] {C : Set (I → Bool)} {l : List I} {a : I} (hla : (a::l).IsChain (· > ·)) : Products.eval C ⟨a::l,hla⟩ = (e C a) * Products.eval C ⟨l,List.IsChain.sublist hla (List.tail_sublist (a::l))⟩ := by simp only [eval.eq_1, List.map, List.prod_cons] +set_option backward.isDefEq.respectTransparency.types false in theorem Products.max_eq_eval [Inhabited I] (l : Products I) (hl : l.val ≠ []) (hlh : l.val.head! = term I ho) : Linear_CC' C hsC ho (l.eval C) = l.Tail.eval (C' C ho) := by @@ -520,6 +525,7 @@ theorem good_lt_maxProducts (q : GoodProducts (π C (ord I · < o))) simp only [term, Ordinal.typein_enum] exact Products.prop_of_isGood C _ q.prop q.val.val.head! (List.head!_mem_self h) +set_option backward.isDefEq.respectTransparency.types false in include hC hsC in /-- Removing the leading `o` from a term of `MaxProducts C` yields a list which `isGood` with respect to diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean b/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean index 8598d72a995750..07a4607f0f0dd8 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean @@ -50,6 +50,7 @@ theorem GoodProducts.linearIndependentEmpty {I} [LinearOrder I] : /-- The empty list as a `Products` -/ def Products.nil : Products I := ⟨[], by simp only [List.isChain_nil]⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem Products.lt_nil_empty {I} [LinearOrder I] : { m : Products I | m < Products.nil } = ∅ := by ext ⟨m, hm⟩ refine ⟨fun h ↦ ?_, by tauto⟩ @@ -58,6 +59,7 @@ theorem Products.lt_nil_empty {I} [LinearOrder I] : { m : Products I | m < Produ instance {α : Type*} [TopologicalSpace α] [Nonempty α] : Nontrivial (LocallyConstant α ℤ) := ⟨0, 1, ne_of_apply_ne DFunLike.coe <| (Function.const_injective (β := ℤ)).ne zero_ne_one⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem Products.isGood_nil {I} [LinearOrder I] : Products.isGood ({fun _ ↦ false} : Set (I → Bool)) Products.nil := by intro h @@ -74,6 +76,7 @@ theorem Products.span_nil_eq_top {I} [LinearOrder I] : obtain rfl : x = default := by simp only [Set.default_coe_singleton, eq_iff_true_of_subsingleton] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/ noncomputable instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where @@ -149,6 +152,7 @@ noncomputable def range_equiv_smaller_toFun (o : Ordinal) (x : range (π C (ord I · < o))) : smaller C o := ⟨πs C o ↑x, x.val, x.property, rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem range_equiv_smaller_toFun_bijective (o : Ordinal) : Function.Bijective (range_equiv_smaller_toFun C o) := by dsimp +unfoldPartialApp [range_equiv_smaller_toFun] diff --git a/Mathlib/Topology/Category/Profinite/Product.lean b/Mathlib/Topology/Category/Profinite/Product.lean index 9867a77714c045..53f9493c34890f 100644 --- a/Mathlib/Topology/Category/Profinite/Product.lean +++ b/Mathlib/Topology/Category/Profinite/Product.lean @@ -74,8 +74,7 @@ theorem eq_of_forall_π_app_eq (a b : C) ext i specialize h ({i} : Finset ι) rw [Subtype.ext_iff] at h - simp only [π_app, ContinuousMap.precomp, ContinuousMap.coe_mk, - Set.MapsTo.val_restrict_apply] at h + simp only [π_app, ContinuousMap.precomp, ContinuousMap.coe_mk] at h exact congr_fun h ⟨i, Finset.mem_singleton.mpr rfl⟩ end IndexFunctor @@ -100,6 +99,7 @@ def indexCone (hC : IsCompact C) : Cone (indexFunctor hC) where variable (hC : IsCompact C) +set_option backward.isDefEq.respectTransparency.types false in instance isIso_indexCone_lift : IsIso ((limitConeIsLimit.{u, u} (indexFunctor hC)).lift (indexCone hC)) := haveI : CompactSpace C := by rwa [← isCompact_iff_compactSpace] diff --git a/Mathlib/Topology/Category/TopCat/Limits/Basic.lean b/Mathlib/Topology/Category/TopCat/Limits/Basic.lean index 1a991c87a70c7d..2e5322bef5807d 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Basic.lean @@ -85,6 +85,7 @@ instance topologicalSpaceConePtOfConeForget : TopologicalSpace (conePtOfConeForget c) := (⨅ j, (F.obj j).str.induced (c.π.app j)) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a functor `F : J ⥤ TopCat` and a cone `c : Cone (F ⋙ forget)` of the underlying functor to types, this is a cone for `F` whose point is `c.pt` with the infimum of the induced topologies by the maps `c.π.app j`. -/ @@ -99,6 +100,7 @@ def coneOfConeForget : Cone F where ext apply ConcreteCategory.congr_hom (c.π.naturality φ) } +set_option backward.isDefEq.respectTransparency.types false in /-- Given a functor `F : J ⥤ TopCat` and a cone `c : Cone (F ⋙ forget)` of the underlying functor to types, the limit of `F` is `c.pt` equipped with the infimum of the induced topologies by the maps `c.π.app j`. -/ @@ -139,6 +141,7 @@ theorem induced_of_isLimit : end IsLimit +set_option backward.isDefEq.respectTransparency.types false in lemma nonempty_isLimit_iff_eq_induced {F : J ⥤ TopCat.{u}} (c : Cone F) (hc : IsLimit ((forget).mapCone c)) : Nonempty (IsLimit c) ↔ c.pt.str = ⨅ j, (F.obj j).str.induced (c.π.app j) := by @@ -156,6 +159,7 @@ theorem limit_topology [HasLimit F] : (limit F).str = ⨅ j, (F.obj j).str.induced (limit.π F j) := induced_of_isLimit _ (limit.isLimit _) +set_option backward.isDefEq.respectTransparency.types false in lemma hasLimit_iff_small_sections : HasLimit F ↔ Small.{u} ((F ⋙ forget).sections) := by rw [← Types.hasLimit_iff_small_sections] @@ -198,6 +202,7 @@ instance topologicalSpaceCoconePtOfCoconeForget : TopologicalSpace (coconePtOfCoconeForget c) := (⨆ j, (F.obj j).str.coinduced (c.ι.app j)) +set_option backward.isDefEq.respectTransparency.types false in /-- Given a functor `F : J ⥤ TopCat` and a cocone `c : Cocone (F ⋙ forget)` of the underlying cocone of types, this is a cocone for `F` whose point is `c.pt` with the supremum of the coinduced topologies by the maps `c.ι.app j`. -/ @@ -213,6 +218,7 @@ def coconeOfCoconeForget : Cocone F where ext apply ConcreteCategory.congr_hom (c.ι.naturality φ) } +set_option backward.isDefEq.respectTransparency.types false in /-- Given a functor `F : J ⥤ TopCat` and a cocone `c : Cocone (F ⋙ forget)` of the underlying cocone of types, the colimit of `F` is `c.pt` equipped with the supremum of the coinduced topologies by the maps `c.ι.app j`. -/ @@ -237,6 +243,7 @@ variable (c : Cocone F) (hc : IsColimit c) include hc +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem coinduced_of_isColimit : c.pt.str = ⨆ j, (F.obj j).str.coinduced (c.ι.app j) := by @@ -271,6 +278,7 @@ lemma continuous_iff_of_isColimit {X : Type u'} [TopologicalSpace X] (f : c.pt end IsColimit +set_option backward.isDefEq.respectTransparency.types false in lemma nonempty_isColimit_iff_eq_coinduced (c : Cocone F) (hc : IsColimit ((forget).mapCocone c)) : Nonempty (IsColimit c) ↔ c.pt.str = ⨆ j, (F.obj j).str.coinduced (c.ι.app j) := by refine ⟨fun ⟨hc⟩ ↦ coinduced_of_isColimit _ hc, fun h ↦ ⟨?_⟩⟩ @@ -292,6 +300,7 @@ theorem colimit_isOpen_iff (F : J ⥤ TopCat.{u}) [HasColimit F] IsOpen U ↔ ∀ j, IsOpen (colimit.ι F j ⁻¹' U) := by apply isOpen_iff_of_isColimit _ (colimit.isColimit _) +set_option backward.isDefEq.respectTransparency.types false in lemma hasColimit_iff_small_colimitType : HasColimit F ↔ Small.{u} (F ⋙ forget).ColimitType := by rw [← Types.hasColimit_iff_small_colimitType] diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index 13a4314451693a..b250d026204b26 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -189,6 +189,7 @@ theorem prod_topology {X Y : TopCat.{u}} : simp [induced_compose] rfl +set_option backward.isDefEq.respectTransparency.types false in theorem range_prod_map {W X Y Z : TopCat.{u}} (f : W ⟶ Y) (g : X ⟶ Z) : Set.range (Limits.prod.map f g) = (Limits.prod.fst : Y ⨯ Z ⟶ _) ⁻¹' Set.range f ∩ @@ -232,6 +233,7 @@ end Prod protected def binaryCofan (X Y : TopCat.{u}) : BinaryCofan X Y := BinaryCofan.mk (ofHom ⟨Sum.inl, by fun_prop⟩) (ofHom ⟨Sum.inr, by fun_prop⟩) +set_option backward.isDefEq.respectTransparency.types false in /-- The constructed binary coproduct cofan in `TopCat` is the coproduct. -/ def binaryCofanIsColimit (X Y : TopCat.{u}) : IsColimit (TopCat.binaryCofan X Y) := by refine Limits.BinaryCofan.isColimitMk (fun s => ofHom diff --git a/Mathlib/Topology/Category/TopCat/OpenNhds.lean b/Mathlib/Topology/Category/TopCat/OpenNhds.lean index 58a92e4c2025d6..3db8792ca58e6c 100644 --- a/Mathlib/Topology/Category/TopCat/OpenNhds.lean +++ b/Mathlib/Topology/Category/TopCat/OpenNhds.lean @@ -59,12 +59,14 @@ instance (x : X) : Lattice (OpenNhds x) := le_sup_left := fun U V => @le_sup_left _ _ U.1.1 V.1.1 le_sup_right := fun U V => @le_sup_right _ _ U.1.1 V.1.1 } +set_option backward.isDefEq.respectTransparency.types false in instance (x : X) : OrderTop (OpenNhds x) where top := ⟨⊤, trivial⟩ le_top x := by cases x simp [le_def] +set_option backward.isDefEq.respectTransparency.types false in instance (x : X) : Inhabited (OpenNhds x) := ⟨⊤⟩ @@ -118,10 +120,12 @@ theorem map_id_obj (x : X) (U) : (map (𝟙 X) x).obj U = U := rfl theorem map_id_obj' (x : X) (U) (p) (q) : (map (𝟙 X) x).obj ⟨⟨U, p⟩, q⟩ = ⟨⟨U, p⟩, q⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem map_id_obj_unop (x : X) (U : (OpenNhds x)ᵒᵖ) : (map (𝟙 X) x).obj (unop U) = unop U := by simp +set_option backward.isDefEq.respectTransparency.types false in theorem op_map_id_obj (x : X) (U : (OpenNhds x)ᵒᵖ) : (map (𝟙 X) x).op.obj U = U := by simp /-- `Opens.map f` and `OpenNhds.map f` form a commuting square (up to natural isomorphism) diff --git a/Mathlib/Topology/Category/TopCat/Opens.lean b/Mathlib/Topology/Category/TopCat/Opens.lean index 903bdd670ef086..b1bb3933b9ecb8 100644 --- a/Mathlib/Topology/Category/TopCat/Opens.lean +++ b/Mathlib/Topology/Category/TopCat/Opens.lean @@ -386,6 +386,7 @@ lemma mem_functorObj_iff {X Y : TopCat.{u}} {f : X ⟶ Y} (hf : IsInducing f) (U conv_rhs => rw [← hf.map_functorObj U] rfl +set_option backward.isDefEq.respectTransparency.types false in lemma le_functorObj_iff {X Y : TopCat.{u}} {f : X ⟶ Y} (hf : IsInducing f) {U : Opens X} {V : Opens Y} : V ≤ hf.functorObj U ↔ (Opens.map f).obj V ≤ U := by obtain ⟨U, hU⟩ := U diff --git a/Mathlib/Topology/Category/TopCat/ULift.lean b/Mathlib/Topology/Category/TopCat/ULift.lean index d1f4ec38a06a55..26fe7b61ac6745 100644 --- a/Mathlib/Topology/Category/TopCat/ULift.lean +++ b/Mathlib/Topology/Category/TopCat/ULift.lean @@ -56,6 +56,7 @@ with the one defined on categories of types. -/ def uliftFunctorCompForgetIso : uliftFunctor.{v, u} ⋙ forget TopCat.{max u v} ≅ forget TopCat.{u} ⋙ CategoryTheory.uliftFunctor.{v, u} := Iso.refl _ +set_option backward.isDefEq.respectTransparency.types false in /-- The `ULift` functor on categories of topological spaces is fully faithful. -/ def uliftFunctorFullyFaithful : uliftFunctor.{v, u}.FullyFaithful where preimage f := ofHom ⟨ULift.down ∘ f ∘ ULift.up, by fun_prop⟩ @@ -68,6 +69,7 @@ instance : uliftFunctor.{v, u}.Faithful := open Limits +set_option backward.isDefEq.respectTransparency.types false in instance : PreservesLimitsOfSize.{w', w} uliftFunctor.{v, u} := by refine ⟨⟨fun {K} ↦ ⟨fun {c} hc ↦ ?_⟩⟩⟩ rw [nonempty_isLimit_iff_eq_induced] diff --git a/Mathlib/Topology/Category/TopPair.lean b/Mathlib/Topology/Category/TopPair.lean index b81ecc4af21ae4..f0b44856218c91 100644 --- a/Mathlib/Topology/Category/TopPair.lean +++ b/Mathlib/Topology/Category/TopPair.lean @@ -100,6 +100,7 @@ abbrev diag : TopCat.{u} ⥤ TopPair.{u} where obj X := TopPair.of (𝟙 X) Topology.IsEmbedding.id map f := TopPair.ofHom f f +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The inclusion functor is left adjoint to the projection to the first component. -/ @[simps] @@ -130,6 +131,9 @@ structure Homotopy (f g : X ⟶ Y) where /-- The proof that the homotopies fit into a commutative square with the maps of the pairs. -/ w : X.map ▷ _ ≫ fst.h = snd.h ≫ Y.map := by cat_disch +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in attribute [reassoc, elementwise] Homotopy.w attribute [local simp] Homotopy.w Homotopy.w_apply @@ -152,6 +156,7 @@ def refl (f : X ⟶ Y) : Homotopy f f where instance : Inhabited (Homotopy (𝟙 X) (𝟙 X)) := ⟨Homotopy.refl _⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a `Homotopy f₀ f₁`, we can define a `Homotopy f₁ f₀` by `TopCat.Homotopy.symm` on the first and second components. -/ @@ -168,6 +173,7 @@ theorem symm_bijective {f₀ f₁ : X ⟶ Y} : Function.Bijective (Homotopy.symm : Homotopy f₀ f₁ → Homotopy f₁ f₀) := Function.bijective_iff_has_inverse.mpr ⟨_, symm_symm, symm_symm⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Given `Homotopy f₀ f₁` and `Homotopy f₁ f₂`, we can define a `Homotopy f₀ f₂` by `TopCat.Homotopy.trans` on the first and second components. diff --git a/Mathlib/Topology/Category/UniformSpace.lean b/Mathlib/Topology/Category/UniformSpace.lean index bfc27e87c775f0..46335ec8599f64 100644 --- a/Mathlib/Topology/Category/UniformSpace.lean +++ b/Mathlib/Topology/Category/UniformSpace.lean @@ -164,19 +164,23 @@ instance instFunLike (X Y : CpltSepUniformSpace) : coe := Subtype.val coe_injective _ _ h := Subtype.ext h +set_option backward.isDefEq.respectTransparency.types false in /-- The concrete category instance on `CpltSepUniformSpace`. -/ instance concreteCategory : ConcreteCategory CpltSepUniformSpace ({ f : · → · // UniformContinuous f }) := inferInstanceAs <| ConcreteCategory (InducedCategory _ toUniformSpace) _ +set_option backward.isDefEq.respectTransparency.types false in instance hasForgetToUniformSpace : HasForget₂ CpltSepUniformSpace UniformSpaceCat := inferInstanceAs <| HasForget₂ (InducedCategory _ toUniformSpace) _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem hom_comp {X Y Z : CpltSepUniformSpace} (f : X ⟶ Y) (g : Y ⟶ Z) : ConcreteCategory.hom (f ≫ g) = ⟨g ∘ f, g.hom.hom.prop.comp f.hom.hom.prop⟩ := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem hom_id (X : CpltSepUniformSpace) : ConcreteCategory.hom (𝟙 X : X ⟶ X) = ⟨id, uniformContinuous_id⟩ := @@ -195,6 +199,7 @@ open UniformSpace open CpltSepUniformSpace +set_option backward.isDefEq.respectTransparency.types false in /-- The functor turning uniform spaces into complete separated uniform spaces. -/ @[simps map] noncomputable def completionFunctor : UniformSpaceCat ⥤ CpltSepUniformSpace where diff --git a/Mathlib/Topology/CompactOpen.lean b/Mathlib/Topology/CompactOpen.lean index f9a1d7a83bf422..93011dc08b89df 100644 --- a/Mathlib/Topology/CompactOpen.lean +++ b/Mathlib/Topology/CompactOpen.lean @@ -358,6 +358,7 @@ theorem tendsto_compactOpen_iff_forall {ι : Type*} {l : Filter ι} (F : ι → rw [compactOpen_eq_iInf_induced] simp [nhds_iInf, nhds_induced, Filter.tendsto_comap_iff, Function.comp_def] +set_option backward.isDefEq.respectTransparency false in /-- A family `F` of functions in `C(X, Y)` converges in the compact-open topology, if and only if it converges in the compact-open topology on each compact subset of `X`. -/ theorem exists_tendsto_compactOpen_iff_forall [WeaklyLocallyCompactSpace X] [T2Space Y] diff --git a/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean b/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean index 4ace9a549bdba9..81be1cd54b4d36 100644 --- a/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean +++ b/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean @@ -60,6 +60,7 @@ instance {S} [DistribSMul S R] [SMulCommClass R S R] : SMulCommClass (Matrix (Fin 2) (Fin 2) R) S (R × R) := (LinearEquiv.finTwoArrow R R).symm.smulCommClass _ _ +set_option backward.isDefEq.respectTransparency.types false in @[deprecated "use Fin 2 → R instead" (since := "2026-04-19")] lemma Matrix.fin_two_smul_prod (g : Matrix (Fin 2) (Fin 2) R) (v : R × R) : g • v = (g 0 0 * v.1 + g 0 1 * v.2, g 1 0 * v.1 + g 1 1 * v.2) := by @@ -110,6 +111,7 @@ lemma equivProjectivization_apply_coe (t : K) : equivProjectivization K t = mk K ![t, 1] (by simp) := rfl +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma equivProjectivization_symm_apply_mk (v : Fin 2 → K) (h : v ≠ 0) : (equivProjectivization K).symm (mk K v h) = if v 1 = 0 then ∞ else (v 1)⁻¹ * v 0 := by @@ -130,6 +132,7 @@ lemma equivProjectivization_smul {g : GL (Fin 2) K} (x : OnePoint K) : equivProjectivization K (g • x) = g • equivProjectivization K x := by rw [Equiv.smul_def, Equiv.apply_symm_apply] +set_option backward.isDefEq.respectTransparency.types false in lemma smul_infty_def {g : GL (Fin 2) K} : g • ∞ = (equivProjectivization K).symm (.mk K ![g 0 0, g 1 0] (fun h ↦ by simpa [det_fin_two, show g 0 0 = 0 from congr_fun h 0, show g 1 0 = 0 from congr_fun h 1] diff --git a/Mathlib/Topology/Compactification/StoneCech.lean b/Mathlib/Topology/Compactification/StoneCech.lean index c6b25c9fc81e38..da20885e51e243 100644 --- a/Mathlib/Topology/Compactification/StoneCech.lean +++ b/Mathlib/Topology/Compactification/StoneCech.lean @@ -245,6 +245,7 @@ instance [Inhabited α] : Inhabited (PreStoneCech α) := def preStoneCechUnit (x : α) : PreStoneCech α := Quot.mk _ (pure x : Ultrafilter α) +set_option backward.isDefEq.respectTransparency false in theorem continuous_preStoneCechUnit : Continuous (preStoneCechUnit : α → PreStoneCech α) := continuous_iff_ultrafilter.mpr fun x g gx ↦ by have : (g.map pure).toFilter ≤ 𝓝 g := by @@ -370,6 +371,7 @@ variable [CompactSpace β] def stoneCechExtend : StoneCech α → β := T2Quotient.lift (continuous_preStoneCechExtend hg) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma stoneCechExtend_extends : stoneCechExtend hg ∘ stoneCechUnit = g := by ext x diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index 46fd7adce3589c..b71094c630ee39 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -671,7 +671,7 @@ variable (X) in /-- Sets that are contained in a compact set form a bornology. Its `cobounded` filter is `Filter.cocompact`. See also `Bornology.relativelyCompact` the bornology of sets with compact closure. -/ -@[implicit_reducible] +@[instance_reducible] def inCompact : Bornology X where cobounded := Filter.cocompact X le_cofinite := Filter.cocompact_le_cofinite diff --git a/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean b/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean index 18f43c237d61be..ad1d65b950c285 100644 --- a/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean +++ b/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean @@ -161,7 +161,6 @@ the intersection `K ∩ A` is closed in `K`. -/ lemma isClosed_iff {A : Set (𝐤X)} : IsClosed A ↔ ∀ (K : Set X), IsCompact K → IsClosed (K ↓∩ .mk X ⁻¹' A) := by simp_rw [isClosed_coinduced, isClosed_iSup_iff, ← isClosed_coinduced] - rfl lemma continuous_dom_iff {f : 𝐤X → Y} : Continuous f ↔ diff --git a/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean b/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean index c3f71b5414bce7..0f87815b0fd554 100644 --- a/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean +++ b/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean @@ -61,7 +61,7 @@ topology, continuous. Note: this definition should be used with an explicit universe parameter `u` for the size of the compact Hausdorff spaces mapping to `X`. -/ -@[implicit_reducible] +@[instance_reducible] def TopologicalSpace.compactlyGenerated (X : Type w) [TopologicalSpace X] : TopologicalSpace X := let f : (Σ (i : (S : CompHaus.{u}) × C(S, X)), i.fst) → X := fun ⟨⟨_, i⟩, s⟩ ↦ i s coinduced f inferInstance diff --git a/Mathlib/Topology/Compactness/Lindelof.lean b/Mathlib/Topology/Compactness/Lindelof.lean index 91b7679bff0d00..d7ccffdcb649fc 100644 --- a/Mathlib/Topology/Compactness/Lindelof.lean +++ b/Mathlib/Topology/Compactness/Lindelof.lean @@ -67,6 +67,7 @@ theorem IsLindelof.compl_mem_sets_of_nhdsWithin (hs : IsLindelof s) {f : Filter rw [← disjoint_principal_right, disjoint_right_comm, (basis_sets _).disjoint_iff_left] exact hf x hx +set_option backward.isDefEq.respectTransparency false in /-- If `p : Set X → Prop` is stable under restriction and union, and each point `x` of a Lindelöf set `s` has a neighborhood `t` within `s` such that `p t`, then `p s` holds. -/ @[elab_as_elim] diff --git a/Mathlib/Topology/Compactness/LocallyFinite.lean b/Mathlib/Topology/Compactness/LocallyFinite.lean index 8d6f5095146f22..62ecb7b52f316e 100644 --- a/Mathlib/Topology/Compactness/LocallyFinite.lean +++ b/Mathlib/Topology/Compactness/LocallyFinite.lean @@ -45,7 +45,7 @@ theorem finite_of_compact [CompactSpace X] {f : ι → Set X} /-- If `X` is a compact space, then a locally finite family of nonempty sets of `X` can have only finitely many elements, `Fintype` version. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def fintypeOfCompact [CompactSpace X] {f : ι → Set X} (hf : LocallyFinite f) (hne : ∀ i, (f i).Nonempty) : Fintype ι := fintypeOfFiniteUniv (hf.finite_of_compact hne) diff --git a/Mathlib/Topology/Compactness/SigmaCompact.lean b/Mathlib/Topology/Compactness/SigmaCompact.lean index 7d412e5a0dc409..7adad95658a47b 100644 --- a/Mathlib/Topology/Compactness/SigmaCompact.lean +++ b/Mathlib/Topology/Compactness/SigmaCompact.lean @@ -280,7 +280,7 @@ protected theorem LocallyFinite.countable_univ {f : ι → Set X} (hf : LocallyF /-- If `f : ι → Set X` is a locally finite covering of a σ-compact topological space by nonempty sets, then the index type `ι` is encodable. -/ -@[implicit_reducible] +@[instance_reducible] protected noncomputable def LocallyFinite.encodable {ι : Type*} {f : ι → Set X} (hf : LocallyFinite f) (hne : ∀ i, (f i).Nonempty) : Encodable ι := @Encodable.ofEquiv _ _ (hf.countable_univ hne).toEncodable (Equiv.Set.univ _).symm diff --git a/Mathlib/Topology/Connected/Clopen.lean b/Mathlib/Topology/Connected/Clopen.lean index 35b4c706784bc4..4a8f04efceb89d 100644 --- a/Mathlib/Topology/Connected/Clopen.lean +++ b/Mathlib/Topology/Connected/Clopen.lean @@ -501,7 +501,7 @@ end Preconnected section connectedComponentSetoid /-- The setoid of connected components of a topological space -/ -@[implicit_reducible] +@[instance_reducible] def connectedComponentSetoid (α : Type*) [TopologicalSpace α] : Setoid α := ⟨fun x y => connectedComponent x = connectedComponent y, ⟨fun x => by trivial, fun h1 => h1.symm, fun h1 h2 => h1.trans h2⟩⟩ diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index 37d9f134d59266..aacae77f952a0b 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -99,7 +99,7 @@ theorem Joined.inv {G : Type*} [Inv G] [TopologicalSpace G] [ContinuousInv G] variable (X) /-- The setoid corresponding the equivalence relation of being joined by a continuous path. -/ -@[implicit_reducible] +@[instance_reducible] def pathSetoid : Setoid X where r := Joined iseqv := Equivalence.mk Joined.refl Joined.symm Joined.trans diff --git a/Mathlib/Topology/Constructible.lean b/Mathlib/Topology/Constructible.lean index fd8072bc572604..3ec4d6c380e99b 100644 --- a/Mathlib/Topology/Constructible.lean +++ b/Mathlib/Topology/Constructible.lean @@ -500,6 +500,7 @@ lemma IsLocallyConstructible.inter_of_isOpen_isCompact variable {ι : Type*} {U : ι → Opens X} +set_option backward.isDefEq.respectTransparency false in lemma IsLocallyConstructible.of_isOpenCover (hU : IsOpenCover U) (H : ∀ i, IsLocallyConstructible ((U i : Set X) ↓∩ s)) : IsLocallyConstructible s := by diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index de701393db9592..e085e50dd1493d 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -299,6 +299,7 @@ def of : X ≃ CofiniteTopology X := (WithTopology.equiv _ _).symm instance [Inhabited X] : Inhabited (CofiniteTopology X) where default := of default +set_option backward.isDefEq.respectTransparency false in theorem isOpen_iff {s : Set (CofiniteTopology X)} : IsOpen s ↔ s.Nonempty → sᶜ.Finite := by simp_rw [isOpen_coinduced, TopologicalSpace.cofinite, isOpen_mk, ← Set.preimage_compl, WithTopology.preimage_toTopology, image_nonempty, diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index 4bfea412958fbd..2d79e1675aa029 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -947,6 +947,9 @@ def emptySum [IsEmpty Y] : Y ⊕ X ≃ₜ X := (sumComm Y X).trans (sumEmpty X Y variable {W X Y Z} +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- `(X ⊕ Y) × Z` is homeomorphic to `X × Z ⊕ Y × Z`. -/ @[simps!] def sumProdDistrib : (X ⊕ Y) × Z ≃ₜ (X × Z) ⊕ (Y × Z) := diff --git a/Mathlib/Topology/ContinuousMap/Basic.lean b/Mathlib/Topology/ContinuousMap/Basic.lean index 876e093cb0da1c..6aad422e4f6f62 100644 --- a/Mathlib/Topology/ContinuousMap/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Basic.lean @@ -110,6 +110,7 @@ theorem const_apply (b : β) (a : α) : const α b a = b := rfl /-- The composition of continuous maps, as a continuous map. -/ +@[implicit_reducible] def comp (f : C(β, γ)) (g : C(α, β)) : C(α, γ) where toFun := f ∘ g diff --git a/Mathlib/Topology/ContinuousMap/Compact.lean b/Mathlib/Topology/ContinuousMap/Compact.lean index 9fe734c25b057f..5565d1fb17d209 100644 --- a/Mathlib/Topology/ContinuousMap/Compact.lean +++ b/Mathlib/Topology/ContinuousMap/Compact.lean @@ -68,6 +68,9 @@ theorem isUniformEmbedding_equivBoundedOfCompact : IsUniformEmbedding (equivBoun { isUniformInducing_equivBoundedOfCompact α β with injective := (equivBoundedOfCompact α β).injective } +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- When `α` is compact, the bounded continuous maps `α →ᵇ 𝕜` are additively equivalent to `C(α, 𝕜)`. -/ diff --git a/Mathlib/Topology/ContinuousMap/CompactlySupported.lean b/Mathlib/Topology/ContinuousMap/CompactlySupported.lean index 588c39cfb1b772..3c40233c08de55 100644 --- a/Mathlib/Topology/ContinuousMap/CompactlySupported.lean +++ b/Mathlib/Topology/ContinuousMap/CompactlySupported.lean @@ -667,6 +667,7 @@ open NNReal namespace CompactlySupportedContinuousMap +set_option backward.isDefEq.respectTransparency.types false in protected lemma exists_add_of_le {f₁ f₂ : C_c(α, ℝ≥0)} (h : f₁ ≤ f₂) : ∃ (g : C_c(α, ℝ≥0)), f₁ + g = f₂ := by refine ⟨⟨f₂.1 - f₁.1, ?_⟩, ?_⟩ @@ -793,6 +794,7 @@ end toNNRealLinear section toRealPositiveLinear +set_option backward.isDefEq.respectTransparency false in /-- For a positive linear functional `Λ : C_c(α, ℝ≥0) → ℝ≥0`, define a positive `ℝ`-linear map. -/ noncomputable def toRealPositiveLinear (Λ : C_c(α, ℝ≥0) →ₗ[ℝ≥0] ℝ≥0) : C_c(α, ℝ) →ₚ[ℝ] ℝ := PositiveLinearMap.mk₀ diff --git a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean index 69d07a5fe3f10b..f1894ab67f93bf 100644 --- a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean +++ b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean @@ -194,6 +194,7 @@ lemma mkD_of_not_continuousOn {s : Set X} [Zero s] {f : X → R} {g : C(s, R)₀ rw [continuousOn_iff_continuous_restrict] at hf exact mkD_of_not_continuous hf +set_option backward.isDefEq.respectTransparency false in lemma mkD_apply_of_continuousOn {s : Set X} [Zero s] {f : X → R} {g : C(s, R)₀} {x : s} (hf : ContinuousOn f s) (hf₀ : f (0 : s) = 0) : mkD (s.restrict f) g x = f x := by @@ -443,6 +444,7 @@ def nonUnitalStarAlgHom_precomp (f : C(X, Y)₀) : C(Y, R)₀ →⋆ₙₐ[R] C( map_star' _ := rfl map_smul' _ _ := rfl +set_option backward.isDefEq.respectTransparency false in variable (X) in /-- The functor `C(X, ·)₀` from non-unital topological star algebras (with non-unital continuous star homomorphisms) to non-unital star algebras. -/ diff --git a/Mathlib/Topology/ContinuousMap/Sigma.lean b/Mathlib/Topology/ContinuousMap/Sigma.lean index 07ceb538882a12..22dd4cc1e02274 100644 --- a/Mathlib/Topology/ContinuousMap/Sigma.lean +++ b/Mathlib/Topology/ContinuousMap/Sigma.lean @@ -71,6 +71,9 @@ theorem exists_lift_sigma (f : C(X, Σ i, Y i)) : ∃ i g, f = (sigmaMk i).comp variable (X Y) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- Homeomorphism between the type `C(X, Σ i, Y i)` of continuous maps from a connected topological space to the disjoint union of a family of topological spaces and the disjoint union of the types of continuous maps `C(X, Y i)`. diff --git a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean index 2b8c165c02034c..e4ff06a7424a94 100644 --- a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean @@ -110,7 +110,7 @@ theorem comp_attachBound_mem_closure (A : Subalgebra ℝ C(X, ℝ)) (f : A) _ ?_ frequently_mem_polynomials -- but need to show that those pullbacks are actually in `A`. rintro _ ⟨g, ⟨-, rfl⟩⟩ - simp only [SetLike.mem_coe, AlgHom.coe_toRingHom, compRightContinuousMap_apply, + simp only [SetLike.mem_coe, AlgHom.coe_toRingHom, Polynomial.toContinuousMapOnAlgHom_apply] apply polynomial_comp_attachBound_mem @@ -365,6 +365,7 @@ state and prove the Stone-Weierstrass theorem, in favor of using `StarSubalgebra which didn't exist at the time Stone-Weierstrass was written. -/ +set_option backward.isDefEq.respectTransparency false in /-- If a star subalgebra of `C(X, 𝕜)` separates points, then the real subalgebra of its purely real-valued elements also separates points. -/ theorem Subalgebra.SeparatesPoints.rclike_to_real {A : StarSubalgebra 𝕜 C(X, 𝕜)} @@ -393,6 +394,7 @@ theorem Subalgebra.SeparatesPoints.rclike_to_real {A : StarSubalgebra 𝕜 C(X, variable [CompactSpace X] +set_option backward.isDefEq.respectTransparency false in /-- The Stone-Weierstrass approximation theorem, `RCLike` version, that a star subalgebra `A` of `C(X, 𝕜)`, where `X` is a compact topological space and `RCLike 𝕜`, is dense if it separates points. -/ @@ -589,6 +591,7 @@ lemma ker_evalStarAlgHom_inter_adjoin_id (s : Set 𝕜) (h0 : 0 ∈ s) : refine fun hf ↦ ⟨?_, nonUnitalStarAlgebraAdjoin_id_subset_ker_evalStarAlgHom h0 hf⟩ exact adjoin_le_starAlgebra_adjoin _ _ hf +set_option backward.isDefEq.respectTransparency false in -- the statement should be in terms of nonunital subalgebras, but we lack API open RingHom Filter Topology in theorem AlgHom.closure_ker_inter {F S K A : Type*} [CommRing K] [Ring A] [Algebra K A] diff --git a/Mathlib/Topology/Convenient/GeneratedBy.lean b/Mathlib/Topology/Convenient/GeneratedBy.lean index b7523666776849..695877a51c242e 100644 --- a/Mathlib/Topology/Convenient/GeneratedBy.lean +++ b/Mathlib/Topology/Convenient/GeneratedBy.lean @@ -47,7 +47,7 @@ namespace TopologicalSpace /-- Given a family of topological spaces `X i`, the `X`-generated topology on a topological space `Y` is the topology that is coinduced by all continuous maps `X i → Y`. -/ -@[implicit_reducible] +@[instance_reducible] def generatedBy : TopologicalSpace Y := ⨆ (i : ι) (f : C(X i, Y)), coinduced f inferInstance diff --git a/Mathlib/Topology/Covering/Basic.lean b/Mathlib/Topology/Covering/Basic.lean index ad257b2dbc7685..dca87e66f9f07e 100644 --- a/Mathlib/Topology/Covering/Basic.lean +++ b/Mathlib/Topology/Covering/Basic.lean @@ -96,6 +96,7 @@ noncomputable def toTrivialization {x : X} [Nonempty I] (h : IsEvenlyCovered f x theorem mem_toTrivialization_baseSet {x : X} [Nonempty I] (h : IsEvenlyCovered f x I) : x ∈ h.toTrivialization.baseSet := h.2.choose_spec.1 +set_option backward.isDefEq.respectTransparency.types false in theorem toTrivialization_apply {x : E} [Nonempty I] (h : IsEvenlyCovered f (f x) I) : (h.toTrivialization x).2 = ⟨x, rfl⟩ := h.fiberHomeomorph.symm.injective <| by @@ -139,6 +140,7 @@ theorem of_preimage_eq_empty [IsEmpty I] {x : X} {U : Set X} (hUx : U ∈ 𝓝 x have := Set.isEmpty_coe_sort.mpr hfV ⟨inferInstance, _, hxV, hV, hfV ▸ isOpen_empty, .empty, isEmptyElim⟩ +set_option backward.isDefEq.respectTransparency false in theorem restrictPreimage {x : X} (hxs : x ∈ s) (h : IsEvenlyCovered f x I) : IsEvenlyCovered (s.restrictPreimage f) ⟨x, hxs⟩ I := have ⟨inst, U, hxU, hU, hfU, H, hH⟩ := h diff --git a/Mathlib/Topology/Covering/Quotient.lean b/Mathlib/Topology/Covering/Quotient.lean index 7296d6dae34a9d..b231b4ac28fed6 100644 --- a/Mathlib/Topology/Covering/Quotient.lean +++ b/Mathlib/Topology/Covering/Quotient.lean @@ -103,6 +103,7 @@ noncomputable def fiberEquivGroup {x : X} (e : f ⁻¹' {x}) : f ⁻¹' {x} ≃ @[simp] theorem fiberEquivGroup_self {x : X} (e : f ⁻¹' {x}) : hf.fiberEquivGroup e e = 1 := (Equiv.apply_eq_iff_eq_symm_apply _).mpr <| Subtype.ext (one_smul ..).symm +set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem fiberEquivGroup_eq_iff {x : X} (e e' : f ⁻¹' {x}) (g : G) : hf.fiberEquivGroup e e' = g ↔ e' = g • (e : E) := by rw [fiberEquivGroup, Equiv.symm_apply_eq, Equiv.ofBijective_apply, Subtype.mk.injEq] diff --git a/Mathlib/Topology/Defs/Filter.lean b/Mathlib/Topology/Defs/Filter.lean index 9dadbcb88ff98e..727d0eed71d4e3 100644 --- a/Mathlib/Topology/Defs/Filter.lean +++ b/Mathlib/Topology/Defs/Filter.lean @@ -231,7 +231,7 @@ def specializationPreorder : Preorder X := lt := fun x y => y ⤳ x ∧ ¬x ⤳ y } /-- A `setoid` version of `Inseparable`, used to define the `SeparationQuotient`. -/ -@[implicit_reducible] +@[instance_reducible] def inseparableSetoid : Setoid X := { Setoid.comap 𝓝 ⊥ with r := Inseparable } /-- The quotient of a topological space by its `inseparableSetoid`. Also called the Kolmogorov diff --git a/Mathlib/Topology/Defs/Induced.lean b/Mathlib/Topology/Defs/Induced.lean index c652bd260cf68d..7526293e644df3 100644 --- a/Mathlib/Topology/Defs/Induced.lean +++ b/Mathlib/Topology/Defs/Induced.lean @@ -60,7 +60,7 @@ variable {X Y : Type*} the induced topology on `X` is the collection of sets that are preimages of some open set in `Y`. This is the coarsest topology that makes `f` continuous. -/ -@[implicit_reducible] +@[instance_reducible] def induced (f : X → Y) (t : TopologicalSpace Y) : TopologicalSpace X where IsOpen s := ∃ t, IsOpen t ∧ f ⁻¹' t = s isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩ @@ -81,7 +81,7 @@ instance _root_.instTopologicalSpaceSubtype {p : X → Prop} [t : TopologicalSpa the coinduced topology on `Y` is defined such that `s : Set Y` is open if the preimage of `s` is open. This is the finest topology that makes `f` continuous. -/ -@[implicit_reducible] +@[instance_reducible] def coinduced (f : X → Y) (t : TopologicalSpace X) : TopologicalSpace Y where IsOpen s := IsOpen (f ⁻¹' s) isOpen_univ := t.isOpen_univ diff --git a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean index 6bb4b5c2385ba4..7a2048708bf28d 100644 --- a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean +++ b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean @@ -247,6 +247,7 @@ protected theorem lowerSemicontinuous (s : Set α) : simpa only [UniformOnFun.tendsto_iff_tendstoUniformlyOn, mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, tendstoUniformlyOn_singleton_iff_tendsto] using! @tendsto_id _ (𝓝 f) +set_option backward.isDefEq.respectTransparency false in /-- The map `(eVariationOn · s)` is lower semicontinuous for uniform convergence on `s`. -/ theorem lowerSemicontinuous_uniformOn (s : Set α) : LowerSemicontinuous fun f : α →ᵤ[{s}] E => eVariationOn f s := fun f ↦ by diff --git a/Mathlib/Topology/EMetricSpace/Defs.lean b/Mathlib/Topology/EMetricSpace/Defs.lean index b9dbd634ed6d89..c1fcc7dfde2fd7 100644 --- a/Mathlib/Topology/EMetricSpace/Defs.lean +++ b/Mathlib/Topology/EMetricSpace/Defs.lean @@ -472,7 +472,7 @@ theorem ordConnected_setOf_eball_subset (x : α) (s : Set α) : OrdConnected { r ⟨fun _ _ _ h₁ _ h₂ => (eball_subset_eball h₂.2).trans h₁⟩ /-- Relation “two points are at a finite edistance” is an equivalence relation. -/ -@[implicit_reducible] +@[instance_reducible] def edistLtTopSetoid : Setoid α where r x y := edist x y < ⊤ iseqv := diff --git a/Mathlib/Topology/EMetricSpace/PairReduction.lean b/Mathlib/Topology/EMetricSpace/PairReduction.lean index 43ef78203069fd..a2c61a6f533307 100644 --- a/Mathlib/Topology/EMetricSpace/PairReduction.lean +++ b/Mathlib/Topology/EMetricSpace/PairReduction.lean @@ -243,6 +243,7 @@ lemma one_le_radius_logSizeBallSeq (hJ : J.Nonempty) (ha : 1 < a) (i : ℕ) : | 0 => exact one_le_logSizeRadius ha | i + 1 => exact one_le_logSizeRadius ha +set_option backward.isDefEq.respectTransparency false in lemma point_mem_finset_logSizeBallSeq (hJ : J.Nonempty) (i : ℕ) (h : (logSizeBallSeq J hJ a c i).finset.Nonempty) : (logSizeBallSeq J hJ a c i).point ∈ (logSizeBallSeq J hJ a c i).finset := by @@ -357,6 +358,7 @@ lemma logSizeRadius_le_card_smallBall (hJ : J.Nonempty) (i : ℕ) (ha : 1 < a) : (point_mem_finset_logSizeBallSeq hJ _ h) simp [h] +set_option backward.isDefEq.respectTransparency false in lemma card_pairSet_le (ha : 1 < a) : #(pairSet J a c) ≤ a * #J := by wlog hJ : J.Nonempty · simp [Finset.not_nonempty_iff_eq_empty.mp hJ] diff --git a/Mathlib/Topology/FiberBundle/Basic.lean b/Mathlib/Topology/FiberBundle/Basic.lean index bddcb12e1ae666..9128c4466d1ebd 100644 --- a/Mathlib/Topology/FiberBundle/Basic.lean +++ b/Mathlib/Topology/FiberBundle/Basic.lean @@ -272,6 +272,7 @@ theorem totalSpaceMk_isClosedEmbedding [T1Space B] (x : B) : rw [TotalSpace.range_mk] exact isClosed_singleton.preimage <| continuous_proj F E⟩ +set_option backward.isDefEq.respectTransparency false in /-- An arbitrary homeomorphism between any fiber and the model fiber. This is useful to transfer topological properties of the model fiber. -/ noncomputable def homeomorphAt (b : B) : E b ≃ₜ F := @@ -491,6 +492,7 @@ theorem mem_trivChange_source (i j : ι) (p : B × F) : rw [trivChange, mem_prod] simp +set_option backward.isDefEq.respectTransparency false in /-- Associate to a trivialization index `i : ι` the corresponding trivialization, i.e., a bijection between `proj ⁻¹ (baseSet i)` and `baseSet i × F`. As the fiber above `x` is `F` but read in the chart with index `index_at x`, the trivialization in the fiber above x is by definition the @@ -661,6 +663,7 @@ theorem localTriv_apply (p : Z.TotalSpace) : (Z.localTriv i) p = ⟨p.1, Z.coordChange (Z.indexAt p.1) i p.1 p.2⟩ := rfl +set_option backward.isDefEq.respectTransparency false in @[simp, mfld_simps] theorem localTrivAt_apply (p : Z.TotalSpace) : (Z.localTrivAt p.1) p = ⟨p.1, p.2⟩ := by rw [localTrivAt, localTriv_apply, coordChange_self] @@ -762,7 +765,7 @@ variable {F E} variable (a : FiberPrebundle F E) {e : Pretrivialization F (π F E)} /-- Topology on the total space that will make the prebundle into a bundle. -/ -@[implicit_reducible] +@[instance_reducible] def totalSpaceTopology (a : FiberPrebundle F E) : TopologicalSpace (TotalSpace F E) := ⨆ (e : Pretrivialization F (π F E)) (_ : e ∈ a.pretrivializationAtlas), coinduced e.setSymm instTopologicalSpaceSubtype @@ -844,7 +847,7 @@ number of "pretrivializations" identifying parts of `E` with product spaces `U establishes that for the topology constructed on the sigma-type using `FiberPrebundle.totalSpaceTopology`, these "pretrivializations" are actually "trivializations" (i.e., homeomorphisms with respect to the constructed topology). -/ -@[implicit_reducible] +@[instance_reducible] def toFiberBundle : @FiberBundle B F _ _ E a.totalSpaceTopology _ := let _ := a.totalSpaceTopology { totalSpaceMk_isInducing' := fun b ↦ a.inducing_totalSpaceMk_of_inducing_comp b diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index 98b4083007ac0f..a3a215afae4ff9 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -65,6 +65,7 @@ def trivialization : Trivialization F (π F (Bundle.Trivial B F)) where proj_toFun _ _ := rfl set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in @[simp] lemma trivialization_symm_apply [Zero F] (b : B) (f : F) : (trivialization B F).symm b f = f := by simp [trivialization, homeomorphProd, TotalSpace.toProd, Trivialization.symm, @@ -263,7 +264,7 @@ instance [∀ x : B, TopologicalSpace (E x)] : ∀ x : B', TopologicalSpace ((f variable [TopologicalSpace B'] [TopologicalSpace (TotalSpace F E)] --- adding `@[implicit_reducible]` causes downstream breakage +-- adding `@[instance_reducible]` causes downstream breakage set_option warn.classDefReducibility false in /-- Definition of `Pullback.TotalSpace.topologicalSpace`, which we make irreducible. -/ irreducible_def pullbackTopology : TopologicalSpace (TotalSpace F (f *ᵖ E)) := @@ -303,6 +304,7 @@ theorem Pullback.continuous_totalSpaceMk [∀ x, TopologicalSpace (E x)] [FiberB variable {E F} variable [∀ _b, Nonempty (E _b)] {K : Type U} [FunLike K B' B] [ContinuousMapClass K B' B] +set_option backward.isDefEq.respectTransparency false in /-- A fiber bundle trivialization can be pulled back to a trivialization on the pullback bundle. -/ @[simps] noncomputable def Bundle.Trivialization.pullback (e : Trivialization F (π F E)) (f : K) : diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index 11e93196721c24..7d3ea204c7b0ff 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -880,6 +880,7 @@ theorem frontier_preimage (e : Trivialization F proj) (s : Set B) : rw [← (e.isImage_preimage_prod s).frontier.preimage_eq, frontier_prod_univ_eq, (e.isImage_preimage_prod _).preimage_eq, e.source_eq, preimage_inter] +set_option backward.isDefEq.respectTransparency false in open scoped Classical in /-- Given two bundle trivializations `e`, `e'` of `proj : Z → B` and a set `s : Set B` such that the base sets of `e` and `e'` intersect `frontier s` on the same set and `e p = e' p` whenever diff --git a/Mathlib/Topology/FiberPartition.lean b/Mathlib/Topology/FiberPartition.lean index 56c7a52991016e..4f7a87c1a7db0e 100644 --- a/Mathlib/Topology/FiberPartition.lean +++ b/Mathlib/Topology/FiberPartition.lean @@ -36,6 +36,7 @@ def sigmaIsoHom : C((x : Fiber f) × x.val, S) where toFun | ⟨a, x⟩ => x.val continuous_toFun := continuous_sigma (by fun_prop) +set_option backward.isDefEq.respectTransparency false in lemma sigmaIsoHom_inj : Function.Injective (sigmaIsoHom f) := by rintro ⟨⟨_, _, rfl⟩, ⟨_, hx⟩⟩ ⟨⟨_, _, rfl⟩, ⟨_, hy⟩⟩ h refine Sigma.subtype_ext ?_ h @@ -50,6 +51,7 @@ lemma sigmaIsoHom_surj : Function.Surjective (sigmaIsoHom f) := def sigmaIncl (a : Fiber f) : C(a.val, S) where toFun x := x.val +set_option backward.isDefEq.respectTransparency false in /-- The inclusion map from a fiber of a composition into the intermediate fiber. -/ def sigmaInclIncl {X : Type*} (g : Y → X) (a : Fiber (g ∘ f)) (b : Fiber (f ∘ (sigmaIncl (g ∘ f) a))) : diff --git a/Mathlib/Topology/Filter.lean b/Mathlib/Topology/Filter.lean index e78d810e846fc9..e2118c12d7bf22 100644 --- a/Mathlib/Topology/Filter.lean +++ b/Mathlib/Topology/Filter.lean @@ -69,6 +69,7 @@ theorem isOpen_iff {s : Set (Filter α)} : IsOpen s ↔ ∃ T : Set (Set α), s isTopologicalBasis_Iic_principal.open_iff_eq_sUnion.trans <| by simp only [exists_subset_range_and_iff, sUnion_image, (· ∘ ·)] +set_option backward.isDefEq.respectTransparency false in theorem nhds_eq (l : Filter α) : 𝓝 l = l.lift' (Iic ∘ 𝓟) := nhds_generateFrom.trans <| by simp only [mem_setOf_eq, @and_comm (l ∈ _), iInf_and, iInf_range, Filter.lift', Filter.lift, diff --git a/Mathlib/Topology/Gluing.lean b/Mathlib/Topology/Gluing.lean index 136fdc6e0b5abe..56ea34412f98e2 100644 --- a/Mathlib/Topology/Gluing.lean +++ b/Mathlib/Topology/Gluing.lean @@ -172,6 +172,7 @@ theorem eqvGen_of_π_eq colimit.isoColimitCocone_ι_hom, Category.id_comp] at this exact Quot.eq.1 this +set_option backward.isDefEq.respectTransparency.types false in theorem ι_eq_iff_rel (i j : D.J) (x : D.U i) (y : D.U j) : 𝖣.ι i x = 𝖣.ι j y ↔ D.Rel ⟨i, x⟩ ⟨j, y⟩ := by constructor @@ -379,6 +380,7 @@ theorem ι_fromOpenSubsetsGlue (i : J) : (ofOpenSubsets U).toGlueData.ι i ≫ fromOpenSubsetsGlue U = Opens.inclusion' _ := Multicoequalizer.π_desc _ _ _ _ _ +set_option backward.isDefEq.respectTransparency.types false in theorem fromOpenSubsetsGlue_injective : Function.Injective (fromOpenSubsetsGlue U) := by intro x y e obtain ⟨i, ⟨x, hx⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x @@ -412,6 +414,7 @@ theorem fromOpenSubsetsGlue_isOpenEmbedding : IsOpenEmbedding (fromOpenSubsetsGl .of_continuous_injective_isOpenMap (ContinuousMap.continuous_toFun _) (fromOpenSubsetsGlue_injective U) (fromOpenSubsetsGlue_isOpenMap U) +set_option backward.isDefEq.respectTransparency.types false in theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by ext constructor diff --git a/Mathlib/Topology/Homeomorph/Lemmas.lean b/Mathlib/Topology/Homeomorph/Lemmas.lean index 1dbcf2a6d5059b..4257d91ebbd659 100644 --- a/Mathlib/Topology/Homeomorph/Lemmas.lean +++ b/Mathlib/Topology/Homeomorph/Lemmas.lean @@ -173,6 +173,7 @@ abbrev sets {s : Set X} {t : Set Y} (h : X ≃ₜ Y) (h_eq : s = h ⁻¹' t) : s h.subtype <| Set.ext_iff.mp h_eq set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in /-- If two sets are equal, then they are homeomorphic. -/ def setCongr {s t : Set X} (h : s = t) : s ≃ₜ t where toEquiv := Equiv.setCongr h @@ -273,6 +274,7 @@ def piCongr {ι₁ ι₂ : Type*} {Y₁ : ι₁ → Type*} {Y₂ : ι₂ → Typ def ulift.{u, v} {X : Type v} [TopologicalSpace X] : ULift.{u, v} X ≃ₜ X where toEquiv := Equiv.ulift +set_option backward.isDefEq.respectTransparency false in /-- The natural homeomorphism `(ι ⊕ ι' → X) ≃ₜ (ι → X) × (ι' → X)`. `Equiv.sumArrowEquivProdArrow` as a homeomorphism. -/ @[simps!] diff --git a/Mathlib/Topology/Homotopy/Basic.lean b/Mathlib/Topology/Homotopy/Basic.lean index fdebd05ecd645e..e3a774a7348ffa 100644 --- a/Mathlib/Topology/Homotopy/Basic.lean +++ b/Mathlib/Topology/Homotopy/Basic.lean @@ -246,6 +246,7 @@ theorem trans_apply {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Hom · rw [extend, ContinuousMap.coe_IccExtend, Set.IccExtend_of_mem] rfl +set_option backward.isDefEq.respectTransparency false in theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) : (F.trans G).symm = G.symm.trans F.symm := by ext ⟨t, _⟩ diff --git a/Mathlib/Topology/Homotopy/HSpaces.lean b/Mathlib/Topology/Homotopy/HSpaces.lean index 73ab1e2285b428..6ff9e9a8344ad2 100644 --- a/Mathlib/Topology/Homotopy/HSpaces.lean +++ b/Mathlib/Topology/Homotopy/HSpaces.lean @@ -113,7 +113,7 @@ namespace IsTopologicalGroup lead to a diamond since a topological field would inherit two `HSpace` structures, one from the `MulOneClass` and one from the `AddZeroClass`. In the case of a group, we make `IsTopologicalGroup.hSpace` an instance." -/ -@[to_additive (attr := implicit_reducible) +@[to_additive (attr := instance_reducible) /-- The definition `toHSpace` is not an instance because it comes together with a multiplicative version which would lead to a diamond since a topological field would inherit two `HSpace` structures, one from the `MulOneClass` and one from the `AddZeroClass`. diff --git a/Mathlib/Topology/Homotopy/HomotopyGroup.lean b/Mathlib/Topology/Homotopy/HomotopyGroup.lean index 3c720fbf834efe..a0ddb6db8c8530 100644 --- a/Mathlib/Topology/Homotopy/HomotopyGroup.lean +++ b/Mathlib/Topology/Homotopy/HomotopyGroup.lean @@ -192,6 +192,7 @@ def currySum (q : Ω^ (M ⊕ N) X x) : C(I^M, Ω^ N X x) where ⟨sumArrowHomeomorphProdArrow.invFun, sumArrowHomeomorphProdArrow.continuous_invFun⟩).curry.continuous_toFun _ +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma currySum_apply_inl_inr (p : Ω^ (M ⊕ N) X x) (y : I^(M ⊕ N)) : currySum x p (y ∘ Sum.inl) (y ∘ Sum.inr) = p y := by @@ -211,6 +212,7 @@ protected def uncurry (p : Ω^ M (Ω^ N X x) const) : C((I^M) × (I^N), X) := lemma uncurry_apply (p : Ω^ M (Ω^ N X x) const) (y : (I^M) × (I^N)) : GenLoop.uncurry x p y = p y.1 y.2 := rfl +set_option backward.isDefEq.respectTransparency.types false in /-- `Ω^M (Ω^N X) ≃ₜ Ω^(M ⊕ N) X`. -/ @[simps] def genLoopGenLoopEquiv : Ω^ M (Ω^ N X x) GenLoop.const ≃ₜ Ω^ (M ⊕ N) X x where @@ -341,6 +343,7 @@ theorem homotopyTo_apply (i : N) {p q : Ω^ N X x} (H : p.1.HomotopyRel q.1 <| C homotopyTo i H t tₙ = H (t.fst, Cube.insertAt i (t.snd, tₙ)) := rfl +set_option backward.isDefEq.respectTransparency.types false in theorem homotopicTo (i : N) {p q : Ω^ N X x} : Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by refine Nonempty.map fun H ↦ ⟨⟨⟨fun t ↦ ⟨homotopyTo i H t, ?_⟩, ?_⟩, ?_, ?_⟩, ?_⟩ @@ -531,7 +534,7 @@ lemma HomotopyGroup.genLoopEquivOfUnique_transAt (N) [DecidableEq N] [Unique N] (genLoopEquivOfUnique _ q).trans (genLoopEquivOfUnique _ p) := by ext t simp only [genLoopEquivOfUnique, GenLoop.transAt, GenLoop.copy, - one_div, Equiv.coe_fn_mk, GenLoop.mk_apply, ContinuousMap.coe_mk, Path.coe_mk', Path.trans, + one_div, ContinuousMap.coe_mk, Path.coe_mk', Path.trans, Function.comp_apply] refine ite_congr rfl (fun _ ↦ congrArg q ?_) fun _ ↦ congrArg p ?_ diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index 812ea115341c92..e146df1472244c 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -325,6 +325,7 @@ lemma eq_liftHomotopy_iff' (H' : C(I × A, E)) : variable {f₀ f₁ : C(A, X)} {S : Set A} (F : f₀.HomotopyRel f₁ S) +set_option backward.isDefEq.respectTransparency.types false in open ContinuousMap in /-- The lift to a covering space of a homotopy between two continuous maps relative to a set given compatible lifts of the continuous maps. -/ @@ -348,6 +349,7 @@ def liftHomotopyRel [PreconnectedSpace A] exact (congr_fun (cov.liftHomotopy_lifts F f₀' _) (1, a)).trans (F.apply_one a) prop' := rel } +set_option backward.isDefEq.respectTransparency.types false in /-- Two continuous maps from a preconnected space to the total space of a covering map are homotopic relative to a set `S` if and only if their compositions with the covering map are homotopic relative to `S`, assuming that they agree at a point in `S`. -/ @@ -362,6 +364,7 @@ theorem homotopicRel_liftPath {γ₀ γ₁ : C(I, X)} h.map fun H ↦ cov.liftHomotopyRel (f₀' := cov.liftPath γ₀ e h₀) (f₁' := cov.liftPath γ₁ e h₁) H ⟨0, .inl rfl, by simp_rw [liftPath_zero]⟩ (liftPath_lifts ..) (liftPath_lifts ..) +set_option backward.isDefEq.respectTransparency.types false in /-- Lifting two paths that are homotopic relative to `{0,1}` starting from the same point also ends up in the same point. -/ theorem liftPath_apply_one_eq_of_homotopicRel {γ₀ γ₁ : C(I, X)} @@ -405,6 +408,7 @@ theorem monodromy_map {x y : E} (γ : Path.Homotopic.Quotient x y) : obtain ⟨γ⟩ := γ exact congr($((cov.eq_liftPath_iff' _).mpr ⟨rfl, γ.source⟩) 1).symm.trans γ.target +set_option backward.isDefEq.respectTransparency.types false in theorem monodromy_eq_of_map_eq {x y : X} {γ : Path.Homotopic.Quotient x y} {ex : p ⁻¹' {x}} {ey : p ⁻¹' {y}} (Γ : Path.Homotopic.Quotient ex.1 ey) (eq : Γ.map ⟨p, cov.continuous⟩ = γ.cast ex.2 ey.2) : @@ -479,6 +483,7 @@ theorem existsUnique_continuousMap_lifts [SimplyConnectedSpace A] [LocallyPathCo rw [eq_liftPath_iff'] exacts [⟨Γ_lifts, Γ_0⟩, ⟨Γ'_lifts, Γ'_0⟩] +set_option backward.isDefEq.respectTransparency.types false in open FundamentalGroup Path.Homotopic.Quotient in /-- A continuous map `f` from a path connected, locally path-connected space `A` to another space `X` lifts uniquely through a covering map `p : E → X` (such that `f a₀` is lifted to `e₀`) @@ -545,6 +550,7 @@ namespace IsQuotientCoveringMap variable {G : Type*} [Group G] [MulAction G E] (hp : IsQuotientCoveringMap p G) {g : G} +set_option backward.isDefEq.respectTransparency.types false in /-- The monodromy action of a quotient covering map commutes with the group action. -/ theorem monodromy_toPermFiber {x y : X} {γ : Path.Homotopic.Quotient x y} {e : p ⁻¹' {x}} : letI monodromy := hp.isCoveringMap.monodromy @@ -559,7 +565,6 @@ theorem monodromy_toPermFiber {x y : X} {γ : Path.Homotopic.Quotient x y} {e : · simp [g', p', hp.map_smul] · simp [g', p', hp.map_smul] · grind - · grind theorem commute_monodromyPerm_toPermFiber {x : X} {γ : FundamentalGroup X x} : Commute (hp.isCoveringMap.monodromyPerm x γ) (hp.toPermFiber x g) := by @@ -584,6 +589,7 @@ theorem monodromy_eq_id_iff : mpr eq := (hp.monodromy_ext e (eq.trans congr($hp.isCoveringMap.monodromy_refl e).symm)).trans hp.isCoveringMap.monodromy_refl +set_option backward.isDefEq.respectTransparency.types false in theorem ker_monodromyPerm : (hp.isCoveringMap.monodromyPerm x).ker = (FundamentalGroup.mapOfEq ⟨p, hp.continuous⟩ e.2).range := by diff --git a/Mathlib/Topology/Homotopy/Path.lean b/Mathlib/Topology/Homotopy/Path.lean index ab43ad7b0b4bf8..dcc6999ae4dfa0 100644 --- a/Mathlib/Topology/Homotopy/Path.lean +++ b/Mathlib/Topology/Homotopy/Path.lean @@ -413,6 +413,7 @@ theorem map_cast {x y : X} (p : Homotopic.Quotient x y) {x' y'} {hx : x' = x} {h end Quotient +set_option backward.isDefEq.respectTransparency false in -- Porting note: we didn't previously need the `α := ...` and `β := ...` hints. theorem hpath_hext {p₁ : Path x₀ x₁} {p₂ : Path x₂ x₃} (hp : ∀ t, p₁ t = p₂ t) : HEq (α := Path.Homotopic.Quotient _ _) ⟦p₁⟧ (β := Path.Homotopic.Quotient _ _) ⟦p₂⟧ := by diff --git a/Mathlib/Topology/Homotopy/Product.lean b/Mathlib/Topology/Homotopy/Product.lean index 4c2cd1f53d3a57..1b01a8c4968163 100644 --- a/Mathlib/Topology/Homotopy/Product.lean +++ b/Mathlib/Topology/Homotopy/Product.lean @@ -119,6 +119,7 @@ def pi (γ : ∀ i, Path.Homotopic.Quotient (as i) (bs i)) : Path.Homotopic.Quot (_root_.Quotient.map Path.pi fun x y hxy => Nonempty.map (piHomotopy x y) (Classical.nonempty_pi.mpr hxy)) (Quotient.choice γ) +set_option backward.isDefEq.respectTransparency false in theorem pi_lift (γ : ∀ i, Path (as i) (bs i)) : (Path.Homotopic.pi fun i => (Quotient.mk (γ i))) = Quotient.mk (Path.pi γ) := by simp_rw [← Quotient.mk'_eq_mk, Quotient.mk', pi, Quotient.choice_eq, Quotient.map_mk] diff --git a/Mathlib/Topology/Homotopy/TopCat/Basic.lean b/Mathlib/Topology/Homotopy/TopCat/Basic.lean index 6a13a15131c4a3..f5014235193b97 100644 --- a/Mathlib/Topology/Homotopy/TopCat/Basic.lean +++ b/Mathlib/Topology/Homotopy/TopCat/Basic.lean @@ -74,6 +74,7 @@ abbrev comp {f₀ f₁ : X ⟶ Y} {g₀ g₁ : Y ⟶ Z} (G : Homotopy g₀ g₁) attribute [nolint simpNF] comp_apply +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma h_comp {f₀ f₁ : X ⟶ Y} {g₀ g₁ : Y ⟶ Z} (G : Homotopy g₀ g₁) (F : Homotopy f₀ f₁) : (G.comp F).h = X ◁ lift (𝟙 I) (𝟙 I) ≫ (α_ _ _ _).inv ≫ F.h ▷ _ ≫ G.h := by diff --git a/Mathlib/Topology/Instances/AddCircle/Defs.lean b/Mathlib/Topology/Instances/AddCircle/Defs.lean index 19d0f23e4a5ce7..f8000183174827 100644 --- a/Mathlib/Topology/Instances/AddCircle/Defs.lean +++ b/Mathlib/Topology/Instances/AddCircle/Defs.lean @@ -658,6 +658,7 @@ lemma isOfFinAddOrder_iff_exists_rat_eq_div {a : 𝕜} : variable (p) +set_option backward.isDefEq.respectTransparency false in /-- The natural bijection between points of order `n` and natural numbers less than and coprime to `n`. The inverse of the map sends `m ↦ (m/n * p : AddCircle p)` where `m` is coprime to `n` and satisfies `0 ≤ m < n`. -/ diff --git a/Mathlib/Topology/Instances/CantorSet.lean b/Mathlib/Topology/Instances/CantorSet.lean index fbbd91931ac4b0..2f13fc37604fec 100644 --- a/Mathlib/Topology/Instances/CantorSet.lean +++ b/Mathlib/Topology/Instances/CantorSet.lean @@ -114,6 +114,7 @@ theorem cantorSet_eq_union_halves : Function.comp_def, ← preCantorSet_succ] exact (preCantorSet_antitone.iInter_nat_add _).symm +set_option backward.isDefEq.respectTransparency false in /-- The preCantor sets are closed. -/ lemma isClosed_preCantorSet (n : ℕ) : IsClosed (preCantorSet n) := by let f := Homeomorph.mulLeft₀ (1 / 3 : ℝ) (by simp) diff --git a/Mathlib/Topology/Instances/Complex.lean b/Mathlib/Topology/Instances/Complex.lean index 713a64e09c69f9..10b5efea88d2e8 100644 --- a/Mathlib/Topology/Instances/Complex.lean +++ b/Mathlib/Topology/Instances/Complex.lean @@ -47,6 +47,7 @@ theorem Complex.subfield_eq_of_closed {K : Subfield ℂ} (hc : IsClosed (K : Set simp only [image_univ] rfl +set_option backward.isDefEq.respectTransparency.types false in /-- Let `K` a subfield of `ℂ` and let `ψ : K →+* ℂ` a ring homomorphism. Assume that `ψ` is uniform continuous, then `ψ` is either the inclusion map or the composition of the inclusion map with the complex conjugation. -/ diff --git a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean index 06a8d14917dfe5..1eea4e8c17c601 100644 --- a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean @@ -569,7 +569,7 @@ theorem edist_ne_top_of_mem_ball {a : β} {r : ℝ≥0∞} (x y : eball a r) : e /-- Each ball in an extended metric space gives us a metric space, as the edist is everywhere finite. -/ -@[implicit_reducible] +@[instance_reducible] def metricSpaceEMetricBall (a : β) (r : ℝ≥0∞) : MetricSpace (eball a r) := EMetricSpace.toMetricSpace edist_ne_top_of_mem_ball diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 17dd0b09ab8e58..938baa9532253c 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -497,6 +497,7 @@ lemma image_mem_irreducibleComponents_of_isPreirreducible_fiber rw [← Set.image_preimage_eq Z hf₄] exact Set.image_mono this⟩ +set_option backward.isDefEq.respectTransparency false in /-- If `f : X → Y` is continuous, open, and has irreducible fibers, then it induces an bijection between irreducible components -/ @[stacks 037A] diff --git a/Mathlib/Topology/IsClosedRestrict.lean b/Mathlib/Topology/IsClosedRestrict.lean index bb2bae721d6989..0b3b803da4ff55 100644 --- a/Mathlib/Topology/IsClosedRestrict.lean +++ b/Mathlib/Topology/IsClosedRestrict.lean @@ -93,6 +93,7 @@ def _root_.Homeomorph.preimageImageRestrict (α : ι → Type*) [∀ i, Topologi exact fun _ ↦ (continuous_apply _).comp continuous_subtype_val continuous_invFun := continuous_reorderRestrictProd.subtype_mk _ +set_option backward.isDefEq.respectTransparency false in /-- The image by `preimageImageRestrict α S s` of `s` seen as a set of `Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s` is a set of `Sᶜ.restrict '' s × (Π i : S, α i)`, and the image of that set by `Prod.snd` is `S.restrict '' s`. diff --git a/Mathlib/Topology/IsLocalHomeomorph.lean b/Mathlib/Topology/IsLocalHomeomorph.lean index b68ee085e39d3c..34f760c8f3c039 100644 --- a/Mathlib/Topology/IsLocalHomeomorph.lean +++ b/Mathlib/Topology/IsLocalHomeomorph.lean @@ -63,6 +63,7 @@ namespace IsLocalHomeomorphOn variable {f s} +set_option backward.isDefEq.respectTransparency false in theorem discreteTopology_of_image (h : IsLocalHomeomorphOn f s) [DiscreteTopology (f '' s)] : DiscreteTopology s := discreteTopology_iff_isOpen_singleton.mpr fun x ↦ by diff --git a/Mathlib/Topology/MetricSpace/CauSeqFilter.lean b/Mathlib/Topology/MetricSpace/CauSeqFilter.lean index 637290461bf182..9a3bfc8747f762 100644 --- a/Mathlib/Topology/MetricSpace/CauSeqFilter.lean +++ b/Mathlib/Topology/MetricSpace/CauSeqFilter.lean @@ -83,6 +83,7 @@ theorem isCauSeq_iff_cauchySeq {α : Type u} [NormedField α] {u : ℕ → α} : IsCauSeq norm u ↔ CauchySeq u := ⟨fun h => CauSeq.cauchySeq ⟨u, h⟩, fun h => h.isCauSeq⟩ +set_option backward.isDefEq.respectTransparency.types false in -- see Note [lower instance priority] /-- A complete normed field is complete as a metric space, as Cauchy sequences converge by assumption and this suffices to characterize completeness. -/ diff --git a/Mathlib/Topology/MetricSpace/Defs.lean b/Mathlib/Topology/MetricSpace/Defs.lean index e580baef4437d1..40da52da8f67b6 100644 --- a/Mathlib/Topology/MetricSpace/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Defs.lean @@ -79,7 +79,7 @@ theorem MetricSpace.ext {α : Type*} {m m' : MetricSpace α} (h : m.toDist = m'. /-- Construct a metric space structure whose underlying topological space structure (definitionally) agrees which a pre-existing topology which is compatible with a given distance function. -/ -@[implicit_reducible] +@[instance_reducible] def MetricSpace.ofDistTopology {α : Type u} [TopologicalSpace α] (dist : α → α → ℝ) (dist_self : ∀ x : α, dist x x = 0) (dist_comm : ∀ x y : α, dist x y = dist y x) (dist_triangle : ∀ x y z : α, dist x z ≤ dist x y + dist y z) diff --git a/Mathlib/Topology/MetricSpace/Gluing.lean b/Mathlib/Topology/MetricSpace/Gluing.lean index b75a6b56bdba80..b2c1bb3b46eb8a 100644 --- a/Mathlib/Topology/MetricSpace/Gluing.lean +++ b/Mathlib/Topology/MetricSpace/Gluing.lean @@ -183,7 +183,7 @@ set_option backward.privateInPublic.warn false in `Φ p` and `Φ q`, and between `Ψ p` and `Ψ q`, coincide up to `2 ε` where `ε > 0`, one can almost glue the two spaces `X` and `Y` along the images of `Φ` and `Ψ`, so that `Φ p` and `Ψ p` are at distance `ε`. -/ -@[implicit_reducible] +@[instance_reducible] def glueMetricApprox [Nonempty Z] (Φ : Z → X) (Ψ : Z → Y) (ε : ℝ) (ε0 : 0 < ε) (H : ∀ p q, |dist (Φ p) (Φ q) - dist (Ψ p) (Ψ q)| ≤ 2 * ε) : MetricSpace (X ⊕ Y) where dist := glueDist Φ Ψ ε @@ -468,7 +468,7 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Given two isometric embeddings `Φ : Z → X` and `Ψ : Z → Y`, we define a pseudometric space structure on `X ⊕ Y` by declaring that `Φ x` and `Ψ x` are at distance `0`. -/ -@[implicit_reducible] +@[instance_reducible] def gluePremetric (hΦ : Isometry Φ) (hΨ : Isometry Ψ) : PseudoMetricSpace (X ⊕ Y) where dist := glueDist Φ Ψ 0 dist_self := glueDist_self Φ Ψ 0 diff --git a/Mathlib/Topology/MetricSpace/GromovHausdorff.lean b/Mathlib/Topology/MetricSpace/GromovHausdorff.lean index 70934af7912b61..ce17f30ae63571 100644 --- a/Mathlib/Topology/MetricSpace/GromovHausdorff.lean +++ b/Mathlib/Topology/MetricSpace/GromovHausdorff.lean @@ -612,6 +612,7 @@ theorem ghDist_le_of_approx_subsets {s : Set X} (Φ : s → Y) {ε₁ ε₂ ε end --section +set_option backward.isDefEq.respectTransparency false in /-- The Gromov-Hausdorff space is second countable. -/ instance : SecondCountableTopology GHSpace := by refine secondCountable_of_countable_discretization fun δ δpos => ?_ diff --git a/Mathlib/Topology/MetricSpace/Isometry.lean b/Mathlib/Topology/MetricSpace/Isometry.lean index c89bf11c768a84..4c9894e25c229f 100644 --- a/Mathlib/Topology/MetricSpace/Isometry.lean +++ b/Mathlib/Topology/MetricSpace/Isometry.lean @@ -610,6 +610,9 @@ def piCongrLeft' {ι' : Type*} [Fintype ι] [Fintype ι'] {Y : ι → Type*} simp_rw [edist_pi_def, Finset.sup_univ_eq_iSup] exact (Equiv.iSup_comp (g := fun b ↦ edist (x1 b) (x2 b)) e.symm) +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The natural isometry `∀ i, Y (e i) ≃ᵢ ∀ j, Y j` obtained from a bijection `ι ≃ ι'` of fintypes. `Equiv.piCongrLeft` as an `IsometryEquiv`. -/ @[simps!] @@ -648,6 +651,9 @@ theorem _root_.Fin.appendIsometry_toHomeomorph (m n : ℕ) : (Fin.appendIsometry m n).toHomeomorph = Fin.appendHomeomorph (X := α) m n := rfl +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- The natural `IsometryEquiv` `(Fin m → ℝ) × (Fin l → ℝ) ≃ᵢ (Fin n → ℝ)` when `m + l = n`. -/ @[simps!] def _root_.Fin.appendIsometryOfEq {n m l : ℕ} (hmln : m + l = n) : diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index d219092d8cfa98..bc5dd4c780072e 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -402,7 +402,7 @@ protected def metricSpace : MetricSpace (∀ n, E n) := /-- Metric space structure on `Π (n : ℕ), E n` when the spaces `E n` have the discrete uniformity, where the distance is given by `dist x y = (1/2)^n`, where `n` is the smallest index where `x` and `y` differ. Not registered as a global instance by default. -/ -@[implicit_reducible] +@[instance_reducible] protected def metricSpaceOfDiscreteUniformity {E : ℕ → Type*} [∀ n, UniformSpace (E n)] (h : ∀ n, uniformity (E n) = 𝓟 SetRel.id) : MetricSpace (∀ n, E n) := haveI : ∀ n, DiscreteTopology (E n) := fun n => discreteTopology_of_discrete_uniformity (h n) @@ -438,7 +438,7 @@ protected def metricSpaceOfDiscreteUniformity {E : ℕ → Type*} [∀ n, Unifor /-- Metric space structure on `ℕ → ℕ` where the distance is given by `dist x y = (1/2)^n`, where `n` is the smallest index where `x` and `y` differ. Not registered as a global instance by default. -/ -@[implicit_reducible] +@[instance_reducible] def metricSpaceNatNat : MetricSpace (ℕ → ℕ) := PiNat.metricSpaceOfDiscreteUniformity fun _ => rfl @@ -955,7 +955,7 @@ variable [∀ i, MetricSpace (F i)] It is highly non-canonical, though, and therefore not registered as a global instance. The distance we use here is `edist x y = ∑' i, min (1/2)^(encode i) (edist (x i) (y i))`. -/ -@[implicit_reducible] +@[instance_reducible] protected def metricSpace : MetricSpace (∀ i, F i) := EMetricSpace.toMetricSpaceOfDist dist (by simp) (by simp [edist_dist]) diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean b/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean index b8af68161d020f..ca97a65f63e757 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean @@ -40,7 +40,7 @@ abbrev PseudoMetricSpace.induced {α β} (f : α → β) (m : PseudoMetricSpace /-- Pull back a pseudometric space structure by an inducing map. This is a version of `PseudoMetricSpace.induced` useful in case if the domain already has a `TopologicalSpace` structure. -/ -@[implicit_reducible] +@[instance_reducible] def Topology.IsInducing.comapPseudoMetricSpace {α β : Type*} [TopologicalSpace α] [m : PseudoMetricSpace β] {f : α → β} (hf : IsInducing f) : PseudoMetricSpace α := .replaceTopology (.induced f m) hf.eq_induced @@ -48,7 +48,7 @@ def Topology.IsInducing.comapPseudoMetricSpace {α β : Type*} [TopologicalSpace /-- Pull back a pseudometric space structure by a uniform inducing map. This is a version of `PseudoMetricSpace.induced` useful in case if the domain already has a `UniformSpace` structure. -/ -@[implicit_reducible] +@[instance_reducible] def IsUniformInducing.comapPseudoMetricSpace {α β} [UniformSpace α] [m : PseudoMetricSpace β] (f : α → β) (h : IsUniformInducing f) : PseudoMetricSpace α := .replaceUniformity (.induced f m) h.comap_uniformity.symm diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index 0de76b0b857754..898ef53d034c74 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -72,7 +72,7 @@ theorem UniformSpace.ofDist_aux (ε : ℝ) (hε : 0 < ε) : ∃ δ > (0 : ℝ), ⟨ε / 2, half_pos hε, fun _x hx _y hy => add_halves ε ▸ add_lt_add hx hy⟩ /-- Construct a uniform structure from a distance function and metric space axioms -/ -@[implicit_reducible] +@[instance_reducible] def UniformSpace.ofDist (dist : α → α → ℝ) (dist_self : ∀ x : α, dist x x = 0) (dist_comm : ∀ x y : α, dist x y = dist y x) (dist_triangle : ∀ x y z : α, dist x z ≤ dist x y + dist y z) : UniformSpace α := @@ -180,7 +180,7 @@ instance (priority := 200) PseudoMetricSpace.toEDist : EDist α := /-- Construct a pseudo-metric space structure whose underlying topological space structure (definitionally) agrees which a pre-existing topology which is compatible with a given distance function. -/ -@[implicit_reducible] +@[instance_reducible] def PseudoMetricSpace.ofDistTopology {α : Type u} [TopologicalSpace α] (dist : α → α → ℝ) (dist_self : ∀ x : α, dist x x = 0) (dist_comm : ∀ x y : α, dist x y = dist y x) (dist_triangle : ∀ x y z : α, dist x z ≤ dist x y + dist y z) diff --git a/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean b/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean index 6cf8b5e81c2ee6..cfa453081a70f2 100644 --- a/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean +++ b/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean @@ -74,7 +74,7 @@ instance (priority := 100) IsCompletelyPseudoMetrizableSpace.of_completeSpace_ps /-- Construct on a completely pseudometrizable space a pseudometric (compatible with the topology) which is complete. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def completelyPseudoMetrizableMetric (X : Type*) [TopologicalSpace X] [h : IsCompletelyPseudoMetrizableSpace X] : PseudoMetricSpace X := h.complete.choose.replaceTopology h.complete.choose_spec.1.symm @@ -87,7 +87,7 @@ theorem complete_completelyPseudoMetrizableMetric (X : Type*) [ht : TopologicalS /-- This definition endows a completely pseudometrizable space with a complete pseudometric. Use it as: `letI := upgradeIsCompletelyPseudoMetrizable X`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def upgradeIsCompletelyPseudoMetrizable (X : Type*) [TopologicalSpace X] [IsCompletelyPseudoMetrizableSpace X] : @@ -187,7 +187,7 @@ instance (priority := 100) IsCompletelyMetrizableSpace.of_completeSpace_metrizab /-- Construct on a completely metrizable space a metric (compatible with the topology) which is complete. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def completelyMetrizableMetric (X : Type*) [TopologicalSpace X] [h : IsCompletelyMetrizableSpace X] : MetricSpace X := h.complete.choose.replaceTopology h.complete.choose_spec.1.symm @@ -200,7 +200,7 @@ theorem complete_completelyMetrizableMetric (X : Type*) [ht : TopologicalSpace X /-- This definition endows a completely metrizable space with a complete metric. Use it as: `letI := upgradeIsCompletelyMetrizable X`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def upgradeIsCompletelyMetrizable (X : Type*) [TopologicalSpace X] [IsCompletelyMetrizableSpace X] : UpgradedIsCompletelyMetrizableSpace X := diff --git a/Mathlib/Topology/Metrizable/Uniformity.lean b/Mathlib/Topology/Metrizable/Uniformity.lean index 6814c779443e60..2dc5b50b8e07da 100644 --- a/Mathlib/Topology/Metrizable/Uniformity.lean +++ b/Mathlib/Topology/Metrizable/Uniformity.lean @@ -58,7 +58,7 @@ namespace PseudoMetricSpace /-- The maximal pseudometric space structure on `X` such that `dist x y ≤ d x y` for all `x y`, where `d : X → X → ℝ≥0` is a function such that `d x x = 0` and `d x y = d y x` for all `x`, `y`. -/ -@[implicit_reducible] +@[instance_reducible] noncomputable def ofPreNNDist (d : X → X → ℝ≥0) (dist_self : ∀ x, d x x = 0) (dist_comm : ∀ x y, d x y = d y x) : PseudoMetricSpace X where dist x y := ↑(⨅ l : List X, ((x::l).zipWith d (l ++ [y])).sum : ℝ≥0) diff --git a/Mathlib/Topology/Neighborhoods.lean b/Mathlib/Topology/Neighborhoods.lean index 7423d380ff397c..dae0480367bac9 100644 --- a/Mathlib/Topology/Neighborhoods.lean +++ b/Mathlib/Topology/Neighborhoods.lean @@ -26,6 +26,7 @@ universe u v variable {X : Type u} [TopologicalSpace X] {ι : Sort v} {α : Type*} {x : X} {s t : Set X} +set_option backward.isDefEq.respectTransparency false in theorem nhds_def' (x : X) : 𝓝 x = ⨅ (s : Set X) (_ : IsOpen s) (_ : x ∈ s), 𝓟 s := by simp only [nhds_def, mem_setOf_eq, @and_comm (x ∈ _), iInf_and] diff --git a/Mathlib/Topology/NhdsWithin.lean b/Mathlib/Topology/NhdsWithin.lean index 1b865516dd12dd..142a9861f31d87 100644 --- a/Mathlib/Topology/NhdsWithin.lean +++ b/Mathlib/Topology/NhdsWithin.lean @@ -119,9 +119,11 @@ theorem mem_nhdsWithin_iff_eventuallyEq {s t : Set α} {x : α} : t ∈ 𝓝[s] x ↔ s =ᶠ[𝓝 x] (s ∩ t : Set α) := by simp_rw [mem_nhdsWithin_iff_eventually, eventuallyEq_set, mem_inter_iff, iff_self_and] +set_option backward.isDefEq.respectTransparency false in lemma mem_nhdsWithin_inter_self {s t : Set α} {x : α} : t ∈ 𝓝[s ∩ t] x := mem_nhdsWithin_iff_eventuallyEq.mpr <| by simp [inter_assoc] +set_option backward.isDefEq.respectTransparency false in lemma mem_nhdsWithin_self_inter {s t : Set α} {x : α} : s ∈ 𝓝[s ∩ t] x := mem_nhdsWithin_iff_eventuallyEq.mpr <| by simp [inter_comm s t, inter_assoc] diff --git a/Mathlib/Topology/OmegaCompletePartialOrder.lean b/Mathlib/Topology/OmegaCompletePartialOrder.lean index 009eb1cfc0a39f..7d19b3dee1ad6a 100644 --- a/Mathlib/Topology/OmegaCompletePartialOrder.lean +++ b/Mathlib/Topology/OmegaCompletePartialOrder.lean @@ -56,6 +56,7 @@ theorem isOpen_univ : IsOpen α univ := @CompleteLattice.ωScottContinuous.top theorem IsOpen.inter (s t : Set α) : IsOpen α s → IsOpen α t → IsOpen α (s ∩ t) := CompleteLattice.ωScottContinuous.inf +set_option backward.isDefEq.respectTransparency false in theorem isOpen_sUnion (s : Set (Set α)) (hs : ∀ t ∈ s, IsOpen α t) : IsOpen α (⋃₀ s) := by simp only [IsOpen] at hs ⊢ convert! CompleteLattice.ωScottContinuous.sSup hs diff --git a/Mathlib/Topology/Order.lean b/Mathlib/Topology/Order.lean index 4cdc12c5c91af1..ee4c945924cef4 100644 --- a/Mathlib/Topology/Order.lean +++ b/Mathlib/Topology/Order.lean @@ -64,7 +64,7 @@ inductive GenerateOpen (g : Set (Set α)) : Set α → Prop | sUnion : ∀ S : Set (Set α), (∀ s ∈ S, GenerateOpen g s) → GenerateOpen g (⋃₀ S) /-- The smallest topological space containing the collection `g` of basic sets -/ -@[implicit_reducible] +@[instance_reducible] def generateFrom (g : Set (Set α)) : TopologicalSpace α where IsOpen := GenerateOpen g isOpen_univ := GenerateOpen.univ @@ -95,7 +95,7 @@ lemma tendsto_nhds_generateFrom_iff {β : Type*} {m : α → β} {f : Filter α} tendsto_principal]; rfl /-- Construct a topology on α given the filter of neighborhoods of each point of α. -/ -@[implicit_reducible] +@[instance_reducible] protected def mkOfNhds (n : α → Filter α) : TopologicalSpace α where IsOpen s := ∀ a ∈ s, s ∈ n a isOpen_univ _ _ := univ_mem @@ -157,7 +157,7 @@ theorem le_generateFrom_iff_subset_isOpen {g : Set (Set α)} {t : TopologicalSpa /-- If `s` equals the collection of open sets in the topology it generates, then `s` defines a topology. -/ -@[implicit_reducible] +@[instance_reducible] protected def mkOfClosure (s : Set (Set α)) (hs : { u | GenerateOpen s u } = s) : TopologicalSpace α where IsOpen u := u ∈ s @@ -647,7 +647,7 @@ lemma generateFrom_insert_empty {α : Type*} {s : Set (Set α)} : /-- This construction is left adjoint to the operation sending a topology on `α` to its neighborhood filter at a fixed point `a : α`. -/ -@[implicit_reducible] +@[instance_reducible] def nhdsAdjoint (a : α) (f : Filter α) : TopologicalSpace α where IsOpen s := a ∈ s → s ∈ f isOpen_univ _ := univ_mem diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index 477b11d1e552ac..71aae750687376 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -66,7 +66,7 @@ variable {α : Type u} {β : Type v} {γ : Type w} `(a, ∞) = { x ∣ a < x }, (-∞, b) = {x ∣ x < b}` for all `a, b` in `α`. We do not register it as an instance as many ordered sets are already endowed with the same topology, most often in a non-defeq way though. Register as a local instance when necessary. -/ -@[implicit_reducible] +@[instance_reducible] def Preorder.topology (α : Type*) [Preorder α] : TopologicalSpace α := generateFrom { s | ∃ a, s = Ioi a ∨ s = Iio a } diff --git a/Mathlib/Topology/Order/Bornology.lean b/Mathlib/Topology/Order/Bornology.lean index 5ce1ef6e561bb5..bcb58e3988f495 100644 --- a/Mathlib/Topology/Order/Bornology.lean +++ b/Mathlib/Topology/Order/Bornology.lean @@ -30,7 +30,7 @@ variable [Lattice α] [Nonempty α] /-- Order-bornology on a nonempty lattice. The bounded sets are the sets that are bounded both above and below. -/ -@[implicit_reducible] +@[instance_reducible] def orderBornology : Bornology α := .ofBounded {s | BddBelow s ∧ BddAbove s} (by simp) @@ -38,6 +38,7 @@ def orderBornology : Bornology α := .ofBounded (fun _ hs _ ht ↦ ⟨hs.1.union ht.1, hs.2.union ht.2⟩) (by simp) +set_option backward.isDefEq.respectTransparency false in @[simp] lemma orderBornology_isBounded : orderBornology.IsBounded s ↔ BddBelow s ∧ BddAbove s := by simp [IsBounded, IsCobounded, -isCobounded_compl_iff] diff --git a/Mathlib/Topology/Order/Completion.lean b/Mathlib/Topology/Order/Completion.lean index a7521c3468d4dd..6144db783dcaf1 100644 --- a/Mathlib/Topology/Order/Completion.lean +++ b/Mathlib/Topology/Order/Completion.lean @@ -65,12 +65,14 @@ instance : TopologicalSpace (Fill α) := Preorder.topology _ instance : OrderTopology (Fill α) := ⟨rfl⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- A continuous embedding of `α` into `Fill α`. -/ def some : α ↪o Fill α where toFun x := ⟨toLex (x, 0), by simp⟩ inj' _ := by simp map_rel_iff' := by simp [Prod.Lex.toLex_le_toLex'] +set_option backward.isDefEq.respectTransparency.types false in instance : DenselyOrdered (Fill α) where dense := by simp only [ofLex_toLex, Subtype.forall, Prod.Lex.lt_iff, Subtype.mk_lt_mk, @@ -90,6 +92,7 @@ instance : DenselyOrdered (Fill α) where · grind [ofLex_toLex] · simp [Prod.Lex.lt_iff, hs, hs'] +set_option backward.isDefEq.respectTransparency.types false in theorem continuous_some [TopologicalSpace α] [OrderTopology α] : Continuous (X := α) some := by simp only [OrderTopology.continuous_iff, ofLex_toLex, Subtype.forall, Lex.forall, Prod.forall] refine fun x q ⟨hx₁, hx₂⟩ ↦ ⟨?_, ?_⟩ diff --git a/Mathlib/Topology/Order/HullKernel.lean b/Mathlib/Topology/Order/HullKernel.lean index ba4af9ac21b64f..86854af2cedea0 100644 --- a/Mathlib/Topology/Order/HullKernel.lean +++ b/Mathlib/Topology/Order/HullKernel.lean @@ -181,6 +181,7 @@ def OrderGenerates := ∀ (a : α), ∃ (S : Set T), a = kernel S variable {T} +set_option backward.isDefEq.respectTransparency false in /-- When `T` is order generating, the `kernel` and the `hull` form a Galois insertion -/ diff --git a/Mathlib/Topology/Order/LawsonTopology.lean b/Mathlib/Topology/Order/LawsonTopology.lean index b72e46d693d0f1..e6820efbaae8da 100644 --- a/Mathlib/Topology/Order/LawsonTopology.lean +++ b/Mathlib/Topology/Order/LawsonTopology.lean @@ -64,7 +64,7 @@ section Preorder /-- The Lawson topology is defined as the meet of `Topology.lower` and the `Topology.scott`. -/ -@[implicit_reducible] +@[instance_reducible] def lawson (α : Type*) [Preorder α] : TopologicalSpace α := lower α ⊓ scott α univ variable (α) [Preorder α] [TopologicalSpace α] diff --git a/Mathlib/Topology/Order/LowerUpperTopology.lean b/Mathlib/Topology/Order/LowerUpperTopology.lean index ff2580b0367db9..b429e624cf280c 100644 --- a/Mathlib/Topology/Order/LowerUpperTopology.lean +++ b/Mathlib/Topology/Order/LowerUpperTopology.lean @@ -61,14 +61,14 @@ namespace Topology The lower topology is the topology generated by the complements of the left-closed right-infinite intervals. -/ -@[implicit_reducible] +@[instance_reducible] def lower (α : Type*) [Preorder α] : TopologicalSpace α := generateFrom {s | ∃ a, (Ici a)ᶜ = s} /-- The upper topology is the topology generated by the complements of the right-closed left-infinite intervals. -/ -@[implicit_reducible] +@[instance_reducible] def upper (α : Type*) [Preorder α] : TopologicalSpace α := generateFrom {s | ∃ a, (Iic a)ᶜ = s} /-- Type synonym for a preorder equipped with the lower set topology. -/ diff --git a/Mathlib/Topology/Order/ScottTopology.lean b/Mathlib/Topology/Order/ScottTopology.lean index 6f1d54273abad6..14aa66e670a7ad 100644 --- a/Mathlib/Topology/Order/ScottTopology.lean +++ b/Mathlib/Topology/Order/ScottTopology.lean @@ -77,7 +77,7 @@ A set `u` is open in the Scott-Hausdorff topology iff when the least upper bound For mild conditions on `D`, this is equivalent to saying that open sets are `DirSupInaccOn D`, and closed sets are `DirSupClosedOn D`. -/ -@[implicit_reducible] +@[instance_reducible] def scottHausdorff (α : Type*) (D : Set (Set α)) [Preorder α] : TopologicalSpace α where IsOpen u := ∀ ⦃d : Set α⦄, d ∈ D → d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a : α⦄, IsLUB d a → a ∈ u → ∃ b ∈ d, Ici b ∩ d ⊆ u @@ -161,7 +161,7 @@ section Preorder /-- The Scott topology. It is defined as the join of the topology of upper sets and the Scott-Hausdorff topology. -/ -@[implicit_reducible] +@[instance_reducible] def scott (α : Type*) (D : Set (Set α)) [Preorder α] : TopologicalSpace α := upperSet α ⊔ scottHausdorff α D diff --git a/Mathlib/Topology/Order/UpperLowerSetTopology.lean b/Mathlib/Topology/Order/UpperLowerSetTopology.lean index 701388137247f8..c6152ebd84023e 100644 --- a/Mathlib/Topology/Order/UpperLowerSetTopology.lean +++ b/Mathlib/Topology/Order/UpperLowerSetTopology.lean @@ -59,7 +59,7 @@ namespace Topology /-- Topology whose open sets are upper sets. Note: In general the upper set topology does not coincide with the upper topology. -/ -@[implicit_reducible] +@[instance_reducible] def upperSet (α : Type*) [Preorder α] : TopologicalSpace α where IsOpen := IsUpperSet isOpen_univ := isUpperSet_univ @@ -69,7 +69,7 @@ def upperSet (α : Type*) [Preorder α] : TopologicalSpace α where /-- Topology whose open sets are lower sets. Note: In general the lower set topology does not coincide with the lower topology. -/ -@[implicit_reducible] +@[instance_reducible] def lowerSet (α : Type*) [Preorder α] : TopologicalSpace α where IsOpen := IsLowerSet isOpen_univ := isLowerSet_univ diff --git a/Mathlib/Topology/Order/WithTop.lean b/Mathlib/Topology/Order/WithTop.lean index 504ce112af04bf..b9eccbf949643e 100644 --- a/Mathlib/Topology/Order/WithTop.lean +++ b/Mathlib/Topology/Order/WithTop.lean @@ -228,6 +228,7 @@ lemma tendsto_untopA [Nonempty ι] {a : WithTop ι} (ha : a ≠ ⊤) : lemma continuousOn_untopA [Nonempty ι] : ContinuousOn untopA { a : WithTop ι | a ≠ ⊤ } := continuousOn_untopD _ +set_option backward.isDefEq.respectTransparency false in @[to_dual] lemma tendsto_untop (a : {a : WithTop ι | a ≠ ⊤}) : Tendsto (fun x ↦ untop x.1 x.2) (𝓝 a) (𝓝 (untop a.1 a.2)) := by diff --git a/Mathlib/Topology/Separation/Basic.lean b/Mathlib/Topology/Separation/Basic.lean index 2e3d88286a9baf..2e7da648c7de89 100644 --- a/Mathlib/Topology/Separation/Basic.lean +++ b/Mathlib/Topology/Separation/Basic.lean @@ -325,7 +325,7 @@ variable (X) in /-- In an R₀ space, relatively compact sets form a bornology. Its cobounded filter is `Filter.coclosedCompact`. See also `Bornology.inCompact` the bornology of sets contained in a compact set. -/ -@[implicit_reducible] +@[instance_reducible] def Bornology.relativelyCompact : Bornology X where cobounded := Filter.coclosedCompact X le_cofinite := Filter.coclosedCompact_le_cofinite @@ -585,6 +585,7 @@ theorem Set.Subsingleton.closure [T1Space X] {s : Set X} (hs : s.Subsingleton) : theorem subsingleton_closure [T1Space X] {s : Set X} : (closure s).Subsingleton ↔ s.Subsingleton := ⟨fun h => h.anti subset_closure, fun h => h.closure⟩ +set_option backward.isDefEq.respectTransparency false in theorem isClosedMap_const {X Y} [TopologicalSpace X] [TopologicalSpace Y] [T1Space Y] {y : Y} : IsClosedMap (Function.const X y) := IsClosedMap.of_nonempty fun s _ h2s => by simp_rw [const, h2s.image_const, isClosed_singleton] diff --git a/Mathlib/Topology/Separation/Hausdorff.lean b/Mathlib/Topology/Separation/Hausdorff.lean index bdcb3685f9d283..4998e1f32113a6 100644 --- a/Mathlib/Topology/Separation/Hausdorff.lean +++ b/Mathlib/Topology/Separation/Hausdorff.lean @@ -404,7 +404,7 @@ section variable (X) /-- The smallest equivalence relation on a topological space giving a T2 quotient. -/ -@[implicit_reducible] +@[instance_reducible] def t2Setoid : Setoid X := sInf {s | T2Space (Quotient s)} /-- The largest T2 quotient of a topological space. This construction is left-adjoint to the diff --git a/Mathlib/Topology/Sets/Closeds.lean b/Mathlib/Topology/Sets/Closeds.lean index 49d759e8d5cb29..e869ee8e83191a 100644 --- a/Mathlib/Topology/Sets/Closeds.lean +++ b/Mathlib/Topology/Sets/Closeds.lean @@ -183,7 +183,7 @@ theorem iInf_mk {ι} (s : ι → Set α) (h : ∀ i, IsClosed (s i)) : iInf_def _ /-- Closed sets in a topological space form a coframe. -/ -@[implicit_reducible] +@[instance_reducible] def coframeMinimalAxioms : Coframe.MinimalAxioms (Closeds α) where iInf_sup_le_sup_sInf a s := (SetLike.coe_injective <| by simp only [coe_sup, coe_iInf, coe_sInf, Set.union_iInter₂]).le diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index c9a12554fea78d..14fb2bd7a6441c 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -258,7 +258,7 @@ theorem mem_sSup {Us : Set (Opens α)} {x : α} : x ∈ sSup Us ↔ ∃ u ∈ Us simp_rw [sSup_eq_iSup, mem_iSup, exists_prop] /-- Open sets in a topological space form a frame. -/ -@[implicit_reducible] +@[instance_reducible] def frameMinimalAxioms : Frame.MinimalAxioms (Opens α) where inf_sSup_le_iSup_inf a s := (ext <| by simp only [coe_inf, coe_iSup, coe_sSup, Set.inter_iUnion₂]).le diff --git a/Mathlib/Topology/Sheaves/Alexandrov.lean b/Mathlib/Topology/Sheaves/Alexandrov.lean index 058bebb985779a..f34b1c9310f3c2 100644 --- a/Mathlib/Topology/Sheaves/Alexandrov.lean +++ b/Mathlib/Topology/Sheaves/Alexandrov.lean @@ -167,6 +167,7 @@ def isLimit {X : TopCat.{v}} [Preorder X] [Topology.IsUpperSet X] congr apply limit.lift_π +set_option backward.isDefEq.respectTransparency.types false in theorem isSheaf_principalsKanExtension {X : TopCat.{v}} [Preorder X] [Topology.IsUpperSet X] (F : X ⥤ C) : Presheaf.IsSheaf (principalsKanExtension F) := by @@ -179,6 +180,7 @@ end Alexandrov open Alexandrov +set_option backward.isDefEq.respectTransparency.types false in /-- The main theorem of this file. If `X` is a topological space and preorder whose topology is the `UpperSet` topology associated diff --git a/Mathlib/Topology/Sheaves/Flasque.lean b/Mathlib/Topology/Sheaves/Flasque.lean index 94a820980075a8..34b89440f7ccd8 100644 --- a/Mathlib/Topology/Sheaves/Flasque.lean +++ b/Mathlib/Topology/Sheaves/Flasque.lean @@ -52,6 +52,7 @@ namespace IsFlasque attribute [instance low] IsFlasque.epi +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in instance pushforward_isFlasque {Y : TopCat.{u}} [IsFlasque F] (f : X ⟶ Y) : IsFlasque (f _* F) where @@ -81,7 +82,7 @@ an open `V` and a section of `F(V)` that maps to `s |_ V` via `g`. -/ abbrev Under := StructuredArrow ⟨op U, s⟩ (Functor.whiskerRight g.hom (CategoryTheory.forget AddCommGrpCat.{u})).mapElements -set_option backward.isDefEq.respectTransparency false in +set_option backward.isDefEq.respectTransparency.types false in /- The next lemma proves that the relation `fun x y ↦ Nonempty (y ⟶ x)` on `Under g s` satisfies the requirements for applying Zorn's lemma -/ lemma structured_arrows_elements_sheaf_chains_bounded (c : Set (Under g s)) @@ -175,6 +176,7 @@ theorem epi_of_shortExact {S : ShortComplex (Sheaf AddCommGrpCat X)} (hS : S.Sho exact leOfHom ((ht t₆) this).some.right.1.unop ((le_iSup f 1) hW) exact ⟨t.right.2 |_ U, by simp [map_restrict, ← tcomp, restrict_restrict]⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- Given a short exact sequence of sheaves, `0 ⟶ 𝓕 ⟶ 𝓖 ⟶ 𝓗 ⟶ 0`, if `𝓕` and `𝓖` are flasque, then `𝓗` is flasque. -/ theorem of_shortExact_of_isFlasque₁₂ {S : ShortComplex (Sheaf AddCommGrpCat X)} diff --git a/Mathlib/Topology/Sheaves/Presheaf.lean b/Mathlib/Topology/Sheaves/Presheaf.lean index c86168c5c462b1..a738cb08cd79ea 100644 --- a/Mathlib/Topology/Sheaves/Presheaf.lean +++ b/Mathlib/Topology/Sheaves/Presheaf.lean @@ -42,6 +42,7 @@ variable (C : Type u) [Category.{v} C] namespace TopCat /-- The category of `C`-valued presheaves on a (bundled) topological space `X`. -/ +@[implicit_reducible] def Presheaf (X : TopCat.{w}) : Type max u v w := (Opens X)ᵒᵖ ⥤ C @@ -130,6 +131,7 @@ abbrev restrictOpen {F : X.Presheaf C} /-- restriction of a section to open subset -/ scoped[AlgebraicGeometry] infixl:80 " |_ " => TopCat.Presheaf.restrictOpen +set_option backward.isDefEq.respectTransparency.types false in theorem restrict_restrict {F : X.Presheaf C} {U V W : Opens X} (e₁ : U ≤ V) (e₂ : V ≤ W) (x : ToType (F.obj (op W))) : x |_ V |_ U = x |_ U := by @@ -137,12 +139,14 @@ theorem restrict_restrict rw [← ConcreteCategory.comp_apply, ← Functor.map_comp] rfl +set_option backward.isDefEq.respectTransparency.types false in theorem map_restrict {F G : X.Presheaf C} (e : F ⟶ G) {U V : Opens X} (h : U ≤ V) (x : ToType (F.obj (op V))) : e.app _ (x |_ U) = e.app _ x |_ U := by delta restrictOpen restrict rw [← ConcreteCategory.comp_apply, NatTrans.naturality, ConcreteCategory.comp_apply] +set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrict_self {F : X.Presheaf C} {U : Opens X} (x : ToType (F.obj (op U))) : x |_ U = x := by @@ -153,7 +157,7 @@ open CategoryTheory.Limits variable (C) /-- The pushforward functor. -/ -@[simps!] +@[simps!, implicit_reducible] def pushforward {X Y : TopCat.{w}} (f : X ⟶ Y) : X.Presheaf C ⥤ Y.Presheaf C := (whiskeringLeft _ _ _).obj (Opens.map f).op @@ -216,6 +220,7 @@ def pushforwardEq {X Y : TopCat.{w}} {f g : X ⟶ Y} (h : f = g) (ℱ : X.Preshe theorem pushforward_eq' {X Y : TopCat.{w}} {f g : X ⟶ Y} (h : f = g) (ℱ : X.Presheaf C) : f _* ℱ = g _* ℱ := by rw [h] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem pushforwardEq_hom_app {X Y : TopCat.{w}} {f g : X ⟶ Y} @@ -227,6 +232,9 @@ variable (C) section Iso +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ +set_option backward.isDefEq.respectTransparency.types false in /-- A homeomorphism of spaces gives an equivalence of categories of presheaves. -/ @[simps!] def presheafEquivOfIso {X Y : TopCat.{w}} (H : X ≅ Y) : X.Presheaf C ≌ Y.Presheaf C := @@ -241,6 +249,7 @@ def toPushforwardOfIso {X Y : TopCat.{w}} (H : X ≅ Y) {ℱ : X.Presheaf C} { (α : H.hom _* ℱ ⟶ 𝒢) : ℱ ⟶ H.inv _* 𝒢 := (presheafEquivOfIso _ H).toAdjunction.homEquiv ℱ 𝒢 α +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem toPushforwardOfIso_app {X Y : TopCat.{w}} (H₁ : X ≅ Y) {ℱ : X.Presheaf C} {𝒢 : Y.Presheaf C} @@ -257,6 +266,7 @@ def pushforwardToOfIso {X Y : TopCat.{w}} (H₁ : X ≅ Y) {ℱ : Y.Presheaf C} (H₂ : ℱ ⟶ H₁.hom _* 𝒢) : H₁.inv _* ℱ ⟶ 𝒢 := ((presheafEquivOfIso _ H₁.symm).toAdjunction.homEquiv ℱ 𝒢).symm H₂ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[simp] theorem pushforwardToOfIso_app {X Y : TopCat.{w}} (H₁ : X ≅ Y) {ℱ : Y.Presheaf C} {𝒢 : X.Presheaf C} diff --git a/Mathlib/Topology/Sheaves/Skyscraper.lean b/Mathlib/Topology/Sheaves/Skyscraper.lean index 1799712bd64344..b7c644818f625b 100644 --- a/Mathlib/Topology/Sheaves/Skyscraper.lean +++ b/Mathlib/Topology/Sheaves/Skyscraper.lean @@ -307,6 +307,7 @@ lemma germ_fromStalk {𝓕 : Presheaf C X} {c : C} (f : 𝓕 ⟶ skyscraperPresh 𝓕.germ U p₀ hU ≫ fromStalk p₀ f = f.app (op U) ≫ eqToHom (if_pos hU) := colimit.ι_desc _ _ +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in theorem to_skyscraper_fromStalk {𝓕 : Presheaf C X} {c : C} (f : 𝓕 ⟶ skyscraperPresheaf p₀ c) : toSkyscraperPresheaf p₀ (fromStalk _ f) = f := by @@ -317,6 +318,7 @@ theorem to_skyscraper_fromStalk {𝓕 : Presheaf C X} {c : C} (f : 𝓕 ⟶ skys · simp · exact ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext .. +set_option backward.isDefEq.respectTransparency.types false in theorem fromStalk_to_skyscraper {𝓕 : Presheaf C X} {c : C} (f : 𝓕.stalk p₀ ⟶ c) : fromStalk p₀ (toSkyscraperPresheaf _ f) = f := by refine 𝓕.stalk_hom_ext fun U hxU ↦ ?_ diff --git a/Mathlib/Topology/Sheaves/Stalks.lean b/Mathlib/Topology/Sheaves/Stalks.lean index 00d6b1c30ba650..664f9350f589a9 100644 --- a/Mathlib/Topology/Sheaves/Stalks.lean +++ b/Mathlib/Topology/Sheaves/Stalks.lean @@ -246,6 +246,7 @@ lemma germ_stalkPullbackHom ((pullback C f).obj F).germ ((Opens.map f).obj U) x hU := by simp [stalkPullbackHom, germ, stalkFunctor, stalkPushforward] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The morphism `(f⁻¹ℱ)(U) ⟶ ℱ_{f(x)}` for some `U ∋ x`. -/ def germToPullbackStalk (f : X ⟶ Y) (F : Y.Presheaf C) (U : Opens X) (x : X) (hx : x ∈ U) : @@ -256,6 +257,7 @@ def germToPullbackStalk (f : X ⟶ Y) (F : Y.Presheaf C) (U : Opens X) (x : X) ( { app := fun V => F.germ _ (f x) (V.hom.unop.le hx) naturality := fun _ _ i => by simp } } +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in variable {C} in @[ext] @@ -271,6 +273,7 @@ lemma pullback_obj_obj_ext {Z : C} {f : X ⟶ Y} {F : Y.Presheaf C} (U : (Opens simpa [pullbackPushforwardAdjunction, Functor.lanAdjunction_unit] using! h V (leOfHom b) +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma pullbackPushforwardAdjunction_unit_pullback_map_germToPullbackStalk @@ -294,6 +297,7 @@ lemma germToPullbackStalk_stalkPullbackHom simp only [pullbackPushforwardAdjunction_unit_pullback_map_germToPullbackStalk_assoc, germ_stalkPullbackHom, germ_res] +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] lemma pullbackPushforwardAdjunction_unit_app_app_germToPullbackStalk @@ -348,6 +352,7 @@ section stalkSpecializes variable {C} +set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `x` specializes to `y`, then there is a natural map `F.stalk y ⟶ F.stalk x`. -/ noncomputable def stalkSpecializes (F : X.Presheaf C) {x y : X} (h : x ⤳ y) : @@ -397,6 +402,7 @@ theorem stalkSpecializes_stalkPushforward (f : X ⟶ Y) (F : X.Presheaf C) {x y ext simp +set_option backward.isDefEq.respectTransparency.types false in /-- The stalks are isomorphic on inseparable points -/ @[simps] def stalkCongr (F : X.Presheaf C) {x y : X} @@ -454,6 +460,7 @@ theorem germ_eq (F : X.Presheaf C) {U V : Opens X} (x : X) (mU : x ∈ U) (mV : obtain ⟨W, iU, iV, e⟩ := (colimit.isColimit ((OpenNhds.inclusion x).op ⋙ F)).eq_iff.mp h exact ⟨(unop W).1, (unop W).2, iU.unop, iV.unop, e⟩ +set_option backward.isDefEq.respectTransparency.types false in theorem stalkFunctor_map_injective_of_app_injective {F G : Presheaf C X} {f : F ⟶ G} (h : ∀ U : Opens X, Function.Injective (f.app (op U))) (x : X) : Function.Injective ((stalkFunctor C x).map f) := fun s t hst => by @@ -473,12 +480,14 @@ variable {B : Set (Opens X)} (hB : Opens.IsBasis B) include hB +set_option backward.isDefEq.respectTransparency.types false in lemma exists_mem_germ_eq_of_isBasis (F : X.Presheaf C) (x : X) (t : ToType (F.stalk x)) : ∃ (U : Opens X) (m : x ∈ U) (_ : U ∈ B) (s : ToType (F.obj (op U))), F.germ _ x m s = t := by obtain ⟨U, hxU, s, rfl⟩ := F.exists_germ_eq t obtain ⟨_, ⟨V, hV, rfl⟩, hxV, hVU⟩ := hB.exists_subset_of_mem_open hxU U.2 exact ⟨V, hxV, hV, F.map (homOfLE hVU).op s, by rw [← ConcreteCategory.comp_apply, F.germ_res']⟩ +set_option backward.isDefEq.respectTransparency.types false in lemma germ_eq_of_isBasis (F : X.Presheaf C) {U V : Opens X} (x : X) (mU : x ∈ U) (mV : x ∈ V) {s : ToType (F.obj (op U))} {t : ToType (F.obj (op V))} (h : F.germ U x mU s = F.germ V x mV t) : @@ -527,6 +536,7 @@ Note that the analogous statement for surjectivity is false: Surjectivity on sta imply surjectivity of the components of a sheaf morphism. However it does imply that the morphism is an epi, but this fact is not yet formalized. -/ +set_option backward.isDefEq.respectTransparency.types false in theorem app_injective_of_stalkFunctor_map_injective {F : Sheaf C X} {G : Presheaf C X} (f : F.1 ⟶ G) (U : Opens X) (h : ∀ x ∈ U, Function.Injective ((stalkFunctor C x).map f)) : Function.Injective (f.app (op U)) := fun s t hst => @@ -573,6 +583,7 @@ theorem mono_iff_stalk_mono {F G : Sheaf C X} (f : F ⟶ G) : Mono f ↔ ∀ x, Mono ((stalkFunctor C x).map f.1) := ⟨fun _ => stalk_mono_of_mono _, fun _ => mono_of_stalk_mono _⟩ +set_option backward.isDefEq.respectTransparency.types false in /-- For surjectivity, we are given an arbitrary section `t` and need to find a preimage for it. We claim that it suffices to find preimages *locally*. That is, for each `x : U` we construct a neighborhood `V ≤ U` and a section `s : F.obj (op V))` such that `f.app (op V) s` and `t` diff --git a/Mathlib/Topology/Sober.lean b/Mathlib/Topology/Sober.lean index 30a25e0eba280b..1bd563a1fb6ff8 100644 --- a/Mathlib/Topology/Sober.lean +++ b/Mathlib/Topology/Sober.lean @@ -156,6 +156,7 @@ theorem genericPoint_specializes [QuasiSober α] [IrreducibleSpace α] (x : α) attribute [local instance] specializationOrder +set_option backward.isDefEq.respectTransparency false in /-- The closed irreducible subsets of a sober space bijects with the points of the space. -/ noncomputable def irreducibleSetEquivPoints [QuasiSober α] [T0Space α] : TopologicalSpace.IrreducibleCloseds α ≃o α where diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 307c535b393481..783df677de583f 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -38,7 +38,7 @@ def constructibleTopologySubbasis (X : Type*) [TopologicalSpace X] : Set (Set X) /-- The constructible topology on a topological space `X` has as a subbasis the open and compact sets of `X` and their complements. -/ -@[implicit_reducible] +@[instance_reducible] def constructibleTopology (X : Type*) [TopologicalSpace X] : TopologicalSpace X := .generateFrom (constructibleTopologySubbasis X) diff --git a/Mathlib/Topology/TietzeExtension.lean b/Mathlib/Topology/TietzeExtension.lean index 1f18c899836993..988717457d4e58 100644 --- a/Mathlib/Topology/TietzeExtension.lean +++ b/Mathlib/Topology/TietzeExtension.lean @@ -69,6 +69,7 @@ theorem ContinuousMap.exists_restrict_eq (hs : IsClosed s) (f : C(s, Y)) : ∃ (g : C(X, Y)), g.restrict s = f := TietzeExtension.exists_restrict_eq' s hs f +set_option backward.isDefEq.respectTransparency false in /-- **Tietze extension theorem** for `TietzeExtension` spaces. Let `e` be a closed embedding of a nonempty topological space `X₁` into a normal topological space `X`. Let `f` be a continuous function on `X₁` with values in a `TietzeExtension` space `Y`. Then there exists a @@ -512,6 +513,7 @@ instance Real.instTietzeExtension : TietzeExtension ℝ where f.exists_restrict_eq_forall_mem_of_closed (fun _ => mem_univ _) univ_nonempty hs |>.imp fun _ ↦ (And.right ·) +set_option backward.isDefEq.respectTransparency false in open NNReal in /-- **Tietze extension theorem** for nonnegative real-valued continuous maps. `ℝ≥0` is a `TietzeExtension` space. -/ diff --git a/Mathlib/Topology/UniformSpace/AbsoluteValue.lean b/Mathlib/Topology/UniformSpace/AbsoluteValue.lean index ab8d8149b1dc0e..c95e2e750ae7c2 100644 --- a/Mathlib/Topology/UniformSpace/AbsoluteValue.lean +++ b/Mathlib/Topology/UniformSpace/AbsoluteValue.lean @@ -36,7 +36,7 @@ variable {𝕜 : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing variable {R : Type*} [CommRing R] (abv : AbsoluteValue R 𝕜) /-- The uniform structure coming from an absolute value. -/ -@[implicit_reducible] +@[instance_reducible] def uniformSpace : UniformSpace R := .ofFun (fun x y => abv (y - x)) (by simp) (fun x y => abv.map_sub y x) (fun _ _ _ => (abv.sub_le _ _ _).trans_eq (add_comm _ _)) diff --git a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean index 7b95754309a634..83a6a2d541fafb 100644 --- a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean +++ b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean @@ -378,6 +378,7 @@ end T0Space variable {f : α → β → γ} variable [CompleteSpace γ] (f) +set_option backward.isDefEq.respectTransparency false in @[fun_prop] theorem uniformContinuous_extension₂ : UniformContinuous₂ (pkg.extend₂ pkg' f) := by rw [uniformContinuous₂_def, AbstractCompletion.extend₂, uncurry_curry] diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index 17cc02dd2e4d84..1e5b907aeebbe1 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -161,7 +161,7 @@ def UniformSpace.Core.mkOfBasis {α : Type u} (B : FilterBasis (α × α)) comp := ((B.hasBasis.lift' (monotone_id.relComp monotone_id)).le_basis_iff B.hasBasis).2 comp /-- A uniform space generates a topological space -/ -@[implicit_reducible] +@[instance_reducible] def UniformSpace.Core.toTopologicalSpace {α : Type u} (u : UniformSpace.Core α) : TopologicalSpace α := .mkOfNhds fun x ↦ .comap (Prod.mk x) u.uniformity diff --git a/Mathlib/Topology/UniformSpace/OfCompactT2.lean b/Mathlib/Topology/UniformSpace/OfCompactT2.lean index d6d172b2e99a59..bb39019ae836f8 100644 --- a/Mathlib/Topology/UniformSpace/OfCompactT2.lean +++ b/Mathlib/Topology/UniformSpace/OfCompactT2.lean @@ -40,7 +40,7 @@ variable {γ : Type*} /-- The unique uniform structure inducing a given compact topological structure. -/ -@[implicit_reducible] +@[instance_reducible] def uniformSpaceOfCompactR1 [TopologicalSpace γ] [CompactSpace γ] [R1Space γ] : UniformSpace γ where uniformity := 𝓝ˢ (diagonal γ) symm := continuous_swap.tendsto_nhdsSet fun _ => Eq.symm diff --git a/Mathlib/Topology/UniformSpace/OfFun.lean b/Mathlib/Topology/UniformSpace/OfFun.lean index 5cf81b8e13dbbb..d6ff09a0f4dbad 100644 --- a/Mathlib/Topology/UniformSpace/OfFun.lean +++ b/Mathlib/Topology/UniformSpace/OfFun.lean @@ -29,7 +29,7 @@ namespace UniformSpace /-- Define a `UniformSpace` using a "distance" function. The function can be, e.g., the distance in a (usual or extended) metric space or an absolute value on a ring. -/ -@[implicit_reducible] +@[instance_reducible] def ofFun [AddCommMonoid M] [PartialOrder M] (d : X → X → M) (refl : ∀ x, d x x = 0) (symm : ∀ x y, d x y = d y x) (triangle : ∀ x y z, d x z ≤ d x y + d y z) @@ -60,7 +60,7 @@ distance in a (usual or extended) metric space or an absolute value on a ring. W there is a preexisting topology, for which the neighborhoods can be expressed using the "distance", and we make sure that the uniform space structure we construct has a topology which is defeq to the original one. -/ -@[implicit_reducible] +@[instance_reducible] def ofFunOfHasBasis [t : TopologicalSpace X] [AddCommMonoid M] [LinearOrder M] (d : X → X → M) (refl : ∀ x, d x x = 0) (symm : ∀ x y, d x y = d y x) (triangle : ∀ x y z, d x z ≤ d x y + d y z) diff --git a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean index 7d76a76a21dc7e..7b7f4bf22f58df 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean @@ -483,6 +483,7 @@ protected def uniformEquivProdArrow [UniformSpace γ] : (α →ᵤ β × γ) ≃ -- the relevant diagram commutes by definition variable (α) (δ : ι → Type*) [∀ i, UniformSpace (δ i)] +set_option backward.isDefEq.respectTransparency false in /-- The natural bijection between `α → Π i, δ i` and `Π i, α → δ i`, upgraded to a uniform isomorphism between `α →ᵤ (Π i, δ i)` and `Π i, α →ᵤ δ i`. -/ protected def uniformEquivPiComm : UniformEquiv (α →ᵤ ∀ i, δ i) (∀ i, α →ᵤ δ i) := @@ -623,6 +624,7 @@ protected theorem topologicalSpace_eq : simp only [UniformOnFun.topologicalSpace, UniformSpace.toTopologicalSpace_iInf] rfl +set_option backward.isDefEq.respectTransparency false in protected theorem hasBasis_uniformity_of_basis_aux₁ {p : ι → Prop} {s : ι → Set (β × β)} (hb : HasBasis (𝓤 β) p s) (S : Set α) : (@uniformity (α →ᵤ[𝔖] β) ((UniformFun.uniformSpace S β).comap S.restrict)).HasBasis p fun i => @@ -824,7 +826,7 @@ lemma uniformContinuous_ofFun_toFun (𝔗 : Set (Set α)) (h : ∀ s ∈ 𝔖, intro s hs obtain ⟨T, hT𝔗, hT, hsT⟩ := h s hs refine ⟨T, hT, hT𝔗, fun f hf ↦ ?_⟩ - simp only [UniformOnFun.gen, Set.mem_iInter, Set.mem_setOf_eq, Function.comp_apply] at hf ⊢ + simp only [UniformOnFun.gen, Set.mem_iInter, Set.mem_setOf_eq] at hf ⊢ intro x hx obtain ⟨t, ht, hxt⟩ := Set.mem_sUnion.mp <| hsT hx exact hf t ht x hxt @@ -1115,6 +1117,7 @@ theorem isClosed_setOf_continuous [TopologicalSpace α] (h : IsCoherentWith 𝔖 rw [← tendsto_id', UniformOnFun.tendsto_iff_tendstoUniformlyOn] at huf exact (huf s hs).continuousOn <| Eventually.frequently <| hu fun _ ↦ Continuous.continuousOn +set_option backward.isDefEq.respectTransparency false in variable (𝔖) in theorem uniformSpace_eq_inf_precomp_of_cover {δ₁ δ₂ : Type*} (φ₁ : δ₁ → α) (φ₂ : δ₂ → α) (𝔗₁ : Set (Set δ₁)) (𝔗₂ : Set (Set δ₂)) @@ -1141,6 +1144,7 @@ theorem uniformSpace_eq_inf_precomp_of_cover {δ₁ δ₂ : Type*} (φ₁ : δ (iInf₂_le_of_le _ (h_preimage₁ hS) le_rfl) (iInf₂_le_of_le _ (h_preimage₂ hS) le_rfl) +set_option backward.isDefEq.respectTransparency false in variable (𝔖) in theorem uniformSpace_eq_iInf_precomp_of_cover {δ : ι → Type*} (φ : Π i, δ i → α) (𝔗 : ∀ i, Set (Set (δ i))) (h_image : ∀ i, MapsTo (φ i '' ·) (𝔗 i) 𝔖) diff --git a/Mathlib/Topology/UniformSpace/UniformEmbedding.lean b/Mathlib/Topology/UniformSpace/UniformEmbedding.lean index 9a494e7eedb9ec..59f59e7cb5ef3a 100644 --- a/Mathlib/Topology/UniformSpace/UniformEmbedding.lean +++ b/Mathlib/Topology/UniformSpace/UniformEmbedding.lean @@ -417,7 +417,7 @@ theorem isUniformEmbedding_comap {α : Type*} {β : Type*} {f : α → β} [u : /-- Pull back a uniform space structure by an embedding, adjusting the new uniform structure to make sure that its topology is defeq to the original one. -/ -@[implicit_reducible] +@[instance_reducible] def Topology.IsEmbedding.comapUniformSpace {α β} [TopologicalSpace α] [u : UniformSpace β] (f : α → β) (h : IsEmbedding f) : UniformSpace α := (u.comap f).replaceTopology h.eq_induced diff --git a/Mathlib/Topology/UnitInterval.lean b/Mathlib/Topology/UnitInterval.lean index 3e370fad2d3f49..819658eb1ff1dd 100644 --- a/Mathlib/Topology/UnitInterval.lean +++ b/Mathlib/Topology/UnitInterval.lean @@ -508,7 +508,7 @@ theorem projIcc_eq_zero {x : ℝ} : projIcc (0 : ℝ) 1 zero_le_one x = 0 ↔ x theorem projIcc_eq_one {x : ℝ} : projIcc (0 : ℝ) 1 zero_le_one x = 1 ↔ 1 ≤ x := projIcc_eq_right zero_lt_one -namespace Tactic.Interactive +namespace Mathlib.Tactic.Interactive /-- `unit_interval` solves the goals `0 ≤ ↑x`, `0 ≤ 1 - ↑x`, `↑x ≤ 1`, and `1 - ↑x ≤ 1` for @@ -523,13 +523,14 @@ macro "unit_interval" : tactic => example (x : unitInterval) : 0 ≤ (x : ℝ) := by unit_interval -end Tactic.Interactive +end Mathlib.Tactic.Interactive section variable {𝕜 : Type*} [Field 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] [TopologicalSpace 𝕜] [IsTopologicalRing 𝕜] +set_option backward.isDefEq.respectTransparency false in -- We only need the ordering on `𝕜` here to avoid talking about flipping the interval over. -- At the end of the day I only care about `ℝ`, so I'm hesitant to put work into generalizing. /-- The image of `[0,1]` under the homeomorphism `fun x ↦ a * x + b` is `[b, a+b]`. diff --git a/Mathlib/Topology/VectorBundle/Basic.lean b/Mathlib/Topology/VectorBundle/Basic.lean index 8c57a42fefaa60..475928158c9177 100644 --- a/Mathlib/Topology/VectorBundle/Basic.lean +++ b/Mathlib/Topology/VectorBundle/Basic.lean @@ -870,7 +870,7 @@ def toFiberPrebundle (a : VectorPrebundle R F E) : FiberPrebundle F E := rw [a.mk_coordChange _ _ hb, e'.mk_symm hb.1] } /-- Topology on the total space that will make the prebundle into a bundle. -/ -@[implicit_reducible] +@[instance_reducible] def totalSpaceTopology (a : VectorPrebundle R F E) : TopologicalSpace (TotalSpace F E) := a.toFiberPrebundle.totalSpaceTopology @@ -906,10 +906,11 @@ theorem continuous_totalSpaceMk (b : B) : /-- Make a `FiberBundle` from a `VectorPrebundle`; auxiliary construction for `VectorPrebundle.toVectorBundle`. -/ -@[implicit_reducible] +@[instance_reducible] def toFiberBundle : @FiberBundle B F _ _ _ a.totalSpaceTopology _ := a.toFiberPrebundle.toFiberBundle +set_option backward.isDefEq.respectTransparency false in /-- Make a `VectorBundle` from a `VectorPrebundle`. Concretely this means that, given a `VectorPrebundle` structure for a sigma-type `E` -- which consists of a number of "pretrivializations" identifying parts of `E` with product spaces `U × F` -- one diff --git a/Mathlib/Topology/VectorBundle/Constructions.lean b/Mathlib/Topology/VectorBundle/Constructions.lean index 6851c1994c7c01..6f9dfc1b34636e 100644 --- a/Mathlib/Topology/VectorBundle/Constructions.lean +++ b/Mathlib/Topology/VectorBundle/Constructions.lean @@ -80,6 +80,7 @@ instance vectorBundle : VectorBundle 𝕜 F (Bundle.Trivial B F) where (trivialization B F).symmL 𝕜 x = ContinuousLinearMap.id 𝕜 F := by ext; simp [trivialization_symm_apply B F] +set_option backward.isDefEq.respectTransparency false in @[simp] lemma continuousLinearEquivAt_trivialization (x : B) : (trivialization B F).continuousLinearEquivAt 𝕜 x (mem_univ _) = ContinuousLinearEquiv.refl 𝕜 F := by diff --git a/Mathlib/Util/AddRelatedDecl.lean b/Mathlib/Util/AddRelatedDecl.lean index 456f300be06a66..0f07b618931dfc 100644 --- a/Mathlib/Util/AddRelatedDecl.lean +++ b/Mathlib/Util/AddRelatedDecl.lean @@ -7,6 +7,7 @@ module public import Mathlib.Init public meta import Lean.Elab.DeclarationRange +public meta import Lean.Linter.TacticTypeCheck /-! # `addRelatedDecl` @@ -27,6 +28,55 @@ def elabOptAttrArg : TSyntax ``optAttrArg → TermElabM (Array Attribute) | `(optAttrArg| (attr := $[$attrs],*)) => elabAttrs attrs | _ => pure #[] +/-- Re-implementation of the inner loop of `Lean.Linter.tacticCheckInstances` for use on +declarations synthesized by Mathlib attributes (`@[simps]`, `@[reassoc]`, `@[elementwise]`, ...). +Returns the list of semireducible non-instance definitions that `Meta.check declType .default` +had to unfold but `Meta.check declType .implicit` would not, or `none` if `declType` already +passes the `.implicit` check. -/ +private def checkImplicitTransparency (declType : Expr) : MetaM (Option (List Name)) := do + let origDiag := (← get).diag + let result : Option (List Name) ← withOptions (diagnostics.set · true) do + try Meta.check declType .default catch _ => return none + let counterDefault := (← get).diag.unfoldCounter + modify ({ · with diag := origDiag }) + try + Meta.check declType .implicit + return none + catch _ => + let counterInst := (← get).diag.unfoldCounter + let diff := Meta.subCounters counterDefault counterInst + let env ← getEnv + return some <| diff.toList.filterMap fun (n, count) => do + guard <| count > 0 + guard <| getReducibilityStatusCore env n matches .semireducible + guard <| !Meta.isInstanceCore env n + return n + -- Always restore the original diagnostics snapshot, mirroring `tacticCheckInstances`. + modify ({ · with diag := origDiag }) + return result + +/-- Extension of `linter.tacticCheckInstances` to lemmas produced by Mathlib attributes such as +`@[simps]`, `@[reassoc]`, and `@[elementwise]`. Call sites pass the syntax of the user's +attribute (`ref`), the name of the generated lemma (`declName`), and the lemma's type +(`declType`); a warning is emitted at `ref` if `declType` is type-correct at `.default` but +not at `.implicit`, listing the semireducible definitions that would need to be +marked `@[implicit_reducible]` to fix the mismatch. + +The check is gated by the existing core option `linter.tacticCheckInstances` and is silent +otherwise; following the convention of the core linter, it does *not* participate in +`linter.all`. -/ +def warnIfImplicitIllTyped (ref : Syntax) (declName : Name) (declType : Expr) : MetaM Unit := do + let lintOpt : Lean.Option Bool := + { name := `linter.tacticCheckInstances, defValue := false } + unless lintOpt.get (← getOptions) do return + let some candidates ← checkImplicitTransparency declType | return + if candidates.isEmpty then return + let bullets := MessageData.joinSep (candidates.map (m!"{MessageData.ofConstName ·}")) Format.line + Lean.Linter.logLint lintOpt ref + m!"generated lemma {MessageData.ofConstName declName} is not type-correct at \ + `.implicit` transparency; consider marking some of the following as \ + `@[implicit_reducible]`:{indentD bullets}" + /-- A helper function for constructing a related declaration from an existing one. This is currently used by the attributes `reassoc` and `elementwise`, @@ -77,6 +127,7 @@ def addRelatedDecl (src tgt : Name) (ref : Syntax) let newValue ← instantiateMVars newValue let newType ← instantiateMVars (← inferType newValue) unless ← isProp newType do throwError "Related declaration is not a proposition: {newType}" + warnIfImplicitIllTyped ref tgt newType addDecl <| ← mkThmOrUnsafeDef { levelParams := newLevels, type := newType, name := tgt, value := newValue } if isProtected (← getEnv) src then diff --git a/Mathlib/Util/CompileInductive.lean b/Mathlib/Util/CompileInductive.lean index 780897eb602329..5539c0fff139e5 100644 --- a/Mathlib/Util/CompileInductive.lean +++ b/Mathlib/Util/CompileInductive.lean @@ -258,28 +258,11 @@ compile_inductive% Option compile_def% False.recOn compile_def% Empty.recOn --- In addition to the manual implementation below, we also have to override the `Float.val` and --- `Float.mk` functions because these also have no implementation in core lean. --- Because `floatSpec.float` is an opaque type, the identity function is as good an implementation --- as any. -private unsafe def Float.valUnsafe : Float → floatSpec.float := unsafeCast -private unsafe def Float.mkUnsafe : floatSpec.float → Float := unsafeCast -@[implemented_by Float.valUnsafe] private def Float.valImpl (x : Float) : floatSpec.float := x.1 -@[implemented_by Float.mkUnsafe] private def Float.mkImpl (x : floatSpec.float) : Float := ⟨x⟩ - -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in -@[csimp] private theorem Float.val_eq : @Float.val = Float.valImpl := rfl - -set_option backward.privateInPublic true in -set_option backward.privateInPublic.warn false in -@[csimp] private theorem Float.mk_eq : @Float.mk = Float.mkImpl := rfl - -- These types need manual implementations because the default implementation in `compileStruct` -- uses `Expr.proj` which has an invalid IR type. open Lean Meta Elab Mathlib.Util in run_cmd Command.liftTermElabM do - for n in [``UInt8, ``UInt16, ``UInt32, ``UInt64, ``USize, ``Float] do + for n in [``UInt8, ``UInt16, ``UInt32, ``UInt64, ``USize, ``Float, ``Float32] do let iv ← getConstInfoInduct n let rv ← getConstInfoRec <| mkRecName n let value ← Elab.Term.elabTerm (← `(fun H t => H t.1)) diff --git a/MathlibTest/CategoryTheory/FunctorAssoc.lean b/MathlibTest/CategoryTheory/FunctorAssoc.lean index b18f255f1756e1..e0f1e3d7c9325f 100644 --- a/MathlibTest/CategoryTheory/FunctorAssoc.lean +++ b/MathlibTest/CategoryTheory/FunctorAssoc.lean @@ -18,6 +18,16 @@ can be inferred from an instance for each of the functors. Taking into account the placement of parentheses, we want to allow `(F ⋙ G) ⋙ H` and `F ⋙ (G ⋙ H)` to have their own instances (even though they are usually propositionally equal). + +Currently, `Functor.comp` has the attribute `implicit_reducible` which +allows Lean to see through the definition of the `obj/map` fields of +compositions of functors, while allowing `(F ⋙ G) ⋙ H` and `F ⋙ (G ⋙ H)` +to have their own instances. In order to keep allowing different instances +for these two "identical" functors, we must not make `Functor.comp` +more reducible: in particular, if `Functor.comp` had the attribute +`instance_reducible`, an instance for `(F ⋙ G) ⋙ H` would be found +when there is an instance for `F ⋙ (G ⋙ H)` (which would be bad). + -/ /-! The two following tests ensure that for the typeclass `Foo`, @@ -58,4 +68,11 @@ example [F.Foo] [G.Foo] [H.Foo] : fail_if_success rfl exact Nat.add_assoc _ _ _ +-- This test demonstrates that if `Functor.comp` had the attribute +-- `instance_reducible`, an instance for `(F ⋙ G) ⋙ H` would be +-- found when `F ⋙ (G ⋙ H)` has an instance. +set_option allowUnsafeReducibility true +attribute [local instance_reducible] Functor.comp in +example [(F ⋙ (G ⋙ H)).Foo] : ((F ⋙ G) ⋙ H).Foo := inferInstance + end CategoryTheory.Functor diff --git a/MathlibTest/ClickSuggestions/Benchmark.lean b/MathlibTest/ClickSuggestions/Benchmark.lean index a32f6da0c9eede..9c4fe85db54d99 100644 --- a/MathlibTest/ClickSuggestions/Benchmark.lean +++ b/MathlibTest/ClickSuggestions/Benchmark.lean @@ -32,7 +32,8 @@ def measureImport (choice : Choice) : MetaM (Nat × PreDiscrTrees) := do run_meta let (all, _) ← measureImport { rw := true, grw := true, app := true, appAt := true } - guard (all < 20_000) + -- Generous limit: wall-clock time is heavily inflated on loaded CI machines. + guard (all < 60_000) def measureEach : MetaM MessageData := do let (rw, _) ← measureImport { rw := true, grw := false, app := false, appAt := false } diff --git a/MathlibTest/DefEqAbuse.lean b/MathlibTest/DefEqAbuse.lean index 77e1a9976f4270..0db094fae6f786 100644 --- a/MathlibTest/DefEqAbuse.lean +++ b/MathlibTest/DefEqAbuse.lean @@ -128,9 +128,9 @@ def myOp {α : Type} [AddCommGroup α] [MyAction ℕ α] (x : α) : α := def testVirtualParent {G : Type} [AddCommGroup G] (s : MySub₂ G) (x : s) : s := myOp x --- The fix: marking the virtual parent `def` as `@[implicit_reducible]` makes it +-- The fix: marking the virtual parent `def` as `@[instance_reducible]` makes it -- transparent enough for instance synthesis to unify the two `AddCommMonoid` paths. -attribute [implicit_reducible] MySub₂.toAddSubgroup +attribute [instance_reducible] MySub₂.toAddSubgroup /-- info: #defeq_abuse: command succeeds with `backward.isDefEq.respectTransparency true`. No abuse detected. -/ #guard_msgs in diff --git a/MathlibTest/DeriveFintype.lean b/MathlibTest/DeriveFintype.lean index 9e18b7a194c081..15f8ff3fbe4ed4 100644 --- a/MathlibTest/DeriveFintype.lean +++ b/MathlibTest/DeriveFintype.lean @@ -12,6 +12,7 @@ namespace tests Tests that the enumerable types succeed, even with universe levels. -/ +set_option backward.isDefEq.respectTransparency false in inductive A | x | y | z deriving Fintype @@ -21,6 +22,7 @@ info: tests.A.enumList : List A #guard_msgs in #check A.enumList +set_option backward.isDefEq.respectTransparency false in inductive A' : Type u | x | y | z deriving Fintype @@ -30,6 +32,7 @@ info: tests.A'.enumList.{u} : List A' #guard_msgs in #check A'.enumList +set_option backward.isDefEq.respectTransparency false in inductive A'' : Type 1 | x | y | z deriving Fintype @@ -160,6 +163,7 @@ instance (s : Set α) [Fintype α] [DecidablePred (· ∈ s)] : Fintype (MySubty Tests from mathlib 3 -/ +set_option backward.isDefEq.respectTransparency false in inductive Alphabet | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z diff --git a/MathlibTest/FastInstance.lean b/MathlibTest/FastInstance.lean index c1e013721ebc70..5cf9c4a9bf2fea 100644 --- a/MathlibTest/FastInstance.lean +++ b/MathlibTest/FastInstance.lean @@ -62,14 +62,14 @@ instance instCommSemigroup [CommSemigroup α] : CommSemigroup (Wrapped α) := fast_instance% Function.Injective.commSemigroup _ val_injective (fun _ _ => rfl) /-- -info: @[implicit_reducible] def testing.instSemigroup.{u_1} : {α : Type u_1} → [Semigroup α] → Semigroup (Wrapped α) := +info: @[instance_reducible] def testing.instSemigroup.{u_1} : {α : Type u_1} → [Semigroup α] → Semigroup (Wrapped α) := fun {α} [inst : Semigroup α] => @Semigroup.mk (Wrapped α) (@instMulWrapped α (@Semigroup.toMul α inst)) ⋯ -/ #guard_msgs in set_option pp.explicit true in #print instSemigroup /-- -info: @[implicit_reducible] def testing.instCommSemigroup.{u_1} : {α : Type u_1} → +info: @[instance_reducible] def testing.instCommSemigroup.{u_1} : {α : Type u_1} → [CommSemigroup α] → CommSemigroup (Wrapped α) := fun {α} [inst : CommSemigroup α] => @CommSemigroup.mk (Wrapped α) (@instSemigroup α (@CommSemigroup.toSemigroup α inst)) ⋯ diff --git a/MathlibTest/InferInstanceAsPercent.lean b/MathlibTest/InferInstanceAsPercent.lean index e86e263fa2b193..53bc864a9f7ccd 100644 --- a/MathlibTest/InferInstanceAsPercent.lean +++ b/MathlibTest/InferInstanceAsPercent.lean @@ -24,7 +24,7 @@ instance : MyInv Nat where def MyNat : Type := Nat -- `inferInstanceAs` leaks the source type `Nat` as the carrier -@[implicit_reducible] +@[instance_reducible] def myNatInv_leaky : MyInv MyNat := inferInstanceAs (MyInv Nat) @@ -34,7 +34,7 @@ instance myNatInv_fixed : MyInv MyNat := -- The binder type is `MyNat`: /-- -info: @[implicit_reducible] def myNatInv_fixed : MyInv MyNat := +info: @[instance_reducible] def myNatInv_fixed : MyInv MyNat := { myInv := fun (a : MyNat) => (Nat.add a 0).succ } -/ #guard_msgs in @@ -75,7 +75,7 @@ instance : TestField Nat where def TestNat := Nat -- Direct instance: all lambda domains correctly use TestNat -@[implicit_reducible] +@[instance_reducible] def testField_direct : TestField TestNat where inv n := n mul := Nat.mul @@ -83,11 +83,11 @@ def testField_direct : TestField TestNat where neg n := n -- Leaky: internal lambda domains use Nat instead of TestNat -@[implicit_reducible] +@[instance_reducible] def testField_leaky : TestField TestNat := inferInstanceAs (TestField Nat) -- Fixed: inferInstanceAs% patches lambda domains to use TestNat -@[implicit_reducible] +@[instance_reducible] def testField_fixed : TestField TestNat := inferInstanceAs% (TestField Nat) -- All three are defeq at default transparency (Nat = TestNat at this level). diff --git a/MathlibTest/InstanceDiamonds.lean b/MathlibTest/InstanceDiamonds.lean index 17ead3a7c8b831..1e75f7ca3ceaf6 100644 --- a/MathlibTest/InstanceDiamonds.lean +++ b/MathlibTest/InstanceDiamonds.lean @@ -66,6 +66,7 @@ noncomputable def f : ℂ ⊗[ℝ] ℂ →ₗ[ℝ] ℝ := map_add' := fun z w => by simp [add_smul] map_smul' := fun r z => by simp [mul_smul] } +set_option backward.isDefEq.respectTransparency false in @[simp] theorem f_apply (z w : ℂ) : f (z ⊗ₜ[ℝ] w) = z.re * w.re := by simp [f] diff --git a/MathlibTest/Linter/Whitespace.lean b/MathlibTest/Linter/Whitespace.lean index b19b94f2b5db63..704aa027125f20 100644 --- a/MathlibTest/Linter/Whitespace.lean +++ b/MathlibTest/Linter/Whitespace.lean @@ -466,7 +466,8 @@ example {a :Nat} : a = a := rfl /-- warning: Variable name `b` is not explicitly referenced. -The binding can be removed (if unused) or named `_` (if used implicitly). +Hint: The binding can be removed (if unused) or named `_` (if used implicitly). Alternatively, prefix the name with `_` to silence this warning: + [apply] _b Note: This linter can be disabled with `set_option linter.unusedVariables false` --- diff --git a/MathlibTest/Simproc/VecPerm.lean b/MathlibTest/Simproc/VecPerm.lean index d56611f093b1c9..e7a211320fc7cb 100644 --- a/MathlibTest/Simproc/VecPerm.lean +++ b/MathlibTest/Simproc/VecPerm.lean @@ -12,12 +12,15 @@ example : ![a, b, c] ∘ Equiv.swap 0 1 = ![b, a, c] := by example : ![a, b, c] ∘ Equiv.swap 0 2 = ![c, b, a] := by simp [vecPerm, Equiv.swap_apply_def] +set_option backward.isDefEq.respectTransparency false in example : ![a, b, c] ∘ c[0, 1] = ![b, a, c] := by simp -- this is dealt with using `Matrix.cons_cons_comp_swap_zero_one` +set_option backward.isDefEq.respectTransparency false in example : ![a, b, c] ∘ c[2, 0, 1] = ![b, c, a] := by simp [vecPerm, Equiv.swap_apply_def] +set_option backward.isDefEq.respectTransparency false in example : ![a, b, c, d] ∘ c[2, 3, 0, 1] = ![b, c, d, a] := by simp [vecPerm, Equiv.swap_apply_def] diff --git a/MathlibTest/TacticCheckInstancesReassoc.lean b/MathlibTest/TacticCheckInstancesReassoc.lean new file mode 100644 index 00000000000000..80bf729be98107 --- /dev/null +++ b/MathlibTest/TacticCheckInstancesReassoc.lean @@ -0,0 +1,45 @@ +import Mathlib.Tactic.CategoryTheory.Reassoc + +set_option linter.tacticCheckInstances true + +open CategoryTheory + +universe v u + +variable {C : Type u} [Category.{v} C] + +/-! reassoc on a clean lemma, no warning expected. -/ + +#guard_msgs in +@[reassoc] +lemma clean_lem {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) (h : X ⟶ Z) (w : f ≫ g = h) : + f ≫ g = h := w + + +/-! a semireducible alias used for `.implicit`-ill-typed equation -/ + +def MyHom (X Y : C) : Type v := X ⟶ Y + +/-- +warning: generated lemma alias_lem_assoc is not type-correct at `.implicit` transparency; consider marking some of the following as `@[implicit_reducible]`: + Quiver.Hom + MyHom + +Note: This linter can be disabled with `set_option linter.tacticCheckInstances false` +-/ +#guard_msgs in +@[reassoc] +lemma alias_lem {X Y Z : C} (f : MyHom X Y) (g : Y ⟶ Z) (h : MyHom X Z) + (w : (f : X ⟶ Y) ≫ g = h) : + (f : X ⟶ Y) ≫ g = h := w + +/-! marking the offenders `@[implicit_reducible]` silences the warning -/ + +set_option allowUnsafeReducibility true +attribute [implicit_reducible] Quiver.Hom MyHom + +#guard_msgs in +@[reassoc] +lemma alias_lem2 {X Y Z : C} (f : MyHom X Y) (g : Y ⟶ Z) (h : MyHom X Z) + (w : (f : X ⟶ Y) ≫ g = h) : + (f : X ⟶ Y) ≫ g = h := w diff --git a/MathlibTest/TacticCheckInstancesSimps.lean b/MathlibTest/TacticCheckInstancesSimps.lean new file mode 100644 index 00000000000000..86abf922ba6c11 --- /dev/null +++ b/MathlibTest/TacticCheckInstancesSimps.lean @@ -0,0 +1,38 @@ +import Mathlib.Tactic.Simps.Basic + +set_option linter.tacticCheckInstances true + +/-! ## clean projection, no warning expected -/ + +structure Wrap (α : Type) where + carrier : List α + +#guard_msgs in +@[simps] +def mkWrap (s : List Nat) : Wrap Nat := { carrier := s } + +/-! a semireducible alias `.implicit`-ill-typed equation. -/ + +structure Fn where + toFun : Nat → Nat + +def MyFn : Type := Fn + +/-- +warning: generated lemma idFn_toFun is not type-correct at `.implicit` transparency; consider marking some of the following as `@[implicit_reducible]`: + MyFn + +Note: This linter can be disabled with `set_option linter.tacticCheckInstances false` +-/ +#guard_msgs in +@[simps] +def idFn : MyFn := ({ toFun := id } : Fn) + +/-! marking the offender `@[implicit_reducible]` silences the warning -/ + +set_option allowUnsafeReducibility true +attribute [implicit_reducible] MyFn + +#guard_msgs in +@[simps] +def idFn2 : MyFn := ({ toFun := id } : Fn) diff --git a/MathlibTest/depRewrite.lean b/MathlibTest/depRewrite.lean index d8beb297c52e06..585c57a4264e47 100644 --- a/MathlibTest/depRewrite.lean +++ b/MathlibTest/depRewrite.lean @@ -250,6 +250,7 @@ theorem let_defeq_test (b : Nat) (eq : 1 = b) (f : (n : Nat) → n = 1 → Nat) exact test_sorry -- Test definitional equalities that get broken by rewriting. +set_option backward.isDefEq.respectTransparency false in example (b : Bool) (h : true = b) (s : Bool → Prop) (q : (c : Bool) → s c → Prop) @@ -260,6 +261,7 @@ example (b : Bool) (h : true = b) exact test_sorry -- As above. +set_option backward.isDefEq.respectTransparency false in example (b : Bool) (h : true = b) (s : Bool → Prop) (q : (c : Bool) → s c → Prop) @@ -272,6 +274,7 @@ example (b : Bool) (h : true = b) exact test_sorry -- As above. +set_option backward.isDefEq.respectTransparency false in example (b : Bool) (h : true = b) (s : Bool → Prop) (q : (c : Bool) → s c → Prop) diff --git a/MathlibTest/matrix.lean b/MathlibTest/matrix.lean index 536de7198fde2c..75a20346778c77 100644 --- a/MathlibTest/matrix.lean +++ b/MathlibTest/matrix.lean @@ -165,6 +165,7 @@ example {α : Type _} [CommRing α] {a b c d e f g h i : α} : Finset.card_singleton, one_smul] ring +set_option backward.isDefEq.respectTransparency false in example {R : Type*} [Semiring R] {a b c d : R} : !![a, b] * (transpose !![c, d]) = !![a * c + b * d] := by ext i j diff --git a/lake-manifest.json b/lake-manifest.json index 99b699c4b2f237..33929543be7acf 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e12c1910fe855cbfc38803cd4e55543906d5fa62", + "rev": "b1c4a69a7e247ab7df20460212001673d74f08c0", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "7e9612bf0b9ee66db3cb5b9988a35afc706f5a12", + "rev": "18a90119a5d316358fde6c86e0ca24e59212e32c", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "d662197a9ca6f411c5738c45ec0192c786462f5d", + "rev": "b1436dc749e722c9920036b52cdc43b3451d0b69", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "a7dbf0c63b694e47f425f3dcddbc0e178bb432d3", + "rev": "57d3325be72a842920813bcb40f96a6f7393c185", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "38d591e778f100aec9762bb582f9c7f55f50e9dc", + "rev": "ee41917ae11d38479fb8fb24745f7ca4bf0a784d", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "023ce7d62a0531e22a5331e20b587817a80d49ff", + "rev": "31a49105f960721073a9adfc82b261f5d0f2ce1e", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "88679d088c9720c27ebdf2ba4dafe17341747f94", + "rev": "da07ca808b6718cb2aed14dba154e5a08b8f8ecf", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.32.0", + "inputRev": "v4.33.0-rc1", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lakefile.lean b/lakefile.lean index a4808f93fdd2c0..bcdf13405f04bf 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -8,6 +8,7 @@ open Lake DSL require "leanprover-community" / "batteries" @ git "main" require "leanprover-community" / "Qq" @ git "master" + require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "main" with NameMap.empty.insert `errorOnBuild diff --git a/lean-toolchain b/lean-toolchain index 94b9f495baff80..fd85b262bf1c73 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.32.0 +leanprover/lean4:v4.33.0-rc1 diff --git a/scripts/nolints.json b/scripts/nolints.json index 26d79efc46e85a..c52b1149fb44d6 100644 --- a/scripts/nolints.json +++ b/scripts/nolints.json @@ -530,8 +530,8 @@ ["defsWithUnderscore", "Profinite.NobelingProof.GoodProducts.sum_to"], ["defsWithUnderscore", "Stream'.WSeq.destruct_append.aux"], ["defsWithUnderscore", "Stream'.WSeq.destruct_join.aux"], - ["defsWithUnderscore", "Tactic.NormNum.NotPowerCertificate.pf_left"], - ["defsWithUnderscore", "Tactic.NormNum.NotPowerCertificate.pf_right"], + ["defsWithUnderscore", "Mathlib.Meta.NormNum.NotPowerCertificate.pf_left"], + ["defsWithUnderscore", "Mathlib.Meta.NormNum.NotPowerCertificate.pf_right"], ["defsWithUnderscore", "CategoryTheory.IsCardinalFiltered.exists_cardinal_directed.Diagram.P"], ["defsWithUnderscore", diff --git a/scripts/set_option_utils.py b/scripts/set_option_utils.py index 9b9d6c76d33681..bf6b27ca60395b 100755 --- a/scripts/set_option_utils.py +++ b/scripts/set_option_utils.py @@ -9,6 +9,7 @@ DEFAULT_OPTIONS = [ "backward.isDefEq.respectTransparency", + "backward.isDefEq.respectTransparency.types", "backward.whnf.reducibleClassField", "backward.inferInstanceAs.wrap", ] From 49ed1b2de10cb2b131a7f689d979839266093264 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Thu, 16 Jul 2026 02:41:34 +0000 Subject: [PATCH 0812/1300] feat(Topology/EMetricSpace/BoundedVariation): more BoundedVariationOn and eVariationOn API (#41519) Various API for `BoundedVariationOn` and `eVariationOn`, including a formula for the `eVariationOn` for finite sets such as pairs, or the variation of the identity function, or more generally a monotone function. Co-authored-by: Terence Tao --- .../EMetricSpace/BoundedVariation.lean | 148 ++++++++++++++---- 1 file changed, 119 insertions(+), 29 deletions(-) diff --git a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean index 7a2048708bf28d..a7db24a2a82ab0 100644 --- a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean +++ b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean @@ -6,6 +6,7 @@ Authors: Sébastien Gouëzel module public import Mathlib.Order.Interval.Set.ProjIcc +public import Mathlib.Data.Finset.Sort public import Mathlib.Tactic.Finiteness public import Mathlib.Topology.UniformSpace.UniformConvergenceTopology public import Mathlib.Topology.Instances.ENNReal.Lemmas @@ -412,7 +413,7 @@ theorem sum (f : α → E) {s : Set α} {E : ℕ → α} (hE : Monotone E) {n : ∑ i ∈ Finset.range n, eVariationOn f (s ∩ Icc (E i) (E (i + 1))) = eVariationOn f (s ∩ Icc (E 0) (E n)) := by induction n with - | zero => simp [eVariationOn.subsingleton f Subsingleton.inter_singleton] + | zero => simp [Subsingleton.inter_singleton] | succ n ih => by_cases hn₀ : n = 0 · simp [hn₀] @@ -433,6 +434,64 @@ theorem sum' (f : α → E) {I : ℕ → α} (hI : Monotone I) {n : ℕ} : gcongr <;> (apply hI; rw [Finset.mem_range] at hi; lia) · simp +/-- The variation of `f` on a two-point set `{a, b}` is the distance between its two values. -/ +@[simp] +theorem pair (f : α → E) (a b : α) : eVariationOn f {a, b} = edist (f a) (f b) := by + wlog hab : a ≤ b generalizing a b + · simpa [edist_comm, pair_comm] using this b a (le_of_not_ge hab) + · apply le_antisymm _ (edist_le f (by simp) (by simp)) + simp only [eVariationOn_eq_strictMonoOn, iSup_le_iff] + rintro ⟨n, u, hmono, hi⟩ + rcases (by omega : n = 0 ∨ n = 1 ∨ 2 ≤ n) with rfl | rfl | hn + · simp + · have := hmono (by simp) (by simp) zero_lt_one + simp [(by grind : u 0 = a), (by grind : u 1 = b), edist_comm] + · have := hmono (by simp) (by grind) zero_lt_one + have := hmono (by grind) (by grind) one_lt_two + grind + +/-- A generalization of `eVariationOn.union` in which the greatest element of `s` is allowed to lie +to the left of the least element of `t`. -/ +theorem union' (f : α → E) {s t : Set α} {x y : α} (hs : IsGreatest s x) (ht : IsLeast t y) + (hxy : x ≤ y) : + eVariationOn f (s ∪ t) = eVariationOn f s + edist (f x) (f y) + eVariationOn f t := by + rw [(by grind [hs.1, ht.1] : s ∪ t = (s ∪ {x, y}) ∪ t), union f _ ht, union f hs] + <;> simp [IsLeast, IsGreatest, hxy, upperBounds_mono_mem hxy hs.2] + +/-- The variation of `f` along the image of `{0, …, n}` under a monotone sequence `u` is the sum of +the distances between consecutive values. -/ +theorem image_range_of_monotone (f : α → E) {u : ℕ → α} (hu : Monotone u) (n : ℕ) : + eVariationOn f (u '' Iic n) = ∑ i ∈ .range n, edist (f (u i)) (f (u (i + 1))) := by + induction n with + | zero => simp [Iic] + | succ n ih => + rw [(by grind : u '' Iic (n + 1) = u '' Iic n ∪ {u n, u (n + 1)}), union f] + · simp [Finset.sum_range_succ, ih] + · simpa [IsGreatest, upperBounds] using ⟨⟨n, by simp⟩, fun a ha ↦ hu ha⟩ + · simp [IsLeast, hu n.le_succ] + +private theorem _root_.BoundedVariationOn.of_finset {E} [PseudoMetricSpace E] (f : α → E) + (s : Finset α) : BoundedVariationOn f s := by + obtain rfl | hne := s.eq_empty_or_nonempty + · simp [BoundedVariationOn] + have := s.card_pos.2 hne + let u : ℕ → α := fun n ↦ s.orderEmbOfFin rfl ⟨min n (s.card - 1), by grind⟩ + have : s = u '' Iic (s.card - 1) := by + ext + simp only [← s.range_orderEmbOfFin rfl, mem_image, mem_Iic, mem_range, u] + constructor + · rintro ⟨i, rfl⟩; exact ⟨i.val, by grind⟩ + · rintro ⟨i, hi, rfl⟩; use ⟨i, by omega⟩; congr; omega + have hmono : Monotone u := fun _ _ _ ↦ OrderEmbedding.monotone _ (by grind) + simp [BoundedVariationOn, this, image_range_of_monotone f hmono _] + +/-- A function valued in a metric space has bounded variation on any `Finset` (the finiteness of +the space's distances makes the total variation finite). -/ +@[simp] +theorem _root_.BoundedVariationOn.of_finite {E} [PseudoMetricSpace E] (f : α → E) (s : Set α) +[Finite s] : BoundedVariationOn f s := by + simpa using BoundedVariationOn.of_finset f s.toFinite.toFinset + /-! ### Composition of bounded variation functions with monotone functions -/ section Monotone @@ -1097,42 +1156,73 @@ theorem _root_.BoundedVariationOn.tendsto_atBot_limUnder [CompleteSpace E] [hE : end eVariationOn +section Monotone + /-! ### Variation of monotone functions -/ -theorem MonotoneOn.eVariationOn_le {f : α → ℝ} {s : Set α} (hf : MonotoneOn f s) {a b : α} - (as : a ∈ s) (bs : b ∈ s) : eVariationOn f (s ∩ Icc a b) ≤ ENNReal.ofReal (f b - f a) := by - apply iSup_le _ - rintro ⟨n, ⟨u, hu, us⟩⟩ - calc - (∑ i ∈ Finset.range n, edist (f (u (i + 1))) (f (u i))) = - ∑ i ∈ Finset.range n, ENNReal.ofReal (f (u (i + 1)) - f (u i)) := by - refine Finset.sum_congr rfl fun i hi => ?_ - simp only [Finset.mem_range] at hi - rw [edist_dist, Real.dist_eq, abs_of_nonneg] - exact sub_nonneg_of_le (hf (us i).1 (us (i + 1)).1 (hu (Nat.le_succ _))) - _ = ENNReal.ofReal (∑ i ∈ Finset.range n, (f (u (i + 1)) - f (u i))) := by - rw [ENNReal.ofReal_sum_of_nonneg] - intro i _ - exact sub_nonneg_of_le (hf (us i).1 (us (i + 1)).1 (hu (Nat.le_succ _))) - _ = ENNReal.ofReal (f (u n) - f (u 0)) := by rw [Finset.sum_range_sub fun i => f (u i)] - _ ≤ ENNReal.ofReal (f b - f a) := by - apply ENNReal.ofReal_le_ofReal - exact sub_le_sub (hf (us n).1 bs (us n).2.2) (hf as (us 0).1 (us 0).2.1) - -theorem MonotoneOn.locallyBoundedVariationOn {f : α → ℝ} {s : Set α} (hf : MonotoneOn f s) : +open ENNReal Finset + +variable {f : α → ℝ} {s : Set α} {C : ℝ} {a b : α} + +/-- The variation of a monotone real-valued function on `s ∩ Icc a b` equals its increment +`f b - f a`. -/ +theorem MonotoneOn.eVariationOn_eq (hf : MonotoneOn f s) (as : a ∈ s) (bs : b ∈ s) : + eVariationOn f (s ∩ Icc a b) = .ofReal (f b - f a) := by + rcases le_or_gt a b with hab | hab + · have hle : eVariationOn f (s ∩ Icc a b) ≤ .ofReal (f b - f a) := by + apply iSup_le _ + rintro ⟨n, ⟨u, hu, us⟩⟩ + calc + _ = ∑ i ∈ range n, .ofReal (f (u (i + 1)) - f (u i)) := by + refine sum_congr rfl fun i hi => ?_ + simp only [Finset.mem_range] at hi + rw [edist_dist, Real.dist_eq, abs_of_nonneg] + exact sub_nonneg_of_le (hf (us i).1 (us (i + 1)).1 (hu (Nat.le_succ _))) + _ = .ofReal (∑ i ∈ range n, (f (u (i + 1)) - f (u i))) := by + rw [ofReal_sum_of_nonneg] + exact fun i _ ↦ sub_nonneg_of_le (hf (us i).1 (us (i + 1)).1 (hu (Nat.le_succ _))) + _ = .ofReal (f (u n) - f (u 0)) := by rw [sum_range_sub (f <| u ·)] + _ ≤ _ := + ofReal_le_ofReal (sub_le_sub (hf (us n).1 bs (us n).2.2) (hf as (us 0).1 (us 0).2.1)) + have h : BoundedVariationOn f (s ∩ Icc a b) := (hle.trans_lt ofReal_lt_top).ne + apply eq_of_le_of_ge hle (ofReal_le_of_le_toReal _) + grw [← h.dist_le (x := a) (y := b)] <;> grind [Real.dist_eq] + · simp [hab, hf bs as hab.le] + +@[deprecated MonotoneOn.eVariationOn_eq (since := "2026-07-08")] +theorem MonotoneOn.eVariationOn_le (hf : MonotoneOn f s) (as : a ∈ s) (bs : b ∈ s) : + eVariationOn f (s ∩ Icc a b) ≤ .ofReal (f b - f a) := (hf.eVariationOn_eq as bs).le + +theorem MonotoneOn.locallyBoundedVariationOn (hf : MonotoneOn f s) : LocallyBoundedVariationOn f s := fun _ _ as bs => - ((hf.eVariationOn_le as bs).trans_lt ENNReal.ofReal_lt_top).ne + ((hf.eVariationOn_eq as bs) ▸ ofReal_lt_top).ne -theorem MonotoneOn.boundedVariationOn - {f : α → ℝ} {s : Set α} {C : ℝ} (hf : MonotoneOn f s) (h : ∀ x ∈ s, |f x| ≤ C) : +theorem MonotoneOn.boundedVariationOn (hf : MonotoneOn f s) (h : ∀ x ∈ s, |f x| ≤ C) : BoundedVariationOn f s := by - suffices eVariationOn f s ≤ ENNReal.ofReal (2 * C) from - ne_of_lt (this.trans_lt (by simp [ENNReal.mul_lt_top])) + suffices eVariationOn f s ≤ .ofReal (2 * C) from + ne_of_lt (this.trans_lt (by simp [mul_lt_top])) rw [eVariationOn.eq_biSup_inter_Icc] simp only [mem_setOf_eq, iSup_le_iff, and_imp, Prod.forall] intro a b as bs hab - grw [hf.eVariationOn_le as bs] - exact ENNReal.ofReal_mono (by grind) + grw [hf.eVariationOn_eq as bs] + exact ofReal_mono (by grind) + +/-- The variation of the identity on `s ∩ Icc a b` is `b - a`. -/ +lemma eVariationOn_id {a b : ℝ} {s : Set ℝ} (as : a ∈ s) (bs : b ∈ s) : + eVariationOn id (s ∩ Icc a b) = .ofReal (b - a) := + (monotone_id.monotoneOn _).eVariationOn_eq as bs + +/-- The variation of the identity on `Icc a b` is `b - a`. -/ +@[simp] +lemma eVariationOn_id_Icc (a b : ℝ) : eVariationOn id (Icc a b) = .ofReal (b - a) := by + simpa using eVariationOn_id (s := univ) (by simp) (by simp) + +/-- The identity function has bounded variation on every interval `Icc a b`. -/ +@[simp] +lemma BoundedVariationOn.id_Icc (a b : ℝ) : BoundedVariationOn id (Icc a b) := by + simp [BoundedVariationOn] + +end Monotone /-! ### Lipschitz functions and bounded variation -/ From 19d52f4cfbb837d7fb244930c315be4dc6a60b53 Mon Sep 17 00:00:00 2001 From: Andrew Yang <36414270+erdOne@users.noreply.github.com> Date: Thu, 16 Jul 2026 02:41:36 +0000 Subject: [PATCH 0813/1300] chore(AlgebraicGeometry): remove `SpecOfNotation` (#41782) This notation is a bad notation as described in the docstring. Since downstream projects can easily add this back under their own discretion, it is not necessary to keep a banned notation in mathlib. Plus, having this notation dissuades people from properly addressing the problem of the lack of notation for `ConcreteCategory.of`. --- Mathlib/AlgebraicGeometry/Scheme.lean | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 6691e0a71a671d..074704b667aabf 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -466,33 +466,11 @@ end Hom end Scheme -/-- The spectrum of a commutative ring, as a scheme. - -The notation `Spec(R)` for `(R : Type*) [CommRing R]` to mean `Spec (CommRingCat.of R)` is -enabled in the scope `SpecOfNotation`. Please do not use it within Mathlib, but it can be -used in downstream projects if desired. To use this, do: -```lean -import Mathlib.AlgebraicGeometry.Scheme - -variable (R : Type*) [CommRing R] - -open scoped SpecOfNotation - -#check Spec(R) -``` --/ +/-- The spectrum of a commutative ring, as a scheme. -/ def Spec (R : CommRingCat) : Scheme where local_affine _ := ⟨⟨⊤, trivial⟩, R, ⟨(Spec.toLocallyRingedSpace.obj (op R)).restrictTopIso⟩⟩ toLocallyRingedSpace := Spec.locallyRingedSpaceObj R -/-- The spectrum of an unbundled ring as a scheme. -WARNING: This is potentially confusing as `Spec (R)` and `Spec(R)` have different meanings. -Hence we avoid using it in mathlib but leave it as a scoped instance for downstream projects. - -WARNING: If `R` is already an element of `CommRingCat`, you should use `Spec R` instead of -`Spec(R)`, which is secretly `Spec(↑R)`. -/ -scoped[SpecOfNotation] notation3 "Spec("R")" => AlgebraicGeometry.Spec <| .of R - theorem Spec_toLocallyRingedSpace (R : CommRingCat) : (Spec R).toLocallyRingedSpace = Spec.locallyRingedSpaceObj R := rfl From a5b9632358932b87ef0d4d84dbfe392166b226fa Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 16 Jul 2026 03:41:49 +0000 Subject: [PATCH 0814/1300] chore: remove redundant backward.privateInPublic exceptions (#41395) Remove all `set_option backward.privateInPublic false` which are not needed, excluding MathlibTest Co-authored-by: Batixx --- Mathlib/Algebra/Category/AlgCat/Basic.lean | 2 -- Mathlib/Algebra/Category/BoolRing.lean | 1 - Mathlib/Algebra/Category/CommAlgCat/Basic.lean | 2 -- Mathlib/Algebra/Category/CommBialgCat.lean | 2 -- Mathlib/Algebra/Category/Grp/Basic.lean | 2 -- Mathlib/Algebra/Category/ModuleCat/Basic.lean | 1 - Mathlib/Algebra/Category/ModuleCat/Semi.lean | 1 - Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean | 1 - Mathlib/Algebra/Category/MonCat/Basic.lean | 2 -- Mathlib/Algebra/Category/Ring/Basic.lean | 4 ---- Mathlib/Algebra/Category/Semigrp/Basic.lean | 2 -- Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean | 1 - Mathlib/CategoryTheory/Bicategory/InducedBicategory.lean | 1 - Mathlib/CategoryTheory/Galois/Decomposition.lean | 1 - Mathlib/CategoryTheory/Galois/EssSurj.lean | 1 - Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean | 1 - Mathlib/Data/NNReal/Defs.lean | 2 -- Mathlib/FieldTheory/CardinalEmb.lean | 1 - Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean | 3 --- Mathlib/Logic/Godel/GodelBetaFunction.lean | 1 - Mathlib/NumberTheory/ArithmeticFunction/Misc.lean | 1 - Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean | 2 -- Mathlib/NumberTheory/NumberField/House.lean | 1 - Mathlib/Order/Category/BddDistLat.lean | 1 - Mathlib/Order/Category/BddLat.lean | 1 - Mathlib/Order/Category/BddOrd.lean | 1 - Mathlib/Order/Category/BoolAlg.lean | 1 - Mathlib/Order/Category/DistLat.lean | 1 - Mathlib/Order/Category/FinBddDistLat.lean | 1 - Mathlib/Order/Category/Frm.lean | 1 - Mathlib/Order/Category/HeytAlg.lean | 1 - Mathlib/Order/Category/Lat.lean | 1 - Mathlib/Order/Category/LinOrd.lean | 1 - Mathlib/Order/Category/PartOrd.lean | 1 - Mathlib/Order/Category/PartOrdEmb.lean | 1 - Mathlib/Order/Category/Preord.lean | 1 - Mathlib/Order/DirectedInverseSystem.lean | 2 -- Mathlib/Order/Nucleus.lean | 2 -- Mathlib/RepresentationTheory/Continuous/TopRep.lean | 1 - Mathlib/RepresentationTheory/Rep/Basic.lean | 2 -- Mathlib/RingTheory/MvPowerSeries/Evaluation.lean | 1 - 41 files changed, 57 deletions(-) diff --git a/Mathlib/Algebra/Category/AlgCat/Basic.lean b/Mathlib/Algebra/Category/AlgCat/Basic.lean index 5ce0fe4c889ec0..c771d334529417 100644 --- a/Mathlib/Algebra/Category/AlgCat/Basic.lean +++ b/Mathlib/Algebra/Category/AlgCat/Basic.lean @@ -27,7 +27,6 @@ universe v u variable (R : Type u) [CommRing R] -set_option backward.privateInPublic true in /-- The category of R-algebras and their morphisms. -/ structure AlgCat where private mk :: @@ -58,7 +57,6 @@ lemma coe_of (X : Type v) [Ring X] [Algebra R X] : (of R X : Type v) = X := rfl variable {R} in -set_option backward.privateInPublic true in /-- The type of morphisms in `AlgCat R`. -/ @[ext] structure Hom (A B : AlgCat.{v} R) where diff --git a/Mathlib/Algebra/Category/BoolRing.lean b/Mathlib/Algebra/Category/BoolRing.lean index 65a667b67ab649..14531f2cb58fda 100644 --- a/Mathlib/Algebra/Category/BoolRing.lean +++ b/Mathlib/Algebra/Category/BoolRing.lean @@ -52,7 +52,6 @@ instance : Inhabited BoolRing := ⟨of PUnit⟩ variable {R} in -set_option backward.privateInPublic true in /-- The type of morphisms in `BoolRing`. -/ @[ext] structure Hom (R S : BoolRing) where diff --git a/Mathlib/Algebra/Category/CommAlgCat/Basic.lean b/Mathlib/Algebra/Category/CommAlgCat/Basic.lean index 890af256ec28cc..d284d947406a86 100644 --- a/Mathlib/Algebra/Category/CommAlgCat/Basic.lean +++ b/Mathlib/Algebra/Category/CommAlgCat/Basic.lean @@ -26,7 +26,6 @@ universe w v u variable {R : Type u} [CommRing R] variable (R) in -set_option backward.privateInPublic true in /-- The category of R-algebras and their morphisms. -/ structure CommAlgCat where private mk :: @@ -57,7 +56,6 @@ abbrev of (X : Type v) [CommRing X] [Algebra R X] : CommAlgCat.{v} R := ⟨X⟩ variable (R) in lemma coe_of (X : Type v) [CommRing X] [Algebra R X] : (of R X : Type v) = X := rfl -set_option backward.privateInPublic true in /-- The type of morphisms in `CommAlgCat R`. -/ @[ext] structure Hom (A B : CommAlgCat.{v} R) where diff --git a/Mathlib/Algebra/Category/CommBialgCat.lean b/Mathlib/Algebra/Category/CommBialgCat.lean index affc3a473c4757..444d27bcfa7a16 100644 --- a/Mathlib/Algebra/Category/CommBialgCat.lean +++ b/Mathlib/Algebra/Category/CommBialgCat.lean @@ -27,7 +27,6 @@ universe v u variable {R : Type u} [CommRing R] variable (R) in -set_option backward.privateInPublic true in /-- The category of commutative `R`-bialgebras and their morphisms. -/ structure CommBialgCat where private mk :: @@ -59,7 +58,6 @@ abbrev of (X : Type v) [CommRing X] [Bialgebra R X] : CommBialgCat.{v} R := ⟨X variable (R) in lemma coe_of (X : Type v) [CommRing X] [Bialgebra R X] : (of R X : Type v) = X := rfl -set_option backward.privateInPublic true in /-- The type of morphisms in `CommBialgCat R`. -/ @[ext] structure Hom (A B : CommBialgCat.{v} R) where diff --git a/Mathlib/Algebra/Category/Grp/Basic.lean b/Mathlib/Algebra/Category/Grp/Basic.lean index 58e59d68d21006..13e4f84c68f9e6 100644 --- a/Mathlib/Algebra/Category/Grp/Basic.lean +++ b/Mathlib/Algebra/Category/Grp/Basic.lean @@ -67,7 +67,6 @@ structure AddGrpCat.Hom (A B : AddGrpCat.{u}) where /-- The underlying monoid homomorphism. -/ hom' : A →+ B -set_option backward.privateInPublic true in /-- The type of morphisms in `GrpCat R`. -/ @[to_additive, ext] structure GrpCat.Hom (A B : GrpCat.{u}) where @@ -284,7 +283,6 @@ structure AddCommGrpCat.Hom (A B : AddCommGrpCat.{u}) where /-- The underlying monoid homomorphism. -/ hom' : A →+ B -set_option backward.privateInPublic true in /-- The type of morphisms in `CommGrpCat R`. -/ @[to_additive, ext] structure CommGrpCat.Hom (A B : CommGrpCat.{u}) where diff --git a/Mathlib/Algebra/Category/ModuleCat/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Basic.lean index 752a2035ff5200..9965a3a3fd951e 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Basic.lean @@ -47,7 +47,6 @@ universe v u variable (R : Type u) [Ring R] -set_option backward.privateInPublic true in /-- The category of R-modules and their morphisms. Note that in the case of `R = ℤ`, we cannot diff --git a/Mathlib/Algebra/Category/ModuleCat/Semi.lean b/Mathlib/Algebra/Category/ModuleCat/Semi.lean index 9fea6dca48d399..13ac4f283f9a36 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Semi.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Semi.lean @@ -45,7 +45,6 @@ universe v u variable (R : Type u) [Semiring R] -set_option backward.privateInPublic true in /-- The category of R-semimodules and their morphisms. Note that in the case of `R = ℕ`, we can not diff --git a/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean index 986077e2bada54..71a5dfc5d55c77 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean @@ -59,7 +59,6 @@ abbrev of (M : Type v) [AddCommGroup M] [Module R M] [TopologicalSpace M] [Conti lemma coe_of (M : Type v) [AddCommGroup M] [Module R M] [TopologicalSpace M] [ContinuousAdd M] [ContinuousSMul R M] : (of R M) = M := rfl -set_option backward.privateInPublic true in variable {R} in /-- Homs in `TopModuleCat` as one field structures over `ContinuousLinearMap`. -/ structure Hom (X Y : TopModuleCat.{v} R) where diff --git a/Mathlib/Algebra/Category/MonCat/Basic.lean b/Mathlib/Algebra/Category/MonCat/Basic.lean index de0d5588f909d1..3d713571f819b1 100644 --- a/Mathlib/Algebra/Category/MonCat/Basic.lean +++ b/Mathlib/Algebra/Category/MonCat/Basic.lean @@ -70,7 +70,6 @@ structure AddMonCat.Hom (A B : AddMonCat.{u}) where /-- The underlying monoid homomorphism. -/ hom' : A →+ B -set_option backward.privateInPublic true in /-- The type of morphisms in `MonCat`. -/ @[to_additive, ext] structure MonCat.Hom (A B : MonCat.{u}) where @@ -257,7 +256,6 @@ structure AddCommMonCat.Hom (A B : AddCommMonCat.{u}) where /-- The underlying monoid homomorphism. -/ hom' : A →+ B -set_option backward.privateInPublic true in /-- The type of morphisms in `CommMonCat`. -/ @[to_additive, ext] structure CommMonCat.Hom (A B : CommMonCat.{u}) where diff --git a/Mathlib/Algebra/Category/Ring/Basic.lean b/Mathlib/Algebra/Category/Ring/Basic.lean index 026c44a5d74c06..b3ef397fe94e89 100644 --- a/Mathlib/Algebra/Category/Ring/Basic.lean +++ b/Mathlib/Algebra/Category/Ring/Basic.lean @@ -63,7 +63,6 @@ lemma coe_of (R : Type u) [Semiring R] : (of R : Type u) = R := lemma of_carrier (R : SemiRingCat.{u}) : of R = R := rfl -set_option backward.privateInPublic true in variable {R} in /-- The type of morphisms in `SemiRingCat`. -/ @[ext] @@ -229,7 +228,6 @@ lemma coe_of (R : Type u) [Ring R] : (of R : Type u) = R := lemma of_carrier (R : RingCat.{u}) : of R = R := rfl -set_option backward.privateInPublic true in variable {R} in /-- The type of morphisms in `RingCat`. -/ @[ext] @@ -404,7 +402,6 @@ lemma coe_of (R : Type u) [CommSemiring R] : (of R : Type u) = R := lemma of_carrier (R : CommSemiRingCat.{u}) : of R = R := rfl -set_option backward.privateInPublic true in variable {R} in /-- The type of morphisms in `CommSemiRingCat`. -/ @[ext] @@ -577,7 +574,6 @@ lemma coe_of (R : Type u) [CommRing R] : (of R : Type u) = R := lemma of_carrier (R : CommRingCat.{u}) : of R = R := rfl -set_option backward.privateInPublic true in variable {R} in /-- The type of morphisms in `CommRingCat`. -/ @[ext] diff --git a/Mathlib/Algebra/Category/Semigrp/Basic.lean b/Mathlib/Algebra/Category/Semigrp/Basic.lean index 741701259c9483..e4f56af05fdb9f 100644 --- a/Mathlib/Algebra/Category/Semigrp/Basic.lean +++ b/Mathlib/Algebra/Category/Semigrp/Basic.lean @@ -75,7 +75,6 @@ structure AddMagmaCat.Hom (A B : AddMagmaCat.{u}) where /-- The underlying `AddHom`. -/ hom' : A →ₙ+ B -set_option backward.privateInPublic true in /-- The type of morphisms in `MagmaCat R`. -/ @[to_additive, ext] structure MagmaCat.Hom (A B : MagmaCat.{u}) where @@ -237,7 +236,6 @@ structure AddSemigrp.Hom (A B : AddSemigrp.{u}) where /-- The underlying `AddHom`. -/ hom' : A →ₙ+ B -set_option backward.privateInPublic true in /-- The type of morphisms in `Semigrp R`. -/ @[to_additive, ext] structure Semigrp.Hom (A B : Semigrp.{u}) where diff --git a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean index 4b2d66c3015a88..16b57c280f78d0 100644 --- a/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean +++ b/Mathlib/AlgebraicGeometry/IdealSheaf/Subscheme.lean @@ -325,7 +325,6 @@ def glueData : Scheme.GlueData where f_open i j := inferInstance set_option backward.defeqAttrib.useBackward true in -set_option backward.privateInPublic true in /-- (Implementation) The map from `Spec(𝒪ₓ/I)` to `X`. See `IdealSheafData.subschemeι` instead. -/ noncomputable def gluedTo : I.glueData.glued ⟶ X := diff --git a/Mathlib/CategoryTheory/Bicategory/InducedBicategory.lean b/Mathlib/CategoryTheory/Bicategory/InducedBicategory.lean index 687fd8e8373703..16ee922018ea09 100644 --- a/Mathlib/CategoryTheory/Bicategory/InducedBicategory.lean +++ b/Mathlib/CategoryTheory/Bicategory/InducedBicategory.lean @@ -46,7 +46,6 @@ variable {C F} instance hasCoeToSort {α : Sort*} [CoeSort C α] : CoeSort (InducedBicategory C F) α := ⟨fun c => F c⟩ -set_option backward.privateInPublic true in /-- `InducedBicategory.Hom X Y` is a type-alias for morphisms between `X Y : B` viewed as objects of `B` with the induced bicategory structure. This is given a `CategoryStruct` instance below, where the identity and composition is induced from `C`. -/ diff --git a/Mathlib/CategoryTheory/Galois/Decomposition.lean b/Mathlib/CategoryTheory/Galois/Decomposition.lean index 1734191c3ed3d5..371f0121d8f359 100644 --- a/Mathlib/CategoryTheory/Galois/Decomposition.lean +++ b/Mathlib/CategoryTheory/Galois/Decomposition.lean @@ -202,7 +202,6 @@ which has at index `x : F.obj X` the element `g x`. -/ private noncomputable def mkSelfProdFib : F.obj (selfProd F X) := (PreservesProduct.iso F _).inv ((Concrete.productEquiv (fun _ : F.obj X ↦ F.obj X)).symm id) -set_option backward.privateInPublic true in @[simp] private lemma mkSelfProdFib_map_π (t : F.obj X) : F.map (Pi.π _ t) (mkSelfProdFib F X) = t := by rw [← piComparison_comp_π] diff --git a/Mathlib/CategoryTheory/Galois/EssSurj.lean b/Mathlib/CategoryTheory/Galois/EssSurj.lean index 046b2cc7be48ca..cd8f59a8e9071d 100644 --- a/Mathlib/CategoryTheory/Galois/EssSurj.lean +++ b/Mathlib/CategoryTheory/Galois/EssSurj.lean @@ -55,7 +55,6 @@ variable [GaloisCategory C] [FiberFunctor F] variable {G : Type*} [Group G] [TopologicalSpace G] [IsTopologicalGroup G] [CompactSpace G] -set_option backward.privateInPublic true in private local instance fintypeQuotient (H : OpenSubgroup (G)) : Fintype (G ⧸ (H : Subgroup (G))) := have : Finite (G ⧸ H.toSubgroup) := H.toSubgroup.quotient_finite_of_isOpen H.isOpen' diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean index d431bfb4973bd9..df5a66d6a3d66d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean @@ -175,7 +175,6 @@ def functorObj (A : (C ⥤ D)) [ComonObj A] : C ⥤ Comon D where set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.privateInPublic true in /-- Functor translating a comonoid object in a functor category to a functor into the category of comonoid objects. -/ diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index f67fe2b24c949d..1c6e7636119389 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -332,12 +332,10 @@ noncomputable example : LinearOrder ℝ≥0 := by infer_instance @[simp, norm_cast, gcongr] lemma coe_lt_coe : (r₁ : ℝ) < r₂ ↔ r₁ < r₂ := Iff.rfl -set_option backward.privateInPublic true in @[bound] private alias ⟨_, Bound.coe_lt_coe_of_lt⟩ := coe_lt_coe @[simp, norm_cast] lemma coe_pos : (0 : ℝ) < r ↔ 0 < r := Iff.rfl -set_option backward.privateInPublic true in @[bound] private alias ⟨_, Bound.coe_pos_of_pos⟩ := coe_pos @[simp, norm_cast] lemma one_le_coe : 1 ≤ (r : ℝ) ↔ 1 ≤ r := by rw [← coe_le_coe, coe_one] diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index 424727a4a73e24..4df957138237b1 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -87,7 +87,6 @@ set_option quotPrecheck false /-- Index a basis of E/F using the initial ordinal of the cardinal `Module.rank F E`. -/ local notation "ι" => (Module.rank F E).ord.ToType -set_option backward.privateInPublic true in local notation i "⁺" => succ i -- Note: conflicts with `PosPart` notation /-- A basis of E/F indexed by the initial ordinal. -/ diff --git a/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean b/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean index 17729c9f9986c3..6d549201b1db5c 100644 --- a/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean +++ b/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean @@ -45,7 +45,6 @@ variable {M' N' : Type*} [AddCommGroup M'] [Module R M'] [AddCommGroup N'] [Modu include hi hj hij -set_option backward.privateInPublic true in private lemma restrict_aux : Bijective (p.compl₁₂ i j) := by refine ⟨LinearMap.ker_eq_bot.mp <| eq_bot_iff.mpr fun m hm ↦ ?_, fun f ↦ ?_⟩ · replace hm : i m ∈ j.range.dualAnnihilator.map (p.toPerfPair.symm : Dual R N →ₗ[R] M) := by @@ -85,7 +84,6 @@ variable {S M' N' : Type*} (i : M' →ₗ[S] M) (j : N' →ₗ[S] N) set_option backward.isDefEq.respectTransparency false in -set_option backward.privateInPublic true in private lemma restrictScalars_injective_aux (hi : Injective i) (hN : span R (LinearMap.range j : Set N) = ⊤) @@ -110,7 +108,6 @@ private lemma restrictScalars_injective_aux simpa using hx n set_option backward.isDefEq.respectTransparency false in -set_option backward.privateInPublic true in private lemma restrictScalars_surjective_aux (h : ∀ g : Module.Dual S N', ∃ m, (p.toPerfPair (i m)).restrictScalars S ∘ₗ j = Algebra.linearMap S R ∘ₗ g) diff --git a/Mathlib/Logic/Godel/GodelBetaFunction.lean b/Mathlib/Logic/Godel/GodelBetaFunction.lean index caa46d6f34c582..c0c8cfe4cc4f16 100644 --- a/Mathlib/Logic/Godel/GodelBetaFunction.lean +++ b/Mathlib/Logic/Godel/GodelBetaFunction.lean @@ -80,7 +80,6 @@ lemma coprimes_lt (a : Fin m → ℕ) (i) : a i < coprimes a i := by simpa only [coprimes] using lt_of_lt_of_le h₁ h₂ open scoped Function in -- required for scoped `on` notation -set_option backward.privateInPublic true in private lemma pairwise_coprime_coprimes (a : Fin m → ℕ) : Pairwise (Coprime on coprimes a) := by intro i j hij wlog! ltij : i < j diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean index 11f9445eac20a4..24db3b4f1f748f 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean @@ -232,7 +232,6 @@ theorem _root_.Nat.divisors_card_eq_one_iff (n : ℕ) : #n.divisors = 1 ↔ n = · refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩ exact (card_le_one.mp h.le 1 (one_mem_divisors.mpr hn) n (n.mem_divisors_self hn)).symm -set_option backward.privateInPublic true in /-- `sigma_eq_one_iff` is to be preferred. -/ private theorem sigma_zero_eq_one_iff (n : ℕ) : σ 0 n = 1 ↔ n = 1 := by simp [sigma_zero_apply] diff --git a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean index 64c2a695430e8a..3b52650f79da2d 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean @@ -565,7 +565,6 @@ private def fastJacobiSym (a : ℤ) (b : ℕ) : ℤ := else fastJacobiSymAux (a % b).natAbs b false (Int.natAbs_pos.mpr hab) -set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in @[csimp] private theorem fastJacobiSym.eq : jacobiSym = fastJacobiSym := by ext a b @@ -594,7 +593,6 @@ set_option backward.privateInPublic.warn false in @[inline, nolint unusedArguments] private def fastLegendreSym (p : ℕ) [Fact p.Prime] (a : ℤ) : ℤ := J(a | p) -set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in @[csimp] private theorem fastLegendreSym.eq : legendreSym = fastLegendreSym := by ext p _ a; rw [legendreSym.to_jacobiSym, fastLegendreSym] diff --git a/Mathlib/NumberTheory/NumberField/House.lean b/Mathlib/NumberTheory/NumberField/House.lean index fb4d16456eef9d..d1322816f703ff 100644 --- a/Mathlib/NumberTheory/NumberField/House.lean +++ b/Mathlib/NumberTheory/NumberField/House.lean @@ -336,7 +336,6 @@ private theorem house_le_bound : ∀ l, house (ξ K x l).1 ≤ (c₁ K) * · exact asiegel_remark K a habs Apos · rw [mul_comm (q : ℝ) (c₁ K)]; rfl -set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in include hpq h0p cardα cardβ ha habs in /-- There exists a "small" non-zero algebraic integral solution of an diff --git a/Mathlib/Order/Category/BddDistLat.lean b/Mathlib/Order/Category/BddDistLat.lean index f8d8b199964fdf..9351e051fa91da 100644 --- a/Mathlib/Order/Category/BddDistLat.lean +++ b/Mathlib/Order/Category/BddDistLat.lean @@ -48,7 +48,6 @@ abbrev of (α : Type*) [DistribLattice α] [BoundedOrder α] : BddDistLat where theorem coe_of (α : Type*) [DistribLattice α] [BoundedOrder α] : ↥(of α) = α := rfl -set_option backward.privateInPublic true in /-- The type of morphisms in `BddDistLat R`. -/ @[ext] structure Hom (X Y : BddDistLat.{u}) where diff --git a/Mathlib/Order/Category/BddLat.lean b/Mathlib/Order/Category/BddLat.lean index 508c5f4f137be2..837c0b91bf2974 100644 --- a/Mathlib/Order/Category/BddLat.lean +++ b/Mathlib/Order/Category/BddLat.lean @@ -48,7 +48,6 @@ abbrev of (α : Type*) [Lattice α] [BoundedOrder α] : BddLat where theorem coe_of (α : Type*) [Lattice α] [BoundedOrder α] : ↥(of α) = α := rfl -set_option backward.privateInPublic true in /-- The type of morphisms in `BddLat`. -/ @[ext] structure Hom (X Y : BddLat.{u}) where diff --git a/Mathlib/Order/Category/BddOrd.lean b/Mathlib/Order/Category/BddOrd.lean index fbda8a11919aec..a6f6a9eb6fc463 100644 --- a/Mathlib/Order/Category/BddOrd.lean +++ b/Mathlib/Order/Category/BddOrd.lean @@ -42,7 +42,6 @@ instance : CoeSort BddOrd Type* := abbrev of (X : Type*) [PartialOrder X] [BoundedOrder X] : BddOrd where carrier := X -set_option backward.privateInPublic true in /-- The type of morphisms in `BddOrd R`. -/ @[ext] structure Hom (X Y : BddOrd.{u}) where diff --git a/Mathlib/Order/Category/BoolAlg.lean b/Mathlib/Order/Category/BoolAlg.lean index 2bd9e8a57f332d..870bd3a1756b3c 100644 --- a/Mathlib/Order/Category/BoolAlg.lean +++ b/Mathlib/Order/Category/BoolAlg.lean @@ -42,7 +42,6 @@ instance : CoeSort BoolAlg (Type _) := attribute [coe] BoolAlg.carrier -set_option backward.privateInPublic true in /-- The type of morphisms in `BoolAlg R`. -/ @[ext] structure Hom (X Y : BoolAlg.{u}) where diff --git a/Mathlib/Order/Category/DistLat.lean b/Mathlib/Order/Category/DistLat.lean index 53f247aa4385da..b9f8af3086b652 100644 --- a/Mathlib/Order/Category/DistLat.lean +++ b/Mathlib/Order/Category/DistLat.lean @@ -44,7 +44,6 @@ attribute [coe] DistLat.carrier /-- Construct a bundled `DistLat` from the underlying type and typeclass. -/ abbrev of (X : Type*) [DistribLattice X] : DistLat := ⟨X⟩ -set_option backward.privateInPublic true in /-- The type of morphisms in `DistLat R`. -/ @[ext] structure Hom (X Y : DistLat.{u}) where diff --git a/Mathlib/Order/Category/FinBddDistLat.lean b/Mathlib/Order/Category/FinBddDistLat.lean index 8a71f5e5a82168..76ba1e5556dd80 100644 --- a/Mathlib/Order/Category/FinBddDistLat.lean +++ b/Mathlib/Order/Category/FinBddDistLat.lean @@ -49,7 +49,6 @@ abbrev of' (α : Type*) [DistribLattice α] [Fintype α] [Nonempty α] : FinBddD carrier := α isBoundedOrder := Fintype.toBoundedOrder α -set_option backward.privateInPublic true in /-- The type of morphisms in `FinBddDistLat R`. -/ @[ext] structure Hom (X Y : FinBddDistLat.{u}) where diff --git a/Mathlib/Order/Category/Frm.lean b/Mathlib/Order/Category/Frm.lean index 1d87b29e749074..77acec73782bdd 100644 --- a/Mathlib/Order/Category/Frm.lean +++ b/Mathlib/Order/Category/Frm.lean @@ -45,7 +45,6 @@ instance : CoeSort Frm (Type _) := attribute [coe] Frm.carrier -set_option backward.privateInPublic true in /-- The type of morphisms in `Frm R`. -/ @[ext] structure Hom (X Y : Frm.{u}) where diff --git a/Mathlib/Order/Category/HeytAlg.lean b/Mathlib/Order/Category/HeytAlg.lean index 1d19ad5e2ede62..5a17e83667cf90 100644 --- a/Mathlib/Order/Category/HeytAlg.lean +++ b/Mathlib/Order/Category/HeytAlg.lean @@ -41,7 +41,6 @@ attribute [coe] HeytAlg.carrier /-- Construct a bundled `HeytAlg` from the underlying type and typeclass. -/ abbrev of (X : Type*) [HeytingAlgebra X] : HeytAlg := ⟨X⟩ -set_option backward.privateInPublic true in /-- The type of morphisms in `HeytAlg R`. -/ @[ext] structure Hom (X Y : HeytAlg.{u}) where diff --git a/Mathlib/Order/Category/Lat.lean b/Mathlib/Order/Category/Lat.lean index 6e4dc11410bbe7..13d2e93325c19c 100644 --- a/Mathlib/Order/Category/Lat.lean +++ b/Mathlib/Order/Category/Lat.lean @@ -48,7 +48,6 @@ attribute [coe] Lat.carrier /-- Construct a bundled `Lat` from the underlying type and typeclass. -/ abbrev of (X : Type*) [Lattice X] : Lat := ⟨X⟩ -set_option backward.privateInPublic true in /-- The type of morphisms in `Lat R`. -/ @[ext] structure Hom (X Y : Lat.{u}) where diff --git a/Mathlib/Order/Category/LinOrd.lean b/Mathlib/Order/Category/LinOrd.lean index 1249fb1c9d7fbe..483c85b4d700c1 100644 --- a/Mathlib/Order/Category/LinOrd.lean +++ b/Mathlib/Order/Category/LinOrd.lean @@ -22,7 +22,6 @@ universe u namespace LinOrd -set_option backward.privateInPublic true in /-- The type of morphisms in `LinOrd R`. -/ @[ext] structure Hom (X Y : LinOrd.{u}) where diff --git a/Mathlib/Order/Category/PartOrd.lean b/Mathlib/Order/Category/PartOrd.lean index 35d4b237d27263..a710bc211addd1 100644 --- a/Mathlib/Order/Category/PartOrd.lean +++ b/Mathlib/Order/Category/PartOrd.lean @@ -40,7 +40,6 @@ instance : CoeSort PartOrd (Type _) := attribute [coe] PartOrd.carrier -set_option backward.privateInPublic true in /-- The type of morphisms in `PartOrd R`. -/ @[ext] structure Hom (X Y : PartOrd.{u}) where diff --git a/Mathlib/Order/Category/PartOrdEmb.lean b/Mathlib/Order/Category/PartOrdEmb.lean index fb1b2bcb849f6c..37ab7b712d6d74 100644 --- a/Mathlib/Order/Category/PartOrdEmb.lean +++ b/Mathlib/Order/Category/PartOrdEmb.lean @@ -43,7 +43,6 @@ instance : CoeSort PartOrdEmb (Type _) := attribute [coe] PartOrdEmb.carrier -set_option backward.privateInPublic true in /-- The type of morphisms in `PartOrdEmb R`. -/ @[ext] structure Hom (X Y : PartOrdEmb.{u}) where diff --git a/Mathlib/Order/Category/Preord.lean b/Mathlib/Order/Category/Preord.lean index 06c19f65effe5d..76479d9f9acb44 100644 --- a/Mathlib/Order/Category/Preord.lean +++ b/Mathlib/Order/Category/Preord.lean @@ -43,7 +43,6 @@ instance : CoeSort Preord (Type u) := attribute [coe] Preord.carrier -set_option backward.privateInPublic true in /-- The type of morphisms in `Preord R`. -/ @[ext] structure Hom (X Y : Preord.{u}) where diff --git a/Mathlib/Order/DirectedInverseSystem.lean b/Mathlib/Order/DirectedInverseSystem.lean index a4de9836e43c4a..468e2e921a06d6 100644 --- a/Mathlib/Order/DirectedInverseSystem.lean +++ b/Mathlib/Order/DirectedInverseSystem.lean @@ -225,7 +225,6 @@ protected noncomputable def lift₂ (z : DirectLimit F₁ f₁) (w : DirectLimit (lift₂Aux ..).2 _ (hyj.trans hji) (hz.trans hki), ← map_map' _ hx hji, jeq, ← map_map' _ hz hki, ← keq, map_map'] -set_option backward.privateInPublic true in theorem lift₂_def₂ (x : Σ i, F₁ i) (y : Σ i, F₂ i) (i) (hxi : x.1 ≤ i) (hyi : y.1 ≤ i) : DirectLimit.lift₂ f₁ f₂ ih compat ⟦x⟧ ⟦y⟧ = ih i (f₁ _ _ hxi x.2) (f₂ _ _ hyi y.2) := (lift₂Aux _ _ _ compat _ _).2 .. @@ -505,7 +504,6 @@ set_option backward.privateInPublic.warn false in noncomputable def globalEquiv (i : ι) : F i ≃ piLT X i := (globalEquivAux equivSucc equivLim i).equiv ⟨i, le_rfl⟩ -set_option backward.privateInPublic true in theorem globalEquiv_naturality ⦃i j⦄ (h : i ≤ j) (x : F j) : letI e := globalEquiv equivSucc equivLim e i (f h x) = piLTProj h (e j x) := by diff --git a/Mathlib/Order/Nucleus.lean b/Mathlib/Order/Nucleus.lean index 746286c2ba8b0a..cc518b3a99cdf0 100644 --- a/Mathlib/Order/Nucleus.lean +++ b/Mathlib/Order/Nucleus.lean @@ -250,7 +250,6 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in instance : CompleteLattice (range n) := n.giAux.liftCompleteLattice -set_option backward.privateInPublic true in instance range.instFrameMinimalAxioms : Frame.MinimalAxioms (range n) where inf_sSup_le_iSup_inf a s := by simp_rw [← Subtype.coe_le_coe, iSup_subtype', iSup, sSup, n.giAux.gc.u_inf] @@ -261,7 +260,6 @@ instance range.instFrameMinimalAxioms : Frame.MinimalAxioms (range n) where instance : Frame (range n) := .ofMinimalAxioms range.instFrameMinimalAxioms -set_option backward.privateInPublic true in /-- Restrict a nucleus to its range. -/ @[simps] def restrict (n : Nucleus X) : FrameHom X (range n) where toFun := rangeFactorization n diff --git a/Mathlib/RepresentationTheory/Continuous/TopRep.lean b/Mathlib/RepresentationTheory/Continuous/TopRep.lean index 8a06ab9ed73212..68277800b92d83 100644 --- a/Mathlib/RepresentationTheory/Continuous/TopRep.lean +++ b/Mathlib/RepresentationTheory/Continuous/TopRep.lean @@ -70,7 +70,6 @@ lemma of_V : (of ρ).V = X := by with_reducible rfl variable (X ρ) in lemma of_ρ : (of ρ).ρ = ρ := by with_reducible rfl -set_option backward.privateInPublic true in /-- The type of morphisms in `TopRep k G`. -/ @[ext] structure Hom (A B : TopRep k G) where diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index 25035ac63d0b12..09276744938c68 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -26,7 +26,6 @@ universe w w' u u' v v' open CategoryTheory open scoped MonoidAlgebra -set_option backward.privateInPublic true in /-- The category of representations of monoid `G` and their morphisms. -/ structure Rep (k : Type u) (G : Type v) [Semiring k] [Monoid G] where private mk :: @@ -68,7 +67,6 @@ lemma of_V : (of ρ).V = X := by with_reducible rfl variable (X ρ) in lemma of_ρ : (of ρ).ρ = ρ := by with_reducible rfl -set_option backward.privateInPublic true in /-- The type of morphisms in `Rep.{w} k G`. -/ @[ext] structure Hom where diff --git a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean index fdd6e317fca4ff..f9cee4959544f9 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean @@ -140,7 +140,6 @@ set_option backward.privateInPublic true in private instance : UniformSpace (MvPolynomial σ R) := comap toMvPowerSeries inferInstance -set_option backward.privateInPublic true in /-- The induced uniform structure of MvPolynomial σ R is an additive group uniform structure -/ private instance [IsUniformAddGroup R] : IsUniformAddGroup (MvPolynomial σ R) := IsUniformAddGroup.comap coeToMvPowerSeries.ringHom From e012556e9488715c31dd4871c4a0c2b513d559e5 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 16 Jul 2026 04:25:43 +0000 Subject: [PATCH 0815/1300] feat: add `ContinuousLinearMap.subtypeL_comp_codRestrict` (#41801) Co-authored-by: ADedecker <48656793+ADedecker@users.noreply.github.com> --- Mathlib/Algebra/Module/Submodule/LinearMap.lean | 4 ++-- .../Algebra/Module/ContinuousLinearMap/Restrict.lean | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/LinearMap.lean b/Mathlib/Algebra/Module/Submodule/LinearMap.lean index 9287cb8d82cd56..2d6c0899bbe945 100644 --- a/Mathlib/Algebra/Module/Submodule/LinearMap.lean +++ b/Mathlib/Algebra/Module/Submodule/LinearMap.lean @@ -167,12 +167,12 @@ theorem codRestrict_apply (p : Submodule R₂ M₂) (f : M →ₛₗ[σ₁₂] M @[simp] theorem comp_codRestrict (p : Submodule R₃ M₃) (h : ∀ b, g b ∈ p) : ((codRestrict p g h).comp f : M →ₛₗ[σ₁₃] p) = codRestrict p (g.comp f) fun _ => h _ := - ext fun _ => rfl + rfl @[simp] theorem subtype_comp_codRestrict (p : Submodule R₂ M₂) (h : ∀ b, f b ∈ p) : p.subtype.comp (codRestrict p f h) = f := - ext fun _ => rfl + rfl @[simp] theorem domRestrict_comp_codRestrict (g : M₂ →ₛₗ[σ₂₃] M₃) (f : M →ₛₗ[σ₁₂] M₂) (p : Submodule R₂ M₂) diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean index b143c030d2091a..ce6e991cf40b4d 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean @@ -128,6 +128,11 @@ theorem ker_codRestrict (f : M₁ →SL[σ₁₂] M₂) (p : Submodule R₂ M₂ ker (f.codRestrict p h : M₁ →ₛₗ[σ₁₂] p) = ker (f : M₁ →ₛₗ[σ₁₂] M₂) := f.toLinearMap.ker_codRestrict p h +@[simp] +theorem subtypeL_comp_codRestrict (f : M₁ →SL[σ₁₂] M₂) (p : Submodule R₂ M₂) (h : ∀ x, f x ∈ p) : + p.subtypeL ∘SL f.codRestrict p h = f := + rfl + @[simp] theorem domRestrict_comp_codRestrict (g : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) (p : Submodule R₂ M₂) (h : ∀ x, f x ∈ p) : From c26b2a17975454a73c889d4ac24605194a720175 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 16 Jul 2026 05:00:50 +0000 Subject: [PATCH 0816/1300] feat(GroupTheory/PGroup): expand p-group API (#40143) Basic properties and iffs with `orderOf`/`Nat.card`/`Monoid.exponent`. --- Mathlib/GroupTheory/PGroup.lean | 131 ++++++++++++++++++++++++++------ Mathlib/GroupTheory/Sylow.lean | 28 +++++++ 2 files changed, 137 insertions(+), 22 deletions(-) diff --git a/Mathlib/GroupTheory/PGroup.lean b/Mathlib/GroupTheory/PGroup.lean index 277134ef82a362..bc8ceb648c588a 100644 --- a/Mathlib/GroupTheory/PGroup.lean +++ b/Mathlib/GroupTheory/PGroup.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2018 Chris Hughes. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Chris Hughes, Thomas Browning +Authors: Chris Hughes, Thomas Browning, Snir Broshi -/ module @@ -30,40 +30,124 @@ variable {p} {G} namespace IsPGroup -theorem iff_orderOf [hp : Fact p.Prime] : IsPGroup p G ↔ ∀ g : G, ∃ k : ℕ, orderOf g = p ^ k := - forall_congr' fun g => - ⟨fun ⟨_, hk⟩ => - Exists.imp (fun _ h => h.right) - ((Nat.dvd_prime_pow hp.out).mp (orderOf_dvd_of_pow_eq_one hk)), - Exists.imp fun k hk => by rw [← hk, pow_orderOf_eq_one]⟩ +theorem _root_.isPGroup_iff_pow_pow_eq_one : IsPGroup p G ↔ ∀ g : G, ∃ k, g ^ p ^ k = 1 := + .rfl + +alias ⟨exists_pow_pow_eq_one, _⟩ := isPGroup_iff_pow_pow_eq_one + +theorem _root_.isPGroup_iff_orderOf_dvd_pow : IsPGroup p G ↔ ∀ g : G, ∃ k, orderOf g ∣ p ^ k := by + simp_rw [isPGroup_iff_pow_pow_eq_one, orderOf_dvd_iff_pow_eq_one] + +alias ⟨exists_orderOf_dvd_pow, _⟩ := isPGroup_iff_orderOf_dvd_pow + +theorem iff_orderOf [Fact p.Prime] : IsPGroup p G ↔ ∀ g : G, ∃ k, orderOf g = p ^ k := by + simp_rw [isPGroup_iff_orderOf_dvd_pow, Nat.dvd_prime_pow Fact.out] + exact forall_congr' fun g ↦ ⟨by grind, .imp <| by grind⟩ + +alias ⟨exists_orderOf_eq_pow, _⟩ := iff_orderOf + +theorem of_card_dvd_pow {n : ℕ} (hG : Nat.card G ∣ p ^ n) : IsPGroup p G := by + refine fun g ↦ ⟨n, ?_⟩ + grw [← orderOf_dvd_iff_pow_eq_one, ← hG, orderOf_dvd_natCard] + +theorem _root_.isPGroup_iff_card_dvd_pow [Finite G] : IsPGroup p G ↔ ∃ n, Nat.card G ∣ p ^ n := by + refine ⟨fun h ↦ ?_, fun ⟨n, hn⟩ ↦ of_card_dvd_pow hn⟩ + rcases eq_or_ne p 0 with rfl | hp + · exact ⟨1, by simp⟩ + refine ⟨Nat.card G, Nat.dvd_pow_self_iff NeZero.out hp |>.mpr fun q hq ↦ ?_⟩ + have ⟨hqp, hqdvd, _⟩ := Nat.mem_primeFactors.mp hq + have ⟨g, hg⟩ := exists_prime_orderOf_dvd_card' q (hp := ⟨hqp⟩) hqdvd + have ⟨k, hk⟩ := h.exists_orderOf_dvd_pow g + exact Nat.mem_primeFactors.mpr ⟨hqp, hqp.dvd_of_dvd_pow <| hg ▸ hk, hp⟩ + +alias ⟨exists_card_dvd_pow, _⟩ := isPGroup_iff_card_dvd_pow theorem dvd_orderOf [Fact p.Prime] (hG : IsPGroup p G) {g : G} (hg : g ≠ 1) : p ∣ orderOf g := by - have ⟨k, hk⟩ := IsPGroup.iff_orderOf.mp hG g + have ⟨k, hk⟩ := hG.exists_orderOf_eq_pow g rw [hk] refine dvd_pow_self _ fun hk0 ↦ hg ?_ rw [← orderOf_eq_one_iff, hk, hk0, pow_zero] -theorem of_card {n : ℕ} (hG : Nat.card G = p ^ n) : IsPGroup p G := fun g => - ⟨n, by rw [← hG, pow_card_eq_one']⟩ +theorem of_card {n : ℕ} (hG : Nat.card G = p ^ n) : IsPGroup p G := + of_card_dvd_pow hG.dvd + +variable (p G) in +theorem of_subsingleton [Subsingleton G] : IsPGroup p G := + of_card (n := 0) (by simp) theorem of_bot : IsPGroup p (⊥ : Subgroup G) := - of_card (n := 0) (by rw [Subgroup.card_bot, pow_zero]) + .of_subsingleton p _ + +variable (G) in +@[simp] +protected theorem zero : IsPGroup 0 G := + fun g ↦ ⟨1, by simp⟩ + +@[simp] +theorem _root_.isPGroup_one_iff_subsingleton : IsPGroup 1 G ↔ Subsingleton G := by + refine ⟨?_, fun h ↦ .of_subsingleton 1 G⟩ + simpa [isPGroup_iff_pow_pow_eq_one] using subsingleton_of_forall_eq 1 + +protected theorem card : IsPGroup (Nat.card G) G := + fun g ↦ ⟨1, by simp⟩ + +@[gcongr] +protected theorem mono {q : ℕ} (hpq : p ∣ q) (hp : IsPGroup p G) : IsPGroup q G := by + rw [isPGroup_iff_orderOf_dvd_pow] at hp ⊢ + exact fun g ↦ (hp g).imp fun k hk ↦ hk.trans <| pow_dvd_pow_of_dvd hpq k + +theorem of_pow {n : ℕ} (h : IsPGroup (p ^ n) G) : IsPGroup p G := + fun g ↦ (h g).imp' (n * ·) <| by simp [pow_mul] theorem iff_card [Fact p.Prime] [Finite G] : IsPGroup p G ↔ ∃ n : ℕ, Nat.card G = p ^ n := by - have hG : Nat.card G ≠ 0 := Nat.card_pos.ne' - refine ⟨fun h => ?_, fun ⟨n, hn⟩ => of_card hn⟩ - suffices ∀ q ∈ (Nat.card G).primeFactorsList, q = p by - use (Nat.card G).primeFactorsList.length - rw [← List.prod_replicate, ← List.eq_replicate_of_mem this, Nat.prod_primeFactorsList hG] - intro q hq - obtain ⟨hq1, hq2⟩ := (Nat.mem_primeFactorsList hG).mp hq - have : Fact q.Prime := ⟨hq1⟩ - obtain ⟨g, hg⟩ := exists_prime_orderOf_dvd_card' q hq2 - obtain ⟨k, hk⟩ := (iff_orderOf.mp h) g - exact (hq1.pow_eq_iff.mp (hg.symm.trans hk).symm).1.symm + simp_rw [isPGroup_iff_card_dvd_pow, Nat.dvd_prime_pow Fact.out] + exact ⟨fun ⟨n, k, _, hk⟩ ↦ ⟨k, hk⟩, fun ⟨n, hn⟩ ↦ ⟨n, n, le_rfl, hn⟩⟩ alias ⟨exists_card_eq, _⟩ := iff_card +theorem _root_.isPGroup_iff_exists_orderOf_dvd_pow [Finite G] : + IsPGroup p G ↔ ∃ k, ∀ g : G, orderOf g ∣ p ^ k := by + refine isPGroup_iff_orderOf_dvd_pow.trans ⟨fun h ↦ ?_, fun ⟨k, hk⟩ ↦ fun g ↦ ⟨k, hk g⟩⟩ + choose k hk using h + have := Fintype.ofFinite G + have ⟨g, _, hg⟩ := Finset.exists_max_image .univ k Finset.univ_nonempty + refine ⟨k g, fun g' ↦ ?_⟩ + grw [← Nat.pow_dvd_pow p <| hg g' <| Finset.mem_univ g'] + exact hk g' + +theorem _root_.isPGroup_iff_exists_pow_pow_eq_one [Finite G] : + IsPGroup p G ↔ ∃ k, ∀ g : G, g ^ p ^ k = 1 := by + simp_rw [isPGroup_iff_exists_orderOf_dvd_pow, orderOf_dvd_iff_pow_eq_one] + +theorem of_exponent_dvd_pow {n : ℕ} (h : Monoid.exponent G ∣ p ^ n) : IsPGroup p G := + fun g ↦ ⟨n, Monoid.exponent_dvd_iff_forall_pow_eq_one.mp h g⟩ + +theorem _root_.isPGroup_iff_exponent_dvd_pow [Finite G] : + IsPGroup p G ↔ ∃ n, Monoid.exponent G ∣ p ^ n := by + simp_rw [isPGroup_iff_exists_orderOf_dvd_pow, Monoid.exponent_dvd] + +alias ⟨exists_exponent_dvd_pow, _⟩ := isPGroup_iff_exponent_dvd_pow + +theorem _root_.isPGroup_iff_exponent_eq_pow [Finite G] [Fact p.Prime] : + IsPGroup p G ↔ ∃ n, Monoid.exponent G = p ^ n := by + simp_rw [isPGroup_iff_exponent_dvd_pow, Nat.dvd_prime_pow Fact.out] + exact ⟨fun ⟨n, k, _, hk⟩ ↦ ⟨k, hk⟩, fun ⟨n, hn⟩ ↦ ⟨n, n, le_rfl, hn⟩⟩ + +alias ⟨exists_exponent_eq_pow, _⟩ := isPGroup_iff_exponent_eq_pow + +theorem _root_.isPGroup_iff_isPGroup_prod_primeFactors (h : p ≠ 0) : + IsPGroup p G ↔ IsPGroup (p.primeFactors.prod id) G := + ⟨(.of_pow <| ·.mono <| p.dvd_prod_primeFactors_pow_self h), .mono p.prod_primeFactors_dvd⟩ + +theorem _root_.isPGroup_iff_primeFactors_card_subset [Finite G] (h : p ≠ 0) : + IsPGroup p G ↔ (Nat.card G).primeFactors ⊆ p.primeFactors := by + refine isPGroup_iff_card_dvd_pow.trans ⟨fun ⟨n, hn⟩ ↦ ?_, fun hG ↦ ?_⟩ + · rcases eq_or_ne n 0 with (rfl | hn0) + · simp_all + grw [← Nat.primeFactors_pow p hn0, Nat.primeFactors_mono hn <| pow_ne_zero n h] + · refine ⟨Nat.card G, Nat.dvd_prod_primeFactors_pow_self NeZero.out |>.trans ?_⟩ + grw [Finset.prod_dvd_prod_of_subset _ _ (·) hG, p.prod_primeFactors_dvd] + section GIsPGroup variable (hG : IsPGroup p G) @@ -88,6 +172,9 @@ theorem to_quotient (H : Subgroup G) [H.Normal] : IsPGroup p (G ⧸ H) := theorem of_equiv {H : Type*} [Group H] (ϕ : G ≃* H) : IsPGroup p H := hG.of_surjective ϕ.toMonoidHom ϕ.surjective +theorem isOfFinOrder (hp : p ≠ 0) (g : G) : IsOfFinOrder g := + hG g |>.elim (isOfFinOrder_iff_pow_eq_one.mpr ⟨_, pow_ne_zero · hp |>.pos, ·⟩) + theorem orderOf_coprime {n : ℕ} (hn : p.Coprime n) (g : G) : (orderOf g).Coprime n := let ⟨k, hk⟩ := hG g (hn.pow_left k).coprime_dvd_left (orderOf_dvd_of_pow_eq_one hk) diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index 65c85703ec4f78..022790fc8c2f24 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -120,6 +120,34 @@ theorem coe_ofCard [Finite G] {p : ℕ} [Fact p.Prime] (H : Subgroup G) (card_eq : Nat.card H = p ^ (Nat.card G).factorization p) : ofCard H card_eq = H := rfl +theorem eq_top_of_zero (H : Sylow 0 G) : (H : Subgroup G) = ⊤ := + (H.is_maximal' (.zero _) le_top).symm + +theorem eq_bot_of_one (H : Sylow 1 G) : (H : Subgroup G) = ⊥ := + have := isPGroup_one_iff_subsingleton.mp H.isPGroup' + eq_bot_of_subsingleton _ + +/-- The type of Sylow `p`-subgroups depends only on the prime factors of `p`. -/ +def equivProdPrimeFactors (h : p ≠ 0) : Sylow p G ≃ Sylow (p.primeFactors.prod id) G where + toFun H := { H with + isPGroup' := isPGroup_iff_isPGroup_prod_primeFactors h |>.mp H.isPGroup', + is_maximal' hQ := H.is_maximal' <| isPGroup_iff_isPGroup_prod_primeFactors h |>.mpr hQ } + invFun H := { H with + isPGroup' := isPGroup_iff_isPGroup_prod_primeFactors h |>.mpr H.isPGroup', + is_maximal' hQ := H.is_maximal' <| isPGroup_iff_isPGroup_prod_primeFactors h |>.mp hQ } + left_inv _ := rfl + right_inv _ := rfl + +@[simp] +theorem coe_equivProdPrimeFactors_apply (h : p ≠ 0) (H : Sylow p G) : + (equivProdPrimeFactors h H : Subgroup G) = H := + rfl + +@[simp] +theorem coe_symm_equivProdPrimeFactors_apply (h : p ≠ 0) (H : Sylow (p.primeFactors.prod id) G) : + (equivProdPrimeFactors h |>.symm H : Subgroup G) = H := + rfl + variable (P : Sylow p G) variable {K : Type*} [Group K] (ϕ : K →* G) {N : Subgroup G} From ec5d4a96c358042d43e201026b3d41ed3f616121 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 16 Jul 2026 05:00:52 +0000 Subject: [PATCH 0817/1300] chore(Geometry/Manifold): remove stale `refine ?_` (#41788) Removes stale `refine ?_` line. This is the only such in mathlib. Co-authored-by: Batixx --- Mathlib/Geometry/Manifold/Complex.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/Complex.lean b/Mathlib/Geometry/Manifold/Complex.lean index 0fb3067a0bda7b..abaa2a8a79c5d3 100644 --- a/Mathlib/Geometry/Manifold/Complex.lean +++ b/Mathlib/Geometry/Manifold/Complex.lean @@ -125,7 +125,6 @@ theorem eqOn_of_isPreconnected_of_isMaxOn_norm [StrictConvexSpace ℝ F] {f : M theorem apply_eq_of_isPreconnected_isCompact_isOpen {f : M → F} {U : Set M} {a b : M} (hd : MDiff[U] f) (hpc : IsPreconnected U) (hc : IsCompact U) (ho : IsOpen U) (ha : a ∈ U) (hb : b ∈ U) : f a = f b := by - refine ?_ -- Subtract `f b` to avoid the assumption `[StrictConvexSpace ℝ F]` wlog hb₀ : f b = 0 generalizing f -- TODO: Add `MDifferentiableOn.sub` etc From b08304e28220db4d7e619756cf8bd7628dee77cc Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Thu, 16 Jul 2026 07:12:14 +0000 Subject: [PATCH 0818/1300] doc(MeasureTheory/Group/Arithmetic): fix underscore in docs (#41790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change docstring of `MeasurableSMul₂` to say `MeasurableSMul₂` instead of `Measurable_SMul₂`. --- Mathlib/MeasureTheory/Group/Arithmetic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/MeasureTheory/Group/Arithmetic.lean b/Mathlib/MeasureTheory/Group/Arithmetic.lean index f4f7730d6a9db9..b0cd42cb597c94 100644 --- a/Mathlib/MeasureTheory/Group/Arithmetic.lean +++ b/Mathlib/MeasureTheory/Group/Arithmetic.lean @@ -457,7 +457,7 @@ class MeasurableVAdd₂ (M α : Type*) [VAdd M α] [MeasurableSpace M] [Measurab Prop where measurable_vadd : Measurable (Function.uncurry (· +ᵥ ·) : M × α → α) -/-- We say that the action of `M` on `α` has `Measurable_SMul₂` if the map +/-- We say that the action of `M` on `α` has `MeasurableSMul₂` if the map `(c, x) ↦ c • x` is a measurable function. -/ @[to_additive MeasurableVAdd₂] class MeasurableSMul₂ (M α : Type*) [SMul M α] [MeasurableSpace M] [MeasurableSpace α] : From 4a15420ccd63b5b652d58ce28a6c19e6a0fb0439 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:28:52 +0000 Subject: [PATCH 0819/1300] feat(MeasureTheory): use `IsApply` for `Kernel` (#41179) --- .../Probability/Kernel/Composition/Comp.lean | 3 +- .../Kernel/Composition/CompProd.lean | 2 +- .../Kernel/Composition/Lemmas.lean | 2 +- .../Kernel/Composition/MeasureComp.lean | 8 +-- .../Kernel/Composition/MeasureCompProd.lean | 8 +-- Mathlib/Probability/Kernel/Defs.lean | 53 +++++++++---------- Mathlib/Probability/Kernel/RadonNikodym.lean | 18 +++---- Mathlib/Probability/Kernel/WithDensity.lean | 5 +- Mathlib/Probability/Moments/SubGaussian.lean | 6 +-- 9 files changed, 52 insertions(+), 53 deletions(-) diff --git a/Mathlib/Probability/Kernel/Composition/Comp.lean b/Mathlib/Probability/Kernel/Composition/Comp.lean index 32f9dbe0d534ec..5c2f8b8ee24601 100644 --- a/Mathlib/Probability/Kernel/Composition/Comp.lean +++ b/Mathlib/Probability/Kernel/Composition/Comp.lean @@ -71,7 +71,8 @@ theorem comp_apply_univ_le (κ : Kernel α β) (η : Kernel β γ) (a : α) : _ = Cη * κ a Set.univ := MeasureTheory.lintegral_const Cη _ = κ a Set.univ * Cη := mul_comm _ _ -@[simp] lemma zero_comp (κ : Kernel α β) : (0 : Kernel β γ) ∘ₖ κ = 0 := by ext; simp [comp_apply] +@[simp] lemma zero_comp (κ : Kernel α β) : (0 : Kernel β γ) ∘ₖ κ = 0 := by + ext; simp [comp_apply, FunLike.coe_zero] @[simp] lemma comp_zero (κ : Kernel β γ) : κ ∘ₖ (0 : Kernel α β) = 0 := by ext; simp [comp_apply] diff --git a/Mathlib/Probability/Kernel/Composition/CompProd.lean b/Mathlib/Probability/Kernel/Composition/CompProd.lean index 286cb1d90bfe6f..7656ba92569585 100644 --- a/Mathlib/Probability/Kernel/Composition/CompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/CompProd.lean @@ -507,7 +507,7 @@ lemma compProd_add_right (μ : Kernel α β) (κ η : Kernel (α × β) γ) by_cases hμ : IsSFiniteKernel μ swap; · simp [hμ] ext a s hs - simp only [compProd_apply hs, coe_add, Pi.add_apply, Measure.coe_add] + simp only [compProd_apply hs, FunLike.coe_add, Pi.add_apply, Measure.coe_add] rw [lintegral_add_left] exact measurable_kernel_prodMk_left' hs a diff --git a/Mathlib/Probability/Kernel/Composition/Lemmas.lean b/Mathlib/Probability/Kernel/Composition/Lemmas.lean index d5ce800e00b2a5..b8e1bfc2749113 100644 --- a/Mathlib/Probability/Kernel/Composition/Lemmas.lean +++ b/Mathlib/Probability/Kernel/Composition/Lemmas.lean @@ -80,7 +80,7 @@ namespace MeasureTheory.Measure lemma compProd_eq_parallelComp_comp_copy_comp [SFinite μ] : μ ⊗ₘ κ = (Kernel.id ∥ₖ κ) ∘ₘ Kernel.copy α ∘ₘ μ := by by_cases hκ : IsSFiniteKernel κ - swap; · simp [hκ] + swap; · simp [FunLike.coe_zero, hκ] rw [compProd_eq_comp_prod, ← Kernel.parallelComp_comp_copy, Measure.comp_assoc] lemma prod_comp_right [SFinite ν] {κ : Kernel β γ} [IsSFiniteKernel κ] : diff --git a/Mathlib/Probability/Kernel/Composition/MeasureComp.lean b/Mathlib/Probability/Kernel/Composition/MeasureComp.lean index 385d2a2b295cfa..6f705017349bd3 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureComp.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureComp.lean @@ -112,7 +112,7 @@ lemma comp_compProd_comm {η : Kernel (α × β) γ} [SFinite μ] [IsSFiniteKern η ∘ₘ (μ ⊗ₘ κ) = ((κ ⊗ₖ η) ∘ₘ μ).snd := by by_cases hκ : IsSFiniteKernel κ; swap · simp [compProd_of_not_isSFiniteKernel _ _ hκ, - Kernel.compProd_of_not_isSFiniteKernel_left _ _ hκ] + Kernel.compProd_of_not_isSFiniteKernel_left _ _ hκ, FunLike.coe_zero] ext s hs rw [Measure.bind_apply hs η.aemeasurable, Measure.snd_apply hs, Measure.bind_apply _ (Kernel.aemeasurable _), Measure.lintegral_compProd (η.measurable_coe hs)] @@ -140,15 +140,15 @@ section AddSMul @[simp] lemma comp_add : κ ∘ₘ (μ + ν) = κ ∘ₘ μ + κ ∘ₘ ν := by - simp_rw [comp_eq_comp_const_apply, Kernel.const_add, Kernel.comp_add_right, Kernel.add_apply] + simp_rw [comp_eq_comp_const_apply, Kernel.const_add, Kernel.comp_add_right, _root_.add_apply] lemma add_comp : (κ + η) ∘ₘ μ = κ ∘ₘ μ + η ∘ₘ μ := by - simp_rw [comp_eq_comp_const_apply, Kernel.comp_add_left, Kernel.add_apply] + simp_rw [comp_eq_comp_const_apply, Kernel.comp_add_left, _root_.add_apply] /-- Same as `add_comp` except that it uses `⇑κ + ⇑η` instead of `⇑(κ + η)` in order to have a simp-normal form on the left of the equality. -/ @[simp] -lemma add_comp' : (⇑κ + ⇑η) ∘ₘ μ = κ ∘ₘ μ + η ∘ₘ μ := by rw [← Kernel.coe_add, add_comp] +lemma add_comp' : (⇑κ + ⇑η) ∘ₘ μ = κ ∘ₘ μ + η ∘ₘ μ := by rw [← FunLike.coe_add, add_comp] @[simp] lemma comp_smul (a : ℝ≥0∞) : κ ∘ₘ (a • μ) = a • (κ ∘ₘ μ) := by diff --git a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean index cccee8bacd55fe..4bb790b943df9e 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -49,13 +49,13 @@ scoped[ProbabilityTheory] infixl:100 " ⊗ₘ " => MeasureTheory.Measure.compPro @[simp] lemma compProd_of_not_sfinite (μ : Measure α) (κ : Kernel α β) (h : ¬ SFinite μ) : μ ⊗ₘ κ = 0 := by - rw [compProd, Kernel.compProd_of_not_isSFiniteKernel_left, Kernel.zero_apply] + rw [compProd, Kernel.compProd_of_not_isSFiniteKernel_left, zero_apply] rwa [Kernel.isSFiniteKernel_const] @[simp] lemma compProd_of_not_isSFiniteKernel (μ : Measure α) (κ : Kernel α β) (h : ¬ IsSFiniteKernel κ) : μ ⊗ₘ κ = 0 := by - rw [compProd, Kernel.compProd_of_not_isSFiniteKernel_right, Kernel.zero_apply] + rw [compProd, Kernel.compProd_of_not_isSFiniteKernel_right, zero_apply] rwa [Kernel.isSFiniteKernel_prodMkLeft_unit] lemma compProd_apply [SFinite μ] [IsSFiniteKernel κ] {s : Set (α × β)} (hs : MeasurableSet s) : @@ -146,14 +146,14 @@ lemma compProd_const {ν : Measure β} [SFinite μ] [SFinite ν] : lemma compProd_add_left (μ ν : Measure α) [SFinite μ] [SFinite ν] (κ : Kernel α β) : (μ + ν) ⊗ₘ κ = μ ⊗ₘ κ + ν ⊗ₘ κ := by by_cases hκ : IsSFiniteKernel κ - · simp_rw [Measure.compProd, Kernel.const_add, Kernel.compProd_add_left, Kernel.add_apply] + · simp_rw [Measure.compProd, Kernel.const_add, Kernel.compProd_add_left, _root_.add_apply] · simp [hκ] lemma compProd_add_right (μ : Measure α) (κ η : Kernel α β) [IsSFiniteKernel κ] [IsSFiniteKernel η] : μ ⊗ₘ (κ + η) = μ ⊗ₘ κ + μ ⊗ₘ η := by by_cases hμ : SFinite μ - · simp_rw [Measure.compProd, Kernel.prodMkLeft_add, Kernel.compProd_add_right, Kernel.add_apply] + · simp_rw [Measure.compProd, Kernel.prodMkLeft_add, Kernel.compProd_add_right, _root_.add_apply] · simp [hμ] lemma compProd_sum_left {ι : Type*} [Countable ι] {μ : ι → Measure α} [∀ i, SFinite (μ i)] : diff --git a/Mathlib/Probability/Kernel/Defs.lean b/Mathlib/Probability/Kernel/Defs.lean index d490b563f55331..6c543a4f5e0a5e 100644 --- a/Mathlib/Probability/Kernel/Defs.lean +++ b/Mathlib/Probability/Kernel/Defs.lean @@ -91,16 +91,25 @@ noncomputable instance instAdd : Add (Kernel α β) where add κ η := ⟨κ + noncomputable instance instSMulNat : SMul ℕ (Kernel α β) where smul n κ := ⟨n • κ, (measurable_const (a := n)).smul κ.2⟩ -@[simp, norm_cast] lemma coe_zero : ⇑(0 : Kernel α β) = 0 := rfl -@[simp, norm_cast] lemma coe_add (κ η : Kernel α β) : ⇑(κ + η) = κ + η := rfl -@[simp, norm_cast] lemma coe_nsmul (n : ℕ) (κ : Kernel α β) : ⇑(n • κ) = n • κ := rfl +instance : IsZeroApply (Kernel α β) α (Measure β) where + zero_apply _ := rfl -@[simp] lemma zero_apply (a : α) : (0 : Kernel α β) a = 0 := rfl -@[simp] lemma add_apply (κ η : Kernel α β) (a : α) : (κ + η) a = κ a + η a := rfl -@[simp] lemma nsmul_apply (n : ℕ) (κ : Kernel α β) (a : α) : (n • κ) a = n • κ a := rfl +instance : IsAddApply (Kernel α β) α (Measure β) where + add_apply _ _ _ := rfl + +instance : IsSMulApply ℕ (Kernel α β) α (Measure β) where + smul_apply _ _ _ := rfl + +@[deprecated (since := "2026-06-30")] alias coe_zero := FunLike.coe_zero +@[deprecated (since := "2026-06-30")] alias coe_add := FunLike.coe_add +@[deprecated (since := "2026-06-30")] alias coe_nsmul := FunLike.coe_smul + +@[deprecated (since := "2026-06-30")] protected alias zero_apply := zero_apply +@[deprecated (since := "2026-06-30")] protected alias add_apply := add_apply +@[deprecated (since := "2026-06-30")] protected alias nsmul_apply := smul_apply noncomputable instance instAddCommMonoid : AddCommMonoid (Kernel α β) := - DFunLike.coe_injective.addCommMonoid _ coe_zero coe_add (by intros; rfl) + fast_instance% FunLike.addCommMonoid instance instPartialOrder : PartialOrder (Kernel α β) := .lift _ DFunLike.coe_injective @@ -112,32 +121,22 @@ noncomputable instance instOrderBot {α β : Type*} [MeasurableSpace α] [MeasurableSpace β] : OrderBot (Kernel α β) where bot := 0 - bot_le κ a := by simp only [coe_zero, Pi.zero_apply, Measure.zero_le] + bot_le κ a := by simp only [zero_apply, Measure.zero_le] -/-- Coercion to a function as an additive monoid homomorphism. -/ -noncomputable def coeAddHom (α β : Type*) [MeasurableSpace α] [MeasurableSpace β] : - Kernel α β →+ α → Measure β where - toFun := (⇑) - map_zero' := coe_zero - map_add' := coe_add +@[deprecated (since := "2026-06-30")] alias coeAddHom := FunLike.coe_coeAddMonoidHom -@[simp] -theorem coeAddHom_apply (α β : Type*) [MeasurableSpace α] [MeasurableSpace β] (κ : Kernel α β) : - coeAddHom α β κ = ⇑κ := rfl +@[deprecated (since := "2026-06-30")] alias coeAddHom_apply := FunLike.coeAddMonoidHom_apply -@[simp] -theorem coe_finsetSum (I : Finset ι) (κ : ι → Kernel α β) : ⇑(∑ i ∈ I, κ i) = ∑ i ∈ I, ⇑(κ i) := - map_sum (coeAddHom α β) _ _ +@[deprecated (since := "2026-06-30")] alias coe_finsetSum := FunLike.coe_sum -@[deprecated (since := "2026-04-08")] alias coe_finset_sum := coe_finsetSum +@[deprecated (since := "2026-04-08")] alias coe_finset_sum := FunLike.coe_sum -theorem finsetSum_apply (I : Finset ι) (κ : ι → Kernel α β) (a : α) : - (∑ i ∈ I, κ i) a = ∑ i ∈ I, κ i a := by rw [coe_finsetSum, Finset.sum_apply] +@[deprecated (since := "2026-06-30")] alias finsetSum_apply := sum_apply -@[deprecated (since := "2026-04-08")] alias finset_sum_apply := finsetSum_apply +@[deprecated (since := "2026-04-08")] alias finset_sum_apply := sum_apply theorem finsetSum_apply' (I : Finset ι) (κ : ι → Kernel α β) (a : α) (s : Set β) : - (∑ i ∈ I, κ i) a s = ∑ i ∈ I, κ i a s := by rw [finsetSum_apply, Measure.finsetSum_apply] + (∑ i ∈ I, κ i) a s = ∑ i ∈ I, κ i a s := by rw [sum_apply, Measure.finsetSum_apply] @[deprecated (since := "2026-04-08")] alias finset_sum_apply' := finsetSum_apply' @@ -221,7 +220,7 @@ instance (priority := 100) IsMarkovKernel.IsZeroOrMarkovKernel [h : IsMarkovKern instance (priority := 100) IsZeroOrMarkovKernel.isZeroOrProbabilityMeasure [IsZeroOrMarkovKernel κ] (a : α) : IsZeroOrProbabilityMeasure (κ a) := by rcases eq_zero_or_isMarkovKernel κ with rfl | h' - · simp only [Kernel.zero_apply] + · simp only [zero_apply] infer_instance · infer_instance @@ -337,7 +336,7 @@ theorem sum_fintype [Fintype ι] (κ : ι → Kernel α β) : Kernel.sum κ = theorem sum_add [Countable ι] (κ η : ι → Kernel α β) : (Kernel.sum fun n => κ n + η n) = Kernel.sum κ + Kernel.sum η := by ext a s hs - simp only [coe_add, Pi.add_apply, sum_apply, Measure.sum_apply _ hs, Pi.add_apply, + simp only [add_apply, sum_apply, Measure.sum_apply _ hs, Pi.add_apply, Measure.coe_add, ENNReal.summable.tsum_add ENNReal.summable] end Sum diff --git a/Mathlib/Probability/Kernel/RadonNikodym.lean b/Mathlib/Probability/Kernel/RadonNikodym.lean index 37e2a38b4c4336..5c504817a8c66d 100644 --- a/Mathlib/Probability/Kernel/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/RadonNikodym.lean @@ -167,7 +167,7 @@ lemma withDensity_one_sub_rnDerivAux (κ η : Kernel α γ) [IsFiniteKernel κ] = κ a s + η a s := by rw [this] simp - simp only [coe_add, Pi.add_apply, Measure.coe_add] at h + simp only [FunLike.coe_add, Pi.add_apply, Measure.coe_add] at h rwa [withDensity_rnDerivAux, add_comm, ENNReal.add_right_inj (measure_ne_top _ _)] at h simp_rw [ofNNReal_toNNReal, ENNReal.ofReal_sub _ (rnDerivAux_nonneg h_le), ENNReal.ofReal_one] rw [withDensity_sub_add_cancel] @@ -381,7 +381,7 @@ lemma rnDeriv_add_singularPart (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFin withDensity η (rnDeriv κ η) + singularPart κ η = κ := by ext a s hs rw [← inter_union_sdiff s (mutuallySingularSetSlice κ η a)] - simp only [coe_add, Pi.add_apply, Measure.coe_add] + simp only [FunLike.coe_add, Pi.add_apply, Measure.coe_add] have hm := measurableSet_mutuallySingularSetSlice κ η a simp only [measure_union (Disjoint.mono inter_subset_right le_rfl disjoint_sdiff_right) (hs.diff hm)] @@ -413,7 +413,7 @@ lemma withDensity_rnDeriv_eq_zero_iff_apply_eq_zero (κ η : Kernel α γ) [IsFi lemma singularPart_eq_zero_iff_absolutelyContinuous (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] (a : α) : singularPart κ η a = 0 ↔ κ a ≪ η a := by - conv_rhs => rw [← rnDeriv_add_singularPart κ η, coe_add, Pi.add_apply] + conv_rhs => rw [← rnDeriv_add_singularPart κ η, add_apply] refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ · rw [h, add_zero] exact withDensity_absolutelyContinuous _ _ @@ -424,7 +424,7 @@ lemma singularPart_eq_zero_iff_absolutelyContinuous (κ η : Kernel α γ) lemma withDensity_rnDeriv_eq_zero_iff_mutuallySingular (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] (a : α) : withDensity η (rnDeriv κ η) a = 0 ↔ κ a ⟂ₘ η a := by - conv_rhs => rw [← rnDeriv_add_singularPart κ η, coe_add, Pi.add_apply] + conv_rhs => rw [← rnDeriv_add_singularPart κ η, add_apply] refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ · rw [h, zero_add] exact mutuallySingular_singularPart _ _ _ @@ -440,7 +440,7 @@ lemma singularPart_eq_zero_iff_measure_eq_zero (κ η : Kernel α γ) simp_rw [Kernel.ext_iff, Measure.ext_iff] at h_eq_add specialize h_eq_add a (mutuallySingularSetSlice κ η a) (measurableSet_mutuallySingularSetSlice κ η a) - simp only [coe_add, Pi.add_apply, Measure.coe_add, + simp only [FunLike.coe_add, Pi.add_apply, Measure.coe_add, withDensity_rnDeriv_mutuallySingularSetSlice κ η, zero_add] at h_eq_add rw [← h_eq_add] exact singularPart_eq_zero_iff_apply_eq_zero κ η a @@ -452,7 +452,7 @@ lemma withDensity_rnDeriv_eq_zero_iff_measure_eq_zero (κ η : Kernel α γ) simp_rw [Kernel.ext_iff, Measure.ext_iff] at h_eq_add specialize h_eq_add a (mutuallySingularSetSlice κ η a)ᶜ (measurableSet_mutuallySingularSetSlice κ η a).compl - simp only [coe_add, Pi.add_apply, Measure.coe_add, + simp only [FunLike.coe_add, Pi.add_apply, Measure.coe_add, singularPart_compl_mutuallySingularSetSlice κ η, add_zero] at h_eq_add rw [← h_eq_add] exact withDensity_rnDeriv_eq_zero_iff_apply_eq_zero κ η a @@ -490,7 +490,7 @@ lemma eq_rnDeriv_measure (h : κ = η.withDensity f + ξ) (hf : Measurable (Function.uncurry f)) (a : α) (hξ : ξ a ⟂ₘ η a) : f a =ᵐ[η a] ∂(κ a)/∂(η a) := by have : κ a = ξ a + (η a).withDensity (f a) := by - rw [h, coe_add, Pi.add_apply, η.withDensity_apply hf, add_comm] + rw [h, add_apply, η.withDensity_apply hf, add_comm] exact (κ a).eq_rnDeriv₀ (hf.comp measurable_prodMk_left).aemeasurable hξ this omit hαγ in @@ -498,7 +498,7 @@ lemma eq_singularPart_measure (h : κ = η.withDensity f + ξ) (hf : Measurable (Function.uncurry f)) (a : α) (hξ : ξ a ⟂ₘ η a) : ξ a = (κ a).singularPart (η a) := by have : κ a = ξ a + (η a).withDensity (f a) := by - rw [h, coe_add, Pi.add_apply, η.withDensity_apply hf, add_comm] + rw [h, add_apply, η.withDensity_apply hf, add_comm] exact (κ a).eq_singularPart (hf.comp measurable_prodMk_left) hξ this variable [IsFiniteKernel κ] {a : α} @@ -579,7 +579,7 @@ lemma rnDeriv_add (κ ν η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel rnDeriv (κ + ν) η a =ᵐ[η a] rnDeriv κ η a + rnDeriv ν η a := by filter_upwards [(κ + ν).rnDeriv_eq_rnDeriv_measure, κ.rnDeriv_eq_rnDeriv_measure, ν.rnDeriv_eq_rnDeriv_measure, (κ a).rnDeriv_add (ν a) (η a)] with x h1 h2 h3 h4 - rw [h1, Pi.add_apply, h2, h3, coe_add, Pi.add_apply, h4, Pi.add_apply] + simp [h1, h2, h3, h4] lemma setLIntegral_rnDeriv_le {κ η : Kernel α γ} [IsFiniteKernel κ] [IsFiniteKernel η] {a : α} {s : Set γ} (hs : MeasurableSet s) : diff --git a/Mathlib/Probability/Kernel/WithDensity.lean b/Mathlib/Probability/Kernel/WithDensity.lean index bec7e016faf23a..c8c3044dc08b5d 100644 --- a/Mathlib/Probability/Kernel/WithDensity.lean +++ b/Mathlib/Probability/Kernel/WithDensity.lean @@ -121,8 +121,7 @@ theorem withDensity_add_left (κ η : Kernel α β) [IsSFiniteKernel κ] [IsSFin (f : α → β → ℝ≥0∞) : withDensity (κ + η) f = withDensity κ f + withDensity η f := by by_cases hf : Measurable (Function.uncurry f) · ext a s - simp only [Kernel.withDensity_apply _ hf, coe_add, Pi.add_apply, withDensity_add_measure, - Measure.add_apply] + simp only [Kernel.withDensity_apply _ hf, add_apply, withDensity_add_measure] · simp_rw [withDensity_of_not_measurable _ hf] rw [zero_add] @@ -140,7 +139,7 @@ lemma withDensity_add_right [IsSFiniteKernel κ] {f g : α → β → ℝ≥0∞ (hf : Measurable (Function.uncurry f)) (hg : Measurable (Function.uncurry g)) : withDensity κ (f + g) = withDensity κ f + withDensity κ g := by ext a - rw [coe_add, Pi.add_apply, Kernel.withDensity_apply _ hf, Kernel.withDensity_apply _ hg, + rw [add_apply, Kernel.withDensity_apply _ hf, Kernel.withDensity_apply _ hg, Kernel.withDensity_apply, Pi.add_apply, MeasureTheory.withDensity_add_right] · fun_prop · exact hf.add hg diff --git a/Mathlib/Probability/Moments/SubGaussian.lean b/Mathlib/Probability/Moments/SubGaussian.lean index 0de6c2ca8428f9..702e717651d331 100644 --- a/Mathlib/Probability/Moments/SubGaussian.lean +++ b/Mathlib/Probability/Moments/SubGaussian.lean @@ -255,7 +255,7 @@ lemma zero [IsFiniteMeasure ν] [IsZeroOrMarkovKernel κ] : HasSubgaussianMGF 0 @[simp] lemma zero_kernel : HasSubgaussianMGF X c (0 : Kernel Ω' Ω) ν := by constructor - · simp + · simp [FunLike.coe_zero] · simp [exp_nonneg] @[simp] @@ -469,9 +469,9 @@ lemma integrable_exp_add_compProd {η : Kernel (Ω' × Ω) Ω''} [IsZeroOrMarkov (hX : HasSubgaussianMGF X c κ ν) (hY : HasSubgaussianMGF Y cY η (ν ⊗ₘ κ)) (t : ℝ) : Integrable (fun ω ↦ exp (t * (X ω.1 + Y ω.2))) ((κ ⊗ₖ η) ∘ₘ ν) := by by_cases hκ : IsSFiniteKernel κ - swap; · simp [hκ] + swap; · simp [FunLike.coe_zero, hκ] rcases eq_zero_or_isMarkovKernel η with rfl | hη - · simp + · simp [FunLike.coe_zero] simp_rw [mul_add, exp_add] refine MemLp.integrable_mul (p := 2) (q := 2) ?_ ?_ · have h := hX.memLp_exp_mul t 2 From 3849b6a105ceeee669a39b2e4c607c61984ebf6f Mon Sep 17 00:00:00 2001 From: Oliver Butterley <51876429+oliver-butterley@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:52:21 +0000 Subject: [PATCH 0820/1300] feat(MeasureTheory.VectorMeasure): variation defined as a supremum is equal to variation defined using the Hahn-Jordan decomposition (#26168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `totalVariation_eq_variation`: if `μ` is a `SignedMeasure` then variation defined as a supremum (`MeasureTheory.VectorMeasure.variation`) is equal to variation defined using the Hahn-Jordan decomposition (`MeasureTheory.SignedMeasure.totalVariation`) . - [x] depends on #26165 Co-authored-by: @yoh-tanimoto --- Mathlib.lean | 1 + .../VectorMeasure/Decomposition/Jordan.lean | 9 +++ .../Variation/SignedMeasure.lean | 81 +++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 Mathlib/MeasureTheory/VectorMeasure/Variation/SignedMeasure.lean diff --git a/Mathlib.lean b/Mathlib.lean index b2b7f153003840..9264cd03c93cf3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5664,6 +5664,7 @@ public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic public import Mathlib.MeasureTheory.VectorMeasure.Variation.Defs public import Mathlib.MeasureTheory.VectorMeasure.Variation.Semivariation +public import Mathlib.MeasureTheory.VectorMeasure.Variation.SignedMeasure public import Mathlib.MeasureTheory.VectorMeasure.WithDensity public import Mathlib.MeasureTheory.VectorMeasure.WithDensityVec public import Mathlib.ModelTheory.Algebra.Field.Basic diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean index 417bfddffebd7e..76deafebc304ab 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean @@ -460,12 +460,21 @@ theorem toJordanDecomposition_eq {s : SignedMeasure α} {j : JordanDecomposition def totalVariation (s : SignedMeasure α) : Measure α := s.toJordanDecomposition.posPart + s.toJordanDecomposition.negPart +instance (s : SignedMeasure α) : IsFiniteMeasure s.totalVariation := by + unfold totalVariation; infer_instance + theorem totalVariation_zero : (0 : SignedMeasure α).totalVariation = 0 := by simp [totalVariation, toJordanDecomposition_zero] theorem totalVariation_neg (s : SignedMeasure α) : (-s).totalVariation = s.totalVariation := by simp [totalVariation, toJordanDecomposition_neg, add_comm] +/-- Pointwise form of `toSignedMeasure_toJordanDecomposition`. -/ +theorem apply_eq_posPart_real_sub_negPart_real (s : SignedMeasure α) {i : Set α} + (hi : MeasurableSet i) : + s i = s.toJordanDecomposition.posPart.real i - s.toJordanDecomposition.negPart.real i := by + grind [Measure.toSignedMeasure_sub_apply, toSignedMeasure, toSignedMeasure_toJordanDecomposition] + theorem null_of_totalVariation_zero (s : SignedMeasure α) {i : Set α} (hs : s.totalVariation i = 0) : s i = 0 := by rw [totalVariation, Measure.coe_add, Pi.add_apply, add_eq_zero] at hs diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/SignedMeasure.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/SignedMeasure.lean new file mode 100644 index 00000000000000..c357f2aac23cde --- /dev/null +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/SignedMeasure.lean @@ -0,0 +1,81 @@ +/- +Copyright (c) 2025 Oliver Butterley. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Oliver Butterley, Yoh Tanimoto +-/ +module + +public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.Jordan +public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic +/-! +# Equivalence of variation definitions for signed measures + +For a `SignedMeasure`, two definitions of variation are available: +* the supremum-based `VectorMeasure.variation`, +* the Hahn–Jordan-based `SignedMeasure.totalVariation`. + +In this file the two notions are shown to coincide. + +## Main results + +* `MeasureTheory.SignedMeasure.totalVariation_eq_variation`: `μ.totalVariation = μ.variation`. + +-/ + +public section + +open scoped ENNReal NNReal + +namespace MeasureTheory.SignedMeasure + +variable {X : Type*} {mX : MeasurableSpace X} (μ : SignedMeasure X) + +/-- The pointwise bound `‖s i‖ ≤ s.totalVariation.real i` for any signed measure. -/ +theorem norm_le_totalVariation (s : SignedMeasure X) (i : Set X) : + ‖s i‖ ≤ s.totalVariation.real i := by + by_cases hi : MeasurableSet i + · rw [s.apply_eq_posPart_real_sub_negPart_real hi, totalVariation, measureReal_add_apply] + grind [measureReal_nonneg, Real.norm_eq_abs] + · simp [hi] + +/-- The pointwise bound `‖s i‖ₑ ≤ s.totalVariation i` for any signed measure. -/ +theorem enorm_le_totalVariation (s : SignedMeasure X) (i : Set X) : + ‖s i‖ₑ ≤ s.totalVariation i := calc + _ = ENNReal.ofReal ‖s i‖ := (ofReal_norm _).symm + _ ≤ ENNReal.ofReal (s.totalVariation.real i) := + ENNReal.ofReal_le_ofReal (s.norm_le_totalVariation i) + _ = _ := by rw [measureReal_def, ENNReal.ofReal_toReal (measure_ne_top _ _)] + +private lemma toMeasureOfZeroLE_apply_eq_enorm {i j : Set X} (him : MeasurableSet i) (hi : 0 ≤[i] μ) + (hjm : MeasurableSet j) : μ.toMeasureOfZeroLE i him hi j = ‖μ (i ∩ j)‖ₑ := by + have : 0 ≤ μ (i ∩ j) := + μ.nonneg_of_zero_le_restrict (μ.zero_le_restrict_subset ‹_› Set.inter_subset_left ‹_›) + rw [Real.enorm_of_nonneg this, μ.toMeasureOfZeroLE_apply hi him hjm, ENNReal.ofReal_eq_coe_nnreal] + +private lemma toMeasureOfLEZero_apply_eq_enorm {i j : Set X} (him : MeasurableSet i) + (hi : μ ≤[i] 0) (hjm : MeasurableSet j) : + μ.toMeasureOfLEZero i him hi j = ‖μ (i ∩ j)‖ₑ := by + have : μ (i ∩ j) ≤ 0 := + μ.nonpos_of_restrict_le_zero (μ.restrict_le_zero_subset ‹_› Set.inter_subset_left ‹_›) + rw [← enorm_neg, Real.enorm_of_nonneg (neg_nonneg.mpr this), μ.toMeasureOfLEZero_apply hi him hjm, + ENNReal.ofReal_eq_coe_nnreal] + +/-- The Hahn–Jordan-based `totalVariation` agrees with the supremum-based `variation`. -/ +theorem totalVariation_eq_variation (μ : SignedMeasure X) : μ.totalVariation = μ.variation := by + ext r hr + apply le_antisymm + · obtain ⟨s, hs, hpos, hneg, hposPart, hnegPart⟩ := μ.toJordanDecomposition_spec + calc μ.totalVariation r + _ = ‖μ (s ∩ r)‖ₑ + ‖μ (sᶜ ∩ r)‖ₑ := by + rw [totalVariation, Measure.add_apply, hposPart, hnegPart, + μ.toMeasureOfZeroLE_apply_eq_enorm hs hpos hr, + μ.toMeasureOfLEZero_apply_eq_enorm hs.compl hneg hr] + _ ≤ μ.variation (s ∩ r) + μ.variation (sᶜ ∩ r) := + add_le_add (μ.enorm_measure_le_variation _) (μ.enorm_measure_le_variation _) + _ = μ.variation ((s ∩ r) ∪ (sᶜ ∩ r)) := + (measure_union (by grind) (hs.compl.inter hr)).symm + _ = μ.variation r := by congr; grind + · apply VectorMeasure.variation_le_of_forall_enorm_le + exact fun s _ ↦ enorm_le_totalVariation μ s + +end MeasureTheory.SignedMeasure From 170a0e5a87e15d8dffaded4386226cd9ab5015b4 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:02:07 +0000 Subject: [PATCH 0821/1300] feat(MeasureTheory/Integral/IntegralEqImproper): {integral,integrableOn}_comp_{exp,log}_Ioi (#41119) Change of variable lemmas for improper integrals on `Set.Ioi a` under `Real.exp` or `Real.log`. Conveniently, no measurability hypotheses on the integrand are needed. Co-authored-by: Terence Tao --- .../Integral/IntegralEqImproper.lean | 87 +++++++++++++------ 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index 23db79f3ecf25c..7de909dd857336 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -1129,47 +1129,82 @@ theorem integral_comp_mul_deriv_Ioi {f f' : ℝ → ℝ} {g : ℝ → ℝ} {a : /-- Substitution `y = x ^ p` in integrals over `Ioi 0` -/ theorem integral_comp_rpow_Ioi (g : ℝ → E) {p : ℝ} (hp : p ≠ 0) : - (∫ x in Ioi 0, (|p| * x ^ (p - 1)) • g (x ^ p)) = ∫ y in Ioi 0, g y := by - let S := Ioi (0 : ℝ) - have a1 : ∀ x : ℝ, x ∈ S → HasDerivWithinAt (fun t : ℝ => t ^ p) (p * x ^ (p - 1)) S x := - fun x hx => (hasDerivAt_rpow_const (Or.inl (mem_Ioi.mp hx).ne')).hasDerivWithinAt - have a2 : InjOn (fun x : ℝ => x ^ p) S := by - rcases lt_or_gt_of_ne hp with (h | h) - · apply StrictAntiOn.injOn - intro x hx y hy hxy - rw [← inv_lt_inv₀ (rpow_pos_of_pos hx p) (rpow_pos_of_pos hy p), ← rpow_neg (le_of_lt hx), - ← rpow_neg (le_of_lt hy)] - exact rpow_lt_rpow (le_of_lt hx) hxy (neg_pos.mpr h) - exact StrictMonoOn.injOn fun x hx y _ hxy => rpow_lt_rpow (mem_Ioi.mp hx).le hxy h - have a3 : (fun t : ℝ => t ^ p) '' S = S := by + ∫ x in Ioi 0, (|p| * x ^ (p - 1)) • g (x ^ p) = ∫ y in Ioi 0, g y := by + have a : (· ^ p) '' (Ioi 0) = Ioi (0 : ℝ) := by ext1 x; rw [mem_image]; constructor · rintro ⟨y, hy, rfl⟩; exact rpow_pos_of_pos hy p - · intro hx; refine ⟨x ^ (1 / p), rpow_pos_of_pos hx _, ?_⟩ - rw [← rpow_mul (le_of_lt hx), one_div_mul_cancel hp, rpow_one] - have := integral_image_eq_integral_abs_deriv_smul measurableSet_Ioi a1 a2 g - rw [a3] at this; rw [this] - refine setIntegral_congr_fun measurableSet_Ioi ?_ - intro x hx; dsimp only + · exact fun hx ↦ ⟨x ^ (1 / p), rpow_pos_of_pos hx _, by simp [← rpow_mul (le_of_lt hx), hp]⟩ + have := integral_image_eq_integral_abs_deriv_smul measurableSet_Ioi + (fun x hx ↦ (hasDerivAt_rpow_const (Or.inl (mem_Ioi.mp hx).ne')).hasDerivWithinAt) + ((rpow_left_injOn hp).mono (by grind)) g + rw [a] at this; rw [this] + refine setIntegral_congr_fun measurableSet_Ioi (fun x hx ↦ ?_) rw [abs_mul, abs_of_nonneg (rpow_nonneg (le_of_lt hx) _)] theorem integral_comp_rpow_Ioi_of_pos {g : ℝ → E} {p : ℝ} (hp : 0 < p) : - (∫ x in Ioi 0, (p * x ^ (p - 1)) • g (x ^ p)) = ∫ y in Ioi 0, g y := by - convert! integral_comp_rpow_Ioi g hp.ne' - rw [abs_of_nonneg hp.le] + ∫ x in Ioi 0, (p * x ^ (p - 1)) • g (x ^ p) = ∫ y in Ioi 0, g y := by + simpa [abs_of_nonneg hp.le] using integral_comp_rpow_Ioi g hp.ne' + +theorem integral_comp_rpow_Ioi_of_pos' {g : ℝ → E} {p : ℝ} (hp : 0 < p) {c : ℝ} (hc : 0 ≤ c) : + ∫ x in Ioi (c ^ p⁻¹), (p * x ^ (p - 1)) • g (x ^ p) = ∫ y in Ioi c, g y := by + have : 0 ≤ c ^ p⁻¹ := by positivity + have : Ioi c = (· ^ p) '' Ioi (c ^ p⁻¹) := by + rw [(continuous_rpow_const hp.le).continuousOn.image_Ioi_of_strictMonoOn + ((strictMonoOn_rpow_Ici_of_exponent_pos hp).mono (by grind)) (tendsto_rpow_atTop hp)] + simp [← rpow_mul hc, hp.ne.symm] + rw [this, integral_image_eq_integral_abs_deriv_smul (measurableSet_Ioi (a := c ^ p⁻¹)) + (fun _ _ ↦ (hasDerivAt_rpow_const (by grind)).hasDerivWithinAt) + ((rpow_left_injOn hp.ne.symm).mono (Set.Ioi_subset_Ici (by positivity)))] + refine setIntegral_congr_fun measurableSet_Ioi (fun x _ ↦ ?_) + have : 0 ≤ x := by grind + rw [abs_of_nonneg (by positivity)] + +/-- Substitution `y = exp x` in integrals over `Ioi a` -/ +theorem integral_comp_exp_Ioi (g : ℝ → E) (a : ℝ) : + ∫ x in Ioi a, exp x • g (exp x) = ∫ y in Ioi (exp a), g y := by + symm; rw [← image_exp_Ioi] + simpa [abs_of_pos (exp_pos _)] using integral_image_eq_integral_abs_deriv_smul + (measurableSet_Ioi (a := a)) (fun x _ ↦ (hasDerivAt_exp x).hasDerivWithinAt) + (fun x _ y _ hxy ↦ exp_injective hxy) g + +theorem integrableOn_comp_exp_Ioi (g : ℝ → E) (a : ℝ) : + IntegrableOn (fun x ↦ exp x • g (exp x)) (Ioi a) ↔ IntegrableOn g (Ioi (exp a)) := by + symm; rw [← image_exp_Ioi] + simpa [abs_of_pos (exp_pos _)] using integrableOn_image_iff_integrableOn_abs_deriv_smul + (measurableSet_Ioi (a := a)) (fun x _ ↦ (hasDerivAt_exp x).hasDerivWithinAt) + (fun x _ y _ hxy ↦ exp_injective hxy) g + +/-- Substitution `y = log x` in integrals over `Ioi a` -/ +theorem integral_comp_log_Ioi (g : ℝ → E) {a : ℝ} (ha : 0 < a) : + ∫ x in Ioi a, x⁻¹ • g (log x) = ∫ y in Ioi (log a), g y := by + simpa [exp_log ha] using (integral_comp_exp_Ioi (fun x ↦ x⁻¹ • g (log x)) (log a)).symm + +theorem integrableOn_comp_log_Ioi (g : ℝ → E) {a : ℝ} (ha : 0 < a) : + IntegrableOn (fun x ↦ x⁻¹ • g (log x)) (Ioi a) ↔ IntegrableOn g (Ioi (log a)) := by + symm + simpa [exp_log ha] using integrableOn_comp_exp_Ioi (fun x ↦ x⁻¹ • g (log x)) (log a) theorem integral_comp_mul_left_Ioi (g : ℝ → E) (a : ℝ) {b : ℝ} (hb : 0 < b) : - (∫ x in Ioi a, g (b * x)) = b⁻¹ • ∫ x in Ioi (b * a), g x := by + ∫ x in Ioi a, g (b * x) = b⁻¹ • ∫ x in Ioi (b * a), g x := by have : ∀ c : ℝ, MeasurableSet (Ioi c) := fun c => measurableSet_Ioi - rw [← integral_indicator (this a), ← integral_indicator (this (b * a)), + rw [← integral_indicator (this _), ← integral_indicator (this _), ← abs_of_pos (inv_pos.mpr hb), ← Measure.integral_comp_mul_left] congr ext1 x rw [← indicator_comp_right, preimage_const_mul_Ioi₀ _ hb, mul_div_cancel_left₀ _ hb.ne', Function.comp_def] +theorem integral_comp_mul_left_Ioi' (g : ℝ → E) (a : ℝ) {b : ℝ} (hb : 0 < b) : + b • ∫ x in Ioi a, g (b * x) = ∫ x in Ioi (b * a), g x := by + simp [integral_comp_mul_left_Ioi g a hb, smul_smul, mul_inv_cancel₀ hb.ne'] + theorem integral_comp_mul_right_Ioi (g : ℝ → E) (a : ℝ) {b : ℝ} (hb : 0 < b) : - (∫ x in Ioi a, g (x * b)) = b⁻¹ • ∫ x in Ioi (a * b), g x := by - simpa only [mul_comm] using integral_comp_mul_left_Ioi g a hb + ∫ x in Ioi a, g (x * b) = b⁻¹ • ∫ x in Ioi (a * b), g x := by + simpa [mul_comm] using integral_comp_mul_left_Ioi g a hb + +theorem integral_comp_mul_right_Ioi' (g : ℝ → E) (a : ℝ) {b : ℝ} (hb : 0 < b) : + b • ∫ x in Ioi a, g (x * b) = ∫ x in Ioi (a * b), g x := by + simp [integral_comp_mul_right_Ioi g a hb, smul_smul, mul_inv_cancel₀ hb.ne'] end IoiChangeVariables From f331b1b9987abdec66954fbe4f00dc2cdd4d73c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:27:08 +0000 Subject: [PATCH 0822/1300] chore(MeasureTheory/SetSemiring): golf some proofs (#40575) The constructions which are defined using choice are unexposed and redefined to allow for these simplifications. --- Mathlib/MeasureTheory/SetSemiring.lean | 449 ++++++++++--------------- 1 file changed, 176 insertions(+), 273 deletions(-) diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 93f5672e20a9d9..17ec14ff8ffedb 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -49,7 +49,7 @@ A ring of sets is a set of sets containing `∅`, stable by union, set differenc -/ -@[expose] public section +public section open Finset Set @@ -72,6 +72,79 @@ structure IsSetRing (C : Set (Set α)) : Prop where union_mem ⦃s t : Set α⦄ : s ∈ C → t ∈ C → s ∪ t ∈ C sdiff_mem ⦃s t : Set α⦄ : s ∈ C → t ∈ C → s \ t ∈ C +namespace IsSetRing + +lemma inter_mem (hC : IsSetRing C) (hs : s ∈ C) (ht : t ∈ C) : s ∩ t ∈ C := by + rw [← sdiff_sdiff_right_self]; exact hC.sdiff_mem hs (hC.sdiff_mem hs ht) + +lemma isSetSemiring (hC : IsSetRing C) : IsSetSemiring C where + empty_mem := hC.empty_mem + inter_mem := fun _ hs _ ht => hC.inter_mem hs ht + sdiff_eq_sUnion' := by + refine fun s hs t ht => ⟨{s \ t}, ?_, ?_, ?_⟩ + · simp only [coe_singleton, Set.singleton_subset_iff] + exact hC.sdiff_mem hs ht + · simp only [coe_singleton, pairwiseDisjoint_singleton] + · simp only [coe_singleton, sUnion_singleton] + +lemma biUnion_mem {ι : Type*} (hC : IsSetRing C) {s : ι → Set α} + (S : Finset ι) (hs : ∀ n ∈ S, s n ∈ C) : + ⋃ i ∈ S, s i ∈ C := by + classical + induction S using Finset.induction with + | empty => simp [hC.empty_mem] + | insert i S _ h => + simp_rw [← Finset.mem_coe, Finset.coe_insert, Set.biUnion_insert] + refine hC.union_mem (hs i (mem_insert_self i S)) ?_ + exact h (fun n hnS ↦ hs n (mem_insert_of_mem hnS)) + +lemma biInter_mem {ι : Type*} (hC : IsSetRing C) {s : ι → Set α} + (S : Finset ι) (hS : S.Nonempty) (hs : ∀ n ∈ S, s n ∈ C) : + ⋂ i ∈ S, s i ∈ C := by + classical + induction hS using Finset.Nonempty.cons_induction with + | singleton => simpa using hs + | cons i S hiS _ h => + simp_rw [← Finset.mem_coe, Finset.coe_cons, Set.biInter_insert] + simp only [cons_eq_insert, Finset.mem_insert, forall_eq_or_imp] at hs + refine hC.inter_mem hs.1 ?_ + exact h (fun n hnS ↦ hs.2 n hnS) + +lemma finsetSup_mem (hC : IsSetRing C) {ι : Type*} {s : ι → Set α} {t : Finset ι} + (hs : ∀ i ∈ t, s i ∈ C) : + t.sup s ∈ C := by + simpa using biUnion_mem hC _ hs + +lemma partialSups_mem {ι : Type*} [Preorder ι] [LocallyFiniteOrderBot ι] + (hC : IsSetRing C) {s : ι → Set α} (hs : ∀ n, s n ∈ C) (n : ι) : + partialSups s n ∈ C := by + simpa only [partialSups_apply, sup'_eq_sup] using hC.finsetSup_mem (fun i hi ↦ hs i) + +lemma disjointed_mem {ι : Type*} [Preorder ι] [LocallyFiniteOrderBot ι] + (hC : IsSetRing C) {s : ι → Set α} (hs : ∀ j, s j ∈ C) (i : ι) : + disjointed s i ∈ C := + disjointedRec (fun _ j ht ↦ hC.sdiff_mem ht <| hs j) (hs i) + +theorem iUnion_le_mem (hC : IsSetRing C) {s : ℕ → Set α} (hs : ∀ n, s n ∈ C) (n : ℕ) : + (⋃ i ≤ n, s i) ∈ C := by + induction n with + | zero => simp [hs 0] + | succ n hn => rw [biUnion_le_succ]; exact hC.union_mem hn (hs _) + +theorem iInter_le_mem (hC : IsSetRing C) {s : ℕ → Set α} (hs : ∀ n, s n ∈ C) (n : ℕ) : + (⋂ i ≤ n, s i) ∈ C := by + induction n with + | zero => simp [hs 0] + | succ n hn => rw [biInter_le_succ]; exact hC.inter_mem hn (hs _) + +theorem accumulate_mem (hC : IsSetRing C) {s : ℕ → Set α} (hs : ∀ i, s i ∈ C) (n : ℕ) : + accumulate s n ∈ C := by + induction n with + | zero => simp [hs 0] + | succ n hn => rw [accumulate_succ]; exact hC.union_mem hn (hs _) + +end IsSetRing + namespace IsSetSemiring lemma isPiSystem (hC : IsSetSemiring C) : IsPiSystem C := fun s hs t ht _ ↦ hC.inter_mem s hs t ht @@ -152,41 +225,29 @@ gives an arbitrary `Finset (Set α)` that satisfies the equality. We remove the empty set to ensure that `t ∉ hC.disjointOfDiff hs ht` even if `t = ∅`. -/ noncomputable def disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : Finset (Set α) := - (hC.sdiff_eq_sUnion' s hs t ht).choose \ {∅} + (hC.exists_finpartition_sdiff hs ht).choose.parts lemma empty_notMem_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : - ∅ ∉ hC.disjointOfDiff hs ht := by - simp only [disjointOfDiff, Finset.mem_sdiff, Finset.mem_singleton, - not_true, and_false, not_false_iff] + ∅ ∉ hC.disjointOfDiff hs ht := + Finpartition.bot_notMem _ lemma subset_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : - ↑(hC.disjointOfDiff hs ht) ⊆ C := by - simp only [disjointOfDiff, coe_sdiff, coe_singleton, sdiff_singleton_subset_iff] - exact (hC.sdiff_eq_sUnion' s hs t ht).choose_spec.1.trans (Set.subset_insert _ _) + ↑(hC.disjointOfDiff hs ht) ⊆ C := + (hC.exists_finpartition_sdiff hs ht).choose_spec lemma pairwiseDisjoint_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : - PairwiseDisjoint (hC.disjointOfDiff hs ht : Set (Set α)) id := by - simp only [disjointOfDiff, coe_sdiff, coe_singleton] - exact Set.PairwiseDisjoint.subset (hC.sdiff_eq_sUnion' s hs t ht).choose_spec.2.1 - sdiff_subset + PairwiseDisjoint (hC.disjointOfDiff hs ht : Set (Set α)) id := + Finpartition.supIndep _ |>.pairwiseDisjoint lemma sUnion_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : - ⋃₀ hC.disjointOfDiff hs ht = s \ t := by - rw [(hC.sdiff_eq_sUnion' s hs t ht).choose_spec.2.2] - simp only [disjointOfDiff, coe_sdiff, coe_singleton] - rw [sUnion_sdiff_singleton_empty] + ⋃₀ hC.disjointOfDiff hs ht = s \ t := + (sup_id_eq_sSup _).symm.trans (Finpartition.sup_parts _) lemma notMem_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) : t ∉ hC.disjointOfDiff hs ht := by intro hs_mem - suffices t ⊆ s \ t by - have h := @disjoint_sdiff_self_right _ t s _ - specialize h le_rfl this - simp only [Set.bot_eq_empty, subset_empty_iff] at h - refine hC.empty_notMem_disjointOfDiff hs ht ?_ - rwa [← h] - rw [← hC.sUnion_disjointOfDiff hs ht] - exact subset_sUnion_of_mem hs_mem + cases disjoint_sdiff_self_right.eq_bot_of_le (Finpartition.le _ hs_mem) + exact hC.empty_notMem_disjointOfDiff hs ht hs_mem lemma sUnion_insert_disjointOfDiff (hC : IsSetSemiring C) (hs : s ∈ C) (ht : t ∈ C) (hst : t ⊆ s) : @@ -214,73 +275,11 @@ section disjointOfDiffUnion variable {I : Finset (Set α)} -/-- In a semiring of sets `C`, for all set `s ∈ C` and finite set of sets `I ⊆ C`, there is a -finite set of sets in `C` whose union is `s \ ⋃₀ I`. -See `IsSetSemiring.disjointOfDiffUnion` for a definition that gives such a set. -/ -lemma exists_disjoint_finset_sdiff_eq (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : - ∃ J : Finset (Set α), ↑J ⊆ C ∧ PairwiseDisjoint (J : Set (Set α)) id ∧ - s \ ⋃₀ I = ⋃₀ J := by - induction I using Finset.induction with - | empty => - simp only [coe_empty, sUnion_empty, sdiff_empty] - refine ⟨{s}, singleton_subset_set_iff.mpr hs, ?_⟩ - simp only [coe_singleton, pairwiseDisjoint_singleton, sUnion_singleton, - and_self_iff] - | insert t I' _ h => ?_ - rw [coe_insert] at hI - have ht : t ∈ C := hI (Set.mem_insert _ _) - obtain ⟨J, h_ss, h_dis, h_eq⟩ := h ((Set.subset_insert _ _).trans hI) - let Ju : ∀ u ∈ C, Finset (Set α) := fun u hu ↦ hC.disjointOfDiff hu ht - have hJu_subset : ∀ (u) (hu : u ∈ C), ↑(Ju u hu) ⊆ C := by - intro u hu x hx - exact hC.subset_disjointOfDiff hu ht hx - have hJu_disj : ∀ (u) (hu : u ∈ C), (Ju u hu : Set (Set α)).PairwiseDisjoint id := fun u hu ↦ - hC.pairwiseDisjoint_disjointOfDiff hu ht - have hJu_sUnion : ∀ (u) (hu : u ∈ C), ⋃₀ (Ju u hu : Set (Set α)) = u \ t := - fun u hu ↦ hC.sUnion_disjointOfDiff hu ht - have hJu_disj' : ∀ (u) (hu : u ∈ C) (v) (hv : v ∈ C) (_h_dis : Disjoint u v), - Disjoint (⋃₀ (Ju u hu : Set (Set α))) (⋃₀ ↑(Ju v hv)) := by - intro u hu v hv huv_disj - rw [hJu_sUnion, hJu_sUnion] - exact disjoint_of_subset Set.sdiff_subset Set.sdiff_subset huv_disj - let J' : Finset (Set α) := Finset.biUnion (Finset.univ : Finset J) fun u ↦ Ju u (h_ss u.prop) - have hJ'_subset : ↑J' ⊆ C := by - intro u - simp only [J', univ_eq_attach, coe_biUnion, mem_coe, mem_attach, iUnion_true, - mem_iUnion, Finset.exists_coe, exists₂_imp] - intro v hv huvt - exact hJu_subset v (h_ss hv) huvt - refine ⟨J', hJ'_subset, ?_, ?_⟩ - · rw [Finset.coe_biUnion] - refine PairwiseDisjoint.biUnion ?_ ?_ - · simp only [univ_eq_attach, mem_coe, id, iSup_eq_iUnion] - simp_rw [PairwiseDisjoint, Set.Pairwise] - intro x _ y _ hxy - have hxy_disj : Disjoint (x : Set α) y := by - by_contra h_contra - refine hxy ?_ - refine Subtype.ext ?_ - exact h_dis.elim x.prop y.prop h_contra - convert! hJu_disj' (x : Set α) (h_ss x.prop) y (h_ss y.prop) hxy_disj - · rw [sUnion_eq_biUnion] - congr - · rw [sUnion_eq_biUnion] - congr - · exact fun u _ ↦ hJu_disj _ _ - · rw [coe_insert, sUnion_insert, Set.union_comm, ← Set.sdiff_sdiff, h_eq] - simp_rw [J', sUnion_eq_biUnion, Set.iUnion_sdiff] - simp only [mem_coe, Finset.mem_biUnion, Finset.mem_univ, - Finset.exists_coe, iUnion_exists, true_and] - rw [iUnion_comm] - refine iUnion_congr fun i ↦ ?_ - by_cases hi : i ∈ J - · simp only [hi, iUnion_true] - rw [← hJu_sUnion i (h_ss hi), sUnion_eq_biUnion] - simp only [mem_coe] - · simp only [hi, iUnion_of_empty, iUnion_empty] - -@[deprecated (since := "2026-06-03")] -alias exists_disjoint_finset_diff_eq := exists_disjoint_finset_sdiff_eq +private theorem exists_finpartition_sdiff_sUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : + ∃ P : Finpartition (s \ ⋃₀ I), ↑P.parts ⊆ C := by + rw [← hC.mem_supClosure_iff, ← sSup_eq_sUnion, ← sup_id_eq_sSup] + have hC' := hC.isSetRing_supClosure + exact hC'.sdiff_mem (subset_supClosure hs) <| hC'.finsetSup_mem <| hI.trans subset_supClosure /-- In a semiring of sets `C`, for all set `s ∈ C` and finite set of sets `I ⊆ C`, `disjointOfDiffUnion` is a finite set of sets in `C` such that @@ -289,34 +288,42 @@ alias exists_disjoint_finset_diff_eq := exists_disjoint_finset_sdiff_eq singleton. -/ noncomputable def disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : Finset (Set α) := - (hC.exists_disjoint_finset_sdiff_eq hs hI).choose \ {∅} + (hC.exists_finpartition_sdiff_sUnion hs hI).choose.parts lemma empty_notMem_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : - ∅ ∉ hC.disjointOfDiffUnion hs hI := by - simp only [disjointOfDiffUnion, Finset.mem_sdiff, Finset.mem_singleton, - not_true, and_false, not_false_iff] + ∅ ∉ hC.disjointOfDiffUnion hs hI := + Finpartition.bot_notMem _ lemma disjointOfDiffUnion_subset (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : - ↑(hC.disjointOfDiffUnion hs hI) ⊆ C := by - simp only [disjointOfDiffUnion, coe_sdiff, coe_singleton, sdiff_singleton_subset_iff] - exact (hC.exists_disjoint_finset_sdiff_eq hs hI).choose_spec.1.trans (Set.subset_insert _ _) + ↑(hC.disjointOfDiffUnion hs hI) ⊆ C := + (hC.exists_finpartition_sdiff_sUnion hs hI).choose_spec lemma pairwiseDisjoint_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) - (hI : ↑I ⊆ C) : PairwiseDisjoint (hC.disjointOfDiffUnion hs hI : Set (Set α)) id := by - simp only [disjointOfDiffUnion, coe_sdiff, coe_singleton] - exact Set.PairwiseDisjoint.subset - (hC.exists_disjoint_finset_sdiff_eq hs hI).choose_spec.2.1 sdiff_subset + (hI : ↑I ⊆ C) : PairwiseDisjoint (hC.disjointOfDiffUnion hs hI : Set (Set α)) id := + (Finpartition.supIndep _).pairwiseDisjoint lemma sdiff_sUnion_eq_sUnion_disjointOfDiffUnion (hC : IsSetSemiring C) (hs : s ∈ C) - (hI : ↑I ⊆ C) : s \ ⋃₀ I = ⋃₀ hC.disjointOfDiffUnion hs hI := by - rw [(hC.exists_disjoint_finset_sdiff_eq hs hI).choose_spec.2.2] - simp only [disjointOfDiffUnion, coe_sdiff, coe_singleton] - rw [sUnion_sdiff_singleton_empty] + (hI : ↑I ⊆ C) : s \ ⋃₀ I = ⋃₀ hC.disjointOfDiffUnion hs hI := + (Finpartition.sup_parts _).symm.trans (sup_id_eq_sSup _) @[deprecated (since := "2026-06-03")] alias diff_sUnion_eq_sUnion_disjointOfDiffUnion := sdiff_sUnion_eq_sUnion_disjointOfDiffUnion +/-- In a semiring of sets `C`, for all set `s ∈ C` and finite set of sets `I ⊆ C`, there is a +finite set of sets in `C` whose union is `s \ ⋃₀ I`. +See `IsSetSemiring.disjointOfDiffUnion` for a definition that gives such a set. -/ +lemma exists_disjoint_finset_sdiff_eq (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : + ∃ J : Finset (Set α), ↑J ⊆ C ∧ PairwiseDisjoint (J : Set (Set α)) id ∧ + s \ ⋃₀ I = ⋃₀ J := + ⟨hC.disjointOfDiffUnion hs hI, + hC.disjointOfDiffUnion_subset hs hI, + hC.pairwiseDisjoint_disjointOfDiffUnion hs hI, + hC.sdiff_sUnion_eq_sUnion_disjointOfDiffUnion hs hI⟩ + +@[deprecated (since := "2026-06-03")] +alias exists_disjoint_finset_diff_eq := exists_disjoint_finset_sdiff_eq + lemma sUnion_disjointOfDiffUnion_subset (hC : IsSetSemiring C) (hs : s ∈ C) (hI : ↑I ⊆ C) : ⋃₀ (hC.disjointOfDiffUnion hs hI : Set (Set α)) ⊆ s := by rw [← hC.sdiff_sUnion_eq_sUnion_disjointOfDiffUnion] @@ -383,123 +390,92 @@ variable {j : Set α} {J : Finset (Set α)} open MeasureTheory Order -theorem disjointOfUnion_props (hC : IsSetSemiring C) (h1 : ↑J ⊆ C) : - ∃ K : Set α → Finset (Set α), - PairwiseDisjoint J K - ∧ (∀ i ∈ J, ↑(K i) ⊆ C) - ∧ PairwiseDisjoint (⋃ x ∈ J, (K x : Set (Set α))) id - ∧ (∀ j ∈ J, ⋃₀ K j ⊆ j) - ∧ (∀ j ∈ J, ∅ ∉ K j) - ∧ ⋃₀ J = ⋃₀ (⋃ x ∈ J, (K x : Set (Set α))) := by - induction J using Finset.cons_induction with - | empty => simp - | cons s J hJ hind => - rw [cons_eq_insert, coe_insert, Set.insert_subset_iff] at h1 - obtain ⟨K, hK0, ⟨hK1, hK2, hK3, hK4, hK5⟩⟩ := hind h1.2 - let K1 : Set α → Finset (Set α) := fun (t : Set α) ↦ - if t = s then (hC.disjointOfDiffUnion h1.1 h1.2) else K t - have hK1s : K1 s = hC.disjointOfDiffUnion h1.1 h1.2 := by simp [K1] - have hK1_of_ne t (ht : t ≠ s) : K1 t = K t := by simp [K1, ht] - use K1 - simp only [cons_eq_insert, - mem_coe, Finset.mem_insert, sUnion_subset_iff, - forall_eq_or_imp, coe_insert, sUnion_insert] - -- two simplification rules for induction hypothesis - have ht1' : ∀ x ∈ J, K1 x = K x := fun x hx ↦ hK1_of_ne _ (fun h_eq ↦ hJ (h_eq ▸ hx)) - have ht2 : (⋃ x ∈ J, (K1 x : Set (Set α))) = ⋃ x ∈ J, ((K x : Set (Set α))) := by - apply iUnion₂_congr - intro x hx - exact_mod_cast hK1_of_ne _ (ne_of_mem_of_not_mem hx hJ) - simp only [hK1s] - refine ⟨?_, ⟨hC.disjointOfDiffUnion_subset h1.1 h1.2, ?_⟩, ?_, - ⟨hC.subset_of_mem_disjointOfDiffUnion h1.1 h1.2, ?_⟩, ?_, ?_⟩ - · apply Set.Pairwise.insert - · intro j hj i hi hij - rw [Function.onFun, ht1' j hj, ht1' i hi] - exact hK0 hj hi hij - · intro i hi _ - have h7 : Disjoint ↑(hC.disjointOfDiffUnion h1.1 h1.2) (K i : Set (Set α)) := by - refine disjoint_of_sSup_disjoint_of_le_of_le - (hC.subset_of_diffUnion_disjointOfDiffUnion h1.1 h1.2) ?_ - (@disjoint_sdiff_left _ (⋃₀ J) s) (Or.inl - (hC.empty_notMem_disjointOfDiffUnion h1.1 h1.2)) - apply sUnion_subset_iff.mp - exact (hK3 i hi).trans (subset_sUnion_of_mem hi) - have h8 : Function.onFun Disjoint K1 s i := by - refine Finset.disjoint_iff_inter_eq_empty.mpr ?_ - rw [ht1' i hi, hK1s] - rw [Set.disjoint_iff_inter_eq_empty] at h7 - exact_mod_cast h7 - exact ⟨h8, Disjoint.symm h8⟩ - · intro i hi - rw [ht1' i hi] - exact hK1 i hi - · simp only [iUnion_iUnion_eq_or_left] - refine pairwiseDisjoint_union.mpr ⟨?_, ?_, ?_⟩ - · rw [hK1s] - exact hC.pairwiseDisjoint_disjointOfDiffUnion h1.1 h1.2 - · simpa [ht2] - · simp only [mem_coe, mem_iUnion, exists_prop, ne_eq, id_eq, forall_exists_index, and_imp] - intro i hi j x hx h3 h4 - obtain ki : i ⊆ s \ ⋃₀ J := hC.subset_of_diffUnion_disjointOfDiffUnion h1.1 h1.2 _ - (hK1s ▸ hi) - obtain hx2 : j ⊆ x := subset_trans (subset_sUnion_of_mem (ht1' x hx ▸ h3)) (hK3 x hx) - obtain kj : j ⊆ ⋃₀ J := hx2.trans <| subset_sUnion_of_mem hx - exact disjoint_of_subset ki kj disjoint_sdiff_left - · intro a ha - simp_rw [hK1_of_ne _ (ne_of_mem_of_not_mem ha hJ)] - change ∀ t' ∈ (K a : Set (Set α)), t' ⊆ a - rw [← sUnion_subset_iff] - exact hK3 a ha - · refine ⟨hC.empty_notMem_disjointOfDiffUnion h1.1 h1.2, ?_⟩ - intro a ha - rw [ht1' a ha] - exact hK4 a ha - · simp only [iUnion_iUnion_eq_or_left, sUnion_union, ht2, K1] - simp_rw [apply_ite, hK5, - ← hC.sdiff_sUnion_eq_sUnion_disjointOfDiffUnion h1.1 h1.2, hK5] - simp only [↓reduceIte, sdiff_union_self] +private theorem exists_partition_disjointed (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (j : J) : + ∃ P : Finpartition (disjointed (fun i ↦ (J.equivFin.symm i : Set α)) (J.equivFin j)), + ↑P.parts ⊆ C := + hC.mem_supClosure_iff.mp <| + hC.isSetRing_supClosure.disjointed_mem (fun _ ↦ subset_supClosure (hJ (Subtype.coe_prop _))) _ /-- For some `hJ : J ⊆ C` and `j : Set α`, where `hC : IsSetSemiring C`, this is a `Finset (Set α)` such that `K j := hC.disjointOfUnion hJ` are disjoint and `⋃₀ K j ⊆ j`, for `j ∈ J`. Using these we write `⋃₀ J` as a disjoint union `⋃₀ J = ⋃₀ ⋃ x ∈ J, (K x)`. See `MeasureTheory.IsSetSemiring.disjointOfUnion_props`. -/ -noncomputable def disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (j : Set α) := - (hC.disjointOfUnion_props hJ).choose j +noncomputable def disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (j : Set α) : + Finset (Set α) := + if hj : j ∈ J then (hC.exists_partition_disjointed hJ ⟨j, hj⟩).choose.parts else ∅ + +private theorem disjointOfUnion_coe (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (j : J) : + hC.disjointOfUnion hJ j = (hC.exists_partition_disjointed hJ j).choose.parts := by + rw [disjointOfUnion, dif_pos j.2] lemma pairwiseDisjoint_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) : - PairwiseDisjoint J (hC.disjointOfUnion hJ) := - (Exists.choose_spec (hC.disjointOfUnion_props hJ)).1 + PairwiseDisjoint J (hC.disjointOfUnion hJ) := by + refine Pairwise.set_of_subtype _ _ fun j k hjk ↦ ?_ + simp_rw [Function.onFun, hC.disjointOfUnion_coe hJ, Finset.disjoint_iff_ne] + exact fun s hs t ht ↦ Disjoint.ne (Finpartition.ne_bot _ hs) <| + .mono (Finpartition.le _ hs) (Finpartition.le _ ht) <| + disjoint_disjointed _ <| J.equivFin.injective.ne hjk lemma disjointOfUnion_subset (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (hj : j ∈ J) : - (disjointOfUnion hC hJ j : Set (Set α)) ⊆ C := - (Exists.choose_spec (hC.disjointOfUnion_props hJ)).2.1 _ hj - -lemma pairwiseDisjoint_biUnion_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) : - PairwiseDisjoint (⋃ x ∈ J, (hC.disjointOfUnion hJ x : Set (Set α))) id := - (Exists.choose_spec (hC.disjointOfUnion_props hJ)).2.2.1 + (disjointOfUnion hC hJ j : Set (Set α)) ⊆ C := by + lift j to J using hj + rw [hC.disjointOfUnion_coe hJ] + exact (hC.exists_partition_disjointed hJ j).choose_spec lemma pairwiseDisjoint_disjointOfUnion_of_mem (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (hj : j ∈ J) : PairwiseDisjoint (hC.disjointOfUnion hJ j : Set (Set α)) id := by - apply PairwiseDisjoint.subset (hC.pairwiseDisjoint_biUnion_disjointOfUnion hJ) - exact subset_iUnion₂_of_subset j hj fun ⦃a⦄ a ↦ a + lift j to J using hj + rw [disjointOfUnion_coe, ← supIndep_iff_pairwiseDisjoint] + exact Finpartition.supIndep _ + +lemma pairwiseDisjoint_biUnion_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) : + PairwiseDisjoint (⋃ x ∈ J, (hC.disjointOfUnion hJ x : Set (Set α))) id := by + simp_rw [← SetLike.mem_coe] + refine Set.PairwiseDisjoint.biUnion + (Pairwise.set_of_subtype _ _ ?_) + (fun _ ↦ hC.pairwiseDisjoint_disjointOfUnion_of_mem hJ) + simp_rw [Function.onFun, disjointOfUnion_coe, SetLike.mem_coe, ← Finset.sup_eq_iSup, + Finpartition.sup_parts] + exact (disjoint_disjointed _).comp_of_injective J.equivFin.injective lemma disjointOfUnion_subset_of_mem (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (hj : j ∈ J) : - ⋃₀ hC.disjointOfUnion hJ j ⊆ j := - (Exists.choose_spec (hC.disjointOfUnion_props hJ)).2.2.2.1 j hj + ⋃₀ hC.disjointOfUnion hJ j ⊆ j := by + lift j to J using hj + grw [disjointOfUnion_coe, ← Finset.sup_id_set_eq_sUnion, Finpartition.sup_parts, + disjointed_subset, Equiv.symm_apply_apply] lemma subset_of_mem_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (hj : j ∈ J) {x : Set α} (hx : x ∈ (hC.disjointOfUnion hJ) j) : x ⊆ j := sUnion_subset_iff.mp (hC.disjointOfUnion_subset_of_mem hJ hj) x hx lemma empty_notMem_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (hj : j ∈ J) : - ∅ ∉ hC.disjointOfUnion hJ j := - (Exists.choose_spec (hC.disjointOfUnion_props hJ)).2.2.2.2.1 j hj + ∅ ∉ hC.disjointOfUnion hJ j := by + lift j to J using hj + rw [disjointOfUnion_coe] + exact Finpartition.bot_notMem _ lemma sUnion_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) : - ⋃₀ ⋃ x ∈ J, (hC.disjointOfUnion hJ x : Set (Set α)) = ⋃₀ J := - (Exists.choose_spec (hC.disjointOfUnion_props hJ)).2.2.2.2.2.symm + ⋃₀ ⋃ x ∈ J, (hC.disjointOfUnion hJ x : Set (Set α)) = ⋃₀ J := by + simp_rw [sUnion_iUnion, ← iSup_eq_iUnion, iSup_subtype', disjointOfUnion_coe, + ← Finset.sup_id_set_eq_sUnion, Finpartition.sup_parts, J.equivFin.surjective.iSup_comp, + iSup_disjointed, J.equivFin.symm.surjective.iSup_comp, iSup_subtype, Finset.sup_eq_iSup, id] + +theorem disjointOfUnion_props (hC : IsSetSemiring C) (h1 : ↑J ⊆ C) : + ∃ K : Set α → Finset (Set α), + PairwiseDisjoint J K + ∧ (∀ i ∈ J, ↑(K i) ⊆ C) + ∧ PairwiseDisjoint (⋃ x ∈ J, (K x : Set (Set α))) id + ∧ (∀ j ∈ J, ⋃₀ K j ⊆ j) + ∧ (∀ j ∈ J, ∅ ∉ K j) + ∧ ⋃₀ J = ⋃₀ (⋃ x ∈ J, (K x : Set (Set α))) := + ⟨hC.disjointOfUnion h1, + hC.pairwiseDisjoint_disjointOfUnion h1, + fun _ ↦ hC.disjointOfUnion_subset h1, + hC.pairwiseDisjoint_biUnion_disjointOfUnion h1, + fun _ ↦ hC.disjointOfUnion_subset_of_mem h1, + fun _ ↦ hC.empty_notMem_disjointOfUnion h1, + (hC.sUnion_disjointOfUnion h1).symm⟩ end disjointOfUnion @@ -535,77 +511,4 @@ protected lemma Ioc [LinearOrder α] [Nonempty α] : end IsSetSemiring -namespace IsSetRing - -lemma inter_mem (hC : IsSetRing C) (hs : s ∈ C) (ht : t ∈ C) : s ∩ t ∈ C := by - rw [← sdiff_sdiff_right_self]; exact hC.sdiff_mem hs (hC.sdiff_mem hs ht) - -lemma isSetSemiring (hC : IsSetRing C) : IsSetSemiring C where - empty_mem := hC.empty_mem - inter_mem := fun _ hs _ ht => hC.inter_mem hs ht - sdiff_eq_sUnion' := by - refine fun s hs t ht => ⟨{s \ t}, ?_, ?_, ?_⟩ - · simp only [coe_singleton, Set.singleton_subset_iff] - exact hC.sdiff_mem hs ht - · simp only [coe_singleton, pairwiseDisjoint_singleton] - · simp only [coe_singleton, sUnion_singleton] - -lemma biUnion_mem {ι : Type*} (hC : IsSetRing C) {s : ι → Set α} - (S : Finset ι) (hs : ∀ n ∈ S, s n ∈ C) : - ⋃ i ∈ S, s i ∈ C := by - classical - induction S using Finset.induction with - | empty => simp [hC.empty_mem] - | insert i S _ h => - simp_rw [← Finset.mem_coe, Finset.coe_insert, Set.biUnion_insert] - refine hC.union_mem (hs i (mem_insert_self i S)) ?_ - exact h (fun n hnS ↦ hs n (mem_insert_of_mem hnS)) - -lemma biInter_mem {ι : Type*} (hC : IsSetRing C) {s : ι → Set α} - (S : Finset ι) (hS : S.Nonempty) (hs : ∀ n ∈ S, s n ∈ C) : - ⋂ i ∈ S, s i ∈ C := by - classical - induction hS using Finset.Nonempty.cons_induction with - | singleton => simpa using hs - | cons i S hiS _ h => - simp_rw [← Finset.mem_coe, Finset.coe_cons, Set.biInter_insert] - simp only [cons_eq_insert, Finset.mem_insert, forall_eq_or_imp] at hs - refine hC.inter_mem hs.1 ?_ - exact h (fun n hnS ↦ hs.2 n hnS) - -lemma finsetSup_mem (hC : IsSetRing C) {ι : Type*} {s : ι → Set α} {t : Finset ι} - (hs : ∀ i ∈ t, s i ∈ C) : - t.sup s ∈ C := by - simpa using biUnion_mem hC _ hs - -lemma partialSups_mem {ι : Type*} [Preorder ι] [LocallyFiniteOrderBot ι] - (hC : IsSetRing C) {s : ι → Set α} (hs : ∀ n, s n ∈ C) (n : ι) : - partialSups s n ∈ C := by - simpa only [partialSups_apply, sup'_eq_sup] using hC.finsetSup_mem (fun i hi ↦ hs i) - -lemma disjointed_mem {ι : Type*} [Preorder ι] [LocallyFiniteOrderBot ι] - (hC : IsSetRing C) {s : ι → Set α} (hs : ∀ j, s j ∈ C) (i : ι) : - disjointed s i ∈ C := - disjointedRec (fun _ j ht ↦ hC.sdiff_mem ht <| hs j) (hs i) - -theorem iUnion_le_mem (hC : IsSetRing C) {s : ℕ → Set α} (hs : ∀ n, s n ∈ C) (n : ℕ) : - (⋃ i ≤ n, s i) ∈ C := by - induction n with - | zero => simp [hs 0] - | succ n hn => rw [biUnion_le_succ]; exact hC.union_mem hn (hs _) - -theorem iInter_le_mem (hC : IsSetRing C) {s : ℕ → Set α} (hs : ∀ n, s n ∈ C) (n : ℕ) : - (⋂ i ≤ n, s i) ∈ C := by - induction n with - | zero => simp [hs 0] - | succ n hn => rw [biInter_le_succ]; exact hC.inter_mem hn (hs _) - -theorem accumulate_mem (hC : IsSetRing C) {s : ℕ → Set α} (hs : ∀ i, s i ∈ C) (n : ℕ) : - accumulate s n ∈ C := by - induction n with - | zero => simp [hs 0] - | succ n hn => rw [accumulate_succ]; exact hC.union_mem hn (hs _) - -end IsSetRing - end MeasureTheory From cd580e54f1a6b46063824e80cec92f64692cbe78 Mon Sep 17 00:00:00 2001 From: qawbecrdtey <40463813+qawbecrdtey@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:14:54 +0000 Subject: [PATCH 0823/1300] chore(FieldTheory): cleanup imports (#40548) --- Mathlib/FieldTheory/AbelRuffini.lean | 2 -- Mathlib/FieldTheory/AbsoluteGaloisGroup.lean | 2 +- Mathlib/FieldTheory/AlgebraicClosure.lean | 1 - Mathlib/FieldTheory/AxGrothendieck.lean | 3 --- Mathlib/FieldTheory/CardinalEmb.lean | 4 ---- Mathlib/FieldTheory/Cardinality.lean | 3 +-- Mathlib/FieldTheory/Finite/Basic.lean | 3 --- Mathlib/FieldTheory/Finite/GaloisField.lean | 1 - Mathlib/FieldTheory/Finite/Polynomial.lean | 1 - Mathlib/FieldTheory/Finiteness.lean | 1 - Mathlib/FieldTheory/Fixed.lean | 1 - Mathlib/FieldTheory/Galois/Basic.lean | 1 - Mathlib/FieldTheory/Galois/Infinite.lean | 1 + Mathlib/FieldTheory/Galois/NormalBasis.lean | 3 +-- Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean | 2 +- Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean | 1 - Mathlib/FieldTheory/IsAlgClosed/Basic.lean | 4 ++-- Mathlib/FieldTheory/Isaacs.lean | 1 - Mathlib/FieldTheory/KummerExtension.lean | 1 - Mathlib/FieldTheory/KummerPolynomial.lean | 1 + Mathlib/FieldTheory/Laurent.lean | 1 - Mathlib/FieldTheory/Minpoly/Field.lean | 3 --- Mathlib/FieldTheory/Minpoly/IsConjRoot.lean | 3 --- Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean | 2 -- Mathlib/FieldTheory/Normal/Closure.lean | 4 +--- Mathlib/FieldTheory/Normal/Defs.lean | 1 - Mathlib/FieldTheory/Perfect.lean | 2 -- Mathlib/FieldTheory/PerfectClosure.lean | 1 - Mathlib/FieldTheory/PrimeField.lean | 1 - Mathlib/FieldTheory/PrimitiveElement.lean | 3 --- Mathlib/FieldTheory/PurelyInseparable/AdjoinPthRoots.lean | 2 +- Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean | 2 -- Mathlib/FieldTheory/RatFunc/AsPolynomial.lean | 4 ---- Mathlib/FieldTheory/RatFunc/Basic.lean | 1 - Mathlib/FieldTheory/RatFunc/Defs.lean | 1 - Mathlib/FieldTheory/RatFunc/Degree.lean | 3 --- Mathlib/FieldTheory/Separable.lean | 5 ----- Mathlib/FieldTheory/SeparableDegree.lean | 4 ---- Mathlib/FieldTheory/SeparablyGenerated.lean | 1 - Mathlib/FieldTheory/SplittingField/Construction.lean | 1 - 40 files changed, 10 insertions(+), 72 deletions(-) diff --git a/Mathlib/FieldTheory/AbelRuffini.lean b/Mathlib/FieldTheory/AbelRuffini.lean index b3f2131950000a..d3363e964bb3b0 100644 --- a/Mathlib/FieldTheory/AbelRuffini.lean +++ b/Mathlib/FieldTheory/AbelRuffini.lean @@ -7,8 +7,6 @@ module public import Mathlib.FieldTheory.AlgebraicClosure public import Mathlib.FieldTheory.PolynomialGaloisGroup -public import Mathlib.GroupTheory.Solvable -public import Mathlib.RingTheory.RootsOfUnity.Basic /-! # The Abel-Ruffini Theorem diff --git a/Mathlib/FieldTheory/AbsoluteGaloisGroup.lean b/Mathlib/FieldTheory/AbsoluteGaloisGroup.lean index 6d4d89c996e872..01a9de6d1489e5 100644 --- a/Mathlib/FieldTheory/AbsoluteGaloisGroup.lean +++ b/Mathlib/FieldTheory/AbsoluteGaloisGroup.lean @@ -5,8 +5,8 @@ Authors: María Inés de Frutos-Fernández -/ module -public import Mathlib.FieldTheory.KrullTopology public import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure +public import Mathlib.FieldTheory.KrullTopology public import Mathlib.Topology.Algebra.Group.TopologicalAbelianization /-! diff --git a/Mathlib/FieldTheory/AlgebraicClosure.lean b/Mathlib/FieldTheory/AlgebraicClosure.lean index d115030664b2ef..6bfa07f324596f 100644 --- a/Mathlib/FieldTheory/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/AlgebraicClosure.lean @@ -7,7 +7,6 @@ module public import Mathlib.FieldTheory.Normal.Closure public import Mathlib.FieldTheory.IsAlgClosed.Basic -public import Mathlib.FieldTheory.IntermediateField.Algebraic /-! # Relative Algebraic Closure diff --git a/Mathlib/FieldTheory/AxGrothendieck.lean b/Mathlib/FieldTheory/AxGrothendieck.lean index 3c5442821041e6..7b3af709f6d07f 100644 --- a/Mathlib/FieldTheory/AxGrothendieck.lean +++ b/Mathlib/FieldTheory/AxGrothendieck.lean @@ -5,11 +5,8 @@ Authors: Chris Hughes -/ module -public import Mathlib.RingTheory.Algebraic.Basic -public import Mathlib.Data.Fintype.Pigeonhole public import Mathlib.ModelTheory.Algebra.Field.IsAlgClosed public import Mathlib.ModelTheory.Algebra.Ring.Definability -public import Mathlib.RingTheory.Polynomial.Basic /-! # Ax-Grothendieck diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index 4df957138237b1..a7b569da89bbbd 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -5,14 +5,10 @@ Authors: Junyan Xu -/ module -public import Mathlib.FieldTheory.SeparableClosure public import Mathlib.FieldTheory.PurelyInseparable.Basic public import Mathlib.LinearAlgebra.FreeAlgebra -public import Mathlib.Order.Interval.Set.WithBotTop public import Mathlib.Order.DirectedInverseSystem -import Mathlib.SetTheory.Ordinal.Basic - /-! # Number of embeddings of an algebraic extension of infinite separable degree diff --git a/Mathlib/FieldTheory/Cardinality.lean b/Mathlib/FieldTheory/Cardinality.lean index 61407dfbda7bc7..4ddfd32cf070fd 100644 --- a/Mathlib/FieldTheory/Cardinality.lean +++ b/Mathlib/FieldTheory/Cardinality.lean @@ -6,8 +6,7 @@ Authors: Eric Rodriguez module public import Mathlib.Algebra.Field.TransferInstance -public import Mathlib.Algebra.Field.ULift -public import Mathlib.Algebra.MvPolynomial.Cardinal +public import Mathlib.Algebra.MonoidAlgebra.Cardinal public import Mathlib.Data.Rat.Encodable public import Mathlib.FieldTheory.Finite.GaloisField public import Mathlib.RingTheory.Localization.Cardinality diff --git a/Mathlib/FieldTheory/Finite/Basic.lean b/Mathlib/FieldTheory/Finite/Basic.lean index 15333b7467c568..b05c1f86b3d8c4 100644 --- a/Mathlib/FieldTheory/Finite/Basic.lean +++ b/Mathlib/FieldTheory/Finite/Basic.lean @@ -6,7 +6,6 @@ Authors: Chris Hughes, Joey van Langen, Casper Putz module public import Mathlib.Algebra.CharP.Algebra -public import Mathlib.Algebra.CharP.Reduced public import Mathlib.Algebra.Field.ZMod public import Mathlib.Data.Nat.Prime.Int public import Mathlib.Data.ZMod.ValMinAbs @@ -14,8 +13,6 @@ public import Mathlib.LinearAlgebra.FreeModule.Finite.Matrix public import Mathlib.FieldTheory.Finiteness public import Mathlib.FieldTheory.Galois.Notation public import Mathlib.FieldTheory.Perfect -public import Mathlib.FieldTheory.Separable -public import Mathlib.RingTheory.IntegralDomain /-! # Finite fields diff --git a/Mathlib/FieldTheory/Finite/GaloisField.lean b/Mathlib/FieldTheory/Finite/GaloisField.lean index 59fe36a193b68b..35b4a5b5a568cc 100644 --- a/Mathlib/FieldTheory/Finite/GaloisField.lean +++ b/Mathlib/FieldTheory/Finite/GaloisField.lean @@ -7,7 +7,6 @@ module public import Mathlib.Algebra.Algebra.ZMod public import Mathlib.FieldTheory.Finite.Basic -public import Mathlib.FieldTheory.Galois.Basic public import Mathlib.RingTheory.Norm.Transitivity /-! diff --git a/Mathlib/FieldTheory/Finite/Polynomial.lean b/Mathlib/FieldTheory/Finite/Polynomial.lean index 79ff199c044ab2..c8845066d92b89 100644 --- a/Mathlib/FieldTheory/Finite/Polynomial.lean +++ b/Mathlib/FieldTheory/Finite/Polynomial.lean @@ -7,7 +7,6 @@ module public import Mathlib.Algebra.MvPolynomial.Expand public import Mathlib.FieldTheory.Finite.Basic -public import Mathlib.LinearAlgebra.Dual.Lemmas public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas public import Mathlib.RingTheory.MvPolynomial.Basic diff --git a/Mathlib/FieldTheory/Finiteness.lean b/Mathlib/FieldTheory/Finiteness.lean index c983d99a32b14e..36b3c6da7f7100 100644 --- a/Mathlib/FieldTheory/Finiteness.lean +++ b/Mathlib/FieldTheory/Finiteness.lean @@ -6,7 +6,6 @@ Authors: Chris Hughes module public import Mathlib.LinearAlgebra.Basis.VectorSpace -public import Mathlib.LinearAlgebra.Dimension.Constructions public import Mathlib.LinearAlgebra.Dimension.Finite /-! diff --git a/Mathlib/FieldTheory/Fixed.lean b/Mathlib/FieldTheory/Fixed.lean index 6b6f965fc8cd58..34cbc7826d00e4 100644 --- a/Mathlib/FieldTheory/Fixed.lean +++ b/Mathlib/FieldTheory/Fixed.lean @@ -11,7 +11,6 @@ public import Mathlib.Algebra.Ring.Action.Invariant public import Mathlib.FieldTheory.Finiteness public import Mathlib.FieldTheory.Normal.Defs public import Mathlib.FieldTheory.Separable -public import Mathlib.LinearAlgebra.Dual.Lemmas public import Mathlib.LinearAlgebra.FreeModule.Finite.Matrix public import Mathlib.RingTheory.Polynomial.Subring diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index 30d74790d3ccca..ca7c4c787c1f51 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -5,7 +5,6 @@ Authors: Thomas Browning, Patrick Lutz, Yongle Hu, Jingting Wang -/ module -public import Mathlib.FieldTheory.Fixed public import Mathlib.FieldTheory.Normal.Closure public import Mathlib.FieldTheory.PrimitiveElement public import Mathlib.FieldTheory.SeparableClosure diff --git a/Mathlib/FieldTheory/Galois/Infinite.lean b/Mathlib/FieldTheory/Galois/Infinite.lean index ad9b29753d6c4d..c8a3b0151ec980 100644 --- a/Mathlib/FieldTheory/Galois/Infinite.lean +++ b/Mathlib/FieldTheory/Galois/Infinite.lean @@ -8,6 +8,7 @@ module public import Mathlib.FieldTheory.KrullTopology public import Mathlib.FieldTheory.Galois.GaloisClosure public import Mathlib.Topology.Algebra.Group.ClosedSubgroup + /-! # The Fundamental Theorem of Infinite Galois Theory diff --git a/Mathlib/FieldTheory/Galois/NormalBasis.lean b/Mathlib/FieldTheory/Galois/NormalBasis.lean index f3cc9e760657d7..af8f0b3d109f29 100644 --- a/Mathlib/FieldTheory/Galois/NormalBasis.lean +++ b/Mathlib/FieldTheory/Galois/NormalBasis.lean @@ -7,11 +7,10 @@ module public import Mathlib.Algebra.Module.PID public import Mathlib.Algebra.MvPolynomial.Funext -public import Mathlib.Algebra.Polynomial.Module.AEval public import Mathlib.FieldTheory.Finite.Basic public import Mathlib.FieldTheory.Galois.Basic public import Mathlib.LinearAlgebra.AnnihilatingPolynomial -public import Mathlib.LinearAlgebra.Matrix.Nondegenerate +public import Mathlib.LinearAlgebra.Dual.Lemmas /-! # The normal basis theorem diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean index c9f959ad11ac34..e29255c21b390a 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean @@ -11,7 +11,7 @@ public import Mathlib.FieldTheory.Fixed public import Mathlib.FieldTheory.SplittingField.IsSplittingField public import Mathlib.RingTheory.Adjoin.Dimension public import Mathlib.RingTheory.TensorProduct.Finite - +public import Mathlib.SetTheory.Cardinal.Subfield /-! # Adjoining Elements to Fields diff --git a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index 345784f10d4501..b307f21014be3f 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -5,7 +5,6 @@ Authors: Kenny Lau -/ module -public import Mathlib.Algebra.CharP.Algebra public import Mathlib.Data.Multiset.Fintype public import Mathlib.FieldTheory.IsAlgClosed.Basic public import Mathlib.FieldTheory.SplittingField.Construction diff --git a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean index 346eb1c2ea3bde..81bd8bcddb2136 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean @@ -5,11 +5,11 @@ Authors: Kenny Lau -/ module +public import Mathlib.Algebra.Ring.Hom.InjSurj +public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas public import Mathlib.FieldTheory.Extension -public import Mathlib.FieldTheory.Normal.Defs public import Mathlib.FieldTheory.Perfect public import Mathlib.RingTheory.Localization.Integral -public import Mathlib.Algebra.Ring.Hom.InjSurj /-! # Algebraically Closed Field diff --git a/Mathlib/FieldTheory/Isaacs.lean b/Mathlib/FieldTheory/Isaacs.lean index fd073efbf3b5f5..759c2623759ad7 100644 --- a/Mathlib/FieldTheory/Isaacs.lean +++ b/Mathlib/FieldTheory/Isaacs.lean @@ -5,7 +5,6 @@ Authors: Junyan Xu -/ module -public import Mathlib.FieldTheory.Normal.Basic public import Mathlib.FieldTheory.PrimitiveElement public import Mathlib.GroupTheory.CosetCover diff --git a/Mathlib/FieldTheory/KummerExtension.lean b/Mathlib/FieldTheory/KummerExtension.lean index 24c9e2b4b77bf8..7ca6f1cd94d505 100644 --- a/Mathlib/FieldTheory/KummerExtension.lean +++ b/Mathlib/FieldTheory/KummerExtension.lean @@ -7,7 +7,6 @@ module public import Mathlib.RingTheory.RootsOfUnity.PrimitiveRoots public import Mathlib.FieldTheory.Galois.Basic -public import Mathlib.FieldTheory.KummerPolynomial public import Mathlib.LinearAlgebra.Eigenspace.Minpoly public import Mathlib.RingTheory.Norm.Basic diff --git a/Mathlib/FieldTheory/KummerPolynomial.lean b/Mathlib/FieldTheory/KummerPolynomial.lean index 50b58c87ef5562..bf11ed5b9a7fbd 100644 --- a/Mathlib/FieldTheory/KummerPolynomial.lean +++ b/Mathlib/FieldTheory/KummerPolynomial.lean @@ -7,6 +7,7 @@ module public import Mathlib.RingTheory.AdjoinRoot public import Mathlib.RingTheory.Norm.Defs + /-! # Irreducibility of X ^ p - a diff --git a/Mathlib/FieldTheory/Laurent.lean b/Mathlib/FieldTheory/Laurent.lean index 4bd5511b7ba995..e4086645764b8b 100644 --- a/Mathlib/FieldTheory/Laurent.lean +++ b/Mathlib/FieldTheory/Laurent.lean @@ -5,7 +5,6 @@ Authors: Yakov Pechersky -/ module -public import Mathlib.Algebra.Polynomial.Taylor public import Mathlib.FieldTheory.RatFunc.AsPolynomial /-! diff --git a/Mathlib/FieldTheory/Minpoly/Field.lean b/Mathlib/FieldTheory/Minpoly/Field.lean index 47a6d5a318f348..da148a2c393d57 100644 --- a/Mathlib/FieldTheory/Minpoly/Field.lean +++ b/Mathlib/FieldTheory/Minpoly/Field.lean @@ -5,11 +5,8 @@ Authors: Riccardo Brasca, Johan Commelin -/ module -public import Mathlib.Algebra.Polynomial.FieldDivision -public import Mathlib.Algebra.Polynomial.Lifts public import Mathlib.FieldTheory.Minpoly.Basic public import Mathlib.RingTheory.Algebraic.Integral -public import Mathlib.RingTheory.LocalRing.Basic /-! # Minimal polynomials on an algebra over a field diff --git a/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean b/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean index 2f800421e5c2c9..9cf746a71dd215 100644 --- a/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean +++ b/Mathlib/FieldTheory/Minpoly/IsConjRoot.lean @@ -6,9 +6,6 @@ Authors: Jiedong Jiang module public import Mathlib.FieldTheory.Extension -public import Mathlib.FieldTheory.IntermediateField.Adjoin.Basic -public import Mathlib.FieldTheory.Minpoly.Basic -public import Mathlib.FieldTheory.Normal.Defs /-! # Conjugate roots diff --git a/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean b/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean index 6a4a871ae1fac2..1e33ebb30378d6 100644 --- a/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean +++ b/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean @@ -5,8 +5,6 @@ Authors: Riccardo Brasca, Paul Lezeau, Junyan Xu -/ module -public import Mathlib.RingTheory.AdjoinRoot -public import Mathlib.FieldTheory.Minpoly.Field public import Mathlib.RingTheory.Polynomial.GaussLemma /-! diff --git a/Mathlib/FieldTheory/Normal/Closure.lean b/Mathlib/FieldTheory/Normal/Closure.lean index 741f14a8f38e3e..aa381251dc1429 100644 --- a/Mathlib/FieldTheory/Normal/Closure.lean +++ b/Mathlib/FieldTheory/Normal/Closure.lean @@ -5,10 +5,8 @@ Authors: Thomas Browning -/ module -public import Mathlib.RingTheory.SimpleRing.Basic public import Mathlib.FieldTheory.Normal.Basic -public import Mathlib.Order.Closure -public import Mathlib.LinearAlgebra.FreeModule.Finite.Matrix + /-! # Normal closures diff --git a/Mathlib/FieldTheory/Normal/Defs.lean b/Mathlib/FieldTheory/Normal/Defs.lean index 05d2b853dca37b..93e37bfca2d814 100644 --- a/Mathlib/FieldTheory/Normal/Defs.lean +++ b/Mathlib/FieldTheory/Normal/Defs.lean @@ -5,7 +5,6 @@ Authors: Kenny Lau, Thomas Browning, Patrick Lutz -/ module -public import Mathlib.Algebra.Polynomial.Splits public import Mathlib.FieldTheory.Galois.Notation public import Mathlib.FieldTheory.IntermediateField.Basic public import Mathlib.FieldTheory.Minpoly.Field diff --git a/Mathlib/FieldTheory/Perfect.lean b/Mathlib/FieldTheory/Perfect.lean index da06cd2ce3611e..fd3c51ea12a7c3 100644 --- a/Mathlib/FieldTheory/Perfect.lean +++ b/Mathlib/FieldTheory/Perfect.lean @@ -5,8 +5,6 @@ Authors: Oliver Nash -/ module -public import Mathlib.Algebra.CharP.Basic -public import Mathlib.Algebra.CharP.Reduced public import Mathlib.FieldTheory.KummerPolynomial public import Mathlib.FieldTheory.Separable diff --git a/Mathlib/FieldTheory/PerfectClosure.lean b/Mathlib/FieldTheory/PerfectClosure.lean index a8d1112e9e7599..6ead8e0ec713ac 100644 --- a/Mathlib/FieldTheory/PerfectClosure.lean +++ b/Mathlib/FieldTheory/PerfectClosure.lean @@ -5,7 +5,6 @@ Authors: Kenny Lau, Yury Kudryashov -/ module -public import Mathlib.Algebra.CharP.Lemmas public import Mathlib.FieldTheory.Perfect /-! diff --git a/Mathlib/FieldTheory/PrimeField.lean b/Mathlib/FieldTheory/PrimeField.lean index 54a807b5663263..35fcf4ee0f13f8 100644 --- a/Mathlib/FieldTheory/PrimeField.lean +++ b/Mathlib/FieldTheory/PrimeField.lean @@ -8,7 +8,6 @@ module public import Mathlib.Algebra.Algebra.Rat public import Mathlib.Algebra.Field.ZMod public import Mathlib.Algebra.CharP.Algebra -public import Mathlib.Tactic.NormNum /-! # Prime fields diff --git a/Mathlib/FieldTheory/PrimitiveElement.lean b/Mathlib/FieldTheory/PrimitiveElement.lean index 401ea67e9c9e43..33e9061877a55c 100644 --- a/Mathlib/FieldTheory/PrimitiveElement.lean +++ b/Mathlib/FieldTheory/PrimitiveElement.lean @@ -5,11 +5,8 @@ Authors: Thomas Browning, Patrick Lutz -/ module -public import Mathlib.Data.Fintype.Pigeonhole public import Mathlib.FieldTheory.IsAlgClosed.Basic public import Mathlib.FieldTheory.SplittingField.Construction -public import Mathlib.RingTheory.IntegralDomain -public import Mathlib.RingTheory.Polynomial.UniqueFactorization /-! # Primitive Element Theorem diff --git a/Mathlib/FieldTheory/PurelyInseparable/AdjoinPthRoots.lean b/Mathlib/FieldTheory/PurelyInseparable/AdjoinPthRoots.lean index 97536f0bd78357..34e7ba2d4f7ae3 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/AdjoinPthRoots.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/AdjoinPthRoots.lean @@ -6,7 +6,7 @@ Authors: Nailin Guan module -public import Mathlib.FieldTheory.PurelyInseparable.PerfectClosure +public import Mathlib.FieldTheory.PurelyInseparable.Basic /-! diff --git a/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean b/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean index 46234c6a9314fb..be8ed4e1305402 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean @@ -5,8 +5,6 @@ Authors: Jz Pan -/ module -public import Mathlib.Algebra.CharP.Lemmas -public import Mathlib.Algebra.CharP.IntermediateField public import Mathlib.FieldTheory.PurelyInseparable.Basic public import Mathlib.LinearAlgebra.Dimension.OrzechProperty diff --git a/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean b/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean index cbd35a8c1442d5..f04b850f0b4f61 100644 --- a/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean +++ b/Mathlib/FieldTheory/RatFunc/AsPolynomial.lean @@ -6,13 +6,9 @@ Authors: Anne Baanen, María Inés de Frutos-Fernández, Filippo A. E. Nuccio module public import Mathlib.FieldTheory.RatFunc.Basic -public import Mathlib.RingTheory.EuclideanDomain public import Mathlib.RingTheory.DedekindDomain.AdicValuation -public import Mathlib.RingTheory.Localization.FractionRing -public import Mathlib.RingTheory.Polynomial.Content import Mathlib.RingTheory.Valuation.IsTrivialOn - /-! # Generalities on the polynomial structure of rational functions diff --git a/Mathlib/FieldTheory/RatFunc/Basic.lean b/Mathlib/FieldTheory/RatFunc/Basic.lean index 942da14ed1066c..497cd79e485fc4 100644 --- a/Mathlib/FieldTheory/RatFunc/Basic.lean +++ b/Mathlib/FieldTheory/RatFunc/Basic.lean @@ -7,7 +7,6 @@ module public import Mathlib.Algebra.CharP.Algebra public import Mathlib.FieldTheory.RatFunc.Defs -public import Mathlib.RingTheory.Polynomial.Content public import Mathlib.RingTheory.Algebraic.Integral /-! diff --git a/Mathlib/FieldTheory/RatFunc/Defs.lean b/Mathlib/FieldTheory/RatFunc/Defs.lean index d154c36647a1c1..fd7a3f0ccebf1a 100644 --- a/Mathlib/FieldTheory/RatFunc/Defs.lean +++ b/Mathlib/FieldTheory/RatFunc/Defs.lean @@ -6,7 +6,6 @@ Authors: Anne Baanen module public import Mathlib.Algebra.Polynomial.Basic -public import Mathlib.Algebra.Ring.NonZeroDivisors public import Mathlib.RingTheory.Localization.FractionRing /-! diff --git a/Mathlib/FieldTheory/RatFunc/Degree.lean b/Mathlib/FieldTheory/RatFunc/Degree.lean index 1e6341be9df298..9218ee979a52ed 100644 --- a/Mathlib/FieldTheory/RatFunc/Degree.lean +++ b/Mathlib/FieldTheory/RatFunc/Degree.lean @@ -6,9 +6,6 @@ Authors: Anne Baanen module public import Mathlib.FieldTheory.RatFunc.AsPolynomial -public import Mathlib.RingTheory.EuclideanDomain -public import Mathlib.RingTheory.Localization.FractionRing -public import Mathlib.RingTheory.Polynomial.Content /-! # The degree of rational functions diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 8065b7de9d05a5..052ffff94300f2 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -5,14 +5,9 @@ Authors: Kenny Lau -/ module -public import Mathlib.Algebra.Polynomial.Expand -public import Mathlib.Algebra.Polynomial.Splits public import Mathlib.Algebra.Squarefree.Basic public import Mathlib.FieldTheory.IntermediateField.Basic -public import Mathlib.FieldTheory.Minpoly.Field -public import Mathlib.RingTheory.Polynomial.Content public import Mathlib.RingTheory.PowerBasis -public import Mathlib.Data.ENat.Lattice /-! diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index 96b438c8359acf..02ee4ca9cf1fd2 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -5,15 +5,11 @@ Authors: Jz Pan -/ module -public import Mathlib.FieldTheory.SplittingField.Construction public import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure -public import Mathlib.FieldTheory.Separable public import Mathlib.FieldTheory.Normal.Closure public import Mathlib.RingTheory.AlgebraicIndependent.Adjoin public import Mathlib.RingTheory.AlgebraicIndependent.TranscendenceBasis public import Mathlib.RingTheory.Polynomial.SeparableDegree -public import Mathlib.RingTheory.Polynomial.UniqueFactorization - /-! diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index 083cbcdcb9ea5a..50417b47d7b220 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -10,7 +10,6 @@ public import Mathlib.Algebra.MvPolynomial.Nilpotent public import Mathlib.Algebra.MvPolynomial.NoZeroDivisors public import Mathlib.Algebra.Order.Ring.Finset public import Mathlib.FieldTheory.SeparableClosure -public import Mathlib.RingTheory.AlgebraicIndependent.AlgebraicClosure public import Mathlib.RingTheory.Polynomial.GaussLemma /-! diff --git a/Mathlib/FieldTheory/SplittingField/Construction.lean b/Mathlib/FieldTheory/SplittingField/Construction.lean index 4afc0022f93020..ff8bd752efb1e1 100644 --- a/Mathlib/FieldTheory/SplittingField/Construction.lean +++ b/Mathlib/FieldTheory/SplittingField/Construction.lean @@ -7,7 +7,6 @@ module public import Mathlib.Algebra.CharP.Algebra public import Mathlib.FieldTheory.SplittingField.IsSplittingField -public import Mathlib.RingTheory.Algebraic.Basic /-! # Splitting fields From e89e724a4f5a943cd02eca82bf8c8bd613c9c10e Mon Sep 17 00:00:00 2001 From: "giuseppe.sorge" <10847456+giuseppesorge@users.noreply.github.com> Date: Thu, 16 Jul 2026 11:34:54 +0000 Subject: [PATCH 0824/1300] =?UTF-8?q?feat(Data/ZMod):=20add=20`Unique=20(Z?= =?UTF-8?q?Mod=202)=CB=A3`=20instance=20(#41742)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strengthen the existing `Subsingleton (ZMod 2)ˣ` instance to a `Unique (ZMod 2)ˣ` instance, resolving the in-source `todo`. The old `Subsingleton` instance is dropped since it derives from `Unique`. Co-authored-by: Giuseppe Sorge --- Mathlib/Data/ZMod/Basic.lean | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index a698c0f0b8cc3c..7781e58c6dcc44 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -937,8 +937,9 @@ lemma subsingleton_iff {n : ℕ} : Subsingleton (ZMod n) ↔ n = 1 := by lemma nontrivial_iff {n : ℕ} : Nontrivial (ZMod n) ↔ n ≠ 1 := by rw [← not_subsingleton_iff_nontrivial, subsingleton_iff] --- todo: this can be made a `Unique` instance. -instance instSubsingletonUnits : Subsingleton (ZMod 2)ˣ := ⟨by decide⟩ +instance : Unique (ZMod 2)ˣ where + default := 1 + uniq := by decide @[simp] theorem add_self_eq_zero_iff_eq_zero {n : ℕ} (hn : Odd n) {a : ZMod n} : From 72bb41197bc7651b2f859fba89394e686a48c809 Mon Sep 17 00:00:00 2001 From: Fawad Haider <153737+FawadHa1der@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:02:09 +0000 Subject: [PATCH 0825/1300] perf(LinearAlgebra/RootSystem/GeckConstruction/Semisimple): replace `aesop` proof with faster `ext; simp` (#41756) --- .../LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean index c076a6eb4574ff..7e5668445c8b87 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Semisimple.lean @@ -211,7 +211,8 @@ private lemma instIsIrreducible_aux₀ {U : LieSubmodule K H (b.support ⊕ ι replace hdx : x = diagonal d := by simpa using! hdx have this (d : b.support ⊕ ι → K) (μ : K) : (diagonal d).toLin' - μ • 1 = (diagonal (d - μ • 1)).toLin' := by - aesop (add simp Pi.single_apply) + ext i j + simp [Pi.single_apply, ite_sub_ite] simp [mem_genWeightSpaceOf, hdx, this, ← toLin'_pow, diagonal_pow] obtain ⟨i, hi⟩ : ∃ i, w (Sum.inr i) ≠ 0 := by obtain ⟨l, hl⟩ : ∃ l, χ (h' l) ≠ 0 := by From 74f793c809b9a275756bff2ea8f9647e684288a1 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:33:12 +0000 Subject: [PATCH 0826/1300] chore(AlgebraicGeometry/Sites): pin ModuleCat imports with `shake: keep` (#41806) The imports `Mathlib.Algebra.Category.ModuleCat.AB` and `Mathlib.Algebra.Category.ModuleCat.FilteredColimits` are used only by the `example` at the end of the file (which checks that the sheafification results apply to `ModuleCat R`). `example` declarations elaborate to a private `_example` that is not persisted as a usable constant, so `lake shake` never sees their instance references and removes both imports, after which the `example` fails with `failed to synthesize Abelian (Sheaf ... (ModuleCat R))`. This PR marks the two imports `-- shake: keep`. This was found while investigating the breakage in #40343. Prepared with Claude code. --- Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean b/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean index 20c0df38e30469..2dcc8faac8a73e 100644 --- a/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean +++ b/Mathlib/AlgebraicGeometry/Sites/AffineEtale.lean @@ -5,8 +5,9 @@ Authors: Christian Merten, Joël Riou -/ module -public import Mathlib.Algebra.Category.ModuleCat.AB -public import Mathlib.Algebra.Category.ModuleCat.FilteredColimits +-- these `ModuleCat` instances are only used by the `example` below, which `shake` cannot see +public import Mathlib.Algebra.Category.ModuleCat.AB -- shake: keep +public import Mathlib.Algebra.Category.ModuleCat.FilteredColimits -- shake: keep public import Mathlib.AlgebraicGeometry.Sites.Affine public import Mathlib.AlgebraicGeometry.Sites.Etale public import Mathlib.CategoryTheory.Abelian.GrothendieckAxioms.Sheaf From 044efe507e1f15fd4f30c9a74a2410fd1aaa6855 Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:42:05 +0000 Subject: [PATCH 0827/1300] feat(RingTheory/MvPowerSeries): partial derivatives of `MvPowerSeries` (#39626) Previously, we had formal derivatives for `PowerSeries` and `Polynomial` and formal partial derivatives for `MvPolynomial`, but no formal partial derivatives for `MvPowerSeries`. This PR adds them. Furthermore, `PowerSeries.derivative` is refactored to be defined in terms of `MvPowerSeries.pderiv`, which reduces code duplication (In particular, there is no need to define the bare function `PowerSeries.derivativeFun` anymore). Most proofs are direct generalizations from the univariate case. I only had to add a few missing API lemmas, which I am PR'ing separately below: - [x] depends on: #39623 - [x] depends on: #39624 - [x] depends on: #39625 --- Mathlib.lean | 1 + .../RingTheory/MvPowerSeries/Derivative.lean | 209 +++++++++++++++ .../RingTheory/PowerSeries/Derivative.lean | 247 ++++++++---------- Mathlib/RingTheory/PowerSeries/Exp.lean | 1 + 4 files changed, 326 insertions(+), 132 deletions(-) create mode 100644 Mathlib/RingTheory/MvPowerSeries/Derivative.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9264cd03c93cf3..8620a9f24a757d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6830,6 +6830,7 @@ public import Mathlib.RingTheory.MvPolynomial.Symmetric.NewtonIdentities public import Mathlib.RingTheory.MvPolynomial.Tower public import Mathlib.RingTheory.MvPolynomial.WeightedHomogeneous public import Mathlib.RingTheory.MvPowerSeries.Basic +public import Mathlib.RingTheory.MvPowerSeries.Derivative public import Mathlib.RingTheory.MvPowerSeries.Equiv public import Mathlib.RingTheory.MvPowerSeries.Evaluation public import Mathlib.RingTheory.MvPowerSeries.Expand diff --git a/Mathlib/RingTheory/MvPowerSeries/Derivative.lean b/Mathlib/RingTheory/MvPowerSeries/Derivative.lean new file mode 100644 index 00000000000000..2d60ca78c9e679 --- /dev/null +++ b/Mathlib/RingTheory/MvPowerSeries/Derivative.lean @@ -0,0 +1,209 @@ +/- +Copyright (c) 2026 Justus Springer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Justus Springer +-/ +module + +public import Mathlib.Algebra.MvPolynomial.PDeriv +public import Mathlib.RingTheory.MvPowerSeries.Inverse +public import Mathlib.RingTheory.MvPowerSeries.Trunc + +/-! +# Formal partial derivatives of multivariate power series + +This file defines `MvPowerSeries.pderiv R i`, the formal partial derivative of a multivariate +power series with respect to variable `i`, as a +`Derivation R (MvPowerSeries σ R) (MvPowerSeries σ R)`. + +See also `PowerSeries.derivative` for the univariate setting. + +## Main definitions + +- `MvPowerSeries.pderiv R i`: the formal partial derivative with respect to `i`, as a derivation. + +## Main results + +- `MvPowerSeries.coeff_pderiv`: coefficient formula + `coeff n (pderiv R i f) = coeff (n + single i 1) f * (n i + 1)`. +- `MvPowerSeries.pderiv_coe`: compatibility with `MvPolynomial.pderiv`. +- `MvPowerSeries.trunc_pderiv`: truncation commutes with partial differentiation. +- `MvPowerSeries.pderiv.ext`: a power series is determined by its constant term and its partial + derivatives. +- `MvPowerSeries.pderiv_pow`: power rule. +- `MvPowerSeries.pderiv_inv`, `MvPowerSeries.pderiv_inv'`: derivative of an inverse. + +-/ + +@[expose] public section + +namespace MvPowerSeries + +open MvPolynomial Finsupp + +variable {σ R : Type*} + +section Semiring + +variable [Semiring R] + +/-- The underlying function of the formal partial derivative with respect to variable `i`. +This is packaged as a derivation in `MvPowerSeries.pderiv`. -/ +noncomputable def pderivFun (i : σ) (f : MvPowerSeries σ R) : MvPowerSeries σ R := + fun d ↦ coeff (d + single i 1) f * (d i + 1) + +theorem coeff_pderivFun {i : σ} (f : MvPowerSeries σ R) (d : σ →₀ ℕ) : + coeff d (f.pderivFun i) = coeff (d + single i 1) f * (d i + 1) := by + rfl + +theorem pderivFun_add {i : σ} (f g : MvPowerSeries σ R) : + pderivFun i (f + g) = pderivFun i f + pderivFun i g := by + ext + rw [coeff_pderivFun, map_add, map_add, coeff_pderivFun, coeff_pderivFun, add_mul] + +theorem pderivFun_C {i : σ} (r : R) : pderivFun i (C r) = 0 := by + ext n + rw [coeff_pderivFun, coeff_add_single_C, zero_mul, (coeff n).map_zero] + +theorem pderivFun_one {i : σ} : pderivFun i (1 : MvPowerSeries σ R) = 0 := by + rw [← map_one C, pderivFun_C (1 : R)] + +end Semiring + +section CommSemiring + +variable [CommSemiring R] + +private theorem pderivFun_coe {i : σ} (f : MvPolynomial σ R) : + (f : MvPowerSeries σ R).pderivFun i = f.pderiv i := by + ext + rw [coeff_pderivFun, coeff_coe, coeff_coe, coeff_pderiv] + +private theorem trunc_pderivFun [DecidableEq σ] {i : σ} (f : MvPowerSeries σ R) (n : σ →₀ ℕ) : + trunc R n (pderivFun i f) = pderiv i (trunc R (n + single i 1) f) := by + ext + rw [coeff_trunc] + split_ifs with h + · rw [coeff_pderivFun, coeff_pderiv, coeff_trunc, if_pos (add_lt_add_left h _)] + · rw [coeff_pderiv, coeff_trunc, if_neg ((add_lt_add_iff_right _).not.mpr h), zero_mul] + +-- A special case of `pderivFun_mul`, used in its proof. +private theorem pderivFun_coe_mul_coe {i : σ} (f g : MvPolynomial σ R) : + pderivFun i (f * g : MvPowerSeries σ R) = f * pderiv i g + g * pderiv i f := by + rw [← coe_mul, pderivFun_coe, pderiv_mul, add_comm, mul_comm _ g, ← coe_mul, ← coe_mul, + MvPolynomial.coe_add] + +private theorem pderivFun_mul {i : σ} (f g : MvPowerSeries σ R) : + pderivFun i (f * g) = f • g.pderivFun i + g • f.pderivFun i := by + classical + ext n + have h₁ : n < n + single i 1 := lt_def.mpr ⟨self_le_add_right _ _, i, by simp⟩ + have h₂ : n + single i 1 < n + single i 1 + single i 1 := + lt_def.mpr ⟨self_le_add_right _ _, i, by simp⟩ + have h₃ : n < n + single i 1 + single i 1 := lt_trans h₁ h₂ + rw [coeff_pderivFun, map_add, ← coeff_trunc_mul_trunc_eq_coeff_mul _ _ _ h₂, smul_eq_mul, + smul_eq_mul, ← coeff_trunc_mul_trunc_eq_coeff_mul₂ _ _ g (f.pderivFun i) h₃ h₁, + ← coeff_trunc_mul_trunc_eq_coeff_mul₂ _ _ f (g.pderivFun i) h₃ h₁, trunc_pderivFun, + trunc_pderivFun, ← coeff_coe, ← coeff_coe, ← coeff_coe, ← map_add, coe_mul, coe_mul, coe_mul, + ← pderivFun_coe_mul_coe, coeff_pderivFun] + +private theorem pderivFun_smul {i : σ} (r : R) (f : MvPowerSeries σ R) : + pderivFun i (r • f) = r • pderivFun i f := by + rw [smul_eq_C_mul, smul_eq_C_mul, pderivFun_mul, pderivFun_C, smul_zero, add_zero, smul_eq_mul] + +variable (R) in +/-- The formal partial derivative of a multivariate formal power series with respect to +variable `i`, as an `R`-derivation on `MvPowerSeries σ R`. -/ +@[no_expose] +noncomputable def pderiv (i : σ) : Derivation R (MvPowerSeries σ R) (MvPowerSeries σ R) where + toFun := pderivFun i + map_add' := pderivFun_add + map_smul' := pderivFun_smul + map_one_eq_zero' := pderivFun_one + leibniz' := pderivFun_mul + +@[simp] theorem pderiv_C {i : σ} {r : R} : pderiv R i (C r) = 0 := pderivFun_C r + +theorem pderiv_one {i : σ} : pderiv R i 1 = 0 := pderiv_C + +theorem coeff_pderiv {i : σ} (f : MvPowerSeries σ R) (n : σ →₀ ℕ) : + coeff n (pderiv R i f) = coeff (n + single i 1) f * (n i + 1) := + coeff_pderivFun f n + +theorem pderiv_coe {i : σ} (f : MvPolynomial σ R) : + pderiv R i f = MvPolynomial.pderiv i f := pderivFun_coe f + +@[simp] +theorem pderiv_X_self {i : σ} : pderiv R i (X i) = 1 := by + classical + ext n + simp only [coeff_pderiv, coeff_X, boole_mul, add_eq_right, coeff_one] + split_ifs <;> simp_all + +@[simp] +theorem pderiv_X_of_ne {i j : σ} (h : j ≠ i) : pderiv R i (X j) = 0 := by + classical + ext n + simpa only [coeff_pderiv, coeff_X, boole_mul, coeff_zero] using + if_neg (ne_iff.mpr ⟨i, by grind [Finsupp.add_apply]⟩) + +theorem pderiv_X [DecidableEq σ] (i j : σ) : + pderiv R i (X j) = Pi.single (M := fun _ => MvPowerSeries σ R) i 1 j := by + by_cases h : i = j + · subst h; simp only [pderiv_X_self, Pi.single_eq_same] + · grind [pderiv_X_of_ne] + +theorem trunc_pderiv [DecidableEq σ] {i : σ} (f : MvPowerSeries σ R) (n : σ →₀ ℕ) : + trunc R n (pderiv R i f) = MvPolynomial.pderiv i (trunc R (n + single i 1) f) := + trunc_pderivFun .. + +/-- The partial derivative of `g^n` equals `n * g^(n-1) * g'`. -/ +theorem pderiv_pow {i : σ} (g : MvPowerSeries σ R) (n : ℕ) : + pderiv R i (g ^ n) = n * g ^ (n - 1) * pderiv R i g := by + rw [Derivation.leibniz_pow, smul_eq_mul, nsmul_eq_mul, mul_assoc] + +end CommSemiring + +/-- If `f` and `g` have the same constant term and all partial derivatives, then they are equal. + +The `CommRing` assumption is needed because the proof uses `smul_right_inj`, which requires +cancellation of addition in `R`; `IsAddTorsionFree` alone does not suffice. -/ +theorem pderiv.ext [CommRing R] [IsAddTorsionFree R] {f g : MvPowerSeries σ R} + (hD : ∀ i, pderiv R i f = pderiv R i g) (hc : constantCoeff f = constantCoeff g) : f = g := by + ext n + by_cases h : n = 0 + · rw [h, coeff_zero_eq_constantCoeff, hc] + obtain ⟨i, hi : n i ≠ 0⟩ := ne_iff.mp h + have : single i 1 ≤ n := fun j ↦ by + by_cases hj : j = i <;> grind [single_eq_same, single_eq_of_ne] + have e := congr(coeff (n - single i 1) $(hD i)) + rwa [coeff_pderiv, coeff_pderiv, tsub_add_cancel_of_le this, coe_tsub, Pi.sub_apply, + single_eq_same, Nat.cast_sub (Nat.one_le_iff_ne_zero.mpr hi), Nat.cast_one, sub_add_cancel, + mul_comm, ← nsmul_eq_mul, mul_comm, ← nsmul_eq_mul, smul_right_inj hi] at e + +@[simp] +theorem pderiv_inv {i : σ} [CommRing R] (f : (MvPowerSeries σ R)ˣ) : + pderiv R i ↑f⁻¹ = -(↑f⁻¹ : MvPowerSeries σ R) ^ 2 * pderiv R i f := + (pderiv R i).leibniz_of_mul_eq_one f.inv_mul + +@[simp] +theorem pderiv_invOf {i : σ} [CommRing R] (f : MvPowerSeries σ R) [Invertible f] : + pderiv R i ⅟f = -⅟f ^ 2 * pderiv R i f := + (pderiv R i).leibniz_invOf f + +/- +The following theorem is stated only in the case that `R` is a field. This is because +there is currently no instance of `Inv (MvPowerSeries σ R)` for more general base rings `R`. +-/ + +@[simp] +theorem pderiv_inv' {i : σ} [Field R] (f : MvPowerSeries σ R) : + pderiv R i f⁻¹ = -f⁻¹ ^ 2 * pderiv R i f := by + by_cases h : constantCoeff f = 0 + · suffices f⁻¹ = 0 by + rw [this, pow_two, zero_mul, neg_zero, zero_mul, map_zero] + rwa [MvPowerSeries.inv_eq_zero] + apply Derivation.leibniz_of_mul_eq_one + exact MvPowerSeries.inv_mul_cancel (h := h) + +end MvPowerSeries diff --git a/Mathlib/RingTheory/PowerSeries/Derivative.lean b/Mathlib/RingTheory/PowerSeries/Derivative.lean index a3abfe874de99a..c926fb57153ca6 100644 --- a/Mathlib/RingTheory/PowerSeries/Derivative.lean +++ b/Mathlib/RingTheory/PowerSeries/Derivative.lean @@ -6,25 +6,31 @@ Authors: Richard M. Hill, Ralf Stephan module public import Mathlib.Algebra.Polynomial.Derivation -public import Mathlib.RingTheory.Derivation.Basic -public import Mathlib.RingTheory.PowerSeries.Inverse +public import Mathlib.RingTheory.MvPowerSeries.Derivative public import Mathlib.RingTheory.PowerSeries.Substitution /-! -# Definitions +# Formal derivatives of univariate power series -In this file we define an operation `derivative` (formal differentiation) -on the ring of formal power series in one variable (over an arbitrary commutative semiring). +This file defines `PowerSeries.derivative`, the formal derivative of a univariate +power series, as a `Derivation R R⟦X⟧ R⟦X⟧`. -Under suitable assumptions, we prove that two power series are equal if their derivatives -are equal and their constant terms are equal. This will give us a simple tool for proving -power series identities. For example, one can easily prove the power series identity -$\exp ( \log (1+X)) = 1+X$ by differentiating twice. +See also `MvPowerSeries.pderiv` for the multivariate setting. -## Main Definition +## Main definitions -- `PowerSeries.derivative R : Derivation R R⟦X⟧ R⟦X⟧` the formal derivative operation. - This is abbreviated `d⁄dX R`. +- `PowerSeries.derivative`: the formal derivative, as a derivation. + +## Main results + +- `PowerSeries.coeff_derivative`: coefficient formula + `coeff n (d⁄dX R f) = coeff (n + 1) f * (n + 1)`. +- `PowerSeries.derivative_coe`: compatibility with `Polynomial.derivative`. +- `PowerSeries.trunc_derivative`: truncation commutes with differentiation. +- `PowerSeries.derivative.ext`: a power series is determined by its constant term and derivative. +- `PowerSeries.derivative_pow`: power rule. +- `PowerSeries.derivative_inv`, `PowerSeries.derivative_inv'`: derivative of an inverse. +- `PowerSeries.derivative_subst`: chain rule for power series substitution. -/ @[expose] public section @@ -33,168 +39,145 @@ namespace PowerSeries open Polynomial Derivation Nat -section CommutativeSemiring -variable {R} [CommSemiring R] - -/-- -The formal derivative of a power series in one variable. -This is defined here as a function, but will be packaged as a -derivation `derivative` on `R⟦X⟧`. --/ -noncomputable def derivativeFun (f : R⟦X⟧) : R⟦X⟧ := mk fun n ↦ coeff (n + 1) f * (n + 1) - -theorem coeff_derivativeFun (f : R⟦X⟧) (n : ℕ) : - coeff n f.derivativeFun = coeff (n + 1) f * (n + 1) := by - rw [derivativeFun, coeff_mk] - -theorem derivativeFun_coe (f : R[X]) : (f : R⟦X⟧).derivativeFun = derivative f := by - ext - rw [coeff_derivativeFun, coeff_coe, coeff_coe, coeff_derivative] - -theorem derivativeFun_add (f g : R⟦X⟧) : - derivativeFun (f + g) = derivativeFun f + derivativeFun g := by - ext - rw [coeff_derivativeFun, map_add, map_add, coeff_derivativeFun, - coeff_derivativeFun, add_mul] - -theorem derivativeFun_C (r : R) : derivativeFun (C r) = 0 := by - ext n - -- Note that `map_zero` didn't get picked up, apparently due to a missing `FunLike.coe` - rw [coeff_derivativeFun, coeff_succ_C, zero_mul, (coeff n).map_zero] - -theorem trunc_derivativeFun (f : R⟦X⟧) (n : ℕ) : - trunc n f.derivativeFun = derivative (trunc (n + 1) f) := by - ext d - rw [coeff_trunc] - split_ifs with h - · have : d + 1 < n + 1 := succ_lt_succ_iff.2 h - rw [coeff_derivativeFun, coeff_derivative, coeff_trunc, if_pos this] - · have : ¬d + 1 < n + 1 := by rwa [succ_lt_succ_iff] - rw [coeff_derivative, coeff_trunc, if_neg this, zero_mul] +variable {R : Type*} ---A special case of `derivativeFun_mul`, used in its proof. -private theorem derivativeFun_coe_mul_coe (f g : R[X]) : derivativeFun (f * g : R⟦X⟧) = - f * derivative g + g * derivative f := by - rw [← coe_mul, derivativeFun_coe, derivative_mul, - add_comm, mul_comm _ g, ← coe_mul, ← coe_mul, Polynomial.coe_add] - -/-- **Leibniz rule for formal power series**. -/ -theorem derivativeFun_mul (f g : R⟦X⟧) : - derivativeFun (f * g) = f • g.derivativeFun + g • f.derivativeFun := by - ext n - have h₁ : n < n + 1 := lt_succ_self n - have h₂ : n < n + 1 + 1 := Nat.lt_add_right _ h₁ - rw [coeff_derivativeFun, map_add, coeff_mul_eq_coeff_trunc_mul_trunc _ _ (lt_succ_self _), - smul_eq_mul, smul_eq_mul, coeff_mul_eq_coeff_trunc_mul_trunc₂ g f.derivativeFun h₂ h₁, - coeff_mul_eq_coeff_trunc_mul_trunc₂ f g.derivativeFun h₂ h₁, trunc_derivativeFun, - trunc_derivativeFun, ← map_add, ← derivativeFun_coe_mul_coe, coeff_derivativeFun] - -theorem derivativeFun_one : derivativeFun (1 : R⟦X⟧) = 0 := by - rw [← map_one C, derivativeFun_C (1 : R)] - -theorem derivativeFun_smul (r : R) (f : R⟦X⟧) : derivativeFun (r • f) = r • derivativeFun f := by - rw [smul_eq_C_mul, smul_eq_C_mul, derivativeFun_mul, derivativeFun_C, smul_zero, add_zero, - smul_eq_mul] +section CommutativeSemiring -variable (R) +variable [CommSemiring R] +variable (R) in /-- The formal derivative of a formal power series -/ -noncomputable def derivative : Derivation R R⟦X⟧ R⟦X⟧ where - toFun := derivativeFun - map_add' := derivativeFun_add - map_smul' := derivativeFun_smul - map_one_eq_zero' := derivativeFun_one - leibniz' := derivativeFun_mul +noncomputable def derivative : Derivation R R⟦X⟧ R⟦X⟧ := + MvPowerSeries.pderiv R () + /-- Abbreviation of `PowerSeries.derivative`, the formal derivative on `R⟦X⟧` -/ scoped notation "d⁄dX" => derivative -variable {R} +@[simp] theorem derivative_C {r : R} : d⁄dX R (C r) = 0 := MvPowerSeries.pderiv_C -@[simp] theorem derivative_C (r : R) : d⁄dX R (C r) = 0 := derivativeFun_C r +theorem derivative_one : d⁄dX R 1 = 0 := MvPowerSeries.pderiv_one theorem coeff_derivative (f : R⟦X⟧) (n : ℕ) : - coeff n (d⁄dX R f) = coeff (n + 1) f * (n + 1) := coeff_derivativeFun f n + coeff n (d⁄dX R f) = coeff (n + 1) f * (n + 1) := by + simp [coeff, derivative, MvPowerSeries.coeff_pderiv] -theorem derivative_coe (f : R[X]) : d⁄dX R f = Polynomial.derivative f := derivativeFun_coe f +theorem derivative_coe (f : R[X]) : d⁄dX R f = Polynomial.derivative f := by + ext + rw [coeff_derivative, coeff_coe, coeff_coe, Polynomial.coeff_derivative] -@[simp] theorem derivative_X : d⁄dX R (X : R⟦X⟧) = 1 := by - ext n; simp only [coeff_derivative, coeff_one, coeff_X, boole_mul, add_eq_right] - split_ifs <;> simp_all +@[simp] theorem derivative_X : d⁄dX R (X : R⟦X⟧) = 1 := + MvPowerSeries.pderiv_X_self +-- We can't use `MvPowerSeries.trunc_pderiv` in the following proof, +-- since `PowerSeries.trunc` is not defined in terms of `MvPowerSeries.trunc`. theorem trunc_derivative (f : R⟦X⟧) (n : ℕ) : - trunc n (d⁄dX R f) = Polynomial.derivative (trunc (n + 1) f) := - trunc_derivativeFun .. + trunc n (d⁄dX R f) = Polynomial.derivative (trunc (n + 1) f) := by + ext d + rw [coeff_trunc] + split_ifs with h + · have : d + 1 < n + 1 := succ_lt_succ_iff.2 h + rw [coeff_derivative, Polynomial.coeff_derivative, coeff_trunc, if_pos this] + · have : ¬d + 1 < n + 1 := by rwa [succ_lt_succ_iff] + rw [Polynomial.coeff_derivative, coeff_trunc, if_neg this, zero_mul] theorem trunc_derivative' (f : R⟦X⟧) (n : ℕ) : trunc (n - 1) (d⁄dX R f) = Polynomial.derivative (trunc n f) := by cases n <;> simp [trunc_derivative] -end CommutativeSemiring +/-- The derivative of `g^n` equals `n * g^(n-1) * g'`. -/ +theorem derivative_pow (g : R⟦X⟧) (n : ℕ) : + d⁄dX R (g ^ n) = n * g ^ (n - 1) * d⁄dX R g := + MvPowerSeries.pderiv_pow g n -/- In the next lemma, we use `smul_right_inj`, which requires not only `IsAddTorsionFree R`, but -also cancellation of addition in `R`. For this reason, the next lemma is stated in the case that `R` -is a `CommRing`. -/ +end CommutativeSemiring /-- If `f` and `g` have the same constant term and derivative, then they are equal. -/ -theorem derivative.ext {R} [CommRing R] [IsAddTorsionFree R] {f g} (hD : d⁄dX R f = d⁄dX R g) - (hc : constantCoeff f = constantCoeff g) : f = g := by - ext n - cases n with - | zero => - rw [coeff_zero_eq_constantCoeff, hc] - | succ n => - have equ : coeff n (d⁄dX R f) = coeff n (d⁄dX R g) := by rw [hD] - rwa [coeff_derivative, coeff_derivative, ← cast_succ, mul_comm, ← nsmul_eq_mul, - mul_comm, ← nsmul_eq_mul, smul_right_inj n.succ_ne_zero] at equ - -@[simp] theorem derivative_inv {R} [CommRing R] (f : R⟦X⟧ˣ) : - d⁄dX R ↑f⁻¹ = -(↑f⁻¹ : R⟦X⟧) ^ 2 * d⁄dX R f := by - apply Derivation.leibniz_of_mul_eq_one - simp - -@[simp] theorem derivative_invOf {R} [CommRing R] (f : R⟦X⟧) [Invertible f] : - d⁄dX R ⅟f = -⅟f ^ 2 * d⁄dX R f := by - rw [Derivation.leibniz_invOf, smul_eq_mul] +theorem derivative.ext [CommRing R] [IsAddTorsionFree R] {f g} (hD : d⁄dX R f = d⁄dX R g) + (hc : constantCoeff f = constantCoeff g) : f = g := + MvPowerSeries.pderiv.ext (fun _ => hD) hc + +@[simp] +theorem derivative_inv [CommRing R] (f : R⟦X⟧ˣ) : + d⁄dX R ↑f⁻¹ = -(↑f⁻¹ : R⟦X⟧) ^ 2 * d⁄dX R f := + MvPowerSeries.pderiv_inv f + +@[simp] +theorem derivative_invOf [CommRing R] (f : R⟦X⟧) [Invertible f] : + d⁄dX R ⅟f = -⅟f ^ 2 * d⁄dX R f := + MvPowerSeries.pderiv_invOf f /- The following theorem is stated only in the case that `R` is a field. This is because there is currently no instance of `Inv R⟦X⟧` for more general base rings `R`. -/ -@[simp] theorem derivative_inv' {R} [Field R] (f : R⟦X⟧) : d⁄dX R f⁻¹ = -f⁻¹ ^ 2 * d⁄dX R f := by - by_cases h : constantCoeff f = 0 - · suffices f⁻¹ = 0 by - rw [this, pow_two, zero_mul, neg_zero, zero_mul, map_zero] - rwa [MvPowerSeries.inv_eq_zero] - apply Derivation.leibniz_of_mul_eq_one - exact PowerSeries.inv_mul_cancel (h := h) -/-- The derivative of g^n equals n * g^(n-1) * g'. -/ -theorem derivative_pow (A : Type*) [CommSemiring A] (g : A⟦X⟧) (n : ℕ) : - d⁄dX A (g ^ n) = n * g ^ (n - 1) * d⁄dX A g := by - rw [Derivation.leibniz_pow, smul_eq_mul, nsmul_eq_mul, mul_assoc] - -variable (A : Type*) [CommRing A] +@[simp] theorem derivative_inv' [Field R] (f : R⟦X⟧) : d⁄dX R f⁻¹ = -f⁻¹ ^ 2 * d⁄dX R f := + MvPowerSeries.pderiv_inv' f /-- Chain rule for polynomials viewed as power series. Use `derivative_subst` instead. -/ -private theorem derivative_subst_coe (p : Polynomial A) {g : A⟦X⟧} (hg : HasSubst g) : - d⁄dX A ((p : A⟦X⟧).subst g) = (d⁄dX A (p : A⟦X⟧)).subst g * d⁄dX A g := by - simp [subst_coe hg, derivative_coe, Derivation.comp_aeval_eq (a := g) (derivative A) p, +private theorem derivative_subst_coe [CommRing R] (p : Polynomial R) {g : R⟦X⟧} (hg : HasSubst g) : + d⁄dX R ((p : R⟦X⟧).subst g) = (d⁄dX R (p : R⟦X⟧)).subst g * d⁄dX R g := by + simp [subst_coe hg, derivative_coe, Derivation.comp_aeval_eq (a := g) (derivative R) p, smul_eq_mul] -theorem derivative_subst {f g : A⟦X⟧} (hg : HasSubst g) : - d⁄dX A (f.subst g) = (d⁄dX A f).subst g * d⁄dX A g := by +theorem derivative_subst [CommRing R] {f g : R⟦X⟧} (hg : HasSubst g) : + d⁄dX R (f.subst g) = (d⁄dX R f).subst g * d⁄dX R g := by ext n obtain ⟨m, hm⟩ := (hg.eventually_coeff_pow_eq_zero (n + 1)).exists_forall_of_atTop - have : coeff (n + 1) (f.subst g) = coeff (n + 1) ((↑(trunc (m + 1) f) : A⟦X⟧).subst g) := by + have : coeff (n + 1) (f.subst g) = coeff (n + 1) ((↑(trunc (m + 1) f) : R⟦X⟧).subst g) := by rw [coeff_subst' hg, coeff_subst' hg] refine finsum_congr fun d ↦ ?_ obtain hd | hd := lt_or_ge d m · rw [coeff_coe_trunc_of_lt (by lia)] · simp [coeff_trunc, hd, hm] - rw [coeff_derivative, this, ← coeff_derivative, derivative_subst_coe A _ hg, coeff_mul, coeff_mul] + rw [coeff_derivative, this, ← coeff_derivative, derivative_subst_coe _ hg, coeff_mul, coeff_mul] refine Finset.sum_congr rfl fun ⟨i, j⟩ hij ↦ ?_ congr 1 simp only [coeff_subst' hg, coeff_derivative, coeff_coe, coeff_trunc] exact finsum_congr fun d ↦ by split_ifs <;> simp (disch := grind [Finset.mem_antidiagonal]) [hm] +section deprecated + +variable [CommSemiring R] + +/-- +The formal derivative of a power series in one variable. +This is defined here as a function, but will be packaged as a +derivation `derivative` on `R⟦X⟧`. +-/ +@[deprecated derivative (since := "2026-06-26")] +noncomputable def derivativeFun (f : R⟦X⟧) := (derivative R).toFun f + +set_option linter.deprecated false in +@[deprecated "Use Derivation.map_add" (since := "2026-06-26")] +theorem derivativeFun_add (f g : R⟦X⟧) : + derivativeFun (f + g) = derivativeFun f + derivativeFun g := + (derivative R).map_add f g + +set_option linter.deprecated false in +@[deprecated "Use Derivation.leibniz" (since := "2026-06-26")] +theorem derivativeFun_mul (f g : R⟦X⟧) : + derivativeFun (f * g) = f • g.derivativeFun + g • f.derivativeFun := + (derivative R).leibniz f g + +set_option linter.deprecated false in +@[deprecated "Use Derivation.map_one_eq_zero" (since := "2026-06-26")] +theorem derivativeFun_one : derivativeFun (1 : R⟦X⟧) = 0 := + (derivative R).map_one_eq_zero + +set_option linter.deprecated false in +@[deprecated "Use Derivation.map_smul" (since := "2026-06-26")] +theorem derivativeFun_smul (r : R) (f : R⟦X⟧) : derivativeFun (r • f) = r • derivativeFun f := + (derivative R).map_smul r f + +@[deprecated (since := "2026-06-26")] alias derivativeFun_C := derivative_C + +@[deprecated (since := "2026-06-26")] alias coeff_derivativeFun := coeff_derivative + +@[deprecated (since := "2026-06-26")] alias derivativeFun_coe := derivative_coe + +@[deprecated (since := "2026-06-26")] alias trunc_derivativeFun := trunc_derivative + +end deprecated + end PowerSeries diff --git a/Mathlib/RingTheory/PowerSeries/Exp.lean b/Mathlib/RingTheory/PowerSeries/Exp.lean index f884c6491322a4..6eecb8c6e834eb 100644 --- a/Mathlib/RingTheory/PowerSeries/Exp.lean +++ b/Mathlib/RingTheory/PowerSeries/Exp.lean @@ -8,6 +8,7 @@ module public import Mathlib.Algebra.Algebra.Rat public import Mathlib.Data.Nat.Cast.Field public import Mathlib.RingTheory.PowerSeries.Derivative +public import Mathlib.RingTheory.PowerSeries.Inverse /-! # Exponential Power Series From 15e888f098dc8d8844f935ca6a12bae4d4582bff Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:36:14 +0000 Subject: [PATCH 0828/1300] chore: update Mathlib dependencies 2026-07-16 (#41812) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 33929543be7acf..c1526339caacfe 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "c5d5b8fe6e5158def25cd28eb94e4141ad97c843", + "rev": "0498c7c070c143a3bf7379f4d99a2c63bb9d9715", "name": "LeanSearchClient", "manifestFile": "lake-manifest.json", "inputRev": "main", From 61f352ee7293f2412389f9c3c45da594a95141e8 Mon Sep 17 00:00:00 2001 From: Rida Hamadani Date: Thu, 16 Jul 2026 14:39:46 +0000 Subject: [PATCH 0829/1300] feat(SimpleGraph): taking or dropping from a cycle results in a path (#35296) --- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 07c8dbd584a538..c6aae21f0c7167 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -366,6 +366,19 @@ theorem IsCycle.isPath_dropLast {p : G.Walk u u} (h : p.IsCycle) : p.dropLast.Is theorem IsPath.dropLast (hp : p.IsPath) : p.dropLast.IsPath := hp.take _ +theorem IsCycle.isPath_drop {u n} {p : G.Walk u u} (h : p.IsCycle) (hn : 0 < n) : + (p.drop n).IsPath := by + replace h : (p.drop 1).IsPath := h.isPath_tail + rw [← Nat.add_sub_of_le hn, drop_add_eq] + simp [h.drop (n - 1)] + +theorem IsCycle.isPath_take {u n} {p : G.Walk u u} (h : p.IsCycle) (hn : n < p.length) : + (p.take n).IsPath := by + replace h : (p.take (p.length - 1)).IsPath := h.isPath_dropLast + suffices ((p.take (p.length - 1)).take n).IsPath by + rwa [take_take, isPath_copy, show min (p.length - 1) n = n by omega] at this + exact h.take n + /-- There exists a trail of maximal length in a non-empty graph on finite edges. -/ lemma exists_isTrail_forall_isTrail_length_le_length (G : SimpleGraph V) [N : Nonempty V] [Finite G.edgeSet] : From f2e1a51678a4bbf29d28ec5f2c148bf32d966c8b Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Thu, 16 Jul 2026 14:39:48 +0000 Subject: [PATCH 0830/1300] feat(LinearAlgebra/Contraction): bijectivity of `dualTensorHom` + generalize to `CommSemiring` (#40297) migrated from #25284 --- Mathlib/Data/Finsupp/Defs.lean | 4 + Mathlib/LinearAlgebra/Contraction.lean | 148 ++++++++++++++++++--- Mathlib/LinearAlgebra/Pi.lean | 10 ++ Mathlib/LinearAlgebra/Trace.lean | 17 +-- Mathlib/RingTheory/Finiteness/Finsupp.lean | 38 +++++- 5 files changed, 184 insertions(+), 33 deletions(-) diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 6faed13e4264fd..23b6de17eee6a9 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -371,6 +371,10 @@ lemma mapRange_surjective (e : M → N) (he₀ : e 0 = 0) (he : Surjective e) : rw [← Set.range_eq_univ, range_mapRange, he.range_eq] simp +lemma mapRange_bijective (e : M → N) (he₀ : e 0 = 0) (he : Bijective e) : + Bijective (Finsupp.mapRange (α := α) e he₀) := + ⟨mapRange_injective e he₀ he.1, mapRange_surjective e he₀ he.2⟩ + end MapRange section Equiv diff --git a/Mathlib/LinearAlgebra/Contraction.lean b/Mathlib/LinearAlgebra/Contraction.lean index 8fd53145b7cf39..417f29cd82bd57 100644 --- a/Mathlib/LinearAlgebra/Contraction.lean +++ b/Mathlib/LinearAlgebra/Contraction.lean @@ -7,6 +7,7 @@ module public import Mathlib.LinearAlgebra.Dual.Lemmas public import Mathlib.LinearAlgebra.Matrix.ToLin +public import Mathlib.LinearAlgebra.TensorProduct.Finiteness /-! # Contractions @@ -39,7 +40,7 @@ section CommSemiring variable [CommSemiring R] variable [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P] [AddCommMonoid Q] variable [Module R M] [Module R N] [Module R P] [Module R Q] -variable [DecidableEq ι] [Fintype ι] (b : Basis ι R M) +variable (b : Basis ι R M) /-- The natural left-handed pairing between a module and its dual. -/ def contractLeft : Module.Dual R M ⊗[R] M →ₗ[R] R := @@ -69,6 +70,14 @@ theorem dualTensorHom_apply (f : Module.Dual R M) (m : M) (n : N) : dualTensorHom R M N (f ⊗ₜ n) m = f m • n := rfl +theorem dualTensorHom_comp_lTensor (f : N →ₗ[R] P) : + dualTensorHom R M P ∘ₗ f.lTensor _ = f.compRight R ∘ₗ dualTensorHom R M N := by + ext; simp + +theorem dualTensorHom_comp_rTensor_dualMap (f : M →ₗ[R] N) : + dualTensorHom R M P ∘ₗ f.dualMap.rTensor _ = f.lcomp R P ∘ₗ dualTensorHom R N P := by + ext; simp + @[simp] theorem transpose_dualTensorHom (f : Module.Dual R M) (m : M) : Dual.transpose (R := R) (dualTensorHom R M M (f ⊗ₜ m)) = @@ -124,6 +133,36 @@ theorem toMatrix_dualTensorHom {m : Type*} {n : Type*} [Fintype m] [Finite n] [D · rw [and_iff_not_or_not, Classical.not_not] at hij rcases hij with hij | hij <;> simp [LinearMap.toMatrix_apply, Finsupp.single_eq_pi_single, hij] +section + +variable (h : 1 ∈ (dualTensorHom R M M).range) +include h + +private theorem finite_projective_of_one_mem_range_dualTensorHom : + Module.Finite R M ∧ Projective R M := by + have ⟨t, eq⟩ := h + obtain ⟨s, rfl⟩ := TensorProduct.exists_finset t + let f : (s → R) →ₗ[R] M := Fintype.linearCombination R (·.1.2) + have : f ∘ₗ pi (·.1.1) = 1 := by + ext; simp [f, ← eq, Fintype.linearCombination_apply, ← s.sum_coe_sort] + exact ⟨.of_surjective f (surjective_of_comp_eq_id _ _ this), .of_split _ f this⟩ + +/-- If the identity linear map lies in the range of the canonical map `M* ⊗[R] M → Hom_R(M, M)`, +then `M` is a finite projective `R`-module (finite part). -/ +theorem Module.Finite.of_one_mem_range_dualTensorHom : Module.Finite R M := + (finite_projective_of_one_mem_range_dualTensorHom h).1 + +/-- If the identity linear map lies in the range of the canonical map `M* ⊗[R] M → Hom_R(M, M)`, +then `M` is a finite projective `R`-module (projective part). -/ +theorem Module.Projective.of_one_mem_range_dualTensorHom : Module.Projective R M := + (finite_projective_of_one_mem_range_dualTensorHom h).2 + +end + +section Fintype + +variable [DecidableEq ι] [Fintype ι] + attribute [-ext] AlgebraTensorModule.curry_injective in /-- If `M` is free, the natural linear map $M^* ⊗ N → Hom(M, N)$ is an equivalence. This function provides this equivalence in return for a basis of `M`. -/ @@ -142,10 +181,13 @@ noncomputable def dualTensorHomEquivOfBasis : Module.Dual R M ⊗[R] N ≃ₗ[R] Fintype.sum_apply, Function.comp_apply, Basis.coe_dualBasis, coe_comp, compr₂ₛₗ_apply, tmul_smul, smul_tmul', ← sum_tmul, Basis.sum_dual_apply_smul_coord]) +theorem coe_dualTensorHomEquivOfBasis : + ⇑(dualTensorHomEquivOfBasis (N := N) b) = dualTensorHom R M N := rfl + @[simp] theorem dualTensorHomEquivOfBasis_apply (x : Module.Dual R M ⊗[R] N) : - dualTensorHomEquivOfBasis b x = dualTensorHom R M N x := by - ext; rfl + dualTensorHomEquivOfBasis b x = dualTensorHom R M N x := + rfl @[simp] theorem dualTensorHomEquivOfBasis_toLinearMap : @@ -163,14 +205,88 @@ theorem dualTensorHomEquivOfBasis_symm_cancel_right (x : M →ₗ[R] N) : dualTensorHom R M N ((dualTensorHomEquivOfBasis b).symm x) = x := by rw [← dualTensorHomEquivOfBasis_apply b, LinearEquiv.apply_symm_apply] -variable (R M N P Q) -variable [Module.Free R M] [Module.Finite R M] - +end Fintype + +theorem dualTensorHom_bijective [Module.Finite R M] [Projective R M] : + Function.Bijective (dualTensorHom R M N) := by + obtain ⟨n, f, g, -, -, eq⟩ := Finite.exists_comp_eq_id_of_projective R M + constructor + · refine .of_comp (f := f.lcomp R N) ?_ + rw [← coe_comp, ← dualTensorHom_comp_rTensor_dualMap, coe_comp, + ← coe_dualTensorHomEquivOfBasis (Pi.basisFun ..)] + refine (EquivLike.injective _).comp (injective_of_comp_eq_id _ (rTensor _ g.dualMap) ?_) + simp [← rTensor_comp, dualMap_comp_dualMap g f, eq] + · refine .of_comp (g := g.dualMap.rTensor N) ?_ + rw [← coe_comp, dualTensorHom_comp_rTensor_dualMap, coe_comp, + ← coe_dualTensorHomEquivOfBasis (Pi.basisFun ..)] + refine (surjective_of_comp_eq_id (f.lcomp R N) _ ?_).comp (EquivLike.surjective _) + ext φ; exact congr(φ ($eq _)) + +theorem dualTensorHom_self_right : dualTensorHom R M R = TensorProduct.rid R (Dual R M) := by + ext; simp + +/- Subsumed by `dualTensorHom_bijective_of_finite_projective_right`. -/ +private theorem dualTensorHom_self_right_bijective : Function.Bijective (dualTensorHom R M R) := by + simpa only [dualTensorHom_self_right] using! LinearEquiv.bijective _ + +theorem dualTensorHom_finsupp [DecidableEq ι] : + dualTensorHom R M (ι →₀ N) = .finsuppLinearMap R ∘ₗ + Finsupp.mapRange.linearMap (dualTensorHom R M N) ∘ₗ (finsuppRight R R _ N ι).toLinearMap := by + ext; simp [Finsupp.single_apply]; aesop + +theorem dualTensorHom_finsupp_bijective (fin : Finite ι ∨ Module.Finite R M) + (h : Function.Bijective (dualTensorHom R M N)) : + Function.Bijective (dualTensorHom R M (ι →₀ N)) := by + classical rw [dualTensorHom_finsupp, coe_comp] + refine .comp ?_ ((Finsupp.mapRange_bijective _ (map_zero _) h).comp (LinearEquiv.bijective _)) + cases fin + · apply finsuppLinearMap_bijective_of_finite + · apply finsuppLinearMap_bijective_of_moduleFinite + +theorem dualTensorHom_bijective_of_comp_eq_id_right (f : N →ₗ[R] P) (g : P →ₗ[R] N) + (comp_eq_id : g ∘ₗ f = .id) (h : Function.Bijective (dualTensorHom R M P)) : + Function.Bijective (dualTensorHom R M N) where + left := .of_comp (f := f.compRight R) <| by + rw [← coe_comp, ← dualTensorHom_comp_lTensor] + refine h.1.comp (injective_of_comp_eq_id _ (g.lTensor _) ?_) + rw [← lTensor_comp, comp_eq_id, lTensor_id] + right := .of_comp (g := g.lTensor _) <| by + rw [← coe_comp, dualTensorHom_comp_lTensor, coe_comp] + refine (surjective_of_comp_eq_id (f.compRight R) _ ?_).comp h.2 + ext; exact congr($comp_eq_id _) + +theorem dualTensorHom_fun_bijective [Finite ι] (h : Function.Bijective (dualTensorHom R M N)) : + Function.Bijective (dualTensorHom R M (ι → N)) := + dualTensorHom_bijective_of_comp_eq_id_right + (Finsupp.linearEquivFunOnFinite R N ι).symm + (Finsupp.linearEquivFunOnFinite ..).toLinearMap (by ext; simp) + (dualTensorHom_finsupp_bijective (.inl ‹_›) h) + +theorem dualTensorHom_bijective_of_finite_projective_right [Module.Finite R N] [Projective R N] : + Function.Bijective (dualTensorHom R M N) := + have ⟨_n, f, g, _, _, eq⟩ := Finite.exists_comp_eq_id_of_projective R N + dualTensorHom_bijective_of_comp_eq_id_right g f eq <| + dualTensorHom_fun_bijective dualTensorHom_self_right_bijective + +theorem dualTensorHom_bijective_of_finite_left_projective_right [Module.Finite R M] + [Projective R N] : Function.Bijective (dualTensorHom R M N) := + have ⟨f, eq⟩ := projective_def'.mp ‹Projective R N› + dualTensorHom_bijective_of_comp_eq_id_right _ _ eq <| + dualTensorHom_finsupp_bijective (.inr ‹_›) dualTensorHom_self_right_bijective + +variable (R M N) in /-- If `M` is finite free, the natural map $M^* ⊗ N → Hom(M, N)$ is an equivalence. -/ @[simp] -noncomputable def dualTensorHomEquiv : Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N := - dualTensorHomEquivOfBasis (Module.Free.chooseBasis R M) +noncomputable def dualTensorHomEquiv [Module.Finite R M] [Projective R M] : + Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N := + .ofBijective _ (dualTensorHom_bijective ..) + +theorem dualTensorHomEquiv_eq_dualTensorHomEquivOfBasis + (b : Basis ι R M) [DecidableEq ι] [Fintype ι] : + have := Module.Finite.of_basis b; have := Module.Free.of_basis b + dualTensorHomEquiv R M N = dualTensorHomEquivOfBasis b := by + ext; rfl end CommSemiring @@ -183,10 +299,11 @@ open TensorProduct open Module TensorProduct LinearMap section CommSemiring + variable [CommSemiring R] variable [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P] [AddCommMonoid Q] variable [Module R M] [Module R N] [Module R P] [Module R Q] -variable [Free R M] [Module.Finite R M] [Free R N] [Module.Finite R N] +variable [Projective R M] [Module.Finite R M] /-- When `M` is a finite free module, the map `lTensorHomToHomLTensor` is an equivalence. Note that `lTensorHomEquivHomLTensor` is not defined directly in terms of @@ -213,10 +330,7 @@ theorem lTensorHomEquivHomLTensor_toLinearMap : have h : Function.Surjective e.toLinearMap := e.surjective refine (cancel_right h).1 ?_ ext f q m - simp only [e, lTensorHomEquivHomLTensor, dualTensorHomEquiv, LinearEquiv.comp_coe, compr₂ₛₗ_apply, - mk_apply, LinearEquiv.coe_coe, LinearEquiv.trans_apply, congr_tmul, LinearEquiv.refl_apply, - dualTensorHomEquivOfBasis_apply, dualTensorHomEquivOfBasis_symm_cancel_left, leftComm_tmul, - dualTensorHom_apply, coe_comp, Function.comp_apply, lTensorHomToHomLTensor_apply, tmul_smul] + simp [e, lTensorHomEquivHomLTensor] attribute [-ext] AlgebraTensorModule.curry_injective in @[simp] @@ -226,11 +340,7 @@ theorem rTensorHomEquivHomRTensor_toLinearMap : have h : Function.Surjective e.toLinearMap := e.surjective refine (cancel_right h).1 ?_ ext f p q m - simp only [e, rTensorHomEquivHomRTensor, dualTensorHomEquiv, compr₂ₛₗ_apply, mk_apply, coe_comp, - LinearEquiv.coe_toLinearMap, Function.comp_apply, - dualTensorHomEquivOfBasis_apply, LinearEquiv.trans_apply, congr_tmul, - dualTensorHomEquivOfBasis_symm_cancel_left, LinearEquiv.refl_apply, assoc_tmul, - dualTensorHom_apply, rTensorHomToHomRTensor_apply, smul_tmul'] + simp [e, rTensorHomEquivHomRTensor, smul_tmul'] variable {R M N P Q} @@ -244,7 +354,7 @@ theorem rTensorHomEquivHomRTensor_apply (x : (M →ₗ[R] P) ⊗[R] Q) : rTensorHomEquivHomRTensor R M P Q x = rTensorHomToHomRTensor (.id R) M P Q x := by rw [← LinearEquiv.coe_toLinearMap, rTensorHomEquivHomRTensor_toLinearMap] -variable (R M N P Q) +variable (R M N P Q) [Projective R N] [Module.Finite R N] /-- When `M` and `N` are free `R` modules, the map `homTensorHomMap` is an equivalence. Note that `homTensorHomEquiv` is not defined directly in terms of `homTensorHomMap`, but the equivalence diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index b5c09907cb69d4..9c59ef302875bd 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -112,6 +112,16 @@ theorem pi_proj_comp (f : M₂ →ₗ[R] ∀ i, φ i) : pi (proj · ∘ₗ f) = theorem proj_surjective (i : ι) : Surjective (proj i : ((i : ι) → φ i) →ₗ[R] φ i) := surjective_eval i +/-- Homs to a pi module are canonically identified with a product of hom types, even linearly so. -/ +@[simps] def _root_.LinearEquiv.linearMapPi (S) [Semiring S] [(i : ι) → Module S (φ i)] + [∀ i, SMulCommClass R S (φ i)] : (Π i, M₂ →ₗ[R] φ i) ≃ₗ[S] M₂ →ₗ[R] Π i, φ i where + toFun := pi + map_add' _ _ := rfl + map_smul' _ _ := rfl + invFun f i := proj i ∘ₗ f + left_inv _ := rfl + right_inv _ := rfl + theorem iInf_ker_proj : (⨅ i, ker (proj i : ((i : ι) → φ i) →ₗ[R] φ i) : Submodule R ((i : ι) → φ i)) = ⊥ := bot_unique <| diff --git a/Mathlib/LinearAlgebra/Trace.lean b/Mathlib/LinearAlgebra/Trace.lean index e963d728cee9ab..6c4239c9efa6e6 100644 --- a/Mathlib/LinearAlgebra/Trace.lean +++ b/Mathlib/LinearAlgebra/Trace.lean @@ -181,8 +181,9 @@ theorem trace_eq_contract_apply (x : Module.Dual R M ⊗[R] M) : /-- When `M` is finite free, the trace of a linear map corresponds to the contraction pairing under the isomorphism `End(M) ≃ M* ⊗ M`. -/ theorem trace_eq_contract' : - LinearMap.trace R M = contractLeft R M ∘ₗ (dualTensorHomEquiv R M M).symm.toLinearMap := - trace_eq_contract_of_basis' (Module.Free.chooseBasis R M) + LinearMap.trace R M = contractLeft R M ∘ₗ (dualTensorHomEquiv R M M).symm.toLinearMap := by + rw [dualTensorHomEquiv_eq_dualTensorHomEquivOfBasis (Module.Free.chooseBasis R M)] + exact trace_eq_contract_of_basis' _ /-- The trace of the identity endomorphism is the dimension of the free module. -/ @[simp] @@ -210,17 +211,7 @@ theorem trace_prodMap : let e := (dualTensorHomEquiv R M M).prodCongr (dualTensorHomEquiv R N N) have h : Function.Surjective e.toLinearMap := e.surjective refine (cancel_right h).1 ?_ - ext - · simp only [dualTensorHomEquiv, LinearEquiv.coe_prodCongr, - dualTensorHomEquivOfBasis_toLinearMap, AlgebraTensorModule.curry_apply, - curry_apply, coe_comp, coe_restrictScalars, coe_inl, Function.comp_apply, prodMap_apply, - map_zero, prodMapLinear_apply, dualTensorHom_prodMap_zero, trace_eq_contract_apply, - contractLeft_apply, coe_fst, coprod_apply, id_coe, id_eq, add_zero, e] - · simp only [dualTensorHomEquiv, LinearEquiv.coe_prodCongr, - dualTensorHomEquivOfBasis_toLinearMap, AlgebraTensorModule.curry_apply, - curry_apply, coe_comp, coe_restrictScalars, coe_inr, Function.comp_apply, prodMap_apply, - map_zero, prodMapLinear_apply, zero_prodMap_dualTensorHom, trace_eq_contract_apply, - contractLeft_apply, coe_snd, coprod_apply, id_coe, id_eq, zero_add, e] + ext <;> simp [e] variable {R M N P} diff --git a/Mathlib/RingTheory/Finiteness/Finsupp.lean b/Mathlib/RingTheory/Finiteness/Finsupp.lean index 49ff8576b1177a..2082f82178c711 100644 --- a/Mathlib/RingTheory/Finiteness/Finsupp.lean +++ b/Mathlib/RingTheory/Finiteness/Finsupp.lean @@ -5,12 +5,13 @@ Authors: Johan Commelin -/ module +public import Mathlib.Algebra.Exact.Basic public import Mathlib.Algebra.FreeAbelianGroup.Finsupp public import Mathlib.Algebra.MonoidAlgebra.Module +public import Mathlib.LinearAlgebra.BilinearMap public import Mathlib.LinearAlgebra.Finsupp.LinearCombination public import Mathlib.LinearAlgebra.Quotient.Basic public import Mathlib.RingTheory.Finiteness.Basic -public import Mathlib.Algebra.Exact.Basic /-! # Finiteness of (sub)modules and finitely supported functions @@ -22,6 +23,41 @@ public section open Function (Surjective) open Finsupp +namespace LinearMap + +variable {R M N ι : Type*} (S : Type*) [Semiring R] [AddCommMonoid M] [AddCommMonoid N] +variable [Module R M] [Module R N] [Semiring S] [Module S N] [SMulCommClass R S N] + +/-- The linear map from `Hom(M,N)^(ι)` to `Hom(M,N^(ι))`. This is the `Finsupp` version of +the forward direction of `LinearEquiv.linearMapPi`. -/ +@[expose, simps!] noncomputable def finsuppLinearMap : (ι →₀ M →ₗ[R] N) →ₗ[S] M →ₗ[R] ι →₀ N := + have := SMulCommClass.symm + LinearMap.flip + { toFun := (Finsupp.mapRange.linearMap <| flip id ·) + map_add' := fun _ _ ↦ by ext; simp + map_smul' := fun _ _ ↦ by ext; simp } + +variable (R M N ι) + +theorem finsuppLinearMap_injective : + Function.Injective (finsuppLinearMap S : (ι →₀ M →ₗ[R] N) → M →ₗ[R] ι →₀ N) := + fun _ _ eq ↦ by ext i m; exact congr($eq m i) + +theorem finsuppLinearMap_bijective_of_moduleFinite [Module.Finite R M] : + Function.Bijective (finsuppLinearMap S : (ι →₀ M →ₗ[R] N) → M →ₗ[R] ι →₀ N) := by + have ⟨s, span_s⟩ := Module.finite_def.mp ‹Module.Finite R M› + classical refine ⟨finsuppLinearMap_injective .., + fun x ↦ ⟨.onFinset (s.sup fun m ↦ (x m).support) (lapply · ∘ₗ x) fun i h ↦ ?_, ?_⟩⟩ + · contrapose! h; exact LinearMap.ext_on span_s (by simpa using! h) + · ext; rfl + +theorem finsuppLinearMap_bijective_of_finite [Finite ι] : + Function.Bijective (finsuppLinearMap S : (ι →₀ M →ₗ[R] N) → M →ₗ[R] ι →₀ N) where + left := finsuppLinearMap_injective .. + right x := ⟨equivFunOnFinite.symm fun i ↦ lapply i ∘ₗ x, by ext; simp⟩ + +end LinearMap + namespace Submodule variable {R M N P : Type*} [Ring R] [AddCommGroup M] [Module R M] [AddCommGroup N] From 9ff650a05edbad3ca4c9f97a49454fb83ef803fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 16 Jul 2026 14:39:50 +0000 Subject: [PATCH 0831/1300] chore(CategoryTheory/Sites): fix docstring (#41819) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See [#mathlib4 > `CategoryTheory.Sieve.ofObjects` @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.60CategoryTheory.2ESieve.2EofObjects.60/near/611065174) --- Mathlib/CategoryTheory/Sites/Sieves.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 35db11657d0a28..9ec716791f7799 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -863,7 +863,8 @@ abbrev ofTwoArrows {U V X : C} (i : U ⟶ X) (j : V ⟶ X) : Sieve X := Sieve.ofArrows (Y := pairFunction U V) (fun k ↦ WalkingPair.casesOn k i j) /-- The sieve of `X : C` that is generated by a family of objects `Y : I → C`: -it consists of morphisms to `X` which factor through at least one of the `Y i`. -/ +it consists of morphisms `p : Z ⟶ X` such that there exists a morphism `Z ⟶ Y i` +for some `i` (note that this does not depend on `p`, only on the object `Z`). -/ def ofObjects {I : Type*} (Y : I → C) (X : C) : Sieve X where arrows Z _ := ∃ (i : I), Nonempty (Z ⟶ Y i) downward_closed := by From 3d1773a1de56b88e2dc19e80110d95f4a2a73545 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:58:09 +0000 Subject: [PATCH 0832/1300] chore: fix many `nsmul`/`zsmul` diamonds (#41332) This PR fixes many diamonds around `nsmul`/`zsmul` fields. The common problematic pattern is that we first define the `AddCommMonoid`/`AddCommGroup` instance, and later define the `SMul` or `Algebra` instance. But we need to define the `smul` operation first, so that it can be used to define the `nsmul` and `zsmul` operations such that there is no diamond. These fixes are all ported from #38781 (the instance diamonds linter), and they were found after we got the `NSMul` and `ZSMul` type classes (#38036). --- Mathlib/Algebra/DirectSum/Basic.lean | 20 ++++--- .../Homology/HomotopyCategory/HomComplex.lean | 14 ++--- .../Calculus/FormalMultilinearSeries.lean | 10 +++- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 5 +- Mathlib/Analysis/Normed/Ring/WithAbs.lean | 2 +- .../LinearAlgebra/CliffordAlgebra/Basic.lean | 12 +++- Mathlib/LinearAlgebra/Quotient/Defs.lean | 56 +++++++++---------- .../LinearAlgebra/TensorAlgebra/Basic.lean | 20 ++++--- Mathlib/NumberTheory/Cyclotomic/Basic.lean | 5 +- .../RingTheory/Extension/Cotangent/Basic.lean | 41 +++----------- Mathlib/RingTheory/Ideal/Cotangent.lean | 6 +- Mathlib/RingTheory/Kaehler/Basic.lean | 12 ++-- .../Module/Spaces/UniformConvergenceCLM.lean | 13 +++-- .../Algebra/Module/Spaces/WeakBilin.lean | 12 ++-- .../Algebra/Module/Spaces/WeakDual.lean | 13 ++++- .../Topology/Algebra/UniformConvergence.lean | 50 +++++++++-------- .../Topology/VectorBundle/Constructions.lean | 5 ++ 17 files changed, 160 insertions(+), 136 deletions(-) diff --git a/Mathlib/Algebra/DirectSum/Basic.lean b/Mathlib/Algebra/DirectSum/Basic.lean index d9fa25f9b299b4..90cac152dc70cd 100644 --- a/Mathlib/Algebra/DirectSum/Basic.lean +++ b/Mathlib/Algebra/DirectSum/Basic.lean @@ -38,7 +38,6 @@ Note: `open DirectSum` will enable the notation `⨁ i, β i` for `DirectSum ι @[implicit_reducible] def DirectSum [∀ i, AddCommMonoid (β i)] : Type _ := Π₀ i, β i -deriving AddCommMonoid, Inhabited, DFunLike set_option backward.inferInstanceAs.wrap.data false in deriving instance CoeFun for DirectSum @@ -58,14 +57,21 @@ scoped[DirectSum] notation3 "⨁ "(...)", "r:(scoped f => DirectSum _ f) => r -- | `(⨁ ($x:ident) ($y:ident), $p) => `(DirectSum _ (fun $x ↦ fun $y ↦ $p)) -- end +namespace DirectSum + +variable {ι β} + +-- This instance exists to avoid nsmul and zsmul diamonds. +instance {R : Type u} [Semiring R] [∀ i, AddCommMonoid (β i)] [∀ i, Module R (β i)] : + SMul R (⨁ i, β i) := inferInstanceAs <| SMul R (Π₀ (i : ι), β i) + +deriving instance AddCommMonoid, Inhabited, DFunLike for DirectSum + instance [DecidableEq ι] [∀ i, AddCommMonoid (β i)] [∀ i, DecidableEq (β i)] : DecidableEq (DirectSum ι β) := inferInstanceAs <| DecidableEq (Π₀ i, β i) -namespace DirectSum - -variable {ι} - +variable (β) in /-- Coercion from a `DirectSum` to a pi type is an `AddMonoidHom`. -/ def coeFnAddMonoidHom [∀ i, AddCommMonoid (β i)] : (⨁ i, β i) →+ (Π i, β i) where toFun x := x @@ -83,8 +89,6 @@ variable [∀ i, AddCommGroup (β i)] instance : AddCommGroup (DirectSum ι β) := inferInstanceAs (AddCommGroup (Π₀ i, β i)) -variable {β} - @[simp] theorem sub_apply (g₁ g₂ : ⨁ i, β i) (i : ι) : (g₁ - g₂) i = g₁ i - g₂ i := rfl @@ -100,8 +104,6 @@ variable [∀ i, AddCommMonoid (β i)] theorem zero_apply (i : ι) : (0 : ⨁ i, β i) i = 0 := rfl -variable {β} - @[simp] theorem add_apply (g₁ g₂ : ⨁ i, β i) (i : ι) : (g₁ + g₂) i = g₁ i + g₂ i := rfl diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 781737c50ae548..ea74f0b4ea0d69 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -66,13 +66,12 @@ variable (F G) of a family of morphisms `F.X p ⟶ G.X q` whenever `p + n = q`, i.e. for all triplets in `HomComplex.Triplet n`. -/ def Cochain := ∀ (T : Triplet n), F.X T.p ⟶ G.X T.q -deriving AddCommGroup - -instance : Module R (Cochain F G n) := - inferInstanceAs <| Module R (∀ _, _) namespace Cochain +-- The `SMul` instance exists to avoid a zsmul diamond. +deriving instance SMul R, AddCommGroup, Module R for Cochain F G n + variable {F G n} /-- A practical constructor for cochains. -/ @@ -579,10 +578,6 @@ def cocycle : AddSubgroup (Cochain F G n) := /-- The type of `n`-cocycles, as a subtype of `Cochain F G n`. -/ def Cocycle : Type v := cocycle F G n -instance : AddCommGroup (Cocycle F G n) := by - dsimp only [Cocycle] - infer_instance - namespace Cocycle variable {F G} @@ -607,6 +602,9 @@ instance : SMul R (Cocycle F G n) where variable (F G n) +instance : AddCommGroup (Cocycle F G n) := + inferInstanceAs <| AddCommGroup (cocycle F G n) + @[simp] lemma coe_zero : (↑(0 : Cocycle F G n) : Cochain F G n) = 0 := by rfl diff --git a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean index 316f25b6c87d18..ddbfde34b6c570 100644 --- a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean +++ b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean @@ -52,14 +52,18 @@ def FormalMultilinearSeries (𝕜 : Type*) (E : Type*) (F : Type*) [Semiring ∀ n : ℕ, E [×n]→L[𝕜] F deriving Inhabited +-- This instance exists to avoid an nsmul diamond. +instance (𝕜') [Semiring 𝕜'] [Module 𝕜' F] [ContinuousConstSMul 𝕜' F] [SMulCommClass 𝕜 𝕜' F] : + SMul 𝕜' (FormalMultilinearSeries 𝕜 E F) where + smul k x n := k • x n + section AddCommMonoid /-- Copy `Pi.addCommMonoid`, ensuring the pointwise operations hold by defeq. -/ -instance : AddCommMonoid (FormalMultilinearSeries 𝕜 E F) where +instance : AddCommMonoid (FormalMultilinearSeries 𝕜 E F) := fast_instance% { __ := Pi.addCommMonoid zero _ := 0 - add x y n := x n + y n - nsmul k x n := k • x n + add x y n := x n + y n } end AddCommMonoid diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index 2cb4f541a38745..43d0bdd03c6568 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -343,10 +343,13 @@ the same ambient group, which permits lemma statements like `lp.monotone` (below @[nolint unusedArguments] def PreLp (E : α → Type*) [∀ i, NormedAddCommGroup (E i)] : Type _ := ∀ i, E i -deriving AddCommGroup namespace PreLp +-- The `SMul` instance exists to avoid a zsmul diamond. +variable [NormedRing 𝕜] [∀ i, Module 𝕜 (E i)] in +deriving instance SMul 𝕜, AddCommGroup for PreLp E + @[simp] lemma add_apply {x y : PreLp E} {i : α} : (x + y) i = x i + y i := rfl @[simp] lemma zero_apply {i : α} : (0 : PreLp E) i = 0 := rfl @[simp] lemma sub_apply {x y : PreLp E} {i : α} : (x - y) i = x i - y i := rfl diff --git a/Mathlib/Analysis/Normed/Ring/WithAbs.lean b/Mathlib/Analysis/Normed/Ring/WithAbs.lean index f91c84490faa61..5b717c5e8f9ecd 100644 --- a/Mathlib/Analysis/Normed/Ring/WithAbs.lean +++ b/Mathlib/Analysis/Normed/Ring/WithAbs.lean @@ -217,7 +217,7 @@ theorem smul_left_def [SMul R T] (x : WithAbs v) (t : T) : instance [SMul R T] [FaithfulSMul R T] : FaithfulSMul (WithAbs v) T where eq_of_smul_eq_smul h := ofAbs_injective v <| FaithfulSMul.eq_of_smul_eq_smul h -instance [SMul T R] : SMul T (WithAbs v) := (equiv v).smul T +instance [SMul T R] : SMul T (WithAbs v) := Equiv.smul T { toFun := ofAbs, invFun := toAbs v } theorem smul_right_def [SMul T R] (t : T) (x : WithAbs v) : t • x = toAbs v (t • x.ofAbs) := rfl diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean index 677367a9f9ed38..98fe5755ddda76 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean @@ -72,16 +72,26 @@ end CliffordAlgebra -/ @[wikidata Q674689] def CliffordAlgebra := CliffordAlgebra.ringCon Q |>.Quotient -deriving Inhabited, Ring, Algebra R +deriving Inhabited namespace CliffordAlgebra +-- This instance exists to avoid nsmul and zsmul diamonds. +instance {R A M} [CommSemiring R] [AddCommGroup M] [CommRing A] + [Algebra R A] [Module R M] [Module A M] (Q : QuadraticForm A M) + [IsScalarTower R A M] : SMul R (CliffordAlgebra Q) := + inferInstanceAs <| SMul R (RingCon.Quotient _) + +deriving instance Ring for CliffordAlgebra + instance (priority := 900) instAlgebra' {R A M} [CommSemiring R] [AddCommGroup M] [CommRing A] [Algebra R A] [Module R M] [Module A M] (Q : QuadraticForm A M) [IsScalarTower R A M] : Algebra R (CliffordAlgebra Q) := inferInstanceAs <| Algebra R (RingCon.Quotient _) +instance : Algebra R (CliffordAlgebra Q) := inferInstance + -- verify there are no diamonds -- but doesn't work at `reducible_and_instances` https://github.com/leanprover-community/mathlib4/issues/10906 example : (Semiring.toNatAlgebra : Algebra ℕ (CliffordAlgebra Q)) = instAlgebra' _ := rfl diff --git a/Mathlib/LinearAlgebra/Quotient/Defs.lean b/Mathlib/LinearAlgebra/Quotient/Defs.lean index 897914e7dfc82c..2c25d9a529dfd0 100644 --- a/Mathlib/LinearAlgebra/Quotient/Defs.lean +++ b/Mathlib/LinearAlgebra/Quotient/Defs.lean @@ -97,34 +97,6 @@ theorem mk_zero : mk 0 = (0 : M ⧸ p) := @[simp] theorem mk_eq_zero : (mk x : M ⧸ p) = 0 ↔ x ∈ p := by simpa using (Quotient.eq' p : mk x = 0 ↔ _) -instance addMonoid : AddMonoid (M ⧸ p) := - inferInstanceAs <| AddMonoid (M ⧸ p.toAddSubgroup) - -instance addCommMonoid : AddCommMonoid (M ⧸ p) := - inferInstanceAs <| AddCommMonoid (M ⧸ p.toAddSubgroup) - -instance addCommGroup : AddCommGroup (M ⧸ p) := - inferInstanceAs <| AddCommGroup (M ⧸ p.toAddSubgroup) - -@[simp] -theorem mk_add : (mk (x + y) : M ⧸ p) = mk x + mk y := - rfl - -@[simp] -theorem mk_neg : (mk (-x) : M ⧸ p) = -(mk x) := - rfl - -@[simp] -theorem mk_sub : (mk (x - y) : M ⧸ p) = mk x - mk y := - rfl - -variable {p} in -@[simp] -theorem mk_out (m : M ⧸ p) : Submodule.Quotient.mk (Quotient.out m) = m := - Quotient.out_eq m - -protected nonrec lemma «forall» {P : M ⧸ p → Prop} : (∀ a, P a) ↔ ∀ a, P (mk a) := Quotient.forall - section SMul variable {S : Type*} [SMul S R] [SMul S M] [IsScalarTower S R M] (P : Submodule R M) @@ -156,6 +128,34 @@ instance isCentralScalar [SMul Sᵐᵒᵖ R] [SMul Sᵐᵒᵖ M] [IsScalarTower end SMul +instance addMonoid : AddMonoid (M ⧸ p) := + inferInstanceAs <| AddMonoid (M ⧸ p.toAddSubgroup) + +instance addCommMonoid : AddCommMonoid (M ⧸ p) := + inferInstanceAs <| AddCommMonoid (M ⧸ p.toAddSubgroup) + +instance addCommGroup : AddCommGroup (M ⧸ p) := + inferInstanceAs <| AddCommGroup (M ⧸ p.toAddSubgroup) + +@[simp] +theorem mk_add : (mk (x + y) : M ⧸ p) = mk x + mk y := + rfl + +@[simp] +theorem mk_neg : (mk (-x) : M ⧸ p) = -(mk x) := + rfl + +@[simp] +theorem mk_sub : (mk (x - y) : M ⧸ p) = mk x - mk y := + rfl + +variable {p} in +@[simp] +theorem mk_out (m : M ⧸ p) : Submodule.Quotient.mk (Quotient.out m) = m := + Quotient.out_eq m + +protected nonrec lemma «forall» {P : M ⧸ p → Prop} : (∀ a, P a) ↔ ∀ a, P (mk a) := Quotient.forall + section Module variable {S : Type*} diff --git a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean index bb23779f58df01..57195a795e536d 100644 --- a/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorAlgebra/Basic.lean @@ -64,7 +64,17 @@ end TensorAlgebra /-- The tensor algebra of the module `M` over the commutative semiring `R`. -/ def TensorAlgebra := TensorAlgebra.ringCon R M |>.Quotient -deriving Inhabited, Semiring +deriving Inhabited + +namespace TensorAlgebra + +-- This instance exists to avoid an nsmul diamond. +instance {R A M} [CommSemiring R] [AddCommMonoid M] [CommSemiring A] + [Algebra R A] [Module A M] : + SMul R (TensorAlgebra A M) := + inferInstanceAs <| SMul R (RingCon.Quotient _) + +deriving instance Semiring for TensorAlgebra -- `IsScalarTower` is not needed, but the instance isn't really canonical without it. @[nolint unusedArguments] @@ -79,19 +89,15 @@ instance instAlgebra {R A M} [CommSemiring R] [AddCommMonoid M] [CommSemiring A] example : (Semiring.toNatAlgebra : Algebra ℕ (TensorAlgebra R M)) = instAlgebra := rfl instance {R S A M} [CommSemiring R] [CommSemiring S] [AddCommMonoid M] [CommSemiring A] - [Algebra R A] [Algebra S A] [Module R M] [Module S M] [Module A M] - [IsScalarTower R A M] [IsScalarTower S A M] : + [Algebra R A] [Algebra S A] [Module A M] : SMulCommClass R S (TensorAlgebra A M) := inferInstanceAs <| SMulCommClass R S (RingCon.Quotient _) instance {R S A M} [CommSemiring R] [CommSemiring S] [AddCommMonoid M] [CommSemiring A] - [SMul R S] [Algebra R A] [Algebra S A] [Module R M] [Module S M] [Module A M] - [IsScalarTower R A M] [IsScalarTower S A M] [IsScalarTower R S A] : + [SMul R S] [Algebra R A] [Algebra S A] [Module A M] [IsScalarTower R S A] : IsScalarTower R S (TensorAlgebra A M) := inferInstanceAs <| IsScalarTower R S (RingCon.Quotient _) -namespace TensorAlgebra - instance {S : Type*} [CommRing S] [Module S M] : Ring (TensorAlgebra S M) := inferInstanceAs <| Ring (RingCon.Quotient _) diff --git a/Mathlib/NumberTheory/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/Cyclotomic/Basic.lean index b6675ff2f46493..159456fa4f3115 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Basic.lean @@ -653,12 +653,13 @@ splitting field of `cyclotomic n K`. If `n` is nonzero in `K`, it has the instance `IsCyclotomicExtension {n} K (CyclotomicField n K)`. -/ def CyclotomicField : Type w := (cyclotomic n K).SplittingField -deriving Field, Inhabited +deriving Inhabited namespace CyclotomicField +-- The `SMul` instance exists to avoid a zsmul diamond. variable [Algebra A K] in -deriving instance Algebra A, IsScalarTower A K for CyclotomicField n K +deriving instance SMul A, Field, Algebra A, IsScalarTower A K for CyclotomicField n K instance algebra : Algebra K (CyclotomicField n K) := inferInstance diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean index 8662f8397efd44..fee707ff864d3d 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basic.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basic.lean @@ -37,7 +37,7 @@ apply them to infinitesimal smooth (or versal) extensions later. -/ -@[expose] public section +@[expose] public noncomputable section open KaehlerDifferential Module MvPolynomial TensorProduct @@ -58,7 +58,6 @@ This is isomorphic to `Sⁿ` with `n` being the number of variables of `P`. abbrev CotangentSpace : Type _ := S ⊗[P.Ring] Ω[P.Ring⁄R] /-- The cotangent complex given by a presentation `R[X] → S` (i.e. a closed embedding `S ↪ Aⁿ`). -/ -noncomputable def cotangentComplex : P.Cotangent →ₗ[S] P.CotangentSpace := letI f : P.Cotangent ≃ₗ[P.Ring] P.ker.Cotangent := { __ := AddEquiv.refl _, map_smul' := Cotangent.val_smul' } @@ -81,7 +80,6 @@ variable {A : Type*} [CommRing A] [Algebra S A] [Algebra P.Ring A] [IsScalarTowe variable (R S) in /-- This is (isomorphic to) the base change of the cotangent complex to `A`, but the domain and codomains of this are more manageable. -/ -noncomputable def _root_.KaehlerDifferential.cotangentComplexBaseChange (P A : Type*) [CommRing P] [CommRing A] [Algebra P S] [Algebra P A] [Algebra R P] [Algebra S A] [IsScalarTower P S A] : @@ -146,8 +144,7 @@ namespace CotangentSpace This is the map on the cotangent space associated to a map of presentation. The matrix associated to this map is the Jacobian matrix. See `CotangentSpace.repr_map`. -/ -protected noncomputable -def map (f : Hom P P') : P.CotangentSpace →ₗ[S] P'.CotangentSpace := by +protected def map (f : Hom P P') : P.CotangentSpace →ₗ[S] P'.CotangentSpace := by letI := ((algebraMap S S').comp (algebraMap P.Ring S)).toAlgebra haveI : IsScalarTower P.Ring S S' := IsScalarTower.of_algebraMap_eq' rfl letI := f.toAlgHom.toAlgebra @@ -238,7 +235,6 @@ If `f` and `g` are two maps `P → P'` between presentations, then the image of `f - g` is in the kernel of `P' → S`. -/ @[simps! apply_coe] -noncomputable def Hom.subToKer (f g : Hom P P') : P.Ring →ₗ[R] P'.ker := by refine ((f.toAlgHom.toLinearMap - g.toAlgHom.toLinearMap).codRestrict (P'.ker.restrictScalars R) ?_) @@ -253,7 +249,6 @@ If `f` and `g` are two maps `P → P'` between presentations, their difference induces a map `P.CotangentSpace →ₗ[S] P'.Cotangent` that makes two maps between the cotangent complexes homotopic. -/ -noncomputable def Hom.sub (f g : Hom P P') : P.CotangentSpace →ₗ[S] P'.Cotangent := by letI := ((algebraMap S S').comp (algebraMap P.Ring S)).toAlgebra haveI : IsScalarTower P.Ring S S' := IsScalarTower.of_algebraMap_eq' rfl @@ -327,7 +322,6 @@ lemma Cotangent.map_sub_map (f g : Hom P P') : variable (P) in /-- The projection map from the relative cotangent space to the module of differentials. -/ -noncomputable abbrev toKaehler : P.CotangentSpace →ₗ[S] Ω[S⁄R] := mapBaseChange _ _ _ lemma toKaehler_surjective : Function.Surjective P.toKaehler := @@ -342,34 +336,25 @@ The first homology of the (naive) cotangent complex of `S` over `R`, induced by a given presentation `0 → I → P → R → 0`, defined as the kernel of `I/I² → S ⊗[P] Ω[P⁄R]`. -/ -protected noncomputable -def H1Cotangent : Type _ := LinearMap.ker P.cotangentComplex +protected def H1Cotangent : Type _ := LinearMap.ker P.cotangentComplex -variable {P : Extension R S} - -noncomputable -instance : AddCommGroup P.H1Cotangent := by delta Extension.H1Cotangent; infer_instance - -set_option backward.isDefEq.respectTransparency false in -noncomputable -instance {R₀} [CommRing R₀] [Algebra R₀ S] [Module R₀ P.Cotangent] - [IsScalarTower R₀ S P.Cotangent] : Module R₀ P.H1Cotangent := by - delta Extension.H1Cotangent; infer_instance +-- The `SMul` instance exists to avoid a zsmul diamond. +variable {R₀} [CommRing R₀] [Algebra R₀ S] [Module R₀ P.Cotangent] + [IsScalarTower R₀ S P.Cotangent] in +deriving instance SMul R₀, AddCommGroup, Module R₀ for (P).H1Cotangent @[simp] lemma H1Cotangent.val_add (x y : P.H1Cotangent) : (x + y).1 = x.1 + y.1 := rfl @[simp] lemma H1Cotangent.val_zero : (0 : P.H1Cotangent).1 = 0 := rfl @[simp] lemma H1Cotangent.val_smul {R₀} [CommRing R₀] [Algebra R₀ S] [Module R₀ P.Cotangent] [IsScalarTower R₀ S P.Cotangent] (r : R₀) (x : P.H1Cotangent) : (r • x).1 = r • x.1 := rfl -set_option backward.isDefEq.respectTransparency false in -noncomputable instance {R₁ R₂} [CommRing R₁] [CommRing R₂] [Algebra R₁ R₂] [Algebra R₁ S] [Algebra R₂ S] [Module R₁ P.Cotangent] [IsScalarTower R₁ S P.Cotangent] [Module R₂ P.Cotangent] [IsScalarTower R₂ S P.Cotangent] [IsScalarTower R₁ R₂ P.Cotangent] : - IsScalarTower R₁ R₂ P.H1Cotangent := by - delta Extension.H1Cotangent; infer_instance + IsScalarTower R₁ R₂ P.H1Cotangent := + inferInstanceAs <| IsScalarTower R₁ R₂ (LinearMap.ker _) lemma subsingleton_h1Cotangent (P : Extension R S) : Subsingleton P.H1Cotangent ↔ Function.Injective P.cotangentComplex := by @@ -393,7 +378,6 @@ lemma exact_hCotangentι_cotangentComplex : Function.Exact h1Cotangentι P.cotan The induced map on the first homology of the (naive) cotangent complex. -/ @[simps!] -noncomputable def H1Cotangent.map (f : Hom P P') : P.H1Cotangent →ₗ[S] P'.H1Cotangent := by refine (Cotangent.map f).restrict (p := LinearMap.ker P.cotangentComplex) (q := (LinearMap.ker P'.cotangentComplex).restrictScalars S) fun x hx ↦ ?_ @@ -430,7 +414,6 @@ lemma H1Cotangent.map_comp_apply (f : Hom P P') (g : Hom P' P'') (x : P.H1Cotang /-- Maps `P₁ → P₂` and `P₂ → P₁` between extensions induce an isomorphism between `H¹(L_P₁)` and `H¹(L_P₂)`. -/ @[simps! apply] -noncomputable def H1Cotangent.equiv {P₁ P₂ : Extension R S} (f₁ : P₁.Hom P₂) (f₂ : P₂.Hom P₁) : P₁.H1Cotangent ≃ₗ[S] P₂.H1Cotangent where __ := map f₁ @@ -456,7 +439,6 @@ namespace Generators variable {ι : Type w} (P : Generators R S ι) /-- The canonical basis on the `CotangentSpace`. -/ -noncomputable def cotangentSpaceBasis : Basis ι S P.toExtension.CotangentSpace := (mvPolynomialBasis _ _).baseChange (R := P.Ring) _ @@ -484,7 +466,6 @@ instance (P : Generators R S ι) : Module.Free S P.toExtension.CotangentSpace := /-- Given generators `R[xᵢ] → S` and an injective map `σ → ι`, this is the composition `I/I² → ⊕ S dxᵢ → ⊕ S dxᵢ` where the second `i` only runs over `σ`. -/ -noncomputable def cotangentRestrict {σ : Type*} {u : σ → ι} (hu : Function.Injective u) : P.toExtension.Cotangent →ₗ[S] (σ →₀ S) := Finsupp.lcomapDomain u hu ∘ₗ P.cotangentSpaceBasis.repr.toLinearMap ∘ₗ @@ -565,7 +546,6 @@ variable {ι : Type w} {ι' : Type*} {P : Generators R S ι} open Extension.H1Cotangent in /-- `H¹(L_{S/R})` is independent of the presentation chosen. -/ @[simps! apply] -noncomputable def Generators.H1Cotangent.equiv (P : Generators R S ι) (P' : Generators R S ι') : P.toExtension.H1Cotangent ≃ₗ[S] P'.toExtension.H1Cotangent := Extension.H1Cotangent.equiv @@ -581,12 +561,10 @@ variable (R S S' T) abbrev H1Cotangent : Type _ := (Generators.self R S).toExtension.H1Cotangent /-- The induced map on the first homology of the (naive) cotangent complex of `S` over `R`. -/ -noncomputable def H1Cotangent.map : H1Cotangent R S' →ₗ[S'] H1Cotangent S T := Extension.H1Cotangent.map (Generators.defaultHom _ _).toExtensionHom /-- Isomorphic algebras induce isomorphic `H¹(L_{S/R})`. -/ -noncomputable def H1Cotangent.mapEquiv (e : S ≃ₐ[R] S') : H1Cotangent R S ≃ₗ[R] H1Cotangent R S' := -- we are constructing data, so we do not use `algebraize` @@ -612,7 +590,6 @@ def H1Cotangent.mapEquiv (e : S ≃ₐ[R] S') : variable {R S S' T} /-- `H¹(L_{S/R})` is independent of the presentation chosen. -/ -noncomputable abbrev Generators.equivH1Cotangent (P : Generators R S ι) : P.toExtension.H1Cotangent ≃ₗ[S] H1Cotangent R S := Generators.H1Cotangent.equiv _ _ diff --git a/Mathlib/RingTheory/Ideal/Cotangent.lean b/Mathlib/RingTheory/Ideal/Cotangent.lean index e504ed7d7706b7..1a2e1331fd47d6 100644 --- a/Mathlib/RingTheory/Ideal/Cotangent.lean +++ b/Mathlib/RingTheory/Ideal/Cotangent.lean @@ -39,9 +39,11 @@ variable [CommSemiring S'] [Algebra S' R] [Algebra S S'] [IsScalarTower S S' R] /-- `I ⧸ I ^ 2` as a quotient of `I`. -/ def Cotangent : Type _ := I ⧸ (I • ⊤ : Submodule R I) -deriving Inhabited, AddCommGroup, Module (R ⧸ I) +deriving Inhabited -deriving instance Module S, IsScalarTower S S', IsScalarTower R (R ⧸ I) for Cotangent I +-- The `SMul` instance exists to avoid nsmul and zsmul diamonds. +deriving instance SMul S, AddCommGroup, Module (R ⧸ I), Module S, IsScalarTower S S', + IsScalarTower R (R ⧸ I) for Cotangent I variable [IsNoetherian R I] in deriving instance IsNoetherian R for Cotangent I diff --git a/Mathlib/RingTheory/Kaehler/Basic.lean b/Mathlib/RingTheory/Kaehler/Basic.lean index f8e1406b7db292..828517e10d74a5 100644 --- a/Mathlib/RingTheory/Kaehler/Basic.lean +++ b/Mathlib/RingTheory/Kaehler/Basic.lean @@ -152,16 +152,16 @@ Note that the slash is `\textfractionsolidus`. -/ def KaehlerDifferential : Type v := (KaehlerDifferential.ideal R S).Cotangent -deriving AddCommGroup, Module (S ⊗[R] S), IsScalarTower S (S ⊗[R] S), Inhabited +deriving Inhabited + +-- The `SMul R'` instance exists to avoid a zsmul diamond. +variable {R' : Type*} [CommRing R'] [Algebra R' S] [SMulCommClass R R' S] in +deriving instance SMul R', AddCommGroup, Module R', Module (S ⊗[R] S), IsScalarTower S (S ⊗[R] S) + for KaehlerDifferential R S @[inherit_doc KaehlerDifferential] notation "Ω[" S "⁄" R "]" => KaehlerDifferential R S -instance KaehlerDifferential.module' {R' : Type*} [CommRing R'] [Algebra R' S] - [SMulCommClass R R' S] : - Module R' Ω[S⁄R] := - inferInstanceAs <| Module R' (_ ⧸ _) - instance KaehlerDifferential.isScalarTower_of_tower {R₁ R₂ : Type*} [CommRing R₁] [CommRing R₂] [Algebra R₁ S] [Algebra R₂ S] [SMul R₁ R₂] [SMulCommClass R R₁ S] [SMulCommClass R R₂ S] [IsScalarTower R₁ R₂ S] : diff --git a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean index 78273f7ecadd37..2e68eaf7c2035a 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean @@ -164,6 +164,12 @@ theorem isEmbedding_coeFn [UniformSpace F] [IsUniformAddGroup F] (𝔖 : Set (Se (UniformOnFun.ofFun 𝔖 ∘ DFunLike.coe) := IsUniformEmbedding.isEmbedding (isUniformEmbedding_coeFn _ _ _) +-- This instance exists to avoid nsmul and zsmul diamonds. +instance (M : Type*) [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜₂ M F] + [TopologicalSpace F] [ContinuousConstSMul M F] (𝔖 : Set (Set E)) : + SMul M (E →SLᵤ[σ, 𝔖] F) where + smul c f := (ofFun σ F 𝔖) (c • (ofFun σ F 𝔖).symm f) + instance instAddCommGroup [TopologicalSpace F] [IsTopologicalAddGroup F] (𝔖 : Set (Set E)) : AddCommGroup (E →SLᵤ[σ, 𝔖] F) := inferInstanceAs <| AddCommGroup (E →SL[σ] F) @@ -224,12 +230,11 @@ theorem t2Space [TopologicalSpace F] [IsTopologicalAddGroup F] [T2Space F] instance instDistribMulAction (M : Type*) [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜₂ M F] [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousConstSMul M F] (𝔖 : Set (Set E)) : - DistribMulAction M (E →SLᵤ[σ, 𝔖] F) where - smul c f := (ofFun σ F 𝔖) (c • (ofFun σ F 𝔖).symm f) - __ : DistribMulAction M (E →SLᵤ[σ, 𝔖] F) := inferInstanceAs <| DistribMulAction M (E →SL[σ] F) + DistribMulAction M (E →SLᵤ[σ, 𝔖] F) := + inferInstanceAs <| DistribMulAction M (E →SL[σ] F) instance {M : Type*} [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜₂ M F] - [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousConstSMul M F] (𝔖 : Set (Set E)) : + [TopologicalSpace F] [ContinuousConstSMul M F] (𝔖 : Set (Set E)) : IsSMulApply M (E →SLᵤ[σ, 𝔖] F) E F where smul_apply _ _ _ := rfl diff --git a/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean b/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean index e75d37c8867b41..c8a66ff79cc078 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/WeakBilin.lean @@ -63,18 +63,20 @@ section WeakTopology @[nolint unusedArguments] def WeakBilin [CommSemiring 𝕜] [AddCommMonoid E] [Module 𝕜 E] [AddCommMonoid F] [Module 𝕜 F] (_ : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) := E -deriving AddCommMonoid, Module 𝕜 namespace WeakBilin +variable [CommSemiring 𝕜] [AddCommMonoid E] [Module 𝕜 E] [AddCommMonoid F] [Module 𝕜 F] + (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) [CommSemiring 𝕝] [Module 𝕝 E] in +deriving instance SMul 𝕝, AddCommMonoid, Module 𝕝 for WeakBilin B + instance instAddCommGroup [CommSemiring 𝕜] [AddCommGroup E] [Module 𝕜 E] [AddCommMonoid F] [Module 𝕜 F] (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) : AddCommGroup (WeakBilin B) := inferInstanceAs <| AddCommGroup E -instance (priority := 100) instModule' [CommSemiring 𝕜] [CommSemiring 𝕝] [AddCommMonoid E] - [Module 𝕜 E] [AddCommMonoid F] [Module 𝕜 F] [Module 𝕝 E] (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) : - Module 𝕝 (WeakBilin B) := - inferInstanceAs <| Module 𝕝 E +instance [CommSemiring 𝕜] [AddCommMonoid E] [Module 𝕜 E] [AddCommMonoid F] [Module 𝕜 F] + (B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜) : Module 𝕜 (WeakBilin B) := + inferInstance instance instIsScalarTower [CommSemiring 𝕜] [CommSemiring 𝕝] [AddCommMonoid E] [Module 𝕜 E] [AddCommMonoid F] [Module 𝕜 F] [SMul 𝕝 𝕜] [Module 𝕝 E] [IsScalarTower 𝕝 𝕜 E] diff --git a/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean b/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean index e7ac7aa3da5de1..2651255c982d3f 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean @@ -61,8 +61,7 @@ functionals `fun v => v x` are continuous. -/ def WeakDual (𝕜 E : Type*) [CommSemiring 𝕜] [TopologicalSpace 𝕜] [ContinuousAdd 𝕜] [ContinuousConstSMul 𝕜 𝕜] [AddCommMonoid E] [Module 𝕜 E] [TopologicalSpace E] := WeakBilin (topDualPairing 𝕜 E) -deriving AddCommMonoid, TopologicalSpace, ContinuousAdd, Inhabited, - FunLike, ContinuousLinearMapClass +deriving TopologicalSpace, Inhabited, FunLike, ContinuousLinearMapClass namespace WeakDual @@ -75,6 +74,8 @@ instance instMulAction (M) [Monoid M] [DistribMulAction M 𝕜] [SMulCommClass [ContinuousConstSMul M 𝕜] : MulAction M (WeakDual 𝕜 E) := inferInstanceAs <| MulAction M (E →L[𝕜] 𝕜) +deriving instance AddCommMonoid, ContinuousAdd for WeakDual + /-- If a monoid `M` distributively continuously acts on `𝕜` and this action commutes with multiplication on `𝕜`, then it acts distributively on `WeakDual 𝕜 E`. -/ instance instDistribMulAction (M) [Monoid M] [DistribMulAction M 𝕜] [SMulCommClass 𝕜 M 𝕜] @@ -200,7 +201,7 @@ end WeakDual def WeakSpace (𝕜 E) [CommSemiring 𝕜] [TopologicalSpace 𝕜] [ContinuousAdd 𝕜] [ContinuousConstSMul 𝕜 𝕜] [AddCommMonoid E] [Module 𝕜 E] [TopologicalSpace E] := WeakBilin (topDualPairing 𝕜 E).flip -deriving AddCommMonoid, TopologicalSpace, ContinuousAdd +deriving TopologicalSpace section Semiring @@ -208,6 +209,12 @@ variable [CommSemiring 𝕜] [TopologicalSpace 𝕜] [ContinuousAdd 𝕜] variable [ContinuousConstSMul 𝕜 𝕜] variable [AddCommMonoid E] [Module 𝕜 E] [TopologicalSpace E] +-- The `SMul` instance exists to avoid an nsmul diamond. +variable [CommSemiring 𝕝] [Module 𝕝 E] in +deriving instance SMul 𝕝 for WeakSpace 𝕜 E + +deriving instance AddCommMonoid, ContinuousAdd for WeakSpace + namespace WeakSpace instance instModule' [CommSemiring 𝕝] [Module 𝕝 E] : Module 𝕝 (WeakSpace 𝕜 E) := diff --git a/Mathlib/Topology/Algebra/UniformConvergence.lean b/Mathlib/Topology/Algebra/UniformConvergence.lean index 3b3a3eb462d10d..91346cd4ff6425 100644 --- a/Mathlib/Topology/Algebra/UniformConvergence.lean +++ b/Mathlib/Topology/Algebra/UniformConvergence.lean @@ -117,6 +117,32 @@ lemma UniformOnFun.toFun_div [Div β] (f g : α →ᵤ[𝔖] β) : @[to_additive (attr := simp)] lemma UniformOnFun.ofFun_div [Div β] (f g : α → β) : ofFun 𝔖 (f / g) = ofFun 𝔖 f / ofFun 𝔖 g := rfl +@[to_additive] +instance {M : Type*} [Pow β M] : Pow (α →ᵤ β) M := inferInstanceAs <| Pow (α → β) M + +@[to_additive (attr := simp) toFun_smul] +lemma UniformFun.toFun_pow {M : Type*} [Pow β M] (c : M) (f : α →ᵤ β) : + toFun (f ^ c) = toFun f ^ c := + rfl + +@[to_additive (attr := simp) ofFun_smul] +lemma UniformFun.ofFun_pow {M : Type*} [Pow β M] (c : M) (f : α → β) : + ofFun (f ^ c) = ofFun f ^ c := + rfl + +@[to_additive] +instance {M : Type*} [Pow β M] : Pow (α →ᵤ[𝔖] β) M := inferInstanceAs <| Pow (α → β) M + +@[to_additive (attr := simp) toFun_smul] +lemma UniformOnFun.toFun_pow {M : Type*} [Pow β M] (c : M) (f : α →ᵤ[𝔖] β) : + toFun 𝔖 (f ^ c) = toFun 𝔖 f ^ c := + rfl + +@[to_additive (attr := simp) ofFun_smul] +lemma UniformOnFun.ofFun_pow {M : Type*} [Pow β M] (c : M) (f : α → β) : + ofFun 𝔖 (f ^ c) = ofFun 𝔖 f ^ c := + rfl + @[to_additive] instance [Monoid β] : Monoid (α →ᵤ β) := inferInstanceAs <| Monoid (α → β) @@ -141,30 +167,6 @@ instance [CommGroup β] : CommGroup (α →ᵤ β) := inferInstanceAs <| CommGro @[to_additive] instance [CommGroup β] : CommGroup (α →ᵤ[𝔖] β) := inferInstanceAs <| CommGroup (α → β) -instance {M : Type*} [SMul M β] : SMul M (α →ᵤ β) := inferInstanceAs <| SMul M (α → β) - -@[simp] -lemma UniformFun.toFun_smul {M : Type*} [SMul M β] (c : M) (f : α →ᵤ β) : - toFun (c • f) = c • toFun f := - rfl - -@[simp] -lemma UniformFun.ofFun_smul {M : Type*} [SMul M β] (c : M) (f : α → β) : - ofFun (c • f) = c • ofFun f := - rfl - -instance {M : Type*} [SMul M β] : SMul M (α →ᵤ[𝔖] β) := inferInstanceAs <| SMul M (α → β) - -@[simp] -lemma UniformOnFun.toFun_smul {M : Type*} [SMul M β] (c : M) (f : α →ᵤ[𝔖] β) : - toFun 𝔖 (c • f) = c • toFun 𝔖 f := - rfl - -@[simp] -lemma UniformOnFun.ofFun_smul {M : Type*} [SMul M β] (c : M) (f : α → β) : - ofFun 𝔖 (c • f) = c • ofFun 𝔖 f := - rfl - instance {M N : Type*} [SMul M N] [SMul M β] [SMul N β] [IsScalarTower M N β] : IsScalarTower M N (α →ᵤ β) := inferInstanceAs <| IsScalarTower M N (α → β) diff --git a/Mathlib/Topology/VectorBundle/Constructions.lean b/Mathlib/Topology/VectorBundle/Constructions.lean index 6f9dfc1b34636e..14e53aa291e030 100644 --- a/Mathlib/Topology/VectorBundle/Constructions.lean +++ b/Mathlib/Topology/VectorBundle/Constructions.lean @@ -181,6 +181,11 @@ section variable (R 𝕜 : Type*) {B : Type*} (F : Type*) (E : B → Type*) {B' : Type*} (f : B' → B) +-- This instance exists to avoid an nsmul diamond. +instance [Semiring R] [∀ x : B, AddCommMonoid (E x)] [i : ∀ x, Module R (E x)] (x : B') : + SMul R ((f *ᵖ E) x) := + inferInstanceAs <| SMul R (E (f x)) + instance [i : ∀ x : B, AddCommMonoid (E x)] (x : B') : AddCommMonoid ((f *ᵖ E) x) := inferInstanceAs <| AddCommMonoid (E (f x)) From 20ac1a52bff5702defcd271be6d5ec21c02d6a5b Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Thu, 16 Jul 2026 17:18:52 +0000 Subject: [PATCH 0833/1300] feat: extend `LawfulXor` lemmas and add `Equiv.xor` (#38037) This PR extends the work of #37712 by adding additional lemmas and adding `xor-as-a-permutation`. Co-authored-by: Eric Wieser --- Mathlib.lean | 4 +- Mathlib/Data/Fin/Init.lean | 35 +++++++++++++++ .../{LawfulXor.lean => LawfulXor/Basic.lean} | 43 +++++++++++++++--- Mathlib/Data/LawfulXor/Equiv.lean | 44 +++++++++++++++++++ 4 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 Mathlib/Data/Fin/Init.lean rename Mathlib/Data/{LawfulXor.lean => LawfulXor/Basic.lean} (72%) create mode 100644 Mathlib/Data/LawfulXor/Equiv.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8620a9f24a757d..3076dcb5539486 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3869,6 +3869,7 @@ public import Mathlib.Data.Fin.Basic public import Mathlib.Data.Fin.Embedding public import Mathlib.Data.Fin.Fin2 public import Mathlib.Data.Fin.FlagRange +public import Mathlib.Data.Fin.Init public import Mathlib.Data.Fin.Parity public import Mathlib.Data.Fin.Pigeonhole public import Mathlib.Data.Fin.Rev @@ -4053,7 +4054,8 @@ public import Mathlib.Data.Int.Sqrt public import Mathlib.Data.Int.Star public import Mathlib.Data.Int.SuccPred public import Mathlib.Data.Int.WithZero -public import Mathlib.Data.LawfulXor +public import Mathlib.Data.LawfulXor.Basic +public import Mathlib.Data.LawfulXor.Equiv public import Mathlib.Data.List.AList public import Mathlib.Data.List.Basic public import Mathlib.Data.List.Chain diff --git a/Mathlib/Data/Fin/Init.lean b/Mathlib/Data/Fin/Init.lean new file mode 100644 index 00000000000000..e33f9b646ef9b2 --- /dev/null +++ b/Mathlib/Data/Fin/Init.lean @@ -0,0 +1,35 @@ +/- +Copyright (c) 2026 Wrenna Robson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Wrenna Robson +-/ +module + +public import Mathlib.Data.Nat.Notation +public import Init.Data.Fin.Bitwise + +/-! +# Basic operations on bounded natural numbers. + +This file should not depend on anything defined in Mathlib (except for notation), so that it can be +upstreamed to Batteries or the Lean standard library easily. +-/ + +@[expose] public section + +/- We don't want to import the algebraic hierarchy in this file. -/ +assert_not_exists Monoid + +namespace Fin + +variable {n k : ℕ} + +theorem xor_assoc (h : k = 2 ^ n) (a b c : Fin k) : (a ^^^ b) ^^^ c = a ^^^ (b ^^^ c) := by + grind [Fin.xor_val, Nat.xor_mod_two_pow, Nat.mod_mod] +theorem xor_comm (a b : Fin k) : a ^^^ b = b ^^^ a := by grind [Fin.xor_val] +@[simp] theorem xor_self [NeZero k] (a : Fin k) : a ^^^ a = 0 := by + grind [Fin.xor_val, Nat.zero_mod] +@[simp] theorem xor_zero [NeZero k] (a : Fin k) : a ^^^ 0 = a := by + grind [Fin.xor_val, Fin.val_zero, Nat.mod_eq_of_lt] + +end Fin diff --git a/Mathlib/Data/LawfulXor.lean b/Mathlib/Data/LawfulXor/Basic.lean similarity index 72% rename from Mathlib/Data/LawfulXor.lean rename to Mathlib/Data/LawfulXor/Basic.lean index bb486390d9a029..04b3dd0aec1e11 100644 --- a/Mathlib/Data/LawfulXor.lean +++ b/Mathlib/Data/LawfulXor/Basic.lean @@ -6,6 +6,7 @@ Authors: Eric Wieser module public import Mathlib.Logic.Function.Basic +public import Mathlib.Data.Fin.Init /-! # The `LawfulXor` typeclass @@ -38,20 +39,26 @@ instance : Std.LawfulCommIdentity (α := α) XorOp.xor 0 where left_id := zero_xor right_id := xor_zero -@[simp] -theorem xor_cancel_right (a b : α) : (a ^^^ b) ^^^ b = a := by - rw [xor_assoc, LawfulXor.xor_self, xor_zero] - @[simp] theorem xor_cancel_left (a b : α) : a ^^^ (a ^^^ b) = b := by rw [← xor_assoc, LawfulXor.xor_self, zero_xor] +@[simp] +theorem xor_cancel_right (a b : α) : (a ^^^ b) ^^^ b = a := by + rw [xor_assoc, LawfulXor.xor_self, xor_zero] + instance : LawfulXor Nat where xor_assoc := Nat.xor_assoc xor_comm := Nat.xor_comm xor_self := Nat.xor_self xor_zero := Nat.xor_zero +instance {w : ℕ} : LawfulXor (Fin (2 ^ w)) where + xor_assoc := Fin.xor_assoc rfl + xor_comm := Fin.xor_comm + xor_self := Fin.xor_self + xor_zero := Fin.xor_zero + instance {w : Nat} : LawfulXor (BitVec w) where xor_assoc := BitVec.xor_assoc xor_comm := BitVec.xor_comm @@ -118,12 +125,36 @@ instance : LawfulXor ISize where xor_self _ := ISize.xor_self xor_zero _ := ISize.xor_zero -lemma xor_right_involutive (a : α) : Function.Involutive (a ^^^ ·) := xor_cancel_left a +lemma xor_right_eq {a : α} : (· ^^^ a) = (a ^^^ ·) := funext (xor_comm · a) lemma xor_left_involutive (a : α) : Function.Involutive (· ^^^ a) := (xor_cancel_right · a) +lemma xor_right_involutive (a : α) : Function.Involutive (a ^^^ ·) := xor_cancel_left a lemma xor_eq_iff_left_eq (a b c : α) : a ^^^ b = c ↔ a = c ^^^ b := xor_left_involutive _ |>.eq_iff - lemma xor_eq_iff_right_eq (a b c : α) : a ^^^ b = c ↔ b = a ^^^ c := xor_right_involutive _ |>.eq_iff + +@[simp] lemma xor_eq_zero_iff {a b : α} : a ^^^ b = 0 ↔ a = b := by + rw [ xor_eq_iff_left_eq, zero_xor] + +@[simp] lemma xor_xor_cancel_comm (a b : α) : a ^^^ b ^^^ a = b := by + rw [xor_comm a, xor_cancel_right] + +@[simp] lemma xor_xor_cancel_comm_assoc (a b : α) : a ^^^ (b ^^^ a) = b := by + rw [xor_comm a, xor_cancel_right] + +@[simp] lemma xor_left_eq_self_iff {a b : α} : a ^^^ b = a ↔ b = 0 := by + rw [xor_eq_iff_right_eq, xor_self a] +@[simp] lemma xor_right_eq_self_iff {a b : α} : b ^^^ a = a ↔ b = 0 := by + rw [xor_eq_iff_left_eq, xor_self a] + +@[simp] lemma xor_left_eq_id_iff {a : α} : (a ^^^ ·) = id ↔ a = 0 := + ⟨((xor_zero a).symm.trans <| congrFun · 0), (· ▸ funext zero_xor)⟩ +@[simp] lemma xor_right_eq_id_iff {a : α} : (· ^^^ a) = id ↔ a = 0 := by + rw [xor_right_eq, xor_left_eq_id_iff] + +@[simp] lemma isFixedPt_xor_left_iff {a b : α} : Function.IsFixedPt (a ^^^ ·) b ↔ a = 0 := + xor_right_eq_self_iff +@[simp] lemma isFixedPt_xor_right_iff {a b : α} : Function.IsFixedPt (· ^^^ a) b ↔ a = 0 := by + rw [xor_right_eq, isFixedPt_xor_left_iff] diff --git a/Mathlib/Data/LawfulXor/Equiv.lean b/Mathlib/Data/LawfulXor/Equiv.lean new file mode 100644 index 00000000000000..192271da341eaa --- /dev/null +++ b/Mathlib/Data/LawfulXor/Equiv.lean @@ -0,0 +1,44 @@ +/- +Copyright (c) 2026 Wrenna Robson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Wrenna Robson +-/ + +module +public import Mathlib.Data.LawfulXor.Basic +public import Mathlib.Algebra.Group.End + +/-! +# LawfulXor equivalences +-/ + +@[expose] public section + +namespace Equiv + +open LawfulXor + +variable {α β : Type*} [XorOp α] [Zero α] [LawfulXor α] {a b c : α} + +/-- `XorOp.xor` as a permutation. -/ +@[simps! apply] protected def xor (a : α) : Perm α where + toFun := (a ^^^ ·) + invFun := (a ^^^ ·) + left_inv := xor_cancel_left a + right_inv := xor_cancel_left a + +@[simp] theorem xor_symm : (Equiv.xor a).symm = Equiv.xor a := rfl + +theorem xor_involutive (a : α) : Function.Involutive (Equiv.xor a) := xor_right_involutive a + +@[simp] theorem xor_zero : Equiv.xor (0 : α) = 1 := Equiv.ext zero_xor + +@[simp] theorem xor_eq_one_iff : Equiv.xor a = 1 ↔ a = 0 := + Equiv.coe_inj.symm.trans xor_left_eq_id_iff + +theorem isFixedPt_xor : Function.IsFixedPt (Equiv.xor a) b ↔ a = 0 := isFixedPt_xor_left_iff + +@[simp] theorem xor_trans_xor : (Equiv.xor b).trans (Equiv.xor a) = Equiv.xor (a ^^^ b) := + Equiv.ext <| (.symm <| xor_assoc a b ·) + +end Equiv From 6ca518ac72a1398fb20f061e45611eead76304cd Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:31:06 +0000 Subject: [PATCH 0834/1300] feat(NumberTheory/EulerProduct/DirichletLSeries): establish Dirichlet series for log of L-functions or Riemann-zeta (#41097) Establishes the Dirichlet series for the logarithm of a Dirichlet L-function (and in particular the Riemann zeta function), to the right of the critical strip. Co-authored-by: Terence Tao --- .../SpecialFunctions/Complex/LogBounds.lean | 5 ++ Mathlib/NumberTheory/EulerProduct/Basic.lean | 40 ++++++++++ .../EulerProduct/DirichletLSeries.lean | 74 +++++++++++++++++++ Mathlib/NumberTheory/LSeries/Basic.lean | 5 ++ Mathlib/NumberTheory/LSeries/PrimesInAP.lean | 37 ---------- 5 files changed, 124 insertions(+), 37 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean b/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean index ff385f84f490a3..96c584f6c2ae85 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean @@ -287,6 +287,11 @@ lemma hasSum_taylorSeries_neg_log {z : ℂ} (hz : ‖z‖ < 1) : · simp simp [field, pow_add, ← mul_pow] +lemma hasSum_taylorSeries_neg_log' {z : ℂ} (hz : ‖z‖ < 1) : + HasSum (fun n : ℕ ↦ z ^ (n + 1) / (n + 1)) (-log (1 - z)) := by + rw_mod_cast [hasSum_nat_add_iff 1 (f := fun n ↦ z ^ n / n) (g := -log (1 - z))] + simpa using hasSum_taylorSeries_neg_log hz + end Complex section Limits diff --git a/Mathlib/NumberTheory/EulerProduct/Basic.lean b/Mathlib/NumberTheory/EulerProduct/Basic.lean index cdc9ee511c42e0..3c85fa476bd30c 100644 --- a/Mathlib/NumberTheory/EulerProduct/Basic.lean +++ b/Mathlib/NumberTheory/EulerProduct/Basic.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Normed.Ring.InfiniteSum public import Mathlib.Analysis.SpecificLimits.Normed +public import Mathlib.Data.Nat.Factorization.PrimePow public import Mathlib.NumberTheory.ArithmeticFunction.Defs public import Mathlib.NumberTheory.SmoothNumbers @@ -379,3 +380,42 @@ theorem eulerProduct_completely_multiplicative {f : ℕ →*₀ F} (hsum : Summa end EulerProduct end CompletelyMultiplicative + +section PrimePow + +/-! ### Reindexing infinite sums and products over prime powers -/ + +open Nat.Primes + +variable {α : Type*} [CommGroup α] [UniformSpace α] [IsUniformGroup α] [CompleteSpace α] [T0Space α] +variable {f : ℕ → α} + +@[to_additive tsum_primes_pow_eq] +theorem tprod_primes_pow_eq (hf : Multipliable fun n : {n // IsPrimePow n} ↦ f n.1) : + ∏' (p : Nat.Primes) (n : ℕ), f (p ^ (n + 1)) = ∏' n : {n : ℕ // IsPrimePow n}, f n := calc + _ = ∏' p : Nat.Primes × ℕ, f (prodNatEquiv p) := by + simpa using (hf.comp_injective prodNatEquiv.injective).tprod_prod.symm + _ = _ := by rw [← Equiv.tprod_eq prodNatEquiv] + +@[to_additive tsum_eq_tsum_primes_of_support_subset_prime_powers] +lemma tprod_eq_tprod_primes_of_mulSupport_subset_prime_powers + (hfm : Multipliable f) (hf : Function.mulSupport f ⊆ {n | IsPrimePow n}) : + ∏' n : ℕ, f n = ∏' (p : Nat.Primes) (k : ℕ), f (p ^ (k + 1)) := by + rw [tprod_primes_pow_eq (hfm.subtype _)] + exact (tprod_subtype_eq_of_mulSupport_subset hf).symm + +@[to_additive tsum_eq_tsum_primes_add_tsum_primes_of_support_subset_prime_powers] +lemma tprod_eq_tprod_primes_mul_tprod_primes_of_mulSupport_subset_prime_powers + (hfm : Multipliable f) (hf : Function.mulSupport f ⊆ {n | IsPrimePow n}) : + ∏' n : ℕ, f n = (∏' p : Nat.Primes, f p) * ∏' (p : Nat.Primes) (k : ℕ), f (p ^ (k + 2)) := by + rw [tprod_eq_tprod_primes_of_mulSupport_subset_prime_powers hfm hf] + have hfs' (p : Nat.Primes) : Multipliable fun k ↦ f (p ^ (k + 1)) := + hfm.comp_injective <| (strictMono_nat_of_lt_succ + (pow_lt_pow_right₀ p.prop.one_lt <| lt_add_one <| · + 1)).injective + simp only [(hfs' _).tprod_eq_zero_mul, zero_add, pow_one] + apply (Multipliable.subtype hfm _).tprod_mul + refine (hfm.comp_injective ?_).prod (f := fun (pk : Nat.Primes × ℕ) ↦ f (pk.1 ^ (pk.2 + 2))) + exact Subtype.val_injective.comp prodNatEquiv.injective |>.comp <| + Function.Injective.prodMap (fun ⦃_ _⦄ ↦ id) <| add_left_injective 1 + +end PrimePow diff --git a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean index 46f260fc0add57..c7299a93b8edab 100644 --- a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean +++ b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean @@ -205,3 +205,77 @@ lemma DirichletCharacter.LSeries_changeLevel {M N : ℕ} [NeZero N] have ha : ‖χ p‖ ≤ 1 := χ.norm_le_one p have hb : ‖(p : ℂ) ^ (-s)‖ ≤ 1 / 2 := norm_prime_cpow_le_one_half ⟨p, h⟩ hs exact ((mul_le_mul ha hb (norm_nonneg _) zero_le_one).trans_lt (by norm_num)).ne + +section LogDirichlet + +open Real hiding log exp_nat_mul exp_add +open ArithmeticFunction Primes Summable + +variable {N : ℕ} (χ : DirichletCharacter ℂ N) {s : ℂ} + +/-- For `1 < s.re`, the sum over primes of `-log (1 - χ p * p ^ (-s))` — the logarithm of the Euler +product — equals the `L`-series of `n ↦ χ n * Λ n / Real.log n`. +-/ +theorem DirichletCharacter.eulerProduct_log_eq_LSeries (hs : 1 < s.re) : + ∑' p : Primes, -log (1 - χ p * p ^ (-s)) = LSeries (fun n ↦ χ n * Λ n / Real.log n) s := by + have hpow_le (p : Primes) : ‖χ p * (p : ℂ) ^ (-s)‖ < 1 := by + grw [norm_mul, norm_le_one, norm_natCast_cpow_of_pos (mod_cast p.prop.pos), neg_re, one_mul] + apply rpow_lt_one_of_one_lt_of_neg (mod_cast p.prop.one_lt) (by linarith) + rw [tsum_congr (fun p ↦ (hasSum_taylorSeries_neg_log' (hpow_le p)).tsum_eq.symm), + LSeries_def₀ (by simp)] + let f : ℕ → ℂ := fun n ↦ χ n * Λ n / Real.log n * ((n : ℂ) ^ (-s)) + calc + _ = ∑' (p : Primes) (k : ℕ), (χ (p ^ (k + 1)) * ((p ^ (k + 1) : ℕ) : ℂ) ^ (-s)) * + Λ (p ^ (k + 1)) / Real.log (p ^ (k + 1)) := by + refine tsum_congr fun p ↦ tsum_congr fun k ↦ ?_ + have : Complex.log p ≠ 0 := mod_cast p.prop.log_ne_zero + simp [mul_pow, ← cpow_nat_mul, ← natCast_cpow_natCast_mul, vonMangoldt_apply_pow, + vonMangoldt_apply_prime p.2, field] + _ = ∑' n : {n : ℕ // IsPrimePow n}, f n := by + rw [← tsum_primes_pow_eq] + · exact tsum_congr fun p ↦ tsum_congr fun k ↦ (by unfold f; simp; ring) + · apply comp_injective _ Subtype.coe_injective (f := f) + apply of_norm_bounded_eventually_nat (g := (↑· ^ (-s.re))) + · simp [hs] + · filter_upwards [eventually_gt_atTop 1] with n hn + simp only [f, norm_mul, norm_div, norm_real, norm_eq_abs] + grw [norm_le_one, vonMangoldt_le_log] + have := log_pos (x := n) (mod_cast hn) + field_simp + rw [← ofReal_natCast n, norm_cpow_eq_rpow_re_of_nonneg (by simp) (by simp; grind)] + simp + _ = _ := by + simp only [div_eq_mul_inv _ (_ ^ _), ← cpow_neg] + suffices (Function.support f) ⊆ {n | IsPrimePow n} from + tsum_subtype_eq_of_support_subset this + intro n hn + contrapose! hn + simp [f, vonMangoldt_eq_zero_iff.mpr hn] + +/-- For `1 < s.re`, the Dirichlet L-function is the exponential of the `L`-series of +`n ↦ χ n * Λ n / Real.log n`. +-/ +theorem DirichletCharacter.LSeries_eq_exp_LSeries (hs : 1 < s.re) : + exp (LSeries (fun (n : ℕ) ↦ χ n * Λ n / Real.log n) s) = L ↗χ s := by + rw [← eulerProduct_log_eq_LSeries χ hs, LSeries_eulerProduct_exp_log χ hs] + +theorem riemannZeta_eq_exp_LSeries {s : ℂ} (hs : 1 < s.re) : + exp (LSeries (fun (n : ℕ) ↦ Λ n / Real.log n) s) = riemannZeta s := by + rw [← LSeries_one_eq_riemannZeta hs] + convert LSeries_eq_exp_LSeries (1 : DirichletCharacter ℂ 1) hs + <;> simp [MulChar.one_apply <| isUnit_of_subsingleton _] + +/-- For real `s > 1`, the logarithm of the (real) Riemann zeta function equals +`∑' n, Λ n / (n ^ s * Real.log n)`, where `Λ` is the von Mangoldt function. +-/ +theorem log_riemannZeta_eq {s : ℝ} (hs : 1 < s) : + Real.log (riemannZeta (s : ℂ)).re = ∑' n, Λ n / (n ^ s * Real.log n) := by + rw [← riemannZeta_eq_exp_LSeries (by simpa using hs), LSeries_def₀ (by simp)] + convert Real.log_exp _ + convert exp_ofReal_re _ + push_cast + congr! 2 with p + rw [ofReal_cpow (by positivity)] + simp [field] + +end LogDirichlet diff --git a/Mathlib/NumberTheory/LSeries/Basic.lean b/Mathlib/NumberTheory/LSeries/Basic.lean index a3b4ff07453907..ffd10e7cd63394 100644 --- a/Mathlib/NumberTheory/LSeries/Basic.lean +++ b/Mathlib/NumberTheory/LSeries/Basic.lean @@ -169,6 +169,11 @@ lemma LSeries_congr {f g : ℕ → ℂ} (h : ∀ {n}, n ≠ 0 → f n = g n) (s LSeries f s = LSeries g s := tsum_congr <| term_congr h s +/-- An alternate spelling of `LSeries` as `∑' n, f n / n ^ s` for the case `f 0 = 0`. -/ +lemma LSeries_def₀ {f : ℕ → ℂ} (hf : f 0 = 0) (s : ℂ) : + LSeries f s = ∑' n, f n / (n ^ s) := by + simp [LSeries, LSeries.term_def₀ hf, cpow_neg, div_eq_mul_inv] + /-- `LSeriesSummable f s` indicates that the L-series of `f` converges absolutely at `s`. -/ def LSeriesSummable (f : ℕ → ℂ) (s : ℂ) : Prop := Summable (term f s) diff --git a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean index c9b77f4253ba06..5603ed3b22c07d 100644 --- a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean +++ b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean @@ -77,43 +77,6 @@ An infinite product or sum over a function supported in prime powers can be writ as an iterated product or sum over primes and natural numbers. -/ -section auxiliary - -variable {α β γ : Type*} [CommGroup α] [UniformSpace α] [IsUniformGroup α] [CompleteSpace α] - [T0Space α] - -open Nat.Primes in -@[to_additive tsum_eq_tsum_primes_of_support_subset_prime_powers] -lemma tprod_eq_tprod_primes_of_mulSupport_subset_prime_powers {f : ℕ → α} - (hfm : Multipliable f) (hf : Function.mulSupport f ⊆ {n | IsPrimePow n}) : - ∏' n : ℕ, f n = ∏' (p : Nat.Primes) (k : ℕ), f (p ^ (k + 1)) := by - have hfm' : Multipliable fun pk : Nat.Primes × ℕ ↦ f (pk.fst ^ (pk.snd + 1)) := - prodNatEquiv.symm.multipliable_iff.mp <| by - simpa only [← coe_prodNatEquiv_apply, Prod.eta, Function.comp_def, Equiv.apply_symm_apply] - using! hfm.subtype _ - simp only [← tprod_subtype_eq_of_mulSupport_subset hf, Set.coe_setOf, ← prodNatEquiv.tprod_eq, - ← hfm'.tprod_prod] - refine tprod_congr fun (p, k) ↦ congrArg f <| coe_prodNatEquiv_apply .. - -@[to_additive tsum_eq_tsum_primes_add_tsum_primes_of_support_subset_prime_powers] -lemma tprod_eq_tprod_primes_mul_tprod_primes_of_mulSupport_subset_prime_powers {f : ℕ → α} - (hfm : Multipliable f) (hf : Function.mulSupport f ⊆ {n | IsPrimePow n}) : - ∏' n : ℕ, f n = (∏' p : Nat.Primes, f p) * ∏' (p : Nat.Primes) (k : ℕ), f (p ^ (k + 2)) := by - rw [tprod_eq_tprod_primes_of_mulSupport_subset_prime_powers hfm hf] - have hfs' (p : Nat.Primes) : Multipliable fun k : ℕ ↦ f (p ^ (k + 1)) := - hfm.comp_injective <| (strictMono_nat_of_lt_succ - fun k ↦ pow_lt_pow_right₀ p.prop.one_lt <| lt_add_one (k + 1)).injective - conv_lhs => - enter [1, p]; rw [(hfs' p).tprod_eq_zero_mul, zero_add, pow_one] - enter [2, 1, k]; rw [add_assoc, one_add_one_eq_two] - exact (Multipliable.subtype hfm _).tprod_mul <| - Multipliable.prod (f := fun (pk : Nat.Primes × ℕ) ↦ f (pk.1 ^ (pk.2 + 2))) <| - hfm.comp_injective <| Subtype.val_injective |>.comp - Nat.Primes.prodNatEquiv.injective |>.comp <| - Function.Injective.prodMap (fun ⦃_ _⦄ a ↦ a) <| add_left_injective 1 - -end auxiliary - /-! ### The L-series of the von Mangoldt function restricted to a residue class -/ From e4fd1baee84ac64a3522e08c61001b1dab34480a Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:44:26 +0000 Subject: [PATCH 0835/1300] chore: update Mathlib dependencies 2026-07-16 (#41826) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index c1526339caacfe..276fd1329a79f8 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "31a49105f960721073a9adfc82b261f5d0f2ce1e", + "rev": "45337c634fbcb2bb22fb45c9847faaa10d4d1b67", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 16274bd25ac511707d2242a6c762e67a48ea46f7 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:40:06 +0000 Subject: [PATCH 0836/1300] perf(Tactic/Linter/UnusedTactic): use `InfoTree.foldInfo` (#41804) This PR refactors the info tree folding in the unused tactic linter to use `InfoTree.foldInfo`. This is defined in Lean core, meaning that it is compiled, and so faster than the interpreter. --- Mathlib/Tactic/Linter/UnusedTactic.lean | 53 ++++++++++--------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/Mathlib/Tactic/Linter/UnusedTactic.lean b/Mathlib/Tactic/Linter/UnusedTactic.lean index 2704ae66527eaf..1127477501760d 100644 --- a/Mathlib/Tactic/Linter/UnusedTactic.lean +++ b/Mathlib/Tactic/Linter/UnusedTactic.lean @@ -5,6 +5,7 @@ Authors: Damiano Testa -/ module +public meta import Lean.Server.InfoUtils -- Import this linter explicitly to ensure that -- this file has a valid copyright header and module docstring. public meta import Mathlib.Tactic.Linter.Header -- shake: keep @@ -144,39 +145,29 @@ def getNames (mctx : MetavarContext) : List Name := let locDecls := (lcts.map (PersistentArray.toList ∘ LocalContext.decls)).flatten.reduceOption locDecls.map LocalDecl.userName -mutual /-- Search for tactic executions in the info tree and remove the syntax of the tactics that changed something. -/ -partial def eraseUsedTacticsList (exceptions : Std.HashSet SyntaxNodeKind) +partial def eraseUsedTactics (exceptions : Std.HashSet SyntaxNodeKind) (trees : PersistentArray InfoTree) : M Unit := - trees.forM (eraseUsedTactics exceptions) - -/-- Search for tactic executions in the info tree and remove the syntax of the tactics that -changed something. -/ -partial def eraseUsedTactics (exceptions : Std.HashSet SyntaxNodeKind) : InfoTree → M Unit - | .node i c => do - if let .ofTacticInfo i := i then - let stx := i.stx - let kind := stx.getKind - if let some r := stx.getRange? true then - if exceptions.contains kind - -- if the tactic is allowed to not change the goals - then modify (·.erase r) - else - -- if the goals have changed - if i.goalsAfter != i.goalsBefore - then modify (·.erase r) - -- bespoke check for `swap_var`: the only change that it does is - -- in the usernames of local declarations, so we check the names before and after - else - if (kind == `Mathlib.Tactic.«tacticSwap_var__,,») && - (getNames i.mctxBefore != getNames i.mctxAfter) - then modify (·.erase r) - eraseUsedTacticsList exceptions c - | .context _ t => eraseUsedTactics exceptions t - | .hole _ => pure () - -end + let ranges := trees.foldl (init := #[]) <| InfoTree.foldInfo fun _ i ranges => Id.run do + let .ofTacticInfo i := i | return ranges + let stx := i.stx + let some r := stx.getRange? true | return ranges + let kind := stx.getKind + -- if the tactic is allowed to not change the goals + if exceptions.contains kind then + return ranges.push r + -- if the goals have changed + if i.goalsAfter != i.goalsBefore then + return ranges.push r + -- bespoke check for `swap_var`: the only change that it does is + -- in the usernames of local declarations, so we check the names before and after + if (kind == `Mathlib.Tactic.«tacticSwap_var__,,») && + (getNames i.mctxBefore != getNames i.mctxAfter) then + return ranges.push r + return ranges + for r in ranges do + modify (·.erase r) /-- The main entry point to the unused tactic linter. -/ def unusedTacticLinter : Linter where run := withSetOptionIn fun stx => do @@ -196,7 +187,7 @@ def unusedTacticLinter : Linter where run := withSetOptionIn fun stx => do let exceptions := (← allowedRef.get).union <| allowedUnusedTacticExt.getState env let go : M Unit := do getTactics (← ignoreTacticKindsRef.get) (fun k => tactics.contains k || convs.contains k) stx - eraseUsedTacticsList exceptions trees + eraseUsedTactics exceptions trees let (_, map) ← go.run {} let unused := map.toArray let key (r : Lean.Syntax.Range) := (r.start.byteIdx, (-r.stop.byteIdx : Int)) From 7d6261f2dc0fd8902626c60e8970bf7c5826afe0 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 16 Jul 2026 21:49:39 +0000 Subject: [PATCH 0837/1300] feat: operators which are strict and with closed range are stable under finite rank perturbation (#39100) This is the key technical result needed to start the theory of Fredholm operators. Co-authored-by: Oliver Nash Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib.lean | 1 + .../Operator/Perturbation/StrictByFinite.lean | 356 ++++++++++++++++++ .../Algebra/Module/FiniteDimension.lean | 6 + 3 files changed, 363 insertions(+) create mode 100644 Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3076dcb5539486..c1d24ccd4a4ae3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2253,6 +2253,7 @@ public import Mathlib.Analysis.Normed.Operator.LinearIsometry public import Mathlib.Analysis.Normed.Operator.Mul public import Mathlib.Analysis.Normed.Operator.NNNorm public import Mathlib.Analysis.Normed.Operator.NormedSpace +public import Mathlib.Analysis.Normed.Operator.Perturbation.StrictByFinite public import Mathlib.Analysis.Normed.Operator.Prod public import Mathlib.Analysis.Normed.Order.Basic public import Mathlib.Analysis.Normed.Order.Hom.Basic diff --git a/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean b/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean new file mode 100644 index 00000000000000..7564999c818a43 --- /dev/null +++ b/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean @@ -0,0 +1,356 @@ +/- +Copyright (c) 2026 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anatole Dedecker +-/ +module + +public import Mathlib.RingTheory.Finiteness.Cofinite +public import Mathlib.Topology.Maps.Strict.Module +public import Mathlib.Topology.LocalAtTarget +public import Mathlib.Topology.Algebra.Module.FiniteDimension +public import Mathlib.Algebra.Module.LinearMap.FiniteRange + +/-! +# Strict linear maps with closed range are closed under finite-rank perturbation + +Fix `𝕜` a complete nontrivially normed field, and `E`, `F` two topological vector spaces +over `𝕜`. This file contains various results expressing that the set of continuous +linear maps `u : E →L[𝕜] F` which are **strict** and have **closed range** is +"stable under finite-rank perturbations". + +More precisely, we prove the following statements: +* `ContinuousLinearMap.isStrictMap_isClosed_range_iff_restrict`: given a closed + subspace `A` of `E` of finite codimension, we have that `u` is strict with closed range + if and only if `u.domRestrict A` is strict with closed range. +* `ContinuousLinearMap.isStrictMap_isClosed_range_iff_of_finiteRangeSetoid`: if `u, v : E →L[𝕜] F` + differ by a finite rank continuous linear map, then `u` is strict with closed range if and only + if `v` is strict with closed range. +* `ContinuousLinearMap.isStrictMap_isClosed_range_iff_quotient`: given a *complemented* + finite dimensional subspace `B` of `F`, we have that `u` is strict with closed range + if and only if `B.mkQL ∘L u` is strict with closed range. + +These three results show up crucially when developing the theory of Fredholm operators +between topological vector spaces. Note that none of the results here use the Hahn-Banach +theorem, so there is no significant restriction on the field. + +## Implementation details + +This file covers almost exactly the content of +[N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 1][bourbaki2023]. However, +there are two notable changes compared to Bourbaki : +* We treat all topological vector spaces over complete nontrivially normed fields, + where Bourbaki restricts to locally convex spaces over `ℝ` or `ℂ`. To do so, we have to + tweak one statement by assuming that a finite dimensional subspace is complemented, which + is always the case when you have Hahn-Banach available. +* We give a different proof, where we reduce the statement to + `AddMonoidHom.isStrictMap_prodMap_iff`. This gives a slightly longer proof, but we + claim that it is more natural. + +Note that these two changes are independent: the extra generality could have been achieved +with Bourbaki's proof. + +## References + +* [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 1][bourbaki2023] + +-/ + +open Topology Set Submodule Function ContinuousLinearMap + +variable {𝕜 : Type*} + [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + +variable {E F : Type*} + [AddCommGroup E] [Module 𝕜 E] [AddCommGroup F] [Module 𝕜 F] + [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] + [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] + +section FiniteCodimSubspace + +/-! +## Proof of `ContinuousLinearMap.isStrictMap_isClosed_range_iff_restrict` + +Let `u : E → F` be a continuous linear map, and `A` a finite codimension closed +subspace of `E`. We want to show that `u` is strict with closed range if and only if +its restriction `u.domRestrict A : A → F` is strict with closed range. + +We do the proof in five steps. Note that we have commented the whole proof, so hopefully +you can follow the argument by reading the source code. +-/ + +/-! +### Step 1 + +We prove the theorem under the assumptions that +- `u` is surjective +- `u.ker` is disjoint from `A` (i.e. `u` is injective on `A`) +- `u.domRestrict A` has closed range + +The strategy of proof is to decompose both spaces into complementary subspace, +with one of the spaces being finite dimensional and `u` preserving this decomposition. + +The result then follows from `AddMonoidHom.isStrictMap_prodMap_iff` and +`ContinuousLinearMap.isStrictMap_of_finiteDimensional`. +-/ + +theorem step1 (u : E →L[𝕜] F) (A : Submodule 𝕜 E) + (A_closed : IsClosed (A : Set E)) [A_cofg : A.CoFG] + (h_ker : Disjoint u.ker A) (range_u : u.range = ⊤) + (range_u_restr : IsClosed ((u.domRestrict A).range : Set F)) : + IsStrictMap u ↔ IsStrictMap (u.domRestrict A) := by + -- Fix `S` an algebraic complement of `A` containing `u.ker`. It has finite dimension. + rcases h_ker.exists_isCompl with ⟨S, ker_le_S, S_compl_A⟩ + have : FiniteDimensional 𝕜 S := .of_fg <| A_cofg.fg_of_isCompl S_compl_A.symm + -- Because `u` is assumed surjective and `S ⊔ A = ⊤`, we have `map u S ⊔ map u A = ⊤`. + -- Furthermore, because the kernel of `u` is fully contained in `S`, we can show that + -- `map u S ⊓ map u A = ⊥`, so that `map u S` and `map u A` are in fact algebraic complements + -- of each other. + have uS_compl_uA : IsCompl (map u.toLinearMap S) (map u.toLinearMap A) := + ⟨disjoint_map_of_ker_le_left S_compl_A.disjoint ker_le_S, + codisjoint_map (LinearMap.range_eq_top.mp range_u) S_compl_A.codisjoint⟩ + -- Because `A` (resp. `map u A`) is closed and `S` (resp `map u S`) has finite dimension, + -- `A` and `S` (resp `map u A` and `map u S`) are in fact *topological* complements of each other. + replace S_compl_A : IsTopCompl S A := + S_compl_A.symm.isTopCompl_of_finiteDimensional_quotient A_closed |>.symm + replace uS_compl_uA : IsTopCompl (map u.toLinearMap S) (map u.toLinearMap A) := + uS_compl_uA.symm.isTopCompl_of_isClosed_of_finiteDimensional + (by simpa using range_u_restr) |>.symm + -- In particular, `S` and `map u S` are T2. + have : T2Space (map u.toLinearMap S) := uS_compl_uA.t2Space (by simpa using range_u_restr) + -- Thus, we have decomposed both the domain and the codomain into topological complements, + -- and `u` preserves this decomposition, inducing maps `uₛ : S → map u S` and `uₐ : A → map u A`. + set uₛ : S →L[𝕜] map u.toLinearMap S := u.restrict (fun _ ↦ mem_map_of_mem) + set uₐ : A →L[𝕜] map u.toLinearMap A := u.restrict (fun _ ↦ mem_map_of_mem) + -- Using the corresponding isomorphisms `(S × A) ≃L[𝕜] E` and `(map u S × map u A) ≃L[𝕜] F`, + -- we have to show that the map `uₛ.prodMap uₐ : S × A → map u S × map u A` is strict + -- if and only if `uₐ : A → map u A` is strict. + -- This follows from `AddMonoidHom.isStrictMap_prodMap_iff`, and the fact that `uₛ` is a + -- continuous linear map between T2 finite dimensional spaces, hence a strict map. + set Φ : (S × A) ≃L[𝕜] E := prodEquivOfIsTopCompl S A S_compl_A + set Ψ : (map u.toLinearMap S × map u.toLinearMap A) ≃L[𝕜] F := + prodEquivOfIsTopCompl _ _ uS_compl_uA + have u_eq : u = Ψ ∘ (uₛ.prodMap uₐ) ∘ Φ.symm := by + ext x + simp [Φ, Ψ, uₛ, uₐ, ← map_add, projection_add_projection_eq_self] + have u_restr_eq : u.domRestrict A = (map u.toLinearMap A).subtypeL ∘ uₐ := rfl + suffices IsStrictMap (uₛ.prodMap uₐ) ↔ IsStrictMap uₐ by + rwa [u_restr_eq, u_eq, ← (isEmbedding_subtypeL _).isStrictMap_iff, + ← Ψ.isHomeomorph.isEmbedding.isStrictMap_iff, + ← Φ.symm.isHomeomorph.isQuotientMap.isStrictMap_iff] + simp_rw [← coe_coe, ContinuousLinearMap.coe_prodMap, LinearMap.isStrictMap_prodMap_iff, coe_coe, + uₛ.isStrictMap_of_finiteDimensional, true_and] + +/-! +### Step 2 + +We prove the theorem under the assumptions that +- `u` is surjective +- `u.ker` is disjoint from `A` (i.e. `u` is injective on `A`) +-/ + +theorem step2 (u : E →L[𝕜] F) (A : Submodule 𝕜 E) + (A_closed : IsClosed (A : Set E)) [A.CoFG] + (h_ker : Disjoint u.ker A) (h_range : u.range = ⊤) : + IsStrictMap u ↔ IsStrictMap (u.domRestrict A) ∧ IsClosed ((u.domRestrict A).range : Set F) := by + -- To reduce to step 1, it suffices to show that `IsStrictMap u → IsClosed (map u A)`. + suffices IsStrictMap u → IsClosed ((u.domRestrict A).range : Set F) by grind only [step1] + -- So, we assume that `u` is strict. Because it is surjective, it is a quotient map. + intro u_strict + have u_quot : IsQuotientMap u := by + rw [LinearMap.range_eq_top, coe_coe] at h_range + simp [isQuotientMap_iff_isStrictMap_surjective, h_range, u_strict] + -- Hence, we have to check that `comap u (map u A)` is closed. This follows from + -- `A ≤ comap u (map u A)` and the fact that `A` is closed with finite codimension. + rw [← u_quot.isClosed_preimage, ← coe_coe, ← Submodule.comap_coe, toLinearMap_domRestrict, + LinearMap.range_domRestrict] + exact Submodule.isClosed_mono_of_finiteDimensional_quotient A_closed (le_comap_map _ _) + +/-! +### Step 3 + +We prove the theorem under the assumptions that +- `u` has closed range +- `u.ker` is disjoint from `A` (i.e. `u` is injective on `A`) +-/ + +theorem step3 (u : E →L[𝕜] F) (A : Submodule 𝕜 E) + (A_closed : IsClosed (A : Set E)) [A.CoFG] + (h_ker : Disjoint u.ker A) (h_range : IsClosed (u.range : Set F)) : + IsStrictMap u ↔ IsStrictMap (u.domRestrict A) ∧ IsClosed ((u.domRestrict A).range : Set F) := by + -- Let `F' := u.range` and `i : F' →L[𝕜] F` be the inclusion map. By assumption, + -- `i` is a closed embedding. + set F' : Submodule 𝕜 F := u.range + set i : F' →L[𝕜] F := F'.subtypeL + have i_clemb : IsClosedEmbedding i := F'.isClosedEmbedding_subtypeL h_range + -- Furthermore, `u` factors as `i ∘ u'` with `u' : E →L[𝕜] F'` surjective, + -- and we clearly have `u.domRestrict A = i ∘ u'.domRestrict A` as well. + set u' : E →L[𝕜] F' := u.rangeRestrict + have range_u' : u'.range = ⊤ := u.range_rangeRestrict + have eq1 : u = i ∘L u' := rfl + have eq2 : u.domRestrict A = i ∘L (u'.domRestrict A) := rfl + -- We can rewrite our goal in terms of `u'`. + simp_rw [eq2, eq1, coe_comp, ← i_clemb.isEmbedding.isStrictMap_iff, toLinearMap_comp, + LinearMap.range_comp, map_coe i.toLinearMap, coe_coe, ← i_clemb.isClosed_iff_image_isClosed] + -- We finish by applying step 2 (using that `u.ker = u'.ker`). + exact step2 u' A A_closed (u.ker_rangeRestrict ▸ h_ker) range_u' + +/-! +### Step 4 + +We prove the theorem under the assumption that `u.ker` is disjoint from `A` +(i.e. `u` is injective on `A`). +-/ + +theorem step4 (u : E →L[𝕜] F) (A : Submodule 𝕜 E) (A_closed : IsClosed (A : Set E)) + [A.CoFG] (h_ker : Disjoint u.ker A) : + (IsStrictMap u ∧ IsClosed (u.range : Set F)) ↔ + IsStrictMap (u.domRestrict A) ∧ IsClosed ((u.domRestrict A).range : Set F) := by + -- To reduce to step 3, it suffices to show that, if `u.domRestrict A` has closed range, + -- then so does `u`. + suffices IsClosed ((u.domRestrict A).range : Set F) → IsClosed (u.range : Set F) by + grind only [step3] + -- This follows from a general lemma, but we recall the proof below for completeness + simpa using u.toLinearMap.isClosed_range_of_isClosed_map_of_finiteDimensional_quotient + -- Assume that `map u A` is closed, and fix `S` an algebraic complement of `A`. + -- It has finite dimension. Then `u.range = map u A ⊔ map u S` is the supremum of + -- a closed subspace and a finite dimensional subspace, hence it is closed. + +/-! +### Step 5 + +We now deduce from the previous steps the full strength of the theorem. +-/ + +/-- Let `u : E → F` be a continuous linear map, and `A` a closed subspace of `E` of finite +codimension. Then `u` is strict with closed range if and only if its restriction +`u.domRestrict A : A → F` is strict with closed range. + +This is [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 1, Prop. 1][bourbaki2023]. -/ +public theorem ContinuousLinearMap.isStrictMap_isClosed_range_iff_restrict + (u : E →L[𝕜] F) (A : Submodule 𝕜 E) (A_closed : IsClosed (A : Set E)) [A.CoFG] : + (IsStrictMap u ∧ IsClosed (u.range : Set F)) ↔ + (IsStrictMap (u.domRestrict A) ∧ IsClosed ((u.domRestrict A).range : Set F)) := by + -- To reduce to step 4, we quotient by `N := A ⊓ u.ker`. Denoting by `π : E → E ⧸ N` + -- the (automatically open) quotient map, `u` factors as `v ∘ π` with `v : E ⧸ N → F`. + set N : Submodule 𝕜 E := A ⊓ u.ker + set π : E →L[𝕜] E ⧸ N := N.mkQL + set v : E ⧸ N →L[𝕜] F := N.liftQL u inf_le_right + have π_quot : IsOpenQuotientMap π := N.isOpenQuotientMap_mkQL + have u_eq : u = v ∘L π := rfl + -- We also consider the submodule `B := map π A` of `E ⧸ N`. It has finite codimension and, + -- by construction, it is disjoint from the kernel of `v`. + set B : Submodule 𝕜 (E ⧸ N) := map N.mkQ A + have B_cofg : B.CoFG := + quotientQuotientEquivQuotient N A inf_le_left |>.symm.finiteDimensional + have v_ker : Disjoint v.ker B := by + simp [disjoint_iff, v, B, toLinearMap_liftQL, ker_liftQ, + map_inf_eq_map_inf_comap, comap_map_mkQ, N, inf_comm] + -- Because `A` contains `N`, we have `A = comap π B`. In particular, `B` is closed. + have comap_B : comap π.toLinearMap B = A := by simp [B, N, π] + have A_mapsTo_B : MapsTo π A B := fun _ ↦ by simp [← comap_B] + have B_closed : IsClosed (B : Set <| E ⧸ N) := by + rwa [← π_quot.isQuotientMap.isClosed_preimage, ← π.coe_coe, ← comap_coe, comap_B] + -- Thus, we can apply step 4 to `v` and `B`: we get that `v` is strict with closed range if + -- and only if `v.domRestrict B` is strict with closed range. + have step4_output : (IsStrictMap v ∧ IsClosed (v.range : Set F)) ↔ + (IsStrictMap (v.domRestrict B) ∧ IsClosed ((v.domRestrict B).range : Set F)) := + step4 v B B_closed v_ker + -- Now, we wish to reduce our statement about `u` and `u.domRestrict A` + -- to what we know about `v` and `v.domRestrict B`. + -- First, it is clear that `range u = range v` and `map u A = map v B`. + have range_eq : v.range = u.range := range_liftQ _ _ _ + have range_restr_eq : (v.domRestrict B).range = (u.domRestrict A).range := by + simp [B, u_eq, π, ← map_comp] + -- Now, recall the equality `A = comap π B`; it ensures that the restriction + -- `π' : A → B` of the open quotient map `π` is *still* an (open) quotient map. + set π' : A →L[𝕜] B := π.restrict A_mapsTo_B + have π'_quot : IsOpenQuotientMap π' := by + let φ : (N.mkQL ⁻¹' B) ≃ₜ A := .setCongr congr(SetLike.coe $comap_B) + exact N.isOpenQuotientMap_mkQL.restrictPreimage B |>.comp + φ.symm.isOpenQuotientMap + -- Note that `u.domRestrict A` factors as `v.domRestrict B ∘ π'`. + have u_restr_eq : u.domRestrict A = v.domRestrict B ∘L π' := rfl + -- We conclude by invoking `IsQuotientMap.isStrictMap_iff` twice, to get that strictness of + -- `u` (resp. `u.domRestrict A`) is equivalent to strictness of `v` (resp. `v.domRestrict B`). + calc IsStrictMap u ∧ IsClosed (u.range : Set F) + ↔ IsStrictMap v ∧ IsClosed (v.range : Set F) := by + rw [← range_eq, u_eq, coe_comp, π_quot.isQuotientMap.isStrictMap_iff] + _ ↔ IsStrictMap (v.domRestrict B) ∧ IsClosed ((v.domRestrict B).range : Set F) := + step4_output + _ ↔ IsStrictMap (u.domRestrict A) ∧ IsClosed ((u.domRestrict A).range : Set F) := by + rw [← range_restr_eq, u_restr_eq, coe_comp, π'_quot.isQuotientMap.isStrictMap_iff] + +end FiniteCodimSubspace + +/-! +## Consequences +-/ + +section FiniteRank + +/-- If two continuous linear maps `u, v : E → F` agree on a subspace `A` of `E` with finite +codimension, then `u` is strict with closed range if and only if `v` is strict with closed range. -/ +public theorem ContinuousLinearMap.isStrictMap_isClosed_range_iff_of_eqOn [T2Space F] + (u v : E →L[𝕜] F) (A : Submodule 𝕜 E) [A.CoFG] (h_eqOn : EqOn u v A) : + (IsStrictMap u ∧ IsClosed (u.range : Set F)) ↔ + (IsStrictMap v ∧ IsClosed (v.range : Set F)) := by + replace h_eqOn : EqOn u v A.topologicalClosure := h_eqOn.closure (by fun_prop) (by fun_prop) + simp_rw [u.isStrictMap_isClosed_range_iff_restrict _ A.isClosed_topologicalClosure, + v.isStrictMap_isClosed_range_iff_restrict _ A.isClosed_topologicalClosure, + LinearMap.coe_range, ContinuousLinearMap.coe_coe, ContinuousLinearMap.coe_domRestrict, + restrict_eq_restrict_iff.mpr h_eqOn] + +open LinearMap.FiniteRangeSetoid + +/-- If two linear maps `u, v : E → F` differ by a finite rank linear map (recall that this is +denoted `u.toLinearMap ≈ v.toLinearMap` in scope `LinearMap.FiniteRangeSetoid`), then `u` is +strict with closed range if and only if `v` is strict with closed range. + +This is [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 1, Cor. 1][bourbaki2023]. -/ +public theorem ContinuousLinearMap.isStrictMap_isClosed_range_iff_of_finiteRangeSetoid [T2Space F] + (u v : E →L[𝕜] F) (h_equiv : u.toLinearMap ≈ v.toLinearMap) : + (IsStrictMap u ∧ IsClosed (u.range : Set F)) ↔ + (IsStrictMap v ∧ IsClosed (v.range : Set F)) := by + let A := u.toLinearMap.eqLocus v.toLinearMap + have : A.CoFG := equiv_iff_eqLocus_coFG.mp h_equiv + exact ContinuousLinearMap.isStrictMap_isClosed_range_iff_of_eqOn u v A + LinearMap.eqOn_eqLocus + +end FiniteRank + +section FiniteDimQuotient + +open LinearMap.FiniteRangeSetoid + +/-- Let `u : E → F` be a continuous linear map, and `A` a *complemented* finite dimensional +subspace of `F`. Then `u` is strict with closed range if and only if the induced map `E → F ⧸ A` +is strict with closed range. + +This is [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 1, Cor. 2][bourbaki2023]. -/ +public theorem ContinuousLinearMap.isStrictMap_isClosed_range_iff_quotient [T2Space F] + (u : E →L[𝕜] F) (A : Submodule 𝕜 F) [FiniteDimensional 𝕜 A] + (A_compl : ClosedComplemented A) : + (IsStrictMap u ∧ IsClosed (u.range : Set F)) ↔ + (IsStrictMap (A.mkQL ∘L u) ∧ IsClosed ((A.mkQL ∘L u).range : Set (F ⧸ A))) := by + obtain ⟨S, A_compl_S⟩ := A_compl.exists_isTopCompl + let Φ : (F ⧸ A) ≃L[𝕜] S := A.quotientEquivOfIsTopCompl S A_compl_S + let i : S →L[𝕜] F := S.subtypeL + have i_clemb : IsClosedEmbedding i := S.isClosedEmbedding_subtypeL A_compl_S.symm.isClosed + set p : F →L[𝕜] F := S.projectionL A A_compl_S.symm with p_def + have eq : i ∘ Φ ∘ A.mkQ = p := rfl + have : u.toLinearMap ≈ (p ∘L u).toLinearMap := by + grw [toLinearMap_comp, p_def, toLinearMap_projectionL, projection_equiv_id, LinearMap.id_comp] + calc IsStrictMap u ∧ IsClosed (range u) + _ ↔ (IsStrictMap (p ∘ u) ∧ IsClosed (range (p ∘ u))) := + ContinuousLinearMap.isStrictMap_isClosed_range_iff_of_finiteRangeSetoid _ _ this + _ ↔ (IsStrictMap (i ∘ Φ ∘ A.mkQ ∘ u) ∧ IsClosed (range (i ∘ Φ ∘ A.mkQ ∘ u))) := by + simp_rw [← eq, Function.comp_assoc] + _ ↔ (IsStrictMap (Φ ∘ A.mkQ ∘ u) ∧ IsClosed (range (Φ ∘ A.mkQ ∘ u))) := by + rw [i_clemb.isStrictMap_iff, i_clemb.isClosed_iff_image_isClosed, ← range_comp] + _ ↔ (IsStrictMap (A.mkQ ∘ u) ∧ IsClosed (range (A.mkQ ∘ u))) := by + rw [Φ.isHomeomorph.isEmbedding.isStrictMap_iff, + Φ.isHomeomorph.isClosedEmbedding.isClosed_iff_image_isClosed, + ← range_comp] + +end FiniteDimQuotient diff --git a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean index 187f8f62f3f110..384955324b6e02 100644 --- a/Mathlib/Topology/Algebra/Module/FiniteDimension.lean +++ b/Mathlib/Topology/Algebra/Module/FiniteDimension.lean @@ -66,6 +66,12 @@ variable {𝕜 E F : Type*} [AddCommGroup E] [TopologicalSpace E] [AddCommGroup F] [TopologicalSpace F] [IsTopologicalAddGroup F] +-- Note: ideally this would be in `Mathlib.Topology.Algebra.Module.Basic`, but `CoFG` imports +-- too much at the moment for this to be allowed. +instance Submodule.CoFG.topologicalClosure [Ring 𝕜] [Module 𝕜 E] [ContinuousAdd E] + [ContinuousConstSMul 𝕜 E] (s : Submodule 𝕜 E) [s.CoFG] : s.topologicalClosure.CoFG := + ‹s.CoFG›.of_le s.le_topologicalClosure + /-- The space of continuous linear maps between finite-dimensional spaces is finite-dimensional. -/ instance ContinuousLinearMap.instModuleFinite [CommRing 𝕜] [Module 𝕜 E] [Module.Finite 𝕜 E] [Module 𝕜 F] [IsNoetherian 𝕜 F] [ContinuousConstSMul 𝕜 F] : From 49b6998db5393654e0e29a78ef42956cd31a5d3b Mon Sep 17 00:00:00 2001 From: danderson70-UNL <288413551+danderson70-UNL@users.noreply.github.com> Date: Thu, 16 Jul 2026 22:25:52 +0000 Subject: [PATCH 0838/1300] doc(Algebra/Polynomial/Degree): fix typo of leading coefficient (#41833) --- Mathlib/Algebra/Polynomial/Degree/Defs.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Polynomial/Degree/Defs.lean b/Mathlib/Algebra/Polynomial/Degree/Defs.lean index 3279fb019fd69d..a4e225ff874b5c 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Defs.lean @@ -20,7 +20,7 @@ public import Mathlib.Order.SuccPred.WithBot * `Polynomial.degree`: the degree of a polynomial, where `0` has degree `⊥` * `Polynomial.natDegree`: the degree of a polynomial, where `0` has degree `0` * `Polynomial.leadingCoeff`: the leading coefficient of a polynomial -* `Polynomial.Monic`: a polynomial is monic if its leading coefficient is 0 +* `Polynomial.Monic`: a polynomial is monic if its leading coefficient is 1 * `Polynomial.nextCoeff`: the next coefficient after the leading coefficient ## Main results From 9944fe2973b8dc0b86949101ed98232c07cd54a0 Mon Sep 17 00:00:00 2001 From: danderson70-UNL <288413551+danderson70-UNL@users.noreply.github.com> Date: Thu, 16 Jul 2026 22:25:54 +0000 Subject: [PATCH 0839/1300] doc(Topology/Algebra/InfiniteSum/NatInt): change typo a+b to a*b (#41834) --- Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean index 8da2192c993191..87629f9031603f 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean @@ -375,7 +375,7 @@ lemma tprod_of_nat_of_neg_add_one [T2Space M] {f : ℤ → M} /-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` have products `a`, `b` respectively, then the `ℤ`-indexed sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...` (with `f₀` at the `0`-th position) has -product `a + b`. -/ +product `a * b`. -/ @[to_additive /-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` have sums `a`, `b` respectively, then the `ℤ`-indexed sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...` (with `f₀` at the `0`-th position) has sum `a + b`. -/] From bfefa91d21732b8ea21199657680224f37f8e748 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 03:27:10 +0000 Subject: [PATCH 0840/1300] fix(Algebra/MonoidAlgebra/Defs): rename AddMonoidAlgebra.coeff_zero_zero (#41783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yaël Dillies Co-authored-by: YaelDillies <14090593+YaelDillies@users.noreply.github.com> --- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index b404caafd7e06a..a5beaaa061b008 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -468,9 +468,12 @@ instance one : One R[M] where one := single 1 1 @[to_additive (dont_translate := R) one_def] lemma one_def : (1 : R[M]) = single 1 1 := rfl -@[to_additive (attr := simp) (dont_translate := R)] +@[to_additive (attr := simp) (dont_translate := R) coeff_one_zero] lemma coeff_one_one : (1 : R[M]).coeff 1 = 1 := by simp [one_def] +@[deprecated (since := "2026-07-15")] +alias _root_.AddMonoidAlgebra.coeff_zero_zero := AddMonoidAlgebra.coeff_one_zero + end One section Mul From fd1d54bcac5caba4eff2ea3421c47d907333f515 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 04:15:58 +0000 Subject: [PATCH 0841/1300] chore: update Mathlib dependencies 2026-07-17 (#41848) This PR updates the Mathlib dependencies. --- .github/actions/get-mathlib-ci/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 2cb8b3a47631b1..13211f6af6e32d 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -10,7 +10,7 @@ inputs: # Default pinned commit used by workflows unless they explicitly override. # Update this ref as needed to pick up changes to mathlib-ci scripts # This is also updated automatically by .github/workflows/update_dependencies.yml - default: 0cd6cbc879d9241f3b4f6cb7e8291e34128c5654 + default: 20a1db8d1e1017676558fe4f5bbea77ee9f0a257 path: description: Checkout destination path. required: false From fe1bd79fc429bd70ba5de37eac27c2e11baa8219 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:51:11 +0000 Subject: [PATCH 0842/1300] chore: update Mathlib dependencies 2026-07-17 (#41853) This PR updates the Mathlib dependencies. --- .github/actions/get-mathlib-ci/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 13211f6af6e32d..ef96111a926264 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -10,7 +10,7 @@ inputs: # Default pinned commit used by workflows unless they explicitly override. # Update this ref as needed to pick up changes to mathlib-ci scripts # This is also updated automatically by .github/workflows/update_dependencies.yml - default: 20a1db8d1e1017676558fe4f5bbea77ee9f0a257 + default: 5668fbbccf0fecefdfcddf539b8406db197dfc59 path: description: Checkout destination path. required: false From f3c143a862db06e8b9ffb382c69285ebc2d3e821 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Fri, 17 Jul 2026 09:00:19 +0000 Subject: [PATCH 0843/1300] ci: zulip emoji reconciliation sweep (#41852) This PR adds a workflow that uses the action added in https://github.com/leanprover-community/mathlib-ci/pull/53 to ensure that zulip emoji reactions do not become stale. (See the [docs](https://github.com/leanprover-community/mathlib-ci/blob/master/docs/zulip-emoji-reconcile.md) for more detail.) This action has been tested on the `ci-dev/zulip-emoji-reconcile` branch, which led to some fixes getting merged in https://github.com/leanprover-community/mathlib-ci/pull/61. (See that PR for links to the specific workflow runs.) In a later PR we will replace the existing legacy zulip emoji reaction workflows with additional `pull_request`, `workflow_run`, etc. triggers on this workflow. Generated with Claude code. --- .github/workflows/zulip_emoji_reconcile.yml | 45 +++++++++++++++ .github/zulip-emoji-config.json | 63 +++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 .github/workflows/zulip_emoji_reconcile.yml create mode 100644 .github/zulip-emoji-config.json diff --git a/.github/workflows/zulip_emoji_reconcile.yml b/.github/workflows/zulip_emoji_reconcile.yml new file mode 100644 index 00000000000000..ddc3f36959d1d3 --- /dev/null +++ b/.github/workflows/zulip_emoji_reconcile.yml @@ -0,0 +1,45 @@ +# Periodic safety net that keeps the Zulip emoji reactions on PR-related messages +# in sync with each PR's actual state (open/closed/merged, labels, CI result). +# The event-driven zulip_emoji_* workflows react to individual label/close/CI +# events; this sweep repairs any drift they miss (dropped webhooks, outages, +# state changes while a workflow was broken). See +# https://github.com/leanprover-community/mathlib-ci/blob/master/docs/zulip-emoji-reconcile.md +name: Zulip emoji reconcile + +on: + schedule: + - cron: "37 * * * *" # hourly, offset to dodge top-of-hour runner load + workflow_dispatch: + inputs: + dry-run: + description: Log planned reaction changes without modifying Zulip + type: boolean + default: false + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +permissions: + contents: read + pull-requests: read + +jobs: + reconcile: + if: github.repository == 'leanprover-community/mathlib4' + runs-on: ubuntu-latest + steps: + - name: Check out reconcile config + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + sparse-checkout: .github/zulip-emoji-config.json + sparse-checkout-cone-mode: false + + - name: Reconcile + uses: leanprover-community/mathlib-ci/.github/actions/zulip-emoji-reconcile@5668fbbccf0fecefdfcddf539b8406db197dfc59 + with: + config: .github/zulip-emoji-config.json + sweep: true + dry-run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry-run }} + zulip-api-key: ${{ secrets.ZULIP_API_KEY }} + github-token: ${{ github.token }} diff --git a/.github/zulip-emoji-config.json b/.github/zulip-emoji-config.json new file mode 100644 index 00000000000000..cf74f5bc472135 --- /dev/null +++ b/.github/zulip-emoji-config.json @@ -0,0 +1,63 @@ +{ + "_comment": "Config for the zulip-emoji-reconcile action (see .github/workflows/zulip_emoji_reconcile.yml), which keeps Zulip emoji reactions in sync with PR state. Format and semantics: https://github.com/leanprover-community/mathlib-ci/blob/master/docs/zulip-emoji-reconcile.md. Derived from scripts/zulip/examples/mathlib4-config.json in that repo; keep the two in sync when the emoji table changes.", + + "github_repo": "leanprover-community/mathlib4", + + "_merged_comment": "bors merges by rebasing a PR's commits onto master, so GitHub reports the PR as CLOSED (not merged) and renames its title to start with '[Merged by Bors] -'. Treat such closed PRs as merged so they get the 'merge' emoji rather than 'closed-pr'. Drop this key for repos that merge via the GitHub merge button/queue, where the PR state is reported as MERGED directly.", + "merged_title_prefix": "[Merged by Bors] -", + + "zulip": { + "site": "https://leanprover.zulipchat.com", + "email": "github-mathlib4-bot@leanprover.zulipchat.com" + }, + + "channels": { + "pr_reviews": "PR reviews", + "reviewers": "mathlib reviewers", + "rss_allow": ["mathlib bors notifications"] + }, + + "ci": { + "_comment": "Case-insensitive substring match against check-run name, workflow name, or status context. The first three select the gating jobs of 'continuous integration' / 'continuous integration (mathlib forks)' -- their check runs are named 'ci / Build', 'ci (fork) / Build', etc. -- while leaving auxiliary jobs (Upload to cache, Post-CI job) out of the emoji. 'Check workflows' is the actionlint workflow: it runs only on PRs touching .github/**, so it contributes nothing on ordinary PRs and becomes the CI signal on workflows-only PRs where the main CI never triggers.", + "check_names": ["Build", "Lint style", "Post-Build Step", "Check workflows"] + }, + + "states": [ + { + "name": "merged", "group": "pr", "priority": 30, + "source": {"state": "merged"}, "emoji": "merge" + }, + { + "name": "closed", "group": "pr", "priority": 20, + "source": {"state": "closed"}, + "emoji": "closed-pr", "emoji_code": "61293", "reaction_type": "realm_emoji" + }, + { + "name": "ready-to-merge", "group": "pr", "priority": 12, + "source": {"label": "ready-to-merge"}, + "emoji": "bors", "emoji_code": "22134", "reaction_type": "realm_emoji" + }, + { + "name": "delegated", "group": "pr", "priority": 11, + "source": {"label": "delegated"}, "emoji": "peace_sign" + }, + { + "name": "awaiting-author", "group": "pr", "priority": 10, + "source": {"label": "awaiting-author"}, "emoji": "writing" + }, + + {"name": "ci-running", "group": "ci", "source": {"ci": "running"}, "emoji": "yellow"}, + {"name": "ci-success", "group": "ci", "source": {"ci": "success"}, "emoji": "check"}, + {"name": "ci-failure", "group": "ci", "source": {"ci": "failure"}, "emoji": "cross_mark"}, + + { + "name": "maintainer-merge", "group": null, + "source": {"label": "maintainer-merge"}, "emoji": "hammer", + "suppress_in": {"channel": "reviewers", "subject_prefix": "maintainer merge"} + }, + { + "name": "migrated", "group": null, "sticky": true, + "source": {"label": "migrated-from-branch"}, "emoji": "skip_forward" + } + ] +} From 2eb08ab8c9be0180ce78d703513eb713e25ddf53 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 17 Jul 2026 09:19:33 +0000 Subject: [PATCH 0844/1300] chore(Data/Prod/Lex): remove `backward.isDefEq.respectTransparency` (#41838) Clean up some `respectTransparency` tech debt. --- Mathlib/Data/Prod/Lex.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/Prod/Lex.lean b/Mathlib/Data/Prod/Lex.lean index f9e878f282b413..dee018f50a0c41 100644 --- a/Mathlib/Data/Prod/Lex.lean +++ b/Mathlib/Data/Prod/Lex.lean @@ -181,13 +181,11 @@ theorem _root_.lexOrd_eq [Ord α] [Ord β] : @lexOrd α β _ _ = instOrdLexProd theorem _root_.Ord.lex_eq [oα : Ord α] [oβ : Ord β] : Ord.lex oα oβ = instOrdLexProd := rfl -set_option backward.isDefEq.respectTransparency false in instance [Ord α] [Ord β] [Std.OrientedOrd α] [Std.OrientedOrd β] : Std.OrientedOrd (α ×ₗ β) := - inferInstanceAs (Std.OrientedCmp (compareLex _ _)) + inferInstanceAs (@Std.OrientedCmp (α × β) (compareLex _ _)) -set_option backward.isDefEq.respectTransparency false in instance [Ord α] [Ord β] [Std.TransOrd α] [Std.TransOrd β] : Std.TransOrd (α ×ₗ β) := - inferInstanceAs (Std.TransCmp (compareLex _ _)) + inferInstanceAs (@Std.TransCmp (α × β) (compareLex _ _)) /-- Dictionary / lexicographic linear order for pairs. -/ instance instLinearOrder (α β : Type*) [LinearOrder α] [LinearOrder β] : LinearOrder (α ×ₗ β) where From d99d52c36bea862ef9499bfaef386d0bcba9ea48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 17 Jul 2026 09:57:53 +0000 Subject: [PATCH 0845/1300] chore(Data): rename `setOf` to `Set.ofPred` (#41507) This is in prevision of making `Set` a one-field structure. `ofPred` will then be the constructor. Generated by Claude Opus then reviewed line-by-line by myself. Assisted-by: Claude Opus 4.8 --- Archive/Imo/Imo1987Q1.lean | 2 +- Archive/Imo/Imo1988Q6.lean | 4 +- Archive/Imo/Imo2008Q2.lean | 4 +- Archive/Imo/Imo2024Q3.lean | 146 +++++++++----- Archive/Imo/Imo2024Q5.lean | 2 +- Archive/Sensitivity.lean | 2 +- Archive/Wiedijk100Theorems/AreaOfACircle.lean | 2 +- Archive/Wiedijk100Theorems/BallotProblem.lean | 6 +- .../Wiedijk100Theorems/BirthdayProblem.lean | 2 +- Archive/Wiedijk100Theorems/CubingACube.lean | 14 +- Archive/Wiedijk100Theorems/Konigsberg.lean | 6 +- Archive/ZagierTwoSquares.lean | 14 +- Counterexamples/AharoniKorman.lean | 14 +- Counterexamples/Phillips.lean | 8 +- .../SeparableNotSecondCountable.lean | 2 +- Counterexamples/SorgenfreyLine.lean | 4 +- Mathlib/Algebra/AffineMonoid/Irreducible.lean | 2 +- .../Algebra/Algebra/NonUnitalSubalgebra.lean | 8 +- Mathlib/Algebra/Algebra/Spectrum/Basic.lean | 7 +- Mathlib/Algebra/Algebra/Spectrum/Pi.lean | 9 +- .../Algebra/Spectrum/Quasispectrum.lean | 6 +- Mathlib/Algebra/Algebra/Subalgebra/Basic.lean | 10 +- Mathlib/Algebra/BigOperators/Associated.lean | 4 +- Mathlib/Algebra/Category/Ring/Topology.lean | 2 +- Mathlib/Algebra/FiniteSupport/Basic.lean | 2 +- .../Group/Action/Pointwise/Set/Basic.lean | 10 +- Mathlib/Algebra/Group/Center.lean | 2 +- .../Algebra/Group/Pointwise/Set/Basic.lean | 5 +- Mathlib/Algebra/Group/Subgroup/Basic.lean | 2 +- Mathlib/Algebra/Group/Subgroup/Lattice.lean | 2 +- .../Group/Subgroup/MulOppositeLemmas.lean | 2 +- Mathlib/Algebra/Group/Submonoid/Basic.lean | 10 +- Mathlib/Algebra/Group/Submonoid/Defs.lean | 2 +- .../Algebra/Group/Submonoid/MulOpposite.lean | 2 +- .../Group/Subsemigroup/MulOpposite.lean | 2 +- .../GroupWithZero/NonZeroDivisors.lean | 4 +- .../HomComplexCohomology.lean | 4 +- .../Homology/HomotopyCategory/KInjective.lean | 2 +- Mathlib/Algebra/Lie/Abelian.lean | 2 +- Mathlib/Algebra/Lie/Basis.lean | 6 +- Mathlib/Algebra/Lie/Character.lean | 2 +- Mathlib/Algebra/Lie/IdealOperations.lean | 2 +- Mathlib/Algebra/Lie/InvariantForm.lean | 6 +- Mathlib/Algebra/Lie/LieTheorem.lean | 2 +- Mathlib/Algebra/Lie/Nilpotent.lean | 2 +- Mathlib/Algebra/Lie/Semisimple/Basic.lean | 2 +- Mathlib/Algebra/Lie/Solvable.lean | 2 +- Mathlib/Algebra/Lie/Subalgebra.lean | 2 +- Mathlib/Algebra/Lie/Submodule.lean | 4 +- Mathlib/Algebra/Lie/Weights/Basic.lean | 10 +- Mathlib/Algebra/Lie/Weights/Cartan.lean | 4 +- Mathlib/Algebra/Lie/Weights/Killing.lean | 2 +- .../Algebra/Module/Submodule/Invariant.lean | 2 +- Mathlib/Algebra/Module/ZLattice/Basic.lean | 12 +- Mathlib/Algebra/Module/ZLattice/Covolume.lean | 2 +- Mathlib/Algebra/Notation/Support.lean | 2 +- Mathlib/Algebra/Order/Antidiag/Nat.lean | 2 +- .../Order/Archimedean/IndicatorCard.lean | 2 +- Mathlib/Algebra/Order/CompleteField.lean | 4 +- Mathlib/Algebra/Order/Group/Ideal.lean | 6 +- .../Order/Group/Pointwise/Interval.lean | 2 +- .../Algebra/Order/GroupWithZero/Basic.lean | 2 +- Mathlib/Algebra/Order/Quantale.lean | 4 +- Mathlib/Algebra/Order/Rearrangement.lean | 2 +- Mathlib/Algebra/Order/Ring/Int.lean | 2 +- Mathlib/Algebra/Order/Ring/Nat.lean | 2 +- Mathlib/Algebra/Order/ToIntervalMod.lean | 2 +- Mathlib/Algebra/Polynomial/Basic.lean | 7 +- Mathlib/Algebra/Polynomial/EraseLead.lean | 2 +- Mathlib/Algebra/Polynomial/Roots.lean | 12 +- Mathlib/Algebra/Ring/Submonoid/Pointwise.lean | 2 +- Mathlib/Algebra/Ring/Subring/MulOpposite.lean | 2 +- .../Algebra/Ring/Subsemiring/MulOpposite.lean | 2 +- Mathlib/Algebra/Star/Center.lean | 2 +- Mathlib/Algebra/Star/Unitary.lean | 2 +- Mathlib/AlgebraicGeometry/AffineScheme.lean | 4 +- .../AlgebraicGeometry/Morphisms/Affine.lean | 10 +- .../Morphisms/FinitePresentation.lean | 2 +- .../Morphisms/Preimmersion.lean | 2 +- .../ProjectiveSpectrum/Topology.lean | 2 +- .../SimplicialSet/Boundary.lean | 4 +- .../SimplicialSet/Degenerate.lean | 2 +- .../AlgebraicTopology/SimplicialSet/Horn.lean | 2 +- .../SimplicialSet/Monoidal.lean | 2 +- .../SimplicialSet/Simplices.lean | 2 +- .../SimplicialSet/StdSimplex.lean | 4 +- Mathlib/Analysis/Analytic/CPolynomialDef.lean | 2 +- Mathlib/Analysis/Analytic/Composition.lean | 2 +- Mathlib/Analysis/Analytic/Constructions.lean | 2 +- Mathlib/Analysis/Analytic/Inverse.lean | 12 +- Mathlib/Analysis/Analytic/Order.lean | 21 +- Mathlib/Analysis/Analytic/Uniqueness.lean | 2 +- Mathlib/Analysis/Asymptotics/Defs.lean | 2 +- Mathlib/Analysis/Asymptotics/Lemmas.lean | 4 +- Mathlib/Analysis/BoxIntegral/Basic.lean | 6 +- .../Analysis/BoxIntegral/Partition/Basic.lean | 9 +- .../BoxIntegral/Partition/Filter.lean | 6 +- .../Analysis/BoxIntegral/Partition/Split.lean | 6 +- .../Analysis/BoxIntegral/UnitPartition.lean | 4 +- .../ContinuousFunctionalCalculus/Commute.lean | 4 +- .../Continuity.lean | 8 +- .../ContinuousFunctionalCalculus/Order.lean | 5 +- .../ContinuousFunctionalCalculus/Range.lean | 10 +- .../ContinuousFunctionalCalculus/Unitary.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Extreme.lean | 8 +- Mathlib/Analysis/CStarAlgebra/Multiplier.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Spectrum.lean | 4 +- .../CStarAlgebra/Unitary/Connected.lean | 4 +- .../Calculus/BumpFunction/SmoothApprox.lean | 9 +- Mathlib/Analysis/Calculus/Deriv/Inv.lean | 2 +- .../Analysis/Calculus/FDeriv/Measurable.lean | 4 +- .../Analysis/Calculus/FDeriv/Symmetric.lean | 2 +- .../Analysis/Calculus/LineDeriv/Basic.lean | 6 +- .../Analysis/Calculus/ParametricIntegral.lean | 4 +- Mathlib/Analysis/Calculus/SmoothSeries.lean | 2 +- .../Analysis/Calculus/TangentCone/Basic.lean | 8 +- .../Analysis/Calculus/TangentCone/Defs.lean | 2 +- .../Analysis/Calculus/TangentCone/Seq.lean | 2 +- Mathlib/Analysis/Complex/AbelLimit.lean | 10 +- Mathlib/Analysis/Complex/AbsMax.lean | 9 +- Mathlib/Analysis/Complex/Basic.lean | 4 +- .../Analysis/Complex/BorelCaratheodory.lean | 2 +- Mathlib/Analysis/Complex/Convex.lean | 4 +- .../Analysis/Complex/Harmonic/Analytic.lean | 4 +- .../Analysis/Complex/Harmonic/MeanValue.lean | 2 +- .../Analysis/Complex/Harmonic/Poisson.lean | 2 +- Mathlib/Analysis/Complex/OpenMapping.lean | 2 +- .../Analysis/Complex/PhragmenLindelof.lean | 6 +- Mathlib/Analysis/Complex/ReImTopology.lean | 92 +++++++-- Mathlib/Analysis/Convex/Basic.lean | 4 +- Mathlib/Analysis/Convex/Caratheodory.lean | 4 +- Mathlib/Analysis/Convex/Combination.lean | 6 +- Mathlib/Analysis/Convex/Continuous.lean | 2 +- Mathlib/Analysis/Convex/Deriv.lean | 4 +- .../Convex/DoublyStochasticMatrix.lean | 2 +- Mathlib/Analysis/Convex/Extrema.lean | 4 +- Mathlib/Analysis/Convex/FunctionTopology.lean | 18 +- Mathlib/Analysis/Convex/Gauge.lean | 75 ++++--- Mathlib/Analysis/Convex/Integral.lean | 4 +- Mathlib/Analysis/Convex/Intrinsic.lean | 4 +- Mathlib/Analysis/Convex/Quasiconvex.lean | 6 +- Mathlib/Analysis/Convex/Segment.lean | 8 +- Mathlib/Analysis/Convex/Side.lean | 87 +++++--- .../AffineIndependentUnion.lean | 4 +- Mathlib/Analysis/Convex/StdSimplex.lean | 2 +- Mathlib/Analysis/Distribution/Support.lean | 2 +- .../Distribution/TemperateGrowth.lean | 4 +- .../Fourier/RiemannLebesgueLemma.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Defs.lean | 2 +- .../InnerProductSpace/Harmonic/Basic.lean | 4 +- .../InnerProductSpace/LinearPMap.lean | 6 +- .../InnerProductSpace/MeanErgodic.lean | 2 +- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 6 +- .../Analysis/InnerProductSpace/l2Space.lean | 2 +- .../Analysis/LocallyConvex/AbsConvexOpen.lean | 2 +- .../LocallyConvex/BalancedCoreHull.lean | 2 +- Mathlib/Analysis/LocallyConvex/Bounded.lean | 4 +- Mathlib/Analysis/LocallyConvex/Polar.lean | 17 +- .../Analysis/LocallyConvex/Separation.lean | 6 +- .../Analysis/LocallyConvex/WithSeminorms.lean | 2 +- Mathlib/Analysis/Matrix/Order.lean | 2 +- Mathlib/Analysis/MeanInequalities.lean | 2 +- Mathlib/Analysis/Meromorphic/Basic.lean | 2 +- Mathlib/Analysis/Meromorphic/Divisor.lean | 6 +- .../Analysis/Meromorphic/IsolatedZeros.lean | 14 +- Mathlib/Analysis/Meromorphic/NormalForm.lean | 2 +- Mathlib/Analysis/Meromorphic/Order.lean | 29 ++- .../Normed/Affine/AddTorsorBases.lean | 8 +- .../Analysis/Normed/Algebra/GelfandMazur.lean | 4 +- .../Normed/Algebra/MatrixExponential.lean | 2 +- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 2 +- Mathlib/Analysis/Normed/Field/Lemmas.lean | 2 +- Mathlib/Analysis/Normed/Group/Basic.lean | 2 +- .../Analysis/Normed/Group/InfiniteSum.lean | 2 +- .../Analysis/Normed/Group/NullSubmodule.lean | 2 +- Mathlib/Analysis/Normed/Group/Quotient.lean | 4 +- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 4 +- Mathlib/Analysis/Normed/Module/Connected.lean | 6 +- Mathlib/Analysis/Normed/Module/Convex.lean | 10 +- .../Normed/Module/FiniteDimension.lean | 21 +- .../Normed/Module/Multilinear/Basic.lean | 2 +- .../PiTensorProduct/InjectiveSeminorm.lean | 10 +- Mathlib/Analysis/Normed/Module/WeakDual.lean | 2 +- Mathlib/Analysis/Normed/Operator/Basic.lean | 2 +- .../Normed/Operator/Compact/Basic.lean | 11 +- Mathlib/Analysis/Normed/Operator/NNNorm.lean | 4 +- Mathlib/Analysis/Normed/Order/Lattice.lean | 2 +- .../Normed/Unbundled/SmoothingSeminorm.lean | 12 +- Mathlib/Analysis/ODE/PicardLindelof.lean | 4 +- Mathlib/Analysis/ODE/Transform.lean | 4 +- Mathlib/Analysis/PSeries.lean | 4 +- Mathlib/Analysis/Polynomial/Basic.lean | 8 +- .../Analysis/Polynomial/MahlerMeasure.lean | 8 +- Mathlib/Analysis/RCLike/Basic.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 16 +- .../Analysis/SpecialFunctions/Bernstein.lean | 3 +- .../SpecialFunctions/Complex/Log.lean | 4 +- .../ExpLog/Order.lean | 4 +- Mathlib/Analysis/SpecialFunctions/Exp.lean | 2 +- .../Integrals/PosLogEqCircleAverage.lean | 4 +- .../SpecialFunctions/JapaneseBracket.lean | 2 +- .../Analysis/SpecialFunctions/Log/Deriv.lean | 2 +- .../SpecialFunctions/Log/Monotone.lean | 2 +- .../SpecialFunctions/NonIntegrable.lean | 2 +- .../Analysis/SpecialFunctions/PolarCoord.lean | 4 +- .../Trigonometric/Arctan.lean | 2 +- .../Trigonometric/Bounds.lean | 2 +- Mathlib/Analysis/SumOverResidueClass.lean | 8 +- .../Abelian/Injective/Dimension.lean | 4 +- .../Abelian/Projective/Dimension.lean | 4 +- Mathlib/CategoryTheory/Galois/Topology.lean | 4 +- .../CategoryTheory/Groupoid/Subgroupoid.lean | 8 +- .../MorphismProperty/Basic.lean | 2 +- Mathlib/CategoryTheory/Sites/Closed.lean | 10 +- .../Sites/Coherent/Comparison.lean | 2 +- .../Sites/Coherent/RegularSheaves.lean | 2 +- Mathlib/CategoryTheory/Sites/Coverage.lean | 2 +- .../Sites/PrecoverageToGrothendieck.lean | 2 +- .../CategoryTheory/Subfunctor/Equalizer.lean | 2 +- .../CategoryTheory/Subfunctor/OfSection.lean | 4 +- .../Additive/CauchyDavenport.lean | 2 +- .../Combinatorics/Additive/Dissociation.lean | 2 +- Mathlib/Combinatorics/Compactness.lean | 2 +- Mathlib/Combinatorics/Configuration.lean | 2 +- .../Enumerative/Composition.lean | 4 +- Mathlib/Combinatorics/Graph/Basic.lean | 7 +- Mathlib/Combinatorics/Graph/Delete.lean | 2 +- Mathlib/Combinatorics/Graph/Lattice.lean | 2 +- Mathlib/Combinatorics/Hindman.lean | 2 +- Mathlib/Combinatorics/Matroid/Basic.lean | 32 ++- Mathlib/Combinatorics/Matroid/Circuit.lean | 4 +- Mathlib/Combinatorics/Matroid/Closure.lean | 19 +- Mathlib/Combinatorics/Matroid/Dual.lean | 6 +- Mathlib/Combinatorics/Matroid/Loop.lean | 14 +- .../Combinatorics/Matroid/Minor/Restrict.lean | 5 +- .../Combinatorics/Quiver/Path/Vertices.lean | 2 +- Mathlib/Combinatorics/Schnirelmann.lean | 35 +++- Mathlib/Combinatorics/SetFamily/Shatter.lean | 2 +- .../Combinatorics/SimpleGraph/Bipartite.lean | 10 +- .../SimpleGraph/Coloring/EdgeLabeling.lean | 2 +- .../SimpleGraph/Coloring/Vertex.lean | 10 +- .../SimpleGraph/Connectivity/Connected.lean | 2 +- .../SimpleGraph/Connectivity/Finite.lean | 2 +- .../SimpleGraph/Connectivity/Subgraph.lean | 22 +-- .../SimpleGraph/DeleteEdges.lean | 2 +- .../Combinatorics/SimpleGraph/Ends/Defs.lean | 4 +- .../SimpleGraph/Hamiltonian.lean | 7 +- .../Combinatorics/SimpleGraph/LapMatrix.lean | 2 +- .../Combinatorics/SimpleGraph/Matching.lean | 4 +- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 24 +-- .../SimpleGraph/Triangle/Basic.lean | 4 +- .../SimpleGraph/Walk/Counting.lean | 26 ++- Mathlib/Computability/DFA.lean | 4 +- Mathlib/Computability/NFA.lean | 8 +- Mathlib/Computability/Reduce.lean | 2 +- Mathlib/Condensed/TopComparison.lean | 9 +- Mathlib/Data/Analysis/Filter.lean | 2 +- Mathlib/Data/DFinsupp/WellFounded.lean | 8 +- Mathlib/Data/ENNReal/Inv.lean | 2 +- Mathlib/Data/ENNReal/Operations.lean | 2 +- Mathlib/Data/Fin/Tuple/Embedding.lean | 2 +- Mathlib/Data/Finset/Basic.lean | 2 +- Mathlib/Data/Finset/Defs.lean | 4 +- Mathlib/Data/Finset/Image.lean | 2 +- Mathlib/Data/Finset/Sort.lean | 2 +- Mathlib/Data/Finsupp/Basic.lean | 2 +- Mathlib/Data/Finsupp/Defs.lean | 2 +- Mathlib/Data/Finsupp/Ext.lean | 9 +- Mathlib/Data/Fintype/Card.lean | 2 +- Mathlib/Data/Fintype/Sets.lean | 4 +- Mathlib/Data/Int/GCD.lean | 4 +- Mathlib/Data/List/Basic.lean | 4 +- Mathlib/Data/List/Lemmas.lean | 8 +- Mathlib/Data/List/Sym.lean | 4 +- Mathlib/Data/Multiset/Fintype.lean | 2 +- Mathlib/Data/Multiset/Sym.lean | 4 +- Mathlib/Data/Nat/Count.lean | 4 +- Mathlib/Data/Nat/Digits/Lemmas.lean | 2 +- Mathlib/Data/Nat/Factorization/Basic.lean | 5 +- Mathlib/Data/Nat/Nth.lean | 187 ++++++++++-------- Mathlib/Data/Nat/Prime/Infinite.lean | 8 +- Mathlib/Data/Nat/PrimeFin.lean | 8 +- Mathlib/Data/PFunctor/Multivariate/Basic.lean | 2 +- Mathlib/Data/PFunctor/Univariate/Basic.lean | 2 +- Mathlib/Data/Prod/TProd.lean | 2 +- Mathlib/Data/QPF/Multivariate/Basic.lean | 2 +- Mathlib/Data/Real/Embedding.lean | 6 +- Mathlib/Data/Set/Basic.lean | 82 ++++++-- Mathlib/Data/Set/Card.lean | 6 +- Mathlib/Data/Set/Countable.lean | 16 +- Mathlib/Data/Set/Defs.lean | 27 +-- Mathlib/Data/Set/Finite/Basic.lean | 6 +- Mathlib/Data/Set/Finite/Lattice.lean | 2 +- Mathlib/Data/Set/Finite/Lemmas.lean | 2 +- Mathlib/Data/Set/Image.lean | 14 +- Mathlib/Data/Set/Insert.lean | 20 +- Mathlib/Data/Set/Lattice.lean | 18 +- Mathlib/Data/Set/List.lean | 2 +- Mathlib/Data/Set/MemPartition.lean | 2 +- Mathlib/Data/Set/Operations.lean | 28 ++- Mathlib/Data/Set/Order.lean | 8 +- Mathlib/Data/Set/Pairwise/Basic.lean | 6 +- Mathlib/Data/Set/Pairwise/List.lean | 2 +- Mathlib/Data/Set/PowersetCard.lean | 2 +- Mathlib/Data/Set/Prod.lean | 4 +- Mathlib/Data/Set/Subset.lean | 2 +- Mathlib/Data/SetLike/Basic.lean | 4 +- Mathlib/Data/Setoid/Partition.lean | 2 +- Mathlib/Data/Sym/Sym2.lean | 9 +- Mathlib/Data/ZMod/Basic.lean | 2 +- Mathlib/Dynamics/BirkhoffSum/NormedSpace.lean | 7 +- .../Dynamics/Ergodic/Action/OfMinimal.lean | 34 +++- Mathlib/Dynamics/Ergodic/Conservative.lean | 4 +- Mathlib/Dynamics/SymbolicDynamics/Basic.lean | 5 +- .../DynamicalEntourage.lean | 2 +- .../TopologicalEntropy/NetEntropy.lean | 8 +- Mathlib/FieldTheory/AxGrothendieck.lean | 2 +- Mathlib/FieldTheory/CardinalEmb.lean | 4 +- Mathlib/FieldTheory/Extension.lean | 2 +- Mathlib/FieldTheory/Finite/Polynomial.lean | 2 +- .../Euclidean/Angle/Oriented/Affine.lean | 18 +- .../Geometry/Group/Growth/QuotientInter.lean | 2 +- Mathlib/Geometry/Manifold/Instances/Real.lean | 18 +- .../Geometry/Manifold/Instances/Sphere.lean | 3 +- .../Manifold/IntegralCurve/ExistUnique.lean | 4 +- .../Manifold/IntegralCurve/Transform.lean | 4 +- .../Manifold/IntegralCurve/UniformTime.lean | 2 +- .../Geometry/Manifold/IsManifold/Basic.lean | 2 +- .../Manifold/LocalInvariantProperties.lean | 2 +- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 4 +- .../Geometry/Manifold/PartitionOfUnity.lean | 2 +- .../Geometry/Manifold/Riemannian/Basic.lean | 21 +- Mathlib/Geometry/Manifold/SmoothApprox.lean | 2 +- .../Geometry/Manifold/StructureGroupoid.lean | 6 +- .../VectorBundle/ContMDiffSection.lean | 6 +- .../VectorBundle/FiberwiseLinear.lean | 2 +- .../VectorBundle/MDifferentiable.lean | 4 +- .../RingedSpace/LocallyRingedSpace.lean | 2 +- Mathlib/GroupTheory/Archimedean.lean | 2 +- Mathlib/GroupTheory/ArchimedeanDensely.lean | 62 ++++-- Mathlib/GroupTheory/ClassEquation.lean | 2 +- Mathlib/GroupTheory/Commensurable.lean | 6 +- Mathlib/GroupTheory/CommutingProbability.lean | 4 +- Mathlib/GroupTheory/Coset/Basic.lean | 2 +- Mathlib/GroupTheory/CosetCover.lean | 2 +- Mathlib/GroupTheory/Finiteness.lean | 8 +- Mathlib/GroupTheory/FreeGroup/Orbit.lean | 6 +- Mathlib/GroupTheory/HNNExtension.lean | 2 +- Mathlib/GroupTheory/Nilpotent.lean | 4 +- Mathlib/GroupTheory/Perm/Centralizer.lean | 14 +- Mathlib/GroupTheory/Perm/ClosureSwap.lean | 2 +- Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 2 +- Mathlib/GroupTheory/Perm/DomMulAct.lean | 2 +- Mathlib/GroupTheory/Perm/Finite.lean | 4 +- Mathlib/GroupTheory/Perm/List.lean | 4 +- Mathlib/GroupTheory/Perm/Support.lean | 2 +- .../SpecificGroups/Alternating.lean | 4 +- .../SpecificGroups/Alternating/KleinFour.lean | 6 +- .../SpecificGroups/Alternating/Simple.lean | 2 +- Mathlib/GroupTheory/Subgroup/Center.lean | 4 +- .../AffineSpace/Simplex/Basic.lean | 4 +- Mathlib/LinearAlgebra/Basis/Flag.lean | 2 +- Mathlib/LinearAlgebra/Basis/Submodule.lean | 2 +- Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 6 +- .../Dimension/StrongRankCondition.lean | 2 +- Mathlib/LinearAlgebra/Dual/Basis.lean | 2 +- Mathlib/LinearAlgebra/Dual/Defs.lean | 4 +- .../LinearAlgebra/ExteriorPower/Basic.lean | 4 +- .../Finsupp/LinearCombination.lean | 4 +- Mathlib/LinearAlgebra/Finsupp/Supported.lean | 2 +- .../LinearAlgebra/LinearIndependent/Defs.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Diagonal.lean | 2 +- .../Matrix/FixedDetMatrices.lean | 4 +- .../PerfectPairing/Restrict.lean | 5 +- .../LinearAlgebra/PiTensorProduct/Basic.lean | 6 +- .../Projectivization/PSL/Stabilizer.lean | 2 +- .../Projectivization/Subspace.lean | 2 +- Mathlib/LinearAlgebra/Reflection.lean | 2 +- .../LinearAlgebra/RootSystem/BaseChange.lean | 6 +- Mathlib/LinearAlgebra/RootSystem/Chain.lean | 52 +++-- .../LinearAlgebra/RootSystem/Finite/G2.lean | 4 +- .../LinearAlgebra/RootSystem/Irreducible.lean | 2 +- .../LinearAlgebra/RootSystem/OfBilinear.lean | 10 +- Mathlib/LinearAlgebra/Span/Defs.lean | 4 +- Mathlib/LinearAlgebra/SymplecticGroup.lean | 2 +- Mathlib/LinearAlgebra/Transvection/Basic.lean | 6 +- Mathlib/Logic/Embedding/Set.lean | 2 +- Mathlib/Logic/Encodable/Basic.lean | 2 +- Mathlib/Logic/Equiv/Set.lean | 7 +- .../Constructions/BorelSpace/Basic.lean | 4 +- .../Constructions/BorelSpace/Order.lean | 20 +- .../Constructions/BorelSpace/Real.lean | 2 +- .../Constructions/Cylinders.lean | 12 +- .../Constructions/HaarToSphere.lean | 2 +- .../Constructions/Polish/Basic.lean | 12 +- .../MeasureTheory/Covering/Besicovitch.lean | 10 +- .../Covering/BesicovitchVectorSpace.lean | 2 +- .../Covering/DensityTheorem.lean | 2 +- .../Covering/Differentiation.lean | 12 +- Mathlib/MeasureTheory/Covering/Vitali.lean | 2 +- .../MeasureTheory/Covering/VitaliFamily.lean | 6 +- .../Function/AEEqOfLIntegral.lean | 2 +- .../Function/AEMeasurableOrder.lean | 2 +- .../Function/AbsolutelyContinuous.lean | 12 +- .../ConditionalExpectation/AEMeasurable.lean | 4 +- .../Function/ConditionalExpectation/Real.lean | 2 +- .../Function/ConvergenceInMeasure.lean | 6 +- Mathlib/MeasureTheory/Function/Egorov.lean | 2 +- .../Function/Intersectivity.lean | 2 +- .../Function/JacobianOneDim.lean | 12 +- .../Function/L1Space/Integrable.lean | 9 +- .../Function/LpSeminorm/Indicator.lean | 2 +- .../Function/LpSeminorm/Trim.lean | 2 +- .../MeasureTheory/Function/LpSpace/Basic.lean | 2 +- .../MeasureTheory/Function/SimpleFunc.lean | 2 +- .../Function/SimpleFuncDenseLp.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 12 +- .../Function/StronglyMeasurable/Lemmas.lean | 2 +- .../Function/UniformIntegrable.lean | 24 +-- .../Group/FundamentalDomain.lean | 14 +- Mathlib/MeasureTheory/Integral/Average.lean | 10 +- .../MeasureTheory/Integral/Bochner/L1.lean | 2 +- .../MeasureTheory/Integral/Bochner/Set.lean | 6 +- .../Integral/CurveIntegral/Basic.lean | 2 +- .../Integral/FinMeasAdditive.lean | 2 +- .../AbsolutelyContinuousFun.lean | 2 +- .../Integral/IntervalIntegral/Basic.lean | 8 +- .../IntervalIntegral/DistLEIntegral.lean | 2 +- .../IntervalIntegral/FundThmCalculus.lean | 2 +- Mathlib/MeasureTheory/Integral/Layercake.lean | 2 +- .../MeasureTheory/Integral/Lebesgue/Add.lean | 4 +- .../Integral/Lebesgue/Basic.lean | 4 +- .../Integral/Lebesgue/Markov.lean | 2 +- .../Integral/LebesgueNormedSpace.lean | 2 +- .../Integral/RieszMarkovKakutani/Real.lean | 6 +- Mathlib/MeasureTheory/Integral/SetToL1.lean | 2 +- .../MeasurableSpace/Constructions.lean | 64 +++--- .../MeasurableSpace/CountablyGenerated.lean | 4 +- .../MeasureTheory/MeasurableSpace/Defs.lean | 2 +- .../MeasurableSpace/Embedding.lean | 19 +- .../MeasurableSpace/MeasurablyGenerated.lean | 2 +- .../MeasureTheory/MeasurableSpace/NCard.lean | 2 +- Mathlib/MeasureTheory/MeasurableSpace/Pi.lean | 2 +- .../MeasureTheory/Measure/AEMeasurable.lean | 4 +- Mathlib/MeasureTheory/Measure/Comap.lean | 4 +- .../Measure/ContinuousPreimage.lean | 5 +- .../Decomposition/IntegralRNDeriv.lean | 2 +- .../Measure/Decomposition/Lebesgue.lean | 2 +- .../MeasureTheory/Measure/FiniteMeasure.lean | 6 +- Mathlib/MeasureTheory/Measure/Haar/Basic.lean | 12 +- .../MeasureTheory/Measure/Haar/Extension.lean | 2 +- .../MeasureTheory/Measure/Haar/OfBasis.lean | 2 +- .../MeasureTheory/Measure/Haar/Unique.lean | 2 +- .../Measure/HasOuterApproxClosedProd.lean | 6 +- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 2 +- .../Measure/IntegralCharFun.lean | 4 +- .../MeasureTheory/Measure/Lebesgue/Basic.lean | 12 +- .../Measure/Lebesgue/VolumeOfBalls.lean | 10 +- .../Measure/LevyProkhorovMetric.lean | 6 +- .../MeasureTheory/Measure/MeasureSpace.lean | 6 +- .../Measure/ProbabilityMeasure.lean | 4 +- Mathlib/MeasureTheory/Measure/Prod.lean | 2 +- Mathlib/MeasureTheory/Measure/Prokhorov.lean | 67 +++++-- Mathlib/MeasureTheory/Measure/Restrict.lean | 14 +- Mathlib/MeasureTheory/Measure/Sub.lean | 8 +- Mathlib/MeasureTheory/Measure/SubFinite.lean | 2 +- Mathlib/MeasureTheory/Measure/Support.lean | 2 +- .../MeasureTheory/Measure/TightNormed.lean | 4 +- .../Measure/Typeclasses/SFinite.lean | 2 +- .../MeasureTheory/Measure/WithDensity.lean | 10 +- Mathlib/MeasureTheory/Order/UpperLower.lean | 4 +- Mathlib/MeasureTheory/OuterMeasure/AE.lean | 4 +- .../OuterMeasure/BorelCantelli.lean | 18 +- Mathlib/MeasureTheory/PiSystem.lean | 4 +- Mathlib/MeasureTheory/SetAlgebra.lean | 6 +- Mathlib/MeasureTheory/SetSemiring.lean | 8 +- .../VectorMeasure/AddContent.lean | 4 +- Mathlib/ModelTheory/Algebra/Field/CharP.lean | 4 +- .../Arithmetic/Presburger/Definability.lean | 22 +-- .../Presburger/Semilinear/Basic.lean | 72 ++++--- .../Presburger/Semilinear/Defs.lean | 6 +- Mathlib/ModelTheory/Definability.lean | 39 ++-- Mathlib/ModelTheory/DirectLimit.lean | 2 +- .../ModelTheory/ElementarySubstructures.lean | 2 +- Mathlib/ModelTheory/Fraisse.lean | 2 +- Mathlib/ModelTheory/Satisfiability.lean | 4 +- Mathlib/ModelTheory/Semantics.lean | 10 +- Mathlib/ModelTheory/Substructures.lean | 9 +- Mathlib/ModelTheory/Topology/Types.lean | 2 +- Mathlib/ModelTheory/Types.lean | 32 ++- Mathlib/ModelTheory/Ultraproducts.lean | 8 +- .../ArithmeticFunction/LFunction.lean | 2 +- Mathlib/NumberTheory/Chebyshev.lean | 4 +- Mathlib/NumberTheory/Cyclotomic/Basic.lean | 18 +- .../DirichletCharacter/Basic.lean | 2 +- .../EulerProduct/DirichletLSeries.lean | 2 +- Mathlib/NumberTheory/FLT/Four.lean | 2 +- .../NumberTheory/FactorisationProperties.lean | 2 +- Mathlib/NumberTheory/FermatPsp.lean | 5 +- Mathlib/NumberTheory/FrobeniusNumber.lean | 7 +- Mathlib/NumberTheory/Height/NumberField.lean | 50 +++-- Mathlib/NumberTheory/LSeries/Dirichlet.lean | 2 +- .../LSeries/DirichletContinuation.lean | 4 +- Mathlib/NumberTheory/LSeries/Injectivity.lean | 4 +- Mathlib/NumberTheory/LSeries/Positivity.lean | 2 +- Mathlib/NumberTheory/LSeries/PrimesInAP.lean | 46 +++-- .../LegendreSymbol/QuadraticChar/Basic.lean | 4 +- Mathlib/NumberTheory/LocalField/Basic.lean | 6 +- Mathlib/NumberTheory/Modular.lean | 2 +- .../ModularForms/CongruenceSubgroups.lean | 2 +- .../CanonicalEmbedding/ConvexBody.lean | 16 +- .../CanonicalEmbedding/FundamentalCone.lean | 4 +- .../CanonicalEmbedding/NormLeOne.lean | 8 +- .../CanonicalEmbedding/PolarCoord.lean | 2 +- .../NumberField/Completion/FinitePlace.lean | 2 +- .../NumberField/Completion/Ramification.lean | 4 +- .../NumberField/Cyclotomic/Basic.lean | 4 +- .../NumberField/DedekindZeta.lean | 2 +- .../NumberField/Ideal/Asymptotics.lean | 2 +- .../NumberField/InfinitePlace/Embeddings.lean | 4 +- .../InfinitePlace/Ramification.lean | 4 +- .../NumberField/ProductFormula.lean | 2 +- .../NumberField/Units/DirichletTheorem.lean | 4 +- Mathlib/NumberTheory/Padics/WithVal.lean | 4 +- Mathlib/NumberTheory/Pell.lean | 8 +- Mathlib/NumberTheory/PrimeCounting.lean | 8 +- Mathlib/NumberTheory/PrimesCongruentOne.lean | 5 +- .../RamificationInertia/Ramification.lean | 2 +- .../RamificationInertia/Valuation.lean | 2 +- Mathlib/NumberTheory/RatFunc/Ostrowski.lean | 18 +- Mathlib/NumberTheory/Rayleigh.lean | 4 +- Mathlib/NumberTheory/SmoothNumbers.lean | 2 +- Mathlib/NumberTheory/SumPrimeReciprocals.lean | 2 +- .../Transcendental/Liouville/Measure.lean | 29 ++- .../Transcendental/Liouville/Residual.lean | 25 ++- Mathlib/NumberTheory/WellApproximable.lean | 16 +- Mathlib/Order/Antichain.lean | 23 ++- Mathlib/Order/Atoms.lean | 7 +- Mathlib/Order/BooleanAlgebra/Set.lean | 4 +- Mathlib/Order/BooleanGenerators.lean | 2 +- Mathlib/Order/Bounds/Basic.lean | 2 +- Mathlib/Order/BourbakiWitt.lean | 14 +- Mathlib/Order/Circular.lean | 4 +- Mathlib/Order/Closure.lean | 7 +- Mathlib/Order/Cofinal.lean | 4 +- Mathlib/Order/CompactlyGenerated/Basic.lean | 2 +- Mathlib/Order/CompleteLattice/Chain.lean | 2 +- .../Indexed.lean | 2 +- Mathlib/Order/CountableSupClosed.lean | 2 +- Mathlib/Order/Filter/Bases/Basic.lean | 6 +- Mathlib/Order/Filter/Basic.lean | 6 +- Mathlib/Order/Filter/CardinalInter.lean | 10 +- Mathlib/Order/Filter/Cocardinal.lean | 2 +- Mathlib/Order/Filter/CountableInter.lean | 8 +- Mathlib/Order/Filter/CountablyGenerated.lean | 4 +- Mathlib/Order/Filter/Defs.lean | 4 +- Mathlib/Order/Filter/ENNReal.lean | 2 +- Mathlib/Order/Filter/Extr.lean | 2 +- Mathlib/Order/Filter/Finite.lean | 6 +- Mathlib/Order/Filter/Lift.lean | 2 +- Mathlib/Order/Filter/Partial.lean | 4 +- Mathlib/Order/Filter/Prod.lean | 2 +- Mathlib/Order/Filter/Tendsto.lean | 2 +- Mathlib/Order/Filter/TendstoCofinite.lean | 2 +- Mathlib/Order/Filter/Ultrafilter/Defs.lean | 4 +- .../Interval/Set/OrdConnectedComponent.lean | 2 +- Mathlib/Order/Interval/Set/Pi.lean | 2 +- Mathlib/Order/JordanHolder.lean | 2 +- Mathlib/Order/KonigLemma.lean | 2 +- Mathlib/Order/LiminfLimsup.lean | 16 +- Mathlib/Order/Minimal.lean | 90 +++++++-- Mathlib/Order/OmegaCompletePartialOrder.lean | 6 +- Mathlib/Order/OrderIsoNat.lean | 2 +- Mathlib/Order/PrimeSeparator.lean | 6 +- Mathlib/Order/ScottContinuity.lean | 12 +- Mathlib/Order/ScottContinuity/Prod.lean | 2 +- Mathlib/Order/SemiconjSup.lean | 2 +- Mathlib/Order/SuccPred/Tree.lean | 2 +- Mathlib/Order/UpperLower/Basic.lean | 8 +- .../BinomialRandomGraph/Defs.lean | 4 +- .../Probability/Distributions/Fernique.lean | 10 +- .../Distributions/SetBernoulli.lean | 22 +-- Mathlib/Probability/HasLaw.lean | 2 +- Mathlib/Probability/IdentDistrib.lean | 2 +- .../Probability/Independence/Integrable.lean | 2 +- .../Independence/Kernel/Indep.lean | 6 +- .../Independence/Kernel/IndepFun.lean | 2 +- .../Independence/Process/Basic.lean | 4 +- .../Kernel/Composition/CompProd.lean | 10 +- .../Kernel/Composition/MapComap.lean | 4 +- .../Kernel/Disintegration/CDFToKernel.lean | 2 +- .../Kernel/Disintegration/Density.lean | 26 +-- .../Disintegration/MeasurableStieltjes.lean | 6 +- .../Kernel/MeasurableIntegral.lean | 4 +- .../Kernel/MeasurableLIntegral.lean | 2 +- Mathlib/Probability/Kernel/RadonNikodym.lean | 10 +- .../Probability/Kernel/Representation.lean | 2 +- .../Probability/Martingale/Convergence.lean | 2 +- .../Martingale/OptionalSampling.lean | 8 +- .../Martingale/OptionalStopping.lean | 6 +- .../Probability/Martingale/Upcrossing.lean | 4 +- Mathlib/Probability/Moments/Basic.lean | 2 +- Mathlib/Probability/Moments/ComplexMGF.lean | 2 +- Mathlib/Probability/Moments/SubGaussian.lean | 2 +- .../Constructions.lean | 5 +- Mathlib/Probability/Process/HittingTime.lean | 10 +- .../Probability/Process/LocalProperty.lean | 10 +- Mathlib/Probability/Process/Stopping.lean | 86 ++++---- Mathlib/Probability/StrongLaw.lean | 2 +- Mathlib/RepresentationTheory/Invariants.lean | 2 +- Mathlib/RingTheory/Algebraic/Cardinality.lean | 2 +- .../TranscendenceBasis.lean | 4 +- Mathlib/RingTheory/Artinian/Module.lean | 14 +- Mathlib/RingTheory/Coalgebra/GroupLike.lean | 2 +- .../DedekindDomain/AdicValuation.lean | 4 +- .../DedekindDomain/Factorization.lean | 8 +- .../DedekindDomain/FiniteAdeleRing.lean | 4 +- .../DedekindDomain/Ideal/Lemmas.lean | 2 +- Mathlib/RingTheory/DedekindDomain/PID.lean | 2 +- .../RingTheory/DedekindDomain/SInteger.lean | 2 +- .../DiscreteValuationRing/Basic.lean | 31 ++- .../RingTheory/DividedPowers/DPMorphism.lean | 4 +- .../RingTheory/DividedPowers/SubDPIdeal.lean | 4 +- Mathlib/RingTheory/Extension/Generators.lean | 2 +- Mathlib/RingTheory/FiniteType.lean | 4 +- Mathlib/RingTheory/FractionalIdeal/Basic.lean | 8 +- .../GradedAlgebra/Homogeneous/Ideal.lean | 6 +- .../HomogeneousLocalization.lean | 2 +- Mathlib/RingTheory/HahnSeries/Lex.lean | 4 +- .../RingTheory/HahnSeries/Multiplication.lean | 8 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 18 +- Mathlib/RingTheory/Ideal/Colon.lean | 2 +- Mathlib/RingTheory/Ideal/Defs.lean | 2 +- .../RingTheory/Ideal/KrullsHeightTheorem.lean | 2 +- .../Ideal/MinimalPrime/Localization.lean | 2 +- .../Ideal/MinimalPrime/Noetherian.lean | 2 +- Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean | 23 ++- .../Ideal/Quotient/HasFiniteQuotients.lean | 10 +- Mathlib/RingTheory/Ideal/Span.lean | 2 +- .../RingTheory/IntegralClosure/GoingDown.lean | 2 +- Mathlib/RingTheory/Jacobson/Radical.lean | 2 +- Mathlib/RingTheory/Jacobson/Ring.lean | 4 +- Mathlib/RingTheory/KrullDimension/PID.lean | 2 +- Mathlib/RingTheory/KrullDimension/Zero.lean | 14 +- Mathlib/RingTheory/LaurentSeries.lean | 14 +- Mathlib/RingTheory/LocalIso.lean | 6 +- .../Localization/AtPrime/Basic.lean | 3 +- Mathlib/RingTheory/MvPolynomial/Basic.lean | 7 +- .../MvPolynomial/EulerIdentity.lean | 2 +- .../MvPolynomial/Symmetric/Defs.lean | 2 +- .../Symmetric/NewtonIdentities.lean | 2 +- .../MvPolynomial/WeightedHomogeneous.lean | 2 +- .../MvPowerSeries/LinearTopology.lean | 2 +- .../MvPowerSeries/Substitution.lean | 2 +- .../Noetherian/UniqueFactorizationDomain.lean | 2 +- Mathlib/RingTheory/Polynomial/Basic.lean | 2 +- Mathlib/RingTheory/Polynomial/Dickson.lean | 6 +- Mathlib/RingTheory/Polynomial/GaussNorm.lean | 4 +- .../RingTheory/Polynomial/HilbertPoly.lean | 2 +- Mathlib/RingTheory/PolynomialLaw/Basic.lean | 2 +- .../RingTheory/PowerSeries/Restricted.lean | 4 +- .../RingTheory/PowerSeries/Substitution.lean | 2 +- Mathlib/RingTheory/PrincipalIdealDomain.lean | 2 +- Mathlib/RingTheory/Regular/IsSMulRegular.lean | 2 +- Mathlib/RingTheory/RingHom/Locally.lean | 2 +- Mathlib/RingTheory/RootsOfUnity/Basic.lean | 4 +- .../RingTheory/Spectrum/Maximal/Basic.lean | 4 +- Mathlib/RingTheory/Spectrum/Prime/Basic.lean | 6 +- .../Spectrum/Prime/IsOpenComapC.lean | 2 +- .../RingTheory/Spectrum/Prime/Jacobson.lean | 4 +- .../RingTheory/Spectrum/Prime/Noetherian.lean | 4 +- .../RingTheory/Spectrum/Prime/Polynomial.lean | 2 +- .../RingTheory/Spectrum/Prime/Topology.lean | 16 +- .../UniqueFactorizationDomain/Ideal.lean | 14 +- Mathlib/RingTheory/Valuation/Archimedean.lean | 7 +- Mathlib/RingTheory/Valuation/Basic.lean | 4 +- Mathlib/RingTheory/Valuation/Integers.lean | 24 ++- .../Valuation/ValuationSubring.lean | 4 +- .../WittVector/TeichmullerSeries.lean | 2 +- Mathlib/SetTheory/Cardinal/Aleph.lean | 4 +- Mathlib/SetTheory/Cardinal/Arithmetic.lean | 2 +- Mathlib/SetTheory/Cardinal/Basic.lean | 2 +- .../Cardinal/Cofinality/Ordinal.lean | 6 +- Mathlib/SetTheory/Cardinal/HasCardinalLT.lean | 2 +- Mathlib/SetTheory/Cardinal/NatCard.lean | 4 +- Mathlib/SetTheory/Cardinal/NatCount.lean | 2 +- Mathlib/SetTheory/Cardinal/Order.lean | 4 +- Mathlib/SetTheory/Cardinal/Pigeonhole.lean | 2 +- Mathlib/SetTheory/Ordinal/Basic.lean | 2 +- Mathlib/SetTheory/Ordinal/Family.lean | 2 +- .../Ordinal/FixedPointApproximants.lean | 2 +- Mathlib/SetTheory/Ordinal/Principal.lean | 9 +- Mathlib/SetTheory/ZFC/Basic.lean | 2 +- .../Multiseries/Corecursion.lean | 2 +- Mathlib/Tactic/Translate/ToDual.lean | 3 + .../Algebra/Category/ProfiniteGrp/Basic.lean | 2 +- .../Algebra/Category/ProfiniteGrp/Limits.lean | 2 +- Mathlib/Topology/Algebra/ConstMulAction.lean | 8 +- Mathlib/Topology/Algebra/Group/Basic.lean | 18 +- .../Topology/Algebra/Group/CompactOpen.lean | 8 +- .../Algebra/Group/SubmonoidClosure.lean | 2 +- .../Topology/Algebra/InfiniteSum/Defs.lean | 2 +- .../Topology/Algebra/InfiniteSum/Order.lean | 2 +- .../Algebra/InfiniteSum/SummationFilter.lean | 4 +- .../Algebra/IsUniformGroup/Basic.lean | 4 +- .../Algebra/Module/Alternating/Topology.lean | 2 +- Mathlib/Topology/Algebra/Module/Basic.lean | 2 +- .../Algebra/Module/Multilinear/Topology.lean | 4 +- .../Algebra/Module/Spaces/CharacterSpace.lean | 4 +- .../Module/Spaces/UniformConvergenceCLM.lean | 2 +- .../Algebra/Module/UniformConvergence.lean | 2 +- Mathlib/Topology/Algebra/Monoid.lean | 22 ++- .../Topology/Algebra/Order/LiminfLimsup.lean | 4 +- Mathlib/Topology/Algebra/PontryaginDual.lean | 2 +- .../Topology/Algebra/ProperAction/Basic.lean | 12 +- .../ProperAction/CompactlyGenerated.lean | 22 ++- Mathlib/Topology/Algebra/Semigroup.lean | 2 +- Mathlib/Topology/Algebra/Support.lean | 4 +- .../ValuativeRel/ValuativeTopology.lean | 17 +- .../Algebra/Valued/LocallyCompact.lean | 22 ++- .../Topology/Algebra/Valued/NormedValued.lean | 17 +- .../Algebra/Valued/ValuationTopology.lean | 22 +-- .../Topology/Algebra/Valued/ValuativeRel.lean | 2 +- .../Topology/Algebra/Valued/ValuedField.lean | 14 +- Mathlib/Topology/Algebra/Valued/WithVal.lean | 14 +- .../Algebra/Valued/WithZeroMulInt.lean | 2 +- .../Topology/Algebra/WithZeroTopology.lean | 2 +- Mathlib/Topology/Baire/Lemmas.lean | 2 +- Mathlib/Topology/Bases.lean | 2 +- Mathlib/Topology/Category/CompHaus/Basic.lean | 2 +- .../Category/Profinite/Nobeling/Basic.lean | 4 +- .../Category/Profinite/Nobeling/Span.lean | 2 +- .../Profinite/Nobeling/Successor.lean | 10 +- .../Profinite/Nobeling/ZeroLimit.lean | 4 +- .../Category/TopCat/Limits/Konig.lean | 2 +- .../Category/TopCat/Limits/Pullbacks.lean | 2 +- Mathlib/Topology/ClopenBox.lean | 2 +- Mathlib/Topology/Closure.lean | 4 +- Mathlib/Topology/ClusterPt.lean | 6 +- Mathlib/Topology/CompactOpen.lean | 48 +++-- .../Topology/Compactification/StoneCech.lean | 4 +- Mathlib/Topology/Compactness/Compact.lean | 2 +- .../Compactness/CountablyCompact.lean | 2 +- Mathlib/Topology/Compactness/Paracompact.lean | 4 +- Mathlib/Topology/Connected/PathConnected.lean | 4 +- Mathlib/Topology/Constructible.lean | 2 +- Mathlib/Topology/Constructions.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 19 +- .../Topology/ContinuousMap/Bounded/Basic.lean | 2 +- Mathlib/Topology/ContinuousMap/Ideals.lean | 12 +- .../ContinuousMap/SecondCountableSpace.lean | 4 +- .../ContinuousMap/StoneWeierstrass.lean | 4 +- .../Topology/ContinuousMap/T0Sierpinski.lean | 2 +- Mathlib/Topology/ContinuousOn.lean | 2 +- Mathlib/Topology/DenseEmbedding.lean | 2 +- Mathlib/Topology/DiscreteQuotient.lean | 27 ++- Mathlib/Topology/DiscreteSubset.lean | 2 +- Mathlib/Topology/EMetricSpace/Basic.lean | 10 +- .../EMetricSpace/BoundedVariation.lean | 2 +- Mathlib/Topology/EMetricSpace/Defs.lean | 21 +- Mathlib/Topology/EMetricSpace/Pi.lean | 4 +- Mathlib/Topology/Filter.lean | 12 +- Mathlib/Topology/GDelta/Basic.lean | 2 +- Mathlib/Topology/GDelta/MetrizableSpace.lean | 7 +- Mathlib/Topology/Homeomorph/Defs.lean | 4 +- Mathlib/Topology/Homotopy/Lifting.lean | 2 +- .../Topology/Instances/AddCircle/Defs.lean | 13 +- .../Topology/Instances/ENNReal/Lemmas.lean | 28 ++- Mathlib/Topology/Instances/Irrational.lean | 10 +- Mathlib/Topology/Instances/Matrix.lean | 7 +- Mathlib/Topology/Irreducible.lean | 2 +- Mathlib/Topology/JacobsonSpace.lean | 2 +- Mathlib/Topology/LocalAtTarget.lean | 2 +- Mathlib/Topology/LocallyFinite.lean | 4 +- Mathlib/Topology/LocallyFinsupp.lean | 10 +- Mathlib/Topology/Maps/Basic.lean | 4 +- .../Maps/Proper/UniversallyClosed.lean | 2 +- Mathlib/Topology/MetricSpace/Algebra.lean | 2 +- Mathlib/Topology/MetricSpace/Bounded.lean | 2 +- .../Topology/MetricSpace/CantorScheme.lean | 2 +- Mathlib/Topology/MetricSpace/Closeds.lean | 4 +- Mathlib/Topology/MetricSpace/Completion.lean | 2 +- .../Topology/MetricSpace/GromovHausdorff.lean | 6 +- .../MetricSpace/GromovHausdorffRealized.lean | 4 +- Mathlib/Topology/MetricSpace/Holder.lean | 14 +- Mathlib/Topology/MetricSpace/Isometry.lean | 10 +- .../MetricSpace/PartitionOfUnity.lean | 2 +- Mathlib/Topology/MetricSpace/PiNat.lean | 14 +- .../Topology/MetricSpace/Pseudo/Basic.lean | 2 +- .../MetricSpace/Pseudo/Constructions.lean | 2 +- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 8 +- .../Topology/MetricSpace/Pseudo/Lemmas.lean | 2 +- .../MetricSpace/ThickenedIndicator.lean | 4 +- Mathlib/Topology/MetricSpace/Thickening.lean | 22 +-- .../MetricSpace/UniformConvergence.lean | 2 +- Mathlib/Topology/Metrizable/Uniformity.lean | 4 +- Mathlib/Topology/Neighborhoods.lean | 20 +- Mathlib/Topology/NhdsKer.lean | 2 +- Mathlib/Topology/NhdsWithin.lean | 2 +- Mathlib/Topology/Order.lean | 27 ++- Mathlib/Topology/Order/Basic.lean | 22 ++- .../Order/Category/FrameAdjunction.lean | 4 +- .../Topology/Order/CountableSeparating.lean | 2 +- Mathlib/Topology/Order/HullKernel.lean | 2 +- Mathlib/Topology/Order/IntermediateValue.lean | 14 +- Mathlib/Topology/Order/LeftRightLim.lean | 2 +- Mathlib/Topology/Order/LeftRightNhds.lean | 34 ++-- .../Topology/Order/LowerUpperTopology.lean | 6 +- Mathlib/Topology/Order/Monotone.lean | 30 ++- Mathlib/Topology/Order/OrderClosed.lean | 4 +- Mathlib/Topology/Order/Rolle.lean | 2 +- Mathlib/Topology/Order/ScottTopology.lean | 2 +- Mathlib/Topology/Order/WithTop.lean | 4 +- Mathlib/Topology/PartitionOfUnity.lean | 2 +- Mathlib/Topology/Perfect.lean | 2 +- Mathlib/Topology/Semicontinuity/Basic.lean | 2 +- .../Semicontinuity/Hemicontinuity.lean | 6 +- Mathlib/Topology/Semicontinuity/Lindelof.lean | 2 +- Mathlib/Topology/Separation/Basic.lean | 23 ++- .../Topology/Separation/PerfectlyNormal.lean | 2 +- Mathlib/Topology/Sets/Opens.lean | 2 +- Mathlib/Topology/Sets/VietorisTopology.lean | 86 ++++---- Mathlib/Topology/Sheaves/EtaleSpace.lean | 6 +- Mathlib/Topology/Sion.lean | 44 +++-- Mathlib/Topology/Sober.lean | 2 +- Mathlib/Topology/Spectral/Prespectral.lean | 4 +- Mathlib/Topology/UniformSpace/Basic.lean | 8 +- Mathlib/Topology/UniformSpace/Cauchy.lean | 17 +- Mathlib/Topology/UniformSpace/Closeds.lean | 28 +-- .../UniformSpace/CompactConvergence.lean | 8 +- Mathlib/Topology/UniformSpace/Completion.lean | 8 +- Mathlib/Topology/UniformSpace/Defs.lean | 2 +- .../UniformSpace/DiscreteUniformity.lean | 2 +- .../Topology/UniformSpace/Equicontinuity.lean | 5 +- Mathlib/Topology/UniformSpace/OfFun.lean | 2 +- Mathlib/Topology/UniformSpace/Path.lean | 2 +- Mathlib/Topology/UniformSpace/Pi.lean | 2 +- .../UniformSpace/ProdApproximation.lean | 2 +- .../UniformConvergenceTopology.lean | 20 +- .../UniformSpace/UniformEmbedding.lean | 2 +- .../DifferentialGeometry/Notation/Basic.lean | 14 +- MathlibTest/FinsetBuilder.lean | 20 +- docs/100.yaml | 2 +- docs/1000.yaml | 8 +- docs/undergrad.yaml | 2 +- 845 files changed, 3555 insertions(+), 2522 deletions(-) diff --git a/Archive/Imo/Imo1987Q1.lean b/Archive/Imo/Imo1987Q1.lean index f8000aa5f9b540..83dfe9fe4d4f0c 100644 --- a/Archive/Imo/Imo1987Q1.lean +++ b/Archive/Imo/Imo1987Q1.lean @@ -56,7 +56,7 @@ fixed points. -/ def fiber (k : ℕ) : Set (Perm α) := {σ : Perm α | card (fixedPoints σ) = k} -instance {k : ℕ} : Fintype (fiber α k) := inferInstanceAs <| Fintype (setOf _) +instance {k : ℕ} : Fintype (fiber α k) := inferInstanceAs <| Fintype (Set.ofPred _) @[simp] theorem mem_fiber {σ : Perm α} {k : ℕ} : σ ∈ fiber α k ↔ card (fixedPoints σ) = k := diff --git a/Archive/Imo/Imo1988Q6.lean b/Archive/Imo/Imo1988Q6.lean index d5ea683cfcae51..808ba4e04a4a8b 100644 --- a/Archive/Imo/Imo1988Q6.lean +++ b/Archive/Imo/Imo1988Q6.lean @@ -92,7 +92,7 @@ theorem constant_descent_vieta_jumping (x y : ℕ) {claim : Prop} {H : ℕ → -- Our assumptions ensure that we can then prove the claim. suffices exc : exceptional.Nonempty by -- Suppose that there exists an element in the exceptional locus. - simp only [Set.Nonempty, Prod.exists, Set.mem_setOf_eq, exceptional] at exc + simp only [Set.Nonempty, Prod.exists, Set.mem_ofPred_eq, exceptional] at exc -- Let (a,b) be such an element, and consider all the possible cases. rcases exc with ⟨a, b, hH, hb⟩ rcases hb with (_ | rfl | rfl | hB | hB) @@ -138,7 +138,7 @@ theorem constant_descent_vieta_jumping (x y : ℕ) {claim : Prop} {H : ℕ → -- This means that m_y = m, -- and the conditions H(m_x, m_y) and m_x < m_y are satisfied. simp only at mx_lt_my hHm m_eq - simp only [exceptional, hHm, Set.mem_setOf_eq, true_and] at h_base + simp only [exceptional, hHm, Set.mem_ofPred_eq, true_and] at h_base push Not at h_base -- Finally, it also means that (m_x, m_y) does not lie in the base locus, -- that m_x ≠ 0, m_x ≠ m_y, B(m_x) ≠ m_y, and B(m_x) ≠ m_x + m_y. diff --git a/Archive/Imo/Imo2008Q2.lean b/Archive/Imo/Imo2008Q2.lean index 695b32fc2160d6..682c6a3dbabf2a 100644 --- a/Archive/Imo/Imo2008Q2.lean +++ b/Archive/Imo/Imo2008Q2.lean @@ -65,7 +65,7 @@ theorem imo2008_q2b : Set.Infinite rationalSolutions := by have hW_sub_S : W ⊆ rationalSolutions := by intro s hs_in_W rw [rationalSolutions] - simp only [Set.mem_setOf_eq] at hs_in_W ⊢ + simp only [Set.mem_ofPred_eq] at hs_in_W ⊢ rcases hs_in_W with ⟨x, y, z, h₁, t, ht_gt_zero, hx_t, hy_t, hz_t⟩ use x, y, z have key_gt_zero : 0 < t ^ 2 + t + 1 := by linarith [pow_pos ht_gt_zero 2, ht_gt_zero] @@ -99,7 +99,7 @@ theorem imo2008_q2b : Set.Infinite rationalSolutions := by set z : ℚ := -t * (t + 1) with hz_def simp only [t, W, K, g, Set.mem_image, Prod.exists] use x, y, z; constructor - · simp only [Set.mem_setOf_eq] + · simp only [Set.mem_ofPred_eq] use x, y, z; constructor · rfl · use t; constructor diff --git a/Archive/Imo/Imo2024Q3.lean b/Archive/Imo/Imo2024Q3.lean index 2c51652ba0ffd4..58c57b4dab2cd0 100644 --- a/Archive/Imo/Imo2024Q3.lean +++ b/Archive/Imo/Imo2024Q3.lean @@ -160,7 +160,7 @@ lemma apply_add_one_ne_of_apply_eq {i j : ℕ} (hi : N ≤ i) (hj : N ≤ j) (hi hij.lt_or_gt.elim (fun h ↦ (hc.apply_add_one_lt_of_apply_eq hi h ha).ne) fun h ↦ (hc.apply_add_one_lt_of_apply_eq hj h ha.symm).ne' -lemma exists_infinite_setOf_apply_eq : ∃ m, {i | a i = m}.Infinite := by +lemma exists_infinite_setOfPred_apply_eq : ∃ m, {i | a i = m}.Infinite := by by_contra! hi have hr : (Set.range a).Infinite := by contrapose! hi with hr @@ -180,16 +180,25 @@ lemma exists_infinite_setOf_apply_eq : ∃ m, {i | a i = m}.Infinite := by exact hc.apply_nth_add_one_eq toFinset_card_pos (N_lt_of_M_le_apply (a := a) (by simp only [apply_nth_zero, hi])).le -lemma nonempty_setOf_infinite_setOf_apply_eq : {m | {i | a i = m}.Infinite}.Nonempty := - hc.exists_infinite_setOf_apply_eq +@[deprecated (since := "2026-07-09")] +alias exists_infinite_setOf_apply_eq := exists_infinite_setOfPred_apply_eq -lemma injOn_setOf_apply_add_one_eq_of_M_le {n : ℕ} (h : M a N ≤ n) : +lemma nonempty_setOfPred_infinite_setOfPred_apply_eq : {m | {i | a i = m}.Infinite}.Nonempty := + hc.exists_infinite_setOfPred_apply_eq + +@[deprecated (since := "2026-07-09")] +alias nonempty_setOf_infinite_setOf_apply_eq := nonempty_setOfPred_infinite_setOfPred_apply_eq + +lemma injOn_setOfPred_apply_add_one_eq_of_M_le {n : ℕ} (h : M a N ≤ n) : Set.InjOn a {i | a (i + 1) = n} := by intro i hi j hj hij have hi' := hi ▸ hc.nth_apply_add_one_eq (Nat.lt_add_one_iff.mp (N_lt_of_M_le_apply (hi ▸ h))) have hj' := hj ▸ hc.nth_apply_add_one_eq (Nat.lt_add_one_iff.mp (N_lt_of_M_le_apply (hj ▸ h))) rw [← hi', ← hj', hij] +@[deprecated (since := "2026-07-09")] +alias injOn_setOf_apply_add_one_eq_of_M_le := injOn_setOfPred_apply_add_one_eq_of_M_le + lemma empty_consecutive_apply_ge_M : {i | M a N ≤ a i ∧ M a N ≤ a (i + 1)} = ∅ := by rw [Set.eq_empty_iff_forall_notMem] intro i @@ -224,7 +233,7 @@ lemma empty_consecutive_apply_ge_M : {i | M a N ≤ a i ∧ M a N ≤ a (i + 1)} have ht' : a (i + 1) = #t' := hc.apply_add_one_eq_card N_le_i rw [← card_t_eq_card_t'] at ht' have ht'inj : Set.InjOn a t := by - refine (hc.injOn_setOf_apply_add_one_eq_of_M_le hi1).mono ?_ + refine (hc.injOn_setOfPred_apply_add_one_eq_of_M_le hi1).mono ?_ simp_all [t, t'] have card_image_eq_card_t : #(Finset.image a t) = #t := Finset.card_image_of_injOn ht'inj have card_image_lt_M : #(Finset.image a t) < M a N := by @@ -246,12 +255,15 @@ lemma card_lt_M_of_M_le {n : ℕ} (h : M a N ≤ n) : suffices H : a (Nat.nth (fun x ↦ a x = n) (M a N - 1) + 1) = M a N from Nat.le_of_eq H.symm convert! hc.apply_nth_add_one_eq hin' (N_lt_of_M_le_apply ha).le using 1 -lemma bddAbove_setOf_infinite_setOf_apply_eq : BddAbove {m | {i | a i = m}.Infinite} := by +lemma bddAbove_setOfPred_infinite_setOfPred_apply_eq : BddAbove {m | {i | a i = m}.Infinite} := by refine ⟨M a N, fun x hi ↦ ?_⟩ by_contra hx exact hi (hc.card_lt_M_of_M_le (not_le.mp hx).le).1 -lemma infinite_setOf_apply_eq_anti {j k : ℕ} (hj : 0 < j) (hk : {i | a i = k}.Infinite) +@[deprecated (since := "2026-07-09")] +alias bddAbove_setOf_infinite_setOf_apply_eq := bddAbove_setOfPred_infinite_setOfPred_apply_eq + +lemma infinite_setOfPred_apply_eq_anti {j k : ℕ} (hj : 0 < j) (hk : {i | a i = k}.Infinite) (hjk : j ≤ k) : {i | a i = j}.Infinite := by have hk' : {i | a (i + 1) = k}.Infinite := by have hinj : Set.InjOn (· + 1) {i | a (i + 1) = k} := (add_left_injective _).injOn @@ -259,7 +271,7 @@ lemma infinite_setOf_apply_eq_anti {j k : ℕ} (hj : 0 < j) (hk : {i | a i = k}. have hk0 : ({i | a i = k} \ {0}).Infinite := hk.sdiff (Set.finite_singleton _) convert! hk0 using 1 ext i - simp only [Set.mem_image, Set.mem_setOf_eq, Set.mem_sdiff, Set.mem_singleton_iff] + simp only [Set.mem_image, Set.mem_ofPred_eq, Set.mem_sdiff, Set.mem_singleton_iff] refine ⟨?_, ?_⟩ · rintro ⟨j, rfl, rfl⟩ simp @@ -268,7 +280,7 @@ lemma infinite_setOf_apply_eq_anti {j k : ℕ} (hj : 0 < j) (hk : {i | a i = k}. have hinj : Set.InjOn (fun x ↦ Nat.nth (a · = a x) (j - 1) + 1) ({i | a (i + 1) = k} \ Set.Ico 0 N) := by intro x hx y hy h - simp only [Set.mem_sdiff, Set.mem_setOf_eq, Set.mem_Ico, zero_le, true_and, not_lt] at hx hy + simp only [Set.mem_sdiff, Set.mem_ofPred_eq, Set.mem_Ico, zero_le, true_and, not_lt] at hx hy rcases hx with ⟨hxk, hNx⟩ rcases hy with ⟨hyk, hNy⟩ simp only [add_left_inj] at h @@ -284,10 +296,13 @@ lemma infinite_setOf_apply_eq_anti {j k : ℕ} (hj : 0 < j) (hk : {i | a i = k}. have hk'' : (_ \ Set.Ico 0 (N + 2)).Infinite := ((Set.infinite_image_iff hinj).mpr (hk'.sdiff (Set.finite_Ico _ _))).sdiff (Set.finite_Ico _ _) refine hk''.mono fun _ hi ↦ ?_ - simp only [Set.mem_image, Set.mem_sdiff, Set.mem_setOf_eq, Set.mem_Ico, zero_le, true_and, + simp only [Set.mem_image, Set.mem_sdiff, Set.mem_ofPred_eq, Set.mem_Ico, zero_le, true_and, not_lt] at hi rcases hi with ⟨⟨x, -, rfl⟩, _⟩ - rw [Set.mem_setOf_eq, hc.apply_nth_add_one_eq_of_lt (by lia), Nat.sub_add_cancel hj] + rw [Set.mem_ofPred_eq, hc.apply_nth_add_one_eq_of_lt (by lia), Nat.sub_add_cancel hj] + +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_apply_eq_anti := infinite_setOfPred_apply_eq_anti /-! ### The definitions of small, medium and big numbers and the eventual alternation -/ @@ -301,41 +316,62 @@ def Small (j : ℕ) : Prop := j ≤ k a variable {a} -lemma infinite_setOf_apply_eq_k : {i | a i = k a}.Infinite := - Nat.sSup_mem hc.nonempty_setOf_infinite_setOf_apply_eq hc.bddAbove_setOf_infinite_setOf_apply_eq +lemma infinite_setOfPred_apply_eq_k : {i | a i = k a}.Infinite := + Nat.sSup_mem hc.nonempty_setOfPred_infinite_setOfPred_apply_eq + hc.bddAbove_setOfPred_infinite_setOfPred_apply_eq + +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_apply_eq_k := infinite_setOfPred_apply_eq_k -lemma infinite_setOf_apply_eq_iff_small {j : ℕ} (hj : 0 < j) : +lemma infinite_setOfPred_apply_eq_iff_small {j : ℕ} (hj : 0 < j) : {i | a i = j}.Infinite ↔ Small a j := - ⟨fun h ↦ le_csSup hc.bddAbove_setOf_infinite_setOf_apply_eq h, - fun h ↦ hc.infinite_setOf_apply_eq_anti hj hc.infinite_setOf_apply_eq_k h⟩ + ⟨fun h ↦ le_csSup hc.bddAbove_setOfPred_infinite_setOfPred_apply_eq h, + fun h ↦ hc.infinite_setOfPred_apply_eq_anti hj hc.infinite_setOfPred_apply_eq_k h⟩ + +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_apply_eq_iff_small := infinite_setOfPred_apply_eq_iff_small -lemma finite_setOf_apply_eq_iff_not_small {j : ℕ} (hj : 0 < j) : +lemma finite_setOfPred_apply_eq_iff_not_small {j : ℕ} (hj : 0 < j) : {i | a i = j}.Finite ↔ ¬Small a j := by - contrapose!; exact hc.infinite_setOf_apply_eq_iff_small hj + contrapose!; exact hc.infinite_setOfPred_apply_eq_iff_small hj -lemma finite_setOf_apply_eq_k_add_one : {i | a i = k a + 1}.Finite := by - rw [hc.finite_setOf_apply_eq_iff_not_small (by lia), Small] +@[deprecated (since := "2026-07-09")] +alias finite_setOf_apply_eq_iff_not_small := finite_setOfPred_apply_eq_iff_not_small + +lemma finite_setOfPred_apply_eq_k_add_one : {i | a i = k a + 1}.Finite := by + rw [hc.finite_setOfPred_apply_eq_iff_not_small (by lia), Small] lia +@[deprecated (since := "2026-07-09")] +alias finite_setOf_apply_eq_k_add_one := finite_setOfPred_apply_eq_k_add_one + /-- There are only finitely many `m` that appear more than `k` times. -/ -lemma finite_setOf_k_lt_card : {m | ∀ hf : {i | a i = m}.Finite, k a < #hf.toFinset}.Finite := by +lemma finite_setOfPred_k_lt_card : + {m | ∀ hf : {i | a i = m}.Finite, k a < #hf.toFinset}.Finite := by rw [← Set.finite_image_iff] - · refine Set.Finite.of_sdiff (hc.finite_setOf_apply_eq_k_add_one.subset fun i hi ↦ ?_) + · refine Set.Finite.of_sdiff (hc.finite_setOfPred_apply_eq_k_add_one.subset fun i hi ↦ ?_) (Set.finite_Iic N) - simp only [Set.mem_sdiff, Set.mem_image, Set.mem_setOf_eq, Set.mem_Iic, not_le] at hi + simp only [Set.mem_sdiff, Set.mem_image, Set.mem_ofPred_eq, Set.mem_Iic, not_le] at hi rcases hi with ⟨⟨j, hjf, rfl⟩, hNi⟩ - rw [Set.mem_setOf_eq, hc.apply_nth_add_one_eq hjf (by lia)] + rw [Set.mem_ofPred_eq, hc.apply_nth_add_one_eq hjf (by lia)] · intro i hi j hj hij simp only [add_left_inj] at hij apply_fun a at hij rwa [Nat.nth_mem _ hi, Nat.nth_mem _ hj] at hij -lemma bddAbove_setOf_k_lt_card : BddAbove {m | ∀ hf : {i | a i = m}.Finite, k a < #hf.toFinset} := - hc.finite_setOf_k_lt_card.bddAbove +@[deprecated (since := "2026-07-09")] +alias finite_setOf_k_lt_card := finite_setOfPred_k_lt_card + +lemma bddAbove_setOfPred_k_lt_card : + BddAbove {m | ∀ hf : {i | a i = m}.Finite, k a < #hf.toFinset} := + hc.finite_setOfPred_k_lt_card.bddAbove + +@[deprecated (since := "2026-07-09")] +alias bddAbove_setOf_k_lt_card := bddAbove_setOfPred_k_lt_card lemma k_pos : 0 < k a := by by_contra! hn - apply nonpos_iff_eq_zero.mp hn ▸ hc.infinite_setOf_apply_eq_k + apply nonpos_iff_eq_zero.mp hn ▸ hc.infinite_setOfPred_apply_eq_k convert! Set.finite_empty ext i simp [(hc.pos i).ne'] @@ -344,8 +380,11 @@ lemma small_one : Small a 1 := by by_contra hns simp only [Small, not_le, Nat.lt_one_iff, hc.k_pos.ne'] at hns -lemma infinite_setOf_apply_eq_one : {i | a i = 1}.Infinite := - (hc.infinite_setOf_apply_eq_iff_small (by decide)).mpr hc.small_one +lemma infinite_setOfPred_apply_eq_one : {i | a i = 1}.Infinite := + (hc.infinite_setOfPred_apply_eq_iff_small (by decide)).mpr hc.small_one + +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_apply_eq_one := infinite_setOfPred_apply_eq_one variable (a) @@ -362,7 +401,7 @@ def Big (j : ℕ) : Prop := l a < j variable {a} lemma k_le_l : k a ≤ l a := - le_csSup hc.bddAbove_setOf_k_lt_card (fun hf ↦ absurd hf hc.infinite_setOf_apply_eq_k) + le_csSup hc.bddAbove_setOfPred_k_lt_card (fun hf ↦ absurd hf hc.infinite_setOfPred_apply_eq_k) lemma k_lt_of_big {j : ℕ} (h : Big a j) : k a < j := hc.k_le_l.trans_lt h @@ -375,10 +414,10 @@ lemma not_small_of_big {j : ℕ} (h : Big a j) : ¬Small a j := by simp [Small, lemma exists_card_le_of_big {j : ℕ} (h : Big a j) : ∃ hf : {i | a i = j}.Finite, #hf.toFinset ≤ k a := by have hns := hc.not_small_of_big h - rw [← hc.finite_setOf_apply_eq_iff_not_small (hc.pos_of_big h)] at hns + rw [← hc.finite_setOfPred_apply_eq_iff_not_small (hc.pos_of_big h)] at hns use hns by_contra! hlt - exact notMem_of_csSup_lt h hc.bddAbove_setOf_k_lt_card fun _ ↦ hlt + exact notMem_of_csSup_lt h hc.bddAbove_setOfPred_k_lt_card fun _ ↦ hlt variable (a N) @@ -401,7 +440,7 @@ lemma not_medium_of_N'aux_lt {j : ℕ} (h : N'aux a N < j) : ¬Medium a (a j) := have hf : s.Finite := by refine (Set.finite_Ioc _ _).biUnion ?_ rintro i ⟨hk, -⟩ - rwa [hc.finite_setOf_apply_eq_iff_not_small (by lia), Small, not_le] + rwa [hc.finite_setOfPred_apply_eq_iff_not_small (by lia), Small, not_le] exact fun hm ↦ notMem_of_csSup_lt (le_sup_left.trans_lt h) (hf.subset fun i hi ↦ (by simpa [s] using! hi)).bddAbove hm @@ -429,18 +468,20 @@ lemma nth_sup_k_le_N'aux_of_small {j : ℕ} (h : Small a j) : Nat.nth (a · = j) (k a) ≤ N'aux a N := match j with | 0 => by simp only [hc.nth_apply_eq_zero, zero_le] - | j + 1 => ((Nat.nth_le_nth ((hc.infinite_setOf_apply_eq_iff_small (Nat.zero_lt_succ j)).mpr h)).2 + | j + 1 => ((Nat.nth_le_nth + ((hc.infinite_setOfPred_apply_eq_iff_small (Nat.zero_lt_succ j)).mpr h)).2 le_sup_left).trans (nth_sup_k_N_add_one_le_N'aux_of_small h) lemma nth_sup_N_add_one_le_N'aux_of_small {j : ℕ} (h : Small a j) : Nat.nth (a · = j) (N + 1) ≤ N'aux a N := match j with | 0 => by simp only [hc.nth_apply_eq_zero, zero_le] - | j + 1 => ((Nat.nth_le_nth ((hc.infinite_setOf_apply_eq_iff_small (Nat.zero_lt_succ j)).mpr h)).2 + | j + 1 => ((Nat.nth_le_nth + ((hc.infinite_setOfPred_apply_eq_iff_small (Nat.zero_lt_succ j)).mpr h)).2 le_sup_right).trans (nth_sup_k_N_add_one_le_N'aux_of_small h) lemma N_lt_N'aux : N < N'aux a N := - Nat.add_one_le_iff.mp ((Nat.le_nth fun hf ↦ absurd hf hc.infinite_setOf_apply_eq_one).trans + Nat.add_one_le_iff.mp ((Nat.le_nth fun hf ↦ absurd hf hc.infinite_setOfPred_apply_eq_one).trans (hc.nth_sup_N_add_one_le_N'aux_of_small hc.small_one)) /-- `N` is less than `N'`. -/ @@ -448,7 +489,7 @@ lemma N_lt_N' : N < N' a N := hc.N_lt_N'aux.trans_le (Nat.le_add_right _ _) lemma lt_card_filter_eq_of_small_nth_lt {i j t : ℕ} (hj0 : 0 < j) (h : Small a j) (ht : Nat.nth (a · = j) t < i) : t < #{m ∈ Finset.range i | a m = j} := by - rw [← hc.infinite_setOf_apply_eq_iff_small hj0] at h + rw [← hc.infinite_setOfPred_apply_eq_iff_small hj0] at h rw [← Nat.count_eq_card_filter_range] exact (Nat.nth_lt_nth h).mp (ht.trans_le (Nat.le_nth_count h _)) @@ -554,7 +595,7 @@ lemma N_add_one_lt_apply_of_apply_big_of_N'_le {i : ℕ} (h : Big a (a i)) (hN' by_contra exact hc.not_small_of_big ((by lia : i = N' a N) ▸ h) hc.small_apply_N' -lemma setOf_apply_eq_of_apply_big_of_N'_le {i : ℕ} (h : Big a (a i)) (hN' : N' a N ≤ i) : +lemma setOfPred_apply_eq_of_apply_big_of_N'_le {i : ℕ} (h : Big a (a i)) (hN' : N' a N ≤ i) : {j | a j = a i} = {j | N < j ∧ Small a (a (j - 1)) ∧ a i = #{t ∈ Finset.range j | a t = a (j - 1)}} := by have hs : {j | N < j ∧ Small a (a (j - 1)) ∧ a i = #{t ∈ Finset.range j | a t = a (j - 1)}} ⊆ @@ -572,11 +613,11 @@ lemma setOf_apply_eq_of_apply_big_of_N'_le {i : ℕ} (h : Big a (a i)) (hN' : N' · simp only [Nat.card_Icc, add_tsub_cancel_right] · simp only [add_left_inj] at htu simp only [Finset.coe_Icc, Set.mem_Icc] at ht hu - rw [← Small, ← hc.infinite_setOf_apply_eq_iff_small (by lia)] at ht hu + rw [← Small, ← hc.infinite_setOfPred_apply_eq_iff_small (by lia)] at ht hu apply_fun a at htu rwa [Nat.nth_mem_of_infinite ht.2, Nat.nth_mem_of_infinite hu.2] at htu refine hs ▸ Finset.card_le_card (Finset.subset_iff.2 fun j hj ↦ ?_) - simp only [Set.Finite.mem_toFinset, Set.mem_setOf_eq] + simp only [Set.Finite.mem_toFinset, Set.mem_ofPred_eq] simp only [Finset.mem_image, Finset.mem_Icc] at hj rcases hj with ⟨t, ⟨ht1, htk⟩, rfl⟩ have hN1 : N < a i - 1 := by @@ -585,7 +626,7 @@ lemma setOf_apply_eq_of_apply_big_of_N'_le {i : ℕ} (h : Big a (a i)) (hN' : N' simp only [add_tsub_cancel_right] rw [← Small] at htk have htki := htk - rw [← hc.infinite_setOf_apply_eq_iff_small (by lia)] at htki + rw [← hc.infinite_setOfPred_apply_eq_iff_small (by lia)] at htki rw [Nat.nth_mem_of_infinite htki] simp only [htk, true_and] refine ⟨Nat.lt_add_one_iff.mpr ((Nat.le_nth (fun hf ↦ absurd hf htki)).trans @@ -593,15 +634,18 @@ lemma setOf_apply_eq_of_apply_big_of_N'_le {i : ℕ} (h : Big a (a i)) (hN' : N' rw [← Nat.count_eq_card_filter_range, Nat.count_nth_succ_of_infinite htki] lia +@[deprecated (since := "2026-07-09")] +alias setOf_apply_eq_of_apply_big_of_N'_le := setOfPred_apply_eq_of_apply_big_of_N'_le + lemma N_lt_of_apply_eq_of_apply_big_of_N'_le {i j : ℕ} (hj : a j = a i) (h : Big a (a i)) (hN' : N' a N ≤ i) : N < j := have hj' : j ∈ {t | a t = a i} := by simpa using hj - (hc.setOf_apply_eq_of_apply_big_of_N'_le h hN' ▸ hj').1 + (hc.setOfPred_apply_eq_of_apply_big_of_N'_le h hN' ▸ hj').1 lemma small_apply_sub_one_of_apply_eq_of_apply_big_of_N'_le {i j : ℕ} (hj : a j = a i) (h : Big a (a i)) (hN' : N' a N ≤ i) : Small a (a (j - 1)) := have hj' : j ∈ {t | a t = a i} := by simpa using hj - (hc.setOf_apply_eq_of_apply_big_of_N'_le h hN' ▸ hj').2.1 + (hc.setOfPred_apply_eq_of_apply_big_of_N'_le h hN' ▸ hj').2.1 /-! ### The main lemmas leading to the required result -/ @@ -628,7 +672,7 @@ lemma apply_add_one_eq_card_small_le_card_eq {i : ℕ} (hi : N' a N < i) (hib : have ht0 : 0 < t := by by_contra! h0 simp [nonpos_iff_eq_zero.mp h0, hc.apply_ne_zero] at htr - rw [← hc.infinite_setOf_apply_eq_iff_small ht0] at hts + rw [← hc.infinite_setOfPred_apply_eq_iff_small ht0] at hts rw [← Nat.count_eq_card_filter_range] at htr constructor · rwa [add_lt_add_iff_right, ← Nat.lt_nth_iff_count_lt hts, @@ -639,7 +683,7 @@ lemma apply_add_one_eq_card_small_le_card_eq {i : ℕ} (hi : N' a N < i) (hib : have := hc.N_add_one_lt_apply_of_apply_big_of_N'_le hib hi.le lia · intro t ht u hu htu - simp only [Finset.coe_filter, Finset.mem_range, Set.mem_setOf_eq, Nat.lt_add_one_iff] at ht hu + simp only [Finset.coe_filter, Finset.mem_range, Set.mem_ofPred_eq, Nat.lt_add_one_iff] at ht hu rw [← Small] at ht hu have ht0 : 0 < t := by by_contra! h0 @@ -649,8 +693,8 @@ lemma apply_add_one_eq_card_small_le_card_eq {i : ℕ} (hi : N' a N < i) (hib : by_contra! h0 simp only [nonpos_iff_eq_zero] at h0 simp [h0, hc.apply_ne_zero] at hu - rw [← hc.infinite_setOf_apply_eq_iff_small ht0] at ht - rw [← hc.infinite_setOf_apply_eq_iff_small hu0] at hu + rw [← hc.infinite_setOfPred_apply_eq_iff_small ht0] at ht + rw [← hc.infinite_setOfPred_apply_eq_iff_small hu0] at hu simp only [add_left_inj] at htu apply_fun a at htu rwa [Nat.nth_mem_of_infinite ht.1, Nat.nth_mem_of_infinite hu.1] at htu @@ -800,10 +844,10 @@ noncomputable def p (n : ℕ) : ℕ := sInf (pSet a n) variable {a} lemma nonempty_pSet (n : ℕ) : (pSet a n).Nonempty := by - rcases hc.infinite_setOf_apply_eq_one.exists_gt n with ⟨i, hi1, hni⟩ - rcases hc.infinite_setOf_apply_eq_one.exists_gt i with ⟨j, hj1, hij⟩ + rcases hc.infinite_setOfPred_apply_eq_one.exists_gt n with ⟨i, hi1, hni⟩ + rcases hc.infinite_setOfPred_apply_eq_one.exists_gt i with ⟨j, hj1, hij⟩ refine ⟨j - n, ?_⟩ - simp only [pSet, Finset.mem_Ico, Set.mem_setOf_eq] + simp only [pSet, Finset.mem_Ico, Set.mem_ofPred_eq] exact ⟨i, ⟨hni.le, by lia⟩, hi1 ▸ ⟨hc.small_one, hj1 ▸ (by congr; lia)⟩⟩ lemma exists_mem_Ico_small_and_apply_add_p_eq (n : ℕ) : @@ -818,7 +862,7 @@ lemma p_pos (n : ℕ) : 0 < p a n := by lemma card_filter_apply_eq_Ico_add_p_le_one (n : ℕ) {j : ℕ} (hjs : Small a j) : #{i ∈ Finset.Ico n (n + p a n) | a i = j} ≤ 1 := by have h : IsLeast (pSet a n) (p a n) := isLeast_csInf (hc.nonempty_pSet n) - simp only [IsLeast, pSet, Set.mem_setOf_eq, mem_lowerBounds, forall_exists_index, and_imp, + simp only [IsLeast, pSet, Set.mem_ofPred_eq, mem_lowerBounds, forall_exists_index, and_imp, Finset.mem_Ico] at h rw [Finset.card_le_one_iff] intro x y hx hy diff --git a/Archive/Imo/Imo2024Q5.lean b/Archive/Imo/Imo2024Q5.lean index 0ba79f1f9813d9..24017a321eed86 100644 --- a/Archive/Imo/Imo2024Q5.lean +++ b/Archive/Imo/Imo2024Q5.lean @@ -1042,7 +1042,7 @@ def answer : ℕ := 3 /-- The final result, combining upper and lower bounds. -/ theorem result : IsLeast {k | ∃ s : Strategy 2022, s.ForcesWinIn k} answer := by - simp_rw [IsLeast, mem_lowerBounds, Set.mem_setOf, forall_exists_index] + simp_rw [IsLeast, mem_lowerBounds, Set.mem_ofPred, forall_exists_index] exact ⟨⟨winningStrategy (by simp), winningStrategy_forcesWinIn_three (by simp)⟩, fun k s h ↦ h.three_le (by simp)⟩ diff --git a/Archive/Sensitivity.lean b/Archive/Sensitivity.lean index b9d1b92d8c5959..10b3e97caba4a6 100644 --- a/Archive/Sensitivity.lean +++ b/Archive/Sensitivity.lean @@ -140,7 +140,7 @@ theorem adj_iff_proj_adj {p q : Q n.succ} (h₀ : p 0 = q 0) : @[symm] theorem adjacent.symm {p q : Q n} : q ∈ p.adjacent ↔ p ∈ q.adjacent := by - simp only [adjacent, ne_comm, Set.mem_setOf_eq] + simp only [adjacent, ne_comm, Set.mem_ofPred_eq] end Q diff --git a/Archive/Wiedijk100Theorems/AreaOfACircle.lean b/Archive/Wiedijk100Theorems/AreaOfACircle.lean index 71aaa05c5d0099..d41ec82f69a97d 100644 --- a/Archive/Wiedijk100Theorems/AreaOfACircle.lean +++ b/Archive/Wiedijk100Theorems/AreaOfACircle.lean @@ -65,7 +65,7 @@ theorem disc_eq_regionBetween : regionBetween (fun x => -sqrt (r ^ 2 - x ^ 2)) (fun x => sqrt (r ^ 2 - x ^ 2)) (Ioc (-r) r) := by ext p - simp only [disc, regionBetween, mem_setOf_eq, mem_Ioo, mem_Ioc] + simp only [disc, regionBetween, mem_ofPred_eq, mem_Ioo, mem_Ioc] constructor <;> intro h · cases abs_lt_of_sq_lt_sq' (lt_of_add_lt_of_nonneg_left h (sq_nonneg p.2)) r.2 with | intro left right => diff --git a/Archive/Wiedijk100Theorems/BallotProblem.lean b/Archive/Wiedijk100Theorems/BallotProblem.lean index 3f35b7cc5b72fd..3d65be551a90cd 100644 --- a/Archive/Wiedijk100Theorems/BallotProblem.lean +++ b/Archive/Wiedijk100Theorems/BallotProblem.lean @@ -74,7 +74,7 @@ open scoped List in theorem mem_countedSequence_iff_perm {p q l} : l ∈ countedSequence p q ↔ l ~ List.replicate p (1 : ℤ) ++ List.replicate q (-1) := by rw [List.perm_replicate_append_replicate] - · simp only [countedSequence, List.subset_def, mem_setOf_eq, List.mem_cons (b := (1 : ℤ)), + · simp only [countedSequence, List.subset_def, mem_ofPred_eq, List.mem_cons (b := (1 : ℤ)), List.mem_singleton] · norm_num1 @@ -200,7 +200,7 @@ theorem first_vote_pos : ((countedSequence_nonempty _ _).image _)] · have : List.cons (-1) '' countedSequence (p + 1) q ∩ {l : List ℤ | l.headI = 1} = ∅ := by ext - simp only [mem_inter_iff, mem_image, mem_setOf_eq, mem_empty_iff_false, iff_false, + simp only [mem_inter_iff, mem_image, mem_ofPred_eq, mem_empty_iff_false, iff_false, not_and, forall_exists_index, and_imp] rintro l _ rfl norm_num @@ -255,7 +255,7 @@ theorem countedSequence_int_pos_counted_succ_succ (p q : ℕ) : rw [counted_succ_succ, union_inter_distrib_right, (_ : List.cons (-1) '' countedSequence (p + 1) q ∩ {l | l.headI = 1} = ∅), union_empty] <;> · ext - simp only [mem_inter_iff, mem_image, mem_setOf_eq, and_iff_left_iff_imp, mem_empty_iff_false, + simp only [mem_inter_iff, mem_image, mem_ofPred_eq, and_iff_left_iff_imp, mem_empty_iff_false, iff_false, not_and, forall_exists_index, and_imp] rintro y _ rfl norm_num diff --git a/Archive/Wiedijk100Theorems/BirthdayProblem.lean b/Archive/Wiedijk100Theorems/BirthdayProblem.lean index 6e8939c320feb3..9f99a4e0b14264 100644 --- a/Archive/Wiedijk100Theorems/BirthdayProblem.lean +++ b/Archive/Wiedijk100Theorems/BirthdayProblem.lean @@ -50,7 +50,7 @@ theorem birthday_measure : trans ‖Fin 23 ↪ Fin 365‖ · rw [← Fintype.card_coe] apply Fintype.card_congr - rw [Set.Finite.coeSort_toFinset, Set.coe_setOf] + rw [Set.Finite.coeSort_toFinset, Set.coe_ofPred] exact Equiv.subtypeInjectiveEquivEmbedding _ _ · rw [Fintype.card_embedding_eq, Fintype.card_fin, Fintype.card_fin] rfl diff --git a/Archive/Wiedijk100Theorems/CubingACube.lean b/Archive/Wiedijk100Theorems/CubingACube.lean index e9deeb72863168..b9fa47e86abaf7 100644 --- a/Archive/Wiedijk100Theorems/CubingACube.lean +++ b/Archive/Wiedijk100Theorems/CubingACube.lean @@ -183,7 +183,7 @@ theorem shiftUp_bottom_subset_bottoms (hc : (cs i).xm ≠ 1) : (cs i).shiftUp.bottom ⊆ ⋃ i : ι, (cs i).bottom := by intro p hp; obtain ⟨hp0, hps⟩ := hp; rw [tail_shiftUp] at hps have : p ∈ (unitCube : Cube (n + 1)).toSet := by - simp only [toSet, forall_iff_succ, hp0, side_unitCube, mem_setOf_eq, mem_Ico, head_shiftUp] + simp only [toSet, forall_iff_succ, hp0, side_unitCube, mem_ofPred_eq, mem_Ico, head_shiftUp] refine ⟨⟨?_, ?_⟩, ?_⟩ · rw [← zero_add (0 : ℝ)]; apply add_le_add · apply zero_le_b h @@ -223,10 +223,10 @@ variable {c : Cube (n + 1)} (h : Correct cs) (v : Valley cs c) theorem valley_unitCube [Nontrivial ι] (h : Correct cs) : Valley cs unitCube := by refine ⟨?_, ?_, ?_⟩ · intro v - simp only [bottom, and_imp, mem_iUnion, mem_setOf_eq] + simp only [bottom, and_imp, mem_iUnion, mem_ofPred_eq] intro h0 hv have : v ∈ (unitCube : Cube (n + 1)).toSet := by - dsimp only [toSet, unitCube, mem_setOf_eq] + dsimp only [toSet, unitCube, mem_ofPred_eq] rw [forall_iff_succ, h0]; constructor · norm_num [side, unitCube] · exact hv @@ -410,7 +410,7 @@ theorem mi_not_onBoundary (j : Fin n) : ¬OnBoundary (mi_mem_bcubes : mi h v ∈ have i'_i'' : i' ≠ i'' := by rintro ⟨⟩ have : (cs i).b ∈ (cs i').toSet := by - simp only [toSet, forall_iff_succ, hi.1, bottom_mem_side h2i', true_and, mem_setOf_eq] + simp only [toSet, forall_iff_succ, hi.1, bottom_mem_side h2i', true_and, mem_ofPred_eq] intro j₂; by_cases hj₂ : j₂ = j · simpa [p', side_tail, hj'.symm, hj₂] using hi''.2 j · simpa [p, hj₂] using! hi'.2 j₂ @@ -456,7 +456,7 @@ theorem valley_mi : Valley cs (cs (mi h v)).shiftUp := by simp only [not_subset, tail_shiftUp] at h2i' rcases h2i' with ⟨p1, hp1, h2p1⟩ have : ∃ p3, p3 ∈ (cs i').tail.toSet ∧ p3 ∉ (cs i).tail.toSet ∧ p3 ∈ c.tail.toSet := by - simp only [toSet, not_forall, mem_setOf_eq] at h2p1; obtain ⟨j, hj⟩ := h2p1 + simp only [toSet, not_forall, mem_ofPred_eq] at h2p1; obtain ⟨j, hj⟩ := h2p1 rcases Ico_lemma (mi_not_onBoundary' j).1 (by simp [hw]) (mi_not_onBoundary' j).2 (le_trans (hp2 j).1 <| le_of_lt (h2p2 j).2) (le_trans (h2p2 j).1 <| le_of_lt (hp2 j).2) ⟨hj, hp1 j⟩ with @@ -465,7 +465,7 @@ theorem valley_mi : Valley cs (cs (mi h v)).shiftUp := by · intro j'; by_cases h : j' = j · simp only [if_pos h]; exact h ▸ h3w · simp only [if_neg h]; exact hp2 j' - · simp only [toSet, not_forall, mem_setOf_eq]; use j; rw [if_pos rfl]; convert! h2w + · simp only [toSet, not_forall, mem_ofPred_eq]; use j; rw [if_pos rfl]; convert! h2w · intro j'; by_cases h : j' = j · simp only [if_pos h, side_tail]; exact h ▸ hw · simp only [if_neg h]; apply hi.2; apply h2p2 @@ -483,7 +483,7 @@ theorem valley_mi : Valley cs (cs (mi h v)).shiftUp := by let p' := @cons n (fun _ => ℝ) (cs i).xm p3 have hp' : p' ∈ (cs i').toSet := by simpa [i, p', toSet, forall_iff_succ, hi'.symm] using! h1p3 have h2p' : p' ∈ (cs i'').toSet := by - simp only [p', toSet, forall_iff_succ, cons_succ, cons_zero, mem_setOf_eq] + simp only [p', toSet, forall_iff_succ, cons_succ, cons_zero, mem_ofPred_eq] refine ⟨?_, by simpa [toSet] using! hi''.2⟩ have : (cs i).b 0 = (cs i'').b 0 := by rw [hi.1, h2i''.1] simp [side, hw', xm, this, h3i''] diff --git a/Archive/Wiedijk100Theorems/Konigsberg.lean b/Archive/Wiedijk100Theorems/Konigsberg.lean index 165b5a6a1dc0e2..fd0a4ab80f81a8 100644 --- a/Archive/Wiedijk100Theorems/Konigsberg.lean +++ b/Archive/Wiedijk100Theorems/Konigsberg.lean @@ -67,15 +67,17 @@ lemma degree_eq_degree (v : Verts) : graph.degree v = degree v := by cases v <;> lemma not_even_degree_iff (w : Verts) : ¬Even (degree w) ↔ w = V1 ∨ w = V2 ∨ w = V3 ∨ w = V4 := by cases w <;> decide -lemma setOf_odd_degree_eq : +lemma setOfPred_odd_degree_eq : {v | Odd (graph.degree v)} = {Verts.V1, Verts.V2, Verts.V3, Verts.V4} := by ext w simp [not_even_degree_iff, ← Nat.not_even_iff_odd] +@[deprecated (since := "2026-07-09")] alias setOf_odd_degree_eq := setOfPred_odd_degree_eq + /-- The Königsberg graph is not Eulerian. -/ theorem not_isEulerian {u v : Verts} (p : graph.Walk u v) (h : p.IsEulerian) : False := by have h := h.card_odd_degree - have h' := setOf_odd_degree_eq + have h' := setOfPred_odd_degree_eq apply_fun Fintype.card at h' rw [h'] at h simp at h diff --git a/Archive/ZagierTwoSquares.lean b/Archive/ZagierTwoSquares.lean index 61f14901867c4d..dcf81cf4017bc7 100644 --- a/Archive/ZagierTwoSquares.lean +++ b/Archive/ZagierTwoSquares.lean @@ -38,7 +38,7 @@ variable (k : ℕ) [hk : Fact (4 * k + 1).Prime] def zagierSet : Set (ℕ × ℕ × ℕ) := {t | t.1 * t.1 + 4 * t.2.1 * t.2.2 = 4 * k + 1} lemma zagierSet_lower_bound {x y z : ℕ} (h : (x, y, z) ∈ zagierSet k) : 0 < x ∧ 0 < y ∧ 0 < z := by - rw [zagierSet, mem_setOf_eq] at h + rw [zagierSet, mem_ofPred_eq] at h refine ⟨?_, ?_, ?_⟩ all_goals by_contra q @@ -57,7 +57,7 @@ lemma zagierSet_lower_bound {x y z : ℕ} (h : (x, y, z) ∈ zagierSet k) : 0 < lemma zagierSet_upper_bound {x y z : ℕ} (h : (x, y, z) ∈ zagierSet k) : x ≤ k + 1 ∧ y ≤ k ∧ z ≤ k := by obtain ⟨_, _, _⟩ := zagierSet_lower_bound k h - rw [zagierSet, mem_setOf_eq] at h + rw [zagierSet, mem_ofPred_eq] at h refine ⟨?_, ?_, ?_⟩ <;> nlinarith lemma zagierSet_subset : zagierSet k ⊆ Ioc 0 (k + 1) ×ˢ Ioc 0 k ×ˢ Ioc 0 k := by @@ -80,7 +80,7 @@ variable (k : ℕ) /-- The obvious involution `(x, y, z) ↦ (x, z, y)`. -/ def obvInvo : Function.End (zagierSet k) := fun ⟨⟨x, y, z⟩, h⟩ => ⟨⟨x, z, y⟩, by - simp only [zagierSet, Set.mem_setOf_eq] at h ⊢ + simp only [zagierSet, Set.mem_ofPred_eq] at h ⊢ linarith [h]⟩ theorem obvInvo_sq : obvInvo k ^ 2 = 1 := rfl @@ -93,7 +93,7 @@ theorem sq_add_sq_of_nonempty_fixedPoints (hn : (fixedPoints (obvInvo k)).Nonemp obtain ⟨⟨⟨x, y, z⟩, he⟩, hf⟩ := hn have := mem_fixedPoints_iff.mp hf simp only [obvInvo, Subtype.mk.injEq, Prod.mk.injEq, true_and] at this - simp only [zagierSet, Set.mem_setOf_eq] at he + simp only [zagierSet, Set.mem_ofPred_eq] at he use x, (2 * y) rw [show 2 * y * (2 * y) = 4 * y * y by linarith, ← he, this.1] @@ -103,7 +103,7 @@ def complexInvo : Function.End (zagierSet k) := fun ⟨⟨x, y, z⟩, h⟩ => ⟨if x + z < y then ⟨x + 2 * z, z, y - x - z⟩ else if 2 * y < x then ⟨x - 2 * y, x + z - y, y⟩ else ⟨2 * y - x, y, x + z - y⟩, by - split_ifs with less more <;> simp only [zagierSet, Set.mem_setOf_eq] at h ⊢ + split_ifs with less more <;> simp only [zagierSet, Set.mem_ofPred_eq] at h ⊢ · -- less: `x + z < y` (`x < y - z` as stated by Zagier) rw [Nat.sub_sub]; zify [less.le] at h ⊢; linarith [h] · -- more: `2 * y < x` @@ -154,7 +154,7 @@ theorem eq_of_mem_fixedPoints {t : zagierSet k} (mem : t ∈ fixedPoints (comple · -- more obtain ⟨_, _, _⟩ := mem; simp_all · -- middle (the one fixed point falls under this case) - simp only [zagierSet, Set.mem_setOf_eq] at h + simp only [zagierSet, Set.mem_ofPred_eq] at h replace mem := mem.1 rw [tsub_eq_iff_eq_add_of_le more, ← two_mul] at mem replace mem := (mul_left_cancel₀ two_ne_zero mem).symm @@ -169,7 +169,7 @@ theorem eq_of_mem_fixedPoints {t : zagierSet k} (mem : t ∈ fixedPoints (comple /-- The singleton containing `(1, 1, k)`. -/ def singletonFixedPoint : Finset (zagierSet k) := - {⟨(1, 1, k), (by simp only [zagierSet, Set.mem_setOf_eq]; linarith)⟩} + {⟨(1, 1, k), (by simp only [zagierSet, Set.mem_ofPred_eq]; linarith)⟩} set_option backward.isDefEq.respectTransparency false in /-- `complexInvo k` has exactly one fixed point. -/ diff --git a/Counterexamples/AharoniKorman.lean b/Counterexamples/AharoniKorman.lean index da1859c03f22e1..4d087cdc8cb311 100644 --- a/Counterexamples/AharoniKorman.lean +++ b/Counterexamples/AharoniKorman.lean @@ -245,7 +245,7 @@ This corresponds to 5.8 (i) in the [hollom2025]. -/ lemma ordConnected_level {n : ℕ} : (level n).OrdConnected := by rw [Set.ordConnected_iff] - simp only [level_eq, Set.mem_setOf_eq, Set.subset_def, Set.mem_Icc, and_imp, Hollom.forall, + simp only [level_eq, Set.mem_ofPred_eq, Set.subset_def, Set.mem_Icc, and_imp, Hollom.forall, Prod.forall, forall_eq, toHollom_le_toHollom_iff_fixed_right] intro a b c d ac bd e f g h1 h2 exact le_antisymm (le_of_toHollom_le_toHollom h1) (le_of_toHollom_le_toHollom h2) @@ -417,7 +417,7 @@ theorem exists_finite_intersection (hC : IsChain (· ≤ ·) C) : -- In fact, we only need it to be nonempty, and find a point. obtain ⟨x, hxy⟩ := this.nonempty induction hxy.1.2 using induction_on_level with | h x y => - simp only [Set.mem_sdiff, Set.mem_inter_iff, toHollom_mem_level_iff, and_true, Set.mem_setOf_eq, + simp only [Set.mem_sdiff, Set.mem_inter_iff, toHollom_mem_level_iff, and_true, Set.mem_ofPred_eq, not_le, D] at hxy -- Take the point `(x, y, n + 1)` in `C` that avoids `D`. As `(u, v, n)` is also in the chain `C`, -- they must be comparable. @@ -843,7 +843,7 @@ lemma square_subset_above (h : (C ∩ level n).Finite) : simp +contextual only [sup_le_iff, embed, RelEmbedding.coe_mk, Function.Embedding.coeFn_mk, Set.mem_inter_iff, and_imp, «forall», toHollom_mem_level_iff, Prod.forall, Set.subset_def, Set.mem_image, Set.mem_Ici, Prod.exists, Prod.mk_le_mk, - Set.mem_setOf_eq, forall_exists_index, Prod.mk.injEq, + Set.mem_ofPred_eq, forall_exists_index, Prod.mk.injEq, toHollom_le_toHollom_iff_fixed_right, Set.mem_sdiff, and_true, ← max_add_add_right, Hollom.ext_iff] -- After simplifying, direct calculations show the subset relation as required. @@ -961,7 +961,7 @@ lemma square_subset_S_case_1 (h : (C ∩ level n).Finite) (h' : (C ∩ level (n rw [eventually_atTop, level_eq] refine ⟨max b c, ?_⟩ simp only [sup_le_iff, embed, RelEmbedding.coe_mk, Function.Embedding.coeFn_mk, - Set.mem_inter_iff, Set.mem_setOf_eq, and_imp, «forall», Prod.forall, + Set.mem_inter_iff, Set.mem_ofPred_eq, and_imp, «forall», Prod.forall, Set.subset_def, Set.mem_image, Set.mem_Ici, Prod.exists, Prod.mk_le_mk, forall_exists_index, Prod.mk.injEq, Hollom.ext_iff] rintro d hbd hcd _ _ _ e f hde hdf rfl rfl rfl g h _ hgh rfl @@ -1032,18 +1032,18 @@ theorem not_S_hits_next (f : SpinalMap C) (hC : IsChain (· ≤ ·) C) cases (C ∩ level (n + 1)).finite_or_infinite -- In the case that `C ∩ level (n + 1)` is finite, this is immediate from the definition of `S`. case inl h => - rw [S, if_pos h, Set.mem_setOf_eq] at hx + rw [S, if_pos h, Set.mem_ofPred_eq] at hx intro hy refine f.incomp_apply ?_ (hx.2 _ hy).symm have := R_subset_level hx.1 - simp only [level_eq, Set.mem_setOf_eq] at this + simp only [level_eq, Set.mem_ofPred_eq] at this intro h simp [level_eq, h, this] at hy -- So suppose it is infinite case inr h => -- Write `(x, y, n)` for our given point, and set `(a, b, n + 1) := f(x, y, n)` induction S_subset_level hx using induction_on_level with | h x y => - simp only [S, if_neg h, Set.mem_setOf_eq] at hx + simp only [S, if_neg h, Set.mem_ofPred_eq] at hx intro hp set fp := f h(x, y, n) with hfp clear_value fp diff --git a/Counterexamples/Phillips.lean b/Counterexamples/Phillips.lean index bea08c8a88d13b..53f57c8e18628f 100644 --- a/Counterexamples/Phillips.lean +++ b/Counterexamples/Phillips.lean @@ -460,7 +460,7 @@ We need the continuum hypothesis to construct it. theorem sierpinski_pathological_family (Hcont : #ℝ = ℵ₁) : ∃ f : ℝ → Set ℝ, (∀ x, (univ \ f x).Countable) ∧ ∀ y, {x : ℝ | y ∈ f x}.Countable := by obtain ⟨r, hr₁, hr₂⟩ := Cardinal.exists_rel_mk_fibers_lt ℝ - refine ⟨fun x ↦ setOf (r x), ?_, ?_⟩ + refine ⟨fun x ↦ Set.ofPred (r x), ?_, ?_⟩ · simpa [Hcont, ← Set.compl_eq_univ_sdiff] using! hr₁ · simpa [Hcont] using hr₂ @@ -512,7 +512,7 @@ theorem countable_ne (Hcont : #ℝ = ℵ₁) (φ : (DiscreteCopy ℝ →ᵇ ℝ) {x | φ.toBoundedAdditiveMeasure.continuousPart univ ≠ φ (f Hcont x)} ⊆ {x | (φ.toBoundedAdditiveMeasure.discreteSupport ∩ spf Hcont x).Nonempty} := by intro x hx - simp only [mem_setOf] at * + simp only [mem_ofPred] at * contrapose! hx exact apply_f_eq_continuousPart Hcont φ x hx |>.symm have B : @@ -520,7 +520,7 @@ theorem countable_ne (Hcont : #ℝ = ℵ₁) (φ : (DiscreteCopy ℝ →ᵇ ℝ) ⋃ y ∈ φ.toBoundedAdditiveMeasure.discreteSupport, {x | y ∈ spf Hcont x} := by intro x hx dsimp at hx - simp only [exists_prop, mem_iUnion, mem_setOf_eq] + simp only [exists_prop, mem_iUnion, mem_ofPred_eq] exact hx apply Countable.mono (Subset.trans A B) exact Countable.biUnion (countable_discreteSupport _) fun a _ => countable_spf_mem Hcont a @@ -531,7 +531,7 @@ theorem comp_ae_eq_const (Hcont : #ℝ = ℵ₁) (φ : (DiscreteCopy ℝ →ᵇ apply ae_restrict_of_ae refine measure_mono_null ?_ ((countable_ne Hcont φ).measure_zero _) intro x - simp only [imp_self, mem_setOf_eq, mem_compl_iff] + simp only [imp_self, mem_ofPred_eq, mem_compl_iff] theorem integrable_comp (Hcont : #ℝ = ℵ₁) (φ : (DiscreteCopy ℝ →ᵇ ℝ) →L[ℝ] ℝ) : IntegrableOn (fun x => φ (f Hcont x)) (Icc 0 1) := by diff --git a/Counterexamples/SeparableNotSecondCountable.lean b/Counterexamples/SeparableNotSecondCountable.lean index 235aea89afe8b5..bdc8853b913742 100644 --- a/Counterexamples/SeparableNotSecondCountable.lean +++ b/Counterexamples/SeparableNotSecondCountable.lean @@ -45,7 +45,7 @@ theorem not_secondCountableTopology : ¬SecondCountableTopology (ℝ ×ₗ Bool) intro h have : {x : ℝ ×ₗ Bool | (ofLex x).2}.Countable := by simpa [Prod.Lex.covBy_iff, Bool.covBy_iff, exists_or, not_covBy, (Bool.le_true _).not_gt, - (Bool.false_le _).lt_iff_ne] using countable_setOf_covBy_left (α := ℝ ×ₗ Bool) + (Bool.false_le _).lt_iff_ne] using countable_setOfPred_covBy_left (α := ℝ ×ₗ Bool) refine not_countable_univ <| (this.image fun x ↦ (ofLex x).1).mono fun x _ ↦ ?_ exact ⟨toLex (x, true), rfl, rfl⟩ diff --git a/Counterexamples/SorgenfreyLine.lean b/Counterexamples/SorgenfreyLine.lean index 3aa441118c278a..6618e73e90a815 100644 --- a/Counterexamples/SorgenfreyLine.lean +++ b/Counterexamples/SorgenfreyLine.lean @@ -71,7 +71,7 @@ theorem nhds_basis_Ico (a : ℝₗ) : (𝓝 a).HasBasis (a < ·) (Ico a ·) := b have : (⨅ x : { i // i ≤ a }, 𝓟 (Ici ↑x)) = 𝓟 (Ici a) := by refine (IsLeast.isGLB ?_).iInf_eq exact ⟨⟨⟨a, le_rfl⟩, rfl⟩, forall_mem_range.2 fun b => principal_mono.2 <| Ici_subset_Ici.2 b.2⟩ - simp only [mem_setOf_eq, iInf_and, iInf_exists, @iInf_comm _ (_ ∈ _), @iInf_comm _ (Set ℝₗ), + simp only [mem_ofPred_eq, iInf_and, iInf_exists, @iInf_comm _ (_ ∈ _), @iInf_comm _ (Set ℝₗ), iInf_iInf_eq_right, mem_Ico] simp_rw [@iInf_comm _ ℝₗ (_ ≤ _), iInf_subtype', ← Ici_inter_Iio, ← inf_principal, ← inf_iInf, ← iInf_inf, this, iInf_subtype] @@ -281,7 +281,7 @@ theorem not_separatedNhds_rat_irrational_antidiag : have H : {x : ℝ | Irrational x} ⊆ ⋃ n, C n := fun x hx => mem_iUnion.2 ⟨_, subset_closure ⟨hx, rfl⟩⟩ have Hd : Dense (⋃ n, interior (C n)) := - IsGδ.setOf_irrational.dense_iUnion_interior_of_closed dense_irrational + IsGδ.setOfPred_irrational.dense_iUnion_interior_of_closed dense_irrational (fun _ => isClosed_closure) H obtain ⟨N, hN⟩ : ∃ n : ℕ+, (interior <| C n).Nonempty := nonempty_iUnion.mp Hd.nonempty /- Choose a rational number `r` in the interior of the closure of `C N`, then choose `n ≥ N > 0` diff --git a/Mathlib/Algebra/AffineMonoid/Irreducible.lean b/Mathlib/Algebra/AffineMonoid/Irreducible.lean index 25361838cedfaf..55f26ba739d5a5 100644 --- a/Mathlib/Algebra/AffineMonoid/Irreducible.lean +++ b/Mathlib/Algebra/AffineMonoid/Irreducible.lean @@ -83,7 +83,7 @@ lemma Submonoid.closure_irreducible [Monoid.FG M] : obtain rfl | hr₀ := eq_or_ne r 1 · simpa using hSmax (y := S \ {1}) (by simpa) Finset.sdiff_subset hrS -- Else find `a`, `b` non-units such that `a * b = r`. - simp only [irreducible_iff, Set.mem_setOf_eq, not_and, not_forall, not_or] at hrirred + simp only [irreducible_iff, Set.mem_ofPred_eq, not_and, not_forall, not_or] at hrirred obtain ⟨a, b, hr, ha, hb⟩ := hrirred <| by simpa -- Write `a = ∏ s ∈ S, s ^ m s`, `b = ∏ s ∈ S, s ^ n s` for some coefficients `m`, `n`. obtain ⟨m, -, hm⟩ := Submonoid.mem_closure_finset (x := a).mp (by rw [hSgen]; exact mem_top _) diff --git a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index 49483234759347..47b6fce6df8a09 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean @@ -507,12 +507,12 @@ abbrev rangeRestrict (f : F) : A →ₙₐ[R] (NonUnitalAlgHom.range f : NonUnit /-- The equalizer of two non-unital `R`-algebra homomorphisms -/ def equalizer (ϕ ψ : F) : NonUnitalSubalgebra R A where carrier := {a | (ϕ a : B) = ψ a} - zero_mem' := by rw [Set.mem_setOf_eq, map_zero, map_zero] + zero_mem' := by rw [Set.mem_ofPred_eq, map_zero, map_zero] add_mem' {x y} (hx : ϕ x = ψ x) (hy : ϕ y = ψ y) := by - rw [Set.mem_setOf_eq, map_add, map_add, hx, hy] + rw [Set.mem_ofPred_eq, map_add, map_add, hx, hy] mul_mem' {x y} (hx : ϕ x = ψ x) (hy : ϕ y = ψ y) := by - rw [Set.mem_setOf_eq, map_mul, map_mul, hx, hy] - smul_mem' r x (hx : ϕ x = ψ x) := by rw [Set.mem_setOf_eq, map_smul, map_smul, hx] + rw [Set.mem_ofPred_eq, map_mul, map_mul, hx, hy] + smul_mem' r x (hx : ϕ x = ψ x) := by rw [Set.mem_ofPred_eq, map_smul, map_smul, hx] @[simp] theorem mem_equalizer (φ ψ : F) (x : A) : diff --git a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean index 4970815af4ca2f..218fdf28feb528 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean @@ -158,7 +158,7 @@ theorem preimage_algebraMap (S : Type*) {R A : Type*} [CommSemiring R] [CommSemi @[simp] theorem resolventSet_of_subsingleton [Subsingleton A] (a : A) : resolventSet R a = Set.univ := by - simp_rw [resolventSet, Subsingleton.elim (algebraMap R A _ - a) 1, isUnit_one, Set.setOf_true] + simp_rw [resolventSet, Subsingleton.elim (algebraMap R A _ - a) 1, isUnit_one, Set.ofPred_true] @[simp] theorem of_subsingleton [Subsingleton A] (a : A) : spectrum R a = ∅ := by @@ -252,11 +252,14 @@ theorem preimage_units_mul_comm (a b : A) : ((↑) : Rˣ → R) ⁻¹' σ (a * b) = (↑) ⁻¹' σ (b * a) := Set.ext fun _ => unit_mem_mul_comm -theorem setOf_isUnit_inter_mul_comm (a b : A) : +theorem setOfPred_isUnit_inter_mul_comm (a b : A) : {r | IsUnit r} ∩ σ (a * b) = {r | IsUnit r} ∩ σ (b * a) := by ext r simpa using fun hr : IsUnit r ↦ unit_mem_mul_comm (r := hr.unit) +@[deprecated (since := "2026-07-09")] +alias setOf_isUnit_inter_mul_comm := setOfPred_isUnit_inter_mul_comm + section Star variable [InvolutiveStar R] [StarRing A] [StarModule R A] diff --git a/Mathlib/Algebra/Algebra/Spectrum/Pi.lean b/Mathlib/Algebra/Algebra/Spectrum/Pi.lean index 1d02f55cde2992..cd62513370b76f 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Pi.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Pi.lean @@ -76,20 +76,20 @@ section spectrum lemma Pi.spectrum_eq [CommSemiring R] [∀ i, Ring (κ i)] [∀ i, Algebra R (κ i)] (a : ∀ i, κ i) : spectrum R a = ⋃ i, spectrum R (a i) := by apply compl_injective - simp_rw [spectrum, Set.compl_iUnion, compl_compl, resolventSet, Set.iInter_setOf, + simp_rw [spectrum, Set.compl_iUnion, compl_compl, resolventSet, Set.iInter_ofPred, Pi.isUnit_iff, sub_apply, algebraMap_apply] lemma Prod.spectrum_eq [CommSemiring R] [Ring A] [Ring B] [Algebra R A] [Algebra R B] (a : A) (b : B) : spectrum R (⟨a, b⟩ : A × B) = spectrum R a ∪ spectrum R b := by apply compl_injective - simp_rw [spectrum, Set.compl_union, compl_compl, resolventSet, ← Set.setOf_and, + simp_rw [spectrum, Set.compl_union, compl_compl, resolventSet, ← Set.ofPred_and, Prod.isUnit_iff, algebraMap_apply, mk_sub_mk] lemma Pi.quasispectrum_eq [Nonempty ι] [CommSemiring R] [∀ i, NonUnitalRing (κ i)] [∀ i, Module R (κ i)] (a : ∀ i, κ i) : quasispectrum R a = ⋃ i, quasispectrum R (a i) := by ext r - simp only [quasispectrum, Set.mem_setOf_eq, Set.mem_iUnion] + simp only [quasispectrum, Set.mem_ofPred_eq, Set.mem_iUnion] by_cases hr : IsUnit r · lift r to Rˣ using hr with r' hr' simp [isQuasiregular_pi_iff] @@ -100,7 +100,8 @@ lemma Prod.quasispectrum_eq [CommSemiring R] [NonUnitalRing A] [NonUnitalRing B] quasispectrum R (⟨a, b⟩ : A × B) = quasispectrum R a ∪ quasispectrum R b := by apply compl_injective ext r - simp only [quasispectrum, Set.mem_compl_iff, Set.mem_setOf_eq, not_forall, not_not, Set.mem_union] + simp only [quasispectrum, Set.mem_compl_iff, Set.mem_ofPred_eq, not_forall, not_not, + Set.mem_union] by_cases hr : IsUnit r · lift r to Rˣ using hr with r' hr' simp [isQuasiregular_prod_iff] diff --git a/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean b/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean index 89ea7868bed4fa..d8518f393142d0 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Quasispectrum.lean @@ -279,7 +279,7 @@ lemma NonUnitalAlgHom.quasispectrum_apply_subset' {F R : Type*} (S : Type*) {A B [FunLike F A B] [NonUnitalAlgHomClass F S A B] (φ : F) (a : A) : quasispectrum R (φ a) ⊆ quasispectrum R a := by refine Set.compl_subset_compl.mp fun x ↦ ?_ - simp only [quasispectrum, Set.mem_compl_iff, Set.mem_setOf_eq, not_forall, not_not, + simp only [quasispectrum, Set.mem_compl_iff, Set.mem_ofPred_eq, not_forall, not_not, forall_exists_index] refine fun hx this ↦ ⟨hx, ?_⟩ rw [Units.smul_def, ← smul_one_smul S] at this ⊢ @@ -304,7 +304,7 @@ lemma quasispectrum_eq_spectrum_union (R : Type*) {A : Type*} [CommSemiring R] [Ring A] [Algebra R A] (a : A) : quasispectrum R a = spectrum R a ∪ {r : R | ¬ IsUnit r} := by ext r rw [quasispectrum] - simp only [Set.mem_setOf_eq, Set.mem_union, ← imp_iff_or_not, spectrum.mem_iff] + simp only [Set.mem_ofPred_eq, Set.mem_union, ← imp_iff_or_not, spectrum.mem_iff] congr! 1 with hr rw [not_iff_not, isQuasiregular_iff_isUnit, ← sub_eq_add_neg, Algebra.algebraMap_eq_smul_one] exact (IsUnit.smul_sub_iff_sub_inv_smul hr.unit a).symm @@ -382,7 +382,7 @@ lemma quasispectrum.mul_comm {R A : Type*} [CommRing R] [NonUnitalRing A] [Modul ← Set.inter_union_compl (quasispectrum R (b * a)) {r | IsUnit r}] congr! 1 · simpa [Set.inter_comm _ {r | IsUnit r}, Unitization.quasispectrum_eq_spectrum_inr, - Unitization.inr_mul] using spectrum.setOf_isUnit_inter_mul_comm _ _ + Unitization.inr_mul] using spectrum.setOfPred_isUnit_inter_mul_comm _ _ · rw [Set.inter_eq_right.mpr, Set.inter_eq_right.mpr] all_goals exact fun _ ↦ quasispectrum.not_isUnit_mem _ diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean index 06c6fc29c2b983..4c38a04387d2e4 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean @@ -1022,14 +1022,14 @@ variable {R A B : Type*} [CommSemiring R] [Semiring A] [Algebra R A] [Semiring B @[simps coe toSubsemiring] def equalizer (ϕ ψ : A →ₐ[R] B) : Subalgebra R A where carrier := { a | ϕ a = ψ a } - zero_mem' := by simp only [Set.mem_setOf_eq, map_zero] - one_mem' := by simp only [Set.mem_setOf_eq, map_one] + zero_mem' := by simp only [Set.mem_ofPred_eq, map_zero] + one_mem' := by simp only [Set.mem_ofPred_eq, map_one] add_mem' {x y} (hx : ϕ x = ψ x) (hy : ϕ y = ψ y) := by - rw [Set.mem_setOf_eq, map_add, map_add, hx, hy] + rw [Set.mem_ofPred_eq, map_add, map_add, hx, hy] mul_mem' {x y} (hx : ϕ x = ψ x) (hy : ϕ y = ψ y) := by - rw [Set.mem_setOf_eq, map_mul, map_mul, hx, hy] + rw [Set.mem_ofPred_eq, map_mul, map_mul, hx, hy] algebraMap_mem' x := by - simp only [Set.mem_setOf_eq, AlgHomClass.commutes] + simp only [Set.mem_ofPred_eq, AlgHomClass.commutes] @[simp] theorem mem_equalizer (φ ψ : A →ₐ[R] B) (x : A) : x ∈ equalizer φ ψ ↔ φ x = ψ x := diff --git a/Mathlib/Algebra/BigOperators/Associated.lean b/Mathlib/Algebra/BigOperators/Associated.lean index a5fb4e8c160e0b..e87c5cd6348a1f 100644 --- a/Mathlib/Algebra/BigOperators/Associated.lean +++ b/Mathlib/Algebra/BigOperators/Associated.lean @@ -95,9 +95,9 @@ theorem divisor_closure_eq_closure [CommMonoidWithZero M₀] [IsCancelMulZero M simp only [Multiset.prod_zero] at hprod left; exact .of_mul_eq_one _ hprod.symm | cons c s hind => - simp only [Multiset.mem_cons, forall_eq_or_imp, Set.mem_setOf] at hm + simp only [Multiset.mem_cons, forall_eq_or_imp, Set.mem_ofPred] at hm simp only [Multiset.prod_cons] at hprod - simp only [Set.mem_setOf_eq] at hind + simp only [Set.mem_ofPred_eq] at hind obtain ⟨ha₁ | ha₂, hs⟩ := hm · rcases ha₁.exists_right_inv with ⟨k, hk⟩ refine hind x (y * k) ?_ hs ?_ diff --git a/Mathlib/Algebra/Category/Ring/Topology.lean b/Mathlib/Algebra/Category/Ring/Topology.lean index 0091d90b2d3289..de7bcc590ee314 100644 --- a/Mathlib/Algebra/Category/Ring/Topology.lean +++ b/Mathlib/Algebra/Category/Ring/Topology.lean @@ -99,7 +99,7 @@ lemma isClosedEmbedding_precomp_of_surjective isClosed_iInter fun x ↦ (isClosed_singleton (x := 0)).preimage (continuous_apply (R := R) x.1) convert! this ext x - simp only [Set.mem_range, Set.mem_iInter, Set.mem_setOf_eq, Subtype.forall, RingHom.mem_ker] + simp only [Set.mem_range, Set.mem_iInter, Set.mem_ofPred_eq, Subtype.forall, RingHom.mem_ker] constructor · rintro ⟨g, rfl⟩ a ha; simp [ha] · exact fun H ↦ ⟨CommRingCat.ofHom (RingHom.liftOfSurjective f.hom hf ⟨x.hom, H⟩), diff --git a/Mathlib/Algebra/FiniteSupport/Basic.lean b/Mathlib/Algebra/FiniteSupport/Basic.lean index d4a8e2c5c0c6eb..9efd55fd9e1d9b 100644 --- a/Mathlib/Algebra/FiniteSupport/Basic.lean +++ b/Mathlib/Algebra/FiniteSupport/Basic.lean @@ -181,7 +181,7 @@ lemma HasFiniteMulSupport.fun_comp_of_injective (hg : Injective g) (hf : f.HasFi lemma HasFiniteMulSupport.of_comp [One β] (hfg : (f ∘ g).HasFiniteMulSupport) (h : f 1 = 1) (hf : Injective f) : g.HasFiniteMulSupport := by - refine Set.Finite.subset hfg fun _ ha ↦ Set.mem_setOf.mpr fun H ↦ Set.mem_setOf.mp ha ?_ + refine Set.Finite.subset hfg fun _ ha ↦ Set.mem_ofPred.mpr fun H ↦ Set.mem_ofPred.mp ha ?_ grind -- The additive version is a special case of `Function.HasFiniteSupport.smul_left`. diff --git a/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean index 4431b953987b0d..d8b8eff457a715 100644 --- a/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Action/Pointwise/Set/Basic.lean @@ -293,8 +293,14 @@ theorem iUnion_inv_smul : ⋃ g : α, g⁻¹ • s = ⋃ g : α, g • s := (Function.Surjective.iSup_congr _ inv_surjective) fun _ ↦ rfl @[to_additive] -theorem iUnion_smul_eq_setOf_exists {s : Set β} : ⋃ g : α, g • s = { a | ∃ g : α, g • a ∈ s } := by - simp_rw [← iUnion_setOf, ← iUnion_inv_smul, ← preimage_smul, preimage] +theorem iUnion_smul_eq_ofPred_exists {s : Set β} : ⋃ g : α, g • s = { a | ∃ g : α, g • a ∈ s } := by + simp_rw [← iUnion_ofPred, ← iUnion_inv_smul, ← preimage_smul, preimage] + +@[deprecated (since := "2026-07-09")] +alias iUnion_smul_eq_setOf_exists := iUnion_smul_eq_ofPred_exists + +@[deprecated (since := "2026-07-09")] +alias iUnion_vadd_eq_setOf_exists := iUnion_vadd_eq_ofPred_exists @[to_additive (attr := simp)] lemma inv_smul_set_distrib (a : α) (s : Set α) : (a • s)⁻¹ = op a⁻¹ • s⁻¹ := by diff --git a/Mathlib/Algebra/Group/Center.lean b/Mathlib/Algebra/Group/Center.lean index 4df0b272320399..e70bb00a9141c7 100644 --- a/Mathlib/Algebra/Group/Center.lean +++ b/Mathlib/Algebra/Group/Center.lean @@ -124,7 +124,7 @@ lemma center_subset_centralizer (S : Set M) : Set.center M ⊆ S.centralizer := @[to_additive addCentralizer_union] lemma centralizer_union : centralizer (S ∪ T) = centralizer S ∩ centralizer T := by - simp [centralizer, or_imp, forall_and, setOf_and] + simp [centralizer, or_imp, forall_and, ofPred_and] @[to_additive (attr := gcongr) addCentralizer_subset] lemma centralizer_subset (h : S ⊆ T) : centralizer T ⊆ centralizer S := fun _ ht s hs ↦ ht s (h hs) diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean index 16b7b3e0ef6e9a..014095bb573ff5 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Basic.lean @@ -159,9 +159,12 @@ section Inv variable {ι : Sort*} [Inv α] {s t : Set α} {a : α} @[to_additive (attr := simp)] -theorem inv_setOf (p : α → Prop) : {x | p x}⁻¹ = {x | p x⁻¹} := +theorem inv_ofPred (p : α → Prop) : {x | p x}⁻¹ = {x | p x⁻¹} := rfl +@[deprecated (since := "2026-07-09")] alias inv_setOf := inv_ofPred +@[deprecated (since := "2026-07-09")] alias neg_setOf := neg_ofPred + @[to_additive (attr := simp, push)] theorem mem_inv : a ∈ s⁻¹ ↔ a⁻¹ ∈ s := Iff.rfl diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 66e94cd9c1cebd..fd1aadbc25f00c 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -524,7 +524,7 @@ def conjugatesOfSet (s : Set G) : Set G := @[to_additive] theorem mem_conjugatesOfSet_iff {x : G} : x ∈ conjugatesOfSet s ↔ ∃ a ∈ s, IsConj a x := by rw [conjugatesOfSet, Set.mem_iUnion₂] - simp only [conjugatesOf, isConj_iff, Set.mem_setOf_eq, exists_prop] + simp only [conjugatesOf, isConj_iff, Set.mem_ofPred_eq, exists_prop] @[to_additive] theorem subset_conjugatesOfSet : s ⊆ conjugatesOfSet s := fun (x : G) (h : x ∈ s) => diff --git a/Mathlib/Algebra/Group/Subgroup/Lattice.lean b/Mathlib/Algebra/Group/Subgroup/Lattice.lean index 0101300c46195a..39795007baa68c 100644 --- a/Mathlib/Algebra/Group/Subgroup/Lattice.lean +++ b/Mathlib/Algebra/Group/Subgroup/Lattice.lean @@ -555,7 +555,7 @@ theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {K : ι → Subgroup G} (h have : iSup K = ⨆ i : PLift ι, ⨆ (_ : True), K i.down := by simp [iSup_plift_down] rw [this, mem_biSup_of_directedOn trivial] · simp - · simp only [setOf_true] + · simp only [ofPred_true] rw [directedOn_onFun_iff, Set.image_univ, directedOn_range] -- `Directed.mono_comp` and much of the Set API requires `Type u` instead of `Sort u` intro i diff --git a/Mathlib/Algebra/Group/Subgroup/MulOppositeLemmas.lean b/Mathlib/Algebra/Group/Subgroup/MulOppositeLemmas.lean index 982d45461cfffc..78551c5eba913f 100644 --- a/Mathlib/Algebra/Group/Subgroup/MulOppositeLemmas.lean +++ b/Mathlib/Algebra/Group/Subgroup/MulOppositeLemmas.lean @@ -107,7 +107,7 @@ theorem unop_iInf (S : ι → Subgroup Gᵐᵒᵖ) : (iInf S).unop = ⨅ i, (S i @[to_additive] theorem op_closure (s : Set G) : (closure s).op = closure (MulOpposite.unop ⁻¹' s) := by - simp_rw [closure, op_sInf, Set.preimage_setOf_eq, Subgroup.coe_unop] + simp_rw [closure, op_sInf, Set.preimage_ofPred_eq, Subgroup.coe_unop] congr with a exact MulOpposite.unop_surjective.forall diff --git a/Mathlib/Algebra/Group/Submonoid/Basic.lean b/Mathlib/Algebra/Group/Submonoid/Basic.lean index e080248b0791ed..70af6fb8736879 100644 --- a/Mathlib/Algebra/Group/Submonoid/Basic.lean +++ b/Mathlib/Algebra/Group/Submonoid/Basic.lean @@ -346,18 +346,18 @@ section IsUnit /-- The submonoid consisting of the units of a monoid -/ @[to_additive /-- The additive submonoid consisting of the additive units of an additive monoid -/] def IsUnit.submonoid (M : Type*) [Monoid M] : Submonoid M where - carrier := setOf IsUnit - one_mem' := by simp only [isUnit_one, Set.mem_setOf_eq] + carrier := Set.ofPred IsUnit + one_mem' := by simp only [isUnit_one, Set.mem_ofPred_eq] mul_mem' := by intro a b ha hb - rw [Set.mem_setOf_eq] at * + rw [Set.mem_ofPred_eq] at * exact IsUnit.mul ha hb @[to_additive] theorem IsUnit.mem_submonoid_iff {M : Type*} [Monoid M] (a : M) : a ∈ IsUnit.submonoid M ↔ IsUnit a := by - change a ∈ setOf IsUnit ↔ IsUnit a - rw [Set.mem_setOf_eq] + change a ∈ Set.ofPred IsUnit ↔ IsUnit a + rw [Set.mem_ofPred_eq] end IsUnit diff --git a/Mathlib/Algebra/Group/Submonoid/Defs.lean b/Mathlib/Algebra/Group/Submonoid/Defs.lean index 5773ce82160051..5ea0a128ae4552 100644 --- a/Mathlib/Algebra/Group/Submonoid/Defs.lean +++ b/Mathlib/Algebra/Group/Submonoid/Defs.lean @@ -317,7 +317,7 @@ open Submonoid @[to_additive /-- The additive submonoid of elements `x : M` such that `f x = g x` -/] def eqLocusM (f g : M →* N) : Submonoid M where carrier := { x | f x = g x } - one_mem' := by rw [Set.mem_setOf_eq, f.map_one, g.map_one] + one_mem' := by rw [Set.mem_ofPred_eq, f.map_one, g.map_one] mul_mem' (hx : _ = _) (hy : _ = _) := by simp [*] @[to_additive (attr := simp)] diff --git a/Mathlib/Algebra/Group/Submonoid/MulOpposite.lean b/Mathlib/Algebra/Group/Submonoid/MulOpposite.lean index aaf2d55239f3e5..48715caa338ad4 100644 --- a/Mathlib/Algebra/Group/Submonoid/MulOpposite.lean +++ b/Mathlib/Algebra/Group/Submonoid/MulOpposite.lean @@ -170,7 +170,7 @@ theorem unop_iInf (S : ι → Submonoid Mᵐᵒᵖ) : (iInf S).unop = ⨅ i, (S @[to_additive] theorem op_closure (s : Set M) : (closure s).op = closure (MulOpposite.unop ⁻¹' s) := by - simp_rw [closure, op_sInf, Set.preimage_setOf_eq, Submonoid.coe_unop] + simp_rw [closure, op_sInf, Set.preimage_ofPred_eq, Submonoid.coe_unop] congr with a exact MulOpposite.unop_surjective.forall diff --git a/Mathlib/Algebra/Group/Subsemigroup/MulOpposite.lean b/Mathlib/Algebra/Group/Subsemigroup/MulOpposite.lean index e783682e5f5864..c477bf9df23ae7 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/MulOpposite.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/MulOpposite.lean @@ -160,7 +160,7 @@ theorem unop_iInf (S : ι → Subsemigroup Mᵐᵒᵖ) : (iInf S).unop = ⨅ i, @[to_additive] theorem op_closure (s : Set M) : (closure s).op = closure (MulOpposite.unop ⁻¹' s) := by - simp_rw [closure, op_sInf, Set.preimage_setOf_eq, Subsemigroup.coe_unop] + simp_rw [closure, op_sInf, Set.preimage_ofPred_eq, Subsemigroup.coe_unop] congr with a exact MulOpposite.unop_surjective.forall diff --git a/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean b/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean index 40dc44026944e1..66fd240db88eae 100644 --- a/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean +++ b/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean @@ -78,7 +78,7 @@ lemma nonZeroDivisorsLeft_eq_right (M₀ : Type*) [CommMonoidWithZero M₀] : @[simp] lemma coe_nonZeroDivisorsLeft_eq [NoZeroDivisors M₀] [Nontrivial M₀] : nonZeroDivisorsLeft M₀ = {x : M₀ | x ≠ 0} := by ext x - simp only [SetLike.mem_coe, mem_nonZeroDivisorsLeft_iff, mul_eq_zero, Set.mem_setOf_eq] + simp only [SetLike.mem_coe, mem_nonZeroDivisorsLeft_iff, mul_eq_zero, Set.mem_ofPred_eq] refine ⟨fun h ↦ ?_, fun hx y hx' ↦ by simp_all⟩ contrapose! h exact ⟨1, Or.inl h, one_ne_zero⟩ @@ -87,7 +87,7 @@ lemma nonZeroDivisorsLeft_eq_right (M₀ : Type*) [CommMonoidWithZero M₀] : nonZeroDivisorsRight M₀ = {x : M₀ | x ≠ 0} := by ext x simp only [SetLike.mem_coe, mem_nonZeroDivisorsRight_iff, mul_eq_zero, forall_eq_or_imp, true_and, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] refine ⟨fun h ↦ ?_, fun hx y hx' ↦ by contradiction⟩ contrapose! h exact ⟨1, h, one_ne_zero⟩ diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index 7d3ea6fd41faa6..69d1f273373b75 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -43,7 +43,7 @@ namespace HomComplex /-- The subgroup of `Cocycle K L n` consisting of coboundaries. -/ def coboundaries : AddSubgroup (Cocycle K L n) where - carrier := setOf (fun α ↦ ∃ (m : ℤ) (hm : m + 1 = n) (β : Cochain K L m), δ m n β = α) + carrier := Set.ofPred (fun α ↦ ∃ (m : ℤ) (hm : m + 1 = n) (β : Cochain K L m), δ m n β = α) zero_mem' := ⟨n - 1, by simp, 0, by simp⟩ add_mem' := by rintro α₁ α₂ ⟨m, hm, β₁, hβ₁⟩ ⟨m', hm', β₂, hβ₂⟩ @@ -145,7 +145,7 @@ lemma toHom_mk_eq_zero_iff (x : Cocycle K L n) : toHom (mk x) = 0 ↔ x ∈ coboundaries K L n := by refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ · simp only [coboundaries, exists_prop, AddSubgroup.mem_mk, AddSubmonoid.mem_mk, - AddSubsemigroup.mem_mk, Set.mem_setOf_eq] + AddSubsemigroup.mem_mk, Set.mem_ofPred_eq] rw [toHom_mk, HomotopyCategory.quotient_map_eq_zero_iff] at h obtain ⟨γ, h⟩ := Cochain.equivHomotopy _ _ h.some simp only [Cochain.ofHom_zero, add_zero, Cocycle.equivHomShift_symm_apply, diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean index b6a656aa516bf1..5b0fefb066cba4 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean @@ -143,7 +143,7 @@ lemma isKInjective_of_injective (L : CochainComplex C ℤ) (d : ℤ) `isKInjective_of_injective_aux` in order to get better approximations, and we pass to the limit. -/ let X (n : ℕ) : Set (Cochain K L (-1)) := - setOf (fun α => (δ (-1) 0 α).EqUpTo (Cochain.ofHom f) (n + d - 1)) + Set.ofPred (fun α => (δ (-1) 0 α).EqUpTo (Cochain.ofHom f) (n + d - 1)) let x₀ : X 0 := ⟨0, fun p q hpq hp ↦ IsZero.eq_of_tgt (L.isZero_of_isStrictlyGE d _ (by lia)) _ _⟩ let φ (n : ℕ) (α : X n) : X (n + 1) := diff --git a/Mathlib/Algebra/Lie/Abelian.lean b/Mathlib/Algebra/Lie/Abelian.lean index 43c6f90d13b74d..f5aeda58e16597 100644 --- a/Mathlib/Algebra/Lie/Abelian.lean +++ b/Mathlib/Algebra/Lie/Abelian.lean @@ -353,7 +353,7 @@ theorem LieSubmodule.trivial_lie_oper_zero [LieModule.IsTrivial L M] : ⁅I, N theorem LieSubmodule.lie_abelian_iff_lie_self_eq_bot : IsLieAbelian I ↔ ⁅I, I⁆ = ⊥ := by simp only [_root_.eq_bot_iff, lieIdeal_oper_eq_span, LieSubmodule.lieSpan_le, - LieSubmodule.bot_coe, Set.subset_singleton_iff, Set.mem_setOf_eq, exists_imp] + LieSubmodule.bot_coe, Set.subset_singleton_iff, Set.mem_ofPred_eq, exists_imp] refine ⟨fun h z x y hz => hz.symm.trans diff --git a/Mathlib/Algebra/Lie/Basis.lean b/Mathlib/Algebra/Lie/Basis.lean index 85a7b0df5153a2..8c19d3ebae5487 100644 --- a/Mathlib/Algebra/Lie/Basis.lean +++ b/Mathlib/Algebra/Lie/Basis.lean @@ -404,10 +404,10 @@ lemma iSupIndep_rootSpace : set sV : Set (b.cartan → R) := {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • b.baseSupp i} with hsV have hs0' : rootSpace b.cartan 0 = ⨆ i ∈ s0, LieModule.genWeightSpace L i := by simp [hs0] have hsU' : U = ⨆ i ∈ sU, LieModule.genWeightSpace L i := by - simp only [hU, hsU, mem_setOf_eq, iSup_exists, iSup_and, iSup_comm (ι := b.cartan → R), + simp only [hU, hsU, mem_ofPred_eq, iSup_exists, iSup_and, iSup_comm (ι := b.cartan → R), iSup_iSup_eq_left, LinearMap.coe_sum, LinearMap.coe_smul] have hsV' : V = ⨆ i ∈ sV, LieModule.genWeightSpace L i := by - simp only [hV, hsV, mem_setOf_eq, iSup_exists, iSup_and, iSup_comm (ι := b.cartan → R), + simp only [hV, hsV, mem_ofPred_eq, iSup_exists, iSup_and, iSup_comm (ι := b.cartan → R), iSup_iSup_eq_left, LinearMap.coe_sum, LinearMap.coe_smul] have hU0 : Disjoint s0 sU := by suffices ∀ g ∈ sU, g ≠ 0 by @@ -531,7 +531,7 @@ lemma root_mem_or_mem_neg (χ : b.cartan.root) : (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = ∑ i, n i • b.baseSupp i) := by have hχ' : ¬ χ.IsZero := by simpa using hχ simp only [hχ', s, singleton_union, mem_union, mem_insert_iff, Weight.coe_eq_zero_iff, - mem_setOf_eq, false_or] at hs + mem_ofPred_eq, false_or] at hs simpa only [← LinearMap.coe_neg, ← Weight.coe_coe, LinearMap.coe_injective.eq_iff] using hs refine hs.symm.imp (fun ⟨n, hn₀, hn⟩ ↦ ?_) (fun ⟨n, hn₀, hn⟩ ↦ ?_) <;> simpa [hn] using this n diff --git a/Mathlib/Algebra/Lie/Character.lean b/Mathlib/Algebra/Lie/Character.lean index b4882120742afb..230e525f145162 100644 --- a/Mathlib/Algebra/Lie/Character.lean +++ b/Mathlib/Algebra/Lie/Character.lean @@ -55,7 +55,7 @@ theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L} LieSubmodule.mem_toSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h induction h using Submodule.span_induction with | mem y h => - simp only [Subtype.exists, LieSubmodule.mem_top, exists_const, Set.mem_setOf_eq] at h + simp only [Subtype.exists, LieSubmodule.mem_top, exists_const, Set.mem_ofPred_eq] at h obtain ⟨z, w, rfl⟩ := h exact lieCharacter_apply_lie .. | zero => exact map_zero _ diff --git a/Mathlib/Algebra/Lie/IdealOperations.lean b/Mathlib/Algebra/Lie/IdealOperations.lean index 830d6a71329130..8f886f7c646e8e 100644 --- a/Mathlib/Algebra/Lie/IdealOperations.lean +++ b/Mathlib/Algebra/Lie/IdealOperations.lean @@ -279,7 +279,7 @@ theorem comap_bracket_eq {J₁ J₂ : LieIdeal R L'} (h : f.IsIdealMorphism) : congr ext simp_all only [Subtype.exists, LieSubmodule.mem_inf, LieHom.mem_idealRange_iff, exists_prop, - Set.mem_setOf_eq, LieHom.coe_toLinearMap, mem_comap, + Set.mem_ofPred_eq, LieHom.coe_toLinearMap, mem_comap, exists_exists_and_exists_and_eq_and, LieHom.map_lie] grind diff --git a/Mathlib/Algebra/Lie/InvariantForm.lean b/Mathlib/Algebra/Lie/InvariantForm.lean index 18f81272293a12..d1c5831cd59868 100644 --- a/Mathlib/Algebra/Lie/InvariantForm.lean +++ b/Mathlib/Algebra/Lie/InvariantForm.lean @@ -172,7 +172,7 @@ lemma atomistic : ∀ I : LieIdeal K L, sSup {J : LieIdeal K L | IsAtom J ∧ J · exact le_sSup ⟨hJ, hJI⟩ rw [← atomistic (J' ⊓ I)] apply sSup_le_sSup - simp only [le_inf_iff, Set.setOf_subset_setOf, and_imp] + simp only [le_inf_iff, Set.ofPred_subset_ofPred, and_imp] tauto suffices J ⊔ J' = ⊤ by rw [← sup_inf_assoc_of_le _ hJI, this, top_inf_eq] exact (orthogonal_isCompl Φ hΦ_nondeg hΦ_inv hΦ_refl hL J hJ).codisjoint.eq_top @@ -198,11 +198,11 @@ theorem isSemisimple_of_nondegenerate : IsSemisimple K L := by intro I hI apply (orthogonal_disjoint Φ hΦ_nondeg hΦ_inv hL I hI).mono_right apply sSup_le - simp only [Set.mem_sdiff, Set.mem_setOf_eq, Set.mem_singleton_iff, and_imp] + simp only [Set.mem_sdiff, Set.mem_ofPred_eq, Set.mem_singleton_iff, and_imp] intro J hJ hJI rw [← lie_eq_self_of_isAtom_of_nonabelian J hJ (hL J hJ), lieIdeal_oper_eq_span, lieSpan_le] rintro _ ⟨x, y, rfl⟩ - simp only [orthogonal_carrier, Set.mem_setOf_eq] + simp only [orthogonal_carrier, Set.mem_ofPred_eq] intro z hz rw [← neg_eq_zero, ← hΦ_inv] suffices ⁅(x : L), z⁆ = 0 by simp only [this, map_zero, LinearMap.zero_apply] diff --git a/Mathlib/Algebra/Lie/LieTheorem.lean b/Mathlib/Algebra/Lie/LieTheorem.lean index 24c3d02bf21ebf..c9a4b6f4c823dd 100644 --- a/Mathlib/Algebra/Lie/LieTheorem.lean +++ b/Mathlib/Algebra/Lie/LieTheorem.lean @@ -71,7 +71,7 @@ private lemma weightSpaceOfIsLieTower_aux (z : L) (v : V) (hv : v ∈ weightSpac have T_apply_succ (w : A) (n : ℕ) : Submodule.map (T χ w) (U' (n + 1)) ≤ U' n := by simp only [OrderHom.coe_mk, U', Submodule.map_span, Submodule.span_le, Set.image_subset_iff] - simp only [Set.subset_def, Set.mem_setOf_eq, Set.mem_preimage, SetLike.mem_coe, + simp only [Set.subset_def, Set.mem_ofPred_eq, Set.mem_preimage, SetLike.mem_coe, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] induction n generalizing w · simp only [zero_add, Nat.lt_one_iff, LinearMap.sub_apply, LieModule.toEnd_apply_apply, diff --git a/Mathlib/Algebra/Lie/Nilpotent.lean b/Mathlib/Algebra/Lie/Nilpotent.lean index 6057a30d645de4..60654f257ddb20 100644 --- a/Mathlib/Algebra/Lie/Nilpotent.lean +++ b/Mathlib/Algebra/Lie/Nilpotent.lean @@ -195,7 +195,7 @@ theorem trivial_iff_lower_central_eq_bot : IsTrivial L M ↔ lowerCentralSeries · simp · rw [LieSubmodule.eq_bot_iff] at h; apply IsTrivial.mk; intro x m; apply h apply LieSubmodule.subset_lieSpan - simp only [Subtype.exists, LieSubmodule.mem_top, exists_prop, true_and, Set.mem_setOf] + simp only [Subtype.exists, LieSubmodule.mem_top, exists_prop, true_and, Set.mem_ofPred] exact ⟨x, m, rfl⟩ section diff --git a/Mathlib/Algebra/Lie/Semisimple/Basic.lean b/Mathlib/Algebra/Lie/Semisimple/Basic.lean index e84e6d1937976e..85a7ece2121e54 100644 --- a/Mathlib/Algebra/Lie/Semisimple/Basic.lean +++ b/Mathlib/Algebra/Lie/Semisimple/Basic.lean @@ -139,7 +139,7 @@ lemma isSimple_of_isAtom (I : LieIdeal R L) (hI : IsAtom I) : IsSimple R I where rw [← sSup_union, Set.union_sdiff_self, Set.union_eq_self_of_subset_left, IsSemisimple.sSup_atoms_eq_top] · apply LieSubmodule.mem_top - · simp only [Set.singleton_subset_iff, Set.mem_setOf_eq, hI] + · simp only [Set.singleton_subset_iff, Set.mem_ofPred_eq, hI] -- Hence we can write `x` as `a + b` with `a ∈ I` -- and `b` in the supremum of the atoms not equal to `I`. rw [LieSubmodule.mem_sup] at hx diff --git a/Mathlib/Algebra/Lie/Solvable.lean b/Mathlib/Algebra/Lie/Solvable.lean index bb82448d13643e..abaada42a8cccb 100644 --- a/Mathlib/Algebra/Lie/Solvable.lean +++ b/Mathlib/Algebra/Lie/Solvable.lean @@ -371,7 +371,7 @@ instance radicalIsSolvable [IsNoetherian R L] : IsSolvable (radical R L) := by rw [← CompleteLattice.isSupClosedCompact_iff_wellFoundedGT] at hwf refine hwf { I : LieIdeal R L | IsSolvable I } ⟨⊥, ?_⟩ fun I hI J hJ => ?_ · exact LieAlgebra.isSolvableBot R L - · rw [Set.mem_setOf_eq] at hI hJ ⊢ + · rw [Set.mem_ofPred_eq] at hI hJ ⊢ apply LieAlgebra.isSolvableAdd R L /-- The `→` direction of this lemma is actually true without the `IsNoetherian` assumption. -/ diff --git a/Mathlib/Algebra/Lie/Subalgebra.lean b/Mathlib/Algebra/Lie/Subalgebra.lean index 66b8058de3041c..c7c82acb21f2f7 100644 --- a/Mathlib/Algebra/Lie/Subalgebra.lean +++ b/Mathlib/Algebra/Lie/Subalgebra.lean @@ -440,7 +440,7 @@ instance : InfSet (LieSubalgebra R L) := ⟨fun S ↦ { sInf {(s : Submodule R L) | s ∈ S} with lie_mem' := @fun x y hx hy ↦ by - simp only [Submodule.mem_carrier, mem_iInter, Submodule.coe_sInf, mem_setOf_eq, + simp only [Submodule.mem_carrier, mem_iInter, Submodule.coe_sInf, mem_ofPred_eq, forall_apply_eq_imp_iff₂, exists_imp, and_imp] at hx hy ⊢ intro K hK exact K.lie_mem (hx K hK) (hy K hK) }⟩ diff --git a/Mathlib/Algebra/Lie/Submodule.lean b/Mathlib/Algebra/Lie/Submodule.lean index 8c2f4846992481..c7d9b6bfbbec78 100644 --- a/Mathlib/Algebra/Lie/Submodule.lean +++ b/Mathlib/Algebra/Lie/Submodule.lean @@ -323,7 +323,7 @@ instance : InfSet (LieSubmodule R L M) := ⟨fun S ↦ { toSubmodule := sInf {(s : Submodule R M) | s ∈ S} lie_mem := fun {x m} h ↦ by - simp only [Submodule.mem_carrier, mem_iInter, Submodule.coe_sInf, mem_setOf_eq, + simp only [Submodule.mem_carrier, mem_iInter, Submodule.coe_sInf, mem_ofPred_eq, forall_apply_eq_imp_iff₂, forall_exists_index, and_imp] at h ⊢ intro N hN; apply N.lie_mem (h N hN) }⟩ @@ -354,7 +354,7 @@ theorem iInf_toSubmodule {ι} (p : ι → LieSubmodule R L M) : theorem coe_sInf (S : Set (LieSubmodule R L M)) : (↑(sInf S) : Set M) = ⋂ s ∈ S, (s : Set M) := by rw [← LieSubmodule.coe_toSubmodule, sInf_toSubmodule, Submodule.coe_sInf] ext m - simp only [mem_iInter, mem_setOf_eq, forall_apply_eq_imp_iff₂, exists_imp, + simp only [mem_iInter, mem_ofPred_eq, forall_apply_eq_imp_iff₂, exists_imp, and_imp, SetLike.mem_coe, mem_toSubmodule] @[simp] diff --git a/Mathlib/Algebra/Lie/Weights/Basic.lean b/Mathlib/Algebra/Lie/Weights/Basic.lean index e3c007ab485e30..e9e42df896bd58 100644 --- a/Mathlib/Algebra/Lie/Weights/Basic.lean +++ b/Mathlib/Algebra/Lie/Weights/Basic.lean @@ -269,12 +269,14 @@ noncomputable instance : DecidablePred (IsNonZero (R := R) (L := L) (M := M)) := set_option backward.isDefEq.respectTransparency.types false in variable (R L M) in /-- The set of weights is equivalent to a subtype. -/ -def equivSetOf : Weight R L M ≃ {χ : L → R | genWeightSpace M χ ≠ ⊥} where +def equivSetOfPred : Weight R L M ≃ {χ : L → R | genWeightSpace M χ ≠ ⊥} where toFun w := ⟨w.1, w.2⟩ invFun w := ⟨w.1, w.2⟩ left_inv w := by simp right_inv w := by simp +@[deprecated (since := "2026-07-09")] alias equivSetOf := equivSetOfPred + lemma genWeightSpaceOf_ne_bot (χ : Weight R L M) (x : L) : genWeightSpaceOf M (χ x) x ≠ ⊥ := by have : ⨅ x, genWeightSpaceOf M (χ x) x ≠ ⊥ := χ.genWeightSpace_ne_bot @@ -673,7 +675,7 @@ lemma iSupIndep_genWeightSpace : iSupIndep fun χ : L → R ↦ genWeightSpace M lemma iSupIndep_genWeightSpace' : iSupIndep fun χ : Weight R L M ↦ genWeightSpace M χ := (iSupIndep_genWeightSpace R L M).comp <| - Subtype.val_injective.comp (Weight.equivSetOf R L M).injective + Subtype.val_injective.comp (Weight.equivSetOfPred R L M).injective lemma iSupIndep_genWeightSpaceOf (x : L) : iSupIndep fun (χ : R) ↦ genWeightSpaceOf M χ x := by rw [← LieSubmodule.iSupIndep_toSubmodule] @@ -690,7 +692,7 @@ lemma finite_genWeightSpace_ne_bot [IsNoetherian R M] : instance Weight.instFinite [IsNoetherian R M] : Finite (Weight R L M) := by have : Finite {χ : L → R | genWeightSpace M χ ≠ ⊥} := finite_genWeightSpace_ne_bot R L M - exact Finite.of_injective (equivSetOf R L M) (equivSetOf R L M).injective + exact Finite.of_injective (equivSetOfPred R L M) (equivSetOfPred R L M).injective noncomputable instance Weight.instFintype [IsNoetherian R M] : Fintype (Weight R L M) := .ofFinite _ @@ -773,7 +775,7 @@ lemma iSup_genWeightSpace_eq_top [IsTriangularizable K L M] : lemma iSup_genWeightSpace_eq_top' [IsTriangularizable K L M] : ⨆ χ : Weight K L M, genWeightSpace M χ = ⊤ := by have := iSup_genWeightSpace_eq_top K L M - erw [← iSup_ne_bot_subtype, ← (Weight.equivSetOf K L M).iSup_comp] at this + erw [← iSup_ne_bot_subtype, ← (Weight.equivSetOfPred K L M).iSup_comp] at this exact this lemma eq_iSup_inf_genWeightSpace [IsTriangularizable K L M] (N : LieSubmodule K L M) : diff --git a/Mathlib/Algebra/Lie/Weights/Cartan.lean b/Mathlib/Algebra/Lie/Weights/Cartan.lean index e6da1b44287b17..552e781a21a35d 100644 --- a/Mathlib/Algebra/Lie/Weights/Cartan.lean +++ b/Mathlib/Algebra/Lie/Weights/Cartan.lean @@ -290,7 +290,7 @@ lemma mem_corootSpace {x : H} : rfl simp_rw [this, corootSpace, ← LieModuleHom.map_top, ← LieSubmodule.mem_toSubmodule, LieSubmodule.toSubmodule_map, LieSubmodule.top_toSubmodule, ← TensorProduct.span_tmul_eq_top, - LinearMap.map_span, Set.image, Set.mem_setOf_eq, exists_exists_exists_and_eq] + LinearMap.map_span, Set.image, Set.mem_ofPred_eq, exists_exists_exists_and_eq] change (x : L) ∈ Submodule.span R {x | ∃ (a : rootSpace H α) (b : rootSpace H (-α)), ⁅(a : L), (b : L)⁆ = x} ↔ _ simp @@ -306,7 +306,7 @@ lemma mem_corootSpace' {x : H} : rw [← Submodule.mem_map, Submodule.coe_subtype, Submodule.map_span, mem_corootSpace, ← this] ext u simp only [Submodule.coe_subtype, mem_image, Subtype.exists, LieSubalgebra.mem_toSubmodule, - exists_and_right, exists_eq_right, mem_setOf_eq, s] + exists_and_right, exists_eq_right, mem_ofPred_eq, s] refine ⟨fun ⟨_, y, hy, z, hz, hyz⟩ ↦ ⟨y, hy, z, hz, hyz⟩, fun ⟨y, hy, z, hz, hyz⟩ ↦ ⟨?_, y, hy, z, hz, hyz⟩⟩ convert! diff --git a/Mathlib/Algebra/Lie/Weights/Killing.lean b/Mathlib/Algebra/Lie/Weights/Killing.lean index 663e391a432b2d..5913e4f432d863 100644 --- a/Mathlib/Algebra/Lie/Weights/Killing.lean +++ b/Mathlib/Algebra/Lie/Weights/Killing.lean @@ -307,7 +307,7 @@ lemma span_weight_isNonZero_eq_top : insert 0 ({α : Weight K H L | α.IsNonZero}.image (Weight.toLinear K H L)) by simpa only [Submodule.span_insert_zero] using Submodule.span_mono this rintro - ⟨α, rfl⟩ - simp only [mem_insert_iff, Weight.coe_toLinear_eq_zero_iff, mem_image, mem_setOf_eq] + simp only [mem_insert_iff, Weight.coe_toLinear_eq_zero_iff, mem_image, mem_ofPred_eq] tauto @[simp] diff --git a/Mathlib/Algebra/Module/Submodule/Invariant.lean b/Mathlib/Algebra/Module/Submodule/Invariant.lean index 620c23580f7b15..cef50d410e3f7e 100644 --- a/Mathlib/Algebra/Module/Submodule/Invariant.lean +++ b/Mathlib/Algebra/Module/Submodule/Invariant.lean @@ -38,7 +38,7 @@ def invtSubmodule : Sublattice (Submodule R M) where ⟨le_trans hp <| Submodule.comap_mono le_sup_left, le_trans hq <| Submodule.comap_mono le_sup_right⟩ infClosed' p hp q hq := by - simp only [Set.mem_setOf_eq, Submodule.comap_inf, le_inf_iff] + simp only [Set.mem_ofPred_eq, Submodule.comap_inf, le_inf_iff] exact ⟨inf_le_of_left_le hp, inf_le_of_right_le hq⟩ lemma mem_invtSubmodule {p : Submodule R M} : diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index 15fc3113bf3843..ffc98f30f3f956 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -311,7 +311,7 @@ variable [NormedAddCommGroup E] [NormedSpace ℝ E] (b : Basis ι ℝ E) theorem fundamentalDomain_subset_parallelepiped [Fintype ι] : fundamentalDomain b ⊆ parallelepiped b := by - rw [fundamentalDomain, parallelepiped_basis_eq, Set.setOf_subset_setOf] + rw [fundamentalDomain, parallelepiped_basis_eq, Set.ofPred_subset_ofPred] exact fun _ h i ↦ Set.Ico_subset_Icc_self (h i) instance [Finite ι] : DiscreteTopology (span ℤ (Set.range b)) := by @@ -342,7 +342,7 @@ theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpac · refine measurableSet_preimage (LinearMap.continuous_of_finiteDimensional _).measurable ?_ exact MeasurableSet.pi Set.countable_univ fun _ _ => measurableSet_Ico · ext - simp only [D, fundamentalDomain, Set.mem_Ico, Set.mem_setOf_eq, LinearEquiv.coe_coe, + simp only [D, fundamentalDomain, Set.mem_Ico, Set.mem_ofPred_eq, LinearEquiv.coe_coe, Set.mem_preimage, Basis.equivFun_apply, Set.mem_pi, Set.mem_univ, forall_true_left] /-- For a ℤ-lattice `Submodule.span ℤ (Set.range b)`, proves that the set defined @@ -409,7 +409,7 @@ theorem fundamentalDomain_ae_parallelepiped [Fintype ι] [MeasurableSpace E] (μ simp_rw [vsub_eq_sub, zero_sub, neg_mem_iff] exact linearIndependent_iff_notMem_span.mp b.linearIndependent i intro x hx - simp_rw [parallelepiped_basis_eq, Set.mem_Icc, Set.mem_sdiff, Set.mem_setOf_eq, + simp_rw [parallelepiped_basis_eq, Set.mem_Icc, Set.mem_sdiff, Set.mem_ofPred_eq, mem_fundamentalDomain, Set.mem_Ico, not_forall, not_and, not_lt] at hx obtain ⟨i, hi⟩ := hx.2 have : b.repr x i = 1 := le_antisymm (hx.1 i).2 (hi (hx.1 i).1) @@ -458,7 +458,7 @@ theorem ZLattice.FG [hs : IsZLattice K L] : L.FG := by refine fg_def.mpr ⟨map (span ℤ s).mkQ L, ?_, span_eq _⟩ let b := Basis.mk h_lind (by rw [← hs.span_top, ← h_span] - exact span_mono (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, subset_rfl])) + exact span_mono (by simp only [Subtype.range_coe_subtype, Set.ofPred_mem_eq, subset_rfl])) rw [show span ℤ s = span ℤ (Set.range b) by simp [b, Basis.coe_mk, Subtype.range_coe_subtype]] have : Fintype s := h_lind.setFinite.fintype refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ quotientEquiv b) ?_ @@ -476,7 +476,7 @@ theorem ZLattice.FG [hs : IsZLattice K L] : L.FG := by · rw [fract, SetLike.mem_coe, sub_eq_add_neg] refine Submodule.add_mem _ h_mem (neg_mem (Set.mem_of_subset_of_mem ?_ (Subtype.mem (floor b x)))) - rw [SetLike.coe_subset_coe, Basis.coe_mk, Subtype.range_coe_subtype, Set.setOf_mem_eq] + rw [SetLike.coe_subset_coe, Basis.coe_mk, Subtype.range_coe_subtype, Set.ofPred_mem_eq] exact span_le.mpr h_incl · -- `span ℤ s` is finitely generated because `s` is finite rw [ker_mkQ, inf_of_le_right (span_le.mpr h_incl)] @@ -557,7 +557,7 @@ theorem ZLattice.rank [hs : IsZLattice K L] : finrank ℤ L = finrank K E := by contrapose! h -- Since `finrank ℤ L > finrank K E`, there exists a vector `v ∈ b` with `v ∉ e` obtain ⟨v, hv⟩ : (Set.range b \ Set.range e).Nonempty := by - rw [Basis.coe_mk, Subtype.range_coe_subtype, Set.setOf_mem_eq, ← Set.toFinset_nonempty] + rw [Basis.coe_mk, Subtype.range_coe_subtype, Set.ofPred_mem_eq, ← Set.toFinset_nonempty] contrapose! h rw [Set.toFinset_sdiff, Finset.sdiff_eq_empty_iff_subset] at h replace h := Finset.card_le_card h diff --git a/Mathlib/Algebra/Module/ZLattice/Covolume.lean b/Mathlib/Algebra/Module/ZLattice/Covolume.lean index 1e055b28c7e9be..dcdd7b8ea7fba5 100644 --- a/Mathlib/Algebra/Module/ZLattice/Covolume.lean +++ b/Mathlib/Algebra/Module/ZLattice/Covolume.lean @@ -249,7 +249,7 @@ private theorem tendsto_card_le_div''_aux {F : E → ℝ} (hF₁ : ∀ x ⦃r : ℝ⦄, 0 ≤ r → F (r • x) = r ^ card ι * (F x)) {c : ℝ} (hc : 0 < c) : c • {x ∈ X | F x ≤ 1} = {x ∈ X | F x ≤ c ^ card ι} := by ext x - simp_rw [Set.mem_smul_set_iff_inv_smul_mem₀ hc.ne', Set.mem_setOf_eq, hF₁ _ + simp_rw [Set.mem_smul_set_iff_inv_smul_mem₀ hc.ne', Set.mem_ofPred_eq, hF₁ _ (inv_pos_of_pos hc).le, inv_pow, inv_mul_le_iff₀ (pow_pos hc _), mul_one, and_congr_left_iff] exact fun _ ↦ ⟨fun h ↦ (smul_inv_smul₀ hc.ne' x) ▸ hX h hc, fun h ↦ hX h (inv_pos_of_pos hc)⟩ diff --git a/Mathlib/Algebra/Notation/Support.lean b/Mathlib/Algebra/Notation/Support.lean index 6499333b2a6073..a1370564d45000 100644 --- a/Mathlib/Algebra/Notation/Support.lean +++ b/Mathlib/Algebra/Notation/Support.lean @@ -175,7 +175,7 @@ lemma mulSupport_comp_eq_preimage (g : κ → M) (f : ι → κ) : lemma mulSupport_prodMk (f : ι → M) (g : ι → N) : mulSupport (fun x ↦ (f x, g x)) = mulSupport f ∪ mulSupport g := Set.ext fun x ↦ by - simp only [mulSupport, not_and_or, mem_union, mem_setOf_eq, Prod.mk_eq_one, Ne] + simp only [mulSupport, not_and_or, mem_union, mem_ofPred_eq, Prod.mk_eq_one, Ne] @[to_additive support_prodMk'] lemma mulSupport_prodMk' (f : ι → M × N) : diff --git a/Mathlib/Algebra/Order/Antidiag/Nat.lean b/Mathlib/Algebra/Order/Antidiag/Nat.lean index e0079f66298e3c..b3c46e44e6de5d 100644 --- a/Mathlib/Algebra/Order/Antidiag/Nat.lean +++ b/Mathlib/Algebra/Order/Antidiag/Nat.lean @@ -192,7 +192,7 @@ private theorem primeFactorsPiBij_inj (d n : ℕ) intro ⟨p, hp, hfg⟩ use f p hp dsimp only [Nat.primeFactorsPiBij] - apply ne_of_mem_of_not_mem (s := {x | p ∣ x}) <;> simp_rw [Set.mem_setOf_eq] + apply ne_of_mem_of_not_mem (s := {x | p ∣ x}) <;> simp_rw [Set.mem_ofPred_eq] · rw [Finset.prod_filter] convert! Finset.dvd_prod_of_mem _ (mem_attach (n.primeFactors) ⟨p, hp⟩) rw [if_pos rfl] diff --git a/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean b/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean index 61be60c432d313..3f239bdb9018b0 100644 --- a/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean +++ b/Mathlib/Algebra/Order/Archimedean/IndicatorCard.lean @@ -75,7 +75,7 @@ lemma limsup_eq_tendsto_sum_indicator_atTop {α R : Type*} (fun n ↦ ∑ k ∈ Finset.range n, (s k).indicator (fun _ ↦ r) ω) atTop } := by nth_rw 1 [← Nat.cofinite_eq_atTop, cofinite.limsup_set_eq] ext ω - rw [mem_setOf_eq, mem_setOf_eq, infinite_iff_tendsto_sum_indicator_atTop h, iff_eq_eq] + rw [mem_ofPred_eq, mem_ofPred_eq, infinite_iff_tendsto_sum_indicator_atTop h, iff_eq_eq] congr end Set diff --git a/Mathlib/Algebra/Order/CompleteField.lean b/Mathlib/Algebra/Order/CompleteField.lean index f576610e5cf93b..6c42efec385428 100644 --- a/Mathlib/Algebra/Order/CompleteField.lean +++ b/Mathlib/Algebra/Order/CompleteField.lean @@ -126,7 +126,7 @@ theorem cutMap_bddAbove (a : α) : BddAbove (cutMap β a) := by theorem cutMap_add (a b : α) : cutMap β (a + b) = cutMap β a + cutMap β b := by refine (image_subset_iff.2 fun q hq => ?_).antisymm ?_ - · rw [mem_setOf_eq, ← sub_lt_iff_lt_add] at hq + · rw [mem_ofPred_eq, ← sub_lt_iff_lt_add] at hq obtain ⟨q₁, hq₁q, hq₁ab⟩ := exists_rat_btwn hq refine ⟨q₁, by rwa [coe_mem_cutMap_iff], q - q₁, ?_, add_sub_cancel _ _⟩ norm_cast @@ -135,7 +135,7 @@ theorem cutMap_add (a b : α) : cutMap β (a + b) = cutMap β a + cutMap β b := · rintro _ ⟨_, ⟨qa, ha, rfl⟩, _, ⟨qb, hb, rfl⟩, rfl⟩ -- After https://github.com/leanprover/lean4/pull/2734, `norm_cast` needs help with beta reduction. refine ⟨qa + qb, ?_, by beta_reduce; norm_cast⟩ - rw [mem_setOf_eq, cast_add] + rw [mem_ofPred_eq, cast_add] exact add_lt_add ha hb end CutMap diff --git a/Mathlib/Algebra/Order/Group/Ideal.lean b/Mathlib/Algebra/Order/Group/Ideal.lean index f0ba65f529b2e3..6d55201f87a3d0 100644 --- a/Mathlib/Algebra/Order/Group/Ideal.lean +++ b/Mathlib/Algebra/Order/Group/Ideal.lean @@ -33,10 +33,10 @@ generated. -/ ideal is finitely generated. -/] theorem fg_of_wellQuasiOrderedLE (I : SemigroupIdeal M) : I.FG := by have hpwo := Set.isPWO_of_wellQuasiOrderedLE { x | x ∈ I } - refine ⟨_, (setOf_minimal_antichain _).finite_of_partiallyWellOrderedOn - (hpwo.mono (setOf_minimal_subset _)), ?_⟩ + refine ⟨_, (setOfPred_minimal_antichain _).finite_of_partiallyWellOrderedOn + (hpwo.mono (setOfPred_minimal_subset _)), ?_⟩ ext x - simp only [mem_closure'', SetLike.setOf_mem_eq, SetLike.mem_coe, Set.mem_setOf_eq] + simp only [mem_closure'', SetLike.setOfPred_mem_eq, SetLike.mem_coe, Set.mem_ofPred_eq] constructor · intro hx rcases hpwo.exists_le_minimal hx with ⟨z, hz, hz'⟩ diff --git a/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean b/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean index 1101a11f3267ee..f90a9b4e3c43b8 100644 --- a/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean +++ b/Mathlib/Algebra/Order/Group/Pointwise/Interval.lean @@ -842,7 +842,7 @@ lemma preimage_const_mul_Ioi_or_Iio (hb : a ≠ 0) {U V : Set α} (hU : U ∈ {s | ∃ a, s = Ioi a ∨ s = Iio a}) (hV : V = (a * ·) ⁻¹' U) : V ∈ {s | ∃ a, s = Ioi a ∨ s = Iio a} := by obtain ⟨aU, (haU | haU)⟩ := hU <;> - simp only [hV, haU, mem_setOf_eq] <;> + simp only [hV, haU, mem_ofPred_eq] <;> use a⁻¹ * aU <;> rcases lt_or_gt_of_ne hb with (hb | hb) · right; rw [Set.preimage_const_mul_Ioi_of_neg _ hb, div_eq_inv_mul] diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index 9810e9a39dfd9d..1003ca665170b5 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -1230,7 +1230,7 @@ lemma inv_strictAnti₀ (hb : 0 < b) (hba : b < a) : a⁻¹ < b⁻¹ := (inv_lt_inv₀ (hb.trans hba) hb).2 hba lemma strictAntiOn_inv_pos : StrictAntiOn (fun x : G₀ ↦ x⁻¹) {r | 0 < r} := - fun ⦃_⦄ ha ⦃_⦄ _ h ↦ inv_strictAnti₀ (Set.mem_setOf.mp ha) h + fun ⦃_⦄ ha ⦃_⦄ _ h ↦ inv_strictAnti₀ (Set.mem_ofPred.mp ha) h lemma antitoneOn_inv_pos : AntitoneOn (fun x : G₀ ↦ x⁻¹) {r | 0 < r} := strictAntiOn_inv_pos.antitoneOn diff --git a/Mathlib/Algebra/Order/Quantale.lean b/Mathlib/Algebra/Order/Quantale.lean index 71cb4d071d7404..478c0e3af442eb 100644 --- a/Mathlib/Algebra/Order/Quantale.lean +++ b/Mathlib/Algebra/Order/Quantale.lean @@ -180,7 +180,7 @@ instance : MulRightMono α where theorem leftMulResiduation_le_iff_mul_le : x ≤ y ⇨ₗ z ↔ x * y ≤ z where mp h1 := by grw [h1] - simp_all only [leftMulResiduation, sSup_mul_distrib, Set.mem_setOf_eq, + simp_all only [leftMulResiduation, sSup_mul_distrib, Set.mem_ofPred_eq, iSup_le_iff, implies_true] mpr h1 := le_sSup h1 @@ -188,7 +188,7 @@ theorem leftMulResiduation_le_iff_mul_le : x ≤ y ⇨ₗ z ↔ x * y ≤ z wher theorem rightMulResiduation_le_iff_mul_le : x ≤ y ⇨ᵣ z ↔ y * x ≤ z where mp h1 := by grw [h1] - simp_all only [rightMulResiduation, mul_sSup_distrib, Set.mem_setOf_eq, + simp_all only [rightMulResiduation, mul_sSup_distrib, Set.mem_ofPred_eq, iSup_le_iff, implies_true] mpr h1 := le_sSup h1 diff --git a/Mathlib/Algebra/Order/Rearrangement.lean b/Mathlib/Algebra/Order/Rearrangement.lean index 44b20c6d3cf59b..bde64c8837496f 100644 --- a/Mathlib/Algebra/Order/Rearrangement.lean +++ b/Mathlib/Algebra/Order/Rearrangement.lean @@ -76,7 +76,7 @@ theorem MonovaryOn.sum_smul_comp_perm_le_sum_smul (hfg : MonovaryOn f g s) set τ : Perm ι := σ.trans (swap a (σ a)) with hτ have hτs : {x | τ x ≠ x} ⊆ s := by intro x hx - simp only [τ, Ne, Set.mem_setOf_eq, Equiv.swap_comp_apply] at hx + simp only [τ, Ne, Set.mem_ofPred_eq, Equiv.swap_comp_apply] at hx split_ifs at hx with h₁ h₂ · obtain rfl | hax := eq_or_ne x a · contradiction diff --git a/Mathlib/Algebra/Order/Ring/Int.lean b/Mathlib/Algebra/Order/Ring/Int.lean index ea4d7a1e64af8e..35c299226e0731 100644 --- a/Mathlib/Algebra/Order/Ring/Int.lean +++ b/Mathlib/Algebra/Order/Ring/Int.lean @@ -44,7 +44,7 @@ instance instIsStrictOrderedRing : IsStrictOrderedRing ℤ := .of_mul_pos @Int.m /-! ### Miscellaneous lemmas -/ lemma isCompl_even_odd : IsCompl { n : ℤ | Even n } { n | Odd n } := by - simp [← not_even_iff_odd, ← Set.compl_setOf, isCompl_compl] + simp [← not_even_iff_odd, ← Set.compl_ofPred, isCompl_compl] @[simp] lemma _root_.Nat.cast_natAbs {α : Type*} [AddGroupWithOne α] (n : ℤ) : (n.natAbs : α) = |n| := by diff --git a/Mathlib/Algebra/Order/Ring/Nat.lean b/Mathlib/Algebra/Order/Ring/Nat.lean index 351db6239412cb..44b8d540a8b9fb 100644 --- a/Mathlib/Algebra/Order/Ring/Nat.lean +++ b/Mathlib/Algebra/Order/Ring/Nat.lean @@ -37,6 +37,6 @@ instance instLinearOrderedCommMonoidWithZero : LinearOrderedCommMonoidWithZero /-! ### Miscellaneous lemmas -/ lemma isCompl_even_odd : IsCompl { n : ℕ | Even n } { n | Odd n } := by - simp only [← Set.compl_setOf, isCompl_compl, ← not_even_iff_odd] + simp only [← Set.compl_ofPred, isCompl_compl, ← not_even_iff_odd] end Nat diff --git a/Mathlib/Algebra/Order/ToIntervalMod.lean b/Mathlib/Algebra/Order/ToIntervalMod.lean index 637edc191bba29..65ee2f49148f4f 100644 --- a/Mathlib/Algebra/Order/ToIntervalMod.lean +++ b/Mathlib/Algebra/Order/ToIntervalMod.lean @@ -678,7 +678,7 @@ alias ⟨_, AddCommGroup.ModEq.toIcoMod_eq_toIcoMod⟩ := toIcoMod_inj theorem Ico_eq_locus_Ioc_eq_iUnion_Ioo : { b | toIcoMod hp a b = toIocMod hp a b } = ⋃ z : ℤ, Set.Ioo (a + z • p) (a + p + z • p) := by ext1 - simp_rw [Set.mem_setOf, Set.mem_iUnion, ← Set.sub_mem_Ioo_iff_left, ← + simp_rw [Set.mem_ofPred, Set.mem_iUnion, ← Set.sub_mem_Ioo_iff_left, ← not_modEq_iff_toIcoMod_eq_toIocMod, modEq_iff_forall_notMem_Ioo_mod hp, not_forall, Classical.not_not] diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index 115ba3c369fd51..60c0b97c08c1ba 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -711,7 +711,7 @@ theorem ext {p q : R[X]} : (∀ n, coeff p n = coeff q n) → p = q := set_option backward.isDefEq.respectTransparency false in /-- Monomials generate the additive monoid of polynomials. -/ -theorem addSubmonoid_closure_setOf_eq_monomial : +theorem addSubmonoid_closure_setOfPred_eq_monomial : AddSubmonoid.closure { p : R[X] | ∃ n a, p = monomial n a } = ⊤ := by apply top_unique rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ← addSubmonoidClosure_single, @@ -720,10 +720,13 @@ theorem addSubmonoid_closure_setOf_eq_monomial : rintro _ ⟨n, a, rfl⟩ exact ⟨n, a, Polynomial.ofFinsupp_single _ _⟩ +@[deprecated (since := "2026-07-09")] +alias addSubmonoid_closure_setOf_eq_monomial := addSubmonoid_closure_setOfPred_eq_monomial + @[ext high] theorem addHom_ext {M : Type*} [AddZeroClass M] {f g : R[X] →+ M} (h : ∀ n a, f (monomial n a) = g (monomial n a)) : f = g := - AddMonoidHom.eq_of_eqOn_denseM addSubmonoid_closure_setOf_eq_monomial <| by + AddMonoidHom.eq_of_eqOn_denseM addSubmonoid_closure_setOfPred_eq_monomial <| by rintro p ⟨n, a, rfl⟩ exact h n a diff --git a/Mathlib/Algebra/Polynomial/EraseLead.lean b/Mathlib/Algebra/Polynomial/EraseLead.lean index 54af338b94faea..df0bffaaa19fec 100644 --- a/Mathlib/Algebra/Polynomial/EraseLead.lean +++ b/Mathlib/Algebra/Polynomial/EraseLead.lean @@ -418,7 +418,7 @@ theorem card_support_eq {n : ℕ} : Function.extend Fin.castSucc x fun _ => f.leadingCoeff, ?_, ?_, ?_⟩ · intro i j hij have hi : i ∈ Set.range (Fin.castSucc : Fin n → Fin (n + 1)) := by - simp only [Fin.range_castSucc, Nat.succ_eq_add_one, Set.mem_setOf_eq] + simp only [Fin.range_castSucc, Nat.succ_eq_add_one, Set.mem_ofPred_eq] exact lt_of_lt_of_le hij (Nat.lt_succ_iff.mp j.2) obtain ⟨i, rfl⟩ := hi rw [Fin.strictMono_castSucc.injective.extend_apply] diff --git a/Mathlib/Algebra/Polynomial/Roots.lean b/Mathlib/Algebra/Polynomial/Roots.lean index 26fb00fb88acf6..d1eebd0d5f4074 100644 --- a/Mathlib/Algebra/Polynomial/Roots.lean +++ b/Mathlib/Algebra/Polynomial/Roots.lean @@ -137,19 +137,21 @@ theorem card_le_degree_of_subset_roots {p : R[X]} {Z : Finset R} (h : Z.val ⊆ #Z ≤ p.natDegree := (Multiset.card_le_card (Finset.val_le_iff_val_subset.2 h)).trans (Polynomial.card_roots' p) -theorem finite_setOf_isRoot {p : R[X]} (hp : p ≠ 0) : Set.Finite { x | IsRoot p x } := by +theorem finite_setOfPred_isRoot {p : R[X]} (hp : p ≠ 0) : Set.Finite { x | IsRoot p x } := by classical - simpa only [← Finset.setOf_mem, Multiset.mem_toFinset, mem_roots hp] + simpa only [← Finset.setOfPred_mem, Multiset.mem_toFinset, mem_roots hp] using p.roots.toFinset.finite_toSet +@[deprecated (since := "2026-07-09")] alias finite_setOf_isRoot := finite_setOfPred_isRoot + theorem eq_zero_of_infinite_isRoot (p : R[X]) (h : Set.Infinite { x | IsRoot p x }) : p = 0 := - not_imp_comm.mp finite_setOf_isRoot h + not_imp_comm.mp finite_setOfPred_isRoot h theorem exists_max_root [LinearOrder R] (p : R[X]) (hp : p ≠ 0) : ∃ x₀, ∀ x, p.IsRoot x → x ≤ x₀ := - Set.exists_upper_bound_image _ _ <| finite_setOf_isRoot hp + Set.exists_upper_bound_image _ _ <| finite_setOfPred_isRoot hp theorem exists_min_root [LinearOrder R] (p : R[X]) (hp : p ≠ 0) : ∃ x₀, ∀ x, p.IsRoot x → x₀ ≤ x := - Set.exists_lower_bound_image _ _ <| finite_setOf_isRoot hp + Set.exists_lower_bound_image _ _ <| finite_setOfPred_isRoot hp theorem eq_of_infinite_eval_eq (p q : R[X]) (h : Set.Infinite { x | eval x p = eval x q }) : p = q := by diff --git a/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean b/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean index b40650b7b053b3..07f5550da9f7d0 100644 --- a/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean +++ b/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean @@ -91,7 +91,7 @@ lemma smul_le : M • N ≤ P ↔ ∀ m ∈ M, ∀ n ∈ N, m • n ∈ P := @[elab_as_elim] protected lemma smul_induction_on {C : A → Prop} {a : A} (ha : a ∈ M • N) (hm : ∀ m ∈ M, ∀ n ∈ N, C (m • n)) (hadd : ∀ x y, C x → C y → C (x + y)) : C a := - (@smul_le _ _ _ _ _ _ _ ⟨⟨setOf C, hadd _ _⟩, by + (@smul_le _ _ _ _ _ _ _ ⟨⟨Set.ofPred C, hadd _ _⟩, by simpa only [smul_zero] using! hm _ (zero_mem _) _ (zero_mem _)⟩).2 hm ha @[simp] diff --git a/Mathlib/Algebra/Ring/Subring/MulOpposite.lean b/Mathlib/Algebra/Ring/Subring/MulOpposite.lean index f92b3d0ab594db..ba378fd1401beb 100644 --- a/Mathlib/Algebra/Ring/Subring/MulOpposite.lean +++ b/Mathlib/Algebra/Ring/Subring/MulOpposite.lean @@ -137,7 +137,7 @@ theorem unop_iInf (S : ι → Subring Rᵐᵒᵖ) : (iInf S).unop = ⨅ i, (S i) opEquiv.symm.map_iInf _ theorem op_closure (s : Set R) : (closure s).op = closure (MulOpposite.unop ⁻¹' s) := by - simp_rw [closure, op_sInf, Set.preimage_setOf_eq, coe_unop] + simp_rw [closure, op_sInf, Set.preimage_ofPred_eq, coe_unop] congr with a exact MulOpposite.unop_surjective.forall diff --git a/Mathlib/Algebra/Ring/Subsemiring/MulOpposite.lean b/Mathlib/Algebra/Ring/Subsemiring/MulOpposite.lean index a2e677732e4c03..f1e8c0369d03d9 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/MulOpposite.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/MulOpposite.lean @@ -143,7 +143,7 @@ theorem unop_iInf (S : ι → Subsemiring Rᵐᵒᵖ) : (iInf S).unop = ⨅ i, ( opEquiv.symm.map_iInf _ theorem op_closure (s : Set R) : (closure s).op = closure (MulOpposite.unop ⁻¹' s) := by - simp_rw [closure, op_sInf, Set.preimage_setOf_eq, coe_unop] + simp_rw [closure, op_sInf, Set.preimage_ofPred_eq, coe_unop] congr with a exact MulOpposite.unop_surjective.forall diff --git a/Mathlib/Algebra/Star/Center.lean b/Mathlib/Algebra/Star/Center.lean index 4b2778c9f4225a..491b0276652147 100644 --- a/Mathlib/Algebra/Star/Center.lean +++ b/Mathlib/Algebra/Star/Center.lean @@ -25,7 +25,7 @@ theorem Set.star_mem_center (ha : a ∈ Set.center R) : star a ∈ Set.center R theorem Set.star_centralizer : star s.centralizer = (star s).centralizer := by simp_rw [centralizer, ← commute_iff_eq] - conv_lhs => simp only [← star_preimage, preimage_setOf_eq, ← commute_star_comm] + conv_lhs => simp only [← star_preimage, preimage_ofPred_eq, ← commute_star_comm] conv_rhs => simp only [← image_star, forall_mem_image] theorem Set.union_star_self_comm (hcomm : ∀ x ∈ s, ∀ y ∈ s, y * x = x * y) diff --git a/Mathlib/Algebra/Star/Unitary.lean b/Mathlib/Algebra/Star/Unitary.lean index 3cf41580a98415..3e33ae62c51776 100644 --- a/Mathlib/Algebra/Star/Unitary.lean +++ b/Mathlib/Algebra/Star/Unitary.lean @@ -34,7 +34,7 @@ unitary -/ def unitary (R : Type*) [Monoid R] [StarMul R] : Submonoid R where carrier := { U | star U * U = 1 ∧ U * star U = 1 } - one_mem' := by simp only [mul_one, and_self_iff, Set.mem_setOf_eq, star_one] + one_mem' := by simp only [mul_one, and_self_iff, Set.mem_ofPred_eq, star_one] mul_mem' := @fun U B ⟨hA₁, hA₂⟩ ⟨hB₁, hB₂⟩ => by refine ⟨?_, ?_⟩ · calc diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 8c4c6eb0e317a8..1204020a0c42ac 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -328,7 +328,7 @@ theorem isBasis_basicOpen (X : Scheme) [IsAffine X] : PrimeSpectrum.isBasis_basic_opens.of_isInducing (TopCat.homeoOfIso (Scheme.forgetToTop.mapIso X.isoSpec)).isInducing using 1 ext V - simp only [Set.mem_range, exists_exists_eq_and, Set.mem_setOf, + simp only [Set.mem_range, exists_exists_eq_and, Set.mem_ofPred, ← Opens.coe_inj (V := V), ← Scheme.toSpecΓ_preimage_basicOpen] rfl @@ -950,7 +950,7 @@ theorem iSup_basicOpen_eq_self_iff {s : Set Γ(X, U)} : · simp only [Opens.carrier_eq_coe, PrimeSpectrum.basicOpen_eq_zeroLocus_compl] rw [← Set.compl_iInter, Set.compl_univ_iff, ← PrimeSpectrum.zeroLocus_iUnion, ← PrimeSpectrum.zeroLocus_empty_iff_eq_top, PrimeSpectrum.zeroLocus_span] - simp only [Set.iUnion_singleton_eq_range, Subtype.range_val_subtype, Set.setOf_mem_eq] + simp only [Set.iUnion_singleton_eq_range, Subtype.range_val_subtype, Set.ofPred_mem_eq] include hU in theorem self_le_iSup_basicOpen_iff {s : Set Γ(X, U)} : diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean index dc5989e94cd4b3..0224602600e0c3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean @@ -121,7 +121,7 @@ lemma isAffine_of_isAffineOpen_basicOpen (s : Set Γ(X, ⊤)) · change IsAffineOpen _ simp only [← basicOpen_eq_of_affine] exact (isAffineOpen_top (Scheme.Spec.obj (op _))).basicOpen _ - · rw [PrimeSpectrum.iSup_basicOpen_eq_top_iff, Subtype.range_coe_subtype, Set.setOf_mem_eq, hs] + · rw [PrimeSpectrum.iSup_basicOpen_eq_top_iff, Subtype.range_coe_subtype, Set.ofPred_mem_eq, hs] · rw [Scheme.toSpecΓ_preimage_basicOpen] exact hs₂ _ i.2 · simp only [Opens.map_top, morphismRestrict_app] @@ -164,7 +164,7 @@ instance : HasAffineProperty @IsAffineHom fun X _ _ _ ↦ IsAffine X where simpa [Scheme.preimage_basicOpen] using! this eq_targetAffineLocally' := by ext X Y f - simp only [targetAffineLocally, Scheme.affineOpens, Set.coe_setOf, Set.mem_setOf_eq, + simp only [targetAffineLocally, Scheme.affineOpens, Set.coe_ofPred, Set.mem_ofPred_eq, Subtype.forall, isAffineHom_iff] rfl @@ -324,7 +324,7 @@ theorem isAffineHom_diagonal_iff {f : X ⟶ Y} : (.diagonal @IsAffineHom)) f).to_iff.trans ?_ simp only [targetAffineLocally, diagonal_isAffine_iff_forall_isAffineOpen_inf, (IsOpenImmersion.opensEquiv (f ⁻¹ᵁ _).ι).forall_congr_left, Scheme.affineOpens, - Subtype.forall, Set.mem_setOf_eq, Scheme.Opens.opensRange_ι, ← Scheme.Hom.preimage_inf, + Subtype.forall, Set.mem_ofPred_eq, Scheme.Opens.opensRange_ι, ← Scheme.Hom.preimage_inf, IsOpenImmersion.opensEquiv_symm_apply, Scheme.Hom.image_preimage_eq_opensRange_inf, ← Scheme.Hom.isAffineOpen_iff_of_isOpenImmersion (Scheme.Opens.ι _)] congr! with U hU V₁ hV₁ V₂ hV₂ @@ -339,11 +339,11 @@ lemma IsAffineOpen.inf [IsAffineHom (pullback.diagonal (terminal.from X))] lemma IsAffineOpen.iInf [IsAffineHom (pullback.diagonal (terminal.from X))] {ι : Sort*} [Finite ι] [Nonempty ι] {U : ι → X.Opens} (hU : ∀ i, IsAffineOpen (U i)) : IsAffineOpen (⨅ i, U i) := - InfClosed.iInf_mem_of_nonempty (s := setOf IsAffineOpen) (fun _ h _ h' ↦ h.inf h') hU + InfClosed.iInf_mem_of_nonempty (s := Set.ofPred IsAffineOpen) (fun _ h _ h' ↦ h.inf h') hU lemma IsAffineOpen.biInf [IsAffineHom (pullback.diagonal (terminal.from X))] {ι : Type*} (s : Set ι) (hs : s.Finite) (hs' : s.Nonempty) {U : ι → X.Opens} (hU : ∀ i ∈ s, IsAffineOpen (U i)) : IsAffineOpen (⨅ i ∈ s, U i) := - InfClosed.biInf_mem_of_nonempty (s := setOf IsAffineOpen) (fun _ h _ h' ↦ h.inf h') hs hs' hU + InfClosed.biInf_mem_of_nonempty (s := Set.ofPred IsAffineOpen) (fun _ h _ h' ↦ h.inf h') hs hs' hU end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean b/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean index 253bbf756c95b1..83a7b57ef31c8a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean @@ -137,7 +137,7 @@ nonrec lemma Scheme.Hom.isLocallyConstructible_image (f : X ⟶ Y) ((Scheme.homeoOfIso (Y.affineCover.f i).isoOpensRange).image_eq_preimage_symm _) apply Set.image_injective.mpr Subtype.val_injective rw [Set.image_preimage_eq_inter_range, ← Set.image_comp, ← Set.image_comp, - Subtype.range_coe_subtype, Set.setOf_mem_eq] + Subtype.range_coe_subtype, Set.ofPred_mem_eq] change _ = (Y.affineCover.pullbackHom f i ≫ (Y.affineCover.f i).isoOpensRange.hom ≫ Opens.ι _).base.hom '' _ rw [Scheme.Hom.isoOpensRange_hom_ι, Cover.pullbackHom_map, Scheme.Hom.comp_base, diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean index 074c35b69a40ba..cbc9212a4c7b9b 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean @@ -105,7 +105,7 @@ instance : IsStableUnderBaseChange @IsPreimmersion := by constructor let L (x : (pullback f g :)) : { x : X × Y | f x.1 = g x.2 } := ⟨⟨pullback.fst f g x, pullback.snd f g x⟩, - by simp only [Set.mem_setOf, ← Scheme.Hom.comp_apply, pullback.condition]⟩ + by simp only [Set.mem_ofPred, ← Scheme.Hom.comp_apply, pullback.condition]⟩ have : IsEmbedding L := IsEmbedding.of_comp (by fun_prop) continuous_subtype_val (SurjectiveOnStalks.isEmbedding_pullback f g) exact IsEmbedding.subtypeVal.comp ((TopCat.pullbackHomeoPreimage _ f.continuous _ diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean index 911ffad935d36b..079d8d5597d8cb 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean @@ -105,7 +105,7 @@ theorem coe_vanishingIdeal (t : Set (ProjectiveSpectrum 𝒜)) : theorem mem_vanishingIdeal (t : Set (ProjectiveSpectrum 𝒜)) (f : A) : f ∈ vanishingIdeal t ↔ ∀ x : ProjectiveSpectrum 𝒜, x ∈ t → f ∈ x.asHomogeneousIdeal := by - rw [← SetLike.mem_coe, coe_vanishingIdeal, Set.mem_setOf_eq] + rw [← SetLike.mem_coe, coe_vanishingIdeal, Set.mem_ofPred_eq] @[simp] theorem vanishingIdeal_singleton (x : ProjectiveSpectrum 𝒜) : diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean index 9f02d77707a461..d990c314ad8f36 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean @@ -35,7 +35,7 @@ namespace SSet all `m`-simplices of `stdSimplex n` that are not surjective (when viewed as monotone function `m → n`). -/ def boundary (n : ℕ) : (Δ[n] : SSet.{u}).Subcomplex where - obj _ := setOf (fun s ↦ ¬Function.Surjective (stdSimplex.asOrderHom s)) + obj _ := Set.ofPred (fun s ↦ ¬Function.Surjective (stdSimplex.asOrderHom s)) map _ _ hs h := hs (Function.Surjective.of_comp h) /-- The boundary `∂Δ[n]` of the `n`-th standard simplex -/ @@ -91,7 +91,7 @@ lemma boundary_obj_eq_univ (m n : ℕ) (h : m < n := by lia) : @[simp] lemma boundary_zero : boundary.{u} 0 = ⊥ := by ext m x - simp only [boundary, Nat.reduceAdd, Set.mem_setOf_eq, Subfunctor.bot_obj, Set.bot_eq_empty, + simp only [boundary, Nat.reduceAdd, Set.mem_ofPred_eq, Subfunctor.bot_obj, Set.bot_eq_empty, Set.mem_empty_iff_false, iff_false, Decidable.not_not] intro x exact ⟨0, by subsingleton⟩ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index 0ee1d0267cef92..e87c929548f6a9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -34,7 +34,7 @@ variable (X : SSet.{u}) /-- An `n`-simplex of a simplicial set `X` is degenerate if it is in the range of `X.map f.op` for some morphism `f : [n] ⟶ [m]` with `m < n`. -/ def degenerate (n : ℕ) : Set (X _⦋n⦌) := - setOf (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ⦋n⦌ ⟶ ⦋m⦌), + Set.ofPred (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ⦋n⦌ ⟶ ⦋m⦌), x ∈ Set.range (X.map f.op)) /-- The set of `n`-dimensional non-degenerate simplices in a simplicial diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index a828db88171e27..b12ece54feb0fa 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -30,7 +30,7 @@ for which the union of `{i}` and the range of `α` is not all of `n` (when viewing `α` as monotone function `m → n`). -/ @[simps -isSimp obj] def horn (n : ℕ) (i : Fin (n + 1)) : (Δ[n] : SSet.{u}).Subcomplex where - obj _ := setOf (fun s ↦ Set.range (stdSimplex.asOrderHom s) ∪ {i} ≠ Set.univ) + obj _ := Set.ofPred (fun s ↦ Set.range (stdSimplex.asOrderHom s) ∪ {i} ≠ Set.univ) map φ s hs h := hs (by rw [Set.eq_univ_iff_forall] at h ⊢; intro j apply Or.imp _ id (h j) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean index 6941c3e697d3a6..42a4cca0d7af1d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean @@ -293,7 +293,7 @@ lemma bicartSq : BicartSq (S.prod T) ((⊤ : X.Subcomplex).prod T) (S.prod ⊤) inf_eq := by ext n ⟨x, y⟩ change _ ∧ _ ↔ _ - simp [prod, Set.prod, Membership.mem, Set.Mem, setOf] + simp [prod, Set.prod, Membership.mem, Set.Mem, Set.ofPred] tauto lemma isPushout : IsPushout (S.ι ▷ (T : SSet)) ((S : SSet) ◁ T.ι) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index 954be17519ec39..71a715edcbf836 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -124,7 +124,7 @@ lemma le_def {s t : X.S} : s ≤ t ↔ s.subcomplex ≤ t.subcomplex := lemma le_iff {s t : X.S} : s ≤ t ↔ ∃ (f : ⦋s.dim⦌ ⟶ ⦋t.dim⦌), X.map f.op t.simplex = s.simplex := by - rw [le_def, Subcomplex.ofSimplex_le_iff, Subfunctor.ofSection_obj, Set.mem_setOf_eq] + rw [le_def, Subcomplex.ofSimplex_le_iff, Subfunctor.ofSection_obj, Set.mem_ofPred_eq] tauto lemma mk_map_le {n m : ℕ} (x : X _⦋n⦌) (f : ⦋m⦌ ⟶ ⦋n⦌) : diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index d6a94c66f7f9c4..2514bf6a3500b3 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -272,7 +272,7 @@ attribute [local simp] image_subset_iff as a subcomplex. -/ @[simps -isSimp obj] def face {n : ℕ} (S : Finset (Fin (n + 1))) : (Δ[n] : SSet.{u}).Subcomplex where - obj U := setOf (fun f ↦ Finset.image (objEquiv f).toOrderHom ⊤ ≤ S) + obj U := Set.ofPred (fun f ↦ Finset.image (objEquiv f).toOrderHom ⊤ ≤ S) map {U V} i := by aesop attribute [local simp] face_obj @@ -605,7 +605,7 @@ private lemma bijective_image_objEquiv_toOrderHom_univ (m : ℕ) : obtain ⟨f₂, rfl⟩ := objEquiv.symm.surjective x₂ simp only [mem_nonDegenerate_iff_mono, Equiv.apply_symm_apply, SimplexCategory.mono_iff_injective, SimplexCategory.len_mk] at h₁ h₂ - simp only [Set.mem_setOf_eq, SimplexCategory.len_mk, Equiv.apply_symm_apply, + simp only [Set.mem_ofPred_eq, SimplexCategory.len_mk, Equiv.apply_symm_apply, Subtype.mk.injEq, EmbeddingLike.apply_eq_iff_eq] at h₃ ⊢ apply SimplexCategory.Hom.ext rw [← OrderHom.range_eq_iff h₁ h₂] diff --git a/Mathlib/Analysis/Analytic/CPolynomialDef.lean b/Mathlib/Analysis/Analytic/CPolynomialDef.lean index 080fd7c388245b..979ee9a81876f0 100644 --- a/Mathlib/Analysis/Analytic/CPolynomialDef.lean +++ b/Mathlib/Analysis/Analytic/CPolynomialDef.lean @@ -392,7 +392,7 @@ theorem changeOrigin_eval_of_finite (p : FormalMultilinearSeries 𝕜 E F) {n : simp_rw [← {m | m < n}.iUnion_of_singleton_coe, preimage_iUnion, ← range_sigmaMk] exact finite_iUnion fun _ ↦ finite_range _ · refine fun s ↦ Not.imp_symm fun hs ↦ ?_ - simp only [preimage_setOf_eq, changeOriginIndexEquiv_apply_fst, mem_setOf, not_lt] at hs + simp only [preimage_ofPred_eq, changeOriginIndexEquiv_apply_fst, mem_ofPred, not_lt] at hs dsimp only [f] rw [changeOriginSeriesTerm_bound p hn _ _ _ hs, _root_.zero_apply, _root_.zero_apply] have hfkl k l : HasSum (f ⟨k, l, ·⟩) (changeOriginSeries p k l (fun _ ↦ x) fun _ ↦ y) := by diff --git a/Mathlib/Analysis/Analytic/Composition.lean b/Mathlib/Analysis/Analytic/Composition.lean index b775c5c5de2c22..d4c0139b0ff4c1 100644 --- a/Mathlib/Analysis/Analytic/Composition.lean +++ b/Mathlib/Analysis/Analytic/Composition.lean @@ -583,7 +583,7 @@ theorem compPartialSumTargetSet_image_compPartialSumSource (m M N : ℕ) ∃ (j : _) (hj : j ∈ compPartialSumSource m M N), compChangeOfVariables m M N j hj = i := by rcases i with ⟨n, c⟩ refine ⟨⟨c.length, c.blocksFun⟩, ?_, ?_⟩ - · simp only [compPartialSumTargetSet, Set.mem_setOf_eq] at hi + · simp only [compPartialSumTargetSet, Set.mem_ofPred_eq] at hi simp only [mem_compPartialSumSource_iff, hi.left, hi.right, true_and, and_true] exact fun a => c.one_le_blocks' _ · dsimp [compChangeOfVariables] diff --git a/Mathlib/Analysis/Analytic/Constructions.lean b/Mathlib/Analysis/Analytic/Constructions.lean index 44c8d8cc59f201..a4823d7cdda8e3 100644 --- a/Mathlib/Analysis/Analytic/Constructions.lean +++ b/Mathlib/Analysis/Analytic/Constructions.lean @@ -742,7 +742,7 @@ theorem HasFPowerSeriesWithinOnBall.compContinuousLinearMap · simp · simp only [Set.mem_insert_iff, add_eq_left, Set.mem_preimage, map_add] at hy1 ⊢ rcases hy1 with (hy1 | hy1) <;> simp [hy1] - · simp only [Metric.eball, edist_zero_right, Set.mem_setOf_eq] at hy2 ⊢ + · simp only [Metric.eball, edist_zero_right, Set.mem_ofPred_eq] at hy2 ⊢ exact lt_of_le_of_lt (ContinuousLinearMap.le_opENorm _ _) (mul_lt_of_lt_div' hy2) theorem HasFPowerSeriesOnBall.compContinuousLinearMap (hf : HasFPowerSeriesOnBall f pf (u x) r) : diff --git a/Mathlib/Analysis/Analytic/Inverse.lean b/Mathlib/Analysis/Analytic/Inverse.lean index dc7900b521cfec..26df5e360d7ad4 100644 --- a/Mathlib/Analysis/Analytic/Inverse.lean +++ b/Mathlib/Analysis/Analytic/Inverse.lean @@ -148,7 +148,7 @@ theorem leftInv_comp (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) ext k simp [h] simp [FormalMultilinearSeries.comp, A, Finset.sum_union B, - applyComposition_ones, C, D, -Set.toFinset_setOf, -Finset.union_singleton] + applyComposition_ones, C, D, -Set.toFinset_ofPred, -Finset.union_singleton] /-! ### The right inverse of a formal multilinear series -/ @@ -222,7 +222,7 @@ theorem comp_rightInv_aux1 {n : ℕ} (hn : 0 < n) (p : FormalMultilinearSeries p 1 fun _ : Fin 1 => q n v := by apply p.congr (Composition.single_length hn) fun j hj1 _ => ?_ simp [applyComposition_single] - simp [FormalMultilinearSeries.comp, A, Finset.sum_union B, C, -Set.toFinset_setOf, + simp [FormalMultilinearSeries.comp, A, Finset.sum_union B, C, -Set.toFinset_ofPred, -add_right_inj, -Composition.single_length, -Finset.union_singleton] theorem comp_rightInv_aux2 (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (x : E) (n : ℕ) @@ -235,7 +235,7 @@ theorem comp_rightInv_aux2 (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[ refine sum_congr rfl fun c hc => p.congr rfl fun j hj1 hj2 => ?_ have : ∀ k, c.blocksFun k < n + 2 := by simp only [Set.mem_toFinset (s := {c : Composition (n + 2) | 1 < c.length}), - Set.mem_setOf_eq] at hc + Set.mem_ofPred_eq] at hc simp [← Composition.ne_single_iff N, Composition.eq_single_iff_length, ne_of_gt hc] simp [applyComposition, this] @@ -257,7 +257,7 @@ theorem comp_rightInv (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F id_apply_one, ContinuousLinearEquiv.coe_apply, continuousMultilinearCurryFin1_symm_apply] | n + 2 => have N : 0 < n + 2 := by simp - simp [comp_rightInv_aux1 N, h, rightInv, comp_rightInv_aux2, -Set.toFinset_setOf] + simp [comp_rightInv_aux1 N, h, rightInv, comp_rightInv_aux2, -Set.toFinset_ofPred] set_option backward.isDefEq.respectTransparency false in theorem rightInv_coeff (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] F) (x : E) @@ -275,7 +275,7 @@ theorem rightInv_coeff (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] ext v have N : 0 < n + 2 := by simp have : ((p 1) fun _ : Fin 1 => 0) = 0 := ContinuousMultilinearMap.map_zero _ - simp [comp_rightInv_aux1 N, this, comp_rightInv_aux2, -Set.toFinset_setOf] + simp [comp_rightInv_aux1 N, this, comp_rightInv_aux2, -Set.toFinset_ofPred] /-! ### Coincidence of the left and the right inverse -/ @@ -392,7 +392,7 @@ theorem radius_right_inv_pos_of_radius_pos_aux1 (n : ℕ) (p : ℕ → ℝ) (hp exact prod_nonneg fun j _ ↦ (by positivity [ha, hp (x.snd.blocksFun j)]) rintro ⟨k, c⟩ hd simp only [Set.mem_toFinset (s := {c | 1 < Composition.length c}), mem_Ico, mem_sigma, - Set.mem_setOf_eq] at hd + Set.mem_ofPred_eq] at hd simp only [mem_compPartialSumTarget_iff] refine ⟨hd.2, c.length_le.trans_lt hd.1.2, fun j => ?_⟩ have : c ≠ Composition.single k (zero_lt_two.trans_le hd.1.1) := by diff --git a/Mathlib/Analysis/Analytic/Order.lean b/Mathlib/Analysis/Analytic/Order.lean index 5f8cb7ed88f349..15629de78bf86b 100644 --- a/Mathlib/Analysis/Analytic/Order.lean +++ b/Mathlib/Analysis/Analytic/Order.lean @@ -577,7 +577,7 @@ namespace AnalyticOnNhd variable {U : Set 𝕜} {f : 𝕜 → E} /-- The set where an analytic function has infinite order is clopen in its domain of analyticity. -/ -theorem isClopen_setOf_analyticOrderAt_eq_top (hf : AnalyticOnNhd 𝕜 f U) : +theorem isClopen_setOfPred_analyticOrderAt_eq_top (hf : AnalyticOnNhd 𝕜 f U) : IsClopen {u : U | analyticOrderAt f u = ⊤} := by constructor · rw [← isOpen_compl_iff, isOpen_iff_forall_mem_open] @@ -602,13 +602,16 @@ theorem isClopen_setOf_analyticOrderAt_eq_top (hf : AnalyticOnNhd 𝕜 f U) : conv => arg 1; intro; left; right; arg 1; intro rw [analyticOrderAt_eq_top, eventually_nhds_iff] - simp only [mem_setOf_eq] at hz + simp only [mem_ofPred_eq] at hz rw [analyticOrderAt_eq_top, eventually_nhds_iff] at hz obtain ⟨t', h₁t', h₂t', h₃t'⟩ := hz use Subtype.val ⁻¹' t' simp only [isOpen_induced h₂t', mem_preimage, h₃t', and_self, and_true] grind +@[deprecated (since := "2026-07-09")] +alias isClopen_setOf_analyticOrderAt_eq_top := isClopen_setOfPred_analyticOrderAt_eq_top + /-- On a connected set, there exists a point where a meromorphic function `f` has finite order iff `f` has finite order at every point. -/ theorem exists_analyticOrderAt_ne_top_iff_forall (hf : AnalyticOnNhd 𝕜 f U) (hU : IsConnected U) : @@ -617,7 +620,7 @@ theorem exists_analyticOrderAt_ne_top_iff_forall (hf : AnalyticOnNhd 𝕜 f U) ( obtain ⟨v⟩ : Nonempty U := inferInstance suffices (∀ (u : U), analyticOrderAt f u ≠ ⊤) ∨ ∀ (u : U), analyticOrderAt f u = ⊤ by tauto simpa [Set.eq_empty_iff_forall_notMem, Set.eq_univ_iff_forall] using - isClopen_iff.1 hf.isClopen_setOf_analyticOrderAt_eq_top + isClopen_iff.1 hf.isClopen_setOfPred_analyticOrderAt_eq_top /-- On a preconnected set, a meromorphic function has finite order at one point if it has finite order at another point. -/ @@ -629,7 +632,7 @@ theorem analyticOrderAt_ne_top_of_isPreconnected {x y : 𝕜} (hf : AnalyticOnNh /-- The set where an analytic function has zero or infinite order is discrete within its domain of analyticity. -/ -theorem codiscrete_setOf_analyticOrderAt_eq_zero_or_top (hf : AnalyticOnNhd 𝕜 f U) : +theorem codiscrete_setOfPred_analyticOrderAt_eq_zero_or_top (hf : AnalyticOnNhd 𝕜 f U) : {u : U | analyticOrderAt f u = 0 ∨ analyticOrderAt f u = ⊤} ∈ Filter.codiscrete U := by simp_rw [mem_codiscrete_subtype_iff_mem_codiscreteWithin, mem_codiscreteWithin, disjoint_principal_right] @@ -640,11 +643,15 @@ theorem codiscrete_setOf_analyticOrderAt_eq_zero_or_top (hf : AnalyticOnNhd 𝕜 · filter_upwards [h₁f] with a ha simp +contextual [(hf a _).analyticOrderAt_eq_zero, ha] +@[deprecated (since := "2026-07-09")] +alias codiscrete_setOf_analyticOrderAt_eq_zero_or_top := + codiscrete_setOfPred_analyticOrderAt_eq_zero_or_top + /-- The set where an analytic function has zero or infinite order is discrete within its domain of analyticity. -/ -theorem codiscreteWithin_setOf_analyticOrderAt_eq_zero_or_top (hf : AnalyticOnNhd 𝕜 f U) : +theorem codiscreteWithin_setOfPred_analyticOrderAt_eq_zero_or_top (hf : AnalyticOnNhd 𝕜 f U) : {u : 𝕜 | analyticOrderAt f u = 0 ∨ analyticOrderAt f u = ⊤} ∈ codiscreteWithin U := by simp_rw [mem_codiscreteWithin, disjoint_principal_right] intro x hx @@ -654,6 +661,10 @@ theorem codiscreteWithin_setOf_analyticOrderAt_eq_zero_or_top (hf : AnalyticOnNh · filter_upwards [h₁f] with a ha simp +contextual [(hf a _).analyticOrderAt_eq_zero, ha] +@[deprecated (since := "2026-07-09")] +alias codiscreteWithin_setOf_analyticOrderAt_eq_zero_or_top := + codiscreteWithin_setOfPred_analyticOrderAt_eq_zero_or_top + /-- If an analytic function `f` is not constantly zero on a connected set `U`, then its set of zeros is codiscrete within `U`. diff --git a/Mathlib/Analysis/Analytic/Uniqueness.lean b/Mathlib/Analysis/Analytic/Uniqueness.lean index c7842ff404e3fc..20fe97cfe84c8c 100644 --- a/Mathlib/Analysis/Analytic/Uniqueness.lean +++ b/Mathlib/Analysis/Analytic/Uniqueness.lean @@ -166,7 +166,7 @@ theorem eqOn_zero_of_preconnected_of_eventuallyEq_zero_aux [CompleteSpace F] {f let u := {x | f =ᶠ[𝓝 x] 0} suffices main : closure u ∩ U ⊆ u by have Uu : U ⊆ u := - hU.subset_of_closure_inter_subset isOpen_setOf_eventually_nhds ⟨z₀, h₀, hfz₀⟩ main + hU.subset_of_closure_inter_subset isOpen_setOfPred_eventually_nhds ⟨z₀, h₀, hfz₀⟩ main intro z hz simpa using mem_of_mem_nhds (Uu hz) /- Take a limit point `x`, then a ball `B (x, r)` on which it has a power series expansion, and diff --git a/Mathlib/Analysis/Asymptotics/Defs.lean b/Mathlib/Analysis/Asymptotics/Defs.lean index ef7188bcd7fc48..cd88403ddedceb 100644 --- a/Mathlib/Analysis/Asymptotics/Defs.lean +++ b/Mathlib/Analysis/Asymptotics/Defs.lean @@ -1176,7 +1176,7 @@ theorem isBigOWith_const_const (c : E) {c' : F''} (hc' : c' ≠ 0) (l : Filter simp only [IsBigOWith_def] apply univ_mem' intro x - rw [mem_setOf, div_mul_cancel₀ _ (norm_ne_zero_iff.mpr hc')] + rw [mem_ofPred, div_mul_cancel₀ _ (norm_ne_zero_iff.mpr hc')] theorem isBigO_const_const (c : E) {c' : F''} (hc' : c' ≠ 0) (l : Filter α) : (fun _x : α => c) =O[l] fun _x => c' := diff --git a/Mathlib/Analysis/Asymptotics/Lemmas.lean b/Mathlib/Analysis/Asymptotics/Lemmas.lean index 026a39b13ca486..6dd234c97c8585 100644 --- a/Mathlib/Analysis/Asymptotics/Lemmas.lean +++ b/Mathlib/Analysis/Asymptotics/Lemmas.lean @@ -610,7 +610,7 @@ theorem IsBigOWith.right_le_sub_of_lt_one {f₁ f₂ : α → E'} (h : IsBigOWit IsBigOWith (1 / (1 - c)) l f₂ fun x => f₂ x - f₁ x := IsBigOWith.of_bound <| mem_of_superset h.bound fun x hx => by - simp only [mem_setOf_eq] at hx ⊢ + simp only [mem_ofPred_eq] at hx ⊢ rw [mul_comm, one_div, ← div_eq_mul_inv, le_div_iff₀, mul_sub, mul_one, mul_comm] · exact le_trans (sub_le_sub_left hx _) (norm_sub_norm_le _ _) · exact sub_pos.2 hc @@ -744,7 +744,7 @@ lemma isBigO_nat_atTop_induction {f : ℕ → E''} {g : ℕ → F''} let ubounds := {C | ∀ m ∈ Finset.Icc n₀ n₁, ‖f m‖ ≤ C * ‖g m‖} let C₁ := (Finset.Icc n₀ n₁).sup' (Finset.nonempty_Icc.mpr H₁) fun n => ‖f n‖ / ‖g n‖ have C₁_mem : C₁ ∈ ubounds := by - rw [Set.mem_setOf] + rw [Set.mem_ofPred] intro m hm calc ‖f m‖ = (‖f m‖ / ‖g m‖) * ‖g m‖ := by by_cases hm' : g m = 0 <;> grind [norm_eq_zero] _ ≤ C₁ * ‖g m‖ := by diff --git a/Mathlib/Analysis/BoxIntegral/Basic.lean b/Mathlib/Analysis/BoxIntegral/Basic.lean index 90d0a9b09bc2e2..6fdefd88a4ba4f 100644 --- a/Mathlib/Analysis/BoxIntegral/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Basic.lean @@ -228,7 +228,7 @@ theorem integrable_iff_cauchy_basis [CompleteSpace F] : Integrable I l f vol ↔ rw [integrable_iff_cauchy, cauchy_map_iff', (l.hasBasis_toFilteriUnion_top _).prod_self.tendsto_iff uniformity_basis_dist_le] refine forall₂_congr fun ε _ => exists_congr fun r => ?_ - simp only [Prod.forall, exists_imp, prodMk_mem_set_prod_eq, and_imp, mem_setOf_eq] + simp only [Prod.forall, exists_imp, prodMk_mem_set_prod_eq, and_imp, mem_ofPred_eq] exact and_congr Iff.rfl ⟨fun H c₁ c₂ π₁ π₂ h₁ hU₁ h₂ hU₂ => H π₁ π₂ c₁ h₁ hU₁ c₂ h₂ hU₂, @@ -600,7 +600,7 @@ theorem tendsto_integralSum_sum_integral (h : Integrable I l f vol) (π₀ : Pre (𝓝 <| ∑ J ∈ π₀.boxes, integral J l f vol) := by refine ((l.hasBasis_toFilteriUnion I π₀).tendsto_iff nhds_basis_closedBall).2 fun ε ε0 => ?_ refine ⟨h.convergenceR ε, h.convergenceR_cond ε, ?_⟩ - simp only [mem_setOf_eq] + simp only [mem_ofPred_eq] rintro π ⟨c, hc, hU⟩ exact h.dist_integralSum_sum_integral_le_of_memBaseSet_of_iUnion_eq ε0 hc hU @@ -807,7 +807,7 @@ theorem HasIntegral.of_bRiemann_eq_false_of_forall_isLittleO (hl : l.bRiemann = classical set δ : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ) := fun c x => if x ∈ s then δ₁ c x (εs x) else (δ₂ c) x ε' refine ⟨δ, fun c => l.rCond_of_bRiemann_eq_false hl, ?_⟩ - simp only [mem_setOf_eq] + simp only [mem_ofPred_eq] rintro π ⟨c, hπδ, hπp⟩ -- Now we split the sum into two parts based on whether `π.tag J` belongs to `s` or not. rw [← g.sum_partition_boxes le_rfl hπp, Metric.mem_closedBall, integralSum, diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean index e4f9829f93ca68..f5a7507378a156 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean @@ -160,14 +160,14 @@ theorem bot_boxes : (⊥ : Prepartition I).boxes = ∅ := rfl /-- An auxiliary lemma used to prove that the same point can't belong to more than `2 ^ Fintype.card ι` closed boxes of a prepartition. -/ -theorem injOn_setOf_mem_Icc_setOf_lower_eq (x : ι → ℝ) : +theorem injOn_setOfPred_mem_Icc_setOfPred_lower_eq (x : ι → ℝ) : InjOn (fun J : Box ι => { i | J.lower i = x i }) { J | J ∈ π ∧ x ∈ Box.Icc J } := by rintro J₁ ⟨h₁, hx₁⟩ J₂ ⟨h₂, hx₂⟩ (H : { i | J₁.lower i = x i } = { i | J₂.lower i = x i }) suffices ∀ i, (Ioc (J₁.lower i) (J₁.upper i) ∩ Ioc (J₂.lower i) (J₂.upper i)).Nonempty by choose y hy₁ hy₂ using this exact π.eq_of_mem_of_mem h₁ h₂ hy₁ hy₂ intro i - simp only [Set.ext_iff, mem_setOf] at H + simp only [Set.ext_iff, mem_ofPred] at H rcases (hx₁.1 i).eq_or_lt with hi₁ | hi₁ · have hi₂ : J₂.lower i = x i := (H _).1 hi₁ have H₁ : x i < J₁.upper i := by simpa only [hi₁] using J₁.lower_lt_upper i @@ -177,6 +177,9 @@ theorem injOn_setOf_mem_Icc_setOf_lower_eq (x : ι → ℝ) : · have hi₂ : J₂.lower i < x i := (hx₂.1 i).lt_of_ne (mt (H _).2 hi₁.ne) exact ⟨x i, ⟨hi₁, hx₁.2 i⟩, ⟨hi₂, hx₂.2 i⟩⟩ +@[deprecated (since := "2026-07-09")] +alias injOn_setOf_mem_Icc_setOf_lower_eq := injOn_setOfPred_mem_Icc_setOfPred_lower_eq + open scoped Classical in /-- The set of boxes of a prepartition that contain `x` in their closures has cardinality at most `2 ^ Fintype.card ι`. -/ @@ -185,7 +188,7 @@ theorem card_filter_mem_Icc_le [Fintype ι] (x : ι → ℝ) : rw [← Fintype.card_set] refine Finset.card_le_card_of_injOn (fun J : Box ι => { i | J.lower i = x i }) (fun _ _ => Finset.mem_univ _) ?_ - simpa using π.injOn_setOf_mem_Icc_setOf_lower_eq x + simpa using π.injOn_setOfPred_mem_Icc_setOfPred_lower_eq x /-- Given a prepartition `π : BoxIntegral.Prepartition I`, `π.iUnion` is the part of `I` covered by the boxes of `π`. -/ diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean b/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean index b211a19341e72f..b940930d2bc433 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Filter.lean @@ -450,7 +450,7 @@ theorem hasBasis_toFilteriUnion (l : IntegrationParams) (I : Box ι) (π₀ : Pr (l.toFilteriUnion I π₀).HasBasis (fun r : ℝ≥0 → (ι → ℝ) → Ioi (0 : ℝ) => ∀ c, l.RCond (r c)) fun r => { π | ∃ c, l.MemBaseSet I c (r c) π ∧ π.iUnion = π₀.iUnion } := by have := fun c => l.hasBasis_toFilterDistortioniUnion I c π₀ - simpa only [setOf_and, setOf_exists] using! hasBasis_iSup this + simpa only [ofPred_and, ofPred_exists] using! hasBasis_iSup this theorem hasBasis_toFilteriUnion_top (l : IntegrationParams) (I : Box ι) : (l.toFilteriUnion I ⊤).HasBasis (fun r : ℝ≥0 → (ι → ℝ) → Ioi (0 : ℝ) => ∀ c, l.RCond (r c)) @@ -461,7 +461,7 @@ theorem hasBasis_toFilteriUnion_top (l : IntegrationParams) (I : Box ι) : theorem hasBasis_toFilter (l : IntegrationParams) (I : Box ι) : (l.toFilter I).HasBasis (fun r : ℝ≥0 → (ι → ℝ) → Ioi (0 : ℝ) => ∀ c, l.RCond (r c)) fun r => { π | ∃ c, l.MemBaseSet I c (r c) π } := by - simpa only [setOf_exists] using! hasBasis_iSup (l.hasBasis_toFilterDistortion I) + simpa only [ofPred_exists] using! hasBasis_iSup (l.hasBasis_toFilterDistortion I) theorem tendsto_embedBox_toFilteriUnion_top (l : IntegrationParams) (h : I ≤ J) : Tendsto (TaggedPrepartition.embedBox I J h) (l.toFilteriUnion I ⊤) @@ -472,7 +472,7 @@ theorem tendsto_embedBox_toFilteriUnion_top (l : IntegrationParams) (h : I ≤ J refine ((l.hasBasis_toFilterDistortioniUnion I c ⊤).tendsto_iff (l.hasBasis_toFilterDistortioniUnion J _ _)).2 fun r hr => ?_ refine ⟨r, hr, fun π hπ => ?_⟩ - rw [mem_setOf_eq, Prepartition.iUnion_top] at hπ + rw [mem_ofPred_eq, Prepartition.iUnion_top] at hπ refine ⟨⟨hπ.1.1, hπ.1.2, fun hD => le_trans (hπ.1.3 hD) (le_max_left _ _), fun _ => ?_⟩, ?_⟩ · refine ⟨_, π₀.iUnion_compl.trans ?_, le_max_right _ _⟩ congr 1 diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Split.lean b/Mathlib/Analysis/BoxIntegral/Partition/Split.lean index 796c691bb8e383..978797635dc6d9 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Split.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Split.lean @@ -63,7 +63,7 @@ def splitLower (I : Box ι) (i : ι) (x : ℝ) : WithBot (Box ι) := theorem coe_splitLower : (splitLower I i x : Set (ι → ℝ)) = ↑I ∩ { y | y i ≤ x } := by rw [splitLower, coe_mk'] ext y - simp only [mem_univ_pi, mem_Ioc, mem_inter_iff, mem_coe, mem_setOf_eq, forall_and, ← Pi.le_def, + simp only [mem_univ_pi, mem_Ioc, mem_inter_iff, mem_coe, mem_ofPred_eq, forall_and, ← Pi.le_def, le_update_iff, le_min_iff, and_assoc, and_forall_ne (p := fun j => y j ≤ upper I j) i, mem_def] rw [and_comm (a := y i ≤ x)] @@ -101,7 +101,7 @@ theorem coe_splitUpper : (splitUpper I i x : Set (ι → ℝ)) = ↑I ∩ { y | classical rw [splitUpper, coe_mk'] ext y - simp only [mem_univ_pi, mem_Ioc, mem_inter_iff, mem_coe, mem_setOf_eq, forall_and, + simp only [mem_univ_pi, mem_Ioc, mem_inter_iff, mem_coe, mem_ofPred_eq, forall_and, forall_update_iff I.lower fun j z => z < y j, max_lt_iff, and_assoc (a := x < y i), and_forall_ne (p := fun j => lower I j < y j) i, mem_def] exact and_comm @@ -173,7 +173,7 @@ theorem mem_split_iff' : J ∈ split I i x ↔ @[simp] theorem iUnion_split (I : Box ι) (i : ι) (x : ℝ) : (split I i x).iUnion = I := by - simp [split, ← inter_union_distrib_left, ← setOf_or, le_or_gt] + simp [split, ← inter_union_distrib_left, ← ofPred_or, le_or_gt] theorem isPartitionSplit (I : Box ι) (i : ι) (x : ℝ) : IsPartition (split I i x) := isPartition_iff_iUnion_eq.2 <| iUnion_split I i x diff --git a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean index 91bc19a0f3d949..5684b81b6a655a 100644 --- a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean +++ b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean @@ -208,7 +208,7 @@ theorem setFinite_index {s : Set (ι → ℝ)} (hs₁ : NullMeasurableSet s) (hs · exact ((Disjoint.inter_right _ (disjoint.mp h)).inter_left _).aedisjoint · exact lt_top_iff_ne_top.mp <| measure_lt_top_of_subset (by simp only [Set.iUnion_subset_iff, Set.inter_subset_right, implies_true]) hs₂ - · rw [Set.mem_setOf, Set.inter_eq_self_of_subset_left hν, volume_box] + · rw [Set.mem_ofPred, Set.inter_eq_self_of_subset_left hν, volume_box] /-- For `B : BoxIntegral.Box`, the set of indices of `unitPartition.box` that are subsets of `B`. This is a finite set. These boxes cover `B` if it has integral vertices, see @@ -220,7 +220,7 @@ def admissibleIndex (B : Box ι) : Finset (ι → ℤ) := by variable {n} in theorem mem_admissibleIndex_iff {B : Box ι} {ν : ι → ℤ} : ν ∈ admissibleIndex n B ↔ box n ν ≤ B := by - rw [admissibleIndex, Set.Finite.mem_toFinset, Set.mem_setOf_eq, Box.coe_subset_coe] + rw [admissibleIndex, Set.Finite.mem_toFinset, Set.mem_ofPred_eq, Box.coe_subset_coe] open scoped Classical in /-- For `B : BoxIntegral.Box`, the `TaggedPrepartition` formed by the set of all diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean index 14eb52c7561fd5..1fa2f8b2e31793 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean @@ -59,7 +59,7 @@ protected theorem Commute.cfcHom {a b : A} (ha : p a) (hb₁ : Commute a b) | add f g hf hg => rw [map_add]; exact hf.add_left hg | mul f g hf hg => rw [map_mul]; exact mul_left hf hg | frequently f hf => - rw [commute_iff_eq, ← Set.mem_setOf (p := fun x => x * b = b * x), + rw [commute_iff_eq, ← Set.mem_ofPred (p := fun x => x * b = b * x), ← (isClosed_eq (by fun_prop) (by fun_prop)).closure_eq] apply mem_closure_of_frequently_of_tendsto hf exact cfcHom_continuous ha |>.tendsto _ @@ -144,7 +144,7 @@ protected theorem Commute.cfcₙHom {a b : A} (ha : p a) (hb₁ : Commute a b) | add f g hf hg => rw [map_add]; exact hf.add_left hg | mul f g hf hg => rw [map_mul]; exact mul_left hf hg | frequently f hf => - rw [commute_iff_eq, ← Set.mem_setOf (p := fun x => x * b = b * x), + rw [commute_iff_eq, ← Set.mem_ofPred (p := fun x => x * b = b * x), ← (isClosed_eq (by fun_prop) (by fun_prop)).closure_eq] apply mem_closure_of_frequently_of_tendsto hf exact cfcₙHom_continuous ha |>.tendsto _ diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean index e423b7abf9d708..24b09a846a51d7 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean @@ -220,7 +220,7 @@ theorem continuous_cfcHomSuperset_left apply continuous_of_uniform_approx_of_continuous rw [Metric.uniformity_basis_dist_le.forall_iff (by aesop)] intro ε hε - simp only [Set.mem_setOf_eq, dist_eq_norm] + simp only [Set.mem_ofPred_eq, dist_eq_norm] obtain ⟨g, hg, g_cont⟩ := frequently_iff.mp hf (Metric.closedBall_mem_nhds f hε) simp only [Metric.mem_closedBall, dist_comm g, dist_eq_norm] at hg refine ⟨_, g_cont, fun x ↦ ?_⟩ @@ -422,7 +422,7 @@ theorem continuousOn_cfc_nnreal {s : Set ℝ≥0} (hs : IsCompact s) intro x hx simpa refine continuousOn_cfc A (hs.image NNReal.continuous_coe) _ hf |>.mono fun a ha ↦ ?_ - simp only [Set.mem_setOf_eq, nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts] at ha ⊢ + simp only [Set.mem_ofPred_eq, nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts] at ha ⊢ rw [← SpectrumRestricts] at ha refine ⟨ha.1.1, ?_⟩ rw [← ha.1.2.algebraMap_image] @@ -754,7 +754,7 @@ theorem continuous_cfcₙHomSuperset_left apply continuous_of_uniform_approx_of_continuous rw [Metric.uniformity_basis_dist_le.forall_iff (by aesop)] intro ε hε - simp only [Set.mem_setOf_eq, dist_eq_norm] + simp only [Set.mem_ofPred_eq, dist_eq_norm] obtain ⟨g, hg, g_cont⟩ := frequently_iff.mp hf (Metric.closedBall_mem_nhds f hε) simp only [Metric.mem_closedBall, dist_comm g, dist_eq_norm] at hg refine ⟨_, g_cont, fun x ↦ ?_⟩ @@ -973,7 +973,7 @@ theorem continuousOn_cfcₙ_nnreal {s : Set ℝ≥0} (hs : IsCompact s) (f : ℝ intro x hx simpa refine continuousOn_cfcₙ A (hs.image NNReal.continuous_coe) _ hf |>.mono fun a ha ↦ ?_ - simp only [Set.mem_setOf_eq, nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts] at ha ⊢ + simp only [Set.mem_ofPred_eq, nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts] at ha ⊢ refine ⟨ha.1.1, ?_⟩ rw [← ha.1.2.algebraMap_image] exact Set.image_mono ha.2 diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean index 796f98de0f49ad..0046479cf9d6f9 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean @@ -482,11 +482,12 @@ lemma isClosed_nonneg : IsClosed {a : A | 0 ≤ a} := by rw [Unitization.isometry_inr (𝕜 := ℂ) |>.isClosedEmbedding.isClosed_iff_image_isClosed] convert! this.inter <| (Unitization.isometry_inr (𝕜 := ℂ)).isClosedEmbedding.isClosed_range ext a - simp only [Set.mem_image, Set.mem_setOf_eq, Set.mem_inter_iff, Set.mem_range, ← exists_and_left] + simp only [Set.mem_image, Set.mem_ofPred_eq, Set.mem_inter_iff, Set.mem_range, + ← exists_and_left] congr! 2 with x exact and_congr_left fun h ↦ by simp [← h] simp only [nonneg_iff_isSelfAdjoint_and_quasispectrumRestricts, - and_congr_right (SpectrumRestricts.nnreal_iff_nnnorm · le_rfl), Set.setOf_and] + and_congr_right (SpectrumRestricts.nnreal_iff_nnnorm · le_rfl), Set.ofPred_and] refine isClosed_eq ?_ ?_ |>.inter <| isClosed_le ?_ ?_ all_goals fun_prop diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean index d5c57f6db61e4f..2bca9810f587b1 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean @@ -125,7 +125,7 @@ variable [ContinuousStar A] [StarModule ℝ A] lemma range_cfc_nnreal_subset [ContinuousFunctionalCalculus ℝ A IsSelfAdjoint] (a : A) (ha : 0 ≤ a := by cfc_tac) : Set.range (cfc (R := ℝ≥0) · a) ⊆ {x | x ∈ StarAlgebra.elemental ℝ a ∧ 0 ≤ x} := by - grw [range_cfc_nnreal_eq_image_cfc_real a ha, Set.setOf_and, SetLike.setOf_mem_eq, + grw [range_cfc_nnreal_eq_image_cfc_real a ha, Set.ofPred_and, SetLike.setOfPred_mem_eq, ← range_cfc_subset ℝ ha.isSelfAdjoint, Set.inter_comm, ← Set.image_preimage_eq_inter_range] exact Set.image_mono fun _ ↦ cfc_nonneg @@ -133,7 +133,7 @@ lemma range_cfc_nnreal [ClosedEmbeddingContinuousFunctionalCalculus ℝ A IsSelfAdjoint] (a : A) (ha : 0 ≤ a) : Set.range (cfc (R := ℝ≥0) · a) = {x | x ∈ StarAlgebra.elemental ℝ a ∧ 0 ≤ x} := by apply subset_antisymm (range_cfc_nnreal_subset a ha) - rw [range_cfc_nnreal_eq_image_cfc_real a ha, Set.setOf_and, SetLike.setOf_mem_eq, + rw [range_cfc_nnreal_eq_image_cfc_real a ha, Set.ofPred_and, SetLike.setOfPred_mem_eq, ← range_cfc _ ha.isSelfAdjoint, Set.inter_comm, ← Set.image_preimage_eq_inter_range] rintro _ ⟨f, hf, rfl⟩ exact cfc_cases _ a f ⟨0, by simp, by simp⟩ fun hf' ha' ↦ @@ -235,18 +235,18 @@ variable [StarModule ℝ A] [ContinuousStar A] [ContinuousConstSMul ℝ A] lemma range_cfcₙ_nnreal_subset [NonUnitalContinuousFunctionalCalculus ℝ A IsSelfAdjoint] (a : A) (ha : 0 ≤ a := by cfc_tac) : Set.range (cfcₙ (R := ℝ≥0) · a) ⊆ {x | x ∈ NonUnitalStarAlgebra.elemental ℝ a ∧ 0 ≤ x} := by - grw [range_cfcₙ_nnreal_eq_image_cfcₙ_real a ha, Set.setOf_and, SetLike.setOf_mem_eq, + grw [range_cfcₙ_nnreal_eq_image_cfcₙ_real a ha, Set.ofPred_and, SetLike.setOfPred_mem_eq, ← range_cfcₙ_subset _ ha.isSelfAdjoint, Set.inter_comm, ← Set.image_preimage_eq_inter_range] exact Set.image_mono fun _ ↦ cfcₙ_nonneg lemma range_cfcₙ_nnreal [NonUnitalClosedEmbeddingContinuousFunctionalCalculus ℝ A IsSelfAdjoint] (a : A) (ha : 0 ≤ a := by cfc_tac) : Set.range (cfcₙ (R := ℝ≥0) · a) = {x | x ∈ NonUnitalStarAlgebra.elemental ℝ a ∧ 0 ≤ x} := by - rw [range_cfcₙ_nnreal_eq_image_cfcₙ_real a ha, Set.setOf_and, SetLike.setOf_mem_eq, + rw [range_cfcₙ_nnreal_eq_image_cfcₙ_real a ha, Set.ofPred_and, SetLike.setOfPred_mem_eq, ← range_cfcₙ _ ha.isSelfAdjoint, Set.inter_comm, ← Set.image_preimage_eq_inter_range] refine Set.Subset.antisymm (Set.image_mono (fun _ ↦ cfcₙ_nonneg)) ?_ rintro _ ⟨f, hf, rfl⟩ - simp only [Set.preimage_setOf_eq, Set.mem_setOf_eq, Set.mem_image] at hf ⊢ + simp only [Set.preimage_ofPred_eq, Set.mem_ofPred_eq, Set.mem_image] at hf ⊢ obtain (⟨h₁, h₂, h₃⟩ | h | h | h) := by simpa only [not_and_or] using em (ContinuousOn f (quasispectrum ℝ a) ∧ f 0 = 0 ∧ IsSelfAdjoint a) diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unitary.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unitary.lean index 28dc156f35cfef..4326a7841cbedb 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unitary.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unitary.lean @@ -29,7 +29,7 @@ variable [Algebra R A] [ContinuousFunctionalCalculus R A p] lemma cfc_unitary_iff (f : R → R) (a : A) (ha : p a := by cfc_tac) (hf : ContinuousOn f (spectrum R a) := by cfc_cont_tac) : cfc f a ∈ unitary A ↔ ∀ x ∈ spectrum R a, star (f x) * f x = 1 := by - simp only [unitary, Submonoid.mem_mk, Subsemigroup.mem_mk, Set.mem_setOf_eq] + simp only [unitary, Submonoid.mem_mk, Subsemigroup.mem_mk, Set.mem_ofPred_eq] rw [← IsStarNormal.cfc_map (p := p) f a |>.star_comm_self |>.eq, and_self, ← cfc_one R a, ← cfc_star, ← cfc_mul .., cfc_eq_cfc_iff_eqOn] exact Iff.rfl diff --git a/Mathlib/Analysis/CStarAlgebra/Extreme.lean b/Mathlib/Analysis/CStarAlgebra/Extreme.lean index aa45572a6a0ff4..7bf7715670618e 100644 --- a/Mathlib/Analysis/CStarAlgebra/Extreme.lean +++ b/Mathlib/Analysis/CStarAlgebra/Extreme.lean @@ -24,11 +24,11 @@ variable {A : Type*} [NonUnitalCStarAlgebra A] /-- The star projections in a non-unital C⋆-algebra are exactly the extreme points of the nonnegative closed unit ball. -/ -theorem isStarProjection_iff_mem_extremePoints_setOf_nonneg_inter_unitClosedBall +theorem isStarProjection_iff_mem_extremePoints_setOfPred_nonneg_inter_unitClosedBall [PartialOrder A] [StarOrderedRing A] {e : A} : IsStarProjection e ↔ e ∈ extremePoints ℝ ({x : A | 0 ≤ x} ∩ closedBall 0 1) := by simp only [mem_closedBall_zero_iff, mem_extremePoints_iff_left, mem_inter_iff, - mem_setOf_eq, and_imp] + mem_ofPred_eq, and_imp] refine ⟨fun he ↦ ⟨⟨he.nonneg, he.norm_le⟩, fun a ha ha1 b hb hb1 ⟨t, s, h0t, h0s, hts, hlin⟩ ↦ ?_⟩, fun ⟨⟨h1, h2⟩, h3⟩ ↦ ?_⟩ · /- Suppose `e` is a star projection, and `a` and `b` are in the nonnegative closed unit ball @@ -83,3 +83,7 @@ theorem isStarProjection_iff_mem_extremePoints_setOf_nonneg_inter_unitClosedBall · rw [← norm_inr (𝕜 := ℂ), norm_le_one_iff_of_nonneg _ this, ← sub_nonneg] calc 0 ≤ star (1 - e : A⁺¹) * (1 - e) := star_mul_self_nonneg _ _ = _ := by simp [LE.le.star_eq, h1, mul_sub, sub_mul, two_smul, sub_sub, add_sub] + +@[deprecated (since := "2026-07-09")] +alias isStarProjection_iff_mem_extremePoints_setOf_nonneg_inter_unitClosedBall := + isStarProjection_iff_mem_extremePoints_setOfPred_nonneg_inter_unitClosedBall diff --git a/Mathlib/Analysis/CStarAlgebra/Multiplier.lean b/Mathlib/Analysis/CStarAlgebra/Multiplier.lean index 2e7e3627c8e6b8..5ba03960d1c82d 100644 --- a/Mathlib/Analysis/CStarAlgebra/Multiplier.lean +++ b/Mathlib/Analysis/CStarAlgebra/Multiplier.lean @@ -522,7 +522,7 @@ theorem isUniformEmbedding_toProdMulOpposite : instance [CompleteSpace A] : CompleteSpace 𝓜(𝕜, A) := by rw [completeSpace_iff_isComplete_range isUniformEmbedding_toProdMulOpposite.isUniformInducing] apply IsClosed.isComplete - simp only [range_toProdMulOpposite, Set.setOf_forall] + simp only [range_toProdMulOpposite, Set.ofPred_forall] exact isClosed_iInter fun x ↦ isClosed_iInter fun y ↦ isClosed_eq (by fun_prop) (by fun_prop) variable [StarRing A] [CStarRing A] diff --git a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean index 2977be3ed121bd..951ea294ce6b81 100644 --- a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean +++ b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean @@ -209,7 +209,7 @@ theorem selfAdjoint.val_re_map_spectrum (a : selfAdjoint A) : lemma IsSelfAdjoint.isConnected_spectrum_compl {a : A} (ha : IsSelfAdjoint a) : IsConnected (σ ℂ a)ᶜ := by suffices IsConnected (((σ ℂ a)ᶜ ∩ {z | 0 ≤ z.im}) ∪ (σ ℂ a)ᶜ ∩ {z | z.im ≤ 0}) by - rw [← Set.inter_union_distrib_left, ← Set.setOf_or] at this + rw [← Set.inter_union_distrib_left, ← Set.ofPred_or] at this rw [← Set.inter_univ (σ ℂ a)ᶜ] convert this exact Eq.symm <| Set.eq_univ_of_forall (fun z ↦ le_total 0 z.im) @@ -222,7 +222,7 @@ lemma IsSelfAdjoint.isConnected_spectrum_compl {a : A} (ha : IsSelfAdjoint a) : case' lower => apply Complex.isConnected_of_lowerHalfPlane ?_ <| Set.inter_subset_right all_goals refine Set.subset_inter (fun z hz hz' ↦ ?_) (fun _ ↦ by simpa using le_of_lt) - rw [Set.mem_setOf_eq, ha.im_eq_zero_of_mem_spectrum hz'] at hz + rw [Set.mem_ofPred_eq, ha.im_eq_zero_of_mem_spectrum hz'] at hz simp_all namespace StarSubalgebra diff --git a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean index 3b531908c14d70..a8d3fd6225926e 100644 --- a/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean +++ b/Mathlib/Analysis/CStarAlgebra/Unitary/Connected.lean @@ -225,10 +225,10 @@ lemma Unitary.continuousOn_argSelfAdjoint : apply ContinuousOn.image_comp_continuous ?_ continuous_subtype_val apply continuousOn_cfc A (s := sphere 0 1 ∩ {z | 2 * (1 - z.re) ≤ ε}) ?_ _ ?_ |>.mono · rintro - ⟨v, hv, rfl⟩ - simp only [Set.subset_inter_iff, Set.mem_setOf_eq] + simp only [Set.subset_inter_iff, Set.mem_ofPred_eq] refine ⟨inferInstance, spectrum_subset_circle v, ?_⟩ intro z hz - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] trans ‖(v - 1 : A)‖ ^ 2 · exact two_mul_one_sub_le_norm_sub_one_sq v.2 hz · refine Real.le_sqrt (by positivity) (by positivity) |>.mp ?_ diff --git a/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean b/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean index 80dd4cd7c301e8..67c4ec8a525ff5 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean @@ -13,7 +13,7 @@ public import Mathlib.Analysis.Calculus.BumpFunction.FiniteDimension In this file we prove that smooth functions are dense in the set of continuous functions from a real finite-dimensional vector space to a Banach space, -see `ContinuousMap.dense_setOf_contDiff`. +see `ContinuousMap.dense_setOfPred_contDiff`. We also prove several unbundled versions of this statement. The heavy part of the proof is done upstream in `ContDiffBump.dist_normed_convolution_le` @@ -52,11 +52,11 @@ theorem UniformContinuous.exists_contDiff_dist_le (hf : UniformContinuous f) (h exact ⟨g, hgc, fun a ↦ (hg a _ fun _ h ↦ (hfδ h).le).trans_lt (half_lt_self hε)⟩ /-- Infinitely smooth functions are dense in the space of continuous functions. -/ -theorem ContinuousMap.dense_setOf_contDiff : Dense {f : C(E, F) | ContDiff ℝ ∞ f} := by +theorem ContinuousMap.dense_setOfPred_contDiff : Dense {f : C(E, F) | ContDiff ℝ ∞ f} := by intro f rw [mem_closure_iff_nhds_basis (nhds_basis_uniformity uniformity_basis_dist.compactConvergenceUniformity)] - simp only [Prod.forall, mem_setOf_eq, and_imp] + simp only [Prod.forall, mem_ofPred_eq, and_imp] intro K ε hK hε have : UniformContinuousOn f (cthickening 1 K) := hK.cthickening.uniformContinuousOn_of_continuous <| by fun_prop @@ -67,3 +67,6 @@ theorem ContinuousMap.dense_setOf_contDiff : Dense {f : C(E, F) | ContDiff ℝ rw [mem_ball, lt_min_iff] at hy exact hfδ _ (mem_cthickening_of_dist_le _ x _ _ hx hy.1.le) _ (self_subset_cthickening _ hx) hy.2 |>.le + +@[deprecated (since := "2026-07-09")] +alias ContinuousMap.dense_setOf_contDiff := ContinuousMap.dense_setOfPred_contDiff diff --git a/Mathlib/Analysis/Calculus/Deriv/Inv.lean b/Mathlib/Analysis/Calculus/Deriv/Inv.lean index e81a21975b47f2..9872e356f606bd 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Inv.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Inv.lean @@ -45,7 +45,7 @@ theorem hasStrictDerivAt_inv (hx : x ≠ 0) : HasStrictDerivAt Inv.inv (-(x ^ 2) refine .of_isLittleO <| this.congr' ?_ (Eventually.of_forall fun _ => mul_one _) refine Eventually.mono ((isOpen_ne.prod isOpen_ne).mem_nhds ⟨hx, hx⟩) ?_ rintro ⟨y, z⟩ ⟨hy, hz⟩ - simp only [mem_setOf_eq] at hy hz + simp only [mem_ofPred_eq] at hy hz simp [field] ring refine (isBigO_refl (fun p : 𝕜 × 𝕜 => p.1 - p.2) _).mul_isLittleO ((isLittleO_one_iff 𝕜).2 ?_) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean index 691f26f39fbed8..ff064c774c6fe5 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean @@ -793,7 +793,7 @@ open Uniformity lemma isOpen_A_with_param {r s : ℝ} (hf : Continuous f.uncurry) (L : E →L[𝕜] F) : IsOpen {p : α × E | p.2 ∈ A (f p.1) L r s} := by have : ProperSpace E := .of_locallyCompactSpace 𝕜 - simp only [A, mem_Ioc, mem_ball, map_sub, mem_setOf_eq] + simp only [A, mem_Ioc, mem_ball, map_sub, mem_ofPred_eq] apply isOpen_iff_mem_nhds.2 rintro ⟨a, x⟩ ⟨r', ⟨Irr', Ir'r⟩, hr⟩ rcases exists_between Irr' with ⟨t, hrt, htr'⟩ @@ -876,7 +876,7 @@ theorem measurableSet_of_differentiableAt_of_isComplete_with_param = {p : α × E | p.2 ∈ D (f p.1) K} := by simp [← differentiable_set_eq_D K hK] rw [this] simp only [D, mem_iInter, mem_iUnion] - simp only [setOf_forall, setOf_exists] + simp only [ofPred_forall, ofPred_exists] refine MeasurableSet.iInter (fun _ ↦ ?_) refine MeasurableSet.iUnion (fun _ ↦ ?_) refine MeasurableSet.iInter (fun _ ↦ ?_) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean index 63fbce1a282eff..513adb09ee91aa 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Symmetric.lean @@ -303,7 +303,7 @@ theorem Convex.taylor_approx_two_segment {v w : E} (hv : x + v ∈ interior s) refine ⟨?_, xt_mem t ⟨ht.1, ht.2.le⟩⟩ rw [add_assoc, add_mem_ball_iff_norm] exact I.trans_lt hδ - simpa only [mem_setOf_eq, add_assoc x, add_sub_cancel_left] using sδ H + simpa only [mem_ofPred_eq, add_assoc x, add_sub_cancel_left] using sδ H _ ≤ ε * (‖h • v‖ + ‖h • w‖) * ‖h • w‖ := by gcongr apply (norm_add_le _ _).trans diff --git a/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean b/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean index 205985ca6109f2..99195d3d7f6af3 100644 --- a/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean @@ -398,7 +398,8 @@ theorem HasLineDerivAt.le_of_lip' {f : E → F} {f' : F} {x₀ : E} (hf : HasLin have A : Continuous (fun (t : 𝕜) ↦ x₀ + t • v) := by fun_prop have : ∀ᶠ x in 𝓝 (x₀ + (0 : 𝕜) • v), ‖f x - f x₀‖ ≤ C * ‖x - x₀‖ := by simpa using hlip filter_upwards [(A.continuousAt (x := 0)).preimage_mem_nhds this] with t ht - simp only [preimage_setOf_eq, add_sub_cancel_left, norm_smul, mem_setOf_eq, mul_comm (‖t‖)] at ht + simp only [preimage_ofPred_eq, add_sub_cancel_left, norm_smul, mem_ofPred_eq, + mul_comm (‖t‖)] at ht simpa [mul_assoc] using ht /-- Converse to the mean value inequality: if `f` is line differentiable at `x₀` and `C`-lipschitz @@ -433,7 +434,8 @@ theorem norm_lineDeriv_le_of_lip' {f : E → F} {x₀ : E} have A : Continuous (fun (t : 𝕜) ↦ x₀ + t • v) := by fun_prop have : ∀ᶠ x in 𝓝 (x₀ + (0 : 𝕜) • v), ‖f x - f x₀‖ ≤ C * ‖x - x₀‖ := by simpa using hlip filter_upwards [(A.continuousAt (x := 0)).preimage_mem_nhds this] with t ht - simp only [preimage_setOf_eq, add_sub_cancel_left, norm_smul, mem_setOf_eq, mul_comm (‖t‖)] at ht + simp only [preimage_ofPred_eq, add_sub_cancel_left, norm_smul, mem_ofPred_eq, + mul_comm (‖t‖)] at ht simpa [mul_assoc] using ht /-- Converse to the mean value inequality: if `f` is `C`-lipschitz on a neighborhood of `x₀` diff --git a/Mathlib/Analysis/Calculus/ParametricIntegral.lean b/Mathlib/Analysis/Calculus/ParametricIntegral.lean index 451dcdc1010172..c7937b328d3ab0 100644 --- a/Mathlib/Analysis/Calculus/ParametricIntegral.lean +++ b/Mathlib/Analysis/Calculus/ParametricIntegral.lean @@ -121,8 +121,8 @@ theorem hasFDerivAt_integral_of_dominated_loc_of_lip' {F' : α → H →L[𝕜] ‖∫ a, ‖x - x₀‖⁻¹ • (F x a - F x₀ a - F' a (x - x₀)) ∂μ‖ := by apply mem_of_superset (ball_mem_nhds _ ε_pos) intro x x_in; simp only - rw [Set.mem_setOf_eq, ← norm_smul_of_nonneg (nneg _), integral_smul, integral_sub, integral_sub, - ← ContinuousLinearMap.integral_apply hF'_int] + rw [Set.mem_ofPred_eq, ← norm_smul_of_nonneg (nneg _), integral_smul, integral_sub, + integral_sub, ← ContinuousLinearMap.integral_apply hF'_int] exacts [hF_int' x x_in, hF_int, (hF_int' x x_in).sub hF_int, hF'_int.apply_continuousLinearMap _] rw [hasFDerivAt_iff_tendsto, tendsto_congr' this, ← tendsto_zero_iff_norm_tendsto_zero, ← diff --git a/Mathlib/Analysis/Calculus/SmoothSeries.lean b/Mathlib/Analysis/Calculus/SmoothSeries.lean index 0c50c2eaa9de4b..2984a03a9df601 100644 --- a/Mathlib/Analysis/Calculus/SmoothSeries.lean +++ b/Mathlib/Analysis/Calculus/SmoothSeries.lean @@ -280,6 +280,6 @@ theorem contDiff_tsum_of_eventually (hf : ∀ i, ContDiff 𝕜 N (f i)) (hv k (hk.trans hm)).subtype _ refine contDiff_tsum (fun i => (hf i).of_le (mod_cast hm)) h'u ?_ rintro k ⟨i, hi⟩ x hk - simp only [t, T, Finite.mem_toFinset, mem_setOf_eq, Finset.mem_range, not_forall, not_le, + simp only [t, T, Finite.mem_toFinset, mem_ofPred_eq, Finset.mem_range, not_forall, not_le, exists_prop, not_exists, not_and, not_lt] at hi exact hi k (Nat.lt_succ_iff.2 (WithTop.coe_le_coe.1 hk)) x diff --git a/Mathlib/Analysis/Calculus/TangentCone/Basic.lean b/Mathlib/Analysis/Calculus/TangentCone/Basic.lean index 6b15b633c211e8..d436c99da89424 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Basic.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Basic.lean @@ -29,7 +29,7 @@ variable [AddCommGroup E] [SMul 𝕜 E] [TopologicalSpace E] {s t : Set E} {x : @[gcongr] theorem tangentConeAt_mono (h : s ⊆ t) : tangentConeAt 𝕜 s x ⊆ tangentConeAt 𝕜 t x := by - simp only [tangentConeAt_def, setOf_subset_setOf] + simp only [tangentConeAt_def, ofPred_subset_ofPred] refine fun y hy ↦ hy.mono ?_ gcongr @@ -40,7 +40,7 @@ respect to `𝕜` is contained in the tangent cone of `s` at `x` with respect to theorem tangentConeAt_mono_field {𝕜' : Type*} [Monoid 𝕜'] [SMul 𝕜 𝕜'] [MulAction 𝕜' E] [IsScalarTower 𝕜 𝕜' E] : tangentConeAt 𝕜 s x ⊆ tangentConeAt 𝕜' s x := by - simp only [tangentConeAt_def, setOf_subset_setOf] + simp only [tangentConeAt_def, ofPred_subset_ofPred] refine fun y hy ↦ hy.mono ?_ rw [← smul_one_smul (Filter 𝕜')] grw [le_top (a := ⊤ • 1)] @@ -49,7 +49,7 @@ theorem Filter.HasBasis.tangentConeAt_eq_biInter_closure {ι} {p : ι → Prop} (h : (𝓝 0).HasBasis p U) : tangentConeAt 𝕜 s x = ⋂ (i) (_ : p i), closure ((univ : Set 𝕜) • (U i ∩ (x + ·) ⁻¹' s)) := by ext y - simp only [tangentConeAt_def, mem_setOf_eq, mem_iInter₂, ← map₂_smul, ← map_prod_eq_map₂, + simp only [tangentConeAt_def, mem_ofPred_eq, mem_iInter₂, ← map₂_smul, ← map_prod_eq_map₂, ((nhdsWithin_hasBasis h _).top_prod.map _).clusterPt_iff_forall_mem_closure, image_prod, image2_smul] @@ -61,7 +61,7 @@ variable [ContinuousAdd E] theorem tangentConeAt_mono_nhds (h : 𝓝[s] x ≤ 𝓝[t] x) : tangentConeAt 𝕜 s x ⊆ tangentConeAt 𝕜 t x := by - simp only [tangentConeAt_def, setOf_subset_setOf] + simp only [tangentConeAt_def, ofPred_subset_ofPred] refine fun y hy ↦ hy.mono ?_ gcongr _ • ?_ rw [nhdsWithin_le_iff] diff --git a/Mathlib/Analysis/Calculus/TangentCone/Defs.lean b/Mathlib/Analysis/Calculus/TangentCone/Defs.lean index 73b3674a166318..f78390aa206123 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Defs.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Defs.lean @@ -113,7 +113,7 @@ This lemma provides a convenient way to unfold the definition of `tangentConeAt` theorem exists_fun_of_mem_tangentConeAt (h : y ∈ tangentConeAt R s x) : ∃ (α : Type (max u v)) (l : Filter α) (_hl : l.NeBot) (c : α → R) (d : α → E), Tendsto d l (𝓝 0) ∧ (∀ᶠ n in l, x + d n ∈ s) ∧ Tendsto (fun n ↦ c n • d n) l (𝓝 y) := by - rw [tangentConeAt, mem_setOf, ← map₂_smul, ← map_prod_eq_map₂, ClusterPt, + rw [tangentConeAt, mem_ofPred, ← map₂_smul, ← map_prod_eq_map₂, ClusterPt, ← neBot_inf_comap_iff_map'] at h refine ⟨R × E, _, h, Prod.fst, Prod.snd, ?_, ?_, ?_⟩ · refine (tendsto_snd (f := ⊤)).mono_left <| inf_le_right.trans <| ?_ diff --git a/Mathlib/Analysis/Calculus/TangentCone/Seq.lean b/Mathlib/Analysis/Calculus/TangentCone/Seq.lean index 793f6005c32653..03a858118f9f01 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Seq.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Seq.lean @@ -41,7 +41,7 @@ theorem mem_tangentConeAt_iff_exists_seq {R E : Type*} [AddCommGroup E] [SMul R (∀ᶠ n in atTop, x + d n ∈ s) ∧ Tendsto (fun n ↦ c n • d n) atTop (𝓝 y) := by constructor · intro h - simp only [tangentConeAt_def, Set.mem_setOf, ← map₂_smul, ← map_prod_eq_map₂, ClusterPt, + simp only [tangentConeAt_def, Set.mem_ofPred, ← map₂_smul, ← map_prod_eq_map₂, ClusterPt, ← neBot_inf_comap_iff_map'] at h rcases @exists_seq_tendsto _ _ _ h with ⟨cd, hcd⟩ simp only [tendsto_inf, tendsto_comap_iff, tendsto_prod_iff', tendsto_nhdsWithin_iff] at hcd diff --git a/Mathlib/Analysis/Complex/AbelLimit.lean b/Mathlib/Analysis/Complex/AbelLimit.lean index e5c69cb9bf16d0..395023bb45b32d 100644 --- a/Mathlib/Analysis/Complex/AbelLimit.lean +++ b/Mathlib/Analysis/Complex/AbelLimit.lean @@ -52,7 +52,7 @@ def stolzCone (s : ℝ) : Set ℂ := {z | |z.im| < s * (1 - z.re)} theorem stolzSet_empty {M : ℝ} (hM : M ≤ 1) : stolzSet M = ∅ := by ext z - rw [stolzSet, Set.mem_setOf, Set.mem_empty_iff_false, iff_false, not_and, not_lt, ← sub_pos] + rw [stolzSet, Set.mem_ofPred, Set.mem_empty_iff_false, iff_false, not_and, not_lt, ← sub_pos] intro zn calc _ ≤ 1 * (1 - ‖z‖) := by gcongr @@ -67,7 +67,7 @@ theorem nhdsWithin_lt_le_nhdsWithin_stolzSet {M : ℝ} (hM : 1 < M) : simp only [eventually_iff, mem_nhdsWithin] refine ⟨Set.Ioo 0 2, isOpen_Ioo, by simp, fun x hx ↦ ?_⟩ push _ ∈ _ at hx - simp only [Set.mem_setOf_eq, stolzSet, ← ofReal_one, ← ofReal_sub, norm_real, + simp only [Set.mem_ofPred_eq, stolzSet, ← ofReal_one, ← ofReal_sub, norm_real, norm_of_nonneg hx.1.1.le, norm_of_nonneg <| (sub_pos.mpr hx.2).le] exact ⟨hx.2, lt_mul_left (sub_pos.mpr hx.2) hM⟩ @@ -100,8 +100,8 @@ lemma stolzCone_subset_stolzSet_aux {s : ℝ} (hs : 0 < s) : ∃ M ε, 0 < M ∧ 0 < ε ∧ {z : ℂ | 1 - ε < z.re} ∩ stolzCone s ⊆ stolzSet M := by peel stolzCone_subset_stolzSet_aux' s with M ε hM hε H rintro z ⟨hzl, hzr⟩ - rw [Set.mem_setOf_eq, sub_lt_comm, ← one_re, ← sub_re] at hzl - rw [stolzCone, Set.mem_setOf_eq, ← one_re, ← sub_re] at hzr + rw [Set.mem_ofPred_eq, sub_lt_comm, ← one_re, ← sub_re] at hzl + rw [stolzCone, Set.mem_ofPred_eq, ← one_re, ← sub_re] at hzr replace H := H (1 - z).re z.im ((mul_pos_iff_of_pos_left hs).mp <| (abs_nonneg z.im).trans_lt hzr) hzl hzr have h : z.im ^ 2 = (1 - z).im ^ 2 := by @@ -116,7 +116,7 @@ lemma nhdsWithin_stolzCone_le_nhdsWithin_stolzSet {s : ℝ} (hs : 0 < s) : use M rw [nhdsWithin_le_iff, mem_nhdsWithin] refine ⟨{w | 1 - ε < w.re}, isOpen_lt continuous_const continuous_re, ?_, H⟩ - simp only [Set.mem_setOf_eq, one_re, sub_lt_self_iff, hε] + simp only [Set.mem_ofPred_eq, one_re, sub_lt_self_iff, hε] end StolzSet diff --git a/Mathlib/Analysis/Complex/AbsMax.lean b/Mathlib/Analysis/Complex/AbsMax.lean index 469ed7e35a22c3..d3f4f0ec12187f 100644 --- a/Mathlib/Analysis/Complex/AbsMax.lean +++ b/Mathlib/Analysis/Complex/AbsMax.lean @@ -218,13 +218,16 @@ theorem norm_eventually_eq_of_isLocalMax {f : E → F} {c : E} (hr <| closure_ball_subset_closedBall hx).1.differentiableWithinAt) fun x hx => (hr <| ball_subset_closedBall hx).2⟩ -theorem isOpen_setOf_mem_nhds_and_isMaxOn_norm {f : E → F} {s : Set E} +theorem isOpen_setOfPred_mem_nhds_and_isMaxOn_norm {f : E → F} {s : Set E} (hd : DifferentiableOn ℂ f s) : IsOpen {z | s ∈ 𝓝 z ∧ IsMaxOn (norm ∘ f) s z} := by refine isOpen_iff_mem_nhds.2 fun z hz => (eventually_eventually_nhds.2 hz.1).and ?_ replace hd : ∀ᶠ w in 𝓝 z, DifferentiableAt ℂ f w := hd.eventually_differentiableAt hz.1 exact (norm_eventually_eq_of_isLocalMax hd <| hz.2.isLocalMax hz.1).mono fun x hx y hy => le_trans (hz.2 hy).out hx.ge +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_mem_nhds_and_isMaxOn_norm := isOpen_setOfPred_mem_nhds_and_isMaxOn_norm + /-- **Maximum modulus principle** on a connected set. Let `U` be a (pre)connected open set in a complex normed space. Let `f : E → F` be a function that is complex differentiable on `U`. Suppose that `‖f x‖` takes its maximum value on `U` at `c ∈ U`. Then `‖f x‖ = ‖f c‖` for all `x ∈ U`. -/ @@ -235,8 +238,8 @@ theorem norm_eqOn_of_isPreconnected_of_isMaxOn {f : E → F} {U : Set E} {c : E} have hV : ∀ x ∈ V, ‖f x‖ = ‖f c‖ := fun x hx => le_antisymm (hm hx.1) (hx.2 hcU) suffices U ⊆ V from fun x hx => hV x (this hx) have hVo : IsOpen V := by - simpa only [ho.mem_nhds_iff, setOf_and, setOf_mem_eq] - using isOpen_setOf_mem_nhds_and_isMaxOn_norm hd + simpa only [ho.mem_nhds_iff, ofPred_and, ofPred_mem_eq] + using isOpen_setOfPred_mem_nhds_and_isMaxOn_norm hd have hVne : (U ∩ V).Nonempty := ⟨c, hcU, hcU, hm⟩ set W := U ∩ {z | ‖f z‖ ≠ ‖f c‖} have hWo : IsOpen W := hd.continuousOn.norm.isOpen_inter_preimage ho isOpen_ne diff --git a/Mathlib/Analysis/Complex/Basic.lean b/Mathlib/Analysis/Complex/Basic.lean index 86fff003bf0e4d..bc2acadf83f392 100644 --- a/Mathlib/Analysis/Complex/Basic.lean +++ b/Mathlib/Analysis/Complex/Basic.lean @@ -631,7 +631,7 @@ open scoped ComplexOrder /-- The *slit plane* is the complex plane with the closed negative real axis removed. -/ def slitPlane : Set ℂ := {z | 0 < z.re ∨ z.im ≠ 0} -lemma mem_slitPlane_iff {z : ℂ} : z ∈ slitPlane ↔ 0 < z.re ∨ z.im ≠ 0 := Set.mem_setOf +lemma mem_slitPlane_iff {z : ℂ} : z ∈ slitPlane ↔ 0 < z.re ∨ z.im ≠ 0 := Set.mem_ofPred /- If `z` is non-zero, then either `z` or `-z` is in `slitPlane`. -/ lemma mem_slitPlane_or_neg_mem_slitPlane {z : ℂ} (hz : z ≠ 0) : @@ -643,7 +643,7 @@ lemma mem_slitPlane_or_neg_mem_slitPlane {z : ℂ} (hz : z ≠ 0) : by_contra! contra exact hz (le_antisymm contra.1.1 contra.2.1) contra.1.2 -lemma slitPlane_eq_union : slitPlane = {z | 0 < z.re} ∪ {z | z.im ≠ 0} := Set.setOf_or.symm +lemma slitPlane_eq_union : slitPlane = {z | 0 < z.re} ∪ {z | z.im ≠ 0} := Set.ofPred_or.symm lemma isOpen_slitPlane : IsOpen slitPlane := (isOpen_lt continuous_const continuous_re).union (isOpen_ne_fun continuous_im continuous_const) diff --git a/Mathlib/Analysis/Complex/BorelCaratheodory.lean b/Mathlib/Analysis/Complex/BorelCaratheodory.lean index 4b30ceacc5feed..36f54a4482ca60 100644 --- a/Mathlib/Analysis/Complex/BorelCaratheodory.lean +++ b/Mathlib/Analysis/Complex/BorelCaratheodory.lean @@ -112,7 +112,7 @@ public theorem borelCaratheodory (hM : 0 < M) (hf : DifferentiableOn ℂ f (ball have hfz : ‖f z - f 0‖ ≤ 2 * (M + ‖f 0‖) * ‖z‖ / (R - ‖z‖) := by apply borelCaratheodory_zero (by positivity) (by fun_prop) ?_ hR hz (by simp) intro x hx - simp only [Set.mem_setOf_eq, sub_re] + simp only [Set.mem_ofPred_eq, sub_re] calc (f x).re - (f 0).re ≤ M - (f 0).re := by gcongr; exact hf₁ hx _ ≤ M + ‖f 0‖ := by linarith [neg_le_abs (f 0).re, abs_re_le_norm (f 0)] have h_denom_ne : R - ‖z‖ ≠ 0 := by linarith [mem_ball_zero_iff.mp hz] diff --git a/Mathlib/Analysis/Complex/Convex.lean b/Mathlib/Analysis/Complex/Convex.lean index 0880cb21418b09..7f356acb4b901f 100644 --- a/Mathlib/Analysis/Complex/Convex.lean +++ b/Mathlib/Analysis/Complex/Convex.lean @@ -71,12 +71,12 @@ namespace Complex lemma isConnected_of_upperHalfPlane {r} {s : Set ℂ} (hs₁ : {z | r < z.im} ⊆ s) (hs₂ : s ⊆ {z | r ≤ z.im}) : IsConnected s := by - refine .subset_closure ?_ hs₁ (by simpa only [closure_setOf_lt_im] using hs₂) + refine .subset_closure ?_ hs₁ (by simpa only [closure_setOfPred_lt_im] using hs₂) exact (convex_halfSpace_im_gt r).isConnected ⟨(r + 1) * I, by simp⟩ lemma isConnected_of_lowerHalfPlane {r} {s : Set ℂ} (hs₁ : {z | z.im < r} ⊆ s) (hs₂ : s ⊆ {z | z.im ≤ r}) : IsConnected s := by - refine .subset_closure ?_ hs₁ (by simpa only [closure_setOf_im_lt] using hs₂) + refine .subset_closure ?_ hs₁ (by simpa only [closure_setOfPred_im_lt] using hs₂) exact (convex_halfSpace_im_lt r).isConnected ⟨(r - 1) * I, by simp⟩ lemma rectangle_eq_convexHull (z w : ℂ) : diff --git a/Mathlib/Analysis/Complex/Harmonic/Analytic.lean b/Mathlib/Analysis/Complex/Harmonic/Analytic.lean index d7bf86de72edee..bcf8efc296cddc 100644 --- a/Mathlib/Analysis/Complex/Harmonic/Analytic.lean +++ b/Mathlib/Analysis/Complex/Harmonic/Analytic.lean @@ -61,7 +61,7 @@ theorem HarmonicAt.analyticAt_complex_partial (hf : HarmonicAt f x) : AnalyticAt ℂ (fun z ↦ fderiv ℝ f z 1 - I * fderiv ℝ f z I) x := DifferentiableOn.analyticAt (s := { x | HarmonicAt f x }) (fun _ hy ↦ (HarmonicAt.differentiableAt_complex_partial hy).differentiableWithinAt) - ((isOpen_setOf_harmonicAt f).mem_nhds hf) + ((isOpen_setOfPred_harmonicAt f).mem_nhds hf) /- If a function `f : ℂ → ℝ` is harmonic on an open ball, then `f` is the real part of a function @@ -141,7 +141,7 @@ Harmonic functions are real analytic. TODO: Prove this for harmonic functions on an arbitrary f.d. inner product space (not just on `ℂ`). -/ theorem HarmonicAt.analyticAt (hf : HarmonicAt f x) : AnalyticAt ℝ f x := by - obtain ⟨ε, h₁ε, h₂ε⟩ := isOpen_iff.1 (isOpen_setOf_harmonicAt (f := f)) x hf + obtain ⟨ε, h₁ε, h₂ε⟩ := isOpen_iff.1 (isOpen_setOfPred_harmonicAt (f := f)) x hf obtain ⟨F, h₁F, h₂F⟩ := InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq (fun _ hy ↦ h₂ε hy) rw [analyticAt_congr (Filter.eventually_of_mem (ball_mem_nhds x h₁ε) (fun y hy ↦ h₂F.symm hy))] diff --git a/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean b/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean index bdea21e7477652..c45e7fd829991e 100644 --- a/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean +++ b/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean @@ -27,7 +27,7 @@ closed disc of radius `R` and center `c`, then the circle average `circleAverage theorem HarmonicOnNhd.circleAverage_eq (hf : HarmonicOnNhd f (closedBall c |R|)) : circleAverage f c R = f c := by obtain ⟨e, h₁e, h₂e⟩ := (isCompact_closedBall c |R|).exists_thickening_subset_open - (isOpen_setOf_harmonicAt f) hf + (isOpen_setOfPred_harmonicAt f) hf rw [thickening_closedBall h₁e (abs_nonneg R)] at h₂e obtain ⟨F, h₁F, h₂F⟩ := InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq h₂e have h₃F : DifferentiableOn ℂ F (closure (ball c |R|)) := by diff --git a/Mathlib/Analysis/Complex/Harmonic/Poisson.lean b/Mathlib/Analysis/Complex/Harmonic/Poisson.lean index 23f6f29bbb0d2f..a496e295af0e66 100644 --- a/Mathlib/Analysis/Complex/Harmonic/Poisson.lean +++ b/Mathlib/Analysis/Complex/Harmonic/Poisson.lean @@ -42,7 +42,7 @@ theorem HarmonicOnNhd.circleAverage_re_herglotzRieszKernel_smul (hf : HarmonicOnNhd f (closedBall c R)) (hw : w ∈ ball c R) : Real.circleAverage ((re ∘ herglotzRieszKernel c w) • f) c R = f w := by obtain ⟨e, h₁e, h₂e⟩ := (isCompact_closedBall c R).exists_thickening_subset_open - (isOpen_setOf_harmonicAt f) (by aesop) + (isOpen_setOfPred_harmonicAt f) (by aesop) rw [thickening_closedBall h₁e (pos_of_mem_ball hw).le] at h₂e obtain ⟨F, h₁F, h₂F⟩ := HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq h₂e have h₃F : DifferentiableOn ℂ F (closure (ball c R)) := by diff --git a/Mathlib/Analysis/Complex/OpenMapping.lean b/Mathlib/Analysis/Complex/OpenMapping.lean index 1b5b168f78ab24..fca5229a25ba7e 100644 --- a/Mathlib/Analysis/Complex/OpenMapping.lean +++ b/Mathlib/Analysis/Complex/OpenMapping.lean @@ -93,7 +93,7 @@ theorem AnalyticAt.eventually_constant_or_nhds_le_map_nhds_aux (hf : AnalyticAt have h2 : ∀ᶠ z in 𝓝 z₀, AnalyticAt ℂ f z := (isOpen_analyticAt ℂ f).eventually_mem hf obtain ⟨ρ, hρ, h3, h4⟩ : ∃ ρ > 0, AnalyticOnNhd ℂ f (closedBall z₀ ρ) ∧ ∀ z ∈ closedBall z₀ ρ, z ≠ z₀ → f z ≠ f z₀ := by - simpa only [setOf_and, subset_inter_iff] using! + simpa only [ofPred_and, subset_inter_iff] using! nhds_basis_closedBall.mem_iff.mp (h2.and (eventually_nhdsWithin_iff.mp h1)) replace h3 : DiffContOnCl ℂ f (ball z₀ ρ) := ⟨h3.differentiableOn.mono ball_subset_closedBall, diff --git a/Mathlib/Analysis/Complex/PhragmenLindelof.lean b/Mathlib/Analysis/Complex/PhragmenLindelof.lean index d5488434b0b8d1..29fd77cf37e4da 100644 --- a/Mathlib/Analysis/Complex/PhragmenLindelof.lean +++ b/Mathlib/Analysis/Complex/PhragmenLindelof.lean @@ -669,7 +669,7 @@ theorem right_half_plane_of_tendsto_zero_on_real (hd : DiffContOnCl ℂ f {z | 0 obtain ⟨x₀, hx₀, hmax⟩ : ∃ x : ℝ, 0 ≤ x ∧ ∀ y : ℝ, 0 ≤ y → ‖f y‖ ≤ ‖f x‖ := by have hfc : ContinuousOn (fun x : ℝ => f x) (Ici 0) := by refine hd.continuousOn.comp continuous_ofReal.continuousOn fun x hx => ?_ - rwa [closure_setOf_lt_re] + rwa [closure_setOfPred_lt_re] by_cases! h₀ : ∀ x : ℝ, 0 ≤ x → f x = 0 · refine ⟨0, le_rfl, fun y hy => ?_⟩; rw [h₀ y hy, h₀ 0 le_rfl] rcases h₀ with ⟨x₀, hx₀, hne⟩ @@ -693,7 +693,7 @@ theorem right_half_plane_of_tendsto_zero_on_real (hd : DiffContOnCl ℂ f {z | 0 -- move to a lemma? intro z hz rw [mem_ball, dist_zero_left, dist_eq, Complex.norm_of_nonneg hx₀] at hz - rw [mem_setOf_eq] + rw [mem_ofPred_eq] contrapose! hz calc x₀ ≤ x₀ - z.re := (le_sub_self_iff _).2 hz @@ -764,7 +764,7 @@ theorem eq_zero_on_right_half_plane_of_superexponential_decay (hd : DiffContOnCl rcases him with ⟨C, hC⟩ -- Due to continuity, it suffices to prove the equality on the open right half-plane. suffices ∀ z : ℂ, 0 < z.re → f z = 0 by - simpa only [closure_setOf_lt_re] using! + simpa only [closure_setOfPred_lt_re] using! EqOn.of_subset_closure this hd.continuousOn continuousOn_const subset_closure Subset.rfl -- Consider $g_n(z)=e^{nz}f(z)$. set g : ℕ → ℂ → E := fun (n : ℕ) (z : ℂ) => exp z ^ n • f z diff --git a/Mathlib/Analysis/Complex/ReImTopology.lean b/Mathlib/Analysis/Complex/ReImTopology.lean index 54a79042637da9..d7cb693dea1abd 100644 --- a/Mathlib/Analysis/Complex/ReImTopology.lean +++ b/Mathlib/Analysis/Complex/ReImTopology.lean @@ -24,8 +24,8 @@ Each statement about `Complex.re` listed below has a counterpart about `Complex. and is a quotient map; * `Complex.interior_preimage_re`, `Complex.closure_preimage_re`, `Complex.frontier_preimage_re`: formulas for `interior (Complex.re ⁻¹' s)` etc; -* `Complex.interior_setOf_re_le` etc: particular cases of the above formulas in the cases when `s` - is one of the infinite intervals `Set.Ioi a`, `Set.Ici a`, `Set.Iio a`, and `Set.Iic a`, +* `Complex.interior_setOfPred_re_le` etc: particular cases of the above formulas in the cases + when `s` is one of the infinite intervals `Set.Ioi a`, `Set.Ici a`, `Set.Iio a`, and `Set.Iic a`, formulated as `interior {z : ℂ | z.re ≤ a} = {z | z.re < a}` etc. ## Tags @@ -80,69 +80,115 @@ theorem frontier_preimage_im (s : Set ℝ) : frontier (im ⁻¹' s) = im ⁻¹' (isOpenMap_im.preimage_frontier_eq_frontier_preimage continuous_im _).symm @[simp] -theorem interior_setOf_re_le (a : ℝ) : interior { z : ℂ | z.re ≤ a } = { z | z.re < a } := by +theorem interior_setOfPred_re_le (a : ℝ) : interior { z : ℂ | z.re ≤ a } = { z | z.re < a } := by simpa only [interior_Iic] using! interior_preimage_re (Iic a) +@[deprecated (since := "2026-07-09")] +alias interior_setOf_re_le := interior_setOfPred_re_le + @[simp] -theorem interior_setOf_im_le (a : ℝ) : interior { z : ℂ | z.im ≤ a } = { z | z.im < a } := by +theorem interior_setOfPred_im_le (a : ℝ) : interior { z : ℂ | z.im ≤ a } = { z | z.im < a } := by simpa only [interior_Iic] using! interior_preimage_im (Iic a) +@[deprecated (since := "2026-07-09")] +alias interior_setOf_im_le := interior_setOfPred_im_le + @[simp] -theorem interior_setOf_le_re (a : ℝ) : interior { z : ℂ | a ≤ z.re } = { z | a < z.re } := by +theorem interior_setOfPred_le_re (a : ℝ) : interior { z : ℂ | a ≤ z.re } = { z | a < z.re } := by simpa only [interior_Ici] using! interior_preimage_re (Ici a) +@[deprecated (since := "2026-07-09")] +alias interior_setOf_le_re := interior_setOfPred_le_re + @[simp] -theorem interior_setOf_le_im (a : ℝ) : interior { z : ℂ | a ≤ z.im } = { z | a < z.im } := by +theorem interior_setOfPred_le_im (a : ℝ) : interior { z : ℂ | a ≤ z.im } = { z | a < z.im } := by simpa only [interior_Ici] using! interior_preimage_im (Ici a) +@[deprecated (since := "2026-07-09")] +alias interior_setOf_le_im := interior_setOfPred_le_im + @[simp] -theorem closure_setOf_re_lt (a : ℝ) : closure { z : ℂ | z.re < a } = { z | z.re ≤ a } := by +theorem closure_setOfPred_re_lt (a : ℝ) : closure { z : ℂ | z.re < a } = { z | z.re ≤ a } := by simpa only [closure_Iio] using! closure_preimage_re (Iio a) +@[deprecated (since := "2026-07-09")] +alias closure_setOf_re_lt := closure_setOfPred_re_lt + @[simp] -theorem closure_setOf_im_lt (a : ℝ) : closure { z : ℂ | z.im < a } = { z | z.im ≤ a } := by +theorem closure_setOfPred_im_lt (a : ℝ) : closure { z : ℂ | z.im < a } = { z | z.im ≤ a } := by simpa only [closure_Iio] using! closure_preimage_im (Iio a) +@[deprecated (since := "2026-07-09")] alias closure_setOf_im_lt := closure_setOfPred_im_lt + @[simp] -theorem closure_setOf_lt_re (a : ℝ) : closure { z : ℂ | a < z.re } = { z | a ≤ z.re } := by +theorem closure_setOfPred_lt_re (a : ℝ) : closure { z : ℂ | a < z.re } = { z | a ≤ z.re } := by simpa only [closure_Ioi] using! closure_preimage_re (Ioi a) +@[deprecated (since := "2026-07-09")] +alias closure_setOf_lt_re := closure_setOfPred_lt_re + @[simp] -theorem closure_setOf_lt_im (a : ℝ) : closure { z : ℂ | a < z.im } = { z | a ≤ z.im } := by +theorem closure_setOfPred_lt_im (a : ℝ) : closure { z : ℂ | a < z.im } = { z | a ≤ z.im } := by simpa only [closure_Ioi] using! closure_preimage_im (Ioi a) +@[deprecated (since := "2026-07-09")] alias closure_setOf_lt_im := closure_setOfPred_lt_im + @[simp] -theorem frontier_setOf_re_le (a : ℝ) : frontier { z : ℂ | z.re ≤ a } = { z | z.re = a } := by +theorem frontier_setOfPred_re_le (a : ℝ) : frontier { z : ℂ | z.re ≤ a } = { z | z.re = a } := by simpa only [frontier_Iic] using! frontier_preimage_re (Iic a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_re_le := frontier_setOfPred_re_le + @[simp] -theorem frontier_setOf_im_le (a : ℝ) : frontier { z : ℂ | z.im ≤ a } = { z | z.im = a } := by +theorem frontier_setOfPred_im_le (a : ℝ) : frontier { z : ℂ | z.im ≤ a } = { z | z.im = a } := by simpa only [frontier_Iic] using! frontier_preimage_im (Iic a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_im_le := frontier_setOfPred_im_le + @[simp] -theorem frontier_setOf_le_re (a : ℝ) : frontier { z : ℂ | a ≤ z.re } = { z | z.re = a } := by +theorem frontier_setOfPred_le_re (a : ℝ) : frontier { z : ℂ | a ≤ z.re } = { z | z.re = a } := by simpa only [frontier_Ici] using! frontier_preimage_re (Ici a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_le_re := frontier_setOfPred_le_re + @[simp] -theorem frontier_setOf_le_im (a : ℝ) : frontier { z : ℂ | a ≤ z.im } = { z | z.im = a } := by +theorem frontier_setOfPred_le_im (a : ℝ) : frontier { z : ℂ | a ≤ z.im } = { z | z.im = a } := by simpa only [frontier_Ici] using! frontier_preimage_im (Ici a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_le_im := frontier_setOfPred_le_im + @[simp] -theorem frontier_setOf_re_lt (a : ℝ) : frontier { z : ℂ | z.re < a } = { z | z.re = a } := by +theorem frontier_setOfPred_re_lt (a : ℝ) : frontier { z : ℂ | z.re < a } = { z | z.re = a } := by simpa only [frontier_Iio] using! frontier_preimage_re (Iio a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_re_lt := frontier_setOfPred_re_lt + @[simp] -theorem frontier_setOf_im_lt (a : ℝ) : frontier { z : ℂ | z.im < a } = { z | z.im = a } := by +theorem frontier_setOfPred_im_lt (a : ℝ) : frontier { z : ℂ | z.im < a } = { z | z.im = a } := by simpa only [frontier_Iio] using! frontier_preimage_im (Iio a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_im_lt := frontier_setOfPred_im_lt + @[simp] -theorem frontier_setOf_lt_re (a : ℝ) : frontier { z : ℂ | a < z.re } = { z | z.re = a } := by +theorem frontier_setOfPred_lt_re (a : ℝ) : frontier { z : ℂ | a < z.re } = { z | z.re = a } := by simpa only [frontier_Ioi] using! frontier_preimage_re (Ioi a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_lt_re := frontier_setOfPred_lt_re + @[simp] -theorem frontier_setOf_lt_im (a : ℝ) : frontier { z : ℂ | a < z.im } = { z | z.im = a } := by +theorem frontier_setOfPred_lt_im (a : ℝ) : frontier { z : ℂ | a < z.im } = { z | z.im = a } := by simpa only [frontier_Ioi] using! frontier_preimage_im (Ioi a) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_lt_im := frontier_setOfPred_lt_im + theorem closure_reProdIm (s t : Set ℝ) : closure (s ×ℂ t) = closure s ×ℂ closure t := by simpa only [← preimage_eq_preimage equivRealProdCLM.symm.toHomeomorph.surjective, equivRealProdCLM.symm.toHomeomorph.preimage_closure] using! @closure_prod_eq _ _ _ _ s t @@ -155,15 +201,21 @@ theorem frontier_reProdIm (s t : Set ℝ) : simpa only [← preimage_eq_preimage equivRealProdCLM.symm.toHomeomorph.surjective, equivRealProdCLM.symm.toHomeomorph.preimage_frontier] using! frontier_prod_eq s t -theorem frontier_setOf_le_re_and_le_im (a b : ℝ) : +theorem frontier_setOfPred_le_re_and_le_im (a b : ℝ) : frontier { z | a ≤ re z ∧ b ≤ im z } = { z | a ≤ re z ∧ im z = b ∨ re z = a ∧ b ≤ im z } := by simpa only [closure_Ici, frontier_Ici] using! frontier_reProdIm (Ici a) (Ici b) -theorem frontier_setOf_le_re_and_im_le (a b : ℝ) : +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_le_re_and_le_im := frontier_setOfPred_le_re_and_le_im + +theorem frontier_setOfPred_le_re_and_im_le (a b : ℝ) : frontier { z | a ≤ re z ∧ im z ≤ b } = { z | a ≤ re z ∧ im z = b ∨ re z = a ∧ im z ≤ b } := by simpa only [closure_Ici, closure_Iic, frontier_Ici, frontier_Iic] using! frontier_reProdIm (Ici a) (Iic b) +@[deprecated (since := "2026-07-09")] +alias frontier_setOf_le_re_and_im_le := frontier_setOfPred_le_re_and_im_le + end Complex open Complex Metric diff --git a/Mathlib/Analysis/Convex/Basic.lean b/Mathlib/Analysis/Convex/Basic.lean index 17234e3fd906d0..1ae23510c91bb6 100644 --- a/Mathlib/Analysis/Convex/Basic.lean +++ b/Mathlib/Analysis/Convex/Basic.lean @@ -122,9 +122,11 @@ theorem DirectedOn.convex_sUnion {c : Set (Set E)} (hdir : DirectedOn (· ⊆ · rw [sUnion_eq_iUnion] exact (directedOn_iff_directed.1 hdir).convex_iUnion fun A => hc A.2 -theorem Convex.setOf_const_imp {P : Prop} (hs : Convex 𝕜 s) : Convex 𝕜 {x | P → x ∈ s} := by +theorem Convex.setOfPred_const_imp {P : Prop} (hs : Convex 𝕜 s) : Convex 𝕜 {x | P → x ∈ s} := by by_cases hP : P <;> simp [hP, hs, convex_univ] +@[deprecated (since := "2026-07-09")] alias Convex.setOf_const_imp := Convex.setOfPred_const_imp + end SMul section Module diff --git a/Mathlib/Analysis/Convex/Caratheodory.lean b/Mathlib/Analysis/Convex/Caratheodory.lean index d46b491697673e..ed18655cbfd064 100644 --- a/Mathlib/Analysis/Convex/Caratheodory.lean +++ b/Mathlib/Analysis/Convex/Caratheodory.lean @@ -55,7 +55,7 @@ then it is in the convex hull of a strict subset of `t`. -/ theorem mem_convexHull_erase [DecidableEq E] {t : Finset E} (h : ¬AffineIndependent 𝕜 ((↑) : t → E)) {x : E} (m : x ∈ convexHull 𝕜 (↑t : Set E)) : ∃ y : (↑t : Set E), x ∈ convexHull 𝕜 (↑(t.erase y) : Set E) := by - simp only [Finset.convexHull_eq, mem_setOf_eq] at m ⊢ + simp only [Finset.convexHull_eq, mem_ofPred_eq] at m ⊢ obtain ⟨f, fpos, fsum, rfl⟩ := m obtain ⟨g, gcombo, gsum, gpos⟩ := exists_nontrivial_relation_sum_zero_of_not_affine_ind h replace gpos := exists_pos_of_sum_zero_of_exists_nonzero g gsum gpos @@ -166,7 +166,7 @@ theorem eq_pos_convex_span_of_mem_convexHull {x : E} (hx : x ∈ convexHull 𝕜 rw [convexHull_eq_union] at hx simp only [exists_prop, Set.mem_iUnion] at hx obtain ⟨t, ht₁, ht₂, ht₃⟩ := hx - simp only [t.convexHull_eq, Set.mem_setOf_eq] at ht₃ + simp only [t.convexHull_eq, Set.mem_ofPred_eq] at ht₃ obtain ⟨w, hw₁, hw₂, hw₃⟩ := ht₃ let t' := {i ∈ t | w i ≠ 0} refine ⟨t', t'.fintypeCoeSort, ((↑) : t' → E), w ∘ ((↑) : t' → E), ?_, ?_, ?_, ?_, ?_⟩ diff --git a/Mathlib/Analysis/Convex/Combination.lean b/Mathlib/Analysis/Convex/Combination.lean index ce97f12f200196..8165b2b1fc2723 100644 --- a/Mathlib/Analysis/Convex/Combination.lean +++ b/Mathlib/Analysis/Convex/Combination.lean @@ -379,7 +379,7 @@ lemma mem_convexHull_iff_exists_fintype {s : Set E} {x : E} : x ∈ convexHull R s ↔ ∃ (ι : Type) (_ : Fintype ι) (w : ι → R) (z : ι → E), (∀ i, 0 ≤ w i) ∧ ∑ i, w i = 1 ∧ (∀ i, z i ∈ s) ∧ ∑ i, w i • z i = x := by constructor - · simp only [convexHull_eq, mem_setOf_eq] + · simp only [convexHull_eq, mem_ofPred_eq] rintro ⟨ι, t, w, z, h⟩ refine ⟨t, inferInstance, w ∘ (↑), z ∘ (↑), ?_⟩ simpa [← sum_attach t, centerMass_eq_of_sum_1 _ _ h.2.1] using h @@ -409,7 +409,7 @@ theorem Finset.convexHull_eq (s : Finset E) : convexHull R ↑s = theorem Finset.mem_convexHull {s : Finset E} {x : E} : x ∈ convexHull R (s : Set E) ↔ ∃ w : E → R, (∀ y ∈ s, 0 ≤ w y) ∧ ∑ y ∈ s, w y = 1 ∧ s.centerMass w id = x := by - rw [Finset.convexHull_eq, Set.mem_setOf_eq] + rw [Finset.convexHull_eq, Set.mem_ofPred_eq] /-- This is a version of `Finset.mem_convexHull` stated without `Finset.centerMass`. -/ lemma Finset.mem_convexHull' {s : Finset E} {x : E} : @@ -617,7 +617,7 @@ namespace Affine.Simplex [IsOrderedRing 𝕜] [AddCommGroup V] [Module 𝕜 V] {n : ℕ} (s : Simplex 𝕜 V n) : convexHull 𝕜 (Set.range s.points) = s.closedInterior := by ext p - rw [convexHull_range_eq_exists_affineCombination, Set.mem_setOf] + rw [convexHull_range_eq_exists_affineCombination, Set.mem_ofPred] constructor <;> intro h · obtain ⟨u, w, hw, hw1, rfl⟩ := h have hw' : ∀ i ∈ u, w i ≤ 1 := by diff --git a/Mathlib/Analysis/Convex/Continuous.lean b/Mathlib/Analysis/Convex/Continuous.lean index 43d9e1edf74da6..b43a4a75640fa7 100644 --- a/Mathlib/Analysis/Convex/Continuous.lean +++ b/Mathlib/Analysis/Convex/Continuous.lean @@ -152,7 +152,7 @@ lemma ConvexOn.continuousOn_tfae (hC : IsOpen C) (hC' : C.Nonempty) (hf : Convex | h, x, hx => by obtain ⟨r, hr⟩ := h hx obtain ⟨ε, hε, hεD⟩ := Metric.mem_nhds_iff.1 <| Filter.inter_mem (hC.mem_nhds hx) hr - simp only [preimage_setOf_eq, Pi.abs_apply, subset_inter_iff, hC.nhdsWithin_eq hx] at hεD ⊢ + simp only [preimage_ofPred_eq, Pi.abs_apply, subset_inter_iff, hC.nhdsWithin_eq hx] at hεD ⊢ obtain ⟨K, hK⟩ := exists_lipschitzOnWith_of_isBounded (hf.subset hεD.1 (convex_ball ..)) (half_lt_self hε) <| isBounded_iff_forall_norm_le.2 ⟨r, by simpa using! hεD.2⟩ exact ⟨K, _, ball_mem_nhds _ (by simpa), hK⟩ diff --git a/Mathlib/Analysis/Convex/Deriv.lean b/Mathlib/Analysis/Convex/Deriv.lean index 0e4fae608c2e01..2b1ccf5be34b2b 100644 --- a/Mathlib/Analysis/Convex/Deriv.lean +++ b/Mathlib/Analysis/Convex/Deriv.lean @@ -492,7 +492,7 @@ lemma monotoneOn_rightDeriv (hfc : ConvexOn ℝ S f) : simp_rw [hfc.rightDeriv_eq_sInf_slope_of_mem_interior hxs, hfc.rightDeriv_eq_sInf_slope_of_mem_interior hys] refine csInf_le_of_le (b := slope f x y) (bddBelow_slope_lt_of_mem_interior hfc hxs) - ⟨y, by simp only [mem_setOf_eq, hxy, and_true]; exact interior_subset hys⟩ + ⟨y, by simp only [mem_ofPred_eq, hxy, and_true]; exact interior_subset hys⟩ (le_csInf ?_ ?_) · have hys' := hys rw [mem_interior_iff_mem_nhds, mem_nhds_iff_exists_Ioo_subset] at hys' @@ -512,7 +512,7 @@ lemma monotoneOn_leftDeriv (hfc : ConvexOn ℝ S f) : simp_rw [hfc.leftDeriv_eq_sSup_slope_of_mem_interior hxs, hfc.leftDeriv_eq_sSup_slope_of_mem_interior hys] refine le_csSup_of_le (b := slope f x y) (bddAbove_slope_gt_of_mem_interior hfc hys) - ⟨x, by simp only [slope_comm, mem_setOf_eq, hxy, and_true]; exact interior_subset hxs⟩ + ⟨x, by simp only [slope_comm, mem_ofPred_eq, hxy, and_true]; exact interior_subset hxs⟩ (csSup_le ?_ ?_) · have hxs' := hxs rw [mem_interior_iff_mem_nhds, mem_nhds_iff_exists_Ioo_subset] at hxs' diff --git a/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean b/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean index 7cc0c9435e4b17..3e493475626fd0 100644 --- a/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean +++ b/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean @@ -65,7 +65,7 @@ lemma doublyStochastic_eq_rowStochastic_inf_colStochastic : doublyStochastic R n = rowStochastic R n ⊓ colStochastic R n := by ext M simp only [rowStochastic, colStochastic, Submonoid.mem_inf, Submonoid.mem_mk, Subsemigroup.mem_mk, - Set.mem_setOf_eq, doublyStochastic] + Set.mem_ofPred_eq, doublyStochastic] grind lemma mem_doublyStochastic_iff_mem_rowStochastic_and_mem_colStochastic {M : Matrix n n R} : diff --git a/Mathlib/Analysis/Convex/Extrema.lean b/Mathlib/Analysis/Convex/Extrema.lean index 4aa46bf303147e..31e5ca00d98b51 100644 --- a/Mathlib/Analysis/Convex/Extrema.lean +++ b/Mathlib/Analysis/Convex/Extrema.lean @@ -32,7 +32,7 @@ theorem IsMinOn.of_isLocalMinOn_of_convexOn_Icc {f : ℝ → β} {a b : ℝ} (a_ (h_local_min : IsLocalMinOn f (Icc a b) a) (h_conv : ConvexOn ℝ (Icc a b) f) : IsMinOn f (Icc a b) a := by rintro c hc - dsimp only [mem_setOf_eq] + dsimp only [mem_ofPred_eq] rw [IsLocalMinOn, nhdsWithin_Icc_eq_nhdsGE a_lt_b] at h_local_min rcases hc.1.eq_or_lt with (rfl | a_lt_c) · exact le_rfl @@ -66,7 +66,7 @@ theorem IsMinOn.of_isLocalMinOn_of_convexOn {f : E → β} {a : E} (a_in_s : a have fg_min_on : IsMinOn (f ∘ g) (Icc 0 1 : Set ℝ) 0 := by refine IsMinOn.of_isLocalMinOn_of_convexOn_Icc one_pos fg_local_min_on ?_ exact (h_conv.comp_affineMap g).subset h_maps (convex_Icc 0 1) - simpa only [hg0, hg1, comp_apply, mem_setOf_eq] using fg_min_on (right_mem_Icc.2 zero_le_one) + simpa only [hg0, hg1, comp_apply, mem_ofPred_eq] using fg_min_on (right_mem_Icc.2 zero_le_one) /-- A local maximum of a concave function is a global maximum, restricted to a set `s`. -/ theorem IsMaxOn.of_isLocalMaxOn_of_concaveOn {f : E → β} {a : E} (a_in_s : a ∈ s) diff --git a/Mathlib/Analysis/Convex/FunctionTopology.lean b/Mathlib/Analysis/Convex/FunctionTopology.lean index 5889e70105e828..1f8fedb8179372 100644 --- a/Mathlib/Analysis/Convex/FunctionTopology.lean +++ b/Mathlib/Analysis/Convex/FunctionTopology.lean @@ -14,8 +14,8 @@ import Mathlib.Topology.Algebra.Monoid We prove the following facts: -* `isClosed_setOf_convexOn` : the set of convex functions on a set is closed -* `isClosed_setOf_concaveOn` : the set of concave functions on a set is closed +* `isClosed_setOfPred_convexOn` : the set of convex functions on a set is closed +* `isClosed_setOfPred_concaveOn` : the set of concave functions on a set is closed -/ open scoped Topology @@ -28,16 +28,22 @@ variable {𝕜 α β : Type*} [Semiring 𝕜] [PartialOrder 𝕜] [PartialOrder [ContinuousConstSMul 𝕜 β] [ContinuousAdd β] /-- The set of convex functions on a set `s` is closed. -/ -public theorem isClosed_setOf_convexOn {s : Set α} : +public theorem isClosed_setOfPred_convexOn {s : Set α} : IsClosed {f : α → β | ConvexOn 𝕜 s f} := by - simp only [ConvexOn, setOf_and, setOf_forall] + simp only [ConvexOn, ofPred_and, ofPred_forall] refine IsClosed.inter isClosed_const ?_ exact isClosed_iInter fun x => isClosed_iInter fun hx => isClosed_iInter fun y => isClosed_iInter fun hy => isClosed_iInter fun a => isClosed_iInter fun b => isClosed_iInter fun ha => isClosed_iInter fun hb => isClosed_iInter fun hab => isClosed_le (by fun_prop) (by fun_prop) +@[deprecated (since := "2026-07-09")] +public alias isClosed_setOf_convexOn := isClosed_setOfPred_convexOn + /-- The set of concave functions on a set `s` is closed. -/ -public theorem isClosed_setOf_concaveOn {s : Set α} : +public theorem isClosed_setOfPred_concaveOn {s : Set α} : IsClosed {f : α → β | ConcaveOn 𝕜 s f} := - isClosed_setOf_convexOn (α := α) (β := βᵒᵈ) + isClosed_setOfPred_convexOn (α := α) (β := βᵒᵈ) + +@[deprecated (since := "2026-07-09")] +public alias isClosed_setOf_concaveOn := isClosed_setOfPred_concaveOn diff --git a/Mathlib/Analysis/Convex/Gauge.lean b/Mathlib/Analysis/Convex/Gauge.lean index f9f9a4716a3155..021e5a3adee0a0 100644 --- a/Mathlib/Analysis/Convex/Gauge.lean +++ b/Mathlib/Analysis/Convex/Gauge.lean @@ -133,10 +133,10 @@ theorem gauge_le_of_mem (ha : 0 ≤ a) (hx : x ∈ a • s) : gauge s x ≤ a := · rw [mem_singleton_iff.1 (zero_smul_set_subset _ hx), gauge_zero] · exact csInf_le bddBelow_gauge_set ⟨ha', hx⟩ -theorem setOf_gauge_le_eq (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : Absorbent ℝ s) +theorem setOfPred_gauge_le_eq (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : Absorbent ℝ s) (ha : 0 ≤ a) : { x | gauge s x ≤ a } = ⋂ (r : ℝ) (_ : a < r), r • s := by ext x - simp_rw [Set.mem_iInter, Set.mem_setOf_eq] + simp_rw [Set.mem_iInter, Set.mem_ofPred_eq] refine ⟨fun h r hr => ?_, fun h => le_of_forall_pos_lt_add fun ε hε => ?_⟩ · have hr' := ha.trans_lt hr rw [mem_smul_set_iff_inv_smul_mem₀ hr'.ne'] @@ -148,27 +148,36 @@ theorem setOf_gauge_le_eq (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ exact hδr.le · linarith [gauge_le_of_mem (by linarith) <| h (a + ε / 2) (by linarith)] -@[deprecated (since := "2026-06-17")] alias gauge_le_eq := setOf_gauge_le_eq +@[deprecated (since := "2026-07-09")] +alias setOf_gauge_le_eq := setOfPred_gauge_le_eq -theorem setOf_gauge_lt_eq' (absorbs : Absorbent ℝ s) (a : ℝ) : +@[deprecated (since := "2026-06-17")] alias gauge_le_eq := setOfPred_gauge_le_eq + +theorem setOfPred_gauge_lt_eq' (absorbs : Absorbent ℝ s) (a : ℝ) : { x | gauge s x < a } = ⋃ (r : ℝ) (_ : 0 < r) (_ : r < a), r • s := by ext - simp_rw [mem_setOf, mem_iUnion, exists_prop] + simp_rw [mem_ofPred, mem_iUnion, exists_prop] exact ⟨exists_lt_of_gauge_lt absorbs, fun ⟨r, hr₀, hr₁, hx⟩ => (gauge_le_of_mem hr₀.le hx).trans_lt hr₁⟩ -@[deprecated (since := "2026-06-17")] alias gauge_lt_eq' := setOf_gauge_lt_eq' +@[deprecated (since := "2026-07-09")] +alias setOf_gauge_lt_eq' := setOfPred_gauge_lt_eq' + +@[deprecated (since := "2026-06-17")] alias gauge_lt_eq' := setOfPred_gauge_lt_eq' -theorem setOf_gauge_lt_eq (absorbs : Absorbent ℝ s) (a : ℝ) : +theorem setOfPred_gauge_lt_eq (absorbs : Absorbent ℝ s) (a : ℝ) : { x | gauge s x < a } = ⋃ r ∈ Set.Ioo 0 (a : ℝ), r • s := by ext - simp_rw [mem_setOf, mem_iUnion, exists_prop, mem_Ioo, and_assoc] + simp_rw [mem_ofPred, mem_iUnion, exists_prop, mem_Ioo, and_assoc] exact ⟨exists_lt_of_gauge_lt absorbs, fun ⟨r, hr₀, hr₁, hx⟩ => (gauge_le_of_mem hr₀.le hx).trans_lt hr₁⟩ -@[deprecated (since := "2026-06-17")] alias gauge_lt_eq := setOf_gauge_lt_eq +@[deprecated (since := "2026-07-09")] +alias setOf_gauge_lt_eq := setOfPred_gauge_lt_eq + +@[deprecated (since := "2026-06-17")] alias gauge_lt_eq := setOfPred_gauge_lt_eq theorem mem_openSegment_of_gauge_lt_one (absorbs : Absorbent ℝ s) (hgauge : gauge s x < 1) : ∃ y ∈ s, x ∈ openSegment ℝ 0 y := by @@ -176,13 +185,16 @@ theorem mem_openSegment_of_gauge_lt_one (absorbs : Absorbent ℝ s) (hgauge : ga refine ⟨y, hy, 1 - r, r, ?_⟩ simp [*] -theorem setOf_gauge_lt_one_subset_self (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) +theorem setOfPred_gauge_lt_one_subset_self (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Absorbent ℝ s) : { x | gauge s x < 1 } ⊆ s := fun _x hx ↦ let ⟨_y, hys, hx⟩ := mem_openSegment_of_gauge_lt_one absorbs hx hs.openSegment_subset h₀ hys hx +@[deprecated (since := "2026-07-09")] +alias setOf_gauge_lt_one_subset_self := setOfPred_gauge_lt_one_subset_self + @[deprecated (since := "2026-06-17")] -alias gauge_lt_one_subset_self := setOf_gauge_lt_one_subset_self +alias gauge_lt_one_subset_self := setOfPred_gauge_lt_one_subset_self theorem gauge_le_one_of_mem {x : E} (hx : x ∈ s) : gauge s x ≤ 1 := gauge_le_of_mem zero_le_one <| by rwa [one_smul] @@ -205,20 +217,27 @@ theorem gauge_sum_le {ι : Type*} (hs : Convex ℝ s) (absorbs : Absorbent ℝ s (f : ι → E) : gauge s (∑ i ∈ t, f i) ≤ ∑ i ∈ t, gauge s (f i) := Finset.le_sum_of_subadditive _ gauge_zero.le (gauge_add_le hs absorbs) _ _ -theorem self_subset_setOf_gauge_le_one : s ⊆ { x | gauge s x ≤ 1 } := fun _ => gauge_le_one_of_mem +theorem self_subset_setOfPred_gauge_le_one : s ⊆ { x | gauge s x ≤ 1 } := + fun _ => gauge_le_one_of_mem + +@[deprecated (since := "2026-07-09")] +alias self_subset_setOf_gauge_le_one := self_subset_setOfPred_gauge_le_one @[deprecated (since := "2026-06-17")] -alias self_subset_gauge_le_one := self_subset_setOf_gauge_le_one +alias self_subset_gauge_le_one := self_subset_setOfPred_gauge_le_one -theorem Convex.setOf_gauge_le (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Absorbent ℝ s) +theorem Convex.setOfPred_gauge_le (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Absorbent ℝ s) (a : ℝ) : Convex ℝ { x | gauge s x ≤ a } := by by_cases ha : 0 ≤ a - · rw [setOf_gauge_le_eq hs h₀ absorbs ha] + · rw [setOfPred_gauge_le_eq hs h₀ absorbs ha] exact convex_iInter fun i => convex_iInter fun _ => hs.smul _ · convert! convex_empty (𝕜 := ℝ) exact eq_empty_iff_forall_notMem.2 fun x hx => ha <| (gauge_nonneg _).trans hx -@[deprecated (since := "2026-06-17")] alias Convex.gauge_le := Convex.setOf_gauge_le +@[deprecated (since := "2026-07-09")] +alias Convex.setOf_gauge_le := Convex.setOfPred_gauge_le + +@[deprecated (since := "2026-06-17")] alias Convex.gauge_le := Convex.setOfPred_gauge_le theorem le_gauge_of_notMem (hs₀ : StarConvex ℝ 0 s) (hs₂ : Absorbs ℝ s {x}) (hx : x ∉ a • s) : a ≤ gauge s x := by @@ -367,15 +386,18 @@ theorem interior_subset_gauge_lt_one (s : Set E) : interior s ⊆ { x | gauge s rcases H₂.exists with ⟨r, hxr, hr₀, hr₁⟩ exact (gauge_le_of_mem hr₀.le hxr).trans_lt hr₁ -theorem setOf_gauge_lt_one_eq_self_of_isOpen (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) +theorem setOfPred_gauge_lt_one_eq_self_of_isOpen (hs₁ : Convex ℝ s) (hs₀ : (0 : E) ∈ s) (hs₂ : IsOpen s) : { x | gauge s x < 1 } = s := by - refine (setOf_gauge_lt_one_subset_self hs₁ ‹_› <| absorbent_nhds_zero <| + refine (setOfPred_gauge_lt_one_subset_self hs₁ ‹_› <| absorbent_nhds_zero <| hs₂.mem_nhds hs₀).antisymm ?_ convert! interior_subset_gauge_lt_one s exact hs₂.interior_eq.symm +@[deprecated (since := "2026-07-09")] +alias setOf_gauge_lt_one_eq_self_of_isOpen := setOfPred_gauge_lt_one_eq_self_of_isOpen + @[deprecated (since := "2026-06-17")] -alias gauge_lt_one_eq_self_of_isOpen := setOf_gauge_lt_one_eq_self_of_isOpen +alias gauge_lt_one_eq_self_of_isOpen := setOfPred_gauge_lt_one_eq_self_of_isOpen theorem gauge_lt_one_of_mem_of_isOpen (hs₂ : IsOpen s) {x : E} (hx : x ∈ s) : gauge s x < 1 := @@ -392,8 +414,8 @@ theorem mem_closure_of_gauge_le_one (hc : Convex ℝ s) (hs₀ : 0 ∈ s) (ha : (h : gauge s x ≤ 1) : x ∈ closure s := by have : ∀ᶠ r : ℝ in 𝓝[<] 1, r • x ∈ s := by filter_upwards [Ico_mem_nhdsLT one_pos] with r ⟨hr₀, hr₁⟩ - apply setOf_gauge_lt_one_subset_self hc hs₀ ha - rw [mem_setOf_eq, gauge_smul_of_nonneg hr₀] + apply setOfPred_gauge_lt_one_subset_self hc hs₀ ha + rw [mem_ofPred_eq, gauge_smul_of_nonneg hr₀] exact mul_lt_one_of_nonneg_of_lt_one_left hr₀ hr₁ h refine mem_closure_of_tendsto ?_ this exact Filter.Tendsto.mono_left (Continuous.tendsto' (by fun_prop) _ _ (one_smul _ _)) @@ -460,18 +482,21 @@ is continuous. If the ambient space is a normed space, then `gauge s` is Lipschi theorem continuous_gauge (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : Continuous (gauge s) := continuous_iff_continuousAt.2 fun _ ↦ continuousAt_gauge hc hs₀ -theorem setOf_gauge_lt_one_eq_interior (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : +theorem setOfPred_gauge_lt_one_eq_interior (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : { x | gauge s x < 1 } = interior s := by refine Subset.antisymm (fun x hx ↦ ?_) (interior_subset_gauge_lt_one s) rcases mem_openSegment_of_gauge_lt_one (absorbent_nhds_zero hs₀) hx with ⟨y, hys, hxy⟩ exact hc.openSegment_interior_self_subset_interior (mem_interior_iff_mem_nhds.2 hs₀) hys hxy +@[deprecated (since := "2026-07-09")] +alias setOf_gauge_lt_one_eq_interior := setOfPred_gauge_lt_one_eq_interior + @[deprecated (since := "2026-06-17")] -alias gauge_lt_one_eq_interior := setOf_gauge_lt_one_eq_interior +alias gauge_lt_one_eq_interior := setOfPred_gauge_lt_one_eq_interior theorem gauge_lt_one_iff_mem_interior (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : gauge s x < 1 ↔ x ∈ interior s := - Set.ext_iff.1 (setOf_gauge_lt_one_eq_interior hc hs₀) _ + Set.ext_iff.1 (setOfPred_gauge_lt_one_eq_interior hc hs₀) _ theorem gauge_le_one_iff_mem_closure (hc : Convex ℝ s) (hs₀ : s ∈ 𝓝 0) : gauge s x ≤ 1 ↔ x ∈ closure s := @@ -504,7 +529,7 @@ theorem gaugeSeminorm_lt_one_of_isOpen (hs : IsOpen s) {x : E} (hx : x ∈ s) : theorem gaugeSeminorm_ball_one (hs : IsOpen s) : (gaugeSeminorm hs₀ hs₁ hs₂).ball 0 1 = s := by rw [Seminorm.ball_zero_eq] - exact setOf_gauge_lt_one_eq_self_of_isOpen hs₁ hs₂.zero_mem hs + exact setOfPred_gauge_lt_one_eq_self_of_isOpen hs₁ hs₂.zero_mem hs end RCLike diff --git a/Mathlib/Analysis/Convex/Integral.lean b/Mathlib/Analysis/Convex/Integral.lean index fbb93244a6bb2d..be148750016be0 100644 --- a/Mathlib/Analysis/Convex/Integral.lean +++ b/Mathlib/Analysis/Convex/Integral.lean @@ -119,7 +119,7 @@ theorem ConcaveOn.average_mem_hypograph [IsFiniteMeasure μ] [NeZero μ] (hg : C (hgc : ContinuousOn g s) (hsc : IsClosed s) (hfs : ∀ᵐ x ∂μ, f x ∈ s) (hfi : Integrable f μ) (hgi : Integrable (g ∘ f) μ) : (⨍ x, f x ∂μ, ⨍ x, g (f x) ∂μ) ∈ {p : E × ℝ | p.1 ∈ s ∧ p.2 ≤ g p.1} := by - simpa only [mem_setOf_eq, Pi.neg_apply, average_neg, neg_le_neg_iff] using + simpa only [mem_ofPred_eq, Pi.neg_apply, average_neg, neg_le_neg_iff] using hg.neg.average_mem_epigraph hgc.neg hsc hfs hfi hgi.neg /-- **Jensen's inequality**: if a function `g : E → ℝ` is convex and continuous on a convex closed @@ -166,7 +166,7 @@ theorem ConcaveOn.set_average_mem_hypograph (hg : ConcaveOn ℝ s g) (hgc : Cont (hsc : IsClosed s) (h0 : μ t ≠ 0) (ht : μ t ≠ ∞) (hfs : ∀ᵐ x ∂μ.restrict t, f x ∈ s) (hfi : IntegrableOn f t μ) (hgi : IntegrableOn (g ∘ f) t μ) : (⨍ x in t, f x ∂μ, ⨍ x in t, g (f x) ∂μ) ∈ {p : E × ℝ | p.1 ∈ s ∧ p.2 ≤ g p.1} := by - simpa only [mem_setOf_eq, Pi.neg_apply, average_neg, neg_le_neg_iff] using + simpa only [mem_ofPred_eq, Pi.neg_apply, average_neg, neg_le_neg_iff] using hg.neg.set_average_mem_epigraph hgc.neg hsc h0 ht hfs hfi hgi.neg /-- **Jensen's inequality**: if a function `g : E → ℝ` is convex and continuous on a convex closed diff --git a/Mathlib/Analysis/Convex/Intrinsic.lean b/Mathlib/Analysis/Convex/Intrinsic.lean index 479217a8826312..eeb1c596241605 100644 --- a/Mathlib/Analysis/Convex/Intrinsic.lean +++ b/Mathlib/Analysis/Convex/Intrinsic.lean @@ -117,7 +117,7 @@ alias ⟨Set.Nonempty.ofIntrinsicClosure, Set.Nonempty.intrinsicClosure⟩ := in @[simp] theorem intrinsicInterior_singleton (x : P) : intrinsicInterior 𝕜 ({x} : Set P) = {x} := by simp only [intrinsicInterior, preimage_coe_affineSpan_singleton, interior_univ, image_univ, - Subtype.range_coe_subtype, mem_affineSpan_singleton, setOf_eq_eq_singleton] + Subtype.range_coe_subtype, mem_affineSpan_singleton, ofPred_eq_eq_singleton] @[simp] theorem intrinsicFrontier_singleton (x : P) : intrinsicFrontier 𝕜 ({x} : Set P) = ∅ := by @@ -126,7 +126,7 @@ theorem intrinsicFrontier_singleton (x : P) : intrinsicFrontier 𝕜 ({x} : Set @[simp] theorem intrinsicClosure_singleton (x : P) : intrinsicClosure 𝕜 ({x} : Set P) = {x} := by simp only [intrinsicClosure, preimage_coe_affineSpan_singleton, closure_univ, image_univ, - Subtype.range_coe_subtype, mem_affineSpan_singleton, setOf_eq_eq_singleton] + Subtype.range_coe_subtype, mem_affineSpan_singleton, ofPred_eq_eq_singleton] /-! Note that neither `intrinsicInterior` nor `intrinsicFrontier` is monotone. diff --git a/Mathlib/Analysis/Convex/Quasiconvex.lean b/Mathlib/Analysis/Convex/Quasiconvex.lean index 2f6e3f05c870da..0961faa7380a84 100644 --- a/Mathlib/Analysis/Convex/Quasiconvex.lean +++ b/Mathlib/Analysis/Convex/Quasiconvex.lean @@ -97,13 +97,13 @@ variable {s : Set E} {f : E → β} {g : β → γ} theorem QuasiconvexOn.monotone_comp (hg : Monotone g) (hf : QuasiconvexOn 𝕜 s f) : QuasiconvexOn 𝕜 s (g ∘ f) := fun c x hx y hy ↦ by - simp only [Function.comp_apply, mem_setOf_eq] at hx hy + simp only [Function.comp_apply, mem_ofPred_eq] at hx hy intro a b ha hb hab - simp only [Function.comp_apply, mem_setOf_eq] + simp only [Function.comp_apply, mem_ofPred_eq] wlog h : f x ≤ f y · grind specialize hf (f y) ⟨hx.1, h⟩ ⟨hy.1, le_rfl⟩ ha hb hab - simp only [mem_setOf_eq] at hf + simp only [mem_ofPred_eq] at hf exact ⟨hf.1, le_trans (hg hf.2) hy.2⟩ theorem QuasiconvexOn.antitone_comp (hg : Antitone g) (hf : QuasiconvexOn 𝕜 s f) : diff --git a/Mathlib/Analysis/Convex/Segment.lean b/Mathlib/Analysis/Convex/Segment.lean index e80914f1504ac1..c5933d477bfb22 100644 --- a/Mathlib/Analysis/Convex/Segment.lean +++ b/Mathlib/Analysis/Convex/Segment.lean @@ -61,12 +61,12 @@ def openSegment (x y : E) : Set E := theorem segment_eq_image₂ (x y : E) : [x -[𝕜] y] = (fun p : 𝕜 × 𝕜 => p.1 • x + p.2 • y) '' { p | 0 ≤ p.1 ∧ 0 ≤ p.2 ∧ p.1 + p.2 = 1 } := by - simp only [segment, image, Prod.exists, mem_setOf_eq, and_assoc] + simp only [segment, image, Prod.exists, mem_ofPred_eq, and_assoc] theorem openSegment_eq_image₂ (x y : E) : openSegment 𝕜 x y = (fun p : 𝕜 × 𝕜 => p.1 • x + p.2 • y) '' { p | 0 < p.1 ∧ 0 < p.2 ∧ p.1 + p.2 = 1 } := by - simp only [openSegment, image, Prod.exists, mem_setOf_eq, and_assoc] + simp only [openSegment, image, Prod.exists, mem_ofPred_eq, and_assoc] theorem segment_symm (x y : E) : [x -[𝕜] y] = [y -[𝕜] x] := Set.ext fun _ => @@ -562,13 +562,13 @@ theorem segment_eq_uIcc (x y : 𝕜) : [x -[𝕜] y] = uIcc x y := /-- A point is in an `Icc` iff it can be expressed as a convex combination of the endpoints. -/ theorem Convex.mem_Icc (h : x ≤ y) : z ∈ Icc x y ↔ ∃ a b, 0 ≤ a ∧ 0 ≤ b ∧ a + b = 1 ∧ a * x + b * y = z := by - simp only [← segment_eq_Icc h, segment, mem_setOf_eq, smul_eq_mul, exists_and_left] + simp only [← segment_eq_Icc h, segment, mem_ofPred_eq, smul_eq_mul, exists_and_left] /-- A point is in an `Ioo` iff it can be expressed as a strict convex combination of the endpoints. -/ theorem Convex.mem_Ioo (h : x < y) : z ∈ Ioo x y ↔ ∃ a b, 0 < a ∧ 0 < b ∧ a + b = 1 ∧ a * x + b * y = z := by - simp only [← openSegment_eq_Ioo h, openSegment, smul_eq_mul, exists_and_left, mem_setOf_eq] + simp only [← openSegment_eq_Ioo h, openSegment, smul_eq_mul, exists_and_left, mem_ofPred_eq] /-- A point is in an `Ioc` iff it can be expressed as a semistrict convex combination of the endpoints. -/ diff --git a/Mathlib/Analysis/Convex/Side.lean b/Mathlib/Analysis/Convex/Side.lean index 93871abdbfb71a..91a26699bf8f45 100644 --- a/Mathlib/Analysis/Convex/Side.lean +++ b/Mathlib/Analysis/Convex/Side.lean @@ -700,10 +700,10 @@ theorem sOppSide_lineMap_right {s : AffineSubspace R P} {x y : P} (hx : x ∈ s) (ht : t < 0) : s.SOppSide y (lineMap x y t) := (sOppSide_lineMap_left hx hy ht).symm -theorem setOf_wSameSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : +theorem setOfPred_wSameSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : { y | s.WSameSide x y } = Set.image2 (fun (t : R) q => t • (x -ᵥ p) +ᵥ q) (Set.Ici 0) s := by ext y - simp_rw [Set.mem_setOf, Set.mem_image2, Set.mem_Ici] + simp_rw [Set.mem_ofPred, Set.mem_image2, Set.mem_Ici] constructor · rw [wSameSide_iff_exists_left hp, or_iff_right hx] rintro ⟨p₂, hp₂, h | h | ⟨r₁, r₂, hr₁, hr₂, h⟩⟩ @@ -718,10 +718,13 @@ theorem setOf_wSameSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ · rintro ⟨t, ht, p', hp', rfl⟩ exact wSameSide_smul_vsub_vadd_right x hp hp' ht -theorem setOf_sSameSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : +@[deprecated (since := "2026-07-09")] +alias setOf_wSameSide_eq_image2 := setOfPred_wSameSide_eq_image2 + +theorem setOfPred_sSameSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : { y | s.SSameSide x y } = Set.image2 (fun (t : R) q => t • (x -ᵥ p) +ᵥ q) (Set.Ioi 0) s := by ext y - simp_rw [Set.mem_setOf, Set.mem_image2, Set.mem_Ioi] + simp_rw [Set.mem_ofPred, Set.mem_image2, Set.mem_Ioi] constructor · rw [sSameSide_iff_exists_left hp] rintro ⟨-, hy, p₂, hp₂, h | h | ⟨r₁, r₂, hr₁, hr₂, h⟩⟩ @@ -735,10 +738,13 @@ theorem setOf_sSameSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ · rintro ⟨t, ht, p', hp', rfl⟩ exact sSameSide_smul_vsub_vadd_right hx hp hp' ht -theorem setOf_wOppSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : +@[deprecated (since := "2026-07-09")] +alias setOf_sSameSide_eq_image2 := setOfPred_sSameSide_eq_image2 + +theorem setOfPred_wOppSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : { y | s.WOppSide x y } = Set.image2 (fun (t : R) q => t • (x -ᵥ p) +ᵥ q) (Set.Iic 0) s := by ext y - simp_rw [Set.mem_setOf, Set.mem_image2, Set.mem_Iic] + simp_rw [Set.mem_ofPred, Set.mem_image2, Set.mem_Iic] constructor · rw [wOppSide_iff_exists_left hp, or_iff_right hx] rintro ⟨p₂, hp₂, h | h | ⟨r₁, r₂, hr₁, hr₂, h⟩⟩ @@ -753,10 +759,13 @@ theorem setOf_wOppSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ · rintro ⟨t, ht, p', hp', rfl⟩ exact wOppSide_smul_vsub_vadd_right x hp hp' ht -theorem setOf_sOppSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : +@[deprecated (since := "2026-07-09")] +alias setOf_wOppSide_eq_image2 := setOfPred_wOppSide_eq_image2 + +theorem setOfPred_sOppSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ s) (hp : p ∈ s) : { y | s.SOppSide x y } = Set.image2 (fun (t : R) q => t • (x -ᵥ p) +ᵥ q) (Set.Iio 0) s := by ext y - simp_rw [Set.mem_setOf, Set.mem_image2, Set.mem_Iio] + simp_rw [Set.mem_ofPred, Set.mem_image2, Set.mem_Iio] constructor · rw [sOppSide_iff_exists_left hp] rintro ⟨-, hy, p₂, hp₂, h | h | ⟨r₁, r₂, hr₁, hr₂, h⟩⟩ @@ -770,6 +779,9 @@ theorem setOf_sOppSide_eq_image2 {s : AffineSubspace R P} {x p : P} (hx : x ∉ · rintro ⟨t, ht, p', hp', rfl⟩ exact sOppSide_smul_vsub_vadd_right hx hp hp' ht +@[deprecated (since := "2026-07-09")] +alias setOf_sOppSide_eq_image2 := setOfPred_sOppSide_eq_image2 + theorem wOppSide_pointReflection {s : AffineSubspace R P} {x : P} (y : P) (hx : x ∈ s) : s.WOppSide y (pointReflection R x y) := (wbtw_pointReflection R _ _).wOppSide₁₃ hx @@ -786,7 +798,8 @@ section Normed variable [SeminormedAddCommGroup V] [NormedSpace ℝ V] [PseudoMetricSpace P] variable [NormedAddTorsor V P] -theorem isConnected_setOf_wSameSide {s : AffineSubspace ℝ P} (x : P) (h : (s : Set P).Nonempty) : +theorem isConnected_setOfPred_wSameSide {s : AffineSubspace ℝ P} (x : P) + (h : (s : Set P).Nonempty) : IsConnected { y | s.WSameSide x y } := by obtain ⟨p, hp⟩ := h have : Nonempty s := ⟨⟨p, hp⟩⟩ @@ -794,29 +807,38 @@ theorem isConnected_setOf_wSameSide {s : AffineSubspace ℝ P} (x : P) (h : (s : · simp only [wSameSide_of_left_mem, hx] have := AddTorsor.connectedSpace V P exact isConnected_univ - · rw [setOf_wSameSide_eq_image2 hx hp, ← Set.image_prod] + · rw [setOfPred_wSameSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Ici.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn convert! AddTorsor.connectedSpace s.direction s -theorem isPreconnected_setOf_wSameSide (s : AffineSubspace ℝ P) (x : P) : +@[deprecated (since := "2026-07-09")] +alias isConnected_setOf_wSameSide := isConnected_setOfPred_wSameSide + +theorem isPreconnected_setOfPred_wSameSide (s : AffineSubspace ℝ P) (x : P) : IsPreconnected { y | s.WSameSide x y } := by rcases Set.eq_empty_or_nonempty (s : Set P) with (h | h) · rw [coe_eq_bot_iff] at h simp only [h, not_wSameSide_bot] exact isPreconnected_empty - · exact (isConnected_setOf_wSameSide x h).isPreconnected + · exact (isConnected_setOfPred_wSameSide x h).isPreconnected + +@[deprecated (since := "2026-07-09")] +alias isPreconnected_setOf_wSameSide := isPreconnected_setOfPred_wSameSide -theorem isConnected_setOf_sSameSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) +theorem isConnected_setOfPred_sSameSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) (h : (s : Set P).Nonempty) : IsConnected { y | s.SSameSide x y } := by obtain ⟨p, hp⟩ := h have : Nonempty s := ⟨⟨p, hp⟩⟩ - rw [setOf_sSameSide_eq_image2 hx hp, ← Set.image_prod] + rw [setOfPred_sSameSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Ioi.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn convert! AddTorsor.connectedSpace s.direction s -theorem isPreconnected_setOf_sSameSide (s : AffineSubspace ℝ P) (x : P) : +@[deprecated (since := "2026-07-09")] +alias isConnected_setOf_sSameSide := isConnected_setOfPred_sSameSide + +theorem isPreconnected_setOfPred_sSameSide (s : AffineSubspace ℝ P) (x : P) : IsPreconnected { y | s.SSameSide x y } := by rcases Set.eq_empty_or_nonempty (s : Set P) with (h | h) · rw [coe_eq_bot_iff] at h @@ -825,9 +847,12 @@ theorem isPreconnected_setOf_sSameSide (s : AffineSubspace ℝ P) (x : P) : · by_cases hx : x ∈ s · simp only [hx, SSameSide, not_true, false_and, and_false] exact isPreconnected_empty - · exact (isConnected_setOf_sSameSide hx h).isPreconnected + · exact (isConnected_setOfPred_sSameSide hx h).isPreconnected -theorem isConnected_setOf_wOppSide {s : AffineSubspace ℝ P} (x : P) (h : (s : Set P).Nonempty) : +@[deprecated (since := "2026-07-09")] +alias isPreconnected_setOf_sSameSide := isPreconnected_setOfPred_sSameSide + +theorem isConnected_setOfPred_wOppSide {s : AffineSubspace ℝ P} (x : P) (h : (s : Set P).Nonempty) : IsConnected { y | s.WOppSide x y } := by obtain ⟨p, hp⟩ := h have : Nonempty s := ⟨⟨p, hp⟩⟩ @@ -835,29 +860,38 @@ theorem isConnected_setOf_wOppSide {s : AffineSubspace ℝ P} (x : P) (h : (s : · simp only [wOppSide_of_left_mem, hx] have := AddTorsor.connectedSpace V P exact isConnected_univ - · rw [setOf_wOppSide_eq_image2 hx hp, ← Set.image_prod] + · rw [setOfPred_wOppSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Iic.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn convert! AddTorsor.connectedSpace s.direction s -theorem isPreconnected_setOf_wOppSide (s : AffineSubspace ℝ P) (x : P) : +@[deprecated (since := "2026-07-09")] +alias isConnected_setOf_wOppSide := isConnected_setOfPred_wOppSide + +theorem isPreconnected_setOfPred_wOppSide (s : AffineSubspace ℝ P) (x : P) : IsPreconnected { y | s.WOppSide x y } := by rcases Set.eq_empty_or_nonempty (s : Set P) with (h | h) · rw [coe_eq_bot_iff] at h simp only [h, not_wOppSide_bot] exact isPreconnected_empty - · exact (isConnected_setOf_wOppSide x h).isPreconnected + · exact (isConnected_setOfPred_wOppSide x h).isPreconnected + +@[deprecated (since := "2026-07-09")] +alias isPreconnected_setOf_wOppSide := isPreconnected_setOfPred_wOppSide -theorem isConnected_setOf_sOppSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) +theorem isConnected_setOfPred_sOppSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) (h : (s : Set P).Nonempty) : IsConnected { y | s.SOppSide x y } := by obtain ⟨p, hp⟩ := h - have : Nonempty s := ⟨⟨p, hp⟩⟩ - rw [setOf_sOppSide_eq_image2 hx hp, ← Set.image_prod] + haveI : Nonempty s := ⟨⟨p, hp⟩⟩ + rw [setOfPred_sOppSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Iio.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn convert! AddTorsor.connectedSpace s.direction s -theorem isPreconnected_setOf_sOppSide (s : AffineSubspace ℝ P) (x : P) : +@[deprecated (since := "2026-07-09")] +alias isConnected_setOf_sOppSide := isConnected_setOfPred_sOppSide + +theorem isPreconnected_setOfPred_sOppSide (s : AffineSubspace ℝ P) (x : P) : IsPreconnected { y | s.SOppSide x y } := by rcases Set.eq_empty_or_nonempty (s : Set P) with (h | h) · rw [coe_eq_bot_iff] at h @@ -866,7 +900,10 @@ theorem isPreconnected_setOf_sOppSide (s : AffineSubspace ℝ P) (x : P) : · by_cases hx : x ∈ s · simp only [hx, SOppSide, not_true, false_and, and_false] exact isPreconnected_empty - · exact (isConnected_setOf_sOppSide hx h).isPreconnected + · exact (isConnected_setOfPred_sOppSide hx h).isPreconnected + +@[deprecated (since := "2026-07-09")] +alias isPreconnected_setOf_sOppSide := isPreconnected_setOfPred_sOppSide end Normed diff --git a/Mathlib/Analysis/Convex/SimplicialComplex/AffineIndependentUnion.lean b/Mathlib/Analysis/Convex/SimplicialComplex/AffineIndependentUnion.lean index 976c2afada058a..18ef039fd8fb41 100644 --- a/Mathlib/Analysis/Convex/SimplicialComplex/AffineIndependentUnion.lean +++ b/Mathlib/Analysis/Convex/SimplicialComplex/AffineIndependentUnion.lean @@ -43,7 +43,7 @@ def ofSimpleGraph {ι : Type*} [DecidableEq ι] (G : SimpleGraph ι) : faces := ({s : Finset ι | ∃ v, s = {v}}) ∪ Sym2.toFinset '' G.edgeSet isRelLowerSet_faces := by intro s hs - simp only [Set.mem_union, Set.mem_setOf_eq, Set.mem_image] at hs + simp only [Set.mem_union, Set.mem_ofPred_eq, Set.mem_image] at hs rcases hs with ⟨v, rfl⟩ | ⟨e, he, rfl⟩ · simp · constructor @@ -52,7 +52,7 @@ def ofSimpleGraph {ι : Type*} [DecidableEq ι] (G : SimpleGraph ι) : by_cases h : b.card = 1 <;> grind [Finset.card_eq_one, Finset.eq_of_subset_of_card_le hb_sub, Sym2.card_toFinset] singleton_mem := by - simp only [Set.mem_union, Set.mem_setOf_eq, Set.mem_image] + simp only [Set.mem_union, Set.mem_ofPred_eq, Set.mem_image] intro v exact Or.inl ⟨v, rfl⟩ diff --git a/Mathlib/Analysis/Convex/StdSimplex.lean b/Mathlib/Analysis/Convex/StdSimplex.lean index 89f918927fa058..7a0c2c2866a186 100644 --- a/Mathlib/Analysis/Convex/StdSimplex.lean +++ b/Mathlib/Analysis/Convex/StdSimplex.lean @@ -37,7 +37,7 @@ def stdSimplex : Set (ι → 𝕜) := theorem stdSimplex_eq_inter : stdSimplex 𝕜 ι = (⋂ x, { f | 0 ≤ f x }) ∩ { f | ∑ x, f x = 1 } := by ext f - simp only [stdSimplex, Set.mem_inter_iff, Set.mem_iInter, Set.mem_setOf_eq] + simp only [stdSimplex, Set.mem_inter_iff, Set.mem_iInter, Set.mem_ofPred_eq] theorem convex_stdSimplex [IsOrderedRing 𝕜] : Convex 𝕜 (stdSimplex 𝕜 ι) := by refine fun f hf g hg a b ha hb hab => ⟨fun x => ?_, ?_⟩ diff --git a/Mathlib/Analysis/Distribution/Support.lean b/Mathlib/Analysis/Distribution/Support.lean index 1598e7ae0ae86b..5e11e4d10f82cc 100644 --- a/Mathlib/Analysis/Distribution/Support.lean +++ b/Mathlib/Analysis/Distribution/Support.lean @@ -99,7 +99,7 @@ theorem mem_dsupport_iff (x : α) : /-- The complement of the support is the largest open set on which `f` vanishes. -/ theorem dsupport_compl_eq : (dsupport f)ᶜ = ⋃₀ { a | IsVanishingOn f a ∧ IsOpen a } := by - simp [dsupport, Set.compl_sInter, Set.compl_image_set_of] + simp [dsupport, Set.compl_sInter, Set.compl_image_ofPred] @[simp high] theorem notMem_dsupport_iff (x : α) : diff --git a/Mathlib/Analysis/Distribution/TemperateGrowth.lean b/Mathlib/Analysis/Distribution/TemperateGrowth.lean index baf2162ae7318e..da91903523ff34 100644 --- a/Mathlib/Analysis/Distribution/TemperateGrowth.lean +++ b/Mathlib/Analysis/Distribution/TemperateGrowth.lean @@ -343,7 +343,7 @@ theorem hasTemperateGrowth_one_add_norm_sq_rpow (r : ℝ) : set t := {y : ℝ | 1 / 2 < y} have ht : Set.range (fun (x : H) ↦ (1 + ‖x‖ ^ 2)) ⊆ t := by rintro - ⟨y, rfl⟩ - simp only [Set.mem_setOf_eq, t] + simp only [Set.mem_ofPred_eq, t] exact lt_add_of_lt_add_left (c := 0) (by norm_num) (by positivity) have hdiff : ContDiffOn ℝ ∞ (fun x ↦ x ^ r) t := contDiffOn_fun_id.rpow_const_of_ne fun x hx ↦ (lt_trans (by norm_num) hx).ne' @@ -392,7 +392,7 @@ theorem hasTemperateGrowth_one_add_norm_sq_rpow (r : ℝ) : congr simpa using hx''.le _ ≤ (2 : ℝ) ^ (n - r) := by - simp only [one_div, Set.mem_setOf_eq, t] at hx + simp only [one_div, Set.mem_ofPred_eq, t] at hx rw [Real.rpow_neg_eq_inv_rpow] gcongr exact ((inv_lt_comm₀ hx'' (by norm_num)).mpr hx).le diff --git a/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean b/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean index cc05da867d4ffa..e9a7b7ee7a544e 100644 --- a/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean +++ b/Mathlib/Analysis/Fourier/RiemannLebesgueLemma.lean @@ -142,7 +142,7 @@ theorem tendsto_integral_exp_inner_smul_cocompact_of_continuous_compact_support have int_A : ∫ v : V, ‖f v - f (v + i w)‖ = ∫ v in A, ‖f v - f (v + i w)‖ := by refine (setIntegral_eq_integral_of_forall_compl_eq_zero fun v hv => ?_).symm dsimp only [A] at hv - simp only [mem_setOf, not_le] at hv + simp only [mem_ofPred, not_le] at hv rw [hR_bd v _, hR_bd (v + i w) _, sub_zero, norm_zero] · rw [← sub_neg_eq_add] refine le_trans ?_ (norm_sub_norm_le _ _) diff --git a/Mathlib/Analysis/InnerProductSpace/Defs.lean b/Mathlib/Analysis/InnerProductSpace/Defs.lean index 2d3af1339eb534..c9bff8edc5adf4 100644 --- a/Mathlib/Analysis/InnerProductSpace/Defs.lean +++ b/Mathlib/Analysis/InnerProductSpace/Defs.lean @@ -515,7 +515,7 @@ lemma topology_eq simp have : p.ball 0 1 = {v | re (cd.inner v v) < 1} := by ext v - simp only [ball_normSeminorm, Metric.mem_ball, dist_eq_norm, sub_zero, Set.mem_setOf_eq, p] + simp only [ball_normSeminorm, Metric.mem_ball, dist_eq_norm, sub_zero, Set.mem_ofPred_eq, p] change √(re (cd.inner v v)) < 1 ↔ re (cd.inner v v) < 1 conv_lhs => rw [show (1 : ℝ) = √1 by simp] rw [sqrt_lt_sqrt_iff] diff --git a/Mathlib/Analysis/InnerProductSpace/Harmonic/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Harmonic/Basic.lean index 94b9aeb598a00f..e13b9675e1c789 100644 --- a/Mathlib/Analysis/InnerProductSpace/Harmonic/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Harmonic/Basic.lean @@ -88,9 +88,11 @@ variable (f) in /-- Harmonicity is an open property. -/ -theorem isOpen_setOf_harmonicAt : IsOpen { x : E | HarmonicAt f x } := +theorem isOpen_setOfPred_harmonicAt : IsOpen { x : E | HarmonicAt f x } := isOpen_iff_mem_nhds.2 (fun _ hx ↦ hx.eventually) +@[deprecated (since := "2026-07-09")] alias isOpen_setOf_harmonicAt := isOpen_setOfPred_harmonicAt + /-- If `f` is harmonic in a neighborhood of `s`, it is harmonic in a neighborhood of every subset. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean index 31ca1a91cbfd0c..601755168bcab6 100644 --- a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean +++ b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean @@ -90,11 +90,11 @@ This definition is needed to construct the adjoint operator and the preferred ve def adjointDomain : Submodule 𝕜 F where carrier := {y | Continuous ((innerₛₗ 𝕜 y).comp T.toFun)} zero_mem' := by - rw [Set.mem_setOf_eq, LinearMap.map_zero, LinearMap.zero_comp] + rw [Set.mem_ofPred_eq, LinearMap.map_zero, LinearMap.zero_comp] exact continuous_zero - add_mem' hx hy := by rw [Set.mem_setOf_eq, LinearMap.map_add] at *; exact hx.add hy + add_mem' hx hy := by rw [Set.mem_ofPred_eq, LinearMap.map_add] at *; exact hx.add hy smul_mem' a x hx := by - rw [Set.mem_setOf_eq, LinearMap.map_smulₛₗ] at * + rw [Set.mem_ofPred_eq, LinearMap.map_smulₛₗ] at * exact hx.const_smul (conj a) /-- The operator `fun x ↦ ⟪y, T x⟫` considered as a continuous linear operator diff --git a/Mathlib/Analysis/InnerProductSpace/MeanErgodic.lean b/Mathlib/Analysis/InnerProductSpace/MeanErgodic.lean index 17fc9ab9169928..4c44ed2b429896 100644 --- a/Mathlib/Analysis/InnerProductSpace/MeanErgodic.lean +++ b/Mathlib/Analysis/InnerProductSpace/MeanErgodic.lean @@ -62,7 +62,7 @@ theorem LinearMap.tendsto_birkhoffAverage_of_ker_subset_closure [NormedSpace By assumption, `LinearMap.range (f - 1)` is dense in the kernel of `g`, so it suffices to prove the theorem for `y = f x - x`. -/ have : IsClosed {x | Tendsto (birkhoffAverage 𝕜 f _root_.id · x) atTop (𝓝 0)} := - isClosed_setOf_tendsto_birkhoffAverage 𝕜 hf uniformContinuous_id continuous_const + isClosed_setOfPred_tendsto_birkhoffAverage 𝕜 hf uniformContinuous_id continuous_const refine closure_minimal (Set.forall_mem_range.2 fun x ↦ ?_) this (hg_ker hy) /- Finally, for `y = f x - x` the average is equal to the difference between averages along the orbits of `f x` and `x`, and most of the terms cancel. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index bda2a2fcf4d0f0..f3570d174fc542 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -177,18 +177,18 @@ theorem EuclideanSpace.ball_zero_eq {n : Type*} [Fintype n] (r : ℝ) (hr : 0 Metric.ball (0 : EuclideanSpace ℝ n) r = {x | ∑ i, x i ^ 2 < r ^ 2} := by ext x have : (0 : ℝ) ≤ ∑ i, x i ^ 2 := Finset.sum_nonneg fun _ _ => sq_nonneg _ - simp_rw [mem_setOf, mem_ball_zero_iff, norm_eq, norm_eq_abs, sq_abs, sqrt_lt this hr] + simp_rw [mem_ofPred, mem_ball_zero_iff, norm_eq, norm_eq_abs, sq_abs, sqrt_lt this hr] theorem EuclideanSpace.closedBall_zero_eq {n : Type*} [Fintype n] (r : ℝ) (hr : 0 ≤ r) : Metric.closedBall (0 : EuclideanSpace ℝ n) r = {x | ∑ i, x i ^ 2 ≤ r ^ 2} := by ext - simp_rw [mem_setOf, mem_closedBall_zero_iff, norm_eq, norm_eq_abs, sq_abs, sqrt_le_left hr] + simp_rw [mem_ofPred, mem_closedBall_zero_iff, norm_eq, norm_eq_abs, sq_abs, sqrt_le_left hr] theorem EuclideanSpace.sphere_zero_eq {n : Type*} [Fintype n] (r : ℝ) (hr : 0 ≤ r) : Metric.sphere (0 : EuclideanSpace ℝ n) r = {x | ∑ i, x i ^ 2 = r ^ 2} := by ext x have : (0 : ℝ) ≤ ∑ i, x i ^ 2 := Finset.sum_nonneg fun _ _ => sq_nonneg _ - simp_rw [mem_setOf, mem_sphere_zero_iff_norm, norm_eq, norm_eq_abs, sq_abs, + simp_rw [mem_ofPred, mem_sphere_zero_iff_norm, norm_eq, norm_eq_abs, sq_abs, Real.sqrt_eq_iff_eq_sq this hr] section diff --git a/Mathlib/Analysis/InnerProductSpace/l2Space.lean b/Mathlib/Analysis/InnerProductSpace/l2Space.lean index 53d6ffa1a20e7e..0c6511cea107d4 100644 --- a/Mathlib/Analysis/InnerProductSpace/l2Space.lean +++ b/Mathlib/Analysis/InnerProductSpace/l2Space.lean @@ -554,7 +554,7 @@ theorem _root_.Orthonormal.exists_hilbertBasis_extension {s : Set E} ∃ (w : Set E) (b : HilbertBasis w 𝕜 E), s ⊆ w ∧ ⇑b = ((↑) : w → E) := let ⟨w, hws, hw_ortho, hw_max⟩ := exists_maximal_orthonormal hs ⟨w, HilbertBasis.mkOfOrthogonalEqBot hw_ortho - (by simpa only [Subtype.range_coe_subtype, Set.setOf_mem_eq, + (by simpa only [Subtype.range_coe_subtype, Set.ofPred_mem_eq, maximal_orthonormal_iff_orthogonalComplement_eq_bot hw_ortho] using hw_max), hws, HilbertBasis.coe_mkOfOrthogonalEqBot _ _⟩ diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean index a8472f4900e4e3..06bf70242eb829 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean @@ -100,7 +100,7 @@ theorem gaugeSeminormFamily_ball (s : AbsConvexOpenSets 𝕜 E) : dsimp only [gaugeSeminormFamily] rw [Seminorm.ball_zero_eq] simp_rw [gaugeSeminorm_toFun] - exact setOf_gauge_lt_one_eq_self_of_isOpen (s.coe_convex.lift ℝ) s.coe_zero_mem s.coe_isOpen + exact setOfPred_gauge_lt_one_eq_self_of_isOpen (s.coe_convex.lift ℝ) s.coe_zero_mem s.coe_isOpen variable [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] variable [LocallyConvexSpace 𝕜 E] diff --git a/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean b/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean index 820e9f6e004795..226d2d36474974 100644 --- a/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean +++ b/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean @@ -76,7 +76,7 @@ theorem balancedCore_empty : balancedCore 𝕜 (∅ : Set E) = ∅ := eq_empty_of_subset_empty (balancedCore_subset _) theorem mem_balancedCore_iff : x ∈ balancedCore 𝕜 s ↔ ∃ t, Balanced 𝕜 t ∧ t ⊆ s ∧ x ∈ t := by - simp_rw [balancedCore, mem_sUnion, mem_setOf_eq, and_assoc] + simp_rw [balancedCore, mem_sUnion, mem_ofPred_eq, and_assoc] theorem smul_balancedCore_subset (s : Set E) {a : 𝕜} (ha : ‖a‖ ≤ 1) : a • balancedCore 𝕜 s ⊆ balancedCore 𝕜 s := by diff --git a/Mathlib/Analysis/LocallyConvex/Bounded.lean b/Mathlib/Analysis/LocallyConvex/Bounded.lean index 14832b54bbd622..4f71bd129a017a 100644 --- a/Mathlib/Analysis/LocallyConvex/Bounded.lean +++ b/Mathlib/Analysis/LocallyConvex/Bounded.lean @@ -356,7 +356,7 @@ theorem isVonNBounded_sub : end IsTopologicalAddGroup /-- The union of all bounded set is the whole space. -/ -theorem sUnion_isVonNBounded_eq_univ : ⋃₀ setOf (IsVonNBounded 𝕜) = (Set.univ : Set E) := +theorem sUnion_isVonNBounded_eq_univ : ⋃₀ Set.ofPred (IsVonNBounded 𝕜) = (Set.univ : Set E) := Set.eq_univ_iff_forall.mpr fun x => Set.mem_sUnion.mpr ⟨{x}, isVonNBounded_singleton _, Set.mem_singleton _⟩ @@ -368,7 +368,7 @@ variable (𝕜 E) Note that this is not registered as an instance, in order to avoid diamonds with the metric bornology. -/ abbrev vonNBornology : Bornology E := - Bornology.ofBounded (setOf (IsVonNBounded 𝕜)) (isVonNBounded_empty 𝕜 E) + Bornology.ofBounded (Set.ofPred (IsVonNBounded 𝕜)) (isVonNBounded_empty 𝕜 E) (fun _ hs _ ht => hs.subset ht) (fun _ hs _ => hs.union) isVonNBounded_singleton variable {E} diff --git a/Mathlib/Analysis/LocallyConvex/Polar.lean b/Mathlib/Analysis/LocallyConvex/Polar.lean index 597edd8783ff7f..ed78d7dbaea42c 100644 --- a/Mathlib/Analysis/LocallyConvex/Polar.lean +++ b/Mathlib/Analysis/LocallyConvex/Polar.lean @@ -82,7 +82,7 @@ theorem polar_nonempty (s : Set E) : Set.Nonempty (B.polar s) := by theorem polar_eq_iInter {s : Set E} : B.polar s = ⋂ x ∈ s, { y : F | ‖B x y‖ ≤ 1 } := by ext - simp only [polar_mem_iff, Set.mem_iInter, Set.mem_setOf_eq] + simp only [polar_mem_iff, Set.mem_iInter, Set.mem_ofPred_eq] /-- The map `B.polar : Set E → Set F` forms an order-reversing Galois connection with `B.flip.polar : Set F → Set E`. We use `OrderDual.toDual` and `OrderDual.ofDual` to express @@ -112,10 +112,10 @@ theorem polar_singleton {a : E} : B.polar {a} = { y | ‖B a y‖ ≤ 1 } := le_ (fun y hy => (polar_mem_iff _ _ _).mp (fun _ hb => by rw [Set.mem_singleton_iff.mp hb]; exact hy)) theorem mem_polar_singleton {x : E} (y : F) : y ∈ B.polar {x} ↔ ‖B x y‖ ≤ 1 := by - simp only [polar_singleton, Set.mem_setOf_eq] + simp only [polar_singleton, Set.mem_ofPred_eq] theorem polar_zero : B.polar ({0} : Set E) = Set.univ := by - simp only [polar_singleton, map_zero, zero_apply, norm_zero, zero_le_one, Set.setOf_true] + simp only [polar_singleton, map_zero, zero_apply, norm_zero, zero_le_one, Set.ofPred_true] theorem subset_bipolar (s : Set E) : s ⊆ B.flip.polar (B.polar s) := fun x hx y hy => by rw [B.flip_apply] @@ -128,7 +128,7 @@ theorem tripolar_eq_polar (s : Set E) : B.polar (B.flip.polar (B.polar s)) = B.p theorem sInter_polar_finite_subset_eq_polar (s : Set E) : ⋂₀ (B.polar '' { F | F.Finite ∧ F ⊆ s }) = B.polar s := by ext x - simp only [Set.sInter_image, Set.mem_setOf_eq, Set.mem_iInter, and_imp] + simp only [Set.sInter_image, Set.mem_ofPred_eq, Set.mem_iInter, and_imp] refine ⟨fun hx a ha ↦ ?_, fun hx F _ hF₂ => polar_antitone _ hF₂ hx⟩ simpa [mem_polar_singleton] using hx _ (Set.finite_singleton a) (Set.singleton_subset_iff.mpr ha) @@ -211,13 +211,16 @@ lemma polarSubmodule_eq_polar (m : SubMulAction 𝕜 E) : theorem mem_polar_iff {x' : StrongDual 𝕜 E} (s : Set E) : x' ∈ polar 𝕜 s ↔ ∀ z ∈ s, ‖x' z‖ ≤ 1 := Iff.rfl -lemma polarSubmodule_eq_setOf {S : Type*} [SetLike S E] [SMulMemClass S 𝕜 E] (m : S) : +lemma polarSubmodule_eq_setOfPred {S : Type*} [SetLike S E] [SMulMemClass S 𝕜 E] (m : S) : polarSubmodule 𝕜 m = { y : StrongDual 𝕜 E | ∀ x ∈ m, y x = 0 } := (topDualPairing 𝕜 E).flip.polar_subMulAction _ +@[deprecated (since := "2026-07-09")] +alias polarSubmodule_eq_setOf := polarSubmodule_eq_setOfPred + lemma mem_polarSubmodule {S : Type*} [SetLike S E] [SMulMemClass S 𝕜 E] (m : S) (y : StrongDual 𝕜 E) : y ∈ polarSubmodule 𝕜 m ↔ ∀ x ∈ m, y x = 0 := - propext_iff.mp congr($(polarSubmodule_eq_setOf 𝕜 m) y) + propext_iff.mp congr($(polarSubmodule_eq_setOfPred 𝕜 m) y) @[simp] theorem zero_mem_polar (s : Set E) : (0 : StrongDual 𝕜 E) ∈ polar 𝕜 s := @@ -237,7 +240,7 @@ theorem polar_singleton {a : E} : polar 𝕜 {a} = { x | ‖x a‖ ≤ 1 } := by simp only [polar, LinearMap.polar_singleton, LinearMap.flip_apply, topDualPairing_apply] theorem mem_polar_singleton {a : E} (y : StrongDual 𝕜 E) : y ∈ polar 𝕜 {a} ↔ ‖y a‖ ≤ 1 := by - simp only [polar_singleton, mem_setOf_eq] + simp only [polar_singleton, mem_ofPred_eq] theorem polar_zero : polar 𝕜 ({0} : Set E) = Set.univ := LinearMap.polar_zero _ diff --git a/Mathlib/Analysis/LocallyConvex/Separation.lean b/Mathlib/Analysis/LocallyConvex/Separation.lean index 459bdf9224b652..a0983da158129c 100644 --- a/Mathlib/Analysis/LocallyConvex/Separation.lean +++ b/Mathlib/Analysis/LocallyConvex/Separation.lean @@ -246,7 +246,7 @@ theorem geometric_hahn_banach_point_point [T1Space E] (hxy : x ≠ y) : /-- A closed convex set is the intersection of the half-spaces containing it. -/ theorem iInter_halfSpaces_eq (hs₁ : Convex ℝ s) (hs₂ : IsClosed s) : ⋂ l : StrongDual ℝ E, { x | ∃ y ∈ s, l x ≤ l y } = s := by - rw [Set.iInter_setOf] + rw [Set.iInter_ofPred] refine Set.Subset.antisymm (fun x hx => ?_) fun x hx l => ⟨x, hx, le_rfl⟩ by_contra h obtain ⟨l, s, hlA, hl⟩ := geometric_hahn_banach_closed_point hs₁ hs₂ h @@ -373,7 +373,7 @@ theorem geometric_hahn_banach_point_point [T1Space E] (hxy : x ≠ y) : theorem iInter_halfSpaces_eq (hs₁ : Convex ℝ s) (hs₂ : IsClosed s) : ⋂ l : StrongDual 𝕜 E, { x | ∃ y ∈ s, re (l x) ≤ re (l y) } = s := by - rw [Set.iInter_setOf] + rw [Set.iInter_ofPred] refine Set.Subset.antisymm (fun x hx => ?_) fun x hx l => ⟨x, hx, le_rfl⟩ by_contra h obtain ⟨l, s, hlA, hl⟩ := geometric_hahn_banach_closed_point (𝕜 := 𝕜) hs₁ hs₂ h @@ -382,7 +382,7 @@ theorem iInter_halfSpaces_eq (hs₁ : Convex ℝ s) (hs₂ : IsClosed s) : theorem iInter_halfSpaces_eq' (hs₁ : Convex ℝ s) (hs₂ : IsClosed s) : ⋂ (l : StrongDual 𝕜 E) (c : ℝ) (_ : ∀ y ∈ s, re (l y) ≤ c), { x | re (l x) ≤ c } = s := by - simp_rw [Set.iInter_setOf] + simp_rw [Set.iInter_ofPred] refine Set.Subset.antisymm (fun x hx => ?_) fun x hx l c hc => hc x hx by_contra h obtain ⟨l, c, hls, hl⟩ := geometric_hahn_banach_closed_point (𝕜 := 𝕜) hs₁ hs₂ h diff --git a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean index 5ec717a849a8a9..84382a377250a0 100644 --- a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean +++ b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean @@ -615,7 +615,7 @@ theorem withSeminorms_iff_mem_nhds_isVonNBounded [IsTopologicalAddGroup E] grw [← ts] rcases (SeminormFamily.basisSets_iff _).1 ht with ⟨w, r, r_pos, hw⟩ rcases eq_or_ne w ∅ with rfl | w_ne - · simp only [ball, Finset.sup_empty, sub_zero, coe_bot, Pi.zero_apply, r_pos, setOf_true] at hw + · simp only [ball, Finset.sup_empty, sub_zero, coe_bot, Pi.zero_apply, r_pos, ofPred_true] at hw simp [hw] have : t = p.ball 0 r := by have : w = Finset.univ := by diff --git a/Mathlib/Analysis/Matrix/Order.lean b/Mathlib/Analysis/Matrix/Order.lean index 21204c2912b36f..b6fbcb31433461 100644 --- a/Mathlib/Analysis/Matrix/Order.lean +++ b/Mathlib/Analysis/Matrix/Order.lean @@ -169,7 +169,7 @@ theorem posSemidef_iff_isHermitian_and_spectrum_nonneg [DecidableEq n] {A : Matr A.PosSemidef ↔ A.IsHermitian ∧ spectrum 𝕜 A ⊆ {a : 𝕜 | 0 ≤ a} := by refine ⟨fun h => ⟨h.isHermitian, fun a => ?_⟩, fun ⟨h1, h2⟩ => ?_⟩ · simp only [h.isHermitian.spectrum_eq_image_range, Set.mem_image, Set.mem_range, - exists_exists_eq_and, Set.mem_setOf_eq, forall_exists_index] + exists_exists_eq_and, Set.mem_ofPred_eq, forall_exists_index] rintro i rfl exact_mod_cast h.eigenvalues_nonneg _ · rw [h1.posSemidef_iff_eigenvalues_nonneg] diff --git a/Mathlib/Analysis/MeanInequalities.lean b/Mathlib/Analysis/MeanInequalities.lean index f63056583fc640..0c75954dab6fd2 100644 --- a/Mathlib/Analysis/MeanInequalities.lean +++ b/Mathlib/Analysis/MeanInequalities.lean @@ -785,7 +785,7 @@ theorem isGreatest_Lp (f : ι → ℝ≥0) {p q : ℝ} (hpq : p.HolderConjugate have B : ∀ y : ℝ≥0, y * y ^ p / y = y ^ p := by refine fun y => mul_div_cancel_left_of_imp fun h => ?_ simp [h, hpq.ne_zero] - simp only [Set.mem_setOf_eq, div_rpow, ← sum_div, ← rpow_mul, + simp only [Set.mem_ofPred_eq, div_rpow, ← sum_div, ← rpow_mul, div_mul_cancel₀ _ hpq.symm.ne_zero, rpow_one, div_le_iff₀ hf, one_mul, hpq.mul_eq_add, ← rpow_sub' A, add_sub_cancel_right, le_refl, true_and, ← mul_div_assoc, B] rw [div_eq_iff, ← rpow_add hf.ne', one_div, one_div, hpq.inv_add_inv_eq_one, rpow_one] diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 7d58e0151fcf9a..bdaba3855399e1 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -503,7 +503,7 @@ theorem congr_codiscreteWithin (hf : MeromorphicOn f U) (h₁ : f =ᶠ[codiscret apply mem_nhdsWithin.mpr use U, h₂, hx, Set.inter_subset_left filter_upwards [this, h₁ x hx] with a h₁a h₂a - simp only [Set.mem_compl_iff, Set.mem_sdiff, Set.mem_setOf_eq, not_and] at h₂a + simp only [Set.mem_compl_iff, Set.mem_sdiff, Set.mem_ofPred_eq, not_and] at h₂a tauto /-- diff --git a/Mathlib/Analysis/Meromorphic/Divisor.lean b/Mathlib/Analysis/Meromorphic/Divisor.lean index 7a06a36c8fab29..543dc8e84cdd7e 100644 --- a/Mathlib/Analysis/Meromorphic/Divisor.lean +++ b/Mathlib/Analysis/Meromorphic/Divisor.lean @@ -48,8 +48,8 @@ noncomputable def divisor (f : 𝕜 → E) (U : Set 𝕜) : ← supportDiscreteWithin_iff_locallyFiniteWithin] by_cases hf : MeromorphicOn f U · filter_upwards [mem_codiscrete_subtype_iff_mem_codiscreteWithin.1 - hf.codiscrete_setOf_meromorphicOrderAt_eq_zero_or_top] - simp only [Set.mem_image, Set.mem_setOf_eq, Subtype.exists, exists_and_left, exists_prop, + hf.codiscrete_setOfPred_meromorphicOrderAt_eq_zero_or_top] + simp only [Set.mem_image, Set.mem_ofPred_eq, Subtype.exists, exists_and_left, exists_prop, exists_eq_right_right, Pi.ofNat_apply, ite_eq_right_iff, WithTop.untop₀_eq_zero, and_imp] tauto · simp [hf, Pi.zero_def] @@ -164,7 +164,7 @@ theorem divisor_congr_codiscreteWithin {f₁ f₂ : 𝕜 → E} (h₁ : f₁ = apply mem_nhdsWithin.mpr use U, h₂, hx, Set.inter_subset_left filter_upwards [this, h₁ x hx] with a h₁a h₂a - simp only [Set.mem_compl_iff, Set.mem_sdiff, Set.mem_setOf_eq, not_and] at h₂a + simp only [Set.mem_compl_iff, Set.mem_sdiff, Set.mem_ofPred_eq, not_and] at h₂a tauto · simp [hx] · simp [divisor, hf₁, (meromorphicOn_congr_codiscreteWithin h₁ h₂).not.1 hf₁] diff --git a/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean b/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean index 3773c083891eff..8ffdcd91c1e7a3 100644 --- a/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean +++ b/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean @@ -68,14 +68,18 @@ theorem eventuallyEq_zero_nhdsNE_of_eventuallyEq_zero_codiscreteWithin (hf : Mer Variant of the principle of isolated zeros, formulated in terms of orders: If `f` is nowhere locally constant zero, then its zero set is discrete within its domain of meromorphicity. -/ -theorem MeromorphicOn.codiscreteWithin_setOf_ne_zero (h₁f : MeromorphicOn f U) +theorem MeromorphicOn.codiscreteWithin_setOfPred_ne_zero (h₁f : MeromorphicOn f U) (h₂f : ∀ u ∈ U, meromorphicOrderAt f u ≠ ⊤) : ∀ᶠ x in codiscreteWithin U, f x ≠ 0 := by filter_upwards [h₁f.analyticAt_mem_codiscreteWithin, - h₁f.codiscreteWithin_setOf_meromorphicOrderAt_eq_zero_or_top h₂f] with x h₁x h₂x + h₁f.codiscreteWithin_setOfPred_meromorphicOrderAt_eq_zero_or_top h₂f] with x h₁x h₂x have := h₂f x h₂x.1 simp_all [← h₁x.analyticOrderAt_eq_zero, h₁x.meromorphicOrderAt_eq] +@[deprecated (since := "2026-07-09")] +alias MeromorphicOn.codiscreteWithin_setOf_ne_zero := + MeromorphicOn.codiscreteWithin_setOfPred_ne_zero + /-! ## Identity Principles -/ @@ -120,11 +124,11 @@ theorem eventually_nhdsSet_eventuallyEq_codiscreteWithin (hf : MeromorphicOn f U ∀ᶠ x in 𝓝ˢ U, f =ᶠ[𝓝[≠] x] g := by rw [eventually_nhdsSet_iff_exists] use {x | f =ᶠ[𝓝[≠] x] g} - simp only [Set.mem_setOf_eq, imp_self, implies_true, and_true] + simp only [Set.mem_ofPred_eq, imp_self, implies_true, and_true] constructor - · apply isOpen_setOf_eventually_nhdsWithin + · apply isOpen_setOfPred_eventually_nhdsWithin · intro x hx - rw [Set.mem_setOf] + rw [Set.mem_ofPred] exact eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin (hf x hx) (hg x hx) hx (hU x hx) h end MeromorphicAt diff --git a/Mathlib/Analysis/Meromorphic/NormalForm.lean b/Mathlib/Analysis/Meromorphic/NormalForm.lean index 87a4d466bcb71e..5613f1682eebf0 100644 --- a/Mathlib/Analysis/Meromorphic/NormalForm.lean +++ b/Mathlib/Analysis/Meromorphic/NormalForm.lean @@ -393,7 +393,7 @@ theorem MeromorphicNFAt.comp_analyticAt (hf : MeromorphicNFAt f (g x)) (hg : Ana IsUnit.smul_eq_zero, true_and] filter_upwards [h₃p, hg.continuousAt.preimage_mem_nhds (hf.filter_mono (by simp))] with a h₁a h₂a - simp_all only [Pi.smul_apply', Pi.pow_apply, Set.preimage_setOf_eq, Set.mem_setOf_eq, + simp_all only [Pi.smul_apply', Pi.pow_apply, Set.preimage_ofPred_eq, Set.mem_ofPred_eq, Function.comp_apply, ← smul_assoc, mul_zpow, smul_eq_mul] congr 2 rw [mul_comm, zpow_mul, zpow_natCast] diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index 1579cfa70c8f60..9feef0df65c452 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -680,7 +680,7 @@ variable {U : Set 𝕜} /-- The set where a meromorphic function has infinite order is clopen in its domain of meromorphy. -/ -theorem isClopen_setOf_meromorphicOrderAt_eq_top (hf : MeromorphicOn f U) : +theorem isClopen_setOfPred_meromorphicOrderAt_eq_top (hf : MeromorphicOn f U) : IsClopen { u : U | meromorphicOrderAt f u = ⊤ } := by constructor · rw [← isOpen_compl_iff, isOpen_iff_forall_mem_open] @@ -708,14 +708,14 @@ theorem isClopen_setOf_meromorphicOrderAt_eq_top (hf : MeromorphicOn f U) : conv => arg 1; intro; left; right; arg 1; intro rw [meromorphicOrderAt_eq_top_iff, eventually_nhdsWithin_iff, eventually_nhds_iff] - simp only [mem_setOf_eq] at hz + simp only [mem_ofPred_eq] at hz rw [meromorphicOrderAt_eq_top_iff, eventually_nhdsWithin_iff, eventually_nhds_iff] at hz obtain ⟨t', h₁t', h₂t', h₃t'⟩ := hz use Subtype.val ⁻¹' t' simp only [mem_compl_iff, mem_singleton_iff, isOpen_induced h₂t', mem_preimage, h₃t', and_self, and_true] intro w hw - simp only [mem_setOf_eq] + simp only [mem_ofPred_eq] -- Trivial case: w = z by_cases h₁w : w = z · rw [h₁w] @@ -727,6 +727,9 @@ theorem isClopen_setOf_meromorphicOrderAt_eq_top (hf : MeromorphicOn f U) : · apply (mem_sdiff w).1 exact ⟨hw, mem_singleton_iff.not.1 (Subtype.coe_ne_coe.2 h₁w)⟩ +@[deprecated (since := "2026-07-09")] +alias isClopen_setOf_meromorphicOrderAt_eq_top := isClopen_setOfPred_meromorphicOrderAt_eq_top + /-- On a connected set, there exists a point where a meromorphic function `f` has finite order iff `f` has finite order at every point. @@ -740,7 +743,7 @@ theorem exists_meromorphicOrderAt_ne_top_iff_forall (hf : MeromorphicOn f U) (hU constructor · intro h₂f have := isPreconnected_iff_preconnectedSpace.1 hU.isPreconnected - rcases isClopen_iff.1 hf.isClopen_setOf_meromorphicOrderAt_eq_top with h | h + rcases isClopen_iff.1 hf.isClopen_setOfPred_meromorphicOrderAt_eq_top with h | h · intro u have : u ∉ (∅ : Set U) := by exact fun a => a rw [← h] at this @@ -806,7 +809,7 @@ theorem analyticAt_mem_codiscreteWithin (hf : MeromorphicOn f U) : /-- The set where a meromorphic function has zero or infinite order is codiscrete within its domain of meromorphicity. -/ -theorem codiscrete_setOf_meromorphicOrderAt_eq_zero_or_top (hf : MeromorphicOn f U) : +theorem codiscrete_setOfPred_meromorphicOrderAt_eq_zero_or_top (hf : MeromorphicOn f U) : {u : U | meromorphicOrderAt f u = 0 ∨ meromorphicOrderAt f u = ⊤} ∈ Filter.codiscrete U := by rw [mem_codiscrete_subtype_iff_mem_codiscreteWithin, mem_codiscreteWithin] intro x hx @@ -822,24 +825,32 @@ theorem codiscrete_setOf_meromorphicOrderAt_eq_zero_or_top (hf : MeromorphicOn f use t \ {x}, fun y h₁y _ ↦ h₁t y h₁y.1 h₁y.2 exact ⟨h₂t.sdiff isClosed_singleton, Set.mem_sdiff_of_mem h₃t hax⟩ · filter_upwards [hf.eventually_analyticAt_or_mem_compl hx, h₁f] with a h₁a h'₁a - simp only [mem_compl_iff, Set.mem_sdiff, mem_image, mem_setOf_eq, Subtype.exists, + simp only [mem_compl_iff, Set.mem_sdiff, mem_image, mem_ofPred_eq, Subtype.exists, exists_and_right, exists_eq_right, not_exists, not_or, not_and, not_forall, Decidable.not_not] rcases h₁a with h' | h' · simp +contextual [h'.meromorphicOrderAt_eq, h'.analyticOrderAt_eq_zero.2, h'₁a] · exact fun ha ↦ (h' ha).elim +@[deprecated (since := "2026-07-09")] +alias codiscrete_setOf_meromorphicOrderAt_eq_zero_or_top := + codiscrete_setOfPred_meromorphicOrderAt_eq_zero_or_top + /-- -Variant of `codiscrete_setOf_meromorphicOrderAt_eq_zero_or_top`: The set where a meromorphic +Variant of `codiscrete_setOfPred_meromorphicOrderAt_eq_zero_or_top`: The set where a meromorphic function has zero or infinite order is codiscrete within its domain of meromorphicity. -/ -theorem codiscreteWithin_setOf_meromorphicOrderAt_eq_zero_or_top (h₁f : MeromorphicOn f U) +theorem codiscreteWithin_setOfPred_meromorphicOrderAt_eq_zero_or_top (h₁f : MeromorphicOn f U) (h₂f : ∀ u ∈ U, meromorphicOrderAt f u ≠ ⊤) : {u ∈ U | meromorphicOrderAt f u = 0 ∨ meromorphicOrderAt f u = ⊤} ∈ codiscreteWithin U := by convert! mem_codiscrete_subtype_iff_mem_codiscreteWithin.1 - h₁f.codiscrete_setOf_meromorphicOrderAt_eq_zero_or_top + h₁f.codiscrete_setOfPred_meromorphicOrderAt_eq_zero_or_top aesop +@[deprecated (since := "2026-07-09")] +alias codiscreteWithin_setOf_meromorphicOrderAt_eq_zero_or_top := + codiscreteWithin_setOfPred_meromorphicOrderAt_eq_zero_or_top + end MeromorphicOn section comp diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean index e9f8c9d346fd3f..38fb17e3bcd2d9 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean @@ -65,12 +65,12 @@ theorem AffineBasis.interior_convexHull {ι E : Type*} [Finite ι] [NormedAddCom · -- The positive-dimensional case. have : FiniteDimensional ℝ E := b.finiteDimensional have : convexHull ℝ (range b) = ⋂ i, b.coord i ⁻¹' Ici 0 := by - rw [b.convexHull_eq_nonneg_coord, setOf_forall]; rfl + rw [b.convexHull_eq_nonneg_coord, ofPred_forall]; rfl ext simp only [this, interior_iInter_of_finite, ← IsOpenMap.preimage_interior_eq_interior_preimage (isOpenMap_barycentric_coord b _) (continuous_barycentric_coord b _), - interior_Ici, mem_iInter, mem_setOf_eq, mem_Ioi, mem_preimage] + interior_Ici, mem_iInter, mem_ofPred_eq, mem_Ioi, mem_preimage] variable {V P : Type*} [NormedAddCommGroup V] [NormedSpace ℝ V] [MetricSpace P] [NormedAddTorsor V P] @@ -128,7 +128,7 @@ theorem affineSpan_eq_top_of_nonempty_interior {s : Set V} theorem AffineBasis.centroid_mem_interior_convexHull {ι} [Fintype ι] (b : AffineBasis ι ℝ V) : Finset.univ.centroid ℝ b ∈ interior (convexHull ℝ (range b)) := by have := b.nonempty - simp only [b.interior_convexHull, mem_setOf_eq, b.coord_apply_centroid (Finset.mem_univ _), + simp only [b.interior_convexHull, mem_ofPred_eq, b.coord_apply_centroid (Finset.mem_univ _), inv_pos, Nat.cast_pos, Finset.card_pos, Finset.univ_nonempty, forall_true_iff] theorem interior_convexHull_nonempty_iff_affineSpan_eq_top [FiniteDimensional ℝ V] {s : Set V} : @@ -136,7 +136,7 @@ theorem interior_convexHull_nonempty_iff_affineSpan_eq_top [FiniteDimensional refine ⟨affineSpan_eq_top_of_nonempty_interior, fun h => ?_⟩ obtain ⟨t, hts, b, hb⟩ := AffineBasis.exists_affine_subbasis h suffices (interior (convexHull ℝ (range b))).Nonempty by - rw [hb, Subtype.range_coe_subtype, setOf_mem_eq] at this + rw [hb, Subtype.range_coe_subtype, ofPred_mem_eq] at this refine this.mono (by gcongr) lift t to Finset V using b.finite_set exact ⟨_, b.centroid_mem_interior_convexHull⟩ diff --git a/Mathlib/Analysis/Normed/Algebra/GelfandMazur.lean b/Mathlib/Analysis/Normed/Algebra/GelfandMazur.lean index 4ffd097b948af3..e89fe2a0b3e25c 100644 --- a/Mathlib/Analysis/Normed/Algebra/GelfandMazur.lean +++ b/Mathlib/Analysis/Normed/Algebra/GelfandMazur.lean @@ -153,7 +153,7 @@ lemma exists_isMinOn_norm_sub_smul (𝕜 : Type*) {F : Type*} [NormedField 𝕜] simp only [isMinOn_univ_iff] refine (show Continuous fun z : 𝕜 ↦ ‖x - algebraMap 𝕜 F z‖ by fun_prop) |>.exists_forall_le_of_isBounded 0 ?_ - simpa [isBounded_def, compl_setOf, Ioi] using this (Ioi_mem_atTop ‖x - (0 : 𝕜) • 1‖) + simpa [isBounded_def, compl_ofPred, Ioi] using this (Ioi_mem_atTop ‖x - (0 : 𝕜) • 1‖) /-! ### The complex case @@ -374,7 +374,7 @@ private lemma exists_isMinOn_norm_φ (x : F) : ∃ z : ℝ × ℝ, IsMinOn (‖ -- otherwise, use `tendsto_φ_cobounded`. simp only [isMinOn_univ_iff] at hu ⊢ refine (continuous_φ x).norm.exists_forall_le_of_isBounded (0, 0) ?_ - simpa [isBounded_def, compl_setOf, Ioi] + simpa [isBounded_def, compl_ofPred, Ioi] using tendsto_norm_cobounded_atTop.comp (tendsto_φ_cobounded hc₀ hu) (Ioi_mem_atTop _) open Algebra in diff --git a/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean b/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean index 3ac3080001d788..ebca3be5a8ee93 100644 --- a/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean @@ -103,7 +103,7 @@ theorem IsHermitian.exp [StarRing 𝔸] [ContinuousStar 𝔸] {A : Matrix m m theorem BlockTriangular.exp [LinearOrder α] [Algebra ℚ 𝔸] {M : Matrix m m 𝔸} {b : m → α} (hM : BlockTriangular M b) : (exp M).BlockTriangular b := - exp_mem (s := blockTriangularSubalgebra ℚ _ b) isClosed_setOf_blockTriangular hM + exp_mem (s := blockTriangularSubalgebra ℚ _ b) isClosed_setOfPred_blockTriangular hM end Ring diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index 3c0dbc98fa36ae..ce61033d88f4d3 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -116,7 +116,7 @@ protected theorem isClosed (a : A) : IsClosed (σ a) := (isOpen_resolventSet a).isClosed_compl theorem mem_resolventSet_of_norm_lt_mul {a : A} {k : 𝕜} (h : ‖a‖ * ‖(1 : A)‖ < ‖k‖) : k ∈ ρ a := by - rw [resolventSet, Set.mem_setOf_eq, Algebra.algebraMap_eq_smul_one] + rw [resolventSet, Set.mem_ofPred_eq, Algebra.algebraMap_eq_smul_one] nontriviality A have hk : k ≠ 0 := ne_zero_of_norm_ne_zero ((mul_nonneg (norm_nonneg _) (norm_nonneg _)).trans_lt h).ne' diff --git a/Mathlib/Analysis/Normed/Field/Lemmas.lean b/Mathlib/Analysis/Normed/Field/Lemmas.lean index 51dad45f85dc63..45e279ea0d992b 100644 --- a/Mathlib/Analysis/Normed/Field/Lemmas.lean +++ b/Mathlib/Analysis/Normed/Field/Lemmas.lean @@ -101,7 +101,7 @@ theorem uniformContinuousOn_inv₀ {s : Set α} (hs : sᶜ ∈ 𝓝 0) : rw [Metric.uniformContinuousOn_iff_le] intro ε hε rcases NormedAddGroup.nhds_zero_basis_norm_lt.mem_iff.mp hs with ⟨r, hr₀, hr⟩ - simp only [Set.subset_compl_comm (t := s), Set.compl_setOf, not_lt] at hr + simp only [Set.subset_compl_comm (t := s), Set.compl_ofPred, not_lt] at hr have hs₀ : ∀ x ∈ s, x ≠ 0 := fun x hx ↦ norm_pos_iff.mp <| hr₀.trans_le (hr hx) refine ⟨ε * r ^ 2, by positivity, fun x hx y hy hxy ↦ ?_⟩ calc diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index f0789e63185df6..0d4b45e5fb3d1e 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -692,7 +692,7 @@ open Set in @[to_additive] lemma SeminormedGroup.disjoint_nhds (x : E) (f : Filter E) : Disjoint (𝓝 x) f ↔ ∃ δ > 0, ∀ᶠ y in f, δ ≤ ‖y⁻¹ * x‖ := by - simp [NormedGroup.nhds_basis_norm_lt x |>.disjoint_iff_left, compl_setOf, eventually_iff] + simp [NormedGroup.nhds_basis_norm_lt x |>.disjoint_iff_left, compl_ofPred, eventually_iff] @[to_additive] lemma SeminormedGroup.disjoint_nhds_one (f : Filter E) : diff --git a/Mathlib/Analysis/Normed/Group/InfiniteSum.lean b/Mathlib/Analysis/Normed/Group/InfiniteSum.lean index 885c2e0ee09e97..9b88acb3c7b603 100644 --- a/Mathlib/Analysis/Normed/Group/InfiniteSum.lean +++ b/Mathlib/Analysis/Normed/Group/InfiniteSum.lean @@ -47,7 +47,7 @@ theorem cauchySeq_finset_iff_vanishing_norm {f : ι → E} : (CauchySeq fun s : Finset ι => ∑ i ∈ s, f i) ↔ ∀ ε > (0 : ℝ), ∃ s : Finset ι, ∀ t, Disjoint t s → ‖∑ i ∈ t, f i‖ < ε := by rw [cauchySeq_finset_iff_sum_vanishing, nhds_basis_ball.forall_iff] - · simp only [ball_zero_eq, Set.mem_setOf_eq] + · simp only [ball_zero_eq, Set.mem_ofPred_eq] · rintro s t hst ⟨s', hs'⟩ exact ⟨s', fun t' ht' => hst <| hs' _ ht'⟩ diff --git a/Mathlib/Analysis/Normed/Group/NullSubmodule.lean b/Mathlib/Analysis/Normed/Group/NullSubmodule.lean index 732b933098ff31..96d92e63c44ff9 100644 --- a/Mathlib/Analysis/Normed/Group/NullSubmodule.lean +++ b/Mathlib/Analysis/Normed/Group/NullSubmodule.lean @@ -42,7 +42,7 @@ def nullSubgroup : Subgroup M where refine (norm_mul_le' x y).trans_eq ?_ rw [hx, hy, add_zero] one_mem' := norm_one' - inv_mem' {x} (hx : ‖x‖ = 0) := by simpa only [Set.mem_setOf_eq, norm_inv'] using hx + inv_mem' {x} (hx : ‖x‖ = 0) := by simpa only [Set.mem_ofPred_eq, norm_inv'] using hx @[to_additive] lemma isClosed_nullSubgroup : IsClosed (nullSubgroup M : Set M) := by diff --git a/Mathlib/Analysis/Normed/Group/Quotient.lean b/Mathlib/Analysis/Normed/Group/Quotient.lean index f6b40a8b9e5163..38dac8b8c09b77 100644 --- a/Mathlib/Analysis/Normed/Group/Quotient.lean +++ b/Mathlib/Analysis/Normed/Group/Quotient.lean @@ -152,7 +152,7 @@ lemma norm_lt_iff : ‖x‖ < r ↔ ∃ m : M, ↑m = x ∧ ‖m‖ < r := by lemma nhds_one_hasBasis : (𝓝 (1 : M ⧸ S)).HasBasis (fun ε ↦ 0 < ε) fun ε ↦ {x | ‖x‖ < ε} := by have : ∀ ε : ℝ, mk '' ball (1 : M) ε = {x : M ⧸ S | ‖x‖ < ε} := by refine fun ε ↦ Set.ext <| forall_mk.2 fun x ↦ ?_ - rw [ball_one_eq, mem_setOf_eq, norm_lt_iff, mem_image] + rw [ball_one_eq, mem_ofPred_eq, norm_lt_iff, mem_image] exact exists_congr fun _ ↦ and_comm rw [← mk_one, nhds_eq, ← funext this] exact .map _ Metric.nhds_basis_ball @@ -211,7 +211,7 @@ noncomputable instance instSeminormedCommGroup : SeminormedCommGroup (M ⧸ S) w __ := groupSeminorm.toSeminormedCommGroup uniformity_dist := by rw [uniformity_eq_comap_nhds_one_left, (nhds_one_hasBasis.comap _).eq_biInf] - simp only [dist, preimage_setOf_eq, norm_eq_groupSeminorm] + simp only [dist, preimage_ofPred_eq, norm_eq_groupSeminorm] variable (S) in /-- The quotient in the category of normed groups. -/ diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index 43d0bdd03c6568..f4d0e0e1968fc5 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -255,7 +255,7 @@ theorem add {f g : ∀ i, E i} (hf : Memℓp f p) (hg : Memℓp g p) : Memℓp ( rcases p.trichotomy with (rfl | rfl | hp) · apply memℓp_zero refine (hf.finite_dsupport.union hg.finite_dsupport).subset fun i => ?_ - simp only [Pi.add_apply, Ne, Set.mem_union, Set.mem_setOf_eq] + simp only [Pi.add_apply, Ne, Set.mem_union, Set.mem_ofPred_eq] contrapose! rintro ⟨hf', hg'⟩ simp [hf', hg'] @@ -1013,7 +1013,7 @@ protected def single (p) (i : α) (a : E i) : lp E p := refine (Set.finite_singleton i).subset ?_ intro j simp only [Set.mem_singleton_iff, Ne, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] rw [not_imp_comm] intro h exact Pi.single_eq_of_ne h _⟩ diff --git a/Mathlib/Analysis/Normed/Module/Connected.lean b/Mathlib/Analysis/Normed/Module/Connected.lean index d6856e77058738..c50c10f2e599c6 100644 --- a/Mathlib/Analysis/Normed/Module/Connected.lean +++ b/Mathlib/Analysis/Normed/Module/Connected.lean @@ -71,7 +71,7 @@ theorem Set.Countable.isPathConnected_compl_of_one_lt_rank obtain ⟨y, hy⟩ : ∃ y, LinearIndependent ℝ ![x, y] := exists_linearIndependent_pair_of_one_lt_rank h x_ne_zero have A : Set.Countable {t : ℝ | ([c + x -[ℝ] c + t • y] ∩ s).Nonempty} := by - apply countable_setOf_nonempty_of_disjoint _ (fun t ↦ inter_subset_right) hs + apply countable_ofPred_nonempty_of_disjoint _ (fun t ↦ inter_subset_right) hs intro t t' htt' apply disjoint_iff_inter_eq_empty.2 have N : {c + x} ∩ s = ∅ := by @@ -81,7 +81,7 @@ theorem Set.Countable.isPathConnected_compl_of_one_lt_rank apply Eq.subset apply segment_inter_eq_endpoint_of_linearIndependent_of_ne hy htt'.symm have B : Set.Countable {t : ℝ | ([c - x -[ℝ] c + t • y] ∩ s).Nonempty} := by - apply countable_setOf_nonempty_of_disjoint _ (fun t ↦ inter_subset_right) hs + apply countable_ofPred_nonempty_of_disjoint _ (fun t ↦ inter_subset_right) hs intro t t' htt' apply disjoint_iff_inter_eq_empty.2 have N : {c - x} ∩ s = ∅ := by @@ -96,7 +96,7 @@ theorem Set.Countable.isPathConnected_compl_of_one_lt_rank obtain ⟨t, ht⟩ : Set.Nonempty ({t : ℝ | ([c + x -[ℝ] c + t • y] ∩ s).Nonempty} ∪ {t : ℝ | ([c - x -[ℝ] c + t • y] ∩ s).Nonempty})ᶜ := ((A.union B).dense_compl ℝ).nonempty let z := c + t • y - simp only [compl_union, mem_inter_iff, mem_compl_iff, mem_setOf_eq, not_nonempty_iff_eq_empty] + simp only [compl_union, mem_inter_iff, mem_compl_iff, mem_ofPred_eq, not_nonempty_iff_eq_empty] at ht have JA : JoinedIn sᶜ a z := by apply JoinedIn.of_segment_subset diff --git a/Mathlib/Analysis/Normed/Module/Convex.lean b/Mathlib/Analysis/Normed/Module/Convex.lean index f167dbde90f139..678d99dcc35dda 100644 --- a/Mathlib/Analysis/Normed/Module/Convex.lean +++ b/Mathlib/Analysis/Normed/Module/Convex.lean @@ -169,17 +169,23 @@ instance (priority := 100) NormedSpace.instPathConnectedSpace : PathConnectedSpa IsTopologicalAddGroup.pathConnectedSpace /-- The set of vectors in the same ray as `x` is connected. -/ -theorem isConnected_setOf_sameRay (x : E) : IsConnected { y | SameRay ℝ x y } := by +theorem isConnected_setOfPred_sameRay (x : E) : IsConnected { y | SameRay ℝ x y } := by by_cases hx : x = 0; · simpa [hx] using isConnected_univ (α := E) simp_rw [← exists_nonneg_left_iff_sameRay hx] exact isConnected_Ici.image _ (by fun_prop) +@[deprecated (since := "2026-07-09")] +alias isConnected_setOf_sameRay := isConnected_setOfPred_sameRay + /-- The set of nonzero vectors in the same ray as the nonzero vector `x` is connected. -/ -theorem isConnected_setOf_sameRay_and_ne_zero {x : E} (hx : x ≠ 0) : +theorem isConnected_setOfPred_sameRay_and_ne_zero {x : E} (hx : x ≠ 0) : IsConnected { y | SameRay ℝ x y ∧ y ≠ 0 } := by simp_rw [← exists_pos_left_iff_sameRay_and_ne_zero hx] exact isConnected_Ioi.image _ (by fun_prop) +@[deprecated (since := "2026-07-09")] +alias isConnected_setOf_sameRay_and_ne_zero := isConnected_setOfPred_sameRay_and_ne_zero + lemma norm_sub_le_of_mem_segment {x y z : E} (hy : y ∈ segment ℝ x z) : ‖y - x‖ ≤ ‖z - x‖ := by rw [segment_eq_image'] at hy diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index 07ae61a5444d89..bf0e33c34c151c 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -327,19 +327,25 @@ protected theorem LinearIndependent.eventually {ι} [Finite ι] {f : ι → E} gcongr exact norm_le_pi_norm (v - u) i -theorem isOpen_setOf_linearIndependent {ι : Type*} [Finite ι] : +theorem isOpen_setOfPred_linearIndependent {ι : Type*} [Finite ι] : IsOpen { f : ι → E | LinearIndependent 𝕜 f } := isOpen_iff_mem_nhds.2 fun _ => LinearIndependent.eventually -theorem isOpen_setOf_nat_le_rank (n : ℕ) : +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_linearIndependent := isOpen_setOfPred_linearIndependent + +theorem isOpen_setOfPred_nat_le_rank (n : ℕ) : IsOpen { f : E →L[𝕜] F | ↑n ≤ (f : E →ₗ[𝕜] F).rank } := by - simp only [LinearMap.le_rank_iff_exists_linearIndependent_finset, setOf_exists, ← exists_prop] + simp only [LinearMap.le_rank_iff_exists_linearIndependent_finset, ofPred_exists, ← exists_prop] refine isOpen_biUnion fun t _ => ?_ have : Continuous fun f : E →L[𝕜] F => fun x : (t : Set E) => f x := continuous_pi fun x => (ContinuousLinearMap.apply 𝕜 F (x : E)).continuous - exact isOpen_setOf_linearIndependent.preimage this + exact isOpen_setOfPred_linearIndependent.preimage this + +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_nat_le_rank := isOpen_setOfPred_nat_le_rank -theorem isOpen_setOf_affineIndependent {ι : Type*} [Finite ι] : +theorem isOpen_setOfPred_affineIndependent {ι : Type*} [Finite ι] : IsOpen {p : ι → E | AffineIndependent 𝕜 p} := by classical rcases isEmpty_or_nonempty ι with h | ⟨⟨i₀⟩⟩ @@ -350,7 +356,10 @@ theorem isOpen_setOf_affineIndependent {ι : Type*} [Finite ι] : have : Fintype ι' := Subtype.fintype _ convert_to! IsOpen ((fun (p : ι → E) (i : ι') ↦ p i -ᵥ p i₀) ⁻¹' {p : ι' → E | LinearIndependent 𝕜 p}) - exact isOpen_setOf_linearIndependent.preimage (by fun_prop) + exact isOpen_setOfPred_linearIndependent.preimage (by fun_prop) + +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_affineIndependent := isOpen_setOfPred_affineIndependent namespace Module.Basis diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean index 8bd303b8226d75..2ab48858ac4d38 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Basic.lean @@ -369,7 +369,7 @@ theorem bounds_bddBelow {f : ContinuousMultilinearMap 𝕜 E G} : theorem isLeast_opNorm (f : ContinuousMultilinearMap 𝕜 E G) : IsLeast {c : ℝ | 0 ≤ c ∧ ∀ m, ‖f m‖ ≤ c * ∏ i, ‖m i‖} ‖f‖ := by refine IsClosed.isLeast_csInf ?_ bounds_nonempty bounds_bddBelow - simp only [Set.setOf_and, Set.setOf_forall] + simp only [Set.ofPred_and, Set.ofPred_forall] exact isClosed_Ici.inter (isClosed_iInter fun m ↦ isClosed_le continuous_const (by fun_prop)) theorem opNorm_nonneg (f : ContinuousMultilinearMap 𝕜 E G) : 0 ≤ ‖f‖ := diff --git a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean index c8ae7ff3aa3e1a..c0e45f198a254f 100644 --- a/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean +++ b/Mathlib/Analysis/Normed/Module/PiTensorProduct/InjectiveSeminorm.lean @@ -86,7 +86,7 @@ lemma dualSeminorms_bounded : BddAbove {p | ∃ (G : Type (max uι u𝕜 uE)) p = Seminorm.comp (normSeminorm 𝕜 (ContinuousMultilinearMap 𝕜 E G →L[𝕜] G)) (toDualContinuousMultilinearMap G (𝕜 := 𝕜) (E := E))} := by use projectiveSeminorm - simp only [mem_upperBounds, Set.mem_setOf_eq, forall_exists_index] + simp only [mem_upperBounds, Set.mem_ofPred_eq, forall_exists_index] intro p G _ _ hp x simpa [hp] using! toDualContinuousMultilinearMap_le_projectiveSeminorm _ @@ -98,7 +98,7 @@ theorem injectiveSeminorm_apply (x : ⨂[𝕜] i, E i) : (_ : SeminormedAddCommGroup G) (_ : NormedSpace 𝕜 G), p = Seminorm.comp (normSeminorm 𝕜 (ContinuousMultilinearMap 𝕜 E G →L[𝕜] G)) (toDualContinuousMultilinearMap G (𝕜 := 𝕜) (E := E))}, p.1 x := by - simpa only [injectiveSeminorm, Set.coe_setOf, Set.mem_setOf_eq] + simpa only [injectiveSeminorm, Set.coe_ofPred, Set.mem_ofPred_eq] using Seminorm.sSup_apply dualSeminorms_bounded set_option backward.isDefEq.respectTransparency false in @@ -151,7 +151,7 @@ theorem norm_eval_le_injectiveSeminorm (f : ContinuousMultilinearMap 𝕜 E F) ( (toDualContinuousMultilinearMap G (𝕜 := 𝕜) (E := E)) ≤ injectiveSeminorm := by simp only [injectiveSeminorm] refine le_csSup dualSeminorms_bounded ?_ - rw [Set.mem_setOf] + rw [Set.mem_ofPred] existsi G, inferInstance, inferInstance rfl refine le_trans ?_ (mul_le_mul_of_nonneg_left (hle x) (norm_nonneg f')) @@ -167,14 +167,14 @@ theorem injectiveSeminorm_le_projectiveSeminorm : rw [injectiveSeminorm] refine csSup_le ?_ ?_ · existsi 0 - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] existsi PUnit, inferInstance, inferInstance ext x simp only [Seminorm.zero_apply, Seminorm.comp_apply, coe_normSeminorm] rw [Subsingleton.elim (toDualContinuousMultilinearMap PUnit.{(max (max uE uι) u𝕜) + 1} x) 0, norm_zero] · intro p hp - simp only [Set.mem_setOf_eq] at hp + simp only [Set.mem_ofPred_eq] at hp obtain ⟨G, _, _, h⟩ := hp rw [h]; intro x; simp only [Seminorm.comp_apply, coe_normSeminorm] exact toDualContinuousMultilinearMap_le_projectiveSeminorm _ diff --git a/Mathlib/Analysis/Normed/Module/WeakDual.lean b/Mathlib/Analysis/Normed/Module/WeakDual.lean index f455dd7bd7e1aa..7303809f7a239c 100644 --- a/Mathlib/Analysis/Normed/Module/WeakDual.lean +++ b/Mathlib/Analysis/Normed/Module/WeakDual.lean @@ -288,7 +288,7 @@ theorem polar_def (s : Set M) : polar 𝕜 s = { f : WeakDual 𝕜 M | ∀ x ∈ /-- The polar `polar 𝕜 s` of a set `s : E` is a closed subset when the weak star topology is used. -/ theorem isClosed_polar (s : Set M) : IsClosed (polar 𝕜 s) := by - simp only [polar_def, setOf_forall] + simp only [polar_def, ofPred_forall] exact isClosed_biInter fun x hx => isClosed_Iic.preimage (WeakBilin.eval_continuous _ _).norm /-- Polar sets of neighborhoods of the origin are bounded in the weak dual. -/ diff --git a/Mathlib/Analysis/Normed/Operator/Basic.lean b/Mathlib/Analysis/Normed/Operator/Basic.lean index ada43ae7b633c5..de6448bdf39c75 100644 --- a/Mathlib/Analysis/Normed/Operator/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Basic.lean @@ -192,7 +192,7 @@ theorem bounds_bddBelow {f : E →SL[σ₁₂] F} : BddBelow { c | 0 ≤ c ∧ theorem isLeast_opNorm [RingHomIsometric σ₁₂] (f : E →SL[σ₁₂] F) : IsLeast {c | 0 ≤ c ∧ ∀ x, ‖f x‖ ≤ c * ‖x‖} ‖f‖ := by refine IsClosed.isLeast_csInf ?_ bounds_nonempty bounds_bddBelow - simp only [setOf_and, setOf_forall] + simp only [ofPred_and, ofPred_forall] refine isClosed_Ici.inter <| isClosed_iInter fun _ ↦ isClosed_le ?_ ?_ <;> fun_prop /-- If one controls the norm of every `A x`, then one controls the norm of `A`. -/ diff --git a/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean b/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean index 4b0f7c8bd1186c..be05a03f41b0b6 100644 --- a/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Compact/Basic.lean @@ -27,7 +27,7 @@ In this file we define compact linear operators between two topological vector s * `IsCompactOperator.clm_comp` : postcomposing a compact operator by a continuous linear map gives a compact operator * `IsCompactOperator.continuous` : compact operators are automatically continuous -* `isClosed_setOf_isCompactOperator` : the set of compact operators is closed for the operator +* `isClosed_setOfPred_isCompactOperator` : the set of compact operators is closed for the operator norm Note that results linking compact operators with `FiniteDimensional` are in a separate file @@ -415,7 +415,7 @@ end Continuous /-- The set of compact operators from a normed space to a complete topological vector space is closed. -/ -theorem isClosed_setOf_isCompactOperator {𝕜₁ 𝕜₂ : Type*} [NontriviallyNormedField 𝕜₁] +theorem isClosed_setOfPred_isCompactOperator {𝕜₁ 𝕜₂ : Type*} [NontriviallyNormedField 𝕜₁] [NormedField 𝕜₂] {σ₁₂ : 𝕜₁ →+* 𝕜₂} {M₁ M₂ : Type*} [SeminormedAddCommGroup M₁] [AddCommGroup M₂] [NormedSpace 𝕜₁ M₁] [Module 𝕜₂ M₂] [UniformSpace M₂] [IsUniformAddGroup M₂] [ContinuousConstSMul 𝕜₂ M₂] [T2Space M₂] [CompleteSpace M₂] : @@ -451,12 +451,15 @@ theorem isClosed_setOf_isCompactOperator {𝕜₁ 𝕜₂ : Type*} [Nontrivially rw [sub_apply] abel +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_isCompactOperator := isClosed_setOfPred_isCompactOperator + theorem compactOperator_topologicalClosure {𝕜₁ 𝕜₂ : Type*} [NontriviallyNormedField 𝕜₁] [NormedField 𝕜₂] {σ₁₂ : 𝕜₁ →+* 𝕜₂} {M₁ M₂ : Type*} [SeminormedAddCommGroup M₁] [AddCommGroup M₂] [NormedSpace 𝕜₁ M₁] [Module 𝕜₂ M₂] [UniformSpace M₂] [IsUniformAddGroup M₂] [ContinuousConstSMul 𝕜₂ M₂] [T2Space M₂] [CompleteSpace M₂] : (compactOperator σ₁₂ M₁ M₂).topologicalClosure = compactOperator σ₁₂ M₁ M₂ := - SetLike.ext' isClosed_setOf_isCompactOperator.closure_eq + SetLike.ext' isClosed_setOfPred_isCompactOperator.closure_eq theorem isCompactOperator_of_tendsto {ι 𝕜₁ 𝕜₂ : Type*} [NontriviallyNormedField 𝕜₁] [NormedField 𝕜₂] {σ₁₂ : 𝕜₁ →+* 𝕜₂} {M₁ M₂ : Type*} [SeminormedAddCommGroup M₁] @@ -464,4 +467,4 @@ theorem isCompactOperator_of_tendsto {ι 𝕜₁ 𝕜₂ : Type*} [NontriviallyN [ContinuousConstSMul 𝕜₂ M₂] [T2Space M₂] [CompleteSpace M₂] {l : Filter ι} [l.NeBot] {F : ι → M₁ →SL[σ₁₂] M₂} {f : M₁ →SL[σ₁₂] M₂} (hf : Tendsto F l (𝓝 f)) (hF : ∀ᶠ i in l, IsCompactOperator (F i)) : IsCompactOperator f := - isClosed_setOf_isCompactOperator.mem_of_tendsto hf hF + isClosed_setOfPred_isCompactOperator.mem_of_tendsto hf hF diff --git a/Mathlib/Analysis/Normed/Operator/NNNorm.lean b/Mathlib/Analysis/Normed/Operator/NNNorm.lean index f2ae9cbd2f6026..5510b8ea8c9b7c 100644 --- a/Mathlib/Analysis/Normed/Operator/NNNorm.lean +++ b/Mathlib/Analysis/Normed/Operator/NNNorm.lean @@ -40,7 +40,7 @@ namespace ContinuousLinearMap theorem nnnorm_def (f : E →SL[σ₁₂] F) : ‖f‖₊ = sInf { c | ∀ x, ‖f x‖₊ ≤ c * ‖x‖₊ } := by ext rw [NNReal.coe_sInf, coe_nnnorm, norm_def, NNReal.coe_image] - simp_rw [← NNReal.coe_le_coe, NNReal.coe_mul, coe_nnnorm, mem_setOf_eq, NNReal.coe_mk, + simp_rw [← NNReal.coe_le_coe, NNReal.coe_mul, coe_nnnorm, mem_ofPred_eq, NNReal.coe_mk, exists_prop] @[simp, nontriviality] @@ -129,7 +129,7 @@ theorem lipschitz_apply (x : E) : LipschitzWith ‖x‖₊ fun f : E →SL[σ₁ theorem exists_mul_lt_apply_of_lt_opNNNorm (f : E →SL[σ₁₂] F) {r : ℝ≥0} (hr : r < ‖f‖₊) : ∃ x, r * ‖x‖₊ < ‖f x‖₊ := by - simpa only [not_forall, not_le, Set.mem_setOf] using + simpa only [not_forall, not_le, Set.mem_ofPred] using notMem_of_lt_csInf (nnnorm_def f ▸ hr : r < sInf { c : ℝ≥0 | ∀ x, ‖f x‖₊ ≤ c * ‖x‖₊ }) (OrderBot.bddBelow _) diff --git a/Mathlib/Analysis/Normed/Order/Lattice.lean b/Mathlib/Analysis/Normed/Order/Lattice.lean index dc4bd9ccc0a8b4..2f23e4812bd089 100644 --- a/Mathlib/Analysis/Normed/Order/Lattice.lean +++ b/Mathlib/Analysis/Normed/Order/Lattice.lean @@ -184,7 +184,7 @@ theorem isClosed_le_of_isClosed_nonneg {G} [ContinuousSub G] (h : IsClosed { x : G | 0 ≤ x }) : IsClosed { p : G × G | p.fst ≤ p.snd } := by have : { p : G × G | p.fst ≤ p.snd } = (fun p : G × G ↦ p.snd - p.fst) ⁻¹' { x : G | 0 ≤ x } := by - ext1 p; simp only [sub_nonneg, Set.preimage_setOf_eq] + ext1 p; simp only [sub_nonneg, Set.preimage_ofPred_eq] rw [this] exact IsClosed.preimage (continuous_snd.sub continuous_fst) h diff --git a/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean b/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean index 9e515e621bb23f..dac8aa822d6a8c 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SmoothingSeminorm.lean @@ -304,7 +304,7 @@ private theorem μ_bddBelow (s : ℕ → ℕ) {x : R} (ψ : ℕ → ℕ) : BddBelow {a : ℝ | ∀ᶠ n : ℝ in map (fun n : ℕ => μ x ^ (↑(s (ψ n)) * (1 / (ψ n : ℝ)))) atTop, n ≤ a} := by use 0 - simp only [mem_lowerBounds, eventually_map, eventually_atTop, Set.mem_setOf_eq, + simp only [mem_lowerBounds, eventually_map, eventually_atTop, Set.mem_ofPred_eq, forall_exists_index] intro r m hm exact le_trans (rpow_nonneg (apply_nonneg μ _) _) (hm m (le_refl _)) @@ -340,11 +340,11 @@ private theorem μ_nonempty {s : ℕ → ℕ} (hs_le : ∀ n : ℕ, s n ≤ n) { n ≤ a}.Nonempty := by by_cases hμx : μ x < 1 · use 1 - simp only [eventually_map, eventually_atTop, Set.mem_setOf_eq] + simp only [eventually_map, eventually_atTop, Set.mem_ofPred_eq] exact ⟨0, fun _ _ ↦ rpow_le_one (apply_nonneg _ _) (le_of_lt hμx) (mul_nonneg (cast_nonneg _) (one_div_nonneg.mpr (cast_nonneg _)))⟩ · use μ x - simp only [eventually_map, eventually_atTop, Set.mem_setOf_eq] + simp only [eventually_map, eventually_atTop, Set.mem_ofPred_eq] use 0 intro b _ nth_rw 2 [← rpow_one (μ x)] @@ -358,7 +358,7 @@ private theorem μ_limsup_le_one {s : ℕ → ℕ} (hs_le : ∀ n : ℕ, s n ≤ simp only [limsup, limsSup] rw [csInf_le_iff (μ_bddBelow μ s ψ) (μ_nonempty μ hs_le ψ)] · intro c hc_bd - simp only [mem_lowerBounds, eventually_map, eventually_atTop, Set.mem_setOf_eq, + simp only [mem_lowerBounds, eventually_map, eventually_atTop, Set.mem_ofPred_eq, forall_exists_index] at hc_bd by_cases hμx : μ x < 1 · apply hc_bd (1 : ℝ) 0 @@ -390,7 +390,7 @@ private theorem limsup_mu_le (hμ1 : μ 1 ≤ 1) {s : ℕ → ℕ} (hs_le : ∀ limsup (fun n : ℕ => μ x ^ ((s (ψ n) : ℝ) * (1 / (ψ n : ℝ)))) atTop := by apply csInf_le_csInf _ (μ_nonempty μ hs_le ψ) · intro b hb - simp only [eventually_map, eventually_atTop, Set.mem_setOf_eq] at hb ⊢ + simp only [eventually_map, eventually_atTop, Set.mem_ofPred_eq] at hb ⊢ obtain ⟨m, hm⟩ := hb use m intro k hkm @@ -400,7 +400,7 @@ private theorem limsup_mu_le (hμ1 : μ 1 ≤ 1) {s : ℕ → ℕ} (hs_le : ∀ exact map_pow_le_pow' hμ1 x _ · use 0 simp only [mem_lowerBounds, eventually_map, eventually_atTop, - Set.mem_setOf_eq, forall_exists_index] + Set.mem_ofPred_eq, forall_exists_index] exact fun _ m hm ↦ le_trans (by positivity) (hm m (le_refl _)) _ ≤ 1 := (μ_limsup_le_one μ hs_le hψ_lim) _ = smoothingFun μ x ^ a := by rw [ha, rpow_zero] diff --git a/Mathlib/Analysis/ODE/PicardLindelof.lean b/Mathlib/Analysis/ODE/PicardLindelof.lean index 5f87041559c1a4..a692cd5696e93c 100644 --- a/Mathlib/Analysis/ODE/PicardLindelof.lean +++ b/Mathlib/Analysis/ODE/PicardLindelof.lean @@ -202,8 +202,8 @@ lemma range_toContinuousMap : instance [CompleteSpace E] : CompleteSpace (FunSpace t₀ x₀ r L) := by rw [completeSpace_iff_isComplete_range isUniformInducing_toContinuousMap] apply IsClosed.isComplete - rw [range_toContinuousMap, setOf_and] - apply isClosed_setOf_lipschitzWith L |>.preimage continuous_coeFun |>.inter + rw [range_toContinuousMap, ofPred_and] + apply isClosed_setOfPred_lipschitzWith L |>.preimage continuous_coeFun |>.inter simp_rw [mem_closedBall_iff_norm] exact isClosed_le (by fun_prop) (by fun_prop) diff --git a/Mathlib/Analysis/ODE/Transform.lean b/Mathlib/Analysis/ODE/Transform.lean index 9f7120d18118ff..3d38ff9b2124b8 100644 --- a/Mathlib/Analysis/ODE/Transform.lean +++ b/Mathlib/Analysis/ODE/Transform.lean @@ -124,7 +124,7 @@ lemma isIntegralCurveOn_comp_mul_ne_zero {a : ℝ} (ha : a ≠ 0) : simp only [comp_apply, Pi.smul_apply, mul_assoc, inv_mul_eq_div, div_self ha, mul_one, smul_smul, one_smul] · simp only [mul_comm _ a⁻¹, ← smul_eq_mul, mem_inv_smul_set_iff₀ ha, smul_inv_smul₀ ha, - setOf_mem_eq] + ofPred_mem_eq] lemma IsIntegralCurveAt.comp_mul_ne_zero (hγ : IsIntegralCurveAt γ v t₀) {a : ℝ} (ha : a ≠ 0) : IsIntegralCurveAt (γ ∘ (· * a)) (a • v ∘ (· * a)) (t₀ / a) := by @@ -133,7 +133,7 @@ lemma IsIntegralCurveAt.comp_mul_ne_zero (hγ : IsIntegralCurveAt γ v t₀) {a refine ⟨ε / |a|, by positivity, ?_⟩ convert! h.comp_mul a ext t - rw [mem_setOf_eq, Metric.mem_ball, Metric.mem_ball, Real.dist_eq, Real.dist_eq, + rw [mem_ofPred_eq, Metric.mem_ball, Metric.mem_ball, Real.dist_eq, Real.dist_eq, lt_div_iff₀ (abs_pos.mpr ha), ← abs_mul, sub_mul, div_mul_cancel₀ _ ha] lemma isIntegralCurveAt_comp_mul_ne_zero {a : ℝ} (ha : a ≠ 0) : diff --git a/Mathlib/Analysis/PSeries.lean b/Mathlib/Analysis/PSeries.lean index b8e4ee7b8c81ad..6499506f39f848 100644 --- a/Mathlib/Analysis/PSeries.lean +++ b/Mathlib/Analysis/PSeries.lean @@ -438,8 +438,8 @@ lemma Real.not_summable_indicator_one_div_natCast {m : ℕ} (hm : m ≠ 0) (k : rw [← summable_nat_add_iff 1] -- shift by one to avoid non-monotonicity at zero have h (n : ℕ) : {n : ℕ | (n : ZMod m) = k - 1}.indicator (fun n : ℕ ↦ (1 / (n + 1 :) : ℝ)) n = if (n : ZMod m) = k - 1 then (1 / (n + 1) : ℝ) else (0 : ℝ) := by - simp only [indicator_apply, mem_setOf_eq, cast_add, cast_one] - simp_rw [indicator_apply, mem_setOf, cast_add, cast_one, ← eq_sub_iff_add_eq, ← h] + simp only [indicator_apply, mem_ofPred_eq, cast_add, cast_one] + simp_rw [indicator_apply, mem_ofPred, cast_add, cast_one, ← eq_sub_iff_add_eq, ← h] rw [summable_indicator_mod_iff (fun n₁ n₂ h ↦ by gcongr) (k - 1)] exact mt (summable_nat_add_iff (f := fun n : ℕ ↦ 1 / (n : ℝ)) 1).mp not_summable_one_div_natCast diff --git a/Mathlib/Analysis/Polynomial/Basic.lean b/Mathlib/Analysis/Polynomial/Basic.lean index 7d91be3f9076fc..0fc260912dd989 100644 --- a/Mathlib/Analysis/Polynomial/Basic.lean +++ b/Mathlib/Analysis/Polynomial/Basic.lean @@ -34,12 +34,12 @@ namespace Polynomial variable {𝕜 : Type*} [NormedField 𝕜] [LinearOrder 𝕜] [IsStrictOrderedRing 𝕜] (P Q : 𝕜[X]) theorem eventually_atTop_not_isRoot (hP : P ≠ 0) : ∀ᶠ x in atTop, ¬P.IsRoot x := - atTop_le_cofinite <| (finite_setOf_isRoot hP).compl_mem_cofinite + atTop_le_cofinite <| (finite_setOfPred_isRoot hP).compl_mem_cofinite @[deprecated (since := "2026-02-05")] alias eventually_no_roots := eventually_atTop_not_isRoot theorem eventually_atBot_not_isRoot (hP : P ≠ 0) : ∀ᶠ x in atBot, ¬P.IsRoot x := - atBot_le_cofinite <| (finite_setOf_isRoot hP).compl_mem_cofinite + atBot_le_cofinite <| (finite_setOfPred_isRoot hP).compl_mem_cofinite variable [OrderTopology 𝕜] @@ -334,7 +334,7 @@ section Cobounded lemma eventually_cofinite_not_isRoot {R : Type*} [CommRing R] [IsDomain R] {P : R[X]} (hP : P ≠ 0) : ∀ᶠ x in cofinite, ¬P.IsRoot x := - (finite_setOf_isRoot hP).compl_mem_cofinite + (finite_setOfPred_isRoot hP).compl_mem_cofinite open Bornology @@ -389,7 +389,7 @@ theorem dvd_of_infinite_eval_dvd_eval set R := P %ₘ Q apply eq_zero_of_infinite_isRoot refine (h.sdiff (finite_abs_eval_le_of_degree_lt degR)).mono fun x mx ↦ ?_ - simp only [Set.mem_sdiff, Set.mem_setOf_eq, not_le] at mx + simp only [Set.mem_sdiff, Set.mem_ofPred_eq, not_le] at mx rw [← eqR, eval_add, eval_mul, Int.dvd_add_self_mul, ← abs_dvd] at mx exact Int.eq_zero_of_abs_lt_dvd mx.1 mx.2 diff --git a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean index 3c827acbd101df..9735cf811ef79d 100644 --- a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean +++ b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean @@ -279,8 +279,8 @@ theorem mahlerMeasure_le_sum_norm_coeff (p : ℂ[X]) : p.mahlerMeasure ≤ p.sum constructor · rw [mem_ae_iff, compl_def, Measure.restrict_apply' (by simp)] apply (Finite.of_sdiff _ <| finite_singleton (2 * π)).measure_zero - simp only [ne_eq, mem_setOf_eq, Decidable.not_not, inter_sdiff_assoc, Icc_sdiff_right] - rw [setOf_inter_eq_sep] + simp only [ne_eq, mem_ofPred_eq, Decidable.not_not, inter_sdiff_assoc, Icc_sdiff_right] + rw [ofPred_inter_eq_sep] apply Finite.of_finite_image (f := circleMap 0 1) ((Multiset.finite_toSet p.roots).subset _) <| fun _ h _ k l ↦ injOn_circleMap_of_abs_sub_le' one_ne_zero (by linarith) h.1 k.1 l simp [hp] @@ -311,11 +311,11 @@ theorem mahlerMeasure_le_sqrt_sum_sq_norm_coeff (p : Polynomial ℂ) : have : ∀ᵐ (θ : ℝ) ∂volume.restrict (uIoc 0 (2 * π)), 0 < ‖p.eval (circleMap 0 1 θ)‖ := by rw [ae_restrict_iff' measurableSet_uIoc] refine Set.Finite.measure_zero ?_ _ - simp only [norm_pos_iff, ne_eq, compl_setOf, Classical.not_imp, Decidable.not_not] + simp only [norm_pos_iff, ne_eq, compl_ofPred, Classical.not_imp, Decidable.not_not] refine Finite.of_finite_image (f := circleMap 0 1) (p.roots.finite_toSet.subset ?_) ?_ · rintro z ⟨θ, ⟨_, heval⟩, rfl⟩ exact (mem_roots hp).mpr heval - · grw [setOf_and, inter_subset_left] + · grw [ofPred_and, inter_subset_left] exact injOn_circleMap_of_abs_sub_le one_ne_zero (by simp [abs_of_pos pi_pos]) have hlogAe : ∀ᵐ (θ : ℝ) ∂volume.restrict (uIoc 0 (2 * π)), exp (log ‖p.eval (circleMap 0 1 θ)‖) = ‖p.eval (circleMap 0 1 θ)‖ := by diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index cdc2a71a64edb5..7317a175c1516b 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -1225,7 +1225,7 @@ open scoped ComplexOrder in lemma instOrderClosedTopology : OrderClosedTopology K where isClosed_le' := by conv in _ ≤ _ => rw [RCLike.le_iff_re_im] - simp_rw [Set.setOf_and] + simp_rw [Set.ofPred_and] refine IsClosed.inter (isClosed_le ?_ ?_) (isClosed_eq ?_ ?_) <;> fun_prop scoped[ComplexOrder] attribute [instance] RCLike.instOrderClosedTopology diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index 11b5244eb49f77..b6cc241ca2857d 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -656,11 +656,11 @@ theorem closedBall_smul (p : Seminorm 𝕜 E) {c : NNReal} (hc : 0 < c) (r : ℝ theorem ball_sup (p : Seminorm 𝕜 E) (q : Seminorm 𝕜 E) (e : E) (r : ℝ) : ball (p ⊔ q) e r = ball p e r ∩ ball q e r := by - simp_rw [ball, ← Set.setOf_and, coe_sup, Pi.sup_apply, sup_lt_iff] + simp_rw [ball, ← Set.ofPred_and, coe_sup, Pi.sup_apply, sup_lt_iff] theorem closedBall_sup (p : Seminorm 𝕜 E) (q : Seminorm 𝕜 E) (e : E) (r : ℝ) : closedBall (p ⊔ q) e r = closedBall p e r ∩ closedBall q e r := by - simp_rw [closedBall, ← Set.setOf_and, coe_sup, Pi.sup_apply, sup_le_iff] + simp_rw [closedBall, ← Set.ofPred_and, coe_sup, Pi.sup_apply, sup_le_iff] theorem ball_finset_sup' (p : ι → Seminorm 𝕜 E) (s : Finset ι) (H : s.Nonempty) (e : E) (r : ℝ) : ball (s.sup' H p) e r = s.inf' H fun i => ball (p i) e r := by @@ -744,22 +744,22 @@ variable {σ₁₂ : 𝕜 →+* 𝕜₂} [RingHomIsometric σ₁₂] theorem ball_comp (p : Seminorm 𝕜₂ E₂) (f : E →ₛₗ[σ₁₂] E₂) (x : E) (r : ℝ) : (p.comp f).ball x r = f ⁻¹' p.ball (f x) r := by ext - simp_rw [ball, mem_preimage, comp_apply, Set.mem_setOf_eq, map_sub] + simp_rw [ball, mem_preimage, comp_apply, Set.mem_ofPred_eq, map_sub] theorem closedBall_comp (p : Seminorm 𝕜₂ E₂) (f : E →ₛₗ[σ₁₂] E₂) (x : E) (r : ℝ) : (p.comp f).closedBall x r = f ⁻¹' p.closedBall (f x) r := by ext - simp_rw [closedBall, mem_preimage, comp_apply, Set.mem_setOf_eq, map_sub] + simp_rw [closedBall, mem_preimage, comp_apply, Set.mem_ofPred_eq, map_sub] variable (p : Seminorm 𝕜 E) theorem preimage_metric_ball {r : ℝ} : p ⁻¹' Metric.ball 0 r = { x | p x < r } := by ext x - simp only [mem_setOf, mem_preimage, mem_ball_zero_iff, Real.norm_of_nonneg (apply_nonneg p _)] + simp only [mem_ofPred, mem_preimage, mem_ball_zero_iff, Real.norm_of_nonneg (apply_nonneg p _)] theorem preimage_metric_closedBall {r : ℝ} : p ⁻¹' Metric.closedBall 0 r = { x | p x ≤ r } := by ext x - simp only [mem_setOf, mem_preimage, mem_closedBall_zero_iff, + simp only [mem_ofPred, mem_preimage, mem_closedBall_zero_iff, Real.norm_of_nonneg (apply_nonneg p _)] theorem ball_zero_eq_preimage_ball {r : ℝ} : p.ball 0 r = p ⁻¹' Metric.ball 0 r := by @@ -797,13 +797,13 @@ theorem balanced_closedBall_zero (r : ℝ) : Balanced 𝕜 (closedBall p 0 r) := theorem ball_finset_sup_eq_iInter (p : ι → Seminorm 𝕜 E) (s : Finset ι) (x : E) {r : ℝ} (hr : 0 < r) : ball (s.sup p) x r = ⋂ i ∈ s, ball (p i) x r := by lift r to NNReal using hr.le - simp_rw [ball, iInter_setOf, finset_sup_apply, NNReal.coe_lt_coe, + simp_rw [ball, iInter_ofPred, finset_sup_apply, NNReal.coe_lt_coe, Finset.sup_lt_iff (show ⊥ < r from hr), ← NNReal.coe_lt_coe, NNReal.coe_mk] theorem closedBall_finset_sup_eq_iInter (p : ι → Seminorm 𝕜 E) (s : Finset ι) (x : E) {r : ℝ} (hr : 0 ≤ r) : closedBall (s.sup p) x r = ⋂ i ∈ s, closedBall (p i) x r := by lift r to NNReal using hr - simp_rw [closedBall, iInter_setOf, finset_sup_apply, NNReal.coe_le_coe, Finset.sup_le_iff, ← + simp_rw [closedBall, iInter_ofPred, finset_sup_apply, NNReal.coe_le_coe, Finset.sup_le_iff, ← NNReal.coe_le_coe, NNReal.coe_mk] theorem ball_finset_sup (p : ι → Seminorm 𝕜 E) (s : Finset ι) (x : E) {r : ℝ} (hr : 0 < r) : diff --git a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean index 2b2dbd9b9e2f95..318b8d1fbacc58 100644 --- a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean +++ b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean @@ -193,7 +193,8 @@ theorem bernsteinApproximation_uniform [LocallyConvexSpace ℝ E] (f : C(I, E)) |>.compactConvergenceUniformity_of_compact |> nhds_basis_uniformity |>.tendsto_right_iff] rintro U ⟨hU₀, hcU⟩ filter_upwards [this U hU₀ hcU] with n hn x - exact setOf_gauge_lt_one_subset_self hcU (mem_of_mem_nhds hU₀) (absorbent_nhds_zero hU₀) (hn x) + exact setOfPred_gauge_lt_one_subset_self hcU (mem_of_mem_nhds hU₀) (absorbent_nhds_zero hU₀) + (hn x) intro U hU₀ hUc /- Choose a constant `C` such that `‖f x - f y‖_U ≤ C` for all `x`, `y`. For a normed space, this would be twice the norm of `f`. -/ diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean index 969f190fefacf8..ad59ce75e0c508 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean @@ -192,7 +192,7 @@ theorem countable_preimage_exp {s : Set ℂ} : (exp ⁻¹' s).Countable ↔ s.Co refine hs.biUnion fun z hz => ?_ by_cases! h : ∃ w, exp w = z · rcases h with ⟨w, rfl⟩ - simp only [Set.preimage, Set.mem_singleton_iff, exp_eq_exp_iff_exists_int, Set.setOf_exists] + simp only [Set.preimage, Set.mem_singleton_iff, exp_eq_exp_iff_exists_int, Set.ofPred_exists] exact Set.countable_iUnion fun m => Set.countable_singleton _ · simp [Set.preimage, h] @@ -303,7 +303,7 @@ noncomputable def expOpenPartialHomeomorph : OpenPartialHomeomorph ℂ ℂ where simp [exp_mem_slitPlane, h₂.ne, (toIocMod_eq_self Real.two_pi_pos).mpr ⟨h₁, by simpa [two_mul] using h₂.le⟩] map_target' z h := by - simp only [mem_setOf, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and] + simp only [mem_ofPred, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and] exact h.imp_left le_of_lt left_inv' _x hx := log_exp hx.1 (le_of_lt hx.2) right_inv' _x hx := exp_log <| slitPlane_ne_zero hx diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean index b8dda31c967e0f..27829bb8786e55 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/ExpLog/Order.lean @@ -104,13 +104,13 @@ lemma CFC.concaveOn_log : ConcaveOn ℝ {a : A | IsStrictlyPositive a} log := by of any positive definite operator, which means that `CFC.log a = lim_{p → 0} p⁻¹ * (a ^ p - 1)` by the continuity of the continuous functional calculus (`tendsto_cfc_fun`). Then, we use the fact that `x^p` is concave for `p ∈ [0,1]` (`CFC.concaveOn_rpow`) and that the set of - concave functions is closed (`isClosed_setOf_concaveOn`) to conclude the proof. -/ + concave functions is closed (`isClosed_setOfPred_concaveOn`) to conclude the proof. -/ set s := {a : A | IsStrictlyPositive a} let f (p : ℝ) := fun a => if a ∈ s then cfc (A := A) (fun x => p⁻¹ * (x ^ p - 1)) a else 0 let g := fun a => if a ∈ s then log (A := A) a else 0 have hg : s.EqOn g (log (A := A)) := by simp +contextual [g, Set.EqOn] refine ConcaveOn.congr ?_ hg - apply isClosed_setOf_concaveOn.mem_of_tendsto (f := f) (b := (𝓝[>] (0 : ℝ))) + apply isClosed_setOfPred_concaveOn.mem_of_tendsto (f := f) (b := (𝓝[>] (0 : ℝ))) tendsto_ite_cfc_rpow_sub_one_ite_log ?_ have h₁ : ∀ᶠ (p : ℝ) in 𝓝[>] 0, 0 < p ∧ p < 1 := nhdsGT_basis 0 |>.mem_of_mem zero_lt_one filter_upwards [h₁] with p ⟨hp, hp'⟩ diff --git a/Mathlib/Analysis/SpecialFunctions/Exp.lean b/Mathlib/Analysis/SpecialFunctions/Exp.lean index f56bc3f95d4d05..8042b6b7f1f515 100644 --- a/Mathlib/Analysis/SpecialFunctions/Exp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Exp.lean @@ -140,7 +140,7 @@ lemma UniformContinuousOn.cexp (a : ℝ) : UniformContinuousOn exp {x : ℂ | x. ring_nf rw [this, mul_comm] have hya : ‖cexp y‖ ≤ Real.exp a := by simpa only [norm_exp, Real.exp_le_exp] - simp only [gt_iff_lt, dist_zero_right, Set.mem_setOf_eq, norm_mul, Complex.norm_exp] at * + simp only [gt_iff_lt, dist_zero_right, Set.mem_ofPred_eq, norm_mul, Complex.norm_exp] at * apply lt_of_le_of_lt (mul_le_mul h3.le hya (Real.exp_nonneg y.re) ha.le) simp [field] diff --git a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean index fc824bea709fd9..69f0f4ee5eb1f5 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean @@ -219,8 +219,8 @@ theorem circleAverage_log_norm_sub_const_eq_log_radius_add_posLog (hR : R ≠ 0) true_and] apply Set.Subsingleton.finite intro z₁ hz₁ z₂ hz₂ - simp_all only [ne_eq, abs_one, mem_sphere_iff_norm, sub_zero, Set.mem_sdiff, Set.mem_setOf_eq, - Decidable.not_not] + simp_all only [ne_eq, abs_one, mem_sphere_iff_norm, sub_zero, Set.mem_sdiff, + Set.mem_ofPred_eq, Decidable.not_not] rw [add_eq_zero_iff_eq_neg.1 hz₁.2, add_eq_zero_iff_eq_neg.1 hz₂.2] filter_upwards [this] with z hz rw [norm_mul, log_mul (norm_ne_zero_iff.2 (Complex.ofReal_ne_zero.mpr hR)) hz] diff --git a/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean b/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean index 52a2ab800666ac..7002ba9f72b6ff 100644 --- a/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean +++ b/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean @@ -106,7 +106,7 @@ theorem finite_integral_one_add_norm {r : ℝ} (hnr : (finrank ℝ E : ℝ) < r) μ (Metric.closedBall (0 : E) (t ^ (-r⁻¹) - 1)) := fun t ht ↦ by congr 1 ext x - simp only [mem_setOf_eq, mem_closedBall_zero_iff] + simp only [mem_ofPred_eq, mem_closedBall_zero_iff] exact le_rpow_one_add_norm_iff_norm_le hr (mem_Ioi.mp ht) x rw [setLIntegral_congr_fun measurableSet_Ioi h_int] set f := fun t : ℝ ↦ μ (Metric.closedBall (0 : E) (t ^ (-r⁻¹) - 1)) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean index d41254b9cd1ef3..56c2032d5fbaf0 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Deriv.lean @@ -388,7 +388,7 @@ theorem hasSum_log_sub_log_of_abs_lt_one {x : ℝ} (h : |x| < 1) : convert! h₁.add (hasSum_pow_div_log_of_abs_lt_one h) using 1 ring_nf · intro m hm - rw [range_two_mul, Set.mem_setOf_eq, ← Nat.even_add_one] at hm + rw [range_two_mul, Set.mem_ofPred_eq, ← Nat.even_add_one] at hm dsimp [term] rw [Even.neg_pow hm, neg_one_mul, neg_add_cancel] diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Monotone.lean b/Mathlib/Analysis/SpecialFunctions/Log/Monotone.lean index 11c472c0be494e..daaa4ea85e67e9 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Monotone.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Monotone.lean @@ -71,7 +71,7 @@ theorem log_div_self_rpow_antitoneOn {a : ℝ} (ha : 0 < a) : log_rpow (rpow_pos_of_pos y_pos a), log_rpow (rpow_pos_of_pos x_pos a), mul_div_assoc, mul_div_assoc, mul_le_mul_iff_right₀ (one_div_pos.mpr ha)] have hbound {z : ℝ} (hz : z ∈ Ici (rexp a⁻¹)) : z ^ a ∈ {b | rexp 1 ≤ b} := by - rw [mem_setOf_eq] + rw [mem_ofPred_eq] convert! rpow_le_rpow _ hz (le_of_lt ha) using 1 · simp only [← exp_mul, Real.exp_eq_exp, field] positivity diff --git a/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean b/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean index f957e408e5bb5a..3d3e3a85d82e49 100644 --- a/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean +++ b/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean @@ -66,7 +66,7 @@ theorem not_integrableOn_of_tendsto_norm_atTop_of_deriv_isBigO_filter_aux ∀ y ∈ [[x.1, x.2]], (DifferentiableAt ℝ f y ∧ ‖deriv f y‖ ≤ C * ‖g y‖) ∧ y ∈ k := (tendsto_fst.uIcc tendsto_snd).eventually ((hd.and hC.bound).and hl).smallSets rcases mem_prod_self_iff.1 h with ⟨s, hsl, hs⟩ - simp only [prod_subset_iff, mem_setOf_eq] at hs + simp only [prod_subset_iff, mem_ofPred_eq] at hs exact ⟨C, C₀, s, hsl, fun x hx y hy z hz => (hs x hx y hy z hz).2, fun x hx y hy z hz => (hs x hx y hy z hz).1.1, fun x hx y hy z hz => (hs x hx y hy z hz).1.2⟩ replace hgi : IntegrableOn (fun x ↦ C * ‖g x‖) k := by exact hgi.norm.smul C diff --git a/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean b/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean index ae94fa6b17397c..053dcbf1bcd84f 100644 --- a/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean +++ b/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean @@ -44,7 +44,7 @@ def polarCoord : OpenPartialHomeomorph (ℝ × ℝ) (ℝ × ℝ) where · simpa using! hr · right simp at hr - simpa only [ne_of_gt hr, Ne, mem_setOf_eq, mul_eq_zero, false_or, + simpa only [ne_of_gt hr, Ne, mem_ofPred_eq, mul_eq_zero, false_or, sin_eq_zero_iff_of_lt_of_lt hθ.1 hθ.2] using! h'θ map_source' := by rintro ⟨x, y⟩ hxy @@ -123,7 +123,7 @@ instance : Measure.IsAddHaarMeasure volume (G := ℝ × ℝ) := theorem polarCoord_source_ae_eq_univ : polarCoord.source =ᵐ[volume] univ := by have A : polarCoord.sourceᶜ ⊆ LinearMap.ker (LinearMap.snd ℝ ℝ ℝ) := by intro x hx - simp only [polarCoord_source, compl_union, mem_inter_iff, mem_compl_iff, mem_setOf_eq, not_lt, + simp only [polarCoord_source, compl_union, mem_inter_iff, mem_compl_iff, mem_ofPred_eq, not_lt, Classical.not_not] at hx exact hx.2 have B : volume (LinearMap.ker (LinearMap.snd ℝ ℝ ℝ) : Set (ℝ × ℝ)) = 0 := by diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean index a4f209c1ff56de..82c11e2b416ee9 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean @@ -78,7 +78,7 @@ theorem continuous_tan : Continuous fun x : {x | cos x ≠ 0} => tan x := theorem continuousOn_tan_Ioo : ContinuousOn tan (Ioo (-(π / 2)) (π / 2)) := by refine ContinuousOn.mono continuousOn_tan fun x => ?_ - simp only [and_imp, mem_Ioo, mem_setOf_eq, Ne] + simp only [and_imp, mem_Ioo, mem_ofPred_eq, Ne] rw [cos_eq_zero_iff] rintro hx_gt hx_lt ⟨r, hxr_eq⟩ rcases le_or_gt 0 r with h | h diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean index 561dc570aa772d..660b110661726d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Bounds.lean @@ -192,7 +192,7 @@ theorem lt_tan {x : ℝ} (h1 : 0 < x) (h2 : x < π / 2) : x < tan x := by have tan_cts_U : ContinuousOn tan U := by apply ContinuousOn.mono continuousOn_tan intro z hz - simp only [mem_setOf_eq] + simp only [mem_ofPred_eq] exact (cos_pos hz).ne' have tan_minus_id_cts : ContinuousOn (fun y : ℝ => tan y - y) U := tan_cts_U.sub continuousOn_id have deriv_pos (y : ℝ) (hy : y ∈ interior U) : 0 < deriv (fun y' : ℝ => tan y' - y') y := by diff --git a/Mathlib/Analysis/SumOverResidueClass.lean b/Mathlib/Analysis/SumOverResidueClass.lean index a48038cf114a6e..905d6f78b83e67 100644 --- a/Mathlib/Analysis/SumOverResidueClass.lean +++ b/Mathlib/Analysis/SumOverResidueClass.lean @@ -25,7 +25,7 @@ public section lemma Finset.sum_indicator_mod {R : Type*} [AddCommMonoid R] (m : ℕ) [NeZero m] (f : ℕ → R) : f = ∑ a : ZMod m, {n : ℕ | (n : ZMod m) = a}.indicator f := by ext n - simp only [Finset.sum_apply, Set.indicator_apply, Set.mem_setOf_eq, Finset.sum_ite_eq, + simp only [Finset.sum_apply, Set.indicator_apply, Set.mem_ofPred_eq, Finset.sum_ite_eq, Finset.mem_univ, ↓reduceIte] set_option backward.isDefEq.respectTransparency false in @@ -37,8 +37,8 @@ lemma summable_indicator_mod_iff_summable {R : Type*} [AddCommGroup R] [Topologi Summable ({n : ℕ | (n : ZMod m) = k}.indicator f) ↔ Summable fun n ↦ f (m * n + k) := by trans Summable ({n : ℕ | (n : ZMod m) = k ∧ k ≤ n}.indicator f) · rw [← (finite_lt_nat k).summable_compl_iff (f := {n : ℕ | (n : ZMod m) = k}.indicator f)] - simp only [summable_subtype_iff_indicator, indicator_indicator, inter_comm, setOf_and, - compl_setOf, not_lt] + simp only [summable_subtype_iff_indicator, indicator_indicator, inter_comm, ofPred_and, + compl_ofPred, not_lt] · let g : ℕ → ℕ := fun n ↦ m * n + k have hg : Function.Injective g := fun m n hmn ↦ by simpa [g, hm.ne] using hmn have hg' : ∀ n ∉ range g, {n : ℕ | (n : ZMod m) = k ∧ k ≤ n}.indicator f n = 0 := by @@ -46,7 +46,7 @@ lemma summable_indicator_mod_iff_summable {R : Type*} [AddCommGroup R] [Topologi contrapose! hn exact (Nat.range_mul_add m k).symm ▸ mem_of_indicator_ne_zero hn convert (Function.Injective.summable_iff hg hg').symm - simp only [Function.comp_apply, mem_setOf_eq, Nat.cast_add, Nat.cast_mul, CharP.cast_eq_zero, + simp only [Function.comp_apply, mem_ofPred_eq, Nat.cast_add, Nat.cast_mul, CharP.cast_eq_zero, zero_mul, zero_add, le_add_iff_nonneg_left, zero_le, and_self, indicator_of_mem, g] /-- If `f : ℕ → ℝ` is decreasing and has a negative term, then `f` is not summable. -/ diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean index fa1da99e06830e..76019033f4d785 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean @@ -271,7 +271,7 @@ set_option backward.isDefEq.respectTransparency.types false in lemma Retract.injectiveDimension_le {X Y : C} (h : Retract X Y) : injectiveDimension X ≤ injectiveDimension Y := sInf_le_sInf_of_subset_insert_top (fun n hn ↦ by - simp only [Set.mem_setOf_eq, not_top_lt, IsEmpty.forall_iff, implies_true, + simp only [Set.mem_ofPred_eq, not_top_lt, IsEmpty.forall_iff, implies_true, Set.insert_eq_of_mem] at hn ⊢ intro i hi have := hn i hi @@ -281,7 +281,7 @@ lemma injectiveDimension_lt_iff {X : C} {n : ℕ} : injectiveDimension X < n ↔ HasInjectiveDimensionLT X n := by refine ⟨fun h ↦ ?_, fun h ↦ sInf_lt_iff.2 ?_⟩ · have : injectiveDimension X ∈ _ := csInf_mem ⟨⊤, by simp⟩ - simp only [Set.mem_setOf_eq] at this + simp only [Set.mem_ofPred_eq] at this exact this _ h · obtain _ | n := n · exact ⟨⊥, fun _ _ ↦ hasInjectiveDimensionLT_of_ge _ 0 _ (by simp), by decide⟩ diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean index f52a1ca97fb834..6c57f6199672c2 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean @@ -276,7 +276,7 @@ set_option backward.isDefEq.respectTransparency.types false in lemma Retract.projectiveDimension_le {X Y : C} (h : Retract X Y) : projectiveDimension X ≤ projectiveDimension Y := sInf_le_sInf_of_subset_insert_top (fun n hn ↦ by - simp only [Set.mem_setOf_eq, not_top_lt, IsEmpty.forall_iff, implies_true, + simp only [Set.mem_ofPred_eq, not_top_lt, IsEmpty.forall_iff, implies_true, Set.insert_eq_of_mem] at hn ⊢ intro i hi have := hn i hi @@ -286,7 +286,7 @@ lemma projectiveDimension_lt_iff {X : C} {n : ℕ} : projectiveDimension X < n ↔ HasProjectiveDimensionLT X n := by refine ⟨fun h ↦ ?_, fun h ↦ sInf_lt_iff.2 ?_⟩ · have : projectiveDimension X ∈ _ := csInf_mem ⟨⊤, by simp⟩ - simp only [Set.mem_setOf_eq] at this + simp only [Set.mem_ofPred_eq] at this exact this _ h · obtain _ | n := n · exact ⟨⊥, fun _ _ ↦ hasProjectiveDimensionLT_of_ge _ 0 _ (by simp), by decide⟩ diff --git a/Mathlib/CategoryTheory/Galois/Topology.lean b/Mathlib/CategoryTheory/Galois/Topology.lean index b31abecc3adaed..972e740d48b674 100644 --- a/Mathlib/CategoryTheory/Galois/Topology.lean +++ b/Mathlib/CategoryTheory/Galois/Topology.lean @@ -82,7 +82,7 @@ instance : TopologicalSpace (Aut F) := Set.range (autEmbedding F) = ⋂ (f : Arrow C), { a | F.map f.hom ≫ (a f.right).hom = (a f.left).hom ≫ F.map f.hom } := by ext a - simp only [Set.mem_range, id_obj, Set.mem_iInter, Set.mem_setOf_eq] + simp only [Set.mem_range, id_obj, Set.mem_iInter, Set.mem_ofPred_eq] refine ⟨fun ⟨σ, h⟩ i ↦ h.symm ▸ σ.hom.naturality i.hom, fun h ↦ ?_⟩ · use NatIso.ofComponents a (fun {X Y} f ↦ h ⟨X, Y, f⟩) rfl-/ @@ -94,7 +94,7 @@ lemma autEmbedding_range : Set.range (autEmbedding F) = ⋂ (f : Arrow C), { a | F.map f.hom ≫ (a f.right).hom = (a f.left).hom ≫ F.map f.hom } := by ext a - simp only [Set.mem_range, Set.mem_iInter, Set.mem_setOf_eq] + simp only [Set.mem_range, Set.mem_iInter, Set.mem_ofPred_eq] refine ⟨fun ⟨σ, h⟩ i ↦ by cat_disch, fun h ↦ ?_⟩ exact ⟨NatIso.ofComponents a (fun {X Y} f ↦ by ext; simpa using ConcreteCategory.congr_hom (h ⟨X, Y, f⟩) _), rfl⟩ diff --git a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean index 725485d6a3f191..d6c5eb3477bf40 100644 --- a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean @@ -382,10 +382,10 @@ by taking preimages. -/ def comap (S : Subgroupoid D) : Subgroupoid C where arrows c d := {f : c ⟶ d | φ.map f ∈ S.arrows (φ.obj c) (φ.obj d)} - inv hp := by rw [mem_setOf, inv_eq_inv, φ.map_inv, ← inv_eq_inv]; exact S.inv hp + inv hp := by rw [mem_ofPred, inv_eq_inv, φ.map_inv, ← inv_eq_inv]; exact S.inv hp mul := by intros - simp only [mem_setOf, Functor.map_comp] + simp only [mem_ofPred, Functor.map_comp] apply S.mul <;> assumption @[gcongr] @@ -393,9 +393,9 @@ theorem comap_mono (S T : Subgroupoid D) : S ≤ T → comap φ S ≤ comap φ T @ST ⟨_, _, _⟩ theorem isNormal_comap {S : Subgroupoid D} (Sn : IsNormal S) : IsNormal (comap φ S) where - wide c := by rw [comap, mem_setOf, Functor.map_id]; apply Sn.wide + wide c := by rw [comap, mem_ofPred, Functor.map_id]; apply Sn.wide conj f γ hγ := by - simp_rw [inv_eq_inv f, comap, mem_setOf, Functor.map_comp, Functor.map_inv, ← inv_eq_inv] + simp_rw [inv_eq_inv f, comap, mem_ofPred, Functor.map_comp, Functor.map_inv, ← inv_eq_inv] exact Sn.conj _ hγ @[simp] diff --git a/Mathlib/CategoryTheory/MorphismProperty/Basic.lean b/Mathlib/CategoryTheory/MorphismProperty/Basic.lean index 51e5d15f28b55d..74fa8da4857ebc 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Basic.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Basic.lean @@ -287,7 +287,7 @@ section variable (P : MorphismProperty C) /-- The set in `Set (Arrow C)` which corresponds to `P : MorphismProperty C`. -/ -def toSet : Set (Arrow C) := setOf (fun f ↦ P f.hom) +def toSet : Set (Arrow C) := Set.ofPred (fun f ↦ P f.hom) lemma mem_toSet_iff (f : Arrow C) : f ∈ P.toSet ↔ P f.hom := Iff.rfl diff --git a/Mathlib/CategoryTheory/Sites/Closed.lean b/Mathlib/CategoryTheory/Sites/Closed.lean index 7ae033f8ffa550..1e9a2af18c9cd1 100644 --- a/Mathlib/CategoryTheory/Sites/Closed.lean +++ b/Mathlib/CategoryTheory/Sites/Closed.lean @@ -232,7 +232,7 @@ lemma GrothendieckTopology.mem_iff_isSheafFor_closedSieves rw [Subtype.ext_iff] at this exact this refine H.isSeparatedFor.ext fun Y f hf ↦ ?_ - simp only [Subfunctor.toFunctor_obj, Functor.sieves_obj, Functor.closedSieves_obj, Set.coe_setOf] + simp only [Subfunctor.toFunctor_obj, Functor.sieves_obj, Functor.closedSieves_obj, Set.coe_ofPred] ext1 dsimp rw [Sieve.pullback_top, ← J.pullback_close, S.pullback_eq_top_of_mem hf, @@ -276,11 +276,11 @@ def topologyOfClosureOperator (c : ∀ X : C, ClosureOperator (Sieve X)) sieves X := { S | c X S = ⊤ } top_mem' X := top_unique ((c X).le_closure _) pullback_stable' X Y S f hS := by - rw [Set.mem_setOf_eq] at hS - rw [Set.mem_setOf_eq, hc, hS, Sieve.pullback_top] + rw [Set.mem_ofPred_eq] at hS + rw [Set.mem_ofPred_eq, hc, hS, Sieve.pullback_top] transitive' X S hS R hR := by - rw [Set.mem_setOf_eq] at hS - rw [Set.mem_setOf_eq, ← (c X).idempotent, eq_top_iff, ← hS] + rw [Set.mem_ofPred_eq] at hS + rw [Set.mem_ofPred_eq, ← (c X).idempotent, eq_top_iff, ← hS] apply (c X).monotone fun Y f hf => _ intro Y f hf rw [Sieve.mem_iff_pullback_eq_top, ← hc] diff --git a/Mathlib/CategoryTheory/Sites/Coherent/Comparison.lean b/Mathlib/CategoryTheory/Sites/Coherent/Comparison.lean index b09b1098ea1c02..6f90a4ba3c613d 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/Comparison.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/Comparison.lean @@ -82,7 +82,7 @@ theorem extensive_regular_generate_coherent [Preregular C] [FinitaryPreExtensive (fun (_ : Unit) ↦ (∐ fun (i : I) => X i)) (fun (_ : Unit) ↦ Sigma.desc f))) · apply Coverage.Saturate.of simp only [Coverage.sup_covering, extensiveCoverage, regularCoverage, Set.mem_union, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] exact Or.inr ⟨_, Sigma.desc f, ⟨rfl, inferInstance⟩⟩ · rintro R g ⟨W, ψ, σ, ⟨⟩, rfl⟩ change _ ∈ ((extensiveCoverage C) ⊔ (regularCoverage C)).toGrothendieck R diff --git a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean index c2f2db39b8ff80..25366af5443c39 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/RegularSheaves.lean @@ -89,7 +89,7 @@ def mapToEqualizer (P : Cᵒᵖ ⥤ Type*) {W X B : C} (f : X ⟶ B) (g₁ g₂ : W ⟶ X) (w : g₁ ≫ f = g₂ ≫ f) : P.obj (op B) ⟶ { x : P.obj (op X) | P.map g₁.op x = P.map g₂.op x } := ↾fun t ↦ - ⟨P.map f.op t, by simp only [Set.mem_setOf_eq, ← comp_apply, ← Functor.map_comp, ← op_comp, w]⟩ + ⟨P.map f.op t, by simp only [Set.mem_ofPred_eq, ← comp_apply, ← Functor.map_comp, ← op_comp, w]⟩ theorem EqualizerCondition.bijective_mapToEqualizer_pullback' {P : Cᵒᵖ ⥤ Type*} (hP : EqualizerCondition P) {X B : C} {π : X ⟶ B} [EffectiveEpi π] diff --git a/Mathlib/CategoryTheory/Sites/Coverage.lean b/Mathlib/CategoryTheory/Sites/Coverage.lean index 832f1c3ae18087..5f9065e22302f0 100644 --- a/Mathlib/CategoryTheory/Sites/Coverage.lean +++ b/Mathlib/CategoryTheory/Sites/Coverage.lean @@ -255,7 +255,7 @@ associated Grothendieck topology is pullback stable, and so an additional constr in the inductive construction is not needed. -/ def toGrothendieck (K : Coverage C) : GrothendieckTopology C := - K.toPrecoverage.toGrothendieck.copy (fun X ↦ setOf (K.Saturate X)) <| by + K.toPrecoverage.toGrothendieck.copy (fun X ↦ Set.ofPred (K.Saturate X)) <| by ext exact K.saturate_iff_saturate_toPrecoverage.symm diff --git a/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean b/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean index fc344b9950c132..d4cc5d8d0760c5 100644 --- a/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/PrecoverageToGrothendieck.lean @@ -59,7 +59,7 @@ It is defined *inductively* as follows: 4. Add all sieves required by the *local character* axiom of a Grothendieck topology. -/ def toGrothendieck (J : Precoverage C) : GrothendieckTopology C where - sieves X := setOf (J.Saturate X) + sieves X := Set.ofPred (J.Saturate X) top_mem' := .top pullback_stable' _ _ _ _ hS := .pullback _ _ hS _ _ transitive' _ _ hS _ hR := .transitive _ _ _ hS hR diff --git a/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean b/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean index e22f8db9518de2..b3ee0e9ad5e92b 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Equalizer.lean @@ -33,7 +33,7 @@ namespace Subfunctor `A.toFunctor ⟶ F₂` with `A : Subfunctor F₁`, as a subcomplex of `F₁`. -/ @[simps -isSimp] protected def equalizer : Subfunctor F₁ where - obj U := setOf (fun x ↦ ∃ (hx : x ∈ A.obj _), f.app _ ⟨x, hx⟩ = g.app _ ⟨x, hx⟩) + obj U := Set.ofPred (fun x ↦ ∃ (hx : x ∈ A.obj _), f.app _ ⟨x, hx⟩ = g.app _ ⟨x, hx⟩) map φ x := by rintro ⟨hx, h⟩ exact ⟨A.map _ hx, diff --git a/Mathlib/CategoryTheory/Subfunctor/OfSection.lean b/Mathlib/CategoryTheory/Subfunctor/OfSection.lean index 45284abc25d019..0673cef2fedd00 100644 --- a/Mathlib/CategoryTheory/Subfunctor/OfSection.lean +++ b/Mathlib/CategoryTheory/Subfunctor/OfSection.lean @@ -35,7 +35,7 @@ variable {F : Cᵒᵖ ⥤ Type w} {X : Cᵒᵖ} (x : F.obj X) by a section `x : F.obj X`. -/ @[simps -isSimp] def ofSection : Subfunctor F where - obj U := setOf (fun u ↦ ∃ (f : X ⟶ U), F.map f x = u) + obj U := Set.ofPred (fun u ↦ ∃ (f : X ⟶ U), F.map f x = u) map {U V} g := by rintro _ ⟨f, rfl⟩ exact ⟨f ≫ g, by simp⟩ @@ -69,7 +69,7 @@ variable {F : Cᵒᵖ ⥤ Type v} lemma ofSection_eq_range {X : Cᵒᵖ} (x : F.obj X) : ofSection x = range (yonedaEquiv.symm x) := by ext U y - simp only [ofSection_obj, Set.mem_setOf_eq, Opposite.op_unop, range_obj, + simp only [ofSection_obj, Set.mem_ofPred_eq, Opposite.op_unop, range_obj, Set.mem_range] constructor · rintro ⟨f, rfl⟩ diff --git a/Mathlib/Combinatorics/Additive/CauchyDavenport.lean b/Mathlib/Combinatorics/Additive/CauchyDavenport.lean index dc5fdf975a8fb2..300291b63d5faa 100644 --- a/Mathlib/Combinatorics/Additive/CauchyDavenport.lean +++ b/Mathlib/Combinatorics/Additive/CauchyDavenport.lean @@ -124,7 +124,7 @@ lemma cauchy_davenport_minOrder_mul (hs : s.Nonempty) (ht : t.Nonempty) : min (minOrder α) ↑(#x.1 + #x.2 - 1) ≤ #(x.1 * x.2)) ⟨hs, ht⟩ ?_ clear! x rintro ⟨s, t⟩ ⟨hs, ht⟩ ih - simp only [min_le_iff, tsub_le_iff_right, Prod.forall, Set.mem_setOf_eq, and_imp, + simp only [min_le_iff, tsub_le_iff_right, Prod.forall, Set.mem_ofPred_eq, and_imp, Nat.cast_le] at * -- If `#t < #s`, we're done by the induction hypothesis on `(t⁻¹, s⁻¹)`. obtain hts | hst := lt_or_ge #t #s diff --git a/Mathlib/Combinatorics/Additive/Dissociation.lean b/Mathlib/Combinatorics/Additive/Dissociation.lean index d50809f67c1099..fb6a16620d56c6 100644 --- a/Mathlib/Combinatorics/Additive/Dissociation.lean +++ b/Mathlib/Combinatorics/Additive/Dissociation.lean @@ -57,7 +57,7 @@ def MulDissociated (s : Set α) : Prop := {t : Finset α | ↑t ⊆ s}.InjOn ( @[to_additive (attr := simp)] lemma mulDissociated_singleton : MulDissociated ({a} : Set α) ↔ a ≠ 1 := by - simp [MulDissociated, setOf_or, -subset_singleton_iff, + simp [MulDissociated, ofPred_or, -subset_singleton_iff, Finset.coe_subset_singleton] @[to_additive (attr := simp)] diff --git a/Mathlib/Combinatorics/Compactness.lean b/Mathlib/Combinatorics/Compactness.lean index a1ae1640e0ae1a..ece779d509df87 100644 --- a/Mathlib/Combinatorics/Compactness.lean +++ b/Mathlib/Combinatorics/Compactness.lean @@ -73,7 +73,7 @@ theorem Finset.rado_selection (g : Finset α → (a : α) → β a) : exact (isClosed_discrete _).preimage (by fun_prop) have he'' (B : Finset (Finset α)) : (⋂ i ∈ B, e i).Nonempty := by refine ⟨g (B.biUnion id), ?_⟩ - simp only [Set.mem_iInter, Set.mem_setOf_eq, e] + simp only [Set.mem_iInter, Set.mem_ofPred_eq, e] intro i hi exact ⟨_, subset_biUnion_of_mem id hi, by simp⟩ simpa using! CompactSpace.iInter_nonempty he' he'' diff --git a/Mathlib/Combinatorics/Configuration.lean b/Mathlib/Combinatorics/Configuration.lean index c95d2b06ce5024..a866f280e8f673 100644 --- a/Mathlib/Combinatorics/Configuration.lean +++ b/Mathlib/Combinatorics/Configuration.lean @@ -147,7 +147,7 @@ theorem Nondegenerate.exists_injective_of_card_le [Nondegenerate P L] [Fintype P -- At most one line through two points of `s` refine Finset.card_le_one_iff.mpr @fun p₁ p₂ hp₁ hp₂ => ?_ simp_rw [t, Finset.mem_compl, Finset.mem_biUnion, not_exists, not_and, - Set.mem_toFinset, Set.mem_setOf_eq, Classical.not_not] at hp₁ hp₂ + Set.mem_toFinset, Set.mem_ofPred_eq, Classical.not_not] at hp₁ hp₂ obtain ⟨l₁, l₂, hl₁, hl₂, hl₃⟩ := Finset.one_lt_card_iff.mp (Nat.one_lt_iff_ne_zero_and_ne_one.mpr ⟨hs₀, hs₁⟩) exact (eq_or_eq (hp₁ l₁ hl₁) (hp₂ l₁ hl₁) (hp₁ l₂ hl₂) (hp₂ l₂ hl₂)).resolve_right hl₃ diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index 201e4ae0e6eefd..e1042092031a89 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -828,7 +828,7 @@ def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1) left_inv := by intro c ext i - simp only [add_comm, Set.toFinset_setOf, Finset.mem_univ, + simp only [add_comm, Set.toFinset_ofPred, Finset.mem_univ, Finset.mem_filter, true_and, exists_prop] constructor · rintro (rfl | rfl | ⟨j, hj1, hj2⟩) @@ -846,7 +846,7 @@ def compositionAsSetEquiv (n : ℕ) : CompositionAsSet n ≃ Finset (Fin (n - 1) intro s ext i have : (i : ℕ) + 1 ≠ n := by lia - simp_rw [add_comm, Fin.ext_iff, Fin.val_zero, Fin.val_last, exists_prop, Set.toFinset_setOf, + simp_rw [add_comm, Fin.ext_iff, Fin.val_zero, Fin.val_last, exists_prop, Set.toFinset_ofPred, Finset.mem_filter_univ, reduceCtorEq, this, false_or, add_left_inj, ← Fin.ext_iff, exists_eq_right'] diff --git a/Mathlib/Combinatorics/Graph/Basic.lean b/Mathlib/Combinatorics/Graph/Basic.lean index e75384bf6f60d2..b122a382a375cd 100644 --- a/Mathlib/Combinatorics/Graph/Basic.lean +++ b/Mathlib/Combinatorics/Graph/Basic.lean @@ -143,9 +143,12 @@ lemma isLink_comm : G.IsLink e x y ↔ G.IsLink e y x := lemma exists_isLink_of_mem_edgeSet (h : e ∈ E(G)) : ∃ x y, G.IsLink e x y := (edge_mem_iff_exists_isLink ..).1 h -lemma edgeSet_eq_setOf_exists_isLink : E(G) = {e | ∃ x y, G.IsLink e x y} := +lemma edgeSet_eq_setOfPred_exists_isLink : E(G) = {e | ∃ x y, G.IsLink e x y} := Set.ext G.edge_mem_iff_exists_isLink +@[deprecated (since := "2026-07-09")] +alias edgeSet_eq_setOf_exists_isLink := edgeSet_eq_setOfPred_exists_isLink + lemma IsLink.left_eq_or_eq (h : G.IsLink e x y) (h' : G.IsLink e z w) : x = z ∨ x = w := G.eq_or_eq_of_isLink_of_isLink h h' @@ -357,7 +360,7 @@ protected lemma ext {G₁ G₂ : Graph α β} (hV : V(G₁) = V(G₂)) convert! rfl using 2 · exact hV.symm · simp [funext_iff, h] - simp [edgeSet_eq_setOf_exists_isLink, h] + simp [edgeSet_eq_setOfPred_exists_isLink, h] /-- Two graphs with the same vertex set and unary incidences are equal. -/ lemma ext_inc {G₁ G₂ : Graph α β} (hV : V(G₁) = V(G₂)) (h : ∀ e x, G₁.Inc e x ↔ G₂.Inc e x) : diff --git a/Mathlib/Combinatorics/Graph/Delete.lean b/Mathlib/Combinatorics/Graph/Delete.lean index a20fe657b79bcc..cec0ab58d13829 100644 --- a/Mathlib/Combinatorics/Graph/Delete.lean +++ b/Mathlib/Combinatorics/Graph/Delete.lean @@ -189,7 +189,7 @@ lemma deleteVerts_isLink (G : Graph α β) (X : Set α) : @[simp] lemma edgeSet_deleteVerts (G : Graph α β) (X : Set α) : E(G.deleteVerts X) = {e | ∃ x y, G.IsLink e x y ∧ x ∉ X ∧ y ∉ X} := by - simp [edgeSet_eq_setOf_exists_isLink] + simp [edgeSet_eq_setOfPred_exists_isLink] @[simp, grind =] lemma deleteVerts_empty (G : Graph α β) : G.deleteVerts (∅ : Set α) = G := by diff --git a/Mathlib/Combinatorics/Graph/Lattice.lean b/Mathlib/Combinatorics/Graph/Lattice.lean index 016505e1cfb08e..c4d5f0c3583888 100644 --- a/Mathlib/Combinatorics/Graph/Lattice.lean +++ b/Mathlib/Combinatorics/Graph/Lattice.lean @@ -47,7 +47,7 @@ instance : SemilatticeInf (Graph α β) where isLink_symm _ _ := { symm _ _ h := ⟨h.1.symm, h.2.symm⟩ } eq_or_eq_of_isLink_of_isLink _ _ _ _ _ h h' := h.1.left_eq_or_eq h'.1 edge_mem_iff_exists_isLink e := by - simp only [edgeSet_eq_setOf_exists_isLink, mem_inter_iff, mem_setOf_eq] + simp only [edgeSet_eq_setOfPred_exists_isLink, mem_inter_iff, mem_ofPred_eq] exact ⟨fun ⟨⟨⟨x, y, hexy⟩, ⟨z, w, hezw⟩⟩, h⟩ ↦ ⟨x, y, hexy, by rwa [← h]⟩, fun ⟨x, y, hfG, hfH⟩ ↦ ⟨⟨⟨_, _, hfG⟩, ⟨_, _, hfH⟩⟩, fun z w ↦ by rw [hfG.isLink_iff_sym2_eq, hfH.isLink_iff_sym2_eq]⟩⟩ diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index 6c3e6555f5bc2a..a0676d26cc1069 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -166,7 +166,7 @@ theorem exists_idempotent_ultrafilter_le_FP {M} [Semigroup M] (a : Stream' M) : · intro U hU V hV rw [Set.mem_iInter] at * intro n - rw [Set.mem_setOf_eq, Ultrafilter.eventually_mul] + rw [Set.mem_ofPred_eq, Ultrafilter.eventually_mul] filter_upwards [hU n] with m hm obtain ⟨n', hn⟩ := FP.mul hm filter_upwards [hV (n' + n)] with m' hm' diff --git a/Mathlib/Combinatorics/Matroid/Basic.lean b/Mathlib/Combinatorics/Matroid/Basic.lean index 3c13de17e8d724..2f143a4f6f9e94 100644 --- a/Mathlib/Combinatorics/Matroid/Basic.lean +++ b/Mathlib/Combinatorics/Matroid/Basic.lean @@ -534,15 +534,21 @@ theorem indep_iff : M.Indep I ↔ ∃ B, M.IsBase B ∧ I ⊆ B := M.indep_iff' (I := I) set_option backward.isDefEq.respectTransparency false in -theorem setOf_indep_eq (M : Matroid α) : {I | M.Indep I} = lowerClosure ({B | M.IsBase B}) := by - simp_rw [indep_iff, lowerClosure, LowerSet.coe_mk, mem_setOf] +theorem setOfPred_indep_eq (M : Matroid α) : {I | M.Indep I} = lowerClosure ({B | M.IsBase B}) := by + simp_rw [indep_iff, lowerClosure, LowerSet.coe_mk, mem_ofPred] + +@[deprecated (since := "2026-07-09")] +alias setOf_indep_eq := setOfPred_indep_eq theorem Indep.exists_isBase_superset (hI : M.Indep I) : ∃ B, M.IsBase B ∧ I ⊆ B := indep_iff.1 hI theorem dep_iff : M.Dep D ↔ ¬M.Indep D ∧ D ⊆ M.E := Iff.rfl -theorem setOf_dep_eq (M : Matroid α) : {D | M.Dep D} = {I | M.Indep I}ᶜ ∩ Iic M.E := rfl +theorem setOfPred_dep_eq (M : Matroid α) : {D | M.Dep D} = {I | M.Indep I}ᶜ ∩ Iic M.E := rfl + +@[deprecated (since := "2026-07-09")] +alias setOf_dep_eq := setOfPred_dep_eq @[aesop unsafe 30% (rule_sets := [Matroid])] theorem Indep.subset_ground (hI : M.Indep I) : I ⊆ M.E := by @@ -1037,13 +1043,16 @@ theorem IsBasis.isBasis_sUnion {Xs : Set (Set α)} (hne : Xs.Nonempty) have := Iff.mpr nonempty_coe_sort hne exact IsBasis.isBasis_iUnion _ fun X ↦ h X X.prop -theorem Indep.isBasis_setOf_insert_isBasis (hI : M.Indep I) : +theorem Indep.isBasis_setOfPred_insert_isBasis (hI : M.Indep I) : M.IsBasis I {x | M.IsBasis I (insert x I)} := by refine hI.isBasis_of_forall_insert (fun e he ↦ (?_ : M.IsBasis _ _)) (fun e he ↦ ⟨fun hu ↦ he.2 ?_, he.1.subset_ground⟩) · rw [insert_eq_of_mem he]; exact hI.isBasis_self simpa using (hu.eq_of_isBasis he.1).symm +@[deprecated (since := "2026-07-09")] +alias Indep.isBasis_setOf_insert_isBasis := Indep.isBasis_setOfPred_insert_isBasis + theorem IsBasis.union_isBasis_union (hIX : M.IsBasis I X) (hJY : M.IsBasis J Y) (h : M.Indep (I ∪ J)) : M.IsBasis (I ∪ J) (X ∪ Y) := by rw [union_eq_iUnion, union_eq_iUnion] @@ -1105,7 +1114,8 @@ end IsBasis section Finite /-- For finite `E`, finitely many matroids have ground set contained in `E`. -/ -theorem finite_setOf_matroid {E : Set α} (hE : E.Finite) : {M : Matroid α | M.E ⊆ E}.Finite := by +theorem finite_setOfPred_matroid {E : Set α} (hE : E.Finite) : + {M : Matroid α | M.E ⊆ E}.Finite := by set f : Matroid α → Set α × (Set (Set α)) := fun M ↦ ⟨M.E, {B | M.IsBase B}⟩ have hf : f.Injective := by refine fun M M' hMM' ↦ ?_ @@ -1114,12 +1124,18 @@ theorem finite_setOf_matroid {E : Set α} (hE : E.Finite) : {M : Matroid α | M. rw [← Set.finite_image_iff hf.injOn] refine (hE.finite_subsets.prod hE.finite_subsets.finite_subsets).subset ?_ rintro _ ⟨M, hE : M.E ⊆ E, rfl⟩ - simp only [Set.mem_prod, Set.mem_setOf_eq] + simp only [Set.mem_prod, Set.mem_ofPred_eq] exact ⟨hE, fun B hB ↦ hB.subset_ground.trans hE⟩ +@[deprecated (since := "2026-07-09")] +alias finite_setOf_matroid := finite_setOfPred_matroid + /-- For finite `E`, finitely many matroids have ground set `E`. -/ -theorem finite_setOf_matroid' {E : Set α} (hE : E.Finite) : {M : Matroid α | M.E = E}.Finite := - (finite_setOf_matroid hE).subset (fun M ↦ by rintro rfl; exact subset_refl M.E) +theorem finite_setOfPred_matroid' {E : Set α} (hE : E.Finite) : {M : Matroid α | M.E = E}.Finite := + (finite_setOfPred_matroid hE).subset (fun M ↦ by rintro rfl; exact subset_refl M.E) + +@[deprecated (since := "2026-07-09")] +alias finite_setOf_matroid' := finite_setOfPred_matroid' end Finite diff --git a/Mathlib/Combinatorics/Matroid/Circuit.lean b/Mathlib/Combinatorics/Matroid/Circuit.lean index 777fe4b0b8a8c4..8cf4d6112a265c 100644 --- a/Mathlib/Combinatorics/Matroid/Circuit.lean +++ b/Mathlib/Combinatorics/Matroid/Circuit.lean @@ -107,7 +107,7 @@ lemma isCircuit_iff_forall_ssubset : M.IsCircuit C ↔ M.Dep C ∧ ∀ ⦃I⦄, exact fun h ↦ ⟨fun h' I hIC ↦ ((not_dep_iff (hIC.subset.trans h.subset_ground)).1 (h' hIC)), fun h I hIC ↦ (h hIC).not_dep⟩ -lemma isCircuit_antichain : IsAntichain (· ⊆ ·) (setOf M.IsCircuit) := +lemma isCircuit_antichain : IsAntichain (· ⊆ ·) (Set.ofPred M.IsCircuit) := fun _ hC _ hC' hne hss ↦ hne <| (IsCircuit.minimal hC').eq_of_subset hC.dep hss lemma IsCircuit.eq_of_not_indep_subset (hC : M.IsCircuit C) (hX : ¬ M.Indep X) (hXC : X ⊆ C) : @@ -256,7 +256,7 @@ lemma Indep.fundCircuit_isCircuit (hI : M.Indep I) (hecl : e ∈ M.closure I) (h · simp [show ∃ x ⊆ I, e ∈ M.closure x ∧ e ∉ x from ⟨I, by simp [hecl, heI]⟩] · rw [hI.closure_sInter_eq_biInter_closure_of_forall_subset ⟨I, by simpa⟩ (by simp +contextual)] simp - simp only [mem_sInter, mem_setOf_eq, and_imp] + simp only [mem_sInter, mem_ofPred_eq, and_imp] exact fun f hf hecl ↦ (hf _ (sdiff_subset.trans aux) hecl).2 rfl lemma Indep.mem_fundCircuit_iff (hI : M.Indep I) (hecl : e ∈ M.closure I) (heI : e ∉ I) : diff --git a/Mathlib/Combinatorics/Matroid/Closure.lean b/Mathlib/Combinatorics/Matroid/Closure.lean index ec24aa323ed492..56ac00514e01a0 100644 --- a/Mathlib/Combinatorics/Matroid/Closure.lean +++ b/Mathlib/Combinatorics/Matroid/Closure.lean @@ -167,11 +167,11 @@ lemma inter_ground_subset_closure (M : Matroid α) (X : Set α) : X ∩ M.E ⊆ lemma mem_closure_iff_forall_mem_isFlat (X : Set α) (hX : X ⊆ M.E := by aesop_mat) : e ∈ M.closure X ↔ ∀ F, M.IsFlat F → X ⊆ F → e ∈ F := by - simp_rw [M.closure_def' X, mem_sInter, mem_setOf, and_imp] + simp_rw [M.closure_def' X, mem_sInter, mem_ofPred, and_imp] lemma subset_closure_iff_forall_subset_isFlat (X : Set α) (hX : X ⊆ M.E := by aesop_mat) : Y ⊆ M.closure X ↔ ∀ F, M.IsFlat F → X ⊆ F → Y ⊆ F := by - simp_rw [M.closure_def' X, subset_sInter_iff, mem_setOf, and_imp] + simp_rw [M.closure_def' X, subset_sInter_iff, mem_ofPred, and_imp] lemma subset_closure (M : Matroid α) (X : Set α) (hX : X ⊆ M.E := by aesop_mat) : X ⊆ M.closure X := by @@ -317,10 +317,10 @@ section Indep variable {ι : Sort*} {I J B : Set α} {x : α} -lemma Indep.closure_eq_setOf_isBasis_insert (hI : M.Indep I) : +lemma Indep.closure_eq_setOfPred_isBasis_insert (hI : M.Indep I) : M.closure I = {x | M.IsBasis I (insert x I)} := by set F := {x | M.IsBasis I (insert x I)} - have hIF : M.IsBasis I F := hI.isBasis_setOf_insert_isBasis + have hIF : M.IsBasis I F := hI.isBasis_setOfPred_insert_isBasis have hF : M.IsFlat F := by refine ⟨fun J X hJF hJX e heX ↦ show M.IsBasis _ _ from ?_, hIF.subset_ground⟩ exact (hIF.isBasis_of_isBasis_of_subset_of_subset (hJX.isBasis_union hJF) hJF.subset @@ -333,16 +333,19 @@ lemma Indep.closure_eq_setOf_isBasis_insert (hI : M.Indep I) : exact (hF'.1 hJ (he.isBasis_union_of_subset hJ.indep hIJ)) (Or.inr (mem_insert _ _)) exact ⟨hF, inter_subset_left.trans hIF.subset⟩ +@[deprecated (since := "2026-07-09")] +alias Indep.closure_eq_setOf_isBasis_insert := Indep.closure_eq_setOfPred_isBasis_insert + lemma Indep.insert_isBasis_iff_mem_closure (hI : M.Indep I) : M.IsBasis I (insert e I) ↔ e ∈ M.closure I := by - rw [hI.closure_eq_setOf_isBasis_insert, mem_setOf] + rw [hI.closure_eq_setOfPred_isBasis_insert, mem_ofPred] lemma Indep.isBasis_closure (hI : M.Indep I) : M.IsBasis I (M.closure I) := by - rw [hI.closure_eq_setOf_isBasis_insert]; exact hI.isBasis_setOf_insert_isBasis + rw [hI.closure_eq_setOfPred_isBasis_insert]; exact hI.isBasis_setOfPred_insert_isBasis lemma IsBasis.closure_eq_closure (h : M.IsBasis I X) : M.closure I = M.closure X := by refine subset_antisymm (M.closure_subset_closure h.subset) ?_ - rw [← M.closure_closure I, h.indep.closure_eq_setOf_isBasis_insert] + rw [← M.closure_closure I, h.indep.closure_eq_setOfPred_isBasis_insert] exact M.closure_subset_closure fun e he ↦ (h.isBasis_subset (subset_insert _ _) (insert_subset he h.subset)) @@ -363,7 +366,7 @@ lemma IsBasis.isBasis_closure_right (h : M.IsBasis I X) : M.IsBasis I (M.closure lemma Indep.mem_closure_iff (hI : M.Indep I) : x ∈ M.closure I ↔ M.Dep (insert x I) ∨ x ∈ I := by - rwa [hI.closure_eq_setOf_isBasis_insert, mem_setOf, isBasis_insert_iff] + rwa [hI.closure_eq_setOfPred_isBasis_insert, mem_ofPred, isBasis_insert_iff] lemma Indep.mem_closure_iff' (hI : M.Indep I) : x ∈ M.closure I ↔ x ∈ M.E ∧ (M.Indep (insert x I) → x ∈ I) := by diff --git a/Mathlib/Combinatorics/Matroid/Dual.lean b/Mathlib/Combinatorics/Matroid/Dual.lean index 00b03e6b085eda..712df49aec0139 100644 --- a/Mathlib/Combinatorics/Matroid/Dual.lean +++ b/Mathlib/Combinatorics/Matroid/Dual.lean @@ -142,13 +142,15 @@ theorem dual_isBase_iff' : M✶.IsBase B ↔ M.IsBase (M.E \ B) ∧ B ⊆ M.E := (em (B ⊆ M.E)).elim (fun h ↦ by rw [dual_isBase_iff, and_iff_left h]) (fun h ↦ iff_of_false (h ∘ (fun h' ↦ h'.subset_ground)) (h ∘ And.right)) -theorem setOf_dual_isBase_eq : {B | M✶.IsBase B} = (fun X ↦ M.E \ X) '' {B | M.IsBase B} := by +theorem setOfPred_dual_isBase_eq : {B | M✶.IsBase B} = (fun X ↦ M.E \ X) '' {B | M.IsBase B} := by ext B - simp only [mem_setOf_eq, mem_image, dual_isBase_iff'] + simp only [mem_ofPred_eq, mem_image, dual_isBase_iff'] refine ⟨fun h ↦ ⟨_, h.1, sdiff_sdiff_cancel_left h.2⟩, fun ⟨B', hB', h⟩ ↦ ⟨?_,h.symm.trans_subset sdiff_subset⟩⟩ rwa [← h, sdiff_sdiff_cancel_left hB'.subset_ground] +@[deprecated (since := "2026-07-09")] alias setOf_dual_isBase_eq := setOfPred_dual_isBase_eq + @[simp] theorem dual_dual (M : Matroid α) : M✶✶ = M := ext_isBase rfl (fun B (h : B ⊆ M.E) ↦ by rw [dual_isBase_iff, dual_isBase_iff, dual_ground, sdiff_sdiff_cancel_left h]) diff --git a/Mathlib/Combinatorics/Matroid/Loop.lean b/Mathlib/Combinatorics/Matroid/Loop.lean index b77c09817dc236..40f1cb229eabb8 100644 --- a/Mathlib/Combinatorics/Matroid/Loop.lean +++ b/Mathlib/Combinatorics/Matroid/Loop.lean @@ -301,9 +301,12 @@ lemma not_isNonloop_iff (he : e ∈ M.E := by aesop_mat) : ¬M.IsNonloop e ↔ M lemma isNonloop_iff_mem_compl_loops : M.IsNonloop e ↔ e ∈ M.E \ M.loops := by rw [isNonloop_iff, IsLoop, and_comm, mem_sdiff] -lemma setOf_isNonloop_eq (M : Matroid α) : {e | M.IsNonloop e} = M.E \ M.loops := +lemma setOfPred_isNonloop_eq (M : Matroid α) : {e | M.IsNonloop e} = M.E \ M.loops := Set.ext (fun _ ↦ isNonloop_iff_mem_compl_loops) +@[deprecated (since := "2026-07-09")] +alias setOf_isNonloop_eq := setOfPred_isNonloop_eq + lemma not_isNonloop_iff_closure : ¬ M.IsNonloop e ↔ M.closure {e} = M.loops := by by_cases he : e ∈ M.E · simp [isLoop_iff_closure_eq_loops_and_mem_ground, he] @@ -446,9 +449,12 @@ lemma IsNonloop.exists_mem_isCocircuit (he : M.IsNonloop e) : ∃ K, M.IsCocircu exact ⟨_, fundCocircuit_isCocircuit heB hB, mem_fundCocircuit M e B⟩ @[simp] -lemma closure_inter_setOf_isNonloop_eq (M : Matroid α) (X : Set α) : +lemma closure_inter_setOfPred_isNonloop_eq (M : Matroid α) (X : Set α) : M.closure (X ∩ {e | M.IsNonloop e}) = M.closure X := by - rw [setOf_isNonloop_eq, ← inter_sdiff_assoc, closure_sdiff_loops_eq, closure_inter_ground] + rw [setOfPred_isNonloop_eq, ← inter_sdiff_assoc, closure_sdiff_loops_eq, closure_inter_ground] + +@[deprecated (since := "2026-07-09")] +alias closure_inter_setOf_isNonloop_eq := closure_inter_setOfPred_isNonloop_eq end IsNonloop @@ -866,7 +872,7 @@ lemma removeLoops_isBasis'_eq : M.removeLoops.IsBasis' = M.IsBasis' := by @[simp] lemma removeLoops_isNonloop_eq : M.removeLoops.IsNonloop = M.IsNonloop := by ext e - rw [removeLoops_eq_restrict, restrict_isNonloop_iff, mem_setOf, and_self] + rw [removeLoops_eq_restrict, restrict_isNonloop_iff, mem_ofPred, and_self] lemma IsNonloop.removeLoops_isNonloop (he : M.IsNonloop e) : M.removeLoops.IsNonloop e := by simpa diff --git a/Mathlib/Combinatorics/Matroid/Minor/Restrict.lean b/Mathlib/Combinatorics/Matroid/Minor/Restrict.lean index e733e8132f366e..6c3bce215c36ee 100644 --- a/Mathlib/Combinatorics/Matroid/Minor/Restrict.lean +++ b/Mathlib/Combinatorics/Matroid/Minor/Restrict.lean @@ -351,10 +351,13 @@ theorem IsRestriction.finitary {M : Matroid α} [Finitary M] (h : N ≤r M) : N. obtain ⟨R, -, rfl⟩ := h infer_instance -theorem finite_setOf_isRestriction (M : Matroid α) [M.Finite] : {N | N ≤r M}.Finite := +theorem finite_setOfPred_isRestriction (M : Matroid α) [M.Finite] : {N | N ≤r M}.Finite := (M.ground_finite.finite_subsets.image (fun R ↦ M ↾ R)).subset <| by rintro _ ⟨R, hR, rfl⟩; exact ⟨_, hR, rfl⟩ +@[deprecated (since := "2026-07-09")] +alias finite_setOf_isRestriction := finite_setOfPred_isRestriction + theorem Indep.of_isRestriction (hI : N.Indep I) (hNM : N ≤r M) : M.Indep I := by obtain ⟨R, -, rfl⟩ := hNM; exact hI.of_restrict diff --git a/Mathlib/Combinatorics/Quiver/Path/Vertices.lean b/Mathlib/Combinatorics/Quiver/Path/Vertices.lean index 16128af67e2017..9c74b8a36d528e 100644 --- a/Mathlib/Combinatorics/Quiver/Path/Vertices.lean +++ b/Mathlib/Combinatorics/Quiver/Path/Vertices.lean @@ -52,7 +52,7 @@ lemma mem_vertices_cons {a b c : V} (p : Path a b) lemma verticesSet_nil {a : V} : {v | v ∈ (nil : Path a a).vertices} = {a} := by simp only [vertices_nil, mem_singleton, Set.ext_iff, Set.mem_singleton_iff] - exact fun x ↦ Set.mem_setOf + exact fun x ↦ Set.mem_ofPred /-- The length of vertices list equals path length plus one -/ @[simp] diff --git a/Mathlib/Combinatorics/Schnirelmann.lean b/Mathlib/Combinatorics/Schnirelmann.lean index b94c8323ae7098..2fc936fc3e93bd 100644 --- a/Mathlib/Combinatorics/Schnirelmann.lean +++ b/Mathlib/Combinatorics/Schnirelmann.lean @@ -214,19 +214,25 @@ lemma schnirelmannDensity_finite {A : Set ℕ} [DecidablePred (· ∈ A)] (hA : @[simp] lemma schnirelmannDensity_univ : schnirelmannDensity Set.univ = 1 := (schnirelmannDensity_eq_one_iff_of_zero_mem (by simp)).2 (by simp) -lemma schnirelmannDensity_setOf_even : schnirelmannDensity (setOf Even) = 0 := +lemma schnirelmannDensity_setOfPred_even : schnirelmannDensity (Set.ofPred Even) = 0 := schnirelmannDensity_eq_zero_of_one_notMem <| by simp -lemma schnirelmannDensity_setOf_prime : schnirelmannDensity (setOf Nat.Prime) = 0 := +@[deprecated (since := "2026-07-09")] +alias schnirelmannDensity_setOf_even := schnirelmannDensity_setOfPred_even + +lemma schnirelmannDensity_setOfPred_prime : schnirelmannDensity (Set.ofPred Nat.Prime) = 0 := schnirelmannDensity_eq_zero_of_one_notMem <| by simp [Nat.not_prime_one] +@[deprecated (since := "2026-07-09")] +alias schnirelmannDensity_setOf_prime := schnirelmannDensity_setOfPred_prime + set_option backward.isDefEq.respectTransparency false in /-- The Schnirelmann density of the set of naturals which are `1 mod m` is `m⁻¹`, for any `m ≠ 1`. Note that if `m = 1`, this set is empty. -/ -lemma schnirelmannDensity_setOf_mod_eq_one {m : ℕ} (hm : m ≠ 1) : +lemma schnirelmannDensity_setOfPred_mod_eq_one {m : ℕ} (hm : m ≠ 1) : schnirelmannDensity {n | n % m = 1} = (m⁻¹ : ℝ) := by rcases m.eq_zero_or_pos with rfl | hm' · simp only [Nat.cast_zero, inv_zero] @@ -235,7 +241,7 @@ lemma schnirelmannDensity_setOf_mod_eq_one {m : ℕ} (hm : m ≠ 1) : apply le_antisymm (schnirelmannDensity_le_of_le m hm'.ne' _) _ · rw [← one_div, ← @Nat.cast_one ℝ] gcongr - simp only [Set.mem_setOf_eq, card_le_one_iff_subset_singleton, subset_iff, + simp only [Set.mem_ofPred_eq, card_le_one_iff_subset_singleton, subset_iff, mem_filter, mem_Ioc, mem_singleton, and_imp] use 1 intro x _ hxm h @@ -244,7 +250,7 @@ lemma schnirelmannDensity_setOf_mod_eq_one {m : ℕ} (hm : m ≠ 1) : rwa [Nat.mod_eq_of_lt hxm'] at h rw [le_schnirelmannDensity_iff] intro n hn - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] have : (Icc 0 ((n - 1) / m)).image (· * m + 1) ⊆ {x ∈ Ioc 0 n | x % m = 1} := by simp only [subset_iff, mem_image, forall_exists_index, mem_filter, mem_Ioc, mem_Icc, and_imp] rintro _ y _ hy' rfl @@ -261,17 +267,26 @@ lemma schnirelmannDensity_setOf_mod_eq_one {m : ℕ} (hm : m ≠ 1) : intro a b simp [hm'.ne'] -lemma schnirelmannDensity_setOf_modeq_one {m : ℕ} : +@[deprecated (since := "2026-07-09")] +alias schnirelmannDensity_setOf_mod_eq_one := schnirelmannDensity_setOfPred_mod_eq_one + +lemma schnirelmannDensity_setOfPred_modeq_one {m : ℕ} : schnirelmannDensity {n | n ≡ 1 [MOD m]} = (m⁻¹ : ℝ) := by rcases eq_or_ne m 1 with rfl | hm · simp [Nat.modEq_one] - rw [← schnirelmannDensity_setOf_mod_eq_one hm] + rw [← schnirelmannDensity_setOfPred_mod_eq_one hm] simp [Nat.ModEq, Nat.one_mod_eq_one.mpr hm] -lemma schnirelmannDensity_setOf_Odd : schnirelmannDensity (setOf Odd) = 2⁻¹ := by - have h : setOf Odd = {n | n % 2 = 1} := Set.ext fun _ => Nat.odd_iff +@[deprecated (since := "2026-07-09")] +alias schnirelmannDensity_setOf_modeq_one := schnirelmannDensity_setOfPred_modeq_one + +lemma schnirelmannDensity_setOfPred_Odd : schnirelmannDensity (Set.ofPred Odd) = 2⁻¹ := by + have h : Set.ofPred Odd = {n | n % 2 = 1} := Set.ext fun _ => Nat.odd_iff simp only [h] - rw [schnirelmannDensity_setOf_mod_eq_one (by norm_num1), Nat.cast_two] + rw [schnirelmannDensity_setOfPred_mod_eq_one (by norm_num1), Nat.cast_two] + +@[deprecated (since := "2026-07-09")] +alias schnirelmannDensity_setOf_Odd := schnirelmannDensity_setOfPred_Odd open scoped Pointwise diff --git a/Mathlib/Combinatorics/SetFamily/Shatter.lean b/Mathlib/Combinatorics/SetFamily/Shatter.lean index ddfc1fc015a6ea..28620ab66940e5 100644 --- a/Mathlib/Combinatorics/SetFamily/Shatter.lean +++ b/Mathlib/Combinatorics/SetFamily/Shatter.lean @@ -120,7 +120,7 @@ lemma card_le_card_shatterer (𝒜 : Finset (Finset α)) : #𝒜 ≤ #𝒜.shatt ((memberSubfamily a 𝒜).shatterer ∩ (nonMemberSubfamily a 𝒜).shatterer).image (insert a) have hℬ : #ℬ = #((memberSubfamily a 𝒜).shatterer ∩ (nonMemberSubfamily a 𝒜).shatterer) := by refine card_image_of_injOn <| insert_erase_invOn.2.injOn.mono ?_ - simp only [coe_inter, Set.subset_def, Set.mem_inter_iff, mem_coe, Set.mem_setOf_eq, and_imp, + simp only [coe_inter, Set.subset_def, Set.mem_inter_iff, mem_coe, Set.mem_ofPred_eq, and_imp, mem_shatterer] exact fun s _ ↦ aux (fun t ht ↦ (mem_filter.1 ht).2) rw [← card_memberSubfamily_add_card_nonMemberSubfamily a] diff --git a/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean b/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean index 4809d9d772754b..888a5b33f51d26 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Bipartite.lean @@ -106,7 +106,7 @@ theorem IsBipartiteWith.mem_of_mem_adj theorem isBipartiteWith_neighborSet (h : G.IsBipartiteWith s t) (hv : v ∈ s) : G.neighborSet v = { w ∈ t | G.Adj v w } := by ext w - rw [mem_neighborSet, Set.mem_setOf_eq, iff_and_self] + rw [mem_neighborSet, Set.mem_ofPred_eq, iff_and_self] exact h.mem_of_mem_adj hv /-- If `G.IsBipartiteWith s t` and `v ∈ s`, then the neighbor set of `v` is a subset of `t`. -/ @@ -132,7 +132,7 @@ theorem IsBipartiteWith.mem_of_mem_adj' theorem isBipartiteWith_neighborSet' (h : G.IsBipartiteWith s t) (hw : w ∈ t) : G.neighborSet w = { v ∈ s | G.Adj v w } := by ext v - rw [mem_neighborSet, adj_comm, Set.mem_setOf_eq, iff_and_self] + rw [mem_neighborSet, adj_comm, Set.mem_ofPred_eq, iff_and_self] exact h.mem_of_mem_adj' hw /-- If `G.IsBipartiteWith s t` and `w ∈ t`, then the neighbor set of `w` is a subset of `s`. -/ @@ -292,7 +292,7 @@ lemma IsBipartite.exists_isBipartiteWith (h : G.IsBipartite) : ∃ s t, G.IsBipa refine ⟨{v | c v = 0}, {v | c v = 1}, by aesop (add simp [Set.disjoint_left]), ?_⟩ rintro v w hvw apply hc at hvw - simp [Set.mem_setOf_eq] at hvw ⊢ + simp [Set.mem_ofPred_eq] at hvw ⊢ lia /-- If a simple graph `G` has a bipartition, then it is bipartite. -/ @@ -417,7 +417,7 @@ in `G`. -/ lemma neighborSet_subset_between_union (hv : v ∈ s) : G.neighborSet v ⊆ (G.between s sᶜ).neighborSet v ∪ s := by intro w hadj - rw [neighborSet, Set.mem_union, Set.mem_setOf, between_adj] + rw [neighborSet, Set.mem_union, Set.mem_ofPred, between_adj] by_cases hw : w ∈ s · exact Or.inr hw · exact Or.inl ⟨hadj, Or.inl ⟨hv, hw⟩⟩ @@ -427,7 +427,7 @@ in `G`. -/ lemma neighborSet_subset_between_union_compl (hw : w ∈ sᶜ) : G.neighborSet w ⊆ (G.between s sᶜ).neighborSet w ∪ sᶜ := by intro v hadj - rw [neighborSet, Set.mem_union, Set.mem_setOf, between_adj] + rw [neighborSet, Set.mem_union, Set.mem_ofPred, between_adj] by_cases hv : v ∈ s · exact Or.inl ⟨hadj, Or.inr ⟨hw, hv⟩⟩ · exact Or.inr hv diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/EdgeLabeling.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/EdgeLabeling.lean index 0be490abb605b8..4f0e21ad25acdb 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/EdgeLabeling.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/EdgeLabeling.lean @@ -141,7 +141,7 @@ def labelGraph (C : EdgeLabeling G K) (k : K) : SimpleGraph V := theorem labelGraph_adj {C : EdgeLabeling G K} {k : K} (x y : V) : (C.labelGraph k).Adj x y ↔ ∃ H : G.Adj x y, C ⟨s(x, y), H⟩ = k := by rw [EdgeLabeling.labelGraph] - simp only [mem_edgeSet, fromEdgeSet_adj, Set.mem_setOf_eq, Ne.eq_def] + simp only [mem_edgeSet, fromEdgeSet_adj, Set.mem_ofPred_eq, Ne.eq_def] grind [Adj.ne] instance [DecidableRel G.Adj] [DecidableEq K] (k : K) {C : EdgeLabeling G K} : diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean index 02d84e2d92cf0f..649280b8e6034b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean @@ -216,7 +216,7 @@ variable (G) in This is `⊤` (infinity) iff `G` isn't colorable with finitely many colors. If `G` is colorable, then `ENat.toNat G.chromaticNumber` is the `ℕ`-valued chromatic number. -/ -noncomputable def chromaticNumber : ℕ∞ := ⨅ n ∈ setOf G.Colorable, (n : ℕ∞) +noncomputable def chromaticNumber : ℕ∞ := ⨅ n ∈ Set.ofPred G.Colorable, (n : ℕ∞) lemma le_chromaticNumber_iff_colorable : n ≤ G.chromaticNumber ↔ ∀ m, G.Colorable m → n ≤ m := by simp [chromaticNumber] @@ -230,7 +230,7 @@ lemma le_chromaticNumber_of_pairwise_adj (hn : n ≤ Nat.card ι) (f : ι → V) le_chromaticNumber_iff_colorable.2 fun _m hm ↦ hn.trans <| hm.card_le_of_pairwise_adj f hf variable (G) in -lemma chromaticNumber_eq_biInf : G.chromaticNumber = ⨅ n ∈ setOf G.Colorable, (n : ℕ∞) := rfl +lemma chromaticNumber_eq_biInf : G.chromaticNumber = ⨅ n ∈ Set.ofPred G.Colorable, (n : ℕ∞) := rfl variable (G) in lemma chromaticNumber_eq_iInf : G.chromaticNumber = ⨅ n : {m | G.Colorable m}, (n : ℕ∞) := by @@ -343,7 +343,7 @@ theorem chromaticNumber_le_iff_colorable {n : ℕ} : G.chromaticNumber ≤ n ↔ obtain ⟨m, hm⟩ := this rw [hm.chromaticNumber_eq_sInf, Nat.cast_le] at h have := Nat.sInf_mem (⟨m, hm⟩ : {n' | G.Colorable n'}.Nonempty) - rw [Set.mem_setOf_eq] at this + rw [Set.mem_ofPred_eq] at this exact this.mono h /-- If the chromatic number of `G` is `n + 1`, then `G` is colorable in no fewer than `n + 1` @@ -400,7 +400,7 @@ theorem chromaticNumber_le_of_forall_imp {V' : Type*} {G' : SimpleGraph V'} (h : ∀ n, G'.Colorable n → G.Colorable n) : G.chromaticNumber ≤ G'.chromaticNumber := by rw [chromaticNumber, chromaticNumber] - simp only [Set.mem_setOf_eq, le_iInf_iff] + simp only [Set.mem_ofPred_eq, le_iInf_iff] intro m hc have := h _ hc rw [← chromaticNumber_le_iff_colorable] at this @@ -424,7 +424,7 @@ lemma card_le_chromaticNumber_iff_forall_surjective [Fintype α] : classical exact Nat.notMem_of_lt_sInf ((Nat.sub_one_lt_of_lt <| card_pos_iff.2 ⟨i⟩).trans_le h) ⟨G.recolorOfEquiv (equivOfCardEq <| by simp) D⟩ - · simp only [chromaticNumber, Set.mem_setOf_eq, le_iInf_iff, Nat.cast_le] + · simp only [chromaticNumber, Set.mem_ofPred_eq, le_iInf_iff, Nat.cast_le] rintro i ⟨C⟩ contrapose! h refine ⟨G.recolorOfCardLE (by simpa using h.le) C, fun hC ↦ ?_⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean index 53affe3aef7695..35f4e56f97f626 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Connected.lean @@ -552,7 +552,7 @@ def supp (C : G.ConnectedComponent) := theorem supp_injective : Function.Injective (ConnectedComponent.supp : G.ConnectedComponent → Set V) := by refine ConnectedComponent.ind₂ ?_ - simp only [ConnectedComponent.supp, Set.ext_iff, ConnectedComponent.eq, Set.mem_setOf_eq] + simp only [ConnectedComponent.supp, Set.ext_iff, ConnectedComponent.eq, Set.mem_ofPred_eq] intro v w h rw [reachable_comm, h] diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean index 83a7a8ec794002..f45691b3dd8dec 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Finite.lean @@ -98,7 +98,7 @@ lemma ConnectedComponent.odd_oddComponents_ncard_subset_supp [Finite V] {G'} rw [Finset.odd_sum_iff_odd_card_odd, Nat.card_eq_fintype_card, Fintype.card_ofFinset] congr! 2 ext c - simp_rw [Set.toFinset_setOf, mem_filter, ← Set.ncard_coe_finset, coe_filter, + simp_rw [Set.toFinset_ofPred, mem_filter, ← Set.ncard_coe_finset, coe_filter, mem_supp_iff, mem_univ, true_and, supp, and_comm] lemma odd_ncard_oddComponents [Finite V] : Odd G.oddComponents.ncard ↔ Odd (Nat.card V) := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean index 5d25f8c3a90171..63f934c130fcba 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean @@ -399,8 +399,8 @@ lemma neighborSet_toSubgraph_internal {u} {i : ℕ} {p : G.Walk u v} (hp : p.IsP Prod.swap_prod_mk] refine ⟨?_, by aesop⟩ rintro ⟨i', ⟨hl, _⟩ | ⟨_, hl⟩⟩ <;> - apply hp.getVert_injOn (by rw [Set.mem_setOf_eq]; lia) - (by rw [Set.mem_setOf_eq]; lia) at hl <;> aesop + apply hp.getVert_injOn (by rw [Set.mem_ofPred_eq]; lia) + (by rw [Set.mem_ofPred_eq]; lia) at hl <;> aesop lemma ncard_neighborSet_toSubgraph_internal_eq_two {u} {i : ℕ} {p : G.Walk u v} (hp : p.IsPath) (h : i ≠ 0) (h' : i < p.length) : @@ -408,7 +408,7 @@ lemma ncard_neighborSet_toSubgraph_internal_eq_two {u} {i : ℕ} {p : G.Walk u v rw [hp.neighborSet_toSubgraph_internal h h'] have : p.getVert (i - 1) ≠ p.getVert (i + 1) := by intro h - have := hp.getVert_injOn (by rw [Set.mem_setOf_eq]; lia) (by rw [Set.mem_setOf_eq]; lia) h + have := hp.getVert_injOn (by rw [Set.mem_ofPred_eq]; lia) (by rw [Set.mem_ofPred_eq]; lia) h lia simp_all @@ -418,11 +418,11 @@ lemma snd_of_toSubgraph_adj {u v v'} {p : G.Walk u v} (hp : p.IsPath) simp only [Sym2.eq, Sym2.rel_iff', Prod.mk.injEq, Prod.swap_prod_mk] at hi rcases hi.1 with ⟨hl1, rfl⟩ | ⟨hr1, hr2⟩ · have : i = 0 := by - apply hp.getVert_injOn (by rw [Set.mem_setOf]; lia) (by rw [Set.mem_setOf]; lia) + apply hp.getVert_injOn (by rw [Set.mem_ofPred]; lia) (by rw [Set.mem_ofPred]; lia) rw [p.getVert_zero, hl1] simp [this] · have : i + 1 = 0 := by - apply hp.getVert_injOn (by rw [Set.mem_setOf]; lia) (by rw [Set.mem_setOf]; lia) + apply hp.getVert_injOn (by rw [Set.mem_ofPred]; lia) (by rw [Set.mem_ofPred]; lia) rw [p.getVert_zero, hr2] contradiction @@ -449,11 +449,11 @@ lemma neighborSet_toSubgraph_internal {u} {i : ℕ} {p : G.Walk u u} (hpc : p.Is Prod.swap_prod_mk] refine ⟨?_, by aesop⟩ rintro ⟨i', ⟨hl1, hl2⟩ | ⟨hr1, hr2⟩⟩ - · apply hpc.getVert_injOn' (by rw [Set.mem_setOf_eq]; lia) - (by rw [Set.mem_setOf_eq]; lia) at hl1 + · apply hpc.getVert_injOn' (by rw [Set.mem_ofPred_eq]; lia) + (by rw [Set.mem_ofPred_eq]; lia) at hl1 simp_all - · apply hpc.getVert_injOn (by rw [Set.mem_setOf_eq]; lia) - (by rw [Set.mem_setOf_eq]; lia) at hr2 + · apply hpc.getVert_injOn (by rw [Set.mem_ofPred_eq]; lia) + (by rw [Set.mem_ofPred_eq]; lia) at hr2 aesop lemma ncard_neighborSet_toSubgraph_eq_two {u v} {p : G.Walk u u} (hpc : p.IsCycle) @@ -653,7 +653,7 @@ lemma extend_finset_to_connected (Gpc : G.Preconnected) {t : Finset V} (tn : t.N exact ⟨v, vt, Walk.end_mem_support _⟩ · apply G.induce_connected_of_patches u · simp only [Finset.coe_biUnion, Finset.mem_coe, List.coe_toFinset, Set.mem_iUnion, - Set.mem_setOf_eq, Walk.start_mem_support, exists_prop, and_true] + Set.mem_ofPred_eq, Walk.start_mem_support, exists_prop, and_true] exact ⟨u, ut⟩ intro v hv simp only [Finset.mem_coe, Finset.mem_biUnion, List.mem_toFinset] at hv @@ -661,7 +661,7 @@ lemma extend_finset_to_connected (Gpc : G.Preconnected) {t : Finset V} (tn : t.N refine ⟨{x | x ∈ (Gpc u w).some.support}, ?_, ?_⟩ · simp only [Finset.coe_biUnion, Finset.mem_coe, List.coe_toFinset] exact fun x xw => Set.mem_iUnion₂.mpr ⟨w, wt, xw⟩ - · simp only [Set.mem_setOf_eq, Walk.start_mem_support, exists_true_left] + · simp only [Set.mem_ofPred_eq, Walk.start_mem_support, exists_true_left] refine ⟨hw, Walk.connected_induce_support _ _ _⟩ end induced_subgraphs diff --git a/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean b/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean index 5e901085b73c54..e5f24b77358f5b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean +++ b/Mathlib/Combinatorics/SimpleGraph/DeleteEdges.lean @@ -194,7 +194,7 @@ theorem edgeFinset_deleteIncidenceSet_eq_filter (G : SimpleGraph V) [DecidableRe apply filter_congr intro _ h rw [incidenceFinset, Set.mem_toFinset, incidenceSet, - Set.mem_setOf_eq, not_and, Classical.imp_iff_right_iff] + Set.mem_ofPred_eq, not_and, Classical.imp_iff_right_iff] left rwa [mem_edgeFinset] at h diff --git a/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean b/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean index b80d0ee12f580f..84ba2f29c26f04 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Ends/Defs.lean @@ -44,7 +44,7 @@ theorem ComponentCompl.supp_injective : Function.Injective (ComponentCompl.supp : G.ComponentCompl K → Set V) := by refine ConnectedComponent.ind₂ ?_ rintro ⟨v, hv⟩ ⟨w, hw⟩ h - simp only [Set.ext_iff, ConnectedComponent.eq, Set.mem_setOf_eq, ComponentCompl.supp] at h ⊢ + simp only [Set.ext_iff, ConnectedComponent.eq, Set.mem_ofPred_eq, ComponentCompl.supp] at h ⊢ exact ((h v).mp ⟨hv, Reachable.refl _⟩).choose_spec theorem ComponentCompl.supp_inj {C D : G.ComponentCompl K} : C.supp = D.supp ↔ C = D := @@ -242,7 +242,7 @@ instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K have : Finite (Set.range touch) := by refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _ apply Set.Finite.ofFinset (K.biUnion (fun v => G.neighborFinset v)) - simp only [Finset.mem_biUnion, mem_neighborFinset, Set.mem_setOf_eq, implies_true] + simp only [Finset.mem_biUnion, mem_neighborFinset, Set.mem_ofPred_eq, implies_true] -- hence `touch` has a finite domain apply Finite.of_injective_finite_range touch_inj diff --git a/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean b/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean index 55db378c1b866e..8c4a27ca168058 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean @@ -88,9 +88,12 @@ lemma IsHamiltonian.toFinset_support (hp : p.IsHamiltonian) : p.support.toFinset alias IsHamiltonian.support_toFinset := IsHamiltonian.toFinset_support omit [Fintype α] in -theorem IsHamiltonian.setOf_support (hp : p.IsHamiltonian) : {v | v ∈ p.support} = Set.univ := +theorem IsHamiltonian.setOfPred_support (hp : p.IsHamiltonian) : {v | v ∈ p.support} = Set.univ := Set.eq_univ_iff_forall.mpr hp.mem_support +@[deprecated (since := "2026-07-09")] +alias IsHamiltonian.setOf_support := IsHamiltonian.setOfPred_support + /-- The length of a Hamiltonian path is one less than the number of vertices of the graph. -/ lemma IsHamiltonian.length_eq (hp : p.IsHamiltonian) : p.length = Fintype.card α - 1 := eq_tsub_of_add_eq <| by @@ -129,7 +132,7 @@ theorem IsHamiltonian.getVert_surjective (hp : p.IsHamiltonian) : p.getVert.Surj omit [DecidableEq β] in theorem IsHamiltonian.injective_of_isPath_map (hp : p.IsHamiltonian) (h : (p.map f).IsPath) : Function.Injective f := by - rw [← Set.injOn_univ, ← hp.setOf_support] + rw [← Set.injOn_univ, ← hp.setOfPred_support] exact h.injOn_support_of_isPath_map lemma isHamiltonian_iff_isPath_and_length_eq [Fintype α] : diff --git a/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean b/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean index c7b9d842835dd3..2f0954cc3d7bb1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean +++ b/Mathlib/Combinatorics/SimpleGraph/LapMatrix.lean @@ -55,7 +55,7 @@ theorem isHermitian_adjMatrix [NonAssocSemiring R] [StarRing R] : (G.adjMatrix R theorem degree_eq_sum_if_adj {R : Type*} [AddCommMonoidWithOne R] (i : V) : (G.degree i : R) = ∑ j : V, if G.Adj i j then 1 else 0 := by unfold degree neighborFinset neighborSet - rw [sum_boole, Set.toFinset_setOf] + rw [sum_boole, Set.toFinset_ofPred] variable [DecidableEq V] diff --git a/Mathlib/Combinatorics/SimpleGraph/Matching.lean b/Mathlib/Combinatorics/SimpleGraph/Matching.lean index 7c54148c2b2dc7..c9d74a816849cf 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Matching.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Matching.lean @@ -222,11 +222,11 @@ theorem IsMatching.verts_eq_biUnion_edgeSet {M : G.Subgraph} (h : M.IsMatching) exact ⟨s(v, u), he, Sym2.mem_mk_left ..⟩ · exact mem_verts_of_mem_edge he hv -theorem IsMatching.injOn_edgeSet : (setOf IsMatching).InjOn (edgeSet (G := G)) := by +theorem IsMatching.injOn_edgeSet : (Set.ofPred IsMatching).InjOn (edgeSet (G := G)) := by refine fun M₁ h₁ M₂ h₂ h ↦ Subgraph.ext ?_ <| Sym2.fromRel_eq_fromRel_iff_eq .. |>.mp h rw [h₁.verts_eq_biUnion_edgeSet, h₂.verts_eq_biUnion_edgeSet, h] -theorem IsMatching.strictMonoOn_edgeSet : StrictMonoOn (edgeSet (G := G)) (setOf IsMatching) := +theorem IsMatching.strictMonoOn_edgeSet : StrictMonoOn (edgeSet (G := G)) (Set.ofPred IsMatching) := edgeSet_monotone.monotoneOn _ |>.strictMonoOn_of_injOn injOn_edgeSet /-- diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index c6aae21f0c7167..79e6744c252548 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -426,7 +426,7 @@ lemma IsPath.getVert_injOn {p : G.Walk u v} (hp : p.IsPath) : induction p generalizing n m with | nil => simp_all | @cons v w u h p ihp => - simp only [length_cons, Set.mem_setOf_eq] at hn hm hnm + simp only [length_cons, Set.mem_ofPred_eq] at hn hm hnm by_cases hn0 : n = 0 <;> by_cases hm0 : m = 0 · lia · simp only [hn0, getVert_zero, Walk.getVert_cons p h hm0] at hnm @@ -444,7 +444,7 @@ lemma IsPath.getVert_eq_start_iff_of_not_nil {i : ℕ} {p : G.Walk u w} (hp : p. p.getVert i = u ↔ i = 0 := by refine ⟨fun h ↦ ?_, by simp_all⟩ by_cases h' : i ≤ p.length - · apply hp.getVert_injOn (by rw [Set.mem_setOf]; lia) (by rw [Set.mem_setOf]; lia) + · apply hp.getVert_injOn (by rw [Set.mem_ofPred]; lia) (by rw [Set.mem_ofPred]; lia) simp [h] · rw [p.getVert_of_length_le (le_of_not_ge h')] at h subst h @@ -473,7 +473,7 @@ lemma IsPath.getVert_injOn_iff (p : G.Walk u v) : Set.InjOn p.getVert {i | i ≤ rw [cons_isPath_iff] refine ⟨ih (by intro n hn m hm hnm - simp only [Set.mem_setOf_eq] at hn hm + simp only [Set.mem_ofPred_eq] at hn hm have := hinj (by rw [length_cons]; lia : n + 1 ≤ (q.cons h).length) (by rw [length_cons]; lia : m + 1 ≤ (q.cons h).length) @@ -516,7 +516,7 @@ lemma IsCycle.getVert_injOn {p : G.Walk u u} (hpc : p.IsCycle) : rw [← p.cons_tail_eq hpc.not_nil] at hpc intro n hn m hm hnm rw [← SimpleGraph.Walk.length_tail_add_one - (p.not_nil_of_tail_not_nil (not_nil_of_isCycle_cons hpc)), Set.mem_setOf] at hn hm + (p.not_nil_of_tail_not_nil (not_nil_of_isCycle_cons hpc)), Set.mem_ofPred] at hn hm have := ((Walk.cons_isCycle_iff _ _).mp hpc).1.getVert_injOn (by lia : n - 1 ≤ p.tail.length) (by lia : m - 1 ≤ p.tail.length) (by simp_all) @@ -525,11 +525,11 @@ lemma IsCycle.getVert_injOn {p : G.Walk u u} (hpc : p.IsCycle) : lemma IsCycle.getVert_injOn' {p : G.Walk u u} (hpc : p.IsCycle) : Set.InjOn p.getVert {i | i ≤ p.length - 1} := by intro n hn m hm hnm - simp only [Set.mem_setOf_eq] at * + simp only [Set.mem_ofPred_eq] at * have := hpc.three_le_length have : p.length - n = p.length - m := Walk.length_reverse _ ▸ hpc.reverse.getVert_injOn - (by simp only [Walk.length_reverse, Set.mem_setOf_eq]; lia) - (by simp only [Walk.length_reverse, Set.mem_setOf_eq]; lia) + (by simp only [Walk.length_reverse, Set.mem_ofPred_eq]; lia) + (by simp only [Walk.length_reverse, Set.mem_ofPred_eq]; lia) (by simp [Walk.getVert_reverse, show p.length - (p.length - n) = n by lia, hnm, show p.length - (p.length - m) = m by lia]) lia @@ -545,8 +545,8 @@ lemma IsCycle.getVert_endpoint_iff {i : ℕ} {p : G.Walk u u} (hpc : p.IsCycle) refine ⟨?_, by aesop⟩ rw [or_iff_not_imp_left] intro h hi - exact hpc.getVert_injOn (by simp only [Set.mem_setOf_eq]; lia) - (by simp only [Set.mem_setOf_eq]; lia) (h.symm ▸ (Walk.getVert_length p).symm) + exact hpc.getVert_injOn (by simp only [Set.mem_ofPred_eq]; lia) + (by simp only [Set.mem_ofPred_eq]; lia) (h.symm ▸ (Walk.getVert_length p).symm) lemma IsCycle.getVert_sub_one_ne_getVert_add_one {i : ℕ} {p : G.Walk u u} (hpc : p.IsCycle) (h : i ≤ p.length) : p.getVert (i - 1) ≠ p.getVert (i + 1) := by @@ -556,8 +556,8 @@ lemma IsCycle.getVert_sub_one_ne_getVert_add_one {i : ℕ} {p : G.Walk u u} (hpc · rw [p.getVert_of_length_le (by lia : p.length ≤ i + 1), hpc.getVert_endpoint_iff (by lia)] at h' lia - have := hpc.getVert_injOn' (by simp only [Set.mem_setOf_eq, Nat.sub_le_iff_le_add]; lia) - (by simp only [Set.mem_setOf_eq]; lia) h' + have := hpc.getVert_injOn' (by simp only [Set.mem_ofPred_eq, Nat.sub_le_iff_le_add]; lia) + (by simp only [Set.mem_ofPred_eq]; lia) h' lia theorem isCycle_iff_isPath_tail_and_le_length {p : G.Walk u u} : @@ -643,7 +643,7 @@ lemma endpoint_notMem_support_takeUntil {p : G.Walk u v} (hp : p.IsPath) (hw : w obtain ⟨n, ⟨hn, hnl⟩⟩ := hv rw [getVert_takeUntil hw hnl] at hn have := p.length_takeUntil_lt_length hw h.symm - have : n = p.length := hp.getVert_injOn (by rw [Set.mem_setOf]; lia) (by simp) + have : n = p.length := hp.getVert_injOn (by rw [Set.mem_ofPred]; lia) (by simp) (hn.symm ▸ p.getVert_length.symm) lia diff --git a/Mathlib/Combinatorics/SimpleGraph/Triangle/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Triangle/Basic.lean index 61f15e3e39a34e..3d2191e25b5802 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Triangle/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Triangle/Basic.lean @@ -95,7 +95,7 @@ lemma edgeDisjointTriangles_iff_mem_sym2_subsingleton : = {s | G.Adj a b ∧ ∃ c, G.Adj a c ∧ G.Adj b c ∧ s = {a, b, c}} := by ext s simp only [mem_sym2_iff, Sym2.mem_iff, forall_eq_or_imp, forall_eq, - mem_cliqueSet_iff, Set.mem_setOf_eq, + mem_cliqueSet_iff, Set.mem_ofPred_eq, is3Clique_iff] constructor · rintro ⟨⟨c, d, e, hcd, hce, hde, rfl⟩, hab⟩ @@ -154,7 +154,7 @@ lemma EdgeDisjointTriangles.card_edgeFinset_le (hG : G.EdgeDisjointTriangles) : rw [← this] refine card_mono ?_ simp [insert_subset, *] - · simpa only [card_le_one, mem_bipartiteBelow, and_imp, Set.Subsingleton, Set.mem_setOf_eq, + · simpa only [card_le_one, mem_bipartiteBelow, and_imp, Set.Subsingleton, Set.mem_ofPred_eq, mem_cliqueFinset_iff, mem_cliqueSet_iff] using hG.mem_sym2_subsingleton (G.not_isDiag_of_mem_edgeSet <| mem_edgeFinset.1 he) diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean index 515384b6880def..7500d2d91af7e0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean @@ -32,20 +32,26 @@ namespace SimpleGraph variable {V : Type u} (G : SimpleGraph V) -theorem Walk.setOf_length_eq_zero (u : V) : {p : G.Walk u u | p.length = 0} = {.nil} := by +theorem Walk.setOfPred_length_eq_zero (u : V) : {p : G.Walk u u | p.length = 0} = {.nil} := by simp [Walk.length_eq_zero_iff, ← Walk.eq_nil_iff_nil] +@[deprecated (since := "2026-07-09")] +alias Walk.setOf_length_eq_zero := Walk.setOfPred_length_eq_zero + @[deprecated (since := "2026-05-12")] -alias set_walk_self_length_zero_eq := Walk.setOf_length_eq_zero +alias set_walk_self_length_zero_eq := Walk.setOfPred_length_eq_zero -theorem Walk.setOf_length_eq_zero_of_ne {u v : V} (h : u ≠ v) : +theorem Walk.setOfPred_length_eq_zero_of_ne {u v : V} (h : u ≠ v) : {p : G.Walk u v | p.length = 0} = ∅ := Set.eq_empty_of_forall_notMem (h <| ·.eq_of_length_eq_zero ·) +@[deprecated (since := "2026-07-09")] +alias Walk.setOf_length_eq_zero_of_ne := Walk.setOfPred_length_eq_zero_of_ne + @[deprecated (since := "2026-05-12")] -alias set_walk_length_zero_eq_of_ne := Walk.setOf_length_eq_zero_of_ne +alias set_walk_length_zero_eq_of_ne := Walk.setOfPred_length_eq_zero_of_ne -theorem Walk.setOf_length_eq_add_one (u v : V) (n : ℕ) : +theorem Walk.setOfPred_length_eq_add_one (u v : V) (n : ℕ) : {p : G.Walk u v | p.length = n + 1} = ⋃ (w : V) (h : G.Adj u w), Walk.cons h '' {p' : G.Walk w v | p'.length = n} := by ext p @@ -53,7 +59,11 @@ theorem Walk.setOf_length_eq_add_one (u v : V) (n : ℕ) : | nil => simp [eq_comm] | cons huw pwv => grind [length_cons, Set.mem_iUnion] -@[deprecated (since := "2026-05-12")] alias set_walk_length_succ_eq := Walk.setOf_length_eq_add_one +@[deprecated (since := "2026-07-09")] +alias Walk.setOf_length_eq_add_one := Walk.setOfPred_length_eq_add_one + +@[deprecated (since := "2026-05-12")] +alias set_walk_length_succ_eq := Walk.setOfPred_length_eq_add_one /-- Walks of length two from `u` to `v` correspond bijectively to common neighbours of `u` and `v`. Note that `u` and `v` may be the same. -/ @@ -92,8 +102,8 @@ theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) : induction n generalizing u v with | zero => grind [finsetWalkLength, Walk.length_eq_zero_iff, Walk.eq_nil_iff_nil, Walk.Nil.eq] | succ n ih => - simp only [finsetWalkLength, Walk.setOf_length_eq_add_one, Finset.coe_biUnion, Finset.mem_coe, - Finset.mem_univ, Set.iUnion_true, Finset.coe_map, Set.iUnion_coe_set] + simp only [finsetWalkLength, Walk.setOfPred_length_eq_add_one, Finset.coe_biUnion, + Finset.mem_coe, Finset.mem_univ, Set.iUnion_true, Finset.coe_map, Set.iUnion_coe_set] congr! grind diff --git a/Mathlib/Computability/DFA.lean b/Mathlib/Computability/DFA.lean index d4c2d06f5c3e19..4dfab27f64c4e5 100644 --- a/Mathlib/Computability/DFA.lean +++ b/Mathlib/Computability/DFA.lean @@ -307,7 +307,7 @@ theorem acceptsFrom_union (M1 : DFA α σ1) (M2 : DFA α σ2) (s1 : σ1) (s2 : ext x simp only [acceptsFrom] rw [Language.add_def, Set.mem_union] - simp_rw [↑Set.mem_setOf] + simp_rw [↑Set.mem_ofPred] induction x generalizing s1 s2 with | nil => simp | cons a x ih => simp only [evalFrom_cons, union_step, ih] @@ -336,7 +336,7 @@ theorem acceptsFrom_inter (s1 : σ1) (s2 : σ2) : (M1.inter M2).acceptsFrom (s1, s2) = M1.acceptsFrom s1 ⊓ M2.acceptsFrom s2 := by ext x simp only [acceptsFrom, Language.mem_inf] - simp_rw [↑Set.mem_setOf] + simp_rw [↑Set.mem_ofPred] induction x generalizing s1 s2 with | nil => simp | cons a x ih => simp only [evalFrom_cons, inter_step, ih] diff --git a/Mathlib/Computability/NFA.lean b/Mathlib/Computability/NFA.lean index 4a01150be85432..d6b094d5262e81 100644 --- a/Mathlib/Computability/NFA.lean +++ b/Mathlib/Computability/NFA.lean @@ -207,7 +207,7 @@ theorem acceptsFrom_iUnion {ι : Sort*} (s : ι → Set σ) : M.acceptsFrom (⋃ i, s i) = ⋃ i, M.acceptsFrom (s i) := by ext x simp only [acceptsFrom, evalFrom_iUnion, mem_iUnion] - simp_rw [↑mem_iUnion, ↑mem_setOf_eq]; tauto + simp_rw [↑mem_iUnion, ↑mem_ofPred_eq]; tauto set_option backward.isDefEq.respectTransparency false in variable (M) in @@ -220,10 +220,10 @@ variable (M) in private theorem mem_acceptsFrom_sep_fact {S : Set σ} {p : Prop} {x : List α} : x ∈ M.acceptsFrom {s ∈ S | p} ↔ x ∈ M.acceptsFrom S ∧ p := by induction x generalizing S with - | nil => simp only [nil_mem_acceptsFrom, mem_setOf_eq]; tauto + | nil => simp only [nil_mem_acceptsFrom, mem_ofPred_eq]; tauto | cons a x ih => have h : M.stepSet {s ∈ S | p} a = {s ∈ M.stepSet S a | p} := by - ext s; simp only [stepSet, mem_setOf_eq, mem_iUnion, exists_prop]; tauto + ext s; simp only [stepSet, mem_ofPred_eq, mem_iUnion, exists_prop]; tauto simp [h, ih] variable (M) in @@ -374,7 +374,7 @@ theorem reverse_reverse : M.reverse.reverse = M := by theorem disjoint_stepSet_reverse {a : α} {S S' : Set σ} : Disjoint S (M.reverse.stepSet S' a) ↔ Disjoint S' (M.stepSet S a) := by rw [← not_iff_not] - simp only [Set.not_disjoint_iff, mem_stepSet, reverse_step, Set.mem_setOf_eq] + simp only [Set.not_disjoint_iff, mem_stepSet, reverse_step, Set.mem_ofPred_eq] tauto theorem disjoint_evalFrom_reverse {x : List α} {S S' : Set σ} diff --git a/Mathlib/Computability/Reduce.lean b/Mathlib/Computability/Reduce.lean index 57283d7201ffe4..6b14845f6f9740 100644 --- a/Mathlib/Computability/Reduce.lean +++ b/Mathlib/Computability/Reduce.lean @@ -291,7 +291,7 @@ theorem toNat_manyOneReducible {p : Set α} : toNat p ≤₀ p := @[simp] theorem manyOneReducible_toNat {p : Set α} : p ≤₀ toNat p := - ⟨Encodable.encode, Computable.encode, by simp [toNat, setOf]⟩ + ⟨Encodable.encode, Computable.encode, by simp [toNat, Set.ofPred]⟩ @[simp] theorem manyOneReducible_toNat_toNat {p : Set α} {q : Set β} : toNat p ≤₀ toNat q ↔ p ≤₀ q := diff --git a/Mathlib/Condensed/TopComparison.lean b/Mathlib/Condensed/TopComparison.lean index 11985db7efee7a..d6f39be67677d1 100644 --- a/Mathlib/Condensed/TopComparison.lean +++ b/Mathlib/Condensed/TopComparison.lean @@ -70,17 +70,18 @@ theorem equalizerCondition_yonedaPresheaf intro Z B π _ _ refine ⟨fun a b h ↦ ?_, fun ⟨a, ha⟩ ↦ ?_⟩ · simp only [yonedaPresheaf, comp, Quiver.Hom.unop_op, TypeCat.Fun.coe_mk, - Set.coe_setOf, mapToEqualizer, Set.mem_setOf_eq, ConcreteCategory.hom_ofHom, Subtype.mk.injEq, - mk.injEq] at h + Set.coe_ofPred, mapToEqualizer, Set.mem_ofPred_eq, ConcreteCategory.hom_ofHom, + Subtype.mk.injEq, mk.injEq] at h simp only [yonedaPresheaf, unop_op] ext x obtain ⟨y, hy⟩ := (hq Z B π).surjective x rw [← hy] exact congr_fun h y · simp only [yonedaPresheaf, comp, Quiver.Hom.unop_op, ConcreteCategory.hom_ofHom, - TypeCat.Fun.coe_mk, mk.injEq, Set.mem_setOf_eq] at ha + TypeCat.Fun.coe_mk, mk.injEq, Set.mem_ofPred_eq] at ha simp only [yonedaPresheaf, comp, Quiver.Hom.unop_op, TypeCat.Fun.coe_mk, - Set.coe_setOf, mapToEqualizer, Set.mem_setOf_eq, ConcreteCategory.hom_ofHom, Subtype.mk.injEq] + Set.coe_ofPred, mapToEqualizer, Set.mem_ofPred_eq, ConcreteCategory.hom_ofHom, + Subtype.mk.injEq] simp only [yonedaPresheaf, unop_op] at a refine ⟨(hq Z B π).lift a (factorsThrough_of_pullbackCondition G X ha), ?_⟩ congr 1 diff --git a/Mathlib/Data/Analysis/Filter.lean b/Mathlib/Data/Analysis/Filter.lean index a910e67c688d7b..c56bc78bc976c0 100644 --- a/Mathlib/Data/Analysis/Filter.lean +++ b/Mathlib/Data/Analysis/Filter.lean @@ -190,7 +190,7 @@ protected def map (m : α → β) {f : Filter α} (F : f.Realizer) : (map m f).R inf_le_left := fun _ _ ↦ image_mono (F.F.inf_le_left _ _) inf_le_right := fun _ _ ↦ image_mono (F.F.inf_le_right _ _) }, filter_eq <| Set.ext fun _ ↦ by - simp only [CFilter.toFilter, image_subset_iff, mem_setOf_eq, Filter.mem_sets, mem_map] + simp only [CFilter.toFilter, image_subset_iff, mem_ofPred_eq, Filter.mem_sets, mem_map] rw [F.mem_sets]⟩ @[simp] diff --git a/Mathlib/Data/DFinsupp/WellFounded.lean b/Mathlib/Data/DFinsupp/WellFounded.lean index 70a91e478f5c98..343b3729cc67a6 100644 --- a/Mathlib/Data/DFinsupp/WellFounded.lean +++ b/Mathlib/Data/DFinsupp/WellFounded.lean @@ -76,25 +76,25 @@ theorem lex_fibration [∀ (i) (s : Set ι), Decidable (i ∈ s)] : simp_rw [piecewise_apply] at hs hr split_ifs at hs with hp · refine ⟨⟨{ j | r j i → j ∈ p }, piecewise x₁ x { j | r j i }, x₂⟩, - .fst ⟨i, fun j hj ↦ ?_, ?_⟩, ?_⟩ <;> simp only [piecewise_apply, Set.mem_setOf_eq] + .fst ⟨i, fun j hj ↦ ?_, ?_⟩, ?_⟩ <;> simp only [piecewise_apply, Set.mem_ofPred_eq] · simp only [if_pos hj] · split_ifs with hi · rwa [hr i hi, if_pos hp] at hs · assumption · ext1 j - simp only [piecewise_apply, Set.mem_setOf_eq] + simp only [piecewise_apply, Set.mem_ofPred_eq] split_ifs with h₁ h₂ <;> try rfl · rw [hr j h₂, if_pos (h₁ h₂)] · rw [Classical.not_imp] at h₁ rw [hr j h₁.1, if_neg h₁.2] · refine ⟨⟨{ j | r j i ∧ j ∈ p }, x₁, piecewise x₂ x { j | r j i }⟩, - .snd ⟨i, fun j hj ↦ ?_, ?_⟩, ?_⟩ <;> simp only [piecewise_apply, Set.mem_setOf_eq] + .snd ⟨i, fun j hj ↦ ?_, ?_⟩, ?_⟩ <;> simp only [piecewise_apply, Set.mem_ofPred_eq] · exact if_pos hj · split_ifs with hi · rwa [hr i hi, if_neg hp] at hs · assumption · ext1 j - simp only [piecewise_apply, Set.mem_setOf_eq] + simp only [piecewise_apply, Set.mem_ofPred_eq] split_ifs with h₁ h₂ <;> try rfl · rw [hr j h₁.1, if_pos h₁.2] · rw [hr j h₂, if_neg] diff --git a/Mathlib/Data/ENNReal/Inv.lean b/Mathlib/Data/ENNReal/Inv.lean index 972e97e91e6a0c..90bb2c8ae29796 100644 --- a/Mathlib/Data/ENNReal/Inv.lean +++ b/Mathlib/Data/ENNReal/Inv.lean @@ -65,7 +65,7 @@ theorem coe_inv_le : (↑r⁻¹ : ℝ≥0∞) ≤ (↑r)⁻¹ := @[simp, norm_cast] theorem coe_inv (hr : r ≠ 0) : (↑r⁻¹ : ℝ≥0∞) = (↑r)⁻¹ := - coe_inv_le.antisymm <| sInf_le <| mem_setOf.2 <| by rw [← coe_mul, mul_inv_cancel₀ hr, coe_one] + coe_inv_le.antisymm <| sInf_le <| mem_ofPred.2 <| by rw [← coe_mul, mul_inv_cancel₀ hr, coe_one] @[simp, norm_cast] theorem coe_inv' [NeZero r] : (↑r⁻¹ : ℝ≥0∞) = (↑r)⁻¹ := coe_inv (NeZero.ne r) diff --git a/Mathlib/Data/ENNReal/Operations.lean b/Mathlib/Data/ENNReal/Operations.lean index 8d551aae3f5dfb..37e6f506a8b956 100644 --- a/Mathlib/Data/ENNReal/Operations.lean +++ b/Mathlib/Data/ENNReal/Operations.lean @@ -277,7 +277,7 @@ end Cancel section Sub theorem sub_eq_sInf {a b : ℝ≥0∞} : a - b = sInf { d | a ≤ d + b } := - le_antisymm (le_sInf fun _ h => tsub_le_iff_right.mpr h) <| sInf_le <| mem_setOf.2 le_tsub_add + le_antisymm (le_sInf fun _ h => tsub_le_iff_right.mpr h) <| sInf_le <| mem_ofPred.2 le_tsub_add /-- This is a special case of `WithTop.coe_sub` in the `ENNReal` namespace -/ @[simp, norm_cast] theorem coe_sub : (↑(r - p) : ℝ≥0∞) = ↑r - ↑p := WithTop.coe_sub diff --git a/Mathlib/Data/Fin/Tuple/Embedding.lean b/Mathlib/Data/Fin/Tuple/Embedding.lean index 832da015637320..cb8d5fdbeedaba 100644 --- a/Mathlib/Data/Fin/Tuple/Embedding.lean +++ b/Mathlib/Data/Fin/Tuple/Embedding.lean @@ -97,7 +97,7 @@ set_option backward.isDefEq.respectTransparency false in /-- The natural equivalence of `Fin 2 ↪ α` with pairs `(a, b)` of distinct elements of `α`. -/ def twoEmbeddingEquiv : (Fin 2 ↪ α) ≃ {(a, b) : α × α | a ≠ b} where toFun e := ⟨(e 0, e 1), by - simp only [ne_eq, Fin.isValue, mem_setOf_eq, EmbeddingLike.apply_eq_iff_eq, zero_eq_one_iff, + simp only [ne_eq, Fin.isValue, mem_ofPred_eq, EmbeddingLike.apply_eq_iff_eq, zero_eq_one_iff, succ_ne_self, not_false_eq_true]⟩ invFun := fun ⟨⟨a, b⟩, h⟩ ↦ { toFun i := if i = 0 then a else b diff --git a/Mathlib/Data/Finset/Basic.lean b/Mathlib/Data/Finset/Basic.lean index a084f3ba85f11d..7bdf67e11ead86 100644 --- a/Mathlib/Data/Finset/Basic.lean +++ b/Mathlib/Data/Finset/Basic.lean @@ -392,7 +392,7 @@ theorem subset_union_elim {s : Finset α} {t₁ t₂ : Set α} (h : ↑s ⊆ t · grind · grind · intro x - simp only [coe_filter, Set.mem_setOf_eq, and_imp] + simp only [coe_filter, Set.mem_ofPred_eq, and_imp] intro hx hx₂ exact ⟨Or.resolve_left (h hx) hx₂, hx₂⟩ diff --git a/Mathlib/Data/Finset/Defs.lean b/Mathlib/Data/Finset/Defs.lean index 6b47b346bb4689..e231d7f8b107f6 100644 --- a/Mathlib/Data/Finset/Defs.lean +++ b/Mathlib/Data/Finset/Defs.lean @@ -127,9 +127,11 @@ theorem mem_coe {a : α} {s : Finset α} : a ∈ (s : Set α) ↔ a ∈ (s : Fin Iff.rfl @[simp] -theorem setOf_mem {α} {s : Finset α} : { a | a ∈ s } = s := +theorem setOfPred_mem {α} {s : Finset α} : { a | a ∈ s } = s := rfl +@[deprecated (since := "2026-07-09")] alias setOf_mem := setOfPred_mem + theorem coe_mem {s : Finset α} (x : (s : Set α)) : ↑x ∈ s := x.2 diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index f9c4beb141464d..9d301d68c9e232 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -611,7 +611,7 @@ theorem mem_filterMap {b : β} : b ∈ s.filterMap f f_inj ↔ ∃ a ∈ s, f a @[simp, norm_cast] theorem coe_filterMap : (s.filterMap f f_inj : Set β) = {b | ∃ a ∈ s, f a = some b} := - Set.ext (by simp only [mem_coe, mem_filterMap, Set.mem_setOf_eq, implies_true]) + Set.ext (by simp only [mem_coe, mem_filterMap, Set.mem_ofPred_eq, implies_true]) @[simp] theorem filterMap_some : s.filterMap some (by simp) = s := diff --git a/Mathlib/Data/Finset/Sort.lean b/Mathlib/Data/Finset/Sort.lean index 90d63007a84764..739519ada9a00f 100644 --- a/Mathlib/Data/Finset/Sort.lean +++ b/Mathlib/Data/Finset/Sort.lean @@ -218,7 +218,7 @@ theorem range_orderEmbOfFin (s : Finset α) {k : ℕ} (h : s.card = k) : simp only [orderEmbOfFin, Set.range_comp ((↑) : _ → α) (s.orderIsoOfFin h), RelEmbedding.coe_trans, Set.image_univ, Finset.orderEmbOfFin, RelIso.range_eq, OrderEmbedding.coe_subtype, OrderIso.coe_toOrderEmbedding, - Subtype.range_coe_subtype, Finset.setOf_mem] + Subtype.range_coe_subtype, Finset.setOfPred_mem] @[simp] theorem image_orderEmbOfFin_univ (s : Finset α) {k : ℕ} (h : s.card = k) : diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index eafda164c1daa8..47bd35a3a4940a 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -675,7 +675,7 @@ theorem filter_eq_zero_iff : f.filter p = 0 ↔ ∀ x, p x → f x = 0 := by simp [DFunLike.ext_iff, filter_eq_indicator] theorem filter_eq_self_iff : f.filter p = f ↔ ∀ x, f x ≠ 0 → p x := by - simp only [DFunLike.ext_iff, filter_eq_indicator, Set.indicator_apply_eq_self, Set.mem_setOf_eq, + simp only [DFunLike.ext_iff, filter_eq_indicator, Set.indicator_apply_eq_self, Set.mem_ofPred_eq, not_imp_comm] @[simp] diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 23b6de17eee6a9..349ef1a0660562 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -349,7 +349,7 @@ theorem support_mapRange_of_injective {e : M → N} (he0 : e 0 = 0) (f : ι → lemma range_mapRange (e : M → N) (he₀ : e 0 = 0) : Set.range (Finsupp.mapRange (α := α) e he₀) = {g | ∀ i, g i ∈ Set.range e} := by ext g - simp only [Set.mem_range, Set.mem_setOf] + simp only [Set.mem_range, Set.mem_ofPred] constructor · grind · intro h diff --git a/Mathlib/Data/Finsupp/Ext.lean b/Mathlib/Data/Finsupp/Ext.lean index e7d14b42f9f12c..fcdbad0d388c47 100644 --- a/Mathlib/Data/Finsupp/Ext.lean +++ b/Mathlib/Data/Finsupp/Ext.lean @@ -17,7 +17,7 @@ These have been moved to their own file to avoid depending on submonoids when de ## Main results -* `Finsupp.add_closure_setOf_eq_single`: `Finsupp` is generated by all the `single`s +* `Finsupp.add_closure_setOfPred_eq_single`: `Finsupp` is generated by all the `single`s * `Finsupp.addHom_ext`: additive homomorphisms that are equal on each `single` are equal everywhere -/ @@ -30,17 +30,20 @@ namespace Finsupp variable [AddZeroClass M] @[simp] -theorem add_closure_setOf_eq_single : +theorem add_closure_setOfPred_eq_single : AddSubmonoid.closure { f : α →₀ M | ∃ a b, f = single a b } = ⊤ := top_unique fun x _hx => Finsupp.induction x (AddSubmonoid.zero_mem _) fun a b _f _ha _hb hf => AddSubmonoid.add_mem _ (AddSubmonoid.subset_closure <| ⟨a, b, rfl⟩) hf +@[deprecated (since := "2026-07-09")] +alias add_closure_setOf_eq_single := add_closure_setOfPred_eq_single + /-- If two additive homomorphisms from `α →₀ M` are equal on each `single a b`, then they are equal. -/ theorem addHom_ext [AddZeroClass N] ⦃f g : (α →₀ M) →+ N⦄ (H : ∀ x y, f (single x y) = g (single x y)) : f = g := by - refine AddMonoidHom.eq_of_eqOn_denseM add_closure_setOf_eq_single ?_ + refine AddMonoidHom.eq_of_eqOn_denseM add_closure_setOfPred_eq_single ?_ rintro _ ⟨x, y, rfl⟩ apply H diff --git a/Mathlib/Data/Fintype/Card.lean b/Mathlib/Data/Fintype/Card.lean index b3e4c624bb749c..882bcfa5829eca 100644 --- a/Mathlib/Data/Fintype/Card.lean +++ b/Mathlib/Data/Fintype/Card.lean @@ -405,7 +405,7 @@ theorem Fintype.card_subtype_compl [Fintype α] (p : α → Prop) [Fintype { x / rw [Fintype.card_of_subtype (Set.toFinset { x | p x }ᶜ), Set.toFinset_compl, Finset.card_compl, Fintype.card_of_subtype] <;> · intro - simp only [Set.mem_toFinset, Set.mem_compl_iff, Set.mem_setOf] + simp only [Set.mem_toFinset, Set.mem_compl_iff, Set.mem_ofPred] theorem Fintype.card_subtype_mono (p q : α → Prop) (h : p ≤ q) [Fintype { x // p x }] [Fintype { x // q x }] : Fintype.card { x // p x } ≤ Fintype.card { x // q x } := diff --git a/Mathlib/Data/Fintype/Sets.lean b/Mathlib/Data/Fintype/Sets.lean index e095956db78eae..1811b5f75f4817 100644 --- a/Mathlib/Data/Fintype/Sets.lean +++ b/Mathlib/Data/Fintype/Sets.lean @@ -176,11 +176,13 @@ theorem toFinset_eq_univ [Fintype α] [Fintype s] : s.toFinset = Finset.univ ↔ rw [← coe_inj, coe_toFinset, coe_univ] @[simp] -theorem toFinset_setOf [Fintype α] (p : α → Prop) [DecidablePred p] [Fintype { x | p x }] : +theorem toFinset_ofPred [Fintype α] (p : α → Prop) [DecidablePred p] [Fintype { x | p x }] : Set.toFinset {x | p x} = Finset.univ.filter p := by ext simp +@[deprecated (since := "2026-07-09")] alias toFinset_setOf := toFinset_ofPred + theorem toFinset_ssubset_univ [Fintype α] {s : Set α} [Fintype s] : s.toFinset ⊂ Finset.univ ↔ s ⊂ univ := by simp diff --git a/Mathlib/Data/Int/GCD.lean b/Mathlib/Data/Int/GCD.lean index e4b2aa4d982941..6cc9051fe51495 100644 --- a/Mathlib/Data/Int/GCD.lean +++ b/Mathlib/Data/Int/GCD.lean @@ -250,8 +250,8 @@ theorem gcd_least_linear {a b : ℤ} (ha : a ≠ 0) : IsLeast { n : ℕ | 0 < n ∧ ∃ x y : ℤ, ↑n = a * x + b * y } (a.gcd b) := by simp_rw [← gcd_dvd_iff] constructor - · simpa [and_true, dvd_refl, Set.mem_setOf_eq] using gcd_pos_of_ne_zero_left b ha - · simp only [lowerBounds, and_imp, Set.mem_setOf_eq] + · simpa [and_true, dvd_refl, Set.mem_ofPred_eq] using gcd_pos_of_ne_zero_left b ha + · simp only [lowerBounds, and_imp, Set.mem_ofPred_eq] exact fun n hn_pos hn => Nat.le_of_dvd hn_pos hn end Int diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 3e8b01e90c6e3b..3e4a92e1a882c2 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -57,9 +57,11 @@ instance : Std.Associative (α := List α) Append.append where theorem singleton_injective : Injective fun a : α => [a] := fun _ _ h => (cons_eq_cons.1 h).1 -theorem set_of_mem_cons (l : List α) (a : α) : { x | x ∈ a :: l } = insert a { x | x ∈ l } := +theorem setOfPred_mem_cons (l : List α) (a : α) : { x | x ∈ a :: l } = insert a { x | x ∈ l } := Set.ext fun _ => mem_cons +@[deprecated (since := "2026-07-13")] alias set_of_mem_cons := setOfPred_mem_cons + /-! ### mem -/ theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α] diff --git a/Mathlib/Data/List/Lemmas.lean b/Mathlib/Data/List/Lemmas.lean index 81eee2bc466ca6..7048b465098851 100644 --- a/Mathlib/Data/List/Lemmas.lean +++ b/Mathlib/Data/List/Lemmas.lean @@ -20,17 +20,19 @@ variable {α β γ : Type*} namespace List @[simp] -theorem setOf_mem_eq_empty_iff {l : List α} : { x | x ∈ l } = ∅ ↔ l = [] := +theorem setOfPred_mem_eq_empty_iff {l : List α} : { x | x ∈ l } = ∅ ↔ l = [] := Set.eq_empty_iff_forall_notMem.trans eq_nil_iff_forall_not_mem.symm +@[deprecated (since := "2026-07-09")] alias setOf_mem_eq_empty_iff := setOfPred_mem_eq_empty_iff + theorem injOn_insertIdx_index_of_notMem (l : List α) (x : α) (hx : x ∉ l) : Set.InjOn (fun k => l.insertIdx k x) { n | n ≤ l.length } := by intro n hn m hm h induction l generalizing n m with | nil => - simp_all [Set.mem_singleton_iff, Set.setOf_eq_eq_singleton, length] + simp_all [Set.mem_singleton_iff, Set.ofPred_eq_eq_singleton, length] | cons hd tl IH => - simp only [length, Set.mem_setOf_eq] at hn hm + simp only [length, Set.mem_ofPred_eq] at hn hm simp only [mem_cons, not_or] at hx cases n <;> cases m · rfl diff --git a/Mathlib/Data/List/Sym.lean b/Mathlib/Data/List/Sym.lean index fa67929e4b5a83..70100756c7c389 100644 --- a/Mathlib/Data/List/Sym.lean +++ b/Mathlib/Data/List/Sym.lean @@ -96,10 +96,12 @@ theorem mem_sym2_iff {xs : List α} {z : Sym2 α} : refine z.ind (fun a b => ?_) simp [mk_mem_sym2_iff] -lemma setOf_mem_sym2 {xs : List α} : +lemma setOfPred_mem_sym2 {xs : List α} : {z : Sym2 α | z ∈ xs.sym2} = {x : α | x ∈ xs}.sym2 := Set.ext fun z ↦ z.ind fun a b => by simp [mk_mem_sym2_iff] +@[deprecated (since := "2026-07-09")] alias setOf_mem_sym2 := setOfPred_mem_sym2 + protected theorem Nodup.sym2 {xs : List α} (h : xs.Nodup) : xs.sym2.Nodup := by induction xs with | nil => simp only [List.sym2, nodup_nil] diff --git a/Mathlib/Data/Multiset/Fintype.lean b/Mathlib/Data/Multiset/Fintype.lean index eec7d8ce4fb54c..78d4bff05e6d0b 100644 --- a/Mathlib/Data/Multiset/Fintype.lean +++ b/Mathlib/Data/Multiset/Fintype.lean @@ -87,7 +87,7 @@ instance : Fintype { p : α × ℕ | p.2 < m.count p.1 } := (by rintro ⟨x, i⟩ simp_rw [Finset.mem_disjiUnion, Multiset.mem_toFinset, Finset.mem_map, Finset.mem_range, - Function.Embedding.coeFn_mk, Prod.mk_inj, Set.mem_setOf_eq] + Function.Embedding.coeFn_mk, Prod.mk_inj, Set.mem_ofPred_eq] simp only [← and_assoc, exists_eq_right, and_iff_right_iff_imp] exact fun h ↦ Multiset.count_pos.mp (by lia)) diff --git a/Mathlib/Data/Multiset/Sym.lean b/Mathlib/Data/Multiset/Sym.lean index fe557531e167ba..624e6d49e4974b 100644 --- a/Mathlib/Data/Multiset/Sym.lean +++ b/Mathlib/Data/Multiset/Sym.lean @@ -70,10 +70,12 @@ theorem mem_sym2_iff {m : Multiset α} {z : Sym2 α} : z ∈ m.sym2 ↔ ∀ y ∈ z, y ∈ m := m.inductionOn fun xs => by simp [List.mem_sym2_iff] -lemma setOf_mem_sym2 {m : Multiset α} : +lemma setOfPred_mem_sym2 {m : Multiset α} : {z : Sym2 α | z ∈ m.sym2} = {x : α | x ∈ m}.sym2 := Set.ext fun z ↦ z.ind fun a b => by simp [mk_mem_sym2_iff] +@[deprecated (since := "2026-07-09")] alias setOf_mem_sym2 := setOfPred_mem_sym2 + protected theorem Nodup.sym2 {m : Multiset α} (h : m.Nodup) : m.sym2.Nodup := m.inductionOn (fun _ h => List.Nodup.sym2 h) h diff --git a/Mathlib/Data/Nat/Count.lean b/Mathlib/Data/Nat/Count.lean index 3e7c42de143f4e..bf87e54d30f5c5 100644 --- a/Mathlib/Data/Nat/Count.lean +++ b/Mathlib/Data/Nat/Count.lean @@ -108,11 +108,11 @@ theorem count_injective {m n : ℕ} (hm : p m) (hn : p n) (heq : count p m = cou · exact this hn hm heq.symm h.symm (by grind) · simpa [heq] using count_strict_mono hm hmn -theorem count_le_card (hp : (setOf p).Finite) (n : ℕ) : count p n ≤ #hp.toFinset := by +theorem count_le_card (hp : (Set.ofPred p).Finite) (n : ℕ) : count p n ≤ #hp.toFinset := by rw [count_eq_card_filter_range] exact Finset.card_mono fun x hx ↦ hp.mem_toFinset.2 (mem_filter.1 hx).2 -theorem count_lt_card {n : ℕ} (hp : (setOf p).Finite) (hpn : p n) : count p n < #hp.toFinset := +theorem count_lt_card {n : ℕ} (hp : (Set.ofPred p).Finite) (hpn : p n) : count p n < #hp.toFinset := (count_lt_count_succ_iff.2 hpn).trans_le (count_le_card hp _) theorem count_iff_forall {n : ℕ} : count p n = n ↔ ∀ n' < n, p n' := by diff --git a/Mathlib/Data/Nat/Digits/Lemmas.lean b/Mathlib/Data/Nat/Digits/Lemmas.lean index b0ed2f0f1f05e1..396761fc325d77 100644 --- a/Mathlib/Data/Nat/Digits/Lemmas.lean +++ b/Mathlib/Data/Nat/Digits/Lemmas.lean @@ -350,7 +350,7 @@ theorem lt_of_mem_digitsAppend {b : ℕ} (hb : 1 < b) (l i : ℕ) theorem mapsTo_ofDigits {b : ℕ} (hb : 1 < b) (l : ℕ) : Set.MapsTo (ofDigits b) {L : List ℕ | L.length = l ∧ ∀ x ∈ L, x < b} {n | n < b ^ l} := - fun _ h ↦ Set.mem_setOf.mpr h.1 ▸ Nat.ofDigits_lt_base_pow_length hb h.2 + fun _ h ↦ Set.mem_ofPred.mpr h.1 ▸ Nat.ofDigits_lt_base_pow_length hb h.2 theorem mapsTo_digitsAppend {b : ℕ} (hb : 1 < b) (l : ℕ) : Set.MapsTo (digitsAppend b l) {n | n < b ^ l} {L : List ℕ | L.length = l ∧ ∀ x ∈ L, x < b} := diff --git a/Mathlib/Data/Nat/Factorization/Basic.lean b/Mathlib/Data/Nat/Factorization/Basic.lean index ef73fda01a634c..754d9c2792659f 100644 --- a/Mathlib/Data/Nat/Factorization/Basic.lean +++ b/Mathlib/Data/Nat/Factorization/Basic.lean @@ -387,11 +387,14 @@ theorem prod_primeFactors_gcd_mul_prod_primeFactors_mul {β : Type*} [CommMonoid · simp · rw [primeFactors_mul hm₀ hn₀, primeFactors_gcd hm₀ hn₀, mul_comm, Finset.prod_union_inter] -theorem setOf_pow_dvd_eq_Icc_factorization {n p : ℕ} (pp : p.Prime) (hn : n ≠ 0) : +theorem setOfPred_pow_dvd_eq_Icc_factorization {n p : ℕ} (pp : p.Prime) (hn : n ≠ 0) : { i : ℕ | i ≠ 0 ∧ p ^ i ∣ n } = Set.Icc 1 (n.factorization p) := by ext simp [one_le_iff_ne_zero, pp.pow_dvd_iff_le_factorization hn] +@[deprecated (since := "2026-07-09")] +alias setOf_pow_dvd_eq_Icc_factorization := setOfPred_pow_dvd_eq_Icc_factorization + /-- The set of positive powers of prime `p` that divide `n` is exactly the set of positive natural numbers up to `n.factorization p`. -/ theorem Icc_factorization_eq_pow_dvd (n : ℕ) {p : ℕ} (pp : Prime p) : diff --git a/Mathlib/Data/Nat/Nth.lean b/Mathlib/Data/Nat/Nth.lean index 89c38d7c03cd3e..96b0924441a24a 100644 --- a/Mathlib/Data/Nat/Nth.lean +++ b/Mathlib/Data/Nat/Nth.lean @@ -35,7 +35,7 @@ and provides lemmas that deal with this function and its connection to `Nat.coun ## Implementation details Much of the below was written before `Set.encard` existed and partly for this reason uses the -pattern `∀ hf : Set.Finite (setOf p), n < hf.toFinset.card` rather than `n < {x | p x}.encard`. +pattern `∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card` rather than `n < {x | p x}.encard`. We should consider changing this. There has been some discussion on the subject of whether both of `nth` and @@ -59,8 +59,8 @@ natural number satisfying `p`), or `0` if there is no such number. See also `Subtype.orderIsoOfNat` for the order isomorphism with ℕ when `p` is infinitely often true. -/ noncomputable def nth (p : ℕ → Prop) (n : ℕ) : ℕ := by classical exact - if h : Set.Finite (setOf p) then h.toFinset.sort.getD n 0 - else @Nat.Subtype.orderIsoOfNat (setOf p) (Set.Infinite.to_subtype h) n + if h : Set.Finite (Set.ofPred p) then h.toFinset.sort.getD n 0 + else @Nat.Subtype.orderIsoOfNat (Set.ofPred p) (Set.Infinite.to_subtype h) n variable {p} @@ -69,98 +69,101 @@ variable {p} -/ -theorem nth_of_card_le (hf : (setOf p).Finite) {n : ℕ} (hn : #hf.toFinset ≤ n) : +theorem nth_of_card_le (hf : (Set.ofPred p).Finite) {n : ℕ} (hn : #hf.toFinset ≤ n) : nth p n = 0 := by rw [nth, dif_pos hf, List.getD_eq_default]; rwa [Finset.length_sort] -theorem nth_eq_getD_sort (h : (setOf p).Finite) (n : ℕ) : +theorem nth_eq_getD_sort (h : (Set.ofPred p).Finite) (n : ℕ) : nth p n = h.toFinset.sort.getD n 0 := dif_pos h -theorem nth_eq_orderEmbOfFin (hf : (setOf p).Finite) {n : ℕ} (hn : n < #hf.toFinset) : +theorem nth_eq_orderEmbOfFin (hf : (Set.ofPred p).Finite) {n : ℕ} (hn : n < #hf.toFinset) : nth p n = hf.toFinset.orderEmbOfFin rfl ⟨n, hn⟩ := by rw [nth_eq_getD_sort hf, Finset.orderEmbOfFin_apply, List.getD_eq_getElem, Fin.getElem_fin] -theorem nth_strictMonoOn (hf : (setOf p).Finite) : +theorem nth_strictMonoOn (hf : (Set.ofPred p).Finite) : StrictMonoOn (nth p) (Set.Iio #hf.toFinset) := by rintro m (hm : m < _) n (hn : n < _) h simp only [nth_eq_orderEmbOfFin, *] exact OrderEmbedding.strictMono _ h -theorem nth_lt_nth_of_lt_card (hf : (setOf p).Finite) {m n : ℕ} (h : m < n) +theorem nth_lt_nth_of_lt_card (hf : (Set.ofPred p).Finite) {m n : ℕ} (h : m < n) (hn : n < #hf.toFinset) : nth p m < nth p n := nth_strictMonoOn hf (h.trans hn) hn h -theorem nth_le_nth_of_lt_card (hf : (setOf p).Finite) {m n : ℕ} (h : m ≤ n) +theorem nth_le_nth_of_lt_card (hf : (Set.ofPred p).Finite) {m n : ℕ} (h : m ≤ n) (hn : n < #hf.toFinset) : nth p m ≤ nth p n := (nth_strictMonoOn hf).monotoneOn (h.trans_lt hn) hn h -theorem lt_of_nth_lt_nth_of_lt_card (hf : (setOf p).Finite) {m n : ℕ} (h : nth p m < nth p n) +theorem lt_of_nth_lt_nth_of_lt_card (hf : (Set.ofPred p).Finite) {m n : ℕ} (h : nth p m < nth p n) (hm : m < #hf.toFinset) : m < n := not_le.1 fun hle => h.not_ge <| nth_le_nth_of_lt_card hf hle hm -theorem le_of_nth_le_nth_of_lt_card (hf : (setOf p).Finite) {m n : ℕ} (h : nth p m ≤ nth p n) +theorem le_of_nth_le_nth_of_lt_card (hf : (Set.ofPred p).Finite) {m n : ℕ} (h : nth p m ≤ nth p n) (hm : m < #hf.toFinset) : m ≤ n := not_lt.1 fun hlt => h.not_gt <| nth_lt_nth_of_lt_card hf hlt hm -theorem nth_injOn (hf : (setOf p).Finite) : (Set.Iio #hf.toFinset).InjOn (nth p) := +theorem nth_injOn (hf : (Set.ofPred p).Finite) : (Set.Iio #hf.toFinset).InjOn (nth p) := (nth_strictMonoOn hf).injOn -theorem range_nth_of_finite (hf : (setOf p).Finite) : Set.range (nth p) = insert 0 (setOf p) := by +theorem range_nth_of_finite (hf : (Set.ofPred p).Finite) : + Set.range (nth p) = insert 0 (Set.ofPred p) := by simpa only [← List.getD_eq_getElem?_getD, ← nth_eq_getD_sort hf, mem_sort, Set.Finite.mem_toFinset] using! Set.range_list_getD (hf.toFinset.sort (· ≤ ·)) 0 @[simp] -theorem image_nth_Iio_card (hf : (setOf p).Finite) : nth p '' Set.Iio #hf.toFinset = setOf p := +theorem image_nth_Iio_card (hf : (Set.ofPred p).Finite) : + nth p '' Set.Iio #hf.toFinset = Set.ofPred p := calc nth p '' Set.Iio #hf.toFinset = Set.range (hf.toFinset.orderEmbOfFin rfl) := by ext x simp only [Set.mem_image, Set.mem_range, Fin.exists_iff, ← nth_eq_orderEmbOfFin hf, Set.mem_Iio, exists_prop] - _ = setOf p := by rw [range_orderEmbOfFin, Set.Finite.coe_toFinset] + _ = Set.ofPred p := by rw [range_orderEmbOfFin, Set.Finite.coe_toFinset] -theorem nth_mem_of_lt_card {n : ℕ} (hf : (setOf p).Finite) (hlt : n < #hf.toFinset) : +theorem nth_mem_of_lt_card {n : ℕ} (hf : (Set.ofPred p).Finite) (hlt : n < #hf.toFinset) : p (nth p n) := (image_nth_Iio_card hf).subset <| Set.mem_image_of_mem _ hlt -theorem exists_lt_card_finite_nth_eq (hf : (setOf p).Finite) {x} (h : p x) : +theorem exists_lt_card_finite_nth_eq (hf : (Set.ofPred p).Finite) {x} (h : p x) : ∃ n, n < #hf.toFinset ∧ nth p n = x := by - rwa [← @Set.mem_setOf_eq _ _ p, ← image_nth_Iio_card hf] at h + rwa [← @Set.mem_ofPred_eq _ _ p, ← image_nth_Iio_card hf] at h /-! ### Lemmas about `Nat.nth` on an infinite set -/ /-- When `s` is an infinite set, `nth` agrees with `Nat.Subtype.orderIsoOfNat`. -/ -theorem nth_apply_eq_orderIsoOfNat (hf : (setOf p).Infinite) (n : ℕ) : - nth p n = @Nat.Subtype.orderIsoOfNat (setOf p) hf.to_subtype n := by rw [nth, dif_neg hf] +theorem nth_apply_eq_orderIsoOfNat (hf : (Set.ofPred p).Infinite) (n : ℕ) : + nth p n = @Nat.Subtype.orderIsoOfNat (Set.ofPred p) hf.to_subtype n := by rw [nth, dif_neg hf] /-- When `s` is an infinite set, `nth` agrees with `Nat.Subtype.orderIsoOfNat`. -/ -theorem nth_eq_orderIsoOfNat (hf : (setOf p).Infinite) : - nth p = (↑) ∘ @Nat.Subtype.orderIsoOfNat (setOf p) hf.to_subtype := +theorem nth_eq_orderIsoOfNat (hf : (Set.ofPred p).Infinite) : + nth p = (↑) ∘ @Nat.Subtype.orderIsoOfNat (Set.ofPred p) hf.to_subtype := funext <| nth_apply_eq_orderIsoOfNat hf -theorem nth_strictMono (hf : (setOf p).Infinite) : StrictMono (nth p) := by +theorem nth_strictMono (hf : (Set.ofPred p).Infinite) : StrictMono (nth p) := by rw [nth_eq_orderIsoOfNat hf] exact (Subtype.strictMono_coe _).comp (OrderIso.strictMono _) -theorem nth_injective (hf : (setOf p).Infinite) : Function.Injective (nth p) := +theorem nth_injective (hf : (Set.ofPred p).Infinite) : Function.Injective (nth p) := (nth_strictMono hf).injective -theorem nth_monotone (hf : (setOf p).Infinite) : Monotone (nth p) := +theorem nth_monotone (hf : (Set.ofPred p).Infinite) : Monotone (nth p) := (nth_strictMono hf).monotone -theorem nth_lt_nth (hf : (setOf p).Infinite) {k n} : nth p k < nth p n ↔ k < n := +theorem nth_lt_nth (hf : (Set.ofPred p).Infinite) {k n} : nth p k < nth p n ↔ k < n := (nth_strictMono hf).lt_iff_lt -theorem nth_le_nth (hf : (setOf p).Infinite) {k n} : nth p k ≤ nth p n ↔ k ≤ n := +theorem nth_le_nth (hf : (Set.ofPred p).Infinite) {k n} : nth p k ≤ nth p n ↔ k ≤ n := (nth_strictMono hf).le_iff_le -theorem range_nth_of_infinite (hf : (setOf p).Infinite) : Set.range (nth p) = setOf p := by +theorem range_nth_of_infinite (hf : (Set.ofPred p).Infinite) : + Set.range (nth p) = Set.ofPred p := by rw [nth_eq_orderIsoOfNat hf] have := hf.to_subtype classical exact Nat.Subtype.coe_comp_ofNat_range -theorem nth_mem_of_infinite (hf : (setOf p).Infinite) (n : ℕ) : p (nth p n) := +theorem nth_mem_of_infinite (hf : (Set.ofPred p).Infinite) (n : ℕ) : p (nth p n) := Set.range_subset_iff.1 (range_nth_of_infinite hf).le n /-! @@ -168,52 +171,52 @@ theorem nth_mem_of_infinite (hf : (setOf p).Infinite) (n : ℕ) : p (nth p n) := -/ theorem exists_lt_card_nth_eq {x} (h : p x) : - ∃ n, (∀ hf : (setOf p).Finite, n < #hf.toFinset) ∧ nth p n = x := by - refine (setOf p).finite_or_infinite.elim (fun hf => ?_) fun hf => ?_ + ∃ n, (∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) ∧ nth p n = x := by + refine (Set.ofPred p).finite_or_infinite.elim (fun hf => ?_) fun hf => ?_ · rcases exists_lt_card_finite_nth_eq hf h with ⟨n, hn, hx⟩ exact ⟨n, fun _ => hn, hx⟩ - · rw [← @Set.mem_setOf_eq _ _ p, ← range_nth_of_infinite hf] at h + · rw [← @Set.mem_ofPred_eq _ _ p, ← range_nth_of_infinite hf] at h rcases h with ⟨n, hx⟩ exact ⟨n, fun hf' => absurd hf' hf, hx⟩ -theorem subset_range_nth : setOf p ⊆ Set.range (nth p) := fun x (hx : p x) => +theorem subset_range_nth : Set.ofPred p ⊆ Set.range (nth p) := fun x (hx : p x) => let ⟨n, _, hn⟩ := exists_lt_card_nth_eq hx ⟨n, hn⟩ -theorem range_nth_subset : Set.range (nth p) ⊆ insert 0 (setOf p) := - (setOf p).finite_or_infinite.elim (fun h => (range_nth_of_finite h).subset) fun h => +theorem range_nth_subset : Set.range (nth p) ⊆ insert 0 (Set.ofPred p) := + (Set.ofPred p).finite_or_infinite.elim (fun h => (range_nth_of_finite h).subset) fun h => (range_nth_of_infinite h).trans_subset (Set.subset_insert _ _) -theorem nth_mem (n : ℕ) (h : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : p (nth p n) := - (setOf p).finite_or_infinite.elim (fun hf => nth_mem_of_lt_card hf (h hf)) fun h => +theorem nth_mem (n : ℕ) (h : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : p (nth p n) := + (Set.ofPred p).finite_or_infinite.elim (fun hf => nth_mem_of_lt_card hf (h hf)) fun h => nth_mem_of_infinite h n -theorem nth_lt_nth' {m n : ℕ} (hlt : m < n) (h : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : +theorem nth_lt_nth' {m n : ℕ} (hlt : m < n) (h : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : nth p m < nth p n := - (setOf p).finite_or_infinite.elim (fun hf => nth_lt_nth_of_lt_card hf hlt (h _)) fun hf => + (Set.ofPred p).finite_or_infinite.elim (fun hf => nth_lt_nth_of_lt_card hf hlt (h _)) fun hf => (nth_lt_nth hf).2 hlt -theorem nth_le_nth' {m n : ℕ} (hle : m ≤ n) (h : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : +theorem nth_le_nth' {m n : ℕ} (hle : m ≤ n) (h : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : nth p m ≤ nth p n := - (setOf p).finite_or_infinite.elim (fun hf => nth_le_nth_of_lt_card hf hle (h _)) fun hf => + (Set.ofPred p).finite_or_infinite.elim (fun hf => nth_le_nth_of_lt_card hf hle (h _)) fun hf => (nth_le_nth hf).2 hle -theorem le_nth {n : ℕ} (h : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : n ≤ nth p n := - (setOf p).finite_or_infinite.elim +theorem le_nth {n : ℕ} (h : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : n ≤ nth p n := + (Set.ofPred p).finite_or_infinite.elim (fun hf => ((nth_strictMonoOn hf).mono <| Set.Iic_subset_Iio.2 (h _)).Iic_id_le _ le_rfl) fun hf => (nth_strictMono hf).id_le _ -theorem isLeast_nth {n} (h : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : +theorem isLeast_nth {n} (h : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : IsLeast {i | p i ∧ ∀ k < n, nth p k < i} (nth p n) := ⟨⟨nth_mem n h, fun _k hk => nth_lt_nth' hk h⟩, fun _x hx => let ⟨k, hk, hkx⟩ := exists_lt_card_nth_eq hx.1 (lt_or_ge k n).elim (fun hlt => absurd hkx (hx.2 _ hlt).ne) fun hle => hkx ▸ nth_le_nth' hle hk⟩ -theorem isLeast_nth_of_lt_card {n : ℕ} (hf : (setOf p).Finite) (hn : n < #hf.toFinset) : +theorem isLeast_nth_of_lt_card {n : ℕ} (hf : (Set.ofPred p).Finite) (hn : n < #hf.toFinset) : IsLeast {i | p i ∧ ∀ k < n, nth p k < i} (nth p n) := isLeast_nth fun _ => hn -theorem isLeast_nth_of_infinite (hf : (setOf p).Infinite) (n : ℕ) : +theorem isLeast_nth_of_infinite (hf : (Set.ofPred p).Infinite) (n : ℕ) : IsLeast {i | p i ∧ ∀ k < n, nth p k < i} (nth p n) := isLeast_nth fun h => absurd h hf @@ -222,7 +225,7 @@ that `Nat.nth s k < x` for all `k < n`, if this set is nonempty. We do not assum nonempty because we use the same "garbage value" `0` both for `sInf` on `ℕ` and for `Nat.nth s n` for `n ≥ #s`. -/ theorem nth_eq_sInf (p : ℕ → Prop) (n : ℕ) : nth p n = sInf {x | p x ∧ ∀ k < n, nth p k < x} := by - by_cases! hn : ∀ hf : (setOf p).Finite, n < #hf.toFinset + by_cases! hn : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset · exact (isLeast_nth hn).csInf_eq.symm · rcases hn with ⟨hf, hn⟩ rw [nth_of_card_le _ hn] @@ -230,7 +233,7 @@ theorem nth_eq_sInf (p : ℕ → Prop) (n : ℕ) : nth p n = sInf {x | p x ∧ rcases exists_lt_card_nth_eq hk.1 with ⟨k, hlt, rfl⟩ exact (hk.2 _ ((hlt hf).trans_le hn)).false -theorem nth_zero : nth p 0 = sInf (setOf p) := by rw [nth_eq_sInf]; simp +theorem nth_zero : nth p 0 = sInf (Set.ofPred p) := by rw [nth_eq_sInf]; simp @[simp] theorem nth_zero_of_zero (h : p 0) : nth p 0 = 0 := by simp [nth_zero, h] @@ -240,14 +243,14 @@ theorem nth_zero_of_exists [DecidablePred p] (h : ∃ n, p n) : nth p 0 = Nat.fi rw [nth_zero]; convert! Nat.sInf_def h theorem nth_eq_zero {n} : - nth p n = 0 ↔ p 0 ∧ n = 0 ∨ ∃ hf : (setOf p).Finite, #hf.toFinset ≤ n := by + nth p n = 0 ↔ p 0 ∧ n = 0 ∨ ∃ hf : (Set.ofPred p).Finite, #hf.toFinset ≤ n := by refine ⟨fun h => ?_, ?_⟩ · simp only [or_iff_not_imp_right, not_exists, not_le] exact fun hn => ⟨h ▸ nth_mem _ hn, nonpos_iff_eq_zero.1 <| h ▸ le_nth hn⟩ · rintro (⟨h₀, rfl⟩ | ⟨hf, hle⟩) exacts [nth_zero_of_zero h₀, nth_of_card_le hf hle] -lemma lt_card_toFinset_of_nth_ne_zero {n : ℕ} (h : nth p n ≠ 0) (hf : (setOf p).Finite) : +lemma lt_card_toFinset_of_nth_ne_zero {n : ℕ} (h : nth p n ≠ 0) (hf : (Set.ofPred p).Finite) : n < #hf.toFinset := by simp only [ne_eq, nth_eq_zero, not_or, not_exists, not_le] at h exact h.2 hf @@ -263,7 +266,7 @@ lemma nth_ne_zero_anti (h₀ : ¬p 0) {a b : ℕ} (hab : a ≤ b) (hb : nth p b mt (nth_eq_zero_mono h₀ hab) hb theorem le_nth_of_lt_nth_succ {k a : ℕ} (h : a < nth p (k + 1)) (ha : p a) : a ≤ nth p k := by - rcases (setOf p).finite_or_infinite with hf | hf + rcases (Set.ofPred p).finite_or_infinite with hf | hf · rcases exists_lt_card_finite_nth_eq hf ha with ⟨n, hn, rfl⟩ rcases lt_or_ge (k + 1) #hf.toFinset with hk | hk · rwa [(nth_strictMonoOn hf).lt_iff_lt hn hk, Nat.lt_succ_iff, @@ -274,10 +277,10 @@ theorem le_nth_of_lt_nth_succ {k a : ℕ} (h : a < nth p (k + 1)) (ha : p a) : a rwa [nth_lt_nth hf, Nat.lt_succ_iff, ← nth_le_nth hf] at h lemma nth_mem_anti {a b : ℕ} (hab : a ≤ b) (h : p (nth p b)) : p (nth p a) := by - by_cases h' : ∀ hf : (setOf p).Finite, a < #hf.toFinset + by_cases h' : ∀ hf : (Set.ofPred p).Finite, a < #hf.toFinset · exact nth_mem a h' · simp only [not_forall, not_lt] at h' - have h'b : ∃ hf : (setOf p).Finite, #hf.toFinset ≤ b := by + have h'b : ∃ hf : (Set.ofPred p).Finite, #hf.toFinset ≤ b := by rcases h' with ⟨hf, ha⟩ exact ⟨hf, ha.trans hab⟩ have ha0 : nth p a = 0 := by simp [nth_eq_zero, h'] @@ -285,12 +288,15 @@ lemma nth_mem_anti {a b : ℕ} (hab : a ≤ b) (h : p (nth p b)) : p (nth p a) : rw [ha0] rwa [hb0] at h -/-- `Nat.nth p` is the least strictly monotone function whose image is contained in `setOf p` -/ +/-- `Nat.nth p` is the least strictly monotone function whose image is contained in +`Set.ofPred p` -/ lemma nth_le_of_strictMonoOn_of_mapsTo {p : ℕ → Prop} (f : ℕ → ℕ) - (hmaps : Set.MapsTo f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card } (setOf p)) - (hmono : StrictMonoOn f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card }) {n : ℕ} : + (hmaps : Set.MapsTo f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card } + (Set.ofPred p)) + (hmono : StrictMonoOn f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card }) + {n : ℕ} : nth p n ≤ f n := by - by_cases! hn : (∀ hf : Set.Finite (setOf p), n < hf.toFinset.card) + by_cases! hn : (∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card) · induction n using Nat.strong_induction_on with | _ n ih => rw [nth_eq_sInf] refine csInf_le (by simp) ⟨hmaps hn, fun k hk => ?_⟩ @@ -300,11 +306,13 @@ lemma nth_le_of_strictMonoOn_of_mapsTo {p : ℕ → Prop} (f : ℕ → ℕ) rw [nth, dif_pos hf, List.getD_eq_default _ _ (by simp [hn])] exact Nat.zero_le _ -/-- `Nat.nth p` is the greatest monotone function whose image contains `setOf p`. -/ +/-- `Nat.nth p` is the greatest monotone function whose image contains `Set.ofPred p`. -/ lemma le_nth_of_monotoneOn_of_surjOn {p : ℕ → Prop} (f : ℕ → ℕ) - (hsurj : Set.SurjOn f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card } (setOf p)) - (hmono : MonotoneOn f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card }) {n : ℕ} - (hn : ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card) : f n ≤ nth p n := by + (hsurj : Set.SurjOn f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card } + (Set.ofPred p)) + (hmono : MonotoneOn f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card }) + {n : ℕ} + (hn : ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card) : f n ≤ nth p n := by induction n with | zero => rw [Nat.nth_zero] @@ -322,21 +330,23 @@ lemma le_nth_of_monotoneOn_of_surjOn {p : ℕ → Prop} (f : ℕ → ℕ) rw [Nat.succ_le_iff] apply hmono.reflect_lt <;> grind -/-- `Nat.nth p` is the unique strictly monotone function whose image is `setOf p`. -/ +/-- `Nat.nth p` is the unique strictly monotone function whose image is `Set.ofPred p`. -/ lemma eq_nth_of_strictMonoOn_of_mapsTo_of_surjOn {p : ℕ → Prop} (f : ℕ → ℕ) - (hsurj : Set.SurjOn f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card } (setOf p)) - (hmaps : Set.MapsTo f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card } (setOf p)) - (hmono : StrictMonoOn f { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card }) : - Set.EqOn f (nth p) { n : ℕ | ∀ hf : Set.Finite (setOf p), n < hf.toFinset.card } := + (hsurj : Set.SurjOn f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card } + (Set.ofPred p)) + (hmaps : Set.MapsTo f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card } + (Set.ofPred p)) + (hmono : StrictMonoOn f { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card }) : + Set.EqOn f (nth p) { n : ℕ | ∀ hf : Set.Finite (Set.ofPred p), n < hf.toFinset.card } := fun _ hi => le_antisymm (Nat.le_nth_of_monotoneOn_of_surjOn _ hsurj hmono.monotoneOn hi) (Nat.nth_le_of_strictMonoOn_of_mapsTo _ hmaps hmono) lemma nth_comp_of_strictMono {n : ℕ} {f : ℕ → ℕ} (hf : StrictMono f) - (h0 : ∀ k, p k → k ∈ Set.range f) (h : ∀ hfi : (setOf p).Finite, n < hfi.toFinset.card) : + (h0 : ∀ k, p k → k ∈ Set.range f) (h : ∀ hfi : (Set.ofPred p).Finite, n < hfi.toFinset.card) : f (nth (fun i ↦ p (f i)) n) = nth p n := by have hs {p' : ℕ → Prop} (h0p' : ∀ k, p' k → k ∈ Set.range f) : - f '' {i | p' (f i)} = setOf p' := by + f '' {i | p' (f i)} = Set.ofPred p' := by ext i refine ⟨fun ⟨_, hi, h⟩ ↦ h ▸ hi, fun he ↦ ?_⟩ rcases h0p' _ he with ⟨t, rfl⟩ @@ -347,7 +357,7 @@ lemma nth_comp_of_strictMono {n : ℕ} {f : ℕ → ℕ} (hf : StrictMono f) replace h := nth_mem _ h rw [← hs h0, ← hf.monotone.map_csInf] rcases h0 _ h with ⟨t, ht⟩ - exact ⟨t, Set.mem_setOf_eq ▸ ht ▸ h⟩ + exact ⟨t, Set.mem_ofPred_eq ▸ ht ▸ h⟩ case _ n ih => repeat nth_rw 1 [nth_eq_sInf] have h0' : ∀ k', (p k' ∧ ∀ k < n + 1, nth p k < k') → k' ∈ Set.range f := fun _ h ↦ h0 _ h.1 @@ -397,7 +407,7 @@ theorem filter_range_nth_subset_insert (k : ℕ) : variable {p} theorem filter_range_nth_eq_insert {k : ℕ} - (hlt : ∀ hf : (setOf p).Finite, k + 1 < #hf.toFinset) : + (hlt : ∀ hf : (Set.ofPred p).Finite, k + 1 < #hf.toFinset) : {n ∈ range (nth p (k + 1)) | p n} = insert (nth p k) {n ∈ range (nth p k) | p n} := by refine (filter_range_nth_subset_insert p k).antisymm fun a ha => ?_ simp only [mem_insert, mem_filter, mem_range] at ha ⊢ @@ -406,16 +416,16 @@ theorem filter_range_nth_eq_insert {k : ℕ} · exact ⟨this, nth_mem _ fun hf => k.lt_succ_self.trans (hlt hf)⟩ · exact ⟨hlt.trans this, hpa⟩ -theorem filter_range_nth_eq_insert_of_finite (hf : (setOf p).Finite) {k : ℕ} +theorem filter_range_nth_eq_insert_of_finite (hf : (Set.ofPred p).Finite) {k : ℕ} (hlt : k + 1 < #hf.toFinset) : {n ∈ range (nth p (k + 1)) | p n} = insert (nth p k) {n ∈ range (nth p k) | p n} := filter_range_nth_eq_insert fun _ => hlt -theorem filter_range_nth_eq_insert_of_infinite (hp : (setOf p).Infinite) (k : ℕ) : +theorem filter_range_nth_eq_insert_of_infinite (hp : (Set.ofPred p).Infinite) (k : ℕ) : {n ∈ range (nth p (k + 1)) | p n} = insert (nth p k) {n ∈ range (nth p k) | p n} := filter_range_nth_eq_insert fun hf => absurd hf hp -theorem count_nth {n : ℕ} (hn : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : +theorem count_nth {n : ℕ} (hn : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : count p (nth p n) = n := by induction n with | zero => exact count_nth_zero _ @@ -424,27 +434,30 @@ theorem count_nth {n : ℕ} (hn : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : ← count_eq_card_filter_range, ihk fun hf => lt_of_succ_lt (hn hf)] simp -theorem count_nth_of_lt_card_finite {n : ℕ} (hp : (setOf p).Finite) (hlt : n < #hp.toFinset) : +theorem count_nth_of_lt_card_finite {n : ℕ} (hp : (Set.ofPred p).Finite) (hlt : n < #hp.toFinset) : count p (nth p n) = n := count_nth fun _ => hlt -theorem count_nth_of_infinite (hp : (setOf p).Infinite) (n : ℕ) : count p (nth p n) = n := +theorem count_nth_of_infinite (hp : (Set.ofPred p).Infinite) (n : ℕ) : count p (nth p n) = n := count_nth fun hf => absurd hf hp -theorem surjective_count_of_infinite_setOf (h : {n | p n}.Infinite) : +theorem surjective_count_of_infinite_setOfPred (h : {n | p n}.Infinite) : Function.Surjective (Nat.count p) := fun n => ⟨nth p n, count_nth_of_infinite h n⟩ -theorem count_nth_succ {n : ℕ} (hn : ∀ hf : (setOf p).Finite, n < #hf.toFinset) : +@[deprecated (since := "2026-07-09")] +alias surjective_count_of_infinite_setOf := surjective_count_of_infinite_setOfPred + +theorem count_nth_succ {n : ℕ} (hn : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : count p (nth p n + 1) = n + 1 := by rw [count_succ, count_nth hn, if_pos (nth_mem _ hn)] -lemma count_nth_succ_of_infinite (hp : (setOf p).Infinite) (n : ℕ) : +lemma count_nth_succ_of_infinite (hp : (Set.ofPred p).Infinite) (n : ℕ) : count p (nth p n + 1) = n + 1 := by rw [count_succ, count_nth_of_infinite hp, if_pos (nth_mem_of_infinite hp _)] @[simp] theorem nth_count {n : ℕ} (hpn : p n) : nth p (count p n) = n := - have : ∀ hf : (setOf p).Finite, count p n < #hf.toFinset := fun hf => count_lt_card hf hpn + have : ∀ hf : (Set.ofPred p).Finite, count p n < #hf.toFinset := fun hf => count_lt_card hf hpn count_injective (nth_mem _ this) hpn (count_nth this) theorem nth_lt_of_lt_count {n k : ℕ} (h : k < count p n) : nth p k < n := by @@ -469,23 +482,25 @@ theorem nth_count_eq_sInf (n : ℕ) : nth p (count p n) = sInf {i : ℕ | p i theorem le_nth_count' {n : ℕ} (hpn : ∃ k, p k ∧ n ≤ k) : n ≤ nth p (count p n) := (le_csInf hpn fun _ => And.right).trans (nth_count_eq_sInf p n).ge -theorem le_nth_count (hp : (setOf p).Infinite) (n : ℕ) : n ≤ nth p (count p n) := +theorem le_nth_count (hp : (Set.ofPred p).Infinite) (n : ℕ) : n ≤ nth p (count p n) := let ⟨m, hp, hn⟩ := hp.exists_gt n le_nth_count' ⟨m, hp, hn.le⟩ /-- If a predicate `p : ℕ → Prop` is true for infinitely many numbers, then `Nat.count p` and `Nat.nth p` form a Galois insertion. -/ -noncomputable def giCountNth (hp : (setOf p).Infinite) : GaloisInsertion (count p) (nth p) := +noncomputable def giCountNth (hp : (Set.ofPred p).Infinite) : GaloisInsertion (count p) (nth p) := GaloisInsertion.monotoneIntro (nth_monotone hp) (count_monotone p) (le_nth_count hp) (count_nth_of_infinite hp) -theorem gc_count_nth (hp : (setOf p).Infinite) : GaloisConnection (count p) (nth p) := +theorem gc_count_nth (hp : (Set.ofPred p).Infinite) : GaloisConnection (count p) (nth p) := (giCountNth hp).gc -theorem count_le_iff_le_nth (hp : (setOf p).Infinite) {a b : ℕ} : count p a ≤ b ↔ a ≤ nth p b := +theorem count_le_iff_le_nth (hp : (Set.ofPred p).Infinite) {a b : ℕ} : + count p a ≤ b ↔ a ≤ nth p b := gc_count_nth hp _ _ -theorem lt_nth_iff_count_lt (hp : (setOf p).Infinite) {a b : ℕ} : a < count p b ↔ nth p a < b := +theorem lt_nth_iff_count_lt (hp : (Set.ofPred p).Infinite) {a b : ℕ} : + a < count p b ↔ nth p a < b := (gc_count_nth hp).lt_iff_lt end Count @@ -496,10 +511,10 @@ theorem nth_of_forall {n : ℕ} (hp : ∀ n' ≤ n, p n') : nth p n = n := by @[simp] theorem nth_true (n : ℕ) : nth (fun _ ↦ True) n = n := nth_of_forall fun _ _ ↦ trivial theorem nth_of_forall_not {n : ℕ} (hp : ∀ n' ≥ n, ¬p n') : nth p n = 0 := by - have : setOf p ⊆ Finset.range n := by + have : Set.ofPred p ⊆ Finset.range n := by intro n' hn' contrapose! hp - exact ⟨n', by simpa using hp, Set.mem_setOf.mp hn'⟩ + exact ⟨n', by simpa using hp, Set.mem_ofPred.mp hn'⟩ rw [nth_of_card_le ((finite_toSet _).subset this)] · refine (Finset.card_le_card ?_).trans_eq (Finset.card_range n) exact Set.Finite.toFinset_subset.mpr this diff --git a/Mathlib/Data/Nat/Prime/Infinite.lean b/Mathlib/Data/Nat/Prime/Infinite.lean index f9e54e918ade47..f7a007c806f2ba 100644 --- a/Mathlib/Data/Nat/Prime/Infinite.lean +++ b/Mathlib/Data/Nat/Prime/Infinite.lean @@ -13,8 +13,8 @@ public import Mathlib.Order.Bounds.Basic ## Notable Theorems - `Nat.exists_infinite_primes`: Euclid's theorem that there exist infinitely many prime numbers. - This also appears as `Nat.not_bddAbove_setOf_prime` and `Nat.infinite_setOf_prime` (the latter - in `Data.Nat.PrimeFin`). + This also appears as `Nat.not_bddAbove_setOfPred_prime` and `Nat.infinite_setOfPred_prime` + (the latter in `Data.Nat.PrimeFin`). -/ @@ -42,12 +42,14 @@ theorem exists_infinite_primes (n : ℕ) : ∃ p, n ≤ p ∧ Prime p := ⟨p, np, pp⟩ /-- A version of `Nat.exists_infinite_primes` using the `BddAbove` predicate. -/ -theorem not_bddAbove_setOf_prime : ¬BddAbove { p | Prime p } := by +theorem not_bddAbove_setOfPred_prime : ¬BddAbove { p | Prime p } := by rw [not_bddAbove_iff] intro n obtain ⟨p, hi, hp⟩ := exists_infinite_primes n.succ exact ⟨p, hp, hi⟩ +@[deprecated (since := "2026-07-09")] alias not_bddAbove_setOf_prime := not_bddAbove_setOfPred_prime + end Infinite end Nat diff --git a/Mathlib/Data/Nat/PrimeFin.lean b/Mathlib/Data/Nat/PrimeFin.lean index c41c68e716e921..91f5c33b25f84f 100644 --- a/Mathlib/Data/Nat/PrimeFin.lean +++ b/Mathlib/Data/Nat/PrimeFin.lean @@ -24,10 +24,12 @@ namespace Nat variable {a b k m n p : ℕ} /-- A version of `Nat.exists_infinite_primes` using the `Set.Infinite` predicate. -/ -theorem infinite_setOf_prime : { p | Prime p }.Infinite := - Set.infinite_of_not_bddAbove not_bddAbove_setOf_prime +theorem infinite_setOfPred_prime : { p | Prime p }.Infinite := + Set.infinite_of_not_bddAbove not_bddAbove_setOfPred_prime -instance Primes.infinite : Infinite Primes := infinite_setOf_prime.to_subtype +@[deprecated (since := "2026-07-09")] alias infinite_setOf_prime := infinite_setOfPred_prime + +instance Primes.infinite : Infinite Primes := infinite_setOfPred_prime.to_subtype instance Primes.countable : Countable Primes := ⟨⟨coeNat.coe, coe_nat_injective⟩⟩ diff --git a/Mathlib/Data/PFunctor/Multivariate/Basic.lean b/Mathlib/Data/PFunctor/Multivariate/Basic.lean index 4264be645cc75a..ad6de96641ef8f 100644 --- a/Mathlib/Data/PFunctor/Multivariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Multivariate/Basic.lean @@ -183,7 +183,7 @@ open Set theorem supp_eq {α : TypeVec n} (a : P.A) (f : P.B a ⟹ α) (i) : @supp.{u} _ P.Obj _ α (⟨a, f⟩ : P α) i = f i '' univ := by - ext x; simp only [supp, image_univ, mem_range, mem_setOf_eq] + ext x; simp only [supp, image_univ, mem_range, mem_ofPred_eq] constructor <;> intro h · apply @h fun i x => ∃ y : P.B a i, f i y = x rw [liftP_iff'] diff --git a/Mathlib/Data/PFunctor/Univariate/Basic.lean b/Mathlib/Data/PFunctor/Univariate/Basic.lean index 1c87cac24b1125..4bb1cd66674ebf 100644 --- a/Mathlib/Data/PFunctor/Univariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Univariate/Basic.lean @@ -219,7 +219,7 @@ open Set theorem supp_eq {α : Type u} (a : P.A) (f : P.B a → α) : @supp.{u} P.Obj _ α (⟨a, f⟩ : P α) = f '' univ := by - ext x; simp only [supp, image_univ, mem_range, mem_setOf_eq] + ext x; simp only [supp, image_univ, mem_range, mem_ofPred_eq] constructor <;> intro h · apply @h fun x => ∃ y : P.B a, f y = x rw [liftp_iff'] diff --git a/Mathlib/Data/Prod/TProd.lean b/Mathlib/Data/Prod/TProd.lean index 5331bd81ce5ca1..5188a52ccf1468 100644 --- a/Mathlib/Data/Prod/TProd.lean +++ b/Mathlib/Data/Prod/TProd.lean @@ -148,7 +148,7 @@ theorem mk_preimage_tprod : rw [mk_preimage_tprod l t] -- `simp [Set.TProd, TProd.mk, this]` can close this goal but is slow. rw [Set.tprod, TProd.mk, mem_preimage, mem_pi, prodMk_mem_set_prod_eq] - simp_rw [mem_setOf_eq, mem_cons] + simp_rw [mem_ofPred_eq, mem_cons] rw [forall_eq_or_imp, and_congr_right_iff] exact fun _ => h diff --git a/Mathlib/Data/QPF/Multivariate/Basic.lean b/Mathlib/Data/QPF/Multivariate/Basic.lean index 1deb05fd27c844..db6cc797aaa84f 100644 --- a/Mathlib/Data/QPF/Multivariate/Basic.lean +++ b/Mathlib/Data/QPF/Multivariate/Basic.lean @@ -262,7 +262,7 @@ theorem suppPreservation_iff_liftpPreservation : q.SuppPreservation ↔ q.LiftPP · rintro α ⟨a, f⟩ simp only [LiftPPreservation] at h ext - simp only [supp, h, mem_setOf_eq] + simp only [supp, h, mem_ofPred_eq] theorem liftpPreservation_iff_uniform : q.LiftPPreservation ↔ q.IsUniform := by rw [← suppPreservation_iff_liftpPreservation, suppPreservation_iff_isUniform] diff --git a/Mathlib/Data/Real/Embedding.lean b/Mathlib/Data/Real/Embedding.lean index b7afcbc8feaedf..01c3a583913309 100644 --- a/Mathlib/Data/Real/Embedding.lean +++ b/Mathlib/Data/Real/Embedding.lean @@ -70,7 +70,7 @@ abbrev ratLt (x : M) : Set ℚ := {r | r.num • 1 < r.den • x} theorem mkRat_mem_ratLt {num : ℤ} {den : ℕ} (hden : den ≠ 0) {x : M} : mkRat num den ∈ ratLt x ↔ num • 1 < den • x := by - rw [Set.mem_setOf] + rw [Set.mem_ofPred] obtain ⟨m, hm0, hnum, hden⟩ := Rat.mkRat_num_den hden (show mkRat num den = _ by rfl) conv in num • 1 => rw [hnum, mul_comm, ← smul_smul, natCast_zsmul] conv in den • x => rw [hden, mul_comm, ← smul_smul] @@ -119,7 +119,7 @@ theorem ratLt_add (x y : M) : ratLt (x + y) = ratLt x + ratLt y := by To ensure a large enough denominator, we take `d * k`, where `1 + 1 ≤ k • (d • (x + y) - a.num • 1)`. -/ intro h - rw [Set.mem_setOf_eq] at h + rw [Set.mem_ofPred_eq] at h obtain ⟨k, hk⟩ := Archimedean.arch (1 + 1) <| sub_pos.mpr h have hk0 : k ≠ 0 := by contrapose! hk @@ -143,7 +143,7 @@ theorem ratLt_add (x y : M) : ratLt (x + y) = ratLt x + ratLt y := by · -- `u ∈ ratLt 1 x`, `v ∈ ratLt 1 y` → `u + v ∈ ratLt 1 (x + y)` intro ⟨u, hu, v, hv, huv⟩ rw [← huv] - rw [Set.mem_setOf_eq] at hu hv ⊢ + rw [Set.mem_ofPred_eq] at hu hv ⊢ exact num_smul_one_lt_den_smul_add hu hv theorem ratLt'_bddAbove (x : M) : BddAbove (ratLt' x) := diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index 27e048988a4e4f..958e231c1ac313 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -143,9 +143,11 @@ instance (s : Set α) : CoeTC s α := ⟨fun x => x.1⟩ theorem Set.coe_eq_subtype (s : Set α) : ↥s = { x // x ∈ s } := rfl -theorem Set.coe_setOf (p : α → Prop) : ↥{ x | p x } = { x // p x } := +theorem Set.coe_ofPred (p : α → Prop) : ↥{ x | p x } = { x // p x } := rfl +@[deprecated (since := "2026-07-09")] alias Set.coe_setOf := Set.coe_ofPred + theorem SetCoe.forall {s : Set α} {p : s → Prop} : (∀ x : s, p x) ↔ ∀ (x) (h : x ∈ s), p ⟨x, h⟩ := Subtype.forall @@ -189,34 +191,53 @@ instance : Inhabited (Set α) := theorem mem_of_mem_of_subset {x : α} {s t : Set α} (hx : x ∈ s) (h : s ⊆ t) : x ∈ t := h hx -theorem setOf_injective : Function.Injective (@setOf α) := injective_id +theorem ofPred_injective : Function.Injective (@ofPred α) := injective_id + +@[deprecated (since := "2026-07-09")] alias setOf_injective := ofPred_injective + +theorem ofPred_inj {p q : α → Prop} : { x | p x } = { x | q x } ↔ p = q := Iff.rfl -theorem setOf_inj {p q : α → Prop} : { x | p x } = { x | q x } ↔ p = q := Iff.rfl +@[deprecated (since := "2026-07-09")] alias setOf_inj := ofPred_inj -/-! ### Lemmas about `mem` and `setOf` -/ +/-! ### Lemmas about `mem` and `ofPred` -/ -theorem setOf_bijective : Bijective (setOf : (α → Prop) → Set α) := +theorem ofPred_bijective : Bijective (ofPred : (α → Prop) → Set α) := bijective_id -theorem subset_setOf {p : α → Prop} {s : Set α} : s ⊆ setOf p ↔ ∀ x, x ∈ s → p x := +@[deprecated (since := "2026-07-09")] alias setOf_bijective := ofPred_bijective + +theorem subset_ofPred {p : α → Prop} {s : Set α} : s ⊆ ofPred p ↔ ∀ x, x ∈ s → p x := Iff.rfl -theorem setOf_subset {p : α → Prop} {s : Set α} : setOf p ⊆ s ↔ ∀ x, p x → x ∈ s := +@[deprecated (since := "2026-07-09")] alias subset_setOf := subset_ofPred + +theorem ofPred_subset {p : α → Prop} {s : Set α} : ofPred p ⊆ s ↔ ∀ x, p x → x ∈ s := Iff.rfl +@[deprecated (since := "2026-07-09")] alias setOf_subset := ofPred_subset + @[simp] -theorem setOf_subset_setOf {p q : α → Prop} : { a | p a } ⊆ { a | q a } ↔ ∀ a, p a → q a := +theorem ofPred_subset_ofPred {p q : α → Prop} : { a | p a } ⊆ { a | q a } ↔ ∀ a, p a → q a := Iff.rfl +@[deprecated (since := "2026-07-09")] alias setOf_subset_setOf := ofPred_subset_ofPred + @[gcongr] -alias ⟨_, setOf_subset_setOf_of_imp⟩ := setOf_subset_setOf +alias ⟨_, ofPred_subset_ofPred_of_imp⟩ := ofPred_subset_ofPred -theorem setOf_and {p q : α → Prop} : { a | p a ∧ q a } = { a | p a } ∩ { a | q a } := +@[deprecated (since := "2026-07-09")] +alias setOf_subset_setOf_of_imp := ofPred_subset_ofPred_of_imp + +theorem ofPred_and {p q : α → Prop} : { a | p a ∧ q a } = { a | p a } ∩ { a | q a } := rfl -theorem setOf_or {p q : α → Prop} : { a | p a ∨ q a } = { a | p a } ∪ { a | q a } := +@[deprecated (since := "2026-07-09")] alias setOf_and := ofPred_and + +theorem ofPred_or {p q : α → Prop} : { a | p a ∨ q a } = { a | p a } ∪ { a | q a } := rfl +@[deprecated (since := "2026-07-09")] alias setOf_or := ofPred_or + /-! ### Subset and strict subset relations -/ -- TODO(Jeremy): write a tactic to unfold specific instances of generic notation? @@ -402,10 +423,15 @@ theorem mem_empty_iff_false (x : α) : x ∈ (∅ : Set α) ↔ False := Iff.rfl @[simp, grind =] -theorem setOf_false : { _a : α | False } = ∅ := +theorem ofPred_false : { _a : α | False } = ∅ := rfl -@[simp] theorem setOf_bot : { _x : α | ⊥ } = ∅ := rfl +@[deprecated (since := "2026-07-09")] alias setOf_false := ofPred_false + +@[simp] theorem ofPred_bot : { _x : α | ⊥ } = ∅ := rfl + +@[deprecated (since := "2026-07-09")] +alias setOf_bot := ofPred_bot @[simp] theorem empty_subset (s : Set α) : ∅ ⊆ s := @@ -500,10 +526,15 @@ Mathematically it is the same as `α` but it has a different type. @[simp, grind =] -theorem setOf_true : { _x : α | True } = univ := +theorem ofPred_true : { _x : α | True } = univ := rfl -@[simp] theorem setOf_top : { _x : α | ⊤ } = univ := rfl +@[deprecated (since := "2026-07-09")] alias setOf_true := ofPred_true + +@[simp] theorem ofPred_top : { _x : α | ⊤ } = univ := rfl + +@[deprecated (since := "2026-07-09")] +alias setOf_top := ofPred_top @[simp] theorem univ_eq_empty_iff : (univ : Set α) = ∅ ↔ IsEmpty α := @@ -802,15 +833,20 @@ theorem union_inter_cancel_left {s t : Set α} : (s ∪ t) ∩ s = s := theorem union_inter_cancel_right {s t : Set α} : (s ∪ t) ∩ t = t := inter_eq_self_of_subset_right subset_union_right -theorem inter_setOf_eq_sep (s : Set α) (p : α → Prop) : s ∩ {a | p a} = {a ∈ s | p a} := +theorem inter_ofPred_eq_sep (s : Set α) (p : α → Prop) : s ∩ {a | p a} = {a ∈ s | p a} := rfl -theorem setOf_inter_eq_sep (p : α → Prop) (s : Set α) : {a | p a} ∩ s = {a ∈ s | p a} := +@[deprecated (since := "2026-07-09")] +alias inter_setOf_eq_sep := inter_ofPred_eq_sep + +theorem ofPred_inter_eq_sep (p : α → Prop) (s : Set α) : {a | p a} ∩ s = {a ∈ s | p a} := inter_comm _ _ +@[deprecated (since := "2026-07-09")] alias setOf_inter_eq_sep := ofPred_inter_eq_sep + theorem sep_eq_inter_sep {α : Type*} {s t : Set α} {p : α → Prop} (hst : s ⊆ t) : {x ∈ s | p x} = s ∩ {x ∈ t | p x} := by - rw [← inter_setOf_eq_sep s p, ← inter_setOf_eq_sep t p, + rw [← inter_ofPred_eq_sep s p, ← inter_ofPred_eq_sep t p, ← inter_assoc, ← left_eq_inter.mpr hst] @[simp] @@ -879,9 +915,12 @@ theorem sep_eq_of_subset (h : s ⊆ t) : { x ∈ t | x ∈ s } = s := @[simp] theorem sep_subset (s : Set α) (p : α → Prop) : { x ∈ s | p x } ⊆ s := fun _ => And.left -theorem sep_subset_setOf (s : Set α) (p : α → Prop) : { x ∈ s | p x } ⊆ { x | p x } := +theorem sep_subset_ofPred (s : Set α) (p : α → Prop) : { x ∈ s | p x } ⊆ { x | p x } := fun _ => And.right +@[deprecated (since := "2026-07-09")] +alias sep_subset_setOf := sep_subset_ofPred + @[simp] theorem sep_eq_self_iff_mem_true : { x ∈ s | p x } = s ↔ ∀ x ∈ s, p x := by simp_rw [Set.ext_iff, mem_sep_iff, and_iff_left_iff_imp] @@ -919,9 +958,12 @@ theorem sep_or : { x ∈ s | p x ∨ q x } = { x ∈ s | p x } ∪ { x ∈ s | q inter_union_distrib_left s {x | p x} {x | q x} @[simp] -theorem sep_setOf : { x ∈ { y | p y } | q x } = { x | p x ∧ q x } := +theorem sep_ofPred : { x ∈ { y | p y } | q x } = { x | p x ∧ q x } := rfl +@[deprecated (since := "2026-07-09")] +alias sep_setOf := sep_ofPred + end Sep /-! ### Powerset -/ diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index ed4397a4baa62c..84b2e41a1f8aed 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -282,7 +282,7 @@ theorem Finite.encard_lt_encard (hs : s.Finite) (h : s ⊂ t) : s.encard < t.enc theorem encard_strictMono [Finite α] : StrictMono (encard : Set α → ℕ∞) := fun _ _ h ↦ (toFinite _).encard_lt_encard h -theorem Finite.encard_strictMonoOn : StrictMonoOn (α := Set α) encard (setOf Set.Finite) := +theorem Finite.encard_strictMonoOn : StrictMonoOn (α := Set α) encard (Set.ofPred Set.Finite) := fun _ hs _ _ hlt ↦ hs.encard_lt_encard hlt theorem Finite.encard_lt_card (hfin : s.Finite) (hne : s ≠ univ) : s.encard < ENat.card α := @@ -845,7 +845,7 @@ theorem fiber_ncard_ne_zero_iff_mem_image {y : β} (hs : s.Finite := by toFinite ncard_image_of_injective _ f.inj' @[simp] theorem ncard_subtype (P : α → Prop) (s : Set α) : - { x : Subtype P | (x : α) ∈ s }.ncard = (s ∩ setOf P).ncard := by + { x : Subtype P | (x : α) ∈ s }.ncard = (s ∩ Set.ofPred P).ncard := by convert! (ncard_image_of_injective _ (@Subtype.coe_injective _ P)).symm ext x simp [← and_assoc, exists_eq_right] @@ -886,7 +886,7 @@ theorem ncard_lt_card [Finite α] (h : s ≠ univ) : s.ncard < Nat.card α := theorem ncard_strictMono [Finite α] : @StrictMono (Set α) _ _ _ ncard := fun _ _ h ↦ ncard_lt_ncard h -theorem Finite.ncard_strictMonoOn : StrictMonoOn (α := Set α) ncard (setOf Set.Finite) := +theorem Finite.ncard_strictMonoOn : StrictMonoOn (α := Set α) ncard (Set.ofPred Set.Finite) := fun _ _ _ ht hlt ↦ ncard_lt_ncard hlt ht theorem ncard_eq_of_bijective {n : ℕ} (f : ∀ i, i < n → α) diff --git a/Mathlib/Data/Set/Countable.lean b/Mathlib/Data/Set/Countable.lean index 6fd4b121fdd197..01d8ac63eef4e7 100644 --- a/Mathlib/Data/Set/Countable.lean +++ b/Mathlib/Data/Set/Countable.lean @@ -270,7 +270,7 @@ theorem countable_isBot (α : Type*) [PartialOrder α] : { x : α | IsBot x }.Co (finite_isBot α).countable /-- The set of finite subsets of a countable set is countable. -/ -theorem countable_setOf_finite_subset {s : Set α} (hs : s.Countable) : +theorem countable_ofPred_finite_subset {s : Set α} (hs : s.Countable) : { t | Set.Finite t ∧ t ⊆ s }.Countable := by have := hs.to_subtype refine (countable_range fun t : Finset s => Subtype.val '' (t : Set s)).mono ?_ @@ -279,9 +279,14 @@ theorem countable_setOf_finite_subset {s : Set α} (hs : s.Countable) : lift t to Finset s using ht.of_finite_image Subtype.val_injective.injOn exact mem_range_self _ +@[deprecated (since := "2026-07-09")] +alias countable_setOf_finite_subset := countable_ofPred_finite_subset + /-- The set of finite sets in a countable type is countable. -/ -theorem Countable.setOf_finite [Countable α] : {s : Set α | s.Finite}.Countable := by - simpa using countable_setOf_finite_subset countable_univ +theorem Countable.ofPred_finite [Countable α] : {s : Set α | s.Finite}.Countable := by + simpa using countable_ofPred_finite_subset countable_univ + +@[deprecated (since := "2026-07-09")] alias Countable.setOf_finite := Countable.ofPred_finite /-- If the codomain of a map is countable and the fibres are countable, the domain is countable. -/ @@ -309,7 +314,7 @@ theorem Countable.image2 {s : Set α} {t : Set β} (hs : s.Countable) (ht : t.Co /-- If a family of disjoint sets is included in a countable set, then only countably many of them are nonempty. -/ -theorem countable_setOf_nonempty_of_disjoint {f : β → Set α} +theorem countable_ofPred_nonempty_of_disjoint {f : β → Set α} (hf : Pairwise (Disjoint on f)) {s : Set α} (h'f : ∀ t, f t ⊆ s) (hs : s.Countable) : Set.Countable {t | (f t).Nonempty} := by rw [← Set.countable_coe_iff] at hs ⊢ @@ -328,6 +333,9 @@ theorem countable_setOf_nonempty_of_disjoint {f : β → Set α} exact not_disjoint_iff_nonempty_inter.2 A (hf H) exact Injective.countable A +@[deprecated (since := "2026-07-09")] +alias countable_setOf_nonempty_of_disjoint := countable_ofPred_nonempty_of_disjoint + end Set theorem Finset.countable_toSet (s : Finset α) : Set.Countable (↑s : Set α) := diff --git a/Mathlib/Data/Set/Defs.lean b/Mathlib/Data/Set/Defs.lean index 8d3e4a504958d1..6aa0379aaef8ce 100644 --- a/Mathlib/Data/Set/Defs.lean +++ b/Mathlib/Data/Set/Defs.lean @@ -5,6 +5,7 @@ Authors: Leonardo de Moura -/ module +public import Batteries.Tactic.Alias public import Batteries.Util.ExtendedBinder public import Mathlib.Tactic.SetNotationForOrder @@ -43,8 +44,8 @@ variable {α : Type u} /-- A set is a collection of elements of some type `α`. Although `Set` is defined as `α → Prop`, this is an implementation detail which should not be -relied on. Instead, `setOf` and membership of a set (`∈`) should be used to convert between sets -and predicates. +relied on. Instead, `Set.ofPred` (also written `{x | p x}`) and membership of a set (`∈`) should be +used to convert between sets and predicates. -/ @[use_set_notation_for_order] def Set (α : Type u) := α → Prop @@ -63,9 +64,11 @@ attribute [to_dual_dont_translate] Set /-- Turn a predicate `p : α → Prop` into a set, also written as `{x | p x}` -/ @[implicit_reducible] -def setOf {α : Type u} (p : α → Prop) : Set α := +def Set.ofPred {α : Type u} (p : α → Prop) : Set α := p +@[deprecated (since := "2026-07-09")] alias setOf := Set.ofPred + namespace Set /-- Membership in a set -/ @@ -114,8 +117,8 @@ syntax (name := setBuilder) "{" extBinder " | " term "}" : term /-- Elaborate set builder notation for `Set`. -* `{x | p x}` is elaborated as `Set.setOf fun x ↦ p x` -* `{x : α | p x}` is elaborated as `Set.setOf fun x : α ↦ p x` +* `{x | p x}` is elaborated as `Set.ofPred fun x ↦ p x` +* `{x : α | p x}` is elaborated as `Set.ofPred fun x : α ↦ p x` * `{binder x | p x}`, where `x` is bound by the `binder` binder, is elaborated as `{x | binder x ∧ p x}`. The typical example is `{x ∈ s | p x}`, which is elaborated as `{x | x ∈ s ∧ p x}`. The possible binders are @@ -137,16 +140,16 @@ See also @[term_elab setBuilder] meta def elabSetBuilder : TermElab | `({ $x:ident | $p }), expectedType? => do - elabTerm (← `(setOf fun $x:ident ↦ $p)) expectedType? + elabTerm (← `(Set.ofPred fun $x:ident ↦ $p)) expectedType? | `({ $x:ident : $t | $p }), expectedType? => do - elabTerm (← `(setOf fun $x:ident : $t ↦ $p)) expectedType? + elabTerm (← `(Set.ofPred fun $x:ident : $t ↦ $p)) expectedType? | `({ $x:ident $b:binderPred | $p }), expectedType? => do - elabTerm (← `(setOf fun $x:ident ↦ satisfies_binder_pred% $x $b ∧ $p)) expectedType? + elabTerm (← `(Set.ofPred fun $x:ident ↦ satisfies_binder_pred% $x $b ∧ $p)) expectedType? | _, _ => throwUnsupportedSyntax /-- Unexpander for set builder notation. -/ -@[app_unexpander setOf] -meta def setOf.unexpander : Lean.PrettyPrinter.Unexpander +@[app_unexpander Set.ofPred] +meta def ofPred.unexpander : Lean.PrettyPrinter.Unexpander | `($_ fun $x:ident ↦ $p) => `({ $x:ident | $p }) | `($_ fun ($x:ident : $ty:term) ↦ $p) => `({ $x:ident : $ty:term | $p }) | _ => throw () @@ -186,8 +189,8 @@ macro (priority := low - 1) "{" pat:term " | " p:term "}" : term => `({ x | match x with | $pat => $p }) /-- Pretty printing for set-builder notation with pattern matching. -/ -@[app_unexpander setOf] -meta def setOfPatternMatchUnexpander : Lean.PrettyPrinter.Unexpander +@[app_unexpander Set.ofPred] +meta def ofPredPatternMatchUnexpander : Lean.PrettyPrinter.Unexpander | `($_ fun $x:ident ↦ match $y:ident with | $pat => $p) => if x == y then `({ $pat:term | $p:term }) diff --git a/Mathlib/Data/Set/Finite/Basic.lean b/Mathlib/Data/Set/Finite/Basic.lean index 0b0151b7ea9964..a56b1b759e3b7c 100644 --- a/Mathlib/Data/Set/Finite/Basic.lean +++ b/Mathlib/Data/Set/Finite/Basic.lean @@ -158,9 +158,11 @@ protected alias ⟨_, toFinset_mono⟩ := Finite.toFinset_subset_toFinset protected alias ⟨_, toFinset_strictMono⟩ := Finite.toFinset_ssubset_toFinset @[simp high] -protected theorem toFinset_setOf [Fintype α] (p : α → Prop) [DecidablePred p] +protected theorem toFinset_ofPred [Fintype α] (p : α → Prop) [DecidablePred p] (h : { x | p x }.Finite) : h.toFinset = ({x | p x} : Finset α) := by simp +@[deprecated (since := "2026-07-09")] protected alias toFinset_setOf := Set.Finite.toFinset_ofPred + @[simp] nonrec theorem disjoint_toFinset {hs : s.Finite} {ht : t.Finite} : Disjoint hs.toFinset ht.toFinset ↔ Disjoint s t := @@ -819,7 +821,7 @@ theorem Finite.card_toFinset {s : Set α} [Fintype s] (h : s.Finite) : theorem card_ne_eq [Fintype α] (a : α) [Fintype { x : α | x ≠ a }] : Fintype.card { x : α | x ≠ a } = Fintype.card α - 1 := by have := Classical.decEq α - rw [← toFinset_card, toFinset_setOf, Finset.filter_ne', + rw [← toFinset_card, toFinset_ofPred, Finset.filter_ne', Finset.card_erase_of_mem (Finset.mem_univ _), Finset.card_univ] /-! ### Infinite sets -/ diff --git a/Mathlib/Data/Set/Finite/Lattice.lean b/Mathlib/Data/Set/Finite/Lattice.lean index e2a5bcaa19b3f3..0c37fc4e09374a 100644 --- a/Mathlib/Data/Set/Finite/Lattice.lean +++ b/Mathlib/Data/Set/Finite/Lattice.lean @@ -114,7 +114,7 @@ instance finite_biUnion' {ι : Type*} (s : Set ι) [Finite s] (t : ι → Set α -/ instance finite_biUnion'' {ι : Type*} (p : ι → Prop) [h : Finite { x | p x }] (t : ι → Set α) [∀ i, Finite (t i)] : Finite (⋃ (x) (_ : p x), t x) := - @Finite.Set.finite_biUnion' _ _ (setOf p) h t _ + @Finite.Set.finite_biUnion' _ _ (Set.ofPred p) h t _ instance finite_iInter {ι : Sort*} [Nonempty ι] (t : ι → Set α) [∀ i, Finite (t i)] : Finite (⋂ i, t i) := diff --git a/Mathlib/Data/Set/Finite/Lemmas.lean b/Mathlib/Data/Set/Finite/Lemmas.lean index fef6ca46061f72..bb9e2c30db108e 100644 --- a/Mathlib/Data/Set/Finite/Lemmas.lean +++ b/Mathlib/Data/Set/Finite/Lemmas.lean @@ -39,7 +39,7 @@ namespace Set theorem Finite.fin_embedding {s : Set α} (h : s.Finite) : ∃ (n : ℕ) (f : Fin n ↪ α), range f = s := ⟨_, (Fintype.equivFin (h.toFinset : Set α)).symm.asEmbedding, by - simp only [Finset.coe_sort_coe, Equiv.asEmbedding_range, Finite.coe_toFinset, setOf_mem_eq]⟩ + simp only [Finset.coe_sort_coe, Equiv.asEmbedding_range, Finite.coe_toFinset, ofPred_mem_eq]⟩ theorem Finite.fin_param {s : Set α} (h : s.Finite) : ∃ (n : ℕ) (f : Fin n → α), Injective f ∧ range f = s := diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index cfd6250f5185c2..cf5b1e49e7485a 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -100,9 +100,11 @@ theorem preimage_ite (f : α → β) (s t₁ t₂ : Set β) : rfl @[simp] -theorem preimage_setOf_eq {p : α → Prop} {f : β → α} : f ⁻¹' { a | p a } = { a | p (f a) } := +theorem preimage_ofPred_eq {p : α → Prop} {f : β → α} : f ⁻¹' { a | p a } = { a | p (f a) } := rfl +@[deprecated (since := "2026-07-09")] alias preimage_setOf_eq := preimage_ofPred_eq + @[simp] theorem preimage_id_eq : preimage (id : α → α) = id := rfl @@ -433,12 +435,12 @@ theorem Nonempty.subset_preimage_const {s : Set α} (hs : Set.Nonempty s) (t : S @[simp] theorem preimage_injective : Injective (preimage f) ↔ Surjective f := by - rw [← Injective.of_comp_iff Set.mem_injective, ← Injective.of_comp_iff' _ Set.setOf_bijective] + rw [← Injective.of_comp_iff Set.mem_injective, ← Injective.of_comp_iff' _ Set.ofPred_bijective] exact injective_comp_right_iff_surjective @[simp] theorem preimage_surjective : Surjective (preimage f) ↔ Injective f := by - rw [← Surjective.of_comp_iff _ Set.setOf_bijective.surjective, + rw [← Surjective.of_comp_iff _ Set.ofPred_bijective.surjective, ← Surjective.of_comp_iff' Set.mem_bijective] exact surjective_comp_right_iff_injective @@ -473,9 +475,11 @@ theorem image_sdiff_preimage {f : α → β} {s : Set α} {t : Set β} : theorem compl_image : image (compl : Set α → Set α) = preimage compl := image_eq_preimage_of_inverse compl_compl compl_compl -theorem compl_image_set_of {p : Set α → Prop} : compl '' { s | p s } = { s | p sᶜ } := +theorem compl_image_ofPred {p : Set α → Prop} : compl '' { s | p s } = { s | p sᶜ } := congr_fun compl_image {x | p x} +@[deprecated (since := "2026-07-13")] alias compl_image_set_of := compl_image_ofPred + theorem inter_preimage_subset (s : Set α) (t : Set β) (f : α → β) : s ∩ f ⁻¹' t ⊆ f ⁻¹' (f '' s ∩ t) := fun _ h => ⟨mem_image_of_mem _ h.left, h.right⟩ @@ -869,7 +873,7 @@ theorem range_subtype_map {p : α → Prop} {q : β → Prop} (f : α → β) (h range (Subtype.map f h) = (↑) ⁻¹' f '' { x | p x } := by ext ⟨x, hx⟩ simp_rw [mem_preimage, mem_range, mem_image, Subtype.exists, Subtype.map] - simp only [Subtype.mk.injEq, exists_prop, mem_setOf_eq] + simp only [Subtype.mk.injEq, exists_prop, mem_ofPred_eq] theorem image_swap_eq_preimage_swap : image (@Prod.swap α β) = preimage Prod.swap := image_eq_preimage_of_inverse Prod.swap_leftInverse Prod.swap_rightInverse diff --git a/Mathlib/Data/Set/Insert.lean b/Mathlib/Data/Set/Insert.lean index 74410133de73aa..0c1f4d8fd00c74 100644 --- a/Mathlib/Data/Set/Insert.lean +++ b/Mathlib/Data/Set/Insert.lean @@ -164,13 +164,17 @@ theorem notMem_singleton_iff {a b : α} : a ∉ ({b} : Set α) ↔ a ≠ b := Iff.rfl @[simp] -theorem setOf_eq_eq_singleton {a : α} : { n | n = a } = {a} := +theorem ofPred_eq_eq_singleton {a : α} : { n | n = a } = {a} := rfl +@[deprecated (since := "2026-07-09")] alias setOf_eq_eq_singleton := ofPred_eq_eq_singleton + @[simp] -theorem setOf_eq_eq_singleton' {a : α} : { x | a = x } = {a} := +theorem ofPred_eq_eq_singleton' {a : α} : { x | a = x } = {a} := ext fun _ => eq_comm +@[deprecated (since := "2026-07-09")] alias setOf_eq_eq_singleton' := ofPred_eq_eq_singleton' + -- TODO: again, annotation needed -- Not `@[simp]` since `mem_singleton_iff` proves it. theorem mem_singleton (a : α) : a ∈ ({a} : Set α) := @@ -263,21 +267,27 @@ theorem eq_singleton_iff_nonempty_unique_mem : s = {a} ↔ s.Nonempty ∧ ∀ x theorem singleton_iff_unique_mem : (∃ a, s = {a}) ↔ ∃! a, a ∈ s := ⟨fun ⟨a, h⟩ ↦ ⟨a, by grind⟩, fun ⟨a, h⟩ ↦ ⟨a, by grind⟩⟩ -theorem setOf_mem_list_eq_replicate {l : List α} {a : α} : +theorem ofPred_mem_list_eq_replicate {l : List α} {a : α} : { x | x ∈ l } = {a} ↔ ∃ n > 0, l = List.replicate n a := by simpa +contextual [Set.ext_iff, iff_iff_implies_and_implies, forall_and, List.eq_replicate_iff, List.length_pos_iff_exists_mem] using ⟨fun _ _ ↦ ⟨_, ‹_›⟩, fun x hx h ↦ h _ hx ▸ hx⟩ -theorem setOf_mem_list_eq_singleton_of_nodup {l : List α} (H : l.Nodup) {a : α} : +@[deprecated (since := "2026-07-09")] +alias setOf_mem_list_eq_replicate := ofPred_mem_list_eq_replicate + +theorem ofPred_mem_list_eq_singleton_of_nodup {l : List α} (H : l.Nodup) {a : α} : { x | x ∈ l } = {a} ↔ l = [a] := by constructor - · rw [setOf_mem_list_eq_replicate] + · rw [ofPred_mem_list_eq_replicate] rintro ⟨n, hn, rfl⟩ simp only [List.nodup_replicate] at H simp [show n = 1 by lia] · rintro rfl simp +@[deprecated (since := "2026-07-09")] +alias setOf_mem_list_eq_singleton_of_nodup := ofPred_mem_list_eq_singleton_of_nodup + -- while `simp` is capable of proving this, it is not capable of turning the LHS into the RHS. @[simp] theorem default_coe_singleton (x : α) : (default : ({x} : Set α)) = ⟨x, rfl⟩ := diff --git a/Mathlib/Data/Set/Lattice.lean b/Mathlib/Data/Set/Lattice.lean index ed47b589df1942..f93f4440df8a70 100644 --- a/Mathlib/Data/Set/Lattice.lean +++ b/Mathlib/Data/Set/Lattice.lean @@ -133,12 +133,16 @@ theorem nonempty_of_nonempty_iUnion_eq_univ {s : ι → Set α} [Nonempty α] (h_Union : ⋃ i, s i = univ) : Nonempty ι := nonempty_of_nonempty_iUnion (s := s) (by simpa only [h_Union] using univ_nonempty) -theorem setOf_exists (p : ι → β → Prop) : { x | ∃ i, p i x } = ⋃ i, { x | p i x } := +theorem ofPred_exists (p : ι → β → Prop) : { x | ∃ i, p i x } = ⋃ i, { x | p i x } := ext fun _ => .symm <| mem_iUnion -theorem setOf_forall (p : ι → β → Prop) : { x | ∀ i, p i x } = ⋂ i, { x | p i x } := +@[deprecated (since := "2026-07-09")] alias setOf_exists := ofPred_exists + +theorem ofPred_forall (p : ι → β → Prop) : { x | ∀ i, p i x } = ⋂ i, { x | p i x } := ext fun _ => .symm <| mem_iInter +@[deprecated (since := "2026-07-09")] alias setOf_forall := ofPred_forall + theorem iUnion_subset {s : ι → Set α} {t : Set α} (h : ∀ i, s i ⊆ t) : ⋃ i, s i ⊆ t := iSup_le h @@ -254,14 +258,18 @@ theorem iInter_subset_iInter₂ (κ : ι → Sort*) (s : ι → Set α) : ⋂ i, s i ⊆ ⋂ (i) (_ : κ i), s i := iInter_mono fun _ => subset_iInter fun _ => Subset.rfl -theorem iUnion_setOf (P : ι → α → Prop) : ⋃ i, { x : α | P i x } = { x : α | ∃ i, P i x } := by +theorem iUnion_ofPred (P : ι → α → Prop) : ⋃ i, { x : α | P i x } = { x : α | ∃ i, P i x } := by ext exact mem_iUnion -theorem iInter_setOf (P : ι → α → Prop) : ⋂ i, { x : α | P i x } = { x : α | ∀ i, P i x } := by +@[deprecated (since := "2026-07-09")] alias iUnion_setOf := iUnion_ofPred + +theorem iInter_ofPred (P : ι → α → Prop) : ⋂ i, { x : α | P i x } = { x : α | ∀ i, P i x } := by ext exact mem_iInter +@[deprecated (since := "2026-07-09")] alias iInter_setOf := iInter_ofPred + theorem iUnion_congr_of_surjective {f : ι → Set α} {g : ι₂ → Set α} (h : ι → ι₂) (h1 : Surjective h) (h2 : ∀ x, g (h x) = f x) : ⋃ x, f x = ⋃ y, g y := h1.iSup_congr h h2 @@ -1435,7 +1443,7 @@ theorem inter_iInter_nat_succ (u : ℕ → Set α) : (u 0 ∩ ⋂ i, u (i + 1)) theorem iUnion_le_nat : ⋃ n : ℕ, {i | i ≤ n} = Set.univ := subset_antisymm (Set.subset_univ _) - (fun i _ ↦ Set.mem_iUnion_of_mem i (Set.mem_setOf.mpr (le_refl _))) + (fun i _ ↦ Set.mem_iUnion_of_mem i (Set.mem_ofPred.mpr (le_refl _))) end Set diff --git a/Mathlib/Data/Set/List.lean b/Mathlib/Data/Set/List.lean index 42e52369b3c860..c47835de7eee52 100644 --- a/Mathlib/Data/Set/List.lean +++ b/Mathlib/Data/Set/List.lean @@ -39,7 +39,7 @@ theorem range_list_map_coe (s : Set α) : range (map ((↑) : s → α)) = { l | @[simp] theorem range_list_get : range l.get = { x | x ∈ l } := by ext x - rw [mem_setOf_eq, mem_iff_get, mem_range] + rw [mem_ofPred_eq, mem_iff_get, mem_range] theorem range_list_getElem? : range (l[·]? : ℕ → Option α) = insert none (some '' { x | x ∈ l }) := by diff --git a/Mathlib/Data/Set/MemPartition.lean b/Mathlib/Data/Set/MemPartition.lean index 55bef6ac416f99..715e42feb60360 100644 --- a/Mathlib/Data/Set/MemPartition.lean +++ b/Mathlib/Data/Set/MemPartition.lean @@ -96,7 +96,7 @@ lemma finite_memPartition (f : ℕ → Set α) (n : ℕ) : Set.Finite (memPartit rw [memPartition_succ] have : Finite (memPartition f n) := Set.finite_coe_iff.mp ih rw [← Set.finite_coe_iff] - simp_rw [setOf_exists, ← exists_prop, setOf_exists, setOf_or] + simp_rw [ofPred_exists, ← exists_prop, ofPred_exists, ofPred_or] refine Finite.Set.finite_biUnion (memPartition f n) _ (fun u _ ↦ ?_) rw [Set.finite_coe_iff] simp diff --git a/Mathlib/Data/Set/Operations.lean b/Mathlib/Data/Set/Operations.lean index 3eba028815998d..be88d70e1d77e1 100644 --- a/Mathlib/Data/Set/Operations.lean +++ b/Mathlib/Data/Set/Operations.lean @@ -73,28 +73,38 @@ namespace Set variable {α : Type u} {β : Type v} {γ : Type w} -/-! ### Lemmas about `mem` and `setOf` -/ +/-! ### Lemmas about `mem` and `Set.ofPred` -/ @[simp, mfld_simps, push] -theorem mem_setOf_eq {x : α} {p : α → Prop} : (x ∈ {y | p y}) = p x := rfl +theorem mem_ofPred_eq {x : α} {p : α → Prop} : (x ∈ {y | p y}) = p x := rfl -grind_pattern mem_setOf_eq => x ∈ setOf p +@[deprecated (since := "2026-07-09")] alias mem_setOf_eq := mem_ofPred_eq + +grind_pattern mem_ofPred_eq => x ∈ Set.ofPred p /-- This lemma is intended for use with `rw` where a membership predicate is needed, hence the explicit argument and the equality in the reverse direction from normal. -See also `Set.mem_setOf_eq` for the reverse direction applied to an argument. -/ -theorem eq_mem_setOf (p : α → Prop) : p = (· ∈ {a | p a}) := rfl +See also `Set.mem_ofPred_eq` for the reverse direction applied to an argument. -/ +theorem eq_mem_ofPred (p : α → Prop) : p = (· ∈ {a | p a}) := rfl + +@[deprecated (since := "2026-07-09")] alias eq_mem_setOf := eq_mem_ofPred + +theorem mem_ofPred {a : α} {p : α → Prop} : a ∈ { x | p x } ↔ p a := Iff.rfl -theorem mem_setOf {a : α} {p : α → Prop} : a ∈ { x | p x } ↔ p a := Iff.rfl +@[deprecated (since := "2026-07-09")] alias mem_setOf := mem_ofPred /-- If `h : a ∈ {x | p x}` then `h.out : p x`. These are definitionally equal, but this can nevertheless be useful for various reasons, e.g. to apply further projection notation or in an argument to `simp`. -/ -alias ⟨_root_.Membership.mem.out, _⟩ := mem_setOf +alias ⟨_root_.Membership.mem.out, _⟩ := mem_ofPred + +theorem notMem_ofPred_iff {a : α} {p : α → Prop} : a ∉ { x | p x } ↔ ¬p a := Iff.rfl + +@[deprecated (since := "2026-07-09")] alias notMem_setOf_iff := notMem_ofPred_iff -theorem notMem_setOf_iff {a : α} {p : α → Prop} : a ∉ { x | p x } ↔ ¬p a := Iff.rfl +@[simp] theorem ofPred_mem_eq {s : Set α} : { x | x ∈ s } = s := rfl -@[simp] theorem setOf_mem_eq {s : Set α} : { x | x ∈ s } = s := rfl +@[deprecated (since := "2026-07-09")] alias setOf_mem_eq := ofPred_mem_eq @[simp, mfld_simps, grind ←, push] theorem mem_univ (x : α) : x ∈ @univ α := trivial diff --git a/Mathlib/Data/Set/Order.lean b/Mathlib/Data/Set/Order.lean index 4711e21232b280..f5a0749752689b 100644 --- a/Mathlib/Data/Set/Order.lean +++ b/Mathlib/Data/Set/Order.lean @@ -108,12 +108,16 @@ theorem AntitoneOn.union [Preorder β] {f g : β → Set α} {s : Set β} (hf : namespace Set -theorem monotone_setOf [Preorder α] {p : α → β → Prop} (hp : ∀ b, Monotone fun a => p a b) : +theorem monotone_ofPred [Preorder α] {p : α → β → Prop} (hp : ∀ b, Monotone fun a => p a b) : Monotone fun a => { b | p a b } := fun _ _ h b => hp b h -theorem antitone_setOf [Preorder α] {p : α → β → Prop} (hp : ∀ b, Antitone fun a => p a b) : +@[deprecated (since := "2026-07-09")] alias monotone_setOf := monotone_ofPred + +theorem antitone_ofPred [Preorder α] {p : α → β → Prop} (hp : ∀ b, Antitone fun a => p a b) : Antitone fun a => { b | p a b } := fun _ _ h b => hp b h +@[deprecated (since := "2026-07-09")] alias antitone_setOf := antitone_ofPred + /-- Quantifying over a set is antitone in the set -/ theorem antitone_bforall {P : α → Prop} : Antitone fun s : Set α => ∀ x ∈ s, P x := fun _ _ hst h x hx => h x <| hst hx diff --git a/Mathlib/Data/Set/Pairwise/Basic.lean b/Mathlib/Data/Set/Pairwise/Basic.lean index 0aa1909479279b..f1bb1b4a50a058 100644 --- a/Mathlib/Data/Set/Pairwise/Basic.lean +++ b/Mathlib/Data/Set/Pairwise/Basic.lean @@ -443,11 +443,15 @@ lemma exists_lt_mem_inter_of_not_pairwise_disjoint [LinearOrder ι] theorem pairwise_disjoint_fiber (f : ι → α) : Pairwise (Disjoint on fun a : α => f ⁻¹' {a}) := pairwise_univ.1 <| Set.pairwiseDisjoint_fiber f univ -lemma subsingleton_setOf_mem_iff_pairwise_disjoint {f : ι → Set α} : +lemma subsingleton_setOfPred_mem_iff_pairwise_disjoint {f : ι → Set α} : (∀ a, {i | a ∈ f i}.Subsingleton) ↔ Pairwise (Disjoint on f) := ⟨fun h _ _ hij ↦ disjoint_left.2 fun a hi hj ↦ hij (h a hi hj), fun h _ _ hx _ hy ↦ by_contra fun hne ↦ disjoint_left.1 (h hne) hx hy⟩ +@[deprecated (since := "2026-07-09")] +alias subsingleton_setOf_mem_iff_pairwise_disjoint := + subsingleton_setOfPred_mem_iff_pairwise_disjoint + /-- Simp normal form of `pairwise_ne_iff_injective`. -/ @[simp] lemma pairwise_not_eq_iff_injective {f : ι → α} : Pairwise (fun i j ↦ ¬ f i = f j) ↔ f.Injective := by diff --git a/Mathlib/Data/Set/Pairwise/List.lean b/Mathlib/Data/Set/Pairwise/List.lean index 4c2bc5eceb3727..5fea4d78d4e59c 100644 --- a/Mathlib/Data/Set/Pairwise/List.lean +++ b/Mathlib/Data/Set/Pairwise/List.lean @@ -34,6 +34,6 @@ theorem Nodup.pairwise_coe [Std.Symm r] (hl : l.Nodup) : rw [List.nodup_cons] at hl have : ∀ b ∈ l, ¬a = b → r a b ↔ r a b := fun b hb => imp_iff_right (ne_of_mem_of_not_mem hb hl.1).symm - simp [Set.setOf_or, Set.pairwise_insert_of_symm, ih hl.2, and_comm, forall₂_congr this] + simp [Set.ofPred_or, Set.pairwise_insert_of_symm, ih hl.2, and_comm, forall₂_congr this] end List diff --git a/Mathlib/Data/Set/PowersetCard.lean b/Mathlib/Data/Set/PowersetCard.lean index 99aa4d495c4c54..84c189271dbe53 100644 --- a/Mathlib/Data/Set/PowersetCard.lean +++ b/Mathlib/Data/Set/PowersetCard.lean @@ -40,7 +40,7 @@ open Finset Set Function @[simp] theorem mem_iff {s : Finset α} : s ∈ powersetCard α n ↔ s.card = n := by - rw [powersetCard, Set.mem_setOf_eq] + rw [powersetCard, Set.mem_ofPred_eq] instance : SetLike (powersetCard α n) α := SetLike.instSubtype diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 14341437454387..468ac76a1c6526 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -523,7 +523,7 @@ open Function.PullbackSelf Function.Pullback theorem preimage_map_fst_pullbackDiagonal {f : X → Y} {g : Z → Y} : @map_fst X Y Z f g ⁻¹' pullbackDiagonal f = pullbackDiagonal (@snd X Y Z f g) := by ext ⟨⟨p₁, p₂⟩, he⟩ - simp_rw [pullbackDiagonal, mem_setOf, Subtype.ext_iff, Prod.ext_iff] + simp_rw [pullbackDiagonal, mem_ofPred, Subtype.ext_iff, Prod.ext_iff] exact (and_iff_left he).symm theorem Function.Injective.preimage_pullbackDiagonal {f : X → Y} {g : Z → X} (inj : g.Injective) : @@ -723,7 +723,7 @@ theorem pi_if {p : ι → Prop} [h : DecidablePred p] (s : Set ι) (t₁ t₂ : by_cases p i <;> simp_all theorem union_pi : (s₁ ∪ s₂).pi t = s₁.pi t ∩ s₂.pi t := by - simp [pi, or_imp, forall_and, setOf_and] + simp [pi, or_imp, forall_and, ofPred_and] theorem union_pi_inter (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) : diff --git a/Mathlib/Data/Set/Subset.lean b/Mathlib/Data/Set/Subset.lean index ec097dbab8d9b6..ac2372f08f5be3 100644 --- a/Mathlib/Data/Set/Subset.lean +++ b/Mathlib/Data/Set/Subset.lean @@ -91,7 +91,7 @@ lemma image_val_sdiff : (↑(D \ E) : Set α) = ↑D \ ↑E := image_sdiff Subty @[simp] lemma image_val_compl : ↑(Dᶜ) = A \ ↑D := by - rw [compl_eq_univ_sdiff, image_val_sdiff, image_univ, Subtype.range_coe_subtype, setOf_mem_eq] + rw [compl_eq_univ_sdiff, image_val_sdiff, image_univ, Subtype.range_coe_subtype, ofPred_mem_eq] @[simp] lemma image_val_sUnion : ↑(⋃₀ T) = ⋃₀ { (B : Set α) | B ∈ T} := by diff --git a/Mathlib/Data/SetLike/Basic.lean b/Mathlib/Data/SetLike/Basic.lean index f99140d7ea9d9a..a7af972e724f48 100644 --- a/Mathlib/Data/SetLike/Basic.lean +++ b/Mathlib/Data/SetLike/Basic.lean @@ -193,7 +193,9 @@ lemma mem_of_subset {s : Set B} (hp : s ⊆ p) {x : B} (hx : x ∈ s) : x ∈ p @[simp] protected theorem eta (x : p) (hx : (x : B) ∈ p) : (⟨x, hx⟩ : p) = x := rfl -@[simp] lemma setOf_mem_eq (a : A) : {b | b ∈ a} = a := rfl +@[simp] lemma setOfPred_mem_eq (a : A) : {b | b ∈ a} = a := rfl + +@[deprecated (since := "2026-07-09")] alias setOf_mem_eq := setOfPred_mem_eq @[nontriviality] lemma mem_of_subsingleton [Subsingleton B] (S : A) [h : Nonempty S] {b : B} : b ∈ S := by diff --git a/Mathlib/Data/Setoid/Partition.lean b/Mathlib/Data/Setoid/Partition.lean index 0bac6f516f6728..62550098fd54b9 100644 --- a/Mathlib/Data/Setoid/Partition.lean +++ b/Mathlib/Data/Setoid/Partition.lean @@ -442,7 +442,7 @@ theorem index_out (x : hs.Quotient) : hs.index x.out = hs.index (hs.out x) := theorem proj_out (x : hs.Quotient) : hs.proj (hs.out x) = x := Quotient.inductionOn' x fun x => Quotient.sound' <| hs.some_index x -theorem class_of {x : α} : setOf (hs.setoid x) = s (hs.index x) := +theorem class_of {x : α} : Set.ofPred (hs.setoid x) = s (hs.index x) := Set.ext fun _y => eq_comm.trans hs.mem_iff_index_eq.symm theorem proj_fiber (x : hs.Quotient) : hs.proj ⁻¹' {x} = s (hs.equivQuotient.symm x) := diff --git a/Mathlib/Data/Sym/Sym2.lean b/Mathlib/Data/Sym/Sym2.lean index de8e76ca24efcc..5f887edb1c958a 100644 --- a/Mathlib/Data/Sym/Sym2.lean +++ b/Mathlib/Data/Sym/Sym2.lean @@ -324,7 +324,7 @@ theorem mem_iff' {a b c : α} : Sym2.Mem a s(b, c) ↔ a = b ∨ a = c := instance : SetLike (Sym2 α) α where coe z := { x | z.Mem x } coe_injective z z' h := by - simp only [Set.ext_iff, Set.mem_setOf_eq] at h + simp only [Set.ext_iff, Set.mem_ofPred_eq] at h obtain ⟨x, y⟩ := z obtain ⟨x', y'⟩ := z' have hx := h x; have hy := h y; have hx' := h x'; have hy' := h y' @@ -556,7 +556,10 @@ def diagSet : Set (Sym2 α) := {z | z.IsDiag} @[simp] lemma range_diag : .range (diag : α → Sym2 α) = diagSet := by ext ⟨a, b⟩; simp [diag, eq_comm] -theorem diagSet_eq_setOf_isDiag : diagSet = {z : Sym2 α | z.IsDiag} := rfl +theorem diagSet_eq_setOfPred_isDiag : diagSet = {z : Sym2 α | z.IsDiag} := rfl + +@[deprecated (since := "2026-07-09")] +alias diagSet_eq_setOf_isDiag := diagSet_eq_setOfPred_isDiag theorem diagSet_eq_univ_of_subsingleton [Subsingleton α] : @diagSet α = Set.univ := by ext; simp @@ -584,7 +587,7 @@ variable {r r₁ r₂ : α → α → Prop} of elements that are related. -/ def fromRel (sym : Std.Symm r) : Set (Sym2 α) := - setOf <| lift ⟨r, fun _ _ ↦ propext ⟨symm, symm⟩⟩ + Set.ofPred <| lift ⟨r, fun _ _ ↦ propext ⟨symm, symm⟩⟩ @[simp] theorem fromRel_prop {sym : Std.Symm r} {a b : α} : s(a, b) ∈ fromRel sym ↔ r a b := diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index 7781e58c6dcc44..9049c491aa452a 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -1283,7 +1283,7 @@ residue class of `k` mod `m`. -/ lemma Nat.range_mul_add (m k : ℕ) : Set.range (fun n : ℕ ↦ m * n + k) = {n : ℕ | (n : ZMod m) = k ∧ k ≤ n} := by ext n - simp only [Set.mem_range, Set.mem_setOf_eq] + simp only [Set.mem_range, Set.mem_ofPred_eq] conv => enter [1, 1, y]; rw [add_comm, eq_comm] refine ⟨fun ⟨a, ha⟩ ↦ ⟨?_, le_iff_exists_add.mpr ⟨_, ha⟩⟩, fun ⟨H₁, H₂⟩ ↦ ?_⟩ · simpa using congr_arg ((↑) : ℕ → ZMod m) ha diff --git a/Mathlib/Dynamics/BirkhoffSum/NormedSpace.lean b/Mathlib/Dynamics/BirkhoffSum/NormedSpace.lean index 191fe3bb458d88..45b0d101a9755c 100644 --- a/Mathlib/Dynamics/BirkhoffSum/NormedSpace.lean +++ b/Mathlib/Dynamics/BirkhoffSum/NormedSpace.lean @@ -130,7 +130,10 @@ theorem uniformEquicontinuous_birkhoffAverage (hf : LipschitzWith 1 f) (hg : Uni then the set of points `x` such that the Birkhoff average of `g` along the orbit of `x` tends to `l x` is a closed set. -/ -theorem isClosed_setOf_tendsto_birkhoffAverage +theorem isClosed_setOfPred_tendsto_birkhoffAverage (hf : LipschitzWith 1 f) (hg : UniformContinuous g) (hl : Continuous l) : IsClosed {x | Tendsto (birkhoffAverage 𝕜 f g · x) atTop (𝓝 (l x))} := - (uniformEquicontinuous_birkhoffAverage 𝕜 hf hg).equicontinuous.isClosed_setOf_tendsto hl + (uniformEquicontinuous_birkhoffAverage 𝕜 hf hg).equicontinuous.isClosed_setOfPred_tendsto hl + +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_tendsto_birkhoffAverage := isClosed_setOfPred_tendsto_birkhoffAverage diff --git a/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean b/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean index 85530fc09bd5a8..b11d13bf7f04af 100644 --- a/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean +++ b/Mathlib/Dynamics/Ergodic/Action/OfMinimal.lean @@ -52,19 +52,31 @@ Let `μ` be a finite inner regular measure on `X` which is ergodic with respect If a null measurable set `s` is a.e. equal to its preimages under the action of a dense set of elements of `M`, then it is either null or conull. -/] -theorem aeconst_of_dense_setOf_preimage_smul_ae (hsm : NullMeasurableSet s μ) +theorem aeconst_of_dense_setOfPred_preimage_smul_ae (hsm : NullMeasurableSet s μ) (hd : Dense {g : M | (g • ·) ⁻¹' s =ᵐ[μ] s}) : EventuallyConst s (ae μ) := by borelize M refine aeconst_of_forall_preimage_smul_ae_eq M hsm ?_ rwa [dense_iff_closure_eq, IsClosed.closure_eq, eq_univ_iff_forall] at hd let f : C(M × X, X) := ⟨(· • ·).uncurry, continuous_smul⟩ - exact isClosed_setOf_preimage_ae_eq f.curry.continuous (measurePreserving_smul · μ) _ hsm + exact isClosed_setOfPred_preimage_ae_eq f.curry.continuous (measurePreserving_smul · μ) _ hsm (measure_ne_top _ _) +@[deprecated (since := "2026-07-09")] +alias aeconst_of_dense_setOf_preimage_smul_ae := aeconst_of_dense_setOfPred_preimage_smul_ae + +@[deprecated (since := "2026-07-09")] +alias aeconst_of_dense_setOf_preimage_vadd_ae := aeconst_of_dense_setOfPred_preimage_vadd_ae + @[to_additive] -theorem aeconst_of_dense_setOf_preimage_smul_eq (hsm : NullMeasurableSet s μ) +theorem aeconst_of_dense_setOfPred_preimage_smul_eq (hsm : NullMeasurableSet s μ) (hd : Dense {g : M | (g • ·) ⁻¹' s = s}) : EventuallyConst s (ae μ) := - aeconst_of_dense_setOf_preimage_smul_ae hsm <| hd.mono fun _ h ↦ mem_setOf.2 <| .of_eq h + aeconst_of_dense_setOfPred_preimage_smul_ae hsm <| hd.mono fun _ h ↦ mem_ofPred.2 <| .of_eq h + +@[deprecated (since := "2026-07-09")] +alias aeconst_of_dense_setOf_preimage_smul_eq := aeconst_of_dense_setOfPred_preimage_smul_eq + +@[deprecated (since := "2026-07-09")] +alias aeconst_of_dense_setOf_preimage_vadd_eq := aeconst_of_dense_setOfPred_preimage_vadd_eq /-- If a monoid `M` continuously acts on an R₁ topological space `X`, `g` is an element of `M` such that its natural powers are dense in `M`, @@ -80,9 +92,9 @@ theorem ergodic_smul_of_denseRange_pow {M : Type*} [Monoid M] [TopologicalSpace Ergodic (g • ·) μ := by borelize M refine ⟨measurePreserving_smul _ _, ⟨fun s hsm hs ↦ ?_⟩⟩ - refine aeconst_of_dense_setOf_preimage_smul_eq hsm.nullMeasurableSet (hg.mono ?_) + refine aeconst_of_dense_setOfPred_preimage_smul_eq hsm.nullMeasurableSet (hg.mono ?_) refine range_subset_iff.2 fun n ↦ ?_ - rw [mem_setOf, ← smul_iterate, preimage_iterate_eq, iterate_fixed hs] + rw [mem_ofPred, ← smul_iterate, preimage_iterate_eq, iterate_fixed hs] end SMul @@ -104,7 +116,7 @@ theorem ErgodicSMul.trans_isMinimal (N : Type*) [MulAction M N] measure_preimage_smul c s hsm := by simpa only [smul_one_smul] using SMulInvariantMeasure.measure_preimage_smul (c • 1 : N) hsm aeconst_of_forall_preimage_smul_ae_eq {s} hsm hs := by - refine aeconst_of_dense_setOf_preimage_smul_ae (M := N) hsm.nullMeasurableSet ?_ + refine aeconst_of_dense_setOfPred_preimage_smul_ae (M := N) hsm.nullMeasurableSet ?_ refine (MulAction.dense_orbit M 1).mono ?_ rintro _ ⟨g, rfl⟩ simpa using hs g @@ -121,7 +133,8 @@ variable {G : Type*} [Group G] [TopologicalSpace G] [ContinuousInv G] @[to_additive] theorem aeconst_of_dense_aestabilizer_smul (hsm : NullMeasurableSet s μ) (hd : Dense (MulAction.aestabilizer G μ s : Set G)) : EventuallyConst s (ae μ) := - aeconst_of_dense_setOf_preimage_smul_ae hsm <| (hd.preimage (isOpenMap_inv _)).mono fun g hg ↦ by + aeconst_of_dense_setOfPred_preimage_smul_ae hsm <| + (hd.preimage (isOpenMap_inv _)).mono fun g hg ↦ by simpa only [preimage_smul] using! hg set_option backward.isDefEq.respectTransparency.types false in @@ -221,12 +234,13 @@ then it is pre-ergodic with respect to any finite inner regular left invariant m theorem preErgodic_of_dense_iUnion_preimage_one {μ : Measure G} [IsFiniteMeasure μ] [μ.InnerRegular] [μ.IsMulLeftInvariant] (f : G →* G) (hf : Dense (⋃ n, f^[n] ⁻¹' 1)) : PreErgodic f μ := by - refine ⟨fun s hsm hs ↦ aeconst_of_dense_setOf_preimage_smul_eq (M := G) hsm.nullMeasurableSet ?_⟩ + refine ⟨fun s hsm hs ↦ + aeconst_of_dense_setOfPred_preimage_smul_eq (M := G) hsm.nullMeasurableSet ?_⟩ refine hf.mono <| iUnion_subset fun n x hx ↦ ?_ have hsn : f^[n] ⁻¹' s = s := by rw [preimage_iterate_eq, iterate_fixed hs] rw [mem_preimage, Set.mem_one] at hx - rw [mem_setOf, ← hsn] + rw [mem_ofPred, ← hsn] ext y simp [hx] diff --git a/Mathlib/Dynamics/Ergodic/Conservative.lean b/Mathlib/Dynamics/Ergodic/Conservative.lean index 0a9c308321bc04..a07d3c7f9920aa 100644 --- a/Mathlib/Dynamics/Ergodic/Conservative.lean +++ b/Mathlib/Dynamics/Ergodic/Conservative.lean @@ -112,7 +112,7 @@ theorem frequently_measure_inter_ne_zero (hf : Conservative f μ) (hs : NullMeas obtain ⟨N, hN, hmax⟩ : ∃ N, μ (t N) ≠ 0 ∧ ∀ n > N, μ (t n) = 0 := by rw [Nat.frequently_atTop_iff_infinite, not_infinite] at H convert! exists_max_image _ (·) H ⟨0, by simpa⟩ using 4 - rw [gt_iff_lt, ← not_le, not_imp_comm, mem_setOf] + rw [gt_iff_lt, ← not_le, not_imp_comm, mem_ofPred] have htm {n : ℕ} : NullMeasurableSet (t n) μ := hs.inter <| hs.preimage <| hf.toQuasiMeasurePreserving.iterate n -- Then all `t n`, `n > N`, are null sets, hence `T = t N \ ⋃ n > N, t n` has positive measure. @@ -145,7 +145,7 @@ theorem measure_mem_forall_ge_image_notMem_eq_zero (hf : Conservative f μ) μ ({ x ∈ s | ∀ m ≥ n, f^[m] x ∉ s }) = 0 := by by_contra H have : NullMeasurableSet (s ∩ { x | ∀ m ≥ n, f^[m] x ∉ s }) μ := by - simp only [setOf_forall, ← compl_setOf] + simp only [ofPred_forall, ← compl_ofPred] exact hs.inter <| .biInter (to_countable _) fun m _ ↦ (hs.preimage <| hf.toQuasiMeasurePreserving.iterate m).compl rcases (hf.exists_gt_measure_inter_ne_zero this H) n with ⟨m, hmn, hm⟩ diff --git a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean index 58d33b1b0a9c2c..72e5102b5e7191 100644 --- a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean +++ b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean @@ -581,7 +581,7 @@ variable {A : Type*} [Fintype A] [Inhabited A] variable {G : Type*} /-- Patterns with support exactly `U` form a finite set. -/ -lemma finite_setOf_pattern_support_eq +lemma finite_setOfPred_pattern_support_eq {A G : Type*} [Finite A] [Inhabited A] (U : Finset G) : ({p : Pattern A G | p.support = U}).Finite := by @@ -607,6 +607,9 @@ lemma finite_setOf_pattern_support_eq let : Fintype { p : Pattern A G | p.support = U } := Fintype.ofEquiv (U → A) e.symm apply toFinite +@[deprecated (since := "2026-07-09")] +alias finite_setOf_pattern_support_eq := finite_setOfPred_pattern_support_eq + /-- The language of a set of configurations `X` on a finite shape `U`. This is the set of all finite patterns obtained by restricting some configuration diff --git a/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean b/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean index edd594e8e8adad..2c79f90c009f3b 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean @@ -95,7 +95,7 @@ lemma dynEntourage_comp_subset (T : X → X) (U V : SetRel X X) (n : ℕ) : (dynEntourage T U n) ○ (dynEntourage T V n) ⊆ dynEntourage T (U ○ V) n := by simp only [dynEntourage, map_iterate, subset_iInter_iff] intro k k_n xy xy_comp - simp only [SetRel.comp, mem_iInter, mem_preimage, map_apply, mem_setOf_eq] at xy_comp ⊢ + simp only [SetRel.comp, mem_iInter, mem_preimage, map_apply, mem_ofPred_eq] at xy_comp ⊢ rcases xy_comp with ⟨z, hz1, hz2⟩ exact mem_ball_comp (hz1 k k_n) (hz2 k k_n) diff --git a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean index fd3269e6bc03fa..0cfa839f9efe76 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean @@ -125,24 +125,24 @@ lemma netMaxcard_finite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : ℕ) have : netMaxcard T F U n = sSup (WithTop.some '' Finset.card '' {s : Finset X | IsDynNetIn T F U n s}) := by rw [netMaxcard, ← image_comp, sSup_image] - simp only [mem_setOf_eq, ENat.some_eq_coe, Function.comp_apply] + simp only [mem_ofPred_eq, ENat.some_eq_coe, Function.comp_apply] exact biSup_congr (fun _ _ ↦ rfl) rw [this] at k_max have h_bdda : BddAbove (Finset.card '' {s : Finset X | IsDynNetIn T F U n s}) := by refine ⟨k, mem_upperBounds.2 ?_⟩ - simp only [mem_image, mem_setOf_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] + simp only [mem_image, mem_ofPred_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] intro s h rw [← ENat.coe_le_coe, k_max] apply le_sSup exact Filter.frequently_principal.mp fun a ↦ a (by simpa using ⟨_, h, rfl⟩) rfl have h_nemp : (Finset.card '' {s : Finset X | IsDynNetIn T F U n s}).Nonempty := by refine ⟨0, ?_⟩ - simp only [mem_image, mem_setOf_eq, Finset.card_eq_zero, exists_eq_right, Finset.coe_empty] + simp only [mem_image, mem_ofPred_eq, Finset.card_eq_zero, exists_eq_right, Finset.coe_empty] exact isDynNetIn_empty rw [← WithTop.coe_sSup' h_bdda] at k_max have key := Nat.sSup_mem h_nemp h_bdda rw [← Nat.cast_inj.mp k_max, mem_image] at key - simp only [mem_setOf_eq] at key + simp only [mem_ofPred_eq] at key exact key · obtain ⟨s, _, s_card⟩ := h rw [← s_card] diff --git a/Mathlib/FieldTheory/AxGrothendieck.lean b/Mathlib/FieldTheory/AxGrothendieck.lean index 7b3af709f6d07f..7c2fceb157777b 100644 --- a/Mathlib/FieldTheory/AxGrothendieck.lean +++ b/Mathlib/FieldTheory/AxGrothendieck.lean @@ -156,7 +156,7 @@ theorem realize_genericPolyMapSurjOnOfInjOn realize_bdEqual, Term.realize_relabel, Equiv.forall_congr_left (Equiv.curry (Fin 2) ι K), Equiv.curry_symm_apply, Fin.forall_fin_succ_pi, Fin.forall_fin_zero_pi, realize_iExs, realize_inf, Sum.forall_sum, - Set.MapsTo, Set.mem_setOf_eq, injOnAlt, funext_iff, Set.SurjOn, Set.image, + Set.MapsTo, Set.mem_ofPred_eq, injOnAlt, funext_iff, Set.SurjOn, Set.image, Set.subset_def, Equiv.forall_congr_left (mvPolynomialSupportLEEquiv mons)] simp +singlePass only [← Sum.elim_comp_inl_inr] -- was `simp` and very slow (https://github.com/leanprover-community/mathlib4/issues/19751) diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index a7b569da89bbbd..c4732343f7b0d8 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -117,8 +117,8 @@ def leastExt : ι → ι := wellFounded_lt.fix fun i ih ↦ let s := range fun j : Iio i ↦ b (ih j j.2) wellFounded_lt.min {k | b k ∉ adjoin F s} <| by - rw [← compl_setOf, nonempty_compl]; by_contra! - simp_rw [eq_univ_iff_forall, mem_setOf] at this + rw [← compl_ofPred, nonempty_compl]; by_contra! + simp_rw [eq_univ_iff_forall, mem_ofPred] at this have := adjoin_le_iff.mpr (range_subset_iff.mpr this) rw [adjoin_basis_eq_top, ← eq_top_iff] at this apply_fun Module.rank F at this diff --git a/Mathlib/FieldTheory/Extension.lean b/Mathlib/FieldTheory/Extension.lean index 7091f5efa90526..cb04dddfd80caa 100644 --- a/Mathlib/FieldTheory/Extension.lean +++ b/Mathlib/FieldTheory/Extension.lean @@ -193,7 +193,7 @@ theorem nonempty_algHom_of_exist_lifts_finset [alg : Algebra.IsAlgebraic F E] ⟨by simpa only [L, restrictScalars_adjoin_eq_sup, left_lt_sup, adjoin_simple_le_iff], AlgHom.coe_ringHom_injective σ.comp_algebraMap⟩ have ⟨(ϕ_ext : ϕ.IsExtendible), ϕ_max⟩ := maximal_iff_forall_gt.mp hϕ - simp_rw [Set.mem_setOf, IsExtendible] at ϕ_max; push Not at ϕ_max + simp_rw [Set.mem_ofPred, IsExtendible] at ϕ_max; push Not at ϕ_max choose S hS using fun σ : Λ ↦ ϕ_max (hL σ) classical have ⟨θ, hθϕ, hθ⟩ := ϕ_ext ({α} ∪ Finset.univ.biUnion S) diff --git a/Mathlib/FieldTheory/Finite/Polynomial.lean b/Mathlib/FieldTheory/Finite/Polynomial.lean index c8845066d92b89..407f421b45c2ad 100644 --- a/Mathlib/FieldTheory/Finite/Polynomial.lean +++ b/Mathlib/FieldTheory/Finite/Polynomial.lean @@ -174,7 +174,7 @@ noncomputable def evalᵢ [CommRing K] : R σ K →ₗ[K] (σ → K) → K := open scoped Classical in noncomputable instance decidableRestrictDegree (m : ℕ) : DecidablePred (· ∈ { n : σ →₀ ℕ | ∀ i, n i ≤ m }) := by - simp only [Set.mem_setOf_eq]; infer_instance + simp only [Set.mem_ofPred_eq]; infer_instance variable [Field K] diff --git a/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean b/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean index 6e11b9084bc6e6..ab792de1c22873 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean @@ -696,7 +696,7 @@ theorem _root_.Collinear.oangle_sign_of_sameRay_vsub {p₁ p₂ p₃ p₄ : P} ( Set.univ ×ˢ {v | SameRay ℝ (p₂ -ᵥ p₁) v ∧ v ≠ 0} have hco : IsConnected s := haveI : ConnectedSpace line[ℝ, p₁, p₂] := AddTorsor.connectedSpace _ _ - (isConnected_univ.prod (isConnected_setOf_sameRay_and_ne_zero + (isConnected_univ.prod (isConnected_setOfPred_sameRay_and_ne_zero (vsub_ne_zero.2 hp₁p₂.symm))).image _ (by fun_prop) have hf : ContinuousOn (fun p : P × P × P => ∡ p.1 p.2.1 p.2.2) s := by refine continuousOn_of_forall_continuousAt fun p hp => continuousAt_oangle ?_ ?_ @@ -705,7 +705,7 @@ theorem _root_.Collinear.oangle_sign_of_sameRay_vsub {p₁ p₂ p₃ p₄ : P} ( obtain ⟨q₁, q₅, q₂⟩ := p dsimp only at hp ⊢ obtain ⟨⟨⟨q, hq⟩, v⟩, hv, rfl, rfl, rfl⟩ := hp - dsimp only [Subtype.coe_mk, Set.mem_setOf] at hv ⊢ + dsimp only [Subtype.coe_mk, Set.mem_ofPred] at hv ⊢ obtain ⟨hvr, -⟩ := hv rintro rfl refine hc₅₁₂ ((collinear_insert_iff_of_mem_affineSpan ?_).2 (collinear_pair _ _ _)) @@ -717,12 +717,12 @@ theorem _root_.Collinear.oangle_sign_of_sameRay_vsub {p₁ p₂ p₃ p₄ : P} ( exact smul_vsub_rev_mem_vectorSpan_pair _ _ _ have hsp : ∀ p : P × P × P, p ∈ s → ∡ p.1 p.2.1 p.2.2 ≠ 0 ∧ ∡ p.1 p.2.1 p.2.2 ≠ π := by intro p hp - simp_rw [s, Set.mem_image, Set.mem_prod, Set.mem_setOf, Set.mem_univ, true_and, + simp_rw [s, Set.mem_image, Set.mem_prod, Set.mem_ofPred, Set.mem_univ, true_and, Prod.ext_iff] at hp obtain ⟨q₁, q₅, q₂⟩ := p dsimp only at hp ⊢ obtain ⟨⟨⟨q, hq⟩, v⟩, hv, rfl, rfl, rfl⟩ := hp - dsimp only [Subtype.coe_mk, Set.mem_setOf] at hv ⊢ + dsimp only [Subtype.coe_mk, Set.mem_ofPred] at hv ⊢ obtain ⟨hvr, hv0⟩ := hv rw [← exists_nonneg_left_iff_sameRay (vsub_ne_zero.2 hp₁p₂.symm)] at hvr obtain ⟨r, -, rfl⟩ := hvr @@ -735,13 +735,13 @@ theorem _root_.Collinear.oangle_sign_of_sameRay_vsub {p₁ p₂ p₃ p₄ : P} ( rw [direction_affineSpan] exact smul_vsub_rev_mem_vectorSpan_pair _ _ _ have hp₁p₂s : (p₁, p₅, p₂) ∈ s := by - simp_rw [s, Set.mem_image, Set.mem_prod, Set.mem_setOf, Set.mem_univ, true_and, + simp_rw [s, Set.mem_image, Set.mem_prod, Set.mem_ofPred, Set.mem_univ, true_and, Prod.ext_iff] refine ⟨⟨⟨p₁, left_mem_affineSpan_pair ℝ _ _⟩, p₂ -ᵥ p₁⟩, ⟨SameRay.rfl, vsub_ne_zero.2 hp₁p₂.symm⟩, ?_⟩ simp have hp₃p₄s : (p₃, p₅, p₄) ∈ s := by - simp_rw [s, Set.mem_image, Set.mem_prod, Set.mem_setOf, Set.mem_univ, true_and, + simp_rw [s, Set.mem_image, Set.mem_prod, Set.mem_ofPred, Set.mem_univ, true_and, Prod.ext_iff] refine ⟨⟨⟨p₃, hc.mem_affineSpan_of_mem_of_ne (Set.mem_insert _ _) (Set.mem_insert_of_mem _ (Set.mem_insert _ _)) @@ -811,11 +811,11 @@ theorem _root_.AffineSubspace.SSameSide.oangle_sign_eq {s : AffineSubspace ℝ P by_cases h : p₁ = p₂; · simp [h] let sp : Set (P × P × P) := (fun p : P => (p₁, p, p₂)) '' {p | s.SSameSide p₃ p} have hc : IsConnected sp := - (isConnected_setOf_sSameSide hp₃p₄.2.1 hp₃p₄.nonempty).image _ (by fun_prop) + (isConnected_setOfPred_sSameSide hp₃p₄.2.1 hp₃p₄.nonempty).image _ (by fun_prop) have hf : ContinuousOn (fun p : P × P × P => ∡ p.1 p.2.1 p.2.2) sp := by refine continuousOn_of_forall_continuousAt fun p hp => continuousAt_oangle ?_ ?_ all_goals - simp_rw [sp, Set.mem_image, Set.mem_setOf] at hp + simp_rw [sp, Set.mem_image, Set.mem_ofPred] at hp obtain ⟨p', hp', rfl⟩ := hp dsimp only rintro rfl @@ -823,7 +823,7 @@ theorem _root_.AffineSubspace.SSameSide.oangle_sign_eq {s : AffineSubspace ℝ P · exact hp'.2.2 hp₂ have hsp : ∀ p : P × P × P, p ∈ sp → ∡ p.1 p.2.1 p.2.2 ≠ 0 ∧ ∡ p.1 p.2.1 p.2.2 ≠ π := by intro p hp - simp_rw [sp, Set.mem_image, Set.mem_setOf] at hp + simp_rw [sp, Set.mem_image, Set.mem_ofPred] at hp obtain ⟨p', hp', rfl⟩ := hp dsimp only rw [oangle_ne_zero_and_ne_pi_iff_affineIndependent] diff --git a/Mathlib/Geometry/Group/Growth/QuotientInter.lean b/Mathlib/Geometry/Group/Growth/QuotientInter.lean index c6faf6930618d6..5e83f8a8dea550 100644 --- a/Mathlib/Geometry/Group/Growth/QuotientInter.lean +++ b/Mathlib/Geometry/Group/Growth/QuotientInter.lean @@ -43,7 +43,7 @@ lemma card_pow_quotient_mul_pow_inter_subgroup_le : _ ≤ #(((A ^ m).image π).image φ * {x ∈ A ^ n | x ∈ H}) := by rw [Finset.card_mul_iff.2] simp only [Set.InjOn, coe_image, coe_pow, coe_filter, Set.mem_prod, Set.mem_image, - exists_exists_and_eq_and, Set.mem_setOf_eq, and_imp, forall_exists_index, Prod.forall, + exists_exists_and_eq_and, Set.mem_ofPred_eq, and_imp, forall_exists_index, Prod.forall, Prod.mk.injEq] rintro _ a₁ b₁ hb₁ rfl - ha₁ _ a₂ b₂ hb₂ rfl - ha₂ hab have hπa₁ : π a₁ = 1 := (QuotientGroup.eq_one_iff _).2 ha₁ diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 051923a0bb6177..da88799829a6d8 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -147,7 +147,7 @@ theorem frontier_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) : frontier { y : PiLp p (fun _ : Fin n ↦ ℝ) | a ≤ y i } = { y | a = y i } := by rw [frontier, closure_halfSpace, interior_halfSpace] ext y - simpa only [mem_sdiff, mem_setOf_eq, not_lt] using antisymm_iff + simpa only [mem_sdiff, mem_ofPred_eq, not_lt] using antisymm_iff theorem range_euclideanQuadrant (n : ℕ) : range (Subtype.val : EuclideanQuadrant n → _) = { y | ∀ i : Fin n, 0 ≤ y i } := Subtype.range_val @@ -271,14 +271,14 @@ def IccLeftChart (x y : ℝ) [h : Fact (x < y)] : target := { z : EuclideanHalfSpace 1 | z.val 0 < y - x } toFun := fun z : Icc x y => ⟨toLp 2 fun _ ↦ z.val - x, sub_nonneg.mpr z.property.1⟩ invFun z := ⟨min (z.val 0 + x) y, by simp [z.prop, h.out.le]⟩ - map_source' := by simp only [mem_setOf_eq, Fin.isValue, sub_lt_sub_iff_right, + map_source' := by simp only [mem_ofPred_eq, Fin.isValue, sub_lt_sub_iff_right, imp_self, implies_true] map_target' := by - simp only [min_lt_iff, mem_setOf_eq]; intro z hz; left + simp only [min_lt_iff, mem_ofPred_eq]; intro z hz; left linarith left_inv' := by rintro ⟨z, hz⟩ h'z - simp only [mem_setOf_eq, mem_Icc] at hz h'z + simp only [mem_ofPred_eq, mem_Icc] at hz h'z simp only [Fin.isValue, sub_add_cancel, hz, inf_of_le_left] right_inv' := by rintro ⟨z, hz⟩ h'z @@ -325,7 +325,7 @@ lemma IccLeftChart_extend_interior_pos {p : Set.Icc x y} (hp : x < p.val ∧ p.v lemma IccLeftChart_extend_bot_mem_frontier : (IccLeftChart x y).extend (𝓡∂ 1) ⊥ ∈ frontier (range (𝓡∂ 1)) := by rw [IccLeftChart_extend_bot, frontier_range_modelWithCornersEuclideanHalfSpace, - mem_setOf, PiLp.zero_apply] + mem_ofPred, PiLp.zero_apply] set_option backward.isDefEq.respectTransparency false in /-- The right chart for the topological space `[x, y]`, defined on `(x,y]` and sending `y` to `0` in @@ -338,14 +338,14 @@ def IccRightChart (x y : ℝ) [h : Fact (x < y)] : toFun z := ⟨toLp 2 fun _ ↦ y - z.val, sub_nonneg.mpr z.property.2⟩ invFun z := ⟨max (y - z.val 0) x, by simp [z.prop, h.out.le, sub_eq_add_neg]⟩ - map_source' := by simp only [mem_setOf_eq, Fin.isValue, sub_lt_sub_iff_left, + map_source' := by simp only [mem_ofPred_eq, Fin.isValue, sub_lt_sub_iff_left, imp_self, implies_true] map_target' := by - simp only [lt_max_iff, mem_setOf_eq]; intro z hz; left + simp only [lt_max_iff, mem_ofPred_eq]; intro z hz; left linarith left_inv' := by rintro ⟨z, hz⟩ h'z - simp only [mem_setOf_eq, mem_Icc] at hz h'z + simp only [mem_ofPred_eq, mem_Icc] at hz h'z simp only [Fin.isValue, sub_eq_add_neg, neg_add_rev, neg_neg, add_neg_cancel_comm_assoc, hz, sup_of_le_left] right_inv' := by @@ -376,7 +376,7 @@ lemma IccRightChart_extend_top : lemma IccRightChart_extend_top_mem_frontier : (IccRightChart x y).extend (𝓡∂ 1) ⊤ ∈ frontier (range (𝓡∂ 1)) := by rw [IccRightChart_extend_top, frontier_range_modelWithCornersEuclideanHalfSpace, - mem_setOf, PiLp.zero_apply] + mem_ofPred, PiLp.zero_apply] /-- Charted space structure on `[x, y]`, using only two charts taking values in `EuclideanHalfSpace 1`. diff --git a/Mathlib/Geometry/Manifold/Instances/Sphere.lean b/Mathlib/Geometry/Manifold/Instances/Sphere.lean index 451f9cc567e4f3..519ef7731cd5cd 100644 --- a/Mathlib/Geometry/Manifold/Instances/Sphere.lean +++ b/Mathlib/Geometry/Manifold/Instances/Sphere.lean @@ -413,7 +413,8 @@ instance EuclideanSpace.instIsManifoldSphere OpenPartialHomeomorph.symm_toPartialEquiv, PartialEquiv.trans_source, PartialEquiv.symm_source, stereographic'_target, stereographic'_source] simp only [modelWithCornersSelf_coe, modelWithCornersSelf_coe_symm, - Set.range_id, Set.inter_univ, Set.univ_inter, Set.compl_singleton_eq, Set.preimage_setOf_eq] + Set.range_id, Set.inter_univ, Set.univ_inter, Set.compl_singleton_eq, + Set.preimage_ofPred_eq] simp only [id, comp_apply, OpenPartialHomeomorph.coe_toPartialEquiv_symm, innerSL_apply_apply, Ne, sphere_ext_iff, real_inner_comm (v' : E)] rfl) diff --git a/Mathlib/Geometry/Manifold/IntegralCurve/ExistUnique.lean b/Mathlib/Geometry/Manifold/IntegralCurve/ExistUnique.lean index 9091f15d9d70d3..28ed7ef3430bc1 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve/ExistUnique.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve/ExistUnique.lean @@ -194,13 +194,13 @@ theorem isMIntegralCurveOn_Ioo_eqOn_of_contMDiff (ht₀ : t₀ ∈ Ioo a b) -- since `Ioo a b` is connected, we get `s = Ioo a b` by showing that `s` is clopen in `Ioo a b` -- in the subtype topology (`s` is also non-empty by assumption) -- here we use a slightly weaker alternative theorem - suffices hsub : Ioo a b ⊆ s from fun t ht ↦ mem_setOf.mp ((subset_def ▸ hsub) t ht).1 + suffices hsub : Ioo a b ⊆ s from fun t ht ↦ mem_ofPred.mp ((subset_def ▸ hsub) t ht).1 apply isPreconnected_Ioo.subset_of_closure_inter_subset (s := Ioo a b) (u := s) _ ⟨t₀, ⟨ht₀, ⟨h, ht₀⟩⟩⟩ · -- is this really the most convenient way to pass to subtype topology? -- TODO: shorten this when better API around subtype topology exists rw [hs, inter_comm, ← Subtype.image_preimage_val, inter_comm, ← Subtype.image_preimage_val, - image_subset_image_iff Subtype.val_injective, preimage_setOf_eq] + image_subset_image_iff Subtype.val_injective, preimage_ofPred_eq] intro t ht rw [mem_preimage, ← closure_subtype] at ht revert ht t diff --git a/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean b/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean index ceed7bccd5e562..46f2b6ea9d182a 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean @@ -123,7 +123,7 @@ lemma isMIntegralCurveOn_comp_mul_ne_zero {a : ℝ} (ha : a ≠ 0) : · ext t simp only [Function.comp_apply, mul_assoc, inv_mul_eq_div, div_self ha, mul_one] · simp only [smul_smul, inv_mul_eq_div, div_self ha, one_smul] - · simp only [mem_setOf_eq, mul_assoc, inv_mul_eq_div, div_self ha, mul_one, setOf_mem_eq] + · simp only [mem_ofPred_eq, mul_assoc, inv_mul_eq_div, div_self ha, mul_one, ofPred_mem_eq] lemma IsMIntegralCurveAt.comp_mul_ne_zero (hγ : IsMIntegralCurveAt γ v t₀) {a : ℝ} (ha : a ≠ 0) : IsMIntegralCurveAt (γ ∘ (· * a)) (a • v) (t₀ / a) := by @@ -132,7 +132,7 @@ lemma IsMIntegralCurveAt.comp_mul_ne_zero (hγ : IsMIntegralCurveAt γ v t₀) { refine ⟨ε / |a|, by positivity, ?_⟩ convert! h.comp_mul a ext t - rw [mem_setOf_eq, Metric.mem_ball, Metric.mem_ball, Real.dist_eq, Real.dist_eq, + rw [mem_ofPred_eq, Metric.mem_ball, Metric.mem_ball, Real.dist_eq, Real.dist_eq, lt_div_iff₀ (abs_pos.mpr ha), ← abs_mul, sub_mul, div_mul_cancel₀ _ ha] lemma isMIntegralCurveAt_comp_mul_ne_zero {a : ℝ} (ha : a ≠ 0) : diff --git a/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean b/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean index 95d84fa3c2f9ca..4b4ad1471634c5 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean @@ -178,7 +178,7 @@ lemma exists_isMIntegralCurve_of_isMIntegralCurveOn [BoundarylessManifold I M] -- another centred at 0 with domain up to `a ∈ S` with `t₀ < a < asup` obtain ⟨a, ha, hlt⟩ := Real.add_neg_lt_sSup (⟨ε, h x⟩ : Set.Nonempty s) (ε := - (ε / 2)) (by rw [neg_lt, neg_zero]; exact half_pos hε) - rw [mem_setOf] at ha + rw [mem_ofPred] at ha rw [← hasup, ← sub_eq_add_neg] at hlt -- integral curve defined on `Ioo (-a) a` obtain ⟨γ, h0, hγ⟩ := ha diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 1edf199297ec0d..8e1ea40bbda521 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -502,7 +502,7 @@ def ModelWithCorners.prod {𝕜 : Type u} [NontriviallyNormedField 𝕜] {E : Ty toFun := fun x => (I x.1, I' x.2) invFun := fun x => (I.symm x.1, I'.symm x.2) source := { x | x.1 ∈ I.source ∧ x.2 ∈ I'.source } - source_eq := by simp only [setOf_true, mfld_simps] + source_eq := by simp only [ofPred_true, mfld_simps] convex_range' := by have : range (fun (x : ModelProd H H') ↦ (I x.1, I' x.2)) = range (Prod.map I I') := rfl rw [this, Set.range_prodMap] diff --git a/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean b/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean index f1e4df6bb2df8c..ed71f41bfe9d91 100644 --- a/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean +++ b/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean @@ -80,7 +80,7 @@ namespace LocalInvariantProp theorem congr_set {s t : Set H} {x : H} {f : H → H'} (hu : s =ᶠ[𝓝 x] t) : P f s x ↔ P f t x := by obtain ⟨o, host, ho, hxo⟩ := mem_nhds_iff.mp hu.mem_iff - simp_rw [subset_def, mem_setOf, ← and_congr_left_iff, ← mem_inter_iff, ← Set.ext_iff] at host + simp_rw [subset_def, mem_ofPred, ← and_congr_left_iff, ← mem_inter_iff, ← Set.ext_iff] at host rw [hG.is_local ho hxo, host, ← hG.is_local ho hxo] theorem is_local_nhds {s u : Set H} {x : H} {f : H → H'} (hu : u ∈ 𝓝[s] x) : diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index a18a93a99f928b..8cad83511a58c5 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -892,7 +892,7 @@ theorem preimage_extChartAt_eventuallyEq_compl_singleton (y : M) (h : s =ᶠ[ apply mem_nhdsWithin_iff_exists_mem_nhds_inter.2 ⟨_, Filter.inter_mem ((continuousAt_extChartAt_symm x).preimage_mem_nhds u_mem) B, ?_⟩ rintro z ⟨hz, h'z⟩ - simp only [eq_iff_iff, mem_setOf_eq] + simp only [eq_iff_iff, mem_ofPred_eq] change z ∈ (extChartAt I x).symm ⁻¹' s ∩ range I ↔ z ∈ (extChartAt I x).symm ⁻¹' t ∩ range I by_cases hIz : z ∈ range I · simp only [mem_inter_iff, mem_preimage, mem_union, mem_compl_iff, hIz, not_true_eq_false, @@ -1085,7 +1085,7 @@ theorem Filter.EventuallyEq.mfderivWithin_eq (hL : f₁ =ᶠ[𝓝[s] x] f) (hx : apply Filter.EventuallyEq.fderivWithin_eq; swap · simp [hx] filter_upwards [extChartAt_preimage_mem_nhdsWithin (I := I) hL] with y hy - simp only [preimage_setOf_eq, mem_setOf_eq] at hy + simp only [preimage_ofPred_eq, mem_ofPred_eq] at hy simp [-extChartAt, hy, hx] · unfold mfderivWithin rw [if_neg h, if_neg] diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index dd40ee6d8ea5b2..e9d0243283efab 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -620,7 +620,7 @@ theorem exists_contMDiffSection_forall_mem_convex_of_local -- Future: can grind do this? apply ρ.locallyFinite.subset fun i x hx ↦ ?_ rw [support] - rw [mem_setOf_eq] at hx ⊢ + rw [mem_ofPred_eq] at hx ⊢ exact left_ne_zero_of_smul hx -- Construct the smooth section and prove it lies in the convex sets `t x`. refine ⟨⟨s, hs⟩, fun x ↦ ?_⟩ diff --git a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean index 687abb5f64b7f8..a77ad8f2ea8290 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean @@ -110,7 +110,7 @@ noncomputable def riemannianMetricVectorSpace : have : Metric.ball (0 : F) 1 = {v : F | ⟪v, v⟫ < 1} := by ext v simp only [Metric.mem_ball, dist_zero_right, norm_eq_sqrt_re_inner (𝕜 := ℝ), - RCLike.re_to_real, Set.mem_setOf_eq] + RCLike.re_to_real, Set.mem_ofPred_eq] conv_lhs => rw [show (1 : ℝ) = √1 by simp] rw [Real.sqrt_lt_sqrt_iff] exact real_inner_self_nonneg @@ -194,7 +194,7 @@ Moreover, we show that in this case the resulting emetric space satisfies the pr Showing that the distance topology coincides with the pre-existing topology is not trivial. The two inclusions are proved respectively in `eventually_riemannianEDist_lt` and -`setOf_riemannianEDist_lt_subset_nhds`. +`setOfPred_riemannianEDist_lt_subset_nhds`. For the first one, we have to show that points which are close for the topology are at small distance. For this, we use the path between the two points which is the pullback of the segment @@ -284,7 +284,7 @@ lemma eventually_norm_mfderivWithin_symm_extChartAt_lt (x : M) : filter_upwards [nhdsWithin_le_nhds (this.preimage_mem_nhds hC), extChartAt_target_mem_nhdsWithin x] with y hy h'y have : y = (extChartAt I x) ((extChartAt I x).symm y) := by simp [-extChartAt, h'y] - simp only [preimage_setOf_eq, mem_setOf_eq] at hy + simp only [preimage_ofPred_eq, mem_ofPred_eq] at hy convert! hy set_option backward.isDefEq.respectTransparency false in @@ -387,7 +387,7 @@ lemma eventually_riemannianEDist_lt (x : M) {c : ℝ≥0∞} (hc : 0 < c) : set_option backward.isDefEq.respectTransparency false in /-- Any neighborhood of `x` contains all the points which are close enough to `x` for the Riemannian distance, `ℝ≥0` version. -/ -lemma setOf_riemannianEDist_lt_subset_nhds [RegularSpace M] {x : M} {s : Set M} (hs : s ∈ 𝓝 x) : +lemma setOfPred_riemannianEDist_lt_subset_nhds [RegularSpace M] {x : M} {s : Set M} (hs : s ∈ 𝓝 x) : ∃ c > (0 : ℝ≥0), {y | riemannianEDist I x y < c} ⊆ s := by /- Consider a closed neighborhood `u` of `x` on which the derivative of the extended chart is bounded by some `C`, contained in `s`, then an open neighborhood `v` of `x` inside `u`, @@ -497,13 +497,20 @@ lemma setOf_riemannianEDist_lt_subset_nhds [RegularSpace M] {x : M} {s : Set M} simp only [Function.comp_apply, γ', (extChartAt I x).left_inv <| uc <| t₁_mem (right_mem_Icc.mpr ht₁0)] +@[deprecated (since := "2026-07-09")] +alias setOf_riemannianEDist_lt_subset_nhds := setOfPred_riemannianEDist_lt_subset_nhds + /-- Any neighborhood of `x` contains all the points which are close enough to `x` for the Riemannian distance, `ℝ≥0∞` version. -/ -lemma setOf_riemannianEDist_lt_subset_nhds' [RegularSpace M] {x : M} {s : Set M} (hs : s ∈ 𝓝 x) : +lemma setOfPred_riemannianEDist_lt_subset_nhds' [RegularSpace M] {x : M} {s : Set M} + (hs : s ∈ 𝓝 x) : ∃ c > 0, {y | riemannianEDist I x y < c} ⊆ s := by - rcases setOf_riemannianEDist_lt_subset_nhds I hs with ⟨c, c_pos, hc⟩ + rcases setOfPred_riemannianEDist_lt_subset_nhds I hs with ⟨c, c_pos, hc⟩ exact ⟨c, mod_cast c_pos, hc⟩ +@[deprecated (since := "2026-07-09")] +alias setOf_riemannianEDist_lt_subset_nhds' := setOfPred_riemannianEDist_lt_subset_nhds' + variable (M) in /-- The pseudoemetric space structure associated to a Riemannian metric on a manifold. Designed so that the topology is defeq to the original one. @@ -517,7 +524,7 @@ additionally the predicate `IsRiemannianManifold I M`. -/ (fun _ _ ↦ riemannianEDist_comm) (fun _ _ _ ↦ riemannianEDist_triangle) (fun x ↦ (basis_sets (𝓝 x)).to_hasBasis' - (fun _ hs ↦ setOf_riemannianEDist_lt_subset_nhds' I hs) + (fun _ hs ↦ setOfPred_riemannianEDist_lt_subset_nhds' I hs) (fun _ hc ↦ eventually_riemannianEDist_lt I x hc)) @[deprecated (since := "2026-01-08")] diff --git a/Mathlib/Geometry/Manifold/SmoothApprox.lean b/Mathlib/Geometry/Manifold/SmoothApprox.lean index 15c5e988a355e2..045a33a036ca7c 100644 --- a/Mathlib/Geometry/Manifold/SmoothApprox.lean +++ b/Mathlib/Geometry/Manifold/SmoothApprox.lean @@ -90,7 +90,7 @@ theorem Continuous.exists_contMDiff_approx_and_eqOn (n : ℕ∞) rcases this with ⟨g, hg⟩ exact ⟨g, fun x ↦ (hg x).1, fun x ↦ (hg x).2.1, fun x ↦ mt (hg x).2.2⟩ have t_conv (x) : Convex ℝ (t x) := (convex_ball (f x) (ε x)).inter <| - (convex_singleton _).setOf_const_imp.inter (convex_singleton _).setOf_const_imp + (convex_singleton _).setOfPred_const_imp.inter (convex_singleton _).setOfPred_const_imp apply exists_contMDiffMap_forall_mem_convex_of_local I t_conv intro x by_cases hx : x ∈ S diff --git a/Mathlib/Geometry/Manifold/StructureGroupoid.lean b/Mathlib/Geometry/Manifold/StructureGroupoid.lean index 2d489305dbddd2..b1639f21861cd2 100644 --- a/Mathlib/Geometry/Manifold/StructureGroupoid.lean +++ b/Mathlib/Geometry/Manifold/StructureGroupoid.lean @@ -233,7 +233,7 @@ def idGroupoid (H : Type*) [TopologicalSpace H] : StructureGroupoid H where have : s = univ := by rwa [open_s.interior_eq, univ_subset_iff] at this simpa only [this, restr_univ] using! hs · exfalso - rw [mem_setOf_eq] at hs + rw [mem_ofPred_eq] at hs rwa [hs] at x's mem_of_eqOnSource' e e' he he'e := by rcases he with he | he @@ -244,7 +244,7 @@ def idGroupoid (H : Type*) [TopologicalSpace H] : StructureGroupoid H where rwa [← this] · right have he : e.toPartialEquiv.source = ∅ := he - rwa [Set.mem_setOf_eq, EqOnSource.source_eq he'e] + rwa [Set.mem_ofPred_eq, EqOnSource.source_eq he'e] /-- Every structure groupoid contains the identity groupoid. -/ instance instStructureGroupoidOrderBot : OrderBot (StructureGroupoid H) where @@ -254,7 +254,7 @@ instance instStructureGroupoidOrderBot : OrderBot (StructureGroupoid H) where have hf : f ∈ {OpenPartialHomeomorph.refl H} ∪ { e : OpenPartialHomeomorph H H | e.source = ∅ } := hf - simp only [singleton_union, mem_setOf_eq, mem_insert_iff] at hf + simp only [singleton_union, mem_ofPred_eq, mem_insert_iff] at hf rcases hf with hf | hf · rw [hf] apply u.id_mem diff --git a/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean index 883566e408db34..a6593d1272ab0b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean @@ -215,7 +215,7 @@ lemma ContMDiffWithinAt.sum_section_of_locallyFinite by_contra! h have : i ∈ s.toFinset := by refine Set.mem_toFinset.mpr ?_ - simp only [s, ne_eq, Set.mem_setOf_eq] + simp only [s, ne_eq, Set.mem_ofPred_eq] use x₀ simpa using ⟨h, mem_of_mem_nhds hu'⟩ exact hi this @@ -224,7 +224,7 @@ lemma ContMDiffWithinAt.sum_section_of_locallyFinite by_contra! h have : i ∈ s.toFinset := by refine Set.mem_toFinset.mpr ?_ - simp only [s, ne_eq, Set.mem_setOf_eq] + simp only [s, ne_eq, Set.mem_ofPred_eq] use y simpa using ⟨h, Set.mem_of_mem_inter_right hy⟩ exact hi this @@ -260,7 +260,7 @@ lemma ContMDiffWithinAt.finsum_section_of_locallyFinite choose U hu hfin using ht y have : {x | t x y ≠ 0} ⊆ {i | ((fun i ↦ {x | t i x ≠ 0}) i ∩ U).Nonempty} := by intro x hx - rw [Set.mem_setOf] at hx ⊢ + rw [Set.mem_ofPred] at hx ⊢ use y simpa using ⟨hx, mem_of_mem_nhds hu⟩ exact Set.Finite.subset hfin this diff --git a/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean b/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean index 5cdff3c88f91bc..08c6e1cbe53fcf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean @@ -235,7 +235,7 @@ private theorem mem_aux {e : OpenPartialHomeomorph (B × F) (B × F)} {n : ℕ (h2φ : ContMDiffOn IB 𝓘(𝕜, F →L[𝕜] F) n (fun x => (φ x).symm : B → F →L[𝕜] F) U), e.EqOnSource (FiberwiseLinear.openPartialHomeomorph φ hU hφ.continuousOn h2φ.continuousOn) := by - simp only [mem_iUnion, mem_setOf_eq] + simp only [mem_iUnion, mem_ofPred_eq] variable (F B IB) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 417ace8c8b5fe6..3b7d06384948c8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -519,7 +519,7 @@ lemma MDifferentiableWithinAt.sum_section_of_locallyFinite by_contra! h have : i ∈ s.toFinset := by refine Set.mem_toFinset.mpr ?_ - simp only [s, ne_eq, Set.mem_setOf_eq] + simp only [s, ne_eq, Set.mem_ofPred_eq] use y simp [h, hy] exact hi this @@ -556,7 +556,7 @@ lemma MDifferentiableWithinAt.finsum_section_of_locallyFinite choose U hu hfin using ht y have : {x | t x y ≠ 0} ⊆ {i | ((fun i ↦ {x | t i x ≠ 0}) i ∩ U).Nonempty} := by intro x hx - rw [Set.mem_setOf] at hx ⊢ + rw [Set.mem_ofPred] at hx ⊢ use y simpa using ⟨hx, mem_of_mem_nhds hu⟩ rw [tsum_eq_finsum (hfin.subset this)] diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index 854ce371863c3d..745a3c0c608e19 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -315,7 +315,7 @@ def emptyIsInitial : Limits.IsInitial (∅ : LocallyRingedSpace.{u}) := Limits.I theorem basicOpen_zero (X : LocallyRingedSpace.{u}) (U : Opens X.carrier) : X.toRingedSpace.basicOpen (0 : X.presheaf.obj <| op U) = ⊥ := by ext x - simp only [RingedSpace.basicOpen, Opens.coe_mk, Set.mem_setOf_eq, + simp only [RingedSpace.basicOpen, Opens.coe_mk, Set.mem_ofPred_eq, Opens.coe_bot, Set.mem_empty_iff_false, iff_false, not_exists] intro hx diff --git a/Mathlib/GroupTheory/Archimedean.lean b/Mathlib/GroupTheory/Archimedean.lean index 343242596c899c..7030d408988017 100644 --- a/Mathlib/GroupTheory/Archimedean.lean +++ b/Mathlib/GroupTheory/Archimedean.lean @@ -85,7 +85,7 @@ theorem Subgroup.exists_isLeast_one_lt {H : Subgroup G} (hbot : H ≠ ⊥) {a : exact ⟨n, _, (@mabs_mem_iff (Subgroup G) G _ _).2 hgH, hn⟩ classical rcases Nat.findX this with ⟨n, ⟨x, hxH, hnx, hxn⟩, hmin⟩ by_contra hxmin - simp only [IsLeast, not_and, mem_setOf_eq, mem_lowerBounds, not_exists, not_forall, + simp only [IsLeast, not_and, mem_ofPred_eq, mem_lowerBounds, not_exists, not_forall, not_le] at hxmin rcases hxmin x ⟨hxH, (one_le_pow_of_one_le' h₀.le _).trans_lt hnx⟩ with ⟨y, ⟨hyH, hy₀⟩, hxy⟩ obtain ⟨m, hm, hya⟩ := hex y hy₀ diff --git a/Mathlib/GroupTheory/ArchimedeanDensely.lean b/Mathlib/GroupTheory/ArchimedeanDensely.lean index aa0dcdb38da470..a440443a50641a 100644 --- a/Mathlib/GroupTheory/ArchimedeanDensely.lean +++ b/Mathlib/GroupTheory/ArchimedeanDensely.lean @@ -157,7 +157,7 @@ lemma Subgroup.isLeast_of_closure_iff_eq_mabs {a b : G} : rw [mem_closure_singleton] at ha obtain ⟨n, rfl⟩ := ha have := h.left - simp only [mem_closure_singleton, mem_setOf_eq] at this + simp only [mem_closure_singleton, mem_ofPred_eq] at this obtain ⟨m, hm⟩ := this.left have key : m * n = 1 := by rw [← zpow_right_inj this.right, zpow_mul', hm, zpow_one] @@ -174,7 +174,7 @@ lemma Subgroup.isLeast_of_closure_iff_eq_mabs {a b : G} : refine ⟨?_, ?_⟩ · simp [h] · intro x - simp only [mem_closure_singleton, mem_setOf_eq, and_imp, forall_exists_index] + simp only [mem_closure_singleton, mem_ofPred_eq, and_imp, forall_exists_index] rintro k rfl hk rw [← zpow_one b, ← zpow_mul, one_mul, zpow_le_zpow_iff_right h, ← zero_add 1, ← Int.lt_iff_add_one_le] @@ -336,7 +336,7 @@ lemma LinearOrderedCommGroupWithZero.discrete_iff_not_denselyOrdered (G : Type*) section WellFounded set_option backward.isDefEq.respectTransparency false in -lemma LinearOrderedAddCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete +lemma LinearOrderedAddCommGroup.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete {G : Type*} [AddCommGroup G] [LinearOrder G] [IsOrderedAddMonoid G] [Nontrivial G] {g : G} : Set.WellFoundedOn {x : G | g ≤ x} (· < ·) ↔ Nonempty (G ≃+o ℤ) := by suffices Set.WellFoundedOn {x : G | 0 ≤ x} (· < ·) ↔ Nonempty (G ≃+o ℤ) by @@ -370,41 +370,57 @@ lemma LinearOrderedAddCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete have : LocallyFiniteOrder G := LocallyFiniteOrder.ofOrderIsoClass f exact BddBelow.wellFoundedOn_lt ⟨0, by simp [mem_lowerBounds]⟩ -lemma LinearOrderedAddCommGroup.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete +@[deprecated (since := "2026-07-09")] +alias LinearOrderedAddCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete := + LinearOrderedAddCommGroup.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete + +lemma LinearOrderedAddCommGroup.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete {G : Type*} [AddCommGroup G] [LinearOrder G] [IsOrderedAddMonoid G] [Nontrivial G] (g : G) : Set.WellFoundedOn {x : G | x ≤ g} (· > ·) ↔ Nonempty (G ≃+o ℤ) := by - rw [← wellFoundedOn_setOf_le_lt_iff_nonempty_discrete (g := -g)] + rw [← wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete (g := -g)] refine ⟨fun h ↦ (h.mapsTo (- ·) ?_).mono' ?_, fun h ↦ (h.mapsTo (- ·) ?_).mono' ?_⟩ <;> · intro simp [Function.onFun, neg_le] +@[deprecated (since := "2026-07-09")] +alias LinearOrderedAddCommGroup.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete := + LinearOrderedAddCommGroup.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete + set_option backward.isDefEq.respectTransparency false in -lemma LinearOrderedCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete +lemma LinearOrderedCommGroup.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete {G : Type*} [CommGroup G] [LinearOrder G] [IsOrderedMonoid G] [Nontrivial G] {g : G} : Set.WellFoundedOn {x : G | g ≤ x} (· < ·) ↔ Nonempty (G ≃*o Multiplicative ℤ) := by let e : G ≃o Additive G := OrderIso.refl G suffices Set.WellFoundedOn {x : G | g ≤ x} (· < ·) ↔ Set.WellFoundedOn {x | e g ≤ x} (· < ·) by - rw [this, LinearOrderedAddCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete, + rw [this, LinearOrderedAddCommGroup.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete, OrderAddMonoidIso.toMultiplicativeRight.nonempty_congr] refine ⟨fun h ↦ (h.mapsTo e.symm fun _ ↦ e.le_symm_apply.mpr).mono' ?_, fun h ↦ (h.mapsTo e fun _ ↦ ?_).mono' ?_⟩ <;> simp [Function.onFun] -lemma LinearOrderedCommGroup.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete +@[deprecated (since := "2026-07-09")] +alias LinearOrderedCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete := + LinearOrderedCommGroup.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete + +lemma LinearOrderedCommGroup.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete {G : Type*} [CommGroup G] [LinearOrder G] [IsOrderedMonoid G] [Nontrivial G] (g : G) : Set.WellFoundedOn {x : G | x ≤ g} (· > ·) ↔ Nonempty (G ≃*o Multiplicative ℤ) := by - rw [← wellFoundedOn_setOf_le_lt_iff_nonempty_discrete (g := g⁻¹)] + rw [← wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete (g := g⁻¹)] refine ⟨fun h ↦ (h.mapsTo (·⁻¹) ?_).mono' ?_, fun h ↦ (h.mapsTo (·⁻¹) ?_).mono' ?_⟩ <;> · intro simp [Function.onFun, inv_le'] +@[deprecated (since := "2026-07-09")] +alias LinearOrderedCommGroup.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete := + LinearOrderedCommGroup.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete + set_option backward.isDefEq.respectTransparency false in -lemma LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete_of_ne_zero +lemma LinearOrderedCommGroupWithZero.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete_of_ne_zero {G₀ : Type*} [LinearOrderedCommGroupWithZero G₀] [Nontrivial G₀ˣ] {g : G₀} (hg : g ≠ 0) : Set.WellFoundedOn {x : G₀ | g ≤ x} (· < ·) ↔ Nonempty (G₀ ≃*o ℤᵐ⁰) := by suffices Set.WellFoundedOn {x : G₀ | g ≤ x} (· < ·) ↔ Set.WellFoundedOn {x : G₀ˣ | Units.mk0 g hg ≤ x} (· < ·) by - rw [this, LinearOrderedCommGroup.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete] + rw [this, LinearOrderedCommGroup.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete] refine Nonempty.congr (fun f ↦ ⟨?_, ?_⟩) (fun f ↦ ⟨?_, ?_⟩) · exact WithZero.withZeroUnitsEquiv.symm.trans f.withZero · intro a b @@ -425,44 +441,52 @@ lemma LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_le_lt_iff_nonempty_disc · simp [Function.onFun] · exact fun x ↦ if h : x = 0 then 1 else Units.mk0 x h · simp +contextual [← Units.val_le_val, MapsTo] - · simp only [mem_sdiff, mem_setOf_eq, mem_singleton_iff, Function.onFun, and_imp] + · simp only [mem_sdiff, mem_ofPred_eq, mem_singleton_iff, Function.onFun, and_imp] intro _ _ ha0 _ _ hb0 h simp [ha0, hb0, ← Units.val_lt_val, h] -lemma LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete_of_ne_zero +@[deprecated (since := "2026-07-09")] +alias LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_le_lt_iff_nonempty_discrete_of_ne_zero := + LinearOrderedCommGroupWithZero.wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete_of_ne_zero + +lemma LinearOrderedCommGroupWithZero.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete_of_ne_zero {G₀ : Type*} [LinearOrderedCommGroupWithZero G₀] [Nontrivial G₀ˣ] {g : G₀} (hg : g ≠ 0) : Set.WellFoundedOn {x : G₀ | x ≤ g} (· > ·) ↔ Nonempty (G₀ ≃*o ℤᵐ⁰) := by have hg' : g⁻¹ ≠ 0 := by simp [hg] - rw [← wellFoundedOn_setOf_le_lt_iff_nonempty_discrete_of_ne_zero hg', + rw [← wellFoundedOn_setOfPred_le_lt_iff_nonempty_discrete_of_ne_zero hg', ← Set.wellFoundedOn_sdiff_singleton (a := 0)] refine ⟨fun h ↦ (h.mapsTo (·⁻¹) ?_).mono' ?_, fun h ↦ (h.mapsTo (·⁻¹) ?_).mono' ?_⟩ · intro x rcases eq_or_ne x 0 with rfl | hx · simp [hg] - simp only [mem_setOf_eq, mem_sdiff, mem_singleton_iff, inv_eq_zero, hx, not_false_eq_true, + simp only [mem_ofPred_eq, mem_sdiff, mem_singleton_iff, inv_eq_zero, hx, not_false_eq_true, and_true] refine (inv_le_comm₀ ?_ ?_).mp <;> simp [zero_lt_iff, hg, hx] - · simp only [mem_setOf_eq, Function.onFun, gt_iff_lt] + · simp only [mem_ofPred_eq, Function.onFun, gt_iff_lt] intro a ha b _ refine inv_strictAnti₀ ?_ contrapose! ha simp only [le_zero_iff] at ha simp [zero_lt_iff, ha, hg] · intro x - simp only [mem_sdiff, mem_setOf_eq, mem_singleton_iff, and_imp] + simp only [mem_sdiff, mem_ofPred_eq, mem_singleton_iff, and_imp] intro hxg hx refine inv_anti₀ ?_ hxg simp [zero_lt_iff, hx] - · simp only [mem_sdiff, mem_setOf_eq, mem_singleton_iff, gt_iff_lt, Function.onFun, and_imp] + · simp only [mem_sdiff, mem_ofPred_eq, mem_singleton_iff, gt_iff_lt, Function.onFun, and_imp] intro a _ _ b _ hb0 refine inv_strictAnti₀ ?_ simp [zero_lt_iff, hb0] +@[deprecated (since := "2026-07-09")] +alias LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete_of_ne_zero := + LinearOrderedCommGroupWithZero.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete_of_ne_zero + instance instWellFoundedGTWithZeroMultiplicativeIntLeOne : WellFoundedGT { v : ℤᵐ⁰ // v ≤ 1 } := { wf := - (LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete_of_ne_zero + (LinearOrderedCommGroupWithZero.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete_of_ne_zero one_ne_zero).mpr instNonemptyOfInhabited } end WellFounded diff --git a/Mathlib/GroupTheory/ClassEquation.lean b/Mathlib/GroupTheory/ClassEquation.lean index 6a4fda33a8de2e..2147807039c374 100644 --- a/Mathlib/GroupTheory/ClassEquation.lean +++ b/Mathlib/GroupTheory/ClassEquation.lean @@ -67,7 +67,7 @@ theorem Group.nat_card_center_add_sum_card_noncenter_eq_card [Finite G] : rw [Finset.card_eq_sum_ones] refine Finset.sum_congr rfl ?_ rintro ⟨g⟩ hg - simp only [noncenter, Set.toFinset_setOf, Finset.mem_univ, true_and, + simp only [noncenter, Set.toFinset_ofPred, Finset.mem_univ, true_and, Finset.mem_sdiff, Finset.mem_filter, Set.not_nontrivial_iff] at hg rw [eq_comm, ← Set.toFinset_card, Finset.card_eq_one] exact ⟨g, Finset.coe_injective <| by simpa using hg.eq_singleton_of_mem mem_carrier_mk⟩ diff --git a/Mathlib/GroupTheory/Commensurable.lean b/Mathlib/GroupTheory/Commensurable.lean index a3868568ee9971..bb5e89d4d4e8d9 100644 --- a/Mathlib/GroupTheory/Commensurable.lean +++ b/Mathlib/GroupTheory/Commensurable.lean @@ -93,11 +93,11 @@ theorem commensurable_inv (H : Subgroup G) (g : ConjAct G) : such that `Commensurable (g • H) H` -/ def commensurator' (H : Subgroup G) : Subgroup (ConjAct G) where carrier := { g : ConjAct G | Commensurable (g • H) H } - one_mem' := by rw [Set.mem_setOf_eq, one_smul] + one_mem' := by rw [Set.mem_ofPred_eq, one_smul] mul_mem' ha hb := by - rw [Set.mem_setOf_eq, mul_smul] + rw [Set.mem_ofPred_eq, mul_smul] exact trans ((commensurable_conj _).mp hb) ha - inv_mem' _ := by rwa [Set.mem_setOf_eq, comm, ← commensurable_inv] + inv_mem' _ := by rwa [Set.mem_ofPred_eq, comm, ← commensurable_inv] /-- For `H` a subgroup of `G`, this is the subgroup of all elements `g : G` such that `Commensurable (g H g⁻¹) H` -/ diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index e1f4c40a973d8e..08069325e3a9c6 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -81,8 +81,8 @@ variable {M} theorem commProb_eq_one_iff [h : Nonempty M] : commProb M = 1 ↔ IsMulCommutative M := by classical - have := Fintype.ofFinite M - rw [commProb, ← Set.coe_setOf, Nat.card_eq_fintype_card, Nat.card_eq_fintype_card] + haveI := Fintype.ofFinite M + rw [commProb, ← Set.coe_ofPred, Nat.card_eq_fintype_card, Nat.card_eq_fintype_card] rw [div_eq_one_iff_eq, ← Nat.cast_pow, Nat.cast_inj, sq, ← card_prod, set_fintype_card_eq_univ_iff, Set.eq_univ_iff_forall] · exact ⟨fun h ↦ ⟨⟨fun x y ↦ h (x, y)⟩⟩, fun h x ↦ mul_comm' ..⟩ diff --git a/Mathlib/GroupTheory/Coset/Basic.lean b/Mathlib/GroupTheory/Coset/Basic.lean index 896ebb56a467bd..5fce88bf8088e5 100644 --- a/Mathlib/GroupTheory/Coset/Basic.lean +++ b/Mathlib/GroupTheory/Coset/Basic.lean @@ -294,7 +294,7 @@ variable {s} {a b : α} theorem eq_class_eq_leftCoset (s : Subgroup α) (g : α) : { x : α | (x : α ⧸ s) = g } = g • s := Set.ext fun z => by - rw [mem_leftCoset_iff, Set.mem_setOf_eq, eq_comm, QuotientGroup.eq, SetLike.mem_coe] + rw [mem_leftCoset_iff, Set.mem_ofPred_eq, eq_comm, QuotientGroup.eq, SetLike.mem_coe] open MulAction in @[to_additive] diff --git a/Mathlib/GroupTheory/CosetCover.lean b/Mathlib/GroupTheory/CosetCover.lean index 5dc34f40e03b57..1edf638d1565fc 100644 --- a/Mathlib/GroupTheory/CosetCover.lean +++ b/Mathlib/GroupTheory/CosetCover.lean @@ -288,7 +288,7 @@ theorem leftCoset_cover_filter_FiniteIndex_aux intro h i hi j hj hij c hi' hj' x hx have hdisjoint := pairwiseDisjoint_leftCoset_cover_const_of_index_eq hcovers' h.symm -- We know the `f k • K k` are pairwise disjoint and need to prove that the `g i • H i` are. - rw [Set.mem_setOf_eq] at hi hj + rw [Set.mem_ofPred_eq] at hi hj have hk' (i) (hi : i ∈ s ∧ (H i).FiniteIndex) (hi' : c ≤ g i • (H i : Set G)) : ∃ (k : κ), k.1.1 = i ∧ K k = D ∧ x ∈ f k • (D : Set G) := by rw [← (ht i hi.1 hi.2).2] at hi' diff --git a/Mathlib/GroupTheory/Finiteness.lean b/Mathlib/GroupTheory/Finiteness.lean index 9fb6565793c25a..94b7800511a2a4 100644 --- a/Mathlib/GroupTheory/Finiteness.lean +++ b/Mathlib/GroupTheory/Finiteness.lean @@ -587,18 +587,18 @@ theorem Submonoid.fg_of_divisive {P : Submonoid M} (hP : ∀ x ∈ P, ∀ y, x * P.FG := by have hpwo := Set.isPWO_of_wellQuasiOrderedLE { x | x ∈ P ∧ x ≠ 1 } rw [fg_iff] - refine ⟨_, ?_, (setOf_minimal_antichain _).finite_of_partiallyWellOrderedOn - (hpwo.mono (setOf_minimal_subset _))⟩ + refine ⟨_, ?_, (setOfPred_minimal_antichain _).finite_of_partiallyWellOrderedOn + (hpwo.mono (setOfPred_minimal_subset _))⟩ ext x constructor · intro hx rw [← P.closure_eq] - exact closure_mono ((setOf_minimal_subset _).trans fun _ => And.left) hx + exact closure_mono ((setOfPred_minimal_subset _).trans fun _ => And.left) hx · intro hx₁ by_cases hx₂ : x = 1 · simp [hx₂] refine hpwo.wellFoundedOn.induction ⟨hx₁, hx₂⟩ fun y ⟨hy₁, hy₂⟩ ih => ?_ - simp only [Set.mem_setOf_eq, and_imp] at ih + simp only [Set.mem_ofPred_eq, and_imp] at ih by_cases hy₃ : Minimal (· ∈ { x | x ∈ P ∧ x ≠ 1 }) y · exact mem_closure_of_mem hy₃ rcases exists_lt_of_not_minimal ⟨hy₁, hy₂⟩ hy₃ with ⟨z, hz₁, hz₂, hz₃⟩ diff --git a/Mathlib/GroupTheory/FreeGroup/Orbit.lean b/Mathlib/GroupTheory/FreeGroup/Orbit.lean index 516448f05a7c3b..fdc6ee23999cbc 100644 --- a/Mathlib/GroupTheory/FreeGroup/Orbit.lean +++ b/Mathlib/GroupTheory/FreeGroup/Orbit.lean @@ -38,17 +38,17 @@ theorem startsWith.ne_one {w : α × Bool} (g : FreeGroup α) (h : g ∈ FreeGro lemma startsWith.disjoint_iff_ne {w w' : α × Bool} : Disjoint (startsWith w) (startsWith w') ↔ w ≠ w' := by simp_all only [ne_eq, startsWith, Set.disjoint_iff_inter_eq_empty, Set.ext_iff, Set.mem_inter_iff, - Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false, not_and, Option.some.injEq] + Set.mem_ofPred_eq, Set.mem_empty_iff_false, iff_false, not_and, Option.some.injEq] exact Iff.intro (fun h ↦ h (mk [w]) (by simp)) (by grind) lemma startsWith.Injective : @startsWith α _ |>.Injective := fun a b h ↦ by - simp only [startsWith, Set.ext_iff, Set.mem_setOf_eq] at h + simp only [startsWith, Set.ext_iff, Set.mem_ofPred_eq] at h simpa using h (mk [a]) theorem startsWith_mk_mul {w : α × Bool} (g : FreeGroup α) (h : ¬ g ∈ startsWith (w.1, !w.2)) : mk [w] * g ∈ startsWith w := by by_cases hC : 0 < g.toWord.length - · simp only [startsWith, Set.mem_setOf_eq, getElem?_pos, Option.some.injEq, + · simp only [startsWith, Set.mem_ofPred_eq, getElem?_pos, Option.some.injEq, Prod.eq_iff_fst_eq_snd_eq, not_and, Bool.not_eq_not, toWord_mul, toWord_mk, reduce.cons, reduce_nil, List.cons_append, List.nil_append, reduce_toWord, hC] at * rw [show g.toWord = g.toWord.head (by grind) :: g.toWord.tail by grind] diff --git a/Mathlib/GroupTheory/HNNExtension.lean b/Mathlib/GroupTheory/HNNExtension.lean index 1ee783a4c4d63c..ae63f573fbae73 100644 --- a/Mathlib/GroupTheory/HNNExtension.lean +++ b/Mathlib/GroupTheory/HNNExtension.lean @@ -125,7 +125,7 @@ theorem induction_on {motive : HNNExtension G A B φ → Prop} (t : motive t) (mul : ∀ x y, motive x → motive y → motive (x * y)) (inv : ∀ x, motive x → motive x⁻¹) : motive x := by let S : Subgroup (HNNExtension G A B φ) := - { carrier := setOf motive + { carrier := Set.ofPred motive one_mem' := by simpa using of 1 mul_mem' := mul _ _ inv_mem' := inv _ } diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index cc26eb161773ef..365bd7e72c0251 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -192,7 +192,7 @@ theorem upperCentralSeries_zero : upperCentralSeries G 0 = ⊥ := rfl theorem upperCentralSeries_one : upperCentralSeries G 1 = center G := by ext simp only [upperCentralSeries, upperCentralSeriesAux, upperCentralSeriesStep, mem_bot, mem_mk, - Submonoid.mem_mk, Subsemigroup.mem_mk, Set.mem_setOf_eq, mem_center_iff] + Submonoid.mem_mk, Subsemigroup.mem_mk, Set.mem_ofPred_eq, mem_center_iff] exact forall_congr' fun y => by rw [commutatorElement_def, mul_inv_eq_one, mul_inv_eq_iff_eq_mul, eq_comm] @@ -201,7 +201,7 @@ theorem _root_.AddSubgroup.upperCentralSeries_one (G : Type*) [AddGroup G] : ext simp only [AddSubgroup.upperCentralSeries, AddSubgroup.upperCentralSeriesAux, AddSubgroup.upperCentralSeriesStep, AddSubgroup.mem_bot, AddSubgroup.mem_mk, - AddSubmonoid.mem_mk, AddSubsemigroup.mem_mk, Set.mem_setOf_eq, AddSubgroup.mem_center_iff] + AddSubmonoid.mem_mk, AddSubsemigroup.mem_mk, Set.mem_ofPred_eq, AddSubgroup.mem_center_iff] exact forall_congr' fun y => by rw [addCommutatorElement_def, add_neg_eq_zero, add_neg_eq_iff_eq_add, eq_comm] diff --git a/Mathlib/GroupTheory/Perm/Centralizer.lean b/Mathlib/GroupTheory/Perm/Centralizer.lean index 0b7059a02889f2..057b16dd8940e6 100644 --- a/Mathlib/GroupTheory/Perm/Centralizer.lean +++ b/Mathlib/GroupTheory/Perm/Centralizer.lean @@ -174,12 +174,12 @@ def range_toPermHom' : Subgroup (Perm g.cycleFactorsFinset) where carrier := {τ | ∀ c, #(τ c).val.support = #c.val.support} one_mem' := by simp mul_mem' hσ hτ := by - simp only [Subtype.forall, Set.mem_setOf_eq, coe_mul, Function.comp_apply] - simp only [Subtype.forall, Set.mem_setOf_eq] at hσ hτ + simp only [Subtype.forall, Set.mem_ofPred_eq, coe_mul, Function.comp_apply] + simp only [Subtype.forall, Set.mem_ofPred_eq] at hσ hτ intro c hc rw [hσ, hτ] inv_mem' hσ := by - simp only [Subtype.forall, Set.mem_setOf_eq] at hσ ⊢ + simp only [Subtype.forall, Set.mem_ofPred_eq] at hσ ⊢ intro c hc rw [← hσ _ (by simp)] simp @@ -467,7 +467,7 @@ theorem nat_card_range_toPermHom : set sc := fun (c : g.cycleFactorsFinset) ↦ #c.val.support with hsc suffices Fintype.card (toPermHom g).range = Fintype.card { k : Perm g.cycleFactorsFinset | sc ∘ k = sc } by - simp only [Nat.card_eq_fintype_card, this, Set.coe_setOf, DomMulAct.stabilizer_card', hsc, + simp only [Nat.card_eq_fintype_card, this, Set.coe_ofPred, DomMulAct.stabilizer_card', hsc, Finset.univ_eq_attach] simp_rw [← CycleType.count_def] apply Finset.prod_congr _ (fun _ _ => rfl) @@ -478,7 +478,7 @@ theorem nat_card_range_toPermHom : simp only [Fintype.card_eq_nat_card] congr ext - rw [mem_range_toPermHom_iff', Set.mem_setOf_eq] + rw [mem_range_toPermHom_iff', Set.mem_ofPred_eq] section Kernel /- Here, we describe the kernel of `g.OnCycleFactors.toPermHom` -/ @@ -652,7 +652,7 @@ theorem card_isConj_mul_eq : rw [Subgroup.nat_card_centralizer_nat_card_stabilizer, Nat.card_eq_fintype_card] convert! MulAction.card_orbit_mul_card_stabilizer_eq_card_group (ConjAct (Perm α)) g · ext h - simp only [Set.mem_setOf_eq, ConjAct.mem_orbit_conjAct, isConj_comm] + simp only [Set.mem_ofPred_eq, ConjAct.mem_orbit_conjAct, isConj_comm] · rw [ConjAct.card, Fintype.card_perm] /-- Cardinality of a conjugacy class in `Equiv.Perm α` of a given `cycleType` -/ @@ -686,7 +686,7 @@ theorem card_of_cycleType_mul_eq (m : Multiset ℕ) : classical obtain ⟨g, rfl⟩ := (exists_with_cycleType_iff α).mpr hm convert! card_isConj_mul_eq g - simp_rw [Set.coe_setOf, Nat.card_eq_fintype_card, ← Fintype.card_coe, Finset.mem_filter, + simp_rw [Set.coe_ofPred, Nat.card_eq_fintype_card, ← Fintype.card_coe, Finset.mem_filter, Finset.mem_univ, true_and, ← isConj_iff_cycleType_eq, isConj_comm (g := g)] · -- empty case rw [(card_of_cycleType_eq_zero_iff α).mpr hm, zero_mul] diff --git a/Mathlib/GroupTheory/Perm/ClosureSwap.lean b/Mathlib/GroupTheory/Perm/ClosureSwap.lean index dcef20d0f5d7c1..7a8cb3d3f0dd39 100644 --- a/Mathlib/GroupTheory/Perm/ClosureSwap.lean +++ b/Mathlib/GroupTheory/Perm/ClosureSwap.lean @@ -94,7 +94,7 @@ theorem swap_mem_closure_isSwap {S : Set (Perm α)} (hS : ∀ f ∈ S, f.IsSwap) obtain rfl | rfl := this <;> simpa [swap_comm] using subset_closure hσ · obtain ⟨x, y, -, rfl⟩ := hS f hf; rwa [swap_inv] · exact orbit_eq_iff.mpr hf ▸ ⟨⟨swap z y, hz⟩, swap_apply_right z y⟩ - · rw [mem_setOf, swap_self]; apply one_mem + · rw [mem_ofPred, swap_self]; apply one_mem /-- If a subgroup is generated by transpositions, then a permutation `f` lies in the subgroup if and only if `f` has finite support and `f x` always lies in the same orbit as `x`. -/ diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index 09af6d294f6052..9a1de233ef70da 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -831,7 +831,7 @@ variable [DecidableEq α] {l : List α} theorem Nodup.isCycleOn_formPerm (h : l.Nodup) : l.formPerm.IsCycleOn { a | a ∈ l } := by refine ⟨l.formPerm.bijOn fun _ => List.formPerm_mem_iff_mem, fun a ha b hb => ?_⟩ - rw [Set.mem_setOf, ← List.idxOf_lt_length_iff] at ha hb + rw [Set.mem_ofPred, ← List.idxOf_lt_length_iff] at ha hb rw [← List.getElem_idxOf ha, ← List.getElem_idxOf hb] refine ⟨l.idxOf b - l.idxOf a, ?_⟩ simp only [sub_eq_neg_add, zpow_add, zpow_neg, Equiv.Perm.inv_eq_iff_eq, zpow_natCast, diff --git a/Mathlib/GroupTheory/Perm/DomMulAct.lean b/Mathlib/GroupTheory/Perm/DomMulAct.lean index a1ca74e4bf92a2..4de8e32868c344 100644 --- a/Mathlib/GroupTheory/Perm/DomMulAct.lean +++ b/Mathlib/GroupTheory/Perm/DomMulAct.lean @@ -112,7 +112,7 @@ theorem stabilizer_ncard [Finite α] [Fintype ι] : Set.ncard {g : Perm α | f ∘ g = f} = ∏ i, (Set.ncard {a | f a = i})! := by classical cases nonempty_fintype α - simp only [← Nat.card_coe_set_eq, Set.coe_setOf, card_eq_fintype_card] + simp only [← Nat.card_coe_set_eq, Set.coe_ofPred, card_eq_fintype_card] exact stabilizer_card f variable [DecidableEq α] [DecidableEq ι] diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index c2a32f6f2de91c..0f0506c292369b 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -277,10 +277,10 @@ lemma disjoint_closure_of_disjoint_support {S T : Set (Perm α)} exact h theorem mem_range_ofSubtype_iff {p : α → Prop} [DecidablePred p] {g : Perm α} : - g ∈ (ofSubtype : Perm (Subtype p) →* Perm α).range ↔ (g.support : Set α) ⊆ setOf p := by + g ∈ (ofSubtype : Perm (Subtype p) →* Perm α).range ↔ (g.support : Set α) ⊆ Set.ofPred p := by constructor · rintro ⟨k, rfl⟩ x - simp only [Finset.mem_coe, mem_support_ofSubtype, Set.mem_setOf_eq] + simp only [Finset.mem_coe, mem_support_ofSubtype, Set.mem_ofPred_eq] exact fun ⟨hx, _⟩ ↦ hx · intro hg refine ⟨g.subtypePerm fun x ↦ ?_, ofSubtype_subtypePerm _ fun x hx ↦ hg (mem_support.mpr hx)⟩ diff --git a/Mathlib/GroupTheory/Perm/List.lean b/Mathlib/GroupTheory/Perm/List.lean index baac42b4178be2..0fc68bae8567f6 100644 --- a/Mathlib/GroupTheory/Perm/List.lean +++ b/Mathlib/GroupTheory/Perm/List.lean @@ -198,7 +198,7 @@ theorem support_formPerm_of_nodup' (l : List α) (h : Nodup l) (h' : ∀ x : α, · intro x hx simp only [Finset.mem_coe, mem_toFinset] at hx obtain ⟨n, hn, rfl⟩ := getElem_of_mem hx - rw [Set.mem_setOf_eq, formPerm_apply_getElem _ h] + rw [Set.mem_ofPred_eq, formPerm_apply_getElem _ h] intro H rw [nodup_iff_injective_get, Function.Injective] at h specialize h H @@ -273,7 +273,7 @@ theorem formPerm_ext_iff {x y x' y' : α} {l l' : List α} (hd : Nodup (x :: y : rw [Equiv.Perm.ext_iff] at h have hx : x' ∈ x :: y :: l := by have : x' ∈ { z | formPerm (x :: y :: l) z ≠ z } := by - rw [Set.mem_setOf_eq, h x', formPerm_apply_head _ _ _ hd'] + rw [Set.mem_ofPred_eq, h x', formPerm_apply_head _ _ _ hd'] simp only [mem_cons, nodup_cons] at hd' push Not at hd' exact hd'.left.left.symm diff --git a/Mathlib/GroupTheory/Perm/Support.lean b/Mathlib/GroupTheory/Perm/Support.lean index 66877efaa0306f..31cbf907e5615e 100644 --- a/Mathlib/GroupTheory/Perm/Support.lean +++ b/Mathlib/GroupTheory/Perm/Support.lean @@ -226,7 +226,7 @@ theorem set_support_apply_mem {p : Perm α} {a : α} : theorem set_support_zpow_subset (n : ℤ) : { x | (p ^ n) x ≠ x } ⊆ { x | p x ≠ x } := by intro x - simp only [Set.mem_setOf_eq, Ne] + simp only [Set.mem_ofPred_eq, Ne] intro hx H simp [zpow_apply_eq_self_of_apply_eq_self H] at hx diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating.lean index 13c0a8012a4303..9a59091907c5a9 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating.lean @@ -240,7 +240,7 @@ theorem closure_cycleType_eq_two_two_eq_alternatingGroup (h5 : 5 ≤ Nat.card α apply le_antisymm · rw [Subgroup.closure_le] intro g hg - simp only [Set.mem_setOf_eq] at hg + simp only [Set.mem_ofPred_eq] at hg simp [mem_alternatingGroup, sign_of_cycleType, hg, ← Units.val_inj] · rw [← Equiv.Perm.closure_three_cycles_eq_alternating, Subgroup.closure_le] intro g hg3 @@ -263,7 +263,7 @@ alias closure_cycleType_eq_2_2_eq_alternatingGroup := theorem cycleType_eq_two_two_subset_alternatingGroup : {g : Perm α | g.cycleType = {2, 2}} ⊆ alternatingGroup α := by intro g hg - rw [Set.mem_setOf_eq] at hg + rw [Set.mem_ofPred_eq] at hg simp [sign_of_cycleType, hg, ← Units.val_inj] theorem _root_.alternatingGroup.closure_cycleType_eq_two_two_eq_top (h5 : 5 ≤ Nat.card α) : diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/KleinFour.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/KleinFour.lean index 38f32ea1732143..64fbb887d2a2cb 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/KleinFour.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/KleinFour.lean @@ -123,7 +123,7 @@ theorem coe_two_sylow_of_card_eq_four · -- card (kleinFour α) ≤ card S simp_rw [← Nat.card_eq_fintype_card] refine (card_two_sylow_of_card_eq_four hα4 S).trans_ge ?_ - rw [Nat.card_eq_card_toFinset, Set.toFinset_union, Set.toFinset_singleton, Set.toFinset_setOf] + rw [Nat.card_eq_card_toFinset, Set.toFinset_union, Set.toFinset_singleton, Set.toFinset_ofPred] apply (Finset.card_union_le _ _).trans rw [Finset.card_singleton, AlternatingGroup.card_of_cycleType, ← Nat.card_eq_fintype_card, hα4] decide @@ -212,7 +212,7 @@ theorem kleinFour_eq_commutator (hα4 : Nat.card α = 4) : refine le_antisymm ?_ comm_le intro g hg rw [← SetLike.mem_coe, coe_kleinFour_of_card_eq_four hα4, - Set.mem_union, Set.mem_singleton_iff, Set.mem_setOf_eq] at hg + Set.mem_union, Set.mem_singleton_iff, Set.mem_ofPred_eq] at hg rcases hg with ⟨rfl⟩ | hg · exact Subgroup.one_mem _ · rw [← hg, ← Equiv.Perm.isConj_iff_cycleType_eq, isConj_iff] at hk22 @@ -227,7 +227,7 @@ theorem kleinFour_eq_commutator (hα4 : Nat.card α = 4) : simp have hk2 := comm_le hk rw [← SetLike.mem_coe, coe_kleinFour_of_card_eq_four hα4, - Set.mem_union, Set.mem_singleton_iff, Set.mem_setOf_eq] at hk2 + Set.mem_union, Set.mem_singleton_iff, Set.mem_ofPred_eq] at hk2 exact hk2.resolve_left hk' end alternatingGroup diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean index 1970ffeef55f6f..5bdbaf68f31411 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean @@ -168,7 +168,7 @@ def iwasawaStructure_four (h5 : 5 ≤ Nat.card α) : is_generator := by rw [eq_top_iff, ← closure_cycleType_eq_two_two_eq_top h5, Subgroup.closure_le] intro g hg - simp only [Set.mem_setOf_eq] at hg + simp only [Set.mem_ofPred_eq] at hg apply Subgroup.mem_iSup_of_mem ⟨(g : Perm α).support, by simp [← sum_cycleType, hg]⟩ rw [mem_map_kleinFour_ofSubtype] <;> simp [hg, ← sum_cycleType] diff --git a/Mathlib/GroupTheory/Subgroup/Center.lean b/Mathlib/GroupTheory/Subgroup/Center.lean index 07054d4d5c66a7..c194efbfb6bc2f 100644 --- a/Mathlib/GroupTheory/Subgroup/Center.lean +++ b/Mathlib/GroupTheory/Subgroup/Center.lean @@ -142,7 +142,7 @@ set_option backward.isDefEq.respectTransparency false in theorem mk_bijOn (G : Type*) [Group G] : Set.BijOn ConjClasses.mk (↑(Subgroup.center G)) (noncenter G)ᶜ := by refine ⟨fun g hg ↦ ?_, fun x hx y _ H ↦ ?_, ?_⟩ - · simp only [mem_noncenter, Set.compl_def, Set.mem_setOf, Set.not_nontrivial_iff] + · simp only [mem_noncenter, Set.compl_def, Set.mem_ofPred, Set.not_nontrivial_iff] intro x hx y hy simp only [mem_carrier_iff_mk_eq, mk_eq_mk_iff_isConj] at hx hy rw [hx.eq_of_right_mem_center hg, hy.eq_of_right_mem_center hg] @@ -150,7 +150,7 @@ theorem mk_bijOn (G : Type*) [Group G] : exact H.eq_of_left_mem_center hx · rintro ⟨g⟩ hg refine ⟨g, ?_, rfl⟩ - simp only [mem_noncenter, Set.compl_def, Set.mem_setOf, Set.not_nontrivial_iff] at hg + simp only [mem_noncenter, Set.compl_def, Set.mem_ofPred, Set.not_nontrivial_iff] at hg rw [SetLike.mem_coe, Subgroup.mem_center_iff] intro h rw [← mul_inv_eq_iff_eq_mul] diff --git a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean index 0e94d3104cfb03..155af0ce598ab5 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean @@ -516,7 +516,7 @@ lemma closedInterior_subset_affineSpan {n : ℕ} {s : Simplex k P n} : @[simp] lemma interior_eq_empty (s : Simplex k P 0) : s.interior = ∅ := by ext p simp only [Simplex.interior, Simplex.setInterior, Nat.reduceAdd, univ_unique, Fin.default_eq_zero, - Fin.isValue, sum_singleton, Set.mem_Ioo, Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false, + Fin.isValue, sum_singleton, Set.mem_Ioo, Set.mem_ofPred_eq, Set.mem_empty_iff_false, iff_false, not_exists, not_and] intro w h hi simpa [h] using hi 0 @@ -525,7 +525,7 @@ lemma closedInterior_subset_affineSpan {n : ℕ} {s : Simplex k P n} : s.closedInterior = {s.points 0} := by ext p simp only [Simplex.closedInterior, Simplex.setInterior, Nat.reduceAdd, univ_unique, - Fin.default_eq_zero, Fin.isValue, sum_singleton, Set.mem_Icc, Set.mem_setOf_eq, + Fin.default_eq_zero, Fin.isValue, sum_singleton, Set.mem_Icc, Set.mem_ofPred_eq, Set.mem_singleton_iff] constructor · rintro ⟨w, h0, hi, rfl⟩ diff --git a/Mathlib/LinearAlgebra/Basis/Flag.lean b/Mathlib/LinearAlgebra/Basis/Flag.lean index a9860c9e1a9e38..13d132de0285e8 100644 --- a/Mathlib/LinearAlgebra/Basis/Flag.lean +++ b/Mathlib/LinearAlgebra/Basis/Flag.lean @@ -48,7 +48,7 @@ theorem flag_le_iff (b : Basis (Fin n) R M) {k p} : theorem flag_succ (b : Basis (Fin n) R M) (k : Fin n) : b.flag k.succ = R ∙ b k ⊔ b.flag k.castSucc := by simp only [flag, Fin.castSucc_lt_castSucc_iff] - simp [Fin.castSucc_lt_iff_succ_le, le_iff_eq_or_lt, setOf_or, image_insert_eq, span_insert] + simp [Fin.castSucc_lt_iff_succ_le, le_iff_eq_or_lt, ofPred_or, image_insert_eq, span_insert] theorem self_mem_flag (b : Basis (Fin n) R M) {i : Fin n} {k : Fin (n + 1)} (h : i.castSucc < k) : b i ∈ b.flag k := diff --git a/Mathlib/LinearAlgebra/Basis/Submodule.lean b/Mathlib/LinearAlgebra/Basis/Submodule.lean index 66a6b48206518a..9675e3ef19ff73 100644 --- a/Mathlib/LinearAlgebra/Basis/Submodule.lean +++ b/Mathlib/LinearAlgebra/Basis/Submodule.lean @@ -131,7 +131,7 @@ lemma mem_center_iff {A} · intros exact ⟨h.2 _ _, h.3 _ _⟩ · intro h - rw [center, mem_setOf_eq] + rw [center, mem_ofPred_eq] constructor case comm => intro y diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index 450f0bb45438a2..e219b02bc95f7c 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -64,7 +64,7 @@ theorem coe_extend (hs : LinearIndepOn K id s) : ⇑(Basis.extend hs) = ((↑) : theorem range_extend (hs : LinearIndepOn K id s) : range (Basis.extend hs) = hs.extend (subset_univ _) := by - rw [coe_extend, Subtype.range_coe_subtype, setOf_mem_eq] + rw [coe_extend, Subtype.range_coe_subtype, ofPred_mem_eq] /-- Auxiliary definition: the index for the new basis vectors in `Basis.sumExtend`. @@ -107,7 +107,7 @@ theorem coe_extendLe (hs : LinearIndepOn K id s) (hst : s ⊆ t) (ht : ⊤ ≤ s theorem range_extendLe (hs : LinearIndepOn K id s) (hst : s ⊆ t) (ht : ⊤ ≤ span K t) : range (Basis.extendLe hs hst ht) = hs.extend hst := by - rw [coe_extendLe, Subtype.range_coe_subtype, setOf_mem_eq] + rw [coe_extendLe, Subtype.range_coe_subtype, ofPred_mem_eq] theorem subset_extendLe (hs : LinearIndepOn K id s) (hst : s ⊆ t) (ht : ⊤ ≤ span K t) : s ⊆ range (Basis.extendLe hs hst ht) := @@ -133,7 +133,7 @@ theorem coe_ofSpan (hs : ⊤ ≤ span K s) : ⇑(ofSpan hs) = ((↑) : _ → _) theorem range_ofSpan (hs : ⊤ ≤ span K s) : range (ofSpan hs) = (linearIndepOn_empty K id).extend (empty_subset s) := by - rw [coe_ofSpan, Subtype.range_coe_subtype, setOf_mem_eq] + rw [coe_ofSpan, Subtype.range_coe_subtype, ofPred_mem_eq] theorem ofSpan_subset (hs : ⊤ ≤ span K s) : range (ofSpan hs) ⊆ s := extendLe_subset (linearIndependent_empty K V) (empty_subset s) hs diff --git a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean index 39ddb80fac1a84..142d9b679805fa 100644 --- a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean @@ -382,7 +382,7 @@ theorem rank_span {v : ι → M} (hv : LinearIndependent R v) : Cardinal.mk_range_eq_of_injective (@LinearIndependent.injective ι R M v _ _ _ _ hv)] theorem rank_span_set {s : Set M} (hs : LinearIndepOn R id s) : Module.rank R ↑(span R s) = #s := by - rw [← @setOf_mem_eq _ s, ← Subtype.range_coe_subtype] + rw [← @ofPred_mem_eq _ s, ← Subtype.range_coe_subtype] exact rank_span hs theorem toENat_rank_span_set {v : ι → M} {s : Set ι} (hs : LinearIndepOn R v s) : diff --git a/Mathlib/LinearAlgebra/Dual/Basis.lean b/Mathlib/LinearAlgebra/Dual/Basis.lean index e6a38da36a96cf..e53f0baea62686 100644 --- a/Mathlib/LinearAlgebra/Dual/Basis.lean +++ b/Mathlib/LinearAlgebra/Dual/Basis.lean @@ -240,7 +240,7 @@ variable {e : ι → M} {ε : ι → Dual R M} def coeffs (h : DualBases e ε) (m : M) : ι →₀ R where toFun i := ε i m support := (h.finite m).toFinset - mem_support_toFun i := by rw [Set.Finite.mem_toFinset, Set.mem_setOf_eq] + mem_support_toFun i := by rw [Set.Finite.mem_toFinset, Set.mem_ofPred_eq] @[simp] theorem coeffs_apply (h : DualBases e ε) (m : M) (i : ι) : h.coeffs m i = ε i m := diff --git a/Mathlib/LinearAlgebra/Dual/Defs.lean b/Mathlib/LinearAlgebra/Dual/Defs.lean index 0323991b305053..8ce80686fc9861 100644 --- a/Mathlib/LinearAlgebra/Dual/Defs.lean +++ b/Mathlib/LinearAlgebra/Dual/Defs.lean @@ -458,7 +458,7 @@ theorem iSup_dualAnnihilator_le_iInf {ι : Sort*} (U : ι → Submodule R M) : lemma coe_dualAnnihilator_span (s : Set M) : ((span R s).dualAnnihilator : Set (Module.Dual R M)) = {f | s ⊆ LinearMap.ker f} := by ext f - simp only [SetLike.mem_coe, mem_dualAnnihilator, Set.mem_setOf_eq, ← LinearMap.mem_ker] + simp only [SetLike.mem_coe, mem_dualAnnihilator, Set.mem_ofPred_eq, ← LinearMap.mem_ker] exact span_le @[simp] @@ -466,7 +466,7 @@ lemma coe_dualCoannihilator_span (s : Set (Module.Dual R M)) : ((span R s).dualCoannihilator : Set M) = {x | ∀ f ∈ s, f x = 0} := by ext x have (φ : _) : x ∈ LinearMap.ker φ ↔ φ ∈ LinearMap.ker (Module.Dual.eval R M x) := by simp - simp only [SetLike.mem_coe, mem_dualCoannihilator, Set.mem_setOf_eq, ← LinearMap.mem_ker, this] + simp only [SetLike.mem_coe, mem_dualCoannihilator, Set.mem_ofPred_eq, ← LinearMap.mem_ker, this] exact span_le end Submodule diff --git a/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean b/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean index 871394de762e87..eacd609d238d82 100644 --- a/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean +++ b/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean @@ -95,7 +95,7 @@ lemma ιMulti_span_fixedDegree_of_span_eq_top {s : Set M} (hs : span R s = ⊤) rintro x hx obtain ⟨f, rfl⟩ := Set.mem_pow.mp hx refine mem_span_of_mem ⟨ExteriorAlgebra.ιInv ∘ Subtype.val ∘ f, ?_, ?_⟩ - · rw [Set.mem_setOf_eq, Set.range_comp, Set.image_subset_iff] + · rw [Set.mem_ofPred_eq, Set.range_comp, Set.image_subset_iff] apply Subset.trans ?_ (s.image_subset_preimage_of_inverse ExteriorAlgebra.ι_leftInverse) grind · rw [ExteriorAlgebra.ιMulti_apply] @@ -373,7 +373,7 @@ lemma ιMulti_family_span_fixedDegree_of_span {I : Type*} [LinearOrder I] {v : I exact Submodule.coe_mem _ · rw [← ιMulti_span_fixedDegree_of_span_eq_top R n M hv, Submodule.span_le] rintro - ⟨f, ⟨f_range, rfl⟩⟩ - rw [Set.mem_setOf] at f_range + rw [Set.mem_ofPred] at f_range obtain ⟨α, rfl⟩ := Set.range_subset_range_iff_exists_comp.mp f_range exact ιMulti_family_span_fixedDegree_aux R v α diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index 23015192aed5a0..d8ee12d84d46df 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -170,7 +170,7 @@ theorem linearCombination_equivMapDomain (f : α ≃ α') (l : α →₀ R) : direction -/ theorem span_eq_range_linearCombination (s : Set M) : span R s = LinearMap.range (linearCombination R ((↑) : s → M)) := by - rw [range_linearCombination, Subtype.range_coe_subtype, Set.setOf_mem_eq] + rw [range_linearCombination, Subtype.range_coe_subtype, Set.ofPred_mem_eq] theorem mem_span_iff_linearCombination (s : Set M) (x : M) : x ∈ span R s ↔ ∃ l : s →₀ R, linearCombination R (↑) l = x := @@ -515,7 +515,7 @@ lemma Submodule.span_eq_iUnion_nat (s : Set M) : (Submodule.span R s : Set M) = ⋃ (n : ℕ), (fun (f : Fin n → (R × M)) ↦ ∑ i, (f i).1 • (f i).2) '' ({f | ∀ i, (f i).2 ∈ s}) := by ext m - simp only [SetLike.mem_coe, mem_iUnion, mem_image, mem_setOf_eq, mem_span_set'] + simp only [SetLike.mem_coe, mem_iUnion, mem_image, mem_ofPred_eq, mem_span_set'] refine exists_congr (fun n ↦ ⟨?_, ?_⟩) · rintro ⟨f, g, rfl⟩ exact ⟨fun i ↦ (f i, g i), fun i ↦ (g i).2, rfl⟩ diff --git a/Mathlib/LinearAlgebra/Finsupp/Supported.lean b/Mathlib/LinearAlgebra/Finsupp/Supported.lean index cf21dbf21d1e89..b81a6ddf740d1c 100644 --- a/Mathlib/LinearAlgebra/Finsupp/Supported.lean +++ b/Mathlib/LinearAlgebra/Finsupp/Supported.lean @@ -48,7 +48,7 @@ def supported (s : Set α) : Submodule R (α →₀ M) where refine Subset.trans (Subset.trans (Finset.coe_subset.2 support_add) ?_) (union_subset hp hq) rw [Finset.coe_union] zero_mem' := by - simp only [subset_def, Finset.mem_coe, Set.mem_setOf_eq, mem_support_iff, zero_apply] + simp only [subset_def, Finset.mem_coe, Set.mem_ofPred_eq, mem_support_iff, zero_apply] intro h ha exact (ha rfl).elim smul_mem' _ _ hp := Subset.trans (Finset.coe_subset.2 support_smul) hp diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean index 67806c70471732..56f2c2116ea195 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean @@ -843,7 +843,7 @@ lemma linearIndepOn_iff' : LinearIndepOn R v s ↔ ∀ (t : Finset ι) (g : ι refine ⟨fun h t g hts h0 i hit ↦ ?_, fun h t g h0 i hit ↦ ?_⟩ · refine h (t.preimage _ Subtype.val_injective.injOn) (fun i ↦ g i) ?_ ⟨i, hts hit⟩ (by simpa) rwa [t.sum_preimage ((↑) : s → ι) Subtype.val_injective.injOn (fun i ↦ g i • v i)] - simp only [Subtype.range_coe_subtype, setOf_mem_eq] + simp only [Subtype.range_coe_subtype, ofPred_mem_eq] exact fun x hxt hxs ↦ (hxs (hts hxt)) |>.elim replace h : ∀ i (hi : i ∈ s), ⟨i, hi⟩ ∈ t → ∀ (h : i ∈ s), g ⟨i, h⟩ = 0 := by simpa [h0] using h (t.image (↑)) (fun i ↦ if hi : i ∈ s then g ⟨i, hi⟩ else 0) diff --git a/Mathlib/LinearAlgebra/Matrix/Diagonal.lean b/Mathlib/LinearAlgebra/Matrix/Diagonal.lean index f93a73bf8be827..b7e00ee95e303e 100644 --- a/Mathlib/LinearAlgebra/Matrix/Diagonal.lean +++ b/Mathlib/LinearAlgebra/Matrix/Diagonal.lean @@ -66,7 +66,7 @@ theorem ker_diagonal_toLin' [DecidableEq m] (w : m → K) : theorem range_diagonal [DecidableEq m] (w : m → K) : LinearMap.range (toLin' (diagonal w)) = ⨆ i ∈ { i | w i ≠ 0 }, LinearMap.range (LinearMap.single K (fun _ => K) i) := by - dsimp only [mem_setOf_eq] + dsimp only [mem_ofPred_eq] rw [← Submodule.map_top, ← iSup_range_single, Submodule.map_iSup] congr; funext i rw [← LinearMap.range_comp, diagonal_comp_single, ← range_smul'] diff --git a/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean b/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean index 8278edc557a2b2..5c9a66561da3d3 100644 --- a/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean +++ b/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean @@ -191,7 +191,7 @@ lemma reduce_mem_reps {m : ℤ} (hm : m ≠ 0) (A : Δ m) : reduce A ∈ reps m suffices A.1 1 0 = 0 ∧ n * A.1 1 0 < A.1 0 0 ∧ n * A.1 1 1 ≤ A.1 0 1 ∧ |A.1 0 1 + -(n * A.1 1 1)| < |A.1 1 1| by simpa only [reps, Fin.isValue, cons_mul, Nat.succ_eq_add_one, Nat.reduceAdd, empty_mul, - Equiv.symm_apply_apply, Set.mem_setOf_eq, of_apply, cons_val', vecMul, cons_dotProduct, + Equiv.symm_apply_apply, Set.mem_ofPred_eq, of_apply, cons_val', vecMul, cons_dotProduct, vecHead, one_mul, vecTail, Function.comp_apply, Fin.succ_zero_eq_one, neg_mul, dotProduct_of_isEmpty, add_zero, zero_mul, zero_add, empty_val', cons_val_fin_one, cons_val_one, cons_val_zero, lt_add_neg_iff_add_lt, le_add_neg_iff_add_le] @@ -200,7 +200,7 @@ lemma reduce_mem_reps {m : ℤ} (hm : m ≠ 0) (A : Δ m) : reduce A ∈ reps m · simp only [reps, Fin.isValue, reduce_of_not_pos h h1, Int.ediv_neg, neg_neg, smul_def, ← mul_assoc, S_mul_S_eq, neg_mul, one_mul, coe_T_zpow, mul_neg, cons_mul, Nat.succ_eq_add_one, Nat.reduceAdd, empty_mul, Equiv.symm_apply_apply, neg_of, neg_cons, neg_empty, - Set.mem_setOf_eq, of_apply, cons_val', Pi.neg_apply, vecMul, cons_dotProduct, vecHead, + Set.mem_ofPred_eq, of_apply, cons_val', Pi.neg_apply, vecMul, cons_dotProduct, vecHead, vecTail, Function.comp_apply, Fin.succ_zero_eq_one, h, mul_zero, dotProduct_of_isEmpty, add_zero, zero_mul, neg_zero, empty_val', cons_val_fin_one, cons_val_one, cons_val_zero, lt_neg, neg_add_rev, zero_add, le_add_neg_iff_add_le, ← le_neg, abs_neg, true_and] diff --git a/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean b/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean index 6d549201b1db5c..ad8616d8d1bf24 100644 --- a/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean +++ b/Mathlib/LinearAlgebra/PerfectPairing/Restrict.lean @@ -164,7 +164,7 @@ lemma exists_basis_basis_of_span_eq_top_of_mem_algebraMap have : IsReflexive L N := .of_isPerfPair p.flip obtain ⟨v, hv₁, hv₂, hv₃⟩ := exists_linearIndependent L (M' : Set M) rw [hM] at hv₂ - let b : Basis _ L M := Basis.mk hv₃ <| by rw [← hv₂, Subtype.range_coe_subtype, Set.setOf_mem_eq] + let b : Basis _ L M := Basis.mk hv₃ <| by rw [← hv₂, Subtype.range_coe_subtype, Set.ofPred_mem_eq] have : Fintype v := Set.Finite.fintype <| Module.Finite.finite_basis b set v' : v → M' := fun i ↦ ⟨i, hv₁ (Subtype.coe_prop i)⟩ have hv' : LinearIndependent K v' := by @@ -184,7 +184,8 @@ lemma exists_basis_basis_of_span_eq_top_of_mem_algebraMap refine le_antisymm (Submodule.span_le.mpr hv₁) fun m hm ↦ ?_ obtain ⟨w, hw₁, hw₂, hw₃⟩ := exists_linearIndependent L (N' : Set N) rw [hN] at hw₂ - let bN : Basis _ L N := Basis.mk hw₃ <| by rw [← hw₂, Subtype.range_coe_subtype, Set.setOf_mem_eq] + let bN : Basis _ L N := Basis.mk hw₃ <| by + rw [← hw₂, Subtype.range_coe_subtype, Set.ofPred_mem_eq] have : Fintype w := Set.Finite.fintype <| Module.Finite.finite_basis bN have e : v ≃ w := Fintype.equivOfCardEq <| by rw [← Module.finrank_eq_card_basis b, ← Module.finrank_eq_card_basis bN, Module.finrank_of_isPerfPair p] diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean index b3986bb327b39f..405485f74613b9 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean @@ -316,7 +316,7 @@ if and only if `x` is equal to the sum of `a • ⨂ₜ[R] i, m i` over all the -/ lemma mem_lifts_iff (x : ⨂[R] i, s i) (p : FreeAddMonoid (R × Π i, s i)) : p ∈ lifts x ↔ List.sum (List.map (fun x ↦ x.1 • ⨂ₜ[R] i, x.2 i) p.toList) = x := by - simp only [lifts, Set.mem_setOf_eq, FreeAddMonoid.toPiTensorProduct] + simp only [lifts, Set.mem_ofPred_eq, FreeAddMonoid.toPiTensorProduct] set_option backward.isDefEq.respectTransparency false in /-- Every element of `⨂[R] i, s i` has a lift in `FreeAddMonoid (R × Π i, s i)`. @@ -338,7 +338,7 @@ respectively, then `p + q` lifts `x + y`. -/ lemma lifts_add {x y : ⨂[R] i, s i} {p q : FreeAddMonoid (R × Π i, s i)} (hp : p ∈ lifts x) (hq : q ∈ lifts y) : p + q ∈ lifts (x + y) := by - simp only [lifts, Set.mem_setOf_eq, AddCon.coe_add] + simp only [lifts, Set.mem_ofPred_eq, AddCon.coe_add] rw [hp, hq] /-- If an element `p` of `FreeAddMonoid (R × Π i, s i)` lifts an element `x` of `⨂[R] i, s i`, @@ -493,7 +493,7 @@ theorem map_range_eq_span_tprod : Submodule.span R {t | ∃ (m : Π i, s i), tprod R (fun i ↦ f i (m i)) = t} := by rw [← Submodule.map_top, ← span_tprod_eq_top, Submodule.map_span, ← Set.range_comp] apply congrArg; ext x - simp only [Set.mem_range, comp_apply, map_tprod, Set.mem_setOf_eq] + simp only [Set.mem_range, comp_apply, map_tprod, Set.mem_ofPred_eq] /-- Given submodules `p i ⊆ s i`, this is the natural map: `⨂[R] i, p i → ⨂[R] i, s i`. This is `TensorProduct.mapIncl` for an arbitrary family of modules. diff --git a/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean b/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean index 2201a9a390797c..f3302b30f7cd12 100644 --- a/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean +++ b/Mathlib/LinearAlgebra/Projectivization/PSL/Stabilizer.lean @@ -36,7 +36,7 @@ def Matrix.SpecialLinearGroup.lineStab (L : Submodule F (ι → F)) : carrier := {A | ∀ w : ι → F, A • w - w ∈ L} one_mem' := by simp mul_mem' {A B} hA hB := fun w ↦ by - simp only [Set.mem_setOf_eq, mul_smul] at hA hB ⊢ + simp only [Set.mem_ofPred_eq, mul_smul] at hA hB ⊢ rw [show A • B • w - w = ((A • (B • w) - A • w) - (B • w - w)) + (B • w - w) + (A • w - w) by abel, ← smul_sub] exact add_mem (add_mem (hA _) (hB w)) (hA w) diff --git a/Mathlib/LinearAlgebra/Projectivization/Subspace.lean b/Mathlib/LinearAlgebra/Projectivization/Subspace.lean index bcc33f04603e05..9a62f08784f8a7 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Subspace.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Subspace.lean @@ -226,7 +226,7 @@ def submodule : Projectivization.Subspace K V ≃o Submodule K V where rw [Projectivization.mk_eq_mk_iff'] exact ⟨c, rfl⟩ } invFun s := - { carrier := setOf <| Projectivization.lift (↑· ∈ s) <| by + { carrier := Set.ofPred <| Projectivization.lift (↑· ∈ s) <| by rintro ⟨-, h⟩ ⟨y, -⟩ c rfl exact Iff.eq <| s.smul_mem_iff <| left_ne_zero_of_smul h mem_add' _ _ _ _ _ h₁ h₂ := s.add_mem h₁ h₂ } diff --git a/Mathlib/LinearAlgebra/Reflection.lean b/Mathlib/LinearAlgebra/Reflection.lean index ba099ca18b8bcb..87747700e75485 100644 --- a/Mathlib/LinearAlgebra/Reflection.lean +++ b/Mathlib/LinearAlgebra/Reflection.lean @@ -398,7 +398,7 @@ lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [IsDomain R] [IsTorsionFree intro F hF ⟨y, hy⟩ hy' simp only [Φ'] at hy' ⊢ rw [range_inclusion] at hy' - simp only [SetLike.coe_sort_coe, mem_setOf_eq] at hy' ⊢ + simp only [SetLike.coe_sort_coe, mem_ofPred_eq] at hy' ⊢ rw [range_inclusion] exact hF hy' exact eq_of_preReflection_mapsTo hΦ'₁ hΦ'₂ hf₁ (this hf₂) hg₁ (this hg₂) diff --git a/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean b/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean index 93819892cef487..362c5954a65b82 100644 --- a/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean +++ b/Mathlib/LinearAlgebra/RootSystem/BaseChange.lean @@ -33,7 +33,7 @@ extension of scalars. noncomputable section open Set Function -open Submodule (span injective_subtype span subset_span span_setOf_mem_eq_top) +open Submodule (span injective_subtype span subset_span span_setOfPred_mem_eq_top) namespace RootPairing @@ -91,12 +91,12 @@ def restrictScalars' : set_option backward.isDefEq.respectTransparency.types false in instance : (P.restrictScalars' K).IsRootSystem where span_root_eq_top := by - rw [← span_setOf_mem_eq_top] + rw [← span_setOfPred_mem_eq_top] congr ext ⟨x, hx⟩ simp [restrictScalars'] span_coroot_eq_top := by - rw [← span_setOf_mem_eq_top] + rw [← span_setOfPred_mem_eq_top] congr ext ⟨x, hx⟩ simp [restrictScalars'] diff --git a/Mathlib/LinearAlgebra/RootSystem/Chain.lean b/Mathlib/LinearAlgebra/RootSystem/Chain.lean index 6cf43c476911c9..a9d2b86d8a5bdd 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Chain.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Chain.lean @@ -42,7 +42,7 @@ variable {P : RootPairing ι R M N} [P.IsCrystallographic] {i j : ι} /-- Note that it is often more convenient to use `RootPairing.root_add_zsmul_mem_range_iff` than to invoke this lemma directly. -/ -lemma setOf_root_add_zsmul_eq_Icc_of_linearIndependent +lemma setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent (h : LinearIndependent R ![P.root i, P.root j]) : ∃ᵉ (q ≤ 0) (p ≥ 0), {z : ℤ | P.root j + z • P.root i ∈ range P.root} = Icc q p := by replace h := LinearIndependent.pair_iff.mp <| h.restrict_scalars' ℤ @@ -63,7 +63,7 @@ lemma setOf_root_add_zsmul_eq_Icc_of_linearIndependent have hki_notMem : P.root k + P.root i ∉ range P.root := by replace hk : P.root k + P.root i = P.root j + (r + 1) • P.root i := by rw [hk]; module replace contra : r + 1 ∉ S := hrs.notMem_of_mem_left <| by simp [contra] - simpa only [hk, S_def, mem_setOf_eq, S] using contra + simpa only [hk, S_def, mem_ofPred_eq, S] using contra have hki_ne : P.root k ≠ -P.root i := by rw [hk] contrapose! h @@ -72,7 +72,7 @@ lemma setOf_root_add_zsmul_eq_Icc_of_linearIndependent have hli_notMem : P.root l - P.root i ∉ range P.root := by replace hl : P.root l - P.root i = P.root j + (s - 1) • P.root i := by rw [hl]; module replace contra : s - 1 ∉ S := hrs.notMem_of_mem_left <| by simp [lt_sub_right_of_add_lt contra] - simpa only [hl, S_def, mem_setOf_eq, S] using contra + simpa only [hl, S_def, mem_ofPred_eq, S] using contra have hli_ne : P.root l ≠ P.root i := by rw [hl] contrapose! h @@ -96,6 +96,10 @@ lemma setOf_root_add_zsmul_eq_Icc_of_linearIndependent simp lia +@[deprecated (since := "2026-07-09")] +alias setOf_root_add_zsmul_eq_Icc_of_linearIndependent := + setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent + variable (i j) open scoped Classical in @@ -105,7 +109,7 @@ open scoped Classical in In the absence of linear independence, it takes a junk value. -/ def chainTopCoeff : ℕ := if h : LinearIndependent R ![P.root i, P.root j] - then (P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.2.choose.toNat + then (P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.2.choose.toNat else 0 open scoped Classical in @@ -115,7 +119,7 @@ open scoped Classical in In the absence of linear independence, it takes a junk value. -/ def chainBotCoeff : ℕ := if h : LinearIndependent R ![P.root i, P.root j] - then (-(P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose).toNat + then (-(P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose).toNat else 0 variable {i j} @@ -135,26 +139,26 @@ lemma root_add_nsmul_mem_range_iff_le_chainTopCoeff {n : ℕ} : P.root j + n • P.root i ∈ range P.root ↔ n ≤ P.chainTopCoeff i j := by set S : Set ℤ := {z | P.root j + z • P.root i ∈ range P.root} with S_def suffices (n : ℤ) ∈ S ↔ n ≤ P.chainTopCoeff i j by - simpa only [S_def, mem_setOf_eq, natCast_zsmul] using this + simpa only [S_def, mem_ofPred_eq, natCast_zsmul] using this have aux : P.chainTopCoeff i j = - (P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.2.choose.toNat := by + (P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.2.choose.toNat := by simp [chainTopCoeff, h] obtain ⟨hp, h₂ : S = _⟩ := - (P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.2.choose_spec + (P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.2.choose_spec rw [aux, h₂, mem_Icc] - have := (P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.1 + have := (P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec.1 lia lemma root_sub_nsmul_mem_range_iff_le_chainBotCoeff {n : ℕ} : P.root j - n • P.root i ∈ range P.root ↔ n ≤ P.chainBotCoeff i j := by set S : Set ℤ := {z | P.root j + z • P.root i ∈ range P.root} with S_def suffices -(n : ℤ) ∈ S ↔ n ≤ P.chainBotCoeff i j by - simpa only [S_def, mem_setOf_eq, neg_smul, natCast_zsmul, ← sub_eq_add_neg] using this + simpa only [S_def, mem_ofPred_eq, neg_smul, natCast_zsmul, ← sub_eq_add_neg] using this have aux : P.chainBotCoeff i j = - (-(P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose).toNat := by + (-(P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose).toNat := by simp [chainBotCoeff, h] obtain ⟨hq, p, hp, h₂ : S = _⟩ := - (P.setOf_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec + (P.setOfPred_root_add_zsmul_eq_Icc_of_linearIndependent h).choose_spec rw [aux, h₂, mem_Icc] lia @@ -192,15 +196,21 @@ lemma root_sub_zsmul_mem_range_iff {z : ℤ} : rw [sub_eq_add_neg, ← neg_smul, P.root_add_zsmul_mem_range_iff h, mem_Icc, mem_Icc] grind -lemma setOf_root_add_zsmul_mem_eq_Icc : +lemma setOfPred_root_add_zsmul_mem_eq_Icc : {k : ℤ | P.root j + k • P.root i ∈ range P.root} = Icc (-P.chainBotCoeff i j : ℤ) (P.chainTopCoeff i j) := by ext; simp [← P.root_add_zsmul_mem_range_iff h] -lemma setOf_root_sub_zsmul_mem_eq_Icc : +@[deprecated (since := "2026-07-09")] +alias setOf_root_add_zsmul_mem_eq_Icc := setOfPred_root_add_zsmul_mem_eq_Icc + +lemma setOfPred_root_sub_zsmul_mem_eq_Icc : {k : ℤ | P.root j - k • P.root i ∈ range P.root} = Icc (-P.chainTopCoeff i j : ℤ) (P.chainBotCoeff i j) := by - ext; rw [← root_sub_zsmul_mem_range_iff h, mem_setOf_eq] + ext; rw [← root_sub_zsmul_mem_range_iff h, mem_ofPred_eq] + +@[deprecated (since := "2026-07-09")] +alias setOf_root_sub_zsmul_mem_eq_Icc := setOfPred_root_sub_zsmul_mem_eq_Icc lemma chainTopCoeff_eq_sSup : P.chainTopCoeff i j = sSup {k | P.root j + k • P.root i ∈ range P.root} := by @@ -212,12 +222,12 @@ lemma chainBotCoeff_eq_sSup : lemma coe_chainTopCoeff_eq_sSup : P.chainTopCoeff i j = sSup {k : ℤ | P.root j + k • P.root i ∈ range P.root} := by - rw [setOf_root_add_zsmul_mem_eq_Icc h] + rw [setOfPred_root_add_zsmul_mem_eq_Icc h] simp lemma coe_chainBotCoeff_eq_sSup : P.chainBotCoeff i j = sSup {k : ℤ | P.root j - k • P.root i ∈ range P.root} := by - rw [setOf_root_sub_zsmul_mem_eq_Icc h] + rw [setOfPred_root_sub_zsmul_mem_eq_Icc h] simp omit h @@ -304,7 +314,7 @@ lemma chainBotCoeff_eq_zero_iff : have : P.chainBotCoeff i j = 0 ↔ Iic (P.chainBotCoeff i j) = {0} := by simpa [Set.ext_iff, mem_Iic, mem_singleton_iff] using ⟨fun h ↦ by simp [h], fun h ↦ by rw [← h]⟩ simp only [h, not_true_eq_false, false_or, this, Iic_chainBotCoeff_eq h, Set.ext_iff, - mem_setOf_eq, mem_singleton_iff] + mem_ofPred_eq, mem_singleton_iff] refine ⟨fun h' ↦ by simpa using h' 1, fun h' n ↦ ⟨fun h'' ↦ ?_, fun h'' ↦ by simp [h'']⟩⟩ replace h' : 1 ∉ {k | P.root j - k • P.root i ∈ range P.root} := by simpa using h' rw [← Iic_chainBotCoeff_eq h, mem_Iic, not_le, Nat.lt_one_iff] at h' @@ -329,7 +339,7 @@ lemma chainBotCoeff_of_add {k : ι} (hk : P.root k = P.root j + P.root i) : OrderIso.addRight 1 '' {n | P.root j - n • P.root i ∈ range P.root} := by simp [this, sub_eq_add_neg] have bdd : BddAbove {z : ℤ | P.root j - z • P.root i ∈ range P.root} := by - rw [setOf_root_sub_zsmul_mem_eq_Icc h] + rw [setOfPred_root_sub_zsmul_mem_eq_Icc h] exact bddAbove_Icc rw [this, ← OrderIso.map_csSup' _ ⟨0, by simp⟩ bdd, OrderIso.addRight_apply] @@ -433,10 +443,10 @@ lemma chainCoeff_chainTopIdx_aux : have hS₁₂ : S₂ = (fun z ↦ (-P.chainTopCoeff i j : ℤ) + z) '' S₁ := by ext; simp [S₁_def, S₂_def, root_chainTopIdx, add_smul, add_assoc, natCast_zsmul] have hS₁ : S₁ = Icc (-P.chainBotCoeff i j : ℤ) (P.chainTopCoeff i j) := by - ext; rw [S₁_def, mem_setOf_eq, root_add_zsmul_mem_range_iff h] + ext; rw [S₁_def, mem_ofPred_eq, root_add_zsmul_mem_range_iff h] have hS₂ : S₂ = Icc (-P.chainBotCoeff i (P.chainTopIdx i j) : ℤ) (P.chainTopCoeff i (P.chainTopIdx i j)) := by - ext; rw [S₂_def, mem_setOf_eq, root_add_zsmul_mem_range_iff h'] + ext; rw [S₂_def, mem_ofPred_eq, root_add_zsmul_mem_range_iff h'] rw [hS₁, hS₂, image_const_add_Icc, neg_add_cancel, Icc_eq_Icc_iff (by simp), neg_eq_iff_eq_neg, neg_add_rev, neg_neg, neg_neg] at hS₁₂ norm_cast at hS₁₂ diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean index 34442361bfc523..5e1faecae227d9 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/G2.lean @@ -587,7 +587,7 @@ lemma card_index_eq_twelve : rw [← this] exact Nat.card_congr <| indexEquivAllRoots P -lemma setOf_index_eq_univ : +lemma setOfPred_index_eq_univ : letI _i := P.indexNeg { long P, -long P, short P, -short P, @@ -597,6 +597,8 @@ lemma setOf_index_eq_univ : threeShortAddTwoLong P, -threeShortAddTwoLong P } = univ := eq_univ_iff_forall.mpr fun i ↦ by simpa using mem_allRoots P i +@[deprecated (since := "2026-07-09")] alias setOf_index_eq_univ := setOfPred_index_eq_univ + end IsIrreducible end EmbeddedG2 diff --git a/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean b/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean index db9d53ee6aad0c..4b907386c113de 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Irreducible.lean @@ -219,7 +219,7 @@ lemma exist_set_root_not_disjoint_and_le_ker_coroot'_of_invtSubmodule (hq : ∀ i, q ∈ invtSubmodule (P.reflection i)) : ∃ Φ : Set ι, (∀ i ∈ Φ, ¬ Disjoint q (R ∙ P.root i)) ∧ (∀ i ∉ Φ, q ≤ ker (P.coroot' i)) := by refine ⟨{i | ¬ Disjoint q (R ∙ P.root i)}, by simp, fun i hi ↦ ?_⟩ - simp only [mem_setOf_eq, not_not] at hi + simp only [mem_ofPred_eq, not_not] at hi rw [← Submodule.mem_invtSubmodule_reflection_iff (by simp) hi] exact hq i diff --git a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean index cdd8d752ac42f3..6d82bce06ca692 100644 --- a/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean +++ b/Mathlib/LinearAlgebra/RootSystem/OfBilinear.lean @@ -125,7 +125,7 @@ def ofBilinear [IsReflexive R M] (B : M →ₗ[R] M →ₗ[R] R) (hNB : LinearMa { toFun := fun x => IsReflective.coroot B x.2 inj' := by intro x y hxy - simp only [mem_setOf_eq] at hxy -- x* = y* + simp only [mem_ofPred_eq] at hxy -- x* = y* have h1 : ∀ z, IsReflective.coroot B x.2 z = IsReflective.coroot B y.2 z := fun z => congrFun (congrArg DFunLike.coe hxy) z have h2x : ∀ z, B x x * IsReflective.coroot B x.2 z = @@ -163,19 +163,19 @@ def ofBilinear [IsReflexive R M] (B : M →ₗ[R] M →ₗ[R] R) (hNB : LinearMa intro y simp [involutive_reflection (coroot_apply_self B x.2) y] } reflectionPerm_root := by - simp [coe_setOf, Module.reflection_apply] + simp [coe_ofPred, Module.reflection_apply] reflectionPerm_coroot x y := by - simp only [coe_setOf, mem_setOf_eq, Embedding.coeFn_mk, Embedding.subtype_apply, + simp only [coe_ofPred, mem_ofPred_eq, Embedding.coeFn_mk, Embedding.subtype_apply, Dual.eval_apply, Equiv.coe_fn_mk] ext z simp only [sub_apply, smul_apply, smul_eq_mul] refine y.2.1.1 ?_ - simp only [mem_setOf_eq, mul_sub, apply_self_mul_coroot_apply B y.2, ← mul_assoc] + simp only [mem_ofPred_eq, mul_sub, apply_self_mul_coroot_apply B y.2, ← mul_assoc] rw [← isOrthogonal_reflection B x.2 hSB y y, apply_self_mul_coroot_apply, ← hSB.eq z, ← hSB.eq z, RingHom.id_apply, RingHom.id_apply, Module.reflection_apply, map_sub, mul_sub, sub_eq_sub_iff_comm, sub_left_inj] refine x.2.1.1 ?_ - simp only [mem_setOf_eq, map_smul, smul_eq_mul] + simp only [mem_ofPred_eq, map_smul, smul_eq_mul] rw [← mul_assoc _ _ (B z x), ← mul_assoc _ _ (B z x), mul_left_comm, apply_self_mul_coroot_apply B x.2, mul_left_comm (B x x), apply_self_mul_coroot_apply B x.2, ← hSB.eq x y, RingHom.id_apply, ← hSB.eq x z, RingHom.id_apply] diff --git a/Mathlib/LinearAlgebra/Span/Defs.lean b/Mathlib/LinearAlgebra/Span/Defs.lean index 881ec49d436539..451ec1d3bdfbcf 100644 --- a/Mathlib/LinearAlgebra/Span/Defs.lean +++ b/Mathlib/LinearAlgebra/Span/Defs.lean @@ -214,10 +214,12 @@ theorem span_span_coe_preimage : span R (((↑) : span R s → M) ⁻¹' s) = (fun _ _ _ ↦ smul_mem _ _) hx' @[simp] -lemma span_setOf_mem_eq_top : +lemma span_setOfPred_mem_eq_top : span R {x : span R s | (x : M) ∈ s} = ⊤ := span_span_coe_preimage +@[deprecated (since := "2026-07-09")] alias span_setOf_mem_eq_top := span_setOfPred_mem_eq_top + theorem span_nat_eq_addSubmonoidClosure (s : Set M) : (span ℕ s).toAddSubmonoid = AddSubmonoid.closure s := by refine Eq.symm (AddSubmonoid.closure_eq_of_le subset_span ?_) diff --git a/Mathlib/LinearAlgebra/SymplecticGroup.lean b/Mathlib/LinearAlgebra/SymplecticGroup.lean index b90e068e0c7209..9a817a301ba627 100644 --- a/Mathlib/LinearAlgebra/SymplecticGroup.lean +++ b/Mathlib/LinearAlgebra/SymplecticGroup.lean @@ -101,7 +101,7 @@ variable [Fintype l] def symplecticGroup : Submonoid (Matrix (l ⊕ l) (l ⊕ l) R) where carrier := { A | A * J l R * Aᵀ = J l R } mul_mem' {a b} ha hb := by - simp only [Set.mem_setOf_eq, transpose_mul] at * + simp only [Set.mem_ofPred_eq, transpose_mul] at * rw [← Matrix.mul_assoc, a.mul_assoc, a.mul_assoc, hb] exact ha one_mem' := by simp diff --git a/Mathlib/LinearAlgebra/Transvection/Basic.lean b/Mathlib/LinearAlgebra/Transvection/Basic.lean index b8fae2efc683c1..6fa4b3ef83fdf3 100644 --- a/Mathlib/LinearAlgebra/Transvection/Basic.lean +++ b/Mathlib/LinearAlgebra/Transvection/Basic.lean @@ -349,7 +349,7 @@ theorem dilatransvection.apply {f : Dual R V} {v : V} {h : IsUnit (1 + f v)} {x @[simp] theorem dilatransvection_mem_dilatransvections {f : Dual R V} {v : V} {h : IsUnit (1 + f v)} : dilatransvection h ∈ dilatransvections R V := by - simp only [dilatransvections, Set.mem_setOf_eq] + simp only [dilatransvections, Set.mem_ofPred_eq] refine ⟨f, v, by simp⟩ open scoped Pointwise in @@ -370,14 +370,14 @@ theorem mem_dilatransvections_iff_rank {e : V ≃ₗ[K] V} : Module.rank K (range ((e : V →ₗ[K] V) - LinearMap.id (R := K))) ≤ 1 := by simp only [dilatransvections] constructor - · simp only [Set.mem_setOf_eq] + · simp only [Set.mem_ofPred_eq] rintro ⟨f, v, he⟩ apply le_trans (rank_mono (t := K ∙ v) ?_) · apply le_trans (rank_span_le _) (by simp) rintro _ ⟨x, rfl⟩ simp [mem_span_singleton, he, LinearMap.transvection.apply] · intro he - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] set u := (e : V →ₗ[K] V) - LinearMap.id with hu rw [eq_sub_iff_add_eq] at hu by_cases hr : Module.rank K (range u) = 0 diff --git a/Mathlib/Logic/Embedding/Set.lean b/Mathlib/Logic/Embedding/Set.lean index ab78cd95916d76..22d95ff0d6ced9 100644 --- a/Mathlib/Logic/Embedding/Set.lean +++ b/Mathlib/Logic/Embedding/Set.lean @@ -30,7 +30,7 @@ variable {α : Sort u} {β : Sort v} (f : α ≃ β) @[simp] theorem Equiv.asEmbedding_range {α β : Sort _} {p : β → Prop} (e : α ≃ Subtype p) : - Set.range e.asEmbedding = setOf p := + Set.range e.asEmbedding = Set.ofPred p := Set.ext fun x ↦ ⟨fun ⟨y, h⟩ ↦ h ▸ Subtype.coe_prop (e y), fun hs ↦ ⟨e.symm ⟨x, hs⟩, by simp⟩⟩ end Equiv diff --git a/Mathlib/Logic/Encodable/Basic.lean b/Mathlib/Logic/Encodable/Basic.lean index 3387a71bde9395..1d367e6a4f5cd6 100644 --- a/Mathlib/Logic/Encodable/Basic.lean +++ b/Mathlib/Logic/Encodable/Basic.lean @@ -193,7 +193,7 @@ theorem decode₂_encode [Encodable α] (a : α) : decode₂ α (encode a) = som theorem decode₂_ne_none_iff [Encodable α] {n : ℕ} : decode₂ α n ≠ none ↔ n ∈ Set.range (encode : α → ℕ) := by - simp_rw [Set.range, Set.mem_setOf_eq, Ne, Option.eq_none_iff_forall_not_mem, + simp_rw [Set.range, Set.mem_ofPred_eq, Ne, Option.eq_none_iff_forall_not_mem, Encodable.mem_decode₂, not_forall, not_not] theorem decode₂_isPartialInv [Encodable α] : IsPartialInv encode (decode₂ α) := fun _ _ => diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index 8989b173d1a22f..7668c425ab9e4e 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -117,9 +117,12 @@ theorem preimage_eq_iff_eq_image {α β} (e : α ≃ β) (s t) : e ⁻¹' s = t theorem eq_preimage_iff_image_eq {α β} (e : α ≃ β) (s t) : s = e ⁻¹' t ↔ e '' s = t := Set.eq_preimage_iff_image_eq e.bijective -lemma setOf_apply_symm_eq_image_setOf {α β} (e : α ≃ β) (p : α → Prop) : +lemma setOfPred_apply_symm_eq_image_setOfPred {α β} (e : α ≃ β) (p : α → Prop) : {b | p (e.symm b)} = e '' {a | p a} := by - rw [Equiv.image_eq_preimage_symm, preimage_setOf_eq] + rw [Equiv.image_eq_preimage_symm, preimage_ofPred_eq] + +@[deprecated (since := "2026-07-09")] +alias setOf_apply_symm_eq_image_setOf := setOfPred_apply_symm_eq_image_setOfPred @[simp] theorem prod_assoc_preimage {α β γ} {s : Set α} {t : Set β} {u : Set γ} : diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index 1167b2f498e1c0..b1567b6a84d713 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -251,7 +251,7 @@ theorem IsGδ.measurableSet (h : IsGδ s) : MeasurableSet s := by theorem measurableSet_of_continuousAt {β} [PseudoEMetricSpace β] (f : α → β) : MeasurableSet { x | ContinuousAt f x } := - (IsGδ.setOf_continuousAt f).measurableSet + (IsGδ.setOfPred_continuousAt f).measurableSet theorem IsClosed.measurableSet (h : IsClosed s) : MeasurableSet s := h.isOpen_compl.measurableSet.of_compl @@ -379,7 +379,7 @@ instance Pi.opensMeasurableSpace_of_subsingleton {ι : Type*} {X : ι → Type*} rw [borel, MeasurableSpace.pi, ciSup_unique] refine MeasurableSpace.generateFrom_le fun s hs ↦ MeasurableSpace.measurableSet_comap.2 ?_ simp +instances only [Pi.topologicalSpace, ciInf_unique, isOpen_induced_eq, Set.mem_image, - Set.mem_setOf_eq] at hs + Set.mem_ofPred_eq] at hs obtain ⟨t, ht, rfl⟩ := hs exact ⟨t, ht.measurableSet, rfl⟩ diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index 1bc877ce80b251..62d08038e1fecf 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -166,7 +166,7 @@ theorem measurableSet_le' : MeasurableSet { p : α × α | p.1 ≤ p.2 } := @[fun_prop] theorem measurable_le : Measurable fun p : α × α => p.1 ≤ p.2 := - measurableSet_setOf.mp measurableSet_le' + measurableSet_setOfPred.mp measurableSet_le' theorem measurableSet_le {f g : δ → α} (hf : Measurable f) (hg : Measurable g) : MeasurableSet { a | f a ≤ g a } := @@ -239,7 +239,7 @@ theorem measurableSet_lt' [SecondCountableTopology α] [OrderClosedTopology α] @[fun_prop] theorem measurable_lt [SecondCountableTopology α] [OrderClosedTopology α] : Measurable fun p : α × α => p.1 < p.2 := - measurableSet_setOf.mp measurableSet_lt' + measurableSet_setOfPred.mp measurableSet_lt' theorem measurableSet_lt [SecondCountableTopology α] [OrderClosedTopology α] {f g : δ → α} (hf : Measurable f) (hg : Measurable g) : @@ -475,7 +475,7 @@ theorem ext_of_Ico' {α : Type*} [TopologicalSpace α] {m : MeasurableSpace α} rcases exists_countable_dense_bot_top α with ⟨s, hsc, hsd, hsb, _⟩ have : (⋃ (l ∈ s) (u ∈ s) (_ : l < u), {Ico l u} : Set (Set α)).Countable := hsc.biUnion fun l _ => hsc.biUnion fun u _ => countable_iUnion fun _ => countable_singleton _ - simp only [← setOf_eq_eq_singleton, ← setOf_exists] at this + simp only [← ofPred_eq_eq_singleton, ← ofPred_exists] at this refine Measure.ext_of_generateFrom_of_cover_subset (BorelSpace.measurable_eq.trans (borel_eq_generateFrom_Ico α)) (isPiSystem_Ico id id) ?_ this @@ -548,7 +548,7 @@ theorem ext_of_Icc' {α : Type*} [TopologicalSpace α] {m : MeasurableSpace α} rcases exists_countable_dense_bot_top α with ⟨s, hsc, hsd, hsb, hst⟩ have : (⋃ (l ∈ s) (u ∈ s) (_ : l ≤ u), {Icc l u} : Set (Set α)).Countable := hsc.biUnion fun l _ => hsc.biUnion fun u _ => countable_iUnion fun _ => countable_singleton _ - simp only [← setOf_eq_eq_singleton, ← setOf_exists] at this + simp only [← ofPred_eq_eq_singleton, ← ofPred_exists] at this refine Measure.ext_of_generateFrom_of_cover_subset (BorelSpace.measurable_eq.trans (borel_eq_generateFrom_Icc α)) (isPiSystem_Icc id id) ?_ this @@ -704,7 +704,7 @@ theorem Measurable.isLUB {ι} [Countable ι] {f : ι → δ → α} {g : δ → rw [‹BorelSpace α›.measurable_eq, borel_eq_generateFrom_Ioi α] apply measurable_generateFrom rintro _ ⟨a, rfl⟩ - simp_rw [Set.preimage, mem_Ioi, lt_isLUB_iff (hg _), exists_range_iff, setOf_exists] + simp_rw [Set.preimage, mem_Ioi, lt_isLUB_iff (hg _), exists_range_iff, ofPred_exists] exact MeasurableSet.iUnion fun i => hf i (isOpen_lt' _).measurableSet /-- If a function is the least upper bound of countably many measurable functions on a measurable @@ -747,7 +747,7 @@ theorem AEMeasurable.isLUB {ι} {μ : Measure δ} [Countable ι] {f : ι → δ nontriviality α have hα : Nonempty α := inferInstance rcases isEmpty_or_nonempty ι with hι | hι - · simp only [IsEmpty.exists_iff, setOf_false, isLUB_empty_iff] at hg + · simp only [IsEmpty.exists_iff, ofPred_false, isLUB_empty_iff] at hg exact aemeasurable_const' (hg.mono fun a ha => hg.mono fun b hb => (ha _).antisymm (hb _)) let p : δ → (ι → α) → Prop := fun x f' => IsLUB { a | ∃ i, f' i = a } (g x) let g_seq := (aeSeqSet hf p).piecewise g fun _ => hα.some @@ -758,7 +758,7 @@ theorem AEMeasurable.isLUB {ι} {μ : Measure δ} [Countable ι] {f : ι → δ · have h_set_eq : { a : α | ∃ i : ι, (hf i).mk (f i) b = a } = { a : α | ∃ i : ι, f i b = a } := by ext x - simp_rw [Set.mem_setOf_eq, aeSeq.mk_eq_fun_of_mem_aeSeqSet hf h] + simp_rw [Set.mem_ofPred_eq, aeSeq.mk_eq_fun_of_mem_aeSeqSet hf h] rw [h_set_eq] exact aeSeq.fun_prop_of_mem_aeSeqSet hf h · exact IsGreatest.isLUB ⟨(@exists_const (hα.some = hα.some) ι _).2 rfl, fun x ⟨i, hi⟩ => hi.ge⟩ @@ -857,7 +857,7 @@ lemma measurableSet_bddAbove_range {ι} [Countable ι] {f : ι → δ → α} (h exact measurableSet_le (hf i) measurable_const have B : ∀ (c : α), MeasurableSet {x | ∀ i, f i x ≤ c} := by intro c - rw [setOf_forall] + rw [ofPred_forall] exact MeasurableSet.iInter (fun i ↦ A i c) obtain ⟨u, hu⟩ : ∃ (u : ℕ → α), Tendsto u atTop atTop := exists_seq_tendsto (atTop : Filter α) have : {b | BddAbove (range (fun i ↦ f i b))} = {x | ∃ n, ∀ i, f i x ≤ u n} := by @@ -869,7 +869,7 @@ lemma measurableSet_bddAbove_range {ι} [Countable ι] {f : ι → δ → α} (h refine ⟨u n, ?_⟩ rintro - ⟨i, rfl⟩ exact hn i - rw [this, setOf_exists] + rw [this, ofPred_exists] exact MeasurableSet.iUnion (fun n ↦ B (u n)) lemma measurableSet_bddBelow_range {ι} [Countable ι] {f : ι → δ → α} (hf : ∀ i, Measurable (f i)) : @@ -1015,7 +1015,7 @@ theorem Measurable.liminf' {ι ι'} {f : ι → δ → α} {v : Filter ι} (hf : have m_meas : ∀ j, MeasurableSet (m j) := fun j ↦ measurableSet_bddBelow_range (fun (i : s j) ↦ hf i) have mc_meas : MeasurableSet {x | ∀ (j : Subtype p), x ∉ m j} := by - rw [setOf_forall] + rw [ofPred_forall] exact MeasurableSet.iInter (fun j ↦ (m_meas j).compl) refine measurable_const.piecewise mc_meas <| .iSup fun j ↦ ?_ let reparam : δ → Subtype p → Subtype p := fun x ↦ liminf_reparam (fun i ↦ f i x) s p diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean index ef30b4946bc384..6baf1dc30f9a44 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean @@ -551,7 +551,7 @@ theorem exists_spanning_measurableSet_le {f : α → ℝ≥0} (hf : Measurable f · have : ⋃ i, sigma_finite_sets i ∩ norm_sets i = (⋃ i, sigma_finite_sets i) ∩ ⋃ i, norm_sets i := by refine Set.iUnion_inter_of_monotone (monotone_spanningSets μ) fun i j hij x => ?_ - simp only [norm_sets, Set.mem_setOf_eq] + simp only [norm_sets, Set.mem_ofPred_eq] refine fun hif => hif.trans ?_ exact mod_cast hij rw [this, norm_sets_spanning, iUnion_spanningSets μ, Set.inter_univ] diff --git a/Mathlib/MeasureTheory/Constructions/Cylinders.lean b/Mathlib/MeasureTheory/Constructions/Cylinders.lean index 4b4200b0564466..4ca7312a2cb5c5 100644 --- a/Mathlib/MeasureTheory/Constructions/Cylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/Cylinders.lean @@ -62,7 +62,7 @@ def squareCylinders (C : ∀ i, Set (Set (α i))) : Set (Set (∀ i, α i)) := theorem squareCylinders_eq_iUnion_image (C : ∀ i, Set (Set (α i))) : squareCylinders C = ⋃ s : Finset ι, (fun t ↦ (s : Set ι).pi t) '' univ.pi C := by ext1 f - simp only [squareCylinders, mem_iUnion, mem_image, mem_univ_pi, mem_setOf_eq, + simp only [squareCylinders, mem_iUnion, mem_image, mem_univ_pi, mem_ofPred_eq, eq_comm (a := f)] theorem isPiSystem_squareCylinders {C : ∀ i, Set (Set (α i))} (hC : ∀ i, IsPiSystem (C i)) @@ -117,7 +117,7 @@ theorem comap_eval_le_generateFrom_squareCylinders_singleton simp only [singleton_pi] rw [MeasurableSpace.comap_eq_generateFrom] refine MeasurableSpace.generateFrom_mono fun S ↦ ?_ - simp only [mem_setOf_eq, mem_image, mem_univ_pi, forall_exists_index, and_imp] + simp only [mem_ofPred_eq, mem_image, mem_univ_pi, forall_exists_index, and_imp] intro t ht h classical refine ⟨fun j ↦ if hji : j = i then by convert! t else univ, fun j ↦ ?_, ?_⟩ @@ -139,7 +139,7 @@ theorem generateFrom_squareCylinders [∀ i, MeasurableSpace (α i)] : apply le_antisymm · rw [MeasurableSpace.generateFrom_le_iff] rintro S ⟨s, t, h, rfl⟩ - simp only [mem_univ_pi, mem_setOf_eq] at h + simp only [mem_univ_pi, mem_ofPred_eq] at h exact MeasurableSet.pi (Finset.countable_toSet _) (fun i _ ↦ h i) · refine iSup_le fun i ↦ ?_ refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_ @@ -147,7 +147,7 @@ theorem generateFrom_squareCylinders [∀ i, MeasurableSpace (α i)] : rw [← Finset.coe_singleton, squareCylinders_eq_iUnion_image] exact subset_iUnion (fun (s : Finset ι) ↦ - (fun t : ∀ i, Set (α i) ↦ (s : Set ι).pi t) '' univ.pi (fun i ↦ setOf MeasurableSet)) + (fun t : ∀ i, Set (α i) ↦ (s : Set ι).pi t) '' univ.pi (fun i ↦ Set.ofPred MeasurableSet)) ({i} : Finset ι) end squareCylinders @@ -366,12 +366,12 @@ theorem generateFrom_measurableCylinders : · refine iSup_le fun i ↦ ?_ refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_ refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_) - simp only [singleton_pi, mem_image, mem_pi, mem_univ, mem_setOf_eq, + simp only [singleton_pi, mem_image, mem_pi, mem_univ, mem_ofPred_eq, forall_true_left, mem_measurableCylinders, forall_exists_index, and_imp] rintro t ht rfl refine ⟨{i}, {f | f ⟨i, Finset.mem_singleton_self i⟩ ∈ t i}, measurable_pi_apply _ (ht i), ?_⟩ ext1 x - simp only [mem_preimage, Function.eval, mem_cylinder, mem_setOf_eq, Finset.restrict] + simp only [mem_preimage, Function.eval, mem_cylinder, mem_ofPred_eq, Finset.restrict] /-- The cylinders of a product space indexed by `ℕ` can be seen as depending on the first coordinates. -/ diff --git a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean index 63ebf1c46e112e..88741fd12812cf 100644 --- a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean +++ b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean @@ -224,7 +224,7 @@ theorem toSphereBallBound_mul_measure_unitBall_le_toSphere_ball {ε : ℝ} using this (ε := min ε 2) (by simp [hε]) (by simp) · gcongr simp - rw [μ.toSphere_apply' measurableSet_ball, Subtype.image_ball, setOf_mem_eq] + rw [μ.toSphere_apply' measurableSet_ball, Subtype.image_ball, ofPred_mem_eq] grw [← ball_subset_sector_of_small_epsilon] <;> try assumption · have hdim : Module.finrank ℝ E ≠ 0 := Module.finrank_pos.ne' have : min (ENNReal.ofReal ε) 2 = ENNReal.ofReal ε := by simpa diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index fe727029a7cca7..9aeeed20ad7d75 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -928,7 +928,7 @@ theorem MeasurableSet.image_of_monotoneOn_of_continuousOn Therefore, we need to remove the points where the map is not injective. There are only countably many points that have several preimages, so this set is also measurable. -/ let u : Set β := {c | ∃ x, ∃ y, x ∈ t ∧ y ∈ t ∧ x < y ∧ g x = c ∧ g y = c} - have hu : Set.Countable u := MonotoneOn.countable_setOf_two_preimages hg + have hu : Set.Countable u := MonotoneOn.countable_setOfPred_two_preimages hg let t' := t ∩ g ⁻¹' u have ht' : MeasurableSet t' := by have : t' = ⋃ c ∈ u, t ∩ g ⁻¹' {c} := by ext; simp [t'] @@ -961,14 +961,14 @@ theorem MeasurableSet.image_of_monotoneOn [SecondCountableTopology β] rw [← image_union] congr! ext - simp only [sdiff_sep_self, not_not, mem_union, mem_setOf_eq, t'] + simp only [sdiff_sep_self, not_not, mem_union, mem_ofPred_eq, t'] tauto rw [this] apply MeasurableSet.union _ (ht'.image g).measurableSet apply MeasurableSet.image_of_monotoneOn_of_continuousOn (ht.diff ht'.measurableSet) (hg.mono sdiff_subset) intro x hx - simp only [sdiff_sep_self, not_not, mem_setOf_eq, t'] at hx + simp only [sdiff_sep_self, not_not, mem_ofPred_eq, t'] at hx exact hx.2.mono sdiff_subset /-- The image of a measurable set under an antitone map is measurable. -/ @@ -1008,11 +1008,11 @@ theorem MeasureTheory.measurableSet_exists_tendsto [TopologicalSpace γ] ((f · x) '' u n) ×ˢ ((f · x) '' u n) := fun x => (hu.map _).prod (hu.map _) simp_rw [and_iff_right (hl.map _), Filter.HasBasis.le_basis_iff (this _).toHasBasis Metric.uniformity_basis_dist_inv_nat_succ, - Set.setOf_forall] + Set.ofPred_forall] refine MeasurableSet.biInter Set.countable_univ fun K _ => ?_ - simp_rw [Set.setOf_exists, true_and] + simp_rw [Set.ofPred_exists, true_and] refine MeasurableSet.iUnion fun N => ?_ - simp_rw [prod_image_image_eq, image_subset_iff, prod_subset_iff, Set.setOf_forall] + simp_rw [prod_image_image_eq, image_subset_iff, prod_subset_iff, Set.ofPred_forall] exact MeasurableSet.biInter (to_countable (u N)) fun i _ => MeasurableSet.biInter (to_countable (u N)) fun j _ => diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index d76c0537778d51..e44a090dcba719 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -286,7 +286,7 @@ theorem lastStep_nonempty : wlog x_le_y : x ≤ y generalizing x y · exact (this hxy.symm (le_of_not_ge x_le_y)).symm rcases eq_or_lt_of_le x_le_y with (rfl | H); · rfl - simp only [nonempty_def, not_exists, exists_prop, not_and, not_lt, not_le, mem_setOf_eq, + simp only [nonempty_def, not_exists, exists_prop, not_and, not_lt, not_le, mem_ofPred_eq, not_forall] at h specialize h y have A : p.c (p.index y) ∉ p.iUnionUpTo y := by @@ -307,7 +307,7 @@ theorem mem_iUnionUpTo_lastStep (x : β) : p.c x ∈ p.iUnionUpTo p.lastStep := have A : ∀ z : β, p.c z ∈ p.iUnionUpTo p.lastStep ∨ p.τ * p.r z < p.R p.lastStep := by have : p.lastStep ∈ {i | ¬∃ b : β, p.c b ∉ p.iUnionUpTo i ∧ p.R i ≤ p.τ * p.r b} := csInf_mem p.lastStep_nonempty - simpa only [not_exists, mem_setOf_eq, not_and_or, not_le, not_notMem] + simpa only [not_exists, mem_ofPred_eq, not_and_or, not_le, not_notMem] by_contra h rcases A x with (H | H); · exact h H have Rpos : 0 < p.R p.lastStep := by @@ -389,7 +389,7 @@ theorem color_lt {i : Ordinal.{u}} (hi : i < p.lastStep) {N : ℕ} rw [index]; rfl rw [this] have : ∃ t, p.c t ∉ p.iUnionUpTo (G n) ∧ p.R (G n) ≤ p.τ * p.r t := by - simpa only [not_exists, exists_prop, not_and, not_lt, not_le, mem_setOf_eq, not_forall] using + simpa only [not_exists, exists_prop, not_and, not_lt, not_le, mem_ofPred_eq, not_forall] using notMem_of_lt_csInf (G_lt_last n hn) (OrderBot.bddBelow _) exact Classical.epsilon_spec this -- the balls with indices `G k` satisfy the characteristic property of satellite configurations. @@ -570,7 +570,7 @@ theorem exist_finset_disjoint_balls_large_measure (μ : Measure α) [IsFiniteMea intro x hx obtain ⟨i, y, hxy, h'⟩ : ∃ (i : Fin N) (i_1 : ↥s), i_1 ∈ u i ∧ x ∈ ball (↑i_1) (r ↑i_1) := by - have : x ∈ range a.c := by simpa only [a, Subtype.range_coe_subtype, setOf_mem_eq] + have : x ∈ range a.c := by simpa only [a, Subtype.range_coe_subtype, ofPred_mem_eq] simpa only [mem_iUnion, bex_def] using hu' this refine mem_iUnion.2 ⟨i, ⟨hx, ?_⟩⟩ simp only [v, exists_prop, mem_iUnion, SetCoe.exists, exists_and_right] @@ -945,7 +945,7 @@ theorem exists_closedBall_covering_tsum_measure_le (μ : Measure α) [SFinite μ · obtain ⟨i, y, ySi, xy⟩ : ∃ (i : Fin N) (y : ↥s'), y ∈ S i ∧ x ∈ ball (y : α) (r1 y) := by have A : x ∈ range q.c := by simpa only [q, not_exists, exists_prop, mem_iUnion, mem_closedBall, not_and, - not_le, mem_setOf_eq, Subtype.range_coe_subtype, Set.mem_sdiff] using h'x + not_le, mem_ofPred_eq, Subtype.range_coe_subtype, Set.mem_sdiff] using h'x simpa only [mem_iUnion, mem_image, bex_def] using hS A refine mem_iUnion₂.2 ⟨y, Or.inr ?_, ?_⟩ · simp only [mem_iUnion, mem_image] diff --git a/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean b/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean index 2d53c3ab68fcff..30036d8b034b08 100644 --- a/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean +++ b/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean @@ -160,7 +160,7 @@ theorem card_le_multiplicity {s : Finset E} (hs : ∀ c ∈ s, ‖c‖ ≤ 2) · refine ⟨5 ^ finrank ℝ E, ?_⟩ rintro _ ⟨s, ⟨rfl, h⟩⟩ exact Besicovitch.card_le_of_separated s h.1 h.2 - · simp only [mem_setOf_eq, Ne] + · simp only [mem_ofPred_eq, Ne] exact ⟨s, rfl, hs, h's⟩ variable (E) diff --git a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean index f1e975f25ca496..c7b88a5764cad5 100644 --- a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean +++ b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean @@ -71,7 +71,7 @@ contain all balls `closedBall y r` when `dist x y ≤ K * r`. -/ theorem closedBall_mem_vitaliFamily_of_dist_le_mul {K : ℝ} {x y : α} {r : ℝ} (h : dist x y ≤ K * r) (rpos : 0 < r) : closedBall y r ∈ (vitaliFamily μ K).setsAt x := by let R := scalingScaleOf μ (max (4 * K + 3) 3) - simp only [vitaliFamily, VitaliFamily.enlarge, Vitali.vitaliFamily, mem_union, mem_setOf_eq, + simp only [vitaliFamily, VitaliFamily.enlarge, Vitali.vitaliFamily, mem_union, mem_ofPred_eq, isClosed_closedBall, true_and, (nonempty_ball.2 rpos).mono ball_subset_interior_closedBall, measurableSet_closedBall] /- The measure is doubling on scales smaller than `R`. Therefore, we treat differently small diff --git a/Mathlib/MeasureTheory/Covering/Differentiation.lean b/Mathlib/MeasureTheory/Covering/Differentiation.lean index d766c48e2e1982..a8b46385bf0cd0 100644 --- a/Mathlib/MeasureTheory/Covering/Differentiation.lean +++ b/Mathlib/MeasureTheory/Covering/Differentiation.lean @@ -103,7 +103,7 @@ theorem ae_eventually_measure_pos [SecondCountableTopology α] : have h : v.FineSubfamilyOn f s := by intro x hx ε εpos rw [hs] at hx - simp only [frequently_filterAt_iff, gt_iff_lt, mem_setOf_eq] at hx + simp only [frequently_filterAt_iff, gt_iff_lt, mem_ofPred_eq] at hx rcases hx ε εpos with ⟨a, a_sets, ax, μa⟩ exact ⟨a, ⟨a_sets, μa⟩, ax⟩ refine le_antisymm ?_ bot_le @@ -183,7 +183,7 @@ theorem ae_eventually_measure_zero_of_singular (hρ : ρ ⟂ₘ μ) : refine v.measure_le_of_frequently_le ρ smul_absolutelyContinuous _ ?_ intro x hx rw [hs] at hx - simp only [mem_inter_iff, not_lt, not_eventually, mem_setOf_eq] at hx + simp only [mem_inter_iff, not_lt, not_eventually, mem_ofPred_eq] at hx exact hx.1 _ ≤ (ε : ℝ≥0∞)⁻¹ * ρ o := by gcongr; apply inter_subset_right _ = 0 := by rw [ρo, mul_zero] @@ -239,13 +239,13 @@ theorem ae_tendsto_div : ∀ᵐ x ∂μ, ∃ c, Tendsto (fun a => ρ a / μ a) ( lift d to ℝ≥0 using I d hd apply v.null_of_frequently_le_of_frequently_ge hρ (ENNReal.coe_lt_coe.1 hcd) · simp only [and_imp, exists_prop, not_frequently, not_and, not_lt, not_le, not_eventually, - mem_setOf_eq, mem_compl_iff, not_forall] + mem_ofPred_eq, mem_compl_iff, not_forall] intro x h1x _ apply h1x.mono fun a ha => ?_ refine (ENNReal.div_le_iff_le_mul ?_ (Or.inr (bot_le.trans_lt ha).ne')).1 ha.le simp only [ENNReal.coe_ne_top, Ne, or_true, not_false_iff] · simp only [and_imp, exists_prop, not_frequently, not_and, not_lt, not_le, not_eventually, - mem_setOf_eq, mem_compl_iff, not_forall] + mem_ofPred_eq, mem_compl_iff, not_forall] intro x _ h2x apply h2x.mono fun a ha => ?_ exact ENNReal.mul_le_of_le_div ha.le @@ -479,7 +479,7 @@ theorem measure_limRatioMeas_top : μ {x | v.limRatioMeas hρ x = ∞} = 0 := by · apply v.mul_measure_le_of_subset_lt_limRatioMeas hρ intro y hy have : v.limRatioMeas hρ y = ∞ := hy.1 - simp only [this, ENNReal.coe_lt_top, mem_setOf_eq] + simp only [this, ENNReal.coe_lt_top, mem_ofPred_eq] · simp only [(zero_lt_one.trans_le hq).ne', true_or, ENNReal.coe_eq_zero, Ne, not_false_iff] have B : Tendsto (fun q : ℝ≥0 => (q : ℝ≥0∞)⁻¹ * ρ s) atTop (𝓝 (∞⁻¹ * ρ s)) := by @@ -502,7 +502,7 @@ theorem measure_limRatioMeas_zero : ρ (v.limRatioMeas hρ ⁻¹' {0}) = 0 := by apply v.measure_le_mul_of_subset_limRatioMeas_lt hρ intro y hy have : v.limRatioMeas hρ y = 0 := hy.1 - simp only [this, mem_setOf_eq, hq, ENNReal.coe_pos] + simp only [this, mem_ofPred_eq, hq, ENNReal.coe_pos] have B : Tendsto (fun q : ℝ≥0 => (q : ℝ≥0∞) * μ s) (𝓝[>] (0 : ℝ≥0)) (𝓝 ((0 : ℝ≥0) * μ s)) := by apply ENNReal.Tendsto.mul_const _ (Or.inr μs) rw [ENNReal.tendsto_coe] diff --git a/Mathlib/MeasureTheory/Covering/Vitali.lean b/Mathlib/MeasureTheory/Covering/Vitali.lean index e14e5573397922..fa438251fc24f8 100644 --- a/Mathlib/MeasureTheory/Covering/Vitali.lean +++ b/Mathlib/MeasureTheory/Covering/Vitali.lean @@ -81,7 +81,7 @@ theorem exists_disjoint_subfamily_covering_enlargement (B : ι → Set α) (t : refine zorn_subset _ fun U UT hU => ?_ refine ⟨⋃₀ U, ?_, fun s hs => subset_sUnion_of_mem hs⟩ simp only [T, Set.sUnion_subset_iff, and_imp, forall_exists_index, mem_sUnion, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] refine ⟨fun u hu => (UT hu).1, (pairwiseDisjoint_sUnion hU.directedOn).2 fun u hu => (UT hu).2.1, fun a hat b u uU hbu hab => ?_⟩ diff --git a/Mathlib/MeasureTheory/Covering/VitaliFamily.lean b/Mathlib/MeasureTheory/Covering/VitaliFamily.lean index 23e8f94328afe5..90dd8d165969ca 100644 --- a/Mathlib/MeasureTheory/Covering/VitaliFamily.lean +++ b/Mathlib/MeasureTheory/Covering/VitaliFamily.lean @@ -209,7 +209,7 @@ def filterAt (x : X) : Filter (Set X) := (𝓝 x).smallSets ⊓ 𝓟 (v.setsAt x theorem _root_.Filter.HasBasis.vitaliFamily {ι : Sort*} {p : ι → Prop} {s : ι → Set X} {x : X} (h : (𝓝 x).HasBasis p s) : (v.filterAt x).HasBasis p (fun i ↦ {t ∈ v.setsAt x | t ⊆ s i}) := by - simpa only [← Set.setOf_inter_eq_sep] using! h.smallSets.inf_principal _ + simpa only [← Set.ofPred_inter_eq_sep] using! h.smallSets.inf_principal _ theorem filterAt_basis_closedBall (x : X) : (v.filterAt x).HasBasis (0 < ·) ({t ∈ v.setsAt x | t ⊆ closedBall x ·}) := @@ -217,7 +217,7 @@ theorem filterAt_basis_closedBall (x : X) : theorem mem_filterAt_iff {x : X} {s : Set (Set X)} : s ∈ v.filterAt x ↔ ∃ ε > (0 : ℝ), ∀ t ∈ v.setsAt x, t ⊆ closedBall x ε → t ∈ s := by - simp only [(v.filterAt_basis_closedBall x).mem_iff, ← and_imp, subset_def, mem_setOf] + simp only [(v.filterAt_basis_closedBall x).mem_iff, ← and_imp, subset_def, mem_ofPred] instance filterAt_neBot (x : X) : (v.filterAt x).NeBot := (v.filterAt_basis_closedBall x).neBot_iff.2 <| v.nontrivial _ _ @@ -244,7 +244,7 @@ theorem eventually_filterAt_measurableSet (x : X) : ∀ᶠ t in v.filterAt x, Me theorem frequently_filterAt_iff {x : X} {P : Set X → Prop} : (∃ᶠ t in v.filterAt x, P t) ↔ ∀ ε > (0 : ℝ), ∃ t ∈ v.setsAt x, t ⊆ closedBall x ε ∧ P t := by - simp only [(v.filterAt_basis_closedBall x).frequently_iff, ← and_assoc, subset_def, mem_setOf] + simp only [(v.filterAt_basis_closedBall x).frequently_iff, ← and_assoc, subset_def, mem_ofPred] theorem eventually_filterAt_subset_of_nhds {x : X} {o : Set X} (hx : o ∈ 𝓝 x) : ∀ᶠ t in v.filterAt x, t ⊆ o := diff --git a/Mathlib/MeasureTheory/Function/AEEqOfLIntegral.lean b/Mathlib/MeasureTheory/Function/AEEqOfLIntegral.lean index 08a6152b377272..5cb80314e9b013 100644 --- a/Mathlib/MeasureTheory/Function/AEEqOfLIntegral.lean +++ b/Mathlib/MeasureTheory/Function/AEEqOfLIntegral.lean @@ -81,7 +81,7 @@ theorem ae_le_of_forall_setLIntegral_le_of_sigmaFinite₀ [SigmaFinite μ] have μs : ∀ n, μ (s n) = 0 := fun n => A _ _ _ (u_pos n) have B : {x | f x ≤ g x}ᶜ ⊆ ⋃ n, s n := by intro x hx - simp only [Set.mem_compl_iff, Set.mem_setOf, not_le] at hx + simp only [Set.mem_compl_iff, Set.mem_ofPred, not_le] at hx have L1 : ∀ᶠ n in atTop, g x + u n ≤ f x := by have : Tendsto (fun n => g x + u n) atTop (𝓝 (g x + (0 : ℝ≥0))) := tendsto_const_nhds.add (ENNReal.tendsto_coe.2 u_lim) diff --git a/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean b/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean index 6d8e1ddff0ba21..ab1b6980def050 100644 --- a/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean +++ b/Mathlib/MeasureTheory/Function/AEMeasurableOrder.lean @@ -77,7 +77,7 @@ theorem MeasureTheory.aemeasurable_of_exist_almost_disjoint_supersets {α : Type change μ _ = 0 convert! this ext y - simp only [mem_setOf_eq, mem_compl_iff, not_notMem] + simp only [mem_ofPred_eq, mem_compl_iff, not_notMem] filter_upwards [this] with x hx apply (iInf_eq_of_forall_ge_of_forall_gt_exists_lt _ _).symm · intro i diff --git a/Mathlib/MeasureTheory/Function/AbsolutelyContinuous.lean b/Mathlib/MeasureTheory/Function/AbsolutelyContinuous.lean index eaecee77b5c49d..5ba2a331eda751 100644 --- a/Mathlib/MeasureTheory/Function/AbsolutelyContinuous.lean +++ b/Mathlib/MeasureTheory/Function/AbsolutelyContinuous.lean @@ -83,7 +83,7 @@ lemma hasBasis_totalLengthFilter : totalLengthFilter.HasBasis (fun (ε : ℝ) => {E : ℕ × (ℕ → X × X) | ∑ i ∈ Finset.range E.1, dist (E.2 i).1 (E.2 i).2 < ε}) := by convert! Filter.HasBasis.comap (α := ℝ) _ (nhds_basis_Ioo_pos _) using 1 ext ε E - simp only [mem_setOf_eq, zero_sub, zero_add, mem_preimage, mem_Ioo, iff_and_self] + simp only [mem_ofPred_eq, zero_sub, zero_add, mem_preimage, mem_Ioo, iff_and_self] suffices 0 ≤ ∑ i ∈ Finset.range E.1, dist (E.2 i).1 (E.2 i).2 by grind exact Finset.sum_nonneg (fun _ _ ↦ dist_nonneg) @@ -105,7 +105,7 @@ lemma disjWithin_mono {a b c d : ℝ} (habcd : uIcc c d ⊆ uIcc a b) : lemma uIoc_subset_of_mem_disjWithin {a b : ℝ} {n : ℕ} {I : ℕ → ℝ × ℝ} (hnI : (n, I) ∈ disjWithin a b) {i : ℕ} (hi : i < n) : uIoc (I i).1 (I i).2 ⊆ uIoc a b := by - simp only [disjWithin, Finset.mem_range, mem_setOf_eq, uIcc, mem_Icc] at hnI + simp only [disjWithin, Finset.mem_range, mem_ofPred_eq, uIcc, mem_Icc] at hnI grind lemma biUnion_uIoc_subset_of_mem_disjWithin {a b : ℝ} {n : ℕ} {I : ℕ → ℝ × ℝ} @@ -233,8 +233,8 @@ theorem uniformContinuousOn (hf : AbsolutelyContinuousOnInterval f a b) : · simp only [comap_inf, comap_principal] congr ext p - simp only [disjWithin, Finset.mem_range, preimage_setOf_eq, Nat.lt_one_iff, - forall_eq, mem_setOf_eq, mem_prod] + simp only [disjWithin, Finset.mem_range, preimage_ofPred_eq, Nat.lt_one_iff, + forall_eq, mem_ofPred_eq, mem_prod] simp · simp [totalLengthFilter, comap_comap, Function.comp_def] @@ -271,7 +271,7 @@ theorem smul {M : Type*} [SeminormedRing M] [Module M F] [NormSMulClass M F] trans dist (f (I i).1 • g (I i).1) (f (I i).1 • g (I i).2) + dist (f (I i).1 • g (I i).2) (f (I i).2 • g (I i).2) · exact dist_triangle _ _ _ - · simp only [disjWithin, mem_setOf_eq] at hnI + · simp only [disjWithin, mem_ofPred_eq] at hnI gcongr · rw [dist_smul₀] gcongr @@ -433,7 +433,7 @@ theorem _root_.IntervalIntegrable.absolutelyContinuousOnInterval_intervalIntegra E ∈ disjWithin a b := eventually_inf_principal.mpr (by simp) filter_upwards [this] with (n, I) hnI - obtain ⟨hnI1, hnI2⟩ := mem_setOf_eq ▸ hnI + obtain ⟨hnI1, hnI2⟩ := mem_ofPred_eq ▸ hnI simp only rw [← integral_norm_eq_lintegral_enorm (h.aestronglyMeasurable_restrict_uIoc.restrict), integral_biUnion_finset _ (by simp +contextual [uIoc]) hnI2] diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean index 7a06aec3ea3e6c..5bb1d4340ccdec 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean @@ -96,11 +96,11 @@ variable {F 𝕜} theorem mem_lpMeasSubgroup_iff_aestronglyMeasurable {m m0 : MeasurableSpace α} {μ : Measure α} {f : Lp F p μ} : f ∈ lpMeasSubgroup F m p μ ↔ AEStronglyMeasurable[m] f μ := by - rw [← AddSubgroup.mem_carrier, lpMeasSubgroup, Set.mem_setOf_eq] + rw [← AddSubgroup.mem_carrier, lpMeasSubgroup, Set.mem_ofPred_eq] theorem mem_lpMeas_iff_aestronglyMeasurable {m m0 : MeasurableSpace α} {μ : Measure α} {f : Lp F p μ} : f ∈ lpMeas F 𝕜 m p μ ↔ AEStronglyMeasurable[m] f μ := by - rw [← SetLike.mem_coe, ← Submodule.mem_carrier, lpMeas, Set.mem_setOf_eq] + rw [← SetLike.mem_coe, ← Submodule.mem_carrier, lpMeas, Set.mem_ofPred_eq] theorem lpMeas.aestronglyMeasurable {m _ : MeasurableSpace α} {μ : Measure α} (f : lpMeas F 𝕜 m p μ) : AEStronglyMeasurable[m] (f : α → F) μ := diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean index 24c3958e3457f9..58c792403511d1 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean @@ -169,7 +169,7 @@ theorem ae_bdd_condExp_of_ae_bdd {R : ℝ≥0} {f : α → ℝ} (hbdd : ∀ᵐ x exact (abs_nonneg _).trans hx by_contra h change μ _ ≠ 0 at h - simp only [← pos_iff_ne_zero, Set.compl_def, Set.mem_setOf_eq, not_le] at h + simp only [← pos_iff_ne_zero, Set.compl_def, Set.mem_ofPred_eq, not_le] at h suffices μ.real {x | ↑R < |(μ[f|m]) x|} * ↑R < μ.real {x | ↑R < |(μ[f|m]) x|} * ↑R by exact this.ne rfl refine lt_of_lt_of_le (setIntegral_gt_gt R.coe_nonneg ?_ h.ne') ?_ diff --git a/Mathlib/MeasureTheory/Function/ConvergenceInMeasure.lean b/Mathlib/MeasureTheory/Function/ConvergenceInMeasure.lean index f148a1ad721cb9..f606c2867f46c5 100644 --- a/Mathlib/MeasureTheory/Function/ConvergenceInMeasure.lean +++ b/Mathlib/MeasureTheory/Function/ConvergenceInMeasure.lean @@ -216,7 +216,7 @@ theorem tendstoInMeasure_of_tendsto_ae_of_measurable_edist [IsFiniteMeasure μ] suffices { x : α | ε ≤ edist (f n x) (g x) } ⊆ t from (measure_mono this).trans ht rw [← Set.compl_subset_compl] intro x hx - rw [Set.mem_compl_iff, Set.notMem_setOf_iff, edist_comm, not_le] + rw [Set.mem_compl_iff, Set.notMem_ofPred_iff, edist_comm, not_le] exact hN n hn x hx /-- Convergence a.e. implies convergence in measure in a finite measure space. -/ @@ -302,7 +302,7 @@ theorem TendstoInMeasure.exists_seq_tendsto_ae (hfg : TendstoInMeasure μ f atTo refine fun x hx => EMetric.tendsto_atTop.mpr fun ε hε => ?_ rw [hs, limsup_eq_iInf_iSup_of_nat] at hx simp only [S, Set.iSup_eq_iUnion, Set.iInf_eq_iInter, Set.compl_iInter, Set.compl_iUnion, - Set.mem_iUnion, Set.mem_iInter, Set.mem_compl_iff, Set.mem_setOf_eq, not_le] at hx + Set.mem_iUnion, Set.mem_iInter, Set.mem_compl_iff, Set.mem_ofPred_eq, not_le] at hx obtain ⟨N, hNx⟩ := hx obtain ⟨k, hk_lt_ε⟩ := h_lt_ε_real ε hε refine ⟨max N (k - 1), fun n hn_ge => lt_of_le_of_lt ?_ hk_lt_ε⟩ @@ -318,7 +318,7 @@ theorem TendstoInMeasure.exists_seq_tendsto_ae (hfg : TendstoInMeasure μ f atTo exact le_trans hNx.le h_inv_n_le_k rw [ae_iff] refine ⟨ExistsSeqTendstoAe.seqTendstoAeSeq_strictMono hfg, measure_mono_null (fun x => ?_) hμs⟩ - rw [Set.mem_setOf_eq, ← @Classical.not_not (x ∈ s), not_imp_not] + rw [Set.mem_ofPred_eq, ← @Classical.not_not (x ∈ s), not_imp_not] exact h_tendsto x theorem TendstoInMeasure.exists_seq_tendstoInMeasure_atTop {u : Filter ι} [NeBot u] diff --git a/Mathlib/MeasureTheory/Function/Egorov.lean b/Mathlib/MeasureTheory/Function/Egorov.lean index 3788930266fdf1..c082381b5d8e03 100644 --- a/Mathlib/MeasureTheory/Function/Egorov.lean +++ b/Mathlib/MeasureTheory/Function/Egorov.lean @@ -49,7 +49,7 @@ variable {n : ℕ} {j : ι} {s : Set α} {ε : ℝ} {f : ι → α → β} {g : theorem mem_notConvergentSeq_iff [Preorder ι] {x : α} : x ∈ notConvergentSeq f g n j ↔ ∃ k ≥ j, (n : ℝ≥0∞)⁻¹ < edist (f k x) (g x) := by - simp_rw [notConvergentSeq, Set.mem_iUnion, exists_prop, mem_setOf] + simp_rw [notConvergentSeq, Set.mem_iUnion, exists_prop, mem_ofPred] theorem notConvergentSeq_antitone [Preorder ι] : Antitone (notConvergentSeq f g n) := fun _ _ hjk => Set.iUnion₂_mono' fun l hl => ⟨l, le_trans hjk hl, Set.Subset.rfl⟩ diff --git a/Mathlib/MeasureTheory/Function/Intersectivity.lean b/Mathlib/MeasureTheory/Function/Intersectivity.lean index 37866f81f6c846..caa14504cf0229 100644 --- a/Mathlib/MeasureTheory/Function/Intersectivity.lean +++ b/Mathlib/MeasureTheory/Function/Intersectivity.lean @@ -56,7 +56,7 @@ lemma bergelson' {s : ℕ → Set α} (hs : ∀ n, MeasurableSet (s n)) (hr₀ : simp_rw [pos_iff_ne_zero] rintro ⟨x, hx⟩ hu refine hx.2 (mem_iUnion.2 ⟨u, ?_⟩) - rw [mem_setOf, indicator_of_mem hx.1, eLpNormEssSup_eq_zero_iff.2] + rw [mem_ofPred, indicator_of_mem hx.1, eLpNormEssSup_eq_zero_iff.2] · simp · rwa [indicator_ae_eq_zero, Function.support_one, inter_univ] -- Define `f n` to be the average of the first `n + 1` indicators of the `s k`. diff --git a/Mathlib/MeasureTheory/Function/JacobianOneDim.lean b/Mathlib/MeasureTheory/Function/JacobianOneDim.lean index c7a11c2bb0c144..f4c98d5cea2c7a 100644 --- a/Mathlib/MeasureTheory/Function/JacobianOneDim.lean +++ b/Mathlib/MeasureTheory/Function/JacobianOneDim.lean @@ -84,11 +84,11 @@ theorem exists_decomposition_of_monotoneOn_hasDerivWithinAt (hs : MeasurableSet (∀ x ∈ b, f' x = 0) ∧ (∀ x ∈ c, 0 ≤ f' x) ∧ InjOn f c := by let a := {x ∈ s | 𝓝[s ∩ Ioi x] x = ⊥} ∪ {x ∈ s | 𝓝[s ∩ Iio x] x = ⊥} have a_count : a.Countable := - countable_setOf_isolated_right_within.union countable_setOf_isolated_left_within + countable_setOfPred_isolated_right_within.union countable_setOfPred_isolated_left_within let s₁ := s \ a have hs₁ : MeasurableSet s₁ := hs.diff a_count.measurableSet let u : Set ℝ := {c | ∃ x y, x ∈ s₁ ∧ y ∈ s₁ ∧ x < y ∧ f x = c ∧ f y = c} - have hu : Set.Countable u := MonotoneOn.countable_setOf_two_preimages (hf.mono sdiff_subset) + have hu : Set.Countable u := MonotoneOn.countable_setOfPred_two_preimages (hf.mono sdiff_subset) let b := s₁ ∩ f ⁻¹' u have hb : MeasurableSet b := by have : b = ⋃ z ∈ u, s₁ ∩ f ⁻¹' {z} := by ext; simp [b] @@ -101,7 +101,7 @@ theorem exists_decomposition_of_monotoneOn_hasDerivWithinAt (hs : MeasurableSet have hc : MeasurableSet c := hs₁.diff hb refine ⟨a, b, c, ?_, a_count.measurableSet, hb, hc, ?_, ?_, a_count, ?_, ?_, ?_, ?_⟩ · ext x - simp only [sdiff_self_inter, inter_union_sdiff, union_sdiff_self, mem_union, mem_setOf_eq, + simp only [sdiff_self_inter, inter_union_sdiff, union_sdiff_self, mem_union, mem_ofPred_eq, or_iff_right_iff_imp, a, b, s₁, c] tauto · simpa [b, c, s₁] using disjoint_sdiff_right @@ -135,7 +135,7 @@ theorem exists_decomposition_of_monotoneOn_hasDerivWithinAt (hs : MeasurableSet have J2 : 𝓝[s ∩ Ioo p x] x = 𝓝[s ∩ Iio x] x := by simp [nhdsWithin_inter, nhdsWithin_Ioo_eq_nhdsLT px] rw [uniqueDiffWithinAt_iff_accPt, accPt_principal_iff_nhdsWithin, J1, J2] - simp only [mem_inter_iff, Set.mem_sdiff, hx.1.1, mem_union, mem_setOf_eq, true_and, not_or, + simp only [mem_inter_iff, Set.mem_sdiff, hx.1.1, mem_union, mem_ofPred_eq, true_and, not_or, mem_preimage, b, s₁, a] at hx exact neBot_iff.2 hx.1.2 · have K : HasDerivWithinAt f 0 (s ∩ Ioo x p) x := by @@ -153,14 +153,14 @@ theorem exists_decomposition_of_monotoneOn_hasDerivWithinAt (hs : MeasurableSet have J2 : 𝓝[s ∩ Ioo x p] x = 𝓝[s ∩ Ioi x] x := by simp [nhdsWithin_inter, nhdsWithin_Ioo_eq_nhdsGT px] rw [uniqueDiffWithinAt_iff_accPt, accPt_principal_iff_nhdsWithin, J1, J2] - simp only [mem_inter_iff, Set.mem_sdiff, hx.1.1, mem_union, mem_setOf_eq, true_and, not_or, + simp only [mem_inter_iff, Set.mem_sdiff, hx.1.1, mem_union, mem_ofPred_eq, true_and, not_or, mem_preimage, b, s₁, a] at hx exact neBot_iff.2 hx.1.1 · /- We have to show that the derivative is nonnegative at points of `c`. As these points are not isolated in `s`, this follows from the fact that `f` is monotone on `s`. -/ intro x hx apply (hf' x hx.1.1).nonneg_of_monotoneOn _ hf - simp only [Set.mem_sdiff, hx.1.1, mem_union, mem_setOf_eq, true_and, not_or, c, s₁, a, b] at hx + simp only [Set.mem_sdiff, hx.1.1, mem_union, mem_ofPred_eq, true_and, not_or, c, s₁, a, b] at hx rw [accPt_principal_iff_nhdsWithin] have : (𝓝[s ∩ Iio x] x).NeBot := neBot_iff.2 hx.1.2 apply this.mono diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 4b20ff68db26a5..05ba349d0edc6e 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -685,14 +685,15 @@ lemma Integrable.measure_norm_gt_lt_top_enorm {E : Type*} [TopologicalSpace E] [ {f : α → E} (hf : Integrable f μ) {ε : ℝ≥0∞} (hε : 0 < ε) : μ {x | ε < ‖f x‖ₑ} < ∞ := by by_cases hε' : ε = ∞ · simp [hε'] - exact lt_of_le_of_lt (measure_mono (fun _ h ↦ (Set.mem_setOf_eq ▸ h).le)) + exact lt_of_le_of_lt (measure_mono (fun _ h ↦ (Set.mem_ofPred_eq ▸ h).le)) (hf.measure_enorm_ge_lt_top hε hε') /-- A non-quantitative version of Markov inequality for integrable functions: the measure of points where `‖f x‖ > ε` is finite for all positive `ε`. -/ lemma Integrable.measure_norm_gt_lt_top {f : α → β} (hf : Integrable f μ) {ε : ℝ} (hε : 0 < ε) : μ {x | ε < ‖f x‖} < ∞ := - lt_of_le_of_lt (measure_mono (fun _ h ↦ (Set.mem_setOf_eq ▸ h).le)) (hf.measure_norm_ge_lt_top hε) + lt_of_le_of_lt (measure_mono (fun _ h ↦ (Set.mem_ofPred_eq ▸ h).le)) + (hf.measure_norm_ge_lt_top hε) /-- If `f` is integrable, then for any `c > 0` the set `{x | f x ≥ c}` has finite measure. -/ @@ -718,7 +719,7 @@ measure. -/ lemma Integrable.measure_gt_lt_top {f : α → β} [Lattice β] [HasSolidNorm β] [AddLeftMono β] (hf : Integrable f μ) {ε : β} (ε_pos : 0 < ε) : μ {a : α | ε < f a} < ∞ := - lt_of_le_of_lt (measure_mono (fun _ hx ↦ (Set.mem_setOf_eq ▸ hx).le)) + lt_of_le_of_lt (measure_mono (fun _ hx ↦ (Set.mem_ofPred_eq ▸ hx).le)) (Integrable.measure_ge_lt_top hf ε_pos) /-- If `f` is `ℝ`-valued and integrable, then for any `c < 0` the set `{x | f x < c}` has finite @@ -726,7 +727,7 @@ measure. -/ lemma Integrable.measure_lt_lt_top {f : α → β} [Lattice β] [HasSolidNorm β] [AddLeftMono β] (hf : Integrable f μ) {c : β} (c_neg : c < 0) : μ {a : α | f a < c} < ∞ := - lt_of_le_of_lt (measure_mono (fun _ hx ↦ (Set.mem_setOf_eq ▸ hx).le)) + lt_of_le_of_lt (measure_mono (fun _ hx ↦ (Set.mem_ofPred_eq ▸ hx).le)) (Integrable.measure_le_lt_top hf c_neg) theorem LipschitzWith.integrable_comp_iff_of_antilipschitz {K K'} {f : α → β} {g : β → γ} diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean index 4bfab0e33c6d3a..1540b803fae179 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Indicator.lean @@ -83,7 +83,7 @@ lemma eLpNormEssSup_indicator_const_eq (s : Set α) (c : ε) (hμs : μ s ≠ 0) have h' := ae_iff.mp (ae_lt_of_essSup_lt h) push Not at h' refine hμs (measure_mono_null (fun x hx_mem => ?_) h') - rw [Set.mem_setOf_eq, Set.indicator_of_mem hx_mem] + rw [Set.mem_ofPred_eq, Set.indicator_of_mem hx_mem] lemma eLpNorm_indicator_const₀ (hs : NullMeasurableSet s μ) (hp : p ≠ 0) (hp_top : p ≠ ∞) : eLpNorm (s.indicator fun _ => c) p μ = ‖c‖ₑ * μ s ^ (1 / p.toReal) := diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Trim.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Trim.lean index 5e0ecf96434ff7..f1d6a55299a0e2 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Trim.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Trim.lean @@ -37,7 +37,7 @@ theorem limsup_trim (hm : m ≤ m0) {f : α → ℝ≥0∞} (hf : Measurable[m] rw [h_set_eq] ext1 a suffices h_meas_eq : μ { x | ¬f x ≤ a } = μ.trim hm { x | ¬f x ≤ a } by - simp_rw [Set.mem_setOf_eq, ae_iff, h_meas_eq] + simp_rw [Set.mem_ofPred_eq, ae_iff, h_meas_eq] refine (trim_measurableSet_eq hm ?_).symm exact (measurableSet_le hf measurable_const).compl diff --git a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean index fec382a50f55dc..f771df1cab54c0 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace/Basic.lean @@ -93,7 +93,7 @@ def Lp {α} (E : Type*) {m : MeasurableSpace α} [NormedAddCommGroup E] (p : ℝ add_mem' {f g} hf hg := by simp [eLpNorm_congr_ae (AEEqFun.coeFn_add f g), eLpNorm_add_lt_top ⟨f.aestronglyMeasurable, hf⟩ ⟨g.aestronglyMeasurable, hg⟩] - neg_mem' {f} hf := by rwa [Set.mem_setOf_eq, eLpNorm_congr_ae (AEEqFun.coeFn_neg f), eLpNorm_neg] + neg_mem' {f} hf := by rwa [Set.mem_ofPred_eq, eLpNorm_congr_ae (AEEqFun.coeFn_neg f), eLpNorm_neg] /-- `α →₁[μ] E` is the type of `L¹` or integrable functions from `α` to `E`. -/ scoped notation:25 α' " →₁[" μ "] " E => MeasureTheory.Lp (α := α') E 1 μ diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index cb2e79885026c6..ca211bf56a3c57 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -832,7 +832,7 @@ theorem approx_apply [TopologicalSpace β] [OrderClosedTopology β] [MeasurableS congr funext k rw [restrict_apply] - · simp only [coe_const, mem_setOf_eq, indicator_apply, Function.const_apply] + · simp only [coe_const, mem_ofPred_eq, indicator_apply, Function.const_apply] · exact hf measurableSet_Ici theorem monotone_approx (i : ℕ → β) (f : α → β) : Monotone (approx i f) := fun _ _ h => diff --git a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean index 277237aff7d8ef..69f66dbf4a722a 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFuncDenseLp.lean @@ -727,7 +727,7 @@ theorem denseRange_coeSimpleFuncNonnegToLpNonneg [hp : Fact (1 ≤ p)] (hp_ne_to have hg_memLp : MemLp (g : α → G) p μ := Lp.memLp (g : Lp G p μ) have zero_mem : (0 : G) ∈ (range (g : α → G) ∪ {0} : Set G) ∩ { y | 0 ≤ y } := by simp only [union_singleton, mem_inter_iff, mem_insert_iff, true_or, - mem_setOf_eq, le_refl, and_self_iff] + mem_ofPred_eq, le_refl, and_self_iff] have : SeparableSpace ((range (g : α → G) ∪ {0}) ∩ { y | 0 ≤ y } : Set G) := by apply IsSeparable.separableSpace apply IsSeparable.mono _ Set.inter_subset_left diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 3353628798b2f4..793cc766d98a7f 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -423,12 +423,12 @@ protected theorem inv₀ [GroupWithZero β] [ContinuousInv₀ β] [MetrizableSpa refine ⟨fun n => ((hf.approx n).restrict {x | f x ≠ 0})⁻¹, fun x => ?_⟩ have : MeasurableSet {x | f x ≠ 0} := ((MeasurableSet.singleton 0).preimage hf.measurable).compl by_cases h : f x = 0 - · simp_all only [ne_eq, measurableSet_setOf, SimpleFunc.coe_inv, SimpleFunc.coe_restrict, - Pi.inv_apply, mem_setOf_eq, not_true_eq_false, not_false_eq_true, indicator_of_notMem, + · simp_all only [ne_eq, measurableSet_setOfPred, SimpleFunc.coe_inv, SimpleFunc.coe_restrict, + Pi.inv_apply, mem_ofPred_eq, not_true_eq_false, not_false_eq_true, indicator_of_notMem, _root_.inv_zero] exact tendsto_const_nhds - · simp_all only [ne_eq, measurableSet_setOf, SimpleFunc.coe_inv, SimpleFunc.coe_restrict, - Pi.inv_apply, mem_setOf_eq, not_false_eq_true, indicator_of_mem] + · simp_all only [ne_eq, measurableSet_setOfPred, SimpleFunc.coe_inv, SimpleFunc.coe_restrict, + Pi.inv_apply, mem_ofPred_eq, not_false_eq_true, indicator_of_mem] apply (hf.tendsto_approx x).inv₀ h @[to_additive (attr := to_fun (attr := fun_prop)) sub] @@ -451,11 +451,11 @@ theorem div [GroupWithZero β] [ContinuousMul β] [ContinuousInv₀ β] [Metriza refine ⟨fun n => hf.approx n / (hg.approx n).restrict {x | g x ≠ 0}, fun x => ?_⟩ have : MeasurableSet {x | g x ≠ 0} := ((MeasurableSet.singleton 0).preimage hg.measurable).compl by_cases h : g x = 0 - · simp_all only [ne_eq, SimpleFunc.coe_div, SimpleFunc.coe_restrict, Pi.div_apply, mem_setOf_eq, + · simp_all only [ne_eq, SimpleFunc.coe_div, SimpleFunc.coe_restrict, Pi.div_apply, mem_ofPred_eq, not_true_eq_false, not_false_eq_true, indicator_of_notMem, _root_.div_zero] exact tendsto_const_nhds · simp_all only [ne_eq, SimpleFunc.coe_div, SimpleFunc.coe_restrict, - Pi.div_apply, mem_setOf_eq, not_false_eq_true, indicator_of_mem] + Pi.div_apply, mem_ofPred_eq, not_false_eq_true, indicator_of_mem] exact (hf.tendsto_approx x).div (hg.tendsto_approx x) h @[to_additive] diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean index f861c5f6d0e688..77f935aff7bc7b 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Lemmas.lean @@ -98,7 +98,7 @@ theorem aestronglyMeasurable_withDensity_iff {E : Type*} [NormedAddCommGroup E] have : (f a : ℝ≥0∞) ≠ 0 := by simpa only [Ne, ENNReal.coe_eq_zero] using h'a rw [ha this] · filter_upwards [ae_restrict_mem A.compl] with x hx - simp only [Classical.not_not, mem_setOf_eq, mem_compl_iff] at hx + simp only [Classical.not_not, mem_ofPred_eq, mem_compl_iff] at hx simp [hx] · rintro ⟨g', g'meas, hg'⟩ refine ⟨fun x => (f x : ℝ)⁻¹ • g' x, hf.coe_nnreal_real.inv.stronglyMeasurable.smul g'meas, ?_⟩ diff --git a/Mathlib/MeasureTheory/Function/UniformIntegrable.lean b/Mathlib/MeasureTheory/Function/UniformIntegrable.lean index 8d2058fb69dd68..4ef928052efa8f 100644 --- a/Mathlib/MeasureTheory/Function/UniformIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/UniformIntegrable.lean @@ -177,7 +177,7 @@ theorem tendsto_indicator_ge (f : α → β) (x : α) : Tendsto (fun M : ℕ => { x | (M : ℝ) ≤ ‖f x‖₊ }.indicator f x) atTop (𝓝 0) := by refine tendsto_atTop_of_eventually_const (i₀ := Nat.ceil (‖f x‖₊ : ℝ) + 1) fun n hn => ?_ rw [Set.indicator_of_notMem] - simp only [not_le, Set.mem_setOf_eq] + simp only [not_le, Set.mem_ofPred_eq] refine lt_of_le_of_lt (Nat.le_ceil _) ?_ refine lt_of_lt_of_le (lt_add_one _) ?_ norm_cast @@ -239,7 +239,7 @@ theorem MemLp.integral_indicator_norm_ge_nonneg_le (hf : MemLp f 1 μ) {ε : ℝ refine ⟨M, hM_pos, (le_of_eq ?_).trans hfM⟩ refine lintegral_congr_ae ?_ filter_upwards [hf.1.ae_eq_mk] with x hx - simp only [Set.indicator_apply, coe_nnnorm, Set.mem_setOf_eq, hx.symm] + simp only [Set.indicator_apply, coe_nnnorm, Set.mem_ofPred_eq, hx.symm] theorem MemLp.eLpNormEssSup_indicator_norm_ge_eq_zero (hf : MemLp f ∞ μ) (hmeas : StronglyMeasurable f) : @@ -252,7 +252,7 @@ theorem MemLp.eLpNormEssSup_indicator_norm_ge_eq_zero (hf : MemLp f ∞ μ) have : { x : α | (eLpNormEssSup f μ + 1).toReal ≤ ‖f x‖ } ⊆ { x : α | eLpNormEssSup f μ < ‖f x‖₊ } := by intro x hx - rw [Set.mem_setOf_eq, ← ENNReal.toReal_lt_toReal hbdd.ne ENNReal.coe_lt_top.ne, + rw [Set.mem_ofPred_eq, ← ENNReal.toReal_lt_toReal hbdd.ne ENNReal.coe_lt_top.ne, ENNReal.coe_toReal, coe_nnnorm] refine lt_of_lt_of_le ?_ hx rw [ENNReal.toReal_lt_toReal hbdd.ne] @@ -295,11 +295,11 @@ theorem MemLp.eLpNorm_indicator_norm_ge_le (hf : MemLp f p μ) (hmeas : Strongly by_cases hx : x ∈ { x : α | M ^ (1 / p.toReal) ≤ ‖f x‖₊ } · rw [Set.indicator_of_mem hx, Set.indicator_of_mem, Real.enorm_of_nonneg (by positivity), ← ENNReal.ofReal_rpow_of_nonneg (norm_nonneg _) ENNReal.toReal_nonneg, ofReal_norm] - rw [Set.mem_setOf_eq] + rw [Set.mem_ofPred_eq] rwa [← hiff] · rw [Set.indicator_of_notMem hx, Set.indicator_of_notMem] · simp [ENNReal.toReal_pos hp_ne_zero hp_ne_top] - · rw [Set.mem_setOf_eq] + · rw [Set.mem_ofPred_eq] rwa [← hiff] /-- This lemma implies that a single function is uniformly integrable (in the probability sense). -/ @@ -623,7 +623,7 @@ theorem unifIntegrable_of' (hp : 1 ≤ p) (hp' : p ≠ ∞) {f : ι → α → · refine (Disjoint.inf_right' _ ?_).inf_left' _ rw [disjoint_iff_inf_le] rintro x ⟨hx₁, hx₂⟩ - rw [Set.mem_setOf_eq] at hx₁ hx₂ + rw [Set.mem_ofPred_eq] at hx₁ hx₂ exact False.elim (hx₂.ne (eq_of_le_of_not_lt hx₁ (not_lt.2 hx₂.le)).symm) _ ≤ eLpNorm (Set.indicator { x | C ≤ ‖f i x‖₊ } (f i)) p μ + (C : ℝ≥0∞) * μ s ^ (1 / ENNReal.toReal p) := by @@ -665,9 +665,9 @@ theorem unifIntegrable_of (hp : 1 ≤ p) (hp' : p ≠ ∞) {f : ι → α → β filter_upwards [(Exists.choose_spec <| hf i).2] with x hx by_cases hfx : x ∈ { x | C ≤ ‖f i x‖₊ } · rw [Set.indicator_of_mem hfx, Set.indicator_of_mem, hx] - rwa [Set.mem_setOf, hx] at hfx + rwa [Set.mem_ofPred, hx] at hfx · rw [Set.indicator_of_notMem hfx, Set.indicator_of_notMem] - rwa [Set.mem_setOf, hx] at hfx + rwa [Set.mem_ofPred, hx] at hfx refine ⟨max C 1, lt_max_of_lt_right one_pos, fun i => le_trans (eLpNorm_mono fun x => ?_) (hCg i)⟩ rw [norm_indicator_eq_indicator_norm, norm_indicator_eq_indicator_norm] grw [← le_max_left] @@ -818,9 +818,9 @@ theorem uniformIntegrable_of [IsFiniteMeasure μ] (hp : 1 ≤ p) (hp' : p ≠ filter_upwards [(Exists.choose_spec <| hf i).2] with x hx by_cases hfx : x ∈ { x | C ≤ ‖f i x‖₊ } · rw [Set.indicator_of_mem hfx, Set.indicator_of_mem, hx] - rwa [Set.mem_setOf, hx] at hfx + rwa [Set.mem_ofPred, hx] at hfx · rw [Set.indicator_of_notMem hfx, Set.indicator_of_notMem] - rwa [Set.mem_setOf, hx] at hfx + rwa [Set.mem_ofPred, hx] at hfx /-- This lemma is superseded by `UniformIntegrable.spec` which does not require measurability. -/ theorem UniformIntegrable.spec' (hp : p ≠ 0) (hp' : p ≠ ∞) (hf : ∀ i, StronglyMeasurable (f i)) @@ -869,9 +869,9 @@ theorem UniformIntegrable.spec (hp : p ≠ 0) (hp' : p ≠ ∞) (hfu : UniformIn filter_upwards [(Exists.choose_spec <| hfu.1 i).2] with x hx by_cases hfx : x ∈ { x | C ≤ ‖f i x‖₊ } · rw [Set.indicator_of_mem hfx, Set.indicator_of_mem, hx] - rwa [Set.mem_setOf, hx] at hfx + rwa [Set.mem_ofPred, hx] at hfx · rw [Set.indicator_of_notMem hfx, Set.indicator_of_notMem] - rwa [Set.mem_setOf, hx] at hfx + rwa [Set.mem_ofPred, hx] at hfx /-- The definition of uniform integrable in mathlib is equivalent to the definition commonly found in literature. -/ diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index c3d2649b7ff7bb..94f37e9880c9a4 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -124,8 +124,8 @@ theorem mk_of_measure_univ_le [IsFiniteMeasure μ] [Countable G] (h_meas : NullM replace h_meas : ∀ g : G, NullMeasurableSet (g • s) μ := fun g => by rw [← inv_inv g, ← preimage_smul]; exact h_meas.preimage (h_qmp g⁻¹) have h_meas' : NullMeasurableSet {a | ∃ g : G, g • a ∈ s} μ := by - rw [← iUnion_smul_eq_setOf_exists]; exact .iUnion h_meas - rw [ae_iff_measure_eq h_meas', ← iUnion_smul_eq_setOf_exists] + rw [← iUnion_smul_eq_ofPred_exists]; exact .iUnion h_meas + rw [ae_iff_measure_eq h_meas', ← iUnion_smul_eq_ofPred_exists] refine le_antisymm (measure_mono <| subset_univ _) ?_ rw [measure_iUnion₀ aedisjoint h_meas] exact h_measure_univ_le } @@ -465,7 +465,7 @@ theorem essSup_measure_restrict (hs : IsFundamentalDomain G s μ) {f : α → intro γ ext x rw [mem_smul_set_iff_inv_smul_mem] - simp only [mem_setOf_eq, hf γ⁻¹ x] + simp only [mem_ofPred_eq, hf γ⁻¹ x] end IsFundamentalDomain @@ -593,8 +593,8 @@ variable [MeasurableConstSMul G α] [SMulInvariantMeasure G α μ] protected theorem fundamentalInterior : IsFundamentalDomain G (fundamentalInterior G s) μ where nullMeasurableSet := hs.nullMeasurableSet.fundamentalInterior _ _ ae_covers := by - simp_rw [ae_iff, not_exists, ← mem_inv_smul_set_iff, setOf_forall, ← compl_setOf, - setOf_mem_eq, ← compl_iUnion] + simp_rw [ae_iff, not_exists, ← mem_inv_smul_set_iff, ofPred_forall, ← compl_ofPred, + ofPred_mem_eq, ← compl_iUnion] have : ((⋃ g : G, g⁻¹ • s) \ ⋃ g : G, g⁻¹ • fundamentalFrontier G s) ⊆ ⋃ g : G, g⁻¹ • fundamentalInterior G s := by @@ -602,7 +602,7 @@ protected theorem fundamentalInterior : IsFundamentalDomain G (fundamentalInteri fundamentalFrontier_union_fundamentalInterior]; rfl refine eq_bot_mono (μ.mono <| compl_subset_compl.2 this) ?_ simp only [iUnion_inv_smul, compl_sdiff, ENNReal.bot_eq_zero, - @iUnion_smul_eq_setOf_exists _ _ _ _ s] + @iUnion_smul_eq_ofPred_exists _ _ _ _ s] exact measure_union_null (measure_iUnion_null fun _ => measure_smul_null hs.measure_fundamentalFrontier _) hs.ae_covers aedisjoint := (pairwise_disjoint_fundamentalInterior _ _).mono fun _ _ => Disjoint.aedisjoint @@ -827,7 +827,7 @@ lemma QuotientMeasureEqMeasurePreimage.sigmaFiniteQuotient SigmaFinite μ := by rw [sigmaFinite_iff] obtain ⟨A, hA_meas, hA, hA'⟩ := Measure.toFiniteSpanningSetsIn (h := i) - simp only [mem_setOf_eq] at hA_meas + simp only [mem_ofPred_eq] at hA_meas refine ⟨⟨fun n ↦ π '' (A n), by simp, fun n ↦ ?_, ?_⟩⟩ · obtain ⟨s, fund_dom_s⟩ := i' have : π ⁻¹' π '' (A n) = _ := MulAction.quotient_preimage_image_eq_union_mul (A n) (G := G) diff --git a/Mathlib/MeasureTheory/Integral/Average.lean b/Mathlib/MeasureTheory/Integral/Average.lean index 48ba3ee5ce1034..d4fedf0a71b88e 100644 --- a/Mathlib/MeasureTheory/Integral/Average.lean +++ b/Mathlib/MeasureTheory/Integral/Average.lean @@ -506,7 +506,7 @@ theorem measure_le_setAverage_pos (hμ : μ s ≠ 0) (hμ₁ : μ s ≠ ∞) (hf refine (integral_sub_average (μ.restrict s) f).not_gt ?_ refine (setIntegral_pos_iff_support_of_nonneg_ae ?_ ?_).2 ?_ · refine measure_mono_null (fun x hx ↦ ?_) H - simp only [Pi.zero_apply, sub_nonneg, mem_compl_iff, mem_setOf_eq, not_le] at hx + simp only [Pi.zero_apply, sub_nonneg, mem_compl_iff, mem_ofPred_eq, not_le] at hx exact hx.le · exact hf.sub (integrableOn_const hμ₁) · rwa [pos_iff_ne_zero, inter_comm, ← sdiff_compl, ← sdiff_inter_self_eq_sdiff, @@ -628,9 +628,9 @@ theorem measure_le_setLAverage_pos (hμ : μ s ≠ 0) (hμ₁ : μ s ≠ ∞) obtain h | h := eq_or_ne (∫⁻ a in s, f a ∂μ) ∞ · simpa [mul_top, hμ₁, laverage, h, top_div_of_ne_top hμ₁, pos_iff_ne_zero] using hμ have := measure_le_setAverage_pos hμ hμ₁ (integrable_toReal_of_lintegral_ne_top hf h) - rw [← setOf_inter_eq_sep, ← Measure.restrict_apply₀ + rw [← ofPred_inter_eq_sep, ← Measure.restrict_apply₀ (hf.aestronglyMeasurable.nullMeasurableSet_le aestronglyMeasurable_const)] - rw [← setOf_inter_eq_sep, ← Measure.restrict_apply₀ + rw [← ofPred_inter_eq_sep, ← Measure.restrict_apply₀ (hf.ennreal_toReal.aestronglyMeasurable.nullMeasurableSet_le aestronglyMeasurable_const), ← measure_sdiff_null (measure_eq_top_of_lintegral_ne_top hf h)] at this refine this.trans_le (measure_mono ?_) @@ -651,8 +651,8 @@ theorem measure_setLAverage_le_pos (hμ : μ s ≠ 0) (hs : NullMeasurableSet s rw [hfg] at hint have := measure_setAverage_le_pos hμ hμ₁ (integrable_toReal_of_lintegral_ne_top hg.aemeasurable hint) - simp_rw [← setOf_inter_eq_sep, ← Measure.restrict_apply₀' hs, hfg'] - rw [← setOf_inter_eq_sep, ← Measure.restrict_apply₀' hs, ← + simp_rw [← ofPred_inter_eq_sep, ← Measure.restrict_apply₀' hs, hfg'] + rw [← ofPred_inter_eq_sep, ← Measure.restrict_apply₀' hs, ← measure_sdiff_null (measure_eq_top_of_lintegral_ne_top hg.aemeasurable hint)] at this refine this.trans_le (measure_mono ?_) rintro x ⟨hfx, hx⟩ diff --git a/Mathlib/MeasureTheory/Integral/Bochner/L1.lean b/Mathlib/MeasureTheory/Integral/Bochner/L1.lean index 23161ffcc4fd9a..f8ae4c1ceccdad 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/L1.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/L1.lean @@ -334,7 +334,7 @@ lemma integral_nonneg {f : α →ₛ F} (hf : 0 ≤ᵐ[μ] f) : · suffices μ (f ⁻¹' {f y}) = 0 by simp [this, measureReal_def] rw [← nonpos_iff_eq_zero] refine le_of_le_of_eq (measure_mono fun x hx ↦ ?_) (ae_iff.mp hf) - simp only [Set.mem_preimage, mem_singleton_iff, mem_setOf_eq] at hx ⊢ + simp only [Set.mem_preimage, mem_singleton_iff, mem_ofPred_eq] at hx ⊢ exact hx ▸ hy lemma integral_mono {f g : α →ₛ F} (h : f ≤ᵐ[μ] g) (hf : Integrable f μ) (hg : Integrable g μ) : diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean index 30d05807d0b676..338ff3f267c912 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Set.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Set.lean @@ -494,7 +494,7 @@ theorem setIntegral_neg_eq_setIntegral_nonpos [PartialOrder E] {f : X → E} (hf : AEStronglyMeasurable f μ) : ∫ x in {x | f x < 0}, f x ∂μ = ∫ x in {x | f x ≤ 0}, f x ∂μ := by have h_union : {x | f x ≤ 0} = {x | f x < 0} ∪ {x | f x = 0} := by - simp_rw [le_iff_lt_or_eq, setOf_or] + simp_rw [le_iff_lt_or_eq, ofPred_or] rw [h_union] have B : NullMeasurableSet {x | f x = 0} μ := hf.nullMeasurableSet_eq_fun aestronglyMeasurable_zero @@ -519,10 +519,10 @@ theorem integral_norm_eq_pos_sub_neg {f : X → ℝ} (hfi : Integrable f μ) : rw [← integral_neg] refine setIntegral_congr_fun₀ h_meas.compl fun x hx => ?_ rw [Real.norm_eq_abs, abs_eq_neg_self.mpr _] - rw [Set.mem_compl_iff, Set.notMem_setOf_iff] at hx + rw [Set.mem_compl_iff, Set.notMem_ofPred_iff] at hx linarith _ = ∫ x in {x | 0 ≤ f x}, f x ∂μ - ∫ x in {x | f x ≤ 0}, f x ∂μ := by - rw [← setIntegral_neg_eq_setIntegral_nonpos hfi.1, compl_setOf]; simp only [not_le] + rw [← setIntegral_neg_eq_setIntegral_nonpos hfi.1, compl_ofPred]; simp only [not_le] theorem setIntegral_const [CompleteSpace E] (c : E) : ∫ _ in s, c ∂μ = μ.real s • c := by rw [integral_const, measureReal_restrict_apply_univ] diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index 6cba01a49d258a..8fbf14f91803ae 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -523,7 +523,7 @@ theorem HasFDerivWithinAt.curveIntegral_segment_source' (hs : Convex ℝ s) intro ε hε obtain ⟨δ, hδ₀, hδ⟩ : ∃ δ > 0, ball a δ ∩ s ⊆ {z | ContinuousWithinAt ω s z ∧ dist (ω z) (ω a) ≤ ε} := by - rw [← Metric.mem_nhdsWithin_iff, setOf_and, inter_mem_iff] + rw [← Metric.mem_nhdsWithin_iff, ofPred_and, inter_mem_iff] exact ⟨hω, (hω.self_of_nhdsWithin ha).eventually <| closedBall_mem_nhds _ hε⟩ rw [eventually_nhdsWithin_iff] filter_upwards [Metric.ball_mem_nhds _ hδ₀] with b hb hbs diff --git a/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean b/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean index 934e06eb232299..0920a1eeb21722 100644 --- a/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean +++ b/Mathlib/MeasureTheory/Integral/FinMeasAdditive.lean @@ -394,7 +394,7 @@ theorem setToSimpleFunc_congr (T : Set α → E →L[ℝ] F) refine fun x y hxy => h_zero _ ((measurableSet_fiber f x).inter (measurableSet_fiber g y)) ?_ rw [EventuallyEq, ae_iff] at h refine measure_mono_null (fun z => ?_) h - simp_rw [Set.mem_inter_iff, Set.mem_setOf_eq, Set.mem_preimage, Set.mem_singleton_iff] + simp_rw [Set.mem_inter_iff, Set.mem_ofPred_eq, Set.mem_preimage, Set.mem_singleton_iff] intro h rwa [h.1, h.2] diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean index f3dc5eb2192ae7..8873f71ee9955b 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/AbsolutelyContinuousFun.lean @@ -76,7 +76,7 @@ lemma exists_dist_slope_lt_pairwiseDisjoint_hasSum {f f' : ℝ → F} {d b η : with ε hε₁ hε₂ hε₃ hε₄ refine ⟨(x, x + ε), ⟨⟨hx.1.1, by linarith, by linarith⟩, ?_⟩, by simp, rfl⟩ exact hδ₂ (by grind) (by simp [abs_eq_self.mpr hε₁.le, hε₃]) - simp only [t, subset_def, mem_setOf_eq] at hu₁ + simp only [t, subset_def, mem_ofPred_eq] at hu₁ refine ⟨u, ⟨hu₁, hu₃, ?_⟩⟩ have : Countable u := by simp [hu₂] have : Pairwise (Disjoint on fun (z : u) ↦ Icc z.val.1 z.val.2) := diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean index fcd72cbb1956e2..89cf34cb5387b2 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean @@ -1344,7 +1344,7 @@ theorem intervalIntegral_pos_of_pos {f : ℝ → ℝ} {a b : ℝ} /-- If `f` and `g` are two functions that are interval integrable on `a..b`, `a ≤ b`, `f x ≤ g x` for a.e. `x ∈ Set.Ioc a b`, and `f x < g x` on a subset of `Set.Ioc a b` of nonzero measure, then `∫ x in a..b, f x ∂μ < ∫ x in a..b, g x ∂μ`. -/ -theorem integral_lt_integral_of_ae_le_of_measure_setOf_lt_ne_zero (hab : a ≤ b) +theorem integral_lt_integral_of_ae_le_of_measure_setOfPred_lt_ne_zero (hab : a ≤ b) (hfi : IntervalIntegrable f μ a b) (hgi : IntervalIntegrable g μ a b) (hle : f ≤ᵐ[μ.restrict (Ioc a b)] g) (hlt : μ.restrict (Ioc a b) {x | f x < g x} ≠ 0) : (∫ x in a..b, f x ∂μ) < ∫ x in a..b, g x ∂μ := by @@ -1354,13 +1354,17 @@ theorem integral_lt_integral_of_ae_le_of_measure_setOf_lt_ne_zero (hab : a ≤ b exact fun x hx => (sub_pos.2 hx.out).ne' exacts [hle.mono fun x => sub_nonneg.2, hgi.1.sub hfi.1] +@[deprecated (since := "2026-07-09")] +alias integral_lt_integral_of_ae_le_of_measure_setOf_lt_ne_zero := + integral_lt_integral_of_ae_le_of_measure_setOfPred_lt_ne_zero + /-- If `f` and `g` are continuous on `[a, b]`, `a < b`, `f x ≤ g x` on this interval, and `f c < g c` at some point `c ∈ [a, b]`, then `∫ x in a..b, f x < ∫ x in a..b, g x`. -/ theorem integral_lt_integral_of_continuousOn_of_le_of_exists_lt {f g : ℝ → ℝ} {a b : ℝ} (hab : a < b) (hfc : ContinuousOn f (Icc a b)) (hgc : ContinuousOn g (Icc a b)) (hle : ∀ x ∈ Ioc a b, f x ≤ g x) (hlt : ∃ c ∈ Icc a b, f c < g c) : (∫ x in a..b, f x) < ∫ x in a..b, g x := by - apply integral_lt_integral_of_ae_le_of_measure_setOf_lt_ne_zero hab.le + apply integral_lt_integral_of_ae_le_of_measure_setOfPred_lt_ne_zero hab.le (hfc.intervalIntegrable_of_Icc hab.le) (hgc.intervalIntegrable_of_Icc hab.le) · simpa only [measurableSet_Ioc, ae_restrict_eq] using! (ae_restrict_mem measurableSet_Ioc).mono hle diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean index 70dc88473d3dd1..f826953a35631b 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean @@ -104,7 +104,7 @@ lemma norm_sub_le_mul_volume_of_norm_deriv_le_of_le {C : ℝ} (hab : a ≤ b) setIntegral_const, smul_eq_mul, mul_comm] simp only [s, Measure.real, Measure.measure_toMeasurable_inter_of_sFinite measurableSet_Ioo] - simp only [inter_def, mem_setOf_eq, and_comm] + simp only [inter_def, mem_ofPred_eq, and_comm] end Line diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean index 6cb4b260335c09..82d269a5e9269d 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/FundThmCalculus.lean @@ -993,7 +993,7 @@ theorem sub_le_integral_of_hasDeriv_right_of_le_Ico (hab : a ≤ b) -- with `t < b` admits another point in `s` slightly to its right -- (this is a sort of real induction). refine s_closed.Icc_subset_of_forall_exists_gt - (by simp only [integral_same, mem_setOf_eq, sub_self, le_rfl]) fun t ht v t_lt_v => ?_ + (by simp only [integral_same, mem_ofPred_eq, sub_self, le_rfl]) fun t ht v t_lt_v => ?_ obtain ⟨y, g'_lt_y', y_lt_G'⟩ : ∃ y : ℝ, (g' t : EReal) < y ∧ (y : EReal) < G' t := EReal.lt_iff_exists_real_btwn.1 ((EReal.coe_le_coe_iff.2 (hφg t ht.2)).trans_lt (f_lt_G' t)) -- bound from below the increase of `∫ x in a..u, G' x` on the right of `t`, using the lower diff --git a/Mathlib/MeasureTheory/Integral/Layercake.lean b/Mathlib/MeasureTheory/Integral/Layercake.lean index 23684e7b6ec4db..15f41be5cefab4 100644 --- a/Mathlib/MeasureTheory/Integral/Layercake.lean +++ b/Mathlib/MeasureTheory/Integral/Layercake.lean @@ -421,7 +421,7 @@ theorem lintegral_comp_eq_lintegral_meas_le_mul (μ : Measure α) (f_nn : 0 ≤ rw [ht] congr 1 apply measure_congr - filter_upwards [f_eq_F] with a ha using by simp [setOf, ha] + filter_upwards [f_eq_F] with a ha using by simp [Set.ofPred, ha] have eq₂ : ∀ᵐ ω ∂μ, ENNReal.ofReal (∫ t in 0..f ω, g t) = ENNReal.ofReal (∫ t in 0..F ω, G t) := by filter_upwards [f_eq_F] with ω fω_nn diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean index e8cd3a16964476..0fba96a44726e2 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean @@ -62,7 +62,7 @@ theorem lintegral_iSup {f : ℕ → α → ℝ≥0∞} (hf : ∀ n, Measurable ( have mono : ∀ r : ℝ≥0∞, Monotone fun n => rs.map c ⁻¹' {r} ∩ { a | r ≤ f n a } := by intro r i j h refine inter_subset_inter_right _ ?_ - simp_rw [subset_def, mem_setOf] + simp_rw [subset_def, mem_ofPred] intro x hx exact le_trans hx (h_mono h x) have h_meas : ∀ n, MeasurableSet {a : α | map c rs a ≤ f n a} := fun n => @@ -143,7 +143,7 @@ theorem lintegral_iSup_ae {f : ℕ → α → ℝ≥0∞} (hf : ∀ n, Measurabl split_ifs with h · rfl · have := Set.notMem_subset hs.1 h - simp only [not_forall, not_le, mem_setOf_eq, not_exists, not_lt] at this + simp only [not_forall, not_le, mem_ofPred_eq, not_exists, not_lt] at this exact this n open Encodable in diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean index 7d990bdd1626b7..8611e81e90214a 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Basic.lean @@ -322,7 +322,7 @@ theorem lintegral_eq_zero_iff' {f : α → ℝ≥0∞} (hf : AEMeasurable f μ) obtain ⟨u, -, bu, tu⟩ := exists_seq_strictAnti_tendsto' (α := ℝ≥0∞) zero_lt_one have u_union : {x | f x ≠ 0} = ⋃ n, {x | u n ≤ f x} := by ext x - rw [mem_iUnion, mem_setOf_eq, ← pos_iff_ne_zero] + rw [mem_iUnion, mem_ofPred_eq, ← pos_iff_ne_zero] rw [ENNReal.tendsto_atTop_zero] at tu constructor <;> intro h' · obtain ⟨n, hn⟩ := tu _ h'; use n, hn _ le_rfl @@ -654,7 +654,7 @@ theorem lintegral_max {f g : α → ℝ≥0∞} (hf : Measurable f) (hg : Measur ∫⁻ x in { x | f x ≤ g x }, g x ∂μ + ∫⁻ x in { x | g x < f x }, f x ∂μ := by have hm : MeasurableSet { x | f x ≤ g x } := measurableSet_le hf hg rw [← lintegral_add_compl (fun x => max (f x) (g x)) hm] - simp only [← compl_setOf, ← not_le] + simp only [← compl_ofPred, ← not_le] refine congr_arg₂ (· + ·) (setLIntegral_congr_fun hm ?_) (setLIntegral_congr_fun hm.compl ?_) exacts [fun x => max_eq_right (a := f x) (b := g x), fun x (hx : ¬ f x ≤ g x) => max_eq_left (not_le.1 hx).le] diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Markov.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Markov.lean index d677cc096087b1..1d7d0e59670eb3 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Markov.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Markov.lean @@ -89,7 +89,7 @@ theorem setLIntegral_eq_top_of_measure_eq_top_ne_zero {f : α → ℝ≥0∞} {s (hf : AEMeasurable f (μ.restrict s)) (hμf : μ ({x ∈ s | f x = ∞}) ≠ 0) : ∫⁻ x in s, f x ∂μ = ∞ := lintegral_eq_top_of_measure_eq_top_ne_zero hf <| - mt (eq_bot_mono <| by rw [← setOf_inter_eq_sep]; exact Measure.le_restrict_apply _ _) hμf + mt (eq_bot_mono <| by rw [← ofPred_inter_eq_sep]; exact Measure.le_restrict_apply _ _) hμf theorem measure_eq_top_of_lintegral_ne_top {f : α → ℝ≥0∞} (hf : AEMeasurable f μ) (hμf : ∫⁻ x, f x ∂μ ≠ ∞) : μ {x | f x = ∞} = 0 := diff --git a/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean b/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean index c0d3e47d862755..83d04034ae2d0b 100644 --- a/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean +++ b/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean @@ -37,7 +37,7 @@ theorem aemeasurable_withDensity_iff {E : Type*} [NormedAddCommGroup E] [NormedS rw [ha this] · filter_upwards [ae_restrict_mem A.compl] intro x hx - simp only [Classical.not_not, mem_setOf_eq, mem_compl_iff] at hx + simp only [Classical.not_not, mem_ofPred_eq, mem_compl_iff] at hx simp [hx] · rintro ⟨g', g'meas, hg'⟩ refine ⟨fun x => (f x : ℝ)⁻¹ • g' x, hf.coe_nnreal_real.inv.smul g'meas, ?_⟩ diff --git a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean index 3d11c7730c808f..04a8f8eae5dbb9 100644 --- a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean +++ b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani/Real.lean @@ -97,7 +97,7 @@ lemma rieszMeasure_le_of_eq_one {f : C_c(X, ℝ)} (hf : ∀ x, 0 ≤ f x) {K : S apply csInf_le' rw [Set.mem_image] use f.nnrealPart - simp_rw [Set.mem_setOf_eq, nnrealPart_apply, Real.one_le_toNNReal] + simp_rw [Set.mem_ofPred_eq, nnrealPart_apply, Real.one_le_toNNReal] refine ⟨(fun x hx ↦ Eq.ge (hfK x hx)), ?_⟩ apply NNReal.eq rw [toNNRealLinear_apply, show f.nnrealPart.toReal = f by ext z; simp [hf z], hp] @@ -138,8 +138,8 @@ lemma range_cut_partition (f : C_c(X, ℝ)) (a : ℝ) {ε : ℝ} (hε : 0 < ε) apply Disjoint.preimage simp_rw [mem_preimage, mem_Ioc, disjoint_left] intro x hx - rw [mem_setOf_eq, and_assoc] at hx - simp_rw [mem_setOf_eq, not_and_or, not_lt, not_le, or_assoc] + rw [mem_ofPred_eq, and_assoc] at hx + simp_rw [mem_ofPred_eq, not_and_or, not_lt, not_le, or_assoc] rcases (by lia : m < n ∨ n < m) with hc | hc · left exact le_trans hx.2.1 (le_tsub_of_add_le_right (hy hc)) diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index 1543712183cc96..d6fd2b10144cec 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -1433,7 +1433,7 @@ theorem StronglyMeasurable.setToFun_prod_right {β : Type*} {mβ : MeasurableSpa apply (hfx.norm.add hfx.norm).mono' (s' n x).aestronglyMeasurable filter_upwards with y simp_rw [s', SimpleFunc.coe_comp]; exact SimpleFunc.norm_approxOn_zero_le _ _ (x, y) n - simp only [mem_setOf_eq, hfx, indicator_of_mem, this, + simp only [mem_ofPred_eq, hfx, indicator_of_mem, this, ← setToFun_simpleFunc_eq_setToSimpleFunc hT, f'] refine tendsto_setToFun_of_dominated_convergence hT (fun y => ‖f x y‖ + ‖f x y‖) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index f671811e27257d..bdced9169c89f0 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -105,7 +105,7 @@ theorem measurable_findGreatest' {p : α → ℕ → Prop} [∀ x, DecidablePred theorem measurable_findGreatest {p : α → ℕ → Prop} [∀ x, DecidablePred (p x)] {N} (hN : ∀ k ≤ N, MeasurableSet { x | p x k }) : Measurable fun x => Nat.findGreatest (p x) N := by refine measurable_findGreatest' fun k hk => ?_ - simp only [Nat.findGreatest_eq_iff, setOf_and, setOf_forall, ← compl_setOf] + simp only [Nat.findGreatest_eq_iff, ofPred_and, ofPred_forall, ← compl_ofPred] repeat' apply_rules [MeasurableSet.inter, MeasurableSet.const, MeasurableSet.iInter, MeasurableSet.compl, hN] <;> try intros @@ -861,11 +861,14 @@ instance Sigma.instMeasurableSpace {α} {β : α → Type*} [m : ∀ a, Measurab section prop variable [MeasurableSpace α] {p q : α → Prop} -@[simp] theorem measurableSet_setOf : MeasurableSet {a | p a} ↔ Measurable p := +@[simp] theorem measurableSet_setOfPred : MeasurableSet {a | p a} ↔ Measurable p := ⟨fun h ↦ measurable_to_prop <| by simpa only [preimage_singleton_true], fun h => by simpa using h (measurableSet_singleton True)⟩ -@[simp] theorem measurable_mem : Measurable (· ∈ s) ↔ MeasurableSet s := measurableSet_setOf.symm +@[deprecated (since := "2026-07-09")] alias measurableSet_setOf := measurableSet_setOfPred + +@[simp] theorem measurable_mem : Measurable (· ∈ s) ↔ MeasurableSet s := + measurableSet_setOfPred.symm alias ⟨_, Measurable.setOf⟩ := measurableSet_setOf @@ -874,40 +877,43 @@ alias ⟨_, MeasurableSet.mem⟩ := measurable_mem @[fun_prop] lemma Measurable.not (hp : Measurable p) : Measurable (¬ p ·) := - measurableSet_setOf.1 hp.setOf.compl + measurableSet_setOfPred.1 hp.setOf.compl @[fun_prop] lemma Measurable.and (hp : Measurable p) (hq : Measurable q) : Measurable fun a ↦ p a ∧ q a := - measurableSet_setOf.1 <| hp.setOf.inter hq.setOf + measurableSet_setOfPred.1 <| hp.setOf.inter hq.setOf @[fun_prop] lemma Measurable.or (hp : Measurable p) (hq : Measurable q) : Measurable fun a ↦ p a ∨ q a := - measurableSet_setOf.1 <| hp.setOf.union hq.setOf + measurableSet_setOfPred.1 <| hp.setOf.union hq.setOf @[fun_prop] lemma Measurable.imp (hp : Measurable p) (hq : Measurable q) : Measurable fun a ↦ p a → q a := - measurableSet_setOf.1 <| hp.setOf.himp hq.setOf + measurableSet_setOfPred.1 <| hp.setOf.himp hq.setOf @[fun_prop] lemma Measurable.iff (hp : Measurable p) (hq : Measurable q) : Measurable fun a ↦ p a ↔ q a := - measurableSet_setOf.1 <| by simp_rw [iff_iff_implies_and_implies]; exact hq.setOf.bihimp hp.setOf + measurableSet_setOfPred.1 <| by + simp_rw [iff_iff_implies_and_implies]; exact hq.setOf.bihimp hp.setOf @[fun_prop] lemma Measurable.forall [Countable ι] {p : ι → α → Prop} (hp : ∀ i, Measurable (p i)) : Measurable fun a ↦ ∀ i, p i a := - measurableSet_setOf.1 <| by rw [setOf_forall]; exact MeasurableSet.iInter fun i ↦ (hp i).setOf + measurableSet_setOfPred.1 <| by + rw [ofPred_forall]; exact MeasurableSet.iInter fun i ↦ (hp i).setOf @[fun_prop] lemma Measurable.exists [Countable ι] {p : ι → α → Prop} (hp : ∀ i, Measurable (p i)) : Measurable fun a ↦ ∃ i, p i a := - measurableSet_setOf.1 <| by rw [setOf_exists]; exact MeasurableSet.iUnion fun i ↦ (hp i).setOf + measurableSet_setOfPred.1 <| by + rw [ofPred_exists]; exact MeasurableSet.iUnion fun i ↦ (hp i).setOf end prop @[fun_prop] lemma Measurable.eq_const {_ : MeasurableSpace α} [MeasurableSpace β] [MeasurableSingletonClass β] {f : α → β} (hf : Measurable f) (a : β) : Measurable fun x => f x = a := - measurableSet_setOf.mp (measurableSet_eq.preimage hf) + measurableSet_setOfPred.mp (measurableSet_eq.preimage hf) @[fun_prop] lemma Measurable.const_eq {_ : MeasurableSpace α} [MeasurableSpace β] [MeasurableSingletonClass β] @@ -926,7 +932,11 @@ instance Set.instMeasurableSpace : MeasurableSpace (Set α) := instance Set.instMeasurableSingletonClass [Countable α] : MeasurableSingletonClass (Set α) := inferInstanceAs <| MeasurableSingletonClass (α → Prop) -@[simp, fun_prop] lemma measurable_setOf : Measurable fun p : α → Prop ↦ {a | p a} := measurable_id +@[simp, fun_prop] lemma measurable_setOfPred : + Measurable fun p : α → Prop ↦ {a | p a} := measurable_id + +@[deprecated (since := "2026-07-09")] +alias measurable_setOf := measurable_setOfPred lemma measurable_set_iff : Measurable g ↔ ∀ a, Measurable fun x ↦ a ∈ g x := measurable_pi_iff @@ -937,29 +947,35 @@ lemma measurable_set_notMem (a : α) : Measurable fun s : Set α ↦ a ∉ s := (Measurable.of_discrete (f := Not)).comp <| measurable_set_mem a lemma measurableSet_mem (a : α) : MeasurableSet {s : Set α | a ∈ s} := - measurableSet_setOf.2 <| measurable_set_mem _ + measurableSet_setOfPred.2 <| measurable_set_mem _ lemma measurableSet_notMem (a : α) : MeasurableSet {s : Set α | a ∉ s} := - measurableSet_setOf.2 <| measurable_set_notMem _ + measurableSet_setOfPred.2 <| measurable_set_notMem _ lemma measurable_compl : Measurable ((·ᶜ) : Set α → Set α) := measurable_set_iff.2 fun _ ↦ measurable_set_notMem _ variable [Countable α] -lemma MeasurableSet.setOf_finite : MeasurableSet {s : Set α | s.Finite} := - Countable.setOf_finite.measurableSet +lemma MeasurableSet.setOfPred_finite : MeasurableSet {s : Set α | s.Finite} := + Countable.ofPred_finite.measurableSet + +@[deprecated (since := "2026-07-09")] +alias MeasurableSet.setOf_finite := MeasurableSet.setOfPred_finite + +lemma MeasurableSet.setOfPred_infinite : MeasurableSet {s : Set α | s.Infinite} := + .setOfPred_finite |> .compl -lemma MeasurableSet.setOf_infinite : MeasurableSet {s : Set α | s.Infinite} := - .setOf_finite |> .compl +@[deprecated (since := "2026-07-09")] +alias MeasurableSet.setOf_infinite := MeasurableSet.setOfPred_infinite lemma MeasurableSet.sep_finite {S : Set (Set α)} (hS : MeasurableSet S) : MeasurableSet {s ∈ S | s.Finite} := - hS.inter .setOf_finite + hS.inter .setOfPred_finite lemma MeasurableSet.sep_infinite {S : Set (Set α)} (hS : MeasurableSet S) : MeasurableSet {s ∈ S | s.Infinite} := - hS.inter .setOf_infinite + hS.inter .setOfPred_infinite @[fun_prop] protected lemma Measurable.subset {s t : β → Set α} (hs : Measurable s) (hs : Measurable t) : @@ -996,10 +1012,10 @@ lemma measurable_finset_notMem (a : α) : Measurable fun s : Finset α ↦ a ∉ (measurable_set_notMem a).comp (comap_measurable _) lemma measurableSet_mem_finset (a : α) : MeasurableSet {s : Finset α | a ∈ s} := - measurableSet_setOf.2 <| measurable_finset_mem _ + measurableSet_setOfPred.2 <| measurable_finset_mem _ lemma measurableSet_notMem_finset (a : α) : MeasurableSet {s : Finset α | a ∉ s} := - measurableSet_setOf.2 <| measurable_finset_notMem _ + measurableSet_setOfPred.2 <| measurable_finset_notMem _ variable [Countable α] @@ -1071,11 +1087,11 @@ theorem measurableSet_eq_fun {m : MeasurableSpace α} [MeasurableSpace β] [Meas @[fun_prop] theorem Measurable.eq {m : MeasurableSpace α} [MeasurableSpace β] [MeasurableEq β] {f g : α → β} (hf : Measurable f) (hg : Measurable g) : Measurable fun x => f x = g x := - measurableSet_setOf.mp (measurableSet_eq_fun hf hg) + measurableSet_setOfPred.mp (measurableSet_eq_fun hf hg) instance [MeasurableSpace α] [MeasurableEq α] : MeasurableSingletonClass α := by constructor - simp_rw [← setOf_eq_eq_singleton, measurableSet_setOf] + simp_rw [← ofPred_eq_eq_singleton, measurableSet_setOfPred] measurability instance [MeasurableSpace α] [MeasurableSingletonClass α] [Countable α] : MeasurableEq α := by diff --git a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean index f55fe7f662619e..3e8032d0ffd9bf 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean @@ -403,7 +403,7 @@ theorem measurable_mapNatBool [MeasurableSpace α] [CountablyGenerated α] : rw [measurable_pi_iff] refine fun n ↦ measurable_to_bool ?_ simp only [preimage, mem_singleton_iff, mapNatBool, - Bool.decide_iff, setOf_mem_eq] + Bool.decide_iff, ofPred_mem_eq] apply measurableSet_natGeneratingSequence theorem injective_mapNatBool [MeasurableSpace α] [CountablyGenerated α] @@ -527,7 +527,7 @@ lemma generateFrom_iUnion_memPartition (t : ℕ → Set α) : rw [hun] exact MeasurableSet.univ | succ n ih => - simp only [memPartition_succ, mem_setOf_eq] at hun + simp only [memPartition_succ, mem_ofPred_eq] at hun obtain ⟨v, hv, huv⟩ := hun rcases huv with rfl | rfl · exact (ih v hv).inter (measurableSet_generateFrom ⟨n, rfl⟩) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index acec91af29c3ec..c56e525e1b2784 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -466,7 +466,7 @@ theorem measurableSet_sSup {ms : Set (MeasurableSpace α)} {s : Set α} : MeasurableSet[sSup ms] s ↔ GenerateMeasurable { s : Set α | ∃ m ∈ ms, MeasurableSet[m] s } s := by change GenerateMeasurable (⋃₀ _) _ ↔ _ - simp [← setOf_exists] + simp [← ofPred_exists] theorem measurableSet_iSup {ι} {m : ι → MeasurableSpace α} {s : Set α} : MeasurableSet[iSup m] s ↔ GenerateMeasurable { s : Set α | ∃ i, MeasurableSet[m i] s } s := by diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index a7728a5abe4265..80c70ad1f714b4 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -640,13 +640,26 @@ def ofInvolutive (f : α → α) (hf : Involutive f) (hf' : Measurable f) : α (ofInvolutive f hf hf').symm = ofInvolutive f hf hf' := rfl set_option backward.isDefEq.respectTransparency.types false in -/-- `setOf` as a `MeasurableEquiv`. -/ +/-- `Set.ofPred` as a `MeasurableEquiv`. -/ @[simps] -protected def setOf {α : Type*} : (α → Prop) ≃ᵐ Set α where +protected def setOfPred {α : Type*} : (α → Prop) ≃ᵐ Set α where toFun p := {a | p a} invFun s a := a ∈ s -@[simp, norm_cast] lemma coe_setOf {α : Type*} : ⇑MeasurableEquiv.setOf = setOf (α := α) := rfl +@[deprecated (since := "2026-07-09")] +protected alias setOf := MeasurableEquiv.setOfPred + +@[deprecated (since := "2026-07-09")] +alias setOf_apply := MeasurableEquiv.setOfPred_apply + +@[deprecated (since := "2026-07-09")] +alias setOf_symm_apply := MeasurableEquiv.setOfPred_symm_apply + +@[simp, norm_cast] lemma coe_setOfPred {α : Type*} : + ⇑MeasurableEquiv.setOfPred = Set.ofPred (α := α) := rfl + +@[deprecated (since := "2026-07-09")] +alias coe_setOf := coe_setOfPred end MeasurableEquiv diff --git a/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean index cfb6d248b68e92..5b0ea96ad8f558 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/MeasurablyGenerated.lean @@ -148,7 +148,7 @@ lemma measurableSet_tendsto {_ : MeasurableSpace β} [MeasurableSpace γ] rcases l.exists_antitone_basis with ⟨u, hu⟩ rcases (Filter.hasBasis_self.mpr hl'.exists_measurable_subset).exists_antitone_subbasis with ⟨v, v_meas, hv⟩ - simp only [hu.tendsto_iff hv.toHasBasis, true_imp_iff, true_and, setOf_forall, setOf_exists] + simp only [hu.tendsto_iff hv.toHasBasis, true_imp_iff, true_and, ofPred_forall, ofPred_exists] exact .iInter fun n ↦ .iUnion fun _ ↦ .biInter (to_countable _) fun i _ ↦ (v_meas n).2.preimage (hf i) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/NCard.lean b/Mathlib/MeasureTheory/MeasurableSpace/NCard.lean index 3c0a42348306c6..83fe980b14f8c0 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/NCard.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/NCard.lean @@ -23,7 +23,7 @@ variable {α : Type*} [Countable α] @[fun_prop] theorem measurable_encard : Measurable (Set.encard : Set α → ℕ∞) := - ENat.measurable_iff.2 fun _n ↦ Countable.measurableSet <| Countable.setOf_finite.mono fun _s hs ↦ + ENat.measurable_iff.2 fun _n ↦ Countable.measurableSet <| Countable.ofPred_finite.mono fun _s hs ↦ finite_of_encard_eq_coe hs @[fun_prop] diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Pi.lean b/Mathlib/MeasureTheory/MeasurableSpace/Pi.lean index 5e83d91a39cb5f..4137c0d7abecaa 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Pi.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Pi.lean @@ -31,7 +31,7 @@ variable {ι : Type*} {α : ι → Type*} lemma MeasurableSpace.pi_eq_generateFrom_projections {mα : ∀ i, MeasurableSpace (α i)} : pi = generateFrom {B | ∃ (i : ι) (A : Set (α i)), MeasurableSet A ∧ eval i ⁻¹' A = B} := by - simp only [pi, ← generateFrom_iUnion_measurableSet, iUnion_setOf, measurableSet_comap] + simp only [pi, ← generateFrom_iUnion_measurableSet, iUnion_ofPred, measurableSet_comap] /-- Boxes formed by π-systems form a π-system. -/ theorem IsPiSystem.pi {C : ∀ i, Set (Set (α i))} (hC : ∀ i, IsPiSystem (C i)) : diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index cd80effcb4f1be..741f7187fd28b8 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -212,7 +212,7 @@ theorem exists_ae_eq_range_subset (H : AEMeasurable f μ) {t : Set β} (ht : ∀ · simp only [g, hx, piecewise_eq_of_notMem, not_false_iff] contrapose hx apply subset_toMeasurable - simp +contextual only [hx, mem_compl_iff, mem_setOf_eq, not_and, + simp +contextual only [hx, mem_compl_iff, mem_ofPred_eq, not_and, not_false_iff, imp_true_iff] · have A : μ (toMeasurable μ { x | f x = H.mk f x ∧ f x ∈ t }ᶜ) = 0 := by rw [measure_toMeasurable, ← compl_mem_ae_iff, compl_compl] @@ -222,7 +222,7 @@ theorem exists_ae_eq_range_subset (H : AEMeasurable f μ) {t : Set β} (ht : ∀ simp only [s, g, hx, piecewise_eq_of_notMem, not_false_iff] contrapose! hx apply subset_toMeasurable - simp only [hx, mem_compl_iff, mem_setOf_eq, false_and, not_false_iff] + simp only [hx, mem_compl_iff, mem_ofPred_eq, false_and, not_false_iff] theorem exists_measurable_nonneg {β} [Preorder β] [Zero β] {mβ : MeasurableSpace β} {f : α → β} (hf : AEMeasurable f μ) (f_nn : ∀ᵐ t ∂μ, 0 ≤ f t) : ∃ g, Measurable g ∧ 0 ≤ g ∧ f =ᵐ[μ] g := by diff --git a/Mathlib/MeasureTheory/Measure/Comap.lean b/Mathlib/MeasureTheory/Measure/Comap.lean index 6f8c9b0efe3580..e1c9d6b4c55fb0 100644 --- a/Mathlib/MeasureTheory/Measure/Comap.lean +++ b/Mathlib/MeasureTheory/Measure/Comap.lean @@ -115,11 +115,11 @@ theorem ae_eq_image_of_ae_eq_comap (f : α → β) (μ : Measure β) (hfi : Inje rw [EventuallyEq, ae_iff] at hst ⊢ have h_eq_α : { a : α | ¬s a = t a } = s \ t ∪ t \ s := by ext1 x - simp only [eq_iff_iff, mem_setOf_eq, mem_union, Set.mem_sdiff] + simp only [eq_iff_iff, mem_ofPred_eq, mem_union, Set.mem_sdiff] tauto have h_eq_β : { a : β | ¬(f '' s) a = (f '' t) a } = f '' s \ f '' t ∪ f '' t \ f '' s := by ext1 x - simp only [eq_iff_iff, mem_setOf_eq, mem_union, Set.mem_sdiff] + simp only [eq_iff_iff, mem_ofPred_eq, mem_union, Set.mem_sdiff] tauto rw [← Set.image_sdiff hfi, ← Set.image_sdiff hfi, ← Set.image_union] at h_eq_β rw [h_eq_β] diff --git a/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean b/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean index 7433d4c2dd68f6..ac3c36e2ec82b4 100644 --- a/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean +++ b/Mathlib/MeasureTheory/Measure/ContinuousPreimage.lean @@ -108,7 +108,7 @@ is a closed set. In particular, if `X = Y` and `s = t`, then we see that the a.e. stabilizer of a set is a closed set. -/ -theorem isClosed_setOf_preimage_ae_eq {f : Z → C(X, Y)} (hf : Continuous f) +theorem isClosed_setOfPred_preimage_ae_eq {f : Z → C(X, Y)} (hf : Continuous f) (hfm : ∀ z, MeasurePreserving (f z) μ ν) (s : Set X) {t : Set Y} (htm : NullMeasurableSet t ν) (ht : ν t ≠ ∞) : IsClosed {z | f z ⁻¹' t =ᵐ[μ] s} := by @@ -123,4 +123,7 @@ theorem isClosed_setOf_preimage_ae_eq {f : Z → C(X, Y)} (hf : Continuous f) rw [measure_congr (hw'.symmDiff (ae_eq_refl _)), symmDiff_comm] at hw exact hw.false +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_preimage_ae_eq := isClosed_setOfPred_preimage_ae_eq + end MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean b/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean index 1a0daa3c7fba7e..c0208fbb633ae9 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean @@ -168,7 +168,7 @@ lemma _root_.ConvexOn.apply_rnDeriv_ae_le_integral (hf : StronglyMeasurable f) have h_compProd : (fun p ↦ μ.rnDeriv ν p.1 * (μ ⊗ₘ κ).rnDeriv (μ ⊗ₘ η) p) =ᵐ[ν ⊗ₘ η] (μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) := (rnDeriv_compProd hκη ν).symm rwa [Filter.EventuallyEq, Measure.ae_compProd_iff] at h_compProd - simp only [measurableSet_setOf] + simp only [measurableSet_setOfPred] fun_prop filter_upwards [h_ae1, h_ae2, h_lt_top, h_integrable.1, h_int.1] with a h_eq_one h_mul_eq h_lt_top h_int' h_int diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean index 810ec64d0ba490..090e050b682153 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean @@ -779,7 +779,7 @@ theorem sup_mem_measurableLE {f g : α → ℝ≥0∞} (hf : f ∈ measurableLE have h₂ := hA.inter (measurableSet_lt hg.1 hf.1) rw [setLIntegral_max hf.1 hg.1] refine (add_le_add (hg.2 _ h₁) (hf.2 _ h₂)).trans_eq ?_ - simp only [← not_le, ← compl_setOf, ← sdiff_eq] + simp only [← not_le, ← compl_ofPred, ← sdiff_eq] exact measure_inter_add_sdiff _ (measurableSet_le hf.1 hg.1) theorem iSup_succ_eq_sup {α} (f : ℕ → α → ℝ≥0∞) (m : ℕ) (a : α) : diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean index 5540b54c0eb58a..99c22bff668a4f 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean @@ -338,7 +338,7 @@ lemma measurableSet_isFiniteMeasure : MeasurableSet { μ : Measure Ω | IsFinite rw [this] exact Measure.measurable_coe MeasurableSet.univ measurableSet_Ico ext μ - simp only [mem_setOf_eq, mem_preimage, mem_Ico, zero_le, true_and] + simp only [mem_ofPred_eq, mem_preimage, mem_Ico, zero_le, true_and] exact isFiniteMeasure_iff μ /-- The monoidal product is a measurable function from the product of finite measures over @@ -354,7 +354,7 @@ theorem measurable_fun_prod {α β : Type*} [MeasurableSpace α] [MeasurableSpac ((Measure.measurable_coe Hv).comp (measurable_subtype_coe.comp measurable_snd)) apply Measurable.measure_of_isPiSystem generateFrom_prod.symm isPiSystem_prod _ · simp_rw [← Set.univ_prod_univ, Measure.prod_prod, Heval MeasurableSet.univ MeasurableSet.univ] - simp only [mem_image2, mem_setOf_eq, forall_exists_index, and_imp] + simp only [mem_image2, mem_ofPred_eq, forall_exists_index, and_imp] intro _ _ Hu _ Hv Heq simp_rw [← Heq, Measure.prod_prod, Heval Hu Hv] @@ -991,7 +991,7 @@ lemma Topology.IsClosedEmbedding.isEmbedding_map_finiteMeasure {Ω : Type*} let B : FiniteMeasure Ω ≃ₜ M := { toFun μ := by refine ⟨μ.map f, ?_⟩ - simp only [null_iff_toMeasure_null, mem_setOf_eq, toMeasure_map, M] + simp only [null_iff_toMeasure_null, mem_ofPred_eq, toMeasure_map, M] rw [Measure.map_apply hf.continuous.measurable hf.isClosed_range.isOpen_compl.measurableSet] simp invFun := M.restrict (fun μ ↦ μ.comap f) diff --git a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean index 070a704d452ef9..db04f2087be649 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Basic.lean @@ -125,7 +125,7 @@ def haarProduct (K₀ : Set G) : Set (Compacts G → ℝ) := @[to_additive (attr := simp)] theorem mem_prehaar_empty {K₀ : Set G} {f : Compacts G → ℝ} : f ∈ haarProduct K₀ ↔ ∀ K : Compacts G, f K ∈ Icc (0 : ℝ) (index (K : Set G) K₀) := by - simp only [haarProduct, Set.pi, forall_prop_of_true, mem_univ, mem_setOf_eq] + simp only [haarProduct, Set.pi, forall_prop_of_true, mem_univ, mem_ofPred_eq] /-- The closure of the collection of elements of the form `prehaar K₀ U`, for `U` open neighbourhoods of `1`, contained in `V`. The closure is taken in the space @@ -166,7 +166,7 @@ theorem le_index_mul (K₀ : PositiveCompacts G) (K : Compacts G) {V : Set G} obtain ⟨t, h1t, h2t⟩ := index_elim K₀.isCompact hV rw [← h2s, ← h2t, mul_comm] refine le_trans ?_ Finset.card_mul_le - apply Nat.sInf_le; refine ⟨_, ?_, rfl⟩; rw [mem_setOf_eq]; refine Subset.trans h1s ?_ + apply Nat.sInf_le; refine ⟨_, ?_, rfl⟩; rw [mem_ofPred_eq]; refine Subset.trans h1s ?_ apply iUnion₂_subset; intro g₁ hg₁; rw [preimage_subset_iff]; intro g₂ hg₂ have := h1t hg₂ rcases this with ⟨_, ⟨g₃, rfl⟩, A, ⟨hg₃, rfl⟩, h2V⟩; rw [mem_preimage, ← mul_assoc] at h2V @@ -199,7 +199,7 @@ theorem index_union_le (K₁ K₂ : Compacts G) {V : Set G} (hV : (interior V).N rcases index_elim K₂.2 hV with ⟨t, h1t, h2t⟩ rw [← h2s, ← h2t] refine le_trans (Nat.sInf_le ⟨_, ?_, rfl⟩) (Finset.card_union_le _ _) - rw [mem_setOf_eq, Finset.set_biUnion_union] + rw [mem_ofPred_eq, Finset.set_biUnion_union] gcongr @[to_additive addIndex_union_eq] @@ -211,7 +211,7 @@ theorem index_union_eq (K₁ K₂ : Compacts G) {V : Set G} (hV : (interior V).N rcases index_elim (K₁.2.union K₂.2) hV with ⟨s, h1s, h2s⟩; rw [← h2s] have (K : Set G) (hK : K ⊆ ⋃ g ∈ s, (g * ·) ⁻¹' V) : index K V ≤ {g ∈ s | ((g * ·) ⁻¹' V ∩ K).Nonempty}.card := by - apply Nat.sInf_le; refine ⟨_, ?_, rfl⟩; rw [mem_setOf_eq] + apply Nat.sInf_le; refine ⟨_, ?_, rfl⟩; rw [mem_ofPred_eq] intro g hg; rcases hK hg with ⟨_, ⟨g₀, rfl⟩, _, ⟨h1g₀, rfl⟩, h2g₀⟩ simp only [mem_preimage] at h2g₀ simp only [mem_iUnion]; use g₀; constructor; swap @@ -242,7 +242,7 @@ theorem mul_left_index_le {K : Set G} (hK : IsCompact K) {V : Set G} (hV : (inte rcases index_elim hK hV with ⟨s, h1s, h2s⟩; rw [← h2s] apply Nat.sInf_le; rw [mem_image] refine ⟨s.map (Equiv.mulRight g⁻¹).toEmbedding, ?_, Finset.card_map _⟩ - simp only [mem_setOf_eq]; refine Subset.trans (image_mono h1s) ?_ + simp only [mem_ofPred_eq]; refine Subset.trans (image_mono h1s) ?_ rintro _ ⟨g₁, ⟨_, ⟨g₂, rfl⟩, ⟨_, ⟨hg₂, rfl⟩, hg₁⟩⟩, rfl⟩ simp only [mem_preimage] at hg₁ simp only [exists_prop, mem_iUnion, Finset.mem_map, Equiv.coe_mulRight, @@ -334,7 +334,7 @@ theorem nonempty_iInter_clPrehaar (K₀ : PositiveCompacts G) : constructor · apply prehaar_mem_haarProduct K₀; use 1; rwa [h1V₀.interior_eq] · simp only [mem_iInter]; rintro ⟨V, hV⟩ h2V; apply subset_closure - apply mem_image_of_mem; rw [mem_setOf_eq] + apply mem_image_of_mem; rw [mem_ofPred_eq] exact ⟨Subset.trans (iInter_subset _ ⟨V, hV⟩) (iInter_subset _ h2V), h1V₀, h2V₀⟩ /-! diff --git a/Mathlib/MeasureTheory/Measure/Haar/Extension.lean b/Mathlib/MeasureTheory/Measure/Haar/Extension.lean index c70206c3b5b12e..39f6ec2c5ad007 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Extension.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Extension.lean @@ -117,7 +117,7 @@ noncomputable def pushforward : have h (a) (ha : a ∈ S) : edist (H.pullback f (t * b) a) (H.pullback f b a) ≤ .ofReal δ := by rw [edist_dist] exact ENNReal.ofReal_le_ofReal (@hf ⟨t * b * φ a, b * φ a⟩ (by simpa)).le - grw [Set.mem_setOf_eq, dist_integral_le_lintegral_edist (H.pullback f (t * b)).integrable + grw [Set.mem_ofPred_eq, dist_integral_le_lintegral_edist (H.pullback f (t * b)).integrable (H.pullback f b).integrable, ← setLIntegral_eq_of_support_subset] · refine ENNReal.toReal_lt_of_lt_ofReal ((setLIntegral_mono measurable_const h).trans_lt ?_) rwa [lintegral_const, restrict_apply_univ] diff --git a/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean b/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean index 7c394e6dd3b6fb..76ce2932f05eac 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/OfBasis.lean @@ -59,7 +59,7 @@ theorem parallelepiped_basis_eq (b : Basis ι ℝ E) : parallelepiped b = {x | ∀ i, b.repr x i ∈ Set.Icc 0 1} := by classical ext x - simp_rw [mem_parallelepiped_iff, mem_setOf_eq, b.ext_elem_iff, _root_.map_sum, + simp_rw [mem_parallelepiped_iff, mem_ofPred_eq, b.ext_elem_iff, _root_.map_sum, map_smul, Finset.sum_apply', Basis.repr_self, Finsupp.smul_single, smul_eq_mul, mul_one, Finsupp.single_apply, Finset.sum_ite_eq', Finset.mem_univ, ite_true, mem_Icc, Pi.le_def, Pi.zero_apply, Pi.one_apply, ← forall_and] diff --git a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean index 1d5afce3f30b57..caaaa7c755bcca 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean @@ -741,7 +741,7 @@ theorem measure_isHaarMeasure_eq_smul_of_isEverywherePos [LocallyCompactSpace G] refine ⟨⋃ a ∈ c, a, ⟨?_, ?_⟩, ?_⟩ · simp only [iUnion_subset_iff] intro a ac x hx - simp only [A, subset_def, mem_setOf_eq] at cA + simp only [A, subset_def, mem_ofPred_eq] at cA exact (cA _ ac).1 x hx · rintro x hx y hy hxy simp only [mem_iUnion, exists_prop] at hx hy diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean index 741040d515ebac..3fd4ab3dd1c2ac 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean @@ -90,9 +90,9 @@ lemma ext_of_lintegral_prod_mul_prod_boundedContinuousFunction rintro - ⟨-, ⟨s₁, hs₁, rfl⟩, -, ⟨t₁, ht₁, rfl⟩, rfl⟩ - ⟨-, ⟨s₂, hs₂, rfl⟩, -, ⟨t₂, ht₂, rfl⟩, rfl⟩ - refine ⟨_, ⟨fun i ↦ s₁ i ∩ s₂ i, ?_, rfl⟩, _, ⟨fun j ↦ t₁ j ∩ t₂ j, ?_, rfl⟩, ?_⟩ - · simp only [Set.mem_pi, mem_univ, mem_setOf_eq, forall_const] at hs₁ hs₂ ⊢ + · simp only [Set.mem_pi, mem_univ, mem_ofPred_eq, forall_const] at hs₁ hs₂ ⊢ exact fun i ↦ (hs₁ i).inter (hs₂ i) - · simp only [Set.mem_pi, mem_univ, mem_setOf_eq, forall_const] at ht₁ ht₂ ⊢ + · simp only [Set.mem_pi, mem_univ, mem_ofPred_eq, forall_const] at ht₁ ht₂ ⊢ exact fun j ↦ (ht₁ j).inter (ht₂ j) simp [Set.pi_inter_distrib, Set.prod_inter_prod] have hπ2 : Prod.instMeasurableSpace = generateFrom π := by @@ -108,7 +108,7 @@ lemma ext_of_lintegral_prod_mul_prod_boundedContinuousFunction · exact ⟨fun _ ↦ Set.univ, fun _ ↦ ⟨fun _ ↦ Set.univ, by simp, by simp⟩, iUnion_const _⟩ refine ext_of_generate_finite π hπ2 hπ1 ?_ hμν rintro - ⟨-, ⟨s, hs, rfl⟩, -, ⟨t, ht, rfl⟩, rfl⟩ - simp only [Set.mem_pi, mem_univ, mem_setOf_eq, forall_const] at hs ht + simp only [Set.mem_pi, mem_univ, mem_ofPred_eq, forall_const] at hs ht have (p : (Π i, X i) × (Π j, Y j)) := ENNReal.continuous_coe.tendsto _ |>.comp <| (tendsto_finsetProd Finset.univ (fun i _ ↦ tendsto_pi_nhds.1 (HasOuterApproxClosed.tendsto_apprSeq (hs i)) (p.1 i))).mul diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 914dd8efc0b228..da41388c14e8c8 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -327,7 +327,7 @@ theorem mkMetric_mono_smul {m₁ m₂ : ℝ≥0∞ → ℝ≥0∞} {c : ℝ≥0 le_of_tendsto_of_tendsto (mkMetric'.tendsto_pre _ s) (ENNReal.Tendsto.const_mul (mkMetric'.tendsto_pre _ s) (Or.inr hc)) (mem_of_superset (Ioo_mem_nhdsGT hr0) fun r' hr' => ?_) - simp only [mem_setOf_eq, mkMetric'.pre] + simp only [mem_ofPred_eq, mkMetric'.pre] rw [← smul_eq_mul, ← smul_apply, smul_boundedBy hc] refine le_boundedBy.2 (fun t => (boundedBy_le _).trans ?_) _ simp only [smul_eq_mul, Pi.smul_apply, extend, iInf_eq_if] diff --git a/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean b/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean index cae25b2ff94c6a..dabe96f4ec7c91 100644 --- a/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean +++ b/Mathlib/MeasureTheory/Measure/IntegralCharFun.lean @@ -98,7 +98,7 @@ lemma measureReal_abs_gt_le_integral_charFun [IsProbabilityMeasure μ] (hr : 0 < calc μ.real {x | r < |x|} _ = μ.real {x | 2 < |2 * r⁻¹ * x|} := by congr 1 with x - simp only [Set.mem_setOf_eq, abs_mul, Nat.abs_ofNat] + simp only [Set.mem_ofPred_eq, abs_mul, Nat.abs_ofNat] rw [abs_of_nonneg (a := r⁻¹) (by positivity), mul_assoc, ← inv_mul_lt_iff₀ (by positivity), inv_mul_cancel₀ (by positivity), lt_inv_mul_iff₀ (by positivity), mul_one] _ = ∫ x in {x | 2 < |2 * r⁻¹ * x|}, 1 ∂μ := by simp @@ -114,7 +114,7 @@ lemma measureReal_abs_gt_le_integral_charFun [IsProbabilityMeasure μ] (hr : 0 < · exact MeasurableSet.preimage measurableSet_Ioi (by fun_prop) · have hx_ne : 2 * r⁻¹ * x ≠ 0 := by intro hx0 - simp only [hx0, Set.mem_setOf_eq, abs_zero] at hx + simp only [hx0, Set.mem_ofPred_eq, abs_zero] at hx linarith rw [le_sub_iff_add_le, ← le_sub_iff_add_le'] norm_num diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean index e1301292f1006f..d6538e19f43682 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean @@ -453,14 +453,14 @@ def regionBetween (f g : α → ℝ) (s : Set α) : Set (α × ℝ) := { p : α × ℝ | p.1 ∈ s ∧ p.2 ∈ Ioo (f p.1) (g p.1) } theorem regionBetween_subset (f g : α → ℝ) (s : Set α) : regionBetween f g s ⊆ s ×ˢ univ := by - simpa only [prod_univ, regionBetween, Set.preimage, setOf_subset_setOf] using fun a => And.left + simpa only [prod_univ, regionBetween, Set.preimage, ofPred_subset_ofPred] using fun a => And.left variable [MeasurableSpace α] {μ : Measure α} {f g : α → ℝ} {s : Set α} /-- The region between two measurable functions on a measurable set is measurable. -/ theorem measurableSet_regionBetween (hf : Measurable f) (hg : Measurable g) (hs : MeasurableSet s) : MeasurableSet (regionBetween f g s) := by - dsimp only [regionBetween, Ioo, mem_setOf_eq, setOf_and] + dsimp only [regionBetween, Ioo, mem_ofPred_eq, ofPred_and] refine MeasurableSet.inter ?_ ((measurableSet_lt (hf.comp measurable_fst) measurable_snd).inter @@ -472,7 +472,7 @@ a version for the region together with the graph of the upper function. -/ theorem measurableSet_region_between_oc (hf : Measurable f) (hg : Measurable g) (hs : MeasurableSet s) : MeasurableSet { p : α × ℝ | p.fst ∈ s ∧ p.snd ∈ Ioc (f p.fst) (g p.fst) } := by - dsimp only [regionBetween, Ioc, mem_setOf_eq, setOf_and] + dsimp only [regionBetween, Ioc, mem_ofPred_eq, ofPred_and] refine MeasurableSet.inter ?_ ((measurableSet_lt (hf.comp measurable_fst) measurable_snd).inter @@ -484,7 +484,7 @@ a version for the region together with the graph of the lower function. -/ theorem measurableSet_region_between_co (hf : Measurable f) (hg : Measurable g) (hs : MeasurableSet s) : MeasurableSet { p : α × ℝ | p.fst ∈ s ∧ p.snd ∈ Ico (f p.fst) (g p.fst) } := by - dsimp only [regionBetween, Ico, mem_setOf_eq, setOf_and] + dsimp only [regionBetween, Ico, mem_ofPred_eq, ofPred_and] refine MeasurableSet.inter ?_ ((measurableSet_le (hf.comp measurable_fst) measurable_snd).inter @@ -496,7 +496,7 @@ a version for the region together with the graphs of both functions. -/ theorem measurableSet_region_between_cc (hf : Measurable f) (hg : Measurable g) (hs : MeasurableSet s) : MeasurableSet { p : α × ℝ | p.fst ∈ s ∧ p.snd ∈ Icc (f p.fst) (g p.fst) } := by - dsimp only [regionBetween, Icc, mem_setOf_eq, setOf_and] + dsimp only [regionBetween, Icc, mem_ofPred_eq, ofPred_and] refine MeasurableSet.inter ?_ ((measurableSet_le (hf.comp measurable_fst) measurable_snd).inter @@ -523,7 +523,7 @@ theorem volume_regionBetween_eq_lintegral' (hf : Measurable f) (hg : Measurable simp only [hx, Real.volume_Ioo] · have hx : { a | x ∈ s ∧ a ∈ Ioo (f x) (g x) } = ∅ := by simp [h] simp only [hx, measure_empty] - dsimp only [regionBetween, preimage_setOf_eq] + dsimp only [regionBetween, preimage_ofPred_eq] rw [h, lintegral_indicator] <;> simp only [hs, Pi.sub_apply] · exact measurableSet_regionBetween hf hg hs diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean index 2aeca2034d8903..0443714debdab2 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean @@ -192,11 +192,11 @@ theorem MeasureTheory.volume_sum_rpow_lt [Nonempty ι] {p : ℝ} (hp : 1 ≤ p) · have : {x : ι → ℝ | (∑ i, |x i| ^ p) ^ (1 / p) < r} = ∅ := by ext x refine ⟨fun hx => ?_, fun hx => hx.elim⟩ - exact not_le.mpr (lt_of_lt_of_le (Set.mem_setOf.mp hx) hr) (h₂ x) + exact not_le.mpr (lt_of_lt_of_le (Set.mem_ofPred.mp hx) hr) (h₂ x) rw [this, measure_empty, ← zero_eq_ofReal.mpr hr, zero_pow Fin.pos'.ne', zero_mul] · rw [← volume_sum_rpow_lt_one _ hp, ← ofReal_pow (le_of_lt hr), ← finrank_pi ℝ] convert! addHaar_smul_of_nonneg volume (le_of_lt hr) {x : ι → ℝ | ∑ i, |x i| ^ p < 1} using 2 - simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hr), Set.preimage_setOf_eq, Pi.smul_apply, + simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hr), Set.preimage_ofPred_eq, Pi.smul_apply, smul_eq_mul, abs_mul, mul_rpow (abs_nonneg _) (abs_nonneg _), abs_inv, inv_rpow (abs_nonneg _), ← Finset.mul_sum, abs_eq_self.mpr (le_of_lt hr), inv_mul_lt_iff₀ (rpow_pos_of_pos hr _), mul_one, ← rpow_lt_rpow_iff @@ -267,11 +267,11 @@ theorem Complex.volume_sum_rpow_lt [Nonempty ι] {p : ℝ} (hp : 1 ≤ p) (r : · have : {x : ι → ℂ | (∑ i, ‖x i‖ ^ p) ^ (1 / p) < r} = ∅ := by ext x refine ⟨fun hx => ?_, fun hx => hx.elim⟩ - exact not_le.mpr (lt_of_lt_of_le (Set.mem_setOf.mp hx) hr) (h₂ x) + exact not_le.mpr (lt_of_lt_of_le (Set.mem_ofPred.mp hx) hr) (h₂ x) rw [this, measure_empty, ← zero_eq_ofReal.mpr hr, zero_pow Fin.pos'.ne', zero_mul] · rw [← Complex.volume_sum_rpow_lt_one _ hp, ← ENNReal.ofReal_pow (le_of_lt hr)] convert! addHaar_smul_of_nonneg volume (le_of_lt hr) {x : ι → ℂ | ∑ i, ‖x i‖ ^ p < 1} using 2 - · simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hr), Set.preimage_setOf_eq, Pi.smul_apply, + · simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hr), Set.preimage_ofPred_eq, Pi.smul_apply, norm_smul, mul_rpow (norm_nonneg _) (norm_nonneg _), Real.norm_eq_abs, abs_inv, inv_rpow (abs_nonneg _), ← Finset.mul_sum, abs_eq_self.mpr (le_of_lt hr), inv_mul_lt_iff₀ (rpow_pos_of_pos hr _), mul_one, ← rpow_lt_rpow_iff (rpow_nonneg (h₁ _) _) @@ -319,7 +319,7 @@ theorem volume_ball (x : EuclideanSpace ℝ ι) (r : ℝ) : rw [Measure.addHaar_ball _ _ hr, this, ofReal_pow hr, finrank_euclideanSpace] rw [← (PiLp.volume_preserving_toLp ι).measure_preimage measurableSet_ball.nullMeasurableSet] - simp only [Set.preimage, ball_zero_eq _ zero_le_one, one_pow, Set.mem_setOf_eq] + simp only [Set.preimage, ball_zero_eq _ zero_le_one, one_pow, Set.mem_ofPred_eq] convert! volume_sum_rpow_lt_one ι one_le_two using 4 · simp [sq_abs] · rw [Gamma_add_one (by simp), Gamma_one_half_eq, ← mul_assoc, mul_div_cancel₀ _ diff --git a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean index 7eef5b97a235c9..d3241ac9bf8c59 100644 --- a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean +++ b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean @@ -528,7 +528,7 @@ lemma ProbabilityMeasure.toMeasure_add_pos_gt_mem_nhds (P : ProbabilityMeasure · exact ε_pos.ne.symm filter_upwards [gt_mem_sets_of_limsInf_gt (α := ℝ≥0∞) isBounded_ge_of_bot (show P.toMeasure G - ε < limsInf ((𝓝 P).map (fun Q ↦ Q.toMeasure G)) from aux)] with Q hQ - simp only [preimage_setOf_eq, mem_setOf_eq] at hQ + simp only [preimage_ofPred_eq, mem_ofPred_eq] at hQ convert! ENNReal.add_lt_add_right ε_top hQ exact (tsub_add_cancel_of_le easy).symm @@ -609,7 +609,7 @@ lemma continuous_ofMeasure_probabilityMeasure : -- we have `P (Gs J) < Q (Gs J) + ε/3`. filter_upwards [(Finset.iInter_mem_sets Js_finite.toFinset).mpr <| fun J _ ↦ mem_nhds_P _ (Gs_open J)] with Q hQ - simp only [Finite.mem_toFinset, mem_setOf_eq, thickening_iUnion, mem_iInter] at hQ + simp only [Finite.mem_toFinset, mem_ofPred_eq, thickening_iUnion, mem_iInter] at hQ -- Note that in order to show that the Lévy-Prokhorov distance between `P` and `Q` is small -- (`≤ 2*ε/3`), it suffices to show that for arbitrary subsets `B ⊆ Ω`, the measure `P B` is -- bounded above up to a small error by the `Q`-measure of a small thickening of `B`. @@ -639,7 +639,7 @@ lemma continuous_ofMeasure_probabilityMeasure : simp only [mem_Ici, mem_union, mem_iUnion, exists_prop] by_cases i_small : i ∈ Iio N · refine Or.inl ⟨i, ?_, self_subset_thickening third_ε_pos _ hi⟩ - simp only [mem_Iio, mem_setOf_eq, JB] + simp only [mem_Iio, mem_ofPred_eq, JB] exact ⟨Set.nonempty_of_mem <| mem_inter ω_in_B hi, i_small⟩ · exact Or.inr ⟨i, by simpa only [mem_Iio, not_lt] using i_small, hi⟩ have subset_thickB : ⋃ i ∈ JB, thickening (ε / 3) (Es i) ⊆ thickening δ B := by diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 6bc4c96d4b6017..4abf42905cf002 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -1226,7 +1226,7 @@ lemma inf_apply {s : Set α} (hs : MeasurableSet s) : obtain ⟨i, hi⟩ := mem_iUnion.1 <| ht' hx₂ refine ⟨i, ?_, hi⟩ by_contra h - simp only [mem_setOf_eq, not_lt] at h + simp only [mem_ofPred_eq, not_lt] at h exact mem_iInter₂.1 hx₁ i h hi have hle₂ : ν (tᶜ ∩ s) ≤ ∑' (n : {k | ν (t' k) < μ (t' k)}), ν (t' n) := (measure_mono hcap).trans (measure_biUnion_le ν (to_countable {k | ν (t' k) < μ (t' k)}) _) @@ -1240,11 +1240,11 @@ lemma inf_apply {s : Set α} (hs : MeasurableSet s) : intro n hn; simpa · rw [Subtype.forall] intro n hn - rw [mem_setOf_eq] at hn + rw [mem_ofPred_eq] at hn simp [le_of_lt hn] · rw [Set.disjoint_iff] rintro k ⟨hk₁, hk₂⟩ - rw [mem_setOf_eq] at hk₁ hk₂ + rw [mem_ofPred_eq] at hk₁ hk₂ exact False.elim <| hk₂.not_ge hk₁ @[simp] diff --git a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean index e6393e4c823ec9..96049a26d29acb 100644 --- a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean @@ -234,7 +234,7 @@ set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma range_toFiniteMeasure : range toFiniteMeasure = {μ : FiniteMeasure Ω | μ.mass = 1} := by ext μ - simp only [mem_range, mem_setOf_eq] + simp only [mem_range, mem_ofPred_eq] refine ⟨fun ⟨ν, hν⟩ ↦ by simp [← hν], fun h ↦ ?_⟩ refine ⟨⟨μ, isProbabilityMeasure_iff_real.2 (by simpa using! h)⟩, ?_⟩ ext s hs @@ -263,7 +263,7 @@ theorem measurable_fun_prod {α β : Type*} [MeasurableSpace α] [MeasurableSpac ↦ μ.1.toMeasure.prod μ.2.toMeasure) := by apply Measurable.measure_of_isPiSystem_of_isProbabilityMeasure generateFrom_prod.symm isPiSystem_prod _ - simp only [mem_image2, mem_setOf_eq, forall_exists_index, and_imp] + simp only [mem_image2, mem_ofPred_eq, forall_exists_index, and_imp] intro _ u Hu v Hv Heq simp_rw [← Heq, Measure.prod_prod] apply Measurable.mul diff --git a/Mathlib/MeasureTheory/Measure/Prod.lean b/Mathlib/MeasureTheory/Measure/Prod.lean index cf5dd69edca651..25c0a0fb7a00de 100644 --- a/Mathlib/MeasureTheory/Measure/Prod.lean +++ b/Mathlib/MeasureTheory/Measure/Prod.lean @@ -763,7 +763,7 @@ theorem prodAssoc_prod [SFinite τ] : isPiSystem_measurableSet isPiSystem_prod ((sfiniteSeq μ i.1.1)).toFiniteSpanningSetsIn ((sfiniteSeq ν i.1.2).toFiniteSpanningSetsIn.prod (sfiniteSeq τ i.2).toFiniteSpanningSetsIn) ?_).symm - rintro s hs _ ⟨t, ht, u, hu, rfl⟩; rw [mem_setOf_eq] at hs ht hu + rintro s hs _ ⟨t, ht, u, hu, rfl⟩; rw [mem_ofPred_eq] at hs ht hu simp_rw [map_apply (MeasurableEquiv.measurable _) (hs.prod (ht.prod hu)), MeasurableEquiv.prodAssoc, MeasurableEquiv.coe_mk, Equiv.prod_assoc_preimage, prod_prod, mul_assoc] diff --git a/Mathlib/MeasureTheory/Measure/Prokhorov.lean b/Mathlib/MeasureTheory/Measure/Prokhorov.lean index 41ce40cac6a1d7..c6712ca53eaf3d 100644 --- a/Mathlib/MeasureTheory/Measure/Prokhorov.lean +++ b/Mathlib/MeasureTheory/Measure/Prokhorov.lean @@ -22,7 +22,7 @@ notably several versions of Prokhorov theorem on tight sets of probability measu * `instCompactSpaceProbabilityMeasure` proves that the space of probability measures on a compact space is itself compact -* `isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le`: Given a sequence of compact +* `isCompact_setOfPred_probabilityMeasure_mass_eq_compl_isCompact_le`: Given a sequence of compact sets `Kₙ` and a sequence `uₙ` tending to zero, the probability measures giving mass at most `uₙ` to the complement of `Kₙ` form a compact set. * `isCompact_closure_of_isTightMeasureSet`: Given a tight set of probability measures, its closure @@ -40,7 +40,7 @@ For the compactness of the space of probability measures in a compact space, we ultrafilter converges, using the Riesz-Markov-Kakutani theorem to construct the limiting measure in terms of its integrals against continuous functions. -For Prokhorov theorem `isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le`, +For Prokhorov theorem `isCompact_setOfPred_probabilityMeasure_mass_eq_compl_isCompact_le`, we rely on the compactness of the space of measures inside each compact set to get convergence of the restriction there, and argue that the full measure converges to the sum of the individual limits of the disjointed components. There is a subtlety that the space of finite measures @@ -67,7 +67,7 @@ variable {E : Type*} [MeasurableSpace E] [TopologicalSpace E] [T2Space E] [Borel set_option backward.isDefEq.respectTransparency.types false in variable (E) in /-- In a compact space, the set of finite measures with mass at most `C` is compact. -/ -theorem isCompact_setOf_finiteMeasure_le_of_compactSpace [CompactSpace E] (C : ℝ≥0) : +theorem isCompact_setOfPred_finiteMeasure_le_of_compactSpace [CompactSpace E] (C : ℝ≥0) : IsCompact {μ : FiniteMeasure E | μ.mass ≤ C} := by /- To prove the compactness, we will show that any sequence has a converging subsequence, in ultrafilters terms as things are not second countable. The integral against any bounded continuous @@ -142,7 +142,7 @@ theorem isCompact_setOf_finiteMeasure_le_of_compactSpace [CompactSpace E] (C : filter_upwards [hf] with μ hμ using by simpa [o] using! hμ let μlim' : FiniteMeasure E := ⟨μlim, ⟨μlim_le.trans_lt (by simp)⟩⟩ refine ⟨μlim', ?_, ?_⟩ - · simp only [mem_setOf_eq, FiniteMeasure.mk_apply, μlim', FiniteMeasure.mass] + · simp only [mem_ofPred_eq, FiniteMeasure.mk_apply, μlim', FiniteMeasure.mass] rw [show C = (ENNReal.ofReal ↑C).toNNReal by simp] exact ENNReal.toNNReal_mono (by simp) μlim_le change Tendsto id f (𝓝 μlim') @@ -155,24 +155,32 @@ theorem isCompact_setOf_finiteMeasure_le_of_compactSpace [CompactSpace E] (C : simp only [FiniteMeasure.toMeasure_mk, RealRMK.integral_rieszMeasure, μlim', μlim] rfl +@[deprecated (since := "2026-07-09")] +alias isCompact_setOf_finiteMeasure_le_of_compactSpace := + isCompact_setOfPred_finiteMeasure_le_of_compactSpace + variable (E) in /-- In a compact space, the set of finite measures with mass `C` is compact. -/ -lemma isCompact_setOf_finiteMeasure_eq_of_compactSpace [CompactSpace E] (C : ℝ≥0) : +lemma isCompact_setOfPred_finiteMeasure_eq_of_compactSpace [CompactSpace E] (C : ℝ≥0) : IsCompact {μ : FiniteMeasure E | μ.mass = C} := by have : {μ : FiniteMeasure E | μ.mass = C} = {μ | μ.mass ≤ C} ∩ {μ | μ.mass = C} := by grind rw [this] - apply IsCompact.inter_right (isCompact_setOf_finiteMeasure_le_of_compactSpace E C) + apply IsCompact.inter_right (isCompact_setOfPred_finiteMeasure_le_of_compactSpace E C) exact isClosed_eq (by fun_prop) (by fun_prop) +@[deprecated (since := "2026-07-09")] +alias isCompact_setOf_finiteMeasure_eq_of_compactSpace := + isCompact_setOfPred_finiteMeasure_eq_of_compactSpace + /-- In a compact space, the space of probability measures is also compact. -/ instance [CompactSpace E] : CompactSpace (ProbabilityMeasure E) := by constructor apply (ProbabilityMeasure.toFiniteMeasure_isEmbedding E).isCompact_iff.2 - simpa using isCompact_setOf_finiteMeasure_eq_of_compactSpace E 1 + simpa using isCompact_setOfPred_finiteMeasure_eq_of_compactSpace E 1 /-- The set of finite measures of mass at most `C` supported on a given compact set `K` is compact. -/ -lemma isCompact_setOf_finiteMeasure_le_of_isCompact +lemma isCompact_setOfPred_finiteMeasure_le_of_isCompact (C : ℝ≥0) {K : Set E} (hK : IsCompact K) : IsCompact {μ : FiniteMeasure E | μ.mass ≤ C ∧ μ Kᶜ = 0} := by let f : K → E := Subtype.val @@ -196,20 +204,24 @@ lemma isCompact_setOf_finiteMeasure_le_of_isCompact exact hμ.2 · exact fun t ht ↦ hf.measurableEmbedding.measurableSet_image' ht · exact hf.continuous.measurable hs - · simp only [null_iff_toMeasure_null, image_subset_iff, preimage_setOf_eq, toMeasure_map, - setOf_subset_setOf, F, T] + · simp only [null_iff_toMeasure_null, image_subset_iff, preimage_ofPred_eq, toMeasure_map, + ofPred_subset_ofPred, F, T] intro μ hμ rw [Measure.map_apply hf.continuous.measurable hK.measurableSet.compl] refine ⟨(mass_map_le _ _).trans hμ, by simp [f]⟩ rw [this] apply IsCompact.image _ (by fun_prop) have : CompactSpace K := isCompact_iff_compactSpace.mp hK - exact isCompact_setOf_finiteMeasure_le_of_compactSpace _ _ + exact isCompact_setOfPred_finiteMeasure_le_of_compactSpace _ _ + +@[deprecated (since := "2026-07-09")] +alias isCompact_setOf_finiteMeasure_le_of_isCompact := + isCompact_setOfPred_finiteMeasure_le_of_isCompact /-- **Prokhorov theorem**: Given a sequence of compact sets `Kₙ` and a sequence `uₙ` tending to zero, the finite measures of mass at most `C` giving mass at most `uₙ` to the complement of `Kₙ` form a compact set. -/ -lemma isCompact_setOf_finiteMeasure_mass_le_compl_isCompact_le +lemma isCompact_setOfPred_finiteMeasure_mass_le_compl_isCompact_le {u : ℕ → ℝ≥0} {K : ℕ → Set E} (C : ℝ≥0) (hu : Tendsto u atTop (𝓝 0)) (hK : ∀ n, IsCompact (K n)) (h : NormalSpace E ∨ Monotone K) : IsCompact {μ : FiniteMeasure E | μ.mass ≤ C ∧ ∀ n, μ (K n)ᶜ ≤ u n} := by @@ -251,8 +263,8 @@ lemma isCompact_setOf_finiteMeasure_mass_le_compl_isCompact_le simp only [Tendsto] rw [← Ultrafilter.coe_map] apply IsCompact.ultrafilter_le_nhds' - (isCompact_setOf_finiteMeasure_le_of_isCompact C (A n)) - simp only [null_iff_toMeasure_null, Ultrafilter.mem_map, preimage_setOf_eq] + (isCompact_setOfPred_finiteMeasure_le_of_isCompact C (A n)) + simp only [null_iff_toMeasure_null, Ultrafilter.mem_map, preimage_ofPred_eq] filter_upwards [hf] with ρ hρ simp only [restrict_mass, restrict_measure_eq, Measure.restrict_apply (A n).measurableSet.compl] @@ -465,23 +477,32 @@ lemma isCompact_setOf_finiteMeasure_mass_le_compl_isCompact_le rw [this, restrict_mass] exact le_trans (apply_mono _ (sdiff_subset_compl (K m) (K n))) (hμ.2 n) +@[deprecated (since := "2026-07-09")] +alias isCompact_setOf_finiteMeasure_mass_le_compl_isCompact_le := + isCompact_setOfPred_finiteMeasure_mass_le_compl_isCompact_le + /-- **Prokhorov theorem**: Given a sequence of compact sets `Kₙ` and a sequence `uₙ` tending to zero, the finite measures of mass `C` giving mass at most `uₙ` to the complement of `Kₙ` form a compact set. -/ -lemma isCompact_setOf_finiteMeasure_mass_eq_compl_isCompact_le {u : ℕ → ℝ≥0} +lemma isCompact_setOfPred_finiteMeasure_mass_eq_compl_isCompact_le {u : ℕ → ℝ≥0} {K : ℕ → Set E} (C : ℝ≥0) (hu : Tendsto u atTop (𝓝 0)) (hK : ∀ n, IsCompact (K n)) (h : NormalSpace E ∨ Monotone K) : IsCompact {μ : FiniteMeasure E | μ.mass = C ∧ ∀ n, μ (K n)ᶜ ≤ u n} := by have : {μ : FiniteMeasure E | μ.mass = C ∧ ∀ n, μ (K n)ᶜ ≤ u n} = {μ | μ.mass ≤ C ∧ ∀ n, μ (K n)ᶜ ≤ u n} ∩ {μ | μ.mass = C} := by ext; grind rw [this] - apply IsCompact.inter_right (isCompact_setOf_finiteMeasure_mass_le_compl_isCompact_le C hu hK h) + apply IsCompact.inter_right + (isCompact_setOfPred_finiteMeasure_mass_le_compl_isCompact_le C hu hK h) exact isClosed_eq (by fun_prop) (by fun_prop) +@[deprecated (since := "2026-07-09")] +alias isCompact_setOf_finiteMeasure_mass_eq_compl_isCompact_le := + isCompact_setOfPred_finiteMeasure_mass_eq_compl_isCompact_le + /-- **Prokhorov theorem**: Given a sequence of compact sets `Kₙ` and a sequence `uₙ` tending to zero, the probability measures giving mass at most `uₙ` to the complement of `Kₙ` form a compact set. -/ -lemma isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le {u : ℕ → ℝ≥0} +lemma isCompact_setOfPred_probabilityMeasure_mass_eq_compl_isCompact_le {u : ℕ → ℝ≥0} {K : ℕ → Set E} (hu : Tendsto u atTop (𝓝 0)) (hK : ∀ n, IsCompact (K n)) (h : NormalSpace E ∨ Monotone K) : IsCompact {μ : ProbabilityMeasure E | ∀ n, μ (K n)ᶜ ≤ u n} := by @@ -489,7 +510,7 @@ lemma isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le {u : ℕ → have : ProbabilityMeasure.toFiniteMeasure '' {μ | ∀ (n : ℕ), μ (K n)ᶜ ≤ u n} = {μ : FiniteMeasure E | μ.mass = 1 ∧ ∀ n, μ (K n)ᶜ ≤ u n} := by ext μ - simp only [mem_image, mem_setOf_eq] + simp only [mem_image, mem_ofPred_eq] refine ⟨?_, ?_⟩ · rintro ⟨ν, hν, rfl⟩ simpa using! hν @@ -498,7 +519,11 @@ lemma isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le {u : ℕ → have : ν.toFiniteMeasure = μ := by ext; rfl exact ⟨ν, by simpa [← this] using! h'μ , this⟩ rw [this] - exact isCompact_setOf_finiteMeasure_mass_eq_compl_isCompact_le 1 hu hK h + exact isCompact_setOfPred_finiteMeasure_mass_eq_compl_isCompact_le 1 hu hK h + +@[deprecated (since := "2026-07-09")] +alias isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le := + isCompact_setOfPred_probabilityMeasure_mass_eq_compl_isCompact_le /-- **Prokhorov theorem**: the closure of a tight set of probability measures is compact. We only require the space to be T2. -/ @@ -517,7 +542,7 @@ lemma isCompact_closure_of_isTightMeasureSet {S : Set (ProbabilityMeasure E)} choose K K_comp hK using A let K' n := ⋃ i ∈ Iic n, K i have h'K : IsCompact {μ : ProbabilityMeasure E | ∀ n, μ (K' n)ᶜ ≤ u n} := by - apply isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le u_lim + apply isCompact_setOfPred_probabilityMeasure_mass_eq_compl_isCompact_le u_lim · exact fun n ↦ (finite_Iic n).isCompact_biUnion (fun i hi ↦ K_comp i) · right simp only [Monotone, mem_Iic, iUnion_subset_iff, K'] @@ -622,7 +647,7 @@ theorem isTightMeasureSet_of_isCompact_closure (hcomp : IsCompact (closure S)) : intro ε εpos rcases lt_or_ge 1 ε with hεbound | hεbound · refine ⟨∅, isCompact_empty, fun μ hμ ↦ ?_⟩ - simp only [mem_setOf_eq] at hμ + simp only [mem_ofPred_eq] at hμ obtain ⟨μ', hμ', rfl⟩ := hμ rw [compl_empty, measure_univ] exact le_of_lt hεbound diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index 6c4f1281f97047..f8570364d77579 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -606,7 +606,7 @@ theorem ae_restrict_uIoc_iff [LinearOrder α] {a b : α} {P : α → Prop} : theorem ae_restrict_iff₀ {p : α → Prop} (hp : NullMeasurableSet { x | p x } (μ.restrict s)) : (∀ᵐ x ∂μ.restrict s, p x) ↔ ∀ᵐ x ∂μ, x ∈ s → p x := by - simp only [ae_iff, ← compl_setOf, Measure.restrict_apply₀ hp.compl] + simp only [ae_iff, ← compl_ofPred, Measure.restrict_apply₀ hp.compl] rw [iff_iff_eq]; congr with x; simp [and_comm] theorem ae_restrict_iff {p : α → Prop} (hp : MeasurableSet { x | p x }) : @@ -616,11 +616,11 @@ theorem ae_restrict_iff {p : α → Prop} (hp : MeasurableSet { x | p x }) : theorem ae_imp_of_ae_restrict {s : Set α} {p : α → Prop} (h : ∀ᵐ x ∂μ.restrict s, p x) : ∀ᵐ x ∂μ, x ∈ s → p x := by simp only [ae_iff] at h ⊢ - simpa [setOf_and, inter_comm] using measure_inter_eq_zero_of_restrict h + simpa [ofPred_and, inter_comm] using measure_inter_eq_zero_of_restrict h theorem ae_restrict_iff'₀ {p : α → Prop} (hs : NullMeasurableSet s μ) : (∀ᵐ x ∂μ.restrict s, p x) ↔ ∀ᵐ x ∂μ, x ∈ s → p x := by - simp only [ae_iff, ← compl_setOf, restrict_apply₀' hs] + simp only [ae_iff, ← compl_ofPred, restrict_apply₀' hs] rw [iff_iff_eq]; congr with x; simp [and_comm] theorem ae_restrict_iff' {p : α → Prop} (hs : MeasurableSet s) : @@ -709,7 +709,7 @@ theorem le_ae_restrict : ae μ ⊓ 𝓟 s ≤ ae (μ.restrict s) := fun _s hs => @[simp] theorem ae_restrict_eq (hs : MeasurableSet s) : ae (μ.restrict s) = ae μ ⊓ 𝓟 s := by ext t - simp only [mem_inf_principal, mem_ae_iff, restrict_apply_eq_zero' hs, compl_setOf, + simp only [mem_inf_principal, mem_ae_iff, restrict_apply_eq_zero' hs, compl_ofPred, Classical.not_imp, fun a => and_comm (a := a ∈ s) (b := a ∉ t)] rfl @@ -810,7 +810,7 @@ theorem MeasurableSet.nullMeasurableSet_subtype_coe {t : Set s} (hs : NullMeasur exact hs.inter (hs'.nullMeasurableSet) | empty => simp only [image_empty, nullMeasurableSet_empty] | compl t' _ ht' => - simp only [← range_sdiff_image Subtype.coe_injective, Subtype.range_coe_subtype, setOf_mem_eq] + simp only [← range_sdiff_image Subtype.coe_injective, Subtype.range_coe_subtype, ofPred_mem_eq] exact hs.diff ht' | iUnion f _ hf => rw [image_iUnion] @@ -851,7 +851,7 @@ theorem Subtype.volume_def : (volume : Measure u) = volume.comap Subtype.val := theorem Subtype.volume_univ (hu : NullMeasurableSet u) : volume (univ : Set u) = volume u := by rw [Subtype.volume_def, comap_apply₀ _ _ _ _ MeasurableSet.univ.nullMeasurableSet] - · simp only [image_univ, Subtype.range_coe_subtype, setOf_mem_eq] + · simp only [image_univ, Subtype.range_coe_subtype, ofPred_mem_eq] · exact Subtype.coe_injective · exact fun t => MeasurableSet.nullMeasurableSet_subtype_coe hu @@ -899,7 +899,7 @@ theorem comap_map (μ : Measure α) : (map f μ).comap f = μ := by rw [hf.comap_apply, hf.map_apply, preimage_image_eq _ hf.injective] theorem ae_map_iff {p : β → Prop} {μ : Measure α} : (∀ᵐ x ∂μ.map f, p x) ↔ ∀ᵐ x ∂μ, p (f x) := by - simp only [ae_iff, hf.map_apply, preimage_setOf_eq] + simp only [ae_iff, hf.map_apply, preimage_ofPred_eq] theorem restrict_map (μ : Measure α) (s : Set β) : (μ.map f).restrict s = (μ.restrict <| f ⁻¹' s).map f := diff --git a/Mathlib/MeasureTheory/Measure/Sub.lean b/Mathlib/MeasureTheory/Measure/Sub.lean index 230414ee42b84e..dcb1b3059aec46 100644 --- a/Mathlib/MeasureTheory/Measure/Sub.lean +++ b/Mathlib/MeasureTheory/Measure/Sub.lean @@ -93,7 +93,7 @@ theorem sub_apply [IsFiniteMeasure ν] (h₁ : MeasurableSet s) (h₂ : ν ≤ simp [add_comm, h_measure_sub_add] apply le_sInf intro d h_d - rw [← h_measure_sub_add, mem_setOf_eq, add_comm d] at h_d + rw [← h_measure_sub_add, mem_ofPred_eq, add_comm d] at h_d apply Measure.le_of_add_le_add_left h_d rw [h_measure_sub_eq] apply Measure.ofMeasurable_apply _ h₁ @@ -116,10 +116,10 @@ theorem restrict_sub_eq_restrict_sub_restrict (h_meas_s : MeasurableSet s) : apply le_antisymm · refine sInf_le_sInf_of_isCoinitialFor ?_ intro ν' h_ν'_in - rw [mem_setOf_eq] at h_ν'_in + rw [mem_ofPred_eq] at h_ν'_in refine ⟨ν'.restrict s, ?_, restrict_le_self⟩ refine ⟨ν' + (⊤ : Measure α).restrict sᶜ, ?_, ?_⟩ - · rw [mem_setOf_eq, add_right_comm, Measure.le_iff] + · rw [mem_ofPred_eq, add_right_comm, Measure.le_iff] intro t h_meas_t repeat rw [← measure_inter_add_sdiff t h_meas_s] refine add_le_add ?_ ?_ @@ -136,7 +136,7 @@ theorem restrict_sub_eq_restrict_sub_restrict (h_meas_s : MeasurableSet s) : simp [restrict_apply h_meas_t, restrict_apply (h_meas_t.inter h_meas_s), inter_assoc] · refine sInf_le_sInf_of_isCoinitialFor ?_ refine forall_mem_image.2 fun t h_t_in => ⟨t.restrict s, ?_, le_rfl⟩ - rw [Set.mem_setOf_eq, ← restrict_add] + rw [Set.mem_ofPred_eq, ← restrict_add] exact restrict_mono Subset.rfl h_t_in theorem sub_apply_eq_zero_of_restrict_le_restrict (h_le : μ.restrict s ≤ ν.restrict s) diff --git a/Mathlib/MeasureTheory/Measure/SubFinite.lean b/Mathlib/MeasureTheory/Measure/SubFinite.lean index 6e0c40c30c160e..4256367ec6d6b6 100644 --- a/Mathlib/MeasureTheory/Measure/SubFinite.lean +++ b/Mathlib/MeasureTheory/Measure/SubFinite.lean @@ -84,7 +84,7 @@ lemma withDensity_sub {f g : α → ℝ≥0∞} [IsFiniteMeasure (μ.withDensity infer_instance rw [withDensity_sub_of_le hg] refine ae_restrict_of_forall_mem ht.compl fun x hx ↦ ?_ - simp only [Set.mem_compl_iff, Set.mem_setOf_eq, not_le, t] at hx + simp only [Set.mem_compl_iff, Set.mem_ofPred_eq, not_le, t] at hx exact hx.le · refine sub_le_of_le_add ?_ rw [← withDensity_add_right _ hg] diff --git a/Mathlib/MeasureTheory/Measure/Support.lean b/Mathlib/MeasureTheory/Measure/Support.lean index 6a25a568568afd..37c3278a70dab6 100644 --- a/Mathlib/MeasureTheory/Measure/Support.lean +++ b/Mathlib/MeasureTheory/Measure/Support.lean @@ -126,7 +126,7 @@ lemma support_subset_of_isClosed {t : Set X} (ht : IsClosed t) (h : t ∈ ae μ) lemma compl_support_eq_sUnion : μ.supportᶜ = ⋃₀ {t : Set X | IsOpen t ∧ μ t = 0} := by ext x - simp only [Set.mem_compl_iff, Set.mem_sUnion, Set.mem_setOf_eq, and_right_comm, + simp only [Set.mem_compl_iff, Set.mem_sUnion, Set.mem_ofPred_eq, and_right_comm, nhds_basis_opens x |>.notMem_measureSupport, fun t ↦ and_comm (b := x ∈ t)] lemma support_eq_sInter : μ.support = ⋂₀ {t : Set X | IsClosed t ∧ μ tᶜ = 0} := by diff --git a/Mathlib/MeasureTheory/Measure/TightNormed.lean b/Mathlib/MeasureTheory/Measure/TightNormed.lean index 92f5f85bc93bf2..6441f3b0a12623 100644 --- a/Mathlib/MeasureTheory/Measure/TightNormed.lean +++ b/Mathlib/MeasureTheory/Measure/TightNormed.lean @@ -153,7 +153,7 @@ lemma isTightMeasureSet_of_forall_basis_tendsto (b : OrthonormalBasis ι 𝕜 E) _ ≤ ⨆ μ ∈ S, μ (⋃ i, {x : E | r / √(Fintype.card ι) < ‖⟪b i, x⟫_𝕜‖}) := by gcongr with μ hμS intro x hx - simp only [Set.mem_setOf_eq, Set.mem_iUnion] at hx ⊢ + simp only [Set.mem_ofPred_eq, Set.mem_iUnion] at hx ⊢ have hx' : r < √(Fintype.card ι) * ⨆ i, ‖⟪b i, x⟫_𝕜‖ := hx.trans_le (b.norm_le_card_mul_iSup_norm_inner x) rw [← div_lt_iff₀' (by positivity)] at hx' @@ -199,7 +199,7 @@ lemma isTightMeasureSet_iff_inner_tendsto : intro r have h_le (μ : Measure E) : μ {x | r < ‖⟪y, x⟫_𝕜‖} ≤ μ {x | r * ‖y‖⁻¹ < ‖x‖} := by refine measure_mono fun x hx ↦ ?_ - simp only [Set.mem_setOf_eq] at hx ⊢ + simp only [Set.mem_ofPred_eq] at hx ⊢ rw [mul_inv_lt_iff₀] · rw [mul_comm] exact hx.trans_le (norm_inner_le_norm y x) diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean index f009a30a3f6990..695dba97b890b8 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean @@ -284,7 +284,7 @@ theorem countable_meas_pos_of_disjoint_iUnion₀ {ι : Type*} {_ : MeasurableSpa ⊆ ⋃ n, { i : ι | 0 < sfiniteSeq μ n (As i) } := by intro i hi by_contra con - simp only [mem_iUnion, mem_setOf_eq, not_exists, not_lt, nonpos_iff_eq_zero] at * + simp only [mem_iUnion, mem_ofPred_eq, not_exists, not_lt, nonpos_iff_eq_zero] at * rw [sum_apply₀] at hi · simp_rw [con] at hi simp at hi diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index a142193dbad040..1b004c6bfe3cd7 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -257,14 +257,14 @@ theorem withDensity_apply_eq_zero' {f : α → ℝ≥0∞} {s : Set α} (hf : AE simp only [Pi.zero_apply] at A convert! A using 2 ext x - simp only [and_comm, exists_prop, mem_inter_iff, mem_setOf_eq, + simp only [and_comm, exists_prop, mem_inter_iff, mem_ofPred_eq, not_forall] · intro hs let t := toMeasurable μ ({ x | f x ≠ 0 } ∩ s) have A : s ⊆ t ∪ { x | f x = 0 } := by intro x hx rcases eq_or_ne (f x) 0 with (fx | fx) - · simp only [fx, mem_union, mem_setOf_eq, or_true] + · simp only [fx, mem_union, mem_ofPred_eq, or_true] · left apply subset_toMeasurable _ _ exact ⟨fx, hx⟩ @@ -293,7 +293,7 @@ theorem ae_withDensity_iff' {p : α → Prop} {f : α → ℝ≥0∞} (hf : AEMe rw [ae_iff, ae_iff, withDensity_apply_eq_zero' hf, iff_iff_eq] congr ext x - simp only [exists_prop, mem_inter_iff, mem_setOf_eq, not_forall] + simp only [exists_prop, mem_inter_iff, mem_ofPred_eq, not_forall] theorem ae_withDensity_iff {p : α → Prop} {f : α → ℝ≥0∞} (hf : Measurable f) : (∀ᵐ x ∂μ.withDensity f, p x) ↔ ∀ᵐ x ∂μ, f x ≠ 0 → p x := @@ -303,7 +303,7 @@ theorem ae_withDensity_iff_ae_restrict' {p : α → Prop} {f : α → ℝ≥0∞ (hf : AEMeasurable f μ) : (∀ᵐ x ∂μ.withDensity f, p x) ↔ ∀ᵐ x ∂μ.restrict { x | f x ≠ 0 }, p x := by rw [ae_withDensity_iff' hf, ae_restrict_iff'₀] - · simp only [mem_setOf] + · simp only [mem_ofPred] · rcases hf with ⟨g, hg, hfg⟩ have nonneg_eq_ae : {x | g x ≠ 0} =ᵐ[μ] {x | f x ≠ 0} := by filter_upwards [hfg] with a ha @@ -439,7 +439,7 @@ theorem lintegral_withDensity_eq_lintegral_mul₀' {μ : Measure α} {f : α → (hf.measurable_mk (measurableSet_singleton 0).compl).compl filter_upwards [ae_restrict_mem M] intro x hx - simp only [Classical.not_not, mem_setOf_eq, mem_compl_iff] at hx + simp only [Classical.not_not, mem_ofPred_eq, mem_compl_iff] at hx simp only [hx, zero_mul, Pi.mul_apply] _ = ∫⁻ a : α, (f * g) a ∂μ := by apply lintegral_congr_ae diff --git a/Mathlib/MeasureTheory/Order/UpperLower.lean b/Mathlib/MeasureTheory/Order/UpperLower.lean index a0fb96c8e8f241..ac7f9c2b05b854 100644 --- a/Mathlib/MeasureTheory/Order/UpperLower.lean +++ b/Mathlib/MeasureTheory/Order/UpperLower.lean @@ -125,7 +125,7 @@ theorem IsUpperSet.null_frontier (hs : IsUpperSet s) : volume (frontier s) = 0 : (Besicovitch.ae_tendsto_measure_inter_div_of_measurableSet _ (isClosed_closure (s := s)).measurableSet) by_cases h : x ∈ closure s <;> - simp only [mem_compl_iff, mem_setOf, h, not_false_eq_true, indicator_of_notMem, + simp only [mem_compl_iff, mem_ofPred, h, not_false_eq_true, indicator_of_notMem, indicator_of_mem, Pi.one_apply] · refine aux₁ fun _ ↦ hs.compl.exists_subset_ball <| frontier_subset_closure ?_ rwa [frontier_compl] @@ -136,7 +136,7 @@ theorem IsLowerSet.null_frontier (hs : IsLowerSet s) : volume (frontier s) = 0 : (Besicovitch.ae_tendsto_measure_inter_div_of_measurableSet _ (isClosed_closure (s := s)).measurableSet) by_cases h : x ∈ closure s <;> - simp only [mem_compl_iff, mem_setOf, h, not_false_eq_true, indicator_of_notMem, + simp only [mem_compl_iff, mem_ofPred, h, not_false_eq_true, indicator_of_notMem, indicator_of_mem, Pi.one_apply] · refine aux₁ fun _ ↦ hs.compl.exists_subset_ball <| frontier_subset_closure ?_ rwa [frontier_compl] diff --git a/Mathlib/MeasureTheory/OuterMeasure/AE.lean b/Mathlib/MeasureTheory/OuterMeasure/AE.lean index 009620a9fd0340..bd19ff9369da89 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/AE.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/AE.lean @@ -138,7 +138,7 @@ theorem ae_le_of_ae_lt {β : Type*} [Preorder β] {f g : α → β} (h : ∀ᵐ @[simp] theorem ae_eq_empty : s =ᵐ[μ] (∅ : Set α) ↔ μ s = 0 := - eventuallyEq_empty.trans <| by simp only [ae_iff, Classical.not_not, setOf_mem_eq] + eventuallyEq_empty.trans <| by simp only [ae_iff, Classical.not_not, ofPred_mem_eq] -- The priority should be higher than `eventuallyEq_univ`. @[simp high] @@ -259,7 +259,7 @@ set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem _root_.Set.mulIndicator_ae_eq_one {M : Type*} [One M] {f : α → M} {s : Set α} : s.mulIndicator f =ᵐ[μ] 1 ↔ μ (s ∩ f.mulSupport) = 0 := by - simp [EventuallyEq, eventually_iff, ae, compl_setOf]; rfl + simp [EventuallyEq, eventually_iff, ae, compl_ofPred]; rfl /-- If `s ⊆ t` modulo a set of measure `0`, then `μ s ≤ μ t`. -/ @[mono] diff --git a/Mathlib/MeasureTheory/OuterMeasure/BorelCantelli.lean b/Mathlib/MeasureTheory/OuterMeasure/BorelCantelli.lean index 3496a39ce1d7d0..68f20073fd02f2 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/BorelCantelli.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/BorelCantelli.lean @@ -16,7 +16,7 @@ then a.e. all points belong to finitely many sets of the family. We prove several versions of this lemma: -- `MeasureTheory.ae_finite_setOf_mem`: as stated above; +- `MeasureTheory.ae_finite_setOfPred_mem`: as stated above; - `MeasureTheory.measure_limsup_cofinite_eq_zero`: in terms of `Filter.limsup` along `Filter.cofinite`; - `MeasureTheory.measure_limsup_atTop_eq_zero`: @@ -67,25 +67,31 @@ theorem measure_limsup_atTop_eq_zero {s : ℕ → Set α} (hs : ∑' i, μ (s i) (sometimes called the "*first* Borel-Cantelli lemma"): if `(s i)` is a countable family of sets such that `∑' i, μ (s i)` is finite, then a.e. all points belong to finitely many sets of the family. -/ -theorem ae_finite_setOf_mem {s : ι → Set α} (h : ∑' i, μ (s i) ≠ ∞) : +theorem ae_finite_setOfPred_mem {s : ι → Set α} (h : ∑' i, μ (s i) ≠ ∞) : ∀ᵐ x ∂μ, {i | x ∈ s i}.Finite := by rw [ae_iff, ← measure_limsup_cofinite_eq_zero h] congr 1 with x simp [mem_limsup_iff_frequently_mem, Filter.Frequently] +@[deprecated (since := "2026-07-09")] +alias ae_finite_setOf_mem := ae_finite_setOfPred_mem + /-- A version of the **Borel-Cantelli lemma**: if `pᵢ` is a sequence of predicates such that `∑' i, μ {x | pᵢ x}` is finite, then the measure of `x` such that `pᵢ x` holds frequently as `i → ∞` (or equivalently, `pᵢ x` holds for infinitely many `i`) is equal to zero. -/ -theorem measure_setOf_frequently_eq_zero {p : ℕ → α → Prop} (hp : ∑' i, μ { x | p i x } ≠ ∞) : +theorem measure_setOfPred_frequently_eq_zero {p : ℕ → α → Prop} (hp : ∑' i, μ { x | p i x } ≠ ∞) : μ { x | ∃ᶠ n in atTop, p n x } = 0 := by - simpa only [limsup_eq_iInf_iSup_of_nat, frequently_atTop, ← bex_def, setOf_forall, - setOf_exists] using! measure_limsup_atTop_eq_zero hp + simpa only [limsup_eq_iInf_iSup_of_nat, frequently_atTop, ← bex_def, ofPred_forall, + ofPred_exists] using! measure_limsup_atTop_eq_zero hp + +@[deprecated (since := "2026-07-09")] +alias measure_setOf_frequently_eq_zero := measure_setOfPred_frequently_eq_zero /-- A version of the **Borel-Cantelli lemma**: if `sᵢ` is a sequence of sets such that `∑' i, μ sᵢ` is finite, then for almost all `x`, `x` does not belong to `sᵢ` for large `i`. -/ theorem ae_eventually_notMem {s : ℕ → Set α} (hs : (∑' i, μ (s i)) ≠ ∞) : ∀ᵐ x ∂μ, ∀ᶠ n in atTop, x ∉ s n := - measure_setOf_frequently_eq_zero hs + measure_setOfPred_frequently_eq_zero hs theorem measure_liminf_cofinite_eq_zero [Infinite ι] {s : ι → Set α} (h : ∑' i, μ (s i) ≠ ∞) : μ (liminf s cofinite) = 0 := by diff --git a/Mathlib/MeasureTheory/PiSystem.lean b/Mathlib/MeasureTheory/PiSystem.lean index 914a6bab4d09ca..819bd8dbc23dda 100644 --- a/Mathlib/MeasureTheory/PiSystem.lean +++ b/Mathlib/MeasureTheory/PiSystem.lean @@ -392,7 +392,7 @@ theorem piiUnionInter_singleton_left (s : ι → Set α) (S : Set ι) : piiUnionInter (fun i => ({s i} : Set (Set α))) S = { s' : Set α | ∃ (t : Finset ι) (_ : ↑t ⊆ S), s' = ⋂ i ∈ t, s i } := by ext1 s' - simp_rw [piiUnionInter, Set.mem_singleton_iff, exists_prop, Set.mem_setOf_eq] + simp_rw [piiUnionInter, Set.mem_singleton_iff, exists_prop, Set.mem_ofPred_eq] refine ⟨fun h => ?_, fun ⟨t, htS, h_eq⟩ => ⟨t, htS, s, fun _ _ => rfl, h_eq⟩⟩ grind @@ -414,7 +414,7 @@ theorem isPiSystem_piiUnionInter (π : ι → Set (Set α)) (hpi : ∀ x, IsPiSy IsPiSystem (piiUnionInter π S) := by classical rintro t1 ⟨p1, hp1S, f1, hf1m, ht1_eq⟩ t2 ⟨p2, hp2S, f2, hf2m, ht2_eq⟩ h_nonempty - simp_rw [piiUnionInter, Set.mem_setOf_eq] + simp_rw [piiUnionInter, Set.mem_ofPred_eq] let g n := ite (n ∈ p1) (f1 n) Set.univ ∩ ite (n ∈ p2) (f2 n) Set.univ have hp_union_ss : ↑(p1 ∪ p2) ⊆ S := by simp only [hp1S, hp2S, Finset.coe_union, union_subset_iff, and_self_iff] diff --git a/Mathlib/MeasureTheory/SetAlgebra.lean b/Mathlib/MeasureTheory/SetAlgebra.lean index a59499c5d23b33..442f5918bfead9 100644 --- a/Mathlib/MeasureTheory/SetAlgebra.lean +++ b/Mathlib/MeasureTheory/SetAlgebra.lean @@ -200,7 +200,7 @@ theorem mem_generateSetAlgebra_elim (s_mem : s ∈ generateSetAlgebra 𝒜) : exact hA a.1 a.2 (f a).1 (f a).2 · ext x simp only [u_eq, compl_iUnion, compl_iInter, mem_iInter, mem_iUnion, mem_compl_iff, - exists_prop, Subtype.exists, mem_setOf_eq, iUnion_exists, iUnion_iUnion_eq', + exists_prop, Subtype.exists, mem_ofPred_eq, iUnion_exists, iUnion_iUnion_eq', iInter_exists] constructor <;> intro hx · choose f hf using hx @@ -230,9 +230,9 @@ theorem countable_generateSetAlgebra (h : 𝒜.Countable) : exact this ▸ h.image compl let f : Set (Set (Set α)) → Set α := fun A ↦ ⋃ a ∈ A, ⋂ t ∈ a, t let 𝒞 := {a | a.Finite ∧ a ⊆ ℬ} - have count_𝒞 : 𝒞.Countable := countable_setOf_finite_subset (countable_coe_iff.1 count_ℬ) + have count_𝒞 : 𝒞.Countable := countable_ofPred_finite_subset (countable_coe_iff.1 count_ℬ) let 𝒟 := {A | A.Finite ∧ A ⊆ 𝒞} - have count_𝒟 : 𝒟.Countable := countable_setOf_finite_subset (countable_coe_iff.1 count_𝒞) + have count_𝒟 : 𝒟.Countable := countable_ofPred_finite_subset (countable_coe_iff.1 count_𝒞) have : generateSetAlgebra 𝒜 ⊆ f '' 𝒟 := by intro s s_mem rcases mem_generateSetAlgebra_elim s_mem with ⟨A, A_fin, mem_A, hA, rfl⟩ diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 17ec14ff8ffedb..41a978e1dd13fb 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -479,7 +479,7 @@ theorem disjointOfUnion_props (hC : IsSetSemiring C) (h1 : ↑J ⊆ C) : end disjointOfUnion -private lemma _root_.Set.Ioc_mem_setOf_Ioc_le [LinearOrder α] (u v : α) : +private lemma _root_.Set.Ioc_mem_ofPred_Ioc_le [LinearOrder α] (u v : α) : Set.Ioc u v ∈ {s : Set α | ∃ u v, u ≤ v ∧ s = Set.Ioc u v} := ⟨u, max u v, by grind, by grind⟩ @@ -492,15 +492,15 @@ protected lemma Ioc [LinearOrder α] [Nonempty α] : inter_mem := by rintro s ⟨u, v, huv, rfl⟩ t ⟨u', v', hu'v', rfl⟩ rw [Set.Ioc_inter_Ioc] - apply Ioc_mem_setOf_Ioc_le + apply Ioc_mem_ofPred_Ioc_le sdiff_eq_sUnion' := by rintro s ⟨u, v, huv, rfl⟩ t ⟨u', v', hu'v', rfl⟩ rcases le_or_gt u' u with hu | hu - · rcases Ioc_mem_setOf_Ioc_le (max u v') v with ⟨u'', v'', h'', heq⟩ + · rcases Ioc_mem_ofPred_Ioc_le (max u v') v with ⟨u'', v'', h'', heq⟩ exists {Set.Ioc u'' v''} grind [coe_singleton, pairwiseDisjoint_singleton] rcases le_or_gt v v' with hv | hv - · rcases Ioc_mem_setOf_Ioc_le u (min u' v) with ⟨u'', v'', h'', heq⟩ + · rcases Ioc_mem_ofPred_Ioc_le u (min u' v) with ⟨u'', v'', h'', heq⟩ exists {Set.Ioc u'' v''} grind [coe_singleton, pairwiseDisjoint_singleton] rw [show Set.Ioc u v \ Set.Ioc u' v' = Set.Ioc u u' ∪ Set.Ioc v' v by grind] diff --git a/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean b/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean index 6cf384cb2e3b6f..bdab9a59a596ff 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/AddContent.lean @@ -145,10 +145,10 @@ lemma exists_extension_of_isSetRing_of_le_measure_of_dense [IsFiniteMeasure μ] have : Dense {s | ‖m₁ s‖ₑ ≤ μ s} := by apply C'_dense.mono intro s hs - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] convert! hm s (C'C s hs) exact C'_dense.extend_eq lip.continuous ⟨s, hs⟩ - simpa only [Dense, IsClosed.closure_eq, Set.mem_setOf_eq] using! this + simpa only [Dense, IsClosed.closure_eq, Set.mem_ofPred_eq] using! this /- Most involved technical step: show that the extension `m₁` of `m₀` is still finitely additive. -/ have hAddit (s t : MeasuredSets μ) (h : Disjoint (s : Set α) t) : diff --git a/Mathlib/ModelTheory/Algebra/Field/CharP.lean b/Mathlib/ModelTheory/Algebra/Field/CharP.lean index 63d0379a5263d5..aa00bd890bd4c1 100644 --- a/Mathlib/ModelTheory/Algebra/Field/CharP.lean +++ b/Mathlib/ModelTheory/Algebra/Field/CharP.lean @@ -56,7 +56,7 @@ instance model_hasChar_of_charP [Field K] [CompatibleRing K] [CharP K p] : simp [hp.ne_zero, hp, Sentence.Realize] | inr hp => subst hp - simp only [ite_true, Theory.model_iff, Set.mem_image, Set.mem_setOf_eq, + simp only [ite_true, Theory.model_iff, Set.mem_image, Set.mem_ofPred_eq, Sentence.Realize, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, Formula.realize_not, realize_eqZero, ← CharZero.charZero_iff_forall_prime_ne_zero] exact CharP.charP_to_charZero K @@ -67,7 +67,7 @@ theorem charP_iff_model_fieldOfChar [Field K] [CompatibleRing K] : (show (Theory.field.Model K) by infer_instance), true_and] split_ifs with hp0 hp · subst hp0 - simp only [Theory.model_iff, Set.mem_image, Set.mem_setOf_eq, Sentence.Realize, + simp only [Theory.model_iff, Set.mem_image, Set.mem_ofPred_eq, Sentence.Realize, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, Formula.realize_not, realize_eqZero, ← CharZero.charZero_iff_forall_prime_ne_zero] exact ⟨fun _ => CharP.ofCharZero _, fun _ => CharP.charP_to_charZero K⟩ diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean index 04f2a85274936b..115c4ef2ada03e 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean @@ -52,7 +52,7 @@ theorem IsLinearSet.definable [Finite α] (hs : IsLinearSet s) : A.Definable pre x.1 i • Term.var (Sum.inr (Sum.inr x))))), ?_⟩ ext x simp only [mem_vadd_set, SetLike.mem_coe, AddSubmonoid.mem_closure_finset', Finset.univ_eq_attach, - nsmul_eq_mul, vadd_eq_add, ↓existsAndEq, true_and, mem_setOf_eq, Formula.realize_iExs, + nsmul_eq_mul, vadd_eq_add, ↓existsAndEq, true_and, mem_ofPred_eq, Formula.realize_iExs, Formula.realize_iInf, Formula.realize_equal, Term.realize_var, Sum.elim_inl, Term.realize_varsToConstants, coe_con, presburger.realize_add, presburger.realize_natCast, Nat.cast_id, presburger.realize_sum, presburger.realize_nsmul, Sum.elim_inr, smul_eq_mul] @@ -69,7 +69,7 @@ theorem IsSemilinearSet.definable [Finite α] (hs : IsSemilinearSet s) : refine ⟨Formula.iSup φ, ?_⟩ ext x have := fun s hs x => Set.ext_iff.1 (hφ ⟨s, hs⟩).symm x - simp only [mem_setOf_eq] at this + simp only [mem_ofPred_eq] at this simp [this] namespace FirstOrder.Language.presburger @@ -117,31 +117,31 @@ lemma isSemilinearSet_boundedFormula_realize {n} (φ : presburger[[A]].BoundedFo | equal t₁ t₂ => rcases term_realize_eq_add_dotProduct t₁ with ⟨k₁, u₁, ht₁⟩ rcases term_realize_eq_add_dotProduct t₂ with ⟨k₂, u₂, ht₂⟩ - convert! Nat.isSemilinearSet_setOf_mulVec_eq ![k₁] ![k₂] (.of ![u₁]) (.of ![u₂]) + convert! Nat.isSemilinearSet_setOfPred_mulVec_eq ![k₁] ![k₂] (.of ![u₁]) (.of ![u₂]) simp [ht₁, ht₂] | rel f => nomatch f | falsum => exact .empty | imp _ _ ih₁ ih₂ => convert! (ih₂.compl.inter ih₁).compl using 1 - simp [setOf_inter_eq_sep, imp_iff_not_or, compl_setOf] + simp [ofPred_inter_eq_sep, imp_iff_not_or, compl_ofPred] | @all n φ ih => let e := (Equiv.sumAssoc α (Fin n) (Fin 1)).trans (Equiv.sumCongr (.refl α) finSumFinEquiv) rw [← isSemilinearSet_image_iff (LinearEquiv.funCongrLeft ℕ ℕ e)] at ih convert! ih.compl.proj.compl using 1 - simp_rw [compl_setOf, not_exists, Fin.forall_fin_succ_pi, Fin.forall_fin_zero_pi, + simp_rw [compl_ofPred, not_exists, Fin.forall_fin_succ_pi, Fin.forall_fin_zero_pi, mem_compl_iff, mem_image, not_not, ← LinearEquiv.eq_symm_apply, LinearEquiv.funCongrLeft_symm, - exists_eq_right, mem_setOf, LinearEquiv.funCongrLeft_apply, LinearMap.funLeft, + exists_eq_right, mem_ofPred, LinearEquiv.funCongrLeft_apply, LinearMap.funLeft, LinearMap.coe_mk, AddHom.coe_mk] congr! 4 ext i cases i using Fin.lastCases <;> simp [e] lemma isSemilinearSet_formula_realize_semilinear (φ : presburger[[A]].Formula α) : - IsSemilinearSet (setOf φ.Realize : Set (α → ℕ)) := by + IsSemilinearSet (Set.ofPred φ.Realize : Set (α → ℕ)) := by let e := Equiv.sumEmpty α (Fin 0) convert! (isSemilinearSet_boundedFormula_realize φ).image (LinearMap.funLeft ℕ ℕ e.symm) ext x - simp only [mem_setOf_eq, mem_image] + simp only [mem_ofPred_eq, mem_image] rw [(e.arrowCongr (.refl ℕ)).exists_congr_left] simp [Formula.Realize, Unique.eq_default, Function.comp_def, LinearMap.funLeft, e] @@ -155,8 +155,8 @@ theorem definable_iff_isSemilinearSet {s : Set (α → ℕ)} : theorem definable₁_iff_ultimately_periodic {s : Set ℕ} : A.Definable₁ presburger s ↔ ∃ k, ∃ p > 0, ∀ x ≥ k, x ∈ s ↔ x + p ∈ s := by rw [Definable₁, definable_iff_isSemilinearSet, - ← isSemilinearSet_image_iff (LinearEquiv.funUnique (Fin 1) ℕ ℕ), ← preimage_setOf_eq] - simp only [LinearEquiv.funUnique_apply, Function.eval, Fin.default_eq_zero, setOf_mem_eq] + ← isSemilinearSet_image_iff (LinearEquiv.funUnique (Fin 1) ℕ ℕ), ← preimage_ofPred_eq] + simp only [LinearEquiv.funUnique_apply, Function.eval, Fin.default_eq_zero, ofPred_mem_eq] rw [image_preimage_eq s fun x => ⟨![x], rfl⟩, Nat.isSemilinearSet_iff_ultimately_periodic] /-- The graph of multiplication is not Presburger definable in `ℕ`. -/ @@ -170,7 +170,7 @@ theorem mul_not_definable : ¬ A.Definable presburger {v : Fin 3 → ℕ | v 0 = rw [definable₁_iff_ultimately_periodic] at hsqr rcases hsqr with ⟨k, p, hp, h⟩ specialize h ((max k p) * (max k p)) ((Nat.le_mul_self _).trans' (le_max_left _ _)) - simp only [mem_setOf_eq, exists_apply_eq_apply, true_iff] at h + simp only [mem_ofPred_eq, exists_apply_eq_apply, true_iff] at h rcases h with ⟨x, h₁⟩ by_cases h₂ : x ≤ max k p · apply Nat.mul_self_le_mul_self at h₂ diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean index 72b087b288370b..f310d38871e47d 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Basic.lean @@ -29,7 +29,7 @@ any commutative monoid. ## Main Results -- `isSemilinearSet_setOf_eq`: the set of solutions to a linear equation `a + f x = b + g y` is +- `isSemilinearSet_setOfPred_eq`: the set of solutions to a linear equation `a + f x = b + g y` is semilinear. - `IsSemilinearSet.inter`, `IsSemilinearSet.diff`: semilinear sets are closed under intersection and set difference. @@ -67,7 +67,8 @@ private theorem sep_apply_eq {ι : Type*} {M : ι → Type*} [∀ i, Add (M i)] variable {M : Type*} [AddCommMonoid M] [PartialOrder M] [WellQuasiOrderedLE M] [IsOrderedCancelAddMonoid M] [CanonicallyOrderedAdd M] -private theorem exists_isSemilinearSet_setOf_le {s : Set M} (hs : IsSlice s) (hs' : s.Nonempty) : +private theorem exists_isSemilinearSet_setOfPred_le {s : Set M} (hs : IsSlice s) + (hs' : s.Nonempty) : ∃ x ∈ s, IsSemilinearSet { y ∈ s | x ≤ y } := by classical let f (x : M) : AddSubmonoid M := @@ -76,7 +77,7 @@ private theorem exists_isSemilinearSet_setOf_le {s : Set M} (hs : IsSlice s) (hs zero_mem' := by simpa add_mem' := by intro a b ha hb - simp only [mem_setOf_eq] at * + simp only [mem_ofPred_eq] at * rw [← add_assoc] exact hs _ hx _ _ ha hb } else ⊥ @@ -97,7 +98,7 @@ private theorem exists_isSemilinearSet_setOf_le {s : Set M} (hs : IsSlice s) (hs refine ⟨a, ha.1, ?_⟩ convert_to IsSemilinearSet (a +ᵥ (f a : Set M)) · ext x - simp only [le_iff_exists_add, mem_setOf_eq, ha.1, ↓reduceDIte, coe_set_mk, + simp only [le_iff_exists_add, mem_ofPred_eq, ha.1, ↓reduceDIte, coe_set_mk, AddSubsemigroup.coe_set_mk, mem_vadd_set, vadd_eq_add, f] grind · refine IsSemilinearSet.vadd a (.of_fg (AddSubmonoid.fg_of_subtractive ?_)) @@ -146,11 +147,11 @@ private theorem Nat.isSemilinearSet_of_isSlice {ι : Type*} [Finite ι] {s : Set induction t using Finset.strongInductionOn generalizing s a with | _ t ih obtain rfl | hs' := s.eq_empty_or_nonempty · exact .empty - rcases hs.exists_isSemilinearSet_setOf_le hs' with ⟨x, hx, hx'⟩ + rcases hs.exists_isSemilinearSet_setOfPred_le hs' with ⟨x, hx, hx'⟩ convert_to IsSemilinearSet ({ y ∈ s | x ≤ y } ∪ ⋃ i ∈ t, ⋃ j ∈ Finset.range (x i), { y ∈ s | y i = j }) · ext y - simp only [Finset.mem_range, mem_union, mem_setOf_eq, mem_iUnion, Pi.le_def] + simp only [Finset.mem_range, mem_union, mem_ofPred_eq, mem_iUnion, Pi.le_def] grind · refine hx'.union (.biUnion_finset fun i hi => .biUnion_finset fun j hj => ?_) simp only [Finset.mem_range] at hj @@ -161,30 +162,37 @@ private theorem Nat.isSemilinearSet_of_isSlice {ι : Type*} [Finite ι] {s : Set variable {M N ι κ : Type*} [AddCommMonoid M] [AddCommMonoid N] {s s₁ s₂ : Set M} -private theorem Nat.isSemilinearSet_setOf_eq [Finite ι] {F G : Type*} +private theorem Nat.isSemilinearSet_setOfPred_eq [Finite ι] {F G : Type*} [FunLike F (ι → ℕ) M] [AddMonoidHomClass F (ι → ℕ) M] [FunLike G (ι → ℕ) M] [AddMonoidHomClass G (ι → ℕ) M] (a b : M) (f : F) (g : G) : IsSemilinearSet { x | a + f x = b + g x } := by apply isSemilinearSet_of_isSlice intro x hx y z hy hz - simp only [mem_setOf, map_add, ← add_assoc] at * + simp only [mem_ofPred, map_add, ← add_assoc] at * conv_lhs => rw [hy, ← hx, add_right_comm _ (g y) (f z), hz, add_right_comm _ (g z)] /-- The set of solutions to a linear equation `a + f x = b + g y` in a finitely generated monoid is semilinear. -/ -public theorem isSemilinearSet_setOf_eq [AddMonoid.FG M] {F G : Type*} [FunLike F M N] +public theorem isSemilinearSet_setOfPred_eq [AddMonoid.FG M] {F G : Type*} [FunLike F M N] [AddMonoidHomClass F M N] [FunLike G M N] [AddMonoidHomClass G M N] (a b : N) (f : F) (g : G) : IsSemilinearSet { x | a + f x = b + g x } := by rcases fg_iff_exists_fin_addMonoidHom.1 (AddMonoid.FG.fg_top (M := M)) with ⟨n, h, hh⟩ rw [AddMonoidHom.mrange_eq_top] at hh - rw [← image_preimage_eq { x | a + f x = b + g x } hh, preimage_setOf_eq] + rw [← image_preimage_eq { x | a + f x = b + g x } hh, preimage_ofPred_eq] apply IsSemilinearSet.image - exact Nat.isSemilinearSet_setOf_eq a b (AddMonoidHom.comp f h) (AddMonoidHom.comp g h) + exact Nat.isSemilinearSet_setOfPred_eq a b (AddMonoidHom.comp f h) (AddMonoidHom.comp g h) -/-- Matrix version of `isSemilinearSet_setOf_eq`. -/ -public theorem Nat.isSemilinearSet_setOf_mulVec_eq [Fintype κ] (u v : ι → ℕ) (A B : Matrix ι κ ℕ) : +@[deprecated (since := "2026-07-09")] +public alias isSemilinearSet_setOf_eq := isSemilinearSet_setOfPred_eq + +/-- Matrix version of `isSemilinearSet_setOfPred_eq`. -/ +public theorem Nat.isSemilinearSet_setOfPred_mulVec_eq [Fintype κ] (u v : ι → ℕ) + (A B : Matrix ι κ ℕ) : IsSemilinearSet { x | u + A *ᵥ x = v + B *ᵥ x } := - isSemilinearSet_setOf_eq u v A.mulVecLin B.mulVecLin + isSemilinearSet_setOfPred_eq u v A.mulVecLin B.mulVecLin + +@[deprecated (since := "2026-07-09")] +public alias Nat.isSemilinearSet_setOf_mulVec_eq := Nat.isSemilinearSet_setOfPred_mulVec_eq public theorem isLinearSet_iff_exists_fin_addMonoidHom {s : Set M} : IsLinearSet s ↔ ∃ (a : M) (n : ℕ) (f : (Fin n → ℕ) →+ M), s = a +ᵥ Set.range f := by @@ -211,7 +219,7 @@ private lemma Nat.isSemilinearSet_preimage_of_isLinearSet [Finite ι] {F : Type* simp only [mem_vadd_set, mem_range, vadd_eq_add, exists_exists_eq_and] apply IsSemilinearSet.proj' convert! - isSemilinearSet_setOf_eq a 0 (g.comp (LinearMap.funLeft ℕ ℕ Sum.inr).toAddMonoidHom) + isSemilinearSet_setOfPred_eq a 0 (g.comp (LinearMap.funLeft ℕ ℕ Sum.inr).toAddMonoidHom) ((f : (ι → ℕ) →+ M).comp (LinearMap.funLeft ℕ ℕ Sum.inl).toAddMonoidHom) simp [LinearMap.funLeft] @@ -275,10 +283,10 @@ private lemma Nat.isSemilinearSet_inter_of_isLinearSet [Finite ι] {s₁ s₂ : rw [isLinearSet_iff_exists_matrix] at hs₁ hs₂ rcases hs₁ with ⟨u, n, A, rfl⟩ rcases hs₂ with ⟨v, m, B, rfl⟩ - simp_rw [← setOf_and, exists_and_exists_comm] + simp_rw [← ofPred_and, exists_and_exists_comm] refine IsSemilinearSet.proj' (IsSemilinearSet.proj' ?_) convert! - isSemilinearSet_setOf_mulVec_eq (κ := (ι ⊕ Fin n) ⊕ Fin m) (Sum.elim u v) 0 + isSemilinearSet_setOfPred_mulVec_eq (κ := (ι ⊕ Fin n) ⊕ Fin m) (Sum.elim u v) 0 (fromBlocks (fromCols 0 A) 0 0 B) (fromBlocks (fromCols 1 0) 0 (fromCols 1 0) 0) simp [fromBlocks_mulVec, fromCols_mulVec, ← Sum.elim_add_add, Sum.elim_eq_iff] @@ -601,7 +609,7 @@ private theorem isSemilinearSet_setOfFractNe : IsSemilinearSet hs.setOfFractNe : convert_to IsSemilinearSet (⋃ u ∈ hs.fundamentalDomain \ {hs.base}, { x | ∃ y ∈ closure hs.basisSet, ∃ y' ∈ closure hs.basisSet, x + y' = u + y }) using 1 · ext x - simp only [setOfFractNe, mem_iUnion, mem_setOf_eq, exists_prop] + simp only [setOfFractNe, mem_iUnion, mem_ofPred_eq, exists_prop] constructor · intro hx refine ⟨hs.fract x, ⟨hs.fract_mem_fundamentalDomain x, hx⟩, ∑ i, (hs.floor x i).toNat • i.1, @@ -615,17 +623,17 @@ private theorem isSemilinearSet_setOfFractNe : IsSemilinearSet hs.setOfFractNe : hs.fract_eq_self_of_mem_fundamentalDomain hu] at heq rwa [heq] · refine .biUnion hs.finite_fundamentalDomain.sdiff fun i hi => .proj' ?_ - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet) (LinearMap.funLeft ℕ ℕ Sum.inr) apply IsSemilinearSet.proj' - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet) (LinearMap.funLeft ℕ ℕ Sum.inr) classical have := Fintype.ofFinite ι convert! - Nat.isSemilinearSet_setOf_mulVec_eq (κ := (ι ⊕ ι) ⊕ ι) 0 i + Nat.isSemilinearSet_setOfPred_mulVec_eq (κ := (ι ⊕ ι) ⊕ ι) 0 i (Matrix.fromCols (Matrix.fromCols 1 0) 1) (Matrix.fromCols (Matrix.fromCols 0 1) 0) using 4 <;> simp [fromCols_mulVec] @@ -638,7 +646,7 @@ private theorem isSemilinearSet_setOfFloorNeg : IsSemilinearSet hs.setOfFloorNeg ∃ z ∈ closure (hs.basisSet \ {i.1}), ∃ z' ∈ closure (hs.basisSet \ {i.1}), x + i.1 + y + z' = hs.base + z }) using 1 · ext x - simp only [setOfFloorNeg, mem_iUnion, mem_setOf_eq] + simp only [setOfFloorNeg, mem_iUnion, mem_ofPred_eq] constructor · intro ⟨hx, i, hi⟩ refine ⟨i, ((- hs.floor x i).toNat - 1) • i.1, ?_, @@ -674,20 +682,20 @@ private theorem isSemilinearSet_setOfFloorNeg : IsSemilinearSet hs.setOfFloorNeg ← eq_neg_iff_add_eq_zero] at heq simpa [heq] using neg_one_lt_zero.trans_le (Nat.cast_nonneg _) · refine .iUnion fun i => .proj' ?_ - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite (finite_singleton _)) (LinearMap.funLeft ℕ ℕ Sum.inr) apply IsSemilinearSet.proj' - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet.sdiff) (LinearMap.funLeft ℕ ℕ Sum.inr) apply IsSemilinearSet.proj' - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet.sdiff) (LinearMap.funLeft ℕ ℕ Sum.inr) have := Fintype.ofFinite ι convert! - Nat.isSemilinearSet_setOf_mulVec_eq (κ := ((ι ⊕ ι) ⊕ ι) ⊕ ι) i.1 hs.base + Nat.isSemilinearSet_setOfPred_mulVec_eq (κ := ((ι ⊕ ι) ⊕ ι) ⊕ ι) i.1 hs.base (Matrix.fromCols (Matrix.fromCols (Matrix.fromCols 1 1) 0) 1) (Matrix.fromCols (Matrix.fromCols (Matrix.fromCols 0 0) 1) 0) using 4 <;> simp [add_comm _ i.1, add_assoc, fromCols_mulVec] @@ -701,7 +709,7 @@ private theorem isSemilinearSet_setOfFloorPos : IsSemilinearSet hs.setOfFloorPos { x | ∃ y ∈ closure {i.1}, ∃ z ∈ closure (hs.basisSet \ {i.1}), ∃ z' ∈ closure (hs.basisSet \ {i.1}), x + z' = hs.base + i.1 + y + z }) using 1 · ext x - simp only [setOfFloorPos, mem_iUnion, mem_setOf_eq, exists_prop] + simp only [setOfFloorPos, mem_iUnion, mem_ofPred_eq, exists_prop] constructor · intro ⟨hx, i, hi, hi'⟩ refine ⟨i, hi, ((hs.floor x i).toNat - 1) • i.1, ?_, @@ -735,20 +743,20 @@ private theorem isSemilinearSet_setOfFloorPos : IsSemilinearSet hs.setOfFloorPos add_assoc hs.base, ← succ_nsmul', hs.floor_add_nsmul_self, hs.floor_base, zero_add] at heq simp [heq] · refine .biUnion (toFinite _) fun i hi => .proj' ?_ - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite (finite_singleton _)) (LinearMap.funLeft ℕ ℕ Sum.inr) apply IsSemilinearSet.proj' - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet.sdiff) (LinearMap.funLeft ℕ ℕ Sum.inr) apply IsSemilinearSet.proj' - rw [setOf_and] + rw [ofPred_and] apply Nat.isSemilinearSet_inter <| Nat.isSemilinearSet_preimage (.closure_of_finite hs.finite_basisSet.sdiff) (LinearMap.funLeft ℕ ℕ Sum.inr) have := Fintype.ofFinite ι convert! - Nat.isSemilinearSet_setOf_mulVec_eq (κ := ((ι ⊕ ι) ⊕ ι) ⊕ ι) 0 (hs.base + i.1) + Nat.isSemilinearSet_setOfPred_mulVec_eq (κ := ((ι ⊕ ι) ⊕ ι) ⊕ ι) 0 (hs.base + i.1) (Matrix.fromCols (Matrix.fromCols (Matrix.fromCols 1 0) 0) 1) (Matrix.fromCols (Matrix.fromCols (Matrix.fromCols 0 1) 1) 0) using 4 <;> simp [add_assoc, fromCols_mulVec] @@ -762,7 +770,7 @@ private lemma Nat.isSemilinearSet_compl_of_isProperLinearSet [Finite ι] {s : Se hs.isSemilinearSet_setOfFloorNeg.union <| hs.isSemilinearSet_setOfFloorPos using 1 ext simp only [mem_compl_iff, hs.mem_iff_fract_eq_and_floor_nonneg, IsProperLinearSet.setOfFractNe, - IsProperLinearSet.setOfFloorNeg, IsProperLinearSet.setOfFloorPos, mem_union, mem_setOf_eq] + IsProperLinearSet.setOfFloorNeg, IsProperLinearSet.setOfFloorPos, mem_union, mem_ofPred_eq] grind private theorem Nat.isSemilinearSet_compl [Finite ι] {s : Set (ι → ℕ)} (hs : IsSemilinearSet s) : diff --git a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean index b2cac15217f2ea..94cb3c8d071909 100644 --- a/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean +++ b/Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean @@ -434,12 +434,12 @@ theorem Nat.isSemilinearSet_iff_ultimately_periodic {s : Set ℕ} : clear hpt induction m with grind [Finset.sup_le_iff] · intro ⟨k, p, hp, hs⟩ - have h₁ : {x ∈ s | x < k}.Finite := (Set.finite_lt_nat k).subset (sep_subset_setOf _ _) + have h₁ : {x ∈ s | x < k}.Finite := (Set.finite_lt_nat k).subset (sep_subset_ofPred _ _) have h₂ : {x ∈ s | k ≤ x ∧ x < k + p}.Finite := - (Set.finite_Ico k (k + p)).subset (sep_subset_setOf _ _) + (Set.finite_Ico k (k + p)).subset (sep_subset_ofPred _ _) convert! (IsSemilinearSet.of_finite h₁).union (.add (.of_finite h₂) (.closure_finset { p })) ext x - simp only [sep_and, Finset.coe_singleton, mem_union, mem_setOf_eq, mem_add, mem_inter_iff, + simp only [sep_and, Finset.coe_singleton, mem_union, mem_ofPred_eq, mem_add, mem_inter_iff, SetLike.mem_coe, AddSubmonoid.mem_closure_singleton, smul_eq_mul, exists_exists_eq_and] constructor · intro hx diff --git a/Mathlib/ModelTheory/Definability.lean b/Mathlib/ModelTheory/Definability.lean index c03b0cea5ec130..cb2db4d1d34c12 100644 --- a/Mathlib/ModelTheory/Definability.lean +++ b/Mathlib/ModelTheory/Definability.lean @@ -54,7 +54,7 @@ variable {α : Type u₁} {β : Type*} /-- A subset of a finite Cartesian product of a structure is definable over a set `A` when membership in the set is given by a first-order formula with parameters from `A`. -/ def Definable (s : Set (α → M)) : Prop := - ∃ φ : L[[A]].Formula α, s = setOf φ.Realize + ∃ φ : L[[A]].Formula α, s = Set.ofPred φ.Realize variable {L} {A} {B : Set M} {s : Set (α → M)} @@ -63,7 +63,7 @@ theorem Definable.map_expansion {L' : FirstOrder.Language} [L'.Structure M] (h : obtain ⟨ψ, rfl⟩ := h refine ⟨(φ.addConstants A).onFormula ψ, ?_⟩ ext x - simp only [mem_setOf_eq, LHom.realize_onFormula] + simp only [mem_ofPred_eq, LHom.realize_onFormula] theorem definable_iff_exists_formula_sum : A.Definable L s ↔ ∃ φ : L.Formula (A ⊕ α), s = {v | φ.Realize (Sum.elim (↑) v)} := by @@ -71,7 +71,7 @@ theorem definable_iff_exists_formula_sum : refine exists_congr (fun φ => iff_iff_eq.2 (congr_arg (s = ·) ?_)) ext simp only [BoundedFormula.constantsVarsEquiv, constantsOn, - mem_setOf_eq, Formula.Realize] + mem_ofPred_eq, Formula.Realize] refine BoundedFormula.realize_mapTermRel_id ?_ (fun _ _ _ => rfl) intros simp only [Term.constantsVarsEquivLeft_symm_apply, Term.realize_varsToConstants, @@ -81,7 +81,7 @@ theorem definable_iff_exists_formula_sum : set_option backward.isDefEq.respectTransparency false in theorem empty_definable_iff : - (∅ : Set M).Definable L s ↔ ∃ φ : L.Formula α, s = setOf φ.Realize := by + (∅ : Set M).Definable L s ↔ ∃ φ : L.Formula α, s = Set.ofPred φ.Realize := by rw [Definable, Equiv.exists_congr_left (LEquiv.addEmptyConstants L (∅ : Set M)).onFormula] simp @@ -121,7 +121,7 @@ theorem Definable.union {f g : Set (α → M)} (hf : A.Definable L f) (hg : A.De rcases hg with ⟨θ, hθ⟩ refine ⟨φ ⊔ θ, ?_⟩ ext - rw [hφ, hθ, mem_setOf_eq, Formula.realize_sup, mem_union, mem_setOf_eq, mem_setOf_eq] + rw [hφ, hθ, mem_ofPred_eq, Formula.realize_sup, mem_union, mem_ofPred_eq, mem_ofPred_eq] theorem definable_finset_inf {ι : Type*} {f : ι → Set (α → M)} (hf : ∀ i, A.Definable L (f i)) (s : Finset ι) : A.Definable L (s.inf f) := by @@ -164,7 +164,7 @@ theorem Definable.compl {s : Set (α → M)} (hf : A.Definable L s) : A.Definabl rcases hf with ⟨φ, hφ⟩ refine ⟨φ.not, ?_⟩ ext v - rw [hφ, compl_setOf, mem_setOf, mem_setOf, Formula.realize_not] + rw [hφ, compl_ofPred, mem_ofPred, mem_ofPred, Formula.realize_not] @[simp] theorem Definable.sdiff {s t : Set (α → M)} (hs : A.Definable L s) (ht : A.Definable L t) : @@ -179,7 +179,7 @@ theorem Definable.preimage_comp (f : α → β) {s : Set (α → M)} (h : A.Defi obtain ⟨φ, rfl⟩ := h refine ⟨φ.relabel f, ?_⟩ ext - simp only [Set.preimage_setOf_eq, mem_setOf_eq, Formula.realize_relabel] + simp only [Set.preimage_ofPred_eq, mem_ofPred_eq, Formula.realize_relabel] theorem Definable.image_comp_equiv {s : Set (β → M)} (h : A.Definable L s) (f : α ≃ β) : A.Definable L ((fun g : β → M => g ∘ f) '' s) := by @@ -203,7 +203,7 @@ theorem definable_iff_finitely_definable : refine ⟨A0, by simp [A0], (φ.restrictFreeVar <| fun x => Sum.casesOn x.1 (fun x hx => Sum.inl ⟨x, by simp [A0, hx]⟩) (fun x _ => Sum.inr x) x.2), ?_⟩ ext - simp only [Formula.Realize, mem_setOf_eq, Finset.coe_sort_coe] + simp only [Formula.Realize, mem_ofPred_eq, Finset.coe_sort_coe] exact iff_comm.1 <| BoundedFormula.realize_restrictFreeVar _ (by simp) · rintro ⟨A0, hA0, hd⟩ exact Definable.mono hd hA0 @@ -214,7 +214,7 @@ theorem Definable.image_comp_sumInl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M obtain ⟨φ, rfl⟩ := h refine ⟨(BoundedFormula.relabel id φ).exs, ?_⟩ ext x - simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs, + simp only [Set.mem_image, mem_ofPred_eq, BoundedFormula.realize_exs, BoundedFormula.realize_relabel, Function.comp_id, Fin.castAdd_zero, Fin.cast_refl] constructor · rintro ⟨y, hy, rfl⟩ @@ -260,7 +260,7 @@ theorem Definable.image_comp {s : Set (β → M)} (h : A.Definable L s) (f : α simp refine (congr rfl (ext fun x => ?_)).mp (h.inter h') simp only [mem_inter_iff, mem_preimage, mem_image, exists_exists_and_eq_and, - mem_setOf_eq] + mem_ofPred_eq] constructor · rintro ⟨⟨y, ys, hy⟩, hx⟩ refine ⟨y, ys, ?_⟩ @@ -467,7 +467,7 @@ theorem DefinableFun.of_empty (hAs : (∅ : Set M).DefinableFun L f) : theorem empty_definableFun_iff : (∅ : Set M).DefinableFun L f ↔ - ∃ φ : L.Formula (Option α), f.tupleGraph = setOf φ.Realize := by + ∃ φ : L.Formula (Option α), f.tupleGraph = Set.ofPred φ.Realize := by simp [DefinableFun, Set.empty_definable_iff] theorem definableFun_iff_empty_definableFun_with_params : @@ -517,7 +517,7 @@ lemma _root_.Set.Definable.preimage_map {S : Set (β → M)} (hS : A.Definable L S) : A.Definable L (F ⁻¹' S) := by have h_graph : A.Definable L { w : α ⊕ β → M | ∀ i, F (w ∘ Sum.inl) i = w (Sum.inr i) } := by - rw [setOf_forall] + rw [ofPred_forall] refine definable_iInter_of_finite fun i => ?_ simpa [tupleGraph] using! (hF i).preimage_comp (fun | none => Sum.inr i | some j => Sum.inl j) @@ -546,7 +546,7 @@ theorem DefinableFun.comp [Finite α] {g : (β → M) → α → M} @[fun_prop] theorem DefinableFun.ite {p : (α → M) → Prop} {g} [DecidablePred p] - (hp : A.Definable L (setOf p)) (hf : DefinableFun L A f) (hg : DefinableFun L A g) : + (hp : A.Definable L (Set.ofPred p)) (hf : DefinableFun L A f) (hg : DefinableFun L A g) : DefinableFun L A fun v => if p v then f v else g v := by let P : Set (Option α → M) := {w | p (w ∘ some)} have hP : A.Definable L P := hp.preimage_comp some @@ -556,17 +556,24 @@ theorem DefinableFun.ite {p : (α → M) → Prop} {g} [DecidablePred p] by_cases h : p (w ∘ some) <;> simp [tupleGraph, P, h] /-- The set where two definable functions agree is definable. -/ -lemma DefinableFun.setOf_eq {f g : (α → M) → M} +lemma DefinableFun.ofPred_eq {f g : (α → M) → M} (hf : A.DefinableFun L f) (hg : A.DefinableFun L g) : A.Definable L {v : α → M | f v = g v} := by have hF : A.DefinableMap L (fun v => ![f v, g v]) := by simp [DefinableMap, *] exact (Definable.diagonal L A).preimage_map hF +@[deprecated (since := "2026-07-09")] +alias DefinableFun.setOf_eq := DefinableFun.ofPred_eq + /-- The preimage of a constant under a definable function is definable. -/ -lemma DefinableFun.setOf_eq_const {f : (α → M) → M} (hf : A.DefinableFun L f) {a : M} (ha : a ∈ A) : +lemma DefinableFun.ofPred_eq_const {f : (α → M) → M} (hf : A.DefinableFun L f) {a : M} + (ha : a ∈ A) : A.Definable L {v : α → M | f v = a} := - hf.setOf_eq (L.definableFun_const α ha) + hf.ofPred_eq (L.definableFun_const α ha) + +@[deprecated (since := "2026-07-09")] +alias DefinableFun.setOf_eq_const := DefinableFun.ofPred_eq_const end Set diff --git a/Mathlib/ModelTheory/DirectLimit.lean b/Mathlib/ModelTheory/DirectLimit.lean index e4f84402dfea00..49e15117d7682a 100644 --- a/Mathlib/ModelTheory/DirectLimit.lean +++ b/Mathlib/ModelTheory/DirectLimit.lean @@ -323,7 +323,7 @@ theorem exists_fg_substructure_in_Sigma (S : L.Substructure (DirectLimit G f)) ( rw [Substructure.map_closure] simp only [Embedding.coe_toHom, of_apply] rw [← image_univ, image_image, image_univ, ← eq_y, - Subtype.range_coe_subtype, Finset.setOf_mem, A_closure] + Subtype.range_coe_subtype, Finset.setOfPred_mem, A_closure] variable {P : Type u₁} [L.Structure P] diff --git a/Mathlib/ModelTheory/ElementarySubstructures.lean b/Mathlib/ModelTheory/ElementarySubstructures.lean index cd078c268aa930..8053d339f69f13 100644 --- a/Mathlib/ModelTheory/ElementarySubstructures.lean +++ b/Mathlib/ModelTheory/ElementarySubstructures.lean @@ -182,7 +182,7 @@ theorem isElementary_closure (hA : L.MeetsDefinable A) : simp only [Subtype.coe_prop] ⟩).term) i, ?_⟩ ext v - simp only [Fin.isValue, mem_setOf_eq, Formula.relabel, Formula.Realize, + simp only [Fin.isValue, mem_ofPred_eq, Formula.relabel, Formula.Realize, BoundedFormula.realize_subst, BoundedFormula.realize_relabel, Nat.add_zero, Fin.castAdd_zero, Fin.cast_refl, Function.comp_id, Fin.natAdd_zero, D] rw [← Formula.Realize, BoundedFormula.realize_toFormula, LHom.realize_onBoundedFormula] diff --git a/Mathlib/ModelTheory/Fraisse.lean b/Mathlib/ModelTheory/Fraisse.lean index e1b2bb61baf394..d35b4bfef5b789 100644 --- a/Mathlib/ModelTheory/Fraisse.lean +++ b/Mathlib/ModelTheory/Fraisse.lean @@ -413,7 +413,7 @@ theorem isFraisseLimit_of_countable_infinite IsFraisseLimit { S : Bundled Language.empty.Structure | Finite S } M where age := by ext S - simp only [age, Structure.fg_iff_finite, mem_setOf_eq, and_iff_left_iff_imp] + simp only [age, Structure.fg_iff_finite, mem_ofPred_eq, and_iff_left_iff_imp] intro hS simp ultrahomogeneous S hS f := by diff --git a/Mathlib/ModelTheory/Satisfiability.lean b/Mathlib/ModelTheory/Satisfiability.lean index 9227c2c63f97ea..fabc6dc85206ff 100644 --- a/Mathlib/ModelTheory/Satisfiability.lean +++ b/Mathlib/ModelTheory/Satisfiability.lean @@ -411,7 +411,7 @@ theorem realize_sentence_iff (h : T.IsComplete) (φ : L.Sentence) (M : Type*) [L theorem eq_complete_theory (h : T.IsComplete) (M : Type*) [L.Structure M] [M ⊨ T] [Nonempty M] : {φ | T ⊨ᵇ φ} = L.completeTheory M := by ext φ - simp only [Set.mem_setOf_eq, L.mem_completeTheory] + simp only [Set.mem_ofPred_eq, L.mem_completeTheory] refine ⟨fun h_models => h_models.realize_sentence M, fun h_realize => ?_⟩ cases h.2 φ with | inl hT => exact hT @@ -480,7 +480,7 @@ theorem isSatisfiable [Nonempty M] : (L.completeTheory M).IsSatisfiable := Theory.Model.isSatisfiable M theorem mem_or_not_mem (φ : L.Sentence) : φ ∈ L.completeTheory M ∨ φ.not ∈ L.completeTheory M := by - simp_rw [completeTheory, Set.mem_setOf_eq, Sentence.Realize, Formula.realize_not, or_not] + simp_rw [completeTheory, Set.mem_ofPred_eq, Sentence.Realize, Formula.realize_not, or_not] theorem isMaximal [Nonempty M] : (L.completeTheory M).IsMaximal := ⟨isSatisfiable L M, mem_or_not_mem L M⟩ diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index 33f68d521a38ff..18e86ea15e52f5 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -614,11 +614,15 @@ theorem LHom.realize_onFormula [L'.Structure M] (φ : L →ᴸ L') [φ.IsExpansi φ.realize_onBoundedFormula ψ @[simp] -theorem LHom.setOf_realize_onFormula [L'.Structure M] (φ : L →ᴸ L') [φ.IsExpansionOn M] - (ψ : L.Formula α) : (setOf (φ.onFormula ψ).Realize : Set (α → M)) = setOf ψ.Realize := by +theorem LHom.setOfPred_realize_onFormula [L'.Structure M] (φ : L →ᴸ L') [φ.IsExpansionOn M] + (ψ : L.Formula α) : + (Set.ofPred (φ.onFormula ψ).Realize : Set (α → M)) = Set.ofPred ψ.Realize := by ext simp +@[deprecated (since := "2026-07-09")] +alias LHom.setOf_realize_onFormula := LHom.setOfPred_realize_onFormula + variable (M) /-- A sentence can be evaluated as true or false in a structure. -/ @@ -719,7 +723,7 @@ theorem mem_completeTheory {φ : Sentence L} : φ ∈ L.completeTheory M ↔ M Iff.rfl theorem elementarilyEquivalent_iff : M ≅[L] N ↔ ∀ φ : L.Sentence, M ⊨ φ ↔ N ⊨ φ := by - simp only [ElementarilyEquivalent, Set.ext_iff, completeTheory, Set.mem_setOf_eq] + simp only [ElementarilyEquivalent, Set.ext_iff, completeTheory, Set.mem_ofPred_eq] variable (M) diff --git a/Mathlib/ModelTheory/Substructures.lean b/Mathlib/ModelTheory/Substructures.lean index a481c6ce6b82cc..5894696c33d143 100644 --- a/Mathlib/ModelTheory/Substructures.lean +++ b/Mathlib/ModelTheory/Substructures.lean @@ -331,15 +331,16 @@ variable {L} (S) is preserved under function symbols, then `p` holds for all elements of the closure of `s`. -/ @[elab_as_elim] theorem closure_induction {p : M → Prop} {x} (h : x ∈ closure L s) (Hs : ∀ x ∈ s, p x) - (Hfun : ∀ {n : ℕ} (f : L.Functions n), ClosedUnder f (setOf p)) : p x := - (@closure_le L M _ ⟨setOf p, fun {_} => Hfun⟩ _).2 Hs h + (Hfun : ∀ {n : ℕ} (f : L.Functions n), ClosedUnder f (Set.ofPred p)) : p x := + (@closure_le L M _ ⟨Set.ofPred p, fun {_} => Hfun⟩ _).2 Hs h /-- If `s` is a dense set in a structure `M`, `Substructure.closure L s = ⊤`, then in order to prove that some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`, and verify that `p` is preserved under function symbols. -/ @[elab_as_elim] theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure L s = ⊤) - (Hs : ∀ x ∈ s, p x) (Hfun : ∀ {n : ℕ} (f : L.Functions n), ClosedUnder f (setOf p)) : p x := by + (Hs : ∀ x ∈ s, p x) (Hfun : ∀ {n : ℕ} (f : L.Functions n), ClosedUnder f (Set.ofPred p)) : + p x := by have : ∀ x ∈ closure L s, p x := fun x hx => closure_induction hx Hs fun {n} => Hfun simpa [hs] using this x @@ -392,7 +393,7 @@ theorem mem_iSup_of_directed {ι : Type*} [hι : Nonempty ι] {S : ι → L.Subs suffices x ∈ closure L (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by simpa only [closure_iUnion, closure_eq (S _)] using this refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) (fun f v hC ↦ ?_) - simp_rw [Set.mem_setOf] at * + simp_rw [Set.mem_ofPred] at * have ⟨i, hi⟩ := hS.finite_le (fun i ↦ Classical.choose (hC i)) refine ⟨i, (S i).fun_mem f v (fun j ↦ hi j (Classical.choose_spec (hC j)))⟩ diff --git a/Mathlib/ModelTheory/Topology/Types.lean b/Mathlib/ModelTheory/Topology/Types.lean index bf3a1bd0c329e3..d289604c4337a1 100644 --- a/Mathlib/ModelTheory/Topology/Types.lean +++ b/Mathlib/ModelTheory/Topology/Types.lean @@ -87,7 +87,7 @@ instance : CompactSpace (T.CompleteType α) := by have subset : (x : Set _) ⊆ T.toTheory := by rwa [Set.mem_iInter₂] at T_inter exact T.isMaximal.1.mono subset · intro φ - simp only [mem_setOf_eq, typesWith_not] + simp only [mem_ofPred_eq, typesWith_not] exact Ultrafilter.mem_or_compl_mem F (T.typesWith φ) · refine ⟨mem_univ _, ?_⟩ · rw [nhds_generateFrom] diff --git a/Mathlib/ModelTheory/Types.lean b/Mathlib/ModelTheory/Types.lean index 7dfcff66945023..8f9efd01ea82d4 100644 --- a/Mathlib/ModelTheory/Types.lean +++ b/Mathlib/ModelTheory/Types.lean @@ -113,11 +113,13 @@ theorem not_mem_iff (p : T.CompleteType α) (φ : L[[α]].Sentence) : φ.not ∈ exact ⟨ht, hf⟩, (p.mem_or_not_mem φ).resolve_left⟩ @[simp] -theorem compl_setOf_mem {φ : L[[α]].Sentence} : +theorem compl_setOfPred_mem {φ : L[[α]].Sentence} : { p : T.CompleteType α | φ ∈ p }ᶜ = { p : T.CompleteType α | φ.not ∈ p } := ext fun _ => (not_mem_iff _ _).symm -theorem setOf_subset_eq_empty_iff (S : L[[α]].Theory) : +@[deprecated (since := "2026-07-09")] alias compl_setOf_mem := compl_setOfPred_mem + +theorem setOfPred_subset_eq_empty_iff (S : L[[α]].Theory) : { p : T.CompleteType α | S ⊆ ↑p } = ∅ ↔ ¬((L.lhomWithConstants α).onTheory T ∪ S).IsSatisfiable := by rw [iff_not_comm, ← not_nonempty_iff_eq_empty, Classical.not_not, Set.Nonempty] @@ -130,36 +132,46 @@ theorem setOf_subset_eq_empty_iff (S : L[[α]].Theory) : rintro ⟨p, hp⟩ exact p.isMaximal.1.mono (union_subset p.subset hp) -theorem setOf_mem_eq_univ_iff (φ : L[[α]].Sentence) : +@[deprecated (since := "2026-07-09")] +alias setOf_subset_eq_empty_iff := setOfPred_subset_eq_empty_iff + +theorem setOfPred_mem_eq_univ_iff (φ : L[[α]].Sentence) : { p : T.CompleteType α | φ ∈ p } = Set.univ ↔ (L.lhomWithConstants α).onTheory T ⊨ᵇ φ := by - rw [models_iff_not_satisfiable, ← compl_empty_iff, compl_setOf_mem, ← setOf_subset_eq_empty_iff] + rw [models_iff_not_satisfiable, ← compl_empty_iff, compl_setOfPred_mem, + ← setOfPred_subset_eq_empty_iff] simp -theorem setOf_subset_eq_univ_iff (S : L[[α]].Theory) : +@[deprecated (since := "2026-07-09")] alias setOf_mem_eq_univ_iff := setOfPred_mem_eq_univ_iff + +theorem setOfPred_subset_eq_univ_iff (S : L[[α]].Theory) : { p : T.CompleteType α | S ⊆ ↑p } = Set.univ ↔ ∀ φ, φ ∈ S → (L.lhomWithConstants α).onTheory T ⊨ᵇ φ := by have h : { p : T.CompleteType α | S ⊆ ↑p } = ⋂₀ ((fun φ => { p | φ ∈ p }) '' S) := by ext simp [subset_def] - simp_rw [h, sInter_eq_univ, ← setOf_mem_eq_univ_iff] + simp_rw [h, sInter_eq_univ, ← setOfPred_mem_eq_univ_iff] refine ⟨fun h φ φS => h _ ⟨_, φS, rfl⟩, ?_⟩ rintro h _ ⟨φ, h1, rfl⟩ exact h _ h1 +@[deprecated (since := "2026-07-09")] alias setOf_subset_eq_univ_iff := setOfPred_subset_eq_univ_iff + theorem nonempty_iff : Nonempty (T.CompleteType α) ↔ T.IsSatisfiable := by rw [← isSatisfiable_onTheory_iff (lhomWithConstants_injective L α)] rw [nonempty_iff_univ_nonempty, nonempty_iff_ne_empty, Ne, not_iff_comm, - ← union_empty ((L.lhomWithConstants α).onTheory T), ← setOf_subset_eq_empty_iff] + ← union_empty ((L.lhomWithConstants α).onTheory T), ← setOfPred_subset_eq_empty_iff] simp instance instNonempty : Nonempty (CompleteType (∅ : L.Theory) α) := nonempty_iff.2 (isSatisfiable_empty L) -theorem iInter_setOf_subset {ι : Type*} (S : ι → L[[α]].Theory) : +theorem iInter_setOfPred_subset {ι : Type*} (S : ι → L[[α]].Theory) : ⋂ i : ι, { p : T.CompleteType α | S i ⊆ p } = { p : T.CompleteType α | ⋃ i : ι, S i ⊆ p } := by ext - simp only [mem_iInter, mem_setOf_eq, iUnion_subset_iff] + simp only [mem_iInter, mem_ofPred_eq, iUnion_subset_iff] + +@[deprecated (since := "2026-07-09")] alias iInter_setOf_subset := iInter_setOfPred_subset theorem toList_foldr_inf_mem {p : T.CompleteType α} {t : Finset L[[α]].Sentence} : t.toList.foldr (· ⊓ ·) ⊤ ∈ p ↔ (t : L[[α]].Theory) ⊆ ↑p := by @@ -211,7 +223,7 @@ lemma typesWith_top : T.typesWith (α := α) ⊤ = Set.univ := univ_subset_iff.mp fun p _ ↦ p.isMaximal.mem_of_models (φ := ⊤) (fun _ _ _ a ↦ a) lemma typesWith_not (φ : L[[α]].Sentence) : T.typesWith ∼φ = (T.typesWith φ)ᶜ := by - exact Eq.symm compl_setOf_mem + exact Eq.symm compl_setOfPred_mem end CompleteType diff --git a/Mathlib/ModelTheory/Ultraproducts.lean b/Mathlib/ModelTheory/Ultraproducts.lean index e84d5b83c0aac8..a41a887d2a6552 100644 --- a/Mathlib/ModelTheory/Ultraproducts.lean +++ b/Mathlib/ModelTheory/Ultraproducts.lean @@ -53,19 +53,19 @@ instance setoidPrestructure : L.Prestructure ((u : Filter α).productSetoid M) : RelMap := fun {_} r x => ∀ᶠ a : α in u, RelMap r fun i => x i a } fun_equiv := fun {n} f x y xy => by refine mem_of_superset (iInter_mem.2 xy) fun a ha => ?_ - simp only [Set.mem_iInter, Set.mem_setOf_eq] at ha - simp only [Set.mem_setOf_eq, ha] + simp only [Set.mem_iInter, Set.mem_ofPred_eq] at ha + simp only [Set.mem_ofPred_eq, ha] rel_equiv := fun {n} r x y xy => by rw [← iff_eq_eq] refine ⟨fun hx => ?_, fun hy => ?_⟩ · refine mem_of_superset (inter_mem hx (iInter_mem.2 xy)) ?_ rintro a ⟨ha1, ha2⟩ - simp only [Set.mem_iInter, Set.mem_setOf_eq] at * + simp only [Set.mem_iInter, Set.mem_ofPred_eq] at * rw [← funext ha2] exact ha1 · refine mem_of_superset (inter_mem hy (iInter_mem.2 xy)) ?_ rintro a ⟨ha1, ha2⟩ - simp only [Set.mem_iInter, Set.mem_setOf_eq] at * + simp only [Set.mem_iInter, Set.mem_ofPred_eq] at * rw [funext ha2] exact ha1 } diff --git a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean index f617e5bb902565..88641b892b3523 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean @@ -255,7 +255,7 @@ local instance : CompleteSpace (ArithmeticFunction R) := by ext f exact ⟨by rintro ⟨f, rfl⟩; simp, fun hf ↦ ⟨⟨f, hf⟩, rfl⟩⟩ rw [ArithmeticFunction.range_coe] - apply isClosed_setOf_map_zero + apply isClosed_setOfPred_map_zero /-- The Euler product of a family of arithmetic functions. Defined as a `tprod`, but see `tendsTo_eulerProduct_of_tendsTo` for the outward facing `eulerProduct` API. -/ diff --git a/Mathlib/NumberTheory/Chebyshev.lean b/Mathlib/NumberTheory/Chebyshev.lean index f128de3719d2e3..6ffaf1bc3538b5 100644 --- a/Mathlib/NumberTheory/Chebyshev.lean +++ b/Mathlib/NumberTheory/Chebyshev.lean @@ -640,7 +640,7 @@ theorem primeCounting_eq_theta_div_log_add_integral {x : ℝ} (hx : 2 ≤ x) : simp only [primeCounting, primeCounting', count_eq_card_filter_range] rw [card_eq_sum_ones, range_succ_eq_Icc_zero, sum_filter] push_cast - let a : ℕ → ℝ := Set.indicator (setOf Nat.Prime) (fun n ↦ log n) + let a : ℕ → ℝ := Set.indicator (Set.ofPred Nat.Prime) (fun n ↦ log n) trans ∑ n ∈ Icc 0 ⌊x⌋₊, (log n)⁻¹ * a n · refine sum_congr rfl fun n hn ↦ ?_ split_ifs with h @@ -676,7 +676,7 @@ theorem theta_eq_primeCounting_mul_log_sub_integral {x : ℝ} (hx : 2 ≤ x) : θ x = π ⌊x⌋₊ * log x - ∫ t in 2..x, π ⌊t⌋₊ / t := by -- Rewrite in a form to which Abel summation can be applied rw [theta_eq_sum_Icc, sum_filter] - let a : ℕ → ℝ := Set.indicator (setOf Nat.Prime) (fun n ↦ 1) + let a : ℕ → ℝ := Set.indicator (Set.ofPred Nat.Prime) (fun n ↦ 1) trans ∑ n ∈ Icc 0 ⌊x⌋₊, log n * a n · refine sum_congr rfl fun n _ ↦ ?_ split_ifs with h <;> simp [a, h] diff --git a/Mathlib/NumberTheory/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/Cyclotomic/Basic.lean index 159456fa4f3115..cde22d0f99bdcf 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Basic.lean @@ -196,7 +196,7 @@ theorem union_left [h : IsCyclotomicExtension T A B] (hS : S ⊆ T) : refine ⟨⟨b, subset_adjoin ⟨n, hn, hn', hb.pow_eq_one⟩⟩, ?_⟩ rwa [← IsPrimitiveRoot.coe_submonoidClass_iff, Subtype.coe_mk] · convert! mem_top (R := A) (x := b) - rw [← adjoin_adjoin_coe_preimage, preimage_setOf_eq] + rw [← adjoin_adjoin_coe_preimage, preimage_ofPred_eq] norm_cast variable {n} @@ -235,7 +235,7 @@ theorem of_union_of_dvd (h : ∃ s ∈ S, s ≠ 0 ∧ n ∣ s) [H : IsCyclotomic · refine _root_.eq_top_iff.2 ?_ rw [← ((iff_adjoin_eq_top S A B).1 H).2] refine adjoin_mono fun x hx ↦ ?_ - simp only [union_singleton, mem_insert_iff, mem_setOf_eq] at hx ⊢ + simp only [union_singleton, mem_insert_iff, mem_ofPred_eq] at hx ⊢ obtain ⟨m, hm, hm'⟩ := hx exact ⟨m, ⟨Or.inr hm, hm'⟩⟩ @@ -249,7 +249,7 @@ theorem iff_union_of_dvd (h : ∃ s ∈ S, s ≠ 0 ∧ n ∣ s) : · exact H.exists_isPrimitiveRoot (subset_union_left hs) · rw [_root_.eq_top_iff, ← ((iff_adjoin_eq_top _ A B).1 H).2] refine adjoin_mono fun x hx => ?_ - simp only [union_singleton, mem_insert_iff, mem_setOf_eq] at hx ⊢ + simp only [union_singleton, mem_insert_iff, mem_ofPred_eq] at hx ⊢ obtain ⟨m, rfl | hm, hxpow⟩ := hx · obtain ⟨y, ⟨hy, hy', ⟨z, rfl⟩⟩⟩ := h exact ⟨_, ⟨hy, hy', by simp only [pow_mul, hxpow, one_pow]⟩⟩ @@ -432,12 +432,12 @@ theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : simp only [mem_singleton_iff, exists_eq_left] refine le_antisymm (adjoin_mono fun x hx => ?_) (adjoin_le fun x hx => ?_) · rw [mem_rootSet'] at hx - simp only [mem_setOf_eq] + simp only [mem_ofPred_eq] rw [isRoot_of_unity_iff (NeZero.pos n)] refine ⟨NeZero.ne n, n, Nat.mem_divisors_self n (NeZero.ne n), ?_⟩ rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map_algebraMap] exact hx.2 - · simp only [mem_setOf_eq] at hx + · simp only [mem_ofPred_eq] at hx obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx.2 refine SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin ?_) _) rw [mem_rootSet', map_cyclotomic, ← eval_map_algebraMap, map_cyclotomic, ← IsRoot] @@ -479,7 +479,7 @@ theorem _root_.IsPrimitiveRoot.adjoin_isCyclotomicExtension {ζ : B} {n : ℕ} [ (fun b₁ b₂ _ _ hb₁ hb₂ => ?_) · rw [Set.mem_singleton_iff] at hb refine subset_adjoin ?_ - simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq, hb] + simp only [mem_singleton_iff, exists_eq_left, mem_ofPred_eq, hb] rw [← Subalgebra.coe_eq_one, Subalgebra.coe_pow, Subtype.coe_mk] exact ⟨NeZero.ne n, ((IsPrimitiveRoot.iff_def ζ n).1 h).1⟩ · exact Subalgebra.algebraMap_mem _ _ @@ -621,7 +621,7 @@ theorem isSplittingField_X_pow_sub_one : IsSplittingField K L (X ^ n - 1) := congr refine Set.ext fun x => ?_ simp only [mem_singleton_iff, ne_eq, exists_eq_left, NeZero.ne, not_false_eq_true, true_and, - mem_setOf_eq] + mem_ofPred_eq] simp only [mem_rootSet', map_sub, map_pow, aeval_one, aeval_X, sub_eq_zero, map_X, and_iff_right_iff_imp, Polynomial.map_sub, Polynomial.map_pow, Polynomial.map_one] exact fun _ => X_pow_sub_C_ne_zero (NeZero.pos n) (1 : L) } @@ -785,7 +785,7 @@ instance isCyclotomicExtension [IsDomain A] [IsFractionRing A K] [NeZero ((n : adjoin_induction (fun y hy => ?_) (fun a => ?_) (fun y z _ _ hy hz => ?_) (fun y z _ _ hy hz => ?_) hx · refine subset_adjoin ?_ - simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq] + simp only [mem_singleton_iff, exists_eq_left, mem_ofPred_eq] exact ⟨NeZero.ne n, by rwa [← Subalgebra.coe_eq_one, Subalgebra.coe_pow, Subtype.coe_mk]⟩ · exact Subalgebra.algebraMap_mem _ a · exact Subalgebra.add_mem _ hy hz @@ -883,7 +883,7 @@ theorem isCyclotomicExtension_iff_eq_adjoin (C : Subalgebra A B) rw [← Subalgebra.range_val C, ← Algebra.map_top, ← this, AlgHom.map_adjoin] congr; ext simp only [Subalgebra.coe_val, ne_eq, ← Subalgebra.coe_eq_one, SubmonoidClass.coe_pow, - Set.mem_image, Set.mem_setOf_eq, Subtype.exists, exists_and_left, exists_prop, + Set.mem_image, Set.mem_ofPred_eq, Subtype.exists, exists_and_left, exists_prop, exists_eq_right_right, and_iff_left_iff_imp, forall_exists_index, and_imp] exact fun n hn₁ hn₂ hx ↦ h.mem_of_pow_eq_one S C hn₁ hn₂ hx diff --git a/Mathlib/NumberTheory/DirichletCharacter/Basic.lean b/Mathlib/NumberTheory/DirichletCharacter/Basic.lean index 2e86d6e8cf4339..35828083f8c8a2 100644 --- a/Mathlib/NumberTheory/DirichletCharacter/Basic.lean +++ b/Mathlib/NumberTheory/DirichletCharacter/Basic.lean @@ -452,7 +452,7 @@ def subgroupOfCoprimeConductor [NeZero n] (d : ℕ) : apply Nat.Coprime.of_dvd_right (conductor_mul_dvd_lcm_conductor _ _) exact (Nat.Coprime.mul_right hχ hψ).coprime_div_right <| Nat.gcd_dvd_mul _ _ one_mem' := by simp [conductor_one] - inv_mem' hχ := by rwa [Set.mem_setOf, conductor_inv] + inv_mem' hχ := by rwa [Set.mem_ofPred, conductor_inv] @[simp] lemma mem_subgroupOfCoprimeConductor [NeZero n] {d : ℕ} {χ : DirichletCharacter R n} : diff --git a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean index c7299a93b8edab..58a6430496fc0b 100644 --- a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean +++ b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean @@ -183,7 +183,7 @@ lemma DirichletCharacter.LSeries_changeLevel {M N : ℕ} [NeZero N] (DirichletCharacter.LSeries_eulerProduct_hasProd χ hs).multipliable · exact multipliable_subtype_iff_mulIndicator.mp Multipliable.of_finite · congr 1 with p - simp only [Set.mulIndicator_apply, Set.mem_setOf_eq, Finset.mem_coe, Nat.mem_primeFactors, + simp only [Set.mulIndicator_apply, Set.mem_ofPred_eq, Finset.mem_coe, Nat.mem_primeFactors, ne_eq, mul_ite, mul_one] by_cases h : p.Prime; swap · simp only [h, false_and, if_false] diff --git a/Mathlib/NumberTheory/FLT/Four.lean b/Mathlib/NumberTheory/FLT/Four.lean index 6f17dfbc8a98a0..ec953d51e0cb79 100644 --- a/Mathlib/NumberTheory/FLT/Four.lean +++ b/Mathlib/NumberTheory/FLT/Four.lean @@ -66,7 +66,7 @@ theorem exists_minimal {a b c : ℤ} (h : Fermat42 a b c) : ∃ a0 b0 c0, Minima let S : Set ℕ := { n | ∃ s : ℤ × ℤ × ℤ, Fermat42 s.1 s.2.1 s.2.2 ∧ n = Int.natAbs s.2.2 } have S_nonempty : S.Nonempty := by use Int.natAbs c - rw [Set.mem_setOf_eq] + rw [Set.mem_ofPred_eq] use ⟨a, ⟨b, c⟩⟩ let m : ℕ := Nat.find S_nonempty have m_mem : m ∈ S := Nat.find_spec S_nonempty diff --git a/Mathlib/NumberTheory/FactorisationProperties.lean b/Mathlib/NumberTheory/FactorisationProperties.lean index cea8ccdfdc3df0..a3842be4fcaaa2 100644 --- a/Mathlib/NumberTheory/FactorisationProperties.lean +++ b/Mathlib/NumberTheory/FactorisationProperties.lean @@ -189,7 +189,7 @@ theorem infinite_odd_deficient : {n : ℕ | Odd n ∧ n.Deficient}.Infinite := b rw [Set.infinite_iff_exists_gt] intro n obtain ⟨p, ⟨_, h2⟩⟩ := exists_infinite_primes (max (n + 1) 3) - exact ⟨p, Set.mem_setOf.mpr ⟨Prime.odd_of_ne_two h2 (Ne.symm (ne_of_lt (by grind))), + exact ⟨p, Set.mem_ofPred.mpr ⟨Prime.odd_of_ne_two h2 (Ne.symm (ne_of_lt (by grind))), Prime.deficient h2⟩, by grind⟩ theorem abundant_iff_sum_divisors : Abundant n ↔ 2 * n < ∑ i ∈ n.divisors, i := by diff --git a/Mathlib/NumberTheory/FermatPsp.lean b/Mathlib/NumberTheory/FermatPsp.lean index 4d0183bf4831e3..b62a748e8003d3 100644 --- a/Mathlib/NumberTheory/FermatPsp.lean +++ b/Mathlib/NumberTheory/FermatPsp.lean @@ -345,8 +345,11 @@ theorem frequently_atTop_fermatPsp {b : ℕ} (h : 1 ≤ b) : ∃ᶠ n in Filter. /-- Infinite set variant of `Nat.exists_infinite_pseudoprimes` -/ -theorem infinite_setOf_pseudoprimes {b : ℕ} (h : 1 ≤ b) : +theorem infinite_setOfPred_pseudoprimes {b : ℕ} (h : 1 ≤ b) : Set.Infinite { n : ℕ | FermatPsp n b } := Nat.frequently_atTop_iff_infinite.mp (frequently_atTop_fermatPsp h) +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_pseudoprimes := infinite_setOfPred_pseudoprimes + end Nat diff --git a/Mathlib/NumberTheory/FrobeniusNumber.lean b/Mathlib/NumberTheory/FrobeniusNumber.lean index 5af9915fceace7..2922468d355663 100644 --- a/Mathlib/NumberTheory/FrobeniusNumber.lean +++ b/Mathlib/NumberTheory/FrobeniusNumber.lean @@ -50,7 +50,7 @@ def FrobeniusNumber (n : ℕ) (s : Set ℕ) : Prop := theorem frobeniusNumber_iff {n : ℕ} {s : Set ℕ} : FrobeniusNumber n s ↔ n ∉ AddSubmonoid.closure s ∧ ∀ k > n, k ∈ AddSubmonoid.closure s := by - simp_rw [FrobeniusNumber, IsGreatest, upperBounds, Set.mem_setOf, not_imp_comm, not_le] + simp_rw [FrobeniusNumber, IsGreatest, upperBounds, Set.mem_ofPred, not_imp_comm, not_le] variable {m n : ℕ} @@ -173,12 +173,15 @@ theorem exists_mem_closure_of_ge : ∃ n, ∀ m ≥ n, setGcd s ∣ m → m ∈ ⟨n, fun m ge dvd ↦ (Submodule.span_nat_eq_addSubmonoidClosure s).le (Submodule.span_mono hts (hn m ge dvd))⟩ -theorem finite_setOf_setGcd_dvd_and_mem_span : +theorem finite_setOfPred_setGcd_dvd_and_mem_span : {n | setGcd s ∣ n ∧ n ∉ Ideal.span s}.Finite := have ⟨n, hn⟩ := exists_mem_closure_of_ge s (Finset.range n).finite_toSet.subset fun m h ↦ Finset.mem_range.mpr <| lt_of_not_ge fun ge ↦ h.2 <| (Submodule.span_nat_eq_addSubmonoidClosure s).ge (hn m ge h.1) +@[deprecated (since := "2026-07-09")] +alias finite_setOf_setGcd_dvd_and_mem_span := finite_setOfPred_setGcd_dvd_and_mem_span + /-- `ℕ` is a Noetherian `ℕ`-module, i.e., `ℕ` is a Noetherian semiring. -/ instance : IsNoetherian ℕ ℕ where noetherian s := by diff --git a/Mathlib/NumberTheory/Height/NumberField.lean b/Mathlib/NumberTheory/Height/NumberField.lean index ed5f89a4f27a54..60cff737cac4dc 100644 --- a/Mathlib/NumberTheory/Height/NumberField.lean +++ b/Mathlib/NumberTheory/Height/NumberField.lean @@ -24,7 +24,7 @@ and set up some API. * Heights on number fields satisfy the **Northcott property**: If `K` is a number field, then the set of elements of `K` of bounded (multiplicative or logarithmic) height is finite; - see `NumberField.finite_setOf_mulHeight₁_le` and `NumberField.finite_setOf_logHeight₁_le`. + see `NumberField.finite_setOfPred_mulHeight₁_le` and `NumberField.finite_setOfPred_logHeight₁_le`. We also provide instances for `Northcott (mulHeight₁ (K := K))` (which automatically leads also to `Northcott (logHeight₁ (K := K))`). @@ -171,7 +171,7 @@ private lemma absNorm_mul_finprod_finitePlace_eq_one_aux [Nonempty ι] (hx : ∀ rw [multiplicity_iSup _ H, map_pow, mul_eq_one_iff_inv_eq₀ h.ne', map_iInf_of_monotone (fun _ ↦ multiplicity ..) (pow_right_monotone <| by lia), map_iInf_of_monotone _ Nat.mono_cast, - map_iInf_of_antitoneOn antitoneOn_inv_pos fun _ ↦ Set.mem_setOf.mpr h] + map_iInf_of_antitoneOn antitoneOn_inv_pos fun _ ↦ Set.mem_ofPred.mpr h] refine iSup_congr fun i ↦ ?_ rw [← mul_eq_one_iff_inv_eq₀ h.ne', mul_comm, Nat.cast_pow] exact apply_mul_absNorm_pow_eq_one v (hx i) @@ -200,13 +200,13 @@ end NumberField We show that a number field `K` has the **Northcott property** with respect to the multiplicative and with respect to the logarithmic height, i.e., for any `B : ℝ` the set of elements `x : K` such that `mulHeight₁ x ≤ B` (resp., `logHeight₁ x ≤ B`) is finite. -See `NumberField.finite_setOf_mulHeight₁_le` and `NumberField.finite_setOf_logHeight₁_le`. +See `NumberField.finite_setOfPred_mulHeight₁_le` and `NumberField.finite_setOfPred_logHeight₁_le`. The main idea of the proof is as follows. We show that for every `x : K` there is `n : ℕ` such that `n * x` is an algebraic integer and `n ≤ mulHeight₁ x`; see `NumberField.exists_nat_le_mulHeight₁`. We also show that the set of `a : 𝓞 K` such that `mulHeight₁ (a / n)` is bounded is finite; -see `NumberField.finite_setOf_prod_infinitePlace_iSup_le`. The result for the multiplicative height -follows by combining these two ingredients, and the result for the logarithmic height follows +see `NumberField.finite_setOfPred_prod_infinitePlace_iSup_le`. The result for the multiplicative +height follows by combining these two ingredients, and the result for the logarithmic height follows from that for any field with a family of admissible absolute values (see `Mathlib.NumberTheory.Height.Northcott`). -/ @@ -331,7 +331,7 @@ private lemma infinitePlace_apply_le_of_prod_le {n : ℕ} (hn : n ≠ 0) (B : end withFinset -lemma finite_setOf_prod_infinitePlace_iSup_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : +lemma finite_setOfPred_prod_infinitePlace_iSup_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : {x : 𝓞 K | ∏ v : InfinitePlace K, (⨆ i, v (![(x : K), n] i)) ^ v.mult ≤ B}.Finite := by set B' := B / n ^ (totalWeight K - 1) suffices Set.BijOn ((↑) : 𝓞 K → K) {x | ∀ (v : InfinitePlace K), v x ≤ B'} @@ -339,40 +339,46 @@ lemma finite_setOf_prod_infinitePlace_iSup_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) this.finite_iff_finite.mpr (Embeddings.finite_of_norm_le K ℂ B') |>.subset fun _ _ ↦ by grind [infinitePlace_apply_le_of_prod_le hn B] refine .mk (fun x hx ↦ ?_) (fun _ _ _ _ ↦ RingOfIntegers.ext) fun a ha ↦ ?_ <;> - simp only [Set.mem_image, Set.mem_setOf_eq] at * + simp only [Set.mem_image, Set.mem_ofPred_eq] at * · exact ⟨x.isIntegral_coe, fun φ ↦ hx <| .mk φ⟩ · rw [← mem_integralClosure_iff ℤ K] at ha exact ⟨⟨a, ha.1⟩, fun v ↦ v.norm_embedding_eq a ▸ ha.2 v.embedding, rfl⟩ +@[deprecated (since := "2026-07-09")] +alias finite_setOf_prod_infinitePlace_iSup_le := finite_setOfPred_prod_infinitePlace_iSup_le + /-- The set of `a : 𝓞 K` such that `mulHeight₁ (a / n) = mulHeight ![a, n]` is bounded (for some given nonzero `n : ℕ`) is finite. -/ -lemma finite_setOf_mulHeight_nat_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : +lemma finite_setOfPred_mulHeight_nat_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : {a : 𝓞 K | mulHeight ![(a : K), n] ≤ B}.Finite := by suffices {a : 𝓞 K | mulHeight ![(a : K), n] ≤ B} ⊆ {a | ∏ v : InfinitePlace K, (⨆ i, v (![(a : K), n] i)) ^ v.mult ≤ n ^ totalWeight K * B} from - (finite_setOf_prod_infinitePlace_iSup_le hn _).subset this - refine Set.setOf_subset_setOf_of_imp fun a ha ↦ ?_ + (finite_setOfPred_prod_infinitePlace_iSup_le hn _).subset this + refine Set.ofPred_subset_ofPred_of_imp fun a ha ↦ ?_ rw [mulHeight_eq <| by simp [hn], mul_comm] at ha grw [← ha, ← mul_assoc, ← one_le_pow_totalWeight_mul_finprod hn, one_mul] -- nonnegativity side goal exact Finset.prod_nonneg fun _ _ ↦ pow_nonneg (Real.iSup_nonneg_of_nonnegHomClass ..) _ +@[deprecated (since := "2026-07-09")] +alias finite_setOf_mulHeight_nat_le := finite_setOfPred_mulHeight_nat_le + variable (K) in /- The set of `x : K` such that `mulHeight₁ x` is bounded and `n * x` is integral (for some given nonzero `n : ℕ`) is finite. This is a stepping stone for the proof of the next result, which is strictly stronger. -/ -private lemma finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : +private lemma finite_setOfPred_isIntegral_nat_mul_and_mulHeight₁_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) : {x : K | IsIntegral ℤ (n * x) ∧ mulHeight₁ x ≤ B}.Finite := by have hn' : (n : K) ≠ 0 := mod_cast hn suffices Set.BijOn (fun a : 𝓞 K ↦ (a / n : K)) {a | mulHeight ![(a : K), n] ≤ B} {x | IsIntegral ℤ (n * x) ∧ mulHeight₁ x ≤ B} from - this.finite_iff_finite.mp <| finite_setOf_mulHeight_nat_le hn B + this.finite_iff_finite.mp <| finite_setOfPred_mulHeight_nat_le hn B refine .mk (fun a ha ↦ ?_) (fun a _ b _ h ↦ ?_) fun x ⟨hx₁, hx₂⟩ ↦ ?_ - · simp only [Set.mem_setOf_eq] at ha ⊢ + · simp only [Set.mem_ofPred_eq] at ha ⊢ rw [mul_div_cancel₀ (a : K) hn', mulHeight₁_div_eq_mulHeight] exact ⟨a.isIntegral_coe, ha⟩ · rwa [div_left_inj' hn', RingOfIntegers.eq_iff] at h - · simp only [Set.mem_setOf_eq, Set.mem_image] + · simp only [Set.mem_ofPred_eq, Set.mem_image] obtain ⟨a, ha⟩ : ∃ a : 𝓞 K, n * x = a := ⟨⟨_, hx₁⟩, rfl⟩ refine ⟨a, ?_, (EuclideanDomain.eq_div_of_mul_eq_right hn' ha).symm⟩ rwa [← ha, ← mulHeight₁_div_eq_mulHeight, mul_div_cancel_left₀ x hn'] @@ -380,28 +386,34 @@ private lemma finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le {n : ℕ} (hn variable (K) in /-- A number field `K` satisfies the **Northcott property**: The set of elements of bounded multiplicative height is finite. -/ -theorem finite_setOf_mulHeight₁_le (B : ℝ) : {x : K | mulHeight₁ x ≤ B}.Finite := by +theorem finite_setOfPred_mulHeight₁_le (B : ℝ) : {x : K | mulHeight₁ x ≤ B}.Finite := by have H : {x : K | mulHeight₁ x ≤ B} = ⋃ n : Fin ⌊B⌋₊, {x : K | IsIntegral ℤ ((n + 1) * x) ∧ mulHeight₁ x ≤ B} := by ext x : 1 obtain ⟨n, hn₀, hn₁, hn⟩ := exists_nat_le_mulHeight₁ x - simp only [Set.mem_setOf_eq, Set.mem_iUnion, exists_and_right, iff_and_self] + simp only [Set.mem_ofPred_eq, Set.mem_iUnion, exists_and_right, iff_and_self] refine fun h ↦ ⟨⟨n - 1, by grind [Nat.le_floor <| hn₁.trans h]⟩, ?_⟩ rwa [← Nat.cast_add_one, Nat.sub_one_add_one hn₀] rw [H] exact Set.finite_iUnion fun n ↦ - mod_cast finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le K (Nat.zero_ne_add_one n).symm B + mod_cast finite_setOfPred_isIntegral_nat_mul_and_mulHeight₁_le K (Nat.zero_ne_add_one n).symm B + +@[deprecated (since := "2026-07-09")] +alias finite_setOf_mulHeight₁_le := finite_setOfPred_mulHeight₁_le instance : Northcott (mulHeight₁ (K := K)) where - finite_le := finite_setOf_mulHeight₁_le K + finite_le := finite_setOfPred_mulHeight₁_le K variable (K) in /-- A number field `K` satisfies the **Northcott property**: The set of elements of bounded logarithmic height is finite. -/ -theorem finite_setOf_logHeight₁_le (B : ℝ) : +theorem finite_setOfPred_logHeight₁_le (B : ℝ) : {x : K | logHeight₁ x ≤ B}.Finite := Northcott.finite_le B +@[deprecated (since := "2026-07-09")] +alias finite_setOf_logHeight₁_le := finite_setOfPred_logHeight₁_le + end NumberField end Northcott diff --git a/Mathlib/NumberTheory/LSeries/Dirichlet.lean b/Mathlib/NumberTheory/LSeries/Dirichlet.lean index b520ffa4266f26..07345140093274 100644 --- a/Mathlib/NumberTheory/LSeries/Dirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/Dirichlet.lean @@ -178,7 +178,7 @@ lemma not_LSeriesSummable_at_one {N : ℕ} (hN : N ≠ 0) (χ : DirichletCharact refine fun h ↦ (Real.not_summable_indicator_one_div_natCast hN 1) ?_ refine h.norm.of_nonneg_of_le (fun m ↦ Set.indicator_apply_nonneg (fun _ ↦ by positivity)) (fun n ↦ ?_) - simp only [norm_term_eq, Set.indicator, Set.mem_setOf_eq] + simp only [norm_term_eq, Set.indicator, Set.mem_ofPred_eq] split_ifs with h₁ h₂ · simp [h₂] · simp [h₁, χ.map_one] diff --git a/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean b/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean index 947ea4773befb0..9ccc38f52d669a 100644 --- a/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean +++ b/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean @@ -360,7 +360,7 @@ lemma deriv_LFunctionTrivChar₁_apply_of_ne_one {s : ℂ} (hs : s ≠ 1) : have H : deriv (LFunctionTrivChar₁ n) s = deriv (fun w ↦ (w - 1) * LFunctionTrivChar n w) s := by refine eventuallyEq_iff_exists_mem.mpr ?_ |>.deriv_eq - exact ⟨_, isOpen_ne.mem_nhds hs, fun _ hw ↦ Function.update_of_ne (Set.mem_setOf.mp hw) ..⟩ + exact ⟨_, isOpen_ne.mem_nhds hs, fun _ hw ↦ Function.update_of_ne (Set.mem_ofPred.mp hw) ..⟩ rw [H, deriv_fun_mul (by fun_prop) (differentiableAt_LFunction _ s (.inl hs)), deriv_sub_const, deriv_id'', one_mul, add_comm] @@ -376,7 +376,7 @@ lemma continuousOn_neg_logDeriv_LFunctionTrivChar₁ : rcases eq_or_ne w 1 with rfl | hw' · exact LFunctionTrivChar₁_apply_one_ne_zero _ · rw [LFunctionTrivChar₁, Function.update_of_ne hw', mul_ne_zero_iff] - exact ⟨sub_ne_zero_of_ne hw', (Set.mem_setOf.mp hw).resolve_left hw'⟩ + exact ⟨sub_ne_zero_of_ne hw', (Set.mem_ofPred.mp hw).resolve_left hw'⟩ end trivial diff --git a/Mathlib/NumberTheory/LSeries/Injectivity.lean b/Mathlib/NumberTheory/LSeries/Injectivity.lean index ce52398f832e09..ea74e592e3d2b2 100644 --- a/Mathlib/NumberTheory/LSeries/Injectivity.lean +++ b/Mathlib/NumberTheory/LSeries/Injectivity.lean @@ -97,7 +97,7 @@ lemma LSeries.tendsto_cpow_mul_atTop {f : ℕ → ℂ} {n : ℕ} (h : ∀ m ≤ have H₁ : (k / (n + 1) : ℂ) = (k / (n + 1) : ℝ) := by push_cast; rfl have H₂ : (n + 1) / k < (1 : ℝ) := (div_lt_one <| mod_cast n.succ_pos.trans H).mpr <| mod_cast H - simp only [Set.mem_setOf_eq, H, Set.indicator_of_mem, F] + simp only [Set.mem_ofPred_eq, H, Set.indicator_of_mem, F] conv => enter [1, x] rw [div_eq_mul_inv, H₁, ← ofReal_cpow H₀, ← ofReal_inv, ← Real.inv_rpow H₀, inv_div] @@ -110,7 +110,7 @@ lemma LSeries.tendsto_cpow_mul_atTop {f : ℕ → ℂ} {n : ℕ} (h : ∀ m ≤ filter_upwards [mem_atTop y] with y' hy' k -- it remains to show that `‖F y' k‖ ≤ ‖F y k‖` (for `y' ≥ y`) rcases lt_or_ge (n + 1) k with H | H - · simp only [Set.mem_setOf_eq, H, Set.indicator_of_mem, norm_div, norm_cpow_real, + · simp only [Set.mem_ofPred_eq, H, Set.indicator_of_mem, norm_div, norm_cpow_real, Complex.norm_natCast, F] rw [← Nat.cast_one, ← Nat.cast_add, Complex.norm_natCast] have hkn : 1 ≤ (k / (n + 1 :) : ℝ) := diff --git a/Mathlib/NumberTheory/LSeries/Positivity.lean b/Mathlib/NumberTheory/LSeries/Positivity.lean index f4b11704341d94..e7855803a338e1 100644 --- a/Mathlib/NumberTheory/LSeries/Positivity.lean +++ b/Mathlib/NumberTheory/LSeries/Positivity.lean @@ -72,7 +72,7 @@ lemma positive_of_differentiable_of_eqOn {a : ℕ → ℂ} (ha₀ : 0 ≤ a) (ha have hxy : x < max x y + 1 := (le_max_left x y).trans_lt (lt_add_one _) have hxy' : abscissaOfAbsConv a < max x y + 1 := hx.trans_lt <| mod_cast hxy have hys : (max x y + 1 : ℂ) ∈ {s | x < s.re} := by - simp only [Set.mem_setOf_eq, add_re, ofReal_re, one_re, hxy] + simp only [Set.mem_ofPred_eq, add_re, ofReal_re, one_re, hxy] have hfx : 0 < f (max x y + 1) := by simpa only [hf' hys, ofReal_add, ofReal_one] using positive ha₀ ha₁ hxy' refine (hfx.trans_le <| hf.apply_le_of_iteratedDeriv_alternating (fun n _ ↦ ?_) ?_) diff --git a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean index 5603ed3b22c07d..0c9debb74db2a0 100644 --- a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean +++ b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean @@ -58,7 +58,7 @@ The main steps of the proof are as follows. ## Main Result We give two versions of **Dirichlet's Theorem**: -* `Nat.infinite_setOf_prime_and_eq_mod` states that the set of primes `p` +* `Nat.infinite_setOfPred_prime_and_eq_mod` states that the set of primes `p` such that `(p : ZMod q) = a` is infinite (when `a` is invertible in `ZMod q`). * `Nat.forall_exists_prime_gt_and_eq_mod` states that for any natural number `n` there is a prime `p > n` such that `(p : ZMod q) = a`. @@ -103,7 +103,7 @@ lemma residueClass_le (n : ℕ) : residueClass a n ≤ vonMangoldt n := @[simp] lemma residueClass_apply_zero : residueClass a 0 = 0 := by - simp only [Set.indicator_apply_eq_zero, Set.mem_setOf_eq, Nat.cast_zero, map_zero, + simp only [Set.indicator_apply_eq_zero, Set.mem_ofPred_eq, Nat.cast_zero, map_zero, implies_true] lemma abscissaOfAbsConv_residueClass_le_one : @@ -114,9 +114,9 @@ lemma abscissaOfAbsConv_residueClass_le_one : convert! this.indicator {n : ℕ | (n : ZMod q) = a} ext1 n by_cases hn : (n : ZMod q) = a - · simp +contextual only [term, Set.indicator, Set.mem_setOf_eq, hn, ↓reduceIte, apply_ite, + · simp +contextual only [term, Set.indicator, Set.mem_ofPred_eq, hn, ↓reduceIte, apply_ite, ite_self] - · simp +contextual only [term, Set.mem_setOf_eq, hn, not_false_eq_true, Set.indicator_of_notMem, + · simp +contextual only [term, Set.mem_ofPred_eq, hn, not_false_eq_true, Set.indicator_of_notMem, ofReal_zero, zero_div, ite_self] /-- The set we are interested in (prime numbers in the residue class `a`) is the same as the support @@ -126,9 +126,9 @@ lemma support_residueClass_prime_div : Function.support (fun n : ℕ ↦ (if n.Prime then residueClass a n else 0) / n) = {p : ℕ | p.Prime ∧ (p : ZMod q) = a} := by simp only [Function.support, ne_eq, div_eq_zero_iff, ite_eq_right_iff, - Set.indicator_apply_eq_zero, Set.mem_setOf_eq, Nat.cast_eq_zero, not_or, Classical.not_imp] + Set.indicator_apply_eq_zero, Set.mem_ofPred_eq, Nat.cast_eq_zero, not_or, Classical.not_imp] ext1 p - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] exact ⟨fun H ↦ ⟨H.1.1, H.1.2.1⟩, fun H ↦ ⟨⟨H.1, H.2, vonMangoldt_ne_zero_iff.mpr H.1.isPrimePow⟩, H.1.ne_zero⟩⟩ @@ -226,7 +226,7 @@ lemma residueClass_apply (ha : IsUnit a) (n : ℕ) : residueClass a n = (q.totient : ℂ)⁻¹ * ∑ χ : DirichletCharacter ℂ q, χ a⁻¹ * χ n * vonMangoldt n := by rw [eq_inv_mul_iff_mul_eq₀ <| mod_cast (Nat.totient_pos.mpr q.pos_of_neZero).ne'] - simp +contextual only [residueClass, Set.indicator_apply, Set.mem_setOf_eq, apply_ite, + simp +contextual only [residueClass, Set.indicator_apply, Set.mem_ofPred_eq, apply_ite, ofReal_zero, mul_zero, ← Finset.sum_mul, sum_char_inv_mul_char_eq ℂ ha n, eq_comm (a := a), ite_mul, zero_mul, ↓reduceIte, ite_self] @@ -277,15 +277,15 @@ lemma continuousOn_LFunctionResidueClassAux' : simp only [LFunctionResidueClassAux, sub_eq_add_neg] refine continuousOn_const.mul <| ContinuousOn.add ?_ ?_ · refine (continuousOn_neg_logDeriv_LFunctionTrivChar₁ q).mono fun s hs ↦ ?_ - simp only [ne_eq, Set.mem_setOf_eq] at hs + simp only [ne_eq, Set.mem_ofPred_eq] at hs tauto · simp only [← Finset.sum_neg_distrib, mul_div_assoc, ← mul_neg, ← neg_div] refine continuousOn_finsetSum _ fun χ hχ ↦ continuousOn_const.mul ?_ replace hχ : χ ≠ 1 := by simpa only [ne_eq, Finset.mem_compl, Finset.mem_singleton] using hχ refine (continuousOn_neg_logDeriv_LFunction_of_nontriv hχ).mono fun s hs ↦ ?_ - simp only [ne_eq, Set.mem_setOf_eq] at hs + simp only [ne_eq, Set.mem_ofPred_eq] at hs rcases hs with rfl | hs - · simp only [ne_eq, Set.mem_setOf_eq, one_re, le_refl, + · simp only [ne_eq, Set.mem_ofPred_eq, one_re, le_refl, LFunction_ne_zero_of_one_le_re χ (.inl hχ), not_false_eq_true] · exact hs χ @@ -297,9 +297,9 @@ lemma continuousOn_LFunctionResidueClassAux : ContinuousOn (LFunctionResidueClassAux a) {s | 1 ≤ s.re} := by refine (continuousOn_LFunctionResidueClassAux' a).mono fun s hs ↦ ?_ rcases eq_or_ne s 1 with rfl | hs₁ - · simp only [ne_eq, Set.mem_setOf_eq, true_or] - · simp only [ne_eq, Set.mem_setOf_eq, hs₁, false_or] - exact fun χ ↦ LFunction_ne_zero_of_one_le_re χ (.inr hs₁) <| Set.mem_setOf.mp hs + · simp only [ne_eq, Set.mem_ofPred_eq, true_or] + · simp only [ne_eq, Set.mem_ofPred_eq, hs₁, false_or] + exact fun χ ↦ LFunction_ne_zero_of_one_le_re χ (.inr hs₁) <| Set.mem_ofPred.mp hs variable {a} @@ -313,7 +313,7 @@ lemma eqOn_LFunctionResidueClassAux (ha : IsUnit a) : (fun s ↦ L ↗(residueClass a) s - (q.totient : ℂ)⁻¹ / (s - 1)) {s | 1 < s.re} := by intro s hs - replace hs := Set.mem_setOf.mp hs + replace hs := Set.mem_ofPred.mp hs simp only [LSeries_residueClass_eq ha hs, LFunctionResidueClassAux] rw [neg_div, ← neg_add', mul_neg, ← neg_mul, div_eq_mul_one_div (q.totient : ℂ)⁻¹, sub_eq_add_neg, ← neg_mul, ← mul_add] @@ -362,7 +362,7 @@ lemma LSeries_residueClass_lower_bound (ha : IsUnit a) : simp only [ofReal_tsum, ofReal_div, ofReal_cpow (Nat.cast_nonneg _), ofReal_natCast, ofReal_add, ofReal_inv, ofReal_sub, ofReal_one] simp_rw [← LFunctionResidueClassAux_real ha hx, - eqOn_LFunctionResidueClassAux ha <| Set.mem_setOf.mpr (ofReal_re x ▸ hx), sub_add_cancel, + eqOn_LFunctionResidueClassAux ha <| Set.mem_ofPred.mpr (ofReal_re x ▸ hx), sub_add_cancel, LSeries, term] refine tsum_congr fun n ↦ ?_ split_ifs with hn @@ -371,7 +371,7 @@ lemma LSeries_residueClass_lower_bound (ha : IsUnit a) : have : ContinuousOn (fun x : ℝ ↦ (LFunctionResidueClassAux a x).re) (Set.Icc 1 2) := continuous_re.continuousOn.comp (t := Set.univ) (continuousOn_LFunctionResidueClassAux a) (fun ⦃x⦄ a ↦ trivial) |>.comp continuous_ofReal.continuousOn fun x hx ↦ by - simpa only [Set.mem_setOf_eq, ofReal_re] using hx.1 + simpa only [Set.mem_ofPred_eq, ofReal_re] using hx.1 obtain ⟨C, hC⟩ := bddBelow_def.mp <| IsCompact.bddBelow_image isCompact_Icc this replace hC {x : ℝ} (hx : x ∈ Set.Icc 1 2) : C ≤ (LFunctionResidueClassAux a x).re := hC (LFunctionResidueClassAux a x).re <| @@ -435,19 +435,22 @@ variable {q : ℕ} [NeZero q] {a : ZMod q} /-- **Dirichlet's Theorem** on primes in arithmetic progression: if `q` is a positive integer and `a : ZMod q` is a unit, then there are infinitely many prime numbers `p` such that `(p : ZMod q) = a`. -/ -theorem infinite_setOf_prime_and_eq_mod (ha : IsUnit a) : +theorem infinite_setOfPred_prime_and_eq_mod (ha : IsUnit a) : {p : ℕ | p.Prime ∧ (p : ZMod q) = a}.Infinite := by by_contra! H exact not_summable_residueClass_prime_div ha <| summable_of_hasFiniteSupport <| show Set.Finite _ from support_residueClass_prime_div a ▸ H +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_prime_and_eq_mod := infinite_setOfPred_prime_and_eq_mod + /-- **Dirichlet's Theorem** on primes in arithmetic progression: if `q` is a positive integer and `a : ZMod q` is a unit, then there are infinitely many prime numbers `p` such that `(p : ZMod q) = a`. -/ theorem forall_exists_prime_gt_and_eq_mod (ha : IsUnit a) (n : ℕ) : ∃ p > n, p.Prime ∧ (p : ZMod q) = a := by - obtain ⟨p, hp₁, hp₂⟩ := Set.infinite_iff_exists_gt.mp (infinite_setOf_prime_and_eq_mod ha) n - exact ⟨p, hp₂.gt, Set.mem_setOf.mp hp₁⟩ + obtain ⟨p, hp₁, hp₂⟩ := Set.infinite_iff_exists_gt.mp (infinite_setOfPred_prime_and_eq_mod ha) n + exact ⟨p, hp₂.gt, Set.mem_ofPred.mp hp₁⟩ /-- **Dirichlet's Theorem** on primes in arithmetic progression: if `q` is a positive integer and `a : ℤ` is coprime to `q`, then there are infinitely many prime numbers `p` @@ -476,10 +479,13 @@ lemma frequently_atTop_prime_and_modEq {q a : ℕ} (hq : q ≠ 0) (h : a.Coprime obtain ⟨p, hn, hp, ha⟩ := forall_exists_prime_gt_and_modEq n hq h exact ⟨p, hn.le, hp, ha⟩ -lemma infinite_setOf_prime_and_modEq {q a : ℕ} (hq : q ≠ 0) (h : a.Coprime q) : +lemma infinite_setOfPred_prime_and_modEq {q a : ℕ} (hq : q ≠ 0) (h : a.Coprime q) : Set.Infinite {p : ℕ | p.Prime ∧ p ≡ a [MOD q]} := frequently_atTop_iff_infinite.1 (frequently_atTop_prime_and_modEq hq h) +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_prime_and_modEq := infinite_setOfPred_prime_and_modEq + end Nat end DirichletsTheorem diff --git a/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean b/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean index 84525ffbd6d2d3..4fe9cf2f5e7cc3 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean @@ -215,7 +215,7 @@ theorem quadraticChar_card_sqrts (hF : ringChar F ≠ 2) (a : F) : #{x : F | x ^ 2 = a}.toFinset = quadraticChar F a + 1 := by -- we consider the cases `a = 0`, `a` is a nonzero square and `a` is a nonsquare in turn by_cases h₀ : a = 0 - · simp only [h₀, sq_eq_zero_iff, Set.setOf_eq_eq_singleton, Set.toFinset_card, + · simp only [h₀, sq_eq_zero_iff, Set.ofPred_eq_eq_singleton, Set.toFinset_card, Set.card_singleton, Int.natCast_succ, Int.ofNat_zero, MulChar.map_zero] · set s := {x : F | x ^ 2 = a}.toFinset by_cases h : IsSquare a @@ -225,7 +225,7 @@ theorem quadraticChar_card_sqrts (hF : ringChar F ≠ 2) (a : F) : have h₁ : s = [b, -b].toFinset := by ext1 rw [← pow_two] at h - simp_rw [s, Set.toFinset_setOf, mem_filter_univ, h, List.toFinset_cons, List.toFinset_nil, + simp_rw [s, Set.toFinset_ofPred, mem_filter_univ, h, List.toFinset_cons, List.toFinset_nil, insert_empty_eq, mem_insert, mem_singleton] exact sq_eq_sq_iff_eq_or_eq_neg norm_cast diff --git a/Mathlib/NumberTheory/LocalField/Basic.lean b/Mathlib/NumberTheory/LocalField/Basic.lean index 5d67a6c2ae686a..2e27508baf8db5 100644 --- a/Mathlib/NumberTheory/LocalField/Basic.lean +++ b/Mathlib/NumberTheory/LocalField/Basic.lean @@ -81,7 +81,7 @@ lemma isCompact_closedBall (γ : ValueGroupWithZero K) : IsCompact { x | valuati · obtain ⟨r, rfl⟩ := ValuativeRel.valuation_surjective r simp only [ne_eq, map_eq_zero] at hr refine ⟨r ^ 2, by simpa using hr, by simpa [pow_two], fun x hx ↦ hrs ?_⟩ - simp only [map_pow, Set.mem_setOf_eq] at hx ⊢ + simp only [map_pow, Set.mem_ofPred_eq] at hx ⊢ exact hx.trans_lt (by simpa [pow_two, hr]) · refine ⟨r', hr', hr, .trans ?_ hrs⟩ intro x hx @@ -93,8 +93,8 @@ lemma isCompact_closedBall (γ : ValueGroupWithZero K) : IsCompact { x | valuati (Homeomorph.mulLeft₀ (γ / r) (by simp [hr, div_eq_zero_iff, hγ])).continuous using 1 refine .trans ?_ (Equiv.image_eq_preimage_symm _ _).symm ext x - simp only [Set.mem_setOf_eq, Homeomorph.coe_symm_toEquiv, Homeomorph.mulLeft₀_symm_apply, inv_div, - Set.preimage_setOf_eq, map_mul, map_div₀, Valuation.restrict_le_iff] + simp only [Set.mem_ofPred_eq, Homeomorph.coe_symm_toEquiv, Homeomorph.mulLeft₀_symm_apply, + inv_div, Set.preimage_ofPred_eq, map_mul, map_div₀, Valuation.restrict_le_iff] rw [div_mul_eq_mul_div, div_le_iff₀ (by simp [hγ])] simp only [IsValuativeTopology.v_eq_valuation, ← map_mul, Valuation.restrict_le_iff] simp [hr] diff --git a/Mathlib/NumberTheory/Modular.lean b/Mathlib/NumberTheory/Modular.lean index 8bacfaaf39e077..caf3b202dfb850 100644 --- a/Mathlib/NumberTheory/Modular.lean +++ b/Mathlib/NumberTheory/Modular.lean @@ -861,7 +861,7 @@ private lemma mem_closure_of_one_lt_norm {x : ℍ} (hxnorm : 1 < ‖(x : ℂ)‖ apply mem_closure_of_frequently_of_tendsto (α := ℝ) (b := 𝓝[<] 1) (f := fun t ↦ ofComplex (t * x)) · apply Filter.Eventually.frequently - simp only [fdo, Set.mem_setOf, Filter.eventually_and, one_lt_normSq_iff] + simp only [fdo, Set.mem_ofPred, Filter.eventually_and, one_lt_normSq_iff] refine ⟨Filter.Tendsto.eventually_const_lt hxnorm (.mono_left ?_ nhdsWithin_le_nhds), ?_⟩ · have : ContinuousAt (fun a : ℝ ↦ (ofComplex (a * x : ℂ) : ℂ)) 1 := by refine .comp (by fun_prop) ((OpenPartialHomeomorph.continuousAt _ ?_).comp (by fun_prop)) diff --git a/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean b/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean index b90c346505bcef..21aaabe9c2bb3a 100644 --- a/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean +++ b/Mathlib/NumberTheory/ModularForms/CongruenceSubgroups.lean @@ -81,7 +81,7 @@ def Gamma0 : Subgroup SL(2, ℤ) where one_mem' := by simp mul_mem' {a} {b} ha hb := by have h := (Matrix.two_mul_expl a.1 b.1).2.2.1 - simp only [coe_mul, Set.mem_setOf_eq] at * + simp only [coe_mul, Set.mem_ofPred_eq] at * simp [h, ha, hb] inv_mem' {a} ha := by simpa [SL2_inv_expl a] using ha diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean index 9fff85d2bd4375..558dabc828b1df 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean @@ -161,7 +161,7 @@ theorem convexBodyLT'_mem {x : K} : · by_cases hw : IsReal w · exact norm_embedding_eq w _ ▸ h₁ w hw · specialize h₂ w (not_isReal_iff_isComplex.mp hw) - rw [apply_ite (w.embedding x ∈ ·), Set.mem_setOf_eq, + rw [apply_ite (w.embedding x ∈ ·), Set.mem_ofPred_eq, mem_ball_zero_iff, norm_embedding_eq] at h₂ rwa [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)] at h₂ · simpa [if_true] using h₂ w₀.val w₀.prop @@ -207,10 +207,10 @@ theorem convexBodyLT'_volume : have vol_box : ∀ B : ℝ≥0, volume {x : ℂ | |x.re| < 1 ∧ |x.im| < B ^ 2} = 4 * B ^ 2 := by intro B rw [← (Complex.volume_preserving_equiv_real_prod.symm).measure_preimage] - · simp_rw [Set.preimage_setOf_eq, Complex.measurableEquivRealProd_symm_apply] + · simp_rw [Set.preimage_ofPred_eq, Complex.measurableEquivRealProd_symm_apply] rw [show {a : ℝ × ℝ | |a.1| < 1 ∧ |a.2| < B ^ 2} = Set.Ioo (-1 : ℝ) (1 : ℝ) ×ˢ Set.Ioo (-(B : ℝ) ^ 2) ((B : ℝ) ^ 2) by - ext; simp_rw [Set.mem_setOf_eq, Set.mem_prod, Set.mem_Ioo, abs_lt]] + ext; simp_rw [Set.mem_ofPred_eq, Set.mem_prod, Set.mem_Ioo, abs_lt]] simp_rw [volume_eq_prod, prod_prod, Real.volume_Ioo, sub_neg_eq_add, one_add_one_eq_two, ← two_mul, ofReal_mul zero_le_two, ofReal_pow (coe_nonneg B), ofReal_ofNat, ofReal_coe_nnreal, ← mul_assoc, show (2 : ℝ≥0∞) * 2 = 4 by norm_num] @@ -320,22 +320,22 @@ theorem convexBodySum_volume_eq_zero_of_le_zero {B} (hB : B ≤ 0) : · suffices convexBodySum K B = ∅ by rw [this, measure_empty] ext x refine ⟨fun hx => ?_, fun h => h.elim⟩ - rw [Set.mem_setOf] at hx + rw [Set.mem_ofPred] at hx linarith [convexBodySumFun_nonneg x] · suffices convexBodySum K B = { 0 } by rw [this, measure_singleton] ext - rw [convexBodySum, Set.mem_setOf_eq, Set.mem_singleton_iff, hB, ← convexBodySumFun_eq_zero_iff] + rw [convexBodySum, Set.mem_ofPred_eq, Set.mem_singleton_iff, hB, ← convexBodySumFun_eq_zero_iff] exact (convexBodySumFun_nonneg _).ge_iff_eq' theorem convexBodySum_mem {x : K} : mixedEmbedding K x ∈ (convexBodySum K B) ↔ ∑ w : InfinitePlace K, (mult w) * w.val x ≤ B := by - simp_rw [Set.mem_setOf_eq, convexBodySumFun, normAtPlace_apply] + simp_rw [Set.mem_ofPred_eq, convexBodySumFun, normAtPlace_apply] rfl theorem convexBodySum_neg_mem {x : mixedSpace K} (hx : x ∈ (convexBodySum K B)) : -x ∈ (convexBodySum K B) := by - rw [Set.mem_setOf, convexBodySumFun_neg] + rw [Set.mem_ofPred, convexBodySumFun_neg] exact hx theorem convexBodySum_convex : Convex ℝ (convexBodySum K B) := by @@ -378,7 +378,7 @@ theorem convexBodySum_volume : · suffices volume (convexBodySum K 1) = (convexBodySumFactor K) by rw [mul_comm] convert! addHaar_smul volume B (convexBodySum K 1) - · simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hB), Set.preimage_setOf_eq, convexBodySumFun, + · simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hB), Set.preimage_ofPred_eq, convexBodySumFun, normAtPlace_smul, abs_inv, abs_eq_self.mpr (le_of_lt hB), ← mul_assoc, mul_comm, mul_assoc, ← Finset.mul_sum, inv_mul_le_iff₀ hB, mul_one] · rw [abs_pow, ofReal_pow (abs_nonneg _), abs_eq_self.mpr (le_of_lt hB), diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean index 5564cd540dfc55..2b157042796b18 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/FundamentalCone.lean @@ -216,7 +216,7 @@ theorem smul_mem_of_mem (hx : x ∈ fundamentalCone K) (hc : c ≠ 0) : refine ⟨?_, ?_⟩ · rw [Set.mem_preimage, logMap_real_smul hx.2 hc] exact hx.1 - · rw [Set.mem_setOf_eq, mixedEmbedding.norm_smul, mul_eq_zero, not_or] + · rw [Set.mem_ofPred_eq, mixedEmbedding.norm_smul, mul_eq_zero, not_or] exact ⟨pow_ne_zero _ (abs_ne_zero.mpr hc), hx.2⟩ theorem smul_mem_iff_mem (hc : c ≠ 0) : @@ -240,7 +240,7 @@ theorem torsion_smul_mem_of_mem (hx : x ∈ fundamentalCone K) {ζ : (𝓞 K)ˣ} constructor · rw [Set.mem_preimage, logMap_torsion_smul _ hζ] exact hx.1 - · rw [Set.mem_setOf_eq, unitSMul_smul, map_mul, norm_unit, one_mul] + · rw [Set.mem_ofPred_eq, unitSMul_smul, map_mul, norm_unit, one_mul] exact hx.2 theorem unit_smul_mem_iff_mem_torsion (hx : x ∈ fundamentalCone K) (u : (𝓞 K)ˣ) : diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean index c298550aef7ff8..6527683f9be0d4 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean @@ -150,7 +150,7 @@ theorem norm_normAtAllPlaces (x : mixedSpace K) : theorem normAtAllPlaces_mem_fundamentalCone_iff {x : mixedSpace K} : mixedSpaceOfRealSpace (normAtAllPlaces x) ∈ fundamentalCone K ↔ x ∈ fundamentalCone K := by simp_rw [fundamentalCone, Set.mem_sdiff, Set.mem_preimage, logMap_normAtAllPlaces, - Set.mem_setOf_eq, norm_normAtAllPlaces] + Set.mem_ofPred_eq, norm_normAtAllPlaces] end normAtAllPlaces @@ -195,8 +195,8 @@ theorem normAtAllPlaces_normLeOne : refine ⟨⟨⟨?_, ?_⟩, ?_⟩, ?_⟩ · rwa [Set.mem_preimage, ← logMap_normAtAllPlaces] at h₁ · exact fun w ↦ normAtPlace_nonneg w y - · rwa [Set.mem_setOf_eq, ← norm_normAtAllPlaces] at h₂ - · rwa [Set.mem_setOf_eq, ← norm_normAtAllPlaces] at h₃ + · rwa [Set.mem_ofPred_eq, ← norm_normAtAllPlaces] at h₂ + · rwa [Set.mem_ofPred_eq, ← norm_normAtAllPlaces] at h₃ · exact ⟨mixedSpaceOfRealSpace x, ⟨⟨h₁, h₃⟩, h₄⟩, normAtAllPlaces_mixedSpaceOfRealSpace h₂⟩ end normLeOne_def @@ -658,7 +658,7 @@ theorem normAtAllPlaces_normLeOne_eq_image : ext x by_cases hx : ∀ w, 0 < x w · rw [← expMapBasis.right_inv (Set.mem_univ_pi.mpr hx), (injective_expMapBasis K).mem_set_image] - simp only [normAtAllPlaces_normLeOne, Set.mem_inter_iff, Set.mem_setOf_eq, expMapBasis_nonneg, + simp only [normAtAllPlaces_normLeOne, Set.mem_inter_iff, Set.mem_ofPred_eq, expMapBasis_nonneg, Set.mem_preimage, logMap_expMapBasis, implies_true, and_true, norm_expMapBasis, pow_le_one_iff_of_nonneg (Real.exp_nonneg _) Module.finrank_pos.ne', Real.exp_le_one_iff, ne_eq, pow_eq_zero_iff', Real.exp_ne_zero, false_and, not_false_eq_true, Set.mem_univ_pi] diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean index a01452ffe40947..387b4a6aa3f1a4 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean @@ -430,7 +430,7 @@ private theorem volume_eq_two_pow_mul_two_pi_pow_mul_integral_aux using (ha₂ ⟨w, hw⟩).le · rw [normAtAllPlaces_apply, normAtPlace_apply_of_isComplex hw, normAtComplexPlaces_apply_isComplex ⟨w, hw⟩] - · simpa [Set.mem_setOf_eq, normAtComplexPlaces_apply_isReal] using (ha₂ w).ne' + · simpa [Set.mem_ofPred_eq, normAtComplexPlaces_apply_isReal] using (ha₂ w).ne' open scoped Classical in /-- diff --git a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean index 3f1ea6c64af1be..8f836bcb491e38 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/FinitePlace.lean @@ -426,7 +426,7 @@ theorem hasFiniteMulSupport_int {x : 𝓞 K} (h_x_nezero : x ≠ 0) : have h_inj : Set.InjOn FinitePlace.maximalIdeal {w | w.maximalIdeal.asIdeal ∣ span {x}} := Function.Injective.injOn maximalIdeal_injective refine (h.subset ?_).of_finite_image h_inj - simp only [dvd_span_singleton, Set.image_subset_iff, Set.preimage_setOf_eq, subset_refl] + simp only [dvd_span_singleton, Set.image_subset_iff, Set.preimage_ofPred_eq, subset_refl] @[deprecated (since := "2026-03-03")] alias mulSupport_finite_int := hasFiniteMulSupport_int diff --git a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean index 823bf60b254f91..932754de6f4d94 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean @@ -112,11 +112,11 @@ theorem inertiaDeg_eq_finrank [w.LiesOver v] : variable {v w} in theorem inertiaDeg_eq_one (hw : w ∈ unramifiedPlacesOver L v) : v.inertiaDeg w = 1 := - have := (Set.mem_setOf.1 hw).1; hw.2.finrank_eq_one v ▸ inertiaDeg_eq_finrank v w + have := (Set.mem_ofPred.1 hw).1; hw.2.finrank_eq_one v ▸ inertiaDeg_eq_finrank v w variable {v w} in theorem inertiaDeg_eq_two (hw : w ∈ ramifiedPlacesOver L v) : v.inertiaDeg w = 2 := - have := (Set.mem_setOf.1 hw).1; hw.2.finrank_eq_two v ▸ inertiaDeg_eq_finrank v w + have := (Set.mem_ofPred.1 hw).1; hw.2.finrank_eq_two v ▸ inertiaDeg_eq_finrank v w variable (K L) in open scoped Classical in diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index 065b78c17a6c67..782aa0ba644efb 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -137,7 +137,7 @@ theorem cyclotomicRing_isIntegralClosure_of_prime_pow : refine ⟨IsFractionRing.injective _ _, @fun x => ⟨fun h => ⟨⟨x, ?_⟩, rfl⟩, ?_⟩⟩ · obtain ⟨y, rfl⟩ := (isIntegralClosure_adjoin_singleton_of_prime_pow hζ).isIntegral_iff.1 h refine adjoin_mono ?_ y.2 - simp only [Set.singleton_subset_iff, Set.mem_setOf_eq] + simp only [Set.singleton_subset_iff, Set.mem_ofPred_eq] exact hζ.pow_eq_one · rintro ⟨y, rfl⟩ exact IsIntegral.algebraMap ((IsCyclotomicExtension.integral {p ^ k} ℤ _).isIntegral _) @@ -822,7 +822,7 @@ theorem cyclotomicRing_isIntegralClosure : refine ⟨IsFractionRing.injective _ _, fun {x} => ⟨fun h => ⟨⟨x, ?_⟩, rfl⟩, ?_⟩⟩ · obtain ⟨y, rfl⟩ := (isIntegralClosure_adjoin_singleton hζ).isIntegral_iff.1 h refine adjoin_mono ?_ y.2 - simp only [Set.singleton_subset_iff, Set.mem_setOf_eq] + simp only [Set.singleton_subset_iff, Set.mem_ofPred_eq] exact hζ.pow_eq_one · rintro ⟨y, rfl⟩ exact IsIntegral.algebraMap ((IsCyclotomicExtension.integral {n} ℤ _).isIntegral _) diff --git a/Mathlib/NumberTheory/NumberField/DedekindZeta.lean b/Mathlib/NumberTheory/NumberField/DedekindZeta.lean index 3c3d6b09835a76..21e3ce4065fab4 100644 --- a/Mathlib/NumberTheory/NumberField/DedekindZeta.lean +++ b/Mathlib/NumberTheory/NumberField/DedekindZeta.lean @@ -83,7 +83,7 @@ theorem tendsto_sub_one_mul_dedekindZeta_nhdsGT : show Finset.Icc 1 n = Finset.Ioc 0 n from Finset.Icc_succ_left_eq_Ioc _ _, show 1 = Nat.card {I : Ideal (𝓞 K) // absNorm I = 0} by simp [Ideal.absNorm_eq_zero_iff], Finset.sum_Ioc_add_eq_sum_Icc (n.zero_le), - ← Finset.card_preimage_eq_sum_card_image_eq (fun k _ ↦ finite_setOf_absNorm_eq k)] + ← Finset.card_preimage_eq_sum_card_image_eq (fun k _ ↦ finite_setOfPred_absNorm_eq k)] simp [Set.coe_eq_subtype] end NumberField diff --git a/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean b/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean index 4cb403cfcf37e5..ae19ab8ba5f47e 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/Asymptotics.lean @@ -137,7 +137,7 @@ theorem tendsto_norm_le_div_atTop₀ : · filter_upwards [eventually_ge_atTop 0] with s hs have : Fintype {I : (Ideal (𝓞 K))⁰ // absNorm (I : Ideal (𝓞 K)) ≤ s} := by simp_rw [← Nat.le_floor_iff hs] - refine @Fintype.ofFinite _ (finite_setOf_absNorm_le₀ ⌊s⌋₊) + refine @Fintype.ofFinite _ (finite_setOfPred_absNorm_le₀ ⌊s⌋₊) let e := fun C : ClassGroup (𝓞 K) ↦ Equiv.subtypeSubtypeEquivSubtypeInter (fun I : (Ideal (𝓞 K))⁰ ↦ absNorm I.1 ≤ s) (fun I ↦ ClassGroup.mk0 I = C) simp_rw [← Nat.card_congr (e _), Nat.card_eq_fintype_card, Fintype.subtype_card] diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean index 2fe245f773389e..66a9a25966ad6b 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean @@ -125,7 +125,7 @@ theorem pow_eq_one_of_norm_le_one {x : K} (hx₀ : x ≠ 0) (hxi : IsIntegral (hx : ∀ φ : K →+* A, ‖φ x‖ ≤ 1) : ∃ (n : ℕ) (_ : 0 < n), x ^ n = 1 := by obtain ⟨a, -, b, -, habne, h⟩ := Set.Infinite.exists_ne_map_eq_of_mapsTo (f := (x ^ · : ℕ → K)) Set.infinite_univ - (fun a _ => mem_setOf.mpr <| + (fun a _ => mem_ofPred.mpr <| ⟨hxi.pow a, fun φ => by simp [pow_le_one₀ (norm_nonneg (φ x)) <| hx φ]⟩) (finite_of_norm_le K A (1 : ℝ)) wlog hlt : b < a @@ -375,7 +375,7 @@ theorem disjoint_unmixedEmbeddingsOver_mixedEmbeddingsOver : theorem union_unmixedEmbeddingsOver_mixedEmbeddingsOver : (unmixedEmbeddingsOver L ψ) ∪ (mixedEmbeddingsOver L ψ) = { φ | ComplexEmbedding.LiesOver φ ψ } := by - grind [unmixedEmbeddingsOver, mixedEmbeddingsOver, ← Set.setOf_or] + grind [unmixedEmbeddingsOver, mixedEmbeddingsOver, ← Set.ofPred_or] end Extension diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean index fb92da2b73dfd2..c983d5383e5ed5 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean @@ -697,7 +697,7 @@ theorem disjoint_ramifiedPlacesOver_unramifiedPlacesOver : theorem union_ramifiedPlacesOver_unramifiedPlacesOver : (ramifiedPlacesOver L v) ∪ (unramifiedPlacesOver L v) = placesOver L v := by - rw [placesOver, ramifiedPlacesOver, unramifiedPlacesOver, ← Set.setOf_or] + rw [placesOver, ramifiedPlacesOver, unramifiedPlacesOver, ← Set.ofPred_or] grind theorem bijOn_sumElim_conjugate : @@ -775,7 +775,7 @@ theorem unramifedPlacesOver_ncard_add_eq_finrank [NumberField K] [NumberField L] union_unmixedEmbeddingsOver_mixedEmbeddingsOver, Set.ncard_eq_toFinset_card] apply (card_nbij AlgHom.toRingHom (fun σ _ ↦ by simpa using ⟨by aesop⟩) AlgHom.coe_ringHom_injective.injOn (fun ψ hψ ↦ ?_)).symm - simp only [Set.Finite.toFinset_setOf, coe_filter, mem_univ, true_and, Set.mem_setOf_eq] at hψ + simp only [Set.Finite.toFinset_ofPred, coe_filter, mem_univ, true_and, Set.mem_ofPred_eq] at hψ exact ⟨⟨ψ, fun _ ↦ by simp [RingHom.algebraMap_toAlgebra, ← hψ.over]⟩, by simp⟩ end placesOver diff --git a/Mathlib/NumberTheory/NumberField/ProductFormula.lean b/Mathlib/NumberTheory/NumberField/ProductFormula.lean index 40c7ea76fc1663..b4861f4f883552 100644 --- a/Mathlib/NumberTheory/NumberField/ProductFormula.lean +++ b/Mathlib/NumberTheory/NumberField/ProductFormula.lean @@ -58,7 +58,7 @@ theorem FinitePlace.prod_eq_inv_abs_norm_int {x : 𝓞 K} (h_x_nezero : x ≠ 0) have h_fin₁ : t₁.Finite := h_fin₀.subset <| by simp [norm_eq_one_iff_notMem, t₁, t₀] have h_fin₂ : t₂.Finite := by refine h_fin₀.subset ?_ - simp only [mulSupport_subset_iff, Set.mem_setOf_eq, t₂, t₀, + simp only [mulSupport_subset_iff, Set.mem_ofPred_eq, t₂, t₀, maxPowDividing, ← dvd_span_singleton] intro v hv simp only [map_pow, Nat.cast_pow, ← pow_zero (absNorm v.asIdeal : ℝ)] at hv diff --git a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean index 17ea502ed382a8..9e37588ae15ce3 100644 --- a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean +++ b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean @@ -310,8 +310,8 @@ theorem exists_unit (w₁ : InfinitePlace K) : rw [map_inv₀, mul_inv_lt_iff₀' (pos_iff.mpr (seq_ne_zero K w₁ hB n)), mul_one] exact seq_decreasing K w₁ hB hnm w hw refine Set.Finite.exists_lt_map_eq_of_forall_mem (t := {I : Ideal (𝓞 K) | Ideal.absNorm I ≤ B}) - (fun n ↦ ?_) (Ideal.finite_setOf_absNorm_le B) - rw [Set.mem_setOf_eq, Ideal.absNorm_span_singleton] + (fun n ↦ ?_) (Ideal.finite_setOfPred_absNorm_le B) + rw [Set.mem_ofPred_eq, Ideal.absNorm_span_singleton] exact seq_norm_le K w₁ hB n set_option backward.isDefEq.respectTransparency.types false in diff --git a/Mathlib/NumberTheory/Padics/WithVal.lean b/Mathlib/NumberTheory/Padics/WithVal.lean index 617294b265bb17..641d6ab71534f2 100644 --- a/Mathlib/NumberTheory/Padics/WithVal.lean +++ b/Mathlib/NumberTheory/Padics/WithVal.lean @@ -45,7 +45,7 @@ lemma isUniformInducing_cast_withVal : IsUniformInducing ((Rat.castHom ℚ_[p]). have hp1 : (p : ℝ)⁻¹ < 1 := by simp [inv_lt_one_iff₀, Nat.Prime.one_lt Fact.out] rw [Filter.HasBasis.isUniformInducing_iff (Valued.hasBasis_uniformity _ _) (Metric.uniformity_basis_dist_le_pow hp0 hp1)] - simp only [Set.mem_setOf_eq, dist_eq_norm_sub, inv_pow, RingEquiv.toRingHom_eq_coe, + simp only [Set.mem_ofPred_eq, dist_eq_norm_sub, inv_pow, RingEquiv.toRingHom_eq_coe, RingHom.coe_comp, Rat.coe_castHom, RingHom.coe_coe, Function.comp_apply, ← Rat.cast_sub, ← map_sub, Padic.eq_padicNorm, true_and, forall_const] constructor @@ -179,7 +179,7 @@ theorem withValUniformEquiv_norm_le_one_iff {p : ℕ} [Fact p.Prime] | hp => rw [Set.ext fun _ ↦ Iff.comm] simp_rw [← Valuation.restrict_le_one_iff Valued.v] - apply withValUniformEquiv.toHomeomorph.isClosed_setOf_iff (q := fun x ↦ ‖x‖ ≤ 1) + apply withValUniformEquiv.toHomeomorph.isClosed_setOfPred_iff (q := fun x ↦ ‖x‖ ≤ 1) (Valued.isClopen_closedBall _ one_ne_zero) simpa [Metric.closedBall] using IsUltrametricDist.isClopen_closedBall (0 : ℚ_[p]) one_ne_zero | ih a => diff --git a/Mathlib/NumberTheory/Pell.lean b/Mathlib/NumberTheory/Pell.lean index 04b6b2d6504225..c9adf9a27c013e 100644 --- a/Mathlib/NumberTheory/Pell.lean +++ b/Mathlib/NumberTheory/Pell.lean @@ -333,25 +333,25 @@ theorem exists_of_not_isSquare (h₀ : 0 < d) (hd : ¬IsSquare d) : refine Infinite.mono (fun q h => ?_) (infinite_rat_abs_sub_lt_one_div_den_sq_of_irrational hξ) have h0 : 0 < (q.2 : ℝ) ^ 2 := pow_pos (Nat.cast_pos.mpr q.pos) 2 have h1 : (q.num : ℝ) / (q.den : ℝ) = q := mod_cast q.num_div_den - rw [mem_setOf, abs_sub_comm, ← @Int.cast_lt ℝ, + rw [mem_ofPred, abs_sub_comm, ← @Int.cast_lt ℝ, ← div_lt_div_iff_of_pos_right (abs_pos_of_pos h0)] push_cast rw [← abs_div, abs_sq, sub_div, mul_div_cancel_right₀ _ h0.ne', ← div_pow, h1, ← sq_sqrt (Int.cast_pos.mpr h₀).le, sq_sub_sq, abs_mul, ← mul_one_div] refine mul_lt_mul'' (((abs_add_le ξ q).trans ?_).trans_lt hM₁) h (abs_nonneg _) (abs_nonneg _) rw [two_mul, add_assoc, add_le_add_iff_left, ← sub_le_iff_le_add'] - rw [mem_setOf, abs_sub_comm] at h + rw [mem_ofPred, abs_sub_comm] at h refine (abs_sub_abs_le_abs_sub (q : ℝ) ξ).trans (h.le.trans ?_) rw [div_le_one h0, one_le_sq_iff_one_le_abs, Nat.abs_cast, Nat.one_le_cast] exact q.pos obtain ⟨m, hm⟩ : ∃ m : ℤ, {q : ℚ | q.1 ^ 2 - d * (q.den : ℤ) ^ 2 = m}.Infinite := by contrapose! hM refine (congr_arg _ (ext fun x => ?_)).mp (Finite.biUnion (finite_Ioo (-M) M) fun m _ => hM m) - simp only [abs_lt, mem_setOf, mem_Ioo, mem_iUnion, exists_prop, exists_eq_right'] + simp only [abs_lt, mem_ofPred, mem_Ioo, mem_iUnion, exists_prop, exists_eq_right'] have hm₀ : m ≠ 0 := by rintro rfl obtain ⟨q, hq⟩ := hm.nonempty - rw [mem_setOf, sub_eq_zero, mul_comm] at hq + rw [mem_ofPred, sub_eq_zero, mul_comm] at hq obtain ⟨a, ha⟩ := (Int.pow_dvd_pow_iff two_ne_zero).mp ⟨d, hq⟩ rw [ha, mul_pow, mul_right_inj' (pow_pos (Int.natCast_pos.mpr q.pos) 2).ne'] at hq exact hd ⟨a, sq a ▸ hq.symm⟩ diff --git a/Mathlib/NumberTheory/PrimeCounting.lean b/Mathlib/NumberTheory/PrimeCounting.lean index 094ba7830c3724..a9d6b59349f06c 100644 --- a/Mathlib/NumberTheory/PrimeCounting.lean +++ b/Mathlib/NumberTheory/PrimeCounting.lean @@ -77,14 +77,14 @@ theorem monotone_primeCounting : Monotone primeCounting := @[simp] theorem primeCounting'_nth_eq (n : ℕ) : π' (nth Prime n) = n := - count_nth_of_infinite infinite_setOf_prime _ + count_nth_of_infinite infinite_setOfPred_prime _ /-- The `n`th prime is greater or equal to `n + 2`. -/ theorem add_two_le_nth_prime (n : ℕ) : n + 2 ≤ nth Prime n := - nth_prime_zero_eq_two ▸ (nth_strictMono infinite_setOf_prime).add_le_nat n 0 + nth_prime_zero_eq_two ▸ (nth_strictMono infinite_setOfPred_prime).add_le_nat n 0 theorem surjective_primeCounting' : Function.Surjective π' := - Nat.surjective_count_of_infinite_setOf infinite_setOf_prime + Nat.surjective_count_of_infinite_setOfPred infinite_setOfPred_prime theorem surjective_primeCounting : Function.Surjective π := by suffices Function.Surjective (π ∘ fun n => n - 1) from this.of_comp @@ -103,7 +103,7 @@ theorem tendsto_primeCounting : Tendsto π atTop atTop := @[simp] theorem prime_nth_prime (n : ℕ) : Prime (nth Prime n) := - nth_mem_of_infinite infinite_setOf_prime _ + nth_mem_of_infinite infinite_setOfPred_prime _ @[simp] lemma primeCounting'_eq_zero_iff {n : ℕ} : n.primeCounting' = 0 ↔ n ≤ 2 := by diff --git a/Mathlib/NumberTheory/PrimesCongruentOne.lean b/Mathlib/NumberTheory/PrimesCongruentOne.lean index 30f10e47ed7288..e10518f8fbadfd 100644 --- a/Mathlib/NumberTheory/PrimesCongruentOne.lean +++ b/Mathlib/NumberTheory/PrimesCongruentOne.lean @@ -65,8 +65,11 @@ theorem frequently_atTop_modEq_one {k : ℕ} (hk0 : k ≠ 0) : exact ⟨p, ⟨hp.2.1.le, hp.1, hp.2.2⟩⟩ /-- For any positive `k : ℕ` there are infinitely many primes `p` such that `p ≡ 1 [MOD k]`. -/ -theorem infinite_setOf_prime_modEq_one {k : ℕ} (hk0 : k ≠ 0) : +theorem infinite_setOfPred_prime_modEq_one {k : ℕ} (hk0 : k ≠ 0) : Set.Infinite {p : ℕ | Nat.Prime p ∧ p ≡ 1 [MOD k]} := frequently_atTop_iff_infinite.1 (frequently_atTop_modEq_one hk0) +@[deprecated (since := "2026-07-09")] +alias infinite_setOf_prime_modEq_one := infinite_setOfPred_prime_modEq_one + end Nat diff --git a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean index 440edccf428699..67a42d6f710014 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean @@ -167,7 +167,7 @@ lemma ramificationIdx'_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : dsimp only [ramificationIdx'] congr 1 ext n - simp only [Set.mem_setOf_eq, Ideal.map_le_iff_le_comap] + simp only [Set.mem_ofPred_eq, Ideal.map_le_iff_le_comap] rw [← comap_coe e, ← e.toRingEquiv_toRingHom, comap_coe, ← RingEquiv.symm_symm (e : S ≃+* S₁), ← map_comap_of_equiv, ← Ideal.map_pow, map_comap_of_equiv, ← comap_coe (RingEquiv.symm _), comap_comap, RingEquiv.symm_symm, e.toRingEquiv_toRingHom, ← e.toAlgHom_toRingHom, diff --git a/Mathlib/NumberTheory/RamificationInertia/Valuation.lean b/Mathlib/NumberTheory/RamificationInertia/Valuation.lean index 8af1bd6a3711a9..ad14d189ee8534 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Valuation.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Valuation.lean @@ -95,7 +95,7 @@ theorem uniformContinuous_algebraMap_liesOver : let γK := σvV.symm (σK.symm (σv.symm (exp (m.log / e)))) have hγK : γK ≠ 0 := by simp [γK, EmbeddingLike.map_eq_zero_iff (f := σK.symm)] use .mk0 _ hγK - simp only [Units.val_mk0, Set.mem_setOf_eq, true_and] + simp only [Units.val_mk0, Set.mem_ofPred_eq, true_and] intro x hx rcases eq_or_ne x 0 with rfl | hx₀; · simp rw [σvV.lt_symm_apply, σK.lt_symm_apply, σv.lt_symm_apply, diff --git a/Mathlib/NumberTheory/RatFunc/Ostrowski.lean b/Mathlib/NumberTheory/RatFunc/Ostrowski.lean index 9e9ea867ed3d8e..4e7cbad0f07236 100644 --- a/Mathlib/NumberTheory/RatFunc/Ostrowski.lean +++ b/Mathlib/NumberTheory/RatFunc/Ostrowski.lean @@ -60,7 +60,7 @@ end Infinity open IsDedekindDomain HeightOneSpectrum Set Valuation Polynomial -lemma setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty [v.IsNontrivial] [v.IsTrivialOn K] +lemma setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty [v.IsNontrivial] [v.IsTrivialOn K] (hle : v RatFunc.X ≤ 1) : {p : K[X] | v p < 1 ∧ p ≠ 0}.Nonempty := by obtain ⟨w, h0, h1⟩ := IsNontrivial.exists_lt_one (v := v) induction w using RatFunc.induction_on with @@ -73,6 +73,10 @@ lemma setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty [v.IsNontrivial] [v exact fun r hr hr0 ↦ ⟨r, lt_iff_le_and_ne.mpr ⟨Polynomial.valuation_le_one_of_valuation_X_le_one _ hle r, hr⟩, hr0⟩ +@[deprecated (since := "2026-07-09")] +alias setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty := + setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty + private lemma one_le_valuation_factor (hne : {p : K[X] | v p < 1 ∧ p ≠ 0}.Nonempty) {a b : K[X]} (hab : v ↑(a * b) < 1 ∧ a ≠ 0 ∧ b ≠ 0) (hπᵥ : degree_lt_wf.min _ hne = a * b) (hb : ¬IsUnit b) : 1 ≤ v ↑a := by @@ -109,18 +113,18 @@ variable [v.IsNontrivial] [v.IsTrivialOn K] (hle : v RatFunc.X ≤ 1) /-- A uniformizing element for the valuation `v`, as a polynomial in `K[X]`. -/ abbrev uniformizingPolynomial : K[X] := - WellFounded.min degree_lt_wf _ (setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty hle) + WellFounded.min degree_lt_wf _ (setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty hle) @[inherit_doc] local notation "πᵥ" => uniformizingPolynomial hle lemma uniformizingPolynomial_ne_zero : πᵥ ≠ 0 := by - have := degree_lt_wf.min_mem _ (setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty hle) + have := degree_lt_wf.min_mem _ (setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty hle) simp_all [uniformizingPolynomial] lemma valuation_uniformizingPolynomial_lt_one : v πᵥ < 1 := by simpa using! (degree_lt_wf.min_mem _ - (setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty hle)).1 + (setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty hle)).1 open Ideal in /-- The maximal ideal of `K[X]` generated by the `uniformizingPolynomial` for `v`. -/ @@ -128,7 +132,7 @@ def valuationIdeal : HeightOneSpectrum K[X] where asIdeal := Submodule.span K[X] {πᵥ} isPrime := IsMaximal.isPrime (PrincipalIdealRing.isMaximal_of_irreducible (irreducible_min_polynomial_valuation_lt_one_and_ne_zero - (setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty hle))) + (setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty hle))) ne_bot := by simpa using uniformizingPolynomial_ne_zero hle @[inherit_doc] @@ -142,11 +146,11 @@ lemma valuation_eq_valuation_uniformizingPolynomial_pow_of_valuation_X_le_one {p v (algebraMap K[X] (RatFunc K) p) = v (πᵥ ^ ((Associates.mk (Pᵥ).asIdeal).count (Associates.mk (Ideal.span {p})).factors)) := by set π := πᵥ - have hne := setOf_polynomial_valuation_lt_one_and_ne_zero_nonempty hle + have hne := setOfPred_polynomial_valuation_lt_one_and_ne_zero_nonempty hle have hπirr : Irreducible π := irreducible_min_polynomial_valuation_lt_one_and_ne_zero hne obtain ⟨k, q, hnq, heq⟩ := WfDvdMonoid.max_power_factor hp hπirr have hπ : π ∈ _ := degree_lt_wf.min_mem _ hne - simp only [ne_eq, mem_setOf] at hπ + simp only [ne_eq, mem_ofPred] at hπ nth_rw 1 [heq] simp only [map_mul, map_pow] suffices v (algebraMap K[X] (RatFunc K) q) = 1 by diff --git a/Mathlib/NumberTheory/Rayleigh.lean b/Mathlib/NumberTheory/Rayleigh.lean index 6f5a2a7626abe6..2c67001a17862a 100644 --- a/Mathlib/NumberTheory/Rayleigh.lean +++ b/Mathlib/NumberTheory/Rayleigh.lean @@ -140,9 +140,9 @@ theorem beattySeq_symmDiff_beattySeq'_pos {r s : ℝ} (hrs : r.HolderConjugate s {beattySeq r k | k > 0} ∆ {beattySeq' s k | k > 0} = {n | 0 < n} := by apply Set.eq_of_subset_of_subset · rintro j (⟨⟨k, hk, hjk⟩, -⟩ | ⟨⟨k, hk, hjk⟩, -⟩) - · rw [Set.mem_setOf_eq, ← hjk, beattySeq, Int.floor_pos] + · rw [Set.mem_ofPred_eq, ← hjk, beattySeq, Int.floor_pos] exact one_le_mul_of_one_le_of_one_le (by norm_cast) hrs.lt.le - · rw [Set.mem_setOf_eq, ← hjk, beattySeq', sub_pos, Int.lt_ceil, Int.cast_one] + · rw [Set.mem_ofPred_eq, ← hjk, beattySeq', sub_pos, Int.lt_ceil, Int.cast_one] exact one_lt_mul_of_le_of_lt (by norm_cast) hrs.symm.lt intro j (hj : 0 < j) have hb₁ : ∀ s ≥ 0, j ∈ {beattySeq s k | k > 0} ↔ j ∈ {beattySeq s k | k} := by diff --git a/Mathlib/NumberTheory/SmoothNumbers.lean b/Mathlib/NumberTheory/SmoothNumbers.lean index 9cb5e4937eafa6..764736e6137fe8 100644 --- a/Mathlib/NumberTheory/SmoothNumbers.lean +++ b/Mathlib/NumberTheory/SmoothNumbers.lean @@ -154,7 +154,7 @@ lemma factoredNumbers_compl {N : ℕ} {s : Finset ℕ} (h : primesBelow N ≤ s) intro n hn simp only [Set.mem_compl_iff, mem_factoredNumbers, Set.mem_sdiff, ne_eq, not_and, not_forall, exists_prop, Set.mem_singleton_iff] at hn - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] obtain ⟨p, hp₁, hp₂⟩ := hn.1 hn.2 have : N ≤ p := by contrapose! hp₂ diff --git a/Mathlib/NumberTheory/SumPrimeReciprocals.lean b/Mathlib/NumberTheory/SumPrimeReciprocals.lean index 5811222e1cb395..9b40e11edb9ca9 100644 --- a/Mathlib/NumberTheory/SumPrimeReciprocals.lean +++ b/Mathlib/NumberTheory/SumPrimeReciprocals.lean @@ -79,7 +79,7 @@ theorem not_summable_one_div_on_primes : Summable.sum_le_tsum (primesBelow ((4 ^ (k.primesBelow.card + 1)).succ) \ primesBelow k) (fun n _ ↦ indicator_nonneg (fun p _ ↦ by positivity) _) h' using 2 with p hp - obtain ⟨hp₁, hp₂⟩ := mem_setOf_eq ▸ Finset.mem_sdiff.mp hp + obtain ⟨hp₁, hp₂⟩ := mem_ofPred_eq ▸ Finset.mem_sdiff.mp hp have hpp := prime_of_mem_primesBelow hp₁ refine (indicator_of_mem ?_ fun n : ℕ ↦ (1 / n : ℝ)).symm exact ⟨hpp, by simpa [primesBelow, hpp] using hp₂⟩ diff --git a/Mathlib/NumberTheory/Transcendental/Liouville/Measure.lean b/Mathlib/NumberTheory/Transcendental/Liouville/Measure.lean index 29b45e17dd4454..f2c647281176c7 100644 --- a/Mathlib/NumberTheory/Transcendental/Liouville/Measure.lean +++ b/Mathlib/NumberTheory/Transcendental/Liouville/Measure.lean @@ -15,7 +15,7 @@ public import Mathlib.Analysis.PSeries In this file we prove that the set of Liouville numbers with exponent (irrationality measure) strictly greater than two is a set of Lebesgue measure zero, see -`volume_iUnion_setOf_liouvilleWith`. +`volume_iUnion_setOfPred_liouvilleWith`. Since this set is a residual set, we show that the filters `residual` and `ae volume` are disjoint. These filters correspond to two common notions of genericity on `ℝ`: residual sets and sets of full @@ -33,7 +33,7 @@ open scoped Filter ENNReal Topology NNReal open Filter Set Metric MeasureTheory Real -theorem setOf_liouvilleWith_subset_aux : +theorem setOfPred_liouvilleWith_subset_aux : { x : ℝ | ∃ p > 2, LiouvilleWith p x } ⊆ ⋃ m : ℤ, (· + (m : ℝ)) ⁻¹' ⋃ n > (0 : ℕ), { x : ℝ | ∃ᶠ b : ℕ in atTop, ∃ a ∈ Finset.Icc (0 : ℤ) b, @@ -72,20 +72,23 @@ theorem setOf_liouvilleWith_subset_aux : · rw [add_le_add_iff_left] exact mul_le_of_le_one_left hb0.le hx01.2.le +@[deprecated (since := "2026-07-09")] +alias setOf_liouvilleWith_subset_aux := setOfPred_liouvilleWith_subset_aux + /-- The set of numbers satisfying the Liouville condition with some exponent `p > 2` has Lebesgue measure zero. -/ @[simp] -theorem volume_iUnion_setOf_liouvilleWith : +theorem volume_iUnion_setOfPred_liouvilleWith : volume (⋃ (p : ℝ) (_hp : 2 < p), { x : ℝ | LiouvilleWith p x }) = 0 := by - simp only [← setOf_exists, exists_prop] - refine measure_mono_null setOf_liouvilleWith_subset_aux ?_ + simp only [← ofPred_exists, exists_prop] + refine measure_mono_null setOfPred_liouvilleWith_subset_aux ?_ rw [measure_iUnion_null_iff]; intro m; rw [measure_preimage_add_right]; clear m refine (measure_biUnion_null_iff <| to_countable _).2 fun n (hn : 1 ≤ n) => ?_ generalize hr : (2 + 1 / n : ℝ) = r replace hr : 2 < r := by simp [← hr, zero_lt_one.trans_le hn] clear hn n - refine measure_setOf_frequently_eq_zero ?_ - simp only [setOf_exists, ← exists_prop, ← Real.dist_eq, ← mem_ball, setOf_mem_eq] + refine measure_setOfPred_frequently_eq_zero ?_ + simp only [ofPred_exists, ← exists_prop, ← Real.dist_eq, ← mem_ball, ofPred_mem_eq] set B : ℤ → ℕ → Set ℝ := fun a b => ball (a / b) (1 / (b : ℝ) ^ r) have hB : ∀ a b, volume (B a b) = ↑((2 : ℝ≥0) / (b : ℝ≥0) ^ r) := fun a b ↦ by rw [Real.volume_ball, mul_one_div, ← NNReal.coe_two, ← NNReal.coe_natCast, ← NNReal.coe_rpow, @@ -106,18 +109,24 @@ theorem volume_iUnion_setOf_liouvilleWith : refine ne_top_of_le_ne_top (ENNReal.tsum_coe_ne_top_iff_summable.2 ?_) (ENNReal.tsum_le_tsum this) refine (Summable.add ?_ ?_).mul_left _ <;> simp only [NNReal.summable_rpow] <;> linarith +@[deprecated (since := "2026-07-09")] +alias volume_iUnion_setOf_liouvilleWith := volume_iUnion_setOfPred_liouvilleWith + theorem ae_not_liouvilleWith : ∀ᵐ x, ∀ p > (2 : ℝ), ¬LiouvilleWith p x := by - simpa only [ae_iff, not_forall, Classical.not_not, setOf_exists] using - volume_iUnion_setOf_liouvilleWith + simpa only [ae_iff, not_forall, Classical.not_not, ofPred_exists] using + volume_iUnion_setOfPred_liouvilleWith theorem ae_not_liouville : ∀ᵐ x, ¬Liouville x := ae_not_liouvilleWith.mono fun _ h₁ h₂ => h₁ 3 (by norm_num) (h₂.liouvilleWith 3) /-- The set of Liouville numbers has Lebesgue measure zero. -/ @[simp] -theorem volume_setOf_liouville : volume { x : ℝ | Liouville x } = 0 := by +theorem volume_setOfPred_liouville : volume { x : ℝ | Liouville x } = 0 := by simpa only [ae_iff, Classical.not_not] using ae_not_liouville +@[deprecated (since := "2026-07-09")] +alias volume_setOf_liouville := volume_setOfPred_liouville + /-- The filters `residual ℝ` and `ae volume` are disjoint. This means that there exists a residual set of Lebesgue measure zero (e.g., the set of Liouville numbers). -/ theorem Real.disjoint_residual_ae : Disjoint (residual ℝ) (ae volume) := diff --git a/Mathlib/NumberTheory/Transcendental/Liouville/Residual.lean b/Mathlib/NumberTheory/Transcendental/Liouville/Residual.lean index d9a0960836a2ac..1961a6e5c07667 100644 --- a/Mathlib/NumberTheory/Transcendental/Liouville/Residual.lean +++ b/Mathlib/NumberTheory/Transcendental/Liouville/Residual.lean @@ -24,37 +24,46 @@ open scoped Filter open Filter Set Metric -theorem setOf_liouville_eq_iInter_iUnion : +theorem setOfPred_liouville_eq_iInter_iUnion : { x | Liouville x } = ⋂ n : ℕ, ⋃ (a : ℤ) (b : ℤ) (_ : 1 < b), ball ((a : ℝ) / b) (1 / (b : ℝ) ^ n) \ {(a : ℝ) / b} := by ext x - simp only [mem_iInter, mem_iUnion, Liouville, mem_setOf_eq, exists_prop, Set.mem_sdiff, + simp only [mem_iInter, mem_iUnion, Liouville, mem_ofPred_eq, exists_prop, Set.mem_sdiff, mem_singleton_iff, mem_ball, Real.dist_eq, and_comm] -theorem IsGδ.setOf_liouville : IsGδ { x | Liouville x } := by - rw [setOf_liouville_eq_iInter_iUnion] +@[deprecated (since := "2026-07-09")] +alias setOf_liouville_eq_iInter_iUnion := setOfPred_liouville_eq_iInter_iUnion + +theorem IsGδ.setOfPred_liouville : IsGδ { x | Liouville x } := by + rw [setOfPred_liouville_eq_iInter_iUnion] refine .iInter fun n => IsOpen.isGδ ?_ refine isOpen_iUnion fun a => isOpen_iUnion fun b => isOpen_iUnion fun _hb => ?_ exact isOpen_ball.inter isClosed_singleton.isOpen_compl +@[deprecated (since := "2026-07-09")] +alias IsGδ.setOf_liouville := IsGδ.setOfPred_liouville -theorem setOf_liouville_eq_irrational_inter_iInter_iUnion : +theorem setOfPred_liouville_eq_irrational_inter_iInter_iUnion : { x | Liouville x } = { x | Irrational x } ∩ ⋂ n : ℕ, ⋃ (a : ℤ) (b : ℤ) (_ : 1 < b), ball (a / b) (1 / (b : ℝ) ^ n) := by refine Subset.antisymm ?_ ?_ · refine subset_inter (fun x hx => hx.irrational) ?_ - rw [setOf_liouville_eq_iInter_iUnion] + rw [setOfPred_liouville_eq_iInter_iUnion] exact iInter_mono fun n => iUnion₂_mono fun a b => iUnion_mono fun _hb => sdiff_subset - · simp only [inter_iInter, inter_iUnion, setOf_liouville_eq_iInter_iUnion] + · simp only [inter_iInter, inter_iUnion, setOfPred_liouville_eq_iInter_iUnion] refine iInter_mono fun n => iUnion₂_mono fun a b => iUnion_mono fun hb => ?_ rw [inter_comm] exact sdiff_subset_sdiff Subset.rfl (singleton_subset_iff.2 ⟨a / b, by norm_cast⟩) +@[deprecated (since := "2026-07-09")] +alias setOf_liouville_eq_irrational_inter_iInter_iUnion := + setOfPred_liouville_eq_irrational_inter_iInter_iUnion + /-- The set of Liouville numbers is a residual set. -/ theorem eventually_residual_liouville : ∀ᶠ x in residual ℝ, Liouville x := by - rw [Filter.Eventually, setOf_liouville_eq_irrational_inter_iInter_iUnion] + rw [Filter.Eventually, setOfPred_liouville_eq_irrational_inter_iInter_iUnion] refine eventually_residual_irrational.and ?_ refine residual_of_dense_Gδ ?_ (Rat.isDenseEmbedding_coe_real.dense.mono ?_) · exact .iInter fun n => IsOpen.isGδ <| diff --git a/Mathlib/NumberTheory/WellApproximable.lean b/Mathlib/NumberTheory/WellApproximable.lean index e5218583626eca..bbfa1ce69699db 100644 --- a/Mathlib/NumberTheory/WellApproximable.lean +++ b/Mathlib/NumberTheory/WellApproximable.lean @@ -76,7 +76,7 @@ def approxOrderOf (A : Type*) [SeminormedGroup A] (n : ℕ) (δ : ℝ) : Set A : @[to_additive mem_approx_add_orderOf_iff] theorem mem_approxOrderOf_iff {A : Type*} [SeminormedGroup A] {n : ℕ} {δ : ℝ} {a : A} : a ∈ approxOrderOf A n δ ↔ ∃ b : A, orderOf b = n ∧ a ∈ ball b δ := by - simp only [approxOrderOf, thickening_eq_biUnion_ball, mem_iUnion₂, mem_setOf_eq, exists_prop] + simp only [approxOrderOf, thickening_eq_biUnion_ball, mem_iUnion₂, mem_ofPred_eq, exists_prop] /-- In a seminormed group `A`, given a sequence of distances `δ₁, δ₂, ...`, `wellApproximable A δ` is the limsup as `n → ∞` of the sets `approxOrderOf A n δₙ`. Thus, it is the set of points that @@ -115,7 +115,7 @@ theorem image_pow_subset (n : ℕ) (hm : 0 < m) : rintro - ⟨a, ha, rfl⟩ obtain ⟨b, hb : orderOf b = n * m, hab : a ∈ ball b δ⟩ := mem_approxOrderOf_iff.mp ha replace hb : b ^ m ∈ {y : A | orderOf y = n} := by - rw [mem_setOf_eq, orderOf_pow' b hm.ne', hb, Nat.gcd_mul_left_left, n.mul_div_cancel hm] + rw [mem_ofPred_eq, orderOf_pow' b hm.ne', hb, Nat.gcd_mul_left_left, n.mul_div_cancel hm] apply ball_subset_thickening hb (m * δ) convert! pow_mem_ball hm hab using 1 simp only [nsmul_eq_mul] @@ -124,7 +124,7 @@ theorem image_pow_subset (n : ℕ) (hm : 0 < m) : theorem smul_subset_of_coprime (han : (orderOf a).Coprime n) : a • approxOrderOf A n δ ⊆ approxOrderOf A (orderOf a * n) δ := by simp_rw [approxOrderOf, thickening_eq_biUnion_ball, ← image_smul, image_iUnion₂, image_smul, - smul_ball'', smul_eq_mul, mem_setOf_eq] + smul_ball'', smul_eq_mul, mem_ofPred_eq] refine iUnion₂_subset_iff.mpr fun b hb c hc => ?_ simp only [mem_iUnion, exists_prop] refine ⟨a * b, ?_, hc⟩ @@ -135,7 +135,7 @@ theorem smul_subset_of_coprime (han : (orderOf a).Coprime n) : theorem smul_eq_of_mul_dvd (hn : 0 < n) (han : orderOf a ^ 2 ∣ n) : a • approxOrderOf A n δ = approxOrderOf A n δ := by simp_rw [approxOrderOf, thickening_eq_biUnion_ball, ← image_smul, image_iUnion₂, image_smul, - smul_ball'', smul_eq_mul, mem_setOf_eq] + smul_ball'', smul_eq_mul, mem_ofPred_eq] replace han : ∀ {b : A}, orderOf b = n → orderOf (a * b) = n := by intro b hb rw [← hb] at han hn @@ -146,11 +146,11 @@ theorem smul_eq_of_mul_dvd (hn : 0 < n) (han : orderOf a ^ 2 ∣ n) : have hf : Surjective f := by rintro ⟨b, hb⟩ refine ⟨⟨a⁻¹ * b, ?_⟩, ?_⟩ - · rw [mem_setOf_eq, ← orderOf_inv, mul_inv_rev, inv_inv, mul_comm] + · rw [mem_ofPred_eq, ← orderOf_inv, mul_inv_rev, inv_inv, mul_comm] apply han simpa · simp only [f, mul_inv_cancel_left] - simpa only [mem_setOf_eq, Subtype.coe_mk, iUnion_coe_set] using + simpa only [mem_ofPred_eq, Subtype.coe_mk, iUnion_coe_set] using hf.iUnion_comp fun b => ball (b : A) δ end approxOrderOf @@ -159,7 +159,7 @@ namespace UnitAddCircle theorem mem_approxAddOrderOf_iff {δ : ℝ} {x : UnitAddCircle} {n : ℕ} (hn : 0 < n) : x ∈ approxAddOrderOf UnitAddCircle n δ ↔ ∃ m < n, gcd m n = 1 ∧ ‖x - ↑((m : ℝ) / n)‖ < δ := by - simp only [mem_approx_add_orderOf_iff, mem_setOf_eq, ball, dist_eq_norm, + simp only [mem_approx_add_orderOf_iff, mem_ofPred_eq, ball, dist_eq_norm, AddCircle.addOrderOf_eq_pos_iff hn, mul_one] constructor · rintro ⟨y, ⟨m, hm₁, hm₂, rfl⟩, hx⟩; exact ⟨m, hm₁, hm₂, hx⟩ @@ -169,7 +169,7 @@ theorem mem_addWellApproximable_iff (δ : ℕ → ℝ) (x : UnitAddCircle) : x ∈ addWellApproximable UnitAddCircle δ ↔ {n : ℕ | ∃ m < n, gcd m n = 1 ∧ ‖x - ↑((m : ℝ) / n)‖ < δ n}.Infinite := by simp only [mem_add_wellApproximable_iff, ← Nat.cofinite_eq_atTop, cofinite.blimsup_set_eq, - mem_setOf_eq] + mem_ofPred_eq] refine iff_of_eq (congr_arg Set.Infinite <| ext fun n => ⟨fun hn => ?_, fun hn => ?_⟩) · exact (mem_approxAddOrderOf_iff hn.1).mp hn.2 · have h : 0 < n := by obtain ⟨m, hm₁, _, _⟩ := hn; exact pos_of_gt hm₁ diff --git a/Mathlib/Order/Antichain.lean b/Mathlib/Order/Antichain.lean index 716191a7b70fa5..33447320056fba 100644 --- a/Mathlib/Order/Antichain.lean +++ b/Mathlib/Order/Antichain.lean @@ -267,19 +267,25 @@ theorem IsAntichain.maximal_mem_iff (hs : IsAntichain (· ≤ ·) s) : Maximal ( /-- If `t` is an antichain shadowing and including the set of maximal elements of `s`, then `t` *is* the set of maximal elements of `s`. -/ -theorem IsAntichain.eq_setOf_maximal (ht : IsAntichain (· ≤ ·) t) +theorem IsAntichain.eq_setOfPred_maximal (ht : IsAntichain (· ≤ ·) t) (h : ∀ x, Maximal (· ∈ s) x → x ∈ t) (hs : ∀ a ∈ t, ∃ b, b ≤ a ∧ Maximal (· ∈ s) b) : {x | Maximal (· ∈ s) x} = t := by refine Set.ext fun x ↦ ⟨h _, fun hx ↦ ?_⟩ obtain ⟨y, hyx, hy⟩ := hs x hx rwa [← ht.eq (h y hy) hx hyx] +@[deprecated (since := "2026-07-09")] +alias IsAntichain.eq_setOf_maximal := IsAntichain.eq_setOfPred_maximal + /-- If `t` is an antichain shadowed by and including the set of minimal elements of `s`, then `t` *is* the set of minimal elements of `s`. -/ -theorem IsAntichain.eq_setOf_minimal (ht : IsAntichain (· ≤ ·) t) +theorem IsAntichain.eq_setOfPred_minimal (ht : IsAntichain (· ≤ ·) t) (h : ∀ x, Minimal (· ∈ s) x → x ∈ t) (hs : ∀ a ∈ t, ∃ b, a ≤ b ∧ Minimal (· ∈ s) b) : {x | Minimal (· ∈ s) x} = t := - ht.to_dual.eq_setOf_maximal h hs + ht.to_dual.eq_setOfPred_maximal h hs + +@[deprecated (since := "2026-07-09")] +alias IsAntichain.eq_setOf_minimal := IsAntichain.eq_setOfPred_minimal end Preorder @@ -299,11 +305,16 @@ theorem isAntichain_iff_forall_not_lt : IsAntichain (· ≤ ·) s ↔ ∀ ⦃a⦄, a ∈ s → ∀ ⦃b⦄, b ∈ s → ¬a < b := ⟨fun hs _ ha _ => hs.not_lt ha, fun hs _ ha _ hb h h' => hs ha hb <| h'.lt_of_ne h⟩ -theorem setOf_maximal_antichain (P : α → Prop) : IsAntichain (· ≤ ·) {x | Maximal P x} := +theorem setOfPred_maximal_antichain (P : α → Prop) : IsAntichain (· ≤ ·) {x | Maximal P x} := fun _ hx _ ⟨hy, _⟩ hne hle ↦ hne (hle.antisymm <| hx.2 hy hle) -theorem setOf_minimal_antichain (P : α → Prop) : IsAntichain (· ≤ ·) {x | Minimal P x} := - (setOf_maximal_antichain (α := αᵒᵈ) P).swap +@[deprecated (since := "2026-07-09")] +alias setOf_maximal_antichain := setOfPred_maximal_antichain + +theorem setOfPred_minimal_antichain (P : α → Prop) : IsAntichain (· ≤ ·) {x | Minimal P x} := + (setOfPred_maximal_antichain (α := αᵒᵈ) P).swap + +@[deprecated (since := "2026-07-09")] alias setOf_minimal_antichain := setOfPred_minimal_antichain end PartialOrder diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index f82253b6da7c7d..73ba47772225cd 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -692,7 +692,7 @@ instance {α} [CompleteAtomicBooleanAlgebra α] : IsAtomistic α := instance {α} [CompleteAtomicBooleanAlgebra α] : IsCoatomistic α := isAtomistic_dual_iff_isCoatomistic.1 inferInstance -lemma eq_setOf_le_sSup_and_isAtom {α} [CompleteAtomicBooleanAlgebra α] {S : Set α} +lemma eq_setOfPred_le_sSup_and_isAtom {α} [CompleteAtomicBooleanAlgebra α] {S : Set α} (hS : ∀ a ∈ S, IsAtom a) : S = {a | a ≤ sSup S ∧ IsAtom a} := by ext a refine ⟨fun h => ⟨le_sSup h, hS a h⟩, fun ⟨hale, hatom⟩ => ?_⟩ @@ -701,6 +701,9 @@ lemma eq_setOf_le_sSup_and_isAtom {α} [CompleteAtomicBooleanAlgebra α] {S : Se · simpa using hatom.1 assumption +@[deprecated (since := "2026-07-09")] +alias eq_setOf_le_sSup_and_isAtom := eq_setOfPred_le_sSup_and_isAtom + set_option backward.isDefEq.respectTransparency false in /-- Representation theorem for complete atomic boolean algebras: @@ -715,7 +718,7 @@ def toSetOfIsAtom {α} [CompleteAtomicBooleanAlgebra α] : α ≃o (Set {a : α have h : ∀ a ∈ Subtype.val '' S, IsAtom a := by rintro a ⟨a', ha', rfl⟩ exact a'.prop - rw [← Subtype.val_injective.image_injective.eq_iff, eq_setOf_le_sSup_and_isAtom h] + rw [← Subtype.val_injective.image_injective.eq_iff, eq_setOfPred_le_sSup_and_isAtom h] ext a simp map_rel_iff' {a b} := by diff --git a/Mathlib/Order/BooleanAlgebra/Set.lean b/Mathlib/Order/BooleanAlgebra/Set.lean index 6d0c6ec6ab3679..3968a813dbc413 100644 --- a/Mathlib/Order/BooleanAlgebra/Set.lean +++ b/Mathlib/Order/BooleanAlgebra/Set.lean @@ -93,9 +93,11 @@ theorem compl_def (s : Set α) : sᶜ = { x | x ∉ s } := theorem mem_compl {s : Set α} {x : α} (h : x ∉ s) : x ∈ sᶜ := h -theorem compl_setOf {α} (p : α → Prop) : { a | p a }ᶜ = { a | ¬p a } := +theorem compl_ofPred {α} (p : α → Prop) : { a | p a }ᶜ = { a | ¬p a } := rfl +@[deprecated (since := "2026-07-09")] alias compl_setOf := compl_ofPred + theorem notMem_of_mem_compl {s : Set α} {x : α} (h : x ∈ sᶜ) : x ∉ s := h diff --git a/Mathlib/Order/BooleanGenerators.lean b/Mathlib/Order/BooleanGenerators.lean index f9eb50e0efb6f3..e152409d611100 100644 --- a/Mathlib/Order/BooleanGenerators.lean +++ b/Mathlib/Order/BooleanGenerators.lean @@ -95,7 +95,7 @@ lemma atomistic (hS : BooleanGenerators S) (a : α) (ha : a ≤ sSup S) : ∃ T apply sSup_le_sSup apply _root_.le_sSup use c, hc, hC _ hc, (le_sSup hc).trans ha - · simp only [Set.sSup_eq_sUnion, sSup_le_iff, Set.mem_sUnion, Set.mem_setOf_eq, + · simp only [Set.sSup_eq_sUnion, sSup_le_iff, Set.mem_sUnion, Set.mem_ofPred_eq, forall_exists_index, and_imp] rintro a T b hbC hb hbS rfl haT apply (le_sSup haT).trans diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index f516384e666df1..a00caaa768c552 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -642,7 +642,7 @@ theorem not_bddAbove_univ [NoTopOrder α] : ¬BddAbove (univ : Set α) := by sim @[to_dual (attr := simp)] theorem upperBounds_empty : upperBounds (∅ : Set α) = univ := by - simp only [upperBounds, eq_univ_iff_forall, mem_setOf_eq, forall_mem_empty, forall_true_iff] + simp only [upperBounds, eq_univ_iff_forall, mem_ofPred_eq, forall_mem_empty, forall_true_iff] @[to_dual (attr := simp)] theorem bddAbove_empty [Nonempty α] : BddAbove (∅ : Set α) := by diff --git a/Mathlib/Order/BourbakiWitt.lean b/Mathlib/Order/BourbakiWitt.lean index 9e3c206ec7afef..beddd537551b2e 100644 --- a/Mathlib/Order/BourbakiWitt.lean +++ b/Mathlib/Order/BourbakiWitt.lean @@ -153,7 +153,7 @@ lemma bot_eq_of_le_or_map_le {y : α} (le_map : ∀ x, x ≤ f x) (hy : IsExtrem right apply le_trans h' (le_cSup _ _ hz) -lemma setOf_isExtremePt_isAdmissible (le_map : ∀ x, x ≤ f x) : +lemma setOfPred_isExtremePt_isAdmissible (le_map : ∀ x, x ≤ f x) : IsAdmissible x f {y | IsExtremePt x f y} := by apply IsAdmissible.mk · constructor @@ -193,14 +193,20 @@ lemma setOf_isExtremePt_isAdmissible (le_map : ∀ x, x ≤ f x) : intro hc' exact lt_irrefl y (lt_of_lt_of_le hy' hc') -lemma setOf_isExtremePt_eq_bot (le_map : ∀ x, x ≤ f x) : {y | IsExtremePt x f y} = bot x f := by +@[deprecated (since := "2026-07-09")] +alias setOf_isExtremePt_isAdmissible := setOfPred_isExtremePt_isAdmissible + +lemma setOfPred_isExtremePt_eq_bot (le_map : ∀ x, x ≤ f x) : {y | IsExtremePt x f y} = bot x f := by rw [← subset_bot_iff] · exact fun _ h ↦ h.mem_bot - · exact setOf_isExtremePt_isAdmissible le_map + · exact setOfPred_isExtremePt_isAdmissible le_map + +@[deprecated (since := "2026-07-09")] +alias setOf_isExtremePt_eq_bot := setOfPred_isExtremePt_eq_bot lemma mem_bot_iff_isExtremePt {y : α} (le_map : ∀ x, x ≤ f x) : y ∈ bot x f ↔ IsExtremePt x f y := by - rw [← setOf_isExtremePt_eq_bot le_map, mem_setOf] + rw [← setOfPred_isExtremePt_eq_bot le_map, mem_ofPred] lemma bot_isChain (le_map : ∀ x, x ≤ f x) : IsChain (· ≤ ·) (bot x f) := by intro y hy z hz _ diff --git a/Mathlib/Order/Circular.lean b/Mathlib/Order/Circular.lean index fba2e79292da1d..073192dbecd6bb 100644 --- a/Mathlib/Order/Circular.lean +++ b/Mathlib/Order/Circular.lean @@ -328,11 +328,11 @@ theorem right_mem_cIcc (a b : α) : b ∈ cIcc a b := theorem compl_cIcc {a b : α} : (cIcc a b)ᶜ = cIoo b a := by ext - rw [Set.mem_cIoo, sbtw_iff_not_btw, cIcc, mem_compl_iff, mem_setOf] + rw [Set.mem_cIoo, sbtw_iff_not_btw, cIcc, mem_compl_iff, mem_ofPred] theorem compl_cIoo {a b : α} : (cIoo a b)ᶜ = cIcc b a := by ext - rw [Set.mem_cIcc, btw_iff_not_sbtw, cIoo, mem_compl_iff, mem_setOf] + rw [Set.mem_cIcc, btw_iff_not_sbtw, cIoo, mem_compl_iff, mem_ofPred] end CircularOrder diff --git a/Mathlib/Order/Closure.lean b/Mathlib/Order/Closure.lean index 4b9b99d6ba2e11..7694f702c4bede 100644 --- a/Mathlib/Order/Closure.lean +++ b/Mathlib/Order/Closure.lean @@ -149,9 +149,12 @@ variable {c} {x y : α} theorem IsClosed.closure_eq : c.IsClosed x → c x = x := c.isClosed_iff.1 /-- The set of closed elements for `c` is exactly its range. -/ -theorem setOf_isClosed_eq_range_closure : {x | c.IsClosed x} = Set.range c := by +theorem setOfPred_isClosed_eq_range_closure : {x | c.IsClosed x} = Set.range c := by ext x; exact ⟨fun hx ↦ ⟨x, hx.closure_eq⟩, by rintro ⟨y, rfl⟩; exact c.isClosed_closure _⟩ +@[deprecated (since := "2026-07-09")] +alias setOf_isClosed_eq_range_closure := setOfPred_isClosed_eq_range_closure + theorem le_closure_iff : x ≤ c y ↔ c x ≤ c y := ⟨fun h ↦ c.idempotent y ▸ c.monotone h, (c.le_closure x).trans⟩ @@ -401,7 +404,7 @@ theorem closure_is_closed (x : α) : u (l x) ∈ l.closed := /-- The set of closed elements for `l` is the range of `u ∘ l`. -/ theorem closed_eq_range_close : l.closed = Set.range (u ∘ l) := - l.closureOperator.setOf_isClosed_eq_range_closure + l.closureOperator.setOfPred_isClosed_eq_range_closure /-- Send an `x` to an element of the set of closed elements (by taking the closure). -/ def toClosed (x : α) : l.closed := diff --git a/Mathlib/Order/Cofinal.lean b/Mathlib/Order/Cofinal.lean index 1269f4bdf408f6..321a2fb702bdad 100644 --- a/Mathlib/Order/Cofinal.lean +++ b/Mathlib/Order/Cofinal.lean @@ -165,7 +165,7 @@ theorem not_bddAbove_iff_isCofinal [NoMaxOrder α] {s : Set α} : ¬ BddAbove s /-- The set of "records" (the smallest inputs yielding the highest values) with respect to a well-ordering of `α` is a cofinal set. -/ -theorem isCofinal_setOf_imp_lt (r : α → α → Prop) [h : IsWellFounded α r] : +theorem isCofinal_setOfPred_imp_lt (r : α → α → Prop) [h : IsWellFounded α r] : IsCofinal { a | ∀ b, r b a → b < a } := by intro a obtain ⟨b, hb, hb'⟩ := h.wf.has_min (Set.Ici a) Set.nonempty_Ici @@ -173,6 +173,8 @@ theorem isCofinal_setOf_imp_lt (r : α → α → Prop) [h : IsWellFounded α r] by_contra! hc' exact hb' c (hb.trans hc') hc +@[deprecated (since := "2026-07-09")] alias isCofinal_setOf_imp_lt := isCofinal_setOfPred_imp_lt + theorem isCofinal_range_of_strictMono [WellFoundedLT α] {f : α → α} (hf : StrictMono f) : IsCofinal (range f) := fun x ↦ ⟨_, ⟨x, rfl⟩, hf.le_apply⟩ diff --git a/Mathlib/Order/CompactlyGenerated/Basic.lean b/Mathlib/Order/CompactlyGenerated/Basic.lean index c1905fb75c6263..07739d090dcd85 100644 --- a/Mathlib/Order/CompactlyGenerated/Basic.lean +++ b/Mathlib/Order/CompactlyGenerated/Basic.lean @@ -452,7 +452,7 @@ lemma iSupIndep_iff_supIndep {ι : Type*} {f : ι → α} : classical have hf : Set.InjOn f {i : ι | f i ≠ ⊥} := by by_contra! hf - simp_all only [Set.InjOn, ne_eq, Set.mem_setOf_eq, not_forall] + simp_all only [Set.InjOn, ne_eq, Set.mem_ofPred_eq, not_forall] obtain ⟨x₁, hx₁, x₂, hx₂, hfeq, hneq⟩ := hf specialize h ({x₁, x₂} : Finset ι) rw [Finset.supIndep_pair hneq, disjoint_iff, hfeq, inf_idem (f x₂)] at h diff --git a/Mathlib/Order/CompleteLattice/Chain.lean b/Mathlib/Order/CompleteLattice/Chain.lean index b10b8b938ecff5..ab70a8e351e20b 100644 --- a/Mathlib/Order/CompleteLattice/Chain.lean +++ b/Mathlib/Order/CompleteLattice/Chain.lean @@ -36,7 +36,7 @@ inductive ChainClosure (r : α → α → Prop) : Set α → Prop | union : ∀ {s}, (∀ a ∈ s, ChainClosure r a) → ChainClosure r (⋃₀ s) /-- An explicit maximal chain. `maxChain` is taken to be the union of all sets in `ChainClosure`. -/ -def maxChain (r : α → α → Prop) : Set α := ⋃₀ setOf (ChainClosure r) +def maxChain (r : α → α → Prop) : Set α := ⋃₀ Set.ofPred (ChainClosure r) lemma chainClosure_empty : ChainClosure r ∅ := by have : ChainClosure r (⋃₀ ∅) := ChainClosure.union fun a h => (notMem_empty _ h).elim diff --git a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean index 727b409414c943..d739752fefd1c8 100644 --- a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean @@ -203,7 +203,7 @@ theorem l_csSup_of_directedOn' (gc : GaloisConnection l u) {s : Set α} theorem l_csSup_of_directedOn (gc : GaloisConnection l u) {s : Set α} (hd : DirectedOn (· ≤ ·) s) (hne : s.Nonempty) (hbdd : BddAbove s) : l (sSup s) = ⨆ x : s, l x := by - simpa only [← comp_def, ← sSup_range, range_comp, Subtype.range_coe_subtype, setOf_mem_eq] + simpa only [← comp_def, ← sSup_range, range_comp, Subtype.range_coe_subtype, ofPred_mem_eq] using gc.l_csSup_of_directedOn' hd hne hbdd theorem l_ciSup_of_directed (gc : GaloisConnection l u) {f : ι → α} (hd : Directed (· ≤ ·) f) diff --git a/Mathlib/Order/CountableSupClosed.lean b/Mathlib/Order/CountableSupClosed.lean index 5bebdc531fc481..84fe705e22325f 100644 --- a/Mathlib/Order/CountableSupClosed.lean +++ b/Mathlib/Order/CountableSupClosed.lean @@ -229,7 +229,7 @@ lemma countableSupClosure_eq_sInter (s : Set α) : countableSupClosure s = ⋂₀ {t | s ⊆ t ∧ CountableSupClosed t} := by have : CountableSupClosed (⋂₀ {t | s ⊆ t ∧ CountableSupClosed t}) := by constructor - simp only [Set.subset_sInter_iff, Set.mem_setOf_eq, and_imp, Set.mem_sInter] + simp only [Set.subset_sInter_iff, Set.mem_ofPred_eq, and_imp, Set.mem_sInter] intro t ht ht_ne ht_c x hx t' hst' ht' exact ht'.isLUB_mem t (ht t' hst' ht') ht_ne ht_c x hx refine le_antisymm (countableSupClosure_min (by grind) (by grind)) (Set.sInter_subset_of_mem ?_) diff --git a/Mathlib/Order/Filter/Bases/Basic.lean b/Mathlib/Order/Filter/Bases/Basic.lean index cfbbfa7a4197ef..983afa593ea91c 100644 --- a/Mathlib/Order/Filter/Bases/Basic.lean +++ b/Mathlib/Order/Filter/Bases/Basic.lean @@ -22,7 +22,7 @@ to `B.filter` if and only if it contains an element of `B`. Given an indexing type `ι`, a predicate `p : ι → Prop`, and a map `s : ι → Set α`, the proposition `h : Filter.IsBasis p s` makes sure the range of `s` bounded by `p` -(i.e. `s '' setOf p`) defines a filter basis `h.filterBasis`. +(i.e. `s '' Set.ofPred p`) defines a filter basis `h.filterBasis`. If one already has a filter `l` on `α`, `Filter.HasBasis l p s` (where `p : ι → Prop` and `s : ι → Set α` as above) means that a set belongs to `l` if and @@ -485,7 +485,7 @@ theorem HasBasis.sup_pure (hl : l.HasBasis p s) (x : α) : theorem HasBasis.inf_principal (hl : l.HasBasis p s) (s' : Set α) : (l ⊓ 𝓟 s').HasBasis p fun i => s i ∩ s' := ⟨fun t => by - simp only [mem_inf_principal, hl.mem_iff, subset_def, mem_setOf_eq, mem_inter_iff, and_imp]⟩ + simp only [mem_inf_principal, hl.mem_iff, subset_def, mem_ofPred_eq, mem_inter_iff, and_imp]⟩ theorem HasBasis.principal_inf (hl : l.HasBasis p s) (s' : Set α) : (𝓟 s' ⊓ l).HasBasis p fun i => s' ∩ s i := by @@ -744,7 +744,7 @@ theorem mem_prod_self_iff {s} : s ∈ la ×ˢ la ↔ ∃ t ∈ la, t ×ˢ t ⊆ lemma eventually_prod_self_iff {r : α → α → Prop} : (∀ᶠ x in la ×ˢ la, r x.1 x.2) ↔ ∃ t ∈ la, ∀ x ∈ t, ∀ y ∈ t, r x y := - mem_prod_self_iff.trans <| by simp only [prod_subset_iff, mem_setOf_eq] + mem_prod_self_iff.trans <| by simp only [prod_subset_iff, mem_ofPred_eq] /-- A version of `eventually_prod_self_iff` that is more suitable for forward rewriting. -/ lemma eventually_prod_self_iff' {r : α × α → Prop} : diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 9dd612296fb2c7..1fb22e6f63d079 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -593,7 +593,7 @@ theorem mem_inf_principal' {f : Filter α} {s t : Set α} : s ∈ f ⊓ 𝓟 t ← (isCompl_principal (t ∩ sᶜ)).le_right_iff, compl_inter, compl_compl] lemma mem_inf_principal {f : Filter α} {s t : Set α} : s ∈ f ⊓ 𝓟 t ↔ { x | x ∈ t → x ∈ s } ∈ f := by - simp only [mem_inf_principal', imp_iff_not_or, setOf_or, compl_def, setOf_mem_eq] + simp only [mem_inf_principal', imp_iff_not_or, ofPred_or, compl_def, ofPred_mem_eq] lemma iSup_inf_principal (f : ι → Filter α) (s : Set α) : ⨆ i, f i ⊓ 𝓟 s = (⨆ i, f i) ⊓ 𝓟 s := by ext @@ -632,7 +632,7 @@ theorem eventually_mem_set {s : Set α} {l : Filter α} : (∀ᶠ x in l, x ∈ protected theorem ext' {f₁ f₂ : Filter α} (h : ∀ p : α → Prop, (∀ᶠ x in f₁, p x) ↔ ∀ᶠ x in f₂, p x) : f₁ = f₂ := - Filter.ext <| Set.setOf_bijective.surjective.forall.mpr h + Filter.ext <| Set.ofPred_bijective.surjective.forall.mpr h theorem Eventually.filter_mono {f₁ f₂ : Filter α} (h : f₁ ≤ f₂) {p : α → Prop} (hp : ∀ᶠ x in f₂, p x) : ∀ᶠ x in f₁, p x := @@ -811,7 +811,7 @@ theorem frequently_iff_forall_eventually_exists_and {p : α → Prop} {f : Filte theorem frequently_iff {f : Filter α} {P : α → Prop} : (∃ᶠ x in f, P x) ↔ ∀ {U}, U ∈ f → ∃ x ∈ U, P x := by simp only [frequently_iff_forall_eventually_exists_and, @and_comm (P _), - Set.setOf_bijective.surjective.forall, Filter.Eventually, mem_setOf] + Set.ofPred_bijective.surjective.forall, Filter.Eventually, mem_ofPred] @[simp, push] theorem not_eventually {p : α → Prop} {f : Filter α} : (¬∀ᶠ x in f, p x) ↔ ∃ᶠ x in f, ¬p x := by diff --git a/Mathlib/Order/Filter/CardinalInter.lean b/Mathlib/Order/Filter/CardinalInter.lean index e6541960d896c4..eb423ae9003c7d 100644 --- a/Mathlib/Order/Filter/CardinalInter.lean +++ b/Mathlib/Order/Filter/CardinalInter.lean @@ -56,7 +56,7 @@ theorem cardinal_sInter_mem {S : Set (Set α)} [CardinalInterFilter l c] (hSc : /-- Every filter is a CardinalInterFilter with c = ℵ₀ -/ theorem _root_.Filter.cardinalInterFilter_aleph0 (l : Filter α) : CardinalInterFilter l ℵ₀ where cardinal_sInter_mem := by - simp_all only [lt_aleph0_iff_subtype_finite, setOf_mem_eq, sInter_mem, + simp_all only [lt_aleph0_iff_subtype_finite, ofPred_mem_eq, sInter_mem, implies_true] /-- Every CardinalInterFilter with c > ℵ₀ is a CountableInterFilter -/ @@ -107,13 +107,13 @@ theorem cardinal_bInter_mem {S : Set ι} (hS : #S < c) theorem eventually_cardinal_forall {p : α → ι → Prop} (hic : #ι < c) : (∀ᶠ x in l, ∀ i, p x i) ↔ ∀ i, ∀ᶠ x in l, p x i := by - simp only [Filter.Eventually, setOf_forall] + simp only [Filter.Eventually, ofPred_forall] exact cardinal_iInter_mem hic theorem eventually_cardinal_ball {S : Set ι} (hS : #S < c) {p : α → ∀ i ∈ S, Prop} : (∀ᶠ x in l, ∀ i hi, p x i hi) ↔ ∀ i hi, ∀ᶠ x in l, p x i hi := by - simp only [Filter.Eventually, setOf_forall] + simp only [Filter.Eventually, ofPred_forall] exact cardinal_bInter_mem hS theorem EventuallyLE.cardinal_iUnion {s t : ι → Set α} (hic : #ι < c) @@ -198,13 +198,13 @@ def ofCardinalUnion (l : Set (Set α)) (hc : 2 < c) (hUnion : ∀ S : Set (Set α), (#S < c) → (∀ s ∈ S, s ∈ l) → ⋃₀ S ∈ l) (hmono : ∀ t ∈ l, ∀ s ⊆ t, s ∈ l) : Filter α := by refine .ofCardinalInter {s | sᶜ ∈ l} hc (fun S hSc hSp ↦ ?_) fun s t ht hsub ↦ ?_ - · rw [mem_setOf_eq, compl_sInter] + · rw [mem_ofPred_eq, compl_sInter] apply hUnion (compl '' S) (lt_of_le_of_lt mk_image_le hSc) intro s hs rw [mem_image] at hs rcases hs with ⟨t, ht, rfl⟩ apply hSp ht - · rw [mem_setOf_eq] + · rw [mem_ofPred_eq] rw [← compl_subset_compl] at hsub exact hmono sᶜ ht tᶜ hsub diff --git a/Mathlib/Order/Filter/Cocardinal.lean b/Mathlib/Order/Filter/Cocardinal.lean index c783b9c7c598e6..8c1efdd22ce138 100644 --- a/Mathlib/Order/Filter/Cocardinal.lean +++ b/Mathlib/Order/Filter/Cocardinal.lean @@ -70,7 +70,7 @@ theorem hasBasis_cocardinal : HasBasis (cocardinal α hreg) {s : Set α | #s < c theorem frequently_cocardinal {p : α → Prop} : (∃ᶠ x in cocardinal α hreg, p x) ↔ c ≤ #{ x | p x } := by - simp only [Filter.Frequently, eventually_cocardinal, not_not, coe_setOf, not_lt] + simp only [Filter.Frequently, eventually_cocardinal, not_not, coe_ofPred, not_lt] lemma frequently_cocardinal_mem {s : Set α} : (∃ᶠ x in cocardinal α hreg, x ∈ s) ↔ c ≤ #s := frequently_cocardinal diff --git a/Mathlib/Order/Filter/CountableInter.lean b/Mathlib/Order/Filter/CountableInter.lean index ca1c030a088a15..45629d38f463ee 100644 --- a/Mathlib/Order/Filter/CountableInter.lean +++ b/Mathlib/Order/Filter/CountableInter.lean @@ -60,13 +60,13 @@ theorem countable_bInter_mem {ι : Type*} {S : Set ι} (hS : S.Countable) {s : theorem eventually_countable_forall [Countable ι] {p : α → ι → Prop} : (∀ᶠ x in l, ∀ i, p x i) ↔ ∀ i, ∀ᶠ x in l, p x i := by - simpa only [Filter.Eventually, setOf_forall] using + simpa only [Filter.Eventually, ofPred_forall] using @countable_iInter_mem _ _ l _ _ fun i => { x | p x i } theorem eventually_countable_ball {ι : Type*} {S : Set ι} (hS : S.Countable) {p : α → ∀ i ∈ S, Prop} : (∀ᶠ x in l, ∀ i hi, p x i hi) ↔ ∀ i hi, ∀ᶠ x in l, p x i hi := by - simpa only [Filter.Eventually, setOf_forall] using + simpa only [Filter.Eventually, ofPred_forall] using @countable_bInter_mem _ l _ _ _ hS fun i hi => { x | p x i hi } theorem eventually_finset_ball {ι : Type*} {S : Finset ι} {p : α → ∀ i ∈ S, Prop} : @@ -176,13 +176,13 @@ def ofCountableUnion (l : Set (Set α)) (hUnion : ∀ S : Set (Set α), S.Countable → (∀ s ∈ S, s ∈ l) → ⋃₀ S ∈ l) (hmono : ∀ t ∈ l, ∀ s ⊆ t, s ∈ l) : Filter α := by refine .ofCountableInter {s | sᶜ ∈ l} (fun S hSc hSp ↦ ?_) fun s t ht hsub ↦ ?_ - · rw [mem_setOf_eq, compl_sInter] + · rw [mem_ofPred_eq, compl_sInter] apply hUnion (compl '' S) (hSc.image _) intro s hs rw [mem_image] at hs rcases hs with ⟨t, ht, rfl⟩ apply hSp ht - · rw [mem_setOf_eq] + · rw [mem_ofPred_eq] rw [← compl_subset_compl] at hsub exact hmono sᶜ ht tᶜ hsub diff --git a/Mathlib/Order/Filter/CountablyGenerated.lean b/Mathlib/Order/Filter/CountablyGenerated.lean index acc28986485df4..ca496240de853f 100644 --- a/Mathlib/Order/Filter/CountablyGenerated.lean +++ b/Mathlib/Order/Filter/CountablyGenerated.lean @@ -34,7 +34,7 @@ class IsCountablyGenerated (f : Filter α) : Prop where /-- `IsCountableBasis p s` means the image of `s` bounded by `p` is a countable filter basis. -/ structure IsCountableBasis (p : ι → Prop) (s : ι → Set α) : Prop extends IsBasis p s where /-- The set of `i` that satisfy the predicate `p` is countable. -/ - countable : (setOf p).Countable + countable : (Set.ofPred p).Countable /-- We say that a filter `l` has a countable basis `s : ι → Set α` bounded by `p : ι → Prop`, if `t ∈ l` if and only if `t` includes `s i` for some `i` such that `p i`, and the set @@ -42,7 +42,7 @@ defined by `p` is countable. -/ structure HasCountableBasis (l : Filter α) (p : ι → Prop) (s : ι → Set α) : Prop extends HasBasis l p s where /-- The set of `i` that satisfy the predicate `p` is countable. -/ - countable : (setOf p).Countable + countable : (Set.ofPred p).Countable /-- A countable filter basis `B` on a type `α` is a nonempty countable collection of sets of `α` such that the intersection of two elements of this collection contains some element diff --git a/Mathlib/Order/Filter/Defs.lean b/Mathlib/Order/Filter/Defs.lean index 3c308f9c7a2ae8..e767332d42aad0 100644 --- a/Mathlib/Order/Filter/Defs.lean +++ b/Mathlib/Order/Filter/Defs.lean @@ -171,7 +171,7 @@ def ker (f : Filter α) : Set α := ⋂₀ f.sets /-- The join of a filter of filters is defined by the relation `s ∈ join f ↔ {t | s ∈ t} ∈ f`. -/ def join (f : Filter (Filter α)) : Filter α where sets := { s | { t : Filter α | s ∈ t } ∈ f } - univ_sets := by simp only [mem_setOf_eq, univ_mem, setOf_true] + univ_sets := by simp only [mem_ofPred_eq, univ_mem, ofPred_true] sets_of_superset hx xy := mem_of_superset hx fun f h => mem_of_superset h xy inter_sets hx hy := mem_of_superset (inter_mem hx hy) fun f ⟨h₁, h₂⟩ => inter_mem h₁ h₂ @@ -458,7 +458,7 @@ elab_rules : tactic return [m.mvarId!] liftMetaTactic fun goal => do goal.apply (← mkConstWithFreshMVarLevels ``Filter.univ_mem') config - evalTactic <|← `(tactic| try dsimp -zeta only [Set.mem_setOf_eq]) + evalTactic <|← `(tactic| try dsimp -zeta only [Set.mem_ofPred_eq]) if let some l := wth then evalTactic <|← `(tactic| intro $[$l]*) if let some e := usingArg then diff --git a/Mathlib/Order/Filter/ENNReal.lean b/Mathlib/Order/Filter/ENNReal.lean index 63cb8665190c29..f5f4aba83a91a6 100644 --- a/Mathlib/Order/Filter/ENNReal.lean +++ b/Mathlib/Order/Filter/ENNReal.lean @@ -296,7 +296,7 @@ lemma toReal_limsup {u : α → ℝ≥0∞} (h₁ : ∀ᶠ a in f, u a ≠ ∞) obtain ⟨x, hx⟩ := h₂ rw [eventually_map] at hx have hx₀ : 0 ≤ x := by obtain ⟨i, hi⟩ := hx.exists; exact toReal_nonneg.trans hi - simp only [limsup, limsSup, eventually_map, ne_eq, sInf_eq_top, Set.mem_setOf_eq, not_forall] + simp only [limsup, limsSup, eventually_map, ne_eq, sInf_eq_top, Set.mem_ofPred_eq, not_forall] refine ⟨.ofReal x, ?_, by simp⟩ filter_upwards [h₁, hx] with i hi simp [le_ofReal_iff_toReal_le, *] diff --git a/Mathlib/Order/Filter/Extr.lean b/Mathlib/Order/Filter/Extr.lean index f8337827d8f967..5f806dabb50622 100644 --- a/Mathlib/Order/Filter/Extr.lean +++ b/Mathlib/Order/Filter/Extr.lean @@ -144,7 +144,7 @@ theorem IsMinOn.isGLB (ha : a ∈ s) (hfsa : IsMinOn f s a) : IsGLB {f x | x ∈ s} (f a) := by rw [isGLB_iff_le_iff] intro b - simp only [mem_lowerBounds, mem_setOf_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] + simp only [mem_lowerBounds, mem_ofPred_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] exact ⟨fun hba x hx ↦ le_trans hba (hfsa hx), fun hb ↦ hb a ha⟩ theorem IsMaxOn.isLUB (ha : a ∈ s) (hfsa : IsMaxOn f s a) : diff --git a/Mathlib/Order/Filter/Finite.lean b/Mathlib/Order/Filter/Finite.lean index 3c34527e21e043..7c28143eefe087 100644 --- a/Mathlib/Order/Filter/Finite.lean +++ b/Mathlib/Order/Filter/Finite.lean @@ -142,7 +142,7 @@ theorem mem_biInf_principal {ι : Type*} {p : ι → Prop} {s : ι → Set α} { rintro ⟨I, hIf, V, hV₁, hV₂, rfl⟩ choose! t ht₁ ht₂ using hV₁ refine ⟨I ∩ {i | p i}, hIf.inter_of_left _, fun i ↦ And.right, ?_⟩ - simp only [mem_inter_iff, iInter_and, biInter_eq_iInter, ht₂, mem_setOf_eq] + simp only [mem_inter_iff, iInter_and, biInter_eq_iInter, ht₂, mem_ofPred_eq] gcongr with i hpi exact ht₁ i hpi · rintro ⟨I, hIf, hpI, hst⟩ @@ -248,12 +248,12 @@ end Lattice @[simp] theorem eventually_all {ι : Sort*} [Finite ι] {l} {p : ι → α → Prop} : (∀ᶠ x in l, ∀ i, p i x) ↔ ∀ i, ∀ᶠ x in l, p i x := by - simpa only [Filter.Eventually, setOf_forall] using iInter_mem + simpa only [Filter.Eventually, ofPred_forall] using iInter_mem @[simp] theorem eventually_all_finite {ι} {I : Set ι} (hI : I.Finite) {l} {p : ι → α → Prop} : (∀ᶠ x in l, ∀ i ∈ I, p i x) ↔ ∀ i ∈ I, ∀ᶠ x in l, p i x := by - simpa only [Filter.Eventually, setOf_forall] using biInter_mem hI + simpa only [Filter.Eventually, ofPred_forall] using biInter_mem hI protected alias _root_.Set.Finite.eventually_all := eventually_all_finite diff --git a/Mathlib/Order/Filter/Lift.lean b/Mathlib/Order/Filter/Lift.lean index 8b1aac68e36d41..e85e736676879e 100644 --- a/Mathlib/Order/Filter/Lift.lean +++ b/Mathlib/Order/Filter/Lift.lean @@ -73,7 +73,7 @@ theorem mem_lift_sets (hg : Monotone g) {s : Set β} : s ∈ f.lift g ↔ ∃ t theorem sInter_lift_sets (hg : Monotone g) : ⋂₀ { s | s ∈ f.lift g } = ⋂ s ∈ f, ⋂₀ { t | t ∈ g s } := by - simp only [sInter_eq_biInter, mem_setOf_eq, mem_lift_sets hg, iInter_exists, + simp only [sInter_eq_biInter, mem_ofPred_eq, mem_lift_sets hg, iInter_exists, iInter_and, @iInter_comm _ (Set β)] theorem mem_lift {s : Set β} {t : Set α} (ht : t ∈ f) (hs : s ∈ g t) : s ∈ f.lift g := diff --git a/Mathlib/Order/Filter/Partial.lean b/Mathlib/Order/Filter/Partial.lean index f77074f13693f2..f1f514c639530f 100644 --- a/Mathlib/Order/Filter/Partial.lean +++ b/Mathlib/Order/Filter/Partial.lean @@ -63,7 +63,7 @@ def rmap (r : SetRel α β) (l : Filter α) : Filter β where univ_sets := by simp sets_of_superset hs st := mem_of_superset hs (SetRel.core_mono st) inter_sets hs ht := by - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] convert! inter_mem hs ht rw [← SetRel.core_inter] @@ -110,7 +110,7 @@ theorem rcomap_rcomap (r : SetRel α β) (s : SetRel β γ) (l : Filter γ) : rcomap r (rcomap s l) = rcomap (r.comp s) l := filter_eq <| by ext t - simp only [rcomap_sets, SetRel.image, Filter.mem_sets, Set.mem_setOf_eq, SetRel.core_comp] + simp only [rcomap_sets, SetRel.image, Filter.mem_sets, Set.mem_ofPred_eq, SetRel.core_comp] constructor · rintro ⟨u, ⟨v, vsets, hv⟩, h⟩ exact ⟨v, vsets, Set.Subset.trans (SetRel.core_mono hv) h⟩ diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index 15aa32cf1cfa23..077557f410efef 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -88,7 +88,7 @@ theorem mem_prod_top {s : Set (α × β)} : theorem eventually_prod_principal_iff {p : α × β → Prop} {s : Set β} : (∀ᶠ x : α × β in f ×ˢ 𝓟 s, p x) ↔ ∀ᶠ x : α in f, ∀ y : β, y ∈ s → p (x, y) := by rw [eventually_iff, eventually_iff, mem_prod_principal] - simp only [mem_setOf_eq] + simp only [mem_ofPred_eq] theorem comap_prod (f : α → β × γ) (b : Filter β) (c : Filter γ) : comap f (b ×ˢ c) = comap (Prod.fst ∘ f) b ⊓ comap (Prod.snd ∘ f) c := by diff --git a/Mathlib/Order/Filter/Tendsto.lean b/Mathlib/Order/Filter/Tendsto.lean index ed556e78c1f9f6..7f85e578caf6eb 100644 --- a/Mathlib/Order/Filter/Tendsto.lean +++ b/Mathlib/Order/Filter/Tendsto.lean @@ -257,7 +257,7 @@ theorem tendsto_pure_left {f : α → β} {a : α} {l : Filter β} : @[simp] theorem map_inf_principal_preimage {f : α → β} {s : Set β} {l : Filter α} : map f (l ⊓ 𝓟 (f ⁻¹' s)) = map f l ⊓ 𝓟 s := - Filter.ext fun t => by simp only [mem_map', mem_inf_principal, mem_setOf_eq, mem_preimage] + Filter.ext fun t => by simp only [mem_map', mem_inf_principal, mem_ofPred_eq, mem_preimage] /-- If two filters are disjoint, then a function cannot tend to both of them along a non-trivial filter. -/ diff --git a/Mathlib/Order/Filter/TendstoCofinite.lean b/Mathlib/Order/Filter/TendstoCofinite.lean index ecec915ed07312..ae5b51a47fe2a6 100644 --- a/Mathlib/Order/Filter/TendstoCofinite.lean +++ b/Mathlib/Order/Filter/TendstoCofinite.lean @@ -115,7 +115,7 @@ theorem Finsupp.mapDomain_tendstoCofinite [TendstoCofinite f] : let e : s ↪ α := Function.Embedding.subtype (fun u ↦ u ∈ s) refine Set.Finite.subset (Set.Finite.image (embDomain e) <| finite_of_degree_le (degree x)) ?_ simp only [Set.subset_def, Set.mem_preimage, Set.mem_singleton_iff, Set.mem_image, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] refine fun y hy ↦ ⟨y.comapDomain e e.injective.injOn, ?_, embDomain_comapDomain ?_⟩ · rw [← hy, degree_mapDomain] exact degree_comapDomain_le_of_canonicallyOrderedAdd .. diff --git a/Mathlib/Order/Filter/Ultrafilter/Defs.lean b/Mathlib/Order/Filter/Ultrafilter/Defs.lean index ffd0bf126c9b5a..3bc9f124e87551 100644 --- a/Mathlib/Order/Filter/Ultrafilter/Defs.lean +++ b/Mathlib/Order/Filter/Ultrafilter/Defs.lean @@ -263,7 +263,7 @@ instance [Nonempty α] : Nonempty (Ultrafilter α) := defined in terms of map and join. -/ def bind (f : Ultrafilter α) (m : α → Ultrafilter β) : Ultrafilter β := ofComplNotMemIff (Filter.bind ↑f fun x => ↑(m x)) fun s => by - simp only [mem_bind', mem_coe, ← compl_mem_iff_notMem, compl_setOf, compl_compl] + simp only [mem_bind', mem_coe, ← compl_mem_iff_notMem, compl_ofPred, compl_compl] instance instBind : Bind Ultrafilter := ⟨@Ultrafilter.bind⟩ @@ -340,7 +340,7 @@ theorem Iic_pure (a : α) : Iic (pure a : Filter α) = {⊥, pure a} := theorem mem_iff_ultrafilter : s ∈ f ↔ ∀ g : Ultrafilter α, ↑g ≤ f → s ∈ g := by refine ⟨fun hf g hg => hg hf, fun H => by_contra fun hf => ?_⟩ set g : Filter (sᶜ : Set α) := comap (↑) f - have : NeBot g := comap_neBot_iff_compl_range.2 (by simpa [compl_setOf]) + have : NeBot g := comap_neBot_iff_compl_range.2 (by simpa [compl_ofPred]) simpa using H ((of g).map (↑)) (map_le_iff_le_comap.mpr (of_le g)) theorem le_iff_ultrafilter {f₁ f₂ : Filter α} : f₁ ≤ f₂ ↔ ∀ g : Ultrafilter α, ↑g ≤ f₁ → ↑g ≤ f₂ := diff --git a/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean b/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean index 442742305150e7..04840e3ddd325e 100644 --- a/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean +++ b/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean @@ -66,7 +66,7 @@ theorem ordConnectedComponent_univ : ordConnectedComponent univ x = univ := by theorem ordConnectedComponent_inter (s t : Set α) (x : α) : ordConnectedComponent (s ∩ t) x = ordConnectedComponent s x ∩ ordConnectedComponent t x := by - simp [ordConnectedComponent, setOf_and] + simp [ordConnectedComponent, ofPred_and] theorem mem_ordConnectedComponent_comm : y ∈ ordConnectedComponent s x ↔ x ∈ ordConnectedComponent s y := by diff --git a/Mathlib/Order/Interval/Set/Pi.lean b/Mathlib/Order/Interval/Set/Pi.lean index a41b95796a6855..2ce0bf7b0c184f 100644 --- a/Mathlib/Order/Interval/Set/Pi.lean +++ b/Mathlib/Order/Interval/Set/Pi.lean @@ -274,7 +274,7 @@ theorem pi_univ_Ioc_update_union (x y : ∀ i, α i) (i₀ : ι) (m : α i₀) ( pi univ fun i ↦ Ioc (update x i₀ m i) (y i)) = pi univ fun i ↦ Ioc (x i) (y i) := by simp_rw [pi_univ_Ioc_update_left hm.1, pi_univ_Ioc_update_right hm.2, ← union_inter_distrib_right, - ← setOf_or, le_or_gt, setOf_true, univ_inter] + ← ofPred_or, le_or_gt, ofPred_true, univ_inter] /-- If `x`, `y`, `x'`, and `y'` are functions `Π i : ι, α i`, then the set difference between the box `[x, y]` and the product of the open intervals `(x' i, y' i)` diff --git a/Mathlib/Order/JordanHolder.lean b/Mathlib/Order/JordanHolder.lean index f8ad82a6a7dcc5..7495b6259ca627 100644 --- a/Mathlib/Order/JordanHolder.lean +++ b/Mathlib/Order/JordanHolder.lean @@ -243,7 +243,7 @@ theorem isMaximal_eraseLast_last {s : CompositionSeries X} (h : 0 < s.length) : IsMaximal s.eraseLast.last s.last := by rw [last_eraseLast, last] have := s.step ⟨s.length - 1, by lia⟩ - simp only [Fin.castSucc_mk, Fin.succ_mk, mem_setOf_eq] at this + simp only [Fin.castSucc_mk, Fin.succ_mk, mem_ofPred_eq] at this convert! this using 3 exact (tsub_add_cancel_of_le h).symm diff --git a/Mathlib/Order/KonigLemma.lean b/Mathlib/Order/KonigLemma.lean index a3817edf8f0d0b..4f30b4079b91e2 100644 --- a/Mathlib/Order/KonigLemma.lean +++ b/Mathlib/Order/KonigLemma.lean @@ -143,7 +143,7 @@ theorem exists_seq_forall_proj_of_forall_finite {α : ℕ → Type*} [Finite (α exact fun i x h ↦ ⟨zero_le, h⟩ have hfin : ∀ (a : αs), {x | a ⋖ x}.Finite := by refine fun ⟨i, a⟩ ↦ ((hfin i a).image (fun b ↦ ⟨_, b⟩)).subset ?_ - simp only [αs, hcovby, subset_def, mem_setOf_eq, mem_image, and_imp, Sigma.forall] + simp only [αs, hcovby, subset_def, mem_ofPred_eq, mem_image, and_imp, Sigma.forall] exact fun j b ⟨_, _⟩ hj ↦ ⟨π hj.le b, by rwa [π_trans], by cases hj; rw [π_refl]⟩ obtain ⟨f, hf0, hf⟩ := exists_orderEmbedding_covby_of_forall_covby_finite hfin ha₀inf have hr : ∀ i, (f i).1 = i := diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index e8c6c6f0732f19..4b9e2442ba5f3d 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -113,7 +113,7 @@ theorem bliminf_true (f : Filter β) (u : β → α) : (bliminf u f fun _ => Tru lemma blimsup_eq_limsup {f : Filter β} {u : β → α} {p : β → Prop} : blimsup u f p = limsup u (f ⊓ 𝓟 {x | p x}) := by - simp only [blimsup_eq, limsup_eq, eventually_inf_principal, mem_setOf_eq] + simp only [blimsup_eq, limsup_eq, eventually_inf_principal, mem_ofPred_eq] lemma bliminf_eq_liminf {f : Filter β} {u : β → α} {p : β → Prop} : bliminf u f p = liminf u (f ⊓ 𝓟 {x | p x}) := @@ -296,7 +296,7 @@ theorem HasBasis.liminf_eq_sSup_iUnion_iInter {ι ι' : Type*} {f : ι → α} { simp_rw [liminf_eq, hv.eventually_iff] congr 1 ext x - simp only [mem_setOf_eq, iInter_coe_set, mem_iUnion, mem_iInter, mem_Iic, Subtype.exists, + simp only [mem_ofPred_eq, iInter_coe_set, mem_iUnion, mem_iInter, mem_Iic, Subtype.exists, exists_prop] theorem HasBasis.liminf_eq_sSup_univ_of_empty {f : ι → α} {v : Filter ι} @@ -449,7 +449,7 @@ lemma HasBasis.blimsup_eq_iInf_iSup {p : ι → Prop} {s : ι → Set β} {f : F (hf : f.HasBasis p s) {q : β → Prop} : blimsup u f q = ⨅ (i) (_ : p i), ⨆ a ∈ s i, ⨆ (_ : q a), u a := by simp only [blimsup_eq_limsup, (hf.inf_principal _).limsup_eq_iInf_iSup, mem_inter_iff, iSup_and, - mem_setOf_eq] + mem_ofPred_eq] theorem blimsup_eq_iInf_biSup {f : Filter β} {p : β → Prop} {u : β → α} : blimsup u f p = ⨅ s ∈ f, ⨆ (b) (_ : p b ∧ b ∈ s), u b := by @@ -616,7 +616,7 @@ theorem bliminf_or_le_inf_aux_right : (bliminf u f fun x => p x ∨ q x) ≤ bli theorem _root_.OrderIso.apply_blimsup [CompleteLattice γ] (e : α ≃o γ) : e (blimsup u f p) = blimsup (e ∘ u) f p := by simp only [blimsup_eq, map_sInf, Function.comp_apply, e.image_eq_preimage_symm, - Set.preimage_setOf_eq, e.le_symm_apply] + Set.preimage_ofPred_eq, e.le_symm_apply] theorem _root_.OrderIso.apply_bliminf [CompleteLattice γ] (e : α ≃o γ) : e (bliminf u f p) = bliminf (e ∘ u) f p := @@ -641,7 +641,7 @@ variable [CompleteDistribLattice α] {f : Filter β} {p q : β → Prop} {u : β lemma limsup_sup_filter {g} : limsup u (f ⊔ g) = limsup u f ⊔ limsup u g := by refine le_antisymm ?_ (sup_le (limsup_le_limsup_of_le le_sup_left) (limsup_le_limsup_of_le le_sup_right)) - simp_rw [limsup_eq, sInf_sup_eq, sup_sInf_eq, mem_setOf_eq, le_iInf₂_iff] + simp_rw [limsup_eq, sInf_sup_eq, sup_sInf_eq, mem_ofPred_eq, le_iInf₂_iff] intro a ha b hb exact sInf_le ⟨ha.mono fun _ h ↦ h.trans le_sup_left, hb.mono fun _ h ↦ h.trans le_sup_right⟩ @@ -650,7 +650,7 @@ lemma liminf_sup_filter {g} : liminf u (f ⊔ g) = liminf u f ⊓ liminf u g := @[simp] theorem blimsup_or_eq_sup : (blimsup u f fun x => p x ∨ q x) = blimsup u f p ⊔ blimsup u f q := by - simp only [blimsup_eq_limsup, ← limsup_sup_filter, ← inf_sup_left, sup_principal, setOf_or] + simp only [blimsup_eq_limsup, ← limsup_sup_filter, ← inf_sup_left, sup_principal, ofPred_or] @[simp] theorem bliminf_or_eq_inf : (bliminf u f fun x => p x ∨ q x) = bliminf u f p ⊓ bliminf u f q := @@ -745,7 +745,7 @@ theorem cofinite.blimsup_set_eq : simp only [blimsup_eq, eventually_cofinite, not_forall, sInf_eq_sInter, exists_prop] ext x refine ⟨fun h => ?_, fun hx t h => ?_⟩ <;> contrapose h - · simp only [mem_sInter, mem_setOf_eq, not_forall, exists_prop] + · simp only [mem_sInter, mem_ofPred_eq, not_forall, exists_prop] exact ⟨{x}ᶜ, by simpa using h, by simp⟩ · exact hx.mono fun i hi => ⟨hi.1, fun hit => h (hit hi.2)⟩ @@ -1012,7 +1012,7 @@ theorem HasBasis.liminf_eq_ciSup_ciInf {v : Filter ι} · have : j = liminf_reparam f s p j := by simp only [m, liminf_reparam, hj, ite_true] conv_lhs => rw [this] apply subset_iUnion _ j - · simp only [m, mem_setOf_eq, ← nonempty_iInter_Iic_iff, not_nonempty_iff_eq_empty] at hj + · simp only [m, mem_ofPred_eq, ← nonempty_iInter_Iic_iff, not_nonempty_iff_eq_empty] at hj simp only [hj, empty_subset] · apply iUnion_subset (fun j ↦ ?_) exact subset_iUnion (fun (k : Subtype p) ↦ (⋂ (i : s k), Iic (f i))) (liminf_reparam f s p j) diff --git a/Mathlib/Order/Minimal.lean b/Mathlib/Order/Minimal.lean index 01cfc2ce2977f5..acbd00836172ff 100644 --- a/Mathlib/Order/Minimal.lean +++ b/Mathlib/Order/Minimal.lean @@ -189,26 +189,28 @@ theorem not_minimal_iff_exists_lt (hx : P x) : ¬ Minimal P x ↔ ∃ y, y < x alias ⟨exists_lt_of_not_minimal, _⟩ := not_minimal_iff_exists_lt @[to_dual] -theorem MinimalFor.of_strictMonoOn_comp (hg : StrictMonoOn g (f '' setOf Q)) +theorem MinimalFor.of_strictMonoOn_comp (hg : StrictMonoOn g (f '' Set.ofPred Q)) (h : MinimalFor Q (g ∘ f) i) : MinimalFor Q f i := by refine ⟨h.prop, fun j hj hle ↦ ?_⟩ by_contra exact h.not_lt hj <| hg ⟨j, hj, rfl⟩ ⟨i, h.prop, rfl⟩ <| lt_of_le_not_ge hle this @[to_dual] -theorem MinimalFor.minimal_of_strictMonoOn (hg : StrictMonoOn g (setOf P)) (h : MinimalFor P g x) : +theorem MinimalFor.minimal_of_strictMonoOn (hg : StrictMonoOn g (Set.ofPred P)) + (h : MinimalFor P g x) : Minimal P x := minimalFor_id.mp <| .of_strictMonoOn_comp (Set.image_id _ ▸ hg) h @[to_dual] -theorem MinimalFor.maximalFor_of_strictAntiOn_comp (hg : StrictAntiOn g (f '' setOf Q)) +theorem MinimalFor.maximalFor_of_strictAntiOn_comp (hg : StrictAntiOn g (f '' Set.ofPred Q)) (h : MinimalFor Q (g ∘ f) i) : MaximalFor Q f i := by refine ⟨h.prop, fun j hj hle ↦ ?_⟩ by_contra exact h.not_lt hj <| hg ⟨i, h.prop, rfl⟩ ⟨j, hj, rfl⟩ <| lt_of_le_not_ge hle this @[to_dual] -theorem MinimalFor.maximal_of_strictAntiOn (hg : StrictAntiOn g (setOf P)) (h : MinimalFor P g x) : +theorem MinimalFor.maximal_of_strictAntiOn (hg : StrictAntiOn g (Set.ofPred P)) + (h : MinimalFor P g x) : Maximal P x := maximalFor_id.mp <| MinimalFor.maximalFor_of_strictAntiOn_comp (Set.image_id _ ▸ hg) h @@ -392,9 +394,12 @@ section Preorder variable [Preorder α] @[to_dual] -theorem setOf_minimal_subset (s : Set α) : {x | Minimal (· ∈ s) x} ⊆ s := +theorem setOfPred_minimal_subset (s : Set α) : {x | Minimal (· ∈ s) x} ⊆ s := sep_subset .. +@[deprecated (since := "2026-07-09")] alias setOf_minimal_subset := setOfPred_minimal_subset +@[deprecated (since := "2026-07-09")] alias setOf_maximal_subset := setOfPred_maximal_subset + @[to_dual] theorem Set.Subsingleton.minimal_mem_iff (h : s.Subsingleton) : Minimal (· ∈ s) x ↔ x ∈ s := by obtain (rfl | ⟨x, rfl⟩) := h.eq_empty_or_singleton <;> simp @@ -453,28 +458,52 @@ theorem minimal_mem_image_antitone_iff (ha : a ∈ s) maximal_mem_image_monotone_iff (β := βᵒᵈ) ha (fun _ _ h h' ↦ hf h' h) @[to_dual (reorder := hf (x y, 3 4))] -theorem image_monotone_setOf_minimal (hf : ∀ ⦃x y⦄, P x → P y → (f x ≤ f y ↔ x ≤ y)) : +theorem image_monotone_setOfPred_minimal (hf : ∀ ⦃x y⦄, P x → P y → (f x ≤ f y ↔ x ≤ y)) : f '' {x | Minimal P x} = {x | Minimal (∃ x₀, P x₀ ∧ f x₀ = ·) x} := by refine Set.ext fun x ↦ ⟨?_, fun h ↦ ?_⟩ · rintro ⟨x, (hx : Minimal _ x), rfl⟩ exact (minimal_mem_image_monotone_iff hx.prop hf).2 hx - obtain ⟨y, hy, rfl⟩ := (mem_setOf_eq ▸ h).prop - exact mem_image_of_mem _ <| (minimal_mem_image_monotone_iff (s := setOf P) hy hf).1 h + obtain ⟨y, hy, rfl⟩ := (mem_ofPred_eq ▸ h).prop + exact mem_image_of_mem _ <| (minimal_mem_image_monotone_iff (s := Set.ofPred P) hy hf).1 h + +@[deprecated (since := "2026-07-09")] +alias image_monotone_setOf_minimal := image_monotone_setOfPred_minimal + +@[deprecated (since := "2026-07-09")] +alias image_monotone_setOf_maximal := image_monotone_setOfPred_maximal @[to_dual (reorder := hf (x y, 3 4))] -theorem image_antitone_setOf_minimal (hf : ∀ ⦃x y⦄, P x → P y → (f x ≤ f y ↔ y ≤ x)) : +theorem image_antitone_setOfPred_minimal (hf : ∀ ⦃x y⦄, P x → P y → (f x ≤ f y ↔ y ≤ x)) : f '' {x | Minimal P x} = {x | Maximal (∃ x₀, P x₀ ∧ f x₀ = ·) x} := - image_monotone_setOf_minimal (β := βᵒᵈ) (fun _ _ hx hy ↦ hf hy hx) + image_monotone_setOfPred_minimal (β := βᵒᵈ) (fun _ _ hx hy ↦ hf hy hx) + +@[deprecated (since := "2026-07-09")] +alias image_antitone_setOf_minimal := image_antitone_setOfPred_minimal + +@[deprecated (since := "2026-07-09")] +alias image_antitone_setOf_maximal := image_antitone_setOfPred_maximal @[to_dual (reorder := hf (x y, 3 4))] -theorem image_monotone_setOf_minimal_mem (hf : ∀ ⦃x y⦄, x ∈ s → y ∈ s → (f x ≤ f y ↔ x ≤ y)) : +theorem image_monotone_setOfPred_minimal_mem (hf : ∀ ⦃x y⦄, x ∈ s → y ∈ s → (f x ≤ f y ↔ x ≤ y)) : f '' {x | Minimal (· ∈ s) x} = {x | Minimal (· ∈ f '' s) x} := - image_monotone_setOf_minimal hf + image_monotone_setOfPred_minimal hf + +@[deprecated (since := "2026-07-09")] +alias image_monotone_setOf_minimal_mem := image_monotone_setOfPred_minimal_mem + +@[deprecated (since := "2026-07-09")] +alias image_monotone_setOf_maximal_mem := image_monotone_setOfPred_maximal_mem @[to_dual (reorder := hf (x y, 3 4))] -theorem image_antitone_setOf_minimal_mem (hf : ∀ ⦃x y⦄, x ∈ s → y ∈ s → (f x ≤ f y ↔ y ≤ x)) : +theorem image_antitone_setOfPred_minimal_mem (hf : ∀ ⦃x y⦄, x ∈ s → y ∈ s → (f x ≤ f y ↔ y ≤ x)) : f '' {x | Minimal (· ∈ s) x} = {x | Maximal (· ∈ f '' s) x} := - image_antitone_setOf_minimal hf + image_antitone_setOfPred_minimal hf + +@[deprecated (since := "2026-07-09")] +alias image_antitone_setOf_minimal_mem := image_antitone_setOfPred_minimal_mem + +@[deprecated (since := "2026-07-09")] +alias image_antitone_setOf_maximal_mem := image_antitone_setOfPred_maximal_mem end Function @@ -507,26 +536,40 @@ theorem minimal_apply_mem_iff (ht : t ⊆ Set.range f) : @[deprecated (since := "2026-04-07")] alias maximal_apply_iff := maximal_apply_mem_iff -theorem image_setOf_minimal : f '' {x | Minimal (· ∈ s) x} = {x | Minimal (· ∈ f '' s) x} := - _root_.image_monotone_setOf_minimal (by simp [f.le_iff_le]) +theorem image_setOfPred_minimal : f '' {x | Minimal (· ∈ s) x} = {x | Minimal (· ∈ f '' s) x} := + _root_.image_monotone_setOfPred_minimal (by simp [f.le_iff_le]) + +@[deprecated (since := "2026-07-09")] +alias image_setOf_minimal := image_setOfPred_minimal @[to_dual] -theorem inter_preimage_setOf_minimal_eq_of_subset (hts : t ⊆ f '' s) : +theorem inter_preimage_setOfPred_minimal_eq_of_subset (hts : t ⊆ f '' s) : x ∈ s ∩ f ⁻¹' {y | Minimal (· ∈ t) y} ↔ Minimal (· ∈ s ∩ f ⁻¹' t) x := by - simp_rw [mem_inter_iff, preimage_setOf_eq, mem_setOf_eq, mem_preimage, + simp_rw [mem_inter_iff, preimage_ofPred_eq, mem_ofPred_eq, mem_preimage, f.minimal_apply_mem_iff (hts.trans (image_subset_range _ _)), minimal_and_iff_left_of_imp (fun _ hx ↦ f.injective.mem_set_image.1 <| hts hx)] +@[deprecated (since := "2026-07-09")] +alias inter_preimage_setOf_minimal_eq_of_subset := inter_preimage_setOfPred_minimal_eq_of_subset + +@[deprecated (since := "2026-07-09")] +alias inter_preimage_setOf_maximal_eq_of_subset := inter_preimage_setOfPred_maximal_eq_of_subset + end OrderEmbedding namespace OrderIso @[to_dual] -theorem image_setOf_minimal (f : α ≃o β) (P : α → Prop) : +theorem image_setOfPred_minimal (f : α ≃o β) (P : α → Prop) : f '' {x | Minimal P x} = {x | Minimal (fun x ↦ P (f.symm x)) x} := by - convert! _root_.image_monotone_setOf_minimal (f := f) (by simp [f.le_iff_le]) + convert! _root_.image_monotone_setOfPred_minimal (f := f) (by simp [f.le_iff_le]) aesop +@[deprecated (since := "2026-07-09")] +alias image_setOf_minimal := image_setOfPred_minimal +@[deprecated (since := "2026-07-09")] +alias image_setOf_maximal := image_setOfPred_maximal + @[to_dual] theorem map_minimal_mem (f : s ≃o t) (hx : Minimal (· ∈ s) x) : Minimal (· ∈ t) (f ⟨x, hx.prop⟩) := by @@ -553,13 +596,18 @@ def mapSetOfMaximal (f : s ≃o t) : {x | Maximal (· ∈ s) x} ≃o {x | Maxima /-- If two sets are antitonically order isomorphic, their minimals/maximals are too. -/ @[to_dual /-- If two sets are antitonically order isomorphic, their maximals/minimals are too. -/] -def setOfMinimalIsoSetOfMaximal (f : s ≃o tᵒᵈ) : +def setOfPredMinimalIsoSetOfPredMaximal (f : s ≃o tᵒᵈ) : {x | Minimal (· ∈ s) x} ≃o {x | Maximal (· ∈ t) (ofDual x)} where toFun x := ⟨(f ⟨x.1, x.2.1⟩).1, ((show s ≃o ofDual ⁻¹' t from f).mapSetOfMinimal x).2⟩ invFun x := ⟨(f.symm ⟨x.1, x.2.1⟩).1, ((show ofDual ⁻¹' t ≃o s from f.symm).mapSetOfMinimal x).2⟩ __ := (show s ≃o ofDual ⁻¹' t from f).mapSetOfMinimal +@[deprecated (since := "2026-07-09")] +alias setOfMinimalIsoSetOfMaximal := setOfPredMinimalIsoSetOfPredMaximal +@[deprecated (since := "2026-07-09")] +alias setOfMaximalIsoSetOfMinimal := setOfPredMaximalIsoSetOfPredMinimal + end OrderIso end Image diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index f8d1f866cd8bf2..83026896b3da13 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -226,16 +226,16 @@ theorem ωSup_le_ωSup_of_le {c₀ c₁ : Chain α} (h : c₀ ≤ c₁) : ωSup lemma isLUB_range_ωSup (c : Chain α) : IsLUB (Set.range c) (ωSup c) := by constructor · simp only [upperBounds, Set.mem_range, forall_exists_index, forall_apply_eq_imp_iff, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] exact fun a ↦ le_ωSup c a · simp only [lowerBounds, upperBounds, Set.mem_range, forall_exists_index, - forall_apply_eq_imp_iff, Set.mem_setOf_eq] + forall_apply_eq_imp_iff, Set.mem_ofPred_eq] exact fun ⦃a⦄ a_1 ↦ ωSup_le c a a_1 lemma ωSup_eq_of_isLUB {c : Chain α} {a : α} (h : IsLUB (Set.range c) a) : a = ωSup c := by rw [le_antisymm_iff] simp only [IsLUB, IsLeast, upperBounds, lowerBounds, Set.mem_range, forall_exists_index, - forall_apply_eq_imp_iff, Set.mem_setOf_eq] at h + forall_apply_eq_imp_iff, Set.mem_ofPred_eq] at h constructor · apply h.2 exact fun a ↦ le_ωSup c a diff --git a/Mathlib/Order/OrderIsoNat.lean b/Mathlib/Order/OrderIsoNat.lean index 51c1dcdaa3349b..894c448ba1d659 100644 --- a/Mathlib/Order/OrderIsoNat.lean +++ b/Mathlib/Order/OrderIsoNat.lean @@ -168,7 +168,7 @@ theorem exists_increasing_or_nonincreasing_subseq' (r : α → α → Prop) (f : have h : ∀ n : ℕ, ∃ n' : ℕ, n < n' ∧ r (f (n + m)) (f (n' + m)) := by intro n have h := hm _ (Nat.le_add_left m n) - simp only [bad, exists_prop, not_not, Set.mem_setOf_eq, not_forall] at h + simp only [bad, exists_prop, not_not, Set.mem_ofPred_eq, not_forall] at h obtain ⟨n', hn1, hn2⟩ := h refine ⟨n + n' - n - m, by lia, ?_⟩ convert! hn2 diff --git a/Mathlib/Order/PrimeSeparator.lean b/Mathlib/Order/PrimeSeparator.lean index 60d5cbfd67f8c5..2e38299d36b946 100644 --- a/Mathlib/Order/PrimeSeparator.lean +++ b/Mathlib/Order/PrimeSeparator.lean @@ -53,7 +53,7 @@ theorem DistribLattice.prime_ideal_of_disjoint_filter_ideal [DistribLattice α] intro c hcS hcC hcNe use sUnion c refine ⟨?_, fun s hs ↦ le_sSup hs⟩ - simp only [mem_setOf_eq, disjoint_sUnion_right, S] + simp only [mem_ofPred_eq, disjoint_sUnion_right, S] let ⟨J, hJ⟩ := hcNe refine ⟨Order.isIdeal_sUnion_of_isChain (fun _ hJ ↦ (hcS hJ).1) hcC hcNe, ⟨le_trans (hcS hJ).2.1 (le_sSup hJ), fun J hJ ↦ (hcS hJ).2.2⟩⟩ @@ -88,12 +88,12 @@ theorem DistribLattice.prime_ideal_of_disjoint_filter_ideal [DistribLattice α] have J₁F : ¬ (Disjoint (F : Set α) J₁) := by intro hdis apply J₁S - simp only [mem_setOf_eq, SetLike.coe_subset_coe, S] + simp only [mem_ofPred_eq, SetLike.coe_subset_coe, S] exact ⟨J₁.isIdeal, le_trans IJ' le_sup_left, hdis⟩ have J₂F : ¬ (Disjoint (F : Set α) J₂) := by intro hdis apply J₂S - simp only [mem_setOf_eq, SetLike.coe_subset_coe, S] + simp only [mem_ofPred_eq, SetLike.coe_subset_coe, S] exact ⟨J₂.isIdeal, le_trans IJ' le_sup_left, hdis⟩ -- Thus, pick cᵢ ∈ F ∩ Jᵢ. let ⟨c₁, ⟨c₁F, c₁J₁⟩⟩ := Set.not_disjoint_iff.1 J₁F diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index a44944daa7eb47..3122343272d4e5 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -111,20 +111,20 @@ lemma ScottContinuousOn.prodMk {g : α → γ} (hD : ∀ a b : α, a ≤ b → { ScottContinuousOn D fun x => (f x, g x) := fun d hd₁ hd₂ hd₃ a hda => by rw [IsLUB, IsLeast, upperBounds] constructor - · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, + · simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_ofPred_eq, Prod.mk_le_mk] intro b hb exact ⟨hf.monotone D hD (hda.1 hb), hg.monotone D hD (hda.1 hb)⟩ · intro ⟨p₁, p₂⟩ hp - simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq, + simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_ofPred_eq, Prod.mk_le_mk] at hp constructor · rw [isLUB_le_iff (hf hd₁ hd₂ hd₃ hda), upperBounds] - simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq] + simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_ofPred_eq] intro _ hb exact (hp _ hb).1 · rw [isLUB_le_iff (hg hd₁ hd₂ hd₃ hda), upperBounds] - simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_setOf_eq] + simp only [mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mem_ofPred_eq] intro _ hb exact (hp _ hb).2 @@ -196,10 +196,10 @@ variable [SemilatticeSup β] @[fun_prop] lemma ScottContinuous.sup₂ : ScottContinuous fun b : β × β => (b.1 ⊔ b.2 : β) := fun d _ _ ⟨p₁, p₂⟩ hdp => by - simp only [IsLUB, IsLeast, upperBounds, Prod.forall, mem_setOf_eq, Prod.mk_le_mk] at hdp + simp only [IsLUB, IsLeast, upperBounds, Prod.forall, mem_ofPred_eq, Prod.mk_le_mk] at hdp simp only [IsLUB, IsLeast, upperBounds, mem_image, Prod.exists, forall_exists_index, and_imp] have e1 : (p₁, p₂) ∈ lowerBounds {x | ∀ (b₁ b₂ : β), (b₁, b₂) ∈ d → (b₁, b₂) ≤ x} := hdp.2 - simp only [lowerBounds, mem_setOf_eq, Prod.forall, Prod.mk_le_mk] at e1 + simp only [lowerBounds, mem_ofPred_eq, Prod.forall, Prod.mk_le_mk] at e1 refine ⟨fun a b₁ b₂ hbd hba => ?_,fun b hb => ?_⟩ · rw [← hba] exact sup_le_sup (hdp.1 _ _ hbd).1 (hdp.1 _ _ hbd).2 diff --git a/Mathlib/Order/ScottContinuity/Prod.lean b/Mathlib/Order/ScottContinuity/Prod.lean index 9cf6a2830551bc..cfc47d5b3e8886 100644 --- a/Mathlib/Order/ScottContinuity/Prod.lean +++ b/Mathlib/Order/ScottContinuity/Prod.lean @@ -44,7 +44,7 @@ lemma ScottContinuousOn.fromProd [Preorder α] [Preorder β] [Preorder γ] (DirectedOn.fst hd₂) (isLUB_prod.mp hdp).1) ext : 1 simp_all only [Subtype.exists, mem_image, Prod.exists, - exists_and_right, exists_eq_right, exists_prop, mem_setOf_eq] + exists_and_right, exists_eq_right, exists_prop, mem_ofPred_eq] lemma ScottContinuous.fromProd {γ : Type*} [Preorder α] [Preorder β] [Preorder γ] {f : α × β → γ} (h₁ : ∀ a, ScottContinuous (fun b => f (a, b))) diff --git a/Mathlib/Order/SemiconjSup.lean b/Mathlib/Order/SemiconjSup.lean index e7ab5076672a2b..d74120564ef8f1 100644 --- a/Mathlib/Order/SemiconjSup.lean +++ b/Mathlib/Order/SemiconjSup.lean @@ -88,7 +88,7 @@ theorem Semiconj.symm_adjoint [PartialOrder α] [Preorder β] {fa : α ≃o α} (h : Function.Semiconj g fa fb) {g' : β → α} (hg' : IsOrderRightAdjoint g g') : Function.Semiconj g' fb fa := by refine fun y => (hg' _).unique ?_ - rw [← fa.surjective.image_preimage { x | g x ≤ fb y }, preimage_setOf_eq] + rw [← fa.surjective.image_preimage { x | g x ≤ fb y }, preimage_ofPred_eq] simp only [h.eq, fb.le_iff_le, fa.isLUB_image'.mpr (hg' _)] variable {G : Type*} diff --git a/Mathlib/Order/SuccPred/Tree.lean b/Mathlib/Order/SuccPred/Tree.lean index cd27b5de99afba..ba4b7fd2e5e80a 100644 --- a/Mathlib/Order/SuccPred/Tree.lean +++ b/Mathlib/Order/SuccPred/Tree.lean @@ -179,7 +179,7 @@ variable {t : RootedTree} lemma SubRootedTree.root_ne_bot_of_mem_subtrees (r : SubRootedTree t) (hr : r ∈ t.subtrees) : r.root ≠ ⊥ := by - simp only [RootedTree.subtrees, Set.mem_setOf_eq] at hr + simp only [RootedTree.subtrees, Set.mem_ofPred_eq] at hr exact hr.1 lemma RootedTree.mem_subtrees_disjoint_iff {t₁ t₂ : SubRootedTree t} diff --git a/Mathlib/Order/UpperLower/Basic.lean b/Mathlib/Order/UpperLower/Basic.lean index 48c4788f45302f..73b7dc2c13f4c8 100644 --- a/Mathlib/Order/UpperLower/Basic.lean +++ b/Mathlib/Order/UpperLower/Basic.lean @@ -170,13 +170,17 @@ theorem Set.antitone_mem : Antitone (· ∈ s) ↔ IsLowerSet s := forall_comm @[simp] -theorem isUpperSet_setOf : IsUpperSet { a | p a } ↔ Monotone p := +theorem isUpperSet_setOfPred : IsUpperSet { a | p a } ↔ Monotone p := Iff.rfl +@[deprecated (since := "2026-07-09")] alias isUpperSet_setOf := isUpperSet_setOfPred + @[simp] -theorem isLowerSet_setOf : IsLowerSet { a | p a } ↔ Antitone p := +theorem isLowerSet_setOfPred : IsLowerSet { a | p a } ↔ Antitone p := forall_comm +@[deprecated (since := "2026-07-09")] alias isLowerSet_setOf := isLowerSet_setOfPred + @[to_dual] lemma IsUpperSet.upperBounds_subset (hs : IsUpperSet s) : s.Nonempty → upperBounds s ⊆ s := fun ⟨_a, ha⟩ _b hb ↦ hs (hb ha) ha diff --git a/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean b/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean index 29ff54fdfee892..a8a46c3a353cf0 100644 --- a/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean +++ b/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean @@ -56,7 +56,7 @@ lemma binomialRandom_eq_map : G(V, p) = map fromEdgeSet setBer(Sym2.diagSetᶜ, refine (map_eq_comap measurable_fromEdgeSet measurableEmbedding_edgeSet ?_ fromEdgeSet_edgeSet).symm filter_upwards [setBernoulli_ae_subset] with S hS - exact ⟨fromEdgeSet S, by simpa [← Set.compl_setOf, Set.subset_compl_iff_disjoint_right] using hS⟩ + exact ⟨fromEdgeSet S, by simpa [← Set.compl_ofPred, Set.subset_compl_iff_disjoint_right] using hS⟩ variable (p) in lemma binomialRandom_apply' (S : Set (SimpleGraph V)) : @@ -74,7 +74,7 @@ instance : IsProbabilityMeasure G(V, p) := by refine measurableEmbedding_edgeSet.isProbabilityMeasure_comap ?_ filter_upwards [setBernoulli_ae_subset] with s hs refine ⟨.fromEdgeSet s, ?_⟩ - simpa [← Set.disjoint_compl_right_iff_subset, ← Set.compl_setOf] using hs + simpa [← Set.disjoint_compl_right_iff_subset, ← Set.compl_ofPred] using hs variable (V) in @[simp] lemma binomialRandom_zero : G(V, 0) = dirac ⊥ := by simp [binomialRandom_eq_map] diff --git a/Mathlib/Probability/Distributions/Fernique.lean b/Mathlib/Probability/Distributions/Fernique.lean index 4e842b77879f78..4997be47256213 100644 --- a/Mathlib/Probability/Distributions/Fernique.lean +++ b/Mathlib/Probability/Distributions/Fernique.lean @@ -134,7 +134,7 @@ lemma measure_le_mul_measure_gt_le_of_map_rotation_eq_self [SFinite μ] · change MeasurableSet {p : E × E | b < ‖p.2‖} exact measurableSet_lt (by fun_prop) (by fun_prop) congr 1 - simp only [Set.preimage_setOf_eq, ContinuousLinearMap.rotation_apply, Real.cos_neg, + simp only [Set.preimage_ofPred_eq, ContinuousLinearMap.rotation_apply, Real.cos_neg, Real.cos_pi_div_four, Real.sin_neg, Real.sin_pi_div_four, neg_smul, neg_neg] have h_twos : ‖2⁻¹ * √2‖ = (√2)⁻¹ := by simp only [norm_mul, norm_inv, Real.norm_ofNat, Real.norm_eq_abs] @@ -147,7 +147,7 @@ lemma measure_le_mul_measure_gt_le_of_map_rotation_eq_self [SFinite μ] _ ≤ (μ.prod μ) {p | (b - a) / √2 < ‖p.1‖ ∧ (b - a) / √2 < ‖p.2‖} := by -- The rotated bands are contained in quadrants. refine measure_mono fun p ↦ ?_ - simp only [Set.mem_setOf_eq, and_imp] + simp only [Set.mem_ofPred_eq, and_imp] intro hp1 hp2 suffices (b - a) / √2 < min ‖p.1‖ ‖p.2‖ from lt_min_iff.mp this calc (b - a) / √2 @@ -495,7 +495,7 @@ theorem lintegral_exp_mul_sq_norm_le_of_map_rotation_eq_self [IsProbabilityMeasu by_contra! h_neg have : {x : E | ‖x‖ ≤ a} = ∅ := by ext x - simp only [Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false, not_le] + simp only [Set.mem_ofPred_eq, Set.mem_empty_iff_false, iff_false, not_le] exact h_neg.trans_le (norm_nonneg _) simp only [this, measure_empty, nonpos_iff_eq_zero] at hc simp [hc] at hc_gt @@ -573,12 +573,12 @@ lemma exists_integrable_exp_sq_of_map_rotation_eq_self_of_isProbabilityMeasure · exact h_of_pos a ha have h_univ : (Set.univ : Set E) = ⋃ a : ℕ, {x | ‖x‖ ≤ a} := by ext x - simp only [Set.mem_univ, Set.mem_iUnion, Set.mem_setOf_eq, true_iff] + simp only [Set.mem_univ, Set.mem_iUnion, Set.mem_ofPred_eq, true_iff] exact exists_nat_ge _ rw [h_univ, Monotone.measure_iUnion] · simp [h_le] · intro a b hab x hx - simp only [Set.mem_setOf_eq] at hx ⊢ + simp only [Set.mem_ofPred_eq] at hx ⊢ exact hx.trans (mod_cast hab) -- So we can take `C = 1` and show that `x ↦ exp (‖x‖ ^ 2)` is integrable, since it is bounded. have hb' : ∀ᵐ x ∂μ, ‖x‖ ≤ b := by diff --git a/Mathlib/Probability/Distributions/SetBernoulli.lean b/Mathlib/Probability/Distributions/SetBernoulli.lean index cf776ae4cb3b12..fef0a807ab982f 100644 --- a/Mathlib/Probability/Distributions/SetBernoulli.lean +++ b/Mathlib/Probability/Distributions/SetBernoulli.lean @@ -48,22 +48,22 @@ noncomputable def setBernoulli : Measure (Set ι) := @[inherit_doc] scoped notation "setBer(" u ", " p ")" => setBernoulli u p instance : IsProbabilityMeasure setBer(u, p) := - MeasurableEquiv.setOf.symm.measurableEmbedding.isProbabilityMeasure_comap <| .of_forall fun P ↦ - ⟨{i | P i}, rfl⟩ + MeasurableEquiv.setOfPred.symm.measurableEmbedding.isProbabilityMeasure_comap <| + .of_forall fun P ↦ ⟨{i | P i}, rfl⟩ variable (u p) in lemma setBernoulli_eq_map : setBer(u, p) = .map (fun p : ι → Prop ↦ {i | p i}) (infinitePi fun i : ι ↦ toNNReal p • dirac (i ∈ u) + toNNReal (σ p) • dirac False) := - MeasurableEquiv.setOf.comap_symm + MeasurableEquiv.setOfPred.comap_symm lemma setBernoulli_apply (S : Set (Set ι)) : setBer(u, p) S = (infinitePi fun i ↦ toNNReal p • dirac (i ∈ u) + toNNReal (σ p) • dirac False) - ((fun t i ↦ i ∈ t) '' S) := MeasurableEquiv.setOf.symm.measurableEmbedding.comap_apply .. + ((fun t i ↦ i ∈ t) '' S) := MeasurableEquiv.setOfPred.symm.measurableEmbedding.comap_apply .. lemma setBernoulli_apply' (S : Set (Set ι)) : setBer(u, p) S = (infinitePi fun i ↦ toNNReal p • dirac (i ∈ u) + toNNReal (σ p) • dirac False) - ((fun p ↦ {i | p i}) ⁻¹' S) := MeasurableEquiv.setOf.symm.comap_apply .. + ((fun p ↦ {i | p i}) ⁻¹' S) := MeasurableEquiv.setOfPred.symm.comap_apply .. variable (u) in @[simp] lemma setBernoulli_zero : setBer(u, 0) = dirac ∅ := by simp [setBernoulli_eq_map] @@ -75,8 +75,8 @@ section Countable variable [Countable ι] lemma setBernoulli_ae_subset : ∀ᵐ s ∂setBer(u, p), s ⊆ u := by - simp only [Filter.Eventually, mem_ae_iff, Set.compl_setOf, Set.not_subset_iff_exists_mem_notMem, - Set.setOf_exists, Set.setOf_and, measure_iUnion_null_iff] + simp only [Filter.Eventually, mem_ae_iff, Set.compl_ofPred, Set.not_subset_iff_exists_mem_notMem, + Set.ofPred_exists, Set.ofPred_and, measure_iUnion_null_iff] rintro i by_cases hi : i ∈ u · simp [*] @@ -118,8 +118,8 @@ variable (p) in rw [tprod_eq_prod, Finset.prod_congr rfl] <;> simp +contextual [ite_add_ite, mt (@hsu _), ← ENNReal.coe_add] _ = toNNReal p ^ s.ncard * toNNReal (σ p) ^ (↑u \ s).ncard := by - simp [Finset.prod_ite, ← Set.ncard_coe_finset, Set.setOf_and, - Set.inter_eq_right.2 hsu, ← Set.compl_setOf, Set.sdiff_eq_compl_inter, Set.inter_comm] + simp [Finset.prod_ite, ← Set.ncard_coe_finset, Set.ofPred_and, + Set.inter_eq_right.2 hsu, ← Set.compl_ofPred, Set.sdiff_eq_compl_inter, Set.inter_comm] @[simp] lemma setBernoulli_real_singleton (p : I) (hsu : s ⊆ u) (hu : u.Finite) : @@ -131,12 +131,12 @@ lemma map_ncard_setBernoulli_real_singleton {u : Set ι} (hu : u.Finite) (p : I) (u.ncard.choose k) * p ^ k * (1 - p) ^ (u.ncard - k) := by have : {s ⊆ u | s.ncard ∈ ({k} : Set ℕ)}.Finite := hu.finite_subsets.subset (by grind) rw [measureReal_def, map_ncard_setBernoulli_apply, ← measureReal_def, - ← Set.biUnion_of_singleton (setOf _)] + ← Set.biUnion_of_singleton (Set.ofPred _)] simp_rw [← this.mem_toFinset] rw [measureReal_biUnion_finset (by simp) (by simp)] have h1 s (hs : s ∈ this.toFinset) : setBer(u, p).real {s} = p ^ k * (1 - p) ^ (u.ncard - k) := by - simp only [Set.mem_singleton_iff, Set.Finite.mem_toFinset, Set.mem_setOf_eq] at hs + simp only [Set.mem_singleton_iff, Set.Finite.mem_toFinset, Set.mem_ofPred_eq] at hs rw [setBernoulli_real_singleton _ hs.1 hu, Set.ncard_sdiff' hs.1 hu, hs.2] rw [Finset.sum_congr rfl h1, Finset.sum_const, nsmul_eq_mul, mul_assoc, ← Set.ncard_eq_toFinset_card _ _] diff --git a/Mathlib/Probability/HasLaw.lean b/Mathlib/Probability/HasLaw.lean index 73c46d781c40af..abc9e450f070bf 100644 --- a/Mathlib/Probability/HasLaw.lean +++ b/Mathlib/Probability/HasLaw.lean @@ -88,7 +88,7 @@ protected lemma HasLaw.id : HasLaw id μ μ where protected lemma HasLaw.ae_iff (hX : HasLaw X μ P) {p : 𝓧 → Prop} (hp : Measurable p) : (∀ᵐ ω ∂P, p (X ω)) ↔ ∀ᵐ x ∂μ, p x := by - rw [← hX.map_eq, ae_map_iff hX.aemeasurable (measurableSet_setOf.2 hp)] + rw [← hX.map_eq, ae_map_iff hX.aemeasurable (measurableSet_setOfPred.2 hp)] protected theorem HasLaw.isFiniteMeasure_iff (hX : HasLaw X μ P) : IsFiniteMeasure P ↔ IsFiniteMeasure μ := by diff --git a/Mathlib/Probability/IdentDistrib.lean b/Mathlib/Probability/IdentDistrib.lean index 3a290b509a42ae..2bfc13bbd8f5ff 100644 --- a/Mathlib/Probability/IdentDistrib.lean +++ b/Mathlib/Probability/IdentDistrib.lean @@ -320,7 +320,7 @@ theorem MemLp.uniformIntegrable_of_identDistrib_aux {ι : Type*} {f : ι → α have : ∀ k, (fun x ↦ Set.indicator {x | C ≤ ‖f k x‖} (fun a ↦ ‖f k a‖) x) = F ∘ f k := by intro k ext x - simp only [Set.indicator, Set.mem_setOf_eq]; norm_cast + simp only [Set.indicator, Set.mem_ofPred_eq]; norm_cast rw [this, this, ← eLpNorm_map_measure F_meas.aestronglyMeasurable (hf i).aemeasurable_fst, (hf i).map_eq, eLpNorm_map_measure F_meas.aestronglyMeasurable (hf j).aemeasurable_fst] diff --git a/Mathlib/Probability/Independence/Integrable.lean b/Mathlib/Probability/Independence/Integrable.lean index c1a4dbb8a9a6fa..c358de8d7f83ab 100644 --- a/Mathlib/Probability/Independence/Integrable.lean +++ b/Mathlib/Probability/Independence/Integrable.lean @@ -44,7 +44,7 @@ lemma MemLp.isProbabilityMeasure_of_indepFun have h'c : μ {ω | c ≤ ‖f ω‖₊} < ∞ := hℒp.meas_ge_lt_top hp hp' c_pos.ne' have := hindep.measure_inter_preimage_eq_mul {x | c ≤ ‖x‖₊} Set.univ (isClosed_le continuous_const continuous_nnnorm).measurableSet MeasurableSet.univ - simp only [Set.preimage_setOf_eq, Set.preimage_univ, Set.inter_univ] at this + simp only [Set.preimage_ofPred_eq, Set.preimage_univ, Set.inter_univ] at this exact ⟨(ENNReal.mul_eq_left hc.ne' h'c.ne).1 this.symm⟩ diff --git a/Mathlib/Probability/Independence/Kernel/Indep.lean b/Mathlib/Probability/Independence/Kernel/Indep.lean index 53e4a8b6990b76..b80f009deda3c9 100644 --- a/Mathlib/Probability/Independence/Kernel/Indep.lean +++ b/Mathlib/Probability/Independence/Kernel/Indep.lean @@ -279,7 +279,7 @@ theorem indep_bot_right (m' : MeasurableSpace Ω) {_mΩ : MeasurableSpace Ω} {κ : Kernel α Ω} {μ : Measure α} [IsZeroOrMarkovKernel κ] : Indep m' ⊥ κ μ := by intro s t _ ht - rw [Set.mem_setOf_eq, MeasurableSpace.measurableSet_bot_iff] at ht + rw [Set.mem_ofPred_eq, MeasurableSpace.measurableSet_bot_iff] at ht rcases eq_zero_or_isMarkovKernel κ with rfl | h · simp refine Filter.Eventually.of_forall (fun a ↦ ?_) @@ -647,7 +647,7 @@ theorem iIndepSet.indep_generateFrom_lt [Preorder ι] {s : ι → Set Ω} convert! iIndepSet.indep_generateFrom_of_disjoint hsm hs { i } {j | j < i} (Set.disjoint_singleton_left.mpr (lt_irrefl _)) using 1 - simp only [Set.mem_singleton_iff, exists_eq_left, Set.setOf_eq_eq_singleton'] + simp only [Set.mem_singleton_iff, exists_eq_left, Set.ofPred_eq_eq_singleton'] theorem iIndepSet.indep_generateFrom_le [Preorder ι] {s : ι → Set Ω} (hsm : ∀ n, MeasurableSet (s n)) (hs : iIndepSet s κ μ) (i : ι) {k : ι} (hk : i < k) : @@ -655,7 +655,7 @@ theorem iIndepSet.indep_generateFrom_le [Preorder ι] {s : ι → Set Ω} convert! iIndepSet.indep_generateFrom_of_disjoint hsm hs { k } {j | j ≤ i} (Set.disjoint_singleton_left.mpr hk.not_ge) using 1 - simp only [Set.mem_singleton_iff, exists_eq_left, Set.setOf_eq_eq_singleton'] + simp only [Set.mem_singleton_iff, exists_eq_left, Set.ofPred_eq_eq_singleton'] theorem iIndepSet.indep_generateFrom_le_nat {s : ℕ → Set Ω} (hsm : ∀ n, MeasurableSet (s n)) (hs : iIndepSet s κ μ) (n : ℕ) : diff --git a/Mathlib/Probability/Independence/Kernel/IndepFun.lean b/Mathlib/Probability/Independence/Kernel/IndepFun.lean index e48ccde3f8f8cc..d8fe6035c66539 100644 --- a/Mathlib/Probability/Independence/Kernel/IndepFun.lean +++ b/Mathlib/Probability/Independence/Kernel/IndepFun.lean @@ -356,7 +356,7 @@ theorem iIndepFun.indepFun_finset (S T : Finset ι) (hST : Disjoint S T) (Measurable.comap_le (measurable_pi_iff.mpr fun i => hf_meas i)) hπS_pi hπT_pi hπS_gen hπT_gen ?_ rintro _ _ ⟨s, ⟨sets_s, hs1, hs2⟩, rfl⟩ ⟨t, ⟨sets_t, ht1, ht2⟩, rfl⟩ - simp only [Set.mem_univ_pi, Set.mem_setOf_eq] at hs1 ht1 + simp only [Set.mem_univ_pi, Set.mem_ofPred_eq] at hs1 ht1 rw [← hs2, ← ht2] classical let sets_s' : ∀ i : ι, Set (β i) := fun i => diff --git a/Mathlib/Probability/Independence/Process/Basic.lean b/Mathlib/Probability/Independence/Process/Basic.lean index 8f314f4984f065..9cb717c758512d 100644 --- a/Mathlib/Probability/Independence/Process/Basic.lean +++ b/Mathlib/Probability/Independence/Process/Basic.lean @@ -106,7 +106,7 @@ lemma IndepFun.process_indepFun {𝓧 : S → Type*} {𝓨 : Type*} πX_pi (@isPiSystem_measurableSet Ω (.comap Y inferInstance)) πX_gen (@generateFrom_measurableSet Ω (.comap Y inferInstance)).symm ?_ rintro - - ⟨-, ⟨I, s, hs, rfl⟩, rfl⟩ ⟨t, ht, rfl⟩ - simp only [Set.mem_pi, Set.mem_univ, Set.mem_setOf_eq, forall_const] at hs + simp only [Set.mem_pi, Set.mem_univ, Set.mem_ofPred_eq, forall_const] at hs have : (fun ω i ↦ X i ω) ⁻¹' .pi I s = (fun ω (i : I) ↦ X i ω) ⁻¹' .pi (SetLike.coe Finset.univ) (fun i ↦ s i) := by @@ -255,7 +255,7 @@ lemma iIndepFun.iIndepFun_process {T : S → Type*} {𝓧 : (i : S) → (j : T i rfl refine iIndepSets.iIndep _ (fun i ↦ (measurable_pi_iff.2 (hX i)).comap_le) π π_pi π_gen fun I s hs ↦ ?_ - simp only [squareCylinders, Set.mem_pi, Set.mem_univ, Set.mem_setOf_eq, forall_const, + simp only [squareCylinders, Set.mem_pi, Set.mem_univ, Set.mem_ofPred_eq, forall_const, ↓existsAndEq, and_true, π] at hs choose! J t ht hs using hs simp_rw [Set.iInter₂_congr (fun i hi ↦ (hs i hi).symm), diff --git a/Mathlib/Probability/Kernel/Composition/CompProd.lean b/Mathlib/Probability/Kernel/Composition/CompProd.lean index 7656ba92569585..9293ee015cf981 100644 --- a/Mathlib/Probability/Kernel/Composition/CompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/CompProd.lean @@ -207,12 +207,12 @@ lemma compProd_deterministic_apply [MeasurableSingletonClass γ] {f : α × β · suffices ∀ b ∈ tᶜ, (if f (x, b) ∈ Prod.mk b ⁻¹' s then (1 : ℝ≥0∞) else 0) = 0 by rw [setLIntegral_congr_fun ht.compl this, lintegral_zero] intro b hb - simp only [t, Set.mem_compl_iff, Set.mem_setOf_eq] at hb + simp only [t, Set.mem_compl_iff, Set.mem_ofPred_eq] at hb simp [hb] · suffices ∀ b ∈ t, (if f (x, b) ∈ Prod.mk b ⁻¹' s then (1 : ℝ≥0∞) else 0) = 1 by rw [setLIntegral_congr_fun ht this, setLIntegral_one] intro b hb - simp only [t, Set.mem_setOf_eq] at hb + simp only [t, Set.mem_ofPred_eq] at hb simp [hb] section Ae @@ -288,8 +288,8 @@ theorem compProd_restrict {s : Set β} {t : Set γ} (hs : MeasurableSet s) (ht : classical rw [Set.indicator_apply] split_ifs with h - · simp only [h, true_and, Set.inter_def, Set.mem_setOf] - · simp only [h, false_and, and_false, Set.setOf_false, measure_empty] + · simp only [h, true_and, Set.inter_def, Set.mem_ofPred] + · simp only [h, false_and, and_false, Set.ofPred_false, measure_empty] simp_rw [this] rw [lintegral_indicator hs] @@ -562,7 +562,7 @@ lemma fst_compProd_apply (κ : Kernel α β) (η : Kernel (α × β) γ) swap; · exact measurable_fst hs have h_eq b : η (x, b) {c | b ∈ s} = s.indicator (fun b ↦ η (x, b) Set.univ) b := by by_cases hb : b ∈ s <;> simp [hb] - simp_rw [Set.preimage, Set.mem_setOf_eq, h_eq] + simp_rw [Set.preimage, Set.mem_ofPred_eq, h_eq] @[simp] lemma fst_compProd (κ : Kernel α β) (η : Kernel (α × β) γ) [IsSFiniteKernel κ] [IsMarkovKernel η] : diff --git a/Mathlib/Probability/Kernel/Composition/MapComap.lean b/Mathlib/Probability/Kernel/Composition/MapComap.lean index 7606bd9421d80c..1546ebcdf9a804 100644 --- a/Mathlib/Probability/Kernel/Composition/MapComap.lean +++ b/Mathlib/Probability/Kernel/Composition/MapComap.lean @@ -454,7 +454,7 @@ lemma fst_map_prod (κ : Kernel α β) {f : β → γ} {g : β → δ} (hg : Mea by_cases hf : Measurable f · ext x s hs rw [fst_apply' _ _ hs, map_apply' _ (hf.prod hg) _, map_apply' _ hf _ hs] - · simp only [Set.preimage, Set.mem_setOf] + · simp only [Set.preimage, Set.mem_ofPred] · exact measurable_fst hs · have : ¬ Measurable (fun x ↦ (f x, g x)) := by contrapose hf; exact hf.fst @@ -516,7 +516,7 @@ lemma snd_map_prod (κ : Kernel α β) {f : β → γ} {g : β → δ} (hf : Mea by_cases hg : Measurable g · ext x s hs rw [snd_apply' _ _ hs, map_apply' _ (hf.prod hg), map_apply' _ hg _ hs] - · simp only [Set.preimage, Set.mem_setOf] + · simp only [Set.preimage, Set.mem_ofPred] · exact measurable_snd hs · have : ¬ Measurable (fun x ↦ (f x, g x)) := by contrapose hg; exact hg.snd diff --git a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean index 0647d82cd7fad6..68403b544d1a92 100644 --- a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean @@ -555,7 +555,7 @@ lemma lintegral_toKernel_mem [IsFiniteKernel κ] (hf : IsCondKernelCDF f κ ν) simp only [preimage_empty, measure_empty, lintegral_const, zero_mul] | basic s hs => rcases hs with ⟨t₁, ht₁, t₂, ht₂, rfl⟩ - simp only [mem_setOf_eq] at ht₁ ht₂ + simp only [mem_ofPred_eq] at ht₁ ht₂ rw [← lintegral_add_compl _ ht₁] have h_eq1 : ∫⁻ x in t₁, hf.toKernel f (a, x) (Prod.mk x ⁻¹' t₁ ×ˢ t₂) ∂(ν a) = ∫⁻ x in t₁, hf.toKernel f (a, x) t₂ ∂(ν a) := by diff --git a/Mathlib/Probability/Kernel/Disintegration/Density.lean b/Mathlib/Probability/Kernel/Disintegration/Density.lean index 5c95391a27fe67..5a10666b89def7 100644 --- a/Mathlib/Probability/Kernel/Disintegration/Density.lean +++ b/Mathlib/Probability/Kernel/Disintegration/Density.lean @@ -175,7 +175,7 @@ lemma meas_countablePartitionSet_le_of_fst_le (hκν : fst κ ≤ ν) (n : ℕ) ≤ fst κ a (countablePartitionSet n x) := by rw [fst_apply' _ _ (measurableSet_countablePartitionSet _ _)] refine measure_mono (fun x ↦ ?_) - simp only [mem_prod, mem_setOf_eq, and_imp] + simp only [mem_prod, mem_ofPred_eq, and_imp] exact fun h _ ↦ h _ ≤ ν a (countablePartitionSet n x) := hκν a _ @@ -219,7 +219,7 @@ lemma setIntegral_densityProcess_of_mem (hκν : fst κ ≤ ν) [hν : IsFiniteK have h0' : fst κ a (countablePartitionSet n x) = 0 := by simpa using (hκν a _).trans h0.le rw [fst_apply' _ _ (measurableSet_countablePartitionSet _ _)] at h0' refine measure_mono_null (fun x ↦ ?_) h0' - simp only [mem_prod, mem_setOf_eq, and_imp] + simp only [mem_prod, mem_ofPred_eq, and_imp] exact fun h _ ↦ h · finiteness congr @@ -235,7 +235,7 @@ lemma setIntegral_densityProcess_of_mem (hκν : fst κ ≤ ν) [hν : IsFiniteK rw [fst_apply' _ _ hu_meas] at h0' refine (measure_mono_null ?_ h0').symm intro p - simp only [mem_prod, mem_setOf_eq, and_imp] + simp only [mem_prod, mem_ofPred_eq, and_imp] exact fun h _ ↦ h rw [div_eq_mul_inv, mul_assoc, ENNReal.inv_mul_cancel h0, mul_one] exact measure_ne_top _ _ @@ -401,7 +401,7 @@ lemma tendsto_eLpNorm_one_densityProcess_limitProcess (hκν : fst κ ≤ ν) [I · refine fun ε _ ↦ ⟨2, fun n ↦ le_of_eq_of_le ?_ (?_ : 0 ≤ ENNReal.ofReal ε)⟩ · suffices {x | 2 ≤ ‖densityProcess κ ν n a x s‖₊} = ∅ by simp [this] ext x - simp only [mem_setOf_eq, mem_empty_iff_false, iff_false, not_le] + simp only [mem_ofPred_eq, mem_empty_iff_false, iff_false, not_le] refine (?_ : _ ≤ (1 : ℝ≥0)).trans_lt one_lt_two rw [Real.nnnorm_of_nonneg (densityProcess_nonneg _ _ _ _ _ _)] exact mod_cast (densityProcess_le_one hκν _ _ _ _) @@ -536,10 +536,10 @@ lemma setIntegral_density (hκν : fst κ ≤ ν) [IsFiniteKernel ν] have : IsFiniteKernel κ := isFiniteKernel_of_isFiniteKernel_fst (h := isFiniteKernel_of_le hκν) have hgen : ‹MeasurableSpace γ› = .generateFrom {s | ∃ n, MeasurableSet[countableFiltration γ n] s} := by - rw [setOf_exists, generateFrom_iUnion_measurableSet (countableFiltration γ), + rw [ofPred_exists, generateFrom_iUnion_measurableSet (countableFiltration γ), iSup_countableFiltration] have hpi : IsPiSystem {s | ∃ n, MeasurableSet[countableFiltration γ n] s} := by - rw [setOf_exists] + rw [ofPred_exists] exact isPiSystem_iUnion_of_monotone _ (fun n ↦ @isPiSystem_measurableSet _ (countableFiltration γ n)) fun _ _ ↦ (countableFiltration γ).mono @@ -660,14 +660,14 @@ lemma densityProcess_fst_univ_ae (κ : Kernel α (γ × β)) [IsFiniteKernel κ] have : {x | ¬ densityProcess κ (fst κ) n a x univ = 1} ⊆ {x | fst κ a (countablePartitionSet n x) = 0} := by intro x hx - simp only [mem_setOf_eq] at hx ⊢ + simp only [mem_ofPred_eq] at hx ⊢ rw [densityProcess_fst_univ] at hx simpa using hx refine measure_mono_null this ?_ have : {x | fst κ a (countablePartitionSet n x) = 0} ⊆ ⋃ (u) (_ : u ∈ countablePartition γ n) (_ : fst κ a u = 0), u := by intro t ht - simp only [mem_setOf_eq, mem_iUnion, exists_prop] at ht ⊢ + simp only [mem_ofPred_eq, mem_iUnion, exists_prop] at ht ⊢ exact ⟨countablePartitionSet n t, countablePartitionSet_mem _ _, ht, mem_countablePartitionSet _ _⟩ refine measure_mono_null this ?_ @@ -693,10 +693,10 @@ lemma tendsto_densityProcess_fst_atTop_univ_of_monotone (κ : Kernel α (γ × simp_rw [fst_apply' _ _ (measurableSet_countablePartitionSet _ _)] constructor · refine fun h h0 ↦ h (measure_mono_null (fun x ↦ ?_) h0) - simp only [mem_prod, mem_setOf_eq, and_imp] + simp only [mem_prod, mem_ofPred_eq, and_imp] exact fun h _ ↦ h · refine fun h_top ↦ eq_top_mono (measure_mono (fun x ↦ ?_)) h_top - simp only [mem_prod, mem_setOf_eq, and_imp] + simp only [mem_prod, mem_ofPred_eq, and_imp] exact fun h _ ↦ h by_cases h0 : fst κ a (countablePartitionSet n x) = 0 · rw [fst_apply' _ _ (measurableSet_countablePartitionSet _ _)] at h0 ⊢ @@ -706,9 +706,9 @@ lemma tendsto_densityProcess_fst_atTop_univ_of_monotone (κ : Kernel α (γ × simp only [this, ENNReal.zero_div] convert! h0 ext x - simp only [mem_prod, mem_univ, and_true, mem_setOf_eq] + simp only [mem_prod, mem_univ, and_true, mem_ofPred_eq] refine fun m ↦ measure_mono_null (fun x ↦ ?_) h0 - simp only [mem_prod, mem_setOf_eq, and_imp] + simp only [mem_prod, mem_ofPred_eq, and_imp] exact fun h _ ↦ h refine ENNReal.Tendsto.div_const ?_ ?_ · convert! tendsto_measure_iUnion_atTop (monotone_const.set_prod hseq) @@ -739,7 +739,7 @@ lemma tendsto_density_fst_atTop_ae_of_monotone [IsFiniteKernel κ] convert! tendsto_integral_density_of_monotone (κ := κ) le_rfl a seq hseq hseq_iUnion hseq_meas simp only [measureReal_def] rw [fst_apply' _ _ MeasurableSet.univ] - simp only [mem_univ, setOf_true] + simp only [mem_univ, ofPred_true] · exact ae_of_all _ (fun c n m hnm ↦ density_mono_set le_rfl a c (hseq hnm)) · exact ae_of_all _ (fun x m ↦ density_le_one le_rfl a x (seq m)) diff --git a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean index ddc1b92a3a98a3..946cd932ec5be9 100644 --- a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean +++ b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean @@ -88,7 +88,7 @@ lemma measurableSet_isRatStieltjesPoint [MeasurableSpace α] (hf : Measurable f) MeasurableSet {a | IsRatStieltjesPoint f a} := by have h1 : MeasurableSet {a | Monotone (f a)} := by change MeasurableSet {a | ∀ q r (_ : q ≤ r), f a q ≤ f a r} - simp_rw [Set.setOf_forall] + simp_rw [Set.ofPred_forall] refine MeasurableSet.iInter (fun q ↦ ?_) refine MeasurableSet.iInter (fun r ↦ ?_) refine MeasurableSet.iInter (fun _ ↦ ?_) @@ -98,7 +98,7 @@ lemma measurableSet_isRatStieltjesPoint [MeasurableSpace α] (hf : Measurable f) have h3 : MeasurableSet {a | Tendsto (f a) atBot (𝓝 0)} := measurableSet_tendsto _ (fun q ↦ hf.eval) have h4 : MeasurableSet {a | ∀ t : ℚ, ⨅ r : Ioi t, f a r = f a t} := by - rw [Set.setOf_forall] + rw [Set.ofPred_forall] refine MeasurableSet.iInter (fun q ↦ ?_) exact measurableSet_eq_fun (.iInf fun _ ↦ hf.eval) hf.eval suffices {a | IsRatStieltjesPoint f a} @@ -107,7 +107,7 @@ lemma measurableSet_isRatStieltjesPoint [MeasurableSpace α] (hf : Measurable f) rw [this] exact (((h1.inter h2).inter h3).inter h4) ext a - simp only [mem_setOf_eq, mem_inter_iff] + simp only [mem_ofPred_eq, mem_inter_iff] refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ · exact ⟨⟨⟨h.mono, h.tendsto_atTop_one⟩, h.tendsto_atBot_zero⟩, h.iInf_rat_gt_eq⟩ · exact ⟨h.1.1.1, h.1.1.2, h.1.2, h.2⟩ diff --git a/Mathlib/Probability/Kernel/MeasurableIntegral.lean b/Mathlib/Probability/Kernel/MeasurableIntegral.lean index 7d83e00f2feddc..60f7c1465ca39a 100644 --- a/Mathlib/Probability/Kernel/MeasurableIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableIntegral.lean @@ -70,7 +70,7 @@ theorem StronglyMeasurable.integral_kernel ⦃f : β → E⦄ exact κ.measurable_coe ((s n).measurableSet_fiber _) · rw [tendsto_pi_nhds]; intro x by_cases hfx : Integrable f (κ x) - · simp only [mem_setOf_eq, hfx, indicator_of_mem, f'] + · simp only [mem_ofPred_eq, hfx, indicator_of_mem, f'] apply tendsto_integral_approxOn_of_measurable_of_range_subset _ hfx exact subset_rfl · simp [f', hfx, integral_undef] @@ -108,7 +108,7 @@ theorem StronglyMeasurable.integral_kernel_prod_right ⦃f : α → β → E⦄ filter_upwards with y simp_rw [s', SimpleFunc.coe_comp]; exact SimpleFunc.norm_approxOn_zero_le _ _ (x, y) n simp only [f', hfx, SimpleFunc.integral_eq_integral _ (this _), indicator_of_mem, - mem_setOf_eq] + mem_ofPred_eq] refine tendsto_integral_of_dominated_convergence (fun y => ‖f x y‖ + ‖f x y‖) (fun n => (s' n x).aestronglyMeasurable) (hfx.norm.add hfx.norm) ?_ ?_ diff --git a/Mathlib/Probability/Kernel/MeasurableLIntegral.lean b/Mathlib/Probability/Kernel/MeasurableLIntegral.lean index 3c6e41f14545f9..2a7782dbce9357 100644 --- a/Mathlib/Probability/Kernel/MeasurableLIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableLIntegral.lean @@ -44,7 +44,7 @@ theorem measurable_kernel_prodMk_left_of_finite {t : Set (α × β)} (ht : Measu using MeasurableSpace.induction_on_inter generateFrom_prod.symm isPiSystem_prod with | empty => simp only [preimage_empty, measure_empty, measurable_const] | basic t ht => - simp only [Set.mem_image2, Set.mem_setOf_eq] at ht + simp only [Set.mem_image2, Set.mem_ofPred_eq] at ht obtain ⟨t₁, ht₁, t₂, ht₂, rfl⟩ := ht classical simp_rw [mk_preimage_prod_right_eq_if] diff --git a/Mathlib/Probability/Kernel/RadonNikodym.lean b/Mathlib/Probability/Kernel/RadonNikodym.lean index 5c504817a8c66d..09de3a75c3af40 100644 --- a/Mathlib/Probability/Kernel/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/RadonNikodym.lean @@ -193,7 +193,7 @@ def mutuallySingularSetSlice (κ η : Kernel α γ) (a : α) : Set γ := lemma mem_mutuallySingularSetSlice (κ η : Kernel α γ) (a : α) (x : γ) : x ∈ mutuallySingularSetSlice κ η a ↔ 1 ≤ rnDerivAux κ (κ + η) a x := by - rw [mutuallySingularSetSlice, mem_setOf] + rw [mutuallySingularSetSlice, mem_ofPred] lemma notMem_mutuallySingularSetSlice (κ η : Kernel α γ) (a : α) (x : γ) : x ∉ mutuallySingularSetSlice κ η a ↔ rnDerivAux κ (κ + η) a x < 1 := by @@ -220,7 +220,7 @@ lemma measure_mutuallySingularSetSlice (κ η : Kernel α γ) [IsFiniteKernel κ · fun_prop · fun_prop refine ae_of_all _ (fun x hx ↦ ?_) - simp only [mem_setOf_eq] at hx + simp only [mem_ofPred_eq] at hx simp [hx] /-- Radon-Nikodym derivative of the kernel `κ` with respect to the kernel `η`. -/ @@ -247,12 +247,12 @@ lemma rnDeriv_eq_top_iff (κ η : Kernel α γ) (a : α) (x : γ) : rnDeriv κ η a x = ∞ ↔ (a, x) ∈ mutuallySingularSet κ η := by simp only [rnDeriv, ENNReal.div_eq_top, ne_eq, ENNReal.ofReal_eq_zero, not_le, tsub_le_iff_right, zero_add, ENNReal.ofReal_ne_top, not_false_eq_true, and_true, or_false, - mutuallySingularSet, mem_setOf_eq, and_iff_right_iff_imp] + mutuallySingularSet, mem_ofPred_eq, and_iff_right_iff_imp] exact fun h ↦ zero_lt_one.trans_le h lemma rnDeriv_eq_top_iff' (κ η : Kernel α γ) (a : α) (x : γ) : rnDeriv κ η a x = ∞ ↔ x ∈ mutuallySingularSetSlice κ η a := by - rw [rnDeriv_eq_top_iff, mutuallySingularSet, mutuallySingularSetSlice, mem_setOf, mem_setOf] + rw [rnDeriv_eq_top_iff, mutuallySingularSet, mutuallySingularSetSlice, mem_ofPred, mem_ofPred] /-- Singular part of the kernel `κ` with respect to the kernel `η`. -/ noncomputable @@ -285,7 +285,7 @@ lemma singularPart_compl_mutuallySingularSetSlice (κ η : Kernel α γ) [IsSFin · exact measurable_singularPart_fun_right κ η a · exact measurable_singularPart_fun κ η refine ae_of_all _ (fun x hx ↦ ?_) - simp only [mem_compl_iff, mutuallySingularSetSlice, mem_setOf, not_le] at hx + simp only [mem_compl_iff, mutuallySingularSetSlice, mem_ofPred, not_le] at hx simp_rw [rnDeriv] rw [← ENNReal.ofReal_div_of_pos, div_eq_inv_mul, ← ENNReal.ofReal_mul, ← mul_assoc, mul_inv_cancel₀, one_mul, tsub_self, Pi.zero_apply] diff --git a/Mathlib/Probability/Kernel/Representation.lean b/Mathlib/Probability/Kernel/Representation.lean index 90a06b713b9bd9..e9846b9dd52e9a 100644 --- a/Mathlib/Probability/Kernel/Representation.lean +++ b/Mathlib/Probability/Kernel/Representation.lean @@ -52,7 +52,7 @@ private lemma exists_measurable_map_eq_unitInterval_aux (κ : Kernel X I) [IsMar have sSup_eq_iUnion_rat : {x : X × I | a < f x.1 x.2} = ⋃ (q : ℚ) (hqI : ↑q ∈ I) (_ : a < (q : ℝ)), {e | (κ e.1).real (Icc 0 ⟨q, hqI⟩) < e.2} := by ext e - simp_all only [lt_sSup_iff, mem_setOf_eq, Subtype.exists, mem_Icc, Rat.cast_nonneg, + simp_all only [lt_sSup_iff, mem_ofPred_eq, Subtype.exists, mem_Icc, Rat.cast_nonneg, mem_iUnion, exists_prop, exists_and_left, f] constructor · rintro ⟨y, hyI, y_mem, (hy : a.1 < y)⟩ diff --git a/Mathlib/Probability/Martingale/Convergence.lean b/Mathlib/Probability/Martingale/Convergence.lean index 465482d146702d..eecdccc9272253 100644 --- a/Mathlib/Probability/Martingale/Convergence.lean +++ b/Mathlib/Probability/Martingale/Convergence.lean @@ -381,7 +381,7 @@ theorem Integrable.tendsto_ae_condExp (hg : Integrable g μ) (fun s _ _ => hlimint.integrableOn) (fun s hs _ => ?_) hgmeas.aestronglyMeasurable stronglyMeasurable_limitProcess.aestronglyMeasurable have hpi : IsPiSystem {s | ∃ n, MeasurableSet[ℱ n] s} := by - rw [Set.setOf_exists] + rw [Set.ofPred_exists] exact isPiSystem_iUnion_of_monotone _ (fun n ↦ (ℱ n).isPiSystem_measurableSet) fun _ _ ↦ ℱ.mono induction s, hs using MeasurableSpace.induction_on_inter (MeasurableSpace.measurableSpace_iSup_eq ℱ) hpi with diff --git a/Mathlib/Probability/Martingale/OptionalSampling.lean b/Mathlib/Probability/Martingale/OptionalSampling.lean index 0c00d1562a9576..da461730194adb 100644 --- a/Mathlib/Probability/Martingale/OptionalSampling.lean +++ b/Mathlib/Probability/Martingale/OptionalSampling.lean @@ -69,7 +69,7 @@ theorem condExp_stopping_time_ae_eq_restrict_eq_const_of_le_const (h : Martingal rw [Set.inter_comm _ t, IsStoppingTime.measurableSet_inter_eq_iff] · suffices {x : Ω | τ x = i} = ∅ by simp [this]; norm_cast ext1 x - simp only [Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false] + simp only [Set.mem_ofPred_eq, Set.mem_empty_iff_false, iff_false] contrapose hin exact_mod_cast hin ▸ hτ_le x @@ -82,7 +82,7 @@ theorem stoppedValue_ae_eq_restrict_eq (h : Martingale f ℱ μ) (hτ : IsStoppi (condExp_stopping_time_ae_eq_restrict_eq_const_of_le_const h hτ hτ_le i).symm rw [Filter.EventuallyEq, ae_restrict_iff' (ℱ.le _ _ (hτ.measurableSet_eq i))] refine Filter.Eventually.of_forall fun x hx => ?_ - rw [Set.mem_setOf_eq] at hx + rw [Set.mem_ofPred_eq] at hx simp [stoppedValue, hx] /-- The value of a martingale `f` at a stopping time `τ` bounded by `n` is the conditional @@ -94,7 +94,7 @@ theorem stoppedValue_ae_eq_condExp_of_le_const_of_countable_range (h : Martingal have : Set.univ = ⋃ i ∈ Set.range τ, {x | τ x = i} := by ext1 x simp only [Set.mem_univ, Set.mem_range, Set.iUnion_exists, Set.iUnion_iUnion_eq', - Set.mem_iUnion, Set.mem_setOf_eq, exists_apply_eq_apply'] + Set.mem_iUnion, Set.mem_ofPred_eq, exists_apply_eq_apply'] nth_rw 1 [← @Measure.restrict_univ Ω _ μ] rw [this, ae_eq_restrict_biUnion_iff _ h_countable_range] intro i hi @@ -206,7 +206,7 @@ theorem stoppedValue_min_ae_eq_condExp [SigmaFiniteFiltration μ ℱ] (h : Marti rw [Filter.EventuallyEq, ae_restrict_iff'] at this swap; · exact hτ.measurableSpace_le _ (hτ.measurableSet_le_stopping_time hσ) filter_upwards [this] with x hx hx_mem - simp only [Set.mem_compl_iff, Set.mem_setOf_eq, not_le] at hx_mem + simp only [Set.mem_compl_iff, Set.mem_ofPred_eq, not_le] at hx_mem exact hx hx_mem.le apply Filter.EventuallyEq.trans _ ((condExp_min_stopping_time_ae_eq_restrict_le hτ hσ).trans _) · exact stoppedValue f τ diff --git a/Mathlib/Probability/Martingale/OptionalStopping.lean b/Mathlib/Probability/Martingale/OptionalStopping.lean index e340024219f05b..58ee77a204452e 100644 --- a/Mathlib/Probability/Martingale/OptionalStopping.lean +++ b/Mathlib/Probability/Martingale/OptionalStopping.lean @@ -132,7 +132,7 @@ theorem smul_le_stoppedValue_hittingBtwn [IsFiniteMeasure μ] (hsub : Submarting intro x hx simp_rw [le_sup'_iff, mem_range, Nat.lt_succ_iff] at hx refine stoppedValue_hittingBtwn_mem ?_ - simp only [Set.mem_Icc, zero_le, true_and, Set.mem_setOf_eq] + simp only [Set.mem_Icc, zero_le, true_and, Set.mem_ofPred_eq] exact let ⟨j, hj₁, hj₂⟩ := hx ⟨j, hj₁, hj₂⟩ @@ -195,9 +195,9 @@ theorem maximal_ineq [IsFiniteMeasure μ] (hsub : Submartingale f 𝒢 μ) (hnon exact hsub.stronglyAdapted.adapted.isStoppingTime_hittingBtwn measurableSet_Ici · exact nullMeasurableSet_lt (measurable_range_sup'' fun n _ ↦ (hsub.stronglyMeasurable n).measurable.le (𝒢.le n)).aemeasurable aemeasurable_const - rw [Set.mem_setOf_eq] at hω + rw [Set.mem_ofPred_eq] at hω have : hittingBtwn f {y : ℝ | ε ≤ y} 0 n ω = n := by - simp only [hittingBtwn, Set.mem_setOf_eq, ite_eq_right_iff, forall_exists_index, and_imp] + simp only [hittingBtwn, Set.mem_ofPred_eq, ite_eq_right_iff, forall_exists_index, and_imp] intro m hm hεm exact False.elim ((not_le.2 hω) ((le_sup'_iff _).2 ⟨m, mem_range.2 (Nat.lt_succ_of_le hm.2), hεm⟩)) diff --git a/Mathlib/Probability/Martingale/Upcrossing.lean b/Mathlib/Probability/Martingale/Upcrossing.lean index c2367d481806f2..559c97aea88063 100644 --- a/Mathlib/Probability/Martingale/Upcrossing.lean +++ b/Mathlib/Probability/Martingale/Upcrossing.lean @@ -522,7 +522,7 @@ theorem upcrossingsBefore_lt_of_exists_upcrossing (hab : a < b) {N₁ N₂ : ℕ (hN₁' : f N₁ ω < a) (hN₂ : N₁ ≤ N₂) (hN₂' : b < f N₂ ω) : upcrossingsBefore a b f N ω < upcrossingsBefore a b f (N₂ + 1) ω := by refine lt_of_lt_of_le (Nat.lt_succ_self _) (le_csSup (upperCrossingTime_lt_bddAbove hab) ?_) - rw [Set.mem_setOf_eq, upperCrossingTime_succ_eq, hittingBtwn_lt_iff _ le_rfl] + rw [Set.mem_ofPred_eq, upperCrossingTime_succ_eq, hittingBtwn_lt_iff _ le_rfl] refine ⟨N₂, ⟨?_, Nat.lt_succ_self _⟩, hN₂'.le⟩ rw [lowerCrossingTime, hittingBtwn_le_iff_of_lt _ (Nat.lt_succ_self _)] refine ⟨N₁, ⟨le_trans ?_ hN₁, hN₂⟩, hN₁'.le⟩ @@ -740,7 +740,7 @@ theorem upcrossingsBefore_eq_sum (hab : a < b) : upcrossingsBefore a b f N ω = rintro k hk rw [Finset.mem_Ico, Nat.succ_le_iff] at hk rw [Set.indicator_of_notMem] - simp only [Set.mem_setOf_eq, not_lt] + simp only [Set.mem_ofPred_eq, not_lt] exact (upperCrossingTime_eq_of_upcrossingsBefore_lt hab hk.1).symm.le rw [Finset.sum_congr rfl h₁, Finset.sum_congr rfl h₂, Finset.sum_const, Finset.sum_const, smul_eq_mul, mul_one, smul_eq_mul, mul_zero, Nat.card_Ico, Nat.add_succ_sub_one, diff --git a/Mathlib/Probability/Moments/Basic.lean b/Mathlib/Probability/Moments/Basic.lean index 2941afd2786b9c..8bc06c60bcbd0e 100644 --- a/Mathlib/Probability/Moments/Basic.lean +++ b/Mathlib/Probability/Moments/Basic.lean @@ -437,7 +437,7 @@ theorem measure_ge_le_exp_mul_mgf [IsFiniteMeasure μ] (ε : ℝ) (ht : 0 ≤ t) calc μ.real {ω | ε ≤ X ω} = μ.real {ω | exp (t * ε) ≤ exp (t * X ω)} := by congr 1 with ω - simp only [Set.mem_setOf_eq, exp_le_exp] + simp only [Set.mem_ofPred_eq, exp_le_exp] exact ⟨fun h => mul_le_mul_of_nonneg_left h ht_pos.le, fun h => le_of_mul_le_mul_left h ht_pos⟩ _ ≤ (exp (t * ε))⁻¹ * μ[fun ω => exp (t * X ω)] := by diff --git a/Mathlib/Probability/Moments/ComplexMGF.lean b/Mathlib/Probability/Moments/ComplexMGF.lean index 9a48e888c2ecc6..80d8551aa605b5 100644 --- a/Mathlib/Probability/Moments/ComplexMGF.lean +++ b/Mathlib/Probability/Moments/ComplexMGF.lean @@ -241,7 +241,7 @@ the same `integrableExpSet`. -/ lemma integrableExpSet_eq_of_mgf' (hXY : mgf X μ = mgf Y μ') (hμμ' : μ = 0 ↔ μ' = 0) : integrableExpSet X μ = integrableExpSet Y μ' := by ext t - simp only [integrableExpSet, Set.mem_setOf_eq] + simp only [integrableExpSet, Set.mem_ofPred_eq] by_cases hμ : μ = 0 · simp [hμ, hμμ'.mp hμ] have : NeZero μ := ⟨hμ⟩ diff --git a/Mathlib/Probability/Moments/SubGaussian.lean b/Mathlib/Probability/Moments/SubGaussian.lean index 702e717651d331..18a8eb31d4b636 100644 --- a/Mathlib/Probability/Moments/SubGaussian.lean +++ b/Mathlib/Probability/Moments/SubGaussian.lean @@ -353,7 +353,7 @@ lemma measure_pos_eq_zero_of_hasSubGaussianMGF_zero (h : HasSubgaussianMGF X 0 ∀ᵐ ω' ∂ν, (κ ω') {ω | 0 < X ω} = 0 := by have hs : {ω | 0 < X ω} = ⋃ ε : {ε : ℚ // 0 < ε}, {ω | ε ≤ X ω} := by ext ω - simp only [Set.mem_setOf_eq, Set.mem_iUnion, Subtype.exists, exists_prop] + simp only [Set.mem_ofPred_eq, Set.mem_iUnion, Subtype.exists, exists_prop] constructor · intro hp obtain ⟨q, h1, h2⟩ := exists_rat_btwn hp diff --git a/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean b/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean index bab0cce586a7d7..f84582dd289484 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean @@ -311,14 +311,15 @@ theorem support_bernoulli : (bernoulli p h).support = { b | cond b (p ≠ 0) (p refine Set.ext fun b => ?_ induction b · simp_rw [mem_support_iff, bernoulli_apply, Bool.cond_false, Ne, ENNReal.coe_sub, - ENNReal.coe_one, Bool.cond_prop, Set.mem_setOf_eq, Bool.false_eq_true, ite_false, not_iff_not] + ENNReal.coe_one, Bool.cond_prop, Set.mem_ofPred_eq, Bool.false_eq_true, ite_false, + not_iff_not] constructor · intro h' simp only [tsub_eq_zero_iff_le, one_le_coe_iff] at h' exact eq_of_le_of_ge h h' · intro h' simp only [h', ENNReal.coe_one, tsub_self] - · simp only [mem_support_iff, bernoulli_apply, Bool.cond_true, Set.mem_setOf_eq, ne_eq, + · simp only [mem_support_iff, bernoulli_apply, Bool.cond_true, Set.mem_ofPred_eq, ne_eq, ENNReal.coe_eq_zero] @[deprecated ProbabilityTheory.bernoulliMeasure_apply_of_notMem_of_notMem (since := "2026-05-29")] diff --git a/Mathlib/Probability/Process/HittingTime.lean b/Mathlib/Probability/Process/HittingTime.lean index 0fe4ccb05c7b77..58507fb6b1f50f 100644 --- a/Mathlib/Probability/Process/HittingTime.lean +++ b/Mathlib/Probability/Process/HittingTime.lean @@ -88,7 +88,7 @@ lemma hittingAfter_empty (n : ι) : hittingAfter u ∅ n = fun _ ↦ ⊤ := by e lemma hittingBtwn_univ {ι : Type*} [ConditionallyCompleteLinearOrder ι] {u : ι → Ω → β} (n m : ι) : hittingBtwn u .univ n m = fun _ ↦ min n m := by ext ω - simp only [hittingBtwn_def, Set.mem_Icc, Set.mem_univ, and_true, Set.setOf_true, Set.inter_univ] + simp only [hittingBtwn_def, Set.mem_Icc, Set.mem_univ, and_true, Set.ofPred_true, Set.inter_univ] by_cases hnm : n ≤ m <;> simp [hnm] <;> grind @[simp] @@ -269,7 +269,7 @@ theorem hittingBtwn_lt_iff {m : ι} (i : ι) (hi : i ≤ m) : rotate_left · exact ⟨n, by simp [mem_lowerBounds]; grind⟩ · exact h - simp only [Set.mem_inter_iff, Set.mem_Icc, Set.mem_setOf_eq] at h' + simp only [Set.mem_inter_iff, Set.mem_Icc, Set.mem_ofPred_eq] at h' obtain ⟨j, ⟨⟨hnj, hjm⟩, hj_mem⟩, hji⟩ := h' exact ⟨j, ⟨hnj, hji⟩, hj_mem⟩ · obtain ⟨k, hk₁, hk₂⟩ := h' @@ -291,7 +291,7 @@ lemma hittingAfter_lt_iff : rotate_left · exact ⟨n, by simp [mem_lowerBounds]; grind⟩ · exact h_exists - simp only [Set.mem_setOf_eq] at h' + simp only [Set.mem_ofPred_eq] at h' obtain ⟨j, hj₁, hj₂⟩ := h' exact ⟨j, ⟨hj₁.1, hj₂⟩, hj₁.2⟩ · obtain ⟨j, hj₁, hj₂⟩ := h' @@ -447,7 +447,7 @@ theorem Adapted.isStoppingTime_hittingBtwn_isStoppingTime [ConditionallyComplete (⋃ i ≤ n, {x | τ x = i} ∩ {x | hittingBtwn u s i N x ≤ n}) ∪ ⋃ i > n, {x | τ x = i} ∩ {x | hittingBtwn u s i N x ≤ n} := by ext x - simp only [Set.mem_setOf_eq, gt_iff_lt, Set.mem_union, Set.mem_iUnion, Set.mem_inter_iff, + simp only [Set.mem_ofPred_eq, gt_iff_lt, Set.mem_union, Set.mem_iUnion, Set.mem_inter_iff, exists_and_left, exists_prop] specialize hτbdd x have h_top : τ x ≠ ⊤ := fun h => by simp [h] at hτbdd @@ -455,7 +455,7 @@ theorem Adapted.isStoppingTime_hittingBtwn_isStoppingTime [ConditionallyComplete simp [← or_and_right, le_or_gt] have h₂ : ⋃ i > n, {x | τ x = i} ∩ {x | hittingBtwn u s i N x ≤ n} = ∅ := by ext x - simp only [gt_iff_lt, Set.mem_iUnion, Set.mem_inter_iff, Set.mem_setOf_eq, exists_prop, + simp only [gt_iff_lt, Set.mem_iUnion, Set.mem_inter_iff, Set.mem_ofPred_eq, exists_prop, Set.mem_empty_iff_false, iff_false, not_exists, not_and, not_le] refine fun m hm hτ ↦ hm.trans_le <| le_hittingBtwn ?_ x specialize hτbdd x diff --git a/Mathlib/Probability/Process/LocalProperty.lean b/Mathlib/Probability/Process/LocalProperty.lean index 4078759db74a29..55ca4d1ae5c9b1 100644 --- a/Mathlib/Probability/Process/LocalProperty.lean +++ b/Mathlib/Probability/Process/LocalProperty.lean @@ -175,7 +175,7 @@ lemma IsStable.locally_and_iff (hp : IsStable 𝓕 p) (hq : IsStable 𝓕 q) : hqX.isLocalizingSequence_localSeq.isStoppingTime n using 1 ext i ω simp_rw [stoppedProcess_indicator_comm, Pi.inf_apply, lt_inf_iff, inf_comm (hpX.localSeq n)] - rw [← stoppedProcess_stoppedProcess, ← stoppedProcess_indicator_comm, Set.setOf_and, + rw [← stoppedProcess_stoppedProcess, ← stoppedProcess_indicator_comm, Set.ofPred_and, Set.inter_comm] simp_rw [← Set.indicator_indicator] rfl @@ -239,7 +239,7 @@ private lemma isPreLocalizingSequence_of_isLocalizingSequence_aux' rw [measure_eq_zero_iff_ae_notMem] filter_upwards [(hσ n).tendsto_top] with ω hTop hmem simp_rw [WithTop.tendsto_nhds_top_iff, eventually_atTop] at hTop - simp only [Set.mem_iInter, Set.mem_setOf_eq] at hmem + simp only [Set.mem_iInter, Set.mem_ofPred_eq] at hmem obtain ⟨N, hN⟩ := hTop (T n) specialize hN N le_rfl specialize hmem N @@ -249,10 +249,10 @@ private lemma isPreLocalizingSequence_of_isLocalizingSequence_aux' · filter_upwards [(hσ n).mono] with ω hω intros i j hij specialize hω hij - simp [setOf] at * + simp [Set.ofPred] at * grind · refine fun i ↦ .nullMeasurableSet ?_ - simp_rw [lt_inf_iff, Set.setOf_and] + simp_rw [lt_inf_iff, Set.ofPred_and] exact MeasurableSet.inter (measurableSet_lt ((hσ n).isStoppingTime i).measurable' (hτ.isStoppingTime n).measurable') <| measurableSet_lt ((hσ n).isStoppingTime i).measurable' measurable_const @@ -282,7 +282,7 @@ private lemma isPreLocalizingSequence_of_isLocalizingSequence_aux fun n ↦ le_trans (EventuallyLE.measure_le ?_) (hnk n)⟩ filter_upwards [(hσ n).mono] with ω hω specialize hω (le_mkStrictMonoAux nk n) - simp [setOf] + simp [Set.ofPred] grind lemma IsLocalizingSequence.isPrelocalizingSequence_inf_extraction diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 450cf34ae7d9f0..15937a0508b42c 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -93,7 +93,7 @@ theorem IsStoppingTime.measurableSet_lt_of_pred [PredOrder ι] (hτ : IsStopping by_cases hi_min : IsMin i · suffices {ω : Ω | τ ω < i} = ∅ by rw [this]; exact @MeasurableSet.empty _ (f i) ext1 ω - simp only [Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false] + simp only [Set.mem_ofPred_eq, Set.mem_empty_iff_false, iff_false] rw [isMin_iff_forall_not_lt] at hi_min cases τ ω with | top => simp @@ -121,7 +121,7 @@ protected theorem measurableSet_eq_of_countable_range (hτ : IsStoppingTime f τ (h_countable : (Set.range τ).Countable) (i : ι) : MeasurableSet[f i] {ω | τ ω = i} := by have : {ω | τ ω = i} = {ω | τ ω ≤ i} \ ⋃ (j ∈ Set.range τ) (_ : j < i), {ω | τ ω ≤ j} := by ext1 a - simp only [Set.mem_setOf_eq, Set.mem_range, Set.iUnion_exists, Set.iUnion_iUnion_eq', + simp only [Set.mem_ofPred_eq, Set.mem_range, Set.iUnion_exists, Set.iUnion_iUnion_eq', Set.mem_sdiff, Set.mem_iUnion, exists_prop, not_exists, not_and] constructor <;> intro h · simp only [h, lt_iff_le_not_ge, le_refl, and_imp, imp_self, imp_true_iff, and_self_iff] @@ -154,7 +154,7 @@ protected theorem measurableSet_ge_of_countable_range {ι} [LinearOrder ι] {τ {f : Filtration ι m} (hτ : IsStoppingTime f τ) (h_countable : (Set.range τ).Countable) (i : ι) : MeasurableSet[f i] {ω | i ≤ τ ω} := by have : {ω | i ≤ τ ω} = {ω | τ ω < i}ᶜ := by - ext1 ω; simp only [Set.mem_setOf_eq, Set.mem_compl_iff, not_lt] + ext1 ω; simp only [Set.mem_ofPred_eq, Set.mem_compl_iff, not_lt] rw [this] exact (hτ.measurableSet_lt_of_countable_range h_countable i).compl @@ -174,7 +174,7 @@ variable [LinearOrder ι] {f : Filtration ι m} {τ : Ω → WithTop ι} theorem IsStoppingTime.measurableSet_gt (hτ : IsStoppingTime f τ) (i : ι) : MeasurableSet[f i] {ω | i < τ ω} := by have : {ω | i < τ ω} = {ω | τ ω ≤ i}ᶜ := by - ext1 ω; simp only [Set.mem_setOf_eq, Set.mem_compl_iff, not_le] + ext1 ω; simp only [Set.mem_ofPred_eq, Set.mem_compl_iff, not_le] rw [this] exact (hτ.measurableSet_le i).compl @@ -188,7 +188,7 @@ theorem IsStoppingTime.measurableSet_lt_of_isLUB (hτ : IsStoppingTime f τ) (i by_cases hi_min : IsMin i · suffices {ω | τ ω < i} = ∅ by rw [this]; exact @MeasurableSet.empty _ (f i) ext1 ω - simp only [Set.mem_setOf_eq, Set.mem_empty_iff_false, iff_false] + simp only [Set.mem_ofPred_eq, Set.mem_empty_iff_false, iff_false] cases τ ω with | top => simp | coe t => norm_cast; exact isMin_iff_forall_not_lt.mp hi_min t @@ -213,7 +213,7 @@ theorem IsStoppingTime.measurableSet_lt_of_isLUB (hτ : IsStoppingTime f τ) (i have h_lt_eq_preimage : {ω | τ ω < i} = τ ⁻¹' Set.Iio i := by ext1 ω; push _ ∈ _; rfl rw [h_lt_eq_preimage, h_Iio_eq_Union] - simp only [Set.preimage_iUnion, Set.preimage_setOf_eq] + simp only [Set.preimage_iUnion, Set.preimage_ofPred_eq] exact MeasurableSet.iUnion fun n => f.mono (h_bound n).le _ (hτ.measurableSet_le (seq n)) theorem IsStoppingTime.measurableSet_lt (hτ : IsStoppingTime f τ) (i : ι) : @@ -231,14 +231,14 @@ theorem IsStoppingTime.measurableSet_lt (hτ : IsStoppingTime f τ) (i : ι) : theorem IsStoppingTime.measurableSet_ge (hτ : IsStoppingTime f τ) (i : ι) : MeasurableSet[f i] {ω | i ≤ τ ω} := by have : {ω | i ≤ τ ω} = {ω | τ ω < i}ᶜ := by - ext1 ω; simp only [Set.mem_setOf_eq, Set.mem_compl_iff, not_lt] + ext1 ω; simp only [Set.mem_ofPred_eq, Set.mem_compl_iff, not_lt] rw [this] exact (hτ.measurableSet_lt i).compl theorem IsStoppingTime.measurableSet_eq (hτ : IsStoppingTime f τ) (i : ι) : MeasurableSet[f i] {ω | τ ω = i} := by have : {ω | τ ω = i} = {ω | τ ω ≤ i} ∩ {ω | τ ω ≥ i} := by - ext1 ω; simp only [Set.mem_setOf_eq, Set.mem_inter_iff, le_antisymm_iff] + ext1 ω; simp only [Set.mem_ofPred_eq, Set.mem_inter_iff, le_antisymm_iff] rw [this] exact (hτ.measurableSet_le i).inter (hτ.measurableSet_ge i) @@ -261,7 +261,7 @@ theorem isStoppingTime_of_measurableSet_eq [Preorder ι] [Countable ι] {f : Fil intro i have h_eq_iUnion : {ω | τ ω ≤ i} = ⋃ k ≤ i, {ω | τ ω = k} := by ext ω - simp only [Set.mem_setOf_eq, Set.mem_iUnion, exists_prop] + simp only [Set.mem_ofPred_eq, Set.mem_iUnion, exists_prop] cases τ ω with | top => simp | coe a => norm_cast; simp @@ -307,7 +307,7 @@ lemma isStoppingTime_of_measurableSet_lt_of_isRightContinuous' [hf : f.IsRightCo -- we write `{τ ≤ t}` as a countable intersection of `{τ < s n}` have h_eq_iInter : {ω | τ ω ≤ t} = ⋂ m, {ω | τ ω < s m} := by ext ω - simp only [Set.mem_setOf_eq, Set.mem_iInter] + simp only [Set.mem_ofPred_eq, Set.mem_iInter] refine ⟨fun h_le m ↦ h_le.trans_lt (mod_cast (hs_gt m)), fun h_lt ↦ ?_⟩ refine le_of_forall_gt fun u hu ↦ ?_ obtain ⟨i, hi⟩ : ∃ i, s i < u := h_exists_lt' u hu @@ -328,7 +328,7 @@ lemma isStoppingTime_of_measurableSet_lt_of_isRightContinuous' [hf : f.IsRightCo intro k have h_eq_k : ⋂ m, {ω | τ ω < s m} = ⋂ (m) (hm : s m ≤ s k), {ω | τ ω < s m} := by ext x - simp only [Set.mem_iInter, Set.mem_setOf_eq] + simp only [Set.mem_iInter, Set.mem_ofPred_eq] refine ⟨fun h m _ ↦ h m, fun h m ↦ ?_⟩ rcases le_total (s m) (s k) with hmk | hkm · exact h m hmk @@ -352,7 +352,7 @@ protected theorem max [LinearOrder ι] {f : Filtration ι m} {τ π : Ω → Wit (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f π) : IsStoppingTime f fun ω => max (τ ω) (π ω) := by intro i - simp_rw [max_le_iff, Set.setOf_and] + simp_rw [max_le_iff, Set.ofPred_and] exact (hτ i).inter (hπ i) protected theorem max_const [LinearOrder ι] {f : Filtration ι m} {τ : Ω → WithTop ι} @@ -363,7 +363,7 @@ protected theorem min [LinearOrder ι] {f : Filtration ι m} {τ π : Ω → Wit (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f π) : IsStoppingTime f fun ω => min (τ ω) (π ω) := by intro i - simp_rw [min_le_iff, Set.setOf_or] + simp_rw [min_le_iff, Set.ofPred_or] exact (hτ i).union (hπ i) protected theorem min_const [LinearOrder ι] {f : Filtration ι m} {τ : Ω → WithTop ι} @@ -397,7 +397,7 @@ theorem add_const [AddGroup ι] [Preorder ι] [AddRightMono ι] simp only have h_eq : {ω | τ ω + i ≤ j} = {ω | τ ω ≤ j - i} := by ext ω - simp only [Set.mem_setOf_eq, coe_sub] + simp only [Set.mem_ofPred_eq, coe_sub] cases τ ω with | top => simp | coe a => norm_cast; simp_rw [← le_sub_iff_add_le] @@ -412,7 +412,7 @@ theorem add_const' [Add ι] [LinearOrder ι] [CanonicallyOrderedAdd ι] [Countab intro j have h : {ω | τ ω + i ≤ j} = ⋃ k : {k | k + i ≤ j}, {ω | τ ω = k} := by ext ω - simp only [Set.mem_setOf_eq, Set.mem_iUnion] + simp only [Set.mem_ofPred_eq, Set.mem_iUnion] cases τ ω with | top => simp | coe a => simp; norm_cast @@ -426,7 +426,7 @@ theorem add [Add ι] [LinearOrder ι] [CanonicallyOrderedAdd ι] [Countable ι] intro j have h : {ω | (τ + π) ω ≤ j} = ⋃ k : Set.Iic j, {ω | π ω = k} ∩ {ω | τ ω + k ≤ j} := by ext ω - simp only [Pi.add_apply, Set.mem_setOf_eq, Set.mem_iUnion, Set.mem_inter_iff] + simp only [Pi.add_apply, Set.mem_ofPred_eq, Set.mem_iUnion, Set.mem_inter_iff] cases τ ω with | top => simp | coe a => @@ -471,7 +471,7 @@ theorem measurableSpace_mono (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f rw [(_ : s ∩ {ω | π ω ≤ i} = s ∩ {ω | τ ω ≤ i} ∩ {ω | π ω ≤ i})] · exact (hs.2 i).inter (hπ i) · ext - simp only [Set.mem_inter_iff, iff_self_and, and_congr_left_iff, Set.mem_setOf_eq] + simp only [Set.mem_inter_iff, iff_self_and, and_congr_left_iff, Set.mem_ofPred_eq] intro hle' _ exact le_trans (hle _) hle' @@ -484,14 +484,14 @@ theorem measurableSpace_const (f : Filtration ι m) (i : ι) : rw [IsStoppingTime.measurableSet] constructor <;> intro h · have h' := h.2 i - simpa only [le_refl, Set.setOf_true, Set.inter_univ] using h' + simpa only [le_refl, Set.ofPred_true, Set.inter_univ] using h' · refine ⟨f.le i _ h, fun j ↦ ?_⟩ by_cases hij : i ≤ j · norm_cast - simp only [hij, Set.setOf_true, Set.inter_univ] + simp only [hij, Set.ofPred_true, Set.inter_univ] exact f.mono hij _ h · norm_cast - simp only [hij, Set.setOf_false, Set.inter_empty, @MeasurableSet.empty _ (f.1 j)] + simp only [hij, Set.ofPred_false, Set.inter_empty, @MeasurableSet.empty _ (f.1 j)] theorem measurableSet_inter_eq_iff (hτ : IsStoppingTime f τ) (s : Set Ω) (i : ι) : MeasurableSet[hτ.measurableSpace] (s ∩ {ω | τ ω = i}) ↔ @@ -499,7 +499,7 @@ theorem measurableSet_inter_eq_iff (hτ : IsStoppingTime f τ) (s : Set Ω) (i : have : ∀ j, {ω : Ω | τ ω = i} ∩ {ω : Ω | τ ω ≤ j} = {ω : Ω | τ ω = i} ∩ {_ω | i ≤ j} := by intro j ext1 ω - simp only [Set.mem_inter_iff, Set.mem_setOf_eq, and_congr_right_iff] + simp only [Set.mem_inter_iff, Set.mem_ofPred_eq, and_congr_right_iff] intro hxi rw [hxi] constructor <;> intro h @@ -508,7 +508,7 @@ theorem measurableSet_inter_eq_iff (hτ : IsStoppingTime f τ) (s : Set Ω) (i : rw [Set.inter_assoc, this] by_cases hij : i ≤ j · norm_cast - simp only [hij, Set.setOf_true, Set.inter_univ] + simp only [hij, Set.ofPred_true, Set.inter_univ] exact f.mono hij _ h · simp [hij] @@ -553,7 +553,7 @@ protected theorem measurableSet_le' (hτ : IsStoppingTime f τ) (i : ι) : refine ⟨f.le i _ (hτ i), fun j ↦ ?_⟩ have : {ω : Ω | τ ω ≤ i} ∩ {ω : Ω | τ ω ≤ j} = {ω : Ω | τ ω ≤ min i j} := by ext1 ω - simp [Set.mem_inter_iff, Set.mem_setOf_eq] + simp [Set.mem_inter_iff, Set.mem_ofPred_eq] rw [this] exact f.mono (min_le_right i j) _ (hτ _) @@ -574,7 +574,7 @@ protected theorem measurableSet_ge' [TopologicalSpace ι] [OrderTopology ι] MeasurableSet[hτ.measurableSpace] {ω | i ≤ τ ω} := by have : {ω | i ≤ τ ω} = {ω | τ ω = i} ∪ {ω | i < τ ω} := by ext1 ω - simp only [le_iff_lt_or_eq, Set.mem_setOf_eq, Set.mem_union] + simp only [le_iff_lt_or_eq, Set.mem_ofPred_eq, Set.mem_union] cases τ ω with | top => simp | coe a => @@ -588,7 +588,7 @@ protected theorem measurableSet_lt' [TopologicalSpace ι] [OrderTopology ι] MeasurableSet[hτ.measurableSpace] {ω | τ ω < i} := by have : {ω | τ ω < i} = {ω | τ ω ≤ i} \ {ω | τ ω = i} := by ext1 ω - simp only [lt_iff_le_and_ne, Set.mem_setOf_eq, Set.mem_sdiff] + simp only [lt_iff_le_and_ne, Set.mem_ofPred_eq, Set.mem_sdiff] rw [this] exact (hτ.measurableSet_le' i).diff (hτ.measurableSet_eq' i) @@ -609,7 +609,7 @@ protected theorem measurableSet_ge_of_countable_range' (hτ : IsStoppingTime f MeasurableSet[hτ.measurableSpace] {ω | i ≤ τ ω} := by have : {ω | i ≤ τ ω} = {ω | τ ω = i} ∪ {ω | i < τ ω} := by ext1 ω - simp only [le_iff_lt_or_eq, Set.mem_setOf_eq, Set.mem_union] + simp only [le_iff_lt_or_eq, Set.mem_ofPred_eq, Set.mem_union] cases τ ω with | top => simp | coe a => @@ -627,7 +627,7 @@ protected theorem measurableSet_lt_of_countable_range' (hτ : IsStoppingTime f MeasurableSet[hτ.measurableSpace] {ω | τ ω < i} := by have : {ω | τ ω < i} = {ω | τ ω ≤ i} \ {ω | τ ω = i} := by ext1 ω - simp only [lt_iff_le_and_ne, Set.mem_setOf_eq, Set.mem_sdiff] + simp only [lt_iff_le_and_ne, Set.mem_ofPred_eq, Set.mem_sdiff] rw [this] exact (hτ.measurableSet_le' i).diff (hτ.measurableSet_eq_of_countable_range' h_countable i) @@ -758,7 +758,7 @@ theorem measurableSet_eq_stopping_time_min [TopologicalSpace ι] (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f π) : MeasurableSet[(hτ.min hπ).measurableSpace] {ω | τ ω = π ω} := by have : {ω | τ ω = π ω} = {ω | τ ω ≤ π ω} ∩ {ω | π ω ≤ τ ω} := by - ext; simp only [Set.mem_setOf_eq, le_antisymm_iff, Set.mem_inter_iff] + ext; simp only [Set.mem_ofPred_eq, le_antisymm_iff, Set.mem_inter_iff] rw [this] refine MeasurableSet.inter (measurableSet_stopping_time_le_min hτ hπ) ?_ convert! (measurableSet_stopping_time_le_min hπ hτ) using 3 @@ -948,7 +948,7 @@ theorem isStronglyProgressive_min_stopping_time [PseudoMetrizableSpace ι] (fun x : s => (x : Set.Iic i × Ω).snd) ⁻¹' {ω | τ ω ≤ min i j} := by ext1 ω simp only [Set.mem_preimage, Set.mem_Iic, coe_min, le_inf_iff, - Set.preimage_setOf_eq, Set.mem_setOf_eq, iff_and_self] + Set.preimage_ofPred_eq, Set.mem_ofPred_eq, iff_and_self] exact fun _ => ω.prop rw [h_set_eq] suffices h_meas : @Measurable _ _ (m_set s) (f i) fun x : s ↦ (x : Set.Iic i × Ω).snd from @@ -969,7 +969,7 @@ theorem isStronglyProgressive_min_stopping_time [PseudoMetrizableSpace ι] norm_cast refine hx_fst_le.trans (le_of_lt ?_) convert! ω.prop - simp only [sc, s, not_le, Set.mem_compl_iff, Set.mem_setOf_eq, ← ht] + simp only [sc, s, not_le, Set.mem_compl_iff, Set.mem_ofPred_eq, ← ht] norm_cast @[deprecated (since := "2026-04-24")] @@ -1027,7 +1027,7 @@ lemma measurableSet_preimage_stoppedValue_inter [PseudoMetrizableSpace β] [Meas (stoppedValue u fun ω => min (τ ω) i) ⁻¹' t ∩ {ω : Ω | τ ω ≤ i} by rw [this]; exact ((h_str_meas i).measurable ht).inter (hτ.measurableSet_le i) ext1 ω - simp only [stoppedValue, Set.mem_inter_iff, Set.mem_preimage, Set.mem_setOf_eq, + simp only [stoppedValue, Set.mem_inter_iff, Set.mem_preimage, Set.mem_ofPred_eq, and_congr_left_iff] intro h rw [min_eq_left h] @@ -1044,8 +1044,8 @@ theorem measurable_stoppedValue [PseudoMetrizableSpace β] [MeasurableSpace β] = (⋃ n, stoppedValue u τ ⁻¹' t ∩ {ω | τ ω ≤ seq n}) ∪ (stoppedValue u τ ⁻¹' t ∩ {ω | τ ω = ⊤}) := by ext1 ω - simp only [Set.mem_preimage, Set.mem_union, Set.mem_iUnion, Set.mem_inter_iff, Set.mem_setOf_eq, - exists_and_left] + simp only [Set.mem_preimage, Set.mem_union, Set.mem_iUnion, Set.mem_inter_iff, + Set.mem_ofPred_eq, exists_and_left] rw [← and_or_left, iff_self_and] intro _ by_cases h : τ ω = ⊤ @@ -1062,7 +1062,7 @@ theorem measurable_stoppedValue [PseudoMetrizableSpace β] [MeasurableSpace β] = (fun ω ↦ u (Classical.arbitrary ι) ω) ⁻¹' t ∩ {ω | τ ω = ⊤} := by ext ω simp only [Set.mem_inter_iff, Set.mem_preimage, stoppedValue, untopA, - Set.mem_setOf_eq, and_congr_left_iff] + Set.mem_ofPred_eq, and_congr_left_iff] intro h simp [h] rw [this] @@ -1088,7 +1088,7 @@ theorem stoppedValue_eq_of_mem_finset [AddCommMonoid E] {s : Finset ι} suffices {i ∈ s | y ∈ {ω : Ω | τ ω = (i : ι)}} = ({(τ y).untopA} : Finset ι) by rw [this, Finset.sum_singleton] ext1 ω - simp only [Set.mem_setOf_eq, Finset.mem_filter, Finset.mem_singleton] + simp only [Set.mem_ofPred_eq, Finset.mem_filter, Finset.mem_singleton] constructor <;> intro h · simp [h.2] · simp only [h] @@ -1118,7 +1118,7 @@ theorem stoppedProcess_eq_of_mem_finset [LinearOrder ι] [AddCommMonoid E] {s : · intro m hm refine Set.indicator_of_notMem ?_ _ rw [Finset.mem_filter] at hm - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] refine (lt_of_lt_of_le ?_ h).ne' exact mod_cast hm.2 · exact h @@ -1128,7 +1128,7 @@ theorem stoppedProcess_eq_of_mem_finset [LinearOrder ι] [AddCommMonoid E] {s : lift τ ω to ι using h_top with i hi rw [Finset.sum_eq_single_of_mem i] · simp only [untopD_coe] - rw [Set.indicator_of_notMem, zero_add, Set.indicator_of_mem] <;> rw [Set.mem_setOf] + rw [Set.indicator_of_notMem, zero_add, Set.indicator_of_mem] <;> rw [Set.mem_ofPred] · exact hi.symm · rw [← hi] exact not_le.2 h @@ -1137,7 +1137,7 @@ theorem stoppedProcess_eq_of_mem_finset [LinearOrder ι] [AddCommMonoid E] {s : exact ⟨hbdd, mod_cast h⟩ · intro b _ hneq rw [Set.indicator_of_notMem] - rw [Set.mem_setOf, ← hi] + rw [Set.mem_ofPred, ← hi] exact mod_cast hneq.symm theorem stoppedProcess_eq'' [LinearOrder ι] [LocallyFiniteOrderBot ι] [AddCommMonoid E] (n : ι) : @@ -1300,7 +1300,7 @@ theorem stoppedValue_sub_eq_sum' [AddCommGroup β] (hle : τ ≤ π) {N : ℕ} ( simp only [Finset.sum_apply, Finset.sum_indicator_eq_sum_filter] refine Finset.sum_congr ?_ fun _ _ => rfl ext i - simp only [Set.mem_setOf_eq, Finset.mem_Ico] + simp only [Set.mem_ofPred_eq, Finset.mem_Ico] specialize hbdd ω lift τ ω to ℕ using hτ_top ω with t ht lift π ω to ℕ using hπ_top ω with b hb @@ -1339,15 +1339,15 @@ theorem stoppedProcess_eq' (n : ℕ) : stoppedProcess u τ n = Set.indicator {a · simp_rw [@eq_comm _ _ (n : WithTop ℕ), @le_iff_eq_or_lt _ _ (n : WithTop ℕ)] have : {a | ↑n + 1 ≤ τ a} = {a | ↑n < τ a} := by ext ω - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] cases τ ω with | top => simp | coe t => simp only [Nat.cast_lt] norm_cast - rw [this, Set.setOf_or] + rw [this, Set.ofPred_or] · rintro ⟨h₁, h₂⟩ - rw [Set.mem_setOf] at h₁ h₂ + rw [Set.mem_ofPred] at h₁ h₂ rw [h₁] at h₂ norm_cast at h₂ grind @@ -1370,7 +1370,7 @@ theorem IsStoppingTime.piecewise_of_le (hτ_st : IsStoppingTime 𝒢 τ) (hη_st intro n have : {ω | s.piecewise τ η ω ≤ n} = s ∩ {ω | τ ω ≤ n} ∪ sᶜ ∩ {ω | η ω ≤ n} := by ext1 ω - simp only [Set.piecewise, Set.mem_setOf_eq] + simp only [Set.piecewise, Set.mem_ofPred_eq] by_cases hx : ω ∈ s <;> simp [hx] rw [this] by_cases hin : i ≤ n diff --git a/Mathlib/Probability/StrongLaw.lean b/Mathlib/Probability/StrongLaw.lean index c8f9eb0db80f95..626be158e016f4 100644 --- a/Mathlib/Probability/StrongLaw.lean +++ b/Mathlib/Probability/StrongLaw.lean @@ -301,7 +301,7 @@ theorem tsum_prob_mem_Ioi_lt_top {X : Ω → ℝ} (hint : Integrable X) (hnonneg obtain ⟨N, hN⟩ : ∃ N : ℕ, X ω ≤ N := exists_nat_ge (X ω) exact Set.mem_iUnion.2 ⟨N, hω, hN⟩ · simp +contextual only [Set.mem_Ioc, Set.mem_Ioi, - Set.iUnion_subset_iff, Set.setOf_subset_setOf, imp_true_iff] + Set.iUnion_subset_iff, Set.ofPred_subset_ofPred, imp_true_iff] rw [this] apply tendsto_measure_iUnion_atTop intro m n hmn x hx diff --git a/Mathlib/RepresentationTheory/Invariants.lean b/Mathlib/RepresentationTheory/Invariants.lean index 01e7ac188479d7..50c4e2cffbd9a9 100644 --- a/Mathlib/RepresentationTheory/Invariants.lean +++ b/Mathlib/RepresentationTheory/Invariants.lean @@ -74,7 +74,7 @@ variable (ρ : Representation k G V) (σ : Representation k G W) /-- The subspace of invariants, consisting of the vectors fixed by all elements of `G`. -/ def invariants : Submodule k V where - carrier := setOf fun v => ∀ g : G, ρ g v = v + carrier := Set.ofPred fun v => ∀ g : G, ρ g v = v zero_mem' g := by simp only [map_zero] add_mem' hv hw g := by simp only [hv g, hw g, map_add] smul_mem' r v hv g := by simp only [hv g, map_smulₛₗ, RingHom.id_apply] diff --git a/Mathlib/RingTheory/Algebraic/Cardinality.lean b/Mathlib/RingTheory/Algebraic/Cardinality.lean index 7e45d940cdf87c..cc0e611901c515 100644 --- a/Mathlib/RingTheory/Algebraic/Cardinality.lean +++ b/Mathlib/RingTheory/Algebraic/Cardinality.lean @@ -40,7 +40,7 @@ theorem lift_cardinalMk_le_sigma_polynomial : ← Polynomial.aeval_def, p.2.2]⟩) fun x y => by intro h - simp only [Set.coe_setOf, ne_eq, Set.mem_setOf_eq, Sigma.mk.inj_iff] at h + simp only [Set.coe_ofPred, ne_eq, Set.mem_ofPred_eq, Sigma.mk.inj_iff] at h refine (Subtype.heq_iff_coe_eq ?_).1 h.2 simp only [h.1, forall_true_iff] rwa [lift_umax, lift_id'.{v}] at this diff --git a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean index 87083dd4ad8d06..3fc6d888aef1fc 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean @@ -333,8 +333,8 @@ theorem isAlgebraic_adjoin_iff_of_matroid_isBasis [NoZeroDivisors A] {s t : Set theorem matroid_closure_eq [IsDomain A] {s : Set A} : (matroid R A).closure s = algebraicClosure (adjoin R s) A := by have ⟨B, hB⟩ := (matroid R A).exists_isBasis s - simp_rw [← hB.closure_eq_closure, hB.1.1.1.closure_eq_setOf_isBasis_insert, Set.ext_iff, - mem_setOf, matroid_isBasis_iff, ← matroid_indep_iff, hB.1.1.1, subset_insert, true_and, + simp_rw [← hB.closure_eq_closure, hB.1.1.1.closure_eq_setOfPred_isBasis_insert, Set.ext_iff, + mem_ofPred, matroid_isBasis_iff, ← matroid_indep_iff, hB.1.1.1, subset_insert, true_and, SetLike.mem_coe, mem_algebraicClosure, ← isAlgebraic_adjoin_iff_of_matroid_isBasis hB, forall_mem_insert] exact fun _ ↦ and_iff_left fun x hx ↦ isAlgebraic_algebraMap (⟨x, subset_adjoin hx⟩ : adjoin R B) diff --git a/Mathlib/RingTheory/Artinian/Module.lean b/Mathlib/RingTheory/Artinian/Module.lean index de051dbbad62e5..5bccde52d124ca 100644 --- a/Mathlib/RingTheory/Artinian/Module.lean +++ b/Mathlib/RingTheory/Artinian/Module.lean @@ -514,14 +514,16 @@ section CommSemiring variable (R : Type*) [CommSemiring R] [IsArtinianRing R] @[stacks 00J7] -lemma setOf_isMaximal_finite : {I : Ideal R | I.IsMaximal}.Finite := by +lemma setOfPred_isMaximal_finite : {I : Ideal R | I.IsMaximal}.Finite := by have ⟨s, H⟩ := Finset.exists_inf_le (Subtype.val (p := fun I : Ideal R ↦ I.IsMaximal)) refine Set.finite_def.2 ⟨s, fun p ↦ ?_⟩ have ⟨q, hq1, hq2⟩ := p.2.isPrime.inf_le'.mp (H p) rwa [← Subtype.ext <| q.2.eq_of_le p.2.ne_top hq2] +@[deprecated (since := "2026-07-09")] alias setOf_isMaximal_finite := setOfPred_isMaximal_finite + instance : Finite (MaximalSpectrum R) := - haveI : Finite {I : Ideal R // I.IsMaximal} := (setOf_isMaximal_finite R).to_subtype + haveI : Finite {I : Ideal R // I.IsMaximal} := (setOfPred_isMaximal_finite R).to_subtype .of_equiv _ (MaximalSpectrum.equivSubtype _).symm end CommSemiring @@ -588,11 +590,13 @@ theorem nilradical_pow_eq_iInf (n : ℕ) : theorem nilradical_eq_iInf : nilradical R = iInf MaximalSpectrum.asIdeal := by simpa using nilradical_pow_eq_iInf R 1 -lemma setOf_isPrime_finite : {I : Ideal R | I.IsPrime}.Finite := by - simpa only [isPrime_iff_isMaximal] using setOf_isMaximal_finite R +lemma setOfPred_isPrime_finite : {I : Ideal R | I.IsPrime}.Finite := by + simpa only [isPrime_iff_isMaximal] using setOfPred_isMaximal_finite R + +@[deprecated (since := "2026-07-09")] alias setOf_isPrime_finite := setOfPred_isPrime_finite instance : Finite (PrimeSpectrum R) := - haveI : Finite {I : Ideal R // I.IsPrime} := (setOf_isPrime_finite R).to_subtype + haveI : Finite {I : Ideal R // I.IsPrime} := (setOfPred_isPrime_finite R).to_subtype .of_equiv _ (PrimeSpectrum.equivSubtype _).symm.toEquiv /-- A temporary field instance on the quotients by maximal ideals. -/ diff --git a/Mathlib/RingTheory/Coalgebra/GroupLike.lean b/Mathlib/RingTheory/Coalgebra/GroupLike.lean index d93f5915453b62..9c9cff4f1172ff 100644 --- a/Mathlib/RingTheory/Coalgebra/GroupLike.lean +++ b/Mathlib/RingTheory/Coalgebra/GroupLike.lean @@ -112,7 +112,7 @@ lemma linearIndepOn_isGroupLikeElem : LinearIndepOn R id {a : A | IsGroupLikeEle -- Let's deal with the `s ∪ {a}` case. | cons a s has ih => simp only [Finset.cons_eq_insert, Finset.coe_insert, Set.subset_def, Set.mem_insert_iff, - Finset.mem_coe, Set.mem_setOf_eq, forall_eq_or_imp] at hs + Finset.mem_coe, Set.mem_ofPred_eq, forall_eq_or_imp] at hs obtain ⟨ha, hs⟩ := hs specialize ih hs -- Assume that there is some `c : A → R` and `d : R` such that `∑ x ∈ s, c x • x = d • a`. diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index d6bc071f7cafd0..7738cf12dfc895 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -713,13 +713,13 @@ noncomputable instance : Valued (adicCompletion K v) ℤᵐ⁰ where refine ⟨fun ⟨t, ht, hts⟩ ↦ ?_, fun ⟨γ, hγ⟩ ↦ ?_⟩ · obtain ⟨δ, hδ⟩ := Valued.mem_nhds_zero.1 ht refine ⟨Units.mapEquiv (valueGroupOrderIso K v).symm.toMulEquiv δ, fun x hx ↦ hts (hδ ?_)⟩ - rw [Set.mem_setOf_eq] at hx ⊢ + rw [Set.mem_ofPred_eq] at hx ⊢ simpa [← map_lt_map_iff (valueGroupOrderIso K v), valueGroupOrderIso_restrict] using hx · refine ⟨{y | Valued.v.restrict y < ↑(Units.mapEquiv (valueGroupOrderIso K v).toMulEquiv γ)}, ?_, fun x hx ↦ hγ ?_⟩ · rw [Valued.mem_nhds_zero] exact ⟨Units.mapEquiv (valueGroupOrderIso K v).toMulEquiv γ, subset_rfl⟩ - · rw [Set.mem_setOf_eq, ← map_lt_map_iff (valueGroupOrderIso K v), + · rw [Set.mem_ofPred_eq, ← map_lt_map_iff (valueGroupOrderIso K v), valueGroupOrderIso_restrict] simpa using hx diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 6d8557b393a511..0e65d551e18789 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -83,7 +83,7 @@ theorem IsDedekindDomain.HeightOneSpectrum.maxPowDividing_eq_pow_multiset_count /-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/ theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) : {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by - rw [← Set.finite_coe_iff, Set.coe_setOf] + rw [← Set.finite_coe_iff, Set.coe_ofPred] have h_fin := fintypeSubtypeDvd I hI refine Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) ?_ @@ -581,11 +581,11 @@ theorem finite_factors' {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) {a : R} intro v hv have hv_irred : Irreducible v.asIdeal := v.irreducible by_contra h_notMem - rw [mem_union, mem_setOf_eq, mem_setOf_eq] at h_notMem + rw [mem_union, mem_ofPred_eq, mem_ofPred_eq] at h_notMem push Not at h_notMem rw [← Associates.count_ne_zero_iff_dvd ha_ne_zero hv_irred, not_not, ← Associates.count_ne_zero_iff_dvd hJ_ne_zero hv_irred, not_not] at h_notMem - rw [mem_setOf_eq, h_notMem.1, h_notMem.2, sub_self] at hv + rw [mem_ofPred_eq, h_notMem.1, h_notMem.2, sub_self] at hv exact hv (Eq.refl 0) exact Finite.subset (Finite.union (Ideal.finite_factors (ideal_factor_ne_zero hI haJ)) (Ideal.finite_factors (constant_factor_ne_zero hI haJ))) h_subset @@ -595,7 +595,7 @@ open Classical in theorem finite_factors (I : FractionalIdeal R⁰ K) : ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite, count K v I = 0 := by by_cases hI : I = 0 - · simp only [hI, count_zero, Filter.eventually_cofinite, not_true_eq_false, setOf_false, + · simp only [hI, count_zero, Filter.eventually_cofinite, not_true_eq_false, ofPred_false, finite_empty] · convert! finite_factors' hI (choose_spec (choose_spec (exists_eq_spanSingleton_mul I))).2 rw [count_ne_zero K _ hI] diff --git a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean index ff857b8f025943..0cda4b73f6bdbb 100644 --- a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean +++ b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean @@ -57,7 +57,7 @@ lemma HeightOneSpectrum.Support.finite (k : K) : (Support R k).Finite := by intro v hv apply_fun v.valuation K at hk simp only [Valuation.map_mul, valuation_of_algebraMap] at hk - rw [Set.mem_setOf_eq, valuation_of_algebraMap] + rw [Set.mem_ofPred_eq, valuation_of_algebraMap] have := intValuation_le_one v n contrapose! this rw [← hk, mul_comm] @@ -157,7 +157,7 @@ theorem isUnit_iff {a : FiniteAdeleRing R K} : IsUnit a ↔ (∀ v, a v ≠ 0) ∧ ∀ᶠ v in Filter.cofinite, Valued.v (a v) = 1 := by rw [RestrictedProduct.isUnit_iff] simp only [isUnit_iff_ne_zero, adicCompletionIntegers.isUnit_iff_valued_eq_one, exists_prop, - Filter.eventually_cofinite, not_and_or, Set.setOf_or] + Filter.eventually_cofinite, not_and_or, Set.ofPred_or] simpa using! fun _ _ ↦ a.2 theorem unitsEquiv_finite_valued_eq_one (a : (FiniteAdeleRing R K)ˣ) : diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index 1b90cf37833abd..b80abb2c4a4035 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -155,7 +155,7 @@ open UniqueFactorizationMonoid in theorem mem_primesOver_iff_mem_normalizedFactors {p : Ideal R} [h : p.IsMaximal] [Algebra R A] [IsDomain R] [IsTorsionFree R A] (hp : p ≠ ⊥) {P : Ideal A} : P ∈ p.primesOver A ↔ P ∈ normalizedFactors (map (algebraMap R A) p) := by - rw [primesOver, Set.mem_setOf_eq, mem_normalizedFactors_iff (map_ne_bot_of_ne_bot hp), + rw [primesOver, Set.mem_ofPred_eq, mem_normalizedFactors_iff (map_ne_bot_of_ne_bot hp), liesOver_iff, under_def, and_congr_right_iff, map_le_iff_le_comap] intro hP refine ⟨fun h ↦ le_of_eq h, fun h' ↦ ((IsCoatom.le_iff_eq (isMaximal_def.mp h) ?_).mp h').symm⟩ diff --git a/Mathlib/RingTheory/DedekindDomain/PID.lean b/Mathlib/RingTheory/DedekindDomain/PID.lean index e769531f63098c..42039fd02e8746 100644 --- a/Mathlib/RingTheory/DedekindDomain/PID.lean +++ b/Mathlib/RingTheory/DedekindDomain/PID.lean @@ -232,7 +232,7 @@ theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime [IsDomain (Set.Finite.ofFinset {P ∈ {⊥} ∪ (normalizedFactors (Ideal.map (algebraMap R Sₚ) p)).toFinset | P.IsPrime} fun P => ?_) - rw [Finset.mem_filter, Finset.mem_union, Finset.mem_singleton, Set.mem_setOf, + rw [Finset.mem_filter, Finset.mem_union, Finset.mem_singleton, Set.mem_ofPred, Multiset.mem_toFinset] exact and_iff_right_of_imp fun hP => diff --git a/Mathlib/RingTheory/DedekindDomain/SInteger.lean b/Mathlib/RingTheory/DedekindDomain/SInteger.lean index 49e3eb3a80843b..290106f1f1d86c 100644 --- a/Mathlib/RingTheory/DedekindDomain/SInteger.lean +++ b/Mathlib/RingTheory/DedekindDomain/SInteger.lean @@ -109,7 +109,7 @@ def unit : Subgroup Kˣ := (⨅ (v) (_ : v ∉ S), (v.valuation K).valuationSubring.unitGroup).copy {x : Kˣ | ∀ (v) (_ : v ∉ S), (v : HeightOneSpectrum R).valuation K x = 1} <| Set.ext fun _ => by - simp only [mem_setOf, SetLike.mem_coe, Subgroup.mem_iInf, Valuation.mem_unitGroup_iff] + simp only [mem_ofPred, SetLike.mem_coe, Subgroup.mem_iInf, Valuation.mem_unitGroup_iff] theorem unit_eq : S.unit K = ⨅ (v) (_ : v ∉ S), (v.valuation K).valuationSubring.unitGroup := diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index 3b66c2607c8ad4..857bec77c16f18 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -664,16 +664,19 @@ variable {K Γ₀ O : Type*} [Field K] [LinearOrderedCommGroupWithZero Γ₀] [C [Algebra O K] {v : Valuation K Γ₀} (hv : v.Integers O) include hv -lemma maximalIdeal_eq_setOf_le_v_algebraMap : +lemma maximalIdeal_eq_setOfPred_le_v_algebraMap : letI : IsDomain O := hv.hom_inj.isDomain ∀ [IsDiscreteValuationRing O] {ϖ : O} (_h : Irreducible ϖ), (IsLocalRing.maximalIdeal O : Set O) = {y : O | v (algebraMap O K y) ≤ v (algebraMap O K ϖ)} := by let : IsDomain O := hv.hom_inj.isDomain intro _ _ h - rw [← hv.coe_span_singleton_eq_setOf_le_v_algebraMap, ← h.maximalIdeal_eq] + rw [← hv.coe_span_singleton_eq_setOfPred_le_v_algebraMap, ← h.maximalIdeal_eq] -lemma maximalIdeal_pow_eq_setOf_le_v_algebraMap_pow : +@[deprecated (since := "2026-07-09")] +alias maximalIdeal_eq_setOf_le_v_algebraMap := maximalIdeal_eq_setOfPred_le_v_algebraMap + +lemma maximalIdeal_pow_eq_setOfPred_le_v_algebraMap_pow : letI : IsDomain O := hv.hom_inj.isDomain ∀ [IsDiscreteValuationRing O] {ϖ : O} (_h : Irreducible ϖ) (n : ℕ), ((IsLocalRing.maximalIdeal O ^ n : Ideal O) : Set O) = @@ -681,24 +684,36 @@ lemma maximalIdeal_pow_eq_setOf_le_v_algebraMap_pow : let : IsDomain O := hv.hom_inj.isDomain intro _ ϖ h n have : (v (algebraMap O K ϖ)) ^ n = v (algebraMap O K (ϖ ^ n)) := by simp - rw [this, ← hv.coe_span_singleton_eq_setOf_le_v_algebraMap, + rw [this, ← hv.coe_span_singleton_eq_setOfPred_le_v_algebraMap, ← Ideal.span_singleton_pow, ← h.maximalIdeal_eq] +@[deprecated (since := "2026-07-09")] +alias maximalIdeal_pow_eq_setOf_le_v_algebraMap_pow := + maximalIdeal_pow_eq_setOfPred_le_v_algebraMap_pow + end Valuation.Integers section Valuation.integer variable {K Γ₀ : Type*} [Field K] [LinearOrderedCommGroupWithZero Γ₀] (v : Valuation K Γ₀) -lemma _root_.Irreducible.maximalIdeal_eq_setOf_le_v_coe +lemma _root_.Irreducible.maximalIdeal_eq_setOfPred_le_v_coe [IsDiscreteValuationRing v.integer] {ϖ : v.integer} (h : Irreducible ϖ) : (IsLocalRing.maximalIdeal v.integer : Set v.integer) = {y : v.integer | v y ≤ v ϖ} := - (Valuation.integer.integers v).maximalIdeal_eq_setOf_le_v_algebraMap h + (Valuation.integer.integers v).maximalIdeal_eq_setOfPred_le_v_algebraMap h -lemma _root_.Irreducible.maximalIdeal_pow_eq_setOf_le_v_coe_pow +@[deprecated (since := "2026-07-09")] +alias _root_.Irreducible.maximalIdeal_eq_setOf_le_v_coe := + _root_.Irreducible.maximalIdeal_eq_setOfPred_le_v_coe + +lemma _root_.Irreducible.maximalIdeal_pow_eq_setOfPred_le_v_coe_pow [IsDiscreteValuationRing v.integer] {ϖ : v.integer} (h : Irreducible ϖ) (n : ℕ) : ((IsLocalRing.maximalIdeal v.integer ^ n : Ideal v.integer) : Set v.integer) = {y : v.integer | v y ≤ v (ϖ : K) ^ n} := - (Valuation.integer.integers v).maximalIdeal_pow_eq_setOf_le_v_algebraMap_pow h _ + (Valuation.integer.integers v).maximalIdeal_pow_eq_setOfPred_le_v_algebraMap_pow h _ + +@[deprecated (since := "2026-07-09")] +alias _root_.Irreducible.maximalIdeal_pow_eq_setOf_le_v_coe_pow := + _root_.Irreducible.maximalIdeal_pow_eq_setOfPred_le_v_coe_pow end Valuation.integer diff --git a/Mathlib/RingTheory/DividedPowers/DPMorphism.lean b/Mathlib/RingTheory/DividedPowers/DPMorphism.lean index e09c1922e5521e..b232b405165571 100644 --- a/Mathlib/RingTheory/DividedPowers/DPMorphism.lean +++ b/Mathlib/RingTheory/DividedPowers/DPMorphism.lean @@ -139,7 +139,7 @@ set_option linter.style.whitespace false in -- manual alignment is not recognise def _root_.DividedPowers.ideal_from_ringHom {f : A →+* B} (hf : I.map f ≤ J) : Ideal A where carrier := {x ∈ I | ∀ n : ℕ, f (hI.dpow n (x : A)) = hJ.dpow n (f (x : A))} add_mem' := fun hx hy ↦ by - simp only [mem_setOf_eq, map_add] at hx hy ⊢ + simp only [mem_ofPred_eq, map_add] at hx hy ⊢ refine ⟨I.add_mem hx.1 hy.1, fun n ↦ ?_⟩ rw [hI.dpow_add hx.1 hy.1, map_sum, hJ.dpow_add (hf (mem_map_of_mem f hx.1)) (hf (mem_map_of_mem f hy.1))] @@ -147,7 +147,7 @@ def _root_.DividedPowers.ideal_from_ringHom {f : A →+* B} (hf : I.map f ≤ J) ext k rw [map_mul, hx.2, hy.2] zero_mem' := by - simp only [mem_setOf_eq, Submodule.zero_mem, map_zero, true_and] + simp only [mem_ofPred_eq, Submodule.zero_mem, map_zero, true_and] intro n induction n with | zero => rw [hI.dpow_zero I.zero_mem, hJ.dpow_zero J.zero_mem, map_one] diff --git a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean index 8ca315ed1a4528..a9253e9a6fa94b 100644 --- a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean +++ b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean @@ -430,7 +430,7 @@ theorem span_carrier_eq_dpow_span {S : Set A} (hS : S ⊆ I) : · rw [le_iInf₂_iff] intro K hK have : S ≤ K := by - simp only [Set.mem_insert_iff, Set.mem_setOf_eq] at hK + simp only [Set.mem_insert_iff, Set.mem_ofPred_eq] at hK rcases hK with rfl | hKS exacts [hS, hKS] rw [span_le] @@ -493,7 +493,7 @@ def dpEqualizer : Ideal A where theorem mem_dpEqualizer_iff {x : A} : x ∈ dpEqualizer hI hI' ↔ x ∈ I ∧ ∀ n : ℕ, hI.dpow n x = hI'.dpow n x := by simp [dpEqualizer, Submodule.mem_mk, AddSubmonoid.mem_mk, AddSubsemigroup.mem_mk, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] theorem dpEqualizer_is_dp_ideal_left : DividedPowers.IsSubDPIdeal hI (dpEqualizer hI hI') := diff --git a/Mathlib/RingTheory/Extension/Generators.lean b/Mathlib/RingTheory/Extension/Generators.lean index 861b6e6f8d6686..d36312d80dfd2a 100644 --- a/Mathlib/RingTheory/Extension/Generators.lean +++ b/Mathlib/RingTheory/Extension/Generators.lean @@ -162,7 +162,7 @@ noncomputable def ofSet {s : Set S} (hs : Algebra.adjoin R s = ⊤) : Generators R S s := by refine ofSurjective (Subtype.val : s → S) ?_ rwa [← AlgHom.range_eq_top, ← Algebra.adjoin_range_eq_range_aeval, - Subtype.range_coe_subtype, Set.setOf_mem_eq] + Subtype.range_coe_subtype, Set.ofPred_mem_eq] variable (R S) in /-- The `Generators` containing the whole algebra, which induces the canonical map `R[S] → S`. -/ diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index 346c6ccb601fa6..c9944661684578 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -127,7 +127,7 @@ theorem iff_quotient_freeAlgebra : · rintro ⟨s, hs⟩ refine ⟨s, FreeAlgebra.lift _ (↑), ?_⟩ rw [← Set.range_eq_univ, ← AlgHom.coe_range, ← adjoin_range_eq_range_freeAlgebra_lift, - Subtype.range_coe_subtype, Finset.setOf_mem, hs, coe_top] + Subtype.range_coe_subtype, Finset.setOfPred_mem, hs, coe_top] · rintro ⟨s, f, hsur⟩ exact .of_surjective f hsur @@ -191,7 +191,7 @@ theorem isNoetherianRing (R S : Type*) [CommRing R] [CommRing S] [Algebra R S] isNoetherianRing_of_surjective (MvPolynomial s R) S (MvPolynomial.aeval (↑) : MvPolynomial s R →ₐ[R] S).toRingHom rw [← Set.range_eq_univ, AlgHom.toRingHom_eq_coe, RingHom.coe_coe, ← AlgHom.coe_range, - ← Algebra.adjoin_range_eq_range_aeval, Subtype.range_coe_subtype, Finset.setOf_mem, hs] + ← Algebra.adjoin_range_eq_range_aeval, Subtype.range_coe_subtype, Finset.setOfPred_mem, hs] rfl theorem _root_.Subalgebra.fg_iff_finiteType (S : Subalgebra R A) : S.FG ↔ Algebra.FiniteType R S := diff --git a/Mathlib/RingTheory/FractionalIdeal/Basic.lean b/Mathlib/RingTheory/FractionalIdeal/Basic.lean index dfda75afb5880e..5d2b0bc60eb0bc 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Basic.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Basic.lean @@ -647,12 +647,12 @@ theorem le_one_iff_exists_coeIdeal {J : FractionalIdeal S P} : · intro hJ refine ⟨⟨⟨⟨{ x : R | algebraMap R P x ∈ J }, ?_⟩, ?_⟩, ?_⟩, ?_⟩ · intro a b ha hb - rw [mem_setOf, map_add] + rw [mem_ofPred, map_add] exact J.val.add_mem ha hb - · rw [mem_setOf, map_zero] + · rw [mem_ofPred, map_zero] exact J.zero_mem · intro c x hx - rw [smul_eq_mul, mem_setOf, map_mul, ← Algebra.smul_def] + rw [smul_eq_mul, mem_ofPred, map_mul, ← Algebra.smul_def] exact J.val.smul_mem c hx · ext x constructor @@ -660,7 +660,7 @@ theorem le_one_iff_exists_coeIdeal {J : FractionalIdeal S P} : rwa [← eq_y] · intro hx obtain ⟨y, rfl⟩ := (mem_one_iff S).mp (hJ hx) - exact mem_setOf.mpr ⟨y, hx, rfl⟩ + exact mem_ofPred.mpr ⟨y, hx, rfl⟩ · rintro ⟨I, hI⟩ rw [← hI] apply coeIdeal_le_one diff --git a/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean b/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean index fd5440a3dc7696..852d4ea0729973 100644 --- a/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean +++ b/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Ideal.lean @@ -175,7 +175,7 @@ is the largest homogeneous ideal of `A` contained in `I`. -/ def Ideal.homogeneousCore : HomogeneousIdeal 𝒜 := ⟨Ideal.homogeneousCore' 𝒜 I, Ideal.homogeneous_span _ _ fun _ h => by - have := Subtype.image_preimage_coe (setOf (SetLike.IsHomogeneousElem 𝒜)) (I : Set A) + have := Subtype.image_preimage_coe (Set.ofPred (SetLike.IsHomogeneousElem 𝒜)) (I : Set A) exact (cast congr(_ ∈ $this) h).1⟩ theorem Ideal.homogeneousCore_mono : Monotone (Ideal.homogeneousCore 𝒜) := @@ -456,7 +456,7 @@ theorem Ideal.homogeneousCore'_eq_sSup : have coe_mono : Monotone (toIdeal : HomogeneousIdeal 𝒜 → Ideal A) := fun x y => id convert! coe_mono.map_isGreatest (Ideal.homogeneousCore.gc 𝒜).isGreatest_u using 1 ext x - rw [mem_image, mem_setOf_eq] + rw [mem_image, mem_ofPred_eq] refine ⟨fun hI => ⟨⟨x, hI.1⟩, ⟨hI.2, rfl⟩⟩, ?_⟩ rintro ⟨x, ⟨hx, rfl⟩⟩ exact ⟨x.isHomogeneous, hx⟩ @@ -518,7 +518,7 @@ theorem Ideal.toIdeal_homogeneousHull_eq_iSup : rw [← Ideal.span_iUnion] apply congr_arg Ideal.span _ ext1 - simp only [Set.mem_iUnion, Set.mem_image, mem_setOf_eq, GradedRing.proj_apply, SetLike.exists, + simp only [Set.mem_iUnion, Set.mem_image, mem_ofPred_eq, GradedRing.proj_apply, SetLike.exists, exists_prop, SetLike.mem_coe] theorem Ideal.homogeneousHull_eq_iSup : diff --git a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean index 488f464e9c2012..e0c7c357ef885c 100644 --- a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean +++ b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean @@ -631,7 +631,7 @@ theorem Away.eventually_smul_mem {m} (hf : f ∈ 𝒜 m) (z : Away 𝒜 f) : obtain ⟨k, hk : f ^ k = _⟩ := z.den_mem apply Filter.mem_of_superset (Filter.Ici_mem_atTop k) rintro k' (hk' : k ≤ k') - simp only [Set.mem_image, SetLike.mem_coe, Set.mem_setOf_eq] + simp only [Set.mem_image, SetLike.mem_coe, Set.mem_ofPred_eq] by_cases hfk : f ^ k = 0 · refine ⟨0, zero_mem _, ?_⟩ rw [← tsub_add_cancel_of_le hk', map_zero, pow_add, hfk, mul_zero, zero_smul] diff --git a/Mathlib/RingTheory/HahnSeries/Lex.lean b/Mathlib/RingTheory/HahnSeries/Lex.lean index 73d3cff80661fe..49de3c51780614 100644 --- a/Mathlib/RingTheory/HahnSeries/Lex.lean +++ b/Mathlib/RingTheory/HahnSeries/Lex.lean @@ -57,9 +57,9 @@ instance : LinearOrder (Lex R⟦Γ⟧) where let v := {i : Γ | (ofLex a).coeff i ≠ (ofLex b).coeff i} have hvu : v ⊆ u := by intro i h - rw [Set.mem_union, Set.mem_setOf_eq, Set.mem_setOf_eq] + rw [Set.mem_union, Set.mem_ofPred_eq, Set.mem_ofPred_eq] contrapose! h - rw [Set.notMem_setOf_iff, not_not, h.1, h.2] + rw [Set.notMem_ofPred_iff, not_not, h.1, h.2] have hv : v.IsWF := ((ofLex a).isPWO_support'.isWF.union (ofLex b).isPWO_support'.isWF).subset hvu let i := hv.min hab diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 0a580f92788457..e152c4a7ab8a8c 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -186,7 +186,7 @@ instance instSMul : SMul R⟦Γ⟧ (HahnModule Γ' R V) where { a : Γ' | (VAddAntidiagonal a (Set.VAddAntidiagonal.finite_of_isPWO x.isPWO_support ((of R).symm y).isPWO_support a)).Nonempty } := by intro a ha - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] contrapose! ha simp [ha] (isPWO_support_vaddAntidiagonal x.isPWO_support ((of R).symm y).isPWO_support).mono h } @@ -346,7 +346,7 @@ theorem support_smul_subset_vadd_support' [MulZeroClass R] [SMulWithZero R V] {x ((of R).symm (x • y)).support ⊆ x.support +ᵥ ((of R).symm y).support := by refine Set.Subset.trans (fun x hx => ?_) (support_vaddAntidiagonal_subset_vadd fun a ↦ Set.VAddAntidiagonal.finite_of_isPWO x.isPWO_support ((of R).symm y).isPWO_support a) - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] contrapose! hx simp [coeff_smul, hx] @@ -679,7 +679,7 @@ def orderTopSubOnePos (Γ R) [LinearOrder Γ] [AddCommMonoid Γ] [IsOrderedCance intro x y hx hy obtain (_ | _) := subsingleton_or_nontrivial R · simp - · simp_all only [Set.mem_setOf_eq, orderTop_self_sub_one_pos_iff] + · simp_all only [Set.mem_ofPred_eq, orderTop_self_sub_one_pos_iff] have h1 : x.val.leadingCoeff * y.val.leadingCoeff = 1 := by rw [hx.2, hy.2, mul_one] constructor · rw [Units.val_mul, orderTop_mul_of_ne_zero (by simp [h1]), hx.1, hy.1, add_zero] @@ -1004,7 +1004,7 @@ instance [IsCancelAdd R] [IsCancelMulZero R] : IsCancelMulZero R⟦Γ⟧ where rintro b c - hxb hbc hbc' contrapose! hbc' rwa [eq_comm, eq_comm (a := c), ← add_eq_add_iff_eq_and_eq - (Set.IsWF.min_le this hyz ((Set.mem_setOf (p := fun a => y.coeff a ≠ z.coeff a)).mpr hbc')) + (Set.IsWF.min_le this hyz ((Set.mem_ofPred (p := fun a => y.coeff a ≠ z.coeff a)).mpr hbc')) (order_le_of_coeff_ne_zero hxb), eq_comm] · simp +contextual [← or_and_right] · simp +contextual [← or_and_right] diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index e650212e940b5e..2c082d95aabe11 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -152,7 +152,7 @@ instance : SMul M (SummableFamily Γ R β) := intro g refine (t.finite_co_support g).subset ?_ intro i hi - simp only [Pi.smul_apply, coeff_smul, ne_eq, Set.mem_setOf_eq] at hi + simp only [Pi.smul_apply, coeff_smul, ne_eq, Set.mem_ofPred_eq] at hi simp only [Function.mem_support, ne_eq] exact right_ne_zero_of_smul hi } ⟩ @@ -286,7 +286,7 @@ def smulFamily [AddCommMonoid V] [SMulWithZero R V] (f : α → R) (s : Summable exact Exists.intro i <| right_ne_zero_of_smul hi finite_co_support' g := by refine Set.Finite.subset (s.finite_co_support g) fun i hi => ?_ - simp_all only [coeff_smul, ne_eq, Set.mem_setOf_eq, Function.mem_support] + simp_all only [coeff_smul, ne_eq, Set.mem_ofPred_eq, Function.mem_support] exact right_ne_zero_of_smul hi theorem hsum_smulFamily [AddCommMonoid V] [SMulWithZero R V] (f : α → R) @@ -377,7 +377,7 @@ theorem smul_support_subset_prod (s : SummableFamily Γ R α) ((s.finite_co_support' gh.1).prod (t.finite_co_support' gh.2)).toFinset := by intro _ hab simp_all only [Function.mem_support, ne_eq, Set.Finite.coe_toFinset, Set.mem_prod, - Set.mem_setOf_eq] + Set.mem_ofPred_eq] exact ⟨left_ne_zero_of_smul hab, right_ne_zero_of_smul hab⟩ theorem hasFiniteSupport_smul (s : SummableFamily Γ R α) @@ -403,7 +403,7 @@ theorem isPWO_iUnion_support_prod_smul {s : α → R⟦Γ⟧} {t : β → V⟦Γ intro ab refine Set.Subset.trans (fun x hx => ?_) (support_vaddAntidiagonal_subset_vadd fun a ↦ Set.VAddAntidiagonal.finite_of_isPWO (s ab.1).isPWO_support (t ab.2).isPWO_support a) - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] contrapose! hx rw [mem_support, not_not, HahnModule.coeff_smul, hx, sum_empty] refine Set.Subset.trans (Set.iUnion_mono fun a => (hsupp a)) ?_ @@ -419,7 +419,7 @@ theorem finite_co_support_prod_smul (s : SummableFamily Γ R α) t.isPWO_iUnion_support g)).finite_toSet.biUnion' (fun gh _ => hasFiniteSupport_smul s t gh)).subset _ exact fun ab hab => by - simp only [ne_eq, Set.mem_setOf_eq] at hab + simp only [ne_eq, Set.mem_ofPred_eq] at hab obtain ⟨ij, hij⟩ := Finset.exists_ne_zero_of_sum_ne_zero hab simp only [mem_coe, mem_vaddAntidiagonal, Set.mem_iUnion, mem_support, ne_eq, Function.mem_support, exists_prop, Prod.exists] @@ -463,7 +463,7 @@ theorem coeff_smul {R} {V} [Semiring R] [AddCommMonoid V] [Module R V] have hsupp := smul_support_subset_prod s t gh simp_all only [mem_vaddAntidiagonal, Set.mem_iUnion, mem_support, ne_eq, Set.Finite.mem_toFinset, Function.mem_support, Set.Finite.coe_toFinset, support_subset_iff, Set.mem_prod, - Set.mem_setOf_eq, Prod.forall, coeff_support, mem_product] + Set.mem_ofPred_eq, Prod.forall, coeff_support, mem_product] exact hsupp ab.1 ab.2 hab set_option backward.isDefEq.respectTransparency false in @@ -627,9 +627,9 @@ def embDomain (s : SummableFamily Γ R α) (f : α ↪ β) : SummableFamily Γ R (by intro b h by_cases hb : b ∈ Set.range f - · simp only [Ne, Set.mem_setOf_eq, dif_pos hb] at h + · simp only [Ne, Set.mem_ofPred_eq, dif_pos hb] at h exact ⟨Classical.choose hb, h, Classical.choose_spec hb⟩ - · simp only [Ne, Set.mem_setOf_eq, dif_neg hb, coeff_zero, not_true_eq_false] at h) + · simp only [Ne, Set.mem_ofPred_eq, dif_neg hb, coeff_zero, not_true_eq_false] at h) variable (s : SummableFamily Γ R α) (f : α ↪ β) {a : α} {b : β} @@ -684,7 +684,7 @@ theorem isPWO_iUnion_support_powers [AddCommMonoid Γ] [LinearOrder Γ] [IsOrder theorem co_support_zero [AddCommMonoid Γ] [PartialOrder Γ] [IsOrderedCancelAddMonoid Γ] [Semiring R] (g : Γ) : {a | ¬((0 : R⟦Γ⟧) ^ a).coeff g = 0} ⊆ {0} := by - simp only [Set.subset_singleton_iff, Set.mem_setOf_eq] + simp only [Set.subset_singleton_iff, Set.mem_ofPred_eq] intro n hn by_contra h' simp_all only [ne_eq, not_false_eq_true, zero_pow, coeff_zero, not_true_eq_false] diff --git a/Mathlib/RingTheory/Ideal/Colon.lean b/Mathlib/RingTheory/Ideal/Colon.lean index 88cefc94603f37..0314583b7a14a1 100644 --- a/Mathlib/RingTheory/Ideal/Colon.lean +++ b/Mathlib/RingTheory/Ideal/Colon.lean @@ -38,7 +38,7 @@ def colon (N : Submodule R M) (S : Set M) : Ideal R where (Set.add_smul_subset _ _ _).trans ((Set.add_subset_add ha hb).trans_eq (by simp)) zero_mem' := (Set.zero_smul_set_subset S).trans (by simp) smul_mem' r := by - simp only [Set.mem_setOf_eq, smul_eq_mul, mul_smul, Set.smul_set_subset_iff] + simp only [Set.mem_ofPred_eq, smul_eq_mul, mul_smul, Set.smul_set_subset_iff] intro x hx y hy exact N.smul_mem _ (hx hy) diff --git a/Mathlib/RingTheory/Ideal/Defs.lean b/Mathlib/RingTheory/Ideal/Defs.lean index aee2dc55cc58e9..2bff77320cba98 100644 --- a/Mathlib/RingTheory/Ideal/Defs.lean +++ b/Mathlib/RingTheory/Ideal/Defs.lean @@ -94,7 +94,7 @@ with the kernel of `LinearMap.toSpanSingleton R M (m - m')`. -/ def Module.eqIdeal (R) {M} [Semiring R] [AddCommMonoid M] [Module R M] (m m' : M) : Ideal R where carrier := {r : R | r • m = r • m'} add_mem' h h' := by simpa [add_smul] using congr($h + $h') - zero_mem' := by simp_rw [Set.mem_setOf, zero_smul] + zero_mem' := by simp_rw [Set.mem_ofPred, zero_smul] smul_mem' _ _ h := by simpa [mul_smul] using congr(_ • $h) end Semiring diff --git a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean index d4c5ee7f5037c7..5de9b5b9eac1f9 100644 --- a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean +++ b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean @@ -51,7 +51,7 @@ lemma IsLocalRing.quotient_artinian_of_mem_minimalPrimes_of_isLocalRing have : Ring.KrullDimLE 0 (R ⧸ I) := Ring.krullDimLE_zero_iff.mpr fun J prime ↦ Ideal.isMaximal_of_isIntegral_of_isMaximal_comap _ <| by convert! IsLocalRing.maximalIdeal.isMaximal R - rw [Ideal.minimalPrimes, Set.mem_setOf] at hp + rw [Ideal.minimalPrimes, Set.mem_ofPred] at hp have := prime.comap (Ideal.Quotient.mk I) exact hp.eq_of_le ⟨this, .trans (by simp) (Ideal.ker_le_comap _)⟩ (le_maximalIdeal this.1) IsNoetherianRing.isArtinianRing_of_krullDimLE_zero diff --git a/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean b/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean index 9f8af8cee49c32..ad072169e4dd17 100644 --- a/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean +++ b/Mathlib/RingTheory/Ideal/MinimalPrime/Localization.lean @@ -41,7 +41,7 @@ variable {R S : Type*} [CommSemiring R] [CommSemiring S] {I J : Ideal R} theorem Ideal.iUnion_minimalPrimes : ⋃ p ∈ I.minimalPrimes, p = { x | ∃ y ∉ I.radical, x * y ∈ I.radical } := by ext x - simp only [Set.mem_iUnion, SetLike.mem_coe, exists_prop, Set.mem_setOf_eq] + simp only [Set.mem_iUnion, SetLike.mem_coe, exists_prop, Set.mem_ofPred_eq] constructor · rintro ⟨p, ⟨⟨hp₁, hp₂⟩, hp₃⟩, hxp⟩ have : p.map (algebraMap R (Localization.AtPrime p)) ≤ (I.map (algebraMap _ _)).radical := by diff --git a/Mathlib/RingTheory/Ideal/MinimalPrime/Noetherian.lean b/Mathlib/RingTheory/Ideal/MinimalPrime/Noetherian.lean index 8863003728235c..e5456ac21b324c 100644 --- a/Mathlib/RingTheory/Ideal/MinimalPrime/Noetherian.lean +++ b/Mathlib/RingTheory/Ideal/MinimalPrime/Noetherian.lean @@ -28,7 +28,7 @@ lemma Ideal.finite_minimalPrimes_of_isNoetherianRing (I : Ideal R) : by_contra hI obtain ⟨I : Ideal R, hI : ¬ I.minimalPrimes.Finite, hmax⟩ := set_has_maximal_iff_noetherian.mpr hR {I : Ideal R | ¬ I.minimalPrimes.Finite} ⟨I, hI⟩ - simp only [Set.mem_setOf_eq, not_imp_not] at hmax + simp only [Set.mem_ofPred_eq, not_imp_not] at hmax have h1 : ¬ I.IsPrime := by contrapose hI; simp [minimalPrimes_eq_subsingleton_self] have h2 : I ≠ ⊤ := by contrapose hI; simp [hI, minimalPrimes_top] obtain ⟨x, hx, y, hy, h⟩ := (not_isPrime_iff.mp h1).resolve_left h2 diff --git a/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean b/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean index 96a0b40221f664..8c6ce13b30c3a0 100644 --- a/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/AbsNorm.lean @@ -417,10 +417,10 @@ lemma exists_isMaximal_dvd_of_dvd_absNorm' exists_isMaximal_dvd_of_dvd_absNorm (Int.prime_iff_natAbs_prime.mpr (by simpa)) _ (by exact_mod_cast hI) -theorem finite_setOf_absNorm_eq [CharZero S] (n : ℕ) : +theorem finite_setOfPred_absNorm_eq [CharZero S] (n : ℕ) : {I : Ideal S | Ideal.absNorm I = n}.Finite := by obtain hn | hn := Nat.eq_zero_or_pos n - · simp only [hn, absNorm_eq_zero_iff, Set.setOf_eq_eq_singleton, Set.finite_singleton] + · simp only [hn, absNorm_eq_zero_iff, Set.ofPred_eq_eq_singleton, Set.finite_singleton] · let f := fun I : Ideal S => Ideal.map (Ideal.Quotient.mk (@Ideal.span S _ {↑n})) I refine Set.Finite.of_finite_image (f := f) ?_ ?_ · suffices Finite (S ⧸ @Ideal.span S _ {↑n}) by @@ -435,26 +435,33 @@ theorem finite_setOf_absNorm_eq [CharZero S] (n : ℕ) : comap_map_mk (span_singleton_absNorm_le J), ← hJ.symm] congr -theorem finite_setOf_absNorm_le [CharZero S] (n : ℕ) : +@[deprecated (since := "2026-07-09")] alias finite_setOf_absNorm_eq := finite_setOfPred_absNorm_eq + +theorem finite_setOfPred_absNorm_le [CharZero S] (n : ℕ) : {I : Ideal S | Ideal.absNorm I ≤ n}.Finite := by rw [show {I : Ideal S | Ideal.absNorm I ≤ n} = (⋃ i ∈ Set.Icc 0 n, {I : Ideal S | Ideal.absNorm I = i}) by ext; simp] - refine Set.Finite.biUnion (Set.finite_Icc 0 n) (fun i _ => Ideal.finite_setOf_absNorm_eq i) + refine Set.Finite.biUnion (Set.finite_Icc 0 n) (fun i _ => Ideal.finite_setOfPred_absNorm_eq i) + +@[deprecated (since := "2026-07-09")] alias finite_setOf_absNorm_le := finite_setOfPred_absNorm_le -theorem finite_setOf_absNorm_le₀ [CharZero S] (n : ℕ) : +theorem finite_setOfPred_absNorm_le₀ [CharZero S] (n : ℕ) : {I : (Ideal S)⁰ | Ideal.absNorm (I : Ideal S) ≤ n}.Finite := by have : Finite {I : Ideal S // I ∈ (Ideal S)⁰ ∧ absNorm I ≤ n} := - (finite_setOf_absNorm_le n).subset fun _ ⟨_, h⟩ ↦ h + (finite_setOfPred_absNorm_le n).subset fun _ ⟨_, h⟩ ↦ h exact Finite.of_equiv _ (Equiv.subtypeSubtypeEquivSubtypeInter _ (fun I ↦ absNorm I ≤ n)).symm +@[deprecated (since := "2026-07-09")] +alias finite_setOf_absNorm_le₀ := finite_setOfPred_absNorm_le₀ + theorem card_norm_le_eq_card_norm_le_add_one (n : ℕ) [CharZero S] : Nat.card {I : Ideal S // absNorm I ≤ n} = Nat.card {I : (Ideal S)⁰ // absNorm (I : Ideal S) ≤ n} + 1 := by classical have : Finite {I : Ideal S // I ∈ (Ideal S)⁰ ∧ absNorm I ≤ n} := - (finite_setOf_absNorm_le n).subset fun _ ⟨_, h⟩ ↦ h + (finite_setOfPred_absNorm_le n).subset fun _ ⟨_, h⟩ ↦ h have : Finite {I : Ideal S // I ∉ (Ideal S)⁰ ∧ absNorm I ≤ n} := - (finite_setOf_absNorm_le n).subset fun _ ⟨_, h⟩ ↦ h + (finite_setOfPred_absNorm_le n).subset fun _ ⟨_, h⟩ ↦ h rw [Nat.card_congr (Equiv.subtypeSubtypeEquivSubtypeInter (fun I ↦ I ∈ (Ideal S)⁰) (fun I ↦ absNorm I ≤ n))] let e : {I : Ideal S // absNorm I ≤ n} ≃ {I : Ideal S // I ∈ (Ideal S)⁰ ∧ absNorm I ≤ n} ⊕ diff --git a/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean b/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean index 656fc378d3e3d2..02bd7bbb6bdde3 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/HasFiniteQuotients.lean @@ -80,12 +80,14 @@ theorem cardQuot_pos (I : Ideal R) (hI : I ≠ ⊥) : 0 < I.cardQuot := by rw [Submodule.cardQuot_apply] exact Nat.card_pos -theorem finite_setOf_mem (x : R) (hx : x ≠ 0) : {I : Ideal R | x ∈ I}.Finite := by +theorem finite_setOfPred_mem (x : R) (hx : x ≠ 0) : {I : Ideal R | x ∈ I}.Finite := by have := finiteQuotient (mt Ideal.span_singleton_eq_bot.mp hx) have : {I | Ideal.comap (Ideal.Quotient.mk (Ideal.span {x})) ⊥ ≤ I}.Finite := .of_equiv _ (Ideal.relIsoOfSurjective _ Ideal.Quotient.mk_surjective).toEquiv simpa [← RingHom.ker_eq_comap_bot] using this +@[deprecated (since := "2026-07-09")] alias finite_setOf_mem := finite_setOfPred_mem + open scoped Pointwise in /-- For every bound `B`, a ring with finite quotients has only finitely many ideals of norm bounded by `B`. -/ @@ -101,10 +103,10 @@ theorem finite_cardQuot_le (B : ℕ) : {I : Ideal R | I.cardQuot ≤ B}.Finite : -- in a ring with finite quotients, each nonzero element is contained in only finitely many ideals -- so it is enough to show that each ideal `I` of norm at most `B` contains some element of `t` suffices {I | Submodule.cardQuot I ≤ B} \ {⊥} ⊆ ⋃ x ∈ t, {I | x ∈ I} from - (t.finite_toSet.biUnion fun x hx ↦ finite_setOf_mem x (by grind)).subset this + (t.finite_toSet.biUnion fun x hx ↦ finite_setOfPred_mem x (by grind)).subset this intro I hI - rw [Set.mem_sdiff, Set.mem_setOf, Submodule.cardQuot_apply] at hI - simp_rw [Set.mem_iUnion, exists_prop, Set.mem_setOf_eq] + rw [Set.mem_sdiff, Set.mem_ofPred, Submodule.cardQuot_apply] at hI + simp_rw [Set.mem_iUnion, exists_prop, Set.mem_ofPred_eq] -- `s` has cardinality `B + 1`, but the quotient `R ⧸ I` has cardinality at most `B` replace hs : (s.image (Ideal.Quotient.mk I)).card < s.card := by have := finiteQuotient hI.2 diff --git a/Mathlib/RingTheory/Ideal/Span.lean b/Mathlib/RingTheory/Ideal/Span.lean index dac38b8076649d..ab0d0df7f1a1c2 100644 --- a/Mathlib/RingTheory/Ideal/Span.lean +++ b/Mathlib/RingTheory/Ideal/Span.lean @@ -169,7 +169,7 @@ lemma span_range_eq_span_range_support (x : ι → α) : congr ext1 a simp only [mem_sdiff, mem_range, mem_singleton_iff] - exact ⟨fun ⟨⟨i, hi⟩, ha⟩ ↦ ⟨⟨i, mem_setOf.mpr (hi ▸ ha)⟩, hi⟩, + exact ⟨fun ⟨⟨i, hi⟩, ha⟩ ↦ ⟨⟨i, mem_ofPred.mpr (hi ▸ ha)⟩, hi⟩, fun ⟨j, hj⟩ ↦ ⟨⟨j.val, hj⟩, by grind⟩⟩ end Semiring diff --git a/Mathlib/RingTheory/IntegralClosure/GoingDown.lean b/Mathlib/RingTheory/IntegralClosure/GoingDown.lean index a42ee0f39c77a2..45ce638b399779 100644 --- a/Mathlib/RingTheory/IntegralClosure/GoingDown.lean +++ b/Mathlib/RingTheory/IntegralClosure/GoingDown.lean @@ -82,7 +82,7 @@ instance [IsDomain S] [FaithfulSMul R S] [Algebra.IsIntegral R S] [IsIntegrallyC (minpoly.isIntegrallyClosed_dvd (Algebra.IsIntegral.isIntegral _) hfa) simp only [IsIntegrallyClosed.minpoly_smul hx0 (Algebra.IsIntegral.isIntegral _), natDegree_scaleRoots, coeff_scaleRoots, Ideal.radical_eq_sInf, Submodule.mem_sInf, - Set.mem_setOf_eq, and_imp] at this + Set.mem_ofPred_eq, and_imp] at this refine ‹p.IsPrime›.mem_of_pow_mem _ ((‹p.IsPrime›.mem_or_mem (this i hi p ?_ inferInstance)).resolve_left hip) simp +contextual [Ideal.span_le, Set.subset_def, LT.lt.ne, hf] diff --git a/Mathlib/RingTheory/Jacobson/Radical.lean b/Mathlib/RingTheory/Jacobson/Radical.lean index cea9cb8d9c956f..0713b35171cb4c 100644 --- a/Mathlib/RingTheory/Jacobson/Radical.lean +++ b/Mathlib/RingTheory/Jacobson/Radical.lean @@ -99,7 +99,7 @@ theorem jacobson_quotient_jacobson : jacobson R (M ⧸ jacobson R M) = ⊥ := by theorem jacobson_lt_top [Nontrivial M] [IsCoatomic (Submodule R M)] : jacobson R M < ⊤ := by obtain ⟨m, hm, -⟩ := (eq_top_or_exists_le_coatom (⊥ : Submodule R M)).resolve_left bot_ne_top - exact (sInf_le <| Set.mem_setOf.mpr hm).trans_lt hm.1.lt_top + exact (sInf_le <| Set.mem_ofPred.mpr hm).trans_lt hm.1.lt_top example [Nontrivial M] [Module.Finite R M] : jacobson R M < ⊤ := jacobson_lt_top R M diff --git a/Mathlib/RingTheory/Jacobson/Ring.lean b/Mathlib/RingTheory/Jacobson/Ring.lean index 7ac3933093829f..a9cc0fb1bb631a 100644 --- a/Mathlib/RingTheory/Jacobson/Ring.lean +++ b/Mathlib/RingTheory/Jacobson/Ring.lean @@ -76,7 +76,7 @@ theorem isJacobsonRing_iff_prime_eq : refine fun h I hI ↦ le_antisymm (fun x hx ↦ ?_) (fun x hx ↦ mem_sInf.mpr fun _ hJ ↦ hJ.left hx) rw [← hI.radical, radical_eq_sInf I, mem_sInf] intro P hP - rw [Set.mem_setOf_eq] at hP + rw [Set.mem_ofPred_eq] at hP rw [jacobson, mem_sInf] at hx rw [← h P hP.right, jacobson, mem_sInf] exact fun J hJ => hx ⟨le_trans hP.left hJ.left, hJ.right⟩ @@ -136,7 +136,7 @@ theorem isJacobsonRing_of_isIntegral [Algebra R S] [Algebra.IsIntegral R S] [IsJ ((isJacobsonRing_iff_prime_eq.1 ‹_›) (comap (algebraMap R S) P) (comap_isPrime _ _)), comap_jacobson] refine sInf_le_sInf fun J hJ => ?_ - simp only [true_and, Set.mem_image, bot_le, Set.mem_setOf_eq] + simp only [true_and, Set.mem_image, bot_le, Set.mem_ofPred_eq] have : J.IsMaximal := by simpa using hJ exact exists_ideal_over_maximal_of_isIntegral J (comap_bot_le_of_injective _ algebraMap_quotient_injective) diff --git a/Mathlib/RingTheory/KrullDimension/PID.lean b/Mathlib/RingTheory/KrullDimension/PID.lean index 370302852f63ef..73b8b5a551713e 100644 --- a/Mathlib/RingTheory/KrullDimension/PID.lean +++ b/Mathlib/RingTheory/KrullDimension/PID.lean @@ -20,7 +20,7 @@ public section instance IsPrincipalIdealRing.krullDimLE_one (R : Type*) [CommRing R] [IsPrincipalIdealRing R] : Ring.KrullDimLE 1 R := by refine Ring.krullDimLE_one_iff.2 fun I hI ↦ or_iff_not_imp_left.2 fun hI' ↦ ?_ - rw [minimalPrimes_eq_minimals, Set.notMem_setOf_iff, not_minimal_iff_exists_lt hI] at hI' + rw [minimalPrimes_eq_minimals, Set.notMem_ofPred_iff, not_minimal_iff_exists_lt hI] at hI' obtain ⟨P, hlt, hP⟩ := hI' have := IsPrincipalIdealRing.of_surjective (Ideal.Quotient.mk P) Ideal.Quotient.mk_surjective have : (I.map (Ideal.Quotient.mk P)).IsMaximal := by diff --git a/Mathlib/RingTheory/KrullDimension/Zero.lean b/Mathlib/RingTheory/KrullDimension/Zero.lean index 1971d6da9a135e..2e48f38c29aeab 100644 --- a/Mathlib/RingTheory/KrullDimension/Zero.lean +++ b/Mathlib/RingTheory/KrullDimension/Zero.lean @@ -32,15 +32,23 @@ lemma Ring.KrullDimLE.mem_minimalPrimes_iff_le_of_isPrime {I J : Ideal R} [I.IsP rwa [mem_minimalPrimes_iff, and_iff_right] variable (R) in -lemma Ring.KrullDimLE.minimalPrimes_eq_setOf_isPrime : +lemma Ring.KrullDimLE.minimalPrimes_eq_setOfPred_isPrime : minimalPrimes R = { I | I.IsPrime } := by ext exact Ideal.mem_minimalPrimes_iff_isPrime +@[deprecated (since := "2026-07-09")] +alias Ring.KrullDimLE.minimalPrimes_eq_setOf_isPrime := + Ring.KrullDimLE.minimalPrimes_eq_setOfPred_isPrime + variable (R) in -lemma Ring.KrullDimLE.minimalPrimes_eq_setOf_isMaximal : +lemma Ring.KrullDimLE.minimalPrimes_eq_setOfPred_isMaximal : minimalPrimes R = { I | I.IsMaximal } := by - ext; simp [minimalPrimes_eq_setOf_isPrime, Ideal.isMaximal_iff_isPrime] + ext; simp [minimalPrimes_eq_setOfPred_isPrime, Ideal.isMaximal_iff_isPrime] + +@[deprecated (since := "2026-07-09")] +alias Ring.KrullDimLE.minimalPrimes_eq_setOf_isMaximal := + Ring.KrullDimLE.minimalPrimes_eq_setOfPred_isMaximal /-- Note that the `ringKrullDim` of the trivial ring is `⊥` and not `0`. -/ example [Subsingleton R] : Ring.KrullDimLE 0 R := inferInstance diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index a5167ec91df88e..f167b704b1dc4e 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -772,7 +772,7 @@ theorem Cauchy.coeff_eventually_equal {ℱ : Filter K⸨X⸩} (hℱ : Cauchy ℱ rw [Filter.eventually_iff] at this convert! this ext - simp only [Set.mem_iInter, Set.mem_setOf_eq]; rfl + simp only [Set.mem_iInter, Set.mem_ofPred_eq]; rfl · rw [biInter_mem (Set.finite_Icc ℓ N)] intro i _ apply (coeff_tendsto hℱ _).eventually @@ -886,7 +886,7 @@ theorem coe_range_dense : DenseRange ((↑) : K⟮X⟯ → K⸨X⸩) := by apply hT₁ apply hγ simpa only [Units.coe_map, MonoidHom.coe_mk, ZeroHom.toFun_eq_coe, OneHom.coe_mk, add_comm, - MonoidWithZeroHom.toZeroHom_coe, ← sub_eq_add_neg, Set.mem_setOf_eq, + MonoidWithZeroHom.toZeroHom_coe, ← sub_eq_add_neg, Set.mem_ofPred_eq, Valuation.restrict_lt_iff_lt_embedding] end Dense @@ -909,7 +909,7 @@ set_option backward.isDefEq.respectTransparency.types false in theorem inducing_coe : IsUniformInducing ((↑) : K⟮X⟯ → K⸨X⸩) := by rw [isUniformInducing_iff, Filter.comap] ext S - simp only [Filter.mem_mk, Set.mem_setOf_eq, uniformity_eq_comap_nhds_zero, + simp only [Filter.mem_mk, Set.mem_ofPred_eq, uniformity_eq_comap_nhds_zero, Filter.mem_comap] constructor · rintro ⟨T, ⟨⟨R, ⟨hR, pre_R⟩⟩, pre_T⟩⟩ @@ -922,7 +922,7 @@ theorem inducing_coe : IsUniformInducing ((↑) : K⟮X⟯ → K⸨X⸩) := by rw [Valuation.restrict_def, ne_eq, restrict₀_eq_zero_iff]; simp [hx]) simp [v_def, Valuation.restrict_lt_iff, ← hx] apply hd - simp only [sub_zero, Set.mem_setOf_eq] + simp only [sub_zero, Set.mem_ofPred_eq] rw [← map_sub, Valuation.restrict_lt_iff_lt_embedding] simp only [valuation_def] rwa [← valuation_eq_LaurentSeries_valuation] @@ -939,12 +939,12 @@ theorem inducing_coe : IsUniformInducing ((↑) : K⟮X⟯ → K⸨X⸩) := by simp only [h, map_zero] at hx exact Units.ne_zero _ hx.symm) simp only [Units.val_mk0, ← Valuation.restrict_lt_iff_lt_embedding, - X_def, Set.setOf_subset_setOf, Valuation.restrict_lt_iff] + X_def, Set.ofPred_subset_ofPred, Valuation.restrict_lt_iff] rw [← hx, embedding_restrict₀] simp [v_def, valuation_coe_ratFunc] · refine subset_trans (fun _ _ ↦ ?_) pre_T apply hd - rw [Set.mem_setOf_eq, sub_zero, Valuation.restrict_lt_iff_lt_embedding, v_def, + rw [Set.mem_ofPred_eq, sub_zero, Valuation.restrict_lt_iff_lt_embedding, v_def, valuation_eq_LaurentSeries_valuation, map_sub] assumption @@ -1095,7 +1095,7 @@ theorem tendsto_valuation (a : (idealX K).adicCompletion K⟮X⟯) : · rw [WithZeroTopology.tendsto_of_ne_zero ((Valuation.ne_zero_iff Valued.v).mpr ha), Filter.eventually_comap, Filter.Eventually, Valued.mem_nhds] use Units.mk0 (Valued.v.restrict a) (by simp [Valuation.restrict_def, ha]) - simp only [Units.val_mk0, v_def, Set.setOf_subset_setOf] + simp only [Units.val_mk0, v_def, Set.ofPred_subset_ofPred] rintro y val_y b rfl rw [← valuedAdicCompletion_eq_valuation'] exact (Valuation.restrict_inj _).mp <| Valuation.map_eq_of_sub_lt Valued.v.restrict val_y diff --git a/Mathlib/RingTheory/LocalIso.lean b/Mathlib/RingTheory/LocalIso.lean index ac833ffa208833..2c537368c1e94b 100644 --- a/Mathlib/RingTheory/LocalIso.lean +++ b/Mathlib/RingTheory/LocalIso.lean @@ -142,11 +142,11 @@ lemma trans [Algebra S T] [Algebra R T] [IsScalarTower R S T] rw [Ideal.map_top, Ideal.map_span] at h1 nth_rw 1 [_root_.eq_top_iff, ← Ideal.top_mul ⊤, ← h1, ← span_isStandardOpenImmersion_eq_top S T, Ideal.span_mul_span, Ideal.span_le, Set.mul_subset_iff] - simp only [Set.mem_image, Set.mem_setOf_eq, SetLike.mem_coe, forall_exists_index, and_imp, + simp only [Set.mem_image, Set.mem_ofPred_eq, SetLike.mem_coe, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] intro g hg x hx refine Ideal.subset_span ⟨⟨⟨g, hg⟩, ⟨x, ?_⟩⟩, rfl⟩ - simp only [Set.mem_setOf_eq, t] + simp only [Set.mem_ofPred_eq, t] let : Algebra (Localization.Away x) (T'' g x) := localizationAlgebra (.powers x) (T' g) have : IsScalarTower S (Localization.Away x) (T'' g x) := @@ -177,7 +177,7 @@ instance [Algebra R T] [IsLocalIso R S] : IsLocalIso T (T ⊗[R] S) := by Ideal.map_le_iff_le_comap, Ideal.span_le] intro g hg apply Ideal.subset_span - simp only [Set.mem_setOf_eq] at hg ⊢ + simp only [Set.mem_ofPred_eq] at hg ⊢ exact .of_algEquiv <| IsLocalization.Away.tensorProductEquivTMulRight R T g (Localization.Away g) end Algebra.IsLocalIso diff --git a/Mathlib/RingTheory/Localization/AtPrime/Basic.lean b/Mathlib/RingTheory/Localization/AtPrime/Basic.lean index 235578219a2783..aac86dcebbdbd6 100644 --- a/Mathlib/RingTheory/Localization/AtPrime/Basic.lean +++ b/Mathlib/RingTheory/Localization/AtPrime/Basic.lean @@ -144,7 +144,8 @@ set_option backward.isDefEq.respectTransparency false in order-preserving bijection with the prime ideals contained in I. -/ @[simps!] def orderIsoOfPrime : { p : Ideal S // p.IsPrime } ≃o { p : Ideal R // p.IsPrime ∧ p ≤ I } := - (IsLocalization.orderIsoOfPrime I.primeCompl S).trans <| .setCongr _ _ <| show setOf _ = setOf _ + (IsLocalization.orderIsoOfPrime I.primeCompl S).trans <| .setCongr _ _ <| + show Set.ofPred _ = Set.ofPred _ by ext; simp [Ideal.primeCompl, ← le_compl_iff_disjoint_left] /-- The prime spectrum of the localization of a commutative ring R at a prime ideal I are in diff --git a/Mathlib/RingTheory/MvPolynomial/Basic.lean b/Mathlib/RingTheory/MvPolynomial/Basic.lean index 86708fc1d603ab..de7e7075485c09 100644 --- a/Mathlib/RingTheory/MvPolynomial/Basic.lean +++ b/Mathlib/RingTheory/MvPolynomial/Basic.lean @@ -216,15 +216,16 @@ theorem linearIndependent_X : LinearIndependent R (X : σ → MvPolynomial σ R) (basisMonomials σ R).linearIndependent.comp (fun s : σ => Finsupp.single s 1) (Finsupp.single_left_injective one_ne_zero) -private lemma finite_setOf_bounded (α) [Finite α] (n : ℕ) : Finite {f : α →₀ ℕ | ∀ a, f a ≤ n} := +private lemma finite_setOfPred_bounded (α) [Finite α] (n : ℕ) : + Finite {f : α →₀ ℕ | ∀ a, f a ≤ n} := ((Set.Finite.pi' fun _ ↦ Set.finite_le_nat _).preimage DFunLike.coe_injective.injOn).to_subtype instance [Finite σ] (N : ℕ) : Module.Finite R (restrictDegree σ R N) := - have := finite_setOf_bounded σ N + have := finite_setOfPred_bounded σ N Module.Finite.of_basis (basisRestrictSupport R _) instance [Finite σ] (N : ℕ) : Module.Finite R (restrictTotalDegree σ R N) := - have := finite_setOf_bounded σ N + have := finite_setOfPred_bounded σ N have : Finite {s : σ →₀ ℕ | s.sum (fun _ e ↦ e) ≤ N} := by rw [Set.finite_coe_iff] at this ⊢ exact this.subset fun n hn i ↦ (eq_or_ne (n i) 0).elim diff --git a/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean b/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean index 4b8c64bb0560c9..bad7ba74f75f7a 100644 --- a/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean +++ b/Mathlib/RingTheory/MvPolynomial/EulerIdentity.lean @@ -65,7 +65,7 @@ theorem IsWeightedHomogeneous.sum_weight_X_mul_pderiv {w : σ → ℕ} · rintro _ ⟨m, hm, rfl⟩ simp_rw [single_eq_monomial, X_mul_pderiv_monomial, smul_smul, ← sum_smul, mul_comm (w _)] congr - rwa [Set.mem_setOf, weight_apply, sum_fintype] at hm + rwa [Set.mem_ofPred, weight_apply, sum_fintype] at hm intro; apply zero_smul · simp · simp_rw [map_add, left_distrib, smul_add, sum_add_distrib, hp, hq] diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean index 23117f70b6d56d..524881370bfe81 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/Defs.lean @@ -106,7 +106,7 @@ def IsSymmetric [CommSemiring R] (φ : MvPolynomial σ R) : Prop := /-- The subalgebra of symmetric `MvPolynomial`s. -/ def symmetricSubalgebra (σ R : Type*) [CommSemiring R] : Subalgebra R (MvPolynomial σ R) where - carrier := setOf IsSymmetric + carrier := Set.ofPred IsSymmetric algebraMap_mem' r e := rename_C e r mul_mem' ha hb e := by rw [map_mul, ha, hb] add_mem' ha hb e := by rw [map_add, ha, hb] diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean index 72e045dbcdd960..b8d00a5b595c78 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/NewtonIdentities.lean @@ -249,7 +249,7 @@ the elementary symmetric polynomials and would like to calculate the values of t theorem psum_eq_mul_esymm_sub_sum (k : ℕ) (h : 0 < k) : psum σ R k = (-1) ^ (k + 1) * k * esymm σ R k - ∑ a ∈ antidiagonal k with a.1 ∈ Set.Ioo 0 k, (-1) ^ a.fst * esymm σ R a.1 * psum σ R a.2 := by - simp only [Set.Ioo, Set.mem_setOf_eq, and_comm] + simp only [Set.Ioo, Set.mem_ofPred_eq, and_comm] have hesymm := mul_esymm_eq_sum σ R k rw [← (sum_filter_add_sum_filter_not {a ∈ antidiagonal k | a.fst < k} (fun a ↦ 0 < a.fst) (fun a ↦ (-1) ^ a.fst * esymm σ R a.fst * psum σ R a.snd))] at hesymm diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index a52c19555e5012..b76f313a3f73a3 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -335,7 +335,7 @@ lemma induction_on {w : σ → M} {m : M} rw [Set.image_subset_iff] intro d hd simp only [MvPolynomial, Submodule.coe_set_mk, AddSubmonoid.coe_set_mk, - AddSubsemigroup.coe_set_mk, preimage_setOf_eq, mem_setOf_eq, A] + AddSubsemigroup.coe_set_mk, preimage_ofPred_eq, mem_ofPred_eq, A] refine ⟨isWeightedHomogeneous_monomial w d 1 hd, fun a ↦ ?_⟩ simpa only [single_eq_monomial, ← MvPolynomial.C_mul_monomial] using monomial _ (a * 1) hd diff --git a/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean b/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean index 7070eac7e14331..19af3d3b6f8383 100644 --- a/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/LinearTopology.lean @@ -92,7 +92,7 @@ theorem basis_le_iff {J K : TwoSidedIdeal R} {d e : σ →₀ ℕ} (hK : K ≠ basis σ R ⟨J, d⟩ ≤ basis σ R ⟨K, e⟩ ↔ J ≤ K ∧ e ≤ d := by classical constructor - · simp only [basis, TwoSidedIdeal.le_iff, TwoSidedIdeal.coe_mk', setOf_subset_setOf] + · simp only [basis, TwoSidedIdeal.le_iff, TwoSidedIdeal.coe_mk', ofPred_subset_ofPred] intro h constructor · intro x hx diff --git a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean index 809896a14082fd..8c166287fb5f29 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean @@ -139,7 +139,7 @@ theorem HasSubst.smul_X (a : σ → R) : /-- Families of `MvPowerSeries` that can be substituted, as an `Ideal` -/ noncomputable def hasSubstIdeal : Ideal (σ → MvPowerSeries τ S) := - { carrier := setOf HasSubst + { carrier := Set.ofPred HasSubst add_mem' := HasSubst.add zero_mem' := HasSubst.zero smul_mem' := HasSubst.mul_left } diff --git a/Mathlib/RingTheory/Noetherian/UniqueFactorizationDomain.lean b/Mathlib/RingTheory/Noetherian/UniqueFactorizationDomain.lean index 6f8df5c4e76863..feb875a2bc7d68 100644 --- a/Mathlib/RingTheory/Noetherian/UniqueFactorizationDomain.lean +++ b/Mathlib/RingTheory/Noetherian/UniqueFactorizationDomain.lean @@ -22,4 +22,4 @@ variable {R : Type*} [CommSemiring R] [IsDomain R] -- see Note [lower instance priority] instance (priority := 100) IsNoetherianRing.wfDvdMonoid [h : IsNoetherianRing R] : WfDvdMonoid R := - WfDvdMonoid.of_setOf_isPrincipal_wellFoundedOn_gt h.wf.wellFoundedOn + WfDvdMonoid.of_setOfPred_isPrincipal_wellFoundedOn_gt h.wf.wellFoundedOn diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index efa067a2e4aa17..7b930a899e740a 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -681,7 +681,7 @@ theorem mem_span_C_coeff : f ∈ Ideal.span { g : R[X] | ∃ i : ℕ, g = C (coe dsimp have : C (coeff f n) ∈ p := by apply subset_span - rw [mem_setOf_eq] + rw [mem_ofPred_eq] use n have : monomial n (1 : R) • C (coeff f n) ∈ p := p.smul_mem _ this convert! this using 1 diff --git a/Mathlib/RingTheory/Polynomial/Dickson.lean b/Mathlib/RingTheory/Polynomial/Dickson.lean index d9f18bf30d1bac..017eea147a0bdd 100644 --- a/Mathlib/RingTheory/Polynomial/Dickson.lean +++ b/Mathlib/RingTheory/Polynomial/Dickson.lean @@ -221,7 +221,7 @@ theorem dickson_one_one_zmod_p (p : ℕ) [Fact p.Prime] : dickson 1 (1 : ZMod p) -- The two polynomials agree on all `x` of the form `x = y + y⁻¹`. apply @Set.Infinite.mono _ { x : K | ∃ y, x = y + y⁻¹ ∧ y ≠ 0 } · rintro _ ⟨x, rfl, hx⟩ - simp only [eval_X, eval_pow, Set.mem_setOf_eq, ZMod.cast_one', add_pow_char, + simp only [eval_X, eval_pow, Set.mem_ofPred_eq, ZMod.cast_one', add_pow_char, dickson_one_one_eval_add_inv _ _ (mul_inv_cancel₀ hx), ZMod.castHom_apply] -- Now we need to show that the set of such `x` is infinite. -- If the set is finite, then we will show that `K` is also finite. @@ -247,7 +247,7 @@ theorem dickson_one_one_zmod_p (p : ℕ) [Fact p.Prime] : dickson 1 (1 : ZMod p) classical convert! (φ.roots ∪ {0}).toFinset.finite_toSet using 1 ext1 y - simp only [φ, Multiset.mem_toFinset, Set.mem_setOf_eq, Finset.mem_coe, Multiset.mem_union, + simp only [φ, Multiset.mem_toFinset, Set.mem_ofPred_eq, Finset.mem_coe, Multiset.mem_union, mem_roots hφ, IsRoot, eval_add, eval_sub, eval_pow, eval_mul, eval_X, eval_C, eval_one, Multiset.mem_singleton] by_cases hy : y = 0 @@ -259,7 +259,7 @@ theorem dickson_one_one_zmod_p (p : ℕ) [Fact p.Prime] : dickson 1 (1 : ZMod p) -- Finally, we prove the claim that our finite union of finite sets covers all of `K`. apply (Set.eq_univ_of_forall _).symm intro x - simp only [exists_prop, Set.mem_iUnion, Ne, Set.mem_setOf_eq] + simp only [exists_prop, Set.mem_iUnion, Ne, Set.mem_ofPred_eq] by_cases hx : x = 0 · simp only [hx, and_true, inv_zero, or_true] exact ⟨_, 1, rfl, one_ne_zero⟩ diff --git a/Mathlib/RingTheory/Polynomial/GaussNorm.lean b/Mathlib/RingTheory/Polynomial/GaussNorm.lean index 20399d9bb6064b..fcd123b823d782 100644 --- a/Mathlib/RingTheory/Polynomial/GaussNorm.lean +++ b/Mathlib/RingTheory/Polynomial/GaussNorm.lean @@ -159,10 +159,10 @@ lemma exists_min_eq_gaussNorm (p : R[X]) (hc : 0 ≤ c) : ∀ j, j < i → v (p.coeff j) * c ^ j < p.gaussNorm v c := by have h_nonempty : {i | gaussNorm v c p = v (p.coeff i) * c ^ i}.Nonempty := by obtain ⟨i, hi⟩ := exists_eq_gaussNorm v c p - exact ⟨i, Set.mem_setOf.mpr hi⟩ + exact ⟨i, Set.mem_ofPred.mpr hi⟩ refine ⟨Nat.find h_nonempty, Nat.find_spec h_nonempty, ?_⟩ intro j hj_lt - simp only [Nat.lt_find_iff, Set.mem_setOf_eq] at hj_lt + simp only [Nat.lt_find_iff, Set.mem_ofPred_eq] at hj_lt exact lt_of_le_of_ne (le_gaussNorm v _ hc j) fun a ↦ hj_lt j (Nat.le_refl j) a.symm /-- If `v` is a nonnegative nonarchimedean function with `v 0 = 0` and `c` is nonnegative, the diff --git a/Mathlib/RingTheory/Polynomial/HilbertPoly.lean b/Mathlib/RingTheory/Polynomial/HilbertPoly.lean index 5eb64277585043..90e7094936dae5 100644 --- a/Mathlib/RingTheory/Polynomial/HilbertPoly.lean +++ b/Mathlib/RingTheory/Polynomial/HilbertPoly.lean @@ -202,7 +202,7 @@ theorem existsUnique_hilbertPoly (p : F[X]) (d : ℕ) : apply eq_of_infinite_eval_eq h (hilbertPoly p d) apply ((Set.Ioi_infinite (max N p.natDegree)).image cast_injective.injOn).mono rintro x ⟨n, hn, rfl⟩ - simp only [Set.mem_Ioi, sup_lt_iff, Set.mem_setOf_eq] at hn ⊢ + simp only [Set.mem_Ioi, sup_lt_iff, Set.mem_ofPred_eq] at hn ⊢ rw [← coeff_mul_invOneSubPow_eq_hilbertPoly_eval d hn.2, hhN n hn.1] /-- diff --git a/Mathlib/RingTheory/PolynomialLaw/Basic.lean b/Mathlib/RingTheory/PolynomialLaw/Basic.lean index 8fd6ea554c4401..d6a7974199da89 100644 --- a/Mathlib/RingTheory/PolynomialLaw/Basic.lean +++ b/Mathlib/RingTheory/PolynomialLaw/Basic.lean @@ -315,7 +315,7 @@ theorem range_φ (s : Finset S) : (φ R s).range = Algebra.adjoin R s := by rw [← Algebra.adjoin_range_eq_range_aeval] congr rw [← Function.comp_def, Set.range_comp] - simp only [Equiv.range_eq_univ, Set.image_univ, Subtype.range_coe_subtype, Finset.setOf_mem] + simp only [Equiv.range_eq_univ, Set.image_univ, Subtype.range_coe_subtype, Finset.setOfPred_mem] variable (S) diff --git a/Mathlib/RingTheory/PowerSeries/Restricted.lean b/Mathlib/RingTheory/PowerSeries/Restricted.lean index 195cbe963fc699..aa9376d8e9906e 100644 --- a/Mathlib/RingTheory/PowerSeries/Restricted.lean +++ b/Mathlib/RingTheory/PowerSeries/Restricted.lean @@ -100,7 +100,7 @@ lemma convergenceSet_BddAbove {f : PowerSeries R} (hf : IsRestricted c f) : obtain ⟨N, hf⟩ := by simpa using (hf 1) rw [bddAbove_def, convergenceSet] use max 1 (max' (image (fun i ↦ ‖coeff i f‖ * c ^ i) (range (N + 1))) (by simp)) - simp only [Set.mem_setOf_eq, le_sup_iff, forall_exists_index, forall_apply_eq_imp_iff] + simp only [Set.mem_ofPred_eq, le_sup_iff, forall_exists_index, forall_apply_eq_imp_iff] intro i rcases le_total i N with h | h · right @@ -121,7 +121,7 @@ lemma mul {f g : PowerSeries R} (hf : IsRestricted c f) (hg : IsRestricted c g) ((isRestricted_iff_abs c f).mp hf)) obtain ⟨b, hb, gBound1⟩ := (bddAbove_iff_exists_ge 1).mp (convergenceSet_BddAbove _ ((isRestricted_iff_abs c g).mp hg)) - simp only [convergenceSet, Set.mem_setOf_eq, forall_exists_index, forall_apply_eq_imp_iff] + simp only [convergenceSet, Set.mem_ofPred_eq, forall_exists_index, forall_apply_eq_imp_iff] at fBound1 gBound1 simp only [isRestricted_iff, norm_mul, norm_pow, Real.norm_eq_abs, abs_norm, PowerSeries.coeff_mul] at ⊢ hf hg diff --git a/Mathlib/RingTheory/PowerSeries/Substitution.lean b/Mathlib/RingTheory/PowerSeries/Substitution.lean index 388287f3320eff..b90587cd27381b 100644 --- a/Mathlib/RingTheory/PowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/PowerSeries/Substitution.lean @@ -124,7 +124,7 @@ theorem HasSubst.smul (r : MvPowerSeries τ S) {a : MvPowerSeries τ S} (ha : Ha /-- Families of `PowerSeries` that can be substituted, as an `Ideal`. -/ noncomputable def HasSubst.ideal : Ideal (MvPowerSeries τ S) where - carrier := setOf HasSubst + carrier := Set.ofPred HasSubst add_mem' := HasSubst.add zero_mem' := HasSubst.zero smul_mem' := HasSubst.smul diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index fc979ae6db2117..82cef431407d2e 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -299,7 +299,7 @@ instance (priority := 100) EuclideanDomain.to_principal_ideal_domain : IsPrincip { x : R | x ∈ S ∧ x ≠ 0 } := fun h₁ => WellFounded.not_lt_min wf _ h₁ (mod_lt x hmin.2) have : x % WellFounded.min wf { x : R | x ∈ S ∧ x ≠ 0 } h = 0 := by - simp only [not_and_or, Set.mem_setOf_eq, not_ne_iff] at this + simp only [not_and_or, Set.mem_ofPred_eq, not_ne_iff] at this exact this.neg_resolve_left <| (mod_mem_iff hmin.1).2 hx simp [*]), fun hx => diff --git a/Mathlib/RingTheory/Regular/IsSMulRegular.lean b/Mathlib/RingTheory/Regular/IsSMulRegular.lean index 8729e80c5be865..89b9259c3d3be3 100644 --- a/Mathlib/RingTheory/Regular/IsSMulRegular.lean +++ b/Mathlib/RingTheory/Regular/IsSMulRegular.lean @@ -124,7 +124,7 @@ variable (R) in lemma biUnion_associatedPrimes_eq_compl_regular [IsNoetherianRing R] : ⋃ p ∈ associatedPrimes R M, p = { r : R | IsSMulRegular M r }ᶜ := Eq.trans (biUnion_associatedPrimes_eq_zero_divisors R M) <| by - simp_rw [Set.compl_setOf, isSMulRegular_iff_right_eq_zero_of_smul, + simp_rw [Set.compl_ofPred, isSMulRegular_iff_right_eq_zero_of_smul, not_forall, exists_prop, and_comm] lemma isSMulRegular_iff_ker_lsmul_eq_bot : diff --git a/Mathlib/RingTheory/RingHom/Locally.lean b/Mathlib/RingTheory/RingHom/Locally.lean index 7102703a45fe72..d357f4d66129fd 100644 --- a/Mathlib/RingTheory/RingHom/Locally.lean +++ b/Mathlib/RingTheory/RingHom/Locally.lean @@ -299,7 +299,7 @@ lemma locally_isStableUnderBaseChange (hPi : RespectsIso P) (hPb : IsStableUnder ← hf.span_eq_top, Ideal.map_le_iff_le_comap, Ideal.span_le] intro g hg apply Ideal.subset_span - simp only [Set.mem_setOf_eq, Algebra.TensorProduct.includeRight_apply, + simp only [Set.mem_ofPred_eq, Algebra.TensorProduct.includeRight_apply, ← IsScalarTower.algebraMap_eq] at hg ⊢ let e := IsLocalization.Away.tensorProductEquivTMulRight R S g (Localization.Away g) rw [← e.toAlgHom.comp_algebraMap] diff --git a/Mathlib/RingTheory/RootsOfUnity/Basic.lean b/Mathlib/RingTheory/RootsOfUnity/Basic.lean index cd6d861a10e498..73a14ab422640d 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Basic.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Basic.lean @@ -56,8 +56,8 @@ variable {k l : ℕ} def rootsOfUnity (k : ℕ) (M : Type*) [CommMonoid M] : Subgroup Mˣ where carrier := {ζ | ζ ^ k = 1} one_mem' := one_pow _ - mul_mem' _ _ := by simp_all only [Set.mem_setOf_eq, mul_pow, one_mul] - inv_mem' _ := by simp_all only [Set.mem_setOf_eq, inv_pow, inv_one] + mul_mem' _ _ := by simp_all only [Set.mem_ofPred_eq, mul_pow, one_mul] + inv_mem' _ := by simp_all only [Set.mem_ofPred_eq, inv_pow, inv_one] @[simp] theorem mem_rootsOfUnity (k : ℕ) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ ζ ^ k = 1 := diff --git a/Mathlib/RingTheory/Spectrum/Maximal/Basic.lean b/Mathlib/RingTheory/Spectrum/Maximal/Basic.lean index 4f5720b20f0226..8da57cb5a6041b 100644 --- a/Mathlib/RingTheory/Spectrum/Maximal/Basic.lean +++ b/Mathlib/RingTheory/Spectrum/Maximal/Basic.lean @@ -31,8 +31,8 @@ def equivSubtype : MaximalSpectrum R ≃ {I : Ideal R // I.IsMaximal} where theorem range_asIdeal : Set.range MaximalSpectrum.asIdeal = {J : Ideal R | J.IsMaximal} := Set.ext fun J ↦ - ⟨fun hJ ↦ let ⟨j, hj⟩ := Set.mem_range.mp hJ; Set.mem_setOf.mpr <| hj ▸ j.isMaximal, - fun hJ ↦ Set.mem_range.mpr ⟨⟨J, Set.mem_setOf.mp hJ⟩, rfl⟩⟩ + ⟨fun hJ ↦ let ⟨j, hj⟩ := Set.mem_range.mp hJ; Set.mem_ofPred.mpr <| hj ▸ j.isMaximal, + fun hJ ↦ Set.mem_range.mpr ⟨⟨J, Set.mem_ofPred.mp hJ⟩, rfl⟩⟩ variable {R} diff --git a/Mathlib/RingTheory/Spectrum/Prime/Basic.lean b/Mathlib/RingTheory/Spectrum/Prime/Basic.lean index f41869d711d73d..7252458688b3ba 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Basic.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Basic.lean @@ -85,8 +85,8 @@ variable (R S) theorem range_asIdeal : Set.range PrimeSpectrum.asIdeal = {J : Ideal R | J.IsPrime} := Set.ext fun J ↦ - ⟨fun hJ ↦ let ⟨j, hj⟩ := Set.mem_range.mp hJ; Set.mem_setOf.mpr <| hj ▸ j.isPrime, - fun hJ ↦ Set.mem_range.mpr ⟨⟨J, Set.mem_setOf.mp hJ⟩, rfl⟩⟩ + ⟨fun hJ ↦ let ⟨j, hj⟩ := Set.mem_range.mp hJ; Set.mem_ofPred.mpr <| hj ▸ j.isPrime, + fun hJ ↦ Set.mem_range.mpr ⟨⟨J, Set.mem_ofPred.mp hJ⟩, rfl⟩⟩ /-- The map from the direct sum of prime spectra to the prime spectrum of a direct product. -/ @[simp] @@ -166,7 +166,7 @@ theorem coe_vanishingIdeal (t : Set (PrimeSpectrum R)) : theorem mem_vanishingIdeal (t : Set (PrimeSpectrum R)) (f : R) : f ∈ vanishingIdeal t ↔ ∀ x ∈ t, f ∈ x.asIdeal := by - rw [← SetLike.mem_coe, coe_vanishingIdeal, Set.mem_setOf_eq] + rw [← SetLike.mem_coe, coe_vanishingIdeal, Set.mem_ofPred_eq] @[simp] theorem vanishingIdeal_singleton (x : PrimeSpectrum R) : diff --git a/Mathlib/RingTheory/Spectrum/Prime/IsOpenComapC.lean b/Mathlib/RingTheory/Spectrum/Prime/IsOpenComapC.lean index 6d285194ff4884..a5113def61ae25 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/IsOpenComapC.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/IsOpenComapC.lean @@ -36,7 +36,7 @@ def imageOfDf (f : R[X]) : Set (PrimeSpectrum R) := { p : PrimeSpectrum R | ∃ i : ℕ, coeff f i ∉ p.asIdeal } theorem isOpen_imageOfDf : IsOpen (imageOfDf f) := by - rw [imageOfDf, setOf_exists fun i (x : PrimeSpectrum R) => coeff f i ∉ x.asIdeal] + rw [imageOfDf, ofPred_exists fun i (x : PrimeSpectrum R) => coeff f i ∉ x.asIdeal] exact isOpen_iUnion fun i => isOpen_basicOpen /-- If a point of `Spec R[x]` is not contained in the vanishing set of `f`, then its image in diff --git a/Mathlib/RingTheory/Spectrum/Prime/Jacobson.lean b/Mathlib/RingTheory/Spectrum/Prime/Jacobson.lean index 8435f122bc27d5..bc04095a3fdbe7 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Jacobson.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Jacobson.lean @@ -93,9 +93,9 @@ lemma isOpen_singleton_tfae_of_isNoetherian_of_isJacobsonRing suffices {x} = (⋃ p ∈ { p : PrimeSpectrum R | IsMin p ∧ p ≠ x }, closure {p})ᶜ by rw [this, isOpen_compl_iff] refine Set.Finite.isClosed_biUnion ?_ (fun _ _ ↦ isClosed_closure) - exact (finite_setOf_isMin R).subset fun x h ↦ h.1 + exact (finite_setOfPred_isMin R).subset fun x h ↦ h.1 ext p - simp only [Set.mem_singleton_iff, ne_eq, Set.mem_setOf_eq, Set.compl_iUnion, Set.mem_iInter, + simp only [Set.mem_singleton_iff, ne_eq, Set.mem_ofPred_eq, Set.compl_iUnion, Set.mem_iInter, Set.mem_compl_iff, and_imp, ← specializes_iff_mem_closure, ← le_iff_specializes, not_imp_not] constructor diff --git a/Mathlib/RingTheory/Spectrum/Prime/Noetherian.lean b/Mathlib/RingTheory/Spectrum/Prime/Noetherian.lean index e24cb019939470..44c6d91919cee7 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Noetherian.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Noetherian.lean @@ -30,13 +30,15 @@ variable (R : Type u) [CommSemiring R] [IsNoetherianRing R] instance : NoetherianSpace (PrimeSpectrum R) := ((noetherianSpace_TFAE <| PrimeSpectrum R).out 0 1).mpr (closedsEmbedding R).dual.wellFoundedLT -lemma finite_setOf_isMin : +lemma finite_setOfPred_isMin : {x : PrimeSpectrum R | IsMin x}.Finite := by have : Function.Injective (asIdeal (R := R)) := @PrimeSpectrum.ext _ _ refine Set.Finite.of_finite_image (f := asIdeal) ?_ this.injOn simp_rw [isMin_iff] exact (minimalPrimes.finite_of_isNoetherianRing R).subset (Set.image_preimage_subset _ _) +@[deprecated (since := "2026-07-09")] alias finite_setOf_isMin := finite_setOfPred_isMin + end IsNoetherianRing end PrimeSpectrum diff --git a/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean b/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean index 50bf1077de1bd6..ab76a77a3a8160 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean @@ -94,7 +94,7 @@ lemma mem_image_comap_zeroLocus_sdiff (f : A) (s : Set A) (x) : exact hqf this · intro H rw [← mem_nilradical, nilradical_eq_sInf, Ideal.mem_sInf] at H - simp only [Set.mem_setOf_eq, Algebra.TensorProduct.algebraMap_apply, + simp only [Set.mem_ofPred_eq, Algebra.TensorProduct.algebraMap_apply, Ideal.Quotient.algebraMap_eq, not_forall] at H obtain ⟨q, hq, hfq⟩ := H have : ∀ a ∈ s, Ideal.Quotient.mk (Ideal.span s) a ⊗ₜ[R] 1 ∈ q := fun a ha ↦ by diff --git a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean index 813b900ffb3528..698b2d9cde242b 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Topology.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Topology.lean @@ -310,7 +310,7 @@ theorem discreteTopology_iff_finite_isMaximal_and_sInf_le_nilradical : letI s := {I : Ideal R | I.IsMaximal} DiscreteTopology (PrimeSpectrum R) ↔ Finite s ∧ sInf s ≤ nilradical R := by rw [discreteTopology_iff_finite_and_krullDimLE_zero, Ring.krullDimLE_zero_iff, - (equivSubtype R).finite_iff, ← Set.coe_setOf, Set.finite_coe_iff, Set.finite_coe_iff] + (equivSubtype R).finite_iff, ← Set.coe_ofPred, Set.finite_coe_iff, Set.finite_coe_iff] refine ⟨fun h ↦ ⟨h.1.subset fun _ h ↦ h.isPrime, nilradical_eq_sInf R ▸ sInf_le_sInf h.2⟩, fun ⟨fin, le⟩ ↦ ?_⟩ have hpm (I : Ideal R) (hI : I.IsPrime) : I.IsMaximal := by @@ -593,7 +593,7 @@ theorem localization_away_comap_range (S : Type v) [CommSemiring S] [Algebra R S [IsLocalization.Away r S] : Set.range (comap (algebraMap R S)) = basicOpen r := by rw [localization_comap_range S (Submonoid.powers r)] ext x - simp only [mem_zeroLocus, basicOpen_eq_zeroLocus_compl, SetLike.mem_coe, Set.mem_setOf_eq, + simp only [mem_zeroLocus, basicOpen_eq_zeroLocus_compl, SetLike.mem_coe, Set.mem_ofPred_eq, Set.singleton_subset_iff, Set.mem_compl_iff, disjoint_iff_inf_le] constructor · intro h₁ h₂ @@ -932,7 +932,7 @@ lemma vanishingIdeal_range_comap : ext x rw [RingHom.ker_eq_comap_bot, ← Ideal.comap_radical, Ideal.radical_eq_sInf] simp only [mem_vanishingIdeal, Set.mem_range, forall_exists_index, forall_apply_eq_imp_iff, - comap_asIdeal, Ideal.mem_comap, bot_le, true_and, Submodule.mem_sInf, Set.mem_setOf_eq] + comap_asIdeal, Ideal.mem_comap, bot_le, true_and, Submodule.mem_sInf, Set.mem_ofPred_eq] exact ⟨fun H I hI ↦ H ⟨I, hI⟩, fun H I ↦ H I.1 I.2⟩ lemma closure_range_comap : @@ -951,7 +951,7 @@ lemma denseRange_comap_iff_minimalPrimes : · intro H I hI have : I ∈ (RingHom.ker f).minimalPrimes := by rw [denseRange_comap_iff_ker_le_nilRadical] at H - simp only [Set.mem_setOf, Ideal.IsMinimalPrime] at hI ⊢ + simp only [Set.mem_ofPred, Ideal.IsMinimalPrime] at hI ⊢ convert! hI using 2 with p exact ⟨fun h ↦ ⟨h.1, bot_le⟩, fun h ↦ ⟨h.1, H.trans (h.1.radical_le_iff.mpr bot_le)⟩⟩ obtain ⟨p, hp, _, rfl⟩ := Ideal.exists_comap_eq_of_mem_minimalPrimes f (I := ⊥) I this @@ -1239,7 +1239,7 @@ protected def _root_.Ideal.minimalPrimes.equivIrreducibleComponents (I : Ideal R let e : {p : Ideal R | p.IsPrime ∧ I ≤ p} ≃o zeroLocus (I : Set R) := ⟨⟨fun x ↦ ⟨⟨x.1, x.2.1⟩, x.2.2⟩, fun x ↦ ⟨x.1.1, x.1.2, x.2⟩, fun _ ↦ rfl, fun _ ↦ rfl⟩, .rfl⟩ rw [irreducibleComponents_eq_maximals_closed] - exact OrderIso.setOfMinimalIsoSetOfMaximal + exact OrderIso.setOfPredMinimalIsoSetOfPredMaximal (e.trans ((PrimeSpectrum.zeroLocusEquivIrreducibleCloseds (I : Set R)).trans (TopologicalSpace.IrreducibleCloseds.orderIsoSubtype' (zeroLocus (I : Set R))).dual)) @@ -1253,15 +1253,15 @@ protected def _root_.minimalPrimes.equivIrreducibleComponents : let e : {p : Ideal R | p.IsPrime ∧ ⊥ ≤ p} ≃o PrimeSpectrum R := ⟨⟨fun x ↦ ⟨x.1, x.2.1⟩, fun x ↦ ⟨x.1, x.2, bot_le⟩, fun _ ↦ rfl, fun _ ↦ rfl⟩, Iff.rfl⟩ rw [irreducibleComponents_eq_maximals_closed] - exact OrderIso.setOfMinimalIsoSetOfMaximal + exact OrderIso.setOfPredMinimalIsoSetOfPredMaximal (e.trans ((PrimeSpectrum.pointsEquivIrreducibleCloseds R).trans (TopologicalSpace.IrreducibleCloseds.orderIsoSubtype' (PrimeSpectrum R)).dual)) lemma vanishingIdeal_irreducibleComponents : vanishingIdeal '' (irreducibleComponents <| PrimeSpectrum R) = minimalPrimes R := by rw [irreducibleComponents_eq_maximals_closed, minimalPrimes_eq_minimals, - image_antitone_setOf_maximal (fun s t hs _ ↦ (vanishingIdeal_anti_mono_iff hs.1).symm), - ← funext (@Set.mem_setOf_eq _ · Ideal.IsPrime), ← vanishingIdeal_isClosed_isIrreducible] + image_antitone_setOfPred_maximal (fun s t hs _ ↦ (vanishingIdeal_anti_mono_iff hs.1).symm), + ← funext (@Set.mem_ofPred_eq _ · Ideal.IsPrime), ← vanishingIdeal_isClosed_isIrreducible] rfl lemma zeroLocus_minimalPrimes : diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean index f6db5564bcc18e..7cfc828023914c 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Ideal.lean @@ -12,7 +12,8 @@ public import Mathlib.RingTheory.UniqueFactorizationDomain.Defs # Unique factorization and ascending chain condition on ideals ## Main results -* `Ideal.setOf_isPrincipal_wellFoundedOn_gt`, `WfDvdMonoid.of_setOf_isPrincipal_wellFoundedOn_gt` +* `Ideal.setOfPred_isPrincipal_wellFoundedOn_gt`, + `WfDvdMonoid.of_setOfPred_isPrincipal_wellFoundedOn_gt` in a domain, well-foundedness of the strict version of ∣ is equivalent to the ascending chain condition on principal ideals. -/ @@ -37,7 +38,7 @@ theorem Ideal.IsPrime.exists_mem_prime_of_ne_bot {R : Type*} [CommSemiring R] section Ideal /-- The ascending chain condition on principal ideals holds in a `WfDvdMonoid` domain. -/ -lemma Ideal.setOf_isPrincipal_wellFoundedOn_gt [CommSemiring α] [WfDvdMonoid α] [IsDomain α] : +lemma Ideal.setOfPred_isPrincipal_wellFoundedOn_gt [CommSemiring α] [WfDvdMonoid α] [IsDomain α] : {I : Ideal α | I.IsPrincipal}.WellFoundedOn (· > ·) := by have : {I : Ideal α | I.IsPrincipal} = ((fun a ↦ Ideal.span {a}) '' Set.univ) := by ext @@ -47,9 +48,12 @@ lemma Ideal.setOf_isPrincipal_wellFoundedOn_gt [CommSemiring α] [WfDvdMonoid α ext exact Ideal.span_singleton_lt_span_singleton +@[deprecated (since := "2026-07-09")] +alias Ideal.setOf_isPrincipal_wellFoundedOn_gt := Ideal.setOfPred_isPrincipal_wellFoundedOn_gt + /-- The ascending chain condition on principal ideals in a domain is sufficient to prove that the domain is `WfDvdMonoid`. -/ -lemma WfDvdMonoid.of_setOf_isPrincipal_wellFoundedOn_gt [CommSemiring α] [IsDomain α] +lemma WfDvdMonoid.of_setOfPred_isPrincipal_wellFoundedOn_gt [CommSemiring α] [IsDomain α] (h : {I : Ideal α | I.IsPrincipal}.WellFoundedOn (· > ·)) : WfDvdMonoid α := by have : WellFounded (α := {I : Ideal α // I.IsPrincipal}) (· > ·) := h @@ -58,4 +62,8 @@ lemma WfDvdMonoid.of_setOf_isPrincipal_wellFoundedOn_gt [CommSemiring α] [IsDom ext exact Ideal.span_singleton_lt_span_singleton.symm +@[deprecated (since := "2026-07-09")] +alias WfDvdMonoid.of_setOf_isPrincipal_wellFoundedOn_gt := + WfDvdMonoid.of_setOfPred_isPrincipal_wellFoundedOn_gt + end Ideal diff --git a/Mathlib/RingTheory/Valuation/Archimedean.lean b/Mathlib/RingTheory/Valuation/Archimedean.lean index 12619adbed5d70..aef4fee0cc104f 100644 --- a/Mathlib/RingTheory/Valuation/Archimedean.lean +++ b/Mathlib/RingTheory/Valuation/Archimedean.lean @@ -48,19 +48,20 @@ lemma wellFounded_gt_on_v_iff_discrete_mrange [Nontrivial (MonoidHom.mrange v)ˣ (hv : Integers v O) : WellFounded ((· > ·) on (v ∘ algebraMap O F)) ↔ Nonempty (MonoidHom.mrange v ≃*o ℤᵐ⁰) := by - rw [← LinearOrderedCommGroupWithZero.wellFoundedOn_setOf_ge_gt_iff_nonempty_discrete_of_ne_zero + rw [← + LinearOrderedCommGroupWithZero.wellFoundedOn_setOfPred_ge_gt_iff_nonempty_discrete_of_ne_zero one_ne_zero, ← Set.wellFoundedOn_range] classical refine ⟨fun h ↦ (h.mapsTo Subtype.val ?_).mono' (by simp), fun h ↦ (h.mapsTo ?_ ?_).mono' ?_⟩ · rintro ⟨_, x, rfl⟩ - simp only [← Subtype.coe_le_coe, OneMemClass.coe_one, Set.mem_setOf_eq, Set.mem_range, + simp only [← Subtype.coe_le_coe, OneMemClass.coe_one, Set.mem_ofPred_eq, Set.mem_range, Function.comp_apply] intro hx obtain ⟨y, rfl⟩ := hv.exists_of_le_one hx exact ⟨y, by simp⟩ · exact fun x ↦ if hx : x ∈ MonoidHom.mrange v then ⟨x, hx⟩ else 1 · intro - simp only [Set.mem_range, Function.comp_apply, MonoidHom.mem_mrange, Set.mem_setOf_eq, + simp only [Set.mem_range, Function.comp_apply, MonoidHom.mem_mrange, Set.mem_ofPred_eq, forall_exists_index] rintro x rfl simp [← Subtype.coe_le_coe, hv.map_le_one] diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index 459a3ef93ff9a0..01cd74bc421dbb 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -445,7 +445,7 @@ def leAddSubgroup (v : Valuation R Γ₀) (γ : Γ₀) : AddSubgroup R where carrier := { x | v x ≤ γ } zero_mem' := by simp add_mem' {x y} x_in y_in := (v.map_add x y).trans (max_le x_in y_in) - neg_mem' x_in := by rwa [Set.mem_setOf, map_neg] + neg_mem' x_in := by rwa [Set.mem_ofPred, map_neg] @[simp] lemma mem_leAddSubgroup_iff {v : Valuation R Γ₀} {γ : Γ₀} {x : R} : @@ -561,7 +561,7 @@ lemma IsEquiv.restrict {Γ₀' : Type*} [LinearOrderedCommGroupWithZero Γ₀'] carrier := { x | v x < γ } zero_mem' := by simp add_mem' {x y} x_in y_in := lt_of_le_of_lt (v.map_add x y) (max_lt x_in y_in) - neg_mem' x_in := by rwa [Set.mem_setOf, map_neg] + neg_mem' x_in := by rwa [Set.mem_ofPred, map_neg] @[simp] lemma mem_ltAddSubgroup_iff {v : Valuation R Γ₀} {γ x} : x ∈ ltAddSubgroup v γ ↔ v x < γ := diff --git a/Mathlib/RingTheory/Valuation/Integers.lean b/Mathlib/RingTheory/Valuation/Integers.lean index 19a5dad8322e23..8cc6af37bfa060 100644 --- a/Mathlib/RingTheory/Valuation/Integers.lean +++ b/Mathlib/RingTheory/Valuation/Integers.lean @@ -32,10 +32,10 @@ variable (v : Valuation R Γ₀) def integer : Subring R where carrier := { x | v x ≤ 1 } one_mem' := le_of_eq v.map_one - mul_mem' {x y} hx hy := by simp only [Set.mem_setOf_eq, map_mul, mul_le_one' hx hy] + mul_mem' {x y} hx hy := by simp only [Set.mem_ofPred_eq, map_mul, mul_le_one' hx hy] zero_mem' := by simp add_mem' {x y} hx hy := le_trans (v.map_add x y) (max_le hx hy) - neg_mem' {x} hx := by simp only [Set.mem_setOf_eq] at hx; simpa only [Set.mem_setOf_eq, map_neg] + neg_mem' {x} hx := by simp only [Set.mem_ofPred_eq] at hx; simpa only [Set.mem_ofPred_eq, map_neg] lemma mem_integer_iff (r : R) : r ∈ v.integer ↔ v r ≤ 1 := by rfl @@ -198,13 +198,16 @@ theorem eq_algebraMap_or_inv_eq_algebraMap (hv : Integers v O) (x : F) : obtain ⟨a, ha⟩ := exists_of_le_one hv h exacts [⟨a, Or.inl ha.symm⟩, ⟨a, Or.inr ha.symm⟩] -lemma coe_span_singleton_eq_setOf_le_v_algebraMap (hv : Integers v O) (x : O) : +lemma coe_span_singleton_eq_setOfPred_le_v_algebraMap (hv : Integers v O) (x : O) : (Ideal.span {x} : Set O) = {y : O | v (algebraMap O F y) ≤ v (algebraMap O F x)} := by rcases eq_or_ne x 0 with rfl | hx · simp [Set.singleton_zero, map_eq_zero_iff _ hv.hom_inj] ext simp [SetLike.mem_coe, Ideal.mem_span_singleton, hv.dvd_iff_le] +@[deprecated (since := "2026-07-09")] +alias coe_span_singleton_eq_setOf_le_v_algebraMap := coe_span_singleton_eq_setOfPred_le_v_algebraMap + lemma bijective_algebraMap_of_subsingleton_units_mrange (hv : Integers v O) [Subsingleton (MonoidHom.mrange v)ˣ] : Function.Bijective (algebraMap O F) := by @@ -231,14 +234,14 @@ lemma isPrincipal_iff_exists_isGreatest (hv : Integers v O) {I : Ideal O} : simp only [Ideal.submodule_span_eq, Ideal.mem_span_singleton] exact ⟨fun hb ↦ dvd_of_le hv (hx.2 <| mem_image_of_mem _ hb), fun hb ↦ I.mem_of_dvd hb ha⟩ -lemma isPrincipal_iff_exists_eq_setOf_valuation_le (hv : Integers v O) {I : Ideal O} : +lemma isPrincipal_iff_exists_eq_setOfPred_valuation_le (hv : Integers v O) {I : Ideal O} : I.IsPrincipal ↔ ∃ x, (I : Set O) = {y | v (algebraMap O F y) ≤ v (algebraMap O F x)} := by rw [isPrincipal_iff_exists_isGreatest hv] constructor <;> rintro ⟨x, hx⟩ · obtain ⟨a, ha, rfl⟩ : ∃ a ∈ I, (v ∘ algebraMap O F) a = x := by simpa using hx.left refine ⟨a, ?_⟩ ext b - simp only [SetLike.mem_coe, mem_setOf_eq] + simp only [SetLike.mem_coe, mem_ofPred_eq] constructor <;> intro h · exact hx.right (Set.mem_image_of_mem _ h) · rw [le_iff_dvd hv] at h @@ -247,6 +250,10 @@ lemma isPrincipal_iff_exists_eq_setOf_valuation_le (hv : Integers v O) {I : Idea · simp [hx] · simp [hx, mem_upperBounds] +@[deprecated (since := "2026-07-09")] +alias isPrincipal_iff_exists_eq_setOf_valuation_le := + isPrincipal_iff_exists_eq_setOfPred_valuation_le + set_option backward.isDefEq.respectTransparency false in lemma not_denselyOrdered_of_isPrincipalIdealRing [IsPrincipalIdealRing O] (hv : Integers v O) : ¬ DenselyOrdered (range v) := by @@ -290,9 +297,12 @@ lemma v_irreducible_lt_one {ϖ : v.integer} (h : Irreducible ϖ) : lemma v_irreducible_pos {ϖ : v.integer} (h : Irreducible ϖ) : 0 < v ϖ := (Valuation.integer.integers v).valuation_irreducible_pos h -lemma coe_span_singleton_eq_setOf_le_v_coe (x : v.integer) : +lemma coe_span_singleton_eq_setOfPred_le_v_coe (x : v.integer) : (Ideal.span {x} : Set v.integer) = {y : v.integer | v y ≤ v x} := - (Valuation.integer.integers v).coe_span_singleton_eq_setOf_le_v_algebraMap x + (Valuation.integer.integers v).coe_span_singleton_eq_setOfPred_le_v_algebraMap x + +@[deprecated (since := "2026-07-09")] +alias coe_span_singleton_eq_setOf_le_v_coe := coe_span_singleton_eq_setOfPred_le_v_coe end integer diff --git a/Mathlib/RingTheory/Valuation/ValuationSubring.lean b/Mathlib/RingTheory/Valuation/ValuationSubring.lean index d3d43003c384c4..b65b444cac3bbd 100644 --- a/Mathlib/RingTheory/Valuation/ValuationSubring.lean +++ b/Mathlib/RingTheory/Valuation/ValuationSubring.lean @@ -553,7 +553,7 @@ section nonunits /-- The nonunits of a valuation subring of `K`, as a nonunital subring of `K` -/ def nonunits : NonUnitalSubring K where carrier := {x | A.valuation x < 1} - mul_mem' ha hb := (mul_lt_mul'' (Set.mem_setOf.mp ha) (Set.mem_setOf.mp hb) + mul_mem' ha hb := (mul_lt_mul'' (Set.mem_ofPred.mp ha) (Set.mem_ofPred.mp hb) zero_le zero_le).trans_eq <| mul_one _ add_mem' ha hb := (A.valuation.map_add ..).trans_lt (max_lt ha hb) zero_mem' := by simp @@ -635,7 +635,7 @@ def principalUnitGroup : Subgroup Kˣ where carrier := {x | A.valuation (x - 1) < 1} mul_mem' := by intro a b ha hb - rw [Set.mem_setOf] at ha hb ⊢ + rw [Set.mem_ofPred] at ha hb ⊢ refine lt_of_le_of_lt ?_ (max_lt hb ha) rw [← one_mul (A.valuation (b - 1)), ← A.valuation.map_one_add_of_lt ha, add_sub_cancel, ← Valuation.map_mul, mul_sub_one, ← sub_add_sub_cancel] diff --git a/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean b/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean index bba4af792f46b6..7a93ca69f21609 100644 --- a/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean +++ b/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean @@ -106,7 +106,7 @@ theorem dvd_sub_sum_teichmuller_iterateFrobeniusEquiv_coeff (x : 𝕎 R) (n : exact teichmuller_mul_pow_coeff_of_ne _ (Ne.intro hb.2).symm · refine fun n ↦ ⟨fun ⟨a, _, ha⟩ ⟨b, _, hb⟩ ↦ ?_⟩ ext - dsimp only [ne_eq, Set.mem_setOf_eq] + dsimp only [ne_eq, Set.mem_ofPred_eq] rw [← Not.imp_symm (teichmuller_mul_pow_coeff_of_ne _) ha] exact Not.imp_symm (teichmuller_mul_pow_coeff_of_ne _) hb diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean index 36682350f70b1c..7aed87f9eb1926 100644 --- a/Mathlib/SetTheory/Cardinal/Aleph.lean +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -180,7 +180,7 @@ theorem range_preOmega : range preOmega = {x | IsInitial x} := range_enumOrd not_bddAbove_isInitial theorem mem_range_preOmega_iff {x : Ordinal} : x ∈ range preOmega ↔ IsInitial x := by - rw [range_preOmega, mem_setOf] + rw [range_preOmega, mem_ofPred] alias ⟨_, IsInitial.mem_range_preOmega⟩ := mem_range_preOmega_iff @@ -269,7 +269,7 @@ theorem range_omega : range omega = {x | ω ≤ x ∧ IsInitial x} := by rw [omega_eq_preOmega, Ordinal.add_sub_cancel_of_le ha'] theorem mem_range_omega_iff {x : Ordinal} : x ∈ range omega ↔ ω ≤ x ∧ IsInitial x := by - rw [range_omega, mem_setOf] + rw [range_omega, mem_ofPred] theorem preOmega_of_omega0_sq_le {o : Ordinal} (ho : ω ^ 2 ≤ o) : preOmega o = ω_ o := by rw [← opow_natCast] at ho diff --git a/Mathlib/SetTheory/Cardinal/Arithmetic.lean b/Mathlib/SetTheory/Cardinal/Arithmetic.lean index 29ab245cadb1d0..4d4c9ea909db3d 100644 --- a/Mathlib/SetTheory/Cardinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Cardinal/Arithmetic.lean @@ -643,7 +643,7 @@ theorem mk_surjective_eq_zero_iff_lift : contrapose! +distrib rw [lift_mk_le', and_comm] simp_rw [mk_ne_zero_iff, mk_eq_zero_iff, nonempty_coe_sort, - Set.Nonempty, mem_setOf, exists_surjective_iff, nonempty_fun] + Set.Nonempty, mem_ofPred, exists_surjective_iff, nonempty_fun] theorem mk_surjective_eq_zero_iff : #{f : α → β | Surjective f} = 0 ↔ #α < #β ∨ (#α ≠ 0 ∧ #β = 0) := by diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 63ee719ca69174..7a57624058d4fe 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -902,7 +902,7 @@ lemma compl_nonempty_of_mk_lt_mk {S : Set α} (h : #S < #α) : Sᶜ.Nonempty := theorem mk_union_le_aleph0 {α} {P Q : Set α} : #(P ∪ Q : Set α) ≤ ℵ₀ ↔ #P ≤ ℵ₀ ∧ #Q ≤ ℵ₀ := by - simp only [le_aleph0_iff_subtype_countable, setOf_mem_eq, Set.union_def, + simp only [le_aleph0_iff_subtype_countable, ofPred_mem_eq, Set.union_def, ← countable_union] theorem mk_sep (s : Set α) (t : α → Prop) : #({ x ∈ s | t x } : Set α) = #{ x : s | t x.1 } := diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean index 4b8bd2fdf007f4..6935f1b23a243b 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Ordinal.lean @@ -157,7 +157,7 @@ theorem exists_ord_cof_eq [LinearOrder α] [WellFoundedLT α] : ∃ s : Set α, IsCofinal s ∧ typeLT s = (Order.cof α).ord := by obtain ⟨s, hs, hs'⟩ := exists_cof_eq α obtain ⟨r, hr, hr'⟩ := exists_ord_eq s - have ht := hs.trans (isCofinal_setOf_imp_lt r) + have ht := hs.trans (isCofinal_setOfPred_imp_lt r) refine ⟨_, ht, (ord_le.2 (cof_le ht)).antisymm' ?_⟩ rw [← hs', hr', type_le_iff'] refine ⟨.ofMonotone (fun x ↦ ⟨x.1, ?_⟩) fun x y hxy ↦ ?_⟩ @@ -561,8 +561,8 @@ theorem mk_bounded_subset {α : Type*} (h : IsStrongPrelimit #α) {r : α → α have h' : IsStrongLimit #α := ⟨ha, @h⟩ have ha := h'.aleph0_le apply le_antisymm - · have : { s : Set α | Bounded r s } = ⋃ i, 𝒫 { j | r j i } := setOf_exists _ - rw [← coe_setOf, this] + · have : { s : Set α | Bounded r s } = ⋃ i, 𝒫 { j | r j i } := ofPred_exists _ + rw [← coe_ofPred, this] refine mk_iUnion_le_sum_mk.trans ((sum_le_mk_mul_iSup (fun i => #(𝒫 { j | r j i }))).trans ((mul_le_max_of_aleph0_le_left ha).trans ?_)) rw [max_eq_left] diff --git a/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean b/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean index d2197340546279..584558ad4dcecc 100644 --- a/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean +++ b/Mathlib/SetTheory/Cardinal/HasCardinalLT.lean @@ -173,7 +173,7 @@ lemma hasCardinalLT_iUnion {ι : Type*} {X : Type*} (S : ι → Set X) {κ : Cardinal} [Fact κ.IsRegular] (hι : HasCardinalLT ι κ) (hS : ∀ i, HasCardinalLT (S i) κ) : HasCardinalLT (⋃ i, S i) κ := by - convert! show HasCardinalLT (setOf ((⨆ i, S i))) κ from hasCardinalLT_subtype_iSup S hι hS + convert! show HasCardinalLT (Set.ofPred ((⨆ i, S i))) κ from hasCardinalLT_subtype_iSup S hι hS aesop /-- The particular case of `hasCardinalLT_prod` when all the inputs are in the diff --git a/Mathlib/SetTheory/Cardinal/NatCard.lean b/Mathlib/SetTheory/Cardinal/NatCard.lean index 742c5bd2782791..ee56380d8b6bd2 100644 --- a/Mathlib/SetTheory/Cardinal/NatCard.lean +++ b/Mathlib/SetTheory/Cardinal/NatCard.lean @@ -196,10 +196,10 @@ theorem ecard_lt_ecard (hs : s.Finite) (hsub : s ⊂ t) : ENat.card s < ENat.car sdiff_union_of_subset hsub.subset] exact le_add_of_le_right hle -theorem card_strictMonoOn : StrictMonoOn (α := Set α) (Nat.card ∘ (↑)) (setOf Set.Finite) := +theorem card_strictMonoOn : StrictMonoOn (α := Set α) (Nat.card ∘ (↑)) (Set.ofPred Set.Finite) := fun _ _ _ ↦ card_lt_card -theorem ecard_strictMonoOn : StrictMonoOn (α := Set α) (ENat.card ∘ (↑)) (setOf Set.Finite) := +theorem ecard_strictMonoOn : StrictMonoOn (α := Set α) (ENat.card ∘ (↑)) (Set.ofPred Set.Finite) := fun _ hs _ _ ↦ hs.ecard_lt_ecard theorem eq_of_subset_of_card_le (ht : t.Finite) (hsub : s ⊆ t) (hcard : Nat.card t ≤ Nat.card s) : diff --git a/Mathlib/SetTheory/Cardinal/NatCount.lean b/Mathlib/SetTheory/Cardinal/NatCount.lean index bbbb21f1ae44c5..88b38d96b78aad 100644 --- a/Mathlib/SetTheory/Cardinal/NatCount.lean +++ b/Mathlib/SetTheory/Cardinal/NatCount.lean @@ -27,7 +27,7 @@ theorem count_le_cardinal : (count p n : Cardinal) ≤ Cardinal.mk { k | p k } : exact Cardinal.mk_subtype_mono fun x hx ↦ hx.2 theorem count_le_setENCard : count p n ≤ Set.encard { k | p k } := by - simp only [Set.encard, ENat.card, Set.coe_setOf, Cardinal.natCast_le_toENat] + simp only [Set.encard, ENat.card, Set.coe_ofPred, Cardinal.natCast_le_toENat] exact Nat.count_le_cardinal n theorem count_le_setNCard (h : { k | p k }.Finite) : count p n ≤ Set.ncard { k | p k } := by diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index 987184dd48fa8d..ffe413a7841ced 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -261,7 +261,7 @@ theorem lift_two : lift.{u, v} 2 = 2 := by simp [← one_add_one_eq_two] @[simp] theorem mk_set {α : Type u} : #(Set α) = 2 ^ #α := by - simp [← mk_congr (Equiv.ofBijective _ Set.setOf_bijective), ← one_add_one_eq_two] + simp [← mk_congr (Equiv.ofBijective _ Set.ofPred_bijective), ← one_add_one_eq_two] /-- A variant of `Cardinal.mk_set` expressed in terms of a `Set` instead of a `Type`. -/ @[simp] @@ -514,7 +514,7 @@ theorem lift_mk_le_lift_mk_mul_of_lift_mk_preimage_le {α : Type u} {β : Type v (Equiv.trans (by rw [Equiv.image_eq_preimage_symm] - simp only [preimage, mem_singleton_iff, ULift.up_inj, mem_setOf_eq, coe_setOf] + simp only [preimage, mem_singleton_iff, ULift.up_inj, mem_ofPred_eq, coe_ofPred] exact Equiv.refl _) Equiv.ulift.symm)).trans_le (hf b) diff --git a/Mathlib/SetTheory/Cardinal/Pigeonhole.lean b/Mathlib/SetTheory/Cardinal/Pigeonhole.lean index 9917abadfcad1c..a984c3e42cd348 100644 --- a/Mathlib/SetTheory/Cardinal/Pigeonhole.lean +++ b/Mathlib/SetTheory/Cardinal/Pigeonhole.lean @@ -60,7 +60,7 @@ theorem infinite_pigeonhole_set {β α : Type u} {s : Set β} (f : s → α) (θ ha.trans (ge_of_eq <| Quotient.sound ⟨Equiv.trans ?_ (Equiv.subtypeSubtypeEquivSubtypeExists _ _).symm⟩) - simp only [coe_eq_subtype, mem_singleton_iff, mem_preimage, mem_setOf_eq] + simp only [coe_eq_subtype, mem_singleton_iff, mem_preimage, mem_ofPred_eq] rfl rintro x ⟨_, hx'⟩; exact hx' diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index dcc77b17305f99..844d543fae1134 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -1164,7 +1164,7 @@ theorem isNormal_ord : Order.IsNormal ord where strictMono := ord_strictMono mem_lowerBounds_upperBounds_of_isSuccLimit := by intro a ha - simp_rw [lowerBounds, upperBounds, mem_setOf, forall_mem_image, ord_le] + simp_rw [lowerBounds, upperBounds, mem_ofPred, forall_mem_image, ord_le] refine fun b H ↦ le_of_forall_lt fun c hc ↦ ?_ simpa using H (ha.succ_lt hc) diff --git a/Mathlib/SetTheory/Ordinal/Family.lean b/Mathlib/SetTheory/Ordinal/Family.lean index 4a01cac1256798..d7897a85c18dcb 100644 --- a/Mathlib/SetTheory/Ordinal/Family.lean +++ b/Mathlib/SetTheory/Ordinal/Family.lean @@ -461,7 +461,7 @@ theorem bsup_eq_of_brange_eq {o o'} {f : ∀ a < o, Ordinal} {g : ∀ a < o', Or @[deprecated "bsup is deprecated" (since := "2026-04-05")] theorem iSup_Iio_eq_bsup {o} {f : ∀ a < o, Ordinal} : ⨆ a : Iio o, f a.1 a.2 = bsup o f := by - simp_rw [Iio, bsup, iSup, range_familyOfBFamily, brange, range, Subtype.exists, mem_setOf] + simp_rw [Iio, bsup, iSup, range_familyOfBFamily, brange, range, Subtype.exists, mem_ofPred] end bsup diff --git a/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean b/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean index cabdc2a132139e..5010bcd45a0cb0 100644 --- a/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean +++ b/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean @@ -54,7 +54,7 @@ theorem not_injective_limitation_set : ¬ InjOn g (Iio (ord <| succ #α)) := by have h := lift_mk_le_lift_mk_of_injective <| injOn_iff_injective.1 h_inj have mk_initialSeg_subtype : #(Iio (ord <| succ #α)) = lift.{u + 1} (succ #α) := by - simpa only [coe_setOf, card_typein, card_ord] using mk_Iio_ordinal (ord <| succ #α) + simpa only [coe_ofPred, card_typein, card_ord] using mk_Iio_ordinal (ord <| succ #α) rw [mk_initialSeg_subtype, lift_lift, lift_le] at h exact not_le_of_gt (Order.lt_succ #α) h diff --git a/Mathlib/SetTheory/Ordinal/Principal.lean b/Mathlib/SetTheory/Ordinal/Principal.lean index 5ea4572e343bc3..bfc52aec9b2b66 100644 --- a/Mathlib/SetTheory/Ordinal/Principal.lean +++ b/Mathlib/SetTheory/Ordinal/Principal.lean @@ -23,7 +23,7 @@ equivalent to the epsilon numbers given by `Ordinal.epsilon`. * `IsPrincipal`: A principal (or indecomposable) ordinal under some binary operation. We include `0` and other typically excluded edge cases for simplicity. -* `not_bddAbove_setOf_isPrincipal`: Principal ordinals (under any operation) are unbounded. +* `not_bddAbove_setOfPred_isPrincipal`: Principal ordinals (under any operation) are unbounded. * `isPrincipal_add_iff_zero_or_omega0_opow`: The additive principal ordinals are `0` and the ordinal powers of `ω`. * `isPrincipal_mul_iff_le_two_or_omega0_opow_opow`: The multiplicative principal ordinals are @@ -177,13 +177,16 @@ private theorem isPrincipal_nfp_iSup (op : Ordinal → Ordinal → Ordinal) (o : ⟨_, Set.mk_mem_prod ha (hb.trans_le h)⟩ /-- Principal ordinals under any operation are unbounded. -/ -theorem not_bddAbove_setOf_isPrincipal (op : Ordinal → Ordinal → Ordinal) : +theorem not_bddAbove_setOfPred_isPrincipal (op : Ordinal → Ordinal → Ordinal) : ¬ BddAbove { o | IsPrincipal op o } := by rintro ⟨a, ha⟩ exact ((le_nfp _ _).trans (ha (isPrincipal_nfp_iSup op (succ a)))).not_gt (lt_succ a) +@[deprecated (since := "2026-07-09")] +alias not_bddAbove_setOf_isPrincipal := not_bddAbove_setOfPred_isPrincipal + @[deprecated (since := "2026-03-17")] -alias not_bddAbove_principal := not_bddAbove_setOf_isPrincipal +alias not_bddAbove_principal := not_bddAbove_setOfPred_isPrincipal /-! ### Additive principal ordinals -/ diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index aee00c41669349..2535cff6f31071 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -563,7 +563,7 @@ def powersetEquiv (x : ZFSet.{u}) : x.powerset ≃ 𝒫 (x : Set ZFSet) where toFun y := ⟨y.1, Set.mem_powerset (mem_powerset.1 y.2)⟩ invFun s := ⟨x.sep (· ∈ s.1), mem_powerset.2 sep_subset⟩ left_inv := by simp +contextual [Function.LeftInverse] - right_inv := by simp +contextual [Function.LeftInverse, Function.RightInverse, Set.setOf_and] + right_inv := by simp +contextual [Function.LeftInverse, Function.RightInverse, Set.ofPred_and] theorem insert_eq (x y : ZFSet) : insert x y = {x} ∪ y := by ext; simp diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean index 75e57d1f301249..373a33001da998 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean @@ -93,7 +93,7 @@ local instance : CompleteSpace (Seq α) := by rw [clusterPt_principal_iff] at hs obtain ⟨t, hts, ht⟩ := hs (Metric.ball s ((1 / 2 : ℝ) ^ (n + 1))) (Metric.ball_mem_nhds _ (by positivity)) - simp only [Metric.ball, Set.mem_setOf_eq] at hts + simp only [Metric.ball, Set.mem_ofPred_eq] at hts rw [← PiNat.apply_eq_of_dist_lt hts (by simp)] at hn rw [← PiNat.apply_eq_of_dist_lt hts (by rfl)] exact ht hn diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index da8dcb078ff371..b1b34fed7d7d26 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -258,6 +258,9 @@ def abbreviationDict : Std.HashMap String String := .ofList [ ("neTop", "NeBot"), ("decidableSucc", "DecidablePred"), + -- `Set.ofPred` is not dual to `Set.ofSucc` + ("ofSucc", "OfPred"), + ("setOfSucc", "SetOfPred"), ] @[inherit_doc GuessName.GuessNameExt] diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean index 3f5841d4654d60..57e5d0d9593898 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean @@ -317,7 +317,7 @@ profinite additive groups. -/] def limitConePtAux : Subgroup (Π j : J, F.obj j) where carrier := {x | ∀ ⦃i j : J⦄ (π : i ⟶ j), F.map π (x i) = x j} mul_mem' hx hy _ _ π := by simp only [Pi.mul_apply, map_mul, hx π, hy π] - one_mem' := by simp only [Set.mem_setOf_eq, Pi.one_apply, map_one, implies_true] + one_mem' := by simp only [Set.mem_ofPred_eq, Pi.one_apply, map_one, implies_true] inv_mem' h _ _ π := by simp only [Pi.inv_apply, map_inv, h π] @[to_additive] diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean index e236cc3e97cd77..8fdb74642fd2c4 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Limits.lean @@ -73,7 +73,7 @@ lemma toLimitFun_continuous (P : ProfiniteGrp.{u}) : Continuous (toLimitFun P) : apply continuous_induced_rng.mpr (continuous_pi _) intro H dsimp only [Functor.comp_obj, CompHausLike.coe_of, Functor.comp_map, - CompHausLike.toCompHausLike_map, CompHausLike.compHausLikeToTop_map, Set.mem_setOf_eq, + CompHausLike.toCompHausLike_map, CompHausLike.compHausLikeToTop_map, Set.mem_ofPred_eq, toLimitFun, MonoidHom.coe_mk, OneHom.coe_mk, Function.comp_apply] apply Continuous.mk intro s _ diff --git a/Mathlib/Topology/Algebra/ConstMulAction.lean b/Mathlib/Topology/Algebra/ConstMulAction.lean index 4a1d99ad78a349..3185cf45929522 100644 --- a/Mathlib/Topology/Algebra/ConstMulAction.lean +++ b/Mathlib/Topology/Algebra/ConstMulAction.lean @@ -169,13 +169,15 @@ theorem set_smul_closure_subset (s : Set M) (t : Set α) : s • closure t ⊆ c exact iUnion₂_subset fun c hc ↦ (smul_closure_subset c t).trans <| closure_mono <| subset_biUnion_of_mem (u := (· • t)) hc -theorem isClosed_setOf_map_smul {N : Type*} (α β) [SMul M α] [SMul N β] +theorem isClosed_setOfPred_map_smul {N : Type*} (α β) [SMul M α] [SMul N β] [TopologicalSpace β] [T2Space β] [ContinuousConstSMul N β] (σ : M → N) : IsClosed { f : α → β | ∀ c x, f (c • x) = σ c • f x } := by - simp only [Set.setOf_forall] + simp only [Set.ofPred_forall] exact isClosed_iInter fun c => isClosed_iInter fun x => isClosed_eq (continuous_apply _) ((continuous_apply _).const_smul _) +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_map_smul := isClosed_setOfPred_map_smul + end SMul section Monoid @@ -607,7 +609,7 @@ instance (priority := 100) t2Space_of_properlyDiscontinuousSMul_of_t2Space [T2Sp by_cases H : γ ∈ bad_Γ_set · exact fun h => (u_v_disjoint γ).le_bot ⟨mem_iInter₂.mp x_in_U₀₀ γ H, mem_iInter₂.mp h.1 γ H⟩ · rintro ⟨-, h'⟩ - simp only [bad_Γ_set, image_smul, not_nonempty_iff_eq_empty, mem_setOf_eq] at H + simp only [bad_Γ_set, image_smul, not_nonempty_iff_eq_empty, mem_ofPred_eq] at H exact eq_empty_iff_forall_notMem.mp H (γ • x) ⟨mem_image_of_mem _ x_in_K₀, h'⟩ /-- The quotient of a second countable space by a group action is second countable. -/ diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 597a465ef34eb1..4e5f532123f3fc 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -48,7 +48,7 @@ variable {G : Type w} {H : Type x} {α : Type u} {β : Type v} /-- In a Hausdorff magma with continuous multiplication, the centralizer of any set is closed. -/ lemma Set.isClosed_centralizer {M : Type*} (s : Set M) [Mul M] [TopologicalSpace M] [SeparatelyContinuousMul M] [T2Space M] : IsClosed (centralizer s) := by - rw [centralizer, setOf_forall] + rw [centralizer, ofPred_forall] refine isClosed_sInter ?_ rintro - ⟨m, ht, rfl⟩ refine isClosed_imp (by simp) <| isClosed_eq ?_ ?_ @@ -284,11 +284,17 @@ section PointwiseLimits variable (G₁ G₂ : Type*) [TopologicalSpace G₂] [T2Space G₂] @[to_additive] -theorem isClosed_setOf_map_inv [Inv G₁] [Inv G₂] [ContinuousInv G₂] : +theorem isClosed_setOfPred_map_inv [Inv G₁] [Inv G₂] [ContinuousInv G₂] : IsClosed { f : G₁ → G₂ | ∀ x, f x⁻¹ = (f x)⁻¹ } := by - simp only [setOf_forall] + simp only [ofPred_forall] exact isClosed_iInter fun i => isClosed_eq (continuous_apply _) (continuous_apply _).inv +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_map_inv := isClosed_setOfPred_map_inv + +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_map_neg := isClosed_setOfPred_map_neg + end PointwiseLimits instance [TopologicalSpace H] [Inv H] [ContinuousInv H] : ContinuousNeg (Additive H) where @@ -804,7 +810,7 @@ theorem Filter.HasBasis.nhds_of_one {ι : Sort*} {p : ι → Prop} {s : ι → S theorem mem_closure_iff_nhds_one {x : G} {s : Set G} : x ∈ closure s ↔ ∀ U ∈ (𝓝 1 : Filter G), ∃ y ∈ s, y / x ∈ U := by rw [mem_closure_iff_nhds_basis ((𝓝 1 : Filter G).basis_sets.nhds_of_one x)] - simp_rw [Set.mem_setOf, id] + simp_rw [Set.mem_ofPred, id] /-- A monoid homomorphism (a bundled morphism of a type that implements `MonoidHomClass`) from a topological group to a topological monoid is continuous @@ -1182,7 +1188,7 @@ theorem Subgroup.properlyDiscontinuousSMul_of_tendsto_cofinite (S : Subgroup G) rw [preimage_compl, compl_compl] at H convert! H ext x - simp only [image_smul, mem_setOf_eq, coe_subtype, mem_preimage, mem_image, Prod.exists] + simp only [image_smul, mem_ofPred_eq, coe_subtype, mem_preimage, mem_image, Prod.exists] exact Set.smul_inter_nonempty_iff' } /-- A subgroup `S` of a topological group `G` acts on `G` properly discontinuously on the right, if @@ -1209,7 +1215,7 @@ theorem Subgroup.properlyDiscontinuousSMul_opposite_of_tendsto_cofinite (S : Sub apply Finite.of_preimage _ (equivOp S).surjective convert! H using 1 ext x - simp only [image_smul, mem_setOf_eq, mem_preimage, mem_image, Prod.exists] + simp only [image_smul, mem_ofPred_eq, mem_preimage, mem_image, Prod.exists] exact Set.op_smul_inter_nonempty_iff } end diff --git a/Mathlib/Topology/Algebra/Group/CompactOpen.lean b/Mathlib/Topology/Algebra/Group/CompactOpen.lean index 36a25124e9fab8..9d1352ce388025 100644 --- a/Mathlib/Topology/Algebra/Group/CompactOpen.lean +++ b/Mathlib/Topology/Algebra/Group/CompactOpen.lean @@ -61,7 +61,7 @@ theorem isClosedEmbedding_toContinuousMap [ContinuousMul B] [T2Space B] : IsClosedEmbedding (toContinuousMap : ContinuousMonoidHom A B → C(A, B)) where toIsEmbedding := isEmbedding_toContinuousMap A B isClosed_range := by - simp only [range_toContinuousMap, Set.setOf_and, Set.setOf_forall] + simp only [range_toContinuousMap, Set.ofPred_and, Set.ofPred_forall] refine .inter (isClosed_singleton.preimage (continuous_eval_const 1)) <| isClosed_iInter fun x ↦ isClosed_iInter fun y ↦ ?_ exact isClosed_eq (continuous_eval_const (x * y)) <| @@ -169,7 +169,7 @@ theorem locallyCompactSpace_of_equicontinuousAt (U : Set X) (V : Set Y) rw [equicontinuous_iff_range, ← Set.image_eq_range] at h ⊢ rwa [← hS4] at h replace hS4 : S4 = Set.pi U (fun _ ↦ W) ∩ Set.range ((↑) : (X →* Y) → (X → Y)) := by - simp_rw [hS4, Set.ext_iff, Set.mem_image, S1, Set.mem_setOf_eq] + simp_rw [hS4, Set.ext_iff, Set.mem_image, S1, Set.mem_ofPred_eq] exact fun f ↦ ⟨fun ⟨g, hg, hf⟩ ↦ hf ▸ ⟨hg, g, rfl⟩, fun ⟨hg, g, hf⟩ ↦ ⟨g, hf ▸ hg, hf⟩⟩ replace hS4 : IsClosed S4 := hS4.symm ▸ (isClosed_set_pi (fun _ _ ↦ hWc.isClosed)).inter (MonoidHom.isClosed_range_coe X Y) @@ -177,7 +177,7 @@ theorem locallyCompactSpace_of_equicontinuousAt (U : Set X) (V : Set Y) let T : Set (ContinuousMonoidHom X Y) := {f | Set.MapsTo f U (interior W)} have h1 : T.Nonempty := ⟨1, fun _ _ ↦ mem_interior_iff_mem_nhds.mpr hWo⟩ have h2 : T ⊆ S2 := fun f hf ↦ hf.mono_right interior_subset - have h3 : IsOpen T := isOpen_induced (ContinuousMap.isOpen_setOf_mapsTo hU isOpen_interior) + have h3 : IsOpen T := isOpen_induced (ContinuousMap.isOpen_setOfPred_mapsTo hU isOpen_interior) exact h1.mono (interior_maximal h2 h3) exact TopologicalSpace.PositiveCompacts.locallyCompactSpace_of_group ⟨⟨S2, (isInducing_toContinuousMap X Y).isCompact_iff.mpr @@ -209,7 +209,7 @@ theorem locallyCompactSpace_of_hasBasis (V : ℕ → Set Y) apply locallyCompactSpace_of_equicontinuousAt (U 0) (V 0) hU0c (hVo.mem_of_mem trivial) rw [hVo.uniformity_of_nhds_one.equicontinuousAt_iff_right] refine fun n _ ↦ Filter.eventually_iff_exists_mem.mpr ⟨U n, hU1 n, fun x hx ⟨f, hf⟩ ↦ ?_⟩ - rw [Set.mem_setOf_eq, map_one, div_one] + rw [Set.mem_ofPred_eq, map_one, div_one] exact hU4 f hf n hx end LocallyCompact diff --git a/Mathlib/Topology/Algebra/Group/SubmonoidClosure.lean b/Mathlib/Topology/Algebra/Group/SubmonoidClosure.lean index b5c4ae89e78e98..c4ff6d865a4207 100644 --- a/Mathlib/Topology/Algebra/Group/SubmonoidClosure.lean +++ b/Mathlib/Topology/Algebra/Group/SubmonoidClosure.lean @@ -70,7 +70,7 @@ theorem mapClusterPt_atTop_pow_tfae (x y : G) : refine fun h ↦ closure_mono (range_subset_iff.2 fun n ↦ ?_) h exact ⟨n, zpow_natCast _ _⟩ tfae_have 4 → 1 := by - refine fun h ↦ closure_minimal ?_ isClosed_setOf_clusterPt h + refine fun h ↦ closure_minimal ?_ isClosed_setOfPred_clusterPt h exact range_subset_iff.2 (mapClusterPt_self_zpow_atTop_pow _) tfae_have 1 → 3 := by rw [mem_closure_iff_clusterPt] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean index e9c50bd7a3ace2..e53ce4e397d95c 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean @@ -254,7 +254,7 @@ theorem hasProd_fintype_support [Fintype β] (f : β → α) (L : SummationFilte (fun b hb ↦ (L.eventually_mem_or_not_mem b).resolve_left hb) filter_upwards [h1, h2] with s hs hs' congr 1 - simp only [Set.mem_iInter, Set.mem_setOf_eq, Set.mem_compl_iff] at hs hs' + simp only [Set.mem_iInter, Set.mem_ofPred_eq, Set.mem_compl_iff] at hs hs' grind @[to_additive] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean index d625839ecea1e3..c12a5cce20054b 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean @@ -84,7 +84,7 @@ protected lemma Multipliable.tprod_subtype_le {κ γ : Type*} [CommGroup γ] [Pa (∏' (b : β), f b) ≤ (∏' (a : κ), f a) := by apply Multipliable.tprod_le_tprod_of_inj _ (Subtype.coe_injective) - (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, h, implies_true]) + (by simp only [Subtype.range_coe_subtype, Set.ofPred_mem_eq, h, implies_true]) (by simp only [le_refl, implies_true]) (by apply hf.subtype) apply hf diff --git a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean index f9ef85a36b04fe..801e5042f17685 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/SummationFilter.lean @@ -63,13 +63,13 @@ def support (L : SummationFilter β) : Set β := {b | ∀ᶠ s in L.filter, b lemma support_eq_limsInf (L : SummationFilter β) : support L = limsInf (L.filter.map (↑)) := by refine eq_of_forall_ge_iff fun c ↦ ?_ - simpa [support, limsInf, setOf_subset] using + simpa [support, limsInf, ofPred_subset] using ⟨fun hL b hb x hx ↦ hL x <| hb.mp <| .of_forall fun c hc ↦ hc hx, fun hL x hx ↦ singleton_subset_iff.mp <| hL _ <| by simpa using hx⟩ lemma support_eq_univ_iff {L : SummationFilter β} : L.support = univ ↔ L.filter ≤ atTop := by - simp only [support, Set.eq_univ_iff_forall, Set.mem_setOf] + simp only [support, Set.eq_univ_iff_forall, Set.mem_ofPred] refine ⟨fun h s hs ↦ ?_, fun h b ↦ .filter_mono h ?_⟩ · obtain ⟨t, ht⟩ := mem_atTop_sets.mp hs have := (Filter.biInter_finset_mem t).mpr fun b hb ↦ h b diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean index a24630c413160c..307f33211b9590 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean @@ -643,7 +643,7 @@ instance QuotientGroup.completeSpace_right' (G : Type u) [Group G] [TopologicalS have h𝓤GN : (𝓤 (G ⧸ N)).HasBasis (fun _ ↦ True) fun i ↦ { x | x.snd / x.fst ∈ (↑) '' u i } := by simpa [uniformity_eq_comap_nhds_one', div_eq_mul_inv] using! hv.comap _ rw [h𝓤GN.cauchySeq_iff] at hx - simp only [mem_setOf_eq, forall_true_left, mem_image] at hx + simp only [mem_ofPred_eq, forall_true_left, mem_image] at hx intro i j rcases hx i with ⟨M, hM⟩ refine ⟨max j M + 1, (le_max_left _ _).trans_lt (lt_add_one _), fun a b ha hb g hg => ?_⟩ @@ -683,7 +683,7 @@ instance QuotientGroup.completeSpace_right' (G : Type u) [Group G] [TopologicalS have h𝓤G : (𝓤 G).HasBasis (fun _ => True) fun i => { x | x.snd / x.fst ∈ u i } := by simpa [uniformity_eq_comap_nhds_one', div_eq_mul_inv] using! hu.toHasBasis.comap _ rw [h𝓤G.cauchySeq_iff'] - simp only [mem_setOf_eq, forall_true_left] + simp only [mem_ofPred_eq, forall_true_left] exact fun m => ⟨m, fun n hmn => Nat.decreasingInduction' diff --git a/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean b/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean index 225fcd15c0dabf..bd6a920f499824 100644 --- a/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean +++ b/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean @@ -38,7 +38,7 @@ instance instTopologicalSpace : TopologicalSpace (E [⋀^ι]→L[𝕜] F) := lemma isClosed_range_toContinuousMultilinearMap [ContinuousSMul 𝕜 E] [T2Space F] : IsClosed (Set.range (toContinuousMultilinearMap : (E [⋀^ι]→L[𝕜] F) → ContinuousMultilinearMap 𝕜 (fun _ : ι ↦ E) F)) := by - simp only [range_toContinuousMultilinearMap, setOf_forall] + simp only [range_toContinuousMultilinearMap, ofPred_forall] repeat refine isClosed_iInter fun _ ↦ ?_ exact isClosed_singleton.preimage (continuous_eval_const _) diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index e2cd9a9f25d672..383e84088b4713 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -289,7 +289,7 @@ closure of the set of linear maps. -/ def linearMapOfMemClosureRangeCoe (f : M₁ → M₂) (hf : f ∈ closure (Set.range ((↑) : (M₁ →ₛₗ[σ] M₂) → M₁ → M₂))) : M₁ →ₛₗ[σ] M₂ := { addMonoidHomOfMemClosureRangeCoe f hf with - map_smul' := (isClosed_setOf_map_smul M₁ M₂ σ).closure_subset_iff.2 + map_smul' := (isClosed_setOfPred_map_smul M₁ M₂ σ).closure_subset_iff.2 (Set.range_subset_iff.2 map_smulₛₗ) hf } /-- Construct a bundled linear map from a pointwise limit of linear maps -/ diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean index 897509f1d31a82..bad87a10fb1fb8 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean @@ -137,9 +137,9 @@ theorem completeSpace (h : IsCoherentWith {s : Set (Π i, E i) | IsVonNBounded Continuous fun f : (Π i, E i) →ᵤ[{s | IsVonNBounded 𝕜 s}] F ↦ toFun _ f m := (uniformContinuous_eval (sUnion_isVonNBounded_eq_univ) _).continuous rw [completeSpace_iff_isComplete_range isUniformInducing_toUniformOnFun, range_toUniformOnFun] - simp only [setOf_and, setOf_forall] + simp only [ofPred_and, ofPred_forall] apply_rules [IsClosed.isComplete, IsClosed.inter] - · exact UniformOnFun.isClosed_setOf_continuous h + · exact UniformOnFun.isClosed_setOfPred_continuous h · exact isClosed_iInter fun m ↦ isClosed_iInter fun i ↦ isClosed_iInter fun x ↦ isClosed_iInter fun y ↦ isClosed_eq H (H.add H) · exact isClosed_iInter fun m ↦ isClosed_iInter fun i ↦ diff --git a/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean b/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean index b79ee86f3a79ae..50bcaaf522082f 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/CharacterSpace.lean @@ -122,7 +122,7 @@ theorem union_zero : /-- The `characterSpace 𝕜 A` along with `0` is always a closed set in `WeakDual 𝕜 A`. -/ theorem union_zero_isClosed [T2Space 𝕜] [ContinuousMul 𝕜] : IsClosed (characterSpace 𝕜 A ∪ {0}) := by - simp only [union_zero, Set.setOf_forall] + simp only [union_zero, Set.ofPred_forall] exact isClosed_iInter fun x => isClosed_iInter fun y => @@ -172,7 +172,7 @@ theorem eq_set_map_one_map_mul [Nontrivial 𝕜] : `WeakDual 𝕜 A`. -/ protected theorem isClosed [Nontrivial 𝕜] [T2Space 𝕜] [ContinuousMul 𝕜] : IsClosed (characterSpace 𝕜 A) := by - rw [eq_set_map_one_map_mul, Set.setOf_and] + rw [eq_set_map_one_map_mul, Set.ofPred_and] refine IsClosed.inter (isClosed_eq (eval_continuous _) continuous_const) ?_ simpa only [(union_zero 𝕜 A).symm] using union_zero_isClosed _ _ diff --git a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean index 2e68eaf7c2035a..7333c8e05c3273 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean @@ -398,7 +398,7 @@ theorem completeSpace [UniformSpace F] [IsUniformAddGroup F] [ContinuousSMul rw [completeSpace_iff_isComplete_range (isUniformInducing_coeFn _ _ _)] apply IsClosed.isComplete have H₁ : IsClosed {f : E →ᵤ[𝔖] F | Continuous ((UniformOnFun.toFun 𝔖) f)} := - UniformOnFun.isClosed_setOf_continuous h𝔖 + UniformOnFun.isClosed_setOfPred_continuous h𝔖 convert! H₁.inter <| (LinearMap.isClosed_range_coe E F σ).preimage diff --git a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean index 3aa854edeb47be..adf0c8d87dad25 100644 --- a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean +++ b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean @@ -84,7 +84,7 @@ lemma UniformFun.continuousSMul_induced_of_range_bounded (φ : hom) refine ⟨_, this hU, fun u hu x ↦ ?_⟩ simpa only [map_smul] using! hu x · intro u U hU - simp only [Set.mem_setOf_eq, map_smul, Pi.smul_apply] + simp only [Set.mem_ofPred_eq, map_smul, Pi.smul_apply] simpa only [Set.mapsTo_range_iff] using (h u hU).eventually_nhds_zero (mem_of_mem_nhds hU) /-- Let `E` be a TVS, `𝔖 : Set (Set α)` and `H` a submodule of `α →ᵤ[𝔖] E`. If the image of any diff --git a/Mathlib/Topology/Algebra/Monoid.lean b/Mathlib/Topology/Algebra/Monoid.lean index 4343372716e917..23c34ccf2b01b5 100644 --- a/Mathlib/Topology/Algebra/Monoid.lean +++ b/Mathlib/Topology/Algebra/Monoid.lean @@ -292,16 +292,23 @@ section PointwiseLimits variable (M₁ M₂ : Type*) [TopologicalSpace M₂] [T2Space M₂] @[to_additive] -theorem isClosed_setOf_map_one [One M₁] [One M₂] : IsClosed { f : M₁ → M₂ | f 1 = 1 } := +theorem isClosed_setOfPred_map_one [One M₁] [One M₂] : IsClosed { f : M₁ → M₂ | f 1 = 1 } := isClosed_eq (continuous_apply 1) continuous_const +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_map_one := isClosed_setOfPred_map_one + +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_map_zero := isClosed_setOfPred_map_zero + @[to_additive] -theorem isClosed_setOf_map_mul [Mul M₁] [Mul M₂] [ContinuousMul M₂] : +theorem isClosed_setOfPred_map_mul [Mul M₁] [Mul M₂] [ContinuousMul M₂] : IsClosed { f : M₁ → M₂ | ∀ x y, f (x * y) = f x * f y } := by - simp only [setOf_forall] + simp only [ofPred_forall] exact isClosed_iInter fun x ↦ isClosed_iInter fun y ↦ isClosed_eq (continuous_apply _) (by fun_prop) +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_map_mul := isClosed_setOfPred_map_mul +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_map_add := isClosed_setOfPred_map_add + section Semigroup variable {M₁ M₂} [Mul M₁] [Mul M₂] [ContinuousMul M₂] @@ -317,7 +324,8 @@ type of bundled homomorphisms that has an `AddHomClass` instance) to `M₁ → M def mulHomOfMemClosureRangeCoe (f : M₁ → M₂) (hf : f ∈ closure (range fun (f : F) (x : M₁) => f x)) : M₁ →ₙ* M₂ where toFun := f - map_mul' := (isClosed_setOf_map_mul M₁ M₂).closure_subset_iff.2 (range_subset_iff.2 map_mul) hf + map_mul' := (isClosed_setOfPred_map_mul M₁ M₂).closure_subset_iff.2 + (range_subset_iff.2 map_mul) hf /-- Construct a bundled semigroup homomorphism from a pointwise limit of semigroup homomorphisms. -/ @[to_additive (attr := simps! -fullyApplied) @@ -351,8 +359,10 @@ type of bundled homomorphisms that has an `AddMonoidHomClass` instance) to `M₁ def monoidHomOfMemClosureRangeCoe (f : M₁ → M₂) (hf : f ∈ closure (range fun (f : F) (x : M₁) => f x)) : M₁ →* M₂ where toFun := f - map_one' := (isClosed_setOf_map_one M₁ M₂).closure_subset_iff.2 (range_subset_iff.2 map_one) hf - map_mul' := (isClosed_setOf_map_mul M₁ M₂).closure_subset_iff.2 (range_subset_iff.2 map_mul) hf + map_one' := (isClosed_setOfPred_map_one M₁ M₂).closure_subset_iff.2 + (range_subset_iff.2 map_one) hf + map_mul' := (isClosed_setOfPred_map_mul M₁ M₂).closure_subset_iff.2 + (range_subset_iff.2 map_mul) hf /-- Construct a bundled monoid homomorphism from a pointwise limit of monoid homomorphisms. -/ @[to_additive (attr := simps! -fullyApplied) diff --git a/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean b/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean index da2292edd9312e..119e3d57f65efd 100644 --- a/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean +++ b/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean @@ -197,7 +197,7 @@ lemma limsup_const_sub (F : Filter ι) [AddCommSemigroup R] [Sub R] [ContinuousS (cobdd : F.IsCoboundedUnder (· ≥ ·) f) (bdd_below : F.IsBoundedUnder (· ≥ ·) f) : Filter.limsup (fun i ↦ c - f i) F = c - Filter.liminf f F := by rcases F.eq_or_neBot with rfl | _ - · simp only [liminf, limsInf, limsup, limsSup, map_bot, eventually_bot, Set.setOf_true] + · simp only [liminf, limsInf, limsup, limsSup, map_bot, eventually_bot, Set.ofPred_true] simp only [IsCoboundedUnder, IsCobounded, map_bot, eventually_bot, true_implies] at cobdd rcases cobdd with ⟨x, hx⟩ refine (csInf_le ?_ (Set.mem_univ _)).antisymm @@ -222,7 +222,7 @@ lemma limsup_sub_const (F : Filter ι) [AddCommSemigroup R] [Sub R] [ContinuousS rcases cobdd with ⟨x, hx⟩ refine ⟨x, mem_lowerBounds.2 fun y ↦ ?_⟩ simp only [Set.mem_univ, hx y, implies_true] - simp only [limsup, limsSup, map_bot, eventually_bot, Set.setOf_true] + simp only [limsup, limsSup, map_bot, eventually_bot, Set.ofPred_true] exact this.antisymm (tsub_le_iff_right.2 this) · apply (Monotone.map_limsSup_of_continuousAt (F := F.map f) (f := fun (x : R) ↦ x - c) _ _).symm · exact fun _ _ h ↦ tsub_le_tsub_right h c diff --git a/Mathlib/Topology/Algebra/PontryaginDual.lean b/Mathlib/Topology/Algebra/PontryaginDual.lean index 2dd281ea6672e0..dc806407ffe9f0 100644 --- a/Mathlib/Topology/Algebra/PontryaginDual.lean +++ b/Mathlib/Topology/Algebra/PontryaginDual.lean @@ -85,7 +85,7 @@ instance [CompactSpace A] : DiscreteTopology (PontryaginDual A) := by let V : Set (PontryaginDual A) := {ψ | Set.MapsTo ψ Set.univ (Circle.centeredArc (π / 2))} have hVopen : IsOpen V := by dsimp only [V] - exact isOpen_induced (ContinuousMap.isOpen_setOf_mapsTo isCompact_univ + exact isOpen_induced (ContinuousMap.isOpen_setOfPred_mapsTo isCompact_univ (Circle.isOpen_centeredArc (π / 2))) have hVeq : V = ({1} : Set (PontryaginDual A)) := by ext ψ diff --git a/Mathlib/Topology/Algebra/ProperAction/Basic.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean index 99ab94ef9ebc6a..175b8c6a90b523 100644 --- a/Mathlib/Topology/Algebra/ProperAction/Basic.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -260,14 +260,14 @@ open scoped Pointwise in /-- If `G` acts properly on `X`, then for each pair of compacts `U, V ⊆ X`, the set of `g` such that `g • U` intersects `V` is compact. -See `MulAction.properSMul_iff_isCompact_setOf_inter_nonempty` for the two-way implication +See `MulAction.properSMul_iff_isCompact_setOfPred_inter_nonempty` for the two-way implication under additional conditions on `G` and `X`. -/ @[to_additive /-- If `G` acts properly on `X`, then for each pair of compacts `U, V ⊆ X`, the set of `g` such that `g +ᵥ U` intersects `V` is compact. -See `AddAction.properVAdd_iff_isCompact_setOf_inter_nonempty` for the two-way implication +See `AddAction.properVAdd_iff_isCompact_setOfPred_inter_nonempty` for the two-way implication under additional conditions on `G` and `X`. -/] -lemma ProperSMul.isCompact_setOf_inter_nonempty +lemma ProperSMul.isCompact_setOfPred_inter_nonempty {G : Type*} [Group G] [MulAction G X] [TopologicalSpace G] [ProperSMul G X] {U V : Set X} (hU : IsCompact U) (hV : IsCompact V) : IsCompact {g : G | (g • U ∩ V).Nonempty} := by @@ -279,6 +279,12 @@ lemma ProperSMul.isCompact_setOf_inter_nonempty rw [← (MulAction.toPerm g).exists_congr_right] simp [and_comm] +@[deprecated (since := "2026-07-09")] +alias ProperSMul.isCompact_setOf_inter_nonempty := ProperSMul.isCompact_setOfPred_inter_nonempty + +@[deprecated (since := "2026-07-09")] +alias ProperVAdd.isCompact_setOf_inter_nonempty := ProperVAdd.isCompact_setOfPred_inter_nonempty + /-- If `G` acts transitively on `X`, and the orbit map of a point in `X` is a proper map, then the action is proper. -/ @[to_additive] diff --git a/Mathlib/Topology/Algebra/ProperAction/CompactlyGenerated.lean b/Mathlib/Topology/Algebra/ProperAction/CompactlyGenerated.lean index 9a98e8768fcde7..f7c2b083c2e676 100644 --- a/Mathlib/Topology/Algebra/ProperAction/CompactlyGenerated.lean +++ b/Mathlib/Topology/Algebra/ProperAction/CompactlyGenerated.lean @@ -22,8 +22,8 @@ weakly locally compact. * `properlyDiscontinuousSMul_iff_properSMul`: If a discrete group acts on a T2 space `X` such that `X × X` is compactly generated, and if the action is continuous in the second variable, then the action is properly discontinuous if and only if it is proper. -* `MulAction.properSMul_iff_isCompact_setOf_inter_nonempty`: if `G` is a topological group acting - continuously on a T2 space `X` such that `X × X` is compactly generated, then the action is +* `MulAction.properSMul_iff_isCompact_setOfPred_inter_nonempty`: if `G` is a topological group + acting continuously on a T2 space `X` such that `X × X` is compactly generated, then the action is proper iff, for each pair of compacts `U, V ⊆ X`, the set of `g : G` such that `g • U` intersects `V` is compact. @@ -44,7 +44,7 @@ variable {G X : Type*} [TopologicalSpace X] [Group G] /-- The `G`-action on `X` is proper iff, for each pair of compacts `U, V` in `X`, the set of `g` such that `U` intersects `g • V` is compact. -See `ProperSMul.isCompact_setOf_inter_nonempty` +See `ProperSMul.isCompact_setOfPred_inter_nonempty` for a one-way implication with fewer conditions. **Note**: We assume `CompactlyCoherentSpace (X × X)` @@ -57,7 +57,7 @@ Importing `Mathlib.Topology.Sequences` makes this implication available. The `G`-action on `X` is proper iff, for each pair of compacts `U, V` in `X`, the set of `g` such that `U` intersects `g +ᵥ V` is compact. -See `ProperVAdd.isCompact_setOf_inter_nonempty` +See `ProperVAdd.isCompact_setOfPred_inter_nonempty` for a one-way implication with fewer conditions. **Note**: We assume `CompactlyCoherentSpace (X × X)` @@ -66,10 +66,10 @@ but this follows from various more familiar conditions, such as `FirstCountableTopology X`. Importing `Mathlib.Topology.Sequences` makes this implication available. -/] -lemma MulAction.properSMul_iff_isCompact_setOf_inter_nonempty [ContinuousSMul G X] : +lemma MulAction.properSMul_iff_isCompact_setOfPred_inter_nonempty [ContinuousSMul G X] : ProperSMul G X ↔ (∀ {U V : Set X}, IsCompact U → IsCompact V → IsCompact {g : G | (g • U ∩ V).Nonempty}) := by - refine ⟨fun h ↦ ProperSMul.isCompact_setOf_inter_nonempty, fun h ↦ ⟨?_⟩⟩ + refine ⟨fun h ↦ ProperSMul.isCompact_setOfPred_inter_nonempty, fun h ↦ ⟨?_⟩⟩ refine isProperMap_iff_isCompact_preimage.mpr ⟨by fun_prop, fun {K} hK ↦ ?_⟩ -- First reduce to the case `K = U × V`. let U := Prod.fst '' K @@ -83,6 +83,14 @@ lemma MulAction.properSMul_iff_isCompact_setOf_inter_nonempty [ContinuousSMul G · exact (hU.prod hV).isClosed.preimage (by fun_prop) · exact fun ⟨g, x⟩ ⟨hgx, hgx'⟩ ↦ ⟨⟨g • x, smul_mem_smul_set hgx', hgx⟩, hgx'⟩ +@[deprecated (since := "2026-07-09")] +alias MulAction.properSMul_iff_isCompact_setOf_inter_nonempty := + MulAction.properSMul_iff_isCompact_setOfPred_inter_nonempty + +@[deprecated (since := "2026-07-09")] +alias AddAction.properVAdd_iff_isCompact_setOf_inter_nonempty := + AddAction.properVAdd_iff_isCompact_setOfPred_inter_nonempty + /-- If a discrete group acts on a T2 space `X` such that `X × X` is compactly generated, and if the action is continuous in the second variable, then the action is properly discontinuous if and only if it is proper. This is in particular true if `X` is first-countable or @@ -91,7 +99,7 @@ weakly locally compact. -/ theorem properlyDiscontinuousSMul_iff_properSMul [DiscreteTopology G] [ContinuousConstSMul G X] : ProperlyDiscontinuousSMul G X ↔ ProperSMul G X := by have : ContinuousSMul G X := ⟨continuous_prod_of_discrete_left.mpr continuous_const_smul⟩ - simp only [MulAction.properSMul_iff_isCompact_setOf_inter_nonempty, isCompact_iff_finite] + simp only [MulAction.properSMul_iff_isCompact_setOfPred_inter_nonempty, isCompact_iff_finite] rw [properlyDiscontinuousSMul_iff] end diff --git a/Mathlib/Topology/Algebra/Semigroup.lean b/Mathlib/Topology/Algebra/Semigroup.lean index ad53ea93e5cab3..0099f7f85f85e7 100644 --- a/Mathlib/Topology/Algebra/Semigroup.lean +++ b/Mathlib/Topology/Algebra/Semigroup.lean @@ -52,7 +52,7 @@ theorem exists_idempotent_of_compact_t2_of_continuous_mul_left {M} [Nonempty M] · rwa [← scaling_eq_self] at hm · rintro m'' ⟨mem'', eq'' : _ = m⟩ m' ⟨mem', eq' : _ = m⟩ refine ⟨N_mul _ mem'' _ mem', ?_⟩ - rw [Set.mem_setOf_eq, mul_assoc, eq', eq''] + rw [Set.mem_ofPred_eq, mul_assoc, eq', eq''] apply Set.inter_subset_left rw [← absorbing_eq_self] at hm exact hm.2 diff --git a/Mathlib/Topology/Algebra/Support.lean b/Mathlib/Topology/Algebra/Support.lean index 333e0edf1cc137..6724d9a28680cf 100644 --- a/Mathlib/Topology/Algebra/Support.lean +++ b/Mathlib/Topology/Algebra/Support.lean @@ -528,7 +528,7 @@ theorem LocallyFinite.exists_finset_nhds_mulSupport_subset {U : ι → Set X} [O rw [inter_assoc] at hz exact mem_of_mem_inter_left hz replace hz := mem_of_mem_inter_right (mem_of_mem_inter_left hz) - simp only [js, Finset.mem_filter, Finite.mem_toFinset, mem_setOf_eq, mem_iInter, + simp only [js, Finset.mem_filter, Finite.mem_toFinset, mem_ofPred_eq, mem_iInter, and_imp] at hz suffices (mulSupport fun i => f i z) ⊆ hnf.toFinset by refine hnf.toFinset.subset_coe_filter_of_subset_forall _ this fun i hi => ?_ @@ -536,7 +536,7 @@ theorem LocallyFinite.exists_finset_nhds_mulSupport_subset {U : ι → Set X} [O contrapose hz simp [hz, subset_mulTSupport (f i) hi] intro i hi - simp only [Finite.coe_toFinset, mem_setOf_eq] + simp only [Finite.coe_toFinset, mem_ofPred_eq] exact ⟨z, ⟨hi, hzn⟩⟩ @[to_additive] diff --git a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean index 6d216faa17e70e..73cb9a4d4b0acf 100644 --- a/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean +++ b/Mathlib/Topology/Algebra/ValuativeRel/ValuativeTopology.lean @@ -42,7 +42,7 @@ noncomputable section variable (R : Type*) [Ring R] [ValuativeRel R] variable {R} in -lemma Valuation.exists_setOf_restrict_le_iff {Γ₀ : Type*} [LinearOrderedCommGroupWithZero Γ₀] +lemma Valuation.exists_setOfPred_restrict_le_iff {Γ₀ : Type*} [LinearOrderedCommGroupWithZero Γ₀] (v : Valuation R Γ₀) [v.Compatible] (x : R) (s : Set R) : (∃ γ : (ValueGroup₀ (.ofClass v))ˣ, {z | v.restrict (z - x) < γ.val} ⊆ s) ↔ ∃ γ : (ValueGroupWithZero R)ˣ, {a | valuation R (a - x) < γ} ⊆ s := by @@ -50,6 +50,9 @@ lemma Valuation.exists_setOf_restrict_le_iff {Γ₀ : Type*} [LinearOrderedCommG fun ⟨r, hr⟩ ↦ ⟨r.mapEquiv (orderMonoidIso v), ?_⟩⟩ all_goals convert! hr; simp +@[deprecated (since := "2026-07-09")] +alias Valuation.exists_setOf_restrict_le_iff := Valuation.exists_setOfPred_restrict_le_iff + /-- We say that a topology on `R` is valuative if the neighborhoods of `0` in `R` are determined by the valuative relation `· ≤ᵥ ·`. -/ class IsValuativeTopology [TopologicalSpace R] where @@ -70,7 +73,7 @@ instance nonarchimedeanRing : NonarchimedeanRing R := instance isValuativeTopology : IsValuativeTopology R where mem_nhds_iff {s x} := by rw [Filter.hasBasis_iff.mp ((valuation R).subgroups_basis.hasBasis_nhds x) s] - simp [neg_add_eq_sub, ← (valuation R).exists_setOf_restrict_le_iff, + simp [neg_add_eq_sub, ← (valuation R).exists_setOfPred_restrict_le_iff, ← restrict_lt_iff_lt_embedding] /-- The uniform structure induced by a valuative relation. Note that this is not made into a @@ -167,7 +170,7 @@ namespace Valuation lemma mem_nhds_iff {s : Set R} {x : R} : s ∈ 𝓝 x ↔ ∃ γ : (ValueGroup₀ (.ofClass v))ˣ, { z | v.restrict (z - x) < γ.val } ⊆ s := by convert! IsValuativeTopology.mem_nhds_iff (s := s) using 4 - simpa [neg_add_eq_sub] using v.exists_setOf_restrict_le_iff _ _ + simpa [neg_add_eq_sub] using v.exists_setOfPred_restrict_le_iff _ _ lemma mem_nhds_zero_iff (s : Set R) : s ∈ 𝓝 0 ↔ ∃ γ : (ValueGroup₀ (.ofClass v))ˣ, { x | v.restrict x < γ.val } ⊆ s := by @@ -276,7 +279,7 @@ section Discrete lemma discreteTopology_of_forall_map_eq_one (h : ∀ x : R, x ≠ 0 → v x = 1) : DiscreteTopology R := by simp only [discreteTopology_iff_isOpen_singleton_zero, isOpen_iff_mem_nhds, mem_singleton_iff, - forall_eq, v.mem_nhds_zero_iff, subset_singleton_iff, mem_setOf_eq] + forall_eq, v.mem_nhds_zero_iff, subset_singleton_iff, mem_ofPred_eq] use 1 contrapose! h obtain ⟨x, hx, hx'⟩ := h @@ -300,7 +303,7 @@ theorem isOpen_ball (r : ValueGroup₀ (.ofClass v)) : IsOpen {x | v.restrict x · simp intro x hx rw [v.mem_nhds_iff] - simp only [setOf_subset_setOf] + simp only [ofPred_subset_ofPred] exact ⟨Units.mk0 _ hr, fun y hy ↦ (sub_add_cancel y x).symm ▸ (v.restrict.map_add _ x).trans_lt (max_lt hy hx)⟩ @@ -325,7 +328,7 @@ theorem isOpen_closedBall {r : ValueGroup₀ (.ofClass v)} (hr : r ≠ 0) : IsOpen {x | v.restrict x ≤ r} := by rw [isOpen_iff_mem_nhds] intro x hx - simp only [v.mem_nhds_iff, setOf_subset_setOf] + simp only [v.mem_nhds_iff, ofPred_subset_ofPred] exact ⟨Units.mk0 _ hr, fun y hy ↦ (sub_add_cancel y x).symm ▸ le_trans (v.restrict.map_add _ _) (max_le (le_of_lt hy) hx)⟩ @@ -336,7 +339,7 @@ theorem isClosed_closedBall (r : ValueGroup₀ (.ofClass v)) : IsClosed {x | v.restrict x ≤ r} := by rw [← isOpen_compl_iff, isOpen_iff_mem_nhds] intro x hx - simp only [mem_compl_iff, mem_setOf_eq, not_le] at hx + simp only [mem_compl_iff, mem_ofPred_eq, not_le] at hx rw [v.mem_nhds_iff] have hx' : v.restrict x ≠ 0 := hx.ne_zero exact ⟨Units.mk0 _ hx', fun y hy hy' ↦ ne_of_lt hy <| map_sub_swap v.restrict x y ▸ diff --git a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean index 9900a414ab07e1..de3604c9b4a537 100644 --- a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean +++ b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean @@ -69,17 +69,18 @@ lemma norm_irreducible_pos {ϖ : 𝒪[K]} (h : Irreducible ϖ) : 0 < ‖ϖ‖ := lemma coe_span_singleton_eq_closedBall (x : 𝒪[K]) : (Ideal.span {x} : Set 𝒪[K]) = Metric.closedBall 0 ‖x‖ := by - simp [Valuation.integer.coe_span_singleton_eq_setOf_le_v_coe, Set.ext_iff, ← NNReal.coe_le_coe] + simp [Valuation.integer.coe_span_singleton_eq_setOfPred_le_v_coe, Set.ext_iff, + ← NNReal.coe_le_coe] lemma _root_.Irreducible.maximalIdeal_eq_closedBall [IsDiscreteValuationRing 𝒪[K]] {ϖ : 𝒪[K]} (h : Irreducible ϖ) : (𝓂[K] : Set 𝒪[K]) = Metric.closedBall 0 ‖ϖ‖ := by - simp [h.maximalIdeal_eq_setOf_le_v_coe, Set.ext_iff, ← NNReal.coe_le_coe] + simp [h.maximalIdeal_eq_setOfPred_le_v_coe, Set.ext_iff, ← NNReal.coe_le_coe] lemma _root_.Irreducible.maximalIdeal_pow_eq_closedBall_pow [IsDiscreteValuationRing 𝒪[K]] {ϖ : 𝒪[K]} (h : Irreducible ϖ) (n : ℕ) : ((𝓂[K] ^ n : Ideal 𝒪[K]) : Set 𝒪[K]) = Metric.closedBall 0 (‖ϖ‖ ^ n) := by - simp [h.maximalIdeal_pow_eq_setOf_le_v_coe_pow, Set.ext_iff, ← NNReal.coe_le_coe] + simp [h.maximalIdeal_pow_eq_setOfPred_le_v_coe_pow, Set.ext_iff, ← NNReal.coe_le_coe] variable (K) in lemma exists_norm_coe_lt_one : ∃ x : 𝒪[K], 0 < ‖(x : K)‖ ∧ ‖(x : K)‖ < 1 := by @@ -152,7 +153,7 @@ lemma totallyBounded_iff_finite_residueField [(Valued.v : Valuation K Γ₀).Ran -- TODO: make Valued.maximalIdeal abbreviations instead of def rw [Valued.maximalIdeal, hp.maximalIdeal_eq, ← SetLike.mem_coe, - (Valuation.integer.integers _).coe_span_singleton_eq_setOf_le_v_algebraMap] + (Valuation.integer.integers _).coe_span_singleton_eq_setOfPred_le_v_algebraMap] rw [dist_comm] at hy' simpa [dist_eq_norm] using! hy'.le · intro H @@ -167,7 +168,8 @@ lemma totallyBounded_iff_finite_residueField [(Valued.v : Valuation K Γ₀).Ran have : {y : 𝒪[K] | v (y : K) ≤ v (p : K) ^ n} = Metric.closedBall 0 (‖p‖ ^ n) := by ext simp [← norm_pow] - simp only [Ideal.univ_eq_iUnion_image_add (𝓂[K] ^ n), hp.maximalIdeal_pow_eq_setOf_le_v_coe_pow, + simp only [Ideal.univ_eq_iUnion_image_add (𝓂[K] ^ n), + hp.maximalIdeal_pow_eq_setOfPred_le_v_coe_pow, this, AddSubgroupClass.coe_norm, Set.image_univ, Set.mem_range, Set.iUnion_exists, Set.iUnion_iUnion_eq', Set.iUnion_subset_iff, Metric.vadd_closedBall, vadd_eq_add, add_zero] intro @@ -264,7 +266,7 @@ lemma locallyFiniteOrder_units_mrange_of_isCompact_integer (hc : IsCompact (X := push Not at hi' exact Subtype.coe_injective.ne_iff.mp (hi'.trans' z0).ne' · intro i - simp only [Set.mem_Icc, Finset.mem_coe, exists_prop, Set.mem_setOf_eq, and_imp] + simp only [Set.mem_Icc, Finset.mem_coe, exists_prop, Set.mem_ofPred_eq, and_imp] -- we get the `c` from the cover that covers our arbitrary `i` with its set obtain ⟨c, hc⟩ := i.val.prop intro hzi hi1 @@ -275,9 +277,9 @@ lemma locallyFiniteOrder_units_mrange_of_isCompact_integer (hc : IsCompact (X := -- and this `c` is either less than or greater than (or equal to) the threshold element simp only [MonoidWithZeroHom.coe_ofClass] at hc split_ifs at hj' with hcj - · simp only [Set.mem_setOf_eq, hc, Subtype.coe_le_coe, Units.val_le_val] at hj' + · simp only [Set.mem_ofPred_eq, hc, Subtype.coe_le_coe, Units.val_le_val] at hj' simp [hcj, le_antisymm hj' hzi] - · simp only [Set.mem_setOf_eq] at hj' + · simp only [Set.mem_ofPred_eq] at hj' rw [dif_neg hcj] simp [← hj', hc] @@ -338,7 +340,7 @@ lemma compactSpace_iff_completeSpace_and_isDiscreteValuationRing_and_finite_resi lemma properSpace_iff_compactSpace_integer [(Valued.v : Valuation K Γ₀).RankOne] : ProperSpace K ↔ CompactSpace 𝒪[K] := by simp only [← isCompact_univ_iff, Subtype.isCompact_iff, Set.image_univ, Subtype.range_coe_subtype, - toNormedField.setOf_mem_integer_eq_closedBall] + toNormedField.setOfPred_mem_integer_eq_closedBall] constructor <;> intro h · exact isCompact_closedBall 0 1 · suffices LocallyCompactSpace K from .of_nontriviallyNormedField_of_weaklyLocallyCompactSpace K @@ -350,7 +352,7 @@ lemma properSpace_iff_completeSpace_and_isDiscreteValuationRing_integer_and_fini ProperSpace K ↔ CompleteSpace K ∧ IsDiscreteValuationRing 𝒪[K] ∧ Finite 𝓀[K] := by simp only [properSpace_iff_compactSpace_integer, compactSpace_iff_completeSpace_and_isDiscreteValuationRing_and_finite_residueField, - toNormedField.setOf_mem_integer_eq_closedBall, + toNormedField.setOfPred_mem_integer_eq_closedBall, completeSpace_iff_isComplete_univ (α := 𝒪[K]), Subtype.isComplete_iff, NormedField.completeSpace_iff_isComplete_closedBall, Set.image_univ, Subtype.range_coe_subtype] diff --git a/Mathlib/Topology/Algebra/Valued/NormedValued.lean b/Mathlib/Topology/Algebra/Valued/NormedValued.lean index d18ca876b0c5fb..afef2272800e22 100644 --- a/Mathlib/Topology/Algebra/Valued/NormedValued.lean +++ b/Mathlib/Topology/Algebra/Valued/NormedValued.lean @@ -76,7 +76,7 @@ def toValued : Valued K ℝ≥0 := rcases RankLeOne.exists_val_lt (valuation (K := K)) with H | H · use Units.mk0 (valuation.restrict 1) (by simp) intro x hx - simp only [Units.val_mk0, mem_setOf_eq, map_one] at hx + simp only [Units.val_mk0, mem_ofPred_eq, map_one] at hx by_cases hx0 : x = 0 · exact h (hx0 ▸ Metric.mem_ball_self hε) · exfalso @@ -91,7 +91,7 @@ def toValued : Valued K ℝ≥0 := intro y hy apply h simp only [Metric.mem_ball, dist_zero_right] - simp only [Units.val_mk0, mem_setOf_eq, restrict_lt_iff, ← NNReal.coe_lt_coe] at hy + simp only [Units.val_mk0, mem_ofPred_eq, restrict_lt_iff, ← NNReal.coe_lt_coe] at hy apply lt_trans hy simpa [RankLeOne.hom', valuation.restrict_def] using! hxy · rintro ⟨ε, hε⟩ @@ -178,8 +178,8 @@ def toNormedField : NormedField L := use δ, hδ_pos apply subset_trans _ hε intro x hx - simp only [mem_setOf_eq, Valuation.norm, hδ, NNReal.coe_lt_coe] at hx - rw [mem_setOf, ← neg_sub, Valuation.map_neg] + simp only [mem_ofPred_eq, Valuation.norm, hδ, NNReal.coe_lt_coe] at hx + rw [mem_ofPred, ← neg_sub, Valuation.map_neg] exact (RankOne.strictMono Valued.v).lt_iff_lt.mp hx · have : Nontrivial Γ₀ˣ := (nontrivial_iff_exists_ne (1 : Γ₀ˣ)).mpr ⟨RankOne.unit val.v, RankOne.unit_ne_one val.v⟩ @@ -187,14 +187,14 @@ def toNormedField : NormedField L := use u apply subset_trans _ hr intro x hx - simp only [Valuation.norm, mem_setOf_eq] + simp only [Valuation.norm, mem_ofPred_eq] apply lt_trans _ hu rw [NNReal.coe_lt_coe, ← neg_sub, Valuation.map_neg] exact (RankOne.strictMono Valued.v).lt_iff_lt.mpr hx · simp only [Directed] intro x y use min x y - simp only [le_principal_iff, mem_principal, setOf_subset_setOf, Prod.forall] + simp only [le_principal_iff, mem_principal, ofPred_subset_ofPred, Prod.forall] exact ⟨fun a b hab => lt_of_lt_of_le hab (min_le_left _ _), fun a b hab => lt_of_lt_of_le hab (min_le_right _ _)⟩ } @@ -258,11 +258,14 @@ theorem one_lt_norm_iff : 1 < ‖x‖ ↔ 1 < val.v x := by rw [← map_one val.v, ← v.restrict_lt_iff] simpa only [map_one] using! (Valuation.RankOne.strictMono val.v).lt_iff_lt (a := 1) -lemma setOf_mem_integer_eq_closedBall : +lemma setOfPred_mem_integer_eq_closedBall : { x : L | x ∈ Valued.v.integer } = Metric.closedBall 0 1 := by ext x simp [mem_integer_iff] +@[deprecated (since := "2026-07-09")] +alias setOf_mem_integer_eq_closedBall := setOfPred_mem_integer_eq_closedBall + end toNormedField /-- diff --git a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean index 32e92c2d0aaf73..2eeaf86c8b915a 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean @@ -72,8 +72,8 @@ theorem subgroups_basis : use γ₀ rintro - ⟨r, r_in, s, s_in, rfl⟩ simp only [ltAddSubgroup, Units.coe_map, MonoidHom.coe_coe, AddSubgroup.coe_set_mk, - AddSubmonoid.coe_set_mk, AddSubsemigroup.coe_set_mk, mem_setOf_eq] at r_in s_in - simp only [coe_ltAddSubgroup, Units.coe_map, MonoidHom.coe_coe, mem_setOf_eq] + AddSubmonoid.coe_set_mk, AddSubsemigroup.coe_set_mk, mem_ofPred_eq] at r_in s_in + simp only [coe_ltAddSubgroup, Units.coe_map, MonoidHom.coe_coe, mem_ofPred_eq] rw [← restrict_lt_iff_lt_embedding] at * calc v.restrict (r * s) = v.restrict r * v.restrict s := Valuation.map_mul _ _ _ @@ -84,7 +84,7 @@ theorem subgroups_basis : rcases GroupWithZero.eq_zero_or_unit (v x) with (Hx | ⟨γx, Hx⟩) · use (1 : (ValueGroup₀ (.ofClass v))ˣ) rintro y _ - simp only [coe_ltAddSubgroup, preimage_setOf_eq, mem_setOf_eq] + simp only [coe_ltAddSubgroup, preimage_ofPred_eq, mem_ofPred_eq] rw [Valuation.map_mul, Hx, zero_mul] exact Units.zero_lt _ · set u : (ValueGroup₀ (.ofClass v))ˣ := Units.mk0 ((restrict₀ (.ofClass v)) x) @@ -93,7 +93,7 @@ theorem subgroups_basis : simp [restrict₀_apply, embedding_apply, hu_def, Hx] use u⁻¹ * γ rintro y (vy_lt : v y < ValueGroup₀.embedding (u⁻¹ * γ).1) - simp only [coe_ltAddSubgroup, preimage_setOf_eq, mem_setOf_eq] + simp only [coe_ltAddSubgroup, preimage_ofPred_eq, mem_ofPred_eq] rw [Valuation.map_mul, Hx, mul_comm] rw [Units.val_mul, mul_comm, map_mul, hu] at vy_lt simpa using mul_inv_lt_of_lt_mul₀ vy_lt @@ -102,7 +102,7 @@ theorem subgroups_basis : rcases GroupWithZero.eq_zero_or_unit (v x) with (Hx | ⟨γx, Hx⟩) · use 1 rintro y _ - simp only [coe_ltAddSubgroup, preimage_setOf_eq, mem_setOf_eq, Valuation.map_mul, Hx, + simp only [coe_ltAddSubgroup, preimage_ofPred_eq, mem_ofPred_eq, Valuation.map_mul, Hx, mul_zero, Units.zero_lt] · set u : (ValueGroup₀ (.ofClass v))ˣ := Units.mk0 ((restrict₀ (.ofClass v)) x) (by simp [restrict₀_apply]; aesop) with hu_def @@ -110,7 +110,7 @@ theorem subgroups_basis : hu_def, Hx] use u⁻¹ * γ rintro y (vy_lt : v y < ValueGroup₀.embedding (u⁻¹ * γ).1) - simp only [coe_ltAddSubgroup, preimage_setOf_eq, mem_setOf_eq, Valuation.map_mul, Hx] + simp only [coe_ltAddSubgroup, preimage_ofPred_eq, mem_ofPred_eq, Valuation.map_mul, Hx] rw [Units.val_mul, mul_comm, map_mul, hu] at vy_lt simpa using mul_inv_lt_of_lt_mul₀ vy_lt } @@ -171,7 +171,7 @@ variable {R Γ₀} theorem mem_nhds {s : Set R} {x : R} : s ∈ 𝓝 x ↔ ∃ γ : (MonoidWithZeroHom.ValueGroup₀ (.ofClass _i.v))ˣ, { y | (v.restrict (y - x) ) < γ.1 } ⊆ s := by - simp only [← nhds_translation_add_neg x, ← sub_eq_add_neg, preimage_setOf_eq, true_and, + simp only [← nhds_translation_add_neg x, ← sub_eq_add_neg, preimage_ofPred_eq, true_and, ((hasBasis_nhds_zero R Γ₀).comap fun y ↦ y - x).mem_iff] theorem mem_nhds_zero {s : Set R} : s ∈ 𝓝 (0 : R) ↔ @@ -199,7 +199,7 @@ section Discrete lemma discreteTopology_of_forall_map_eq_one (h : ∀ x : R, x ≠ 0 → v x = 1) : DiscreteTopology R := by simp only [discreteTopology_iff_isOpen_singleton_zero, isOpen_iff_mem_nhds, mem_singleton_iff, - forall_eq, mem_nhds_zero, subset_singleton_iff, mem_setOf_eq] + forall_eq, mem_nhds_zero, subset_singleton_iff, mem_ofPred_eq] use 1 contrapose! h obtain ⟨x, hx, hx'⟩ := h @@ -237,7 +237,7 @@ theorem isOpen_ball (r : ValueGroup₀ (.ofClass _i.v)) : · simp intro x hx rw [mem_nhds] - simp only [setOf_subset_setOf] + simp only [ofPred_subset_ofPred] exact ⟨Units.mk0 _ hr, fun y hy ↦ (sub_add_cancel y x).symm ▸ (v.restrict.map_add _ x).trans_lt (max_lt hy hx)⟩ @@ -260,7 +260,7 @@ theorem isOpen_closedBall {r : ValueGroup₀ (.ofClass _i.v)} (hr : r ≠ 0) : rw [isOpen_iff_mem_nhds] intro x hx rw [mem_nhds] - simp only [setOf_subset_setOf] + simp only [ofPred_subset_ofPred] exact ⟨Units.mk0 _ hr, fun y hy ↦ (sub_add_cancel y x).symm ▸ le_trans (v.restrict.map_add _ _) (max_le (le_of_lt hy) hx)⟩ @@ -270,7 +270,7 @@ theorem isClosed_closedBall (r : ValueGroup₀ (.ofClass _i.v)) : IsClosed {x | v.restrict x ≤ r} := by rw [← isOpen_compl_iff, isOpen_iff_mem_nhds] intro x hx - simp only [mem_compl_iff, mem_setOf_eq, not_le] at hx + simp only [mem_compl_iff, mem_ofPred_eq, not_le] at hx rw [mem_nhds] have hx' : v.restrict x ≠ 0 := hx.ne_zero exact ⟨Units.mk0 _ hx', fun y hy hy' ↦ ne_of_lt hy <| map_sub_swap v.restrict x y ▸ diff --git a/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean b/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean index 60fce74c07b24e..6d1b786b733b71 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean @@ -59,7 +59,7 @@ instance (priority := low) {R : Type*} [Ring R] [ValuativeRel R] [UniformSpace R simp_rw [Valuation.restrict_lt_iff_lt_embedding] convert! mem_nhds_zero_iff (R := R) simpa [← Valuation.restrict_lt_iff_lt_embedding] using - (valuation R).exists_setOf_restrict_le_iff 0 _ + (valuation R).exists_setOfPred_restrict_le_iff 0 _ lemma v_eq_valuation {R : Type*} [Ring R] [ValuativeRel R] [UniformSpace R] [IsUniformAddGroup R] [IsValuativeTopology R] : diff --git a/Mathlib/Topology/Algebra/Valued/ValuedField.lean b/Mathlib/Topology/Algebra/Valued/ValuedField.lean index a9e2878a6be5ec..a61856d733f391 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuedField.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuedField.lean @@ -98,7 +98,7 @@ instance (priority := 100) Valued.isTopologicalDivisionRing [Valued K Γ₀] : use min (γ * (γ' * γ')) γ' intro y y_in apply hs - simp only [mem_setOf_eq, Units.min_val, Units.val_mul] at y_in + simp only [mem_ofPred_eq, Units.min_val, Units.val_mul] at y_in exact Valuation.inversion_estimate _ x_ne y_in } set_option backward.isDefEq.respectTransparency.types false in @@ -112,7 +112,7 @@ instance (priority := 100) ValuedRing.separated [Valued K Γ₀] : T0Space K := set γ' := Units.mk0 ((ValueGroup₀.restrict₀ _) x) (v.restrict.ne_zero_iff.mpr x_ne) with hdef exact ⟨γ', fun y hy => by simp only [Valuation.restrict_lt_iff_lt_embedding, hdef, sub_zero, Units.val_mk0, - mem_setOf_eq, embedding_restrict₀] at hy + mem_ofPred_eq, embedding_restrict₀] at hy simpa using hy⟩ section @@ -147,7 +147,7 @@ theorem Valued.continuous_valuation_of_surjective [hv : Valued K Γ₀] rw [Filter.Eventually, Valued.mem_nhds_zero] obtain ⟨x, hx⟩ := hsurj γ use Units.mk0 (restrict₀ (.ofClass hv.v) x) (by simp [restrict₀_apply, hx, hγ]) - simp only [Units.val_mk0, setOf_subset_setOf, ← v.restrict_def, Valuation.restrict_lt_iff, hx, + simp only [Units.val_mk0, ofPred_subset_ofPred, ← v.restrict_def, Valuation.restrict_lt_iff, hx, imp_self, implies_true] · have h0 : hv.v x ≠ 0 := (Valuation.ne_zero_iff _).mpr h rw [ContinuousAt, WithZeroTopology.tendsto_of_ne_zero h0] @@ -215,7 +215,7 @@ lemma valuation_isClosedMap : IsClosedMap (v.restrict : K → (ValueGroup₀ (.o refine IsClosedMap.of_nonempty ?_ intro U hU hU' simp only [← isOpen_compl_iff, isOpen_iff_mem_nhds, mem_compl_iff, mem_nhds, subset_compl_comm, - compl_setOf, not_lt] at hU + compl_ofPred, not_lt] at hU simp only [isClosed_iff, mem_image, map_eq_zero, exists_eq_right, ne_eq, image_subset_iff] refine (em _).imp_right fun h ↦ ?_ obtain ⟨γ, h⟩ := hU _ h @@ -241,7 +241,7 @@ theorem continuous_extension : Continuous (Valued.extension : hat K → _) := by exact zero_ne_one.symm convert! Valued.locally_const this ext x - rw [Valuation.map_one, mem_preimage, mem_singleton_iff, mem_setOf_eq] + rw [Valuation.map_one, mem_preimage, mem_singleton_iff, mem_ofPred_eq] obtain ⟨V, V_in, hV⟩ : ∃ V ∈ 𝓝 (1 : hat K), ∀ x : K, (x : hat K) ∈ V → (v x : Γ₀) = 1 := by rwa [Completion.isDenseInducing_coe.nhds_eq_comap, mem_comap] at preimage_one have : ∃ V' ∈ 𝓝 (1 : hat K), (0 : hat K) ∉ V' ∧ ∀ (x) (_ : x ∈ V') (y) (_ : y ∈ V'), @@ -387,10 +387,10 @@ theorem closure_coe_completion_v_lt {γ : Γ₀ˣ} : have heq : γ₀ = embedding γ₀' := rfl suffices γ₀ ≠ 0 → (x ∈ closure ((↑) '' { x : K | v x < (γ : Γ₀) }) ↔ γ₀ < (γ : Γ₀)) by rcases eq_or_ne γ₀ 0 with h | h - · simp only [(Valuation.zero_iff _).mp h, mem_setOf_eq, Valuation.map_zero, Units.zero_lt, + · simp only [(Valuation.zero_iff _).mp h, mem_ofPred_eq, Valuation.map_zero, Units.zero_lt, iff_true] apply subset_closure - exact ⟨0, by simp only [mem_setOf_eq, Valuation.map_zero, Units.zero_lt, true_and]; rfl⟩ + exact ⟨0, by simp only [mem_ofPred_eq, Valuation.map_zero, Units.zero_lt, true_and]; rfl⟩ · exact this h intro h have h' : γ₀' ≠ 0 := by simpa only [heq, map_ne_zero] using h diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index d02b53fc6f22cb..09cf269950aa83 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -218,7 +218,7 @@ instance : (valuation v).Compatible := .ofValuation (valuation v) instance : IsValuativeTopology (WithVal v) where mem_nhds_iff {s x} := by - simp only [Set.image_add_left, Set.preimage_setOf_eq, Valued.mem_nhds] + simp only [Set.image_add_left, Set.preimage_ofPred_eq, Valued.mem_nhds] let e := ValuativeRel.ValueGroupWithZero.orderMonoidIso (valuation v) apply e.unitsCongr.symm.exists_congr fun a ↦ ?_ simp [-OrderMonoidIso.val_unitsCongr_symm_apply, OrderMonoidIso.unitsCongr_symm_apply, @@ -547,11 +547,11 @@ theorem IsEquiv.uniformContinuous_equiv [hval : Valued R Γ₀'] (hv : Valued.v have hs0' : 0 < Valued.v.restrict (toVal v s) := by simp [restrict_pos_iff, h.pos_iff, ← hv, hs₀] have h' : v.restrict.IsEquiv w.restrict := h.restrict - rw [← hr, equiv_apply, Set.mem_setOf_eq, lt_div_iff₀ ((restrict_pos_iff Valued.v s).mpr hs₀), hv, + rw [← hr, equiv_apply, Set.mem_ofPred_eq, lt_div_iff₀ ((restrict_pos_iff Valued.v s).mpr hs₀), hv, ← map_mul, ← lt_def, ← ofVal_mul, ← hy, ← toVal_mul, ← h'.orderRingIso_apply, ← h'.orderRingIso.lt_symm_apply] simp only [toVal_mul, orderRingIso_symm_apply, lt_def, ofVal_mul, restrict_lt_iff] - simp only [equiv_symm_apply, Units.val_mk0, Set.mem_setOf_eq, lt_div_iff₀ hs0'] at hx + simp only [equiv_symm_apply, Units.val_mk0, Set.mem_ofPred_eq, lt_div_iff₀ hs0'] at hx rwa [← map_mul, restrict_lt_iff] at hx theorem IsEquiv.uniformContinuous_equiv_symm [hval : Valued R Γ₀'] (hv : Valued.v = w) @@ -569,8 +569,8 @@ theorem IsEquiv.uniformContinuous_equiv_symm [hval : Valued R Γ₀'] (hv : Valu (eq_zero h (r := s.ofVal)).ne] exact ⟨hr₀.ne', hs₀.ne'⟩) intro x hx - simp only [equiv_symm_apply, Set.mem_setOf_eq] - simp only [equiv_apply, Units.val_mk0, Set.mem_setOf_eq] at hx + simp only [equiv_symm_apply, Set.mem_ofPred_eq] + simp only [equiv_apply, Units.val_mk0, Set.mem_ofPred_eq] at hx rw [lt_div_iff₀, ← map_mul, restrict_lt_iff, hv, h.lt_iff_lt, map_mul] at hx · rw [← hr, lt_div_iff₀ ((restrict_pos_iff Valued.v s).mpr hs₀), ← map_mul, ← lt_def, ← h.orderRingIso_apply] @@ -592,7 +592,7 @@ lemma IsEquiv.uniformContinuous (h : v.IsEquiv w) : intro x let u := WithZero.unzero (Units.ne_zero x) obtain ⟨a, ha, y, hu⟩ := (mem_valueGroup_iff_of_comm _).mp u.2 - simp only [Set.mem_setOf_eq, RingHom.id_apply] + simp only [Set.mem_ofPred_eq, RingHom.id_apply] set y₀ := h_val.orderMonoidIso x with hy₀_def have hy₀_ne_zero : y₀ ≠ 0 := by simp [hy₀_def] set y := (Units.mk0 y₀ hy₀_ne_zero) with hy_def @@ -659,7 +659,7 @@ theorem IsEquiv.valuedCompletion_le_one_iff {K : Type*} [Field K] {v : Valuation Valued.v x ≤ 1 ↔ Valued.v.restrict x ≤ 1 := by rw [restrict_le_one_iff] simp_rw [h1] convert! - (mapEquiv h.uniformEquiv).toHomeomorph.isClosed_setOf_iff + (mapEquiv h.uniformEquiv).toHomeomorph.isClosed_setOfPred_iff (Valued.isClopen_closedBall _ one_ne_zero) (Valued.isClopen_closedBall _ one_ne_zero) rw [restrict_le_one_iff] rfl diff --git a/Mathlib/Topology/Algebra/Valued/WithZeroMulInt.lean b/Mathlib/Topology/Algebra/Valued/WithZeroMulInt.lean index de8116ebd5373c..4389b89196151b 100644 --- a/Mathlib/Topology/Algebra/Valued/WithZeroMulInt.lean +++ b/Mathlib/Topology/Algebra/Valued/WithZeroMulInt.lean @@ -28,7 +28,7 @@ variable {R Γ₀ : Type*} [Ring R] [LinearOrderedCommGroupWithZero Γ₀] -- TODO: use ValuativeRel after https://github.com/leanprover-community/mathlib4/issues/26833 lemma tendsto_zero_pow_of_v_lt_one [MulArchimedean Γ₀] [Valued R Γ₀] {x : R} (hx : v x < 1) : Tendsto (fun n : ℕ ↦ x ^ n) atTop (𝓝 0) := by - simp only [(hasBasis_nhds_zero _ _).tendsto_right_iff, mem_setOf_eq, map_pow, eventually_atTop, + simp only [(hasBasis_nhds_zero _ _).tendsto_right_iff, mem_ofPred_eq, map_pow, eventually_atTop, forall_const] intro y let v : Valuation R Γ₀ := Valued.v diff --git a/Mathlib/Topology/Algebra/WithZeroTopology.lean b/Mathlib/Topology/Algebra/WithZeroTopology.lean index 760e23fee1833b..e63ced78bf90aa 100644 --- a/Mathlib/Topology/Algebra/WithZeroTopology.lean +++ b/Mathlib/Topology/Algebra/WithZeroTopology.lean @@ -142,7 +142,7 @@ theorem isOpen_Iio {a : Γ₀} : IsOpen (Iio a) := structure: the set `{p : Γ₀ × Γ₀ | p.1 ≤ p.2}` is closed. -/ scoped instance (priority := 100) orderClosedTopology : OrderClosedTopology Γ₀ where isClosed_le' := by - simp only [← isOpen_compl_iff, compl_setOf, not_le, isOpen_iff_mem_nhds] + simp only [← isOpen_compl_iff, compl_ofPred, not_le, isOpen_iff_mem_nhds] rintro ⟨a, b⟩ (hab : b < a) rw [nhds_prod_eq, nhds_of_ne_zero hab.ne_zero, pure_prod] exact Iio_mem_nhds hab diff --git a/Mathlib/Topology/Baire/Lemmas.lean b/Mathlib/Topology/Baire/Lemmas.lean index 280eb034d31ce2..db6caef6a28599 100644 --- a/Mathlib/Topology/Baire/Lemmas.lean +++ b/Mathlib/Topology/Baire/Lemmas.lean @@ -156,7 +156,7 @@ theorem mem_residual {s : Set X} : s ∈ residual X ↔ ∃ t ⊆ s, IsGδ t ∧ /-- A property holds on a residual (comeagre) set if and only if it holds on some dense `Gδ` set. -/ theorem eventually_residual {p : X → Prop} : (∀ᶠ x in residual X, p x) ↔ ∃ t : Set X, IsGδ t ∧ Dense t ∧ ∀ x ∈ t, p x := by - simp only [Filter.Eventually, mem_residual, subset_def, mem_setOf_eq] + simp only [Filter.Eventually, mem_residual, subset_def, mem_ofPred_eq] tauto theorem dense_of_mem_residual {s : Set X} (hs : s ∈ residual X) : Dense s := diff --git a/Mathlib/Topology/Bases.lean b/Mathlib/Topology/Bases.lean index ee125a1602e517..9b1badd9e13844 100644 --- a/Mathlib/Topology/Bases.lean +++ b/Mathlib/Topology/Bases.lean @@ -793,7 +793,7 @@ theorem exists_countable_basis [SecondCountableTopology α] : ∃ b : Set (Set α), b.Countable ∧ ∅ ∉ b ∧ IsTopologicalBasis b := by obtain ⟨b, hb₁, hb₂⟩ := @SecondCountableTopology.is_open_generated_countable α _ _ refine ⟨_, ?_, notMem_sdiff_of_mem ?_, (isTopologicalBasis_of_subbasis hb₂).sdiff_empty⟩ - exacts [((countable_setOf_finite_subset hb₁).image _).mono sdiff_subset, rfl] + exacts [((countable_ofPred_finite_subset hb₁).image _).mono sdiff_subset, rfl] theorem exists_seq_basis [SecondCountableTopology α] : ∃ b : ℕ → Set α, IsTopologicalBasis (range b) := by diff --git a/Mathlib/Topology/Category/CompHaus/Basic.lean b/Mathlib/Topology/Category/CompHaus/Basic.lean index b90b4b4da53606..c2d23e758e0289 100644 --- a/Mathlib/Topology/Category/CompHaus/Basic.lean +++ b/Mathlib/Topology/Category/CompHaus/Basic.lean @@ -144,7 +144,7 @@ def limitCone {J : Type v} [SmallCategory J] (F : J ⥤ CompHaus.{max v u}) : Li { u : ∀ j, F.obj j | ∀ {i j : J} (f : i ⟶ j), F.map f (u i) = u j } = ⋂ (i : J) (j : J) (f : i ⟶ j), { u | F.map f (u i) = u j } := by ext1 - simp only [Set.mem_iInter, Set.mem_setOf_eq] + simp only [Set.mem_iInter, Set.mem_ofPred_eq] rw [this] apply isClosed_iInter intro i diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean index b4813d826e9696..c547cd151f17d9 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean @@ -613,7 +613,7 @@ theorem eval_πs_image {l : Products I} {o : Ordinal} (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } = (πs C o) '' eval (π C (ord I · < o)) '' { m | m < l } := by ext f - simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and] + simp only [Set.mem_image, Set.mem_ofPred_eq, exists_exists_and_eq_and] apply exists_congr; intro m apply and_congr_right; intro hm rw [eval_πs C (lt_ord_of_lt hm hl)] @@ -622,7 +622,7 @@ theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } = (πs' C h) '' eval (π C (ord I · < o₁)) '' { m | m < l } := by ext f - simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and] + simp only [Set.mem_image, Set.mem_ofPred_eq, exists_exists_and_eq_and] apply exists_congr; intro m apply and_congr_right; intro hm rw [eval_πs' C h (lt_ord_of_lt hm hl)] diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean index a6266639986c86..cbef1d3551ca73 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean @@ -210,7 +210,7 @@ theorem GoodProducts.spanFin [WellFoundedLT I] : apply Submodule.smul_mem apply Submodule.subset_span refine ⟨m, ⟨?_, rfl⟩⟩ - simp only [Set.mem_setOf_eq] + simp only [Set.mem_ofPred_eq] have hmas : m.val ≤ as := hc (by simpa only [Finset.mem_coe, Finsupp.mem_support_iff] using hm) refine le_trans hmas ?_ diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean index 9800928e9d2578..f85f8dbf1c5b4f 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean @@ -114,7 +114,7 @@ theorem contained_C1 : contained (π (C1 C ho) (ord I · < o)) o := theorem union_C0C1_eq : (C0 C ho) ∪ (C1 C ho) = C := by ext x - simp only [C0, C1, Set.mem_union, Set.mem_inter_iff, Set.mem_setOf_eq, + simp only [C0, C1, Set.mem_union, Set.mem_inter_iff, Set.mem_ofPred_eq, ← and_or_left, and_iff_left_iff_imp, Bool.dichotomy (x (term I ho)), implies_true] /-- @@ -214,7 +214,7 @@ theorem C0_projOrd {x : I → Bool} (hx : x ∈ C0 C ho) : Proj (ord I · < o) x rw [← not_imp_not] at hsC simp only [not_lt, Bool.not_eq_true, Order.succ_le_iff] at hsC exact (hsC hi).symm - · simp only [C0, Set.mem_inter_iff, Set.mem_setOf_eq] at hx + · simp only [C0, Set.mem_inter_iff, Set.mem_ofPred_eq] at hx rw [eq_comm, ord_term ho] at hi rw [← hx.2, hi] @@ -296,7 +296,7 @@ def MaxProducts : Set (Products I) := {l | l.isGood C ∧ term I ho ∈ l.val} include hsC in theorem union_succ : GoodProducts C = GoodProducts (π C (ord I · < o)) ∪ MaxProducts C ho := by ext l - simp only [GoodProducts, MaxProducts, Set.mem_union, Set.mem_setOf_eq] + simp only [GoodProducts, MaxProducts, Set.mem_union, Set.mem_ofPred_eq] refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ · by_cases hh : term I ho ∈ l.val · exact Or.inr ⟨h, hh⟩ @@ -583,7 +583,7 @@ theorem maxTail_isGood (l : MaxProducts C ho) dsimp only [eval] rw [Products.eval_πs C (Products.prop_of_isGood _ _ q.prop)] refine ⟨q.val, ⟨?_, rfl⟩⟩ - simp only [Products.lt_iff_lex_lt, Set.mem_setOf_eq] + simp only [Products.lt_iff_lex_lt, Set.mem_ofPred_eq] exact good_lt_maxProducts C hsC ho q l · apply Submodule.finsuppSum_mem intro q hq @@ -592,7 +592,7 @@ theorem maxTail_isGood (l : MaxProducts C ho) rw [Finsupp.mem_supported] at hmmem rw [← Finsupp.mem_support_iff] at hq refine ⟨⟨term I ho :: q.val, isChain_cons_of_lt C hsC ho l q (hmmem hq)⟩, ⟨?_, rfl⟩⟩ - simp only [Products.lt_iff_lex_lt, Set.mem_setOf_eq] + simp only [Products.lt_iff_lex_lt, Set.mem_ofPred_eq] rw [max_eq_o_cons_tail C hsC ho l] exact List.Lex.cons ((Products.lt_iff_lex_lt q l.val.Tail).mp (hmmem hq)) diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean b/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean index 07a4607f0f0dd8..94cf0ce02c0a79 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean @@ -54,7 +54,7 @@ set_option backward.isDefEq.respectTransparency.types false in theorem Products.lt_nil_empty {I} [LinearOrder I] : { m : Products I | m < Products.nil } = ∅ := by ext ⟨m, hm⟩ refine ⟨fun h ↦ ?_, by tauto⟩ - simp only [Set.mem_setOf_eq, lt_iff_lex_lt, nil, List.not_lex_nil] at h + simp only [Set.mem_ofPred_eq, lt_iff_lex_lt, nil, List.not_lex_nil] at h instance {α : Type*} [TopologicalSpace α] [Nonempty α] : Nontrivial (LocallyConstant α ℤ) := ⟨0, 1, ne_of_apply_ne DFunLike.coe <| (Function.const_injective (β := ℤ)).ne zero_ne_one⟩ @@ -89,7 +89,7 @@ instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) intro _ apply hll have he : {Products.nil} ⊆ {m | m < ⟨l,hl⟩} := by - simpa only [Products.nil, Products.lt_iff_lex_lt, Set.singleton_subset_iff, Set.mem_setOf_eq] + simpa only [Products.nil, Products.lt_iff_lex_lt, Set.singleton_subset_iff, Set.mem_ofPred_eq] grw [← he] rw [Products.span_nil_eq_top] exact Submodule.mem_top diff --git a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean index 62a504a5a47ba4..9a534c7e789e48 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean @@ -113,7 +113,7 @@ theorem partialSections.closed [∀ j : J, T2Space (F.obj j)] {G : Finset J} partialSections F H = ⋂ (f : FiniteDiagramArrow G) (_ : f ∈ H), {u | F.map f.2.2.2.2 (u f.1) = u f.2.1} := by ext1 - simp only [Set.mem_iInter, Set.mem_setOf_eq] + simp only [Set.mem_iInter, Set.mem_ofPred_eq] rfl rw [this] apply isClosed_biInter diff --git a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean index a9b32ee97e30ed..77d5d149109e68 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean @@ -135,7 +135,7 @@ theorem range_pullback_to_prod {X Y Z : TopCat.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) ext x constructor · rintro ⟨y, rfl⟩ - simp only [← ConcreteCategory.comp_apply, Set.mem_setOf_eq] + simp only [← ConcreteCategory.comp_apply, Set.mem_ofPred_eq] simp [pullback.condition] · rintro (h : f (_, _).1 = g (_, _).2) use (pullbackIsoProdSubtype f g).inv ⟨⟨_, _⟩, h⟩ diff --git a/Mathlib/Topology/ClopenBox.lean b/Mathlib/Topology/ClopenBox.lean index 042f17d7e81d8d..764ece7be66f59 100644 --- a/Mathlib/Topology/ClopenBox.lean +++ b/Mathlib/Topology/ClopenBox.lean @@ -48,7 +48,7 @@ theorem exists_prod_subset (W : Clopens (X × Y)) {a : X × Y} (h : a ∈ W) : have hV : IsCompact V := (W.2.1.preimage hp).isCompact let U : Set X := {x | MapsTo (Prod.mk x) V W} have hUV : U ×ˢ V ⊆ W := fun ⟨_, _⟩ hw ↦ hw.1 hw.2 - exact ⟨⟨U, (ContinuousMap.isClopen_setOf_mapsTo hV W.2).preimage + exact ⟨⟨U, (ContinuousMap.isClopen_setOfPred_mapsTo hV W.2).preimage (ContinuousMap.id (X × Y)).curry.2⟩, by simp [U, V, MapsTo], ⟨V, W.2.preimage hp⟩, h, hUV⟩ variable [CompactSpace X] diff --git a/Mathlib/Topology/Closure.lean b/Mathlib/Topology/Closure.lean index f2b757227e75cf..1c1594198d825f 100644 --- a/Mathlib/Topology/Closure.lean +++ b/Mathlib/Topology/Closure.lean @@ -37,7 +37,7 @@ variable {X : Type u} [TopologicalSpace X] {ι : Sort v} {x : X} {s s₁ s₂ t section Interior theorem mem_interior : x ∈ interior s ↔ ∃ t ⊆ s, IsOpen t ∧ x ∈ t := by - simp only [interior, mem_sUnion, mem_setOf_eq, and_assoc, and_left_comm] + simp only [interior, mem_sUnion, mem_ofPred_eq, and_assoc, and_left_comm] @[simp] theorem isOpen_interior : IsOpen (interior s) := @@ -276,7 +276,7 @@ theorem closure_closure : closure (closure s) = closure s := isClosed_closure.closure_eq theorem closure_eq_compl_interior_compl : closure s = (interior sᶜ)ᶜ := by - rw [interior, closure, compl_sUnion, compl_image_set_of] + rw [interior, closure, compl_sUnion, compl_image_ofPred] simp only [compl_subset_compl, isOpen_compl_iff] @[simp] diff --git a/Mathlib/Topology/ClusterPt.lean b/Mathlib/Topology/ClusterPt.lean index 4ed4ac24377b38..9b9cafb0edc733 100644 --- a/Mathlib/Topology/ClusterPt.lean +++ b/Mathlib/Topology/ClusterPt.lean @@ -246,10 +246,12 @@ theorem clusterPt_principal {x : X} {C : Set X} : /-- The set of cluster points of a filter is closed. In particular, the set of limit points of a sequence is closed. -/ -theorem isClosed_setOf_clusterPt {f : Filter X} : IsClosed { x | ClusterPt x f } := by - simp only [clusterPt_iff_forall_mem_closure, setOf_forall] +theorem isClosed_setOfPred_clusterPt {f : Filter X} : IsClosed { x | ClusterPt x f } := by + simp only [clusterPt_iff_forall_mem_closure, ofPred_forall] exact isClosed_biInter fun _ _ ↦ isClosed_closure +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_clusterPt := isClosed_setOfPred_clusterPt + theorem mem_closure_iff_clusterPt : x ∈ closure s ↔ ClusterPt x (𝓟 s) := mem_closure_iff_frequently.trans clusterPt_principal_iff_frequently.symm diff --git a/Mathlib/Topology/CompactOpen.lean b/Mathlib/Topology/CompactOpen.lean index 93011dc08b89df..baa2fdad25904d 100644 --- a/Mathlib/Topology/CompactOpen.lean +++ b/Mathlib/Topology/CompactOpen.lean @@ -56,28 +56,33 @@ theorem compactOpen_eq : @compactOpen X Y _ _ = .generateFrom (image2 (fun K U ↦ {f | MapsTo f K U}) {K | IsCompact K} {t | IsOpen t}) := rfl -theorem isOpen_setOf_mapsTo (hK : IsCompact K) (hU : IsOpen U) : +theorem isOpen_setOfPred_mapsTo (hK : IsCompact K) (hU : IsOpen U) : IsOpen {f : C(X, Y) | MapsTo f K U} := isOpen_generateFrom_of_mem <| mem_image2_of_mem hK hU +@[deprecated (since := "2026-07-09")] alias isOpen_setOf_mapsTo := isOpen_setOfPred_mapsTo + lemma eventually_mapsTo {f : C(X, Y)} (hK : IsCompact K) (hU : IsOpen U) (h : MapsTo f K U) : ∀ᶠ g : C(X, Y) in 𝓝 f, MapsTo g K U := - (isOpen_setOf_mapsTo hK hU).mem_nhds h + (isOpen_setOfPred_mapsTo hK hU).mem_nhds h -lemma isOpen_setOf_range_subset [CompactSpace X] (hU : IsOpen U) : +lemma isOpen_setOfPred_range_subset [CompactSpace X] (hU : IsOpen U) : IsOpen {f : C(X, Y) | range f ⊆ U} := by simp_rw [← mapsTo_univ_iff_range_subset] - exact isOpen_setOf_mapsTo isCompact_univ hU + exact isOpen_setOfPred_mapsTo isCompact_univ hU + +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_range_subset := isOpen_setOfPred_range_subset lemma eventually_range_subset [CompactSpace X] {f : C(X, Y)} (hU : IsOpen U) (h : range f ⊆ U) : ∀ᶠ g : C(X, Y) in 𝓝 f, range g ⊆ U := - (isOpen_setOf_range_subset hU).mem_nhds h + (isOpen_setOfPred_range_subset hU).mem_nhds h lemma nhds_compactOpen (f : C(X, Y)) : 𝓝 f = ⨅ (K : Set X) (_ : IsCompact K) (U : Set Y) (_ : IsOpen U) (_ : MapsTo f K U), 𝓟 {g : C(X, Y) | MapsTo g K U} := by - simp_rw +instances [compactOpen_eq, nhds_generateFrom, mem_setOf_eq, @and_comm (f ∈ _), iInf_and, - ← image_prod, iInf_image, biInf_prod, mem_setOf_eq] + simp_rw +instances [compactOpen_eq, nhds_generateFrom, mem_ofPred_eq, @and_comm (f ∈ _), iInf_and, + ← image_prod, iInf_image, biInf_prod, mem_ofPred_eq] lemma tendsto_nhds_compactOpen {l : Filter α} {f : α → C(Y, Z)} {g : C(Y, Z)} : Tendsto f l (𝓝 g) ↔ @@ -101,7 +106,7 @@ protected lemma mem_nhds_iff {f : C(X, Y)} {s : Set C(X, Y)} : s ∈ 𝓝 f ↔ ∃ S : Set (Set X × Set Y), S.Finite ∧ (∀ K U, (K, U) ∈ S → IsCompact K ∧ IsOpen U ∧ MapsTo f K U) ∧ {g : C(X, Y) | ∀ K U, (K, U) ∈ S → MapsTo g K U} ⊆ s := by - simp [f.hasBasis_nhds.mem_iff, ← setOf_forall, and_assoc] + simp [f.hasBasis_nhds.mem_iff, ← ofPred_forall, and_assoc] lemma _root_.Filter.HasBasis.nhds_continuousMapConst {ι : Type*} {c : Y} {p : ι → Prop} {U : ι → Set Y} (h : (𝓝 c).HasBasis p U) : @@ -132,7 +137,7 @@ section Functorial /-- `C(X, ·)` is a functor. -/ @[fun_prop] theorem continuous_postcomp (g : C(Y, Z)) : Continuous (ContinuousMap.comp g : C(X, Y) → C(X, Z)) := - continuous_compactOpen.2 fun _K hK _U hU ↦ isOpen_setOf_mapsTo hK (hU.preimage g.2) + continuous_compactOpen.2 fun _K hK _U hU ↦ isOpen_setOfPred_mapsTo hK (hU.preimage g.2) /-- If `g : C(Y, Z)` is injective, then the composition `ContinuousMap.comp g : C(X, Y) → C(X, Z)` is injective too. -/ @@ -145,8 +150,8 @@ then the composition `ContinuousMap.comp g : C(X, Y) → C(X, Z)` is a topology theorem isInducing_postcomp (g : C(Y, Z)) (hg : IsInducing g) : IsInducing (g.comp : C(X, Y) → C(X, Z)) where eq_induced := by - simp only [compactOpen_eq, induced_generateFrom_eq, image_image2, hg.setOf_isOpen, - image2_image_right, MapsTo, mem_preimage, preimage_setOf_eq, comp_apply] + simp only [compactOpen_eq, induced_generateFrom_eq, image_image2, hg.setOfPred_isOpen, + image2_image_right, MapsTo, mem_preimage, preimage_ofPred_eq, comp_apply] /-- If `g : C(Y, Z)` is a topological embedding, then the composition `ContinuousMap.comp g : C(X, Y) → C(X, Z)` is an embedding too. -/ @@ -158,7 +163,7 @@ theorem isEmbedding_postcomp (g : C(Y, Z)) (hg : IsEmbedding g) : @[continuity, fun_prop] theorem continuous_precomp (f : C(X, Y)) : Continuous (fun g => g.comp f : C(Y, Z) → C(X, Z)) := continuous_compactOpen.2 fun K hK U hU ↦ by - simpa only [mapsTo_image_iff] using! isOpen_setOf_mapsTo (hK.image f.2) hU + simpa only [mapsTo_image_iff] using! isOpen_setOfPred_mapsTo (hK.image f.2) hU variable (Z) in /-- Precomposition by a continuous map is itself a continuous map between spaces of continuous maps. @@ -245,15 +250,20 @@ instance [LocallyCompactPair X Y] : ContinuousEval C(X, Y) X Y where instance : ContinuousEvalConst C(X, Y) X Y where continuous_eval_const x := - continuous_def.2 fun U hU ↦ by simpa using! isOpen_setOf_mapsTo isCompact_singleton hU + continuous_def.2 fun U hU ↦ by simpa using! isOpen_setOfPred_mapsTo isCompact_singleton hU -lemma isClosed_setOf_mapsTo {t : Set Y} (ht : IsClosed t) (s : Set X) : +lemma isClosed_setOfPred_mapsTo {t : Set Y} (ht : IsClosed t) (s : Set X) : IsClosed {f : C(X, Y) | MapsTo f s t} := - ht.setOf_mapsTo fun _ _ ↦ continuous_eval_const _ + ht.setOfPred_mapsTo fun _ _ ↦ continuous_eval_const _ -lemma isClopen_setOf_mapsTo (hK : IsCompact K) (hU : IsClopen U) : +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_mapsTo := isClosed_setOfPred_mapsTo + +lemma isClopen_setOfPred_mapsTo (hK : IsCompact K) (hU : IsClopen U) : IsClopen {f : C(X, Y) | MapsTo f K U} := - ⟨isClosed_setOf_mapsTo hU.isClosed K, isOpen_setOf_mapsTo hK hU.isOpen⟩ + ⟨isClosed_setOfPred_mapsTo hU.isClosed K, isOpen_setOfPred_mapsTo hK hU.isOpen⟩ + +@[deprecated (since := "2026-07-09")] alias isClopen_setOf_mapsTo := isClopen_setOfPred_mapsTo @[norm_cast] lemma specializes_coe {f g : C(X, Y)} : ⇑f ⤳ ⇑g ↔ f ⤳ g := by @@ -289,7 +299,7 @@ instance [RegularSpace Y] : RegularSpace C(X, Y) := rcases (hK.image f.continuous).exists_isOpen_closure_subset (hU.mem_nhdsSet.2 hf.image_subset) with ⟨V, hVo, hKV, hVU⟩ filter_upwards [mem_lift' (eventually_mapsTo hK hVo (mapsTo_iff_image_subset.2 hKV))] with g hg - refine ((isClosed_setOf_mapsTo isClosed_closure K).closure_subset ?_).mono_right hVU + refine ((isClosed_setOfPred_mapsTo isClosed_closure K).closure_subset ?_).mono_right hVU exact closure_mono (fun _ h ↦ h.mono_right subset_closure) hg instance [T3Space Y] : T3Space C(X, Y) := inferInstance @@ -339,7 +349,7 @@ theorem compactOpen_eq_iInf_induced : refine le_antisymm (le_iInf₂ fun s _ ↦ compactOpen_le_induced s) ?_ refine le_generateFrom <| forall_mem_image2.2 fun K (hK : IsCompact K) U hU ↦ ?_ refine TopologicalSpace.le_def.1 (iInf₂_le K hK) _ ?_ - convert! isOpen_induced (isOpen_setOf_mapsTo (isCompact_iff_isCompact_univ.1 hK) hU) + convert! isOpen_induced (isOpen_setOfPred_mapsTo (isCompact_iff_isCompact_univ.1 hK) hU) simp [Subtype.forall, MapsTo] theorem nhds_compactOpen_eq_iInf_nhds_induced (f : C(X, Y)) : diff --git a/Mathlib/Topology/Compactification/StoneCech.lean b/Mathlib/Topology/Compactification/StoneCech.lean index da20885e51e243..940be182337632 100644 --- a/Mathlib/Topology/Compactification/StoneCech.lean +++ b/Mathlib/Topology/Compactification/StoneCech.lean @@ -85,7 +85,7 @@ theorem ultrafilter_converges_iff {u : Ultrafilter (Ultrafilter α)} {x : Ultraf rw [eq_comm, ← Ultrafilter.coe_le_coe] change ↑u ≤ 𝓝 x ↔ ∀ s ∈ x, { v : Ultrafilter α | s ∈ v } ∈ u simp only [TopologicalSpace.nhds_generateFrom, le_iInf_iff, ultrafilterBasis, le_principal_iff, - mem_setOf_eq] + mem_ofPred_eq] constructor · intro h a ha exact h _ ⟨ha, a, rfl⟩ @@ -118,7 +118,7 @@ instance : TotallyDisconnectedSpace (Ultrafilter α) := by rw [Tendsto, ← coe_map, ultrafilter_converges_iff] ext s change s ∈ b ↔ {t | s ∈ t} ∈ map pure b - simp_rw [mem_map, preimage_setOf_eq, mem_pure, setOf_mem_eq] + simp_rw [mem_map, preimage_ofPred_eq, mem_pure, ofPred_mem_eq] theorem ultrafilter_comap_pure_nhds (b : Ultrafilter α) : comap pure (𝓝 b) ≤ b := by rw [TopologicalSpace.nhds_generateFrom] diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index b71094c630ee39..bf7020f23175f6 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -1162,7 +1162,7 @@ theorem isCompact_pi_infinite {s : ∀ i, Set (X i)} : theorem isCompact_univ_pi {s : ∀ i, Set (X i)} (h : ∀ i, IsCompact (s i)) : IsCompact (pi univ s) := by convert! isCompact_pi_infinite h - simp only [← mem_univ_pi, setOf_mem_eq] + simp only [← mem_univ_pi, ofPred_mem_eq] instance Pi.compactSpace [∀ i, CompactSpace (X i)] : CompactSpace (∀ i, X i) := ⟨by rw [← pi_univ univ]; exact isCompact_univ_pi fun i => isCompact_univ⟩ diff --git a/Mathlib/Topology/Compactness/CountablyCompact.lean b/Mathlib/Topology/Compactness/CountablyCompact.lean index 84a527bde374da..69dc417dbfb3fa 100644 --- a/Mathlib/Topology/Compactness/CountablyCompact.lean +++ b/Mathlib/Topology/Compactness/CountablyCompact.lean @@ -338,7 +338,7 @@ theorem isCountablyCompact_iff_infinite_subset_has_accPt [T1Space E] {A : Set E} hx.frequently.mp (by simp) · -- Case 2: Infinite range obtain ⟨a, haA, hacc⟩ := h (Set.range x ∩ A) inter_subset_right <| by - rw [eventually_iff, mem_cofinite, compl_setOf] at hx + rw [eventually_iff, mem_cofinite, compl_ofPred] at hx exact hfin.inter_of_finite_sdiff (hx.image x |>.subset (by grind)) refine ⟨a, haA, ?_⟩ simp_rw [mapClusterPt_iff_frequently, frequently_cofinite_iff_infinite] diff --git a/Mathlib/Topology/Compactness/Paracompact.lean b/Mathlib/Topology/Compactness/Paracompact.lean index 4a7fd7ab720f6a..78bc1e4851cb99 100644 --- a/Mathlib/Topology/Compactness/Paracompact.lean +++ b/Mathlib/Topology/Compactness/Paracompact.lean @@ -87,7 +87,7 @@ theorem precise_refinement [ParacompactSpace X] (u : ι → Set X) (uo : ∀ a, · simp only [eq_univ_iff_forall, mem_iUnion] exact fun x ↦ ⟨ind (t_inv x), _, rfl, ht_inv _⟩ · refine fun x ↦ ⟨U x, hxU x, ((hU x).image ind).subset ?_⟩ - simp only [subset_def, mem_iUnion, mem_setOf_eq, Set.Nonempty, mem_inter_iff] + simp only [subset_def, mem_iUnion, mem_ofPred_eq, Set.Nonempty, mem_inter_iff] rintro i ⟨y, ⟨a, rfl, hya⟩, hyU⟩ exact mem_image_of_mem _ ⟨y, hya, hyU⟩ · simp only [subset_def, mem_iUnion] @@ -245,7 +245,7 @@ theorem refinement_of_locallyCompact_sigmaCompact_of_nhds_basis_set [WeaklyLocal (finite_le_nat _).biUnion fun k _ ↦ finite_range _ apply this.subset rintro ⟨k, c, hc⟩ - simp only [mem_iUnion, mem_setOf_eq, Subtype.coe_mk] + simp only [mem_iUnion, mem_ofPred_eq, Subtype.coe_mk] rintro ⟨x, hxB : x ∈ B c (r k c), hxK⟩ refine ⟨k, ?_, ⟨c, hc⟩, rfl⟩ have := (mem_compl_iff _ _).1 (hr k c hxB) diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index aacae77f952a0b..0f5e74fbe2fcd1 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -529,7 +529,7 @@ theorem IsPathConnected.exists_path_through_family' {n : ℕ} ∃ (γ : Path (p 0) (p (last n))) (t : Fin (n + 1) → I), (∀ t, γ t ∈ s) ∧ ∀ i, γ (t i) = p i := by rcases h.exists_path_through_family p hp with ⟨γ, hγ⟩ rcases hγ with ⟨h₁, h₂⟩ - simp only [range, mem_setOf_eq] at h₂ + simp only [range, mem_ofPred_eq] at h₂ rw [range_subset_iff] at h₁ choose! t ht using h₂ exact ⟨γ, t, h₁, ht⟩ @@ -576,7 +576,7 @@ theorem pathConnectedSpace_iff_univ : PathConnectedSpace X ↔ IsPathConnected ( theorem isPathConnected_iff_pathConnectedSpace : IsPathConnected F ↔ PathConnectedSpace F := by rw [pathConnectedSpace_iff_univ, IsInducing.subtypeVal.isPathConnected_iff, image_univ, - Subtype.range_val_subtype, setOf_mem_eq] + Subtype.range_val_subtype, ofPred_mem_eq] theorem isPathConnected_univ [PathConnectedSpace X] : IsPathConnected (univ : Set X) := pathConnectedSpace_iff_univ.mp inferInstance diff --git a/Mathlib/Topology/Constructible.lean b/Mathlib/Topology/Constructible.lean index 3ec4d6c380e99b..277cdb8ba899cf 100644 --- a/Mathlib/Topology/Constructible.lean +++ b/Mathlib/Topology/Constructible.lean @@ -135,7 +135,7 @@ lemma IsRetrocompact_iff_isSpectralMap_subtypeVal : IsRetrocompact s ↔ IsSpectralMap (Subtype.val : s → X) := by refine ⟨fun hs ↦ ⟨continuous_subtype_val, fun t htopen htcomp ↦ ?_⟩, fun hs t htcomp htopen ↦ ?_⟩ · rw [IsEmbedding.subtypeVal.isCompact_iff, image_preimage_eq_inter_range, - Subtype.range_coe_subtype, setOf_mem_eq, inter_comm] + Subtype.range_coe_subtype, ofPred_mem_eq, inter_comm] exact hs htcomp htopen · simpa using (hs.isCompact_preimage_of_isOpen htopen htcomp).image continuous_subtype_val diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index e085e50dd1493d..758c9254cedd4c 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -1144,7 +1144,7 @@ theorem pi_eq_generateFrom : { g | ∃ (s : ∀ a, Set (A a)) (i : Finset ι), (∀ a ∈ i, IsOpen (s a)) ∧ g = pi (↑i) s } := calc Pi.topologicalSpace _ = @Pi.topologicalSpace ι A fun _ => generateFrom { s | IsOpen s } := by - simp +instances only [generateFrom_setOf_isOpen] + simp +instances only [generateFrom_setOfPred_isOpen] _ = _ := pi_generateFrom_eq theorem pi_generateFrom_eq_finite {X : ι → Type*} {g : ∀ a, Set (Set (X a))} [Finite ι] diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index 2d79e1675aa029..80c90689295441 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -149,9 +149,13 @@ theorem Continuous.prodMk_left (y : Y) : Continuous fun x : X => (x, y) := by fu /-- If `f x y` is continuous in `x` for all `y ∈ s`, then the set of `x` such that `f x` maps `s` to `t` is closed. -/ -lemma IsClosed.setOf_mapsTo {α : Type*} {f : X → α → Z} {s : Set α} {t : Set Z} (ht : IsClosed t) +lemma IsClosed.setOfPred_mapsTo {α : Type*} {f : X → α → Z} {s : Set α} {t : Set Z} + (ht : IsClosed t) (hf : ∀ a ∈ s, Continuous (f · a)) : IsClosed {x | MapsTo (f x) s t} := by - simpa only [MapsTo, setOf_forall] using! isClosed_biInter fun y hy ↦ ht.preimage (hf y hy) + simpa only [MapsTo, ofPred_forall] using! isClosed_biInter fun y hy ↦ ht.preimage (hf y hy) + +@[deprecated (since := "2026-07-09")] +alias IsClosed.setOf_mapsTo := IsClosed.setOfPred_mapsTo theorem Continuous.comp₂ {g : X × Y → Z} (hg : Continuous g) {e : W → X} (he : Continuous e) {f : W → Y} (hf : Continuous f) : Continuous fun w => g (e w, f w) := @@ -300,13 +304,16 @@ theorem prod_mem_nhds {s : Set X} {t : Set Y} {x : X} {y : Y} (hx : s ∈ 𝓝 x s ×ˢ t ∈ 𝓝 (x, y) := prod_mem_nhds_iff.2 ⟨hx, hy⟩ -theorem isOpen_setOf_disjoint_nhds_nhds : IsOpen { p : X × X | Disjoint (𝓝 p.1) (𝓝 p.2) } := by - simp only [isOpen_iff_mem_nhds, Prod.forall, mem_setOf_eq] +theorem isOpen_setOfPred_disjoint_nhds_nhds : IsOpen { p : X × X | Disjoint (𝓝 p.1) (𝓝 p.2) } := by + simp only [isOpen_iff_mem_nhds, Prod.forall, mem_ofPred_eq] intro x y h obtain ⟨U, hU, V, hV, hd⟩ := ((nhds_basis_opens x).disjoint_iff (nhds_basis_opens y)).mp h exact mem_nhds_prod_iff'.mpr ⟨U, V, hU.2, hU.1, hV.2, hV.1, fun ⟨x', y'⟩ ⟨hx', hy'⟩ => disjoint_of_disjoint_of_mem hd (hU.2.mem_nhds hx') (hV.2.mem_nhds hy')⟩ +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_disjoint_nhds_nhds := isOpen_setOfPred_disjoint_nhds_nhds + theorem Filter.Eventually.prod_nhds {p : X → Prop} {q : Y → Prop} {x : X} {y : Y} (hx : ∀ᶠ x in 𝓝 x, p x) (hy : ∀ᶠ y in 𝓝 y, q y) : ∀ᶠ z : X × Y in 𝓝 (x, y), p z.1 ∧ q z.2 := prod_mem_nhds hx hy @@ -459,7 +466,7 @@ theorem map_fst_nhdsWithin (x : X × Y) : map Prod.fst (𝓝[Prod.snd ⁻¹' {x. rcases x with ⟨x, y⟩ rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs rcases hs with ⟨u, hu, v, hv, H⟩ - simp only [prod_subset_iff, mem_singleton_iff, mem_setOf_eq, mem_preimage] at H + simp only [prod_subset_iff, mem_singleton_iff, mem_ofPred_eq, mem_preimage] at H exact mem_of_superset hu fun z hz => H _ hz _ (mem_of_mem_nhds hv) rfl @[simp] @@ -477,7 +484,7 @@ theorem map_snd_nhdsWithin (x : X × Y) : map Prod.snd (𝓝[Prod.fst ⁻¹' {x. rcases x with ⟨x, y⟩ rw [mem_map, nhdsWithin, mem_inf_principal, mem_nhds_prod_iff] at hs rcases hs with ⟨u, hu, v, hv, H⟩ - simp only [prod_subset_iff, mem_singleton_iff, mem_setOf_eq, mem_preimage] at H + simp only [prod_subset_iff, mem_singleton_iff, mem_ofPred_eq, mem_preimage] at H exact mem_of_superset hv fun z hz => H _ (mem_of_mem_nhds hu) _ hz rfl @[simp] diff --git a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean index f114cf07b1a555..31e9ef5ceb591a 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean @@ -207,7 +207,7 @@ instance instMetricSpace {β} [MetricSpace β] : MetricSpace (α →ᵇ β) wher theorem nndist_eq : nndist f g = sInf { C | ∀ x : α, nndist (f x) (g x) ≤ C } := Subtype.ext <| dist_eq.trans <| by rw [val_eq_coe, coe_sInf, coe_image] - simp_rw [mem_setOf_eq, ← NNReal.coe_le_coe, NNReal.coe_mk, exists_prop, coe_nndist] + simp_rw [mem_ofPred_eq, ← NNReal.coe_le_coe, NNReal.coe_mk, exists_prop, coe_nndist] theorem nndist_set_exists : ∃ C, ∀ x : α, nndist (f x) (g x) ≤ C := Subtype.exists.mpr <| dist_set_exists.imp fun _ ⟨ha, h⟩ => ⟨ha, h⟩ diff --git a/Mathlib/Topology/ContinuousMap/Ideals.lean b/Mathlib/Topology/ContinuousMap/Ideals.lean index 7ab99056669275..2ab382bd0cacc2 100644 --- a/Mathlib/Topology/ContinuousMap/Ideals.lean +++ b/Mathlib/Topology/ContinuousMap/Ideals.lean @@ -94,7 +94,7 @@ def idealOfSet (s : Set X) : Ideal C(X, R) where theorem idealOfSet_closed [T2Space R] (s : Set X) : IsClosed (idealOfSet R s : Set C(X, R)) := by - simp only [idealOfSet, Submodule.coe_set_mk, Set.setOf_forall] + simp only [idealOfSet, Submodule.coe_set_mk, Set.ofPred_forall] exact isClosed_iInter fun x => isClosed_iInter fun _ => isClosed_eq (continuous_eval_const x) continuous_const @@ -114,14 +114,14 @@ def setOfIdeal (I : Ideal C(X, R)) : Set X := theorem notMem_setOfIdeal {I : Ideal C(X, R)} {x : X} : x ∉ setOfIdeal I ↔ ∀ ⦃f : C(X, R)⦄, f ∈ I → f x = 0 := by - rw [← Set.mem_compl_iff, setOfIdeal, compl_compl, Set.mem_setOf] + rw [← Set.mem_compl_iff, setOfIdeal, compl_compl, Set.mem_ofPred] theorem mem_setOfIdeal {I : Ideal C(X, R)} {x : X} : x ∈ setOfIdeal I ↔ ∃ f ∈ I, (f : C(X, R)) x ≠ 0 := by - simp_rw [setOfIdeal, Set.mem_compl_iff, Set.mem_setOf]; push Not; rfl + simp_rw [setOfIdeal, Set.mem_compl_iff, Set.mem_ofPred]; push Not; rfl theorem setOfIdeal_open [T2Space R] (I : Ideal C(X, R)) : IsOpen (setOfIdeal I) := by - simp only [setOfIdeal, Set.setOf_forall, isOpen_compl_iff] + simp only [setOfIdeal, Set.ofPred_forall, isOpen_compl_iff] exact isClosed_iInter fun f => isClosed_iInter fun _ => isClosed_eq (map_continuous f) continuous_const @@ -176,7 +176,7 @@ theorem exists_mul_le_one_eqOn_ge (f : C(X, ℝ≥0)) {c : ℝ≥0} (hc : 0 < c) (inv_mul_le_iff₀ (hc.trans_le le_sup_right)).mpr ((mul_one (f x ⊔ c)).symm ▸ le_sup_left), fun x hx => by simpa only [coe_const, mul_apply, coe_mk, Pi.inv_apply, Pi.sup_apply, - Function.const_apply, sup_eq_left.mpr (Set.mem_setOf.mp hx), ne_eq, Pi.one_apply] + Function.const_apply, sup_eq_left.mpr (Set.mem_ofPred.mp hx), ne_eq, Pi.one_apply] using inv_mul_cancel₀ (hc.trans_le hx).ne' ⟩ variable [CompactSpace X] [T2Space X] @@ -200,7 +200,7 @@ theorem idealOfSet_ofIdeal_eq_closure (I : Ideal C(X, 𝕜)) : have ht : IsClosed t := isClosed_le continuous_const (map_continuous f).nnnorm have htI : Disjoint t (setOfIdeal I)ᶜ := by refine Set.subset_compl_iff_disjoint_left.mp fun x hx => ?_ - simpa only [t, Set.mem_setOf, Set.mem_compl_iff, not_le] using! + simpa only [t, Set.mem_ofPred, Set.mem_compl_iff, not_le] using! (nnnorm_eq_zero.mpr (mem_idealOfSet.mp hf hx)).trans_lt (half_pos hε) /- It suffices to produce `g : C(X, ℝ≥0)` which takes values in `[0,1]` and is constantly `1` on `t` such that when composed with the natural embedding of `ℝ≥0` into `𝕜` lies in the ideal `I`. diff --git a/Mathlib/Topology/ContinuousMap/SecondCountableSpace.lean b/Mathlib/Topology/ContinuousMap/SecondCountableSpace.lean index 5fbf560cfa8504..4729dd4fbaa0dc 100644 --- a/Mathlib/Topology/ContinuousMap/SecondCountableSpace.lean +++ b/Mathlib/Topology/ContinuousMap/SecondCountableSpace.lean @@ -58,7 +58,7 @@ theorem compactOpen_eq_generateFrom {S : Set (Set X)} {T : Set (Set Y)} rw [mapsTo_sUnion, forall_mem_image] exact fun x hx ↦ hLt x <| hsK x hx have hsub : (⋂ L ∈ s, {g : C(X, Y) | MapsTo g L (⋃₀ t)}) ⊆ {g | MapsTo g K U} := by - simp only [← setOf_forall, ← mapsTo_iUnion, ← sUnion_eq_biUnion] + simp only [← ofPred_forall, ← mapsTo_iUnion, ← sUnion_eq_biUnion] exact fun g hg ↦ hg.mono hKs (sUnion_subset hTU) refine mem_of_superset ((biInter_mem hsf).2 fun L hL ↦ ?_) hsub refine mem_iInf_of_mem _ <| mem_iInf_of_mem ?_ <| mem_principal_self _ @@ -76,7 +76,7 @@ theorem secondCountableTopology [SecondCountableTopology Y] is_open_generated_countable := by rcases hX with ⟨S, hScount, hScomp, hS⟩ refine ⟨_, ?_, compactOpen_eq_generateFrom (S := S) hScomp (isBasis_countableBasis _) ?_⟩ - · exact .image2 hScount (countable_setOf_finite_subset (countable_countableBasis Y)) _ + · exact .image2 hScount (countable_ofPred_finite_subset (countable_countableBasis Y)) _ · intro f x V hV hx apply hS exacts [isOpen_of_mem_countableBasis hV, hx] diff --git a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean index e4ff06a7424a94..1b32fdaf342225 100644 --- a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean @@ -195,7 +195,7 @@ theorem sublattice_closure_eq_top (L : Set C(X, ℝ)) (nA : L.Nonempty) intro x y refine IsOpen.mem_nhds ?_ ?_ · apply isOpen_lt <;> fun_prop - · rw [Set.mem_setOf_eq, w₂] + · rw [Set.mem_ofPred_eq, w₂] exact sub_lt_self _ pos -- Fixing `x` for a moment, we have a family of functions `fun y ↦ g x y` -- which on different patches (the `U x y`) are greater than `f z - ε`. @@ -229,7 +229,7 @@ theorem sublattice_closure_eq_top (L : Set C(X, ℝ)) (nA : L.Nonempty) intro x refine IsOpen.mem_nhds ?_ ?_ · apply isOpen_lt <;> fun_prop - · dsimp only [W, Set.mem_setOf_eq] + · dsimp only [W, Set.mem_ofPred_eq] rw [h_eq] exact lt_add_of_pos_right _ pos -- Since `X` is compact, there is some finset `ys t` diff --git a/Mathlib/Topology/ContinuousMap/T0Sierpinski.lean b/Mathlib/Topology/ContinuousMap/T0Sierpinski.lean index 77c27b073bb658..2bf5cf4e42a1a9 100644 --- a/Mathlib/Topology/ContinuousMap/T0Sierpinski.lean +++ b/Mathlib/Topology/ContinuousMap/T0Sierpinski.lean @@ -36,7 +36,7 @@ theorem eq_induced_by_maps_to_sierpinski (X : Type*) [t : TopologicalSpace X] : · intro u h rw [← generateFrom_iUnion_isOpen] apply isOpen_generateFrom_of_mem - simp only [Set.mem_iUnion, Set.mem_setOf_eq, isOpen_induced_iff] + simp only [Set.mem_iUnion, Set.mem_ofPred_eq, isOpen_induced_iff] exact ⟨⟨u, h⟩, {True}, isOpen_singleton_true, by simp [Set.preimage]⟩ variable (X : Type*) [TopologicalSpace X] diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index b31ebedce237be..43db4451329174 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -211,7 +211,7 @@ theorem continuousOn_to_generateFrom_iff {β : Type*} {T : Set (Set β)} {f : α @ContinuousOn α β _ (.generateFrom T) f s ↔ ∀ x ∈ s, ∀ t ∈ T, f x ∈ t → f ⁻¹' t ∈ 𝓝[s] x := forall₂_congr fun x _ => by delta ContinuousWithinAt - simp only [TopologicalSpace.nhds_generateFrom, tendsto_iInf, tendsto_principal, mem_setOf_eq, + simp only [TopologicalSpace.nhds_generateFrom, tendsto_iInf, tendsto_principal, mem_ofPred_eq, and_imp] exact forall_congr' fun t => forall_comm diff --git a/Mathlib/Topology/DenseEmbedding.lean b/Mathlib/Topology/DenseEmbedding.lean index 92af2caba8769b..243ba4a265f691 100644 --- a/Mathlib/Topology/DenseEmbedding.lean +++ b/Mathlib/Topology/DenseEmbedding.lean @@ -341,7 +341,7 @@ theorem isClosed_property [TopologicalSpace β] {e : α → β} {p : β → Prop univ = closure (range e) := he.closure_range.symm _ ⊆ closure { b | p b } := closure_mono <| range_subset_iff.mpr h _ = _ := hp.closure_eq - simpa only [univ_subset_iff, eq_univ_iff_forall, mem_setOf] + simpa only [univ_subset_iff, eq_univ_iff_forall, mem_ofPred] theorem isClosed_property2 [TopologicalSpace β] {e : α → β} {p : β → β → Prop} (he : DenseRange e) (hp : IsClosed { q : β × β | p q.1 q.2 }) (h : ∀ a₁ a₂, p (e a₁) (e a₂)) : ∀ b₁ b₂, p b₁ b₂ := diff --git a/Mathlib/Topology/DiscreteQuotient.lean b/Mathlib/Topology/DiscreteQuotient.lean index b5045bc4dc69c2..24a3741bd22948 100644 --- a/Mathlib/Topology/DiscreteQuotient.lean +++ b/Mathlib/Topology/DiscreteQuotient.lean @@ -74,19 +74,22 @@ variable {α X Y Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] [Topologic @[ext] structure DiscreteQuotient (X : Type*) [TopologicalSpace X] extends Setoid X where /-- For every point `x`, the set `{ y | Rel x y }` is an open set. -/ - protected isOpen_setOf_rel : ∀ x, IsOpen (setOf (toSetoid x)) + protected isOpen_setOfPred_rel : ∀ x, IsOpen (Set.ofPred (toSetoid x)) namespace DiscreteQuotient variable (S : DiscreteQuotient X) +@[deprecated (since := "2026-07-09")] +protected alias isOpen_setOf_rel := DiscreteQuotient.isOpen_setOfPred_rel + lemma toSetoid_injective : Function.Injective (@toSetoid X _) | ⟨_, _⟩, ⟨_, _⟩, _ => by congr /-- Construct a discrete quotient from a clopen set. -/ def ofIsClopen {A : Set X} (h : IsClopen A) : DiscreteQuotient X where toSetoid := ⟨fun x y => x ∈ A ↔ y ∈ A, fun _ => Iff.rfl, Iff.symm, Iff.trans⟩ - isOpen_setOf_rel x := by by_cases hx : x ∈ A <;> simp [hx, h.1, h.2, ← compl_setOf] + isOpen_setOfPred_rel x := by by_cases hx : x ∈ A <;> simp [hx, h.1, h.2, ← compl_ofPred] theorem refl : ∀ x, S.toSetoid x x := S.refl' @@ -106,7 +109,7 @@ instance : TopologicalSpace S := /-- The projection from `X` to the given discrete quotient. -/ def proj : X → S := Quotient.mk'' -theorem fiber_eq (x : X) : S.proj ⁻¹' {S.proj x} = setOf (S.toSetoid x) := +theorem fiber_eq (x : X) : S.proj ⁻¹' {S.proj x} = Set.ofPred (S.toSetoid x) := Set.ext fun _ => eq_comm.trans Quotient.eq'' theorem proj_surjective : Function.Surjective S.proj := @@ -121,7 +124,7 @@ theorem proj_continuous : Continuous S.proj := instance : DiscreteTopology S := discreteTopology_iff_isOpen_singleton.2 <| S.proj_surjective.forall.2 fun x => by rw [← S.proj_isQuotientMap.isOpen_preimage, fiber_eq] - exact S.isOpen_setOf_rel _ + exact S.isOpen_setOfPred_rel _ theorem proj_isLocallyConstant : IsLocallyConstant S.proj := (IsLocallyConstant.iff_continuous S.proj).2 S.proj_continuous @@ -135,10 +138,13 @@ theorem isOpen_preimage (A : Set S) : IsOpen (S.proj ⁻¹' A) := theorem isClosed_preimage (A : Set S) : IsClosed (S.proj ⁻¹' A) := (S.isClopen_preimage A).1 -theorem isClopen_setOf_rel (x : X) : IsClopen (setOf (S.toSetoid x)) := by +theorem isClopen_setOfPred_rel (x : X) : IsClopen (Set.ofPred (S.toSetoid x)) := by rw [← fiber_eq] apply isClopen_preimage +@[deprecated (since := "2026-07-09")] +alias isClopen_setOf_rel := isClopen_setOfPred_rel + instance : Min (DiscreteQuotient X) := ⟨fun S₁ S₂ => ⟨S₁.1 ⊓ S₂.1, fun x => (S₁.2 x).inter (S₂.2 x)⟩⟩ @@ -170,7 +176,7 @@ variable (g : C(Y, Z)) (f : C(X, Y)) /-- Comap a discrete quotient along a continuous map. -/ def comap (S : DiscreteQuotient Y) : DiscreteQuotient X where toSetoid := Setoid.comap f S.1 - isOpen_setOf_rel _ := (S.2 _).preimage f.continuous + isOpen_setOfPred_rel _ := (S.2 _).preimage f.continuous @[simp] theorem comap_id : S.comap (ContinuousMap.id X) = S := rfl @@ -228,12 +234,13 @@ end OfLE instance [LocallyConnectedSpace X] : OrderBot (DiscreteQuotient X) where bot := { toSetoid := connectedComponentSetoid X - isOpen_setOf_rel := fun x => by + isOpen_setOfPred_rel := fun x => by convert! isOpen_connectedComponent (x := x) ext y simpa only [connectedComponentSetoid, ← connectedComponent_eq_iff_mem] using! eq_comm } bot_le S := fun x y (h : connectedComponent x = connectedComponent y) => - (S.isClopen_setOf_rel x).connectedComponent_subset (S.refl _) <| h.symm ▸ mem_connectedComponent + (S.isClopen_setOfPred_rel x).connectedComponent_subset (S.refl _) <| + h.symm ▸ mem_connectedComponent @[simp] theorem proj_bot_eq [LocallyConnectedSpace X] {x y : X} : @@ -367,7 +374,7 @@ lemma comp_finsetClopens [CompactSpace X] : (Set.image (fun (t : Clopens X) ↦ t.carrier) ∘ (↑)) ∘ finsetClopens X = fun ⟨f, _⟩ ↦ f.classes := by ext d - simp only [Setoid.classes, Set.mem_setOf_eq, Function.comp_apply, + simp only [Setoid.classes, Set.mem_ofPred_eq, Function.comp_apply, finsetClopens, Set.coe_toFinset, Set.mem_image, Set.mem_range, exists_exists_eq_and] constructor @@ -404,7 +411,7 @@ variable (f : LocallyConstant X α) /-- Any locally constant function induces a discrete quotient. -/ def discreteQuotient : DiscreteQuotient X where toSetoid := .comap f ⊥ - isOpen_setOf_rel _ := f.isLocallyConstant _ + isOpen_setOfPred_rel _ := f.isLocallyConstant _ /-- The (locally constant) function from the discrete quotient associated to a locally constant function. -/ diff --git a/Mathlib/Topology/DiscreteSubset.lean b/Mathlib/Topology/DiscreteSubset.lean index 2006d086f5c68a..7db1a6b745b62f 100644 --- a/Mathlib/Topology/DiscreteSubset.lean +++ b/Mathlib/Topology/DiscreteSubset.lean @@ -468,7 +468,7 @@ alias finite_diff_of_mem_codiscreteWithin := finite_sdiff_of_mem_codiscreteWithi theorem cofinite_inf_le_codiscreteWithin (hK : IsCompact K) : cofinite ⊓ 𝓟 K ≤ codiscreteWithin K := by intro s hs - simpa [mem_inf_principal, compl_setOf] using! hK.finite_sdiff_of_mem_codiscreteWithin hs + simpa [mem_inf_principal, compl_ofPred] using! hK.finite_sdiff_of_mem_codiscreteWithin hs theorem codiscreteWithin_eq [T1Space X] (hK : IsCompact K) : codiscreteWithin K = cofinite ⊓ 𝓟 K := by diff --git a/Mathlib/Topology/EMetricSpace/Basic.lean b/Mathlib/Topology/EMetricSpace/Basic.lean index 4ff81c6ad493e4..2f755e399e3f56 100644 --- a/Mathlib/Topology/EMetricSpace/Basic.lean +++ b/Mathlib/Topology/EMetricSpace/Basic.lean @@ -322,28 +322,28 @@ variable {s : Set α} theorem lebesgue_number_lemma_of_emetric {ι : Sort*} {c : ι → Set α} (hs : IsCompact s) (hc₁ : ∀ i, IsOpen (c i)) (hc₂ : s ⊆ ⋃ i, c i) : ∃ δ > 0, ∀ x ∈ s, ∃ i, eball x δ ⊆ c i := by - simpa only [eball, UniformSpace.ball, preimage_setOf_eq, edist_comm] + simpa only [eball, UniformSpace.ball, preimage_ofPred_eq, edist_comm] using uniformity_basis_edist.lebesgue_number_lemma hs hc₁ hc₂ theorem lebesgue_number_lemma_of_emetric_nhds' {c : (x : α) → x ∈ s → Set α} (hs : IsCompact s) (hc : ∀ x hx, c x hx ∈ 𝓝 x) : ∃ δ > 0, ∀ x ∈ s, ∃ y : s, eball x δ ⊆ c y y.2 := by - simpa only [eball, UniformSpace.ball, preimage_setOf_eq, edist_comm] + simpa only [eball, UniformSpace.ball, preimage_ofPred_eq, edist_comm] using uniformity_basis_edist.lebesgue_number_lemma_nhds' hs hc theorem lebesgue_number_lemma_of_emetric_nhds {c : α → Set α} (hs : IsCompact s) (hc : ∀ x ∈ s, c x ∈ 𝓝 x) : ∃ δ > 0, ∀ x ∈ s, ∃ y, eball x δ ⊆ c y := by - simpa only [eball, UniformSpace.ball, preimage_setOf_eq, edist_comm] + simpa only [eball, UniformSpace.ball, preimage_ofPred_eq, edist_comm] using uniformity_basis_edist.lebesgue_number_lemma_nhds hs hc theorem lebesgue_number_lemma_of_emetric_nhdsWithin' {c : (x : α) → x ∈ s → Set α} (hs : IsCompact s) (hc : ∀ x hx, c x hx ∈ 𝓝[s] x) : ∃ δ > 0, ∀ x ∈ s, ∃ y : s, eball x δ ∩ s ⊆ c y y.2 := by - simpa only [eball, UniformSpace.ball, preimage_setOf_eq, edist_comm] + simpa only [eball, UniformSpace.ball, preimage_ofPred_eq, edist_comm] using uniformity_basis_edist.lebesgue_number_lemma_nhdsWithin' hs hc theorem lebesgue_number_lemma_of_emetric_nhdsWithin {c : α → Set α} (hs : IsCompact s) (hc : ∀ x ∈ s, c x ∈ 𝓝[s] x) : ∃ δ > 0, ∀ x ∈ s, ∃ y, eball x δ ∩ s ⊆ c y := by - simpa only [eball, UniformSpace.ball, preimage_setOf_eq, edist_comm] + simpa only [eball, UniformSpace.ball, preimage_ofPred_eq, edist_comm] using uniformity_basis_edist.lebesgue_number_lemma_nhdsWithin hs hc theorem lebesgue_number_lemma_of_emetric_sUnion {c : Set (Set α)} (hs : IsCompact s) diff --git a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean index a7db24a2a82ab0..174e0498c54e05 100644 --- a/Mathlib/Topology/EMetricSpace/BoundedVariation.lean +++ b/Mathlib/Topology/EMetricSpace/BoundedVariation.lean @@ -1202,7 +1202,7 @@ theorem MonotoneOn.boundedVariationOn (hf : MonotoneOn f s) (h : ∀ x ∈ s, |f suffices eVariationOn f s ≤ .ofReal (2 * C) from ne_of_lt (this.trans_lt (by simp [mul_lt_top])) rw [eVariationOn.eq_biSup_inter_Icc] - simp only [mem_setOf_eq, iSup_le_iff, and_imp, Prod.forall] + simp only [mem_ofPred_eq, iSup_le_iff, and_imp, Prod.forall] intro a b as bs hab grw [hf.eVariationOn_eq as bs] exact ofReal_mono (by grind) diff --git a/Mathlib/Topology/EMetricSpace/Defs.lean b/Mathlib/Topology/EMetricSpace/Defs.lean index c1fcc7dfde2fd7..7008002199fb9a 100644 --- a/Mathlib/Topology/EMetricSpace/Defs.lean +++ b/Mathlib/Topology/EMetricSpace/Defs.lean @@ -43,7 +43,7 @@ in terms of the elements of the uniformity. -/ theorem uniformity_dist_of_mem_uniformity [LT β] {U : Filter (α × α)} (z : β) (D : α → α → β) (H : ∀ s, s ∈ U ↔ ∃ ε > z, ∀ {a b : α}, D a b < ε → (a, b) ∈ s) : U = ⨅ ε > z, 𝓟 { p : α × α | D p.1 p.2 < ε } := - HasBasis.eq_biInf ⟨fun s => by simp only [H, subset_def, Prod.forall, mem_setOf]⟩ + HasBasis.eq_biInf ⟨fun s => by simp only [H, subset_def, Prod.forall, mem_ofPred]⟩ open scoped Uniformity Topology Filter NNReal ENNReal Pointwise @@ -392,7 +392,7 @@ instance Prod.pseudoEMetricSpaceMax [PseudoEMetricSpace β] : max_le (le_trans (edist_triangle _ _ _) (add_le_add (le_max_left _ _) (le_max_left _ _))) (le_trans (edist_triangle _ _ _) (add_le_add (le_max_right _ _) (le_max_right _ _))) uniformity_edist := uniformity_prod.trans <| by - simp [PseudoEMetricSpace.uniformity_edist, ← iInf_inf_eq, setOf_and] + simp [PseudoEMetricSpace.uniformity_edist, ← iInf_inf_eq, ofPred_and] toUniformSpace := inferInstance theorem Prod.edist_eq [PseudoEMetricSpace β] (x y : α × β) : @@ -416,7 +416,7 @@ theorem mem_closedEBall' : y ∈ closedEBall x ε ↔ edist x y ≤ ε := by @[simp] theorem closedEBall_top (x : α) : closedEBall x ∞ = univ := - eq_univ_of_forall fun _ => mem_setOf.2 le_top + eq_univ_of_forall fun _ => mem_ofPred.2 le_top theorem eball_subset_closedEBall : eball x ε ⊆ closedEBall x ε := fun _ h => le_of_lt h.out @@ -464,13 +464,20 @@ theorem eball_eq_empty_iff : eball x ε = ∅ ↔ ε = 0 := ⟨fun h => le_bot_iff.1 (le_of_not_gt fun ε0 => h _ (mem_eball_self ε0)), fun ε0 _ h => not_lt_of_ge (le_of_eq ε0) (pos_of_mem_eball h)⟩ -theorem ordConnected_setOf_closedEBall_subset (x : α) (s : Set α) : +theorem ordConnected_setOfPred_closedEBall_subset (x : α) (s : Set α) : OrdConnected { r | closedEBall x r ⊆ s } := ⟨fun _ _ _ h₁ _ h₂ => (closedEBall_subset_closedEBall h₂.2).trans h₁⟩ -theorem ordConnected_setOf_eball_subset (x : α) (s : Set α) : OrdConnected { r | eball x r ⊆ s } := +@[deprecated (since := "2026-07-09")] +alias ordConnected_setOf_closedEBall_subset := ordConnected_setOfPred_closedEBall_subset + +theorem ordConnected_setOfPred_eball_subset (x : α) (s : Set α) : + OrdConnected { r | eball x r ⊆ s } := ⟨fun _ _ _ h₁ _ h₂ => (eball_subset_eball h₂.2).trans h₁⟩ +@[deprecated (since := "2026-07-09")] +alias ordConnected_setOf_eball_subset := ordConnected_setOfPred_eball_subset + /-- Relation “two points are at a finite edistance” is an equivalence relation. -/ @[instance_reducible] def edistLtTopSetoid : Setoid α where @@ -652,10 +659,10 @@ alias closedBall_subset_closedBall := closedEBall_subset_closedEBall @[deprecated (since := "2026-01-24")] alias ball_eq_empty_iff := eball_eq_empty_iff @[deprecated (since := "2026-01-24")] -alias ordConnected_setOf_closedBall_subset := ordConnected_setOf_closedEBall_subset +alias ordConnected_setOf_closedBall_subset := ordConnected_setOfPred_closedEBall_subset @[deprecated (since := "2026-01-24")] -alias ordConnected_setOf_ball_subset := ordConnected_setOf_eball_subset +alias ordConnected_setOf_ball_subset := ordConnected_setOfPred_eball_subset @[deprecated (since := "2026-01-24")] alias edistLtTopSetoid := edistLtTopSetoid @[deprecated (since := "2026-01-24")] alias ball_zero := eball_zero diff --git a/Mathlib/Topology/EMetricSpace/Pi.lean b/Mathlib/Topology/EMetricSpace/Pi.lean index 7a106a7bcbd9c5..5b96678f747b7e 100644 --- a/Mathlib/Topology/EMetricSpace/Pi.lean +++ b/Mathlib/Topology/EMetricSpace/Pi.lean @@ -67,10 +67,10 @@ instance pseudoEMetricSpacePi [∀ b, PseudoEMetricSpace (X b)] : PseudoEMetricS toUniformSpace := Pi.uniformSpace _ uniformity_edist := by simp only [Pi.uniformity, PseudoEMetricSpace.uniformity_edist, comap_iInf, gt_iff_lt, - preimage_setOf_eq, comap_principal, edist_pi_def] + preimage_ofPred_eq, comap_principal, edist_pi_def] rw [iInf_comm]; congr; funext ε rw [iInf_comm]; congr; funext εpos - simp [setOf_forall, εpos] + simp [ofPred_forall, εpos] end Pi diff --git a/Mathlib/Topology/Filter.lean b/Mathlib/Topology/Filter.lean index e2118c12d7bf22..453161136dda42 100644 --- a/Mathlib/Topology/Filter.lean +++ b/Mathlib/Topology/Filter.lean @@ -53,9 +53,11 @@ instance : TopologicalSpace (Filter α) := theorem isOpen_Iic_principal {s : Set α} : IsOpen (Iic (𝓟 s)) := GenerateOpen.basic _ (mem_range_self _) -theorem isOpen_setOf_mem {s : Set α} : IsOpen { l : Filter α | s ∈ l } := by +theorem isOpen_setOfPred_mem {s : Set α} : IsOpen { l : Filter α | s ∈ l } := by simpa only [Iic_principal] using isOpen_Iic_principal +@[deprecated (since := "2026-07-09")] alias isOpen_setOf_mem := isOpen_setOfPred_mem + theorem isTopologicalBasis_Iic_principal : IsTopologicalBasis (range (Iic ∘ 𝓟 : Set α → Set (Filter α))) := { exists_subset_inter := by @@ -72,7 +74,7 @@ theorem isOpen_iff {s : Set (Filter α)} : IsOpen s ↔ ∃ T : Set (Set α), s set_option backward.isDefEq.respectTransparency false in theorem nhds_eq (l : Filter α) : 𝓝 l = l.lift' (Iic ∘ 𝓟) := nhds_generateFrom.trans <| by - simp only [mem_setOf_eq, @and_comm (l ∈ _), iInf_and, iInf_range, Filter.lift', Filter.lift, + simp only [mem_ofPred_eq, @and_comm (l ∈ _), iInf_and, iInf_range, Filter.lift', Filter.lift, (· ∘ ·), mem_Iic, le_principal_iff] theorem nhds_eq' (l : Filter α) : 𝓝 l = l.lift' fun s => { l' | s ∈ l' } := by @@ -80,7 +82,7 @@ theorem nhds_eq' (l : Filter α) : 𝓝 l = l.lift' fun s => { l' | s ∈ l' } : protected theorem tendsto_nhds {la : Filter α} {lb : Filter β} {f : α → Filter β} : Tendsto f la (𝓝 lb) ↔ ∀ s ∈ lb, ∀ᶠ a in la, s ∈ f a := by - simp only [nhds_eq', tendsto_lift', mem_setOf_eq] + simp only [nhds_eq', tendsto_lift', mem_ofPred_eq] protected theorem HasBasis.nhds {l : Filter α} {p : ι → Prop} {s : ι → Set α} (h : HasBasis l p s) : HasBasis (𝓝 l) p fun i => Iic (𝓟 (s i)) := by @@ -137,7 +139,7 @@ theorem monotone_nhds : Monotone (𝓝 : Filter α → Filter (Filter α)) := theorem sInter_nhds (l : Filter α) : ⋂₀ { s | s ∈ 𝓝 l } = Iic l := by simp_rw [nhds_eq, Function.comp_def, sInter_lift'_sets monotone_principal.Iic, Iic, - le_principal_iff, ← setOf_forall, ← Filter.le_def] + le_principal_iff, ← ofPred_forall, ← Filter.le_def] @[simp] theorem nhds_mono {l₁ l₂ : Filter α} : 𝓝 l₁ ≤ 𝓝 l₂ ↔ l₁ ≤ l₂ := by @@ -192,7 +194,7 @@ theorem isInducing_nhds : IsInducing (𝓝 : X → Filter X) := isInducing_iff_nhds.2 fun x => (nhds_def' _).trans <| by simp +contextual only [nhds_nhds, comap_iInf, comap_principal, - Iic_principal, preimage_setOf_eq, ← mem_interior_iff_mem_nhds, setOf_mem_eq, + Iic_principal, preimage_ofPred_eq, ← mem_interior_iff_mem_nhds, ofPred_mem_eq, IsOpen.interior_eq] @[continuity] diff --git a/Mathlib/Topology/GDelta/Basic.lean b/Mathlib/Topology/GDelta/Basic.lean index a2ee08f033db7f..0b9aad1476bf83 100644 --- a/Mathlib/Topology/GDelta/Basic.lean +++ b/Mathlib/Topology/GDelta/Basic.lean @@ -188,7 +188,7 @@ theorem residual_of_dense_Gδ {s : Set X} (ho : IsGδ s) (hd : Dense s) : s ∈ theorem mem_residual_iff {s : Set X} : s ∈ residual X ↔ ∃ S : Set (Set X), (∀ t ∈ S, IsOpen t) ∧ (∀ t ∈ S, Dense t) ∧ S.Countable ∧ ⋂₀ S ⊆ s := - mem_countableGenerate_iff.trans <| by simp_rw [subset_def, mem_setOf, forall_and, and_assoc] + mem_countableGenerate_iff.trans <| by simp_rw [subset_def, mem_ofPred, forall_and, and_assoc] end residual diff --git a/Mathlib/Topology/GDelta/MetrizableSpace.lean b/Mathlib/Topology/GDelta/MetrizableSpace.lean index 4d43e81eca6264..148ea649ff4c62 100644 --- a/Mathlib/Topology/GDelta/MetrizableSpace.lean +++ b/Mathlib/Topology/GDelta/MetrizableSpace.lean @@ -48,16 +48,19 @@ end Metrizable section ContinuousAt variable {Y : Type*} [TopologicalSpace Y] -theorem IsGδ.setOf_continuousAt [PseudoMetrizableSpace Y] (f : X → Y) : +theorem IsGδ.setOfPred_continuousAt [PseudoMetrizableSpace Y] (f : X → Y) : IsGδ { x | ContinuousAt f x } := by let := pseudoMetrizableSpaceUniformity Y have := pseudoMetrizableSpaceUniformity_countably_generated Y obtain ⟨U, _, hU⟩ := (@uniformity_hasBasis_open_symmetric Y _).exists_antitone_subbasis simp only [Uniform.continuousAt_iff_prod, nhds_prod_eq] simp only [(nhds_basis_opens _).prod_self.tendsto_iff hU.toHasBasis, - forall_prop_of_true, setOf_forall] + forall_prop_of_true, ofPred_forall] refine .iInter fun k ↦ IsOpen.isGδ <| isOpen_iff_mem_nhds.2 fun x ↦ ?_ rintro ⟨s, ⟨hsx, hso⟩, hsU⟩ filter_upwards [IsOpen.mem_nhds hso hsx] with _ hy using ⟨s, ⟨hy, hso⟩, hsU⟩ +@[deprecated (since := "2026-07-09")] +alias IsGδ.setOf_continuousAt := IsGδ.setOfPred_continuousAt + end ContinuousAt diff --git a/Mathlib/Topology/Homeomorph/Defs.lean b/Mathlib/Topology/Homeomorph/Defs.lean index 2833bea0f96d53..dda79217df4a00 100644 --- a/Mathlib/Topology/Homeomorph/Defs.lean +++ b/Mathlib/Topology/Homeomorph/Defs.lean @@ -376,11 +376,13 @@ theorem nhds_eq_comap (h : X ≃ₜ Y) (x : X) : 𝓝 x = comap h (𝓝 (h x)) : theorem comap_nhds_eq (h : X ≃ₜ Y) (y : Y) : comap h (𝓝 y) = 𝓝 (h.symm y) := by rw [h.nhds_eq_comap, h.apply_symm_apply] -theorem isClosed_setOf_iff {p : X → Prop} {q : Y → Prop} (f : X ≃ₜ Y) (hs : IsClopen {x | p x}) +theorem isClosed_setOfPred_iff {p : X → Prop} {q : Y → Prop} (f : X ≃ₜ Y) (hs : IsClopen {x | p x}) (ht : IsClopen {y | q y}) : IsClosed { x : X | p x ↔ q (f x) } := by simpa [iff_def] using! (isClosed_imp hs.2 (f.isClosed_preimage.2 ht.1)).inter (isClosed_imp (f.isOpen_preimage.2 ht.2) hs.1) +@[deprecated (since := "2026-07-09")] alias isClosed_setOf_iff := isClosed_setOfPred_iff + end Homeomorph namespace Equiv diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index e146df1472244c..8886cdcacbb203 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -98,7 +98,7 @@ theorem exists_lift_nhds {f : C(I × A, X)} {g : I × A → E} (g_lifts : p ∘ change g' (t n, a) ∈ (q e).source; rw [g'_a _ le_rfl] exact h_sub ⟨le_rfl, t_mono n.le_succ⟩ · rw [← t_0]; exact ⟨t_mono n.zero_le, le_rfl⟩ - · have ht := Set.mem_setOf.mp (frontier_le_subset_eq continuous_fst continuous_const hfr) + · have ht := Set.mem_ofPred.mp (frontier_le_subset_eq continuous_fst continuous_const hfr) have : f ta ∈ (q e).target := huv ⟨hu (by rw [ht]; exact ⟨le_rfl, t_mono n.le_succ⟩), hav⟩ rw [if_pos this] -- here we use that {tₙ} × Nₙ₊₁ is mapped to the domain of `q e` diff --git a/Mathlib/Topology/Instances/AddCircle/Defs.lean b/Mathlib/Topology/Instances/AddCircle/Defs.lean index f8000183174827..77ea785d6b0a06 100644 --- a/Mathlib/Topology/Instances/AddCircle/Defs.lean +++ b/Mathlib/Topology/Instances/AddCircle/Defs.lean @@ -177,7 +177,7 @@ theorem toIcoMod_eventuallyEq_toIocMod (hx : ¬x ≡ a [PMOD p]) : refine IsOpen.mem_nhds ?_ ?_ · rw [Ico_eq_locus_Ioc_eq_iUnion_Ioo] exact isOpen_iUnion fun i => isOpen_Ioo - · rwa [mem_setOf_eq, ← not_modEq_iff_toIcoMod_eq_toIocMod hp, AddCommGroup.modEq_comm] + · rwa [mem_ofPred_eq, ← not_modEq_iff_toIcoMod_eq_toIocMod hp, AddCommGroup.modEq_comm] theorem continuousAt_toIcoMod (hx : ¬x ≡ a [PMOD p]) : ContinuousAt (toIcoMod hp a) x := continuousAt_id.sub <| tendsto_nhds_of_eventually_eq <| @@ -241,7 +241,7 @@ theorem card_torsion_le_of_isSMulRegular (n : ℕ) (h0 : n ≠ 0) (hn : IsSMulRe have (x : {x : AddCircle p | n • x = 0}) : ∃ (k : Fin n) (y : 𝕜), y = x.1 ∧ n • y = k.1 • p := by obtain ⟨x, hx⟩ := x obtain ⟨y, rfl⟩ := mk_surjective x - rw [Set.mem_setOf, ← mk_nsmul, eq_zero_iff] at hx + rw [Set.mem_ofPred, ← mk_nsmul, eq_zero_iff] at hx have ⟨m', hm⟩ := hx have : NeZero n := ⟨h0⟩ rw [← (Int.divModEquiv n).symm_apply_apply m', Int.divModEquiv_symm_apply] at hm @@ -285,10 +285,13 @@ variable [LinearOrder 𝕜] [IsOrderedAddMonoid 𝕜] theorem finite_torsion {n : ℕ} (hn : 0 < n) : { u : AddCircle p | n • u = 0 }.Finite := finite_torsion_of_isSMulRegular _ _ <| .of_right_eq_zero_of_smul fun _ ↦ by simp [hn.ne'] -theorem finite_setOf_addOrderOf_eq {n : ℕ} (hn : 0 < n) : +theorem finite_setOfPred_addOrderOf_eq {n : ℕ} (hn : 0 < n) : {u : AddCircle p | addOrderOf u = n}.Finite := (finite_torsion p hn).subset fun _ h ↦ ((addOrderOf_eq_iff hn).mp h).1 +@[deprecated (since := "2026-07-09")] +alias finite_setOf_addOrderOf_eq := finite_setOfPred_addOrderOf_eq + theorem coe_eq_zero_of_pos_iff (hp : 0 < p) {x : 𝕜} (hx : 0 < x) : (x : AddCircle p) = 0 ↔ ∃ n : ℕ, n • p = x := by rw [coe_eq_zero_iff] @@ -681,12 +684,12 @@ theorem card_addOrderOf_eq_totient {n : ℕ} : · simp only [Nat.totient_zero, addOrderOf_eq_zero_iff] rcases em (∃ u : AddCircle p, ¬IsOfFinAddOrder u) with (⟨u, hu⟩ | h) · have : Infinite { u : AddCircle p // ¬IsOfFinAddOrder u } := by - rw [← coe_setOf, infinite_coe_iff] + rw [← coe_ofPred, infinite_coe_iff] exact infinite_not_isOfFinAddOrder hu exact Nat.card_eq_zero_of_infinite · have : IsEmpty { u : AddCircle p // ¬IsOfFinAddOrder u } := by simpa [isEmpty_subtype] using h exact Nat.card_of_isEmpty - · rw [← coe_setOf, Nat.card_congr (setAddOrderOfEquiv p hn), + · rw [← coe_ofPred, Nat.card_congr (setAddOrderOfEquiv p hn), n.totient_eq_card_lt_and_coprime] simp only [Nat.gcd_comm] diff --git a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean index 1eea4e8c17c601..4a7fa19ba74025 100644 --- a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean @@ -146,7 +146,7 @@ theorem tendsto_nhds_top {m : α → ℝ≥0∞} {f : Filter α} (h : ∀ n : theorem tendsto_nat_nhds_top : Tendsto (fun n : ℕ => ↑n) atTop (𝓝 ∞) := tendsto_nhds_top fun n => - mem_atTop_sets.2 ⟨n + 1, fun _m hm => mem_setOf.2 <| Nat.cast_lt.2 <| Nat.lt_of_succ_le hm⟩ + mem_atTop_sets.2 ⟨n + 1, fun _m hm => mem_ofPred.2 <| Nat.cast_lt.2 <| Nat.lt_of_succ_le hm⟩ @[simp, norm_cast] theorem tendsto_coe_nhds_top {f : α → ℝ≥0} {l : Filter α} : @@ -418,13 +418,13 @@ theorem continuousOn_sub : ContinuousOn (fun p : ℝ≥0∞ × ℝ≥0∞ => p.fst - p.snd) { p : ℝ≥0∞ × ℝ≥0∞ | p ≠ ⟨∞, ∞⟩ } := by rw [ContinuousOn] rintro ⟨x, y⟩ hp - simp only [Ne, Set.mem_setOf_eq, Prod.mk_inj] at hp + simp only [Ne, Set.mem_ofPred_eq, Prod.mk_inj] at hp exact tendsto_nhdsWithin_of_tendsto_nhds (tendsto_sub (not_and_or.mp hp)) theorem continuous_sub_left {a : ℝ≥0∞} (a_ne_top : a ≠ ∞) : Continuous (a - ·) := by change Continuous (Function.uncurry Sub.sub ∘ (a, ·)) refine continuousOn_sub.comp_continuous (.prodMk_right a) fun x => ?_ - simp only [a_ne_top, Ne, mem_setOf_eq, Prod.mk_inj, false_and, not_false_iff] + simp only [a_ne_top, Ne, mem_ofPred_eq, Prod.mk_inj, false_and, not_false_iff] theorem continuous_nnreal_sub {a : ℝ≥0} : Continuous fun x : ℝ≥0∞ => (a : ℝ≥0∞) - x := continuous_sub_left coe_ne_top @@ -441,7 +441,7 @@ theorem continuous_sub_right (a : ℝ≥0∞) : Continuous fun x : ℝ≥0∞ => · rw [show (fun x => x - a) = (fun p : ℝ≥0∞ × ℝ≥0∞ => p.fst - p.snd) ∘ fun x => ⟨x, a⟩ by rfl] apply continuousOn_sub.comp_continuous (by fun_prop) intro x - simp only [a_infty, Ne, mem_setOf_eq, Prod.mk_inj, and_false, not_false_iff] + simp only [a_infty, Ne, mem_ofPred_eq, Prod.mk_inj, and_false, not_false_iff] protected theorem Tendsto.pow {f : Filter α} {m : α → ℝ≥0∞} {a : ℝ≥0∞} {n : ℕ} (hm : Tendsto m f (𝓝 a)) : Tendsto (fun x => m x ^ n) f (𝓝 (a ^ n)) := @@ -661,15 +661,23 @@ theorem Metric.ediam_closure (s : Set α) : ediam (closure s) = ediam s := by theorem Metric.diam_closure {α : Type*} [PseudoMetricSpace α] (s : Set α) : Metric.diam (closure s) = diam s := by simp only [Metric.diam, Metric.ediam_closure] -theorem isClosed_setOf_lipschitzOnWith {α β} [PseudoEMetricSpace α] [PseudoEMetricSpace β] (K : ℝ≥0) +theorem isClosed_setOfPred_lipschitzOnWith {α β} [PseudoEMetricSpace α] [PseudoEMetricSpace β] + (K : ℝ≥0) (s : Set α) : IsClosed { f : α → β | LipschitzOnWith K f s } := by - simp only [LipschitzOnWith, setOf_forall] + simp only [LipschitzOnWith, ofPred_forall] refine isClosed_biInter fun x _ => isClosed_biInter fun y _ => isClosed_le ?_ ?_ exacts [.edist (continuous_apply x) (continuous_apply y), continuous_const] -theorem isClosed_setOf_lipschitzWith {α β} [PseudoEMetricSpace α] [PseudoEMetricSpace β] (K : ℝ≥0) : +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_lipschitzOnWith := isClosed_setOfPred_lipschitzOnWith + +theorem isClosed_setOfPred_lipschitzWith {α β} [PseudoEMetricSpace α] [PseudoEMetricSpace β] + (K : ℝ≥0) : IsClosed { f : α → β | LipschitzWith K f } := by - simp only [← lipschitzOnWith_univ, isClosed_setOf_lipschitzOnWith] + simp only [← lipschitzOnWith_univ, isClosed_setOfPred_lipschitzOnWith] + +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_lipschitzWith := isClosed_setOfPred_lipschitzWith protected lemma LipschitzOnWith.closure [PseudoEMetricSpace β] {f : α → β} {s : Set α} {K : ℝ≥0} (hcont : ContinuousOn f (closure s)) (hf : LipschitzOnWith K f s) : @@ -929,6 +937,6 @@ lemma Dense.lipschitzWith_extend {α β : Type*} rintro ⟨x, y⟩ ⟨hx, hy⟩ have Ax : hs.extend f x = f ⟨x, hx⟩ := hs.extend_eq hf.continuous ⟨x, hx⟩ have Ay : hs.extend f y = f ⟨y, hy⟩ := hs.extend_eq hf.continuous ⟨y, hy⟩ - simp only [Set.mem_setOf_eq, Ax, Ay] + simp only [Set.mem_ofPred_eq, Ax, Ay] exact hf ⟨x, hx⟩ ⟨y, hy⟩ - simpa only [Dense, IsClosed.closure_eq, Set.mem_setOf_eq, Prod.forall] using! this + simpa only [Dense, IsClosed.closure_eq, Set.mem_ofPred_eq, Prod.forall] using! this diff --git a/Mathlib/Topology/Instances/Irrational.lean b/Mathlib/Topology/Instances/Irrational.lean index c41da3cb18631b..843286cf44a3db 100644 --- a/Mathlib/Topology/Instances/Irrational.lean +++ b/Mathlib/Topology/Instances/Irrational.lean @@ -15,8 +15,8 @@ public import Mathlib.Topology.Instances.Real.Lemmas In this file we prove the following theorems: -* `IsGδ.setOf_irrational`, `dense_irrational`, `eventually_residual_irrational`: irrational numbers - form a dense Gδ set; +* `IsGδ.setOfPred_irrational`, `dense_irrational`, `eventually_residual_irrational`: irrational + numbers form a dense Gδ set; * `Irrational.eventually_forall_le_dist_cast_div`, `Irrational.eventually_forall_le_dist_cast_div_of_denom_le`; @@ -38,9 +38,11 @@ open Set Filter Metric open Filter Topology -protected theorem IsGδ.setOf_irrational : IsGδ { x | Irrational x } := +protected theorem IsGδ.setOfPred_irrational : IsGδ { x | Irrational x } := (countable_range _).isGδ_compl +@[deprecated (since := "2026-07-09")] alias IsGδ.setOf_irrational := IsGδ.setOfPred_irrational + theorem dense_irrational : Dense { x : ℝ | Irrational x } := by refine Real.isTopologicalBasis_Ioo_rat.dense_iff.2 ?_ @@ -50,7 +52,7 @@ theorem dense_irrational : Dense { x : ℝ | Irrational x } := by exact exists_irrational_btwn (Rat.cast_lt.2 hlt) theorem eventually_residual_irrational : ∀ᶠ x in residual ℝ, Irrational x := - residual_of_dense_Gδ .setOf_irrational dense_irrational + residual_of_dense_Gδ .setOfPred_irrational dense_irrational namespace Irrational diff --git a/Mathlib/Topology/Instances/Matrix.lean b/Mathlib/Topology/Instances/Matrix.lean index c3758be01ab206..b0264407092214 100644 --- a/Mathlib/Topology/Instances/Matrix.lean +++ b/Mathlib/Topology/Instances/Matrix.lean @@ -308,12 +308,15 @@ theorem Continuous.matrix_blockDiag' Continuous fun x => blockDiag' (A x) := continuous_pi fun _i => continuous_matrix fun _j _k => hA.matrix_elem _ _ -theorem isClosed_setOf_blockTriangular {α : Type*} {b : m → α} [LinearOrder α] [Zero R] +theorem isClosed_setOfPred_blockTriangular {α : Type*} {b : m → α} [LinearOrder α] [Zero R] [T2Space R] : IsClosed {M : Matrix m m R | M.BlockTriangular b} := by - simp only [BlockTriangular, Set.setOf_forall] + simp only [BlockTriangular, Set.ofPred_forall] refine isClosed_iInter fun i => isClosed_iInter fun j => isClosed_iInter fun _ => ?_ exact isClosed_eq (continuous_id.matrix_elem i j) continuous_const +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_blockTriangular := isClosed_setOfPred_blockTriangular + end BlockMatrices end Continuity diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 938baa9532253c..452d75ce3c439f 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -337,7 +337,7 @@ theorem isPreirreducible_iff_subset_closure_inter_open (S : Set X) : · intro a b ha hb ⟨p, pS, pa⟩ bS by_contra! h0 suffices p ∉ closure (S ∩ b) from this <| (h b hb bS) pS - simp only [closure, mem_sInter, mem_setOf_eq, and_imp, not_forall, exists_prop] + simp only [closure, mem_sInter, mem_ofPred_eq, and_imp, not_forall, exists_prop] use aᶜ grind [isClosed_compl_iff, subset_compl_iff_disjoint_left, disjoint_iff_inter_eq_empty] diff --git a/Mathlib/Topology/JacobsonSpace.lean b/Mathlib/Topology/JacobsonSpace.lean index 8dc924808ef18b..c035387e253acc 100644 --- a/Mathlib/Topology/JacobsonSpace.lean +++ b/Mathlib/Topology/JacobsonSpace.lean @@ -35,7 +35,7 @@ variable (X) {Y} [TopologicalSpace X] [TopologicalSpace Y] {f : X → Y} section closedPoints /-- The set of closed points. -/ -def closedPoints : Set X := setOf (IsClosed {·}) +def closedPoints : Set X := Set.ofPred (IsClosed {·}) variable {X} diff --git a/Mathlib/Topology/LocalAtTarget.lean b/Mathlib/Topology/LocalAtTarget.lean index 1ff14ed4d98080..a8b0228efad726 100644 --- a/Mathlib/Topology/LocalAtTarget.lean +++ b/Mathlib/Topology/LocalAtTarget.lean @@ -220,7 +220,7 @@ lemma isOpenMap_iff_comp : IsOpenMap f ↔ ∀ i, IsOpenMap (f ∘ ((↑) : U i intro V hV convert! isOpen_iUnion (fun i ↦ hf i _ <| isOpen_induced hV) simp_rw [Set.image_comp, Set.image_preimage_eq_inter_range, ← Set.image_iUnion, - Subtype.range_coe_subtype, SetLike.setOf_mem_eq, hU.iUnion_inter] + Subtype.range_coe_subtype, SetLike.setOfPred_mem_eq, hU.iUnion_inter] lemma generalizingMap_iff_comp : GeneralizingMap f ↔ ∀ i, GeneralizingMap (f ∘ ((↑) : U i → α)) := by diff --git a/Mathlib/Topology/LocallyFinite.lean b/Mathlib/Topology/LocallyFinite.lean index 21ae2a80a11d42..61ec1828ad70af 100644 --- a/Mathlib/Topology/LocallyFinite.lean +++ b/Mathlib/Topology/LocallyFinite.lean @@ -82,7 +82,7 @@ protected theorem nhdsWithin_iUnion (hf : LocallyFinite f) (a : X) : 𝓝[⋃ i, f i] a = 𝓝[⋃ i, f i ∩ U] a := by rw [← iUnion_inter, ← nhdsWithin_inter_of_mem' (nhdsWithin_le_nhds haU)] _ = 𝓝[⋃ i ∈ {j | (f j ∩ U).Nonempty}, (f i ∩ U)] a := by - simp only [mem_setOf_eq, iUnion_nonempty_self] + simp only [mem_ofPred_eq, iUnion_nonempty_self] _ = ⨆ i ∈ {j | (f j ∩ U).Nonempty}, 𝓝[f i ∩ U] a := nhdsWithin_biUnion hfin _ _ _ ≤ ⨆ i, 𝓝[f i ∩ U] a := iSup₂_le_iSup _ _ _ ≤ ⨆ i, 𝓝[f i] a := iSup_mono fun i ↦ nhdsWithin_mono _ inter_subset_left @@ -200,7 +200,7 @@ theorem Equiv.locallyFinite_comp_iff (e : ι' ≃ ι) : LocallyFinite (f ∘ e) theorem locallyFinite_sum {f : ι ⊕ ι' → Set X} : LocallyFinite f ↔ LocallyFinite (f ∘ Sum.inl) ∧ LocallyFinite (f ∘ Sum.inr) := by simp only [locallyFinite_iff_smallSets, ← forall_and, ← finite_preimage_inl_and_inr, - preimage_setOf_eq, (· ∘ ·), eventually_and] + preimage_ofPred_eq, (· ∘ ·), eventually_and] theorem LocallyFinite.sumElim {g : ι' → Set X} (hf : LocallyFinite f) (hg : LocallyFinite g) : LocallyFinite (Sum.elim f g) := diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 0d8819f14dca29..658bf3dce78d73 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -80,7 +80,7 @@ theorem supportDiscreteWithin_iff_locallyFiniteWithin [T1Space X] [Zero Y] {f : f =ᶠ[codiscreteWithin U] 0 ↔ ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support) := by have : f.support = (U \ {x | f x = (0 : X → Y) x}) := by ext x - simp only [mem_support, ne_eq, Pi.zero_apply, Set.mem_sdiff, mem_setOf_eq, iff_and_self] + simp only [mem_support, ne_eq, Pi.zero_apply, Set.mem_sdiff, mem_ofPred_eq, iff_and_self] exact (h ·) rw [EventuallyEq, Filter.Eventually, codiscreteWithin_iff_locallyFiniteComplementWithin, this] @@ -206,7 +206,7 @@ theorem eq_zero_codiscreteWithin [Zero Y] [T1Space X] (D : locallyFinsuppWithin apply codiscreteWithin_iff_locallyFiniteComplementWithin.2 have : D.support = (U \ {x | D x = (0 : X → Y) x}) := by ext x - simp only [mem_support, ne_eq, Pi.zero_apply, Set.mem_sdiff, Set.mem_setOf_eq, iff_and_self] + simp only [mem_support, ne_eq, Pi.zero_apply, Set.mem_sdiff, Set.mem_ofPred_eq, iff_and_self] exact (support_subset_iff.1 D.supportWithinDomain) x rw [← this] exact D.supportLocallyFiniteWithinDomain @@ -221,7 +221,7 @@ theorem discreteSupport [Zero Y] [T1Space X] (D : locallyFinsuppWithin U Y) : constructor · exact fun hx ↦ ⟨by tauto, D.supportWithinDomain hx⟩ · intro hx - rw [mem_inter_iff, mem_compl_iff, mem_setOf_eq] at hx + rw [mem_inter_iff, mem_compl_iff, mem_ofPred_eq] at hx tauto rw [this] apply isDiscrete_of_codiscreteWithin @@ -271,7 +271,7 @@ Functions with locally finite support within `U` form an additive submonoid of f protected def addSubmonoid [AddMonoid Y] : AddSubmonoid (X → Y) where carrier := {f | f.support ⊆ U ∧ ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)} zero_mem' := by - simp only [support_subset_iff, ne_eq, mem_setOf_eq, Pi.zero_apply, not_true_eq_false, + simp only [support_subset_iff, ne_eq, mem_ofPred_eq, Pi.zero_apply, not_true_eq_false, IsEmpty.forall_iff, implies_true, support_zero, inter_empty, finite_empty, and_true, true_and] exact fun _ _ ↦ ⟨⊤, univ_mem⟩ @@ -286,7 +286,7 @@ protected def addSubmonoid [AddMonoid Y] : AddSubmonoid (X → Y) where use t₁ ∩ t₂, inter_mem ht₁.1 ht₂.1 apply Set.Finite.subset (s := (t₁ ∩ f.support) ∪ (t₂ ∩ g.support)) (ht₁.2.union ht₂.2) intro a ha - simp_all only [support_subset_iff, ne_eq, mem_setOf_eq, + simp_all only [support_subset_iff, ne_eq, mem_ofPred_eq, mem_inter_iff, mem_support, Pi.add_apply, mem_union, true_and] by_contra! hCon simp_all diff --git a/Mathlib/Topology/Maps/Basic.lean b/Mathlib/Topology/Maps/Basic.lean index f05bc5d51367aa..84685026e27afe 100644 --- a/Mathlib/Topology/Maps/Basic.lean +++ b/Mathlib/Topology/Maps/Basic.lean @@ -161,10 +161,12 @@ theorem image_eq_isOpen_inter_range (hf : IsInducing f) {s : Set X} (hs : IsOpen obtain ⟨c, hc, rfl⟩ := hf.isOpen_iff.1 hs exact ⟨c, hc, image_preimage_eq_inter_range⟩ -theorem setOf_isOpen (hf : IsInducing f) : +theorem setOfPred_isOpen (hf : IsInducing f) : {s : Set X | IsOpen s} = preimage f '' {t | IsOpen t} := Set.ext fun _ ↦ hf.isOpen_iff +@[deprecated (since := "2026-07-09")] alias setOf_isOpen := setOfPred_isOpen + theorem dense_iff (hf : IsInducing f) {s : Set X} : Dense s ↔ ∀ x, f x ∈ closure (f '' s) := by simp only [Dense, hf.closure_eq_preimage_closure_image, mem_preimage] diff --git a/Mathlib/Topology/Maps/Proper/UniversallyClosed.lean b/Mathlib/Topology/Maps/Proper/UniversallyClosed.lean index 43615f5136d0e7..4fd7a3dbef3d91 100644 --- a/Mathlib/Topology/Maps/Proper/UniversallyClosed.lean +++ b/Mathlib/Topology/Maps/Proper/UniversallyClosed.lean @@ -59,7 +59,7 @@ theorem isProperMap_iff_isClosedMap_filter {X : Type u} {Y : Type v} [Topologica -- must contain some element of the form `(z, pure z)`. In other words, we have `z ∈ U` and -- `Uᶜ ∈ pure z`, which means `z ∈ Uᶜ` by the definition of pure. -- This is a contradiction, which completes the proof. - rcases hx (U ×ˢ {𝒢 | Uᶜ ∈ 𝒢}) (prod_mem_nhds hU (isOpen_setOf_mem.mem_nhds hUc)) with + rcases hx (U ×ˢ {𝒢 | Uᶜ ∈ 𝒢}) (prod_mem_nhds hU (isOpen_setOfPred_mem.mem_nhds hUc)) with ⟨⟨z, 𝒢⟩, ⟨⟨hz : z ∈ U, hz' : Uᶜ ∈ 𝒢⟩, rfl : 𝒢 = pure z⟩⟩ exact hz' hz diff --git a/Mathlib/Topology/MetricSpace/Algebra.lean b/Mathlib/Topology/MetricSpace/Algebra.lean index f5fe9c63a1d14b..7064d168835556 100644 --- a/Mathlib/Topology/MetricSpace/Algebra.lean +++ b/Mathlib/Topology/MetricSpace/Algebra.lean @@ -177,7 +177,7 @@ theorem TendstoLocallyUniformlyOn.smul₀_of_isBoundedUnder {X ι : Type*} [Topo filter_upwards [hF x hx (Metric.dist_mem_uniformity one_pos), hG x hx (Metric.dist_mem_uniformity one_pos), tendsto_snd hC] with ⟨n, y⟩ hFn hGn hfg simp only [mem_prod, Metric.mem_ball, Prod.dist_eq, Prod.fst_zero, Prod.snd_zero, sup_lt_iff, - mem_preimage, mem_setOf] at hFn hGn hfg ⊢ + mem_preimage, mem_ofPred] at hFn hGn hfg ⊢ grw [dist_triangle_left (F n y) 0 (f y), dist_triangle_left (G n y) 0 (g y)] constructor <;> constructor <;> linarith diff --git a/Mathlib/Topology/MetricSpace/Bounded.lean b/Mathlib/Topology/MetricSpace/Bounded.lean index bd4e06e4f1504f..b8c98c6936ff4e 100644 --- a/Mathlib/Topology/MetricSpace/Bounded.lean +++ b/Mathlib/Topology/MetricSpace/Bounded.lean @@ -650,7 +650,7 @@ theorem exists_forall_le_of_isBounded {f : β → α} (hf : Continuous f) (x₀ refine hf.exists_forall_le' (x₀ := x₀) ?_ have hU : {x : β | f x₀ < f x} ∈ Filter.cocompact β := by refine Filter.mem_cocompact'.mpr ⟨_, ?_, fun ⦃_⦄ a ↦ a⟩ - simp only [Set.compl_setOf, not_lt] + simp only [Set.compl_ofPred, not_lt] exact Metric.isCompact_of_isClosed_isBounded (isClosed_le (by fun_prop) (by fun_prop)) h filter_upwards [hU] with x hx using hx.le diff --git a/Mathlib/Topology/MetricSpace/CantorScheme.lean b/Mathlib/Topology/MetricSpace/CantorScheme.lean index baadcf3f8b6a98..0b9977d47176eb 100644 --- a/Mathlib/Topology/MetricSpace/CantorScheme.lean +++ b/Mathlib/Topology/MetricSpace/CantorScheme.lean @@ -142,7 +142,7 @@ theorem VanishingDiam.map_continuous [TopologicalSpace β] [DiscreteTopology β] rw [_root_.eventually_nhds_iff] refine ⟨(↑)⁻¹' cylinder x.1 n, ?_, ?_, by simp⟩ · rintro y hyx - rw [mem_preimage, Subtype.coe_mk, cylinder_eq_res, mem_setOf] at hyx + rw [mem_preimage, Subtype.coe_mk, cylinder_eq_res, mem_ofPred] at hyx apply hn · rw [← hyx] apply map_mem diff --git a/Mathlib/Topology/MetricSpace/Closeds.lean b/Mathlib/Topology/MetricSpace/Closeds.lean index a99e197f1afe61..84f4056f1a67af 100644 --- a/Mathlib/Topology/MetricSpace/Closeds.lean +++ b/Mathlib/Topology/MetricSpace/Closeds.lean @@ -37,7 +37,7 @@ variable {α : Type*} [PseudoEMetricSpace α] theorem mem_hausdorffEntourage_of_hausdorffEDist_lt {s t : Set α} {δ : ℝ≥0∞} (h : hausdorffEDist s t < δ) : (s, t) ∈ hausdorffEntourage {p | edist p.1 p.2 < δ} := by rw [hausdorffEDist, max_lt_iff] at h - rw [hausdorffEntourage, Set.mem_setOf] + rw [hausdorffEntourage, Set.mem_ofPred] conv => enter [2, 2, 1, 1, _]; rw [edist_comm] have {s t : Set α} (h : ⨆ x ∈ s, infEDist x t < δ) : s ⊆ SetRel.preimage {p | edist p.1 p.2 < δ} t := by @@ -48,7 +48,7 @@ theorem mem_hausdorffEntourage_of_hausdorffEDist_lt {s t : Set α} {δ : ℝ≥0 theorem hausdorffEDist_le_of_mem_hausdorffEntourage {s t : Set α} {δ : ℝ≥0∞} (h : (s, t) ∈ hausdorffEntourage {p | edist p.1 p.2 ≤ δ}) : hausdorffEDist s t ≤ δ := by rw [hausdorffEDist, max_le_iff] - rw [hausdorffEntourage, Set.mem_setOf] at h + rw [hausdorffEntourage, Set.mem_ofPred] at h conv at h => enter [2, 2, 1, 1, _]; rw [edist_comm] have {s t : Set α} (h : s ⊆ SetRel.preimage {p | edist p.1 p.2 ≤ δ} t) : ⨆ x ∈ s, infEDist x t ≤ δ := by diff --git a/Mathlib/Topology/MetricSpace/Completion.lean b/Mathlib/Topology/MetricSpace/Completion.lean index 888e2d05587c21..9dd98004995c58 100644 --- a/Mathlib/Topology/MetricSpace/Completion.lean +++ b/Mathlib/Topology/MetricSpace/Completion.lean @@ -105,7 +105,7 @@ protected theorem mem_uniformity_dist (s : Set (Completion α × Completion α)) by_cases! h : ε ≤ dist x y · exact Or.inl h · have Z := hε h - simp only [Set.mem_setOf_eq] at Z + simp only [Set.mem_ofPred_eq] at Z exact Or.inr Z simp only [not_le.mpr hxy, false_or] at this exact ts this diff --git a/Mathlib/Topology/MetricSpace/GromovHausdorff.lean b/Mathlib/Topology/MetricSpace/GromovHausdorff.lean index ce17f30ae63571..47d4dd6127f509 100644 --- a/Mathlib/Topology/MetricSpace/GromovHausdorff.lean +++ b/Mathlib/Topology/MetricSpace/GromovHausdorff.lean @@ -226,7 +226,7 @@ theorem ghDist_le_hausdorffDist {X : Type u} [MetricSpace X] [CompactSpace X] [N rw [eq_toGHSpace_iff] exact ⟨fun x => F (Ψ' x), (kuratowskiEmbedding.isometry _).comp IΨ', range_comp _ _⟩ refine csInf_le ⟨0, ?_⟩ ?_ - · simp only [lowerBounds, mem_image, mem_prod, mem_setOf_eq, Prod.exists, and_imp, + · simp only [lowerBounds, mem_image, mem_prod, mem_ofPred_eq, Prod.exists, and_imp, forall_exists_index] intro t _ _ _ _ ht rw [← ht] @@ -289,7 +289,7 @@ theorem hausdorffDist_optimal {X : Type u} [MetricSpace X] [CompactSpace X] [Non -- check that the induced "distance" is a candidate have Fgood : F ∈ candidates X Y := by simp only [F, candidates, forall_const, - dist_eq_zero, Set.mem_setOf_eq] + dist_eq_zero, Set.mem_ofPred_eq] repeat' constructor · exact fun x y => calc @@ -398,7 +398,7 @@ instance : MetricSpace GHSpace where refine le_antisymm ?_ ?_ · apply csInf_le · exact ⟨0, by rintro b ⟨⟨u, v⟩, -, rfl⟩; exact hausdorffDist_nonneg⟩ - · simp only [mem_image, mem_prod, mem_setOf_eq, Prod.exists] + · simp only [mem_image, mem_prod, mem_ofPred_eq, Prod.exists] exists y, y simpa only [and_self_iff, hausdorffDist_self_zero, eq_self_iff_true, and_true] · apply le_csInf diff --git a/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean b/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean index f30003724c53e3..8dc9e1b6036bf2 100644 --- a/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean +++ b/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean @@ -231,7 +231,7 @@ private theorem closed_candidatesB : IsClosed (candidatesB X Y) := by ⋂ x, { f : Cb X Y | f (x, x) = 0 }) ∩ ⋂ (x) (y), { f : Cb X Y | f (x, y) ≤ maxVar X Y } := by ext - simp only [candidatesB, candidates, mem_inter_iff, mem_iInter, mem_setOf_eq] + simp only [candidatesB, candidates, mem_inter_iff, mem_iInter, mem_ofPred_eq] rw [this] repeat' first @@ -389,7 +389,7 @@ set_option backward.privateInPublic true in /-- The distance on `X ⊕ Y` is a candidate -/ private theorem dist_mem_candidates : (fun p : (X ⊕ Y) × (X ⊕ Y) => dist p.1 p.2) ∈ candidates X Y := by - simp_rw [candidates, Set.mem_setOf_eq, dist_comm, dist_triangle, dist_self, maxVar_bound, + simp_rw [candidates, Set.mem_ofPred_eq, dist_comm, dist_triangle, dist_self, maxVar_bound, forall_const, and_true] exact ⟨fun x y => rfl, fun x y => rfl⟩ diff --git a/Mathlib/Topology/MetricSpace/Holder.lean b/Mathlib/Topology/MetricSpace/Holder.lean index 11d9e8bf780056..5eb1eac1c7515a 100644 --- a/Mathlib/Topology/MetricSpace/Holder.lean +++ b/Mathlib/Topology/MetricSpace/Holder.lean @@ -223,18 +223,21 @@ lemma interpolate_const {C s t₁ t₂ : ℝ≥0} {A : Set X} variable (f) in /-- For fixed `f : X → Y`, `A : Set X` and `C : ℝ≥0`, the set of all parameters `r : ℝ≥0` such that `f` is `(C, r)`-Hölder on `A` is convex. -/ -lemma _root_.convex_setOf_holderOnWith (C : ℝ≥0) (A : Set X) : +lemma _root_.convex_setOfPred_holderOnWith (C : ℝ≥0) (A : Set X) : Convex ℝ≥0 {r | HolderOnWith C r f A} := by intro r hr s hs _ _ _ _ ht rw [smul_eq_mul, smul_eq_mul, ← mul_comm r, ← mul_comm s] exact hr.interpolate_const hs ht +@[deprecated (since := "2026-07-09")] +alias _root_.convex_setOf_holderOnWith := _root_.convex_setOfPred_holderOnWith + lemma of_le_of_le {C₁ C₂ s t : ℝ≥0} {A : Set X} (hf₁ : HolderOnWith C₁ r f A) (hf₂ : HolderOnWith C₂ s f A) (hrt : r ≤ t) (hts : t ≤ s) : HolderOnWith (max C₁ C₂) t f A := by replace hf₁ := hf₁.mono_const (le_max_left C₁ C₂) replace hf₂ := hf₂.mono_const (le_max_right C₁ C₂) - exact convex_setOf_holderOnWith f (max C₁ C₂) A |>.segment_subset hf₁ hf₂ + exact convex_setOfPred_holderOnWith f (max C₁ C₂) A |>.segment_subset hf₁ hf₂ (NNReal.Icc_subset_segment ⟨hrt, hts⟩) end HolderOnWith @@ -318,10 +321,13 @@ lemma interpolate_const {C s t₁ t₂ : ℝ≥0} variable (f) in /-- For fixed `f : X → Y` and `C : ℝ≥0`, the set of all parameters `r : ℝ≥0` such that `f` is `(C, r)`-Hölder is convex. -/ -lemma _root_.convex_setOf_holderWith (C : ℝ≥0) : +lemma _root_.convex_setOfPred_holderWith (C : ℝ≥0) : Convex ℝ≥0 {r | HolderWith C r f} := by simp_rw [← holderOnWith_univ] - exact convex_setOf_holderOnWith f C _ + exact convex_setOfPred_holderOnWith f C _ + +@[deprecated (since := "2026-07-09")] +alias _root_.convex_setOf_holderWith := _root_.convex_setOfPred_holderWith lemma of_le_of_le {C₁ C₂ s t : ℝ≥0} (hf₁ : HolderWith C₁ r f) (hf₂ : HolderWith C₂ s f) (hrt : r ≤ t) diff --git a/Mathlib/Topology/MetricSpace/Isometry.lean b/Mathlib/Topology/MetricSpace/Isometry.lean index 4c9894e25c229f..b9e0189c095dff 100644 --- a/Mathlib/Topology/MetricSpace/Isometry.lean +++ b/Mathlib/Topology/MetricSpace/Isometry.lean @@ -234,21 +234,23 @@ theorem diam_range (hf : Isometry f) : Metric.diam (range f) = Metric.diam (univ rw [← image_univ] exact hf.diam_image univ -theorem preimage_setOf_dist (hf : Isometry f) (x : α) (p : ℝ → Prop) : +theorem preimage_setOfPred_dist (hf : Isometry f) (x : α) (p : ℝ → Prop) : f ⁻¹' { y | p (dist y (f x)) } = { y | p (dist y x) } := by simp [hf.dist_eq] +@[deprecated (since := "2026-07-09")] alias preimage_setOf_dist := preimage_setOfPred_dist + theorem preimage_closedBall (hf : Isometry f) (x : α) (r : ℝ) : f ⁻¹' Metric.closedBall (f x) r = Metric.closedBall x r := - hf.preimage_setOf_dist x (· ≤ r) + hf.preimage_setOfPred_dist x (· ≤ r) theorem preimage_ball (hf : Isometry f) (x : α) (r : ℝ) : f ⁻¹' Metric.ball (f x) r = Metric.ball x r := - hf.preimage_setOf_dist x (· < r) + hf.preimage_setOfPred_dist x (· < r) theorem preimage_sphere (hf : Isometry f) (x : α) (r : ℝ) : f ⁻¹' Metric.sphere (f x) r = Metric.sphere x r := - hf.preimage_setOf_dist x (· = r) + hf.preimage_setOfPred_dist x (· = r) theorem mapsTo_ball (hf : Isometry f) (x : α) (r : ℝ) : MapsTo f (Metric.ball x r) (Metric.ball (f x) r) := diff --git a/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean b/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean index 4128bba223e4e3..a84ec966909b97 100644 --- a/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean +++ b/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean @@ -81,7 +81,7 @@ theorem exists_forall_closedEBall_subset_aux₂ (y : X) : (Ioi (0 : ℝ) ∩ ENNReal.ofReal ⁻¹' ⋂ (i) (_ : y ∈ K i), { r | closedEBall y r ⊆ U i }) := (convex_Ioi _).inter <| OrdConnected.convex <| OrdConnected.preimage_ennreal_ofReal <| ordConnected_iInter fun i => ordConnected_iInter fun (_ : y ∈ K i) => - ordConnected_setOf_closedEBall_subset y (U i) + ordConnected_setOfPred_closedEBall_subset y (U i) /-- Let `X` be an extended metric space. Let `K : ι → Set X` be a locally finite family of closed sets, let `U : ι → Set X` be a family of open sets such that `K i ⊆ U i` for all `i`. Then there diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index bc5dd4c780072e..0ff0d4f59dbc78 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -412,7 +412,7 @@ protected def metricSpaceOfDiscreteUniformity {E : ℕ → Type*} [∀ n, Unifor eq_of_dist_eq_zero := PiNat.eq_of_dist_eq_zero _ _ toUniformSpace := Pi.uniformSpace _ uniformity_dist := by - simp only [Pi.uniformity, h, SetRel.id, comap_principal, preimage_setOf_eq] + simp only [Pi.uniformity, h, SetRel.id, comap_principal, preimage_ofPred_eq] apply le_antisymm · simp only [le_iInf_iff, le_principal_iff] intro ε εpos @@ -420,9 +420,9 @@ protected def metricSpaceOfDiscreteUniformity {E : ℕ → Type*} [∀ n, Unifor apply @mem_iInf_of_iInter _ _ _ _ _ (Finset.range n).finite_toSet fun i => { p : (∀ n : ℕ, E n) × ∀ n : ℕ, E n | p.fst i = p.snd i } - · simp only [mem_principal, setOf_subset_setOf, imp_self, imp_true_iff] + · simp only [mem_principal, ofPred_subset_ofPred, imp_self, imp_true_iff] · rintro ⟨x, y⟩ hxy - simp only [Finset.mem_coe, Finset.mem_range, iInter_coe_set, mem_iInter, mem_setOf_eq] + simp only [Finset.mem_coe, Finset.mem_range, iInter_coe_set, mem_iInter, mem_ofPred_eq] at hxy apply lt_of_le_of_lt _ hn rw [← mem_cylinder_iff_dist_le, mem_cylinder_iff] @@ -431,7 +431,7 @@ protected def metricSpaceOfDiscreteUniformity {E : ℕ → Type*} [∀ n, Unifor intro n refine mem_iInf_of_mem ((1 / 2) ^ n : ℝ) ?_ refine mem_iInf_of_mem (by positivity) ?_ - simp only [mem_principal, setOf_subset_setOf, Prod.forall] + simp only [mem_principal, ofPred_subset_ofPred, Prod.forall] intro x y hxy exact apply_eq_of_dist_lt hxy le_rfl } @@ -842,7 +842,7 @@ protected def pseudoEMetricSpace : PseudoEMetricSpace (∀ i, F i) where _ = _ := ENNReal.tsum_add .. toUniformSpace := Pi.uniformSpace _ uniformity_edist := by - simp only [Pi.uniformity, comap_iInf, gt_iff_lt, preimage_setOf_eq, comap_principal, + simp only [Pi.uniformity, comap_iInf, gt_iff_lt, preimage_ofPred_eq, comap_principal, PseudoEMetricSpace.uniformity_edist, le_antisymm_iff, le_iInf_iff, le_principal_iff] constructor · intro ε hε @@ -858,7 +858,7 @@ protected def pseudoEMetricSpace : PseudoEMetricSpace (∀ i, F i) where refine mem_iInf_of_mem δ (mem_iInf_of_mem δpos ?_) simp only [mem_principal, Subset.rfl] · rintro ⟨x, y⟩ hxy - simp only [mem_iInter, mem_setOf_eq, SetCoe.forall, Finset.mem_coe] at hxy + simp only [mem_iInter, mem_ofPred_eq, SetCoe.forall, Finset.mem_coe] at hxy calc edist x y = ∑' i : ι, min (2⁻¹ ^ encode i) (edist (x i) (y i)) := rfl _ = ∑ i ∈ K, min (2⁻¹ ^ encode i) (edist (x i) (y i)) + @@ -878,7 +878,7 @@ protected def pseudoEMetricSpace : PseudoEMetricSpace (∀ i, F i) where · intro i ε hε₀ have : (0 : ℝ≥0∞) < 2⁻¹ ^ encode i := ENNReal.pow_pos (by norm_num) _ refine mem_iInf_of_mem (min (2⁻¹ ^ encode i) ε) <| mem_iInf_of_mem (by positivity) ?_ - simp only [and_imp, Prod.forall, setOf_subset_setOf, lt_min_iff, mem_principal] + simp only [and_imp, Prod.forall, ofPred_subset_ofPred, lt_min_iff, mem_principal] intro x y hn exact (edist_le_edist_pi_of_edist_lt hn).trans_lt diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean index c41d8cca739342..05062ab1fe9e0c 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean @@ -70,7 +70,7 @@ nonrec theorem isUniformInducing_iff [PseudoMetricSpace β] {f : α → β} : ∀ δ > 0, ∃ ε > 0, ∀ {a b : α}, dist (f a) (f b) < ε → dist a b < δ := isUniformInducing_iff'.trans <| Iff.rfl.and <| ((uniformity_basis_dist.comap _).le_basis_iff uniformity_basis_dist).trans <| by - simp only [subset_def, Prod.forall, gt_iff_lt, preimage_setOf_eq, Prod.map_apply, mem_setOf] + simp only [subset_def, Prod.forall, gt_iff_lt, preimage_ofPred_eq, Prod.map_apply, mem_ofPred] nonrec theorem isUniformEmbedding_iff [PseudoMetricSpace β] {f : α → β} : IsUniformEmbedding f ↔ Function.Injective f ∧ UniformContinuous f ∧ diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean b/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean index ca97a65f63e757..2b6fdf53288f97 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean @@ -35,7 +35,7 @@ abbrev PseudoMetricSpace.induced {α β} (f : α → β) (m : PseudoMetricSpace uniformity_dist := (uniformity_basis_dist.comap _).eq_biInf toBornology := Bornology.induced f cobounded_sets := Set.ext fun s => mem_comap_iff_compl.trans <| by - simp only [← isBounded_def, isBounded_iff, forall_mem_image, mem_setOf] + simp only [← isBounded_def, isBounded_iff, forall_mem_image, mem_ofPred] /-- Pull back a pseudometric space structure by an inducing map. This is a version of `PseudoMetricSpace.induced` useful in case if the domain already has a `TopologicalSpace` diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index 898ef53d034c74..a7f27cf04491d5 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -624,7 +624,7 @@ theorem forall_of_forall_mem_ball (p : α → Prop) (x : α) theorem isBounded_iff {s : Set α} : IsBounded s ↔ ∃ C : ℝ, ∀ ⦃x⦄, x ∈ s → ∀ ⦃y⦄, y ∈ s → dist x y ≤ C := by - rw [isBounded_def, ← Filter.mem_sets, @PseudoMetricSpace.cobounded_sets α, mem_setOf_eq, + rw [isBounded_def, ← Filter.mem_sets, @PseudoMetricSpace.cobounded_sets α, mem_ofPred_eq, compl_compl] lemma boundedSpace_iff : BoundedSpace α ↔ ∃ C, ∀ a b : α, dist a b ≤ C := by @@ -722,7 +722,7 @@ protected theorem mk_uniformity_basis_le {β : Type*} {p : β → Prop} {f : β rcases exists_between ε₀ with ⟨ε', hε'⟩ rcases hf ε' hε'.1 with ⟨i, hi, H⟩ exact ⟨i, hi, fun x (hx : _ ≤ _) => hε <| lt_of_le_of_lt (le_trans hx H) hε'.2⟩ - · exact fun ⟨i, hi, H⟩ => ⟨f i, hf₀ i hi, fun x (hx : _ < _) => H (mem_setOf.2 hx.le)⟩ + · exact fun ⟨i, hi, H⟩ => ⟨f i, hf₀ i hi, fun x (hx : _ < _) => H (mem_ofPred.2 hx.le)⟩ /-- Constant size closed neighborhoods of the diagonal form a basis of the uniformity filter. -/ @@ -939,7 +939,7 @@ iff the distances between distinct points are uniformly bounded away from zero. protected lemma uniformSpace_eq_bot : ‹PseudoMetricSpace α›.toUniformSpace = ⊥ ↔ ∃ r : ℝ, 0 < r ∧ Pairwise (r ≤ dist · · : α → α → Prop) := by - simp only [uniformity_basis_dist.uniformSpace_eq_bot, mem_setOf_eq, not_lt] + simp only [uniformity_basis_dist.uniformSpace_eq_bot, mem_ofPred_eq, not_lt] end Metric @@ -1105,7 +1105,7 @@ abbrev PseudoMetricSpace.replaceBornology {α} [B : Bornology α] (m : PseudoMet { m with toBornology := B cobounded_sets := Set.ext <| compl_surjective.forall.2 fun s => - (H s).trans <| by rw [isBounded_iff, mem_setOf_eq, compl_compl] } + (H s).trans <| by rw [isBounded_iff, mem_ofPred_eq, compl_compl] } theorem PseudoMetricSpace.replaceBornology_eq {α} [m : PseudoMetricSpace α] [B : Bornology α] (H : ∀ s, @IsBounded _ B s ↔ @IsBounded _ PseudoMetricSpace.toBornology s) : diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean b/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean index b904383d0ca551..bd5e7cc7d38204 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean @@ -119,7 +119,7 @@ end Metric theorem lebesgue_number_lemma_of_metric {s : Set α} {ι : Sort*} {c : ι → Set α} (hs : IsCompact s) (hc₁ : ∀ i, IsOpen (c i)) (hc₂ : s ⊆ ⋃ i, c i) : ∃ δ > 0, ∀ x ∈ s, ∃ i, ball x δ ⊆ c i := by - simpa only [ball, UniformSpace.ball, preimage_setOf_eq, dist_comm] + simpa only [ball, UniformSpace.ball, preimage_ofPred_eq, dist_comm] using uniformity_basis_dist.lebesgue_number_lemma hs hc₁ hc₂ theorem lebesgue_number_lemma_of_metric_sUnion {s : Set α} {c : Set (Set α)} (hs : IsCompact s) diff --git a/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean b/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean index 42a398918befbb..de806dfeab2a6e 100644 --- a/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean +++ b/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean @@ -85,7 +85,7 @@ theorem thickenedIndicatorAux_one_of_mem_closure (δ : ℝ) (E : Set α) {x : α theorem thickenedIndicatorAux_zero {δ : ℝ} (δ_pos : 0 < δ) (E : Set α) {x : α} (x_out : x ∉ thickening δ E) : thickenedIndicatorAux δ E x = 0 := by - rw [thickening, mem_setOf_eq, not_lt] at x_out + rw [thickening, mem_ofPred_eq, not_lt] at x_out unfold thickenedIndicatorAux apply le_antisymm _ bot_le have key := tsub_le_tsub @@ -148,7 +148,7 @@ theorem thickenedIndicatorAux_tendsto_indicator_closure {δseq : ℕ → ℝ} rcases δseq_lim with ⟨N, hN⟩ apply tendsto_atTop_of_eventually_const (i₀ := N) intro n n_large - have key : x ∉ thickening ε E := by simpa only [thickening, mem_setOf_eq, not_lt] using ε_lt.le + have key : x ∉ thickening ε E := by simpa only [thickening, mem_ofPred_eq, not_lt] using ε_lt.le refine le_antisymm ?_ bot_le apply (thickenedIndicatorAux_mono (lt_of_abs_lt (hN n n_large)).le E x).trans exact (thickenedIndicatorAux_zero ε_pos E key).le diff --git a/Mathlib/Topology/MetricSpace/Thickening.lean b/Mathlib/Topology/MetricSpace/Thickening.lean index 943fff19de448d..6718f1919ccf03 100644 --- a/Mathlib/Topology/MetricSpace/Thickening.lean +++ b/Mathlib/Topology/MetricSpace/Thickening.lean @@ -63,7 +63,7 @@ lemma eventually_notMem_thickening_of_infEDist_pos {E : Set α} {x : α} (h : x ∀ᶠ δ in 𝓝 (0 : ℝ), x ∉ Metric.thickening δ E := by obtain ⟨ε, ⟨ε_pos, ε_lt⟩⟩ := exists_real_pos_lt_infEDist_of_notMem_closure h filter_upwards [eventually_lt_nhds ε_pos] with δ hδ - simp only [thickening, mem_setOf_eq, not_lt] + simp only [thickening, mem_ofPred_eq, not_lt] exact (ENNReal.ofReal_le_ofReal hδ.le).trans ε_lt.le @[deprecated (since := "2026-01-08")] @@ -85,7 +85,7 @@ theorem isOpen_thickening {δ : ℝ} {E : Set α} : IsOpen (thickening δ E) := /-- The (open) thickening of the empty set is empty. -/ @[simp] theorem thickening_empty (δ : ℝ) : thickening δ (∅ : Set α) = ∅ := by - simp only [thickening, setOf_false, infEDist_empty, not_top_lt] + simp only [thickening, ofPred_false, infEDist_empty, not_top_lt] theorem thickening_of_nonpos (hδ : δ ≤ 0) (s : Set α) : thickening δ s = ∅ := eq_empty_of_forall_notMem fun _ => ((ENNReal.ofReal_of_nonpos hδ).trans_le bot_le).not_gt @@ -128,9 +128,9 @@ theorem frontier_thickening_disjoint (A : Set α) : lemma subset_compl_thickening_compl_thickening_self (δ : ℝ) (E : Set α) : E ⊆ (thickening δ (thickening δ E)ᶜ)ᶜ := by intro x x_in_E - simp only [thickening, mem_compl_iff, mem_setOf_eq, not_lt] + simp only [thickening, mem_compl_iff, mem_ofPred_eq, not_lt] apply le_infEDist.mpr fun y hy ↦ ?_ - simp only [mem_compl_iff, mem_setOf_eq, not_lt] at hy + simp only [mem_compl_iff, mem_ofPred_eq, not_lt] at hy simpa only [edist_comm] using le_trans hy <| Metric.infEDist_le_edist_of_mem x_in_E /-- The δ-thickening of the complement of the δ-thickening of a set is contained in the complement @@ -201,7 +201,7 @@ lemma eventually_notMem_cthickening_of_infEDist_pos {E : Set α} {x : α} (h : x ∀ᶠ δ in 𝓝 (0 : ℝ), x ∉ Metric.cthickening δ E := by obtain ⟨ε, ⟨ε_pos, ε_lt⟩⟩ := exists_real_pos_lt_infEDist_of_notMem_closure h filter_upwards [eventually_lt_nhds ε_pos] with δ hδ - simp only [cthickening, mem_setOf_eq, not_le] + simp only [cthickening, mem_ofPred_eq, not_le] exact ((ofReal_lt_ofReal_iff ε_pos).mpr hδ).trans ε_lt @[deprecated (since := "2026-01-08")] @@ -232,7 +232,7 @@ theorem isClosed_cthickening {δ : ℝ} {E : Set α} : IsClosed (cthickening δ /-- The closed thickening of the empty set is empty. -/ @[simp] theorem cthickening_empty (δ : ℝ) : cthickening δ (∅ : Set α) = ∅ := by - simp only [cthickening, ENNReal.ofReal_ne_top, setOf_false, infEDist_empty, top_le_iff] + simp only [cthickening, ENNReal.ofReal_ne_top, ofPred_false, infEDist_empty, top_le_iff] theorem cthickening_of_nonpos {δ : ℝ} (hδ : δ ≤ 0) (E : Set α) : cthickening δ E = closure E := by ext x @@ -283,7 +283,7 @@ theorem cthickening_subset_thickening' {δ₁ δ₂ : ℝ} (δ₂_pos : 0 < δ `Metric.cthickening δ E` with the same radius. -/ theorem thickening_subset_cthickening (δ : ℝ) (E : Set α) : thickening δ E ⊆ cthickening δ E := by intro x hx - rw [thickening, mem_setOf_eq] at hx + rw [thickening, mem_ofPred_eq] at hx exact hx.le theorem thickening_subset_cthickening_of_le {δ₁ δ₂ : ℝ} (hle : δ₁ ≤ δ₂) (E : Set α) : @@ -339,17 +339,17 @@ theorem cthickening_mem_nhdsSet (E : Set α) {δ : ℝ} (hδ : 0 < δ) : cthicke @[simp] theorem thickening_union (δ : ℝ) (s t : Set α) : thickening δ (s ∪ t) = thickening δ s ∪ thickening δ t := by - simp_rw [thickening, infEDist_union, min_lt_iff, setOf_or] + simp_rw [thickening, infEDist_union, min_lt_iff, ofPred_or] @[simp] theorem cthickening_union (δ : ℝ) (s t : Set α) : cthickening δ (s ∪ t) = cthickening δ s ∪ cthickening δ t := by - simp_rw [cthickening, infEDist_union, min_le_iff, setOf_or] + simp_rw [cthickening, infEDist_union, min_le_iff, ofPred_or] @[simp] theorem thickening_iUnion (δ : ℝ) (f : ι → Set α) : thickening δ (⋃ i, f i) = ⋃ i, thickening δ (f i) := by - simp_rw [thickening, infEDist_iUnion, iInf_lt_iff, setOf_exists] + simp_rw [thickening, infEDist_iUnion, iInf_lt_iff, ofPred_exists] lemma thickening_biUnion {ι : Type*} (δ : ℝ) (f : ι → Set α) (I : Set ι) : thickening δ (⋃ i ∈ I, f i) = ⋃ i ∈ I, thickening δ (f i) := by simp only [thickening_iUnion] @@ -475,7 +475,7 @@ theorem cthickening_eq_iInter_cthickening' {δ : ℝ} (s : Set ℝ) (hsδ : s · exact subset_iInter₂ fun _ hε => cthickening_mono (le_of_lt (hsδ hε)) E · unfold cthickening intro x hx - simp only [mem_iInter, mem_setOf_eq] at * + simp only [mem_iInter, mem_ofPred_eq] at * apply ENNReal.le_of_forall_pos_le_add intro η η_pos _ rcases hs (δ + η) (lt_add_of_pos_right _ (NNReal.coe_pos.mpr η_pos)) with ⟨ε, ⟨hsε, hε⟩⟩ diff --git a/Mathlib/Topology/MetricSpace/UniformConvergence.lean b/Mathlib/Topology/MetricSpace/UniformConvergence.lean index c63df0f2087219..6154a61cd1f937 100644 --- a/Mathlib/Topology/MetricSpace/UniformConvergence.lean +++ b/Mathlib/Topology/MetricSpace/UniformConvergence.lean @@ -239,7 +239,7 @@ noncomputable instance : PseudoEMetricSpace (α →ᵤ[𝔖] β) where let _ := Fintype.ofFinite 𝔖; simp_rw [← isUniformInducing_pi_restrict.comap_uniformity, PseudoEMetricSpace.uniformity_edist, comap_iInf, comap_principal, edist_eq_pi_restrict, - Set.preimage_setOf_eq] + Set.preimage_ofPred_eq] lemma edist_le {f g : α →ᵤ[𝔖] β} {C : ℝ≥0∞} : edist f g ≤ C ↔ ∀ x ∈ ⋃₀ 𝔖, edist (toFun 𝔖 f x) (toFun 𝔖 g x) ≤ C := by diff --git a/Mathlib/Topology/Metrizable/Uniformity.lean b/Mathlib/Topology/Metrizable/Uniformity.lean index 2dc5b50b8e07da..4d61f3a49b1779 100644 --- a/Mathlib/Topology/Metrizable/Uniformity.lean +++ b/Mathlib/Topology/Metrizable/Uniformity.lean @@ -136,7 +136,7 @@ theorem le_two_mul_dist_ofPreNNDist (d : X → X → ℝ≥0) (dist_self : ∀ x intro m hm rw [← not_lt, Nat.lt_iff_add_one_le, ← hL_len] intro hLm - rw [mem_setOf_eq, take_of_length_le hLm, two_mul, add_le_iff_nonpos_left, nonpos_iff_eq_zero, + rw [mem_ofPred_eq, take_of_length_le hLm, two_mul, add_le_iff_nonpos_left, nonpos_iff_eq_zero, sum_eq_zero_iff, ← forall_iff_forall_mem, forall_zipWith, ← isChain_cons_append_singleton_iff_forall₂] at hm <;> @@ -236,7 +236,7 @@ protected theorem UniformSpace.metrizable_uniformity (X : Type*) [UniformSpace X · refine fun n hn => ⟨n, hn, fun x hx => (hdist_le _ _).trans_lt ?_⟩ rwa [← NNReal.coe_pow, NNReal.coe_lt_coe, ← not_le, hle_d, Classical.not_not] · refine fun n _ => ⟨n + 1, trivial, fun x hx => ?_⟩ - rw [mem_setOf_eq] at hx + rw [mem_ofPred_eq] at hx contrapose! hx refine le_trans ?_ ((div_le_iff₀' zero_lt_two).2 (hd_le x.1 x.2)) rwa [← NNReal.coe_two, ← NNReal.coe_div, ← NNReal.coe_pow, NNReal.coe_le_coe, pow_succ, diff --git a/Mathlib/Topology/Neighborhoods.lean b/Mathlib/Topology/Neighborhoods.lean index dae0480367bac9..05f67d3358d795 100644 --- a/Mathlib/Topology/Neighborhoods.lean +++ b/Mathlib/Topology/Neighborhoods.lean @@ -28,7 +28,7 @@ variable {X : Type u} [TopologicalSpace X] {ι : Sort v} {α : Type*} {x : X} {s set_option backward.isDefEq.respectTransparency false in theorem nhds_def' (x : X) : 𝓝 x = ⨅ (s : Set X) (_ : IsOpen s) (_ : x ∈ s), 𝓟 s := by - simp only [nhds_def, mem_setOf_eq, @and_comm (x ∈ _), iInf_and] + simp only [nhds_def, mem_ofPred_eq, @and_comm (x ∈ _), iInf_and] /-- The open sets containing `x` are a basis for the neighborhood filter. See `nhds_basis_opens'` for a variant using open neighborhoods instead. -/ @@ -68,7 +68,7 @@ theorem mem_nhds_iff : s ∈ 𝓝 x ↔ ∃ t ⊆ s, IsOpen t ∧ x ∈ t := containing `x`. -/ theorem eventually_nhds_iff {p : X → Prop} : (∀ᶠ y in 𝓝 x, p y) ↔ ∃ t : Set X, (∀ y ∈ t, p y) ∧ IsOpen t ∧ x ∈ t := - mem_nhds_iff.trans <| by simp only [subset_def, mem_setOf_eq] + mem_nhds_iff.trans <| by simp only [subset_def, mem_ofPred_eq] theorem frequently_nhds_iff {p : X → Prop} : (∃ᶠ y in 𝓝 x, p y) ↔ ∀ U : Set X, x ∈ U → IsOpen U → ∃ y ∈ U, p y := @@ -223,7 +223,7 @@ theorem Filter.EventuallyEq.tendsto {l : Filter α} {f : α → X} (hf : f =ᶠ[ /-! ### Interior, closure and frontier in terms of neighborhoods -/ theorem interior_eq_nhds' : interior s = { x | s ∈ 𝓝 x } := - Set.ext fun x => by simp only [mem_interior, mem_nhds_iff, mem_setOf_eq] + Set.ext fun x => by simp only [mem_interior, mem_nhds_iff, mem_ofPred_eq] theorem interior_eq_nhds : interior s = { x | 𝓝 x ≤ 𝓟 s } := interior_eq_nhds'.trans <| by simp only [le_principal_iff] @@ -233,11 +233,17 @@ theorem interior_mem_nhds : interior s ∈ 𝓝 x ↔ s ∈ 𝓝 x := ⟨fun h => mem_of_superset h interior_subset, fun h => IsOpen.mem_nhds isOpen_interior (mem_interior_iff_mem_nhds.2 h)⟩ -theorem interior_setOf_eq {p : X → Prop} : interior { x | p x } = { x | ∀ᶠ y in 𝓝 x, p y } := +theorem interior_setOfPred_eq {p : X → Prop} : interior { x | p x } = { x | ∀ᶠ y in 𝓝 x, p y } := interior_eq_nhds' -theorem isOpen_setOf_eventually_nhds {p : X → Prop} : IsOpen { x | ∀ᶠ y in 𝓝 x, p y } := by - simp only [← interior_setOf_eq, isOpen_interior] +@[deprecated (since := "2026-07-09")] +alias interior_setOf_eq := interior_setOfPred_eq + +theorem isOpen_setOfPred_eventually_nhds {p : X → Prop} : IsOpen { x | ∀ᶠ y in 𝓝 x, p y } := by + simp only [← interior_setOfPred_eq, isOpen_interior] + +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_eventually_nhds := isOpen_setOfPred_eventually_nhds theorem subset_interior_iff_nhds {V : Set X} : s ⊆ interior V ↔ ∀ x ∈ s, V ∈ 𝓝 x := by simp_rw [subset_def, mem_interior_iff_mem_nhds] @@ -245,7 +251,7 @@ theorem subset_interior_iff_nhds {V : Set X} : s ⊆ interior V ↔ ∀ x ∈ s, theorem isOpen_iff_nhds : IsOpen s ↔ ∀ x ∈ s, 𝓝 x ≤ 𝓟 s := calc IsOpen s ↔ s ⊆ interior s := subset_interior_iff_isOpen.symm - _ ↔ ∀ x ∈ s, 𝓝 x ≤ 𝓟 s := by simp_rw [interior_eq_nhds, subset_def, mem_setOf] + _ ↔ ∀ x ∈ s, 𝓝 x ≤ 𝓟 s := by simp_rw [interior_eq_nhds, subset_def, mem_ofPred] theorem TopologicalSpace.ext_iff_nhds {X} {t t' : TopologicalSpace X} : t = t' ↔ ∀ x, @nhds _ t x = @nhds _ t' x := diff --git a/Mathlib/Topology/NhdsKer.lean b/Mathlib/Topology/NhdsKer.lean index e8d5f418a6b623..8278230e1c10b3 100644 --- a/Mathlib/Topology/NhdsKer.lean +++ b/Mathlib/Topology/NhdsKer.lean @@ -29,7 +29,7 @@ lemma nhdsKer_singleton_eq_ker_nhds (x : X) : nhdsKer {x} = (𝓝 x).ker := by s @[simp] theorem mem_nhdsKer_singleton : x ∈ nhdsKer {y} ↔ x ⤳ y := by - rw [nhdsKer_singleton_eq_ker_nhds, ker_nhds_eq_specializes, mem_setOf] + rw [nhdsKer_singleton_eq_ker_nhds, ker_nhds_eq_specializes, mem_ofPred] lemma nhdsKer_def (s : Set X) : nhdsKer s = ⋂₀ {t : Set X | IsOpen t ∧ s ⊆ t} := (hasBasis_nhdsSet _).ker.trans sInter_eq_biInter.symm diff --git a/Mathlib/Topology/NhdsWithin.lean b/Mathlib/Topology/NhdsWithin.lean index 142a9861f31d87..cf2bf1be79dc2e 100644 --- a/Mathlib/Topology/NhdsWithin.lean +++ b/Mathlib/Topology/NhdsWithin.lean @@ -391,7 +391,7 @@ theorem tendsto_nhdsWithin_of_tendsto_nhds {f : α → β} {a : α} {s : Set α} theorem eventually_mem_of_tendsto_nhdsWithin {f : β → α} {a : α} {s : Set α} {l : Filter β} (h : Tendsto f l (𝓝[s] a)) : ∀ᶠ i in l, f i ∈ s := by - simp_rw [nhdsWithin_eq, tendsto_iInf, mem_setOf_eq, tendsto_principal, mem_inter_iff, + simp_rw [nhdsWithin_eq, tendsto_iInf, mem_ofPred_eq, tendsto_principal, mem_inter_iff, eventually_and] at h exact (h univ ⟨mem_univ a, isOpen_univ⟩).2 diff --git a/Mathlib/Topology/Order.lean b/Mathlib/Topology/Order.lean index ee4c945924cef4..4476de9fddcb5c 100644 --- a/Mathlib/Topology/Order.lean +++ b/Mathlib/Topology/Order.lean @@ -91,7 +91,7 @@ theorem nhds_generateFrom {g : Set (Set α)} {a : α} : lemma tendsto_nhds_generateFrom_iff {β : Type*} {m : α → β} {f : Filter α} {g : Set (Set β)} {b : β} : Tendsto m f (@nhds β (generateFrom g) b) ↔ ∀ s ∈ g, b ∈ s → m ⁻¹' s ∈ f := by - simp only [nhds_generateFrom, @forall_comm (b ∈ _), tendsto_iInf, mem_setOf_eq, and_imp, + simp only [nhds_generateFrom, @forall_comm (b ∈ _), tendsto_iInf, mem_ofPred_eq, and_imp, tendsto_principal]; rfl /-- Construct a topology on α given the filter of neighborhoods of each point of α. -/ @@ -197,10 +197,13 @@ theorem generateFrom_anti {α} {g₁ g₂ : Set (Set α)} (h : g₁ ⊆ g₂) : generateFrom g₂ ≤ generateFrom g₁ := (gc_generateFrom _).monotone_u h -theorem generateFrom_setOf_isOpen (t : TopologicalSpace α) : +theorem generateFrom_setOfPred_isOpen (t : TopologicalSpace α) : generateFrom { s | IsOpen[t] s } = t := (gciGenerateFrom α).u_l_eq t +@[deprecated (since := "2026-07-09")] +alias generateFrom_setOf_isOpen := generateFrom_setOfPred_isOpen + theorem leftInverse_generateFrom : LeftInverse generateFrom fun t : TopologicalSpace α => { s | IsOpen[t] s } := (gciGenerateFrom α).leftInverse_u_l @@ -208,9 +211,11 @@ theorem leftInverse_generateFrom : theorem generateFrom_surjective : Surjective (generateFrom : Set (Set α) → TopologicalSpace α) := (gciGenerateFrom α).u_surjective -theorem setOf_isOpen_injective : Injective fun t : TopologicalSpace α => { s | IsOpen[t] s } := +theorem setOfPred_isOpen_injective : Injective fun t : TopologicalSpace α => { s | IsOpen[t] s } := (gciGenerateFrom α).l_injective +@[deprecated (since := "2026-07-09")] alias setOf_isOpen_injective := setOfPred_isOpen_injective + end Lattice end TopologicalSpace @@ -779,7 +784,7 @@ theorem continuous_iff_le_induced {t₁ : TopologicalSpace α} {t₂ : Topologic lemma continuous_generateFrom_iff {t : TopologicalSpace α} {b : Set (Set β)} : Continuous[t, generateFrom b] f ↔ ∀ s ∈ b, IsOpen (f ⁻¹' s) := by rw [continuous_iff_coinduced_le, le_generateFrom_iff_subset_isOpen] - simp only [isOpen_coinduced, subset_def, mem_setOf_eq] + simp only [isOpen_coinduced, subset_def, mem_ofPred_eq] @[continuity, fun_prop] theorem continuous_induced_dom {t : TopologicalSpace β} : Continuous[induced f t, t] f := @@ -991,26 +996,32 @@ theorem generateFrom_union (a₁ a₂ : Set (Set α)) : generateFrom (a₁ ∪ a₂) = generateFrom a₁ ⊓ generateFrom a₂ := (gc_generateFrom α).u_inf -theorem setOf_isOpen_sup (t₁ t₂ : TopologicalSpace α) : +theorem setOfPred_isOpen_sup (t₁ t₂ : TopologicalSpace α) : { s | IsOpen[t₁ ⊔ t₂] s } = { s | IsOpen[t₁] s } ∩ { s | IsOpen[t₂] s } := rfl +@[deprecated (since := "2026-07-09")] alias setOf_isOpen_sup := setOfPred_isOpen_sup + theorem generateFrom_iUnion {f : ι → Set (Set α)} : generateFrom (⋃ i, f i) = ⨅ i, generateFrom (f i) := (gc_generateFrom α).u_iInf -theorem setOf_isOpen_iSup {t : ι → TopologicalSpace α} : +theorem setOfPred_isOpen_iSup {t : ι → TopologicalSpace α} : { s | IsOpen[⨆ i, t i] s } = ⋂ i, { s | IsOpen[t i] s } := (gc_generateFrom α).l_iSup +@[deprecated (since := "2026-07-09")] alias setOf_isOpen_iSup := setOfPred_isOpen_iSup + theorem generateFrom_sUnion {S : Set (Set (Set α))} : generateFrom (⋃₀ S) = ⨅ s ∈ S, generateFrom s := (gc_generateFrom α).u_sInf -theorem setOf_isOpen_sSup {T : Set (TopologicalSpace α)} : +theorem setOfPred_isOpen_sSup {T : Set (TopologicalSpace α)} : { s | IsOpen[sSup T] s } = ⋂ t ∈ T, { s | IsOpen[t] s } := (gc_generateFrom α).l_sSup +@[deprecated (since := "2026-07-09")] alias setOf_isOpen_sSup := setOfPred_isOpen_sSup + theorem generateFrom_union_isOpen (a b : TopologicalSpace α) : generateFrom ({ s | IsOpen[a] s } ∪ { s | IsOpen[b] s }) = a ⊓ b := (gciGenerateFrom α).u_inf_l _ _ @@ -1036,7 +1047,7 @@ variable {t : ι → TopologicalSpace α} theorem isOpen_iSup_iff {s : Set α} : IsOpen[⨆ i, t i] s ↔ ∀ i, IsOpen[t i] s := show s ∈ {s | IsOpen[iSup t] s} ↔ s ∈ { x : Set α | ∀ i : ι, IsOpen[t i] x } by - simp [setOf_isOpen_iSup] + simp [setOfPred_isOpen_iSup] theorem isOpen_sSup_iff {s : Set α} {T : Set (TopologicalSpace α)} : IsOpen[sSup T] s ↔ ∀ t ∈ T, IsOpen[t] s := by diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index 71aae750687376..da0e355670a44f 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -129,7 +129,7 @@ theorem le_mem_nhds [OrderTopology α] {a b : α} (h : a < b) : ∀ᶠ x in 𝓝 theorem nhds_eq_order [OrderTopology α] (a : α) : 𝓝 a = (⨅ b ∈ Iio a, 𝓟 (Ioi b)) ⊓ ⨅ b ∈ Ioi a, 𝓟 (Iio b) := by rw [OrderTopology.topology_eq_generate_intervals (α := α), nhds_generateFrom] - simp_rw [mem_setOf_eq, @and_comm (a ∈ _), exists_or, or_and_right, iInf_or, iInf_and, + simp_rw [mem_ofPred_eq, @and_comm (a ∈ _), exists_or, or_and_right, iInf_or, iInf_and, iInf_exists, iInf_inf_eq, iInf_comm (ι := Set α), iInf_iInf_eq_left, mem_Ioi, mem_Iio] @[to_dual none] @@ -169,7 +169,7 @@ lemma exists_countable_generateFrom_Ioi_Iio refine ⟨a '' t, t_count.image _, ?_⟩ apply le_antisymm · apply le_generateFrom_iff_subset_isOpen.2 - simp only [mem_image, exists_exists_and_eq_and, setOf_subset_setOf, forall_exists_index, + simp only [mem_image, exists_exists_and_eq_and, ofPred_subset_ofPred, forall_exists_index, and_imp] grind [isOpen_Iio', isOpen_Ioi'] · rw [ht] @@ -192,7 +192,7 @@ lemma isTopologicalBasis_biInter_Ioi_Iio_of_generateFrom (c : Set α) · apply hg_fin.isOpen_biInter (fun i hi ↦ ?_) rw [h] exact isOpen_generateFrom_of_mem ⟨i, hgc hi, Or.inr rfl⟩ - simp only [exists_and_left, image_subset_iff, preimage_setOf_eq, setOf_subset_setOf, and_imp] + simp only [exists_and_left, image_subset_iff, preimage_ofPred_eq, ofPred_subset_ofPred, and_imp] intro k k_fin hk let kl := {s ∈ k | ∃ a ∈ c, s = Ioi a} let kr := {s ∈ k | ∃ a ∈ c, s = Iio a} @@ -562,10 +562,10 @@ theorem SecondCountableTopology.of_separableSpace_orderTopology [DenselyOrdered /-- The set of points which are isolated on the right is countable when the space is second-countable. -/ -@[to_dual countable_setOf_covBy_left +@[to_dual countable_setOfPred_covBy_left /-- The set of points which are isolated on the left is countable when the space is second-countable. -/] -theorem countable_setOf_covBy_right [SecondCountableTopology α] : +theorem countable_setOfPred_covBy_right [SecondCountableTopology α] : Set.Countable { x : α | ∃ y, x ⋖ y } := by nontriviality α let s := { x : α | ∃ y, x ⋖ y } @@ -605,11 +605,17 @@ theorem countable_setOf_covBy_right [SecondCountableTopology α] : simp_rw [subset_def, mem_Ioo, mem_Ioc] exact fun u hu ↦ ⟨hu.1, Hy _ _ hx.1 hu.2⟩ +@[deprecated (since := "2026-07-09")] alias countable_setOf_covBy_right := + countable_setOfPred_covBy_right + +@[deprecated (since := "2026-07-09")] alias countable_setOf_covBy_left := + countable_setOfPred_covBy_left + /-- The set of points which are isolated on the left is countable when the space is second-countable. -/ theorem countable_of_isolated_left' [SecondCountableTopology α] : Set.Countable { x : α | ∃ y, y < x ∧ Ioo y x = ∅ } := by - simpa only [← covBy_iff_Ioo_eq] using countable_setOf_covBy_left + simpa only [← covBy_iff_Ioo_eq] using countable_setOfPred_covBy_left /-- Consider a disjoint family of intervals `(x, y)` with `x < y` in a second-countable space. Then the family is countable. @@ -622,7 +628,7 @@ theorem Set.PairwiseDisjoint.countable_of_Ioo [SecondCountableTopology α] have : (s \ { x | ∃ y, x ⋖ y }).Countable := (h.subset sdiff_subset).countable_of_isOpen (fun _ _ ↦ isOpen_Ioo) fun x hx ↦ (not_covBy_iff_exists_mem_Ioo (h' _ hx.1)).1 <| mt (Exists.intro (y x)) hx.2 - this.of_sdiff countable_setOf_covBy_right + this.of_sdiff countable_setOfPred_covBy_right /-- For a function taking values in a second countable space, the set of points `x` for which the image under `f` of `(x, ∞)` is separated above from `f x` is countable. We give @@ -703,7 +709,7 @@ instance instIsCountablyGenerated_atTop [SeparableSpace α] : · obtain ⟨s, s_count, hs⟩ := exists_countable_dense α have : atTop = generate (Ici '' s) := by refine atTop_eq_generate_of_not_bddAbove fun ⟨x, hx⟩ ↦ ?_ - simp only [eq_empty_iff_forall_notMem, IsTop, mem_setOf_eq, not_forall, not_le] at h + simp only [eq_empty_iff_forall_notMem, IsTop, mem_ofPred_eq, not_forall, not_le] at h obtain ⟨y, hy, hxy⟩ := hs.exists_mem_open isOpen_Ioi (h x) exact (hx hy).not_gt hxy rw [this] diff --git a/Mathlib/Topology/Order/Category/FrameAdjunction.lean b/Mathlib/Topology/Order/Category/FrameAdjunction.lean index 58466076192101..bca85b7a868217 100644 --- a/Mathlib/Topology/Order/Category/FrameAdjunction.lean +++ b/Mathlib/Topology/Order/Category/FrameAdjunction.lean @@ -59,7 +59,7 @@ points of `L`. -/ @[simps] def openOfElementHom : FrameHom L (Set (PT L)) where toFun u := {x | x u} - map_inf' a b := by simp [Set.setOf_and] + map_inf' a b := by simp [Set.ofPred_and] map_top' := by simp map_sSup' S := by ext; simp [Prop.exists_iff] @@ -73,7 +73,7 @@ instance instTopologicalSpace : TopologicalSpace (PT L) where isOpen_sUnion S hS := by choose f hf using hS use ⨆ t, ⨆ ht, f t ht - simp_rw [map_iSup, iSup_Prop_eq, setOf_exists, hf, sUnion_eq_biUnion] + simp_rw [map_iSup, iSup_Prop_eq, ofPred_exists, hf, sUnion_eq_biUnion] /-- Characterization of when a subset of the space of points is open. -/ lemma isOpen_iff (U : Set (PT L)) : IsOpen U ↔ ∃ u : L, {x | x u} = U := Iff.rfl diff --git a/Mathlib/Topology/Order/CountableSeparating.lean b/Mathlib/Topology/Order/CountableSeparating.lean index ac0d56692ea459..0f40972928b231 100644 --- a/Mathlib/Topology/Order/CountableSeparating.lean +++ b/Mathlib/Topology/Order/CountableSeparating.lean @@ -33,7 +33,7 @@ instance range_Iio : HasCountableSeparatingOn X (· ∈ range Iio) s := by rcases TopologicalSpace.exists_countable_dense X with ⟨s, hsc, hsd⟩ set t := s ∪ {x | ∃ y, y ⋖ x} refine ⟨Iio '' t, .image ?_ _, ?_, ?_⟩ - · exact hsc.union countable_setOf_covBy_left + · exact hsc.union countable_setOfPred_covBy_left · exact image_subset_range _ _ · rintro x - y - h by_contra! hne diff --git a/Mathlib/Topology/Order/HullKernel.lean b/Mathlib/Topology/Order/HullKernel.lean index 86854af2cedea0..14b525b1637247 100644 --- a/Mathlib/Topology/Order/HullKernel.lean +++ b/Mathlib/Topology/Order/HullKernel.lean @@ -113,7 +113,7 @@ lemma isTopologicalBasis_relativeLower (hT : ∀ p ∈ T, InfPrime p) : IsTopologicalBasis { S : Set T | ∃ (a : α), (hull T a)ᶜ = S } := by convert! isTopologicalBasis_subtype Topology.IsLower.isTopologicalBasis (· ∈ T) ext R - simp only [preimage_compl, mem_setOf_eq, IsLower.lowerBasis, mem_image, exists_exists_and_eq_and] + simp only [preimage_compl, mem_ofPred_eq, IsLower.lowerBasis, mem_image, exists_exists_and_eq_and] constructor <;> intro ha · obtain ⟨a, ha'⟩ := ha use {a} diff --git a/Mathlib/Topology/Order/IntermediateValue.lean b/Mathlib/Topology/Order/IntermediateValue.lean index 14c222e07ed536..fad1f7ddd6e2d4 100644 --- a/Mathlib/Topology/Order/IntermediateValue.lean +++ b/Mathlib/Topology/Order/IntermediateValue.lean @@ -288,7 +288,7 @@ theorem IsPreconnected.mem_intervals {s : Set α} (hs : IsPreconnected s) : `Iic`, `Iio`, or `univ`, or `∅`. The converse statement requires `α` to be densely ordered. Though one can represent `∅` as `(Inf ∅, Inf ∅)`, we include it into the list of possible cases to improve readability. -/ -theorem setOf_isPreconnected_subset_of_ordered : +theorem setOfPred_isPreconnected_subset_of_ordered : { s : Set α | IsPreconnected s } ⊆ -- bounded intervals (range (uncurry Icc) ∪ range (uncurry Ico) ∪ range (uncurry Ioc) ∪ range (uncurry Ioo)) ∪ @@ -299,6 +299,9 @@ theorem setOf_isPreconnected_subset_of_ordered : simp only [union_insert, union_singleton, mem_insert_iff, mem_union, mem_range, Prod.exists, uncurry_apply_pair, exists_apply_eq_apply, true_or, or_true, exists_apply_eq_apply2] +@[deprecated (since := "2026-07-09")] +alias setOf_isPreconnected_subset_of_ordered := setOfPred_isPreconnected_subset_of_ordered + /-! ### Intervals are connected @@ -511,19 +514,22 @@ instance (priority := 100) ordered_connected_space : PreconnectedSpace α := the set of the intervals `Icc`, `Ico`, `Ioc`, `Ioo`, `Ici`, `Ioi`, `Iic`, `Iio`, `(-∞, +∞)`, or `∅`. Though one can represent `∅` as `(sInf s, sInf s)`, we include it into the list of possible cases to improve readability. -/ -theorem setOf_isPreconnected_eq_of_ordered : +theorem setOfPred_isPreconnected_eq_of_ordered : { s : Set α | IsPreconnected s } = -- bounded intervals range (uncurry Icc) ∪ range (uncurry Ico) ∪ range (uncurry Ioc) ∪ range (uncurry Ioo) ∪ -- unbounded intervals and `univ` (range Ici ∪ range Ioi ∪ range Iic ∪ range Iio ∪ {univ, ∅}) := by - refine Subset.antisymm setOf_isPreconnected_subset_of_ordered ?_ + refine Subset.antisymm setOfPred_isPreconnected_subset_of_ordered ?_ simp only [subset_def, forall_mem_range, uncurry, or_imp, forall_and, mem_union, - mem_setOf_eq, insert_eq, mem_singleton_iff, forall_eq, forall_true_iff, and_true, + mem_ofPred_eq, insert_eq, mem_singleton_iff, forall_eq, forall_true_iff, and_true, isPreconnected_Icc, isPreconnected_Ico, isPreconnected_Ioc, isPreconnected_Ioo, isPreconnected_Ioi, isPreconnected_Iio, isPreconnected_Ici, isPreconnected_Iic, isPreconnected_univ, isPreconnected_empty] +@[deprecated (since := "2026-07-09")] +alias setOf_isPreconnected_eq_of_ordered := setOfPred_isPreconnected_eq_of_ordered + /-- This lemma characterizes when a subset `s` of a densely ordered conditionally complete linear order is totally disconnected with respect to the order topology: between any two distinct points of `s` must lie a point not in `s`. -/ diff --git a/Mathlib/Topology/Order/LeftRightLim.lean b/Mathlib/Topology/Order/LeftRightLim.lean index 0d580b39379eb8..ba70e94ddaf5bb 100644 --- a/Mathlib/Topology/Order/LeftRightLim.lean +++ b/Mathlib/Topology/Order/LeftRightLim.lean @@ -302,7 +302,7 @@ theorem le_leftLim (h : x < y) : f x ≤ leftLim f y := by rw [leftLim_eq_sSup hf] refine le_csSup ⟨f y, ?_⟩ (mem_image_of_mem _ h) simp only [upperBounds, mem_image, mem_Iio, forall_exists_index, and_imp, - forall_apply_eq_imp_iff₂, mem_setOf_eq] + forall_apply_eq_imp_iff₂, mem_ofPred_eq] intro z hz exact hf hz.le diff --git a/Mathlib/Topology/Order/LeftRightNhds.lean b/Mathlib/Topology/Order/LeftRightNhds.lean index 5767a8b5ac527d..d9f3fa22d3613b 100644 --- a/Mathlib/Topology/Order/LeftRightNhds.lean +++ b/Mathlib/Topology/Order/LeftRightNhds.lean @@ -106,22 +106,28 @@ theorem mem_nhdsGT_iff_exists_Ioo_subset [NoMaxOrder α] {a : α} {s : Set α} : /-- The set of points which are isolated on the right is countable when the space is second-countable. -/ -theorem countable_setOf_isolated_right [SecondCountableTopology α] : +theorem countable_setOfPred_isolated_right [SecondCountableTopology α] : { x : α | 𝓝[>] x = ⊥ }.Countable := by - simp only [nhdsGT_eq_bot_iff, setOf_or] - exact (subsingleton_isTop α).countable.union countable_setOf_covBy_right + simp only [nhdsGT_eq_bot_iff, ofPred_or] + exact (subsingleton_isTop α).countable.union countable_setOfPred_covBy_right + +@[deprecated (since := "2026-07-09")] +alias countable_setOf_isolated_right := countable_setOfPred_isolated_right /-- The set of points which are isolated on the left is countable when the space is second-countable. -/ -theorem countable_setOf_isolated_left [SecondCountableTopology α] : +theorem countable_setOfPred_isolated_left [SecondCountableTopology α] : { x : α | 𝓝[<] x = ⊥ }.Countable := - countable_setOf_isolated_right (α := αᵒᵈ) + countable_setOfPred_isolated_right (α := αᵒᵈ) + +@[deprecated (since := "2026-07-09")] +alias countable_setOf_isolated_left := countable_setOfPred_isolated_left /-- The set of points in a set which are isolated on the right in this set is countable when the space is second-countable. -/ -theorem countable_setOf_isolated_right_within [SecondCountableTopology α] {s : Set α} : +theorem countable_setOfPred_isolated_right_within [SecondCountableTopology α] {s : Set α} : { x ∈ s | 𝓝[s ∩ Ioi x] x = ⊥ }.Countable := by - /- This does not follow from `countable_setOf_isolated_right`, which gives the result when `s` + /- This does not follow from `countable_setOfPred_isolated_right`, which gives the result when `s` is the whole space, as one cannot use it inside the subspace since it doesn't have the order topology. Instead, we follow the main steps of its proof. -/ let t := { x ∈ s | 𝓝[s ∩ Ioi x] x = ⊥ ∧ ¬ IsTop x} @@ -135,7 +141,7 @@ theorem countable_setOf_isolated_right_within [SecondCountableTopology α] {s : simp [H, (subsingleton_isTop α).countable] have (x) (hx : x ∈ t) : ∃ y > x, s ∩ Ioo x y = ∅ := by simp only [← empty_mem_iff_bot, mem_nhdsWithin_iff_exists_mem_nhds_inter, - subset_empty_iff, IsTop, not_forall, not_le, mem_setOf_eq, t] at hx + subset_empty_iff, IsTop, not_forall, not_le, mem_ofPred_eq, t] at hx rcases hx.2.1 with ⟨u, hu, h'u⟩ obtain ⟨y, hxy, hy⟩ : ∃ y, x < y ∧ Ico x y ⊆ u := exists_Ico_subset_of_mem_nhds hu hx.2.2 refine ⟨y, hxy, ?_⟩ @@ -157,11 +163,17 @@ theorem countable_setOf_isolated_right_within [SecondCountableTopology α] {s : rw [disjoint_iff_forall_ne] exact fun u hu v hv ↦ ((hu.2.trans_le this).trans hv.1).ne +@[deprecated (since := "2026-07-09")] +alias countable_setOf_isolated_right_within := countable_setOfPred_isolated_right_within + /-- The set of points in a set which are isolated on the left in this set is countable when the space is second-countable. -/ -theorem countable_setOf_isolated_left_within [SecondCountableTopology α] {s : Set α} : +theorem countable_setOfPred_isolated_left_within [SecondCountableTopology α] {s : Set α} : { x ∈ s | 𝓝[s ∩ Iio x] x = ⊥ }.Countable := - countable_setOf_isolated_right_within (α := αᵒᵈ) + countable_setOfPred_isolated_right_within (α := αᵒᵈ) + +@[deprecated (since := "2026-07-09")] +alias countable_setOf_isolated_left_within := countable_setOfPred_isolated_left_within /-- A set is a neighborhood of `a` within `(a, +∞)` if and only if it contains an interval `(a, u]` with `a < u`. -/ @@ -357,7 +369,7 @@ variable {l : Filter β} {f g : β → α} @[to_additive] theorem nhds_eq_iInf_mabs_div (a : α) : 𝓝 a = ⨅ r > 1, 𝓟 { b | |a / b|ₘ < r } := by - simp only [nhds_eq_order, mabs_lt, setOf_and, ← inf_principal, iInf_inf_eq] + simp only [nhds_eq_order, mabs_lt, ofPred_and, ← inf_principal, iInf_inf_eq] refine (congr_arg₂ _ ?_ ?_).trans (inf_comm ..) · refine (Equiv.divLeft a).iInf_congr fun x => ?_; simp [Ioi] · refine (Equiv.divRight a).iInf_congr fun x => ?_; simp [Iio] diff --git a/Mathlib/Topology/Order/LowerUpperTopology.lean b/Mathlib/Topology/Order/LowerUpperTopology.lean index b429e624cf280c..d3336a755cc676 100644 --- a/Mathlib/Topology/Order/LowerUpperTopology.lean +++ b/Mathlib/Topology/Order/LowerUpperTopology.lean @@ -267,7 +267,7 @@ theorem isUpperSet_of_isClosed (h : IsClosed s) : IsUpperSet s := theorem tendsto_nhds_iff_not_le {β : Type*} {f : β → α} {l : Filter β} {x : α} : Filter.Tendsto f l (𝓝 x) ↔ ∀ y, ¬y ≤ x → ∀ᶠ z in l, ¬y ≤ f z := by simp +instances [topology_eq_lowerTopology, tendsto_nhds_generateFrom_iff, Filter.Eventually, Ici, - compl_setOf] + compl_ofPred] /-- The closure of a singleton `{a}` in the lower topology is the left-closed right-infinite interval @@ -363,7 +363,7 @@ lemma isTopologicalSpace_basis (U : Set α) : IsOpen U ↔ U = univ ∨ ∃ a, ( intro s hs obtain ⟨a, ha⟩ := (subset_insert_iff_of_notMem hUS).mp hS1 hs subst hS2 ha - simp_all only [compl_Ici, mem_Ici, sSup_le_iff, mem_setOf_eq, mem_Iio, not_lt] + simp_all only [compl_Ici, mem_Ici, sSup_le_iff, mem_ofPred_eq, mem_Iio, not_lt] · intro b hb rw [mem_Ici, sSup_le_iff] intro c hc @@ -554,7 +554,7 @@ instance : IsUpper Prop where congr exact le_antisymm (fun h hs => by - simp only [compl_Iic, mem_setOf_eq] + simp only [compl_Iic, mem_ofPred_eq] rw [← Ioi_True, ← Ioi_False] at hs rcases hs with (rfl | rfl) · use True diff --git a/Mathlib/Topology/Order/Monotone.lean b/Mathlib/Topology/Order/Monotone.lean index 667414ec596d7e..803e7a26eb70cf 100644 --- a/Mathlib/Topology/Order/Monotone.lean +++ b/Mathlib/Topology/Order/Monotone.lean @@ -51,7 +51,7 @@ lemma MonotoneOn.insert_of_continuousWithinAt [TopologicalSpace β] [OrderClosed /-- If a function is monotone on a set in a second countable topological space, then there are only countably many points that have several preimages. -/ -lemma MonotoneOn.countable_setOf_two_preimages [SecondCountableTopology α] +lemma MonotoneOn.countable_setOfPred_two_preimages [SecondCountableTopology α] (hf : MonotoneOn f s) : Set.Countable {c | ∃ x y, x ∈ s ∧ y ∈ s ∧ x < y ∧ f x = c ∧ f y = c} := by nontriviality α @@ -84,27 +84,39 @@ lemma MonotoneOn.countable_setOf_two_preimages [SecondCountableTopology α] rw [hfx _ hd, hfy _ hc] at this exact not_le.2 H this +@[deprecated (since := "2026-07-09")] alias MonotoneOn.countable_setOf_two_preimages := + MonotoneOn.countable_setOfPred_two_preimages + /-- If a function is monotone in a second countable topological space, then there are only countably many points that have several preimages. -/ -lemma Monotone.countable_setOf_two_preimages [SecondCountableTopology α] +lemma Monotone.countable_setOfPred_two_preimages [SecondCountableTopology α] (hf : Monotone f) : Set.Countable {c | ∃ x y, x < y ∧ f x = c ∧ f y = c} := by rw [← monotoneOn_univ] at hf - simpa using hf.countable_setOf_two_preimages + simpa using hf.countable_setOfPred_two_preimages + +@[deprecated (since := "2026-07-09")] alias Monotone.countable_setOf_two_preimages := + Monotone.countable_setOfPred_two_preimages /-- If a function is antitone on a set in a second countable topological space, then there are only countably many points that have several preimages. -/ -lemma AntitoneOn.countable_setOf_two_preimages [SecondCountableTopology α] +lemma AntitoneOn.countable_setOfPred_two_preimages [SecondCountableTopology α] (hf : AntitoneOn f s) : Set.Countable {c | ∃ x y, x ∈ s ∧ y ∈ s ∧ x < y ∧ f x = c ∧ f y = c} := - (MonotoneOn.countable_setOf_two_preimages hf.dual_right :) + (MonotoneOn.countable_setOfPred_two_preimages hf.dual_right :) + +@[deprecated (since := "2026-07-09")] alias AntitoneOn.countable_setOf_two_preimages := + AntitoneOn.countable_setOfPred_two_preimages /-- If a function is antitone in a second countable topological space, then there are only countably many points that have several preimages. -/ -lemma Antitone.countable_setOf_two_preimages [SecondCountableTopology α] +lemma Antitone.countable_setOfPred_two_preimages [SecondCountableTopology α] (hf : Antitone f) : Set.Countable {c | ∃ x y, x < y ∧ f x = c ∧ f y = c} := - (Monotone.countable_setOf_two_preimages hf.dual_right :) + (Monotone.countable_setOfPred_two_preimages hf.dual_right :) + +@[deprecated (since := "2026-07-09")] alias Antitone.countable_setOf_two_preimages := + Antitone.countable_setOfPred_two_preimages section Continuity @@ -117,7 +129,7 @@ theorem MonotoneOn.countable_not_continuousWithinAt_Ioi (hf : MonotoneOn f s) : Set.Countable {x ∈ s | ¬ContinuousWithinAt f (s ∩ Ioi x) x} := by apply (countable_image_lt_image_Ioi_within s f).mono rintro x ⟨xs, hx : ¬ContinuousWithinAt f (s ∩ Ioi x) x⟩ - dsimp only [mem_setOf_eq] + dsimp only [mem_ofPred_eq] contrapose! hx refine tendsto_order.2 ⟨fun m hm => ?_, fun u hu => ?_⟩ · filter_upwards [@self_mem_nhdsWithin _ _ x (s ∩ Ioi x)] with y hy @@ -143,7 +155,7 @@ theorem MonotoneOn.countable_not_continuousWithinAt (hf : MonotoneOn f s) : refine compl_subset_compl.1 ?_ simp only [compl_union] rintro x ⟨hx, h'x⟩ - simp only [mem_compl_iff, mem_setOf_eq, not_and, not_not] at hx h'x ⊢ + simp only [mem_compl_iff, mem_ofPred_eq, not_and, not_not] at hx h'x ⊢ intro xs exact continuousWithinAt_iff_continuous_left'_right'.2 ⟨h'x xs, hx xs⟩ diff --git a/Mathlib/Topology/Order/OrderClosed.lean b/Mathlib/Topology/Order/OrderClosed.lean index 55e9bcb6d130e9..d00a24b8265d16 100644 --- a/Mathlib/Topology/Order/OrderClosed.lean +++ b/Mathlib/Topology/Order/OrderClosed.lean @@ -661,7 +661,7 @@ theorem frontier_Iic_subset (a : α) : frontier (Iic a) ⊆ {a} := @[to_dual (reorder := f g, hf hg) frontier_gt_subset_eq] theorem frontier_lt_subset_eq (hf : Continuous f) (hg : Continuous g) : frontier { b | f b < g b } ⊆ { b | f b = g b } := by - simpa only [← not_lt, ← compl_setOf, frontier_compl, eq_comm] using frontier_le_subset_eq hg hf + simpa only [← not_lt, ← compl_ofPred, frontier_compl, eq_comm] using frontier_le_subset_eq hg hf @[to_dual none] theorem continuous_if_le [TopologicalSpace γ] [∀ x, Decidable (f x ≤ g x)] {f' g' : β → γ} @@ -755,7 +755,7 @@ instance [Preorder α] [TopologicalSpace α] [OrderClosedTopology α] [Preorder instance {ι : Type*} {α : ι → Type*} [∀ i, Preorder (α i)] [∀ i, TopologicalSpace (α i)] [∀ i, OrderClosedTopology (α i)] : OrderClosedTopology (∀ i, α i) := by constructor - simp only [Pi.le_def, setOf_forall] + simp only [Pi.le_def, ofPred_forall] exact isClosed_iInter fun i => isClosed_le (continuous_apply i).fst' (continuous_apply i).snd' instance Pi.orderClosedTopology' [Preorder β] [TopologicalSpace β] [OrderClosedTopology β] : diff --git a/Mathlib/Topology/Order/Rolle.lean b/Mathlib/Topology/Order/Rolle.lean index 80920414548d6c..a720c41bec0b9d 100644 --- a/Mathlib/Topology/Order/Rolle.lean +++ b/Mathlib/Topology/Order/Rolle.lean @@ -50,7 +50,7 @@ theorem exists_Ioo_extr_on_Icc (hab : a < b) (hfc : ContinuousOn f (Icc a b)) (h -- `f` is a constant, so we can take any point in `Ioo a b` rcases nonempty_Ioo.2 hab with ⟨c', hc'⟩ refine ⟨c', hc', Or.inl fun x hx ↦ ?_⟩ - simp only [mem_setOf_eq, this x hx, this c' (Ioo_subset_Icc_self hc'), le_rfl] + simp only [mem_ofPred_eq, this x hx, this c' (Ioo_subset_Icc_self hc'), le_rfl] · refine ⟨C, ⟨lt_of_le_of_ne Cmem.1 <| mt ?_ hC, lt_of_le_of_ne Cmem.2 <| mt ?_ hC⟩, Or.inr Cge⟩ exacts [fun h => by rw [h], fun h => by rw [h, hfI]] · refine ⟨c, ⟨lt_of_le_of_ne cmem.1 <| mt ?_ hc, lt_of_le_of_ne cmem.2 <| mt ?_ hc⟩, Or.inl cle⟩ diff --git a/Mathlib/Topology/Order/ScottTopology.lean b/Mathlib/Topology/Order/ScottTopology.lean index 14aa66e670a7ad..3b9603a850e7fe 100644 --- a/Mathlib/Topology/Order/ScottTopology.lean +++ b/Mathlib/Topology/Order/ScottTopology.lean @@ -257,7 +257,7 @@ lemma monotone_of_continuous [IsScott α D] (hf : Continuous f) : Monotone f := rw [isOpen_iff_isUpperSet_and_dirSupInaccOn (D := D)] at hu obtain ⟨c, hcd, hfcb⟩ := hu.2 h₀ d₁ d₂ d₃ h simp only [upperBounds, mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, - mem_setOf] at hb + mem_ofPred] at hb exact hfcb <| hb _ hcd end Preorder diff --git a/Mathlib/Topology/Order/WithTop.lean b/Mathlib/Topology/Order/WithTop.lean index b9eccbf949643e..51497b3cc42cfb 100644 --- a/Mathlib/Topology/Order/WithTop.lean +++ b/Mathlib/Topology/Order/WithTop.lean @@ -76,7 +76,7 @@ instance [ts : TopologicalSpace ι] [ht : OrderTopology ι] [SecondCountableTopo have h_basis : IsTopologicalBasis basis := isTopologicalBasis_biInter_Ioi_Iio_of_generateFrom c hc rw [OrderTopology.topology_eq_generate_intervals (α := WithTop ι)] apply le_generateFrom_iff_subset_isOpen.2 - simp only [setOf_subset_setOf, forall_exists_index] + simp only [ofPred_subset_ofPred, forall_exists_index] rintro u a (rfl | rfl) -- Consider an interval of the form `Ioi a`. We should cover it by finite intersections of -- our sets. @@ -233,7 +233,7 @@ set_option backward.isDefEq.respectTransparency false in lemma tendsto_untop (a : {a : WithTop ι | a ≠ ⊤}) : Tendsto (fun x ↦ untop x.1 x.2) (𝓝 a) (𝓝 (untop a.1 a.2)) := by have : Nonempty ι := ⟨untop a.1 a.2⟩ - simp only [← untopA_eq_untop, ne_eq, coe_setOf, mem_setOf_eq] + simp only [← untopA_eq_untop, ne_eq, coe_ofPred, mem_ofPred_eq] exact (tendsto_untopA a.2).comp <| tendsto_subtype_rng.mp tendsto_id @[to_dual] diff --git a/Mathlib/Topology/PartitionOfUnity.lean b/Mathlib/Topology/PartitionOfUnity.lean index 0816828b7d7e68..ee7cb47650d9cd 100644 --- a/Mathlib/Topology/PartitionOfUnity.lean +++ b/Mathlib/Topology/PartitionOfUnity.lean @@ -185,7 +185,7 @@ def finsupport : Finset ι := (ρ.locallyFinite.point_finite x₀).toFinset @[simp] theorem mem_finsupport (x₀ : X) {i} : i ∈ ρ.finsupport x₀ ↔ i ∈ support fun i ↦ ρ i x₀ := by - simp only [finsupport, mem_support, Finite.mem_toFinset, mem_setOf_eq] + simp only [finsupport, mem_support, Finite.mem_toFinset, mem_ofPred_eq] @[simp] theorem coe_finsupport (x₀ : X) : diff --git a/Mathlib/Topology/Perfect.lean b/Mathlib/Topology/Perfect.lean index 5bf5d949327568..d84276ea78e025 100644 --- a/Mathlib/Topology/Perfect.lean +++ b/Mathlib/Topology/Perfect.lean @@ -227,7 +227,7 @@ theorem exists_countable_union_perfect_of_isClosed [SecondCountableTopology α] simp only [V, iUnion_inter] apply Countable.biUnion · exact bct.mono (sep_subset _ _) - · exact sep_subset_setOf _ _ + · exact sep_subset_ofPred _ _ refine ⟨V ∩ C, D, Vct, ⟨?_, ?_⟩, ?_⟩ · refine hclosed.sdiff (isOpen_biUnion fun _ ↦ ?_) exact fun ⟨Ub, _⟩ ↦ IsTopologicalBasis.isOpen bbasis Ub diff --git a/Mathlib/Topology/Semicontinuity/Basic.lean b/Mathlib/Topology/Semicontinuity/Basic.lean index 25a093cc66f5aa..858f8f36a78929 100644 --- a/Mathlib/Topology/Semicontinuity/Basic.lean +++ b/Mathlib/Topology/Semicontinuity/Basic.lean @@ -334,7 +334,7 @@ variable [TopologicalSpace γ] [ClosedIciTopology γ] theorem lowerSemicontinuousOn_iff_isClosed_epigraph {f : α → γ} {s : Set α} (hs : IsClosed s) : LowerSemicontinuousOn f s ↔ IsClosed {p : α × γ | p.1 ∈ s ∧ f p.1 ≤ p.2} := by simp_rw [lowerSemicontinuousOn_iff, lowerSemicontinuousWithinAt_iff, - eventually_nhdsWithin_iff, ← isOpen_compl_iff, compl_setOf, isOpen_iff_eventually, mem_setOf, + eventually_nhdsWithin_iff, ← isOpen_compl_iff, compl_ofPred, isOpen_iff_eventually, mem_ofPred, not_and, not_le] constructor · intro hf ⟨x, y⟩ h diff --git a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean index a0b3a823bdedf4..b7271bbeb3fcdd 100644 --- a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean +++ b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean @@ -116,7 +116,7 @@ lemma isClosedMap_iff_upperHemicontinuous {f : α → β} : lemma lowerHemicontinuous_iff_isOpen_inter_nonempty : LowerHemicontinuous f ↔ ∀ u, IsOpen u → IsOpen {x | (f x ∩ u).Nonempty} := by simp_rw [lowerHemicontinuous_iff, lowerHemicontinuousAt_iff, isOpen_iff_mem_nhds, - forall_comm (α := α), mem_setOf, Filter.Eventually] + forall_comm (α := α), mem_ofPred, Filter.Eventually] /-- A correspondence `f : α → Set β` is lower hemicontinuous if and only if its *lower inverse* (i.e., `u : Set β ↦ (f ⁻¹' (Iic uᶜ))ᶜ`, note that `f ⁻¹' (Iic u) = {x | (f x ∩ u).Nonempty}`) @@ -341,7 +341,7 @@ The more general fact is that if `f` is upper hemicontinuous at `x₀` within `s `x₀` is a cluster point of `s ∩ {x | (f x).Nonempty}`, then `(f x₀).Nonempty`. -/ lemma UpperHemicontinuous.isClosed_domain (hf : UpperHemicontinuous f) : IsClosed {x | (f x).Nonempty} := by - simp only [← isOpen_compl_iff, compl_setOf, not_nonempty_iff_eq_empty, isOpen_iff_mem_nhds] + simp only [← isOpen_compl_iff, compl_ofPred, not_nonempty_iff_eq_empty, isOpen_iff_mem_nhds] intro x (hx : f x = ∅) simp_rw [upperHemicontinuous_iff, upperHemicontinuousAt_iff] at hf simpa [hx, empty_mem_iff_bot, nhdsSet_eq_bot_iff] using! hf x ∅ @@ -389,7 +389,7 @@ lemma UpperHemicontinuousAt.mem_of_tendsto {ι : Type*} [RegularSpace β] {x₀ exact hst.notMem_of_mem_left hyn hn apply hy.mp filter_upwards [hx (hf s hs)] with n hn hyn - simp only [← subset_interior_iff_mem_nhdsSet, preimage_setOf_eq, mem_setOf_eq] at hn + simp only [← subset_interior_iff_mem_nhdsSet, preimage_ofPred_eq, mem_ofPred_eq] at hn exact interior_subset <| hn hyn /-! ### Open lower sections -/ diff --git a/Mathlib/Topology/Semicontinuity/Lindelof.lean b/Mathlib/Topology/Semicontinuity/Lindelof.lean index 6165315e2729d1..ed6fc5f882357a 100644 --- a/Mathlib/Topology/Semicontinuity/Lindelof.lean +++ b/Mathlib/Topology/Semicontinuity/Lindelof.lean @@ -80,7 +80,7 @@ theorem exists_countable_upperSemicontinuous_isGLB {s : X → E} {𝓕 : Set (X rcases D_dense.exists_between H with ⟨d, d_mem, hd⟩ obtain ⟨f, f_mem, hf⟩ : ∃ f ∈ A d, f x < d := by have : x ∈ {y | s y < d} := hd.1 - simpa only [hA d, mem_iUnion₂, exists_prop, U, mem_setOf_eq] using this + simpa only [hA d, mem_iUnion₂, exists_prop, U, mem_ofPred_eq] using this suffices e < e by simpa exact (he (mem_image_of_mem _ (mem_iUnion₂_of_mem d_mem f_mem))).trans_lt hf |>.trans hd.2 diff --git a/Mathlib/Topology/Separation/Basic.lean b/Mathlib/Topology/Separation/Basic.lean index 2e7da648c7de89..9d1094ef15732f 100644 --- a/Mathlib/Topology/Separation/Basic.lean +++ b/Mathlib/Topology/Separation/Basic.lean @@ -379,7 +379,7 @@ lemma nhdsWithin_compl_singleton_le [T1Space X] (x y : X) : 𝓝[{x}ᶜ] x ≤ · rw [Ne.nhdsWithin_compl_singleton hy] exact nhdsWithin_le_nhds -theorem isOpen_setOf_eventually_nhdsWithin [T1Space X] {p : X → Prop} : +theorem isOpen_setOfPred_eventually_nhdsWithin [T1Space X] {p : X → Prop} : IsOpen { x | ∀ᶠ y in 𝓝[≠] x, p y } := by refine isOpen_iff_mem_nhds.mpr fun a ha => ?_ filter_upwards [eventually_nhds_nhdsWithin.mpr ha] with b hb @@ -388,6 +388,9 @@ theorem isOpen_setOf_eventually_nhdsWithin [T1Space X] {p : X → Prop} : · rw [h.symm.nhdsWithin_compl_singleton] at hb exact hb.filter_mono nhdsWithin_le_nhds +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_eventually_nhdsWithin := isOpen_setOfPred_eventually_nhdsWithin + @[simp] protected lemma Set.Finite.isClosed [T1Space X] {s : Set X} (hs : s.Finite) : IsClosed s := by rw [← biUnion_of_singleton s] @@ -944,12 +947,18 @@ theorem tendsto_nhds_unique_inseparable {f : Y → X} {l : Filter Y} {a b : X} [ (ha : Tendsto f l (𝓝 a)) (hb : Tendsto f l (𝓝 b)) : Inseparable a b := .of_nhds_neBot <| neBot_of_le <| le_inf ha hb -theorem isClosed_setOf_specializes : IsClosed { p : X × X | p.1 ⤳ p.2 } := by - simp only [← isOpen_compl_iff, compl_setOf, ← disjoint_nhds_nhds_iff_not_specializes, - isOpen_setOf_disjoint_nhds_nhds] +theorem isClosed_setOfPred_specializes : IsClosed { p : X × X | p.1 ⤳ p.2 } := by + simp only [← isOpen_compl_iff, compl_ofPred, ← disjoint_nhds_nhds_iff_not_specializes, + isOpen_setOfPred_disjoint_nhds_nhds] + +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_specializes := isClosed_setOfPred_specializes + +theorem isClosed_setOfPred_inseparable : IsClosed { p : X × X | Inseparable p.1 p.2 } := by + simp only [← specializes_iff_inseparable, isClosed_setOfPred_specializes] -theorem isClosed_setOf_inseparable : IsClosed { p : X × X | Inseparable p.1 p.2 } := by - simp only [← specializes_iff_inseparable, isClosed_setOf_specializes] +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_inseparable := isClosed_setOfPred_inseparable /-- In an R₁ space, a point belongs to the closure of a compact set `K` if and only if it is topologically inseparable from some point of `K`. -/ @@ -971,7 +980,7 @@ theorem IsCompact.closure_eq_biUnion_inseparable {K : Set X} (hK : IsCompact K) theorem IsCompact.closure_eq_biUnion_closure_singleton {K : Set X} (hK : IsCompact K) : closure K = ⋃ x ∈ K, closure {x} := by simp only [hK.closure_eq_biUnion_inseparable, ← specializes_iff_inseparable, - specializes_iff_mem_closure, setOf_mem_eq] + specializes_iff_mem_closure, ofPred_mem_eq] /-- In an R₁ space, if a compact set `K` is contained in an open set `U`, then its closure is also contained in `U`. -/ diff --git a/Mathlib/Topology/Separation/PerfectlyNormal.lean b/Mathlib/Topology/Separation/PerfectlyNormal.lean index 6e405d69ec8117..8317576c61b0e3 100644 --- a/Mathlib/Topology/Separation/PerfectlyNormal.lean +++ b/Mathlib/Topology/Separation/PerfectlyNormal.lean @@ -55,7 +55,7 @@ theorem perfectlyNormalSpace_iff_forall_isClosed_preimage_zero : · suffices ∀ n, f n x = 0 from by simp [h, this] exact fun n => hfs n hp · contrapose h - simp only [preimage, notMem_setOf_iff, ContinuousMap.coe_mk, mem_singleton_iff] + simp only [preimage, notMem_ofPred_iff, ContinuousMap.coe_mk, mem_singleton_iff] apply ne_of_gt obtain ⟨i, hi⟩ := mem_iUnion.1 <| compl_iInter _ ▸ mem_compl (hu ▸ h) calc diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index 14fb2bd7a6441c..cc3280cda6292b 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -345,7 +345,7 @@ theorem isBasis_iff_cover {B : Set (Opens α)} : · intro hB U refine ⟨{ V : Opens α | V ∈ B ∧ V ≤ U }, fun U hU => hU.left, ext ?_⟩ rw [coe_sSup, hB.open_eq_sUnion' U.isOpen] - simp_rw [sUnion_eq_biUnion, iUnion, mem_setOf_eq, iSup_and, iSup_image] + simp_rw [sUnion_eq_biUnion, iUnion, mem_ofPred_eq, iSup_and, iSup_image] rfl · intro h rw [isBasis_iff_nbhd] diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index 0e37beec6b55e1..921dec54209993 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -65,12 +65,12 @@ theorem isOpen_inter_nonempty_of_isOpen {U : Set α} (h : IsOpen U) : /-- When `Set` is equipped with the Vietoris topology, the powerset of a closed set is closed. -/ theorem _root_.IsClosed.powerset_vietoris {F : Set α} (h : IsClosed F) : IsClosed F.powerset := by - simp_rw [powerset, ← isOpen_compl_iff, compl_setOf, ← inter_compl_nonempty_iff] + simp_rw [powerset, ← isOpen_compl_iff, compl_ofPred, ← inter_compl_nonempty_iff] exact isOpen_inter_nonempty_of_isOpen h.isOpen_compl theorem isClosed_inter_nonempty_of_isClosed {F : Set α} (h : IsClosed F) : IsClosed {s | (s ∩ F).Nonempty} := by - simp_rw +singlePass [← compl_compl F, inter_compl_nonempty_iff, ← compl_setOf] + simp_rw +singlePass [← compl_compl F, inter_compl_nonempty_iff, ← compl_ofPred] exact h.isOpen_compl.powerset_vietoris.isClosed_compl theorem isClopen_singleton_empty : IsClopen {(∅ : Set α)} := by @@ -86,7 +86,7 @@ theorem isTopologicalBasis : refine isTopologicalBasis_of_subbasis rfl |>.isTopologicalBasis_of_exists_subset ?_ ?_ <;> rw [forall_mem_image] · intro u ⟨hu₁, hu₂⟩ - simp_rw [setOf_and, setOf_forall] + simp_rw [ofPred_and, ofPred_forall] exact (isOpen_sUnion hu₂).powerset_vietoris.inter <| hu₁.isOpen_biInter fun U hU => isOpen_inter_nonempty_of_isOpen (hu₂ U hU) · intro t ⟨ht₁, ht₂⟩ s hs @@ -106,7 +106,7 @@ theorem isTopologicalBasis : at hs ⊢ rw [mem_inter_iff, mem_powerset_iff, mem_iInter₂] at hs exists insert U ((U ∩ ·) '' v) - simp_rw [show ⋃₀ (insert U ((U ∩ ·) '' v)) = U by simp, mem_setOf, finite_insert, + simp_rw [show ⋃₀ (insert U ((U ∩ ·) '' v)) = U by simp, mem_ofPred, finite_insert, forall_mem_insert, forall_mem_image, ← inter_assoc, inter_eq_left.mpr hs.1] refine ⟨⟨hv₂.image _, hU, fun V hV => hU.inter (hv₁ hV)⟩, by grind, fun t ⟨htU, _, ht⟩ => ⟨htU, mem_iInter₂_of_mem ?_⟩⟩ @@ -123,7 +123,7 @@ theorem _root_.TopologicalSpace.IsTopologicalBasis.vietoris refine isTopologicalBasis.isTopologicalBasis_of_exists_subset ?_ ?_ <;> rw [forall_mem_image] · intro ⟨V, u⟩ ⟨hV, hu, huB, _⟩ - simp_rw [setOf_and, setOf_forall] + simp_rw [ofPred_and, ofPred_forall] exact hV.powerset_vietoris.inter <| hu.isOpen_biInter fun V hV => isOpen_inter_nonempty_of_isOpen <| hB.isOpen <| huB hV · intro u ⟨hu₁, hu₂⟩ s ⟨hs₁, hs₂⟩ @@ -163,8 +163,8 @@ theorem continuous_iff {f : α → Set β} : rw [continuous_generateFrom_iff] rintro _ (⟨U, hU, rfl⟩ | ⟨U, hU, rfl⟩) · exact h₁ U hU - · simp_rw [preimage_setOf_eq, ← not_disjoint_iff_nonempty_inter, ← compl_setOf, isOpen_compl_iff, - ← subset_compl_iff_disjoint_right] + · simp_rw [preimage_ofPred_eq, ← not_disjoint_iff_nonempty_inter, ← compl_ofPred, + isOpen_compl_iff, ← subset_compl_iff_disjoint_right] exact h₂ Uᶜ hU.isClosed_compl @[fun_prop] @@ -172,8 +172,8 @@ theorem isEmbedding_singleton : IsEmbedding ({·} : α → Set α) where injective := Set.singleton_injective eq_induced := by simp_rw [TopologicalSpace.vietoris, induced_generateFrom_eq, image_union, image_image, - powerset, preimage_setOf_eq, singleton_subset_iff, singleton_inter_nonempty, union_self, - setOf_mem_eq, image_id', generateFrom_setOf_isOpen] + powerset, preimage_ofPred_eq, singleton_subset_iff, singleton_inter_nonempty, union_self, + ofPred_mem_eq, image_id', generateFrom_setOfPred_isOpen] @[fun_prop] theorem continuous_singleton : Continuous ({·} : α → Set α) := @@ -194,7 +194,7 @@ theorem _root_.TopologicalSpace.isClosed_range_singleton [T2Space α] {t : Topol obtain ⟨U, V, hU, hV, hxU, hyV, hUV⟩ := t2_separation hxy filter_upwards [(h₂ hU).inter (h₂ hV) |>.mem_nhds ⟨⟨x, hx, hxU⟩, ⟨y, hy, hyV⟩⟩] rintro _ ⟨hzU, hzV⟩ ⟨z, rfl⟩ - rw [Set.mem_setOf, Set.singleton_inter_nonempty] at hzU hzV + rw [Set.mem_ofPred, Set.singleton_inter_nonempty] at hzU hzV exact hUV.notMem_of_mem_left hzU hzV @[fun_prop] @@ -206,7 +206,7 @@ theorem isClosedEmbedding_singleton [T2Space α] : @[fun_prop] theorem continuous_union : Continuous (fun x : Set α × Set α => x.1 ∪ x.2) := by - simp_rw [continuous_iff, powerset, preimage_setOf_eq, union_subset_iff, setOf_and] + simp_rw [continuous_iff, powerset, preimage_ofPred_eq, union_subset_iff, ofPred_and] exact ⟨ fun U hU => .inter (hU.powerset_vietoris.preimage continuous_fst) @@ -218,7 +218,7 @@ theorem continuous_union : Continuous (fun x : Set α × Set α => x.1 ∪ x.2) @[fun_prop] theorem continuous_range_of_finite {ι : Type*} [Finite ι] : Continuous (range : (ι → α) → Set α) := by - simp_rw [continuous_iff, powerset, preimage_setOf_eq, range_subset_iff, setOf_forall] + simp_rw [continuous_iff, powerset, preimage_ofPred_eq, range_subset_iff, ofPred_forall] exact ⟨ fun U hU => isOpen_iInter_of_finite fun i => hU.preimage <| continuous_apply i, fun F hF => isClosed_iInter fun i => hF.preimage <| continuous_apply i⟩ @@ -227,7 +227,7 @@ theorem continuous_range_of_finite {ι : Type*} [Finite ι] : continuous. -/ @[fun_prop] theorem _root_.Continuous.image_vietoris (hf : Continuous f) : Continuous (f '' ·) := by - simp_rw [continuous_iff, powerset, preimage_setOf_eq, image_subset_iff] + simp_rw [continuous_iff, powerset, preimage_ofPred_eq, image_subset_iff] constructor <;> exact fun U hU => (hU.preimage hf).powerset_vietoris /-- When `Set` is equipped with the Vietoris topology, taking the image under an inducing map is @@ -238,7 +238,7 @@ theorem _root_.Topology.IsInducing.image_vietoris (hf : IsInducing f) : IsInduci have : {U : Set α | IsOpen U} = (f ⁻¹' ·) '' {V : Set β | IsOpen V} := Set.ext fun _ => hf.isOpen_iff simp_rw [TopologicalSpace.vietoris, this, induced_generateFrom_eq, image_union, image_image, - powerset, preimage_setOf_eq, image_subset_iff, image_inter_nonempty_iff] + powerset, preimage_ofPred_eq, image_subset_iff, image_inter_nonempty_iff] /-- When `Set` is equipped with the Vietoris topology, taking the image under an embedding is an embedding. -/ @@ -264,7 +264,7 @@ private theorem isCompact_aux {K : Set α} (hK : IsCompact K) rw [sUnion_eq_biUnion] at hLu obtain ⟨T, hTS, hT, hLT⟩ := (hs L hL).elim_finite_subcover_image (fun _ h => h.1) hLu refine ⟨(fun U => {s | (s ∩ U).Nonempty}) '' T, by grind [image_subset_iff], hT.image _, ?_⟩ - simp_rw [sUnion_image, ← setOf_exists, ← nonempty_iUnion, ← inter_iUnion] + simp_rw [sUnion_image, ← ofPred_exists, ← nonempty_iUnion, ← inter_iUnion] grw [← hLT] grind · -- Otherwise, the set `K \ ⋃ Uⱼ` intersects every `Lᵢ`, so it is in one of the covering sets. @@ -357,19 +357,19 @@ theorem isOpen_inter_nonempty_of_isOpen {U : Set α} (h : IsOpen U) : theorem isClosed_subsets_of_isClosed {F : Set α} (h : IsClosed F) : IsClosed {K : Compacts α | ↑K ⊆ F} := by - simp_rw [← isOpen_compl_iff, Set.compl_setOf, ← Set.inter_compl_nonempty_iff] + simp_rw [← isOpen_compl_iff, Set.compl_ofPred, ← Set.inter_compl_nonempty_iff] exact isOpen_inter_nonempty_of_isOpen h.isOpen_compl theorem isClosed_inter_nonempty_of_isClosed {F : Set α} (h : IsClosed F) : IsClosed {K : Compacts α | (↑K ∩ F).Nonempty} := by - simp_rw +singlePass [← compl_compl F, Set.inter_compl_nonempty_iff, ← Set.compl_setOf] + simp_rw +singlePass [← compl_compl F, Set.inter_compl_nonempty_iff, ← Set.compl_ofPred] exact (isOpen_subsets_of_isOpen h.isOpen_compl).isClosed_compl theorem isClopen_singleton_bot : IsClopen {(⊥ : Compacts α)} := by convert! vietoris.isClopen_singleton_empty.preimage continuous_coe rw [← coe_bot, ← image_singleton (f := SetLike.coe), SetLike.coe_injective.preimage_image] -theorem isOpen_setOf_disjoint_coe [T2Space α] : +theorem isOpen_setOfPred_disjoint_coe [T2Space α] : IsOpen {p : Compacts α × Compacts α | Disjoint (p.1 : Set α) p.2} := by rw [isOpen_iff_forall_mem_open] intro ⟨K, L⟩ hKL @@ -378,9 +378,15 @@ theorem isOpen_setOf_disjoint_coe [T2Space α] : exact ⟨{K' : Compacts α | ↑K' ⊆ U} ×ˢ {L' : Compacts α | ↑L' ⊆ V}, by grind, (isOpen_subsets_of_isOpen hU).prod (isOpen_subsets_of_isOpen hV), hKU, hLV⟩ -theorem isOpen_setOf_disjoint [T2Space α] : +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_disjoint_coe := isOpen_setOfPred_disjoint_coe + +theorem isOpen_setOfPred_disjoint [T2Space α] : IsOpen {p : Compacts α × Compacts α | Disjoint p.1 p.2} := by - simpa only [disjoint_coe_iff] using isOpen_setOf_disjoint_coe + simpa only [disjoint_coe_iff] using isOpen_setOfPred_disjoint_coe + +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_disjoint := isOpen_setOfPred_disjoint theorem closure_finite_subsets (s : Set α) : closure {K : Compacts α | (K : Set α).Finite ∧ ↑K ⊆ s} = {K : Compacts α | ↑K ⊆ closure s} := by @@ -390,9 +396,12 @@ theorem closure_finite_subsets (s : Set α) : vietoris.closure_finite_subsets] exact fun K ⟨hK, _⟩ => ⟨⟨K, hK.isCompact⟩, rfl⟩ -theorem dense_setOf_finite : Dense {K : Compacts α | (K : Set α).Finite} := by +theorem dense_setOfPred_finite : Dense {K : Compacts α | (K : Set α).Finite} := by simpa [dense_iff_closure_eq] using closure_finite_subsets univ +@[deprecated (since := "2026-07-09")] +alias dense_setOf_finite := dense_setOfPred_finite + /-- Given a basis `B` on a topological space `α`, the topology of `Compacts α` has a basis consisting of sets of the form `{K | K ⊆ U₁ ∪ … ∪ Uₙ, K ∩ U₁ ≠ ∅, …, K ∩ Uₙ ≠ ∅}`, where `U₁, …, Uₙ ∈ B`. -/ @@ -404,7 +413,7 @@ theorem _root_.TopologicalSpace.IsTopologicalBasis.compacts refine hB.vietoris.isInducing isEmbedding_coe.isInducing |>.isTopologicalBasis_of_exists_subset ?_ ?_ <;> simp_rw [forall_mem_image] · intro u ⟨hu, huB⟩ - simp_rw [setOf_and, setOf_forall] + simp_rw [ofPred_and, ofPred_forall] exact .inter (isOpen_subsets_of_isOpen <| isOpen_sUnion fun U hU => hB.isOpen <| huB hU) (hu.isOpen_biInter fun U hU => isOpen_inter_nonempty_of_isOpen <| hB.isOpen <| huB hU) @@ -472,7 +481,7 @@ theorem continuous_prod : Continuous fun p : Compacts α × Compacts β => p.1 · rw [isOpen_iff_forall_mem_open] intro ⟨K, L⟩ ⟨⟨x, y⟩, ⟨(hx : x ∈ K), (hy : y ∈ L)⟩, hxy⟩ obtain ⟨V, W, hV, hW, hxV, hyW, hVW⟩ := isOpen_prod_iff.mp hU x y hxy - grw [preimage_setOf_eq, ← hVW] + grw [preimage_ofPred_eq, ← hVW] simp_rw [Function.comp_apply, coe_prod, prod_inter_prod, prod_nonempty_iff] exact ⟨_, .rfl, (isOpen_inter_nonempty_of_isOpen hV).prod (isOpen_inter_nonempty_of_isOpen hW), @@ -518,8 +527,8 @@ instance [DiscreteTopology α] : DiscreteTopology (Compacts α) := by (isOpen_subsets_of_isOpen (isOpen_discrete (K : Set α))).inter (K.isCompact.finite_of_discrete.isOpen_biInter fun x hx => isOpen_inter_nonempty_of_isOpen (isOpen_discrete { x })) - simp_rw [← setOf_forall, inter_singleton_nonempty, ← Set.subset_def, ← setOf_and, - ← subset_antisymm_iff, SetLike.coe_set_eq, setOf_eq_eq_singleton] + simp_rw [← ofPred_forall, inter_singleton_nonempty, ← Set.subset_def, ← ofPred_and, + ← subset_antisymm_iff, SetLike.coe_set_eq, ofPred_eq_eq_singleton] @[simp] theorem discreteTopology_iff : DiscreteTopology (Compacts α) ↔ DiscreteTopology α := @@ -544,14 +553,14 @@ theorem t2Space_iff : T2Space (Compacts α) ↔ T2Space α := instance [RegularSpace α] : RegularSpace (Compacts α) := by simp_rw [regularSpace_generateFrom induced_generateFrom_eq, image_union, image_image, powerset, - preimage_setOf_eq, Filter.disjoint_iff] + preimage_ofPred_eq, Filter.disjoint_iff] rintro _ (⟨U, hU, rfl⟩ | ⟨U, hU, rfl⟩) K hK · obtain ⟨V, W, hV, hW, hKV, hUW, hVW⟩ := SeparatedNhds.of_isCompact_isClosed K.isCompact hU.isClosed_compl (disjoint_compl_right_iff_subset.mpr hK) refine ⟨{K | (↑K ∩ W).Nonempty}, ?_, {K | ↑K ⊆ V}, (isOpen_subsets_of_isOpen hV).mem_nhds_iff.mpr hKV, by grind [Set.Nonempty]⟩ - simp_rw [(isOpen_inter_nonempty_of_isOpen hW).mem_nhdsSet, compl_setOf, + simp_rw [(isOpen_inter_nonempty_of_isOpen hW).mem_nhdsSet, compl_ofPred, ← inter_compl_nonempty_iff] grw [hUW] · obtain ⟨x, hx₁, hx₂⟩ := hK @@ -559,7 +568,7 @@ instance [RegularSpace α] : RegularSpace (Compacts α) := by SeparatedNhds.of_isCompact_isClosed (isCompact_singleton (x := x)) hU.isClosed_compl (by simpa) refine ⟨{K | ↑K ⊆ W}, ?_, {K | (↑K ∩ V).Nonempty}, ?_, by grind [Set.Nonempty]⟩ - · simp_rw [(isOpen_subsets_of_isOpen hW).mem_nhdsSet, compl_setOf, not_nonempty_iff_eq_empty, + · simp_rw [(isOpen_subsets_of_isOpen hW).mem_nhdsSet, compl_ofPred, not_nonempty_iff_eq_empty, ← disjoint_iff_inter_eq_empty, ← subset_compl_iff_disjoint_right] gcongr · rw [(isOpen_inter_nonempty_of_isOpen hV).mem_nhds_iff] @@ -575,7 +584,7 @@ theorem t3Space_iff : T3Space (Compacts α) ↔ T3Space α := instance [SecondCountableTopology α] : SecondCountableTopology (Compacts α) := by obtain ⟨b, hb₁, -, hb₂⟩ := exists_countable_basis α - exact hb₂.compacts.secondCountableTopology <| (countable_setOf_finite_subset hb₁).image _ + exact hb₂.compacts.secondCountableTopology <| (countable_ofPred_finite_subset hb₁).image _ @[simp] theorem secondCountableTopology_iff : @@ -661,7 +670,7 @@ instance [LocallyCompactSpace α] : LocallyCompactSpace (Compacts α) := by instance [SeparableSpace α] : SeparableSpace (Compacts α) := by obtain ⟨s, hs₁, hs₂⟩ := exists_countable_dense α - refine ⟨_, (countable_setOf_finite_subset hs₁).preimage SetLike.coe_injective, ?_⟩ + refine ⟨_, (countable_ofPred_finite_subset hs₁).preimage SetLike.coe_injective, ?_⟩ simp [dense_iff_closure_eq, closure_finite_subsets, hs₂.closure_eq] @[simp] @@ -733,9 +742,13 @@ theorem isClosed_inter_nonempty_of_isClosed {F : Set α} (h : IsClosed F) : IsClosed {K : NonemptyCompacts α | (↑K ∩ F).Nonempty} := (vietoris.isClosed_inter_nonempty_of_isClosed h).preimage continuous_coe -theorem isOpen_setOf_disjoint_coe [T2Space α] : +theorem isOpen_setOfPred_disjoint_coe [T2Space α] : IsOpen {p : NonemptyCompacts α × NonemptyCompacts α | Disjoint (p.1 : Set α) p.2} := - Compacts.isOpen_setOf_disjoint_coe.preimage <| continuous_toCompacts.prodMap continuous_toCompacts + Compacts.isOpen_setOfPred_disjoint_coe.preimage <| + continuous_toCompacts.prodMap continuous_toCompacts + +@[deprecated (since := "2026-07-09")] +alias isOpen_setOf_disjoint_coe := isOpen_setOfPred_disjoint_coe theorem closure_finite_subsets (s : Set α) : closure {K : NonemptyCompacts α | (K : Set α).Finite ∧ ↑K ⊆ s} = @@ -743,8 +756,11 @@ theorem closure_finite_subsets (s : Set α) : simpa [isOpenEmbedding_toCompacts.isOpenMap.preimage_closure_eq_closure_preimage continuous_toCompacts] using congr(toCompacts ⁻¹' $(Compacts.closure_finite_subsets s)) -theorem dense_setOf_finite : Dense {K : NonemptyCompacts α | (K : Set α).Finite} := - Compacts.dense_setOf_finite.preimage isOpenEmbedding_toCompacts.isOpenMap +theorem dense_setOfPred_finite : Dense {K : NonemptyCompacts α | (K : Set α).Finite} := + Compacts.dense_setOfPred_finite.preimage isOpenEmbedding_toCompacts.isOpenMap + +@[deprecated (since := "2026-07-09")] +alias dense_setOf_finite := dense_setOfPred_finite /-- Given a basis `B` on a topological space `α`, the topology of `NonemptyCompacts α` has a basis consisting of sets of the form `{K | K ⊆ U₁ ∪ … ∪ Uₙ, K ∩ U₁ ≠ ∅, …, K ∩ Uₙ ≠ ∅}`, where @@ -757,7 +773,7 @@ theorem _root_.TopologicalSpace.IsTopologicalBasis.nonemptyCompacts refine hB.compacts.isInducing isEmbedding_toCompacts.isInducing |>.isTopologicalBasis_of_exists_subset ?_ ?_ <;> simp_rw [forall_mem_image] · rintro u ⟨hu, -, huB⟩ - simp_rw [setOf_and, setOf_forall] + simp_rw [ofPred_and, ofPred_forall] exact .inter (isOpen_subsets_of_isOpen <| isOpen_sUnion fun U hU => hB.isOpen <| huB hU) (hu.isOpen_biInter fun U hU => isOpen_inter_nonempty_of_isOpen <| hB.isOpen <| huB hU) diff --git a/Mathlib/Topology/Sheaves/EtaleSpace.lean b/Mathlib/Topology/Sheaves/EtaleSpace.lean index a097299154aab9..8c559b3dd6c2a7 100644 --- a/Mathlib/Topology/Sheaves/EtaleSpace.lean +++ b/Mathlib/Topology/Sheaves/EtaleSpace.lean @@ -66,7 +66,7 @@ then a neighborhood of `g` consists of germs of `s` at points `x ∈ U`. -/ protected theorem eventually_nhds (g : EtaleSpace F) {U : Opens X} (h : g.base ∈ U) (s : ToType (F.obj (op U))) (hs : F.germ U g.base h s = g.germ) : ∀ᶠ g' : EtaleSpace F in 𝓝 g, ∃ hgU : g'.base ∈ U, g'.germ = F.germ U g'.base hgU s := by - simp only [nhds_generateFrom, Filter.Eventually, mem_setOf_eq, iInf_and, iInf_exists] + simp only [nhds_generateFrom, Filter.Eventually, mem_ofPred_eq, iInf_and, iInf_exists] refine mem_iInf_of_mem _ <| mem_iInf_of_mem ?_ <| mem_iInf_of_mem U <| mem_iInf_of_mem s <| mem_iInf_of_mem rfl <| mem_principal_self _ simp [*] @@ -133,9 +133,9 @@ noncomputable def homeomorph (U : Opens X) simp_rw [continuous_iff_continuousAt, continuousAt_prod_of_discrete_right] rintro ⟨y, ⟨g⟩⟩ simp only [ContinuousAt, nhds_subtype_eq_comap, tendsto_comap_iff, comp_def, - nhds_generateFrom, tendsto_iInf, mem_setOf_eq, tendsto_principal] + nhds_generateFrom, tendsto_iInf, mem_ofPred_eq, tendsto_principal] rintro _ ⟨hmem, V, f, rfl⟩ - simp only [mem_setOf_eq] at hmem + simp only [mem_ofPred_eq] at hmem rcases hmem with ⟨hyV, hgf⟩ rcases F.germ_eq _ _ _ _ _ hgf with ⟨W, hyW, ιWU, ιWV, hW⟩ filter_upwards [W.isOpen.preimage continuous_subtype_val |>.mem_nhds hyW] with z hz diff --git a/Mathlib/Topology/Sion.lean b/Mathlib/Topology/Sion.lean index 91e3dceffe7134..c287bc2c4b8219 100644 --- a/Mathlib/Topology/Sion.lean +++ b/Mathlib/Topology/Sion.lean @@ -175,26 +175,29 @@ variable [TopologicalSpace F] [AddCommGroup F] [Module ℝ F] variable (X Y f) in /-- The set of parameters `z` in the segment `[y, y']` such that `f b z ≤ f b' y`. -/ -def setOf_sublevelLeft_subset (b b' : β) (y y' : Y) : Set (segment ℝ y.val y'.val) := +def setOfPred_sublevelLeft_subset (b b' : β) (y y' : Y) : Set (segment ℝ y.val y'.val) := {z | sublevelLeft X f b z ⊆ sublevelLeft X f b' y} +@[deprecated (since := "2026-07-09")] +alias setOf_sublevelLeft_subset := setOfPred_sublevelLeft_subset + include ne_X kX hfx hfx' cY hfy hfy' in -/-- Under suitable inequalities, `setOf_sublevelLeft_subset` is closed -/ -theorem isClosed_setOf_sublevelLeft_subset +/-- Under suitable inequalities, `setOfPred_sublevelLeft_subset` is closed -/ +theorem isClosed_setOfPred_sublevelLeft_subset (a : E) (b b' : β) (y y' : Y) (ha : ∀ x ∈ X, f a y ⊔ f a y' ≤ f x y ⊔ f x y') (hb : ∀ y ∈ Y, ∃ x ∈ X, f x y ≤ b) (hb' : b' < f a y ⊔ f a y') (hbb' : b < b') : - IsClosed (setOf_sublevelLeft_subset X Y f b b' y y') := by - set J := setOf_sublevelLeft_subset X Y f b b' y y' - -- Write `J` for `setOf_sublevelLeft_subset X Y f b b' y y'`. + IsClosed (setOfPred_sublevelLeft_subset X Y f b b' y y') := by + set J := setOfPred_sublevelLeft_subset X Y f b b' y y' + -- Write `J` for `setOfPred_sublevelLeft_subset X Y f b b' y y'`. rw [isClosed_iff_clusterPt] /- Let `z in segment ℝ y y'` be a cluster point of `J`; we have to show that `z ∈ J`, i.e `sublevelLeft t z ⊆ sublevelLeft t' y1`. Let `x ∈ sublevelLeft t z` and let us prove that `x ∈ sublevelLeft X f b' y`. -/ intro z hz x hx - suffices ∃ z' ∈ setOf_sublevelLeft_subset X Y f b b' y y', x ∈ sublevelLeft X f b' (z' : F) by + suffices ∃ z' ∈ setOfPred_sublevelLeft_subset X Y f b b' y y', x ∈ sublevelLeft X f b' (z' : F) by obtain ⟨z', hz', hxz'⟩ := this /- We need to prove `x ∈ sublevelLeft X f b' y`. Assume that there is `z' ∈ J` such that `x ∈ sublevelLeft b' z'`. @@ -221,13 +224,16 @@ theorem isClosed_setOf_sublevelLeft_subset rw [clusterPt_principal_subtype_iff_frequently (cY.segment_subset y.prop y'.prop)] at hz suffices ∀ᶠ z' : F in nhdsWithin z Y, (∃ hz' : z' ∈ segment ℝ y.val y'.val, - (⟨z', hz'⟩ : segment ℝ y.val y'.val) ∈ setOf_sublevelLeft_subset X Y f b b' y y') → + (⟨z', hz'⟩ : segment ℝ y.val y'.val) ∈ setOfPred_sublevelLeft_subset X Y f b b' y y') → ∃ hz' : z' ∈ segment ℝ y.val y'.val, x ∈ sublevelLeft X f b' z' - ∧ (⟨z', hz'⟩ : segment ℝ y.val y'.val) ∈ setOf_sublevelLeft_subset X Y f b b' y y' by + ∧ (⟨z', hz'⟩ : segment ℝ y.val y'.val) ∈ setOfPred_sublevelLeft_subset X Y f b b' y y' by obtain ⟨z', hz', hxz'1, hxz'2⟩ := hz.mp this |>.exists exact ⟨⟨z', hz'⟩, ⟨hxz'2, hxz'1⟩⟩ exact hfx.mp <| .of_forall fun z hzt' ⟨hz, hz'⟩ ↦ ⟨hz, ⟨hzt'.le, hz'⟩⟩ +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_sublevelLeft_subset := isClosed_setOfPred_sublevelLeft_subset + variable [DenselyOrdered β] variable [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] @@ -241,15 +247,15 @@ public theorem exists_lt_iInf_of_lt_iInf_of_sup obtain ⟨t', htt', ht'⟩ := exists_between (ht a ha) lift y1 to Y using hy1 lift y2 to Y using hy2 - let J1 := setOf_sublevelLeft_subset X Y f t t' y1 y2 + let J1 := setOfPred_sublevelLeft_subset X Y f t t' y1 y2 have mem_J1_iff (z : segment ℝ (y1 : F) y2) : z ∈ J1 ↔ sublevelLeft X f t z ⊆ sublevelLeft X f t' y1 := by - simp [J1, setOf_sublevelLeft_subset] + simp [J1, setOfPred_sublevelLeft_subset] let φ : segment ℝ (y1 : F) y2 ≃ₜ segment ℝ (y2 : F) y1 := .setCongr (segment_symm ℝ (y1 : F) y2) - let J2 := φ ⁻¹' (setOf_sublevelLeft_subset X Y f t t' y2 y1) + let J2 := φ ⁻¹' (setOfPred_sublevelLeft_subset X Y f t t' y2 y1) have mem_J2_iff (z : segment ℝ (y1 : F) y2) : z ∈ J2 ↔ sublevelLeft X f t z ⊆ sublevelLeft X f t' y2 := by - simp [J2, setOf_sublevelLeft_subset, φ, Homeomorph.setCongr] + simp [J2, setOfPred_sublevelLeft_subset, φ, Homeomorph.setCongr] have h_mem_Y (z : segment ℝ (y1 : F) y2) : (z : F) ∈ Y := cY.segment_subset y1.2 y2.2 z.prop have hJ1J2 : J1 ∩ J2 = ∅ := by rw [Set.eq_empty_iff_forall_notMem] @@ -268,11 +274,11 @@ public theorem exists_lt_iInf_of_lt_iInf_of_sup have : IsPreconnected (Set.univ : Set (segment ℝ (y1 : F) y2)) := by simpa [← Topology.IsInducing.subtypeVal.isPreconnected_image] using (convex_segment (y1 : F) y2).isPreconnected - have hJ1 : IsClosed J1 := isClosed_setOf_sublevelLeft_subset ne_X kX hfy hfy' + have hJ1 : IsClosed J1 := isClosed_setOfPred_sublevelLeft_subset ne_X kX hfy hfy' cY hfx hfx' a t t' y1 y2 ha' hinfi_le ht' htt' have hJ2 : IsClosed J2 := by simp only [sup_comm (f _ y1)] at ha' ht' - simpa [J2, sup_comm] using isClosed_setOf_sublevelLeft_subset ne_X kX hfy hfy' + simpa [J2, sup_comm] using isClosed_setOfPred_sublevelLeft_subset ne_X kX hfy hfy' cY hfx hfx' a t t' y2 y1 ha' hinfi_le ht' htt' have h_univ : univ ⊆ J1 ∪ J2 := image_subset_image_iff Subtype.val_injective |>.mp <| by simp [hJ1_union_J2] @@ -353,12 +359,12 @@ public theorem minimax rcases eq_empty_or_nonempty Y with ⟨rfl⟩ | ne_Y · -- the case when `Y` is empty is trivial simp only [mem_empty_iff_false, IsEmpty.forall_iff, implies_true, false_and, exists_const, - setOf_false, isLUB_empty_iff] at * + ofPred_false, isLUB_empty_iff] at * replace hsup_y : ∀ x ∈ X, sup_y x = sup_inf := fun x hx ↦ le_antisymm (hsup_y x hx sup_inf) (hsup_inf (sup_y x)) suffices {t | ∃ x ∈ X, sup_y x = t} = {sup_inf} from (this ▸ hinf_sup).unique (by simp) |>.le ext t - simp only [mem_setOf_eq, mem_singleton_iff] + simp only [mem_ofPred_eq, mem_singleton_iff] constructor · rintro ⟨x, hx, rfl⟩ exact hsup_y x hx @@ -374,7 +380,7 @@ public theorem minimax simp only [mem_iInter, mem_preimage, mem_Iic] at hx' rw [lt_isGLB_iff hinf_sup] at ht obtain ⟨c, hc, htc⟩ := ht - simp only [mem_lowerBounds, mem_setOf_eq, forall_exists_index, and_imp, + simp only [mem_lowerBounds, mem_ofPred_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] at hc apply not_le.mpr htc (le_trans (hc x hx) _) rw [isLUB_le_iff (hsup_y x hx), mem_upperBounds] @@ -388,7 +394,7 @@ public theorem minimax ne_X kX hfy hfy' cY hfx hfx' cX (t := t) (toFinite _) (Subtype.coe_image_subset Y ↑s) - simp only [lt_isLUB_iff hsup_inf, mem_setOf_eq, exists_exists_and_eq_and] + simp only [lt_isLUB_iff hsup_inf, mem_ofPred_eq, exists_exists_and_eq_and] use y0 hs', hy0 hs' specialize ht0 hs' obtain ⟨a, ha, h⟩ := LowerSemicontinuousOn.exists_isMinOn ne_X kX (hfy (y0 hs') (hy0 hs')) diff --git a/Mathlib/Topology/Sober.lean b/Mathlib/Topology/Sober.lean index 1bd563a1fb6ff8..8d604540f2b982 100644 --- a/Mathlib/Topology/Sober.lean +++ b/Mathlib/Topology/Sober.lean @@ -98,7 +98,7 @@ theorem isGenericPoint_iff_forall_closed (hS : IsClosed S) (hxS : x ∈ S) : IsGenericPoint x S ↔ ∀ Z : Set α, IsClosed Z → x ∈ Z → S ⊆ Z := by have : closure {x} ⊆ S := closure_minimal (singleton_subset_iff.2 hxS) hS simp_rw [IsGenericPoint, subset_antisymm_iff, this, true_and, closure, subset_sInter_iff, - mem_setOf_eq, and_imp, singleton_subset_iff] + mem_ofPred_eq, and_imp, singleton_subset_iff] end genericPoint diff --git a/Mathlib/Topology/Spectral/Prespectral.lean b/Mathlib/Topology/Spectral/Prespectral.lean index c259887f6e8c49..335c9e9c3ce7f1 100644 --- a/Mathlib/Topology/Spectral/Prespectral.lean +++ b/Mathlib/Topology/Spectral/Prespectral.lean @@ -62,14 +62,14 @@ lemma PrespectralSpace.of_isOpenCover {ι : Type*} {U : ι → Opens X} (hU : IsOpenCover U) [∀ i, PrespectralSpace (U i)] : PrespectralSpace X := by refine .of_isTopologicalBasis (hU.isTopologicalBasis fun i ↦ isTopologicalBasis) ?_ - simp only [Set.mem_iUnion, Set.mem_image, Set.mem_setOf_eq, forall_exists_index, and_imp, + simp only [Set.mem_iUnion, Set.mem_image, Set.mem_ofPred_eq, forall_exists_index, and_imp, forall_comm (α := Set _), forall_apply_eq_imp_iff₂] exact fun i V hV hV' ↦ hV'.image continuous_subtype_val lemma PrespectralSpace.of_isInducing [PrespectralSpace Y] (f : X → Y) (hf : IsInducing f) (hf' : IsSpectralMap f) : PrespectralSpace X := .of_isTopologicalBasis (PrespectralSpace.isTopologicalBasis.isInducing hf) (by - simp only [Set.mem_image, Set.mem_setOf_eq, forall_exists_index, and_imp] + simp only [Set.mem_image, Set.mem_ofPred_eq, forall_exists_index, and_imp] rintro _ U h₁ h₂ rfl exact hf'.isCompact_preimage_of_isOpen h₁ h₂) diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index 45ae3163670cf2..ee911231c8d03d 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -63,7 +63,7 @@ lemma IsOpen.relInv [TopologicalSpace α] [TopologicalSpace β] lemma IsOpen.relImage [TopologicalSpace α] [TopologicalSpace β] {s : SetRel α β} (hs : IsOpen s) {t : Set α} : IsOpen (s.image t) := by - simp_rw [SetRel.image, ← exists_prop, Set.setOf_exists] + simp_rw [SetRel.image, ← exists_prop, Set.ofPred_exists] exact isOpen_biUnion fun _ _ => hs.preimage <| .prodMk_right _ lemma IsOpen.relPreimage [TopologicalSpace α] [TopologicalSpace β] @@ -76,7 +76,7 @@ lemma IsClosed.relInv [TopologicalSpace α] [TopologicalSpace β] lemma IsClosed.relImage_of_finite [TopologicalSpace α] [TopologicalSpace β] {s : SetRel α β} (hs : IsClosed s) {t : Set α} (ht : t.Finite) : IsClosed (s.image t) := by - simp_rw [SetRel.image, ← exists_prop, Set.setOf_exists] + simp_rw [SetRel.image, ← exists_prop, Set.ofPred_exists] exact ht.isClosed_biUnion fun _ _ => hs.preimage <| .prodMk_right _ lemma IsClosed.relPreimage_of_finite [TopologicalSpace α] [TopologicalSpace β] @@ -201,7 +201,7 @@ theorem closure_eq_uniformity (s : Set <| α × α) : closure s = ⋂ V ∈ {V | V ∈ 𝓤 α ∧ SetRel.IsSymm V}, V ○ s ○ V := by ext ⟨x, y⟩ simp +contextual only - [mem_closure_iff_nhds_basis (UniformSpace.hasBasis_nhds_prod x y), mem_iInter, mem_setOf_eq, + [mem_closure_iff_nhds_basis (UniformSpace.hasBasis_nhds_prod x y), mem_iInter, mem_ofPred_eq, and_imp, mem_comp_comp, ← mem_inter_iff, inter_comm, Set.Nonempty] theorem uniformity_hasBasis_closed : @@ -785,7 +785,7 @@ theorem entourageProd_mem_uniformity [t₁ : UniformSpace α] [t₂ : UniformSpa theorem ball_entourageProd (u : SetRel α α) (v : SetRel β β) (x : α × β) : ball x (entourageProd u v) = ball x.1 u ×ˢ ball x.2 v := by - ext p; simp only [ball, entourageProd, Set.mem_setOf_eq, Set.mem_prod, Set.mem_preimage] + ext p; simp only [ball, entourageProd, Set.mem_ofPred_eq, Set.mem_prod, Set.mem_preimage] instance IsSymm_entourageProd {u : SetRel α α} {v : SetRel β β} [u.IsSymm] [v.IsSymm] : (entourageProd u v).IsSymm where diff --git a/Mathlib/Topology/UniformSpace/Cauchy.lean b/Mathlib/Topology/UniformSpace/Cauchy.lean index 346f9f6d9e8159..8be9eee003328f 100644 --- a/Mathlib/Topology/UniformSpace/Cauchy.lean +++ b/Mathlib/Topology/UniformSpace/Cauchy.lean @@ -550,7 +550,8 @@ theorem Filter.TotallyBounded.mono {f g : Filter α} (h : f ≤ g) (hg : g.Total f.TotallyBounded := fun U hU => (hg U hU).imp fun _ => And.imp_right (@h _) -theorem Filter.TotallyBounded.totallyBounded_setOf_clusterPt {f : Filter α} (h : f.TotallyBounded) : +theorem Filter.TotallyBounded.totallyBounded_setOfPred_clusterPt {f : Filter α} + (h : f.TotallyBounded) : TotallyBounded {x | ClusterPt x f} := by refine uniformity_hasBasis_closed.totallyBounded_iff.2 fun V hV => ?_ obtain ⟨t, htf, hst⟩ := h V hV.1 @@ -558,10 +559,14 @@ theorem Filter.TotallyBounded.totallyBounded_setOf_clusterPt {f : Filter α} (h rw [← SetRel.preimage_eq_biUnion, id, ← (hV.2.relPreimage_of_finite htf).closure_eq] exact hx.mem_closure_of_mem _ hst +@[deprecated (since := "2026-07-09")] +alias Filter.TotallyBounded.totallyBounded_setOf_clusterPt := + Filter.TotallyBounded.totallyBounded_setOfPred_clusterPt + /-- The closure of a totally bounded set is totally bounded. -/ theorem TotallyBounded.closure {s : Set α} (h : TotallyBounded s) : TotallyBounded (closure s) := by rw [closure_eq_cluster_pts] - exact (Filter.totallyBounded_principal_iff.mpr h).totallyBounded_setOf_clusterPt + exact (Filter.totallyBounded_principal_iff.mpr h).totallyBounded_setOfPred_clusterPt @[simp] lemma totallyBounded_closure {s : Set α} : TotallyBounded (closure s) ↔ TotallyBounded s := @@ -749,9 +754,13 @@ theorem TotallyBounded.isCompact_of_isComplete {s : Set α} (ht : TotallyBounded theorem TotallyBounded.isCompact_of_isClosed [CompleteSpace α] {s : Set α} (ht : TotallyBounded s) (hc : IsClosed s) : IsCompact s := ht.isCompact_of_isComplete hc.isComplete -theorem Filter.TotallyBounded.isCompact_setOf_clusterPt +theorem Filter.TotallyBounded.isCompact_setOfPred_clusterPt [CompleteSpace α] {f : Filter α} (hf : f.TotallyBounded) : IsCompact {x | ClusterPt x f} := - hf.totallyBounded_setOf_clusterPt.isCompact_of_isClosed isClosed_setOf_clusterPt + hf.totallyBounded_setOfPred_clusterPt.isCompact_of_isClosed isClosed_setOfPred_clusterPt + +@[deprecated (since := "2026-07-09")] +alias Filter.TotallyBounded.isCompact_setOf_clusterPt := + Filter.TotallyBounded.isCompact_setOfPred_clusterPt theorem Filter.TotallyBounded.exists_clusterPt [CompleteSpace α] {f : Filter α} [f.NeBot] (hf : f.TotallyBounded) : ∃ x, ClusterPt x f := by diff --git a/Mathlib/Topology/UniformSpace/Closeds.lean b/Mathlib/Topology/UniformSpace/Closeds.lean index 31a020be6fbe21..414d506192496a 100644 --- a/Mathlib/Topology/UniformSpace/Closeds.lean +++ b/Mathlib/Topology/UniformSpace/Closeds.lean @@ -163,7 +163,7 @@ theorem isOpen_inter_nonempty_of_isOpen {U : Set α} (hU : IsOpen U) : /-- In the Hausdorff uniformity, the powerset of a closed set is closed. -/ theorem _root_.IsClosed.powerset_hausdorff {F : Set α} (hF : IsClosed F) : IsClosed F.powerset := by - simp_rw [Set.powerset, ← isOpen_compl_iff, Set.compl_setOf, ← Set.inter_compl_nonempty_iff] + simp_rw [Set.powerset, ← isOpen_compl_iff, Set.compl_ofPred, ← Set.inter_compl_nonempty_iff] exact isOpen_inter_nonempty_of_isOpen hF.isOpen_compl theorem isClopen_singleton_empty : IsClopen {(∅ : Set α)} := by @@ -231,7 +231,7 @@ theorem isUniformInducing_closure : IsUniformInducing (closure (X := α)) := by theorem nhds_closure (s : Set α) : 𝓝 (closure s) = 𝓝 s := by simp_rw +singlePass [isUniformInducing_closure.isInducing.nhds_eq_comap, closure_closure] -theorem isClosed_setOf_totallyBounded : IsClosed {s : Set α | TotallyBounded s} := by +theorem isClosed_setOfPred_totallyBounded : IsClosed {s : Set α | TotallyBounded s} := by simp_rw [isClosed_iff_frequently, nhds_eq_comap_uniformity] intro s hs U hU obtain ⟨V : SetRel α α, hV, hVU⟩ := comp_mem_uniformity_sets hU @@ -243,6 +243,9 @@ theorem isClosed_setOf_totallyBounded : IsClosed {s : Set α | TotallyBounded s} simp [Set.subset_def] grind +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_totallyBounded := isClosed_setOfPred_totallyBounded + instance [DiscreteUniformity α] : DiscreteUniformity (Set α) := by rw [discreteUniformity_iff_setRelId_mem_uniformity] convert! Filter.mem_lift' (DiscreteUniformity.relId_mem_uniformity α) @@ -270,7 +273,7 @@ theorem IsUniformInducing.image_hausdorff {f : α → β} (hf : IsUniformInducin Filter.comap_lift'_eq2 monotone_hausdorffEntourage] congr with U ⟨s, t⟩ simp only [Function.comp, hausdorffEntourage, SetRel.preimage, SetRel.image, Set.preimage, - Set.mem_setOf, Set.image_subset_iff, Set.exists_mem_image] + Set.mem_ofPred, Set.image_subset_iff, Set.exists_mem_image] /-- When `Set` is equipped with the Hausdorff uniformity, taking the image under a uniform embedding is a uniform embedding. -/ @@ -283,7 +286,7 @@ theorem IsUniformEmbedding.image_hausdorff {f : α → β} (hf : IsUniformEmbedd theorem TotallyBounded.powerset_hausdorff {t : Set α} (ht : TotallyBounded t) : TotallyBounded t.powerset := by simp_rw [(𝓤 α).basis_sets.uniformity_hausdorff.totallyBounded_iff, Function.comp_id, - Set.powerset, Set.setOf_subset, Set.mem_iUnion] + Set.powerset, Set.ofPred_subset, Set.mem_iUnion] intro (U : SetRel α α) hU obtain ⟨u, hu, ht⟩ := ht U hU refine ⟨u.powerset, hu.powerset, fun s hs => ⟨u ∩ U.image s, by grind, fun x hx => ?_, @@ -298,7 +301,7 @@ theorem TotallyBounded.nhds_vietoris_le_nhds_hausdorff {s : Set α} (hs : Totall open UniformSpace TopologicalSpace.vietoris in simp_rw [nhds_eq_comap_uniformity, uniformity_hasBasis_open.uniformity_hausdorff |>.comap _ |>.ge_iff, Function.comp_id, - hausdorffEntourage, Set.preimage_setOf_eq, Set.setOf_and] + hausdorffEntourage, Set.preimage_ofPred_eq, Set.ofPred_and] intro U ⟨hU₁, hU₂⟩ have : U.IsRefl := ⟨fun _ => refl_mem_uniformity hU₁⟩ let := TopologicalSpace.vietoris α @@ -377,8 +380,11 @@ theorem totallyBounded_subsets_of_totallyBounded {t : Set α} (ht : TotallyBound TotallyBounded {F : Closeds α | ↑F ⊆ t} := totallyBounded_preimage isUniformEmbedding_coe.isUniformInducing ht.powerset_hausdorff -theorem isClosed_setOf_totallyBounded : IsClosed {s : Closeds α | TotallyBounded (s : Set α)} := - UniformSpace.hausdorff.isClosed_setOf_totallyBounded.preimage uniformContinuous_coe.continuous +theorem isClosed_setOfPred_totallyBounded : IsClosed {s : Closeds α | TotallyBounded (s : Set α)} := + UniformSpace.hausdorff.isClosed_setOfPred_totallyBounded.preimage uniformContinuous_coe.continuous + +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_totallyBounded := isClosed_setOfPred_totallyBounded instance [DiscreteUniformity α] : DiscreteUniformity (Closeds α) := isUniformEmbedding_coe.discreteUniformity @@ -476,8 +482,8 @@ theorem compactSpace_iff : CompactSpace (Closeds α) ↔ CompactSpace α := by (fun i => {C : Closeds α | ↑C ⊆ F i}) (fun i => isClosed_subsets_of_isClosed (hF₁ i)) simp_rw [← Set.disjoint_iff_inter_eq_empty, Set.disjoint_compl_left_iff_subset, - ← Set.setOf_forall, ← Set.subset_iInter_iff, hF₂, Set.subset_empty_iff, coe_eq_empty, - Set.setOf_eq_eq_singleton] at this + ← Set.ofPred_forall, ← Set.subset_iInter_iff, hF₂, Set.subset_empty_iff, coe_eq_empty, + Set.ofPred_eq_eq_singleton] at this obtain ⟨s, hs⟩ := this .rfl specialize @hs ⟨⋂ i ∈ s, F i, isClosed_biInter fun i _ => hF₁ i⟩ .rfl exact ⟨s, congr($hs)⟩ @@ -533,7 +539,7 @@ theorem isClosedEmbedding_toCloseds [T2Space α] [CompleteSpace α] : IsClosedEmbedding (toCloseds (α := α)) where __ := isEmbedding_toCloseds isClosed_range := by - convert! Closeds.isClosed_setOf_totallyBounded + convert! Closeds.isClosed_setOfPred_totallyBounded exact subset_antisymm (Set.range_subset_iff.mpr fun K => K.isCompact.totallyBounded) (fun K hK => ⟨⟨K, hK.isCompact_of_isClosed K.isClosed⟩, rfl⟩) @@ -606,7 +612,7 @@ instance [CompleteSpace α] : CompleteSpace (Compacts α) := by rw [Set.iUnion₂_subset_iff] intro K' ⟨_, (hK' : ↑K' ⊆ V.preimage K)⟩ grw [← hVU, SetRel.preimage_comp, ← ht₂, hK'] - let L : Compacts α := ⟨{x | ClusterPt x l}, hl.isCompact_setOf_clusterPt⟩ + let L : Compacts α := ⟨{x | ClusterPt x l}, hl.isCompact_setOfPred_clusterPt⟩ exists L simp_rw [nhds_eq_comap_uniformity'] rw [uniformity_hasBasis_closed.uniformity_compacts.comap _ |>.ge_iff] diff --git a/Mathlib/Topology/UniformSpace/CompactConvergence.lean b/Mathlib/Topology/UniformSpace/CompactConvergence.lean index 4406312173f31f..543d6e60b52fb3 100644 --- a/Mathlib/Topology/UniformSpace/CompactConvergence.lean +++ b/Mathlib/Topology/UniformSpace/CompactConvergence.lean @@ -405,7 +405,7 @@ theorem uniformSpace_eq_iInf_precomp_of_cover {δ : ι → Type*} [∀ i, Topolo have h_cover' : ∀ S ∈ 𝔖, ∃ I : Set ι, I.Finite ∧ S ⊆ ⋃ i ∈ I, range (φ i) := fun S hS ↦ by refine ⟨{i | (range (φ i) ∩ S).Nonempty}, h_lf.finite_nonempty_inter_compact hS, inter_eq_right.mp ?_⟩ - simp_rw [iUnion₂_inter, mem_setOf, iUnion_nonempty_self, ← iUnion_inter, h_cover, univ_inter] + simp_rw [iUnion₂_inter, mem_ofPred, iUnion_nonempty_self, ← iUnion_inter, h_cover, univ_inter] -- ... and we just pull it back. simp_rw +zetaDelta [compactConvergenceUniformSpace, replaceTopology_eq, UniformOnFun.uniformSpace_eq_iInf_precomp_of_cover _ _ _ h_image h_preimage h_cover', @@ -426,7 +426,7 @@ instance instCompleteSpaceOfCompactlyCoherentSpace [CompactlyCoherentSpace α] : rw [completeSpace_iff_isComplete_range isUniformEmbedding_toUniformOnFunIsCompact.isUniformInducing, range_toUniformOnFunIsCompact, ← completeSpace_coe_iff_isComplete] - exact (UniformOnFun.isClosed_setOf_continuous + exact (UniformOnFun.isClosed_setOfPred_continuous CompactlyCoherentSpace.isCoherentWith).completeSpace_coe end CompleteSpace @@ -439,7 +439,7 @@ Note that this set does not have to be a closed set when `β` is not T0. This lemma is useful to prove that, e.g., the space of paths between two points and the space of homotopies between two continuous maps are complete spaces, without assuming that the codomain is a Hausdorff space. -/ -theorem isComplete_setOf_eqOn [CompleteSpace C(α, β)] (f : α → β) (s : Set α) : +theorem isComplete_setOfPred_eqOn [CompleteSpace C(α, β)] (f : α → β) (s : Set α) : IsComplete {g : C(α, β) | EqOn g f s} := by classical intro l hlc hlf @@ -456,4 +456,6 @@ theorem isComplete_setOf_eqOn [CompleteSpace C(α, β)] (f : α → β) (s : Set refine ⟨g, Set.piecewise_eqOn _ _ _, hf'.trans_eq ?_⟩ rwa [eq_comm, ← Inseparable, ← inseparable_coe, inseparable_pi] +@[deprecated (since := "2026-07-09")] alias isComplete_setOf_eqOn := isComplete_setOfPred_eqOn + end ContinuousMap diff --git a/Mathlib/Topology/UniformSpace/Completion.lean b/Mathlib/Topology/UniformSpace/Completion.lean index de432525d28e07..71b55c667e8fd1 100644 --- a/Mathlib/Topology/UniformSpace/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Completion.lean @@ -75,7 +75,7 @@ def gen (s : SetRel α α) : SetRel (CauchyFilter α) (CauchyFilter α) := { p | s ∈ p.1.val ×ˢ p.2.val } theorem monotone_gen : Monotone (gen : SetRel α α → _) := - monotone_setOf fun p => @Filter.monotone_mem _ (p.1.val ×ˢ p.2.val) + monotone_ofPred fun p => @Filter.monotone_mem _ (p.1.val ×ˢ p.2.val) -- Porting note: this was a calc proof, but I could not make it work private theorem symm_gen : map Prod.swap ((𝓤 α).lift' gen) ≤ (𝓤 α).lift' gen := by @@ -83,12 +83,12 @@ private theorem symm_gen : map Prod.swap ((𝓤 α).lift' gen) ≤ (𝓤 α).lif { p : CauchyFilter α × CauchyFilter α | s ∈ (p.2.val ×ˢ p.1.val : Filter (α × α)) } have h₁ : map Prod.swap ((𝓤 α).lift' gen) = (𝓤 α).lift' f := by delta gen - simp [f, map_lift'_eq, monotone_setOf, Filter.monotone_mem, Function.comp_def, + simp [f, map_lift'_eq, monotone_ofPred, Filter.monotone_mem, Function.comp_def, image_swap_eq_preimage_swap] have h₂ : (𝓤 α).lift' f ≤ (𝓤 α).lift' gen := uniformity_lift_le_swap (monotone_principal.comp - (monotone_setOf fun p => @Filter.monotone_mem _ (p.2.val ×ˢ p.1.val))) + (monotone_ofPred fun p => @Filter.monotone_mem _ (p.2.val ×ˢ p.1.val))) (by have h := fun p : CauchyFilter α × CauchyFilter α => @Filter.prod_comm _ _ p.2.val p.1.val simp only [Function.comp, h, mem_map, f] @@ -173,7 +173,7 @@ theorem denseRange_pureCauchy : DenseRange (pureCauchy : α → CauchyFilter α) ht'₂ <| SetRel.prodMk_mem_comp (@h (a, x) ⟨h₁, hx⟩) h₂⟩ ⟨x, ht''₂ <| by dsimp [gen]; exact this⟩ simp only [closure_eq_cluster_pts, ClusterPt, nhds_eq_uniformity, lift'_inf_principal_eq, - Set.inter_comm _ (range pureCauchy), mem_setOf_eq] + Set.inter_comm _ (range pureCauchy), mem_ofPred_eq] refine (lift'_neBot_iff ?_).mpr (fun s hs => ?_) · exact monotone_const.inter monotone_preimage · let ⟨y, hy⟩ := h_ex s hs diff --git a/Mathlib/Topology/UniformSpace/Defs.lean b/Mathlib/Topology/UniformSpace/Defs.lean index 1e5b907aeebbe1..2ebe8974574aa0 100644 --- a/Mathlib/Topology/UniformSpace/Defs.lean +++ b/Mathlib/Topology/UniformSpace/Defs.lean @@ -500,7 +500,7 @@ theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} : theorem mem_nhds_uniformity_iff_left {x : α} {s : Set α} : s ∈ 𝓝 x ↔ { p : α × α | p.2 = x → p.1 ∈ s } ∈ 𝓤 α := by rw [uniformity_eq_symm, mem_nhds_uniformity_iff_right] - simp only [mem_map, preimage_setOf_eq, Prod.snd_swap, Prod.fst_swap] + simp only [mem_map, preimage_ofPred_eq, Prod.snd_swap, Prod.fst_swap] theorem nhdsWithin_eq_comap_uniformity_of_mem {x : α} {T : Set α} (hx : x ∈ T) (S : Set α) : 𝓝[S] x = (𝓤 α ⊓ 𝓟 (T ×ˢ S)).comap (Prod.mk x) := by diff --git a/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean b/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean index b9de3393d2bba1..921a9a550f56a9 100644 --- a/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean +++ b/Mathlib/Topology/UniformSpace/DiscreteUniformity.lean @@ -68,7 +68,7 @@ variable {X} in instance {Y : Type*} [UniformSpace Y] [DiscreteUniformity Y] : DiscreteUniformity (X × Y) := by simp [discreteUniformity_iff_eq_principal_setRelId, uniformity_prod_eq_comap_prod, - eq_principal_setRelId, SetRel.id, Set.prod_eq, Prod.ext_iff, Set.setOf_and] + eq_principal_setRelId, SetRel.id, Set.prod_eq, Prod.ext_iff, Set.ofPred_and] variable {x} in /-- On a space with a discrete uniformity, any function is uniformly continuous. -/ diff --git a/Mathlib/Topology/UniformSpace/Equicontinuity.lean b/Mathlib/Topology/UniformSpace/Equicontinuity.lean index 65e2ca29f6eaae..c13f968f195452 100644 --- a/Mathlib/Topology/UniformSpace/Equicontinuity.lean +++ b/Mathlib/Topology/UniformSpace/Equicontinuity.lean @@ -977,12 +977,15 @@ theorem EquicontinuousAt.tendsto_of_mem_closure {l : Filter ι} {F : ι → X /-- If `F : ι → X → α` is an equicontinuous family of functions, `f : X → α` is a continuous function, and `l` is a filter on `ι`, then `{x | Filter.Tendsto (F · x) l (𝓝 (f x))}` is a closed set. -/ -theorem Equicontinuous.isClosed_setOf_tendsto {l : Filter ι} {F : ι → X → α} {f : X → α} +theorem Equicontinuous.isClosed_setOfPred_tendsto {l : Filter ι} {F : ι → X → α} {f : X → α} (hF : Equicontinuous F) (hf : Continuous f) : IsClosed {x | Tendsto (F · x) l (𝓝 (f x))} := closure_subset_iff_isClosed.mp fun x hx ↦ (hF x).tendsto_of_mem_closure (hf.continuousAt.mono_left inf_le_left) (fun _ ↦ id) hx +@[deprecated (since := "2026-07-09")] +alias Equicontinuous.isClosed_setOf_tendsto := Equicontinuous.isClosed_setOfPred_tendsto + end end diff --git a/Mathlib/Topology/UniformSpace/OfFun.lean b/Mathlib/Topology/UniformSpace/OfFun.lean index d6ff09a0f4dbad..c92a8ac3a27fd9 100644 --- a/Mathlib/Topology/UniformSpace/OfFun.lean +++ b/Mathlib/Topology/UniformSpace/OfFun.lean @@ -39,7 +39,7 @@ def ofFun [AddCommMonoid M] [PartialOrder M] { uniformity := ⨅ r > 0, 𝓟 { x | d x.1 x.2 < r } refl := le_iInf₂ fun r hr => principal_mono.2 <| by simp [Set.subset_def, *] symm := tendsto_iInf_iInf fun r => tendsto_iInf_iInf fun _ => tendsto_principal_principal.2 - fun x hx => by rwa [mem_setOf, symm] + fun x hx => by rwa [mem_ofPred, symm] comp := le_iInf₂ fun r hr => let ⟨δ, h0, hδr⟩ := half r hr; le_principal_iff.2 <| mem_of_superset (mem_lift' <| mem_iInf_of_mem δ <| mem_iInf_of_mem h0 <| mem_principal_self _) diff --git a/Mathlib/Topology/UniformSpace/Path.lean b/Mathlib/Topology/UniformSpace/Path.lean index da9af285d290ff..e02ce8da7fe7c2 100644 --- a/Mathlib/Topology/UniformSpace/Path.lean +++ b/Mathlib/Topology/UniformSpace/Path.lean @@ -79,6 +79,6 @@ theorem uniformContinuous_trans : is a complete uniform space. -/ instance instCompleteSpace [CompleteSpace X] : CompleteSpace (Path x y) := isUniformEmbedding_coe.completeSpace <| by simpa [Set.EqOn, range_coe] - using ContinuousMap.isComplete_setOf_eqOn (Function.update (fun _ : I ↦ y) 0 x) {0, 1} + using ContinuousMap.isComplete_setOfPred_eqOn (Function.update (fun _ : I ↦ y) 0 x) {0, 1} end Path diff --git a/Mathlib/Topology/UniformSpace/Pi.lean b/Mathlib/Topology/UniformSpace/Pi.lean index e16e31c44cdca3..fc2b794a72f7b8 100644 --- a/Mathlib/Topology/UniformSpace/Pi.lean +++ b/Mathlib/Topology/UniformSpace/Pi.lean @@ -130,7 +130,7 @@ protected theorem CompleteSpace.iInf {ι X : Type*} {u : ι → UniformSpace X} Filter.comap_comap, comp_def, const, Prod.eta, comap_id'] -- Hence, it suffices to show that its range, the diagonal, is closed in `Π i, (X, u i)`. simp_rw [@completeSpace_iff_isComplete_range _ _ (_) (_) _ this, range_const_eq_diagonal, - setOf_forall] + ofPred_forall] -- The separation of `t` ensures that this is the case in `Π i, (X, t)`, hence the result -- since the topology associated to each `u i` is finer than `t`. have : Pi.topologicalSpace (t₂ := fun i ↦ (u i).toTopologicalSpace) ≤ diff --git a/Mathlib/Topology/UniformSpace/ProdApproximation.lean b/Mathlib/Topology/UniformSpace/ProdApproximation.lean index 7ee1f6bc4a8a3c..2bc0d117b938a2 100644 --- a/Mathlib/Topology/UniformSpace/ProdApproximation.lean +++ b/Mathlib/Topology/UniformSpace/ProdApproximation.lean @@ -106,7 +106,7 @@ lemma denseRange_tensorHom [CompactSpace X] [T2Space X] [CompactSpace Y] obtain ⟨J, hJu, hJ'⟩ := (hasBasis_compactConvergenceUniformity_of_compact).mem_iff.mp this obtain ⟨n, g, h, hgh⟩ := exists_finite_sum_mul_approximation_of_mem_uniformity f hJu have hG := Set.mem_of_subset_of_mem hJ' (a := (f, tensorHom <| ∑ i, g i ⊗ₜ h i)) - simp only [Prod.forall, Set.mem_setOf_eq, forall_const] at hG + simp only [Prod.forall, Set.mem_ofPred_eq, forall_const] at hG simpa using ⟨_, hG <| by simpa [tensorHom] using hgh⟩ end prodMul diff --git a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean index 7b7f4bf22f58df..d94800cb2f26ef 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean @@ -455,7 +455,7 @@ instance [T2Space β] : T2Space (α →ᵤ β) := protected theorem tendsto_iff_tendstoUniformly {F : ι → α →ᵤ β} {f : α →ᵤ β} : Tendsto F p (𝓝 f) ↔ TendstoUniformly (toFun ∘ F) (toFun f) p := by rw [(UniformFun.hasBasis_nhds α β f).tendsto_right_iff, TendstoUniformly] - simp only [mem_setOf, UniformFun.gen, Function.comp_def] + simp only [mem_ofPred, UniformFun.gen, Function.comp_def] set_option backward.isDefEq.respectTransparency false in /-- The natural bijection between `α → β × γ` and `(α → β) × (α → γ)`, upgraded to a uniform @@ -510,12 +510,15 @@ protected def uniformEquivPiComm : UniformEquiv (α →ᵤ ∀ i, δ i) (∀ i, /-- The set of continuous functions is closed in the uniform convergence topology. This is a simple wrapper over `TendstoUniformly.continuous`. -/ -theorem isClosed_setOf_continuous [TopologicalSpace α] : +theorem isClosed_setOfPred_continuous [TopologicalSpace α] : IsClosed {f : α →ᵤ β | Continuous (toFun f)} := by refine isClosed_iff_forall_filter.2 fun f u _ hu huf ↦ ?_ rw [← tendsto_id', UniformFun.tendsto_iff_tendstoUniformly] at huf exact huf.continuous <| Eventually.frequently (le_principal_iff.mp hu) +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_continuous := isClosed_setOfPred_continuous + variable {α} (β) in theorem uniformSpace_eq_inf_precomp_of_cover {δ₁ δ₂ : Type*} (φ₁ : δ₁ → α) (φ₂ : δ₂ → α) (h_cover : range φ₁ ∪ range φ₂ = univ) : @@ -763,7 +766,7 @@ protected theorem uniformity_eq_of_basis {ι : Sort*} {p : ι → Prop} {V : ι 𝓤 (α →ᵤ[𝔖] β) = ⨅ s ∈ 𝔖, ⨅ (i) (_ : p i), 𝓟 (UniformOnFun.gen 𝔖 s (V i)) := by simp_rw [iInf_uniformity, uniformity_comap, (UniformFun.hasBasis_uniformity_of_basis _ _ h).eq_biInf, comap_iInf, comap_principal, - Function.comp_apply, UniformFun.gen, Subtype.forall, UniformOnFun.gen, preimage_setOf_eq, + Function.comp_apply, UniformFun.gen, Subtype.forall, UniformOnFun.gen, preimage_ofPred_eq, Prod.map_fst, Prod.map_snd, Function.comp_apply, UniformFun.toFun_ofFun, restrict_apply] protected theorem uniformity_eq : 𝓤 (α →ᵤ[𝔖] β) = ⨅ s ∈ 𝔖, ⨅ V ∈ 𝓤 β, 𝓟 (UniformOnFun.gen 𝔖 s V) := @@ -783,7 +786,7 @@ protected theorem nhds_eq_of_basis {ι : Sort*} {p : ι → Prop} {V : ι → Se (h : (𝓤 β).HasBasis p V) (f : α →ᵤ[𝔖] β) : 𝓝 f = ⨅ s ∈ 𝔖, ⨅ (i) (_ : p i), 𝓟 {g | ∀ x ∈ s, (toFun 𝔖 f x, toFun 𝔖 g x) ∈ V i} := by simp_rw [nhds_eq_comap_uniformity, UniformOnFun.uniformity_eq_of_basis _ _ h, comap_iInf, - comap_principal, UniformOnFun.gen, preimage_setOf_eq] + comap_principal, UniformOnFun.gen, preimage_ofPred_eq] protected theorem nhds_eq (f : α →ᵤ[𝔖] β) : 𝓝 f = ⨅ s ∈ 𝔖, ⨅ V ∈ 𝓤 β, 𝓟 {g | ∀ x ∈ s, (toFun 𝔖 f x, toFun 𝔖 g x) ∈ V} := @@ -826,7 +829,7 @@ lemma uniformContinuous_ofFun_toFun (𝔗 : Set (Set α)) (h : ∀ s ∈ 𝔖, intro s hs obtain ⟨T, hT𝔗, hT, hsT⟩ := h s hs refine ⟨T, hT, hT𝔗, fun f hf ↦ ?_⟩ - simp only [UniformOnFun.gen, Set.mem_iInter, Set.mem_setOf_eq] at hf ⊢ + simp only [UniformOnFun.gen, Set.mem_iInter, Set.mem_ofPred_eq] at hf ⊢ intro x hx obtain ⟨t, ht, hxt⟩ := Set.mem_sUnion.mp <| hsT hx exact hf t ht x hxt @@ -1028,7 +1031,7 @@ of `TendstoUniformlyOn`) for all `S ∈ 𝔖`. -/ protected theorem tendsto_iff_tendstoUniformlyOn {F : ι → α →ᵤ[𝔖] β} {f : α →ᵤ[𝔖] β} : Tendsto F p (𝓝 f) ↔ ∀ s ∈ 𝔖, TendstoUniformlyOn (toFun 𝔖 ∘ F) (toFun 𝔖 f) p s := by simp only [UniformOnFun.nhds_eq, tendsto_iInf, tendsto_principal, TendstoUniformlyOn, - Function.comp_apply, mem_setOf] + Function.comp_apply, mem_ofPred] protected lemma continuous_rng_iff {X : Type*} [TopologicalSpace X] {f : X → (α →ᵤ[𝔖] β)} : Continuous f ↔ ∀ s ∈ 𝔖, @@ -1111,12 +1114,15 @@ protected def uniformEquivPiComm : (α →ᵤ[𝔖] ((i : ι) → δ i)) ≃ᵤ Then the set of continuous functions is closed in the topology of uniform convergence on the sets of `𝔖`. -/ -theorem isClosed_setOf_continuous [TopologicalSpace α] (h : IsCoherentWith 𝔖) : +theorem isClosed_setOfPred_continuous [TopologicalSpace α] (h : IsCoherentWith 𝔖) : IsClosed {f : α →ᵤ[𝔖] β | Continuous (toFun 𝔖 f)} := by refine isClosed_iff_forall_filter.2 fun f u _ hu huf ↦ h.continuous_iff.2 fun s hs ↦ ?_ rw [← tendsto_id', UniformOnFun.tendsto_iff_tendstoUniformlyOn] at huf exact (huf s hs).continuousOn <| Eventually.frequently <| hu fun _ ↦ Continuous.continuousOn +@[deprecated (since := "2026-07-09")] +alias isClosed_setOf_continuous := isClosed_setOfPred_continuous + set_option backward.isDefEq.respectTransparency false in variable (𝔖) in theorem uniformSpace_eq_inf_precomp_of_cover {δ₁ δ₂ : Type*} (φ₁ : δ₁ → α) (φ₂ : δ₂ → α) diff --git a/Mathlib/Topology/UniformSpace/UniformEmbedding.lean b/Mathlib/Topology/UniformSpace/UniformEmbedding.lean index 59f59e7cb5ef3a..1aaf86a3677273 100644 --- a/Mathlib/Topology/UniformSpace/UniformEmbedding.lean +++ b/Mathlib/Topology/UniformSpace/UniformEmbedding.lean @@ -405,7 +405,7 @@ instance CompleteSpace.sum [CompleteSpace α] [CompleteSpace β] : CompleteSpace theorem IsUniformEmbedding.discreteUniformity [DiscreteUniformity β] {f : α → β} (hf : IsUniformEmbedding f) : DiscreteUniformity α := by simp_rw [discreteUniformity_iff_eq_principal_setRelId, ← hf.comap_uniformity, - DiscreteUniformity.eq_principal_setRelId, comap_principal, SetRel.id, preimage_setOf_eq, + DiscreteUniformity.eq_principal_setRelId, comap_principal, SetRel.id, preimage_ofPred_eq, hf.injective.eq_iff] end diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 055a66b9f12458..34ebdba01e1cc5 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -1004,32 +1004,32 @@ variable {EM' : Type*} [NormedAddCommGroup EM'] {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] {f : M → M'} {s : Set M} -/-- info: setOf fun x ↦ MDifferentiableAt I I' f x : Set M -/ +/-- info: Set.ofPred fun x ↦ MDifferentiableAt I I' f x : Set M -/ #guard_msgs in #check {x | MDiffAt f x} -/-- info: setOf fun x ↦ MDifferentiableWithinAt I I' f s x : Set M -/ +/-- info: Set.ofPred fun x ↦ MDifferentiableWithinAt I I' f s x : Set M -/ #guard_msgs in #check {x | MDiffAt[s] f x} -/-- info: setOf fun x ↦ ContMDiffAt I I' Top.top f x : Set M -/ +/-- info: Set.ofPred fun x ↦ ContMDiffAt I I' Top.top f x : Set M -/ #guard_msgs in #check {x | CMDiffAt ⊤ f x} -/-- info: setOf fun x ↦ ContMDiffWithinAt I I' 2 f s x : Set M -/ +/-- info: Set.ofPred fun x ↦ ContMDiffWithinAt I I' 2 f s x : Set M -/ #guard_msgs in #check {x | CMDiffAt[s] 2 f x} open ContDiff in -- for the ∞ notation -/-- info: setOf fun x ↦ ContMDiffAt I I' (↑Top.top) f x : Set M -/ +/-- info: Set.ofPred fun x ↦ ContMDiffAt I I' (↑Top.top) f x : Set M -/ #guard_msgs in #check {x | CMDiffAt ∞ f x} -/-- info: setOf fun x ↦ Injective ⇑(mfderiv I I' f x) : Set M -/ +/-- info: Set.ofPred fun x ↦ Injective ⇑(mfderiv I I' f x) : Set M -/ #guard_msgs in #check {x | Function.Injective (mfderiv% f x) } -/-- info: setOf fun x ↦ Surjective ⇑(mfderivWithin I I' f s x) : Set M -/ +/-- info: Set.ofPred fun x ↦ Surjective ⇑(mfderivWithin I I' f s x) : Set M -/ #guard_msgs in #check {x | Function.Surjective (mfderiv[s] f x) } diff --git a/MathlibTest/FinsetBuilder.lean b/MathlibTest/FinsetBuilder.lean index 84374a51e25cca..81ec255fa934d1 100644 --- a/MathlibTest/FinsetBuilder.lean +++ b/MathlibTest/FinsetBuilder.lean @@ -23,12 +23,12 @@ example : ({x : α | p x} : Finset α) = univ.filter p := rfl -- If the type of `s` (or the entire expression) is `Finset ?α`, elaborate as `Finset`; -- otherwise as `Set` example (s : Finset α) : {x ∈ s | p x} = s.filter p := rfl -example (s : Finset α) : ({x ∈ s | p x} : Set α) = setOf fun x => x ∈ s ∧ p x := rfl -example (s : Finset α) : {x ∈ (s : Set α) | p x} = setOf fun x => x ∈ s ∧ p x := rfl +example (s : Finset α) : ({x ∈ s | p x} : Set α) = Set.ofPred fun x => x ∈ s ∧ p x := rfl +example (s : Finset α) : {x ∈ (s : Set α) | p x} = Set.ofPred fun x => x ∈ s ∧ p x := rfl -- elaborate as `Set` if no expected type present -example : {x | p x} = setOf p := rfl -example : {x : α | p x} = setOf p := rfl +example : {x | p x} = Set.ofPred p := rfl +example : {x : α | p x} = Set.ofPred p := rfl variable [DecidableEq α] @@ -36,8 +36,8 @@ example (s : Finset α) : {x ∉ s | p x} = sᶜ.filter p := rfl example (a : α) : ({x ≠ a | p x} : Finset α) = ({a}ᶜ : Finset α).filter p := rfl -- elaborate as `Set` if the `s` or the expected type is not `Finset ?α` -example (s : Set α) : {x ∉ s | p x} = setOf fun x => x ∉ s ∧ p x := rfl -example (a : α) : {x ≠ a | p x} = setOf fun x => x ≠ a ∧ p x := rfl +example (s : Set α) : {x ∉ s | p x} = Set.ofPred fun x => x ∉ s ∧ p x := rfl +example (a : α) : {x ≠ a | p x} = Set.ofPred fun x => x ≠ a ∧ p x := rfl end Fintype @@ -50,8 +50,8 @@ example (a : α) : ({x ≤ a | p x} : Finset α) = (Iic a).filter p := rfl example (a : α) : ({x < a | p x} : Finset α) = (Iio a).filter p := rfl -- elaborate as `Set` if the expected type is not `Finset ?α` -example (a : α) : {x ≤ a | p x} = setOf fun x => x ≤ a ∧ p x := rfl -example (a : α) : {x < a | p x} = setOf fun x => x < a ∧ p x := rfl +example (a : α) : {x ≤ a | p x} = Set.ofPred fun x => x ≤ a ∧ p x := rfl +example (a : α) : {x < a | p x} = Set.ofPred fun x => x < a ∧ p x := rfl end LocallyFiniteOrderBot @@ -62,7 +62,7 @@ example (a : α) : ({x ≥ a | p x} : Finset α) = (Ici a).filter p := rfl example (a : α) : ({x > a | p x} : Finset α) = (Ioi a).filter p := rfl -- elaborate as `Set` if the expected type is not `Finset ?α` -example (a : α) : {x ≥ a | p x} = setOf fun x => x ≥ a ∧ p x := rfl -example (a : α) : {x > a | p x} = setOf fun x => x > a ∧ p x := rfl +example (a : α) : {x ≥ a | p x} = Set.ofPred fun x => x ≥ a ∧ p x := rfl +example (a : α) : {x > a | p x} = Set.ofPred fun x => x > a ∧ p x := rfl end LocallyFiniteOrderTop diff --git a/docs/100.yaml b/docs/100.yaml index 17a09b6ceb64c1..90e3fc0709d52c 100644 --- a/docs/100.yaml +++ b/docs/100.yaml @@ -198,7 +198,7 @@ authors: Thomas Zhu, Rémy Degenne, Etienne Marion 48: title : Dirichlet’s Theorem - decl : Nat.infinite_setOf_prime_and_eq_mod + decl : Nat.infinite_setOfPred_prime_and_eq_mod authors: David Loeffler, Michael Stoll 49: title : The Cayley-Hamilton Theorem diff --git a/docs/1000.yaml b/docs/1000.yaml index a5dda2cc4d3a59..386cf2c01a6a5c 100644 --- a/docs/1000.yaml +++ b/docs/1000.yaml @@ -548,7 +548,7 @@ Q544369: Q550402: title: Dirichlet's theorem on arithmetic progressions - decl: Nat.infinite_setOf_prime_and_eq_mod + decl: Nat.infinite_setOfPred_prime_and_eq_mod authors: David Loeffler, Michael Stoll Q552367: @@ -3654,9 +3654,9 @@ Q7245073: Q7249519: title: Prokhorov's theorem decls: - - isCompact_setOf_finiteMeasure_mass_le_compl_isCompact_le - - isCompact_setOf_finiteMeasure_mass_eq_compl_isCompact_le - - isCompact_setOf_probabilityMeasure_mass_eq_compl_isCompact_le + - isCompact_setOfPred_finiteMeasure_mass_le_compl_isCompact_le + - isCompact_setOfPred_finiteMeasure_mass_eq_compl_isCompact_le + - isCompact_setOfPred_probabilityMeasure_mass_eq_compl_isCompact_le - isCompact_closure_of_isTightMeasureSet Q7255475: diff --git a/docs/undergrad.yaml b/docs/undergrad.yaml index e5f5202fbfc094..c2b131a3402a68 100644 --- a/docs/undergrad.yaml +++ b/docs/undergrad.yaml @@ -291,7 +291,7 @@ Single Variable Real Analysis: completeness of R: 'Real.instCompleteSpace' Bolzano-Weierstrass theorem: 'tendsto_subseq_of_bounded' compact subsets of $\R$: 'Metric.isCompact_iff_isClosed_bounded' - connected subsets of $\R$: 'setOf_isPreconnected_eq_of_ordered' + connected subsets of $\R$: 'setOfPred_isPreconnected_eq_of_ordered' additive subgroups of $\R$: 'AddSubgroup.dense_or_cyclic' Numerical series: Convergence of real-valued series: 'https://en.wikipedia.org/wiki/Series_(mathematics)#Convergent_series' From 119eea4bbfa6d2b3363d0358c2fb79e9e13b881c Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 17 Jul 2026 09:57:55 +0000 Subject: [PATCH 0846/1300] chore: ignore more revisions in .git-blame-ignore-revs (#41681) There are surely more such PRs, but I won't hunt them all down. Having a way to sort such PRs by diff (and tackling the largest PRs first) would be nice. --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6275ba74ef0ab9..2e65eab6e07acb 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -4,3 +4,5 @@ fc48848e4374f13c796a7399bfccd2e228f776df # 2025-11-19 move Mathlib to the module system (#31786) 6a54a80825b060ab20dc31751ebdce78b3a3b518 +# 2025-12-01 fix spelling in doc-strings (#32286) +b728e1450a53133aa4171eeadc0bc8d3ee58415c From 19f249b3c2d3b17248049eeecc11430aac723e93 Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Fri, 17 Jul 2026 10:49:58 +0000 Subject: [PATCH 0847/1300] chore(Geometry/Manifold/MFDeriv/Basic): use custom elaborators (#40803) As requested [here](https://github.com/leanprover-community/mathlib4/pull/40748#issuecomment-4741875703). --- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 625 ++++++++----------- 1 file changed, 274 insertions(+), 351 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index 8cad83511a58c5..fd47f4d3de49e2 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -111,61 +111,52 @@ theorem UniqueMDiffOn.prod {s : Set M} {t : Set M'} (hs : UniqueMDiff[s]) (ht : UniqueMDiff[t]) : UniqueMDiff[s ×ˢ t] := fun x h ↦ (hs x.1 h.1).prod (ht x.2 h.2) -theorem MDifferentiableWithinAt.mono (hst : s ⊆ t) (h : MDifferentiableWithinAt I I' f t x) : - MDifferentiableWithinAt I I' f s x := +theorem MDifferentiableWithinAt.mono (hst : s ⊆ t) (h : MDiffAt[t] f x) : MDiffAt[s] f x := ⟨ContinuousWithinAt.mono h.1 hst, DifferentiableWithinAt.mono h.differentiableWithinAt_writtenInExtChartAt (inter_subset_inter_left _ (preimage_mono hst))⟩ -theorem mdifferentiableWithinAt_univ : - MDifferentiableWithinAt I I' f univ x ↔ MDifferentiableAt I I' f x := by +theorem mdifferentiableWithinAt_univ : MDiffAt[univ] f x ↔ MDiffAt f x := by simp_rw [MDifferentiableWithinAt, MDifferentiableAt, ChartedSpace.LiftPropAt] -theorem mdifferentiableWithinAt_inter (ht : t ∈ 𝓝 x) : - MDifferentiableWithinAt I I' f (s ∩ t) x ↔ MDifferentiableWithinAt I I' f s x := by +theorem mdifferentiableWithinAt_inter (ht : t ∈ 𝓝 x) : MDiffAt[s ∩ t] f x ↔ MDiffAt[s] f x := by rw [MDifferentiableWithinAt, MDifferentiableWithinAt, differentiableWithinAt_localInvariantProp.liftPropWithinAt_inter ht] -theorem mdifferentiableWithinAt_inter' (ht : t ∈ 𝓝[s] x) : - MDifferentiableWithinAt I I' f (s ∩ t) x ↔ MDifferentiableWithinAt I I' f s x := by +theorem mdifferentiableWithinAt_inter' (ht : t ∈ 𝓝[s] x) : MDiffAt[s ∩ t] f x ↔ MDiffAt[s] f x := by rw [MDifferentiableWithinAt, MDifferentiableWithinAt, differentiableWithinAt_localInvariantProp.liftPropWithinAt_inter' ht] -theorem MDifferentiableAt.mdifferentiableWithinAt (h : MDifferentiableAt I I' f x) : - MDifferentiableWithinAt I I' f s x := +theorem MDifferentiableAt.mdifferentiableWithinAt (h : MDiffAt f x) : MDiffAt[s] f x := MDifferentiableWithinAt.mono (subset_univ _) (mdifferentiableWithinAt_univ.2 h) -theorem MDifferentiableWithinAt.mdifferentiableAt (h : MDifferentiableWithinAt I I' f s x) - (hs : s ∈ 𝓝 x) : MDifferentiableAt I I' f x := by +theorem MDifferentiableWithinAt.mdifferentiableAt (h : MDiffAt[s] f x) (hs : s ∈ 𝓝 x) : + MDiffAt f x := by have : s = univ ∩ s := by rw [univ_inter] rwa [this, mdifferentiableWithinAt_inter hs, mdifferentiableWithinAt_univ] at h -theorem MDifferentiableOn.mono (h : MDifferentiableOn I I' f t) (st : s ⊆ t) : - MDifferentiableOn I I' f s := fun x hx => (h x (st hx)).mono st +theorem MDifferentiableOn.mono (h : MDiff[t] f) (st : s ⊆ t) : MDiff[s] f := + fun x hx => (h x (st hx)).mono st @[simp] -theorem mdifferentiableOn_empty : MDifferentiableOn I I' f ∅ := fun _x hx ↦ hx.elim +theorem mdifferentiableOn_empty : MDiff[∅] f := fun _x hx ↦ hx.elim -theorem mdifferentiableOn_univ : MDifferentiableOn I I' f univ ↔ MDifferentiable I I' f := by +theorem mdifferentiableOn_univ : MDiff[univ] f ↔ MDiff f := by simp only [MDifferentiableOn, mdifferentiableWithinAt_univ, mfld_simps]; rfl -theorem MDifferentiableOn.mdifferentiableAt (h : MDifferentiableOn I I' f s) (hx : s ∈ 𝓝 x) : - MDifferentiableAt I I' f x := +theorem MDifferentiableOn.mdifferentiableAt (h : MDiff[s] f) (hx : s ∈ 𝓝 x) : MDiffAt f x := (h x (mem_of_mem_nhds hx)).mdifferentiableAt hx -theorem MDifferentiable.mdifferentiableOn (h : MDifferentiable I I' f) : - MDifferentiableOn I I' f s := +theorem MDifferentiable.mdifferentiableOn (h : MDiff f) : MDiff[s] f := (mdifferentiableOn_univ.2 h).mono (subset_univ _) theorem mdifferentiableOn_of_locally_mdifferentiableOn - (h : ∀ x ∈ s, ∃ u, IsOpen u ∧ x ∈ u ∧ MDifferentiableOn I I' f (s ∩ u)) : - MDifferentiableOn I I' f s := by + (h : ∀ x ∈ s, ∃ u, IsOpen u ∧ x ∈ u ∧ MDiff[s ∩ u] f) : MDiff[s] f := by intro x xs rcases h x xs with ⟨t, t_open, xt, ht⟩ exact (mdifferentiableWithinAt_inter (t_open.mem_nhds xt)).1 (ht x ⟨xs, xt⟩) -theorem MDifferentiable.mdifferentiableAt (hf : MDifferentiable I I' f) : - MDifferentiableAt I I' f x := +theorem MDifferentiable.mdifferentiableAt (hf : MDiff f) : MDiffAt f x := hf x /-! @@ -173,9 +164,8 @@ theorem MDifferentiable.mdifferentiableAt (hf : MDifferentiable I I' f) : through extended charts -/ - theorem mdifferentiableWithinAt_iff_target_inter {f : M → M'} {s : Set M} {x : M} : - MDifferentiableWithinAt I I' f s x ↔ + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ DifferentiableWithinAt 𝕜 (writtenInExtChartAt I I' x f) ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) ((extChartAt I x) x) := by @@ -187,7 +177,7 @@ theorem mdifferentiableWithinAt_iff_target_inter {f : M → M'} {s : Set M} {x : /-- One can reformulate smoothness within a set at a point as continuity within this set at this point, and smoothness in the corresponding extended chart. -/ theorem mdifferentiableWithinAt_iff : - MDifferentiableWithinAt I I' f s x ↔ + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ DifferentiableWithinAt 𝕜 (extChartAt I' (f x) ∘ f ∘ (extChartAt I x).symm) ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by @@ -202,7 +192,7 @@ a smaller set, but their germs at `extChartAt I x x` are equal. It is sometimes using this in the goal. -/ theorem mdifferentiableWithinAt_iff_target_inter' : - MDifferentiableWithinAt I I' f s x ↔ + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ DifferentiableWithinAt 𝕜 (extChartAt I' (f x) ∘ f ∘ (extChartAt I x).symm) ((extChartAt I x).target ∩ @@ -215,9 +205,7 @@ theorem mdifferentiableWithinAt_iff_target_inter' : /-- One can reformulate smoothness within a set at a point as continuity within this set at this point, and smoothness in the corresponding extended chart in the target. -/ theorem mdifferentiableWithinAt_iff_target : - MDifferentiableWithinAt I I' f s x ↔ - ContinuousWithinAt f s x ∧ - MDifferentiableWithinAt I 𝓘(𝕜, E') (extChartAt I' (f x) ∘ f) s x := by + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ MDiffAt[s] (extChartAt I' (f x) ∘ f) x := by simp_rw [MDifferentiableWithinAt, liftPropWithinAt_iff', ← and_assoc] have cont : ContinuousWithinAt f s x ∧ ContinuousWithinAt (extChartAt I' (f x) ∘ f) s x ↔ @@ -230,8 +218,7 @@ theorem mdifferentiableWithinAt_iff_target : rfl theorem mdifferentiableAt_iff_target {x : M} : - MDifferentiableAt I I' f x ↔ - ContinuousAt f x ∧ MDifferentiableAt I 𝓘(𝕜, E') (extChartAt I' (f x) ∘ f) x := by + MDiffAt f x ↔ ContinuousAt f x ∧ MDiffAt (extChartAt I' (f x) ∘ f) x := by rw [← mdifferentiableWithinAt_univ, ← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_iff_target, continuousWithinAt_univ] @@ -241,11 +228,10 @@ variable {e : OpenPartialHomeomorph M H} {e' : OpenPartialHomeomorph M' H'} open IsManifold -theorem mdifferentiableWithinAt_iff_source_of_mem_maximalAtlas - (he : e ∈ maximalAtlas I 1 M) (hx : x ∈ e.source) : - MDifferentiableWithinAt I I' f s x ↔ - MDifferentiableWithinAt 𝓘(𝕜, E) I' (f ∘ (e.extend I).symm) ((e.extend I).symm ⁻¹' s ∩ range I) - (e.extend I x) := by +theorem mdifferentiableWithinAt_iff_source_of_mem_maximalAtlas (he : e ∈ maximalAtlas I 1 M) + (hx : x ∈ e.source) : + MDiffAt[s] f x ↔ + MDiffAt[(e.extend I).symm ⁻¹' s ∩ range I] (f ∘ (e.extend I).symm) (e.extend I x) := by have h2x := hx; rw [← e.extend_source (I := I)] at h2x simp_rw [MDifferentiableWithinAt, differentiableWithinAt_localInvariantProp.liftPropWithinAt_indep_chart_source he hx, @@ -256,27 +242,23 @@ theorem mdifferentiableWithinAt_iff_source_of_mem_maximalAtlas theorem mdifferentiableWithinAt_iff_source_of_mem_source [IsManifold I 1 M] {x' : M} (hx' : x' ∈ (chartAt H x).source) : - MDifferentiableWithinAt I I' f s x' ↔ - MDifferentiableWithinAt 𝓘(𝕜, E) I' (f ∘ (extChartAt I x).symm) - ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x') := + MDiffAt[s] f x' ↔ + MDiffAt[(extChartAt I x).symm ⁻¹' s ∩ range I] (f ∘ (extChartAt I x).symm) + (extChartAt I x x') := mdifferentiableWithinAt_iff_source_of_mem_maximalAtlas (chart_mem_maximalAtlas x) hx' theorem mdifferentiableAt_iff_source_of_mem_source [IsManifold I 1 M] {x' : M} (hx' : x' ∈ (chartAt H x).source) : - MDifferentiableAt I I' f x' ↔ - MDifferentiableWithinAt 𝓘(𝕜, E) I' (f ∘ (extChartAt I x).symm) (range I) - (extChartAt I x x') := by + MDiffAt f x' ↔ MDiffAt[range I] (f ∘ (extChartAt I x).symm) (extChartAt I x x') := by simp_rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_iff_source_of_mem_source hx', preimage_univ, univ_inter] theorem mdifferentiableWithinAt_iff_target_of_mem_source [IsManifold I' 1 M'] {x : M} {y : M'} (hy : f x ∈ (chartAt H' y).source) : - MDifferentiableWithinAt I I' f s x ↔ - ContinuousWithinAt f s x ∧ MDifferentiableWithinAt I 𝓘(𝕜, E') (extChartAt I' y ∘ f) s x := by + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ MDiffAt[s] (extChartAt I' y ∘ f) x := by simp_rw [MDifferentiableWithinAt] rw [differentiableWithinAt_localInvariantProp.liftPropWithinAt_indep_chart_target - (chart_mem_maximalAtlas y) hy, - and_congr_right] + (chart_mem_maximalAtlas y) hy, and_congr_right] intro hf simp_rw [StructureGroupoid.liftPropWithinAt_self_target] simp_rw [((chartAt H' y).continuousAt hy).comp_continuousWithinAt hf] @@ -286,14 +268,13 @@ theorem mdifferentiableWithinAt_iff_target_of_mem_source theorem mdifferentiableAt_iff_target_of_mem_source [IsManifold I' 1 M'] {x : M} {y : M'} (hy : f x ∈ (chartAt H' y).source) : - MDifferentiableAt I I' f x ↔ - ContinuousAt f x ∧ MDifferentiableAt I 𝓘(𝕜, E') (extChartAt I' y ∘ f) x := by + MDiffAt f x ↔ ContinuousAt f x ∧ MDiffAt (extChartAt I' y ∘ f) x := by rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_iff_target_of_mem_source hy, continuousWithinAt_univ, ← mdifferentiableWithinAt_univ] theorem mdifferentiableWithinAt_iff_of_mem_maximalAtlas {x : M} (he : e ∈ maximalAtlas I 1 M) (he' : e' ∈ maximalAtlas I' 1 M') (hx : x ∈ e.source) (hy : f x ∈ e'.source) : - MDifferentiableWithinAt I I' f s x ↔ + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ DifferentiableWithinAt 𝕜 (e'.extend I' ∘ f ∘ (e.extend I).symm) ((e.extend I).symm ⁻¹' s ∩ range I) (e.extend I x) := @@ -304,7 +285,7 @@ if the set if `s` lies in `e.source`. -/ theorem mdifferentiableWithinAt_iff_image {x : M} (he : e ∈ maximalAtlas I 1 M) (he' : e' ∈ maximalAtlas I' 1 M') (hs : s ⊆ e.source) (hx : x ∈ e.source) (hy : f x ∈ e'.source) : - MDifferentiableWithinAt I I' f s x ↔ + MDiffAt[s] f x ↔ ContinuousWithinAt f s x ∧ DifferentiableWithinAt 𝕜 (e'.extend I' ∘ f ∘ (e.extend I).symm) (e.extend I '' s) (e.extend I x) := by @@ -316,7 +297,7 @@ theorem mdifferentiableWithinAt_iff_image {x : M} (he : e ∈ maximalAtlas I 1 M point, and smoothness in any chart containing that point. -/ theorem mdifferentiableWithinAt_iff_of_mem_source [IsManifold I 1 M] [IsManifold I' 1 M'] {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : - MDifferentiableWithinAt I I' f s x' ↔ + MDiffAt[s] f x' ↔ ContinuousWithinAt f s x' ∧ DifferentiableWithinAt 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x') := @@ -328,7 +309,7 @@ point, and smoothness in any chart containing that point. Version requiring diff in the target instead of `range I`. -/ theorem mdifferentiableWithinAt_iff_of_mem_source' [IsManifold I 1 M] [IsManifold I' 1 M'] {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : - MDifferentiableWithinAt I I' f s x' ↔ + MDiffAt[s] f x' ↔ ContinuousWithinAt f s x' ∧ DifferentiableWithinAt 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' (s ∩ f ⁻¹' (extChartAt I' y).source)) @@ -345,7 +326,7 @@ theorem mdifferentiableWithinAt_iff_of_mem_source' [IsManifold I 1 M] [IsManifol theorem mdifferentiableAt_iff_of_mem_source [IsManifold I 1 M] [IsManifold I' 1 M'] {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : - MDifferentiableAt I I' f x' ↔ + MDiffAt f x' ↔ ContinuousAt f x' ∧ DifferentiableWithinAt 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) (range I) (extChartAt I x x') := @@ -354,7 +335,7 @@ theorem mdifferentiableAt_iff_of_mem_source [IsManifold I 1 M] [IsManifold I' 1 theorem mdifferentiableOn_iff_of_mem_maximalAtlas (he : e ∈ maximalAtlas I 1 M) (he' : e' ∈ maximalAtlas I' 1 M') (hs : s ⊆ e.source) (h2s : MapsTo f s e'.source) : - MDifferentiableOn I I' f s ↔ + MDiff[s] f ↔ ContinuousOn f s ∧ DifferentiableOn 𝕜 (e'.extend I' ∘ f ∘ (e.extend I).symm) (e.extend I '' s) := by simp_rw [ContinuousOn, DifferentiableOn, Set.forall_mem_image, ← forall_and, MDifferentiableOn] @@ -363,7 +344,7 @@ theorem mdifferentiableOn_iff_of_mem_maximalAtlas (he : e ∈ maximalAtlas I 1 M /-- Differentiability on a set is equivalent to differentiability in the extended charts. -/ theorem mdifferentiableOn_iff_of_mem_maximalAtlas' (he : e ∈ maximalAtlas I 1 M) (he' : e' ∈ maximalAtlas I' 1 M') (hs : s ⊆ e.source) (h2s : MapsTo f s e'.source) : - MDifferentiableOn I I' f s ↔ + MDiff[s] f ↔ DifferentiableOn 𝕜 (e'.extend I' ∘ f ∘ (e.extend I).symm) (e.extend I '' s) := (mdifferentiableOn_iff_of_mem_maximalAtlas he he' hs h2s).trans <| and_iff_right_of_imp fun h ↦ (e.continuousOn_writtenInExtend_iff hs h2s).1 h.continuousOn @@ -377,7 +358,7 @@ Note: this lemma uses `extChartAt I x '' s` instead of `(extChartAt I x).symm that this set lies in `(extChartAt I x).target`. -/ theorem mdifferentiableOn_iff_of_subset_source {x : M} {y : M'} (hs : s ⊆ (chartAt H x).source) (h2s : MapsTo f s (chartAt H' y).source) : - MDifferentiableOn I I' f s ↔ + MDiff[s] f ↔ ContinuousOn f s ∧ DifferentiableOn 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) (extChartAt I x '' s) := mdifferentiableOn_iff_of_mem_maximalAtlas (chart_mem_maximalAtlas x) @@ -391,7 +372,7 @@ that this set lies in `(extChartAt I x).target`. -/ theorem mdifferentiableOn_iff_of_subset_source' {x : M} {y : M'} (hs : s ⊆ (extChartAt I x).source) (h2s : MapsTo f s (extChartAt I' y).source) : - MDifferentiableOn I I' f s ↔ + MDiff[s] f ↔ DifferentiableOn 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) (extChartAt I x '' s) := by rw [extChartAt_source] at hs h2s exact mdifferentiableOn_iff_of_mem_maximalAtlas' (chart_mem_maximalAtlas x) @@ -400,7 +381,7 @@ theorem mdifferentiableOn_iff_of_subset_source' /-- One can reformulate smoothness on a set as continuity on this set, and smoothness in any extended chart. -/ theorem mdifferentiableOn_iff : - MDifferentiableOn I I' f s ↔ + MDiff[s] f ↔ ContinuousOn f s ∧ ∀ (x : M) (y : M'), DifferentiableOn 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) @@ -428,10 +409,9 @@ theorem mdifferentiableOn_iff : /-- One can reformulate smoothness on a set as continuity on this set, and smoothness in any extended chart in the target. -/ theorem mdifferentiableOn_iff_target : - MDifferentiableOn I I' f s ↔ + MDiff[s] f ↔ ContinuousOn f s ∧ - ∀ y : M', MDifferentiableOn I 𝓘(𝕜, E') (extChartAt I' y ∘ f) - (s ∩ f ⁻¹' (extChartAt I' y).source) := by + ∀ y : M', MDiff[s ∩ f ⁻¹' (extChartAt I' y).source] (extChartAt I' y ∘ f) := by simp only [mdifferentiableOn_iff, ModelWithCorners.source_eq, chartAt_self_eq, OpenPartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_trans, extChartAt, OpenPartialHomeomorph.extend, Set.preimage_univ, Set.inter_univ, and_congr_right_iff] @@ -445,7 +425,7 @@ theorem mdifferentiableOn_iff_target : /-- One can reformulate smoothness as continuity and smoothness in any extended chart. -/ theorem mdifferentiable_iff : - MDifferentiable I I' f ↔ + MDiff f ↔ Continuous f ∧ ∀ (x : M) (y : M'), DifferentiableOn 𝕜 (extChartAt I' y ∘ f ∘ (extChartAt I x).symm) @@ -456,9 +436,9 @@ theorem mdifferentiable_iff : /-- One can reformulate smoothness as continuity and smoothness in any extended chart in the target. -/ theorem mdifferentiable_iff_target : - MDifferentiable I I' f ↔ + MDiff f ↔ Continuous f ∧ ∀ y : M', - MDifferentiableOn I 𝓘(𝕜, E') (extChartAt I' y ∘ f) (f ⁻¹' (extChartAt I' y).source) := by + MDiff[f ⁻¹' (extChartAt I' y).source] (extChartAt I' y ∘ f) := by rw [← mdifferentiableOn_univ, mdifferentiableOn_iff_target] simp [continuousOn_univ] @@ -468,37 +448,34 @@ end IsManifold variable {n : WithTop ℕ∞} -theorem ContMDiffWithinAt.mdifferentiableWithinAt (hf : ContMDiffWithinAt I I' n f s x) - (hn : n ≠ 0) : MDifferentiableWithinAt I I' f s x := by - suffices h : MDifferentiableWithinAt I I' f (s ∩ f ⁻¹' (extChartAt I' (f x)).source) x by +theorem ContMDiffWithinAt.mdifferentiableWithinAt (hf : CMDiffAt[s] n f x) (hn : n ≠ 0) : + MDiffAt[s] f x := by + suffices h : MDiffAt[s ∩ f ⁻¹' (extChartAt I' (f x)).source] f x by rwa [mdifferentiableWithinAt_inter'] at h apply hf.1.preimage_mem_nhdsWithin exact extChartAt_source_mem_nhds (f x) rw [mdifferentiableWithinAt_iff] exact ⟨hf.1.mono inter_subset_left, (hf.2.differentiableWithinAt hn).mono (by mfld_set_tac)⟩ -theorem ContMDiffAt.mdifferentiableAt (hf : ContMDiffAt I I' n f x) (hn : n ≠ 0) : - MDifferentiableAt I I' f x := +theorem ContMDiffAt.mdifferentiableAt (hf : CMDiffAt n f x) (hn : n ≠ 0) : MDiffAt f x := mdifferentiableWithinAt_univ.1 <| ContMDiffWithinAt.mdifferentiableWithinAt hf hn -theorem ContMDiff.mdifferentiableAt (hf : ContMDiff I I' n f) (hn : n ≠ 0) : - MDifferentiableAt I I' f x := +theorem ContMDiff.mdifferentiableAt (hf : CMDiff n f) (hn : n ≠ 0) : MDiffAt f x := hf.contMDiffAt.mdifferentiableAt hn -theorem ContMDiff.mdifferentiableWithinAt (hf : ContMDiff I I' n f) (hn : n ≠ 0) : - MDifferentiableWithinAt I I' f s x := +theorem ContMDiff.mdifferentiableWithinAt (hf : CMDiff n f) (hn : n ≠ 0) : MDiffAt[s] f x := (hf.contMDiffAt.mdifferentiableAt hn).mdifferentiableWithinAt -theorem ContMDiffOn.mdifferentiableOn (hf : ContMDiffOn I I' n f s) (hn : n ≠ 0) : - MDifferentiableOn I I' f s := fun x hx => (hf x hx).mdifferentiableWithinAt hn +theorem ContMDiffOn.mdifferentiableOn (hf : CMDiff[s] n f) (hn : n ≠ 0) : MDiff[s] f := + fun x hx => (hf x hx).mdifferentiableWithinAt hn -theorem ContMDiff.mdifferentiable (hf : ContMDiff I I' n f) (hn : n ≠ 0) : MDifferentiable I I' f := +theorem ContMDiff.mdifferentiable (hf : CMDiff n f) (hn : n ≠ 0) : MDiff f := fun x => (hf x).mdifferentiableAt hn -theorem MDifferentiableOn.continuousOn (h : MDifferentiableOn I I' f s) : ContinuousOn f s := +theorem MDifferentiableOn.continuousOn (h : MDiff[s] f) : ContinuousOn f s := fun x hx => (h x hx).continuousWithinAt -theorem MDifferentiable.continuous (h : MDifferentiable I I' f) : Continuous f := +theorem MDifferentiable.continuous (h : MDiff f) : Continuous f := continuous_iff_continuousAt.2 fun x => (h x).continuousAt /-! ### Deriving continuity from differentiability on manifolds -/ @@ -506,25 +483,25 @@ theorem MDifferentiable.continuous (h : MDifferentiable I I' f) : Continuous f : theorem writtenInExtChartAt_comp (h : ContinuousWithinAt f s x) : writtenInExtChartAt I I'' x (g ∘ f) =ᶠ[𝓝[(extChartAt I x).symm ⁻¹' s ∩ range I] (extChartAt I x x)] - (writtenInExtChartAt I' I'' (f x) g ∘ writtenInExtChartAt I I' x f) := by + (writtenInExtChartAt I' I'' (f x) g ∘ writtenInExtChartAt I I' x f) := by apply @Filter.mem_of_superset _ _ (f ∘ (extChartAt I x).symm ⁻¹' (extChartAt I' (f x)).source) _ (extChartAt_preimage_mem_nhdsWithin (h.preimage_mem_nhdsWithin (extChartAt_source_mem_nhds _))) mfld_set_tac -variable {f' f₀' f₁' : TangentSpace I x →L[𝕜] TangentSpace I' (f x)} - {g' : TangentSpace I' (f x) →L[𝕜] TangentSpace I'' (g (f x))} +variable {f' f₀' f₁' : TangentSpace% x →L[𝕜] TangentSpace% (f x)} + {g' : TangentSpace% (f x) →L[𝕜] TangentSpace% (g (f x))} set_option backward.isDefEq.respectTransparency false in /-- `UniqueMDiffWithinAt` achieves its goal: it implies the uniqueness of the derivative. -/ protected nonrec theorem UniqueMDiffWithinAt.eq (U : UniqueMDiffAt[s] x) - (h : HasMFDerivWithinAt I I' f s x f') (h₁ : HasMFDerivWithinAt I I' f s x f₁') : f' = f₁' := by + (h : HasMFDerivAt[s] f x f') (h₁ : HasMFDerivAt[s] f x f₁') : f' = f₁' := by -- `by apply` because the instances can be found in the term but not in the goal. apply U.eq h.2 h₁.2 protected theorem UniqueMDiffOn.eq (U : UniqueMDiff[s]) (hx : x ∈ s) - (h : HasMFDerivWithinAt I I' f s x f') (h₁ : HasMFDerivWithinAt I I' f s x f₁') : f' = f₁' := + (h : HasMFDerivAt[s] f x f') (h₁ : HasMFDerivAt[s] f x f₁') : f' = f₁' := UniqueMDiffWithinAt.eq (U _ hx) h h₁ /-! @@ -534,22 +511,22 @@ We mimic the API for functions between vector spaces -/ @[simp, mfld_simps] -theorem mfderivWithin_univ : mfderivWithin I I' f univ = mfderiv I I' f := by +theorem mfderivWithin_univ : mfderiv[univ] f = mfderiv% f := by ext x : 1 simp only [mfderivWithin, mfderiv, mfld_simps] rw [mdifferentiableWithinAt_univ] set_option backward.isDefEq.respectTransparency false in -theorem mfderivWithin_zero_of_not_mdifferentiableWithinAt - (h : ¬MDifferentiableWithinAt I I' f s x) : mfderivWithin I I' f s x = 0 := by +theorem mfderivWithin_zero_of_not_mdifferentiableWithinAt (h : ¬MDiffAt[s] f x) : + mfderiv[s] f x = 0 := by simp only [mfderivWithin, h, if_neg, not_false_iff] set_option backward.isDefEq.respectTransparency false in -theorem mfderiv_zero_of_not_mdifferentiableAt (h : ¬MDifferentiableAt I I' f x) : - mfderiv I I' f x = 0 := by simp only [mfderiv, h, if_neg, not_false_iff] +theorem mfderiv_zero_of_not_mdifferentiableAt (h : ¬MDiffAt f x) : + mfderiv% f x = 0 := by simp only [mfderiv, h, if_neg, not_false_iff] @[nontriviality] -theorem mdifferentiable_of_subsingleton [Subsingleton E] : MDifferentiable I I' f := by +theorem mdifferentiable_of_subsingleton [Subsingleton E] : MDiff f := by intro x have : Subsingleton H := I.injective.subsingleton have : DiscreteTopology M := discreteTopology H M @@ -557,178 +534,166 @@ theorem mdifferentiable_of_subsingleton [Subsingleton E] : MDifferentiable I I' exact (hasFDerivAt_of_subsingleton _ _).differentiableAt.differentiableWithinAt @[nontriviality] -theorem mdifferentiableWithinAt_of_subsingleton [Subsingleton E] : - MDifferentiableWithinAt I I' f s x := +theorem mdifferentiableWithinAt_of_subsingleton [Subsingleton E] : MDiffAt[s] f x := (mdifferentiable_of_subsingleton x).mdifferentiableWithinAt /-- If `f : M → M'` has injective differential at `x` within `s`, it is `MDifferentiable` at `x` within `s`. -/ -lemma mdifferentiableWithinAt_of_mfderivWithin_injective - (hf : Injective (mfderivWithin I I' f s x)) : - MDifferentiableWithinAt I I' f s x := by +lemma mdifferentiableWithinAt_of_mfderivWithin_injective (hf : Injective (mfderiv[s] f x)) : + MDiffAt[s] f x := by nontriviality E - have : Nontrivial (TangentSpace I x) := inferInstanceAs (Nontrivial E) + have : Nontrivial (TangentSpace% x) := inferInstanceAs (Nontrivial E) contrapose hf rw [mfderivWithin_zero_of_not_mdifferentiableWithinAt hf] exact not_injective_const /-- If `f : M → M'` has injective differential at `x`, it is `MDifferentiable` at `x`. -/ -lemma mdifferentiableAt_of_mfderiv_injective {f : M → M'} (hf : Injective (mfderiv I I' f x)) : - MDifferentiableAt I I' f x := by +lemma mdifferentiableAt_of_mfderiv_injective {f : M → M'} (hf : Injective (mfderiv% f x)) : + MDiffAt f x := by simp only [← mdifferentiableWithinAt_univ, ← mfderivWithin_univ] at hf ⊢ exact mdifferentiableWithinAt_of_mfderivWithin_injective hf -theorem mdifferentiableWithinAt_of_isInvertible_mfderivWithin - (hf : (mfderivWithin I I' f s x).IsInvertible) : MDifferentiableWithinAt I I' f s x := +theorem mdifferentiableWithinAt_of_isInvertible_mfderivWithin (hf : (mfderiv[s] f x).IsInvertible) : + MDiffAt[s] f x := mdifferentiableWithinAt_of_mfderivWithin_injective hf.injective -theorem mdifferentiableAt_of_isInvertible_mfderiv - (hf : (mfderiv I I' f x).IsInvertible) : MDifferentiableAt I I' f x := +theorem mdifferentiableAt_of_isInvertible_mfderiv (hf : (mfderiv% f x).IsInvertible) : + MDiffAt f x := mdifferentiableAt_of_mfderiv_injective hf.injective -theorem HasMFDerivWithinAt.mono (h : HasMFDerivWithinAt I I' f t x f') (hst : s ⊆ t) : - HasMFDerivWithinAt I I' f s x f' := +theorem HasMFDerivWithinAt.mono (h : HasMFDerivAt[t] f x f') (hst : s ⊆ t) : + HasMFDerivAt[s] f x f' := ⟨ContinuousWithinAt.mono h.1 hst, HasFDerivWithinAt.mono h.2 (inter_subset_inter (preimage_mono hst) (Subset.refl _))⟩ -theorem HasMFDerivAt.hasMFDerivWithinAt (h : HasMFDerivAt I I' f x f') : - HasMFDerivWithinAt I I' f s x f' := +theorem HasMFDerivAt.hasMFDerivWithinAt (h : HasMFDerivAt% f x f') : HasMFDerivAt[s] f x f' := ⟨ContinuousAt.continuousWithinAt h.1, HasFDerivWithinAt.mono h.2 inter_subset_right⟩ -theorem HasMFDerivWithinAt.mdifferentiableWithinAt (h : HasMFDerivWithinAt I I' f s x f') : - MDifferentiableWithinAt I I' f s x := +theorem HasMFDerivWithinAt.mdifferentiableWithinAt (h : HasMFDerivAt[s] f x f') : MDiffAt[s] f x := ⟨h.1, ⟨f', h.2⟩⟩ -theorem HasMFDerivAt.mdifferentiableAt (h : HasMFDerivAt I I' f x f') : - MDifferentiableAt I I' f x := by +theorem HasMFDerivAt.mdifferentiableAt (h : HasMFDerivAt% f x f') : MDiffAt f x := by rw [mdifferentiableAt_iff] exact ⟨h.1, ⟨f', h.2⟩⟩ @[simp, mfld_simps] -theorem hasMFDerivWithinAt_univ : - HasMFDerivWithinAt I I' f univ x f' ↔ HasMFDerivAt I I' f x f' := by +theorem hasMFDerivWithinAt_univ : HasMFDerivAt[univ] f x f' ↔ HasMFDerivAt% f x f' := by simp only [HasMFDerivWithinAt, HasMFDerivAt, continuousWithinAt_univ, mfld_simps] -theorem hasMFDerivAt_unique (h₀ : HasMFDerivAt I I' f x f₀') (h₁ : HasMFDerivAt I I' f x f₁') : +theorem hasMFDerivAt_unique (h₀ : HasMFDerivAt% f x f₀') (h₁ : HasMFDerivAt% f x f₁') : f₀' = f₁' := by rw [← hasMFDerivWithinAt_univ] at h₀ h₁ exact (uniqueMDiffWithinAt_univ I).eq h₀ h₁ set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivWithinAt_inter' (h : t ∈ 𝓝[s] x) : - HasMFDerivWithinAt I I' f (s ∩ t) x f' ↔ HasMFDerivWithinAt I I' f s x f' := by + HasMFDerivAt[s ∩ t] f x f' ↔ HasMFDerivAt[s] f x f' := by rw [HasMFDerivWithinAt, HasMFDerivWithinAt, extChartAt_preimage_inter_eq, hasFDerivWithinAt_inter', continuousWithinAt_inter' h] exact extChartAt_preimage_mem_nhdsWithin h set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivWithinAt_inter (h : t ∈ 𝓝 x) : - HasMFDerivWithinAt I I' f (s ∩ t) x f' ↔ HasMFDerivWithinAt I I' f s x f' := by + HasMFDerivAt[s ∩ t] f x f' ↔ HasMFDerivAt[s] f x f' := by rw [HasMFDerivWithinAt, HasMFDerivWithinAt, extChartAt_preimage_inter_eq, hasFDerivWithinAt_inter, continuousWithinAt_inter h] exact extChartAt_preimage_mem_nhds h -theorem HasMFDerivWithinAt.union (hs : HasMFDerivWithinAt I I' f s x f') - (ht : HasMFDerivWithinAt I I' f t x f') : HasMFDerivWithinAt I I' f (s ∪ t) x f' := by +theorem HasMFDerivWithinAt.union (hs : HasMFDerivAt[s] f x f') (ht : HasMFDerivAt[t] f x f') : + HasMFDerivAt[s ∪ t] f x f' := by constructor · exact ContinuousWithinAt.union hs.1 ht.1 · convert! HasFDerivWithinAt.union hs.2 ht.2 using 1 simp only [union_inter_distrib_right, preimage_union] -theorem HasMFDerivWithinAt.mono_of_mem_nhdsWithin - (h : HasMFDerivWithinAt I I' f s x f') (ht : s ∈ 𝓝[t] x) : - HasMFDerivWithinAt I I' f t x f' := +theorem HasMFDerivWithinAt.mono_of_mem_nhdsWithin (h : HasMFDerivAt[s] f x f') (ht : s ∈ 𝓝[t] x) : + HasMFDerivAt[t] f x f' := (hasMFDerivWithinAt_inter' ht).1 (h.mono inter_subset_right) -theorem HasMFDerivWithinAt.hasMFDerivAt (h : HasMFDerivWithinAt I I' f s x f') (hs : s ∈ 𝓝 x) : - HasMFDerivAt I I' f x f' := by +theorem HasMFDerivWithinAt.hasMFDerivAt (h : HasMFDerivAt[s] f x f') (hs : s ∈ 𝓝 x) : + HasMFDerivAt% f x f' := by rwa [← univ_inter s, hasMFDerivWithinAt_inter hs, hasMFDerivWithinAt_univ] at h -theorem MDifferentiableWithinAt.hasMFDerivWithinAt (h : MDifferentiableWithinAt I I' f s x) : - HasMFDerivWithinAt I I' f s x (mfderivWithin I I' f s x) := by +theorem MDifferentiableWithinAt.hasMFDerivWithinAt (h : MDiffAt[s] f x) : + HasMFDerivAt[s] f x (mfderiv[s] f x) := by refine ⟨h.1, ?_⟩ simp only [mfderivWithin, h, mfld_simps] exact DifferentiableWithinAt.hasFDerivWithinAt h.2 theorem mdifferentiableWithinAt_iff_exists_hasMFDerivWithinAt : - MDifferentiableWithinAt I I' f s x ↔ ∃ f', HasMFDerivWithinAt I I' f s x f' := by - refine ⟨fun h ↦ ⟨mfderivWithin I I' f s x, h.hasMFDerivWithinAt⟩, ?_⟩ + MDiffAt[s] f x ↔ ∃ f', HasMFDerivWithinAt I I' f s x f' := by + refine ⟨fun h ↦ ⟨mfderiv[s] f x, h.hasMFDerivWithinAt⟩, ?_⟩ rintro ⟨f', hf'⟩ exact hf'.mdifferentiableWithinAt -theorem MDifferentiableWithinAt.mono_of_mem_nhdsWithin - (h : MDifferentiableWithinAt I I' f s x) {t : Set M} - (hst : s ∈ 𝓝[t] x) : MDifferentiableWithinAt I I' f t x := +theorem MDifferentiableWithinAt.mono_of_mem_nhdsWithin (h : MDiffAt[s] f x) {t : Set M} + (hst : s ∈ 𝓝[t] x) : MDiffAt[t] f x := (h.hasMFDerivWithinAt.mono_of_mem_nhdsWithin hst).mdifferentiableWithinAt -theorem MDifferentiableWithinAt.congr_nhds (h : MDifferentiableWithinAt I I' f s x) {t : Set M} - (hst : 𝓝[s] x = 𝓝[t] x) : MDifferentiableWithinAt I I' f t x := +theorem MDifferentiableWithinAt.congr_nhds (h : MDiffAt[s] f x) {t : Set M} + (hst : 𝓝[s] x = 𝓝[t] x) : MDiffAt[t] f x := h.mono_of_mem_nhdsWithin <| hst ▸ self_mem_nhdsWithin theorem mdifferentiableWithinAt_congr_nhds {t : Set M} (hst : 𝓝[s] x = 𝓝[t] x) : - MDifferentiableWithinAt I I' f s x ↔ MDifferentiableWithinAt I I' f t x := + MDiffAt[s] f x ↔ MDiffAt[t] f x := ⟨fun h => h.congr_nhds hst, fun h => h.congr_nhds hst.symm⟩ set_option backward.isDefEq.respectTransparency false in -protected theorem MDifferentiableWithinAt.mfderivWithin (h : MDifferentiableWithinAt I I' f s x) : - mfderivWithin I I' f s x = +protected theorem MDifferentiableWithinAt.mfderivWithin (h : MDiffAt[s] f x) : + mfderiv[s] f x = fderivWithin 𝕜 (writtenInExtChartAt I I' x f :) ((extChartAt I x).symm ⁻¹' s ∩ range I) ((extChartAt I x) x) := by simp only [mfderivWithin, h, if_pos] -theorem MDifferentiableAt.hasMFDerivAt (h : MDifferentiableAt I I' f x) : - HasMFDerivAt I I' f x (mfderiv I I' f x) := by +theorem MDifferentiableAt.hasMFDerivAt (h : MDiffAt f x) : HasMFDerivAt% f x (mfderiv% f x) := by refine ⟨h.continuousAt, ?_⟩ simp only [mfderiv, h, mfld_simps] exact DifferentiableWithinAt.hasFDerivWithinAt h.differentiableWithinAt_writtenInExtChartAt set_option backward.isDefEq.respectTransparency false in -protected theorem MDifferentiableAt.mfderiv (h : MDifferentiableAt I I' f x) : - mfderiv I I' f x = +protected theorem MDifferentiableAt.mfderiv (h : MDiffAt f x) : + mfderiv% f x = fderivWithin 𝕜 (writtenInExtChartAt I I' x f :) (range I) ((extChartAt I x) x) := by simp only [mfderiv, h, if_pos] -protected theorem HasMFDerivAt.mfderiv (h : HasMFDerivAt I I' f x f') : mfderiv I I' f x = f' := +protected theorem HasMFDerivAt.mfderiv (h : HasMFDerivAt% f x f') : mfderiv% f x = f' := (hasMFDerivAt_unique h h.mdifferentiableAt.hasMFDerivAt).symm -protected theorem HasMFDerivWithinAt.mfderivWithin (h : HasMFDerivWithinAt I I' f s x f') - (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I' f s x = f' := by +protected theorem HasMFDerivWithinAt.mfderivWithin (h : HasMFDerivAt[s] f x f') + (hxs : UniqueMDiffAt[s] x) : mfderiv[s] f x = f' := by ext rw [hxs.eq h h.mdifferentiableWithinAt.hasMFDerivWithinAt] set_option backward.isDefEq.respectTransparency false in theorem HasMFDerivWithinAt.mfderivWithin_eq_zero (h : HasMFDerivWithinAt I I' f s x 0) : - mfderivWithin I I' f s x = 0 := by + mfderiv[s] f x = 0 := by simp only [mfld_simps, mfderivWithin, h.mdifferentiableWithinAt, ↓reduceIte] simp only [HasMFDerivWithinAt, mfld_simps] at h rw [fderivWithin, if_pos] exact h.2 -theorem MDifferentiable.mfderivWithin (h : MDifferentiableAt I I' f x) - (hxs : UniqueMDiffAt[s] x) : mfderivWithin I I' f s x = mfderiv I I' f x := by +theorem MDifferentiable.mfderivWithin (h : MDiffAt f x) (hxs : UniqueMDiffAt[s] x) : + mfderiv[s] f x = mfderiv% f x := by apply HasMFDerivWithinAt.mfderivWithin _ hxs exact h.hasMFDerivAt.hasMFDerivWithinAt -theorem mfderivWithin_subset (st : s ⊆ t) (hs : UniqueMDiffAt[s] x) - (h : MDifferentiableWithinAt I I' f t x) : - mfderivWithin I I' f s x = mfderivWithin I I' f t x := +theorem mfderivWithin_subset (st : s ⊆ t) (hs : UniqueMDiffAt[s] x) (h : MDiffAt[t] f x) : + mfderiv[s] f x = mfderiv[t] f x := ((MDifferentiableWithinAt.hasMFDerivWithinAt h).mono st).mfderivWithin hs -theorem mfderivWithin_inter (ht : t ∈ 𝓝 x) : - mfderivWithin I I' f (s ∩ t) x = mfderivWithin I I' f s x := by +theorem mfderivWithin_inter (ht : t ∈ 𝓝 x) : mfderiv[s ∩ t] f x = mfderiv[s] f x := by rw [mfderivWithin, mfderivWithin, extChartAt_preimage_inter_eq, mdifferentiableWithinAt_inter ht, fderivWithin_inter (extChartAt_preimage_mem_nhds ht)] -theorem mfderivWithin_of_mem_nhds (h : s ∈ 𝓝 x) : mfderivWithin I I' f s x = mfderiv I I' f x := by +theorem mfderivWithin_of_mem_nhds (h : s ∈ 𝓝 x) : mfderiv[s] f x = mfderiv% f x := by rw [← mfderivWithin_univ, ← univ_inter s, mfderivWithin_inter h] -lemma mfderivWithin_of_isOpen (hs : IsOpen s) (hx : x ∈ s) : - mfderivWithin I I' f s x = mfderiv I I' f x := +lemma mfderivWithin_of_isOpen (hs : IsOpen s) (hx : x ∈ s) : mfderiv[s] f x = mfderiv% f x := mfderivWithin_of_mem_nhds (hs.mem_nhds hx) set_option backward.isDefEq.respectTransparency false in theorem hasMFDerivWithinAt_insert {y : M} : - HasMFDerivWithinAt I I' f (insert y s) x f' ↔ HasMFDerivWithinAt I I' f s x f' := by + HasMFDerivAt[insert y s] f x f' ↔ HasMFDerivAt[s] f x f' := by have : T1Space M := I.t1Space M refine ⟨fun h => h.mono <| subset_insert y s, fun hf ↦ ?_⟩ rcases eq_or_ne x y with rfl | h @@ -751,28 +716,26 @@ theorem hasMFDerivWithinAt_insert {y : M} : alias ⟨HasMFDerivWithinAt.of_insert, HasMFDerivWithinAt.insert'⟩ := hasMFDerivWithinAt_insert -protected theorem HasMFDerivWithinAt.insert (h : HasMFDerivWithinAt I I' f s x f') : - HasMFDerivWithinAt I I' f (insert x s) x f' := +protected theorem HasMFDerivWithinAt.insert (h : HasMFDerivAt[s] f x f') : + HasMFDerivAt[insert x s] f x f' := h.insert' theorem hasMFDerivWithinAt_sdiff_singleton (y : M) : - HasMFDerivWithinAt I I' f (s \ {y}) x f' ↔ HasMFDerivWithinAt I I' f s x f' := by + HasMFDerivAt[s \ {y}] f x f' ↔ HasMFDerivAt[s] f x f' := by rw [← hasMFDerivWithinAt_insert, insert_sdiff_singleton, hasMFDerivWithinAt_insert] @[deprecated (since := "2026-06-03")] alias hasMFDerivWithinAt_diff_singleton := hasMFDerivWithinAt_sdiff_singleton -theorem mfderivWithin_eq_mfderiv (hs : UniqueMDiffAt[s] x) (h : MDifferentiableAt I I' f x) : - mfderivWithin I I' f s x = mfderiv I I' f x := by +theorem mfderivWithin_eq_mfderiv (hs : UniqueMDiffAt[s] x) (h : MDiffAt f x) : + mfderiv[s] f x = mfderiv% f x := by rw [← mfderivWithin_univ] exact mfderivWithin_subset (subset_univ _) hs h.mdifferentiableWithinAt -theorem mdifferentiableWithinAt_insert_self : - MDifferentiableWithinAt I I' f (insert x s) x ↔ MDifferentiableWithinAt I I' f s x := +theorem mdifferentiableWithinAt_insert_self : MDiffAt[insert x s] f x ↔ MDiffAt[s] f x := ⟨fun h ↦ h.mono (subset_insert x s), fun h ↦ h.hasMFDerivWithinAt.insert.mdifferentiableWithinAt⟩ -theorem mdifferentiableWithinAt_insert {y : M} : - MDifferentiableWithinAt I I' f (insert y s) x ↔ MDifferentiableWithinAt I I' f s x := by +theorem mdifferentiableWithinAt_insert {y : M} : MDiffAt[insert y s] f x ↔ MDiffAt[s] f x := by rcases eq_or_ne x y with (rfl | h) · exact mdifferentiableWithinAt_insert_self have : T1Space M := I.t1Space M @@ -782,8 +745,7 @@ theorem mdifferentiableWithinAt_insert {y : M} : alias ⟨MDifferentiableWithinAt.of_insert, MDifferentiableWithinAt.insert'⟩ := mdifferentiableWithinAt_insert -protected theorem MDifferentiableWithinAt.insert (h : MDifferentiableWithinAt I I' f s x) : - MDifferentiableWithinAt I I' f (insert x s) x := +protected theorem MDifferentiableWithinAt.insert (h : MDiffAt[s] f x) : MDiffAt[insert x s] f x := h.insert' /-! ### Being differentiable on a union of open sets can be tested on each set -/ @@ -792,9 +754,7 @@ section mdifferentiableOn_union /-- If a function is differentiable on two open sets, it is also differentiable on their union. -/ lemma MDifferentiableOn.union_of_isOpen - (hf : MDifferentiableOn I I' f s) (hf' : MDifferentiableOn I I' f t) - (hs : IsOpen s) (ht : IsOpen t) : - MDifferentiableOn I I' f (s ∪ t) := by + (hf : MDiff[s] f) (hf' : MDiff[t] f) (hs : IsOpen s) (ht : IsOpen t) : MDiff[s ∪ t] f := by intro x hx obtain (hx | hx) := hx · exact (hf x hx).mdifferentiableAt (hs.mem_nhds hx) |>.mdifferentiableWithinAt @@ -802,35 +762,31 @@ lemma MDifferentiableOn.union_of_isOpen /-- A function is differentiable on two open sets iff it is differentiable on their union. -/ lemma mdifferentiableOn_union_iff_of_isOpen (hs : IsOpen s) (ht : IsOpen t) : - MDifferentiableOn I I' f (s ∪ t) ↔ MDifferentiableOn I I' f s ∧ MDifferentiableOn I I' f t := + MDiff[s ∪ t] f ↔ MDiff[s] f ∧ MDiff[t] f := ⟨fun h ↦ ⟨h.mono subset_union_left, h.mono subset_union_right⟩, fun ⟨hfs, hft⟩ ↦ MDifferentiableOn.union_of_isOpen hfs hft hs ht⟩ -lemma mdifferentiable_of_mdifferentiableOn_union_of_isOpen (hf : MDifferentiableOn I I' f s) - (hf' : MDifferentiableOn I I' f t) (hst : s ∪ t = univ) (hs : IsOpen s) (ht : IsOpen t) : - MDifferentiable I I' f := by +lemma mdifferentiable_of_mdifferentiableOn_union_of_isOpen (hf : MDiff[s] f) (hf' : MDiff[t] f) + (hst : s ∪ t = univ) (hs : IsOpen s) (ht : IsOpen t) : MDiff f := by rw [← mdifferentiableOn_univ, ← hst] exact hf.union_of_isOpen hf' hs ht /-- If a function is differentiable on open sets `s i`, it is differentiable on their union. -/ -lemma MDifferentiableOn.iUnion_of_isOpen {ι : Type*} {s : ι → Set M} - (hf : ∀ i : ι, MDifferentiableOn I I' f (s i)) (hs : ∀ i, IsOpen (s i)) : - MDifferentiableOn I I' f (⋃ i, s i) := by +lemma MDifferentiableOn.iUnion_of_isOpen + {ι : Type*} {s : ι → Set M} (hf : ∀ i : ι, MDiff[s i] f) (hs : ∀ i, IsOpen (s i)) : + MDiff[⋃ i, s i] f := by rintro x ⟨si, ⟨i, rfl⟩, hxsi⟩ exact (hf i).mdifferentiableAt ((hs i).mem_nhds hxsi) |>.mdifferentiableWithinAt /-- A function is differentiable on a union of open sets `s i` iff it is differentiable on each `s i`. -/ -lemma mdifferentiableOn_iUnion_iff_of_isOpen {ι : Type*} {s : ι → Set M} - (hs : ∀ i, IsOpen (s i)) : - MDifferentiableOn I I' f (⋃ i, s i) ↔ ∀ i : ι, MDifferentiableOn I I' f (s i) := +lemma mdifferentiableOn_iUnion_iff_of_isOpen {ι : Type*} {s : ι → Set M} (hs : ∀ i, IsOpen (s i)) : + MDiff[⋃ i, s i] f ↔ ∀ i : ι, MDiff[s i] f := ⟨fun h i ↦ h.mono <| subset_iUnion_of_subset i fun _ a ↦ a, fun h ↦ MDifferentiableOn.iUnion_of_isOpen h hs⟩ lemma mdifferentiable_of_mdifferentiableOn_iUnion_of_isOpen {ι : Type*} {s : ι → Set M} - (hf : ∀ i : ι, MDifferentiableOn I I' f (s i)) - (hs : ∀ i, IsOpen (s i)) (hs' : ⋃ i, s i = univ) : - MDifferentiable I I' f := by + (hf : ∀ i : ι, MDiff[s i] f) (hs : ∀ i, IsOpen (s i)) (hs' : ⋃ i, s i = univ) : MDiff f := by rw [← mdifferentiableOn_univ, ← hs'] exact MDifferentiableOn.iUnion_of_isOpen hf hs @@ -838,44 +794,40 @@ end mdifferentiableOn_union /-! ### Deriving continuity from differentiability on manifolds -/ -theorem HasMFDerivWithinAt.continuousWithinAt (h : HasMFDerivWithinAt I I' f s x f') : +theorem HasMFDerivWithinAt.continuousWithinAt (h : HasMFDerivAt[s] f x f') : ContinuousWithinAt f s x := h.1 -theorem HasMFDerivAt.continuousAt (h : HasMFDerivAt I I' f x f') : ContinuousAt f x := +theorem HasMFDerivAt.continuousAt (h : HasMFDerivAt% f x f') : ContinuousAt f x := h.1 -theorem tangentMapWithin_subset {p : TangentBundle I M} (st : s ⊆ t) - (hs : UniqueMDiffAt[s] p.1) (h : MDifferentiableWithinAt I I' f t p.1) : - tangentMapWithin I I' f s p = tangentMapWithin I I' f t p := by +theorem tangentMapWithin_subset + {p : TangentBundle I M} (st : s ⊆ t) (hs : UniqueMDiffAt[s] p.1) (h : MDiffAt[t] f p.1) : + tangentMap[s] f p = tangentMap[t] f p := by simp only [tangentMapWithin, mfld_simps] rw [mfderivWithin_subset st hs h] -theorem tangentMapWithin_univ : tangentMapWithin I I' f univ = tangentMap I I' f := by +theorem tangentMapWithin_univ : tangentMap[(univ : Set M)] f = tangentMap% f := by ext p : 1 simp only [tangentMapWithin, tangentMap, mfld_simps] theorem tangentMapWithin_eq_tangentMap {p : TangentBundle I M} (hs : UniqueMDiffAt[s] p.1) - (h : MDifferentiableAt I I' f p.1) : tangentMapWithin I I' f s p = tangentMap I I' f p := by + (h : MDiffAt f p.1) : tangentMap[s] f p = tangentMap% f p := by rw [← mdifferentiableWithinAt_univ] at h rw [← tangentMapWithin_univ] exact tangentMapWithin_subset (subset_univ _) hs h @[simp, mfld_simps] -theorem tangentMapWithin_proj {p : TangentBundle I M} : - (tangentMapWithin I I' f s p).proj = f p.proj := - rfl +theorem tangentMapWithin_proj {p : TangentBundle I M} : (tangentMap[s] f p).proj = f p.proj := rfl @[simp, mfld_simps] -lemma tangentMapWithin_snd {X : TangentSpace I x} : - (tangentMapWithin I I' f s X).2 = (mfderivWithin I I' f s x) X := rfl +lemma tangentMapWithin_snd {X : TangentSpace% x} : (tangentMap[s] f X).2 = (mfderiv[s] f x) X := rfl @[simp, mfld_simps] -theorem tangentMap_proj {p : TangentBundle I M} : (tangentMap I I' f p).proj = f p.proj := - rfl +theorem tangentMap_proj {p : TangentBundle I M} : (tangentMap% f p).proj = f p.proj := rfl @[simp, mfld_simps] -lemma tangentMap_snd {X : TangentSpace I x} : (tangentMap I I' f X).2 = (mfderiv I I' f x) X := rfl +lemma tangentMap_snd {X : TangentSpace% x} : (tangentMap% f X).2 = (mfderiv% f x) X := rfl /-- If two sets coincide locally around `x`, except maybe at a point `y`, then their preimage under `extChartAt x` coincide locally, except maybe at `extChartAt I x x`. -/ @@ -909,7 +861,7 @@ theorem preimage_extChartAt_eventuallyEq_compl_singleton (y : M) (h : s =ᶠ[ /-- If two sets coincide locally, except maybe at a point, then it is equivalent to have a manifold derivative within one or the other. -/ theorem hasMFDerivWithinAt_congr_set' (y : M) (h : s =ᶠ[𝓝[{y}ᶜ] x] t) : - HasMFDerivWithinAt I I' f s x f' ↔ HasMFDerivWithinAt I I' f t x f' := by + HasMFDerivAt[s] f x f' ↔ HasMFDerivAt[t] f x f' := by have : T1Space M := I.t1Space M simp only [HasMFDerivWithinAt] refine and_congr ?_ ?_ @@ -918,26 +870,25 @@ theorem hasMFDerivWithinAt_congr_set' (y : M) (h : s =ᶠ[𝓝[{y}ᶜ] x] t) : exact preimage_extChartAt_eventuallyEq_compl_singleton y h theorem hasMFDerivWithinAt_congr_set (h : s =ᶠ[𝓝 x] t) : - HasMFDerivWithinAt I I' f s x f' ↔ HasMFDerivWithinAt I I' f t x f' := + HasMFDerivAt[s] f x f' ↔ HasMFDerivAt[t] f x f' := hasMFDerivWithinAt_congr_set' x <| h.filter_mono inf_le_left /-- If two sets coincide around a point (except possibly at a single point `y`), then it is equivalent to be differentiable within one or the other set. -/ theorem mdifferentiableWithinAt_congr_set' (y : M) (h : s =ᶠ[𝓝[{y}ᶜ] x] t) : - MDifferentiableWithinAt I I' f s x ↔ MDifferentiableWithinAt I I' f t x := by + MDiffAt[s] f x ↔ MDiffAt[t] f x := by simp only [mdifferentiableWithinAt_iff_exists_hasMFDerivWithinAt] exact exists_congr fun _ => hasMFDerivWithinAt_congr_set' _ h -theorem mdifferentiableWithinAt_congr_set (h : s =ᶠ[𝓝 x] t) : - MDifferentiableWithinAt I I' f s x ↔ MDifferentiableWithinAt I I' f t x := by +theorem mdifferentiableWithinAt_congr_set (h : s =ᶠ[𝓝 x] t) : MDiffAt[s] f x ↔ MDiffAt[t] f x := by simp only [mdifferentiableWithinAt_iff_exists_hasMFDerivWithinAt] exact exists_congr fun _ => hasMFDerivWithinAt_congr_set h /-- If two sets coincide locally, except maybe at a point, then derivatives within these sets are the same. -/ theorem mfderivWithin_congr_set' (y : M) (h : s =ᶠ[𝓝[{y}ᶜ] x] t) : - mfderivWithin I I' f s x = mfderivWithin I I' f t x := by - by_cases hx : MDifferentiableWithinAt I I' f s x + mfderiv[s] f x = mfderiv[t] f x := by + by_cases hx : MDiffAt[s] f x · simp only [mfderivWithin, hx, (mdifferentiableWithinAt_congr_set' y h).1 hx, ↓reduceIte] apply fderivWithin_congr_set' (extChartAt I x x) exact preimage_extChartAt_eventuallyEq_compl_singleton y h @@ -945,31 +896,31 @@ theorem mfderivWithin_congr_set' (y : M) (h : s =ᶠ[𝓝[{y}ᶜ] x] t) : /-- If two sets coincide locally, then derivatives within these sets are the same. -/ -theorem mfderivWithin_congr_set (h : s =ᶠ[𝓝 x] t) : - mfderivWithin I I' f s x = mfderivWithin I I' f t x := +theorem mfderivWithin_congr_set (h : s =ᶠ[𝓝 x] t) : mfderiv[s] f x = mfderiv[t] f x := mfderivWithin_congr_set' x <| h.filter_mono inf_le_left /-- If two sets coincide locally, except maybe at a point, then derivatives within these sets coincide locally. -/ theorem mfderivWithin_eventually_congr_set' (y : M) (h : s =ᶠ[𝓝[{y}ᶜ] x] t) : - ∀ᶠ y in 𝓝 x, mfderivWithin I I' f s y = mfderivWithin I I' f t y := + ∀ᶠ y in 𝓝 x, mfderiv[s] f y = mfderiv[t] f y := (eventually_nhds_nhdsWithin.2 h).mono fun _ => mfderivWithin_congr_set' y /-- If two sets coincide locally, then derivatives within these sets coincide locally. -/ theorem mfderivWithin_eventually_congr_set (h : s =ᶠ[𝓝 x] t) : - ∀ᶠ y in 𝓝 x, mfderivWithin I I' f s y = mfderivWithin I I' f t y := + ∀ᶠ y in 𝓝 x, mfderiv[s] f y = mfderiv[t] f y := mfderivWithin_eventually_congr_set' x <| h.filter_mono inf_le_left -theorem HasMFDerivAt.congr_mfderiv (h : HasMFDerivAt I I' f x f') (h' : f' = f₁') : - HasMFDerivAt I I' f x f₁' := +theorem HasMFDerivAt.congr_mfderiv (h : HasMFDerivAt% f x f') (h' : f' = f₁') : + HasMFDerivAt% f x f₁' := h' ▸ h -theorem HasMFDerivWithinAt.congr_mfderiv (h : HasMFDerivWithinAt I I' f s x f') (h' : f' = f₁') : - HasMFDerivWithinAt I I' f s x f₁' := +theorem HasMFDerivWithinAt.congr_mfderiv (h : HasMFDerivAt[s] f x f') (h' : f' = f₁') : + HasMFDerivAt[s] f x f₁' := h' ▸ h -theorem HasMFDerivWithinAt.congr_of_eventuallyEq (h : HasMFDerivWithinAt I I' f s x f') - (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : HasMFDerivWithinAt I I' f₁ s x f' := by +theorem HasMFDerivWithinAt.congr_of_eventuallyEq + (h : HasMFDerivAt[s] f x f') (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : + HasMFDerivAt[s] f₁ x f' := by refine ⟨ContinuousWithinAt.congr_of_eventuallyEq h.1 h₁ hx, ?_⟩ apply HasFDerivWithinAt.congr_of_eventuallyEq h.2 · have : @@ -980,106 +931,103 @@ theorem HasMFDerivWithinAt.congr_of_eventuallyEq (h : HasMFDerivWithinAt I I' f simp +contextual only [hx, mfld_simps] · simp only [hx, mfld_simps] -theorem HasMFDerivWithinAt.congr_mono (h : HasMFDerivWithinAt I I' f s x f') - (ht : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (h₁ : t ⊆ s) : HasMFDerivWithinAt I I' f₁ t x f' := +theorem HasMFDerivWithinAt.congr_mono + (h : HasMFDerivAt[s] f x f') (ht : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (h₁ : t ⊆ s) : + HasMFDerivAt[t] f₁ x f' := (h.mono h₁).congr_of_eventuallyEq (Filter.mem_inf_of_right ht) hx set_option backward.isDefEq.respectTransparency false in -theorem HasMFDerivAt.congr_of_eventuallyEq (h : HasMFDerivAt I I' f x f') (h₁ : f₁ =ᶠ[𝓝 x] f) : - HasMFDerivAt I I' f₁ x f' := by +theorem HasMFDerivAt.congr_of_eventuallyEq (h : HasMFDerivAt% f x f') (h₁ : f₁ =ᶠ[𝓝 x] f) : + HasMFDerivAt% f₁ x f' := by rw [← hasMFDerivWithinAt_univ] at h ⊢ apply h.congr_of_eventuallyEq _ (mem_of_mem_nhds h₁ :) rwa [nhdsWithin_univ] theorem mdifferentiableWithinAt_congr (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : f₁ x = f x) : - MDifferentiableWithinAt I I' f₁ s x ↔ MDifferentiableWithinAt I I' f s x := + MDiffAt[s] f₁ x ↔ MDiffAt[s] f x := differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_iff h₁ hx -theorem MDifferentiableWithinAt.congr_of_mem - (h : MDifferentiableWithinAt I I' f s x) (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : x ∈ s) : - MDifferentiableWithinAt I I' f₁ s x := +theorem MDifferentiableWithinAt.congr_of_mem (h : MDiffAt[s] f x) (h₁ : ∀ y ∈ s, f₁ y = f y) + (hx : x ∈ s) : MDiffAt[s] f₁ x := differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_of_mem h h₁ hx theorem mdifferentiableWithinAt_congr_of_mem (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : x ∈ s) : - MDifferentiableWithinAt I I' f₁ s x ↔ MDifferentiableWithinAt I I' f s x := + MDiffAt[s] f₁ x ↔ MDiffAt[s] f x := differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_iff_of_mem h₁ hx theorem Filter.EventuallyEq.mdifferentiablefWithinAt_iff (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : - MDifferentiableWithinAt I I' f₁ s x ↔ MDifferentiableWithinAt I I' f s x := + MDiffAt[s] f₁ x ↔ MDiffAt[s] f x := differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_iff_of_eventuallyEq h₁ hx -theorem MDifferentiableWithinAt.congr_of_eventuallyEq (h : MDifferentiableWithinAt I I' f s x) - (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : MDifferentiableWithinAt I I' f₁ s x := +theorem MDifferentiableWithinAt.congr_of_eventuallyEq (h : MDiffAt[s] f x) (h₁ : f₁ =ᶠ[𝓝[s] x] f) + (hx : f₁ x = f x) : MDiffAt[s] f₁ x := (h.hasMFDerivWithinAt.congr_of_eventuallyEq h₁ hx).mdifferentiableWithinAt theorem MDifferentiableWithinAt.congr_of_eventuallyEq_of_mem - (h : MDifferentiableWithinAt I I' f s x) (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : x ∈ s) : - MDifferentiableWithinAt I I' f₁ s x := + (h : MDiffAt[s] f x) (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : x ∈ s) : MDiffAt[s] f₁ x := h.congr_of_eventuallyEq h₁ (mem_of_mem_nhdsWithin hx h₁ :) theorem MDifferentiableWithinAt.congr_of_eventuallyEq_insert - (h : MDifferentiableWithinAt I I' f s x) (h₁ : f₁ =ᶠ[𝓝[insert x s] x] f) : - MDifferentiableWithinAt I I' f₁ s x := + (h : MDiffAt[s] f x) (h₁ : f₁ =ᶠ[𝓝[insert x s] x] f) : MDiffAt[s] f₁ x := (h.insert.congr_of_eventuallyEq_of_mem h₁ (mem_insert x s)).of_insert theorem Filter.EventuallyEq.mdifferentiableWithinAt_iff (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : - MDifferentiableWithinAt I I' f s x ↔ MDifferentiableWithinAt I I' f₁ s x := + MDiffAt[s] f x ↔ MDiffAt[s] f₁ x := mdifferentiablefWithinAt_iff h₁.symm hx.symm -theorem MDifferentiableWithinAt.congr_mono (h : MDifferentiableWithinAt I I' f s x) - (ht : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (h₁ : t ⊆ s) : - MDifferentiableWithinAt I I' f₁ t x := +theorem MDifferentiableWithinAt.congr_mono + (h : MDiffAt[s] f x) (ht : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (h₁ : t ⊆ s) : + MDiffAt[t] f₁ x := (HasMFDerivWithinAt.congr_mono h.hasMFDerivWithinAt ht hx h₁).mdifferentiableWithinAt -theorem MDifferentiableWithinAt.congr (h : MDifferentiableWithinAt I I' f s x) - (ht : ∀ x ∈ s, f₁ x = f x) (hx : f₁ x = f x) : MDifferentiableWithinAt I I' f₁ s x := +theorem MDifferentiableWithinAt.congr + (h : MDiffAt[s] f x) (ht : ∀ x ∈ s, f₁ x = f x) (hx : f₁ x = f x) : + MDiffAt[s] f₁ x := (HasMFDerivWithinAt.congr_mono h.hasMFDerivWithinAt ht hx (Subset.refl _)).mdifferentiableWithinAt /-- Version of `MDifferentiableWithinAt.congr` where `x` need not be contained in `s`, but `f` and `f₁` are equal on a set containing both. -/ -theorem MDifferentiableWithinAt.congr' (h : MDifferentiableWithinAt I I' f s x) - (ht : ∀ x ∈ t, f₁ x = f x) (hst : s ⊆ t) (hxt : x ∈ t) : MDifferentiableWithinAt I I' f₁ s x := +theorem MDifferentiableWithinAt.congr' + (h : MDiffAt[s] f x) (ht : ∀ x ∈ t, f₁ x = f x) (hst : s ⊆ t) (hxt : x ∈ t) : MDiffAt[s] f₁ x := h.congr (fun _y hy ↦ ht _y (hst hy)) (ht x hxt) theorem Filter.EventuallyEq.mdifferentiableAt_iff (h₁ : f₁ =ᶠ[𝓝 x] f) : - MDifferentiableAt I I' f₁ x ↔ MDifferentiableAt I I' f x := + MDiffAt f₁ x ↔ MDiffAt f x := differentiableWithinAt_localInvariantProp.liftPropAt_congr_iff_of_eventuallyEq h₁ -theorem MDifferentiableOn.congr (h : MDifferentiableOn I I' f s) (h₁ : ∀ y ∈ s, f₁ y = f y) : - MDifferentiableOn I I' f₁ s := +theorem MDifferentiableOn.congr (h : MDiff[s] f) (h₁ : ∀ y ∈ s, f₁ y = f y) : MDiff[s] f₁ := differentiableWithinAt_localInvariantProp.liftPropOn_congr h h₁ -theorem mdifferentiableOn_congr (h₁ : ∀ y ∈ s, f₁ y = f y) : - MDifferentiableOn I I' f₁ s ↔ MDifferentiableOn I I' f s := +theorem mdifferentiableOn_congr (h₁ : ∀ y ∈ s, f₁ y = f y) : MDiff[s] f₁ ↔ MDiff[s] f := differentiableWithinAt_localInvariantProp.liftPropOn_congr_iff h₁ -theorem MDifferentiableOn.congr_mono (h : MDifferentiableOn I I' f s) (h' : ∀ x ∈ t, f₁ x = f x) - (h₁ : t ⊆ s) : MDifferentiableOn I I' f₁ t := fun x hx => +theorem MDifferentiableOn.congr_mono (h : MDiff[s] f) (h' : ∀ x ∈ t, f₁ x = f x) (h₁ : t ⊆ s) : + MDiff[t] f₁ := fun x hx => (h x (h₁ hx)).congr_mono h' (h' x hx) h₁ -theorem MDifferentiableAt.congr_of_eventuallyEq (h : MDifferentiableAt I I' f x) - (hL : f₁ =ᶠ[𝓝 x] f) : MDifferentiableAt I I' f₁ x := +theorem MDifferentiableAt.congr_of_eventuallyEq (h : MDiffAt f x) (hL : f₁ =ᶠ[𝓝 x] f) : + MDiffAt f₁ x := (h.hasMFDerivAt.congr_of_eventuallyEq hL).mdifferentiableAt -theorem MDifferentiableWithinAt.mfderivWithin_congr_mono (h : MDifferentiableWithinAt I I' f s x) +theorem MDifferentiableWithinAt.mfderivWithin_congr_mono (h : MDiffAt[s] f x) (hs : ∀ x ∈ t, f₁ x = f x) (hx : f₁ x = f x) (hxt : UniqueMDiffAt[t] x) (h₁ : t ⊆ s) : - mfderivWithin I I' f₁ t x = mfderivWithin I I' f s x := + mfderiv[t] f₁ x = mfderiv[s] f x := (HasMFDerivWithinAt.congr_mono h.hasMFDerivWithinAt hs hx h₁).mfderivWithin hxt -theorem MDifferentiableWithinAt.mfderivWithin_mono (h : MDifferentiableWithinAt I I' f s x) - (hxt : UniqueMDiffAt[t] x) (h₁ : t ⊆ s) : - mfderivWithin I I' f t x = mfderivWithin I I' f s x := +theorem MDifferentiableWithinAt.mfderivWithin_mono + (h : MDiffAt[s] f x) (hxt : UniqueMDiffAt[t] x) (h₁ : t ⊆ s) : + mfderiv[t] f x = mfderiv[s] f x := h.mfderivWithin_congr_mono (fun _ _ ↦ rfl) rfl hxt h₁ theorem MDifferentiableWithinAt.mfderivWithin_mono_of_mem_nhdsWithin - (h : MDifferentiableWithinAt I I' f s x) (hxt : UniqueMDiffAt[t] x) (h₁ : s ∈ 𝓝[t] x) : - mfderivWithin I I' f t x = mfderivWithin I I' f s x := + (h : MDiffAt[s] f x) (hxt : UniqueMDiffAt[t] x) (h₁ : s ∈ 𝓝[t] x) : + mfderiv[t] f x = mfderiv[s] f x := (HasMFDerivWithinAt.mono_of_mem_nhdsWithin h.hasMFDerivWithinAt h₁).mfderivWithin hxt set_option backward.isDefEq.respectTransparency false in theorem Filter.EventuallyEq.mfderivWithin_eq (hL : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : - mfderivWithin I I' f₁ s x = mfderivWithin I I' f s x := by - by_cases h : MDifferentiableWithinAt I I' f s x + mfderiv[s] f₁ x = mfderiv[s] f x := by + by_cases h : MDiffAt[s] f x · unfold mfderivWithin simp only [h, (hL.mdifferentiableWithinAt_iff hx).1 h, ↓reduceIte, writtenInExtChartAt] apply Filter.EventuallyEq.fderivWithin_eq; swap @@ -1092,24 +1040,23 @@ theorem Filter.EventuallyEq.mfderivWithin_eq (hL : f₁ =ᶠ[𝓝[s] x] f) (hx : rwa [← hL.mdifferentiableWithinAt_iff hx] theorem Filter.EventuallyEq.mfderivWithin_eq_of_mem (hL : f₁ =ᶠ[𝓝[s] x] f) (hx : x ∈ s) : - mfderivWithin I I' f₁ s x = mfderivWithin I I' f s x := + mfderiv[s] f₁ x = mfderiv[s] f x := hL.mfderivWithin_eq (mem_of_mem_nhdsWithin hx hL :) theorem mfderivWithin_congr (hL : ∀ x ∈ s, f₁ x = f x) (hx : f₁ x = f x) : - mfderivWithin I I' f₁ s x = mfderivWithin I I' f s x := + mfderiv[s] f₁ x = mfderiv[s] f x := Filter.EventuallyEq.mfderivWithin_eq (Filter.eventuallyEq_of_mem self_mem_nhdsWithin hL) hx theorem mfderivWithin_congr_of_mem (hL : ∀ x ∈ s, f₁ x = f x) (hx : x ∈ s) : - mfderivWithin I I' f₁ s x = mfderivWithin I I' f s x := + mfderiv[s] f₁ x = mfderiv[s] f x := Filter.EventuallyEq.mfderivWithin_eq_of_mem (Filter.eventuallyEq_of_mem self_mem_nhdsWithin hL) hx theorem tangentMapWithin_congr (h : ∀ x ∈ s, f x = f₁ x) (p : TangentBundle I M) (hp : p.1 ∈ s) : - tangentMapWithin I I' f s p = tangentMapWithin I I' f₁ s p := by + tangentMap[s] f p = tangentMap[s] f₁ p := by refine TotalSpace.ext (h p.1 hp) ?_ rw [tangentMapWithin, h p.1 hp, tangentMapWithin, mfderivWithin_congr h (h _ hp)] -theorem Filter.EventuallyEq.mfderiv_eq (hL : f₁ =ᶠ[𝓝 x] f) : - mfderiv I I' f₁ x = mfderiv I I' f x := by +theorem Filter.EventuallyEq.mfderiv_eq (hL : f₁ =ᶠ[𝓝 x] f) : mfderiv% f₁ x = mfderiv% f x := by have A : f₁ x = f x := (mem_of_mem_nhds hL :) rw [← mfderivWithin_univ, ← mfderivWithin_univ] rw [← nhdsWithin_univ] at hL @@ -1118,21 +1065,21 @@ theorem Filter.EventuallyEq.mfderiv_eq (hL : f₁ =ᶠ[𝓝 x] f) : /-- A congruence lemma for `mfderiv`, (ab)using the fact that `TangentSpace I' (f x)` is definitionally equal to `E'`. -/ theorem mfderiv_congr_point {x' : M} (h : x = x') : - @Eq (E →L[𝕜] E') (mfderiv I I' f x) (mfderiv I I' f x') := by subst h; rfl + @Eq (E →L[𝕜] E') (mfderiv% f x) (mfderiv% f x') := by subst h; rfl /-- A congruence lemma for `mfderiv`, (ab)using the fact that `TangentSpace I' (f x)` is definitionally equal to `E'`. -/ theorem mfderiv_congr {f' : M → M'} (h : f = f') : - @Eq (E →L[𝕜] E') (mfderiv I I' f x) (mfderiv I I' f' x) := by subst h; rfl + @Eq (E →L[𝕜] E') (mfderiv% f x) (mfderiv% f' x) := by subst h; rfl /-! ### Composition lemmas -/ variable (x) set_option backward.isDefEq.respectTransparency false in -theorem HasMFDerivWithinAt.comp (hg : HasMFDerivWithinAt I' I'' g u (f x) g') - (hf : HasMFDerivWithinAt I I' f s x f') (hst : s ⊆ f ⁻¹' u) : - HasMFDerivWithinAt I I'' (g ∘ f) s x (g'.comp f') := by +theorem HasMFDerivWithinAt.comp (hg : HasMFDerivAt[u] g (f x) g') + (hf : HasMFDerivAt[s] f x f') (hst : s ⊆ f ⁻¹' u) : + HasMFDerivAt[s] (g ∘ f) x (g'.comp f') := by refine ⟨ContinuousWithinAt.comp hg.1 hf.1 hst, ?_⟩ have A : HasFDerivWithinAt (writtenInExtChartAt I' I'' (f x) g ∘ writtenInExtChartAt I I' x f) @@ -1157,164 +1104,140 @@ theorem HasMFDerivWithinAt.comp (hg : HasMFDerivWithinAt I' I'' g u (f x) g') simp only [mfld_simps] /-- The **chain rule for manifolds**. -/ -theorem HasMFDerivAt.comp (hg : HasMFDerivAt I' I'' g (f x) g') (hf : HasMFDerivAt I I' f x f') : - HasMFDerivAt I I'' (g ∘ f) x (g'.comp f') := by +theorem HasMFDerivAt.comp (hg : HasMFDerivAt% g (f x) g') (hf : HasMFDerivAt% f x f') : + HasMFDerivAt% (g ∘ f) x (g'.comp f') := by rw [← hasMFDerivWithinAt_univ] at * exact HasMFDerivWithinAt.comp x (hg.mono (subset_univ _)) hf subset_preimage_univ -theorem HasMFDerivAt.comp_hasMFDerivWithinAt (hg : HasMFDerivAt I' I'' g (f x) g') - (hf : HasMFDerivWithinAt I I' f s x f') : - HasMFDerivWithinAt I I'' (g ∘ f) s x (g'.comp f') := by +theorem HasMFDerivAt.comp_hasMFDerivWithinAt (hg : HasMFDerivAt% g (f x) g') + (hf : HasMFDerivAt[s] f x f') : HasMFDerivAt[s] (g ∘ f) x (g'.comp f') := by rw [← hasMFDerivWithinAt_univ] at * exact HasMFDerivWithinAt.comp x (hg.mono (subset_univ _)) hf subset_preimage_univ -theorem MDifferentiableWithinAt.comp (hg : MDifferentiableWithinAt I' I'' g u (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) : - MDifferentiableWithinAt I I'' (g ∘ f) s x := by +theorem MDifferentiableWithinAt.comp (hg : MDiffAt[u] g (f x)) (hf : MDiffAt[s] f x) + (h : s ⊆ f ⁻¹' u) : MDifferentiableWithinAt I I'' (g ∘ f) s x := by rcases hf.2 with ⟨f', hf'⟩ - have F : HasMFDerivWithinAt I I' f s x f' := ⟨hf.1, hf'⟩ + have F : HasMFDerivAt[s] f x f' := ⟨hf.1, hf'⟩ rcases hg.2 with ⟨g', hg'⟩ - have G : HasMFDerivWithinAt I' I'' g u (f x) g' := ⟨hg.1, hg'⟩ + have G : HasMFDerivAt[u] g (f x) g' := ⟨hg.1, hg'⟩ exact (HasMFDerivWithinAt.comp x G F h).mdifferentiableWithinAt -theorem MDifferentiableWithinAt.comp_of_eq {y : M'} (hg : MDifferentiableWithinAt I' I'' g u y) - (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hy : f x = y) : - MDifferentiableWithinAt I I'' (g ∘ f) s x := by +theorem MDifferentiableWithinAt.comp_of_eq + {y : M'} (hg : MDiffAt[u] g y) (hf : MDiffAt[s] f x) (h : s ⊆ f ⁻¹' u) (hy : f x = y) : + MDiffAt[s] (g ∘ f) x := by subst hy; exact hg.comp _ hf h theorem MDifferentiableWithinAt.comp_of_preimage_mem_nhdsWithin - (hg : MDifferentiableWithinAt I' I'' g u (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (h : f ⁻¹' u ∈ 𝓝[s] x) : - MDifferentiableWithinAt I I'' (g ∘ f) s x := + (hg : MDiffAt[u] g (f x)) (hf : MDiffAt[s] f x) (h : f ⁻¹' u ∈ 𝓝[s] x) : MDiffAt[s] (g ∘ f) x := (hg.comp _ (hf.mono inter_subset_right) inter_subset_left).mono_of_mem_nhdsWithin (Filter.inter_mem h self_mem_nhdsWithin) -theorem MDifferentiableWithinAt.comp_of_preimage_mem_nhdsWithin_of_eq {y : M'} - (hg : MDifferentiableWithinAt I' I'' g u y) - (hf : MDifferentiableWithinAt I I' f s x) (h : f ⁻¹' u ∈ 𝓝[s] x) (hy : f x = y) : +theorem MDifferentiableWithinAt.comp_of_preimage_mem_nhdsWithin_of_eq + {y : M'} (hg : MDiffAt[u] g y) (hf : MDiffAt[s] f x) (h : f ⁻¹' u ∈ 𝓝[s] x) (hy : f x = y) : MDifferentiableWithinAt I I'' (g ∘ f) s x := by subst hy; exact MDifferentiableWithinAt.comp_of_preimage_mem_nhdsWithin _ hg hf h -theorem MDifferentiableAt.comp (hg : MDifferentiableAt I' I'' g (f x)) - (hf : MDifferentiableAt I I' f x) : MDifferentiableAt I I'' (g ∘ f) x := +theorem MDifferentiableAt.comp (hg : MDiffAt g (f x)) (hf : MDiffAt f x) : MDiffAt (g ∘ f) x := (hg.hasMFDerivAt.comp x hf.hasMFDerivAt).mdifferentiableAt -theorem MDifferentiableAt.comp_of_eq {y : M'} (hg : MDifferentiableAt I' I'' g y) - (hf : MDifferentiableAt I I' f x) (hy : f x = y) : MDifferentiableAt I I'' (g ∘ f) x := by +theorem MDifferentiableAt.comp_of_eq {y : M'} (hg : MDiffAt g y) (hf : MDiffAt f x) (hy : f x = y) : + MDiffAt (g ∘ f) x := by subst hy; exact hg.comp _ hf theorem MDifferentiableAt.comp_mdifferentiableWithinAt - (hg : MDifferentiableAt I' I'' g (f x)) (hf : MDifferentiableWithinAt I I' f s x) : - MDifferentiableWithinAt I I'' (g ∘ f) s x := by + (hg : MDiffAt g (f x)) (hf : MDiffAt[s] f x) : MDiffAt[s] (g ∘ f) x := by rw [← mdifferentiableWithinAt_univ] at hg exact hg.comp _ hf (by simp) -theorem MDifferentiableAt.comp_mdifferentiableWithinAt_of_eq {y : M'} - (hg : MDifferentiableAt I' I'' g y) (hf : MDifferentiableWithinAt I I' f s x) (hy : f x = y) : - MDifferentiableWithinAt I I'' (g ∘ f) s x := by +theorem MDifferentiableAt.comp_mdifferentiableWithinAt_of_eq + {y : M'} (hg : MDiffAt g y) (hf : MDiffAt[s] f x) (hy : f x = y) : MDiffAt[s] (g ∘ f) x := by subst hy; exact hg.comp_mdifferentiableWithinAt _ hf -theorem mfderivWithin_comp (hg : MDifferentiableWithinAt I' I'' g u (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) : - mfderivWithin I I'' (g ∘ f) s x = - (mfderivWithin I' I'' g u (f x)).comp (mfderivWithin I I' f s x) := by +theorem mfderivWithin_comp + (hg : MDiffAt[u] g (f x)) (hf : MDiffAt[s] f x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) : + mfderiv[s] (g ∘ f) x = (mfderiv[u] g (f x)).comp (mfderiv[s] f x) := by apply HasMFDerivWithinAt.mfderivWithin _ hxs exact HasMFDerivWithinAt.comp x hg.hasMFDerivWithinAt hf.hasMFDerivWithinAt h -theorem mfderivWithin_comp_of_eq {x : M} {y : M'} (hg : MDifferentiableWithinAt I' I'' g u y) - (hf : MDifferentiableWithinAt I I' f s x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) - (hy : f x = y) : - mfderivWithin I I'' (g ∘ f) s x = - (mfderivWithin I' I'' g u y).comp (mfderivWithin I I' f s x) := by +theorem mfderivWithin_comp_of_eq {x : M} {y : M'} (hg : MDiffAt[u] g y) + (hf : MDiffAt[s] f x) (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : + mfderiv[s] (g ∘ f) x = (mfderiv[u] g y).comp (mfderiv[s] f x) := by subst hy; exact mfderivWithin_comp x hg hf h hxs -theorem mfderivWithin_comp_of_preimage_mem_nhdsWithin - (hg : MDifferentiableWithinAt I' I'' g u (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (h : f ⁻¹' u ∈ 𝓝[s] x) - (hxs : UniqueMDiffAt[s] x) : - mfderivWithin I I'' (g ∘ f) s x = - (mfderivWithin I' I'' g u (f x)).comp (mfderivWithin I I' f s x) := by +theorem mfderivWithin_comp_of_preimage_mem_nhdsWithin (hg : MDiffAt[u] g (f x)) + (hf : MDiffAt[s] f x) (h : f ⁻¹' u ∈ 𝓝[s] x) (hxs : UniqueMDiffAt[s] x) : + mfderiv[s] (g ∘ f) x = (mfderiv[u] g (f x)).comp (mfderiv[s] f x) := by have A : s ∩ f ⁻¹' u ∈ 𝓝[s] x := Filter.inter_mem self_mem_nhdsWithin h - have B : mfderivWithin I I'' (g ∘ f) s x = mfderivWithin I I'' (g ∘ f) (s ∩ f ⁻¹' u) x := by + have B : mfderiv[s] (g ∘ f) x = mfderiv[s ∩ f ⁻¹' u] (g ∘ f) x := by apply MDifferentiableWithinAt.mfderivWithin_mono_of_mem_nhdsWithin _ hxs A exact hg.comp _ (hf.mono inter_subset_left) inter_subset_right - have C : mfderivWithin I I' f s x = mfderivWithin I I' f (s ∩ f ⁻¹' u) x := + have C : mfderiv[s] f x = mfderiv[s ∩ f ⁻¹' u] f x := MDifferentiableWithinAt.mfderivWithin_mono_of_mem_nhdsWithin (hf.mono inter_subset_left) hxs A rw [B, C] exact mfderivWithin_comp _ hg (hf.mono inter_subset_left) inter_subset_right (hxs.inter' h) theorem mfderivWithin_comp_of_preimage_mem_nhdsWithin_of_eq {y : M'} - (hg : MDifferentiableWithinAt I' I'' g u y) - (hf : MDifferentiableWithinAt I I' f s x) (h : f ⁻¹' u ∈ 𝓝[s] x) - (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : - mfderivWithin I I'' (g ∘ f) s x = - (mfderivWithin I' I'' g u y).comp (mfderivWithin I I' f s x) := by + (hg : MDiffAt[u] g y) (hf : MDiffAt[s] f x) (h : f ⁻¹' u ∈ 𝓝[s] x) (hxs : UniqueMDiffAt[s] x) + (hy : f x = y) : mfderiv[s] (g ∘ f) x = (mfderiv[u] g y).comp (mfderiv[s] f x) := by subst hy; exact mfderivWithin_comp_of_preimage_mem_nhdsWithin _ hg hf h hxs -theorem mfderiv_comp_mfderivWithin (hg : MDifferentiableAt I' I'' g (f x)) - (hf : MDifferentiableWithinAt I I' f s x) (hxs : UniqueMDiffAt[s] x) : - mfderivWithin I I'' (g ∘ f) s x = - (mfderiv I' I'' g (f x)).comp (mfderivWithin I I' f s x) := by +theorem mfderiv_comp_mfderivWithin (hg : MDiffAt g (f x)) (hf : MDiffAt[s] f x) + (hxs : UniqueMDiffAt[s] x) : + mfderiv[s] (g ∘ f) x = (mfderiv% g (f x)).comp (mfderiv[s] f x) := by rw [← mfderivWithin_univ] exact mfderivWithin_comp _ hg.mdifferentiableWithinAt hf (by simp) hxs -theorem mfderiv_comp_mfderivWithin_of_eq {x : M} {y : M'} (hg : MDifferentiableAt I' I'' g y) - (hf : MDifferentiableWithinAt I I' f s x) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : - mfderivWithin I I'' (g ∘ f) s x = - (mfderiv I' I'' g y).comp (mfderivWithin I I' f s x) := by +theorem mfderiv_comp_mfderivWithin_of_eq {x : M} {y : M'} (hg : MDiffAt g y) + (hf : MDiffAt[s] f x) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : + mfderiv[s] (g ∘ f) x = (mfderiv% g y).comp (mfderiv[s] f x) := by subst hy; exact mfderiv_comp_mfderivWithin x hg hf hxs -theorem mfderiv_comp (hg : MDifferentiableAt I' I'' g (f x)) (hf : MDifferentiableAt I I' f x) : - mfderiv I I'' (g ∘ f) x = (mfderiv I' I'' g (f x)).comp (mfderiv I I' f x) := by +theorem mfderiv_comp (hg : MDiffAt g (f x)) (hf : MDiffAt f x) : + mfderiv% (g ∘ f) x = (mfderiv% g (f x)).comp (mfderiv% f x) := by apply HasMFDerivAt.mfderiv exact HasMFDerivAt.comp x hg.hasMFDerivAt hf.hasMFDerivAt -theorem mfderiv_comp_of_eq {x : M} {y : M'} (hg : MDifferentiableAt I' I'' g y) - (hf : MDifferentiableAt I I' f x) (hy : f x = y) : - mfderiv I I'' (g ∘ f) x = (mfderiv I' I'' g (f x)).comp (mfderiv I I' f x) := by +theorem mfderiv_comp_of_eq {x : M} {y : M'} (hg : MDiffAt g y) (hf : MDiffAt f x) (hy : f x = y) : + mfderiv% (g ∘ f) x = (mfderiv% g (f x)).comp (mfderiv% f x) := by subst hy; exact mfderiv_comp x hg hf -theorem mfderiv_comp_apply (hg : MDifferentiableAt I' I'' g (f x)) - (hf : MDifferentiableAt I I' f x) (v : TangentSpace I x) : - mfderiv I I'' (g ∘ f) x v = (mfderiv I' I'' g (f x)) ((mfderiv I I' f x) v) := by +theorem mfderiv_comp_apply (hg : MDiffAt g (f x)) (hf : MDiffAt f x) (v : TangentSpace% x) : + mfderiv% (g ∘ f) x v = (mfderiv% g (f x)) ((mfderiv% f x) v) := by rw [mfderiv_comp _ hg hf] rfl -theorem mfderiv_comp_apply_of_eq {y : M'} (hg : MDifferentiableAt I' I'' g y) - (hf : MDifferentiableAt I I' f x) (hy : f x = y) (v : TangentSpace I x) : - mfderiv I I'' (g ∘ f) x v = (mfderiv I' I'' g y) ((mfderiv I I' f x) v) := by +theorem mfderiv_comp_apply_of_eq + {y : M'} (hg : MDiffAt g y) (hf : MDiffAt f x) (hy : f x = y) (v : TangentSpace% x) : + mfderiv% (g ∘ f) x v = (mfderiv% g y) ((mfderiv% f x) v) := by subst hy; exact mfderiv_comp_apply _ hg hf v -theorem MDifferentiableOn.comp (hg : MDifferentiableOn I' I'' g u) (hf : MDifferentiableOn I I' f s) - (st : s ⊆ f ⁻¹' u) : MDifferentiableOn I I'' (g ∘ f) s := fun x hx => +theorem MDifferentiableOn.comp (hg : MDiff[u] g) (hf : MDiff[s] f) (st : s ⊆ f ⁻¹' u) : + MDiff[s] (g ∘ f) := fun x hx => MDifferentiableWithinAt.comp x (hg (f x) (st hx)) (hf x hx) st -theorem MDifferentiable.comp_mdifferentiableOn (hg : MDifferentiable I' I'' g) - (hf : MDifferentiableOn I I' f s) : MDifferentiableOn I I'' (g ∘ f) s := by +theorem MDifferentiable.comp_mdifferentiableOn (hg : MDiff g) (hf : MDiff[s] f) : + MDiff[s] (g ∘ f) := by rw [← mdifferentiableOn_univ] at hg exact hg.comp hf (by simp) -theorem MDifferentiable.comp (hg : MDifferentiable I' I'' g) (hf : MDifferentiable I I' f) : - MDifferentiable I I'' (g ∘ f) := fun x => MDifferentiableAt.comp x (hg (f x)) (hf x) +theorem MDifferentiable.comp (hg : MDiff g) (hf : MDiff f) : MDiff (g ∘ f) := + fun x => MDifferentiableAt.comp x (hg (f x)) (hf x) -theorem tangentMapWithin_comp_at (p : TangentBundle I M) - (hg : MDifferentiableWithinAt I' I'' g u (f p.1)) (hf : MDifferentiableWithinAt I I' f s p.1) - (h : s ⊆ f ⁻¹' u) (hps : UniqueMDiffAt[s] p.1) : - tangentMapWithin I I'' (g ∘ f) s p = - tangentMapWithin I' I'' g u (tangentMapWithin I I' f s p) := by +theorem tangentMapWithin_comp_at (p : TangentBundle I M) (hg : MDiffAt[u] g (f p.1)) + (hf : MDiffAt[s] f p.1) (h : s ⊆ f ⁻¹' u) (hps : UniqueMDiffAt[s] p.1) : + tangentMap[s] (g ∘ f) p = tangentMap[u] g (tangentMap[s] f p) := by simp only [tangentMapWithin, mfld_simps] rw [mfderivWithin_comp p.1 hg hf h hps] rfl -theorem tangentMap_comp_at (p : TangentBundle I M) (hg : MDifferentiableAt I' I'' g (f p.1)) - (hf : MDifferentiableAt I I' f p.1) : - tangentMap I I'' (g ∘ f) p = tangentMap I' I'' g (tangentMap I I' f p) := by +theorem tangentMap_comp_at (p : TangentBundle I M) (hg : MDiffAt g (f p.1)) (hf : MDiffAt f p.1) : + tangentMap% (g ∘ f) p = tangentMap% g (tangentMap% f p) := by simp only [tangentMap, mfld_simps] rw [mfderiv_comp p.1 hg hf] rfl -theorem tangentMap_comp (hg : MDifferentiable I' I'' g) (hf : MDifferentiable I I' f) : - tangentMap I I'' (g ∘ f) = tangentMap I' I'' g ∘ tangentMap I I' f := by +theorem tangentMap_comp (hg : MDiff g) (hf : MDiff f) : + tangentMap% (g ∘ f) = tangentMap% g ∘ tangentMap% f := by ext p : 1; exact tangentMap_comp_at _ (hg _) (hf _) end DerivativesProperties From e86c4a1abe2c47eb7674d245289adbb21fc680d9 Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Fri, 17 Jul 2026 10:50:01 +0000 Subject: [PATCH 0848/1300] chore: rename `OpenPartialHomeomorph.to_isOpenEmbedding` (#41854) As requested in a PR review [here](https://github.com/leanprover-community/mathlib4/pull/41045#discussion_r3493300962). I also included a correction of a different docstring. --- Mathlib/Geometry/Manifold/Instances/Sphere.lean | 2 +- Mathlib/Topology/OpenPartialHomeomorph/Basic.lean | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Instances/Sphere.lean b/Mathlib/Geometry/Manifold/Instances/Sphere.lean index 519ef7731cd5cd..ea27f5a75ea293 100644 --- a/Mathlib/Geometry/Manifold/Instances/Sphere.lean +++ b/Mathlib/Geometry/Manifold/Instances/Sphere.lean @@ -307,7 +307,7 @@ theorem range_stereographic_symm (hv : ‖v‖ = 1) (hv' : v ∈ sphere 0 1 := b lemma isOpenEmbedding_stereographic_symm (hv : ‖v‖ = 1) : Topology.IsOpenEmbedding (stereographic hv).symm := - (stereographic hv).symm.to_isOpenEmbedding (by simp) + (stereographic hv).symm.isOpenEmbedding (by simp) end StereographicProjection diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean index bb87598e2874a5..bf365a5092deb1 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean @@ -15,8 +15,8 @@ public import Mathlib.Topology.Sets.Opens ## Main definitions * `OpenPartialHomeomorph.refl`: the identity open partial homeomorphism -* `Topology.IsOpenEmbedding.toOpenPartialHomeomorph`: construct a partial homeomorphism from an - open embedding +* `Topology.IsOpenEmbedding.toOpenPartialHomeomorph`: construct an open partial homeomorphism from + an open embedding -/ @[expose] public section @@ -224,10 +224,12 @@ theorem isOpenEmbedding_restrict : IsOpenEmbedding (e.source.restrict e) := by /-- An open partial homeomorphism whose source is all of `X` defines an open embedding of `X` into `Y`. The converse is also true; see `IsOpenEmbedding.toOpenPartialHomeomorph`. -/ -theorem to_isOpenEmbedding (h : e.source = Set.univ) : IsOpenEmbedding e := +theorem isOpenEmbedding (h : e.source = Set.univ) : IsOpenEmbedding e := e.isOpenEmbedding_restrict.comp ((Homeomorph.setCongr h).trans <| Homeomorph.Set.univ X).symm.isOpenEmbedding +@[deprecated (since := "2026-07-17")] alias to_isOpenEmbedding := isOpenEmbedding + end OpenPartialHomeomorph /-! @@ -239,7 +241,7 @@ variable (f : X → Y) (h : IsOpenEmbedding f) /-- An open embedding of `X` into `Y`, with `X` nonempty, defines an open partial homeomorphism whose source is all of `X`. The converse is also true; see -`OpenPartialHomeomorph.to_isOpenEmbedding`. -/ +`OpenPartialHomeomorph.isOpenEmbedding`. -/ @[simps! (attr := mfld_simps) -fullyApplied apply source target] noncomputable def toOpenPartialHomeomorph [Nonempty X] : OpenPartialHomeomorph X Y := OpenPartialHomeomorph.ofContinuousOpen (h.isEmbedding.injective.injOn.toPartialEquiv f univ) From 7c8ff804e2608c13c288de9a42c3a5771f124d58 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Fri, 17 Jul 2026 11:15:37 +0000 Subject: [PATCH 0849/1300] chore(Algebra/Category/ModuleCat/Stalk): avoid heartbeat modification (#40982) Splitting up a `simp only` to get under the threshhold. Right now this is the only remaining heartbeat modification in mathlib. Co-authored-by: Batixx --- Mathlib/Algebra/Category/ModuleCat/Stalk.lean | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean index aa61c5a60d282a..9b08de80664e8a 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Stalk.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Stalk.lean @@ -57,10 +57,8 @@ def colimit.smul (r : (R ⋙ forget _).ColimitType) (m : (M ⋙ forget _).Colimi refine Functor.ιColimitType_eq_of_map_eq_map _ _ _ α β ?_ simp [*, ← R.map_comp_apply, ← M.map_comp_apply, -Functor.map_comp] -#adaptation_note /-- As of nightly-2026-02-10, we need to increase the maxHeartbeats limits here. -/ set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in -set_option synthInstance.maxHeartbeats 40000 in -- /-- (Implementation). The module structure on `AddCommGrpCat.FilteredColimits.colimit`. -/ noncomputable abbrev filteredColimitsModule : Module (RingCat.FilteredColimits.colimit R) (AddCommGrpCat.FilteredColimits.colimit M) where @@ -96,7 +94,12 @@ noncomputable abbrev filteredColimitsModule : Module (RingCat.FilteredColimits.c (rightToMax V₁ V₂ ≫ rightToMax U (max V₁ V₂)) refine Functor.ιColimitType_eq_of_map_eq_map _ _ _ β α ?_ dsimp - simp only [*, ← ConcreteCategory.comp_apply, ← Functor.map_comp, map_add, smul_add] + -- We use this pattern instead of a single `simp` to avoid heatbeat modifications + rw [H, H, H] + simp only [← ConcreteCategory.comp_apply, ← Functor.map_comp] + simp only [map_add, ← ConcreteCategory.comp_apply, ← Functor.map_comp, h₁, h₂, h₃, h₄, H] + simp only [Functor.map_comp, RingCat.hom_comp, RingHom.coe_comp, Function.comp_apply, + Category.assoc, AddCommGrpCat.hom_comp, AddMonoidHom.coe_comp, smul_add] add_smul r s m := Quot.induction_on₃ r s m <| by rintro ⟨U₁, a₁⟩ ⟨U₂, a₂⟩ ⟨V, b⟩ obtain ⟨s, α, β, h₁, h₂, h₃, h₄⟩ := crown₄ @@ -113,7 +116,7 @@ noncomputable abbrev filteredColimitsModule : Module (RingCat.FilteredColimits.c rintro ⟨V, b⟩ refine Functor.ιColimitType_eq_of_map_eq_map _ _ _ (𝟙 _) (leftToMax _ _) ?_ dsimp - simp only [map_zero, zero_smul, *] + simp only [map_zero, zero_smul] /-- Given a cofiltered diagram of rings `R`, and a module `M` over `R`, this is the `colim R`-module structure of `colim M`. -/ From d4519b399018129db0a28eda3488eddfed9f73c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 17 Jul 2026 11:15:40 +0000 Subject: [PATCH 0850/1300] chore(Data/ENat): replace `coe` with `natCast` in lemma names (#41140) ... following the naming convention --- Mathlib/Algebra/Module/SpanRank.lean | 2 +- .../Polynomial/Degree/TrailingDegree.lean | 14 +- Mathlib/Analysis/Analytic/Order.lean | 18 +- Mathlib/Analysis/Calculus/SmoothSeries.lean | 2 +- Mathlib/Analysis/Convex/Radon.lean | 6 +- .../Distribution/SchwartzSpace/Deriv.lean | 2 +- Mathlib/Analysis/Meromorphic/NormalForm.lean | 2 +- Mathlib/Analysis/Meromorphic/Order.lean | 6 +- .../Abelian/Injective/Dimension.lean | 4 +- .../Abelian/Projective/Dimension.lean | 4 +- .../Combinatorics/Matroid/IndepAxioms.lean | 4 +- .../SimpleGraph/Coloring/Vertex.lean | 10 +- .../Connectivity/EdgeConnectivity.lean | 4 +- Mathlib/Combinatorics/SimpleGraph/Diam.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Girth.lean | 10 +- Mathlib/Combinatorics/SimpleGraph/Metric.lean | 12 +- .../SimpleGraph/VertexCover.lean | 2 +- Mathlib/Data/ENat/Basic.lean | 173 ++++++++++++------ Mathlib/Data/ENat/BigOperators.lean | 4 +- Mathlib/Data/ENat/Defs.lean | 5 +- Mathlib/Data/ENat/Lattice.lean | 47 +++-- Mathlib/Data/ENat/Pow.lean | 6 +- Mathlib/Data/Nat/Multiplicity.lean | 6 +- Mathlib/Data/Seq/Basic.lean | 2 +- Mathlib/Data/Set/Card.lean | 10 +- Mathlib/Data/Set/PowersetCard.lean | 4 +- .../TopologicalEntropy/CoverEntropy.lean | 6 +- .../TopologicalEntropy/NetEntropy.lean | 8 +- .../Dynamics/TopologicalEntropy/Subset.lean | 2 +- .../GroupAction/MultiplePrimitivity.lean | 4 +- .../GroupTheory/Perm/MaximalSubgroups.lean | 2 +- Mathlib/MeasureTheory/Measure/Restrict.lean | 2 +- .../LevelOne/DimensionFormula.lean | 2 +- .../NumberField/Cyclotomic/Ideal.lean | 2 +- .../NumberTheory/Padics/PadicVal/Basic.lean | 3 +- Mathlib/Order/KrullDimension.lean | 22 +-- .../Probability/Martingale/BorelCantelli.lean | 2 +- .../Martingale/OptionalStopping.lean | 4 +- .../Probability/Martingale/Upcrossing.lean | 4 +- Mathlib/Probability/Process/Stopping.lean | 2 +- .../DedekindDomain/AdicValuation.lean | 8 +- .../DiscreteValuationRing/Basic.lean | 6 +- Mathlib/RingTheory/Ideal/Height.lean | 2 +- .../RingTheory/Ideal/KrullsHeightTheorem.lean | 12 +- Mathlib/RingTheory/Ideal/NatInt.lean | 2 +- Mathlib/RingTheory/Multiplicity.lean | 8 +- .../MvPowerSeries/NoZeroDivisors.lean | 8 +- Mathlib/RingTheory/MvPowerSeries/Order.lean | 20 +- .../RingTheory/MvPowerSeries/PiTopology.lean | 2 +- .../RingTheory/OrderOfVanishing/Basic.lean | 2 +- .../OrderOfVanishing/Noetherian.lean | 6 +- .../Polynomial/Eisenstein/Distinguished.lean | 6 +- Mathlib/RingTheory/PowerSeries/Order.lean | 8 +- .../RamificationInertia/Ramification.lean | 6 +- .../Multiplicity.lean | 4 +- Mathlib/SetTheory/Cardinal/Embedding.lean | 8 +- Mathlib/SetTheory/Cardinal/NatCount.lean | 2 +- Mathlib/Tactic/ENatToNat.lean | 8 +- .../Topology/CWComplex/Classical/Basic.lean | 9 +- .../Topology/Instances/AddCircle/Defs.lean | 4 +- Mathlib/Topology/Instances/ENat.lean | 2 +- 61 files changed, 321 insertions(+), 238 deletions(-) diff --git a/Mathlib/Algebra/Module/SpanRank.lean b/Mathlib/Algebra/Module/SpanRank.lean index 559adf4c06ed9e..fac00f334ee0fe 100644 --- a/Mathlib/Algebra/Module/SpanRank.lean +++ b/Mathlib/Algebra/Module/SpanRank.lean @@ -196,7 +196,7 @@ theorem FG.exists_span_finset_card_eq_spanFinrank {p : Submodule R M} (h : p.FG) obtain ⟨s, ⟨hs₁, hs₂⟩⟩ := exists_span_set_encard_eq_spanFinrank h have s_f := Set.finite_of_encard_eq_coe hs₁ refine ⟨s_f.toFinset, ⟨?_, by simpa using hs₂⟩⟩ - simpa [s_f.encard_eq_coe_toFinset_card, ENat.coe_inj] using hs₁ + simpa [s_f.encard_eq_coe_toFinset_card, ENat.natCast_inj] using hs₁ lemma lift_spanRank_le_iff_exists_span_set_card_le (p : Submodule R M) {a : Cardinal.{max u v}} : Cardinal.lift.{v} p.spanRank ≤ a ↔ ∃ s : Set M, Cardinal.lift.{v} #s ≤ a ∧ span R s = p := by diff --git a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean index cb762e933de609..a8cad592992e73 100644 --- a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean @@ -92,7 +92,7 @@ theorem trailingDegree_eq_top : trailingDegree p = ⊤ ↔ p = 0 := theorem trailingDegree_eq_natTrailingDegree (hp : p ≠ 0) : trailingDegree p = (natTrailingDegree p : ℕ∞) := - .symm <| ENat.coe_toNat <| mt trailingDegree_eq_top.1 hp + .symm <| ENat.natCast_toNat <| mt trailingDegree_eq_top.1 hp theorem trailingDegree_eq_iff_natTrailingDegree_eq {p : R[X]} {n : ℕ} (hp : p ≠ 0) : p.trailingDegree = n ↔ p.natTrailingDegree = n := by @@ -108,7 +108,7 @@ theorem natTrailingDegree_eq_of_trailingDegree_eq_some {p : R[X]} {n : ℕ} @[simp] theorem natTrailingDegree_le_trailingDegree : ↑(natTrailingDegree p) ≤ trailingDegree p := - ENat.coe_toNat_le_self _ + ENat.natCast_toNat_le_self _ theorem natTrailingDegree_eq_of_trailingDegree_eq [Semiring S] {q : S[X]} (h : trailingDegree p = trailingDegree q) : natTrailingDegree p = natTrailingDegree q := by @@ -119,7 +119,7 @@ theorem trailingDegree_le_of_ne_zero (h : coeff p n ≠ 0) : trailingDegree p min_le (mem_support_iff.2 h) theorem natTrailingDegree_le_of_ne_zero (h : coeff p n ≠ 0) : natTrailingDegree p ≤ n := - ENat.toNat_le_of_le_coe <| trailingDegree_le_of_ne_zero h + ENat.toNat_le_of_le_natCast <| trailingDegree_le_of_ne_zero h @[simp] lemma coeff_natTrailingDegree_eq_zero : coeff p p.natTrailingDegree = 0 ↔ p = 0 := by constructor @@ -156,7 +156,7 @@ theorem trailingCoeff_eq_coeff_zero (h : coeff p 0 ≠ 0) : trailingCoeff p = co theorem trailingDegree_ne_of_natTrailingDegree_ne {n : ℕ} : p.natTrailingDegree ≠ n → trailingDegree p ≠ n := - mt fun h => by rw [natTrailingDegree, h, ENat.toNat_coe] + mt fun h => by rw [natTrailingDegree, h, ENat.toNat_natCast] theorem natTrailingDegree_le_of_trailingDegree_le {n : ℕ} {hp : p ≠ 0} (H : (n : ℕ∞) ≤ trailingDegree p) : n ≤ natTrailingDegree p := by @@ -300,7 +300,7 @@ theorem le_natTrailingDegree_mul (h : p * q ≠ 0) : p.natTrailingDegree + q.natTrailingDegree ≤ (p * q).natTrailingDegree := by have hp : p ≠ 0 := fun hp => h (by rw [hp, zero_mul]) have hq : q ≠ 0 := fun hq => h (by rw [hq, mul_zero]) - rw [← ENat.coe_le_coe, ENat.coe_add, ← trailingDegree_eq_natTrailingDegree hp, + rw [← ENat.natCast_le_natCast, ENat.natCast_add, ← trailingDegree_eq_natTrailingDegree hp, ← trailingDegree_eq_natTrailingDegree hq, ← trailingDegree_eq_natTrailingDegree h] exact le_trailingDegree_mul @@ -325,7 +325,7 @@ theorem trailingDegree_mul' (h : p.trailingCoeff * q.trailingCoeff ≠ 0) : have hq : q ≠ 0 := fun hq => h (by rw [hq, trailingCoeff_zero, mul_zero]) refine le_antisymm ?_ le_trailingDegree_mul rw [trailingDegree_eq_natTrailingDegree hp, trailingDegree_eq_natTrailingDegree hq, ← - ENat.coe_add] + ENat.natCast_add] apply trailingDegree_le_of_ne_zero rwa [coeff_mul_natTrailingDegree_add_natTrailingDegree] @@ -334,7 +334,7 @@ theorem natTrailingDegree_mul' (h : p.trailingCoeff * q.trailingCoeff ≠ 0) : have hp : p ≠ 0 := fun hp => h (by rw [hp, trailingCoeff_zero, zero_mul]) have hq : q ≠ 0 := fun hq => h (by rw [hq, trailingCoeff_zero, mul_zero]) apply natTrailingDegree_eq_of_trailingDegree_eq_some - rw [trailingDegree_mul' h, ENat.coe_add, ← trailingDegree_eq_natTrailingDegree hp, + rw [trailingDegree_mul' h, ENat.natCast_add, ← trailingDegree_eq_natTrailingDegree hp, ← trailingDegree_eq_natTrailingDegree hq] theorem natTrailingDegree_mul [NoZeroDivisors R] (hp : p ≠ 0) (hq : q ≠ 0) : diff --git a/Mathlib/Analysis/Analytic/Order.lean b/Mathlib/Analysis/Analytic/Order.lean index 15629de78bf86b..2c16752f28d89b 100644 --- a/Mathlib/Analysis/Analytic/Order.lean +++ b/Mathlib/Analysis/Analytic/Order.lean @@ -69,7 +69,7 @@ lemma analyticOrderNatAt_of_not_analyticAt (hf : ¬ AnalyticAt 𝕜 f z₀) : analyticOrderNatAt f z₀ = 0 := by simp [analyticOrderNatAt, hf] @[simp] lemma Nat.cast_analyticOrderNatAt (hf : analyticOrderAt f z₀ ≠ ⊤) : - analyticOrderNatAt f z₀ = analyticOrderAt f z₀ := ENat.coe_toNat hf + analyticOrderNatAt f z₀ = analyticOrderAt f z₀ := ENat.natCast_toNat hf /-- The order of a function `f` at a `z₀` is infinity iff `f` vanishes locally around `z₀`. -/ lemma analyticOrderAt_eq_top : analyticOrderAt f z₀ = ⊤ ↔ ∀ᶠ z in 𝓝 z₀, f z = 0 where @@ -88,7 +88,7 @@ lemma AnalyticAt.analyticOrderAt_eq_natCast (hf : AnalyticAt 𝕜 f z₀) : ∃ (g : 𝕜 → E), AnalyticAt 𝕜 g z₀ ∧ g z₀ ≠ 0 ∧ ∀ᶠ z in 𝓝 z₀, f z = (z - z₀) ^ n • g z := by unfold analyticOrderAt split_ifs with h - · simp only [ENat.top_ne_coe, false_iff] + · simp only [ENat.top_ne_natCast, false_iff] contrapose h rw [← hf.exists_eventuallyEq_pow_smul_nonzero_iff] exact ⟨n, h⟩ @@ -114,12 +114,12 @@ lemma AnalyticAt.analyticOrderAt_ne_top (hf : AnalyticAt 𝕜 f z₀) : analyticOrderAt f z₀ ≠ ⊤ ↔ ∃ (g : 𝕜 → E), AnalyticAt 𝕜 g z₀ ∧ g z₀ ≠ 0 ∧ f =ᶠ[𝓝 z₀] fun z ↦ (z - z₀) ^ analyticOrderNatAt f z₀ • g z := by - simp only [← ENat.coe_toNat_eq_self, Eq.comm, EventuallyEq, ← hf.analyticOrderAt_eq_natCast, + simp only [← ENat.natCast_toNat_eq_self, Eq.comm, EventuallyEq, ← hf.analyticOrderAt_eq_natCast, analyticOrderNatAt] lemma analyticOrderAt_eq_zero : analyticOrderAt f z₀ = 0 ↔ ¬ AnalyticAt 𝕜 f z₀ ∨ f z₀ ≠ 0 := by by_cases hf : AnalyticAt 𝕜 f z₀ - · rw [← ENat.coe_zero, hf.analyticOrderAt_eq_natCast] + · rw [← ENat.natCast_zero, hf.analyticOrderAt_eq_natCast] constructor · intro ⟨g, _, _, hg⟩ simpa [hf, hg.self_of_nhds] @@ -157,7 +157,7 @@ lemma natCast_le_analyticOrderAt (hf : AnalyticAt 𝕜 f z₀) {n : ℕ} : · simpa using ⟨0, analyticAt_const .., by simpa⟩ · let m := (hf.exists_eventuallyEq_pow_smul_nonzero_iff.mpr h).choose obtain ⟨g, hg, hg_ne, hm⟩ := (hf.exists_eventuallyEq_pow_smul_nonzero_iff.mpr h).choose_spec - rw [ENat.coe_le_coe] + rw [ENat.natCast_le_natCast] refine ⟨fun hmn ↦ ⟨fun z ↦ (z - z₀) ^ (m - n) • g z, by fun_prop, ?_⟩, fun ⟨h, hh, hfh⟩ ↦ ?_⟩ · filter_upwards [hm] with z hz using by rwa [← mul_smul, ← pow_add, Nat.add_sub_of_le hmn] · contrapose! hg_ne @@ -249,7 +249,7 @@ lemma analyticOrderAt_smul {f : 𝕜 → 𝕜} (hf : AnalyticAt 𝕜 f z₀) (hg -- Non-trivial case: both functions do not vanish around z₀ obtain ⟨f', h₁f', h₂f', h₃f'⟩ := hf.analyticOrderAt_ne_top.1 hf' obtain ⟨g', h₁g', h₂g', h₃g'⟩ := hg.analyticOrderAt_ne_top.1 hg' - rw [← Nat.cast_analyticOrderNatAt hf', ← Nat.cast_analyticOrderNatAt hg', ← ENat.coe_add, + rw [← Nat.cast_analyticOrderNatAt hf', ← Nat.cast_analyticOrderNatAt hg', ← ENat.natCast_add, (hf.smul hg).analyticOrderAt_eq_natCast] refine ⟨f' • g', h₁f'.smul h₁g', ?_, ?_⟩ · simp @@ -273,7 +273,7 @@ theorem AnalyticAt.analyticOrderAt_deriv_add_one {x : 𝕜} (hf : AnalyticAt | coe r => have hrne : r ≠ 0 := by intro hr - rw [hr, ENat.coe_zero, AnalyticAt.analyticOrderAt_eq_zero (by fun_prop)] at h + rw [hr, ENat.natCast_zero, AnalyticAt.analyticOrderAt_eq_zero (by fun_prop)] at h grind obtain ⟨s, rfl⟩ := Nat.exists_add_one_eq.mpr (Nat.pos_of_ne_zero hrne) rw [Nat.cast_succ] @@ -297,7 +297,7 @@ theorem AnalyticAt.analyticOrderAt_deriv_add_one {x : 𝕜} (hf : AnalyticAt · simp_rw [← Nat.cast_smul_eq_nsmul 𝕜] fun_prop rwa [← Pi.add_def, analyticOrderAt_add_eq_right_of_lt] - rw [this, ← ENat.add_one_le_iff (ENat.coe_ne_top _), ← Nat.cast_add_one, + rw [this, ← ENat.add_one_le_iff (ENat.natCast_ne_top _), ← Nat.cast_add_one, natCast_le_analyticOrderAt (by fun_prop)] exact ⟨deriv F, hFa.deriv, by simp⟩ @@ -545,7 +545,7 @@ lemma AnalyticAt.analyticOrderAt_comp (hf : AnalyticAt 𝕜 f (g z₀)) (hg : An rw [eventuallyConst_iff_analyticOrderAt_sub_eq_top] at hg_nc obtain ⟨r, hr⟩ := ENat.ne_top_iff_exists.mp hf' obtain ⟨s, hs⟩ := ENat.ne_top_iff_exists.mp hg_nc - rw [← hr, ← hs, ← ENat.coe_mul, (hf.comp hg).analyticOrderAt_eq_natCast] + rw [← hr, ← hs, ← ENat.natCast_mul, (hf.comp hg).analyticOrderAt_eq_natCast] rw [Eq.comm, hf.analyticOrderAt_eq_natCast] at hr rcases hr with ⟨F, hFa, hFne, hfF⟩ rw [Eq.comm, AnalyticAt.analyticOrderAt_eq_natCast (by fun_prop)] at hs diff --git a/Mathlib/Analysis/Calculus/SmoothSeries.lean b/Mathlib/Analysis/Calculus/SmoothSeries.lean index 2984a03a9df601..73c763dade6705 100644 --- a/Mathlib/Analysis/Calculus/SmoothSeries.lean +++ b/Mathlib/Analysis/Calculus/SmoothSeries.lean @@ -236,7 +236,7 @@ theorem contDiff_tsum (hf : ∀ i, ContDiff 𝕜 N (f i)) (hv : ∀ k : ℕ, (k exact h'f _ _ _ hm · intro m hm have h'm : ((m + 1 : ℕ) : ℕ∞) ≤ N := by - simpa only [ENat.coe_add, ENat.coe_one] using Order.add_one_le_of_lt hm + simpa only [ENat.natCast_add, ENat.natCast_one] using Order.add_one_le_of_lt hm rw [iteratedFDeriv_tsum hf hv h'f hm.le] have A n x : HasFDerivAt (iteratedFDeriv 𝕜 m (f n)) (fderiv 𝕜 (iteratedFDeriv 𝕜 m (f n)) x) x := (ContDiff.differentiable_iteratedFDeriv (mod_cast hm) diff --git a/Mathlib/Analysis/Convex/Radon.lean b/Mathlib/Analysis/Convex/Radon.lean index 9043ab54a482d4..92941191aaa3c9 100644 --- a/Mathlib/Analysis/Convex/Radon.lean +++ b/Mathlib/Analysis/Convex/Radon.lean @@ -268,14 +268,14 @@ theorem helly_theorem_set_compact [TopologicalSpace E] [T2Space E] {F : Set (Set (⋂₀ (F : Set (Set E))).Nonempty := by apply helly_theorem_set_compact' h_convex h_compact intro I hI_ss hI_card - obtain ⟨J, _, hJ_ss, hJ_card⟩ := exists_superset_subset_encard_eq hI_ss (hkt := h_card) - (by simpa only [encard_coe_eq_coe_finsetCard, ← ENat.coe_one, ← ENat.coe_add, Nat.cast_le]) + obtain ⟨J, _, hJ_ss, hJ_card⟩ := exists_superset_subset_encard_eq hI_ss (by norm_cast) h_card apply Set.Nonempty.mono <| sInter_mono (by simpa [hI_ss]) have hJ_fin : Fintype J := Finite.fintype <| finite_of_encard_eq_coe hJ_card let J' := J.toFinset rw [← coe_toFinset J] apply h_inter J' · simpa [J'] - · rwa [encard_eq_coe_toFinset_card J, ← ENat.coe_one, ← ENat.coe_add, Nat.cast_inj] at hJ_card + · rwa [encard_eq_coe_toFinset_card J, ← ENat.natCast_one, ← ENat.natCast_add, Nat.cast_inj] + at hJ_card end Convex diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean index a2fb1ea5576e0f..9efebf08e07e4c 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean @@ -137,7 +137,7 @@ theorem iteratedLineDerivOp_eq_iteratedFDeriv {n : ℕ} {m : Fin n → E} {f : rw [iteratedLineDerivOp_succ_left, iteratedFDeriv_succ_apply_left, ← fderiv_continuousMultilinear_apply_const_apply] · simp only [lineDerivOp_apply_eq_fderiv, ← ih] - · exact (f.smooth ⊤).differentiable_iteratedFDeriv (mod_cast ENat.coe_lt_top n) x + · exact (f.smooth ⊤).differentiable_iteratedFDeriv (mod_cast ENat.natCast_lt_top n) x end fderiv diff --git a/Mathlib/Analysis/Meromorphic/NormalForm.lean b/Mathlib/Analysis/Meromorphic/NormalForm.lean index 5613f1682eebf0..013745f17b20d1 100644 --- a/Mathlib/Analysis/Meromorphic/NormalForm.lean +++ b/Mathlib/Analysis/Meromorphic/NormalForm.lean @@ -79,7 +79,7 @@ theorem meromorphicNFAt_iff_analyticAt_or : · right use analyticOrderNatAt f x have : analyticOrderAt f x ≠ ⊤ := h₂f - rw [← ENat.coe_toNat_eq_self, eq_comm, h.analyticOrderAt_eq_natCast] at this + rw [← ENat.natCast_toNat_eq_self, eq_comm, h.analyticOrderAt_eq_natCast] at this obtain ⟨g, h₁g, h₂g, h₃g⟩ := this use g, h₁g, h₂g simpa diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index 9feef0df65c452..c6c76d27223ebb 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -79,7 +79,7 @@ lemma meromorphicOrderAt_eq_top_iff : filter_upwards [h] with z hf hz rwa [smul_eq_zero_iff_right <| pow_ne_zero _ (sub_ne_zero.mpr hz)] at hf · obtain ⟨m, hm⟩ := ENat.ne_top_iff_exists.mp h - simp only [← hm, ENat.coe_ne_top, false_iff] + simp only [← hm, ENat.natCast_ne_top, false_iff] contrapose h rw [analyticOrderAt_eq_top] rw [← hf.choose_spec.frequently_eq_iff_eventually_eq analyticAt_const] @@ -110,7 +110,7 @@ lemma meromorphicOrderAt_eq_int_iff {n : ℤ} (hf : MeromorphicAt f x) : meromor rwa [hfz_eq hz, ← mul_smul, smul_eq_zero_iff_right] at hfz exact mul_ne_zero (pow_ne_zero _ (sub_ne_zero.mpr hz)) (zpow_ne_zero _ (sub_ne_zero.mpr hz)) · obtain ⟨m, h⟩ := ENat.ne_top_iff_exists.mp h - rw [← h, ENat.map_coe, ← WithTop.coe_natCast, ← coe_sub, WithTop.coe_inj] + rw [← h, ENat.map_natCast, ← WithTop.coe_natCast, ← coe_sub, WithTop.coe_inj] obtain ⟨g, hg_an, hg_ne, hg_eq⟩ := hf.choose_spec.analyticOrderAt_eq_natCast.mp h.symm replace hg_eq : ∀ᶠ (z : 𝕜) in 𝓝[≠] x, f z = (z - x) ^ (↑m - ↑hf.choose : ℤ) • g z := by rw [eventually_nhdsWithin_iff] @@ -285,7 +285,7 @@ lemma AnalyticAt.meromorphicOrderAt_eq (hf : AnalyticAt 𝕜 f x) : cases hn : analyticOrderAt f x · rw [ENat.map_top, meromorphicOrderAt_eq_top_iff] exact (analyticOrderAt_eq_top.mp hn).filter_mono nhdsWithin_le_nhds - · simp_rw [ENat.map_coe, meromorphicOrderAt_eq_int_iff hf.meromorphicAt, zpow_natCast] + · simp_rw [ENat.map_natCast, meromorphicOrderAt_eq_int_iff hf.meromorphicAt, zpow_natCast] rcases hf.analyticOrderAt_eq_natCast.mp hn with ⟨g, h1, h2, h3⟩ exact ⟨g, h1, h2, h3.filter_mono nhdsWithin_le_nhds⟩ diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean index 76019033f4d785..c688fbac4d02f9 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Dimension.lean @@ -315,9 +315,9 @@ lemma injectiveDimension_ne_top_iff (X : C) : simp only [WithBot.coe_top, ne_eq, not_true_eq_false, false_and, true_and, false_or] at this obtain ⟨n, hn⟩ := this rw [← injectiveDimension_le_iff, hd, WithBot.coe_top, top_le_iff] at hn - exact ENat.coe_ne_top _ ((WithBot.coe_eq_coe).1 hn) + exact ENat.natCast_ne_top _ ((WithBot.coe_eq_coe).1 hn) | coe d => - simp only [ne_eq, WithBot.coe_eq_top, ENat.coe_ne_top, not_false_eq_true, true_iff] + simp only [ne_eq, WithBot.coe_eq_top, ENat.natCast_ne_top, not_false_eq_true, true_iff] exact ⟨d, by simpa only [← injectiveDimension_le_iff] using! hd.le⟩ end CategoryTheory diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean index 6c57f6199672c2..d0129e75b71cb3 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Dimension.lean @@ -320,9 +320,9 @@ lemma projectiveDimension_ne_top_iff (X : C) : simp only [WithBot.coe_top, ne_eq, not_true_eq_false, false_and, true_and, false_or] at this obtain ⟨n, hn⟩ := this rw [← projectiveDimension_le_iff, hd, WithBot.coe_top, top_le_iff] at hn - exact ENat.coe_ne_top _ ((WithBot.coe_eq_coe).1 hn) + exact ENat.natCast_ne_top _ ((WithBot.coe_eq_coe).1 hn) | coe d => - simp only [ne_eq, WithBot.coe_eq_top, ENat.coe_ne_top, not_false_eq_true, true_iff] + simp only [ne_eq, WithBot.coe_eq_top, ENat.natCast_ne_top, not_false_eq_true, true_iff] exact ⟨d, by simpa only [← projectiveDimension_le_iff] using! hd.le⟩ lemma projectiveDimension_eq_zero_iff (X : C) : diff --git a/Mathlib/Combinatorics/Matroid/IndepAxioms.lean b/Mathlib/Combinatorics/Matroid/IndepAxioms.lean index f7db37bf5cfac3..d795f4ad869238 100644 --- a/Mathlib/Combinatorics/Matroid/IndepAxioms.lean +++ b/Mathlib/Combinatorics/Matroid/IndepAxioms.lean @@ -298,11 +298,11 @@ theorem _root_.Matroid.existsMaximalSubsetProperty_of_bdd {P : Set α → Prop} rintro I hI hIX have hfin : Set.Finite (ncard '' {Y | P Y ∧ I ⊆ Y ∧ Y ⊆ X}) := by rw [finite_iff_bddAbove, bddAbove_def] - simp_rw [ENat.le_coe_iff] at hP + simp_rw [ENat.le_natCast_iff] at hP use n rintro x ⟨Y, ⟨hY, -, -⟩, rfl⟩ obtain ⟨n₀, heq, hle⟩ := hP Y hY - rwa [ncard_def, heq, ENat.toNat_coe] + rwa [ncard_def, heq, ENat.toNat_natCast] obtain ⟨Y, ⟨hY, hIY, hYX⟩, hY'⟩ := Finite.exists_maximalFor' ncard _ hfin ⟨I, hI, rfl.subset, hIX⟩ refine ⟨Y, hIY, ⟨hY, hYX⟩, fun K ⟨hPK, hKX⟩ hYK ↦ ?_⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean index 649280b8e6034b..b5feae588bcaeb 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean @@ -238,7 +238,7 @@ lemma chromaticNumber_eq_iInf : G.chromaticNumber = ⨅ n : {m | G.Colorable m}, lemma Colorable.chromaticNumber_eq_sInf (h : G.Colorable n) : G.chromaticNumber = sInf {n' : ℕ | G.Colorable n'} := by - rw [ENat.coe_sInf, chromaticNumber] + rw [ENat.natCast_sInf, chromaticNumber] exact ⟨_, h⟩ variable (G) in @@ -338,7 +338,7 @@ theorem chromaticNumber_ne_top_iff_exists : G.chromaticNumber ≠ ⊤ ↔ ∃ n, theorem chromaticNumber_le_iff_colorable {n : ℕ} : G.chromaticNumber ≤ n ↔ G.Colorable n := by refine ⟨fun h ↦ ?_, Colorable.chromaticNumber_le⟩ - have : G.chromaticNumber ≠ ⊤ := (trans h (ENat.coe_lt_top n)).ne + have : G.chromaticNumber ≠ ⊤ := (trans h (ENat.natCast_lt_top n)).ne rw [chromaticNumber_ne_top_iff_exists] at this obtain ⟨m, hm⟩ := this rw [hm.chromaticNumber_eq_sInf, Nat.cast_le] at h @@ -350,7 +350,7 @@ theorem chromaticNumber_le_iff_colorable {n : ℕ} : G.chromaticNumber ≤ n ↔ colors. -/ theorem chromaticNumber_eq_iff_colorable_not_colorable : G.chromaticNumber = n + 1 ↔ G.Colorable (n + 1) ∧ ¬G.Colorable n := by - rw [eq_iff_le_not_lt, not_lt, ENat.add_one_le_iff (ENat.coe_ne_top n), ← not_le, + rw [eq_iff_le_not_lt, not_lt, ENat.add_one_le_iff (ENat.natCast_ne_top n), ← not_le, chromaticNumber_le_iff_colorable, ← Nat.cast_add_one, chromaticNumber_le_iff_colorable] theorem colorable_chromaticNumber {m : ℕ} (hc : G.Colorable m) : @@ -479,7 +479,7 @@ theorem eq_top_of_chromaticNumber_eq_card [Fintype V] suffices G.Coloring (Finset.univ.erase b) by simpa using Coloring.colorable this apply Coloring.mk (fun x ↦ if h' : x ≠ b then ⟨x, by simp [h']⟩ else ⟨a, by simp [hne]⟩) grind [Adj.ne', adj_symm] - rw [h, ← ENat.coe_one, ← ENat.coe_sub, ENat.coe_le_coe] at this + rw [h, ← ENat.natCast_one, ← ENat.natCast_sub, ENat.natCast_le_natCast] at this have := Fintype.one_lt_card_iff_nontrivial.mpr <| SimpleGraph.nontrivial_iff.mp ⟨_, _, hh⟩ grind @@ -573,7 +573,7 @@ theorem cliqueFree_of_chromaticNumber_lt {n : ℕ} (hc : G.chromaticNumber < n) obtain ⟨m, hc'⟩ := chromaticNumber_ne_top_iff_exists.mp hne have := colorable_chromaticNumber hc' refine this.cliqueFree ?_ - rw [← ENat.coe_toNat_eq_self] at hne + rw [← ENat.natCast_toNat_eq_self] at hne rw [← hne] at hc simpa using hc diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/EdgeConnectivity.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/EdgeConnectivity.lean index 782be9e4aab0f0..f0570db48af00b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/EdgeConnectivity.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/EdgeConnectivity.lean @@ -96,7 +96,7 @@ lemma IsEdgeReachable.le_degree [Fintype (G.neighborSet u)] (h : G.IsEdgeReachab (huv : u ≠ v) : k ≤ G.degree u := by classical by_contra! hh - rw [← card_incidenceSet_eq_degree, ← ENat.coe_lt_coe, Set.coe_fintypeCard] at hh + rw [← card_incidenceSet_eq_degree, ← ENat.natCast_lt_natCast, Set.coe_fintypeCard] at hh obtain ⟨w, _⟩ := h hh |>.exists_isPath simpa using w.adj_snd <| mt Walk.Nil.eq huv @@ -134,7 +134,7 @@ lemma isBridge_iff_not_isEdgeReachable_two (huv : G.Adj u v) : refine ⟨fun h ↦ h.not_isEdgeReachable_two, fun hc hr ↦ hc fun s hs₂ ↦ ?_⟩ by_cases! hs₁ : s.encard ≠ (1 : ℕ) · apply G.isEdgeReachable_one.mpr huv.reachable - exact lt_of_le_of_ne (ENat.lt_coe_add_one_iff.mp hs₂) hs₁ + exact lt_of_le_of_ne (ENat.lt_natCast_add_one_iff.mp hs₂) hs₁ obtain ⟨x, rfl⟩ := s.encard_eq_one.mp hs₁ obtain rfl | hx := eq_or_ne s(u, v) x · exact hr diff --git a/Mathlib/Combinatorics/SimpleGraph/Diam.lean b/Mathlib/Combinatorics/SimpleGraph/Diam.lean index d3a098ab90c523..101630ba2e883b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Diam.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Diam.lean @@ -391,7 +391,7 @@ lemma ediam_eq_top_iff_radius_eq_top [Nonempty α] : G.ediam = ⊤ ↔ G.radius intro hr obtain ⟨w, hw⟩ := G.exists_eccent_eq_radius have hdiam : G.ediam ≤ 2 * G.eccent w := ediam_le_two_mul_eccent w - exact ne_top_of_lt <| lt_of_le_of_lt hdiam <| WithTop.mul_lt_top (ENat.coe_lt_top 2) <| + exact ne_top_of_lt <| lt_of_le_of_lt hdiam <| WithTop.mul_lt_top (ENat.natCast_lt_top 2) <| lt_top_iff_ne_top.mpr (hw ▸ hr) lemma ediam_le_two_mul_radius : G.ediam ≤ 2 * G.radius := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Girth.lean b/Mathlib/Combinatorics/SimpleGraph/Girth.lean index 7b9df7bf40e396..f943d166f869dc 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Girth.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Girth.lean @@ -68,8 +68,8 @@ lemma exists_egirth_eq_length : refine ⟨?_, fun h ↦ ?_⟩ · rintro ⟨a, w, hw, _⟩ hG exact hG _ hw - · simp_rw [← egirth_eq_top, ← Ne.eq_def, egirth, iInf_subtype', iInf_sigma', ENat.iInf_coe_ne_top, - ← exists_prop, Subtype.exists', Sigma.exists', eq_comm] at h ⊢ + · simp_rw [← egirth_eq_top, ← Ne.eq_def, egirth, iInf_subtype', iInf_sigma', + ENat.iInf_natCast_ne_top, ← exists_prop, Subtype.exists', Sigma.exists', eq_comm] at h ⊢ exact ciInf_mem _ lemma three_le_egirth : 3 ≤ G.egirth := by @@ -115,7 +115,7 @@ noncomputable def girth (G : SimpleGraph α) : ℕ := G.egirth.toNat lemma girth_le_length {a} {w : G.Walk a a} (h : w.IsCycle) : G.girth ≤ w.length := - ENat.coe_le_coe.mp <| G.egirth.coe_toNat_le_self.trans <| egirth_le_length h + ENat.natCast_le_natCast.mp <| G.egirth.natCast_toNat_le_self.trans <| egirth_le_length h lemma three_le_girth (hG : ¬ G.IsAcyclic) : 3 ≤ G.girth := ENat.toNat_le_toNat three_le_egirth <| egirth_eq_top.not.mpr hG @@ -130,13 +130,13 @@ lemma girth_anti {G' : SimpleGraph α} (hab : G ≤ G') (h : ¬ G.IsAcyclic) : G lemma Walk.IsCircuit.girth_le_length {a} {w : G.Walk a a} (hwc : w.IsCircuit) : G.girth ≤ w.length := - ENat.coe_le_coe.mp <| G.egirth.coe_toNat_le_self.trans <| hwc.egirth_le_length + ENat.natCast_le_natCast.mp <| G.egirth.natCast_toNat_le_self.trans <| hwc.egirth_le_length lemma exists_girth_eq_length : (∃ (a : α) (w : G.Walk a a), w.IsCycle ∧ G.girth = w.length) ↔ ¬ G.IsAcyclic := by refine ⟨by tauto, fun h ↦ ?_⟩ obtain ⟨_, _, _⟩ := exists_egirth_eq_length.mpr h - simp_all only [girth, ENat.toNat_coe] + simp_all only [girth, ENat.toNat_natCast] tauto @[simp] lemma girth_bot : girth (⊥ : SimpleGraph α) = 0 := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Metric.lean b/Mathlib/Combinatorics/SimpleGraph/Metric.lean index 972055dd8912c8..82f64cc0e67c11 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Metric.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Metric.lean @@ -115,14 +115,14 @@ theorem edist_comm : G.edist u v = G.edist v u := by lemma exists_walk_of_edist_eq_coe {k : ℕ} (h : G.edist u v = k) : ∃ p : G.Walk u v, p.length = k := - have : G.edist u v ≠ ⊤ := by rw [h]; exact ENat.coe_ne_top _ + have : G.edist u v ≠ ⊤ := by rw [h]; exact ENat.natCast_ne_top _ have ⟨p, hp⟩ := exists_walk_of_edist_ne_top this ⟨p, Nat.cast_injective (hp.trans h)⟩ lemma edist_ne_top_iff_reachable : G.edist u v ≠ ⊤ ↔ G.Reachable u v := by refine ⟨reachable_of_edist_ne_top, fun h ↦ ?_⟩ by_contra hx - simp only [edist, iInf_eq_top, ENat.coe_ne_top] at hx + simp only [edist, iInf_eq_top, ENat.natCast_ne_top] at hx exact h.elim hx /-- @@ -213,7 +213,7 @@ theorem dist_eq_sInf : G.dist u v = sInf (Set.range (Walk.length : G.Walk u v @[grind =] lemma Reachable.coe_dist_eq_edist (h : G.Reachable u v) : G.dist u v = G.edist u v := - ENat.coe_toNat <| edist_ne_top_iff_reachable.mpr h + ENat.natCast_toNat <| edist_ne_top_iff_reachable.mpr h protected theorem Reachable.exists_walk_length_eq_dist (hr : G.Reachable u v) : ∃ p : G.Walk u v, p.length = G.dist u v := @@ -278,14 +278,14 @@ lemma Reachable.dist_triangle_left (h : G.Reachable u v) (w) : G.dist u w ≤ G.dist u v + G.dist v w := by by_cases! h' : ¬G.Reachable u w · grind [dist_eq_zero_iff_eq_or_not_reachable] - rw [← ENat.coe_le_coe, ENat.coe_add] + rw [← ENat.natCast_le_natCast, ENat.natCast_add] grind [SimpleGraph.edist_triangle, Reachable.trans, Reachable.symm] lemma Reachable.dist_triangle_right (h : G.Reachable v w) (u) : G.dist u w ≤ G.dist u v + G.dist v w := by by_cases! h' : ¬G.Reachable u w · grind [dist_eq_zero_iff_eq_or_not_reachable] - rw [← ENat.coe_le_coe, ENat.coe_add] + rw [← ENat.natCast_le_natCast, ENat.natCast_add] grind [SimpleGraph.edist_triangle, Reachable.trans, Reachable.symm] theorem dist_comm : G.dist u v = G.dist v u := by @@ -306,7 +306,7 @@ The distance between vertices is equal to `1` if and only if these vertices are -/ @[simp] theorem dist_eq_one_iff_adj : G.dist u v = 1 ↔ G.Adj u v := by - rw [dist, ENat.toNat_eq_iff, ENat.coe_one, edist_eq_one_iff_adj] + rw [dist, ENat.toNat_eq_iff, ENat.natCast_one, edist_eq_one_iff_adj] decide theorem Adj.diff_dist_adj (hadj : G.Adj v w) : diff --git a/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean b/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean index 9ee8b3fb346b87..89fd57f3f80745 100644 --- a/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean +++ b/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean @@ -173,7 +173,7 @@ theorem vertexCoverNum_top : vertexCoverNum (completeGraph V) = ENat.card V - 1 rw [Set.encard_sdiff (by simp) (Set.finite_of_encard_eq_coe ht₁), Set.encard_univ] refine ENat.le_sub_of_add_le_left (by simp [ht₁]) ?_ refine add_le_of_le_tsub_right_of_le (Order.add_one_le_of_lt ENat.one_lt_card) ?_ - grw [ht₁, ENat.coe_sub, hn] + grw [ht₁, ENat.natCast_sub, hn] simp [add_assoc, one_add_one_eq_two, le_tsub_add] obtain ⟨a, b, _, _, hne⟩ := Set.one_lt_encard_iff.mp <| this have := @ht₂ a b (by simp [hne]) diff --git a/Mathlib/Data/ENat/Basic.lean b/Mathlib/Data/ENat/Basic.lean index 51cc047600a5ec..d7ead409489d53 100644 --- a/Mathlib/Data/ENat/Basic.lean +++ b/Mathlib/Data/ENat/Basic.lean @@ -26,7 +26,7 @@ There are two natural coercions from `ℕ` to `WithTop ℕ = ENat`: `WithTop.som Lean 3, this difference was hidden in typeclass instances. Since these instances were definitionally equal, we did not duplicate generic lemmas about `WithTop α` and `WithTop.some` coercion for `ENat` and `Nat.cast` coercion. If you need to apply a lemma about `WithTop`, you may either rewrite back -and forth using `ENat.some_eq_coe`, or restate the lemma for `ENat`. +and forth using `ENat.some_eq_natCast`, or restate the lemma for `ENat`. ## TODO @@ -56,31 +56,47 @@ variable {a b c d m n : ℕ∞} /-- Lemmas about `WithTop` expect (and can output) `WithTop.some` but the normal form for coercion `ℕ → ℕ∞` is `Nat.cast`. -/ -@[simp] theorem some_eq_coe : (WithTop.some : ℕ → ℕ∞) = Nat.cast := rfl +@[simp] theorem some_eq_natCast : (WithTop.some : ℕ → ℕ∞) = Nat.cast := rfl -theorem coe_inj {a b : ℕ} : (a : ℕ∞) = b ↔ a = b := WithTop.coe_inj +@[deprecated (since := "2026-07-17")] alias some_eq_coe := some_eq_natCast -@[simp] theorem succ_coe (n : ℕ) : SuccOrder.succ (n : ℕ∞) = (n + 1 : ℕ) := WithTop.succ_coe +theorem natCast_inj {a b : ℕ} : (a : ℕ∞) = b ↔ a = b := WithTop.coe_inj + +@[deprecated (since := "2026-07-17")] alias coe_inj := natCast_inj + +@[simp] theorem succ_natCast (n : ℕ) : SuccOrder.succ (n : ℕ∞) = (n + 1 : ℕ) := WithTop.succ_coe + +@[deprecated (since := "2026-07-17")] alias succ_coe := succ_natCast @[simp] theorem succ_top : SuccOrder.succ (⊤ : ℕ∞) = ⊤ := rfl instance : SuccAddOrder ℕ∞ where succ_eq_add_one x := by cases x <;> simp -theorem coe_zero : ((0 : ℕ) : ℕ∞) = 0 := +theorem natCast_zero : ((0 : ℕ) : ℕ∞) = 0 := rfl -theorem coe_one : ((1 : ℕ) : ℕ∞) = 1 := +@[deprecated (since := "2026-07-17")] alias coe_zero := natCast_zero + +theorem natCast_one : ((1 : ℕ) : ℕ∞) = 1 := rfl -theorem coe_add (m n : ℕ) : ↑(m + n) = (m + n : ℕ∞) := +@[deprecated (since := "2026-07-17")] alias coe_one := natCast_one + +theorem natCast_add (m n : ℕ) : ↑(m + n) = (m + n : ℕ∞) := rfl +@[deprecated (since := "2026-07-17")] alias coe_add := natCast_add + @[simp, norm_cast] -theorem coe_sub (m n : ℕ) : ↑(m - n) = (m - n : ℕ∞) := +theorem natCast_sub (m n : ℕ) : ↑(m - n) = (m - n : ℕ∞) := rfl -@[simp] lemma coe_mul (m n : ℕ) : ↑(m * n) = (m * n : ℕ∞) := rfl +@[deprecated (since := "2026-07-17")] alias coe_sub := natCast_sub + +@[simp] lemma natCast_mul (m n : ℕ) : ↑(m * n) = (m * n : ℕ∞) := rfl + +@[deprecated (since := "2026-07-17")] alias coe_mul := natCast_mul @[simp] theorem mul_top (hm : m ≠ 0) : m * ⊤ = ⊤ := WithTop.mul_top hm @[simp] theorem top_mul (hm : m ≠ 0) : ⊤ * m = ⊤ := WithTop.top_mul hm @@ -104,25 +120,30 @@ lemma eq_top_of_pow (n : ℕ) (ha : a ^ n = ⊤) : a = ⊤ := WithTop.eq_top_of_ /-- Convert a `ℕ∞` to a `ℕ` using a proof that it is not infinite. -/ def lift (x : ℕ∞) (h : x < ⊤) : ℕ := WithTop.untop x (WithTop.lt_top_iff_ne_top.mp h) -@[simp] theorem coe_lift (x : ℕ∞) (h : x < ⊤) : (lift x h : ℕ∞) = x := +@[simp] theorem natCast_lift (x : ℕ∞) (h : x < ⊤) : (lift x h : ℕ∞) = x := WithTop.coe_untop x (WithTop.lt_top_iff_ne_top.mp h) -@[simp] theorem lift_coe (n : ℕ) : lift (n : ℕ∞) (WithTop.coe_lt_top n) = n := rfl + +@[deprecated (since := "2026-07-17")] alias coe_lift := natCast_lift + +@[simp] theorem lift_natCast (n : ℕ) : lift (n : ℕ∞) (WithTop.natCast_lt_top n) = n := rfl @[simp] theorem lift_lt_iff {x : ℕ∞} {h} {n : ℕ} : lift x h < n ↔ x < n := WithTop.untop_lt_iff _ @[simp] theorem lift_le_iff {x : ℕ∞} {h} {n : ℕ} : lift x h ≤ n ↔ x ≤ n := WithTop.untop_le_iff _ @[simp] theorem lt_lift_iff {x : ℕ} {n : ℕ∞} {h} : x < lift n h ↔ x < n := WithTop.lt_untop_iff _ @[simp] theorem le_lift_iff {x : ℕ} {n : ℕ∞} {h} : x ≤ lift n h ↔ x ≤ n := WithTop.le_untop_iff _ -@[simp] theorem lift_zero : lift 0 (WithTop.coe_lt_top 0) = 0 := rfl -@[simp] theorem lift_one : lift 1 (WithTop.coe_lt_top 1) = 1 := rfl +@[deprecated (since := "2026-07-17")] alias lift_coe := lift_natCast + +@[simp] theorem lift_zero : lift 0 (WithTop.natCast_lt_top 0) = 0 := rfl +@[simp] theorem lift_one : lift 1 (WithTop.natCast_lt_top 1) = 1 := rfl @[simp] theorem lift_ofNat (n : ℕ) [n.AtLeastTwo] : - lift ofNat(n) (WithTop.coe_lt_top n) = OfNat.ofNat n := rfl + lift ofNat(n) (WithTop.natCast_lt_top n) = OfNat.ofNat n := rfl @[simp] theorem add_lt_top {a b : ℕ∞} : a + b < ⊤ ↔ a < ⊤ ∧ b < ⊤ := WithTop.add_lt_top @[simp] theorem add_eq_top {a b : ℕ∞} : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := WithTop.add_eq_top @[simp] theorem lift_add (a b : ℕ∞) (h : a + b < ⊤) : lift (a + b) h = lift a (add_lt_top.1 h).1 + lift b (add_lt_top.1 h).2 := by - apply coe_inj.1 + apply natCast_inj.1 simp instance canLift : CanLift ℕ∞ ℕ (↑) (· ≠ ⊤) := WithTop.canLift @@ -145,9 +166,11 @@ def toNatHom : MonoidWithZeroHom ℕ∞ ℕ where lemma toNatHom_apply (n : ℕ) : toNatHom n = toNat n := rfl @[simp] -theorem toNat_coe (n : ℕ) : toNat n = n := +theorem toNat_natCast (n : ℕ) : toNat n = n := rfl +@[deprecated (since := "2026-07-17")] alias toNat_coe := toNat_natCast + @[simp] theorem toNat_zero : toNat 0 = 0 := rfl @@ -189,9 +212,11 @@ theorem recTopCoe_ofNat {C : ℕ∞ → Sort*} (d : C ⊤) (f : ∀ a : ℕ, C a rfl @[simp] -theorem top_ne_coe (a : ℕ) : ⊤ ≠ (a : ℕ∞) := +theorem top_ne_natCast (a : ℕ) : ⊤ ≠ (a : ℕ∞) := nofun +@[deprecated (since := "2026-07-17")] alias top_ne_coe := top_ne_natCast + @[simp] theorem top_ne_ofNat (a : ℕ) [a.AtLeastTwo] : ⊤ ≠ (ofNat(a) : ℕ∞) := nofun @@ -200,9 +225,11 @@ theorem top_ne_ofNat (a : ℕ) [a.AtLeastTwo] : ⊤ ≠ (ofNat(a) : ℕ∞) := @[simp] lemma top_ne_one : (⊤ : ℕ∞) ≠ 1 := nofun @[simp] -theorem coe_ne_top (a : ℕ) : (a : ℕ∞) ≠ ⊤ := +theorem natCast_ne_top (a : ℕ) : (a : ℕ∞) ≠ ⊤ := nofun +@[deprecated (since := "2026-07-17")] alias coe_ne_top := natCast_ne_top + @[simp] theorem ofNat_ne_top (a : ℕ) [a.AtLeastTwo] : (ofNat(a) : ℕ∞) ≠ ⊤ := nofun @@ -211,9 +238,11 @@ theorem ofNat_ne_top (a : ℕ) [a.AtLeastTwo] : (ofNat(a) : ℕ∞) ≠ ⊤ := @[simp] lemma one_ne_top : 1 ≠ (⊤ : ℕ∞) := nofun @[simp] -theorem top_sub_coe (a : ℕ) : (⊤ : ℕ∞) - a = ⊤ := +theorem top_sub_natCast (a : ℕ) : (⊤ : ℕ∞) - a = ⊤ := rfl +@[deprecated (since := "2026-07-17")] alias top_sub_coe := top_sub_natCast + @[simp] theorem top_sub_one : (⊤ : ℕ∞) - 1 = ⊤ := rfl @@ -233,20 +262,28 @@ theorem one_lt_top : (1 : ℕ∞) < ⊤ := @[simp] theorem sub_top (a : ℕ∞) : a - ⊤ = 0 := WithTop.sub_top @[simp] -theorem coe_toNat_eq_self : ENat.toNat n = n ↔ n ≠ ⊤ := - ENat.recTopCoe (by decide) (fun _ => by simp [toNat_coe]) n +theorem natCast_toNat_eq_self : ENat.toNat n = n ↔ n ≠ ⊤ := + ENat.recTopCoe (by decide) (fun _ => by simp [toNat_natCast]) n -alias ⟨_, coe_toNat⟩ := coe_toNat_eq_self +@[deprecated (since := "2026-07-17")] alias coe_toNat_eq_self := natCast_toNat_eq_self -@[simp] lemma toNat_eq_iff_eq_coe (n : ℕ∞) (m : ℕ) [NeZero m] : +alias ⟨_, natCast_toNat⟩ := natCast_toNat_eq_self + +@[deprecated (since := "2026-07-17")] alias coe_toNat := natCast_toNat + +@[simp] lemma toNat_eq_iff_eq_natCast (n : ℕ∞) (m : ℕ) [NeZero m] : n.toNat = m ↔ n = m := by cases n · simpa using NeZero.ne' m · simp -theorem coe_toNat_le_self (n : ℕ∞) : ↑(toNat n) ≤ n := +@[deprecated (since := "2026-07-17")] alias toNat_eq_iff_eq_coe := toNat_eq_iff_eq_natCast + +theorem natCast_toNat_le_self (n : ℕ∞) : ↑(toNat n) ≤ n := ENat.recTopCoe le_top (fun _ => le_rfl) n +@[deprecated (since := "2026-07-17")] alias coe_toNat_le_self := natCast_toNat_le_self + theorem toNat_add {m n : ℕ∞} (hm : m ≠ ⊤) (hn : n ≠ ⊤) : toNat (m + n) = toNat m + toNat n := by lift m to ℕ using hm lift n to ℕ using hn @@ -255,26 +292,28 @@ theorem toNat_add {m n : ℕ∞} (hm : m ≠ ⊤) (hn : n ≠ ⊤) : toNat (m + theorem toNat_sub {n : ℕ∞} (hn : n ≠ ⊤) (m : ℕ∞) : toNat (m - n) = toNat m - toNat n := by lift n to ℕ using hn induction m - · rw [top_sub_coe, toNat_top, zero_tsub] - · rw [← coe_sub, toNat_coe, toNat_coe, toNat_coe] + · rw [top_sub_natCast, toNat_top, zero_tsub] + · rw [← natCast_sub, toNat_natCast, toNat_natCast, toNat_natCast] @[simp] theorem toNat_mul (a b : ℕ∞) : (a * b).toNat = a.toNat * b.toNat := by cases a <;> cases b · simp · rename_i b; cases b <;> simp · rename_i a; cases a <;> simp - · simp only [toNat_coe]; rw [← coe_mul, toNat_coe] + · simp only [toNat_natCast]; rw [← natCast_mul, toNat_natCast] theorem toNat_eq_iff {m : ℕ∞} {n : ℕ} (hn : n ≠ 0) : toNat m = n ↔ m = n := by induction m <;> simp [hn.symm] -lemma toNat_le_of_le_coe {m : ℕ∞} {n : ℕ} (h : m ≤ n) : toNat m ≤ n := by - lift m to ℕ using ne_top_of_le_ne_top (coe_ne_top n) h +lemma toNat_le_of_le_natCast {m : ℕ∞} {n : ℕ} (h : m ≤ n) : toNat m ≤ n := by + lift m to ℕ using ne_top_of_le_ne_top (natCast_ne_top n) h simpa using h +@[deprecated (since := "2026-07-17")] alias toNat_le_of_le_coe := toNat_le_of_le_natCast + @[gcongr] lemma toNat_le_toNat {m n : ℕ∞} (h : m ≤ n) (hn : n ≠ ⊤) : toNat m ≤ toNat n := - toNat_le_of_le_coe <| h.trans_eq (coe_toNat hn).symm + toNat_le_of_le_natCast <| h.trans_eq (natCast_toNat hn).symm @[deprecated Order.succ_eq_add_one (since := "2026-05-25")] theorem succ_def (m : ℕ∞) : Order.succ m = m + 1 := @@ -286,11 +325,15 @@ theorem add_one_le_iff (hm : m ≠ ⊤) : m + 1 ≤ n ↔ m < n := theorem add_one_le_iff' (hn : n ≠ ⊤) : m + 1 ≤ n ↔ m < n := Order.add_one_le_iff_of_not_isMax' (not_isMax_iff_ne_top.mpr hn) -theorem coe_add_one_le_iff {m : ℕ} {n : ℕ∞} : m + 1 ≤ n ↔ m < n := - add_one_le_iff <| coe_ne_top m +theorem natCast_add_one_le_iff {m : ℕ} {n : ℕ∞} : m + 1 ≤ n ↔ m < n := + add_one_le_iff <| natCast_ne_top m + +@[deprecated (since := "2026-07-17")] alias coe_add_one_le_iff := natCast_add_one_le_iff -theorem add_one_le_coe_iff {m : ℕ∞} {n : ℕ} : m + 1 ≤ n ↔ m < n := - add_one_le_iff' <| coe_ne_top n +theorem add_one_le_natCast_iff {m : ℕ∞} {n : ℕ} : m + 1 ≤ n ↔ m < n := + add_one_le_iff' <| natCast_ne_top n + +@[deprecated (since := "2026-07-17")] alias add_one_le_coe_iff := add_one_le_natCast_iff @[deprecated Order.one_le_iff_ne_zero (since := "2026-05-25")] protected theorem one_le_iff_ne_zero : 1 ≤ n ↔ n ≠ 0 := @@ -322,22 +365,34 @@ theorem add_le_add_iff_right {m n k : ENat} (h : k ≠ ⊤) : n + k ≤ m + k ↔ n ≤ m := WithTop.add_le_add_iff_right h -theorem lt_coe_add_one_iff {m : ℕ∞} {n : ℕ} : m < n + 1 ↔ m ≤ n := - lt_add_one_iff (coe_ne_top n) +theorem lt_natCast_add_one_iff {m : ℕ∞} {n : ℕ} : m < n + 1 ↔ m ≤ n := + lt_add_one_iff (natCast_ne_top n) + +@[deprecated (since := "2026-07-17")] alias lt_coe_add_one_iff := lt_natCast_add_one_iff -theorem coe_lt_add_one_iff {m : ℕ} {n : ℕ∞} : m < n + 1 ↔ m ≤ n := - lt_add_one_iff' (coe_ne_top m) +theorem natCast_lt_add_one_iff {m : ℕ} {n : ℕ∞} : m < n + 1 ↔ m ≤ n := + lt_add_one_iff' (natCast_ne_top m) -theorem le_coe_iff {n : ℕ∞} {k : ℕ} : n ≤ ↑k ↔ ∃ (n₀ : ℕ), n = n₀ ∧ n₀ ≤ k := +@[deprecated (since := "2026-07-17")] alias coe_lt_add_one_iff := natCast_lt_add_one_iff + +theorem le_natCast_iff {n : ℕ∞} {k : ℕ} : n ≤ ↑k ↔ ∃ (n₀ : ℕ), n = n₀ ∧ n₀ ≤ k := WithTop.le_coe_iff +@[deprecated (since := "2026-07-17")] alias le_coe_iff := le_natCast_iff + @[simp] -lemma coe_lt_top (n : ℕ) : (n : ℕ∞) < ⊤ := - WithTop.coe_lt_top n +lemma natCast_lt_top (n : ℕ) : (n : ℕ∞) < ⊤ := + WithTop.natCast_lt_top n + +@[deprecated (since := "2026-07-17")] alias coe_lt_top := natCast_lt_top + +lemma natCast_lt_natCast {n m : ℕ} : (n : ℕ∞) < (m : ℕ∞) ↔ n < m := by simp -lemma coe_lt_coe {n m : ℕ} : (n : ℕ∞) < (m : ℕ∞) ↔ n < m := by simp +@[deprecated (since := "2026-07-17")] alias coe_lt_coe := natCast_lt_natCast -lemma coe_le_coe {n m : ℕ} : (n : ℕ∞) ≤ (m : ℕ∞) ↔ n ≤ m := by simp +lemma natCast_le_natCast {n m : ℕ} : (n : ℕ∞) ≤ (m : ℕ∞) ↔ n ≤ m := by simp + +@[deprecated (since := "2026-07-17")] alias coe_le_coe := natCast_le_natCast @[elab_as_elim] theorem nat_induction {motive : ℕ∞ → Prop} (a : ℕ∞) (zero : motive 0) @@ -354,7 +409,7 @@ lemma add_one_pos : 0 < n + 1 := lemma natCast_lt_succ {n : ℕ} : (n : ℕ∞) < (n : ℕ∞) + 1 := by - rw [← Nat.cast_one, ← Nat.cast_add, coe_lt_coe] + rw [← Nat.cast_one, ← Nat.cast_add, natCast_lt_natCast] exact lt_add_one n lemma add_lt_add_iff_right {k : ℕ∞} (h : k ≠ ⊤) : n + k < m + k ↔ n < m := @@ -380,10 +435,10 @@ lemma exists_ne_top {p : ℕ∞ → Prop} : (∃ x ≠ ⊤, p x) ↔ ∃ x : ℕ lemma eq_top_iff_forall_gt : n = ⊤ ↔ ∀ m : ℕ, m < n := WithTop.eq_top_iff_forall_gt lemma eq_top_iff_forall_ge : n = ⊤ ↔ ∀ m : ℕ, m ≤ n := WithTop.eq_top_iff_forall_ge -/-- Version of `WithTop.forall_coe_le_iff_le` using `Nat.cast` rather than `WithTop.some`. -/ +/-- Version of `WithTop.forall_natCast_le_iff_le` using `Nat.cast` rather than `WithTop.some`. -/ lemma forall_natCast_le_iff_le : (∀ a : ℕ, a ≤ m → a ≤ n) ↔ m ≤ n := WithTop.forall_coe_le_iff_le -/-- Version of `WithTop.eq_of_forall_coe_le_iff` using `Nat.cast` rather than `WithTop.some`. -/ +/-- Version of `WithTop.eq_of_forall_natCast_le_iff` using `Nat.cast` rather than `WithTop.some`. -/ lemma eq_of_forall_natCast_le_iff (hm : ∀ a : ℕ, a ≤ m ↔ a ≤ n) : m = n := WithTop.eq_of_forall_coe_le_iff hm @@ -396,7 +451,9 @@ lemma sub_ne_top_iff : a - b ≠ ⊤ ↔ a ≠ ⊤ ∨ b = ⊤ := WithTop.sub_ne lemma addLECancellable_of_ne_top : a ≠ ⊤ → AddLECancellable a := WithTop.addLECancellable_of_ne_top lemma addLECancellable_of_lt_top : a < ⊤ → AddLECancellable a := WithTop.addLECancellable_of_lt_top -lemma addLECancellable_coe (a : ℕ) : AddLECancellable (a : ℕ∞) := WithTop.addLECancellable_coe _ +lemma addLECancellable_natCast (a : ℕ) : AddLECancellable (a : ℕ∞) := WithTop.addLECancellable_coe _ + +@[deprecated (since := "2026-07-17")] alias addLECancellable_coe := addLECancellable_natCast protected lemma le_sub_of_add_le_left (ha : a ≠ ⊤) : a + b ≤ c → b ≤ c - a := (addLECancellable_of_ne_top ha).le_tsub_of_add_le_left @@ -407,7 +464,8 @@ protected lemma le_sub_of_add_le_right (hb : b ≠ ⊤) : a + b ≤ c → a ≤ protected lemma le_sub_one_of_lt (h : a < b) : a ≤ b - 1 := by cases b · simp - · exact ENat.le_sub_of_add_le_right one_ne_top <| lt_coe_add_one_iff.mp <| lt_tsub_iff_right.mp h + · exact ENat.le_sub_of_add_le_right one_ne_top <| lt_natCast_add_one_iff.mp <| + lt_tsub_iff_right.mp h lemma lt_add_left {n k : ℕ∞} (h : n ≠ ⊤) (h' : 0 < k) : n < k + n := calc _ = 0 + n := (zero_add n).symm @@ -469,7 +527,7 @@ instance : Unique ℕ∞ˣ where obtain ⟨y, x_y⟩ := ne_top_iff_exists.1 x_top obtain ⟨z, x_z⟩ := ne_top_iff_exists.1 x_inv_top replace x_y := x_y.symm - rw [x_y, ← x_z, ← coe_mul, ← coe_one, coe_inj, _root_.mul_eq_one] at this + rw [x_y, ← x_z, ← natCast_mul, ← natCast_one, natCast_inj, _root_.mul_eq_one] at this rwa [this.1, Nat.cast_one, Units.val_eq_one] at x_y section withTop_enat @@ -488,7 +546,7 @@ lemma add_one_natCast_le_withTop_of_lt {m : ℕ} {n : WithTop ℕ∞} (h : m < n | (⊤ : ℕ∞) => simp | (n : ℕ) => norm_cast - simp only [coe_ne_top] + simp only [natCast_ne_top] @[simp] lemma natCast_ne_coe_top (n : ℕ) : (n : WithTop ℕ∞) ≠ (⊤ : ℕ∞) := nofun @@ -515,7 +573,9 @@ def map (f : ℕ → α) (k : ℕ∞) : WithTop α := WithTop.map f k theorem map_top (f : ℕ → α) : map f ⊤ = ⊤ := rfl @[simp] -theorem map_coe (f : ℕ → α) (a : ℕ) : map f a = f a := rfl +theorem map_natCast (f : ℕ → α) (a : ℕ) : map f a = f a := rfl + +@[deprecated (since := "2026-07-17")] alias map_coe := map_natCast @[simp] protected theorem map_zero (f : ℕ → α) : map f 0 = f 0 := rfl @@ -610,7 +670,7 @@ protected def _root_.MonoidWithZeroHom.ENatMap {S : Type*} [MulZeroOneClass S] [ | top => have : (f x : WithTop S) ≠ 0 := by simpa [hf.eq_iff' (map_zero f)] using hx simp [mul_top hx, WithTop.mul_top this] - | coe y => simp [← Nat.cast_mul, -coe_mul] } + | coe y => simp [← Nat.cast_mul, -natCast_mul] } /-- A version of `ENat.map` for `RingHom`s. -/ @[simps -fullyApplied] @@ -635,17 +695,18 @@ lemma eq_top_iff_forall_ge {n : WithBot ℕ∞} : n = ⊤ ↔ ∀ m : ℕ, m ≤ _root_.WithBot.eq_top_iff_forall_ge lemma lt_add_one_iff {n : WithBot ℕ∞} {m : ℕ} : n < m + 1 ↔ n ≤ m := by - rw [← WithBot.coe_one, ← ENat.coe_one, WithBot.coe_natCast, ← Nat.cast_add, ← WithBot.coe_natCast] + rw [← WithBot.coe_one, ← ENat.natCast_one, WithBot.coe_natCast, ← Nat.cast_add, + ← WithBot.coe_natCast] cases n · simp only [bot_le, WithBot.bot_lt_coe] - · rw [WithBot.coe_lt_coe, Nat.cast_add, ENat.coe_one, ENat.lt_add_one_iff (ENat.coe_ne_top _), + · rw [WithBot.coe_lt_coe, Nat.cast_add, natCast_one, ENat.lt_add_one_iff (natCast_ne_top _), ← WithBot.coe_le_coe, WithBot.coe_natCast] lemma add_one_le_iff {n : ℕ} {m : WithBot ℕ∞} : n + 1 ≤ m ↔ n < m := by - rw [← WithBot.coe_one, ← ENat.coe_one, WithBot.coe_natCast, ← Nat.cast_add, ← WithBot.coe_natCast] + rw [← WithBot.coe_one, ← natCast_one, WithBot.coe_natCast, ← Nat.cast_add, ← WithBot.coe_natCast] cases m · simp - · rw [WithBot.coe_le_coe, ENat.coe_add, ENat.coe_one, ENat.add_one_le_iff (ENat.coe_ne_top n), + · rw [WithBot.coe_le_coe, natCast_add, natCast_one, ENat.add_one_le_iff (natCast_ne_top n), ← WithBot.coe_lt_coe, WithBot.coe_natCast] lemma add_one_le_natCast_iff {n : WithBot ℕ∞} {m : ℕ} : n + 1 ≤ m ↔ n < m := by diff --git a/Mathlib/Data/ENat/BigOperators.lean b/Mathlib/Data/ENat/BigOperators.lean index c9b2924b86b2b4..a83edc8721cf0b 100644 --- a/Mathlib/Data/ENat/BigOperators.lean +++ b/Mathlib/Data/ENat/BigOperators.lean @@ -74,8 +74,8 @@ theorem lt_top_of_sum_ne_top {s : Finset α} {f : α → ℕ∞} (h : ∑ x ∈ infinity -/ theorem toNat_sum {s : Finset α} {f : α → ℕ∞} (hf : ∀ a ∈ s, f a ≠ ⊤) : ENat.toNat (∑ a ∈ s, f a) = ∑ a ∈ s, ENat.toNat (f a) := by - rw [← coe_inj, coe_toNat (sum_ne_top.2 hf), Nat.cast_sum] - exact sum_congr rfl fun x hx => (coe_toNat (hf x hx)).symm + rw [← natCast_inj, natCast_toNat (sum_ne_top.2 hf), Nat.cast_sum] + exact sum_congr rfl fun x hx => (natCast_toNat (hf x hx)).symm theorem sum_lt_sum_of_nonempty {s : Finset α} (hs : s.Nonempty) {f g : α → ℕ∞} (Hlt : ∀ i ∈ s, f i < g i) : ∑ i ∈ s, f i < ∑ i ∈ s, g i := by diff --git a/Mathlib/Data/ENat/Defs.lean b/Mathlib/Data/ENat/Defs.lean index eb0306f4c4b004..3558a5153a0b17 100644 --- a/Mathlib/Data/ENat/Defs.lean +++ b/Mathlib/Data/ENat/Defs.lean @@ -5,6 +5,7 @@ Authors: Mario Carneiro, Simon Hudon, Yury Kudryashov -/ module +public import Batteries.Tactic.Alias public import Mathlib.Data.Nat.Notation public import Mathlib.Order.TypeTags @@ -33,8 +34,10 @@ theorem recTopCoe_top {C : ℕ∞ → Sort*} (d : C ⊤) (f : ∀ a : ℕ, C a) rfl @[simp] -theorem recTopCoe_coe {C : ℕ∞ → Sort*} (d : C ⊤) (f : ∀ a : ℕ, C a) (x : ℕ) : +theorem recTopCoe_natCast {C : ℕ∞ → Sort*} (d : C ⊤) (f : ∀ a : ℕ, C a) (x : ℕ) : @recTopCoe C d f ↑x = f x := rfl +@[deprecated (since := "2026-07-17")] alias recTopCoe_coe := recTopCoe_natCast + end ENat diff --git a/Mathlib/Data/ENat/Lattice.lean b/Mathlib/Data/ENat/Lattice.lean index ded4493d69fee1..b9d43a031df0e3 100644 --- a/Mathlib/Data/ENat/Lattice.lean +++ b/Mathlib/Data/ENat/Lattice.lean @@ -35,34 +35,51 @@ noncomputable instance : CompleteLinearOrder (WithBot ENat) := namespace ENat variable {ι : Sort*} {f : ι → ℕ} {s : Set ℕ} -lemma iSup_coe_eq_top : ⨆ i, (f i : ℕ∞) = ⊤ ↔ ¬ BddAbove (range f) := WithTop.iSup_coe_eq_top -lemma iSup_coe_ne_top : ⨆ i, (f i : ℕ∞) ≠ ⊤ ↔ BddAbove (range f) := iSup_coe_eq_top.not_left -lemma iSup_coe_lt_top : ⨆ i, (f i : ℕ∞) < ⊤ ↔ BddAbove (range f) := WithTop.iSup_coe_lt_top -lemma iInf_coe_eq_top : ⨅ i, (f i : ℕ∞) = ⊤ ↔ IsEmpty ι := WithTop.iInf_coe_eq_top -lemma iInf_coe_ne_top : ⨅ i, (f i : ℕ∞) ≠ ⊤ ↔ Nonempty ι := by - rw [Ne, iInf_coe_eq_top, not_isEmpty_iff] -lemma iInf_coe_lt_top : ⨅ i, (f i : ℕ∞) < ⊤ ↔ Nonempty ι := WithTop.iInf_coe_lt_top +lemma iSup_natCast_eq_top : ⨆ i, (f i : ℕ∞) = ⊤ ↔ ¬ BddAbove (range f) := WithTop.iSup_coe_eq_top +lemma iSup_natCast_ne_top : ⨆ i, (f i : ℕ∞) ≠ ⊤ ↔ BddAbove (range f) := iSup_natCast_eq_top.not_left +lemma iSup_natCast_lt_top : ⨆ i, (f i : ℕ∞) < ⊤ ↔ BddAbove (range f) := WithTop.iSup_coe_lt_top +lemma iInf_natCast_eq_top : ⨅ i, (f i : ℕ∞) = ⊤ ↔ IsEmpty ι := WithTop.iInf_coe_eq_top +lemma iInf_natCast_ne_top : ⨅ i, (f i : ℕ∞) ≠ ⊤ ↔ Nonempty ι := by + rw [Ne, iInf_natCast_eq_top, not_isEmpty_iff] +lemma iInf_natCast_lt_top : ⨅ i, (f i : ℕ∞) < ⊤ ↔ Nonempty ι := WithTop.iInf_coe_lt_top + +@[deprecated (since := "2026-07-17")] alias iSup_coe_eq_top := iSup_natCast_eq_top +@[deprecated (since := "2026-07-17")] alias iSup_coe_ne_top := iSup_natCast_ne_top +@[deprecated (since := "2026-07-17")] alias iSup_coe_lt_top := iSup_natCast_lt_top +@[deprecated (since := "2026-07-17")] alias iInf_coe_eq_top := iInf_natCast_eq_top +@[deprecated (since := "2026-07-17")] alias iInf_coe_ne_top := iInf_natCast_ne_top +@[deprecated (since := "2026-07-17")] alias iInf_coe_lt_top := iInf_natCast_lt_top + +lemma natCast_sSup : BddAbove s → ↑(sSup s) = ⨆ a ∈ s, (a : ℕ∞) := WithTop.coe_sSup + +@[deprecated (since := "2026-07-17")] alias coe_sSup := natCast_sSup + +lemma natCast_sInf (hs : s.Nonempty) : ↑(sInf s) = ⨅ a ∈ s, (a : ℕ∞) := + WithTop.coe_sInf hs (OrderBot.bddBelow s) -lemma coe_sSup : BddAbove s → ↑(sSup s) = ⨆ a ∈ s, (a : ℕ∞) := WithTop.coe_sSup +@[deprecated (since := "2026-07-17")] alias coe_sInf := natCast_sInf -lemma coe_sInf (hs : s.Nonempty) : ↑(sInf s) = ⨅ a ∈ s, (a : ℕ∞) := - WithTop.coe_sInf hs (OrderBot.bddBelow s) +lemma natCast_iSup : BddAbove (range f) → ↑(⨆ i, f i) = ⨆ i, (f i : ℕ∞) := WithTop.coe_iSup _ -lemma coe_iSup : BddAbove (range f) → ↑(⨆ i, f i) = ⨆ i, (f i : ℕ∞) := WithTop.coe_iSup _ +@[deprecated (since := "2026-07-17")] alias coe_iSup := natCast_iSup -@[norm_cast] lemma coe_iInf [Nonempty ι] : ↑(⨅ i, f i) = ⨅ i, (f i : ℕ∞) := +@[norm_cast] lemma natCast_iInf [Nonempty ι] : ↑(⨅ i, f i) = ⨅ i, (f i : ℕ∞) := WithTop.coe_iInf (OrderBot.bddBelow _) +@[deprecated (since := "2026-07-17")] alias coe_iInf := natCast_iInf + @[simp] lemma iInf_eq_top_of_isEmpty [IsEmpty ι] : ⨅ i, (f i : ℕ∞) = ⊤ := - iInf_coe_eq_top.mpr ‹_› + iInf_natCast_eq_top.mpr ‹_› -lemma iInf_eq_coe_iff {f : ι → ℕ∞} {n : ℕ} : +lemma iInf_eq_natCast_iff {f : ι → ℕ∞} {n : ℕ} : ⨅ i, f i = n ↔ (∃ i, f i = n) ∧ ∀ i, n ≤ f i := by by_cases! hι : IsEmpty ι · simp [iInf_of_isEmpty] apply ciInf_eq_iff +@[deprecated (since := "2026-07-17")] alias iInf_eq_coe_iff := iInf_eq_natCast_iff + lemma iInf_toNat : (⨅ i, (f i : ℕ∞)).toNat = ⨅ i, f i := by cases isEmpty_or_nonempty ι · simp @@ -98,7 +115,7 @@ lemma sSup_eq_top_of_infinite (h : s.Infinite) : sSup s = ⊤ := by specialize h y hy have hxt : y < ⊤ := lt_of_le_of_lt h hx use y.toNat - simp [toNat_le_of_le_coe h, LT.lt.ne_top hxt] + simp [toNat_le_of_le_natCast h, LT.lt.ne_top hxt] lemma finite_of_sSup_lt_top (h : sSup s < ⊤) : s.Finite := by contrapose! h diff --git a/Mathlib/Data/ENat/Pow.lean b/Mathlib/Data/ENat/Pow.lean index e83311d992c684..b008843be24cac 100644 --- a/Mathlib/Data/ENat/Pow.lean +++ b/Mathlib/Data/ENat/Pow.lean @@ -39,7 +39,7 @@ lemma epow_def {x y : ℕ∞} : x ^ y = if y < ⊤ then x ^ y.toNat else if x = 0 then 0 else if x = 1 then 1 else ⊤ := by cases y with | top => simp only [lt_self_iff_false, ↓reduceIte]; rfl - | coe n => simp only [coe_lt_top, ↓reduceIte, toNat_coe]; rfl + | coe n => simp only [natCast_lt_top, ↓reduceIte, toNat_natCast]; rfl @[simp, norm_cast] lemma epow_natCast {y : ℕ} : x ^ (y : ℕ∞) = x ^ y := rfl @@ -68,11 +68,11 @@ lemma top_epow (h : y ≠ 0) : (⊤ : ℕ∞) ^ y = ⊤ := by @[simp] lemma epow_zero : x ^ (0 : ℕ∞) = 1 := by - rw [← coe_zero, epow_natCast, pow_zero] + rw [← natCast_zero, epow_natCast, pow_zero] @[simp] lemma epow_one : x ^ (1 : ℕ∞) = x := by - rw [← coe_one, epow_natCast, pow_one] + rw [← natCast_one, epow_natCast, pow_one] lemma epow_top (h : 1 < x) : x ^ (⊤ : ℕ∞) = ⊤ := by have : (0 : ℕ∞) ≤ 1 := zero_le_one diff --git a/Mathlib/Data/Nat/Multiplicity.lean b/Mathlib/Data/Nat/Multiplicity.lean index 88faa7909725f9..9a65a42698a4c8 100644 --- a/Mathlib/Data/Nat/Multiplicity.lean +++ b/Mathlib/Data/Nat/Multiplicity.lean @@ -165,18 +165,18 @@ theorem emultiplicity_factorial_mul {n p : ℕ} (hp : p.Prime) : and `n - 1`. -/ theorem multiplicity_factorial_pow {n p : ℕ} (hp : p.Prime) : multiplicity p (p ^ n).factorial = ∑ i ∈ Finset.range n, p ^ i := by - rw [← ENat.coe_inj, ← (Nat.finiteMultiplicity_iff.2 + rw [← ENat.natCast_inj, ← (Nat.finiteMultiplicity_iff.2 ⟨hp.ne_one, (p ^ n).factorial_pos⟩).emultiplicity_eq_multiplicity] induction n with | zero => simp [hp.emultiplicity_one] | succ n h => - rw [pow_succ', hp.emultiplicity_factorial_mul, h, Finset.sum_range_succ, ENat.coe_add] + rw [pow_succ', hp.emultiplicity_factorial_mul, h, Finset.sum_range_succ, ENat.natCast_add] /-- A prime power divides `n!` iff it is at most the sum of the quotients `n / p ^ i`. This sum is expressed over the set `Ico 1 b` where `b` is any bound greater than `log p n` -/ theorem pow_dvd_factorial_iff {p : ℕ} {n r b : ℕ} (hp : p.Prime) (hbn : log p n < b) : p ^ r ∣ n ! ↔ r ≤ ∑ i ∈ Ico 1 b, n / p ^ i := by - rw [← ENat.coe_le_coe, ← hp.emultiplicity_factorial hbn, pow_dvd_iff_le_emultiplicity] + rw [← ENat.natCast_le_natCast, ← hp.emultiplicity_factorial hbn, pow_dvd_iff_le_emultiplicity] theorem emultiplicity_factorial_le_div_pred {p : ℕ} (hp : p.Prime) (n : ℕ) : emultiplicity p n ! ≤ (n / (p - 1) : ℕ) := by diff --git a/Mathlib/Data/Seq/Basic.lean b/Mathlib/Data/Seq/Basic.lean index da942f04c234bf..4ff20f6e3fc407 100644 --- a/Mathlib/Data/Seq/Basic.lean +++ b/Mathlib/Data/Seq/Basic.lean @@ -120,7 +120,7 @@ theorem lt_length'_iff {s : Seq α} {n : ℕ} : n < s.length' ↔ ∃ a, a ∈ s.get? n := by by_cases h : s.Terminates · simpa [length'_of_terminates h] using lt_length_iff - · simp only [length'_of_not_terminates h, ENat.coe_lt_top, Option.mem_def, true_iff] + · simp only [length'_of_not_terminates h, ENat.natCast_lt_top, Option.mem_def, true_iff] rw [not_terminates_iff] at h rw [← Option.isSome_iff_exists] exact h n diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index 84b2e41a1f8aed..52b8f13cd2f277 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -144,7 +144,7 @@ theorem Finite.encard_lt_top (h : s.Finite) : s.encard < ⊤ := by exact lt_tsub_iff_right.1 ht' theorem Finite.encard_eq_coe (h : s.Finite) : s.encard = ENat.toNat s.encard := - (ENat.coe_toNat h.encard_lt_top.ne).symm + (ENat.natCast_toNat h.encard_lt_top.ne).symm theorem Finite.exists_encard_eq_coe (h : s.Finite) : ∃ (n : ℕ), s.encard = n := ⟨_, h.encard_eq_coe⟩ @@ -168,7 +168,7 @@ theorem finite_of_encard_eq_coe {k : ℕ} (h : s.encard = k) : s.Finite := finite_of_encard_le_coe h.le theorem encard_le_coe_iff {k : ℕ} : s.encard ≤ k ↔ s.Finite ∧ ∃ (n₀ : ℕ), s.encard = n₀ ∧ n₀ ≤ k := - ⟨fun h ↦ ⟨finite_of_encard_le_coe h, by rwa [ENat.le_coe_iff] at h⟩, + ⟨fun h ↦ ⟨finite_of_encard_le_coe h, by rwa [ENat.le_natCast_iff] at h⟩, fun ⟨_,⟨n₀,hs, hle⟩⟩ ↦ by rwa [hs, Nat.cast_le]⟩ @[simp] @@ -616,14 +616,14 @@ noncomputable def ncard (s : Set α) : ℕ := ENat.toNat s.encard theorem ncard_def (s : Set α) : s.ncard = ENat.toNat s.encard := rfl theorem Finite.cast_ncard_eq (hs : s.Finite) : s.ncard = s.encard := by - rwa [ncard, ENat.coe_toNat_eq_self, ne_eq, encard_eq_top_iff, Set.Infinite, not_not] + rwa [ncard, ENat.natCast_toNat_eq_self, ne_eq, encard_eq_top_iff, Set.Infinite, not_not] variable (s) in @[simp] theorem coe_ncard_eq_encard [Finite s] : s.ncard = s.encard := s.toFinite.cast_ncard_eq -lemma ncard_le_encard (s : Set α) : s.ncard ≤ s.encard := ENat.coe_toNat_le_self _ +lemma ncard_le_encard (s : Set α) : s.ncard ≤ s.encard := ENat.natCast_toNat_le_self _ @[simp] theorem _root_.Nat.card_coe_set_eq (s : Set α) : Nat.card s = s.ncard := rfl @@ -646,7 +646,7 @@ lemma cast_ncard {s : Set α} (hs : s.Finite) : theorem encard_le_coe_iff_finite_ncard_le {k : ℕ} : s.encard ≤ k ↔ s.Finite ∧ s.ncard ≤ k := by rw [encard_le_coe_iff, and_congr_right_iff] - exact fun hfin ↦ ⟨fun ⟨n₀, hn₀, hle⟩ ↦ by rwa [ncard_def, hn₀, ENat.toNat_coe], + exact fun hfin ↦ ⟨fun ⟨n₀, hn₀, hle⟩ ↦ by rwa [ncard_def, hn₀, ENat.toNat_natCast], fun h ↦ ⟨s.ncard, by rw [hfin.cast_ncard_eq], h⟩⟩ theorem Infinite.ncard (hs : s.Infinite) : s.ncard = 0 := by diff --git a/Mathlib/Data/Set/PowersetCard.lean b/Mathlib/Data/Set/PowersetCard.lean index 84c189271dbe53..f23a7e47667ecc 100644 --- a/Mathlib/Data/Set/PowersetCard.lean +++ b/Mathlib/Data/Set/PowersetCard.lean @@ -74,12 +74,12 @@ theorem exists_mem_notMem (hn : 1 ≤ n) (hα : n < ENat.card α) {a b : α} (ha ∃ s : powersetCard α n, a ∈ s ∧ b ∉ s := by have ha' : n ≤ Set.encard {b}ᶜ := by rwa [← (Set.encard_add_encard_compl {b}).trans (Set.encard_univ α), Set.encard_singleton, - add_comm, ENat.lt_add_one_iff' (ENat.coe_ne_top n)] at hα + add_comm, ENat.lt_add_one_iff' (ENat.natCast_ne_top n)] at hα obtain ⟨s, has, has', hs⟩ := Set.exists_superset_subset_encard_eq (s := {a}) (by simp [Ne.symm hab]) (by simpa) ha' have : Set.Finite s := Set.finite_of_encard_eq_coe hs exact ⟨⟨Set.Finite.toFinset this, by - rwa [mem_iff, ← ENat.coe_inj, ← this.encard_eq_coe_toFinset_card]⟩, + rwa [mem_iff, ← ENat.natCast_inj, ← this.encard_eq_coe_toFinset_card]⟩, by simpa using has, by simpa using has'⟩ theorem exists_mem_notMem_iff_ne (s t : Set.powersetCard α n) : s ≠ t ↔ ∃ a ∈ s, a ∉ t := by diff --git a/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean index 6df21185d76b11..8b62e2ea3e1e21 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/CoverEntropy.lean @@ -227,9 +227,9 @@ lemma coverMincard_finite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : simp only [Nat.cast_inj] have : Nonempty {s : Finset X // IsDynCoverOf T F U n s} := by by_contra h - apply ENat.coe_ne_top k + apply ENat.natCast_ne_top k rw [k_min, coverMincard, iInf₂_eq_top] - simp only [ENat.coe_ne_top, imp_false] + simp only [ENat.natCast_ne_top, imp_false] rw [nonempty_subtype, not_exists] at h exact h have key := ciInf_mem fun s : {s : Finset X // IsDynCoverOf T F U n s} ↦ (s.val.card : ℕ∞) @@ -417,7 +417,7 @@ lemma coverEntropyEntourage_finite_of_isCompact_invariant [UniformSpace X] apply (coverEntropyEntourage_antitone T F V_U).trans_lt apply (s_cover.coverEntropyEntourage_le_log_card_div F_inv one_ne_zero).trans_lt rw [Nat.cast_one, div_one, log_lt_top_iff, ← ENat.toENNReal_top] - exact_mod_cast (ENat.coe_ne_top (Finset.card s)).lt_top + exact_mod_cast (ENat.natCast_ne_top (Finset.card s)).lt_top /-! ### Cover entropy -/ diff --git a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean index 0cfa839f9efe76..5e35956c7197c3 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/NetEntropy.lean @@ -125,14 +125,14 @@ lemma netMaxcard_finite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : ℕ) have : netMaxcard T F U n = sSup (WithTop.some '' Finset.card '' {s : Finset X | IsDynNetIn T F U n s}) := by rw [netMaxcard, ← image_comp, sSup_image] - simp only [mem_ofPred_eq, ENat.some_eq_coe, Function.comp_apply] + simp only [mem_ofPred_eq, ENat.some_eq_natCast, Function.comp_apply] exact biSup_congr (fun _ _ ↦ rfl) rw [this] at k_max have h_bdda : BddAbove (Finset.card '' {s : Finset X | IsDynNetIn T F U n s}) := by refine ⟨k, mem_upperBounds.2 ?_⟩ simp only [mem_image, mem_ofPred_eq, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] intro s h - rw [← ENat.coe_le_coe, k_max] + rw [← ENat.natCast_le_natCast, k_max] apply le_sSup exact Filter.frequently_principal.mp fun a ↦ a (by simpa using ⟨_, h, rfl⟩) rfl have h_nemp : (Finset.card '' {s : Finset X | IsDynNetIn T F U n s}).Nonempty := by @@ -193,7 +193,7 @@ lemma netMaxcard_infinite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : apply Iff.intro <;> intro h · intro k rw [netMaxcard, iSup_subtype', iSup_eq_top] at h - specialize h k (ENat.coe_lt_top k) + specialize h k (ENat.natCast_lt_top k) simp only [Nat.cast_lt, Subtype.exists, exists_prop] at h obtain ⟨s, s_net, s_k⟩ := h exact ⟨s, s_net, s_k.le⟩ @@ -201,7 +201,7 @@ lemma netMaxcard_infinite_iff (T : X → X) (F : Set X) (U : SetRel X X) (n : specialize h (k + 1) obtain ⟨s, s_net, s_card⟩ := h apply s_net.card_le_netMaxcard.trans_lt' - rw [ENat.coe_lt_coe] + rw [Nat.cast_lt] exact (lt_add_one k).trans_le s_card lemma netMaxcard_le_coverMincard (T : X → X) (F : Set X) (n : ℕ) : diff --git a/Mathlib/Dynamics/TopologicalEntropy/Subset.lean b/Mathlib/Dynamics/TopologicalEntropy/Subset.lean index 721a6d24706bb2..77992ea71884af 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/Subset.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/Subset.lean @@ -157,7 +157,7 @@ lemma coverMincard_union_le (T : X → X) (F G : Set X) (U : SetRel X X) (n : · rw [hG, add_top]; exact le_top obtain ⟨s, s_cover, s_coverMincard⟩ := (coverMincard_finite_iff T F U n).1 hF obtain ⟨t, t_cover, t_coverMincard⟩ := (coverMincard_finite_iff T G U n).1 hG - rw [← s_coverMincard, ← t_coverMincard, ← ENat.coe_add] + rw [← s_coverMincard, ← t_coverMincard, ← ENat.natCast_add] apply (IsDynCoverOf.coverMincard_le_card _).trans (WithTop.coe_mono (s.card_union_le t)) rw [s.coe_union t] exact s_cover.union t_cover diff --git a/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean b/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean index d80e862c7214c6..94543ff1b6bf12 100644 --- a/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean +++ b/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean @@ -202,7 +202,7 @@ theorem isMultiplyPreprimitive_succ_iff_ofStabilizer apply congr_arg₂ _ _ rfl rw [show s = g⁻¹ • s' by simp [hs'], ← Set.image_smul, (MulAction.injective g⁻¹).encard_image, hst] - rw [Set.encard_insert_of_notMem, Subtype.coe_injective.encard_image, ENat.coe_one] + rw [Set.encard_insert_of_notMem, Subtype.coe_injective.encard_image, ENat.natCast_one] exact notMem_val_image M t /-- The fixator of a subset of cardinal `d` in an `n`-primitive action @@ -264,7 +264,7 @@ theorem isMultiplyPreprimitive_of_le · apply hrec (isMultiplyPreprimitive_of_isMultiplyPretransitive_succ M α hα) (Nat.lt_succ_iff.mp hmn') - · refine le_trans ?_ hα; rw [ENat.coe_le_coe]; exact Nat.le_succ n + · refine le_trans ?_ hα; rw [ENat.natCast_le_natCast]; exact Nat.le_succ n variable {M α} diff --git a/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean b/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean index 36496e5dc9de92..baf5a3c7fb9dde 100644 --- a/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean +++ b/Mathlib/GroupTheory/Perm/MaximalSubgroups.lean @@ -187,7 +187,7 @@ theorem has_swap_mem_of_lt_stabilizer [DecidableEq α] exact finite_of_encard_eq_coe hα have hα : Nat.card α = 2 := by rw [← ENat.card_coe_set_eq, ENat.card_eq_coe_natCard, Nat.card_coe_set_eq, ncard_univ] at hα - exact ENat.coe_inj.mp hα + exact ENat.natCast_inj.mp hα have hα2 : Fact (Nat.card (Perm α)).Prime := by apply Fact.mk rw [Nat.card_perm, hα, Nat.factorial_two] diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index f8570364d77579..0d3653212c0910 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -1145,7 +1145,7 @@ lemma MeasureTheory.Measure.sum_restrict_le {_ : MeasurableSpace α} exact nsmul_le_nsmul_left zero_le <| calc {a ∈ F | a ∈ C}.card _ ≤ C.card := card_mono <| fun i hi ↦ (F.mem_filter.mp hi).2 _ = (C : Set ι).ncard := (ncard_coe_finset C).symm - _ ≤ M := ENat.toNat_le_of_le_coe hCM + _ ≤ M := ENat.toNat_le_of_le_natCast hCM _ = M • (μ.restrict (⋃ C ∈ Cs, (P C)) t) := by rw [← smul_sum, ← Cs.tsum_subtype, μ.restrict_biUnion_finset _ P_meas, Measure.sum_apply _ ht] refine fun C₁ hC₁ C₂ hC₂ hC ↦ Set.disjoint_iff.mpr fun x hx ↦ hC <| ?_ diff --git a/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean b/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean index 338c97bf8495d0..9e0d76ea087884 100644 --- a/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean +++ b/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean @@ -297,7 +297,7 @@ theorem sturm_bound_levelOne_nat {k : ℕ} {f : ModularForm 𝒮ℒ (k : ℤ)} have hsucc : k / 12 = (k - 12) / 12 + 1 := by lia rw [qExpansion_eq_qExpansion_discriminant_mul f h0, PowerSeries.order_mul, discriminant_qExpansion_order, add_comm, hsucc, Nat.cast_add, Nat.cast_one] at h - exact (ENat.add_lt_add_iff_right (ENat.coe_ne_top 1)).mp h + exact (ENat.add_lt_add_iff_right (ENat.natCast_ne_top 1)).mp h /-- **Sturm bound for level-1 modular forms.** If a modular form `f` of weight `k` for `SL(2, ℤ)` has q-expansion of order strictly greater than `k / 12`, then `f` is identically zero. diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean index f60bf3daf50e2a..ed1f884df164be 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Ideal.lean @@ -324,7 +324,7 @@ theorem ramificationIdx_eq_of_not_dvd (hm : ¬ p ∣ m) : · apply emultiplicity_le_one_of_separable · exact isUnit_iff_degree_eq_zero.not.mpr (Irreducible.degree_pos h₂.1).ne' · exact (zeta_spec m ℚ K).toInteger_isPrimitiveRoot.separable_minpoly_mod hm - · rw [ENat.coe_one] + · rw [ENat.natCast_one] exact Order.one_le_iff_pos.mpr <| emultiplicity_pos_of_dvd h₂.2.2 theorem inertiaDegIn_eq_of_not_dvd (hm : ¬ p ∣ m) : diff --git a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean index 28a3121252e60b..5d99ec1a0fe21e 100644 --- a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean +++ b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean @@ -186,7 +186,8 @@ theorem padicValNat_self [Fact p.Prime] : padicValNat p p = 1 := by theorem one_le_padicValNat_of_dvd {n : ℕ} [hp : Fact p.Prime] (hn : n ≠ 0) (div : p ∣ n) : 1 ≤ padicValNat p n := by - rwa [← ENat.coe_le_coe, padicValNat_eq_emultiplicity hn, ← pow_dvd_iff_le_emultiplicity, pow_one] + rwa [← ENat.natCast_le_natCast, padicValNat_eq_emultiplicity hn, + ← pow_dvd_iff_le_emultiplicity, pow_one] theorem dvd_iff_padicValNat_ne_zero {p n : ℕ} [Fact p.Prime] (hn0 : n ≠ 0) : p ∣ n ↔ padicValNat p n ≠ 0 := diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index ebc60f5c915fb6..5d637a67b8c2af 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -204,7 +204,7 @@ lemma length_le_height {p : LTSeries α} {x : α} (hlast : p.last ≤ x) : simp only [Fin.succ_mk, RelSeries.last, Fin.last] congr; lia) suffices p'.length ≤ height x by - simp only [RelSeries.snoc_length, RelSeries.eraseLast_length, Nat.cast_add, ENat.coe_sub, + simp only [RelSeries.snoc_length, RelSeries.eraseLast_length, Nat.cast_add, ENat.natCast_sub, Nat.cast_one, p'] at this convert! this norm_cast @@ -360,7 +360,7 @@ lemma coheight_orderIso (f : α ≃o β) (x : α) : coheight (f x) = coheight x private lemma exists_eq_iSup_of_iSup_eq_coe {α : Type*} [Nonempty α] {f : α → ℕ∞} {n : ℕ} (h : (⨆ x, f x) = n) : ∃ x, f x = n := by - obtain ⟨x, hx⟩ := ENat.sSup_mem_of_nonempty_of_lt_top (h ▸ ENat.coe_lt_top _) + obtain ⟨x, hx⟩ := ENat.sSup_mem_of_nonempty_of_lt_top (h ▸ ENat.natCast_lt_top _) use x simpa [hx] using! h @@ -371,7 +371,7 @@ lemma exists_series_of_le_height (a : α) {n : ℕ} (h : n ≤ height a) : cases ha : height a with | top => clear h - rw [height_eq_iSup_last_eq, iSup_subtype', ENat.iSup_coe_eq_top, bddAbove_def] at ha + rw [height_eq_iSup_last_eq, iSup_subtype', ENat.iSup_natCast_eq_top, bddAbove_def] at ha contrapose! ha use n rintro m ⟨⟨p, rfl⟩, hp⟩ @@ -445,7 +445,7 @@ lemma height_eq_top_iff {x : α} : apply exists_series_of_le_height x (n := n) simp [h] mpr h := by - rw [height_eq_iSup_last_eq, iSup_subtype', ENat.iSup_coe_eq_top, bddAbove_def] + rw [height_eq_iSup_last_eq, iSup_subtype', ENat.iSup_natCast_eq_top, bddAbove_def] push Not intro n obtain ⟨p, hlast, hp⟩ := h (n + 1) @@ -746,7 +746,7 @@ lemma krullDim_eq_iSup_length [Nonempty α] : lemma krullDim_lt_coe_iff {n : ℕ} : krullDim α < n ↔ ∀ l : LTSeries α, l.length < n := by rw [krullDim, ← WithBot.coe_natCast] rcases n with - | n - · rw [ENat.coe_zero, ← bot_eq_zero, WithBot.lt_coe_bot] + · rw [ENat.natCast_zero, ← bot_eq_zero, WithBot.lt_coe_bot] simp · simp [ENat.WithBot.lt_add_one_iff, WithBot.coe_natCast] @@ -1113,15 +1113,15 @@ lemma height_le_of_krullDim_preimage_le (x : α) : let i : Fin (p.length + 1) := ⟨p.length - (m + 1), Nat.sub_lt_succ p.length _⟩ suffices h'' : f (p i) < f x by obtain ⟨n', hn'⟩ : ∃ (n' : ℕ), n' = height (f (p i)) := ENat.ne_top_iff_exists.mp - ((height_mono h''.le).trans_lt (h' ▸ ENat.coe_lt_top _)).ne - have h_lt : n' < n := ENat.coe_lt_coe.mp - (h' ▸ hn' ▸ height_strictMono h'' (hn' ▸ ENat.coe_lt_top _)) + ((height_mono h''.le).trans_lt (h' ▸ ENat.natCast_lt_top _)).ne + have h_lt : n' < n := ENat.natCast_lt_natCast.mp + (h' ▸ hn' ▸ height_strictMono h'' (hn' ▸ ENat.natCast_lt_top _)) have := (length_le_height_last (p := p.take i)).trans <| ih n' h_lt (p i) hn'.symm - rw [RelSeries.take_length, ENat.coe_sub, Nat.cast_add, Nat.cast_one, tsub_le_iff_right, + rw [RelSeries.take_length, ENat.natCast_sub, Nat.cast_add, Nat.cast_one, tsub_le_iff_right, add_assoc, add_comm _ (_ + 1), ← add_assoc, ← mul_add_one] at this refine not_lt_of_ge ?_ (h_len.trans_le this) gcongr - rwa [← ENat.coe_one, ← ENat.coe_add, ENat.coe_le_coe] + rwa [← ENat.natCast_one, ← ENat.natCast_add, ENat.natCast_le_natCast] refine (f.monotone ((p.monotone (Fin.le_last _)).trans hp)).lt_of_not_ge fun h'' ↦ ?_ let q' : LTSeries α := p.drop i let q : LTSeries (f ⁻¹' {f x}) := ⟨q'.length, fun j ↦ ⟨q' j, le_antisymm @@ -1130,7 +1130,7 @@ lemma height_le_of_krullDim_preimage_le (x : α) : (f.monotone (q'.monotone (Fin.zero_le _))))⟩, fun i ↦ q'.step i⟩ have := (LTSeries.length_le_krullDim q).trans (h (f x)) simp only [RelSeries.drop_length, Nat.cast_le, tsub_le_iff_right, q', i, q] at this - have : p.length > m := ENat.coe_lt_coe.mp ((le_add_left le_rfl).trans_lt h_len) + have : p.length > m := ENat.natCast_lt_natCast.mp ((le_add_left le_rfl).trans_lt h_len) lia include h in diff --git a/Mathlib/Probability/Martingale/BorelCantelli.lean b/Mathlib/Probability/Martingale/BorelCantelli.lean index ae70ff31aa470b..c373de1431710d 100644 --- a/Mathlib/Probability/Martingale/BorelCantelli.lean +++ b/Mathlib/Probability/Martingale/BorelCantelli.lean @@ -80,7 +80,7 @@ theorem stoppedAbove_le (hr : 0 ≤ r) (hf0 : f 0 = 0) (hbdd : ∀ᵐ ω ∂μ, ∀ i, |f (i + 1) ω - f i ω| ≤ R) (i : ℕ) : ∀ᵐ ω ∂μ, stoppedAbove f r i ω ≤ r + R := by filter_upwards [hbdd] with ω hbddω - rw [stoppedAbove, stoppedProcess, ENat.some_eq_coe] + rw [stoppedAbove, stoppedProcess, ENat.some_eq_natCast] by_cases h_zero : (min (i : ℕ∞) (leastGE f r ω)).untopA = 0 · simp only [h_zero, hf0, Pi.zero_apply] positivity diff --git a/Mathlib/Probability/Martingale/OptionalStopping.lean b/Mathlib/Probability/Martingale/OptionalStopping.lean index 58ee77a204452e..32f83b3ae779e6 100644 --- a/Mathlib/Probability/Martingale/OptionalStopping.lean +++ b/Mathlib/Probability/Martingale/OptionalStopping.lean @@ -81,11 +81,11 @@ theorem submartingale_of_expected_stoppedValue_mono [SigmaFiniteFiltration μ (isStoppingTime_const 𝒢 j) ?_ ⟨j, fun _ => le_rfl⟩ · intro ω - simp only [Set.piecewise, ENat.some_eq_coe] + simp only [Set.piecewise, ENat.some_eq_natCast] split_ifs with hω · exact mod_cast hij · norm_cast - · rwa [stoppedValue_const, ← ENat.some_eq_coe, stoppedValue_piecewise_const, + · rwa [stoppedValue_const, ← ENat.some_eq_natCast, stoppedValue_piecewise_const, integral_piecewise (𝒢.le _ _ hs) (hint _).integrableOn (hint _).integrableOn, ← integral_add_compl (𝒢.le _ _ hs) (hint j), add_le_add_iff_right] at hf diff --git a/Mathlib/Probability/Martingale/Upcrossing.lean b/Mathlib/Probability/Martingale/Upcrossing.lean index 559c97aea88063..74595c57259107 100644 --- a/Mathlib/Probability/Martingale/Upcrossing.lean +++ b/Mathlib/Probability/Martingale/Upcrossing.lean @@ -379,7 +379,7 @@ theorem StronglyAdapted.upcrossingStrat (hf : StronglyAdapted ℱ f) : stronglyMeasurable_const.indicator ?_ have hl := hf.isStoppingTime_lowerCrossingTime (a := a) (b := b) (N := N) (n := i) n have hu := hf.isStoppingTime_upperCrossingTime (a := a) (b := b) (N := N) (n := i + 1) n - simp only [ENat.some_eq_coe, Nat.cast_le] at hl hu + simp only [ENat.some_eq_natCast, Nat.cast_le] at hl hu simp_rw [← not_le] exact hl.inter hu.compl @@ -755,7 +755,7 @@ theorem StronglyAdapted.measurable_upcrossingsBefore (hf : StronglyAdapted ℱ f rw [this] refine Finset.measurable_fun_sum _ fun i _ => Measurable.indicator measurable_const <| ℱ.le N _ ?_ - simpa only [ENat.some_eq_coe, Nat.cast_lt] using! + simpa only [ENat.some_eq_natCast, Nat.cast_lt] using! hf.isStoppingTime_upperCrossingTime.measurableSet_lt_of_pred N theorem StronglyAdapted.integrable_upcrossingsBefore [IsFiniteMeasure μ] diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 15937a0508b42c..7b190245593c6d 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -1319,7 +1319,7 @@ theorem stoppedValue_eq {N : ℕ} (hbdd : ∀ ω, τ ω ≤ N) : stoppedValue u have h_top : τ ω ≠ ⊤ := fun h_contra ↦ by simp [h_contra] at hbdd lift τ ω to ℕ using h_top with t ht simp only [Nat.cast_le] at hbdd - simp only [ENat.some_eq_coe, Finset.coe_range] + simp only [ENat.some_eq_natCast, Finset.coe_range] exact ⟨t, by simpa, Nat.cast_inj.mpr rfl⟩ set_option backward.isDefEq.respectTransparency.types false in diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index 7738cf12dfc895..d64cab22b35496 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -189,7 +189,7 @@ theorem intValuation_eq_exp_neg_multiplicity {r : R} (hr : r ≠ 0) : have hsr : Ideal.span {r} ≠ 0 := Submodule.span_singleton_eq_bot.mp.mt hr have hfm : FiniteMultiplicity v.asIdeal (Ideal.span {r}) := FiniteMultiplicity.of_prime_left v.prime hsr - rw [v.intValuation_if_neg hr, exp_inj, neg_inj, Int.natCast_inj, ← ENat.coe_inj, + rw [v.intValuation_if_neg hr, exp_inj, neg_inj, Int.natCast_inj, ← ENat.natCast_inj, ← FiniteMultiplicity.emultiplicity_eq_multiplicity hfm, UniqueFactorizationMonoid.emultiplicity_eq_count_normalizedFactors (irreducible v) hsr, normalize_eq, Ideal.count_associates_factors_eq hsr v.isPrime v.ne_bot] @@ -260,9 +260,9 @@ theorem intValuation_le_exp_iff_le_emultiplicity {r : R} {n : ℕ} : theorem exp_le_intValuation_iff_emultiplicity_le {r : R} {n : ℕ} : exp (-(n : ℤ)) ≤ v.intValuation r ↔ emultiplicity v.asIdeal (Ideal.span {r}) ≤ n := by - rw [← ENat.lt_coe_add_one_iff, ← ENat.coe_one, ← ENat.coe_add, emultiplicity_lt_iff_not_dvd, - ← intValuation_le_pow_iff_dvd, not_le, Nat.cast_add, Nat.cast_one, neg_add, exp_add, - exp_neg 1, mul_inv_lt_iff₀ (by simp)] + rw [← ENat.lt_natCast_add_one_iff, ← ENat.natCast_one, ← ENat.natCast_add, + emultiplicity_lt_iff_not_dvd, ← intValuation_le_pow_iff_dvd, not_le, Nat.cast_add, Nat.cast_one, + neg_add, exp_add, exp_neg 1, mul_inv_lt_iff₀ (by simp)] by_cases hv : v.intValuation r = 0 · simp [hv] · rw [lt_mul_exp_iff_le hv] diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index 857bec77c16f18..70c655827665ef 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -500,7 +500,7 @@ lemma addVal_eq_iff_associated (x y : R) : simp only [hx', AddValuation.map_mul, addVal_eq_zero_of_unit, AddValuation.map_pow, nsmul_eq_mul, zero_add, hy', associated_unit_mul_right_iff, associated_unit_mul_left_iff] at h ⊢ - simp only [addVal_uniformizer hϖ, mul_one, ENat.coe_inj] at h + simp only [addVal_uniformizer hϖ, mul_one, ENat.natCast_inj] at h rw [h] exact Associates.mk_eq_mk_iff_associated.mp rfl · rintro ⟨u, rfl⟩ @@ -523,7 +523,7 @@ noncomputable def idealOrderIsoENat : Ideal R ≃o ENatᵒᵈ where · obtain ⟨ϖ, hϖ⟩ := exists_irreducible R obtain ⟨n, u, hu⟩ := eq_unit_mul_pow_irreducible hx0 hϖ rw [hu, addVal_def' u hϖ, span_singleton_mul_left_unit u.isUnit, - ENat.recTopCoe_coe, hϖ.maximalIdeal_eq, span_singleton_pow] + ENat.recTopCoe_natCast, hϖ.maximalIdeal_eq, span_singleton_pow] right_inv n := by obtain ⟨k, rfl⟩ := OrderDual.toDual.surjective n dsimp @@ -531,7 +531,7 @@ noncomputable def idealOrderIsoENat : Ideal R ≃o ENatᵒᵈ where | top => simp | coe k => obtain ⟨ϖ, hϖ⟩ := exists_irreducible R - rw [OrderDual.toDual_inj, ENat.recTopCoe_coe, hϖ.maximalIdeal_eq, + rw [OrderDual.toDual_inj, ENat.recTopCoe_natCast, hϖ.maximalIdeal_eq, span_singleton_pow, ← hϖ.addVal_pow k, addVal_eq_iff_associated] exact associated_generator_span_self (ϖ ^ k) map_rel_iff' {I J} := by diff --git a/Mathlib/RingTheory/Ideal/Height.lean b/Mathlib/RingTheory/Ideal/Height.lean index 64b9a4419ec3fd..55b2fb28a0fea1 100644 --- a/Mathlib/RingTheory/Ideal/Height.lean +++ b/Mathlib/RingTheory/Ideal/Height.lean @@ -52,7 +52,7 @@ lemma Ideal.height_eq_inf_minimalPrimes : I.height = ⨅ J ∈ I.minimalPrimes, lemma Ideal.exists_isPrime_height_eq {I : Ideal R} {n : ℕ} (hI : I.height = n) : ∃ (p : Ideal R) (_ : p.IsPrime) (_ : I ≤ p), p.height = n := by - simp only [Ideal.height, ENat.iInf_eq_coe_iff] at hI + simp only [Ideal.height, ENat.iInf_eq_natCast_iff] at hI rcases hI with ⟨⟨p, ⟨⟨⟨hpp, hIp⟩, _⟩, h⟩, -⟩, -⟩ exact ⟨p, hpp, hIp, h ▸ p.height_eq_primeHeight⟩ diff --git a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean index 5de9b5b9eac1f9..40ad2a3e8f8c53 100644 --- a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean +++ b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean @@ -194,7 +194,7 @@ nonrec lemma Ideal.height_le_spanRank_toENat_of_mem_minimalPrimes have := hp.isPrime cases n with | zero => - rw [ENat.coe_zero, nonpos_iff_eq_zero, height_eq_zero_iff, minimalPrimes] + rw [ENat.natCast_zero, nonpos_iff_eq_zero, height_eq_zero_iff, minimalPrimes] simp_all | succ n => wlog hR : ∃ (_ : IsLocalRing R), p = maximalIdeal R @@ -204,7 +204,7 @@ nonrec lemma Ideal.height_le_spanRank_toENat_of_mem_minimalPrimes exact this _ (s.image (algebraMap R (Localization p.primeCompl))) (by simpa using hp) inferInstance _ H (Finset.card_image_le.trans hn) ⟨inferInstance, rfl⟩ obtain ⟨_, rfl⟩ := hR - simp_rw [height_le_iff_covBy, ENat.coe_add, ENat.coe_one, ENat.lt_coe_add_one_iff] + simp_rw [height_le_iff_covBy, ENat.natCast_add, ENat.natCast_one, ENat.lt_natCast_add_one_iff] intro q hq hpq hq' obtain ⟨x, s', hxs', rfl, hxq⟩ : ∃ x s', x ∉ s' ∧ s = insert x s' ∧ x ∉ q := by have : ¬(s : Set R) ⊆ q := by @@ -271,7 +271,7 @@ lemma Ideal.height_le_spanRank (I : Ideal R) (hI : I ≠ ⊤) : instance Ideal.finiteHeight_of_isNoetherianRing (I : Ideal R) : I.FiniteHeight := finiteHeight_iff_lt.mpr <| Or.elim (em (I = ⊤)) Or.inl - fun h ↦ Or.inr <| (I.height_le_spanFinrank h).trans_lt (ENat.coe_lt_top _) + fun h ↦ Or.inr <| (I.height_le_spanFinrank h).trans_lt (ENat.natCast_lt_top _) instance [IsLocalRing R] : FiniteRingKrullDim R := by apply finiteRingKrullDim_iff_ne_bot_and_top.mpr @@ -286,12 +286,12 @@ instance [IsLocalRing R] : FiniteRingKrullDim R := by lemma Ideal.exists_spanRank_eq_and_height_eq (I : Ideal R) (hI : I ≠ ⊤) : ∃ J ≤ I, J.spanRank = I.height ∧ J.height = I.height := by obtain ⟨J, hJ₁, hJ₂, hJ₃⟩ := exists_spanRank_le_and_le_height_of_le_height I _ - (ENat.coe_toNat_le_self I.height) - rw [ENat.coe_toNat_eq_self.mpr (Ideal.height_ne_top hI)] at hJ₃ + (ENat.natCast_toNat_le_self I.height) + rw [ENat.natCast_toNat_eq_self.mpr (Ideal.height_ne_top hI)] at hJ₃ refine ⟨J, hJ₁, le_antisymm ?_ (le_trans ?_ (J.height_le_spanRank ?_)), le_antisymm (Ideal.height_mono hJ₁) hJ₃⟩ · convert! hJ₂ - exact Cardinal.ofENat_eq_nat.mpr (ENat.coe_toNat (I.height_ne_top hI)).symm + exact Cardinal.ofENat_eq_nat.mpr (ENat.natCast_toNat (I.height_ne_top hI)).symm · exact Cardinal.ofENat_le_ofENat_of_le hJ₃ · rintro rfl exact hI (top_le_iff.mp hJ₁) diff --git a/Mathlib/RingTheory/Ideal/NatInt.lean b/Mathlib/RingTheory/Ideal/NatInt.lean index 9ca28837740fee..732704a0faad64 100644 --- a/Mathlib/RingTheory/Ideal/NatInt.lean +++ b/Mathlib/RingTheory/Ideal/NatInt.lean @@ -94,7 +94,7 @@ theorem Ideal.isPrime_int_iff {P : Ideal ℤ} : theorem ringKrullDim_nat : ringKrullDim ℕ = 2 := by refine le_antisymm (iSup_le fun s ↦ le_of_not_gt fun hs ↦ ?_) ?_ - · replace hs : 2 < s.length := ENat.coe_lt_coe.mp (WithBot.coe_lt_coe.mp hs) + · replace hs : 2 < s.length := ENat.natCast_lt_natCast.mp (WithBot.coe_lt_coe.mp hs) let s := s.take ⟨3, by lia⟩ have : NeZero s.length := ⟨three_ne_zero⟩ have h1 : ⊥ < (s 1).asIdeal := bot_le.trans_lt (s.step 0) diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index c4ea958b61e5be..32e3fff999f4ea 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -308,7 +308,7 @@ theorem FiniteMultiplicity.not_of_unit_left (a : α) (u : αˣ) : ¬ FiniteMulti theorem emultiplicity_eq_zero : emultiplicity a b = 0 ↔ ¬a ∣ b := by by_cases hf : FiniteMultiplicity a b - · rw [← ENat.coe_zero, emultiplicity_eq_coe] + · rw [← ENat.natCast_zero, emultiplicity_eq_coe] simp · simpa [emultiplicity_eq_top.2 hf] using FiniteMultiplicity.not_iff_forall.1 hf 1 @@ -356,13 +356,13 @@ theorem emultiplicity_le_emultiplicity_iff {c d : β} : next h_2 => simp_all only [not_exists, Decidable.not_not, le_top] next h_1 => simp_all only [not_exists, Decidable.not_not, not_true_eq_false, top_le_iff, - dite_eq_right_iff, ENat.coe_ne_top, imp_false, not_false_eq_true, implies_true] + dite_eq_right_iff, ENat.natCast_ne_top, imp_false, not_false_eq_true, implies_true] theorem FiniteMultiplicity.multiplicity_le_multiplicity_iff {c d : β} (hab : FiniteMultiplicity a b) (hcd : FiniteMultiplicity c d) : multiplicity a b ≤ multiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b → c ^ n ∣ d := by - rw [← ENat.coe_le_coe, ← hab.emultiplicity_eq_multiplicity, ← hcd.emultiplicity_eq_multiplicity] - apply emultiplicity_le_emultiplicity_iff + rw [← ENat.natCast_le_natCast, ← hab.emultiplicity_eq_multiplicity, + ← hcd.emultiplicity_eq_multiplicity, emultiplicity_le_emultiplicity_iff] theorem emultiplicity_eq_emultiplicity_iff {c d : β} : emultiplicity a b = emultiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b ↔ c ^ n ∣ d := diff --git a/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean b/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean index 92710c44b43b68..2a578480230ac4 100644 --- a/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean +++ b/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean @@ -150,18 +150,18 @@ theorem weightedOrder_mul (w : σ → ℕ) (f g : MvPowerSeries σ R) : · by_cases hg : g.weightedOrder w < ⊤ · let p := (f.weightedOrder w).toNat have hp : p = f.weightedOrder w := by - simpa only [p, ENat.coe_toNat_eq_self, ← lt_top_iff_ne_top] + simpa only [p, ENat.natCast_toNat_eq_self, ← lt_top_iff_ne_top] let q := (g.weightedOrder w).toNat have hq : q = g.weightedOrder w := by - simpa only [q, ENat.coe_toNat_eq_self, ← lt_top_iff_ne_top] + simpa only [q, ENat.natCast_toNat_eq_self, ← lt_top_iff_ne_top] have : f.weightedHomogeneousComponent w p * g.weightedHomogeneousComponent w q ≠ 0 := by simp only [ne_eq, mul_eq_zero] intro H rcases H with H | H <;> · refine weightedHomogeneousComponent_of_weightedOrder ?_ H - simp only [ENat.coe_toNat_eq_self, ne_eq, weightedOrder_eq_top_iff, p, q] + simp only [ENat.natCast_toNat_eq_self, ne_eq, weightedOrder_eq_top_iff, p, q] rw [← ne_eq, ne_zero_iff_weightedOrder_finite w] - exact ENat.coe_toNat (ne_top_of_lt (by simpa)) + exact ENat.natCast_toNat (ne_top_of_lt (by simpa)) rw [← weightedHomogeneousComponent_mul_of_le_weightedOrder (le_of_eq hp) (le_of_eq hq)] at this rw [← hp, ← hq, ← Nat.cast_add, ← not_lt] diff --git a/Mathlib/RingTheory/MvPowerSeries/Order.lean b/Mathlib/RingTheory/MvPowerSeries/Order.lean index 9e2f8dabeae3bb..09420051194ecd 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Order.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Order.lean @@ -146,14 +146,14 @@ def weightedOrder (f : MvPowerSeries σ R) : ℕ∞ := by theorem ne_zero_iff_weightedOrder_finite : f ≠ 0 ↔ (f.weightedOrder w).toNat = f.weightedOrder w := by - simp only [weightedOrder, ne_eq, coe_toNat_eq_self, dite_eq_left_iff, - ENat.coe_ne_top, imp_false, not_not] + simp only [weightedOrder, ne_eq, natCast_toNat_eq_self, dite_eq_left_iff, + ENat.natCast_ne_top, imp_false, not_not] /-- The `0` power series is the unique power series with infinite order. -/ @[simp] theorem weightedOrder_eq_top_iff : f.weightedOrder w = ⊤ ↔ f = 0 := by - rw [← not_iff_not, ← ne_eq, ← ne_eq, ne_zero_iff_weightedOrder_finite w, coe_toNat_eq_self] + rw [← not_iff_not, ← ne_eq, ← ne_eq, ne_zero_iff_weightedOrder_finite w, natCast_toNat_eq_self] /-- If the order of a formal power series `f` is finite, then some coefficient of weight equal to the order of `f` is nonzero. -/ @@ -186,7 +186,7 @@ theorem nat_le_weightedOrder {n : ℕ} (h : ∀ d, weight w d < n → coeff d f n ≤ f.weightedOrder w := by by_contra! H have : (f.weightedOrder w).toNat = f.weightedOrder w := by - rw [coe_toNat_eq_self]; exact ne_top_of_lt H + rw [natCast_toNat_eq_self]; exact ne_top_of_lt H obtain ⟨d, hfd, hd⟩ := exists_coeff_ne_zero_and_weightedOrder w this rw [← hd, Nat.cast_lt] at H exact hfd (h d H) @@ -197,9 +197,9 @@ theorem le_weightedOrder {n : ℕ∞} (h : ∀ d : σ →₀ ℕ, weight w d < n n ≤ f.weightedOrder w := by cases n · rw [top_le_iff, weightedOrder_eq_top_iff] - ext d; exact h d (ENat.coe_lt_top _) + ext d; exact h d (ENat.natCast_lt_top _) · apply nat_le_weightedOrder; - simpa only [ENat.some_eq_coe, Nat.cast_lt] using h + simpa only [ENat.some_eq_natCast, Nat.cast_lt] using h /-- The order of a formal power series is exactly `n` if and only if some coefficient of weight `n` is nonzero, and the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/ @@ -208,7 +208,7 @@ theorem weightedOrder_eq_nat {n : ℕ} : (∃ d, coeff d f ≠ 0 ∧ weight w d = n) ∧ ∀ d, weight w d < n → coeff d f = 0 := by constructor · intro h - obtain ⟨d, hd⟩ := f.exists_coeff_ne_zero_and_weightedOrder w (by simp only [h, toNat_coe]) + obtain ⟨d, hd⟩ := f.exists_coeff_ne_zero_and_weightedOrder w (by simp only [h, toNat_natCast]) exact ⟨⟨d, by simpa [h, Nat.cast_inj, ne_eq] using hd⟩, fun e he ↦ f.coeff_eq_zero_of_lt_weightedOrder w (by simp only [h, Nat.cast_lt, he])⟩ · rintro ⟨⟨d, hd', hd⟩, h⟩ @@ -623,7 +623,7 @@ theorem weightedHomogeneousComponent_of_weightedOrder {f : MvPowerSeries σ R} {p : ℕ} (hf : p = f.weightedOrder w) : f.weightedHomogeneousComponent w p ≠ 0 := by intro hf' - obtain ⟨d, hd⟩ := f.exists_coeff_ne_zero_and_weightedOrder w (by rw [← hf, toNat_coe]) + obtain ⟨d, hd⟩ := f.exists_coeff_ne_zero_and_weightedOrder w (by rw [← hf, toNat_natCast]) simp only [ne_eq, ← hf, Nat.cast_inj] at hd apply hd.1 rw [MvPowerSeries.ext_iff] at hf' @@ -669,10 +669,10 @@ theorem weightedHomogeneousComponent_mul_of_le_weightedOrder {f g : MvPowerSerie rcases trichotomy_of_add_eq_add hd with h | h | h · rw [if_pos h.1, if_pos h.2] · rw [if_neg (ne_of_lt h), zero_mul] - rw [← ENat.coe_lt_coe] at h + rw [← ENat.natCast_lt_natCast] at h rw [coeff_eq_zero_of_lt_weightedOrder w (lt_of_lt_of_le h hf), zero_mul] · rw [if_neg (ne_of_lt h), mul_zero] - rw [← ENat.coe_lt_coe] at h + rw [← ENat.natCast_lt_natCast] at h rw [coeff_eq_zero_of_lt_weightedOrder w (lt_of_lt_of_le h hg), mul_zero] · symm apply IsWeightedHomogeneous.coeff_eq_zero _ hd diff --git a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean index 83891fff07bb91..d9447d155470ef 100644 --- a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean @@ -297,7 +297,7 @@ theorem summable_pow_of_constantCoeff_eq_zero {f : MvPowerSeries σ R} apply summable_of_tendsto_order_atTop_nhds_top simp_rw [ENat.tendsto_nhds_top_iff_natCast_lt, Filter.eventually_atTop] refine fun n ↦ ⟨n + 1, fun m hm ↦ lt_of_lt_of_le ?_ (le_order_pow _)⟩ - refine (ENat.coe_lt_coe.mpr (Nat.add_one_le_iff.mp hm)).trans_le ?_ + refine (ENat.natCast_lt_natCast.mpr (Nat.add_one_le_iff.mp hm)).trans_le ?_ simpa [nsmul_eq_mul] using ENat.self_le_mul_right m (order_ne_zero_iff_constCoeff_eq_zero.mpr h) section GeomSeries diff --git a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean index 6f1cc894d1adac..a5805af5c8630d 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean @@ -250,7 +250,7 @@ def ordMonoidWithZeroHom [Nontrivial R] : R →*₀ ℤᵐ⁰ where generalize ord R y = y' cases x' <;> cases y' on_goal 4 => - simp only [← ENat.coe_add, ENat.recTopCoe_coe, Nat.cast_add (R := ℤ), + simp only [← ENat.natCast_add, ENat.recTopCoe_natCast, Nat.cast_add (R := ℤ), ofAdd_add, WithZero.coe_mul] all_goals simp all_goals simp_all [mul_mem_nonZeroDivisors] diff --git a/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean b/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean index 29fed9bd750345..ee87c5495bbc8a 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean @@ -45,15 +45,15 @@ def ordMonoidHom : R⁰ →* Multiplicative ℕ where @[simp] lemma ordMonoidHom_eq_ord (x : R⁰) : (ordMonoidHom x).toAdd = Ring.ord R x := - (ENat.coe_toNat (ord_ne_top x.2)) + (ENat.natCast_toNat (ord_ne_top x.2)) @[simp] lemma ordMonoidWithZeroHom_eq_ordMonoidHom [Nontrivial R] (x : R⁰) : .coe (.ofAdd ((ordMonoidHom x).toAdd : ℤ)) = ordMonoidWithZeroHom R x := by simp only [SetLike.coe_mem, ordMonoidWithZeroHom_eq_ord, ordMonoidHom, MonoidHom.coe_mk, OneHom.coe_mk, toAdd_ofAdd] - rw [← ENat.coe_lift (ord R x.1) (ord_lt_top x.2), ENat.recTopCoe_coe, - ENat.coe_lift, ENat.lift_eq_toNat_of_lt_top] + rw [← ENat.natCast_lift (ord R x.1) (ord_lt_top x.2), ENat.recTopCoe_natCast, + ENat.natCast_lift, ENat.lift_eq_toNat_of_lt_top] /-- Analogue of `ord_ne_top` for `ordMonoidWithZeroHom`. diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/Distinguished.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/Distinguished.lean index 1afbd10b315879..553177cb1a5e02 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/Distinguished.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/Distinguished.lean @@ -66,8 +66,8 @@ lemma degree_eq_coe_lift_order_map (distinguish : g.IsDistinguishedAt I) (order_finite_iff_ne_zero.2 (distinguish.map_ne_zero_of_eq_mul f h notMem eq)) := by have : Nontrivial R := _root_.nontrivial_iff.mpr ⟨0, PowerSeries.constantCoeff h, ne_of_mem_of_not_mem I.zero_mem notMem⟩ - rw [Polynomial.degree_eq_natDegree distinguish.monic.ne_zero, Nat.cast_inj, ← ENat.coe_inj, - ENat.coe_lift, Eq.comm, PowerSeries.order_eq_nat] + rw [Polynomial.degree_eq_natDegree distinguish.monic.ne_zero, Nat.cast_inj, ← ENat.natCast_inj, + ENat.natCast_lift, Eq.comm, PowerSeries.order_eq_nat] have mapf : f.map (Ideal.Quotient.mk I) = (Polynomial.X ^ g.natDegree : (R ⧸ I)[X]) * h.map (Ideal.Quotient.mk I) := by simp [← map_eq_X_pow distinguish, eq] @@ -80,7 +80,7 @@ lemma coe_natDegree_eq_order_map (distinguish : g.IsDistinguishedAt I) (notMem : PowerSeries.constantCoeff h ∉ I) (eq : f = g * h) : g.natDegree = (f.map (Ideal.Quotient.mk I)).order := by rw [natDegree, distinguish.degree_eq_coe_lift_order_map f h notMem eq] - exact ENat.coe_lift _ <| order_finite_iff_ne_zero.2 <| + exact ENat.natCast_lift _ <| order_finite_iff_ne_zero.2 <| distinguish.map_ne_zero_of_eq_mul f h notMem eq end degree_eq_order_map diff --git a/Mathlib/RingTheory/PowerSeries/Order.lean b/Mathlib/RingTheory/PowerSeries/Order.lean index 34d20eb1524bf4..68ed7443035f79 100644 --- a/Mathlib/RingTheory/PowerSeries/Order.lean +++ b/Mathlib/RingTheory/PowerSeries/Order.lean @@ -70,7 +70,7 @@ theorem order_eq_top {φ : R⟦X⟧} : φ.order = ⊤ ↔ φ = 0 := by simpa using order_finite_iff_ne_zero.not_left theorem coe_toNat_order {φ : R⟦X⟧} (hf : φ ≠ 0) : φ.order.toNat = φ.order := by - rw [ENat.coe_toNat_eq_self.mpr (order_eq_top.not.mpr hf)] + rw [ENat.natCast_toNat_eq_self.mpr (order_eq_top.not.mpr hf)] /-- If the order of a formal power series is finite, then the coefficient indexed by the order is nonzero. -/ @@ -97,7 +97,7 @@ theorem coeff_of_lt_order_toNat (n : ℕ) (h : n < φ.order.toNat) : coeff n φ by_cases h' : φ = 0 · simp [h'] · refine coeff_of_lt_order _ ?_ - rwa [← coe_toNat_order h', ENat.coe_lt_coe] + rwa [← coe_toNat_order h', ENat.natCast_lt_natCast] /-- The order of a formal power series is at least `n` if the `i`th coefficient is `0` for all `i < n`. -/ @@ -343,7 +343,7 @@ theorem order_eq_emultiplicity_X {R : Type*} [Semiring R] (φ : R⟦X⟧) : · rw [X_pow_eq, order_monomial] split_ifs · simp - · rw [← hn, ENat.coe_lt_coe] + · rw [← hn, ENat.natCast_lt_natCast] simp end OrderBasic @@ -398,7 +398,7 @@ theorem order_mul (φ ψ : R⟦X⟧) : order (φ * ψ) = order φ + order ψ := apply le_antisymm _ (le_order_mul _ _) by_cases! h : φ = 0 ∨ ψ = 0 · rcases h with h | h <;> simp [h] - · rw [← coe_toNat_order h.1, ← coe_toNat_order h.2, ← ENat.coe_add] + · rw [← coe_toNat_order h.1, ← coe_toNat_order h.2, ← ENat.natCast_add] apply order_le rw [coeff_mul, Finset.sum_eq_single_of_mem ⟨φ.order.toNat, ψ.order.toNat⟩ (by simp)] · exact mul_ne_zero (coeff_order h.1) (coeff_order h.2) diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index 858337d1921ab3..33298caa981ff9 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -94,7 +94,7 @@ theorem ramificationIdx_eq_one [q.IsPrime] [Algebra.EssFiniteType R S] let Sq := Localization.AtPrime q let : Algebra Rp Sq := Localization.AtPrime.algebraOfLiesOver p q have : Algebra.EssFiniteType Rp Sq := Algebra.EssFiniteType.of_comp R Rp Sq - rw [ramificationIdx_def, ENat.toNat_eq_iff_eq_coe, Nat.cast_one, Module.length_eq_one_iff, + rw [ramificationIdx_def, ENat.toNat_eq_iff_eq_natCast, Nat.cast_one, Module.length_eq_one_iff, isSimpleModule_iff_isCoatom, ← Ideal.isMaximal_def, IsLocalRing.isMaximal_iff, IsScalarTower.algebraMap_eq R Rp Sq, ← map_map, Localization.AtPrime.map_eq_maximalIdeal] exact Algebra.FormallyUnramified.map_maximalIdeal @@ -106,7 +106,7 @@ theorem ramificationIdx_eq_one_iff [q.IsPrime] [Algebra.EssFiniteType R S] [Algebra.IsIntegral R S] [PerfectField (q.under R).ResidueField] : q.ramificationIdx R = 1 ↔ Algebra.IsUnramifiedAt R q := by refine ⟨fun h ↦ ?_, fun _ ↦ ramificationIdx_eq_one q R⟩ - rw [ramificationIdx_def, ENat.toNat_eq_iff_eq_coe, Nat.cast_one, Module.length_eq_one_iff, + rw [ramificationIdx_def, ENat.toNat_eq_iff_eq_natCast, Nat.cast_one, Module.length_eq_one_iff, isSimpleModule_iff_isCoatom, ← Ideal.isMaximal_def, IsLocalRing.isMaximal_iff] at h let p := q.under R let Rp := Localization.AtPrime p @@ -152,7 +152,7 @@ theorem ramificationIdx'_eq_ramificationIdx' [IsDedekindDomain S] rw [map_map, ← IsScalarTower.algebraMap_eq, Ideal.map_mul, Ideal.map_pow, map_eq_top_of_not_le (Localization.AtPrime q) hqI, mul_top, AtPrime.map_eq_maximalIdeal] at h have hSq := isDiscreteValuationRing_of_dedekind_domain S hq' (Localization.AtPrime q) - rw [ramificationIdx_eq p q, h, hSq.length_quotient_pow_maximalIdeal, ENat.toNat_coe] + rw [ramificationIdx_eq p q, h, hSq.length_quotient_pow_maximalIdeal, ENat.toNat_natCast] @[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_ramificationIdx'' := ramificationIdx'_eq_ramificationIdx' diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean index 9a08267a8ea4bd..00bd185a998460 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean @@ -107,7 +107,7 @@ theorem multiplicity_eq_count_normalizedFactors {a b : R} (ha : Irreducible a) ( multiplicity a b = (normalizedFactors b).count (normalize a) := by have := emultiplicity_eq_count_normalizedFactors ha hb rwa [(finiteMultiplicity_of_emultiplicity_eq_natCast this).emultiplicity_eq_multiplicity, - ENat.coe_inj] at this + ENat.natCast_inj] at this /-- The number of times an irreducible factor `p` appears in `normalizedFactors x` is defined by the number of times it divides `x`. @@ -176,7 +176,7 @@ lemma pow_dvd_pow_iff_dvd {a b : R} {n : ℕ} (hn : n ≠ 0) : a ^ n ∣ b ^ n intro H p hp have := H p hp rwa [emultiplicity_pow hp, emultiplicity_pow hp, - ENat.mul_le_mul_left_iff (by exact_mod_cast hn) (ENat.coe_ne_top _)] at this + ENat.mul_le_mul_left_iff (by exact_mod_cast hn) (ENat.natCast_ne_top _)] at this @[fun_prop] lemma hasFiniteMulSupport_fun_pow_multiplicity {α M : Type*} [CommMonoid M] [Subsingleton Rˣ] diff --git a/Mathlib/SetTheory/Cardinal/Embedding.lean b/Mathlib/SetTheory/Cardinal/Embedding.lean index 19818a5612b935..6ca8f1fb53ff78 100644 --- a/Mathlib/SetTheory/Cardinal/Embedding.lean +++ b/Mathlib/SetTheory/Cardinal/Embedding.lean @@ -55,15 +55,15 @@ theorem exists_embedding_disjoint_range_of_add_le_ENat_card apply nonempty_of_card_le rwa [Fintype.card_fin, ← add_le_add_iff_left s.ncard, ← Nat.card_eq_fintype_card, Nat.card_coe_set_eq, - ncard_add_ncard_compl, ← ENat.coe_le_coe, - ← ENat.card_eq_coe_natCard, ENat.coe_add] + ncard_add_ncard_compl, ← ENat.natCast_le_natCast, + ← ENat.card_eq_coe_natCard, ENat.natCast_add] · exact ⟨valEmbedding.trans s.toFinite.infinite_compl.to_subtype.natEmbedding⟩ theorem exists_embedding_disjoint_range_of_add_le_Nat_card [Finite α] (hs : s.ncard + n ≤ Nat.card α) : ∃ y : Fin n ↪ α, Disjoint s (range y) := by apply exists_embedding_disjoint_range_of_add_le_ENat_card - rwa [← ENat.coe_add, ENat.card_eq_coe_natCard, ENat.coe_le_coe] + rwa [← ENat.natCast_add, ENat.card_eq_coe_natCard, ENat.natCast_le_natCast] theorem restrictSurjective_of_add_le_ENatCard (hn : m + n ≤ ENat.card α) : Surjective (fun (x : Fin (m + n) ↪ α) ↦ (Fin.castAddEmb n).trans x) := by @@ -83,7 +83,7 @@ theorem restrictSurjective_of_le_ENatCard (hmn : m ≤ n) (hn : n ≤ ENat.card theorem restrictSurjective_of_add_le_natCard [Finite α] (hn : m + n ≤ Nat.card α) : Surjective (fun x : Fin (m + n) ↪ α ↦ (castAddEmb n).trans x) := by apply restrictSurjective_of_add_le_ENatCard - rwa [← ENat.coe_add, ENat.card_eq_coe_natCard, ENat.coe_le_coe] + rwa [← ENat.natCast_add, ENat.card_eq_coe_natCard, ENat.natCast_le_natCast] theorem restrictSurjective_of_le_natCard [Finite α] (hmn : m ≤ n) (hn : n ≤ Nat.card α) : Function.Surjective (fun x : Fin n ↪ α ↦ (castLEEmb hmn).trans x) := by diff --git a/Mathlib/SetTheory/Cardinal/NatCount.lean b/Mathlib/SetTheory/Cardinal/NatCount.lean index 88b38d96b78aad..6b223db08f53f8 100644 --- a/Mathlib/SetTheory/Cardinal/NatCount.lean +++ b/Mathlib/SetTheory/Cardinal/NatCount.lean @@ -31,7 +31,7 @@ theorem count_le_setENCard : count p n ≤ Set.encard { k | p k } := by exact Nat.count_le_cardinal n theorem count_le_setNCard (h : { k | p k }.Finite) : count p n ≤ Set.ncard { k | p k } := by - rw [Set.ncard_def, ← ENat.coe_le_coe, ENat.coe_toNat (by simpa)] + rw [Set.ncard_def, ← ENat.natCast_le_natCast, ENat.natCast_toNat (by simpa)] exact count_le_setENCard n end Nat diff --git a/Mathlib/Tactic/ENatToNat.lean b/Mathlib/Tactic/ENatToNat.lean index 756787614a3c71..fee98a99ea2925 100644 --- a/Mathlib/Tactic/ENatToNat.lean +++ b/Mathlib/Tactic/ENatToNat.lean @@ -27,9 +27,9 @@ public meta section namespace Mathlib.Tactic.ENatToNat -attribute [enat_to_nat_top] OfNat.ofNat_ne_zero ne_eq not_false_eq_true -attribute [enat_to_nat_top] ENat.coe_ne_top ENat.top_ne_coe ENat.coe_lt_top top_le_iff le_top -attribute [enat_to_nat_top] top_add ENat.sub_top ENat.top_sub_coe ENat.mul_top ENat.top_mul +attribute [enat_to_nat_top] OfNat.ofNat_ne_zero ne_eq not_false_eq_true ENat.natCast_ne_top + ENat.top_ne_natCast ENat.natCast_lt_top top_le_iff le_top +attribute [enat_to_nat_top] top_add ENat.sub_top ENat.top_sub_natCast ENat.mul_top ENat.top_mul @[enat_to_nat_top] lemma not_lt_top (x : ENat) : ¬(⊤ < x) := by cases x <;> simp @@ -50,7 +50,7 @@ attribute [enat_to_nat_top] top_add ENat.sub_top ENat.top_sub_coe ENat.mul_top E @[enat_to_nat_coe] lemma coe_one : (1 : ENat) = ((1 : ℕ) : ENat) := rfl -attribute [enat_to_nat_coe] ENat.coe_inj ENat.coe_le_coe ENat.coe_lt_coe +attribute [enat_to_nat_coe] ENat.natCast_inj ENat.natCast_le_natCast ENat.natCast_lt_natCast open Qq Lean Elab Tactic Term Meta in /-- Finds the first `ENat` in the context and applies the `cases` tactic to it. diff --git a/Mathlib/Topology/CWComplex/Classical/Basic.lean b/Mathlib/Topology/CWComplex/Classical/Basic.lean index 946ba6ba2375eb..3d5c0296936294 100644 --- a/Mathlib/Topology/CWComplex/Classical/Basic.lean +++ b/Mathlib/Topology/CWComplex/Classical/Basic.lean @@ -504,9 +504,10 @@ private lemma RelCWComplex.iUnion_openCell_eq_iUnion_closedCell [RelCWComplex C apply iUnion₂_subset fun l hl ↦ iUnion₂_subset fun i _ ↦ ?_ rw [← cellFrontier_union_openCell_eq_closedCell] apply union_subset - · exact (hm' l (Nat.le_of_lt_succ hl) ((ENat.coe_lt_coe.2 hl).trans hm) i) + · exact (hm' l (Nat.le_of_lt_succ hl) ((ENat.natCast_lt_natCast.2 hl).trans hm) i) · apply subset_union_of_subset_right - exact subset_iUnion₂_of_subset l ((ENat.coe_lt_coe.2 hl).trans hm) <| subset_iUnion _ i + exact subset_iUnion₂_of_subset l ((ENat.natCast_lt_natCast.2 hl).trans hm) <| + subset_iUnion _ i · exact subset_union_of_subset_right (subset_iUnion₂_of_subset m hm (subset_iUnion _ j)) _ lemma RelCWComplex.union_iUnion_openCell_eq_complex [RelCWComplex C D] : @@ -514,7 +515,7 @@ lemma RelCWComplex.union_iUnion_openCell_eq_complex [RelCWComplex C D] : suffices D ∪ ⋃ n, ⋃ (j : cell C n), openCell n j = D ∪ ⋃ (m : ℕ) (_ : m < (⊤ : ℕ∞)) (j : cell C m), closedCell m j by simpa [union] using this - simp_rw [← RelCWComplex.iUnion_openCell_eq_iUnion_closedCell, ENat.coe_lt_top, iUnion_true] + simp_rw [← RelCWComplex.iUnion_openCell_eq_iUnion_closedCell, ENat.natCast_lt_top, iUnion_true] lemma CWComplex.iUnion_openCell_eq_complex [CWComplex C] : ⋃ (n : ℕ) (j : cell C n), openCell n j = C := by @@ -1030,7 +1031,7 @@ lemma RelCWComplex.disjoint_skeletonLT_openCell [RelCWComplex C D] {n : ℕ∞} apply disjoint_openCell_of_ne intro simp_all only [Sigma.mk.inj_iff] - exact (lt_self_iff_false m).mp (ENat.coe_lt_coe.1 (hln.trans_le hnm)) + exact (lt_self_iff_false m).mp (ENat.natCast_lt_natCast.1 (hln.trans_le hnm)) /-- A skeleton and an open cell of a higher dimension are disjoint. -/ @[alias_in CWComplex] diff --git a/Mathlib/Topology/Instances/AddCircle/Defs.lean b/Mathlib/Topology/Instances/AddCircle/Defs.lean index 77ea785d6b0a06..01f3d741901d44 100644 --- a/Mathlib/Topology/Instances/AddCircle/Defs.lean +++ b/Mathlib/Topology/Instances/AddCircle/Defs.lean @@ -262,7 +262,7 @@ theorem finite_torsion_of_isSMulRegular (n : ℕ) (hn : IsSMulRegular 𝕜 n) : nontriviality 𝕜 obtain rfl | h0 := eq_or_ne n 0 exacts [hn.not_zero.elim, ENat.card_lt_top.mp <| - (card_torsion_le_of_isSMulRegular p n h0 hn).trans_lt <| ENat.coe_lt_top n] + (card_torsion_le_of_isSMulRegular p n h0 hn).trans_lt <| ENat.natCast_lt_top n] theorem card_torsion_le_of_isSMulRegular_int (n : ℤ) (h0 : n ≠ 0) (hn : IsSMulRegular 𝕜 n) : {x : AddCircle p | n • x = 0}.encard ≤ n.natAbs := by @@ -276,7 +276,7 @@ theorem finite_torsion_of_isSMulRegular_int (n : ℤ) (hn : IsSMulRegular 𝕜 n nontriviality 𝕜 obtain rfl | h0 := eq_or_ne n 0 exacts [hn.not_zero.elim, ENat.card_lt_top.mp <| - (card_torsion_le_of_isSMulRegular_int p n h0 hn).trans_lt <| ENat.coe_lt_top _] + (card_torsion_le_of_isSMulRegular_int p n h0 hn).trans_lt <| ENat.natCast_lt_top _] end Torsion diff --git a/Mathlib/Topology/Instances/ENat.lean b/Mathlib/Topology/Instances/ENat.lean index e60bfbe1582e96..17b2a2b60d21fd 100644 --- a/Mathlib/Topology/Instances/ENat.lean +++ b/Mathlib/Topology/Instances/ENat.lean @@ -56,7 +56,7 @@ theorem mem_nhds_iff {x : ℕ∞} {s : Set ℕ∞} (hx : x ≠ ⊤) : s ∈ 𝓝 simp [hx] theorem mem_nhds_natCast_iff (n : ℕ) {s : Set ℕ∞} : s ∈ 𝓝 (n : ℕ∞) ↔ (n : ℕ∞) ∈ s := - mem_nhds_iff (coe_ne_top _) + mem_nhds_iff (natCast_ne_top _) theorem tendsto_nhds_top_iff_natCast_lt {α : Type*} {l : Filter α} {f : α → ℕ∞} : Tendsto f l (𝓝 ⊤) ↔ ∀ n : ℕ, ∀ᶠ a in l, n < f a := by From 9eff1ee39c2aac897304f83a33cab038ce2a04a2 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Fri, 17 Jul 2026 11:54:42 +0000 Subject: [PATCH 0851/1300] chore(Tactic/Algebra): pin Lemmas import with `shake: keep` (#41805) The `algebra` tactic references the lemmas in `Mathlib.Tactic.Algebra.Lemmas` (`isNat_zero_eq`, `add_algebraMap`, `neg_algebraMap`, ...) only inside `q(...)` Qq quotations. These references are reflected as name data, not `Expr.const` nodes, so `lake shake` cannot see them and removes the import. This PR marks the import `-- shake: keep`, as is already done for the same Qq-output-dependency situation in e.g. `Mathlib/Tactic/TFAE.lean` and `Mathlib/Tactic/ITauto.lean`. This was found while investigating the breakage in #40343. Prepared with Claude code. --- Mathlib/Tactic/Algebra/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index 196a24afa6a3cd..8f111bbc098d17 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -6,7 +6,7 @@ Authors: Arend Mellendijk module public meta import Lean.Meta.Tactic.NormCast -public import Mathlib.Tactic.Algebra.Lemmas +public import Mathlib.Tactic.Algebra.Lemmas -- shake: keep (Qq output dependency) public import Mathlib.Tactic.Ring.RingNF /-! From f4bd7cb94316d8474b7170fcd8682390dbe351c0 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Fri, 17 Jul 2026 11:54:44 +0000 Subject: [PATCH 0852/1300] chore(Tactic/NormNum): pin Lean.Elab.Tactic.Try import with `shake: keep` (#41807) `Core.lean` uses the `register_try?_tactic` command, which is a builtin command that checks whether `Lean.Elab.Tactic.Try` is imported and, if not, logs a warning and returns without registering anything. Using a command is not a constant reference, so `lake shake` cannot see the dependency and replaces the import with the lighter `Lean.Meta.Tactic.Try.Collect`; this silently turns `register_try?_tactic norm_num` into a no-op (only a build warning, no error). This PR marks the import `-- shake: keep`. This was found while investigating the breakage in #40343. Prepared with Claude code. --- Mathlib/Tactic/NormNum/Core.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Tactic/NormNum/Core.lean b/Mathlib/Tactic/NormNum/Core.lean index a82d5d3ca3e269..576a8048ee47b9 100644 --- a/Mathlib/Tactic/NormNum/Core.lean +++ b/Mathlib/Tactic/NormNum/Core.lean @@ -9,7 +9,7 @@ public meta import Mathlib.Lean.Expr.Rat public import Mathlib.Tactic.Hint public import Mathlib.Tactic.NormNum.Result public meta import Mathlib.Util.Qq -public import Lean.Elab.Tactic.Try +public import Lean.Elab.Tactic.Try -- shake: keep (`register_try?_tactic` command dependency) /-! ## `norm_num` core functionality From adba4dba8da0689880ac609b429794a0fc967b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 17 Jul 2026 13:18:25 +0000 Subject: [PATCH 0853/1300] doc(NumberTheory/LSeries/PrimesInAP): delete auxiliary section header (#41851) The auxiliary section was deleted but not its header. --- Mathlib/NumberTheory/LSeries/PrimesInAP.lean | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean index 0c9debb74db2a0..3e305fe2df95dd 100644 --- a/Mathlib/NumberTheory/LSeries/PrimesInAP.lean +++ b/Mathlib/NumberTheory/LSeries/PrimesInAP.lean @@ -70,13 +70,6 @@ prime number, arithmetic progression, residue class, Dirichlet's Theorem @[expose] public section -/-! -### Auxiliary statements - -An infinite product or sum over a function supported in prime powers can be written -as an iterated product or sum over primes and natural numbers. --/ - /-! ### The L-series of the von Mangoldt function restricted to a residue class -/ From 47550252e70469195497c1f7b5ab861ab26a4c91 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:27:58 +0000 Subject: [PATCH 0854/1300] perf(Tactic/Linter/Style): don't fold info trees in `show` linter (#41761) This PR re-implements the `show` linter to not search the info tree, and instead work directly in the syntax. --- Mathlib/Init.lean | 2 + Mathlib/RingTheory/WittVector/Truncated.lean | 2 +- Mathlib/Tactic/Linter/Style.lean | 51 +++++++++----------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/Mathlib/Init.lean b/Mathlib/Init.lean index e49829ccc5766f..7628dfa0a20bed 100644 --- a/Mathlib/Init.lean +++ b/Mathlib/Init.lean @@ -146,3 +146,5 @@ run_cmd liftTermElabM do let some cinfo := env.find? mlRes | throwError "{mlRes}: this code should be unreachable." if !cinfo.type.isAppOf ``Lean.Option then throwError "{.ofConstName mlRes} is not an option, it is a{indentD cinfo.type}" + +#allow_unused_tactic! Mathlib.Linter.Style.show diff --git a/Mathlib/RingTheory/WittVector/Truncated.lean b/Mathlib/RingTheory/WittVector/Truncated.lean index c5bf274255efd8..00fd63733332b1 100644 --- a/Mathlib/RingTheory/WittVector/Truncated.lean +++ b/Mathlib/RingTheory/WittVector/Truncated.lean @@ -197,7 +197,7 @@ end TruncatedWittVector /-- A macro tactic used to prove that `truncateFun` respects ring operations. -/ macro (name := witt_truncateFun_tac) "witt_truncateFun_tac" : tactic => `(tactic| - { show _ = WittVector.truncateFun n _ + { change _ = WittVector.truncateFun n _ apply TruncatedWittVector.out_injective iterate rw [WittVector.out_truncateFun] first diff --git a/Mathlib/Tactic/Linter/Style.lean b/Mathlib/Tactic/Linter/Style.lean index a3ed8ab4a86ac6..8e1d4af6bcdea4 100644 --- a/Mathlib/Tactic/Linter/Style.lean +++ b/Mathlib/Tactic/Linter/Style.lean @@ -628,35 +628,28 @@ public register_option linter.style.show : Bool := { descr := "enable the show linter" } -namespace Style.show +namespace Style -@[inherit_doc Mathlib.Linter.linter.style.show] -def showLinter : Linter where run := withSetOptionIn fun stx => do - unless getLinterValue linter.style.show (← getLinterOptions) do - return - if (← get).messages.hasErrors then - return - for tree in (← getInfoTrees) do - tree.foldInfoM (init := ()) fun ci i _ => do - let .ofTacticInfo tac := i | return - unless tac.stx.isOfKind ``Lean.Parser.Tactic.show do return - let some _ := tac.stx.getRange? true | return - let (goal :: goals) := tac.goalsBefore | return - let (goal' :: goals') := tac.goalsAfter | return - if goals != goals' then return -- `show` didn't act on first goal -> can't replace with `change` - -- Even if `goal == goal'`, the tactic may have assigned metavariables. - let diff ← ci.runCoreM do - let before ← (do instantiateMVars (← goal.getType)).run' {} { mctx := tac.mctxBefore } - let after ← (do instantiateMVars (← goal'.getType)).run' {} { mctx := tac.mctxAfter } - return before != after - if diff then - logLint linter.style.show tac.stx m!"\ - The `show` tactic should only be used to indicate intermediate goal states for \ - readability.\nHowever, this tactic invocation changed the goal. Please use `change` \ - instead for these purposes." - -initialize addLinter showLinter - -end Style.show +open Tactic + +/-- Run the `show` tactic, with a linter warning when one should use `change` instead. -/ +def elabShow (newType : Term) : TacticM Unit := do + let goal :: goals ← getGoals | throwNoGoalsToBeSolved + let before ← instantiateMVars (← goal.getType) + evalTactic (← `(tactic| show $newType)) + if getLinterValue linter.style.show (← getLinterOptions) then + let goal' :: goals' ← getGoals | return + if goals != goals' then return -- `show` didn't act on first goal -> can't replace with `change` + let after ← instantiateMVars (← goal'.getType) + if before != after then + logLint linter.style.show (← getRef) m!"\ + The `show` tactic should only be used to indicate intermediate goal states for \ + readability.\nHowever, this tactic invocation changed the goal. Please use `change` \ + instead for these purposes." + +@[tactic_alt Tactic.show] +elab (name := «show») "show " newType:term : tactic => elabShow newType + +end Style end Mathlib.Linter From 8449c32ba46b9e3cbfa7d10b4071130c4cc04c19 Mon Sep 17 00:00:00 2001 From: Qinghev <38534045+Qinghev@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:06:29 +0000 Subject: [PATCH 0855/1300] Add docstrings for reversed range telescoping lemmas (#39605) This PR adds docstrings for two existing `Finset` telescoping lemmas and their additive versions generated by `to_additive`: * `Finset.prod_range_div'` / `Finset.sum_range_sub'` * `Finset.eq_prod_range_div` / `Finset.eq_sum_range_sub` It is documentation-only: no declarations or imports are changed. CI has passed. AI assistance: Codex was used to help inspect the public PR/CI status and update this PR description. --- Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index a4436803d59118..b7faa997208659 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -896,11 +896,17 @@ additive group reduces to the difference of the last and first terms. -/] lemma prod_range_div (f : ℕ → G) (n : ℕ) : (∏ i ∈ range n, f (i + 1) / f i) = f n / f 0 := by apply prod_range_induction <;> simp -@[to_additive] +/-- A reversed telescoping product along `{0, ..., n - 1}` of a commutative-group-valued function +reduces to the ratio of the first and last factors. -/ +@[to_additive /-- A reversed telescoping sum along `{0, ..., n - 1}` of a function valued in a +commutative additive group reduces to the difference of the first and last terms. -/] lemma prod_range_div' (f : ℕ → G) (n : ℕ) : (∏ i ∈ range n, f i / f (i + 1)) = f 0 / f n := by apply prod_range_induction <;> simp -@[to_additive] +/-- Express `f n` as `f 0` multiplied by the telescoping product of consecutive ratios from +`0` to `n - 1`. -/ +@[to_additive /-- Express `f n` as `f 0` plus the telescoping sum of consecutive differences from +`0` to `n - 1`. -/] lemma eq_prod_range_div (f : ℕ → G) (n : ℕ) : f n = f 0 * ∏ i ∈ range n, f (i + 1) / f i := by rw [prod_range_div, mul_div_cancel] From 7ffc1c27cb91ddf84fa84efbfa01c3578c39d54f Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 17 Jul 2026 16:51:06 +0000 Subject: [PATCH 0856/1300] chore(GroupTheory): rename `IsSolvable` to `Group.IsSolvable` (#41820) Renames `IsSolvable` to `Group.IsSolvable`. --- Archive/Wiedijk100Theorems/AbelRuffini.lean | 4 +- Mathlib/FieldTheory/AbelRuffini.lean | 63 ++++++------ Mathlib/FieldTheory/Normal/Basic.lean | 6 +- Mathlib/GroupTheory/IsPerfect.lean | 2 +- Mathlib/GroupTheory/Nilpotent.lean | 2 +- Mathlib/GroupTheory/Solvable.lean | 96 ++++++++++++++----- .../GroupTheory/SpecificGroups/ZGroup.lean | 6 +- 7 files changed, 112 insertions(+), 67 deletions(-) diff --git a/Archive/Wiedijk100Theorems/AbelRuffini.lean b/Archive/Wiedijk100Theorems/AbelRuffini.lean index b4e87d9ea25164..36cad23bca78d9 100644 --- a/Archive/Wiedijk100Theorems/AbelRuffini.lean +++ b/Archive/Wiedijk100Theorems/AbelRuffini.lean @@ -155,8 +155,8 @@ theorem not_solvable_by_rad (p : ℕ) (x : ℂ) (hx : aeval x (Φ ℚ a b) = 0) have h_irred := irreducible_Phi a b p hp hpa hpb hp2b apply mt (isSolvable_gal_of_irreducible · h_irred hx) intro h - refine Equiv.Perm.not_solvable _ (le_of_eq ?_) - (solvable_of_surjective (gal_Phi a b hab h_irred).2) + refine Equiv.Perm.not_isSolvable _ (le_of_eq ?_) + (Group.isSolvable_of_surjective (gal_Phi a b hab h_irred).2) rw_mod_cast [Cardinal.mk_fintype, complex_roots_Phi a b h_irred.separable] theorem not_solvable_by_rad' (x : ℂ) (hx : aeval x (Φ ℚ 4 2) = 0) : x ∉ solvableByRad ℚ ℂ := by diff --git a/Mathlib/FieldTheory/AbelRuffini.lean b/Mathlib/FieldTheory/AbelRuffini.lean index d3363e964bb3b0..4ccaa3a7ac3635 100644 --- a/Mathlib/FieldTheory/AbelRuffini.lean +++ b/Mathlib/FieldTheory/AbelRuffini.lean @@ -30,24 +30,24 @@ open Polynomial variable {F E : Type*} [Field F] [Field E] [Algebra F E] -theorem gal_zero_isSolvable : IsSolvable (0 : F[X]).Gal := by infer_instance +theorem gal_zero_isSolvable : Group.IsSolvable (0 : F[X]).Gal := by infer_instance -theorem gal_one_isSolvable : IsSolvable (1 : F[X]).Gal := by infer_instance +theorem gal_one_isSolvable : Group.IsSolvable (1 : F[X]).Gal := by infer_instance -theorem gal_C_isSolvable (x : F) : IsSolvable (C x).Gal := by infer_instance +theorem gal_C_isSolvable (x : F) : Group.IsSolvable (C x).Gal := by infer_instance -theorem gal_X_isSolvable : IsSolvable (X : F[X]).Gal := by infer_instance +theorem gal_X_isSolvable : Group.IsSolvable (X : F[X]).Gal := by infer_instance -theorem gal_X_sub_C_isSolvable (x : F) : IsSolvable (X - C x).Gal := by infer_instance +theorem gal_X_sub_C_isSolvable (x : F) : Group.IsSolvable (X - C x).Gal := by infer_instance -theorem gal_X_pow_isSolvable (n : ℕ) : IsSolvable (X ^ n : F[X]).Gal := by infer_instance +theorem gal_X_pow_isSolvable (n : ℕ) : Group.IsSolvable (X ^ n : F[X]).Gal := by infer_instance -theorem gal_mul_isSolvable {p q : F[X]} (_ : IsSolvable p.Gal) (_ : IsSolvable q.Gal) : - IsSolvable (p * q).Gal := - solvable_of_solvable_injective (Gal.restrictProd_injective p q) +theorem gal_mul_isSolvable {p q : F[X]} (_ : Group.IsSolvable p.Gal) (_ : Group.IsSolvable q.Gal) : + Group.IsSolvable (p * q).Gal := + Group.isSolvable_of_isSolvable_injective (Gal.restrictProd_injective p q) -theorem gal_prod_isSolvable {s : Multiset F[X]} (hs : ∀ p ∈ s, IsSolvable (Gal p)) : - IsSolvable s.prod.Gal := by +theorem gal_prod_isSolvable {s : Multiset F[X]} (hs : ∀ p ∈ s, Group.IsSolvable (Gal p)) : + Group.IsSolvable s.prod.Gal := by apply Multiset.induction_on' s · exact gal_one_isSolvable · intro p t hps _ ht @@ -55,34 +55,35 @@ theorem gal_prod_isSolvable {s : Multiset F[X]} (hs : ∀ p ∈ s, IsSolvable (G exact gal_mul_isSolvable (hs p hps) ht theorem gal_isSolvable_of_splits {p q : F[X]} - (_ : Fact ((p.map (algebraMap F q.SplittingField)).Splits)) (hq : IsSolvable q.Gal) : - IsSolvable p.Gal := - haveI : IsSolvable (q.SplittingField ≃ₐ[F] q.SplittingField) := hq - solvable_of_surjective (AlgEquiv.restrictNormalHom_surjective q.SplittingField) + (_ : Fact ((p.map (algebraMap F q.SplittingField)).Splits)) (hq : Group.IsSolvable q.Gal) : + Group.IsSolvable p.Gal := + haveI : Group.IsSolvable (q.SplittingField ≃ₐ[F] q.SplittingField) := hq + Group.isSolvable_of_surjective (AlgEquiv.restrictNormalHom_surjective q.SplittingField) theorem gal_isSolvable_tower (p q : F[X]) (hpq : (p.map (algebraMap F q.SplittingField)).Splits) - (hp : IsSolvable p.Gal) (hq : IsSolvable (q.map (algebraMap F p.SplittingField)).Gal) : - IsSolvable q.Gal := by + (hp : Group.IsSolvable p.Gal) + (hq : Group.IsSolvable (q.map (algebraMap F p.SplittingField)).Gal) : + Group.IsSolvable q.Gal := by let K := p.SplittingField let L := q.SplittingField have : Fact ((p.map (algebraMap F L)).Splits) := ⟨hpq⟩ let ϕ : Gal(L/K) ≃* (q.map (algebraMap F K)).Gal := (IsSplittingField.algEquiv L (q.map (algebraMap F K))).autCongr have ϕ_inj : Function.Injective ϕ.toMonoidHom := ϕ.injective - have : IsSolvable Gal(K/F) := hp - have : IsSolvable Gal(L/K) := solvable_of_solvable_injective ϕ_inj + have : Group.IsSolvable Gal(K/F) := hp + have : Group.IsSolvable Gal(L/K) := Group.isSolvable_of_isSolvable_injective ϕ_inj exact isSolvable_of_isScalarTower F p.SplittingField q.SplittingField section GalXPowSubC set_option backward.isDefEq.respectTransparency false in -theorem gal_X_pow_sub_one_isSolvable (n : ℕ) : IsSolvable (X ^ n - 1 : F[X]).Gal := by +theorem gal_X_pow_sub_one_isSolvable (n : ℕ) : Group.IsSolvable (X ^ n - 1 : F[X]).Gal := by by_cases hn : n = 0 · rw [hn, pow_zero, sub_self] exact gal_zero_isSolvable have hn' : 0 < n := pos_iff_ne_zero.mpr hn have hn'' : (X ^ n - 1 : F[X]) ≠ 0 := X_pow_sub_C_ne_zero hn' 1 - apply isSolvable_of_comm + apply Group.isSolvable_of_comm intro σ τ ext a ha simp only [mem_rootSet_of_ne hn'', map_sub, aeval_X_pow, aeval_one, sub_eq_zero] at ha @@ -96,7 +97,7 @@ theorem gal_X_pow_sub_one_isSolvable (n : ℕ) : IsSolvable (X ^ n - 1 : F[X]).G set_option backward.isDefEq.respectTransparency false in theorem gal_X_pow_sub_C_isSolvable_aux (n : ℕ) (a : F) - (h : ((X ^ n - 1 : F[X]).map (RingHom.id F)).Splits) : IsSolvable (X ^ n - C a).Gal := by + (h : ((X ^ n - 1 : F[X]).map (RingHom.id F)).Splits) : Group.IsSolvable (X ^ n - C a).Gal := by by_cases ha : a = 0 · rw [ha, C_0, sub_zero] exact gal_X_pow_isSolvable n @@ -114,7 +115,7 @@ theorem gal_X_pow_sub_C_isSolvable_aux (n : ℕ) (a : F) (Splits.degree_eq_one_of_irreducible (h.of_dvd (map_ne_zero hn''') (minpoly.dvd F c (by rwa [map_id, map_sub, sub_eq_zero, aeval_X_pow, aeval_one]))) (minpoly.irreducible ((SplittingField.instNormal (X ^ n - C a)).isIntegral c)))) - apply isSolvable_of_comm + apply Group.isSolvable_of_comm intro σ τ ext b hb rw [mem_rootSet_of_ne hn'', map_sub, aeval_X_pow, aeval_C, sub_eq_zero] at hb @@ -172,7 +173,7 @@ theorem splits_X_pow_sub_one_of_X_pow_sub_C {F : Type*} [Field F] {E : Type*} [F hs', ← C_pow, hb, ← mul_assoc, C_mul_C, one_mul] rfl -theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by +theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : Group.IsSolvable (X ^ n - C x).Gal := by by_cases hx : x = 0 · rw [hx, C_0, sub_zero] exact gal_X_pow_isSolvable n @@ -259,7 +260,7 @@ protected theorem solvableByRad.induction (motive : ∀ x, x ∈ solvableByRad F exact h private theorem induction_rad {x : E} (hx : x ∈ solvableByRad F E) {n : ℕ} (hn : n ≠ 0) - (hα : IsSolvable (minpoly F (x ^ n)).Gal) : IsSolvable (minpoly F x).Gal := by + (hα : Group.IsSolvable (minpoly F (x ^ n)).Gal) : Group.IsSolvable (minpoly F x).Gal := by let p := minpoly F (x ^ n) have hp : p.comp (X ^ n) ≠ 0 := by intro h @@ -288,8 +289,8 @@ open IntermediateField private theorem induction_step {x y z : E} (hx : x ∈ solvableByRad F E) (hy : y ∈ solvableByRad F E) (hz : z ∈ solvableByRad F E) - (hx' : IsSolvable (minpoly F x).Gal) (hy' : IsSolvable (minpoly F y).Gal) (hz' : z ∈ F⟮x, y⟯) : - IsSolvable (minpoly F z).Gal := by + (hx' : Group.IsSolvable (minpoly F x).Gal) (hy' : Group.IsSolvable (minpoly F y).Gal) + (hz' : z ∈ F⟮x, y⟯) : Group.IsSolvable (minpoly F z).Gal := by let p := minpoly F x let q := minpoly F y have hpq := SplittingField.splits (p * q) @@ -313,7 +314,7 @@ private theorem induction_step {x y z : E} infer_instance theorem isSolvable_gal_minpoly {x : E} (hx : x ∈ solvableByRad F E) : - IsSolvable (minpoly F x).Gal := by + Group.IsSolvable (minpoly F x).Gal := by induction hx using solvableByRad.induction with | mem y => rw [minpoly.eq_X_sub_C E]; infer_instance | add y z hy hz hy' hz' => @@ -328,11 +329,11 @@ alias solvableByRad.isSolvable := isSolvable_gal_minpoly /-- **Abel-Ruffini Theorem** (one direction): An irreducible polynomial with a `solvableByRad` root has a solvable Galois group. -/ theorem isSolvable_gal_of_irreducible {x : E} (hx : x ∈ solvableByRad F E) {q : F[X]} - (q_irred : Irreducible q) (q_aeval : aeval x q = 0) : IsSolvable q.Gal := by - have : IsSolvable (q * C q.leadingCoeff⁻¹).Gal := by + (q_irred : Irreducible q) (q_aeval : aeval x q = 0) : Group.IsSolvable q.Gal := by + have : Group.IsSolvable (q * C q.leadingCoeff⁻¹).Gal := by rw [minpoly.eq_of_irreducible q_irred q_aeval] exact isSolvable_gal_minpoly hx - refine solvable_of_surjective (Gal.restrictDvd_surjective ⟨C q.leadingCoeff⁻¹, rfl⟩ ?_) + refine Group.isSolvable_of_surjective (Gal.restrictDvd_surjective ⟨C q.leadingCoeff⁻¹, rfl⟩ ?_) aesop @[deprecated (since := "2026-02-28")] diff --git a/Mathlib/FieldTheory/Normal/Basic.lean b/Mathlib/FieldTheory/Normal/Basic.lean index bdd25a16e7bbf0..47738d12e80bc2 100644 --- a/Mathlib/FieldTheory/Normal/Basic.lean +++ b/Mathlib/FieldTheory/Normal/Basic.lean @@ -243,8 +243,8 @@ theorem Normal.minpoly_eq_iff_mem_orbit [h : Normal F E] {x y : E} : variable (F K₁) -theorem isSolvable_of_isScalarTower [Normal F K₁] [h1 : IsSolvable (K₁ ≃ₐ[F] K₁)] - [h2 : IsSolvable (E ≃ₐ[K₁] E)] : IsSolvable Gal(E/F) := by +theorem isSolvable_of_isScalarTower [Normal F K₁] [h1 : Group.IsSolvable (K₁ ≃ₐ[F] K₁)] + [h2 : Group.IsSolvable (E ≃ₐ[K₁] E)] : Group.IsSolvable Gal(E/F) := by let f : (E ≃ₐ[K₁] E) →* Gal(E/F) := { toFun := fun ϕ => AlgEquiv.ofAlgHom (ϕ.toAlgHom.restrictScalars F) (ϕ.symm.toAlgHom.restrictScalars F) @@ -252,7 +252,7 @@ theorem isSolvable_of_isScalarTower [Normal F K₁] [h1 : IsSolvable (K₁ ≃ map_one' := AlgEquiv.ext fun _ => rfl map_mul' := fun _ _ => AlgEquiv.ext fun _ => rfl } refine - solvable_of_ker_le_range f (AlgEquiv.restrictNormalHom K₁) fun ϕ hϕ => + Group.isSolvable_of_ker_le_range f (AlgEquiv.restrictNormalHom K₁) fun ϕ hϕ => ⟨{ ϕ with commutes' := fun x => ?_ }, AlgEquiv.ext fun _ => rfl⟩ exact Eq.trans (ϕ.restrictNormal_commutes K₁ x).symm (congr_arg _ (AlgEquiv.ext_iff.mp hϕ x)) diff --git a/Mathlib/GroupTheory/IsPerfect.lean b/Mathlib/GroupTheory/IsPerfect.lean index ca51df8499158c..8e51a7e4d149b1 100644 --- a/Mathlib/GroupTheory/IsPerfect.lean +++ b/Mathlib/GroupTheory/IsPerfect.lean @@ -82,7 +82,7 @@ lemma not_isNilpotent [Nontrivial G] [IsPerfect G] : ¬ IsNilpotent G := open scoped IsMulCommutative in variable (G) in lemma not_isMulCommutative [Nontrivial G] [IsPerfect G] : ¬ IsMulCommutative G := - fun _ ↦ (not_isSolvable G) CommGroup.isSolvable + fun _ ↦ (not_isSolvable G) inferInstance instance subsingleton_of_isMulCommutative [hG : IsPerfect G] [h_comm : IsMulCommutative G] : Subsingleton G := by diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 365bd7e72c0251..5306d9a770513c 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -1158,7 +1158,7 @@ theorem Group.nilpotencyClass_pi [Fintype η] [∀ i, IsNilpotent (Gs i)] : end FinitePi /-- A nilpotent subgroup is solvable -/ -instance (priority := 100) IsNilpotent.to_isSolvable [h : IsNilpotent G] : IsSolvable G := by +instance (priority := 100) IsNilpotent.to_isSolvable [h : IsNilpotent G] : Group.IsSolvable G := by obtain ⟨n, hn⟩ := nilpotent_iff_lowerCentralSeries.1 h use n rw [eq_bot_iff, ← hn] diff --git a/Mathlib/GroupTheory/Solvable.lean b/Mathlib/GroupTheory/Solvable.lean index 81ef26cc5c3af8..e597bbaccfceeb 100644 --- a/Mathlib/GroupTheory/Solvable.lean +++ b/Mathlib/GroupTheory/Solvable.lean @@ -101,6 +101,8 @@ section Solvable variable (G) +namespace Group + /-- A group `G` is solvable if its derived series is eventually trivial. We use this definition because it's the most convenient one to work with. -/ @[mk_iff isSolvable_def, wikidata Q759832] @@ -108,24 +110,36 @@ class IsSolvable : Prop where /-- A group `G` is solvable if its derived series is eventually trivial. -/ solvable : ∃ n : ℕ, derivedSeries G n = ⊥ -instance (priority := 100) CommGroup.isSolvable {G : Type*} [CommGroup G] : IsSolvable G := +@[deprecated (since := "2026-07-16")] +alias _root_.IsSolvable := Group.IsSolvable + +@[deprecated (since := "2026-07-17")] +alias _root_.isSolvable_def := Group.isSolvable_def + +instance (priority := 100) {G : Type*} [CommGroup G] : IsSolvable G := ⟨⟨1, le_bot_iff.mp (Abelianization.commutator_subset_ker (MonoidHom.id G))⟩⟩ theorem isSolvable_of_comm {G : Type*} [hG : Group G] (h : ∀ a b : G, a * b = b * a) : IsSolvable G := by let hG' : CommGroup G := { hG with mul_comm := h } cases hG - exact CommGroup.isSolvable + infer_instance + +@[deprecated (since := "2026-07-16")] +alias _root_.isSolvable_of_comm := Group.isSolvable_of_comm theorem isSolvable_of_top_eq_bot (h : (⊤ : Subgroup G) = ⊥) : IsSolvable G := ⟨⟨0, h⟩⟩ -instance (priority := 100) isSolvable_of_subsingleton [Subsingleton G] : IsSolvable G := +@[deprecated (since := "2026-07-16")] +alias _root_.isSolvable_of_top_eq_bot := Group.isSolvable_of_top_eq_bot + +instance (priority := 100) [Subsingleton G] : IsSolvable G := isSolvable_of_top_eq_bot G (by simp [eq_iff_true_of_subsingleton]) variable {G} -theorem solvable_of_ker_le_range {G' G'' : Type*} [Group G'] [Group G''] (f : G' →* G) +theorem isSolvable_of_ker_le_range {G' G'' : Type*} [Group G'] [Group G''] (f : G' →* G) (g : G →* G'') (hfg : g.ker ≤ f.range) [hG' : IsSolvable G'] [hG'' : IsSolvable G''] : IsSolvable G := by obtain ⟨n, hn⟩ := id hG'' @@ -138,23 +152,32 @@ theorem solvable_of_ker_le_range {G' G'' : Type*} [Group G'] [Group G''] (f : G' (le_bot_iff.mp ((map_derivedSeries_le_derivedSeries g n).trans hn.le))).trans hfg | succ m hm => exact commutator_le_map_commutator hm hm -theorem solvable_of_solvable_injective (hf : Function.Injective f) [IsSolvable G'] : +@[deprecated (since := "2026-07-16")] +alias _root_.solvable_of_ker_le_range := isSolvable_of_ker_le_range + +theorem isSolvable_of_isSolvable_injective (hf : Function.Injective f) [IsSolvable G'] : IsSolvable G := - solvable_of_ker_le_range (1 : G' →* G) f ((f.ker_eq_bot hf).symm ▸ bot_le) + isSolvable_of_ker_le_range (1 : G' →* G) f ((f.ker_eq_bot hf).symm ▸ bot_le) + +@[deprecated (since := "2026-07-16")] +alias _root_.solvable_of_solvable_injective := isSolvable_of_isSolvable_injective + +instance (H : Subgroup G) [IsSolvable G] : IsSolvable H := + isSolvable_of_isSolvable_injective H.subtype_injective -instance subgroup_solvable_of_solvable (H : Subgroup G) [IsSolvable G] : IsSolvable H := - solvable_of_solvable_injective H.subtype_injective +theorem isSolvable_of_surjective (hf : Function.Surjective f) [IsSolvable G] : IsSolvable G' := + isSolvable_of_ker_le_range f (1 : G' →* G) (f.range_eq_top_of_surjective hf ▸ le_top) -theorem solvable_of_surjective (hf : Function.Surjective f) [IsSolvable G] : IsSolvable G' := - solvable_of_ker_le_range f (1 : G' →* G) (f.range_eq_top_of_surjective hf ▸ le_top) +@[deprecated (since := "2026-07-16")] +alias _root_.solvable_of_surjective := isSolvable_of_surjective -instance solvable_quotient_of_solvable (H : Subgroup G) [H.Normal] [IsSolvable G] : +instance (H : Subgroup G) [H.Normal] [IsSolvable G] : IsSolvable (G ⧸ H) := - solvable_of_surjective (QuotientGroup.mk'_surjective H) + isSolvable_of_surjective (QuotientGroup.mk'_surjective H) -instance solvable_prod {G' : Type*} [Group G'] [IsSolvable G] [IsSolvable G'] : +instance {G' : Type*} [Group G'] [IsSolvable G] [IsSolvable G'] : IsSolvable (G × G') := - solvable_of_ker_le_range (MonoidHom.inl G G') (MonoidHom.snd G G') fun x hx => + isSolvable_of_ker_le_range (MonoidHom.inl G G') (MonoidHom.snd G G') fun x hx => ⟨x.1, Prod.ext rfl hx.symm⟩ variable (G) in @@ -168,17 +191,24 @@ theorem IsSolvable.commutator_lt_top_of_nontrivial [hG : IsSolvable G] [Nontrivi | zero => exact derivedSeries_zero G | succ n h => rwa [derivedSeries_succ, h] +@[deprecated (since := "2026-07-16")] +alias _root_.IsSolvable.commutator_lt_top_of_nontrivial := + Group.IsSolvable.commutator_lt_top_of_nontrivial + theorem IsSolvable.commutator_lt_of_ne_bot [IsSolvable G] {H : Subgroup G} (hH : H ≠ ⊥) : ⁅H, H⁆ < H := by rw [← nontrivial_iff_ne_bot] at hH rw [← H.range_subtype, MonoidHom.range_eq_map, ← map_commutator, map_subtype_lt_map_subtype] exact commutator_lt_top_of_nontrivial H +@[deprecated (since := "2026-07-16")] +alias _root_.IsSolvable.commutator_lt_of_ne_bot := Group.IsSolvable.commutator_lt_of_ne_bot + theorem isSolvable_iff_commutator_lt [WellFoundedLT (Subgroup G)] : IsSolvable G ↔ ∀ H : Subgroup G, H ≠ ⊥ → ⁅H, H⁆ < H := by refine ⟨fun _ _ ↦ IsSolvable.commutator_lt_of_ne_bot, fun h ↦ ?_⟩ suffices h : IsSolvable (⊤ : Subgroup G) from - solvable_of_surjective (MonoidHom.range_eq_top.mp (range_subtype ⊤)) + isSolvable_of_surjective (MonoidHom.range_eq_top.mp (range_subtype ⊤)) induction (⊤ : Subgroup G) using WellFoundedLT.induction with | ind H hH rcases eq_or_ne H ⊥ with rfl | h' · infer_instance @@ -193,6 +223,11 @@ theorem isSolvable_iff_commutator_lt [WellFoundedLT (Subgroup G)] : ← MonoidHom.range_eq_map, ← MonoidHom.range_eq_map, range_subtype, range_subtype] | succ n ih => rw [derivedSeries_succ, map_commutator, ih, derivedSeries_succ, map_commutator] +@[deprecated (since := "2026-07-16")] +alias _root_.isSolvable_iff_commutator_lt := Group.isSolvable_iff_commutator_lt + +end Group + end Solvable section IsSimpleGroup @@ -208,8 +243,8 @@ theorem IsSimpleGroup.derivedSeries_succ {n : ℕ} : derivedSeries G n.succ = co · rw [h, commutator_bot_left] · rwa [h] -theorem IsSimpleGroup.comm_iff_isSolvable : (∀ a b : G, a * b = b * a) ↔ IsSolvable G := - ⟨isSolvable_of_comm, fun ⟨⟨n, hn⟩⟩ => by +theorem IsSimpleGroup.comm_iff_isSolvable : (∀ a b : G, a * b = b * a) ↔ Group.IsSolvable G := + ⟨Group.isSolvable_of_comm, fun ⟨⟨n, hn⟩⟩ => by cases n · intro a b refine (mem_bot.1 ?_).trans (mem_bot.1 ?_).symm <;> @@ -224,31 +259,40 @@ end IsSimpleGroup section PermNotSolvable -theorem not_solvable_of_mem_derivedSeries {g : G} (h1 : g ≠ 1) - (h2 : ∀ n : ℕ, g ∈ derivedSeries G n) : ¬IsSolvable G := - mt (isSolvable_def _).mp +theorem not_isSolvable_of_mem_derivedSeries {g : G} (h1 : g ≠ 1) + (h2 : ∀ n : ℕ, g ∈ derivedSeries G n) : ¬Group.IsSolvable G := + mt (Group.isSolvable_def _).mp (not_exists_of_forall_not fun n h => h1 (Subgroup.mem_bot.mp ((congr_arg (g ∈ ·) h).mp (h2 n)))) -theorem Equiv.Perm.fin_5_not_solvable : ¬IsSolvable (Equiv.Perm (Fin 5)) := by +@[deprecated (since := "2026-07-16")] +alias not_solvable_of_mem_derivedSeries := not_isSolvable_of_mem_derivedSeries + +theorem Equiv.Perm.not_isSolvable_fin_5 : ¬Group.IsSolvable (Equiv.Perm (Fin 5)) := by let x : Equiv.Perm (Fin 5) := ⟨![1, 2, 0, 3, 4], ![2, 0, 1, 3, 4], by decide, by decide⟩ let y : Equiv.Perm (Fin 5) := ⟨![3, 4, 2, 0, 1], ![3, 4, 2, 0, 1], by decide, by decide⟩ let z : Equiv.Perm (Fin 5) := ⟨![0, 3, 2, 1, 4], ![0, 3, 2, 1, 4], by decide, by decide⟩ have key : x = z * ⁅x, y * x * y⁻¹⁆ * z⁻¹ := by unfold x y z; decide - refine not_solvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => ?_ + refine not_isSolvable_of_mem_derivedSeries (show x ≠ 1 by decide) fun n => ?_ induction n with | zero => exact mem_top x | succ n ih => rw [key, (derivedSeries_normal _ _).mem_comm_iff, inv_mul_cancel_left] exact commutator_mem_commutator ih ((derivedSeries_normal _ _).conj_mem _ ih _) -theorem Equiv.Perm.not_solvable (X : Type*) (hX : 5 ≤ Cardinal.mk X) : - ¬IsSolvable (Equiv.Perm X) := by +@[deprecated (since := "2026-07-16")] +alias Equiv.Perm.fin_5_not_solvable := Equiv.Perm.not_isSolvable_fin_5 + +theorem Equiv.Perm.not_isSolvable (X : Type*) (hX : 5 ≤ Cardinal.mk X) : + ¬Group.IsSolvable (Equiv.Perm X) := by intro h have key : Nonempty (Fin 5 ↪ X) := by rwa [← Cardinal.lift_mk_le, Cardinal.mk_fin, Cardinal.lift_natCast, Cardinal.lift_id] exact - Equiv.Perm.fin_5_not_solvable - (solvable_of_solvable_injective (Equiv.Perm.viaEmbeddingHom_injective (Nonempty.some key))) + Equiv.Perm.not_isSolvable_fin_5 (Group.isSolvable_of_isSolvable_injective + (Equiv.Perm.viaEmbeddingHom_injective (Nonempty.some key))) + +@[deprecated (since := "2026-07-16")] +alias Equiv.Perm.not_solvable := Equiv.Perm.not_isSolvable end PermNotSolvable diff --git a/Mathlib/GroupTheory/SpecificGroups/ZGroup.lean b/Mathlib/GroupTheory/SpecificGroups/ZGroup.lean index 5d2ea8e53c8e99..cf1257ee337175 100644 --- a/Mathlib/GroupTheory/SpecificGroups/ZGroup.lean +++ b/Mathlib/GroupTheory/SpecificGroups/ZGroup.lean @@ -100,8 +100,8 @@ theorem commutator_lt [Finite G] [IsZGroup G] [Nontrivial G] : commutator G < rw [← Subgroup.isComplement'_top_left, ← (not_lt_top_iff.mp h)] exact hP.isComplement' rfl -instance [Finite G] [IsZGroup G] : IsSolvable G := by - rw [isSolvable_iff_commutator_lt] +instance [Finite G] [IsZGroup G] : Group.IsSolvable G := by + rw [Group.isSolvable_iff_commutator_lt] intro H h rw [← H.nontrivial_iff_ne_bot] at h rw [← H.range_subtype, MonoidHom.range_eq_map, ← Subgroup.map_commutator, @@ -149,7 +149,7 @@ theorem isCyclic_commutator [Finite G] [IsZGroup G] : IsCyclic (commutator G) := rcases eq_or_ne H ⊥ with rfl | h · rw [Subgroup.commutator_bot_left] infer_instance - · specialize hH ⁅H, H⁆ (IsSolvable.commutator_lt_of_ne_bot h) + · specialize hH ⁅H, H⁆ (Group.IsSolvable.commutator_lt_of_ne_bot h) replace hH : IsCyclic (⁅commutator H, commutator H⁆ : Subgroup H) := by let f := Subgroup.equivMapOfInjective ⁅commutator H, commutator H⁆ _ H.subtype_injective rw [Subgroup.map_commutator, Subgroup.map_subtype_commutator] at f From 973f002c05cca1a7477075af1edfdfcf1cbd8b2c Mon Sep 17 00:00:00 2001 From: Robert Hawkins Date: Fri, 17 Jul 2026 17:17:12 +0000 Subject: [PATCH 0857/1300] feat(Data/Multiset/Antidiagonal): `antidiagonal_add` and `map_swap_antidiagonal` (#39495) Adds `map_swap_antidiagonal` and `antidiagonal_add`. --- Mathlib/Data/Multiset/Antidiagonal.lean | 18 ++++++++++++++++++ Mathlib/Data/Multiset/Bind.lean | 1 + 2 files changed, 19 insertions(+) diff --git a/Mathlib/Data/Multiset/Antidiagonal.lean b/Mathlib/Data/Multiset/Antidiagonal.lean index bee2b53eb87c7c..4a8aacc3cb5955 100644 --- a/Mathlib/Data/Multiset/Antidiagonal.lean +++ b/Mathlib/Data/Multiset/Antidiagonal.lean @@ -74,6 +74,24 @@ theorem antidiagonal_cons (a : α) (s) : map_coe, antidiagonal_coe', coe_add] rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)] <;> simp +theorem antidiagonal_add (s t : Multiset α) : + (s + t).antidiagonal = + s.antidiagonal.bind fun p ↦ t.antidiagonal.map fun q ↦ (p.1 + q.1, p.2 + q.2) := by + induction s using Multiset.induction_on with + | empty => simp + | cons a s ih => + simp_rw [cons_add, antidiagonal_cons, ih, add_bind, bind_map, map_bind, map_map] + congr! <;> simp + +@[simp] +theorem map_swap_antidiagonal (s : Multiset α) : + s.antidiagonal.map Prod.swap = s.antidiagonal := by + induction s using Multiset.induction_on with + | empty => rfl + | cons a s ih => + simp only [antidiagonal_cons, map_add, map_map, ← Prod.map_comp_swap, + ← Multiset.map_map _ Prod.swap, ih, add_comm] + theorem antidiagonal_eq_map_powerset [DecidableEq α] (s : Multiset α) : s.antidiagonal = s.powerset.map fun t ↦ (s - t, t) := by induction s using Multiset.induction_on with diff --git a/Mathlib/Data/Multiset/Bind.lean b/Mathlib/Data/Multiset/Bind.lean index b35d48970e9f00..5158f768926b95 100644 --- a/Mathlib/Data/Multiset/Bind.lean +++ b/Mathlib/Data/Multiset/Bind.lean @@ -153,6 +153,7 @@ theorem mem_bind {b s} {f : α → Multiset β} : b ∈ bind s f ↔ ∃ a ∈ s @[simp] theorem card_bind : card (s.bind f) = (s.map (card ∘ f)).sum := by simp [bind] +@[congr] theorem bind_congr {f g : α → Multiset β} {m : Multiset α} : (∀ a ∈ m, f a = g a) → bind m f = bind m g := by simp +contextual [bind] From 6c0d6d2ff8e286c3409135f5501c69283b1ef31a Mon Sep 17 00:00:00 2001 From: Etienne Marion <66847262+EtienneC30@users.noreply.github.com> Date: Fri, 17 Jul 2026 18:06:40 +0000 Subject: [PATCH 0858/1300] feat: set-integral when a random variable is independent from a set (#40252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a random variable `X` is independent from a sigma-algebra `m` and `A` is a set in `m`, then `∫ ω in A, f (X ω) ∂P = P.real A * ∫ ω, f (X ω) ∂P` for any `AEStronglyMeasurable` function `f`. --- .../Probability/Independence/Integration.lean | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Mathlib/Probability/Independence/Integration.lean b/Mathlib/Probability/Independence/Integration.lean index 36bfa475e2706e..545d20576b1184 100644 --- a/Mathlib/Probability/Independence/Integration.lean +++ b/Mathlib/Probability/Independence/Integration.lean @@ -483,4 +483,37 @@ lemma iIndepFun.integral_fun_prod_eq_prod_integral ∫ ω, ∏ i, X i ω ∂μ = ∏ i, μ[X i] := hX.integral_fun_prod_comp (fun i ↦ (mX i).aemeasurable) (fun _ ↦ aestronglyMeasurable_id) +section SetIntegral + +variable {Ω 𝓧 : Type*} {m mΩ : MeasurableSpace Ω} {P : Measure Ω} [m𝓧 : MeasurableSpace 𝓧] + {X : Ω → 𝓧} {A : Set Ω} + +/-- If a random variable `X` is independent of a sigma-algebra `m` and `A` is a set in `m` +then `∫ ω in A, f (X ω) ∂P = P.real A • ∫ ω, f (X ω) ∂P` for a measurable function `f : 𝓧 → E`. -/ +lemma Indep.setIntegral_eq_smul {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + (hm : m ≤ mΩ) {f : 𝓧 → E} (hA1 : Indep m (m𝓧.comap X) P) + (hX : AEMeasurable X P) (hA2 : MeasurableSet[m] A) + (hf : AEStronglyMeasurable f (P.map X)) : + ∫ ω in A, f (X ω) ∂P = P.real A • ∫ ω, f (X ω) ∂P := + calc ∫ ω in A, f (X ω) ∂P + = ∫ ω, id (A.indicator (1 : Ω → ℝ) ω) • f (X ω) ∂P := by + rw [← integral_indicator (hm A hA2)] + congr with ω + by_cases hω : ω ∈ A <;> simp [hω] + _ = P.real A • ∫ ω, f (X ω) ∂P := by + rw [IndepFun.integral_fun_comp_smul_comp _ _ hX (by fun_prop) hf] + · simp [hm A hA2] + · exact hA1.indicator_indepFun 1 hA2 + · exact (aemeasurable_indicator_const_iff 1).2 (hm A hA2).nullMeasurableSet + +/-- If a random variable `X` is independent of a sigma-algebra `m` and `A` is a set in `m` +then `∫ ω in A, f (X ω) ∂P = P.real A * ∫ ω, f (X ω) ∂P` for a measurable function `f : 𝓧 → ℝ`. -/ +lemma Indep.setIntegral_eq_mul (hm : m ≤ mΩ) {f : 𝓧 → ℝ} (hA1 : Indep m (m𝓧.comap X) P) + (hX : AEMeasurable X P) (hA : MeasurableSet[m] A) + (hf : AEStronglyMeasurable f (P.map X)) : + ∫ ω in A, f (X ω) ∂P = P.real A * ∫ ω, f (X ω) ∂P := + hA1.setIntegral_eq_smul hm hX hA hf + +end SetIntegral + end ProbabilityTheory From 324e878abc1732a33f0bec6860e1b520836682f2 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 17 Jul 2026 18:58:01 +0000 Subject: [PATCH 0859/1300] feat(Analysis): two codiscrete-equal meromorphic functions have codiscrete-equal derivatives (#41093) --- Mathlib/Analysis/Meromorphic/IsolatedZeros.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean b/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean index 8ffdcd91c1e7a3..f142682550ba0d 100644 --- a/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean +++ b/Mathlib/Analysis/Meromorphic/IsolatedZeros.lean @@ -132,3 +132,16 @@ theorem eventually_nhdsSet_eventuallyEq_codiscreteWithin (hf : MeromorphicOn f U exact eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin (hf x hx) (hg x hx) hx (hU x hx) h end MeromorphicAt + +/-- If meromorphic `f` and `g` agree on `codiscreteWithin U`, so do their derivatives. -/ +theorem MeromorphicOn.deriv_eventuallyEq_codiscreteWithin (hf : MeromorphicOn f U) + (hg : MeromorphicOn g U) (h : f =ᶠ[codiscreteWithin U] g) : + deriv f =ᶠ[codiscreteWithin U] deriv g := by + rw [EventuallyEq, Filter.Eventually, mem_codiscreteWithin_iff_forall_mem_nhdsNE] + intro x hx + by_cases hacc : AccPt x (𝓟 U) + · have h : f =ᶠ[𝓝[≠] x] g := + (hf x hx).eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin (hg x hx) hx hacc h + filter_upwards [h.nhdsNE_deriv] using by simp +contextual + · rw [accPt_iff_frequently_nhdsNE, not_frequently] at hacc + filter_upwards [hacc] using by grind From fbebe666d7327dc6f0170b0db64521a481a50396 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:07:59 +0000 Subject: [PATCH 0860/1300] feat(Analysis/Convex/Function): composition of strictly and non-strictly convex functions (#40830) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently have composition lemmas for `StrictCon{vex/cave}On` of the form: ```lean theorem StrictConvexOn.comp : StrictConvexOn 𝕜 (f '' s) g → StrictMonoOn g (f '' s) → StrictConvexOn 𝕜 s f → s.InjOn f → StrictConvexOn 𝕜 s (g ∘ f) ``` If we let either function be convex instead of strictly convex we get: ```lean theorem ConvexOn.comp_strictConvexOn : ConvexOn 𝕜 (f '' s) g → StrictMonoOn g (f '' s) → StrictConvexOn 𝕜 s f → StrictConvexOn 𝕜 s (g ∘ f) theorem StrictConvexOn.comp_convexOn : StrictConvexOn 𝕜 (f '' s) g → MonotoneOn g (f '' s) → ConvexOn 𝕜 s f → s.InjOn f → StrictConvexOn 𝕜 s (g ∘ f) ``` In a `Module` these are both stronger than the original version (since `StrictConvexOn` implies `ConvexOn`), but they work over any `SMul`. --- Mathlib/Analysis/Convex/Function.lean | 53 ++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/Convex/Function.lean b/Mathlib/Analysis/Convex/Function.lean index b7e6d6e9283e1c..78749ca0befddc 100644 --- a/Mathlib/Analysis/Convex/Function.lean +++ b/Mathlib/Analysis/Convex/Function.lean @@ -166,23 +166,58 @@ theorem StrictConvexOn.comp (hg : StrictConvexOn 𝕜 (f '' s) g) (hf : StrictCo hf.2 hx hy hxy ha hb hab).trans <| hg.2 (mem_image_of_mem f hx) (mem_image_of_mem f hy) (mt (hf' hx hy) hxy) ha hb hab⟩ +theorem StrictConcaveOn.comp_strictConvexOn (hg : StrictConcaveOn 𝕜 (f '' s) g) + (hf : StrictConvexOn 𝕜 s f) (hg' : StrictAntiOn g (f '' s)) (hf' : s.InjOn f) : + StrictConcaveOn 𝕜 s (g ∘ f) := + hg.dual.comp hf hg' hf' + theorem StrictConcaveOn.comp (hg : StrictConcaveOn 𝕜 (f '' s) g) (hf : StrictConcaveOn 𝕜 s f) (hg' : StrictMonoOn g (f '' s)) (hf' : s.InjOn f) : StrictConcaveOn 𝕜 s (g ∘ f) := - ⟨hf.1, fun _ hx _ hy hxy _ _ ha hb hab => - (hg.2 (mem_image_of_mem f hx) (mem_image_of_mem f hy) (mt (hf' hx hy) hxy) ha hb hab).trans <| - hg' (hg.1 (mem_image_of_mem f hx) (mem_image_of_mem f hy) ha.le hb.le hab) - (mem_image_of_mem f <| hf.1 hx hy ha.le hb.le hab) <| - hf.2 hx hy hxy ha hb hab⟩ + hg.comp_strictConvexOn (β := βᵒᵈ) hf hg'.dual hf' theorem StrictConvexOn.comp_strictConcaveOn (hg : StrictConvexOn 𝕜 (f '' s) g) (hf : StrictConcaveOn 𝕜 s f) (hg' : StrictAntiOn g (f '' s)) (hf' : s.InjOn f) : StrictConvexOn 𝕜 s (g ∘ f) := hg.dual.comp hf hg' hf' -theorem StrictConcaveOn.comp_strictConvexOn (hg : StrictConcaveOn 𝕜 (f '' s) g) - (hf : StrictConvexOn 𝕜 s f) (hg' : StrictAntiOn g (f '' s)) (hf' : s.InjOn f) : - StrictConcaveOn 𝕜 s (g ∘ f) := - hg.dual.comp hf hg' hf' +theorem ConvexOn.comp_strictConvexOn (hg : ConvexOn 𝕜 (f '' s) g) (hf : StrictConvexOn 𝕜 s f) + (hg' : StrictMonoOn g (f '' s)) : StrictConvexOn 𝕜 s (g ∘ f) := by + refine ⟨hf.left, fun x hx y hy hxy a b ha hb hab ↦ .trans_le (b := g (a • f x + b • f y)) ?_ ?_⟩ + · refine hg' (mem_image_of_mem f <| hf.1 hx hy ha.le hb.le hab) ?_ <| hf.2 hx hy hxy ha hb hab + exact hg.left (mem_image_of_mem f hx) (mem_image_of_mem f hy) ha.le hb.le hab + · exact hg.right (mem_image_of_mem f hx) (mem_image_of_mem f hy) ha.le hb.le hab + +theorem ConcaveOn.comp_strictConvexOn (hg : ConcaveOn 𝕜 (f '' s) g) (hf : StrictConvexOn 𝕜 s f) + (hg' : StrictAntiOn g (f '' s)) : StrictConcaveOn 𝕜 s (g ∘ f) := + hg.dual.comp_strictConvexOn hf hg' + +theorem ConcaveOn.comp_strictConcaveOn (hg : ConcaveOn 𝕜 (f '' s) g) (hf : StrictConcaveOn 𝕜 s f) + (hg' : StrictMonoOn g (f '' s)) : StrictConcaveOn 𝕜 s (g ∘ f) := + hg.comp_strictConvexOn (β := βᵒᵈ) hf hg'.dual + +theorem ConvexOn.comp_strictConcaveOn (hg : ConvexOn 𝕜 (f '' s) g) (hf : StrictConcaveOn 𝕜 s f) + (hg' : StrictAntiOn g (f '' s)) : StrictConvexOn 𝕜 s (g ∘ f) := + hg.dual.comp_strictConcaveOn hf hg' + +theorem StrictConvexOn.comp_convexOn (hg : StrictConvexOn 𝕜 (f '' s) g) (hf : ConvexOn 𝕜 s f) + (hg' : MonotoneOn g (f '' s)) (hf' : s.InjOn f) : StrictConvexOn 𝕜 s (g ∘ f) := by + refine ⟨hf.left, fun x hx y hy hxy a b ha hb hab ↦ .trans_le' (b := g (a • f x + b • f y)) ?_ ?_⟩ + · exact hg.right (mem_image_of_mem f hx) (mem_image_of_mem f hy) (hf'.ne hx hy hxy) ha hb hab + · refine hg' ?_ ?_ <| hf.right hx hy ha.le hb.le hab + · exact mem_image_of_mem f <| hf.left hx hy ha.le hb.le hab + · exact hg.left (mem_image_of_mem f hx) (mem_image_of_mem f hy) ha.le hb.le hab + +theorem StrictConcaveOn.comp_convexOn (hg : StrictConcaveOn 𝕜 (f '' s) g) (hf : ConvexOn 𝕜 s f) + (hg' : AntitoneOn g (f '' s)) (hf' : s.InjOn f) : StrictConcaveOn 𝕜 s (g ∘ f) := + hg.dual.comp_convexOn hf hg' hf' + +theorem StrictConvexOn.comp_concaveOn (hg : StrictConvexOn 𝕜 (f '' s) g) (hf : ConcaveOn 𝕜 s f) + (hg' : AntitoneOn g (f '' s)) (hf' : s.InjOn f) : StrictConvexOn 𝕜 s (g ∘ f) := + hg.comp_convexOn (β := βᵒᵈ) hf hg'.dual hf' + +theorem StrictConcaveOn.comp_concaveOn (hg : StrictConcaveOn 𝕜 (f '' s) g) (hf : ConcaveOn 𝕜 s f) + (hg' : MonotoneOn g (f '' s)) (hf' : s.InjOn f) : StrictConcaveOn 𝕜 s (g ∘ f) := + hg.dual.comp_concaveOn hf hg' hf' end SMul From ce279564d4aa42137601a853c32685eedb0ba0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Fri, 17 Jul 2026 19:29:29 +0000 Subject: [PATCH 0861/1300] feat: `HasSmallInductiveDimensionLT` is monotonic (#40897) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We prove that `HasSmallInductiveDimensionLT m` implies `HasSmallInductiveDimensionLT n` whenever `m ≤ n`. --- Mathlib/Topology/SmallInductiveDimension.lean | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Mathlib/Topology/SmallInductiveDimension.lean b/Mathlib/Topology/SmallInductiveDimension.lean index c31d8e015a7647..811b88bf42dbe9 100644 --- a/Mathlib/Topology/SmallInductiveDimension.lean +++ b/Mathlib/Topology/SmallInductiveDimension.lean @@ -79,4 +79,25 @@ lemma hasSmallInductiveDimensionLT_one_iff : @[deprecated (since := "2026-06-21")] alias HasSmallInductiveDimensionLT_one_iff := hasSmallInductiveDimensionLT_one_iff -end +theorem HasSmallInductiveDimensionLT.mono {m n : ℕ} (hmn : m ≤ n) + (H : HasSmallInductiveDimensionLT X m) : HasSmallInductiveDimensionLT X n := by + induction n generalizing m X with + | zero => simp_all + | succ m IH => + cases H with + | zero => exact .succ _ ∅ (by simpa) (by simp) + | succ n s hs h => + refine .succ _ s hs fun U hU ↦ IH ?_ (h U hU) + rwa [add_le_add_iff_right] at hmn + +theorem HasSmallInductiveDimensionLE.mono {m n : ℕ} (hmn : m ≤ n) + (H : HasSmallInductiveDimensionLE X m) : HasSmallInductiveDimensionLE X n := by + apply HasSmallInductiveDimensionLT.mono _ H + rwa [add_le_add_iff_right] + +theorem HasSmallInductiveDimensionLT.hasSmallInductiveDimensionLE {n : ℕ} + (H : HasSmallInductiveDimensionLT X n) : HasSmallInductiveDimensionLE X n := + HasSmallInductiveDimensionLT.mono n.le_succ H + +instance (n : ℕ) [IsEmpty X] : HasSmallInductiveDimensionLT X n := + .mono zero_le <| hasSmallInductiveDimensionLT_zero_iff.2 ‹_› From 7c77f1a0a4ab250b995c54f933ab259044ed3379 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Fri, 17 Jul 2026 20:05:00 +0000 Subject: [PATCH 0862/1300] feat: the product of vector measures (#41546) Co-authored-by: sgouezel --- Mathlib.lean | 1 + .../MeasureTheory/VectorMeasure/Basic.lean | 56 +++-- Mathlib/MeasureTheory/VectorMeasure/Prod.lean | 197 ++++++++++++++++++ 3 files changed, 238 insertions(+), 16 deletions(-) create mode 100644 Mathlib/MeasureTheory/VectorMeasure/Prod.lean diff --git a/Mathlib.lean b/Mathlib.lean index c1d24ccd4a4ae3..1db92a61911933 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5663,6 +5663,7 @@ public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.JordanSub public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.Lebesgue public import Mathlib.MeasureTheory.VectorMeasure.Decomposition.RadonNikodym public import Mathlib.MeasureTheory.VectorMeasure.Integral +public import Mathlib.MeasureTheory.VectorMeasure.Prod public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral public import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic public import Mathlib.MeasureTheory.VectorMeasure.Variation.Defs diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index fbd4d3298f9852..223244e95bddee 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -133,12 +133,30 @@ theorem hasSum_of_disjoint_iUnion (hm : ∀ i, MeasurableSet (f i)) (hd : Pairwi · simp [Function.apply_extend MeasurableSet, Function.comp_def, hm] · exact hd.disjoint_extend_bot (he.factorsThrough _) +theorem of_if {ι : Type*} {x : ι} {B : Set ι} {A : Set α} [Decidable (x ∈ B)] : + v (if x ∈ B then A else ∅) = indicator B (fun _ => v A) x := by + split_ifs with h <;> simp [h] + variable [T2Space M] theorem of_disjoint_iUnion (hm : ∀ i, MeasurableSet (f i)) (hd : Pairwise (Disjoint on f)) : v (⋃ i, f i) = ∑' i, v (f i) := (hasSum_of_disjoint_iUnion hm hd).tsum_eq.symm +theorem of_biUnion {ι : Type*} {s : Set ι} {f : ι → Set α} (hs : s.Countable) + (hd : s.Pairwise (Disjoint on f)) (h : ∀ b ∈ s, MeasurableSet (f b)) : + v (⋃ b ∈ s, f b) = ∑' p : s, v (f p) := by + haveI := hs.toEncodable + rw [biUnion_eq_iUnion] + apply of_disjoint_iUnion + · exact fun x ↦ h x x.2 + · exact hd.on_injective Subtype.coe_injective fun x => x.2 + +theorem of_biUnion_finset {ι : Type*} {s : Finset ι} {f : ι → Set α} (hd : PairwiseDisjoint (↑s) f) + (hm : ∀ b ∈ s, MeasurableSet (f b)) : v (⋃ b ∈ s, f b) = ∑ p ∈ s, v (f p) := by + rw [← Finset.sum_attach, Finset.attach_eq_univ, ← tsum_fintype (L := .unconditional s)] + exact of_biUnion s.countable_toSet hd hm + theorem of_union {A B : Set α} (h : Disjoint A B) (hA : MeasurableSet A) (hB : MeasurableSet B) : v (A ∪ B) = v A + v B := by rw [Set.union_eq_iUnion, of_disjoint_iUnion, tsum_fintype, Fintype.sum_bool, cond, cond] @@ -206,22 +224,6 @@ theorem of_nonpos_disjoint_union_eq_zero {s : SignedMeasure α} {A B : Set α} ( rw [of_union h hA₁ hB₁] at hAB linarith -lemma of_biUnion_finset {ι : Type*} {s : Finset ι} {f : ι → Set α} (hd : PairwiseDisjoint (↑s) f) - (hm : ∀ b ∈ s, MeasurableSet (f b)) : v (⋃ b ∈ s, f b) = ∑ p ∈ s, v (f p) := by - classical - induction s using Finset.induction with - | empty => simp - | insert a s has ih => - simp only [Finset.mem_insert, iUnion_iUnion_eq_or_left, has, not_false_eq_true, - Finset.sum_insert] - rw [of_union, ih] - · exact hd.subset (by simp) - · grind - · simp only [disjoint_iUnion_right] - exact fun i hi ↦ hd (by simp) (by simp [hi]) (by grind) - · apply hm _ (by simp) - · apply Finset.measurableSet_biUnion _ (by grind) - theorem tendsto_vectorMeasure_iUnion_atTop_nat {s : ℕ → Set α} (hm : Monotone s) (hs : ∀ i, MeasurableSet (s i)) : Tendsto (fun n ↦ v (s n)) atTop (𝓝 (v (⋃ n, s n))) := by @@ -250,6 +252,22 @@ theorem tendsto_vectorMeasure_iInter_atTop_nat exact tendsto_vectorMeasure_iUnion_atTop_nat (fun i j hij ↦ by simpa using hm hij) (fun i ↦ (hs i).compl) +/-- If two vector measures give the same mass to the whole space and coincide on a +generating π-system, then they coincide. -/ +theorem ext_of_generateFrom {M : Type*} [AddCommGroup M] [TopologicalSpace M] [T2Space M] + {X : Type*} {mX : MeasurableSpace X} {μ ν : VectorMeasure X M} + (C : Set (Set X)) (hμν : ∀ s ∈ C, μ s = ν s) + (hA : mX = MeasurableSpace.generateFrom C) (hC : IsPiSystem C) + (h_univ : μ Set.univ = ν Set.univ) : μ = ν := by + ext s hs + induction s, hs using MeasurableSpace.induction_on_inter hA hC with + | empty => simp + | basic t ht => exact hμν t ht + | compl t htm iht => + simp [of_compl, iht, htm, h_univ] + | iUnion f hfd hfm ihf => + simp [of_disjoint_iUnion, hfm, hfd, ihf] + end section SMul @@ -714,6 +732,12 @@ theorem restrict_apply {i : Set α} (hi : MeasurableSet i) {j : Set α} (hj : Me rw [restrict, dif_pos hi] exact if_pos hj +@[simp] theorem restrict_apply_univ {i : Set α} : + v.restrict i univ = v i := by + by_cases hi : MeasurableSet i + · simp [restrict_apply, hi] + · simp [restrict_not_measurable, hi] + theorem restrict_eq_self {i : Set α} (hi : MeasurableSet i) {j : Set α} (hj : MeasurableSet j) (hij : j ⊆ i) : v.restrict i j = v j := by rw [restrict_apply v hi hj, Set.inter_eq_left.2 hij] diff --git a/Mathlib/MeasureTheory/VectorMeasure/Prod.lean b/Mathlib/MeasureTheory/VectorMeasure/Prod.lean new file mode 100644 index 00000000000000..04f1e98f87acea --- /dev/null +++ b/Mathlib/MeasureTheory/VectorMeasure/Prod.lean @@ -0,0 +1,197 @@ +/- +Copyright (c) 2026 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.MeasureTheory.Integral.Prod +public import Mathlib.MeasureTheory.VectorMeasure.SetIntegral +public import Mathlib.MeasureTheory.VectorMeasure.Variation.Semivariation + +/-! +# Product of vector measures + +Given two vector measures, we define their product `μ.prod ν B` as the vector measure assigning +to a measurable product `s × t` the mass `B (μ s) (ν t)`, if such a vector measure exists. +We show that it exists when either `μ` or `ν` has finite variation. + +The API is modelled on the one for the product of positive measures. +-/ + +public section + +open Filter Function MeasureTheory RCLike Set TopologicalSpace Topology +open scoped ENNReal NNReal Finset + +variable {ι X Y E F G H I J : Type*} {mX : MeasurableSpace X} {mY : MeasurableSpace Y} + [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] + [NormedAddCommGroup G] [NormedSpace ℝ G] + [NormedAddCommGroup H] [NormedSpace ℝ H] + [NormedAddCommGroup I] [NormedSpace ℝ I] + [NormedAddCommGroup J] [NormedSpace ℝ J] + {μ : VectorMeasure X E} {ν : VectorMeasure Y F} {B : E →L[ℝ] F →L[ℝ] G} + +namespace MeasureTheory.VectorMeasure + +/-- Two vector measures `μ` and `ν` have a product with respect to `B` if there exists a +measure giving mass `B (μ s) (ν t)` to any measurable product set `s × t`. +This is satisfied whenever `μ` or `ν` has finite variation. -/ +class HasProd (μ : VectorMeasure X E) (ν : VectorMeasure Y F) (B : E →L[ℝ] F →L[ℝ] G) : Prop where + exists_prod : ∃ ρ : VectorMeasure (X × Y) G, ∀ (s : Set X) (t : Set Y), + MeasurableSet s → MeasurableSet t → ρ (s ×ˢ t) = B (μ s) (ν t) + +/-- The product of two vector measures `μ` and `ν` with respect to a continuous bilinear map `B`, +giving mass `B (μ s) (ν t)` to any measurable product set `s × t`. +If such a measure does not exist, we use the junk value `0`. -/ +noncomputable def prod (μ : VectorMeasure X E) (ν : VectorMeasure Y F) (B : E →L[ℝ] F →L[ℝ] G) : + VectorMeasure (X × Y) G := + open scoped Classical in if h : HasProd μ ν B then h.exists_prod.choose else 0 + +lemma prod_eq_zero_of_not_hasProd (h : ¬HasProd μ ν B) : + μ.prod ν B = 0 := by + grind [HasProd, prod] + +@[simp] lemma prod_apply [h : HasProd μ ν B] {s : Set X} {t : Set Y} : + μ.prod ν B (s ×ˢ t) = B (μ s) (ν t) := by + rcases eq_or_ne s ∅ with rfl | hs + · simp + rcases eq_or_ne t ∅ with rfl | ht + · simp + by_cases h's : MeasurableSet s; swap + · simp only [h's, not_false_eq_true, not_measurable, _root_.map_zero, _root_.zero_apply] + rw [not_measurable] + simp [measurableSet_prod, hs, ht, h's] + by_cases h't : MeasurableSet t; swap + · simp only [h't, not_false_eq_true, not_measurable, _root_.map_zero] + rw [not_measurable] + simp [measurableSet_prod, hs, ht, h't] + simpa [prod, h] using h.exists_prod.choose_spec s t h's h't + +lemma HasProd.flip [HasProd μ ν B] : HasProd ν μ B.flip where + exists_prod := by + refine ⟨(μ.prod ν B).map Prod.swap, fun s t hs ht ↦ ?_⟩ + rw [map_apply _ (by fun_prop) (hs.prod ht)] + simp + +lemma hasProd_flip_iff : HasProd ν μ B.flip ↔ HasProd μ ν B := + ⟨fun h ↦ by simpa using HasProd.flip (μ := ν) (ν := μ) (B := B.flip), fun h ↦ HasProd.flip⟩ + +omit [NormedSpace ℝ F] in +/-- If `ν` is a vector measure, and `s ⊆ X × Y` is measurable, then `x ↦ ν { y | (x, y) ∈ s }` is +a strongly measurable function. -/ +theorem stronglyMeasurable_vectorMeasure_prodMk_left {s : Set (X × Y)} + (hs : MeasurableSet s) : StronglyMeasurable fun x ↦ ν (Prod.mk x ⁻¹' s) := by + induction s, hs + using MeasurableSpace.induction_on_inter generateFrom_prod.symm isPiSystem_prod with + | empty => simp [stronglyMeasurable_const] + | basic s hs => + obtain ⟨s, hs, t, -, rfl⟩ := hs + classical + simpa [mk_preimage_prod_right_eq_if, of_if] using stronglyMeasurable_const.indicator hs + | compl s hs ihs => + simp_rw [preimage_compl, VectorMeasure.of_compl (measurable_prodMk_left hs)] + exact stronglyMeasurable_const.sub ihs + | iUnion f hfd hfm ihf => + have (a : X) : HasSum (fun i ↦ ν (Prod.mk a ⁻¹' f i)) (ν (Prod.mk a ⁻¹' ⋃ i, f i)) := by + rw [preimage_iUnion] + apply hasSum_of_disjoint_iUnion + exacts [fun i ↦ measurable_prodMk_left (hfm i), hfd.mono fun _ _ ↦ .preimage _] + exact StronglyMeasurable.hasSum ihf this + +omit [NormedSpace ℝ E] in +theorem integrable_vectorMeasure_prodMk_left [IsFiniteMeasure μ.variation] + {s : Set (X × Y)} (hs : MeasurableSet s) : + μ.Integrable fun x ↦ ν (Prod.mk x ⁻¹' s) := by + refine Integrable.of_bound (μ := μ.variation) ?_ ν.bound ?_ + · exact (stronglyMeasurable_vectorMeasure_prodMk_left hs).aestronglyMeasurable + · exact Eventually.of_forall (fun x ↦ norm_apply_le_bound) + +/-- The product of two vector measures when the first one has finite variation, obtained by +integrating the measure of the fibers, as in the definition of the product of positive measures. +*Do not use*: This is only used to instantiate the typeclass `HasProd`. Instead, use `μ.prod ν B`, +which uses the typeclass instance. -/ +private noncomputable def prodOfIsFiniteMeasureLeft + (μ : VectorMeasure X E) (ν : VectorMeasure Y F) (B : E →L[ℝ] F →L[ℝ] G) + [IsFiniteMeasure μ.variation] : + VectorMeasure (X × Y) G where + measureOf' s := open scoped Classical in + if MeasurableSet s then ∫ᵛ x, ν (Prod.mk x ⁻¹' s) ∂[B.flip; μ] else 0 + empty' := by simp + not_measurable' := by simp +contextual + m_iUnion' f f_meas f_disj := by + simp only [f_meas, ↓reduceIte, implies_true, MeasurableSet.iUnion, preimage_iUnion, + HasSum, SummationFilter.unconditional_filter] + have A (a : Finset ℕ) : ∑ y ∈ a, ∫ᵛ x, ν (Prod.mk x ⁻¹' f y) ∂[B.flip; μ] + = ∫ᵛ x, ∑ y ∈ a, ν (Prod.mk x ⁻¹' f y) ∂[B.flip; μ] := by + rw [integral_finsetSum _ (fun i hi ↦ integrable_vectorMeasure_prodMk_left (f_meas i))] + simp_rw [A] + apply tendsto_integral_filter_of_dominated_convergence (bound := fun x ↦ ν.bound) + · apply Eventually.of_forall (fun a ↦ ?_) + apply StronglyMeasurable.aestronglyMeasurable + apply Finset.stronglyMeasurable_fun_sum _ (fun i hi ↦ ?_) + apply stronglyMeasurable_vectorMeasure_prodMk_left (f_meas i) + · filter_upwards with a + filter_upwards with x + rw [← VectorMeasure.of_biUnion_finset] + · apply norm_apply_le_bound + · exact fun i hi j hj hij ↦ (f_disj hij).preimage _ + · exact fun i hi ↦ measurable_prodMk_left (f_meas i) + · apply integrable_const + · filter_upwards with x + apply hasSum_of_disjoint_iUnion + · exact fun i ↦ measurable_prodMk_left (f_meas i) + · exact fun i j hij ↦ (f_disj hij).preimage _ + +instance [CompleteSpace G] [IsFiniteMeasure μ.variation] : HasProd μ ν B where + exists_prod := by + classical + refine ⟨prodOfIsFiniteMeasureLeft μ ν B, fun s t hs ht ↦ ?_⟩ + simp [prodOfIsFiniteMeasureLeft, hs.prod ht, ↓reduceIte, mk_preimage_prod_right_eq_if, + of_if, integral_indicator hs, ContinuousLinearMap.flip_apply, hs, restrict_apply] + +instance [CompleteSpace G] [h : IsFiniteMeasure ν.variation] : HasProd μ ν B := + hasProd_flip_iff.1 inferInstance + +lemma prod_eq_of_forall_apply_prod {ρ : VectorMeasure (X × Y) G} (hρ : ∀ (s : Set X) (t : Set Y), + MeasurableSet s → MeasurableSet t → ρ (s ×ˢ t) = B (μ s) (ν t)) : + μ.prod ν B = ρ := by + have : HasProd μ ν B := ⟨ρ, hρ⟩ + apply ext_of_generateFrom _ _ generateFrom_prod.symm isPiSystem_prod + · rw [← univ_prod_univ, hρ _ _ MeasurableSet.univ MeasurableSet.univ, prod_apply] + · rintro - ⟨s, hs, t, ht, rfl⟩ + rw [prod_apply, hρ _ _ hs ht] + +lemma prod_apply_eq_integral [CompleteSpace G] [IsFiniteMeasure μ.variation] + {s : Set (X × Y)} (hs : MeasurableSet s) : + μ.prod ν B s = ∫ᵛ x, ν (Prod.mk x ⁻¹' s) ∂[B.flip; μ] := by + have : μ.prod ν B = prodOfIsFiniteMeasureLeft μ ν B := by + classical + apply prod_eq_of_forall_apply_prod (fun s t hs ht ↦ ?_) + simp [prodOfIsFiniteMeasureLeft, hs.prod ht, ↓reduceIte, mk_preimage_prod_right_eq_if, + of_if, integral_indicator hs, ContinuousLinearMap.flip_apply, restrict_apply, hs] + rw [this] + simp [prodOfIsFiniteMeasureLeft, hs] + +lemma prod_flip_apply_eq_integral [CompleteSpace G] [IsFiniteMeasure μ.variation] + {B : F →L[ℝ] E →L[ℝ] G} {s : Set (X × Y)} (hs : MeasurableSet s) : + μ.prod ν B.flip s = ∫ᵛ x, ν (Prod.mk x ⁻¹' s) ∂[B; μ] := by + simp [prod_apply_eq_integral hs] + +lemma variation_prod_le [CompleteSpace G] [IsFiniteMeasure μ.variation] [SFinite ν.variation] : + (μ.prod ν B).variation ≤ ‖B‖ₑ • μ.variation.prod ν.variation := by + apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) + rw [prod_apply_eq_integral hs] + simp only [Measure.smul_apply, smul_eq_mul, Measure.prod_apply hs] + grw [enorm_integral_le_lintegral_enorm, ContinuousLinearMap.opENorm_flip, + enorm_measure_le_variation] + +instance [CompleteSpace G] [IsFiniteMeasure μ.variation] [IsFiniteMeasure ν.variation] : + IsFiniteMeasure (μ.prod ν B).variation := by + have : IsFiniteMeasure (‖B‖ₑ • μ.variation.prod ν.variation) := by + simp only [enorm_eq_nnnorm, Measure.coe_nnreal_smul] + infer_instance + exact isFiniteMeasure_of_le _ variation_prod_le + +end MeasureTheory.VectorMeasure From 5b213d382c3f3a77e87c75e8388f274fa4b23262 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 17 Jul 2026 20:17:20 +0000 Subject: [PATCH 0863/1300] feat: solvable group iff solvable subgroup and solvable quotient (#41824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove that for a normal subgroup `N` of `G`, `G` is solvable if and only if the subgroup `N` is solvable and the quotient `G ⧸ N` is solvable. --- Mathlib/GroupTheory/Solvable.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/GroupTheory/Solvable.lean b/Mathlib/GroupTheory/Solvable.lean index e597bbaccfceeb..5f65e2f9c1a653 100644 --- a/Mathlib/GroupTheory/Solvable.lean +++ b/Mathlib/GroupTheory/Solvable.lean @@ -175,6 +175,11 @@ instance (H : Subgroup G) [H.Normal] [IsSolvable G] : IsSolvable (G ⧸ H) := isSolvable_of_surjective (QuotientGroup.mk'_surjective H) +theorem isSolvable_iff_subgroup_quotient (H : Subgroup G) [H.Normal] : + IsSolvable G ↔ IsSolvable H ∧ IsSolvable (G ⧸ H) := + ⟨fun _ ↦ ⟨inferInstance, inferInstance⟩, fun ⟨_, _⟩ ↦ + isSolvable_of_ker_le_range H.subtype (QuotientGroup.mk' H) (by simp)⟩ + instance {G' : Type*} [Group G'] [IsSolvable G] [IsSolvable G'] : IsSolvable (G × G') := isSolvable_of_ker_le_range (MonoidHom.inl G G') (MonoidHom.snd G G') fun x hx => From f0c0e38ccea78bf786a680459c30d68ea0673cc9 Mon Sep 17 00:00:00 2001 From: "Fernando M. Reich" Date: Fri, 17 Jul 2026 21:13:51 +0000 Subject: [PATCH 0864/1300] feat(Topology/Algebra/Group/Basic): add eq_of_tendsto_div_nhds_one (#41230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `tendsto_div_nhds_one_iff_eq` to `Topology.Algebra.Group.Basic`, next to `tendsto_div_nhds_one_iff`: for functions into a Hausdorff topological group, if `f → a` and `g → b` along a nontrivial filter, then `f / g → 1` if and only if `a = b`. The implication `eq_of_tendsto_div_nhds_one` is kept as an `alias`, and the additive versions are generated by `@[to_additive]`. Also adds the `GroupWithZero`/`ContinuousInv₀` variant `tendsto_div_nhds_one_iff_eq₀` (assuming `b ≠ 0`), with its implication alias `eq_of_tendsto_div_nhds_one₀`, in `Topology.Algebra.GroupWithZero`. --- Mathlib/Topology/Algebra/Group/Basic.lean | 12 ++++++++++++ Mathlib/Topology/Algebra/GroupWithZero.lean | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 4e5f532123f3fc..0d869609ea35c1 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -1104,6 +1104,18 @@ theorem tendsto_div_nhds_one_iff {α : Type*} {l : Filter α} {x : G} {u : α haveI A : Tendsto (fun _ : α => x) l (𝓝 x) := tendsto_const_nhds ⟨fun h => by simpa using h.mul A, fun h => by simpa using h.div' A⟩ +/-- If `f → a` and `g → b` along a nontrivial filter on the domain, valued in a +Hausdorff topological group, then `f / g → 1` if and only if `a = b`. -/ +@[to_additive] +theorem tendsto_div_nhds_one_iff_eq {α : Type*} {l : Filter α} [l.NeBot] [T2Space G] + {f g : α → G} {a b : G} (hf : Tendsto f l (𝓝 a)) (hg : Tendsto g l (𝓝 b)) : + Tendsto (fun x ↦ f x / g x) l (𝓝 1) ↔ a = b := + ⟨fun hfg => tendsto_nhds_unique hf <| by simpa using hfg.mul hg, + fun h => by subst h; simpa using hf.div' hg⟩ + +@[to_additive] +alias ⟨eq_of_tendsto_div_nhds_one, _⟩ := tendsto_div_nhds_one_iff_eq + @[to_additive] theorem nhds_translation_div (x : G) : comap (· / x) (𝓝 1) = 𝓝 x := by simpa only [div_eq_mul_inv] using nhds_translation_mul_inv x diff --git a/Mathlib/Topology/Algebra/GroupWithZero.lean b/Mathlib/Topology/Algebra/GroupWithZero.lean index f3e4162725415f..03ea9232739f5e 100644 --- a/Mathlib/Topology/Algebra/GroupWithZero.lean +++ b/Mathlib/Topology/Algebra/GroupWithZero.lean @@ -192,6 +192,18 @@ theorem Filter.Tendsto.div {l : Filter α} {a b : G₀} (hf : Tendsto f l (𝓝 (hg : Tendsto g l (𝓝 b)) (hy : b ≠ 0) : Tendsto (f / g) l (𝓝 (a / b)) := by simpa only [div_eq_mul_inv] using! hf.mul (hg.inv₀ hy) +/-- If `f → a` and `g → b` along a nontrivial filter, valued in a Hausdorff +`GroupWithZero` with continuous multiplication and `ContinuousInv₀`, and `b ≠ 0`, +then `f / g → 1` if and only if `a = b`. -/ +theorem tendsto_div_nhds_one_iff_eq₀ + {l : Filter α} [l.NeBot] [T2Space G₀] {a b : G₀} + (hf : Tendsto f l (𝓝 a)) (hg : Tendsto g l (𝓝 b)) (hb : b ≠ 0) : + Tendsto (fun x ↦ f x / g x) l (𝓝 1) ↔ a = b := + ⟨fun hfg => (div_eq_one_iff_eq hb).mp (tendsto_nhds_unique (hf.div hg hb) hfg), + fun hab => (div_eq_one_iff_eq hb).mpr hab ▸ hf.div hg hb⟩ + +alias ⟨eq_of_tendsto_div_nhds_one₀, _⟩ := tendsto_div_nhds_one_iff_eq₀ + theorem Filter.tendsto_mul_iff_of_ne_zero [T1Space G₀] {f g : α → G₀} {l : Filter α} {x y : G₀} (hg : Tendsto g l (𝓝 y)) (hy : y ≠ 0) : Tendsto (fun n => f n * g n) l (𝓝 <| x * y) ↔ Tendsto f l (𝓝 x) := by From 4851ebd9bfe9aae548388b92ebd13ded9332abba Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Fri, 17 Jul 2026 21:45:03 +0000 Subject: [PATCH 0865/1300] feat(Analysis/InnerProductSpace/TensorProduct): continuous version of `TensorProduct.mk` (#40340) and isometric version of `TensorProduct.rid`. --- .../InnerProductSpace/TensorProduct.lean | 63 ++++++++++++++++--- .../TensorProduct/Associator.lean | 8 +++ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean b/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean index 2bd4bbe4e721e8..6f67d05d24c682 100644 --- a/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean +++ b/Mathlib/Analysis/InnerProductSpace/TensorProduct.lean @@ -197,6 +197,19 @@ theorem ext_iff_inner_left_threefold {x y : E ⊗[𝕜] F ⊗[𝕜] G} : simpa only [← inner_conj_symm x, ← inner_conj_symm y, starRingEnd_apply, star_inj] using ext_iff_inner_right_threefold (x := x) (y := y) +variable (𝕜 E F) in +/-- The canonical continuous bilinear map `E → F → E ⊗ F`. This is the continuous version of +`mk`. -/ +noncomputable def mkL : E →L[𝕜] F →L[𝕜] E ⊗[𝕜] F := (mk 𝕜 E F).mkContinuous₂ 1 fun _ _ ↦ by simp + +@[simp] lemma coe_mkL_apply (x : E) : ⇑(mkL 𝕜 E F x) = mk 𝕜 E F x := rfl +@[simp] lemma toLinearMap₁₂_mkL : (mkL 𝕜 E F).toLinearMap₁₂ = mk 𝕜 E F := rfl +@[simp] lemma toLinearMap_mkL_apply (x : E) : (mkL 𝕜 E F x).toLinearMap = mk 𝕜 E F x := rfl +lemma mkL_apply_apply (x : E) (y : F) : mkL 𝕜 E F x y = x ⊗ₜ y := rfl + +@[fun_prop] lemma continuous_tmul : Continuous fun x : E × F ↦ x.1 ⊗ₜ[𝕜] x.2 := + (mkL 𝕜 E F).continuous₂ + section isometry /-- The tensor product map of two linear isometries is a linear isometry. In particular, this is @@ -360,21 +373,53 @@ variable (𝕜 E) in noncomputable def lidIsometry : 𝕜 ⊗[𝕜] E ≃ₗᵢ[𝕜] E := TensorProduct.lid 𝕜 E |>.isometryOfInner inner_lid_lid -@[simp] lemma lidIsometry_apply (x : 𝕜 ⊗[𝕜] E) : - lidIsometry 𝕜 E x = TensorProduct.lid 𝕜 E x := rfl -@[simp] lemma lidIsometry_symm_apply (x : E) : - (lidIsometry 𝕜 E).symm x = 1 ⊗ₜ x := rfl - @[simp] lemma toLinearEquiv_lidIsometry : (lidIsometry 𝕜 E).toLinearEquiv = TensorProduct.lid 𝕜 E := rfl -@[simp] lemma norm_lid (x : 𝕜 ⊗[𝕜] E) : - ‖TensorProduct.lid 𝕜 E x‖ = ‖x‖ := lidIsometry 𝕜 E |>.norm_map x -@[simp] lemma nnnorm_lid (x : 𝕜 ⊗[𝕜] E) : - ‖TensorProduct.lid 𝕜 E x‖₊ = ‖x‖₊ := lidIsometry 𝕜 E |>.nnnorm_map x +lemma toContinuousLinearMap_symm_lidIsometry : + (lidIsometry 𝕜 E).symm.toContinuousLinearEquiv.toContinuousLinearMap = mkL 𝕜 𝕜 E 1 := rfl + +@[simp] lemma lidIsometry_apply (x : 𝕜 ⊗[𝕜] E) : lidIsometry 𝕜 E x = TensorProduct.lid 𝕜 E x := rfl +@[simp] lemma lidIsometry_symm_apply (x : E) : (lidIsometry 𝕜 E).symm x = 1 ⊗ₜ x := rfl + +@[simp] lemma norm_lid (x) : ‖TensorProduct.lid 𝕜 E x‖ = ‖x‖ := (lidIsometry 𝕜 E).norm_map x +@[simp] lemma nnnorm_lid (x) : ‖TensorProduct.lid 𝕜 E x‖₊ = ‖x‖₊ := lidIsometry 𝕜 E |>.nnnorm_map x + @[simp] lemma enorm_lid (x : 𝕜 ⊗[𝕜] E) : ‖TensorProduct.lid 𝕜 E x‖ₑ = ‖x‖ₑ := lidIsometry 𝕜 E |>.toLinearIsometry.enorm_map x +@[simp] theorem inner_rid_rid (x y : E ⊗[𝕜] 𝕜) : + inner 𝕜 (TensorProduct.rid 𝕜 E x) (TensorProduct.rid 𝕜 E y) = inner 𝕜 x y := by + simp [← lid_comm] + +variable (𝕜 E) in +/-- The linear isometry equivalence version of `TensorProduct.rid`. -/ +noncomputable def ridIsometry : E ⊗[𝕜] 𝕜 ≃ₗᵢ[𝕜] E := + TensorProduct.rid 𝕜 E |>.isometryOfInner inner_rid_rid + +@[simp] lemma toLinearEquiv_ridIsometry : + (ridIsometry 𝕜 E).toLinearEquiv = TensorProduct.rid 𝕜 E := rfl + +lemma toContinuousLinearMap_symm_ridIsometry : + (ridIsometry 𝕜 E).symm.toContinuousLinearEquiv.toContinuousLinearMap = (mkL 𝕜 E 𝕜).flip 1 := rfl + +@[simp] lemma ridIsometry_apply (x) : ridIsometry 𝕜 E x = TensorProduct.rid 𝕜 E x := rfl +@[simp] lemma symm_ridIsometry_apply (x) : (ridIsometry 𝕜 E).symm x = x ⊗ₜ 1 := rfl + +lemma lidIsometry_eq_ridIsometry : lidIsometry 𝕜 𝕜 = ridIsometry 𝕜 𝕜 := by ext; simp [lid_eq_rid] + +@[simp] lemma norm_rid (x) : ‖TensorProduct.rid 𝕜 E x‖ = ‖x‖ := (ridIsometry 𝕜 E).norm_map x +@[simp] lemma nnnorm_rid (x) : ‖TensorProduct.rid 𝕜 E x‖₊ = ‖x‖₊ := by simp [← NNReal.coe_inj] + +@[simp] lemma enorm_rid (x) : ‖TensorProduct.rid 𝕜 E x‖ₑ = ‖x‖ₑ := + ridIsometry 𝕜 E |>.toLinearIsometry.enorm_map x + +@[simp] lemma commIsometry_trans_lidIsometry : + (commIsometry 𝕜 E 𝕜).trans (lidIsometry 𝕜 E) = ridIsometry 𝕜 E := by ext; simp + +@[simp] lemma commIsometry_trans_ridIsometry : + (commIsometry 𝕜 𝕜 E).trans (ridIsometry 𝕜 E) = lidIsometry 𝕜 E := by ext; simp + @[simp] theorem inner_assoc_assoc (x y : E ⊗[𝕜] F ⊗[𝕜] G) : inner 𝕜 (TensorProduct.assoc 𝕜 E F G x) (TensorProduct.assoc 𝕜 E F G y) = inner 𝕜 x y := x.induction_on (by simp) (fun a _ => diff --git a/Mathlib/LinearAlgebra/TensorProduct/Associator.lean b/Mathlib/LinearAlgebra/TensorProduct/Associator.lean index 805b62f114ce94..7bb8c73ec41975 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Associator.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Associator.lean @@ -92,11 +92,19 @@ theorem comm_trans_lid : TensorProduct.comm R M R ≪≫ₗ TensorProduct.lid R M = TensorProduct.rid R M := LinearEquiv.toLinearMap_injective (ext (by ext; rfl)) +@[simp] lemma lid_comm (x) : + TensorProduct.lid R M (TensorProduct.comm R M R x) = TensorProduct.rid R M x := + congr($comm_trans_lid _) + @[simp] theorem comm_trans_rid : TensorProduct.comm R R M ≪≫ₗ TensorProduct.rid R M = TensorProduct.lid R M := LinearEquiv.toLinearMap_injective (ext (by ext; rfl)) +@[simp] lemma rid_comm (x) : + TensorProduct.rid R M (TensorProduct.comm R R M x) = TensorProduct.lid R M x := + congr($comm_trans_rid _) + variable (R) in theorem lid_eq_rid : TensorProduct.lid R R = TensorProduct.rid R R := LinearEquiv.toLinearMap_injective <| ext' mul_comm From 121d7591eab2d616ebb32a388283104e9417d0f2 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Fri, 17 Jul 2026 22:50:26 +0000 Subject: [PATCH 0866/1300] chore(Order/ConditionallyCompletePartialOrder/Indexed): use `to_dual` more to kill `TODO` (#41589) This PR uses `to_dual` to translate some theorems about `ConditionallyCompletePartialOrder` and kill TODO. --- .../Indexed.lean | 66 +++---------------- 1 file changed, 8 insertions(+), 58 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean index d739752fefd1c8..58859320d93b60 100644 --- a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean @@ -14,10 +14,6 @@ public import Mathlib.Order.GaloisConnection.Basic This file proves lemmas about `iSup` and `iInf` for functions valued in a conditionally complete partial order, as opposed to a conditionally complete lattice. -## TODO - -+ Use `@[to_dual]` in the `GaloisConnection` and `OrderIso` sections. - -/ public section @@ -195,21 +191,25 @@ section Sup variable [ConditionallyCompletePartialOrderSup α] [ConditionallyCompletePartialOrderSup β] [Nonempty ι] {l : α → β} {u : β → α} +@[to_dual u_csInf_of_directedOn'] theorem l_csSup_of_directedOn' (gc : GaloisConnection l u) {s : Set α} (hd : DirectedOn (· ≤ ·) s) (hne : s.Nonempty) (hbdd : BddAbove s) : l (sSup s) = sSup (l '' s) := gc.isLUB_l_image (hd.isLUB_csSup hne hbdd) |>.unique <| (hd.mono_comp gc.monotone_l).isLUB_csSup (hne.image l) (gc.monotone_l.map_bddAbove hbdd) +@[to_dual u_csInf_of_directedOn] theorem l_csSup_of_directedOn (gc : GaloisConnection l u) {s : Set α} (hd : DirectedOn (· ≤ ·) s) (hne : s.Nonempty) (hbdd : BddAbove s) : l (sSup s) = ⨆ x : s, l x := by simpa only [← comp_def, ← sSup_range, range_comp, Subtype.range_coe_subtype, ofPred_mem_eq] using gc.l_csSup_of_directedOn' hd hne hbdd +@[to_dual u_ciInf_of_directed] theorem l_ciSup_of_directed (gc : GaloisConnection l u) {f : ι → α} (hd : Directed (· ≤ ·) f) (hf : BddAbove (range f)) : l (⨆ i, f i) = ⨆ i, l (f i) := by rw [iSup, gc.l_csSup_of_directedOn hd.directedOn_range (range_nonempty _) hf, iSup_range'] +@[to_dual u_ciInf_set_of_directedOn] theorem l_ciSup_set_of_directedOn (gc : GaloisConnection l u) {s : Set γ} {f : γ → α} (hd : DirectedOn (· ≤ ·) (f '' s)) (hf : BddAbove (f '' s)) (hne : s.Nonempty) : l (⨆ i : s, f i) = ⨆ i : s, l (f i) := by @@ -220,33 +220,6 @@ theorem l_ciSup_set_of_directedOn (gc : GaloisConnection l u) {s : Set γ} {f : end Sup -section Inf - -variable [ConditionallyCompletePartialOrderInf α] [ConditionallyCompletePartialOrderInf β] - [Nonempty ι] {l : α → β} {u : β → α} - -theorem u_csInf_of_directedOn (gc : GaloisConnection l u) {s : Set β} (hd : DirectedOn (· ≥ ·) s) - (hne : s.Nonempty) (hbdd : BddBelow s) : - u (sInf s) = ⨅ x : s, u x := - gc.dual.l_csSup_of_directedOn hd hne hbdd - -theorem u_csInf_of_directedOn' (gc : GaloisConnection l u) {s : Set β} (hd : DirectedOn (· ≥ ·) s) - (hne : s.Nonempty) (hbdd : BddBelow s) : - u (sInf s) = sInf (u '' s) := - gc.dual.l_csSup_of_directedOn' hd hne hbdd - -theorem u_ciInf_of_directed (gc : GaloisConnection l u) {f : ι → β} (hd : Directed (· ≥ ·) f) - (hf : BddBelow (range f)) : - u (⨅ i, f i) = ⨅ i, u (f i) := - gc.dual.l_ciSup_of_directed hd hf - -theorem u_ciInf_set_of_directedOn (gc : GaloisConnection l u) {s : Set γ} {f : γ → β} - (hd : DirectedOn (· ≥ ·) (f '' s)) (hf : BddBelow (f '' s)) - (hne : s.Nonempty) : u (⨅ i : s, f i) = ⨅ i : s, u (f i) := - gc.dual.l_ciSup_set_of_directedOn hd hf hne - -end Inf - end GaloisConnection namespace OrderIso @@ -257,18 +230,22 @@ variable [ConditionallyCompletePartialOrderSup α] [ConditionallyCompletePartial [Nonempty ι] -- these need to have `directed` in their names. +@[to_dual] theorem map_csSup_of_directedOn (e : α ≃o β) {s : Set α} (hd : DirectedOn (· ≤ ·) s) (hne : s.Nonempty) (hbdd : BddAbove s) : e (sSup s) = ⨆ x : s, e x := e.to_galoisConnection.l_csSup_of_directedOn hd hne hbdd +@[to_dual] theorem map_csSup_of_directedOn' (e : α ≃o β) {s : Set α} (hd : DirectedOn (· ≤ ·) s) (hne : s.Nonempty) (hbdd : BddAbove s) : e (sSup s) = sSup (e '' s) := e.to_galoisConnection.l_csSup_of_directedOn' hd hne hbdd +@[to_dual] theorem map_ciSup_of_directed (e : α ≃o β) {f : ι → α} (hd : Directed (· ≤ ·) f) (hf : BddAbove (range f)) : e (⨆ i, f i) = ⨆ i, e (f i) := e.to_galoisConnection.l_ciSup_of_directed hd hf +@[to_dual] theorem map_ciSup_set_of_directedOn (e : α ≃o β) {s : Set γ} {f : γ → α} (hd : DirectedOn (· ≤ ·) (f '' s)) (hf : BddAbove (f '' s)) (hne : s.Nonempty) : e (⨆ i : s, f i) = ⨆ i : s, e (f i) := @@ -276,31 +253,4 @@ theorem map_ciSup_set_of_directedOn (e : α ≃o β) {s : Set γ} {f : γ → α end Sup -section Inf - -variable [ConditionallyCompletePartialOrderInf α] [ConditionallyCompletePartialOrderInf β] - [Nonempty ι] - -theorem map_csInf_of_directedOn (e : α ≃o β) {s : Set α} (hd : DirectedOn (· ≥ ·) s) - (hne : s.Nonempty) (hbdd : BddBelow s) : - e (sInf s) = ⨅ x : s, e x := - e.dual.map_csSup_of_directedOn hd hne hbdd - -theorem map_csInf_of_directedOn' (e : α ≃o β) {s : Set α} (hd : DirectedOn (· ≥ ·) s) - (hne : s.Nonempty) (hbdd : BddBelow s) : - e (sInf s) = sInf (e '' s) := - e.dual.map_csSup_of_directedOn' hd hne hbdd - -theorem map_ciInf_of_directed (e : α ≃o β) {f : ι → α} (hd : Directed (· ≥ ·) f) - (hf : BddBelow (range f)) : - e (⨅ i, f i) = ⨅ i, e (f i) := - e.dual.map_ciSup_of_directed hd hf - -theorem map_ciInf_set_of_directedOn (e : α ≃o β) {s : Set γ} {f : γ → α} - (hd : DirectedOn (· ≥ ·) (f '' s)) (hf : BddBelow (f '' s)) - (hne : s.Nonempty) : e (⨅ i : s, f i) = ⨅ i : s, e (f i) := - e.dual.map_ciSup_set_of_directedOn hd hf hne - -end Inf - end OrderIso From 8baa3d095e9735e43cf5985d10ae3e9a0f5834d7 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Fri, 17 Jul 2026 23:35:31 +0000 Subject: [PATCH 0867/1300] feat(Analysis): use `IsApply` for `GroupSeminorm` (#41560) Also adds instances for `AddCommMonoid` --- Mathlib/Analysis/Normed/Group/Seminorm.lean | 106 +++++++++++--------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/Mathlib/Analysis/Normed/Group/Seminorm.lean b/Mathlib/Analysis/Normed/Group/Seminorm.lean index 0b0c1322132f2a..4216f3f0e604b5 100644 --- a/Mathlib/Analysis/Normed/Group/Seminorm.lean +++ b/Mathlib/Analysis/Normed/Group/Seminorm.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.NNReal.Defs public import Mathlib.Order.ConditionallyCompleteLattice.Group +public import Mathlib.Data.FunLike.Module /-! # Group seminorms @@ -224,13 +225,17 @@ instance instZeroGroupSeminorm : Zero (GroupSeminorm E) := mul_le' := fun _ _ => (zero_add _).ge inv' := fun _ => rfl }⟩ -@[to_additive (attr := simp, norm_cast)] -theorem coe_zero : ⇑(0 : GroupSeminorm E) = 0 := - rfl +@[to_additive] +instance : IsZeroApply (GroupSeminorm E) E ℝ where + zero_apply _ := rfl -@[to_additive (attr := simp)] -theorem zero_apply (x : E) : (0 : GroupSeminorm E) x = 0 := - rfl +@[deprecated (since := "2026-07-10")] alias _root_.GroupSeminorm.coe_zero := FunLike.coe_zero +@[deprecated (since := "2026-07-10")] alias _root_.AddGroupSeminorm.coe_zero := FunLike.coe_zero + +@[deprecated (since := "2026-07-10")] protected alias _root_.GroupSeminorm.zero_apply := + zero_apply +@[deprecated (since := "2026-07-10")] protected alias _root_.AddGroupSeminorm.zero_apply := + zero_apply @[to_additive] instance : Inhabited (GroupSeminorm E) := @@ -246,13 +251,17 @@ instance : Add (GroupSeminorm E) := add_add_add_comm _ _ _ _ inv' := fun x => by simp_rw [map_inv_eq_map p, map_inv_eq_map q] }⟩ -@[to_additive (attr := simp)] -theorem coe_add : ⇑(p + q) = p + q := - rfl +@[to_additive] +instance : IsAddApply (GroupSeminorm E) E ℝ where + add_apply _ _ _ := rfl -@[to_additive (attr := simp)] -theorem add_apply (x : E) : (p + q) x = p x + q x := - rfl +@[deprecated (since := "2026-07-10")] alias _root_.GroupSeminorm.coe_add := FunLike.coe_add +@[deprecated (since := "2026-07-10")] alias _root_.AddGroupSeminorm.coe_add := FunLike.coe_add + +@[deprecated (since := "2026-07-10")] protected alias _root_.GroupSeminorm.add_apply := + add_apply +@[deprecated (since := "2026-07-10")] protected alias _root_.AddGroupSeminorm.add_apply := + add_apply open scoped Classical in @[to_additive] @@ -450,17 +459,18 @@ instance toSMul : SMul R (AddGroupSeminorm E) := apply map_add_le_add neg' := fun x => by simp_rw [map_neg_eq_map] }⟩ -@[simp, norm_cast] -theorem coe_smul (r : R) (p : AddGroupSeminorm E) : ⇑(r • p) = r • ⇑p := - rfl +instance : IsSMulApply R (AddGroupSeminorm E) E ℝ where + smul_apply _ _ _ := rfl -@[simp] -theorem smul_apply (r : R) (p : AddGroupSeminorm E) (x : E) : (r • p) x = r • p x := - rfl +@[deprecated (since := "2026-07-10")] alias coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias smul_apply := smul_apply instance isScalarTower [SMul R' ℝ] [SMul R' ℝ≥0] [IsScalarTower R' ℝ≥0 ℝ] [SMul R R'] [IsScalarTower R R' ℝ] : IsScalarTower R R' (AddGroupSeminorm E) := - ⟨fun r a p => ext fun x => smul_assoc r a (p x)⟩ + FunLike.isScalarTower + +instance : AddCommMonoid (AddGroupSeminorm E) := fast_instance% FunLike.addCommMonoid theorem smul_sup (r : R) (p q : AddGroupSeminorm E) : r • (p ⊔ q) = r • p ⊔ r • q := have Real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by @@ -519,13 +529,12 @@ instance : Zero (NonarchAddGroupSeminorm E) := add_le_max' := fun r s => by simp only [Pi.zero_apply]; rw [max_eq_right]; rfl neg' := fun _ => rfl }⟩ -@[simp, norm_cast] -theorem coe_zero : ⇑(0 : NonarchAddGroupSeminorm E) = 0 := - rfl +instance : IsZeroApply (NonarchAddGroupSeminorm E) E ℝ where + zero_apply _ := rfl -@[simp] -theorem zero_apply (x : E) : (0 : NonarchAddGroupSeminorm E) x = 0 := - rfl +@[deprecated (since := "2026-07-10")] alias coe_zero := FunLike.coe_zero + +@[deprecated (since := "2026-07-10")] protected alias zero_apply := zero_apply instance : Inhabited (NonarchAddGroupSeminorm E) := ⟨0⟩ @@ -637,17 +646,18 @@ instance : SMul R (GroupSeminorm E) := apply map_mul_le_add inv' := fun x => by simp_rw [map_inv_eq_map p] }⟩ +instance : IsSMulApply R (GroupSeminorm E) E ℝ where + smul_apply _ _ _ := rfl + +@[deprecated (since := "2026-07-10")] alias coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias smul_apply := smul_apply + instance [SMul R' ℝ] [SMul R' ℝ≥0] [IsScalarTower R' ℝ≥0 ℝ] [SMul R R'] [IsScalarTower R R' ℝ] : IsScalarTower R R' (GroupSeminorm E) := - ⟨fun r a p => ext fun x => smul_assoc r a <| p x⟩ + FunLike.isScalarTower -@[simp, norm_cast] -theorem coe_smul (r : R) (p : GroupSeminorm E) : ⇑(r • p) = r • ⇑p := - rfl - -@[simp] -theorem smul_apply (r : R) (p : GroupSeminorm E) (x : E) : (r • p) x = r • p x := - rfl +instance : AddCommMonoid (GroupSeminorm E) := fast_instance% FunLike.addCommMonoid theorem smul_sup (r : R) (p q : GroupSeminorm E) : r • (p ⊔ q) = r • p ⊔ r • q := have Real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by @@ -691,17 +701,15 @@ instance : SMul R (NonarchAddGroupSeminorm E) := apply map_add_le_max neg' := fun x => by simp_rw [map_neg_eq_map p] }⟩ -instance [SMul R' ℝ] [SMul R' ℝ≥0] [IsScalarTower R' ℝ≥0 ℝ] [SMul R R'] [IsScalarTower R R' ℝ] : - IsScalarTower R R' (NonarchAddGroupSeminorm E) := - ⟨fun r a p => ext fun x => smul_assoc r a <| p x⟩ +instance : IsSMulApply R (NonarchAddGroupSeminorm E) E ℝ where + smul_apply _ _ _ := rfl -@[simp, norm_cast] -theorem coe_smul (r : R) (p : NonarchAddGroupSeminorm E) : ⇑(r • p) = r • ⇑p := - rfl +@[deprecated (since := "2026-07-10")] alias coe_smul := FunLike.coe_smul -@[simp] -theorem smul_apply (r : R) (p : NonarchAddGroupSeminorm E) (x : E) : (r • p) x = r • p x := - rfl +@[deprecated (since := "2026-07-10")] protected alias smul_apply := smul_apply + +instance [SMul R' ℝ] [SMul R' ℝ≥0] [IsScalarTower R' ℝ≥0 ℝ] [SMul R R'] [IsScalarTower R R' ℝ] : + IsScalarTower R R' (NonarchAddGroupSeminorm E) := FunLike.isScalarTower theorem smul_sup (r : R) (p q : NonarchAddGroupSeminorm E) : r • (p ⊔ q) = r • p ⊔ r • q := have Real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by @@ -769,13 +777,15 @@ instance : Add (GroupNorm E) := eq_one_of_map_eq_zero' := fun _x hx => of_not_not fun h => hx.not_gt <| add_pos (map_pos_of_ne_one p h) (map_pos_of_ne_one q h) }⟩ -@[to_additive (attr := simp)] -theorem coe_add : ⇑(p + q) = p + q := - rfl +@[to_additive] +instance : IsAddApply (GroupNorm E) E ℝ where + add_apply _ _ _ := rfl -@[to_additive (attr := simp)] -theorem add_apply (x : E) : (p + q) x = p x + q x := - rfl +@[deprecated (since := "2026-07-10")] alias _root_.GroupNorm.coe_add := FunLike.coe_add +@[deprecated (since := "2026-07-10")] alias _root_.AddGroupNorm.coe_add := FunLike.coe_add + +@[deprecated (since := "2026-07-10")] protected alias _root_.GroupNorm.add_apply := add_apply +@[deprecated (since := "2026-07-10")] protected alias _root_.AddGroupNorm.add_apply := add_apply -- Note: To define an instance SupSet (GroupNorm E) requires a canonical "bottom" norm for sSup ∅. -- The zero function fails definiteness; the discrete norm needs complex proofs. From be529d50184614ea1391c2d5fcce169c89c59b7e Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Sat, 18 Jul 2026 00:01:25 +0000 Subject: [PATCH 0868/1300] chore(Data/SetLike/Basic): generalise instance (#40025) * Generalise the standard `IsConcreteLE` instance from `PartialOrder.ofSetLike` to `LE.ofSetLike` Co-authored-by: artie2000 --- Mathlib/Data/SetLike/Basic.lean | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/SetLike/Basic.lean b/Mathlib/Data/SetLike/Basic.lean index a7af972e724f48..42d6868b82cfbd 100644 --- a/Mathlib/Data/SetLike/Basic.lean +++ b/Mathlib/Data/SetLike/Basic.lean @@ -224,10 +224,17 @@ section default variable (A B : Type*) [SetLike A B] -/-- The order induced from a `SetLike` instance by inclusion. -/ +/-- The order induced from a `SetLike` instance by inclusion. + +An order defined as `.ofSetLike` will automatically make available an instance +of `IsConcreteLE`. +-/ @[reducible] def LE.ofSetLike : LE A where le := fun H K => ∀ ⦃x⦄, x ∈ H → x ∈ K +instance : letI := LE.ofSetLike A B; IsConcreteLE A B := + letI := LE.ofSetLike A B; { coe_subset_coe' := Iff.rfl } + /-- The partial order induced from a `SetLike` instance by inclusion. A partial order defined as `.ofSetLike` will automatically make available an instance @@ -238,9 +245,6 @@ of `IsConcreteLE`. lt s t := letI := LE.ofSetLike A B; s ≤ t ∧ ¬t ≤ s __ := PartialOrder.lift (SetLike.coe : A → Set B) SetLike.coe_injective -instance : letI := PartialOrder.ofSetLike A B; IsConcreteLE A B := - letI := PartialOrder.ofSetLike A B; { coe_subset_coe' := Iff.rfl } - end default namespace SetLike From 83a4552f285feb130cff762452c122a35c70e704 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sat, 18 Jul 2026 00:01:27 +0000 Subject: [PATCH 0869/1300] chore(MathlibTest): fix defLemma warnings (#40593) In all these cases, a dummy definition was declared of type True: the `defProp` linter complains that a declaration of type `True` should be a `lemma`. Instead, change to a definition with value (the natural 0). --- MathlibTest/Linter/DocPrime.lean | 5 ++--- MathlibTest/Tactic/Says/Basic.lean | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/MathlibTest/Linter/DocPrime.lean b/MathlibTest/Linter/DocPrime.lean index 7f3139c7d0e153..98cdba35572a0c 100644 --- a/MathlibTest/Linter/DocPrime.lean +++ b/MathlibTest/Linter/DocPrime.lean @@ -79,7 +79,7 @@ Declarations whose name ends with a `'` are expected to contain an explanation f Note: This linter can be disabled with `set_option linter.docPrime false` -/ #guard_msgs in -abbrev abbrev_no_doc' : True := .intro +abbrev abbrev_no_doc' : Nat := 0 /-- warning: `def_no_doc'` is missing a doc-string, please add one. @@ -88,8 +88,7 @@ Declarations whose name ends with a `'` are expected to contain an explanation f Note: This linter can be disabled with `set_option linter.docPrime false` -/ #guard_msgs in -set_option linter.defProp false in -def def_no_doc' : True := .intro +def def_no_doc' := 0 -- Anonymous declarations in a primed namespace should not get flagged by the linter. namespace Foo' diff --git a/MathlibTest/Tactic/Says/Basic.lean b/MathlibTest/Tactic/Says/Basic.lean index 1ab8f8f01ae9b7..918a1270d99929 100644 --- a/MathlibTest/Tactic/Says/Basic.lean +++ b/MathlibTest/Tactic/Says/Basic.lean @@ -97,12 +97,11 @@ example : True := by -- Check that verification works even with multi-line suggestions, as produced by aesop def P : Prop := True def Q : Prop := True -set_option linter.defProp false in @[simp] -def very_long_lemma_name_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa : Q → P := fun _ => trivial -set_option linter.defProp false in +theorem very_long_lemma_name_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa : Q → P := fun _ => trivial + @[simp] -def very_long_lemma_name_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb : Q := trivial +theorem very_long_lemma_name_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb : Q := trivial /-- info: Try this: [apply] aesop? says From 9e039082d06a42911856d23d9adb22342796bd74 Mon Sep 17 00:00:00 2001 From: TJHeeringa <16029718+TJHeeringa@users.noreply.github.com> Date: Sat, 18 Jul 2026 00:01:29 +0000 Subject: [PATCH 0870/1300] feat(Analysis/Normed): add additional symm lemmas (#41149) `Equiv` and `LinearEquiv` have the symm lemmas `symm_apply_eq` and `eq_symm_apply`. This adds those lemmas for `LinearIsometryEquiv`. --- Mathlib/Algebra/AddConstMap/Equiv.lean | 16 ++++++++++++++++ Mathlib/Algebra/Group/Action/Equidecomp.lean | 8 ++++++++ Mathlib/Algebra/Lie/Basic.lean | 14 +++++++++++++- Mathlib/Algebra/Star/StarAlgHom.lean | 8 ++++++++ Mathlib/Analysis/Normed/Affine/Isometry.lean | 6 ++++++ .../Analysis/Normed/Operator/LinearIsometry.lean | 6 ++++++ Mathlib/Data/PEquiv.lean | 6 ++++++ .../QuadraticForm/IsometryEquiv.lean | 8 ++++++++ Mathlib/Logic/Equiv/PartialEquiv.lean | 8 ++++++-- .../MeasureTheory/MeasurableSpace/Embedding.lean | 6 ++++++ Mathlib/Topology/Homeomorph/Defs.lean | 3 +++ Mathlib/Topology/MetricSpace/DilationEquiv.lean | 6 ++++++ 12 files changed, 92 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/AddConstMap/Equiv.lean b/Mathlib/Algebra/AddConstMap/Equiv.lean index cb710dcb956f05..d16e46ddcd4879 100644 --- a/Mathlib/Algebra/AddConstMap/Equiv.lean +++ b/Mathlib/Algebra/AddConstMap/Equiv.lean @@ -76,6 +76,22 @@ initialize_simps_projections AddConstEquiv (toFun → apply, invFun → symm_app @[simp] lemma symm_symm (e : G ≃+c[a, b] H) : e.symm.symm = e := rfl +theorem symm_apply_eq (e : G ≃+c[a, b] H) {a b} : + e.symm a = b ↔ a = e b := + e.toEquiv.symm_apply_eq + +theorem eq_symm_apply (e : G ≃+c[a, b] H) {a b} : + b = e.symm a ↔ e b = a := + e.toEquiv.eq_symm_apply + +@[simp] theorem apply_symm_apply (e : G ≃+c[a, b] H) (a) : + e (e.symm a) = a := + e.toEquiv.apply_symm_apply _ + +@[simp] theorem symm_apply_apply (e : G ≃+c[a, b] H) (a) : + e.symm (e a) = a := + e.toEquiv.symm_apply_apply _ + /-- The identity map as an `AddConstEquiv`. -/ @[simps! toEquiv apply] def refl (a : G) : G ≃+c[a, a] G where diff --git a/Mathlib/Algebra/Group/Action/Equidecomp.lean b/Mathlib/Algebra/Group/Action/Equidecomp.lean index c84317733ea596..7e7f2c8c8bb7d7 100644 --- a/Mathlib/Algebra/Group/Action/Equidecomp.lean +++ b/Mathlib/Algebra/Group/Action/Equidecomp.lean @@ -206,6 +206,14 @@ theorem right_inv {f : Equidecomp X G} {x : X} (h : x ∈ f.target) : @[simp] theorem symm_symm (f : Equidecomp X G) : f.symm.symm = f := rfl +theorem symm_apply_eq (f : Equidecomp X G) {x y} (hx : x ∈ f.toPartialEquiv.target) + (hy : y ∈ f.toPartialEquiv.source) : f.symm x = y ↔ x = f y := + f.toPartialEquiv.symm_apply_eq hy hx + +theorem eq_symm_apply (f : Equidecomp X G) {x y} (hx : x ∈ f.toPartialEquiv.target) + (hy : y ∈ f.toPartialEquiv.source) : y = f.symm x ↔ f y = x := + f.toPartialEquiv.eq_symm_apply hy hx + theorem symm_involutive : Function.Involutive (symm : Equidecomp X G → _) := symm_symm theorem symm_bijective : Function.Bijective (symm : Equidecomp X G → _) := symm_involutive.bijective diff --git a/Mathlib/Algebra/Lie/Basic.lean b/Mathlib/Algebra/Lie/Basic.lean index 4faaf1c401eb03..381271a197b485 100644 --- a/Mathlib/Algebra/Lie/Basic.lean +++ b/Mathlib/Algebra/Lie/Basic.lean @@ -614,6 +614,12 @@ theorem apply_symm_apply (e : L₁ ≃ₗ⁅R⁆ L₂) : ∀ x, e (e.symm x) = x theorem symm_apply_apply (e : L₁ ≃ₗ⁅R⁆ L₂) : ∀ x, e.symm (e x) = x := e.toLinearEquiv.symm_apply_apply +theorem symm_apply_eq (e : L₁ ≃ₗ⁅R⁆ L₂) {x y} : e.symm x = y ↔ x = e y := + e.toLinearEquiv.symm_apply_eq + +theorem eq_symm_apply (e : L₁ ≃ₗ⁅R⁆ L₂) {x y} : y = e.symm x ↔ e y = x := + e.toLinearEquiv.eq_symm_apply + @[simp] theorem refl_symm : (refl : L₁ ≃ₗ⁅R⁆ L₁).symm = refl := rfl @@ -982,7 +988,13 @@ theorem symm_apply_apply (e : M ≃ₗ⁅R,L⁆ N) : ∀ x, e.symm (e x) = x := theorem apply_eq_iff_eq_symm_apply {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : e m = n ↔ m = e.symm n := - (e : M ≃ N).apply_eq_iff_eq_symm_apply + e.toEquiv.apply_eq_iff_eq_symm_apply + +theorem symm_apply_eq {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : e.symm n = m ↔ n = e m := + e.toEquiv.symm_apply_eq + +theorem eq_symm_apply {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : m = e.symm n ↔ e m = n := + e.toEquiv.eq_symm_apply @[simp] theorem symm_symm (e : M ≃ₗ⁅R,L⁆ N) : e.symm.symm = e := rfl diff --git a/Mathlib/Algebra/Star/StarAlgHom.lean b/Mathlib/Algebra/Star/StarAlgHom.lean index b397f0e47014c3..1ab72e19fff626 100644 --- a/Mathlib/Algebra/Star/StarAlgHom.lean +++ b/Mathlib/Algebra/Star/StarAlgHom.lean @@ -759,6 +759,14 @@ theorem invFun_eq_symm {e : A ≃⋆ₐ[R] B} : EquivLike.inv e = e.symm := @[simp] theorem symm_symm (e : A ≃⋆ₐ[R] B) : e.symm.symm = e := rfl +lemma symm_apply_eq (e : A ≃⋆ₐ[R] B) {x y} : + e.symm x = y ↔ x = e y := + e.toEquiv.symm_apply_eq + +lemma eq_symm_apply (e : A ≃⋆ₐ[R] B) {x y} : + y = e.symm x ↔ e y = x := + e.toEquiv.eq_symm_apply + theorem symm_bijective : Function.Bijective (symm : (A ≃⋆ₐ[R] B) → B ≃⋆ₐ[R] A) := Function.bijective_iff_has_inverse.mpr ⟨_, symm_symm, symm_symm⟩ diff --git a/Mathlib/Analysis/Normed/Affine/Isometry.lean b/Mathlib/Analysis/Normed/Affine/Isometry.lean index dcc79f70b38242..463269c4eda314 100644 --- a/Mathlib/Analysis/Normed/Affine/Isometry.lean +++ b/Mathlib/Analysis/Normed/Affine/Isometry.lean @@ -505,6 +505,12 @@ theorem symm_apply_apply (x : P) : e.symm (e x) = x := @[simp] theorem symm_symm : e.symm.symm = e := rfl +theorem symm_apply_eq {x y} : e.symm x = y ↔ x = e y := + e.toAffineEquiv.symm_apply_eq + +theorem eq_symm_apply {x y} : y = e.symm x ↔ e y = x := + e.toAffineEquiv.eq_symm_apply + theorem symm_bijective : Bijective (AffineIsometryEquiv.symm : (P₂ ≃ᵃⁱ[𝕜] P) → _) := Function.bijective_iff_has_inverse.mpr ⟨_, symm_symm, symm_symm⟩ diff --git a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean index e7d7846c89702a..c6806b5a5107ea 100644 --- a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean +++ b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean @@ -644,6 +644,12 @@ theorem apply_symm_apply (x : E₂) : e (e.symm x) = x := theorem symm_apply_apply (x : E) : e.symm (e x) = x := e.toLinearEquiv.symm_apply_apply x +theorem symm_apply_eq {x y} : e.symm x = y ↔ x = e y := + e.toEquiv.symm_apply_eq + +theorem eq_symm_apply {x y} : y = e.symm x ↔ e y = x := + e.toEquiv.eq_symm_apply + theorem map_eq_zero_iff {x : E} : e x = 0 ↔ x = 0 := e.toLinearEquiv.map_eq_zero_iff diff --git a/Mathlib/Data/PEquiv.lean b/Mathlib/Data/PEquiv.lean index a67bfd518f7b97..e8f11e00649fe6 100644 --- a/Mathlib/Data/PEquiv.lean +++ b/Mathlib/Data/PEquiv.lean @@ -126,6 +126,12 @@ theorem symm_refl : (PEquiv.refl α).symm = PEquiv.refl α := @[simp] theorem symm_symm (f : α ≃. β) : f.symm.symm = f := rfl +theorem symm_apply_eq (f : α ≃. β) {x : β} {y : α} : f.symm x = y ↔ x = f y := by + rw [eq_some_iff, eq_comm] + +theorem eq_symm_apply (f : α ≃. β) {x : β} {y : α} : y = f.symm x ↔ f y = x := by + rw [← eq_some_iff, eq_comm] + theorem symm_bijective : Function.Bijective (PEquiv.symm : (α ≃. β) → β ≃. α) := Function.bijective_iff_has_inverse.mpr ⟨_, symm_symm, symm_symm⟩ diff --git a/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean b/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean index bda0fcc2cee93b..617db5c14d2ebb 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/IsometryEquiv.lean @@ -102,6 +102,14 @@ def toIsometry (g : Q₁.IsometryEquiv Q₂) : Q₁ →qᵢ Q₂ where @[simp] lemma symm_apply_apply (f : Q₁.IsometryEquiv Q₂) (x : M₁) : f.symm (f x) = x := f.toEquiv.symm_apply_apply x +theorem symm_apply_eq (f : Q₁.IsometryEquiv Q₂) {x y} : + f.symm x = y ↔ x = f y := + f.toEquiv.symm_apply_eq + +theorem eq_symm_apply (f : Q₁.IsometryEquiv Q₂) {x y} : + y = f.symm x ↔ f y = x := + f.toEquiv.eq_symm_apply + @[simp] lemma coe_symm_toLinearEquiv (f : Q₁.IsometryEquiv Q₂) : f.toLinearEquiv.symm = f.symm := rfl diff --git a/Mathlib/Logic/Equiv/PartialEquiv.lean b/Mathlib/Logic/Equiv/PartialEquiv.lean index 4dc289c751030d..88b41aace89d4a 100644 --- a/Mathlib/Logic/Equiv/PartialEquiv.lean +++ b/Mathlib/Logic/Equiv/PartialEquiv.lean @@ -200,10 +200,14 @@ theorem right_inv {x : β} (h : x ∈ e.target) : e (e.symm x) = x := theorem target_subset_range : e.target ⊆ range e := fun x hx ↦ ⟨e.symm x, right_inv e hx⟩ -theorem eq_symm_apply {x : α} {y : β} (hx : x ∈ e.source) (hy : y ∈ e.target) : - x = e.symm y ↔ e x = y := +theorem symm_apply_eq {x : α} {y : β} (hx : x ∈ e.source) (hy : y ∈ e.target) : + e.symm y = x ↔ y = e x := ⟨fun h => by rw [← e.right_inv hy, h], fun h => by rw [← e.left_inv hx, h]⟩ +theorem eq_symm_apply {x : α} {y : β} (hx : x ∈ e.source) (hy : y ∈ e.target) : + x = e.symm y ↔ e x = y := by + simp [eq_comm, ← symm_apply_eq e hx hy] + protected theorem mapsTo : MapsTo e e.source e.target := fun _ => e.map_source theorem mapsTo_symm : MapsTo e.symm e.target e.source := diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 80c70ad1f714b4..0d39a6f9539cf7 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -293,6 +293,12 @@ theorem self_trans_symm (e : α ≃ᵐ β) : e.trans e.symm = refl α := theorem trans_symm (e₁ : α ≃ᵐ β) (e₂ : β ≃ᵐ γ) : (e₁.trans e₂).symm = e₂.symm.trans (e₁.symm) := rfl +theorem symm_apply_eq (e : α ≃ᵐ β) {x y} : e.symm x = y ↔ x = e y := + e.toEquiv.symm_apply_eq + +theorem eq_symm_apply (e : α ≃ᵐ β) {x y} : y = e.symm x ↔ e y = x := + e.toEquiv.eq_symm_apply + protected theorem surjective (e : α ≃ᵐ β) : Surjective e := e.toEquiv.surjective diff --git a/Mathlib/Topology/Homeomorph/Defs.lean b/Mathlib/Topology/Homeomorph/Defs.lean index dda79217df4a00..1a6cece2085aa5 100644 --- a/Mathlib/Topology/Homeomorph/Defs.lean +++ b/Mathlib/Topology/Homeomorph/Defs.lean @@ -153,6 +153,9 @@ theorem symm_apply_apply (h : X ≃ₜ Y) (x : X) : h.symm (h x) = x := theorem symm_apply_eq (h : X ≃ₜ Y) {x : X} {y : Y} : h.symm y = x ↔ y = h x := Equiv.symm_apply_eq _ +theorem eq_symm_apply (h : X ≃ₜ Y) {x : X} {y : Y} : x = h.symm y ↔ h x = y := + Equiv.eq_symm_apply _ + @[simp] theorem self_trans_symm (h : X ≃ₜ Y) : h.trans h.symm = Homeomorph.refl X := by ext diff --git a/Mathlib/Topology/MetricSpace/DilationEquiv.lean b/Mathlib/Topology/MetricSpace/DilationEquiv.lean index f0932919866e03..b6eba13de0165e 100644 --- a/Mathlib/Topology/MetricSpace/DilationEquiv.lean +++ b/Mathlib/Topology/MetricSpace/DilationEquiv.lean @@ -87,6 +87,12 @@ theorem symm_bijective : Function.Bijective (DilationEquiv.symm : (X ≃ᵈ Y) @[simp] theorem apply_symm_apply (e : X ≃ᵈ Y) (x : Y) : e (e.symm x) = x := e.right_inv x @[simp] theorem symm_apply_apply (e : X ≃ᵈ Y) (x : X) : e.symm (e x) = x := e.left_inv x +theorem symm_apply_eq (e : X ≃ᵈ Y) {x : X} {y : Y} : e.symm y = x ↔ y = e x := + Equiv.symm_apply_eq _ + +theorem eq_symm_apply (e : X ≃ᵈ Y) {x : X} {y : Y} : x = e.symm y ↔ e x = y := + Equiv.eq_symm_apply _ + /-- See Note [custom simps projection]. -/ def Simps.symm_apply (e : X ≃ᵈ Y) : Y → X := e.symm From ecc9242d05028b378accc9012574a95bb5aa5382 Mon Sep 17 00:00:00 2001 From: Bolton Bailey Date: Sat, 18 Jul 2026 00:49:13 +0000 Subject: [PATCH 0871/1300] chore(Data/Vector): add `grind` to cons lemmas (#39098) This PR affects `List.Vector.head_cons` and `List.Vector.tail_cons`. It moves the simp attribute assignment of these lemmas to the lemma declarations and also applies the `grind =` attribute. --- Mathlib/Data/Vector/Basic.lean | 2 -- Mathlib/Data/Vector/Defs.lean | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Vector/Basic.lean b/Mathlib/Data/Vector/Basic.lean index efc2b10a439fc4..fb17c54d8a9ac6 100644 --- a/Mathlib/Data/Vector/Basic.lean +++ b/Mathlib/Data/Vector/Basic.lean @@ -30,8 +30,6 @@ namespace List.Vector @[inherit_doc] infixr:67 " ::ᵥ " => Vector.cons -attribute [simp] head_cons tail_cons - instance [Inhabited α] : Inhabited (Vector α n) := ⟨ofFn default⟩ diff --git a/Mathlib/Data/Vector/Defs.lean b/Mathlib/Data/Vector/Defs.lean index d8d1e7526b95df..14cca7251d8c3c 100644 --- a/Mathlib/Data/Vector/Defs.lean +++ b/Mathlib/Data/Vector/Defs.lean @@ -65,6 +65,7 @@ def head : Vector α (Nat.succ n) → α | ⟨a :: _, _⟩ => a /-- The head of a vector obtained by prepending is the element prepended. -/ +@[simp, grind =] theorem head_cons (a : α) : ∀ v : Vector α n, head (cons a v) = a | ⟨_, _⟩ => rfl @@ -74,6 +75,7 @@ def tail : Vector α n → Vector α (n - 1) | ⟨_ :: v, h⟩ => ⟨v, congrArg pred h⟩ /-- The tail of a vector obtained by prepending is the vector prepended. to -/ +@[simp, grind =] theorem tail_cons (a : α) : ∀ v : Vector α n, tail (cons a v) = v | ⟨_, _⟩ => rfl From a68722614ca0ed25121e45d1295916a210f4b1b0 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Sat, 18 Jul 2026 00:49:15 +0000 Subject: [PATCH 0872/1300] chore(SpecialFunctions/Log): fix naming typo (#41773) This lemma used to be named `EReal.ENNReal.rpow_eq_exp_mul_log` which I presume was accidental and the name was intended to be `ENNReal.rpow_eq_exp_mul_log`, and so this PR renames accordingly. --- .../Analysis/SpecialFunctions/Log/ENNRealLogExp.lean | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean index fc408708586741..b1163b6cf30f7d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean @@ -63,13 +63,17 @@ lemma exp_nmul (x : EReal) (n : ℕ) : exp (n * x) = (exp x) ^ n := by lemma exp_mul (x : EReal) (y : ℝ) : exp (x * y) = (exp x) ^ y := by rw [← log_eq_iff, log_rpow, log_exp, log_exp, mul_comm] -lemma ENNReal.rpow_eq_exp_mul_log (x : ℝ≥0∞) (y : ℝ) : x ^ y = exp (y * log x) := by - rw [mul_comm, EReal.exp_mul, exp_log] - end EReal end Exp namespace ENNReal + +lemma rpow_eq_exp_mul_log (x : ℝ≥0∞) (y : ℝ) : x ^ y = exp (y * log x) := by + rw [← log_rpow, exp_log] + +@[deprecated (since := "2026-07-15")] alias _root_.EReal.ENNReal.rpow_eq_exp_mul_log := + rpow_eq_exp_mul_log + section OrderIso set_option backward.isDefEq.respectTransparency false in From f10b8a1610b7e4f55019a86bff5ca9d553b96b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sat, 18 Jul 2026 01:29:03 +0000 Subject: [PATCH 0873/1300] feat(Analysis/Convex/TotallyBounded): strengthen to an iff (#41226) ... and golf the existing proof using the fancy new `grw`. From MeanFourier --- Mathlib/Analysis/Convex/TotallyBounded.lean | 29 +++++++++---------- Mathlib/Analysis/LocallyConvex/AbsConvex.lean | 17 +++++------ .../Algebra/IsUniformGroup/Basic.lean | 10 +++++-- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Mathlib/Analysis/Convex/TotallyBounded.lean b/Mathlib/Analysis/Convex/TotallyBounded.lean index 354cca05cbdd74..b3e836ef62cfd9 100644 --- a/Mathlib/Analysis/Convex/TotallyBounded.lean +++ b/Mathlib/Analysis/Convex/TotallyBounded.lean @@ -30,26 +30,23 @@ public section open Set Pointwise -variable (E : Type*) {s : Set E} +variable {E : Type*} {s : Set E} variable [AddCommGroup E] [Module ℝ E] -variable [UniformSpace E] [IsUniformAddGroup E] [lcs : LocallyConvexSpace ℝ E] [ContinuousSMul ℝ E] +variable [UniformSpace E] [IsUniformAddGroup E] [LocallyConvexSpace ℝ E] [ContinuousSMul ℝ E] -theorem totallyBounded_convexHull (hs : TotallyBounded s) : +protected lemma TotallyBounded.convexHull (hs : TotallyBounded s) : TotallyBounded (convexHull ℝ s) := by - rw [totallyBounded_iff_subset_finite_iUnion_nhds_zero] + rw [totallyBounded_iff_subset_finite_iUnion_nhds_zero] at ⊢ hs intro U hU obtain ⟨W, hW₁, hW₂⟩ := exists_nhds_zero_half hU - obtain ⟨V, ⟨hV₁, hV₂, hV₃⟩⟩ := (locallyConvexSpace_iff_exists_convex_subset_zero ℝ E).mp lcs W hW₁ - obtain ⟨t, ⟨htf, hts⟩⟩ := (totallyBounded_iff_subset_finite_iUnion_nhds_zero.mp hs) _ hV₁ - obtain ⟨t', ⟨htf', hts'⟩⟩ := (totallyBounded_iff_subset_finite_iUnion_nhds_zero.mp - (IsCompact.totallyBounded (Finite.isCompact_convexHull ℝ htf)) _ hV₁) + obtain ⟨V, hV₁,hV₂, hV₃⟩ := (locallyConvexSpace_iff_exists_convex_subset_zero ℝ E).mp ‹_› W hW₁ + obtain ⟨t, htf, hts⟩ := hs _ hV₁ + obtain ⟨t', htf', hts'⟩ := totallyBounded_iff_subset_finite_iUnion_nhds_zero.mp + (htf.isCompact_convexHull ℝ).totallyBounded _ hV₁ use t', htf' simp only [iUnion_vadd_set, vadd_eq_add] at hts hts' ⊢ - calc convexHull ℝ s - _ ⊆ convexHull ℝ (t + V) := convexHull_mono hts - _ ⊆ convexHull ℝ t + convexHull ℝ V := convexHull_add_subset - _ = convexHull ℝ t + V := by rw [hV₂.convexHull_eq] - _ ⊆ t' + V + V := add_subset_add_right hts' - _ = t' + (V + V) := by rw [add_assoc] - _ ⊆ t' + (W + W) := add_subset_add_left (add_subset_add hV₃ hV₃) - _ ⊆ t' + U := add_subset_add_left (add_subset_iff.mpr hW₂) + grw [hts, convexHull_add_subset, hV₂.convexHull_eq, hts', add_assoc, hV₃, add_subset_iff.mpr hW₂] + +@[simp] lemma totallyBounded_convexHull : TotallyBounded (convexHull ℝ s) ↔ TotallyBounded s where + mp := .subset <| subset_convexHull .. + mpr := .convexHull diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvex.lean b/Mathlib/Analysis/LocallyConvex/AbsConvex.lean index 5b78057dd8b372..e1d6281cd53e35 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvex.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvex.lean @@ -343,17 +343,15 @@ theorem convexHull_union_neg_eq_absConvexHull {s : Set E} : rw [← Convex.convexHull_eq (convex_convexHull ℝ (s ∪ -s))] exact convexHull_mono balancedHull_subset_convexHull_union_neg) -variable (E 𝕜) {s : Set E} +variable (𝕜) {s : Set E} variable [NontriviallyNormedField 𝕜] [PartialOrder 𝕜] [Module 𝕜 E] [SMulCommClass ℝ 𝕜 E] variable [UniformSpace E] [IsUniformAddGroup E] [lcs : LocallyConvexSpace ℝ E] [ContinuousSMul ℝ E] --- TVS II.25 Prop3 -theorem totallyBounded_absConvexHull (hs : TotallyBounded s) : - TotallyBounded (absConvexHull ℝ s) := by - rw [← convexHull_union_neg_eq_absConvexHull] - apply totallyBounded_convexHull - rw [totallyBounded_union] - exact ⟨hs, totallyBounded_neg hs⟩ +@[simp] +lemma totallyBounded_absConvexHull : TotallyBounded (absConvexHull ℝ s) ↔ TotallyBounded s := by + simp [← convexHull_union_neg_eq_absConvexHull] + +protected alias ⟨_, TotallyBounded.absConvexHull⟩ := totallyBounded_absConvexHull end @@ -367,5 +365,4 @@ theorem isCompact_closedAbsConvexHull_of_totallyBounded {E : Type*} [AddCommGrou [QuasiCompleteSpace ℝ E] {s : Set E} (ht : TotallyBounded s) : IsCompact (closedAbsConvexHull ℝ s) := by rw [closedAbsConvexHull_eq_closure_absConvexHull] - exact isCompact_closure_of_totallyBounded_quasiComplete (𝕜 := ℝ) - (totallyBounded_absConvexHull E ht) + exact isCompact_closure_of_totallyBounded_quasiComplete (𝕜 := ℝ) ht.absConvexHull diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean index 307f33211b9590..8f8d8abf600ab1 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Basic.lean @@ -137,9 +137,13 @@ theorem totallyBounded_iff_subset_finite_iUnion_nhds_one {s : Set α} : simp [← preimage_smul_inv, preimage] @[to_additive] -theorem totallyBounded_inv {s : Set α} (hs : TotallyBounded s) : TotallyBounded (s⁻¹) := by - convert! TotallyBounded.image hs uniformContinuous_inv - aesop +protected lemma TotallyBounded.inv {s : Set α} (hs : TotallyBounded s) : TotallyBounded s⁻¹ := by + simpa using hs.image uniformContinuous_inv + +@[to_additive (attr := simp)] +lemma totallyBounded_inv {s : Set α} : TotallyBounded s⁻¹ ↔ TotallyBounded s where + mp hs := by simpa using hs.inv + mpr := .inv section UniformConvergence From ba2ac755bd0af40f773715e03e290d8ef9f73e72 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sat, 18 Jul 2026 01:56:40 +0000 Subject: [PATCH 0874/1300] chore(RingTheory/Polynomial/Basic): golf `degreeLTEquiv` (#39514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also extracts the `monomial i a ∈ degreeLT R n` proof to a lemma. --- Mathlib/RingTheory/Polynomial/Basic.lean | 43 ++++++------------------ 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index 7b930a899e740a..0572fe353a160f 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -88,6 +88,9 @@ theorem degreeLE_eq_span_X_pow [DecidableEq R] {n : ℕ} : theorem mem_degreeLT {n : ℕ} {f : R[X]} : f ∈ degreeLT R n ↔ degree f < n := by simpa [degreeLT, Submodule.mem_iInf] using (degree_lt_iff_coeff_zero _ _).symm +theorem monomial_coe_mem_degreeLT {n : ℕ} (i : Fin n) (a : R) : monomial i a ∈ degreeLT R n := + mem_degreeLT.mpr <| degree_monomial_le i a |>.trans_lt <| by simp + @[gcongr, mono] theorem degreeLT_mono {m n : ℕ} (H : m ≤ n) : degreeLT R m ≤ degreeLT R n := fun _ hf => mem_degreeLT.2 (lt_of_lt_of_le (mem_degreeLT.1 hf) <| WithBot.coe_le_coe.2 H) @@ -105,43 +108,19 @@ theorem degreeLT_eq_span_X_pow [DecidableEq R] {n : ℕ} : rw [Submodule.span_le, Finset.coe_image, Set.image_subset_iff] intro k hk apply mem_degreeLT.2 - exact lt_of_le_of_lt (degree_X_pow_le _) (WithBot.coe_lt_coe.2 <| Finset.mem_range.1 hk) + exact degree_X_pow_le _ |>.trans_lt <| WithBot.coe_lt_coe.2 <| Finset.mem_range.1 hk +variable (R) in /-- The first `n` coefficients on `degreeLT n` form a linear equivalence with `Fin n → R`. -/ -def degreeLTEquiv (R) [Semiring R] (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where +def degreeLTEquiv (n : ℕ) : degreeLT R n ≃ₗ[R] Fin n → R where toFun p n := (↑p : R[X]).coeff n invFun f := ⟨∑ i : Fin n, monomial i (f i), - (degreeLT R n).sum_mem fun i _ => - mem_degreeLT.mpr - (lt_of_le_of_lt (degree_monomial_le i (f i)) (WithBot.coe_lt_coe.mpr i.is_lt))⟩ - map_add' p q := by - ext - dsimp - rw [coeff_add] - map_smul' x p := by - ext - dsimp - rw [coeff_smul] - rfl - left_inv := by - rintro ⟨p, hp⟩ - ext1 - simp only - by_cases hp0 : p = 0 - · subst hp0 - simp only [coeff_zero, map_zero, Finset.sum_const_zero] - rw [mem_degreeLT, degree_eq_natDegree hp0, Nat.cast_lt] at hp - conv_rhs => rw [p.as_sum_range' n hp, ← Fin.sum_univ_eq_sum_range] - right_inv f := by - ext i - simp only [finsetSum_coeff] - rw [Finset.sum_eq_single i, coeff_monomial, if_pos rfl] - · rintro j - hji - rw [coeff_monomial, if_neg] - rwa [← Fin.ext_iff] - · intro h - exact (h (Finset.mem_univ _)).elim + degreeLT R n |>.sum_mem fun i _ ↦ monomial_coe_mem_degreeLT i (f i)⟩ + map_add' p q := by ext; simp + map_smul' x p := by ext; simp + left_inv := fun ⟨p, hp⟩ ↦ by simpa using p.sum_fin (monomial ·) (by simp) (mem_degreeLT.mp hp) + right_inv f := by ext i; grind [finsetSum_coeff, Finset.sum_eq_single i, coeff_monomial] theorem degreeLTEquiv_eq_zero_iff_eq_zero {n : ℕ} {p : R[X]} (hp : p ∈ degreeLT R n) : degreeLTEquiv _ _ ⟨p, hp⟩ = 0 ↔ p = 0 := by simp From abb22825db7e020c94f38a007ae3fffe6c3a7532 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Sat, 18 Jul 2026 03:35:18 +0000 Subject: [PATCH 0875/1300] feat(RingTheory/Localization/Integer): cardinality of `finsetIntegerMultiple` (#41688) This PR proves injectivity of `integerMultiple` and computes the cardinality of `card_finsetIntegerMultiple`. Co-authored-by: tb65536 --- Mathlib/RingTheory/Localization/Integer.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/RingTheory/Localization/Integer.lean b/Mathlib/RingTheory/Localization/Integer.lean index 2d307a6a86a984..638dfe9bacf2a4 100644 --- a/Mathlib/RingTheory/Localization/Integer.lean +++ b/Mathlib/RingTheory/Localization/Integer.lean @@ -124,6 +124,13 @@ theorem map_integerMultiple {ι : Type*} (s : Finset ι) (f : ι → S) (i : s) algebraMap R S (integerMultiple M s f i) = commonDenom M s f • f i := ((exist_integer_multiples M s f).choose_spec _ i.prop).choose_spec +theorem integerMultipleMultiple_injective {ι : Type*} (s : Finset ι) (f : ι → S) + (hf : Function.Injective f) : Function.Injective (integerMultiple M s f) := by + intro i j h + rw [← SetLike.coe_eq_coe, ← hf.eq_iff, + ← (IsLocalization.smul_bijective S (commonDenom M s f)).injective.eq_iff, + ← map_integerMultiple M s f i, ← map_integerMultiple M s f j, h] + /-- A choice of a common multiple of the denominators of a finite set of fractions. -/ noncomputable def commonDenomOfFinset (s : Finset S) : M := commonDenom M s id @@ -146,4 +153,10 @@ theorem finsetIntegerMultiple_image [DecidableEq R] (s : Finset S) : · rintro ⟨x, hx, rfl⟩ exact ⟨_, ⟨⟨x, hx⟩, s.mem_attach _, rfl⟩, map_integerMultiple M s id _⟩ +@[simp] +theorem card_finsetIntegerMultiple [DecidableEq R] (s : Finset S) : + (finsetIntegerMultiple M s).card = s.card := + (Finset.card_image_of_injective _ (integerMultipleMultiple_injective M s id injective_id)).trans + Finset.card_attach + end IsLocalization From c81c5cbb1cbf71482901fd2f72ab66909ac54fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Sat, 18 Jul 2026 09:48:13 +0000 Subject: [PATCH 0876/1300] doc: fix the docstring of `IsTopologicalTorsor` (#41780) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docstring incorrectly refers to `+ᵥ` and `-ᵥ` instead of their multiplicative versions. --- Mathlib/Topology/Algebra/Group/Torsor.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Algebra/Group/Torsor.lean b/Mathlib/Topology/Algebra/Group/Torsor.lean index e06ff5bde26c9c..6ac8dfab5b444c 100644 --- a/Mathlib/Topology/Algebra/Group/Torsor.lean +++ b/Mathlib/Topology/Algebra/Group/Torsor.lean @@ -28,7 +28,7 @@ class IsTopologicalAddTorsor {V : Type*} [AddGroup V] [TopologicalSpace V] (P : Type*) [AddTorsor V P] [TopologicalSpace P] extends ContinuousVAdd V P where continuous_vsub : Continuous (fun x : P × P => x.1 -ᵥ x.2) -/-- A topological torsor over a topological group is a torsor where `+ᵥ` and `-ᵥ` are continuous. -/ +/-- A topological torsor over a topological group is a torsor where `•` and `/ₛ` are continuous. -/ @[to_additive] class IsTopologicalTorsor {V : Type*} [Group V] [TopologicalSpace V] (P : Type*) [Torsor V P] [TopologicalSpace P] extends ContinuousSMul V P where From 1a9188a8647774da43efde12a5657f72b6f2ed67 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sat, 18 Jul 2026 16:19:03 +0000 Subject: [PATCH 0877/1300] chore: update Mathlib dependencies 2026-07-18 (#41894) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 276fd1329a79f8..6d680856071099 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "45337c634fbcb2bb22fb45c9847faaa10d4d1b67", + "rev": "d4ce69c1bdf7e2d4d728ae3159bcc78b4a5ab830", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 168b9f3a7b2a75315d46232ec28c97f66a467c61 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:14:27 +0000 Subject: [PATCH 0878/1300] doc: fix composition order in Presieve.pullback docstring (#41573) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR fixes the `Presieve.pullback` docstring, which said the pullback of `R` along `f : X ⟶ Y` consists of all `g : Z ⟶ X` such that `f ≫ g` is in `R`; the definition uses `R (g ≫ f)`, and `f ≫ g` is not even well-typed, so the docstring now says `g ≫ f`. Follow-up to [#40527 (feat(CategoryTheory/Sites): pushforward and pullback of presieves)](https://github.com/leanprover-community/mathlib4/pull/40527). 🤖 Prepared with Claude Code --- Mathlib/CategoryTheory/Sites/Sieves.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 9ec716791f7799..b9f71008c03af4 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -320,7 +320,7 @@ lemma pushforward_singleton {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : rw [← ofArrows_pUnit.{0}, pushforward_ofArrows, ofArrows_pUnit.{0}] /-- The pullback of a presieve `R` on `Y` along a morphism `f : X ⟶ Y` is the presieve on `X` -given by all morphisms `g : Z ⟶ X` such that `f ≫ g` is in `R`. -/ +given by all morphisms `g : Z ⟶ X` such that `g ≫ f` is in `R`. -/ def pullback {X Y : C} (f : X ⟶ Y) (R : Presieve Y) : Presieve X := fun _ g ↦ R (g ≫ f) From f041774a2d6216174f56771a5e40e444b3a78f8a Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sat, 18 Jul 2026 18:19:28 +0000 Subject: [PATCH 0879/1300] chore: update Mathlib dependencies 2026-07-18 (#41901) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 6d680856071099..2462db917175d2 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "d4ce69c1bdf7e2d4d728ae3159bcc78b4a5ab830", + "rev": "2c810760f0a0c4536b397dbe30ca9b2f2f467366", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 0ce75b01aba167cf198469d268db587948f44e5a Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Sat, 18 Jul 2026 21:24:09 +0000 Subject: [PATCH 0880/1300] doc: fix typos in SimplicialSet docstrings (#41571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR fixes four docstring typos in `Mathlib/AlgebraicTopology/SimplicialSet/`: "simplcial" → "simplicial" in `Nonsingular.iso`, the broken code reference `s : X : N` → `s : X.N` (plus a missing final period) in `N.toSemiSimplexCategory`, a stray trailing semicolon in `stdSimplex.fullyFaithful`, and "the colimit of the its monogenous subcomplexes" → "the colimit of its monogenous subcomplexes" in `isColimitCoconeN`. Follow-up to [#40254 (feat(AlgebraicTopology): nonsingular simplicial set is colimit of standard simplices)](https://github.com/leanprover-community/mathlib4/pull/40254). 🤖 Prepared with Claude Code --- .../SimplicialSet/NonDegenerateSimplicesColimit.lean | 2 +- Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean | 2 +- Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean | 2 +- Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean index 210c120d4df70c..a847168193dce4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesColimit.lean @@ -89,7 +89,7 @@ lemma fac (s : Cocone X.functorN) (x : X.N) : end isColimitCoconeN open isColimitCoconeN in -/-- If `X : SSet`, then `X` is the colimit of the its monogenous subcomplexes. +/-- If `X : SSet`, then `X` is the colimit of its monogenous subcomplexes. (Note: a monogenous subcomplex of `X` is generated by a unique nondegenerate simplex `x : X.N`.) -/ public noncomputable def isColimitCoconeN : IsColimit X.coconeN where diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean index 0d31bdaaec145b..ed84b6e2cc4ba9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Nonsingular.lean @@ -121,7 +121,7 @@ lemma Nonsingular.isIso_toOfSimplex [X.Nonsingular] rw [Subcomplex.isIso_toOfSimplex_iff] exact Nonsingular.mono' x hx -/-- If `x : X _⦋n⦌` is a nondegenerate simplex of a nonsingular simplcial set, +/-- If `x : X _⦋n⦌` is a nondegenerate simplex of a nonsingular simplicial set, this is the isomorphism `Δ[n] ≅ Subcomplex.ofSimplex x` induced by `x`. -/ @[expose, simps! hom] noncomputable def Nonsingular.iso diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean index 319b40edc98f78..b54db0d54e0ea1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonsingularColimit.lean @@ -37,7 +37,7 @@ namespace N set_option backward.isDefEq.respectTransparency false in /-- If `X` is a nonsingular simplicial set, this is the functor `X.N ⥤ SemiSimplexCategory` which sends a nondegenerate -simplex `s : X : N` to `⦋s.dim⦌ₛ` -/ +simplex `s : X.N` to `⦋s.dim⦌ₛ`. -/ @[simps obj map] noncomputable def toSemiSimplexCategory : X.N ⥤ SemiSimplexCategory where obj s := ⦋s.dim⦌ₛ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 2514bf6a3500b3..4daed92d919f28 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -51,7 +51,7 @@ namespace stdSimplex open Finset Opposite SimplexCategory -/-- The functor `stdSimplex : SimplexCategory ⥤ SSet` is fully faithful; -/ +/-- The functor `stdSimplex : SimplexCategory ⥤ SSet` is fully faithful. -/ abbrev fullyFaithful : stdSimplex.{u}.FullyFaithful := ULiftYoneda.fullyFaithful SimplexCategory From 5f6fd26f8a2e331274b6ce3103aaadca3cd2a33a Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Sat, 18 Jul 2026 21:34:45 +0000 Subject: [PATCH 0881/1300] chore(AlgebraicTopology/Reedy): cosmetic cleanups (#41581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR makes three cosmetic fixes in `Mathlib/AlgebraicTopology/Reedy/Basic.lean`: replace the ASCII `<-` with `←` in the proof of `degHom_comp_le_right`, fix the grammar typo "degree of a morphisms" in the docstring of `degHom`, and delete the unused `universe u` declaration. Follow-up to [#41141 (feat(AlgebraicTopology): Reedy structures)](https://github.com/leanprover-community/mathlib4/pull/41141). 🤖 Prepared with Claude Code --- Mathlib/AlgebraicTopology/Reedy/Basic.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/AlgebraicTopology/Reedy/Basic.lean b/Mathlib/AlgebraicTopology/Reedy/Basic.lean index 625b0026c3d70a..7a48df269b089b 100644 --- a/Mathlib/AlgebraicTopology/Reedy/Basic.lean +++ b/Mathlib/AlgebraicTopology/Reedy/Basic.lean @@ -30,8 +30,6 @@ https://github.com/leanprover-community/project-intentions/issues/5 @[expose] public section -universe u - open CategoryTheory namespace HomotopicalAlgebra @@ -123,7 +121,7 @@ lemma unique {X Y : C} {f : X ⟶ Y} (fac fac' : W₁.MapFactorizationData W₂ obtain rfl : fac = fac' := Subsingleton.elim _ _ simp -/-- The degree of a morphisms for a Reedy structure. It is defined as the degree of +/-- The degree of a morphism for a Reedy structure. It is defined as the degree of the intermediate object in the Reedy factorization, but it is also the smallest degree of an intermediate object in a factorization, see the lemma `degHom_le`. -/ @[no_expose] @@ -168,7 +166,7 @@ lemma degHom_comp_le_left {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : lemma degHom_comp_le_right {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : r.degHom (f ≫ g) ≤ r.degHom g := by have ⟨_, g₁, g₂, _, _, h_fac, h_deg⟩ := r.exists_fac g - rw [h_deg, ← h_fac, <- Category.assoc] + rw [h_deg, ← h_fac, ← Category.assoc] exact r.degHom_le (f ≫ g₁) g₂ lemma prop₂_of_degHom_eq_deg_left {X Y : C} {f : X ⟶ Y} (hf : r.degHom f = r.deg X) : From cb31bafb093067f5ec7df56724cf708940124295 Mon Sep 17 00:00:00 2001 From: "mathlib-nolints[bot]" <258989889+mathlib-nolints[bot]@users.noreply.github.com> Date: Sun, 19 Jul 2026 00:41:00 +0000 Subject: [PATCH 0882/1300] chore(scripts): update nolints.json (#41908) I am happy to remove some nolints for you! --- scripts/nolints.json | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/scripts/nolints.json b/scripts/nolints.json index c52b1149fb44d6..65c5e2657ceec6 100644 --- a/scripts/nolints.json +++ b/scripts/nolints.json @@ -117,8 +117,6 @@ ["defsWithUnderscore", "CovariantDerivative.finite_affine_combination"], ["defsWithUnderscore", "CovariantDerivative.of_isCovariantDerivativeOn_of_open_cover"], - ["defsWithUnderscore", "DirectSum.congr_addEquiv"], - ["defsWithUnderscore", "DirectSum.congr_linearEquiv"], ["defsWithUnderscore", "DirichletCharacter.primitive_mul"], ["defsWithUnderscore", "DividedPowers.ideal_from_ringHom"], ["defsWithUnderscore", "DividedPowers.subDPIdeal_inf_of_quot"], @@ -159,9 +157,6 @@ ["defsWithUnderscore", "Int.le_induction"], ["defsWithUnderscore", "Int.le_induction_down"], ["defsWithUnderscore", "IntermediateField.restrict_algEquiv"], - ["defsWithUnderscore", "IsLocalDiffeomorph.diffeomorph_of_bijective"], - ["defsWithUnderscore", "IsLocalFrameOn.fintype_of_finiteDimensional"], - ["defsWithUnderscore", "IsLocalHomeomorph.toHomeomorph_of_bijective"], ["defsWithUnderscore", "IsLocalization.invertible_mk'_one"], ["defsWithUnderscore", "IsUltrametricDist.ball_openAddSubgroup"], ["defsWithUnderscore", "IsUltrametricDist.ball_openSubgroup"], @@ -184,8 +179,6 @@ ["defsWithUnderscore", "Matrix.equiv_GL_linearindependent"], ["defsWithUnderscore", "Matroid.aesop_mat"], ["defsWithUnderscore", "MeasureTheory.tacticVolume_tac"], - ["defsWithUnderscore", "ModelWithCorners.of_convex_range"], - ["defsWithUnderscore", "ModelWithCorners.of_target_univ"], ["defsWithUnderscore", "ModularForm.eisensteinSeries_MF"], ["defsWithUnderscore", "ModularForm.eta_q"], ["defsWithUnderscore", "ModuleCat.forget₂AddCommGroup_preservesLimitsAux"], @@ -219,7 +212,6 @@ ["defsWithUnderscore", "Ordinal.pred_succ_gi"], ["defsWithUnderscore", "PadicInt.addChar_of_value_at_one"], ["defsWithUnderscore", "PadicInt.continuousAddCharEquiv_of_norm_mul"], - ["defsWithUnderscore", "PadicInt.dividedPowers_of_injective"], ["defsWithUnderscore", "Polynomial.divX_hom"], ["defsWithUnderscore", "Polynomial.hilbertPoly_linearMap"], ["defsWithUnderscore", "Polynomial.smul_pow"], @@ -310,7 +302,6 @@ ["defsWithUnderscore", "lTensor.linearEquiv_of_rightInverse"], ["defsWithUnderscore", "rTensor.inverse_of_rightInverse"], ["defsWithUnderscore", "rTensor.linearEquiv_of_rightInverse"], - ["defsWithUnderscore", "AbsoluteValue.Completion.extensionEmbedding_of_comp"], ["defsWithUnderscore", "AddChar.FiniteField.primitiveChar_to_Complex"], ["defsWithUnderscore", "AddCommGrpCat.Colimits.isColimit_of_bijective_desc"], ["defsWithUnderscore", "AlgEquiv.ofLinearEquiv_symm.aux"], @@ -431,7 +422,6 @@ ["defsWithUnderscore", "Submodule.quotientPi_aux.invFun"], ["defsWithUnderscore", "Submodule.quotientPi_aux.toFun"], ["defsWithUnderscore", "SzemerediRegularity.Positivity.tacticSz_positivity"], - ["defsWithUnderscore", "Tactic.Interactive.tacticUnit_interval"], ["defsWithUnderscore", "Tactic.ReduceModChar.reduce_mod_char"], ["defsWithUnderscore", "Tactic.ReduceModChar.reduce_mod_char!"], ["defsWithUnderscore", "TopCat.Presheaf.algebra_section_stalk"], @@ -530,8 +520,6 @@ ["defsWithUnderscore", "Profinite.NobelingProof.GoodProducts.sum_to"], ["defsWithUnderscore", "Stream'.WSeq.destruct_append.aux"], ["defsWithUnderscore", "Stream'.WSeq.destruct_join.aux"], - ["defsWithUnderscore", "Mathlib.Meta.NormNum.NotPowerCertificate.pf_left"], - ["defsWithUnderscore", "Mathlib.Meta.NormNum.NotPowerCertificate.pf_right"], ["defsWithUnderscore", "CategoryTheory.IsCardinalFiltered.exists_cardinal_directed.Diagram.P"], ["defsWithUnderscore", @@ -551,6 +539,8 @@ ["defsWithUnderscore", "Mathlib.Meta.Finset.ProveEmptyOrConsResult.eq_trans"], ["defsWithUnderscore", "Mathlib.Meta.List.ProveNilOrConsResult.eq_trans"], ["defsWithUnderscore", "Mathlib.Meta.Multiset.ProveZeroOrConsResult.eq_trans"], + ["defsWithUnderscore", "Mathlib.Meta.NormNum.NotPowerCertificate.pf_left"], + ["defsWithUnderscore", "Mathlib.Meta.NormNum.NotPowerCertificate.pf_right"], ["defsWithUnderscore", "Mathlib.Meta.NormNum.Result.eq_trans"], ["defsWithUnderscore", "CategoryTheory.IsCardinalFiltered.exists_cardinal_directed.Diagram.IsTerminal.lift"], @@ -602,7 +592,6 @@ ["docBlame", "IntermediateField.delabAdjoinNotation"], ["docBlame", "IsAdjoinRoot.map"], ["docBlame", "JordanHolderLattice.IsMaximal"], - ["docBlame", "JordanHolderLattice.Iso"], ["docBlame", "Lean.ExportM"], ["docBlame", "MaximalSpectrum.asIdeal"], ["docBlame", "ModularForm.«term_∣[_]_»"], From c2ea7ca1e55ede82135eb79555926975d87bd264 Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Sun, 19 Jul 2026 02:25:22 +0000 Subject: [PATCH 0883/1300] feat: add theorem that Bird's determinant algorithm computes Matrix.det (#41160) This PR adds: ```lean theorem det_eq_birdDet {n : Nat} (A : Array R) (hA : A.size = n * n) : Matrix.det (Matrix.ofArray (m := n) (n := n) A hA) = birdDet n A ``` showing that Bird's determinant algorithm computes `Matrix.det`. The PR also adds: - `BirdDet.Spec.birdDet` - an alternative implementation of Bird's algorithm that's stated in terms of `Matrix` instead of `Array`. Co-authored-by: Oliver Nash Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Co-authored-by: Johan Commelin --- Mathlib.lean | 1 + Mathlib/Data/Fin/Tuple/Basic.lean | 20 ++ Mathlib/GroupTheory/Perm/Fin.lean | 6 + Mathlib/LinearAlgebra/Matrix/Defs.lean | 7 + .../Matrix/Determinant/Bird/Correctness.lean | 305 ++++++++++++++++++ .../Matrix/Determinant/Bird/Defs.lean | 106 ++++-- Mathlib/Order/Fin/Tuple.lean | 51 ++- Mathlib/Tactic/Determinant/Bird/Cert.lean | 99 +++--- docs/references.bib | 12 + 9 files changed, 532 insertions(+), 75 deletions(-) create mode 100644 Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Correctness.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1db92a61911933..06874d1c0aa5ec 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5113,6 +5113,7 @@ public import Mathlib.LinearAlgebra.Matrix.Circulant public import Mathlib.LinearAlgebra.Matrix.ConjTranspose public import Mathlib.LinearAlgebra.Matrix.Defs public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Correctness public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs public import Mathlib.LinearAlgebra.Matrix.Determinant.Misc public import Mathlib.LinearAlgebra.Matrix.Determinant.TotallyUnimodular diff --git a/Mathlib/Data/Fin/Tuple/Basic.lean b/Mathlib/Data/Fin/Tuple/Basic.lean index 6d18a6513dea9c..b9119b3c735890 100644 --- a/Mathlib/Data/Fin/Tuple/Basic.lean +++ b/Mathlib/Data/Fin/Tuple/Basic.lean @@ -119,6 +119,11 @@ theorem tail_cons : tail (cons x p) = p := by @[simp] theorem cons_succ : cons x p i.succ = p i := by simp [cons] +@[simp] +theorem cons_comp_succ {α : Sort*} (x : α) (p : Fin n → α) : + cons x p ∘ Fin.succ = p := + funext fun _ ↦ Fin.cons_succ .. + @[simp] theorem cons_zero : cons x p 0 = x := by simp [cons] @@ -166,6 +171,10 @@ theorem cons_self_tail : cons (q 0) (tail q) = q := by ext j cases j using Fin.cases <;> simp [tail] +@[simp] +theorem cons_zero_succ : (cons 0 Fin.succ : Fin (n + 1) → Fin (n + 1)) = id := + cons_self_tail id + /-- Equivalence between tuples of length `n + 1` and pairs of an element and a tuple of length `n` given by separating out the first element of the tuple. @@ -870,6 +879,11 @@ lemma removeNth_apply (p : Fin (n + 1)) (f : ∀ i, α i) (i : Fin n) : p.removeNth f i = f (p.succAbove i) := rfl +@[simp] +theorem cons_comp_succ_succAbove (x : β) (p : Fin (n + 1) → β) (i : Fin (n + 1)) : + cons x p ∘ i.succ.succAbove = cons x (i.removeNth p) := + funext (Fin.cases rfl fun _ ↦ by simp [removeNth]) + lemma removeNth_fun_const {α : Type*} {n : ℕ} (i : Fin (n + 1)) (a : α) : i.removeNth (fun _ ↦ a) = (fun _ ↦ a) := rfl @@ -1027,6 +1041,12 @@ lemma removeNth_update_succAbove (p : Fin (n + 1)) (i : Fin n) (x : α (p.succAb lemma insertNth_self_removeNth (p : Fin (n + 1)) (f : ∀ j, α j) : insertNth p (f p) (removeNth p f) = f := by simp +@[simp] +lemma range_insertNth {α : Type*} (p : Fin (n + 1)) (x : α) (f : Fin n → α) : + Set.range (p.insertNth x f) = Set.insert x (Set.range f) := by + ext y + simp [Fin.exists_iff_succAbove p, Set.insert, eq_comm] + @[simp] theorem update_insertNth (p : Fin (n + 1)) (x y : α p) (f : ∀ i, α (p.succAbove i)) : update (p.insertNth x f) p y = p.insertNth y f := by diff --git a/Mathlib/GroupTheory/Perm/Fin.lean b/Mathlib/GroupTheory/Perm/Fin.lean index 229799f3cb3b4a..e2582a29d62569 100644 --- a/Mathlib/GroupTheory/Perm/Fin.lean +++ b/Mathlib/GroupTheory/Perm/Fin.lean @@ -273,6 +273,12 @@ theorem insertNth_comp_cycleRange_symm {α : Type*} (p : Fin (n + 1)) (a : α) ( ext j simp +theorem cons_removeNth_eq_comp_cycleRange_symm {α : Type*} + (x : Fin (n + 1) → α) (p : Fin (n + 1)) : + Fin.cons (x p) (p.removeNth x) = x ∘ p.cycleRange.symm := by + ext i + cases i using Fin.cons <;> simp [Fin.removeNth_apply] + @[simp] theorem cons_apply_cycleRange {α : Type*} (a : α) (x : Fin n → α) (p j : Fin (n + 1)) : (Fin.cons a x : _ → α) (p.cycleRange j) = (p.insertNth a x : _ → α) j := by diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index a985501cb0eaf3..f0c9653717e388 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -6,6 +6,7 @@ Authors: Ellen Arlt, Blair Shi, Sean Leather, Mario Carneiro, Johan Commelin, Lu module public import Mathlib.Algebra.Module.Pi +public import Batteries.Data.Fin.Lemmas public import Mathlib.Data.Fin.Basic public import Mathlib.Logic.Nontrivial.Basic public import Mathlib.Tactic.CrossRefAttribute @@ -103,6 +104,12 @@ def ofArray {m n : ℕ} (A : Array R) (hA : A.size = m * n) : Matrix (Fin m) (Fi theorem ofArray_apply {m n : ℕ} (A : Array R) (hA : A.size = m * n) (i : Fin m) (j : Fin n) : ofArray A hA i j = A[Fin.mkDivMod i j] := rfl +lemma ofArray_eq_of_getD [Zero R] {m n : ℕ} (A : Array R) (hA : A.size = m * n) : + ofArray A hA = .of fun i j ↦ A.getD (n * i.val + j.val) 0 := by + ext i j + have : n * i.val + j.val < m * n := (Fin.mkDivMod i j).isLt + simp [ofArray, hA, this] + /-- `M.map f` is the matrix obtained by applying `f` to each entry of the matrix `M`. This is available in bundled forms as: diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Correctness.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Correctness.lean new file mode 100644 index 00000000000000..ab794ec3ebfa43 --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Correctness.lean @@ -0,0 +1,305 @@ +/- +Copyright (c) 2026 Paul Cadman. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Paul Cadman +-/ +module + +public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs +import Mathlib.Algebra.Order.BigOperators.Group.LocallyFinite +import Mathlib.Data.Fintype.Order +import Mathlib.Order.Preorder.Finite + +/-! +# Correctness of Bird's determinant algorithm + +This file contains a proof that Bird's division-free algorithm computes +`Matrix.det`, in both its matrix form `BirdDet.Spec.birdDet` +(`birdDetSpec_eq_det`) and its flat-array form `BirdDet.birdDet` +(`det_eq_birdDet`), formalizing the combinatorial argument of +[Richard S. Bird, *A simple division-free algorithm for computing determinants*][bird2011]. + +## Correspondence with the paper + +* A word of length `p` is a tuple `Fin p → Fin n`, using the indexing convention + above (NB: Indices in Bird's paper start at 1). +* `f[α, β]`, the minor on rows `α` and columns `β`, is `(A.submatrix α β).det`. +* `f[iα, jα]`, a bordered minor, is `bminor A i j α`, with the word `iα` spelled + `Fin.cons i α`. +* `f[α, α]`, a principal minor, is `pminor A α`. +* If `i : Fin n` represents Bird's symbol `r = i.val + 1`, then Bird's + `βᵣ = [r + 1, ..., n]` is represented by `Finset.Ioi i`. +* Bird's `Sₚ(βᵣ)`, the length `p` subsequences of `βᵣ`, is represented by `S p i`. + +The theorem names `paper_eq1`, ..., `paper_eq5` follow Bird's numbering. + +## Main results + +- `BirdDet.birdDetSpec_eq_det`: `Matrix.det` computes the same determinant as `BirdDet.Spec.birdDet` +- `BirdDet.det_eq_birdDet`: `Matrix.det` computes the same determinant as `BirdDet.birdDet` +-/ + +namespace BirdDet + +open Function +variable {R : Type*} [CommRing R] {m n : ℕ} + +/-- `sumFrom n lo f` is the sum of `f` over the half-open interval `[lo, n)`. -/ +theorem sumFrom_eq_sum_Ico {lo : ℕ} (f : ℕ → R) : + BirdDet.sumFrom n lo f = ∑ k ∈ Finset.Ico lo n, f k := by + induction lo using BirdDet.sumFrom_induct n with + | step lo hlo ih => rw [sumFrom_step n lo f hlo, ih, ← Finset.sum_eq_sum_Ico_succ_bot hlo f] + | stop lo hlo => rw [sumFrom_stop n lo f hlo, Finset.Ico_eq_empty hlo, Finset.sum_empty] + +theorem sumFrom_fin_tail (i : Fin n) (f : ℕ → R) : + BirdDet.sumFrom n (i.val + 1) f = ∑ k ∈ Finset.Ioi i, f k.val := calc + _ = ∑ k ∈ Finset.Ico (i.val + 1) n, f k := by rw [sumFrom_eq_sum_Ico] + _ = ∑ k ∈ (Finset.range n).filter (i.val < ·), f k := by congr; ext; aesop + _ = ∑ k ∈ Finset.range n, if i.val < k then f k else 0 := by rw [Finset.sum_filter] + _ = ∑ k : Fin n, if i.val < k.val then f k.val else 0 := by rw [← Fin.sum_univ_eq_sum_range] + _ = ∑ k ∈ Finset.Ioi i, f k.val := by simp [← Finset.sum_filter, Finset.filter_lt_eq_Ioi] + +/-- The scalar recurrence initialized by array lookup agrees pointwise + with the matrix recurrence. -/ +theorem iterate_stepEntry_get_eq_spec (A : Array R) (hA : A.size = n * n) (t : ℕ) (i j : Fin n) : + ((stepEntry n A)^[t] (BirdDet.get n A)) i.val j.val = + (Spec.stepEntry (.ofArray A hA))^[t] (.ofArray A hA) i j := by + rw [Matrix.ofArray_eq_of_getD] + induction t generalizing i j with + | zero => simp [get_eq] + | succ t ih => + simp_rw [iterate_succ_apply', stepEntry_eq, Spec.stepEntry_eq, sumFrom_fin_tail, ih, + Matrix.of_apply, get_eq] + +/-- The flat-array algorithm `BirdDet.birdDet` computes the same determinant as + `BirdDet.Spec.birdDet`. -/ +theorem birdDet_eq_birdDetSpec (A : Array R) (hA : A.size = n * n) : + birdDet n A = Spec.birdDet (.ofArray A hA) := by + cases n with + | zero => rw [birdDet_zero, Spec.birdDetSpec_zero] + | succ k => simp [birdDet_succ, Spec.birdDetSpec_succ, ← iterate_stepEntry_get_eq_spec A hA k] + +variable (A : Matrix (Fin n) (Fin n) R) {p : ℕ} + +/-- Bird's bordered minor `f[iα, jα]`. -/ +abbrev bminor (i j : Fin n) (α : Fin p → Fin n) : R := + (A.submatrix (Fin.cons i α) (Fin.cons j α)).det + +/-- Bird's principal minor `f[α, α]`. -/ +abbrev pminor (α : Fin p → Fin n) : R := + (A.submatrix α α).det + +lemma det_submatrix_removeNth_eq_sign_mul_bminor + (α : Fin (p + 1) → Fin n) (i : Fin n) (s : Fin (p + 1)) : + (A.submatrix (Fin.cons i (s.removeNth α)) α).det = + (-1 : R) ^ s.val * bminor A i (α s) (s.removeNth α) := + calc + _ = (-1 : R) ^ s.val * ((A.submatrix (Fin.cons i (s.removeNth α)) α) + |>.submatrix id (Fin.cycleRange s).symm).det := by + rw [Matrix.det_permute'] + simp [← mul_assoc, ← pow_add] + _ = (-1 : R) ^ s.val * bminor A i (α s) (s.removeNth α) := by + congrm _ * Matrix.det ?_ + simp [Fin.cons_removeNth_eq_comp_cycleRange_symm] + +/-- First-column Laplace expansion of a bordered minor -/ +theorem det_bordered_expand (α : Fin (p + 1) → Fin n) (i j : Fin n) : + bminor A i j α = + pminor A α * A i j - ∑ s : Fin (p + 1), bminor A i (α s) (s.removeNth α) * A (α s) j := calc + _ = A i j * pminor A α + + ∑ s : Fin (p + 1), (-1 : R) ^ (s.val + 1) * A (α s) j * + (A.submatrix (Fin.cons i (s.removeNth α)) α).det := by + rw [bminor, Matrix.det_succ_column_zero, Fin.sum_univ_succ]; simp + _ = pminor A α * A i j + + ∑ s : Fin (p + 1), + ((-1 : R) ^ (s.val + 1) * + (A.submatrix (Fin.cons i (s.removeNth α)) α).det) * A (α s) j := by + simp only [mul_comm (A i j), mul_right_comm] + _ = pminor A α * A i j + + ∑ s : Fin (p + 1), -(bminor A i (α s) (s.removeNth α) * A (α s) j) := by + simp only [det_submatrix_removeNth_eq_sign_mul_bminor, ← mul_assoc, ← pow_add]; aesop + _ = pminor A α * A i j - + ∑ s : Fin (p + 1), bminor A i (α s) (s.removeNth α) * A (α s) j := by + simp only [Finset.sum_neg_distrib, sub_eq_add_neg] + +/-- A bordered minor is zero when its border column already occurs in the word. -/ +theorem bminor_eq_zero_of_mem_range + {k : Fin n} (α : Fin p → Fin n) (i : Fin n) (hk : k ∈ Set.range α) : + bminor A i k α = 0 := by + obtain ⟨q, rfl⟩ := hk + -- The repeated columns in the submatrix used in bminor are `0` and `q + 1`. + exact Matrix.det_zero_of_column_eq q.succ_ne_zero <| by simp + +/-- `S p i` is Bird's `Sₚ(βᵢ)`: words `α` of length `p` over the alphabet `βᵢ`. -/ +def S (p : ℕ) (i : Fin n) : Finset (Fin p → Fin n) := + {α : Fin p → Fin n | StrictMono (Fin.cons i α)} + +/-- Membership in `S p i` is strict monotonicity of the bordered word. -/ +theorem mem_S_iff {p : ℕ} {i : Fin n} {α : Fin p → Fin n} : + α ∈ S p i ↔ StrictMono (Fin.cons i α) := + Finset.mem_filter_univ α + +/-- The base case of equation (1): `S₀(α) = {ε}`, the singleton of the empty +word `ε`. -/ +theorem S_zero (i : Fin n) : S 0 i = {![]} := by + ext; simp [mem_S_iff, Fin.strictMono_iff_lt_succ, eq_iff_true_of_subsingleton] + +/-- The unique maximum-length word over the symbols above `0` is `Fin.succ`. -/ +@[simp] lemma S_zero_eq_singleton {p : ℕ} : S p 0 = {Fin.succ} := by + ext; simp [mem_S_iff] + +/-! ## Decomposition `S_{p+1}(βᵢ) = { kα | k ∈ βᵢ, α ∈ S_p(β_k) }` -/ + +/-- `S (p + 1) i` can be written as the image of a `biUnion` -/ +theorem S_succ_eq_biUnion {p : ℕ} (i : Fin n) : + S (p + 1) i = (Finset.Ioi i).biUnion fun k ↦ (S p k).image (Fin.cons k) := by + ext α + simp only [Finset.mem_biUnion, Finset.mem_image, Finset.mem_Ioi, mem_S_iff] + refine ⟨fun hα ↦ ⟨α 0, (Fin.strictMono_cons.mp hα).1 0, Fin.tail α, ?_, Fin.cons_self_tail α⟩, ?_⟩ + · simp only [Fin.cons_self_tail] + exact hα.comp Fin.strictMono_succ + · rintro ⟨k, hk, u, hu, rfl⟩ + exact StrictMono.vecCons hu hk + +/-- A symbol above `i` that does not occur in a word in `S p i` can be inserted while +preserving strict monotonicity. -/ +lemma exists_insertNth_mem_S {p : ℕ} {i : Fin n} {α : Fin p → Fin n} {k : Fin n} + (hα : α ∈ S p i) (hik : i < k) (hk : k ∉ Set.range α) : + ∃ t : Fin (p + 1), t.insertNth k α ∈ S (p + 1) i := by + set t := ⨅ j ∈ {j | k < α j}, j.castSucc with t_eq + use t + simp only [mem_S_iff, Fin.strictMono_cons] at ⊢ hα + refine ⟨fun j ↦ Fin.succAboveCases t ?_ ?_ j, ?_⟩ + · simp only [t_eq, Set.mem_ofPred_eq, Fin.strictMono_insertNth_iff, hα.2, lt_iInf_iff, + le_iInf_iff, forall_exists_index, and_imp, iInf_le_iff_forall_lt, iInf_lt_iff, + exists_prop, true_and] + refine ⟨fun j x hjx h ↦ ?_, fun j h ↦ ?_⟩ + · contrapose! h + have k_ne (j : Fin p) : k ≠ α j := fun hj ↦ hk ⟨j, hj.symm⟩ + exact ⟨j, h.lt_of_ne (k_ne _), hjx⟩ + · obtain ⟨q, hkq, hqj⟩ := h j.succ j.castSucc_lt_succ + exact hkq.trans_le <| hα.2.monotone <| Fin.castSucc_lt_succ_iff.mp hqj + · simpa + · simpa using hα.1 + +variable (p) in +/-- Bird's equation (1) : `x^(p)_ij = (-1)^p ∑ { f[iα, jα] | α ∈ S_p(βᵢ) }`. -/ +abbrev Eq1 : Prop := + (Spec.stepEntry A)^[p] A = .of fun i j ↦ (-1) ^ p * ∑ α ∈ S p i, bminor A i j α + +/-! ## Equations (2) and (3): substituting the induction hypothesis -/ + +/-- Bird's equation (2), assuming equation (1) at `p` as the induction hypothesis. -/ +theorem paper_eq2 (i : Fin n) (hEq1 : Eq1 A p) : + (-∑ k ∈ Finset.Ioi i, (Spec.stepEntry A)^[p] A k k) = + (-1) ^ (p + 1) * ∑ α ∈ S (p + 1) i, pminor A α := by + calc + (-∑ k ∈ Finset.Ioi i, (Spec.stepEntry A)^[p] A k k) = + (-1) ^ (p + 1) * ∑ k ∈ Finset.Ioi i, ∑ α ∈ S p k, bminor A k k α := by + simp only [hEq1, Matrix.of_apply, ← Finset.mul_sum] + ring + _ = (-1) ^ (p + 1) * ∑ α ∈ S (p + 1) i, pminor A α := by + rw [S_succ_eq_biUnion, Finset.sum_biUnion] + · congrm (((-1) ^ (p + 1) * ∑ k ∈ Finset.Ioi i, ?_)) + symm + exact Finset.sum_image fun _ _ _ _ hαβ => (Fin.cons_inj.mp hαβ).2 + · grind [Set.PairwiseDisjoint, Set.Pairwise, Finset.disjoint_left, Fin.cons_inj] + +/-- Bird's equation (3), assuming equation (1) at `p` as the induction hypothesis. -/ +theorem paper_eq3 (i j : Fin n) (hEq1 : Eq1 A p) : + ((Spec.stepEntry A)^[p + 1] A) i j = + (-1) ^ (p + 1) * (∑ α ∈ S (p + 1) i, pminor A α * A i j - + ∑ k ∈ Finset.Ioi i, ∑ α ∈ S p i, bminor A i k α * A k j) := by + simp_rw [iterate_succ_apply', Spec.stepEntry_eq, Matrix.of_apply, paper_eq2 _ _ hEq1, hEq1, + Matrix.of_apply, mul_assoc, Finset.sum_mul, ← Finset.mul_sum] + ring + +/-! ## Equation (5): first-column Laplace expansion -/ + +/-- Bird's equation (5) -/ +theorem paper_eq5 (i j : Fin n) : + ∑ α ∈ S (p + 1) i, bminor A i j α = + ∑ α ∈ S (p + 1) i, pminor A α * A i j - + ∑ α ∈ S (p + 1) i, ∑ t : Fin (p + 1), bminor A i (α t) (t.removeNth α) * A (α t) j := calc + _ = ∑ α ∈ S (p + 1) i, (pminor A α * A i j - + ∑ t : Fin (p + 1), bminor A i (α t) (t.removeNth α) * A (α t) j) := by + exact Finset.sum_congr rfl <| by simp [det_bordered_expand] + _ = ∑ α ∈ S (p + 1) i, pminor A α * A i j - + ∑ α ∈ S (p + 1) i, ∑ t : Fin (p + 1), bminor A i (α t) (t.removeNth α) * A (α t) j := by + rw [Finset.sum_sub_distrib] + +/-! ## Comparing equations (3) and (5): reindex by sorted insert/delete -/ + +/-- The off-diagonal sums in Bird's equations (3) and (5) agree. -/ +theorem paper_eq3_eq5_off_diag (i j : Fin n) : + ∑ k ∈ Finset.Ioi i, ∑ α ∈ S p i, bminor A i k α * A k j = + ∑ α' ∈ S (p + 1) i, ∑ t : Fin (p + 1), bminor A i (α' t) (t.removeNth α') * A (α' t) j := by + rw [Finset.sum_comm, ← Finset.sum_product', ← Finset.sum_product'] + -- The right-hand summand is the left-hand summand composed with the deletion map + -- + -- d (α, t) := (t.removeNth α, α t). + -- + -- This map is injective, and every left-hand summand outside its image is zero, + -- so `sum_of_injOn` applies. + symm + refine Finset.sum_of_injOn (fun ⟨α, k⟩ ↦ ⟨k.removeNth α, α k⟩) ?_ ?_ ?_ ?_ + · simp only [Set.InjOn, Finset.coe_product, Finset.coe_univ, Set.mem_prod, Set.mem_univ, + and_true, Finset.mem_coe, Prod.mk.injEq, and_imp, Prod.forall, mem_S_iff, Fin.strictMono_cons] + intros α k hi hiα α' k' hj hiα' hremove hvalue + suffices hrange : Set.range α = Set.range α' by + rw [hiα.range_inj hiα'] at hrange + subst α' + exact ⟨rfl, hiα.injective hvalue⟩ + calc + _ = Set.insert (α k) (Set.range (k.removeNth α)) := by + rw [← Fin.range_insertNth, Fin.insertNth_self_removeNth] + _ = Set.insert (α' k') (Set.range (k'.removeNth α')) := by + rw [hvalue, hremove] + _ = Set.range α' := by + rw [← Fin.range_insertNth, Fin.insertNth_self_removeNth] + · rintro ⟨α, t⟩ hα + simp only [Finset.coe_product, Finset.coe_univ, Set.mem_prod, Set.mem_univ, and_true, + Finset.mem_coe, Finset.coe_Ioi, Set.mem_Ioi, mem_S_iff, Fin.strictMono_cons] at hα ⊢ + obtain ⟨hbound, hmono⟩ := hα + exact ⟨⟨fun q => hbound (t.succAbove q), hmono.removeNth t⟩, hbound t⟩ + · rintro ⟨α, k⟩ htarget hnotmem + simp only [Finset.mem_product, Finset.mem_Ioi] at htarget + obtain ⟨hα, hk⟩ := htarget + by_cases hoccurs : k ∈ Set.range α + · -- The border column `k` is repeated among the columns indexed by `α` and + -- so the bordered minor is 0. + rw [bminor_eq_zero_of_mem_range A α i hoccurs, zero_mul] + · contrapose hnotmem + obtain ⟨t, ht⟩ := exists_insertNth_mem_S hα hk hoccurs + exact ⟨(t.insertNth k α, t), by simpa, by simp⟩ + · simp + +/-! ## Bird's Equation (1) -/ +theorem paper_eq1 : Eq1 A p := by + induction p with + | zero => + ext i j + simp [iterate_zero_apply, S_zero, bminor] + | succ p ih => + ext i j + rw [Matrix.of_apply, paper_eq3 A i j ih, paper_eq5 A, paper_eq3_eq5_off_diag A] + +/-! ## instantiating equation (1) to prove Theorem 1 -/ + +/-- Bird's Theorem 1 -/ +theorem birdDetSpec_eq_det (A : Matrix (Fin n) (Fin n) R) : + Matrix.det A = Spec.birdDet A := by + cases n with + | zero => simp + | succ k => + have : ∑ α ∈ S k 0, bminor A 0 0 α = A.det := by simp [bminor] + rw [Spec.birdDetSpec_succ, paper_eq1, Matrix.of_apply, ← mul_assoc, ← pow_add]; aesop + +/-- `BirdDet.birdDet n A` computes the determinant of the `n × n` matrix whose + entries are stored in row-major order in `A`. -/ +public theorem det_eq_birdDet (A : Array R) (hA : A.size = n * n) : + Matrix.det (.ofArray A hA) = birdDet n A := by + rw [birdDet_eq_birdDetSpec, birdDetSpec_eq_det] + +end BirdDet diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Defs.lean index f482861da89563..bd309b8fc51e54 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Bird/Defs.lean @@ -5,27 +5,31 @@ Authors: Paul Cadman -/ module +public import Mathlib.Algebra.BigOperators.Group.Finset.Basic +public import Mathlib.Order.Interval.Finset.Fin public import Mathlib.Algebra.Ring.Defs +public import Mathlib.Data.Fintype.Basic +public import Mathlib.LinearAlgebra.Matrix.Defs +public import Mathlib.Logic.Function.Iterate /-! # A division-free determinant algorithm -This file defines `birdDet`, an implementation of an division-free algorithm for -computing determinants. The algorithm runs in O(n^4) for an n-by-n matrix. +This file defines `birdDet`and `Spec.birdDet`, implementations of an +division-free algorithm for computing determinants. The algorithm runs in O(n^4) +for an n-by-n matrix. -This determinant algorithm comes from: - -Title: A simple division-free algorithm for computing determinants. -Author: Richard S. Bird -URL: https://doi.org/10.1016/j.ipl.2011.08.006 +This determinant algorithm comes from +[Richard S. Bird, *A simple division-free algorithm for computing determinants*][bird2011]. ## Main definitions - `BirdDet.birdDet`: The entrypoint for the determinant calculation. - `BirdDet.get`: matrix entry lookup. - `BirdDet.sumFrom`: The sum `f lo + ... + f (n - 1)`. -- `BirdDet.iter`: The internal scalar recurrence for Bird's algorithm. +- `BirdDet.stepEntry`: One scalar recurrence step. +- `BirdDet.Spec.birdDet`: An implementation of Bird's algorithm using `Matrix`. ## Main lemmas @@ -45,15 +49,15 @@ stored in `A` in row-major order. The function does not check the matrix index bounds. -/ -@[expose] protected def get (n : ℕ) (A : Array R) (i j : ℕ) : R := - A.getD (i * n + j) 0 +protected def get (n : ℕ) (A : Array R) (i j : ℕ) : R := + A.getD (n * i + j) 0 /-- Sum `f lo + ... + f (n - 1)`. Returns zero when `n <= lo`. -/ -@[expose] protected def sumFrom (n lo : ℕ) (f : ℕ → R) : R := +protected def sumFrom (n lo : ℕ) (f : ℕ → R) : R := if lo < n then f lo + BirdDet.sumFrom n (lo + 1) f else 0 /-- -# Scalar formula for one recurrence step. +One entry of one scalar Bird recurrence step. Bird's paper defines a matrix recursion for an `n × n` matrix `A`: @@ -83,24 +87,26 @@ F_{t+1} i j = + ∑ k from i+1 to n-1, (F_t i k) * (A k j) ``` -/ -@[expose] protected def iter (n : ℕ) (A : Array R) (t : ℕ) (F : ℕ → ℕ → R) : ℕ → ℕ → R := - match t with - | 0 => F - | t + 1 => fun i j => - -(BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F k k) * BirdDet.get n A i j - + BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F i k * BirdDet.get n A k j +def stepEntry (n : ℕ) (A : Array R) (F : ℕ → ℕ → R) (i j : ℕ) : R := + -(BirdDet.sumFrom n (i + 1) fun k => F k k) * BirdDet.get n A i j + + BirdDet.sumFrom n (i + 1) fun k => F i k * BirdDet.get n A k j /-- `birdDet n A` computes the determinant of the `n × n` matrix whose entries are stored in `A` in row-major order. -/ -@[expose] def birdDet (n : ℕ) (A : Array R) : R := +def birdDet (n : ℕ) (A : Array R) : R := match n with | 0 => 1 - | k + 1 => (-1 : R) ^ k * BirdDet.iter n A k (BirdDet.get n A) 0 0 + | k + 1 => (-1 : R) ^ k * (stepEntry n A)^[k] (BirdDet.get n A) 0 0 /- Unfolding lemmas -/ +/-- Unfold a row-major matrix entry lookup. -/ +theorem get_eq (n : ℕ) (A : Array R) (i j : ℕ) : + BirdDet.get n A i j = A.getD (n * i + j) 0 := by + rfl + theorem sumFrom_step (n lo : ℕ) (f : ℕ → R) (h : lo < n) : BirdDet.sumFrom n lo f = f lo + BirdDet.sumFrom n (lo + 1) f := by rw [BirdDet.sumFrom] @@ -111,21 +117,65 @@ theorem sumFrom_stop (n lo : ℕ) (f : ℕ → R) (h : ¬ lo < n) : rw [BirdDet.sumFrom] simp [h] -theorem iter_zero (n : ℕ) (A : Array R) (F : ℕ → ℕ → R) (i j : ℕ) : - BirdDet.iter n A 0 F i j = F i j := rfl +/-- Induction following the recursive structure of `sumFrom`. -/ +@[elab_as_elim] +theorem sumFrom_induct (n : ℕ) (motive : ℕ → Prop) + (step : ∀ lo, lo < n → motive (lo + 1) → motive lo) + (stop : ∀ lo, ¬lo < n → motive lo) (lo : ℕ) : motive lo := + BirdDet.sumFrom.induct n motive step stop lo + +/-- Unfold one scalar Bird recurrence step to the entry-wise formula. -/ +theorem stepEntry_eq (n : ℕ) (A : Array R) (F : ℕ → ℕ → R) (i j : ℕ) : + stepEntry n A F i j = + -(BirdDet.sumFrom n (i + 1) fun k => F k k) * BirdDet.get n A i j + + BirdDet.sumFrom n (i + 1) fun k => F i k * BirdDet.get n A k j := by + rfl -theorem iter_succ (n : ℕ) (A : Array R) (t : ℕ) (F : ℕ → ℕ → R) (i j : ℕ) : - BirdDet.iter n A (t + 1) F i j = - -(BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F k k) * BirdDet.get n A i j - + BirdDet.sumFrom n (i + 1) fun k => BirdDet.iter n A t F i k * BirdDet.get n A k j := rfl +theorem birdDet_zero (A : Array R) : birdDet 0 A = 1 := by + rfl -theorem birdDet_zero (A : Array R) : birdDet 0 A = 1 := rfl +/-- Unfold `birdDet` at a successor dimension. -/ +theorem birdDet_succ (k : ℕ) (A : Array R) : + birdDet (k + 1) A = + (-1 : R) ^ k * (stepEntry (k + 1) A)^[k] (BirdDet.get (k + 1) A) 0 0 := + by rw [birdDet] theorem birdDet_eq (n k : ℕ) (A : Array R) (hn : n = k + 1) : - birdDet n A = (-1 : R) ^ k * BirdDet.iter n A k (BirdDet.get n A) 0 0 := by + birdDet n A = (-1 : R) ^ k * (stepEntry n A)^[k] (BirdDet.get n A) 0 0 := by subst hn + exact birdDet_succ k A + +namespace Spec + +open scoped BigOperators + +/-- One entry of one Matrix/Fin Bird recurrence step. -/ +def stepEntry {n : ℕ} (A F : Matrix (Fin n) (Fin n) R) : Matrix (Fin n) (Fin n) R := + .of fun i j ↦ (-∑ k ∈ Finset.Ioi i, F k k) * A i j + + ∑ k ∈ Finset.Ioi i, F i k * A k j + +/-- A version of the Bird determinant algorithm that is stated in terms of `Matrix`. -/ +def birdDet {n : ℕ} (A : Matrix (Fin n) (Fin n) R) : R := + match n with + | 0 => 1 + | k + 1 => (-1 : R) ^ k * (stepEntry A)^[k] A 0 0 + +theorem stepEntry_eq {n : ℕ} (A F : Matrix (Fin n) (Fin n) R) : + stepEntry A F = + .of fun i j ↦ (-∑ k ∈ Finset.Ioi i, F k k) * A i j + + ∑ k ∈ Finset.Ioi i, F i k * A k j := by rfl +@[simp] theorem birdDetSpec_zero (A : Matrix (Fin 0) (Fin 0) R) : + birdDet A = 1 := by + rfl + +theorem birdDetSpec_succ {k : ℕ} (A : Matrix (Fin (k + 1)) (Fin (k + 1)) R) : + birdDet A = (-1 : R) ^ k * (stepEntry A)^[k] A 0 0 := by + rw [birdDet] + +end Spec + end BirdDet end diff --git a/Mathlib/Order/Fin/Tuple.lean b/Mathlib/Order/Fin/Tuple.lean index 488e6c08581a3e..dbb9c233a1af61 100644 --- a/Mathlib/Order/Fin/Tuple.lean +++ b/Mathlib/Order/Fin/Tuple.lean @@ -62,7 +62,53 @@ lemma liftFun_vecCons {n : ℕ} (r : α → α → Prop) [IsTrans α r] {f : Fin simp only [liftFun_iff_succ r, forall_iff_succ, cons_val_succ, cons_val_zero, ← succ_castSucc, castSucc_zero] -variable [Preorder α] {n : ℕ} {f : Fin (n + 1) → α} {a : α} +open scoped Relator in +lemma Fin.liftFun_cons {n : ℕ} (r : α → α → Prop) [IsTrans α r] {f : Fin n → α} {a : α} : + ((· < ·) ⇒ r) (cons a f) (cons a f) ↔ (∀ i, r a (f i)) ∧ ((· < ·) ⇒ r) f f := by + match n with + | 0 => simp [Relator.LiftFun] + | n + 1 => + apply (liftFun_vecCons r).trans + simp only [forall_iff_succ, and_congr_left_iff, iff_self_and] + intro h r0 i + exact _root_.trans r0 (h (by grind)) + +variable [Preorder α] {n : ℕ} + +lemma Fin.strictMono_insertNth_iff (q : Fin (n + 1)) (x : α) (f : Fin n → α) : + StrictMono (q.insertNth x f) ↔ + StrictMono f ∧ (∀ i, i.castSucc < q → f i < x) ∧ (∀ i, q ≤ i.castSucc → x < f i) := by + refine ⟨fun h ↦ ⟨fun a b hab ↦ ?_, ⟨fun i hlt ↦ ?_, fun i hlt ↦ ?_⟩⟩, ?_⟩ + · simpa [hab] using h (a := q.succAbove a) (b := q.succAbove b) + · have : q.succAbove i < q := by simp [succAbove_of_castSucc_lt, hlt] + simpa using h this + · have : q < q.succAbove i := by simp [succAbove_of_le_castSucc, hlt, ← le_castSucc_iff] + simpa using h this + · rintro ⟨h, hlt, hgt⟩ a b hab + cases a using succAboveCases q <;> cases b using succAboveCases q + · simp at hab + · rename_i j + have : q ≤ j.castSucc := by simpa [lt_succAbove_iff_le_castSucc] using hab + simpa using hgt _ this + · rename_i j + have : j.castSucc < q := by simpa [succAbove_lt_iff_castSucc_lt] using hab + simpa using hlt _ this + · simpa using h <| (strictMono_succAbove _).lt_iff_lt.mp hab + +lemma Fin.strictMono_cons {f : Fin n → α} {a : α} : + StrictMono (Fin.cons a f) ↔ (∀ j, a < f j) ∧ StrictMono f := + liftFun_cons (· < ·) + +@[simp] lemma Fin.strictMono_cons_zero_succ {f : Fin n → Fin (n + 1)} : + StrictMono (Fin.cons 0 f) ↔ f = Fin.succ := by + refine ⟨fun h ↦ funext fun i ↦ ?_, fun h ↦ by simp [h, strictMono_id]⟩ + have key (g : Fin (n + 1) → Fin (n + 1)) (hg : StrictMono g) : g = id := by + -- Import restrictions prevent us using `StrictMono.eq_id`: hence this manual proof. + refine funext fun x ↦ le_antisymm ?_ (hg.id_le x) + simpa using ((Fin.rev_strictAnti.comp_strictMono hg).comp Fin.rev_strictAnti).id_le (Fin.rev x) + simpa using congrFun (key _ h) i.succ + +variable {f : Fin (n + 1) → α} {a : α} @[simp] lemma strictMono_vecCons : StrictMono (vecCons a f) ↔ a < f 0 ∧ StrictMono f := liftFun_vecCons (· < ·) @@ -92,6 +138,9 @@ lemma monotone_vecCons : Monotone (vecCons a f) ↔ a ≤ f 0 ∧ Monotone f := lemma StrictMono.vecCons (hf : StrictMono f) (ha : a < f 0) : StrictMono (vecCons a f) := strictMono_vecCons.2 ⟨ha, hf⟩ +lemma StrictMono.removeNth (hf : StrictMono f) (i : Fin (n + 1)) : StrictMono (i.removeNth f) := + hf.comp (Fin.strictMono_succAbove i) + lemma StrictAnti.vecCons (hf : StrictAnti f) (ha : f 0 < a) : StrictAnti (vecCons a f) := strictAnti_vecCons.2 ⟨ha, hf⟩ diff --git a/Mathlib/Tactic/Determinant/Bird/Cert.lean b/Mathlib/Tactic/Determinant/Bird/Cert.lean index 8d3e14344d2e52..4be7b7d4ab6fd0 100644 --- a/Mathlib/Tactic/Determinant/Bird/Cert.lean +++ b/Mathlib/Tactic/Determinant/Bird/Cert.lean @@ -12,7 +12,7 @@ public meta import Mathlib.Tactic.Ring # Certificate-chain evaluator for `BirdDet.birdDet` -This file contains an evaulator that computes the ring tactic normal form of +This file contains an evaluator that computes the ring tactic normal form of `Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs.birdDet` via iteratively unfolding its definition, using the ring tactic for ring operations, and caching intermediate certificates. @@ -31,23 +31,24 @@ certBirdDet (birdDet n A) = ring normal form of 1 -- via certEval n = k + 1: birdDet n A - = (-1)^k * iter n A k (get n A) 0 0 -- via BirdDet.birdDet_eq - = ring normal form of the product -- certMul (certBirdSign k) (certIter k 0 0) + = (-1)^k * (stepEntry n A)^[k] (get n A) 0 0 -- via BirdDet.birdDet_eq + = ring normal form of the product -- certMul (certBirdSign k) (certIterStepEntry k 0 0) ``` -The `iter n A k (get n A) i j` function branches on k, (k=0, k=t+1) and -therefore the `certIter` function has two branches: +The `(stepEntry n A)^[k] (get n A) i j` expression branches on `k`, so +`certIterStepEntry` has two branches: ``` -certIter k i j +certIterStepEntry k i j k = 0: - iter n A 0 F i j = F i j -- via BirdDet.iter_zero - = ring normal form of A[i][j] -- via certEntry i j + (stepEntry n A)^[0] F i j + = F i j -- via Function.iterate_zero_apply + = ring normal form of A[i][j] -- via certEntry i j k = t + 1: - iter n A (t + 1) F i j - = -(sumFrom n (i + 1) fun k => iter n A t F k k) * get n A i j - + sumFrom n (i + 1) fun k => iter n A t F i k * get n A k j - -- via BirdDet.iter_succ + (stepEntry n A)^[t + 1] F i j + = -(sumFrom n (i + 1) fun k => (stepEntry n A)^[t] F k k) * get n A i j + + sumFrom n (i + 1) fun k => (stepEntry n A)^[t] F i k * get n A k j + -- via Function.iterate_succ_apply' = normal form of the first summand + normal form of the second summand -- via certAdd (certMul (certNeg (certDiag t (i + 1))) (certEntry i j)) @@ -57,15 +58,16 @@ certIter k i j Then the `certDiag` and `certTail` functions certify the two kinds of `sumFrom` expressions. -The evaulator also memoizes the `certIter`, `certDiag` and `certEntry` functions -to improve performance. +The evaluator also memoizes `certIterStepEntry`, `certDiag` and `certEntry` to +improve performance. ## Main definitions - `certEntry` certifies `BirdDet.get`. -- `certSumFromStop` and `certSumFromStep` certifies `BirdDet.sumFrom_stop` and +- `certSumFromStop` and `certSumFromStep` certify `BirdDet.sumFrom_stop` and `BirdDet.sumFrom_step`. -- `certIter` certifies `BirdDet.iter_zero` and `BirdDet.iter_succ`. +- `certIterStepEntry` certifies entries of + `(BirdDet.stepEntry n A)^[t] (BirdDet.get n A)`. - `certBirdDet` certifies `BirdDet.birdDet_zero` and `BirdDet.birdDet_eq`. -/ @@ -90,11 +92,11 @@ abbrev CertResult {u : Level} {α : Q(Type u)} namespace Ctx -/-- Return an expression for the partially applied function `iter n A t (get n A)` -/ -def iterP (ctx : Ctx rα) (t : ℕ) : Q(ℕ → ℕ → $α) := +/-- Return the expression `(stepEntry n A)^[t] (get n A)`. -/ +def iterStepEntry (ctx : Ctx rα) (t : ℕ) : Q(ℕ → ℕ → $α) := let dim : Q(ℕ) := ctx.dimensionLit let A : Q(Array $α) := ctx.arrayExpr - q(BirdDet.iter $dim $A $t (BirdDet.get $dim $A)) + q((BirdDet.stepEntry $dim $A)^[$t] (BirdDet.get $dim $A)) /-- Return an expression `sumFrom n lo f` -/ def sumFrom (ctx : Ctx rα) (lo : ℕ) (f : Q(ℕ → $α)) : Q($α) := @@ -151,8 +153,8 @@ end Cert structure CertCache {u : Level} {α : Q(Type u)} (rα : Q(CommRing $α)) where /-- Cache for entry certificates, keyed by matrix indices. -/ entryCache : Std.HashMap (ℕ × ℕ) (Cert rα) := {} - /-- Cache for `iter` certificates, keyed by recursion index and matrix indices. -/ - iterCache : Std.HashMap (ℕ × ℕ × ℕ) (Cert rα) := {} + /-- Cache for iterated `stepEntry` certificates, keyed by step and matrix indices. -/ + iterStepEntryCache : Std.HashMap (ℕ × ℕ × ℕ) (Cert rα) := {} /-- Cache for diagonal-tail certificates, keyed by recursion index and lower bound. -/ diagCache : Std.HashMap (ℕ × ℕ) (Cert rα) := {} @@ -230,7 +232,7 @@ def certEntry (i j : ℕ) : CertM rα (Cert rα) := do let {dimension := dim, dimensionLit := dimLit, arrayExpr := A, arrayEntries, ..} := ctx let lhs : Q($α) := q(BirdDet.get $dimLit $A $i $j) -- The index of the matrix entry (i, j) in arrayEntries - let idx := i * dim + j + let idx := dim * i + j let entry := arrayEntries.getD idx q(0) let ce ← certEval entry have : $lhs =Q $entry := ⟨⟩ @@ -280,23 +282,25 @@ def certSumFromStep mutual -/-- Certify a `BirdDet.iter` call. -/ -partial def certIter (t i j : ℕ) : CertM rα (Cert rα) := do - if let some c := (← get).iterCache[(t, i, j)]? then +/-- Certify an entry of `(BirdDet.stepEntry n A)^[t] (BirdDet.get n A)`. -/ +partial def certIterStepEntry (t i j : ℕ) : CertM rα (Cert rα) := do + if let some c := (← get).iterStepEntryCache[(t, i, j)]? then return c let ctx ← read let {dimensionLit := dimLit, arrayExpr := A, ..} := ctx let cert ← match t with - -- The t=0 branch of `BirdDet.iter`, unfold using `BirdDet.iter_zero` + -- The `t = 0` branch of `Function.iterate`. | 0 => do let ce ← certEntry i j - let h := q(BirdDet.iter_zero $dimLit $A (BirdDet.get $dimLit $A) $i $j) + let hIter := q(Function.iterate_zero_apply + (BirdDet.stepEntry $dimLit $A) (BirdDet.get $dimLit $A)) + let h := q(congrArg (fun F : ℕ → ℕ → $α => F $i $j) $hIter) pure (ce.chainProof h) - -- The t=t+1 branch of `BirdDet.iter`, unfold using `BirdDet.iter_succ` + -- The `t = t' + 1` branch of `Function.iterate`. | t' + 1 => do - -- First summand in `BirdDet.iter_succ`: + -- First summand in one `BirdDet.stepEntry` application: -- -(sumFrom n (i + 1) fun k => F_t k k) * get n A i j - let diagSummand := q(fun k => $(ctx.iterP t') k k) + let diagSummand := q(fun k => $(ctx.iterStepEntry t') k k) let negDiagSum := q(-$(ctx.sumFrom (i + 1) diagSummand)) let entryCert ← certEntry i j let diagProdCert ← @@ -308,31 +312,34 @@ partial def certIter (t i j : ℕ) : CertM rα (Cert rα) := do let diagSumCert ← certDiag t' (i + 1) let negDiagSumCert ← certNeg diagSumCert certMul negDiagSumCert entryCert - -- Second summand in `BirdDet.iter_succ`: + -- Second summand in one `BirdDet.stepEntry` application: -- sumFrom n (i + 1) fun k => F_t i k * get n A k j let tailSumCert ← certTail t' i j (i + 1) let rhsCert ← certAdd diagProdCert tailSumCert - let h := q(BirdDet.iter_succ $dimLit $A $t' (BirdDet.get $dimLit $A) $i $j) + let hIter := q(Function.iterate_succ_apply' + (BirdDet.stepEntry $dimLit $A) $t' (BirdDet.get $dimLit $A)) + let h := q(congrArg (fun F : ℕ → ℕ → $α ↦ F $i $j) $hIter) pure (rhsCert.chainProof h) - modify fun s => {s with iterCache := s.iterCache.insert (t, i, j) cert} + modify fun s => + {s with iterStepEntryCache := s.iterStepEntryCache.insert (t, i, j) cert} return cert -/-- Certify the diagonal tail sum from `BirdDet.iter_succ`: +/-- Certify the diagonal tail sum in one `BirdDet.stepEntry` application: ``` -sumFrom n (i + 1) fun k => iter n A t F k k) +sumFrom n (i + 1) fun k => (stepEntry n A)^[t] F k k) ``` -/ partial def certDiag (t lo : ℕ) : CertM rα (Cert rα) := do if let some c := (← get).diagCache[(t, lo)]? then return c let ctx ← read - let diagonalSummand := q(fun k => $(ctx.iterP t) k k) + let diagonalSummand := q(fun k => $(ctx.iterStepEntry t) k k) let cert ← if lo < ctx.dimension then do - let headCert := certIter t lo lo + let headCert := certIterStepEntry t lo lo let tailCert := certDiag t (lo + 1) certSumFromStep lo @@ -344,10 +351,10 @@ partial def certDiag (t lo : ℕ) : CertM rα (Cert rα) := do modify fun s => {s with diagCache := s.diagCache.insert (t, lo) cert} return cert -/-- Certify the upper-tail sum from `BirdDet.iter_succ`: +/-- Certify the upper-tail sum in one `BirdDet.stepEntry` application: ``` -sumFrom n (i + 1) fun k => iter n A t F i k * get n A k j +sumFrom n (i + 1) fun k => (stepEntry n A)^[t] F i k * get n A k j ``` -/ partial def certTail (t i j lo : ℕ) : CertM rα (Cert rα) := do @@ -355,23 +362,23 @@ partial def certTail (t i j lo : ℕ) : CertM rα (Cert rα) := do let {dimensionLit := dimLit, arrayExpr := A, ..} := ctx let tailSummand := q(fun k => - $(ctx.iterP t) $i k * + $(ctx.iterStepEntry t) $i k * BirdDet.get $dimLit $A k $j) if lo < ctx.dimension then do - -- headCert certifies `iter n A t F i lo * get n A lo j` + -- headCert certifies `(stepEntry n A)^[t] F i lo * get n A lo j` let headCert := do let entryCert ← certEntry lo j -- If `get n A lo j = 0` then we can skip computation of - -- `iter n A t F i lo` + -- `(stepEntry n A)^[t] F i lo` if entryCert.isZero then zeroProdCert - q($(ctx.iterP t) $i $lo) + q($(ctx.iterStepEntry t) $i $lo) entryCert else do - let iterCert ← certIter t i lo - certMul iterCert entryCert + let iterateCert ← certIterStepEntry t i lo + certMul iterateCert entryCert let tailCert := certTail t i j (lo + 1) certSumFromStep lo @@ -399,7 +406,7 @@ def certBirdDet : CertM rα (Cert rα) := do -- so we set k := `ctx.dimension - 1`. let k := dim - 1 let cs ← certBirdSign k - let ci ← certIter k 0 0 + let ci ← certIterStepEntry k 0 0 let cm ← certMul cs ci have kLit := mkNatLitQ k have : $dimLit =Q $kLit + 1 := ⟨⟩ diff --git a/docs/references.bib b/docs/references.bib index 5a22b39d8fdf62..c72b34d1b8d66a 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -480,6 +480,18 @@ @Book{ billingsley1999 url = {https://doi.org/10.1002/9780470316962} } +@Article{ bird2011, + author = {Bird, Richard S.}, + title = {A simple division-free algorithm for computing + determinants}, + journal = {Information Processing Letters}, + volume = {111}, + pages = {1072--1074}, + year = {2011}, + doi = {10.1016/j.ipl.2011.08.006}, + url = {https://doi.org/10.1016/j.ipl.2011.08.006} +} + @Book{ birdwadler, author = {Richard Bird and Philip Wadler}, year = {1988}, From 8c79cb4f540eeb519b1a2187009a1916521fd168 Mon Sep 17 00:00:00 2001 From: rshlyakh <157648681+rshlyakh@users.noreply.github.com> Date: Sun, 19 Jul 2026 04:22:38 +0000 Subject: [PATCH 0884/1300] feat(RingTheory/Ideal): add Algebra.HasGoingUp (#40911) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This closely mirrors `Mathlib/RingTheory/Ideal/GoingDown.lean` by defining an analogous predicate `Algebra.HasGoingUp` and proving basic properties. It includes: - `Algebra.HasGoingUp.iff_specializingMap_primeSpectrumComap`: going up is equivalent to specializations lifting along `Spec S → Spec R`. - `Algebra.HasGoingUp.of_isIntegral`: integral algebras satisfy going up. - `Ideal.exists_ltSeries_of_hasGoingUp`: a generalization of `exists_ideal_over_prime_of_isIntegral_of_isPrime` from `Mathlib/RingTheory/Ideal/GoingUp.lean` to chains of arbitrary length. This was previously an explicitly marked `TODO`. --- Mathlib.lean | 1 + Mathlib/RingTheory/Ideal/GoingUp.lean | 3 +- Mathlib/RingTheory/Ideal/HasGoingUp.lean | 133 +++++++++++++++++++++++ 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 Mathlib/RingTheory/Ideal/HasGoingUp.lean diff --git a/Mathlib.lean b/Mathlib.lean index 06874d1c0aa5ec..ce7026455fc354 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6667,6 +6667,7 @@ public import Mathlib.RingTheory.Ideal.Defs public import Mathlib.RingTheory.Ideal.Finsupp public import Mathlib.RingTheory.Ideal.GoingDown public import Mathlib.RingTheory.Ideal.GoingUp +public import Mathlib.RingTheory.Ideal.HasGoingUp public import Mathlib.RingTheory.Ideal.Height public import Mathlib.RingTheory.Ideal.IdempotentFG public import Mathlib.RingTheory.Ideal.Int diff --git a/Mathlib/RingTheory/Ideal/GoingUp.lean b/Mathlib/RingTheory/Ideal/GoingUp.lean index 9fde57b65168e9..bc28dc66b4cad4 100644 --- a/Mathlib/RingTheory/Ideal/GoingUp.lean +++ b/Mathlib/RingTheory/Ideal/GoingUp.lean @@ -303,8 +303,7 @@ theorem exists_ideal_over_prime_of_isIntegral_of_isDomain [Algebra.IsIntegral R end /-- More general going-up theorem than `exists_ideal_over_prime_of_isIntegral_of_isDomain`. -TODO: Version of going-up theorem with arbitrary length chains (by induction on this)? - Not sure how best to write an ascending chain in Lean -/ +Generalized to arbitrary length chains in `Ideal.exists_ltSeries_of_hasGoingUp`. -/ theorem exists_ideal_over_prime_of_isIntegral_of_isPrime [Algebra.IsIntegral R S] (P : Ideal R) [IsPrime P] (I : Ideal S) [IsPrime I] (hIP : I.comap (algebraMap R S) ≤ P) : diff --git a/Mathlib/RingTheory/Ideal/HasGoingUp.lean b/Mathlib/RingTheory/Ideal/HasGoingUp.lean new file mode 100644 index 00000000000000..6d1ffb5e88bea3 --- /dev/null +++ b/Mathlib/RingTheory/Ideal/HasGoingUp.lean @@ -0,0 +1,133 @@ +/- +Copyright (c) 2026 Robert Shlyakhtenko. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Robert Shlyakhtenko +-/ + +module + +public import Mathlib.RingTheory.Spectrum.Prime.Topology + +/-! +# Going up + +In this file we define a predicate `Algebra.HasGoingUp`: An `R`-algebra `S` satisfies +`Algebra.HasGoingUp R S` if for every pair of prime ideals `p ≤ q` of `R` with +`P` a prime of `S` lying above `p`, there exists a prime `P ≤ Q` of `S` lying above `q`. + +This file closely mirrors `Mathlib.RingTheory.Ideal.GoingDown`. + +## Main results + +- `Algebra.HasGoingUp.iff_specializingMap_primeSpectrumComap`: going up is equivalent + to specializations lifting along `Spec S → Spec R`. +- `Algebra.HasGoingUp.of_isIntegral`: integral algebras satisfy going up. +-/ + +@[expose] public section + +/-- +An `R`-algebra `S` satisfies `Algebra.HasGoingUp R S` if for every pair of +prime ideals `p ≤ q` of `R` with `P` a prime of `S` lying above `p`, there exists a +prime `P ≤ Q` of `S` lying above `q`. + +The condition only asks for `<` which is easier to prove, use +`Ideal.exists_ideal_ge_liesOver_of_le` for applying it. -/ +@[stacks 00HV "(1)"] +class Algebra.HasGoingUp + (R S : Type*) [CommRing R] [CommRing S] [Algebra R S] : Prop where + exists_ideal_ge_liesOver_of_lt {q : Ideal R} [q.IsPrime] (P : Ideal S) [P.IsPrime] : + P.under R < q → ∃ Q, P ≤ Q ∧ Q.IsPrime ∧ Q.LiesOver q + +variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] + +namespace Ideal + +lemma exists_ideal_ge_liesOver_of_le [Algebra.HasGoingUp R S] + {p q : Ideal R} [q.IsPrime] (P : Ideal S) [P.IsPrime] [P.LiesOver p] + (hle : p ≤ q) : + ∃ Q, P ≤ Q ∧ Q.IsPrime ∧ Q.LiesOver q := by + rcases eq_or_ne p q with rfl | h + · use P + · rw [P.over_def p] at hle h + exact Algebra.HasGoingUp.exists_ideal_ge_liesOver_of_lt P (lt_of_le_of_ne hle h) + +lemma exists_ideal_gt_liesOver_of_lt [Algebra.HasGoingUp R S] + {p q : Ideal R} [q.IsPrime] (P : Ideal S) [P.IsPrime] [P.LiesOver p] + (hpq : p < q) : + ∃ Q, P < Q ∧ Q.IsPrime ∧ Q.LiesOver q := by + obtain ⟨Q, hPQ, hQ, hQq⟩ := P.exists_ideal_ge_liesOver_of_le (p := p) (q := q) hpq.le + refine ⟨Q, lt_of_le_of_ne hPQ fun h ↦ ?_, hQ, hQq⟩ + subst Q + simp [P.over_def p, P.over_def q] at hpq + +/-- This generalizes `exists_ideal_over_prime_of_isIntegral_of_isPrime` +to arbitrary length chains. -/ +lemma exists_ltSeries_of_hasGoingUp [Algebra.HasGoingUp R S] + (l : LTSeries (PrimeSpectrum R)) + (P : Ideal S) [P.IsPrime] + [lo : P.LiesOver (RelSeries.head l).asIdeal] : + ∃ L : LTSeries (PrimeSpectrum S), + L.length = l.length ∧ + L.head = (⟨P, inferInstance⟩ : PrimeSpectrum S) ∧ + List.map (PrimeSpectrum.comap (algebraMap R S)) (L.toList) = l.toList := by + induction l using RelSeries.inductionOn generalizing P with + | singleton q => + refine ⟨RelSeries.singleton _ ⟨P, inferInstance⟩, rfl, rfl, ?_⟩ + simpa [PrimeSpectrum.ext_iff] using lo.over.symm + | cons l q lt ih => + simp only [RelSeries.head_cons] at lo + obtain ⟨Q, PQlt, hQ, Qlo⟩ := + Ideal.exists_ideal_gt_liesOver_of_lt P lt + obtain ⟨L, len, head, spec⟩ := ih Q + refine ⟨L.cons ⟨P, inferInstance⟩ (by + simp_all only [Set.mem_ofPred_eq] + exact PQlt), by simpa using len, rfl, ?_⟩ + simpa [spec, PrimeSpectrum.ext_iff] using lo.over.symm + +end Ideal + +namespace Algebra.HasGoingUp + +variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] + +/-- An `R`-algebra `S` has the going up property if and only if specializations lift +along `Spec S → Spec R`. -/ +@[stacks 00HW "(2)"] +lemma iff_specializingMap_primeSpectrumComap : + Algebra.HasGoingUp R S ↔ + SpecializingMap (PrimeSpectrum.comap (algebraMap R S)) := by + refine ⟨?_, fun h ↦ ⟨fun {q} hq P hP hlt ↦ ?_⟩⟩ + · intro h P q hq + simp only [flip] at hq + rw [← PrimeSpectrum.le_iff_specializes] at hq + obtain ⟨Q, hle, hQ, h⟩ := P.asIdeal.exists_ideal_ge_liesOver_of_le (q := q.asIdeal) + (p := P.asIdeal.under R) hq + refine ⟨⟨Q, hQ⟩, (PrimeSpectrum.le_iff_specializes P _).mp hle, ?_⟩ + ext : 1 + exact h.over.symm + · have : PrimeSpectrum.comap (algebraMap R S) ⟨P, hP⟩ ⤳ (⟨q, hq⟩ : PrimeSpectrum R) := + (PrimeSpectrum.le_iff_specializes _ _).mp hlt.le + obtain ⟨Q, hs, heq⟩ := h this + refine ⟨Q.asIdeal, (PrimeSpectrum.le_iff_specializes _ _).mpr hs, Q.2, ⟨?_⟩⟩ + simpa [PrimeSpectrum.ext_iff] using heq.symm + +variable (R S) in +@[stacks 00HX] +lemma trans (T : Type*) [CommRing T] [Algebra R T] [Algebra S T] [IsScalarTower R S T] + [Algebra.HasGoingUp R S] [Algebra.HasGoingUp S T] : + Algebra.HasGoingUp R T := by + rw [iff_specializingMap_primeSpectrumComap, IsScalarTower.algebraMap_eq R S T] + simp only [PrimeSpectrum.comap_comp] + apply SpecializingMap.comp + · rwa [← iff_specializingMap_primeSpectrumComap] + · rwa [← iff_specializingMap_primeSpectrumComap] + +/-- Integral algebras satisfy the going up property. -/ +@[stacks 00GU] +instance of_isIntegral [Algebra.IsIntegral R S] : Algebra.HasGoingUp R S where + exists_ideal_ge_liesOver_of_lt {q} _ P _ hPq := + let ⟨Q, hPQ, hQ, hQq⟩ := Ideal.exists_ideal_over_prime_of_isIntegral_of_isPrime q P hPq.le + ⟨Q, hPQ, hQ, ⟨hQq.symm⟩⟩ + +end Algebra.HasGoingUp From d0f60b50073983b3f2ab5b5ba68632cb7e9c0a54 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sun, 19 Jul 2026 19:15:41 +0000 Subject: [PATCH 0885/1300] feat: sections of a fiber bundle with `Subsingleton` fiber are smooth and differentiable (#41027) This will be used to prove that the Levi-Civita connection is smooth. From the path towards the Levi-Civita connection and Riemannian geometry. --- .../Geometry/Manifold/VectorBundle/Basic.lean | 31 +++++++++++++++++++ .../VectorBundle/MDifferentiable.lean | 24 ++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 5c09cb521e7377..a85626f4793e70 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -230,6 +230,8 @@ theorem contMDiffWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace F E} : ContMDiffWithinAt (IB.prod 𝓘(𝕜, F)) IB n (π F E) s p := (contMDiffAt_proj E).contMDiffWithinAt +section + variable (𝕜) [∀ x, AddCommMonoid (E x)] variable [∀ x, Module 𝕜 (E x)] [VectorBundle 𝕜 F E] @@ -253,6 +255,35 @@ theorem contMDiffWithinAt_zeroSection {t : Set B} {x : B} : ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (zeroSection F E) t x := (contMDiff_zeroSection _ _ x).contMDiffWithinAt +end + +variable {s : ∀ x, E x} {u : Set B} {x : B} + +@[nontriviality] +lemma contMDiffWithinAt_section_of_subsingleton [Subsingleton F] : + ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x := by + rw [contMDiffWithinAt_section] + apply contMDiffWithinAt_const |>.congr + · intro y _ + apply Subsingleton.elim + rfl + +@[nontriviality] +lemma contMDiffAt_section_of_subsingleton [Subsingleton F] : + ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x := by + rw [← contMDiffWithinAt_univ] + apply contMDiffWithinAt_section_of_subsingleton + +@[nontriviality] +lemma contMDiffOn_section_of_subsingleton [Subsingleton F] : + ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u := + fun _x _hx ↦ contMDiffWithinAt_section_of_subsingleton .. + +@[nontriviality] +lemma contMDiff_section_of_subsingleton [Subsingleton F] : + ContMDiff IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) := + fun _x ↦ contMDiffAt_section_of_subsingleton .. + end Bundle end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 3b7d06384948c8..ed056ceab00c41 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -99,6 +99,8 @@ theorem mdifferentiableWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace MDiffAt[s] (π F E) p := (mdifferentiableAt_proj E).mdifferentiableWithinAt +section + variable (𝕜) [∀ x, AddCommMonoid (E x)] variable [∀ x, Module 𝕜 (E x)] [VectorBundle 𝕜 F E] @@ -121,6 +123,28 @@ theorem mdifferentiableWithinAt_zeroSection {t : Set B} {x : B} : MDiffAt[t] (zeroSection F E) x := (mdifferentiable_zeroSection _ _ x).mdifferentiableWithinAt +end + +variable {s : ∀ x, E x} {u : Set B} {x : B} + +@[nontriviality] +lemma mdifferentiableWithinAt_section_of_subsingleton [Subsingleton F] : + MDiffAt[u] (T% s) x := + (contMDiffWithinAt_section_of_subsingleton _).mdifferentiableWithinAt one_ne_zero + +@[nontriviality] +lemma mdifferentiableAt_section_of_subsingleton [Subsingleton F] : MDiffAt (T% s) x := by + rw [← mdifferentiableWithinAt_univ] + apply mdifferentiableWithinAt_section_of_subsingleton + +@[nontriviality] +lemma mdifferentiableOn_section_of_subsingleton [Subsingleton F] : MDiff[u] (T% s) := + fun _x _hx ↦ mdifferentiableWithinAt_section_of_subsingleton .. + +@[nontriviality] +lemma mdifferentiable_section_of_subsingleton [Subsingleton F] : MDiff (T% s) := + fun _x ↦ mdifferentiableAt_section_of_subsingleton .. + end Bundle section coordChange From d0060d7bbba57d53450b2ebe84d015f5e926793a Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Sun, 19 Jul 2026 20:11:12 +0000 Subject: [PATCH 0886/1300] feat(Data/Finset/Card): iterating a function's image on a finite set stabilises (#38488) ...and does so in a bounded number of steps (which is why this is Finset-specific). In a later PR, I'll add this for endofunctions on a fintype, as well as add a Set.Finite version. --- Mathlib/Data/Finset/Card.lean | 34 ++++++++++++++++++++++++++++++++++ Mathlib/Data/Finset/Image.lean | 1 + 2 files changed, 35 insertions(+) diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 36844cf000c3f0..7018b37de1f282 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -932,4 +932,38 @@ theorem eraseInduction [DecidableEq α] {p : Finset α → Prop} (H : (S : Finset α) → (∀ s ∈ S, p (S.erase s)) → p S) (S : Finset α) : p S := S.strongInduction fun S ih => H S fun _ hs => ih _ (erase_ssubset hs) +/-- +Given a function `f` which sends the finite set `s` to itself, the sequence of images of `s` under +iterates of `f` is eventually constant. Furthermore, the sequence of images stabilises in fewer +than `#s` steps. +-/ +theorem image_iterate_stabilises_lt_card [DecidableEq α] {f : α → α} {s : Finset α} + (hs : Set.MapsTo f s s) (hs₀ : s.Nonempty) : + ∃ n < #s, ∀ m, n ≤ m → s.image f^[m] = s.image f^[n] := by + let g (i : ℕ) : Finset α := s.image f^[i] + have (i : ℕ) : 0 < #(g i) := (hs₀.image _).card_pos + have hg : Antitone g := antitone_nat_of_succ_le <| fun i ↦ by + simp_rw [g, Function.iterate_succ, ← image_image] + grw [hs.finsetImage_subset] + have eq_iff (i j : ℕ) : #(g i) - 1 = #(g j) - 1 ↔ g i = g j := by + wlog hij : j ≤ i generalizing i j + · grind + exact ⟨fun h ↦ eq_of_subset_of_card_le (hg hij) (by grind), by grind⟩ + have hG : Antitone (fun i ↦ #(g i) - 1) := fun i j h ↦ by dsimp; gcongr #?_ - 1; exact hg h + rcases Nat.stabilises_of_antitone hG (by grind [=_ image_image, iterate_succ']) with ⟨n, hn, hn'⟩ + exact ⟨n, by grind⟩ + +/-- +Given a function `f` which sends the finite set `s` to itself, the sequence of images of `s` under +iterates of `f` is eventually constant. Furthermore, the sequence of images stabilises in at most +`#s` steps. +-/ +theorem image_iterate_stabilises_le_card [DecidableEq α] {f : α → α} {s : Finset α} + (hs : Set.MapsTo f s s) : + ∃ n ≤ #s, ∀ m, n ≤ m → s.image f^[m] = s.image f^[n] := by + obtain rfl | hs₀ := s.eq_empty_or_nonempty + · simp + obtain ⟨n, hn', hn⟩ := image_iterate_stabilises_lt_card hs hs₀ + exact ⟨n, hn'.le, hn⟩ + end Finset diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index 9d301d68c9e232..1d13014ff47769 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -403,6 +403,7 @@ theorem _root_.Function.Commute.finset_image [DecidableEq α] {f g : α → α} (h : Function.Commute f g) : Function.Commute (image f) (image g) := Function.Semiconj.finset_image h +@[gcongr] theorem image_subset_image {s₁ s₂ : Finset α} (h : s₁ ⊆ s₂) : s₁.image f ⊆ s₂.image f := by simp only [subset_def, image_val, subset_dedup', dedup_subset', Multiset.map_subset_map h] From 169c26b52a38b704fad2c009372d76844a059bdf Mon Sep 17 00:00:00 2001 From: David Kurniadi Angdinata Date: Mon, 20 Jul 2026 01:34:02 +0000 Subject: [PATCH 0887/1300] refactor: rename restrict to domRestrict (#25980) Update the documentation for consistency, and to contrast with `codRestrict` which is prevalent. --- Archive/Sensitivity.lean | 4 +- Mathlib/Algebra/Group/Subgroup/Basic.lean | 6 +- Mathlib/Algebra/Group/Subgroup/Ker.lean | 14 +- .../Algebra/Group/Submonoid/Operations.lean | 159 +++++++++++------- .../Group/Subsemigroup/Operations.lean | 15 +- .../Algebra/Module/Submodule/LinearMap.lean | 2 +- Mathlib/Algebra/Ring/Subsemiring/Defs.lean | 4 +- .../ContinuousFunctionalCalculus/Commute.lean | 4 +- .../Continuity.lean | 21 +-- .../Integral.lean | 32 ++-- .../NonUnital.lean | 26 +-- .../ContinuousFunctionalCalculus/Range.lean | 4 +- .../ContinuousFunctionalCalculus/Unique.lean | 2 +- .../ContinuousFunctionalCalculus/Unital.lean | 24 +-- .../ApproximatesLinearOn.lean | 18 +- Mathlib/Analysis/Complex/BranchLogRoot.lean | 8 +- Mathlib/Analysis/Complex/Tietze.lean | 9 +- Mathlib/Analysis/Convex/Approximation.lean | 51 +++--- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 9 +- .../Matrix/HermitianFunctionalCalculus.lean | 4 +- Mathlib/Analysis/Meromorphic/Basic.lean | 2 +- .../Module/MultipliableUniformlyOn.lean | 2 +- .../Operator/Perturbation/StrictByFinite.lean | 2 +- .../Analysis/SpecialFunctions/Log/Basic.lean | 8 +- .../Trigonometric/Arctan.lean | 2 +- .../Trigonometric/Complex.lean | 2 +- Mathlib/Combinatorics/Matroid/Map.lean | 2 +- Mathlib/Data/Finset/Pi.lean | 17 +- Mathlib/Data/Fintype/Inv.lean | 4 +- Mathlib/Data/Set/Finite/Basic.lean | 2 +- Mathlib/Data/Set/Functor.lean | 11 +- Mathlib/Data/Set/Monotone.lean | 18 +- Mathlib/Data/Set/Restrict.lean | 144 +++++++++------- .../Dynamics/TopologicalEntropy/Semiconj.lean | 12 +- Mathlib/FieldTheory/CardinalEmb.lean | 2 +- Mathlib/FieldTheory/Extension.lean | 8 +- Mathlib/FieldTheory/IsAlgClosed/Basic.lean | 7 +- Mathlib/FieldTheory/IsSepClosed.lean | 7 +- .../FieldTheory/PurelyInseparable/Basic.lean | 4 +- Mathlib/GroupTheory/Complement.lean | 8 +- .../GroupTheory/FiniteAbelian/Duality.lean | 29 ++-- Mathlib/GroupTheory/Focal.lean | 6 +- .../GroupTheory/MonoidLocalization/Basic.lean | 26 +-- .../GroupTheory/MonoidLocalization/Maps.lean | 13 +- .../MonoidLocalization/MonoidWithZero.lean | 2 +- Mathlib/GroupTheory/PGroup.lean | 2 +- Mathlib/GroupTheory/QuotientGroup/Basic.lean | 27 ++- Mathlib/GroupTheory/Transfer.lean | 14 +- Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 2 +- .../Finsupp/LinearCombination.lean | 2 +- .../LinearAlgebra/LinearIndependent/Defs.lean | 6 +- .../RootSystem/Finite/Nondegenerate.lean | 2 +- .../LinearAlgebra/RootSystem/WeylGroup.lean | 32 ++-- Mathlib/Logic/Function/DependsOn.lean | 12 +- .../Constructions/BorelSpace/Basic.lean | 4 +- .../Constructions/Cylinders.lean | 10 +- .../Constructions/Polish/Basic.lean | 10 +- .../Polish/StronglyMeasurable.lean | 2 +- .../ConditionalExpectation/CondJensen.lean | 2 +- Mathlib/MeasureTheory/Function/Jacobian.lean | 16 +- .../Function/SpecialFunctions/Basic.lean | 2 +- .../Function/StronglyMeasurable/Basic.lean | 4 +- .../MeasureTheory/Integral/CircleAverage.lean | 2 +- .../MeasureTheory/Integral/IntegrableOn.lean | 2 +- .../Integral/IntervalIntegral/Periodic.lean | 6 +- .../MeasurableSpace/Constructions.lean | 16 +- .../MeasurableSpace/Embedding.lean | 4 +- .../MeasureTheory/Measure/AEMeasurable.lean | 10 +- .../MeasureTheory/Measure/FiniteMeasure.lean | 8 +- .../Measure/ResolventTransform.lean | 2 +- .../SpecificCodomains/ContinuousMap.lean | 8 +- .../SpecificCodomains/ContinuousMapZero.lean | 8 +- .../DirichletCharacter/Basic.lean | 5 +- Mathlib/NumberTheory/MulChar/Basic.lean | 20 ++- Mathlib/NumberTheory/MulChar/Duality.lean | 12 +- Mathlib/NumberTheory/MulChar/Lemmas.lean | 11 +- Mathlib/NumberTheory/NumberField/CMField.lean | 2 +- .../NumberTheory/NumberField/Ideal/Basic.lean | 4 +- Mathlib/Order/Interval/Set/ProjIcc.lean | 7 +- Mathlib/Order/ModularLattice.lean | 4 +- Mathlib/Order/Restriction.lean | 6 +- .../Independence/Process/Basic.lean | 10 +- .../Kernel/IonescuTulcea/Traj.lean | 4 +- Mathlib/Probability/Process/Filtration.lean | 2 +- Mathlib/Probability/Process/Stopping.lean | 2 +- Mathlib/Probability/ProductMeasure.lean | 6 +- Mathlib/RingTheory/AlgebraTower.lean | 10 +- .../AlgebraicIndependent/Basic.lean | 2 +- .../IsIntegralClosure/Basic.lean | 2 +- Mathlib/RingTheory/Localization/Defs.lean | 8 +- Mathlib/RingTheory/Norm/Basic.lean | 2 +- Mathlib/RingTheory/Trace/Basic.lean | 2 +- Mathlib/RingTheory/Unramified/Basic.lean | 2 +- .../Cardinal/SchroederBernstein.lean | 2 +- Mathlib/Topology/Algebra/GroupWithZero.lean | 4 +- .../Topology/Algebra/InfiniteSum/Basic.lean | 4 +- .../Module/ContinuousLinearMap/Restrict.lean | 2 +- .../Algebra/Module/UniformConvergence.lean | 8 +- Mathlib/Topology/Algebra/Monoid.lean | 4 +- .../Category/TopCat/Limits/Products.lean | 4 +- Mathlib/Topology/Clopen.lean | 2 +- Mathlib/Topology/Coherent.lean | 4 +- Mathlib/Topology/CompactOpen.lean | 10 +- .../Compactness/CompactlyCoherentSpace.lean | 6 +- Mathlib/Topology/Constructions.lean | 61 ++++--- Mathlib/Topology/ContinuousMap/Basic.lean | 18 +- .../Topology/ContinuousMap/Bounded/Basic.lean | 18 +- .../ContinuousMap/ContinuousMapZero.lean | 12 +- Mathlib/Topology/ContinuousMap/Interval.lean | 4 +- .../Topology/ContinuousMap/StarOrdered.lean | 2 +- .../ContinuousMap/StoneWeierstrass.lean | 4 +- .../Topology/ContinuousMap/Weierstrass.lean | 2 +- Mathlib/Topology/ContinuousOn.lean | 44 +++-- Mathlib/Topology/Covering/Basic.lean | 6 +- Mathlib/Topology/EMetricSpace/Lipschitz.lean | 13 +- Mathlib/Topology/ExtremallyDisconnected.lean | 13 +- Mathlib/Topology/FiberBundle/Basic.lean | 6 +- .../Topology/FiberBundle/Trivialization.lean | 2 +- .../Topology/Instances/AddCircle/Defs.lean | 12 +- .../Topology/Instances/ENNReal/Lemmas.lean | 2 +- Mathlib/Topology/Instances/EReal/Lemmas.lean | 2 +- Mathlib/Topology/Instances/Real/Lemmas.lean | 2 +- Mathlib/Topology/IsClosedRestrict.lean | 59 ++++--- Mathlib/Topology/IsLocalHomeomorph.lean | 12 +- Mathlib/Topology/LocalAtTarget.lean | 5 +- Mathlib/Topology/LocallyConstant/Basic.lean | 6 +- .../Topology/MetricSpace/Antilipschitz.lean | 17 +- Mathlib/Topology/MetricSpace/Holder.lean | 2 +- .../Topology/MetricSpace/Pseudo/Basic.lean | 2 +- .../MetricSpace/UniformConvergence.lean | 16 +- Mathlib/Topology/NhdsWithin.lean | 2 +- .../Topology/OpenPartialHomeomorph/Basic.lean | 15 +- .../OpenPartialHomeomorph/Constructions.lean | 4 +- Mathlib/Topology/Order/IntermediateValue.lean | 28 +-- .../Topology/Order/MonotoneConvergence.lean | 10 +- Mathlib/Topology/PreorderRestrict.lean | 4 +- Mathlib/Topology/Semicontinuity/Basic.lean | 4 +- Mathlib/Topology/Semicontinuity/Defs.lean | 14 +- Mathlib/Topology/SeparatedMap.lean | 4 +- Mathlib/Topology/Separation/Basic.lean | 2 +- Mathlib/Topology/TietzeExtension.lean | 16 +- Mathlib/Topology/UniformSpace/Ascoli.lean | 62 +++---- Mathlib/Topology/UniformSpace/Basic.lean | 4 +- Mathlib/Topology/UniformSpace/Cauchy.lean | 2 +- .../UniformSpace/CompactConvergence.lean | 16 +- Mathlib/Topology/UniformSpace/Dini.lean | 4 +- .../Topology/UniformSpace/Equicontinuity.lean | 20 +-- .../Topology/UniformSpace/HeineCantor.lean | 2 +- Mathlib/Topology/UniformSpace/Pi.lean | 10 +- .../UniformSpace/UniformConvergence.lean | 2 +- .../UniformConvergenceTopology.lean | 33 ++-- 151 files changed, 974 insertions(+), 770 deletions(-) diff --git a/Archive/Sensitivity.lean b/Archive/Sensitivity.lean index 10b3e97caba4a6..6c5dc359e204d0 100644 --- a/Archive/Sensitivity.lean +++ b/Archive/Sensitivity.lean @@ -387,12 +387,12 @@ theorem exists_eigenvalue (H : Set (Q m.succ)) (hH : Card H ≥ 2 ^ m + 1) : rw [rank_range_of_injective (g m) g_injective] apply dim_V have dimW : dim W = card H := by - have li : LinearIndependent ℝ (H.restrict e) := by + have li : LinearIndependent ℝ (H.domRestrict e) := by convert! (dualBases_e_ε m.succ).basis.linearIndependent.comp _ Subtype.val_injective rw [(dualBases_e_ε _).coe_basis] rfl have hdW := rank_span li - rw [Set.range_restrict] at hdW + rw [Set.range_domRestrict] at hdW convert! hdW rw [← (dualBases_e_ε _).coe_basis, Cardinal.mk_image_eq (dualBases_e_ε _).basis.injective, Cardinal.mk_fintype] diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index fd1aadbc25f00c..18a69ab25d626f 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -1087,20 +1087,20 @@ theorem normalClosure_eq_top_of {N : Subgroup G} [hn : N.Normal] {g g' : G} {hg have h : ∀ x : N, (MulAut.conj c) x ∈ N := by rintro ⟨x, hx⟩ exact hn.conj_mem _ hx c - have hs : Function.Surjective (((MulAut.conj c).toMonoidHom.restrict N).codRestrict _ h) := by + have hs : Function.Surjective (((MulAut.conj c).toMonoidHom.domRestrict N).codRestrict _ h) := by rintro ⟨x, hx⟩ refine ⟨⟨c⁻¹ * x * c, ?_⟩, ?_⟩ · have h := hn.conj_mem _ hx c⁻¹ rwa [inv_inv] at h simp only [MonoidHom.codRestrict_apply, MulEquiv.coe_toMonoidHom, MulAut.conj_apply, - MonoidHom.restrict_apply, Subtype.mk_eq_mk, ← mul_assoc, mul_inv_cancel, one_mul] + MonoidHom.domRestrict_apply, Subtype.mk_eq_mk, ← mul_assoc, mul_inv_cancel, one_mul] rw [mul_assoc, mul_inv_cancel, mul_one] rw [eq_top_iff, ← MonoidHom.range_eq_top.2 hs, MonoidHom.range_eq_map] grw [eq_top_iff.1 ht] refine map_le_iff_le_comap.2 (normalClosure_le_normal ?_) rw [Set.singleton_subset_iff, SetLike.mem_coe] simp only [MonoidHom.codRestrict_apply, MulEquiv.coe_toMonoidHom, MulAut.conj_apply, - MonoidHom.restrict_apply, mem_comap] + MonoidHom.domRestrict_apply, mem_comap] exact subset_normalClosure (Set.mem_singleton _) end IsConj diff --git a/Mathlib/Algebra/Group/Subgroup/Ker.lean b/Mathlib/Algebra/Group/Subgroup/Ker.lean index e67add089fe1fa..95ec91625fd995 100644 --- a/Mathlib/Algebra/Group/Subgroup/Ker.lean +++ b/Mathlib/Algebra/Group/Subgroup/Ker.lean @@ -94,10 +94,14 @@ instance _root_.Subgroup.range_isMulCommutative {G : Type*} [Group G] [IsMulComm range_eq_map f ▸ Subgroup.map_isMulCommutative ⊤ f @[to_additive (attr := simp)] -theorem restrict_range (f : G →* N) : (f.restrict K).range = K.map f := by - simp_rw [SetLike.ext_iff, mem_range, mem_map, restrict_apply, SetLike.exists, +theorem domRestrict_range (f : G →* N) : (f.domRestrict K).range = K.map f := by + simp_rw [SetLike.ext_iff, mem_range, mem_map, domRestrict_apply, SetLike.exists, exists_prop, forall_const] +@[deprecated (since := "2026-07-19")] alias restrict_range := domRestrict_range +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrict_range := _root_.AddMonoidHom.domRestrict_range + /-- The canonical surjective group homomorphism `G →* f(G)` induced by a group homomorphism `G →* N`. -/ @[to_additive @@ -280,9 +284,13 @@ theorem ker_le_comap (f : G →* N) (H : Subgroup N) : f.ker ≤ H.comap f := comap_mono bot_le @[to_additive (attr := simp)] -theorem ker_restrict (f : G →* M) : (f.restrict K).ker = f.ker.subgroupOf K := +theorem ker_domRestrict (f : G →* M) : (f.domRestrict K).ker = f.ker.subgroupOf K := rfl +@[deprecated (since := "2026-07-19")] alias ker_restrict := ker_domRestrict +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.ker_restrict := _root_.AddMonoidHom.ker_domRestrict + @[to_additive (attr := simp)] theorem ker_codRestrict {S} [SetLike S N] [SubmonoidClass S N] (f : G →* N) (s : S) (h : ∀ x, f x ∈ s) : (f.codRestrict s h).ker = f.ker := diff --git a/Mathlib/Algebra/Group/Submonoid/Operations.lean b/Mathlib/Algebra/Group/Submonoid/Operations.lean index 40db10c2cc5728..c31d1fc2ee1a36 100644 --- a/Mathlib/Algebra/Group/Submonoid/Operations.lean +++ b/Mathlib/Algebra/Group/Submonoid/Operations.lean @@ -57,7 +57,8 @@ In this file we define various operations on `Submonoid`s and `MonoidHom`s. * `MonoidHom.mrange`: range of a monoid homomorphism as a submonoid of the codomain; * `MonoidHom.mker`: kernel of a monoid homomorphism as a submonoid of the domain; -* `MonoidHom.restrict`: restrict a monoid homomorphism to a submonoid; +* `MonoidHom.domRestrict`: restrict a monoid homomorphism to a submonoid of its domain; +* `MonoidHom.restrict`: restrict the domain and codomain of a monoid homomorphism; * `MonoidHom.codRestrict`: restrict the codomain of a monoid homomorphism to a submonoid; * `MonoidHom.mrangeRestrict`: restrict a monoid homomorphism to its range; @@ -170,9 +171,9 @@ open Set ### `comap` and `map` -/ -/-- The preimage of a submonoid along a monoid homomorphism is a submonoid. -/ +/-- The preimage of a `Submonoid` along a `MonoidHom` is a `Submonoid`. -/ @[to_additive - /-- The preimage of an `AddSubmonoid` along an `AddMonoid` homomorphism is an `AddSubmonoid`. -/] + /-- The preimage of an `AddSubmonoid` along an `AddMonoidHom` is an `AddSubmonoid`. -/] def comap (f : F) (S : Submonoid N) : Submonoid M where carrier := f ⁻¹' S @@ -196,9 +197,9 @@ theorem comap_comap (S : Submonoid P) (g : N →* P) (f : M →* N) : theorem comap_id (S : Submonoid P) : S.comap (MonoidHom.id P) = S := ext (by simp) -/-- The image of a submonoid along a monoid homomorphism is a submonoid. -/ +/-- The image of a `Submonoid` along a `MonoidHom` is a `Submonoid`. -/ @[to_additive - /-- The image of an `AddSubmonoid` along an `AddMonoid` homomorphism is an `AddSubmonoid`. -/] + /-- The image of an `AddSubmonoid` along an `AddMonoidHom` is an `AddSubmonoid`. -/] def map (f : F) (S : Submonoid M) : Submonoid N where carrier := f '' S @@ -428,9 +429,9 @@ end GaloisInsertion variable {M : Type*} [MulOneClass M] (S : Submonoid M) -/-- The top submonoid is isomorphic to the monoid. -/ +/-- The top `Submonoid` is isomorphic to the `Monoid`. -/ @[to_additive (attr := simps) -/-- The top additive submonoid is isomorphic to the additive monoid. -/] +/-- The top `AddSubmonoid` is isomorphic to the `AddMonoid`. -/] def topEquiv : (⊤ : Submonoid M) ≃* M where toFun x := x invFun x := ⟨x, mem_top x⟩ @@ -441,9 +442,9 @@ def topEquiv : (⊤ : Submonoid M) ≃* M where theorem topEquiv_toMonoidHom : ((topEquiv : _ ≃* M) : _ →* M) = (⊤ : Submonoid M).subtype := rfl -/-- A subgroup is isomorphic to its image under an injective function. If you have an isomorphism, +/-- A `Subgroup` is isomorphic to its image under an injective function. If you have an isomorphism, use `MulEquiv.submonoidMap` for better definitional equalities. -/ -@[to_additive /-- An additive subgroup is isomorphic to its image under an injective function. If +@[to_additive /-- An `AddSubgroup` is isomorphic to its image under an injective function. If you have an isomorphism, use `AddEquiv.addSubmonoidMap` for better definitional equalities. -/] noncomputable def equivMapOfInjective (f : M →* N) (hf : Function.Injective f) : S ≃* S.map f := { Equiv.Set.image f S hf with map_mul' := fun _ _ => Subtype.ext (f.map_mul _ _) } @@ -458,13 +459,12 @@ theorem closure_closure_coe_preimage {s : Set M} : closure (((↑) : closure s eq_top_iff.2 fun x _ ↦ Subtype.recOn x fun _ hx' ↦ closure_induction (fun _ h ↦ subset_closure h) (one_mem _) (fun _ _ _ _ ↦ mul_mem) hx' -/-- Given submonoids `s`, `t` of monoids `M`, `N` respectively, `s × t` as a submonoid -of `M × N`. -/ +/-- Given `Submonoid`s `s`, `t` of `Monoid`s `M`, `N` respectively, `s × t` as a `Submonoid` of +`M × N`. -/ @[to_additive prod - /-- Given `AddSubmonoid`s `s`, `t` of `AddMonoid`s `A`, `B` respectively, `s × t` - as an `AddSubmonoid` of `A × B`. -/] -def prod (s : Submonoid M) (t : Submonoid N) : - Submonoid (M × N) where + /-- Given `AddSubmonoid`s `s`, `t` of `AddMonoid`s `A`, `B` respectively, `s × t` as an + `AddSubmonoid` of `A × B`. -/] +def prod (s : Submonoid M) (t : Submonoid N) : Submonoid (M × N) where carrier := s ×ˢ t one_mem' := ⟨s.one_mem, t.one_mem⟩ mul_mem' hp hq := ⟨s.mul_mem hp.1 hq.1, t.mul_mem hp.2 hq.2⟩ @@ -500,9 +500,9 @@ theorem top_prod_top : (⊤ : Submonoid M).prod (⊤ : Submonoid N) = ⊤ := theorem bot_prod_bot : (⊥ : Submonoid M).prod (⊥ : Submonoid N) = ⊥ := SetLike.coe_injective <| by simp [coe_prod] -/-- The product of submonoids is isomorphic to their product as monoids. -/ +/-- The product of `Submonoid`s is isomorphic to their product as `Monoid`s. -/ @[to_additive prodEquiv - /-- The product of additive submonoids is isomorphic to their product as additive monoids. -/] + /-- The product of `AddSubmonoid`s is isomorphic to their product as `AddMonoid`s. -/] def prodEquiv (s : Submonoid M) (t : Submonoid N) : s.prod t ≃* s × t := { (Equiv.Set.prod (s : Set M) (t : Set N)) with map_mul' := fun _ _ => rfl } @@ -644,7 +644,7 @@ def mrange (f : M →* N) : Submonoid N := ``` -/ -/-- The range of a monoid homomorphism is a submonoid. See Note [range copy pattern]. -/ +/-- The range of a `MonoidHom` is a `Submonoid`. See Note [range copy pattern]. -/ @[to_additive /-- The range of an `AddMonoidHom` is an `AddSubmonoid`. -/] def mrange (f : F) : Submonoid N := ((⊤ : Submonoid M).map f).copy (Set.range f) Set.image_univ.symm @@ -683,9 +683,9 @@ lemma mrange_prodMap {M' N' : Type*} [MulOneClass M'] [MulOneClass N'] (f : M MonoidHom.mrange (f.prodMap g) = (MonoidHom.mrange f).prod (MonoidHom.mrange g) := SetLike.coe_injective Set.range_prodMap -/-- The range of a surjective monoid hom is the whole of the codomain. -/ +/-- The range of a surjective `MonoidHom` is the whole of the codomain. -/ @[to_additive (attr := simp) - /-- The range of a surjective `AddMonoid` hom is the whole of the codomain. -/] + /-- The range of a surjective `AddMonoidHom` is the whole of the codomain. -/] theorem mrange_eq_top_of_surjective (f : F) (hf : Function.Surjective f) : mrange f = (⊤ : Submonoid N) := mrange_eq_top.2 hf @@ -694,11 +694,11 @@ theorem mrange_eq_top_of_surjective (f : F) (hf : Function.Surjective f) : theorem mclosure_preimage_le (f : F) (s : Set N) : closure (f ⁻¹' s) ≤ (closure s).comap f := closure_le.2 fun _ hx => SetLike.mem_coe.2 <| mem_comap.2 <| subset_closure hx -/-- The image under a monoid hom of the submonoid generated by a set equals the submonoid generated -by the image of the set. -/ +/-- The image under a `MonoidHom` of the `Submonoid` generated by a set equals the `Submonoid` +generated by the image of the set. -/ @[to_additive - /-- The image under an `AddMonoid` hom of the `AddSubmonoid` generated by a set equals - the `AddSubmonoid` generated by the image of the set. -/] + /-- The image under an `AddMonoidHom` of the `AddSubmonoid` generated by a set equals the + `AddSubmonoid` generated by the image of the set. -/] theorem map_mclosure (f : F) (s : Set M) : (closure s).map f = closure (f '' s) := Set.image_preimage.l_comm_of_u_comm (gc_map_comap f) (Submonoid.gi N).gc (Submonoid.gi M).gc fun _ ↦ rfl @@ -707,40 +707,58 @@ theorem map_mclosure (f : F) (s : Set M) : (closure s).map f = closure (f '' s) theorem mclosure_range (f : F) : closure (Set.range f) = mrange f := by rw [← Set.image_univ, ← map_mclosure, mrange_eq_map, closure_univ] -/-- Restriction of a monoid hom to a submonoid of the domain. -/ -@[to_additive /-- Restriction of an `AddMonoid` hom to an `AddSubmonoid` of the domain. -/] -def restrict {N S : Type*} [MulOneClass N] [SetLike S M] [SubmonoidClass S M] (f : M →* N) +/-- Restriction of a `MonoidHom` to a `Submonoid` of the domain. -/ +@[to_additive /-- Restriction of an `AddMonoidHom` to an `AddSubmonoid` of the domain. -/] +def domRestrict {N S : Type*} [MulOneClass N] [SetLike S M] [SubmonoidClass S M] (f : M →* N) (s : S) : s →* N := f.comp (SubmonoidClass.subtype _) @[to_additive (attr := simp)] -theorem restrict_apply {N S : Type*} [MulOneClass N] [SetLike S M] [SubmonoidClass S M] - (f : M →* N) (s : S) (x : s) : f.restrict s x = f x := +theorem domRestrict_apply {N S : Type*} [MulOneClass N] [SetLike S M] [SubmonoidClass S M] + (f : M →* N) (s : S) (x : s) : f.domRestrict s x = f x := rfl +@[deprecated (since := "2026-07-19")] alias restrict_apply := domRestrict_apply +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrict_apply := _root_.AddMonoidHom.domRestrict_apply + @[to_additive (attr := simp)] -theorem restrict_eq_one_iff {N S : Type*} [MulOneClass N] {f : M →* N} [SetLike S M] +theorem domRestrict_eq_one_iff {N S : Type*} [MulOneClass N] {f : M →* N} [SetLike S M] [SubmonoidClass S M] {s : S} : - f.restrict s = 1 ↔ ∀ x ∈ s, f x = 1 := by + f.domRestrict s = 1 ↔ ∀ x ∈ s, f x = 1 := by simp [MonoidHom.ext_iff] +@[deprecated (since := "2026-07-19")] alias restrict_eq_one_iff := domRestrict_eq_one_iff +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrict_eq_zero_iff := _root_.AddMonoidHom.domRestrict_eq_zero_iff + @[to_additive (attr := simp)] -theorem restrict_mrange (f : M →* N) : mrange (f.restrict S) = S.map f := by +theorem domRestrict_mrange (f : M →* N) : mrange (f.domRestrict S) = S.map f := by simp [SetLike.ext_iff] -/-- -A version of `MonoidHom.restrict` as an homomorphism. --/ -@[to_additive (attr := simps apply) /-- A version of `AddMonoidHom.restrict` as an homomorphism. -/] -def restrictHom {S : Type*} [SetLike S M] [SubmonoidClass S M] (M' : S) (A : Type*) +@[deprecated (since := "2026-07-19")] alias restrict_mrange := domRestrict_mrange +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrict_mrange := _root_.AddMonoidHom.domRestrict_mrange + +/-- A version of `MonoidHom.domRestrict` as a homomorphism. -/ +@[to_additive (attr := simps apply) + /-- A version of `AddMonoidHom.domRestrict` as a homomorphism. -/] +def domRestrictHom {S : Type*} [SetLike S M] [SubmonoidClass S M] (M' : S) (A : Type*) [CommMonoid A] : (M →* A) →* (M' →* A) where - toFun f := f.restrict M' + toFun f := f.domRestrict M' map_one' := by ext; simp map_mul' _ _ := by ext; simp -/-- Restriction of a monoid hom to a submonoid of the codomain. -/ +@[deprecated (since := "2026-07-19")] alias restrictHom := domRestrictHom +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrictHom := _root_.AddMonoidHom.domRestrictHom +@[deprecated (since := "2026-07-19")] alias restrictHom_apply := domRestrictHom_apply +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrictHom_apply := _root_.AddMonoidHom.domRestrictHom_apply + +/-- Restriction of a `MonoidHom` to a `Submonoid` of the codomain. -/ @[to_additive (attr := simps apply) - /-- Restriction of an `AddMonoid` hom to an `AddSubmonoid` of the codomain. -/] + /-- Restriction of an `AddMonoidHom` to an `AddSubmonoid` of the codomain. -/] def codRestrict {S} [SetLike S N] [SubmonoidClass S N] (f : M →* N) (s : S) (h : ∀ x, f x ∈ s) : M →* s where toFun n := ⟨f n, h n⟩ @@ -752,8 +770,9 @@ lemma injective_codRestrict {S} [SetLike S N] [SubmonoidClass S N] (f : M →* N (h : ∀ x, f x ∈ s) : Function.Injective (f.codRestrict s h) ↔ Function.Injective f := ⟨fun H _ _ hxy ↦ H <| Subtype.ext hxy, fun H _ _ hxy ↦ H (congr_arg Subtype.val hxy)⟩ -/-- Restriction of a monoid hom to its range interpreted as a submonoid. -/ -@[to_additive /-- Restriction of an `AddMonoid` hom to its range interpreted as a submonoid. -/] +/-- Restriction of a `MonoidHom` to its range interpreted as a `Submonoid`. -/ +@[to_additive + /-- Restriction of an `AddMonoidHom` to its range interpreted as an `AddSubmonoid`. -/] def mrangeRestrict {N} [MulOneClass N] (f : M →* N) : M →* (mrange f) := (f.codRestrict (mrange f)) fun x => ⟨x, rfl⟩ @@ -766,10 +785,10 @@ theorem coe_mrangeRestrict {N} [MulOneClass N] (f : M →* N) (x : M) : theorem mrangeRestrict_surjective (f : M →* N) : Function.Surjective f.mrangeRestrict := fun ⟨_, ⟨x, rfl⟩⟩ => ⟨x, rfl⟩ -/-- The multiplicative kernel of a monoid hom is the submonoid of elements `x : G` such -that `f x = 1`. -/ +/-- The multiplicative kernel of a `MonoidHom` is the `Submonoid` of elements `x : G` such that +`f x = 1`. -/ @[to_additive - /-- The additive kernel of an `AddMonoid` hom is the `AddSubmonoid` of elements such that + /-- The additive kernel of an `AddMonoidHom` is the `AddSubmonoid` of elements such that `f x = 0`. -/] def mker (f : F) : Submonoid M := (⊥ : Submonoid N).comap f @@ -795,9 +814,14 @@ theorem comap_bot' (f : F) : (⊥ : Submonoid N).comap f = mker f := rfl @[to_additive (attr := simp)] -theorem restrict_mker (f : M →* N) : mker (f.restrict S) = (MonoidHom.mker f).comap S.subtype := +theorem domRestrict_mker (f : M →* N) : + mker (f.domRestrict S) = (MonoidHom.mker f).comap S.subtype := rfl +@[deprecated (since := "2026-07-19")] alias restrict_mker := domRestrict_mker +@[deprecated (since := "2026-07-19")] +alias _root_.AddMonoidHom.restrict_mker := _root_.AddMonoidHom.domRestrict_mker + set_option backward.isDefEq.respectTransparency false in @[to_additive] theorem mrangeRestrict_mker (f : M →* N) : mker (mrangeRestrict f) = mker f := by @@ -837,9 +861,9 @@ lemma mker_fst : mker (fst M N) = .prod ⊥ ⊤ := SetLike.ext fun _ => (iff_of_ @[to_additive (attr := simp)] lemma mker_snd : mker (snd M N) = .prod ⊤ ⊥ := SetLike.ext fun _ => (iff_of_eq (true_and _)).symm -/-- The `MonoidHom` from the preimage of a submonoid to itself. -/ +/-- The `MonoidHom` from the preimage of a `Submonoid` to itself. -/ @[to_additive (attr := simps) - /-- The `AddMonoidHom` from the preimage of an additive submonoid to itself. -/] + /-- The `AddMonoidHom` from the preimage of an `AddSubmonoid` to itself. -/] def submonoidComap (f : M →* N) (N' : Submonoid N) : N'.comap f →* N' where toFun x := ⟨f x, x.2⟩ @@ -854,11 +878,11 @@ lemma submonoidComap_surjective_of_surjective (f : M →* N) (N' : Submonoid N) apply Subtype.val_injective simp [hx] -/-- The `MonoidHom` from a submonoid to its image. +/-- The `MonoidHom` from a `Submonoid` to its image. See `MulEquiv.SubmonoidMap` for a variant for `MulEquiv`s. -/ @[to_additive (attr := simps) - /-- The `AddMonoidHom` from an additive submonoid to its image. See `AddEquiv.AddSubmonoidMap` - for a variant for `AddEquiv`s. -/] + /-- The `AddMonoidHom` from an `AddSubmonoid` to its image. + See `AddEquiv.AddSubmonoidMap` for a variant for `AddEquiv`s. -/] def submonoidMap (f : M →* N) (M' : Submonoid M) : M' →* M'.map f where toFun x := ⟨f x, ⟨x, x.2, rfl⟩⟩ map_one' := Subtype.ext <| f.map_one @@ -920,9 +944,8 @@ theorem prod_eq_top_iff {s : Submonoid M} {t : Submonoid N} : s.prod t = ⊤ ↔ theorem mrange_inl_sup_mrange_inr : mrange (inl M N) ⊔ mrange (inr M N) = ⊤ := by simp only [mrange_inl, mrange_inr, prod_bot_sup_bot_prod, top_prod_top] -/-- The monoid hom associated to an inclusion of submonoids. -/ -@[to_additive - /-- The `AddMonoid` hom associated to an inclusion of submonoids. -/] +/-- The `MonoidHom` associated to an inclusion of `Submonoid`s. -/ +@[to_additive /-- The `AddMonoidHom` associated to an inclusion of `AddSubmonoid`s. -/] def inclusion {S T : Submonoid M} (h : S ≤ T) : S →* T := S.subtype.codRestrict _ fun x => h x.2 @@ -969,16 +992,15 @@ theorem nontrivial_iff_exists_ne_one (S : Submonoid M) : Nontrivial S ↔ ∃ x _ ↔ ∃ (x : _) (hx : x ∈ S), (⟨x, hx⟩ : S) ≠ ⟨1, S.one_mem⟩ := Subtype.exists _ ↔ ∃ x ∈ S, x ≠ (1 : M) := by simp [Ne] -/-- A submonoid is either the trivial submonoid or nontrivial. -/ -@[to_additive /-- An additive submonoid is either the trivial additive submonoid or nontrivial. -/] +/-- A `Submonoid` is either the trivial `Submonoid` or nontrivial. -/ +@[to_additive /-- An `AddSubmonoid` is either the trivial `AddSubmonoid` or nontrivial. -/] theorem bot_or_nontrivial (S : Submonoid M) : S = ⊥ ∨ Nontrivial S := by simp only [eq_bot_iff_forall, nontrivial_iff_exists_ne_one, ← not_forall, ← Classical.not_imp, Classical.em] -/-- A submonoid is either the trivial submonoid or contains a nonzero element. -/ +/-- A `Submonoid` is either the trivial `Submonoid` or contains a nonzero element. -/ @[to_additive - /-- An additive submonoid is either the trivial additive submonoid or contains a nonzero - element. -/] + /-- An `AddSubmonoid` is either the trivial `AddSubmonoid` or contains a nonzero element. -/] theorem bot_or_exists_ne_one (S : Submonoid M) : S = ⊥ ∨ ∃ x ∈ S, x ≠ (1 : M) := S.bot_or_nontrivial.imp_right S.nontrivial_iff_exists_ne_one.mp @@ -993,12 +1015,12 @@ section Pi variable {ι : Type*} {M : ι → Type*} [∀ i, MulOneClass (M i)] -/-- A version of `Set.pi` for submonoids. Given an index set `I` and a family of submodules -`s : Π i, Submonoid f i`, `pi I s` is the submonoid of dependent functions `f : Π i, f i` such that -`f i` belongs to `Pi I s` whenever `i ∈ I`. -/ +/-- A version of `Set.pi` for `Submonoid`s. Given an index set `I` and a family of `Submonoid`s +`s : Π i, Submonoid f i`, `pi I s` is the `Submonoid` of dependent functions `f : Π i, f i` such +that `f i` belongs to `Pi I s` whenever `i ∈ I`. -/ @[to_additive /-- A version of `Set.pi` for `AddSubmonoid`s. Given an index set `I` and a family - of submodules `s : Π i, AddSubmonoid f i`, `pi I s` is the `AddSubmonoid` of dependent functions - `f : Π i, f i` such that `f i` belongs to `pi I s` whenever `i ∈ I`. -/] + of `AddSubmonoid`s `s : Π i, AddSubmonoid f i`, `pi I s` is the `AddSubmonoid` of dependent + functions `f : Π i, f i` such that `f i` belongs to `pi I s` whenever `i ∈ I`. -/] def pi (I : Set ι) (S : ∀ i, Submonoid (M i)) : Submonoid (∀ i, M i) where carrier := I.pi fun i => (S i).carrier one_mem' i _ := (S i).one_mem @@ -1055,6 +1077,15 @@ end Pi end Submonoid +/-- Restrict the domain and codomain of a `MonoidHom`. -/ +@[to_additive /-- Restrict the domain and codomain of an `AddMonoidHom`. -/] +def MonoidHom.restrict {M' : Submonoid M} {N' : Submonoid N} {f : M →* N} + (h : Set.MapsTo f M' N') : M' →* N' := (f.domRestrict M').codRestrict N' <| SetLike.forall.mpr h + +@[to_additive] lemma MonoidHom.restrict_injective {M' : Submonoid M} {N' : Submonoid N} {f : M →* N} + (h : Set.MapsTo f M' N') (hf' : Function.Injective f) : Function.Injective <| f.restrict h := + fun _ _ h => Subtype.ext <| hf' <| Subtype.ext_iff.mp h + namespace MulEquiv variable {S} {T : Submonoid M} diff --git a/Mathlib/Algebra/Group/Subsemigroup/Operations.lean b/Mathlib/Algebra/Group/Subsemigroup/Operations.lean index 78a71b73f9e9ac..76075f246abc03 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Operations.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Operations.lean @@ -50,7 +50,7 @@ In this file we define various operations on `Subsemigroup`s and `MulHom`s. ### Operations on `MulHom`s * `MulHom.srange`: range of a semigroup homomorphism as a subsemigroup of the codomain; -* `MulHom.restrict`: restrict a semigroup homomorphism to a subsemigroup; +* `MulHom.domRestrict`: restrict a semigroup homomorphism to a subsemigroup of its domain; * `MulHom.codRestrict`: restrict the codomain of a semigroup homomorphism to a subsemigroup; * `MulHom.srangeRestrict`: restrict a semigroup homomorphism to its range; @@ -595,14 +595,21 @@ theorem map_mclosure (f : M →ₙ* N) (s : Set M) : (closure s).map f = closure /-- Restriction of a semigroup hom to a subsemigroup of the domain. -/ @[to_additive /-- Restriction of an AddSemigroup hom to an `AddSubsemigroup` of the domain. -/] -def restrict {N : Type*} [Mul N] [SetLike σ M] [MulMemClass σ M] (f : M →ₙ* N) (S : σ) : S →ₙ* N := +def domRestrict {N : Type*} [Mul N] [SetLike σ M] [MulMemClass σ M] (f : M →ₙ* N) + (S : σ) : S →ₙ* N := f.comp (MulMemClass.subtype S) @[to_additive (attr := simp)] -theorem restrict_apply {N : Type*} [Mul N] [SetLike σ M] [MulMemClass σ M] (f : M →ₙ* N) {S : σ} - (x : S) : f.restrict S x = f x := +theorem domRestrict_apply {N : Type*} [Mul N] [SetLike σ M] [MulMemClass σ M] + (f : M →ₙ* N) {S : σ} (x : S) : f.domRestrict S x = f x := rfl +@[deprecated (since := "2026-07-19")] alias restrict := domRestrict +@[deprecated (since := "2026-07-19")] alias _root_.AddHom.restrict := _root_.AddHom.domRestrict +@[deprecated (since := "2026-07-19")] alias restrict_apply := domRestrict_apply +@[deprecated (since := "2026-07-19")] +alias _root_.AddHom.restrict_apply := _root_.AddHom.domRestrict_apply + /-- Restriction of a semigroup hom to a subsemigroup of the codomain. -/ @[to_additive (attr := simps) /-- Restriction of an `AddSemigroup` hom to an `AddSubsemigroup` of the codomain. -/] diff --git a/Mathlib/Algebra/Module/Submodule/LinearMap.lean b/Mathlib/Algebra/Module/Submodule/LinearMap.lean index 2d6c0899bbe945..af088ed609c33c 100644 --- a/Mathlib/Algebra/Module/Submodule/LinearMap.lean +++ b/Mathlib/Algebra/Module/Submodule/LinearMap.lean @@ -148,7 +148,7 @@ theorem domRestrict_apply (f : M →ₛₗ[σ₁₂] M₂) (p : Submodule R M) ( rfl lemma coe_domRestrict (f : M →ₛₗ[σ₁₂] M₂) (p : Submodule R M) : - ⇑(f.domRestrict p) = Set.restrict p f := rfl + ⇑(f.domRestrict p) = Set.domRestrict p f := rfl /-- A linear map `f : M₂ → M` whose values lie in a submodule `p ⊆ M` can be restricted to a linear map M₂ → p. diff --git a/Mathlib/Algebra/Ring/Subsemiring/Defs.lean b/Mathlib/Algebra/Ring/Subsemiring/Defs.lean index 34f225d4096fd6..c0aeb69b76bc87 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Defs.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Defs.lean @@ -400,9 +400,11 @@ def domRestrict (f : R →+* S) (s : σR) : s →+* S := f.comp <| SubsemiringClass.subtype s @[simp] -theorem restrict_apply (f : R →+* S) {s : σR} (x : s) : f.domRestrict s x = f x := +theorem domRestrict_apply (f : R →+* S) {s : σR} (x : s) : f.domRestrict s x = f x := rfl +@[deprecated (since := "2026-07-19")] alias restrict_apply := domRestrict_apply + /-- The subsemiring of elements `x : R` such that `f x = g x` -/ def eqLocusS (f g : R →+* S) : Subsemiring R := { (f : R →* S).eqLocusM g, (f : R →+ S).eqLocusM g with carrier := { x | f x = g x } } diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean index 1fa2f8b2e31793..d0ad5f1394a70f 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Commute.lean @@ -78,7 +78,7 @@ protected theorem Commute.cfc {a b : A} (hb₁ : Commute a b) (hb₂ : Commute (star a) b) (f : 𝕜 → 𝕜) : Commute (cfc f a) b := cfc_cases (fun x ↦ Commute x b) a f (Commute.zero_left _) - fun hf ha ↦ hb₁.cfcHom ha hb₂ ⟨_, hf.restrict⟩ + fun hf ha ↦ hb₁.cfcHom ha hb₂ ⟨_, hf.domRestrict⟩ /-- For `a` selfadjoint, an element commutes with `cfc f a` if it commutes with `a`. @@ -163,7 +163,7 @@ protected theorem Commute.cfcₙ {a b : A} (hb₁ : Commute a b) (hb₂ : Commute (star a) b) (f : 𝕜 → 𝕜) : Commute (cfcₙ f a) b := cfcₙ_cases (fun x ↦ Commute x b) a f (Commute.zero_left _) - fun hf hf₀ ha ↦ hb₁.cfcₙHom ha hb₂ ⟨⟨_, hf.restrict⟩, hf₀⟩ + fun hf hf₀ ha ↦ hb₁.cfcₙHom ha hb₂ ⟨⟨_, hf.domRestrict⟩, hf₀⟩ /-- For `a` selfadjoint, an element commutes with `cfcₙ f a` if it commutes with `a`. diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean index 24b09a846a51d7..7fd03a672db3dc 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Continuity.lean @@ -96,7 +96,7 @@ theorem tendsto_cfc_fun {l : Filter X} {F : X → R → R} {f : R → R} {a : A} rw [Function.comp_apply, cfc_apply (hf := x.2)] rw [cfc_apply ..] apply cfcHom_continuous _ |>.tendsto _ |>.comp - rw [hf.tendsto_restrict_iff_tendstoUniformlyOn Subtype.property] + rw [hf.tendsto_domRestrict_iff_tendstoUniformlyOn Subtype.property] intro t simp only [eventually_comap, Subtype.forall] peel h_tendsto t with ht x _ @@ -235,12 +235,13 @@ satisfying the predicate `p` (associated to `𝕜`) and whose `𝕜`-spectrum is theorem continuousOn_cfc {s : Set 𝕜} (hs : IsCompact s) (f : 𝕜 → 𝕜) (hf : ContinuousOn f s := by cfc_cont_tac) : ContinuousOn (cfc f) {a | p a ∧ spectrum 𝕜 a ⊆ s} := - continuousOn_iff_continuous_restrict.mpr <| by + continuousOn_iff_continuous_domRestrict.mpr <| by convert! - continuous_cfcHomSuperset_left hs ⟨_, hf.restrict⟩ ((↑) : {a | p a ∧ spectrum 𝕜 a ⊆ s} → A) + continuous_cfcHomSuperset_left hs ⟨_, hf.domRestrict⟩ + ((↑) : {a | p a ∧ spectrum 𝕜 a ⊆ s} → A) continuous_subtype_val (fun x ↦ x.2.2) with x - rw [cfcHomSuperset_apply, Set.restrict_apply, cfc_apply _ _ x.2.1 (hf.mono x.2.2)] + rw [cfcHomSuperset_apply, Set.domRestrict_apply, cfc_apply _ _ x.2.1 (hf.mono x.2.2)] congr! open UniformOnFun in @@ -626,9 +627,9 @@ theorem tendsto_cfcₙ_fun {l : Filter X} {F : X → R → R} {f : R → R} {a : rw [cfcₙ_apply ..] apply cfcₙHom_continuous _ |>.tendsto _ |>.comp rw [ContinuousMapZero.isEmbedding_toContinuousMap.isInducing.tendsto_nhds_iff] - change Tendsto (fun x : s ↦ (⟨_, x.2.1.restrict⟩ : C(quasispectrum R a, R))) _ - (𝓝 ⟨_, hf.restrict⟩) - rw [hf.tendsto_restrict_iff_tendstoUniformlyOn (fun x ↦ x.2.1)] + change Tendsto (fun x : s ↦ (⟨_, x.2.1.domRestrict⟩ : C(quasispectrum R a, R))) _ + (𝓝 ⟨_, hf.domRestrict⟩) + rw [hf.tendsto_domRestrict_iff_tendstoUniformlyOn (fun x ↦ x.2.1)] intro t simp only [eventually_comap, Subtype.forall] peel h_tendsto t with ht x _ @@ -771,12 +772,12 @@ theorem continuousOn_cfcₙ {s : Set 𝕜} (hs : IsCompact s) (f : 𝕜 → 𝕜 (hf : ContinuousOn f s := by cfc_cont_tac) (hf0 : f 0 = 0 := by cfc_zero_tac) : ContinuousOn (cfcₙ f · : A → A) {a | p a ∧ quasispectrum 𝕜 a ⊆ s} := by by_cases hs0 : 0 ∈ s - · rw [continuousOn_iff_continuous_restrict] + · rw [continuousOn_iff_continuous_domRestrict] convert! - continuous_cfcₙHomSuperset_left hs (hs0 := ⟨hs0⟩) ⟨⟨_, hf.restrict⟩, hf0⟩ (X := + continuous_cfcₙHomSuperset_left hs (hs0 := ⟨hs0⟩) ⟨⟨_, hf.domRestrict⟩, hf0⟩ (X := {a : A | p a ∧ quasispectrum 𝕜 a ⊆ s}) continuous_subtype_val (fun x ↦ x.2.2) with x - rw [cfcₙHomSuperset_apply, Set.restrict_apply, cfcₙ_apply _ _ (hf.mono x.2.2) hf0 x.2.1] + rw [cfcₙHomSuperset_apply, Set.domRestrict_apply, cfcₙ_apply _ _ (hf.mono x.2.2) hf0 x.2.1] congr! · convert! continuousOn_empty _ rw [Set.eq_empty_iff_forall_notMem] diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean index f0b36c1bf86346..a0c58585f2073e 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean @@ -74,7 +74,7 @@ For a version with stronger assumptions which in practice are often easier to ve `integrable_cfc`. -/ lemma integrable_cfc' (f : X → 𝕜 → 𝕜) (a : A) (hf : Integrable - (fun x : X => mkD ((spectrum 𝕜 a).restrict (f x)) 0) μ) + (fun x : X => mkD ((spectrum 𝕜 a).domRestrict (f x)) 0) μ) (ha : p a := by cfc_tac) : Integrable (fun x => cfc (f x) a) μ := by conv in cfc _ _ => rw [cfc_eq_cfcL_mkD _ a] @@ -85,7 +85,7 @@ For a version with stronger assumptions which in practice are often easier to ve `integrableOn_cfc`. -/ lemma integrableOn_cfc' {s : Set X} (f : X → 𝕜 → 𝕜) (a : A) (hf : IntegrableOn - (fun x : X => mkD ((spectrum 𝕜 a).restrict (f x)) 0) s μ) + (fun x : X => mkD ((spectrum 𝕜 a).domRestrict (f x)) 0) s μ) (ha : p a := by cfc_tac) : IntegrableOn (fun x => cfc (f x) a) s μ := by exact integrable_cfc' _ _ hf ha @@ -130,21 +130,21 @@ For a version with stronger assumptions which in practice are often easier to ve lemma cfc_integral' [NormedSpace ℝ A] (f : X → 𝕜 → 𝕜) (a : A) (hf₁ : ∀ᵐ x ∂μ, ContinuousOn (f x) (spectrum 𝕜 a)) (hf₂ : Integrable - (fun x : X => mkD ((spectrum 𝕜 a).restrict (f x)) 0) μ) + (fun x : X => mkD ((spectrum 𝕜 a).domRestrict (f x)) 0) μ) (ha : p a := by cfc_tac) : cfc (fun z => ∫ x, f x z ∂μ) a = ∫ x, cfc (f x) a ∂μ := by have key₁ (z : spectrum 𝕜 a) : - ∫ x, f x z ∂μ = (∫ x, mkD ((spectrum 𝕜 a).restrict (f x)) 0 ∂μ) z := by + ∫ x, f x z ∂μ = (∫ x, mkD ((spectrum 𝕜 a).domRestrict (f x)) 0 ∂μ) z := by rw [integral_apply hf₂] refine integral_congr_ae ?_ filter_upwards [hf₁] with x cont_x rw [mkD_apply_of_continuousOn cont_x] have key₂ (z : spectrum 𝕜 a) : - ∫ x, f x z ∂μ = mkD ((spectrum 𝕜 a).restrict (fun z ↦ ∫ x, f x z ∂μ)) 0 z := by + ∫ x, f x z ∂μ = mkD ((spectrum 𝕜 a).domRestrict (fun z ↦ ∫ x, f x z ∂μ)) 0 z := by rw [mkD_apply_of_continuousOn] - rw [continuousOn_iff_continuous_restrict] + rw [continuousOn_iff_continuous_domRestrict] refine continuous_congr key₁ |>.mpr ?_ - exact map_continuous (∫ x, mkD ((spectrum 𝕜 a).restrict (f x)) 0 ∂μ) + exact map_continuous (∫ x, mkD ((spectrum 𝕜 a).domRestrict (f x)) 0 ∂μ) simp_rw [cfc_eq_cfcL_mkD _ a, cfcL_integral a _ hf₂ ha] congr ext z @@ -157,7 +157,7 @@ For a version with stronger assumptions which in practice are often easier to ve lemma cfc_setIntegral' {s : Set X} [NormedSpace ℝ A] (f : X → 𝕜 → 𝕜) (a : A) (hf₁ : ∀ᵐ x ∂(μ.restrict s), ContinuousOn (f x) (spectrum 𝕜 a)) (hf₂ : IntegrableOn - (fun x : X => mkD ((spectrum 𝕜 a).restrict (f x)) 0) s μ) + (fun x : X => mkD ((spectrum 𝕜 a).domRestrict (f x)) 0) s μ) (ha : p a := by cfc_tac) : cfc (fun z => ∫ x in s, f x z ∂μ) a = ∫ x in s, cfc (f x) a ∂μ := cfc_integral' _ _ hf₁ hf₂ ha @@ -228,7 +228,7 @@ For a version with stronger assumptions which in practice are often easier to ve `integrable_cfcₙ`. -/ lemma integrable_cfcₙ' (f : X → 𝕜 → 𝕜) (a : A) (hf : Integrable - (fun x : X => mkD ((quasispectrum 𝕜 a).restrict (f x)) 0) μ) + (fun x : X => mkD ((quasispectrum 𝕜 a).domRestrict (f x)) 0) μ) (ha : p a := by cfc_tac) : Integrable (fun x => cfcₙ (f x) a) μ := by conv in cfcₙ _ _ => rw [cfcₙ_eq_cfcₙL_mkD _ a] @@ -239,7 +239,7 @@ For a version with stronger assumptions which in practice are often easier to ve `integrableOn_cfcₙ`. -/ lemma integrableOn_cfcₙ' {s : Set X} (f : X → 𝕜 → 𝕜) (a : A) (hf : IntegrableOn - (fun x : X => mkD ((quasispectrum 𝕜 a).restrict (f x)) 0) s μ) + (fun x : X => mkD ((quasispectrum 𝕜 a).domRestrict (f x)) 0) s μ) (ha : p a := by cfc_tac) : IntegrableOn (fun x => cfcₙ (f x) a) s μ := by exact integrable_cfcₙ' _ _ hf ha @@ -288,21 +288,21 @@ lemma cfcₙ_integral' [NormedSpace ℝ A] (f : X → 𝕜 → 𝕜) (a : A) (hf₁ : ∀ᵐ x ∂μ, ContinuousOn (f x) (quasispectrum 𝕜 a)) (hf₂ : ∀ᵐ x ∂μ, f x 0 = 0) (hf₃ : Integrable - (fun x : X => mkD ((quasispectrum 𝕜 a).restrict (f x)) 0) μ) + (fun x : X => mkD ((quasispectrum 𝕜 a).domRestrict (f x)) 0) μ) (ha : p a := by cfc_tac) : cfcₙ (fun z => ∫ x, f x z ∂μ) a = ∫ x, cfcₙ (f x) a ∂μ := by have key₁ (z : quasispectrum 𝕜 a) : - ∫ x, f x z ∂μ = (∫ x, mkD ((quasispectrum 𝕜 a).restrict (f x)) 0 ∂μ) z := by + ∫ x, f x z ∂μ = (∫ x, mkD ((quasispectrum 𝕜 a).domRestrict (f x)) 0 ∂μ) z := by rw [integral_apply hf₃] refine integral_congr_ae ?_ filter_upwards [hf₁, hf₂] with x cont_x zero_x rw [mkD_apply_of_continuousOn cont_x zero_x] have key₂ (z : quasispectrum 𝕜 a) : - ∫ x, f x z ∂μ = mkD ((quasispectrum 𝕜 a).restrict (fun z ↦ ∫ x, f x z ∂μ)) 0 z := by + ∫ x, f x z ∂μ = mkD ((quasispectrum 𝕜 a).domRestrict (fun z ↦ ∫ x, f x z ∂μ)) 0 z := by rw [mkD_apply_of_continuousOn] - · rw [continuousOn_iff_continuous_restrict] + · rw [continuousOn_iff_continuous_domRestrict] refine continuous_congr key₁ |>.mpr ?_ - exact map_continuous (∫ x, mkD ((quasispectrum 𝕜 a).restrict (f x)) 0 ∂μ) + exact map_continuous (∫ x, mkD ((quasispectrum 𝕜 a).domRestrict (f x)) 0 ∂μ) · exact integral_eq_zero_of_ae hf₂ simp_rw [cfcₙ_eq_cfcₙL_mkD _ a, cfcₙL_integral a _ hf₃ ha] congr @@ -317,7 +317,7 @@ lemma cfcₙ_setIntegral' {s : Set X} [NormedSpace ℝ A] (f : X → 𝕜 → (hf₁ : ∀ᵐ x ∂(μ.restrict s), ContinuousOn (f x) (quasispectrum 𝕜 a)) (hf₂ : ∀ᵐ x ∂(μ.restrict s), f x 0 = 0) (hf₃ : IntegrableOn - (fun x : X => mkD ((quasispectrum 𝕜 a).restrict (f x)) 0) s μ) + (fun x : X => mkD ((quasispectrum 𝕜 a).domRestrict (f x)) 0) s μ) (ha : p a := by cfc_tac) : cfcₙ (fun z => ∫ x in s, f x z ∂μ) a = ∫ x in s, cfcₙ (f x) a ∂μ := cfcₙ_integral' _ _ hf₁ hf₂ hf₃ ha diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index 09286ec3c9466e..30b7a734f0a8f1 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -214,7 +214,7 @@ for non-unital algebras, and all the API applies to this declaration. For more i module documentation for `Analysis.CStarAlgebra.ContinuousFunctionalCalculus.Unital`. -/ noncomputable irreducible_def cfcₙ (f : R → R) (a : A) : A := if h : p a ∧ ContinuousOn f (σₙ R a) ∧ f 0 = 0 - then cfcₙHom h.1 ⟨⟨_, h.2.1.restrict⟩, h.2.2⟩ + then cfcₙHom h.1 ⟨⟨_, h.2.1.domRestrict⟩, h.2.2⟩ else 0 variable (f g : R → R) (a : A) @@ -223,13 +223,13 @@ variable (hg : ContinuousOn g (σₙ R a) := by cfc_cont_tac) (hg0 : g 0 = 0 := variable (ha : p a := by cfc_tac) set_option backward.privateInPublic true in -lemma cfcₙ_apply : cfcₙ f a = cfcₙHom (a := a) ha ⟨⟨_, hf.restrict⟩, hf0⟩ := by +lemma cfcₙ_apply : cfcₙ f a = cfcₙHom (a := a) ha ⟨⟨_, hf.domRestrict⟩, hf0⟩ := by rw [cfcₙ_def, dif_pos ⟨ha, hf, hf0⟩] lemma cfcₙ_apply_pi {ι : Type*} (f : ι → R → R) (a : A) (ha := by cfc_tac) (hf : ∀ i, ContinuousOn (f i) (σₙ R a) := by cfc_cont_tac) (hf0 : ∀ i, f i 0 = 0 := by cfc_zero_tac) : - (fun i => cfcₙ (f i) a) = (fun i => cfcₙHom (a := a) ha ⟨⟨_, (hf i).restrict⟩, hf0 i⟩) := by + (fun i => cfcₙ (f i) a) = (fun i => cfcₙHom (a := a) ha ⟨⟨_, (hf i).domRestrict⟩, hf0 i⟩) := by ext i simp only [cfcₙ_apply (f i) a (hf i) (hf0 i)] @@ -253,10 +253,10 @@ lemma cfcₙ_apply_of_not_map_zero {f : R → R} (a : A) (hf : ¬ f 0 = 0) : set_option backward.isDefEq.respectTransparency false in lemma cfcₙHom_eq_cfcₙ_extend {a : A} (g : R → R) (ha : p a) (f : C(σₙ R a, R)₀) : cfcₙHom ha f = cfcₙ (Function.extend Subtype.val f g) a := by - have h : f = (σₙ R a).restrict (Function.extend Subtype.val f g) := by + have h : f = (σₙ R a).domRestrict (Function.extend Subtype.val f g) := by ext; simp have hg : ContinuousOn (Function.extend Subtype.val f g) (σₙ R a) := - continuousOn_iff_continuous_restrict.mpr <| h ▸ map_continuous f + continuousOn_iff_continuous_domRestrict.mpr <| h ▸ map_continuous f have hg0 : (Function.extend Subtype.val f g) 0 = 0 := by rw [← quasispectrum.coe_zero (R := R) a, Subtype.val_injective.extend_apply] exact map_zero f @@ -265,13 +265,13 @@ lemma cfcₙHom_eq_cfcₙ_extend {a : A} (g : R → R) (ha : p a) (f : C(σₙ R congr! lemma cfcₙ_eq_cfcₙL {a : A} {f : R → R} (ha : p a) (hf : ContinuousOn f (σₙ R a)) (hf0 : f 0 = 0) : - cfcₙ f a = cfcₙL ha ⟨⟨_, hf.restrict⟩, hf0⟩ := by + cfcₙ f a = cfcₙL ha ⟨⟨_, hf.domRestrict⟩, hf0⟩ := by rw [cfcₙ_def, dif_pos ⟨ha, hf, hf0⟩, cfcₙL_apply] set_option backward.privateInPublic true in /-- A version of `cfcₙ_apply` in terms of `ContinuousMapZero.mkD` -/ lemma cfcₙ_apply_mkD : - cfcₙ f a = cfcₙHom (a := a) ha (mkD ((quasispectrum R a).restrict f) 0) := by + cfcₙ f a = cfcₙHom (a := a) ha (mkD ((quasispectrum R a).domRestrict f) 0) := by by_cases f_cont : ContinuousOn f (quasispectrum R a) · by_cases f_zero : f 0 = 0 · rw [cfcₙ_apply f a, mkD_of_continuousOn f_cont f_zero] @@ -282,11 +282,11 @@ lemma cfcₙ_apply_mkD : set_option backward.privateInPublic true in /-- A version of `cfcₙ_eq_cfcₙL` in terms of `ContinuousMapZero.mkD` -/ lemma cfcₙ_eq_cfcₙL_mkD : - cfcₙ f a = cfcₙL (a := a) ha (mkD ((quasispectrum R a).restrict f) 0) := + cfcₙ f a = cfcₙL (a := a) ha (mkD ((quasispectrum R a).domRestrict f) 0) := cfcₙ_apply_mkD _ _ lemma cfcₙ_cases (P : A → Prop) (a : A) (f : R → R) (h₀ : P 0) - (haf : ∀ (hf : ContinuousOn f (σₙ R a)) h0 ha, P (cfcₙHom ha ⟨⟨_, hf.restrict⟩, h0⟩)) : + (haf : ∀ (hf : ContinuousOn f (σₙ R a)) h0 ha, P (cfcₙHom ha ⟨⟨_, hf.domRestrict⟩, h0⟩)) : P (cfcₙ f a) := by by_cases h : ContinuousOn f (σₙ R a) ∧ f 0 = 0 ∧ p a · rw [cfcₙ_apply f a h.1 h.2.1 h.2.2] @@ -334,7 +334,7 @@ lemma cfcₙ_congr {f g : R → R} {a : A} (hfg : (σₙ R a).EqOn f g) : · rw [cfcₙ_apply f a (h.2.1.congr hfg) (hfg (quasispectrum.zero_mem R a) ▸ h.2.2) h.1, cfcₙ_apply g a h.2.1 h.2.2 h.1] congr 3 - exact Set.restrict_eq_iff.mpr hfg + exact Set.domRestrict_eq_iff.mpr hfg · simp only [not_and_or] at h obtain (ha | hg | h0) := h · simp [cfcₙ_apply_of_not_predicate a ha] @@ -475,7 +475,8 @@ lemma cfcₙ_comp (g f : R → R) (a : A) cfcₙ (g ∘ f) a = cfcₙ g (cfcₙ f a) := by have := hg.comp hf <| (σₙ R a).mapsTo_image f have sp_eq : - σₙ R (cfcₙHom (show p a from ha) ⟨ContinuousMap.mk _ hf.restrict, hf0⟩) = f '' (σₙ R a) := by + σₙ R (cfcₙHom (show p a from ha) ⟨ContinuousMap.mk _ hf.domRestrict, hf0⟩) = + f '' (σₙ R a) := by rw [cfcₙHom_map_quasispectrum (by exact ha) _] ext simp @@ -483,7 +484,8 @@ lemma cfcₙ_comp (g f : R → R) (a : A) cfcₙ_apply _ _ (by convert! hg) (ha := cfcₙHom_predicate (show p a from ha) _), ← cfcₙHom_comp _ _] swap - · exact ⟨.mk _ <| hf.restrict.codRestrict fun x ↦ by rw [sp_eq]; use x.1; simp, Subtype.ext hf0⟩ + · exact ⟨.mk _ <| hf.domRestrict.codRestrict fun x ↦ by rw [sp_eq]; use x.1; simp, + Subtype.ext hf0⟩ · congr · exact fun _ ↦ rfl diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean index 2bca9810f587b1..cf9eb7b98f6c36 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Range.lean @@ -89,7 +89,7 @@ theorem cfcHom_mem_elemental {a : A} (ha : p a) (f : C(spectrum 𝕜 a, 𝕜)) : theorem cfc_mem_elemental (f : 𝕜 → 𝕜) (a : A) : cfc f a ∈ elemental 𝕜 a := cfc_cases _ a f (zero_mem _) fun hf ha ↦ - cfcHom_mem_elemental ha ⟨_, hf.restrict⟩ + cfcHom_mem_elemental ha ⟨_, hf.domRestrict⟩ @[deprecated (since := "2026-03-20")] alias cfc_apply_mem_elemental := cfc_mem_elemental @@ -198,7 +198,7 @@ theorem cfcₙHom_mem_elemental {a : A} (ha : p a) (f : C(quasispectrum 𝕜 a, theorem cfcₙ_mem_elemental (f : 𝕜 → 𝕜) (a : A) : cfcₙ f a ∈ elemental 𝕜 a := cfcₙ_cases _ a f (zero_mem _) fun hf hf₀ ha ↦ - cfcₙHom_mem_elemental ha ⟨⟨_, hf.restrict⟩, hf₀⟩ + cfcₙHom_mem_elemental ha ⟨⟨_, hf.domRestrict⟩, hf₀⟩ @[deprecated (since := "2026-03-20")] alias cfcₙ_apply_mem_elemental := cfcₙ_mem_elemental diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean index d6c19e91ac41c8..45f381d02adc6a 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean @@ -475,7 +475,7 @@ lemma StarAlgHomClass.map_cfc (φ : F) (f : R → R) (a : A) suffices ψ.comp (cfcHom ha) = (cfcHom hψa).comp (ContinuousMap.compStarAlgHom' R R ι) by have hf' : ContinuousOn f (spectrum R (ψ a)) := hf.mono h_spec rw [cfc_apply .., cfc_apply ..] - congrm($(this) ⟨_, hf.restrict⟩) + congrm($(this) ⟨_, hf.domRestrict⟩) refine ContinuousMap.UniqueHom.eq_of_continuous_of_map_id _ _ _ ?_ ?_ ?apply_id case apply_id => trans cfcHom hψa (.restrict (spectrum R (ψ a)) (.id R)) diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean index e1daf6ea7a326d..a32d0687a18f6a 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean @@ -306,7 +306,7 @@ and all the API applies to this declaration. For more information, see the modul for `Analysis.CStarAlgebra.ContinuousFunctionalCalculus.Unital`. -/ noncomputable irreducible_def cfc (f : R → R) (a : A) : A := if h : p a ∧ ContinuousOn f (spectrum R a) - then cfcHom h.1 ⟨_, h.2.restrict⟩ + then cfcHom h.1 ⟨_, h.2.domRestrict⟩ else 0 variable (f g : R → R) (a : A) (ha : p a := by cfc_tac) @@ -314,12 +314,12 @@ variable (hf : ContinuousOn f (spectrum R a) := by cfc_cont_tac) variable (hg : ContinuousOn g (spectrum R a) := by cfc_cont_tac) set_option backward.privateInPublic true in -lemma cfc_apply : cfc f a = cfcHom (a := a) ha ⟨_, hf.restrict⟩ := by +lemma cfc_apply : cfc f a = cfcHom (a := a) ha ⟨_, hf.domRestrict⟩ := by rw [cfc_def, dif_pos ⟨ha, hf⟩] lemma cfc_apply_pi {ι : Type*} (f : ι → R → R) (a : A) (ha : p a := by cfc_tac) (hf : ∀ i, ContinuousOn (f i) (spectrum R a) := by cfc_cont_tac) : - (fun i => cfc (f i) a) = (fun i => cfcHom (a := a) ha ⟨_, (hf i).restrict⟩) := by + (fun i => cfc (f i) a) = (fun i => cfcHom (a := a) ha ⟨_, (hf i).domRestrict⟩) := by ext i simp only [cfc_apply (f i) a ha (hf i)] @@ -337,21 +337,21 @@ lemma cfc_apply_of_not_continuousOn {f : R → R} (a : A) (hf : ¬ ContinuousOn lemma cfcHom_eq_cfc_extend {a : A} (g : R → R) (ha : p a) (f : C(spectrum R a, R)) : cfcHom ha f = cfc (Function.extend Subtype.val f g) a := by - have h : f = (spectrum R a).restrict (Function.extend Subtype.val f g) := by + have h : f = (spectrum R a).domRestrict (Function.extend Subtype.val f g) := by ext; simp have hg : ContinuousOn (Function.extend Subtype.val f g) (spectrum R a) := - continuousOn_iff_continuous_restrict.mpr <| h ▸ map_continuous f + continuousOn_iff_continuous_domRestrict.mpr <| h ▸ map_continuous f rw [cfc_apply ..] congr! lemma cfc_eq_cfcL {a : A} {f : R → R} (ha : p a) (hf : ContinuousOn f (spectrum R a)) : - cfc f a = cfcL ha ⟨_, hf.restrict⟩ := by + cfc f a = cfcL ha ⟨_, hf.domRestrict⟩ := by rw [cfc_def, dif_pos ⟨ha, hf⟩, cfcL_apply] set_option backward.privateInPublic true in /-- A version of `cfc_apply` in terms of `ContinuousMap.mkD` -/ lemma cfc_apply_mkD : - cfc f a = cfcHom (a := a) ha (mkD ((spectrum R a).restrict f) 0) := by + cfc f a = cfcHom (a := a) ha (mkD ((spectrum R a).domRestrict f) 0) := by by_cases hf : ContinuousOn f (spectrum R a) · rw [cfc_apply f a, mkD_of_continuousOn hf] · rw [cfc_apply_of_not_continuousOn a hf, mkD_of_not_continuousOn hf, @@ -360,11 +360,11 @@ lemma cfc_apply_mkD : set_option backward.privateInPublic true in /-- A version of `cfc_eq_cfcL` in terms of `ContinuousMapZero.mkD` -/ lemma cfc_eq_cfcL_mkD : - cfc f a = cfcL (a := a) ha (mkD ((spectrum R a).restrict f) 0) := + cfc f a = cfcL (a := a) ha (mkD ((spectrum R a).domRestrict f) 0) := cfc_apply_mkD _ _ lemma cfc_cases (P : A → Prop) (a : A) (f : R → R) (h₀ : P 0) - (haf : (hf : ContinuousOn f (spectrum R a)) → (ha : p a) → P (cfcHom ha ⟨_, hf.restrict⟩)) : + (haf : (hf : ContinuousOn f (spectrum R a)) → (ha : p a) → P (cfcHom ha ⟨_, hf.domRestrict⟩)) : P (cfc f a) := by by_cases h : p a ∧ ContinuousOn f (spectrum R a) · rw [cfc_apply f a h.1 h.2] @@ -418,7 +418,7 @@ lemma cfc_congr {f g : R → R} {a : A} (hfg : (spectrum R a).EqOn f g) : by_cases h : p a ∧ ContinuousOn g (spectrum R a) · rw [cfc_apply (ha := h.1) (hf := h.2.congr hfg), cfc_apply (ha := h.1) (hf := h.2)] congr 2 - exact Set.restrict_eq_iff.mpr hfg + exact Set.domRestrict_eq_iff.mpr hfg · obtain (ha | hg) := not_and_or.mp h · simp [cfc_apply_of_not_predicate a ha] · rw [cfc_apply_of_not_continuousOn a hg, cfc_apply_of_not_continuousOn] @@ -604,7 +604,7 @@ lemma cfc_comp (g f : R → R) (a : A) (ha : p a := by cfc_tac) (hf : ContinuousOn f (spectrum R a) := by cfc_cont_tac) : cfc (g ∘ f) a = cfc g (cfc f a) := by have := hg.comp hf <| (spectrum R a).mapsTo_image f - have sp_eq : spectrum R (cfcHom (show p a from ha) (ContinuousMap.mk _ hf.restrict)) = + have sp_eq : spectrum R (cfcHom (show p a from ha) (ContinuousMap.mk _ hf.domRestrict)) = f '' (spectrum R a) := by rw [cfcHom_map_spectrum (by exact ha) _] ext @@ -612,7 +612,7 @@ lemma cfc_comp (g f : R → R) (a : A) (ha : p a := by cfc_tac) rw [cfc_apply .., cfc_apply f a, cfc_apply _ _ (cfcHom_predicate (show p a from ha) _) (by convert! hg), ← cfcHom_comp _ _] swap - · exact ContinuousMap.mk _ <| hf.restrict.codRestrict fun x ↦ by rw [sp_eq]; use x.1; simp + · exact ContinuousMap.mk _ <| hf.domRestrict.codRestrict fun x ↦ by rw [sp_eq]; use x.1; simp · congr · exact fun _ ↦ rfl diff --git a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean index 4276e5a0d0b4ad..69dcdb8498b138 100644 --- a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean +++ b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/ApproximatesLinearOn.lean @@ -109,15 +109,15 @@ theorem lipschitz_sub (hf : ApproximatesLinearOn f f' s c) : hf.lipschitzOnWith.to_restrict protected theorem lipschitz (hf : ApproximatesLinearOn f f' s c) : - LipschitzWith (‖f'‖₊ + c) (s.restrict f) := by - simpa only [restrict_apply, add_sub_cancel] using! + LipschitzWith (‖f'‖₊ + c) (s.domRestrict f) := by + simpa only [domRestrict_apply, add_sub_cancel] using! (f'.lipschitz.restrict s).add hf.lipschitz_sub -protected theorem continuous (hf : ApproximatesLinearOn f f' s c) : Continuous (s.restrict f) := +protected theorem continuous (hf : ApproximatesLinearOn f f' s c) : Continuous (s.domRestrict f) := hf.lipschitz.continuous protected theorem continuousOn (hf : ApproximatesLinearOn f f' s c) : ContinuousOn f s := - continuousOn_iff_continuous_restrict.2 hf.continuous + continuousOn_iff_continuous_domRestrict.2 hf.continuous end @@ -310,14 +310,14 @@ variable {f' : E ≃L[𝕜] F} {s : Set E} {c : ℝ≥0} local notation "N" => ‖(f'.symm : F →L[𝕜] E)‖₊ protected theorem antilipschitz (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) - (hc : Subsingleton E ∨ c < N⁻¹) : AntilipschitzWith (N⁻¹ - c)⁻¹ (s.restrict f) := by + (hc : Subsingleton E ∨ c < N⁻¹) : AntilipschitzWith (N⁻¹ - c)⁻¹ (s.domRestrict f) := by rcases hc with hE | hc · exact AntilipschitzWith.of_subsingleton - convert! (f'.antilipschitz.restrict s).add_lipschitzWith hf.lipschitz_sub hc - simp [restrict] + convert! (f'.antilipschitz.domRestrict s).add_lipschitzWith hf.lipschitz_sub hc + simp [domRestrict] protected theorem injective (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) - (hc : Subsingleton E ∨ c < N⁻¹) : Injective (s.restrict f) := + (hc : Subsingleton E ∨ c < N⁻¹) : Injective (s.domRestrict f) := (hf.antilipschitz hc).injective protected theorem injOn (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) @@ -353,7 +353,7 @@ def toPartialEquiv (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) Use properties of `OpenPartialHomeomorph` instead. -/ theorem inverse_continuousOn (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) (hc : Subsingleton E ∨ c < N⁻¹) : ContinuousOn (hf.toPartialEquiv hc).symm (f '' s) := by - apply continuousOn_iff_continuous_restrict.2 + apply continuousOn_iff_continuous_domRestrict.2 refine ((hf.antilipschitz hc).to_rightInvOn' ?_ (hf.toPartialEquiv hc).right_inv').continuous exact fun x hx => (hf.toPartialEquiv hc).map_target hx diff --git a/Mathlib/Analysis/Complex/BranchLogRoot.lean b/Mathlib/Analysis/Complex/BranchLogRoot.lean index ffcf8ac4c78979..3c3beb89fb1c79 100644 --- a/Mathlib/Analysis/Complex/BranchLogRoot.lean +++ b/Mathlib/Analysis/Complex/BranchLogRoot.lean @@ -44,13 +44,13 @@ theorem exists_continuousOn_eqOn_exp_comp (hUc : IsSimplyConnected U) (hUo : IsO have hx₀ : g x₀ ≠ 0 := ne_of_mem_of_not_mem (mem_image_of_mem g hx₀U) hU₀ lift x₀ to U using hx₀U rcases isCoveringMapOn_exp.existsUnique_continuousMap_lifts - ⟨U.restrict g, continuousOn_iff_continuous_restrict.mp hgc⟩ (exp_log hx₀) + ⟨U.domRestrict g, continuousOn_iff_continuous_domRestrict.mp hgc⟩ (exp_log hx₀) (fun x ↦ ne_of_mem_of_not_mem (mem_image_of_mem g x.2) hU₀) with ⟨f, ⟨-, hf⟩, -⟩ obtain ⟨g, hg⟩ : ∃ g : X → ℂ, ∀ z : U, g z = f z := ⟨fun z ↦ if hz : z ∈ U then f ⟨z, hz⟩ else 0, by simp⟩ refine ⟨g, ?hg_cont, ?hg_inv⟩ case hg_cont => - rw [continuousOn_iff_continuous_restrict] + rw [continuousOn_iff_continuous_domRestrict] convert! map_continuous f ext z exact hg z @@ -70,8 +70,8 @@ theorem exists_continuousOn_pow_eq (hUc : IsSimplyConnected U) (hUo : IsOpen U) classical rcases exists_continuousOn_eqOn_exp_comp hUc hUo hgc hU₀ with ⟨f, hfc, hf⟩ refine ⟨U.piecewise (exp <| f · / n) (g · ^ (1 / n : ℂ)), ?_, fun z ↦ ?_⟩ - · rw [continuousOn_iff_continuous_restrict, restrict_piecewise, - ← continuousOn_iff_continuous_restrict] + · rw [continuousOn_iff_continuous_domRestrict, domRestrict_piecewise, + ← continuousOn_iff_continuous_domRestrict] fun_prop · by_cases hz : z ∈ U · simp [hz, ← exp_nat_mul, mul_div_cancel₀ (b := ↑n) (f z) (mod_cast hn), ← hf hz, diff --git a/Mathlib/Analysis/Complex/Tietze.lean b/Mathlib/Analysis/Complex/Tietze.lean index c028b0a20e11e1..10e72d07abaaa5 100644 --- a/Mathlib/Analysis/Complex/Tietze.lean +++ b/Mathlib/Analysis/Complex/Tietze.lean @@ -17,7 +17,7 @@ There are two main results here: - `RCLike.instTietzeExtensionTVS`: finite-dimensional topological vector spaces over `ℝ` (or `ℂ`) have the Tietze extension property. -- `BoundedContinuousFunction.exists_norm_eq_restrict_eq`: when mapping into a finite-dimensional +- `BoundedContinuousFunction.exists_norm_eq_domRestrict_eq`: when mapping into a finite-dimensional normed vector space over `ℝ` (or `ℂ`), the extension can be chosen to preserve the norm of the bounded continuous function it extends. @@ -110,8 +110,8 @@ include 𝕜 hs in embedding and bundled composition. If `e : C(X, Y)` is a closed embedding of a topological space into a normal topological space and `f : X →ᵇ ℝ` is a bounded continuous function, then there exists a bounded continuous function `g : Y →ᵇ ℝ` of the same norm such that `g ∘ e = f`. -/ -theorem exists_norm_eq_restrict_eq (f : s →ᵇ E) : - ∃ g : X →ᵇ E, ‖g‖ = ‖f‖ ∧ g.restrict s = f := by +theorem exists_norm_eq_domRestrict_eq (f : s →ᵇ E) : + ∃ g : X →ᵇ E, ‖g‖ = ‖f‖ ∧ g.domRestrict s = f := by by_cases hf : ‖f‖ = 0; · exact ⟨0, by aesop⟩ have := Metric.instTietzeExtensionClosedBall.{u, v} 𝕜 (0 : E) (by simp_all : 0 < ‖f‖) have hf' x : f x ∈ Metric.closedBall 0 ‖f‖ := by simpa using! f.norm_coe_le_norm x @@ -125,4 +125,7 @@ theorem exists_norm_eq_restrict_eq (f : s →ᵇ E) : rw [hx] exact g'.norm_le (norm_nonneg g') |>.mp le_rfl x +@[deprecated (since := "2026-07-19")] +alias exists_norm_eq_restrict_eq := exists_norm_eq_domRestrict_eq + end BoundedContinuousFunction diff --git a/Mathlib/Analysis/Convex/Approximation.lean b/Mathlib/Analysis/Convex/Approximation.lean index 1e2ae788358a8d..5ed0b00ca15204 100644 --- a/Mathlib/Analysis/Convex/Approximation.lean +++ b/Mathlib/Analysis/Convex/Approximation.lean @@ -69,7 +69,7 @@ that `f ≤ φ` on `s` and `f x = a`. This is an auxiliary lemma used in the pro lemma exists_affine_le_of_lt {x : E} {a : ℝ} (hx : x ∈ s) (hax : a < φ x) (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), - s.restrict (re ∘ l) + const s c ≤ s.restrict φ ∧ re (l x) + c = a := by + s.domRestrict (re ∘ l) + const s c ≤ s.domRestrict φ ∧ re (l x) + c = a := by let A := { p : E × 𝕜 | p.1 ∈ s ∧ φ p.1 ≤ re p.2 } obtain ⟨L, ⟨b, hLb⟩⟩ := geometric_hahn_banach_point_closed (𝕜 := 𝕜) hφcv.convex_re_epigraph (hφc.isClosed_re_epigraph hsc) (by simp [A, hax] : (x, ofReal a) ∉ A) @@ -109,34 +109,34 @@ the supremum of a family of functions that are the restrictions to `s` of contin functions in `E`. -/ theorem sSup_affine_eq (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : - sSup {f | f ≤ s.restrict φ ∧ ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = s.restrict (re ∘ l) + const s c} = - s.restrict φ := by + sSup {f | f ≤ s.domRestrict φ ∧ + ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = s.domRestrict (re ∘ l) + const s c} = s.domRestrict φ := by let A := { p : E × 𝕜 | p.1 ∈ s ∧ φ p.1 ≤ re p.2 } ext x rw [sSup_apply] refine csSup_eq_of_forall_le_of_forall_lt_exists_gt ?_ (fun r ⟨f, hf⟩ => ?_) (fun r hr => ?_) · obtain ⟨l, c, hlc⟩ := exists_affine_le_of_lt (𝕜 := 𝕜) x.2 (show φ x - 1 < φ x by grind) hsc hφc hφcv - exact ⟨φ x - 1, hlc.2 ▸ ⟨⟨s.restrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩, rfl⟩⟩ + exact ⟨φ x - 1, hlc.2 ▸ ⟨⟨s.domRestrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩, rfl⟩⟩ · exact hf ▸ f.2.1 x · obtain ⟨z, hz⟩ := exists_between hr obtain ⟨l, c, hlc⟩ := exists_affine_le_of_lt (𝕜 := 𝕜) x.2 hz.2 hsc hφc hφcv - exact ⟨z, hlc.2 ▸ ⟨⟨s.restrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩, rfl⟩, hz.1⟩ + exact ⟨z, hlc.2 ▸ ⟨⟨s.domRestrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩, rfl⟩, hz.1⟩ /-- The countable version of `sSup_affine_eq`. -/ theorem sSup_of_countable_affine_eq [HereditarilyLindelofSpace E] (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : - ∃ 𝓕' : Set (s → ℝ), 𝓕'.Countable ∧ sSup 𝓕' = s.restrict φ ∧ - ∀ f ∈ 𝓕', f ≤ s.restrict φ ∧ - ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = s.restrict (re ∘ l) + const s c := by + ∃ 𝓕' : Set (s → ℝ), 𝓕'.Countable ∧ sSup 𝓕' = s.domRestrict φ ∧ + ∀ f ∈ 𝓕', f ≤ s.domRestrict φ ∧ + ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = s.domRestrict (re ∘ l) + const s c := by by_cases! hs : s.Nonempty - · let 𝓕 := {f | f ≤ s.restrict φ ∧ - ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = s.restrict (re ∘ l) + const s c} - have hl : IsLUB 𝓕 (s.restrict φ) := by + · let 𝓕 := {f | f ≤ s.domRestrict φ ∧ + ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = s.domRestrict (re ∘ l) + const s c} + have hl : IsLUB 𝓕 (s.domRestrict φ) := by refine (hφcv.sSup_affine_eq (𝕜 := 𝕜) hsc hφc) ▸ isLUB_csSup ?_ ?_ · obtain ⟨l, c, hlc⟩ := exists_affine_le_of_lt (𝕜 := 𝕜) hs.some_mem (by grind : φ hs.some - 1 < φ (⟨hs.some, hs.some_mem⟩ : s)) hsc hφc hφcv - exact ⟨s.restrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩ + exact ⟨s.domRestrict (re ∘ l) + const s c, hlc.1, l, c, rfl⟩ · exact (bddAbove_def.2 ⟨φ ∘ Subtype.val, fun y hy => hy.1⟩) have hr (f) (hf : f ∈ 𝓕) : LowerSemicontinuous f := by obtain ⟨l, c, hlc⟩ := hf.2 @@ -145,27 +145,28 @@ theorem sSup_of_countable_affine_eq [HereditarilyLindelofSpace E] (hsc : IsClose refine ⟨𝓕', h𝓕'.2.1, h𝓕'.2.2.csSup_eq ?_, fun f hf => h𝓕'.1 hf⟩ by_contra! grind [(isLUB_empty_iff.1 (this ▸ h𝓕'.2.2)) (fun x : s => φ x - 1) ⟨hs.some, hs.some_mem⟩] - · use ∅; simp [restrict_def]; grind + · use ∅; simp [domRestrict_def]; grind /-- The sequential version of `sSup_of_countable_affine_eq`. -/ theorem sSup_of_nat_affine_eq [HereditarilyLindelofSpace E] (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : ∃ (l : ℕ → E →L[𝕜] 𝕜) (c : ℕ → ℝ), - (∀ i, s.restrict (re ∘ (l i)) + const s (c i) ≤ s.restrict φ) ∧ - ⨆ i, s.restrict (re ∘ (l i)) + const s (c i) = s.restrict φ := by + (∀ i, s.domRestrict (re ∘ (l i)) + const s (c i) ≤ s.domRestrict φ) ∧ + ⨆ i, s.domRestrict (re ∘ (l i)) + const s (c i) = s.domRestrict φ := by obtain ⟨𝓕', h𝓕'⟩ := hφcv.sSup_of_countable_affine_eq (𝕜 := 𝕜) hsc hφc by_cases! he : 𝓕'.Nonempty · obtain ⟨f, hf⟩ := h𝓕'.1.exists_eq_range he - have (i : ℕ) : ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f i = s.restrict (re ∘ l) + const s c := by simp_all + have (i : ℕ) : ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), + f i = s.domRestrict (re ∘ l) + const s c := by simp_all choose l c hlc using this refine ⟨l, c, fun i => (hlc i) ▸ (h𝓕'.2.2 (f i) (hf ▸ mem_range_self i)).1, ?_⟩ calc _ = ⨆ i, f i := by congr with i x; exact congrFun (hlc i).symm x _ = _ := by rw [← sSup_range, ← hf, h𝓕'.2.1] - · by_cases! hsφ : s.restrict φ = 0 + · by_cases! hsφ : s.domRestrict φ = 0 · have := congrFun hsφ refine ⟨fun _ => 0, fun _ => 0, ?_, ?_⟩ - · simp_all [restrict_def] + · simp_all [domRestrict_def] · ext; simp_all · obtain ⟨x, hx⟩ := Function.ne_iff.1 hsφ have : s = ∅ := by have := congrFun h𝓕'.2.1 x; simp_all @@ -178,7 +179,7 @@ theorem univ_sSup_affine_eq (hφc : LowerSemicontinuous φ) (hφcv : ConvexOn let 𝓕 := {f | f ≤ φ ∘ Subtype.val ∧ ∃ (l : E →L[𝕜] 𝕜) (c : ℝ), f = (re ∘ l) ∘ Subtype.val + const univ c} have := hφcv.sSup_affine_eq (𝕜 := 𝕜) isClosed_univ (lowerSemicontinuousOn_univ_iff.2 hφc) - simp only [restrict_eq] at this + simp only [domRestrict_eq] at this calc _ = sSup ((fun g => g ∘ (Equiv.Set.univ E).symm) '' 𝓕) := by congr @@ -236,23 +237,23 @@ variable [AddCommGroup E] [Module ℝ E] [IsTopologicalAddGroup E] [ContinuousSM /-- The real version of `sSup_affine_eq`. -/ theorem real_sSup_affine_eq (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : - sSup {f | f ≤ s.restrict φ ∧ ∃ (l : E →L[ℝ] ℝ) (c : ℝ), f = s.restrict l + const s c} = - s.restrict φ := + sSup {f | f ≤ s.domRestrict φ ∧ + ∃ (l : E →L[ℝ] ℝ) (c : ℝ), f = s.domRestrict l + const s c} = s.domRestrict φ := sSup_affine_eq (𝕜 := ℝ) hsc hφc hφcv /-- The real version of `sSup_of_countable_affine_eq`. -/ theorem real_sSup_of_countable_affine_eq [HereditarilyLindelofSpace E] (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : - ∃ 𝓕' : Set (s → ℝ), 𝓕'.Countable ∧ sSup 𝓕' = s.restrict φ ∧ - ∀ f ∈ 𝓕', f ≤ s.restrict φ ∧ ∃ (l : E →L[ℝ] ℝ) (c : ℝ), f = s.restrict l + const s c := + ∃ 𝓕' : Set (s → ℝ), 𝓕'.Countable ∧ sSup 𝓕' = s.domRestrict φ ∧ + ∀ f ∈ 𝓕', f ≤ s.domRestrict φ ∧ ∃ (l : E →L[ℝ] ℝ) (c : ℝ), f = s.domRestrict l + const s c := sSup_of_countable_affine_eq (𝕜 := ℝ) hsc hφc hφcv /-- The real version of `sSup_of_nat_affine_eq`. -/ theorem real_sSup_of_nat_affine_eq [HereditarilyLindelofSpace E] (hsc : IsClosed s) (hφc : LowerSemicontinuousOn φ s) (hφcv : ConvexOn ℝ s φ) : ∃ (l : ℕ → E →L[ℝ] ℝ) (c : ℕ → ℝ), - (∀ i, s.restrict (l i) + const s (c i) ≤ s.restrict φ) ∧ - ⨆ i, s.restrict (l i) + const s (c i) = s.restrict φ := + (∀ i, s.domRestrict (l i) + const s (c i) ≤ s.domRestrict φ) ∧ + ⨆ i, s.domRestrict (l i) + const s (c i) = s.domRestrict φ := sSup_of_nat_affine_eq (𝕜 := ℝ) hsc hφc hφcv /-- The real version of `univ_sSup_affine_eq`. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index f3570d174fc542..a938a909f274d3 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -1046,15 +1046,16 @@ theorem Orthonormal.exists_orthonormalBasis_extension (hv : Orthonormal 𝕜 (( theorem Orthonormal.exists_orthonormalBasis_extension_of_card_eq {ι : Type*} [Fintype ι] (card_ι : finrank 𝕜 E = Fintype.card ι) {v : ι → E} {s : Set ι} - (hv : Orthonormal 𝕜 (s.restrict v)) : ∃ b : OrthonormalBasis ι 𝕜 E, ∀ i ∈ s, b i = v i := by - have hsv : Injective (s.restrict v) := hv.linearIndependent.injective - have hX : Orthonormal 𝕜 ((↑) : Set.range (s.restrict v) → E) := by + (hv : Orthonormal 𝕜 (s.domRestrict v)) : + ∃ b : OrthonormalBasis ι 𝕜 E, ∀ i ∈ s, b i = v i := by + have hsv : Injective (s.domRestrict v) := hv.linearIndependent.injective + have hX : Orthonormal 𝕜 ((↑) : Set.range (s.domRestrict v) → E) := by rwa [orthonormal_subtype_range hsv] obtain ⟨Y, b₀, hX, hb₀⟩ := hX.exists_orthonormalBasis_extension have hιY : Fintype.card ι = Y.card := by refine card_ι.symm.trans ?_ exact Module.finrank_eq_card_finset_basis b₀.toBasis - have hvsY : s.MapsTo v Y := (s.mapsTo_image v).mono_right (by rwa [← range_restrict]) + have hvsY : s.MapsTo v Y := (s.mapsTo_image v).mono_right (by rwa [← range_domRestrict]) have hsv' : Set.InjOn v s := by rw [Set.injOn_iff_injective] exact hsv diff --git a/Mathlib/Analysis/Matrix/HermitianFunctionalCalculus.lean b/Mathlib/Analysis/Matrix/HermitianFunctionalCalculus.lean index 0da2a279b0fdd5..4db359d9b8c1ec 100644 --- a/Mathlib/Analysis/Matrix/HermitianFunctionalCalculus.lean +++ b/Mathlib/Analysis/Matrix/HermitianFunctionalCalculus.lean @@ -144,8 +144,8 @@ lemma cfc_eq (f : ℝ → ℝ) : cfc f A = hA.cfc f := by have hA' : IsSelfAdjoint A := hA have := cfcHom_eq_of_continuous_of_map_id hA' hA.cfcAux hA.isClosedEmbedding_cfcAux.continuous hA.cfcAux_id - rw [cfc_apply f A hA' (by rw [continuousOn_iff_continuous_restrict]; fun_prop), this] - simp only [cfcAux_apply, ContinuousMap.coe_mk, Function.comp_def, Set.restrict_apply, + rw [cfc_apply f A hA' (by rw [continuousOn_iff_continuous_domRestrict]; fun_prop), this] + simp only [cfcAux_apply, ContinuousMap.coe_mk, Function.comp_def, Set.domRestrict_apply, IsHermitian.cfc] open Polynomial in diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index bdaba3855399e1..560e866ba86d6c 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -755,6 +755,6 @@ Meromorphic functions are measurable. have h₂ : IsOpen s := isOpen_analyticAt 𝕜 f have h₃ : ContinuousOn f s := fun z hz ↦ hz.continuousAt.continuousWithinAt exact .of_union_range_cover (.subtype_coe h₂.measurableSet) (.subtype_coe h₁.measurableSet) - (by simp [-mem_compl_iff]) h₃.restrict.measurable (measurable_of_countable _) + (by simp [-mem_compl_iff]) h₃.domRestrict.measurable (measurable_of_countable _) end Meromorphic diff --git a/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean b/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean index a57b8fa378a933..11855889c53cd9 100644 --- a/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean +++ b/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean @@ -93,7 +93,7 @@ lemma hasProdUniformlyOn_one_add (hK : IsCompact K) (hu : Summable u) · simp [TendstoUniformly, hKe] · have hCK : CompactSpace K := isCompact_iff_compactSpace.mp hK have hne : Nonempty K := by rwa [Set.nonempty_coe_sort, Set.nonempty_iff_ne_empty] - let f' i : C(K, R) := ⟨_, continuousOn_iff_continuous_restrict.mp (hcts i)⟩ + let f' i : C(K, R) := ⟨_, continuousOn_iff_continuous_domRestrict.mp (hcts i)⟩ have hf'_bd : ∀ᶠ i in cofinite, ‖f' i‖ ≤ u i := by simp only [ContinuousMap.norm_le_of_nonempty] filter_upwards [h] with i hi using fun x ↦ hi x x.2 diff --git a/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean b/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean index 7564999c818a43..2821b3a2c07dff 100644 --- a/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean +++ b/Mathlib/Analysis/Normed/Operator/Perturbation/StrictByFinite.lean @@ -299,7 +299,7 @@ public theorem ContinuousLinearMap.isStrictMap_isClosed_range_iff_of_eqOn [T2Spa simp_rw [u.isStrictMap_isClosed_range_iff_restrict _ A.isClosed_topologicalClosure, v.isStrictMap_isClosed_range_iff_restrict _ A.isClosed_topologicalClosure, LinearMap.coe_range, ContinuousLinearMap.coe_coe, ContinuousLinearMap.coe_domRestrict, - restrict_eq_restrict_iff.mpr h_eqOn] + domRestrict_eq_domRestrict_iff.mpr h_eqOn] open LinearMap.FiniteRangeSetoid diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index a35cf9821d420d..2776daac653ac8 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -361,20 +361,20 @@ lemma tendsto_log_nhdsLT_zero : Tendsto log (𝓝[<] 0) atBot := tendsto_log_nhdsNE_zero.mono_left <| nhdsWithin_mono _ fun _ h ↦ ne_of_lt h theorem continuousOn_log : ContinuousOn log {0}ᶜ := by - simp +unfoldPartialApp only [continuousOn_iff_continuous_restrict, - restrict] + simp +unfoldPartialApp only [continuousOn_iff_continuous_domRestrict, + domRestrict] conv in log _ => rw [log_of_ne_zero (show (x : ℝ) ≠ 0 from x.2)] exact expOrderIso.symm.continuous.comp (continuous_subtype_val.norm.subtype_mk _) /-- The real logarithm is continuous as a function from nonzero reals. -/ @[fun_prop] theorem continuous_log : Continuous fun x : { x : ℝ // x ≠ 0 } => log x := - continuousOn_iff_continuous_restrict.1 <| continuousOn_log.mono fun _ => id + continuousOn_iff_continuous_domRestrict.1 <| continuousOn_log.mono fun _ => id /-- The real logarithm is continuous as a function from positive reals. -/ @[fun_prop] theorem continuous_log' : Continuous fun x : { x : ℝ // 0 < x } => log x := - continuousOn_iff_continuous_restrict.1 <| continuousOn_log.mono fun _ hx => ne_of_gt hx + continuousOn_iff_continuous_domRestrict.1 <| continuousOn_log.mono fun _ hx => ne_of_gt hx theorem continuousAt_log (hx : x ≠ 0) : ContinuousAt log x := (continuousOn_log x hx).continuousAt <| isOpen_compl_singleton.mem_nhds hx diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean index 82c11e2b416ee9..dc89658bb21aeb 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean @@ -74,7 +74,7 @@ theorem continuousOn_tan : ContinuousOn tan {x | cos x ≠ 0} := by @[continuity] theorem continuous_tan : Continuous fun x : {x | cos x ≠ 0} => tan x := - continuousOn_iff_continuous_restrict.1 continuousOn_tan + continuousOn_iff_continuous_domRestrict.1 continuousOn_tan theorem continuousOn_tan_Ioo : ContinuousOn tan (Ioo (-(π / 2)) (π / 2)) := by refine ContinuousOn.mono continuousOn_tan fun x => ?_ diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean index 940d207a167d3a..d9b4042693f612 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean @@ -219,7 +219,7 @@ theorem continuousOn_tan : ContinuousOn tan {x | cos x ≠ 0} := @[continuity] theorem continuous_tan : Continuous fun x : {x | cos x ≠ 0} => tan x := - continuousOn_iff_continuous_restrict.1 continuousOn_tan + continuousOn_iff_continuous_domRestrict.1 continuousOn_tan theorem cos_eq_iff_quadratic {z w : ℂ} : cos z = w ↔ exp (z * I) ^ 2 - 2 * w * exp (z * I) + 1 = 0 := by diff --git a/Mathlib/Combinatorics/Matroid/Map.lean b/Mathlib/Combinatorics/Matroid/Map.lean index 09be193481e7b0..02bb34d456264e 100644 --- a/Mathlib/Combinatorics/Matroid/Map.lean +++ b/Mathlib/Combinatorics/Matroid/Map.lean @@ -344,7 +344,7 @@ def map (M : Matroid α) (f : α → β) (hf : InjOn f M.E) : Matroid β := Matr (Indep := fun I ↦ ∃ I₀, M.Indep I₀ ∧ I = f '' I₀) (hM := by refine ⟨M.mapSetEmbedding ⟨_, hf.injective⟩, by simp, fun I ↦ ?_⟩ - simp_rw [mapSetEmbedding_indep_iff', Embedding.coeFn_mk, restrict_apply, + simp_rw [mapSetEmbedding_indep_iff', Embedding.coeFn_mk, domRestrict_apply, ← image_image f Subtype.val, Subtype.exists_set_subtype (p := fun J ↦ M.Indep J ∧ I = f '' J)] exact ⟨fun ⟨I₀, _, hI₀⟩ ↦ ⟨I₀, hI₀⟩, fun ⟨I₀, hI₀⟩ ↦ ⟨I₀, hI₀.1.subset_ground, hI₀⟩⟩) diff --git a/Mathlib/Data/Finset/Pi.lean b/Mathlib/Data/Finset/Pi.lean index 02a23d4c580540..4bc2a8e1b54ebf 100644 --- a/Mathlib/Data/Finset/Pi.lean +++ b/Mathlib/Data/Finset/Pi.lean @@ -164,11 +164,14 @@ theorem restrict_def (s : Finset ι) : s.restrict (π := π) = fun f x ↦ f x : variable {s t u : Finset ι} -theorem _root_.Set.piCongrLeft_comp_restrict : - (s.equivToSet.symm.piCongrLeft (fun i : s ↦ π i)) ∘ (s : Set ι).restrict = s.restrict := rfl +theorem _root_.Set.piCongrLeft_comp_domRestrict : + (s.equivToSet.symm.piCongrLeft (fun i : s ↦ π i)) ∘ (s : Set ι).domRestrict = s.restrict := rfl + +@[deprecated (since := "2026-07-19")] +alias _root_.Set.piCongrLeft_comp_restrict := _root_.Set.piCongrLeft_comp_domRestrict theorem piCongrLeft_comp_restrict : - (s.equivToSet.piCongrLeft (fun i : s ↦ π i)) ∘ s.restrict = (s : Set ι).restrict := rfl + (s.equivToSet.piCongrLeft (fun i : s ↦ π i)) ∘ s.restrict = (s : Set ι).domRestrict := rfl /-- If a function `f` is restricted to a finite set `t`, and `s ⊆ t`, this is the restriction to `s`. -/ @@ -184,7 +187,7 @@ theorem restrict₂_comp_restrict₂ (hst : s ⊆ t) (htu : t ⊆ u) : (restrict₂ (π := π) hst) ∘ (restrict₂ htu) = restrict₂ (hst.trans htu) := rfl lemma dependsOn_restrict (s : Finset ι) : DependsOn (s.restrict (π := π)) s := - (s : Set ι).dependsOn_restrict + (s : Set ι).dependsOn_domRestrict lemma restrict_preimage_univ [DecidablePred (· ∈ s)] (t : (i : s) → Set (π i)) : s.restrict ⁻¹' (Set.univ.pi t) = @@ -192,12 +195,14 @@ lemma restrict_preimage_univ [DecidablePred (· ∈ s)] (t : (i : s) → Set (π ext simp_all -lemma restrict_preimage [DecidableEq ι] {I : Set ι} +lemma domRestrict_preimage [DecidableEq ι] {I : Set ι} [DecidablePred (· ∈ I)] (s : Finset I) (u : (i : I) → Set (π i)) : - I.restrict ⁻¹' Set.pi s u = + I.domRestrict ⁻¹' Set.pi s u = Set.pi (s.image Subtype.val) (fun i ↦ if h : i ∈ I then u ⟨i, h⟩ else .univ) := by grind +@[deprecated (since := "2026-07-19")] alias restrict_preimage := domRestrict_preimage + lemma restrict₂_preimage [DecidablePred (· ∈ s)] (hst : s ⊆ t) (u : (i : s) → Set (π i)) : (restrict₂ hst) ⁻¹' (Set.univ.pi u) = (@Set.univ t).pi (fun j ↦ if h : j.1 ∈ s then u ⟨j.1, h⟩ else Set.univ) := by diff --git a/Mathlib/Data/Fintype/Inv.lean b/Mathlib/Data/Fintype/Inv.lean index 721acc048bcf87..4955764aea0eb6 100644 --- a/Mathlib/Data/Fintype/Inv.lean +++ b/Mathlib/Data/Fintype/Inv.lean @@ -59,7 +59,7 @@ theorem left_inv_of_invOfMemRange (b : Set.range f) : f (hf.invOfMemRange b) = b theorem right_inv_of_invOfMemRange (a : α) : hf.invOfMemRange ⟨f a, Set.mem_range_self a⟩ = a := hf (Finset.choose_spec (fun a' => f a' = f a) _ _).right -theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = hf.invOfMemRange := by +theorem invFun_restrict [Nonempty α] : (Set.range f).domRestrict (invFun f) = hf.invOfMemRange := by ext ⟨b, h⟩ apply hf simp [hf.left_inv_of_invOfMemRange, @invFun_eq _ _ _ f b (Set.mem_range.mp h)] @@ -92,7 +92,7 @@ theorem left_inv_of_invOfMemRange : f (f.invOfMemRange b) = b := theorem right_inv_of_invOfMemRange (a : α) : f.invOfMemRange ⟨f a, Set.mem_range_self a⟩ = a := f.injective.right_inv_of_invOfMemRange a -theorem invFun_restrict [Nonempty α] : (Set.range f).restrict (invFun f) = f.invOfMemRange := by +theorem invFun_restrict [Nonempty α] : (Set.range f).domRestrict (invFun f) = f.invOfMemRange := by ext ⟨b, h⟩ apply f.injective simp [f.left_inv_of_invOfMemRange, @invFun_eq _ _ _ f b (Set.mem_range.mp h)] diff --git a/Mathlib/Data/Set/Finite/Basic.lean b/Mathlib/Data/Set/Finite/Basic.lean index a56b1b759e3b7c..ad8fe01d4490f1 100644 --- a/Mathlib/Data/Set/Finite/Basic.lean +++ b/Mathlib/Data/Set/Finite/Basic.lean @@ -917,7 +917,7 @@ theorem not_injOn_infinite_finite_image {f : α → β} {s : Set α} (h_inf : s. have : Finite (f '' s) := finite_coe_iff.mpr h_fin have : Infinite s := infinite_coe_iff.mpr h_inf have h := not_injective_infinite_finite - ((f '' s).codRestrict (s.restrict f) fun x => ⟨x, x.property, rfl⟩) + ((f '' s).codRestrict (s.domRestrict f) fun x => ⟨x, x.property, rfl⟩) contrapose h rwa [injective_codRestrict, ← injOn_iff_injective] diff --git a/Mathlib/Data/Set/Functor.lean b/Mathlib/Data/Set/Functor.lean index 0f503b76ec6d22..81676ac0a58c5e 100644 --- a/Mathlib/Data/Set/Functor.lean +++ b/Mathlib/Data/Set/Functor.lean @@ -130,10 +130,13 @@ theorem mem_of_mem_coe {a : α} (ha : a ∈ (γ : Set α)) : ⟨a, coe_subset ha theorem eq_univ_of_coe_eq (hγ : (γ : Set α) = β) : γ = univ := eq_univ_of_forall fun ⟨_, ha⟩ => mem_of_mem_coe <| hγ.symm ▸ ha -theorem image_coe_eq_restrict_image {δ : Type*} {f : α → δ} : f '' γ = β.restrict f '' γ := +theorem image_coe_eq_domRestrict_image {δ : Type*} {f : α → δ} : f '' γ = β.domRestrict f '' γ := ext fun _ => ⟨fun ⟨_, h, ha⟩ => ⟨_, mem_of_mem_coe h, ha⟩, fun ⟨_, h, ha⟩ => ⟨_, mem_coe_of_mem _ h, ha⟩⟩ +@[deprecated (since := "2026-07-19")] +alias image_coe_eq_restrict_image := image_coe_eq_domRestrict_image + end with_instance /-! ### Coercion applying functoriality for `Subtype.val` @@ -162,9 +165,13 @@ theorem mem_of_mem_image_val (ha : a ∈ (γ : Set α)) : ⟨a, image_val_subset theorem eq_univ_of_image_val_eq (hγ : (γ : Set α) = β) : γ = univ := eq_univ_of_forall fun ⟨_, ha⟩ => mem_of_mem_image_val <| hγ.symm ▸ ha -theorem image_image_val_eq_restrict_image {δ : Type*} {f : α → δ} : f '' γ = β.restrict f '' γ := by +theorem image_image_val_eq_domRestrict_image {δ : Type*} {f : α → δ} : + f '' γ = β.domRestrict f '' γ := by ext; simp +@[deprecated (since := "2026-07-19")] +alias image_image_val_eq_restrict_image := image_image_val_eq_domRestrict_image + end Set /-! ### Wrapper to enable the `Set` monad -/ diff --git a/Mathlib/Data/Set/Monotone.lean b/Mathlib/Data/Set/Monotone.lean index c367d3d931025f..693f62507ec01d 100644 --- a/Mathlib/Data/Set/Monotone.lean +++ b/Mathlib/Data/Set/Monotone.lean @@ -112,8 +112,10 @@ namespace Monotone variable [Preorder α] [Preorder β] {f : α → β} -protected theorem restrict (h : Monotone f) (s : Set α) : Monotone (s.restrict f) := fun _ _ hxy => - h hxy +protected theorem domRestrict (h : Monotone f) (s : Set α) : Monotone (s.domRestrict f) := + fun _ _ hxy => h hxy + +@[deprecated (since := "2026-07-19")] alias restrict := Monotone.domRestrict protected theorem codRestrict (h : Monotone f) {s : Set β} (hs : ∀ x, f x ∈ s) : Monotone (s.codRestrict f hs) := @@ -129,10 +131,16 @@ section strictMono variable [Preorder α] [Preorder β] {f : α → β} {s : Set α} @[simp] -theorem strictMono_restrict : - StrictMono (s.restrict f) ↔ StrictMonoOn f s := by simp [Set.restrict, StrictMono, StrictMonoOn] +theorem strictMono_domRestrict : StrictMono (s.domRestrict f) ↔ StrictMonoOn f s := by + simp [Set.domRestrict, StrictMono, StrictMonoOn] + +alias ⟨_root_.StrictMono.of_domRestrict, _root_.StrictMonoOn.domRestrict⟩ := strictMono_domRestrict -alias ⟨_root_.StrictMono.of_restrict, _root_.StrictMonoOn.restrict⟩ := strictMono_restrict +@[deprecated (since := "2026-07-19")] alias strictMono_restrict := strictMono_domRestrict +@[deprecated (since := "2026-07-19")] +alias _root_.StrictMono.of_restrict := _root_.StrictMono.of_domRestrict +@[deprecated (since := "2026-07-19")] +alias _root_.StrictMonoOn.restrict := _root_.StrictMonoOn.domRestrict theorem StrictMono.codRestrict (hf : StrictMono f) {s : Set β} (hs : ∀ x, f x ∈ s) : StrictMono (Set.codRestrict f s hs) := diff --git a/Mathlib/Data/Set/Restrict.lean b/Mathlib/Data/Set/Restrict.lean index 684e2299f861bb..efa8e9ee08c862 100644 --- a/Mathlib/Data/Set/Restrict.lean +++ b/Mathlib/Data/Set/Restrict.lean @@ -12,7 +12,7 @@ public import Mathlib.Data.Set.Image ## Main definitions -* `Set.restrict f s` : restrict the domain of `f` to the set `s`; +* `Set.domRestrict f s` : restrict the domain of `f` to the set `s`; * `Set.codRestrict f s h` : given `h : ∀ x, f x ∈ s`, restrict the codomain of `f` to the set `s`; -/ @@ -24,96 +24,94 @@ open Equiv Equiv.Perm Function namespace Set -/-! ### Restrict -/ -section restrict +/-! ### Domain restriction -/ +section domRestrict /-- Restrict domain of a function `f` to a set `s`. Same as `Subtype.restrict` but this version takes an argument `↥s` instead of `Subtype s`. -/ -def restrict (s : Set α) (f : ∀ a : α, π a) : ∀ a : s, π a := fun x => f x +def domRestrict (s : Set α) (f : ∀ a : α, π a) : ∀ a : s, π a := fun x => f x -theorem restrict_def (s : Set α) : s.restrict (π := π) = fun f x ↦ f x := rfl +theorem domRestrict_def (s : Set α) : s.domRestrict (π := π) = fun f x ↦ f x := rfl -theorem restrict_eq (f : α → β) (s : Set α) : s.restrict f = f ∘ Subtype.val := +theorem domRestrict_eq (f : α → β) (s : Set α) : s.domRestrict f = f ∘ Subtype.val := rfl -@[simp] lemma restrict_id (s : Set α) : restrict s id = Subtype.val := rfl +@[simp] lemma domRestrict_id (s : Set α) : domRestrict s id = Subtype.val := rfl @[simp, grind =] -theorem restrict_apply (f : (a : α) → π a) (s : Set α) (x : s) : s.restrict f x = f x := +theorem domRestrict_apply (f : (a : α) → π a) (s : Set α) (x : s) : s.domRestrict f x = f x := rfl -theorem restrict_eq_iff {f : ∀ a, π a} {s : Set α} {g : ∀ a : s, π a} : - restrict s f = g ↔ ∀ (a) (ha : a ∈ s), f a = g ⟨a, ha⟩ := +theorem domRestrict_eq_iff {f : ∀ a, π a} {s : Set α} {g : ∀ a : s, π a} : + domRestrict s f = g ↔ ∀ (a) (ha : a ∈ s), f a = g ⟨a, ha⟩ := funext_iff.trans Subtype.forall -theorem eq_restrict_iff {s : Set α} {f : ∀ a : s, π a} {g : ∀ a, π a} : - f = restrict s g ↔ ∀ (a) (ha : a ∈ s), f ⟨a, ha⟩ = g a := +theorem eq_domRestrict_iff {s : Set α} {f : ∀ a : s, π a} {g : ∀ a, π a} : + f = domRestrict s g ↔ ∀ (a) (ha : a ∈ s), f ⟨a, ha⟩ = g a := funext_iff.trans Subtype.forall @[simp] -theorem range_restrict (f : α → β) (s : Set α) : Set.range (s.restrict f) = f '' s := +theorem range_domRestrict (f : α → β) (s : Set α) : Set.range (s.domRestrict f) = f '' s := (range_comp _ _).trans <| congr_arg (f '' ·) Subtype.range_coe -theorem image_restrict (f : α → β) (s t : Set α) : - s.restrict f '' Subtype.val ⁻¹' t = f '' (t ∩ s) := by - rw [restrict_eq, image_comp, image_preimage_eq_inter_range, Subtype.range_coe] +theorem image_domRestrict (f : α → β) (s t : Set α) : + s.domRestrict f '' Subtype.val ⁻¹' t = f '' (t ∩ s) := by + rw [domRestrict_eq, image_comp, image_preimage_eq_inter_range, Subtype.range_coe] @[simp] -theorem restrict_dite {s : Set α} [∀ x, Decidable (x ∈ s)] (f : ∀ a ∈ s, β) +theorem domRestrict_dite {s : Set α} [∀ x, Decidable (x ∈ s)] (f : ∀ a ∈ s, β) (g : ∀ a ∉ s, β) : - (s.restrict fun a => if h : a ∈ s then f a h else g a h) = (fun a : s => f a a.2) := + (s.domRestrict fun a => if h : a ∈ s then f a h else g a h) = (fun a : s => f a a.2) := funext fun a => dif_pos a.2 @[simp] -theorem restrict_dite_compl {s : Set α} [∀ x, Decidable (x ∈ s)] (f : ∀ a ∈ s, β) +theorem domRestrict_dite_compl {s : Set α} [∀ x, Decidable (x ∈ s)] (f : ∀ a ∈ s, β) (g : ∀ a ∉ s, β) : - (sᶜ.restrict fun a => if h : a ∈ s then f a h else g a h) = (fun a : (sᶜ : Set α) => g a a.2) := + (sᶜ.domRestrict fun a => if h : a ∈ s then f a h else g a h) = + (fun a : (sᶜ : Set α) => g a a.2) := funext fun a => dif_neg a.2 @[simp] -theorem restrict_ite (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : - (s.restrict fun a => if a ∈ s then f a else g a) = s.restrict f := - restrict_dite _ _ +theorem domRestrict_ite (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : + (s.domRestrict fun a => if a ∈ s then f a else g a) = s.domRestrict f := domRestrict_dite _ _ @[simp] -theorem restrict_ite_compl (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : - (sᶜ.restrict fun a => if a ∈ s then f a else g a) = sᶜ.restrict g := - restrict_dite_compl _ _ +theorem domRestrict_ite_compl (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : + (sᶜ.domRestrict fun a => if a ∈ s then f a else g a) = sᶜ.domRestrict g := + domRestrict_dite_compl _ _ @[simp] -theorem restrict_piecewise (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : - s.restrict (piecewise s f g) = s.restrict f := - restrict_ite _ _ _ +theorem domRestrict_piecewise (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : + s.domRestrict (piecewise s f g) = s.domRestrict f := domRestrict_ite _ _ _ @[simp] -theorem restrict_piecewise_compl (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : - sᶜ.restrict (piecewise s f g) = sᶜ.restrict g := - restrict_ite_compl _ _ _ +theorem domRestrict_piecewise_compl (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : + sᶜ.domRestrict (piecewise s f g) = sᶜ.domRestrict g := domRestrict_ite_compl _ _ _ -theorem restrict_extend_range (f : α → β) (g : α → γ) (g' : β → γ) : - (range f).restrict (extend f g g') = fun x => g x.coe_prop.choose := by +theorem domRestrict_extend_range (f : α → β) (g : α → γ) (g' : β → γ) : + (range f).domRestrict (extend f g g') = fun x => g x.coe_prop.choose := by classical - exact restrict_dite _ _ + exact domRestrict_dite _ _ @[simp] -theorem restrict_extend_compl_range (f : α → β) (g : α → γ) (g' : β → γ) : - (range f)ᶜ.restrict (extend f g g') = g' ∘ Subtype.val := by +theorem domRestrict_extend_compl_range (f : α → β) (g : α → γ) (g' : β → γ) : + (range f)ᶜ.domRestrict (extend f g g') = g' ∘ Subtype.val := by classical - exact restrict_dite_compl _ _ + exact domRestrict_dite_compl _ _ /-- If a function `f` is restricted to a set `t`, and `s ⊆ t`, this is the restriction to `s`. -/ @[simp] -def restrict₂ {s t : Set α} (hst : s ⊆ t) (f : ∀ a : t, π a) : ∀ a : s, π a := +def domRestrict₂ {s t : Set α} (hst : s ⊆ t) (f : ∀ a : t, π a) : ∀ a : s, π a := fun x => f ⟨x.1, hst x.2⟩ -theorem restrict₂_def {s t : Set α} (hst : s ⊆ t) : - restrict₂ (π := π) hst = fun f x ↦ f ⟨x.1, hst x.2⟩ := rfl +theorem domRestrict₂_def {s t : Set α} (hst : s ⊆ t) : + domRestrict₂ (π := π) hst = fun f x ↦ f ⟨x.1, hst x.2⟩ := rfl -theorem restrict₂_comp_restrict {s t : Set α} (hst : s ⊆ t) : - (restrict₂ (π := π) hst) ∘ t.restrict = s.restrict := rfl +theorem domRestrict₂_comp_domRestrict {s t : Set α} (hst : s ⊆ t) : + (domRestrict₂ (π := π) hst) ∘ t.domRestrict = s.domRestrict := rfl -theorem restrict₂_comp_restrict₂ {s t u : Set α} (hst : s ⊆ t) (htu : t ⊆ u) : - (restrict₂ (π := π) hst) ∘ (restrict₂ htu) = restrict₂ (hst.trans htu) := rfl +theorem domRestrict₂_comp_domRestrict₂ {s t u : Set α} (hst : s ⊆ t) (htu : t ⊆ u) : + (domRestrict₂ (π := π) hst) ∘ (domRestrict₂ htu) = domRestrict₂ (hst.trans htu) := rfl theorem range_extend_subset (f : α → β) (g : α → γ) (g' : β → γ) : range (extend f g g') ⊆ range g ∪ g' '' (range f)ᶜ := by @@ -154,8 +152,8 @@ theorem val_codRestrict_apply (f : ι → α) (s : Set α) (h : ∀ x, f x ∈ s rfl @[simp] -theorem restrict_comp_codRestrict {f : ι → α} {g : α → β} {b : Set α} (h : ∀ x, f x ∈ b) : - b.restrict g ∘ b.codRestrict f h = g ∘ f := +theorem domRestrict_comp_codRestrict {f : ι → α} {g : α → β} {b : Set α} + (h : ∀ x, f x ∈ b) : b.domRestrict g ∘ b.codRestrict f h = g ∘ f := rfl @[simp] @@ -181,10 +179,38 @@ theorem codRestrict_range_surjective (f : ι → α) : variable {s : Set α} {f₁ f₂ : α → β} @[simp] -theorem restrict_eq_restrict_iff : restrict s f₁ = restrict s f₂ ↔ EqOn f₁ f₂ s := - restrict_eq_iff - -end restrict +theorem domRestrict_eq_domRestrict_iff : + domRestrict s f₁ = domRestrict s f₂ ↔ EqOn f₁ f₂ s := domRestrict_eq_iff + +@[deprecated (since := "2026-07-19")] alias restrict := domRestrict +@[deprecated (since := "2026-07-19")] alias restrict_def := domRestrict_def +@[deprecated (since := "2026-07-19")] alias restrict_eq := domRestrict_eq +@[deprecated (since := "2026-07-19")] alias restrict_id := domRestrict_id +@[deprecated (since := "2026-07-19")] alias restrict_apply := domRestrict_apply +@[deprecated (since := "2026-07-19")] alias restrict_eq_iff := domRestrict_eq_iff +@[deprecated (since := "2026-07-19")] alias eq_restrict_iff := eq_domRestrict_iff +@[deprecated (since := "2026-07-19")] alias range_restrict := range_domRestrict +@[deprecated (since := "2026-07-19")] alias image_restrict := image_domRestrict +@[deprecated (since := "2026-07-19")] alias restrict_dite := domRestrict_dite +@[deprecated (since := "2026-07-19")] alias restrict_dite_compl := domRestrict_dite_compl +@[deprecated (since := "2026-07-19")] alias restrict_ite := domRestrict_ite +@[deprecated (since := "2026-07-19")] alias restrict_ite_compl := domRestrict_ite_compl +@[deprecated (since := "2026-07-19")] alias restrict_piecewise := domRestrict_piecewise +@[deprecated (since := "2026-07-19")] alias restrict_piecewise_compl := domRestrict_piecewise_compl +@[deprecated (since := "2026-07-19")] alias restrict_extend_range := domRestrict_extend_range +@[deprecated (since := "2026-07-19")] +alias restrict_extend_compl_range := domRestrict_extend_compl_range +@[deprecated (since := "2026-07-19")] alias restrict₂ := domRestrict₂ +@[deprecated (since := "2026-07-19")] alias restrict₂_def := domRestrict₂_def +@[deprecated (since := "2026-07-19")] alias restrict₂_comp_restrict := domRestrict₂_comp_domRestrict +@[deprecated (since := "2026-07-19")] +alias restrict₂_comp_restrict₂ := domRestrict₂_comp_domRestrict₂ +@[deprecated (since := "2026-07-19")] +alias restrict_comp_codRestrict := domRestrict_comp_codRestrict +@[deprecated (since := "2026-07-19")] +alias restrict_eq_restrict_iff := domRestrict_eq_domRestrict_iff + +end domRestrict variable {s s₁ s₂ : Set α} {t t₁ t₂ : Set β} {p : Set γ} {f f₁ f₂ : α → β} {g g₁ g₂ : β → γ} {f' f₁' f₂' : β → α} {g' : γ → β} {a : α} {b : β} @@ -207,17 +233,19 @@ theorem MapsTo.coe_iterate_restrict {f : α → α} (h : MapsTo f s s) (x : s) ( /-- Restricting the domain and then the codomain is the same as `MapsTo.restrict`. -/ @[simp] -theorem codRestrict_restrict (h : ∀ x : s, f x ∈ t) : - codRestrict (s.restrict f) t h = MapsTo.restrict f s t fun x hx => h ⟨x, hx⟩ := +theorem codRestrict_domRestrict (h : ∀ x : s, f x ∈ t) : + codRestrict (s.domRestrict f) t h = MapsTo.restrict f s t fun x hx => h ⟨x, hx⟩ := rfl -/-- Reverse of `Set.codRestrict_restrict`. -/ +@[deprecated (since := "2026-07-19")] alias codRestrict_restrict := codRestrict_domRestrict + +/-- Reverse of `Set.codRestrict_domRestrict`. -/ theorem MapsTo.restrict_eq_codRestrict (h : MapsTo f s t) : - h.restrict f s t = codRestrict (s.restrict f) t fun x => h x.2 := + h.restrict f s t = codRestrict (s.domRestrict f) t fun x => h x.2 := rfl theorem MapsTo.coe_restrict (h : Set.MapsTo f s t) : - Subtype.val ∘ h.restrict f s t = s.restrict f := + Subtype.val ∘ h.restrict f s t = s.domRestrict f := rfl theorem MapsTo.range_restrict (f : α → β) (s : Set α) (t : Set β) (h : MapsTo f s t) : @@ -282,7 +310,7 @@ end /-! ### Injectivity on a set -/ section injOn -theorem injOn_iff_injective : InjOn f s ↔ Injective (s.restrict f) := +theorem injOn_iff_injective : InjOn f s ↔ Injective (s.domRestrict f) := ⟨fun H a b h => Subtype.ext <| H a.2 b.2 h, fun H a as b bs h => congr_arg Subtype.val <| @H ⟨a, as⟩ ⟨b, bs⟩ h⟩ @@ -297,7 +325,7 @@ end injOn /-! ### Surjectivity on a set -/ section surjOn -theorem surjOn_iff_surjective : SurjOn f s univ ↔ Surjective (s.restrict f) := +theorem surjOn_iff_surjective : SurjOn f s univ ↔ Surjective (s.domRestrict f) := ⟨fun H b => let ⟨a, as, e⟩ := @H b trivial ⟨⟨a, as⟩, e⟩, diff --git a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean index 5ab181c92b7d3c..907f5c1bea1884 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean @@ -211,23 +211,23 @@ lemma coverEntropy_image_le_of_uniformContinuousOn_invariant [UniformSpace X] [U (h' : UniformContinuousOn φ G) (hF : F ⊆ G) (hG : MapsTo S G G) : coverEntropy T (φ '' F) ≤ coverEntropy S F := by rw [← coverEntropy_restrict_subset hF hG] - have hφ : Semiconj (G.restrict φ) (hG.restrict S G G) T := by + have hφ : Semiconj (G.domRestrict φ) (hG.restrict S G G) T := by intro x - rw [G.restrict_apply, G.restrict_apply, hG.val_restrict_apply, h.eq x] + rw [G.domRestrict_apply, G.domRestrict_apply, hG.val_restrict_apply, h.eq x] apply (coverEntropy_image_le_of_uniformContinuous hφ (uniformContinuousOn_iff_restrict.1 h') (val ⁻¹' F)).trans_eq' - rw [← image_image_val_eq_restrict_image, image_preimage_coe G F, inter_eq_right.2 hF] + rw [← image_image_val_eq_domRestrict_image, image_preimage_coe G F, inter_eq_right.2 hF] lemma coverEntropyInf_image_le_of_uniformContinuousOn_invariant [UniformSpace X] [UniformSpace Y] {S : X → X} {T : Y → Y} {φ : X → Y} (h : Semiconj φ S T) {F G : Set X} (h' : UniformContinuousOn φ G) (hF : F ⊆ G) (hG : MapsTo S G G) : coverEntropyInf T (φ '' F) ≤ coverEntropyInf S F := by rw [← coverEntropyInf_restrict_subset hF hG] - have hφ : Semiconj (G.restrict φ) (hG.restrict S G G) T := by + have hφ : Semiconj (G.domRestrict φ) (hG.restrict S G G) T := by intro a - rw [G.restrict_apply, G.restrict_apply, hG.val_restrict_apply, h.eq a] + rw [G.domRestrict_apply, G.domRestrict_apply, hG.val_restrict_apply, h.eq a] apply (coverEntropyInf_image_le_of_uniformContinuous hφ (uniformContinuousOn_iff_restrict.1 h') (val ⁻¹' F)).trans_eq' - rw [← image_image_val_eq_restrict_image, image_preimage_coe G F, inter_eq_right.2 hF] + rw [← image_image_val_eq_domRestrict_image, image_preimage_coe G F, inter_eq_right.2 hF] end Dynamics diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index c4732343f7b0d8..d634d57c24f003 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -184,7 +184,7 @@ theorem succEquiv_coherence (i : ι) (f) : (succEquiv i f).1 = f.comp (Subalgebra.inclusion <| strictMono_filtration.monotone <| le_succ i) := by ext simp [succEquiv, embEquivOfIsAlgClosed, embEquivOfAdjoinSplits, Equiv.sigmaEquivProdOfEquiv, - algHomEquivSigma, AlgHom.restrictDomain, Subalgebra.inclusion, Set.inclusion, equivOfEq, + algHomEquivSigma, AlgHom.domRestrict, Subalgebra.inclusion, Set.inclusion, equivOfEq, Subalgebra.equivOfEq] instance (i : ι) : FiniteDimensional (E⟮ Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩ transfer_eq_pow _ _ <| transferSylow_eq_pow_aux P hP g hg -theorem transferSylow_restrict_eq_pow : (transferSylow P hP).restrict P = fun x : P ↦ x ^ P.index := +theorem transferSylow_domRestrict_eq_pow : ⇑((transferSylow P hP).domRestrict (P : Subgroup G)) = + (fun x : P => x ^ (P : Subgroup G).index) := funext fun g => transferSylow_eq_pow P hP g g.2 +@[deprecated (since := "2026-07-19")] +alias transferSylow_restrict_eq_pow := transferSylow_domRestrict_eq_pow + /-- **Burnside's normal p-complement theorem**: If `N(P) ≤ C(P)`, then `P` has a normal complement. -/ theorem ker_transferSylow_isComplement' : IsComplement' (transferSylow P hP).ker P := by - have hf : Function.Bijective ((transferSylow P hP).restrict (P : Subgroup G)) := - (transferSylow_restrict_eq_pow P hP).symm ▸ (P.2.powEquiv' P.not_dvd_index).bijective - rw [Function.Bijective, ← range_eq_top, restrict_range] at hf + have hf : Function.Bijective ((transferSylow P hP).domRestrict (P : Subgroup G)) := + (transferSylow_domRestrict_eq_pow P hP).symm ▸ (P.2.powEquiv' P.not_dvd_index).bijective + rw [Function.Bijective, ← range_eq_top, domRestrict_range] at hf have := range_eq_top.mp (top_le_iff.mp (hf.2.ge.trans (map_le_range (transferSylow P hP) P))) rw [← (comap_injective this).eq_iff, comap_top, comap_map_eq, sup_comm, SetLike.ext'_iff, normal_mul, ← ker_eq_bot_iff, ← map_subtype_inj, - ker_restrict, subgroupOf_map_subtype, Subgroup.map_bot, coe_top] at hf + ker_domRestrict, subgroupOf_map_subtype, Subgroup.map_bot, coe_top] at hf exact isComplement'_of_disjoint_and_mul_eq_univ (disjoint_iff.2 hf.1) hf.2 theorem not_dvd_card_ker_transferSylow : ¬p ∣ Nat.card (transferSylow P hP).ker := diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index e219b02bc95f7c..967d8c9c2e7b58 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -248,7 +248,7 @@ theorem LinearMap.exists_leftInverse_of_injective (f : V →ₗ[K] V') (hf_inj : have BC := this.subset_extend (subset_univ _) let hC := Basis.extend this have Vinh : Inhabited V := ⟨0⟩ - refine ⟨(hC.constr ℕ : _ → _) (C.restrict (invFun f)), hB.ext fun b => ?_⟩ + refine ⟨(hC.constr ℕ : _ → _) (C.domRestrict (invFun f)), hB.ext fun b => ?_⟩ rw [image_subset_iff] at BC have fb_eq : f b = hC ⟨f b, BC b.2⟩ := by change f b = Basis.extend this _ diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index d8ee12d84d46df..9b3442cd4109ad 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -252,7 +252,7 @@ theorem linearCombinationOn_range (s : Set α) : set_option backward.isDefEq.respectTransparency false in theorem linearCombination_restrict (s : Set α) : - linearCombination R (s.restrict v) = Submodule.subtype _ ∘ₗ + linearCombination R (s.domRestrict v) = Submodule.subtype _ ∘ₗ linearCombinationOn α M R v s ∘ₗ (supportedEquivFinsupp s).symm.toLinearMap := by ext; simp [linearCombinationOn] diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean index 56f2c2116ea195..7aa2a50b4add8f 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean @@ -321,7 +321,7 @@ theorem LinearIndepOn.of_comp (f : M →ₗ[R] M') (hfv : LinearIndepOn R (f ∘ lemma LinearIndependent.of_linearIndependent_subset (s : Set ι') {v : ι → ι' → R} (hv : LinearIndependent R fun (i : ι) (j : s) ↦ v i j) : LinearIndependent R v := - hv.of_comp ⟨⟨s.restrict, fun _ _ ↦ rfl⟩, fun _ _ ↦ rfl⟩ + hv.of_comp ⟨⟨s.domRestrict, fun _ _ ↦ rfl⟩, fun _ _ ↦ rfl⟩ /-- If `f` is a linear map injective on the span of the range of `v`, then the family `f ∘ v` is linearly independent if and only if the family `v` is linearly independent. @@ -429,10 +429,10 @@ theorem linearDepOn_iffₛ : ¬LinearIndepOn R v s ↔ linearDepOn_iff'ₛ theorem linearIndependent_restrict_iff : - LinearIndependent R (s.restrict v) ↔ LinearIndepOn R v s := Iff.rfl + LinearIndependent R (s.domRestrict v) ↔ LinearIndepOn R v s := Iff.rfl theorem LinearIndepOn.linearIndependent_restrict (hs : LinearIndepOn R v s) : - LinearIndependent R (s.restrict v) := + LinearIndependent R (s.domRestrict v) := hs theorem linearIndepOn_iff_linearCombinationOnₛ : diff --git a/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean b/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean index 6b85caa8e09c0a..d260e9d1212860 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Finite/Nondegenerate.lean @@ -388,7 +388,7 @@ private lemma linearIndepOn_coroot_iff_aux {s : Set ι} (h : LinearIndepOn R P.r ⟨fun i ↦ Units.mk0 (2 / P.RootForm (P.root i) (P.root i)) (by simp [two_ne_zero, IsAnisotropic.rootForm_root_ne_zero]), fun i ↦ by simp [coroot_eq_polarizationEquiv_apply_root]⟩ - have : (s.restrict P.coroot) = P.PolarizationEquiv.toLinearMap ∘ (f • (s.restrict P.root)) := by + have : s.domRestrict P.coroot = P.PolarizationEquiv.toLinearMap ∘ (f • s.domRestrict P.root) := by ext; simp [hf, polarizationEquiv_apply] rw [← linearIndependent_restrict_iff, this, LinearMap.linearIndependent_iff_of_injOn _ P.PolarizationEquiv.injective.injOn] diff --git a/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean b/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean index 62346e7cdc23b3..106295ce5620c9 100644 --- a/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean +++ b/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean @@ -104,26 +104,26 @@ lemma weylGroup.induction' [Nonempty ι] {pred : (g : Aut P) → g ∈ P.weylGro set_option backward.isDefEq.respectTransparency false in lemma range_weylGroup_weightHom : - MonoidHom.range ((Equiv.weightHom P).restrict P.weylGroup) = + MonoidHom.range ((Equiv.weightHom P).domRestrict P.weylGroup) = Subgroup.closure (range P.reflection) := by refine (Subgroup.closure_eq_of_le _ ?_ ?_).symm · rintro - ⟨i, rfl⟩ - simp only [MonoidHom.restrict_range, Subgroup.coe_map, Equiv.weightHom_apply, mem_image, + simp only [MonoidHom.domRestrict_range, Subgroup.coe_map, Equiv.weightHom_apply, mem_image, SetLike.mem_coe] use Equiv.reflection P i exact ⟨reflection_mem_weylGroup P i, Equiv.reflection_weightEquiv P i⟩ · rintro fg ⟨⟨w, hw⟩, rfl⟩ induction hw using Subgroup.closure_induction'' with | one => - change ((Equiv.weightHom P).restrict P.weylGroup) 1 ∈ _ + change ((Equiv.weightHom P).domRestrict P.weylGroup) 1 ∈ _ simp only [map_one, one_mem] | mem w' hw' => obtain ⟨i, rfl⟩ := hw' - simp only [MonoidHom.restrict_apply, Equiv.weightHom_apply, Equiv.reflection_weightEquiv] + simp only [MonoidHom.domRestrict_apply, Equiv.weightHom_apply, Equiv.reflection_weightEquiv] simpa only [reflection_mem_weylGroup] using! Subgroup.subset_closure (mem_range_self i) | inv_mem w' hw' => obtain ⟨i, rfl⟩ := hw' - simp only [Equiv.reflection_inv, MonoidHom.restrict_apply, Equiv.weightHom_apply, + simp only [Equiv.reflection_inv, MonoidHom.domRestrict_apply, Equiv.weightHom_apply, Equiv.reflection_weightEquiv] simpa only [reflection_mem_weylGroup] using! Subgroup.subset_closure (mem_range_self i) | mul w₁ w₂ hw₁ hw₂ h₁ h₂ => @@ -131,54 +131,54 @@ lemma range_weylGroup_weightHom : set_option backward.isDefEq.respectTransparency false in lemma range_weylGroup_coweightHom : - MonoidHom.range ((Equiv.coweightHom P).restrict P.weylGroup) = + MonoidHom.range ((Equiv.coweightHom P).domRestrict P.weylGroup) = Subgroup.closure (range (MulOpposite.op ∘ P.coreflection)) := by refine (Subgroup.closure_eq_of_le _ ?_ ?_).symm · rintro - ⟨i, rfl⟩ - simp only [MonoidHom.restrict_range, Subgroup.coe_map, mem_image, + simp only [MonoidHom.domRestrict_range, Subgroup.coe_map, mem_image, SetLike.mem_coe] use Equiv.reflection P i refine ⟨reflection_mem_weylGroup P i, by simp⟩ · rintro fg ⟨⟨w, hw⟩, rfl⟩ induction hw using Subgroup.closure_induction'' with | one => - change ((Equiv.coweightHom P).restrict P.weylGroup) 1 ∈ _ + change ((Equiv.coweightHom P).domRestrict P.weylGroup) 1 ∈ _ simp only [map_one, one_mem] | mem w' hw' => obtain ⟨i, rfl⟩ := hw' - simp only [MonoidHom.restrict_apply, Equiv.coweightHom_apply, Equiv.reflection_coweightEquiv] + simp only [MonoidHom.domRestrict_apply, Equiv.coweightHom_apply, + Equiv.reflection_coweightEquiv] simpa only [reflection_mem_weylGroup] using! Subgroup.subset_closure (mem_range_self i) | inv_mem w' hw' => obtain ⟨i, rfl⟩ := hw' - simp only [Equiv.reflection_inv, MonoidHom.restrict_apply, Equiv.coweightHom_apply, + simp only [Equiv.reflection_inv, MonoidHom.domRestrict_apply, Equiv.coweightHom_apply, Equiv.reflection_coweightEquiv] simpa only [reflection_mem_weylGroup] using! Subgroup.subset_closure (mem_range_self i) | mul w₁ w₂ hw₁ hw₂ h₁ h₂ => simpa only [← Submonoid.mk_mul_mk _ w₁ w₂ hw₁ hw₂, map_mul] using! Subgroup.mul_mem _ h₁ h₂ /-- The permutation representation of the Weyl group induced by `reflectionPerm`. -/ -abbrev weylGroupToPerm := (Equiv.indexHom P).restrict P.weylGroup +abbrev weylGroupToPerm := (Equiv.indexHom P).domRestrict P.weylGroup lemma range_weylGroupToPerm : P.weylGroupToPerm.range = Subgroup.closure (range P.reflectionPerm) := by refine (Subgroup.closure_eq_of_le _ ?_ ?_).symm · rintro - ⟨i, rfl⟩ - simp only [MonoidHom.restrict_range, Subgroup.coe_map, mem_image, - SetLike.mem_coe] + simp only [MonoidHom.domRestrict_range, Subgroup.coe_map, mem_image, SetLike.mem_coe] use Equiv.reflection P i refine ⟨reflection_mem_weylGroup P i, by simp⟩ · rintro fg ⟨⟨w, hw⟩, rfl⟩ induction hw using Subgroup.closure_induction'' with | one => - change ((Equiv.indexHom P).restrict P.weylGroup) 1 ∈ _ + change ((Equiv.indexHom P).domRestrict P.weylGroup) 1 ∈ _ simp only [map_one, one_mem] | mem w' hw' => obtain ⟨i, rfl⟩ := hw' - simp only [MonoidHom.restrict_apply, Equiv.indexHom_apply, Equiv.reflection_indexEquiv] + simp only [MonoidHom.domRestrict_apply, Equiv.indexHom_apply, Equiv.reflection_indexEquiv] simpa only [reflection_mem_weylGroup] using! Subgroup.subset_closure (mem_range_self i) | inv_mem w' hw' => obtain ⟨i, rfl⟩ := hw' - simp only [Equiv.reflection_inv, MonoidHom.restrict_apply, Equiv.indexHom_apply, + simp only [Equiv.reflection_inv, MonoidHom.domRestrict_apply, Equiv.indexHom_apply, Equiv.reflection_indexEquiv] simpa only [reflection_mem_weylGroup] using! Subgroup.subset_closure (mem_range_self i) | mul w₁ w₂ hw₁ hw₂ h₁ h₂ => diff --git a/Mathlib/Logic/Function/DependsOn.lean b/Mathlib/Logic/Function/DependsOn.lean index 9fc7fc598a1907..596f880fe3d231 100644 --- a/Mathlib/Logic/Function/DependsOn.lean +++ b/Mathlib/Logic/Function/DependsOn.lean @@ -21,7 +21,7 @@ On the other hand one wants to be able for example to describe some function as with respect to some variables, and be able to deduce this when applying transformations mentioned above. This is why we introduce the predicate `DependsOn f s`, which states that if `x` and `y` coincide over the set `s`, then `f x = f y`. -This is equivalent to `Function.FactorsThrough f s.restrict`. +This is equivalent to `Function.FactorsThrough f s.domRestrict`. ## Main definition @@ -30,7 +30,7 @@ This is equivalent to `Function.FactorsThrough f s.restrict`. ## Main statement * `dependsOn_iff_factorsThrough`: A function `f` depends on `s` if and only if it factors - through `s.restrict`. + through `s.domRestrict`. ## Implementation notes @@ -65,12 +65,12 @@ def DependsOn (f : (Π i, α i) → β) (s : Set ι) : Prop := ∀ ⦃x y⦄, (∀ i ∈ s, x i = y i) → f x = f y lemma dependsOn_iff_factorsThrough {f : (Π i, α i) → β} {s : Set ι} : - DependsOn f s ↔ FactorsThrough f s.restrict := by + DependsOn f s ↔ FactorsThrough f s.domRestrict := by rw [DependsOn, FactorsThrough] simp [funext_iff] lemma dependsOn_iff_exists_comp [Nonempty β] {f : (Π i, α i) → β} {s : Set ι} : - DependsOn f s ↔ ∃ g : (Π i : s, α i) → β, f = g ∘ s.restrict := by + DependsOn f s ↔ ∃ g : (Π i : s, α i) → β, f = g ∘ s.domRestrict := by rw [dependsOn_iff_factorsThrough, factorsThrough_iff] lemma dependsOn_univ (f : (Π i, α i) → β) : DependsOn f univ := @@ -87,5 +87,7 @@ lemma DependsOn.mono {s t : Set ι} (hst : s ⊆ t) (hf : DependsOn f s) : Depen /-- A function which depends on the empty set is constant. -/ lemma DependsOn.empty (hf : DependsOn f ∅) (x y : Π i, α i) : f x = f y := hf (by simp) -lemma Set.dependsOn_restrict (s : Set ι) : DependsOn (s.restrict (π := α)) s := +lemma Set.dependsOn_domRestrict (s : Set ι) : DependsOn (s.domRestrict (π := α)) s := fun _ _ h ↦ funext fun i ↦ h i.1 i.2 + +@[deprecated (since := "2026-07-19")] alias Set.dependsOn_restrict := Set.dependsOn_domRestrict diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index b1567b6a84d713..77a45966d4e35e 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -503,7 +503,7 @@ theorem ContinuousOn.measurable_of_countable_compl [MeasurableSingletonClass α] {f : α → γ} {s : Set α} (hf : ContinuousOn f s) (hs : (sᶜ).Countable) : Measurable f := by apply measurable_of_measurable_on_compl_countable _ hs rw [compl_compl] - exact (continuousOn_iff_continuous_restrict.1 hf).measurable + exact (continuousOn_iff_continuous_domRestrict.1 hf).measurable /-- If a function is continuous outside of a countable set, then it is measurable. -/ theorem measurable_of_countable_not_continuousAt [MeasurableSingletonClass α] @@ -585,7 +585,7 @@ theorem ContinuousMap.measurable (f : C(α, γ)) : Measurable f := theorem measurable_of_continuousOn_compl_singleton [T1Space α] {f : α → γ} (a : α) (hf : ContinuousOn f {a}ᶜ) : Measurable f := measurable_of_measurable_on_compl_singleton a - (continuousOn_iff_continuous_restrict.1 hf).measurable + (continuousOn_iff_continuous_domRestrict.1 hf).measurable theorem Continuous.measurable2 [SecondCountableTopologyEither α β] {f : δ → α} {g : δ → β} {c : α → β → γ} (h : Continuous fun p : α × β => c p.1 p.2) (hf : Measurable f) diff --git a/Mathlib/MeasureTheory/Constructions/Cylinders.lean b/Mathlib/MeasureTheory/Constructions/Cylinders.lean index 4ca7312a2cb5c5..e75df0ba659b56 100644 --- a/Mathlib/MeasureTheory/Constructions/Cylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/Cylinders.lean @@ -460,7 +460,7 @@ lemma measurable_update_cylinderEvents_left {a : ι} [DecidableEq ι] {x : X a} measurable_update_cylinderEvents'.comp measurable_prodMk_right lemma measurable_restrict_cylinderEvents (Δ : Set ι) : - Measurable[cylinderEvents (X := X) Δ] (restrict Δ) := by + Measurable[cylinderEvents (X := X) Δ] (domRestrict Δ) := by rw [@measurable_pi_iff]; exact fun i ↦ measurable_cylinderEvent_apply i.2 end cylinderEvents @@ -468,7 +468,7 @@ end cylinderEvents /-- A measurable set from the product sigma-algebra only depends on countably many coordinates. -/ lemma MeasurableSet.eq_preimage_restrict_countable [∀ i, MeasurableSpace (α i)] {s : Set (Π i, α i)} (hs : MeasurableSet s) : - ∃ I : Set ι, ∃ t, I.Countable ∧ s = I.restrict ⁻¹' t := by + ∃ I : Set ι, ∃ t, I.Countable ∧ s = I.domRestrict ⁻¹' t := by refine induction_on_inter generateFrom_squareCylinders.symm (isPiSystem_squareCylinders (fun _ ↦ isPiSystem_measurableSet) (by simp)) ⟨∅, ∅, by simp⟩ ?_ ?_ ?_ s hs @@ -478,13 +478,13 @@ lemma MeasurableSet.eq_preimage_restrict_countable exact ⟨I, tᶜ, hI, by simp⟩ intro f df mf hf choose! I t hI hf using hf - refine ⟨⋃ n, I n, ⋃ n, (⋃ k, I k).restrict '' (f n), countable_iUnion hI, ?_⟩ + refine ⟨⋃ n, I n, ⋃ n, (⋃ k, I k).domRestrict '' (f n), countable_iUnion hI, ?_⟩ ext x simp only [hf, mem_iUnion, mem_preimage, preimage_iUnion, mem_image] refine ⟨fun ⟨i, hi⟩ ↦ ⟨i, x, hi, rfl⟩, fun ⟨n, x', hn, hx⟩ ↦ ⟨n, ?_⟩⟩ - have (x : Π i, α i) : (I n).restrict x = + have (x : Π i, α i) : (I n).domRestrict x = (fun (x : Π (i : ⋃ k, I k), α i) (i : I n) ↦ x ⟨i.1, subset_iUnion I n i.2⟩) - ((⋃ k, I k).restrict x) := rfl + ((⋃ k, I k).domRestrict x) := rfl rwa [this, ← hx, ← this] end MeasureTheory diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index 9aeeed20ad7d75..9a3f69f3e301b5 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -596,7 +596,7 @@ then for any measurable space `β` and `g : Z → β`, the composition `g ∘ f` measurable if and only if the restriction of `g` to the range of `f` is measurable. -/ theorem measurable_comp_iff_restrict {f : X → Z} [CountablySeparated (range f)] - (hf : Measurable f) {g : Z → β} : Measurable (g ∘ f) ↔ Measurable (restrict (range f) g) := + (hf : Measurable f) {g : Z → β} : Measurable (g ∘ f) ↔ Measurable (domRestrict (range f) g) := forall₂_congr fun s _ => measurableSet_preimage_iff_preimage_val hf (s := g ⁻¹' s) /-- If `f : X → Z` is a surjective Borel measurable map from a standard Borel space @@ -808,7 +808,7 @@ theorem IsClosed.measurableSet_image_of_continuousOn_injOn rw [image_eq_range] have : PolishSpace s := IsClosed.polishSpace hs apply measurableSet_range_of_continuous_injective - · rwa [continuousOn_iff_continuous_restrict] at f_cont + · rwa [continuousOn_iff_continuous_domRestrict] at f_cont · rwa [injOn_iff_injective] at f_inj variable {α β : Type*} [MeasurableSpace β] @@ -864,9 +864,9 @@ the restriction of `f` to `s` is a measurable embedding. -/ theorem ContinuousOn.measurableEmbedding [BorelSpace β] [TopologicalSpace γ] [PolishSpace γ] [MeasurableSpace γ] [BorelSpace γ] (hs : MeasurableSet s) (f_cont : ContinuousOn f s) - (f_inj : InjOn f s) : MeasurableEmbedding (s.restrict f) := + (f_inj : InjOn f s) : MeasurableEmbedding (s.domRestrict f) := { injective := injOn_iff_injective.1 f_inj - measurable := (continuousOn_iff_continuous_restrict.1 f_cont).measurable + measurable := (continuousOn_iff_continuous_domRestrict.1 f_cont).measurable measurableSet_image' := by intro u hu have A : MeasurableSet (((↑) : s → γ) '' u) := @@ -1035,7 +1035,7 @@ theorem Measurable.tprod {f : ι → X → E} (h : ∀ i : ι, Measurable (f i)) Measurable (fun x => ∏'[L] i : ι, f i x) := by let E := { x | Multipliable (f · x) L } have hE : MeasurableSet E := measurableSet_exists_tendsto (by fun_prop) - have h0 : (Eᶜ.restrict fun x => ∏'[L] i, f i x) = fun _ => 1 := + have h0 : (Eᶜ.domRestrict fun x => ∏'[L] i, f i x) = fun _ => 1 := funext fun ⟨x, hx⟩ => tprod_eq_one_of_not_multipliable hx refine measurable_of_restrict_of_restrict_compl hE ?_ (h0 ▸ measurable_const) refine measurable_of_tendsto_metrizable' L.filter ?_ (tendsto_pi_nhds.mpr fun e => e.2.hasProd) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean b/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean index b3c9f2544b451e..726235c55c69d2 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/StronglyMeasurable.lean @@ -102,7 +102,7 @@ theorem StronglyMeasurable.tprod {f : ι → X → E} (h : ∀ i : ι, StronglyM StronglyMeasurable (fun x => ∏'[L] i : ι, f i x) := by let E := { x | Multipliable (f · x) L } have hE : MeasurableSet E := StronglyMeasurable.measurableSet_exists_tendsto (by fun_prop) - have h0 : (Eᶜ.restrict fun x => ∏'[L] i, f i x) = fun _ => 1 := + have h0 : (Eᶜ.domRestrict fun x => ∏'[L] i, f i x) = fun _ => 1 := funext fun ⟨x, hx⟩ => tprod_eq_one_of_not_multipliable hx refine stronglyMeasurable_of_restrict_of_restrict_compl hE ?_ (h0 ▸ stronglyMeasurable_const) refine stronglyMeasurable_of_tendsto L.filter ?_ (tendsto_pi_nhds.mpr fun e => e.2.hasProd) diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean index bea52d41254491..414b1d42c2da4a 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondJensen.lean @@ -109,7 +109,7 @@ private lemma ConvexOn.map_condExp_le_of_hereditarilyLindelofSpace [IsFiniteMeas · exact ((L i).integrable_comp hf_int).add (integrable_const (c i)) · filter_upwards [hf] with a ha using hLc1 i ⟨f a, ha⟩ filter_upwards [hp, hw, hφ_cvx.1.condExp_mem hm hf_int hs hf] with a hp hw hq - rw [show φ (μ[f | m] a) = s.restrict φ ⟨μ[f | m] a, hq⟩ by simp, ← hLc2] + rw [show φ (μ[f | m] a) = s.domRestrict φ ⟨μ[f | m] a, hq⟩ by simp, ← hLc2] simpa [iSup_congr hp] using! ciSup_le hw /-- Conditional Jensen's inequality for finite measures. -/ diff --git a/Mathlib/MeasureTheory/Function/Jacobian.lean b/Mathlib/MeasureTheory/Function/Jacobian.lean index a641df4f1adc90..fe7664d0202314 100644 --- a/Mathlib/MeasureTheory/Function/Jacobian.lean +++ b/Mathlib/MeasureTheory/Function/Jacobian.lean @@ -39,7 +39,7 @@ For the next statements, `s` is a measurable set and `f` is differentiable on `s (with a derivative `f'`) and injective on `s`. * `measurable_image_of_fderivWithin`: the image `f '' s` is measurable. -* `measurableEmbedding_of_fderivWithin`: the function `s.restrict f` is a measurable embedding. +* `measurableEmbedding_of_fderivWithin`: the function `s.domRestrict f` is a measurable embedding. * `lintegral_abs_det_fderiv_eq_addHaar_image`: the image measure is given by `μ (f '' s) = ∫⁻ x in s, |(f' x).det| ∂μ`. * `lintegral_image_eq_lintegral_abs_det_fderiv_mul`: for `g : E → ℝ≥0∞`, one has @@ -784,7 +784,7 @@ theorem nullMeasurable_image_of_fderivWithin (hs : NullMeasurableSet s μ) to `s` is a measurable embedding. -/ theorem measurableEmbedding_of_fderivWithin (hs : MeasurableSet s) (hf' : ∀ x ∈ s, HasFDerivWithinAt f (f' x) s x) (hf : InjOn f s) : - MeasurableEmbedding (s.restrict f) := + MeasurableEmbedding (s.domRestrict f) := haveI : DifferentiableOn ℝ f s := fun x hx => (hf' x hx).differentiableWithinAt this.continuousOn.measurableEmbedding hs hf @@ -1145,12 +1145,12 @@ theorem map_withDensity_abs_det_fderiv_eq_addHaar (hs : NullMeasurableSet s μ) /-- Change of variable formula for differentiable functions, set version: if a function `f` is injective and differentiable on a measurable set `s`, then the pushforward of the measure with density `|(f' x).det|` on `s` is the Lebesgue measure on the image set. This version is expressed -in terms of the restricted function `s.restrict f`. +in terms of the restricted function `s.domRestrict f`. For a version for the original function, see `map_withDensity_abs_det_fderiv_eq_addHaar`. -/ theorem restrict_map_withDensity_abs_det_fderiv_eq_addHaar (hs : MeasurableSet s) (hf' : ∀ x ∈ s, HasFDerivWithinAt f (f' x) s x) (hf : InjOn f s) : - Measure.map (s.restrict f) (comap (↑) (μ.withDensity fun x => ENNReal.ofReal |(f' x).det|)) = + Measure.map (s.domRestrict f) (comap (↑) (μ.withDensity fun x => ENNReal.ofReal |(f' x).det|)) = μ.restrict (f '' s) := by obtain ⟨u, u_meas, uf⟩ : ∃ u, Measurable u ∧ EqOn u f s := by classical @@ -1168,7 +1168,7 @@ theorem restrict_map_withDensity_abs_det_fderiv_eq_addHaar (hs : MeasurableSet s restrict_withDensity hs] exact map_withDensity_abs_det_fderiv_eq_addHaar μ hs.nullMeasurableSet u' (hf.congr uf.symm) rw [uf.image_eq] at A - have : F = s.restrict f := by + have : F = s.domRestrict f := by ext x exact uf x.2 rwa [this] at A @@ -1185,7 +1185,7 @@ theorem lintegral_image_eq_lintegral_abs_det_fderiv_mul (hs : MeasurableSet s) ∫⁻ x in f '' s, g x ∂μ = ∫⁻ x in s, ENNReal.ofReal |(f' x).det| * g (f x) ∂μ := by rw [← restrict_map_withDensity_abs_det_fderiv_eq_addHaar μ hs hf' hf, (measurableEmbedding_of_fderivWithin hs hf' hf).lintegral_map] - simp only [Set.restrict_apply, ← Function.comp_apply (f := g)] + simp only [Set.domRestrict_apply, ← Function.comp_apply (f := g)] rw [← (MeasurableEmbedding.subtype_coe hs).lintegral_map, map_comap_subtype_coe hs, setLIntegral_withDensity_eq_setLIntegral_mul_non_measurable₀ _ _ _ hs] · simp only [Pi.mul_apply] @@ -1201,7 +1201,7 @@ theorem integrableOn_image_iff_integrableOn_abs_det_fderiv_smul (hs : Measurable IntegrableOn g (f '' s) μ ↔ IntegrableOn (fun x => |(f' x).det| • g (f x)) s μ := by rw [IntegrableOn, ← restrict_map_withDensity_abs_det_fderiv_eq_addHaar μ hs hf' hf, (measurableEmbedding_of_fderivWithin hs hf' hf).integrable_map_iff] - simp only [Set.restrict_eq, ← Function.comp_assoc, ENNReal.ofReal] + simp only [Set.domRestrict_eq, ← Function.comp_assoc, ENNReal.ofReal] rw [← (MeasurableEmbedding.subtype_coe hs).integrable_map_iff, map_comap_subtype_coe hs, restrict_withDensity hs, integrable_withDensity_iff_integrable_coe_smul₀] · simp_rw [IntegrableOn, Real.coe_toNNReal _ (abs_nonneg _), Function.comp_apply] @@ -1215,7 +1215,7 @@ theorem integral_image_eq_integral_abs_det_fderiv_smul (hs : MeasurableSet s) ∫ x in f '' s, g x ∂μ = ∫ x in s, |(f' x).det| • g (f x) ∂μ := by rw [← restrict_map_withDensity_abs_det_fderiv_eq_addHaar μ hs hf' hf, (measurableEmbedding_of_fderivWithin hs hf' hf).integral_map] - simp only [Set.restrict_apply, ← Function.comp_apply (f := g), ENNReal.ofReal] + simp only [Set.domRestrict_apply, ← Function.comp_apply (f := g), ENNReal.ofReal] rw [← (MeasurableEmbedding.subtype_coe hs).integral_map, map_comap_subtype_coe hs, setIntegral_withDensity_eq_setIntegral_smul₀ (aemeasurable_toNNReal_abs_det_fderivWithin μ hs hf') _ hs] diff --git a/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean b/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean index 8fdb92ba8a019d..cadcb50ba1bb02 100644 --- a/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean +++ b/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean @@ -38,7 +38,7 @@ theorem measurable_exp : Measurable exp := theorem measurable_log : Measurable log := measurable_of_measurable_on_compl_singleton 0 <| - Continuous.measurable <| continuousOn_iff_continuous_restrict.1 continuousOn_log + Continuous.measurable <| continuousOn_iff_continuous_domRestrict.1 continuousOn_log lemma measurable_of_measurable_exp (hf : Measurable (fun x ↦ exp (f x))) : Measurable f := by diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index 793cc766d98a7f..362c1da5896bab 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -840,7 +840,7 @@ theorem _root_.ContinuousOn.stronglyMeasurable_of_countable_compl [MeasurableSpa rw [this] apply StronglyMeasurable.dite (f := fun x ↦ f x) (g := fun x ↦ f x) ?_ ?_ h's · have : SecondCountableTopologyEither s β := by cases h.out <;> infer_instance - exact (continuousOn_iff_continuous_restrict.1 hf).stronglyMeasurable + exact (continuousOn_iff_continuous_domRestrict.1 hf).stronglyMeasurable · have := hs.to_subtype exact MeasureTheory.StronglyMeasurable.of_discrete @@ -896,7 +896,7 @@ theorem _root_.stronglyMeasurable_of_stronglyMeasurable_union_cover {m : Measura theorem _root_.stronglyMeasurable_of_restrict_of_restrict_compl {_ : MeasurableSpace α} [TopologicalSpace β] {f : α → β} {s : Set α} (hs : MeasurableSet s) - (h₁ : StronglyMeasurable (s.restrict f)) (h₂ : StronglyMeasurable (sᶜ.restrict f)) : + (h₁ : StronglyMeasurable (s.domRestrict f)) (h₂ : StronglyMeasurable (sᶜ.domRestrict f)) : StronglyMeasurable f := stronglyMeasurable_of_stronglyMeasurable_union_cover s sᶜ hs hs.compl (union_compl_self s).ge h₁ h₂ diff --git a/Mathlib/MeasureTheory/Integral/CircleAverage.lean b/Mathlib/MeasureTheory/Integral/CircleAverage.lean index 11d99983cbf002..1360791d7efdd0 100644 --- a/Mathlib/MeasureTheory/Integral/CircleAverage.lean +++ b/Mathlib/MeasureTheory/Integral/CircleAverage.lean @@ -201,7 +201,7 @@ theorem ContinuousOn.circleAverage {f : ℂ → E} {s : Set ℝ} {c : ℂ} (hf : ContinuousOn f {z : ℂ | ‖z - c‖ ∈ s}) (hs : ∀ r ∈ s, 0 ≤ r) : ContinuousOn (circleAverage f c) s := by - rw [continuousOn_iff_continuous_restrict] at * + rw [continuousOn_iff_continuous_domRestrict] at * apply (intervalIntegral.continuous_parametric_intervalIntegral_of_continuous' _ _ _).const_smul have (x : s × ℝ) : circleMap c x.1 x.2 ∈ {z | ‖z - c‖ ∈ s} := by simp [abs_of_nonneg (hs x.1 (Subtype.coe_prop x.1))] diff --git a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean index cc0a24004fb02a..b96636b34e70da 100644 --- a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean +++ b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean @@ -768,7 +768,7 @@ theorem ContinuousOn.aestronglyMeasurable [TopologicalSpace α] [TopologicalSpac mem_of_superset (self_mem_ae_restrict hs) (subset_preimage_image _ _)⟩ cases h.out · rw [image_eq_range] - exact isSeparable_range <| continuousOn_iff_continuous_restrict.1 hf + exact isSeparable_range <| continuousOn_iff_continuous_domRestrict.1 hf · exact .of_separableSpace _ /-- A function which is continuous on a compact set `s` is almost everywhere strongly measurable diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean index 08e968aeb02179..2a6fd7c4acb662 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean @@ -131,7 +131,7 @@ instance : IsUnifLocDoublingMeasure (volume : Measure (AddCircle T)) := by noncomputable def measurableEquivIoc (a : ℝ) : AddCircle T ≃ᵐ Ioc a (a + T) where toEquiv := equivIoc T a measurable_toFun := measurable_of_measurable_on_compl_singleton _ - (continuousOn_iff_continuous_restrict.mp <| continuousOn_of_forall_continuousAt fun _x hx => + (continuousOn_iff_continuous_domRestrict.mp <| continuousOn_of_forall_continuousAt fun _x hx => continuousAt_equivIoc T a hx).measurable measurable_invFun := AddCircle.measurable_mk'.comp measurable_subtype_coe @@ -140,7 +140,7 @@ noncomputable def measurableEquivIoc (a : ℝ) : AddCircle T ≃ᵐ Ioc a (a + T noncomputable def measurableEquivIco (a : ℝ) : AddCircle T ≃ᵐ Ico a (a + T) where toEquiv := equivIco T a measurable_toFun := measurable_of_measurable_on_compl_singleton _ - (continuousOn_iff_continuous_restrict.mp <| continuousOn_of_forall_continuousAt fun _x hx => + (continuousOn_iff_continuous_domRestrict.mp <| continuousOn_of_forall_continuousAt fun _x hx => continuousAt_equivIco T a hx).measurable measurable_invFun := AddCircle.measurable_mk'.comp measurable_subtype_coe @@ -224,7 +224,7 @@ also satisfies `MemLp` with respect to the Haar measure. -/ lemma MeasureTheory.MemLp.memLp_liftIoc {T : ℝ} [hT : Fact (0 < T)] {t : ℝ} {f : ℝ → ℂ} {p : ℝ≥0∞} (hLp : MemLp f p (volume.restrict (Ioc t (t + T)))) : MemLp (AddCircle.liftIoc T t f) p := by - simp only [AddCircle.liftIoc, Set.restrict_def, Function.comp_def] + simp only [AddCircle.liftIoc, Set.domRestrict_def, Function.comp_def] apply hLp.comp_measurePreserving refine .comp (measurePreserving_subtype_coe measurableSet_Ioc) ?_ exact AddCircle.measurePreserving_equivIoc T diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index bdced9169c89f0..70a5380e22d166 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -266,7 +266,7 @@ theorem measurable_of_measurable_union_cover {f : α → β} (s t : Set α) (hs .of_union_cover hs ht h (hc hu) (hd hu) theorem measurable_of_restrict_of_restrict_compl {f : α → β} {s : Set α} (hs : MeasurableSet s) - (h₁ : Measurable (s.restrict f)) (h₂ : Measurable (sᶜ.restrict f)) : Measurable f := + (h₁ : Measurable (s.domRestrict f)) (h₂ : Measurable (sᶜ.domRestrict f)) : Measurable f := measurable_of_measurable_union_cover s sᶜ hs hs.compl (union_compl_self s).ge h₁ h₂ theorem Measurable.dite [∀ x, Decidable (x ∈ s)] {f : s → β} (hf : Measurable f) @@ -275,17 +275,17 @@ theorem Measurable.dite [∀ x, Decidable (x ∈ s)] {f : s → β} (hf : Measur measurable_of_restrict_of_restrict_compl hs (by simpa) (by simpa) theorem measurable_of_measurable_on_compl_finite [MeasurableSingletonClass α] {f : α → β} - (s : Set α) (hs : s.Finite) (hf : Measurable (sᶜ.restrict f)) : Measurable f := + (s : Set α) (hs : s.Finite) (hf : Measurable (sᶜ.domRestrict f)) : Measurable f := have := hs.to_subtype measurable_of_restrict_of_restrict_compl hs.measurableSet (measurable_of_finite _) hf theorem measurable_of_measurable_on_compl_countable [MeasurableSingletonClass α] {f : α → β} - (s : Set α) (hs : s.Countable) (hf : Measurable (sᶜ.restrict f)) : Measurable f := + (s : Set α) (hs : s.Countable) (hf : Measurable (sᶜ.domRestrict f)) : Measurable f := have := hs.to_subtype measurable_of_restrict_of_restrict_compl hs.measurableSet (measurable_of_countable _) hf theorem measurable_of_measurable_on_compl_singleton [MeasurableSingletonClass α] {f : α → β} (a : α) - (hf : Measurable ({ x | x ≠ a }.restrict f)) : Measurable f := + (hf : Measurable ({ x | x ≠ a }.domRestrict f)) : Measurable f := measurable_of_measurable_on_compl_finite {a} (finite_singleton a) hf end Subtype @@ -645,12 +645,12 @@ theorem measurable_update_left {a : δ} [DecidableEq δ] {x : X a} : measurable_update'.comp measurable_prodMk_right @[fun_prop] -theorem Set.measurable_restrict (s : Set δ) : Measurable (s.restrict (π := X)) := +theorem Set.measurable_restrict (s : Set δ) : Measurable (s.domRestrict (π := X)) := measurable_pi_lambda _ fun _ ↦ measurable_pi_apply _ @[fun_prop] theorem Set.measurable_restrict₂ {s t : Set δ} (hst : s ⊆ t) : - Measurable (restrict₂ (π := X) hst) := + Measurable (domRestrict₂ (π := X) hst) := measurable_pi_lambda _ fun _ ↦ measurable_pi_apply _ @[fun_prop] @@ -664,12 +664,12 @@ theorem Finset.measurable_restrict₂ {s t : Finset δ} (hst : s ⊆ t) : @[fun_prop] theorem Set.measurable_restrict_apply (s : Set α) {f : α → γ} (hf : Measurable f) : - Measurable (s.restrict f) := hf.comp measurable_subtype_coe + Measurable (s.domRestrict f) := hf.comp measurable_subtype_coe @[fun_prop] theorem Set.measurable_restrict₂_apply {s t : Set α} (hst : s ⊆ t) {f : t → γ} (hf : Measurable f) : - Measurable (restrict₂ (π := fun _ ↦ γ) hst f) := hf.comp (measurable_inclusion hst) + Measurable (domRestrict₂ (π := fun _ ↦ γ) hst f) := hf.comp (measurable_inclusion hst) @[fun_prop] theorem Finset.measurable_restrict_apply (s : Finset α) {f : α → γ} (hf : Measurable f) : diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 0d39a6f9539cf7..3f52e91e301cfa 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -106,9 +106,9 @@ theorem measurable_rangeSplitting (hf : MeasurableEmbedding f) : theorem measurable_extend (hf : MeasurableEmbedding f) {g : α → γ} {g' : β → γ} (hg : Measurable g) (hg' : Measurable g') : Measurable (extend f g g') := by refine measurable_of_restrict_of_restrict_compl hf.measurableSet_range ?_ ?_ - · rw [restrict_extend_range] + · rw [domRestrict_extend_range] simpa only [rangeSplitting] using! hg.comp hf.measurable_rangeSplitting - · rw [restrict_extend_compl_range] + · rw [domRestrict_extend_compl_range] exact hg'.comp measurable_subtype_coe theorem exists_measurable_extend (hf : MeasurableEmbedding f) {g : α → γ} (hg : Measurable g) diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index 741f7187fd28b8..2a3ef8b3c7eade 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -90,15 +90,15 @@ theorem sum_measure [Countable ι] {μ : ι → Measure α} (h : ∀ i, AEMeasur exact subset_toMeasurable _ _ hx set g : α → β := (⋂ i, s i).piecewise (const α default) f refine ⟨g, measurable_of_restrict_of_restrict_compl hsm ?_ ?_, ae_sum_iff.mpr fun i => ?_⟩ - · rw [restrict_piecewise] + · rw [domRestrict_piecewise] simp only [s] exact measurable_const - · rw [restrict_piecewise_compl, compl_iInter] + · rw [domRestrict_piecewise_compl, compl_iInter] intro t ht refine ⟨⋃ i, (h i).mk f ⁻¹' t ∩ (s i)ᶜ, MeasurableSet.iUnion fun i ↦ (measurable_mk _ ht).inter (measurableSet_toMeasurable _ _).compl, ?_⟩ ext ⟨x, hx⟩ - simp only [mem_preimage, mem_iUnion, Set.restrict, mem_inter_iff, + simp only [mem_preimage, mem_iUnion, Set.domRestrict, mem_inter_iff, mem_compl_iff] at hx ⊢ constructor · rintro ⟨i, hxt, hxs⟩ @@ -399,9 +399,9 @@ lemma MeasureTheory.NullMeasurable.aemeasurable {f : α → β} refine ⟨v.piecewise (fun _ ↦ default) f, ?_, measure_mono_null (fun x ↦ not_imp_comm.2 fun hxv ↦ (piecewise_eq_of_notMem _ _ _ hxv).symm) hvμ⟩ refine measurable_of_restrict_of_restrict_compl hvm ?_ ?_ - · rw [restrict_piecewise] + · rw [domRestrict_piecewise] apply measurable_const - · rw [restrict_piecewise_compl, restrict_eq] + · rw [domRestrict_piecewise_compl, domRestrict_eq] refine measurable_generateFrom fun s hs ↦ .of_subtype_image ?_ rw [preimage_comp, Subtype.image_preimage_coe] convert! (hTm s hs).diff hvm using 1 diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean index 99c22bff668a4f..57efab4598d22d 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasure.lean @@ -994,14 +994,14 @@ lemma Topology.IsClosedEmbedding.isEmbedding_map_finiteMeasure {Ω : Type*} simp only [null_iff_toMeasure_null, mem_ofPred_eq, toMeasure_map, M] rw [Measure.map_apply hf.continuous.measurable hf.isClosed_range.isOpen_compl.measurableSet] simp - invFun := M.restrict (fun μ ↦ μ.comap f) + invFun := M.domRestrict (fun μ ↦ μ.comap f) continuous_toFun := by fun_prop continuous_invFun := by - rw [← continuousOn_iff_continuous_restrict] + rw [← continuousOn_iff_continuous_domRestrict] exact hf.continuousOn_comap_finiteMeasure left_inv μ := by ext s hs - simp only [Set.restrict_apply, toMeasure_comap, toMeasure_map] + simp only [Set.domRestrict_apply, toMeasure_comap, toMeasure_map] rw [Measure.comap_apply, Measure.map_apply, preimage_image_eq] · exact hf.injective · exact hf.continuous.measurable @@ -1011,7 +1011,7 @@ lemma Topology.IsClosedEmbedding.isEmbedding_map_finiteMeasure {Ω : Type*} · exact hs right_inv μ := by ext s hs - simp only [Set.restrict_apply, toMeasure_map] + simp only [Set.domRestrict_apply, toMeasure_map] rw [Measure.map_apply hf.continuous.measurable hs] simp only [toMeasure_comap] rw [Measure.comap_apply _ hf.injective, image_preimage_eq_inter_range] diff --git a/Mathlib/MeasureTheory/Measure/ResolventTransform.lean b/Mathlib/MeasureTheory/Measure/ResolventTransform.lean index 6fd7d22cf63abf..d5d3637a883033 100644 --- a/Mathlib/MeasureTheory/Measure/ResolventTransform.lean +++ b/Mathlib/MeasureTheory/Measure/ResolventTransform.lean @@ -64,7 +64,7 @@ theorem measurable_resolvent {a : A} [OpensMeasurableSpace 𝕜] [NormedRing A] have h1 : ContinuousOn (resolvent (R := 𝕜) a) (resolventSet 𝕜 a) := HasDerivAt.continuousOn (fun _ hx ↦ hasDerivAt_resolvent_const_left hx) have h2 : ContinuousOn (resolvent (R := 𝕜) a) (resolventSet 𝕜 a)ᶜ := by - rw [continuousOn_iff_continuous_restrict] + rw [continuousOn_iff_continuous_domRestrict] convert continuous_const (y := (0 : A)) with x simp have h3 : MeasurableSet (resolventSet 𝕜 a) := (isOpen_resolventSet a).measurableSet diff --git a/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean b/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean index 3f7e457ac04f41..d8d3bab2989078 100644 --- a/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean +++ b/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMap.lean @@ -94,9 +94,9 @@ lemma hasFiniteIntegral_mkD_restrict_of_bound {s : Set Y} [CompactSpace s] (bound : X → ℝ) (bound_int : HasFiniteIntegral bound μ) (bound_ge : ∀ᵐ x ∂μ, ∀ y ∈ s, ‖f x y‖ ≤ bound x) : - HasFiniteIntegral (fun x ↦ mkD (s.restrict (f x)) g) μ := by + HasFiniteIntegral (fun x ↦ mkD (s.domRestrict (f x)) g) μ := by refine hasFiniteIntegral_mkD_of_bound _ _ ?_ bound bound_int ?_ - · simpa [← continuousOn_iff_continuous_restrict] + · simpa [← continuousOn_iff_continuous_domRestrict] · simpa lemma aeStronglyMeasurable_mkD_of_uncurry [CompactSpace Y] [TopologicalSpace X] @@ -117,7 +117,7 @@ open Set in lemma aeStronglyMeasurable_mkD_restrict_of_uncurry {t : Set Y} [CompactSpace t] [TopologicalSpace X] [OpensMeasurableSpace X] [SecondCountableTopologyEither X (C(t, E))] (f : X → Y → E) (g : C(t, E)) (f_cont : ContinuousOn (Function.uncurry f) (univ ×ˢ t)) : - AEStronglyMeasurable (fun x ↦ mkD (t.restrict (f x)) g) μ := + AEStronglyMeasurable (fun x ↦ mkD (t.domRestrict (f x)) g) μ := continuous_mkD_restrict_of_uncurry _ _ f_cont |>.aestronglyMeasurable open Set in @@ -126,7 +126,7 @@ lemma aeStronglyMeasurable_restrict_mkD_restrict_of_uncurry {s : Set X} {t : Set [SecondCountableTopologyEither X (C(t, E))] (hs : MeasurableSet s) (f : X → Y → E) (g : C(t, E)) (f_cont : ContinuousOn (Function.uncurry f) (s ×ˢ t)) : - AEStronglyMeasurable (fun x ↦ mkD (t.restrict (f x)) g) (μ.restrict s) := + AEStronglyMeasurable (fun x ↦ mkD (t.domRestrict (f x)) g) (μ.restrict s) := continuousOn_mkD_restrict_of_uncurry _ _ f_cont |>.aestronglyMeasurable hs end ContinuousMap diff --git a/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMapZero.lean b/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMapZero.lean index 0913017e1daaad..f2d3031a5bf8ba 100644 --- a/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMapZero.lean +++ b/Mathlib/MeasureTheory/SpecificCodomains/ContinuousMapZero.lean @@ -66,9 +66,9 @@ lemma hasFiniteIntegral_mkD_restrict_of_bound {s : Set Y} [CompactSpace s] [Zero (bound : X → ℝ) (bound_int : HasFiniteIntegral bound μ) (bound_ge : ∀ᵐ x ∂μ, ∀ y ∈ s, ‖f x y‖ ≤ bound x) : - HasFiniteIntegral (fun x ↦ mkD (s.restrict (f x)) g) μ := by + HasFiniteIntegral (fun x ↦ mkD (s.domRestrict (f x)) g) μ := by refine hasFiniteIntegral_mkD_of_bound _ _ ?_ f_ae_zero bound bound_int ?_ - · simpa [← continuousOn_iff_continuous_restrict] + · simpa [← continuousOn_iff_continuous_domRestrict] · simpa lemma aeStronglyMeasurable_mkD_of_uncurry [CompactSpace Y] [Zero Y] [TopologicalSpace X] @@ -100,7 +100,7 @@ lemma aeStronglyMeasurable_mkD_restrict_of_uncurry {t : Set Y} [CompactSpace t] [TopologicalSpace X] [OpensMeasurableSpace X] [SecondCountableTopologyEither X (C(t, E))] (f : X → Y → E) (g : C(t, E)₀) (f_cont : ContinuousOn (Function.uncurry f) (univ ×ˢ t)) (f_zero : ∀ᵐ x ∂μ, f x (0 : t) = 0) : - AEStronglyMeasurable (fun x ↦ mkD (t.restrict (f x)) g) μ := by + AEStronglyMeasurable (fun x ↦ mkD (t.domRestrict (f x)) g) μ := by rw [← ContinuousMapZero.isEmbedding_toContinuousMap.aestronglyMeasurable_comp_iff] refine aestronglyMeasurable_congr ?_ |>.mp <| ContinuousMap.aeStronglyMeasurable_mkD_restrict_of_uncurry f g f_cont @@ -114,7 +114,7 @@ lemma aeStronglyMeasurable_restrict_mkD_restrict_of_uncurry {s : Set X} {t : Set (hs : MeasurableSet s) (f : X → Y → E) (g : C(t, E)₀) (f_cont : ContinuousOn (Function.uncurry f) (s ×ˢ t)) (f_zero : ∀ᵐ x ∂(μ.restrict s), f x (0 : t) = 0) : - AEStronglyMeasurable (fun x ↦ mkD (t.restrict (f x)) g) (μ.restrict s) := by + AEStronglyMeasurable (fun x ↦ mkD (t.domRestrict (f x)) g) (μ.restrict s) := by rw [← ContinuousMapZero.isEmbedding_toContinuousMap.aestronglyMeasurable_comp_iff] refine aestronglyMeasurable_congr ?_ |>.mp <| ContinuousMap.aeStronglyMeasurable_restrict_mkD_restrict_of_uncurry hs f g f_cont diff --git a/Mathlib/NumberTheory/DirichletCharacter/Basic.lean b/Mathlib/NumberTheory/DirichletCharacter/Basic.lean index 35828083f8c8a2..4569ebb8e61f68 100644 --- a/Mathlib/NumberTheory/DirichletCharacter/Basic.lean +++ b/Mathlib/NumberTheory/DirichletCharacter/Basic.lean @@ -463,11 +463,12 @@ variable (R) in of level `n` that send every element of `H` to `1`. -/ noncomputable def annihilator (H : Set (ZMod n)ˣ) : Subgroup (DirichletCharacter R n) := - (MulChar.restrictHom ((Submonoid.closure H).map (Units.coeHom (ZMod n))) _).ker + (MulChar.domRestrictHom ((Submonoid.closure H).map (Units.coeHom (ZMod n))) _).ker theorem mem_annihilator_iff_mem_closure {H : Set (ZMod n)ˣ} {χ : DirichletCharacter R n} : χ ∈ annihilator R H ↔ ∀ x ∈ Submonoid.closure H, χ x = 1 := by - simp only [annihilator, MonoidHom.mem_ker, MulChar.restrictHom_apply, MulChar.restrict_eq_one_iff] + simp only [annihilator, MonoidHom.mem_ker, MulChar.domRestrictHom_apply, + MulChar.domRestrict_eq_one_iff] refine ⟨fun hχ x hx ↦ ?_, fun h u ↦ ?_⟩ · exact hχ <| (Submonoid.unitsEquivUnitsType _) <| ⟨x, Submonoid.mem_units_of_val_mem_inv_val_mem _ ⟨x, hx, rfl⟩ diff --git a/Mathlib/NumberTheory/MulChar/Basic.lean b/Mathlib/NumberTheory/MulChar/Basic.lean index 1eaae6cdaf2b94..dc3c465d304326 100644 --- a/Mathlib/NumberTheory/MulChar/Basic.lean +++ b/Mathlib/NumberTheory/MulChar/Basic.lean @@ -378,23 +378,29 @@ noncomputable def mulEquivToUnitHom : MulChar R R' ≃* (Rˣ →* R'ˣ) := The restriction of a `MulChar` to a submonoid. -/ @[simps! apply] -noncomputable def restrict {S : Type*} [SetLike S R] [SubmonoidClass S R] (T : S) +noncomputable def domRestrict {S : Type*} [SetLike S R] [SubmonoidClass S R] (T : S) (χ : MulChar R R') : MulChar T R' := ofUnitHom <| χ.toUnitHom.comp <| Units.map (SubmonoidClass.subtype T) +@[deprecated (since := "2026-07-19")] alias restrict := domRestrict +@[deprecated (since := "2026-07-19")] alias restrict_apply := domRestrict_apply + /-- The restriction of a `MulChar` to a submonoid as an homomorphism. -/ @[simps] -noncomputable def restrictHom {S : Type*} [SetLike S R] [SubmonoidClass S R] (T : S) +noncomputable def domRestrictHom {S : Type*} [SetLike S R] [SubmonoidClass S R] (T : S) (R'' : Type*) [CommMonoidWithZero R''] : (MulChar R R'') →* MulChar T R'' where - toFun := restrict T + toFun := domRestrict T map_one' := by ext x - rw [restrict_apply, if_pos x.isUnit, MulChar.one_apply x.isUnit.coe, one_apply_coe] + rw [domRestrict_apply, if_pos x.isUnit, MulChar.one_apply x.isUnit.coe, one_apply_coe] map_mul' x y := by ext; simp +@[deprecated (since := "2026-07-19")] alias restrictHom := domRestrictHom +@[deprecated (since := "2026-07-19")] alias restrictHom_apply := domRestrictHom_apply + end Group /-! @@ -419,10 +425,12 @@ lemma eq_one_iff {χ : MulChar R R'} : χ = 1 ↔ ∀ a : Rˣ, χ a = 1 := by lemma ne_one_iff {χ : MulChar R R'} : χ ≠ 1 ↔ ∃ a : Rˣ, χ a ≠ 1 := by simp only [Ne, eq_one_iff, not_forall] -theorem restrict_eq_one_iff {S : Type*} [SetLike S R] [SubmonoidClass S R] {T : S} - {χ : MulChar R R'} : χ.restrict T = 1 ↔ ∀ x : Tˣ, χ x = 1 := by +theorem domRestrict_eq_one_iff {S : Type*} [SetLike S R] [SubmonoidClass S R] {T : S} + {χ : MulChar R R'} : χ.domRestrict T = 1 ↔ ∀ x : Tˣ, χ x = 1 := by simp [eq_one_iff] +@[deprecated (since := "2026-07-19")] alias restrict_eq_one_iff := domRestrict_eq_one_iff + end nontrivial section quadratic_and_comp diff --git a/Mathlib/NumberTheory/MulChar/Duality.lean b/Mathlib/NumberTheory/MulChar/Duality.lean index 849c97a5e8e9f2..a0795bd1294a19 100644 --- a/Mathlib/NumberTheory/MulChar/Duality.lean +++ b/Mathlib/NumberTheory/MulChar/Duality.lean @@ -80,15 +80,17 @@ Let `N` be a submonoid of `M` group and let `R` be a ring with enough roots of u Then any `R`-value multiplicative character of `N` can be extended to a multiplicative character of `M`. -/ -theorem restrictHom_surjective (N : Submonoid M) : - Function.Surjective (MulChar.restrictHom N R) := by +theorem domRestrictHom_surjective (N : Submonoid M) : + Function.Surjective (MulChar.domRestrictHom N R) := by intro χ - obtain ⟨ψ, hψ⟩ := (χ.toUnitHom.comp N.unitsEquivUnitsType).restrict_surjective R N.units + obtain ⟨ψ, hψ⟩ := (χ.toUnitHom.comp N.unitsEquivUnitsType).domRestrict_surjective R N.units refine ⟨MulChar.ofUnitHom ψ, ext fun _ ↦ ?_⟩ - rw [MonoidHom.restrictHom_apply] at hψ - rw [restrictHom_apply, restrict_ofUnitHom] + rw [MonoidHom.domRestrictHom_apply] at hψ + rw [domRestrictHom_apply, domRestrict_ofUnitHom] simp [hψ] +@[deprecated (since := "2026-07-19")] alias restrictHom_surjective := domRestrictHom_surjective + /-- The `MulEquiv` between the double dual `MulChar (MulChar M R) R` of `M` and `Mˣ`. The image `m` of `η : MulChar (MulChar M R) R` is such that, for all `R`-valued multiplicative character `χ` of `M`, we have `χ m = η χ`, see `MulChar.apply_mulCharEquiv`. diff --git a/Mathlib/NumberTheory/MulChar/Lemmas.lean b/Mathlib/NumberTheory/MulChar/Lemmas.lean index a12ad1c2c010eb..71bc5bee79a3f2 100644 --- a/Mathlib/NumberTheory/MulChar/Lemmas.lean +++ b/Mathlib/NumberTheory/MulChar/Lemmas.lean @@ -28,14 +28,15 @@ lemma eq_iff {g : Rˣ} (hg : ∀ x, x ∈ Subgroup.zpowers g) (χ₁ χ₂ : Mul rw [← Equiv.apply_eq_iff_eq equivToUnitHom, MonoidHom.eq_iff_eq_on_generator hg, ← coe_equivToUnitHom, ← coe_equivToUnitHom, Units.ext_iff] -theorem restrict_ofUnitHom (f : Rˣ →* R'ˣ) (S : Submonoid R) : - restrict S (ofUnitHom f) = - ofUnitHom ((f.restrict S.units).comp S.unitsEquivUnitsType.symm) := by +theorem domRestrict_ofUnitHom (f : Rˣ →* R'ˣ) (S : Submonoid R) : domRestrict S (ofUnitHom f) = + ofUnitHom ((f.domRestrict S.units).comp S.unitsEquivUnitsType.symm) := by ext x - simp only [ofUnitHom_eq, restrict_apply, Units.isUnit, reduceIte, equivToUnitHom_symm_coe, - MonoidHom.coe_comp, MonoidHom.coe_coe, Function.comp_apply, MonoidHom.restrict_apply] + simp only [ofUnitHom_eq, domRestrict_apply, Units.isUnit, reduceIte, equivToUnitHom_symm_coe, + MonoidHom.coe_comp, MonoidHom.coe_coe, Function.comp_apply, MonoidHom.domRestrict_apply] rw [← Submonoid.val_unitsEquivUnitsType_symm_apply_coe S x, equivToUnitHom_symm_coe] +@[deprecated (since := "2026-07-19")] alias restrict_ofUnitHom := domRestrict_ofUnitHom + end CommMonoid section Ring diff --git a/Mathlib/NumberTheory/NumberField/CMField.lean b/Mathlib/NumberTheory/NumberField/CMField.lean index 0e67085517ab75..8272694d46d539 100644 --- a/Mathlib/NumberTheory/NumberField/CMField.lean +++ b/Mathlib/NumberTheory/NumberField/CMField.lean @@ -329,7 +329,7 @@ The action of `unitsMulComplexConjInv` of the torsion is the same as the 2-power -/ theorem map_unitsMulComplexConjInv_torsion : Subgroup.map (unitsMulComplexConjInv K) (torsion K) = (powMonoidHom 2).range := by - rw [← MonoidHom.restrict_range] + rw [← MonoidHom.domRestrict_range] exact congr_arg (MonoidHom.range ·) (MonoidHom.ext fun ζ ↦ by simp) /-- diff --git a/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean b/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean index 885aaaba9c7c07..f7da87a7b6c8eb 100644 --- a/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Ideal/Basic.lean @@ -54,7 +54,7 @@ For `I` an integral ideal of `K`, the group morphism from the group of roots of of order `n` to `(𝓞 K ⧸ I)ˣ`. -/ def Ideal.rootsOfUnityMapQuot (n : ℕ) : (rootsOfUnity n (𝓞 K)) →* ((𝓞 K) ⧸ I)ˣ := - (Units.map (Ideal.Quotient.mk I).toMonoidHom).restrict _ + (Units.map (Ideal.Quotient.mk I).toMonoidHom).domRestrict _ @[simp] theorem Ideal.rootsOfUnityMapQuot_apply (n : ℕ) {x : (𝓞 K)ˣ} (hx : x ∈ rootsOfUnity n (𝓞 K)) : @@ -64,7 +64,7 @@ theorem Ideal.rootsOfUnityMapQuot_apply (n : ℕ) {x : (𝓞 K)ˣ} (hx : x ∈ r For `I` an integral ideal of `K`, the group morphism from the torsion of `K` to `(𝓞 K ⧸ I)ˣ`. -/ def Ideal.torsionMapQuot : (Units.torsion K) →* ((𝓞 K) ⧸ I)ˣ := - (Units.map (Ideal.Quotient.mk I).toMonoidHom).restrict (torsion K) + (Units.map (Ideal.Quotient.mk I).toMonoidHom).domRestrict (torsion K) @[simp] theorem Ideal.torsionMapQuot_apply {x : (𝓞 K)ˣ} (hx : x ∈ torsion K) : diff --git a/Mathlib/Order/Interval/Set/ProjIcc.lean b/Mathlib/Order/Interval/Set/ProjIcc.lean index 1f2ecf76cbfc6e..b8d6abf42ab99d 100644 --- a/Mathlib/Order/Interval/Set/ProjIcc.lean +++ b/Mathlib/Order/Interval/Set/ProjIcc.lean @@ -283,6 +283,9 @@ protected theorem Set.OrdConnected.IicExtend {s : Set (Iic b)} (hs : s.OrdConnec {x | IicExtend (· ∈ s) x}.OrdConnected := ⟨fun _ hx _ hy _ hz => hs.out hx hy ⟨min_le_min le_rfl hz.1, min_le_min le_rfl hz.2⟩⟩ -protected theorem Set.OrdConnected.restrict (hs : s.OrdConnected) : - {x | restrict t (· ∈ s) x}.OrdConnected := +protected theorem Set.OrdConnected.domRestrict (hs : s.OrdConnected) : + {x | domRestrict t (· ∈ s) x}.OrdConnected := ⟨fun _ hx _ hy _ hz => hs.out hx hy hz⟩ + +@[deprecated (since := "2026-07-19")] +alias Set.OrdConnected.restrict := Set.OrdConnected.domRestrict diff --git a/Mathlib/Order/ModularLattice.lean b/Mathlib/Order/ModularLattice.lean index 26c414b0e8ba09..71243a72638390 100644 --- a/Mathlib/Order/ModularLattice.lean +++ b/Mathlib/Order/ModularLattice.lean @@ -252,10 +252,10 @@ def infIccOrderIsoIccSup' (a b : α) : Icc (a ⊓ b) b ≃o Icc a (a ⊔ b) := OrderIso.setCongr _ _ (by rw [sup_comm]) theorem inf_strictMonoOn_Icc_sup {a b : α} : StrictMonoOn (fun c => a ⊓ c) (Icc b (a ⊔ b)) := - StrictMono.of_restrict (infIccOrderIsoIccSup a b).symm.strictMono + StrictMono.of_domRestrict (infIccOrderIsoIccSup a b).symm.strictMono theorem sup_strictMonoOn_Icc_inf {a b : α} : StrictMonoOn (fun c => c ⊔ b) (Icc (a ⊓ b) a) := - StrictMono.of_restrict (infIccOrderIsoIccSup a b).strictMono + StrictMono.of_domRestrict (infIccOrderIsoIccSup a b).strictMono set_option backward.isDefEq.respectTransparency false in /-- The diamond isomorphism between the open intervals `(a ⊓ b, a)` and `(b, a ⊔ b)`. -/ diff --git a/Mathlib/Order/Restriction.lean b/Mathlib/Order/Restriction.lean index a17dd0147bd0d0..e5f7475638b24f 100644 --- a/Mathlib/Order/Restriction.lean +++ b/Mathlib/Order/Restriction.lean @@ -36,14 +36,14 @@ section Set open Set /-- Restrict domain of a function `f` indexed by `α` to elements `≤ a`. -/ -def restrictLe (a : α) := (Iic a).restrict (π := π) +def restrictLe (a : α) := (Iic a).domRestrict (π := π) @[simp] lemma restrictLe_apply (a : α) (f : (a : α) → π a) (i : Iic a) : restrictLe a f i = f i := rfl /-- If a function `f` indexed by `α` is restricted to elements `≤ π`, and `a ≤ b`, this is the restriction to elements `≤ a`. -/ -def restrictLe₂ {a b : α} (hab : a ≤ b) := Set.restrict₂ (π := π) (Iic_subset_Iic.2 hab) +def restrictLe₂ {a b : α} (hab : a ≤ b) := Set.domRestrict₂ (π := π) (Iic_subset_Iic.2 hab) @[simp] lemma restrictLe₂_apply {a b : α} (hab : a ≤ b) (f : (i : Iic b) → π i) (i : Iic a) : @@ -56,7 +56,7 @@ theorem restrictLe₂_comp_restrictLe₂ {a b c : α} (hab : a ≤ b) (hbc : b (restrictLe₂ (π := π) hab) ∘ (restrictLe₂ hbc) = restrictLe₂ (hab.trans hbc) := rfl lemma dependsOn_restrictLe (a : α) : DependsOn (restrictLe (π := π) a) (Iic a) := - (Iic a).dependsOn_restrict + (Iic a).dependsOn_domRestrict end Set diff --git a/Mathlib/Probability/Independence/Process/Basic.lean b/Mathlib/Probability/Independence/Process/Basic.lean index 9cb717c758512d..35950009968220 100644 --- a/Mathlib/Probability/Independence/Process/Basic.lean +++ b/Mathlib/Probability/Independence/Process/Basic.lean @@ -49,8 +49,8 @@ lemma IndepFun.process_congr_left {𝓧 : S → Type*} {𝓨 : Type*} κ a ((fun ω i ↦ X i ω) ⁻¹' s) * κ a (Y ⁻¹' t) := h1 ((fun ω i ↦ X i ω) ⁻¹' s) (Y ⁻¹' t) ⟨s, hs, rfl⟩ ⟨t, ht, rfl⟩ obtain ⟨I, u, hI, rfl⟩ : ∃ (I : Set S) (u : Set (Π i : I, 𝓧 i)), - I.Countable ∧ s = I.restrict ⁻¹' u := hs.eq_preimage_restrict_countable - have aux (f : (i : S) → Ω → 𝓧 i) : (fun ω i ↦ f i ω) ⁻¹' I.restrict ⁻¹' u = + I.Countable ∧ s = I.domRestrict ⁻¹' u := hs.eq_preimage_restrict_countable + have aux (f : (i : S) → Ω → 𝓧 i) : (fun ω i ↦ f i ω) ⁻¹' I.domRestrict ⁻¹' u = (fun ω (i : I) ↦ f i ω) ⁻¹' u := rfl simp_rw [aux] at * have _ : Countable I := hI.to_subtype @@ -206,16 +206,16 @@ lemma iIndepFun.process_congr {T : S → Type*} {𝓧 : (i : S) → (j : T i) simp_rw [h3, h3'] choose! I u hI hu using fun i hi ↦ (mg i hi).eq_preimage_restrict_countable have h4 (f : (i : S) → (j : T i) → Ω → 𝓧 i j) : ⋂ i ∈ s, (fun i ω j ↦ f i j ω) i ⁻¹' g i = - ⋂ i ∈ s, (fun i ω j ↦ f i j ω) i ⁻¹' (I i).restrict ⁻¹' u i := + ⋂ i ∈ s, (fun i ω j ↦ f i j ω) i ⁻¹' (I i).domRestrict ⁻¹' u i := (biInf_congr (fun i hi ↦ by rw [hu i hi])).symm have h4' a (f : (i : S) → (j : T i) → Ω → 𝓧 i j) : ∏ i ∈ s, κ a ((fun i ω j ↦ f i j ω) i ⁻¹' g i) = - ∏ i ∈ s, κ a ((fun i ω j ↦ f i j ω) i ⁻¹' (I i).restrict ⁻¹' u i) := by + ∏ i ∈ s, κ a ((fun i ω j ↦ f i j ω) i ⁻¹' (I i).domRestrict ⁻¹' u i) := by refine Finset.prod_congr rfl fun i hi ↦ ?_ rw [hu i hi] have h5 := h1 s (fun i hi ↦ ⟨g i, mg i hi, rfl⟩) simp_rw [h4, h4'] at h5 ⊢ - have h6 i (f : (j : T i) → Ω → 𝓧 i j) : (fun ω j ↦ f j ω) ⁻¹' (I i).restrict ⁻¹' (u i) = + have h6 i (f : (j : T i) → Ω → 𝓧 i j) : (fun ω j ↦ f j ω) ⁻¹' (I i).domRestrict ⁻¹' (u i) = (fun ω (j : I i) ↦ f j ω) ⁻¹' (u i) := rfl simp_rw [h6] at h5 ⊢ have h : diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean b/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean index a122983ba7a04b..b080a0a7338c44 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean @@ -581,7 +581,7 @@ theorem traj_comp_partialTraj {a b : ℕ} (hab : a ≤ b) : a deterministic kernel with another kernel. This is an intermediate result to compute integrals with respect to this kernel. -/ theorem traj_eq_prod (a : ℕ) : - traj κ a = (Kernel.id ×ₖ (traj κ a).map (Set.Ioi a).restrict).map (IicProdIoi a) := by + traj κ a = (Kernel.id ×ₖ (traj κ a).map (Set.Ioi a).domRestrict).map (IicProdIoi a) := by refine (eq_traj' _ (a + 1) _ fun b hb ↦ ?_).symm rw [← map_comp_right] conv_lhs => enter [2]; change (IicProdIoc a b) ∘ @@ -598,7 +598,7 @@ set_option backward.isDefEq.respectTransparency.types false in theorem traj_map_updateFinset {n : ℕ} (x : Π i : Iic n, X i) : (traj κ n x).map (updateFinset · (Iic n) x) = traj κ n x := by nth_rw 2 [traj_eq_prod] - have : (updateFinset · _ x) = IicProdIoi n ∘ (Prod.mk x) ∘ (Set.Ioi n).restrict := by + have : (updateFinset · _ x) = IicProdIoi n ∘ (Prod.mk x) ∘ (Set.Ioi n).domRestrict := by ext; simp [IicProdIoi, updateFinset] rw [this, ← Function.comp_assoc, ← Measure.map_map, ← Measure.map_map, map_apply, prod_apply, map_apply, id_apply, Measure.dirac_prod] diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index 1acab2920eb875..7230b6601715e1 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -527,7 +527,7 @@ def piFinset : @Filtration (Π i, X i) (Finset ι) _ pi where le' s := s.measurable_restrict.comap_le lemma piFinset_eq_comap_restrict (s : Finset ι) : - piFinset (X := X) s = pi.comap (s : Set ι).restrict := rfl + piFinset (X := X) s = pi.comap (s : Set ι).domRestrict := rfl end piFinset diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 7b190245593c6d..72e3d37a65d1c5 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -958,7 +958,7 @@ theorem isStronglyProgressive_min_stopping_time [PseudoMetrizableSpace ι] suffices h_min_eq_left : (fun x : sc => min (↑(x : Set.Iic i × Ω).fst) (τ (x : Set.Iic i × Ω).snd)) = fun x : sc => ↑(x : Set.Iic i × Ω).fst by - simp +unfoldPartialApp only [sc, Set.restrict, h_min_eq_left] + simp +unfoldPartialApp only [sc, Set.domRestrict, h_min_eq_left] exact (h_meas_fst _).withTop_coe ext1 ω rw [min_eq_left] diff --git a/Mathlib/Probability/ProductMeasure.lean b/Mathlib/Probability/ProductMeasure.lean index d794815f67ec67..5f4f6d45baa1e5 100644 --- a/Mathlib/Probability/ProductMeasure.lean +++ b/Mathlib/Probability/ProductMeasure.lean @@ -414,11 +414,11 @@ lemma infinitePi_pi {s : Finset ι} {t : (i : ι) → Set (X i)} · exact .univ_pi fun i ↦ mt i.1 i.2 theorem infinitePi_map_restrict' {I : Set ι} : - (infinitePi μ).map I.restrict = infinitePi fun i : I ↦ μ i := by + (infinitePi μ).map I.domRestrict = infinitePi fun i : I ↦ μ i := by apply eq_infinitePi intro s t ht classical - rw [map_apply (by fun_prop), restrict_preimage, infinitePi_pi _ (by measurability)] + rw [map_apply (by fun_prop), domRestrict_preimage, infinitePi_pi _ (by measurability)] · simp · exact .pi s.countable_toSet (by measurability) @@ -432,7 +432,7 @@ lemma infinitePi_pi_of_countable {s : Set ι} (hs : Countable s) {t : (i : ι) · conv in ∏ _ ∈ _, _ => rw [← infinitePi_pi _ (by measurability), ← infinitePi_map_restrict', map_apply (by fun_prop) (by apply MeasurableSet.pi (countable_toSet _) (by measurability)), - restrict_preimage] + domRestrict_preimage] simp only [coe_image, dite_eq_ite] have : s.pi t = ⋂ s' : Finset s, diff --git a/Mathlib/RingTheory/AlgebraTower.lean b/Mathlib/RingTheory/AlgebraTower.lean index bb118571dec097..115298b1016d52 100644 --- a/Mathlib/RingTheory/AlgebraTower.lean +++ b/Mathlib/RingTheory/AlgebraTower.lean @@ -186,21 +186,23 @@ variable {A} {C D : Type*} [CommSemiring A] [CommSemiring C] [CommSemiring D] [A variable [CommSemiring B] [Algebra A B] [Algebra B C] [IsScalarTower A B C] (f : C →ₐ[A] D) /-- Restrict the domain of an `AlgHom`. -/ -def AlgHom.restrictDomain : B →ₐ[A] D := +def AlgHom.domRestrict : B →ₐ[A] D := f.comp (IsScalarTower.toAlgHom A B C) +@[deprecated (since := "2026-07-19")] alias AlgHom.restrictDomain := AlgHom.domRestrict + /-- Extend the scalars of an `AlgHom`. -/ -def AlgHom.extendScalars : @AlgHom B C D _ _ _ _ (f.restrictDomain B).toRingHom.toAlgebra where +def AlgHom.extendScalars : @AlgHom B C D _ _ _ _ (f.domRestrict B).toRingHom.toAlgebra where __ := f commutes' := fun _ ↦ rfl - __ := (f.restrictDomain B).toRingHom.toAlgebra + __ := (f.domRestrict B).toRingHom.toAlgebra variable {B} /-- `AlgHom`s from the top of a tower are equivalent to a pair of `AlgHom`s. -/ def algHomEquivSigma : (C →ₐ[A] D) ≃ Σ f : B →ₐ[A] D, @AlgHom B C D _ _ _ _ f.toRingHom.toAlgebra where - toFun f := ⟨f.restrictDomain B, f.extendScalars B⟩ + toFun f := ⟨f.domRestrict B, f.extendScalars B⟩ invFun fg := let _ := fg.1.toRingHom.toAlgebra fg.2.restrictScalars A diff --git a/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean b/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean index 4341d511a5dfeb..f3f901a4a128fa 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/Basic.lean @@ -263,7 +263,7 @@ theorem algebraicIndependent_bounded_of_finset_algebraicIndependent_bounded {n : section Subtype theorem AlgebraicIndependent.restrict_of_comp_subtype {s : Set ι} - (hs : AlgebraicIndependent R (x ∘ (↑) : s → A)) : AlgebraicIndependent R (s.restrict x) := + (hs : AlgebraicIndependent R (x ∘ (↑) : s → A)) : AlgebraicIndependent R (s.domRestrict x) := hs variable (R A) diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean index ec145943e0646d..4d82e9594a1417 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean @@ -171,7 +171,7 @@ theorem integralClosure_map_algEquiv [Algebra R S] (f : A ≃ₐ[R] S) : them. -/ def AlgHom.mapIntegralClosure [Algebra R S] (f : A →ₐ[R] S) : integralClosure R A →ₐ[R] integralClosure R S := - (f.restrictDomain (integralClosure R A)).codRestrict (integralClosure R S) (fun ⟨_, h⟩ => h.map f) + (f.domRestrict (integralClosure R A)).codRestrict (integralClosure R S) (fun ⟨_, h⟩ => h.map f) @[simp] theorem AlgHom.coe_mapIntegralClosure [Algebra R S] (f : A →ₐ[R] S) diff --git a/Mathlib/RingTheory/Localization/Defs.lean b/Mathlib/RingTheory/Localization/Defs.lean index c4ee68b3b7f6ed..5285a6a75ec002 100644 --- a/Mathlib/RingTheory/Localization/Defs.lean +++ b/Mathlib/RingTheory/Localization/Defs.lean @@ -465,12 +465,12 @@ theorem mk'_add (x₁ x₂ : R) (y₁ y₂ : M) : set_option backward.isDefEq.respectTransparency false in theorem mul_add_inv_left {g : R →+* P} (h : ∀ y : M, IsUnit (g y)) (y : M) (w z₁ z₂ : P) : - w * ↑(IsUnit.liftRight (g.toMonoidHom.restrict M) h y)⁻¹ + z₁ = + w * ↑(IsUnit.liftRight (g.toMonoidHom.domRestrict M) h y)⁻¹ + z₁ = z₂ ↔ w + g y * z₁ = g y * z₂ := by - rw [mul_comm, ← one_mul z₁, ← Units.inv_mul (IsUnit.liftRight (g.toMonoidHom.restrict M) h y), + rw [mul_comm, ← one_mul z₁, ← Units.inv_mul (IsUnit.liftRight (g.toMonoidHom.domRestrict M) h y), mul_assoc, ← mul_add, Units.inv_mul_eq_iff_eq_mul, Units.inv_mul_cancel_left, IsUnit.coe_liftRight] - simp [RingHom.toMonoidHom_eq_coe, MonoidHom.restrict_apply] + simp [RingHom.toMonoidHom_eq_coe, MonoidHom.domRestrict_apply] theorem lift_spec_mul_add {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) (z w w' v) : ((toLocalizationMap M S).lift hg) z * w + w' = v ↔ @@ -506,7 +506,7 @@ variable {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) `g : R →* P` such that `g y` is invertible for all `y : M`, the homomorphism induced from `S` to `P` maps `f x * (f y)⁻¹` to `g x * (g y)⁻¹` for all `x : R, y ∈ M`. -/ theorem lift_mk' (x y) : - lift hg (mk' S x y) = g x * ↑(IsUnit.liftRight (g.toMonoidHom.restrict M) hg y)⁻¹ := + lift hg (mk' S x y) = g x * ↑(IsUnit.liftRight (g.toMonoidHom.domRestrict M) hg y)⁻¹ := (toLocalizationMap M S).lift_mk' _ _ _ theorem lift_mk'_spec (x v) (y : M) : lift hg (mk' S x y) = v ↔ g x = g y * v := diff --git a/Mathlib/RingTheory/Norm/Basic.lean b/Mathlib/RingTheory/Norm/Basic.lean index 3d824925a0be44..9d7cce53e9e6c7 100644 --- a/Mathlib/RingTheory/Norm/Basic.lean +++ b/Mathlib/RingTheory/Norm/Basic.lean @@ -205,7 +205,7 @@ theorem prod_embeddings_eq_finrank_pow [Algebra L F] [IsScalarTower K L F] [IsAl congr exact AlgHom.card L F E · intro σ - simp only [algHomEquivSigma, Equiv.coe_fn_mk, AlgHom.restrictDomain, AlgHom.comp_apply, + simp only [algHomEquivSigma, Equiv.coe_fn_mk, AlgHom.domRestrict, AlgHom.comp_apply, IsScalarTower.coe_toAlgHom'] lemma norm_eq_of_algEquiv [Ring T] [Algebra R T] (e : S ≃ₐ[R] T) (x) : diff --git a/Mathlib/RingTheory/Trace/Basic.lean b/Mathlib/RingTheory/Trace/Basic.lean index 6a1ebb4d996197..f2faaedc18e787 100644 --- a/Mathlib/RingTheory/Trace/Basic.lean +++ b/Mathlib/RingTheory/Trace/Basic.lean @@ -246,7 +246,7 @@ theorem sum_embeddings_eq_finrank_mul [FiniteDimensional K F] [Algebra.IsSeparab let : Algebra L E := σ.toRingHom.toAlgebra simp_rw [Finset.sum_const, Finset.card_univ, ← AlgHom.card L F E] · intro σ - simp only [algHomEquivSigma, Equiv.coe_fn_mk, AlgHom.restrictDomain, AlgHom.comp_apply, + simp only [algHomEquivSigma, Equiv.coe_fn_mk, AlgHom.domRestrict, AlgHom.comp_apply, IsScalarTower.coe_toAlgHom'] theorem trace_eq_sum_embeddings [FiniteDimensional K L] [Algebra.IsSeparable K L] {x : L} : diff --git a/Mathlib/RingTheory/Unramified/Basic.lean b/Mathlib/RingTheory/Unramified/Basic.lean index e43c70344a6464..f28b28d1e42a3a 100644 --- a/Mathlib/RingTheory/Unramified/Basic.lean +++ b/Mathlib/RingTheory/Unramified/Basic.lean @@ -220,7 +220,7 @@ theorem comp [FormallyUnramified R A] [FormallyUnramified A B] : have e' := FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B) (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc]) - let := (f₁.restrictDomain A).toAlgebra + let := (f₁.domRestrict A).toAlgebra let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl } let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm } ext1 x diff --git a/Mathlib/SetTheory/Cardinal/SchroederBernstein.lean b/Mathlib/SetTheory/Cardinal/SchroederBernstein.lean index 71617b5757f725..b723fe84f29f69 100644 --- a/Mathlib/SetTheory/Cardinal/SchroederBernstein.lean +++ b/Mathlib/SetTheory/Cardinal/SchroederBernstein.lean @@ -135,7 +135,7 @@ theorem min_injective [I : Nonempty ι] : ∃ i, Nonempty (∀ j, β i ↪ β j) hs.eq_of_subset this (subset_insert _ _) ▸ mem_insert .. let ⟨i⟩ := I hf i f this rfl - ⟨i, ⟨fun j => ⟨s.restrict (fun x => x j) ∘ surjInv e, + ⟨i, ⟨fun j => ⟨s.domRestrict (fun x => x j) ∘ surjInv e, ((hs.1 j).injective).comp (injective_surjInv _)⟩⟩⟩ end Wo diff --git a/Mathlib/Topology/Algebra/GroupWithZero.lean b/Mathlib/Topology/Algebra/GroupWithZero.lean index 03ea9232739f5e..ad409ad08d53ad 100644 --- a/Mathlib/Topology/Algebra/GroupWithZero.lean +++ b/Mathlib/Topology/Algebra/GroupWithZero.lean @@ -155,8 +155,8 @@ def Homeomorph.inv₀ : {g : G₀ // g ≠ 0} ≃ₜ {g : G₀ // g ≠ 0} where invFun g := ⟨g⁻¹, inv_ne_zero g.2⟩ left_inv _ := by simp right_inv _ := by simp - continuous_toFun := continuous_induced_rng.mpr continuousOn_inv₀.restrict - continuous_invFun := continuous_induced_rng.mpr continuousOn_inv₀.restrict + continuous_toFun := continuous_induced_rng.mpr continuousOn_inv₀.domRestrict + continuous_invFun := continuous_induced_rng.mpr continuousOn_inv₀.domRestrict end GroupWithZero diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index e29ceff425043b..2480307ec0476c 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -164,8 +164,8 @@ lemma hasProd_unique [Unique β] (f : β → α) (L := unconditional β) [L.LeAt hasProd_single default (fun _ hb ↦ False.elim <| hb <| Unique.uniq ..) L @[to_additive (attr := simp)] -lemma hasProd_singleton (m : β) (f : β → α) : HasProd (({m} : Set β).restrict f) (f m) := - hasProd_unique (Set.restrict {m} f) +lemma hasProd_singleton (m : β) (f : β → α) : HasProd (({m} : Set β).domRestrict f) (f m) := + hasProd_unique (Set.domRestrict {m} f) @[to_additive] theorem hasProd_ite_eq (b : β) [DecidablePred (· = b)] (a : α) (L := unconditional β) [L.LeAtTop] : diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean index ce6e991cf40b4d..56ccf8a30b50bf 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Restrict.lean @@ -101,7 +101,7 @@ theorem toLinearMap_domRestrict (f : M₁ →SL[σ₁₂] M₂) (p : Submodule R rfl lemma coe_domRestrict (f : M₁ →SL[σ₁₂] M₂) (p : Submodule R₁ M₁) : - ⇑(f.domRestrict p) = Set.restrict p f := + ⇑(f.domRestrict p) = Set.domRestrict p f := rfl /-- Restrict codomain of a continuous linear map. -/ diff --git a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean index adf0c8d87dad25..093a172afc1321 100644 --- a/Mathlib/Topology/Algebra/Module/UniformConvergence.lean +++ b/Mathlib/Topology/Algebra/Module/UniformConvergence.lean @@ -102,11 +102,11 @@ lemma UniformOnFun.continuousSMul_induced_of_image_bounded (φ : hom) (hφ : IsI simp +instances only [induced_iInf, UniformOnFun.topologicalSpace_eq, induced_compose] refine continuousSMul_iInf fun s ↦ continuousSMul_iInf fun hs ↦ ?_ let : TopologicalSpace H := - .induced (UniformFun.ofFun ∘ s.restrict ∘ φ) (UniformFun.topologicalSpace s E) + .induced (UniformFun.ofFun ∘ s.domRestrict ∘ φ) (UniformFun.topologicalSpace s E) set φ' : H →ₗ[𝕜] (s → E) := - { toFun := s.restrict ∘ φ, - map_smul' := fun c x ↦ by exact congr_arg s.restrict (map_smul φ c x), - map_add' := fun x y ↦ by exact congr_arg s.restrict (map_add φ x y) } + { toFun := s.domRestrict ∘ φ, + map_smul' := fun c x ↦ by exact congr_arg s.domRestrict (map_smul φ c x), + map_add' := fun x y ↦ by exact congr_arg s.domRestrict (map_add φ x y) } refine UniformFun.continuousSMul_induced_of_range_bounded 𝕜 s E H φ' ⟨rfl⟩ fun u ↦ ?_ simpa only [Set.image_eq_range] using! h u s hs diff --git a/Mathlib/Topology/Algebra/Monoid.lean b/Mathlib/Topology/Algebra/Monoid.lean index 23c34ccf2b01b5..0dac831950493b 100644 --- a/Mathlib/Topology/Algebra/Monoid.lean +++ b/Mathlib/Topology/Algebra/Monoid.lean @@ -789,10 +789,10 @@ theorem continuousOn_list_prod {f : ι → X → M} (l : List ι) {t : Set X} (h : ∀ i ∈ l, ContinuousOn (f i) t) : ContinuousOn (fun a => (l.map fun i => f i a).prod) t := by intro x hx - rw [continuousWithinAt_iff_continuousAt_restrict _ hx] + rw [continuousWithinAt_iff_continuousAt_domRestrict _ hx] refine tendsto_list_prod _ fun i hi => ?_ specialize h i hi x hx - rw [continuousWithinAt_iff_continuousAt_restrict _ hx] at h + rw [continuousWithinAt_iff_continuousAt_domRestrict _ hx] at h exact h @[to_additive (attr := continuity)] diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index b250d026204b26..de6303f57eff6c 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -284,7 +284,7 @@ theorem binaryCofan_isColimit_iff {X Y : TopCat.{u}} (c : BinaryCofan X Y) : by_cases h : x ∈ Set.range c.inl · revert h x apply (IsOpen.continuousOn_iff _).mp - · rw [continuousOn_iff_continuous_restrict] + · rw [continuousOn_iff_continuous_domRestrict] convert_to Continuous (f ∘ h₁.isEmbedding.toHomeomorph.symm) · ext ⟨x, hx⟩ exact dif_pos hx @@ -293,7 +293,7 @@ theorem binaryCofan_isColimit_iff {X Y : TopCat.{u}} (c : BinaryCofan X Y) : · revert h x simp only [← mem_compl_iff] apply (IsOpen.continuousOn_iff _).mp - · rw [continuousOn_iff_continuous_restrict] + · rw [continuousOn_iff_continuous_domRestrict] have : ∀ a, a ∉ Set.range c.inl → a ∈ Set.range c.inr := by rintro a (h : a ∈ (Set.range c.inl)ᶜ) rwa [eq_compl_iff_isCompl.mpr h₃.symm] diff --git a/Mathlib/Topology/Clopen.lean b/Mathlib/Topology/Clopen.lean index 0481c2b7bd21d4..6eca3456925d07 100644 --- a/Mathlib/Topology/Clopen.lean +++ b/Mathlib/Topology/Clopen.lean @@ -143,7 +143,7 @@ theorem continuous_boolIndicator_iff_isClopen (U : Set X) : theorem continuousOn_boolIndicator_iff_isClopen (s U : Set X) : ContinuousOn U.boolIndicator s ↔ IsClopen (((↑) : s → X) ⁻¹' U) := by - rw [continuousOn_iff_continuous_restrict, ← continuous_boolIndicator_iff_isClopen] + rw [continuousOn_iff_continuous_domRestrict, ← continuous_boolIndicator_iff_isClopen] rfl end Clopen diff --git a/Mathlib/Topology/Coherent.lean b/Mathlib/Topology/Coherent.lean index dfa687ac874a5e..35e101e166914c 100644 --- a/Mathlib/Topology/Coherent.lean +++ b/Mathlib/Topology/Coherent.lean @@ -52,12 +52,12 @@ protected theorem continuous_iff {Y : Type*} [TopologicalSpace Y] {f : X → Y} (hS : IsCoherentWith S) : Continuous f ↔ ∀ s ∈ S, ContinuousOn f s := ⟨fun h _ _ ↦ h.continuousOn, fun h ↦ continuous_def.2 fun _u hu ↦ hS.isOpen_iff.2 fun s hs ↦ - hu.preimage <| (h s hs).restrict⟩ + hu.preimage <| (h s hs).domRestrict⟩ theorem of_continuous_prop (h : ∀ f : X → Prop, (∀ s ∈ S, ContinuousOn f s) → Continuous f) : IsCoherentWith S where isOpen_of_forall_induced u hu := by - simp only [continuousOn_iff_continuous_restrict, continuous_Prop] at * + simp only [continuousOn_iff_continuous_domRestrict, continuous_Prop] at * exact h _ hu theorem of_isClosed (h : ∀ t : Set X, (∀ s ∈ S, IsClosed ((↑) ⁻¹' t : Set s)) → IsClosed t) : diff --git a/Mathlib/Topology/CompactOpen.lean b/Mathlib/Topology/CompactOpen.lean index baa2fdad25904d..72358cfcca49fb 100644 --- a/Mathlib/Topology/CompactOpen.lean +++ b/Mathlib/Topology/CompactOpen.lean @@ -443,7 +443,7 @@ theorem continuous_of_continuous_uncurry (f : X → C(Y, Z)) theorem continuousOn_of_continuousOn_uncurry {s : Set X} (f : X → C(Y, Z)) (h : ContinuousOn (Function.uncurry fun x y => f x y) (s ×ˢ univ)) : ContinuousOn f s := - continuousOn_iff_continuous_restrict.mpr <| continuous_of_continuous_uncurry _ <| + continuousOn_iff_continuous_domRestrict.mpr <| continuous_of_continuous_uncurry _ <| h.comp_continuous (continuous_subtype_val.prodMap continuous_id) (fun x ↦ ⟨x.1.2, trivial⟩) /-- The currying process is a continuous map between function spaces. -/ @@ -507,7 +507,7 @@ lemma continuousOn_mkD_of_uncurry {s : Set T} ContinuousOn (fun x ↦ mkD (f x) g) s := by have (x) (hx : x ∈ s) : Continuous (f x) := f_cont.comp_continuous (Continuous.prodMk_right x) fun _ ↦ ⟨hx, trivial⟩ - simp_rw [continuousOn_iff_continuous_restrict, s.restrict_def] + simp_rw [continuousOn_iff_continuous_domRestrict, s.domRestrict_def] refine continuous_of_continuous_uncurry _ ?_ conv in mkD _ _ => rw [mkD_of_continuous (this x x.2)] exact f_cont.comp_continuous (.prodMap continuous_subtype_val continuous_id) @@ -516,7 +516,7 @@ lemma continuousOn_mkD_of_uncurry {s : Set T} open Set in lemma continuous_mkD_restrict_of_uncurry {t : Set X} (f : T → X → Y) (g : C(t, Y)) (f_cont : ContinuousOn (Function.uncurry f) (univ ×ˢ t)) : - Continuous (fun x ↦ mkD (t.restrict (f x)) g) := by + Continuous (fun x ↦ mkD (t.domRestrict (f x)) g) := by have (x : _) : ContinuousOn (f x) t := f_cont.comp (Continuous.prodMk_right x).continuousOn fun _ hz ↦ ⟨trivial, hz⟩ refine continuous_of_continuous_uncurry _ ?_ @@ -528,10 +528,10 @@ open Set in lemma continuousOn_mkD_restrict_of_uncurry {s : Set T} {t : Set X} (f : T → X → Y) (g : C(t, Y)) (f_cont : ContinuousOn (Function.uncurry f) (s ×ˢ t)) : - ContinuousOn (fun x ↦ mkD (t.restrict (f x)) g) s := by + ContinuousOn (fun x ↦ mkD (t.domRestrict (f x)) g) s := by have (x) (hx : x ∈ s) : ContinuousOn (f x) t := f_cont.comp (Continuous.prodMk_right x).continuousOn fun _ hz ↦ ⟨hx, hz⟩ - simp_rw [continuousOn_iff_continuous_restrict, s.restrict_def] + simp_rw [continuousOn_iff_continuous_domRestrict, s.domRestrict_def] refine continuous_of_continuous_uncurry _ ?_ conv in mkD _ _ => rw [mkD_of_continuousOn (this x x.2)] exact f_cont.comp_continuous (.prodMap continuous_subtype_val continuous_subtype_val) diff --git a/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean b/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean index ad1d65b950c285..0c2ee518a18fcc 100644 --- a/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean +++ b/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean @@ -166,7 +166,7 @@ lemma continuous_dom_iff {f : 𝐤X → Y} : Continuous f ↔ (∀ (K : Set X), IsCompact K → ContinuousOn (f ∘ CompactCoherentification.mk X) K) := by simp_rw [continuous_coinduced_dom, continuous_iSup_dom, continuous_coinduced_dom, - continuousOn_iff_continuous_restrict] + continuousOn_iff_continuous_domRestrict] rfl lemma continuous_mk_symm : Continuous (CompactCoherentification.mk X).symm := by @@ -185,7 +185,7 @@ lemma isOpenMap_mk : IsOpenMap (CompactCoherentification.mk X) := by lemma continuousOn_isCompact_mk {K : Set X} (hK : IsCompact K) : ContinuousOn (CompactCoherentification.mk X) K := by - rw [continuousOn_iff_continuous_restrict] + rw [continuousOn_iff_continuous_domRestrict] exact ⟨fun U hU ↦ isOpen_iff.mp hU K hK⟩ lemma continuousOn_rng_of_isCompact {f : X → 𝐤Y} {K : Set X} @@ -223,7 +223,7 @@ lemma continuous_mk_comp_iff_of_compactSpace [CompactSpace X] {f : X → Y} : lemma continuousOn_mk_comp_iff_of_Compact {A : Set X} (hA : IsCompact A) {f : X → Y} : ContinuousOn ((CompactCoherentification.mk Y) ∘ f) A ↔ ContinuousOn f A := by - simp_rw [continuousOn_iff_continuous_restrict] + simp_rw [continuousOn_iff_continuous_domRestrict] let := isCompact_iff_compactSpace.1 hA exact continuous_mk_comp_iff_of_compactSpace diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index 758c9254cedd4c..e553a7ed5291f3 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -393,10 +393,12 @@ theorem IsOpen.isOpenEmbedding_subtypeVal {s : Set X} (hs : IsOpen s) : theorem IsOpen.isOpenMap_subtype_val {s : Set X} (hs : IsOpen s) : IsOpenMap ((↑) : s → X) := hs.isOpenEmbedding_subtypeVal.isOpenMap -theorem IsOpenMap.restrict {f : X → Y} (hf : IsOpenMap f) {s : Set X} (hs : IsOpen s) : - IsOpenMap (s.restrict f) := +theorem IsOpenMap.domRestrict {f : X → Y} (hf : IsOpenMap f) {s : Set X} (hs : IsOpen s) : + IsOpenMap (s.domRestrict f) := hf.comp hs.isOpenMap_subtype_val +@[deprecated (since := "2026-07-19")] alias IsOpenMap.restrict := IsOpenMap.domRestrict + @[fun_prop] lemma IsClosed.isClosedEmbedding_subtypeVal {s : Set X} (hs : IsClosed s) : IsClosedEmbedding ((↑) : s → X) := .subtypeVal hs @@ -405,10 +407,12 @@ theorem IsClosed.isClosedMap_subtype_val {s : Set X} (hs : IsClosed s) : IsClosedMap ((↑) : s → X) := hs.isClosedEmbedding_subtypeVal.isClosedMap -theorem IsClosedMap.restrict {f : X → Y} (hf : IsClosedMap f) {s : Set X} (hs : IsClosed s) : - IsClosedMap (s.restrict f) := +theorem IsClosedMap.domRestrict {f : X → Y} (hf : IsClosedMap f) {s : Set X} + (hs : IsClosed s) : IsClosedMap (s.domRestrict f) := hf.comp hs.isClosedMap_subtype_val +@[deprecated (since := "2026-07-19")] alias IsClosedMap.restrict := IsClosedMap.domRestrict + @[continuity, fun_prop] theorem Continuous.subtype_mk {f : Y → X} (h : Continuous f) (hp : ∀ x, p (f x)) : Continuous fun x => (⟨f x, hp x⟩ : Subtype p) := @@ -549,11 +553,11 @@ theorem Continuous.restrict {f : X → Y} {s : Set X} {t : Set Y} (h1 : MapsTo f lemma IsOpenMap.mapsToRestrict {f : X → Y} (hf : IsOpenMap f) {s : Set X} {t : Set Y} (hs : IsOpen s) (ht : MapsTo f s t) : IsOpenMap ht.restrict := - (hf.restrict hs).codRestrict _ + (hf.domRestrict hs).codRestrict _ lemma IsClosedMap.mapsToRestrict {f : X → Y} (hf : IsClosedMap f) {s : Set X} {t : Set Y} (hs : IsClosed s) (ht : MapsTo f s t) : IsClosedMap ht.restrict := - (hf.restrict hs).codRestrict _ + (hf.domRestrict hs).codRestrict _ @[continuity, fun_prop] theorem Continuous.restrictPreimage {f : X → Y} {s : Set Y} (h : Continuous f) : @@ -859,13 +863,17 @@ def Homeomorph.piCurry {X Y Z : Type*} continuous_toFun := continuous_pi (fun i ↦ Pi.continuous_precomp (Prod.mk i)) @[continuity, fun_prop] -lemma Pi.continuous_restrict (S : Set ι) : - Continuous (S.restrict : (∀ i : ι, A i) → (∀ i : S, A i)) := +lemma Pi.continuous_domRestrict (S : Set ι) : + Continuous (S.domRestrict : (∀ i : ι, A i) → (∀ i : S, A i)) := Pi.continuous_precomp' ((↑) : S → ι) +@[deprecated (since := "2026-07-19")] alias Pi.continuous_restrict := Pi.continuous_domRestrict + @[continuity, fun_prop] -lemma Pi.continuous_restrict₂ {s t : Set ι} (hst : s ⊆ t) : Continuous (restrict₂ (π := A) hst) := - continuous_pi fun _ ↦ continuous_apply _ +lemma Pi.continuous_domRestrict₂ {s t : Set ι} (hst : s ⊆ t) : + Continuous (domRestrict₂ (π := A) hst) := continuous_pi fun _ ↦ continuous_apply _ + +@[deprecated (since := "2026-07-19")] alias Pi.continuous_restrict₂ := Pi.continuous_domRestrict₂ @[continuity, fun_prop] theorem Finset.continuous_restrict (s : Finset ι) : Continuous (s.restrict (π := A)) := @@ -879,13 +887,19 @@ theorem Finset.continuous_restrict₂ {s t : Finset ι} (hst : s ⊆ t) : variable [TopologicalSpace Z] @[continuity, fun_prop] -theorem Pi.continuous_restrict_apply (s : Set X) {f : X → Z} (hf : Continuous f) : - Continuous (s.restrict f) := hf.comp continuous_subtype_val +theorem Pi.continuous_domRestrict_apply (s : Set X) {f : X → Z} (hf : Continuous f) : + Continuous (s.domRestrict f) := hf.comp continuous_subtype_val + +@[deprecated (since := "2026-07-19")] +alias Pi.continuous_restrict_apply := Pi.continuous_domRestrict_apply @[continuity, fun_prop] -theorem Pi.continuous_restrict₂_apply {s t : Set X} (hst : s ⊆ t) +theorem Pi.continuous_domRestrict₂_apply {s t : Set X} (hst : s ⊆ t) {f : t → Z} (hf : Continuous f) : - Continuous (restrict₂ (π := fun _ ↦ Z) hst f) := hf.comp (continuous_inclusion hst) + Continuous (domRestrict₂ (π := fun _ ↦ Z) hst f) := hf.comp (continuous_inclusion hst) + +@[deprecated (since := "2026-07-19")] +alias Pi.continuous_restrict₂_apply := Pi.continuous_domRestrict₂_apply @[continuity, fun_prop] theorem Finset.continuous_restrict_apply (s : Finset X) {f : X → Z} (hf : Continuous f) : @@ -896,16 +910,21 @@ theorem Finset.continuous_restrict₂_apply {s t : Finset X} (hst : s ⊆ t) {f : t → Z} (hf : Continuous f) : Continuous (restrict₂ (π := fun _ ↦ Z) hst f) := hf.comp (continuous_inclusion hst) -lemma Pi.induced_restrict (S : Set ι) : - induced (S.restrict) Pi.topologicalSpace = +lemma Pi.induced_domRestrict (S : Set ι) : + induced (S.domRestrict) Pi.topologicalSpace = ⨅ i ∈ S, induced (eval i) (T i) := by simp +unfoldPartialApp [← iInf_subtype'', ← induced_precomp' ((↑) : S → ι), - restrict] + domRestrict] + +@[deprecated (since := "2026-07-19")] alias Pi.induced_restrict := Pi.induced_domRestrict + +lemma Pi.induced_domRestrict_sUnion (𝔖 : Set (Set ι)) : + induced (⋃₀ 𝔖).domRestrict (Pi.topologicalSpace (Y := fun i : (⋃₀ 𝔖) ↦ A i)) = + ⨅ S ∈ 𝔖, induced S.domRestrict Pi.topologicalSpace := by + simp_rw [Pi.induced_domRestrict, iInf_sUnion] -lemma Pi.induced_restrict_sUnion (𝔖 : Set (Set ι)) : - induced (⋃₀ 𝔖).restrict (Pi.topologicalSpace (Y := fun i : (⋃₀ 𝔖) ↦ A i)) = - ⨅ S ∈ 𝔖, induced S.restrict Pi.topologicalSpace := by - simp_rw [Pi.induced_restrict, iInf_sUnion] +@[deprecated (since := "2026-07-19")] +alias Pi.induced_restrict_sUnion := Pi.induced_domRestrict_sUnion theorem Filter.Tendsto.update [DecidableEq ι] {l : Filter Y} {f : Y → ∀ i, A i} {x : ∀ i, A i} (hf : Tendsto f l (𝓝 x)) (i : ι) {g : Y → A i} {xi : A i} (hg : Tendsto g l (𝓝 xi)) : diff --git a/Mathlib/Topology/ContinuousMap/Basic.lean b/Mathlib/Topology/ContinuousMap/Basic.lean index 6aad422e4f6f62..70dfd5b8693d60 100644 --- a/Mathlib/Topology/ContinuousMap/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Basic.lean @@ -283,7 +283,7 @@ def restrict (f : C(α, β)) : C(s, β) where toFun := f ∘ ((↑) : s → α) @[simp] -theorem coe_restrict (f : C(α, β)) : ⇑(f.restrict s) = s.restrict f := +theorem coe_restrict (f : C(α, β)) : ⇑(f.restrict s) = s.domRestrict f := rfl @[simp] @@ -298,7 +298,7 @@ theorem restrict_apply_mk (f : C(α, β)) (s : Set α) (x : α) (hx : x ∈ s) : theorem injective_restrict [T2Space β] {s : Set α} (hs : Dense s) : Injective (restrict s : C(α, β) → C(s, β)) := fun f g h ↦ DFunLike.ext' <| (map_continuous f).ext_on hs (map_continuous g) <| - Set.restrict_eq_restrict_iff.1 <| congr_arg DFunLike.coe h + Set.domRestrict_eq_domRestrict_iff.1 <| congr_arg DFunLike.coe h /-- The restriction of a continuous map to the preimage of a set. -/ @[simps] @@ -335,19 +335,17 @@ lemma mkD_apply_of_continuous {f : α → β} {g : C(α, β)} {x : α} (hf : Con lemma mkD_of_continuousOn {s : Set α} {f : α → β} {g : C(s, β)} (hf : ContinuousOn f s) : - mkD (s.restrict f) g = ⟨s.restrict f, hf.restrict⟩ := - mkD_of_continuous hf.restrict + mkD (s.domRestrict f) g = ⟨s.domRestrict f, hf.domRestrict⟩ := mkD_of_continuous hf.domRestrict lemma mkD_of_not_continuousOn {s : Set α} {f : α → β} {g : C(s, β)} (hf : ¬ ContinuousOn f s) : - mkD (s.restrict f) g = g := by - rw [continuousOn_iff_continuous_restrict] at hf + mkD (s.domRestrict f) g = g := by + rw [continuousOn_iff_continuous_domRestrict] at hf exact mkD_of_not_continuous hf lemma mkD_apply_of_continuousOn {s : Set α} {f : α → β} {g : C(s, β)} {x : s} (hf : ContinuousOn f s) : - mkD (s.restrict f) g x = f x := by - rw [mkD_of_continuousOn hf, coe_mk, Set.restrict_apply] + mkD (s.domRestrict f) g x = f x := by rw [mkD_of_continuousOn hf, coe_mk, Set.domRestrict_apply] lemma mkD_eq_self {f g : C(α, β)} : mkD f g = f := mkD_of_continuous f.continuous @@ -367,8 +365,8 @@ noncomputable def liftCover : C(α, β) := haveI H : ⋃ i, S i = Set.univ := Set.iUnion_eq_univ_iff.2 fun x ↦ (hS x).imp fun _ ↦ mem_of_mem_nhds mk (Set.liftCover S (fun i ↦ φ i) hφ H) <| continuous_of_cover_nhds hS fun i ↦ by - rw [continuousOn_iff_continuous_restrict] - simpa +unfoldPartialApp only [Set.restrict, Set.liftCover_coe] + rw [continuousOn_iff_continuous_domRestrict] + simpa +unfoldPartialApp only [Set.domRestrict, Set.liftCover_coe] using map_continuous (φ i) variable {S φ hφ hS} diff --git a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean index 31e9ef5ceb591a..ce9f56fc4406e5 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/Basic.lean @@ -348,15 +348,19 @@ theorem continuous_compContinuous {δ : Type*} [TopologicalSpace δ] (g : C(δ, Continuous fun f : α →ᵇ β => f.compContinuous g := (lipschitz_compContinuous g).continuous -/-- Restrict a bounded continuous function to a set. -/ -def restrict (f : α →ᵇ β) (s : Set α) : s →ᵇ β := +/-- Restrict the domain of a bounded continuous function to a set. -/ +def domRestrict (f : α →ᵇ β) (s : Set α) : s →ᵇ β := f.compContinuous <| (ContinuousMap.id _).restrict s @[simp] -theorem coe_restrict (f : α →ᵇ β) (s : Set α) : ⇑(f.restrict s) = f ∘ (↑) := rfl +theorem coe_domRestrict (f : α →ᵇ β) (s : Set α) : ⇑(f.domRestrict s) = f ∘ (↑) := rfl @[simp] -theorem restrict_apply (f : α →ᵇ β) (s : Set α) (x : s) : f.restrict s x = f x := rfl +theorem domRestrict_apply (f : α →ᵇ β) (s : Set α) (x : s) : f.domRestrict s x = f x := rfl + +@[deprecated (since := "2026-07-19")] alias restrict := domRestrict +@[deprecated (since := "2026-07-19")] alias coe_restrict := coe_domRestrict +@[deprecated (since := "2026-07-19")] alias restrict_apply := domRestrict_apply /-- Composition (in the target) of a bounded continuous function with a Lipschitz map again gives a bounded continuous function. -/ @@ -429,7 +433,7 @@ theorem extend_of_empty [IsEmpty α] (f : α ↪ δ) (g : α →ᵇ β) (h : δ @[simp] theorem dist_extend_extend (f : α ↪ δ) (g₁ g₂ : α →ᵇ β) (h₁ h₂ : δ →ᵇ β) : dist (g₁.extend f h₁) (g₂.extend f h₂) = - max (dist g₁ g₂) (dist (h₁.restrict (range f)ᶜ) (h₂.restrict (range f)ᶜ)) := by + max (dist g₁ g₂) (dist (h₁.domRestrict (range f)ᶜ) (h₂.domRestrict (range f)ᶜ)) := by refine le_antisymm ((dist_le <| le_max_iff.2 <| Or.inl dist_nonneg).2 fun x => ?_) (max_le ?_ ?_) · rcases em (∃ y, f y = x) with (⟨x, rfl⟩ | hx) · simp only [extend_apply] @@ -437,8 +441,8 @@ theorem dist_extend_extend (f : α ↪ δ) (g₁ g₂ : α →ᵇ β) (h₁ h₂ · simp only [extend_apply' hx] lift x to ((range f)ᶜ : Set δ) using hx calc - dist (h₁ x) (h₂ x) = dist (h₁.restrict (range f)ᶜ x) (h₂.restrict (range f)ᶜ x) := rfl - _ ≤ dist (h₁.restrict (range f)ᶜ) (h₂.restrict (range f)ᶜ) := dist_coe_le_dist x + dist (h₁ x) (h₂ x) = dist (h₁.domRestrict (range f)ᶜ x) (h₂.domRestrict (range f)ᶜ x) := rfl + _ ≤ dist (h₁.domRestrict (range f)ᶜ) (h₂.domRestrict (range f)ᶜ) := dist_coe_le_dist x _ ≤ _ := le_max_right _ _ · refine (dist_le dist_nonneg).2 fun x => ?_ rw [← extend_apply f g₁ h₁, ← extend_apply f g₂ h₂] diff --git a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean index f1894ab67f93bf..ce0246b22432be 100644 --- a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean +++ b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean @@ -185,20 +185,20 @@ lemma mkD_apply_of_continuous [Zero X] {f : X → R} {g : C(X, R)₀} {x : X} lemma mkD_of_continuousOn {s : Set X} [Zero s] {f : X → R} {g : C(s, R)₀} (hf : ContinuousOn f s) (hf₀ : f (0 : s) = 0) : - mkD (s.restrict f) g = ⟨⟨s.restrict f, hf.restrict⟩, hf₀⟩ := - mkD_of_continuous hf.restrict hf₀ + mkD (s.domRestrict f) g = ⟨⟨s.domRestrict f, hf.domRestrict⟩, hf₀⟩ := + mkD_of_continuous hf.domRestrict hf₀ lemma mkD_of_not_continuousOn {s : Set X} [Zero s] {f : X → R} {g : C(s, R)₀} (hf : ¬ ContinuousOn f s) : - mkD (s.restrict f) g = g := by - rw [continuousOn_iff_continuous_restrict] at hf + mkD (s.domRestrict f) g = g := by + rw [continuousOn_iff_continuous_domRestrict] at hf exact mkD_of_not_continuous hf set_option backward.isDefEq.respectTransparency false in lemma mkD_apply_of_continuousOn {s : Set X} [Zero s] {f : X → R} {g : C(s, R)₀} {x : s} (hf : ContinuousOn f s) (hf₀ : f (0 : s) = 0) : - mkD (s.restrict f) g x = f x := by - rw [mkD_of_continuousOn hf hf₀, coe_mk, ContinuousMap.coe_mk, restrict_apply] + mkD (s.domRestrict f) g x = f x := by + rw [mkD_of_continuousOn hf hf₀, coe_mk, ContinuousMap.coe_mk, domRestrict_apply] open ContinuousMap in /-- Link between `ContinuousMapZero.mkD` and `ContinuousMap.mkD`. -/ diff --git a/Mathlib/Topology/ContinuousMap/Interval.lean b/Mathlib/Topology/ContinuousMap/Interval.lean index 0fb7cbdb661cd5..332dda5cceed50 100644 --- a/Mathlib/Topology/ContinuousMap/Interval.lean +++ b/Mathlib/Topology/ContinuousMap/Interval.lean @@ -128,8 +128,8 @@ noncomputable def concatCM : toFun fg := concat fg.val.1 fg.val.2 continuous_toFun := by let S : Set (C(Icc a b, E) × C(Icc b c, E)) := {fg | fg.1 ⊤ = fg.2 ⊥} - change Continuous (S.restrict concat.uncurry) - refine continuousOn_iff_continuous_restrict.mp (fun fg hfg => ?_) + change Continuous (S.domRestrict concat.uncurry) + refine continuousOn_iff_continuous_domRestrict.mp (fun fg hfg => ?_) refine tendsto_concat ?_ hfg ?_ ?_ · exact eventually_nhdsWithin_of_forall (fun _ => id) · exact tendsto_nhdsWithin_of_tendsto_nhds continuousAt_fst diff --git a/Mathlib/Topology/ContinuousMap/StarOrdered.lean b/Mathlib/Topology/ContinuousMap/StarOrdered.lean index 935fd6ecb50ea8..2b6d25c63de6e3 100644 --- a/Mathlib/Topology/ContinuousMap/StarOrdered.lean +++ b/Mathlib/Topology/ContinuousMap/StarOrdered.lean @@ -61,7 +61,7 @@ instance {R : Type*} [PartialOrder R] [NonUnitalSemiring R] [StarRing R] constructor · rw [ContinuousMap.le_def] intro h - use (mk _ ContinuousSqrt.continuousOn_sqrt.restrict).comp + use (mk _ ContinuousSqrt.continuousOn_sqrt.domRestrict).comp ⟨_, map_continuous (f.prodMk g) |>.codRestrict (s := {x | x.1 ≤ x.2}) (by exact h)⟩ ext x simpa [IsSelfAdjoint.star_eq <| .of_nonneg (ContinuousSqrt.sqrt_nonneg (f x, g x) (h x))] diff --git a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean index 1b32fdaf342225..bb86c4ef0b75a9 100644 --- a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean @@ -339,8 +339,8 @@ theorem exists_mem_subalgebra_near_continuous_of_isCompact_of_separatesPoints simp obtain ⟨⟨gK, hgKAK⟩, hgapprox⟩ := @ContinuousMap.exists_mem_subalgebra_near_continuous_of_separatesPoints _ _ - (isCompact_iff_compactSpace.mp hK) AK hsep (K.restrict f) - (ContinuousOn.restrict (Continuous.continuousOn f.continuous)) ε pos + (isCompact_iff_compactSpace.mp hK) AK hsep (K.domRestrict f) + (ContinuousOn.domRestrict (Continuous.continuousOn f.continuous)) ε pos obtain ⟨g, hgA, hgKAK⟩ := Subalgebra.mem_map.mp hgKAK use g, hgA intro x hxK diff --git a/Mathlib/Topology/ContinuousMap/Weierstrass.lean b/Mathlib/Topology/ContinuousMap/Weierstrass.lean index 8ad35348147a19..5684143b2ef6dd 100644 --- a/Mathlib/Topology/ContinuousMap/Weierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/Weierstrass.lean @@ -109,7 +109,7 @@ can be approximated to within any `ε > 0` on `[a,b]` by some polynomial. theorem exists_polynomial_near_of_continuousOn (a b : ℝ) (f : ℝ → ℝ) (c : ContinuousOn f (Set.Icc a b)) (ε : ℝ) (pos : 0 < ε) : ∃ p : ℝ[X], ∀ x ∈ Set.Icc a b, |p.eval x - f x| < ε := by - let f' : C(Set.Icc a b, ℝ) := ⟨fun x => f x, continuousOn_iff_continuous_restrict.mp c⟩ + let f' : C(Set.Icc a b, ℝ) := ⟨fun x => f x, continuousOn_iff_continuous_domRestrict.mp c⟩ obtain ⟨p, b⟩ := exists_polynomial_near_continuousMap a b f' ε pos use p rw [norm_lt_iff _ pos] at b diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index 43db4451329174..fd57872c1e3888 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -49,10 +49,13 @@ theorem continuousOn_univ {f : α → β} : ContinuousOn f univ ↔ Continuous f simp [continuous_iff_continuousAt, ContinuousOn, ContinuousAt, ContinuousWithinAt, nhdsWithin_univ] -theorem continuousWithinAt_iff_continuousAt_restrict (f : α → β) {x : α} {s : Set α} (h : x ∈ s) : - ContinuousWithinAt f s x ↔ ContinuousAt (s.restrict f) ⟨x, h⟩ := +theorem continuousWithinAt_iff_continuousAt_domRestrict (f : α → β) {x : α} {s : Set α} + (h : x ∈ s) : ContinuousWithinAt f s x ↔ ContinuousAt (s.domRestrict f) ⟨x, h⟩ := tendsto_nhdsWithin_iff_subtype h f _ +@[deprecated (since := "2026-07-19")] alias continuousWithinAt_iff_continuousAt_restrict := + continuousWithinAt_iff_continuousAt_domRestrict + theorem ContinuousWithinAt.tendsto_nhdsWithin {t : Set β} (h : ContinuousWithinAt f s x) (ht : MapsTo f s t) : Tendsto f (𝓝[s] x) (𝓝[t] f x) := @@ -99,30 +102,35 @@ theorem ContinuousOn.continuousWithinAt (hf : ContinuousOn f s) (hx : x ∈ s) : ContinuousWithinAt f s x := hf x hx -theorem continuousOn_iff_continuous_restrict : - ContinuousOn f s ↔ Continuous (s.restrict f) := by +theorem continuousOn_iff_continuous_domRestrict : + ContinuousOn f s ↔ Continuous (s.domRestrict f) := by rw [ContinuousOn, continuous_iff_continuousAt]; constructor · rintro h ⟨x, xs⟩ - exact (continuousWithinAt_iff_continuousAt_restrict f xs).mp (h x xs) + exact (continuousWithinAt_iff_continuousAt_domRestrict f xs).mp (h x xs) intro h x xs - exact (continuousWithinAt_iff_continuousAt_restrict f xs).mpr (h ⟨x, xs⟩) + exact (continuousWithinAt_iff_continuousAt_domRestrict f xs).mpr (h ⟨x, xs⟩) + +alias ⟨ContinuousOn.domRestrict, _⟩ := continuousOn_iff_continuous_domRestrict -alias ⟨ContinuousOn.restrict, _⟩ := continuousOn_iff_continuous_restrict +@[deprecated (since := "2026-07-19")] +alias continuousOn_iff_continuous_restrict := continuousOn_iff_continuous_domRestrict +@[deprecated (since := "2026-07-19")] +alias ContinuousOn.restrict := ContinuousOn.domRestrict theorem ContinuousOn.mapsToRestrict {t : Set β} (hf : ContinuousOn f s) (ht : MapsTo f s t) : Continuous (ht.restrict f s t) := - hf.restrict.codRestrict _ + hf.domRestrict.codRestrict _ theorem continuousOn_iff' : ContinuousOn f s ↔ ∀ t : Set β, IsOpen t → ∃ u, IsOpen u ∧ f ⁻¹' t ∩ s = u ∩ s := by - have : ∀ t, IsOpen (s.restrict f ⁻¹' t) ↔ ∃ u : Set α, IsOpen u ∧ f ⁻¹' t ∩ s = u ∩ s := by + have : ∀ t, IsOpen (s.domRestrict f ⁻¹' t) ↔ ∃ u : Set α, IsOpen u ∧ f ⁻¹' t ∩ s = u ∩ s := by intro t - rw [isOpen_induced_iff, Set.restrict_eq, Set.preimage_comp] + rw [isOpen_induced_iff, Set.domRestrict_eq, Set.preimage_comp] simp only [Subtype.preimage_coe_eq_preimage_coe_iff] constructor <;> · rintro ⟨u, ou, useq⟩ exact ⟨u, ou, by simpa only [Set.inter_comm, eq_comm] using useq⟩ - rw [continuousOn_iff_continuous_restrict, continuous_def]; simp only [this] + rw [continuousOn_iff_continuous_domRestrict, continuous_def]; simp only [this] /-- If a function is continuous on a set for some topologies, then it is continuous on the same set with respect to any finer topology on the source space. -/ @@ -140,11 +148,11 @@ theorem ContinuousOn.mono_rng {α β : Type*} {t₁ : TopologicalSpace α} {t₂ theorem continuousOn_iff_isClosed : ContinuousOn f s ↔ ∀ t : Set β, IsClosed t → ∃ u, IsClosed u ∧ f ⁻¹' t ∩ s = u ∩ s := by - have : ∀ t, IsClosed (s.restrict f ⁻¹' t) ↔ ∃ u : Set α, IsClosed u ∧ f ⁻¹' t ∩ s = u ∩ s := by + have : ∀ t, IsClosed (s.domRestrict f ⁻¹' t) ↔ ∃ u : Set α, IsClosed u ∧ f ⁻¹' t ∩ s = u ∩ s := by intro t - rw [isClosed_induced_iff, Set.restrict_eq, Set.preimage_comp] + rw [isClosed_induced_iff, Set.domRestrict_eq, Set.preimage_comp] simp only [Subtype.preimage_coe_eq_preimage_coe_iff, eq_comm, Set.inter_comm s] - rw [continuousOn_iff_continuous_restrict, continuous_iff_isClosed]; simp only [this] + rw [continuousOn_iff_continuous_domRestrict, continuous_iff_isClosed]; simp only [this] theorem continuous_of_cover_nhds {ι : Sort*} {s : ι → Set α} (hs : ∀ x : α, ∃ i, s i ∈ 𝓝 x) (hf : ∀ i, ContinuousOn f (s i)) : @@ -842,21 +850,21 @@ theorem Topology.IsOpenEmbedding.map_nhdsWithin_preimage_eq {f : α → β} (hf theorem Topology.IsQuotientMap.continuousOn_isOpen_iff {f : α → β} {g : β → γ} (h : IsQuotientMap f) {s : Set β} (hs : IsOpen s) : ContinuousOn g s ↔ ContinuousOn (g ∘ f) (f ⁻¹' s) := by - simp only [continuousOn_iff_continuous_restrict, (h.restrictPreimage_isOpen hs).continuous_iff] + simp only [continuousOn_iff_continuous_domRestrict, (h.restrictPreimage_isOpen hs).continuous_iff] rfl theorem IsOpenMap.continuousOn_image_of_leftInvOn {f : α → β} {s : Set α} - (h : IsOpenMap (s.restrict f)) {finv : β → α} (hleft : LeftInvOn finv f s) : + (h : IsOpenMap (s.domRestrict f)) {finv : β → α} (hleft : LeftInvOn finv f s) : ContinuousOn finv (f '' s) := by refine continuousOn_iff'.2 fun t ht => ⟨f '' (t ∩ s), ?_, ?_⟩ - · rw [← image_restrict] + · rw [← image_domRestrict] exact h _ (ht.preimage continuous_subtype_val) · rw [inter_eq_self_of_subset_left (image_mono inter_subset_right), hleft.image_inter'] theorem IsOpenMap.continuousOn_range_of_leftInverse {f : α → β} (hf : IsOpenMap f) {finv : β → α} (hleft : Function.LeftInverse finv f) : ContinuousOn finv (range f) := by rw [← image_univ] - exact (hf.restrict isOpen_univ).continuousOn_image_of_leftInvOn fun x _ => hleft x + exact (hf.domRestrict isOpen_univ).continuousOn_image_of_leftInvOn fun x _ => hleft x /-- If `f` is continuous on an open set `s` and continuous at each point of another set `t` then `f` is continuous on `s ∪ t`. -/ diff --git a/Mathlib/Topology/Covering/Basic.lean b/Mathlib/Topology/Covering/Basic.lean index dca87e66f9f07e..8b0990a1c623e6 100644 --- a/Mathlib/Topology/Covering/Basic.lean +++ b/Mathlib/Topology/Covering/Basic.lean @@ -76,10 +76,10 @@ noncomputable def toTrivialization' {x : X} [Nonempty I] (h : IsEvenlyCovered f right_inv' xi := by rintro ⟨hx, -⟩; simpa [hx] using fun h ↦ (h (H.symm _).2).elim open_source := hfU open_target := hU.prod isOpen_univ - continuousOn_toFun := continuousOn_iff_continuous_restrict.mpr <| + continuousOn_toFun := continuousOn_iff_continuous_domRestrict.mpr <| ((continuous_subtype_val.prodMap continuous_id).comp H.continuous).congr fun ⟨e, (he : f e ∈ U)⟩ ↦ by simp [Prod.map, he] - continuousOn_invFun := continuousOn_iff_continuous_restrict.mpr <| + continuousOn_invFun := continuousOn_iff_continuous_domRestrict.mpr <| ((continuous_subtype_val.comp H.symm.continuous).comp (by fun_prop : Continuous fun ui ↦ ⟨⟨_, ui.2.1⟩, ui.1.2⟩)).congr fun ⟨⟨x, i⟩, ⟨hx, _⟩⟩ ↦ by simp [hx] baseSet := U @@ -126,7 +126,7 @@ theorem of_trivialization [DiscreteTopology I] {x : X} {t : Trivialization I f} left_inv e := Subtype.ext <| t.symm_apply_mk_proj (t.mem_source.mpr e.2) right_inv xi := by simp [t.proj_symm_apply', t.apply_symm_apply'] continuous_toFun := (IsInducing.subtypeVal.prodMap .id).continuous_iff.mpr <| - (continuousOn_iff_continuous_restrict.mp <| t.continuousOn_toFun.mono t.source_eq.ge).congr + (continuousOn_iff_continuous_domRestrict.mp <| t.continuousOn_toFun.mono t.source_eq.ge).congr fun e ↦ by simp [t.mk_proj_snd' e.2] continuous_invFun := IsInducing.subtypeVal.continuous_iff.mpr <| t.continuousOn_invFun.comp_continuous (continuous_subtype_val.prodMap continuous_id) diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index d0ff94b93fc003..344d98497ae0a9 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -94,15 +94,16 @@ lemma LocallyLipschitzOn.mono (hf : LocallyLipschitzOn t f) (h : s ⊆ t) : Loca protected lemma LocallyLipschitz.locallyLipschitzOn (h : LocallyLipschitz f) : LocallyLipschitzOn s f := (locallyLipschitzOn_univ.2 h).mono s.subset_univ -theorem lipschitzOnWith_iff_restrict : LipschitzOnWith K f s ↔ LipschitzWith K (s.restrict f) := by +theorem lipschitzOnWith_iff_restrict : + LipschitzOnWith K f s ↔ LipschitzWith K (s.domRestrict f) := by simp [LipschitzOnWith, LipschitzWith] lemma lipschitzOnWith_restrict {t : Set s} : - LipschitzOnWith K (s.restrict f) t ↔ LipschitzOnWith K f (s ∩ Subtype.val '' t) := by + LipschitzOnWith K (s.domRestrict f) t ↔ LipschitzOnWith K f (s ∩ Subtype.val '' t) := by simp [LipschitzOnWith] lemma locallyLipschitzOn_iff_restrict : - LocallyLipschitzOn s f ↔ LocallyLipschitz (s.restrict f) := by + LocallyLipschitzOn s f ↔ LocallyLipschitz (s.domRestrict f) := by simp only [LocallyLipschitzOn, LocallyLipschitz, SetCoe.forall', lipschitzOnWith_restrict, nhds_subtype_eq_comap_nhdsWithin, mem_comap] @@ -221,8 +222,8 @@ protected theorem eval {α : ι → Type u} [∀ i, PseudoEMetricSpace (α i)] [ LipschitzWith.of_edist_le fun f g => by convert! edist_le_pi_edist f g i /-- The restriction of a `K`-Lipschitz function is `K`-Lipschitz. -/ -protected theorem restrict (hf : LipschitzWith K f) (s : Set α) : LipschitzWith K (s.restrict f) := - fun x y => hf x y +protected theorem restrict (hf : LipschitzWith K f) (s : Set α) : + LipschitzWith K (s.domRestrict f) := fun x y => hf x y /-- The composition of Lipschitz functions is Lipschitz. -/ protected theorem comp {Kf Kg : ℝ≥0} {f : β → γ} {g : α → β} (hf : LipschitzWith Kf f) @@ -418,7 +419,7 @@ namespace LocallyLipschitzOn variable [PseudoEMetricSpace α] [PseudoEMetricSpace β] {f : α → β} {s : Set α} protected lemma continuousOn (hf : LocallyLipschitzOn s f) : ContinuousOn f s := - continuousOn_iff_continuous_restrict.2 hf.restrict.continuous + continuousOn_iff_continuous_domRestrict.2 hf.restrict.continuous end LocallyLipschitzOn diff --git a/Mathlib/Topology/ExtremallyDisconnected.lean b/Mathlib/Topology/ExtremallyDisconnected.lean index f20d78a916ddb2..570f0c3f42b60c 100644 --- a/Mathlib/Topology/ExtremallyDisconnected.lean +++ b/Mathlib/Topology/ExtremallyDisconnected.lean @@ -142,7 +142,7 @@ a compact subset $E$ of $D$, such that $\pi$ maps $E$ onto $A$ and satisfies the "Zorn subset condition", where $\pi(E_0) \ne A$ for any proper closed subset $E_0 \subsetneq E$. -/ lemma exists_compact_surjective_zorn_subset [T1Space A] [CompactSpace D] {X : D → A} (X_cont : Continuous X) (X_surj : X.Surjective) : ∃ E : Set D, CompactSpace E ∧ X '' E = univ ∧ - ∀ E₀ : Set E, E₀ ≠ univ → IsClosed E₀ → E.restrict X '' E₀ ≠ univ := by + ∀ E₀ : Set E, E₀ ≠ univ → IsClosed E₀ → E.domRestrict X '' E₀ ≠ univ := by -- suffices to apply Zorn's lemma on the subsets of $D$ that are closed and mapped onto $A$ let S : Set <| Set D := {E : Set D | IsClosed E ∧ X '' E = univ} suffices ∀ (C : Set <| Set D) (_ : C ⊆ S) (_ : IsChain (· ⊆ ·) C), ∃ s ∈ S, ∀ c ∈ C, s ⊆ c by @@ -152,7 +152,7 @@ lemma exists_compact_surjective_zorn_subset [T1Space A] [CompactSpace D] {X : D intro E₀ E₀_min E₀_closed contrapose E₀_min exact eq_univ_of_image_val_eq <| - E_min.eq_of_subset ⟨E₀_closed.trans E_closed, image_image_val_eq_restrict_image ▸ E₀_min⟩ + E_min.eq_of_subset ⟨E₀_closed.trans E_closed, image_image_val_eq_domRestrict_image ▸ E₀_min⟩ image_val_subset -- suffices to prove intersection of chain is minimal intro C C_sub C_chain @@ -267,16 +267,17 @@ protected theorem CompactT2.ExtremallyDisconnected.projective [ExtremallyDisconn have X₁_surj : X₁.Surjective := fun a => ⟨⟨⟨a, _⟩, (f_surj <| φ a).choose_spec.symm⟩, rfl⟩ rcases exists_compact_surjective_zorn_subset X₁_cont X₁_surj with ⟨E, _, E_onto, E_min⟩ -- apply Lemma 2.3 to get homeomorphism $\pi_1|_E : E \to A$ - let ρ : E → A := E.restrict X₁ - have ρ_cont : Continuous ρ := X₁_cont.continuousOn.restrict + let ρ : E → A := E.domRestrict X₁ + have ρ_cont : Continuous ρ := X₁_cont.continuousOn.domRestrict have ρ_surj : ρ.Surjective := fun a => by rcases (E_onto ▸ mem_univ a : a ∈ X₁ '' E) with ⟨d, ⟨hd, rfl⟩⟩; exact ⟨⟨d, hd⟩, rfl⟩ let ρ' := ExtremallyDisconnected.homeoCompactToT2 ρ_cont ρ_surj E_min -- prove $\rho := \pi_2|_E \circ \pi_1|_E^{-1}$ satisfies $\phi = f \circ \rho$ let X₂ : D → B := Prod.snd ∘ Subtype.val have X₂_cont : Continuous X₂ := continuous_snd.comp continuous_subtype_val - refine ⟨E.restrict X₂ ∘ ρ'.symm, ⟨X₂_cont.continuousOn.restrict.comp ρ'.symm.continuous, ?_⟩⟩ - suffices f ∘ E.restrict X₂ = φ ∘ ρ' by + refine ⟨E.domRestrict X₂ ∘ ρ'.symm, + ⟨X₂_cont.continuousOn.domRestrict.comp ρ'.symm.continuous, ?_⟩⟩ + suffices f ∘ E.domRestrict X₂ = φ ∘ ρ' by rw [← comp_assoc, this, comp_assoc, Homeomorph.self_comp_symm, comp_id] ext x exact x.val.mem.symm diff --git a/Mathlib/Topology/FiberBundle/Basic.lean b/Mathlib/Topology/FiberBundle/Basic.lean index 9128c4466d1ebd..054bcbbaa56355 100644 --- a/Mathlib/Topology/FiberBundle/Basic.lean +++ b/Mathlib/Topology/FiberBundle/Basic.lean @@ -780,7 +780,7 @@ theorem isOpen_source (e : Pretrivialization F (π F E)) : refine isOpen_iSup_iff.mpr fun e' => isOpen_iSup_iff.mpr fun _ => ?_ refine isOpen_coinduced.mpr (isOpen_induced_iff.mpr ⟨e.target, e.open_target, ?_⟩) ext ⟨x, hx⟩ - simp only [mem_preimage, Pretrivialization.setSymm, restrict, e.mem_target, e.mem_source, + simp only [mem_preimage, Pretrivialization.setSymm, domRestrict, e.mem_target, e.mem_source, e'.proj_symm_apply hx] theorem isOpen_target_of_mem_pretrivializationAtlas_inter (e e' : Pretrivialization F (π F E)) @@ -835,9 +835,9 @@ theorem inducing_totalSpaceMk_of_inducing_comp (b : B) (h : IsInducing (a.pretrivializationAt b ∘ TotalSpace.mk b)) : @IsInducing _ _ _ a.totalSpaceTopology (TotalSpace.mk b) := by let := a.totalSpaceTopology - rw [← restrict_comp_codRestrict (a.mem_pretrivializationAt_source b)] at h + rw [← domRestrict_comp_codRestrict (a.mem_pretrivializationAt_source b)] at h apply IsInducing.of_codRestrict (a.mem_pretrivializationAt_source b) - refine h.of_comp ?_ (continuousOn_iff_continuous_restrict.mp + refine h.of_comp ?_ (continuousOn_iff_continuous_domRestrict.mp (a.trivializationOfMemPretrivializationAtlas (a.pretrivialization_mem_atlas b)).continuousOn) exact (a.continuous_totalSpaceMk b).codRestrict (a.mem_pretrivializationAt_source b) diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index 7d3ea204c7b0ff..3e939884409947 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -132,7 +132,7 @@ theorem mk_proj_snd' (ex : proj x ∈ e.baseSet) : (proj x, (e x).2) = e x := /-- Composition of inverse and coercion from the subtype of the target. -/ def setSymm : e.target → Z := - e.target.restrict e.toPartialEquiv.symm + e.target.domRestrict e.toPartialEquiv.symm theorem mem_target {x : B × F} : x ∈ e.target ↔ x.1 ∈ e.baseSet := by rw [e.target_eq, prod_univ, mem_preimage] diff --git a/Mathlib/Topology/Instances/AddCircle/Defs.lean b/Mathlib/Topology/Instances/AddCircle/Defs.lean index 01f3d741901d44..961fd112f6bbe1 100644 --- a/Mathlib/Topology/Instances/AddCircle/Defs.lean +++ b/Mathlib/Topology/Instances/AddCircle/Defs.lean @@ -317,12 +317,12 @@ def equivIoc : AddCircle p ≃ Ioc a (a + p) := /-- Given a function on `𝕜`, return the unique function on `AddCircle p` agreeing with `f` on `[a, a + p)`. -/ def liftIco (f : 𝕜 → B) : AddCircle p → B := - restrict _ f ∘ AddCircle.equivIco p a + domRestrict _ f ∘ AddCircle.equivIco p a /-- Given a function on `𝕜`, return the unique function on `AddCircle p` agreeing with `f` on `(a, a + p]`. -/ def liftIoc (f : 𝕜 → B) : AddCircle p → B := - restrict _ f ∘ AddCircle.equivIoc p a + domRestrict _ f ∘ AddCircle.equivIoc p a variable {p a} @@ -797,7 +797,7 @@ theorem liftIoc_eq_liftIco {f : 𝕜 → B} (hf : f a = f (a + p)) : theorem liftIco_eq_lift_Icc {f : 𝕜 → B} (h : f a = f (a + p)) : liftIco p a f = - Quot.lift (restrict (Icc a <| a + p) f) + Quot.lift (domRestrict (Icc a <| a + p) f) (by rintro _ _ ⟨_⟩ exact h) ∘ @@ -806,7 +806,7 @@ theorem liftIco_eq_lift_Icc {f : 𝕜 → B} (h : f a = f (a + p)) : theorem liftIoc_eq_lift_Icc {f : 𝕜 → B} (h : f a = f (a + p)) : liftIoc p a f = - Quot.lift (restrict (Icc a <| a + p) f) + Quot.lift (domRestrict (Icc a <| a + p) f) (by rintro _ _ ⟨_⟩ exact h) ∘ @@ -826,7 +826,7 @@ theorem liftIco_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f a = f ( (hc : ContinuousOn f <| Icc a (a + p)) : Continuous (liftIco p a f) := by rw [liftIco_eq_lift_Icc hf] refine Continuous.comp ?_ (homeoIccQuot p a).continuous_toFun - exact continuous_coinduced_dom.mpr (continuousOn_iff_continuous_restrict.mp hc) + exact continuous_coinduced_dom.mpr (continuousOn_iff_continuous_domRestrict.mp hc) theorem liftIco_zero_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f 0 = f p) (hc : ContinuousOn f <| Icc 0 p) : Continuous (liftIco p 0 f) := @@ -836,7 +836,7 @@ theorem liftIoc_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f a = f ( (hc : ContinuousOn f <| Icc a (a + p)) : Continuous (liftIoc p a f) := by rw [liftIoc_eq_lift_Icc hf] refine Continuous.comp ?_ (homeoIccQuot p a).continuous_toFun - exact continuous_coinduced_dom.mpr (continuousOn_iff_continuous_restrict.mp hc) + exact continuous_coinduced_dom.mpr (continuousOn_iff_continuous_domRestrict.mp hc) theorem liftIoc_zero_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f 0 = f p) (hc : ContinuousOn f <| Icc 0 p) : Continuous (liftIoc p 0 f) := diff --git a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean index 4a7fa19ba74025..21abe387b6a04a 100644 --- a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean @@ -112,7 +112,7 @@ lemma continuousAt_toReal (hx : x ≠ ∞) : ContinuousAt ENNReal.toReal x := /-- The set of finite `ℝ≥0∞` numbers is homeomorphic to `ℝ≥0`. -/ def neTopHomeomorphNNReal : { a | a ≠ ∞ } ≃ₜ ℝ≥0 where toEquiv := neTopEquivNNReal - continuous_toFun := continuousOn_iff_continuous_restrict.1 continuousOn_toNNReal + continuous_toFun := continuousOn_iff_continuous_domRestrict.1 continuousOn_toNNReal continuous_invFun := continuous_coe.subtype_mk _ /-- The set of finite `ℝ≥0∞` numbers is homeomorphic to `ℝ≥0`. -/ diff --git a/Mathlib/Topology/Instances/EReal/Lemmas.lean b/Mathlib/Topology/Instances/EReal/Lemmas.lean index 2fae51424907ce..21769f8ca7d518 100644 --- a/Mathlib/Topology/Instances/EReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/EReal/Lemmas.lean @@ -74,7 +74,7 @@ theorem continuousOn_toReal : ContinuousOn EReal.toReal ({⊥, ⊤}ᶜ : Set ERe /-- The set of finite `EReal` numbers is homeomorphic to `ℝ`. -/ def neBotTopHomeomorphReal : ({⊥, ⊤}ᶜ : Set EReal) ≃ₜ ℝ where toEquiv := neTopBotEquivReal - continuous_toFun := continuousOn_iff_continuous_restrict.1 continuousOn_toReal + continuous_toFun := continuousOn_iff_continuous_domRestrict.1 continuousOn_toReal continuous_invFun := continuous_coe_real_ereal.subtype_mk _ /-! ### ENNReal coercion -/ diff --git a/Mathlib/Topology/Instances/Real/Lemmas.lean b/Mathlib/Topology/Instances/Real/Lemmas.lean index 1603147677df83..fb67fbe9ca9a69 100644 --- a/Mathlib/Topology/Instances/Real/Lemmas.lean +++ b/Mathlib/Topology/Instances/Real/Lemmas.lean @@ -63,7 +63,7 @@ theorem Real.uniformContinuous_abs : UniformContinuous (abs : ℝ → ℝ) := ⟨ε, ε0, fun _ _ ↦ lt_of_le_of_lt (abs_abs_sub_abs_le_abs_sub _ _)⟩ theorem Real.continuous_inv : Continuous fun a : { r : ℝ // r ≠ 0 } => a.val⁻¹ := - continuousOn_inv₀.restrict + continuousOn_inv₀.domRestrict theorem Real.uniformContinuous_mul (s : Set (ℝ × ℝ)) {r₁ r₂ : ℝ} (H : ∀ x ∈ s, |(x : ℝ × ℝ).1| < r₁ ∧ |x.2| < r₂) : diff --git a/Mathlib/Topology/IsClosedRestrict.lean b/Mathlib/Topology/IsClosedRestrict.lean index 0b3b803da4ff55..3e4da191d698d9 100644 --- a/Mathlib/Topology/IsClosedRestrict.lean +++ b/Mathlib/Topology/IsClosedRestrict.lean @@ -15,10 +15,11 @@ the restriction to a subset of coordinates `S : Set ι` is a closed set. The idea of the proof is to use `isClosedMap_snd_of_compactSpace`, which is the fact that if `X` is a compact topological space, then `Prod.snd : X × Y → Y` is a closed map. -We remark that `s` is included in the set `Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s`, and we build -a homeomorphism `Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s ≃ₜ Sᶜ.restrict '' s × Π i : S, α i`. -`Sᶜ.restrict '' s` is a compact space since `s` is compact, and the lemma applies, -with `X = Sᶜ.restrict '' s` and `Y = Π i : S, α i`. +We remark that `s` is included in the set `Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s`, and we build +a homeomorphism +`Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s ≃ₜ Sᶜ.domRestrict '' s × Π i : S, α i`. +`Sᶜ.domRestrict '' s` is a compact space since `s` is compact, and the lemma applies, +with `X = Sᶜ.domRestrict '' s` and `Y = Π i : S, α i`. -/ @@ -32,32 +33,32 @@ namespace Topology open scoped Classical in /-- Given a set in a product space `s : Set (Π j, α j)` and a set of coordinates `S : Set ι`, -`Sᶜ.restrict '' s × (Π i : S, α i)` is the set of functions that coincide with an element of `s` +`Sᶜ.domRestrict '' s × (Π i : S, α i)` is the set of functions that coincide with an element of `s` on `Sᶜ` and are arbitrary on `S`. `reorderRestrictProd` sends a term of that type to `Π j, α j` by looking for the value at `j` in one part of the product or the other depending on whether `j` is in `S` or not. -/ noncomputable def reorderRestrictProd (S : Set ι) (s : Set (Π j, α j)) - (p : Sᶜ.restrict '' s × (Π i : S, α i)) : + (p : Sᶜ.domRestrict '' s × (Π i : S, α i)) : Π j, α j := fun j ↦ if h : j ∈ S then (p.2 : Π j : ↑(S : Set ι), α j) ⟨j, h⟩ else (p.1 : Π j : ↑(Sᶜ : Set ι), α j) ⟨j, h⟩ @[simp] -lemma reorderRestrictProd_of_mem (p : Sᶜ.restrict '' s × (Π i : S, α i)) (j : S) : +lemma reorderRestrictProd_of_mem (p : Sᶜ.domRestrict '' s × (Π i : S, α i)) (j : S) : reorderRestrictProd S s p j = (p.2 : Π j : ↑(S : Set ι), α j) j := by have hj : ↑j ∈ S := j.prop simp [reorderRestrictProd, hj] @[simp] -lemma reorderRestrictProd_of_compl (p : Sᶜ.restrict '' s × (Π i : S, α i)) (j : (Sᶜ : Set ι)) : +lemma reorderRestrictProd_of_compl (p : Sᶜ.domRestrict '' s × (Π i : S, α i)) (j : (Sᶜ : Set ι)) : reorderRestrictProd S s p j = (p.1 : Π j : ↑(Sᶜ : Set ι), α j) j := by have hj : ↑j ∉ S := j.prop simp [reorderRestrictProd, hj] @[simp] -lemma restrict_compl_reorderRestrictProd (p : Sᶜ.restrict '' s × (Π i : S, α i)) : - Sᶜ.restrict (reorderRestrictProd S s p) = p.1 := by ext; simp +lemma restrict_compl_reorderRestrictProd (p : Sᶜ.domRestrict '' s × (Π i : S, α i)) : + Sᶜ.domRestrict (reorderRestrictProd S s p) = p.1 := by ext; simp lemma continuous_reorderRestrictProd [∀ i, TopologicalSpace (α i)] : Continuous (reorderRestrictProd S s) := by @@ -67,14 +68,15 @@ lemma continuous_reorderRestrictProd [∀ i, TopologicalSpace (α i)] : · fun_prop · exact ((continuous_apply _).comp continuous_subtype_val).comp continuous_fst -lemma reorderRestrictProd_mem_preimage_image_restrict (p : Sᶜ.restrict '' s × (Π i : S, α i)) : - reorderRestrictProd S s p ∈ Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s := by +lemma reorderRestrictProd_mem_preimage_image_restrict (p : Sᶜ.domRestrict '' s × (Π i : S, α i)) : + reorderRestrictProd S s p ∈ Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s := by obtain ⟨y, hy_mem_s, hy_eq⟩ := p.1.2 exact ⟨y, hy_mem_s, hy_eq.trans (restrict_compl_reorderRestrictProd p).symm⟩ @[simp] -lemma reorderRestrictProd_restrict_compl (x : Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s) : - reorderRestrictProd S s ⟨⟨Sᶜ.restrict x, x.2⟩, fun i ↦ (x : Π j, α j) i⟩ = (x : Π j, α j) := by +lemma reorderRestrictProd_restrict_compl (x : Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s) : + reorderRestrictProd S s ⟨⟨Sᶜ.domRestrict x, x.2⟩, fun i ↦ (x : Π j, α j) i⟩ = + (x : Π j, α j) := by ext; simp [reorderRestrictProd] /-- Homeomorphism between the set of functions that coincide with a given set of functions away @@ -82,8 +84,8 @@ from a given set `S`, and dependent functions away from `S` times any value on ` noncomputable def _root_.Homeomorph.preimageImageRestrict (α : ι → Type*) [∀ i, TopologicalSpace (α i)] (S : Set ι) (s : Set (Π j, α j)) : - Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s ≃ₜ Sᶜ.restrict '' s × (Π i : S, α i) where - toFun x := ⟨⟨Sᶜ.restrict x, x.2⟩, fun i ↦ (x : Π j, α j) i⟩ + Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s ≃ₜ Sᶜ.domRestrict '' s × (Π i : S, α i) where + toFun x := ⟨⟨Sᶜ.domRestrict x, x.2⟩, fun i ↦ (x : Π j, α j) i⟩ invFun p := ⟨reorderRestrictProd S s p, reorderRestrictProd_mem_preimage_image_restrict p⟩ left_inv x := by ext; simp right_inv p := by ext <;> simp @@ -95,15 +97,16 @@ def _root_.Homeomorph.preimageImageRestrict (α : ι → Type*) [∀ i, Topologi set_option backward.isDefEq.respectTransparency false in /-- The image by `preimageImageRestrict α S s` of `s` seen as a set of -`Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s` is a set of `Sᶜ.restrict '' s × (Π i : S, α i)`, and the -image of that set by `Prod.snd` is `S.restrict '' s`. +`Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s` is a set of +`Sᶜ.domRestrict '' s × (Π i : S, α i)`, and the image of that set by `Prod.snd` is +`S.domRestrict '' s`. Used in `IsCompact.isClosed_image_restrict` to prove that the restriction of a compact closed set in a product space to a set of coordinates is closed. -/ lemma image_snd_preimageImageRestrict [∀ i, TopologicalSpace (α i)] : Prod.snd '' (Homeomorph.preimageImageRestrict α S s '' - ((fun (x : Sᶜ.restrict ⁻¹' Sᶜ.restrict '' s) ↦ (x : Π j, α j)) ⁻¹' s)) - = S.restrict '' s := by + ((fun (x : Sᶜ.domRestrict ⁻¹' Sᶜ.domRestrict '' s) ↦ (x : Π j, α j)) ⁻¹' s)) + = S.domRestrict '' s := by ext x simp only [Homeomorph.preimageImageRestrict, Homeomorph.homeomorph_mk_coe, Equiv.coe_fn_mk, mem_image, mem_preimage, Subtype.exists, exists_and_left, Prod.exists, Prod.mk.injEq, @@ -112,7 +115,7 @@ lemma image_snd_preimageImageRestrict [∀ i, TopologicalSpace (α i)] : · rintro ⟨y, _, z, hz_mem, _, hzx⟩ exact ⟨z, hz_mem, hzx⟩ · rintro ⟨z, hz_mem, hzx⟩ - exact ⟨Sᶜ.restrict z, mem_image_of_mem Sᶜ.restrict hz_mem, z, hz_mem, + exact ⟨Sᶜ.domRestrict z, mem_image_of_mem Sᶜ.domRestrict hz_mem, z, hz_mem, ⟨⟨⟨z, hz_mem, rfl⟩, rfl⟩, hzx⟩⟩ end Topology @@ -124,26 +127,26 @@ variable [∀ i, TopologicalSpace (α i)] /-- The restriction of a compact closed set in a product space to a set of coordinates is closed. -/ theorem IsCompact.isClosed_image_restrict (S : Set ι) (hs_compact : IsCompact s) (hs_closed : IsClosed s) : - IsClosed (S.restrict '' s) := by + IsClosed (S.domRestrict '' s) := by rw [← Topology.image_snd_preimageImageRestrict] - have : CompactSpace (Sᶜ.restrict '' s) := - isCompact_iff_compactSpace.mp (hs_compact.image (Pi.continuous_restrict _)) + have : CompactSpace (Sᶜ.domRestrict '' s) := + isCompact_iff_compactSpace.mp (hs_compact.image (Pi.continuous_domRestrict _)) refine isClosedMap_snd_of_compactSpace _ ?_ rw [Homeomorph.isClosed_image] exact hs_closed.preimage continuous_subtype_val lemma isClosedMap_restrict_of_compactSpace [∀ i, CompactSpace (α i)] : - IsClosedMap (S.restrict : (Π i, α i) → _) := fun s hs ↦ by + IsClosedMap (S.domRestrict : (Π i, α i) → _) := fun s hs ↦ by classical - have : S.restrict (π := α) = Prod.fst ∘ (Homeomorph.piEquivPiSubtypeProd (· ∈ S) α) := rfl + have : S.domRestrict (π := α) = Prod.fst ∘ (Homeomorph.piEquivPiSubtypeProd (· ∈ S) α) := rfl rw [this, image_comp] exact isClosedMap_fst_of_compactSpace _ <| (Homeomorph.isClosed_image _).mpr hs lemma IsClosed.isClosed_image_eval (i : ι) (hs_compact : IsCompact s) (hs_closed : IsClosed s) : IsClosed ((fun x ↦ x i) '' s) := by - suffices IsClosed (Set.restrict {i} '' s) by - have : Homeomorph.piUnique _ ∘ Set.restrict {i} = fun (x : Π j, α j) ↦ x i := rfl + suffices IsClosed (Set.domRestrict {i} '' s) by + have : Homeomorph.piUnique _ ∘ Set.domRestrict {i} = fun (x : Π j, α j) ↦ x i := rfl rwa [← this, image_comp, Homeomorph.isClosed_image (Homeomorph.piUnique _)] exact hs_compact.isClosed_image_restrict {i} hs_closed diff --git a/Mathlib/Topology/IsLocalHomeomorph.lean b/Mathlib/Topology/IsLocalHomeomorph.lean index 34f760c8f3c039..fd7cd8b2c2a980 100644 --- a/Mathlib/Topology/IsLocalHomeomorph.lean +++ b/Mathlib/Topology/IsLocalHomeomorph.lean @@ -44,19 +44,19 @@ def IsLocalHomeomorphOn := ∀ x ∈ s, ∃ e : OpenPartialHomeomorph X Y, x ∈ e.source ∧ f = e theorem isLocalHomeomorphOn_iff_isOpenEmbedding_restrict {f : X → Y} : - IsLocalHomeomorphOn f s ↔ ∀ x ∈ s, ∃ U ∈ 𝓝 x, IsOpenEmbedding (U.restrict f) := by + IsLocalHomeomorphOn f s ↔ ∀ x ∈ s, ∃ U ∈ 𝓝 x, IsOpenEmbedding (U.domRestrict f) := by refine ⟨fun h x hx ↦ ?_, fun h x hx ↦ ?_⟩ · obtain ⟨e, hxe, rfl⟩ := h x hx exact ⟨e.source, e.open_source.mem_nhds hxe, e.isOpenEmbedding_restrict⟩ · obtain ⟨U, hU, emb⟩ := h x hx - have : IsOpenEmbedding ((interior U).restrict f) := by + have : IsOpenEmbedding ((interior U).domRestrict f) := by refine emb.comp ⟨.inclusion interior_subset, ?_⟩ rw [Set.range_inclusion]; exact isOpen_induced isOpen_interior obtain ⟨cont, inj, openMap⟩ := isOpenEmbedding_iff_continuous_injective_isOpenMap.mp this have : Nonempty X := ⟨x⟩ exact ⟨OpenPartialHomeomorph.ofContinuousOpenRestrict (Set.injOn_iff_injective.mpr inj).toPartialEquiv - (continuousOn_iff_continuous_restrict.mpr cont) openMap isOpen_interior, + (continuousOn_iff_continuous_domRestrict.mpr cont) openMap isOpen_interior, mem_interior_iff_mem_nhds.mpr hU, rfl⟩ namespace IsLocalHomeomorphOn @@ -179,7 +179,7 @@ protected theorem IsLocalHomeomorph.isLocalHomeomorphOn (hf : IsLocalHomeomorph IsLocalHomeomorphOn f s := fun x _ ↦ hf x theorem isLocalHomeomorph_iff_isOpenEmbedding_restrict {f : X → Y} : - IsLocalHomeomorph f ↔ ∀ x : X, ∃ U ∈ 𝓝 x, IsOpenEmbedding (U.restrict f) := by + IsLocalHomeomorph f ↔ ∀ x : X, ∃ U ∈ 𝓝 x, IsOpenEmbedding (U.domRestrict f) := by simp_rw [isLocalHomeomorph_iff_isLocalHomeomorphOn_univ, isLocalHomeomorphOn_iff_isOpenEmbedding_restrict, imp_iff_right (Set.mem_univ _)] @@ -272,8 +272,8 @@ theorem isTopologicalBasis (hf : IsLocalHomeomorph f) : IsTopologicalBasis rwa [Subtype.range_val] · obtain ⟨f, hxf, rfl⟩ := hf x refine ⟨f.source ∩ U, ⟨f.target ∩ f.symm ⁻¹' U, f.symm.isOpen_inter_preimage hU, - ⟨_, continuousOn_iff_continuous_restrict.mp (f.continuousOn_invFun.mono fun _ h ↦ h.1)⟩, - ?_, (Set.range_restrict _ _).trans ?_⟩, ⟨hxf, hx⟩, fun _ h ↦ h.2⟩ + ⟨_, continuousOn_iff_continuous_domRestrict.mp (f.continuousOn_invFun.mono fun _ h ↦ h.1)⟩, + ?_, (Set.range_domRestrict _ _).trans ?_⟩, ⟨hxf, hx⟩, fun _ h ↦ h.2⟩ · ext y; exact f.right_inv y.2.1 · apply (f.symm_image_target_inter_eq _).trans rw [Set.preimage_inter, ← Set.inter_assoc, Set.inter_eq_self_of_subset_left diff --git a/Mathlib/Topology/LocalAtTarget.lean b/Mathlib/Topology/LocalAtTarget.lean index a8b0228efad726..97c4dd4c028e2f 100644 --- a/Mathlib/Topology/LocalAtTarget.lean +++ b/Mathlib/Topology/LocalAtTarget.lean @@ -38,7 +38,8 @@ variable {ι : Type*} {U : ι → Opens β} theorem Set.restrictPreimage_isInducing (s : Set β) (h : IsInducing f) : IsInducing (s.restrictPreimage f) := by simp_rw [← IsInducing.subtypeVal.of_comp_iff, isInducing_iff_nhds, restrictPreimage, - MapsTo.coe_restrict, restrict_eq, ← @Filter.comap_comap _ _ _ _ _ f, Function.comp_apply] at h ⊢ + MapsTo.coe_restrict, domRestrict_eq, ← @Filter.comap_comap _ _ _ _ _ f, + Function.comp_apply] at h ⊢ intro a rw [← h, ← IsInducing.subtypeVal.nhds_eq_comap] @@ -150,7 +151,7 @@ theorem isClosedMap_iff_restrictPreimage : theorem isInducing_iff_restrictPreimage (h : Continuous f) : IsInducing f ↔ ∀ i, IsInducing ((U i).1.restrictPreimage f) := by simp_rw [← IsInducing.subtypeVal.of_comp_iff, isInducing_iff_nhds, restrictPreimage, - MapsTo.coe_restrict, restrict_eq, ← Filter.comap_comap] + MapsTo.coe_restrict, domRestrict_eq, ← Filter.comap_comap] constructor · intro H i x rw [Function.comp_apply, ← H, ← IsInducing.subtypeVal.nhds_eq_comap] diff --git a/Mathlib/Topology/LocallyConstant/Basic.lean b/Mathlib/Topology/LocallyConstant/Basic.lean index 8bd260514e4ecc..7fecd269873639 100644 --- a/Mathlib/Topology/LocallyConstant/Basic.lean +++ b/Mathlib/Topology/LocallyConstant/Basic.lean @@ -533,12 +533,12 @@ def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) rw [Set.union_eq_iUnion] at h refine (locallyFinite_of_finite _).continuous h (fun i ↦ ?_) (fun i ↦ ?_) · cases i <;> [exact h₂; exact h₁] - · cases i <;> rw [continuousOn_iff_continuous_restrict] + · cases i <;> rw [continuousOn_iff_continuous_domRestrict] · convert! hg ext x - simp only [cond_false, restrict_apply, Subtype.coe_eta, dite_eq_right_iff] + simp only [cond_false, domRestrict_apply, Subtype.coe_eta, dite_eq_right_iff] exact fun hx ↦ hfg x ⟨hx, x.prop⟩ - · simp only [cond_true, restrict_dite, Subtype.coe_eta] + · simp only [cond_true, domRestrict_dite, Subtype.coe_eta] exact hf @[simp] diff --git a/Mathlib/Topology/MetricSpace/Antilipschitz.lean b/Mathlib/Topology/MetricSpace/Antilipschitz.lean index 4f63bb1a0afe13..e03a6c47b547b9 100644 --- a/Mathlib/Topology/MetricSpace/Antilipschitz.lean +++ b/Mathlib/Topology/MetricSpace/Antilipschitz.lean @@ -118,21 +118,22 @@ theorem comp {Kg : ℝ≥0} {g : β → γ} (hg : AntilipschitzWith Kg g) {Kf : _ ≤ Kf * (Kg * edist (g (f x)) (g (f y))) := mul_right_mono (hg _ _) _ = _ := by rw [ENNReal.coe_mul, mul_assoc]; rfl -theorem restrict (hf : AntilipschitzWith K f) (s : Set α) : AntilipschitzWith K (s.restrict f) := - fun x y => hf x y +theorem domRestrict (hf : AntilipschitzWith K f) (s : Set α) : + AntilipschitzWith K (s.domRestrict f) := fun x y => hf x y + +@[deprecated (since := "2026-07-19")] alias restrict := domRestrict theorem codRestrict (hf : AntilipschitzWith K f) {s : Set β} (hs : ∀ x, f x ∈ s) : AntilipschitzWith K (s.codRestrict f hs) := fun x y => hf x y -theorem to_rightInvOn' {s : Set α} (hf : AntilipschitzWith K (s.restrict f)) {g : β → α} +theorem to_rightInvOn' {s : Set α} (hf : AntilipschitzWith K (s.domRestrict f)) {g : β → α} {t : Set β} (g_maps : MapsTo g t s) (g_inv : RightInvOn g f t) : - LipschitzWith K (t.restrict g) := fun x y => by - simpa only [restrict_apply, g_inv x.mem, g_inv y.mem, Subtype.edist_mk_mk] + LipschitzWith K (t.domRestrict g) := fun x y => by + simpa only [domRestrict_apply, g_inv x.mem, g_inv y.mem, Subtype.edist_mk_mk] using! hf ⟨g x, g_maps x.mem⟩ ⟨g y, g_maps y.mem⟩ theorem to_rightInvOn (hf : AntilipschitzWith K f) {g : β → α} {t : Set β} (h : RightInvOn g f t) : - LipschitzWith K (t.restrict g) := - (hf.restrict univ).to_rightInvOn' (mapsTo_univ g t) h + LipschitzWith K (t.domRestrict g) := (hf.domRestrict univ).to_rightInvOn' (mapsTo_univ g t) h theorem to_rightInverse (hf : AntilipschitzWith K f) {g : β → α} (hg : Function.RightInverse g f) : LipschitzWith K g := by @@ -183,7 +184,7 @@ theorem isClosedEmbedding {α : Type*} {β : Type*} [EMetricSpace α] [EMetricSp { (hf.isUniformEmbedding hfc).isEmbedding with isClosed_range := hf.isClosed_range hfc } theorem subtype_coe (s : Set α) : AntilipschitzWith 1 ((↑) : s → α) := - AntilipschitzWith.id.restrict s + AntilipschitzWith.id.domRestrict s @[nontriviality] theorem of_subsingleton [Subsingleton α] {K : ℝ≥0} : AntilipschitzWith K f := fun x y => by diff --git a/Mathlib/Topology/MetricSpace/Holder.lean b/Mathlib/Topology/MetricSpace/Holder.lean index 5eb1eac1c7515a..6573ec0abb3a46 100644 --- a/Mathlib/Topology/MetricSpace/Holder.lean +++ b/Mathlib/Topology/MetricSpace/Holder.lean @@ -246,7 +246,7 @@ namespace HolderWith variable {C r : ℝ≥0} {f : X → Y} -theorem restrict_iff {s : Set X} : HolderWith C r (s.restrict f) ↔ HolderOnWith C r f s := by +theorem restrict_iff {s : Set X} : HolderWith C r (s.domRestrict f) ↔ HolderOnWith C r f s := by simp [HolderWith, HolderOnWith] protected alias ⟨_, _root_.HolderOnWith.holderWith⟩ := restrict_iff diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean index 05062ab1fe9e0c..0d1a6668760ace 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean @@ -285,4 +285,4 @@ theorem ContinuousOn.isSeparable_image {α : Type*} [TopologicalSpace α] [Pseud [TopologicalSpace β] {f : α → β} {s : Set α} (hf : ContinuousOn f s) (hs : IsSeparable s) : IsSeparable (f '' s) := by rw [image_eq_range, ← image_univ] - exact (isSeparable_univ_iff.2 hs.separableSpace).image hf.restrict + exact (isSeparable_univ_iff.2 hs.separableSpace).image hf.domRestrict diff --git a/Mathlib/Topology/MetricSpace/UniformConvergence.lean b/Mathlib/Topology/MetricSpace/UniformConvergence.lean index 6154a61cd1f937..db7bef0596d10e 100644 --- a/Mathlib/Topology/MetricSpace/UniformConvergence.lean +++ b/Mathlib/Topology/MetricSpace/UniformConvergence.lean @@ -215,14 +215,14 @@ lemma edist_def' [Finite 𝔖] (f g : α →ᵤ[𝔖] β) : lemma edist_eq_restrict_sUnion [Finite 𝔖] {f g : α →ᵤ[𝔖] β} : edist f g = edist - (UniformFun.ofFun ((⋃₀ 𝔖).restrict (toFun 𝔖 f))) - (UniformFun.ofFun ((⋃₀ 𝔖).restrict (toFun 𝔖 g))) := + (UniformFun.ofFun ((⋃₀ 𝔖).domRestrict (toFun 𝔖 f))) + (UniformFun.ofFun ((⋃₀ 𝔖).domRestrict (toFun 𝔖 g))) := iSup_subtype' lemma edist_eq_pi_restrict [Fintype 𝔖] {f g : α →ᵤ[𝔖] β} : edist f g = edist - (fun s : 𝔖 ↦ UniformFun.ofFun ((s : Set α).restrict (toFun 𝔖 f))) - (fun s : 𝔖 ↦ UniformFun.ofFun ((s : Set α).restrict (toFun 𝔖 g))) := by + (fun s : 𝔖 ↦ UniformFun.ofFun ((s : Set α).domRestrict (toFun 𝔖 f))) + (fun s : 𝔖 ↦ UniformFun.ofFun ((s : Set α).domRestrict (toFun 𝔖 g))) := by simp_rw [edist_def', iSup_subtype', edist_pi_def, Finset.sup_univ_eq_iSup] rfl @@ -273,11 +273,11 @@ lemma lipschitzWith_one_ofFun_toFun' [Finite 𝔗] (h : ⋃₀ 𝔖 ⊆ ⋃₀ lipschitzWith_iff.mpr fun _x hx ↦ lipschitzWith_eval (h hx) lemma lipschitzWith_restrict (s : Set α) (hs : s ∈ 𝔖) : - LipschitzWith 1 (UniformFun.ofFun ∘ s.restrict ∘ toFun 𝔖 : (α →ᵤ[𝔖] β) → (s →ᵤ β)) := + LipschitzWith 1 (UniformFun.ofFun ∘ s.domRestrict ∘ toFun 𝔖 : (α →ᵤ[𝔖] β) → (s →ᵤ β)) := UniformFun.lipschitzWith_iff.mpr fun x ↦ lipschitzWith_eval ⟨s, hs, x.2⟩ lemma isometry_restrict (s : Set α) : - Isometry (UniformFun.ofFun ∘ s.restrict ∘ toFun {s} : (α →ᵤ[{s}] β) → (s →ᵤ β)) := by + Isometry (UniformFun.ofFun ∘ s.domRestrict ∘ toFun {s} : (α →ᵤ[{s}] β) → (s →ᵤ β)) := by simp [Isometry, edist_def, UniformFun.edist_def, iSup_subtype] end EMetric @@ -311,13 +311,13 @@ noncomputable instance [BoundedSpace β] : BoundedSpace (α →ᵤ[𝔖] β) whe lemma edist_continuousRestrict [TopologicalSpace α] {f g : α →ᵤ[𝔖] β} [CompactSpace (⋃₀ 𝔖)] (hf : ContinuousOn (toFun 𝔖 f) (⋃₀ 𝔖)) (hg : ContinuousOn (toFun 𝔖 g) (⋃₀ 𝔖)) : - edist (⟨_, hf.restrict⟩ : C(⋃₀ 𝔖, β)) ⟨_, hg.restrict⟩ = edist f g := by + edist (⟨_, hf.domRestrict⟩ : C(⋃₀ 𝔖, β)) ⟨_, hg.domRestrict⟩ = edist f g := by simp [ContinuousMap.edist_eq_iSup, iSup_subtype, edist_def] lemma edist_continuousRestrict_of_singleton [TopologicalSpace α] {s : Set α} {f g : α →ᵤ[{s}] β} [CompactSpace s] (hf : ContinuousOn (toFun {s} f) s) (hg : ContinuousOn (toFun {s} g) s) : - edist (⟨_, hf.restrict⟩ : C(s, β)) ⟨_, hg.restrict⟩ = edist f g := by + edist (⟨_, hf.domRestrict⟩ : C(s, β)) ⟨_, hg.domRestrict⟩ = edist f g := by simp [ContinuousMap.edist_eq_iSup, iSup_subtype, edist_def] end Metric diff --git a/Mathlib/Topology/NhdsWithin.lean b/Mathlib/Topology/NhdsWithin.lean index cf2bf1be79dc2e..5c9dbd6e8c85a5 100644 --- a/Mathlib/Topology/NhdsWithin.lean +++ b/Mathlib/Topology/NhdsWithin.lean @@ -516,7 +516,7 @@ theorem frequently_nhds_subtype_iff (s : Set α) (a : s) (P : α → Prop) : eventually_nhds_subtype_iff s a (¬ P ·) |>.not theorem tendsto_nhdsWithin_iff_subtype {s : Set α} {a : α} (h : a ∈ s) (f : α → β) (l : Filter β) : - Tendsto f (𝓝[s] a) l ↔ Tendsto (s.restrict f) (𝓝 ⟨a, h⟩) l := by + Tendsto f (𝓝[s] a) l ↔ Tendsto (s.domRestrict f) (𝓝 ⟨a, h⟩) l := by rw [nhdsWithin_eq_map_subtype_coe h, tendsto_map'_iff]; rfl theorem clusterPt_principal_subtype_iff_frequently {s t : Set α} (hst : s ⊆ t) {J : Set s} {a : s} : diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean index bf365a5092deb1..e28ea04df2bc05 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean @@ -124,22 +124,23 @@ theorem isOpen_image_iff_of_subset_source {s : Set X} (hs : s ⊆ e.source) : `OpenPartialHomeomorph`. -/ @[simps toPartialHomeomorph] def ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) - (ho : IsOpenMap (e.source.restrict e)) (hs : IsOpen e.source) : OpenPartialHomeomorph X Y where + (ho : IsOpenMap (e.source.domRestrict e)) (hs : IsOpen e.source) : + OpenPartialHomeomorph X Y where toPartialEquiv := e open_source := hs - open_target := by simpa only [range_restrict, e.image_source_eq_target] using ho.isOpen_range + open_target := by simpa only [range_domRestrict, e.image_source_eq_target] using ho.isOpen_range continuousOn_toFun := hc continuousOn_invFun := e.image_source_eq_target ▸ ho.continuousOn_image_of_leftInvOn e.leftInvOn @[simp] theorem coe_ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) - (ho : IsOpenMap (e.source.restrict e)) (hs : IsOpen e.source) : + (ho : IsOpenMap (e.source.domRestrict e)) (hs : IsOpen e.source) : ⇑(ofContinuousOpenRestrict e hc ho hs) = e := rfl @[simp] theorem coe_ofContinuousOpenRestrict_symm (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) - (ho : IsOpenMap (e.source.restrict e)) (hs : IsOpen e.source) : + (ho : IsOpenMap (e.source.domRestrict e)) (hs : IsOpen e.source) : ⇑(ofContinuousOpenRestrict e hc ho hs).symm = e.symm := rfl @@ -148,7 +149,7 @@ theorem coe_ofContinuousOpenRestrict_symm (e : PartialEquiv X Y) (hc : Continuou @[simps! toPartialHomeomorph] def ofContinuousOpen (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) (ho : IsOpenMap e) (hs : IsOpen e.source) : OpenPartialHomeomorph X Y := - ofContinuousOpenRestrict e hc (ho.restrict hs) hs + ofContinuousOpenRestrict e hc (ho.domRestrict hs) hs @[simp] theorem coe_ofContinuousOpen (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) @@ -215,10 +216,10 @@ def toHomeomorphOfSourceEqUnivTargetEqUniv (h : e.source = (univ : Set X)) (h' : continuous_invFun := by simpa only [continuousOn_univ, h'] using e.continuousOn_symm -theorem isOpenEmbedding_restrict : IsOpenEmbedding (e.source.restrict e) := by +theorem isOpenEmbedding_restrict : IsOpenEmbedding (e.source.domRestrict e) := by refine .of_continuous_injective_isOpenMap (e.continuousOn.comp_continuous continuous_subtype_val Subtype.prop) e.injOn.injective fun V hV ↦ ?_ - rw [Set.restrict_eq, Set.image_comp] + rw [Set.domRestrict_eq, Set.image_comp] exact e.isOpen_image_of_subset_source (e.open_source.isOpenMap_subtype_val V hV) fun _ ⟨x, _, h⟩ ↦ h ▸ x.2 diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean index bda74e60b811cb..9b447abef39aa9 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean @@ -269,7 +269,7 @@ theorem subtypeRestr_def : e.subtypeRestr hs = (s.openPartialHomeomorphSubtypeCo @[simp, mfld_simps] theorem subtypeRestr_coe : - ((e.subtypeRestr hs : OpenPartialHomeomorph s Y) : s → Y) = Set.restrict ↑s (e : X → Y) := + ((e.subtypeRestr hs : OpenPartialHomeomorph s Y) : s → Y) = Set.domRestrict ↑s (e : X → Y) := rfl @[simp, mfld_simps] @@ -312,7 +312,7 @@ theorem subtypeRestr_symm_apply {U : Opens X} (hU : Nonempty U) {y : Y} (hy : y ∈ (e.subtypeRestr hU).target) : (Subtype.val ∘ (e.subtypeRestr hU).symm) y = e.symm y := by rw [e.eq_symm_apply _ hy.1] - · change restrict _ e _ = _ + · change domRestrict _ e _ = _ rw [← e.subtypeRestr_coe hU, (e.subtypeRestr hU).right_inv hy] · have := OpenPartialHomeomorph.map_target _ hy rwa [e.subtypeRestr_source] at this diff --git a/Mathlib/Topology/Order/IntermediateValue.lean b/Mathlib/Topology/Order/IntermediateValue.lean index fad1f7ddd6e2d4..c860a7b10030ec 100644 --- a/Mathlib/Topology/Order/IntermediateValue.lean +++ b/Mathlib/Topology/Order/IntermediateValue.lean @@ -95,14 +95,14 @@ theorem IsPreconnected.intermediate_value₂ {s : Set X} (hs : IsPreconnected s) (ha' : f a ≤ g a) (hb' : g b ≤ f b) : ∃ x ∈ s, f x = g x := let ⟨x, hx⟩ := @intermediate_value_univ₂ s α _ _ _ _ (Subtype.preconnectedSpace hs) ⟨a, ha⟩ ⟨b, hb⟩ _ _ - (continuousOn_iff_continuous_restrict.1 hf) (continuousOn_iff_continuous_restrict.1 hg) ha' - hb' + (continuousOn_iff_continuous_domRestrict.1 hf) + (continuousOn_iff_continuous_domRestrict.1 hg) ha' hb' ⟨x, x.2, hx⟩ theorem IsPreconnected.intermediate_value₂_eventually₁ {s : Set X} (hs : IsPreconnected s) {a : X} {l : Filter X} (ha : a ∈ s) [NeBot l] (hl : l ≤ 𝓟 s) {f g : X → α} (hf : ContinuousOn f s) (hg : ContinuousOn g s) (ha' : f a ≤ g a) (he : g ≤ᶠ[l] f) : ∃ x ∈ s, f x = g x := by - rw [continuousOn_iff_continuous_restrict] at hf hg + rw [continuousOn_iff_continuous_domRestrict] at hf hg obtain ⟨b, h⟩ := @intermediate_value_univ₂_eventually₁ _ _ _ _ _ _ (Subtype.preconnectedSpace hs) ⟨a, ha⟩ _ (comap_coe_neBot_of_le_principal hl) _ _ hf hg ha' (he.comap _) @@ -112,7 +112,7 @@ theorem IsPreconnected.intermediate_value₂_eventually₂ {s : Set X} (hs : IsP {l₁ l₂ : Filter X} [NeBot l₁] [NeBot l₂] (hl₁ : l₁ ≤ 𝓟 s) (hl₂ : l₂ ≤ 𝓟 s) {f g : X → α} (hf : ContinuousOn f s) (hg : ContinuousOn g s) (he₁ : f ≤ᶠ[l₁] g) (he₂ : g ≤ᶠ[l₂] f) : ∃ x ∈ s, f x = g x := by - rw [continuousOn_iff_continuous_restrict] at hf hg + rw [continuousOn_iff_continuous_domRestrict] at hf hg obtain ⟨b, h⟩ := @intermediate_value_univ₂_eventually₂ _ _ _ _ _ _ (Subtype.preconnectedSpace hs) _ _ (comap_coe_neBot_of_le_principal hl₁) (comap_coe_neBot_of_le_principal hl₂) _ _ hf hg @@ -736,7 +736,7 @@ theorem ContinuousOn.surjOn_of_tendsto {f : α → δ} {s : Set α} [OrdConnecte (hf : ContinuousOn f s) (hbot : Tendsto (fun x : s => f x) atBot atBot) (htop : Tendsto (fun x : s => f x) atTop atTop) : SurjOn f s univ := haveI := Classical.inhabited_of_nonempty hs.to_subtype - surjOn_iff_surjective.2 <| hf.restrict.surjective htop hbot + surjOn_iff_surjective.2 <| hf.domRestrict.surjective htop hbot /-- If a function `f : α → β` is continuous on a nonempty interval `s`, its restriction to `s` tends to `Filter.atTop : Filter β` along `Filter.atBot : Filter ↥s` and tends to @@ -792,9 +792,9 @@ theorem Continuous.strictMonoOn_of_inj_rigidity {f : α → δ} have hbt : b ≤ t := le_max_left b y have hf_mono_st : StrictMonoOn f (Icc s t) ∨ StrictAntiOn f (Icc s t) := by have : Fact (s ≤ t) := ⟨hsa.trans <| hbt.trans' hab.le⟩ - have := Continuous.strictMono_of_inj_boundedOrder' (f := Set.restrict (Icc s t) f) - hf_c.continuousOn.restrict hf_i.injOn.injective - exact this.imp strictMono_restrict.mp strictAntiOn_iff_strictAnti.mpr + have := Continuous.strictMono_of_inj_boundedOrder' (f := Set.domRestrict (Icc s t) f) + hf_c.continuousOn.domRestrict hf_i.injOn.injective + exact this.imp strictMono_domRestrict.mp strictAntiOn_iff_strictAnti.mpr have (h : StrictAntiOn f (Icc s t)) : False := by have : Icc a b ⊆ Icc s t := Icc_subset_Icc hsa hbt replace : StrictAntiOn f (Icc a b) := StrictAntiOn.mono h this @@ -815,10 +815,10 @@ theorem ContinuousOn.strictMonoOn_of_injOn_Icc {a b : α} {f : α → δ} (hf_c : ContinuousOn f (Icc a b)) (hf_i : InjOn f (Icc a b)) : StrictMonoOn f (Icc a b) := by have : Fact (a ≤ b) := ⟨hab⟩ - refine StrictMono.of_restrict ?_ - set g : Icc a b → δ := Set.restrict (Icc a b) f + refine StrictMono.of_domRestrict ?_ + set g : Icc a b → δ := Set.domRestrict (Icc a b) f have hgab : g ⊥ ≤ g ⊤ := by aesop - exact Continuous.strictMono_of_inj_boundedOrder (f := g) hf_c.restrict hgab hf_i.injective + exact Continuous.strictMono_of_inj_boundedOrder (f := g) hf_c.domRestrict hgab hf_i.injective /-- Suppose `f : [a, b] → δ` is continuous and injective. Then `f` is strictly antitone (decreasing) if `f(b) ≤ f(a)`. -/ @@ -856,10 +856,10 @@ theorem ContinuousOn.strictMonoOn_of_injOn_Ioo {a b : α} {f : α → δ} (hab : (hf_c : ContinuousOn f (Ioo a b)) (hf_i : InjOn f (Ioo a b)) : StrictMonoOn f (Ioo a b) ∨ StrictAntiOn f (Ioo a b) := by have : Inhabited (Ioo a b) := Classical.inhabited_of_nonempty (nonempty_Ioo_subtype hab) - let g : Ioo a b → δ := Set.restrict (Ioo a b) f + let g : Ioo a b → δ := Set.domRestrict (Ioo a b) f have : StrictMono g ∨ StrictAnti g := - Continuous.strictMono_of_inj hf_c.restrict hf_i.injective - exact this.imp strictMono_restrict.mp strictAntiOn_iff_strictAnti.mpr + Continuous.strictMono_of_inj hf_c.domRestrict hf_i.injective + exact this.imp strictMono_domRestrict.mp strictAntiOn_iff_strictAnti.mpr /-! ### Images of continuous monotone functions diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 525b8006cece8f..d74c618daea080 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -169,11 +169,11 @@ instance Prod.supConvergenceClass [SupConvergenceClass α] [SupConvergenceClass β] : SupConvergenceClass (α × β) := by constructor rintro ⟨a, b⟩ s h - rw [isLUB_prod, ← range_restrict, ← range_restrict] at h + rw [isLUB_prod, ← range_domRestrict, ← range_domRestrict] at h have A : Tendsto (fun x : s => (x : α × β).1) atTop (𝓝 a) := - tendsto_atTop_isLUB (monotone_fst.restrict s) h.1 + tendsto_atTop_isLUB (monotone_fst.domRestrict s) h.1 have B : Tendsto (fun x : s => (x : α × β).2) atTop (𝓝 b) := - tendsto_atTop_isLUB (monotone_snd.restrict s) h.2 + tendsto_atTop_isLUB (monotone_snd.domRestrict s) h.2 exact A.prodMk_nhds B instance [Preorder α] [Preorder β] [TopologicalSpace α] [TopologicalSpace β] [InfConvergenceClass α] @@ -184,8 +184,8 @@ instance Pi.supConvergenceClass {ι : Type*} {α : ι → Type*} [∀ i, Preorder (α i)] [∀ i, TopologicalSpace (α i)] [∀ i, SupConvergenceClass (α i)] : SupConvergenceClass (∀ i, α i) := by refine ⟨fun f s h => ?_⟩ - simp only [isLUB_pi, ← range_restrict] at h - exact tendsto_pi_nhds.2 fun i => tendsto_atTop_isLUB ((monotone_eval _).restrict _) (h i) + simp only [isLUB_pi, ← range_domRestrict] at h + exact tendsto_pi_nhds.2 fun i => tendsto_atTop_isLUB ((monotone_eval _).domRestrict _) (h i) instance Pi.infConvergenceClass {ι : Type*} {α : ι → Type*} [∀ i, Preorder (α i)] [∀ i, TopologicalSpace (α i)] diff --git a/Mathlib/Topology/PreorderRestrict.lean b/Mathlib/Topology/PreorderRestrict.lean index 211997c2e9b47d..541b732aad7cb9 100644 --- a/Mathlib/Topology/PreorderRestrict.lean +++ b/Mathlib/Topology/PreorderRestrict.lean @@ -23,11 +23,11 @@ variable {α : Type*} [Preorder α] {X : α → Type*} [∀ i, TopologicalSpace @[continuity, fun_prop] theorem continuous_restrictLe (a : α) : Continuous (restrictLe (π := X) a) := - Pi.continuous_restrict _ + Pi.continuous_domRestrict _ @[continuity, fun_prop] theorem continuous_restrictLe₂ {a b : α} (hab : a ≤ b) : Continuous (restrictLe₂ (π := X) hab) := - Pi.continuous_restrict₂ _ + Pi.continuous_domRestrict₂ _ variable [LocallyFiniteOrderBot α] diff --git a/Mathlib/Topology/Semicontinuity/Basic.lean b/Mathlib/Topology/Semicontinuity/Basic.lean index 858f8f36a78929..6217107646a186 100644 --- a/Mathlib/Topology/Semicontinuity/Basic.lean +++ b/Mathlib/Topology/Semicontinuity/Basic.lean @@ -183,7 +183,7 @@ theorem LowerSemicontinuous.isOpen_preimage (hf : LowerSemicontinuous f) (y : β theorem lowerSemicontinuousOn_iff_preimage_Ioi : LowerSemicontinuousOn f s ↔ ∀ b, ∃ u, IsOpen u ∧ s ∩ f ⁻¹' Set.Ioi b = s ∩ u := by - simp only [← lowerSemicontinuous_restrict_iff, restrict_eq, + simp only [← lowerSemicontinuous_restrict_iff, domRestrict_eq, lowerSemicontinuous_iff_isOpen_preimage, preimage_comp, isOpen_induced_iff, Subtype.preimage_coe_eq_preimage_coe_iff, eq_comm] @@ -240,7 +240,7 @@ theorem LowerSemicontinuous.isClosed_preimage {f : α → γ} (hf : LowerSemicon theorem lowerSemicontinuousOn_iff_preimage_Iic {f : α → γ} : LowerSemicontinuousOn f s ↔ ∀ b, ∃ v, IsClosed v ∧ s ∩ f ⁻¹' Set.Iic b = s ∩ v := by - simp only [← lowerSemicontinuous_restrict_iff, restrict_eq, + simp only [← lowerSemicontinuous_restrict_iff, domRestrict_eq, lowerSemicontinuous_iff_isClosed_preimage, preimage_comp, isClosed_induced_iff, Subtype.preimage_coe_eq_preimage_coe_iff, eq_comm] diff --git a/Mathlib/Topology/Semicontinuity/Defs.lean b/Mathlib/Topology/Semicontinuity/Defs.lean index 0f929f8d6d07a3..d47c66a8651ffb 100644 --- a/Mathlib/Topology/Semicontinuity/Defs.lean +++ b/Mathlib/Topology/Semicontinuity/Defs.lean @@ -148,10 +148,10 @@ theorem semicontinuousOn_univ_iff : SemicontinuousOn r univ ↔ Semicontinuous r simp [SemicontinuousOn, Semicontinuous, semicontinuousWithinAt_univ_iff] @[simp] theorem semicontinuous_restrict_iff : - Semicontinuous (s.restrict r) ↔ SemicontinuousOn r s := by + Semicontinuous (s.domRestrict r) ↔ SemicontinuousOn r s := by rw [SemicontinuousOn, Semicontinuous, SetCoe.forall] refine forall₂_congr fun a ha ↦ forall₂_congr fun b _ ↦ ?_ - simp only [nhdsWithin_eq_map_subtype_coe ha, eventually_map, restrict] + simp only [nhdsWithin_eq_map_subtype_coe ha, eventually_map, domRestrict] theorem Semicontinuous.semicontinuousAt (h : Semicontinuous r) (x : α) : SemicontinuousAt r x := @@ -389,7 +389,7 @@ theorem lowerSemicontinuousOn_univ_iff : LowerSemicontinuousOn f univ ↔ LowerS semicontinuousOn_univ_iff @[simp] theorem lowerSemicontinuous_restrict_iff : - LowerSemicontinuous (s.restrict f) ↔ LowerSemicontinuousOn f s := + LowerSemicontinuous (s.domRestrict f) ↔ LowerSemicontinuousOn f s := semicontinuous_restrict_iff (r := (f · > ·)) theorem LowerSemicontinuous.lowerSemicontinuousAt (h : LowerSemicontinuous f) (x : α) : @@ -468,7 +468,7 @@ theorem upperSemicontinuousWithinAt_univ_iff : semicontinuousWithinAt_univ_iff @[simp] theorem upperSemicontinuousOn_iff_restrict {s : Set α} : - UpperSemicontinuous (s.restrict f) ↔ UpperSemicontinuousOn f s := + UpperSemicontinuous (s.domRestrict f) ↔ UpperSemicontinuousOn f s := lowerSemicontinuous_restrict_iff (β := βᵒᵈ) theorem UpperSemicontinuousAt.upperSemicontinuousWithinAt (s : Set α) @@ -735,7 +735,7 @@ theorem lowerHemicontinuousOn_univ_iff : LowerHemicontinuousOn f univ ↔ LowerH semicontinuousOn_univ_iff @[simp] theorem lowerHemicontinuous_restrict_iff : - LowerHemicontinuous (s.restrict f) ↔ LowerHemicontinuousOn f s := + LowerHemicontinuous (s.domRestrict f) ↔ LowerHemicontinuousOn f s := semicontinuous_restrict_iff (r := (fun x t ↦ IsOpen t ∧ ((f x) ∩ t).Nonempty)) theorem LowerHemicontinuous.lowerHemicontinuousAt (h : LowerHemicontinuous f) (x : α) : @@ -849,7 +849,7 @@ theorem upperHemicontinuousWithinAt_univ_iff : semicontinuousWithinAt_univ_iff @[simp] theorem upperHemicontinuousOn_iff_restrict {s : Set α} : - UpperHemicontinuous (s.restrict f) ↔ UpperHemicontinuousOn f s := + UpperHemicontinuous (s.domRestrict f) ↔ UpperHemicontinuousOn f s := semicontinuous_restrict_iff (r := (fun x t ↦ t ∈ 𝓝ˢ (f x))) theorem UpperHemicontinuousAt.upperHemicontinuousWithinAt (s : Set α) @@ -991,7 +991,7 @@ theorem hasOpenLowerSectionsOn_univ_iff : semicontinuousOn_univ_iff @[simp] theorem hasOpenLowerSections_restrict_iff : - HasOpenLowerSections (s.restrict f) ↔ HasOpenLowerSectionsOn f s := + HasOpenLowerSections (s.domRestrict f) ↔ HasOpenLowerSectionsOn f s := semicontinuous_restrict_iff (r := (fun x b ↦ b ∈ f x)) theorem HasOpenLowerSections.hasOpenLowerSectionsOn (h : HasOpenLowerSections f) (s : Set α) : diff --git a/Mathlib/Topology/SeparatedMap.lean b/Mathlib/Topology/SeparatedMap.lean index fa21f476ac921a..21a245c5712f9a 100644 --- a/Mathlib/Topology/SeparatedMap.lean +++ b/Mathlib/Topology/SeparatedMap.lean @@ -208,8 +208,8 @@ theorem eq_of_comp_eq theorem eqOn_of_comp_eqOn (hs : IsPreconnected s) (h₁ : ContinuousOn g₁ s) (h₂ : ContinuousOn g₂ s) (he : s.EqOn (p ∘ g₁) (p ∘ g₂)) {a : A} (has : a ∈ s) (ha : g₁ a = g₂ a) : s.EqOn g₁ g₂ := by - rw [← Set.restrict_eq_restrict_iff] at he ⊢ - rw [continuousOn_iff_continuous_restrict] at h₁ h₂ + rw [← Set.domRestrict_eq_domRestrict_iff] at he ⊢ + rw [continuousOn_iff_continuous_domRestrict] at h₁ h₂ rw [isPreconnected_iff_preconnectedSpace] at hs exact sep.eq_of_comp_eq inj h₁ h₂ he ⟨a, has⟩ ha diff --git a/Mathlib/Topology/Separation/Basic.lean b/Mathlib/Topology/Separation/Basic.lean index 9d1094ef15732f..d95b92339eefc2 100644 --- a/Mathlib/Topology/Separation/Basic.lean +++ b/Mathlib/Topology/Separation/Basic.lean @@ -807,7 +807,7 @@ lemma Set.Finite.isDiscrete [T1Space X] {s : Set X} (hs : s.Finite) : IsDiscrete theorem Set.Finite.continuousOn [T1Space X] [TopologicalSpace Y] {s : Set X} (hs : s.Finite) (f : X → Y) : ContinuousOn f s := by - rw [continuousOn_iff_continuous_restrict] + rw [continuousOn_iff_continuous_domRestrict] have : Finite s := hs fun_prop diff --git a/Mathlib/Topology/TietzeExtension.lean b/Mathlib/Topology/TietzeExtension.lean index 988717457d4e58..05a3401b914c0e 100644 --- a/Mathlib/Topology/TietzeExtension.lean +++ b/Mathlib/Topology/TietzeExtension.lean @@ -279,11 +279,14 @@ theorem exists_extension_norm_eq_of_isClosedEmbedding (f : X →ᵇ ℝ) {e : X set. If `f` is a bounded continuous real-valued function defined on a closed set in a normal topological space, then it can be extended to a bounded continuous function of the same norm defined on the whole space. -/ -theorem exists_norm_eq_restrict_eq_of_closed {s : Set Y} (f : s →ᵇ ℝ) (hs : IsClosed s) : - ∃ g : Y →ᵇ ℝ, ‖g‖ = ‖f‖ ∧ g.restrict s = f := +theorem exists_norm_eq_domRestrict_eq_of_closed {s : Set Y} (f : s →ᵇ ℝ) (hs : IsClosed s) : + ∃ g : Y →ᵇ ℝ, ‖g‖ = ‖f‖ ∧ g.domRestrict s = f := exists_extension_norm_eq_of_isClosedEmbedding' f ((ContinuousMap.id _).restrict s) hs.isClosedEmbedding_subtypeVal +@[deprecated (since := "2026-07-19")] +alias exists_norm_eq_restrict_eq_of_closed := exists_norm_eq_domRestrict_eq_of_closed + /-- **Tietze extension theorem** for real-valued bounded continuous maps, a version for a closed embedding and a bounded continuous function that takes values in a non-trivial closed interval. See also `exists_extension_forall_mem_of_isClosedEmbedding` for a more general statement that works @@ -440,14 +443,17 @@ set. Let `s` be a closed set in a normal topological space `Y`. Let `f` be a bou real-valued function on `s`. Let `t` be a nonempty convex set of real numbers (we use `OrdConnected` instead of `Convex` to automatically deduce this argument by typeclass search) such that `f x ∈ t` for all `x : s`. Then there exists a bounded continuous real-valued function -`g : Y →ᵇ ℝ` such that `g y ∈ t` for all `y` and `g.restrict s = f`. -/ -theorem exists_forall_mem_restrict_eq_of_closed {s : Set Y} (f : s →ᵇ ℝ) (hs : IsClosed s) +`g : Y →ᵇ ℝ` such that `g y ∈ t` for all `y` and `g.domRestrict s = f`. -/ +theorem exists_forall_mem_domRestrict_eq_of_closed {s : Set Y} (f : s →ᵇ ℝ) (hs : IsClosed s) {t : Set ℝ} [OrdConnected t] (hf : ∀ x, f x ∈ t) (hne : t.Nonempty) : - ∃ g : Y →ᵇ ℝ, (∀ y, g y ∈ t) ∧ g.restrict s = f := by + ∃ g : Y →ᵇ ℝ, (∀ y, g y ∈ t) ∧ g.domRestrict s = f := by obtain ⟨g, hg, hgf⟩ := exists_extension_forall_mem_of_isClosedEmbedding f hf hne hs.isClosedEmbedding_subtypeVal exact ⟨g, hg, DFunLike.coe_injective hgf⟩ +@[deprecated (since := "2026-07-19")] +alias exists_forall_mem_restrict_eq_of_closed := exists_forall_mem_domRestrict_eq_of_closed + end BoundedContinuousFunction namespace ContinuousMap diff --git a/Mathlib/Topology/UniformSpace/Ascoli.lean b/Mathlib/Topology/UniformSpace/Ascoli.lean index c10f99ce784917..716a7b82de3960 100644 --- a/Mathlib/Topology/UniformSpace/Ascoli.lean +++ b/Mathlib/Topology/UniformSpace/Ascoli.lean @@ -216,28 +216,29 @@ as well as their unprimed versions in case `𝔖` covers `X`. -/ theorem EquicontinuousOn.comap_uniformOnFun_eq {𝔖 : Set (Set X)} (𝔖_compact : ∀ K ∈ 𝔖, IsCompact K) (F_eqcont : ∀ K ∈ 𝔖, EquicontinuousOn F K) : (UniformOnFun.uniformSpace X α 𝔖).comap F = - (Pi.uniformSpace _).comap ((⋃₀ 𝔖).restrict ∘ F) := by + (Pi.uniformSpace _).comap ((⋃₀ 𝔖).domRestrict ∘ F) := by -- Recall that the uniform structure on `X →ᵤ[𝔖] α` is the one induced by all the maps - -- `K.restrict : (X →ᵤ[𝔖] α) → (K →ᵤ α)` for `K ∈ 𝔖`. Its pullback along `F`, which is + -- `K.domRestrict : (X →ᵤ[𝔖] α) → (K →ᵤ α)` for `K ∈ 𝔖`. Its pullback along `F`, which is -- the LHS of our goal, is thus the uniform structure induced by the maps - -- `K.restrict ∘ F : ι → (K →ᵤ α)` for `K ∈ 𝔖`. + -- `K.domRestrict ∘ F : ι → (K →ᵤ α)` for `K ∈ 𝔖`. have H1 : (UniformOnFun.uniformSpace X α 𝔖).comap F = - ⨅ (K ∈ 𝔖), (UniformFun.uniformSpace _ _).comap (K.restrict ∘ F) := by + ⨅ (K ∈ 𝔖), (UniformFun.uniformSpace _ _).comap (K.domRestrict ∘ F) := by simp_rw [UniformOnFun.uniformSpace, UniformSpace.comap_iInf, ← UniformSpace.comap_comap, UniformFun.ofFun, Equiv.coe_fn_mk, UniformOnFun.toFun, UniformOnFun.ofFun, Function.comp_def, UniformFun, Equiv.coe_fn_symm_mk] -- Now, note that a similar fact is true for the uniform structure on `X → α` induced by - -- the map `(⋃₀ 𝔖).restrict : (X → α) → ((⋃₀ 𝔖) → α)`: it is equal to the one induced by - -- all maps `K.restrict : (X → α) → (K → α)` for `K ∈ 𝔖`, which means that the RHS of our - -- goal is the uniform structure induced by the maps `K.restrict ∘ F : ι → (K → α)` for `K ∈ 𝔖`. - have H2 : (Pi.uniformSpace _).comap ((⋃₀ 𝔖).restrict ∘ F) = - ⨅ (K ∈ 𝔖), (Pi.uniformSpace _).comap (K.restrict ∘ F) := by + -- the map `(⋃₀ 𝔖).domRestrict : (X → α) → ((⋃₀ 𝔖) → α)`: it is equal to the one induced by + -- all maps `K.domRestrict : (X → α) → (K → α)` for `K ∈ 𝔖`, which means that the RHS of our + -- goal is the uniform structure induced by the maps `K.domRestrict ∘ F : ι → (K → α)` + -- for `K ∈ 𝔖`. + have H2 : (Pi.uniformSpace _).comap ((⋃₀ 𝔖).domRestrict ∘ F) = + ⨅ (K ∈ 𝔖), (Pi.uniformSpace _).comap (K.domRestrict ∘ F) := by simp_rw [UniformSpace.comap_comap, Pi.uniformSpace_comap_restrict_sUnion (fun _ ↦ α) 𝔖, UniformSpace.comap_iInf] -- But, for `K ∈ 𝔖` fixed, we know that the uniform structures of `K →ᵤ α` and `K → α` - -- induce, via the equicontinuous family `K.restrict ∘ F`, the same uniform structure on `ι`. - have H3 : ∀ K ∈ 𝔖, (UniformFun.uniformSpace K α).comap (K.restrict ∘ F) = - (Pi.uniformSpace _).comap (K.restrict ∘ F) := fun K hK ↦ by + -- induce, via the equicontinuous family `K.domRestrict ∘ F`, the same uniform structure on `ι`. + have H3 : ∀ K ∈ 𝔖, (UniformFun.uniformSpace K α).comap (K.domRestrict ∘ F) = + (Pi.uniformSpace _).comap (K.domRestrict ∘ F) := fun K hK ↦ by have : CompactSpace K := isCompact_iff_compactSpace.mp (𝔖_compact K hK) exact (equicontinuous_restrict_iff _ |>.mpr <| F_eqcont K hK).comap_uniformFun_eq -- Combining these three facts completes the proof. @@ -257,7 +258,7 @@ lemma EquicontinuousOn.isUniformInducing_uniformOnFun_iff_pi' [UniformSpace ι] {𝔖 : Set (Set X)} (𝔖_compact : ∀ K ∈ 𝔖, IsCompact K) (F_eqcont : ∀ K ∈ 𝔖, EquicontinuousOn F K) : IsUniformInducing (UniformOnFun.ofFun 𝔖 ∘ F) ↔ - IsUniformInducing ((⋃₀ 𝔖).restrict ∘ F) := by + IsUniformInducing ((⋃₀ 𝔖).domRestrict ∘ F) := by rw [isUniformInducing_iff_uniformSpace, isUniformInducing_iff_uniformSpace, ← EquicontinuousOn.comap_uniformOnFun_eq 𝔖_compact F_eqcont] rfl @@ -280,7 +281,7 @@ lemma EquicontinuousOn.isUniformInducing_uniformOnFun_iff_pi [UniformSpace ι] let φ : ((⋃₀ 𝔖) → α) ≃ᵤ (X → α) := UniformEquiv.piCongrLeft (β := fun _ ↦ α) (Equiv.subtypeUnivEquiv 𝔖_covers) rw [EquicontinuousOn.isUniformInducing_uniformOnFun_iff_pi' 𝔖_compact F_eqcont, - show restrict (⋃₀ 𝔖) ∘ F = φ.symm ∘ F by rfl] + show domRestrict (⋃₀ 𝔖) ∘ F = φ.symm ∘ F by rfl] exact ⟨fun H ↦ φ.isUniformInducing.comp H, fun H ↦ φ.symm.isUniformInducing.comp H⟩ /-- Let `X` be a topological space, `𝔖` a family of compact subsets of `X`, `α` a uniform space, @@ -296,10 +297,10 @@ lemma EquicontinuousOn.inducing_uniformOnFun_iff_pi' [TopologicalSpace ι] {𝔖 : Set (Set X)} (𝔖_compact : ∀ K ∈ 𝔖, IsCompact K) (F_eqcont : ∀ K ∈ 𝔖, EquicontinuousOn F K) : IsInducing (UniformOnFun.ofFun 𝔖 ∘ F) ↔ - IsInducing ((⋃₀ 𝔖).restrict ∘ F) := by + IsInducing ((⋃₀ 𝔖).domRestrict ∘ F) := by rw [isInducing_iff, isInducing_iff] change (_ = ((UniformOnFun.uniformSpace X α 𝔖).comap F).toTopologicalSpace) ↔ - (_ = ((Pi.uniformSpace _).comap ((⋃₀ 𝔖).restrict ∘ F)).toTopologicalSpace) + (_ = ((Pi.uniformSpace _).comap ((⋃₀ 𝔖).domRestrict ∘ F)).toTopologicalSpace) rw [← EquicontinuousOn.comap_uniformOnFun_eq 𝔖_compact F_eqcont] /-- Let `X` be a topological space, `𝔖` a covering of `X` by compact subsets, `α` a uniform space, @@ -319,7 +320,7 @@ lemma EquicontinuousOn.isInducing_uniformOnFun_iff_pi [TopologicalSpace ι] let φ : ((⋃₀ 𝔖) → α) ≃ₜ (X → α) := Homeomorph.piCongrLeft (Y := fun _ ↦ α) (Equiv.subtypeUnivEquiv 𝔖_covers) rw [EquicontinuousOn.inducing_uniformOnFun_iff_pi' 𝔖_compact F_eqcont, - show restrict (⋃₀ 𝔖) ∘ F = φ.symm ∘ F by rfl] + show domRestrict (⋃₀ 𝔖) ∘ F = φ.symm ∘ F by rfl] exact ⟨fun H ↦ φ.isInducing.comp H, fun H ↦ φ.symm.isInducing.comp H⟩ -- TODO: find a way to factor common elements of this proof and the proof of @@ -332,17 +333,17 @@ theorem EquicontinuousOn.tendsto_uniformOnFun_iff_pi' {𝔖 : Set (Set X)} (𝔖_compact : ∀ K ∈ 𝔖, IsCompact K) (F_eqcont : ∀ K ∈ 𝔖, EquicontinuousOn F K) (ℱ : Filter ι) (f : X → α) : Tendsto (UniformOnFun.ofFun 𝔖 ∘ F) ℱ (𝓝 <| UniformOnFun.ofFun 𝔖 f) ↔ - Tendsto ((⋃₀ 𝔖).restrict ∘ F) ℱ (𝓝 <| (⋃₀ 𝔖).restrict f) := by + Tendsto ((⋃₀ 𝔖).domRestrict ∘ F) ℱ (𝓝 <| (⋃₀ 𝔖).domRestrict f) := by -- Recall that the uniform structure on `X →ᵤ[𝔖] α` is the one induced by all the maps - -- `K.restrict : (X →ᵤ[𝔖] α) → (K →ᵤ α)` for `K ∈ 𝔖`. + -- `K.domRestrict : (X →ᵤ[𝔖] α) → (K →ᵤ α)` for `K ∈ 𝔖`. -- Similarly, the uniform structure on `X → α` induced by the map - -- `(⋃₀ 𝔖).restrict : (X → α) → ((⋃₀ 𝔖) → α)` is equal to the one induced by - -- all maps `K.restrict : (X → α) → (K → α)` for `K ∈ 𝔖` + -- `(⋃₀ 𝔖).domRestrict : (X → α) → ((⋃₀ 𝔖) → α)` is equal to the one induced by + -- all maps `K.domRestrict : (X → α) → (K → α)` for `K ∈ 𝔖` -- Thus, we just have to compare the two sides of our goal when restricted to some -- `K ∈ 𝔖`, where we can apply `Equicontinuous.tendsto_uniformFun_iff_pi`. - rw [← Filter.tendsto_comap_iff (g := (⋃₀ 𝔖).restrict), ← nhds_induced] + rw [← Filter.tendsto_comap_iff (g := (⋃₀ 𝔖).domRestrict), ← nhds_induced] simp_rw +instances [UniformOnFun.topologicalSpace_eq, - Pi.induced_restrict_sUnion 𝔖 (A := fun _ ↦ α), _root_.nhds_iInf, nhds_induced, tendsto_iInf, + Pi.induced_domRestrict_sUnion 𝔖 (A := fun _ ↦ α), _root_.nhds_iInf, nhds_induced, tendsto_iInf, tendsto_comap_iff] congrm ∀ K (hK : K ∈ 𝔖), ?_ have : CompactSpace K := isCompact_iff_compactSpace.mp (𝔖_compact K hK) @@ -365,7 +366,8 @@ theorem EquicontinuousOn.tendsto_uniformOnFun_iff_pi let φ : ((⋃₀ 𝔖) → α) ≃ₜ (X → α) := Homeomorph.piCongrLeft (Y := fun _ ↦ α) (Equiv.subtypeUnivEquiv 𝔖_covers) rw [EquicontinuousOn.tendsto_uniformOnFun_iff_pi' 𝔖_compact F_eqcont, - show restrict (⋃₀ 𝔖) ∘ F = φ.symm ∘ F by rfl, show restrict (⋃₀ 𝔖) f = φ.symm f by rfl, + show domRestrict (⋃₀ 𝔖) ∘ F = φ.symm ∘ F by rfl, + show domRestrict (⋃₀ 𝔖) f = φ.symm f by rfl, φ.symm.isInducing.tendsto_nhds_iff] /-- Let `X` be a topological space, `𝔖` a family of compact subsets of `X` and @@ -375,14 +377,14 @@ theorem EquicontinuousOn.isClosed_range_pi_of_uniformOnFun' {𝔖 : Set (Set X)} (𝔖_compact : ∀ K ∈ 𝔖, IsCompact K) (F_eqcont : ∀ K ∈ 𝔖, EquicontinuousOn F K) (H : IsClosed (range <| UniformOnFun.ofFun 𝔖 ∘ F)) : - IsClosed (range <| (⋃₀ 𝔖).restrict ∘ F) := by + IsClosed (range <| (⋃₀ 𝔖).domRestrict ∘ F) := by -- Do we have no equivalent of `nontriviality`? rcases isEmpty_or_nonempty α with _ | _ · simp [isClosed_discrete] -- This follows from the previous lemmas and the characterization of the closure using filters. simp_rw [isClosed_iff_clusterPt, ← Filter.map_top, ← mapClusterPt_def, mapClusterPt_iff_ultrafilter, range_comp, Subtype.coe_injective.surjective_comp_right.forall, - ← restrict_eq, ← EquicontinuousOn.tendsto_uniformOnFun_iff_pi' 𝔖_compact F_eqcont] + ← domRestrict_eq, ← EquicontinuousOn.tendsto_uniformOnFun_iff_pi' 𝔖_compact F_eqcont] exact fun f ⟨u, _, hu⟩ ↦ mem_image_of_mem _ <| H.mem_of_tendsto hu <| Eventually.of_forall mem_range_self @@ -422,8 +424,8 @@ theorem ArzelaAscoli.compactSpace_of_closed_inducing' [TopologicalSpace ι] { (F_pointwiseCompact : ∀ K ∈ 𝔖, ∀ x ∈ K, ∃ Q, IsCompact Q ∧ ∀ i, F i x ∈ Q) : CompactSpace ι := by -- By equicontinuity, we know that the topology on `ι` is also the one induced by - -- `restrict (⋃₀ 𝔖) ∘ F`. - have : IsInducing (restrict (⋃₀ 𝔖) ∘ F) := by + -- `domRestrict (⋃₀ 𝔖) ∘ F`. + have : IsInducing (domRestrict (⋃₀ 𝔖) ∘ F) := by rwa [EquicontinuousOn.inducing_uniformOnFun_iff_pi' 𝔖_compact F_eqcont] at F_ind -- Thus, we just have to check that the range of this map is compact. rw [← isCompact_univ_iff, this.isCompact_iff, image_univ] @@ -433,7 +435,7 @@ theorem ArzelaAscoli.compactSpace_of_closed_inducing' [TopologicalSpace ι] { rw [← forall_sUnion] at F_pointwiseCompact choose! Q Q_compact F_in_Q using F_pointwiseCompact -- Notice that, since the range of `F` is closed in `X →ᵤ[𝔖] α`, equicontinuity ensures that - -- the range of `(⋃₀ 𝔖).restrict ∘ F` is still closed in the product topology. + -- the range of `(⋃₀ 𝔖).domRestrict ∘ F` is still closed in the product topology. -- But it's contained in the product of the `Q x`s, which is compact by Tykhonov, hence -- it is compact as well. refine IsCompact.of_isClosed_subset (isCompact_univ_pi fun x ↦ Q_compact x x.2) @@ -480,7 +482,7 @@ theorem ArzelaAscoli.isCompact_closure_of_isClosedEmbedding [TopologicalSpace ι have : ∀ K ∈ 𝔖, ∀ x ∈ K, Continuous (eval x ∘ F) := fun K hK x hx ↦ UniformOnFun.uniformContinuous_eval_of_mem _ _ hx hK |>.continuous.comp F_clemb.continuous have cls_eqcont : ∀ K ∈ 𝔖, EquicontinuousOn (F ∘ ((↑) : closure s → ι)) K := - fun K hK ↦ (s_eqcont K hK).closure' <| show Continuous (K.restrict ∘ F) from + fun K hK ↦ (s_eqcont K hK).closure' <| show Continuous (K.domRestrict ∘ F) from continuous_pi fun ⟨x, hx⟩ ↦ this K hK x hx have cls_pointwiseCompact : ∀ K ∈ 𝔖, ∀ x ∈ K, ∃ Q, IsCompact Q ∧ closure s ⊆ {i | F i x ∈ Q} := fun K hK x hx ↦ (s_pointwiseCompact K hK x hx).imp fun Q hQ ↦ ⟨hQ.1, closure_minimal hQ.2 <| diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index ee911231c8d03d..06107840d37d0c 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -680,7 +680,7 @@ theorem UniformContinuous.subtype_map [UniformSpace α] [UniformSpace β] {p : (hf.comp uniformContinuous_subtype_val).subtype_mk _ theorem uniformContinuousOn_iff_restrict [UniformSpace α] [UniformSpace β] {f : α → β} {s : Set α} : - UniformContinuousOn f s ↔ UniformContinuous (s.restrict f) := by + UniformContinuousOn f s ↔ UniformContinuous (s.domRestrict f) := by delta UniformContinuousOn UniformContinuous rw [← map_uniformity_set_coe, tendsto_map'_iff]; rfl @@ -697,7 +697,7 @@ theorem tendsto_of_uniformContinuous_subtype [UniformSpace α] [UniformSpace β] theorem UniformContinuousOn.continuousOn [UniformSpace α] [UniformSpace β] {f : α → β} {s : Set α} (h : UniformContinuousOn f s) : ContinuousOn f s := by rw [uniformContinuousOn_iff_restrict] at h - rw [continuousOn_iff_continuous_restrict] + rw [continuousOn_iff_continuous_domRestrict] exact h.continuous instance [UniformSpace α] [(𝓤 α).IsCountablyGenerated] (s : Set α) : (𝓤 s).IsCountablyGenerated := diff --git a/Mathlib/Topology/UniformSpace/Cauchy.lean b/Mathlib/Topology/UniformSpace/Cauchy.lean index 8be9eee003328f..e32c38af6b5a53 100644 --- a/Mathlib/Topology/UniformSpace/Cauchy.lean +++ b/Mathlib/Topology/UniformSpace/Cauchy.lean @@ -176,7 +176,7 @@ lemma Cauchy.map_of_le [UniformSpace β] {f : Filter α} {m : α → β} (hf : C (hm : UniformContinuousOn m s) (hfs : f ≤ 𝓟 s) : Cauchy (map m f) := by suffices Cauchy (comap (Subtype.val : s → α) f) by - simpa [Set.restrict_def, ← Function.comp_def, ← map_map, + simpa [Set.domRestrict_def, ← Function.comp_def, ← map_map, subtype_coe_map_comap, inf_eq_left.mpr hfs] using this.map hm.restrict exact hf.comap' (fun _ x ↦ x) (comap_coe_neBot_of_le_principal (h := hf.1) hfs) diff --git a/Mathlib/Topology/UniformSpace/CompactConvergence.lean b/Mathlib/Topology/UniformSpace/CompactConvergence.lean index 543d6e60b52fb3..37a4ec960de3a4 100644 --- a/Mathlib/Topology/UniformSpace/CompactConvergence.lean +++ b/Mathlib/Topology/UniformSpace/CompactConvergence.lean @@ -347,26 +347,34 @@ section ContinuousOnRestrict /-- Given functions `F i, f` which are continuous on a compact set `s`, `F` tends to `f` uniformly on `s` if and only if the restrictions (as elements of `C(s, β)`) converge. -/ -theorem _root_.ContinuousOn.tendsto_restrict_iff_tendstoUniformlyOn {s : Set α} [CompactSpace s] +theorem _root_.ContinuousOn.tendsto_domRestrict_iff_tendstoUniformlyOn {s : Set α} [CompactSpace s] {f : α → β} (hf : ContinuousOn f s) {ι : Type*} {p : Filter ι} {F : ι → α → β} (hF : ∀ i, ContinuousOn (F i) s) : - Tendsto (fun i ↦ ⟨_, (hF i).restrict⟩ : ι → C(s, β)) p (𝓝 ⟨_, hf.restrict⟩) ↔ + Tendsto (fun i ↦ ⟨_, (hF i).domRestrict⟩ : ι → C(s, β)) p (𝓝 ⟨_, hf.domRestrict⟩) ↔ TendstoUniformlyOn F f p s := by rw [ContinuousMap.tendsto_iff_tendstoUniformly, tendstoUniformlyOn_iff_tendstoUniformly_comp_coe] congr! +@[deprecated (since := "2026-07-19")] +alias _root_.ContinuousOn.tendsto_restrict_iff_tendstoUniformlyOn := + _root_.ContinuousOn.tendsto_domRestrict_iff_tendstoUniformlyOn + open UniformOnFun in /-- A family `f : X → α → β`, each of which is continuous on a compact set `s : Set α` is continuous in the topology `X → α →ᵤ[{s}] β` if and only if the family of continuous restrictions `X → C(s, β)` is continuous. -/ -theorem _root_.ContinuousOn.continuous_restrict_iff_continuous_uniformOnFun +theorem _root_.ContinuousOn.continuous_domRestrict_iff_continuous_uniformOnFun {X : Type*} [TopologicalSpace X] {f : X → α → β} {s : Set α} (hf : ∀ x, ContinuousOn (f x) s) [CompactSpace s] : - Continuous (fun x ↦ ⟨_, (hf x).restrict⟩ : X → C(s, β)) ↔ + Continuous (fun x ↦ ⟨_, (hf x).domRestrict⟩ : X → C(s, β)) ↔ Continuous (fun x ↦ ofFun {s} (f x)) := by rw [ContinuousMap.continuous_iff_continuous_uniformFun, UniformOnFun.continuous_rng_iff] simp [Function.comp_def] +@[deprecated (since := "2026-07-19")] +alias _root_.ContinuousOn.continuous_restrict_iff_continuous_uniformOnFun := + _root_.ContinuousOn.continuous_domRestrict_iff_continuous_uniformOnFun + end ContinuousOnRestrict theorem uniformSpace_eq_inf_precomp_of_cover {δ₁ δ₂ : Type*} [TopologicalSpace δ₁] diff --git a/Mathlib/Topology/UniformSpace/Dini.lean b/Mathlib/Topology/UniformSpace/Dini.lean index cd6fd6672de1b0..c5fc86b1ab616e 100644 --- a/Mathlib/Topology/UniformSpace/Dini.lean +++ b/Mathlib/Topology/UniformSpace/Dini.lean @@ -77,8 +77,8 @@ lemma tendstoLocallyUniformlyOn_of_forall_tendsto {s : Set α} (hf : ContinuousOn f s) (h_tendsto : ∀ x ∈ s, Tendsto (F · x) atTop (𝓝 (f x))) : TendstoLocallyUniformlyOn F f atTop s := by rw [tendstoLocallyUniformlyOn_iff_tendstoLocallyUniformly_comp_coe] - exact tendstoLocallyUniformly_of_forall_tendsto (hF_cont · |>.restrict) - (fun _ _ h x ↦ hF_mono _ x.2 h) hf.restrict (fun x ↦ h_tendsto x x.2) + exact tendstoLocallyUniformly_of_forall_tendsto (hF_cont · |>.domRestrict) + (fun _ _ h x ↦ hF_mono _ x.2 h) hf.domRestrict (fun x ↦ h_tendsto x x.2) /-- **Dini's theorem**: if `F n` is a monotone increasing collection of continuous functions on a compact space converging pointwise to a continuous function `f`, then `F n` converges uniformly to diff --git a/Mathlib/Topology/UniformSpace/Equicontinuity.lean b/Mathlib/Topology/UniformSpace/Equicontinuity.lean index c13f968f195452..047a4a4833d4d2 100644 --- a/Mathlib/Topology/UniformSpace/Equicontinuity.lean +++ b/Mathlib/Topology/UniformSpace/Equicontinuity.lean @@ -168,7 +168,7 @@ lemma EquicontinuousWithinAt.mono {F : ι → X → α} {x₀ : X} {S T : Set X} rw [EquicontinuousWithinAt, EquicontinuousAt, nhdsWithin_univ] lemma equicontinuousAt_restrict_iff (F : ι → X → α) {S : Set X} (x₀ : S) : - EquicontinuousAt (S.restrict ∘ F) x₀ ↔ EquicontinuousWithinAt F S x₀ := by + EquicontinuousAt (S.domRestrict ∘ F) x₀ ↔ EquicontinuousWithinAt F S x₀ := by simp [EquicontinuousWithinAt, EquicontinuousAt, ← eventually_nhds_subtype_iff] @@ -185,7 +185,7 @@ lemma equicontinuousOn_univ (F : ι → X → α) : simp [EquicontinuousOn, Equicontinuous] lemma equicontinuous_restrict_iff (F : ι → X → α) {S : Set X} : - Equicontinuous (S.restrict ∘ F) ↔ EquicontinuousOn F S := by + Equicontinuous (S.domRestrict ∘ F) ↔ EquicontinuousOn F S := by simp [Equicontinuous, EquicontinuousOn, equicontinuousAt_restrict_iff] lemma UniformEquicontinuous.uniformEquicontinuousOn {F : ι → β → α} (H : UniformEquicontinuous F) @@ -201,7 +201,7 @@ lemma uniformEquicontinuousOn_univ (F : ι → β → α) : simp [UniformEquicontinuousOn, UniformEquicontinuous] lemma uniformEquicontinuous_restrict_iff (F : ι → β → α) {S : Set β} : - UniformEquicontinuous (S.restrict ∘ F) ↔ UniformEquicontinuousOn F S := by + UniformEquicontinuous (S.domRestrict ∘ F) ↔ UniformEquicontinuousOn F S := by rw [UniformEquicontinuous, UniformEquicontinuousOn] conv in _ ⊓ _ => rw [← Subtype.range_val (s := S), ← range_prodMap, ← map_comap] rfl @@ -769,7 +769,7 @@ with `Set.EquicontinuousWithinAt.closure`, but we don't do it because, even with marker, it would introduce ambiguities while working in namespace `Set` (e.g, in the proof of any theorem called `Set.something`). -/ theorem EquicontinuousWithinAt.closure' {A : Set Y} {u : Y → X → α} {S : Set X} {x₀ : X} - (hA : EquicontinuousWithinAt (u ∘ (↑) : A → X → α) S x₀) (hu₁ : Continuous (S.restrict ∘ u)) + (hA : EquicontinuousWithinAt (u ∘ (↑) : A → X → α) S x₀) (hu₁ : Continuous (S.domRestrict ∘ u)) (hu₂ : Continuous (eval x₀ ∘ u)) : EquicontinuousWithinAt (u ∘ (↑) : closure A → X → α) S x₀ := by intro U hU @@ -788,7 +788,7 @@ theorem EquicontinuousAt.closure' {A : Set Y} {u : Y → X → α} {x₀ : X} (hA : EquicontinuousAt (u ∘ (↑) : A → X → α) x₀) (hu : Continuous u) : EquicontinuousAt (u ∘ (↑) : closure A → X → α) x₀ := by rw [← equicontinuousWithinAt_univ] at hA ⊢ - exact hA.closure' (Pi.continuous_restrict _ |>.comp hu) (continuous_apply x₀ |>.comp hu) + exact hA.closure' (Pi.continuous_domRestrict _ |>.comp hu) (continuous_apply x₀ |>.comp hu) /-- If a set of functions is equicontinuous at some `x₀`, its closure for the product topology is also equicontinuous at `x₀`. -/ @@ -802,7 +802,7 @@ topology of pointwise convergence on `S ∪ {x₀}`, see `Set.EquicontinuousWith protected theorem Set.EquicontinuousWithinAt.closure {A : Set (X → α)} {S : Set X} {x₀ : X} (hA : A.EquicontinuousWithinAt S x₀) : (closure A).EquicontinuousWithinAt S x₀ := - hA.closure' (u := id) (Pi.continuous_restrict _) (continuous_apply _) + hA.closure' (u := id) (Pi.continuous_domRestrict _) (continuous_apply _) /-- If a set of functions is equicontinuous, the same is true for its closure in *any* topology for which evaluation at any point is continuous. Since this will be applied to @@ -818,7 +818,7 @@ topology for which evaluation at any `x ∈ S` is continuous. Since this will be continuity conditions. See also `Set.EquicontinuousOn.closure` for a more familiar (but weaker) statement. -/ theorem EquicontinuousOn.closure' {A : Set Y} {u : Y → X → α} {S : Set X} - (hA : EquicontinuousOn (u ∘ (↑) : A → X → α) S) (hu : Continuous (S.restrict ∘ u)) : + (hA : EquicontinuousOn (u ∘ (↑) : A → X → α) S) (hu : Continuous (S.domRestrict ∘ u)) : EquicontinuousOn (u ∘ (↑) : closure A → X → α) S := fun x hx ↦ (hA x hx).closure' hu <| by exact continuous_apply ⟨x, hx⟩ |>.comp hu @@ -840,7 +840,7 @@ applied to `DFunLike` types, we state it for any topological space with a map to the right continuity conditions. See also `Set.UniformEquicontinuousOn.closure` for a more familiar (but weaker) statement. -/ theorem UniformEquicontinuousOn.closure' {A : Set Y} {u : Y → β → α} {S : Set β} - (hA : UniformEquicontinuousOn (u ∘ (↑) : A → β → α) S) (hu : Continuous (S.restrict ∘ u)) : + (hA : UniformEquicontinuousOn (u ∘ (↑) : A → β → α) S) (hu : Continuous (S.domRestrict ∘ u)) : UniformEquicontinuousOn (u ∘ (↑) : closure A → β → α) S := by intro U hU rcases mem_uniformity_isClosed hU with ⟨V, hV, hVclosed, hVU⟩ @@ -861,7 +861,7 @@ theorem UniformEquicontinuous.closure' {A : Set Y} {u : Y → β → α} (hA : UniformEquicontinuous (u ∘ (↑) : A → β → α)) (hu : Continuous u) : UniformEquicontinuous (u ∘ (↑) : closure A → β → α) := by rw [← uniformEquicontinuousOn_univ] at hA ⊢ - exact hA.closure' (Pi.continuous_restrict _ |>.comp hu) + exact hA.closure' (Pi.continuous_domRestrict _ |>.comp hu) /-- If a set of functions is uniformly equicontinuous, its closure for the product topology is also uniformly equicontinuous. -/ @@ -874,7 +874,7 @@ topology is also uniformly equicontinuous. This would also be true for the coars pointwise convergence on `S`, see `UniformEquicontinuousOn.closure'`. -/ protected theorem Set.UniformEquicontinuousOn.closure {A : Set <| β → α} {S : Set β} (hA : A.UniformEquicontinuousOn S) : (closure A).UniformEquicontinuousOn S := - UniformEquicontinuousOn.closure' (u := id) hA (Pi.continuous_restrict _) + UniformEquicontinuousOn.closure' (u := id) hA (Pi.continuous_domRestrict _) /- Implementation note: The following lemma (as well as all the following variations) could diff --git a/Mathlib/Topology/UniformSpace/HeineCantor.lean b/Mathlib/Topology/UniformSpace/HeineCantor.lean index 87d689964bb750..a3c9f8490f96b0 100644 --- a/Mathlib/Topology/UniformSpace/HeineCantor.lean +++ b/Mathlib/Topology/UniformSpace/HeineCantor.lean @@ -48,7 +48,7 @@ theorem IsCompact.uniformContinuousOn_of_continuous {s : Set α} {f : α → β} (hf : ContinuousOn f s) : UniformContinuousOn f s := by rw [uniformContinuousOn_iff_restrict] rw [isCompact_iff_compactSpace] at hs - rw [continuousOn_iff_continuous_restrict] at hf + rw [continuousOn_iff_continuous_domRestrict] at hf exact CompactSpace.uniformContinuous_of_continuous hf /-- If `s` is compact and `f` is continuous at all points of `s`, then `f` is diff --git a/Mathlib/Topology/UniformSpace/Pi.lean b/Mathlib/Topology/UniformSpace/Pi.lean index fc2b794a72f7b8..959a3b1aabbb93 100644 --- a/Mathlib/Topology/UniformSpace/Pi.lean +++ b/Mathlib/Topology/UniformSpace/Pi.lean @@ -80,14 +80,14 @@ lemma Pi.uniformSpace_comap_precomp (φ : ι' → ι) : uniformSpace_comap_precomp' (fun _ ↦ β) φ lemma Pi.uniformContinuous_restrict (S : Set ι) : - UniformContinuous (S.restrict : (∀ i : ι, α i) → (∀ i : S, α i)) := + UniformContinuous (S.domRestrict : (∀ i : ι, α i) → (∀ i : S, α i)) := Pi.uniformContinuous_precomp' _ ((↑) : S → ι) lemma Pi.uniformSpace_comap_restrict (S : Set ι) : - UniformSpace.comap (S.restrict) (Pi.uniformSpace (fun i : S ↦ α i)) = + UniformSpace.comap (S.domRestrict) (Pi.uniformSpace (fun i : S ↦ α i)) = ⨅ i ∈ S, UniformSpace.comap (eval i) (U i) := by simp +unfoldPartialApp - [← iInf_subtype'', ← uniformSpace_comap_precomp' _ ((↑) : S → ι), Set.restrict] + [← iInf_subtype'', ← uniformSpace_comap_precomp' _ ((↑) : S → ι), Set.domRestrict] lemma cauchy_pi_iff [Nonempty ι] {l : Filter (∀ i, α i)} : Cauchy l ↔ ∀ i, Cauchy (map (eval i) l) := by @@ -111,8 +111,8 @@ instance Pi.complete [∀ i, CompleteSpace (α i)] : CompleteSpace (∀ i, α i) rwa [nhds_pi, le_pi] lemma Pi.uniformSpace_comap_restrict_sUnion (𝔖 : Set (Set ι)) : - UniformSpace.comap (⋃₀ 𝔖).restrict (Pi.uniformSpace (fun i : (⋃₀ 𝔖) ↦ α i)) = - ⨅ S ∈ 𝔖, UniformSpace.comap S.restrict (Pi.uniformSpace (fun i : S ↦ α i)) := by + UniformSpace.comap (⋃₀ 𝔖).domRestrict (Pi.uniformSpace (fun i : (⋃₀ 𝔖) ↦ α i)) = + ⨅ S ∈ 𝔖, UniformSpace.comap S.domRestrict (Pi.uniformSpace (fun i : S ↦ α i)) := by simp_rw [Pi.uniformSpace_comap_restrict α, iInf_sUnion] /-- An infimum of complete uniformities is complete, diff --git a/Mathlib/Topology/UniformSpace/UniformConvergence.lean b/Mathlib/Topology/UniformSpace/UniformConvergence.lean index 283de8651863b5..62a4ecaeba2d06 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergence.lean @@ -130,7 +130,7 @@ theorem tendstoUniformlyOn_iff_tendstoUniformly_comp_coe : forall₂_congr fun u _ => by simp lemma tendstoUniformlyOn_iff_restrict {K : Set α} : TendstoUniformlyOn F f p K ↔ - TendstoUniformly (fun n : ι => K.restrict (F n)) (K.restrict f) p := + TendstoUniformly (fun n : ι => K.domRestrict (F n)) (K.domRestrict f) p := tendstoUniformlyOn_iff_tendstoUniformly_comp_coe /-- A sequence of functions `Fₙ` converges uniformly to a limiting function `f` w.r.t. diff --git a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean index d94800cb2f26ef..0d4026c0018bbc 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean @@ -569,13 +569,13 @@ protected def gen (𝔖) (S : Set α) (V : Set (β × β)) : Set ((α →ᵤ[ { uv : (α →ᵤ[𝔖] β) × (α →ᵤ[𝔖] β) | ∀ x ∈ S, (toFun 𝔖 uv.1 x, toFun 𝔖 uv.2 x) ∈ V } /-- For `S : Set α` and `V : Set (β × β)`, we have -`UniformOnFun.gen 𝔖 S V = (S.restrict × S.restrict) ⁻¹' (UniformFun.gen S β V)`. +`UniformOnFun.gen 𝔖 S V = (S.domRestrict × S.domRestrict) ⁻¹' (UniformFun.gen S β V)`. This is the crucial fact for proving that the family `UniformOnFun.gen S V` for `S ∈ 𝔖` and `V ∈ 𝓤 β` is indeed a basis for the uniformity `α →ᵤ[𝔖] β` endowed with `𝒱(α, β, 𝔖, uβ)` the uniform structure of `𝔖`-convergence, as defined in `UniformOnFun.uniformSpace`. -/ protected theorem gen_eq_preimage_restrict {𝔖} (S : Set α) (V : Set (β × β)) : UniformOnFun.gen 𝔖 S V = - Prod.map (S.restrict ∘ UniformFun.toFun) (S.restrict ∘ UniformFun.toFun) ⁻¹' + Prod.map (S.domRestrict ∘ UniformFun.toFun) (S.domRestrict ∘ UniformFun.toFun) ⁻¹' UniformFun.gen S β V := by ext uv exact ⟨fun h ⟨x, hx⟩ => h x hx, fun h x hx => h ⟨x, hx⟩⟩ @@ -604,11 +604,11 @@ variable (α β) [UniformSpace β] (𝔖 : Set (Set α)) /-- Uniform structure of `𝔖`-convergence, i.e uniform convergence on the elements of `𝔖`, declared as an instance on `α →ᵤ[𝔖] β`. It is defined as the infimum, for `S ∈ 𝔖`, of the pullback -by `S.restrict`, the map of restriction to `S`, of the uniform structure `𝒰(s, β, uβ)` on +by `S.domRestrict`, the map of restriction to `S`, of the uniform structure `𝒰(s, β, uβ)` on `↥S →ᵤ β`. We will denote it `𝒱(α, β, 𝔖, uβ)`, where `uβ` is the uniform structure on `β`. -/ instance uniformSpace : UniformSpace (α →ᵤ[𝔖] β) := ⨅ (s : Set α) (_ : s ∈ 𝔖), - .comap (UniformFun.ofFun ∘ s.restrict ∘ UniformOnFun.toFun 𝔖) 𝒰(s, β, _) + .comap (UniformFun.ofFun ∘ s.domRestrict ∘ UniformOnFun.toFun 𝔖) 𝒰(s, β, _) local notation "𝒱(" α ", " β ", " 𝔖 ", " u ")" => @UniformOnFun.uniformSpace α β u 𝔖 @@ -618,19 +618,20 @@ instance topologicalSpace : TopologicalSpace (α →ᵤ[𝔖] β) := 𝒱(α, β, 𝔖, _).toTopologicalSpace /-- The topology of `𝔖`-convergence is the infimum, for `S ∈ 𝔖`, of topology induced by the map -of `S.restrict : (α →ᵤ[𝔖] β) → (↥S →ᵤ β)` of restriction to `S`, where `↥S →ᵤ β` is endowed with +of `S.domRestrict : (α →ᵤ[𝔖] β) → (↥S →ᵤ β)` of restriction to `S`, where `↥S →ᵤ β` is endowed with the topology of uniform convergence. -/ protected theorem topologicalSpace_eq : UniformOnFun.topologicalSpace α β 𝔖 = ⨅ (s : Set α) (_ : s ∈ 𝔖), TopologicalSpace.induced - (UniformFun.ofFun ∘ s.restrict ∘ toFun 𝔖) (UniformFun.topologicalSpace s β) := by + (UniformFun.ofFun ∘ s.domRestrict ∘ toFun 𝔖) (UniformFun.topologicalSpace s β) := by simp only [UniformOnFun.topologicalSpace, UniformSpace.toTopologicalSpace_iInf] rfl set_option backward.isDefEq.respectTransparency false in protected theorem hasBasis_uniformity_of_basis_aux₁ {p : ι → Prop} {s : ι → Set (β × β)} (hb : HasBasis (𝓤 β) p s) (S : Set α) : - (@uniformity (α →ᵤ[𝔖] β) ((UniformFun.uniformSpace S β).comap S.restrict)).HasBasis p fun i => + (@uniformity (α →ᵤ[𝔖] β) ((UniformFun.uniformSpace S β).comap S.domRestrict)).HasBasis p + fun i => UniformOnFun.gen 𝔖 S (s i) := by simp_rw [UniformOnFun.gen_eq_preimage_restrict, uniformity_comap] exact (UniformFun.hasBasis_uniformity_of_basis S β hb).comap _ @@ -638,7 +639,8 @@ protected theorem hasBasis_uniformity_of_basis_aux₁ {p : ι → Prop} {s : ι protected theorem hasBasis_uniformity_of_basis_aux₂ (h : DirectedOn (· ⊆ ·) 𝔖) {p : ι → Prop} {s : ι → Set (β × β)} (hb : HasBasis (𝓤 β) p s) : DirectedOn - ((fun s : Set α => (UniformFun.uniformSpace s β).comap (s.restrict : (α →ᵤ β) → s →ᵤ β)) ⁻¹'o + ((fun s : Set α => + (UniformFun.uniformSpace s β).comap (s.domRestrict : (α →ᵤ β) → s →ᵤ β)) ⁻¹'o GE.ge) 𝔖 := h.mono fun _ _ hst => @@ -733,7 +735,7 @@ protected theorem hasBasis_nhds (f : α →ᵤ[𝔖] β) (h : 𝔖.Nonempty) (h' /-- If `S ∈ 𝔖`, then the restriction to `S` is a uniformly continuous map from `α →ᵤ[𝔖] β` to `↥S →ᵤ β`. -/ protected theorem uniformContinuous_restrict (h : s ∈ 𝔖) : - UniformContinuous (UniformFun.ofFun ∘ (s.restrict : (α → β) → s → β) ∘ toFun 𝔖) := by + UniformContinuous (UniformFun.ofFun ∘ (s.domRestrict : (α → β) → s → β) ∘ toFun 𝔖) := by change _ ≤ _ simp only [map_le_iff_le_comap, iInf_uniformity] exact iInf₂_le s h @@ -767,7 +769,7 @@ protected theorem uniformity_eq_of_basis {ι : Sort*} {p : ι → Prop} {V : ι simp_rw [iInf_uniformity, uniformity_comap, (UniformFun.hasBasis_uniformity_of_basis _ _ h).eq_biInf, comap_iInf, comap_principal, Function.comp_apply, UniformFun.gen, Subtype.forall, UniformOnFun.gen, preimage_ofPred_eq, - Prod.map_fst, Prod.map_snd, Function.comp_apply, UniformFun.toFun_ofFun, restrict_apply] + Prod.map_fst, Prod.map_snd, Function.comp_apply, UniformFun.toFun_ofFun, domRestrict_apply] protected theorem uniformity_eq : 𝓤 (α →ᵤ[𝔖] β) = ⨅ s ∈ 𝔖, ⨅ V ∈ 𝓤 β, 𝓟 (UniformOnFun.gen 𝔖 s V) := UniformOnFun.uniformity_eq_of_basis _ _ (𝓤 β).basis_sets @@ -896,7 +898,7 @@ protected theorem comap_eq {f : γ → β} : -- on `iInf`. simp_rw [UniformOnFun.uniformSpace, UniformSpace.comap_iInf, UniformFun.comap_eq, ← UniformSpace.comap_comap] - -- By definition, `∀ S ∈ 𝔖, (f ∘ —) ∘ S.restrict = S.restrict ∘ (f ∘ —)`. + -- By definition, `∀ S ∈ 𝔖, (f ∘ —) ∘ S.domRestrict = S.domRestrict ∘ (f ∘ —)`. rfl /-- Post-composition by a uniformly continuous function is uniformly continuous for the @@ -979,7 +981,7 @@ theorem t2Space_of_covering [T2Space β] (h : ⋃₀ 𝔖 = univ) : T2Space (α /-- The restriction map from `α →ᵤ[𝔖] β` to `⋃₀ 𝔖 → β` is uniformly continuous. -/ theorem uniformContinuous_restrict_toFun : - UniformContinuous ((⋃₀ 𝔖).restrict ∘ toFun 𝔖 : (α →ᵤ[𝔖] β) → ⋃₀ 𝔖 → β) := by + UniformContinuous ((⋃₀ 𝔖).domRestrict ∘ toFun 𝔖 : (α →ᵤ[𝔖] β) → ⋃₀ 𝔖 → β) := by rw [uniformContinuous_pi] intro ⟨x, hx⟩ obtain ⟨s : Set α, hs : s ∈ 𝔖, hxs : x ∈ s⟩ := mem_sUnion.mpr hx @@ -990,7 +992,8 @@ theorem uniformContinuous_restrict_toFun : `α →ᵤ[𝔖] β`. -/ lemma isUniformInducing_pi_restrict : IsUniformInducing - (fun f : α →ᵤ[𝔖] β ↦ fun s : 𝔖 ↦ UniformFun.ofFun ((s : Set α).restrict (toFun 𝔖 f))) := by + (fun f : α →ᵤ[𝔖] β ↦ + fun s : 𝔖 ↦ UniformFun.ofFun ((s : Set α).domRestrict (toFun 𝔖 f))) := by simp_rw [isUniformInducing_iff_uniformSpace, Pi.uniformSpace_eq, UniformSpace.comap_iInf, ← UniformSpace.comap_comap, iInf_subtype] rfl @@ -1035,11 +1038,11 @@ protected theorem tendsto_iff_tendstoUniformlyOn {F : ι → α →ᵤ[𝔖] β} protected lemma continuous_rng_iff {X : Type*} [TopologicalSpace X] {f : X → (α →ᵤ[𝔖] β)} : Continuous f ↔ ∀ s ∈ 𝔖, - Continuous (UniformFun.ofFun ∘ s.restrict ∘ UniformOnFun.toFun 𝔖 ∘ f) := by + Continuous (UniformFun.ofFun ∘ s.domRestrict ∘ UniformOnFun.toFun 𝔖 ∘ f) := by simp only [continuous_iff_continuousAt, ContinuousAt, UniformOnFun.tendsto_iff_tendstoUniformlyOn, UniformFun.tendsto_iff_tendstoUniformly, tendstoUniformlyOn_iff_tendstoUniformly_comp_coe, @forall_comm X, - Function.comp_def, restrict_eq, UniformFun.toFun_ofFun] + Function.comp_def, domRestrict_eq, UniformFun.toFun_ofFun] instance [CompleteSpace β] : CompleteSpace (α →ᵤ[𝔖] β) := by rcases isEmpty_or_nonempty β From 970ca71b97ed15739cd2646bb2eb0f15724a8fc5 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 20 Jul 2026 03:19:32 +0000 Subject: [PATCH 0888/1300] feat(Combinatorics/SimpleGraph/Walk): relate `edges` and `darts` (#41720) --- .../SimpleGraph/Connectivity/Subgraph.lean | 34 +++---------------- .../Combinatorics/SimpleGraph/Walk/Basic.lean | 13 +++++++ .../SimpleGraph/Walk/Traversal.lean | 8 +++++ 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean index 63f934c130fcba..9278d2676c0496 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean @@ -281,42 +281,18 @@ theorem toSubgraph_adj_penultimate {u v} (w : G.Walk u v) (h : ¬ w.Nil) : simpa [show w.length - 1 + 1 = w.length by lia] using w.toSubgraph_adj_getVert (by lia : w.length - 1 < w.length) +lemma adj_toSubgraph_iff_mem_edges {u v u' v' : V} {p : G.Walk u v} : + p.toSubgraph.Adj u' v' ↔ s(u', v') ∈ p.edges := by + rw [← mem_edges_toSubgraph, Subgraph.mem_edgeSet] + theorem toSubgraph_adj_iff {u v u' v'} (w : G.Walk u v) : w.toSubgraph.Adj u' v' ↔ ∃ i, s(w.getVert i, w.getVert (i + 1)) = s(u', v') ∧ i < w.length := by - constructor - · intro hadj - unfold Walk.toSubgraph at hadj - match w with - | .nil => - simp only [singletonSubgraph_adj, Pi.bot_apply, Prop.bot_eq_false] at hadj - | .cons h p => - simp only [Subgraph.sup_adj, subgraphOfAdj_adj, Sym2.eq, Sym2.rel_iff', Prod.mk.injEq, - Prod.swap_prod_mk] at hadj - cases hadj with - | inl hl => - use 0 - simp only [Walk.getVert_zero, zero_add, getVert_cons_succ] - refine ⟨?_, by simp only [length_cons, Nat.zero_lt_succ]⟩ - exact Sym2.eq_iff.mpr hl - | inr hr => - obtain ⟨i, hi⟩ := (toSubgraph_adj_iff _).mp hr - use i + 1 - simp only [getVert_cons_succ] - constructor - · exact hi.1 - · simp only [Walk.length_cons, Nat.add_lt_add_right hi.2 1] - · rintro ⟨i, hi⟩ - rw [← Subgraph.mem_edgeSet, ← hi.1, Subgraph.mem_edgeSet] - exact toSubgraph_adj_getVert _ hi.2 + grind [adj_toSubgraph_iff_mem_edges, mk_mem_edges_iff_exists] lemma mem_support_of_adj_toSubgraph {u v u' v' : V} {p : G.Walk u v} (hp : p.toSubgraph.Adj u' v') : u' ∈ p.support := p.mem_verts_toSubgraph.mp (p.toSubgraph.edge_vert hp) -lemma adj_toSubgraph_iff_mem_edges {u v u' v' : V} {p : G.Walk u v} : - p.toSubgraph.Adj u' v' ↔ s(u', v') ∈ p.edges := by - rw [← p.mem_edges_toSubgraph, Subgraph.mem_edgeSet] - theorem toSubgraph_le_iff {w : G.Walk u v} (hnil : ¬w.Nil) {G' : G.Subgraph} : w.toSubgraph ≤ G' ↔ w.edgeSet ⊆ G'.edgeSet := by refine ⟨fun hw e he ↦ Subgraph.edgeSet_mono hw <| w.mem_edges_toSubgraph.mpr he, fun hw ↦ ?_⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean index bf05e097bb608e..c52c900a859119 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean @@ -125,6 +125,9 @@ def darts {u v : V} : G.Walk u v → List G.Dart This is defined to be the list of edges underlying `SimpleGraph.Walk.darts`. -/ def edges {u v : V} (p : G.Walk u v) : List (Sym2 V) := p.darts.map Dart.edge +theorem edges_eq_map_darts (p : G.Walk u v) : p.edges = p.darts.map Dart.edge := + rfl + @[simp] theorem support_nil {u : V} : (nil : G.Walk u u).support = [u] := rfl @@ -253,6 +256,16 @@ theorem length_darts {u v : V} (p : G.Walk u v) : p.darts.length = p.length := b @[simp, grind =] theorem length_edges {u v : V} (p : G.Walk u v) : p.edges.length = p.length := by simp [edges] +/-- Use `edge_getElem_darts` to rewrite in the reverse direction. -/ +theorem getElem_edges_eq_edge_getElem_darts {p : G.Walk u v} {i : ℕ} (h : i < p.edges.length) : + p.edges[i] = (p.darts[i]'(by grind)).edge := + List.getElem_map .. + +/-- Use `getElem_edges_eq_edge_getElem_darts` to rewrite in the reverse direction. -/ +theorem edge_getElem_darts {p : G.Walk u v} {i : ℕ} (h : i < p.darts.length) : + p.darts[i].edge = p.edges[i]'(by grind) := by + rw [getElem_edges_eq_edge_getElem_darts] + @[simp] theorem fst_darts_getElem {p : G.Walk u v} {i : ℕ} (hi : i < p.darts.length) : p.darts[i].fst = p.support.dropLast[i]'(by grind) := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean index 74a26d858848b9..1580d0c9dca043 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean @@ -129,6 +129,14 @@ theorem darts_getElem_eq_getVert {u v : V} {p : G.Walk u v} (n : ℕ) (h : n < p rw [p.length_darts] at h ext <;> simp [p.getVert_eq_support_getElem (le_of_lt h), p.getVert_eq_support_getElem h] +theorem getElem_edges {p : G.Walk u v} {i : ℕ} (h : i < p.edges.length) : + p.edges[i] = s(p.getVert i, p.getVert (i + 1)) := by + simp [getElem_edges_eq_edge_getElem_darts, darts_getElem_eq_getVert] + +theorem mk_mem_edges_iff_exists {u' v' : V} (p : G.Walk u v) : + s(u', v') ∈ p.edges ↔ ∃ i < p.length, s(p.getVert i, p.getVert (i + 1)) = s(u', v') := by + constructor <;> grind [getElem_edges, List.mem_iff_getElem] + theorem adj_of_infix_support {u v u' v'} {p : G.Walk u v} (h : [u', v'] <:+: p.support) : G.Adj u' v' := by have ⟨k, hk, h⟩ := List.infix_iff_getElem?.mp h From b9a117e2e3e3a0443ee381bd514bcbff36b51950 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 20 Jul 2026 03:19:34 +0000 Subject: [PATCH 0889/1300] chore(Combinatorics/SimpleGraph/Finite): fix `Fintype` instances in `edgeFinset_inf` (#41789) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike `edgeFinset_sup`, `edgeFinset_inf` only accepts `Fintype` instances for `G` and `H` and not their inf, relying on the [`fintypeEdgeSetInf`](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Combinatorics/SimpleGraph/Basic.html#SimpleGraph.fintypeEdgeSetInf) instance providing it. This means the theorem can't be used with a different `Fintype (G₁ ⊓ G₂).edgeSet`. --- Mathlib/Combinatorics/SimpleGraph/Finite.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index e8b42995533a41..570439f204882e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -99,7 +99,8 @@ theorem edgeFinset_sup [Fintype (edgeSet (G₁ ⊔ G₂))] [DecidableEq V] : (G₁ ⊔ G₂).edgeFinset = G₁.edgeFinset ∪ G₂.edgeFinset := by simp [edgeFinset] @[simp] -theorem edgeFinset_inf [DecidableEq V] : (G₁ ⊓ G₂).edgeFinset = G₁.edgeFinset ∩ G₂.edgeFinset := by +theorem edgeFinset_inf [Fintype (G₁ ⊓ G₂).edgeSet] [DecidableEq V] : + (G₁ ⊓ G₂).edgeFinset = G₁.edgeFinset ∩ G₂.edgeFinset := by simp [edgeFinset] @[simp] From b300f2cccef44f3a31377e8dccfe366fa956902c Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 20 Jul 2026 03:19:36 +0000 Subject: [PATCH 0890/1300] feat(Combinatorics/SimpleGraph/Basic): `Disjoint` for graph sets (#41795) --- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 31 ++++++++++++++++++- Mathlib/Combinatorics/SimpleGraph/Finite.lean | 10 +++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index f0d556b1218da8..c2b8107c55eb08 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -13,6 +13,8 @@ public import Mathlib.Data.Sym.Sym2 public import Mathlib.Order.CompleteBooleanAlgebra public import Mathlib.Tactic.CrossRefAttribute +import Mathlib.Data.Set.Lattice + /-! # Simple graphs @@ -155,7 +157,7 @@ def completeBipartiteGraph (V W : Type*) : SimpleGraph (V ⊕ W) where namespace SimpleGraph -variable {ι : Sort*} {V : Type u} (G : SimpleGraph V) {a b c u v w : V} {e : Sym2 V} +variable {ι : Sort*} {V : Type u} (G H : SimpleGraph V) {a b c u v w : V} {e : Sym2 V} @[simp] protected theorem irrefl {v : V} : ¬G.Adj v v := @@ -553,6 +555,11 @@ variable {G G₁ G₂} @[simp] lemma disjoint_edgeSet : Disjoint G₁.edgeSet G₂.edgeSet ↔ Disjoint G₁ G₂ := by rw [Set.disjoint_iff, disjoint_iff_inf_le, ← edgeSet_inf, ← edgeSet_bot, OrderEmbedding.le_iff_le] +theorem disjoint_of_disjoint_support (h : Disjoint G.support H.support) : Disjoint G H := by + simp_rw [Set.disjoint_left, mem_support] at h + rw [← disjoint_edgeSet, Set.disjoint_left, Sym2.forall] + grind [mem_edgeSet] + @[simp] lemma edgeSet_eq_empty : G.edgeSet = ∅ ↔ G = ⊥ := by rw [← edgeSet_bot, edgeSet_inj] @[simp] lemma edgeSet_nonempty : G.edgeSet.Nonempty ↔ G ≠ ⊥ := by @@ -755,6 +762,17 @@ theorem mk'_mem_incidenceSet_right_iff : s(a, b) ∈ G.incidenceSet b ↔ G.Adj theorem edge_mem_incidenceSet_iff {e : G.edgeSet} : ↑e ∈ G.incidenceSet a ↔ a ∈ (e : Sym2 V) := and_iff_right e.2 +theorem iUnion_incidenceSet : ⋃ v, G.incidenceSet v = G.edgeSet := by + ext ⟨_, _⟩ + simp [mk'_mem_incidenceSet_iff] + +variable {G H} in +theorem disjoint_incidenceSet : + (∀ v, Disjoint (G.incidenceSet v) (H.incidenceSet v)) ↔ Disjoint G H := by + simp_rw [← disjoint_edgeSet, ← iUnion_incidenceSet, Set.disjoint_iUnion_left, + Set.disjoint_iUnion_right, Set.disjoint_left, Sym2.forall] + grind [mk'_mem_incidenceSet_iff] + theorem incidenceSet_inter_incidenceSet_subset (h : a ≠ b) : G.incidenceSet a ∩ G.incidenceSet b ⊆ {s(a, b)} := fun _e he => (Sym2.mem_and_mem_iff h).1 ⟨he.1.2, he.2.2⟩ @@ -798,6 +816,11 @@ variable (v) in theorem neighborSet_ne_univ : G.neighborSet v ≠ .univ := Set.ne_univ_iff_exists_notMem _ |>.mpr ⟨v, G.notMem_neighborSet_self⟩ +variable {G H} in +theorem disjoint_neighborSet : + (∀ v, Disjoint (G.neighborSet v) (H.neighborSet v)) ↔ Disjoint G H := by + simp_rw [← disjoint_edgeSet, Set.disjoint_left, mem_neighborSet, Sym2.forall, mem_edgeSet] + @[simp] theorem mem_incidenceSet (v w : V) : s(v, w) ∈ G.incidenceSet v ↔ G.Adj v w := by simp [incidenceSet] @@ -890,6 +913,12 @@ instance decidableMemCommonNeighbors [DecidableRel G.Adj] (v w : V) : DecidablePred (· ∈ G.commonNeighbors v w) := inferInstanceAs <| DecidablePred fun u => u ∈ G.neighborSet v ∧ u ∈ G.neighborSet w +variable {G H} in +theorem disjoint_commonNeighbors : + (∀ u v, Disjoint (G.commonNeighbors u v) (H.commonNeighbors u v)) ↔ Disjoint G H := by + simp_rw [← disjoint_edgeSet, Set.disjoint_left, mem_commonNeighbors, Sym2.forall, mem_edgeSet] + grind + theorem commonNeighbors_top_eq {v w : V} : (⊤ : SimpleGraph V).commonNeighbors v w = Set.univ \ {v, w} := by ext u diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index 570439f204882e..7f557583f56e0a 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -47,7 +47,7 @@ open Finset Function namespace SimpleGraph -variable {V : Type*} (G : SimpleGraph V) {e : Sym2 V} +variable {V : Type*} (G H : SimpleGraph V) {e : Sym2 V} section EdgeFinset @@ -197,6 +197,10 @@ protected alias ⟨IsIsolated.of_neighborFinset_eq_empty, IsIsolated.neighborFin attribute [simp] IsIsolated.neighborFinset_eq_empty +theorem disjoint_neighborFinset_of_disjoint [Fintype <| H.neighborSet v] (h : Disjoint G H) : + Disjoint (G.neighborFinset v) (H.neighborFinset v) := by + simp [← Finset.disjoint_coe, disjoint_neighborSet.mpr h v] + /-- `G.degree v` is the number of vertices adjacent to `v`. -/ def degree : ℕ := #(G.neighborFinset v) @@ -289,6 +293,10 @@ theorem incidenceFinset_subset [DecidableEq V] [Fintype G.edgeSet] : G.incidenceFinset v ⊆ G.edgeFinset := Set.toFinset_subset_toFinset.mpr (G.incidenceSet_subset v) +theorem disjoint_incidenceFinset_of_disjoint [DecidableEq V] [Fintype <| H.neighborSet v] + (h : Disjoint G H) : Disjoint (G.incidenceFinset v) (H.incidenceFinset v) := by + simp [← Finset.disjoint_coe, disjoint_incidenceSet.mpr h v] + /-- The degree of a vertex is at most the number of edges. -/ theorem degree_le_card_edgeFinset [Fintype G.edgeSet] : G.degree v ≤ #G.edgeFinset := by From fb6b1ce3f5e96319e0b29f9badf9b969fd8a3b9c Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 20 Jul 2026 03:19:38 +0000 Subject: [PATCH 0891/1300] feat(Combinatorics/SimpleGraph): basic `Adj.toWalk` API (#41797) --- .../SimpleGraph/Connectivity/Subgraph.lean | 4 ++++ Mathlib/Combinatorics/SimpleGraph/Paths.lean | 3 +++ .../Combinatorics/SimpleGraph/Walk/Basic.lean | 19 ++++++++++++++++--- .../Combinatorics/SimpleGraph/Walk/Chord.lean | 3 +++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean index 9278d2676c0496..580506f2a193cf 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/Subgraph.lean @@ -215,6 +215,10 @@ theorem mem_edges_toSubgraph (p : G.Walk u v) {e : Sym2 V} : theorem edgeSet_toSubgraph (p : G.Walk u v) : p.toSubgraph.edgeSet = p.edgeSet := Set.ext fun _ => p.mem_edges_toSubgraph +theorem _root_.SimpleGraph.Adj.toSubgraph_toWalk (h : G.Adj u v) : + h.toWalk.toSubgraph = G.subgraphOfAdj h := by + ext <;> simp + @[simp] theorem toSubgraph_append (p : G.Walk u v) (q : G.Walk v w) : (p.append q).toSubgraph = p.toSubgraph ⊔ q.toSubgraph := by induction p <;> simp [*, sup_assoc] diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 79e6744c252548..3e6c2fba4cecab 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -211,6 +211,9 @@ theorem IsPath.nil_iff_eq {u v : V} {p : G.Walk u v} (hp : p.IsPath) : p.Nil ↔ rintro rfl exact isPath_iff_nil.mp hp +theorem _root_.SimpleGraph.Adj.isPath_toWalk (h : G.Adj u v) : h.toWalk.IsPath := by + simp [h.ne] + theorem IsPath.reverse {u v : V} {p : G.Walk u v} (h : p.IsPath) : p.reverse.IsPath := by simpa [isPath_def] using h diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean index c52c900a859119..60a1eac384d4d0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean @@ -95,6 +95,9 @@ theorem length_nil {u : V} : (nil : G.Walk u u).length = 0 := rfl theorem length_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) : (cons h p).length = p.length + 1 := rfl +theorem _root_.SimpleGraph.Adj.length_toWalk (h : G.Adj u v) : h.toWalk.length = 1 := by + simp + theorem eq_of_length_eq_zero {u v : V} : ∀ {p : G.Walk u v}, p.length = 0 → u = v | nil, _ => rfl @@ -135,6 +138,9 @@ theorem support_nil {u : V} : (nil : G.Walk u u).support = [u] := rfl theorem support_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) : (cons h p).support = u :: p.support := rfl +theorem _root_.SimpleGraph.Adj.support_toWalk (h : G.Adj u v) : h.toWalk.support = [u, v] := + rfl + @[simp] theorem support_ne_nil {u v : V} (p : G.Walk u v) : p.support ≠ [] := by cases p <;> simp @@ -225,6 +231,9 @@ theorem darts_nil {u : V} : (nil : G.Walk u u).darts = [] := rfl theorem darts_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) : (cons h p).darts = ⟨(u, v), h⟩ :: p.darts := rfl +theorem _root_.SimpleGraph.Adj.darts_toWalk (h : G.Adj u v) : h.toWalk.darts = [⟨(u, v), h⟩] := + rfl + theorem cons_map_snd_darts {u v : V} (p : G.Walk u v) : (u :: p.darts.map (·.snd)) = p.support := by induction p <;> simp [*] @@ -245,6 +254,9 @@ theorem edges_nil {u : V} : (nil : G.Walk u u).edges = [] := rfl theorem edges_cons {u v w : V} (h : G.Adj u v) (p : G.Walk v w) : (cons h p).edges = s(u, v) :: p.edges := rfl +theorem _root_.SimpleGraph.Adj.edges_toWalk (h : G.Adj u v) : h.toWalk.edges = [s(u, v)] := + rfl + @[simp, grind =] theorem length_support {u v : V} (p : G.Walk u v) : p.support.length = p.length + 1 := by induction p <;> simp [*] @@ -499,10 +511,11 @@ def ofDarts (l : List G.Dart) (hne : l ≠ []) (hchain : l.IsChain G.DartAdj) : | d₁ :: d₂ :: l => .cons (hchain.rel ▸ d₁.adj) <| ofDarts (d₂ :: l) (l.cons_ne_nil d₂) hchain.of_cons -variable (G) in @[simp] -theorem ofDarts_singleton (d : G.Dart) : - ofDarts [d] ([].cons_ne_nil d) (.singleton d) = .cons d.adj .nil := +theorem ofDarts_singleton (d : G.Dart) : ofDarts [d] (by simp) (by simp) = .cons d.adj .nil := + rfl + +theorem ofDarts_singleton' (d : G.Dart) : ofDarts [d] (by simp) (by simp) = d.adj.toWalk := rfl @[simp] diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Chord.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Chord.lean index a4e77ed007da16..03633a5d10df42 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Chord.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Chord.lean @@ -54,5 +54,8 @@ theorem IsChordless.mem_edges {p : G.Walk u v} (h : p.IsChordless) {u' v' : V} (hu' : u' ∈ p.support) (hv' : v' ∈ p.support) (hadj : G.Adj u' v') : s(u', v') ∈ p.edges := isChordless_iff_forall_mem_edges.mp h hu' hv' hadj +theorem _root_.SimpleGraph.Adj.isChordless_toWalk (h : G.Adj u v) : h.toWalk.IsChordless := by + grind [isChordless_iff_forall_mem_edges, h.support_toWalk, h.edges_toWalk, Adj.ne] + end Walk end SimpleGraph From 888e057fda8ac936fe2f6514937c5b78cb9c3d87 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 20 Jul 2026 03:37:06 +0000 Subject: [PATCH 0892/1300] feat: `Commute` and `IsCoprime` are `Std.Symm` (#41612) --- Mathlib/Algebra/Group/Commute/Defs.lean | 4 ++++ Mathlib/RingTheory/Coprime/Basic.lean | 3 +++ 2 files changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Group/Commute/Defs.lean b/Mathlib/Algebra/Group/Commute/Defs.lean index 6f2ce3d81994b2..94867aebf3fbc5 100644 --- a/Mathlib/Algebra/Group/Commute/Defs.lean +++ b/Mathlib/Algebra/Group/Commute/Defs.lean @@ -76,6 +76,10 @@ protected theorem symm_iff {a b : S} : Commute a b ↔ Commute b a := instance : @Std.Refl S Commute := ⟨Commute.refl⟩ +@[to_additive] +instance : @Std.Symm S Commute where + symm _ _ := .symm + -- This instance is useful for `Finset.noncommProd` @[to_additive] instance on_refl {f : G → S} : Std.Refl fun a b => Commute (f a) (f b) := diff --git a/Mathlib/RingTheory/Coprime/Basic.lean b/Mathlib/RingTheory/Coprime/Basic.lean index 2b88d64f35a22c..f1db8a4060789e 100644 --- a/Mathlib/RingTheory/Coprime/Basic.lean +++ b/Mathlib/RingTheory/Coprime/Basic.lean @@ -55,6 +55,9 @@ theorem IsCoprime.symm (H : IsCoprime x y) : IsCoprime y x := theorem isCoprime_comm : IsCoprime x y ↔ IsCoprime y x := ⟨IsCoprime.symm, IsCoprime.symm⟩ +instance : @Std.Symm R IsCoprime where + symm _ _ := .symm + theorem isCoprime_self : IsCoprime x x ↔ IsUnit x := ⟨fun ⟨a, b, h⟩ => .of_mul_eq_one (a + b) <| by rwa [mul_comm, add_mul], fun h => let ⟨b, hb⟩ := isUnit_iff_exists_inv'.1 h From 4b382654e5b6ee85dd23c9ab6e8add18c241ab11 Mon Sep 17 00:00:00 2001 From: danderson70-UNL <288413551+danderson70-UNL@users.noreply.github.com> Date: Mon, 20 Jul 2026 05:53:52 +0000 Subject: [PATCH 0893/1300] doc(RingTheory/MvPowerSeries/Evaluation): fix typo (#41836) --- Mathlib/RingTheory/MvPowerSeries/Evaluation.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean index f9cee4959544f9..fdbe675de82661 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean @@ -24,7 +24,7 @@ consisting of ideals. Given `φ : R →+* S`, `a : σ → S`, and `f : MvPowerSeries σ R`, `MvPowerSeries.eval₂ f φ a` is the evaluation of the multivariate power series `f` at `a`. -It `f` is (the coercion of) a polynomial, it coincides with the evaluation of that polynomial. +If `f` is (the coercion of) a polynomial, it coincides with the evaluation of that polynomial. Otherwise, it is defined by density from polynomials; its values are irrelevant unless `φ` is continuous and `a` satisfies two conditions bundled in `MvPowerSeries.HasEval a` : From c732b96d05efdb1fb84511dfdc24a8f70005ae99 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Mon, 20 Jul 2026 07:31:17 +0000 Subject: [PATCH 0894/1300] chore(Geometry/Euclidean/Sphere): drop unneeded distinctness hypothesis (#41582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR removes the `p₁ ≠ p₂` hypothesis from `Sphere.center_mem_affineSpan_pair_iff_isDiameter`: the iff also holds when the points coincide (both sides then say `p₁ = s.center`), and the neighbouring `isDiameter_iff_*` lemmas carry no distinctness hypotheses. The degenerate case is handled by a one-line `simp`. Follow-up to [#41143 (feat(Geometry/Euclidean/Sphere): lemmas about points on a sphere)](https://github.com/leanprover-community/mathlib4/pull/41143). 🤖 Prepared with Claude Code --- Mathlib/Geometry/Euclidean/Sphere/Basic.lean | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean index a817ccaf313279..570fe9d18aa88a 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean @@ -605,16 +605,17 @@ lemma isDiameter_iff_mem_and_mem_and_wbtw : rw [mem_sphere.1 h₁, mem_sphere'.1 h₂, ← two_mul, eq_comm] at hd exact isDiameter_iff_mem_and_mem_and_dist.2 ⟨h₁, h₂, hd⟩ -/-- The center lies on the line through two distinct points of a sphere if and only if those +/-- The center lies on the line through two points of a sphere if and only if those points are the endpoints of a diameter. -/ -theorem center_mem_affineSpan_pair_iff_isDiameter - (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (hp₁p₂ : p₁ ≠ p₂) : +theorem center_mem_affineSpan_pair_iff_isDiameter (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) : s.center ∈ line[ℝ, p₁, p₂] ↔ s.IsDiameter p₁ p₂ := by - rw [isDiameter_iff_mem_and_mem_and_wbtw] - refine ⟨fun h => ⟨hp₁, hp₂, ?_⟩, fun h => h.2.2.mem_affineSpan⟩ - refine wbtw_of_collinear_of_dist_center_le_radius ?_ hp₁ ?_ hp₂ hp₁p₂ - · rw [Set.insert_comm]; exact collinear_insert_of_mem_affineSpan_pair h - · simpa using radius_nonneg_of_mem hp₁ + rcases eq_or_ne p₁ p₂ with rfl | hp₁p₂ + · simp [isDiameter_iff_left_mem_and_midpoint_eq_center, hp₁, eq_comm] + · rw [isDiameter_iff_mem_and_mem_and_wbtw] + refine ⟨fun h => ⟨hp₁, hp₂, ?_⟩, fun h => h.2.2.mem_affineSpan⟩ + refine wbtw_of_collinear_of_dist_center_le_radius ?_ hp₁ ?_ hp₂ hp₁p₂ + · rw [Set.insert_comm]; exact collinear_insert_of_mem_affineSpan_pair h + · simpa using radius_nonneg_of_mem hp₁ end Sphere From 25b5fe90757b65d5d4e5edcd863a8293f34710ae Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Mon, 20 Jul 2026 10:02:34 +0000 Subject: [PATCH 0895/1300] fix: add an adaptation note as a followup to the 4.33.0-rc1 bump (#41837) Add an adaptation note to `set_option` for `rightUnitor_inv_left_snd` to mark that the option is required to avoid changing auto-generated lemma signatures. This is important so that a (future follow-up to) `scripts/rm_set_option.py` doesn't automatically delete it, otherwise it would break the build for that CI workflow. See [this Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/4.2E33.2E0-rc1.20Multiple.20.60respectTransparency.60-related.20issues/near/611153200). --- Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean index 1ce1ae1ce8b305..1d995fe3a4337d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean @@ -162,6 +162,8 @@ lemma rightUnitor_inv_left_fst (Y : Over X) : (ρ_ Y).inv.left ≫ pullback.fst _ (𝟙 X) = 𝟙 _ := limit.lift_π _ _ +#adaptation_note +/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma rightUnitor_inv_left_snd (Y : Over X) : From 4cb03f453732be00b43b623661457188c10c1149 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:05:39 +0000 Subject: [PATCH 0896/1300] style: fix spacing around left arrows (#41937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regex search ←\w. Replace `rw [←a, ...]` with `rw [← a, ...]` etc. I check the replacements in tactic file are unproblematic Co-authored-by: Batixx --- Cache/Main.lean | 2 +- Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean | 2 +- Mathlib/NumberTheory/SelbergSieve.lean | 4 ++-- Mathlib/Tactic/CategoryTheory/Slice.lean | 2 +- Mathlib/Tactic/NormNum/Basic.lean | 2 +- Mathlib/Tactic/NormNum/Eq.lean | 2 +- Mathlib/Tactic/Ring/Common.lean | 2 +- Mathlib/Topology/Sets/Opens.lean | 4 ++-- MathlibTest/Algebra/Polynomial.lean | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cache/Main.lean b/Cache/Main.lean index dcce94de04f8fd..8a721d6c500554 100644 --- a/Cache/Main.lean +++ b/Cache/Main.lean @@ -256,7 +256,7 @@ def main (args : List String) : IO Unit := do unstageFiles stagingDir?.get! overwrite let putStaged (stagingDir : FilePath) := do let repo := repo?.getD MATHLIBREPO - if !(←stagingDir.isDir) then IO.println "--staging-dir must be a directory" return + if !(← stagingDir.isDir) then IO.println "--staging-dir must be a directory" return else let fileSet ← getFilesWithExtension stagingDir "ltar" let auth ← getUploadAuth diff --git a/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean b/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean index 7a830cde3f2de0..506bc6c0e52653 100644 --- a/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean +++ b/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean @@ -343,7 +343,7 @@ theorem MeromorphicAt.meromorphicTrailingCoeffAt_sub_eq_sub {f₁ f₂ : 𝕜 rw [sub_eq_add_neg, hf₁.meromorphicTrailingCoeffAt_add_eq_add (by fun_prop)] · rw [meromorphicTrailingCoeffAt_neg, sub_eq_add_neg] · rwa [← meromorphicOrderAt_neg] - · rwa [meromorphicTrailingCoeffAt_neg, ←sub_eq_add_neg] + · rwa [meromorphicTrailingCoeffAt_neg, ← sub_eq_add_neg] /-- If `f₁` and `f₂` have equal order at `x` and if their trailing coefficients do not cancel, then the diff --git a/Mathlib/NumberTheory/SelbergSieve.lean b/Mathlib/NumberTheory/SelbergSieve.lean index af6311cc74e0c1..7a855ecf194573 100644 --- a/Mathlib/NumberTheory/SelbergSieve.lean +++ b/Mathlib/NumberTheory/SelbergSieve.lean @@ -244,7 +244,7 @@ private theorem sum_divisors_lambda_sq_larger_sum (f : ℕ → ℕ → ℕ → congr! 1 with d hd rw [mem_divisors] at hd suffices ∀ d1 d2, (d1 ∣ d ∧ d2 ∣ d ∧ d = d1.lcm d2) = (d = d1.lcm d2) by - simp_rw [←Nat.divisors_filter_dvd_of_dvd hd.2 hd.1, sum_filter, ite_sum_zero, ← ite_and, this] + simp_rw [← Nat.divisors_filter_dvd_of_dvd hd.2 hd.1, sum_filter, ite_sum_zero, ← ite_and, this] simp +contextual [← and_assoc, Nat.dvd_lcm_left, Nat.dvd_lcm_right] theorem upperMoebius_lambdaSquared (weights : ℕ → ℝ) (hw : weights 1 = 1) : @@ -312,7 +312,7 @@ theorem inv_selbergTerms_eq_sum_divisors_moebius_nu {l : ℕ} (hl : Squarefree l theorem nu_inv_eq_sum_divisors_inv_selbergTerms {d : ℕ} (hdP : d ∣ s.prodPrimes) : (s.nu d)⁻¹ = ∑ l ∈ divisors s.prodPrimes, if l ∣ d then (s.selbergTerms l)⁻¹ else 0 := by - rw [eq_comm, ←sum_filter, Nat.divisors_filter_dvd_of_dvd prodPrimes_ne_zero hdP] + rw [eq_comm, ← sum_filter, Nat.divisors_filter_dvd_of_dvd prodPrimes_ne_zero hdP] have hd_pos : 0 < d := Nat.pos_of_ne_zero <| ne_zero_of_dvd_ne_zero prodPrimes_ne_zero hdP revert hdP; revert d apply (ArithmeticFunction.sum_eq_iff_sum_mul_moebius_eq_on _ (fun _ _ ↦ Nat.dvd_trans)).mpr diff --git a/Mathlib/Tactic/CategoryTheory/Slice.lean b/Mathlib/Tactic/CategoryTheory/Slice.lean index aa7a254d6e05b1..44e7887810f226 100644 --- a/Mathlib/Tactic/CategoryTheory/Slice.lean +++ b/Mathlib/Tactic/CategoryTheory/Slice.lean @@ -36,7 +36,7 @@ syntax (name := slice) "slice " num ppSpace num : conv `evalSlice` - rewrites the target expression using `Category.assoc`. - uses `congr` to split off the first `a-1` terms and rotates to `a`-th (last) term -- counts the number `k` of rewrites as it uses `←Category.assoc` to bring the target to +- counts the number `k` of rewrites as it uses `← Category.assoc` to bring the target to left associated form; from the first step this is the total number of remaining terms from `C` - it now splits off `b-a` terms from target using `congr` leaving the desired subterm - finally, it rewrites it once more using `Category.assoc` to bring it to right-associated diff --git a/Mathlib/Tactic/NormNum/Basic.lean b/Mathlib/Tactic/NormNum/Basic.lean index 75d94adc7e7ec4..93a7212043770f 100644 --- a/Mathlib/Tactic/NormNum/Basic.lean +++ b/Mathlib/Tactic/NormNum/Basic.lean @@ -529,7 +529,7 @@ def Result.mul {u : Level} {α : Q(Type u)} {a b : Q($α)} (ra : Result q($a)) ( | .isNNRat dsα .., .isNegNat rα .. | .isNegNat rα .., .isNNRat dsα .. => -- could alternatively try to combine `rα` and `dsα` here, but we'd have to do a defeq check -- so would still need to be in `MetaM`. - ratArm (←synthInstanceQ q(DivisionRing $α)) + ratArm (← synthInstanceQ q(DivisionRing $α)) | .isNNRat dsα .., _ | _, .isNNRat dsα .. => nnratArm dsα | .isNegNat rα .., _ | _, .isNegNat rα .. => intArm rα diff --git a/Mathlib/Tactic/NormNum/Eq.lean b/Mathlib/Tactic/NormNum/Eq.lean index 1e97bb3291dc1e..f4b96a1d825e3a 100644 --- a/Mathlib/Tactic/NormNum/Eq.lean +++ b/Mathlib/Tactic/NormNum/Eq.lean @@ -112,7 +112,7 @@ such that `norm_num` successfully recognises both `a` and `b`. -/ | .isNNRat dsα .., .isNegNat rα .. | .isNegNat rα .., .isNNRat dsα .. => -- could alternatively try to combine `rα` and `dsα` here, but we'd have to do a defeq check -- so would still need to be in `MetaM`. - ratArm (←synthInstanceQ q(DivisionRing $α)) + ratArm (← synthInstanceQ q(DivisionRing $α)) | .isNNRat dsα .., _ | _, .isNNRat dsα .. => nnratArm dsα | .isNegNat rα .., _ | _, .isNegNat rα .. => intArm rα | .isNat _ na pa, .isNat mα nb pb => diff --git a/Mathlib/Tactic/Ring/Common.lean b/Mathlib/Tactic/Ring/Common.lean index 996a6a91af732a..d5b432a833389a 100644 --- a/Mathlib/Tactic/Ring/Common.lean +++ b/Mathlib/Tactic/Ring/Common.lean @@ -1081,7 +1081,7 @@ theorem atom_pf (a : R) {e : ℕ} (hone : (nat_lit 1).rawCast = e) theorem atom_pf' (p : (a : R) = a') {e : ℕ} (hone : (nat_lit 1).rawCast = e) (hb : a' ^ e * (nat_lit 1).rawCast = b) : - a = b + 0 := by simp [← hone, ←hb, *] + a = b + 0 := by simp [← hone, ← hb, *] /-- Evaluates an atom, an expression where `ring` can find no additional structure. diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index cc3280cda6292b..7e789d277caf22 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -282,10 +282,10 @@ theorem mem_compl {U : Opens α} {x : α} : x ∈ Uᶜ ↔ ∃ V : Opens α, Dis simp [compl_eq_sSup_disjoint] theorem interior_compl {U : Opens α} : Opens.interior (U : Set α)ᶜ = Uᶜ := by - simp [←himp_bot, himp_def] + simp [← himp_bot, himp_def] theorem coe_compl_eq_interior_compl {U : Opens α} : ↑(Uᶜ) = interior (U : Set α)ᶜ := by - rw [←interior_compl, coe_interior] + rw [← interior_compl, coe_interior] /-- The coercion from open sets to sets as a `FrameHom`. -/ @[simps] protected def frameHom : FrameHom (Opens α) (Set α) where diff --git a/MathlibTest/Algebra/Polynomial.lean b/MathlibTest/Algebra/Polynomial.lean index e56b3b9a2c5b53..9680c297df39cd 100644 --- a/MathlibTest/Algebra/Polynomial.lean +++ b/MathlibTest/Algebra/Polynomial.lean @@ -38,5 +38,5 @@ example : (reprPrec p2 65).pretty = "(C 57 + C 22 * X ^ 2)" := by native_decide -- test that parens are added inside `C` def pu1 : (ULift.{1} ℕ)[X] := ⟨⟨{1}, Pi.single 1 (ULift.up 37), - by intro; simp [Pi.single, Function.update_apply, ←ULift.down_inj]⟩⟩ + by intro; simp [Pi.single, Function.update_apply, ← ULift.down_inj]⟩⟩ example : reprStr pu1 = "C (ULift.up 37) * X" := by native_decide From 4608056c77c52468b80773e8dcd585ef821c7c5e Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:28:49 +0000 Subject: [PATCH 0897/1300] feat(NumberTheory/Height/NumberField): the absolute height of an algebraic number (#41605) This PR defines the absolute height of an algebraic number. The proof that this definition does not depend on the choice of ambient number field is in #41606, but it would be nice to have this definition in mathlib earlier for statements in a downstream repo. Co-authored-by: tb65536 --- Mathlib/NumberTheory/Height/NumberField.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/NumberTheory/Height/NumberField.lean b/Mathlib/NumberTheory/Height/NumberField.lean index 60cff737cac4dc..45013475cc1e12 100644 --- a/Mathlib/NumberTheory/Height/NumberField.lean +++ b/Mathlib/NumberTheory/Height/NumberField.lean @@ -130,6 +130,21 @@ lemma mulHeight_eq {ι : Type*} {x : ι → K} (hx : x ≠ 0) : simp only [FinitePlace.coe_apply, InfinitePlace.coe_apply, Height.mulHeight_eq hx, prod_archAbsVal_eq, prod_nonarchAbsVal_eq fun v ↦ ⨆ i, v (x i)] +open Classical IntermediateField in +/-- The absolute multiplicative height of an algebraic number. This is defined for elements of any +field of characteristic zero, with a junk value of `0` if the element is not algebraic. -/ +noncomputable def absMulHeight₁ {K : Type*} [Field K] [CharZero K] (x : K) : ℝ := + if hx : IsIntegral ℚ x then + haveI : FiniteDimensional ℚ ℚ⟮x⟯ := adjoin.finiteDimensional hx + haveI : NumberField ℚ⟮x⟯ := {} + (Height.mulHeight₁ (AdjoinSimple.gen ℚ x)) ^ (Module.finrank ℚ ℚ⟮x⟯ : ℝ)⁻¹ + else 1 + +/-- The absolute logarithmic height of an algebraic number. This is defined for elements of any +field of characteristic zero, with a junk value of `0` if the element is not algebraic. -/ +noncomputable def absLogHeight₁ {K : Type*} [Field K] [CharZero K] (x : K) : ℝ := + (absMulHeight₁ x).log + variable (K) in lemma totalWeight_eq_sum_mult : totalWeight K = ∑ v : InfinitePlace K, v.mult := by simp only [totalWeight] From a7bedb3429f68ecebaea8531f3fb94f7fce0d252 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Mon, 20 Jul 2026 19:52:23 +0000 Subject: [PATCH 0898/1300] ci: don't fail fork post-build cache verify on "expected" cache invalidations (#41825) The `post_steps` "verify that everything was available in the cache" step reads the cache back with the PR branch's own `lake exe cache get`, while CI writes it with master's `cache` binary. For fork PRs those are different binaries, so a PR that changes the cache tool's key space (e.g. a `rootHashGeneration` bump in a toolchain bump) reads a different key space than the one the cache was written under and misses every file, hard-failing a build whose cache is in fact correct. Make the verify step warn-and-continue on such a miss, but only when it is an expected key-space invalidation: the build is a fork PR (`github.event.pull_request.head.repo.fork`, the same signal that sends the write path to master's binary) and this PR's `Cache/` differs from master's. Every non-fork build (master, bors, dev branches) reads and writes with one binary, so a miss there is a hard failure, as is an unchanged `Cache/` or an unavailable baseline. --- .github/workflows/build_template.yml | 72 +++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 6e333b0394ffa4..8fbaa837db97fe 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -686,12 +686,18 @@ jobs: # Sparse-checkout master's `.github/actions/` so the trust dispatch # below loads from a trust-rooted source, not from PR-branch-controlled # content. Mirrors the `Checkout local actions` step in the `build` job. - - name: Checkout local actions + # Also check out the cache tool (`Cache/`) at this ref. The verify step + # below compares it against the PR branch's `Cache/` to classify a cache + # miss. `github.workflow_sha` is the base ref the workflow runs from, + # master for fork PRs, whose `cache` binary wrote the cache. + - name: Checkout local actions and Cache baseline uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 - sparse-checkout: .github/actions + sparse-checkout: | + .github/actions + Cache path: workflow-actions # Sets MATHLIB_CACHE_FROM in env so the `cache get` calls below pick @@ -730,16 +736,60 @@ jobs: lake exe cache --repo=${{ github.event.pull_request.head.repo.full_name || github.repository }} get Archive Counterexamples - name: verify that everything was available in the cache + # Verify the cache reconstitutes this commit's oleans. This job reads + # the cache with the PR branch's own `lake exe cache get`. The write + # path uses master's `cache` binary for fork PRs and the PR branch's + # binary for every other build. So a fork PR whose `Cache/` differs + # from master reads a different `.ltar` key space (say, after a + # `rootHashGeneration` bump) and misses every file. That is an expected + # invalidation: warn and continue. Any other build reads and writes + # with the same binary, so a miss there is a real gap and is fatal. + env: + # GitHub sets this from the event payload; it is empty for pushes + # (master, bors), so those fail closed below. + HEAD_REPO_IS_FORK: ${{ github.event.pull_request.head.repo.fork }} run: | - echo "::group::{verify Mathlib cache}" - lake build --no-build --rehash -v Mathlib - echo "::endgroup::" - echo "::group::{verify Archive cache}" - lake build --no-build --rehash -v Archive - echo "::endgroup::" - echo "::group::{verify Counterexamples cache}" - lake build --no-build --rehash -v Counterexamples - echo "::endgroup::" + set +e + fail=0 + for target in Mathlib Archive Counterexamples; do + echo "::group::{verify ${target} cache}" + lake build --no-build --rehash -v "${target}" || fail=1 + echo "::endgroup::" + done + if [ "${fail}" -eq 0 ]; then + exit 0 + fi + + # Only fork PRs read and write the cache with different binaries. + # Every other build (master, bors, dev branches) uses one binary, so + # a miss is a real gap. + if [ "${HEAD_REPO_IS_FORK}" != "true" ]; then + echo "::error::Cache verification failed on an in-repo build; the uploaded cache is incomplete." + exit 1 + fi + + # `workflow-actions/Cache` is master's cache tool at + # `github.workflow_sha`; `Cache` is the PR branch's. Matching source + # means the key spaces agree, so the miss is a real gap. Differing + # source means the PR changed the key space, so the miss is expected. + # The cache writer is master's binary at upload time, which can be + # newer than `workflow_sha` when a `Cache/` change lands on master + # mid-build; that skew can only hard-fail like an unguarded verify + # or soft-pass a key space that genuinely diverged. + dout=$(diff -rq workflow-actions/Cache Cache 2>&1) + dstat=$? + if [ "${dstat}" -eq 0 ]; then + echo "::error::Cache verification failed and this PR's Cache/ matches master's, so the key spaces agree: the uploaded cache is incomplete." + exit 1 + elif [ "${dstat}" -eq 1 ]; then + echo "::warning::Cache verification incomplete, but this PR's Cache/ differs from master's. CI wrote the cache with master's binary and this job reads it with the PR branch's, so a changed key space (such as a rootHashGeneration bump) misses as expected. Continuing; the cache repopulates once this lands on master." + echo "${dout}" + exit 0 + else + echo "::error::Cache verification failed and master's Cache/ baseline could not be compared (diff status ${dstat}); treating as a failure." + echo "${dout}" + exit 1 + fi - name: check declarations in db files run: | From 04b57243be81f40f869c790a495ffc05af747dc5 Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Mon, 20 Jul 2026 20:28:07 +0000 Subject: [PATCH 0899/1300] feat: generalize `Topology/OpenPartialHomeomorph/Basic` to `PartialHomeomorph` (#41045) This is a continuation of #39084. --- Mathlib.lean | 1 + Mathlib/Logic/Equiv/PartialEquiv.lean | 8 + Mathlib/Topology/Constructions.lean | 7 + .../Topology/OpenPartialHomeomorph/Basic.lean | 66 ++--- Mathlib/Topology/PartialHomeomorph/Basic.lean | 263 ++++++++++++++++++ 5 files changed, 299 insertions(+), 46 deletions(-) create mode 100644 Mathlib/Topology/PartialHomeomorph/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index ce7026455fc354..4eb52906ba16c8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -8126,6 +8126,7 @@ public import Mathlib.Topology.Order.T5 public import Mathlib.Topology.Order.UpperLowerSetTopology public import Mathlib.Topology.Order.WithTop public import Mathlib.Topology.Partial +public import Mathlib.Topology.PartialHomeomorph.Basic public import Mathlib.Topology.PartialHomeomorph.Defs public import Mathlib.Topology.PartitionOfUnity public import Mathlib.Topology.Path diff --git a/Mathlib/Logic/Equiv/PartialEquiv.lean b/Mathlib/Logic/Equiv/PartialEquiv.lean index 88b41aace89d4a..c3f02961fb5519 100644 --- a/Mathlib/Logic/Equiv/PartialEquiv.lean +++ b/Mathlib/Logic/Equiv/PartialEquiv.lean @@ -284,6 +284,14 @@ protected def toEquiv : e.source ≃ e.target where left_inv := fun ⟨_, hx⟩ => Subtype.ext <| e.left_inv hx right_inv := fun ⟨_, hy⟩ => Subtype.ext <| e.right_inv hy +lemma toEquiv_eq_codRestrict_restrict : + e.toEquiv = codRestrict (e.source.domRestrict e) e.target (by simp) := + rfl + +lemma toEquiv_symm_eq_codRestrict_restrict : + e.toEquiv.symm = codRestrict (e.target.domRestrict e.invFun) e.source (by simp) := by + rfl + @[simp, mfld_simps] theorem symm_source : e.symm.source = e.target := rfl diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index e553a7ed5291f3..2b7a4896b7af9c 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -538,6 +538,13 @@ theorem Continuous.codRestrict {f : X → Y} {s : Set Y} (hf : Continuous f) (hs Continuous (s.codRestrict f hs) := hf.subtype_mk hs +theorem continuous_codRestrict_iff {f : X → Y} {s : Set Y} (hs : ∀ a, f a ∈ s) : + Continuous (codRestrict f s hs) ↔ Continuous f := by + refine ⟨?_, fun hf ↦ hf.codRestrict hs⟩ + simp_rw [continuous_def] + intro hf t ht + exact hf (Subtype.val ⁻¹' t) (isOpen_induced ht) + theorem IsOpenMap.codRestrict {f : X → Y} (hf : IsOpenMap f) {s : Set Y} (hs : ∀ a, f a ∈ s) : IsOpenMap (s.codRestrict f hs) := hf.subtype_mk hs diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean index e28ea04df2bc05..50b6c4a0363ede 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Basic.lean @@ -5,9 +5,9 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.Topology.Homeomorph.Lemmas public import Mathlib.Topology.OpenPartialHomeomorph.Defs public import Mathlib.Topology.Sets.Opens +public import Mathlib.Topology.PartialHomeomorph.Basic /-! # Partial homeomorphisms: basic theory @@ -120,17 +120,15 @@ theorem isOpen_image_iff_of_subset_source {s : Set X} (hs : s ⊆ e.source) : IsOpen (e '' s) ↔ IsOpen s := by rw [← e.symm.isOpen_symm_image_iff_of_subset_target hs, e.symm_symm] -/-- A `PartialEquiv` with continuous open forward map and open source is a -`OpenPartialHomeomorph`. -/ -@[simps toPartialHomeomorph] +/-- A `PartialEquiv` which is continuous on its source and has open forward map (on its source) +and open source is an `OpenPartialHomeomorph`. -/ +@[simps! toPartialHomeomorph] def ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) (ho : IsOpenMap (e.source.domRestrict e)) (hs : IsOpen e.source) : OpenPartialHomeomorph X Y where - toPartialEquiv := e + toPartialHomeomorph := PartialHomeomorph.ofContinuousOpenRestrict e hc ho open_source := hs - open_target := by simpa only [range_domRestrict, e.image_source_eq_target] using ho.isOpen_range - continuousOn_toFun := hc - continuousOn_invFun := e.image_source_eq_target ▸ ho.continuousOn_image_of_leftInvOn e.leftInvOn + open_target := by simpa [e.image_source_eq_target] using ho.isOpen_range @[simp] theorem coe_ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) @@ -144,8 +142,8 @@ theorem coe_ofContinuousOpenRestrict_symm (e : PartialEquiv X Y) (hc : Continuou ⇑(ofContinuousOpenRestrict e hc ho hs).symm = e.symm := rfl -/-- A `PartialEquiv` with continuous open forward map and open source is a -`OpenPartialHomeomorph`. -/ +/-- A `PartialEquiv` which is continuous on its source and has open forward map (on its source) and +open source is an `OpenPartialHomeomorph`. -/ @[simps! toPartialHomeomorph] def ofContinuousOpen (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) (ho : IsOpenMap e) (hs : IsOpen e.source) : OpenPartialHomeomorph X Y := @@ -165,19 +163,10 @@ theorem coe_ofContinuousOpen_symm (e : PartialEquiv X Y) (hc : ContinuousOn e e. /-- The homeomorphism obtained by restricting an `OpenPartialHomeomorph` to a subset of the source. -/ -@[simps] +@[simps!] def homeomorphOfImageSubsetSource {s : Set X} {t : Set Y} (hs : s ⊆ e.source) (ht : e '' s = t) : s ≃ₜ t := - have h₁ : MapsTo e s t := mapsTo_iff_image_subset.2 ht.subset - have h₂ : t ⊆ e.target := ht ▸ e.image_source_eq_target ▸ image_mono hs - have h₃ : MapsTo e.symm t s := ht ▸ forall_mem_image.2 fun _x hx => - (e.left_inv (hs hx)).symm ▸ hx - { toFun := MapsTo.restrict e s t h₁ - invFun := MapsTo.restrict e.symm t s h₃ - left_inv := fun a => Subtype.ext (e.left_inv (hs a.2)) - right_inv := fun b => Subtype.ext <| e.right_inv (h₂ b.2) - continuous_toFun := (e.continuousOn.mono hs).mapsToRestrict h₁ - continuous_invFun := (e.continuousOn_symm.mono h₂).mapsToRestrict h₃ } + e.toPartialHomeomorph.homeomorphOfImageSubsetSource hs ht /-- An open partial homeomorphism defines a homeomorphism between its source and target. -/ @[simps!] @@ -197,31 +186,17 @@ theorem nhds_eq_comap_inf_principal {x} (hx : x ∈ e.source) : /-- If an open partial homeomorphism has source and target equal to univ, then it induces a homeomorphism between the whole spaces, expressed in this definition. -/ -@[simps (attr := mfld_simps) -fullyApplied apply symm_apply] +@[simps! (attr := mfld_simps) -fullyApplied apply symm_apply] -- TODO: add a `PartialEquiv` version def toHomeomorphOfSourceEqUnivTargetEqUniv (h : e.source = (univ : Set X)) (h' : e.target = univ) : - X ≃ₜ Y where - toFun := e - invFun := e.symm - left_inv x := - e.left_inv <| by - rw [h] - exact mem_univ _ - right_inv x := - e.right_inv <| by - rw [h'] - exact mem_univ _ - continuous_toFun := by - simpa only [continuousOn_univ, h] using e.continuousOn - continuous_invFun := by - simpa only [continuousOn_univ, h'] using e.continuousOn_symm - -theorem isOpenEmbedding_restrict : IsOpenEmbedding (e.source.domRestrict e) := by - refine .of_continuous_injective_isOpenMap (e.continuousOn.comp_continuous - continuous_subtype_val Subtype.prop) e.injOn.injective fun V hV ↦ ?_ - rw [Set.domRestrict_eq, Set.image_comp] - exact e.isOpen_image_of_subset_source (e.open_source.isOpenMap_subtype_val V hV) - fun _ ⟨x, _, h⟩ ↦ h ▸ x.2 + X ≃ₜ Y := + e.toPartialHomeomorph.toHomeomorphOfSourceEqUnivTargetEqUniv h h' + +theorem isOpenEmbedding_restrict : IsOpenEmbedding (e.source.domRestrict e) where + toIsEmbedding := e.isEmbedding_restrict + isOpen_range := by + rw [range_domRestrict, image_source_eq_target] + exact e.open_target /-- An open partial homeomorphism whose source is all of `X` defines an open embedding of `X` into `Y`. The converse is also true; see `IsOpenEmbedding.toOpenPartialHomeomorph`. -/ @@ -287,7 +262,6 @@ theorem openPartialHomeomorphSubtypeCoe_source : @[simp, mfld_simps] theorem openPartialHomeomorphSubtypeCoe_target : (s.openPartialHomeomorphSubtypeCoe hs).target = s := by - simp only [openPartialHomeomorphSubtypeCoe, Subtype.range_coe_subtype, mfld_simps] - rfl + simp [openPartialHomeomorphSubtypeCoe] end TopologicalSpace.Opens diff --git a/Mathlib/Topology/PartialHomeomorph/Basic.lean b/Mathlib/Topology/PartialHomeomorph/Basic.lean new file mode 100644 index 00000000000000..065a60a32b12d0 --- /dev/null +++ b/Mathlib/Topology/PartialHomeomorph/Basic.lean @@ -0,0 +1,263 @@ +/- +Copyright (c) 2019 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +module + +public import Mathlib.Topology.Homeomorph.Lemmas +public import Mathlib.Topology.PartialHomeomorph.Defs + +/-! +# Partial homeomorphisms: basic theory + + +## Main definitions + +* `PartialHomeomorph.refl`: the identity partial homeomorphism +* `IsEmbedding.toPartialHomeomorph`: an embedding of `X` into `Y`, with `X` nonempty, + defines a partial homeomorphism whose source is all of `X`. +-/ + +@[expose] public section + +open Function Set Filter Topology + +variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} + [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] + [TopologicalSpace Z] [TopologicalSpace Z'] + +namespace PartialHomeomorph + +/-- The identity on the whole space as a partial homeomorphism. -/ +@[simps! -fullyApplied apply, simps! -isSimp source target] +protected def refl (X : Type*) [TopologicalSpace X] : PartialHomeomorph X X := + (Homeomorph.refl X).toPartialHomeomorph + +@[simp] +theorem refl_partialEquiv : (PartialHomeomorph.refl X).toPartialEquiv = PartialEquiv.refl X := + rfl + +@[simp] +theorem refl_symm : (PartialHomeomorph.refl X).symm = PartialHomeomorph.refl X := + rfl + +variable (e : PartialHomeomorph X Y) + +theorem source_preimage_target : e.source ⊆ e ⁻¹' e.target := + e.mapsTo + +theorem image_eq_target_inter_inv_preimage {s : Set X} (h : s ⊆ e.source) : + e '' s = e.target ∩ e.symm ⁻¹' s := + e.toPartialEquiv.image_eq_target_inter_inv_preimage h + +theorem image_source_inter_eq' (s : Set X) : e '' (e.source ∩ s) = e.target ∩ e.symm ⁻¹' s := + e.toPartialEquiv.image_source_inter_eq' s + +theorem image_source_inter_eq (s : Set X) : + e '' (e.source ∩ s) = e.target ∩ e.symm ⁻¹' (e.source ∩ s) := + e.toPartialEquiv.image_source_inter_eq s + +theorem symm_image_eq_source_inter_preimage {s : Set Y} (h : s ⊆ e.target) : + e.symm '' s = e.source ∩ e ⁻¹' s := + e.symm.image_eq_target_inter_inv_preimage h + +theorem symm_image_target_inter_eq (s : Set Y) : + e.symm '' (e.target ∩ s) = e.source ∩ e ⁻¹' (e.target ∩ s) := + e.symm.image_source_inter_eq _ + +theorem source_inter_preimage_inv_preimage (s : Set X) : + e.source ∩ e ⁻¹' (e.symm ⁻¹' s) = e.source ∩ s := + e.toPartialEquiv.source_inter_preimage_inv_preimage s + +theorem target_inter_inv_preimage_preimage (s : Set Y) : + e.target ∩ e.symm ⁻¹' (e ⁻¹' s) = e.target ∩ s := + e.symm.source_inter_preimage_inv_preimage _ + +theorem source_inter_preimage_target_inter (s : Set Y) : + e.source ∩ e ⁻¹' (e.target ∩ s) = e.source ∩ e ⁻¹' s := + e.toPartialEquiv.source_inter_preimage_target_inter s + +theorem image_source_eq_target : e '' e.source = e.target := + e.toPartialEquiv.image_source_eq_target + +theorem symm_image_target_eq_source : e.symm '' e.target = e.source := + e.symm.image_source_eq_target + +/-- A `PartialEquiv` which is continuous on its source and has open forward map (on its source) is a +`PartialHomeomorph`. -/ +@[simps toPartialEquiv] +def ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) + (ho : IsOpenMap (e.source.domRestrict e)) : PartialHomeomorph X Y where + toPartialEquiv := e + continuousOn_toFun := hc + continuousOn_invFun := e.image_source_eq_target ▸ ho.continuousOn_image_of_leftInvOn e.leftInvOn + +@[simp] +theorem coe_ofContinuousOpenRestrict (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) + (ho : IsOpenMap (e.source.domRestrict e)) : ⇑(ofContinuousOpenRestrict e hc ho) = e := + rfl + +@[simp] +theorem coe_ofContinuousOpenRestrict_symm (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) + (ho : IsOpenMap (e.source.domRestrict e)) : + ⇑(ofContinuousOpenRestrict e hc ho).symm = e.symm := + rfl + +/-- A `PartialEquiv` which is continuous on its source and has open forward map (on its source) and +open source is a `PartialHomeomorph`. -/ +@[simps! toPartialEquiv] +def ofContinuousOpen (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) (ho : IsOpenMap e) + (hs : IsOpen e.source) : PartialHomeomorph X Y := + ofContinuousOpenRestrict e hc (ho.domRestrict hs) + +@[simp] +theorem coe_ofContinuousOpen (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) + (ho : IsOpenMap e) (hs : IsOpen e.source) : + ⇑(ofContinuousOpen e hc ho hs) = e := + rfl + +@[simp] +theorem coe_ofContinuousOpen_symm (e : PartialEquiv X Y) (hc : ContinuousOn e e.source) + (ho : IsOpenMap e) (hs : IsOpen e.source) : + ⇑(ofContinuousOpen e hc ho hs).symm = e.symm := + rfl + +/-- The homeomorphism obtained by restricting a `PartialHomeomorph` to a subset of the source. +-/ +@[simps] +def homeomorphOfImageSubsetSource {s : Set X} {t : Set Y} (hs : s ⊆ e.source) (ht : e '' s = t) : + s ≃ₜ t := + have h₁ : MapsTo e s t := mapsTo_iff_image_subset.2 ht.subset + have h₂ : t ⊆ e.target := ht ▸ e.image_source_eq_target ▸ image_mono hs + have h₃ : MapsTo e.symm t s := ht ▸ forall_mem_image.2 fun _x hx => + (e.left_inv (hs hx)).symm ▸ hx + { toFun := MapsTo.restrict e s t h₁ + invFun := MapsTo.restrict e.symm t s h₃ + left_inv := fun a => Subtype.ext (e.left_inv (hs a.2)) + right_inv := fun b => Subtype.ext <| e.right_inv (h₂ b.2) + continuous_toFun := (e.continuousOn.mono hs).mapsToRestrict h₁ + continuous_invFun := (e.continuousOn_symm.mono h₂).mapsToRestrict h₃ } + +/-- A partial homeomorphism defines a homeomorphism between its source and target. -/ +@[simps!] +def toHomeomorphSourceTarget : e.source ≃ₜ e.target := + e.homeomorphOfImageSubsetSource subset_rfl e.image_source_eq_target + +theorem secondCountableTopology_source [SecondCountableTopology Y] : + SecondCountableTopology e.source := + e.toHomeomorphSourceTarget.secondCountableTopology + +/-- If a partial homeomorphism has source and target equal to univ, then it induces a +homeomorphism between the whole spaces, expressed in this definition. -/ +@[simps -fullyApplied apply symm_apply] +-- TODO: add a `PartialEquiv` version +def toHomeomorphOfSourceEqUnivTargetEqUniv (h : e.source = (univ : Set X)) (h' : e.target = univ) : + X ≃ₜ Y where + toFun := e + invFun := e.symm + left_inv x := + e.left_inv <| by + rw [h] + exact mem_univ _ + right_inv x := + e.right_inv <| by + rw [h'] + exact mem_univ _ + continuous_toFun := by + simpa only [continuousOn_univ, h] using e.continuousOn + continuous_invFun := by + simpa only [continuousOn_univ, h'] using e.continuousOn_symm + +theorem isEmbedding_restrict : IsEmbedding (e.source.domRestrict e.toFun) := by + rw [isEmbedding_iff] + constructor + · apply Topology.IsInducing.of_codRestrict (t := e.target) (by simp) + rw [← PartialEquiv.toEquiv_eq_codRestrict_restrict] + exact e.toHomeomorphSourceTarget.isInducing + · rw [domRestrict_eq, toFun_eq_coe e, e.injOn.injective_iff e.source (by simp)] + exact Subtype.val_injective + +/-- A partial homeomorphism whose source is all of `X` defines an embedding of `X` into +`Y`. The converse is also true; see `IsEmbedding.toPartialHomeomorph`. -/ +theorem isEmbedding (h : e.source = Set.univ) : IsEmbedding e := + e.isEmbedding_restrict.comp + ((Homeomorph.setCongr h).trans <| Homeomorph.Set.univ X).symm.isEmbedding + +/-- If a `PartialEquiv` is a homeomorphism when restricted to source and target, then it is a +`PartialHomeomorph`. -/ +def ofIsHomeomorphToEquiv (f : PartialEquiv X Y) (h : IsHomeomorph (f.toEquiv)) : + PartialHomeomorph X Y where + toPartialEquiv := f + continuousOn_toFun := by + rw [continuousOn_iff_continuous_domRestrict, + ← continuous_codRestrict_iff (s := f.target) (by simp)] + exact h.continuous + continuousOn_invFun := by + rw [continuousOn_iff_continuous_domRestrict, + ← continuous_codRestrict_iff (s := f.source) (by simp)] + exact ((Equiv.isHomeomorph_iff _).1 h).2 + +end PartialHomeomorph + +/-! +## Embeddings +-/ + +namespace Topology.IsEmbedding + +variable (f : X → Y) (h : IsEmbedding f) + +/-- An embedding of `X` into `Y`, with `X` nonempty, defines a partial homeomorphism +whose source is all of `X`. The converse is also true; see `PartialHomeomorph.isEmbedding`. -/ +@[simps! -fullyApplied apply source target] +noncomputable def toPartialHomeomorph [Nonempty X] : PartialHomeomorph X Y := + PartialHomeomorph.ofIsHomeomorphToEquiv (h.injective.injOn.toPartialEquiv f univ) (by + rw [isHomeomorph_iff_isEmbedding_surjective] + refine ⟨?_, Equiv.surjective _⟩ + rw [PartialEquiv.toEquiv_eq_codRestrict_restrict] + apply IsEmbedding.codRestrict + simpa! [domRestrict_eq] using h.comp subtypeVal) + +variable [Nonempty X] + +lemma toPartialHomeomorph_left_inv {x : X} : (h.toPartialHomeomorph f).symm (f x) = x := by + rw [← congr_fun (h.toPartialHomeomorph_apply f), PartialHomeomorph.left_inv] + exact Set.mem_univ _ + +lemma toPartialHomeomorph_right_inv {x : Y} (hx : x ∈ Set.range f) : + f ((h.toPartialHomeomorph f).symm x) = x := by + rw [← congr_fun (h.toPartialHomeomorph_apply f), PartialHomeomorph.right_inv] + rwa [toPartialHomeomorph_target] + +end Topology.IsEmbedding + +/-! inclusion of a set in a topological space -/ +namespace Set + +/- `Nonempty s` is not a type class argument because `s`, being a subset, rarely comes with a type +class instance. Then we'd have to manually provide the instance every time we use the following +lemmas, tediously using `haveI := ...` or `@foobar _ _ _ ...`. -/ +variable (s : Set X) (hs : Nonempty s) + +/-- The inclusion of an subset `s` of a space `X` into `X` is a partial homeomorphism +from the subtype `s` to `X`. -/ +noncomputable def partialHomeomorphSubtypeCoe : PartialHomeomorph s X := + IsEmbedding.subtypeVal.toPartialHomeomorph _ + +@[simp] +theorem partialHomeomorphSubtypeCoe_coe : + (s.partialHomeomorphSubtypeCoe hs : s → X) = (↑) := + rfl + +@[simp] +theorem partialHomeomorphSubtypeCoe_source : + (s.partialHomeomorphSubtypeCoe hs).source = Set.univ := + rfl + +@[simp] +theorem partialHomeomorphSubtypeCoe_target : + (s.partialHomeomorphSubtypeCoe hs).target = s := by + simp [partialHomeomorphSubtypeCoe] + +end Set From 910a7566b3f8a515bfc5417cdd31b2ed1ce4df93 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Mon, 20 Jul 2026 20:57:32 +0000 Subject: [PATCH 0900/1300] feat(SimpleGraph/Subwalks): an empty walk at `v` is a subwalk of any walk to `v` (#41626) --- Mathlib/Combinatorics/SimpleGraph/Walk/Subwalks.lean | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Subwalks.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Subwalks.lean index 64ccad53c6b19e..b315345a00053b 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Subwalks.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Subwalks.lean @@ -40,9 +40,15 @@ lemma isSubwalk_rfl {u v} (p : G.Walk u v) : p.IsSubwalk p := ⟨nil, nil, by simp⟩ @[simp] -lemma nil_isSubwalk {u v} (q : G.Walk u v) : (Walk.nil : G.Walk u u).IsSubwalk q := +lemma isSubwalk_nil_start {u v} (q : G.Walk u v) : (Walk.nil : G.Walk u u).IsSubwalk q := ⟨nil, q, by simp⟩ +@[deprecated (since := "2026-07-11")] alias nil_isSubwalk := isSubwalk_nil_start + +@[simp] +theorem isSubwalk_nil_end {u v} (q : G.Walk u v) : (nil : G.Walk v v).IsSubwalk q := + ⟨q, nil, by simp⟩ + protected lemma IsSubwalk.cons {u v u' v' w} {p : G.Walk u v} {q : G.Walk u' v'} (hpq : p.IsSubwalk q) (h : G.Adj w u') : p.IsSubwalk (q.cons h) := by obtain ⟨r1, r2, rfl⟩ := hpq From 55b7917b472489c7c56a0fa6393af05cfd536599 Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Tue, 21 Jul 2026 01:32:44 +0000 Subject: [PATCH 0901/1300] feat(NumberTheory/LSeries): Define the L-series of a modular form (#31187) Define the L-function of a modular form (showing it is meromorphic on C and agrees with the naive Dirichlet series for `re s` large). --- Mathlib.lean | 1 + .../Complex/UpperHalfPlane/Topology.lean | 8 + .../SpecialFunctions/Gamma/Deligne.lean | 9 +- .../SpecialFunctions/Pow/Complex.lean | 9 + .../Matrix/SpecialLinearGroup.lean | 2 + .../ModularForms/ArithmeticSubgroups.lean | 14 ++ .../NumberTheory/ModularForms/LFunction.lean | 199 ++++++++++++++++++ .../NumberTheory/ModularForms/QExpansion.lean | 7 + Mathlib/Topology/Algebra/Group/Basic.lean | 15 +- 9 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 Mathlib/NumberTheory/ModularForms/LFunction.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4eb52906ba16c8..0e66be08e499e5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5834,6 +5834,7 @@ public import Mathlib.NumberTheory.ModularForms.JacobiTheta.Bounds public import Mathlib.NumberTheory.ModularForms.JacobiTheta.Manifold public import Mathlib.NumberTheory.ModularForms.JacobiTheta.OneVariable public import Mathlib.NumberTheory.ModularForms.JacobiTheta.TwoVariable +public import Mathlib.NumberTheory.ModularForms.LFunction public import Mathlib.NumberTheory.ModularForms.LevelOne public import Mathlib.NumberTheory.ModularForms.LevelOne.Basic public import Mathlib.NumberTheory.ModularForms.LevelOne.DimensionFormula diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean index fa7163e6fe288f..29514842852516 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean @@ -186,6 +186,14 @@ lemma eventuallyEq_coe_comp_ofComplex {z : ℂ} (hz : 0 < z.im) : filter_upwards [isOpen_upperHalfPlaneSet.mem_nhds hz] with x hx simp only [Function.comp_apply, ofComplex_apply_of_im_pos hx, id_eq] +@[fun_prop] +lemma continuousOn_ofComplex_I_mul : + ContinuousOn (fun t : ℝ ↦ ofComplex (I * t)) (Set.Ioi 0) := by + simp only [ofComplex_apply_eq_ite, continuousOn_iff_continuous_domRestrict, + continuous_induced_rng] + have : Continuous (fun t : ℝ ↦ Complex.I * t) := by fun_prop + exact (this.comp continuous_subtype_val).congr (by simp +contextual) + lemma J_smul (τ : ℍ) : J • τ = ofComplex (-(conj ↑τ)) := by ext rw [coe_J_smul, ofComplex_apply_of_im_pos (by simpa using τ.im_pos)] diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Deligne.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Deligne.lean index fa8d2a794a3389..b0ee5de3dd9c49 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Deligne.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Deligne.lean @@ -85,13 +85,20 @@ lemma Gammaℂ_one : Gammaℂ 1 = 1 / π := by section analyticity +@[fun_prop] lemma differentiable_Gammaℝ_inv : Differentiable ℂ (fun s ↦ (Gammaℝ s)⁻¹) := by conv => enter [2, s]; rw [Gammaℝ, mul_inv] - refine Differentiable.mul (fun s ↦ .inv ?_ (by simp [pi_ne_zero])) ?_ + refine Differentiable.mul (fun s ↦ .inv ?_ (by simp)) ?_ · refine ((differentiableAt_id.neg.div_const (2 : ℂ)).const_cpow ?_) exact Or.inl (ofReal_ne_zero.mpr pi_ne_zero) · exact differentiable_one_div_Gamma.comp (differentiable_id.div_const _) +@[fun_prop] +lemma differentiable_Gammaℂ_inv : Differentiable ℂ (fun s ↦ (Gammaℂ s)⁻¹) := by + conv => enter [2, s]; rw [Gammaℂ, mul_inv] + refine (Differentiable.inv ?_ (by simp)).mul differentiable_one_div_Gamma + exact (differentiable_neg.const_cpow (by simp)).const_mul _ + lemma Gammaℝ_residue_zero : Tendsto (fun s ↦ s * Gammaℝ s) (𝓝[≠] 0) (𝓝 2) := by have h : Tendsto (fun z : ℂ ↦ z / 2 * Gamma (z / 2)) (𝓝[≠] 0) (𝓝 1) := by refine tendsto_self_mul_Gamma_nhds_zero.comp ?_ diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean index 67af1099ddb412..3aac623dd59cb2 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean @@ -214,6 +214,15 @@ theorem inv_cpow_eq_ite (x : ℂ) (n : ℂ) : theorem inv_cpow (x : ℂ) (n : ℂ) (hx : x.arg ≠ π) : x⁻¹ ^ n = (x ^ n)⁻¹ := by rw [inv_cpow_eq_ite, if_neg hx] +lemma inv_cpow_ofReal_nonneg {a : ℝ} (ha : 0 ≤ a) (r : ℂ) : + ((a : ℂ)⁻¹) ^ r = (a ^ r : ℂ)⁻¹ := + inv_cpow _ _ <| by simpa [arg_ofReal_of_nonneg ha] using Real.pi_ne_zero.symm + +lemma div_cpow_ofReal_nonneg {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (r : ℂ) : + ((a : ℂ) / (b : ℂ)) ^ r = (a : ℂ) ^ r / (b : ℂ) ^ r := by + rw [div_eq_mul_inv, ← ofReal_inv, mul_cpow_ofReal_nonneg ha (inv_nonneg_of_nonneg hb), + ofReal_inv, inv_cpow_ofReal_nonneg hb, div_eq_mul_inv] + /-- `Complex.inv_cpow_eq_ite` with the `ite` on the other side. -/ theorem inv_cpow_eq_ite' (x : ℂ) (n : ℂ) : (x ^ n)⁻¹ = if x.arg = π then conj (x⁻¹ ^ conj n) else x⁻¹ ^ n := by diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index 70392a20ca0f78..cbb6fad7f6e145 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -829,11 +829,13 @@ def S : SL(2, ℤ) := def T : SL(2, ℤ) := ⟨!![1, 1; 0, 1], by simp [Matrix.det_fin_two_of]⟩ +@[simp] theorem coe_S : ↑S = !![0, -1; 1, 0] := rfl lemma S_inv : S⁻¹ = -S := by decide +@[simp] theorem coe_T : ↑T = (!![1, 1; 0, 1] : Matrix _ _ ℤ) := rfl diff --git a/Mathlib/NumberTheory/ModularForms/ArithmeticSubgroups.lean b/Mathlib/NumberTheory/ModularForms/ArithmeticSubgroups.lean index eba88f2176e2fc..916091ed81b23a 100644 --- a/Mathlib/NumberTheory/ModularForms/ArithmeticSubgroups.lean +++ b/Mathlib/NumberTheory/ModularForms/ArithmeticSubgroups.lean @@ -71,6 +71,20 @@ instance (Γ' : Subgroup (GL n R)) [HasDetOne Γ] : HasDetOne (Γ ⊓ Γ') where instance (Γ' : Subgroup (GL n R)) [HasDetOne Γ] : HasDetOne (Γ' ⊓ Γ) where det_eq hg := HasDetOne.det_eq hg.2 +open scoped Pointwise in +instance (Γ : Subgroup (GL n R)) [HasDetOne Γ] (g : ConjAct <| GL n R) : + HasDetOne (g • Γ) where + det_eq {h} hh := by + rw [mem_pointwise_smul_iff_inv_smul_mem] at hh + simpa [ConjAct.smul_def] using HasDetOne.det_eq hh + +open scoped Pointwise in +instance (Γ : Subgroup (GL n R)) [HasDetPlusMinusOne Γ] (g : ConjAct <| GL n R) : + HasDetPlusMinusOne (g • Γ) where + det_eq {h} hh := by + rw [mem_pointwise_smul_iff_inv_smul_mem] at hh + simpa [ConjAct.smul_def] using HasDetPlusMinusOne.det_eq hh + end det_typeclasses section SL2Z_in_GL2R diff --git a/Mathlib/NumberTheory/ModularForms/LFunction.lean b/Mathlib/NumberTheory/ModularForms/LFunction.lean new file mode 100644 index 00000000000000..30cd98cb30b24e --- /dev/null +++ b/Mathlib/NumberTheory/ModularForms/LFunction.lean @@ -0,0 +1,199 @@ +/- +Copyright (c) 2025 David Loeffler. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: David Loeffler +-/ +module + +public import Mathlib.NumberTheory.ModularForms.Bounds +public import Mathlib.NumberTheory.LSeries.AbstractFuncEq +public import Mathlib.NumberTheory.LSeries.MellinEqDirichlet +public import Mathlib.Analysis.PSeries + +/-! +# The `L`-function of a modular form +-/ + +@[expose] public section + +open UpperHalfPlane hiding I +open scoped Real +open Filter Complex MatrixGroups Asymptotics + +variable {Γ : Subgroup (GL (Fin 2) ℝ)} [Γ.IsArithmetic] + {k : ℤ} (hk : 0 < k) {F : Type*} [FunLike F ℍ ℂ] (f : F) {s : ℂ} + +local notation "h" => Subgroup.strictWidthInfty + +open ConjAct Pointwise in +private local instance : + Subgroup.IsArithmetic (toConjAct (ModularGroup.S : GL (Fin 2) ℝ)⁻¹ • Γ) := by + convert Subgroup.IsArithmetic.conj Γ ↑(ModularGroup.S⁻¹) + simp only [ModularGroup.S_inv, ← map_inv] + ext i j + fin_cases i <;> fin_cases j <;> simp [ModularGroup.S] + +namespace ModularForm + +variable [ModularFormClass F Γ k] + +section asymptotics -- private lemmas about aymptotics along `I * ℝ` + +private lemma tendsto_ofComplex_I_mul_atTop_atImInfty : + Tendsto (fun t : ℝ ↦ ofComplex (I * t)) atTop atImInfty := by + rw [atImInfty, tendsto_comap_iff] + refine tendsto_id.congr' ?_ + filter_upwards [eventually_gt_atTop 0] with t ht + simp [ofComplex_apply_of_im_pos, ht, ← coe_im] + +include F k Γ in -- conclusion doesn't explicitly refer these +private lemma isBigO_comp_ofComplex_I_mul_sub_valueAtInfty (r : ℝ) : + (fun t : ℝ ↦ f (ofComplex (I * t)) - valueAtInfty f) =O[atTop] (fun t ↦ t ^ r) := by + obtain ⟨C, hCpos, hCO⟩ := ModularFormClass.exp_decay_sub_atImInfty' f + refine (hCO.comp_tendsto tendsto_ofComplex_I_mul_atTop_atImInfty).trans ?_ + refine (EventuallyEq.isBigO ?_).trans (isLittleO_exp_neg_mul_rpow_atTop hCpos r).isBigO + filter_upwards [eventually_gt_atTop 0] with t ht + simp [ht, ofComplex_apply_of_im_pos, ← coe_im] + +end asymptotics + +/-- A `WeakFEPair` structure associated to a modular form. -/ +@[simps] noncomputable def weakFEPair : WeakFEPair ℂ where + f t := f (ofComplex (I * t)) + g t := translate f ModularGroup.S (ofComplex (I * t)) + k := k + hk := mod_cast hk + ε := I ^ k + hε := zpow_ne_zero _ I_ne_zero + f₀ := valueAtInfty f + g₀ := valueAtInfty (translate f ModularGroup.S) + hf_int := ContinuousOn.locallyIntegrableOn (by fun_prop) measurableSet_Ioi + hg_int := ContinuousOn.locallyIntegrableOn (by fun_prop) measurableSet_Ioi + h_feq t (ht : 0 < t) := by + rw [coe_translate, slash_def] + suffices f (ofComplex (I * t⁻¹)) = I ^ k * t ^ k * + (f ((ModularGroup.S : GL (Fin 2) ℝ) • ofComplex (I * t)) * ofComplex (I * t) ^ (-k)) by + simpa [σ, denom] + rw [ofComplex_apply_of_im_pos (by simpa), ofComplex_apply_of_im_pos (by simpa), + mul_comm (f _), ← mul_assoc, ← mul_zpow, zpow_neg, + mul_inv_cancel₀ (zpow_ne_zero _ (by aesop))] + simp only [one_mul] + congr 1 + ext + rw [coe_smul_of_det_pos (by simp)] + simp [num, denom, div_eq_mul_inv, mul_comm] + hf_top r := by -- `by exact` to hide use of private lemma in @[expose]'d declaration + exact isBigO_comp_ofComplex_I_mul_sub_valueAtInfty f r + hg_top r := by -- `by exact` to hide use of private lemma in @[expose]'d declaration + exact isBigO_comp_ofComplex_I_mul_sub_valueAtInfty (translate f ModularGroup.S) r + +/-- The `L`-series of a modular form (including its Archimedean `Γ`-factor). -/ +noncomputable def Λ : ℂ → ℂ := (weakFEPair hk f).Λ + +/-- Shared Dirichlet-series summability argument for modular and cusp forms. -/ +private lemma hasSum_Λ_of_qExpansion_isBigO {r : ℝ} + (hpos : 0 < s.re) (hs : r + 1 < s.re) + (hΛ : Λ hk f s = mellin (fun t ↦ (weakFEPair hk f).f t - (weakFEPair hk f).f₀) s) + (hcoeff : (fun n ↦ (qExpansion (h Γ) f).coeff n) =O[atTop] fun n ↦ (n : ℝ) ^ r) : + HasSum (fun n ↦ π ^ (-s) * Gamma s * (qExpansion (h Γ) f).coeff n / + ↑(2 * n / h Γ : ℝ) ^ s) (Λ hk f s) := by + rw [hΛ] + have hh := Γ.strictWidthInfty_pos + have hΓ := Γ.strictWidthInfty_mem_strictPeriods + refine hasSum_mellin_pi_mul₀ (fun _ ↦ by positivity) hpos ?_ ?_ + · -- show `q`-expansion converges to `f` on positive imaginary axis + intro t (ht : 0 < t) + have := hasSum_qExpansion f hh hΓ (ofComplex (I * t)) + convert! hasSum_ite_sub_hasSum this 0 using 2 with n + · rcases Nat.eq_zero_or_pos n with rfl | hn + · simp + · simp [hn.ne', Function.Periodic.qParam, ofComplex_apply_eq_ite, ht, ← exp_nat_mul] + grind [I_sq] + · simp only [weakFEPair] + rw [qExpansion_coeff_zero hh, pow_zero, mul_one] + · exact ModularFormClass.analyticAt_cuspFunction_zero f hh hΓ + · exact SlashInvariantFormClass.periodic_comp_ofComplex f hΓ + · -- show summability of Dirichlet series + simp_rw [mul_comm (2 : ℝ), mul_div_assoc, + Real.mul_rpow (Nat.cast_nonneg _) (show 0 ≤ 2 / h Γ by positivity), ← div_div] + apply Summable.div_const + apply summable_of_isBigO_nat (Real.summable_nat_rpow.mpr <| show r - s.re < -1 by linarith) + simp only [Real.rpow_sub' (Nat.cast_nonneg _) (show r - s.re ≠ 0 by linarith)] + apply IsBigO.mul _ (isBigO_refl _ _) + simpa using hcoeff.norm_left + +lemma hasSum_Λ (hs : k + 1 < s.re) : + HasSum (fun n ↦ π ^ (-s) * Gamma s * (qExpansion (h Γ) f).coeff n / + ↑(2 * n / h Γ : ℝ) ^ s) (Λ hk f s) := by + refine hasSum_Λ_of_qExpansion_isBigO hk f (r := k) + (by linarith [show (0 : ℝ) < k from mod_cast hk]) (by exact_mod_cast hs) ?_ ?_ + · rw [Λ, ← ((weakFEPair hk f).hasMellin <| by grind [weakFEPair]).2] + · simpa using ModularFormClass.qExpansion_isBigO hk.le f + +/-- The `L`-series of a modular form (without its Archimedean `Γ`-factor). -/ +noncomputable def L (s : ℂ) : ℂ := Λ hk f s * (2 / Gammaℂ s) + +/-- Shared conversion from the completed `Λ`-series to the ordinary `L`-series. -/ +private lemma hasSum_L_of_hasSum_Λ (hs : 0 < s.re) + (hΛ : HasSum (fun n ↦ π ^ (-s) * Gamma s * + (qExpansion (h Γ) f).coeff n / ↑(2 * n / h Γ : ℝ) ^ s) (Λ hk f s)) : + HasSum (fun i ↦ (qExpansion (h Γ) f).coeff i / ↑i ^ s) (h Γ ^ (-s) * L hk f s) := by + convert! hΛ.mul_right (2 / Gammaℂ s * h Γ ^ (-s)) using 1 + · ext n + generalize (PowerSeries.coeff n) (qExpansion (h Γ) f) = p + rw [Gammaℂ, ← div_div, ← div_div, div_self two_ne_zero, one_div, cpow_neg (2 * _), inv_inv, + ← ofReal_ofNat, mul_cpow_ofReal_nonneg two_pos.le Real.pi_pos.le] + simp only [ofReal_div, ofReal_mul, ofReal_ofNat, ofReal_natCast] + have : (2 * n / h Γ : ℂ) ^ s = 2 ^ s * n ^ s / h Γ ^ s := by + rw [← ofReal_ofNat, ← ofReal_natCast, ← ofReal_mul, + div_cpow_ofReal_nonneg (by grind) Γ.strictWidthInfty_nonneg, ofReal_mul, + mul_cpow_ofReal_nonneg zero_le_two n.cast_nonneg] + rw [this, cpow_neg, cpow_neg] + have := Gamma_ne_zero_of_re_pos hs + have := cpow_ne_zero_iff (y := s).mpr (.inl <| ofReal_ne_zero.mpr Γ.strictWidthInfty_pos.ne') + field_simp + · grind [L] + +theorem hasSum_L (hs : k + 1 < s.re) : + HasSum (fun n ↦ (qExpansion (h Γ) f).coeff n / n ^ s) (h Γ ^ (-s) * L hk f s) := + hasSum_L_of_hasSum_Λ hk f (by linarith [show (0 : ℝ) < k from mod_cast hk]) (hasSum_Λ hk f hs) + +end ModularForm + +open ModularForm + +namespace CuspForm + +variable [CuspFormClass F Γ k] + +/-- For cusp forms the FE-pair is a strong FE-pair. -/ +lemma isStrongFEPair : IsStrongFEPair (weakFEPair hk f) where + hf₀ := (CuspFormClass.zero_at_infty f).valueAtInfty_eq_zero + hg₀ := (CuspFormClass.zero_at_infty <| translate f ModularGroup.S).valueAtInfty_eq_zero + +@[fun_prop] +lemma differentiable_Λ : Differentiable ℂ (Λ hk f) := + (isStrongFEPair hk f).differentiable_Λ + +lemma Λ_eq_mellin : Λ hk f = mellin (fun t ↦ f (ofComplex (I * t))) := + (isStrongFEPair hk f).Λ_eq + +lemma hasSum_Λ (hk : 0 < k) (hs : k / 2 + 1 < s.re) : + HasSum (fun n ↦ π ^ (-s) * Gamma s * (qExpansion (h Γ) f).coeff n / ↑(2 * n / h Γ : ℝ) ^ s) + (Λ hk f s) := by + refine hasSum_Λ_of_qExpansion_isBigO hk f (r := k / 2) + (by linarith [show (0 : ℝ) < k from mod_cast hk]) hs ?_ ?_ + · simp [Λ_eq_mellin, (CuspFormClass.zero_at_infty f).valueAtInfty_eq_zero] + · simpa using CuspFormClass.qExpansion_isBigO f + +@[fun_prop] +lemma differentiable_L : Differentiable ℂ (L hk f) := by + unfold L + simp only [div_eq_mul_inv] + fun_prop + +theorem hasSum_L (hs : k / 2 + 1 < s.re) : + HasSum (fun n ↦ (qExpansion (h Γ) f).coeff n / n ^ s) (h Γ ^ (-s) * L hk f s) := + hasSum_L_of_hasSum_Λ hk f (by linarith [show (0 : ℝ) < k from mod_cast hk]) (hasSum_Λ f hk hs) + +end CuspForm diff --git a/Mathlib/NumberTheory/ModularForms/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/QExpansion.lean index ddf5691779616f..7fda871e61b063 100644 --- a/Mathlib/NumberTheory/ModularForms/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/QExpansion.lean @@ -660,6 +660,13 @@ lemma qExpansion_of_pow [Γ.HasDetPlusMinusOne] (hh : 0 < h) have := (qExpansionRingHom h hh hΓ).map_pow (DirectSum.of _ k f) n simpa [DirectSum.ofPow] +/-- Specialized version of `UpperHalfPlane.hasSum_qExpansion` for modular forms, with many +arguments filled in automatically. -/ +lemma hasSum_qExpansion (hh : 0 < h) {k : ℤ} [ModularFormClass F Γ k] + [Fact (IsCusp .infty Γ)] (hΓ : h ∈ Γ.strictPeriods) (τ : ℍ) : + HasSum (fun m ↦ (qExpansion h f).coeff m * 𝕢 h τ ^ m) (f τ) := + τ.hasSum_qExpansion hh (periodic_comp_ofComplex f hΓ) (holo f) (bdd_at_infty f) + end ModularForm namespace ModularFormClass diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 0d869609ea35c1..a726f7cc3df5fe 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -434,6 +434,16 @@ instance ConjAct.units_continuousConstSMul {M} [Monoid M] [TopologicalSpace M] [ContinuousMul M] : ContinuousConstSMul (ConjAct Mˣ) M := ⟨fun _ => (continuous_const.mul continuous_id).mul continuous_const⟩ +open scoped Pointwise in +instance [Group G] [Group H] [TopologicalSpace G] [MulDistribMulAction H G] + [ContinuousConstSMul H G] {𝒢 : Subgroup G} (h : H) [DiscreteTopology 𝒢] : + DiscreteTopology ↑(h • 𝒢) := by + simp only [← SetLike.coe_sort_coe, ← isDiscrete_iff_discreteTopology] at * + refine IsDiscrete.image_of_isOpenMap ‹_› ?_ fun x y ↦ by simp + apply IsOpenMap.of_inverse (f' := fun x ↦ h⁻¹ • x) (continuous_const_smul _) <;> + · intro x + simp + variable [TopologicalSpace G] [Inv G] [Mul G] /-- Conjugation is jointly continuous on `G × G` when both `mul` and `inv` are continuous. -/ @@ -450,6 +460,10 @@ theorem IsTopologicalGroup.continuous_conj [SeparatelyContinuousMul G] (g : G) : Continuous fun h : G => g * h * g⁻¹ := (continuous_mul_const g⁻¹).comp (continuous_const_mul g) +instance {G : Type*} [Group G] [TopologicalSpace G] [SeparatelyContinuousMul G] : + ContinuousConstSMul (ConjAct G) G where + continuous_const_smul h := IsTopologicalGroup.continuous_conj (ConjAct.ofConjAct h) + /-- Conjugation acting on fixed element of the group is continuous when both `mul` and `inv` are continuous. -/ @[to_additive (attr := continuity, fun_prop) @@ -1063,7 +1077,6 @@ lemma Filter.tendsto_const_div_iff' (b : G) {c : G} {f : α → G} {l : Filter @[deprecated (since := "2026-02-03")] alias Filter.tendsto_const_div_iff := Filter.tendsto_const_div_iff' - /-- A version of `Homeomorph.mulLeft a b⁻¹` that is defeq to `a / b`. -/ @[to_additive (attr := simps! +simpRhs) /-- A version of `Homeomorph.addLeft a (-b)` that is defeq to `a - b`. -/] From bc63109edf7834d3037842895ad82b7602b1c1f6 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 21 Jul 2026 02:54:05 +0000 Subject: [PATCH 0902/1300] chore(RingTheory/Localization/Integer): fix typo in theorem name (#41897) This PR fixes a typo in the name of a recently added theorem. Co-authored-by: tb65536 --- Mathlib/RingTheory/Localization/Integer.lean | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/Localization/Integer.lean b/Mathlib/RingTheory/Localization/Integer.lean index 638dfe9bacf2a4..673abe1debab8a 100644 --- a/Mathlib/RingTheory/Localization/Integer.lean +++ b/Mathlib/RingTheory/Localization/Integer.lean @@ -124,13 +124,16 @@ theorem map_integerMultiple {ι : Type*} (s : Finset ι) (f : ι → S) (i : s) algebraMap R S (integerMultiple M s f i) = commonDenom M s f • f i := ((exist_integer_multiples M s f).choose_spec _ i.prop).choose_spec -theorem integerMultipleMultiple_injective {ι : Type*} (s : Finset ι) (f : ι → S) +theorem integerMultiple_injective {ι : Type*} (s : Finset ι) (f : ι → S) (hf : Function.Injective f) : Function.Injective (integerMultiple M s f) := by intro i j h rw [← SetLike.coe_eq_coe, ← hf.eq_iff, ← (IsLocalization.smul_bijective S (commonDenom M s f)).injective.eq_iff, ← map_integerMultiple M s f i, ← map_integerMultiple M s f j, h] +@[deprecated (since := "2026-07-18")] alias integerMultipleMultiple_injective := + integerMultiple_injective + /-- A choice of a common multiple of the denominators of a finite set of fractions. -/ noncomputable def commonDenomOfFinset (s : Finset S) : M := commonDenom M s id @@ -156,7 +159,7 @@ theorem finsetIntegerMultiple_image [DecidableEq R] (s : Finset S) : @[simp] theorem card_finsetIntegerMultiple [DecidableEq R] (s : Finset S) : (finsetIntegerMultiple M s).card = s.card := - (Finset.card_image_of_injective _ (integerMultipleMultiple_injective M s id injective_id)).trans + (Finset.card_image_of_injective _ (integerMultiple_injective M s id injective_id)).trans Finset.card_attach end IsLocalization From eba3d887fc52c98627f4b81507c0efc3096e91b9 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Tue, 21 Jul 2026 05:20:29 +0000 Subject: [PATCH 0903/1300] chore(Algebra/ModuleCat):generalize projective dimension results to `Ring` (#41969) In this PR we generalize projective dimension results about `ModuleCat` to `Ring`, also adding a better doc. --- .../ModuleCat/Ext/DimensionShifting.lean | 2 +- .../ModuleCat/ProjectiveDimension.lean | 24 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Ext/DimensionShifting.lean b/Mathlib/Algebra/Category/ModuleCat/Ext/DimensionShifting.lean index 6362c36c84d3a1..90bea29d9f7f83 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Ext/DimensionShifting.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Ext/DimensionShifting.lean @@ -22,7 +22,7 @@ public section universe v u -variable {R : Type u} [CommRing R] +variable {R : Type u} [Ring R] variable {M : Type v} [AddCommGroup M] [Module R M] {N : Type v} [AddCommGroup N] [Module R N] diff --git a/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean b/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean index 45e18839de5af7..de496361c2c1be 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean @@ -14,13 +14,33 @@ public import Mathlib.CategoryTheory.Abelian.Projective.Dimension # Projective Dimension in ModuleCat +This file deals with preservation of `projectiveDimension` in (semi) linear equivalences. +Previously we only know this for linear equivalence within same universe level, now it works with +all universe level where the ring `R` is small. + +## Main Results + +* `ModuleCat.hasProjectiveDimensionLE_of_semiLinearEquiv`: a module `N` satisfy + `HasProjectiveDimensionLE N n` if it is semi-linear equivalent to a module `M` that + `HasProjectiveDimensionLE M n`. + +* `ModuleCat.projectiveDimension_eq_of_semiLinearEquiv`: `projectiveDimension` is preserved + under arbitrary semi-linear equivalence. + +* `ModuleCat.hasProjectiveDimensionLE_of_linearEquiv`: a module `N` satisfy + `HasProjectiveDimensionLE N n` if it is linear equivalent to a module `M` that + `HasProjectiveDimensionLE M n`. + +* `ModuleCat.projectiveDimension_eq_of_linearEquiv`: `projectiveDimension` is preserved + under arbitrary linear equivalence. + -/ public section universe v v' u u' -variable {R : Type u} [CommRing R] +variable {R : Type u} [Ring R] open CategoryTheory Abelian Module @@ -28,7 +48,7 @@ namespace ModuleCat section -variable [Small.{v} R] {R' : Type u'} [CommRing R'] [Small.{v'} R'] (e : R ≃+* R') +variable [Small.{v} R] {R' : Type u'} [Ring R'] [Small.{v'} R'] (e : R ≃+* R') variable {M : ModuleCat.{v} R} {N : ModuleCat.{v'} R'} From 3ad2bbaa4afbcac3bf0f30c13ec558ecc9217eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 21 Jul 2026 09:18:46 +0000 Subject: [PATCH 0904/1300] feat: correspondence between affine group schemes and Hopf algebras (#40500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Construct `Spec` as a functor from `R`-Hopf algebras to group schemes over `Spec R`, show it is full and faithful and has affine group schemes as essential image. From Toric, FLT Co-authored-by: Andrew Yang Co-authored-by: Michał Mrugała Co-authored-by: Christian Merten --- Mathlib.lean | 1 + Mathlib/AlgebraicGeometry/Group/Affine.lean | 489 ++++++++++++++++++ Mathlib/AlgebraicGeometry/Scheme.lean | 2 +- .../RingTheory/Bialgebra/TensorProduct.lean | 17 + Mathlib/RingTheory/TensorProduct/Maps.lean | 51 ++ 5 files changed, 559 insertions(+), 1 deletion(-) create mode 100644 Mathlib/AlgebraicGeometry/Group/Affine.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0e66be08e499e5..940bafeb31283a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1390,6 +1390,7 @@ public import Mathlib.AlgebraicGeometry.Geometrically.Reduced public import Mathlib.AlgebraicGeometry.Gluing public import Mathlib.AlgebraicGeometry.GluingOneHypercover public import Mathlib.AlgebraicGeometry.Group.Abelian +public import Mathlib.AlgebraicGeometry.Group.Affine public import Mathlib.AlgebraicGeometry.Group.Smooth public import Mathlib.AlgebraicGeometry.IdealSheaf.Basic public import Mathlib.AlgebraicGeometry.IdealSheaf.Functorial diff --git a/Mathlib/AlgebraicGeometry/Group/Affine.lean b/Mathlib/AlgebraicGeometry/Group/Affine.lean new file mode 100644 index 00000000000000..f35aa382472e43 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/Group/Affine.lean @@ -0,0 +1,489 @@ +/- +Copyright (c) 2025 Yaël Dillies, Christian Merten, Michał Mrugała, Andrew Yang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies, Christian Merten, Michał Mrugała, Andrew Yang +-/ +module + +public import Mathlib.Algebra.Category.CommHopfAlgCat +public import Mathlib.AlgebraicGeometry.Morphisms.FiniteType +public import Mathlib.CategoryTheory.Monoidal.Cartesian.CommGrp_ +public import Mathlib.RingTheory.Bialgebra.TensorProduct + +/-! +# The equivalence between Hopf algebras and affine group schemes + +This file constructs `Spec` as a functor from `R`-Hopf algebras to group schemes over `Spec R`, +shows it is full and faithful, and has affine group schemes as essential image. + +We want to show that affine group schemes correspond to Hopf algebras. This can easily be done +categorically assuming both categories on either side are defined thoughtfully. However, the +categorical version will not be workable with if we do not also have links to the non-categorical +notions. Therefore, one solution would be to build the left, top and right edges of the following +diagram so that the bottom edge can be obtained by composing the three. + +``` + Cogrp Mod_R ≌ Grp AffSch_{Spec R} ≌ Aff Grp Sch_{Spec R} + ↑ ↓ ↑ ↓ +R-Hopf algebras ⇄ Affine group schemes over Spec R +``` + +If we do not care about going back from affine group schemes over `Spec R` to `R`-Hopf algebras +(e.g. because all our affine group schemes are given as the `Spec` of some algebra), then we can +follow the following simpler diagram: + +``` + Cogrp Mod_R ⥤ Grp Sch_{Spec R} + ↑ ↓ ↓ +R-Hopf algebras → Affine group schemes over Spec R +``` +where the top `⥤` comes from the essentially surjective functor `Cogrp Mod_R ⥤ Grp Sch_{Spec R}`, +so that in particular we do not easily know that its inverse is given by `Γ`. +-/ + +@[expose] public section + +suppress_compilation + +open AlgebraicGeometry Coalgebra Scheme CategoryTheory MonoidalCategory CartesianMonoidalCategory + Functor Monoidal Opposite TensorProduct MonObj GrpObj +open Limits hiding prodComparison + +universe w v u +variable {R : CommRingCat.{u}} + +/-! +### Left edge: `R`-Hopf algebras correspond to cogroup objects under `R` + +Ways to turn an unbundled `R`-Hopf algebra into a bundled cogroup object under `R`, and vice versa, +are already provided in `Mathlib.Algebra.Category.CommHopfAlgCat`. + +### Top edge: `Spec` as a functor on Hopf algebras + +In this section we bundle `Spec` as a functor from `R`-Hopf algebras to affine group schemes over +`Spec R`. +-/ + +namespace AlgebraicGeometry + +section topEdge + +variable (R) in +/-- `Spec` as a functor from `R`-algebras to schemes over `Spec R`. -/ +@[implicit_reducible] def algSpec : (CommAlgCat R)ᵒᵖ ⥤ Over (Spec R) := + (commAlgCatEquivUnder R).op.functor ⋙ (Over.opEquivOpUnder R).inverse ⋙ Over.post Scheme.Spec + +variable (R) in +/-- The Gamma functor as a functor from schemes over `Spec R` to `R`-algebras. -/ +@[implicit_reducible] def algΓ : Over (Spec R) ⥤ (CommAlgCat R)ᵒᵖ := + Over.post Γ.rightOp ⋙ Over.map (ΓSpecIso R).inv.op ⋙ + (Over.opEquivOpUnder R).functor ⋙ (commAlgCatEquivUnder R).inverse.op + +instance preservesLimitsOfSize_algSpec : PreservesLimitsOfSize.{w, v} (algSpec R) := + inferInstanceAs <| PreservesLimitsOfSize.{w, v} <| + (commAlgCatEquivUnder R).op.functor ⋙ (Over.opEquivOpUnder R).inverse ⋙ Over.post Scheme.Spec + +set_option backward.isDefEq.respectTransparency false in +instance preservesColimitsOfSize_algΓ : PreservesColimitsOfSize.{w, v} (algΓ R) := by + unfold algΓ; infer_instance + +@[simp] lemma algSpec_obj_hom (X : (CommAlgCat R)ᵒᵖ) : + ((algSpec R).obj X).hom = Spec.map (CommRingCat.ofHom (algebraMap R X.unop)) := rfl + +@[simp] lemma algSpec_map_left {X Y : (CommAlgCat R)ᵒᵖ} (f : X ⟶ Y) : + ((algSpec R).map f).left = Spec.map ((commAlgCatEquivUnder R).functor.map f.unop).right := rfl + +lemma preservesTerminalIso_algSpec : + preservesTerminalIso (algSpec R) = Over.isoMk (.refl (Spec R)) := by + ext : 1; exact toUnit_unique .. + +@[simp] lemma preservesTerminalIso_algSpec_inv_left : + (preservesTerminalIso (algSpec R)).inv.left = 𝟙 (Spec R) := by + rw [preservesTerminalIso_algSpec]; rfl + +@[simp] +lemma prodComparison_algSpec_left (X Y : (CommAlgCat R)ᵒᵖ) : + (prodComparison (algSpec R) X Y).left = (pullbackSpecIso R X.unop Y.unop).inv := rfl + +@[simp] +lemma prodComparisonIso_algSpec_inv_left (X Y : (CommAlgCat R)ᵒᵖ) : + (prodComparisonIso (algSpec R) X Y).inv.left = (pullbackSpecIso R X.unop Y.unop).hom := by + have : (Over.forget (Spec R)).mapIso (prodComparisonIso (algSpec R) X Y) = + (pullbackSpecIso R X.unop Y.unop).symm := + Iso.ext (prodComparison_algSpec_left X Y) + exact congrArg Iso.inv this + +attribute [local simp] ε_of_cartesianMonoidalCategory μ_of_cartesianMonoidalCategory in +set_option backward.isDefEq.respectTransparency false in +/-- `Spec` as a functor from `R`-algebras to schemes over `Spec R` is braided. + +The monoidal data is copied from `Functor.Braided.ofChosenFiniteProducts` so that `ε`, `η` are +definitionally `𝟙 (Spec R)` and `μ`, `δ` are definitionally `pullbackSpecIso`. -/ +instance braidedAlgSpec : (algSpec R).Braided := + .copy (.ofChosenFiniteProducts _) + (Over.homMk <| 𝟙 <| Spec R) + (fun X Y ↦ Over.homMk (pullbackSpecIso R X.unop Y.unop).hom) + (Over.homMk <| 𝟙 <| Spec R) + (fun X Y ↦ Over.homMk (pullbackSpecIso R X.unop Y.unop).inv <| by + simpa using Over.w (prodComparison (algSpec R) X Y)) + (Over.OverMorphism.ext (by simp)) + (funext fun X ↦ funext fun Y ↦ Over.OverMorphism.ext (by simp)) + (Over.OverMorphism.ext (by + rw [Functor.OplaxMonoidal.η_of_cartesianMonoidalCategory, ← preservesTerminalIso_hom, + preservesTerminalIso_algSpec]; rfl)) + (funext fun X ↦ funext fun Y ↦ Over.OverMorphism.ext (by + rw [Functor.OplaxMonoidal.δ_of_cartesianMonoidalCategory, prodComparison_algSpec_left]; rfl)) + +@[simp] lemma ε_algSpec_left : (LaxMonoidal.ε (algSpec R)).left = 𝟙 (Spec R) := rfl +@[simp] lemma η_algSpec_left : (OplaxMonoidal.η (algSpec R)).left = 𝟙 (Spec R) := rfl + +@[simp] lemma δ_algSpec_left (X Y : (CommAlgCat R)ᵒᵖ) : + (OplaxMonoidal.δ (algSpec R) X Y).left = (pullbackSpecIso R X.unop Y.unop).inv := rfl + +@[simp] lemma μ_algSpec_left (X Y : (CommAlgCat R)ᵒᵖ) : + (LaxMonoidal.μ (algSpec R) X Y).left = (pullbackSpecIso R X.unop Y.unop).hom := rfl + +/-- `Spec` is full on `R`-algebras. -/ +instance algSpec.instFull : (algSpec R).Full := + inferInstanceAs <| Functor.Full <| + (commAlgCatEquivUnder R).op.functor ⋙ (Over.opEquivOpUnder R).inverse ⋙ Over.post Scheme.Spec + +/-- `Spec` is faithful on `R`-algebras. -/ +instance algSpec.instFaithful : (algSpec R).Faithful := + inferInstanceAs <| Functor.Faithful <| + (commAlgCatEquivUnder R).op.functor ⋙ (Over.opEquivOpUnder R).inverse ⋙ Over.post Scheme.Spec + +/-- `Spec` is fully faithful on `R`-algebras, with inverse `Gamma`. -/ +def algSpec.fullyFaithful : (algSpec R).FullyFaithful := + ((commAlgCatEquivUnder R).op.trans (Over.opEquivOpUnder R).symm).fullyFaithfulFunctor.comp <| + Spec.fullyFaithful.over _ + +variable (R) in +/-- `Spec` as a functor from `R`-bialgebras to monoid schemes over `Spec R`. -/ +abbrev bialgSpec : (CommBialgCat R)ᵒᵖ ⥤ Mon (Over <| Spec R) := + (commBialgCatEquivComonCommAlgCat R).functor.leftOp ⋙ (algSpec R).mapMon + +/-- `Spec` is full on `R`-bialgebras. -/ +instance bialgSpec.instFull : (bialgSpec R).Full := inferInstance + +/-- `Spec` is faithful on `R`-bialgebras. -/ +instance bialgSpec.instFaithful : (bialgSpec R).Faithful := inferInstance + +/-- `Spec` is fully faithful on `R`-bialgebras, with inverse `Gamma`. -/ +def bialgSpec.fullyFaithful : (bialgSpec R).FullyFaithful := + (commBialgCatEquivComonCommAlgCat R).fullyFaithfulFunctor.leftOp.comp algSpec.fullyFaithful.mapMon + +variable (R) in +/-- `Spec` as a functor from `R`-Hopf algebras to group schemes over `Spec R`. -/ +abbrev hopfSpec : (CommHopfAlgCat R)ᵒᵖ ⥤ Grp (Over <| Spec R) := + (commHopfAlgCatEquivCogrpCommAlgCat R).functor.leftOp ⋙ (algSpec R).mapGrp + +/-- `Spec` is full on `R`-Hopf algebras. -/ +instance hopfSpec.instFull : (hopfSpec R).Full := inferInstance + +/-- `Spec` is faithful on `R`-Hopf algebras. -/ +instance hopfSpec.instFaithful : (hopfSpec R).Faithful := inferInstance + +/-- `Spec` is fully faithful on `R`-Hopf algebras, with inverse `Gamma`. -/ +def hopfSpec.fullyFaithful : (hopfSpec R).FullyFaithful := + (commHopfAlgCatEquivCogrpCommAlgCat R).fullyFaithfulFunctor.leftOp.comp + algSpec.fullyFaithful.mapGrp + +section universe_polymorphic +variable {R A : CommRingCat.{u}} + +-- Note that this creates a diamond with `instOverClass`. We keep it for convenience. +-- Once `OverClass` is refactored (see https://github.com/leanprover-community/mathlib4/pull/41542), +-- the diamond will be downgraded to the invariant about the `outParam` argument of `OverClass` +-- being determined by the first two arguments being broken. +@[simps -isSimp] +instance specOverSpec [Algebra R A] : (Spec A).Over (Spec R) where + hom := Spec.map <| CommRingCat.ofHom <| algebraMap .. + +instance locallyOfFiniteType_specOverSpec [Algebra R A] [Algebra.FiniteType R A] : + LocallyOfFiniteType (Spec A ↘ Spec R) := by + rw [specOverSpec_over, HasRingHomProperty.Spec_iff (P := @LocallyOfFiniteType)] + simpa [RingHom.finiteType_algebraMap] + +attribute [local simp] AlgHom.toUnder in +@[simps! one] +instance instMonObjSpecAsOverSpec [Bialgebra R A] : MonObj ((Spec A).asOver (Spec R)) := + ((bialgSpec R).obj <| .op <| .of R A).mon + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +lemma one_spec_asOver_spec [Bialgebra R A] : + η[(Spec A).asOver (Spec R)] = LaxMonoidal.ε (algSpec R) ≫ + Over.homMk (V := (Spec A).asOver (Spec R)) + (Spec.map <| CommRingCat.ofHom <| Bialgebra.counitAlgHom R A) + (by simp [specOverSpec_over, ← Spec.map_comp, ← CommRingCat.ofHom_comp, + CommRingCat.of_carrier]) := rfl + +lemma one_spec_asOver_spec_left [Bialgebra R A] : + η[(Spec A).asOver (Spec R)].left = + (Spec.map <| CommRingCat.ofHom <| Bialgebra.counitAlgHom R A) := rfl + +lemma mul_spec_asOver_spec_left [Bialgebra R A] : + μ[(Spec A).asOver (Spec R)].left = + (pullbackSpecIso R A A).hom ≫ Spec.map (CommRingCat.ofHom (Bialgebra.comulAlgHom R A)) := rfl + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +instance isCommMonObj_spec_asOver_spec [Bialgebra R A] [IsCocomm R A] : + IsCommMonObj ((Spec A).asOver (Spec R)) where + mul_comm := by + ext + have := congr((pullbackSpecIso R A A).hom ≫ ((bialgSpec R).map <| .op <| CommBialgCat.ofHom <| + $(Bialgebra.comm_comp_comulBialgHom (R := R) (A := A))).hom.left) + dsimp [commBialgCatEquivComonCommAlgCat] at this ⊢ + have h₁ : (Algebra.TensorProduct.includeRight : A →ₐ[R] A ⊗[R] A) = + (RingHomClass.toRingHom (Bialgebra.TensorProduct.comm R A A)).comp + Algebra.TensorProduct.includeLeftRingHom := rfl + have h₂ : (Algebra.TensorProduct.includeLeftRingHom) = + (RingHomClass.toRingHom (Bialgebra.TensorProduct.comm R A A)).comp + (Algebra.TensorProduct.includeRight : A →ₐ[R] A ⊗[R] A) := rfl + convert! this using 1 + simp only [mul_spec_asOver_spec_left, ← Category.assoc, algSpec, Equivalence.op_functor, + comp_obj, op_obj, commAlgCatEquivUnder_functor_obj, Over.opEquivOpUnder_inverse_obj, + CommRingCat.mkUnder_hom, Over.post_obj, Spec_obj, Over.mk_left, Over.mk_hom, Spec_map, + Quiver.Hom.unop_op, Spec.map_comp] + congr 1 + rw [← Iso.eq_comp_inv, Category.assoc, ← Iso.inv_comp_eq] + ext + · simp [AlgHom.toUnder, specOverSpec, over, OverClass.hom, h₁]; rfl + · simp [AlgHom.toUnder, specOverSpec, over, OverClass.hom, h₂]; rfl + +instance instGrpObjSpecAsOverSpec [HopfAlgebra R A] : GrpObj ((Spec A).asOver (Spec R)) where + __ := instMonObjSpecAsOverSpec + __ := ((hopfSpec R).obj <| .op <| .of R A).grp + +instance instCommGrpObjSpecAsOverSpec [HopfAlgebra R A] [IsCocomm R A] : + CommGrpObj ((Spec A).asOver (Spec R)) where + +instance {R S T : Type u} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] + (f : S →ₐ[R] T) : (Spec.map (CommRingCat.ofHom f.toRingHom)).IsOver (Spec (.of R)) where + comp_over := by simp [specOverSpec_over, ← Spec.map_comp, ← CommRingCat.ofHom_comp] + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +/-- `Spec.map` as a `MulEquiv` on hom-sets. -/ +def Spec.mapMulEquiv {R S T : Type u} [CommRing R] [CommRing S] [CommRing T] [Bialgebra R S] + [Algebra R T] : + WithConv (S →ₐ[R] T) ≃* + ((Spec (.of T)).asOver (Spec (.of R)) ⟶ (Spec (.of S)).asOver (Spec (.of R))) where + toFun f := (Spec.map (CommRingCat.ofHom f.ofConv.toRingHom)).asOver _ + invFun f := ⟨(Spec.preimage f.left).hom, by + suffices CommRingCat.ofHom (algebraMap R S) ≫ Spec.preimage f.left = + CommRingCat.ofHom (algebraMap R T) from fun r ↦ congr($this r) + apply Spec.map_injective + simpa [-comp_over] using! f.w⟩ + left_inv f := by + apply WithConv.ofConv_injective + apply AlgHom.coe_ringHom_injective + simp + right_inv f := by ext1; simp + map_mul' f g := by + ext1 + dsimp [AlgHom.convMul_def, AlgHom.comp_toRingHom, Hom.mul_def] + simp only [← Category.assoc, Spec.map_comp, mul_spec_asOver_spec_left] + congr 1 + rw [← Iso.comp_inv_eq] + ext + all_goals + · simp only [specOverSpec_over, ← Spec.map_comp, ← CommRingCat.ofHom_comp, + ← AlgHom.comp_toRingHom, Category.assoc, pullbackSpecIso_inv_fst, pullbackSpecIso_inv_snd, + limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app] + congr 3 + ext; simp + +/-- The adjunction between `Spec` and `Γ` as functors between commutative `R`-algebras and +schemes over `Spec R`. -/ +def algΓAlgSpecAdjunction (R : CommRingCat) : algΓ R ⊣ algSpec R := by + have overAdjunction := Over.postAdjunctionRight (Y := .op <| R) ΓSpec.adjunction + have overEquivAlg := ((Over.opEquivOpUnder R).trans (commAlgCatEquivUnder R).op.symm).toAdjunction + simpa using! overAdjunction.comp overEquivAlg + +end universe_polymorphic + +section universe_monomorphic +variable {R A : CommRingCat.{u}} {X M G : Scheme.{u}} + +/-- The global sections of an affine scheme over `Spec R` are a `R`-algebra. -/ +instance [X.Over (Spec R)] [IsAffine X] : Algebra R Γ(X, ⊤) := + ((commAlgCatEquivUnder R).inverse.obj <| + .mk (Spec.fullyFaithful.preimage <| X.isoSpec.inv ≫ X ↘ Spec R).unop).algebra + +lemma algebraMap_presheafObj [X.Over (Spec R)] [IsAffine X] : + algebraMap R Γ(X, ⊤) = (Spec.fullyFaithful.preimage <| X.isoSpec.inv ≫ X ↘ Spec R).unop.hom := + rfl + +attribute [local simp] specOverSpec_over algebraMap_presheafObj in +attribute [-simp] Hom.isOver_iff in +instance [X.Over (Spec R)] [IsAffine X] : X.toSpecΓ.IsOver (Spec R) where + +instance [X.Over (Spec R)] [IsAffine X] : X.isoSpec.hom.IsOver (Spec R) := + inferInstanceAs (X.toSpecΓ.IsOver (Spec R)) + +/-- The global sections of an affine monoid scheme over `Spec R` are a `R`-bialgebra. -/ +instance [M.Over (Spec R)] [MonObj (M.asOver (Spec R))] [IsAffine M] : + Bialgebra R Γ(M, ⊤) := by + have : MonObj ((algSpec R).obj <| .op <| CommAlgCat.of R Γ(M, ⊤)) := + .ofIso <| M.isoSpec.asOver (Spec R) + have : MonObj (op <| CommAlgCat.of R Γ(M, ⊤)) := algSpec.fullyFaithful.monObj _ + exact ((commBialgCatEquivComonCommAlgCat R).inverse.obj <| + .op <| .mk <| .op <| .of R Γ(M, ⊤)).bialgebra + +/-- The global sections of an affine group scheme over `Spec R` are a `R`-Hopf algebra. -/ +instance [G.Over (Spec R)] [GrpObj (G.asOver (Spec R))] [IsAffine G] : + HopfAlgebra R Γ(G, ⊤) := by + have : GrpObj ((algSpec R).obj <| .op <| CommAlgCat.of R Γ(G, ⊤)) := + .ofIso <| G.isoSpec.asOver (Spec R) + have : GrpObj (op <| CommAlgCat.of R Γ(G, ⊤)) := algSpec.fullyFaithful.grpObj _ + exact ((commHopfAlgCatEquivCogrpCommAlgCat R).inverse.obj <| + .op <| .mk <| .op <| .of R Γ(G, ⊤)).hopfAlgebra + +variable {R S T : Type u} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] + +open TensorProduct Algebra.TensorProduct CommRingCat RingHomClass + +variable (R S T) in +/-- The isomorphism between the fiber product of two schemes `Spec S` and `Spec T` +over a scheme `Spec R` and the `Spec` of the tensor product `S ⊗[R] T`. + +This is a version of `pullbackSpecIso` stated in terms of `specOverSpec`. +TODO: Unify with `pullbackSpecIso` once `OverClass` is refactored to not bundle the morphism. -/ +def pullbackSpecIso' [Algebra R T] : + pullback (Spec (.of S) ↘ Spec (.of R)) (Spec (.of T) ↘ Spec (.of R)) ≅ + Spec (.of <| S ⊗[R] T) := pullbackSpecIso .. + +set_option backward.defeqAttrib.useBackward true in +lemma pullbackSpecIso'_symmetry [Algebra R T] : + (pullbackSymmetry .. ≪≫ pullbackSpecIso' R S T).hom = + (pullbackSpecIso' ..).hom ≫ + Spec.map (CommRingCat.ofHom (Algebra.TensorProduct.comm R S T)) := by + simp_rw [Iso.trans_hom, ← Iso.eq_comp_inv, Category.assoc, ← Iso.inv_comp_eq] + ext + · have : (RingHomClass.toRingHom (Algebra.TensorProduct.comm R S T)).comp + Algebra.TensorProduct.includeLeftRingHom = + RingHomClass.toRingHom Algebra.TensorProduct.includeRight := rfl + rw [Category.assoc, pullbackSymmetry_hom_comp_fst] + simp only [pullbackSpecIso', specOverSpec_over, pullbackSpecIso_inv_snd, Category.assoc, + pullbackSpecIso_inv_fst, ← Spec.map_comp, ← CommRingCat.ofHom_comp, this] + have : (RingHomClass.toRingHom (Algebra.TensorProduct.comm R S T)).comp + (RingHomClass.toRingHom Algebra.TensorProduct.includeRight) = + Algebra.TensorProduct.includeLeftRingHom := rfl + rw [Category.assoc, pullbackSymmetry_hom_comp_snd] + simp only [pullbackSpecIso', specOverSpec_over, pullbackSpecIso_inv_fst, Category.assoc, + pullbackSpecIso_inv_snd, ← Spec.map_comp, ← CommRingCat.ofHom_comp, this] + +set_option backward.defeqAttrib.useBackward true in +instance [Algebra R T] : + (pullbackSymmetry .. ≪≫ pullbackSpecIso' R S T).hom.IsOver (Spec (.of S)) where + comp_over := by + rw [← cancel_epi (pullbackSymmetry .. ≪≫ pullbackSpecIso' ..).inv, + Scheme.canonicallyOverPullback_over, Iso.inv_hom_id_assoc, Iso.trans_inv, Category.assoc, + pullbackSymmetry_inv_comp_snd] + exact (pullbackSpecIso_inv_fst ..).symm + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +set_option linter.flexible false in +-- The `simp` calls are non-terminal merely because the `erw` calls are necessary. +-- If this proof breaks because of a non-terminal `simp` in the future, it is likely that one can +-- simply remove the following `erw`. +variable (R S T) in +lemma μ_pullback_left_fst [Algebra R T] : + (LaxMonoidal.μ (Over.pullback (Spec.map (CommRingCat.ofHom (algebraMap R S)))) + (Over.mk (Spec.map (CommRingCat.ofHom (algebraMap R T)))) + (Over.mk (Spec.map (CommRingCat.ofHom (algebraMap R T))))).left ≫ + pullback.fst _ _ = + (((pullbackSymmetry .. ≪≫ pullbackSpecIso' R S T).hom.asOver (Spec (.of S)) ⊗ₘ + ((pullbackSymmetry .. ≪≫ pullbackSpecIso' R S T).hom.asOver (Spec (.of S)))).left) ≫ + (pullbackSpecIso S (S ⊗[R] T) (S ⊗[R] T)).hom ≫ + Spec.map (CommRingCat.ofHom (Algebra.TensorProduct.mapRingHom (algebraMap _ _) + Algebra.TensorProduct.includeRight.toRingHom + Algebra.TensorProduct.includeRight.toRingHom + (by simp [← IsScalarTower.algebraMap_eq]) + (by simp [← IsScalarTower.algebraMap_eq]))) ≫ (pullbackSpecIso R T T).inv := by + simp + ext <;> simp + · simp only [← Spec.map_comp, ← CommRingCat.ofHom_comp, + Algebra.TensorProduct.mapRingHom_comp_includeLeftRingHom] + simp [specOverSpec_over] + erw [Over.tensorHom_left_fst_assoc] + simp [pullbackSpecIso'] + rfl + · simp only [← Spec.map_comp, ← CommRingCat.ofHom_comp, + Algebra.TensorProduct.mapRingHom_comp_includeRight] + simp [specOverSpec_over] + erw [Over.tensorHom_left_snd_assoc] + simp [pullbackSpecIso'] + rfl + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +instance [Bialgebra R T] : + IsMonHom <| (pullbackSymmetry .. ≪≫ pullbackSpecIso' R S T).hom.asOver (Spec (.of S)) where + one_hom := by + ext + rw [← cancel_mono (pullbackSpecIso' ..).inv] + ext + · simp [Scheme.monObjAsOverPullback_one, ε_algSpec_left (R := CommRingCat.of _), + pullbackSpecIso', specOverSpec_over, ← Spec.map_comp, ← CommRingCat.ofHom_comp, + AlgHom.toUnder, Under.homMk_right, Bialgebra.TensorProduct.counitAlgHom_def, + AlgHom.comp_toRingHom, RingHom.comp_assoc] + · simp [Scheme.monObjAsOverPullback_one, ε_algSpec_left (R := CommRingCat.of _), + pullbackSpecIso', specOverSpec_over, ← Spec.map_comp, ← CommRingCat.ofHom_comp, + AlgHom.toUnder, Under.homMk_right, + ← AlgHom.coe_restrictScalars R (Bialgebra.counitAlgHom S _), -AlgHom.coe_restrictScalars, + ← AlgHom.comp_toRingHom, Bialgebra.counitAlgHom_comp_includeRight] + simp [AlgHom.comp_toRingHom, Algebra.toRingHom_ofId] + mul_hom := by + ext + rw [← cancel_mono (pullbackSpecIso' ..).inv] + ext + · have : includeLeftRingHom = algebraMap S (S ⊗[R] T) := rfl + simp [Scheme.monObjAsOverPullback_mul, pullbackSpecIso', specOverSpec_over, ← Spec.map_comp, + ← CommRingCat.ofHom_comp, OverClass.asOver, mul_spec_asOver_spec_left, this, Hom.asOver, + OverClass.asOverHom, pullback.condition] + rfl + · convert! congr($(μ_pullback_left_fst R S T) ≫ (pullbackSpecIso R T T).hom ≫ + Spec.map (CommRingCat.ofHom (Bialgebra.comulAlgHom R T).toRingHom)) using 1 + · simp [Scheme.monObjAsOverPullback_mul, pullbackSpecIso', specOverSpec_over, + OverClass.asOver, Hom.asOver, OverClass.asOverHom, mul_spec_asOver_spec_left] + · simp [pullbackSpecIso', specOverSpec_over, OverClass.asOver, Hom.asOver, ← Spec.map_comp, + OverClass.asOverHom, mul_spec_asOver_spec_left, ← CommRingCat.ofHom_comp, + ← Bialgebra.comul_includeRight] + +end universe_monomorphic +end topEdge + +/-! +### Right edge: The essential image of `Spec` on Hopf algebras + +In this section we show that the essential image of `R`-Hopf algebras under `Spec` is precisely +affine group schemes over `Spec R`. +-/ + +section rightEdge + +/-- The essential image of `R`-algebras under `Spec` is precisely affine schemes over `Spec R`. -/ +@[simp] +lemma essImage_algSpec {G : Over <| Spec R} : (algSpec R).essImage G ↔ IsAffine G.left := by + simp [algSpec, Functor.essImage_overPost (F := Scheme.Spec)] + +/-- The essential image of `R`-bialgebras under `Spec` is precisely affine monoid schemes over +`Spec R`. -/ +@[simp] +lemma essImage_bialgSpec {G : Mon <| Over <| Spec R} : + (bialgSpec R).essImage G ↔ IsAffine G.X.left := by simp + +/-- The essential image of `R`-Hopf algebras under `Spec` is precisely affine group schemes over +`Spec R`. -/ +@[simp] +lemma essImage_hopfSpec {G : Grp <| Over <| Spec R} : + (hopfSpec R).essImage G ↔ IsAffine G.X.left := by simp + +end rightEdge + +end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 074704b667aabf..f93f889c2c0f18 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -490,7 +490,7 @@ theorem Spec.map_comp {R S T : CommRingCat} (f : R ⟶ S) (g : S ⟶ T) : Scheme.Hom.ext' <| Spec.locallyRingedSpaceMap_comp f g /-- The spectrum, as a contravariant functor from commutative rings to schemes. -/ -@[simps] +@[simps, implicit_reducible] protected def Scheme.Spec : CommRingCatᵒᵖ ⥤ Scheme where obj R := Spec (unop R) map f := Spec.map f.unop diff --git a/Mathlib/RingTheory/Bialgebra/TensorProduct.lean b/Mathlib/RingTheory/Bialgebra/TensorProduct.lean index f7cab519b0e299..331b5f42784215 100644 --- a/Mathlib/RingTheory/Bialgebra/TensorProduct.lean +++ b/Mathlib/RingTheory/Bialgebra/TensorProduct.lean @@ -247,6 +247,23 @@ def _root_.Coalgebra.Repr.mul {b : A} (ℛ₁ : Coalgebra.Repr R a ι) (ℛ₂ : end Semiring +@[simp] +lemma counitAlgHom_comp_includeRight [CommSemiring A] [Semiring B] [Algebra R A] [Bialgebra R B] : + ((counitAlgHom A (A ⊗[R] B)).restrictScalars R).comp Algebra.TensorProduct.includeRight = + (Algebra.ofId R A).comp (counitAlgHom R B) := by + ext; simp [Algebra.algebraMap_eq_smul_one] + +lemma comul_includeRight [CommSemiring A] [CommSemiring B] [Bialgebra R B] [Algebra R A] : + (RingHomClass.toRingHom (Bialgebra.comulAlgHom A (A ⊗[R] B))).comp + (RingHomClass.toRingHom Algebra.TensorProduct.includeRight) = + (Algebra.TensorProduct.mapRingHom (algebraMap R A) + (RingHomClass.toRingHom (Algebra.TensorProduct.includeRight (A := A))) + (RingHomClass.toRingHom (Algebra.TensorProduct.includeRight (A := A))) + (by simp [← IsScalarTower.algebraMap_eq]) + (by simp [← IsScalarTower.algebraMap_eq])).comp + (RingHomClass.toRingHom (Bialgebra.comulAlgHom R B)) := by + ext x; simp [← (ℛ R x).eq, TensorProduct.tmul_sum] + section CommSemiring variable [CommSemiring A] [Bialgebra R A] diff --git a/Mathlib/RingTheory/TensorProduct/Maps.lean b/Mathlib/RingTheory/TensorProduct/Maps.lean index f0ea4e76927495..ddf98d68e24918 100644 --- a/Mathlib/RingTheory/TensorProduct/Maps.lean +++ b/Mathlib/RingTheory/TensorProduct/Maps.lean @@ -294,6 +294,10 @@ lemma linearMap_comp_rid : (Algebra.linearMap S (S ⊗[R] B)).restrictScalars R (TensorProduct.rid R R S).toLinearMap = (Algebra.linearMap R B).lTensor S := by ext; simp +@[simp] lemma rid_comp_includeLeftRingHom : + (Algebra.TensorProduct.rid R S A : A ⊗[R] R →+* A).comp includeLeftRingHom = .id A := by + ext; simp + section variable (R A B C : Type*) [CommSemiring R] [CommSemiring A] [Algebra R A] [Semiring B] @@ -489,6 +493,49 @@ end variable {R S A} +section mapRingHom +variable {R S T R' S' T' : Type*} + [CommSemiring R] [CommSemiring S] [CommSemiring T] [Algebra R S] [Algebra R T] + [CommSemiring R'] [CommSemiring S'] [CommSemiring T'] [Algebra R' S'] [Algebra R' T'] + (fR : R →+* R') (fS : S →+* S') (fT : T →+* T') + (HS : fS.comp (algebraMap _ _) = (algebraMap _ _).comp fR) + (HT : fT.comp (algebraMap _ _) = (algebraMap _ _).comp fR) + +/-- Heterobasic version of `Algebra.TensorProduct.map` as a ring homomorphism. + +Note that this would generalise `map` if we were to have `SemiAlgHom`. -/ +def mapRingHom : S ⊗[R] T →+* S' ⊗[R'] T' := + letI := fR.toAlgebra + letI := ((algebraMap R' S').comp fR).toAlgebra + letI := ((algebraMap R' T').comp fR).toAlgebra + letI := fS.toAlgebra + letI := fT.toAlgebra + letI : IsScalarTower R R' S' := .of_algebraMap_eq' rfl + letI : IsScalarTower R R' T' := .of_algebraMap_eq' rfl + letI : IsScalarTower R S S' := .of_algebraMap_eq' HS.symm + letI : IsScalarTower R T T' := .of_algebraMap_eq' HT.symm + (lift (R := R) (S := R) (includeLeft.comp (IsScalarTower.toAlgHom R S S')) + ((includeRight.restrictScalars R).comp (IsScalarTower.toAlgHom R T T')) + (fun _ _ ↦ .all _ _)).toRingHom + +@[simp] +lemma mapRingHom_tmul (s : S) (t : T) : mapRingHom fR fS fT HS HT (s ⊗ₜ t) = fS s ⊗ₜ fT t := by + trans (fS s * 1 : S') ⊗ₜ[R'] (1 * fT t : T') + · dsimp [mapRingHom, lift_tmul, algebraMap] + · simp + +@[simp] +lemma mapRingHom_comp_includeLeftRingHom : + (mapRingHom fR fS fT HS HT).comp (includeLeftRingHom) = includeLeftRingHom.comp fS := by + ext; simp + +@[simp] +lemma mapRingHom_comp_includeRight : + (mapRingHom fR fS fT HS HT).comp (RingHomClass.toRingHom includeRight) = + (RingHomClass.toRingHom includeRight).comp fT := by ext; simp + +end mapRingHom + /-- The tensor product of a pair of algebra morphisms. -/ def map (f : A →ₐ[S] C) (g : B →ₐ[R] D) : A ⊗[R] B →ₐ[S] C ⊗[R] D := algHomOfLinearMapTensorProduct (AlgebraTensorModule.map f.toLinearMap g.toLinearMap) (by simp) @@ -524,6 +571,10 @@ theorem map_comp_includeLeft (f : A →ₐ[S] C) (g : B →ₐ[R] D) : (map f g).comp includeLeft = includeLeft.comp f := AlgHom.ext <| by simp +@[simp] lemma map_comp_includeLeftRingHom (f : A →ₐ[S] C) (g : B →ₐ[R] D) : + (map f g : A ⊗[R] B →+* C ⊗[R] D).comp includeLeftRingHom = + includeLeftRingHom.comp (f : A →+* C) := by ext; simp + @[simp] theorem map_restrictScalars_comp_includeRight (f : A →ₐ[S] C) (g : B →ₐ[R] D) : ((map f g).restrictScalars R).comp includeRight = includeRight.comp g := From f2d15f30b3beb63a70672caee898437e0a61e2e9 Mon Sep 17 00:00:00 2001 From: Nicola Falciola Date: Tue, 21 Jul 2026 10:03:44 +0000 Subject: [PATCH 0905/1300] feat(Algebra/FreeAbelianGroup/Finsupp): rw a as sum over the elements in its support (#40288) API for FreeAbelianGroup, a can rw as a sum over the elements in its support --- Mathlib/Algebra/FreeAbelianGroup/Finsupp.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Algebra/FreeAbelianGroup/Finsupp.lean b/Mathlib/Algebra/FreeAbelianGroup/Finsupp.lean index 0cd73de508978d..b0dd2e43443b6d 100644 --- a/Mathlib/Algebra/FreeAbelianGroup/Finsupp.lean +++ b/Mathlib/Algebra/FreeAbelianGroup/Finsupp.lean @@ -151,4 +151,9 @@ theorem support_add (a b : FreeAbelianGroup X) : support (a + b) ⊆ a.support theorem card_support_eq_zero {a : FreeAbelianGroup X} : a.support.card = 0 ↔ a = 0 := by simp +theorem eq_sum_support_coeff_smul_of (a : FreeAbelianGroup X) : + a = ∑ x ∈ a.support, coeff x a • of x := by + conv_lhs => rw [← toFreeAbelianGroup_toFinsupp a, ← sum_single a.toFinsupp] + simp [sum, support, coeff] + end FreeAbelianGroup From 3dfea7c0c262200402250f503f76826c50e08fcd Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Tue, 21 Jul 2026 10:31:09 +0000 Subject: [PATCH 0906/1300] doc(RingTheory/Ideal/IsPrincipal): fix a typo in the module docstring (#41970) --- Mathlib/RingTheory/Ideal/IsPrincipal.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/RingTheory/Ideal/IsPrincipal.lean b/Mathlib/RingTheory/Ideal/IsPrincipal.lean index cb0437b5e43100..0751c30479e538 100644 --- a/Mathlib/RingTheory/Ideal/IsPrincipal.lean +++ b/Mathlib/RingTheory/Ideal/IsPrincipal.lean @@ -16,7 +16,7 @@ This file deals with the set of principal ideals of a `CommRing R`. * `Ideal.isPrincipalSubmonoid`: the submonoid of `Ideal R` formed by the principal ideals of `R`. -* `Ideal.isPrincipalNonZeroDivisorSubmonoid`: the submonoid of `(Ideal R)⁰` formed by the +* `Ideal.isPrincipalNonZeroDivisorsSubmonoid`: the submonoid of `(Ideal R)⁰` formed by the non-zero-divisors principal ideals of `R`. * `Ideal.associatesMulEquivIsPrincipal`: the `MulEquiv` between the monoid of `Associates R` and From 530c505eca7d1431ff06275e3bd377cf940e5c52 Mon Sep 17 00:00:00 2001 From: Bingyu Xia <71547343+BryceT233@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:28:20 +0000 Subject: [PATCH 0907/1300] feat(RingTheory/MvPowerSeries): multivariable power series ring is a noetherian ring when the index is finite (#40205) This is a split of #36507 which includes `isEmptyEquiv`, `optionEquivLeft` and `finSuccEquiv`. We use `finSuccEquiv` to show multivariable power series ring over a noetherian ring is a noetherian ring when the index is finite. --- Mathlib/RingTheory/MvPowerSeries/Equiv.lean | 207 +++++++++++++++++++- 1 file changed, 205 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/MvPowerSeries/Equiv.lean b/Mathlib/RingTheory/MvPowerSeries/Equiv.lean index 1f51936fe63f60..ba3b3f01ed9b36 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Equiv.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Equiv.lean @@ -12,10 +12,22 @@ public import Mathlib.RingTheory.MvPowerSeries.Trunc public import Mathlib.RingTheory.MvPowerSeries.Rename public import Mathlib.RingTheory.PowerSeries.Substitution +import Mathlib.RingTheory.PowerSeries.Ideal + /-! # Equivalences related to power series rings -This file establishes a number of equivalences related to power series rings. +This file establishes a number of equivalences related to power series rings and +is patterned after `Mathlib/Algebra/MvPolynomial/Equiv.lean`. + +* `MvPowerSeries.isEmptyEquiv` : The isomorphism between multivariable power series + in no variables and the ground ring. + +* `MvPowerSeries.optionEquivLeft` : The isomorphism between multivariable power series + in `Option σ` and power series with coefficients in `MvPowerSeries σ R`. + +* `MvPowerSeries.finSuccEquiv` : The isomorphism between multivariable power series + in `Fin (n + 1)` and power series over multivariable power series in `Fin n`. * `MvPowerSeries.toAdicCompletionAlgEquiv` : the canonical isomorphism from multivariate power series to the adic completion of multivariate polynomials @@ -27,8 +39,199 @@ This file establishes a number of equivalences related to power series rings. noncomputable section +open Finsupp Finset Function + namespace MvPowerSeries +section CommSemiring + +variable {σ R : Type*} [CommSemiring R] + +section isEmptyEquiv + +variable (σ R) in +/-- The isomorphism between multivariable power series in no variables and the ground ring. -/ +@[simps!] +def isEmptyEquiv [IsEmpty σ] : MvPowerSeries σ R ≃ₐ[R] R where + __ := constantCoeff + invFun := C + left_inv _ := by ext x; simp [Subsingleton.eq_zero x] + commutes' _ := rfl + +end isEmptyEquiv + +section optionEquivLeft + +variable (R σ) in +/-- Implementation detail for `optionEquivLeft`. Use `MvPowerSeries.optionEquivLeft` instead. -/ +private def optionFunLeft (p : MvPowerSeries (Option σ) R) : PowerSeries (MvPowerSeries σ R) := + .mk fun n ↦ fun x ↦ p.coeff (x.optionElim n) + +set_option backward.isDefEq.respectTransparency false in +private lemma coeff_coeff_optionFunLeft (p : MvPowerSeries (Option σ) R) (n : ℕ) (x : σ →₀ ℕ) : + coeff x (PowerSeries.coeff n (optionFunLeft σ R p)) = coeff (x.optionElim n) p := by + rw [optionFunLeft, PowerSeries.coeff_mk] + exact LinearMap.proj_apply .. + +private theorem optionFunLeft_monomial (x : Option σ →₀ ℕ) (r : R) : + optionFunLeft σ R (monomial x r) = PowerSeries.monomial (x none) (monomial x.some r) := by + classical + ext n y + rw [PowerSeries.coeff_monomial, coeff_coeff_optionFunLeft, coeff_monomial] + split_ifs with h1 h2 h3 + · simp [← h1] + · absurd h2 + rw [← optionElim_apply_none n, h1] + · replace h1 : ¬ y = x.some := fun h ↦ by + absurd h1; ext u + cases u <;> simp_all + rw [coeff_monomial, if_neg h1] + · rw [coeff_zero] + +private lemma optionFunLeft_mul (p q : MvPowerSeries (Option σ) R) : + optionFunLeft σ R (p * q) = optionFunLeft σ R p * optionFunLeft σ R q := by + classical + ext k x + simp only [coeff_coeff_optionFunLeft, coeff_mul, PowerSeries.coeff_mul, map_sum, sum_sigma'] + refine sum_bij (fun y _ ↦ ⟨(y.1 none, y.2 none), (y.1.some, y.2.some)⟩) ?_ ?_ ?_ ?_ + · intros; simp_all [Finsupp.ext_iff] + · intros; ext t <;> cases t + all_goals simp_all [Finsupp.ext_iff] + · rintro ⟨⟨m, n⟩, ⟨u, v⟩⟩ h + suffices ∃ a b, (a none = m ∧ b none = n) ∧ a.some = u ∧ a + b = optionElim k x ∧ + b.some = v by simpa + use u.optionElim m, v.optionElim n + suffices optionElim m u + optionElim n v = optionElim k x by simp_all + ext t; cases t <;> simp_all [Finsupp.ext_iff] + · intros; simp_all [Finsupp.ext_iff] + +variable (R σ) in +/-- An inverse function of `optionFunLeft`. -/ +private def optionInvFunLeft (p : PowerSeries (MvPowerSeries σ R)) : + MvPowerSeries (Option σ) R := fun x ↦ (p.coeff (x none)).coeff x.some + +private lemma coeff_optionInvFunLeft (p : PowerSeries (MvPowerSeries σ R)) (x : Option σ →₀ ℕ) : + coeff x (optionInvFunLeft σ R p) = (p.coeff (x none)).coeff x.some := rfl + +variable (R σ) in +/-- The algebra isomorphism between multivariable power series in `Option σ` and + power series with coefficients in `MvPowerSeries σ R`. -/ +@[no_expose] +def optionEquivLeft : MvPowerSeries (Option σ) R ≃ₐ[R] PowerSeries (MvPowerSeries σ R) where + toFun := optionFunLeft σ R + invFun := optionInvFunLeft σ R + left_inv _ := by ext; simp [coeff_optionInvFunLeft, coeff_coeff_optionFunLeft] + right_inv _ := by ext; simp [coeff_optionInvFunLeft, coeff_coeff_optionFunLeft] + map_mul' := optionFunLeft_mul + map_add' _ _ := by ext; simp [coeff_coeff_optionFunLeft] + commutes' := by + simpa [MvPowerSeries.algebraMap_apply, PowerSeries.C] using + optionFunLeft_monomial (0 : Option σ →₀ ℕ) + +lemma coeff_coeff_optionEquivLeft (p : MvPowerSeries (Option σ) R) (n : ℕ) (x : σ →₀ ℕ) : + coeff x (PowerSeries.coeff n (optionEquivLeft σ R p)) = coeff (x.optionElim n) p := + coeff_coeff_optionFunLeft .. + +theorem optionEquivLeft_monomial (x : Option σ →₀ ℕ) (r : R) : + optionEquivLeft σ R (monomial x r) = PowerSeries.monomial (x none) (monomial x.some r) := + optionFunLeft_monomial .. + +@[simp] +lemma optionEquivLeft_X_some (i : σ) : + optionEquivLeft σ R (X (Option.some i)) = (PowerSeries.C (X i)) := by + have : (optionElim 0 (single i 1)) = single (Option.some i) 1 := by + classical + ext a; cases a <;> simp [single_apply] + simpa [← X_def, PowerSeries.monomial_eq_C_mul_X_pow, this] using + optionEquivLeft_monomial (single (Option.some i) 1 : Option σ →₀ ℕ) (1 : R) + +@[simp] +lemma optionEquivLeft_X_none : optionEquivLeft σ R (X none) = PowerSeries.X := by + simpa [PowerSeries.monomial_eq_C_mul_X_pow, ← X_def] using + optionEquivLeft_monomial (single none 1 : Option σ →₀ ℕ) (1 : R) + +@[simp] +lemma optionEquivLeft_C (r : R) : (optionEquivLeft σ R) (C r) = PowerSeries.C (C r) := by + simpa using optionEquivLeft_monomial (0 : Option σ →₀ ℕ) (r : R) + +end optionEquivLeft + +section finSuccEquiv + +variable {n : ℕ} + +private lemma embDomain_finSuccEquiv_cons {M : Type*} [AddCommMonoid M] {n : ℕ} (i : M) + (x : Fin n →₀ M) : embDomain (finSuccEquiv n).toEmbedding (cons i x) = optionElim i x := by + ext a; cases a <;> simp [embDomain_eq_mapDomain] + +variable (n R) in +/-- The algebra isomorphism between multivariable power series in `Fin (n + 1)` and +power series over multivariable power series in `Fin n`. -/ +def finSuccEquiv : MvPowerSeries (Fin (n + 1)) R ≃ₐ[R] PowerSeries (MvPowerSeries (Fin n) R) := + (renameEquiv R (_root_.finSuccEquiv n)).trans (optionEquivLeft (Fin n) R) + +theorem coeff_coeff_finSuccEquiv (p : MvPowerSeries (Fin (n + 1)) R) {k : ℕ} {x : Fin n →₀ ℕ} : + coeff x (PowerSeries.coeff k (finSuccEquiv R n p)) = coeff (x.cons k) p := by + suffices coeff x (PowerSeries.coeff k (optionEquivLeft (Fin n) R + (rename (_root_.finSuccEquiv n) p))) = coeff (Finsupp.cons k x) p by simpa [finSuccEquiv] + simp_rw [← Equiv.coe_toEmbedding, coeff_coeff_optionEquivLeft, ← embDomain_finSuccEquiv_cons, + coeff_embDomain_rename] + +@[simp] +theorem finSuccEquiv_X_zero : finSuccEquiv R n (X 0) = .X := by + ext k x + simp_rw [coeff_coeff_finSuccEquiv, PowerSeries.coeff_X, coeff_X, cons_eq_single_zero_iff] + split_ifs with h1 h2 h3 + · simp [h1.left] + · tauto + · rw [coeff_one, if_neg (by tauto)] + · rw [coeff_zero] + +@[simp] +theorem finSuccEquiv_X_succ (j : Fin n) : finSuccEquiv R n (X j.succ) = .C (X j) := by + ext k x + simp_rw [coeff_coeff_finSuccEquiv, PowerSeries.coeff_C, coeff_X, cons_eq_single_succ_iff] + split_ifs with h1 h2 h3 + · simp [h1.left] + · tauto + · rw [coeff_X, if_neg (by tauto)] + · rw [coeff_zero] + +@[simp] +theorem finSuccEquiv_C (r : R) : (finSuccEquiv R n) (C r) = PowerSeries.C (C r) := by + ext k x + simp_rw [coeff_coeff_finSuccEquiv, PowerSeries.coeff_C, coeff_C, ← cons_zero_zero, + cons_injective2.eq_iff] + split_ifs with h1 h2 h3 + · simp [h1.right] + · tauto + · rw [coeff_C, if_neg (by tauto)] + · rw [coeff_zero] + +theorem finSuccEquiv_comp_C : (MvPowerSeries.finSuccEquiv R n).symm.toRingHom.comp + (PowerSeries.C.comp MvPowerSeries.C) = MvPowerSeries.C := by + ext1; simp [AlgEquiv.symm_apply_eq] + +variable (S : Type*) [CommRing S] [IsNoetherianRing S] + +private lemma isNoetherianRing_fin (n : ℕ) : IsNoetherianRing (MvPowerSeries (Fin n) S) := by + induction n with + | zero => + exact isNoetherianRing_of_ringEquiv S (isEmptyEquiv (Fin 0) S).toRingEquiv.symm + | succ n _ => + exact isNoetherianRing_of_ringEquiv (PowerSeries (MvPowerSeries (Fin n) S)) + (finSuccEquiv S n).toRingEquiv.symm + +instance isNoetherianRing [Finite σ] : IsNoetherianRing (MvPowerSeries σ S) := by + cases nonempty_fintype σ + have := isNoetherianRing_fin S (Fintype.card σ) + exact isNoetherianRing_of_ringEquiv (MvPowerSeries (Fin (Fintype.card σ)) S) + (renameEquiv S (Fintype.equivFin σ)).toRingEquiv.symm + +end finSuccEquiv + +end CommSemiring + section toAdicCompletion open Finsupp @@ -165,7 +368,7 @@ section toMvPowerSeries variable {R σ τ : Type*} [CommSemiring R] {f : PowerSeries R} (i : σ) (r : R) -open Function PowerSeries Filter Finsupp +open PowerSeries Filter namespace PowerSeries /-- Given a power series `p : R⟦X⟧` and an index `i`, we may view it as a From f02ed541605188aecbda9c6cca3eedd237bd3260 Mon Sep 17 00:00:00 2001 From: ayhon <43295942+ayhon@users.noreply.github.com> Date: Tue, 21 Jul 2026 13:01:32 +0000 Subject: [PATCH 0908/1300] feat: binder plicity code action (#40641) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A code action which allows users to switch between implicit and explicit binders. Developed live during the [Meta Café](https://leanprover.zulipchat.com/#narrow/channel/579629-Event-announcements/topic/The.20Meta.20Caf.C3.A9/with/601800951) with the guidance of @thorimur and various others. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Jon Eugster --- Mathlib.lean | 2 + Mathlib/Init.lean | 2 + Mathlib/Util/CodeActions.lean | 8 +++ Mathlib/Util/CodeActions/BinderPlicity.lean | 61 +++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 Mathlib/Util/CodeActions.lean create mode 100644 Mathlib/Util/CodeActions/BinderPlicity.lean diff --git a/Mathlib.lean b/Mathlib.lean index 940bafeb31283a..ba40b66d79de85 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -8256,6 +8256,8 @@ public import Mathlib.Util.AssertNoSorry public import Mathlib.Util.AtLocation public import Mathlib.Util.AtomM public import Mathlib.Util.AtomM.Recurse +public import Mathlib.Util.CodeActions +public import Mathlib.Util.CodeActions.BinderPlicity public import Mathlib.Util.CompileInductive public import Mathlib.Util.CountHeartbeats public import Mathlib.Util.DelabNonCanonical diff --git a/Mathlib/Init.lean b/Mathlib/Init.lean index 7628dfa0a20bed..be658564cb7a98 100644 --- a/Mathlib/Init.lean +++ b/Mathlib/Init.lean @@ -39,6 +39,8 @@ public import ImportGraph.Tools public import Mathlib.Tactic.Linter.Lint -- This import makes the `#min_imports in` command available globally. public import Mathlib.Tactic.MinImports +-- This import makes the binder plicity code action available globally +public import Mathlib.Util.CodeActions /-! This is the root file in Mathlib: it is imported by virtually *all* Mathlib files. diff --git a/Mathlib/Util/CodeActions.lean b/Mathlib/Util/CodeActions.lean new file mode 100644 index 00000000000000..5ce386109c0a07 --- /dev/null +++ b/Mathlib/Util/CodeActions.lean @@ -0,0 +1,8 @@ +/- +Copyright (c) 2026 Fernando Leal. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Fernando Leal, Thomas Murrills +-/ +module + +public import Mathlib.Util.CodeActions.BinderPlicity diff --git a/Mathlib/Util/CodeActions/BinderPlicity.lean b/Mathlib/Util/CodeActions/BinderPlicity.lean new file mode 100644 index 00000000000000..1a7883d36f8919 --- /dev/null +++ b/Mathlib/Util/CodeActions/BinderPlicity.lean @@ -0,0 +1,61 @@ +/- +Copyright (c) 2026 Fernando Leal. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Fernando Leal, Thomas Murrills +-/ +module + +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. +public import Mathlib.Tactic.Linter.Header -- shake: keep +public meta import Lean.Server.CodeActions.Basic + +/-! +# Binder plicity code action + +A code action that allows one to switch between explicit and implicit binders. + + - `(x : Nat)` turns into `{x : Nat}` + - `{x : nat}` turns into `(x : Nat)` + +## Implementation notes + +We make use of `Syntax.reprint` to transform our new syntax into +a `String`. Since `Syntax.reprint` adds whitespace when working +over synthetic syntax nodes, we produce the new syntax by modifying +the old one instead of creating it from scratch. +-/ + +namespace Mathlib.CodeAction + +public meta section + +open Lean Server Lsp Parser.Term + +/-- A code action to switch between explicit and implicit binders -/ +@[code_action_provider] +def binderPlicity : CodeActionProvider := fun params snap => do + let doc ← RequestM.readDoc + let mkCodeAction kind range newText : LazyCodeAction := { + eager.title := s!"Make {kind}: {newText}" + eager.kind? := "refactor.rewrite" + eager.edit? := some <| .ofTextEdit doc.versionedIdentifier { range, newText } } + let mut codeActions := #[] + for stx in snap.stx.topDown do + let some stxRange := stx.getRange? | continue + let lspRange := doc.meta.text.utf8RangeToLspRange stxRange + unless lspRange.start ≤ params.range.end do continue + unless params.range.start ≤ lspRange.end do continue + if stx.isOfKind ``explicitBinder then + -- This code action does not support explicit binders with optional values + unless stx[3].isNone do continue + let newStx := stx.modifyArg 0 fun lparen => Syntax.atom lparen.getHeadInfo "{" + let newStx := newStx.modifyArg 4 fun rparen => Syntax.atom rparen.getHeadInfo "}" + let some newText := newStx.unsetTrailing.reprint | continue + codeActions := codeActions.push <| mkCodeAction "implicit" lspRange newText + else if stx.isOfKind ``implicitBinder then + let newStx := stx.modifyArg 0 fun lparen => Syntax.atom lparen.getHeadInfo "(" + let newStx := newStx.modifyArg 3 fun rparen => Syntax.atom rparen.getHeadInfo ")" + let some newText := newStx.unsetTrailing.reprint | continue + codeActions := codeActions.push <| mkCodeAction "explicit" lspRange newText + return codeActions From db19808db24fab3f99fc1309a0fe84190ea8f88f Mon Sep 17 00:00:00 2001 From: Pepa Montero Jimena Date: Tue, 21 Jul 2026 13:55:04 +0000 Subject: [PATCH 0909/1300] feat: scalar multiplication by a group element is a diffeomorphism (#41832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define `Diffeomorph.smul`, the diffeomorphism given by scalar multiplication by an element of a group `G` acting Cⁿ-differentiably on a manifold `M` is a diffeomorphism from `M` to itself. Prove `ContMDiffSMul.contMDiff_const_smul`: if the action is `ContMDiffSMul` then for every `g`, `x ↦ g • x` is `Cⁿ`. Also add additive versions of these. Split off from #40727 since it is independently useful. --- Mathlib/Geometry/Manifold/Algebra/SMul.lean | 48 ++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/Algebra/SMul.lean b/Mathlib/Geometry/Manifold/Algebra/SMul.lean index 0f2d1913bd6bb9..9ef32240eec7a5 100644 --- a/Mathlib/Geometry/Manifold/Algebra/SMul.lean +++ b/Mathlib/Geometry/Manifold/Algebra/SMul.lean @@ -1,11 +1,12 @@ /- Copyright (c) 2026 Ben Eltschig. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Ben Eltschig +Authors: Ben Eltschig, Pepa Montero -/ module public import Mathlib.Geometry.Manifold.Algebra.Monoid +public import Mathlib.Geometry.Manifold.Diffeomorph /-! # Cⁿ monoid actions @@ -17,6 +18,9 @@ In this file we define Cⁿ actions (e.g. by Lie groups or monoids) on manifolds We also provide `ContMDiffSMul` instances for scalar multiplication in normed spaces and for the action of the monoid `E →L[𝕜] E` of continuous linear maps on any normed space `E`. +For a group `G` acting smoothly on `M`, we define `Diffeomorph.smul`, scalar multiplication by a +fixed `g : G` as a diffeomorphism of `M` (in analogy to `Homeomorph.smul`). + See also: * `ContMDiffMul I n G` for continuous differentiability of multiplication `G × G → G` in a single type `G`, @@ -137,6 +141,12 @@ theorem ContMDiffOn.smul (hf : CMDiff[s] n f) (hg : CMDiff[s] n g) : theorem ContMDiff.smul (hf : CMDiff n f) (hg : CMDiff n g) : CMDiff n (f • g) := fun x ↦ (hf x).smul (hg x) +-- TODO: after #41534 is merged, weaken the hypothesis to `ContMDiffConstSMul` +@[to_additive] +theorem ContMDiffSMul.contMDiff_const_smul {n : ℕ∞ω} [ContMDiffSMul I I' n G M] (g : G) : + CMDiff n fun x : M ↦ g • x := + contMDiff_const.smul (I := I) contMDiff_id + end @[to_additive prod] @@ -179,3 +189,39 @@ instance {n : ℕ∞ω} : ContMDiffSMul 𝓘(𝕜, E →L[𝕜] E) 𝓘(𝕜, E) (@id ((E →L[𝕜] E) × E)) := by rw [contMDiff_prod_module_iff, ← contMDiff_prod_iff]; exact contMDiff_id exact isBoundedBilinearMap_apply.contDiff.contMDiff.comp h + +section Diffeomorph + +variable [Group G] [MulAction G M] {n : ℕ∞ω} [ContMDiffSMul I I' n G M] (g : G) + +variable (I I' n) in +/-- The diffeomorphism given by scalar multiplication by an element of a group `G` acting +Cⁿ-differentiably on a manifold `M` is a diffeomorphism from `M` to itself. Its inverse is scalar +multiplication by `g⁻¹`. -/ +@[expose, to_additive +/-- The diffeomorphism given by affine-addition of an element of an additive group `G` acting +Cⁿ-differentiably on a manifold `M` is a diffeomorphism from `M` to itself. Its inverse is +addition of `-g`. -/] +def Diffeomorph.smul : M ≃ₘ^n⟮I', I'⟯ M where + toEquiv := MulAction.toPerm g + contMDiff_toFun := ContMDiffSMul.contMDiff_const_smul (I := I) g + contMDiff_invFun := ContMDiffSMul.contMDiff_const_smul (I := I) g⁻¹ + +@[to_additive (attr := simp)] +lemma Diffeomorph.smul_toHomeomorph : + haveI : ContinuousSMul G M := ContMDiffSMul.continuousSMul (I := I) (I' := I') n + (Diffeomorph.smul I I' n g).toHomeomorph = Homeomorph.smul (α := M) g := + rfl + +@[to_additive (attr := simp)] +lemma Diffeomorph.smul_apply (x : M) : Diffeomorph.smul I I' n g x = g • x := rfl + +@[to_additive (attr := simp)] +lemma Diffeomorph.smul_symm_apply (x : M) : (Diffeomorph.smul I I' n g).symm x = g⁻¹ • x := rfl + +@[to_additive] +lemma Diffeomorph.smul_symm : + (Diffeomorph.smul I I' n g : M ≃ₘ^n⟮I', I'⟯ M).symm = Diffeomorph.smul I I' n g⁻¹ := + Diffeomorph.ext fun _ ↦ rfl + +end Diffeomorph From 6e593caa39bbd85e5b437ad7e69eb2e5beb1e0fa Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Tue, 21 Jul 2026 13:55:06 +0000 Subject: [PATCH 0910/1300] chore: make Cartan subalgebra a parameter of `LieAlgebra.Basis` rather than field (#41972) This allows greater definitional control over the Cartan subalgebra which turns out to be very useful in later work. The price is that `LieAlgebra.Basis.isCartanSubalgebra` and `LieAlgebra.Basis.isLieAbelian_cartan` must both be demoted from `instance` to `lemma` but overall the extra definitional control is a big win. --- Mathlib/Algebra/Lie/Basis.lean | 187 ++++++++++-------- .../RootSystem/GeckConstruction/Basis.lean | 8 +- 2 files changed, 108 insertions(+), 87 deletions(-) diff --git a/Mathlib/Algebra/Lie/Basis.lean b/Mathlib/Algebra/Lie/Basis.lean index 8c19d3ebae5487..d4eb96ec95f310 100644 --- a/Mathlib/Algebra/Lie/Basis.lean +++ b/Mathlib/Algebra/Lie/Basis.lean @@ -51,7 +51,8 @@ namespace LieAlgebra /-- A basis for a semisimple Lie algebra distinguishes a natural Cartan subalgebra and a base for the associated root system. -/ @[ext] -structure Basis (ι R L : Type*) [Finite ι] [CommRing R] [LieRing L] [LieAlgebra R L] where +structure Basis (ι : Type*) {R L : Type*} [Finite ι] [CommRing R] [LieRing L] [LieAlgebra R L] + (H : LieSubalgebra R L) where /-- The Cartan matrix. -/ A : Matrix ι ι ℤ /-- The basis for the Cartan subalgebra. -/ @@ -60,9 +61,7 @@ structure Basis (ι R L : Type*) [Finite ι] [CommRing R] [LieRing L] [LieAlgebr e : ι → L /-- The generators of the lower Borel subalgebra. -/ f : ι → L - /-- The span of the `h`, included to give definitional control. -/ - cartan : LieSubalgebra R L - cartan_eq_lieSpan : cartan = lieSpan R L (range h) + cartan_eq_lieSpan : H = lieSpan R L (range h) span_ef : lieSpan R L (range e ∪ range f) = ⊤ linInd : LinearIndependent R h nondegen : A.Nondegenerate @@ -76,7 +75,8 @@ namespace Basis section CommRing -variable {ι R L : Type*} [Finite ι] [CommRing R] [LieRing L] [LieAlgebra R L] (b : Basis ι R L) +variable {ι R L : Type*} [Finite ι] [CommRing R] [LieRing L] [LieAlgebra R L] + {H : LieSubalgebra R L} (b : Basis ι H) @[simp] lemma A_diag_eq_two [IsAddTorsionFree L] (i : ι) : b.A i i = 2 := by have : NoZeroSMulDivisors ℤ L := IsAddTorsionFree.to_noZeroSMulDivisors_int @@ -84,26 +84,26 @@ variable {ι R L : Type*} [Finite ι] [CommRing R] [LieRing L] [LieAlgebra R L] rw [sub_smul, ofNat_smul_eq_nsmul, ← (b.sl2 i).lie_h_e_nsmul, b.lie_h_e i i]; abel rwa [IsAddTorsionFree.zsmul_eq_zero_iff_left (b.sl2 i).e_ne_zero, sub_eq_zero] at aux -@[simp] lemma coe_cartan_eq_span : - b.cartan = Submodule.span R (range b.h) := by - rw [b.cartan_eq_lieSpan] +lemma coe_cartan_eq_span : + H = Submodule.span R (range b.h) := by + conv_lhs => rw [b.cartan_eq_lieSpan] apply coe_lieSpan_eq_span_of_forall_lie_eq_zero rintro - ⟨i, rfl⟩ - ⟨j, rfl⟩ exact b.lie_h_h i j -instance : IsLieAbelian b.cartan := by - rw [cartan_eq_lieSpan, isLieAbelian_lieSpan_iff] +include b in +theorem isLieAbelian_cartan : IsLieAbelian H := by + rw [b.cartan_eq_lieSpan, isLieAbelian_lieSpan_iff] rintro - ⟨i, rfl⟩ - ⟨j, rfl⟩ exact b.lie_h_h i j /-- A basis has a natural involution obtained by interchanging the roles of `e` and `f` and negating `h`. -/ -@[simps -fullyApplied] def symm : Basis ι R L where +@[simps -fullyApplied] def symm : Basis ι H where A := b.A h := -b.h e := b.f f := b.e - cartan := b.cartan cartan_eq_lieSpan := by rw [← neg_range', lieSpan_neg] exact b.cartan_eq_lieSpan @@ -119,17 +119,17 @@ negating `h`. -/ @[simp] lemma symm_symm : b.symm.symm = b := by aesop /-- As shown in `LieAlgebra.Basis.coroot_eq_h'` this is a coroot. -/ -def h' (i : ι) : b.cartan := ⟨b.h i, b.cartan_eq_lieSpan ▸ subset_lieSpan <| mem_range_self i⟩ +def h' (i : ι) : H := ⟨b.h i, b.cartan_eq_lieSpan ▸ subset_lieSpan <| mem_range_self i⟩ @[simp] lemma symm_h' (i : ι) : (b.symm.h' i) = -b.h' i := rfl private lemma cartan_lie_mem_lieSpan_e {x y : L} - (hx : x ∈ b.cartan) (hy : y ∈ lieSpan R L (range b.e)) : + (hx : x ∈ H) (hy : y ∈ lieSpan R L (range b.e)) : ⁅x, y⁆ ∈ lieSpan R L (range b.e) := by induction hy using lieSpan_induction with | mem u hu => obtain ⟨i, rfl⟩ := hu - rw [← mem_toSubmodule, coe_cartan_eq_span] at hx + rw [← mem_toSubmodule, b.coe_cartan_eq_span] at hx induction hx using Submodule.span_induction with | mem v hv => obtain ⟨j, rfl⟩ := hv @@ -146,38 +146,38 @@ private lemma cartan_lie_mem_lieSpan_e {x y : L} exact sub_mem (LieSubalgebra.lie_mem _ hu hv') (LieSubalgebra.lie_mem _ hv hu') /-- The nilpotent part of the "upper" Borel subalgebra associated to a basis. -/ -def borelUpper : LieSubmodule R b.cartan L where +def borelUpper : LieSubmodule R H L where __ := lieSpan R L <| range b.e lie_mem {x y} hy := by obtain ⟨x, hx⟩ := x simpa using b.cartan_lie_mem_lieSpan_e hx hy /-- The nilpotent part of the "lower" Borel subalgebra associated to a basis. -/ -def borelLower : LieSubmodule R b.cartan L where +def borelLower : LieSubmodule R H L where __ := lieSpan R L <| range b.f lie_mem := b.symm.borelUpper.lie_mem private lemma iSup_cartan_borelLower_borelUpper_eq_top_aux {y z : L} (hy : y ∈ lieSpan R L (range b.e)) (hz : z ∈ lieSpan R L (range b.f)) : - ⁅y, z⁆ ∈ b.cartan.toLieSubmodule ⊔ b.borelLower ⊔ b.borelUpper := by + ⁅y, z⁆ ∈ H.toLieSubmodule ⊔ b.borelLower ⊔ b.borelUpper := by have (i : ι) (x : L) (hx : x ∈ lieSpan R L (range b.f)) : - ⁅b.e i, x⁆ ∈ b.cartan.toLieSubmodule ⊔ b.borelLower := by + ⁅b.e i, x⁆ ∈ H.toLieSubmodule ⊔ b.borelLower := by induction hx using LieSubalgebra.lieSpan_induction with | mem u hu => obtain ⟨j, rfl⟩ := hu rcases eq_or_ne i j with rfl | hij · rw [(b.sl2 i).lie_e_f] apply LieSubmodule.mem_sup_left - rw [b.cartan_eq_lieSpan, mem_toLieSubmodule] + nth_rw 1 [mem_toLieSubmodule, b.cartan_eq_lieSpan] exact LieSubalgebra.subset_lieSpan <| mem_range_self i · simp [b.lie_e_f_ne _ _ hij] | zero => simp | add u v _ _ hu hv => rw [lie_add]; exact add_mem hu hv | smul t u _ hu => rw [lie_smul]; exact SMulMemClass.smul_mem t hu | lie u v hu hv hu' hv' => - obtain ⟨w₁, hw₁, w₂, hw₂, hwu⟩ : ∃ y ∈ b.cartan, ∃ z ∈ b.borelLower, y + z = ⁅b.e i, u⁆ := by + obtain ⟨w₁, hw₁, w₂, hw₂, hwu⟩ : ∃ y ∈ H, ∃ z ∈ b.borelLower, y + z = ⁅b.e i, u⁆ := by simpa only [LieSubmodule.mem_sup] using! hu' - obtain ⟨w₃, hw₃, w₄, hw₄, hwv⟩ : ∃ y ∈ b.cartan, ∃ z ∈ b.borelLower, y + z = ⁅b.e i, v⁆ := by + obtain ⟨w₃, hw₃, w₄, hw₄, hwv⟩ : ∃ y ∈ H, ∃ z ∈ b.borelLower, y + z = ⁅b.e i, v⁆ := by simpa only [LieSubmodule.mem_sup] using! hv' rw [leibniz_lie, ← hwu, ← hwv, lie_add, add_lie, ← add_assoc] repeat apply add_mem @@ -198,7 +198,7 @@ private lemma iSup_cartan_borelLower_borelUpper_eq_top_aux rw [lie_lie] apply sub_mem · obtain ⟨yc, hyc, yl, hyl, yu, hyu, aux⟩ : - ∃ᵉ (yc ∈ b.cartan) (yl ∈ lieSpan R L (range b.f)) (yu ∈ lieSpan R L (range b.e)), + ∃ᵉ (yc ∈ H) (yl ∈ lieSpan R L (range b.f)) (yu ∈ lieSpan R L (range b.e)), yc + yl + yu = ⁅v, z⁆ := by simpa [LieSubmodule.mem_sup] using! hv' hz simp only [← aux, lie_add] repeat apply add_mem @@ -208,7 +208,7 @@ private lemma iSup_cartan_borelLower_borelUpper_eq_top_aux · rw [← lie_skew, neg_mem_iff] exact LieSubmodule.mem_sup_right <| LieSubalgebra.lie_mem _ hyu hu · obtain ⟨yc, hyc, yl, hyl, yu, hyu, aux⟩ : - ∃ᵉ (yc ∈ b.cartan) (yl ∈ lieSpan R L (range b.f)) (yu ∈ lieSpan R L (range b.e)), + ∃ᵉ (yc ∈ H) (yl ∈ lieSpan R L (range b.f)) (yu ∈ lieSpan R L (range b.e)), yc + yl + yu = ⁅u, z⁆ := by simpa [LieSubmodule.mem_sup] using! hu' hz simp only [← aux, lie_add] repeat apply add_mem @@ -220,8 +220,8 @@ private lemma iSup_cartan_borelLower_borelUpper_eq_top_aux /-- Lemma 4.5 from [Geck](Geck2017). -/ lemma iSup_cartan_borelLower_borelUpper_eq_top : - iSup ![b.cartan.toLieSubmodule, b.borelLower, b.borelUpper] = ⊤ := by - suffices b.cartan.toLieSubmodule ⊔ b.borelLower ⊔ b.borelUpper = ⊤ by simpa + iSup ![H.toLieSubmodule, b.borelLower, b.borelUpper] = ⊤ := by + suffices H.toLieSubmodule ⊔ b.borelLower ⊔ b.borelUpper = ⊤ by simpa refine eq_top_iff.mpr fun x hx ↦ ?_ replace hx : x ∈ lieSpan R L (range b.e ∪ range b.f) := by simp [b.span_ef] induction hx using lieSpan_induction with @@ -234,10 +234,10 @@ lemma iSup_cartan_borelLower_borelUpper_eq_top : | smul t u _ hu => exact SMulMemClass.smul_mem t hu | lie u v _ _ hu hv => obtain ⟨yc, hyc, yl, hyl, yu, hyu, rfl⟩ : - ∃ᵉ (yc ∈ b.cartan) (yl ∈ lieSpan R L (range b.f)) (yu ∈ lieSpan R L (range b.e)), + ∃ᵉ (yc ∈ H) (yl ∈ lieSpan R L (range b.f)) (yu ∈ lieSpan R L (range b.e)), yc + yl + yu = u := by simpa [LieSubmodule.mem_sup] using! hu obtain ⟨zc, hzc, zl, hzl, zu, hzu, rfl⟩ : - ∃ᵉ (zc ∈ b.cartan) (zl ∈ lieSpan R L (range b.f)) (zu ∈ lieSpan R L (range b.e)), + ∃ᵉ (zc ∈ H) (zl ∈ lieSpan R L (range b.f)) (zu ∈ lieSpan R L (range b.e)), zc + zl + zu = v := by simpa [LieSubmodule.mem_sup] using! hv simp only [lie_add, add_lie, ← add_assoc] repeat apply add_mem @@ -260,7 +260,7 @@ variable [Fintype ι] /-- These elements constitute a base for the root system of the Lie algebra relative to the associated Cartan subalgebra. -/ -def baseSupp (i : ι) : Dual R b.cartan := +def baseSupp (i : ι) : Dual R H := ∑ j, b.A i j • ((Basis.span b.linInd).map (LinearEquiv.ofEq _ _ b.coe_cartan_eq_span).symm).coord j @@ -280,9 +280,9 @@ def baseSupp (i : ι) : Dual R b.cartan := set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma symm_baseSupp : b.symm.baseSupp = -b.baseSupp := by - let b₁ : Module.Basis ι R b.cartan := + let b₁ : Module.Basis ι R H := (Basis.span b.linInd).map (LinearEquiv.ofEq _ _ b.coe_cartan_eq_span).symm - let b₂ : Module.Basis ι R b.cartan := + let b₂ : Module.Basis ι R H := (Basis.span b.linInd.neg).map (LinearEquiv.ofEq _ _ b.symm.coe_cartan_eq_span).symm suffices b₁.coord = -b₂.coord by ext1 i @@ -297,17 +297,17 @@ lemma linearIndependent_baseSupp [IsDomain R] [CharZero R] : have : ((Int.castRingHom R).mapMatrix b.A).Nondegenerate := by rw [Matrix.nondegenerate_iff_det_ne_zero, ← RingHom.map_det] simpa using! b.nondegen.det_ne_zero - let v : ι → Dual R b.cartan := + let v : ι → Dual R H := ((Basis.span b.linInd).map (LinearEquiv.ofEq _ _ b.coe_cartan_eq_span).symm).coord have hv : LinearIndependent R v := Basis.linearIndependent_coord _ simpa [Int.cast_smul_eq_zsmul] using! hv.sum_smul_of_nondegenerate this -@[simp] lemma baseSupp_apply_smul_e (i : ι) (x : b.cartan) : +@[simp] lemma baseSupp_apply_smul_e (i : ι) (x : H) : b.baseSupp i x • b.e i = ⁅x, b.e i⁆ := by obtain ⟨x, hx⟩ := x simp only [coe_bracket_of_module] have hx' : x ∈ Submodule.span R (range b.h) := by - rwa [← LieSubalgebra.mem_toSubmodule, coe_cartan_eq_span] at hx + rwa [← LieSubalgebra.mem_toSubmodule, b.coe_cartan_eq_span] at hx induction hx' using Submodule.span_induction with | mem u hu => obtain ⟨j, rfl⟩ := hu @@ -323,7 +323,7 @@ lemma linearIndependent_baseSupp [IsDomain R] [CharZero R] : rw [← coe_cartan_eq_span, LieSubalgebra.mem_toSubmodule] at hu rw [← SetLike.mk_smul_mk _ t u hu, map_smul, smul_assoc, hv', smul_lie] -@[simp] lemma baseSupp_apply_smul_f (i : ι) (x : b.cartan) : +@[simp] lemma baseSupp_apply_smul_f (i : ι) (x : H) : b.baseSupp i x • b.f i = -⁅x, b.f i⁆ := by rw [← neg_eq_iff_eq_neg, ← neg_smul, ← LinearMap.neg_apply] have := b.symm.baseSupp_apply_smul_e i x @@ -335,7 +335,9 @@ variable [IsDomain R] [CharZero R] set_option backward.isDefEq.respectTransparency.types false in /-- Lemma 4.4 from [Geck](Geck2017). -/ lemma borelUpper_le_biSup : - b.borelUpper ≤ ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) := by + letI := b.isLieAbelian_cartan + b.borelUpper ≤ ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • b.baseSupp i) := by + let := b.isLieAbelian_cartan classical intro x hx replace hx : x ∈ lieSpan R L (range b.e) := by simpa [borelUpper] using hx @@ -351,7 +353,7 @@ lemma borelUpper_le_biSup : | add _ _ _ _ hu hv => exact add_mem hu hv | smul t _ _ hu => exact SMulMemClass.smul_mem t hu | lie u v _ _ hu hv => - let s : Set (b.cartan → R) := {χ | ∃ n : ι → ℕ, n ≠ 0 ∧ χ = ∑ i, n i • b.baseSupp i} + let s : Set (H → R) := {χ | ∃ n : ι → ℕ, n ≠ 0 ∧ χ = ∑ i, n i • b.baseSupp i} have hs : ∀ χ₁ ∈ s, ∀ χ₂ ∈ s, χ₁ + χ₂ ∈ s := by rintro - ⟨n₁, hn₁, rfl⟩ - ⟨n₂, hn₂, rfl⟩ refine ⟨n₁ + n₂, by simp [hn₁], ?_⟩ @@ -368,25 +370,28 @@ lemma borelUpper_le_biSup : · use ⟨χ.property.choose, χ.property.choose_spec.1⟩ ext i simpa using congr_fun χ.property.choose_spec.2.symm i - replace hu : u ∈ ⨆ χ, ⨆ (_ : χ ∈ s), rootSpace b.cartan χ := by + replace hu : u ∈ ⨆ χ, ⨆ (_ : χ ∈ s), rootSpace H χ := by convert! hu; rw [iSup_subtype', iSup_subtype', ← e.iSup_comp]; rfl - replace hv : v ∈ ⨆ χ, ⨆ (_ : χ ∈ s), rootSpace b.cartan χ := by + replace hv : v ∈ ⨆ χ, ⨆ (_ : χ ∈ s), rootSpace H χ := by convert! hv; rw [iSup_subtype', iSup_subtype', ← e.iSup_comp]; rfl convert! mem_biSup_genWeightSpace_of hs hu hv rw [iSup_subtype', iSup_subtype', ← e.iSup_comp]; rfl /-- Lemma 4.4 from [Geck](Geck2017). -/ lemma borelLower_le_biSup : - b.borelLower ≤ ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • (-b.baseSupp) i) := by + letI := b.isLieAbelian_cartan + b.borelLower ≤ ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • (-b.baseSupp) i) := by simpa only [symm_baseSupp] using! b.symm.borelUpper_le_biSup private lemma cartan_borelLower_borelUpper_le : - letI U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • (-b.baseSupp) i) - letI V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) - ![b.cartan.toLieSubmodule, b.borelLower, b.borelUpper] ≤ ![rootSpace b.cartan 0, U, V] := by + letI := b.isLieAbelian_cartan + letI U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • (-b.baseSupp) i) + letI V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • b.baseSupp i) + ![H.toLieSubmodule, b.borelLower, b.borelUpper] ≤ ![rootSpace H 0, U, V] := by + let := b.isLieAbelian_cartan intro i fin_cases i - · exact toLieSubmodule_le_rootSpace_zero R L b.cartan + · exact toLieSubmodule_le_rootSpace_zero R L H · exact b.borelLower_le_biSup · exact b.borelUpper_le_biSup @@ -394,20 +399,22 @@ variable [IsTorsionFree R L] set_option backward.isDefEq.respectTransparency.types false in lemma iSupIndep_rootSpace : - letI U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • (-b.baseSupp) i) - letI V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) - iSupIndep ![rootSpace b.cartan 0, U, V] := by - set U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • (-b.baseSupp) i) with hU - set V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) with hV - set s0 : Set (b.cartan → R) := {0} with hs0 - set sU : Set (b.cartan → R) := {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • (-b.baseSupp) i} with hsU - set sV : Set (b.cartan → R) := {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • b.baseSupp i} with hsV - have hs0' : rootSpace b.cartan 0 = ⨆ i ∈ s0, LieModule.genWeightSpace L i := by simp [hs0] + letI := b.isLieAbelian_cartan + letI U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • (-b.baseSupp) i) + letI V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • b.baseSupp i) + iSupIndep ![rootSpace H 0, U, V] := by + let := b.isLieAbelian_cartan + set U := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • (-b.baseSupp) i) with hU + set V := ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • b.baseSupp i) with hV + set s0 : Set (H → R) := {0} with hs0 + set sU : Set (H → R) := {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • (-b.baseSupp) i} with hsU + set sV : Set (H → R) := {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • b.baseSupp i} with hsV + have hs0' : rootSpace H 0 = ⨆ i ∈ s0, LieModule.genWeightSpace L i := by simp [hs0] have hsU' : U = ⨆ i ∈ sU, LieModule.genWeightSpace L i := by - simp only [hU, hsU, mem_ofPred_eq, iSup_exists, iSup_and, iSup_comm (ι := b.cartan → R), + simp only [hU, hsU, mem_ofPred_eq, iSup_exists, iSup_and, iSup_comm (ι := H → R), iSup_iSup_eq_left, LinearMap.coe_sum, LinearMap.coe_smul] have hsV' : V = ⨆ i ∈ sV, LieModule.genWeightSpace L i := by - simp only [hV, hsV, mem_ofPred_eq, iSup_exists, iSup_and, iSup_comm (ι := b.cartan → R), + simp only [hV, hsV, mem_ofPred_eq, iSup_exists, iSup_and, iSup_comm (ι := H → R), iSup_iSup_eq_left, LinearMap.coe_sum, LinearMap.coe_smul] have hU0 : Disjoint s0 sU := by suffices ∀ g ∈ sU, g ≠ 0 by @@ -451,36 +458,41 @@ lemma iSupIndep_rootSpace : specialize this i rw [comp_apply, Nat.cast_eq_zero, Pi.add_apply, Nat.add_eq_zero_iff] at this simpa using this.2 - have key := LieModule.iSupIndep_genWeightSpace R b.cartan L - have h₀ : Disjoint (rootSpace b.cartan 0) (U ⊔ V) := by + have key := LieModule.iSupIndep_genWeightSpace R H L + have h₀ : Disjoint (rootSpace H 0) (U ⊔ V) := by convert! key.disjoint_biSup_biSup (hU0.union_right hV0) rw [iSup_union, hsU', hsV'] - have h₁ : Disjoint U (V ⊔ rootSpace b.cartan 0) := by + have h₁ : Disjoint U (V ⊔ rootSpace H 0) := by convert! key.disjoint_biSup_biSup (hUV.union_right hU0.symm) rw [iSup_union, hs0', hsV'] - have h₂ : Disjoint V (rootSpace b.cartan 0 ⊔ U) := by + have h₂ : Disjoint V (rootSpace H 0 ⊔ U) := by convert! key.disjoint_biSup_biSup (Disjoint.union_left hV0 hUV).symm rw [iSup_union, hs0', hsU'] simp [iSupIndep_fin_three, h₀, h₁, h₂] set_option linter.unusedFintypeInType false in lemma cartan_eq : - b.cartan.toLieSubmodule = rootSpace b.cartan 0 := + letI := b.isLieAbelian_cartan + H.toLieSubmodule = rootSpace H 0 := congr_fun ((b.iSupIndep_rootSpace.le_iff_eq_of_iSup_eq_top b.iSup_cartan_borelLower_borelUpper_eq_top).mp b.cartan_borelLower_borelUpper_le) 0 lemma borelLower_eq : - b.borelLower = ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • (-b.baseSupp) i) := + letI := b.isLieAbelian_cartan + b.borelLower = ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • (-b.baseSupp) i) := congr_fun ((b.iSupIndep_rootSpace.le_iff_eq_of_iSup_eq_top b.iSup_cartan_borelLower_borelUpper_eq_top).mp b.cartan_borelLower_borelUpper_le) 1 lemma borelUpper_eq : - b.borelUpper = ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace b.cartan (∑ i, n i • b.baseSupp i) := + letI := b.isLieAbelian_cartan + b.borelUpper = ⨆ (n : ι → ℕ) (_ : n ≠ 0), rootSpace H (∑ i, n i • b.baseSupp i) := congr_fun ((b.iSupIndep_rootSpace.le_iff_eq_of_iSup_eq_top b.iSup_cartan_borelLower_borelUpper_eq_top).mp b.cartan_borelLower_borelUpper_le) 2 set_option linter.unusedFintypeInType false in -instance [IsNoetherian R L] : b.cartan.IsCartanSubalgebra := by +include b in +lemma isCartanSubalgebra [IsNoetherian R L] : H.IsCartanSubalgebra := by + let := b.isLieAbelian_cartan rw [← eq_rootSpace_zero_iff_isCartan, b.cartan_eq] end CommRing @@ -488,10 +500,13 @@ end CommRing open AddSubmonoid IsKilling LieModule Matrix variable {ι K L : Type*} [Fintype ι] [Field K] [CharZero K] [LieRing L] [LieAlgebra K L] - [FiniteDimensional K L] (b : Basis ι K L) + [FiniteDimensional K L] {H : LieSubalgebra K L} (b : Basis ι H) /-- The elements `LieAlgebra.Basis.baseSupp` as roots in the sense of `LieSubalgebra.root`. -/ -def baseSupp' (i : ι) : b.cartan.root := by +def baseSupp' (i : ι) : + letI := b.isCartanSubalgebra + H.root := by + let := b.isCartanSubalgebra refine ⟨⟨b.baseSupp i, ?_⟩, ?_⟩ · simp only [LieSubmodule.eq_bot_iff, ne_eq, not_forall] exact ⟨b.e i, (mem_genWeightSpace _ _ _).mpr fun x ↦ ⟨1, by simp⟩, (b.sl2 i).e_ne_zero⟩ @@ -499,34 +514,37 @@ def baseSupp' (i : ι) : b.cartan.root := by @[simp] lemma coe_linearMap_baseSupp' (i : ι) : b.baseSupp' i = b.baseSupp i := rfl -variable [IsTriangularizable K b.cartan L] [IsKilling K L] +variable [IsTriangularizable K H L] [IsKilling K L] lemma linearIndepOn_root_baseSupp : - LinearIndepOn K (rootSystem b.cartan).root (range b.baseSupp') := by + letI := b.isCartanSubalgebra + LinearIndepOn K (rootSystem H).root (range b.baseSupp') := by let e : ι ≃ range b.baseSupp' := Equiv.ofInjective _ <| fun i j hij ↦ b.linearIndependent_baseSupp.injective <| by simpa [baseSupp'] using hij rw [LinearIndepOn, ← linearIndependent_equiv e] exact b.linearIndependent_baseSupp -lemma root_mem_or_mem_neg (χ : b.cartan.root) : - (rootSystem b.cartan).root χ ∈ closure ((rootSystem b.cartan).root '' range b.baseSupp') ∨ - -(rootSystem b.cartan).root χ ∈ closure ((rootSystem b.cartan).root '' range b.baseSupp') := by +lemma root_mem_or_mem_neg (χ : letI := b.isCartanSubalgebra; H.root) : + letI := b.isCartanSubalgebra + ( (rootSystem H).root χ ∈ closure ((rootSystem H).root '' range b.baseSupp') ∨ + -(rootSystem H).root χ ∈ closure ((rootSystem H).root '' range b.baseSupp')) := by + let := b.isCartanSubalgebra have (n : ι → ℕ) : - ∑ i, n i • b.baseSupp i ∈ closure (⇑(rootSystem b.cartan).root '' range b.baseSupp') := by + ∑ i, n i • b.baseSupp i ∈ closure (⇑(rootSystem H).root '' range b.baseSupp') := by simp_rw [← Submodule.span_nat_eq_addSubmonoidClosure, Submodule.mem_toAddSubmonoid] exact Submodule.sum_smul_mem _ _ fun i _ ↦ Submodule.subset_span <| by simp - let s : Set (b.cartan → K) := {0} ∪ + let s : Set (H → K) := {0} ∪ {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = -∑ i, n i • b.baseSupp i} ∪ {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • b.baseSupp i} - have hs : ⨆ α ∈ s, rootSpace b.cartan α = ⊤ := by + have hs : ⨆ α ∈ s, rootSpace H α = ⊤ := by have := b.iSup_cartan_borelLower_borelUpper_eq_top - rw [borelLower_eq, borelUpper_eq, cartan_eq] at this + rw [borelLower_eq, borelUpper_eq, b.cartan_eq] at this rw [iSup_union, iSup_union] - simpa [iSup_and, iSup_comm (ι := b.cartan → K)] using this + simpa [iSup_and, iSup_comm (ι := H → K)] using this obtain ⟨χ, hχ⟩ := χ change χ.toLinear ∈ _ ∨ -χ.toLinear ∈ _ replace hs : ⇑χ ∈ s := - (iSupIndep_genWeightSpace K b.cartan L).mem_of_biSup_eq_top hs χ.genWeightSpace_ne_bot + (iSupIndep_genWeightSpace K H L).mem_of_biSup_eq_top hs χ.genWeightSpace_ne_bot replace hs : (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = -∑ i, n i • b.baseSupp i) ∨ (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = ∑ i, n i • b.baseSupp i) := by have hχ' : ¬ χ.IsZero := by simpa using hχ @@ -536,8 +554,11 @@ lemma root_mem_or_mem_neg (χ : b.cartan.root) : refine hs.symm.imp (fun ⟨n, hn₀, hn⟩ ↦ ?_) (fun ⟨n, hn₀, hn⟩ ↦ ?_) <;> simpa [hn] using this n /-- The distinguished root system base associated to a basis. -/ -def base : RootPairing.Base (rootSystem b.cartan) := - .mk' (rootSystem b.cartan) (range b.baseSupp') b.linearIndepOn_root_baseSupp b.root_mem_or_mem_neg +def base : + letI := b.isCartanSubalgebra + RootPairing.Base (rootSystem H) := + letI := b.isCartanSubalgebra + .mk' (rootSystem H) (range b.baseSupp') b.linearIndepOn_root_baseSupp b.root_mem_or_mem_neg /-- The support of `LieAlgebra.Basis.base` is in one-to-one correspondence with the indexing set of the basis. -/ @@ -549,18 +570,20 @@ def baseSupportEquiv : ι ≃ b.base.support := @[simp] lemma coe_baseSupportEquiv_apply (i : ι) : b.baseSupportEquiv i = b.baseSupp i := rfl @[simp] lemma coroot_eq_h' (i : ι) : + letI := b.isCartanSubalgebra coroot (b.baseSupportEquiv i) = b.h' i := by + let := b.isCartanSubalgebra suffices b.h' i ∈ corootSpace (b.baseSupp' i) by have _i : IsAddTorsionFree L := .of_isTorsionFree K L exact (eq_coroot_of_mem_corootSpace_of_two (b.baseSupp' i).val this (by simp [baseSupp'])).symm - have h_mem : ⁅b.e i, b.f i⁆ ∈ b.cartan := by - rw [(b.sl2 i).lie_e_f, b.cartan_eq_lieSpan] + have h_mem : ⁅b.e i, b.f i⁆ ∈ H := by + nth_rw 1 [(b.sl2 i).lie_e_f, b.cartan_eq_lieSpan] exact subset_lieSpan <| mem_range_self i have h_eq : b.h' i = ⟨⁅b.e i, b.f i⁆, h_mem⟩ := by simp [(b.sl2 i).lie_e_f, h'] rw [h_eq] - have he : b.e i ∈ rootSpace b.cartan (b.baseSupp i) := + have he : b.e i ∈ rootSpace H (b.baseSupp i) := (mem_genWeightSpace _ _ _).mpr fun ⟨z, hz⟩ ↦ ⟨1, by simp⟩ - have hf : b.f i ∈ rootSpace b.cartan (-b.baseSupp i) := + have hf : b.f i ∈ rootSpace H (-b.baseSupp i) := (mem_genWeightSpace _ _ _).mpr fun ⟨z, hz⟩ ↦ ⟨1, by simp [← eq_neg_iff_add_eq_zero]⟩ exact (mem_corootSpace _).mpr <| Submodule.subset_span ⟨b.e i, he, b.f i, hf, rfl⟩ diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean index aefcf38fd038cd..4f2175b34bcff9 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean @@ -42,12 +42,11 @@ attribute [local instance 100] LieRing.ofAssociativeRing /-- The Geck construction yields a basis of the Lie algebra it constructs. -/ def basis : - LieAlgebra.Basis b.support K (lieAlgebra b) where + LieAlgebra.Basis b.support (cartanSubalgebra' b) where A := b.cartanMatrix h i := ⟨h i, h_mem_lieAlgebra i⟩ e i := ⟨e i, e_mem_lieAlgebra i⟩ f i := ⟨f i, f_mem_lieAlgebra i⟩ - cartan := cartanSubalgebra' b cartan_eq_lieSpan := by rw [cartanSubalgebra', cartanSubalgebra_eq_lieSpan, ← LieSubalgebra.comap_lieSpan_range_eq] rfl @@ -88,14 +87,13 @@ def basis : @[simp] lemma basis_A_eq : (basis b).A = b.cartanMatrix := rfl -instance : (cartanSubalgebra' b).IsCartanSubalgebra := - inferInstanceAs (basis b).cartan.IsCartanSubalgebra +instance : (cartanSubalgebra' b).IsCartanSubalgebra := (basis b).isCartanSubalgebra open LieAlgebra.IsKilling in /-- Up to equivalence, `LieAlgebra.IsKilling.rootSystem` is left inverse to `RootPairing.GeckConstruction.lieAlgebra`. -/ def equivRootSystem [IsAlgClosed K] : - P.Equiv (rootSystem (basis b).cartan) := + P.Equiv (rootSystem (cartanSubalgebra' b)) := b.equivOfCartanMatrixEq _ (basis b).baseSupportEquiv <| by simp [(basis b).cartanMatrix_base_eq] end RootPairing.GeckConstruction From 1e3b447b6258c052c9a666c9d392bd6ba5c9433b Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:25:28 +0000 Subject: [PATCH 0911/1300] chore: update Mathlib dependencies 2026-07-21 (#41977) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 2462db917175d2..da3bfd52ff5d8e 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "2c810760f0a0c4536b397dbe30ca9b2f2f467366", + "rev": "2ccad61f0f1bb8000458a72fc7ec5df8a7a821b2", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From a6b233c22a6c17c412ebd5c31dd4235927368d3c Mon Sep 17 00:00:00 2001 From: Kamille Bidan <25210160030@m.fudan.edu.cn> Date: Tue, 21 Jul 2026 16:19:08 +0000 Subject: [PATCH 0912/1300] feat(Topology/CantorBendixson): add iterated derived sets and perfect kernel (#37376) Define the transfinite iteration of the relative derived-set operator via `gfpApprox` and introduce the perfect kernel of a set. Co-authored-by: NoneMore --- Mathlib.lean | 1 + .../Ordinal/FixedPointApproximants.lean | 93 ++++++++- Mathlib/Topology/CantorBendixson.lean | 192 ++++++++++++++++++ 3 files changed, 276 insertions(+), 10 deletions(-) create mode 100644 Mathlib/Topology/CantorBendixson.lean diff --git a/Mathlib.lean b/Mathlib.lean index ba40b66d79de85..98b51d695a0a11 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7768,6 +7768,7 @@ public import Mathlib.Topology.CWComplex.Classical.Basic public import Mathlib.Topology.CWComplex.Classical.Finite public import Mathlib.Topology.CWComplex.Classical.Graph public import Mathlib.Topology.CWComplex.Classical.Subcomplex +public import Mathlib.Topology.CantorBendixson public import Mathlib.Topology.Category.Born public import Mathlib.Topology.Category.CompHaus.Basic public import Mathlib.Topology.Category.CompHaus.EffectiveEpi diff --git a/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean b/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean index 5010bcd45a0cb0..ca301d27ef32c7 100644 --- a/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean +++ b/Mathlib/SetTheory/Ordinal/FixedPointApproximants.lean @@ -139,6 +139,43 @@ theorem lfpApprox_eq_of_mem_fixedPoints (hab : a ≤ b) · exact apply_lfpApprox_le_lfpApprox_of_lt f hi' · simp [IH i hi hi', hf] +theorem lfpApprox_eq_all_of_fixedPoint (hx : x ≤ f x) : + (∀ o, lfpApprox f x o = x) ↔ f x = x := by + refine ⟨fun h ↦ ?_, fun h o ↦ ?_⟩ + · specialize h 1 + rwa [← zero_add 1, lfpApprox_add_one f hx, lfpApprox_zero] at h + · have : lfpApprox f x 0 ∈ fixedPoints f := by + rwa [mem_fixedPoints_iff, lfpApprox_zero] + simpa [lfpApprox_zero] using + lfpApprox_eq_of_mem_fixedPoints f zero_le this + +/-- If the sequence of ordinal-indexed approximations takes a value twice, +then it actually stabilised at that value. -/ +lemma lfpApprox_mem_fixedPoints_of_eq (hx : x ≤ f x) (hab : a < b) (hac : a ≤ c) + (hf : lfpApprox f x a = lfpApprox f x b) : lfpApprox f x c ∈ fixedPoints f := by + have H : lfpApprox f x a ∈ fixedPoints f := by + rw [mem_fixedPoints_iff, ← lfpApprox_add_one f hx] + exact (lfpApprox_mono_right f).eq_of_ge_of_le + hf (lt_add_one a).le (add_one_le_of_lt hab) + rwa [lfpApprox_eq_of_mem_fixedPoints f hac H] + +theorem lfpApprox_eq_of_fixedPoint_or_zero (hx : x ≤ f x) (o : Ordinal) : + lfpApprox f x o = x ↔ f x = x ∨ o = 0 := by + refine ⟨fun h => ?_, fun h => ?_⟩ + · rcases eq_or_ne o 0 with (rfl | ho) + · exact Or.inr rfl + · have hpos : (0 : Ordinal) < o := + zero_lt_one.trans_le (one_le_iff_ne_zero.mpr ho) + have hmem : lfpApprox f x 0 ∈ fixedPoints f := + lfpApprox_mem_fixedPoints_of_eq f hx hpos (le_refl _) + ((lfpApprox_zero f).trans h.symm) + have hfx : f x = x := + (mem_fixedPoints_iff.mp (by simpa [lfpApprox_zero] using hmem)) + exact Or.inl hfx + · rcases h with (hf | rfl) + · exact (lfpApprox_eq_all_of_fixedPoint f hx).mpr hf o + · exact lfpApprox_zero f + variable (x) in /-- There are distinct indices smaller than the successor of the domain's cardinality yielding the same value -/ @@ -153,16 +190,6 @@ theorem exists_lfpApprox_eq_lfpApprox : ∃ a < ord <| succ #α, ∃ b < ord <| · intro h_eq; rw [Subtype.coe_inj] at h_eq; exact h_nab h_eq · exact h_fab -/-- If the sequence of ordinal-indexed approximations takes a value twice, -then it actually stabilised at that value. -/ -lemma lfpApprox_mem_fixedPoints_of_eq (hx : x ≤ f x) (hab : a < b) (hac : a ≤ c) - (hf : lfpApprox f x a = lfpApprox f x b) : lfpApprox f x c ∈ fixedPoints f := by - have H : lfpApprox f x a ∈ fixedPoints f := by - rw [mem_fixedPoints_iff, ← lfpApprox_add_one f hx] - exact (lfpApprox_mono_right f).eq_of_ge_of_le - hf (lt_add_one a).le (add_one_le_of_lt hab) - rwa [lfpApprox_eq_of_mem_fixedPoints f hac H] - /-- The approximation at the index of the successor of the domain's cardinality is a fixed point -/ theorem lfpApprox_ord_mem_fixedPoint (hx : x ≤ f x) : lfpApprox f x (ord <| succ #α) ∈ fixedPoints f := by @@ -199,6 +226,28 @@ theorem lfp_mem_range_lfpApprox : f.lfp ∈ Set.range (lfpApprox f ⊥) := by use ord <| succ #α exact lfpApprox_ord_eq_lfp f +/-- If `lfpApprox f x a` is a fixed point, then the supremum of the whole +ordinal-indexed sequence equals the value at `a`. -/ +lemma iSup_lfpApprox_eq_of_mem_fixedPoints (hf : lfpApprox f x a ∈ fixedPoints f) : + ⨆ i : Ordinal, lfpApprox f x i = lfpApprox f x a := by + apply (le_iSup (lfpApprox f x) a).antisymm' + refine ciSup_le fun i => ?_ + by_cases h : i ≤ a + · exact lfpApprox_mono_right f h + · exact (lfpApprox_eq_of_mem_fixedPoints f (le_of_not_ge h) hf).le + +/-- The ordinal-indexed supremum of `lfpApprox` equals `nextFixed`: the least fixed point +greater than or equal to `x`. -/ +theorem nextFixed_eq_iSup_lfpApprox (hx : x ≤ f x) : + (f.nextFixed x hx).val = ⨆ a : Ordinal, lfpApprox f x a := by + let o := (succ #α).ord + have hfix : lfpApprox f x o ∈ fixedPoints f := + lfpApprox_ord_mem_fixedPoint f hx + rw [iSup_lfpApprox_eq_of_mem_fixedPoints f hfix] + apply le_antisymm + · exact f.nextFixed_le hx (y := ⟨lfpApprox f x o, hfix⟩) (le_lfpApprox f) + · exact lfpApprox_le_of_mem_fixedPoints f (f.nextFixed x hx).2 (f.le_nextFixed hx) o + variable (x) in /-- The ordinal-indexed sequence approximating the greatest fixed point greater than an initial value `x`. It is defined in such a way that we have `gfpApprox 0 x = x` and @@ -247,6 +296,18 @@ theorem gfpApprox_eq_of_mem_fixedPoints {a b : Ordinal} (h_ab : a ≤ b) (h : gfpApprox f x a ∈ fixedPoints f) : gfpApprox f x b = gfpApprox f x a := lfpApprox_eq_of_mem_fixedPoints f.dual h_ab h +theorem gfpApprox_eq_all_of_fixedPoint (hx : f x ≤ x) : + (∀ o, gfpApprox f x o = x) ↔ f x = x := + lfpApprox_eq_all_of_fixedPoint f.dual hx + +lemma gfpApprox_mem_fixedPoints_of_eq (hx : f x ≤ x) (hab : a < b) (hac : a ≤ c) + (hf : gfpApprox f x a = gfpApprox f x b) : gfpApprox f x c ∈ fixedPoints f := + lfpApprox_mem_fixedPoints_of_eq f.dual hx hab hac hf + +theorem gfpApprox_eq_of_fixedPoint_or_zero (hx : f x ≤ x) (o : Ordinal) : + gfpApprox f x o = x ↔ f x = x ∨ o = 0 := + lfpApprox_eq_of_fixedPoint_or_zero f.dual hx o + /-- There are distinct indices smaller than the successor of the domain's cardinality yielding the same value -/ theorem exists_gfpApprox_eq_gfpApprox : ∃ a < ord <| succ #α, ∃ b < ord <| succ #α, @@ -273,4 +334,16 @@ theorem gfpApprox_ord_eq_gfp : gfpApprox f ⊤ (ord <| succ #α) = f.gfp := theorem gfp_mem_range_gfpApprox : f.gfp ∈ Set.range (gfpApprox f ⊤) := lfp_mem_range_lfpApprox f.dual +/-- If `gfpApprox f x a` is a fixed point, then the infimum of the whole +ordinal-indexed sequence equals the value at `a`. -/ +lemma iInf_gfpApprox_eq_of_mem_fixedPoints (hf : gfpApprox f x a ∈ fixedPoints f) : + ⨅ i : Ordinal, gfpApprox f x i = gfpApprox f x a := + iSup_lfpApprox_eq_of_mem_fixedPoints f.dual hf + +/-- The ordinal-indexed infimum of `gfpApprox` equals `prevFixed`: the greatest fixed point +less than or equal to `x`. -/ +theorem prevFixed_eq_iInf_gfpApprox (hx : f x ≤ x) : + (f.prevFixed x hx).val = ⨅ a : Ordinal, gfpApprox f x a := + nextFixed_eq_iSup_lfpApprox f.dual hx + end OrdinalApprox diff --git a/Mathlib/Topology/CantorBendixson.lean b/Mathlib/Topology/CantorBendixson.lean new file mode 100644 index 00000000000000..b6a3ce56652c67 --- /dev/null +++ b/Mathlib/Topology/CantorBendixson.lean @@ -0,0 +1,192 @@ +/- +Copyright (c) 2026 Zikang Yu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Zikang Yu +-/ +module + +public import Mathlib.SetTheory.Cardinal.Ordinal +public import Mathlib.SetTheory.Ordinal.FixedPointApproximants +public import Mathlib.Topology.DerivedSet + +/-! +# Cantor-Bendixson derivatives and perfect kernel + +This file defines the transfinite iteration of the relative derived-set operator +and the associated perfect kernel. + +For closed sets, the relative derived set agrees with `derivedSet`, so this recovers the usual +Cantor-Bendixson derivative sequence of a closed set. + +## Main definitions + +* `CantorBendixson.iteratedDerivedSet s a`: the `a`-th transfinite iterate of `relDerivedSet` + starting from `s`. +* `CantorBendixson.perfectKernel s`: the largest perfect subset of `s`, defined as the + intersection of all iterated derived sets of `s`. + +## Main statements + +* `CantorBendixson.iteratedDerivedSet_constant_iff_preperfect`: a set is preperfect if and only + if every iterated derived set is equal to the original set. +* `CantorBendixson.iteratedDerivedSet_stay`: the iterated derived-set sequence eventually + stabilizes. +* `CantorBendixson.perfect_perfectKernel`: the perfect kernel of a closed set is perfect. +* `CantorBendixson.subset_perfectKernel_of_perfect`: the perfect kernel is the largest perfect + subset. + +## Notation + +* `sᵈ[a]`: the `a`-th iterated relative derived set of `s`. + +## Implementation notes + +* We define `iteratedDerivedSet` using `OrdinalApprox.gfpApprox` applied to `relDerivedSet`. + This keeps the transfinite sequence antitone for arbitrary sets. +* If `s` is closed, then `relDerivedSet s = derivedSet s`, so successor stages agree with the + ambient derived-set operator. + +## TODO + +* Pointwise and setwise Cantor-Bendixson ranks. +* A generalized Cantor-Bendixson decomposition theorem for arbitrary topological spaces and + arbitrary cardinalities of topological bases. + +-/ + +@[expose] public section + +open Filter Set Cardinal OrdinalApprox Function + +universe u + +namespace CantorBendixson + +section + +variable {X : Type u} [TopologicalSpace X] + +/-- The transfinite iteration of the relative derived-set operator on a set. -/ +def iteratedDerivedSet (s : Set X) : Ordinal → Set X := + gfpApprox relDerivedSet s + +@[inherit_doc CantorBendixson.iteratedDerivedSet] +scoped[CantorBendixson] notation:max s "ᵈ[" a "]" => iteratedDerivedSet s a + +variable {s t : Set X} {a b : Ordinal} + +@[simp] +theorem iteratedDerivedSet_zero : + sᵈ[0] = s := by + simp [iteratedDerivedSet, gfpApprox_zero] + +@[simp] +theorem iteratedDerivedSet_succ : + sᵈ[a + 1] = relDerivedSet (sᵈ[a]) := by + simpa [iteratedDerivedSet] using + gfpApprox_add_one relDerivedSet relDerivedSet_subset a + +theorem iteratedDerivedSet_limit (ha : Order.IsSuccLimit a) : + sᵈ[a] = ⋂ b : Set.Iio a, sᵈ[b] := by + simpa [iteratedDerivedSet] using gfpApprox_of_isSuccLimit relDerivedSet ha + +/-- A set is preperfect if and only if every stage of its iterated relative derived-set sequence +is equal to the original set. -/ +theorem iteratedDerivedSet_constant_iff_preperfect : + Preperfect s ↔ ∀ a : Ordinal, sᵈ[a] = s := by + rw [preperfect_iff_eq_relDerivedSet, eq_comm, + ← (gfpApprox_eq_all_of_fixedPoint relDerivedSet (relDerivedSet_subset))] + simp [iteratedDerivedSet] + +theorem isClosed_iteratedDerivedSet (hs : IsClosed s) : + ∀ a : Ordinal, IsClosed sᵈ[a] := by + intro a + induction a using Ordinal.limitRecOn with + | zero => simpa only [iteratedDerivedSet_zero] + | add_one a ha => + simp_all [ha.relDerivedSet_eq, isClosed_iff_derivedSet_subset, derivedSet_mono] + | limit a ha ih => + simpa [iteratedDerivedSet_limit ha] using + isClosed_iInter fun i => isClosed_iInter fun hi => ih i hi + +theorem iteratedDerivedSet_antitone (s : Set X) : + Antitone (iteratedDerivedSet s) := gfpApprox_anti_right relDerivedSet + +theorem iteratedDerivedSet_mono : + Monotone (fun s : Set X => iteratedDerivedSet s) := + gfpApprox_mono_mid _ + +/-- If the iterated derived set stops changing at a successor stage, then `sᵈ[a]` is a fixed +point of `relDerivSet`. -/ +theorem mem_fixedPoints_of_iteratedDerivedSet_succ_eq (ha : sᵈ[a + 1] = sᵈ[a]) : + sᵈ[a] ∈ fixedPoints relDerivedSet := by + rw [Function.mem_fixedPoints_iff] + simpa [iteratedDerivedSet_succ] using ha.symm + +theorem iteratedDerivedSet_mem_fixedPoints (s : Set X) : + ∃ a : Ordinal, sᵈ[a] ∈ fixedPoints relDerivedSet := by + refine ⟨(Order.succ #(Set X)).ord, + gfpApprox_ord_mem_fixedPoint relDerivedSet relDerivedSet_subset⟩ + +/-- The perfect kernel of a set, defined as the intersection of all iterated derived sets. It is +the largest perfect subset of the original set. -/ +def perfectKernel (s : Set X) : Set X := + ⋂ a : Ordinal, sᵈ[a] + +theorem perfectKernel_subset_iteratedDerivedSet (s : Set X) (a : Ordinal) : + perfectKernel s ⊆ sᵈ[a] := + Set.iInter_subset _ a + +theorem perfectKernel_subset (s : Set X) : + perfectKernel s ⊆ s := by + simpa [iteratedDerivedSet_zero] using perfectKernel_subset_iteratedDerivedSet s 0 + +theorem perfectKernel_mono (hst : s ⊆ t) : + perfectKernel s ⊆ perfectKernel t := by + simpa [perfectKernel] using Set.iInter_mono'' (iteratedDerivedSet_mono hst) + +theorem isClosed_perfectKernel (hs : IsClosed s) : + IsClosed (perfectKernel s) := + isClosed_iInter (isClosed_iteratedDerivedSet hs) + +@[simp] +theorem perfectKernel_empty : + perfectKernel (∅ : Set X) = ∅ := by + simpa using perfectKernel_subset ∅ + +/-- Once `sᵈ[a]` is a fixed point of `relDerivSet`, the perfect kernel equals `sᵈ[a]`. -/ +theorem perfectKernel_eq_iteratedDerivedSet_of_mem_fixedPoints + (ha : sᵈ[a] ∈ fixedPoints relDerivedSet) : + perfectKernel s = sᵈ[a] := by + refine le_antisymm (perfectKernel_subset_iteratedDerivedSet s a) ?_ + refine Set.subset_iInter fun i => ?_ + rcases lt_or_ge i a with hi | hi + · exact iteratedDerivedSet_antitone s hi.le + · exact (gfpApprox_eq_of_mem_fixedPoints relDerivedSet hi ha).ge + +/-- Every perfect subset of a set is contained in its perfect kernel. -/ +theorem _root_.Perfect.subset_perfectKernel + {P : Set X} (hP : Perfect P) (hPs : P ⊆ s) : + P ⊆ perfectKernel s := by + refine Set.subset_iInter fun i => ?_ + simpa [iteratedDerivedSet_constant_iff_preperfect.mp hP.acc i] using + iteratedDerivedSet_mono hPs i + +/-- The perfect kernel of a closed set is perfect. -/ +theorem perfect_perfectKernel (hs : IsClosed s) : + Perfect (perfectKernel s) := by + obtain ⟨a, ha⟩ := iteratedDerivedSet_mem_fixedPoints s + rw [perfectKernel_eq_iteratedDerivedSet_of_mem_fixedPoints ha] + refine perfect_iff_eq_derivedSet.mpr ?_ + simpa [(isClosed_iteratedDerivedSet hs a).relDerivedSet_eq] using + (Function.mem_fixedPoints_iff.mp ha).symm + +/-- Taking the perfect kernel of a closed set is idempotent. -/ +theorem perfectKernel_idem (hs : IsClosed s) : + perfectKernel (perfectKernel s) = perfectKernel s := + subset_antisymm (perfectKernel_subset _) <| + (perfect_perfectKernel hs).subset_perfectKernel Subset.rfl + +end + +end CantorBendixson From 216cd98dfcfb87e235f9f0759fe3c563f65419c1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 21 Jul 2026 17:03:43 +0000 Subject: [PATCH 0913/1300] =?UTF-8?q?chore(Geometry/Manifold/MFDeriv/Atlas?= =?UTF-8?q?):=20use=20custom=20elaborators=20for=20mf=E2=80=A6=20(#41844)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …deriv more Co-authored-by: Floris van Doorn --- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index b35e51a090b995..adef040c3344e0 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -393,7 +393,7 @@ lemma fderivWithin_extChartAt_comp_extChartAt_symm_range : /-- The manifold derivative of `extChartAt` at the basepoint is the identity. -/ lemma mfderiv_extChartAt_self : - mfderiv I 𝓘(𝕜, E) (extChartAt I x) x = ContinuousLinearMap.id 𝕜 _ := by + mfderiv% (extChartAt I x) x = ContinuousLinearMap.id 𝕜 _ := by rw [← TangentBundle.continuousLinearMapAt_trivializationAt (by simp), TangentBundle.continuousLinearMapAt_trivializationAt_eq_core (by simp)] ext v @@ -404,8 +404,7 @@ set_option backward.isDefEq.respectTransparency false in /-- The manifold derivative within `range I` of `(extChartAt I x).symm` at the chart point is the identity. -/ lemma mfderivWithin_range_extChartAt_symm : - mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) (extChartAt I x x) = - ContinuousLinearMap.id 𝕜 _ := by + mfderiv[range I] (extChartAt I x).symm (extChartAt I x x) = ContinuousLinearMap.id 𝕜 _ := by have hcomp := mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (I := I) (mem_extChartAt_source x) rw [mfderiv_extChartAt_self, ContinuousLinearMap.comp_id] at hcomp @@ -415,7 +414,7 @@ set_option backward.isDefEq.respectTransparency false in /-- The inverse of the derivative of `(extChartAt I x).symm` at the chart point, applied to a tangent vector, gives back the tangent vector. -/ lemma mfderivWithin_extChartAt_symm_inverse_apply (v : TangentSpace I x) : - (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) (extChartAt I x x)).inverse v = v := by + (mfderiv[range I] (extChartAt I x).symm (extChartAt I x x)).inverse v = v := by rw [mfderivWithin_range_extChartAt_symm, ContinuousLinearMap.inverse_id] exact ContinuousLinearMap.id_apply .. From 3de5ed81cc71b9ea62597b865ba0baaeb5eb0ea9 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 21 Jul 2026 17:14:30 +0000 Subject: [PATCH 0914/1300] chore: remove `suffices` identical to goal (#41974) ``` suffices IsChain R (a::l) by assumption ``` is completely redundant since `IsChain R (a::l)` is already the goal anyways. Maybe (probably) there are more I just found this one by accident. Co-authored-by: Batixx --- Mathlib/Data/List/Destutter.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Data/List/Destutter.lean b/Mathlib/Data/List/Destutter.lean index d4ff78764eaa9d..389ba61aef577b 100644 --- a/Mathlib/Data/List/Destutter.lean +++ b/Mathlib/Data/List/Destutter.lean @@ -105,8 +105,6 @@ theorem destutter'_of_isChain_cons (h : (a :: l).IsChain R) : l.destutter' R a = @[simp] theorem destutter'_eq_self_iff (a) : l.destutter' R a = a :: l ↔ (a :: l).IsChain R := ⟨fun h => by - suffices IsChain R (a::l) by - assumption rw [← h] exact l.isChain_destutter' R a, destutter'_of_isChain_cons _ _⟩ From d08b44007406a632bf0c15c269a89befa2ca08d1 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 21 Jul 2026 20:34:24 +0000 Subject: [PATCH 0915/1300] feat(Analysis): characterizing and congr lemma for toMeromorphicNFAt (#41092) The first two new lemma `toMeromorphicNFAt_of_meromorphicOrderAt_ne_zero` and `MeromorphicAt.meromorphicOrderAt_nonneg_iff_analyticAt_toMeromorphicNFAt` characterize the behavior of `toMeromorphicNFAt` for meromorphic function, so one no longer needs to unfold the definition of it. `toMeromorphicNFAt_congr` and `MeromorphicAt.toMeromorphicNFAt_eventuallyEq_iff` shows that two functions have equal `toMeromorphicNFAt` in nhds if they equal in the punctured nhds. Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Analysis/Meromorphic/NormalForm.lean | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Mathlib/Analysis/Meromorphic/NormalForm.lean b/Mathlib/Analysis/Meromorphic/NormalForm.lean index 013745f17b20d1..d3c63eaa3ab74e 100644 --- a/Mathlib/Analysis/Meromorphic/NormalForm.lean +++ b/Mathlib/Analysis/Meromorphic/NormalForm.lean @@ -437,6 +437,10 @@ lemma MeromorphicAt.eqOn_compl_singleton_toMeromorphicNFAt (hf : MeromorphicAt f toMeromorphicNFAt f x = 0 := by simp [toMeromorphicNFAt, hf] +@[simp] lemma toMeromorphicNFAt_of_meromorphicOrderAt_ne_zero + (horder : meromorphicOrderAt f x ≠ 0) : toMeromorphicNFAt f x x = 0 := by + simp [toMeromorphicNFAt, meromorphicAt_of_meromorphicOrderAt_ne_zero, horder] + /-- Conversion to normal form at `x` changes the value only at x. -/ lemma MeromorphicAt.eq_nhdsNE_toMeromorphicNFAt (hf : MeromorphicAt f x) : f =ᶠ[𝓝[≠] x] toMeromorphicNFAt f x := @@ -472,6 +476,39 @@ theorem meromorphicNFAt_toMeromorphicNFAt : · simp only [toMeromorphicNFAt, hf, ↓reduceDIte] exact analyticAt_const.meromorphicNFAt +@[simp] +lemma MeromorphicAt.meromorphicOrderAt_toMeromorphicNFAt (hf : MeromorphicAt f x) : + meromorphicOrderAt (toMeromorphicNFAt f x) x = meromorphicOrderAt f x := + (meromorphicOrderAt_congr hf.eq_nhdsNE_toMeromorphicNFAt).symm + +lemma MeromorphicAt.meromorphicOrderAt_eq_zero_iff_toMeromorphicNFAt_ne_zero + (hf : MeromorphicAt f x) : + meromorphicOrderAt f x = 0 ↔ toMeromorphicNFAt f x x ≠ 0 := by + simp [← meromorphicNFAt_toMeromorphicNFAt.meromorphicOrderAt_eq_zero_iff, hf] + +lemma MeromorphicAt.meromorphicOrderAt_nonneg_iff_analyticAt_toMeromorphicNFAt + (hf : MeromorphicAt f x) : + 0 ≤ meromorphicOrderAt f x ↔ AnalyticAt 𝕜 (toMeromorphicNFAt f x) x := by + simp [← meromorphicNFAt_toMeromorphicNFAt.meromorphicOrderAt_nonneg_iff_analyticAt, hf] + +@[gcongr] +lemma toMeromorphicNFAt_eventuallyEq_nhds_congr {f g : 𝕜 → E} (hfg : f =ᶠ[𝓝[≠] x] g) : + toMeromorphicNFAt f x =ᶠ[𝓝 x] toMeromorphicNFAt g x := by + by_cases hf : MeromorphicAt f x + · exact meromorphicNFAt_toMeromorphicNFAt.eventuallyEq_nhdsNE_iff_eventuallyEq_nhds + meromorphicNFAt_toMeromorphicNFAt |>.mp <| hf.eq_nhdsNE_toMeromorphicNFAt.symm.trans + <| hfg.trans ((MeromorphicAt.meromorphicAt_congr hfg).mp hf).eq_nhdsNE_toMeromorphicNFAt + · simp [hf, MeromorphicAt.meromorphicAt_congr hfg |>.not.mp] + +@[simp] +lemma MeromorphicAt.toMeromorphicNFAt_eventuallyEq_nhds_iff {f g : 𝕜 → E} (hf : MeromorphicAt f x) + (hg : MeromorphicAt g x) : + toMeromorphicNFAt f x =ᶠ[𝓝 x] toMeromorphicNFAt g x ↔ f =ᶠ[𝓝[≠] x] g where + mp h := + hf.eq_nhdsNE_toMeromorphicNFAt.trans (h.filter_mono nhdsWithin_le_nhds) + |>.trans hg.eq_nhdsNE_toMeromorphicNFAt.symm + mpr := toMeromorphicNFAt_eventuallyEq_nhds_congr + /-- If `f` has normal form at `x`, then `f` equals `f.toNF`. -/ @[simp] theorem toMeromorphicNFAt_eq_self : toMeromorphicNFAt f x = f ↔ MeromorphicNFAt f x where From ece52d227d92315f62cef5b65d1e9db938369c77 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 21 Jul 2026 20:44:46 +0000 Subject: [PATCH 0916/1300] chore: remove redundant `have _` (#41727) Removes most redundant `have _`. Some may remain, but i got to a point of diminishing returns. Like #41716 Co-authored-by: Batixx --- Mathlib/Algebra/MvPolynomial/Division.lean | 2 -- Mathlib/RingTheory/ZMod/UnitsCyclic.lean | 1 - Mathlib/Topology/Algebra/FilterBasis.lean | 1 - Mathlib/Topology/Sheaves/Alexandrov.lean | 1 - 4 files changed, 5 deletions(-) diff --git a/Mathlib/Algebra/MvPolynomial/Division.lean b/Mathlib/Algebra/MvPolynomial/Division.lean index 47a32344741244..557cbd21f024b7 100644 --- a/Mathlib/Algebra/MvPolynomial/Division.lean +++ b/Mathlib/Algebra/MvPolynomial/Division.lean @@ -266,8 +266,6 @@ theorem eq_modMonomial_single_iff (h : X i ∣ p - r) : theorem X_dvd_mul_iff [IsCancelMulZero R] : X i ∣ p * q ↔ X i ∣ p ∨ X i ∣ q := by nontriviality R - have _ : NoZeroDivisors (MvPolynomial σ R) := - IsLeftCancelMulZero.to_noZeroDivisors (MvPolynomial σ R) constructor · intro h suffices (p.modMonomial (Finsupp.single i 1)) * (q.modMonomial (Finsupp.single i 1)) = diff --git a/Mathlib/RingTheory/ZMod/UnitsCyclic.lean b/Mathlib/RingTheory/ZMod/UnitsCyclic.lean index eca1e31672e31a..7bfbeb1bfccd57 100644 --- a/Mathlib/RingTheory/ZMod/UnitsCyclic.lean +++ b/Mathlib/RingTheory/ZMod/UnitsCyclic.lean @@ -196,7 +196,6 @@ theorem orderOf_one_add_prime {p : ℕ} (hp : p.Prime) (hp2 : p ≠ 2) (n : ℕ) /-- If `p` is an odd prime, then `(ZMod (p ^ n))ˣ` is cyclic for all n -/ theorem isCyclic_units_of_prime_pow (p : ℕ) (hp : p.Prime) (hp2 : p ≠ 2) (n : ℕ) : IsCyclic (ZMod (p ^ n))ˣ := by - have _ : NeZero (p ^ n) := ⟨pow_ne_zero n hp.ne_zero⟩ have := Fact.mk hp rcases n with _ | n · rw [pow_zero]; infer_instance diff --git a/Mathlib/Topology/Algebra/FilterBasis.lean b/Mathlib/Topology/Algebra/FilterBasis.lean index 83aeebd4e50250..33f18777ab10a7 100644 --- a/Mathlib/Topology/Algebra/FilterBasis.lean +++ b/Mathlib/Topology/Algebra/FilterBasis.lean @@ -386,7 +386,6 @@ instance (priority := 100) continuousSMul [IsTopologicalRing R] : @ContinuousSMul R M _ _ B.topology := by let B' := B.toAddGroupFilterBasis let _ := B'.topology - have _ := B'.isTopologicalAddGroup exact ContinuousSMul.of_basis_zero B'.nhds_zero_hasBasis (fun {_} => by simpa using! B.smul) (by simpa using! B.smul_left) B.smul_right diff --git a/Mathlib/Topology/Sheaves/Alexandrov.lean b/Mathlib/Topology/Sheaves/Alexandrov.lean index f34b1c9310f3c2..d9a558fe6f13b7 100644 --- a/Mathlib/Topology/Sheaves/Alexandrov.lean +++ b/Mathlib/Topology/Sheaves/Alexandrov.lean @@ -200,5 +200,4 @@ theorem Topology.IsUpperSet.isSheaf_of_isRightKanExtension @rightKanExtensionUnique _ _ _ _ _ _ _ _ _ _ (by assumption) _ _ (by assumption) change TopCat.Presheaf.IsSheaf (X := TopCat.of X) P rw [isSheaf_iso_iff this] - have _ : Topology.IsUpperSet (TopCat.of X) := inferInstanceAs <| Topology.IsUpperSet X exact isSheaf_principalsKanExtension (X := TopCat.of X) F From 7aa191845a29cbdee3ed8cc90fbc56c264cc78f9 Mon Sep 17 00:00:00 2001 From: Evgenia Karunus Date: Tue, 21 Jul 2026 21:06:15 +0000 Subject: [PATCH 0917/1300] feat(Order/Interval/Set/Disjoint): add iUnion_Icc_eq_Ici_self_iff (and dual), iUnion_Ioi_eq_Ioi_iInf, iUnion_Iio_eq_Iio_iSup (#41319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the Carleson project. ___ **Upstreaming from Carleson: [Carleson/ToMathlib/Order/Interval/Set/Disjoint.lean](https://github.com/fpvandoorn/carleson/blob/master/Carleson/ToMathlib/Order/Interval/Set/Disjoint.lean)** Changes from the Carleson version: 1. `IsGLB.biUnion_Ioi_eq_Ioi` theorem is deleted, because Mathlib has `IsGLB.biUnion_Ioi_eq`. `IsGLB.biUnion_Ioi_eq_Ioi` was not referenced anywhere in Carleson (apart from this very file we're porting), so nothing else to clean up. Carleson: ``` #check IsGLB.biUnion_Ioi_eq_Ioi IsGLB.biUnion_Ioi_eq_Ioi.{u_1} {α : Type u_1} [LinearOrder α] {s : Set α} {a : α} (a_glb : IsGLB s a) : ⋃ x ∈ s, Ioi x = Ioi a ``` Mathlib: ``` #check IsGLB.biUnion_Ioi_eq IsGLB.biUnion_Ioi_eq.{v} {α : Type v} [LinearOrder α] {s : Set α} {a : α} (h : IsGLB s a) : ⋃ x ∈ s, Ioi x = Ioi a ``` 2. `Set.iUnion_Icc_eq_Ici_self_iff` upstreamed (verbatim) 3. `Set.iUnion_Icc_eq_Iic_self_iff` newly added theorem, dual of the above 4. `iUnion_Ioi_eq_Ioi_iInf`, `iUnion_Iio_eq_Iio_iSup` - upstreamed (refactored) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Order/Interval/Set/Disjoint.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Order/Interval/Set/Disjoint.lean b/Mathlib/Order/Interval/Set/Disjoint.lean index f42c0a674c0c52..acc9039263b971 100644 --- a/Mathlib/Order/Interval/Set/Disjoint.lean +++ b/Mathlib/Order/Interval/Set/Disjoint.lean @@ -149,6 +149,11 @@ theorem iUnion_Ioc_eq_Ioi_self_iff {f : ι → α} {a : α} : ⋃ i, Ioc a (f i) = Ioi a ↔ ∀ x, a < x → ∃ i, x ≤ f i := by simp [← Ioi_inter_Iic, ← inter_iUnion, subset_def] +@[to_dual (attr := simp)] +theorem iUnion_Icc_eq_Ici_self_iff {f : ι → α} {a : α} : + ⋃ i, Icc a (f i) = Ici a ↔ ∀ x ≥ a, ∃ i, x ≤ f i := by + simp [← Ici_inter_Iic, ← inter_iUnion, subset_def] + @[simp] theorem biUnion_Ico_eq_Iio_self_iff {p : ι → Prop} {f : ∀ i, p i → α} {a : α} : ⋃ (i) (hi : p i), Ico (f i hi) a = Iio a ↔ ∀ x < a, ∃ i hi, f i hi ≤ x := by @@ -182,6 +187,14 @@ theorem IsLUB.biUnion_Iio_eq (h : IsLUB s a) : ⋃ x ∈ s, Iio x = Iio a := theorem IsLUB.iUnion_Iio_eq (h : IsLUB (range f) a) : ⋃ x, Iio (f x) = Iio a := h.dual.iUnion_Ioi_eq +theorem iUnion_Ioi_eq_Ioi_iInf {R : Type*} [CompleteLinearOrder R] {f : ι → R} : + ⋃ i : ι, Ioi (f i) = Ioi (⨅ i, f i) := + isGLB_iInf.iUnion_Ioi_eq + +theorem iUnion_Iio_eq_Iio_iSup {R : Type*} [CompleteLinearOrder R] {f : ι → R} : + ⋃ i : ι, Iio (f i) = Iio (⨆ i, f i) := + isLUB_iSup.iUnion_Iio_eq + theorem IsGLB.biUnion_Ici_eq_Ioi (a_glb : IsGLB s a) (a_notMem : a ∉ s) : ⋃ x ∈ s, Ici x = Ioi a := by refine (iUnion₂_subset fun x hx => ?_).antisymm fun x hx => ?_ From 5a23ed22eb909450ebabb930bb1bb62ecefa1063 Mon Sep 17 00:00:00 2001 From: Rida Hamadani Date: Tue, 21 Jul 2026 21:06:17 +0000 Subject: [PATCH 0918/1300] chore(Combinatorics/SimpleGraph): fix naming of `colorable_iff_forall_connectedComponents` (#41648) Adhering by the naming convention, the `connectedComponents` in `colorable_iff_forall_connectedComponents` should be singular. --- .../Combinatorics/SimpleGraph/Coloring/Constructions.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Constructions.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Constructions.lean index 7f66cbecdec51d..2710470c5a078f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Constructions.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Constructions.lean @@ -173,7 +173,7 @@ lemma two_colorable_iff_forall_loop_even {α : Type*} {G : SimpleGraph α} : · intro _ w ho have := (w.three_le_chromaticNumber_of_odd_loop ho).trans h.chromaticNumber_le norm_cast - · apply colorable_iff_forall_connectedComponents.2 + · apply colorable_iff_forall_connectedComponent.2 intro c obtain ⟨_, hv⟩ := c.nonempty_supp use fun a ↦ Fin.ofNat 2 (c.connected_toSimpleGraph ⟨_, hv⟩ a).some.length diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean index b5feae588bcaeb..8116036b084a49 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean @@ -314,11 +314,14 @@ theorem colorable_iff_exists_bdd_nat_coloring (n : ℕ) : simp only [Fin.mk_eq_mk, Ne] exact C.valid hvw -theorem colorable_iff_forall_connectedComponents {n : ℕ} : +theorem colorable_iff_forall_connectedComponent {n : ℕ} : G.Colorable n ↔ ∀ c : G.ConnectedComponent, (c.toSimpleGraph).Colorable n := ⟨fun ⟨C⟩ _ ↦ ⟨fun v ↦ C v, fun h h1 ↦ C.valid h h1⟩, fun h ↦ ⟨G.homOfConnectedComponents (fun c ↦ (h c).some)⟩⟩ +@[deprecated (since := "2026-07-12")] +alias colorable_iff_forall_connectedComponents := colorable_iff_forall_connectedComponent + theorem colorable_set_nonempty_of_colorable {n : ℕ} (hc : G.Colorable n) : { n : ℕ | G.Colorable n }.Nonempty := ⟨n, hc⟩ From e94b481ea884a59a092232194641a42a796ddf37 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:41:12 +0000 Subject: [PATCH 0919/1300] refactor(Archive/Imo/Imo2000Q2): replace SOS certificate with classical AM-GM argument (#41267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR rewrites the proof of IMO 2000 Q2 from https://github.com/leanprover-community/mathlib4/pull/40286. It drops the second (Ravi) substitution and the SOS-solver-found certificate in favour of the classical argument: at most one of the three factors is nonpositive, and in the all-positive case each pairwise product is bounded by a square via AM-GM. One helper lemma instead of three, and every inequality step is a visible `sq_nonneg`. Supersedes #41263. 🤖 Prepared with Claude Code --- Archive/Imo/Imo2000Q2.lean | 105 ++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 60 deletions(-) diff --git a/Archive/Imo/Imo2000Q2.lean b/Archive/Imo/Imo2000Q2.lean index 94d7670e8d0faa..894763bc8507f5 100644 --- a/Archive/Imo/Imo2000Q2.lean +++ b/Archive/Imo/Imo2000Q2.lean @@ -17,21 +17,14 @@ We follow the first solution from . We parametrize `A = x / y`, `B = y / z`, `C = z / x` where `x, y, z > 0`. -This reduces the problem to proving `(x - y + z)(y - z + x)(z - x + y) ≤ 8xyz`. +This reduces the problem to proving `(x - y + z)(y - z + x)(z - x + y) ≤ xyz`. -We then reparametrize `x = q + r`, `y = r + p`, `z = p + q` where `p, q, r ∈ ℝ`, -which transforms the inequality to `8pqr ≤ (q + r)(r + p)(p + q)`. - -The proof splits into cases based on the signs of `p`, `q`, `r`. -When all are positive, AM-GM gives the result. -When at least one is negative or zero, the inequality is verified by sign analysis. - -## Implementation notes - -- The inequality is reduced via `A = x / y`, `B = y / z`, `C = z / x`, then the substitution - `x = q + r`, `y = r + p`, `z = p + q`. -- Helper lemmas prove `8pqr ≤ (p + q)(r + p)(q + r)` by AM-GM when `p, q, r > 0` and by sign - analysis otherwise; the main proof closes with `grind`. +Writing `u = x - y + z`, `v = y - z + x`, `w = z - x + y`, we have `u + v = 2x`, +`v + w = 2y`, `w + u = 2z`, so any two of `u`, `v`, `w` have a positive sum and hence +at most one of them can be nonpositive. If one is nonpositive the left-hand side is +nonpositive and the inequality is clear. Otherwise all three are positive, and by AM-GM +`uv ≤ ((u + v) / 2) ^ 2 = x ^ 2`, and similarly `vw ≤ y ^ 2` and `wu ≤ z ^ 2`; multiplying +these gives `(uvw) ^ 2 ≤ (xyz) ^ 2`, from which the inequality follows. ## References @@ -41,48 +34,39 @@ When at least one is negative or zero, the inequality is verified by sign analys namespace Imo2000Q2 -/-- When `p`, `q`, `r > 0`, `8pqr ≤ (p + q)(r + p)(q + r)`, by writing the difference of squares as -a sum of nonnegative squares. -/ -lemma eight_mul_le_prod_add_of_pos {p q r : ℝ} (p_pos : 0 < p) - (q_pos : 0 < q) (r_pos : 0 < r) : - 8 * p * q * r ≤ (p + q) * (q + r) * (r + p) := by - suffices 0 ≤ ((p + q) * (q + r) * (r + p)) ^ 2 - (8 * p * q * r) ^ 2 from - le_of_sq_le_sq (le_of_sub_nonneg this) (by positivity) - calc 0 ≤ (p * (q - r) ^ 2 + q * (r - p) ^ 2 + r * (p - q) ^ 2) - * ((p + q) * (q + r) * (r + p) + 8 * p * q * r) := by positivity - _ = ((p + q) * (q + r) * (r + p)) ^ 2 - (8 * p * q * r) ^ 2 := by ring - -/-- When `p ≤ 0` but `q`, `r > 0` and both pairwise sums are positive, the left side is -nonpositive so the inequality holds. -/ -lemma eight_mul_le_prod_add_of_nonpos {p q r : ℝ} (p_nonpos : p ≤ 0) (r_pos : 0 < r) (q_pos : 0 < q) - (p_add_q_pos : 0 < p + q) (r_add_p_pos : 0 < r + p) : - 8 * p * q * r ≤ (p + q) * (r + p) * (q + r) := by - calc 8 * p * q * r ≤ 0 := by grw [mul_nonpos_of_nonpos_of_nonneg ?_ (by positivity)] - grw [mul_nonpos_of_nonpos_of_nonneg (by grind) (by positivity)] - _ ≤ (p + q) * (r + p) * (q + r) := by positivity - -/-- When all three pairwise sums `p + q`, `r + p`, `q + r` are positive, the inequality holds by -casing on the signs of `p`, `q`, `r`. -/ -lemma eight_mul_le_prod_add_of_add_pos (p q r : ℝ) - (hpq : 0 < p + q := by grind) - (hqr : 0 < q + r := by grind) - (hrp : 0 < r + p := by grind) : - 8 * p * q * r ≤ (p + q) * (q + r) * (r + p) := by - rcases lt_or_ge 0 p with p_pos | p_nonpos <;> - rcases lt_or_ge 0 q with q_pos | q_nonpos <;> - rcases lt_or_ge 0 r with r_pos | r_nonpos - -- At most one of `p`, `q`, `r` can be negative; otherwise some pairwise sum is nonpositive. - · exact eight_mul_le_prod_add_of_pos p_pos q_pos r_pos - · -- `r` is the unique nonpositive variable. - convert eight_mul_le_prod_add_of_nonpos r_nonpos q_pos p_pos hrp hqr using 1 <;> ring - · -- `q` is the unique nonpositive variable. - convert eight_mul_le_prod_add_of_nonpos q_nonpos p_pos r_pos hqr hpq using 1 <;> ring - · linarith - · -- `p` is the unique nonpositive variable. - convert eight_mul_le_prod_add_of_nonpos p_nonpos r_pos q_pos hpq hrp using 1; ring - · linarith - · linarith - · linarith +/-- For positive reals `x`, `y`, `z` we have `(x - y + z)(y - z + x)(z - x + y) ≤ xyz`. -/ +lemma prod_sub_add_le {x y z : ℝ} (hx : 0 < x) (hy : 0 < y) (hz : 0 < z) : + (x - y + z) * (y - z + x) * (z - x + y) ≤ x * y * z := by + -- At most one of the three factors can be nonpositive, since any two of them + -- sum to twice one of `x`, `y`, `z`. If one is nonpositive, so is the product. + rcases le_or_gt (x - y + z) 0 with hu | hu + · have hv : 0 < y - z + x := by linarith + have hw : 0 < z - x + y := by linarith + calc (x - y + z) * (y - z + x) * (z - x + y) + ≤ 0 := mul_nonpos_of_nonpos_of_nonneg + (mul_nonpos_of_nonpos_of_nonneg hu hv.le) hw.le + _ ≤ x * y * z := by positivity + rcases le_or_gt (y - z + x) 0 with hv | hv + · have hw : 0 < z - x + y := by linarith + calc (x - y + z) * (y - z + x) * (z - x + y) + ≤ 0 := mul_nonpos_of_nonpos_of_nonneg + (mul_nonpos_of_nonneg_of_nonpos hu.le hv) hw.le + _ ≤ x * y * z := by positivity + rcases le_or_gt (z - x + y) 0 with hw | hw + · calc (x - y + z) * (y - z + x) * (z - x + y) + ≤ 0 := mul_nonpos_of_nonneg_of_nonpos (mul_nonneg hu.le hv.le) hw + _ ≤ x * y * z := by positivity + -- All three factors are positive. By AM-GM each pairwise product is bounded by a square: + have h1 : (x - y + z) * (y - z + x) ≤ x ^ 2 := by linarith [sq_nonneg (y - z)] + have h2 : (y - z + x) * (z - x + y) ≤ y ^ 2 := by linarith [sq_nonneg (z - x)] + have h3 : (z - x + y) * (x - y + z) ≤ z ^ 2 := by linarith [sq_nonneg (x - y)] + -- Multiplying the three bounds gives the squared inequality, and both sides are positive. + refine le_of_sq_le_sq ?_ (by positivity) + calc ((x - y + z) * (y - z + x) * (z - x + y)) ^ 2 + = ((x - y + z) * (y - z + x)) * ((y - z + x) * (z - x + y)) + * ((z - x + y) * (x - y + z)) := by ring + _ ≤ x ^ 2 * y ^ 2 * z ^ 2 := by gcongr + _ = (x * y * z) ^ 2 := by ring /-- **IMO 2000 Q2**. If `A`, `B`, `C > 0` and `ABC = 1`, then `(A - 1 + 1 / B)(B - 1 + 1 / C)(C - 1 + 1 / A) ≤ 1`. -/ @@ -92,9 +76,10 @@ theorem imo2000_q2 {A B C : ℝ} obtain ⟨x, y, z, x_pos, y_pos, z_pos, rfl, rfl, rfl⟩ : ∃ x y z, 0 < x ∧ 0 < y ∧ 0 < z ∧ A = x / y ∧ B = y / z ∧ C = z / x := ⟨A, 1, 1 / B, by grind only [inv_pos]⟩ - -- If `x = q + r`, `y = r + p`, `z = p + q`, it suffices to show `8pqr ≤ (q + r)(r + p)(p + q)`. - have := eight_mul_le_prod_add_of_add_pos ((y + z - x) / 2) ((z + x - y) / 2) ((x + y - z) / 2) - field_simp - grind + have key : (x / y - 1 + 1 / (y / z)) * (y / z - 1 + 1 / (z / x)) * (z / x - 1 + 1 / (x / y)) + = (x - y + z) * (y - z + x) * (z - x + y) / (x * y * z) := by + field_simp + rw [key, div_le_one (by positivity)] + exact prod_sub_add_le x_pos y_pos z_pos end Imo2000Q2 From e9cf26e723a4bc51b8a5fe2ea3a4392f196d48de Mon Sep 17 00:00:00 2001 From: Li Jiale <185082061+Scarlett-le@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:41:14 +0000 Subject: [PATCH 0920/1300] =?UTF-8?q?feat(Geometry/Euclidean/Angle/Sphere)?= =?UTF-8?q?:=20central=20angle=20equals=20=CF=80=20iff=20diameter,=200=20i?= =?UTF-8?q?ff=20equal=20points=20(#41314)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two lemmas characterising the two degenerate values of the central angle `∠ p₁ s.center p₂` on a sphere of nonzero radius: * `EuclideanGeometry.Sphere.angle_center_eq_pi_iff_isDiameter`: the central angle is `π` iff `p₁` and `p₂` are the endpoints of a diameter (`s.IsDiameter p₁ p₂`). * `EuclideanGeometry.Sphere.angle_center_eq_zero_iff_eq`: the central angle is `0` iff `p₁ = p₂`. Co-authored-by: Scarlett-le <735979178@qq.com> --- Mathlib/Geometry/Euclidean/Angle/Sphere.lean | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mathlib/Geometry/Euclidean/Angle/Sphere.lean b/Mathlib/Geometry/Euclidean/Angle/Sphere.lean index 884fb30fa6fba4..82667ad1417015 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Sphere.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Sphere.lean @@ -126,6 +126,26 @@ theorem isDiameter_of_angle_eq_pi_div_two {p₁ p₂ p₃ : P} {s : Sphere P} exact this.elim hne₁₂.symm hne₂₃ exact h_eq ▸ hd +/-- On a sphere of nonzero radius, the central angle `∠ p₁ s.center p₂` equals `π` iff +`p₁` and `p₂` are diametrically opposite. -/ +theorem angle_center_eq_pi_iff_isDiameter {s : Sphere P} {p₁ p₂ : P} + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (hr : s.radius ≠ 0) : + ∠ p₁ s.center p₂ = π ↔ s.IsDiameter p₁ p₂ := by + rw [angle_eq_pi_iff_sbtw] + exact ⟨fun h => isDiameter_iff_mem_and_mem_and_wbtw.2 ⟨hp₁, hp₂, h.wbtw⟩, fun h => h.sbtw hr⟩ + +/-- On a sphere of nonzero radius, the central angle `∠ p₁ s.center p₂` equals zero iff +`p₁ = p₂`. -/ +theorem angle_center_eq_zero_iff_eq {s : Sphere P} {p₁ p₂ : P} + (hp₁ : p₁ ∈ s) (hp₂ : p₂ ∈ s) (hr : s.radius ≠ 0) : + ∠ p₁ s.center p₂ = 0 ↔ p₁ = p₂ := by + constructor + · intro h + refine vsub_left_cancel (eq_of_angle_eq_zero_of_norm_eq (by simpa [angle] using h) ?_) + rw [norm_vsub_center_eq_radius hp₁, norm_vsub_center_eq_radius hp₂] + · rintro rfl + exact angle_self_of_ne fun h => hr (center_mem_iff.mp (h ▸ hp₁)) + /-- For a tangent line to a sphere, the angle between the line and the radius at the tangent point equals `π / 2`. -/ theorem IsTangentAt.angle_eq_pi_div_two {s : Sphere P} {p q : P} {as : AffineSubspace ℝ P} From 518fa20575f6d23a0b1aa2f91c4e241b5f1b24d3 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:41:16 +0000 Subject: [PATCH 0921/1300] feat(NumberTheory/SumPrimeReciprocals): represent sums/products over Nat.Primes as sums/products over Nat (#41461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `Nat.Primes.tsum_eq_tsum_ite`: `∑' p : Nat.Primes, f p = ∑' n, if n.Prime then f n else 0`, reindexing a sum over the prime subtype as a sum over `ℕ` with composite terms zeroed. A thin consequence of `tsum_subtype`, used downstream in the Meissel-Mertens constant development. Analogous lemmas for `Summable` and `HasSum` also added, as well as multiplicative versions. Co-authored-by: Terence Tao --- Mathlib/NumberTheory/SumPrimeReciprocals.lean | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Mathlib/NumberTheory/SumPrimeReciprocals.lean b/Mathlib/NumberTheory/SumPrimeReciprocals.lean index 9b40e11edb9ca9..057a61481806b7 100644 --- a/Mathlib/NumberTheory/SumPrimeReciprocals.lean +++ b/Mathlib/NumberTheory/SumPrimeReciprocals.lean @@ -30,6 +30,36 @@ public section open Set Nat open scoped Topology +section PrimeSums + +variable {M : Type*} [CommMonoid M] [TopologicalSpace M] (f : ℕ → M) + +omit [TopologicalSpace M] in +@[to_additive] +private lemma ite_prime_eq_mulIndicator : + (fun n : ℕ ↦ if n.Prime then f n else 1) = {n | n.Prime}.mulIndicator f := by + ext; simp [Set.mulIndicator_apply] + +/-- Reindex a product over `Nat.Primes` as a product over `ℕ`, extending `f` by `1`. -/ +@[to_additive /-- Reindex a sum over `Nat.Primes` as a sum over `ℕ`, extending `f` by `0`. -/] +theorem Nat.Primes.tprod_eq_tprod_ite : + ∏' p : Primes, f p = ∏' n : ℕ, if n.Prime then f n else 1 := by + rw [ite_prime_eq_mulIndicator]; exact tprod_subtype {n | n.Prime} f + +/-- `Multipliable` over `Nat.Primes` iff over `ℕ` extending `f` by `1`. -/ +@[to_additive /-- `Summable` over `Nat.Primes` iff over `ℕ` extending `f` by `0`. -/] +theorem Nat.Primes.multipliable_iff_multipliable_ite : + Multipliable (fun p : Primes ↦ f p) ↔ Multipliable fun n : ℕ ↦ if n.Prime then f n else 1 := by + rw [ite_prime_eq_mulIndicator]; exact multipliable_subtype_iff_mulIndicator + +/-- `HasProd` over `Nat.Primes` iff over `ℕ` extending `f` by `1`. -/ +@[to_additive /-- `HasSum` over `Nat.Primes` iff over `ℕ` extending `f` by `0`. -/] +theorem Nat.Primes.hasProd_iff_hasProd_ite {a : M} : + HasProd (fun p : Primes ↦ f p) a ↔ HasProd (fun n : ℕ ↦ if n.Prime then f n else 1) a := by + rw [ite_prime_eq_mulIndicator]; exact hasProd_subtype_iff_mulIndicator + +end PrimeSums + /-- The cardinality of the set of `k`-rough numbers `≤ N` is bounded by `N` times the sum of `1/p` over the primes `k ≤ p ≤ N`. -/ -- This needs `Mathlib/Analysis/RCLike/Basic.lean`, so we put it here From 2b40556aa883f0160f2dabdb3eae767b1cc3f4fd Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:41:18 +0000 Subject: [PATCH 0922/1300] chore(Analysis/RCLike/Basic): state norm_I with positive polarity (#41585) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR restates `RCLike.norm_I` with the `if` condition in positive polarity, changing the RHS from `if (I : K) ≠ 0 then 1 else 0` to `if (I : K) = 0 then 0 else 1`. The latter is the simp-normal form (`ne_eq` and `ite_not` rewrite the former to it) and matches every comparable `if _ = 0 then 0 else 1` statement in Mathlib; the negated form was the only one of its kind. The proof is unchanged and there are no downstream uses of the lemma yet. Follow-up to [#41359 (feat(Analysis/RCLike/Basic): add norm_I)](https://github.com/leanprover-community/mathlib4/pull/41359). 🤖 Prepared with Claude Code --- Mathlib/Analysis/RCLike/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 7317a175c1516b..6dfc89e90b652b 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -728,7 +728,7 @@ theorem norm_I_of_ne_zero (hI : (I : K) ≠ 0) : ‖(I : K)‖ = 1 := by rw [← mul_self_inj_of_nonneg (norm_nonneg I) zero_le_one, one_mul, ← norm_mul, I_mul_I_of_nonzero hI, norm_neg, norm_one] -theorem norm_I : ‖(I : K)‖ = if (I : K) ≠ 0 then 1 else 0 := by +theorem norm_I : ‖(I : K)‖ = if (I : K) = 0 then 0 else 1 := by grind [norm_I_of_ne_zero, norm_eq_zero] theorem re_eq_norm_of_mul_conj (x : K) : re (x * conj x) = ‖x * conj x‖ := by From 6421d4ee2b6741a3cd115360f647e42635c9f680 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Tue, 21 Jul 2026 21:41:20 +0000 Subject: [PATCH 0923/1300] chore: fix argument names of `MonoidAlgebra.induction_on` (#41900) Fix argument names for `MonoidAlgebra.induction_on` and `AddMonoidAlgebra.induction_on` and `MonoidAlgebra.induction_linear`. Name the motive `motive` and name the minor premises according to their contents. --- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 37 +++++++++++++------------ Mathlib/RepresentationTheory/Basic.lean | 6 ++-- Mathlib/RingTheory/FiniteType.lean | 24 ++++++++-------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index a5beaaa061b008..17a0cca0379ccd 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -443,10 +443,10 @@ lemma induction {motive : R[M] → Prop} (x : R[M]) (by simpa using zero) (fun m r x ↦ single_add m r (ofCoeff x)) @[to_additive (attr := elab_as_elim)] -lemma induction_linear {p : R[M] → Prop} (x : R[M]) (zero : p 0) - (add : ∀ x y : R[M], p x → p y → p (x + y)) - (single : ∀ m r, p (single m r)) : p x := - Finsupp.induction_linear (motive := (p <| ofCoeff ·)) x.coeff zero (fun _ _ ↦ add _ _) +lemma induction_linear {motive : R[M] → Prop} (x : R[M]) (zero : motive 0) + (add : ∀ x y : R[M], motive x → motive y → motive (x + y)) + (single : ∀ m r, motive (single m r)) : motive x := + Finsupp.induction_linear (motive := (motive <| ofCoeff ·)) x.coeff zero (fun _ _ ↦ add _ _) (fun _ _ ↦ single _ _) @[to_additive (attr := simp) addSubmonoidClosure_single] @@ -729,13 +729,13 @@ lemma single_pow (m : M) (r : R) : ∀ n : ℕ, single m r ^ n = single (m ^ n) | 0 => by simp [one_def] | n + 1 => by simp [pow_succ, single_pow _ _ n] -lemma induction_on {p : R[M] → Prop} (x : R[M]) - (hM : ∀ m, p (of R M m)) (hadd : ∀ x y : R[M], p x → p y → p (x + y)) - (hsmul : ∀ (r : R) (x), p x → p (r • x)) : p x := - Finsupp.induction_linear (motive := fun x ↦ p <| ofCoeff x) x.coeff - (by simpa using hsmul 0 (of R M 1) (hM 1)) - (fun x y hf hg ↦ hadd (ofCoeff x) (ofCoeff y) hf hg) - fun m r ↦ by simpa using hsmul r (of R M m) (hM m) +lemma induction_on {motive : R[M] → Prop} (x : R[M]) + (of : ∀ m, motive (.of R M m)) (add : ∀ x y : R[M], motive x → motive y → motive (x + y)) + (smul : ∀ (r : R) (x), motive x → motive (r • x)) : motive x := + Finsupp.induction_linear (motive := fun x ↦ motive <| ofCoeff x) x.coeff + (by simpa using smul 0 (.of R M 1) (of 1)) + (fun x y hf hg ↦ add (ofCoeff x) (ofCoeff y) hf hg) + fun m r ↦ by simpa using smul r (.of R M m) (of m) @[to_additive (dont_translate := R)] instance isLocalHom_singleOneRingHom : IsLocalHom (singleOneRingHom (R := R) (M := M)) where @@ -1001,13 +1001,14 @@ def singleHom [AddZeroClass M] : R × Multiplicative M →* R[M] where map_mul' _a _b := (single_mul_single ..).symm set_option backward.isDefEq.respectTransparency false in -theorem induction_on [AddMonoid M] {p : R[M] → Prop} (x : R[M]) - (hM : ∀ m, p (of R M <| .ofAdd m)) (hadd : ∀ x y : R[M], p x → p y → p (x + y)) - (hsmul : ∀ (r : R) (x), p x → p (r • x)) : p x := - Finsupp.induction_linear (motive := fun x ↦ p (ofCoeff x)) x.coeff - (by simpa using hsmul 0 (of R M 1) (hM 0)) - (fun x y hf hg ↦ hadd (ofCoeff x) (ofCoeff y) hf hg) - fun m r ↦ by simpa using! hsmul r (of R M m) (hM m) +theorem induction_on [AddMonoid M] {motive : R[M] → Prop} (x : R[M]) + (of : ∀ m, motive (.of R M <| .ofAdd m)) + (add : ∀ x y : R[M], motive x → motive y → motive (x + y)) + (smul : ∀ (r : R) (x), motive x → motive (r • x)) : motive x := + Finsupp.induction_linear (motive := fun x ↦ motive (ofCoeff x)) x.coeff + (by simpa using smul 0 (.of R M 1) (of 0)) + (fun x y hf hg ↦ add (ofCoeff x) (ofCoeff y) hf hg) + fun m r ↦ by simpa using! smul r (.of R M m) (of m) /-- If two ring homomorphisms from `R[M]` are equal on all `single m 1` and `single 0 r`, then they are equal. diff --git a/Mathlib/RepresentationTheory/Basic.lean b/Mathlib/RepresentationTheory/Basic.lean index aba2c6dd1bd0f4..a0d2d91c6d1a9c 100644 --- a/Mathlib/RepresentationTheory/Basic.lean +++ b/Mathlib/RepresentationTheory/Basic.lean @@ -497,9 +497,9 @@ variable {k G V : Type*} [CommSemiring k] [Group G] [AddCommMonoid V] [Module k lemma asAlgebraHom_ofMulAction_smul_eq_mul (x y : k[G]) : (ofMulAction k G G).asAlgebraHom x y = x * y := by induction x using induction_on with - | hM g => ext; simp [MonoidAlgebra.coeff_single_mul_apply] - | hadd x y hx hy => simp [hx, hy, add_mul] - | hsmul r x hx => simp [← hx] + | of g => ext; simp [MonoidAlgebra.coeff_single_mul_apply] + | add x y hx hy => simp [hx, hy, add_mul] + | smul r x hx => simp [← hx] @[deprecated (since := "2026-06-18")] alias ofMulAction_self_smul_eq_mul := asAlgebraHom_ofMulAction_smul_eq_mul diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index c9944661684578..0e3083e6021af4 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -382,7 +382,7 @@ theorem mvPolynomial_aeval_of_surjective_of_closure [AddCommMonoid M] [CommSemir (MvPolynomial.aeval fun s : S => of' R M ↑s : MvPolynomial S R → R[M]) := by intro f induction f using induction_on with - | hM m => + | of m => have : m ∈ closure S := hS.symm ▸ mem_top _ refine AddSubmonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨MvPolynomial.X ⟨m, hm⟩, MvPolynomial.aeval_X _ _⟩ @@ -392,11 +392,11 @@ theorem mvPolynomial_aeval_of_surjective_of_closure [AddCommMonoid M] [CommSemir ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, one_mul]; rfl⟩ - | hadd f g ihf ihg => + | add f g ihf ihg => rcases ihf with ⟨P, rfl⟩ rcases ihg with ⟨Q, rfl⟩ exact ⟨P + Q, map_add _ _ _⟩ - | hsmul r f ih => + | smul r f ih => rcases ih with ⟨P, rfl⟩ exact ⟨r • P, map_smul _ _ _⟩ @@ -410,7 +410,7 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} (FreeAlgebra.lift R fun s : S => of' R M ↑s : FreeAlgebra R S → R[M]) := by intro f induction f using induction_on with - | hM m => + | of m => have : m ∈ closure S := hS.symm ▸ mem_top _ refine AddSubmonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨FreeAlgebra.ι R ⟨m, hm⟩, FreeAlgebra.lift_ι_apply _ _⟩ @@ -420,11 +420,11 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, one_mul]; rfl⟩ - | hadd f g ihf ihg => + | add f g ihf ihg => rcases ihf with ⟨P, rfl⟩ rcases ihg with ⟨Q, rfl⟩ exact ⟨P + Q, map_add _ _ _⟩ - | hsmul r f ih => + | smul r f ih => rcases ih with ⟨P, rfl⟩ exact ⟨r • P, map_smul _ _ _⟩ @@ -531,7 +531,7 @@ theorem mvPolynomial_aeval_of_surjective_of_closure [CommMonoid M] [CommSemiring (MvPolynomial.aeval fun s : S => of R M ↑s : MvPolynomial S R → R[M]) := by intro f induction f using induction_on with - | hM m => + | of m => have : m ∈ closure S := hS.symm ▸ mem_top _ refine Submonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨MvPolynomial.X ⟨m, hm⟩, MvPolynomial.aeval_X _ _⟩ @@ -540,10 +540,10 @@ theorem mvPolynomial_aeval_of_surjective_of_closure [CommMonoid M] [CommSemiring exact ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, one_mul]⟩ - | hadd f g ihf ihg => + | add f g ihf ihg => rcases ihf with ⟨P, rfl⟩; rcases ihg with ⟨Q, rfl⟩ exact ⟨P + Q, map_add _ _ _⟩ - | hsmul r f ih => + | smul r f ih => rcases ih with ⟨P, rfl⟩ exact ⟨r • P, map_smul _ _ _⟩ @@ -558,7 +558,7 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} (FreeAlgebra.lift R fun s : S => of R M ↑s : FreeAlgebra R S → R[M]) := by intro f induction f using induction_on with - | hM m => + | of m => have : m ∈ closure S := hS.symm ▸ mem_top _ refine Submonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨FreeAlgebra.ι R ⟨m, hm⟩, FreeAlgebra.lift_ι_apply _ _⟩ @@ -567,11 +567,11 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} exact ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, one_mul]⟩ - | hadd f g ihf ihg => + | add f g ihf ihg => rcases ihf with ⟨P, rfl⟩ rcases ihg with ⟨Q, rfl⟩ exact ⟨P + Q, map_add _ _ _⟩ - | hsmul r f ih => + | smul r f ih => rcases ih with ⟨P, rfl⟩ exact ⟨r • P, map_smul _ _ _⟩ From 1254e7173d9dd4c53591a69900929f83ba5ba189 Mon Sep 17 00:00:00 2001 From: SofiaSL <84034608+SofiaSL@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:41:22 +0000 Subject: [PATCH 0924/1300] feat: a Hilbert Basis is a (unconditional) Schauder basis (#41906) Added definitions that allow us to convert a Hilbert basis to a Schauder basis or an unconditional Schauder basis. This is related to, but does not depend on PR #41840. This is the second in a sequence of PRs I and Alan have planned proving that the Hermite polynomials are orthogonal under the appropriate inner product, and that they form a basis of the associated Hilbert space. This code was written with AI assistance at the ICARM summer school on formalization of mathematics and verified by me. Co-authored-by: Alan Li Co-authored-by: Sofia Co-authored-by: Alan Li --- .../Analysis/InnerProductSpace/l2Space.lean | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/l2Space.lean b/Mathlib/Analysis/InnerProductSpace/l2Space.lean index 0c6511cea107d4..e2bc31114865e1 100644 --- a/Mathlib/Analysis/InnerProductSpace/l2Space.lean +++ b/Mathlib/Analysis/InnerProductSpace/l2Space.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.InnerProductSpace.Projection.Basic public import Mathlib.Analysis.Normed.Lp.lpSpace public import Mathlib.Analysis.InnerProductSpace.PiL2 +public import Mathlib.Analysis.Normed.Module.Bases /-! # Hilbert sum of a family of inner product spaces @@ -54,6 +55,12 @@ We also define a *predicate* `IsHilbertSum 𝕜 G V`, where `V : Π i, G i → * `HilbertBasis.mkOfOrthogonalEqBot`: Make a Hilbert basis of `E` from an orthonormal family `v : ι → E` of vectors in `E` whose span has trivial orthogonal complement. +* `HilbertBasis.toUnconditionalSchauderBasis`: Convert a Hilbert basis of `E` into an unconditional + Schauder basis (`UnconditionalSchauderBasis`), with coordinate functionals `x ↦ ⟪b i, x⟫`. + +* `HilbertBasis.toSchauderBasis`: Convert a Hilbert basis of `E` indexed by `ℕ` into a classical + Schauder basis (`SchauderBasis`). + ## Main results * `lp.instInnerProductSpace`: Construction of the inner product space instance on the Hilbert sum @@ -483,6 +490,29 @@ theorem coe_toOrthonormalBasis [Fintype ι] (b : HilbertBasis ι 𝕜 E) : (b.toOrthonormalBasis : ι → E) = b := OrthonormalBasis.coe_mk _ _ +/-- A Hilbert basis of is an unconditional Schauder basis (`UnconditionalSchauderBasis`), +with coordinate functionals `x ↦ ⟪b i, x⟫`. The basis expansion `x = ∑' i, ⟪b i, x⟫ • b i` +converges unconditionally. -/ +@[simps] +protected def toUnconditionalSchauderBasis (b : HilbertBasis ι 𝕜 E) : + UnconditionalSchauderBasis ι 𝕜 E where + basis := b + coord i := innerSL 𝕜 (b i) + ortho i j := by + classical + simpa [innerSL_apply_apply, Pi.single_apply] using orthonormal_iff_ite.mp b.orthonormal i j + expansion x := by + simpa only [innerSL_apply_apply, ← b.repr_apply_apply] using b.hasSum_repr x + +/-- Every Hilbert basis indexed by `ℕ` is a Schauder basis (`SchauderBasis`) with +coordinate functionals `x ↦ ⟪b i, x⟫`. The expansion `x = ∑ i, ⟪b i, x⟫ • b i` converges. -/ +@[simps] +protected def toSchauderBasis (b : HilbertBasis ℕ 𝕜 E) : SchauderBasis 𝕜 E where + basis := ⇑b + coord i := innerSL 𝕜 (b i) + ortho := b.toUnconditionalSchauderBasis.ortho + expansion x := (b.toUnconditionalSchauderBasis.expansion x).mono_left SummationFilter.le_atTop + protected theorem hasSum_orthogonalProjectionOnto {U : Submodule 𝕜 E} [CompleteSpace U] (b : HilbertBasis ι 𝕜 U) (x : E) : HasSum (fun i => ⟪(b i : E), x⟫ • b i) (U.orthogonalProjectionOnto x) := by From 27d317e991a3d34e0a2c77d4ea169eacf7d33121 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 21 Jul 2026 22:12:35 +0000 Subject: [PATCH 0925/1300] feat(Analysis): sum of sines and cosines (#41170) Some elementary results that I find convenient to have --- .../Trigonometric/Complex.lean | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean index d9b4042693f612..1ce811d7089ef0 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Complex.lean @@ -26,7 +26,7 @@ noncomputable section namespace Complex -open Set Filter +open Set Filter Finset open scoped Real @@ -253,11 +253,52 @@ theorem sin_surjective : Function.Surjective sin := by theorem range_sin : Set.range sin = Set.univ := sin_surjective.range_eq +theorem sin_mul_sum_sin (n : ℕ) (a b : ℂ) : + sin (a / 2) * ∑ i ∈ range n, sin (a * i + b) = sin (n * a / 2) * sin ((n - 1) * a / 2 + b) := by + apply mul_left_cancel₀ (show (-2 : ℂ) ≠ 0 by simp) + simp_rw [← mul_assoc, mul_sum] + calc + ∑ i ∈ range n, -2 * sin (a / 2) * sin (a * i + b) + = ∑ x ∈ range n, (cos (a * (↑(x + 1) - 1 / 2) + b) - cos (-(a * (x - 1 / 2) + b))) := by + congr! 1 with x hx + rw [cos_sub_cos] + push_cast + ring_nf + _ = -2 * sin (n * a / 2) * sin ((n - 1) * a / 2 + b) := by + simp_rw [cos_neg, sum_range_sub (fun i ↦ cos (a * (i - 1 / 2) + b)), cos_sub_cos] + ring_nf + +theorem sum_sin (n : ℕ) {a : ℂ} (h : ∀ k : ℤ, a ≠ k * (2 * π)) (b : ℂ) : + ∑ i ∈ range n, sin (a * i + b) = sin (n * a / 2) * sin ((n - 1) * a / 2 + b) / sin (a / 2) := by + rw [← sin_mul_sum_sin] + grind [sin_ne_zero_iff] + +theorem sin_mul_sum_cos (n : ℕ) (a b : ℂ) : + sin (a / 2) * ∑ i ∈ range n, cos (a * i + b) = sin (n * a / 2) * cos ((n - 1) * a / 2 + b) := by + apply mul_left_cancel₀ (show (2 : ℂ) ≠ 0 by simp) + simp_rw [← mul_assoc, mul_sum] + calc + ∑ i ∈ range n, 2 * sin (a / 2) * cos (a * i + b) + = ∑ x ∈ range n, (sin (a * (↑(x + 1) - 1 / 2) + b) - sin (a * (x - 1 / 2) + b)) := by + congr! 1 with x hx + rw [sin_sub_sin] + push_cast + ring_nf + _ = 2 * sin (n * a / 2) * cos ((n - 1) * a / 2 + b) := by + simp_rw [sum_range_sub (fun i ↦ sin (a * (i - 1 / 2) + b)), sin_sub_sin] + ring_nf + +theorem sum_cos (n : ℕ) {a : ℂ} (h : ∀ k : ℤ, a ≠ k * (2 * π)) (b : ℂ) : + ∑ i ∈ range n, cos (a * i + b) = sin (n * a / 2) * cos ((n - 1) * a / 2 + b) / sin (a / 2) := by + rw [← sin_mul_sum_cos] + grind [sin_ne_zero_iff] + end Complex namespace Real open scoped Real +open Finset theorem cos_eq_zero_iff {θ : ℝ} : cos θ = 0 ↔ ∃ k : ℤ, θ = (2 * k + 1) * π / 2 := mod_cast @Complex.cos_eq_zero_iff θ @@ -334,4 +375,22 @@ theorem tan_eq_one_sub_tan_half_sq_div_one_add_tan_half_sq (x : ℝ) : tan x = (2 * tan (x / 2)) / (1 - tan (x / 2) ^ 2) := mod_cast @Complex.tan_eq_one_sub_tan_half_sq_div_one_add_tan_half_sq x +theorem sin_mul_sum_sin (n : ℕ) (a b : ℝ) : + sin (a / 2) * ∑ i ∈ range n, sin (a * i + b) = sin (n * a / 2) * sin ((n - 1) * a / 2 + b) := by + exact_mod_cast congr($(Complex.sin_mul_sum_sin n a b).re) + +theorem sum_sin (n : ℕ) {a : ℝ} (h : ∀ k : ℤ, a ≠ k * (2 * π)) (b : ℝ) : + ∑ i ∈ range n, sin (a * i + b) = sin (n * a / 2) * sin ((n - 1) * a / 2 + b) / sin (a / 2) := by + have h := Complex.sum_sin n (a := a) (by exact_mod_cast h) b + exact_mod_cast congr($(h).re) + +theorem sin_mul_sum_cos (n : ℕ) (a b : ℝ) : + sin (a / 2) * ∑ i ∈ range n, cos (a * i + b) = sin (n * a / 2) * cos ((n - 1) * a / 2 + b) := by + exact_mod_cast congr($(Complex.sin_mul_sum_cos n a b).re) + +theorem sum_cos (n : ℕ) {a : ℝ} (h : ∀ k : ℤ, a ≠ k * (2 * π)) (b : ℝ) : + ∑ i ∈ range n, cos (a * i + b) = sin (n * a / 2) * cos ((n - 1) * a / 2 + b) / sin (a / 2) := by + have h := Complex.sum_cos n (a := a) (by exact_mod_cast h) b + exact_mod_cast congr($(h).re) + end Real From a064bf1c89d37fa85cff6fdf7ce891335bd5ad4f Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Tue, 21 Jul 2026 22:35:07 +0000 Subject: [PATCH 0926/1300] feat: `RingHom` equivalent to `AlgHom` over `Nat` or `Int` (#41899) Bundle `RingHom.toNatAlgHom` and `RingHom.toIntAlgHom` as `Equiv`s. Also make the arguments to `RingHom.equivRatAlgHom` explicit. --- Mathlib/Algebra/Algebra/Hom.lean | 14 ++++++++++++++ Mathlib/Algebra/Algebra/Hom/Rat.lean | 3 +-- .../NumberField/CanonicalEmbedding/Basic.lean | 4 ++-- .../NumberField/Discriminant/Basic.lean | 2 +- Mathlib/NumberTheory/NumberField/EquivReindex.lean | 4 ++-- .../NumberField/InfinitePlace/Basic.lean | 2 +- .../NumberField/InfinitePlace/Embeddings.lean | 4 ++-- 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Hom.lean b/Mathlib/Algebra/Algebra/Hom.lean index e27c84a71918b3..0942fd932ac708 100644 --- a/Mathlib/Algebra/Algebra/Hom.lean +++ b/Mathlib/Algebra/Algebra/Hom.lean @@ -422,6 +422,13 @@ lemma toNatAlgHom_coe [Semiring R] [Semiring S] (f : R →+* S) : lemma toNatAlgHom_apply [Semiring R] [Semiring S] (f : R →+* S) (x : R) : f.toNatAlgHom x = f x := rfl +variable (R) (S) in +/-- Ring homomorphisms are the same as `ℕ`-algebra homomorphisms. -/ +@[simps] +def equivNatAlgHom [Semiring R] [Semiring S] : (R →+* S) ≃ (R →ₐ[ℕ] S) where + toFun := RingHom.toNatAlgHom + invFun := AlgHom.toRingHom + /-- Reinterpret a `RingHom` as a `ℤ`-algebra homomorphism. -/ def toIntAlgHom [Ring R] [Ring S] (f : R →+* S) : R →ₐ[ℤ] S := { f with commutes' := fun n => by simp } @@ -437,6 +444,13 @@ lemma toIntAlgHom_injective [Ring R] [Ring S] : Function.Injective (RingHom.toIntAlgHom : (R →+* S) → _) := fun _ _ e ↦ DFunLike.ext _ _ (fun x ↦ DFunLike.congr_fun e x) +variable (R) (S) in +/-- Ring homomorphisms are the same as `ℤ`-algebra homomorphisms. -/ +@[simps] +def equivIntAlgHom [Ring R] [Ring S] : (R →+* S) ≃ (R →ₐ[ℤ] S) where + toFun := RingHom.toIntAlgHom + invFun := AlgHom.toRingHom + end RingHom namespace Algebra diff --git a/Mathlib/Algebra/Algebra/Hom/Rat.lean b/Mathlib/Algebra/Algebra/Hom/Rat.lean index 1c9f1a564452cf..41fcb31b9d4213 100644 --- a/Mathlib/Algebra/Algebra/Hom/Rat.lean +++ b/Mathlib/Algebra/Algebra/Hom/Rat.lean @@ -46,13 +46,12 @@ theorem AlgHom.toRingHom_toRatAlgHom [Ring R] [Ring S] [Algebra ℚ R] [Algebra (f : R →ₐ[ℚ] S) : (f : R →+* S).toRatAlgHom = f := AlgHom.ext fun _x => rfl +variable (R) (S) in /-- The equivalence between `RingHom` and `ℚ`-algebra homomorphisms. -/ @[simps] def RingHom.equivRatAlgHom [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] : (R →+* S) ≃ (R →ₐ[ℚ] S) where toFun := RingHom.toRatAlgHom invFun := AlgHom.toRingHom - left_inv f := RingHom.toRatAlgHom_toRingHom f - right_inv f := AlgHom.toRingHom_toRatAlgHom f end diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index d2dd850a19dc0a..b9051ae510212b 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -125,7 +125,7 @@ noncomputable def latticeBasis [NumberField K] : -- In order to prove that the determinant is nonzero, we show that it is equal to the -- square of the discriminant of the integral basis and thus it is not zero let N := Algebra.embeddingsMatrixReindex ℚ ℂ (fun i => integralBasis K (e i)) - RingHom.equivRatAlgHom + (RingHom.equivRatAlgHom K ℂ) rw [show M = N.transpose by { ext : 2; rfl }] rw [Matrix.det_transpose, ← pow_ne_zero_iff two_ne_zero] convert! @@ -133,7 +133,7 @@ noncomputable def latticeBasis [NumberField K] : (Algebra.discr_not_zero_of_basis ℚ (integralBasis K)) rw [← Algebra.discr_reindex ℚ (integralBasis K) e.symm] exact (Algebra.discr_eq_det_embeddingsMatrixReindex_pow_two ℚ ℂ - (fun i => integralBasis K (e i)) RingHom.equivRatAlgHom).symm + (fun i => integralBasis K (e i)) (RingHom.equivRatAlgHom K ℂ)).symm @[simp] theorem latticeBasis_apply [NumberField K] (i : Free.ChooseBasisIndex ℤ (𝓞 K)) : diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean index 9144e95ea4163d..d016880ea8c385 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Basic.lean @@ -95,7 +95,7 @@ theorem _root_.NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis let e : (index K) ≃ Module.Free.ChooseBasisIndex ℤ (𝓞 K) := (indexEquiv K).trans f.symm let M := (mixedEmbedding.stdBasis K).toMatrix ((latticeBasis K).reindex e.symm) let N := Algebra.embeddingsMatrixReindex ℚ ℂ (integralBasis K ∘ f.symm) - RingHom.equivRatAlgHom + (RingHom.equivRatAlgHom K ℂ) suffices M.map ofRealHom = matrixToStdBasis K * (Matrix.reindex (indexEquiv K).symm (indexEquiv K).symm N).transpose by calc volume (fundamentalDomain (latticeBasis K)) diff --git a/Mathlib/NumberTheory/NumberField/EquivReindex.lean b/Mathlib/NumberTheory/NumberField/EquivReindex.lean index 1eaf27e1199dea..da08787bb27cf3 100644 --- a/Mathlib/NumberTheory/NumberField/EquivReindex.lean +++ b/Mathlib/NumberTheory/NumberField/EquivReindex.lean @@ -42,7 +42,7 @@ abbrev basisMatrix : Matrix (K →+* ℂ) (K →+* ℂ) ℂ := theorem basisMatrix_eq_embeddingsMatrixReindex : basisMatrix K = Algebra.embeddingsMatrixReindex ℚ ℂ - (integralBasis K ∘ (equivReindex K)) RingHom.equivRatAlgHom := by + (integralBasis K ∘ (equivReindex K)) (RingHom.equivRatAlgHom K ℂ) := by ext; simp [Algebra.embeddingsMatrixReindex] open ComplexConjugate in @@ -58,7 +58,7 @@ theorem det_of_basisMatrix_non_zero [DecidableEq (K →+* ℂ)] : (basisMatrix K (Algebra.discr_not_zero_of_basis ℚ (integralBasis K)) rw [← Algebra.discr_reindex ℚ (integralBasis K) (equivReindex K).symm] exact (Algebra.discr_eq_det_embeddingsMatrixReindex_pow_two ℚ ℂ - (integralBasis K ∘ (equivReindex K)) RingHom.equivRatAlgHom).symm + (integralBasis K ∘ (equivReindex K)) (RingHom.equivRatAlgHom K ℂ)).symm instance [DecidableEq (K →+* ℂ)] : Invertible (basisMatrix K) := invertibleOfIsUnitDet _ (Ne.isUnit (det_of_basisMatrix_non_zero K)) diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index 6ba3d66943e5d1..86c0ea3a187be9 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -371,7 +371,7 @@ theorem prod_eq_abs_norm (x : K) : ∏ w : InfinitePlace K, w x ^ mult w = abs (Algebra.norm ℚ x) := by classical convert! (congr_arg (‖·‖) (Algebra.norm_eq_prod_embeddings ℚ ℂ x)).symm - · rw [norm_prod, ← Fintype.prod_equiv RingHom.equivRatAlgHom (fun f => ‖f x‖) + · rw [norm_prod, ← Fintype.prod_equiv (RingHom.equivRatAlgHom K ℂ) (fun f => ‖f x‖) (fun φ => ‖φ x‖) fun _ => by simp [RingHom.equivRatAlgHom_apply]] rw [← Finset.prod_fiberwise Finset.univ mk (fun φ => ‖φ x‖)] have (w : InfinitePlace K) (φ) (hφ : φ ∈ ({φ | mk φ = w} : Finset _)) : diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean index 66a9a25966ad6b..a9a4da6b0bf5a2 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Embeddings.lean @@ -53,13 +53,13 @@ variable [NumberField K] /-- There are finitely many embeddings of a number field. -/ noncomputable instance : Fintype (K →+* A) := - Fintype.ofEquiv (K →ₐ[ℚ] A) RingHom.equivRatAlgHom.symm + Fintype.ofEquiv (K →ₐ[ℚ] A) (RingHom.equivRatAlgHom K A).symm variable [IsAlgClosed A] /-- The number of embeddings of a number field is equal to its finrank. -/ theorem card : Fintype.card (K →+* A) = finrank ℚ K := by - rw [Fintype.ofEquiv_card RingHom.equivRatAlgHom.symm, AlgHom.card] + rw [Fintype.ofEquiv_card (RingHom.equivRatAlgHom K A).symm, AlgHom.card] instance : Nonempty (K →+* A) := by rw [← Fintype.card_pos_iff, NumberField.Embeddings.card K A] From 752186be9d1970f766cb265c2adb8b860499fc83 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:28:39 +0000 Subject: [PATCH 0927/1300] chore: golf FormalMultilinearSeries.fderiv_sum (#41580) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR golfs the proof of `FormalMultilinearSeries.fderiv_sum` to use the existing API lemma `HasFPowerSeriesOnBall.sum`, instead of re-deriving it via `hasSum`/`tsum_eq` and unfolding the definition of `FormalMultilinearSeries.sum` with `rw`. Follow-up to [#41018 (feat(Analysis): lemma for fderiv of FormalMultilinearSeries.sum)](https://github.com/leanprover-community/mathlib4/pull/41018). 🤖 Prepared with Claude Code --- Mathlib/Analysis/Calculus/FDeriv/Analytic.lean | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean index b2d8e8918e7cd9..d73e96d56424df 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean @@ -223,10 +223,7 @@ protected theorem HasFPowerSeriesOnBall.fderiv [CompleteSpace F] protected theorem FormalMultilinearSeries.fderiv_sum [CompleteSpace F] (h : ‖x‖ₑ < p.radius) : fderiv 𝕜 p.sum x = p.derivSeries.sum x := by - have h := p.hasFPowerSeriesOnBall (zero_le.trans_lt h) |>.fderiv.hasSum - (show x ∈ Metric.eball 0 p.radius by simpa using h) |>.tsum_eq - rw [zero_add] at h - rw [← h, FormalMultilinearSeries.sum] + simpa using (p.hasFPowerSeriesOnBall (zero_le.trans_lt h)).fderiv.sum (by simpa using h) protected theorem FormalMultilinearSeries.hasFDerivAt_sum [CompleteSpace F] (h : ‖x‖ₑ < p.radius) : HasFDerivAt p.sum (p.derivSeries.sum x) x := by From 5d2015052792a852b71383c9484185a1a26ba74c Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:42:50 +0000 Subject: [PATCH 0928/1300] doc: remove dangling reference to deleted lemma in asymptotics docstring (#41574) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR rewords the `Bounded Range versus IsBigO Asymptotics` section docstring in `Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean`, which referenced `Function.Even.isBigO_atTop_iff_isBigO_atBot`, a lemma deliberately removed during review and not present anywhere in Mathlib. The new text describes what the section actually contains, including the main general result `Continuous.isBounded_range_iff_isBigO` (previously unmentioned). Follow-up to [#40664 (feat: Bounded Range versus `IsBigO` Asymptotics)](https://github.com/leanprover-community/mathlib4/pull/40664). 🤖 Prepared with Claude Code --- Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean b/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean index 5b01e03ea44e57..2848136c0677e9 100644 --- a/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean +++ b/Mathlib/Analysis/Asymptotics/SpecificAsymptotics.lean @@ -212,12 +212,11 @@ section boundedRange /-! ## Bounded Range versus `IsBigO` Asymptotics -For a continuous function `f` into a seminormed space, defined on an unbounded linear order whose -order topology has compact intervals, having bounded range is equivalent to being `O(1)` along both -`atTop` and `atBot` (`Continuous.isBounded_range_iff_isBigO_atTop_atBot`). For an even function a -single `O(1)` bound along `atTop` already suffices -(`Continuous.isBounded_range_iff_isBigO_atTop_of_even`), since `Function.Even` transports an `atTop` -bound to an `atBot` bound (`Function.Even.isBigO_atTop_iff_isBigO_atBot`). +For a continuous function `f` into a seminormed space, having bounded range is equivalent to being +`O(1)` along the cocompact filter (`Continuous.isBounded_range_iff_isBigO`). On an unbounded linear +order whose order topology has compact intervals, this means being `O(1)` along both `atTop` and +`atBot` (`Continuous.isBounded_range_iff_isBigO_atTop_atBot`). For an even function a single `O(1)` +bound along `atTop` already suffices (`Continuous.isBounded_range_iff_isBigO_atTop_of_even`). -/ variable From 46ff937713b1d85cf6642ff8164d212292e30f6b Mon Sep 17 00:00:00 2001 From: Francesco Chotuck <101644758+FrankieNC@users.noreply.github.com> Date: Wed, 22 Jul 2026 01:24:18 +0000 Subject: [PATCH 0929/1300] feat(Algebra/Order/BigOperators): monotonicity of finite products (#41061) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `Monotone.finsetProd'`/`Antitone.finsetProd'` (and `MonotoneOn`/`AntitoneOn` variants, with additive versions `finsetSum`) for ordered commutative monoids, plus unprimed `Monotone.finsetProd` etc. for commutative monoids with zero with nonnegativity hypotheses — the finite-indexed generalisations of `Monotone.mul'` and `Monotone.mul`. Co-authored-by: Yongxi (Aaron) Lin <97214596+CoolRmal@users.noreply.github.com> --- .../Order/BigOperators/Group/Finset.lean | 28 +++++++++++++++++++ .../BigOperators/GroupWithZero/Finset.lean | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean index cf94a12bd7304e..b716bb73a6d7bd 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean @@ -116,6 +116,34 @@ or equal to the corresponding summand `g i` of another finite sum, then `∑ i ∈ s, f i ≤ ∑ i ∈ s, g i`. -/ add_decl_doc sum_le_sum +/-- A finite product of monotone functions is monotone. -/ +@[to_additive finsetSum /-- A finite sum of monotone functions is monotone. -/] +theorem _root_.Monotone.finsetProd' [MulLeftMono N] {γ : Type*} [Preorder γ] + {f : ι → γ → N} (hf : ∀ i ∈ s, Monotone (f i)) : + Monotone fun x ↦ ∏ i ∈ s, f i x := + fun _ _ hab ↦ Finset.prod_le_prod' fun i hi ↦ hf i hi hab + +/-- A finite product of functions monotone on `u` is monotone on `u`. -/ +@[to_additive finsetSum /-- A finite sum of functions monotone on `u` is monotone on `u`. -/] +theorem _root_.MonotoneOn.finsetProd' [MulLeftMono N] {γ : Type*} [Preorder γ] {u : Set γ} + {f : ι → γ → N} (hf : ∀ i ∈ s, MonotoneOn (f i) u) : + MonotoneOn (fun x ↦ ∏ i ∈ s, f i x) u := + fun _ ha _ hb hab ↦ Finset.prod_le_prod' fun i hi ↦ hf i hi ha hb hab + +/-- A finite product of antitone functions is antitone. -/ +@[to_additive finsetSum /-- A finite sum of antitone functions is antitone. -/] +theorem _root_.Antitone.finsetProd' [MulLeftMono N] {γ : Type*} [Preorder γ] + {f : ι → γ → N} (hf : ∀ i ∈ s, Antitone (f i)) : + Antitone fun x ↦ ∏ i ∈ s, f i x := + fun _ _ hab ↦ Finset.prod_le_prod' fun i hi ↦ hf i hi hab + +/-- A finite product of functions antitone on `u` is antitone on `u`. -/ +@[to_additive finsetSum /-- A finite sum of functions antitone on `u` is antitone on `u`. -/] +theorem _root_.AntitoneOn.finsetProd' [MulLeftMono N] {γ : Type*} [Preorder γ] {u : Set γ} + {f : ι → γ → N} (hf : ∀ i ∈ s, AntitoneOn (f i) u) : + AntitoneOn (fun x ↦ ∏ i ∈ s, f i x) u := + fun _ ha _ hb hab ↦ Finset.prod_le_prod' fun i hi ↦ hf i hi ha hb hab + @[to_additive sum_nonneg] theorem one_le_prod' [MulLeftMono N] (h : ∀ i ∈ s, 1 ≤ f i) : 1 ≤ ∏ i ∈ s, f i := le_trans (by rw [prod_const_one]) (prod_le_prod' h) diff --git a/Mathlib/Algebra/Order/BigOperators/GroupWithZero/Finset.lean b/Mathlib/Algebra/Order/BigOperators/GroupWithZero/Finset.lean index 038dc379e422b1..5aaad7f42e9161 100644 --- a/Mathlib/Algebra/Order/BigOperators/GroupWithZero/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/GroupWithZero/Finset.lean @@ -45,6 +45,34 @@ lemma prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) gcongr exacts [prod_nonneg h0.2, h0.1.trans h1.1, h1.1, ih h0.2 h1.2] +/-- A finite product of nonnegative monotone functions is monotone. See also +`Monotone.finsetProd'` for the case of an ordered commutative multiplicative monoid. -/ +theorem _root_.Monotone.finsetProd {γ : Type*} [Preorder γ] {f : ι → γ → R} + (hf : ∀ i ∈ s, Monotone (f i)) (hf₀ : ∀ i ∈ s, ∀ x, 0 ≤ f i x) : + Monotone fun x ↦ ∏ i ∈ s, f i x := + fun _ _ hab ↦ prod_le_prod (fun i hi ↦ hf₀ i hi _) fun i hi ↦ hf i hi hab + +/-- A finite product of functions nonnegative and monotone on `u` is monotone on `u`. See also +`MonotoneOn.finsetProd'` for the case of an ordered commutative multiplicative monoid. -/ +theorem _root_.MonotoneOn.finsetProd {γ : Type*} [Preorder γ] {u : Set γ} {f : ι → γ → R} + (hf : ∀ i ∈ s, MonotoneOn (f i) u) (hf₀ : ∀ i ∈ s, ∀ x ∈ u, 0 ≤ f i x) : + MonotoneOn (fun x ↦ ∏ i ∈ s, f i x) u := + fun _ ha _ hb hab ↦ prod_le_prod (fun i hi ↦ hf₀ i hi _ ha) fun i hi ↦ hf i hi ha hb hab + +/-- A finite product of nonnegative antitone functions is antitone. See also +`Antitone.finsetProd'` for the case of an ordered commutative multiplicative monoid. -/ +theorem _root_.Antitone.finsetProd {γ : Type*} [Preorder γ] {f : ι → γ → R} + (hf : ∀ i ∈ s, Antitone (f i)) (hf₀ : ∀ i ∈ s, ∀ x, 0 ≤ f i x) : + Antitone fun x ↦ ∏ i ∈ s, f i x := + fun _ _ hab ↦ prod_le_prod (fun i hi ↦ hf₀ i hi _) fun i hi ↦ hf i hi hab + +/-- A finite product of functions nonnegative and antitone on `u` is antitone on `u`. See also +`AntitoneOn.finsetProd'` for the case of an ordered commutative multiplicative monoid. -/ +theorem _root_.AntitoneOn.finsetProd {γ : Type*} [Preorder γ] {u : Set γ} {f : ι → γ → R} + (hf : ∀ i ∈ s, AntitoneOn (f i) u) (hf₀ : ∀ i ∈ s, ∀ x ∈ u, 0 ≤ f i x) : + AntitoneOn (fun x ↦ ∏ i ∈ s, f i x) u := + fun _ ha _ hb hab ↦ prod_le_prod (fun i hi ↦ hf₀ i hi _ hb) fun i hi ↦ hf i hi ha hb hab + /-- If each `f i`, `i ∈ s` belongs to `[0, 1]`, then their product is less than or equal to one. See also `Finset.prod_le_one'` for the case of an ordered commutative multiplicative monoid. -/ lemma prod_le_one (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ 1) : ∏ i ∈ s, f i ≤ 1 := by From b2ab8e6fbaa0ba97f8286df7507c4f21c27f4d06 Mon Sep 17 00:00:00 2001 From: gnahz04 <7452518+gnahz04@users.noreply.github.com> Date: Wed, 22 Jul 2026 05:31:37 +0000 Subject: [PATCH 0930/1300] feat(Analysis/InnerProductSpace): uniform convergence in an RKHS with bounded kernel (#41131) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `RKHS.tendstoUniformlyOn_of_norm_kerFun_le`: if the kernel functions are uniformly bounded on a set `s` (`‖kerFun H x‖ ≤ C` for `x ∈ s`), then convergence in `H`-norm implies uniform convergence of the underlying functions on `s`. The whole-space version `tendstoUniformly_of_norm_kerFun_le` is a corollary. This is the quantitative strengthening enabled by `norm_apply_le`: pointwise convergence already follows from the existing `continuous_eval`, but the explicit bound `‖f x‖ ≤ ‖f‖ * ‖kerFun H x‖` upgrades it to uniform convergence under a bounded kernel. Per review by Hampus Nyberg: generalized to `TendstoUniformlyOn` on a set, and stated the bound without the `√` (on `‖kerFun H x‖`, which equals `√‖kernel H x x‖`). **AI disclosure.** I used Claude Code (Claude Opus 4.8) to draft and iterate the Lean proof. I work in kernel methods / RKHS, understand the statement and proof, and can justify the design choices to reviewers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Hao Zhang --- .../InnerProductSpace/Reproducing.lean | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Reproducing.lean b/Mathlib/Analysis/InnerProductSpace/Reproducing.lean index 1591e3e66d5f6e..ae5f04b693fee6 100644 --- a/Mathlib/Analysis/InnerProductSpace/Reproducing.lean +++ b/Mathlib/Analysis/InnerProductSpace/Reproducing.lean @@ -37,7 +37,8 @@ positive semidefinite matrices. public noncomputable section -open ContinuousLinearMap InnerProductSpace Submodule ComplexConjugate +open ContinuousLinearMap InnerProductSpace Submodule ComplexConjugate Filter +open scoped Topology /-- A reproducing kernel Hilbert space is a Hilbert space with an @@ -150,6 +151,30 @@ bounded by `‖f‖` times the square root of the kernel diagonal `‖kernel H x lemma norm_apply_le (f : H) (x : X) : ‖f x‖ ≤ ‖f‖ * √‖kernel H x x‖ := by grw [← adjoint_kerFun, le_opNorm, norm_map, norm_kerFun_eq_sqrt_norm_kernel, mul_comm] +variable {H} in +/-- If the kernel functions are uniformly bounded on a set `s` (`‖kerFun H x‖ ≤ C` for `x ∈ s`), +then convergence in `H`-norm implies uniform convergence of the underlying functions on `s`. -/ +theorem tendstoUniformlyOn_of_norm_kerFun_le {C : ℝ} {s : Set X} + (hC : ∀ x ∈ s, ‖kerFun H x‖ ≤ C) + {ι : Type*} {l : Filter ι} {F : ι → H} {f : H} (h : Tendsto F l (𝓝 f)) : + TendstoUniformlyOn (fun n => ⇑(F n)) (⇑f) l s := by + rw [Metric.tendstoUniformlyOn_iff] + intro ε hε + have hnorm := (tendsto_iff_norm_sub_tendsto_zero.mp h).mul_const C + rw [zero_mul] at hnorm + filter_upwards [hnorm.eventually (gt_mem_nhds hε)] with n hn x hx + rw [dist_eq_norm', ← Pi.sub_apply, ← coe_sub] + grw [norm_apply_le, ← norm_kerFun_eq_sqrt_norm_kernel, hC x hx, hn] + +variable {H} in +/-- If the kernel functions are uniformly bounded (`‖kerFun H x‖ ≤ C` for all `x`), then +convergence in `H`-norm implies uniform convergence of the underlying functions. -/ +theorem tendstoUniformly_of_norm_kerFun_le {C : ℝ} (hC : ∀ x, ‖kerFun H x‖ ≤ C) + {ι : Type*} {l : Filter ι} {F : ι → H} {f : H} (h : Tendsto F l (𝓝 f)) : + TendstoUniformly (fun n => ⇑(F n)) (⇑f) l := by + rw [← tendstoUniformlyOn_univ] + exact tendstoUniformlyOn_of_norm_kerFun_le (fun x _ => hC x) h + set_option backward.isDefEq.respectTransparency.types false in /-- The span of the kernel functions is dense. -/ theorem kerFun_dense : topologicalClosure (span 𝕜 {kerFun H x v | (x) (v)}) = ⊤ := by From 2c973492e65594fdd0862aab9df10df782604a5a Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 22 Jul 2026 06:26:30 +0000 Subject: [PATCH 0931/1300] =?UTF-8?q?feat:=20derivative=20of=20the=20Hergl?= =?UTF-8?q?otz=E2=80=93Riesz=20kernel=20integral=20(#41952)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To prepare for the upcoming proof of the "Lemma on Logarithmic Derivatives" or Value Distribution Theory, compute the derivative of the Herglotz–Riesz kernel integral, as it appears in the Poisson integral formula of single-variable complex analysis. This material is used in [Project VD](https://github.com/kebekus/ProjectVD), formalizing Value Distribution Theory for meromorphic functions on the complex plane. Claude Code was used to create this PR. --- Mathlib/Analysis/Complex/Poisson.lean | 133 +++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/Complex/Poisson.lean b/Mathlib/Analysis/Complex/Poisson.lean index b154d58cc976bf..66d882e3164f42 100644 --- a/Mathlib/Analysis/Complex/Poisson.lean +++ b/Mathlib/Analysis/Complex/Poisson.lean @@ -6,6 +6,7 @@ Authors: Mihai Iancu, Stefan Kebekus, Sebastian Schleissinger, Aristotle AI module public import Mathlib.Analysis.Complex.MeanValue +public import Mathlib.Analysis.Calculus.ParametricIntervalIntegral /-! # Poisson Integral Formula @@ -17,7 +18,7 @@ integration and with the Poisson kernel, respectively. public section -open Complex Metric Real Set +open Complex MeasureTheory Metric Real Set variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] @@ -140,6 +141,38 @@ theorem le_re_herglotzRieszKernel {c z : ℂ} (hz : z ∈ sphere c R) (hw : w simpa using le_re_herglotzRieszKernel_aux (z - c).arg (w - c).arg ‖w - c‖ ‖z - c‖ (by simpa using h₁w) (mem_ball_iff_norm.1 hw) +/-- +The Herglotz–Riesz kernel `herglotzRieszKernel c w` is continuous on the circle `sphere c |R|` +whenever `w ∈ ball c R`. +-/ +@[fun_prop] lemma continuousOn_herglotzRieszKernel_sphere (hw : w ∈ ball c R) : + ContinuousOn (herglotzRieszKernel c w) (sphere c |R|) := by + apply ContinuousOn.div (by fun_prop) (by fun_prop) + grind [mem_sphere, mem_ball, le_abs_self R] + +/-- +Taking real parts commutes with the Herglotz–Riesz kernel integral of a real-valued +circle-integrable function. +-/ +theorem re_circleAverage_herglotzRieszKernel_smul {g : ℂ → ℝ} + (hg : CircleIntegrable g 0 R) (hw : w ∈ ball 0 R) : + (circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R).re + = circleAverage ((Complex.re ∘ herglotzRieszKernel 0 w) • g) 0 R := by + have h₁ : CircleIntegrable (fun ζ ↦ (g ζ : ℂ)) 0 R := by + simp only [CircleIntegrable, intervalIntegrable_iff] at hg ⊢ + exact Complex.ofRealCLM.integrable_comp hg + have h₂ : CircleIntegrable (fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R := + h₁.smul_of_continuousOn (continuousOn_herglotzRieszKernel_sphere hw) + calc (circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R).re + = circleAverage (Complex.reCLM ∘ fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R := + (Complex.reCLM.circleAverage_comp_comm h₂).symm + _ = circleAverage ((Complex.re ∘ herglotzRieszKernel 0 w) • g) 0 R := by + simp [Function.comp_def, Complex.mul_re, Pi.mul_def] + +/-! +## Integral Formulas +-/ + -- Trigonometric identity used in the computation of -- `DiffContOnCl.circleAverage_re_smul_on_ball_zero`. private lemma circleAverage_re_smul_on_ball_zero_aux {φ θ : ℝ} {r : ℝ} : @@ -150,10 +183,6 @@ private lemma circleAverage_re_smul_on_ball_zero_aux {φ θ : ℝ} {r : ℝ} : I_re, I_im, add_im, sub_im, mul_im, div_im, ofReal_im, normSq_apply] grind [Real.sin_sq] -/-! -## Integral Formulas --/ - -- Version of `DiffContOnCl.circleAverage_re_smul` in case where the center of the ball is zero. private lemma DiffContOnCl.circleAverage_re_smul_on_ball_zero [CompleteSpace E] (hf : DiffContOnCl ℂ f (ball 0 R)) (hw : w ∈ ball 0 R) : @@ -257,3 +286,97 @@ theorem DiffContOnCl.circleAverage_poissonKernel_smul' [CompleteSpace E] {c : Real.circleAverage (fun z ↦ ((‖z - c‖ ^ 2 - ‖w - c‖ ^ 2) / ‖(z - c) - (w - c)‖ ^ 2) • f z) c R = f w := by apply hf.circleAverage_poissonKernel_smul hw + +/-! +## Derivative of the Herglotz–Riesz Kernel Integral +-/ + +/- +For `w ∈ ball c R`, there is a radius `d > 0` such that `ball w d ⊆ ball c R` and all points of +`ball w d` keep distance at least `d` from the circle `sphere c R`. +-/ +private lemma exists_ball_subset_forall_le_norm_circleMap_sub (hw : w ∈ ball c R) : + ∃ d > 0, ball w d ⊆ ball c R ∧ ∀ x ∈ ball w d, ∀ θ : ℝ, d ≤ ‖circleMap c R θ - x‖ := by + have : Disjoint {w} (ball c R)ᶜ := by simpa + obtain ⟨d, hd, h_disj⟩ := this.exists_thickenings isCompact_singleton isOpen_ball.isClosed_compl + refine ⟨d, hd, ?_, ?_⟩ <;> grw [thickening_singleton] at h_disj + · simpa using (h_disj.mono_right (self_subset_thickening hd _)).subset_compl_left + · intro x hx θ + have := h_disj.subset_compl_right hx + simp only [mem_compl_iff, mem_thickening_iff, mem_ball, not_lt, not_exists, not_and] at this + simpa [← dist_eq_norm'] using this (circleMap c R θ) (by simp [dist_eq_norm, le_abs_self]) + +/-- +**Derivative of the Herglotz–Riesz kernel integral**: if `f` is circle integrable and `w` lies +inside the circle, then `w ↦ circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • f ζ) 0 R` has +derivative `circleAverage (fun ζ ↦ (2 * ζ / (ζ - w) ^ 2) • f ζ) 0 R` at `w`. +-/ +theorem hasDerivAt_circleAverage_herglotzRieszKernel_smul (hg : CircleIntegrable f 0 R) + (hw : w ∈ ball 0 R) : + HasDerivAt (fun w ↦ circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • f ζ) 0 R) + (circleAverage (fun ζ ↦ (2 * ζ / (ζ - w) ^ 2) • f ζ) 0 R) w := by + have hR : 0 < R := pos_of_mem_ball hw + obtain ⟨d, hd, hsub, hdist⟩ := exists_ball_subset_forall_le_norm_circleMap_sub hw + have hgm : AEStronglyMeasurable (fun θ ↦ f (circleMap 0 R θ)) + (volume.restrict (uIoc 0 (2 * π))) := (intervalIntegrable_iff.1 hg).aestronglyMeasurable + simp only [circleAverage_def] + apply HasDerivAt.const_smul + refine (intervalIntegral.hasDerivAt_integral_of_dominated_loc_of_deriv_le + (F' := fun x θ ↦ (2 * circleMap 0 R θ / (circleMap 0 R θ - x) ^ 2) • f (circleMap 0 R θ)) + (bound := fun θ ↦ 2 * R * (d ^ 2)⁻¹ * ‖f (circleMap 0 R θ)‖) + (ball_mem_nhds w hd) ?meas1 ?int ?meas2 ?bound ?int_bound ?diff).2 + -- Measurability of the integrand, for `x` near `w` + case meas1 => + filter_upwards with x + apply AEStronglyMeasurable.smul _ hgm + simp only [herglotzRieszKernel_def, sub_zero] + exact Measurable.aestronglyMeasurable (by fun_prop) + -- Integrability of the integrand at `w` + case int => + have h₁ : CircleIntegrable (herglotzRieszKernel 0 w • f) 0 R := + hg.smul_of_continuousOn (continuousOn_herglotzRieszKernel_sphere hw) + simpa only [CircleIntegrable, Pi.smul_apply'] using h₁ + -- Measurability of the differentiated integrand + case meas2 => + exact (Measurable.aestronglyMeasurable (by fun_prop)).smul hgm + -- Uniform bound for the differentiated integrand near `w` + case bound => + filter_upwards with θ _ x hx + have h₁ : ‖(2 : ℂ)‖ = 2 := by norm_num + rw [norm_smul, norm_div, norm_mul, norm_circleMap_zero, abs_of_pos hR, norm_pow, + div_eq_mul_inv, h₁] + gcongr + exact hdist x hx θ + -- Integrability of the bound + case int_bound => + exact (IntervalIntegrable.norm hg).const_mul _ + -- Differentiability of the integrand in `x`, for `x` near `w` + case diff => + filter_upwards with θ _ x hx + have h₁ : circleMap 0 R θ - x ≠ 0 := sub_ne_zero.2 (circleMap_ne_mem_ball (hsub hx) θ) + have h₂ : HasDerivAt (fun x ↦ herglotzRieszKernel 0 x (circleMap 0 R θ)) + (2 * circleMap 0 R θ / (circleMap 0 R θ - x) ^ 2) x := by + have h₃ := ((hasDerivAt_id' x).const_add (circleMap 0 R θ)).div + ((hasDerivAt_id' x).const_sub (circleMap 0 R θ)) h₁ + simpa [herglotzRieszKernel_def, sub_zero, sub_sub, ← two_mul, Pi.div_def] using h₃ + exact h₂.smul_const (f (circleMap 0 R θ)) + +/-- +The Herglotz–Riesz kernel integral of a circle-integrable function is differentiable in the pole +parameter, throughout the open ball. +-/ +theorem differentiableOn_circleAverage_herglotzRieszKernel_smul (hg : CircleIntegrable f 0 R) : + DifferentiableOn ℂ + (fun w ↦ circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • f ζ) 0 R) (ball 0 R) := + fun _ hw ↦ hasDerivAt_circleAverage_herglotzRieszKernel_smul hg hw + |>.differentiableAt.differentiableWithinAt + +/-- +The Herglotz–Riesz kernel integral of a circle-integrable function is analytic in the pole +parameter, throughout the open ball. +-/ +theorem analyticOnNhd_circleAverage_herglotzRieszKernel_smul [CompleteSpace E] + (hg : CircleIntegrable f 0 R) : + AnalyticOnNhd ℂ + (fun w ↦ circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • f ζ) 0 R) (ball 0 R) := + (differentiableOn_circleAverage_herglotzRieszKernel_smul hg).analyticOnNhd isOpen_ball From 288f16d9a07189233a9bc5e1c143c38d1f3f4d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 22 Jul 2026 09:58:39 +0000 Subject: [PATCH 0932/1300] chore(CategoryTheory): make `Under` `implicit_reducible` (#41998) This follows what's already done for `Over`. Demonstrate the progress by removing the `set_option` on `AlgEquiv.toUnder`. From Toric --- Mathlib/Algebra/Category/Ring/Under/Basic.lean | 9 +-------- Mathlib/CategoryTheory/Comma/Over/Basic.lean | 3 ++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/Category/Ring/Under/Basic.lean b/Mathlib/Algebra/Category/Ring/Under/Basic.lean index 378eac1234c29c..d37e6263bd4e7f 100644 --- a/Mathlib/Algebra/Category/Ring/Under/Basic.lean +++ b/Mathlib/Algebra/Category/Ring/Under/Basic.lean @@ -55,7 +55,7 @@ lemma toAlgHom_apply {A B : Under R} (f : A ⟶ B) (a : A) : variable (R) in /-- Make an object of `Under R` from an `R`-algebra. -/ -@[simps! hom, simps! -isSimp right] +@[implicit_reducible, simps! hom, simps! -isSimp right] def mkUnder (A : Type u) [CommRing A] [Algebra R A] : Under R := Under.mk (CommRingCat.ofHom <| algebraMap R A) @@ -93,19 +93,12 @@ end AlgHom namespace AlgEquiv -set_option backward.isDefEq.respectTransparency.types false in /-- Make an isomorphism in `Under R` from an algebra isomorphism. -/ def toUnder {A B : Type u} [CommRing A] [CommRing B] [Algebra R A] [Algebra R B] (f : A ≃ₐ[R] B) : CommRingCat.mkUnder R A ≅ CommRingCat.mkUnder R B where hom := f.toAlgHom.toUnder inv := f.symm.toAlgHom.toUnder - hom_inv_id := by - ext (a : (CommRingCat.mkUnder R A).right) - simp - inv_hom_id := by - ext a - simp @[simp] lemma toUnder_hom_right_apply {A B : Type u} [CommRing A] [CommRing B] [Algebra R A] diff --git a/Mathlib/CategoryTheory/Comma/Over/Basic.lean b/Mathlib/CategoryTheory/Comma/Over/Basic.lean index ade71fe2cc76df..bce0081bf753f8 100644 --- a/Mathlib/CategoryTheory/Comma/Over/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Over/Basic.lean @@ -660,6 +660,7 @@ end CostructuredArrow /-- The under category has as objects arrows with domain `X` and as morphisms commutative triangles. -/ +@[implicit_reducible] def Under (X : T) := StructuredArrow X (𝟭 T) @@ -718,7 +719,7 @@ theorem comp_right (a b c : Under X) (f : a ⟶ b) (g : b ⟶ c) : (f ≫ g).rig rfl /-- To give an object in the under category, it suffices to give an arrow with domain `X`. -/ -@[simps! right hom] +@[implicit_reducible, simps! right hom] def mk {X Y : T} (f : X ⟶ Y) : Under X := StructuredArrow.mk f From 2fbdcd8270d0d227095d4fc5389da590c479ff5a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky <5342086+pechersky@users.noreply.github.com> Date: Wed, 22 Jul 2026 10:21:19 +0000 Subject: [PATCH 0933/1300] feat(Algebra/Group/WithOne): subsingleton when IsEmpty source (#40688) --- Mathlib/Algebra/Group/WithOne/Defs.lean | 4 ++++ Mathlib/Topology/Compactification/OnePoint/Basic.lean | 3 +++ 2 files changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Group/WithOne/Defs.lean b/Mathlib/Algebra/Group/WithOne/Defs.lean index b61d5187b8f4a6..3c850ff484721e 100644 --- a/Mathlib/Algebra/Group/WithOne/Defs.lean +++ b/Mathlib/Algebra/Group/WithOne/Defs.lean @@ -85,6 +85,10 @@ instance inhabited : Inhabited (WithOne α) := instance instNontrivial [Nonempty α] : Nontrivial (WithOne α) := Option.nontrivial +@[to_additive] +instance [IsEmpty α] : Subsingleton (WithOne α) := + inferInstanceAs <| Subsingleton (Option α) + /-- The canonical map from `α` into `WithOne α` -/ @[to_additive (attr := coe, match_pattern) /-- The canonical map from `α` into `WithZero α` -/] def coe : α → WithOne α := diff --git a/Mathlib/Topology/Compactification/OnePoint/Basic.lean b/Mathlib/Topology/Compactification/OnePoint/Basic.lean index 7b11727c02f2f1..7e511fbbf50329 100644 --- a/Mathlib/Topology/Compactification/OnePoint/Basic.lean +++ b/Mathlib/Topology/Compactification/OnePoint/Basic.lean @@ -82,6 +82,9 @@ instance : CoeTC X (OnePoint X) := ⟨some⟩ instance : Inhabited (OnePoint X) := ⟨∞⟩ +instance [IsEmpty X] : Subsingleton (OnePoint X) := + inferInstanceAs <| Subsingleton (Option X) + protected lemma «forall» {p : OnePoint X → Prop} : (∀ (x : OnePoint X), p x) ↔ p ∞ ∧ ∀ (x : X), p x := Option.forall From 033397d8f1f2858ed9cb13b229db18a76a7324ce Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Wed, 22 Jul 2026 11:01:21 +0000 Subject: [PATCH 0934/1300] feat: a linear map which is a local embedding is an embedding (#41955) This is a nice intermediate result that will ultimately be used to show that Fredholm operators are stable under compact perturbation. Note that Bourbaki gives a proof which is very specific to R and C. After writing down multiple completely different proofs for the general result over the last few days, I eventually realised that their proof could just be tweaked slightly to work over a nontrivially normed field. I think it gives a really nice argument, so it's fully commented. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib.lean | 1 + .../Algebra/Module/EmbeddingOfLocal.lean | 167 ++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean diff --git a/Mathlib.lean b/Mathlib.lean index 98b51d695a0a11..129271448fa6be 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7658,6 +7658,7 @@ public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Quotient public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Restrict public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.RestrictScalars public import Mathlib.Topology.Algebra.Module.Determinant +public import Mathlib.Topology.Algebra.Module.EmbeddingOfLocal public import Mathlib.Topology.Algebra.Module.Equiv public import Mathlib.Topology.Algebra.Module.FiniteDimension public import Mathlib.Topology.Algebra.Module.FiniteDimensionBilinear diff --git a/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean b/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean new file mode 100644 index 00000000000000..d65e247829244a --- /dev/null +++ b/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean @@ -0,0 +1,167 @@ +/- +Copyright (c) 2026 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anatole Dedecker +-/ +module + +public import Mathlib.Analysis.LocallyConvex.BalancedCoreHull +public import Mathlib.Analysis.SpecificLimits.Normed + +/-! +# A linear map which is locally an embedding is an embedding + +Fix `𝕜` a `NontriviallyNormedField`, `E`, `F` two topological vector spaces over `𝕜`, and +`f : E → F` a `𝕜`-linear map. We show that, if there is a neighborhood `V` of `0 : E` +such that the restriction `V → F` is an embedding, then `f` itself is an embedding. + +Note that this result is false for topological groups, as shown by the following counterexamples: +* first, in the group setting, there are local embeddings (even local homeomorphisms) which + are not globally injective; an example is the quotient map `ℝ → 𝕋 := ℝ ⧸ ℤ`; +* even if assume that `f` is globally injective, the theorem still fails. Consider for example + `f : ℝ → 𝕋 × 𝕋` given by `x ↦ ([x], [α * x])`, with `α` irrational. `f` is injective, and locally + an embedding by the inverse function theorem, yet it is not globally an embedding: any + neighborhood of `f(0) = (0, 0)` contains infinitely many points `f(n)`, `n ∈ ℤ`, since + `α * n` gets arbitrarily close to being an integer infinitely many times. + +## Main results + +* `ContinuousSMul.topology_eq_of_induced_eq`: let `t₁`, `t₂` be two vector space + topologies on `E`, and assume that there is a `t₁`-neighborhood of 0 `V` in restriction to + which the two topologies coincide. Then `t₁ = t₂`. +* `LinearMap.isInducing_of_restrict_nhds_zero`: consider a linear map `f : E → F`, and assume + there is a neighborhood of 0 `V` in `E` such that `V.domRestrict f : V → F` satisfies + `Topology.IsInducing`. Then `f` satisfies `Topology.IsInducing`. +* `LinearMap.isEmbedding_of_restrict_nhds_zero`: consider a linear map `f : E → F`, and assume + there is a neighborhood of 0 `V` in `E` such that `V.domRestrict f : V → F` is a topological + embedding. Then `f` is a topological embedding. + +## TODO + +We will also need the fact that if the restriction `V → F` is a *closed* embedding, then +`f : E → F` is a *closed* embedding. This will follow from the fact that a subgroup which is +locally closed at `0` is in fact closed, which we don't have yet + +## Implementation details + +The content of this file is essentially (variations of) +[N. Bourbaki, *Théories Spectrales*, Chapitre III, § 5, n° 1, lemme 1][bourbaki2023], except +Bourbaki's proof is very specific to `𝕜 = ℝ` or `𝕜 = ℂ`, since it relies crucially on balanced +sets being connected. + +Nevertheless, we are able to adapt their proof to arbitrary nontrivially normed fields. +The key argument, replacing the fact that a connected set cannot be covered nontrivially by +disjoint open sets, is that a balanced set `W` cannot intersect nontrivially both `c • V` +and `Vᶜ`, when `V` is a neighborhood of `0` and `0 < ‖c‖ < 1`. We refer to the (highly commented!) +proof for more details. + +## References + +* [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 5, n° 1, lemme 1][bourbaki2023] + +-/ + +@[expose] public section + +open Topology Filter Bornology Set +open scoped Pointwise Set.Notation + +variable {𝕜₁ 𝕜₂ E F : Type*} [NontriviallyNormedField 𝕜₁] [NontriviallyNormedField 𝕜₂] + [AddCommGroup E] [AddCommGroup F] [Module 𝕜₁ E] [Module 𝕜₂ F] {σ : 𝕜₁ →+* 𝕜₂} {f : E →ₛₗ[σ] F} + +variable (𝕜₁) in +/-- Consider a vector space `E` over a `NontriviallyNormedField` `𝕜`, and `t₁`, `t₂` two +vector space topologies on `E`. + +Assume that there is a `t₁`-neighborhood of zero `V` such that the two topogies induce the +same filter of neighborhoods of `0` *in the subspace `V`*. Then `t₁ = t₂`. -/ +lemma ContinuousSMul.topology_eq_of_nhds_inf_principal_eq (t₁ t₂ : TopologicalSpace E) + [@IsTopologicalAddGroup E t₁ _] [@IsTopologicalAddGroup E t₂ _] + [@ContinuousSMul 𝕜₁ E _ _ t₁] [@ContinuousSMul 𝕜₁ E _ _ t₂] + {V : Set E} (V_mem : V ∈ @nhds E t₁ 0) (H : @nhds E t₁ 0 ⊓ 𝓟 V = @nhds E t₂ 0 ⊓ 𝓟 V) : + t₁ = t₂ := by + classical + -- For `i = 1, 2`, denote by `𝓕ᵢ` the filter of neighborhoods of `0` for the topology `tᵢ`. + set 𝓕₁ := @nhds E t₁ 0 + set 𝓕₂ := @nhds E t₂ 0 + -- Note that, because `V ∈ 𝓕₁`, `H` may be rewritten as `𝓕₁ = 𝓕₂ ⊓ 𝓟 V`. + replace H : 𝓕₁ = 𝓕₂ ⊓ 𝓟 V := by simpa [← H] + -- Because both `t₁` and `t₂` are additive group topologies, it is enough to show `𝓕₁ = 𝓕₂`. + suffices 𝓕₁ = 𝓕₂ by rwa [IsTopologicalAddGroup.ext_iff] <;> infer_instance + -- If we can show that `V ∈ 𝓕₂` we are done, because then `𝓕₁ = 𝓕₂ ⊓ 𝓟 V = 𝓕₂`. + suffices V ∈ 𝓕₂ by simpa [H] + -- Hence, let us show that `V ∈ 𝓕₂`. Fix a scalar `c` with `0 < ‖c‖ < 1`. + obtain ⟨c, hc₀, hc₁⟩ := NormedField.exists_norm_lt_one 𝕜₁ + have c_ne : c ≠ 0 := norm_pos_iff.mp hc₀ + -- We know that `c • V ∈ 𝓕₁ = 𝓕₂ ⊓ 𝓟 V`. + have cV_mem : c • V ∈ 𝓕₂ ⊓ 𝓟 V := by + simpa [← H, 𝓕₁, set_smul_mem_nhds_zero_iff c_ne] + -- Furthermore, we know that `𝓕₂` has a basis of balanced sets + have basis_𝓕₂ : HasBasis 𝓕₂ (fun (s : Set E) ↦ s ∈ 𝓕₂ ∧ Balanced 𝕜₁ s) id := + let := t₂; nhds_basis_balanced 𝕜₁ E + -- Hence, we get a balanced set `W ∈ 𝓕₂` such that `W ∩ V ⊆ c • V`. + obtain ⟨W, ⟨W_mem_𝓕₂, W_bal⟩, hW⟩ := basis_𝓕₂.inf_principal V |>.mem_iff.mp cV_mem + -- We claim that `W ⊆ V`. This will conclude the proof, since `W ∈ 𝓕₂`. + suffices W ⊆ V from mem_of_superset W_mem_𝓕₂ this + -- Let `w ∈ W` be arbitrary. + intro w w_in_W + -- Because `V` is a `t₁`-neighborhood of `0`, we have `c ^ n • w ∈ V` for some natural number `n`. + obtain ⟨n, hn⟩ : ∃ n : ℕ, c ^ n • w ∈ V := by + let := t₁ + have : Tendsto (fun k : ℕ ↦ c ^ k • w) atTop (𝓝 0) := + zero_smul 𝕜₁ w ▸ (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hc₁).smul_const w + exact this.eventually_mem V_mem |>.exists + -- We will conclude by reducing `c ^ n • w ∈ V` to `w = c ^ 0 • w ∈ V` inductively. + suffices c ^ 0 • w ∈ V by simpa + apply Nat.decreasingInduction (motive := fun (k : ℕ) _ ↦ c^k • w ∈ V) ?_ hn n.zero_le + -- To do so, we show that if `k : ℕ` is such that `c ^ (k + 1) • w ∈ V` then `c ^ k • w ∈ V`. + intro k _ (hk : c ^ (k + 1) • w ∈ V) + -- Indeed, because `W` is balanced, we have `c ^ (k + 1) • w ∈ W ∩ V ⊆ c • V` + have : c ^ (k + 1) • w ∈ c • V := + hW ⟨W_bal.smul_mem (by grw [norm_pow, hc₁.le, one_pow]) w_in_W, hk⟩ + -- Cancelling `c`, we get `c ^ k • w ∈ V` as we claimed. + rwa [pow_add, pow_one, mul_comm, mul_smul, smul_mem_smul_set_iff₀ c_ne V] at this + +variable (𝕜₁) in +/-- Consider a vector space `E` over a `NontriviallyNormedField` `𝕜`, and `t₁`, `t₂` two topologies +on `E` which are compatible with the vector space structure. + +Assume that there is a `t₁`-neighborhood of zero `V` such that the two topogies induce the +same topology *on the subspace `V`*. Then `t₁ = t₂`. -/ +lemma ContinuousSMul.topology_eq_of_induced_eq (t₁ t₂ : TopologicalSpace E) + [@IsTopologicalAddGroup E t₁ _] [@IsTopologicalAddGroup E t₂ _] + [@ContinuousSMul 𝕜₁ E _ _ t₁] [@ContinuousSMul 𝕜₁ E _ _ t₂] + {V : Set E} (V_mem : V ∈ @nhds E t₁ 0) + (H : t₁.induced ((↑) : V → E) = t₂.induced ((↑) : V → E)) : + t₁ = t₂ := by + apply topology_eq_of_nhds_inf_principal_eq 𝕜₁ t₁ t₂ V_mem + set o : V := ⟨0, letI := t₁; mem_of_mem_nhds V_mem⟩ + simp_rw [← map_comap_setCoe_val, show 0 = (o : E) from rfl, ← nhds_induced] + rw [H] + +variable [TopologicalSpace E] [TopologicalSpace F] + [IsTopologicalAddGroup E] [IsTopologicalAddGroup F] + [ContinuousSMul 𝕜₁ E] [ContinuousSMul 𝕜₂ F] [RingHomIsometric σ] + +lemma LinearMap.isInducing_of_restrict_nhds_zero {V : Set E} + (V_mem : V ∈ 𝓝 0) (H : IsInducing (Set.domRestrict V f)) : IsInducing f := by + rw [isInducing_iff] + -- Call `t₁` the original topology on `E`, and `t₂` the topology induced by `f`. Because + -- `f` is linear, `t₂` is also a vector space topology. + have := topologicalAddGroup_induced f + have := continuousSMul_inducedₛₗ f σ.isometry.continuous + -- Because `Set.domRestrict V f` is an inducing, `t₁` and `t₂` induce the same topology + -- on `V`, so we get `t₁ = t₂` from the lemmas above. + apply ContinuousSMul.topology_eq_of_induced_eq 𝕜₁ _ (.induced f _) V_mem + rw [induced_compose, ← domRestrict_eq, ← H.eq_induced, ← IsInducing.subtypeVal.eq_induced] + +lemma LinearMap.isEmbedding_of_restrict_nhds_zero {V : Set E} + (V_mem : V ∈ 𝓝 0) (H : IsEmbedding (Set.domRestrict V f)) : IsEmbedding f := by + refine ⟨isInducing_of_restrict_nhds_zero V_mem H.isInducing, ?_⟩ + have f_injOn : InjOn f V := injOn_iff_injective.2 H.injective + rw [← LinearMap.ker_eq_bot, Submodule.eq_bot_iff] + intro x hx + obtain ⟨c, hc, c_ne : c ≠ 0⟩ := absorbent_nhds_zero (𝕜 := 𝕜₁) V_mem + |>.eventually_nhdsNE_zero x |>.and eventually_mem_nhdsWithin |>.exists + rw [← smul_eq_zero_iff_right c_ne, ← f_injOn.eq_iff hc (mem_of_mem_nhds V_mem), map_zero, + map_smulₛₗ, hx, smul_zero] From c026161a585cd81c984425fbf72406b5523442c7 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:01:24 +0000 Subject: [PATCH 0935/1300] chore: fix diamond for unit powers (#41999) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reported in [#mathlib4 > Diamond for powers @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Diamond.20for.20powers/near/611869447) --- Mathlib/Algebra/Group/TypeTags/Basic.lean | 12 ++++++++---- Mathlib/Data/ZMod/IntUnitsPower.lean | 5 ++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Group/TypeTags/Basic.lean b/Mathlib/Algebra/Group/TypeTags/Basic.lean index a07b3ee9363195..bc013a65d865c4 100644 --- a/Mathlib/Algebra/Group/TypeTags/Basic.lean +++ b/Mathlib/Algebra/Group/TypeTags/Basic.lean @@ -48,10 +48,12 @@ def Multiplicative (α : Type*) := α namespace Additive /-- Reinterpret `x : α` as an element of `Additive α`. -/ +@[implicit_reducible] def ofMul : α ≃ Additive α := ⟨fun x => x, fun x => x, fun _ => rfl, fun _ => rfl⟩ /-- Reinterpret `x : Additive α` as an element of `α`. -/ +@[implicit_reducible] def toMul : Additive α ≃ α := ofMul.symm @[simp] @@ -80,10 +82,12 @@ end Additive namespace Multiplicative /-- Reinterpret `x : α` as an element of `Multiplicative α`. -/ +@[implicit_reducible] def ofAdd : α ≃ Multiplicative α := ⟨fun x => x, fun x => x, fun _ => rfl, fun _ => rfl⟩ /-- Reinterpret `x : Multiplicative α` as an element of `α`. -/ +@[implicit_reducible] def toAdd : Multiplicative α ≃ α := ofAdd.symm @[simp] @@ -262,12 +266,12 @@ instance Multiplicative.mulOneClass [AddZeroClass α] : MulOneClass (Multiplicat mul_one := @add_zero α _ instance Additive.addMonoid [h : Monoid α] : AddMonoid (Additive α) where - nsmul := h.npow + nsmul n a := ofMul (a.toMul ^ n) nsmul_zero := h.npow_zero nsmul_succ := h.npow_succ instance Multiplicative.monoid [h : AddMonoid α] : Monoid (Multiplicative α) where - npow := h.nsmul + npow n a := ofAdd (n • a.toAdd) npow_zero := h.nsmul_zero npow_succ := h.nsmul_succ @@ -415,14 +419,14 @@ instance Multiplicative.involutiveInv [InvolutiveNeg α] : InvolutiveInv (Multip instance Additive.subNegMonoid [h : DivInvMonoid α] : SubNegMonoid (Additive α) where sub_eq_add_neg := h.div_eq_mul_inv - zsmul := h.zpow + zsmul n a := ofMul (a.toMul ^ n) zsmul_zero' := h.zpow_zero' zsmul_succ' := h.zpow_succ' zsmul_neg' := h.zpow_neg' instance Multiplicative.divInvMonoid [h : SubNegMonoid α] : DivInvMonoid (Multiplicative α) where div_eq_mul_inv := h.sub_eq_add_neg - zpow := h.zsmul + zpow n a := ofAdd (n • a.toAdd) zpow_zero' := h.zsmul_zero' zpow_succ' := h.zsmul_succ' zpow_neg' := h.zsmul_neg' diff --git a/Mathlib/Data/ZMod/IntUnitsPower.lean b/Mathlib/Data/ZMod/IntUnitsPower.lean index e341f184756521..da609972b04ba3 100644 --- a/Mathlib/Data/ZMod/IntUnitsPower.lean +++ b/Mathlib/Data/ZMod/IntUnitsPower.lean @@ -64,9 +64,8 @@ instance Int.instUnitsPow : Pow ℤˣ R where pow u r := (r • Additive.ofMul u).toMul -- The above instances form no typeclass diamonds with the standard power operators --- but we will need `reducible_and_instances` which currently fails https://github.com/leanprover-community/mathlib4/issues/10906 -example : Int.instUnitsPow = NPow.toPow := rfl -example : Int.instUnitsPow = ZPow.toPow := rfl +example : Int.instUnitsPow = NPow.toPow := by with_implicit rfl +example : Int.instUnitsPow = ZPow.toPow := by with_implicit rfl @[simp] lemma ofMul_uzpow (u : ℤˣ) (r : R) : Additive.ofMul (u ^ r) = r • Additive.ofMul u := rfl From eb6a272ec5968ee3d5f6f02bd4232f057c25073b Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Wed, 22 Jul 2026 14:11:08 +0000 Subject: [PATCH 0936/1300] fix: update `scripts/rm_set_option.py` to ignore more comments (#41997) Currently `scripts/rm_set_option.py` will ignore any lines that look like `set_option ... in -- COMMENT`; however, the 4.33.0-rc1 bump introduced many `set_option`s that were unsafe to delete as indicated by a preceding `#adaptation_note`/comment. This PR updates the script to ignore `--` and `/-- ... -/` comments before a set_option. This includes catching `#adaptation_note`s Related [Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/4.2E33.2E0-rc1.20Multiple.20.60respectTransparency.60-related.20issues/near/611128727) :robot: Prepared with Claude --- scripts/rm_set_option.py | 11 +++++++++-- scripts/set_option_utils.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/rm_set_option.py b/scripts/rm_set_option.py index e78c7fcbbb4d64..3f8adb8219fa21 100755 --- a/scripts/rm_set_option.py +++ b/scripts/rm_set_option.py @@ -29,6 +29,7 @@ DEFAULT_OPTIONS, PROJECT_DIR, commented_pattern, + is_annotated, lake_build_with_progress, lakefile_pattern, removable_pattern, @@ -198,6 +199,8 @@ def scan_files(dag: DAG, options: list[str], value: str = "false") -> dict[str, for i, line in enumerate(lines): if any(p.match(line) for p in commented_pats): continue + if is_annotated(lines, i): + continue if any(p.match(line) for p in removable_pats): removable.append(i) if removable: @@ -206,12 +209,16 @@ def scan_files(dag: DAG, options: list[str], value: str = "false") -> dict[str, def count_skipped(filepath: Path, options: list[str], value: str = "false") -> int: - """Count set_option lines with trailing comments.""" + """Count set_option lines with trailing/preceding comments.""" commented_pats = [commented_pattern(opt, value) for opt in options] + removable_pats = [removable_pattern(opt, value) for opt in options] + lines = filepath.read_text().splitlines() count = 0 - for line in filepath.read_text().splitlines(): + for i, line in enumerate(lines): if any(p.match(line) for p in commented_pats): count += 1 + elif any(p.match(line) for p in removable_pats) and is_annotated(lines, i): + count += 1 return count diff --git a/scripts/set_option_utils.py b/scripts/set_option_utils.py index bf6b27ca60395b..5437234ec0913f 100755 --- a/scripts/set_option_utils.py +++ b/scripts/set_option_utils.py @@ -34,6 +34,20 @@ def commented_pattern(option: str, value: str = "false") -> re.Pattern: return re.compile(rf"^\s*set_option {escaped} {escaped_val} in\s+--") +def is_annotated(lines: list[str], idx: int) -> bool: + """Check whether line `idx` is immediately preceded by a `--` comment + or by a (possibly multi-line) `/-- ... -/` doc comment or `/- ... -/` block comment. + """ + if idx == 0: + return False + prev = lines[idx - 1] + if re.search(r"^\s*--", prev): + return True + if re.search(r"-/\s*$", prev): + return True + return False + + def lakefile_pattern(option: str, value: str = "false") -> re.Pattern: """Match lakefile entries for an option.""" escaped = re.escape(option) From 0df1c567a3ec27af53d51952435e689ff1e3fdf4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:59:25 +0000 Subject: [PATCH 0937/1300] chore: golf proof of smoothness of immersions and submersions (#41635) The current proof of `Is{Immersion,Submersion}AtOfComplement.contMDiffOn` is slightly longer because two lemmas expect (mathematically equivalent, but incompatible) models with corners. Side-step this by passing to the normed space setting at first, where this issue does not arise. Pointed out by kim-em using Claude code. While at it, also golf one proof using `fun_prop`. --- Mathlib/Geometry/Manifold/Immersion.lean | 13 +++---------- Mathlib/Geometry/Manifold/Submersion.lean | 11 +---------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index b10829aeea42e2..e5833d62e83de1 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -423,12 +423,7 @@ theorem contMDiffOn (h : IsImmersionAtOfComplement F I J n f x) : h.codChart_mem_maximalAtlas le_rfl h.mapsto_domChart_source_codChart_source, ← h.domChart.extend_target_eq_image_source] have : CMDiff n (h.equiv ∘ fun x ↦ (x, 0)) := by - have : ContMDiff 𝓘(𝕜, E × F) 𝓘(𝕜, E'') n h.equiv := by - rw [contMDiff_iff_contDiff] - exact h.equiv.contDiff - apply this.comp - rw [contMDiff_iff_contDiff, contDiff_prod_iff] - exact ⟨contDiff_id, contDiff_const (c := (0 : F))⟩ + rw [contMDiff_iff_contDiff]; fun_prop exact this.contMDiffOn.congr h.writtenInCharts /-- A `C^n` immersion at `x` is `C^n` at `x`. -/ @@ -473,10 +468,8 @@ private lemma aux {f : M → N} {φ : N → N'} rw [h.domChart.extend_target_eq_image_source] exact ⟨(f ∘ (extChartAt I x).symm) y, ht hy.1, by simp⟩ -- Composing with a suitable projection to cancel the inclusion, we deduce that `f` is `C^n`. - have h'''' : ContDiffWithinAt 𝕜 n ((Prod.fst ∘ h.equiv.symm) ∘ f'') s x' := by - refine ContDiffWithinAt.comp x' ?_ h''' (mapsTo_univ _ _) - rw [contDiffWithinAt_univ] - exact contDiffAt_fst.comp _ h.equiv.symm.contDiff.contDiffAt + have h'''' : ContDiffWithinAt 𝕜 n ((Prod.fst ∘ h.equiv.symm) ∘ f'') s x' := + ContDiffWithinAt.comp x' (by fun_prop) h''' (mapsTo_univ _ _) exact h''''.congr_of_mem (fun y hy ↦ by simp [f'']) hx' /-- A function `f : M → N` between `C^n` manifolds is `C^n` at `x` if and only if it is continuous diff --git a/Mathlib/Geometry/Manifold/Submersion.lean b/Mathlib/Geometry/Manifold/Submersion.lean index 6a821bd6ad7f7b..3396a8f134e912 100644 --- a/Mathlib/Geometry/Manifold/Submersion.lean +++ b/Mathlib/Geometry/Manifold/Submersion.lean @@ -368,16 +368,7 @@ theorem contMDiffOn (h : IsSubmersionAtOfComplement F I J n f x) : rw [← contMDiffOn_writtenInExtend_iff h.domChart_mem_maximalAtlas h.codChart_mem_maximalAtlas le_rfl h.mapsto_domChart_source_codChart_source, ← h.domChart.extend_target_eq_image_source] - have : CMDiff n (Prod.fst ∘ h.equiv) := by - -- Note that we cannot use `h₁.comp contMDiff_fst` since `h₁` and `contMDiff_fst` require - -- different models with corners on `E'' × F`. The former uses `𝓘(𝕜, E'' × F)` while the latter - -- uses `(𝓘(𝕜, E'')).prod (𝓘(𝕜, F)`. - have h₁ : ContMDiff 𝓘(𝕜, E) 𝓘(𝕜, E'' × F) n h.equiv := by - rw [contMDiff_iff_contDiff] - exact h.equiv.contDiff - apply ContMDiff.comp ?_ h₁ - rw [contMDiff_iff_contDiff] - exact contDiff_fst + have : CMDiff n (Prod.fst ∘ h.equiv) := by rw [contMDiff_iff_contDiff]; fun_prop exact this.contMDiffOn.congr h.writtenInCharts /-- A `C^n` submersion at `x` is `C^n` at `x`. -/ From 68bad90c62f70ef958bb6cf0e0b98893de8860c3 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:09:37 +0000 Subject: [PATCH 0938/1300] chore: replace `simp only []` with `simp only` (#41927) Slightly simplify. There are no `simp []`, `rw []` or `grind []` used; so these are probably the only empty lists one can replace. Co-authored-by: Batixx --- Counterexamples/AharoniKorman.lean | 2 +- .../SpecialFunctions/Integrals/PosLogEqCircleAverage.lean | 2 +- Mathlib/CategoryTheory/Limits/Fubini.lean | 8 ++++---- Mathlib/Computability/PartrecCode.lean | 2 +- Mathlib/Computability/RE.lean | 2 +- Mathlib/Computability/TuringMachine/Config.lean | 6 +++--- Mathlib/ModelTheory/Encoding.lean | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Counterexamples/AharoniKorman.lean b/Counterexamples/AharoniKorman.lean index 4d087cdc8cb311..a7f42ed111cf6c 100644 --- a/Counterexamples/AharoniKorman.lean +++ b/Counterexamples/AharoniKorman.lean @@ -794,7 +794,7 @@ theorem apply_eq_of_line_eq (f : SpinalMap C) {n : ℕ} (hC : IsChain (· ≤ · have hy : y ∈ level n := ordConnected_level.out hlo.2 hhi.2 ⟨h₂l, h₂h⟩ induction hx using induction_on_level with | h x₁ y₁ => induction hy using induction_on_level with | h x₂ y₂ => - simp only [] at hxy + simp only at hxy simp only [line_toHollom] at h obtain ⟨k, rfl⟩ := exists_add_of_le hxy obtain rfl : y₂ = y₁ + k := by lia diff --git a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean index 69f0f4ee5eb1f5..6a490053138507 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean @@ -127,7 +127,7 @@ theorem circleAverage_log_norm_sub_const₁ (h : ‖a‖ = 1) : _ = ∫ x in 0..(2 * π), log (4 * sin (x / 2) ^ 2) / 2 := by apply integral_congr intro x hx - simp only [] + simp only rw [Complex.norm_def, log_sqrt (circleMap 0 1 x - 1).normSq_nonneg] congr calc Complex.normSq (circleMap 0 1 x - 1) diff --git a/Mathlib/CategoryTheory/Limits/Fubini.lean b/Mathlib/CategoryTheory/Limits/Fubini.lean index 704051a5a2940d..1dad10d3e098ef 100644 --- a/Mathlib/CategoryTheory/Limits/Fubini.lean +++ b/Mathlib/CategoryTheory/Limits/Fubini.lean @@ -591,7 +591,7 @@ theorem colimitFlipCompColimIsoColimitCompColim_ι_ι_hom (j) (k) : (colimitFlipCompColimIsoColimitCompColim F).hom = (colimit.ι _ k ≫ colimit.ι (F ⋙ colim) j : _ ⟶ colimit (F ⋙ colim)) := by dsimp [colimitFlipCompColimIsoColimitCompColim] - slice_lhs 1 3 => simp only [] + slice_lhs 1 3 => simp only simp [Equivalence.unit] set_option backward.defeqAttrib.useBackward true in @@ -602,7 +602,7 @@ theorem colimitFlipCompColimIsoColimitCompColim_ι_ι_inv (k) (j) : (colimitFlipCompColimIsoColimitCompColim F).inv = (colimit.ι _ j ≫ colimit.ι (F.flip ⋙ colim) k : _ ⟶ colimit (F.flip ⋙ colim)) := by dsimp [colimitFlipCompColimIsoColimitCompColim] - slice_lhs 1 3 => simp only [] + slice_lhs 1 3 => simp only simp [Equivalence.counitInv] end @@ -737,7 +737,7 @@ theorem colimitCurrySwapCompColimIsoColimitCurryCompColim_ι_ι_hom {j} {k} : (colimit.ι _ k ≫ colimit.ι (curry.obj G ⋙ colim) j : _ ⟶ colimit (curry.obj G ⋙ colim)) := by dsimp [colimitCurrySwapCompColimIsoColimitCurryCompColim] - slice_lhs 1 3 => simp only [] + slice_lhs 1 3 => simp only simp set_option backward.defeqAttrib.useBackward true in @@ -750,7 +750,7 @@ theorem colimitCurrySwapCompColimIsoColimitCurryCompColim_ι_ι_inv {j} {k} : colimit.ι (curry.obj _ ⋙ colim) k : _ ⟶ colimit (curry.obj (Prod.swap K J ⋙ G) ⋙ colim)) := by dsimp [colimitCurrySwapCompColimIsoColimitCurryCompColim] - slice_lhs 1 3 => simp only [] + slice_lhs 1 3 => simp only rw [colimitIsoColimitCurryCompColim_ι_ι_inv, HasColimit.ι_isoOfEquivalence_inv] dsimp [Equivalence.counitInv] rw [CategoryTheory.Bifunctor.map_id] diff --git a/Mathlib/Computability/PartrecCode.lean b/Mathlib/Computability/PartrecCode.lean index 9b69165e860e1a..c9a6f39432e586 100644 --- a/Mathlib/Computability/PartrecCode.lean +++ b/Mathlib/Computability/PartrecCode.lean @@ -840,7 +840,7 @@ private theorem hG : Primrec G := by conv => congr · ext p - dsimp only [] + dsimp only erw [Option.bind_eq_bind, ← Option.map_eq_bind] refine Primrec.option_map ((hlup.comp <| L.pair <| (k.pair cg).pair n).comp Primrec.fst) ?_ unfold Primrec₂ diff --git a/Mathlib/Computability/RE.lean b/Mathlib/Computability/RE.lean index 16aebb86bd055e..cd0dd8e712867b 100644 --- a/Mathlib/Computability/RE.lean +++ b/Mathlib/Computability/RE.lean @@ -212,7 +212,7 @@ theorem ite {f₁ f₂ : ℕ → ℕ} (hf₁ : Computable f₁) (hf₂ : Computa theorem to_re {p : α → Prop} (hp : ComputablePred p) : REPred p := by obtain ⟨f, hf, rfl⟩ := computable_iff.1 hp unfold REPred - dsimp only [] + dsimp only refine (Partrec.cond hf (Decidable.Partrec.const' (Part.some ())) Partrec.none).of_eq fun n => Part.ext fun a => ?_ diff --git a/Mathlib/Computability/TuringMachine/Config.lean b/Mathlib/Computability/TuringMachine/Config.lean index 7e3cbccc14e442..dd621371498bdf 100644 --- a/Mathlib/Computability/TuringMachine/Config.lean +++ b/Mathlib/Computability/TuringMachine/Config.lean @@ -595,7 +595,7 @@ theorem stepNormal.is_ret (c k v) : ∃ k' v', stepNormal c k v = Cfg.ret k' v' | comp f _g _IHf IHg => apply IHg | case f g IHf IHg => rw [stepNormal] - simp only [] + simp only cases v.headI <;> [apply IHf; apply IHg] | fix f IHf => apply IHf | _ => exact ⟨_, _, rfl⟩ @@ -620,7 +620,7 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : exact Or.inl (Part.mem_some _) · exact Or.inr ⟨_, Part.mem_some _, hv₂⟩ refine fun c he => evalInduction he fun y h IH => ?_ - rintro v (⟨v'⟩ | ⟨k', v'⟩) rfl hr <;> rw [Cfg.then] at h IH <;> simp only [] at h IH + rintro v (⟨v'⟩ | ⟨k', v'⟩) rfl hr <;> rw [Cfg.then] at h IH <;> simp only at h IH · have := mem_eval.2 ⟨hr, rfl⟩ rw [fok, Part.bind_eq_bind, Part.mem_bind_iff] at this obtain ⟨v'', h₁, h₂⟩ := this @@ -639,7 +639,7 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : · obtain ⟨k₀, v₀, e₀⟩ := stepNormal.is_ret f Cont.halt v'.tail have e₁ := stepNormal_then f Cont.halt (Cont.fix f k) v'.tail rw [e₀, Cont.then, Cfg.then] at e₁ - simp only [] at e₁ + simp only at e₁ obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ := IH (stepRet (k₀.then (Cont.fix f k)) v₀) (by rw [stepRet, if_neg he, e₁]; rfl) v'.tail _ stepRet_then (by apply ReflTransGen.single; rw [e₀]; rfl) diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index 9be97dac9e4207..1d91ab5a2079f7 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -261,13 +261,13 @@ theorem listDecode_encode_list (l : List (Σ n, L.BoundedFormula α n)) : rw [length_map, length_finRange] | imp _ _ ih1 ih2 => intro l - simp only [] at * + simp only at * rw [listEncode, List.append_assoc, cons_append, listDecode] simp only [ih1, ih2, length_cons, le_add_iff_nonneg_left, _root_.zero_le, ↓reduceDIte, getElem_cons_zero, getElem_cons_succ, sigmaImp_apply, drop_succ_cons, drop_zero] | all _ ih => intro l - simp only [] at * + simp only at * rw [listEncode, cons_append, listDecode] simp only [ih, length_cons, le_add_iff_nonneg_left, _root_.zero_le, ↓reduceDIte, getElem_cons_zero, sigmaAll_apply, drop_succ_cons, drop_zero] From 2c5cc288c3de73e6716b3c7e08ce5731c4bcf0f0 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:24:54 +0000 Subject: [PATCH 0939/1300] feat(Algebra/Algebra/Bilinear): generalize to `NonUnitalNonAssocCommSemiring` (#39738) Complete a TODO which can now be done since #28604 is merged. Co-authored-by: NoahW314 --- Mathlib/Algebra/Algebra/Bilinear.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Bilinear.lean b/Mathlib/Algebra/Algebra/Bilinear.lean index 9ff4db4ac00bc2..d8fe93624f9956 100644 --- a/Mathlib/Algebra/Algebra/Bilinear.lean +++ b/Mathlib/Algebra/Algebra/Bilinear.lean @@ -172,9 +172,7 @@ variable (R A) in end Semiring section CommSemiring --- TODO: Generalise to `NonUnitalNonAssocCommSemiring`. This can't currently be done --- because there is no instance **to** `NonUnitalNonAssocCommSemiring`. -variable [CommSemiring R] [NonUnitalCommSemiring A] +variable [CommSemiring R] [NonUnitalNonAssocCommSemiring A] [Module R A] [SMulCommClass R A A] [IsScalarTower R A A] @[simp] lemma flip_mul : (mul R A).flip = mul R A := by ext; simp [mul_comm] @@ -192,7 +190,7 @@ open scoped RingTheory.LinearMap namespace NonUnitalAlgHom variable [CommSemiring R] - [NonUnitalSemiring A] [Module R A] [SMulCommClass R A A] [IsScalarTower R A A] + [NonUnitalNonAssocSemiring A] [Module R A] [SMulCommClass R A A] [IsScalarTower R A A] [NonUnitalNonAssocSemiring B] [Module R B] [SMulCommClass R B B] [IsScalarTower R B B] lemma comp_mul' (f : A →ₙₐ[R] B) : (f : A →ₗ[R] B) ∘ₗ μ = μ[R] ∘ₗ (f ⊗ₘ f) := From b050d8ed03718019165da9e14302cf3a69272476 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:24:57 +0000 Subject: [PATCH 0940/1300] feat(Logic/Function): add Set.separatesPoints_mono (#41434) Also makes a small stylistic improvement to the previous definition --- Mathlib/Logic/Function/Basic.lean | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index d2d3f67f4f10da..55aa858a0fb15e 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -1216,7 +1216,13 @@ theorem Function.LeftInverse.cast_eq {γ : β → Sort v} {f : α → β} {g : /-- A set of functions "separates points" if for each pair of distinct points there is a function taking different values on them. -/ def Set.SeparatesPoints {α β : Type*} (A : Set (α → β)) : Prop := - ∀ ⦃x y : α⦄, x ≠ y → ∃ f ∈ A, (f x : β) ≠ f y + ∀ ⦃x y : α⦄, x ≠ y → ∃ f ∈ A, f x ≠ f y + +theorem Set.separatesPoints_mono {α β : Type*} {A B : Set (α → β)} (hAB : A ⊆ B) + (hA : Set.SeparatesPoints A) : Set.SeparatesPoints B := by + intro x y hne + obtain ⟨f, hfA, hne'⟩ := hA hne + exact ⟨f, hAB hfA, hne'⟩ theorem InvImage.equivalence {α : Sort u} {β : Sort v} (r : β → β → Prop) (f : α → β) (h : Equivalence r) : Equivalence (InvImage r f) := From 3a41afdb6a1ea6f2d01d07ef13cef1d56273b72c Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:24:59 +0000 Subject: [PATCH 0941/1300] feat(Topology/MetricSpace): add separatesPoints_lipschitzWith_one (#41436) Together with #41434 this can be strengthened, but for now the strongest version of the claim is added, and further versions can be added later if they're deemed helpful. Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Topology/MetricSpace/Lipschitz.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Topology/MetricSpace/Lipschitz.lean b/Mathlib/Topology/MetricSpace/Lipschitz.lean index 74fb124898b3d3..6907ca8a731bc4 100644 --- a/Mathlib/Topology/MetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/MetricSpace/Lipschitz.lean @@ -168,6 +168,11 @@ lemma _root_.Real.lipschitzWith_toNNReal : LipschitzWith 1 Real.toNNReal := by simpa only [NNReal.coe_one, dist_prod_same_right, one_mul, Real.dist_eq] using! lipschitzWith_iff_dist_le_mul.mp lipschitzWith_max (x, 0) (y, 0) +/-- The set of functions which are 1-Lipschitz on a metric space separates points. -/ +theorem _root_.Set.separatesPoints_lipschitzWith_one (E : Type*) [MetricSpace E] : + { f : E → ℝ | LipschitzWith 1 f }.SeparatesPoints := + fun _ y _ ↦ ⟨(dist · y), by simp [LipschitzWith.dist_left], by simpa⟩ + end Metric section EMetric From bcaf924143a7c24b55a6ce214d4c327670de8f4c Mon Sep 17 00:00:00 2001 From: Judson Date: Wed, 22 Jul 2026 16:25:01 +0000 Subject: [PATCH 0942/1300] feat(Analysis/CStarAlgebra/Matrix): add CStarAlgebra instance for matrices (#41518) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the bundled CStarAlgebra instance for Matrix n n ℂ in the L2 operator norm (Mathlib already has CStarRing scoped in Matrix.Norms.L2Operator, but not the bundled algebra). Composed from the existing scoped instances. Follow-up to #40900. Co-authored-by: Jireh Loreaux --- Mathlib/Analysis/CStarAlgebra/Matrix.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Analysis/CStarAlgebra/Matrix.lean b/Mathlib/Analysis/CStarAlgebra/Matrix.lean index 8f7d0060050db6..177e5295e09034 100644 --- a/Mathlib/Analysis/CStarAlgebra/Matrix.lean +++ b/Mathlib/Analysis/CStarAlgebra/Matrix.lean @@ -5,6 +5,7 @@ Authors: Hans Parshall -/ module +public import Mathlib.Analysis.CStarAlgebra.Classes public import Mathlib.Analysis.InnerProductSpace.Adjoint public import Mathlib.Analysis.Matrix.Normed public import Mathlib.Analysis.RCLike.Basic @@ -289,6 +290,12 @@ lemma instCStarRing : CStarRing (Matrix n n 𝕜) where scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instCStarRing +/-- The matrices `Matrix n n ℂ` with the L2 operator norm form a `CStarAlgebra`. -/ +@[instance_reducible] noncomputable def instCStarAlgebra {n : Type*} [Fintype n] [DecidableEq n] : + CStarAlgebra (Matrix n n ℂ) where + +scoped[Matrix.Norms.L2Operator] attribute [instance] Matrix.instCStarAlgebra + end Matrix end L2OpNorm From dfda59dbfd3b5f54f214d40d9f7aff1f6ad41085 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:25:04 +0000 Subject: [PATCH 0943/1300] chore: no `public def` inside `public section` etc (#41787) Removes all the private/public keywords in front of a declaration, when we are already in a private/public section anyways. (no private ever appears) Co-authored-by: Batixx --- Mathlib/AlgebraicGeometry/StructureSheaf.lean | 2 +- Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean | 2 +- MathlibTest/Util/AliasIn/AliasInModuleSystem.lean | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/StructureSheaf.lean index 9cded788235d69..68e666459733de 100644 --- a/Mathlib/AlgebraicGeometry/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/StructureSheaf.lean @@ -66,7 +66,7 @@ namespace AlgebraicGeometry variable (R) in /-- The prime spectrum as an object of `TopCat`. -/ -public def PrimeSpectrum.Top : TopCat := TopCat.of (PrimeSpectrum R) +def PrimeSpectrum.Top : TopCat := TopCat.of (PrimeSpectrum R) namespace StructureSheaf diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean index 5bdbaf68f31411..0140a636b658e0 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/Simple.lean @@ -199,7 +199,7 @@ theorem normal_subgroup_eq_bot_or_eq_top · apply normal_subgroup_eq_bot_or_eq_top_of_card_ne_six hα hα' /-- When `α` has at least 5 elements, then `alternatingGroup α` is a simple group. -/ -public theorem isSimpleGroup (hα : 5 ≤ Nat.card α) : +theorem isSimpleGroup (hα : 5 ≤ Nat.card α) : IsSimpleGroup (alternatingGroup α) where exists_pair_ne := by rw [← _root_.nontrivial_iff] diff --git a/MathlibTest/Util/AliasIn/AliasInModuleSystem.lean b/MathlibTest/Util/AliasIn/AliasInModuleSystem.lean index f02bf509f19516..07cbfc2b3ad7fd 100644 --- a/MathlibTest/Util/AliasIn/AliasInModuleSystem.lean +++ b/MathlibTest/Util/AliasIn/AliasInModuleSystem.lean @@ -71,7 +71,7 @@ Look at this docstring! open Lean in run_cmd logInfo m!"{(← Lean.findDocString? (← getEnv) `Foo.Baz.baz5).get!}" -@[alias_in Baz] public def Foo.Bar.baz6 : Nat := 1 +@[alias_in Baz] def Foo.Bar.baz6 : Nat := 1 /-- error: The `alias_in` attribute cannot be used for private declarations. -/ #guard_msgs in From cba869277b7f3c09f96ece2a118ed4c1c8115b89 Mon Sep 17 00:00:00 2001 From: ajirving <29164966+ajirving@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:25:06 +0000 Subject: [PATCH 0944/1300] style: fix by on newline (#41794) Fixes some instances of by being on a newline or the first line of the proof rather than the final line of the declaration (as required by Mathlib style). --- Mathlib/Algebra/Homology/Factorizations/CM5a.lean | 4 ++-- Mathlib/Algebra/SkewPolynomial/Basic.lean | 4 ++-- .../SimplexCategory/GeneratorsRelations/Basic.lean | 4 +--- .../Analysis/InnerProductSpace/Projection/Minimal.lean | 5 +++-- Mathlib/Analysis/InnerProductSpace/SingularValues.lean | 5 +++-- .../Sites/Descent/DescentDataAsCoalgebra.lean | 4 ++-- Mathlib/Geometry/Convex/Cone/Dual.lean | 4 ++-- Mathlib/Geometry/Convex/Cone/Face/Basic.lean | 4 ++-- Mathlib/Geometry/Euclidean/Circumcenter.lean | 5 +++-- Mathlib/Geometry/Euclidean/Simplex.lean | 4 ++-- Mathlib/GroupTheory/Index.lean | 4 ++-- Mathlib/MeasureTheory/Integral/CircleAverage.lean | 4 ++-- Mathlib/NumberTheory/LSeries/ZetaZeros.lean | 8 ++++---- Mathlib/NumberTheory/SelbergSieve.lean | 3 +-- Mathlib/RingTheory/Polynomial/DegreeLT.lean | 5 +++-- 15 files changed, 34 insertions(+), 33 deletions(-) diff --git a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean index 7986eecf05df60..d8b6aeca200214 100644 --- a/Mathlib/Algebra/Homology/Factorizations/CM5a.lean +++ b/Mathlib/Algebra/Homology/Factorizations/CM5a.lean @@ -380,8 +380,8 @@ lemma quasiIsoAt_ι [Mono f] [Mono (homologyMap f n)] (q : ℤ) (hq : q ≤ n) : rw [← quasiIsoAt_iff_comp_right _ (π f n), mappingCocone.lift_fst] exact hf q hq · have := mono_homologyMap_π f n n (by lia) - have : Mono (homologyMap (mappingCocone.triangle (α f n)).mor₁ n) := - by dsimp; infer_instance + have : Mono (homologyMap (mappingCocone.triangle (α f n)).mor₁ n) := by + dsimp; infer_instance have h₁ := (exact_homologyShortComplex f n).fIsKernel have h₂ := (CochainComplex.homologyMap_exact₂_of_distTriang _ (DerivedCategory.mappingCocone_triangle_distinguished (α f n)) n).fIsKernel diff --git a/Mathlib/Algebra/SkewPolynomial/Basic.lean b/Mathlib/Algebra/SkewPolynomial/Basic.lean index 43773e49ace59e..ff0d4f73937d07 100644 --- a/Mathlib/Algebra/SkewPolynomial/Basic.lean +++ b/Mathlib/Algebra/SkewPolynomial/Basic.lean @@ -586,8 +586,8 @@ protected lemma smul_sum {T : Type*} [DistribSMul T S] (p : SkewPolynomial R) (b end Sum @[simp] -lemma coeff_add (p q : SkewPolynomial R) (n : ℕ) : coeff (p + q) n = coeff p n + coeff q n := - by simp [coeff] +lemma coeff_add (p q : SkewPolynomial R) (n : ℕ) : coeff (p + q) n = coeff p n + coeff q n := by + simp [coeff] end Semiring diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/Basic.lean index 28d66c1ed61ea7..03897ae8eb9109 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/GeneratorsRelations/Basic.lean @@ -134,9 +134,7 @@ lemma hom_induction (P : MorphismProperty SimplexCategoryGenRel) (id : ∀ {n : ℕ}, P (𝟙 (mk n))) (comp_δ : ∀ {n m : ℕ} (u : mk n ⟶ mk m) (i : Fin (m + 2)), P u → P (u ≫ δ i)) (comp_σ : ∀ {n m : ℕ} (u : mk n ⟶ mk (m + 1)) (i : Fin (m + 1)), P u → P (u ≫ σ i)) - {a b : SimplexCategoryGenRel} (f : a ⟶ b) : - P f := - by + {a b : SimplexCategoryGenRel} (f : a ⟶ b) : P f := by suffices generators.multiplicativeClosure ≤ P by rw [multiplicativeClosure_isGenerator_eq_top, top_le_iff] at this rw [this] diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean index 8310c62e48e4ce..68bd196c30648f 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Minimal.lean @@ -78,8 +78,9 @@ theorem exists_norm_eq_iInf_of_complete_convex {K : Set F} (ne : K.Nonempty) (h 2 * (‖a‖ * ‖a‖ + ‖b‖ * ‖b‖) := calc 4 * ‖u - half • (wq + wp)‖ * ‖u - half • (wq + wp)‖ + ‖wp - wq‖ * ‖wp - wq‖ = - 2 * ‖u - half • (wq + wp)‖ * (2 * ‖u - half • (wq + wp)‖) + ‖wp - wq‖ * ‖wp - wq‖ := - by ring + 2 * ‖u - half • (wq + wp)‖ * (2 * ‖u - half • (wq + wp)‖) + + ‖wp - wq‖ * ‖wp - wq‖ := by + ring _ = absR 2 * ‖u - half • (wq + wp)‖ * (absR 2 * ‖u - half • (wq + wp)‖) + ‖wp - wq‖ * ‖wp - wq‖ := by diff --git a/Mathlib/Analysis/InnerProductSpace/SingularValues.lean b/Mathlib/Analysis/InnerProductSpace/SingularValues.lean index 33953e92c1ef32..bc3fbc9fb1f5b2 100644 --- a/Mathlib/Analysis/InnerProductSpace/SingularValues.lean +++ b/Mathlib/Analysis/InnerProductSpace/SingularValues.lean @@ -101,8 +101,9 @@ theorem singularValues_nonneg (i : ℕ) : 0 ≤ T.singularValues i := by rw [singularValues, Finsupp.embDomain_apply, Finsupp.ofSupportFinite_coe] split_ifs <;> positivity -theorem singularValues_pos_iff_ne_zero (i : ℕ) : 0 < T.singularValues i ↔ T.singularValues i ≠ 0 := - by grind [T.singularValues_nonneg i] +theorem singularValues_pos_iff_ne_zero (i : ℕ) : + 0 < T.singularValues i ↔ T.singularValues i ≠ 0 := by + grind [T.singularValues_nonneg i] /-- Connection between `LinearMap.singularValues` and `LinearMap.IsSymmetric.eigenvalues`. diff --git a/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean b/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean index 151bea4e7600cb..8795048b194979 100644 --- a/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean +++ b/Mathlib/CategoryTheory/Sites/Descent/DescentDataAsCoalgebra.lean @@ -65,8 +65,8 @@ structure DescentDataAsCoalgebra hom (i₁ i₂ : ι) : obj i₁ ⟶ (F.map (f i₁).op.toLoc).l.toFunctor.obj ((F.map (f i₂).op.toLoc).r.toFunctor.obj (obj i₂)) - counit (i : ι) : hom i i ≫ (F.map (f i).op.toLoc).adj.counit.toNatTrans.app _ = 𝟙 _ := - by cat_disch + counit (i : ι) : hom i i ≫ (F.map (f i).op.toLoc).adj.counit.toNatTrans.app _ = 𝟙 _ := by + cat_disch coassoc (i₁ i₂ i₃ : ι) : hom i₁ i₂ ≫ (F.map (f i₁).op.toLoc).l.toFunctor.map ((F.map (f i₂).op.toLoc).r.toFunctor.map (hom i₂ i₃)) = diff --git a/Mathlib/Geometry/Convex/Cone/Dual.lean b/Mathlib/Geometry/Convex/Cone/Dual.lean index 9019b02bbc1007..c1597d600d0cab 100644 --- a/Mathlib/Geometry/Convex/Cone/Dual.lean +++ b/Mathlib/Geometry/Convex/Cone/Dual.lean @@ -116,8 +116,8 @@ alias dual_span := dual_hull variable {M' : Type*} [AddCommMonoid M'] [Module R M'] -@[simp] lemma dual_image (s : Set M') (q : M' →ₗ[R] M) : dual p (q '' s) = dual (p.comp q) s := - by ext; simp +@[simp] lemma dual_image (s : Set M') (q : M' →ₗ[R] M) : dual p (q '' s) = dual (p.comp q) s := by + ext; simp /-- Duality with respect to a general bilinear map can be expressed as duality using the identity pairing. -/ diff --git a/Mathlib/Geometry/Convex/Cone/Face/Basic.lean b/Mathlib/Geometry/Convex/Cone/Face/Basic.lean index 777c71f0d0b5a7..c99b7852c9fa02 100644 --- a/Mathlib/Geometry/Convex/Cone/Face/Basic.lean +++ b/Mathlib/Geometry/Convex/Cone/Face/Basic.lean @@ -61,8 +61,8 @@ theorem mem_of_smul_add_smul_mem_left {x y : M} {a b : R} (hF : F.IsFaceOf C) (h hF.2 hx (smul_mem _ hb.le hy) ha h theorem mem_of_smul_add_smul_mem_right {x y : M} {a b : R} (hF : F.IsFaceOf C) (hx : x ∈ C) - (hy : y ∈ C) (ha : 0 < a) (hb : 0 < b) (h : a • x + b • y ∈ F) : y ∈ F := - by apply hF.2 hy (smul_mem _ ha.le hx) hb; rwa [add_comm] + (hy : y ∈ C) (ha : 0 < a) (hb : 0 < b) (h : a • x + b • y ∈ F) : y ∈ F := by + apply hF.2 hy (smul_mem _ ha.le hx) hb; rwa [add_comm] /-- A pointed cone `C` is a face of itself. -/ @[refl, simp] diff --git a/Mathlib/Geometry/Euclidean/Circumcenter.lean b/Mathlib/Geometry/Euclidean/Circumcenter.lean index 38f13272631a25..c39390db2cc772 100644 --- a/Mathlib/Geometry/Euclidean/Circumcenter.lean +++ b/Mathlib/Geometry/Euclidean/Circumcenter.lean @@ -67,8 +67,9 @@ theorem existsUnique_dist_eq_of_insert {s : AffineSubspace ℝ P} let cr₂ := √(cr * cr + ycc₂ * ycc₂) use ⟨cc₂, cr₂⟩ simp -zeta -proj only - have hpo : p = (1 : ℝ) • (p -ᵥ orthogonalProjection s p : V) +ᵥ (orthogonalProjection s p : P) := - by simp + have hpo : p = (1 : ℝ) • (p -ᵥ orthogonalProjection s p : V) +ᵥ + (orthogonalProjection s p : P) := by + simp constructor · constructor · refine vadd_mem_of_mem_direction ?_ (mem_affineSpan ℝ (Set.mem_insert_of_mem _ hcc)) diff --git a/Mathlib/Geometry/Euclidean/Simplex.lean b/Mathlib/Geometry/Euclidean/Simplex.lean index 7ccbcfba69441d..ce7628ed0203ea 100644 --- a/Mathlib/Geometry/Euclidean/Simplex.lean +++ b/Mathlib/Geometry/Euclidean/Simplex.lean @@ -110,8 +110,8 @@ theorem dist_point_centroid (t : Affine.Triangle ℝ P) (i : Fin 3) : /-- In a triangle, the distance from a vertex to the `faceOppositeCentroid` equals three times the distance from the `centroid` to the `faceOppositeCentroid`. -/ theorem dist_point_faceOppositeCentroid (t : Affine.Triangle ℝ P) (i : Fin 3) : - dist (t.points i) (t.faceOppositeCentroid i) = 3 * dist t.centroid (t.faceOppositeCentroid i) := - by + dist (t.points i) (t.faceOppositeCentroid i) = + 3 * dist t.centroid (t.faceOppositeCentroid i) := by rw [Affine.Simplex.dist_point_faceOppositeCentroid] norm_cast diff --git a/Mathlib/GroupTheory/Index.lean b/Mathlib/GroupTheory/Index.lean index 9e3c08a992a7f8..579a2624ffd741 100644 --- a/Mathlib/GroupTheory/Index.lean +++ b/Mathlib/GroupTheory/Index.lean @@ -691,8 +691,8 @@ lemma isFiniteRelIndex_iff_finiteIndex : rw [isFiniteRelIndex_iff_relIndex_ne_zero, finiteIndex_iff, relIndex] @[to_additive] -theorem not_finiteIndex_iff : ¬ H.FiniteIndex ↔ H.index = 0 := - by simp [finiteIndex_iff] +theorem not_finiteIndex_iff : ¬ H.FiniteIndex ↔ H.index = 0 := by + simp [finiteIndex_iff] @[simp] theorem finiteIndex_toAddSubgroup_iff : H.toAddSubgroup.FiniteIndex ↔ H.FiniteIndex := by diff --git a/Mathlib/MeasureTheory/Integral/CircleAverage.lean b/Mathlib/MeasureTheory/Integral/CircleAverage.lean index 1360791d7efdd0..33e0e2d1823ec9 100644 --- a/Mathlib/MeasureTheory/Integral/CircleAverage.lean +++ b/Mathlib/MeasureTheory/Integral/CircleAverage.lean @@ -203,8 +203,8 @@ theorem ContinuousOn.circleAverage {f : ℂ → E} {s : Set ℝ} {c : ℂ} ContinuousOn (circleAverage f c) s := by rw [continuousOn_iff_continuous_domRestrict] at * apply (intervalIntegral.continuous_parametric_intervalIntegral_of_continuous' _ _ _).const_smul - have (x : s × ℝ) : circleMap c x.1 x.2 ∈ {z | ‖z - c‖ ∈ s} := - by simp [abs_of_nonneg (hs x.1 (Subtype.coe_prop x.1))] + have (x : s × ℝ) : circleMap c x.1 x.2 ∈ {z | ‖z - c‖ ∈ s} := by + simp [abs_of_nonneg (hs x.1 (Subtype.coe_prop x.1))] apply hf.comp (f := (fun x ↦ ⟨circleMap c x.1 x.2, this x⟩)) fun_prop diff --git a/Mathlib/NumberTheory/LSeries/ZetaZeros.lean b/Mathlib/NumberTheory/LSeries/ZetaZeros.lean index 5b8765ca7d6d46..3de3859e78e028 100644 --- a/Mathlib/NumberTheory/LSeries/ZetaZeros.lean +++ b/Mathlib/NumberTheory/LSeries/ZetaZeros.lean @@ -54,11 +54,11 @@ private lemma compl_riemannZetaZeros_mem_codiscrete : · exact Filter.mem_of_superset (this x hx) (by grind [riemannZeta_one_ne_zero, mem_riemannZetaZeros]) -lemma isClosed_riemannZetaZeros : IsClosed riemannZetaZeros := - by simpa using (mem_codiscrete'.mp compl_riemannZetaZeros_mem_codiscrete).1 +lemma isClosed_riemannZetaZeros : IsClosed riemannZetaZeros := by + simpa using (mem_codiscrete'.mp compl_riemannZetaZeros_mem_codiscrete).1 -lemma isDiscrete_riemannZetaZeros : IsDiscrete riemannZetaZeros := - by simpa using (mem_codiscrete'.mp compl_riemannZetaZeros_mem_codiscrete).2 +lemma isDiscrete_riemannZetaZeros : IsDiscrete riemannZetaZeros := by + simpa using (mem_codiscrete'.mp compl_riemannZetaZeros_mem_codiscrete).2 /-- Any compact subset of `ℂ` contains only finitely many zeros of the Riemann zeta function. -/ lemma IsCompact.inter_riemannZetaZeros_finite {S : Set ℂ} (hS : IsCompact S) : diff --git a/Mathlib/NumberTheory/SelbergSieve.lean b/Mathlib/NumberTheory/SelbergSieve.lean index 7a855ecf194573..1bdaf06eaeaaf1 100644 --- a/Mathlib/NumberTheory/SelbergSieve.lean +++ b/Mathlib/NumberTheory/SelbergSieve.lean @@ -306,8 +306,7 @@ theorem inv_selbergTerms_eq_sum_divisors_moebius_nu {l : ℕ} (hl : Squarefree l congr! 1 with ⟨d, e⟩ hd obtain ⟨rfl, -⟩ : d * e = l ∧ _ := by simpa using hd obtain ⟨hde, -⟩ : d.Coprime e ∧ _ := by simpa only [squarefree_mul_iff] using hl - obtain ⟨hd0, he0⟩ : ¬s.nu d = 0 ∧ ¬s.nu e = 0 := - by simp_all [s.nu_mult.map_mul_of_coprime hde] + obtain ⟨hd0, he0⟩ : ¬s.nu d = 0 ∧ ¬s.nu e = 0 := by simp_all [s.nu_mult.map_mul_of_coprime hde] simp [field, s.nu_mult.map_mul_of_coprime hde, mul_assoc] theorem nu_inv_eq_sum_divisors_inv_selbergTerms {d : ℕ} (hdP : d ∣ s.prodPrimes) : diff --git a/Mathlib/RingTheory/Polynomial/DegreeLT.lean b/Mathlib/RingTheory/Polynomial/DegreeLT.lean index eb85f8480eec66..6a74613781c1ef 100644 --- a/Mathlib/RingTheory/Polynomial/DegreeLT.lean +++ b/Mathlib/RingTheory/Polynomial/DegreeLT.lean @@ -117,8 +117,9 @@ lemma addLinearEquiv_symm_apply_inr (Q : R[X]_n) : lemma addLinearEquiv_symm_apply (PQ) : ((addLinearEquiv R m n).symm PQ : R[X]) = (PQ.1 : R[X]) + (PQ.2 : R[X]) * X ^ (m : ℕ) := calc - _ = ((addLinearEquiv R m n).symm (LinearMap.inl R _ _ PQ.1 + LinearMap.inr R _ _ PQ.2) : R[X]) := - by rw [LinearMap.inl_apply, LinearMap.inr_apply, Prod.add_def, add_zero, zero_add] + _ = ((addLinearEquiv R m n).symm (LinearMap.inl R _ _ PQ.1 + LinearMap.inr R _ _ PQ.2) : + R[X]) := by + rw [LinearMap.inl_apply, LinearMap.inr_apply, Prod.add_def, add_zero, zero_add] _ = _ := by rw [map_add, Submodule.coe_add, addLinearEquiv_symm_apply_inl, addLinearEquiv_symm_apply_inr] From 03b2a04be172c9ef9c9b9d25cdbf4ffd2064a326 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:22:02 +0000 Subject: [PATCH 0945/1300] perf: lower priority for `IsSimpleRing.instNontrivial` and `UnitalShelf.toOne` (#40304) These instances have very weak keys `([Nontrivial, *])` resp. `([One, *])`, hence are always applied. Let's lower their priority a bit. --- Mathlib/Algebra/Quandle.lean | 2 ++ Mathlib/RingTheory/SimpleRing/Basic.lean | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Quandle.lean b/Mathlib/Algebra/Quandle.lean index fd39b97a931215..9ab055f2195342 100644 --- a/Mathlib/Algebra/Quandle.lean +++ b/Mathlib/Algebra/Quandle.lean @@ -108,6 +108,8 @@ class UnitalShelf (α : Type u) extends Shelf α, One α where one_act : ∀ a : α, act 1 a = a act_one : ∀ a : α, act a 1 = a +attribute [instance 100] UnitalShelf.toOne + /-- The type of homomorphisms between shelves. This is also the notion of rack and quandle homomorphisms. -/ diff --git a/Mathlib/RingTheory/SimpleRing/Basic.lean b/Mathlib/RingTheory/SimpleRing/Basic.lean index 300ab378076f26..11c4a0c353d51d 100644 --- a/Mathlib/RingTheory/SimpleRing/Basic.lean +++ b/Mathlib/RingTheory/SimpleRing/Basic.lean @@ -15,7 +15,7 @@ A ring `R` is **simple** if it has only two two-sided ideals, namely `⊥` and ` ## Main results -- `IsSimpleRing.nontrivial`: simple rings are non-trivial. +- `IsSimpleRing.instNontrivial`: simple rings are non-trivial. - `DivisionRing.isSimpleRing`: division rings are simple. - `RingHom.injective`: every ring homomorphism from a simple ring to a nontrivial ring is injective. - `IsSimpleRing.iff_injective_ringHom`: a ring is simple iff every ring homomorphism to a nontrivial @@ -35,6 +35,8 @@ instance [IsSimpleRing R] : Nontrivial R := by obtain ⟨x, _, hx⟩ := SetLike.exists_of_lt (bot_lt_top : (⊥ : TwoSidedIdeal R) < ⊤) use x, 0, hx +attribute [instance 200] IsSimpleRing.instNontrivial + lemma one_mem_of_ne_bot {A : Type*} [NonAssocRing A] [IsSimpleRing A] (I : TwoSidedIdeal A) (hI : I ≠ ⊥) : (1 : A) ∈ I := (eq_bot_or_eq_top I).resolve_left hI ▸ ⟨⟩ From 3d8d5c0359d52cc45e9a5283d8328e5385201f22 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:22:04 +0000 Subject: [PATCH 0946/1300] feat(LinearAlgebra/LinearIndependent/Basic): linear independence along faithful algebra maps (#41682) This PR adds results about linear independence along faithful algebra maps. Co-authored-by: tb65536 --- Mathlib.lean | 1 + .../LinearIndependent/Algebra.lean | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 Mathlib/LinearAlgebra/LinearIndependent/Algebra.lean diff --git a/Mathlib.lean b/Mathlib.lean index 129271448fa6be..e5265e463a28cb 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5087,6 +5087,7 @@ public import Mathlib.LinearAlgebra.JordanChevalley public import Mathlib.LinearAlgebra.Lagrange public import Mathlib.LinearAlgebra.LeftExact public import Mathlib.LinearAlgebra.LinearDisjoint +public import Mathlib.LinearAlgebra.LinearIndependent.Algebra public import Mathlib.LinearAlgebra.LinearIndependent.BaseChange public import Mathlib.LinearAlgebra.LinearIndependent.Basic public import Mathlib.LinearAlgebra.LinearIndependent.Defs diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Algebra.lean b/Mathlib/LinearAlgebra/LinearIndependent/Algebra.lean new file mode 100644 index 00000000000000..036b20fdc43ac7 --- /dev/null +++ b/Mathlib/LinearAlgebra/LinearIndependent/Algebra.lean @@ -0,0 +1,37 @@ +/- +Copyright (c) 2026 Thomas Browning. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Thomas Browning +-/ +module + +public import Mathlib.Algebra.Algebra.Hom +public import Mathlib.LinearAlgebra.LinearIndependent.Defs + +/-! +# Linear independence and algebra maps + +This file collects results relating linear independence along algebra maps. + +These results cannot go in `LinearAlgebra/LinearIndependent/Basic.lean` due to the algebra import. +-/ + +public section + +variable {R S A : Type*} [CommSemiring R] [CommSemiring S] [Semiring A] + [Algebra R S] [Algebra S A] [Algebra R A] [IsScalarTower R S A] [FaithfulSMul S A] + +@[simp] +theorem LinearIndependent.algebraMap_comp_iff {ι : Type*} {v : ι → S} : + LinearIndependent R (algebraMap S A ∘ v) ↔ LinearIndependent R v := + (IsScalarTower.toAlgHom R S A).toLinearMap.linearIndependent_iff_of_injOn (by simp) + +@[simp] +theorem LinearIndepOn.algebraMap_comp_iff {ι : Type*} {v : ι → S} {s : Set ι} : + LinearIndepOn R (algebraMap S A ∘ v) s ↔ LinearIndepOn R v s := + LinearIndependent.algebraMap_comp_iff + +@[simp] +theorem LinearIndepOn.id_image_algebraMap_iff {s : Set S} : + LinearIndepOn R id (algebraMap S A '' s) ↔ LinearIndepOn R id s := + (linearIndepOn_iff_image (by simp)).symm.trans LinearIndepOn.algebraMap_comp_iff From 6ff9d2aabb8ca3a2d2b70ad0f239b49830e01a5b Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:22:07 +0000 Subject: [PATCH 0947/1300] chore: replace some redundant `simpa only using h` (#41931) This replaces all `simpa only using h` with `exact h` (this works at reducible transparency, so there should be no issue). EDIT: I meant `with_reducible exact ...` would work as well (The background of this PR is that i want to golf `simpa [...] using h` more generally, but that is quite computationally expensive) Co-authored-by: Batixx --- Mathlib/Algebra/Category/Grp/EpiMono.lean | 2 +- Mathlib/Analysis/Convex/StdSimplex.lean | 2 +- Mathlib/RingTheory/FractionalIdeal/Operations.lean | 2 +- Mathlib/RingTheory/RootsOfUnity/Complex.lean | 4 ++-- Mathlib/Topology/MetricSpace/Pseudo/Pi.lean | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Category/Grp/EpiMono.lean b/Mathlib/Algebra/Category/Grp/EpiMono.lean index ecca59b6ecd775..b829d0ab5e921a 100644 --- a/Mathlib/Algebra/Category/Grp/EpiMono.lean +++ b/Mathlib/Algebra/Category/Grp/EpiMono.lean @@ -227,7 +227,7 @@ theorem h_apply_infinity (x : B) (hx : x ∈ f.hom.range) : (h x) ∞ = ∞ := b change ((τ).symm.trans (g x)).trans τ _ = _ simp only [Equiv.coe_trans, Function.comp_apply] rw [τ_symm_apply_infinity, g_apply_fromCoset] - simpa only using τ_apply_fromCoset' f x hx + exact τ_apply_fromCoset' f x hx theorem h_apply_fromCoset (x : B) : (h x) (fromCoset ⟨f.hom.range, 1, one_leftCoset _⟩) = diff --git a/Mathlib/Analysis/Convex/StdSimplex.lean b/Mathlib/Analysis/Convex/StdSimplex.lean index 7a0c2c2866a186..23e19ff83b6045 100644 --- a/Mathlib/Analysis/Convex/StdSimplex.lean +++ b/Mathlib/Analysis/Convex/StdSimplex.lean @@ -301,7 +301,7 @@ variable [IsOrderedRing S] @[simp] lemma le_one (s : stdSimplex S X) (x : X) : s x ≤ 1 := by rw [← sum_eq_one s] - simpa only using Finset.single_le_sum (by simp) (by simp) + exact Finset.single_le_sum (by simp) (by simp) lemma image_linearMap (f : X → Y) : Set.image (FunOnFinite.linearMap S S f) (stdSimplex S X) ⊆ stdSimplex S Y := by diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index 67a3cf90c533bf..ecc710ca45a3ec 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -289,7 +289,7 @@ variable {I J : FractionalIdeal R⁰ K} (h : K →ₐ[R] K') theorem exists_ne_zero_mem_isInteger [Nontrivial R] (hI : I ≠ 0) : ∃ x, x ≠ 0 ∧ algebraMap R K x ∈ I := by obtain ⟨y : K, y_mem, y_notMem⟩ := - SetLike.exists_of_lt (by simpa only using bot_lt_iff_ne_bot.mpr hI) + SetLike.exists_of_lt (bot_lt_iff_ne_bot.mpr hI) have y_ne_zero : y ≠ 0 := by simpa using y_notMem obtain ⟨z, ⟨x, hx⟩⟩ := exists_integer_multiple R⁰ y refine ⟨x, ?_, ?_⟩ diff --git a/Mathlib/RingTheory/RootsOfUnity/Complex.lean b/Mathlib/RingTheory/RootsOfUnity/Complex.lean index aec808d1ed3b3b..733daaab5a1e2a 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Complex.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Complex.lean @@ -108,8 +108,8 @@ nonrec theorem mem_rootsOfUnity (n : ℕ) [NeZero n] (x : Units ℂ) : have hn0 : (n : ℂ) ≠ 0 := mod_cast NeZero.out constructor · intro h - obtain ⟨i, hi, H⟩ : ∃ i < (n : ℕ), exp (2 * π * I / n) ^ i = x := by - simpa only using (isPrimitiveRoot_exp n NeZero.out).eq_pow_of_pow_eq_one h + obtain ⟨i, hi, H⟩ : ∃ i < (n : ℕ), exp (2 * π * I / n) ^ i = x := + (isPrimitiveRoot_exp n NeZero.out).eq_pow_of_pow_eq_one h refine ⟨i, hi, ?_⟩ rw [← H, ← exp_nat_mul] congr 1 diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean b/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean index 023a65d4d1cb14..a4d0deb374ca70 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Pi.lean @@ -43,7 +43,7 @@ instance pseudoMetricSpacePi : PseudoMetricSpace (∀ b, X b) := by lift C to ℝ≥0 using hC refine ⟨fun H x hx y hy ↦ NNReal.coe_le_coe.2 <| Finset.sup_le fun b _ ↦ H b hx hy, fun H b x hx y hy ↦ NNReal.coe_le_coe.2 ?_⟩ - simpa only using Finset.sup_le_iff.1 (NNReal.coe_le_coe.1 <| H hx hy) b (Finset.mem_univ b) + exact Finset.sup_le_iff.1 (NNReal.coe_le_coe.1 <| H hx hy) b (Finset.mem_univ b) lemma nndist_pi_def (f g : ∀ b, X b) : nndist f g = sup univ fun b => nndist (f b) (g b) := rfl From b7d0290f4efa01090ea4141df3a07a02f29016c2 Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:22:10 +0000 Subject: [PATCH 0948/1300] doc(RingTheory/MvPowerSeries/Order): improve docstrings of `order` and `weightedOrder` (#41959) These docstrings weren't very informative. Also `weightedOrder` mentioned the Lean 3 name `mv_power_series`. --- Mathlib/RingTheory/MvPowerSeries/Order.lean | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/MvPowerSeries/Order.lean b/Mathlib/RingTheory/MvPowerSeries/Order.lean index 09420051194ecd..0097654ce0edb8 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Order.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Order.lean @@ -135,7 +135,8 @@ theorem ne_zero_iff_exists_coeff_ne_zero_and_weight : f ≠ 0 ↔ (∃ n : ℕ, ∃ d : σ →₀ ℕ, coeff d f ≠ 0 ∧ weight w d = n) := by simpa using ne_zero_iff_exists_coeff_ne_zero f -/-- The weighted order of a mv_power_series -/ +/-- The weighted order with respect to `w : σ → ℕ`. This is the minimum value +of `weight w d` over all exponents `d` with nonzero coefficient `coeff d f`. -/ def weightedOrder (f : MvPowerSeries σ R) : ℕ∞ := by classical exact dite (f = 0) (fun _ => ⊤) fun h => @@ -384,7 +385,8 @@ theorem ne_zero_iff_exists_coeff_ne_zero_and_degree : simp_rw [degree_eq_weight_one] exact ne_zero_iff_exists_coeff_ne_zero_and_weight (fun _ => 1) -/-- The order of an `MvPowerSeries`. -/ +/-- The order of a multivariate power series is the the minimum total degree over all +exponents `d` with nonzero coefficient `coeff d f`. -/ def order (f : MvPowerSeries σ R) : ℕ∞ := weightedOrder (fun _ => 1) f @[simp] From 2e27cde445666f05d31d420598bba4c78b3251b2 Mon Sep 17 00:00:00 2001 From: Tian Chen <27919714+peakpoint@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:22:12 +0000 Subject: [PATCH 0949/1300] =?UTF-8?q?feat(Topology):=20generalize=20Dieudo?= =?UTF-8?q?nn=C3=A9's=20theorem=20to=20R1=20spaces=20(#41968)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Topology/Compactness/Paracompact.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/Compactness/Paracompact.lean b/Mathlib/Topology/Compactness/Paracompact.lean index 78bc1e4851cb99..a4501e5bb9e31d 100644 --- a/Mathlib/Topology/Compactness/Paracompact.lean +++ b/Mathlib/Topology/Compactness/Paracompact.lean @@ -293,11 +293,11 @@ instance (priority := 100) paracompact_of_locallyCompact_sigmaCompact [WeaklyLoc ⟨β, c, t, hto, htc, htf⟩ exact ⟨β, t, fun x ↦ (hto x).1.2, htc, htf, fun b ↦ ⟨i <| c b, (hto b).2⟩⟩ -/-- **Dieudonné's theorem**: a paracompact Hausdorff space is normal. +/-- **Dieudonné's theorem**: a paracompact R₁ space is normal. Formalization is based on the proof at [ncatlab](https://ncatlab.org/nlab/show/paracompact+Hausdorff+spaces+are+normal). -/ -instance (priority := 100) T4Space.of_paracompactSpace_t2Space [T2Space X] [ParacompactSpace X] : - T4Space X := by +instance (priority := 100) NormalSpace.of_paracompactSpace_r1Space + [R1Space X] [ParacompactSpace X] : NormalSpace X := by -- First we show how to go from points to a set on one side. have : ∀ s t : Set X, IsClosed s → (∀ x ∈ s, ∃ u v, IsOpen u ∧ IsOpen v ∧ x ∈ u ∧ t ⊆ v ∧ Disjoint u v) → @@ -318,6 +318,6 @@ instance (priority := 100) T4Space.of_paracompactSpace_t2Space [T2Space X] [Para refine { normal := fun s t hs ht hst ↦ this s t hs fun x hx ↦ ?_ } rcases this t {x} ht fun y hy ↦ (by simp_rw [singleton_subset_iff] - exact t2_separation (hst.symm.ne_of_mem hy hx)) + exact r1_separation <| ht.not_inseparable hy <| hst.notMem_of_mem_left hx) with ⟨v, u, hv, hu, htv, hxu, huv⟩ exact ⟨u, v, hu, hv, singleton_subset_iff.1 hxu, htv, huv.symm⟩ From 9b53612f8d8de79c06e752024f9b087e9ea5d0fa Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:22:15 +0000 Subject: [PATCH 0950/1300] chore: golf proofs of `mdifferentiableAt_atlas{_symm}` (#42011) - introduce `mdifferentiableAt_of_mem_maximalAtlas` and `mdifferentiableAt_symm_of_mem_maximalAtlas`; these generalise the corresponding results to members of the maximal atlas; - golf the proofs of these lemmas by re-using the corresponding results about maximal atlas members being C^n. The second bullet slightly strenthens an import dependency (of this file on the corresponding `C^n` proofs): I consider this unproblematic since - that dependency was already implicit before, - there does not seem a pressing need to tease apart imports further; if such need arises, this proof can be reverted, - for #41796 (the first half of "the composition of immersions is an immersion"), I need versions of these lemmas for extended charts (which are known to be in the maximal atlas). This is a neat way to obtain this. --- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 54 +++++++------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index adef040c3344e0..e20cd71759467d 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -89,47 +89,29 @@ end ModelWithCorners section Charts -variable [IsManifold I 1 M] [IsManifold I' 1 M'] - [IsManifold I'' 1 M''] {e : OpenPartialHomeomorph M H} - -theorem mdifferentiableAt_atlas (h : e ∈ atlas H M) {x : M} (hx : x ∈ e.source) : MDiffAt e x := by - rw [mdifferentiableAt_iff] - refine ⟨(e.continuousOn x hx).continuousAt (e.open_source.mem_nhds hx), ?_⟩ - have mem : - I ((chartAt H x : M → H) x) ∈ I.symm ⁻¹' ((chartAt H x).symm ≫ₕ e).source ∩ range I := by - simp only [hx, mfld_simps] - have : (chartAt H x).symm.trans e ∈ contDiffGroupoid 1 I := - HasGroupoid.compatible (chart_mem_atlas H x) h - have A : - ContDiffOn 𝕜 1 (I ∘ (chartAt H x).symm.trans e ∘ I.symm) - (I.symm ⁻¹' ((chartAt H x).symm.trans e).source ∩ range I) := - this.1 - have B := A.differentiableOn one_ne_zero (I ((chartAt H x : M → H) x)) mem - simp only [mfld_simps] at B - rw [inter_comm, differentiableWithinAt_inter] at B - · simpa only [mfld_simps] - · apply IsOpen.mem_nhds ((OpenPartialHomeomorph.open_source _).preimage I.continuous_symm) mem.1 +variable {e : OpenPartialHomeomorph M H} + +theorem mdifferentiableAt_of_mem_maximalAtlas + (h : e ∈ IsManifold.maximalAtlas I 1 M) {x : M} (hx : x ∈ e.source) : MDiffAt e x := + (contMDiffAt_of_mem_maximalAtlas h hx).mdifferentiableAt one_ne_zero + +lemma mdifferentiableAt_symm_of_mem_maximalAtlas + (h : e ∈ IsManifold.maximalAtlas I 1 M) {x : H} (hx : x ∈ e.target) : + MDiffAt e.symm x := + contMDiffAt_symm_of_mem_maximalAtlas h hx |>.mdifferentiableAt one_ne_zero + +variable [IsManifold I 1 M] [IsManifold I' 1 M'] [IsManifold I'' 1 M''] + +theorem mdifferentiableAt_atlas (h : e ∈ atlas H M) {x : M} (hx : x ∈ e.source) : MDiffAt e x := + contMDiffAt_of_mem_maximalAtlas (IsManifold.subset_maximalAtlas h) hx + |>.mdifferentiableAt one_ne_zero theorem mdifferentiableOn_atlas (h : e ∈ atlas H M) : MDiff[e.source] e := fun _x hx => (mdifferentiableAt_atlas h hx).mdifferentiableWithinAt theorem mdifferentiableAt_atlas_symm (h : e ∈ atlas H M) {x : H} (hx : x ∈ e.target) : - MDiffAt e.symm x := by - rw [mdifferentiableAt_iff] - refine ⟨(e.continuousOn_symm x hx).continuousAt (e.open_target.mem_nhds hx), ?_⟩ - have mem : I x ∈ I.symm ⁻¹' (e.symm ≫ₕ chartAt H (e.symm x)).source ∩ range I := by - simp only [hx, mfld_simps] - have : e.symm.trans (chartAt H (e.symm x)) ∈ contDiffGroupoid 1 I := - HasGroupoid.compatible h (chart_mem_atlas H _) - have A : - ContDiffOn 𝕜 1 (I ∘ e.symm.trans (chartAt H (e.symm x)) ∘ I.symm) - (I.symm ⁻¹' (e.symm.trans (chartAt H (e.symm x))).source ∩ range I) := - this.1 - have B := A.differentiableOn one_ne_zero (I x) mem - simp only [mfld_simps] at B - rw [inter_comm, differentiableWithinAt_inter] at B - · simpa only [mfld_simps] - · apply IsOpen.mem_nhds ((OpenPartialHomeomorph.open_source _).preimage I.continuous_symm) mem.1 + MDiffAt e.symm x := + mdifferentiableAt_symm_of_mem_maximalAtlas (IsManifold.subset_maximalAtlas h) hx theorem mdifferentiableOn_atlas_symm (h : e ∈ atlas H M) : MDiff[e.target] e.symm := fun _x hx => (mdifferentiableAt_atlas_symm h hx).mdifferentiableWithinAt From 280cbb137e2622964c6bc46be3678b50d05b0d22 Mon Sep 17 00:00:00 2001 From: Junye <108162087+JJYYY-JJY@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:55:38 +0000 Subject: [PATCH 0951/1300] chore: remove flexible linter suppressions (#40033) Replace `simp; infer_instance` with explicit proofs. Co-authored-by: Junye Ji --- .../Dynamics/TopologicalEntropy/DynamicalEntourage.lean | 8 ++++---- Mathlib/Topology/UniformSpace/Ultra/Constructions.lean | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean b/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean index 2c79f90c009f3b..4452a93e0c88f3 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/DynamicalEntourage.lean @@ -83,13 +83,13 @@ lemma ball_dynEntourage_mem_nhds [UniformSpace X] (h : Continuous T) simp only [map_iterate, _root_.ball_preimage] exact (h.iterate k).continuousAt.preimage_mem_nhds (ball_mem_nhds (T^[k] x) U_uni) -set_option linter.flexible false in -- simp followed by infer_instance instance isRefl_dynEntourage [U.IsRefl] : (dynEntourage T U n).IsRefl := by - simp [dynEntourage]; infer_instance + simp only [dynEntourage, map_iterate] + infer_instance -set_option linter.flexible false in -- simp followed by infer_instance instance isSymm_dynEntourage [U.IsSymm] : (dynEntourage T U n).IsSymm := by - simp [dynEntourage]; infer_instance + simp only [dynEntourage, map_iterate] + infer_instance lemma dynEntourage_comp_subset (T : X → X) (U V : SetRel X X) (n : ℕ) : (dynEntourage T U n) ○ (dynEntourage T V n) ⊆ dynEntourage T (U ○ V) n := by diff --git a/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean b/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean index d95ba71c68bdcf..e2d559176cd9b4 100644 --- a/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean +++ b/Mathlib/Topology/UniformSpace/Ultra/Constructions.lean @@ -80,10 +80,10 @@ instance IsUltraUniformity.pi {ι : Type*} {X : ι → Type*} [U : Π i, Uniform instance IsUltraUniformity.bot [UniformSpace X] [DiscreteUniformity X] : IsUltraUniformity X := by have := Filter.hasBasis_principal (SetRel.id (α := X)) rw [← DiscreteUniformity.eq_principal_setRelId] at this - apply mk_of_hasBasis this <;> { rw [forall_const]; infer_instance } + exact mk_of_hasBasis this inferInstance inferInstance lemma IsUltraUniformity.top : @IsUltraUniformity X (⊤ : UniformSpace X) := by let : UniformSpace X := ⊤ have := Filter.hasBasis_top (α := (X × X)) rw [← top_uniformity] at this - apply mk_of_hasBasis this <;> { rw [forall_const]; infer_instance } + exact mk_of_hasBasis this inferInstance inferInstance From 8c507ffc76096945923128217ca4c9e6180b7282 Mon Sep 17 00:00:00 2001 From: Eric Wieser <425260+eric-wieser@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:55:40 +0000 Subject: [PATCH 0952/1300] feat: connect BinaryTree and Ordnode (#40370) These types are basically isomorphic; this PR adds the trivial defs that link them. --- Mathlib/Data/Ordmap/Ordnode.lean | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Mathlib/Data/Ordmap/Ordnode.lean b/Mathlib/Data/Ordmap/Ordnode.lean index 5992819f2d0e9c..ba756f8df2559b 100644 --- a/Mathlib/Data/Ordmap/Ordnode.lean +++ b/Mathlib/Data/Ordmap/Ordnode.lean @@ -8,6 +8,7 @@ module public import Mathlib.Order.Compare public import Mathlib.Data.Nat.PSub public import Batteries.Data.List.Lemmas +public import Mathlib.Data.Tree.Basic /-! # Ordered sets @@ -68,7 +69,9 @@ universe u /-- An `Ordnode α` is a finite set of values, represented as a tree. The operations on this type maintain that the tree is balanced - and correctly stores subtree sizes at each level. -/ + and correctly stores subtree sizes at each level. + +This is a copy of `BinaryTree` with a cached `size` field for `BinaryTree.numNodes`. -/ inductive Ordnode (α : Type u) : Type u | nil : Ordnode α | node (size : ℕ) (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α @@ -166,6 +169,28 @@ O(1). Construct a node with the correct size information, without rebalancing. - def node' (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α := node (size l + size r + 1) l x r +/-- Convert to an `OrdNode` by pre-computing the sizes. -/ +@[simp] +def _root_.BinaryTree.toOrdNode : BinaryTree α → Ordnode α + | .nil => .nil + | .node x l r => .node' l.toOrdNode x r.toOrdNode + +@[simp] +theorem size_toOrdNode (b : BinaryTree α) : + b.toOrdNode.size = b.numNodes := by + induction b with simp [BinaryTree.toOrdNode, *] + +/-- Convert to an `BinaryTree`, discarding the cached size information. -/ +@[simp] +def toBinaryTree : Ordnode α → BinaryTree α + | .nil => .nil + | .node _ l x r => .node x l.toBinaryTree r.toBinaryTree + +@[simp] +theorem toBinaryTree_toOrdNode (b : BinaryTree α) : + toBinaryTree b.toOrdNode = b := by + induction b with simp [BinaryTree.toOrdNode, toBinaryTree, * ] + /-- Basic pretty printing for `Ordnode α` that shows the structure of the tree. ``` From 0b6c1c0146ff30103803371f12a16c8d515c8c97 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Wed, 22 Jul 2026 17:55:43 +0000 Subject: [PATCH 0953/1300] feat(Algebra/FreeMonoid): `FreeMonoid.length` is surjective (#41928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove the theorem `FreeMonoid.length_surjective`, stating that `FreeMonoid.length` is surjective when `α` is nonempty. --- Mathlib/Algebra/FreeMonoid/Basic.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index 806fe80a9bcdac..bc1c911462ccfa 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -172,6 +172,10 @@ theorem length_eq_zero : length a = 0 ↔ a = 1 := List.length_eq_zero_iff @[to_additive (attr := simp)] theorem length_of (m : α) : length (of m) = 1 := rfl +@[to_additive] +theorem length_surjective [Nonempty α] : (@length α).Surjective := + ‹Nonempty α›.elim fun a n => ⟨FreeMonoid.ofList (List.replicate n a), by simp [length]⟩ + @[to_additive FreeAddMonoid.length_eq_one] theorem length_eq_one : length a = 1 ↔ ∃ m, a = FreeMonoid.of m := List.length_eq_one_iff From 0c60917e582430c2052c4d5ccd7ca1176ad9a6cc Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Wed, 22 Jul 2026 17:55:46 +0000 Subject: [PATCH 0954/1300] fix(GroupTheory/Coprod): fix recursor argument name (#41930) Fix the argument names of `Monoid.Coprod.induction_on'` and `Monoid.Coprod.induction_on`. Name the motive `motive` and name the minor premises according to their contents. --- Mathlib/GroupTheory/Coprod/Basic.lean | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Mathlib/GroupTheory/Coprod/Basic.lean b/Mathlib/GroupTheory/Coprod/Basic.lean index 2cdc9c603dd46e..c831e8580d95a9 100644 --- a/Mathlib/GroupTheory/Coprod/Basic.lean +++ b/Mathlib/GroupTheory/Coprod/Basic.lean @@ -193,10 +193,10 @@ theorem mk_of_inl (x : M) : (mk (of (.inl x)) : M ∗ N) = inl x := rfl theorem mk_of_inr (x : N) : (mk (of (.inr x)) : M ∗ N) = inr x := rfl @[to_additive (attr := elab_as_elim)] -theorem induction_on' {C : M ∗ N → Prop} (m : M ∗ N) - (one : C 1) - (inl_mul : ∀ m x, C x → C (inl m * x)) - (inr_mul : ∀ n x, C x → C (inr n * x)) : C m := by +theorem induction_on' {motive : M ∗ N → Prop} (m : M ∗ N) + (one : motive 1) + (inl_mul : ∀ m x, motive x → motive (inl m * x)) + (inr_mul : ∀ n x, motive x → motive (inr n * x)) : motive m := by rcases mk_surjective m with ⟨x, rfl⟩ induction x using FreeMonoid.inductionOn' with | one => exact one @@ -206,8 +206,9 @@ theorem induction_on' {C : M ∗ N → Prop} (m : M ∗ N) | inr n => simpa using inr_mul n _ ih @[to_additive (attr := elab_as_elim)] -theorem induction_on {C : M ∗ N → Prop} (m : M ∗ N) - (inl : ∀ m, C (inl m)) (inr : ∀ n, C (inr n)) (mul : ∀ x y, C x → C y → C (x * y)) : C m := +theorem induction_on {motive : M ∗ N → Prop} (m : M ∗ N) + (inl : ∀ m, motive (inl m)) (inr : ∀ n, motive (inr n)) + (mul : ∀ x y, motive x → motive y → motive (x * y)) : motive m := induction_on' m (by simpa using inl 1) (fun _ _ ↦ mul _ _ (inl _)) fun _ _ ↦ mul _ _ (inr _) /-- Lift a monoid homomorphism `FreeMonoid (M ⊕ N) →* P` satisfying additional properties to From b8a692e177dda10fde4d351f9b00c81ae9f76a20 Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:55:48 +0000 Subject: [PATCH 0955/1300] chore: split file `Algebra.Lie.Algebra.Basis` (#41985) --- Mathlib.lean | 3 +- Mathlib/Algebra/Lie/Basis/Base.lean | 124 ++++++++++++++++++ .../Lie/{Basis.lean => Basis/Basic.lean} | 106 +-------------- .../RootSystem/GeckConstruction/Basis.lean | 2 +- 4 files changed, 129 insertions(+), 106 deletions(-) create mode 100644 Mathlib/Algebra/Lie/Basis/Base.lean rename Mathlib/Algebra/Lie/{Basis.lean => Basis/Basic.lean} (80%) diff --git a/Mathlib.lean b/Mathlib.lean index e5265e463a28cb..d7206ddd4fff79 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -717,7 +717,8 @@ public import Mathlib.Algebra.Lie.AdjointAction.Derivation public import Mathlib.Algebra.Lie.AdjointAction.JordanChevalley public import Mathlib.Algebra.Lie.BaseChange public import Mathlib.Algebra.Lie.Basic -public import Mathlib.Algebra.Lie.Basis +public import Mathlib.Algebra.Lie.Basis.Base +public import Mathlib.Algebra.Lie.Basis.Basic public import Mathlib.Algebra.Lie.CartanCriterion public import Mathlib.Algebra.Lie.CartanExists public import Mathlib.Algebra.Lie.CartanSubalgebra diff --git a/Mathlib/Algebra/Lie/Basis/Base.lean b/Mathlib/Algebra/Lie/Basis/Base.lean new file mode 100644 index 00000000000000..7960cb04f2ec11 --- /dev/null +++ b/Mathlib/Algebra/Lie/Basis/Base.lean @@ -0,0 +1,124 @@ +/- +Copyright (c) 2026 Oliver Nash. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Oliver Nash +-/ +module + +public import Mathlib.Algebra.Lie.Basis.Basic +public import Mathlib.Algebra.Lie.Weights.RootSystem +public import Mathlib.LinearAlgebra.RootSystem.BaseExists +public import Mathlib.LinearAlgebra.RootSystem.CartanMatrix + +/-! + +# The root system base associated to a Lie algebra basis + +-/ + +@[expose] public section + +noncomputable section + +namespace LieAlgebra.Basis + +open AddSubmonoid Function IsKilling LieModule LieSubalgebra Matrix Set + +variable {ι K L : Type*} [Fintype ι] [Field K] [CharZero K] [LieRing L] [LieAlgebra K L] + [FiniteDimensional K L] {H : LieSubalgebra K L} (b : Basis ι H) + +/-- The elements `LieAlgebra.Basis.baseSupp` as roots in the sense of `LieSubalgebra.root`. -/ +def baseSupp' (i : ι) : + letI := b.isCartanSubalgebra + H.root := by + let := b.isCartanSubalgebra + refine ⟨⟨b.baseSupp i, ?_⟩, ?_⟩ + · simp only [LieSubmodule.eq_bot_iff, ne_eq, not_forall] + exact ⟨b.e i, (mem_genWeightSpace _ _ _).mpr fun x ↦ ⟨1, by simp⟩, (b.sl2 i).e_ne_zero⟩ + · simpa [Weight.IsNonZero, Weight.IsZero] using b.linearIndependent_baseSupp.ne_zero i + +@[simp] lemma coe_linearMap_baseSupp' (i : ι) : b.baseSupp' i = b.baseSupp i := rfl + +variable [IsTriangularizable K H L] [IsKilling K L] + +lemma linearIndepOn_root_baseSupp : + letI := b.isCartanSubalgebra + LinearIndepOn K (rootSystem H).root (range b.baseSupp') := by + let e : ι ≃ range b.baseSupp' := Equiv.ofInjective _ <| fun i j hij ↦ + b.linearIndependent_baseSupp.injective <| by simpa [baseSupp'] using hij + rw [LinearIndepOn, ← linearIndependent_equiv e] + exact b.linearIndependent_baseSupp + +lemma root_mem_or_mem_neg (χ : letI := b.isCartanSubalgebra; H.root) : + letI := b.isCartanSubalgebra + ( (rootSystem H).root χ ∈ closure ((rootSystem H).root '' range b.baseSupp') ∨ + -(rootSystem H).root χ ∈ closure ((rootSystem H).root '' range b.baseSupp')) := by + let := b.isCartanSubalgebra + have (n : ι → ℕ) : + ∑ i, n i • b.baseSupp i ∈ closure (⇑(rootSystem H).root '' range b.baseSupp') := by + simp_rw [← Submodule.span_nat_eq_addSubmonoidClosure, Submodule.mem_toAddSubmonoid] + exact Submodule.sum_smul_mem _ _ fun i _ ↦ Submodule.subset_span <| by simp + let s : Set (H → K) := {0} ∪ + {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = -∑ i, n i • b.baseSupp i} ∪ + {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • b.baseSupp i} + have hs : ⨆ α ∈ s, rootSpace H α = ⊤ := by + have := b.iSup_cartan_borelLower_borelUpper_eq_top + rw [borelLower_eq, borelUpper_eq, b.cartan_eq] at this + rw [iSup_union, iSup_union] + simpa [iSup_and, iSup_comm (ι := H → K)] using this + obtain ⟨χ, hχ⟩ := χ + change χ.toLinear ∈ _ ∨ -χ.toLinear ∈ _ + replace hs : ⇑χ ∈ s := + (iSupIndep_genWeightSpace K H L).mem_of_biSup_eq_top hs χ.genWeightSpace_ne_bot + replace hs : (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = -∑ i, n i • b.baseSupp i) ∨ + (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = ∑ i, n i • b.baseSupp i) := by + have hχ' : ¬ χ.IsZero := by simpa using hχ + simp only [hχ', s, singleton_union, mem_union, mem_insert_iff, Weight.coe_eq_zero_iff, + mem_ofPred_eq, false_or] at hs + simpa only [← LinearMap.coe_neg, ← Weight.coe_coe, LinearMap.coe_injective.eq_iff] using hs + refine hs.symm.imp (fun ⟨n, hn₀, hn⟩ ↦ ?_) (fun ⟨n, hn₀, hn⟩ ↦ ?_) <;> simpa [hn] using this n + +/-- The distinguished root system base associated to a basis. -/ +def base : + letI := b.isCartanSubalgebra + RootPairing.Base (rootSystem H) := + letI := b.isCartanSubalgebra + .mk' (rootSystem H) (range b.baseSupp') b.linearIndepOn_root_baseSupp b.root_mem_or_mem_neg + +/-- The support of `LieAlgebra.Basis.base` is in one-to-one correspondence with the indexing +set of the basis. -/ +def baseSupportEquiv : ι ≃ b.base.support := + have : Injective b.baseSupp' := + fun i j hij ↦ b.linearIndependent_baseSupp.injective <| by simpa [baseSupp'] using hij + (Equiv.ofInjective _ this).trans (Set.Finite.subtypeEquivToFinset _) + +@[simp] lemma coe_baseSupportEquiv_apply (i : ι) : b.baseSupportEquiv i = b.baseSupp i := rfl + +@[simp] lemma coroot_eq_h' (i : ι) : + letI := b.isCartanSubalgebra + coroot (b.baseSupportEquiv i) = b.h' i := by + let := b.isCartanSubalgebra + suffices b.h' i ∈ corootSpace (b.baseSupp' i) by + have _i : IsAddTorsionFree L := .of_isTorsionFree K L + exact (eq_coroot_of_mem_corootSpace_of_two (b.baseSupp' i).val this (by simp [baseSupp'])).symm + have h_mem : ⁅b.e i, b.f i⁆ ∈ H := by + nth_rw 1 [(b.sl2 i).lie_e_f, b.cartan_eq_lieSpan] + exact subset_lieSpan <| mem_range_self i + have h_eq : b.h' i = ⟨⁅b.e i, b.f i⁆, h_mem⟩ := by simp [(b.sl2 i).lie_e_f, h'] + rw [h_eq] + have he : b.e i ∈ rootSpace H (b.baseSupp i) := + (mem_genWeightSpace _ _ _).mpr fun ⟨z, hz⟩ ↦ ⟨1, by simp⟩ + have hf : b.f i ∈ rootSpace H (-b.baseSupp i) := + (mem_genWeightSpace _ _ _).mpr fun ⟨z, hz⟩ ↦ ⟨1, by simp [← eq_neg_iff_add_eq_zero]⟩ + exact (mem_corootSpace _).mpr <| Submodule.subset_span ⟨b.e i, he, b.f i, hf, rfl⟩ + +lemma cartanMatrix_base_eq : + b.base.cartanMatrix = b.A.reindex b.baseSupportEquiv b.baseSupportEquiv := by + suffices b.base.cartanMatrix.reindex b.baseSupportEquiv.symm b.baseSupportEquiv.symm = b.A by + rwa [← (reindex b.baseSupportEquiv b.baseSupportEquiv).symm_apply_eq] + ext i j + apply FaithfulSMul.algebraMap_injective ℤ K + rw [reindex_apply, submatrix_apply, RootPairing.Base.algebraMap_cartanMatrixIn_apply] + simp [← Weight.coe_coe] + +end LieAlgebra.Basis diff --git a/Mathlib/Algebra/Lie/Basis.lean b/Mathlib/Algebra/Lie/Basis/Basic.lean similarity index 80% rename from Mathlib/Algebra/Lie/Basis.lean rename to Mathlib/Algebra/Lie/Basis/Basic.lean index d4eb96ec95f310..a9c18c8033098a 100644 --- a/Mathlib/Algebra/Lie/Basis.lean +++ b/Mathlib/Algebra/Lie/Basis/Basic.lean @@ -5,10 +5,7 @@ Authors: Oliver Nash -/ module -public import Mathlib.Algebra.Lie.Killing -public import Mathlib.Algebra.Lie.Weights.RootSystem -public import Mathlib.LinearAlgebra.RootSystem.BaseExists -public import Mathlib.LinearAlgebra.RootSystem.CartanMatrix +public import Mathlib.Algebra.Lie.Weights.Killing /-! # Bases of semisimple Lie algebras @@ -64,7 +61,7 @@ structure Basis (ι : Type*) {R L : Type*} [Finite ι] [CommRing R] [LieRing L] cartan_eq_lieSpan : H = lieSpan R L (range h) span_ef : lieSpan R L (range e ∪ range f) = ⊤ linInd : LinearIndependent R h - nondegen : A.Nondegenerate + nondegen : A.Nondegenerate -- TODO Replace with `(b.A.det : R) ≠ 0` to support positive char sl2 (i : ι) : IsSl2Triple (h i) (e i) (f i) lie_h_h (i j : ι) : ⁅h i, h j⁆ = 0 lie_h_e (i j : ι) : ⁅h j, e i⁆ = A i j • e i @@ -497,105 +494,6 @@ lemma isCartanSubalgebra [IsNoetherian R L] : H.IsCartanSubalgebra := by end CommRing -open AddSubmonoid IsKilling LieModule Matrix - -variable {ι K L : Type*} [Fintype ι] [Field K] [CharZero K] [LieRing L] [LieAlgebra K L] - [FiniteDimensional K L] {H : LieSubalgebra K L} (b : Basis ι H) - -/-- The elements `LieAlgebra.Basis.baseSupp` as roots in the sense of `LieSubalgebra.root`. -/ -def baseSupp' (i : ι) : - letI := b.isCartanSubalgebra - H.root := by - let := b.isCartanSubalgebra - refine ⟨⟨b.baseSupp i, ?_⟩, ?_⟩ - · simp only [LieSubmodule.eq_bot_iff, ne_eq, not_forall] - exact ⟨b.e i, (mem_genWeightSpace _ _ _).mpr fun x ↦ ⟨1, by simp⟩, (b.sl2 i).e_ne_zero⟩ - · simpa [Weight.IsNonZero, Weight.IsZero] using b.linearIndependent_baseSupp.ne_zero i - -@[simp] lemma coe_linearMap_baseSupp' (i : ι) : b.baseSupp' i = b.baseSupp i := rfl - -variable [IsTriangularizable K H L] [IsKilling K L] - -lemma linearIndepOn_root_baseSupp : - letI := b.isCartanSubalgebra - LinearIndepOn K (rootSystem H).root (range b.baseSupp') := by - let e : ι ≃ range b.baseSupp' := Equiv.ofInjective _ <| fun i j hij ↦ - b.linearIndependent_baseSupp.injective <| by simpa [baseSupp'] using hij - rw [LinearIndepOn, ← linearIndependent_equiv e] - exact b.linearIndependent_baseSupp - -lemma root_mem_or_mem_neg (χ : letI := b.isCartanSubalgebra; H.root) : - letI := b.isCartanSubalgebra - ( (rootSystem H).root χ ∈ closure ((rootSystem H).root '' range b.baseSupp') ∨ - -(rootSystem H).root χ ∈ closure ((rootSystem H).root '' range b.baseSupp')) := by - let := b.isCartanSubalgebra - have (n : ι → ℕ) : - ∑ i, n i • b.baseSupp i ∈ closure (⇑(rootSystem H).root '' range b.baseSupp') := by - simp_rw [← Submodule.span_nat_eq_addSubmonoidClosure, Submodule.mem_toAddSubmonoid] - exact Submodule.sum_smul_mem _ _ fun i _ ↦ Submodule.subset_span <| by simp - let s : Set (H → K) := {0} ∪ - {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = -∑ i, n i • b.baseSupp i} ∪ - {f | ∃ n : ι → ℕ, n ≠ 0 ∧ f = ∑ i, n i • b.baseSupp i} - have hs : ⨆ α ∈ s, rootSpace H α = ⊤ := by - have := b.iSup_cartan_borelLower_borelUpper_eq_top - rw [borelLower_eq, borelUpper_eq, b.cartan_eq] at this - rw [iSup_union, iSup_union] - simpa [iSup_and, iSup_comm (ι := H → K)] using this - obtain ⟨χ, hχ⟩ := χ - change χ.toLinear ∈ _ ∨ -χ.toLinear ∈ _ - replace hs : ⇑χ ∈ s := - (iSupIndep_genWeightSpace K H L).mem_of_biSup_eq_top hs χ.genWeightSpace_ne_bot - replace hs : (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = -∑ i, n i • b.baseSupp i) ∨ - (∃ n : ι → ℕ, n ≠ 0 ∧ χ.toLinear = ∑ i, n i • b.baseSupp i) := by - have hχ' : ¬ χ.IsZero := by simpa using hχ - simp only [hχ', s, singleton_union, mem_union, mem_insert_iff, Weight.coe_eq_zero_iff, - mem_ofPred_eq, false_or] at hs - simpa only [← LinearMap.coe_neg, ← Weight.coe_coe, LinearMap.coe_injective.eq_iff] using hs - refine hs.symm.imp (fun ⟨n, hn₀, hn⟩ ↦ ?_) (fun ⟨n, hn₀, hn⟩ ↦ ?_) <;> simpa [hn] using this n - -/-- The distinguished root system base associated to a basis. -/ -def base : - letI := b.isCartanSubalgebra - RootPairing.Base (rootSystem H) := - letI := b.isCartanSubalgebra - .mk' (rootSystem H) (range b.baseSupp') b.linearIndepOn_root_baseSupp b.root_mem_or_mem_neg - -/-- The support of `LieAlgebra.Basis.base` is in one-to-one correspondence with the indexing -set of the basis. -/ -def baseSupportEquiv : ι ≃ b.base.support := - have : Injective b.baseSupp' := - fun i j hij ↦ b.linearIndependent_baseSupp.injective <| by simpa [baseSupp'] using hij - (Equiv.ofInjective _ this).trans (Set.Finite.subtypeEquivToFinset _) - -@[simp] lemma coe_baseSupportEquiv_apply (i : ι) : b.baseSupportEquiv i = b.baseSupp i := rfl - -@[simp] lemma coroot_eq_h' (i : ι) : - letI := b.isCartanSubalgebra - coroot (b.baseSupportEquiv i) = b.h' i := by - let := b.isCartanSubalgebra - suffices b.h' i ∈ corootSpace (b.baseSupp' i) by - have _i : IsAddTorsionFree L := .of_isTorsionFree K L - exact (eq_coroot_of_mem_corootSpace_of_two (b.baseSupp' i).val this (by simp [baseSupp'])).symm - have h_mem : ⁅b.e i, b.f i⁆ ∈ H := by - nth_rw 1 [(b.sl2 i).lie_e_f, b.cartan_eq_lieSpan] - exact subset_lieSpan <| mem_range_self i - have h_eq : b.h' i = ⟨⁅b.e i, b.f i⁆, h_mem⟩ := by simp [(b.sl2 i).lie_e_f, h'] - rw [h_eq] - have he : b.e i ∈ rootSpace H (b.baseSupp i) := - (mem_genWeightSpace _ _ _).mpr fun ⟨z, hz⟩ ↦ ⟨1, by simp⟩ - have hf : b.f i ∈ rootSpace H (-b.baseSupp i) := - (mem_genWeightSpace _ _ _).mpr fun ⟨z, hz⟩ ↦ ⟨1, by simp [← eq_neg_iff_add_eq_zero]⟩ - exact (mem_corootSpace _).mpr <| Submodule.subset_span ⟨b.e i, he, b.f i, hf, rfl⟩ - -lemma cartanMatrix_base_eq : - b.base.cartanMatrix = b.A.reindex b.baseSupportEquiv b.baseSupportEquiv := by - suffices b.base.cartanMatrix.reindex b.baseSupportEquiv.symm b.baseSupportEquiv.symm = b.A by - rwa [← (reindex b.baseSupportEquiv b.baseSupportEquiv).symm_apply_eq] - ext i j - apply FaithfulSMul.algebraMap_injective ℤ K - rw [reindex_apply, submatrix_apply, RootPairing.Base.algebraMap_cartanMatrixIn_apply] - simp [← Weight.coe_coe] - end Basis end LieAlgebra diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean index 4f2175b34bcff9..9fc6edca4deb56 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basis.lean @@ -5,7 +5,7 @@ Authors: Oliver Nash -/ module -public import Mathlib.Algebra.Lie.Basis +public import Mathlib.Algebra.Lie.Basis.Base public import Mathlib.Algebra.Lie.CartanCriterion public import Mathlib.LinearAlgebra.RootSystem.GeckConstruction.Semisimple public import Mathlib.LinearAlgebra.RootSystem.GeckConstruction.Relations From 69ac67288807cdc1d809a91e1f9c6a520c423bbb Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:55:51 +0000 Subject: [PATCH 0956/1300] chore: add deprecation for file move `Mathlib.Algebra.Lie.Basis` (#42004) --- Mathlib.lean | 1 + Mathlib/Algebra/Lie/Basis.lean | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 Mathlib/Algebra/Lie/Basis.lean diff --git a/Mathlib.lean b/Mathlib.lean index d7206ddd4fff79..8e6ed43550d3d8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -717,6 +717,7 @@ public import Mathlib.Algebra.Lie.AdjointAction.Derivation public import Mathlib.Algebra.Lie.AdjointAction.JordanChevalley public import Mathlib.Algebra.Lie.BaseChange public import Mathlib.Algebra.Lie.Basic +public import Mathlib.Algebra.Lie.Basis public import Mathlib.Algebra.Lie.Basis.Base public import Mathlib.Algebra.Lie.Basis.Basic public import Mathlib.Algebra.Lie.CartanCriterion diff --git a/Mathlib/Algebra/Lie/Basis.lean b/Mathlib/Algebra/Lie/Basis.lean new file mode 100644 index 00000000000000..c343ff52f1c3af --- /dev/null +++ b/Mathlib/Algebra/Lie/Basis.lean @@ -0,0 +1,10 @@ +/- +Copyright (c) 2026 Oliver Nash. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Oliver Nash +-/ +module -- shake: keep-all + +public import Mathlib.Algebra.Lie.Basis.Base + +deprecated_module (since := "2026-07-21") From 713a1f62a8c880cf66692d93e0bc3b2bf416d082 Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Wed, 22 Jul 2026 18:34:50 +0000 Subject: [PATCH 0957/1300] ci: publish the cache for off-master release tags (#42009) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch releases (`v4.X.Y`, Y ≥ 1) and patched release candidates (e.g. `v4.32.0-rc1-patch1`) live on `bump_to_*` branches that are not ancestors of `master`, but we want their artifacts to land on the master cache once they are published. Trust: creating `v4.*` tags is ruleset-restricted to release managers, so the tag push is already protected. The `cache-upload-master` environment's deployment policy (already updated) admits only `master`, `staging`, and `v4.*` tag refs. The workflow file that runs is the one at the tagged commit, so the whole stack is the tag's own tree (no version skew); tags from older lineages never trigger it, and coverage starts with the first `.0` release tagged after this lands. --- .../actions/cache-trust-dispatch/action.yml | 84 +++++++++----- .github/workflows/build_template.yml | 3 +- .github/workflows/release_cache.yml | 103 ++++++++++++++++++ Cache/SECURITY.md | 6 +- 4 files changed, 166 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/release_cache.yml diff --git a/.github/actions/cache-trust-dispatch/action.yml b/.github/actions/cache-trust-dispatch/action.yml index 3cb8f2f785ced0..ebe78e1dcae772 100644 --- a/.github/actions/cache-trust-dispatch/action.yml +++ b/.github/actions/cache-trust-dispatch/action.yml @@ -1,4 +1,4 @@ -# Single source of truth mapping (repo, branch) → (upload container, +# Single source of truth mapping (repo, ref) → (upload container, # read fallback chain) for Mathlib's multi-container cache. # # Called by build, upload_cache, and post_steps in build_template.yml so @@ -14,7 +14,10 @@ inputs: description: GitHub repo full name (`owner/name`). required: true branch: - description: Branch name (`github.head_ref || github.ref_name`). + description: | + Branch name (`github.head_ref || github.ref_name`); on tag-triggered + runs this is the tag name, distinguished via `github.ref_type` inside + the dispatch step. required: true head-sha: description: | @@ -55,6 +58,10 @@ runs: REPO="${{ inputs.repo }}" BRANCH="${{ inputs.branch }}" HEAD_SHA="${{ inputs.head-sha }}" + # Whether `branch` names a branch or a tag. Read from the run context + # rather than an input: unlike `repo`/`branch`, the value does not + # depend on which event shape (PR vs push) the caller handles. + REF_TYPE="${{ github.ref_type }}" PRIMARY="" READ_CHAIN="" REPO_SCOPE="" @@ -80,30 +87,55 @@ runs: else case "$REPO" in "leanprover-community/mathlib4") - case "$BRANCH" in - "master"|"staging") - # Master / staging are the only writers that feed `master` - # (`staging` is bors's merge candidate, which fast-forwards to - # `master`). Read `master` only, not the default [master, - # legacy]: files the read chain serves are skipped at stage - # time, so keeping `legacy` would leave legacy-only files out of - # `master` for good. Reading `master` alone turns them into - # misses that get rebuilt and uploaded, so `master` fills itself - # into a standalone cache. (Only PRIMARY=master does this; other - # runs write to `forks` and keep the wider chain.) - PRIMARY="master" - READ_CHAIN="master" - ;; - *) - # `bors trying`, `ci-dev/*`, maintainer dev branches on the - # canonical repo: trust level is fork-equivalent (the OIDC - # token's RBAC scopes them to `forks`). Reads must widen - # past the default [master, legacy] so the post-build - # verification finds the just-uploaded fork-trust artifacts. - PRIMARY="forks" - READ_CHAIN="master,forks,legacy" - ;; - esac + if [ "$REF_TYPE" = "tag" ]; then + case "$BRANCH" in + v4.*) + # `v4.*` release tags: release_cache.yml rebuilds off-master + # release commits (patch releases, patched release + # candidates) and publishes them into `master`, the container + # canonical checkouts read. Tag creation is restricted to + # release managers by a tag ruleset, and the + # `cache-upload-master` environment admits `v4.*` tag refs, + # so these builds carry master trust. Reads are `master`-only + # for the same fill-in reason as the master/staging arm + # below. + PRIMARY="master" + READ_CHAIN="master" + ;; + *) + # Other tags have no trust class of their own: + # fork-equivalent, like the dev-branch arm below. + PRIMARY="forks" + READ_CHAIN="master,forks,legacy" + ;; + esac + else + case "$BRANCH" in + "master"|"staging") + # Master, staging, and `v4.*` release tags (above) are the + # only writers that feed `master` (`staging` is bors's merge + # candidate, which fast-forwards to `master`). Read `master` + # only, not the default [master, legacy]: files the read + # chain serves are skipped at stage time, so keeping `legacy` + # would leave legacy-only files out of `master` for good. + # Reading `master` alone turns them into misses that get + # rebuilt and uploaded, so `master` fills itself into a + # standalone cache. (Only PRIMARY=master does this; other + # runs write to `forks` and keep the wider chain.) + PRIMARY="master" + READ_CHAIN="master" + ;; + *) + # `bors trying`, `ci-dev/*`, maintainer dev branches on the + # canonical repo: trust level is fork-equivalent (the OIDC + # token's RBAC scopes them to `forks`). Reads must widen + # past the default [master, legacy] so the post-build + # verification finds the just-uploaded fork-trust artifacts. + PRIMARY="forks" + READ_CHAIN="master,forks,legacy" + ;; + esac + fi ;; "leanprover-community/mathlib4-nightly-testing") case "$BRANCH" in diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 8fbaa837db97fe..51a6dde611dac2 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -1,4 +1,5 @@ -# Reusable workflow invoked by build.yml, bors.yml, build_fork.yml, and ci_dev.yml. +# Reusable workflow invoked by build.yml, bors.yml, build_fork.yml, ci_dev.yml, +# and release_cache.yml. on: workflow_call: diff --git a/.github/workflows/release_cache.yml b/.github/workflows/release_cache.yml new file mode 100644 index 00000000000000..242874105ab702 --- /dev/null +++ b/.github/workflows/release_cache.yml @@ -0,0 +1,103 @@ +name: publish release cache + +# Publishes the Mathlib cache for release tags whose commits are not on +# `master`. +# +# Patch releases (`v4.X.Y` with Y ≥ 1) and patched release candidates (e.g. +# `v4.32.0-rc1-patch1`) are committed on `bump_to_*` branches that never merge +# back into `master`, so the master push build never caches them; their branch +# CI writes only the fork-trust container, which a canonical checkout at the +# tag never reads. This workflow rebuilds the tagged commit and publishes the +# result to the `master` container, where every consumer finds it. Tags that +# point at commits on `master` (plain release candidates and `.0` releases) +# are already cached by the master push build, so the gate job skips them. +# +# Trust model: +# - Creating a `v4.*` tag is restricted to release managers by a tag +# ruleset, so a tag push is a deliberate release-manager action — and the +# tagged tree is what runs here, including this workflow file. Tags cut +# from lineages predating this file simply never trigger it. +# - The upload job mints its OIDC token under the `cache-upload-master` +# environment (inside build_template.yml); the environment's deployment +# policy admits only `master`, `staging`, and `v4.*` tag refs. +# +# Retry: a spuriously failed run can simply be re-run ("Re-run failed jobs" / +# `gh run rerun`) — same tag, same tree, no tag re-push involved. The +# `workflow_dispatch` trigger covers what re-run cannot: a tag push that never +# produced a run, or a re-run window that has expired. Dispatch it AT the tag +# ref (`gh workflow run release_cache.yml --ref v4.X.Y`); the run then executes +# the tag's own tree exactly as a tag push would. + +on: + push: + tags: + - 'v4.*' + # Manual fallback; see the retry note above. The `tags` filter does not + # apply to dispatches — the gate job's ref guards enforce it instead, so a + # dispatch on a branch ref skips cleanly. + workflow_dispatch: + +# `v4.*` tags are immutable (the tag ruleset blocks updates), so this group +# only ever collides on re-runs of the same tag; keep those queued rather +# than cancelled. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + +# Read-only by default; the build job elevates for itself only. +permissions: + contents: read + +jobs: + gate: + name: skip tags already on master + # The ref guards double as the dispatch-path filter; on the push path the + # `tags` trigger filter has already enforced them. + if: ${{ github.repository == 'leanprover-community/mathlib4' && github.ref_type == 'tag' && startsWith(github.ref_name, 'v4.') }} + runs-on: ubuntu-latest + outputs: + off_master: ${{ steps.check.outputs.off_master }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + # `merge-base` needs history, so fetch all of it. + fetch-depth: 0 + + - name: check whether the tagged commit is on master + id: check + run: | + if git merge-base --is-ancestor "$GITHUB_SHA" origin/master; then + echo "Tag $GITHUB_REF_NAME points at a commit on master; the master push build covers its cache." + echo "off_master=false" >> "$GITHUB_OUTPUT" + else + echo "Tag $GITHUB_REF_NAME is not on master; rebuilding it to publish its cache." + echo "off_master=true" >> "$GITHUB_OUTPUT" + fi + + build: + name: ci + needs: gate + if: ${{ needs.gate.outputs.off_master == 'true' }} + # What build_template.yml needs, granted to this job only — the same set + # build.yml grants it on push events. In particular, the OIDC token for + # the cache upload can be minted here and nowhere else in this workflow. + permissions: + contents: read + id-token: write + actions: read # Allow get-tools to download the prebuilt tools artifact from master's publish_tools runs + pull-requests: write # Only allow PR comments/labels + uses: ./.github/workflows/build_template.yml + with: + concurrency_group: ${{ github.workflow }}-${{ github.ref }} + pr_branch_ref: ${{ github.sha }} + # Release tags publish to the `master` container under the master writer + # identity; see the trust note above and cache-trust-dispatch, which + # routes `v4.*` tag refs to that container. + cache_application_id: ${{ vars.CACHE_MASTER_WRITER_AZURE_APP_ID }} + cache_environment: cache-upload-master + # The cache-snapshot warming artifact exists to seed master and PR + # builds, which a release tag's snapshot cannot do. + publish_cache: false + # Skip the Post-CI job: it grooms PR labels, and a tag run has no PR. + run_post_ci: false + runs_on: pr + secrets: inherit diff --git a/Cache/SECURITY.md b/Cache/SECURITY.md index 0c93d31772981e..0e6dc59988a3c7 100644 --- a/Cache/SECURITY.md +++ b/Cache/SECURITY.md @@ -21,7 +21,7 @@ CI job and assigned a trust level: | Container | Who may write | Trust | |-----------------------|--------------------------------------------------------|--------| -| `master` | mathlib4 `master`/`staging` | high | +| `master` | mathlib4 `master`/`staging`, `v4.*` release tags | high | | `forks` | mathlib4 PR builds, non-master branches, `bors try` | medium | | `nightly-testing` | nightly-testing's trusted branches | medium | | `pr-toolchain-tests` | nightly-testing's experimental toolchain branches | low | @@ -148,5 +148,5 @@ The trust model does not attempt to defend against: | Trust property tests | [`Cache/Test.lean`](Test.lean) | | User-facing CLI surface, env vars | [`Cache/Main.lean`](Main.lean), [`Cache/README.md`](README.md) | | OIDC mint + per-job dispatch | [`.github/workflows/build_template.yml`](../.github/workflows/build_template.yml) (`upload_cache` job) | -| (repo, branch) → trust class policy table | [`.github/actions/cache-trust-dispatch/action.yml`](../.github/actions/cache-trust-dispatch/action.yml) | -| Caller `cache_application_id` ternaries | [`.github/workflows/build.yml`](../.github/workflows/build.yml), [`bors.yml`](../.github/workflows/bors.yml), [`build_fork.yml`](../.github/workflows/build_fork.yml), [`ci_dev.yml`](../.github/workflows/ci_dev.yml) | +| (repo, ref) → trust class policy table | [`.github/actions/cache-trust-dispatch/action.yml`](../.github/actions/cache-trust-dispatch/action.yml) | +| Caller `cache_application_id` wiring | [`.github/workflows/build.yml`](../.github/workflows/build.yml), [`bors.yml`](../.github/workflows/bors.yml), [`build_fork.yml`](../.github/workflows/build_fork.yml), [`ci_dev.yml`](../.github/workflows/ci_dev.yml), [`release_cache.yml`](../.github/workflows/release_cache.yml) | From 17b4b96c4eb874624e9cab005e966a25fd68ab14 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:44:14 +0000 Subject: [PATCH 0958/1300] chore(Geometry/Manifold/MFDeriv/Atlas): remove backcompat option (#41843) The defeq abuse just needs a simple rewrite to fix. --- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index e20cd71759467d..cb00db35fa0bf9 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -309,7 +309,6 @@ lemma mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt simp only [Function.comp_def, PartialEquiv.left_inv (extChartAt I x) hz, id_eq] · simp only [Function.comp_def, PartialEquiv.right_inv (extChartAt I x) hy, id_eq] -set_option backward.isDefEq.respectTransparency false in /-- The composition of the derivative of the inverse of `extChartAt` with the derivative of `extChartAt` gives the identity. Version where the basepoint belongs to `(extChartAt I x).source`. -/ @@ -319,6 +318,7 @@ lemma mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' = ContinuousLinearMap.id _ _ := by have : y = (extChartAt I x).symm (extChartAt I x y) := ((extChartAt I x).left_inv hy).symm convert! mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt ((extChartAt I x).map_source hy) + rw [(extChartAt I x).left_inv (by simpa using hy)] lemma isInvertible_mfderivWithin_extChartAt_symm {y : E} (hy : y ∈ (extChartAt I x).target) : (mfderiv[range I] (extChartAt I x).symm y).IsInvertible := From ef7aa707423d6835bc485b7c128842c0ebe0e5f4 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Wed, 22 Jul 2026 19:14:53 +0000 Subject: [PATCH 0959/1300] feat(EllipticCurve/Affine/Point): easy instances (#41264) --- Mathlib/Algebra/Group/Action/Faithful.lean | 3 +++ .../AlgebraicGeometry/EllipticCurve/Affine/Point.lean | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/Mathlib/Algebra/Group/Action/Faithful.lean b/Mathlib/Algebra/Group/Action/Faithful.lean index a47408126fa473..bb73aa1a73b64f 100644 --- a/Mathlib/Algebra/Group/Action/Faithful.lean +++ b/Mathlib/Algebra/Group/Action/Faithful.lean @@ -51,6 +51,9 @@ class FaithfulSMul (M : Type*) (α : Type*) [SMul M α] : Prop where export FaithfulSMul (eq_of_smul_eq_smul) export FaithfulVAdd (eq_of_vadd_eq_vadd) +@[to_additive] instance (priority := low) [SMul M α] [Subsingleton M] : FaithfulSMul M α := + ⟨fun _ ↦ Subsingleton.elim ..⟩ + @[to_additive] lemma smul_left_injective' [SMul M α] [FaithfulSMul M α] : Injective ((· • ·) : M → α → α) := fun _ _ h ↦ FaithfulSMul.eq_of_smul_eq_smul (congr_fun h) diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean index d9f1b1fde1b2ea..3c2431076352ca 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean @@ -139,6 +139,17 @@ lemma coe_basis : (CoordinateRing.basis W' : Fin 2 → W'.CoordinateRing) = ![1, fin_cases n exacts [basis_zero, basis_one] +instance : Module.Free R[X] W'.CoordinateRing := .of_basis (CoordinateRing.basis W') + +instance : Module.Free R W'.CoordinateRing := .trans (S := R[X]) + +instance [Nontrivial R] : Nontrivial W'.CoordinateRing := + ⟨_, _, (CoordinateRing.basis W').ne_zero 0⟩ + +instance : FaithfulSMul R[X] W'.CoordinateRing := by nontriviality R; infer_instance + +instance : FaithfulSMul R W'.CoordinateRing := .trans R R[X] _ + lemma smul (x : R[X]) (y : W'.CoordinateRing) : x • y = mk W' (C x) * y := (algebraMap_smul W'.CoordinateRing x y).symm From b1de3b7b0763def682d9f6f6877eb395629cce45 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 22 Jul 2026 20:04:21 +0000 Subject: [PATCH 0960/1300] perf(Positivity): filter with `isProp` in `compareHyp` (#42014) This PR adds a check in the assumption procedure of `positivity` so that it only considers hypotheses that are propositions (and not data). --- Mathlib/Tactic/Positivity/Core.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Tactic/Positivity/Core.lean b/Mathlib/Tactic/Positivity/Core.lean index b69cd0624625f5..7966f979454fa4 100644 --- a/Mathlib/Tactic/Positivity/Core.lean +++ b/Mathlib/Tactic/Positivity/Core.lean @@ -351,6 +351,7 @@ initialize registerTraceClass `Tactic.positivity.failure where `a` is a numeral. -/ def compareHyp (pα : Q(PartialOrder $α)) (e : Q($α)) (ldecl : LocalDecl) : MetaM (Strictness zα e pα) := do + unless ← isProp ldecl.type do return .none have e' : Q(Prop) := ldecl.type let p : Q($e') := .fvar ldecl.fvarId match e' with @@ -396,6 +397,7 @@ def compareHyp (pα : Q(PartialOrder $α)) (e : Q($α)) (ldecl : LocalDecl) : /-- A variation on `assumption` when the hypothesis is `e ≠ 0` or `0 ≠ e`. -/ def compareHypNonzero {pα?} (e : Q($α)) (ldecl : LocalDecl) : MetaM (Strictness zα e pα?) := do + unless ← isProp ldecl.type do return .none have e' : Q(Prop) := ldecl.type let p : Q($e') := .fvar ldecl.fvarId match e' with From 7779d601f7103882175b3125539d5d1232911f5e Mon Sep 17 00:00:00 2001 From: "Louis (Yiyang) Liu" Date: Wed, 22 Jul 2026 21:01:31 +0000 Subject: [PATCH 0961/1300] feat(Analysis/SpecialFunctions/ImproperIntegrals): Frullani integral (#34815) - [x] depends on: #34966 Co-authored-by: Deep0Thinking Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Louis Liu --- Mathlib.lean | 1 + .../SpecialFunctions/FrullaniIntegral.lean | 236 ++++++++++++++++++ .../SpecialFunctions/ImproperIntegrals.lean | 3 +- 3 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8e6ed43550d3d8..4325c25d6e8eff 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2357,6 +2357,7 @@ public import Mathlib.Analysis.SpecialFunctions.Elliptic.Weierstrass public import Mathlib.Analysis.SpecialFunctions.Exp public import Mathlib.Analysis.SpecialFunctions.ExpDeriv public import Mathlib.Analysis.SpecialFunctions.Exponential +public import Mathlib.Analysis.SpecialFunctions.FrullaniIntegral public import Mathlib.Analysis.SpecialFunctions.Gamma.Basic public import Mathlib.Analysis.SpecialFunctions.Gamma.Beta public import Mathlib.Analysis.SpecialFunctions.Gamma.BohrMollerup diff --git a/Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean b/Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean new file mode 100644 index 00000000000000..2b4d285183a8d4 --- /dev/null +++ b/Mathlib/Analysis/SpecialFunctions/FrullaniIntegral.lean @@ -0,0 +1,236 @@ +/- +Copyright (c) 2026 Louis (Yiyang) Liu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Louis (Yiyang) Liu +-/ +module + +public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic +public import Mathlib.MeasureTheory.Integral.IntegralEqImproper + +/-! +# Frullani's integral + +This file proves **Frullani's integral**: if `f : ℝ → E` is locally integrable on `(0, ∞)` with +`f x → L` as `x → 0⁺` and `f x → R` as `x → +∞`, and `0 < a` and `0 < b`, then +`∫ x in Ioi 0, x⁻¹ • (f (a * x) - f (b * x)) = log (b / a) • (L - R)` +(`Frullani.integral_Ioi_eq`), provided the integrand is integrable on `(0, ∞)`. + +We also prove a limit form `Frullani.tendsto_intervalIntegral`, which does not require global +integrability of the integrand. +-/ + +public section + +open Real Set Filter MeasureTheory intervalIntegral Topology Metric + +namespace Frullani + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {f : ℝ → E} + {a b c : ℝ} {L R : E} + +lemma intervalIntegrable_inv_smul (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) + (hb : 0 < b) : IntervalIntegrable (fun x ↦ x⁻¹ • f x) volume a b := by + have hsub : uIcc a b ⊆ Ioi 0 := by simp [uIcc, Icc_subset_Ioi_iff, ha, hb] + have hf_int : IntervalIntegrable f volume a b := + intervalIntegrable_iff.mpr + ((hf.integrableOn_compact_subset hsub isCompact_uIcc).mono_set uIoc_subset_uIcc) + exact hf_int.continuousOn_smul (continuousOn_inv₀.mono fun x hx ↦ ne_of_gt (hsub hx)) + +lemma intervalIntegrable_inv_smul_comp_mul (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) + (hb : 0 < b) (hc : 0 < c) : + IntervalIntegrable (fun x ↦ x⁻¹ • f (c * x)) volume a b := by + have hsub : uIcc a b ⊆ Ioi 0 := by simp [uIcc, Icc_subset_Ioi_iff, ha, hb] + have hf_cint : IntervalIntegrable f volume (c * a) (c * b) := + intervalIntegrable_iff.mpr + ((hf.integrableOn_compact_subset (by simp [uIcc, Icc_subset_Ioi_iff, mul_pos hc ha, + mul_pos hc hb]) isCompact_uIcc).mono_set uIoc_subset_uIcc) + have hf_comp : IntervalIntegrable (fun x ↦ f (c * x)) volume a b := by + have h := hf_cint.comp_mul_left (c := c) + rwa [mul_div_cancel_left₀ a hc.ne', mul_div_cancel_left₀ b hc.ne'] at h + exact hf_comp.continuousOn_smul (continuousOn_inv₀.mono fun x hx ↦ ne_of_gt (hsub hx)) + +lemma integral_comp_mul_inv_smul {ε r : ℝ} (hc : c ≠ 0) : + ∫ x in ε..r, x⁻¹ • f (c * x) = ∫ x in c * ε..c * r, x⁻¹ • f x := by + let u : ℝ → E := fun x ↦ x⁻¹ • f x + have key : (fun x ↦ x⁻¹ • f (c * x)) = fun x ↦ c • u (c * x) := by + funext x + simp only [u, smul_smul] + congr 1 + field_simp + rw [key, intervalIntegral.integral_smul, smul_integral_comp_mul_left] + +variable [CompleteSpace E] + +lemma norm_integral_inv_smul_sub_le (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) + (hb : 0 < b) {V : E} {δ : ℝ} (hδ : 0 ≤ δ) (h : ∀ x ∈ uIoc a b, ‖f x - V‖ ≤ δ) : + ‖(∫ x in a..b, x⁻¹ • f x) - log (b / a) • V‖ ≤ δ * |log (b / a)| := by + have hsub : uIcc a b ⊆ Ioi 0 := by simp [uIcc, Icc_subset_Ioi_iff, ha, hb] + have hint_f : IntervalIntegrable (fun x ↦ x⁻¹ • f x) volume a b := + intervalIntegrable_inv_smul hf ha hb + have hint_V : IntervalIntegrable (fun x ↦ x⁻¹ • V) volume a b := by + apply ContinuousOn.intervalIntegrable + exact (continuousOn_inv₀.mono (fun x hx ↦ ne_of_gt (hsub hx))).smul continuousOn_const + have hint_inv : IntervalIntegrable (fun x : ℝ ↦ x⁻¹ * δ) volume a b := by + apply ContinuousOn.intervalIntegrable + exact (continuousOn_inv₀.mono (fun x hx ↦ ne_of_gt (hsub hx))).mul continuousOn_const + calc ‖(∫ x in a..b, x⁻¹ • f x) - log (b / a) • V‖ + _ = ‖∫ x in a..b, x⁻¹ • (f x - V)‖ := by + congr 1 + have : log (b / a) • V = ∫ x in a..b, x⁻¹ • V := by + rw [intervalIntegral.integral_smul_const (f := fun x ↦ (x⁻¹ : ℝ)) (c := V), + integral_inv_of_pos ha hb] + rw [this, ← integral_sub hint_f hint_V] + congr 1 + funext x + exact (smul_sub _ _ _).symm + _ ≤ |∫ x in a..b, x⁻¹ * δ| := by + apply norm_integral_le_abs_of_norm_le + · exact (ae_restrict_mem measurableSet_uIoc).mono fun x hx ↦ by + have hx_pos : 0 < x := + lt_of_lt_of_le (lt_min ha hb) (uIoc_subset_uIcc hx).1 + rw [norm_smul, Real.norm_eq_abs, abs_of_pos (inv_pos.2 hx_pos)] + exact mul_le_mul_of_nonneg_left (h x hx) (inv_nonneg.2 hx_pos.le) + · exact hint_inv + _ = δ * |log (b / a)| := by + simp_rw [mul_comm, intervalIntegral.integral_const_mul, integral_inv_of_pos ha hb] + exact (abs_mul δ (log (b / a))).trans (by rw [abs_of_nonneg hδ]) + +lemma tendsto_integral_inv_smul_of_tendsto_uniform (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) + (hb : 0 < b) {F : Filter ℝ} (hpos : ∀ᶠ t in F, 0 < t) {V : E} + (huni : ∀ δ > 0, ∀ᶠ t in F, ∀ x ∈ uIoc (a * t) (b * t), ‖f x - V‖ ≤ δ) : + Tendsto (fun t ↦ ∫ x in (a * t)..(b * t), x⁻¹ • f x) F (𝓝 (log (b / a) • V)) := by + rw [Metric.tendsto_nhds] + intro δ hδ + set C := |log (b / a)| with hC_def + set δ' := δ / (C + 1) + filter_upwards [hpos, huni δ' (by positivity)] with t ht_pos hbound + have hlog_eq : log (b * t / (a * t)) = log (b / a) := by + rw [mul_div_mul_right b a (ne_of_gt ht_pos)] + calc dist (∫ x in a * t..b * t, x⁻¹ • f x) (log (b / a) • V) + _ = ‖(∫ x in a * t..b * t, x⁻¹ • f x) - log (b / a) • V‖ := dist_eq_norm _ _ + _ = ‖(∫ x in a * t..b * t, x⁻¹ • f x) - log (b * t / (a * t)) • V‖ := by rw [hlog_eq] + _ ≤ δ' * |log (b * t / (a * t))| := + norm_integral_inv_smul_sub_le hf (by positivity) (by positivity) (by positivity) hbound + _ = δ' * C := by rw [hlog_eq] + _ = δ * (C / (C + 1)) := by ring + _ < δ * 1 := mul_lt_mul_of_pos_left ((div_lt_one (by positivity)).2 (lt_add_one C)) hδ + _ = δ := mul_one δ + +lemma tendsto_integral_inv_smul_nhdsWithin (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) + (hb : 0 < b) (hL : Tendsto f (𝓝[>] 0) (𝓝 L)) : + Tendsto (fun ε ↦ ∫ x in (a * ε)..(b * ε), x⁻¹ • f x) (𝓝[>] 0) (𝓝 (log (b / a) • L)) := by + apply tendsto_integral_inv_smul_of_tendsto_uniform hf ha hb self_mem_nhdsWithin + intro δ hδ + have hev : ∀ᶠ x in 𝓝[>] (0 : ℝ), dist (f x) L < δ := + hL.eventually (ball_mem_nhds L hδ) + rw [Filter.Eventually, mem_nhdsWithin_iff] at hev + obtain ⟨η, hη, hη_sub⟩ := hev + set M := max a b with hM_def + have hM : 0 < M := lt_max_of_lt_left ha + filter_upwards [self_mem_nhdsWithin, + nhdsWithin_le_nhds (Iio_mem_nhds (div_pos hη hM))] with t ht_pos ht_bound + intro x hx + have hx_pos : 0 < x := (lt_min (by positivity) (by positivity)).trans_le (uIoc_subset_uIcc hx).1 + have hx_lt_η : dist x 0 < η := by + rw [Real.dist_eq, sub_zero, abs_of_pos hx_pos] + calc x + _ ≤ max (a * t) (b * t) := (uIoc_subset_uIcc hx).2 + _ = M * t := by rw [hM_def, max_mul_of_nonneg _ _ ht_pos.le] + _ < M * (η / M) := mul_lt_mul_of_pos_left ht_bound hM + _ = η := mul_div_cancel₀ η (ne_of_gt hM) + have := hη_sub ⟨mem_ball.2 hx_lt_η, hx_pos⟩ + rw [mem_ofPred_eq, dist_eq_norm] at this + exact le_of_lt this + +/-- If `f → R` as `x → +∞` and `f` is locally integrable on `(0, ∞)`, then the weighted integral +`∫ x in a*r..b*r, x⁻¹ • f x` converges to `log(b/a) • R` as `r → +∞`. -/ +lemma tendsto_integral_inv_smul_atTop (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) (hb : 0 < b) + (hR : Tendsto f atTop (𝓝 R)) : + Tendsto (fun r ↦ ∫ x in (a * r)..(b * r), x⁻¹ • f x) atTop (𝓝 (log (b / a) • R)) := by + apply tendsto_integral_inv_smul_of_tendsto_uniform hf ha hb + (eventually_atTop.2 ⟨1, fun r hr ↦ zero_lt_one.trans_le hr⟩) + intro δ hδ + have hev : ∀ᶠ x in atTop, dist (f x) R < δ := + hR.eventually (ball_mem_nhds R hδ) + rw [Filter.eventually_atTop] at hev + obtain ⟨N, hN⟩ := hev + have hm : 0 < min a b := lt_min ha hb + filter_upwards [eventually_atTop.2 ⟨max 1 (N / min a b), fun r hr ↦ hr⟩] with t ht + intro x hx + have ht_pos : 0 < t := lt_of_lt_of_le one_pos ((le_max_left 1 _).trans ht) + have hNx : N ≤ x := + calc N + _ = min a b * (N / min a b) := by field_simp + _ ≤ min a b * t := + mul_le_mul_of_nonneg_left ((le_max_right _ _).trans ht) hm.le + _ = min (a * t) (b * t) := by rw [min_mul_of_nonneg _ _ ht_pos.le] + _ ≤ x := (uIoc_subset_uIcc hx).1 + have hdist := hN x hNx + rw [dist_eq_norm] at hdist + exact le_of_lt hdist + +/-- **Frullani's integral**, limit form, for functions valued in a complete normed space. +If `f` is locally integrable on `(0, ∞)` with `f x → L` as `x → 0⁺` and `f x → R` as `x → +∞`, +and `0 < a` and `0 < b`, then `∫ x in ε..r, x⁻¹ • (f (a * x) - f (b * x)) → log (b / a) • (L - R)` +as `ε → 0⁺` and `r → +∞`. -/ +theorem tendsto_intervalIntegral (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) (hb : 0 < b) + (hL : Tendsto f (𝓝[>] 0) (𝓝 L)) (hR : Tendsto f atTop (𝓝 R)) : + Tendsto (fun p : ℝ × ℝ ↦ ∫ x in p.1..p.2, x⁻¹ • (f (a * x) - f (b * x))) + ((𝓝[>] 0) ×ˢ atTop) (𝓝 (log (b / a) • (L - R))) := by + let u := fun x ↦ x⁻¹ • f x + have hint {p q : ℝ} (hp : 0 < p) (hq : 0 < q) : IntervalIntegrable u volume p q := + intervalIntegrable_inv_smul hf hp hq + have hsplit {ε r : ℝ} (hε : 0 < ε) (hr : 0 < r) : + ∫ x in ε..r, x⁻¹ • (f (a * x) - f (b * x)) = + (∫ x in (a * ε)..(b * ε), u x) - ∫ x in (a * r)..(b * r), u x := by + calc ∫ x in ε..r, x⁻¹ • (f (a * x) - f (b * x)) + _ = (∫ x in ε..r, x⁻¹ • f (a * x)) - ∫ x in ε..r, x⁻¹ • f (b * x) := by + simp_rw [smul_sub] + exact integral_sub (intervalIntegrable_inv_smul_comp_mul hf hε hr ha) + (intervalIntegrable_inv_smul_comp_mul hf hε hr hb) + _ = (∫ y in a * ε..a * r, u y) - ∫ y in b * ε..b * r, u y := by + rw [integral_comp_mul_inv_smul ha.ne', integral_comp_mul_inv_smul hb.ne'] + _ = _ := integral_interval_sub_interval_comm + (hint (mul_pos ha hε) (mul_pos ha hr)) + (hint (mul_pos hb hε) (mul_pos hb hr)) + (hint (mul_pos ha hε) (mul_pos hb hε)) + have h_ev : (fun p : ℝ × ℝ ↦ ∫ x in p.1..p.2, x⁻¹ • (f (a * x) - f (b * x))) =ᶠ[(𝓝[>] 0) ×ˢ atTop] + fun p ↦ (∫ x in (a * p.1)..(b * p.1), u x) - ∫ x in (a * p.2)..(b * p.2), u x := by + filter_upwards [prod_mem_prod (eventually_nhdsWithin_of_forall fun _ h ↦ h) + (eventually_atTop.2 ⟨1, fun _ h ↦ lt_of_lt_of_le one_pos h⟩)] with ⟨ε, r⟩ ⟨hε, hr⟩ + exact hsplit hε hr + rw [tendsto_congr' h_ev, show log (b / a) • (L - R) = + log (b / a) • L - log (b / a) • R from smul_sub _ _ _] + exact ((tendsto_integral_inv_smul_nhdsWithin hf ha hb hL).comp tendsto_fst).sub + ((tendsto_integral_inv_smul_atTop hf ha hb hR).comp tendsto_snd) + +/-- **Frullani's integral** for functions valued in a complete normed space. +If `f` is locally integrable on `(0, ∞)` with `f x → L` as `x → 0⁺` and `f x → R` as `x → +∞`, +`0 < a` and `0 < b`, and `x ↦ x⁻¹ • (f (a * x) - f (b * x))` is integrable on `(0, ∞)`, then +`∫ x in Ioi 0, x⁻¹ • (f (a * x) - f (b * x)) = log (b / a) • (L - R)`. -/ +theorem integral_Ioi_eq (hf : LocallyIntegrableOn f (Ioi 0)) (ha : 0 < a) (hb : 0 < b) + (hL : Tendsto f (𝓝[>] 0) (𝓝 L)) (hR : Tendsto f atTop (𝓝 R)) + (hint : IntegrableOn (fun x ↦ x⁻¹ • (f (a * x) - f (b * x))) (Ioi 0)) : + ∫ x in Ioi 0, x⁻¹ • (f (a * x) - f (b * x)) = log (b / a) • (L - R) := by + have h_lim := (tendsto_intervalIntegral hf ha hb hL hR).mono_left curry_le_prod + set g := fun x ↦ x⁻¹ • (f (a * x) - f (b * x)) with hg + apply tendsto_nhds_unique + (hint.continuousWithinAt_Ici_primitive_Ioi.mono_left (nhdsWithin_mono 0 Ioi_subset_Ici_self)) + rw [tendsto_nhdsWithin_nhds] + intro ε hε + rw [Metric.tendsto_nhds] at h_lim + specialize h_lim (ε / 2) (by positivity) + rw [eventually_curry_iff, Filter.Eventually, mem_nhdsWithin_iff] at h_lim + obtain ⟨δ, hδ_pos, hδ⟩ := h_lim + simp_rw [subset_def, mem_inter_iff, mem_ball] at hδ + refine ⟨δ, hδ_pos, ?_⟩ + intro x hx hdist + specialize hδ x ⟨hdist, hx⟩ + rw [mem_ofPred] at hδ + have hint' : IntegrableOn g (Ioi x) := hint.mono (by grind) (by simp) + have htends := intervalIntegral_tendsto_integral_Ioi x hint' tendsto_id + have hle := le_of_tendsto (htends.dist tendsto_const_nhds) (hδ.mono (fun _ hy ↦ hy.le)) + linarith + +end Frullani diff --git a/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean b/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean index e3900fef798c67..2a14f893870c0a 100644 --- a/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean +++ b/Mathlib/Analysis/SpecialFunctions/ImproperIntegrals.lean @@ -5,9 +5,8 @@ Authors: David Loeffler -/ module -public import Mathlib.Analysis.SpecialFunctions.JapaneseBracket public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic -public import Mathlib.MeasureTheory.Group.Integral +public import Mathlib.Analysis.SpecialFunctions.JapaneseBracket public import Mathlib.MeasureTheory.Integral.IntegralEqImproper public import Mathlib.MeasureTheory.Measure.Lebesgue.Integral From b5d557f7df250b0a7476c30778a3b17a1e448a26 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Thu, 23 Jul 2026 01:41:34 +0000 Subject: [PATCH 0962/1300] refactor(LinearAlgebra): semilinearize `Submodule.Quotient.equiv` (#42001) This PR generalizes `Submodule.Quotient.equiv` to a semi-linear equivalence. --- Mathlib/LinearAlgebra/Quotient/Basic.lean | 49 +++++++++++++---------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/Mathlib/LinearAlgebra/Quotient/Basic.lean b/Mathlib/LinearAlgebra/Quotient/Basic.lean index f1b61653a489d8..261bc284bcf553 100644 --- a/Mathlib/LinearAlgebra/Quotient/Basic.lean +++ b/Mathlib/LinearAlgebra/Quotient/Basic.lean @@ -321,34 +321,39 @@ theorem span_preimage_eq [RingHomSurjective τ₁₂] {f : M →ₛₗ[τ₁₂] rw [hk, ← LinearMap.map_le_map_iff, map_span, map_comap_eq, Set.image_preimage_eq_of_subset h₁] exact inf_le_right +variable {R₂ : Type*} [Ring R₂] {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} + [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] +variable {M N : Type*} [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R₂ N] + (P : Submodule R M) (Q : Submodule R₂ N) + /-- If `P` is a submodule of `M` and `Q` a submodule of `N`, -and `f : M ≃ₗ N` maps `P` to `Q`, then `M ⧸ P` is equivalent to `N ⧸ Q`. -/ -@[simps apply] -def Quotient.equiv {N : Type*} [AddCommGroup N] [Module R N] (P : Submodule R M) - (Q : Submodule R N) (f : M ≃ₗ[R] N) (hf : P.map (f : M →ₗ[R] N) = Q) : (M ⧸ P) ≃ₗ[R] N ⧸ Q := - { P.mapQ Q (f : M →ₗ[R] N) fun _ hx => hf ▸ Submodule.mem_map_of_mem hx with - toFun := P.mapQ Q (f : M →ₗ[R] N) fun _ hx => hf ▸ Submodule.mem_map_of_mem hx - invFun := - Q.mapQ P (f.symm : N →ₗ[R] M) fun x hx => by - rw [← hf, Submodule.mem_map] at hx - obtain ⟨y, hy, rfl⟩ := hx - simpa - left_inv := fun x => Submodule.Quotient.induction_on _ x (by simp) - right_inv := fun x => Submodule.Quotient.induction_on _ x (by simp) } +and `f : M ≃ₛₗ[σ] N` maps `P` to `Q`, then `M ⧸ P` is equivalent to `N ⧸ Q`. -/ +def Quotient.equiv (f : M ≃ₛₗ[σ₁₂] N) (hf : P.map (f : M →ₛₗ[σ₁₂] N) = Q) : + (M ⧸ P) ≃ₛₗ[σ₁₂] N ⧸ Q where + __ := P.mapQ Q (f : M →ₛₗ[σ₁₂] N) (map_le_iff_le_comap.mp hf.le) + invFun := Q.mapQ P (f.symm : N →ₛₗ[σ₂₁] M) (hf.symm.trans (map_equiv_eq_comap_symm f _)).le + left_inv x := Quotient.induction_on _ x (by simp) + right_inv x := Quotient.induction_on _ x (by simp) + +@[simp] +lemma Quotient.equiv_apply (f : M ≃ₛₗ[σ₁₂] N) (hf : P.map (f : M →ₛₗ[σ₁₂] N) = Q) (a : M ⧸ P) : + equiv P Q f hf a = P.mapQ Q (f : M →ₛₗ[σ₁₂] N) (map_le_iff_le_comap.mp hf.le) a := + rfl @[simp] -theorem Quotient.equiv_symm {R M N : Type*} [Ring R] [AddCommGroup M] [Module R M] - [AddCommGroup N] [Module R N] (P : Submodule R M) (Q : Submodule R N) (f : M ≃ₗ[R] N) - (hf : P.map (f : M →ₗ[R] N) = Q) : - (Quotient.equiv P Q f hf).symm = - Quotient.equiv Q P f.symm ((Submodule.map_symm_eq_iff f).mpr hf) := +lemma Quotient.equiv_symm (f : M ≃ₛₗ[σ₁₂] N) (hf : P.map (f : M →ₛₗ[σ₁₂] N) = Q) : + (Quotient.equiv P Q f hf).symm = Quotient.equiv Q P f.symm ((map_symm_eq_iff f).mpr hf) := rfl @[simp] -theorem Quotient.equiv_trans {N O : Type*} [AddCommGroup N] [Module R N] [AddCommGroup O] - [Module R O] (P : Submodule R M) (Q : Submodule R N) (S : Submodule R O) (e : M ≃ₗ[R] N) - (f : N ≃ₗ[R] O) (he : P.map (e : M →ₗ[R] N) = Q) (hf : Q.map (f : N →ₗ[R] O) = S) - (hef : P.map (e.trans f : M →ₗ[R] O) = S) : +theorem Quotient.equiv_trans {R₃ : Type*} {O : Type*} [Ring R₃] [AddCommGroup O] [Module R₃ O] + {σ₂₃ : R₂ →+* R₃} {σ₃₂ : R₃ →+* R₂} {σ₁₃ : R →+* R₃} {σ₃₁ : R₃ →+* R} + [RingHomInvPair σ₂₃ σ₃₂] [RingHomInvPair σ₃₂ σ₂₃] + [RingHomInvPair σ₁₃ σ₃₁] [RingHomInvPair σ₃₁ σ₁₃] + [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] [RingHomCompTriple σ₃₂ σ₂₁ σ₃₁] + (S : Submodule R₃ O) (e : M ≃ₛₗ[σ₁₂] N) (f : N ≃ₛₗ[σ₂₃] O) + (he : P.map (e : M →ₛₗ[σ₁₂] N) = Q) (hf : Q.map (f : N →ₛₗ[σ₂₃] O) = S) + (hef : P.map ((e.trans f : M ≃ₛₗ[σ₁₃] O) : M →ₛₗ[σ₁₃] O) = S) : Quotient.equiv P S (e.trans f) hef = (Quotient.equiv P Q e he).trans (Quotient.equiv Q S f hf) := by ext From 1b92f9f3413674899dbec743da67a884ffd76a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20G=2E=20Dorais?= <3247514+fgdorais@users.noreply.github.com> Date: Thu, 23 Jul 2026 03:41:05 +0000 Subject: [PATCH 0963/1300] chore: adaptations for batteries#1921 (#42013) Fixes newly deprecated modules from Batteries. Co-authored-by: mathlib-nightly-testing[bot] Co-authored-by: F. G. Dorais --- Mathlib/Analysis/Real/Pi/Chudnovsky.lean | 2 +- lake-manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Real/Pi/Chudnovsky.lean b/Mathlib/Analysis/Real/Pi/Chudnovsky.lean index a1ff2d4c48d30d..8aa136c188f0ac 100644 --- a/Mathlib/Analysis/Real/Pi/Chudnovsky.lean +++ b/Mathlib/Analysis/Real/Pi/Chudnovsky.lean @@ -5,7 +5,7 @@ Authors: Kim Morrison -/ module -meta import Batteries.Data.Rat.Float -- shake: keep (for `#eval` sanity check) +meta import Batteries.Data.Float.Rat -- shake: keep (for `#eval` sanity check) public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan public import Mathlib.MeasureTheory.Integral.Bochner.Basic public import Mathlib.Tactic.Positivity diff --git a/lake-manifest.json b/lake-manifest.json index da3bfd52ff5d8e..d4b1f3146e6c82 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "2ccad61f0f1bb8000458a72fc7ec5df8a7a821b2", + "rev": "975a7ed3e5ed7838da79d5abddc50df73d0c84af", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 8f560a221155625bff8f33163ec62b33cd9f81a2 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Thu, 23 Jul 2026 04:46:29 +0000 Subject: [PATCH 0964/1300] feat(Algebra/ModuleCat): injective dimension in linear equiv (#41885) In this PR, we prove that injective dimension is stable under arbitrary (semi) linear equivalence. --- Mathlib.lean | 1 + .../ModuleCat/InjectiveDimension.lean | 161 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4325c25d6e8eff..2e3a729ae403b3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -170,6 +170,7 @@ public import Mathlib.Algebra.Category.ModuleCat.FilteredColimits public import Mathlib.Algebra.Category.ModuleCat.Free public import Mathlib.Algebra.Category.ModuleCat.Images public import Mathlib.Algebra.Category.ModuleCat.Injective +public import Mathlib.Algebra.Category.ModuleCat.InjectiveDimension public import Mathlib.Algebra.Category.ModuleCat.Kernels public import Mathlib.Algebra.Category.ModuleCat.LeftResolution public import Mathlib.Algebra.Category.ModuleCat.Limits diff --git a/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean b/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean new file mode 100644 index 00000000000000..384f9e81601bef --- /dev/null +++ b/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean @@ -0,0 +1,161 @@ +/- +Copyright (c) 2025 Nailin Guan. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Nailin Guan +-/ +module + +public import Mathlib.Algebra.Category.ModuleCat.Ext.DimensionShifting +public import Mathlib.Algebra.Category.ModuleCat.EnoughInjectives +public import Mathlib.Algebra.Category.ModuleCat.Injective +public import Mathlib.Algebra.Homology.ShortComplex.ModuleCat +public import Mathlib.CategoryTheory.Abelian.Injective.Dimension + +/-! + +# Injective Dimension in ModuleCat + +This file deals with preservation of `injectiveDimension` in (semi) linear equivalences. +Previously we only know this for linear equivalence within same universe level, now it works with +all universe level where the ring `R` is small. + +## Main Results + +* `ModuleCat.hasInjectiveDimensionLE_iff_of_linearEquiv`: `HasInjectiveDimensionLE` is preserved + under arbitrary linear equivalence. + +* `ModuleCat.hasInjectiveDimensionLE_iff_of_semiLinearEquiv`: `HasInjectiveDimensionLE` is preserved + under arbitrary semi-linear equivalence. + +* `ModuleCat.injectiveDimension_eq_of_semiLinearEquiv`: `injectiveDimension` is preserved + under arbitrary semi-linear equivalence. + +* `ModuleCat.injectiveDimension_eq_of_linearEquiv`: `injectiveDimension` is preserved + under arbitrary linear equivalence. + +-/ + +public section + +universe v v' u u' + +variable {R : Type u} [Ring R] + +open CategoryTheory Abelian + +namespace ModuleCat + +private lemma hasInjectiveDimensionLE_iff_of_linearEquiv_aux [Small.{v} R] + {M : ModuleCat.{v} R} {N : ModuleCat.{max v v'} R} + (e : M ≃ₗ[R] N) (n : ℕ) : HasInjectiveDimensionLE M n ↔ HasInjectiveDimensionLE N n := by + have : Small.{max v v'} R := small_lift R + induction n generalizing M N with + | zero => + simp [HasInjectiveDimensionLE, ← injective_iff_hasInjectiveDimensionLT_one, + ← Module.injective_iff_injective_object R M, ← Module.injective_iff_injective_object R N, + ← Module.Baer.iff_injective, Module.Baer.congr e] + | succ n ih => + let ⟨I, _, f, _⟩ := EnoughInjectives.presentation M + have injf : Function.Injective f.hom := (mono_iff_injective f).mp ‹_› + let S : ShortComplex (ModuleCat.{v} R) := + ModuleCat.shortComplexOfCompEqZero _ _ f.hom.exact_map_mkQ_range.linearMap_comp_eq_zero + have exactS := ModuleCat.shortComplex_shortExact S + f.hom.exact_map_mkQ_range injf (Submodule.mkQ_surjective _) + let I' := ModuleCat.of R (ULift.{v'} I) + let f' : N →ₗ[R] I' := ULift.moduleEquiv.symm.toLinearMap.comp (f.hom.comp e.symm.toLinearMap) + have injf' : Function.Injective f' := by simpa [f'] + let S' : ShortComplex (ModuleCat.{max v v'} R) := + ModuleCat.shortComplexOfCompEqZero _ _ f'.exact_map_mkQ_range.linearMap_comp_eq_zero + have exactS' := ModuleCat.shortComplex_shortExact S' + f'.exact_map_mkQ_range injf' (Submodule.mkQ_surjective _) + let eCoker : ModuleCat.of R (I ⧸ f.hom.range) ≃ₗ[R] ModuleCat.of R (I' ⧸ f'.range) := + Submodule.Quotient.equiv _ _ ULift.moduleEquiv.symm (by simp [f', LinearMap.range_comp]) + exact (exactS.hasInjectiveDimensionLT_X₃_iff n inferInstance).symm.trans + ((ih eCoker).trans (exactS'.hasInjectiveDimensionLT_X₃_iff n inferInstance)) + +lemma hasInjectiveDimensionLE_iff_of_linearEquiv [Small.{v} R] [Small.{v'} R] + {M : ModuleCat.{v} R} {N : ModuleCat.{v'} R} + (e : M ≃ₗ[R] N) (n : ℕ) : HasInjectiveDimensionLE M n ↔ HasInjectiveDimensionLE N n := by + let eM : M ≃ₗ[R] ModuleCat.of R (ULift.{v'} M) := ULift.moduleEquiv.symm + rw [hasInjectiveDimensionLE_iff_of_linearEquiv_aux eM, + ← hasInjectiveDimensionLE_iff_of_linearEquiv_aux (e.symm.trans eM)] + +section SemiLinear + +variable [Small.{v} R] {R' : Type u'} [Ring R'] (eR : R ≃+* R') + +attribute [local instance] RingHomInvPair.of_ringEquiv + +set_option backward.isDefEq.respectTransparency.types false in +private lemma hasInjectiveDimensionLE_iff_of_semiLinearEquiv_aux [Small.{v} R'] + {M : ModuleCat.{v} R} {N : ModuleCat.{v} R'} (e : M ≃ₛₗ[RingHomClass.toRingHom eR] N) + (n : ℕ) : HasInjectiveDimensionLE M n ↔ HasInjectiveDimensionLE N n := by + induction n generalizing M N with + | zero => + simp only [HasInjectiveDimensionLE, zero_add, ← injective_iff_hasInjectiveDimensionLT_one, + ← Module.injective_iff_injective_object R M, ← Module.injective_iff_injective_object R' N] + exact ⟨fun _ ↦ Module.Injective.of_ringEquiv eR e, + fun _ ↦ Module.Injective.of_ringEquiv eR.symm e.symm⟩ + | succ n ih => + let ⟨I', _, f', _⟩ := EnoughInjectives.presentation N + have : Module.Injective R' I' := Module.injective_module_of_injective_object R' I' + have injf' : Function.Injective f'.hom := (mono_iff_injective f').mp ‹_› + let S' : ShortComplex (ModuleCat.{v} R') := + ModuleCat.shortComplexOfCompEqZero _ _ f'.hom.exact_map_mkQ_range.linearMap_comp_eq_zero + have exactS' := ModuleCat.shortComplex_shortExact S' + f'.hom.exact_map_mkQ_range injf' (Submodule.mkQ_surjective _) + let I : ModuleCat.{v} R := + let := Module.compHom I' eR.toRingHom + ModuleCat.of R I' + let eI : I ≃ₛₗ[RingHomClass.toRingHom eR] I' := { + __ := AddEquiv.refl I + map_smul' r i := rfl } + have : Injective (ModuleCat.of R I) := by + rw [← Module.injective_iff_injective_object] + exact Module.Injective.of_ringEquiv eR.symm eI.symm + let f : M →ₗ[R] I := eI.symm.toLinearMap.comp (f'.hom.comp e.toLinearMap) + have injf : Function.Injective f := by simpa [f] + let S : ShortComplex (ModuleCat.{v} R) := + ModuleCat.shortComplexOfCompEqZero _ _ f.exact_map_mkQ_range.linearMap_comp_eq_zero + have exactS := ModuleCat.shortComplex_shortExact S + f.exact_map_mkQ_range injf (Submodule.mkQ_surjective _) + let eCoker : ModuleCat.of R (I ⧸ f.range) ≃ₛₗ[RingHomClass.toRingHom eR] + ModuleCat.of R' (I' ⧸ f'.hom.range) := + Submodule.Quotient.equiv _ _ eI + (by simp [f, ← Submodule.map_symm_eq_iff eI, LinearMap.range_comp]) + exact (exactS.hasInjectiveDimensionLT_X₃_iff n inferInstance).symm.trans + ((ih eCoker).trans (exactS'.hasInjectiveDimensionLT_X₃_iff n inferInstance)) + +set_option backward.isDefEq.respectTransparency.types false in +attribute [local instance] small_lift in +lemma hasInjectiveDimensionLE_iff_of_semiLinearEquiv [Small.{v'} R'] + {M : ModuleCat.{v} R} {N : ModuleCat.{v'} R'} (e : M ≃ₛₗ[RingHomClass.toRingHom eR] N) + (n : ℕ) : HasInjectiveDimensionLE M n ↔ HasInjectiveDimensionLE N n := by + let eM : M ≃ₗ[R] ModuleCat.of R (ULift.{v'} M) := ULift.moduleEquiv.symm + let eN : N ≃ₗ[R'] ModuleCat.of R' (ULift.{v} N) := ULift.moduleEquiv.symm + rw [hasInjectiveDimensionLE_iff_of_linearEquiv_aux eM, + hasInjectiveDimensionLE_iff_of_linearEquiv_aux eN] + exact hasInjectiveDimensionLE_iff_of_semiLinearEquiv_aux eR ((eM.symm.trans e).trans eN) n + +lemma injectiveDimension_eq_of_semiLinearEquiv [Small.{v'} R'] + {M : ModuleCat.{v} R} {N : ModuleCat.{v'} R'} (e : M ≃ₛₗ[RingHomClass.toRingHom eR] N) : + injectiveDimension M = injectiveDimension N := by + refine eq_of_forall_ge_iff (fun N ↦ ?_) + induction N with + | bot => simpa [injectiveDimension_eq_bot_iff, ModuleCat.isZero_iff_subsingleton] using + e.subsingleton_congr + | coe n => + induction n with + | top => simp + | coe n => + simp [injectiveDimension_le_iff, hasInjectiveDimensionLE_iff_of_semiLinearEquiv eR e n] + +end SemiLinear + +variable [Small.{v} R] [Small.{v'} R] {M : ModuleCat.{v} R} {N : ModuleCat.{v'} R} + +lemma injectiveDimension_eq_of_linearEquiv (e : M ≃ₗ[R] N) : + injectiveDimension M = injectiveDimension N := + injectiveDimension_eq_of_semiLinearEquiv.{v, v'} (M := M) (N := N) (RingEquiv.refl R) e + +end ModuleCat From 8e45b0548034eeda677a64e1e0b07837390835b6 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Thu, 23 Jul 2026 05:40:58 +0000 Subject: [PATCH 0965/1300] feat: add Ideal.IsPrincipal.of_isPrincipal_pow_of_coprime (#39982) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/RingTheory/ClassGroup/Basic.lean | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Mathlib/RingTheory/ClassGroup/Basic.lean b/Mathlib/RingTheory/ClassGroup/Basic.lean index da61aa42c60676..e91fe290266922 100644 --- a/Mathlib/RingTheory/ClassGroup/Basic.lean +++ b/Mathlib/RingTheory/ClassGroup/Basic.lean @@ -365,6 +365,19 @@ theorem ClassGroup.mk_eq_one_iff {I : (FractionalIdeal R⁰ K)ˣ} : · intro x_eq; apply Units.ne_zero I; simp [hx', x_eq] · simp [hx'] +/-- A fractional ideal is principal if a power coprime to the class number is principal. -/ +theorem FractionalIdeal.isPrincipal.of_isPrincipal_pow_of_coprime [IsDedekindDomain R] + [Fintype (ClassGroup R)] {n : ℕ} (hn : n.Coprime (Fintype.card (ClassGroup R))) + (I : FractionalIdeal R⁰ K) (hI : ((I ^ n : FractionalIdeal R⁰ K) : Submodule R K).IsPrincipal) : + (I : Submodule R K).IsPrincipal := by + obtain (rfl | ⟨u, rfl⟩) := GroupWithZero.eq_zero_or_unit I + · simp [bot_isPrincipal] + rw [← ClassGroup.mk_eq_one_iff, ← orderOf_eq_one_iff, ← Nat.dvd_one, ← hn, + Nat.dvd_gcd_iff] + refine ⟨?_, orderOf_dvd_card⟩ + rw [orderOf_dvd_iff_pow_eq_one, ← map_pow, ClassGroup.mk_eq_one_iff] + exact_mod_cast hI + /-- If the class group is trivial, any unit fractional ideal is principal. -/ theorem ClassGroup.isPrincipal_coeSubmodule_of_isUnit [Subsingleton (ClassGroup R)] (I : FractionalIdeal R⁰ K) (hI : IsUnit I) : @@ -387,6 +400,18 @@ theorem ClassGroup.mk0_eq_one_iff [IsDedekindDomain R] {I : Ideal R} (hI : I ∈ ClassGroup.mk0 ⟨I, hI⟩ = 1 ↔ I.IsPrincipal := ClassGroup.mk_eq_one_iff.trans (coeSubmodule_isPrincipal R _) +/-- An ideal is principal if a power coprime to the class number is principal. -/ +theorem Ideal.IsPrincipal.of_isPrincipal_pow_of_coprime [IsDedekindDomain R] + [Fintype (ClassGroup R)] {n : ℕ} (hn : n.Coprime (Fintype.card (ClassGroup R))) + {I : Ideal R} (hI : (I ^ n).IsPrincipal) : I.IsPrincipal := by + by_cases hI0 : I = 0 + · simp [hI0, bot_isPrincipal] + rw [← ClassGroup.mk0_eq_one_iff (pow_mem (mem_nonZeroDivisors_of_ne_zero hI0) n)] at hI + rw [← ClassGroup.mk0_eq_one_iff (mem_nonZeroDivisors_of_ne_zero hI0), ← orderOf_eq_one_iff, + ← Nat.dvd_one, ← hn, Nat.dvd_gcd_iff] + refine ⟨?_, orderOf_dvd_card⟩ + rwa [orderOf_dvd_iff_pow_eq_one, ← map_pow, SubmonoidClass.mk_pow] + theorem ClassGroup.mk0_eq_mk0_inv_iff [IsDedekindDomain R] {I J : (Ideal R)⁰} : ClassGroup.mk0 I = (ClassGroup.mk0 J)⁻¹ ↔ ∃ x ≠ (0 : R), I * J = Ideal.span {x} := by From 3e8105934319cb416a3536919a7d84bf7d72cd0c Mon Sep 17 00:00:00 2001 From: Etienne Marion <66847262+EtienneC30@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:03:46 +0000 Subject: [PATCH 0966/1300] refactor: change the definition of the stopped sigma-algebra (#42021) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the definition of [MeasureTheory.IsStoppingTime.measurableSpace](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Probability/Process/Stopping.html#MeasureTheory.IsStoppingTime.measurableSpace) to require that it contains only sets that are measurable wrt `⨆ t, f t` where `f` is the filtration. This is what is done for instance in _Semimartingale Theory and Stochastic Calculus_ by He Wang Yan and is needed in the Brownian motion project. --- Mathlib/Probability/Process/Stopping.lean | 35 ++++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 72e3d37a65d1c5..0e98b272618003 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -442,7 +442,7 @@ variable [Preorder ι] {f : Filtration ι m} {τ π : Ω → WithTop ι} /-- The associated σ-algebra with a stopping time. -/ @[instance_reducible] protected def measurableSpace (hτ : IsStoppingTime f τ) : MeasurableSpace Ω where - MeasurableSet' s := MeasurableSet s ∧ ∀ i : ι, MeasurableSet[f i] (s ∩ {ω | τ ω ≤ i}) + MeasurableSet' s := MeasurableSet[⨆ t, f t] s ∧ ∀ i : ι, MeasurableSet[f i] (s ∩ {ω | τ ω ≤ i}) measurableSet_empty := by simp measurableSet_compl s hs := by refine ⟨hs.1.compl, fun i ↦ ?_⟩ @@ -462,7 +462,7 @@ protected def measurableSpace (hτ : IsStoppingTime f τ) : MeasurableSpace Ω w protected theorem measurableSet (hτ : IsStoppingTime f τ) (s : Set Ω) : MeasurableSet[hτ.measurableSpace] s - ↔ MeasurableSet s ∧ ∀ i : ι, MeasurableSet[f i] (s ∩ {ω | τ ω ≤ i}) := + ↔ MeasurableSet[⨆ t, f t] s ∧ ∀ i : ι, MeasurableSet[f i] (s ∩ {ω | τ ω ≤ i}) := Iff.rfl theorem measurableSpace_mono (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f π) (hle : τ ≤ π) : @@ -475,7 +475,11 @@ theorem measurableSpace_mono (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f intro hle' _ exact le_trans (hle _) hle' -theorem measurableSpace_le (hτ : IsStoppingTime f τ) : hτ.measurableSpace ≤ m := fun _ hs ↦ hs.1 +theorem measurableSpace_le' (hτ : IsStoppingTime f τ) : + hτ.measurableSpace ≤ ⨆ t, f t := fun _ hs ↦ hs.1 + +theorem measurableSpace_le (hτ : IsStoppingTime f τ) : hτ.measurableSpace ≤ m := + hτ.measurableSpace_le'.trans (iSup_le f.le) @[simp] theorem measurableSpace_const (f : Filtration ι m) (i : ι) : @@ -485,7 +489,7 @@ theorem measurableSpace_const (f : Filtration ι m) (i : ι) : constructor <;> intro h · have h' := h.2 i simpa only [le_refl, Set.ofPred_true, Set.inter_univ] using h' - · refine ⟨f.le i _ h, fun j ↦ ?_⟩ + · refine ⟨le_iSup f i s h, fun j ↦ ?_⟩ by_cases hij : i ≤ j · norm_cast simp only [hij, Set.ofPred_true, Set.inter_univ] @@ -504,7 +508,7 @@ theorem measurableSet_inter_eq_iff (hτ : IsStoppingTime f τ) (s : Set Ω) (i : rw [hxi] constructor <;> intro h · simpa [Set.inter_assoc, this] using h.2 i - · refine ⟨f.le i _ h, fun j ↦ ?_⟩ + · refine ⟨le_iSup f i _ h, fun j ↦ ?_⟩ rw [Set.inter_assoc, this] by_cases hij : i ≤ j · norm_cast @@ -550,7 +554,7 @@ variable [LinearOrder ι] {f : Filtration ι m} {τ π : Ω → WithTop ι} protected theorem measurableSet_le' (hτ : IsStoppingTime f τ) (i : ι) : MeasurableSet[hτ.measurableSpace] {ω | τ ω ≤ i} := by - refine ⟨f.le i _ (hτ i), fun j ↦ ?_⟩ + refine ⟨le_iSup f i _ (hτ i), fun j ↦ ?_⟩ have : {ω : Ω | τ ω ≤ i} ∩ {ω : Ω | τ ω ≤ j} = {ω : Ω | τ ω ≤ min i j} := by ext1 ω simp [Set.mem_inter_iff, Set.mem_ofPred_eq] @@ -649,11 +653,20 @@ protected theorem measurable' [TopologicalSpace ι] [OrderTopology ι] [SecondCountableTopology ι] (hτ : IsStoppingTime f τ) : Measurable τ := hτ.measurable.mono (measurableSpace_le hτ) le_rfl +protected theorem measurable_iSup [TopologicalSpace ι] + [OrderTopology ι] [SecondCountableTopology ι] (hτ : IsStoppingTime f τ) : + Measurable[⨆ t, f t] τ := hτ.measurable.mono (measurableSpace_le' hτ) le_rfl + protected lemma measurableSet_eq_top [TopologicalSpace ι] [OrderTopology ι] [SecondCountableTopology ι] (hτ : IsStoppingTime f τ) : MeasurableSet {ω | τ ω = ⊤} := (measurableSet_singleton _).preimage hτ.measurable' +protected lemma measurableSet_eq_top' [TopologicalSpace ι] + [OrderTopology ι] [SecondCountableTopology ι] (hτ : IsStoppingTime f τ) : + MeasurableSet[⨆ t, f t] {ω | τ ω = ⊤} := + (measurableSet_singleton _).preimage hτ.measurable_iSup + protected theorem measurable_of_le [TopologicalSpace ι] [OrderTopology ι] [SecondCountableTopology ι] (hτ : IsStoppingTime f τ) {i : ι} (hτ_le : ∀ ω, τ ω ≤ i) : Measurable[f i] τ := @@ -698,7 +711,7 @@ theorem measurableSet_inter_le [TopologicalSpace ι] [SecondCountableTopology ι ext ω by_cases hτi : τ ω ≤ i <;> grind simp_rw [h_eq] - refine ⟨hs.1.inter (measurableSet_le hτ.measurable' hπ.measurable'), fun i ↦ ?_⟩ + refine ⟨hs.1.inter (measurableSet_le hτ.measurable_iSup hπ.measurable_iSup), fun i ↦ ?_⟩ refine ((hs.2 i).inter ((hτ.min hπ) i)).inter ?_ apply @measurableSet_le _ _ _ _ _ (Filtration.seq f i) _ _ _ _ _ ?_ ?_ · exact (hτ.min_const i).measurable_of_le fun _ => min_le_right _ _ @@ -730,7 +743,7 @@ theorem measurableSet_le_stopping_time [TopologicalSpace ι] [SecondCountableTop [OrderTopology ι] (hτ : IsStoppingTime f τ) (hπ : IsStoppingTime f π) : MeasurableSet[hτ.measurableSpace] {ω | τ ω ≤ π ω} := by rw [hτ.measurableSet] - refine ⟨measurableSet_le hτ.measurable' hπ.measurable', fun j ↦ ?_⟩ + refine ⟨measurableSet_le hτ.measurable_iSup hπ.measurable_iSup, fun j ↦ ?_⟩ have : {ω | τ ω ≤ π ω} ∩ {ω | τ ω ≤ j} = {ω | min (τ ω) j ≤ min (π ω) j} ∩ {ω | τ ω ≤ j} := by ext simpa using fun a b ↦ Std.IsPreorder.le_trans _ _ _ a b @@ -1056,7 +1069,7 @@ theorem measurable_stoppedValue [PseudoMetrizableSpace β] [MeasurableSpace β] exact (h_seq_tendsto t).exists rw [this] refine MeasurableSet.union ?_ ?_ - · exact MeasurableSet.iUnion fun i ↦ f.le (seq i) _ + · exact MeasurableSet.iUnion fun i ↦ le_iSup f (seq i) _ (measurableSet_preimage_stoppedValue_inter hf_prog hτ ht (seq i)) · have : stoppedValue u τ ⁻¹' t ∩ {ω | τ ω = ⊤} = (fun ω ↦ u (Classical.arbitrary ι) ω) ⁻¹' t ∩ {ω | τ ω = ⊤} := by @@ -1066,9 +1079,9 @@ theorem measurable_stoppedValue [PseudoMetrizableSpace β] [MeasurableSpace β] intro h simp [h] rw [this] - refine MeasurableSet.inter (ht.preimage ?_) hτ.measurableSet_eq_top + refine MeasurableSet.inter (ht.preimage ?_) hτ.measurableSet_eq_top' exact (hf_prog.stronglyAdapted (Classical.arbitrary ι)).measurable.mono - (f.le (Classical.arbitrary ι)) le_rfl + (le_iSup f (Classical.arbitrary ι)) le_rfl end Progressive From e780b56e9235c747285043b5cd5f2ebba300daad Mon Sep 17 00:00:00 2001 From: ajirving <29164966+ajirving@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:32:13 +0000 Subject: [PATCH 0967/1300] feat(Topology/Algebra): inv and div for infinite products over groups with zero (#40591) Proves two lemmas for infinite products over groups with zero: inverses and division behave as expected provided the limit is nonzero. This requires an extra import to get some of the GroupWithZero API. Maybe the GroupWithZero results should be in a different file but I was just adding to what was already there in Group.lean. --- .../Topology/Algebra/InfiniteSum/Group.lean | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean index 5f707e92f90dd6..089c65ef760b25 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean @@ -6,6 +6,7 @@ Authors: Johannes Hölzl module public import Mathlib.SetTheory.Cardinal.Finite +public import Mathlib.Topology.Algebra.GroupWithZero public import Mathlib.Topology.Algebra.InfiniteSum.Basic public import Mathlib.Topology.UniformSpace.Cauchy public import Mathlib.Topology.Algebra.IsUniformGroup.Defs @@ -415,8 +416,10 @@ theorem tprod_const [T2Space G] (a : G) : ∏' _ : β, a = a ^ (Nat.card β) := end IsTopologicalGroup section CommGroupWithZero -variable {K : Type*} [CommGroupWithZero K] [TopologicalSpace K] [SeparatelyContinuousMul K] - {f g : α → K} + +variable {K : Type*} [CommGroupWithZero K] [TopologicalSpace K] + {f g : α → K} {L : SummationFilter α} + /-! ## Groups with a zero @@ -424,6 +427,10 @@ These lemmas apply to a `CommGroupWithZero`; the most familiar case is when `K` are specific to the product setting and do not have a sensible additive analogue. -/ +section SeparatelyContinuousMul + +variable [SeparatelyContinuousMul K] + open Finset in lemma HasProd.congr_cofinite₀ {c : K} (hc : HasProd f c) {s : Finset α} (hs : ∀ a ∈ s, f a ≠ 0) (hs' : ∀ a ∉ s, f a = g a) : @@ -459,4 +466,36 @@ lemma Multipliable.congr_cofinite₀ (hf : Multipliable f) (hf' : ∀ a, f a ≠ obtain ⟨s, hs⟩ : ∃ s : Finset α, ∀ i ∉ s, f i = g i := ⟨hfg.toFinset, by simp⟩ exact (hc.congr_cofinite₀ (fun a _ ↦ hf' a) hs).multipliable +end SeparatelyContinuousMul + +theorem HasProd.inv₀ {a : K} [ContinuousInv₀ K] (h : HasProd f a L) (ha : a ≠ 0) : + HasProd (fun x ↦ (f x)⁻¹) a⁻¹ L := by + simp_rw [HasProd, Finset.prod_inv_distrib] + exact Tendsto.inv₀ h ha + +theorem Multipliable.inv₀ [ContinuousInv₀ K] (h : Multipliable f L) (ne_zero : ∏'[L] x, f x ≠ 0) : + Multipliable (fun x ↦ (f x)⁻¹) L := + h.hasProd.inv₀ ne_zero|>.multipliable + +theorem Multipliable.tprod_inv₀ [ContinuousInv₀ K] [T2Space K] [L.NeBot] + (h : Multipliable f L) (ne_zero : ∏'[L] x, f x ≠ 0) : + ∏'[L] x, (f x)⁻¹ = (∏'[L] x, f x )⁻¹ := + h.hasProd.inv₀ ne_zero|>.tprod_eq + +theorem HasProd.div₀ [ContinuousInv₀ K] [ContinuousMul K] {a b : K} + (hf : HasProd f a L) (hg : HasProd g b L) (hb : b ≠ 0) : + HasProd (fun x ↦ f x / g x) (a / b) L := by + simp only [div_eq_mul_inv] + exact hf.mul <| hg.inv₀ hb + +theorem Multipliable.div₀ [ContinuousInv₀ K] [ContinuousMul K] + (hf : Multipliable f L) (hg : Multipliable g L) (ne_zero : ∏'[L] x, g x ≠ 0) : + Multipliable (fun x ↦ f x / g x) L := + hf.hasProd.div₀ hg.hasProd ne_zero|>.multipliable + +theorem Multipliable.tprod_div₀ [ContinuousInv₀ K] [ContinuousMul K] [T2Space K] [L.NeBot] + (hf : Multipliable f L) (hg : Multipliable g L) (ne_zero : ∏'[L] x, g x ≠ 0) : + (∏'[L] x, f x / g x) = (∏'[L] x, f x) / (∏'[L] x, g x) := + hf.hasProd.div₀ hg.hasProd ne_zero|>.tprod_eq + end CommGroupWithZero From bbc4475e9e8fd25fbc8e26d636dd8b37be8f105a Mon Sep 17 00:00:00 2001 From: Jun Kwon Date: Thu, 23 Jul 2026 13:11:29 +0000 Subject: [PATCH 0968/1300] feat(Combinatorics/Graph): `Simple` typeclass for `Graph` (#37870) This PR introduces two type classes on `Graph`: `Loopless` and `Simple`. --- Mathlib.lean | 1 + Mathlib/Combinatorics/Graph/Simple.lean | 140 ++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 Mathlib/Combinatorics/Graph/Simple.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2e3a729ae403b3..efb85f00c55e2d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3578,6 +3578,7 @@ public import Mathlib.Combinatorics.Graph.Basic public import Mathlib.Combinatorics.Graph.Delete public import Mathlib.Combinatorics.Graph.Lattice public import Mathlib.Combinatorics.Graph.Maps +public import Mathlib.Combinatorics.Graph.Simple public import Mathlib.Combinatorics.Graph.Subgraph public import Mathlib.Combinatorics.HalesJewett public import Mathlib.Combinatorics.Hall.Basic diff --git a/Mathlib/Combinatorics/Graph/Simple.lean b/Mathlib/Combinatorics/Graph/Simple.lean new file mode 100644 index 00000000000000..008686765ff4b4 --- /dev/null +++ b/Mathlib/Combinatorics/Graph/Simple.lean @@ -0,0 +1,140 @@ +/- +Copyright (c) 2026 Jun Kwon. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jun Kwon, Peter Nelson +-/ +module + +public import Mathlib.Combinatorics.Graph.Subgraph +public import Mathlib.Combinatorics.SimpleGraph.Maps + +/-! +# Simple graphs + +This file defines two type classes for graphs `Graph α β`: `Loopless` and `Simple`. + +## Main definitions +- `Loopless`: a graph is loopless if it has no loops +- `Simple`: a graph is simple if it has no multiple edges between the same pair of vertices +- `toSimpleGraph`: a function that constructs a `SimpleGraph V(G)` from a Graph `G` +- `ofSimpleGraph`: a function that constructs a `Graph α (Sym2 α)` from a `SimpleGraph α` + +TODO: Show `ofSimpleGraph (toSimpleGraph G)` is isomorphic to `G` when isomorphism on `Graph` is +defined. +-/ + +public section + +variable {α β : Type*} {G H : Graph α β} {u v : α} {e f : β} {X Y : Set α} + +open Set SimpleGraph + +namespace Graph + +section Loopless + +/-- A loopless graph is one where the ends of every edge are distinct. -/ +@[mk_iff] +protected class Loopless (G : Graph α β) : Prop where + not_isLoopAt : ∀ e x, ¬ G.IsLoopAt e x + +@[simp] +lemma not_isLoopAt (G : Graph α β) [G.Loopless] (e : β) (x : α) : ¬ G.IsLoopAt e x := + Loopless.not_isLoopAt e x + +lemma not_adj_self (G : Graph α β) [G.Loopless] (x : α) : ¬ G.Adj x x := + fun ⟨e, he⟩ ↦ Loopless.not_isLoopAt e x he + +lemma Adj.ne [G.Loopless] (hxy : G.Adj u v) : u ≠ v := fun h ↦ G.not_adj_self u <| h ▸ hxy + +lemma IsLink.ne [G.Loopless] (he : G.IsLink e u v) : u ≠ v := Adj.ne ⟨e, he⟩ + +lemma loopless_iff_forall_ne_of_adj : G.Loopless ↔ ∀ u v, G.Adj u v → u ≠ v := + ⟨fun _ _ _ h ↦ h.ne, fun h ↦ ⟨fun _ x hex ↦ h x x hex.adj rfl⟩⟩ + +lemma vertexSet_nontrivial_of_edgeSet_nonempty_of_loopless [G.Loopless] (hE : E(G).Nonempty) : + V(G).Nontrivial := by + obtain ⟨e, he⟩ := hE + obtain ⟨x, y, hxy⟩ := exists_isLink_of_mem_edgeSet he + exact ⟨x, hxy.left_mem, y, hxy.right_mem, hxy.adj.ne⟩ + +lemma Loopless.anti [hG : G.Loopless] (hle : H ≤ G) : H.Loopless := by + rw [loopless_iff_forall_ne_of_adj] at hG ⊢ + exact fun x y hxy ↦ hG x y <| hxy.mono hle + +@[simp] +lemma Inc.isNonloopAt [G.Loopless] (h : G.Inc e u) : G.IsNonloopAt e u := + h.isLoopAt_or_isNonloopAt.resolve_left (Loopless.not_isLoopAt _ _) + +end Loopless + +section Simple + +/-- A `Simple` graph is a `Loopless` graph where no pair of vertices are the ends of more than one +edge. -/ +@[mk_iff] +class Simple (G : Graph α β) : Prop extends G.Loopless where + eq_of_isLink : ∀ ⦃e f x y⦄, G.IsLink e x y → G.IsLink f x y → e = f + +variable [G.Simple] + +lemma IsLink.eq (h : G.IsLink e u v) (h' : G.IsLink f u v) : e = f := + Simple.eq_of_isLink h h' + +lemma Simple.anti (hle : H ≤ G) : H.Simple where + not_isLoopAt e x := by simp [toLoopless.anti hle] + eq_of_isLink e f x y he hf := (he.mono hle).eq (hf.mono hle) + +instance (V : Set α) : (Graph.noEdge V β).Simple where + not_isLoopAt := by simp [IsLoopAt] + eq_of_isLink := by simp + +instance : (⊥ : Graph α β).Simple := inferInstanceAs (Graph.noEdge _ β).Simple + +end Simple + +section toSimpleGraph + +/-- Construct a simple graph from a graph. -/ +@[expose, simps (attr := grind =)] +def toSimpleGraph (G : Graph α β) : SimpleGraph V(G) where + Adj u v := u ≠ v ∧ G.Adj u v + symm := ⟨fun u v ↦ by grind [adj_comm]⟩ + +lemma toSimpleGraph_adj_iff [G.Loopless] (u v : V(G)) : G.toSimpleGraph.Adj u v ↔ G.Adj u v := by + grind [Adj.ne] + +lemma toSimpleGraph_mono (h : G ≤s H) : G.toSimpleGraph ≤ h.vertexSet_eq ▸ H.toSimpleGraph := by + rintro u v hadj + match G, H with + | ⟨GV, GL, GE, _, _, _, _⟩, ⟨HV, HL, HE, _, _, _, _⟩ => + obtain ⟨hne, hadj⟩ := toSimpleGraph_adj .. ▸ hadj + obtain ⟨hle, h⟩ := h + simp only at h + subst GV + simp [toSimpleGraph_adj, hne, hadj.mono hle] + +/-- Construct a graph from a simple graph. It has every element of the vertex type as a vertex. -/ +@[expose, simps (attr := grind =)] +def ofSimpleGraph (G : SimpleGraph α) : Graph α (Sym2 α) where + vertexSet := Set.univ + edgeSet := G.edgeSet + IsLink e x y := e = s(x, y) ∧ e ∈ G.edgeSet + isLink_symm e he := ⟨fun u v ↦ by simp [Sym2.eq_swap]⟩ + eq_or_eq_of_isLink_of_isLink e u v x y he hf := by grind + edge_mem_iff_exists_isLink e := by induction e with | h u v => grind + +@[simp] +lemma ofSimpleGraph_adj_iff {G : SimpleGraph α} (u v : α) : + (ofSimpleGraph G).Adj u v ↔ G.Adj u v := by simp [Adj] + +/-- The isomorphism between `toSimpleGraph (ofSimpleGraph G)` and `G`. -/ +def toSimpleGraphOfSimpleGraphIso (G : SimpleGraph α) : + (toSimpleGraph (ofSimpleGraph G)) ≃g G := by + use Equiv.Set.univ α + refine ⟨fun h ↦ ⟨fun h' ↦ h.ne (congrArg Subtype.val h'), ?_⟩, fun ⟨_, h⟩ ↦ ?_⟩ <;> + revert h <;> rw [ofSimpleGraph_adj_iff] <;> exact id + +end toSimpleGraph + +end Graph From bd913bfd965f710f91b813f79e2f8186f0d5346b Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:44:36 +0000 Subject: [PATCH 0969/1300] feat(Order/ConditionallyCompleteLattice/Indexed): `iSup_iSup_eq_{left/right}` for `ConditionallyCompleteLinearOrderBot` (#38856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and `≤` versions for `ConditionallyCompleteLattice`. --- Mathlib/Order/CompleteLattice/Basic.lean | 11 ++----- .../ConditionallyCompleteLattice/Indexed.lean | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Mathlib/Order/CompleteLattice/Basic.lean b/Mathlib/Order/CompleteLattice/Basic.lean index 9ac1a9e45d4ea7..41b80c78b11274 100644 --- a/Mathlib/Order/CompleteLattice/Basic.lean +++ b/Mathlib/Order/CompleteLattice/Basic.lean @@ -441,18 +441,11 @@ theorem iSup₂_comm {ι₁ ι₂ : Sort*} {κ₁ : ι₁ → Sort*} {κ₂ : ι @[to_dual (attr := simp)] theorem iSup_iSup_eq_left {b : β} {f : ∀ x : β, x = b → α} : ⨆ x, ⨆ h : x = b, f x h = f b rfl := - (le_iSup₂ (f := f) b rfl).antisymm' - (iSup_le fun c => - iSup_le <| by - rintro rfl - rfl) + le_antisymm (iSup₂_le fun _ h ↦ h ▸ le_rfl) (le_iSup₂ (f := f) b rfl) @[to_dual (attr := simp)] theorem iSup_iSup_eq_right {b : β} {f : ∀ x : β, b = x → α} : ⨆ x, ⨆ h : b = x, f x h = f b rfl := - (le_iSup₂ b rfl).antisymm' - (iSup₂_le fun c => by - rintro rfl - rfl) + le_antisymm (iSup₂_le fun _ h ↦ h ▸ le_refl (f b rfl)) (le_iSup₂ b rfl) @[to_dual] theorem iSup_subtype {p : ι → Prop} {f : Subtype p → α} : iSup f = ⨆ (i) (h : p i), f ⟨i, h⟩ := diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean index 9767efeee07a8a..c3f5582bb7a2bc 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean @@ -380,6 +380,26 @@ lemma ciInf_image {ι ι' : Type*} {s : Set ι} {f : ι → ι'} {g : ι' → α ⨅ i ∈ (f '' s), g i = ⨅ x ∈ s, g (f x) := ciSup_image (α := αᵒᵈ) hf hg' +theorem le_ciSup_ciSup_eq_left {b : β} {f : ∀ x : β, x = b → α} : + f b rfl ≤ ⨆ x, ⨆ h : x = b, f x h := by + refine le_ciSup₂ (f := f) ⟨f b rfl, ?_⟩ b rfl + rintro a ⟨_, ⟨b, rfl⟩, ⟨rfl, rfl⟩⟩ + rfl + +theorem ciInf_ciInf_eq_left_le {b : β} {f : ∀ x : β, x = b → α} : + ⨅ x, ⨅ h : x = b, f x h ≤ f b rfl := + le_ciSup_ciSup_eq_left (α := αᵒᵈ) + +theorem le_ciSup_ciSup_eq_right {b : β} {f : ∀ x : β, b = x → α} : + f b rfl ≤ ⨆ x, ⨆ h : b = x, f x h := by + refine le_ciSup₂ ⟨f b rfl, ?_⟩ b rfl + rintro a ⟨_, ⟨b, rfl⟩, ⟨rfl, rfl⟩⟩ + rfl + +theorem ciInf_ciInf_eq_right_le {b : β} {f : ∀ x : β, b = x → α} : + ⨅ x, ⨅ h : b = x, f x h ≤ f b rfl := + le_ciSup_ciSup_eq_right (α := αᵒᵈ) + /-- Note that equality need not hold: consider `ι := Bool, p := (·), α := ℤ, f := fun _ ↦ -1`, then the LHS is `-1` but the RHS is `-1 ⊔ sSup ∅ = -1 ⊔ 0 = 0`. -/ theorem ciSup_exists_le {p : ι → Prop} {f : Exists p → α} : ⨆ ih, f ih ≤ ⨆ (i) (h), f ⟨i, h⟩ := by @@ -553,6 +573,16 @@ theorem ciSup_exists {p : ι → Prop} {f : Exists p → α} : ⨆ ih, f ih = refine le_antisymm ciSup_exists_le <| ciSup_le' fun i ↦ ciSup_le' fun hi ↦ ?_ simp [show Exists p from ⟨i, hi⟩] +@[simp] +theorem ciSup_ciSup_eq_left {b : β} {f : ∀ x : β, x = b → α} : + ⨆ x, ⨆ h : x = b, f x h = f b rfl := + le_antisymm (ciSup_le' fun _ ↦ ciSup_le' (· ▸ le_rfl)) le_ciSup_ciSup_eq_left + +@[simp] +theorem ciSup_ciSup_eq_right {b : β} {f : ∀ x : β, b = x → α} : + ⨆ x, ⨆ h : b = x, f x h = f b rfl := + le_antisymm (ciSup_le' fun _ ↦ ciSup_le' (· ▸ le_refl (f b rfl))) le_ciSup_ciSup_eq_right + lemma ciSup_or' (p q : Prop) (f : p ∨ q → α) : ⨆ (h : p ∨ q), f h = (⨆ h : p, f (.inl h)) ⊔ ⨆ h : q, f (.inr h) := by by_cases hp : p <;> From aa96a837e258fa872ed7874be89a21d4e188a83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 23 Jul 2026 16:42:40 +0000 Subject: [PATCH 0970/1300] feat(RingTheory/MonoidAlgebra): `toAdditive` as a `BialgEquiv` (#41413) Also add a few missing lemmas about the less bundled versions, make variable names follow the local file convention and explicit a missing argument. Also unprotected `toMultiplicative` and `toAdditive` because I do not see any reason why these should have been protected in the first place. From Toric --- Mathlib/Algebra/MonoidAlgebra/Basic.lean | 40 ++++++++++++----- Mathlib/Algebra/MonoidAlgebra/MapDomain.lean | 38 +++++++++++----- .../RingTheory/Bialgebra/MonoidAlgebra.lean | 44 ++++++++++++++++++- Mathlib/RingTheory/FiniteType.lean | 4 +- 4 files changed, 101 insertions(+), 25 deletions(-) diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index 57fa8f1f929668..23fc281e997a9b 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -684,20 +684,36 @@ end AddMonoidAlgebra variable [CommSemiring R] [Semiring A] [Algebra R A] -set_option backward.isDefEq.respectTransparency false in -variable (A M) in +namespace AddMonoidAlgebra +variable [AddMonoid M] + +variable (R A M) in /-- The algebra equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of `Multiplicative`. -/ -def AddMonoidAlgebra.toMultiplicativeAlgEquiv [AddMonoid M] : - AddMonoidAlgebra A M ≃ₐ[R] MonoidAlgebra A (Multiplicative M) where - toRingEquiv := AddMonoidAlgebra.toMultiplicative A M - commutes' r := by simp [AddMonoidAlgebra.toMultiplicative] +@[simps!] +def toMultiplicativeAlgEquiv : AddMonoidAlgebra A M ≃ₐ[R] MonoidAlgebra A (Multiplicative M) where + toRingEquiv := toMultiplicative A M + commutes' r := by ext; simp -set_option backward.isDefEq.respectTransparency false in -variable (A M) in +@[simp] +lemma toMultiplicativeAlgEquiv_single (m : M) (a : A) : + toMultiplicativeAlgEquiv R A M (single m a) = .single (.ofAdd m) a := by ext; simp + +end AddMonoidAlgebra + +namespace MonoidAlgebra +variable [Monoid M] + +variable (R A M) in /-- The algebra equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive`. -/ -def MonoidAlgebra.toAdditiveAlgEquiv [Monoid M] : - MonoidAlgebra A M ≃ₐ[R] AddMonoidAlgebra A (Additive M) where - toRingEquiv := MonoidAlgebra.toAdditive A M - commutes' r := by simp [MonoidAlgebra.toAdditive] +@[simps!] +def toAdditiveAlgEquiv : MonoidAlgebra A M ≃ₐ[R] AddMonoidAlgebra A (Additive M) where + toRingEquiv := toAdditive A M + commutes' r := by simp [toAdditive] + +@[simp] +lemma toAdditiveAlgEquiv_single (m : M) (a : A) : + toAdditiveAlgEquiv R A M (single m a) = .single (.ofMul m) a := by ext; simp + +end MonoidAlgebra diff --git a/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean b/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean index 6ae7e4da44424a..36186ecbe9f128 100644 --- a/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean +++ b/Mathlib/Algebra/MonoidAlgebra/MapDomain.lean @@ -486,12 +486,15 @@ end MonoidAlgebra #### Conversions between `AddMonoidAlgebra` and `MonoidAlgebra` -/ +namespace AddMonoidAlgebra +variable [Semiring R] [Add M] + set_option backward.isDefEq.respectTransparency false in -variable (k G) in +variable (R M) in /-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of `Multiplicative` -/ -protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] : - AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) where +@[simps] +def toMultiplicative : AddMonoidAlgebra R M ≃+* MonoidAlgebra R (Multiplicative M) where toFun x := .ofCoeff <| x.coeff.mapDomain .ofAdd invFun x := .ofCoeff <| x.coeff.mapDomain Multiplicative.toAdd left_inv x := by ext; simp @@ -500,14 +503,23 @@ protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] : map_mul' x y := by classical ext - simp [MonoidAlgebra.coeff_mul, AddMonoidAlgebra.coeff_mul, Finsupp.sum_mapDomain_index, add_mul, - mul_add, ite_add_zero, Multiplicative.ext_iff] + simp [MonoidAlgebra.coeff_mul, coeff_mul, sum_mapDomain_index, add_mul, mul_add, ite_add_zero, + Multiplicative.ext_iff] + +@[simp] +lemma toMultiplicative_single (m : M) (r : R) : + toMultiplicative R M (single m r) = .single (.ofAdd m) r := by simp [toMultiplicative] + +end AddMonoidAlgebra + +namespace MonoidAlgebra +variable [Semiring R] [Mul M] set_option backward.isDefEq.respectTransparency false in -variable (k G) in +variable (R M) in /-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/ -protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] : - MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) where +@[simps] +def toAdditive : MonoidAlgebra R M ≃+* AddMonoidAlgebra R (Additive M) where toFun x := .ofCoeff <| x.coeff.mapDomain .ofMul invFun x := .ofCoeff <| x.coeff.mapDomain Additive.toMul left_inv x := by ext; simp @@ -516,5 +528,11 @@ protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] : map_mul' x y := by classical ext - simp [MonoidAlgebra.coeff_mul, AddMonoidAlgebra.coeff_mul, Finsupp.sum_mapDomain_index, add_mul, - mul_add, ite_add_zero, Additive.ext_iff] + simp [coeff_mul, AddMonoidAlgebra.coeff_mul, sum_mapDomain_index, add_mul, mul_add, + ite_add_zero, Additive.ext_iff] + +@[simp] +lemma toAdditive_single (m : M) (r : R) : toAdditive R M (single m r) = .single (.ofMul m) r := by + ext; simp + +end MonoidAlgebra diff --git a/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean index 9dbe2b156ccb53..f1f82a6b59b6c7 100644 --- a/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean @@ -5,7 +5,7 @@ Authors: Amelia Livingston, Yaël Dillies, Michał Mrugała -/ module -public import Mathlib.RingTheory.Bialgebra.Hom +public import Mathlib.RingTheory.Bialgebra.Equiv public import Mathlib.RingTheory.Coalgebra.MonoidAlgebra /-! @@ -87,6 +87,48 @@ lemma mapDomainBialgHom_mapDomainBialgHom (f : N →* O) (g : M →* N) (x : R[M end MonoidAlgebra +namespace AddMonoidAlgebra +variable [CommSemiring R] [Semiring A] [Bialgebra R A] [AddMonoid M] + +variable (R A M) in +/-- The bialgebra equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of +`Multiplicative`. -/ +-- TODO: Make `BialgEquiv.toCoalgEquiv` the simp normal form so that this can be simp +@[simps! -isSimp] +def toMultiplicativeBialgEquiv : A[M] ≃ₐc[R] MonoidAlgebra A (Multiplicative M) := + .ofAlgEquiv (toMultiplicativeAlgEquiv R A M) (by ext <;> simp) <| by + ext a + · simp [Algebra.TensorProduct.one_def] + · simp [← (Coalgebra.Repr.arbitrary R a).eq] + +@[simp] +lemma toMultiplicativeBialgEquiv_single (m : M) (a : A) : + toMultiplicativeBialgEquiv R A M (single m a) = .single (.ofAdd m) a := by + simp [toMultiplicativeBialgEquiv] + +end AddMonoidAlgebra + +namespace MonoidAlgebra +variable [CommSemiring R] [Semiring A] [Bialgebra R A] [Monoid M] + +variable (R A M) in +/-- The bialgebra equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of +`Additive`. -/ +-- TODO: Make `BialgEquiv.toCoalgEquiv` the simp normal form so that this can be simp +@[simps! -isSimp] +def toAdditiveBialgEquiv : A[M] ≃ₐc[R] AddMonoidAlgebra A (Additive M) := + .ofAlgEquiv (toAdditiveAlgEquiv R A M) (by ext <;> simp) <| by + ext a + · simp [Algebra.TensorProduct.one_def] + · simp [← (Coalgebra.Repr.arbitrary R a).eq] + +@[simp] +lemma toAdditiveBialgEquiv_single (m : M) (a : A) : + toAdditiveBialgEquiv R A M (single m a) = .single (.ofMul m) a := by + simp [toAdditiveBialgEquiv] + +end MonoidAlgebra + namespace LaurentPolynomial open AddMonoidAlgebra diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index 0e3083e6021af4..1ba1ee31b36601 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -577,12 +577,12 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} /-- If a monoid `M` is finitely generated then `R[M]` is of finite type. -/ instance finiteType_of_fg [CommRing R] [Monoid.FG M] : FiniteType R R[M] := - (AddMonoidAlgebra.finiteType_of_fg R (Additive M)).equiv (toAdditiveAlgEquiv R M).symm + (AddMonoidAlgebra.finiteType_of_fg R (Additive M)).equiv (toAdditiveAlgEquiv R R M).symm /-- A monoid `M` is finitely generated if and only if `R[M]` is of finite type. -/ theorem finiteType_iff_fg [CommRing R] [Nontrivial R] : FiniteType R R[M] ↔ Monoid.FG M where mp h := Monoid.fg_iff_add_fg.2 <| - AddMonoidAlgebra.finiteType_iff_fg.1 <| h.equiv <| toAdditiveAlgEquiv R M + AddMonoidAlgebra.finiteType_iff_fg.1 <| h.equiv <| toAdditiveAlgEquiv R R M mpr _ := inferInstance /-- If `R[M]` is of finite type then `M` is finitely generated. -/ From 3f102b58baed7d73426a25cd6bac6b5463d549a4 Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:50:06 +0000 Subject: [PATCH 0971/1300] feat: products of bases of Lie algebras (#41971) If two Lie algebras have bases with matching Cartan matrices, then they are isomorphic. --- Mathlib.lean | 1 + Mathlib/Algebra/Lie/Basis/Basic.lean | 3 +- Mathlib/Algebra/Lie/Basis/Prod.lean | 309 ++++++++++++++++++++++ Mathlib/Algebra/Lie/Prod.lean | 6 + Mathlib/Algebra/Lie/Semisimple/Basic.lean | 7 + Mathlib/Algebra/Lie/Subalgebra.lean | 18 ++ Mathlib/Algebra/Module/Submodule/Ker.lean | 5 + Mathlib/Algebra/Module/Submodule/Map.lean | 7 + 8 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Algebra/Lie/Basis/Prod.lean diff --git a/Mathlib.lean b/Mathlib.lean index efb85f00c55e2d..638124f2103e51 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -721,6 +721,7 @@ public import Mathlib.Algebra.Lie.Basic public import Mathlib.Algebra.Lie.Basis public import Mathlib.Algebra.Lie.Basis.Base public import Mathlib.Algebra.Lie.Basis.Basic +public import Mathlib.Algebra.Lie.Basis.Prod public import Mathlib.Algebra.Lie.CartanCriterion public import Mathlib.Algebra.Lie.CartanExists public import Mathlib.Algebra.Lie.CartanSubalgebra diff --git a/Mathlib/Algebra/Lie/Basis/Basic.lean b/Mathlib/Algebra/Lie/Basis/Basic.lean index a9c18c8033098a..0b0ee9794e0536 100644 --- a/Mathlib/Algebra/Lie/Basis/Basic.lean +++ b/Mathlib/Algebra/Lie/Basis/Basic.lean @@ -5,7 +5,8 @@ Authors: Oliver Nash -/ module -public import Mathlib.Algebra.Lie.Weights.Killing +public import Mathlib.Algebra.Lie.Sl2 +public import Mathlib.Algebra.Lie.Weights.Cartan /-! # Bases of semisimple Lie algebras diff --git a/Mathlib/Algebra/Lie/Basis/Prod.lean b/Mathlib/Algebra/Lie/Basis/Prod.lean new file mode 100644 index 00000000000000..70df65bc073ea7 --- /dev/null +++ b/Mathlib/Algebra/Lie/Basis/Prod.lean @@ -0,0 +1,309 @@ +/- +Copyright (c) 2026 Oliver Nash. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Oliver Nash +-/ +module + +public import Mathlib.Algebra.Lie.Basis.Basic +public import Mathlib.Algebra.Lie.Prod +public import Mathlib.Algebra.Lie.Semisimple.Basic + +/-! +# Products of bases Lie algebras + +Given two finite-dimensional simple Lie algebras, if they admit bases with matching Cartan matrices, +they must be isomorphic. This file provides a proof of this as `LieAlgebra.Basis.equivOfReindex`. + +-/ + +noncomputable section + +namespace LieAlgebra.Basis + +open Function LieSubalgebra Set Submodule + +variable {ι₁ ι₂ L₁ L₂ : Type*} [Finite ι₁] [Finite ι₂] (eι : ι₁ ≃ ι₂) [LieRing L₁] [LieRing L₂] + +section CommRing + +variable {R : Type*} [CommRing R] + [LieAlgebra R L₁] {H₁ : LieSubalgebra R L₁} (b₁ : Basis ι₁ H₁) + [LieAlgebra R L₂] {H₂ : LieSubalgebra R L₂} (b₂ : Basis ι₂ H₂) + +/-- A distinguished subalgebra of the product of two based Lie algebras with equivalent indexing +sets. -/ +protected def prod : + LieSubalgebra R (L₁ × L₂) := + .lieSpan _ _ <| + {(b₁.h i, b₂.h (eι i)) | i : ι₁} ∪ + {(b₁.e i, b₂.e (eι i)) | i : ι₁} ∪ + {(b₁.f i, b₂.f (eι i)) | i : ι₁} + +/-- The equivalence obtained by interchanging the two bases consumed by `LieAlgebra.Basis.prod`. -/ +def prodSymmEquiv : prod eι.symm b₂ b₁ ≃ₗ⁅R⁆ b₁.prod eι b₂ := + have : (prod eι.symm b₂ b₁).map (LieEquiv.prodComm R L₂ L₁) = b₁.prod eι b₂ := by + rw [prod, prod, map_lieSpan]; congr; ext; aesop + (LieEquiv.lieSubalgebraMap (prod eι.symm b₂ b₁) (LieEquiv.prodComm _ _ _)).trans + (LieEquiv.ofEq _ _ <| by simpa) + +@[simp] +lemma prodSymmEquiv_symm_apply {y : b₁.prod eι b₂} : + (prodSymmEquiv eι b₁ b₂).symm y = + ⟨((y : L₁ × L₂).snd, (y : L₁ × L₂).fst), ((prodSymmEquiv eι b₁ b₂).symm y).property⟩ := + rfl + +lemma h_mem_prod (i : ι₁) : + (b₁.h i, b₂.h (eι i)) ∈ b₁.prod eι b₂ := + subset_lieSpan <| by aesop + +/-- A distinguished subalgebra of the Lie algebra defined by `LieAlgebra.Basis.prod`. + +Subject to the assumtions demanded by `LieAlgebra.Basis.isCartanSubalgebra` this will be a Cartan +subalgebra of `LieAlgebra.Basis.prod`. -/ +def prodCartan : + LieSubalgebra R (prod eι b₁ b₂) := + .lieSpan _ _ {⟨(b₁.h i, b₂.h (eι i)), h_mem_prod eι b₁ b₂ i⟩ | i : ι₁} + +open Finsupp in +lemma prodCartanEquiv_aux : + InjOn (LinearMap.fst R L₁ L₂) (span R {(b₁.h i, b₂.h (eι i)) | i : ι₁}) := by + suffices ∀ y, (∃ l : ι₁ →₀ R, + (l.linearCombination R fun i ↦ (b₁.h i, b₂.h (eι i))) = (0, y)) → y = 0 by + have aux : {(b₁.h i, b₂.h (eι i)) | i : ι₁} = (fun i : ι₁ ↦ (b₁.h i, b₂.h (eι i))) '' univ := by + ext; simp + simp_rw [← LinearMap.disjoint_ker_iff_injOn, LinearMap.disjoint_ker, aux, + mem_span_image_iff_linearCombination] + aesop + intro y ⟨f, hf⟩ + suffices linearCombination R b₁.h f = 0 by + rw [LinearMap.map_eq_zero_iff _ b₁.linInd] at this + aesop (add simp Prod.ext_iff) + replace hf := (LinearMap.fst R L₁ L₂).congr_arg hf + rw [← LinearMap.comp_apply, ← Finsupp.linearCombination_linear_comp] at hf + aesop + +open LinearMap in +/-- The Lie subalgebra `LieAlgebra.Basis.prod` is a copy of the Cartan subalgebra of the input. -/ +def prodCartanEquiv : + prodCartan eι b₁ b₂ ≃ₗ[R] H₁ := + /- Informally this is obvious since `prodCartan eι b₁ b₂` is the linear span of + `{(b₁.h i, b₂.h (eι i)) | i : ι₁}` and `H₁` is the linear span of `{b₁.h i | i : ι₁}` (and both + families are linearly independent) but formally some care is required. -/ + have h₁ : (prodCartan eι b₁ b₂).map (prod eι b₁ b₂).incl = + (lieSpan R (L₁ × L₂) {(b₁.h i, b₂.h (eι i)) | i : ι₁} : Set (L₁ × L₂)) := by + rw [prodCartan, map_lieSpan]; congr; aesop + have h₂ : (lieSpan R _ {(b₁.h i, b₂.h (eι i)) | i : ι₁}) = + span R {(b₁.h i, b₂.h (eι i)) | i : ι₁} := + coe_lieSpan_eq_span_of_forall_lie_eq_zero <| by simp [b₁.lie_h_h, b₂.lie_h_h] + have h₃ : (span R {(b₁.h i, b₂.h (eι i)) | i : ι₁}).map (.fst R L₁ L₂) = span R (range b₁.h) := by + rw [Submodule.map_span]; congr; ext; simp + have h₄ : lieSpan R L₁ (range b₁.h) = span R (range b₁.h) := by + rw [← b₁.coe_cartan_eq_span, toSubmodule_inj, ← b₁.cartan_eq_lieSpan] + have h₅ : (H₁ : Set L₁) = lieSpan R L₁ (range b₁.h) := by simp [b₁.cartan_eq_lieSpan] + let e₀ : prodCartan eι b₁ b₂ ≃ₗ[R] (prodCartan eι b₁ b₂).map (prod eι b₁ b₂).incl := + (prodCartan eι b₁ b₂).equivMapOfInjective (prod eι b₁ b₂).incl <| by simp + let e₁ : (prodCartan eι b₁ b₂).map (prod eι b₁ b₂).incl ≃ₗ[R] + lieSpan R (L₁ × L₂) {(b₁.h i, b₂.h (eι i)) | i : ι₁} := LieEquiv.ofEq _ _ h₁ + let e₂ : lieSpan R (L₁ × L₂) {(b₁.h i, b₂.h (eι i)) | i : ι₁} ≃ₗ[R] + span R {(b₁.h i, b₂.h (eι i)) | i : ι₁} := LinearEquiv.ofEq _ _ h₂ + let e₃ : span R {(b₁.h i, b₂.h (eι i)) | i : ι₁} ≃ₗ[R] span R (range b₁.h) := + (LinearEquiv.ofBijective _ ⟨submoduleMap_injective_of_injOn (prodCartanEquiv_aux eι b₁ b₂), + submoduleMap_surjective _ _⟩).trans <| .ofEq _ _ h₃ + let e₄ : span R (range b₁.h) ≃ₗ[R] lieSpan R L₁ (range b₁.h) := LinearEquiv.ofEq _ _ h₄.symm + let e₅ : lieSpan R L₁ (range b₁.h) ≃ₗ[R] H₁ := (LieEquiv.ofEq _ _ h₅).symm + e₀.trans <| e₁.trans <| e₂.trans <| e₃.trans <| e₄.trans e₅ + +protected abbrev prodH (i : ι₁) : b₁.prod eι b₂ := + ⟨(b₁.h i, b₂.h (eι i)), subset_lieSpan <| by aesop⟩ + +protected abbrev prodE (i : ι₁) : b₁.prod eι b₂ := + ⟨(b₁.e i, b₂.e (eι i)), subset_lieSpan <| by aesop⟩ + +protected abbrev prodF (i : ι₁) : b₁.prod eι b₂ := + ⟨(b₁.f i, b₂.f (eι i)), subset_lieSpan <| by aesop⟩ + +lemma basisProd_aux : + lieSpan R (prod eι b₁ b₂) (range (prodE eι b₁ b₂) ∪ range (prodF eι b₁ b₂)) = ⊤ := by + suffices lieSpan R (prod eι b₁ b₂) (range (prodE eι b₁ b₂) ∪ range (prodF eι b₁ b₂)) = + lieSpan R (prod eι b₁ b₂) + (range (prodH eι b₁ b₂) ∪ range (prodE eι b₁ b₂) ∪ range (prodF eι b₁ b₂)) by + have hr : range (prodH eι b₁ b₂) ∪ range (prodE eι b₁ b₂) ∪ range (prodF eι b₁ b₂) = + Subtype.val ⁻¹' ( {(b₁.h i, b₂.h (eι i)) | i : ι₁} ∪ + {(b₁.e i, b₂.e (eι i)) | i : ι₁} ∪ + {(b₁.f i, b₂.f (eι i)) | i : ι₁} ) := by + ext; simp [Subtype.ext_iff] + rw [this, hr] + exact lieSpan_lieSpan_coe_preimage + simp only [union_assoc] + refine le_antisymm (lieSpan_mono <| by simp) (lieSpan_le.mpr <| union_subset ?_ subset_lieSpan) + rintro - ⟨i, rfl⟩ + have hef : prodH eι b₁ b₂ i = ⁅prodE eι b₁ b₂ i, prodF eι b₁ b₂ i⁆ := by + simp [Subtype.ext_iff, (b₁.sl2 i).lie_e_f, (b₂.sl2 (eι i)).lie_e_f] + rw [hef] + apply lie_mem + · exact subset_lieSpan <| mem_union_left _ <| mem_range_self i + · exact subset_lieSpan <| mem_union_right _ <| mem_range_self i + +/-- A distinguished basis carried by `LieAlgebra.Basis.prod`. -/ +def basisProd (hA : b₁.A.reindex eι eι = b₂.A) : + Basis ι₁ (prodCartan eι b₁ b₂) where + A := b₁.A + h := prodH eι b₁ b₂ + e := prodE eι b₁ b₂ + f := prodF eι b₁ b₂ + cartan_eq_lieSpan := rfl + span_ef := b₁.basisProd_aux eι b₂ + linInd := .of_comp (prod eι b₁ b₂).subtype <| .of_comp (LinearMap.fst R L₁ L₂) b₁.linInd + nondegen := b₁.nondegen + sl2 i := + { h_ne_zero := by simp [Subtype.ext_iff, (b₁.sl2 i).h_ne_zero] + lie_e_f := by simp [Subtype.ext_iff, (b₁.sl2 i).lie_e_f, (b₂.sl2 (eι i)).lie_e_f] + lie_h_e_nsmul := by + simp [Subtype.ext_iff, (b₁.sl2 i).lie_h_e_nsmul, (b₂.sl2 (eι i)).lie_h_e_nsmul] + lie_h_f_nsmul := by + simp [Subtype.ext_iff, (b₁.sl2 i).lie_h_f_nsmul, (b₂.sl2 (eι i)).lie_h_f_nsmul] } + lie_h_h i j := by simp [Subtype.ext_iff, b₁.lie_h_h, b₂.lie_h_h] + lie_h_e i j := by simp [Subtype.ext_iff, b₁.lie_h_e, b₂.lie_h_e, ← hA] + lie_h_f i j := by simp [Subtype.ext_iff, b₁.lie_h_f, b₂.lie_h_f, ← hA] + lie_e_f_ne i j hij := by + have hij' : eι i ≠ eι j := by aesop + simp [Subtype.ext_iff, b₁.lie_e_f_ne i j hij, b₂.lie_e_f_ne _ _ hij'] + +lemma surjective_fst_prod : + Surjective ((LieHom.fst R L₁ L₂).comp (prod eι b₁ b₂).incl) := by + set L : LieSubalgebra R (L₁ × L₂) := b₁.prod eι b₂ + set p₁ : L →ₗ⁅R⁆ L₁ := (LieHom.fst R L₁ L₂).comp L.incl + have h₁ : range b₁.e = range (p₁ ∘ prodE eι b₁ b₂) := rfl + have h₂ : range b₁.f = range (p₁ ∘ prodF eι b₁ b₂) := rfl + rw [← LieHom.range_eq_top, eq_top_iff, ← b₁.span_ef, map_top, ← b₁.basisProd_aux eι b₂, + map_lieSpan, image_union, h₁, h₂] + simp [range_comp] + +lemma surjective_snd_prod : + Surjective ((LieHom.snd R L₁ L₂).comp (prod eι b₁ b₂).incl) := by + set L : LieSubalgebra R (L₁ × L₂) := b₁.prod eι b₂ + set p₂ : L →ₗ⁅R⁆ L₂ := (LieHom.snd R L₁ L₂).comp L.incl + have h₁ : range b₂.e = range (p₂ ∘ prodE eι b₁ b₂) := by + simp [show p₂ ∘ prodE eι b₁ b₂ = b₂.e ∘ eι from rfl] + have h₂ : range b₂.f = range (p₂ ∘ prodF eι b₁ b₂) := by + simp [show p₂ ∘ prodF eι b₁ b₂ = b₂.f ∘ eι from rfl] + rw [← LieHom.range_eq_top, eq_top_iff, ← b₂.span_ef, map_top, + ← b₁.basisProd_aux eι b₂, map_lieSpan, image_union, h₁, h₂] + simp [range_comp] + +lemma lie_fst_eq_zero_of_mem_prodCartan + {y : b₁.prod eι b₂} (hy : y ∈ prodCartan eι b₁ b₂) (x : H₁) : + ⁅(y : L₁ × L₂).fst, (x : L₁)⁆ = 0 := by + have := b₁.isLieAbelian_cartan + induction hy using lieSpan_induction with + | mem u hu => + obtain ⟨i, rfl⟩ := hu + suffices ⁅b₁.h' i, x⁆ = 0 by simpa [Subtype.ext_iff, Basis.h'] using this + apply trivial_lie_zero + | zero => simp + | add u v hu hv hu' hv' => simp [hu', hv'] + | smul t u hu hu' => simp [hu'] + | lie u v hu hv hu' hv' => simp [hu', hv'] + +lemma lie_snd_eq_zero_of_mem_prodCartan + {y : b₁.prod eι b₂} (hy : y ∈ prodCartan eι b₁ b₂) (x : H₂) : + ⁅(y : L₁ × L₂).snd, (x : L₂)⁆ = 0 := by + suffices (prodSymmEquiv eι b₁ b₂).symm y ∈ prodCartan eι.symm b₂ b₁ from + lie_fst_eq_zero_of_mem_prodCartan eι.symm b₂ b₁ this x + replace hy : + (prodSymmEquiv eι b₁ b₂).symm y ∈ (prodCartan eι b₁ b₂).map (prodSymmEquiv eι b₁ b₂).symm := + mem_image_of_mem (prodSymmEquiv eι b₁ b₂).symm hy + rw [prodCartan, map_lieSpan] at hy + rw [prodCartan] + convert hy + ext; simp; grind + +end CommRing + +section Field + +variable {K : Type*} [Field K] [CharZero K] + [LieAlgebra K L₁] [FiniteDimensional K L₁] {H₁ : LieSubalgebra K L₁} (b₁ : Basis ι₁ H₁) + [LieAlgebra K L₂] [FiniteDimensional K L₂] {H₂ : LieSubalgebra K L₂} (b₂ : Basis ι₂ H₂) + (hA : b₁.A.reindex eι eι = b₂.A) +include hA + +lemma prod_lt_top [Nontrivial L₂] : + b₁.prod eι b₂ < ⊤ := by + /- This innocent-looking result is the key. The informal literature seems only to contain + somewhat heavy-weight proofs (e.g., [Chapter IV, Theorem 14.2](humphreys1972) makes an + inductive argument using highest weights) but in fact it follows very easily from + `LieAlgebra.Basis.isCartanSubalgebra`. The argument is essentially: if `b₁.prod eι b₂` is not + proper then it's Cartan subalgebra contains `H₁ × H₂` which is absurd since it + `LieAlgebra.Basis.prodCartanEquiv` tells us it is equivalent to `H₁`. -/ + have := Fintype.ofFinite ι₁ + have := Fintype.ofFinite ι₂ + have := b₁.isCartanSubalgebra + have := b₂.isCartanSubalgebra + have := (basisProd eι b₁ b₂ hA).isCartanSubalgebra + rw [lt_top_iff_ne_top] + intro contra + have (x : H₁ × H₂) (hx) : ⟨(x.1, x.2), hx⟩ ∈ prodCartan eι b₁ b₂ := by + rw [← mem_toLieSubmodule, ← rootSpace_zero_eq, LieModule.mem_genWeightSpace] + refine fun ⟨y, hy⟩ ↦ ⟨1, ?_⟩ + simpa [Subtype.ext_iff] using ⟨lie_fst_eq_zero_of_mem_prodCartan eι b₁ b₂ hy x.fst, + lie_snd_eq_zero_of_mem_prodCartan eι b₁ b₂ hy x.snd⟩ + let f : H₁ × H₂ →ₗ[K] prodCartan eι b₁ b₂ := + { toFun x := ⟨⟨⟨x.fst, x.snd⟩, by simp [contra]⟩, this x _⟩ + map_add' := by simp + map_smul' := by simp } + have f_inj : Injective f := fun x y h ↦ by simpa [Prod.ext_iff, f] using h + let g : H₁ × H₂ →ₗ[K] H₁ := (prodCartanEquiv eι b₁ b₂) ∘ₗ f + have hg₁ : Injective g := by simpa [g] + obtain ⟨x₂ : H₂, hx₂ : x₂ ≠ 0⟩ := exists_ne (0 : H₂) + have hg₂ : g (0, x₂) = g (0, 0) := rfl + aesop + +variable [IsSimple K L₁] [IsSimple K L₂] + +/-- `LieAlgebra.Basis.prod` is equivalent to its left input algebra. -/ +def prodEquivLeft : + b₁.prod eι b₂ ≃ₗ⁅K⁆ L₁ := + let L : LieSubalgebra K (L₁ × L₂) := b₁.prod eι b₂ + let p₁ : L →ₗ⁅K⁆ L₁ := (LieHom.fst K L₁ L₂).comp L.incl + have : Injective p₁ := by + let p₂ : L →ₗ⁅K⁆ L₂ := (LieHom.snd K L₁ L₂).comp L.incl + have disj : Disjoint p₁.ker p₂.ker := by + rw [disjoint_iff, _root_.eq_bot_iff] + rintro ⟨⟨x, y⟩, -⟩ + simp [p₁, p₂, Subtype.ext_iff] + set I₁ : LieIdeal K L₂ := p₁.ker.map p₂ + suffices I₁ ≠ ⊤ by + replace this := (IsSimple.eq_bot_or_eq_top I₁).resolve_right this + rw [LieIdeal.map_eq_bot_iff] at this + rw [← p₁.ker_eq_bot, disj.eq_bot_of_le this] + have : Nontrivial L₂ := IsSimple.nontrivial K L₂ + have := (prod_lt_top eι b₁ b₂ hA).ne + contrapose this + have hI₁ : (I₁ : Set L₂) = p₂ '' p₁.ker := + congr_arg SetLike.coe <| p₁.ker.coe_map_of_surjective (surjective_snd_prod eι b₁ b₂) + have hL₂ (x₂ : L₂) : (0, x₂) ∈ L := by + replace this : x₂ ∈ (I₁ : Set L₂) := by simp [this] + simpa [p₂, p₁, hI₁] using this + have hL₁ (x₁ : L₁) : (x₁, 0) ∈ L := by + obtain ⟨⟨⟨-, y⟩, hy⟩, rfl⟩ : x₁ ∈ range p₁ := mem_range.mpr (surjective_fst_prod eι b₁ b₂ x₁) + simpa [p₁] using sub_mem hy (hL₂ y) + rw [eq_top_iff] + rintro ⟨x₁, x₂⟩ - + simpa using add_mem (hL₁ x₁) (hL₂ x₂) + .ofBijective p₁ ⟨this, surjective_fst_prod eι b₁ b₂⟩ + +/-- `LieAlgebra.Basis.prod` is equivalent to its right input algebra. -/ +def prodEquivRight : + b₁.prod eι b₂ ≃ₗ⁅K⁆ L₂ := + (prodSymmEquiv eι b₁ b₂).symm.trans (prodEquivLeft eι.symm b₂ b₁ <| by simp [← hA]) + +/-- Simple Lie algebras with equivalent bases are equivalent. -/ +public def equivOfReindex : + L₁ ≃ₗ⁅K⁆ L₂ := + (prodEquivLeft eι b₁ b₂ hA).symm.trans (prodEquivRight eι b₁ b₂ hA) + +end Field + +end LieAlgebra.Basis diff --git a/Mathlib/Algebra/Lie/Prod.lean b/Mathlib/Algebra/Lie/Prod.lean index ad29ba43b02a3e..d7c96694a62254 100644 --- a/Mathlib/Algebra/Lie/Prod.lean +++ b/Mathlib/Algebra/Lie/Prod.lean @@ -209,4 +209,10 @@ theorem prodMap_zero : (0 : L₁ →ₗ⁅R⁆ L₃).prodMap (0 : L₂ →ₗ⁅ end LieHom +variable (R L₁ L₂) in +/-- The map `(x, y) ↦ (y, x)` as a Lie equivalence. -/ +@[simps!] def LieEquiv.prodComm : (L₁ × L₂) ≃ₗ⁅R⁆ L₂ × L₁ where + __ := LinearEquiv.prodComm R L₁ L₂ + map_lie' := by simp + end diff --git a/Mathlib/Algebra/Lie/Semisimple/Basic.lean b/Mathlib/Algebra/Lie/Semisimple/Basic.lean index 85a7ece2121e54..8775195af3224d 100644 --- a/Mathlib/Algebra/Lie/Semisimple/Basic.lean +++ b/Mathlib/Algebra/Lie/Semisimple/Basic.lean @@ -87,6 +87,13 @@ instance : LieModule.IsIrreducible R L L := by contrapose _i infer_instance +include R in +/-- A simple lie algebra is non-trivial. -/ +lemma nontrivial : Nontrivial L := by + have := IsSimple.non_abelian R (L := L) + contrapose! this + infer_instance + protected lemma isAtom_top : IsAtom (⊤ : LieIdeal R L) := isAtom_top variable {R L} in diff --git a/Mathlib/Algebra/Lie/Subalgebra.lean b/Mathlib/Algebra/Lie/Subalgebra.lean index c7c82acb21f2f7..08df1c027dd3e2 100644 --- a/Mathlib/Algebra/Lie/Subalgebra.lean +++ b/Mathlib/Algebra/Lie/Subalgebra.lean @@ -376,6 +376,15 @@ def comap : LieSubalgebra R L := @[simp] lemma mem_comap {x : L} : x ∈ K₂.comap f ↔ f x ∈ K₂ := Iff.rfl +/-- A Lie subalgebra is equivalent to its push forward along an injective linear map. -/ +@[simps!] noncomputable def equivMapOfInjective (hf : Function.Injective f) : + K ≃ₗ⁅R⁆ K.map f where + __ := Submodule.equivMapOfInjective f.toLinearMap hf K + map_lie' {x y} := by + ext + change f ⁅(x : L), (y : L)⁆ = ⁅f (x : L), f (y : L)⁆ + simp + section LatticeStructure open Set @@ -542,6 +551,8 @@ variable (R L) instance wellFoundedGT_of_noetherian [IsNoetherian R L] : WellFoundedGT (LieSubalgebra R L) := RelHomClass.isWellFounded (⟨toSubmodule, @fun _ _ h ↦ h⟩ : _ →r (· > ·)) +theorem map_top : f.range = LieSubalgebra.map f ⊤ := by ext; simp + variable {R L K K' f} section NestedSubalgebras @@ -670,6 +681,13 @@ theorem coe_lieSpan_eq_span_of_forall_lie_eq_zero | smul_left r x y _ _ h => simp [smul_mem _ r h] | smul_right r x y _ _ h => simp [smul_mem _ r h] +theorem map_lieSpan : + (lieSpan R L s).map f = lieSpan R L₂ (f '' s) := by + refine le_antisymm ?_ (lieSpan_le.mpr <| Set.image_mono subset_lieSpan) + rw [map_le_iff_le_comap, lieSpan_le] + change s ⊆ f ⁻¹' (lieSpan R L₂ (f '' s)) + exact image_subset_iff.mp <| subset_lieSpan + variable (R L) /-- `lieSpan` forms a Galois insertion with the coercion from `LieSubalgebra` to `Set`. -/ diff --git a/Mathlib/Algebra/Module/Submodule/Ker.lean b/Mathlib/Algebra/Module/Submodule/Ker.lean index edc703d483c836..37a58fe84bf4cf 100644 --- a/Mathlib/Algebra/Module/Submodule/Ker.lean +++ b/Mathlib/Algebra/Module/Submodule/Ker.lean @@ -164,6 +164,11 @@ def iterateKer (f : M →ₗ[R] M) : ℕ →o Submodule R M where rw [LinearMap.mem_ker] at h rw [LinearMap.mem_ker, add_comm, pow_add, Module.End.mul_apply, h, map_zero] +lemma ker_submoduleMap {τ₂₁ : R₂ →+* R} [RingHomInvPair τ₁₂ τ₂₁] + (f : M →ₛₗ[τ₁₂] M₂) (p : Submodule R M) : + (f.submoduleMap p).ker = f.ker.comap p.subtype := by + ext; simp [Subtype.ext_iff] + end AddCommMonoid section Ring diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 87b6047a2a4e44..bb3e5df6eb879d 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -675,6 +675,13 @@ theorem submoduleMap_injective [RingHomSurjective σ₁₂] {f : M →ₛₗ[σ (p : Submodule R M) : Injective (f.submoduleMap p) := f.toAddMonoidHom.addSubmonoidMap_injective hf _ +theorem submoduleMap_injective_of_injOn [RingHomSurjective σ₁₂] + {p : Submodule R M} {f : M →ₛₗ[σ₁₂] M₂} (hf : Set.InjOn f p) : + Injective (f.submoduleMap p) := by + intro ⟨x, hx⟩ ⟨y, hy⟩ hxy + replace hxy : f x = f y := by simpa [Subtype.ext_iff] using hxy + aesop + open Submodule theorem map_codRestrict [RingHomSurjective σ₂₁] (p : Submodule R M) (f : M₂ →ₛₗ[σ₂₁] M) (h p') : From 6c5a9081e9b704f0d366214e1fd5e68e1538a4b2 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:19:13 +0000 Subject: [PATCH 0972/1300] chore: update Mathlib dependencies 2026-07-23 (#42036) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index d4b1f3146e6c82..ca62f89cbe2320 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "975a7ed3e5ed7838da79d5abddc50df73d0c84af", + "rev": "0a7a0cdc42f531e02361cb303b8cbf0e7d334f82", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From c89fc4beb7cc1c4465575d0a4f631dcbefc0dbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 24 Jul 2026 07:15:58 +0000 Subject: [PATCH 0973/1300] chore: add missing `noncomputable` (#41446) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All these definitions are noncomputable (because they use choice/produce sets), but the computability checker doesn't spot this until I try making `Set` a one-field structure. This is because the computability checker doesn't even try to compute sorts, but it doesn't see that `s : Set α` is (equivalent to) a family of sorts. --- .../Algebra/Homology/EulerCharacteristic.lean | 4 ++- .../SpecialFunctions/Complex/Circle.lean | 4 ++- .../Presentable/SharplyLT/Basic.lean | 4 ++- .../Combinatorics/SimpleGraph/Partition.lean | 12 ++++++-- Mathlib/Data/Real/Embedding.lean | 4 ++- Mathlib/Data/Set/MemPartition.lean | 4 ++- .../Geometry/Euclidean/Sphere/Tangent.lean | 8 +++-- Mathlib/GroupTheory/Commutator/Basic.lean | 8 +++-- Mathlib/GroupTheory/Complement.lean | 8 +++-- Mathlib/GroupTheory/DoubleCoset.lean | 4 ++- Mathlib/GroupTheory/GroupAction/Defs.lean | 4 ++- Mathlib/GroupTheory/SchurZassenhaus.lean | 4 ++- Mathlib/GroupTheory/Transfer.lean | 12 ++++---- Mathlib/LinearAlgebra/Basis/Flag.lean | 5 +++- Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 4 ++- Mathlib/LinearAlgebra/StdBasis.lean | 4 ++- .../Constructions/ClosedCompactCylinders.lean | 4 ++- .../Constructions/Cylinders.lean | 4 ++- .../MeasureTheory/Covering/VitaliFamily.lean | 4 ++- .../Function/AEMeasurableSequence.lean | 4 +-- .../AEStronglyMeasurable.lean | 4 ++- .../MeasurableSpace/CountablyGenerated.lean | 18 +++++++++-- .../Measure/Decomposition/Exhaustion.lean | 16 +++++++--- .../Measure/Decomposition/Lebesgue.lean | 4 ++- .../Measure/MutuallySingular.lean | 4 ++- .../Measure/Typeclasses/Finite.lean | 10 +++++-- .../Measure/Typeclasses/SFinite.lean | 8 +++-- Mathlib/ModelTheory/Algebra/Field/CharP.lean | 4 ++- .../Algebra/Field/IsAlgClosed.lean | 4 ++- Mathlib/NumberTheory/LSeries/ZetaZeros.lean | 4 ++- .../CanonicalEmbedding/ConvexBody.lean | 8 +++-- .../CanonicalEmbedding/NormLeOne.lean | 13 ++++++-- .../Interval/Set/OrdConnectedComponent.lean | 8 +++-- Mathlib/Order/Preorder/Chain.lean | 4 ++- .../Process/PartitionFiltration.lean | 4 ++- .../Extension/Presentation/Core.lean | 30 ++++++++++++++----- .../RingTheory/FractionalIdeal/Extended.lean | 5 +++- .../RingTheory/Polynomial/ContentIdeal.lean | 4 ++- .../RingTheory/Smooth/NoetherianDescent.lean | 30 ++++++++++++++----- .../Profinite/Nobeling/Successor.lean | 4 ++- .../Profinite/Nobeling/ZeroLimit.lean | 8 +++-- .../Topology/Compactness/SigmaCompact.lean | 4 ++- Mathlib/Topology/Connected/Basic.lean | 4 ++- Mathlib/Topology/Instances/CantorSet.lean | 8 +++-- Mathlib/Topology/Irreducible.lean | 4 ++- Mathlib/Topology/UrysohnsLemma.lean | 6 ++-- 46 files changed, 244 insertions(+), 85 deletions(-) diff --git a/Mathlib/Algebra/Homology/EulerCharacteristic.lean b/Mathlib/Algebra/Homology/EulerCharacteristic.lean index 9c2852324d0a16..ec0524f03889ce 100644 --- a/Mathlib/Algebra/Homology/EulerCharacteristic.lean +++ b/Mathlib/Algebra/Homology/EulerCharacteristic.lean @@ -103,7 +103,9 @@ variable (c : ComplexShape ι) [c.EulerCharSigns] /-- The support of a graded object with respect to finite rank: the set of indices where the rank is nonzero. -/ -def finrankSupport (X : CategoryTheory.GradedObject ι (ModuleCat R)) : Set ι := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def finrankSupport (X : CategoryTheory.GradedObject ι (ModuleCat R)) : Set ι := Function.support (fun i => Module.finrank R (X i)) /-- The finite rank support is contained in a set if and only if diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean index 47d2ab09a82a81..de73674c439fd5 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean @@ -117,7 +117,9 @@ lemma exp_injOn_Ioc {a b : ℝ} (h : b - a ≤ 2 * π) : InjOn exp (Ioc a b) := exp_injOn_of_forall_sub_mem_Ioo <| fun x ⟨hx1, hx2⟩ y ⟨hy1, hy2⟩ ↦ by constructor <;> linarith /-- The image under `Circle.exp` of the interval of angles `(-r, r)`. -/ -def centeredArc (r : ℝ) : Set Circle := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def centeredArc (r : ℝ) : Set Circle := exp '' {x | |x| < r} theorem bijOn_exp_Ioo_centeredArc {r : ℝ} (hr : r ≤ π) : diff --git a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean index 2574454c5dec62..6145f498b08a60 100644 --- a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean +++ b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean @@ -145,7 +145,9 @@ lemma hφ₀ (B : Set X) (hB : HasCardinalLT B κ₂) {T : Type w} (f : T → B) open scoped Classical in /-- This coincides with `φ₀` when `HasCardinalLT B κ₂` holds. -/ -def φ (B : Set X) : Set X := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def φ (B : Set X) : Set X := if hB : HasCardinalLT B κ₂ then φ₀ Y m B hB else B omit [Fact κ₁.IsRegular] [Fact κ₂.IsRegular] [PartialOrder X] in diff --git a/Mathlib/Combinatorics/SimpleGraph/Partition.lean b/Mathlib/Combinatorics/SimpleGraph/Partition.lean index e4f586ed8d83d9..b929a2d9603922 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Partition.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Partition.lean @@ -82,7 +82,9 @@ variable {G} variable (P : G.Partition) /-- The part in the partition that `v` belongs to. -/ -def partOfVertex (v : V) : Set V := Classical.choose (P.isPartition.2 v) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def partOfVertex (v : V) : Set V := Classical.choose (P.isPartition.2 v) theorem partOfVertex_mem (v : V) : P.partOfVertex v ∈ P.parts := by obtain ⟨h, -⟩ := (P.isPartition.2 v).choose_spec.1 @@ -100,13 +102,17 @@ theorem partOfVertex_ne_of_adj {v w : V} (h : G.Adj v w) : P.partOfVertex v ≠ /-- Create a coloring using the parts themselves as the colors. Each vertex is colored by the part it's contained in. -/ -def toColoring : G.Coloring P.parts := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def toColoring : G.Coloring P.parts := Coloring.mk (fun v ↦ ⟨P.partOfVertex v, P.partOfVertex_mem v⟩) fun hvw ↦ by rw [Ne, Subtype.mk_eq_mk] exact P.partOfVertex_ne_of_adj hvw /-- Like `SimpleGraph.Partition.toColoring` but uses `Set V` as the coloring type. -/ -def toColoring' : G.Coloring (Set V) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def toColoring' : G.Coloring (Set V) := Coloring.mk P.partOfVertex fun hvw ↦ P.partOfVertex_ne_of_adj hvw theorem colorable [Fintype P.parts] : G.Colorable (Fintype.card P.parts) := diff --git a/Mathlib/Data/Real/Embedding.lean b/Mathlib/Data/Real/Embedding.lean index 01c3a583913309..7f0078f4681cab 100644 --- a/Mathlib/Data/Real/Embedding.lean +++ b/Mathlib/Data/Real/Embedding.lean @@ -77,7 +77,9 @@ theorem mkRat_mem_ratLt {num : ℤ} {den : ℕ} (hden : den ≠ 0) {x : M} : exact (smul_lt_smul_iff_of_pos_left (Nat.zero_lt_of_ne_zero hm0)).symm /-- `ratLt` as a set of real numbers. -/ -abbrev ratLt' (x : M) : Set ℝ := (Rat.castHom ℝ) '' (ratLt x) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable abbrev ratLt' (x : M) : Set ℝ := (Rat.castHom ℝ) '' (ratLt x) /-- Mapping `M` to `ℝ`, defined as the supremum of `ratLt' x`. -/ noncomputable diff --git a/Mathlib/Data/Set/MemPartition.lean b/Mathlib/Data/Set/MemPartition.lean index 715e42feb60360..6187c7c49ef485 100644 --- a/Mathlib/Data/Set/MemPartition.lean +++ b/Mathlib/Data/Set/MemPartition.lean @@ -110,7 +110,9 @@ instance instFintype_memPartition (f : ℕ → Set α) (n : ℕ) : Fintype (memP open scoped Classical in /-- The set in `memPartition f n` to which `a : α` belongs. -/ -def memPartitionSet (f : ℕ → Set α) : ℕ → α → Set α +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def memPartitionSet (f : ℕ → Set α) : ℕ → α → Set α | 0 => fun _ ↦ univ | n + 1 => fun a ↦ if a ∈ f n then memPartitionSet f n a ∩ f n else memPartitionSet f n a \ f n diff --git a/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean b/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean index 3b20ce9f999210..d7facf6a615b88 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Tangent.lean @@ -259,7 +259,9 @@ lemma IsTangentAt.eq_orthogonalProjection {s : Sphere P} {p : P} {as : AffineSub rwa [isTangent_iff_isTangentAt_orthogonalProjection] at h' /-- The set of all maximal tangent spaces to the sphere `s`. -/ -def tangentSet (s : Sphere P) : Set (AffineSubspace ℝ P) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def tangentSet (s : Sphere P) : Set (AffineSubspace ℝ P) := s.orthRadius '' s lemma mem_tangentSet_iff {as : AffineSubspace ℝ P} {s : Sphere P} : @@ -292,7 +294,9 @@ lemma isTangent_of_mem_tangentsFrom {as : AffineSubspace ℝ P} {s : Sphere P} { isTangent_of_mem_tangentSet h.1 /-- The set of all maximal common tangent spaces to the spheres `s₁` and `s₂`. -/ -def commonTangents (s₁ s₂ : Sphere P) : Set (AffineSubspace ℝ P) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def commonTangents (s₁ s₂ : Sphere P) : Set (AffineSubspace ℝ P) := s₁.tangentSet ∩ s₂.tangentSet lemma mem_commonTangents_iff {as : AffineSubspace ℝ P} {s₁ s₂ : Sphere P} : diff --git a/Mathlib/GroupTheory/Commutator/Basic.lean b/Mathlib/GroupTheory/Commutator/Basic.lean index bae1b8b7e53cd9..9a0b563f52daab 100644 --- a/Mathlib/GroupTheory/Commutator/Basic.lean +++ b/Mathlib/GroupTheory/Commutator/Basic.lean @@ -461,13 +461,17 @@ open Subgroup /-- Representatives `(g₁, g₂) : G × G` of commutators `⁅g₁, g₂⁆ ∈ G`. -/ @[to_additive /-- Representatives `(g₁, g₂) : G × G` of additive commutators `⁅g₁, g₂⁆ ∈ G`. -/] -def commutatorRepresentatives : Set (G × G) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def commutatorRepresentatives : Set (G × G) := Set.range fun g : commutatorSet G => (g.2.choose, g.2.choose_spec.choose) /-- Subgroup generated by representatives `g₁ g₂ : G` of commutators `⁅g₁, g₂⁆ ∈ G`. -/ @[to_additive /-- Additive subgroup generated by representatives `g₁ g₂ : G` of additive commutators `⁅g₁, g₂⁆ ∈ G`. -/] -def closureCommutatorRepresentatives : Subgroup G := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def closureCommutatorRepresentatives : Subgroup G := closure (Prod.fst '' commutatorRepresentatives G ∪ Prod.snd '' commutatorRepresentatives G) @[to_additive] diff --git a/Mathlib/GroupTheory/Complement.lean b/Mathlib/GroupTheory/Complement.lean index 3d9c324060a59c..e349da7968f410 100644 --- a/Mathlib/GroupTheory/Complement.lean +++ b/Mathlib/GroupTheory/Complement.lean @@ -611,11 +611,15 @@ theorem smul_apply_eq_smul_apply_inv_smul (f : F) (S : H.LeftTransversal) (q : G end Action @[to_additive] -instance : Inhabited H.LeftTransversal := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : Inhabited H.LeftTransversal := ⟨⟨Set.range Quotient.out, isComplement_range_left Quotient.out_eq'⟩⟩ @[to_additive] -instance : Inhabited H.RightTransversal := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : Inhabited H.RightTransversal := ⟨⟨Set.range Quotient.out, isComplement_range_right Quotient.out_eq'⟩⟩ theorem IsComplement'.isCompl (h : IsComplement' H K) : IsCompl H K := by diff --git a/Mathlib/GroupTheory/DoubleCoset.lean b/Mathlib/GroupTheory/DoubleCoset.lean index d6e8aeecbd926e..c3945c8e42951b 100644 --- a/Mathlib/GroupTheory/DoubleCoset.lean +++ b/Mathlib/GroupTheory/DoubleCoset.lean @@ -106,7 +106,9 @@ lemma rel_bot_eq_right_group_rel (H : Subgroup G) : exact ⟨b * a⁻¹, h, 1, rfl, by rw [mul_one, inv_mul_cancel_right]⟩ /-- Create a double coset out of an element of `H \ G / K` -/ -def quotToDoubleCoset (H K : Subgroup G) (q : Quotient (H : Set G) K) : Set G := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def quotToDoubleCoset (H K : Subgroup G) (q : Quotient (H : Set G) K) : Set G := doubleCoset q.out H K /-- Map from `G` to `H \ G / K` -/ diff --git a/Mathlib/GroupTheory/GroupAction/Defs.lean b/Mathlib/GroupTheory/GroupAction/Defs.lean index caf5017f31ea4b..1e8459e5c76e51 100644 --- a/Mathlib/GroupTheory/GroupAction/Defs.lean +++ b/Mathlib/GroupTheory/GroupAction/Defs.lean @@ -476,7 +476,9 @@ def selfEquivSigmaOrbits' : α ≃ Σ ω : Ω, ω.orbit := /-- Decomposition of a type `X` as a disjoint union of its orbits under a group action. -/ @[to_additive /-- Decomposition of a type `X` as a disjoint union of its orbits under an additive group action. -/] -def selfEquivSigmaOrbits : α ≃ Σ ω : Ω, orbit G ω.out := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def selfEquivSigmaOrbits : α ≃ Σ ω : Ω, orbit G ω.out := (selfEquivSigmaOrbits' G α).trans <| Equiv.sigmaCongrRight fun _ => Equiv.setCongr <| orbitRel.Quotient.orbit_eq_orbit_out _ Quotient.out_eq' diff --git a/Mathlib/GroupTheory/SchurZassenhaus.lean b/Mathlib/GroupTheory/SchurZassenhaus.lean index 0052fbe5e7ca20..96c099be0b0218 100644 --- a/Mathlib/GroupTheory/SchurZassenhaus.lean +++ b/Mathlib/GroupTheory/SchurZassenhaus.lean @@ -42,7 +42,9 @@ def QuotientDiff := ⟨fun α => diff_self (MonoidHom.id H) α, fun h => by rw [← diff_inv, h, inv_one], fun h h' => by rw [← diff_mul_diff, h, h', one_mul]⟩) -instance : Inhabited H.QuotientDiff := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : Inhabited H.QuotientDiff := inferInstanceAs (Inhabited <| Quotient _) theorem smul_diff_smul' [hH : Normal H] (g : Gᵐᵒᵖ) : diff --git a/Mathlib/GroupTheory/Transfer.lean b/Mathlib/GroupTheory/Transfer.lean index eef6c92a2cc052..ff5a8110579785 100644 --- a/Mathlib/GroupTheory/Transfer.lean +++ b/Mathlib/GroupTheory/Transfer.lean @@ -27,7 +27,7 @@ In this file we construct the transfer homomorphism. If `hP : N(P) ≤ C(P)`, then `(transfer P hP).ker` is a normal `p`-complement. -/ -@[expose] public section +@[expose] public noncomputable section variable {G : Type*} [Group G] {H : Subgroup G} {A : Type*} [CommGroup A] (ϕ : H →* A) @@ -44,7 +44,7 @@ variable (R S T : H.LeftTransversal) [FiniteIndex H] /-- The difference of two left transversals -/ @[to_additive /-- The difference of two left transversals -/] -noncomputable def diff : A := +def diff : A := let α := S.2.leftQuotientEquiv let β := T.2.leftQuotientEquiv let _ := H.fintypeQuotientOfFiniteIndex @@ -86,7 +86,7 @@ variable (H) in /-- The transfer transversal as a function. Given a `⟨g⟩`-orbit `q₀, g • q₀, ..., g ^ (m - 1) • q₀` in `G ⧸ H`, an element `g ^ k • q₀` is mapped to `g ^ k • g₀` for a fixed choice of representative `g₀` of `q₀`. -/ -noncomputable def transferFunction : G ⧸ H → G := fun q => +def transferFunction : G ⧸ H → G := fun q => g ^ (cast (quotientEquivSigmaZMod H g q).2 : ℤ) * (quotientEquivSigmaZMod H g q).1.out.out lemma transferFunction_apply (q : G ⧸ H) : @@ -145,7 +145,7 @@ open MulAction Subgroup Subgroup.leftTransversals the transfer homomorphism is `transfer ϕ : G →* A`. -/ @[to_additive /-- Given `ϕ : H →+ A` from `H : AddSubgroup G` to an additive commutative group `A`, the transfer homomorphism is `transfer ϕ : G →+ A`. -/] -noncomputable def transfer [FiniteIndex H] : G →* A := +def transfer [FiniteIndex H] : G →* A := let T : H.LeftTransversal := default { toFun := fun g => diff ϕ T (g • T) map_one' := by rw [one_smul, diff_self] @@ -228,7 +228,7 @@ theorem transfer_center_eq_pow [FiniteIndex (center G)] (g : G) : variable (G) in /-- The transfer homomorphism `G →* center G`. -/ -noncomputable def transferCenterPow [FiniteIndex (center G)] : G →* center G where +def transferCenterPow [FiniteIndex (center G)] : G →* center G where toFun g := ⟨g ^ (center G).index, (center G).pow_index_mem g⟩ map_one' := Subtype.ext (one_pow (center G).index) map_mul' a b := by simp_rw [← show ∀ _, (_ : center G) = _ from transfer_center_eq_pow, map_mul] @@ -245,7 +245,7 @@ include hP open scoped IsMulCommutative in /-- The homomorphism `G →* P` in Burnside's transfer theorem. -/ -noncomputable def transferSylow [P.FiniteIndex] : G →* P := +def transferSylow [P.FiniteIndex] : G →* P := haveI : IsMulCommutative P := ⟨⟨fun a b => Subtype.ext (hP (le_normalizer b.2) a a.2)⟩⟩ transfer (MonoidHom.id P) diff --git a/Mathlib/LinearAlgebra/Basis/Flag.lean b/Mathlib/LinearAlgebra/Basis/Flag.lean index 13d132de0285e8..6659869cbbd319 100644 --- a/Mathlib/LinearAlgebra/Basis/Flag.lean +++ b/Mathlib/LinearAlgebra/Basis/Flag.lean @@ -19,7 +19,10 @@ to be the subspace spanned by the first `k` vectors of the basis `b`. We also prove some lemmas about this definition. -/ -@[expose] public section +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- This is why this section is `noncomputable`. +-- See https://github.com/leanprover/lean4/issues/14084. +@[expose] public noncomputable section open Set Submodule diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index 967d8c9c2e7b58..da1e7bed2f4cd2 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -69,7 +69,9 @@ theorem range_extend (hs : LinearIndepOn K id s) : /-- Auxiliary definition: the index for the new basis vectors in `Basis.sumExtend`. The specific value of this definition should be considered an implementation detail. -/ -def sumExtendIndex (hs : LinearIndependent K v) : Set V := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def sumExtendIndex (hs : LinearIndependent K v) : Set V := LinearIndepOn.extend hs.linearIndepOn_id (subset_univ _) \ range v /-- If `v` is a linear independent family of vectors, extend it to a basis indexed by a sum type. -/ diff --git a/Mathlib/LinearAlgebra/StdBasis.lean b/Mathlib/LinearAlgebra/StdBasis.lean index 6e83f65a5ce362..173420427c58f2 100644 --- a/Mathlib/LinearAlgebra/StdBasis.lean +++ b/Mathlib/LinearAlgebra/StdBasis.lean @@ -137,7 +137,9 @@ theorem basisFun_equivFun : (Pi.basisFun R η).equivFun = LinearEquiv.refl _ _ : variable {η} /-- The `R`-submodule of `η → R` consisting of functions supported in the subset `s`. -/ -def spanSubset (s : Set η) : Submodule R (η → R) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def spanSubset (s : Set η) : Submodule R (η → R) := .span R (Pi.basisFun R η '' s) variable {R} {s : Set η} diff --git a/Mathlib/MeasureTheory/Constructions/ClosedCompactCylinders.lean b/Mathlib/MeasureTheory/Constructions/ClosedCompactCylinders.lean index 2321bf6e04aa32..ae61a053e0514c 100644 --- a/Mathlib/MeasureTheory/Constructions/ClosedCompactCylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/ClosedCompactCylinders.lean @@ -55,7 +55,9 @@ noncomputable def closedCompactCylinders.finset (ht : t ∈ closedCompactCylinde ((mem_closedCompactCylinders t).mp ht).choose /-- A set `S` such that `t = cylinder s S`. `s` is given by `closedCompactCylinders.finset`. -/ -def closedCompactCylinders.set (ht : t ∈ closedCompactCylinders X) : +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def closedCompactCylinders.set (ht : t ∈ closedCompactCylinders X) : Set (Π i : closedCompactCylinders.finset ht, X i) := ((mem_closedCompactCylinders t).mp ht).choose_spec.choose diff --git a/Mathlib/MeasureTheory/Constructions/Cylinders.lean b/Mathlib/MeasureTheory/Constructions/Cylinders.lean index e75df0ba659b56..1e28d660c5adb5 100644 --- a/Mathlib/MeasureTheory/Constructions/Cylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/Cylinders.lean @@ -294,7 +294,9 @@ noncomputable def measurableCylinders.finset (ht : t ∈ measurableCylinders α) ((mem_measurableCylinders t).mp ht).choose /-- A set `S` such that `t = cylinder s S`. `s` is given by `measurableCylinders.finset`. -/ -def measurableCylinders.set (ht : t ∈ measurableCylinders α) : +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def measurableCylinders.set (ht : t ∈ measurableCylinders α) : Set (∀ i : measurableCylinders.finset ht, α i) := ((mem_measurableCylinders t).mp ht).choose_spec.choose diff --git a/Mathlib/MeasureTheory/Covering/VitaliFamily.lean b/Mathlib/MeasureTheory/Covering/VitaliFamily.lean index 90dd8d165969ca..39f485fac5c75f 100644 --- a/Mathlib/MeasureTheory/Covering/VitaliFamily.lean +++ b/Mathlib/MeasureTheory/Covering/VitaliFamily.lean @@ -117,7 +117,9 @@ theorem exists_disjoint_covering_ae : /-- Given `h : v.FineSubfamilyOn f s`, then `h.index` is a set parametrizing a disjoint covering of almost every `s`. -/ -protected def index : Set (X × Set X) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +protected noncomputable def index : Set (X × Set X) := h.exists_disjoint_covering_ae.choose /-- Given `h : v.FineSubfamilyOn f s`, then `h.covering p` is a set in the family, diff --git a/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean b/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean index 857b773485759a..7d9cc492ad554a 100644 --- a/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean +++ b/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean @@ -21,7 +21,7 @@ and a measurable set `aeSeqSet hf p`, such that * `x ∈ aeSeqSet hf p → p x (fun n ↦ f n x)` -/ -@[expose] public section +@[expose] public noncomputable section open MeasureTheory @@ -38,7 +38,7 @@ def aeSeqSet (hf : ∀ i, AEMeasurable (f i) μ) (p : α → (ι → β) → Pro open scoped Classical in /-- A sequence of measurable functions that are equal to `f` and verify property `p` on the measurable set `aeSeqSet hf p`. -/ -noncomputable def aeSeq (hf : ∀ i, AEMeasurable (f i) μ) (p : α → (ι → β) → Prop) : ι → α → β := +def aeSeq (hf : ∀ i, AEMeasurable (f i) μ) (p : α → (ι → β) → Prop) : ι → α → β := fun i x => ite (x ∈ aeSeqSet hf p) ((hf i).mk (f i) x) (⟨f i x⟩ : Nonempty β).some namespace aeSeq diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index 2bd25eb785e359..e668c596342d7d 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -947,7 +947,9 @@ theorem exists_set_sigmaFinite (hf : AEFinStronglyMeasurable f μ) : exact Eventually.of_forall hgt_zero /-- A measurable set `t` such that `f =ᵐ[μ.restrict tᶜ] 0` and `sigma_finite (μ.restrict t)`. -/ -def sigmaFiniteSet (hf : AEFinStronglyMeasurable f μ) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def sigmaFiniteSet (hf : AEFinStronglyMeasurable f μ) : Set α := hf.exists_set_sigmaFinite.choose protected theorem measurableSet (hf : AEFinStronglyMeasurable f μ) : diff --git a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean index 3e8032d0ffd9bf..7782e46859e4ba 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/CountablyGenerated.lean @@ -57,6 +57,9 @@ class CountablyGenerated (α : Type*) [m : MeasurableSpace α] : Prop where /-- A countable set of sets that generate the measurable space. We insert `∅` to ensure it is nonempty. -/ +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def countableGeneratingSet (α : Type*) [MeasurableSpace α] [h : CountablyGenerated α] : Set (Set α) := insert ∅ h.isCountablyGenerated.choose @@ -83,6 +86,9 @@ lemma measurableSet_countableGeneratingSet [MeasurableSpace α] [CountablyGenera exact measurableSet_generateFrom hs /-- A countable sequence of sets generating the measurable space. -/ +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def natGeneratingSequence (α : Type*) [MeasurableSpace α] [CountablyGenerated α] : ℕ → (Set α) := enumerateCountable (countable_countableGeneratingSet (α := α)) ∅ @@ -143,6 +149,9 @@ open scoped Classical in Some of those sets may be empty, but the nonempty ones are the atoms of the measurable space. See `measurableAtom_eq_countablyGeneratedAtom_natGeneratingSequence`. -/ +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def countablyGeneratedAtom (α : Type*) [MeasurableSpace α] [CountablyGenerated α] : (ℕ → Prop) → Set α := fun p ↦ ⋂ n, if p n then natGeneratingSequence α n else (natGeneratingSequence α n)ᶜ @@ -570,7 +579,10 @@ variable [m : MeasurableSpace α] [h : CountablyGenerated α] /-- For each `n : ℕ`, `countablePartition α n` is a partition of the space in at most `2^n` sets. Each partition is finer than the preceding one. The measurable space generated by the union of all those partitions is the measurable space on `α`. -/ -def countablePartition (α : Type*) [MeasurableSpace α] [CountablyGenerated α] : ℕ → Set (Set α) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def countablePartition (α : Type*) [MeasurableSpace α] [CountablyGenerated α] : + ℕ → Set (Set α) := memPartition (enumerateCountable countable_countableGeneratingSet ∅) lemma measurableSet_enumerateCountable_countableGeneratingSet @@ -626,7 +638,9 @@ lemma measurableSet_countablePartition (n : ℕ) {s : Set α} (hs : s ∈ counta generateFrom_countablePartition_le α n _ (measurableSet_generateFrom hs) /-- The set in `countablePartition α n` to which `a : α` belongs. -/ -def countablePartitionSet (n : ℕ) (a : α) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def countablePartitionSet (n : ℕ) (a : α) : Set α := memPartitionSet (enumerateCountable countable_countableGeneratingSet ∅) n a lemma countablePartitionSet_mem (n : ℕ) (a : α) : diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean index 0bc097a039a1c1..61fe8b8a04804a 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean @@ -62,7 +62,9 @@ variable {α : Type*} {mα : MeasurableSpace α} {μ ν : Measure α} {s t : Set open scoped Classical in /-- A measurable set such that `μ.restrict (μ.sigmaFiniteSetWRT ν)` is sigma-finite and for all measurable sets `t ⊆ sᶜ`, either `ν t = 0` or `μ t = ∞`. -/ -def Measure.sigmaFiniteSetWRT (μ ν : Measure α) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def Measure.sigmaFiniteSetWRT (μ ν : Measure α) : Set α := if h : ∃ s : Set α, MeasurableSet s ∧ SigmaFinite (μ.restrict s) ∧ (∀ t, t ⊆ sᶜ → ν t ≠ 0 → μ t = ∞) then h.choose @@ -123,7 +125,9 @@ lemma exists_isSigmaFiniteSet_measure_ge (μ ν : Measure α) [IsFiniteMeasure /-- A measurable set such that `μ.restrict (μ.sigmaFiniteSetGE ν n)` is sigma-finite and for `C` the supremum of `ν s` over all measurable sets `s` with `μ.restrict s` sigma-finite, `ν (μ.sigmaFiniteSetGE ν n) ≥ C - 1/n`. -/ -def Measure.sigmaFiniteSetGE (μ ν : Measure α) [IsFiniteMeasure ν] (n : ℕ) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def Measure.sigmaFiniteSetGE (μ ν : Measure α) [IsFiniteMeasure ν] (n : ℕ) : Set α := (exists_isSigmaFiniteSet_measure_ge μ ν n).choose lemma measurableSet_sigmaFiniteSetGE [IsFiniteMeasure ν] (n : ℕ) : @@ -159,7 +163,9 @@ lemma tendsto_measure_sigmaFiniteSetGE (μ ν : Measure α) [IsFiniteMeasure ν] /-- A measurable set such that `μ.restrict (μ.sigmaFiniteSetWRT' ν)` is sigma-finite and `ν (μ.sigmaFiniteSetWRT' ν)` has maximal measure among such sets. -/ -def Measure.sigmaFiniteSetWRT' (μ ν : Measure α) [IsFiniteMeasure ν] : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def Measure.sigmaFiniteSetWRT' (μ ν : Measure α) [IsFiniteMeasure ν] : Set α := ⋃ n, μ.sigmaFiniteSetGE ν n lemma measurableSet_sigmaFiniteSetWRT' [IsFiniteMeasure ν] : @@ -304,7 +310,9 @@ section SigmaFiniteSet /-- A measurable set such that `μ.restrict μ.sigmaFiniteSet` is sigma-finite, and for all measurable sets `s ⊆ μ.sigmaFiniteSetᶜ`, either `μ s = 0` or `μ s = ∞`. -/ -def Measure.sigmaFiniteSet (μ : Measure α) : Set α := μ.sigmaFiniteSetWRT μ +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def Measure.sigmaFiniteSet (μ : Measure α) : Set α := μ.sigmaFiniteSetWRT μ @[measurability] lemma measurableSet_sigmaFiniteSet : MeasurableSet μ.sigmaFiniteSet := diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean index 090e050b682153..ebed332152835a 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean @@ -833,7 +833,9 @@ theorem iSup_le_le {α : Type*} (f : ℕ → α → ℝ≥0∞) (n k : ℕ) (hk end SuprLemmas /-- `measurableLEEval μ ν` is the set of `∫⁻ x, f x ∂μ` for all `f ∈ measurableLE μ ν`. -/ -def measurableLEEval (μ ν : Measure α) : Set ℝ≥0∞ := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def measurableLEEval (μ ν : Measure α) : Set ℝ≥0∞ := (fun f : α → ℝ≥0∞ ↦ ∫⁻ x, f x ∂μ) '' measurableLE μ ν end LebesgueDecomposition diff --git a/Mathlib/MeasureTheory/Measure/MutuallySingular.lean b/Mathlib/MeasureTheory/Measure/MutuallySingular.lean index 302749961949c7..e5ce715eee3895 100644 --- a/Mathlib/MeasureTheory/Measure/MutuallySingular.lean +++ b/Mathlib/MeasureTheory/Measure/MutuallySingular.lean @@ -53,7 +53,9 @@ theorem mk {s t : Set α} (hs : μ s = 0) (ht : ν t = 0) (hst : univ ⊆ s ∪ exact subset_toMeasurable _ _ hxs /-- A set such that `μ h.nullSet = 0` and `ν h.nullSetᶜ = 0`. -/ -def nullSet (h : μ ⟂ₘ ν) : Set α := h.choose +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def nullSet (h : μ ⟂ₘ ν) : Set α := h.choose lemma measurableSet_nullSet (h : μ ⟂ₘ ν) : MeasurableSet h.nullSet := h.choose_spec.1 diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean index ff9b25f67c9c75..86e8176e35b8ce 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/Finite.lean @@ -563,7 +563,10 @@ theorem isFiniteMeasure_iff_isFiniteMeasureOnCompacts_of_compactSpace [Topologic /-- Compact covering of a `σ`-compact topological space as `MeasureTheory.Measure.FiniteSpanningSetsIn`. -/ -def MeasureTheory.Measure.finiteSpanningSetsInCompact [TopologicalSpace α] [SigmaCompactSpace α] +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def MeasureTheory.Measure.finiteSpanningSetsInCompact + [TopologicalSpace α] [SigmaCompactSpace α] {_ : MeasurableSpace α} (μ : Measure α) [IsLocallyFiniteMeasure μ] : μ.FiniteSpanningSetsIn { K | IsCompact K } where set := compactCovering α @@ -573,7 +576,10 @@ def MeasureTheory.Measure.finiteSpanningSetsInCompact [TopologicalSpace α] [Sig /-- A locally finite measure on a `σ`-compact topological space admits a finite spanning sequence of open sets. -/ -def MeasureTheory.Measure.finiteSpanningSetsInOpen [TopologicalSpace α] [SigmaCompactSpace α] +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def MeasureTheory.Measure.finiteSpanningSetsInOpen + [TopologicalSpace α] [SigmaCompactSpace α] {_ : MeasurableSpace α} (μ : Measure α) [IsLocallyFiniteMeasure μ] : μ.FiniteSpanningSetsIn { K | IsOpen K } where set n := ((isCompact_compactCovering α n).exists_open_superset_measure_lt_top μ).choose diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean index 695dba97b890b8..e1cc8af8cd1ba7 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses/SFinite.lean @@ -104,7 +104,9 @@ theorem SigmaFinite.out (h : SigmaFinite μ) : Nonempty (μ.FiniteSpanningSetsIn h.1 /-- If `μ` is σ-finite it has finite spanning sets in the collection of all measurable sets. -/ -def Measure.toFiniteSpanningSetsIn (μ : Measure α) [h : SigmaFinite μ] : +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def Measure.toFiniteSpanningSetsIn (μ : Measure α) [h : SigmaFinite μ] : μ.FiniteSpanningSetsIn { s | MeasurableSet s } where set n := toMeasurable μ (h.out.some.set n) set_mem _ := measurableSet_toMeasurable _ _ @@ -116,7 +118,9 @@ def Measure.toFiniteSpanningSetsIn (μ : Measure α) [h : SigmaFinite μ] : /-- A noncomputable way to get a monotone collection of sets that span `univ` and have finite measure using `Classical.choose`. This definition satisfies monotonicity in addition to all other properties in `SigmaFinite`. -/ -def spanningSets (μ : Measure α) [SigmaFinite μ] (i : ℕ) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def spanningSets (μ : Measure α) [SigmaFinite μ] (i : ℕ) : Set α := accumulate μ.toFiniteSpanningSetsIn.set i theorem monotone_spanningSets (μ : Measure α) [SigmaFinite μ] : Monotone (spanningSets μ) := diff --git a/Mathlib/ModelTheory/Algebra/Field/CharP.lean b/Mathlib/ModelTheory/Algebra/Field/CharP.lean index aa00bd890bd4c1..e022f7bf5eaf73 100644 --- a/Mathlib/ModelTheory/Algebra/Field/CharP.lean +++ b/Mathlib/ModelTheory/Algebra/Field/CharP.lean @@ -41,7 +41,9 @@ noncomputable def eqZero (n : ℕ) : Language.ring.Sentence := simp [eqZero] /-- The first-order theory of fields of characteristic `p` as a theory over the language of rings -/ -def _root_.FirstOrder.Language.Theory.fieldOfChar (p : ℕ) : Language.ring.Theory := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def _root_.FirstOrder.Language.Theory.fieldOfChar (p : ℕ) : Language.ring.Theory := Theory.field ∪ if p = 0 then (fun q => ∼(eqZero q)) '' {q : ℕ | q.Prime} diff --git a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean index 338de145fc0c25..c8b764647d3eb4 100644 --- a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean +++ b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean @@ -80,7 +80,9 @@ theorem realize_genericMonicPolyHasRoot [Field K] [CompatibleRing K] (n : ℕ) : /-- The theory of algebraically closed fields of characteristic `p` as a theory over the language of rings -/ -def _root_.FirstOrder.Language.Theory.ACF (p : ℕ) : Theory .ring := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def _root_.FirstOrder.Language.Theory.ACF (p : ℕ) : Theory .ring := Theory.fieldOfChar p ∪ genericMonicPolyHasRoot '' {n | 0 < n} instance [Language.ring.Structure K] (p : ℕ) [h : (Theory.ACF p).Model K] : diff --git a/Mathlib/NumberTheory/LSeries/ZetaZeros.lean b/Mathlib/NumberTheory/LSeries/ZetaZeros.lean index 3de3859e78e028..0b8046e67ae5d1 100644 --- a/Mathlib/NumberTheory/LSeries/ZetaZeros.lean +++ b/Mathlib/NumberTheory/LSeries/ZetaZeros.lean @@ -30,7 +30,9 @@ so that in particular any compact subset of `ℂ` contains only finitely many ze @[expose] public section /-- The zeros of Riemann's ζ-function. -/ -def riemannZetaZeros : Set ℂ := riemannZeta ⁻¹' {0} +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def riemannZetaZeros : Set ℂ := riemannZeta ⁻¹' {0} lemma mem_riemannZetaZeros {z : ℂ} : z ∈ riemannZetaZeros ↔ riemannZeta z = 0 := .rfl diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean index 558dabc828b1df..9dfad8b98b3b82 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean @@ -55,7 +55,9 @@ variable (f : InfinitePlace K → ℝ≥0) /-- The convex body defined by `f`: the set of points `x : E` such that `‖x w‖ < f w` for all infinite places `w`. -/ -abbrev convexBodyLT : Set (mixedSpace K) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable abbrev convexBodyLT : Set (mixedSpace K) := (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } => ball 0 (f w))) ×ˢ (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } => ball 0 (f w))) @@ -145,7 +147,9 @@ open scoped Classical in needed to ensure the element constructed is not real, see for example `exists_primitive_element_lt_of_isComplex`. -/ -abbrev convexBodyLT' : Set (mixedSpace K) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable abbrev convexBodyLT' : Set (mixedSpace K) := (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } ↦ ball 0 (f w))) ×ˢ (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } ↦ if w = w₀ then {x | |x.re| < 1 ∧ |x.im| < (f w : ℝ) ^ 2} else ball 0 (f w))) diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean index 6527683f9be0d4..3d71faf8b0a105 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean @@ -161,7 +161,10 @@ variable [NumberField K] /-- The set of elements of the `fundamentalCone` of `norm ≤ 1`. -/ -abbrev normLeOne : Set (mixedSpace K) := fundamentalCone K ∩ {x | mixedEmbedding.norm x ≤ 1} +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable abbrev normLeOne : Set (mixedSpace K) := + fundamentalCone K ∩ {x | mixedEmbedding.norm x ≤ 1} variable {K} in theorem mem_normLeOne {x : mixedSpace K} : @@ -633,7 +636,9 @@ open scoped Classical in The set that parametrizes `normAtAllPlaces '' (normLeOne K)`, see `normAtAllPlaces_normLeOne_eq_image`. -/ -abbrev paramSet : Set (realSpace K) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable abbrev paramSet : Set (realSpace K) := Set.univ.pi fun w ↦ if w = w₀ then Set.Iic 0 else Set.Ico 0 1 theorem measurableSet_paramSet : @@ -720,7 +725,9 @@ open scoped Classical in A compact set that contains `expMapBasis '' closure (paramSet K)` and furthermore is almost equal to it, see `compactSet_ae`. -/ -abbrev compactSet : Set (realSpace K) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable abbrev compactSet : Set (realSpace K) := (Set.Icc (0 : ℝ) 1) • (expMapBasis '' Set.univ.pi fun w ↦ if w = w₀ then {0} else Set.Icc 0 1) theorem isCompact_compactSet : diff --git a/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean b/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean index 04840e3ddd325e..cbb153278c6641 100644 --- a/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean +++ b/Mathlib/Order/Interval/Set/OrdConnectedComponent.lean @@ -116,7 +116,9 @@ theorem ordConnectedProj_eq {x y : s} : /-- A set that intersects each order connected component of a set by a single point. Defined as the range of `Set.ordConnectedProj s`. -/ -def ordConnectedSection (s : Set α) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def ordConnectedSection (s : Set α) : Set α := range <| ordConnectedProj s theorem dual_ordConnectedSection (s : Set α) : @@ -165,7 +167,9 @@ theorem dual_ordSeparatingSet : /-- An auxiliary neighborhood that will be used in the proof of `OrderTopology.CompletelyNormalSpace`. -/ -def ordT5Nhd (s t : Set α) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def ordT5Nhd (s t : Set α) : Set α := ⋃ x ∈ s, ordConnectedComponent (tᶜ ∩ (ordConnectedSection <| ordSeparatingSet s t)ᶜ) x theorem disjoint_ordT5Nhd : Disjoint (ordT5Nhd s t) (ordT5Nhd t s) := by diff --git a/Mathlib/Order/Preorder/Chain.lean b/Mathlib/Order/Preorder/Chain.lean index 8536a31860ec24..0e11d2201928e7 100644 --- a/Mathlib/Order/Preorder/Chain.lean +++ b/Mathlib/Order/Preorder/Chain.lean @@ -292,7 +292,9 @@ theorem IsMaxChain.symm (h : IsMaxChain r s) : IsMaxChain (flip r) s := open scoped Classical in /-- Given a set `s`, if there exists a chain `t` strictly including `s`, then `SuccChain s` is one of these chains. Otherwise it is `s`. -/ -def SuccChain (r : α → α → Prop) (s : Set α) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def SuccChain (r : α → α → Prop) (s : Set α) : Set α := if h : ∃ t, IsChain r s ∧ SuperChain r s t then h.choose else s theorem succChain_spec (h : ∃ t, IsChain r s ∧ SuperChain r s t) : diff --git a/Mathlib/Probability/Process/PartitionFiltration.lean b/Mathlib/Probability/Process/PartitionFiltration.lean index 1f100fc7eda116..8f5a575179566e 100644 --- a/Mathlib/Probability/Process/PartitionFiltration.lean +++ b/Mathlib/Probability/Process/PartitionFiltration.lean @@ -105,7 +105,9 @@ variable {α : Type*} [MeasurableSpace α] [CountablyGenerated α] /-- A filtration built from the measurable spaces generated by `countablePartition α n` for all `n : ℕ`. -/ -def countableFiltration (α : Type*) [m : MeasurableSpace α] [CountablyGenerated α] : +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def countableFiltration (α : Type*) [m : MeasurableSpace α] [CountablyGenerated α] : Filtration ℕ m where seq n := generateFrom (countablePartition α n) mono' := monotone_nat_of_le_succ (generateFrom_countablePartition_le_succ _) diff --git a/Mathlib/RingTheory/Extension/Presentation/Core.lean b/Mathlib/RingTheory/Extension/Presentation/Core.lean index caedd44508860c..3e486502c770da 100644 --- a/Mathlib/RingTheory/Extension/Presentation/Core.lean +++ b/Mathlib/RingTheory/Extension/Presentation/Core.lean @@ -34,7 +34,9 @@ namespace Algebra.Presentation variable (P) in /-- The coefficients of a presentation are the coefficients of the relations. -/ -def coeffs : Set R := ⋃ (i : σ), (P.relation i).coeffs +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def coeffs : Set R := ⋃ (i : σ), (P.relation i).coeffs lemma coeffs_relation_subset_coeffs (x : σ) : ((P.relation x).coeffs : Set R) ⊆ P.coeffs := @@ -45,7 +47,9 @@ lemma finite_coeffs [Finite σ] : P.coeffs.Finite := variable (P) in /-- The core of a presentation is the subalgebra generated by the coefficients of the relations. -/ -def core : Subalgebra ℤ R := Algebra.adjoin _ P.coeffs +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def core : Subalgebra ℤ R := Algebra.adjoin _ P.coeffs variable (P) in lemma coeffs_subset_core : P.coeffs ⊆ P.core := Algebra.subset_adjoin @@ -56,12 +60,20 @@ lemma coeffs_relation_subset_core (x : σ) : variable (P) in /-- The core coerced to a type for performance reasons. -/ -def Core : Type _ := P.core - -instance : CommRing P.Core := fast_instance% (inferInstanceAs <| CommRing P.core) -instance : Algebra P.Core R := fast_instance% (inferInstanceAs <| Algebra P.core R) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def Core : Type _ := P.core + +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : CommRing P.Core := fast_instance% (inferInstanceAs <| CommRing P.core) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : Algebra P.Core R := fast_instance% (inferInstanceAs <| Algebra P.core R) instance : FaithfulSMul P.Core R := inferInstanceAs <| FaithfulSMul P.core R -instance : Algebra P.Core S := fast_instance% (inferInstanceAs <| Algebra P.core S) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : Algebra P.Core S := fast_instance% (inferInstanceAs <| Algebra P.core S) instance : IsScalarTower P.Core R S := inferInstanceAs <| IsScalarTower P.core R S instance [Finite σ] : FiniteType ℤ P.Core := .adjoin_of_finite P.finite_coeffs @@ -257,7 +269,9 @@ lemma jacobianRelations_spec [DecidableEq σ] [Fintype σ] : convert! P.exists_sum_eq_σ_jacobian_mul_σ_jacobian_inv_sub_one.choose_spec /-- The set of coefficients that is enough to descend a submersive presentation `P`. -/ -def coeffs : Set R := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def coeffs : Set R := P.toPresentation.coeffs ∪ (P.σ (P.jacobian_isUnit.unit⁻¹ :)).coeffs ∪ ⋃ i, (P.jacobianRelations i).coeffs diff --git a/Mathlib/RingTheory/FractionalIdeal/Extended.lean b/Mathlib/RingTheory/FractionalIdeal/Extended.lean index d158d68aa6fd15..cfd6b34781258a 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Extended.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Extended.lean @@ -37,7 +37,10 @@ This file defines the extension of a fractional ideal along a ring homomorphism. fractional ideal, fractional ideals, extended, extension -/ -@[expose] public section +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- This is why this section is `noncomputable`. +-- See https://github.com/leanprover/lean4/issues/14084. +@[expose] public noncomputable section open IsLocalization FractionalIdeal Module Submodule diff --git a/Mathlib/RingTheory/Polynomial/ContentIdeal.lean b/Mathlib/RingTheory/Polynomial/ContentIdeal.lean index 9758b54a8d9a11..4bc689bd797578 100644 --- a/Mathlib/RingTheory/Polynomial/ContentIdeal.lean +++ b/Mathlib/RingTheory/Polynomial/ContentIdeal.lean @@ -48,7 +48,9 @@ open Ideal variable {R S : Type*} [Semiring R] [Semiring S] (p : R[X]) /-- The content ideal of a polynomial `p` is the ideal generated by its coefficients. -/ -def contentIdeal := span (p.coeffs : Set R) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def contentIdeal := span (p.coeffs : Set R) theorem contentIdeal_def : p.contentIdeal = span (p.coeffs : Set R) := rfl diff --git a/Mathlib/RingTheory/Smooth/NoetherianDescent.lean b/Mathlib/RingTheory/Smooth/NoetherianDescent.lean index 65ffbc4d7bab00..9255cf2f38d237 100644 --- a/Mathlib/RingTheory/Smooth/NoetherianDescent.lean +++ b/Mathlib/RingTheory/Smooth/NoetherianDescent.lean @@ -51,20 +51,34 @@ variable (D : DescentAux A B) variable (R) /-- (Implementation detail): The finite type `R`-algebra. -/ -def subalgebra (D : DescentAux A B) : Subalgebra R A := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def subalgebra (D : DescentAux A B) : Subalgebra R A := Algebra.adjoin R (D.P.coeffs ∪ ((⋃ i, (D.h i).coeffs) ∪ (⋃ i, ⋃ x ∈ (D.q i).coeffs, x.coeffs) ∪ (⋃ i, ⋃ x ∈ (D.p i).coeffs, x.coeffs)) : Set A) -instance : CommRing (D.subalgebra R) := inferInstanceAs <| CommRing (Algebra.adjoin _ _) - -instance algebra₀ : Algebra R (D.subalgebra R) := inferInstanceAs <| Algebra R (Algebra.adjoin _ _) - -instance algebra₁ : Algebra (D.subalgebra R) A := inferInstanceAs <| Algebra (Algebra.adjoin _ _) A - -instance algebra₂ : Algebra (D.subalgebra R) B := inferInstanceAs <| Algebra (Algebra.adjoin _ _) B +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance : CommRing (D.subalgebra R) := + inferInstanceAs <| CommRing (Algebra.adjoin _ _) + +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance algebra₀ : Algebra R (D.subalgebra R) := + inferInstanceAs <| Algebra R (Algebra.adjoin _ _) + +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance algebra₁ : Algebra (D.subalgebra R) A := + inferInstanceAs <| Algebra (Algebra.adjoin _ _) A + +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable instance algebra₂ : Algebra (D.subalgebra R) B := + inferInstanceAs <| Algebra (Algebra.adjoin _ _) B instance : IsScalarTower (D.subalgebra R) A B := inferInstanceAs <| IsScalarTower (Algebra.adjoin _ _) _ _ diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean index f85f8dbf1c5b4f..126fe2f46aaaf9 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean @@ -121,7 +121,9 @@ theorem union_C0C1_eq : (C0 C ho) ∪ (C1 C ho) = C := by The intersection of `C0` and the projection of `C1`. We will apply the inductive hypothesis to this set. -/ -def C' := C0 C ho ∩ π (C1 C ho) (ord I · < o) +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def C' := C0 C ho ∩ π (C1 C ho) (ord I · < o) include hC in theorem isClosed_C' : IsClosed (C' C ho) := diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean b/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean index 94cf0ce02c0a79..0c987502211b5d 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/ZeroLimit.lean @@ -141,7 +141,9 @@ The image of the `GoodProducts` for `π C (ord I · < o)` in `LocallyConstant C refers to the setting in which we will use this, when we are mapping in `GoodProducts` from a smaller set, i.e. when `o` is a smaller ordinal than the one `C` is "contained" in. -/ -def smaller (o : Ordinal) : Set (LocallyConstant C ℤ) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def smaller (o : Ordinal) : Set (LocallyConstant C ℤ) := (πs C o) '' (range (π C (ord I · < o))) /-- @@ -237,7 +239,9 @@ theorem GoodProducts.union : range C = ⋃ (e : {o' // o' < o}), (smaller C e.va The image of the `GoodProducts` in `C` is equivalent to the union of `smaller C o'` over all ordinals `o' < o`. -/ -def GoodProducts.range_equiv : range C ≃ ⋃ (e : {o' // o' < o}), (smaller C e.val) := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def GoodProducts.range_equiv : range C ≃ ⋃ (e : {o' // o' < o}), (smaller C e.val) := Equiv.setCongr (union C ho hsC) theorem GoodProducts.range_equiv_factorization : diff --git a/Mathlib/Topology/Compactness/SigmaCompact.lean b/Mathlib/Topology/Compactness/SigmaCompact.lean index 7adad95658a47b..d63b47913bcc46 100644 --- a/Mathlib/Topology/Compactness/SigmaCompact.lean +++ b/Mathlib/Topology/Compactness/SigmaCompact.lean @@ -199,7 +199,9 @@ variable [SigmaCompactSpace X] open SigmaCompactSpace /-- A choice of compact covering for a `σ`-compact space, chosen to be monotone. -/ -def compactCovering : ℕ → Set X := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def compactCovering : ℕ → Set X := accumulate exists_compact_covering.choose theorem isCompact_compactCovering (n : ℕ) : IsCompact (compactCovering X n) := diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 5caac6abf7f4d1..77f2be54b3eb9f 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -500,7 +500,9 @@ open scoped Classical in component of `x` in `F` is the connected component of `x` in the subtype `F` seen as a set in `α`. This definition does not make sense if `x` is not in `F` so we return the empty set in this case. -/ -def connectedComponentIn (F : Set α) (x : α) : Set α := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def connectedComponentIn (F : Set α) (x : α) : Set α := if h : x ∈ F then (↑) '' connectedComponent (⟨x, h⟩ : F) else ∅ theorem connectedComponentIn_eq_image {F : Set α} {x : α} (h : x ∈ F) : diff --git a/Mathlib/Topology/Instances/CantorSet.lean b/Mathlib/Topology/Instances/CantorSet.lean index 2f13fc37604fec..559ef80a5c80fd 100644 --- a/Mathlib/Topology/Instances/CantorSet.lean +++ b/Mathlib/Topology/Instances/CantorSet.lean @@ -39,7 +39,9 @@ This file defines the Cantor ternary set and proves a few properties. middle third of each interval. Formally, the order `n + 1` pre-Cantor set is the union of the images under the functions `(· / 3)` and `((2 + ·) / 3)` of `preCantorSet n`. -/ -def preCantorSet : ℕ → Set ℝ +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def preCantorSet : ℕ → Set ℝ | 0 => Set.Icc 0 1 | n + 1 => (· / 3) '' preCantorSet n ∪ (fun x ↦ (2 + x) / 3) '' preCantorSet n @@ -52,7 +54,9 @@ def preCantorSet : ℕ → Set ℝ pre-Cantor sets. This means that the Cantor set is obtained by iteratively removing the open middle third of each subinterval, starting from the unit interval `[0, 1]`. -/ -def cantorSet : Set ℝ := ⋂ n, preCantorSet n +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def cantorSet : Set ℝ := ⋂ n, preCantorSet n /-! diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 452d75ce3c439f..1b9488ed10d67b 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -133,7 +133,9 @@ lemma exists_mem_irreducibleComponents_subset_of_isIrreducible (s : Set X) (hs : /-- A maximal irreducible set that contains a given point. -/ @[stacks 004W "(4)"] -def irreducibleComponent (x : X) : Set X := +-- Note: `Set` has no computational content, but Lean still attempts to compile it. +-- See https://github.com/leanprover/lean4/issues/14084. +noncomputable def irreducibleComponent (x : X) : Set X := Classical.choose (exists_preirreducible {x} isPreirreducible_singleton) theorem irreducibleComponent_property (x : X) : diff --git a/Mathlib/Topology/UrysohnsLemma.lean b/Mathlib/Topology/UrysohnsLemma.lean index aa2e075d08d5fc..3d6524584b726f 100644 --- a/Mathlib/Topology/UrysohnsLemma.lean +++ b/Mathlib/Topology/UrysohnsLemma.lean @@ -82,7 +82,7 @@ lemmas about `midpoint`. Urysohn's lemma, normal topological space, locally compact topological space -/ -@[expose] public section +@[expose] public noncomputable section variable {X : Type*} [TopologicalSpace X] @@ -155,7 +155,7 @@ theorem subset_right_C (c : CU P) : c.C ⊆ c.right.C := /-- `n`-th approximation to a continuous function `f : X → ℝ` such that `f = 0` on `c.C` and `f = 1` outside of `c.U`. -/ -noncomputable def approx : ℕ → CU P → X → ℝ +def approx : ℕ → CU P → X → ℝ | 0, c, x => indicator c.Uᶜ 1 x | n + 1, c, x => midpoint ℝ (approx n c.left x) (approx n c.right x) @@ -237,7 +237,7 @@ theorem approx_mono (c : CU P) (x : X) : Monotone fun n => c.approx n x := * `0 ≤ f x ≤ 1` for all `x`; * `f` equals zero on `c.C` and equals one outside of `c.U`; -/ -protected noncomputable def lim (c : CU P) (x : X) : ℝ := +protected def lim (c : CU P) (x : X) : ℝ := ⨆ n, c.approx n x theorem tendsto_approx_atTop (c : CU P) (x : X) : From 38b74e6b6295a228f04cde8588d5a01bfa022ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 24 Jul 2026 07:59:59 +0000 Subject: [PATCH 0974/1300] =?UTF-8?q?chore(Data):=20move=20`IsStrictOrdere?= =?UTF-8?q?dRing=20=E2=84=9A=E2=89=A50`=20to=20`Algebra.Order`=20(#41850)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I need this in a later PR. Also take the opportunity to use `deriving` for two out of the three instances. --- Mathlib.lean | 1 + Mathlib/Algebra/Order/Ring/NNRat.lean | 35 ++++++++++++++++++++++++ Mathlib/Algebra/Order/Ring/Rat.lean | 9 +++--- Mathlib/Combinatorics/SetFamily/LYM.lean | 2 +- Mathlib/Data/Finset/Density.lean | 2 +- Mathlib/Data/NNRat/Floor.lean | 5 ++-- Mathlib/Data/NNRat/Order.lean | 15 +--------- Mathlib/Data/Rat/Star.lean | 2 +- Mathlib/RingTheory/Binomial.lean | 2 +- Mathlib/Topology/Instances/Rat.lean | 2 +- 10 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 Mathlib/Algebra/Order/Ring/NNRat.lean diff --git a/Mathlib.lean b/Mathlib.lean index 638124f2103e51..c5952d3640103a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1101,6 +1101,7 @@ public import Mathlib.Algebra.Order.Ring.InjSurj public import Mathlib.Algebra.Order.Ring.Int public import Mathlib.Algebra.Order.Ring.Interval public import Mathlib.Algebra.Order.Ring.IsNonarchimedean +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Algebra.Order.Ring.Nat public import Mathlib.Algebra.Order.Ring.Opposite public import Mathlib.Algebra.Order.Ring.Ordering.Basic diff --git a/Mathlib/Algebra/Order/Ring/NNRat.lean b/Mathlib/Algebra/Order/Ring/NNRat.lean new file mode 100644 index 00000000000000..2216eed6895640 --- /dev/null +++ b/Mathlib/Algebra/Order/Ring/NNRat.lean @@ -0,0 +1,35 @@ +/- +Copyright (c) 2019 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Mario Carneiro +-/ +module + +public import Mathlib.Algebra.Order.Ring.Rat +public import Mathlib.Algebra.Order.Nonneg.Ring +public import Mathlib.Data.NNRat.Defs + +/-! +# The nonnegative rational numbers form a linear ordered commutative semiring + +This file proves that the linear order on `ℚ≥0` makes it into an ordered semiring. + +`ℚ≥0` is in fact a linearly ordered semifield. To access this fact, one must also import +`Mathlib/Algebra/Field/Rat.lean`. + +## Tags + +rat, rationals, field, ℚ, numerator, denominator, num, denom, order, ordering +-/ + +assert_not_exists Field Finset + +public section + +namespace NNRat + +instance : IsStrictOrderedRing ℚ≥0 := Nonneg.isStrictOrderedRing + +deriving instance OrderedSub, CanonicallyOrderedAdd for NNRat + +end NNRat diff --git a/Mathlib/Algebra/Order/Ring/Rat.lean b/Mathlib/Algebra/Order/Ring/Rat.lean index c8c8ad5ae0b84c..58c6fa105e49a4 100644 --- a/Mathlib/Algebra/Order/Ring/Rat.lean +++ b/Mathlib/Algebra/Order/Ring/Rat.lean @@ -10,13 +10,12 @@ public import Mathlib.Algebra.Order.Ring.Unbundled.Rat public import Mathlib.Algebra.Ring.Rat /-! -# The rational numbers form a linear ordered field +# The rational numbers form a linear ordered commutative ring -This file constructs the order on `ℚ` and proves that `ℚ` is a discrete, linearly ordered -commutative ring. +This file proves that the linear order on `ℚ` makes it into an ordered ring. -`ℚ` is in fact a linearly ordered field, but this fact is located in `Data.Rat.Field` instead of -here because we need the order on `ℚ` to define `ℚ≥0`, which we itself need to define `Field`. +`ℚ` is in fact a linearly ordered field. To access this fact, one must also import +`Mathlib/Algebra/Field/Rat.lean`. ## Tags diff --git a/Mathlib/Combinatorics/SetFamily/LYM.lean b/Mathlib/Combinatorics/SetFamily/LYM.lean index 86cefa4a22f52c..a5d537a2359753 100644 --- a/Mathlib/Combinatorics/SetFamily/LYM.lean +++ b/Mathlib/Combinatorics/SetFamily/LYM.lean @@ -7,9 +7,9 @@ module public import Mathlib.Algebra.Field.Basic public import Mathlib.Algebra.Field.Rat +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Combinatorics.Enumerative.DoubleCounting public import Mathlib.Combinatorics.SetFamily.Shadow -public import Mathlib.Data.NNRat.Order public import Mathlib.Data.Nat.Cast.Order.Ring /-! diff --git a/Mathlib/Data/Finset/Density.lean b/Mathlib/Data/Finset/Density.lean index bd7d5064b003b5..847080985a91f1 100644 --- a/Mathlib/Data/Finset/Density.lean +++ b/Mathlib/Data/Finset/Density.lean @@ -6,8 +6,8 @@ Authors: Yaël Dillies module public import Mathlib.Algebra.Order.Field.Rat +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Data.Fintype.Card -public import Mathlib.Data.NNRat.Order public import Mathlib.Data.Rat.Cast.CharZero public import Mathlib.Tactic.Positivity.Basic diff --git a/Mathlib/Data/NNRat/Floor.lean b/Mathlib/Data/NNRat/Floor.lean index f7ec482a29d49e..eb35bbb93f5cd1 100644 --- a/Mathlib/Data/NNRat/Floor.lean +++ b/Mathlib/Data/NNRat/Floor.lean @@ -5,10 +5,11 @@ Authors: Eric Wieser -/ module +public meta import Mathlib.Data.Rat.Floor + public import Mathlib.Algebra.Order.Floor.Semiring -public import Mathlib.Data.NNRat.Order +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Data.Rat.Floor -public meta import Mathlib.Data.Rat.Floor /-! # Floor Function for Non-negative Rational Numbers diff --git a/Mathlib/Data/NNRat/Order.lean b/Mathlib/Data/NNRat/Order.lean index 84d67a31538acd..21027d5f34eec5 100644 --- a/Mathlib/Data/NNRat/Order.lean +++ b/Mathlib/Data/NNRat/Order.lean @@ -5,19 +5,6 @@ Authors: Yaël Dillies, Bhavik Mehta -/ module -public import Mathlib.Data.NNRat.Defs public import Mathlib.Algebra.Order.Ring.Rat -public import Mathlib.Algebra.Order.Nonneg.Ring -/-! -# Bundled ordered algebra structures on `ℚ≥0` - --/ - -public section - -instance : IsStrictOrderedRing ℚ≥0 := Nonneg.isStrictOrderedRing - --- TODO: `deriving instance OrderedSub for NNRat` doesn't work yet, so we add the instance manually -instance NNRat.instOrderedSub : OrderedSub ℚ≥0 := Nonneg.orderedSub -instance NNRat.instCanonicallyOrderedAdd : CanonicallyOrderedAdd ℚ≥0 := Nonneg.canonicallyOrderedAdd +deprecated_module (since := "2026-04-29") diff --git a/Mathlib/Data/Rat/Star.lean b/Mathlib/Data/Rat/Star.lean index 0e10b183895b52..dfbd8497525211 100644 --- a/Mathlib/Data/Rat/Star.lean +++ b/Mathlib/Data/Rat/Star.lean @@ -8,8 +8,8 @@ module public import Mathlib.Algebra.GroupWithZero.Commute public import Mathlib.Algebra.Order.Monoid.Submonoid public import Mathlib.Algebra.Order.Ring.Abs +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Algebra.Order.Star.Basic -public import Mathlib.Data.NNRat.Order /-! # Star ordered ring structures on `ℚ` and `ℚ≥0` diff --git a/Mathlib/RingTheory/Binomial.lean b/Mathlib/RingTheory/Binomial.lean index ede4089fd6784e..fea1415c4514d6 100644 --- a/Mathlib/RingTheory/Binomial.lean +++ b/Mathlib/RingTheory/Binomial.lean @@ -8,9 +8,9 @@ module public import Mathlib.Algebra.Algebra.Rat public import Mathlib.Algebra.Group.Torsion public import Mathlib.Algebra.Module.Rat +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Algebra.Polynomial.Smeval public import Mathlib.Algebra.Ring.NegOnePow -public import Mathlib.Data.NNRat.Order public import Mathlib.GroupTheory.GroupAction.Ring public import Mathlib.RingTheory.Polynomial.Pochhammer public import Mathlib.Tactic.Field diff --git a/Mathlib/Topology/Instances/Rat.lean b/Mathlib/Topology/Instances/Rat.lean index 41efad1a53bffe..1e2408bbc0fdd6 100644 --- a/Mathlib/Topology/Instances/Rat.lean +++ b/Mathlib/Topology/Instances/Rat.lean @@ -7,7 +7,7 @@ module public import Mathlib.Algebra.Algebra.Rat public import Mathlib.Algebra.Module.Rat -public import Mathlib.Data.NNRat.Order +public import Mathlib.Algebra.Order.Ring.NNRat public import Mathlib.Topology.Algebra.Order.Archimedean public import Mathlib.Topology.Algebra.Ring.Real public import Mathlib.Topology.Instances.Nat From 44ea3a0e13339f31231dde209c4f8196e179065d Mon Sep 17 00:00:00 2001 From: Jon Eugster <9141564+joneugster@users.noreply.github.com> Date: Fri, 24 Jul 2026 08:39:15 +0000 Subject: [PATCH 0975/1300] feat(scripts/autolabel): use `Cli` and integrate `curl` call into `autolabel` (#34952) - use `Cli` for `lake exe autolabel` - add arguments `--pr xxx --gh` and `--pr xxx --curl ` to chose between different interaction methods with github - add `--force` to skip the check whether labels are already present. (note: the current `curl` setup doesn't perform this step and neither does the refactor, so I added a `Todo` to remember this. ) - make CI-workflow simpler and more robust by removing current stdout-parsing of the debug-messages which `autolabel` emits. - remove CI-trigger on `push`: this was useful back in the days when PRs happened on mathlib4-branches, as it allowed changes to the workflow to be tested directly in the PR. Since this used a security gap which has been closed since, we remove that code completely. ### Testing Make some local changes and commit them. Ensure your local `origin/master` is in sync with `upstream/master` if you are on a fork. - `lake exe autolabel`: prints the labels which would be applicable - `lake exe autolabel --pr 34952 --gh --force` adds these labels to this PR using `gh`. - `lake exe autolabel --pr 34952 --gh` adds these labels to this PR using `gh` if no topic labels are present. - `lake exe autolabel --pr 34952 --curl ` adds these labels to this PR using `curl`. This requires a github access token for authentication --- .github/workflows/add_label_from_diff.yaml | 30 +---- scripts/autolabel.lean | 134 +++++++++++++-------- 2 files changed, 85 insertions(+), 79 deletions(-) diff --git a/.github/workflows/add_label_from_diff.yaml b/.github/workflows/add_label_from_diff.yaml index 3738c9c273d046..3e79bd0b360971 100644 --- a/.github/workflows/add_label_from_diff.yaml +++ b/.github/workflows/add_label_from_diff.yaml @@ -3,10 +3,6 @@ name: Autolabel PRs on: pull_request_target: types: [opened] - push: - paths: - - scripts/autolabel.lean - - .github/workflows/add_label_from_diff.yaml # Limit permissions for GITHUB_TOKEN for the entire workflow permissions: @@ -51,31 +47,7 @@ jobs: - name: Run autolabel working-directory: pr-branch run: | - labels="$("${GITHUB_WORKSPACE}/tools/.lake/build/bin/autolabel")" - printf '%s\n' "${labels}" - # extract - label="$(printf '%s' "${labels}" | sed -n 's=^::notice::.*#\[\([^,]*\)\].*=\1=p')" - printf 'label: "%s"\n' "${label}" - if [ -n "${label}" ] && [ -n "${PR_NUMBER}" ] - then - printf 'Applying label %s\n' "${label}" - # we use curl rather than octokit/request-action so that the job won't fail - # (and send an annoying email) if the labels don't exist - url="https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/labels" - printf 'url: %s\n' "${url}" - jsonLabel="$(printf '{"labels":["%s"]}' "${label}")" - printf 'jsonLabel: %s\n' "${jsonLabel}" - curl --request POST \ - --header 'Accept: application/vnd.github+json' \ - --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ - --header 'X-GitHub-Api-Version: 2022-11-28' \ - --url "${url}" \ - --data "${jsonLabel}" - else - echo "There is no single label that we could apply, so we are not applying any label." - fi + "${GITHUB_WORKSPACE}/tools/.lake/build/bin/autolabel" --pr "${{ github.event.pull_request.number }}" --curl "${{ secrets.GITHUB_TOKEN }}" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # the PR number could be undefined in workflows triggered by 'push', - # in which case we only log the applicable label and exit PR_NUMBER: ${{ github.event.pull_request.number }} diff --git a/scripts/autolabel.lean b/scripts/autolabel.lean index 20ae2508666034..e9b4031194fc9b 100644 --- a/scripts/autolabel.lean +++ b/scripts/autolabel.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jon Eugster, Damiano Testa -/ import Lean.Elab.Command +import Cli.Basic /-! # Automatic labelling of PRs @@ -27,9 +28,7 @@ needs to be updated here if necessary: files have been modified and then finds all labels which should be added based on these changes. These are printed for testing purposes. -`lake exe autolabel [NUMBER]` will further try to add the applicable labels -to the PR specified. This requires the **GitHub CLI** `gh` to be installed! -Example: `lake exe autolabel 10402` for PR https://github.com/leanprover-community/mathlib4/pull/10402. +See `lake exe autolabel --help` for all arguments available. The script can add up to `MAX_LABELS` labels (defined below). If more than `MAX_LABELS` labels would be applicable, nothing happens. @@ -381,29 +380,24 @@ Note: `file` is duplicated below so that it is also visible in the plain text ou def githubAnnotation (type file title message : String) : String := s!"::{type} file={file},title={title}::{file}: {message}" -end AutoLabel - -open IO AutoLabel in - -/-- `args` is expected to have length 0 or 1, where the first argument is the PR number. - -If a PR number is provided, the script requires GitHub CLI `gh` to be installed in order -to add the label to the PR. - -## Exit codes: - -- `0`: success -- `1`: invalid arguments provided -- `2`: invalid labels defined -- `3`: ~labels do not cover all of `Mathlib/`~ (unused; only emitting warning) --/ -unsafe def main (args : List String): IO UInt32 := do - if args.length > 1 then - println s!"::error:: autolabel: invalid number of arguments ({args.length}), \ - expected at most 1. Please run without arguments or provide the target PR's \ - number as a single argument!" - return 1 - let prNumber? := args[0]? +/-- Available implementations about how to communicate with Github -/ +inductive GithubInteraction where +/-- no interaction with github -/ +| none +/-- use `gh` -/ +| gh (pr : Nat) +/-- use `curl` with an access token -/ +| curl (pr : Nat) (token : String) + +open IO in +def autoLabelCli (args : Cli.Parsed) : IO UInt32 := do + let force := args.hasFlag "force" + let tool: GithubInteraction := + match ((args.flag? "pr").map (·.as! Nat)), args.hasFlag "gh", args.flag? "curl" with + | none, _, _ => .none + | some _, false, none => .none + | some pr, true, _ => .gh pr + | some pr, false, some curlFlag => .curl pr (curlFlag.as! String) -- test: validate that all paths in `mathlibLabelData` actually exist let mut valid := true @@ -441,41 +435,81 @@ unsafe def main (args : List String): IO UInt32 := do -- return 3 -- get the modified files - println "Computing 'git diff --name-only origin/master...HEAD'" let gitDiff ← IO.Process.run { cmd := "git", args := #["diff", "--name-only", "origin/master...HEAD"] } - println s!"---\n{gitDiff}\n---" let modifiedFiles : Array FilePath := (gitDiff.splitOn "\n").toArray.map (⟨·⟩) -- find labels covering the modified files - let labels := dropDependentLabels <| getMatchingLabels modifiedFiles - println s!"::notice::Applicable labels: {labels}" + let newLabels := dropDependentLabels <| getMatchingLabels modifiedFiles + println s!"::notice::Applicable labels: {newLabels}" - match labels with + match newLabels with | #[] => - println s!"::warning::no label to add" + println s!"::warning::no labels to add" | newLabels => - match prNumber? with - | some n => - if newLabels.size > MAX_LABELS then - println s!"::notice::not adding more than {MAX_LABELS} labels: {newLabels}" - return 0 - let labelsPresent ← IO.Process.run { + if newLabels.size > MAX_LABELS then + println s!"::notice::not adding more than {MAX_LABELS} labels: {newLabels}" + return 0 + match tool with + | .gh prNr => + let labelsPresent ← if force then pure "" else IO.Process.run { cmd := "gh" - args := #["pr", "view", n, "--json", "labels", "--jq", ".labels .[] .name"]} - let labels := labelsPresent.splitToList (· == '\n') + args := #["pr", "view", s!"{prNr}", "--json", "labels", "--jq", ".labels .[] .name"]} + let existingLabels := labelsPresent.splitToList (· == '\n') let autoLabels := mathlibLabels.map (·.toString) - match labels.filter autoLabels.contains with - | [] => -- if the PR does not have a label that this script could add, then we add a label + match existingLabels.filter autoLabels.contains with + | [] => let _ ← IO.Process.run { cmd := "gh", - args := #["pr", "edit", n, "--add-label", s!"\"{",".intercalate <| newLabels.toList.map (·.toString)}\""] } - println s!"::notice::added labels: {newLabels}" - | t_labels_already_present => - println s!"::notice::Did not add labels '{newLabels}', \ - since {t_labels_already_present} were already present" - | none => - println s!"::warning::no PR-number provided, not adding labels. \ - (call `lake exe autolabel 150602` to add the labels to PR `150602`)" + args := #["pr", "edit", s!"{prNr}", "--add-label", ",".intercalate <| newLabels.toList.map (·.toString)] } + println s!"::notice::added label: {newLabels}" + | t_labels_already_present => + println s!"::notice::did not add labels '{newLabels}', since {t_labels_already_present} \ + were already present" + | .curl prNr token => + -- TODO: take existing labels on the PR into account + let _ ← IO.Process.run { + cmd := "curl", + args := #[ + "--request", "POST", + "--header", "Accept: application/vnd.github+json", + "--header", s!"authorization: Bearer {token}", + "--header", "X-GitHub-Api-Version: 2022-11-28", + "--url", s!"https://api.github.com/repos/leanprover-community/mathlib4/issues/{prNr}/labels", + "--data", "{\"labels\":[\"" ++ s!"{"\",\"".intercalate <| newLabels.toList.map (·.toString)}" ++ "\"]}" + ]} + println s!"::notice::added label: {newLabels}" + | .none => + println s!"::notice::github interaction disabled, not adding labels." return 0 + +end AutoLabel + +/-- Setting up command line options and help text for `lake exe autolabel` -/ +def autolabel : Cli.Cmd := `[Cli| + autolabel VIA AutoLabel.autoLabelCli; ["0.1.0"] + " + Determine a list of applicable mathlib labels comparing current changes to `origin/master`. + + This tool is mathlib-specific and has no application in downstream projects. + " + FLAGS: + "pr" : Nat; "the mathlib PR number. Must be combined with `--gh` or `--curl`." + "gh"; "apply label(s) using `gh`. Usage: `lake exe autolabel --pr 20156 --gh`" + "curl" : String; "apply label(s) using `curl`. \ + Usage: `lake exe autolabel --pr 20156 --curl `. \ + (currently, this implies `--force`)" + "force"; "apply labels even if there are already labels on the PR." +] + +/-- lake exe autolabel + +## Exit codes: + +- `0`: success +- `2`: invalid labels defined +- `3`: ~labels do not cover all of `Mathlib/`~ (unused; only emitting warning) +-/ +public def main (args : List String) : IO UInt32 := + autolabel.validate args From c6ef9d7c1a509fa04df7f3cf2dbf72e74e214be4 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:14:53 +0000 Subject: [PATCH 0976/1300] chore(Algebra): remove an `erw` (#40310) Co-authored-by: Batixx --- Mathlib/Algebra/Ring/Divisibility/Basic.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Ring/Divisibility/Basic.lean b/Mathlib/Algebra/Ring/Divisibility/Basic.lean index 05bb2b130d1cc7..0d86efaaf2ecb2 100644 --- a/Mathlib/Algebra/Ring/Divisibility/Basic.lean +++ b/Mathlib/Algebra/Ring/Divisibility/Basic.lean @@ -39,10 +39,9 @@ theorem MulEquiv.decompositionMonoid (f : F) [DecompositionMonoid β] : Decompos primal a b c h := by rw [← map_dvd_iff f, map_mul] at h obtain ⟨a₁, a₂, h⟩ := DecompositionMonoid.primal _ h - refine ⟨symm f a₁, symm f a₂, ?_⟩ - simp_rw [← map_dvd_iff f, ← map_mul, eq_symm_apply] - iterate 2 erw [(f : α ≃* β).apply_symm_apply] - exact h + refine ⟨EquivLike.inv f a₁, EquivLike.inv f a₂, ?_⟩ + simp_rw [← map_dvd_iff f, EquivLike.apply_inv_apply, h, true_and, ← EquivLike.apply_eq_iff_eq f, + h.2.2, map_mul, EquivLike.apply_inv_apply] /-- If `G` is a `LeftCancelSemiGroup`, left multiplication by `g` yields an equivalence between `G` From c8f8b4a345a19bf3c689e8965eec8cf628f1b8ff Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:53:01 +0000 Subject: [PATCH 0977/1300] chore(Order): fix defs with underscore in their names (#41878) Per naming convention, defs should not have underscores in their name. This is also counted as strong technical debt, according to the counter we have 493 right now. This PR fixes all of them in Mathlib/Order except one, namely [RelIso.Simps.symm_apply](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Order/RelIso/Basic.html#RelIso.Simps.symm_apply), which is a bit weird. All renames here are quite simple, just go from `snake_case` to `lowerCamelCase` (+ add deprecations). If this PR looks good, i would be happy to do this to the (vast majority of) other defs with underscore in mathlib. :) Co-authored-by: Batixx --- Mathlib/Algebra/Lie/Semisimple/Basic.lean | 4 +- Mathlib/Data/Set/Lattice.lean | 2 +- .../Constructions/BorelSpace/Order.lean | 2 +- Mathlib/Order/BooleanGenerators.lean | 20 ++++++---- Mathlib/Order/Category/NonemptyFinLinOrd.lean | 5 ++- Mathlib/Order/Filter/Ker.lean | 21 +++++----- Mathlib/Order/GaloisConnection/Basic.lean | 10 ++++- Mathlib/Order/LiminfLimsup.lean | 40 +++++++++++-------- 8 files changed, 64 insertions(+), 40 deletions(-) diff --git a/Mathlib/Algebra/Lie/Semisimple/Basic.lean b/Mathlib/Algebra/Lie/Semisimple/Basic.lean index 8775195af3224d..a4cb98dc4eb69a 100644 --- a/Mathlib/Algebra/Lie/Semisimple/Basic.lean +++ b/Mathlib/Algebra/Lie/Semisimple/Basic.lean @@ -277,11 +277,11 @@ lemma booleanGenerators : BooleanGenerators {I : LieIdeal R L | IsAtom I} where finitelyAtomistic _ _ hs _ hIs := finitelyAtomistic _ hs _ hIs instance (priority := 100) instDistribLattice : DistribLattice (LieIdeal R L) := - (booleanGenerators R L).distribLattice_of_sSup_eq_top sSup_atoms_eq_top + (booleanGenerators R L).distribLatticeOfSSupEqTop sSup_atoms_eq_top noncomputable instance (priority := 100) instBooleanAlgebra : BooleanAlgebra (LieIdeal R L) := - (booleanGenerators R L).booleanAlgebra_of_sSup_eq_top sSup_atoms_eq_top + (booleanGenerators R L).booleanAlgebraOfSSupEqTop sSup_atoms_eq_top /-- A semisimple Lie algebra has trivial radical. -/ instance (priority := 100) instHasTrivialRadical : HasTrivialRadical R L := by diff --git a/Mathlib/Data/Set/Lattice.lean b/Mathlib/Data/Set/Lattice.lean index f93f4440df8a70..57cde84ea757e2 100644 --- a/Mathlib/Data/Set/Lattice.lean +++ b/Mathlib/Data/Set/Lattice.lean @@ -884,7 +884,7 @@ theorem sUnion_powerset_gc : /-- `⋃₀` and `𝒫` form a Galois insertion. -/ def sUnionPowersetGI : GaloisInsertion (⋃₀ · : Set (Set α) → Set α) (𝒫 · : Set α → Set (Set α)) := - gi_sSup_Iic + giSSupIic /-- If all sets in a collection are either `∅` or `Set.univ`, then so is their union. -/ theorem sUnion_mem_empty_univ {S : Set (Set α)} (h : S ⊆ {∅, univ}) : diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index 62d08038e1fecf..0cf4995802c825 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -1018,7 +1018,7 @@ theorem Measurable.liminf' {ι ι'} {f : ι → δ → α} {v : Filter ι} (hf : rw [ofPred_forall] exact MeasurableSet.iInter (fun j ↦ (m_meas j).compl) refine measurable_const.piecewise mc_meas <| .iSup fun j ↦ ?_ - let reparam : δ → Subtype p → Subtype p := fun x ↦ liminf_reparam (fun i ↦ f i x) s p + let reparam : δ → Subtype p → Subtype p := fun x ↦ liminfReparam (fun i ↦ f i x) s p let F0 : Subtype p → δ → α := fun j x ↦ ⨅ (i : s j), f i x have F0_meas : ∀ j, Measurable (F0 j) := fun j ↦ .iInf (fun (i : s j) ↦ hf i) set F1 : δ → α := fun x ↦ F0 (reparam x j) x with hF1 diff --git a/Mathlib/Order/BooleanGenerators.lean b/Mathlib/Order/BooleanGenerators.lean index e152409d611100..ef9f5b2744773d 100644 --- a/Mathlib/Order/BooleanGenerators.lean +++ b/Mathlib/Order/BooleanGenerators.lean @@ -25,9 +25,9 @@ A set of *Boolean generators* in a compactly generated complete lattice is a sub the predicate described above. * `IsCompactlyGenerated.BooleanGenerators.complementedLattice_of_sSup_eq_top`: if `S` generates the entire lattice, then it is complemented. -* `IsCompactlyGenerated.BooleanGenerators.distribLattice_of_sSup_eq_top`: +* `IsCompactlyGenerated.BooleanGenerators.distribLatticeOfSSupEqTop`: if `S` generates the entire lattice, then it is distributive. -* `IsCompactlyGenerated.BooleanGenerators.booleanAlgebra_of_sSup_eq_top`: +* `IsCompactlyGenerated.BooleanGenerators.booleanAlgebraOfSSupEqTop`: if `S` generates the entire lattice, then it is a Boolean algebra. -/ @@ -52,7 +52,7 @@ A set of *Boolean generators* in a compactly generated complete lattice is a sub If the supremum of `S` is the whole lattice, then the lattice is a Boolean algebra -(see `IsCompactlyGenerated.BooleanGenerators.booleanAlgebra_of_sSup_eq_top`). +(see `IsCompactlyGenerated.BooleanGenerators.booleanAlgebraOfSSupEqTop`). -/ structure BooleanGenerators (S : Set α) : Prop where /-- The elements in a collection of Boolean generators are all atoms. -/ @@ -140,7 +140,7 @@ lemma sSup_inter (hS : BooleanGenerators S) {T₁ T₂ : Set α} (hT₁ : T₁ /-- A lattice generated by Boolean generators is a distributive lattice. -/ @[instance_reducible] -def distribLattice_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S = ⊤) : +def distribLatticeOfSSupEqTop (hS : BooleanGenerators S) (h : sSup S = ⊤) : DistribLattice α where le_sup_inf a b c := by obtain ⟨Ta, hTa, rfl⟩ := hS.atomistic a (h ▸ le_top) @@ -153,20 +153,26 @@ def distribLattice_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S = ⊤) simp only [Set.union_subset_iff, Set.mem_inter_iff, Set.mem_union] tauto +@[deprecated (since := "2026-07-18")] +alias distribLattice_of_sSup_eq_top := distribLatticeOfSSupEqTop + lemma complementedLattice_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S = ⊤) : ComplementedLattice α := by - let _i := hS.distribLattice_of_sSup_eq_top h + let _i := hS.distribLatticeOfSSupEqTop h have _i₁ := isAtomistic_of_sSup_eq_top hS h apply complementedLattice_of_isAtomistic /-- A compactly generated complete lattice generated by Boolean generators is a Boolean algebra. -/ @[instance_reducible] noncomputable -def booleanAlgebra_of_sSup_eq_top (hS : BooleanGenerators S) (h : sSup S = ⊤) : BooleanAlgebra α := - let _i := hS.distribLattice_of_sSup_eq_top h +def booleanAlgebraOfSSupEqTop (hS : BooleanGenerators S) (h : sSup S = ⊤) : BooleanAlgebra α := + let _i := hS.distribLatticeOfSSupEqTop h have := hS.complementedLattice_of_sSup_eq_top h DistribLattice.booleanAlgebraOfComplemented α +@[deprecated (since := "2026-07-18")] +alias booleanAlgebra_of_sSup_eq_top := booleanAlgebraOfSSupEqTop + lemma sSup_le_sSup_iff_of_atoms (hS : BooleanGenerators S) (X Y : Set α) (hX : X ⊆ S) (hY : Y ⊆ S) : sSup X ≤ sSup Y ↔ X ⊆ Y := by refine ⟨?_, sSup_le_sSup⟩ diff --git a/Mathlib/Order/Category/NonemptyFinLinOrd.lean b/Mathlib/Order/Category/NonemptyFinLinOrd.lean index 06094177458cbd..b17955e0d9b334 100644 --- a/Mathlib/Order/Category/NonemptyFinLinOrd.lean +++ b/Mathlib/Order/Category/NonemptyFinLinOrd.lean @@ -228,4 +228,7 @@ def nonemptyFinLinOrdDualCompForgetToFinPartOrd : inv.app X := FinPartOrd.ofHom OrderHom.id /-- The generating arrow `i ⟶ i+1` in the category `Fin n` -/ -def Fin.hom_succ {n} (i : Fin n) : i.castSucc ⟶ i.succ := homOfLE (Fin.castSucc_le_succ i) +def Fin.homSucc {n} (i : Fin n) : i.castSucc ⟶ i.succ := homOfLE (Fin.castSucc_le_succ i) + +@[deprecated (since := "2026-07-18")] +alias Fin.hom_succ := Fin.homSucc diff --git a/Mathlib/Order/Filter/Ker.lean b/Mathlib/Order/Filter/Ker.lean index 9e397bb1f6d2e9..eee196ab879368 100644 --- a/Mathlib/Order/Filter/Ker.lean +++ b/Mathlib/Order/Filter/Ker.lean @@ -31,22 +31,25 @@ lemma ker_def (f : Filter α) : f.ker = ⋂ s ∈ f, s := sInter_eq_biInter @[simp] lemma subset_ker : s ⊆ f.ker ↔ ∀ t ∈ f, s ⊆ t := subset_sInter_iff /-- `Filter.principal` forms a Galois coinsertion with `Filter.ker`. -/ -def gi_principal_ker : GaloisCoinsertion (𝓟 : Set α → Filter α) ker := +def giPrincipalKer : GaloisCoinsertion (𝓟 : Set α → Filter α) ker := GaloisConnection.toGaloisCoinsertion (fun s f ↦ by simp [principal_le_iff]) <| by simp only [subset_def, mem_ker, mem_principal]; aesop -lemma ker_mono : Monotone (ker : Filter α → Set α) := gi_principal_ker.gc.monotone_u -lemma ker_surjective : Surjective (ker : Filter α → Set α) := gi_principal_ker.u_surjective +@[deprecated (since := "2026-07-18")] +alias gi_principal_ker := giPrincipalKer + +lemma ker_mono : Monotone (ker : Filter α → Set α) := giPrincipalKer.gc.monotone_u +lemma ker_surjective : Surjective (ker : Filter α → Set α) := giPrincipalKer.u_surjective @[simp] lemma ker_bot : ker (⊥ : Filter α) = ∅ := sInter_eq_empty_iff.2 fun _ ↦ ⟨∅, trivial, id⟩ -@[simp] lemma ker_top : ker (⊤ : Filter α) = univ := gi_principal_ker.gc.u_top -@[simp] lemma ker_eq_univ : ker f = univ ↔ f = ⊤ := gi_principal_ker.gc.u_eq_top.trans <| by simp -@[simp] lemma ker_inf (f g : Filter α) : ker (f ⊓ g) = ker f ∩ ker g := gi_principal_ker.gc.u_inf +@[simp] lemma ker_top : ker (⊤ : Filter α) = univ := giPrincipalKer.gc.u_top +@[simp] lemma ker_eq_univ : ker f = univ ↔ f = ⊤ := giPrincipalKer.gc.u_eq_top.trans <| by simp +@[simp] lemma ker_inf (f g : Filter α) : ker (f ⊓ g) = ker f ∩ ker g := giPrincipalKer.gc.u_inf @[simp] lemma ker_iInf (f : ι → Filter α) : ker (⨅ i, f i) = ⋂ i, ker (f i) := - gi_principal_ker.gc.u_iInf + giPrincipalKer.gc.u_iInf @[simp] lemma ker_sInf (S : Set (Filter α)) : ker (sInf S) = ⋂ f ∈ S, ker f := - gi_principal_ker.gc.u_sInf -@[simp] lemma ker_principal (s : Set α) : ker (𝓟 s) = s := gi_principal_ker.u_l_eq _ + giPrincipalKer.gc.u_sInf +@[simp] lemma ker_principal (s : Set α) : ker (𝓟 s) = s := giPrincipalKer.u_l_eq _ @[simp] lemma ker_pure (a : α) : ker (pure a) = {a} := by rw [← principal_singleton, ker_principal] diff --git a/Mathlib/Order/GaloisConnection/Basic.lean b/Mathlib/Order/GaloisConnection/Basic.lean index a626179797da76..b9c0ea6b1e3bd9 100644 --- a/Mathlib/Order/GaloisConnection/Basic.lean +++ b/Mathlib/Order/GaloisConnection/Basic.lean @@ -418,15 +418,21 @@ theorem gc_Ici_sInf [CompleteSemilatticeInf α] : fun _ _ ↦ le_sInf_iff.symm /-- `sSup` and `Iic` form a Galois insertion. -/ -def gi_sSup_Iic [CompleteSemilatticeSup α] : +def giSSupIic [CompleteSemilatticeSup α] : GaloisInsertion (sSup : Set α → α) (Iic : α → Set α) := gc_sSup_Iic.toGaloisInsertion fun _ ↦ le_sSup le_rfl +@[deprecated (since := "2026-07-18")] +alias gi_sSup_Iic := giSSupIic + /-- `toDual ∘ Ici` and `sInf ∘ ofDual` form a Galois coinsertion. -/ -def gci_Ici_sInf [CompleteSemilatticeInf α] : +def gciIciSInf [CompleteSemilatticeInf α] : GaloisCoinsertion (toDual ∘ Ici : α → (Set α)ᵒᵈ) (sInf ∘ ofDual : (Set α)ᵒᵈ → α) := gc_Ici_sInf.toGaloisCoinsertion fun _ ↦ sInf_le le_rfl +@[deprecated (since := "2026-07-18")] +alias gci_Ici_sInf := gciIciSInf + /-- If `α` is a partial order with bottom element (e.g., `ℕ`, `ℝ≥0`), then `WithBot.unbot' ⊥` and coercion form a Galois insertion. -/ @[to_dual giUntopDTop diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index 4b9e2442ba5f3d..0294720f9cad97 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -974,12 +974,12 @@ section Classical open scoped Classical in /-- Given an indexed family of sets `s j` over `j : Subtype p` and a function `f`, then -`liminf_reparam j` is equal to `j` if `f` is bounded below on `s j`, and otherwise to some +`liminfReparam j` is equal to `j` if `f` is bounded below on `s j`, and otherwise to some index `k` such that `f` is bounded below on `s k` (if there exists one). To ensure good measurability behavior, this index `k` is chosen as the minimal suitable index. This function is used to write down a liminf in a measurable way, in `Filter.HasBasis.liminf_eq_ciSup_ciInf` and `Filter.HasBasis.liminf_eq_ite`. -/ -noncomputable def liminf_reparam +noncomputable def liminfReparam (f : ι → α) (s : ι' → Set ι) (p : ι' → Prop) [Countable (Subtype p)] [Nonempty (Subtype p)] (j : Subtype p) : Subtype p := let m : Set (Subtype p) := {j | BddBelow (range (fun (i : s j) ↦ f i))} @@ -992,6 +992,9 @@ noncomputable def liminf_reparam · exact ⟨0, Or.inr H⟩ if j ∈ m then j else g (Nat.find Z) +@[deprecated (since := "2026-07-18")] +alias liminf_reparam := liminfReparam + /-- Writing a liminf as a supremum of infimum, in a (possibly non-complete) conditionally complete linear order. A reparametrization trick is needed to avoid taking the infimum of sets which are not bounded below. -/ @@ -999,31 +1002,31 @@ theorem HasBasis.liminf_eq_ciSup_ciInf {v : Filter ι} {p : ι' → Prop} {s : ι' → Set ι} [Countable (Subtype p)] [Nonempty (Subtype p)] (hv : v.HasBasis p s) {f : ι → α} (hs : ∀ (j : Subtype p), (s j).Nonempty) (H : ∃ (j : Subtype p), BddBelow (range (fun (i : s j) ↦ f i))) : - liminf f v = ⨆ (j : Subtype p), ⨅ (i : s (liminf_reparam f s p j)), f i := by + liminf f v = ⨆ (j : Subtype p), ⨅ (i : s (liminfReparam f s p j)), f i := by classical rcases H with ⟨j0, hj0⟩ let m : Set (Subtype p) := {j | BddBelow (range (fun (i : s j) ↦ f i))} have : ∀ (j : Subtype p), Nonempty (s j) := fun j ↦ Nonempty.coe_sort (hs j) have A : ⋃ (j : Subtype p), ⋂ (i : s j), Iic (f i) = - ⋃ (j : Subtype p), ⋂ (i : s (liminf_reparam f s p j)), Iic (f i) := by + ⋃ (j : Subtype p), ⋂ (i : s (liminfReparam f s p j)), Iic (f i) := by apply Subset.antisymm · apply iUnion_subset (fun j ↦ ?_) by_cases hj : j ∈ m - · have : j = liminf_reparam f s p j := by simp only [m, liminf_reparam, hj, ite_true] + · have : j = liminfReparam f s p j := by simp only [m, liminfReparam, hj, ite_true] conv_lhs => rw [this] apply subset_iUnion _ j · simp only [m, mem_ofPred_eq, ← nonempty_iInter_Iic_iff, not_nonempty_iff_eq_empty] at hj simp only [hj, empty_subset] · apply iUnion_subset (fun j ↦ ?_) - exact subset_iUnion (fun (k : Subtype p) ↦ (⋂ (i : s k), Iic (f i))) (liminf_reparam f s p j) - have B : ∀ (j : Subtype p), ⋂ (i : s (liminf_reparam f s p j)), Iic (f i) = - Iic (⨅ (i : s (liminf_reparam f s p j)), f i) := by + exact subset_iUnion (fun (k : Subtype p) ↦ (⋂ (i : s k), Iic (f i))) (liminfReparam f s p j) + have B : ∀ (j : Subtype p), ⋂ (i : s (liminfReparam f s p j)), Iic (f i) = + Iic (⨅ (i : s (liminfReparam f s p j)), f i) := by intro j apply (Iic_ciInf _).symm - change liminf_reparam f s p j ∈ m + change liminfReparam f s p j ∈ m by_cases Hj : j ∈ m - · simpa only [m, liminf_reparam, if_pos Hj] using Hj - · simp only [m, liminf_reparam, if_neg Hj] + · simpa only [m, liminfReparam, if_pos Hj] using Hj + · simp only [m, liminfReparam, if_neg Hj] have Z : ∃ n, (exists_surjective_nat (Subtype p)).choose n ∈ m ∨ ∀ j, j ∉ m := by rcases (exists_surjective_nat (Subtype p)).choose_spec j0 with ⟨n, rfl⟩ exact ⟨n, Or.inl hj0⟩ @@ -1040,7 +1043,7 @@ theorem HasBasis.liminf_eq_ite {v : Filter ι} {p : ι' → Prop} {s : ι' → S [Countable (Subtype p)] [Nonempty (Subtype p)] (hv : v.HasBasis p s) (f : ι → α) : liminf f v = if ∃ (j : Subtype p), s j = ∅ then sSup univ else if ∀ (j : Subtype p), ¬BddBelow (range (fun (i : s j) ↦ f i)) then sSup ∅ - else ⨆ (j : Subtype p), ⨅ (i : s (liminf_reparam f s p j)), f i := by + else ⨆ (j : Subtype p), ⨅ (i : s (liminfReparam f s p j)), f i := by by_cases H : ∃ (j : Subtype p), s j = ∅ · rw [if_pos H] rcases H with ⟨j, hj⟩ @@ -1058,15 +1061,18 @@ theorem HasBasis.liminf_eq_ite {v : Filter ι} {p : ι' → Prop} {s : ι' → S · push Not at H' exact H' -/-- Given an indexed family of sets `s j` and a function `f`, then `limsup_reparam j` is equal +/-- Given an indexed family of sets `s j` and a function `f`, then `limsupReparam j` is equal to `j` if `f` is bounded above on `s j`, and otherwise to some index `k` such that `f` is bounded above on `s k` (if there exists one). To ensure good measurability behavior, this index `k` is chosen as the minimal suitable index. This function is used to write down a limsup in a measurable way, in `Filter.HasBasis.limsup_eq_ciInf_ciSup` and `Filter.HasBasis.limsup_eq_ite`. -/ -noncomputable def limsup_reparam +noncomputable def limsupReparam (f : ι → α) (s : ι' → Set ι) (p : ι' → Prop) [Countable (Subtype p)] [Nonempty (Subtype p)] (j : Subtype p) : Subtype p := - liminf_reparam (α := αᵒᵈ) f s p j + liminfReparam (α := αᵒᵈ) f s p j + +@[deprecated (since := "2026-07-18")] +alias limsup_reparam := limsupReparam /-- Writing a limsup as an infimum of supremum, in a (possibly non-complete) conditionally complete linear order. A reparametrization trick is needed to avoid taking the supremum of sets which are @@ -1075,7 +1081,7 @@ theorem HasBasis.limsup_eq_ciInf_ciSup {v : Filter ι} {p : ι' → Prop} {s : ι' → Set ι} [Countable (Subtype p)] [Nonempty (Subtype p)] (hv : v.HasBasis p s) {f : ι → α} (hs : ∀ (j : Subtype p), (s j).Nonempty) (H : ∃ (j : Subtype p), BddAbove (range (fun (i : s j) ↦ f i))) : - limsup f v = ⨅ (j : Subtype p), ⨆ (i : s (limsup_reparam f s p j)), f i := + limsup f v = ⨅ (j : Subtype p), ⨆ (i : s (limsupReparam f s p j)), f i := HasBasis.liminf_eq_ciSup_ciInf (α := αᵒᵈ) hv hs H open scoped Classical in @@ -1086,7 +1092,7 @@ theorem HasBasis.limsup_eq_ite {v : Filter ι} {p : ι' → Prop} {s : ι' → S [Countable (Subtype p)] [Nonempty (Subtype p)] (hv : v.HasBasis p s) (f : ι → α) : limsup f v = if ∃ (j : Subtype p), s j = ∅ then sInf univ else if ∀ (j : Subtype p), ¬BddAbove (range (fun (i : s j) ↦ f i)) then sInf ∅ - else ⨅ (j : Subtype p), ⨆ (i : s (limsup_reparam f s p j)), f i := + else ⨅ (j : Subtype p), ⨆ (i : s (limsupReparam f s p j)), f i := HasBasis.liminf_eq_ite (α := αᵒᵈ) hv f end Classical From 3cb224193b71588ebd13864e19be8a10af6ebe5a Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 24 Jul 2026 10:39:53 +0000 Subject: [PATCH 0978/1300] perf(FieldTheory/CardinalEmb): golf `succEquiv_coherence` (#41704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace a big `simp` with `rfl`, which speeds up kernel typechecking and removes a `set_option backward.isDefEq.respectTransparency false`. Remove two `have` lines in `instance (i : ι) : Algebra.IsSeparable (E⟮ Date: Fri, 24 Jul 2026 10:39:55 +0000 Subject: [PATCH 0979/1300] chore(Order/Antidiag/Pi): review API and remove backward options (#41874) This PR golfs some proofs, removes local notation (which means the theorem displays more nicely in Loogle + docs), and removes some `set_option backward.isDefEq.respectTransparency.types false in`. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) --- Mathlib/Algebra/Order/Antidiag/Pi.lean | 39 +++++++++----------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/Mathlib/Algebra/Order/Antidiag/Pi.lean b/Mathlib/Algebra/Order/Antidiag/Pi.lean index ce8416da368259..10dfd75c03ab53 100644 --- a/Mathlib/Algebra/Order/Antidiag/Pi.lean +++ b/Mathlib/Algebra/Order/Antidiag/Pi.lean @@ -9,6 +9,7 @@ module public import Mathlib.Algebra.Group.Pointwise.Finset.Scalar public import Mathlib.Data.Fin.Tuple.NatAntidiagonal public import Mathlib.Data.Finset.Sym +public import Mathlib.Algebra.Group.Pi.Lemmas /-! # Antidiagonal of functions as finsets @@ -58,7 +59,6 @@ In this section, we define the antidiagonals in `Fin d → μ` by recursion on ` computationally efficient, although probably not as efficient as `Finset.Nat.antidiagonalTuple`. -/ -set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary construction for `finAntidiagonal` that bundles a proof of lawfulness (`mem_finAntidiagonal`), as this is needed to invoke `disjiUnion`. Using `Finset.disjiUnion` makes this computationally much more efficient than using `Finset.biUnion`. -/ @@ -73,16 +73,10 @@ def finAntidiagonal.aux (d : ℕ) (n : μ) : {s : Finset (Fin d → μ) // ∀ f { val := (antidiagonal n).disjiUnion (fun ab => (aux d ab.2).1.map { toFun := Fin.cons (ab.1) - inj' := Fin.cons_right_injective _ }) - (fun i _hi j _hj hij => Finset.disjoint_left.2 fun t hti htj => hij <| by - simp_rw [Finset.mem_map, Embedding.coeFn_mk] at hti htj - obtain ⟨ai, hai, hij'⟩ := hti - obtain ⟨aj, haj, rfl⟩ := htj - rw [Fin.cons_inj] at hij' - ext - · exact hij'.1 - · obtain ⟨-, rfl⟩ := hij' - rw [← (aux d i.2).prop ai |>.mp hai, ← (aux d j.2).prop ai |>.mp haj]) + inj' := Fin.cons_right_injective _ }) <| by + intro i _ j _ hij + simp only [Finset.disjoint_left, Finset.mem_map, Embedding.coeFn_mk] + grind [Fin.cons_inj] property := fun f => by simp_rw [mem_disjiUnion, mem_antidiagonal, mem_map, Embedding.coeFn_mk, Prod.exists, (aux d _).prop, Fin.sum_univ_succ] @@ -92,7 +86,6 @@ def finAntidiagonal.aux (d : ℕ) (n : μ) : {s : Finset (Fin d → μ) // ∀ f · intro hf exact ⟨_, _, hf, _, rfl, Fin.cons_self_tail f⟩ } -set_option backward.isDefEq.respectTransparency false in /-- `finAntidiagonal d n` is the type of `d`-tuples with sum `n`. TODO: deduplicate with the less general `Finset.Nat.antidiagonalTuple`. -/ @@ -109,13 +102,13 @@ choosing an identification `s ≃ Fin s.card` and proving that the end result do choice. -/ -set_option backward.isDefEq.respectTransparency false in /-- The finset of functions `ι → μ` with support contained in `s` and sum `n`. -/ def piAntidiag (s : Finset ι) (n : μ) : Finset (ι → μ) := by refine (Fintype.truncEquivFinOfCardEq <| Fintype.card_coe s).lift (fun e ↦ (finAntidiagonal s.card n).map ⟨fun f i ↦ if hi : i ∈ s then f (e ⟨i, hi⟩) else 0, ?_⟩) fun e₁ e₂ ↦ ?_ - · rintro f g hfg + · rw [Injective] + rintro f g hfg ext i simpa using congr_fun hfg (e.symm i) · ext f @@ -126,7 +119,6 @@ def piAntidiag (s : Finset ι) (n : μ) : Finset (ι → μ) := by variable {s : Finset ι} {n : μ} {f : ι → μ} -set_option backward.isDefEq.respectTransparency false in @[simp] lemma mem_piAntidiag : f ∈ piAntidiag s n ↔ s.sum f = n ∧ ∀ i, f i ≠ 0 → i ∈ s := by rw [piAntidiag] induction Fintype.truncEquivFinOfCardEq (Fintype.card_coe s) using Trunc.ind with | _ e @@ -181,8 +173,7 @@ lemma piAntidiag_cons (hi : i ∉ s) (n : μ) : constructor · rintro ⟨hn, hf⟩ refine ⟨_, _, hn, update f i 0, ⟨sum_update_of_notMem hi _ _, fun j ↦ ?_⟩, by aesop⟩ - have := fun h₁ h₂ ↦ (hf j h₁).resolve_left h₂ - aesop (add simp [update]) + grind · rintro ⟨a, _, hn, g, ⟨rfl, hg⟩, rfl⟩ have := hg i aesop (add simp [sum_add_distrib]) @@ -206,16 +197,14 @@ end CanonicallyOrderedAddCommMonoid section Nat variable [DecidableEq ι] -/-- Local notation for the pointwise operation `n • s := {n • a | a ∈ s}` to avoid conflict with the -pointwise operation `n • s := s + ... + s` (`n` times). -/ -local infixr:73 " •ℕ " => @SMul.smul _ _ Finset.smulFinset +open Pointwise lemma piAntidiag_univ_fin_eq_antidiagonalTuple (n k : ℕ) : piAntidiag univ n = Nat.antidiagonalTuple k n := by ext; simp [Nat.mem_antidiagonalTuple] lemma nsmul_piAntidiag [DecidableEq (ι → ℕ)] (s : Finset ι) (m : ℕ) {n : ℕ} (hn : n ≠ 0) : - n •ℕ piAntidiag s m = {f ∈ piAntidiag s (n * m) | ∀ i ∈ s, n ∣ f i} := by + n • piAntidiag s m = {f ∈ piAntidiag s (n * m) | ∀ i ∈ s, n ∣ f i} := by ext f refine mem_smul_finset.trans ?_ simp only [mem_filter, mem_piAntidiag, and_assoc] @@ -233,18 +222,16 @@ lemma nsmul_piAntidiag [DecidableEq (ι → ℕ)] (s : Finset ι) (m : ℕ) {n : grind lemma map_nsmul_piAntidiag (s : Finset ι) (m : ℕ) {n : ℕ} (hn : n ≠ 0) : - (piAntidiag s m).map - ⟨(n • ·), fun _ _ h ↦ funext fun i ↦ mul_right_injective₀ hn (congr_fun h i)⟩ = + (piAntidiag s m).map ⟨(n • ·), nsmul_right_injective hn⟩ = {f ∈ piAntidiag s (n * m) | ∀ i ∈ s, n ∣ f i} := by classical rw [map_eq_image]; exact nsmul_piAntidiag _ _ hn lemma nsmul_piAntidiag_univ [Fintype ι] (m : ℕ) {n : ℕ} (hn : n ≠ 0) : - n •ℕ (piAntidiag univ m) = {f ∈ piAntidiag (univ : Finset ι) (n * m) | ∀ i, n ∣ f i} := by + n • piAntidiag univ m = {f ∈ piAntidiag (univ : Finset ι) (n * m) | ∀ i, n ∣ f i} := by simpa using nsmul_piAntidiag (univ : Finset ι) m hn lemma map_nsmul_piAntidiag_univ [Fintype ι] (m : ℕ) {n : ℕ} (hn : n ≠ 0) : - (piAntidiag (univ : Finset ι) m).map - ⟨(n • ·), fun _ _ h ↦ funext fun i ↦ mul_right_injective₀ hn (congr_fun h i)⟩ = + (piAntidiag (univ : Finset ι) m).map ⟨(n • ·), nsmul_right_injective hn⟩ = {f ∈ piAntidiag (univ : Finset ι) (n * m) | ∀ i, n ∣ f i} := by simpa using map_nsmul_piAntidiag (univ : Finset ι) m hn From 587ae26313049f30905157f1814f88e578c59744 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:04:27 +0000 Subject: [PATCH 0980/1300] feat(Data/Complex/Basic): add simproc to reduce powers of I (#39506) This is enabled by default to make eg i^5 simplify automatically. We intentionally require the exponent to be a numeral, as this is intended to be a reduction statement, and for symbolic `n`, the lemma `I_pow_eq_pow_mod` should be used instead. Note that we can't have `I_pow_eq_pow_mod` as a simp lemma due to looping. --- Mathlib/Algebra/Group/Defs.lean | 16 ++++++-- .../Meromorphic/FactorizedRational.lean | 2 +- .../Elliptic/Weierstrass.lean | 2 +- Mathlib/Data/Complex/Basic.lean | 18 +++++++++ MathlibTest/Simproc/IPow.lean | 40 +++++++++++++++++++ 5 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 MathlibTest/Simproc/IPow.lean diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index d948baeee2b0ef..3111721ff63fc4 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -1068,9 +1068,13 @@ variable [DivInvMonoid G] ZPow.zpow n x = x ^ n := rfl -@[to_additive (attr := simp) zero_zsmul] theorem zpow_zero (a : G) : a ^ (0 : ℤ) = 1 := +@[to_additive zero_zsmul] theorem zpow_zero (a : G) : a ^ (0 : ℤ) = 1 := DivInvMonoid.zpow_zero' a +-- `zpow_zero` is provable by `simp` (via `zpow_ofNat`), so the `simpNF` linter rejects tagging it. +-- We still want the additive `zero_zsmul` to be `simp`, so we tag that one manually. +attribute [simp] zero_zsmul + @[to_additive (attr := simp, norm_cast) natCast_zsmul] theorem zpow_natCast (a : G) : ∀ n : ℕ, a ^ (n : ℤ) = a ^ n | 0 => (zpow_zero _).trans (pow_zero _).symm @@ -1080,7 +1084,9 @@ theorem zpow_natCast (a : G) : ∀ n : ℕ, a ^ (n : ℤ) = a ^ n _ = a ^ (n + 1) := (pow_succ _ _).symm -@[to_additive ofNat_zsmul] +-- TODO: consider also making `ofNat_zsmul` a `simp` lemma; it is currently not, because it breaks +-- `simp`-normal forms involving `(2 : ℤ) • ·` used in the theory of oriented angles. +@[to_additive ofNat_zsmul, simp] lemma zpow_ofNat (a : G) (n : ℕ) : a ^ (ofNat(n) : ℤ) = a ^ OfNat.ofNat n := zpow_natCast .. @@ -1117,9 +1123,13 @@ theorem mul_div_assoc (a b c : G) : a * b / c = a * (b / c) := by theorem one_div (a : G) : 1 / a = a⁻¹ := (inv_eq_one_div a).symm -@[to_additive (attr := simp) one_zsmul] +@[to_additive one_zsmul] lemma zpow_one (a : G) : a ^ (1 : ℤ) = a := by rw [zpow_ofNat, pow_one] +-- `zpow_one` is provable by `simp` (via `zpow_ofNat`), so the `simpNF` linter rejects tagging it. +-- We still want the additive `one_zsmul` to be `simp`, so we tag that one manually. +attribute [simp] one_zsmul + @[to_additive two_zsmul] lemma zpow_two (a : G) : a ^ (2 : ℤ) = a * a := by rw [zpow_ofNat, pow_two] @[to_additive neg_one_zsmul] diff --git a/Mathlib/Analysis/Meromorphic/FactorizedRational.lean b/Mathlib/Analysis/Meromorphic/FactorizedRational.lean index 22febde0bebfcc..a2d9a2215c064f 100644 --- a/Mathlib/Analysis/Meromorphic/FactorizedRational.lean +++ b/Mathlib/Analysis/Meromorphic/FactorizedRational.lean @@ -55,7 +55,7 @@ lemma mulSupport (d : 𝕜 → ℤ) : constructor <;> intro h · simp_all only [mem_mulSupport, ne_eq, mem_support] by_contra hCon - simp_all [zpow_zero] + simp_all · simp_all only [mem_mulSupport, ne_eq, ne_iff] use u simp_all [zero_zpow_eq_one₀] diff --git a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean index 59061499ba94c8..8f444fe996e9a4 100644 --- a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean +++ b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean @@ -346,7 +346,7 @@ lemma hasSumLocallyUniformly_derivWeierstrassPExcept (l₀ : ℂ) : Filter.eventually_atTop.mpr ⟨2 * r, ?_⟩ rintro _ h s hs l rfl split_ifs - · simpa using! show 0 ≤ ‖↑l‖ ^ 3 by positivity + · simp have : s ≠ ↑l := by rintro rfl; exfalso; linarith have : l ≠ 0 := by rintro rfl; simp_all; linarith simp only [Complex.norm_div, norm_neg, Complex.norm_ofNat, norm_pow] diff --git a/Mathlib/Data/Complex/Basic.lean b/Mathlib/Data/Complex/Basic.lean index 751a401d26700f..05d0f1c424d5d0 100644 --- a/Mathlib/Data/Complex/Basic.lean +++ b/Mathlib/Data/Complex/Basic.lean @@ -11,6 +11,7 @@ public import Mathlib.Algebra.Star.Basic public import Mathlib.Data.Real.Basic public import Mathlib.Order.Interval.Set.UnorderedInterval public import Mathlib.Tactic.Ring +public import Mathlib.Util.Qq /-! # The complex numbers @@ -635,6 +636,19 @@ lemma I_pow_eq_pow_mod (n : ℕ) : I ^ n = I ^ (n % 4) := by conv_lhs => rw [← Nat.div_add_mod n 4] simp [pow_add, pow_mul, I_pow_four] +open Qq in +/-- Reduce `Complex.I ^ n` to `Complex.I ^ (n % 4)` when `n` is a literal natural number at +least `4`. Combined with `Nat.reduceMod` this normalises every literal power of `I` to one of +`I ^ 0`, `I ^ 1`, `I ^ 2`, `I ^ 3`, which the existing `@[simp]` lemmas dispatch. -/ +simproc I_pow_eq_pow_mod' (I ^ _) := .ofQ fun u a e => + match u, a, e with + | 1, ~q(ℂ), ~q(I ^ ($n : ℕ)) => do + let some n' := n.nat? | return .continue + if n' < 4 then return .continue + -- we don't reduce `n % 4`, further, since `Nat.reduceMod` will handle that + return .visit <| .mk q(I ^ ($n % 4)) <| .some q(I_pow_eq_pow_mod $n) + | _, _, _ => return .continue + @[simp] theorem sub_re (z w : ℂ) : (z - w).re = z.re - w.re := rfl @@ -729,6 +743,10 @@ theorem div_I (z : ℂ) : z / I = -(z * I) := theorem inv_I : I⁻¹ = -I := by rw [inv_eq_one_div, div_I, one_mul] +lemma I_zpow_eq_zpow_mod (m : ℤ) : I ^ m = I ^ (m % 4) := by + conv_lhs => rw [← Int.mul_ediv_add_emod m 4] + simp [zpow_add₀, zpow_mul, zpow_ofNat] + theorem normSq_inv (z : ℂ) : normSq z⁻¹ = (normSq z)⁻¹ := by simp theorem normSq_div (z w : ℂ) : normSq (z / w) = normSq z / normSq w := by simp diff --git a/MathlibTest/Simproc/IPow.lean b/MathlibTest/Simproc/IPow.lean new file mode 100644 index 00000000000000..dcd804e1fd4e60 --- /dev/null +++ b/MathlibTest/Simproc/IPow.lean @@ -0,0 +1,40 @@ +import Mathlib.Data.Complex.Basic + +/-! +# Tests for `simp`-reduction about `I ^ _`. +-/ + +open Complex + +-- simp can reduce I ^ n for literal nats n, as well as literal ints n, but not for variables n. +example : I ^ 4 = 1 := by simp +example : I ^ 5 = I := by simp +example : I ^ 100 = 1 := by simp + +example : I ^ 3 = -I := by simp + +example : I ^ (4 : ℤ) = 1 := by simp +example : I ^ (5 : ℤ) = I := by simp +example : I ^ (-4 : ℤ) = 1 := by simp +example : I ^ (-5 : ℤ) = -I := by simp +example : I ^ (-6 : ℤ) = -1 := by simp +example : I ^ (-7 : ℤ) = I := by simp +example : I ^ (-100 : ℤ) = 1 := by simp + +/-- error: `simp` made no progress -/ +#guard_msgs in +example {n : ℕ} : I ^ n = I ^ (n % 4) := by simp + +-- the appropriate simp only sequence can reduce I ^ n for literal nats n +example : I ^ 5 = I := by simp only [I_pow_eq_pow_mod', Nat.reduceMod, pow_one] +example : I ^ 6 = -1 := by simp only [I_pow_eq_pow_mod', Nat.reduceMod, I_sq] +example : I ^ 7 = -I := by simp only [I_pow_eq_pow_mod', Nat.reduceMod, I_pow_three] +example : I ^ 8 = 1 := by simp only [I_pow_eq_pow_mod', Nat.reduceMod, pow_zero] + +-- the appropriate simp only sequence can reduce I ^ n for literal ints n +example : I ^ (5 : ℤ) = I := by + simp only [zpow_ofNat, I_pow_eq_pow_mod', Nat.reduceMod, pow_one] + +-- the appropriate simp only sequence can reduce I ^ (-n) for literal nats n +example : I ^ (-5 : ℤ) = -I := by + simp only [Int.reduceNeg, zpow_neg, zpow_ofNat, I_pow_eq_pow_mod', Nat.reduceMod, pow_one, inv_I] From 27e661d190313c99f15518c8cc1d6a6f838f6ac4 Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:04:29 +0000 Subject: [PATCH 0981/1300] refactor(Tactic/Determinant/Bird): move norm_det simproc to Tactic/NormDet (#42058) move the determinant normalization simproc `norm_det` and `eval_det` tactic to `Tactic/NormDet` in preparation for generalizing the tactic to work with mathlib Matrix determinants: #42059. --- Mathlib.lean | 2 +- Mathlib/Tactic.lean | 2 +- Mathlib/Tactic/{Determinant/Bird.lean => NormDet.lean} | 0 MathlibTest/matrix.lean | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename Mathlib/Tactic/{Determinant/Bird.lean => NormDet.lean} (100%) diff --git a/Mathlib.lean b/Mathlib.lean index c5952d3640103a..624f35d65fc813 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7322,7 +7322,6 @@ public import Mathlib.Tactic.DeriveCountable public import Mathlib.Tactic.DeriveEncodable public import Mathlib.Tactic.DeriveFintype public import Mathlib.Tactic.DeriveTraversable -public import Mathlib.Tactic.Determinant.Bird public import Mathlib.Tactic.Determinant.Bird.Cert public import Mathlib.Tactic.Determinant.Bird.Meta public import Mathlib.Tactic.DuplicateDecls @@ -7447,6 +7446,7 @@ public import Mathlib.Tactic.MoveAdd public import Mathlib.Tactic.NoncommRing public import Mathlib.Tactic.Nontriviality public import Mathlib.Tactic.Nontriviality.Core +public import Mathlib.Tactic.NormDet public import Mathlib.Tactic.NormNum public import Mathlib.Tactic.NormNum.Abs public import Mathlib.Tactic.NormNum.Basic diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 6e239fb555cc45..8cdb1fb50331d3 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -99,7 +99,6 @@ public import Mathlib.Tactic.DeriveCountable public import Mathlib.Tactic.DeriveEncodable public import Mathlib.Tactic.DeriveFintype public import Mathlib.Tactic.DeriveTraversable -public import Mathlib.Tactic.Determinant.Bird public import Mathlib.Tactic.Determinant.Bird.Cert public import Mathlib.Tactic.Determinant.Bird.Meta public import Mathlib.Tactic.DuplicateDecls @@ -224,6 +223,7 @@ public import Mathlib.Tactic.MoveAdd public import Mathlib.Tactic.NoncommRing public import Mathlib.Tactic.Nontriviality public import Mathlib.Tactic.Nontriviality.Core +public import Mathlib.Tactic.NormDet public import Mathlib.Tactic.NormNum public import Mathlib.Tactic.NormNum.Abs public import Mathlib.Tactic.NormNum.Basic diff --git a/Mathlib/Tactic/Determinant/Bird.lean b/Mathlib/Tactic/NormDet.lean similarity index 100% rename from Mathlib/Tactic/Determinant/Bird.lean rename to Mathlib/Tactic/NormDet.lean diff --git a/MathlibTest/matrix.lean b/MathlibTest/matrix.lean index 75a20346778c77..d944e88b907c0f 100644 --- a/MathlibTest/matrix.lean +++ b/MathlibTest/matrix.lean @@ -7,7 +7,7 @@ import Mathlib.LinearAlgebra.Matrix.Determinant.Basic import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs import Mathlib.LinearAlgebra.Matrix.Notation import Mathlib.RingTheory.Polynomial.Basic -import Mathlib.Tactic.Determinant.Bird +import Mathlib.Tactic.NormDet import Qq open Qq From 16d467a36303d69caff8b983dee7a47b2873b577 Mon Sep 17 00:00:00 2001 From: Zeta-Wu <100186590+Zeta-Wu@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:54:25 +0000 Subject: [PATCH 0982/1300] doc: improve StrictUniversalPropertyFixedTarget docstring (#42049) The documentation of `StrictUniversalPropertyFixedTarget` was slightly misleading. This PR updates it to better reflect the fields of the structure. --- Mathlib/CategoryTheory/Localization/Predicate.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Localization/Predicate.lean b/Mathlib/CategoryTheory/Localization/Predicate.lean index 573923a404148a..0c9be1a2c34ed5 100644 --- a/Mathlib/CategoryTheory/Localization/Predicate.lean +++ b/Mathlib/CategoryTheory/Localization/Predicate.lean @@ -69,9 +69,9 @@ end Functor namespace Localization -/-- This universal property states that a functor `L : C ⥤ D` inverts morphisms -in `W` and that all functors `D ⥤ E` (for a fixed category `E`) uniquely factor -through `L`. -/ +/-- This universal property states that a functor `L : C ⥤ D` inverts the morphisms +in `W` and every functor `F : C ⥤ E` (for a fixed category `E`) inverting `W` admits +a unique factorisation through `L`. -/ structure StrictUniversalPropertyFixedTarget where /-- the functor `L` inverts `W` -/ inverts : W.IsInvertedBy L From 014cbc3f5cd19c72d206671b9e7ae6929a5100dc Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 12:28:35 +0000 Subject: [PATCH 0983/1300] fix(Order/Partition): rename a binder shadowing Partition.sSup_eq (#42061) The new name is better anyway, and simplifies life for the `blanketSimpArgs` linter in #42056: cherry-picked from that PR. Co-authored-by: sgraf812 <1151264+sgraf812@users.noreply.github.com> --- Mathlib/Order/Partition/Basic.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Order/Partition/Basic.lean b/Mathlib/Order/Partition/Basic.lean index 06607e2b07569c..d69a518d279de9 100644 --- a/Mathlib/Order/Partition/Basic.lean +++ b/Mathlib/Order/Partition/Basic.lean @@ -156,15 +156,15 @@ def partscopyEquiv (P : Partition s) (hst : s = t) : ↥(P.copy hst) ≃ ↥P := /-- A constructor for `Partition s` that removes `⊥` from the set of parts. -/ @[simps] -def removeBot (P : Set α) (indep : _root_.sSupIndep P) (sSup_eq : sSup P = s) : Partition s where +def removeBot (P : Set α) (indep : _root_.sSupIndep P) (hsSup : sSup P = s) : Partition s where parts := P \ {⊥} sSupIndep' := indep.mono sdiff_subset bot_notMem' := by simp - sSup_eq' := by simp [← sSup_eq] + sSup_eq' := by simp [← hsSup] @[simp] -lemma mem_removeBot (P : Set α) (indep : _root_.sSupIndep P) (sSup_eq : sSup P = s) : - x ∈ removeBot P indep sSup_eq ↔ x ∈ P ∧ x ≠ ⊥ := Iff.rfl +lemma mem_removeBot (P : Set α) (indep : _root_.sSupIndep P) (hsSup : sSup P = s) : + x ∈ removeBot P indep hsSup ↔ x ∈ P ∧ x ≠ ⊥ := Iff.rfl @[simp] lemma notMem_of_bot (P : Partition (⊥ : α)) (x : α) : x ∉ P := by From 7529bd52c81fcc944a2244149498a7672921411c Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Fri, 24 Jul 2026 12:38:00 +0000 Subject: [PATCH 0984/1300] feat(Tactic/NormDet): change norm_det simproc to work with Matrix.det (#42059) Previously the `norm_det` simproc / `eval_det` tactic normalized Bird determinants, i.e `BirdDet.birdDet`. This commit changes `norm_det` to normalize `Matrix.det` calls, using #41160 to connect Bird's determinant with `Matrix.det`. Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib/LinearAlgebra/Matrix/Defs.lean | 8 +++ Mathlib/Tactic/NormDet.lean | 71 +++++++++++++++++++++++--- MathlibTest/matrix.lean | 67 ++++++++++++------------ 3 files changed, 104 insertions(+), 42 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Defs.lean b/Mathlib/LinearAlgebra/Matrix/Defs.lean index f0c9653717e388..e5c634e31ac9ec 100644 --- a/Mathlib/LinearAlgebra/Matrix/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/Defs.lean @@ -104,6 +104,14 @@ def ofArray {m n : ℕ} (A : Array R) (hA : A.size = m * n) : Matrix (Fin m) (Fi theorem ofArray_apply {m n : ℕ} (A : Array R) (hA : A.size = m * n) (i : Fin m) (j : Fin n) : ofArray A hA i j = A[Fin.mkDivMod i j] := rfl +/-- The matrix constructed from the row-major array of `A`'s entries is `A`. -/ +@[simp] +theorem ofArray_ofFn {m n : ℕ} (A : Matrix (Fin m) (Fin n) R) : + ofArray (.ofFn fun k : Fin (m * n) ↦ A k.divNat k.modNat) Array.size_ofFn = A := by + ext i j + rw [ofArray_apply, Fin.getElem_fin, Array.getElem_ofFn, Fin.divNat_mkDivMod, + Fin.modNat_mkDivMod] + lemma ofArray_eq_of_getD [Zero R] {m n : ℕ} (A : Array R) (hA : A.size = m * n) : ofArray A hA = .of fun i j ↦ A.getD (n * i.val + j.val) 0 := by ext i j diff --git a/Mathlib/Tactic/NormDet.lean b/Mathlib/Tactic/NormDet.lean index 05fdc2ae97903a..de5787fcd9efa6 100644 --- a/Mathlib/Tactic/NormDet.lean +++ b/Mathlib/Tactic/NormDet.lean @@ -5,30 +5,85 @@ Authors: Paul Cadman -/ module -public import Mathlib.Tactic.Determinant.Bird.Cert +public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic +meta import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Correctness +public meta import Mathlib.Tactic.Determinant.Bird.Cert /-! # `norm_det` simproc and `eval_det` tactic -A tactic for normalizing matrix determinants. +This module defines the `norm_det` simproc and the `eval_det` tactic for +normalizing determinants of matrix literals over a commutative ring. -/ public meta section -open Lean Meta Elab Tactic Simp +open Lean Meta Qq open Mathlib.Tactic.Determinant /-- reify a `BirdDet` call and normalize it using the certificate-chain evaluator -/ -def normalizeBirdDet (e : Expr) : MetaM Simp.Result := do +private def normalizeBirdDet (e : Expr) : MetaM Simp.Result := do let ⟨rα, ctx⟩ ← reifyBirdDet e let detNorm ← certBirdDet (rα := rα) |>.run' {} |>.run ctx |>.run .reducible Mathlib.Tactic.RingNF.cleanup {} {expr := detNorm.norm, proof? := some detNorm.proof} -/-- Normalize a literal `birdDet` call using the certificate-chain evaluator. -/ -simproc_decl norm_det (BirdDet.birdDet _ _) := fun e => do - return .done (← normalizeBirdDet e) +/-- Normalize the determinant of `A` from its `entries` in row-major order -/ +private def normalizeDetFromEntries {u : Level} {α : Q(Type u)} {n : Q(ℕ)} (rα : Q(CommRing $α)) + (A : Q(Matrix (Fin $n) (Fin $n) $α)) (entries : Array Q($α)) : + MetaM Simp.Result := do + let arrayExpr : Q(Array $α) ← mkArrayLit α entries.toList + let hA ← mkDecideProofQ q(Array.size $arrayExpr = $n * $n) + have : $arrayExpr =Q Array.ofFn fun k : Fin ($n * $n) ↦ $A k.divNat k.modNat := ⟨⟩ + let ofArrayEqA := q(Matrix.ofArray_ofFn $A) + let birdDet := q(BirdDet.birdDet $n $arrayExpr) + let detEqBirdDet := q($ofArrayEqA ▸ BirdDet.det_eq_birdDet $arrayExpr $hA) + let birdDetNorm ← normalizeBirdDet birdDet + let detEqBirdDetRes : Simp.Result := ⟨birdDet, some detEqBirdDet, true⟩ + detEqBirdDetRes.mkEqTrans birdDetNorm -/-- Normalize `birdDet` calls in the target using the certificate-chain simproc. -/ +/-- Extract the entries of a square `!![...]` matrix literal in row-major order. +Returns `none` if `A` is not an `n × n` matrix literal. -/ +private def entriesOfMatrixLiteral? {u : Level} {α : Q(Type u)} {n : Q(ℕ)} + (A : Q(Matrix (Fin $n) (Fin $n) $α)) : + MetaM (Option (Array Q($α))) := do + let some dim ← getNatValue? n | return none + let ~q(Matrix.of $rows) := A | return none + let (matrixRows, _, _) ← Matrix.matchVecConsPrefix n rows + unless matrixRows.length == dim do return none + let entriesByRow ← matrixRows.mapM fun row => do + let (entries, _, _) ← Matrix.matchVecConsPrefix n row + return entries + unless entriesByRow.all (·.length == dim) do return none + let entries ← entriesByRow.flatten.mapM fun entry => do + let some entry ← checkTypeQ entry α | throwError "expected matrix entry to have type {α}" + return entry + return some entries.toArray + +/-- The `norm_det` simproc normalizes determinants of matrices written using `!![...]` +notation over a commutative ring. -/ +simproc_decl norm_det (Matrix.det _) := fun e => do + let e ← instantiateMVars e + let ⟨_, _, e⟩ ← inferTypeQ' e + let ~q(@Matrix.det (Fin $n) _ _ _ $rα $matrix) := e | return .continue + let some entries ← entriesOfMatrixLiteral? matrix | return .continue + return .done (← normalizeDetFromEntries rα matrix entries) + +/-- +`eval_det` normalizes determinants of matrices written using `!![...]` notation +over a commutative ring. + +Examples: + +```lean +example : Matrix.det (R := ℤ) !![1, 2; 3, 4] = -2 := by + eval_det + +example {R : Type*} [CommRing R] (a b c d : R) : + Matrix.det !![a, b; c, d] = a * d - b * c := by + eval_det + ring +``` +-/ macro (name := evalDet) "eval_det" : tactic => `(tactic| simp only [norm_det]) end diff --git a/MathlibTest/matrix.lean b/MathlibTest/matrix.lean index d944e88b907c0f..59a4cd34833e27 100644 --- a/MathlibTest/matrix.lean +++ b/MathlibTest/matrix.lean @@ -7,6 +7,7 @@ import Mathlib.LinearAlgebra.Matrix.Determinant.Basic import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs import Mathlib.LinearAlgebra.Matrix.Notation import Mathlib.RingTheory.Polynomial.Basic +import Mathlib.Tactic.FieldSimp import Mathlib.Tactic.NormDet import Qq @@ -190,65 +191,63 @@ example (ι : Type*) [Inhabited ι] : Matrix.replicateCol ι (fun (_ : Fin 3) => simp_all rfl -section BirdDet - -open BirdDet +section NormDet variable {R : Type*} [CommRing R] -example : birdDet 0 #[] = (1 : ℤ) := by +example : Matrix.det !![] = (1 : ℤ) := by eval_det -example : birdDet 1 #[-1] = -1 := by +example : Matrix.det !![-1] = -1 := by eval_det -example : birdDet 2 #[1, 2, 3, 4] = -2 := by +example : Matrix.det !![1, 2; 3, 4] = -2 := by eval_det -example : birdDet 2 (let A := #[1, 2, 3, 4]; A) = -2 := by +example : Matrix.det (let A := !![1, 2; 3, 4]; A) = -2 := by eval_det -example (a b c d : R) : - birdDet 2 #[a, b, c, d] = a * d - b * c := by +example (a b c d : R) : Matrix.det !![a, b; c, d] = a * d - b * c := by eval_det ring -example (a b c d : R) : - birdDet 2 #[a, b, c, d] = a * d - b * c := by +example (a b c d : R) : Matrix.det !![a, b; c, d] = a * d - b * c := by simp only [norm_det] ring -example : birdDet 2 #[1, 2, 2, 4] + birdDet 2 #[2, 3, 4, 5] = -2 := by - simp only [norm_det] +example : Matrix.det !![1, 2; 2, 4] + Matrix.det !![2, 3; 4, 5] = -2 := by + eval_det norm_num -example : birdDet 2 #[birdDet 2 #[2, 3, 4, 5], 2, 2, 4] = -12 := by - simp only [norm_det] +example : Matrix.det !![Matrix.det !![2, 3; 4, 5], 2; 2, 4] = -12 := by + eval_det -example : - birdDet 8 - #[ 2, 0, -1, 0, 0, 0, 0, 0, - 0, 2, 0, -1, 0, 0, 0, 0, - -1, 0, 2, -1, 0, 0, 0, 0, - 0, -1, -1, 2, -1, 0, 0, 0, - 0, 0, 0, -1, 2, -1, 0, 0, - 0, 0, 0, 0, -1, 2, -1, 0, - 0, 0, 0, 0, 0, -1, 2, -1, - 0, 0, 0, 0, 0, 0, -1, 2] = 1 := by - simp only [norm_det] +example : Matrix.det + !![ 2, 0, -1, 0, 0, 0, 0, 0; + 0, 2, 0, -1, 0, 0, 0, 0; + -1, 0, 2, -1, 0, 0, 0, 0; + 0, -1, -1, 2, -1, 0, 0, 0; + 0, 0, 0, -1, 2, -1, 0, 0; + 0, 0, 0, 0, -1, 2, -1, 0; + 0, 0, 0, 0, 0, -1, 2, -1; + 0, 0, 0, 0, 0, 0, -1, 2] = 1 := by + eval_det open MvPolynomial in -lemma test_case_11 : - birdDet (R := MvPolynomial (Fin 3) R) - 3 - #[1 , X 0, (X 0) ^ 2, - 1 , X 1, (X 1) ^ 2, - 1 , X 2, (X 2) ^ 2] = (X 0 - X 1) * (X 1 - X 2) * (X 2 - X 0) := by - simp only [norm_det] +example : Matrix.det (R := MvPolynomial (Fin 3) R) + !![1 , X 0, (X 0) ^ 2; + 1 , X 1, (X 1) ^ 2; + 1 , X 2, (X 2) ^ 2] = (X 0 - X 1) * (X 1 - X 2) * (X 2 - X 0) := by + eval_det ring -end BirdDet +example {K : Type*} [Field K] (x i j k : K) (hx : x ≠ 0) : Matrix.det + !![x ^ 3, 0, 0; i, 1 / x, 0; j, k, 1 / x ^ 2] = 1 := by + eval_det + field_simp [hx] + +end NormDet end Matrix From bd0b6647eaa50f9e8317a9859f2444219022a7f7 Mon Sep 17 00:00:00 2001 From: Sebastian Graf Date: Fri, 24 Jul 2026 13:05:55 +0000 Subject: [PATCH 0985/1300] perf: restrict Subsingleton.eq_zero/eq_one simp arguments to their intended type (#42053) `Subsingleton.eq_zero` and `Subsingleton.eq_one` have a bare variable as their LHS, so as simp lemmas they are tried on every visited subterm, and each attempt runs a `Subsingleton` instance search. Pinning the type argument at the call site makes unification fail cheaply on all other subterms and confines the instance search to the type actually being collapsed. Instruction counts for `lake env lean` on v4.33.0-rc1: `Mathlib.Algebra.Central.End` drops from 14.8G to 8.2G. The remaining call sites show the same pattern at smaller scale. --- Mathlib/Algebra/Central/End.lean | 2 +- Mathlib/Algebra/MvPolynomial/NoZeroDivisors.lean | 2 +- Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean | 3 ++- Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean | 2 +- Mathlib/Combinatorics/Enumerative/Partition/Glaisher.lean | 2 +- Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean | 4 ++-- Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean | 4 ++-- Mathlib/RingTheory/Polynomial/IntegralNormalization.lean | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Central/End.lean b/Mathlib/Algebra/Central/End.lean index d7317e1f219ae8..3deeaa9914248f 100644 --- a/Mathlib/Algebra/Central/End.lean +++ b/Mathlib/Algebra/Central/End.lean @@ -60,7 +60,7 @@ public theorem LinearEquiv.conjAlgEquiv_ext_iff' {S M₂ : Type*} [CommRing S] [ (f g : M ≃ₗ[R] M₂) : f.conjAlgEquiv S = g.conjAlgEquiv S ↔ ∃ α : Sˣ, f = α • g := by refine ⟨fun h ↦ ?_, fun ⟨y, h⟩ ↦ conjAlgEquiv_ext_iff.mpr ⟨(y : S), congr($h)⟩⟩ by_cases! Subsingleton M - · exact ⟨1, by ext; simp [Subsingleton.eq_zero]⟩ + · exact ⟨1, by ext; simp [Subsingleton.eq_zero (α := M)]⟩ obtain ⟨α, hα⟩ := conjAlgEquiv_ext_iff.mp h obtain ⟨β, hβ⟩ := conjAlgEquiv_ext_iff.mp h.symm obtain ⟨x, hx⟩ := exists_ne (0 : M) diff --git a/Mathlib/Algebra/MvPolynomial/NoZeroDivisors.lean b/Mathlib/Algebra/MvPolynomial/NoZeroDivisors.lean index df972cdcceac7a..9edb22e301b5cb 100644 --- a/Mathlib/Algebra/MvPolynomial/NoZeroDivisors.lean +++ b/Mathlib/Algebra/MvPolynomial/NoZeroDivisors.lean @@ -50,7 +50,7 @@ lemma degreeOf_prod_eq {ι : Type*} (s : Finset ι) (f : ι → MvPolynomial σ (h : ∀ i ∈ s, f i ≠ 0) : degreeOf n (∏ i ∈ s, f i) = ∑ i ∈ s, degreeOf n (f i) := by rcases subsingleton_or_nontrivial (MvPolynomial σ R) with nontrivial | nontrivial - · simp [Subsingleton.eq_zero] + · simp [Subsingleton.eq_zero (α := MvPolynomial σ R)] · classical induction s using Finset.induction_on with | empty => simp diff --git a/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean b/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean index 1f7c54af7551f6..aa557fde431bf0 100644 --- a/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean +++ b/Mathlib/Analysis/Normed/Operator/ContinuousAlgEquiv.lean @@ -164,7 +164,8 @@ public theorem StarAlgEquiv.eq_linearIsometryEquivConjStarAlgEquiv -- Assume nontriviality of `V`. by_cases! Subsingleton V · by_cases! Subsingleton W - · use { toLinearEquiv := 0, norm_map' _ := by simp [Subsingleton.eq_zero] } + · use { toLinearEquiv := 0, + norm_map' _ := by simp [Subsingleton.eq_zero (α := V), Subsingleton.eq_zero (α := W)] } exact ext fun _ ↦ Subsingleton.allEq _ _ simpa using congr(f $(Subsingleton.allEq 0 1)) /- By `ContinuousAlgEquiv.eq_continuousLinearEquivConjContinuousAlgEquiv`, diff --git a/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean b/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean index 1501e34ebc3410..1e6c4ad8408bc3 100644 --- a/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean +++ b/Mathlib/Combinatorics/Enumerative/Partition/GenFun.lean @@ -69,7 +69,7 @@ theorem tendsto_order_genFun_term_atTop_nhds_top (f : ℕ → ℕ → R) (i : intro m hm grw [PowerSeries.smul_eq_C_mul, ← le_order_mul] refine lt_add_of_nonneg_of_lt (by simp) ?_ - nontriviality R using Subsingleton.eq_zero + nontriviality R using Subsingleton.eq_zero (α := R⟦X⟧) rw [order_X_pow] norm_cast grind diff --git a/Mathlib/Combinatorics/Enumerative/Partition/Glaisher.lean b/Mathlib/Combinatorics/Enumerative/Partition/Glaisher.lean index fbe261a305a3db..ab91795d4ac85b 100644 --- a/Mathlib/Combinatorics/Enumerative/Partition/Glaisher.lean +++ b/Mathlib/Combinatorics/Enumerative/Partition/Glaisher.lean @@ -80,7 +80,7 @@ $$ -/ theorem hasProd_powerSeriesMk_card_countRestricted {m : ℕ} (hm : 0 < m) : HasProd (fun i ↦ ∑ j ∈ range m, X ^ ((i + 1) * j)) (PowerSeries.mk fun n ↦ (#(countRestricted n m) : R)) := by - nontriviality R using Subsingleton.eq_one + nontriviality R using Subsingleton.eq_one (α := R⟦X⟧) convert! hasProd_genFun (fun i c ↦ if c < m then (1 : R) else 0) using 1 · ext1 i rw [sum_range_eq_add_Ico _ hm, sum_Ico_eq_sum_range] diff --git a/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean b/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean index 8a72260798fcdf..329a690d007514 100644 --- a/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean +++ b/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean @@ -43,7 +43,7 @@ namespace Pentagonal theorem tendsto_order_pow_mul_prod_one_sub_pow (k : ℕ) : Tendsto (fun n ↦ (X ^ ((k + 1) * n) * ∏ i ∈ Finset.range (n + 1), (1 - X ^ (k + i + 1)) : R⟦X⟧).order) atTop (𝓝 ⊤) := by - nontriviality R using Subsingleton.eq_zero + nontriviality R using Subsingleton.eq_zero (α := R⟦X⟧) refine ENat.tendsto_nhds_top_iff_natCast_lt.mpr fun n ↦ eventually_atTop.mpr ⟨n + 1, ?_⟩ intro m hm grw [← le_order_mul, order_X_pow] @@ -53,7 +53,7 @@ theorem tendsto_order_pow_mul_prod_one_sub_pow (k : ℕ) : theorem tendsto_order_neg_X_pow (k : ℕ) : Tendsto (fun i ↦ (-(X : R⟦X⟧) ^ (i + k + 1)).order) atTop (𝓝 ⊤) := by - nontriviality R using Subsingleton.eq_zero + nontriviality R using Subsingleton.eq_zero (α := R⟦X⟧) simp_rw [order_neg, order_X_pow, add_assoc] exact ENat.tendsto_natCast_nhds_top.comp (tendsto_add_atTop_nat _) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 510b6f87e8faaa..e20fca7a52a06d 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -58,10 +58,10 @@ lemma gammaSet_one_const (a a' : Fin 2 → ZMod 1) : gammaSet 1 r a = gammaSet 1 /-- For level `N = 1`, the gamma sets simplify to only a `gcd` condition. -/ lemma gammaSet_one_eq (a : Fin 2 → ZMod 1) : gammaSet 1 r a = {v : Fin 2 → ℤ | (v 0).gcd (v 1) = r} := by - simp [gammaSet, Subsingleton.eq_zero] + simp [gammaSet, Subsingleton.eq_zero (α := Fin 2 → ZMod 1)] lemma gammaSet_one_mem_iff (v : Fin 2 → ℤ) : v ∈ gammaSet 1 r 0 ↔ (v 0).gcd (v 1) = r := by - simp [gammaSet, Subsingleton.eq_zero] + simp [gammaSet, Subsingleton.eq_zero (α := Fin 2 → ZMod 1)] /-- For level `N = 1`, the gamma sets are all equivalent; this is the equivalence. -/ def gammaSet_one_equiv (a a' : Fin 2 → ZMod 1) : gammaSet 1 r a ≃ gammaSet 1 r a' := diff --git a/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean b/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean index 16fa71e9d8e32a..5229e7c85a895d 100644 --- a/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean +++ b/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean @@ -185,7 +185,7 @@ variable [Semiring R] [IsCancelMulZero R] @[simp] theorem support_integralNormalization {f : R[X]} : (integralNormalization f).support = f.support := by - nontriviality R using Subsingleton.eq_zero + nontriviality R using Subsingleton.eq_zero (α := R[X]) have : IsDomain R := {} by_cases hf : f = 0; · simp [hf] ext i From 0434c03386d3e7f7fd3ed95754543eabe4ab251b Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:05:57 +0000 Subject: [PATCH 0986/1300] chore(GroupTheory/Coset/Basic): automated extraction from #42056 (#42062) This PR was automatically created from PR #42056 by @sgraf812 via a [review comment](https://github.com/leanprover-community/mathlib4/pull/42056#discussion_r3645245042) by @grunweg. Co-authored-by: sgraf812 <1151264+sgraf812@users.noreply.github.com> --- Mathlib/GroupTheory/Coset/Basic.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/GroupTheory/Coset/Basic.lean b/Mathlib/GroupTheory/Coset/Basic.lean index 5fce88bf8088e5..068c187fb61c79 100644 --- a/Mathlib/GroupTheory/Coset/Basic.lean +++ b/Mathlib/GroupTheory/Coset/Basic.lean @@ -144,11 +144,11 @@ variable [Group α] {s : Set α} {x : α} @[to_additive mem_leftAddCoset_iff] theorem mem_leftCoset_iff (a : α) : x ∈ a • s ↔ a⁻¹ * x ∈ s := - Iff.intro (fun ⟨b, hb, Eq⟩ => by simp [Eq.symm, hb]) fun h => ⟨a⁻¹ * x, h, by simp⟩ + Iff.intro (fun ⟨b, hb, h⟩ => by simp [h.symm, hb]) fun h => ⟨a⁻¹ * x, h, by simp⟩ @[to_additive mem_rightAddCoset_iff] theorem mem_rightCoset_iff (a : α) : x ∈ op a • s ↔ x * a⁻¹ ∈ s := - Iff.intro (fun ⟨b, hb, Eq⟩ => by simp [Eq.symm, hb]) fun h => ⟨x * a⁻¹, h, by simp⟩ + Iff.intro (fun ⟨b, hb, h⟩ => by simp [h.symm, hb]) fun h => ⟨x * a⁻¹, h, by simp⟩ end CosetGroup From df124433afa3e7b801b7339a398ace5a153b1644 Mon Sep 17 00:00:00 2001 From: Francesco Chotuck <101644758+FrankieNC@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:39:31 +0000 Subject: [PATCH 0987/1300] feat(Algebra/Notation/Indicator): pointwise evaluation of a function-valued indicator (#40909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `Set.mulIndicator_apply_apply` and its `to_additive` companion `Set.indicator_apply_apply`: for a family of functions `f : α → β → M`, `s.mulIndicator f a b = s.mulIndicator (fun i ↦ f i b) a`, so evaluating a function-valued indicator at `b` commutes with the indicator. It is the pointwise form of `Set.mulIndicator_comp_of_one` (with `g` the evaluation map at `b`). --- Mathlib/Algebra/Notation/Indicator.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Notation/Indicator.lean b/Mathlib/Algebra/Notation/Indicator.lean index ba7178798403bd..cf61481ca68c40 100644 --- a/Mathlib/Algebra/Notation/Indicator.lean +++ b/Mathlib/Algebra/Notation/Indicator.lean @@ -228,6 +228,13 @@ lemma comp_mulIndicator_const (c : M) (f : M → N) (hf : f 1 = 1) : (fun x => f (s.mulIndicator (fun _ => c) x)) = s.mulIndicator fun _ => f c := (mulIndicator_comp_of_one hf).symm +/-- Evaluating the indicator of a family of functions at a point commutes with the indicator: +`s.mulIndicator f a b = s.mulIndicator (f · b) a`. -/ +@[to_additive] +lemma mulIndicator_apply_apply (f : α → β → M) (b : β) : + s.mulIndicator f a b = s.mulIndicator (fun i ↦ f i b) a := by + by_cases h : a ∈ s <;> simp [h] + @[to_additive] lemma mulIndicator_preimage (s : Set α) (f : α → M) (B : Set M) : mulIndicator s f ⁻¹' B = s.ite (f ⁻¹' B) (1 ⁻¹' B) := From ba1004b8762576f38efa413f9c405dfd7cc4c0bb Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:39:36 +0000 Subject: [PATCH 0988/1300] doc(RingTheory/HahnSeries/PowerSeries): fix old reference to `mv_power_series` in comment (#41954) This PR fixes an occurrences of `mv_power_series` from the Lean 3 days. Co-authored-by: tb65536 --- Mathlib/RingTheory/HahnSeries/PowerSeries.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean index a5bb85af445c40..edae469e7ab14b 100644 --- a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean +++ b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean @@ -142,7 +142,7 @@ theorem ofPowerSeries_X_pow {R} [Semiring R] (n : ℕ) : simp set_option backward.isDefEq.respectTransparency false in --- Lemmas about converting hahn_series over fintype to and from mv_power_series +-- Lemmas converting Hahn series over a finite index type to and from `MvPowerSeries` /-- The ring `R⟦σ →₀ ℕ⟧` is isomorphic to `MvPowerSeries σ R` for a `Finite` `σ`. We take the index set of the hahn series to be `Finsupp` rather than `pi`, even though we assume `Finite σ` as this is more natural for alignment with `MvPowerSeries`. From 5ffb4e1cf8c97808ca9d9004ad4795ff30d6e17b Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:39:38 +0000 Subject: [PATCH 0989/1300] feat: set `pp.mvars.anonymous false` for `MathlibTest` (#42016) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR sets `pp.mvars.anonymous false` for `MathlibTest` in the lakefile, and removes the now-superfluous `set_option`s which did so in individual tests. In tests, we always want to set this option (which pretty-prints autogenerated mvars such as `?m.37` as `?_`) to ensure that they are stable. Instead of looking for it during review, we can just have it always set to the correct value by default. In fact, this PR also catches some unstable tests which slipped past during review. It also documents the decision to not use the standard mathlib options, and removes stale documentation around `mathlibLeanOptions`. (Note: `mathlibLeanOptions` implicitly says that tests should use ``⟨`maxSynthPendingDepth, .ofNat 3⟩``, but we've been getting by just fine without that.) So far this is the only option for `MathlibTest`, but we may as well still put it in an array to hold the documentation and not interrupt the flow of `lean_lib`s. (And maybe make it easier set other options for MathlibTest in the future if we find we need them.) --- MathlibTest/Algebra/MonoidAlgebra/Defs.lean | 1 - MathlibTest/Attribute/ToAdditive/Basic.lean | 4 +--- MathlibTest/CategoryTheory/Bicategory/Basic.lean | 1 - MathlibTest/CategoryTheory/CategoryStar.lean | 2 -- MathlibTest/CategoryTheory/Monoidal/Basic.lean | 1 - MathlibTest/DefEqAbuse.lean | 2 +- MathlibTest/DifferentialGeometry/Notation/Advanced.lean | 3 --- MathlibTest/DifferentialGeometry/Notation/Basic.lean | 2 -- .../DifferentialGeometry/Notation/Delaborators.lean | 1 - MathlibTest/EuclideanSpace.lean | 1 - MathlibTest/FinCoercions.lean | 2 -- MathlibTest/Tactic/Abel.lean | 1 - MathlibTest/Tactic/Check.lean | 1 - MathlibTest/Tactic/GRewrite.lean | 4 ++-- MathlibTest/Util/PrintSorries.lean | 2 -- MathlibTest/Widget/Conv.lean | 1 - MathlibTest/superscript.lean | 2 -- lakefile.lean | 9 ++++++++- 18 files changed, 12 insertions(+), 28 deletions(-) diff --git a/MathlibTest/Algebra/MonoidAlgebra/Defs.lean b/MathlibTest/Algebra/MonoidAlgebra/Defs.lean index b0d1f964a903b0..cee2bc582a0412 100644 --- a/MathlibTest/Algebra/MonoidAlgebra/Defs.lean +++ b/MathlibTest/Algebra/MonoidAlgebra/Defs.lean @@ -5,7 +5,6 @@ variable {R M A} [Semiring R] [Monoid M] [AddMonoid A] section Notation open scoped MonoidAlgebra AddMonoidAlgebra -set_option pp.mvars.anonymous false -- TODO: could resolve ambiguity based on Monoid / AddMonoid /-- error: Ambiguous term diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index 36768fc9e78cfc..f9ee3c8b408e4a 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -98,7 +98,6 @@ instance : my_has_scalar Nat Nat := ⟨fun a b => a * b⟩ set_option linter.translate.warnInvalid false in attribute [to_additive (reorder := α β) my_has_scalar] my_has_pow -set_option pp.mvars.anonymous false in /-- error: `to_additive` validation failed: expected {α : Type _} → {β : Type _} → [self : my_has_scalar β α] → α → β → α @@ -107,7 +106,6 @@ but 'Test.my_has_scalar.smul' has type -/ #guard_msgs in attribute [to_additive existing smul] my_has_pow.pow -set_option pp.mvars.anonymous false in /-- error: `to_additive` validation failed: expected {β : Type _} → {α : Type _} → [self : my_has_scalar β α] → α → β → α @@ -594,7 +592,7 @@ lemma one_eq_one'' {α : Type*} [One α] : (1 : α) = 1 := rfl /-- error: `to_additive` validation failed: expected - ∀ {α : Type ?u.1} [inst : Zero α], 0 = 0 + ∀ {α : Type _} [inst : Zero α], 0 = 0 but 'Eq.trans' has type ∀ {α : Sort u} {a b c : α}, a = b → b = c → a = c -/ diff --git a/MathlibTest/CategoryTheory/Bicategory/Basic.lean b/MathlibTest/CategoryTheory/Bicategory/Basic.lean index 65c11b8880474c..f8de368a9ddf04 100644 --- a/MathlibTest/CategoryTheory/Bicategory/Basic.lean +++ b/MathlibTest/CategoryTheory/Bicategory/Basic.lean @@ -33,7 +33,6 @@ set_option backward.defeqAttrib.useBackward true in /-- error: expression contains metavariables: (F.map f ≫ η.app b) ≫ ?_ -/ #guard_msgs in -set_option pp.mvars false in example (η : F ⟶ G) {θ ι : G ⟶ H} (Γ : θ ⟶ ι) : η ≫ θ ⟶ η ≫ ι where as := { app a := η.app a ◁ Γ.as.app a diff --git a/MathlibTest/CategoryTheory/CategoryStar.lean b/MathlibTest/CategoryTheory/CategoryStar.lean index 5e0f143a13f2d0..29bef43bbd9d0c 100644 --- a/MathlibTest/CategoryTheory/CategoryStar.lean +++ b/MathlibTest/CategoryTheory/CategoryStar.lean @@ -4,8 +4,6 @@ import Mathlib.CategoryTheory.Functor.Category open CategoryTheory -set_option pp.mvars.anonymous false - section variable (C : Type*) [Category* C] diff --git a/MathlibTest/CategoryTheory/Monoidal/Basic.lean b/MathlibTest/CategoryTheory/Monoidal/Basic.lean index 4430c8758736d5..d0a1a40e6a8315 100644 --- a/MathlibTest/CategoryTheory/Monoidal/Basic.lean +++ b/MathlibTest/CategoryTheory/Monoidal/Basic.lean @@ -30,7 +30,6 @@ example {V₁ V₂ V₃ : C} (R : ∀ V₁ V₂ : C, V₁ ⊗ V₂ ⟶ V₂ ⊗ /-- error: expression contains metavariables: x ⊗ y ⊗ ?_ -/ #guard_msgs in -set_option pp.mvars false in example {x y z w : C} (f : x ⟶ y) (g : y ⟶ z) (h : x ⊗ y ⊗ w ⟶ y ⊗ z ⊗ w) (η : f ⊗ₘ (g ▷ w) = h) : (f ⊗ₘ g) ▷ w = 𝟙 _ ⊗≫ h ⊗≫ 𝟙 _ := by diff --git a/MathlibTest/DefEqAbuse.lean b/MathlibTest/DefEqAbuse.lean index 0db094fae6f786..3d6e28170b8b7d 100644 --- a/MathlibTest/DefEqAbuse.lean +++ b/MathlibTest/DefEqAbuse.lean @@ -187,7 +187,7 @@ theorem zoC_eq_iff {α} [GrC α] (a : α) : NumC.fromNat 0 = a ↔ a = GrC.add a /-- warning: #defeq_abuse: tactic fails with `backward.isDefEq.respectTransparency true` but succeeds with `false`. The following isDefEq checks are the root causes of the failure: - ❌️ @ZoC.zo Int instZoCInt =?= @ZoC.zo Int (@GrC.toZoC Int ?m.11) + ❌️ @ZoC.zo Int instZoCInt =?= @ZoC.zo Int (@GrC.toZoC Int ?_) -/ #guard_msgs in example (a : Int) : NumC.fromNat 0 = a ↔ a = GrC.add a a := by diff --git a/MathlibTest/DifferentialGeometry/Notation/Advanced.lean b/MathlibTest/DifferentialGeometry/Notation/Advanced.lean index 1f0384072fa830..49ccd375e56f0f 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Advanced.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Advanced.lean @@ -56,7 +56,6 @@ error: Could not find a model with corners for `TangentBundle (modelWithCornersS Hint: the expected type contains metavariables, maybe you need to provide an implicit argument -/ #guard_msgs in -set_option pp.mvars.anonymous false in lemma contMDiff_proj : CMDiff ∞ (proj) := by unfold proj exact contMDiff_snd_tangentBundle_modelSpace 𝕜 𝓘(𝕜) @@ -419,7 +418,6 @@ error: Could not find a model with corners for `ContinuousLinearMap σ E'' E'''' Hint: failures to find a model with corners can be debugged with the command `set_option trace.Elab.DiffGeo.MDiff true`. -/ #guard_msgs in -set_option pp.mvars.anonymous false in #check CMDiff 2 f variable {f : M → E'' →SL[σ] E''''} in @@ -491,7 +489,6 @@ trace: [Elab.DiffGeo.MDiff] Finding a model with corners for: `M` -/ #guard_msgs in set_option trace.Elab.DiffGeo.MDiff true in -set_option pp.mvars.anonymous false in #check CMDiff 2 f end diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index 34ebdba01e1cc5..213d4267306fcf 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -565,7 +565,6 @@ error: Could not find a model with corners for `?_`. Hint: the expected type contains metavariables, maybe you need to provide an implicit argument -/ #guard_msgs in -set_option pp.mvars.anonymous false in #check UniqueMDiffAt[Set.univ] m variable {s : TopologicalSpace.Opens M} @@ -589,7 +588,6 @@ in the application UniqueMDiffOn I s -/ #guard_msgs in -set_option pp.mvars.anonymous false in #check UniqueMDiffOn I s end UniqueMDiff diff --git a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean index 6c43114e28e058..52383e8278587d 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Delaborators.lean @@ -230,7 +230,6 @@ variable {g : E × E → E × E} #check MDifferentiable 𝓘(ℝ, E × E) ((𝓘(ℝ, E)).prod (𝓘(ℝ, E))) g -- This can yield rather confusing errors -set_option pp.mvars.anonymous false in /-- error: Tactic `apply` failed: could not unify the conclusion of `@mdifferentiable_id` MDiff id diff --git a/MathlibTest/EuclideanSpace.lean b/MathlibTest/EuclideanSpace.lean index c0336ec46c27fb..781eb674053644 100644 --- a/MathlibTest/EuclideanSpace.lean +++ b/MathlibTest/EuclideanSpace.lean @@ -10,7 +10,6 @@ section delaborator #guard_msgs in #check !₂[1, 2, 3] -set_option pp.mvars.anonymous false in /-- info: !₀[] : WithLp 0 (Fin 0 → ?_) -/ #guard_msgs in #check !₀[] diff --git a/MathlibTest/FinCoercions.lean b/MathlibTest/FinCoercions.lean index 69c81e743a53f6..2341fae3fce457 100644 --- a/MathlibTest/FinCoercions.lean +++ b/MathlibTest/FinCoercions.lean @@ -6,8 +6,6 @@ module import Mathlib -set_option pp.mvars.anonymous false - -- We first verify that there is no global coercion from `Nat` to `Fin n`. -- Such a coercion would frequently introduce unexpected modular arithmetic. diff --git a/MathlibTest/Tactic/Abel.lean b/MathlibTest/Tactic/Abel.lean index 643483f1a391bb..ce9b97245c920c 100644 --- a/MathlibTest/Tactic/Abel.lean +++ b/MathlibTest/Tactic/Abel.lean @@ -176,7 +176,6 @@ h : R (2 • myId x) (2 • myId x) ⊢ True -/ #guard_msgs (trace) in -set_option pp.mvars.anonymous false in example (x : ℤ) (R : ℤ → ℤ → Prop) [Std.Refl R] : True := by have h : R (myId x + x) (x + myId x) := refl _ abel_nf at h diff --git a/MathlibTest/Tactic/Check.lean b/MathlibTest/Tactic/Check.lean index 49c0e03800cae9..7c83b034b541f9 100644 --- a/MathlibTest/Tactic/Check.lean +++ b/MathlibTest/Tactic/Check.lean @@ -1,6 +1,5 @@ import Mathlib.Tactic.Check -set_option pp.mvars.anonymous false set_option linter.unusedTactic false set_option linter.unusedVariables false diff --git a/MathlibTest/Tactic/GRewrite.lean b/MathlibTest/Tactic/GRewrite.lean index cb7404bd831eea..db429d3cbca5af 100644 --- a/MathlibTest/Tactic/GRewrite.lean +++ b/MathlibTest/Tactic/GRewrite.lean @@ -114,7 +114,7 @@ example (h₁ : W ⊂ Y) (h₂ : X ⊂ (W ∪ Z)) : X ⊂ (Y ∪ Z) := by -- Binder names are preserved: /-- -trace: α : Type ?u.3 +trace: α : Type _ X Y Z W : Set α a b : ℕ h : a < b @@ -130,7 +130,7 @@ example {a b : Nat} (h : a < b) (f : Nat → Nat) (hf : ∀ i, 0 ≤ f i) : rfl /-- -trace: α : Type ?u.3 +trace: α : Type _ X Y Z W : Set α ⊢ ∀ {α : Type u_1} [inst : LinearOrder α] (a b : α), max a b ≤ max a b -/ diff --git a/MathlibTest/Util/PrintSorries.lean b/MathlibTest/Util/PrintSorries.lean index a760b777a1b9b5..8520023e1c8eb3 100644 --- a/MathlibTest/Util/PrintSorries.lean +++ b/MathlibTest/Util/PrintSorries.lean @@ -1,7 +1,5 @@ import Mathlib.Util.PrintSorries -set_option pp.mvars.anonymous false - /-! Direct use of `sorry` -/ diff --git a/MathlibTest/Widget/Conv.lean b/MathlibTest/Widget/Conv.lean index 0a3c1f34fa301a..1c065f5fc4a16a 100644 --- a/MathlibTest/Widget/Conv.lean +++ b/MathlibTest/Widget/Conv.lean @@ -152,7 +152,6 @@ example : 1 = Nat.log2 4 → False := by test "/0/1/1" exact test_sorry -set_option pp.mvars.anonymous false in /-- info: `conv?` would output: conv => diff --git a/MathlibTest/superscript.lean b/MathlibTest/superscript.lean index 479a7602b86ea3..9ccaae63acbbb0 100644 --- a/MathlibTest/superscript.lean +++ b/MathlibTest/superscript.lean @@ -194,7 +194,6 @@ open Nat' (γ) in #guard_msgs in #check testsub(ᵧ ₙ) /- The delaborator should reject metavariables. -/ -set_option pp.mvars.anonymous false in /-- info: checkSubscript ?_ : Unit -/ #guard_msgs in #check checkSubscript ?_ @@ -229,7 +228,6 @@ open Nat' (γ) in #guard_msgs in #check testsup(ᵞ ⁿ) /- The delaborator should reject metavariables. -/ -set_option pp.mvars false in /-- info: checkSuperscript ?_ : Unit -/ #guard_msgs in #check checkSuperscript ?_ diff --git a/lakefile.lean b/lakefile.lean index bcdf13405f04bf..2afc2a7a30308a 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -39,7 +39,7 @@ abbrev mathlibOnlyLinters : Array LeanOption := #[ ] /-- These options are passed as `leanOptions` to building mathlib, as well as the -`Archive` and `Counterexamples`. (`tests` omits the first two options.) -/ +`Archive` and `Counterexamples`. -/ abbrev mathlibLeanOptions := #[ ⟨`pp.unicode.fun, true⟩, -- pretty-prints `fun a ↦ b` ⟨`autoImplicit, false⟩, @@ -47,6 +47,12 @@ abbrev mathlibLeanOptions := #[ ] ++ -- options that are used in `lake build` mathlibOnlyLinters.map fun s ↦ { s with name := `weak ++ s.name } +/-- These options are passed as `leanOptions` when building `MathlibTest`. We don't use the typical +mathlib options in order to simulate the default downstream environment. -/ +abbrev mathlibTestOptions : Array LeanOption := #[ + ⟨`pp.mvars.anonymous, false⟩ -- test stability: pretty-print `?m.37` as `?_` + ] + package mathlib where testDriver := "MathlibTest" lintDriver := "batteries/runLinter" @@ -79,6 +85,7 @@ lean_lib Cache where lean_lib MathlibTest where globs := #[`MathlibTest.+] + leanOptions := mathlibTestOptions lean_lib Archive where leanOptions := mathlibLeanOptions From f1578558c05ce56bdc0cf3d15d85b7c940815821 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:39:41 +0000 Subject: [PATCH 0990/1300] feat(Analysis/Normed/Operator/LinearIsometry): add toLinearEquiv_refl (#42019) --- Mathlib/Analysis/Normed/Operator/LinearIsometry.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean index c6806b5a5107ea..fc839187ae9144 100644 --- a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean +++ b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean @@ -629,6 +629,8 @@ instance instInhabited : Inhabited (E ≃ₗᵢ[R] E) := ⟨refl R E⟩ theorem coe_refl : ⇑(refl R E) = id := rfl +@[simp] theorem toLinearEquiv_refl : (refl R E).toLinearEquiv = .refl R E := rfl + @[simp] theorem toContinuousLinearEquiv_refl : (refl R E).toContinuousLinearEquiv = .refl R E := rfl /-- The inverse `LinearIsometryEquiv`. -/ From dfa98dc38651decbfe2df272b404a7a886250f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hagb=20=28Junyu=20Guo=20=E9=83=AD=E4=BF=8A=E4=BD=99=29?= Date: Fri, 24 Jul 2026 14:31:57 +0000 Subject: [PATCH 0991/1300] fix(Data/Finsupp/MonomialOrder): add the missing namespace for deprecated names (#41653) These were incorrectly deprecated as part of a rename in #39494 because the namespace `MonomialOrder` was missing. We fix this here. --- Mathlib/Data/Finsupp/MonomialOrder.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Data/Finsupp/MonomialOrder.lean b/Mathlib/Data/Finsupp/MonomialOrder.lean index 859628c5d6b8a9..551bdf44f3d4e2 100644 --- a/Mathlib/Data/Finsupp/MonomialOrder.lean +++ b/Mathlib/Data/Finsupp/MonomialOrder.lean @@ -21,7 +21,7 @@ get them as instances. In this formalization, they are presented as a structure `MonomialOrder` which encapsulates `MonomialOrder.toSyn`, an additive and monotone isomorphism to a linearly ordered cancellative additive commutative monoid. -The entry `MonomialOrder.wf` asserts that `MonomialOrder.syn` is well founded. +The entry `MonomialOrder.wellFoundedLT_syn` asserts that `MonomialOrder.syn` is well founded. The terminology comes from commutative algebra and algebraic geometry, especially Gröbner bases, where `c : σ →₀ ℕ` are exponents of monomials. @@ -77,16 +77,16 @@ structure MonomialOrder (σ : Type*) where attribute [instance] MonomialOrder.addCommMonoidSyn MonomialOrder.linearOrderSyn MonomialOrder.isOrderedAddMonoid_syn MonomialOrder.wellFoundedLT_syn +namespace MonomialOrder + +variable {σ : Type*} (m : MonomialOrder σ) + @[deprecated (since := "2026-07-07")] alias acm := MonomialOrder.addCommMonoidSyn @[deprecated (since := "2026-07-07")] alias lo := MonomialOrder.linearOrderSyn @[deprecated (since := "2026-07-07")] alias wf := MonomialOrder.wellFoundedLT_syn -namespace MonomialOrder - -variable {σ : Type*} (m : MonomialOrder σ) - instance : AddCancelCommMonoid m.syn where add_left_cancel := m.toSyn.symm.injective.isLeftCancelAdd _ (map_add _) |>.add_left_cancel From 309c8709ca7a1c0e45da3e18e33d697dfcd98a19 Mon Sep 17 00:00:00 2001 From: Luigi Massacci <48868075+luigi-massacci@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:32:00 +0000 Subject: [PATCH 0992/1300] feat: add `LocallyIntegrable` multiplication lemmas mirroring existing API for `LocallyIntegrableOn` (#41733) Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- .../Function/LocallyIntegrable.lean | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean index 9c0a2c366006b4..ca5624ada9cfd6 100644 --- a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean @@ -811,4 +811,31 @@ theorem smul_continuousOn [LocallyCompactSpace X] [T2Space X] {𝕜 : Type*} [No end LocallyIntegrableOn +namespace LocallyIntegrable + +variable [LocallyCompactSpace X] [T2Space X] [NormedRing R] [SecondCountableTopologyEither X R] + {𝕜 : Type*} [NormedRing 𝕜] [Module 𝕜 E] [NormSMulClass 𝕜 E] + +theorem continuous_mul {f g : X → R} (hg : Continuous g) + (hf : LocallyIntegrable f μ) : LocallyIntegrable (fun x => g x * f x) μ := + locallyIntegrableOn_univ.1 ((hf.locallyIntegrableOn univ).continuousOn_mul + hg.continuousOn isOpen_univ.isLocallyClosed) + +theorem mul_continuous {f g : X → R} (hg : Continuous g) + (hf : LocallyIntegrable f μ) : LocallyIntegrable (fun x => f x * g x) μ := + locallyIntegrableOn_univ.1 ((hf.locallyIntegrableOn univ).mul_continuousOn + hg.continuousOn isOpen_univ.isLocallyClosed) + +theorem continuous_smul [SecondCountableTopologyEither X 𝕜] {f : X → E} {g : X → 𝕜} + (hg : Continuous g) (hf : LocallyIntegrable f μ) : LocallyIntegrable (fun x => g x • f x) μ := + locallyIntegrableOn_univ.1 ((hf.locallyIntegrableOn univ).continuousOn_smul + isOpen_univ.isLocallyClosed hg.continuousOn) + +theorem smul_continuous [SecondCountableTopologyEither X E] {f : X → 𝕜} {g : X → E} + (hg : Continuous g) (hf : LocallyIntegrable f μ) : LocallyIntegrable (fun x => f x • g x) μ := + locallyIntegrableOn_univ.1 ((hf.locallyIntegrableOn univ).smul_continuousOn + isOpen_univ.isLocallyClosed hg.continuousOn) + +end LocallyIntegrable + end MeasureTheory From 7f5175c8724369407daa59cd14af73e9c6b755c5 Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Fri, 24 Jul 2026 14:46:04 +0000 Subject: [PATCH 0993/1300] perf(FieldTheory/PurelyInseparable): golf proof (#41664) This one proof was taking a huge amount of time to typecheck, presumably because of some defeq abuse. Fixing this up gives a nice speedup in this file. --- .../PurelyInseparable/PerfectClosure.lean | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean b/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean index be8ed4e1305402..5ace9db7520107 100644 --- a/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean +++ b/Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean @@ -232,20 +232,21 @@ instance isPurelyInseparable_iSup {ι : Sort*} {t : ι → IntermediateField F E theorem adjoin_eq_adjoin_pow_expChar_pow_of_isSeparable (S : Set E) [Algebra.IsSeparable F (adjoin F S)] (q : ℕ) [ExpChar F q] (n : ℕ) : adjoin F S = adjoin F ((· ^ q ^ n) '' S) := by - set L := adjoin F S set M := adjoin F ((· ^ q ^ n) '' S) - have hi : M ≤ L := by - rw [adjoin_le_iff] - rintro _ ⟨y, hy, rfl⟩ + have := expChar_of_injective_algebraMap (algebraMap F M).injective q + refine le_antisymm (adjoin_le_iff.2 fun x hx ↦ ?_) (adjoin_le_iff.2 ?_) + · have : Algebra.IsSeparable M M⟮x⟯ := + (isSeparable_adjoin_simple_iff_isSeparable M E).2 <| + ((isSeparable_adjoin_iff_isSeparable F E).1 inferInstance x hx).tower_top M + have : IsPurelyInseparable M M⟮x⟯ := + (isPurelyInseparable_adjoin_simple_iff_pow_mem M E q).2 + ⟨n, ⟨x ^ q ^ n, subset_adjoin F _ ⟨x, hx, rfl⟩⟩, rfl⟩ + have hx' := mem_adjoin_simple_self M x + rw [M⟮x⟯.eq_bot_of_isPurelyInseparable_of_isSeparable, mem_bot] at hx' + obtain ⟨y, rfl⟩ := hx' + exact y.2 + · rintro _ ⟨y, hy, rfl⟩ exact pow_mem (subset_adjoin F S hy) _ - let := (inclusion hi).toAlgebra - have : Algebra.IsSeparable M (extendScalars hi) := - Algebra.isSeparable_tower_top_of_isSeparable F M L - have : IsPurelyInseparable M (extendScalars hi) := by - rw [extendScalars_adjoin hi, isPurelyInseparable_adjoin_iff_pow_mem M _ q] - exact fun x hx ↦ ⟨n, ⟨x ^ q ^ n, subset_adjoin F _ ⟨x, hx, rfl⟩⟩, rfl⟩ - simpa only [extendScalars_restrictScalars, restrictScalars_bot_eq_self] using congr_arg - (restrictScalars F) (extendScalars hi).eq_bot_of_isPurelyInseparable_of_isSeparable /-- If `E / F` is a separable field extension of exponential characteristic `q`, then `F(S) = F(S ^ (q ^ n))` for any subset `S` of `E` and any natural number `n`. -/ From 8ab8444157b2ade031e28ed9ef63dc07c4e1f77b Mon Sep 17 00:00:00 2001 From: Jun Kwon Date: Fri, 24 Jul 2026 14:56:08 +0000 Subject: [PATCH 0994/1300] feat(Data/List): Nodup and head & getLast lemmas (#38830) Given a Nodup list: * If a prefix contains the last element, they are equal * If a suffix contains the first element, they are equal * If an infix contains the first element, it is a prefix * If an infix contains the last element, it is a suffix * If the first and the last element are the same, it is a singleton * `countP` is cardinality of the filter of `toFinset`. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Oliver Nash --- Mathlib/Data/Finset/Basic.lean | 3 +++ Mathlib/Data/Finset/Card.lean | 5 +++++ Mathlib/Data/List/Nodup.lean | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/Mathlib/Data/Finset/Basic.lean b/Mathlib/Data/Finset/Basic.lean index 7bdf67e11ead86..5e032bdacc7bb3 100644 --- a/Mathlib/Data/Finset/Basic.lean +++ b/Mathlib/Data/Finset/Basic.lean @@ -511,6 +511,9 @@ theorem toFinset_filter (s : List α) (p : α → Bool) : (s.filter p).toFinset = s.toFinset.filter (p ·) := by ext; simp [List.mem_filter] +theorem filter_toFinset (s : List α) (p : α → Prop) [DecidablePred p] : + s.toFinset.filter p = (s.filter p).toFinset := by simp + end List namespace Finset diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 7018b37de1f282..4e5dc19df677dc 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -212,6 +212,11 @@ theorem List.toFinset_card_le : #l.toFinset ≤ l.length := theorem List.toFinset_card_of_nodup {l : List α} (h : l.Nodup) : #l.toFinset = l.length := Multiset.toFinset_card_of_nodup h +lemma List.Nodup.card_eq_countP {l : List α} {P : α → Prop} [DecidablePred P] (h : l.Nodup) : + (l.toFinset.filter P).card = countP P l := by + rw [l.countP_eq_length_filter, l.filter_toFinset P] + exact toFinset_card_of_nodup (h.filter P) + end ToMultiset namespace Finset diff --git a/Mathlib/Data/List/Nodup.lean b/Mathlib/Data/List/Nodup.lean index b4a80de0e66537..6679355bbc2fbf 100644 --- a/Mathlib/Data/List/Nodup.lean +++ b/Mathlib/Data/List/Nodup.lean @@ -121,6 +121,10 @@ theorem not_nodup_of_get_eq_of_ne (xs : List α) (n m : Fin xs.length) rw [nodup_iff_injective_get] exact fun hinj => hne (hinj h) +lemma Nodup.head_eq_getLast_iff (hne : l ≠ []) (hnd : l.Nodup) : + l.head hne = l.getLast hne ↔ ∃ x, l = [x] := by + cases l <;> grind + -- This is incorrectly named and should be `idxOf_get`; -- this already exists, so will require a deprecation dance. theorem get_idxOf [BEq α] [LawfulBEq α] {l : List α} (H : Nodup l) (i : Fin l.length) : @@ -252,6 +256,26 @@ lemma nodup_tail_reverse (l : List α) (h : l[0]? = l.getLast?) : List.nodup_append_comm] simp [List.getLast_eq_getElem] +lemma Nodup.eq_of_head_mem_of_suffix (h : l₁ <:+ l₂) {hne : l₂ ≠ []} (hl : l₂.head hne ∈ l₁) + (hnd : l₂.Nodup) : l₁ = l₂ := by + grind [List.IsSuffix] + +lemma Nodup.eq_of_getLast_mem_of_prefix (h : l₁ <+: l₂) {hne : l₂ ≠ []} (hl : l₂.getLast hne ∈ l₁) + (hnd : l₂.Nodup) : l₁ = l₂ := by + grind [List.IsPrefix] + +lemma Nodup.prefix_of_head_mem_of_infix (h : l₁ <:+: l₂) {hne : l₂ ≠ []} (hl : l₂.head hne ∈ l₁) + (hnd : l₂.Nodup) : l₁ <+: l₂ := by + grind [List.IsInfix] + +lemma Nodup.suffix_of_getLast_mem_of_infix (h : l₁ <:+: l₂) {hne : l₂ ≠ []} + (hl : l₂.getLast hne ∈ l₁) (hnd : l₂.Nodup) : l₁ <:+ l₂ := by + grind [List.IsInfix] + +lemma Nodup.eq_of_head_mem_of_getLast_mem_of_infix (h : l₁ <:+: l₂) {hne : l₂ ≠ []} + (hlh : l₂.head hne ∈ l₁) (hlg : l₂.getLast hne ∈ l₁) (hnd : l₂.Nodup) : l₁ = l₂ := by + grind [List.IsInfix] + theorem Nodup.erase_getElem [BEq α] [LawfulBEq α] {l : List α} (hl : l.Nodup) (i : Nat) (h : i < l.length) : l.erase l[i] = l.eraseIdx ↑i := by induction l generalizing i with From a21131a4adb876a0d55d9195a6bec2d724e1fbaa Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 24 Jul 2026 15:46:36 +0000 Subject: [PATCH 0995/1300] =?UTF-8?q?fix(Geometry/Manifold/Instances/Real)?= =?UTF-8?q?:=20make=20EuclideanHalfSpace=20and=20Eu=E2=80=A6=20(#42031)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …clideanQuadrant implicit_reducible This allows removing some technical debt and fixes all but two warnings of the linter.tacticCheckInstances linter in this file. (The remaining ones are about identifying membership in Set.Icc with the conjuction of the two individual hypotheses, i.e. are unrelated to this file.) --- Mathlib/Geometry/Manifold/Instances/Icc.lean | 2 -- Mathlib/Geometry/Manifold/Instances/Real.lean | 15 ++++----------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Instances/Icc.lean b/Mathlib/Geometry/Manifold/Instances/Icc.lean index 3dbdb7fe34c83e..a7b42272c3f27e 100644 --- a/Mathlib/Geometry/Manifold/Instances/Icc.lean +++ b/Mathlib/Geometry/Manifold/Instances/Icc.lean @@ -107,7 +107,6 @@ lemma contMDiff_subtype_coe_Icc : CMDiff n (fun (z : Icc x y) ↦ (z : ℝ)) := rw [max_eq_left hw, max_eq_left] linarith -set_option backward.isDefEq.respectTransparency false in /-- The projection from `ℝ` to a closed segment is smooth on the segment, in the manifold sense. -/ lemma contMDiffOn_projIcc : CMDiff[Icc x y] n (Set.projIcc x y h.out.le) := by intro z hz @@ -176,7 +175,6 @@ lemma mfderivWithin_projIcc_one {z : ℝ} (hz : z ∈ Icc x y) : congr simp [projIcc_of_mem h.out.le hz] -set_option backward.isDefEq.respectTransparency false in lemma mfderivWithin_comp_projIcc_one {f : Icc x y → M} {w : Icc x y} : mfderiv[Icc x y] (f ∘ (projIcc x y h.out.le)) w 1 = mfderiv% f w 1 := by by_cases hw : MDiffAt f w; swap diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index da88799829a6d8..1cf415f0bbeec8 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -55,6 +55,7 @@ open scoped Manifold ContDiff ENNReal /-- The half-space in `ℝ^n`, used to model manifolds with boundary. We only define it when `1 ≤ n`, as the definition only makes sense in this case. -/ +@[implicit_reducible] def EuclideanHalfSpace (n : ℕ) [NeZero n] : Type := { x : EuclideanSpace ℝ (Fin n) // 0 ≤ x 0 } deriving TopologicalSpace @@ -63,6 +64,7 @@ deriving TopologicalSpace The quadrant in `ℝ^n`, used to model manifolds with corners, made of all vectors with nonnegative coordinates. -/ +@[implicit_reducible] def EuclideanQuadrant (n : ℕ) : Type := { x : EuclideanSpace ℝ (Fin n) // ∀ i : Fin n, 0 ≤ x i } deriving TopologicalSpace @@ -167,7 +169,6 @@ theorem interior_euclideanQuadrant (n : ℕ) (p : ℝ≥0∞) (a : ℝ) : end -set_option backward.isDefEq.respectTransparency false in /-- Definition of the model with corners `(EuclideanSpace ℝ (Fin n), EuclideanHalfSpace n)`, used as a model for manifolds with boundary. In the scope `Manifold`, use the shortcut `𝓡∂ n`. @@ -200,7 +201,6 @@ def modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] : exact ((PiLp.continuous_toLp 2 _).comp <| (PiLp.continuous_ofLp 2 _).update 0 <| (PiLp.continuous_apply 2 _ 0).max continuous_const).subtype_mk _ -set_option backward.isDefEq.respectTransparency false in /-- Definition of the model with corners `(EuclideanSpace ℝ (Fin n), EuclideanQuadrant n)`, used as a model for manifolds with corners -/ @@ -261,7 +261,6 @@ lemma frontier_range_modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] : apply range_euclideanHalfSpace _ = { y | 0 = y 0 } := frontier_halfSpace 2 _ _ -set_option backward.isDefEq.respectTransparency false in /-- The left chart for the topological space `[x, y]`, defined on `[x,y)` and sending `x` to `0` in `EuclideanHalfSpace 1`. -/ @@ -271,8 +270,7 @@ def IccLeftChart (x y : ℝ) [h : Fact (x < y)] : target := { z : EuclideanHalfSpace 1 | z.val 0 < y - x } toFun := fun z : Icc x y => ⟨toLp 2 fun _ ↦ z.val - x, sub_nonneg.mpr z.property.1⟩ invFun z := ⟨min (z.val 0 + x) y, by simp [z.prop, h.out.le]⟩ - map_source' := by simp only [mem_ofPred_eq, Fin.isValue, sub_lt_sub_iff_right, - imp_self, implies_true] + map_source' := by simp map_target' := by simp only [min_lt_iff, mem_ofPred_eq]; intro z hz; left linarith @@ -309,7 +307,6 @@ end Fact.Manifold open Fact.Manifold -set_option backward.isDefEq.respectTransparency false in lemma IccLeftChart_extend_bot : (IccLeftChart x y).extend (𝓡∂ 1) ⊥ = 0 := by norm_num [IccLeftChart, modelWithCornersEuclideanHalfSpace_zero] congr @@ -327,7 +324,6 @@ lemma IccLeftChart_extend_bot_mem_frontier : rw [IccLeftChart_extend_bot, frontier_range_modelWithCornersEuclideanHalfSpace, mem_ofPred, PiLp.zero_apply] -set_option backward.isDefEq.respectTransparency false in /-- The right chart for the topological space `[x, y]`, defined on `(x,y]` and sending `y` to `0` in `EuclideanHalfSpace 1`. -/ @@ -338,8 +334,7 @@ def IccRightChart (x y : ℝ) [h : Fact (x < y)] : toFun z := ⟨toLp 2 fun _ ↦ y - z.val, sub_nonneg.mpr z.property.2⟩ invFun z := ⟨max (y - z.val 0) x, by simp [z.prop, h.out.le, sub_eq_add_neg]⟩ - map_source' := by simp only [mem_ofPred_eq, Fin.isValue, sub_lt_sub_iff_left, - imp_self, implies_true] + map_source' := by simp map_target' := by simp only [lt_max_iff, mem_ofPred_eq]; intro z hz; left linarith @@ -367,7 +362,6 @@ def IccRightChart (x y : ℝ) [h : Fact (x < y)] : continuousOn_toFun := by fun_prop continuousOn_invFun := by fun_prop -set_option backward.isDefEq.respectTransparency false in lemma IccRightChart_extend_top : (IccRightChart x y).extend (𝓡∂ 1) ⊤ = 0 := by norm_num [IccRightChart, modelWithCornersEuclideanHalfSpace_zero] @@ -445,7 +439,6 @@ lemma boundary_product [I.Boundaryless] : (I.prod (𝓡∂ 1)).boundary (M × Icc x y) = Set.prod univ {⊥, ⊤} := by rw [I.boundary_of_boundaryless_left, boundary_Icc] -set_option backward.isDefEq.respectTransparency false in /-- The manifold structure on `[x, y]` is smooth. -/ instance instIsManifoldIcc (x y : ℝ) [Fact (x < y)] {n : ℕ∞ω} : IsManifold (𝓡∂ 1) n (Icc x y) := by From 73fbc3ec50df9de77cd78daa1983f270e3867f89 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Fri, 24 Jul 2026 16:24:01 +0000 Subject: [PATCH 0996/1300] feat: specific variations of `Tendsto.smul` when one of the limits is zero or one (#41987) --- Mathlib/Analysis/LocallyConvex/Basic.lean | 3 +- Mathlib/Topology/Algebra/ConstMulAction.lean | 11 ++++++ Mathlib/Topology/Algebra/Module/Basic.lean | 10 ++--- .../Algebra/Module/EmbeddingOfLocal.lean | 7 ++-- Mathlib/Topology/Algebra/MulAction.lean | 38 +++++++++++++++++++ 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/Mathlib/Analysis/LocallyConvex/Basic.lean b/Mathlib/Analysis/LocallyConvex/Basic.lean index cdfd69065a23f7..4ce40495bb0431 100644 --- a/Mathlib/Analysis/LocallyConvex/Basic.lean +++ b/Mathlib/Analysis/LocallyConvex/Basic.lean @@ -230,8 +230,7 @@ variable [TopologicalSpace E] [ContinuousSMul 𝕜 E] /-- Every neighbourhood of the origin is absorbent. -/ theorem absorbent_nhds_zero (hA : A ∈ 𝓝 (0 : E)) : Absorbent 𝕜 A := - absorbent_iff_inv_smul.2 fun x ↦ Filter.tendsto_inv₀_cobounded.smul tendsto_const_nhds <| by - rwa [zero_smul] + absorbent_iff_inv_smul.2 fun _ ↦ Filter.tendsto_inv₀_cobounded.zero_smul_const _ hA /-- The union of `{0}` with the interior of a balanced set is balanced. -/ theorem Balanced.zero_insert_interior (hA : Balanced 𝕜 A) : diff --git a/Mathlib/Topology/Algebra/ConstMulAction.lean b/Mathlib/Topology/Algebra/ConstMulAction.lean index 3185cf45929522..4d70c0264fba55 100644 --- a/Mathlib/Topology/Algebra/ConstMulAction.lean +++ b/Mathlib/Topology/Algebra/ConstMulAction.lean @@ -180,6 +180,17 @@ theorem isClosed_setOfPred_map_smul {N : Type*} (α β) [SMul M α] [SMul N β] end SMul +section SMulZeroClass + +variable [TopologicalSpace α] [Zero α] [SMulZeroClass M α] [ContinuousConstSMul M α] + +protected theorem Filter.Tendsto.const_smul_zero {g : β → α} {l : Filter β} + (c : M) (hg : Tendsto g l (𝓝 0)) : + Tendsto (fun x ↦ c • g x) l (𝓝 0) := + smul_zero c (A := α) ▸ hg.const_smul c + +end SMulZeroClass + section Monoid variable [TopologicalSpace α] diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index 383e84088b4713..da0922c9267489 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -66,9 +66,9 @@ theorem Submodule.eq_top_of_nonempty_interior' [NeBot (𝓝[{ x : R | IsUnit x } rcases hs with ⟨y, hy⟩ refine Submodule.eq_top_iff'.2 fun x => ?_ rw [mem_interior_iff_mem_nhds] at hy - have : Tendsto (fun c : R => y + c • x) (𝓝[{ x : R | IsUnit x }] 0) (𝓝 (y + (0 : R) • x)) := - tendsto_const_nhds.add ((tendsto_nhdsWithin_of_tendsto_nhds tendsto_id).smul tendsto_const_nhds) - rw [zero_smul, add_zero] at this + have : Tendsto (fun c : R ↦ y + c • x) (𝓝[{ x : R | IsUnit x }] 0) (𝓝 (y + 0)) := + tendsto_const_nhds.add ((tendsto_nhdsWithin_of_tendsto_nhds tendsto_id).zero_smul_const _) + rw [add_zero] at this obtain ⟨_, hu : y + _ • _ ∈ s, u, rfl⟩ := nonempty_of_mem (inter_mem (Filter.mem_map.1 (this hy)) self_mem_nhdsWithin) have hy' : y ∈ ↑s := mem_of_mem_nhds hy @@ -90,8 +90,8 @@ theorem Module.punctured_nhds_neBot [Nontrivial M] [NeBot (𝓝[≠] (0 : R))] [ rcases exists_ne (0 : M) with ⟨y, hy⟩ suffices Tendsto (fun c : R => x + c • y) (𝓝[≠] 0) (𝓝[≠] x) from this.neBot refine Tendsto.inf ?_ (tendsto_principal_principal.2 <| ?_) - · convert! tendsto_const_nhds.add ((@tendsto_id R _).smul_const y) - rw [zero_smul, add_zero] + · convert! tendsto_const_nhds.add ((@tendsto_id R _).zero_smul_const y) + rw [add_zero] · intro c hc simpa [hy] using hc diff --git a/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean b/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean index d65e247829244a..29325bbb0d51eb 100644 --- a/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean +++ b/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean @@ -106,11 +106,10 @@ lemma ContinuousSMul.topology_eq_of_nhds_inf_principal_eq (t₁ t₂ : Topologic -- Let `w ∈ W` be arbitrary. intro w w_in_W -- Because `V` is a `t₁`-neighborhood of `0`, we have `c ^ n • w ∈ V` for some natural number `n`. - obtain ⟨n, hn⟩ : ∃ n : ℕ, c ^ n • w ∈ V := by + obtain ⟨n, hn⟩ : ∃ n : ℕ, c ^ n • w ∈ V := let := t₁ - have : Tendsto (fun k : ℕ ↦ c ^ k • w) atTop (𝓝 0) := - zero_smul 𝕜₁ w ▸ (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hc₁).smul_const w - exact this.eventually_mem V_mem |>.exists + tendsto_pow_atTop_nhds_zero_of_norm_lt_one hc₁ |>.zero_smul_const w + |>.eventually_mem V_mem |>.exists -- We will conclude by reducing `c ^ n • w ∈ V` to `w = c ^ 0 • w ∈ V` inductively. suffices c ^ 0 • w ∈ V by simpa apply Nat.decreasingInduction (motive := fun (k : ℕ) _ ↦ c^k • w ∈ V) ?_ hn n.zero_le diff --git a/Mathlib/Topology/Algebra/MulAction.lean b/Mathlib/Topology/Algebra/MulAction.lean index a2c24ba7ee7ad6..ce466c4e934f2e 100644 --- a/Mathlib/Topology/Algebra/MulAction.lean +++ b/Mathlib/Topology/Algebra/MulAction.lean @@ -201,10 +201,48 @@ instance SMulMemClass.continuousSMul {S : Type*} [SetLike S X] [SMulMemClass S M end SMul +section SMulZeroClass + +variable [Zero X] [SMulZeroClass M X] [ContinuousSMul M X] + +protected theorem Filter.Tendsto.smul_zero {f : α → M} {g : α → X} {l : Filter α} {c : M} + (hf : Tendsto f l (𝓝 c)) (hg : Tendsto g l (𝓝 0)) : + Tendsto (fun x ↦ f x • g x) l (𝓝 0) := + smul_zero c (A := X) ▸ hf.smul hg + +end SMulZeroClass + +section SMulWithZero + +variable [Zero M] [Zero X] [SMulWithZero M X] [ContinuousSMul M X] + +protected theorem Filter.Tendsto.zero_smul {f : α → M} {g : α → X} {l : Filter α} {a : X} + (hf : Tendsto f l (𝓝 0)) (hg : Tendsto g l (𝓝 a)) : + Tendsto (fun x ↦ f x • g x) l (𝓝 0) := + zero_smul M a ▸ hf.smul hg + +protected theorem Filter.Tendsto.zero_smul_const {f : α → M} {l : Filter α} + (hf : Tendsto f l (𝓝 0)) (a : X) : + Tendsto (fun x ↦ f x • a) l (𝓝 0) := + hf.zero_smul tendsto_const_nhds + +end SMulWithZero + section Monoid variable [Monoid M] [MulAction M X] [ContinuousSMul M X] +@[to_additive] +protected theorem Filter.Tendsto.one_smul {f : α → M} {g : α → X} {l : Filter α} {a : X} + (hf : Tendsto f l (𝓝 1)) (hg : Tendsto g l (𝓝 a)) : + Tendsto (fun x ↦ f x • g x) l (𝓝 a) := + one_smul M a ▸ hf.smul hg + +@[to_additive] +protected theorem Filter.Tendsto.one_smul_const {f : α → M} {l : Filter α} + (hf : Tendsto f l (𝓝 1)) (a : X) : Tendsto (fun x ↦ f x • a) l (𝓝 a) := + hf.one_smul tendsto_const_nhds + @[to_additive] instance Units.continuousSMul : ContinuousSMul Mˣ X := IsInducing.id.continuousSMul Units.continuous_val rfl From 32e89fb3b5a50a4a30fc6c8e2e1672ee45e0e4c1 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Fri, 24 Jul 2026 17:08:21 +0000 Subject: [PATCH 0997/1300] feat(RingTheory/PowerSeries/Derivative): add coeff_iterate_derivative (#41138) A simple lemma about iterating the derivative --- Mathlib/RingTheory/PowerSeries/Derivative.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/RingTheory/PowerSeries/Derivative.lean b/Mathlib/RingTheory/PowerSeries/Derivative.lean index c926fb57153ca6..8ba5d9e04603c4 100644 --- a/Mathlib/RingTheory/PowerSeries/Derivative.lean +++ b/Mathlib/RingTheory/PowerSeries/Derivative.lean @@ -61,6 +61,23 @@ theorem coeff_derivative (f : R⟦X⟧) (n : ℕ) : coeff n (d⁄dX R f) = coeff (n + 1) f * (n + 1) := by simp [coeff, derivative, MvPowerSeries.coeff_pderiv] +/-- The `k`-th coefficient of the `n`-th formal derivative: differentiating `n` times multiplies the +`(k + n)`-th coefficient by the ascending factorial `(k + 1)(k + 2) ⋯ (k + n)`. -/ +theorem coeff_iterate_derivative (f : R⟦X⟧) (n k : ℕ) : + coeff k ((d⁄dX R)^[n] f) = (k + 1).ascFactorial n * coeff (k + n) f := by + induction n generalizing k with + | zero => simp + | succ n ih => + rw [Function.iterate_succ_apply', coeff_derivative, ih, Nat.ascFactorial_succ, + ← Nat.succ_ascFactorial] + grind + +/-- Specialisation of `coeff_iterate_derivative` at `k = 0`: the constant term of the `n`-th formal +derivative recovers `n !` times the `n`-th coefficient, `constantCoeff (Dⁿ f) = n ! * coeff n f`. -/ +theorem constantCoeff_iterate_derivative (f : R⟦X⟧) (n : ℕ) : + constantCoeff ((d⁄dX R)^[n] f) = n ! * coeff n f := by + simpa using coeff_iterate_derivative f n 0 + theorem derivative_coe (f : R[X]) : d⁄dX R f = Polynomial.derivative f := by ext rw [coeff_derivative, coeff_coe, coeff_coe, Polynomial.coeff_derivative] From 3b3581acea0edde26ed8babafe6c547f85eeba01 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 24 Jul 2026 17:51:01 +0000 Subject: [PATCH 0998/1300] fix(Algebra/FreeMonoid): fix recursor argument names (#41929) Fix the argument names of `FreeMonoid.recOn`, `FreeMonoid.inductionOn`, and `FreeMonoid.inductionOn'`. Name the motive `motive` and name the minor premises according to their contents. --- Mathlib/Algebra/FreeMonoid/Basic.lean | 47 ++++++++++--------- .../Algebra/Group/Submonoid/Membership.lean | 2 +- Mathlib/GroupTheory/Coprod/Basic.lean | 4 +- .../LinearAlgebra/PiTensorProduct/Basic.lean | 2 +- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index bc1c911462ccfa..b5e85acc3ed9cb 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -236,16 +236,18 @@ end Mem /-- Recursor for `FreeAddMonoid` using `0` and `FreeAddMonoid.of x + xs` instead of `[]` and `x :: xs`. -/] -- Porting note: change from `List.recOn` to `List.rec` since only the latter is computable -def recOn {C : FreeMonoid α → Sort*} (xs : FreeMonoid α) (h0 : C 1) - (ih : ∀ x xs, C xs → C (of x * xs)) : C xs := List.rec h0 ih xs +def recOn {motive : FreeMonoid α → Sort*} (xs : FreeMonoid α) (one : motive 1) + (of_mul : ∀ x xs, motive xs → motive (of x * xs)) : motive xs := List.rec one of_mul xs @[to_additive (attr := simp)] -theorem recOn_one {C : FreeMonoid α → Sort*} (h0 : C 1) (ih : ∀ x xs, C xs → C (of x * xs)) : - @recOn α C 1 h0 ih = h0 := rfl +theorem recOn_one {motive : FreeMonoid α → Sort*} (one : motive 1) + (of_mul : ∀ x xs, motive xs → motive (of x * xs)) : + @recOn α motive 1 one of_mul = one := rfl @[to_additive (attr := simp)] -theorem recOn_of_mul {C : FreeMonoid α → Sort*} (x : α) (xs : FreeMonoid α) (h0 : C 1) - (ih : ∀ x xs, C xs → C (of x * xs)) : @recOn α C (of x * xs) h0 ih = ih x xs (recOn xs h0 ih) := +theorem recOn_of_mul {motive : FreeMonoid α → Sort*} (x : α) (xs : FreeMonoid α) (one : motive 1) + (of_mul : ∀ x xs, motive xs → motive (of x * xs)) : + @recOn α motive (of x * xs) one of_mul = of_mul x xs (recOn xs one of_mul) := rfl /-! ### Induction -/ @@ -255,18 +257,19 @@ section induction_principles /-- An induction principle on free monoids, with cases for `1`, `FreeMonoid.of` and `*`. -/ @[to_additive (attr := elab_as_elim, induction_eliminator) /-- An induction principle on free monoids, with cases for `0`, `FreeAddMonoid.of` and `+`. -/] -protected theorem inductionOn {C : FreeMonoid α → Prop} (z : FreeMonoid α) (one : C 1) - (of : ∀ (x : α), C (FreeMonoid.of x)) (mul : ∀ (x y : FreeMonoid α), C x → C y → C (x * y)) : - C z := - List.rec one (fun _ _ ih => mul [_] _ (of _) ih) z +protected theorem inductionOn {motive : FreeMonoid α → Prop} (z : FreeMonoid α) (one : motive 1) + (of : ∀ (x : α), motive (FreeMonoid.of x)) + (mul : ∀ (x y : FreeMonoid α), motive x → motive y → motive (x * y)) : + motive z := + recOn z one fun x xs ih => mul (.of x) xs (of x) ih /-- An induction principle for free monoids which mirrors induction on lists, with cases analogous to the empty list and cons -/ @[to_additive (attr := elab_as_elim) /-- An induction principle for free monoids which mirrors induction on lists, with cases analogous to the empty list and cons -/] -protected theorem inductionOn' {p : FreeMonoid α → Prop} (a : FreeMonoid α) - (one : p (1 : FreeMonoid α)) (mul_of : ∀ b a, p a → p (of b * a)) : p a := - List.rec one (fun _ _ tail_ih => mul_of _ _ tail_ih) a +protected theorem inductionOn' {motive : FreeMonoid α → Prop} (a : FreeMonoid α) + (one : motive (1 : FreeMonoid α)) (of_mul : ∀ b a, motive a → motive (of b * a)) : motive a := + recOn a one of_mul end induction_principles @@ -275,16 +278,18 @@ end induction_principles @[to_additive (attr := elab_as_elim, cases_eliminator) /-- A version of `List.casesOn` for `FreeAddMonoid` using `0` and `FreeAddMonoid.of x + xs` instead of `[]` and `x :: xs`. -/] -def casesOn {C : FreeMonoid α → Sort*} (xs : FreeMonoid α) (h0 : C 1) - (ih : ∀ x xs, C (of x * xs)) : C xs := List.casesOn xs h0 ih +def casesOn {motive : FreeMonoid α → Sort*} (xs : FreeMonoid α) (one : motive 1) + (of_mul : ∀ x xs, motive (of x * xs)) : motive xs := List.casesOn xs one of_mul @[to_additive (attr := simp)] -theorem casesOn_one {C : FreeMonoid α → Sort*} (h0 : C 1) (ih : ∀ x xs, C (of x * xs)) : - @casesOn α C 1 h0 ih = h0 := rfl +theorem casesOn_one {motive : FreeMonoid α → Sort*} (one : motive 1) + (of_mul : ∀ x xs, motive (of x * xs)) : + @casesOn α motive 1 one of_mul = one := rfl @[to_additive (attr := simp)] -theorem casesOn_of_mul {C : FreeMonoid α → Sort*} (x : α) (xs : FreeMonoid α) (h0 : C 1) - (ih : ∀ x xs, C (of x * xs)) : @casesOn α C (of x * xs) h0 ih = ih x xs := rfl +theorem casesOn_of_mul {motive : FreeMonoid α → Sort*} (x : α) (xs : FreeMonoid α) (one : motive 1) + (of_mul : ∀ x xs, motive (of x * xs)) : + @casesOn α motive (of x * xs) one of_mul = of_mul x xs := rfl @[to_additive (attr := ext)] theorem hom_eq ⦃f g : FreeMonoid α →* M⦄ (h : ∀ x, f (of x) = g (of x)) : f = g := @@ -431,7 +436,7 @@ theorem map_surjective {f : α → β} : Function.Surjective (map f) ↔ Functio | one => have H := congr_arg length hb simp only [length_one, length_of, Nat.zero_ne_one, map_one] at H - | mul_of head _ _ => + | of_mul head _ _ => simp only [map_mul, map_of] at hb use head have H := congr_arg length hb @@ -441,7 +446,7 @@ theorem map_surjective {f : α → β} : Function.Surjective (map f) ↔ Functio intro fs d induction d using FreeMonoid.inductionOn' with | one => use 1; rfl - | mul_of head tail ih => + | of_mul head tail ih => specialize fs head rcases fs with ⟨a, rfl⟩ rcases ih with ⟨b, rfl⟩ diff --git a/Mathlib/Algebra/Group/Submonoid/Membership.lean b/Mathlib/Algebra/Group/Submonoid/Membership.lean index e9e109c8842c1a..01e73b2c7a7a47 100644 --- a/Mathlib/Algebra/Group/Submonoid/Membership.lean +++ b/Mathlib/Algebra/Group/Submonoid/Membership.lean @@ -277,7 +277,7 @@ theorem closure_induction_left obtain ⟨l, rfl⟩ := h induction l using FreeMonoid.inductionOn' with | one => exact one - | mul_of x y ih => + | of_mul x y ih => simp only [map_mul, FreeMonoid.lift_eval_of] refine mul_left _ x.prop (FreeMonoid.lift Subtype.val y) _ (ih ?_) simp only [closure_eq_mrange, mem_mrange, exists_apply_eq_apply] diff --git a/Mathlib/GroupTheory/Coprod/Basic.lean b/Mathlib/GroupTheory/Coprod/Basic.lean index c831e8580d95a9..eb2be828212cbb 100644 --- a/Mathlib/GroupTheory/Coprod/Basic.lean +++ b/Mathlib/GroupTheory/Coprod/Basic.lean @@ -200,7 +200,7 @@ theorem induction_on' {motive : M ∗ N → Prop} (m : M ∗ N) rcases mk_surjective m with ⟨x, rfl⟩ induction x using FreeMonoid.inductionOn' with | one => exact one - | mul_of x xs ih => + | of_mul x xs ih => cases x with | inl m => simpa using inl_mul m _ ih | inr n => simpa using inr_mul n _ ih @@ -582,7 +582,7 @@ theorem con_inv_mul_cancel (x : FreeMonoid (G ⊕ H)) : rw [← mk_eq_mk, map_mul, map_one] induction x using FreeMonoid.inductionOn' with | one => simp - | mul_of x xs ihx => + | of_mul x xs ihx => simp only [toList_of_mul, map_cons, reverse_cons, ofList_append, map_mul, ofList_singleton] rwa [mul_assoc, ← mul_assoc (mk (of _)), mk_of_inv_mul, one_mul] diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean index 405485f74613b9..30f274638e5728 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean @@ -301,7 +301,7 @@ lemma _root_.FreeAddMonoid.toPiTensorProduct (p : FreeAddMonoid (R × Π i, s i) List.sum (List.map (fun x ↦ x.1 • ⨂ₜ[R] i, x.2 i) p.toList) := by induction p using FreeAddMonoid.inductionOn' with | zero => rfl - | add_of b a ih => + | of_add b a ih => rw [FreeAddMonoid.toList_of_add, List.map_cons, List.sum_cons, ← ih, ← tprodCoeff_eq_smul_tprod] rfl From 26245e682c354e86f2a4a300812fe4673ae107dc Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 24 Jul 2026 18:27:12 +0000 Subject: [PATCH 0999/1300] chore(GroupTheory/Torsion): rename `IsTorsion` to `IsMulTorsion` (#41213) `GroupTheory/Torsion.lean` has some bad to_additive translations. This PR fixes this by renaming `Monoid.IsTorsion` to `IsMulTorsion` and `AddMonoid.IsTorsion` to `IsAddTorsion`. This also aligns better with `IsMulTorsionFree` and `IsAddTorsionFree`. This PR has a lot of deprecations, but you can check the lean-aware declarations diff to make sure I didn't miss anything. Co-authored-by: tb65536 --- Mathlib/Algebra/Module/Torsion/Basic.lean | 16 +- Mathlib/GroupTheory/FiniteAbelian/Basic.lean | 25 +- Mathlib/GroupTheory/Torsion.lean | 232 ++++++++++++------- 3 files changed, 177 insertions(+), 96 deletions(-) diff --git a/Mathlib/Algebra/Module/Torsion/Basic.lean b/Mathlib/Algebra/Module/Torsion/Basic.lean index b270a3c789eecc..9d69c7470c6ce9 100644 --- a/Mathlib/Algebra/Module/Torsion/Basic.lean +++ b/Mathlib/Algebra/Module/Torsion/Basic.lean @@ -938,10 +938,8 @@ theorem torsionBy_eq_span_singleton {R : Type w} [CommRing R] (a b : R) (ha : a end Ideal.Quotient -namespace AddMonoid - -theorem isTorsion_iff_isTorsion_nat [AddCommMonoid M] : - AddMonoid.IsTorsion M ↔ Module.IsTorsion ℕ M := by +theorem isAddTorsion_iff_isTorsion_nat [AddCommMonoid M] : + IsAddTorsion M ↔ Module.IsTorsion ℕ M := by refine ⟨fun h x => ?_, fun h x => ?_⟩ · obtain ⟨n, h0, hn⟩ := (h x).exists_nsmul_eq_zero exact ⟨⟨n, mem_nonZeroDivisors_of_ne_zero <| ne_of_gt h0⟩, hn⟩ @@ -949,8 +947,11 @@ theorem isTorsion_iff_isTorsion_nat [AddCommMonoid M] : obtain ⟨n, hn⟩ := @h x exact ⟨n, Nat.pos_of_ne_zero (nonZeroDivisors.coe_ne_zero _), hn⟩ -theorem isTorsion_iff_isTorsion_int [AddCommGroup M] : - AddMonoid.IsTorsion M ↔ Module.IsTorsion ℤ M := by +@[deprecated (since := "2026-07-01")] alias AddMonoid.isTorsion_iff_isTorsion_nat := + isAddTorsion_iff_isTorsion_nat + +theorem isAddTorsion_iff_isTorsion_int [AddCommGroup M] : + IsAddTorsion M ↔ Module.IsTorsion ℤ M := by refine ⟨fun h x => ?_, fun h x => ?_⟩ · obtain ⟨n, h0, hn⟩ := (h x).exists_nsmul_eq_zero exact @@ -960,7 +961,8 @@ theorem isTorsion_iff_isTorsion_int [AddCommGroup M] : obtain ⟨n, hn⟩ := @h x exact ⟨_, Int.natAbs_pos.2 (nonZeroDivisors.coe_ne_zero n), natAbs_nsmul_eq_zero.2 hn⟩ -end AddMonoid +@[deprecated (since := "2026-07-01")] alias AddMonoid.isTorsion_iff_isTorsion_int := + isAddTorsion_iff_isTorsion_int namespace AddSubgroup diff --git a/Mathlib/GroupTheory/FiniteAbelian/Basic.lean b/Mathlib/GroupTheory/FiniteAbelian/Basic.lean index cdbd825b6e0b2b..6ae6c08bf50888 100644 --- a/Mathlib/GroupTheory/FiniteAbelian/Basic.lean +++ b/Mathlib/GroupTheory/FiniteAbelian/Basic.lean @@ -158,19 +158,24 @@ lemma equiv_directSum_zmod_of_finite' (G : Type*) [AddCommGroup G] [Finite G] : rintro ⟨i, hi⟩ exact one_lt_pow₀ (hp _).one_lt hi -theorem finite_of_fg_torsion [hG' : AddGroup.FG G] (hG : AddMonoid.IsTorsion G) : Finite G := +theorem finite_of_fg_isAddTorsion [hG' : AddGroup.FG G] (hG : IsAddTorsion G) : Finite G := @Module.finite_of_fg_torsion _ _ _ (Module.Finite.iff_addGroup_fg.mpr hG') <| - AddMonoid.isTorsion_iff_isTorsion_int.mp hG + isAddTorsion_iff_isTorsion_int.mp hG + +@[deprecated (since := "2026-07-01")] alias finite_of_fg_torsion := finite_of_fg_isAddTorsion end AddCommGroup namespace CommGroup -theorem finite_of_fg_torsion [CommGroup G] [Group.FG G] (hG : Monoid.IsTorsion G) : Finite G := - @Finite.of_equiv _ _ (AddCommGroup.finite_of_fg_torsion (Additive G) hG) Multiplicative.ofAdd +@[to_additive existing] +theorem finite_of_fg_isMulTorsion [CommGroup G] [Group.FG G] (hG : IsMulTorsion G) : Finite G := + @Finite.of_equiv _ _ (AddCommGroup.finite_of_fg_isAddTorsion (Additive G) hG) Multiplicative.ofAdd + +@[deprecated (since := "2026-07-01")] alias finite_of_fg_torsion := finite_of_fg_isMulTorsion /-- The **Structure Theorem For Finite Abelian Groups** in a multiplicative version: -A finite commutative group `G` is isomorphic to a finite product of finite cyclic groups. -/ +A finite abelian group `G` is isomorphic to a finite product of finite cyclic groups. -/ theorem equiv_prod_multiplicative_zmod_of_finite (G : Type*) [CommGroup G] [Finite G] : ∃ (ι : Type) (_ : Fintype ι) (n : ι → ℕ), (∀ (i : ι), 1 < n i) ∧ Nonempty (G ≃* ((i : ι) → Multiplicative (ZMod (n i)))) := by @@ -178,9 +183,9 @@ theorem equiv_prod_multiplicative_zmod_of_finite (G : Type*) [CommGroup G] [Fini exact ⟨ι, inst, n, h₁, ⟨MulEquiv.toAdditive.symm <| h₂.some.trans <| (DirectSum.addEquivProd _).trans (MulEquiv.piMultiplicative _).toAdditiveRight⟩⟩ -/-- The **Structure theorem of finitely generated abelian groups** in a multiplicative version : - Any finitely generated abelian group is the product of a power of `ℤ` - and a direct product of some `ZMod (p i ^ e i)` for some prime powers `p i ^ e i`. -/ +/-- The **Structure theorem of finitely generated abelian groups** in a multiplicative version: +Any finitely generated abelian group is the product of a power of `ℤ` +and a direct product of some `ZMod (p i ^ e i)` for some prime powers `p i ^ e i`. -/ theorem equiv_free_prod_prod_multiplicative_zmod (G : Type*) [CommGroup G] [hG : Group.FG G] : ∃ (ι j : Type) (_ : Fintype ι) (_ : Fintype j) (p : ι → ℕ) (_ : ∀ i, Nat.Prime <| p i) (e : ι → ℕ), @@ -199,8 +204,8 @@ namespace Subgroup lemma finiteIndex_range_powMonoidHom_of_fg (A : Type*) [CommGroup A] [Group.FG A] {n : ℕ} (hn : n ≠ 0) : (powMonoidHom (α := A) n).range.FiniteIndex := - finiteIndex_iff_finite_quotient.mpr <| CommGroup.finite_of_fg_torsion _ <| - CommGroup.isTorsion_quotient_range_powMonoidHom A hn + finiteIndex_iff_finite_quotient.mpr <| CommGroup.finite_of_fg_isMulTorsion _ <| + CommGroup.isMulTorsion_quotient_range_powMonoidHom A hn @[to_additive] lemma isFiniteRelIndex_map_powMonoidHom_of_fg {A : Type*} [CommGroup A] {B : Subgroup A} diff --git a/Mathlib/GroupTheory/Torsion.lean b/Mathlib/GroupTheory/Torsion.lean index e8bb7939eff18f..3965c8503da696 100644 --- a/Mathlib/GroupTheory/Torsion.lean +++ b/Mathlib/GroupTheory/Torsion.lean @@ -46,58 +46,73 @@ periodic group, aperiodic group, torsion subgroup, torsion abelian group variable {G H : Type*} -namespace Monoid +section variable (G) [Monoid G] /-- A predicate on a monoid saying that all elements are of finite order. -/ @[to_additive /-- A predicate on an additive monoid saying that all elements are of finite order. -/] -def IsTorsion := +def IsMulTorsion := ∀ g : G, IsOfFinOrder g +@[deprecated (since := "2026-07-01")] alias Monoid.IsTorsion := IsMulTorsion +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion := IsAddTorsion + /-- A monoid is not a torsion monoid if it has an element of infinite order. -/ @[to_additive (attr := simp) -/-- An additive monoid is not a torsion monoid if it has an element of infinite order. -/] -theorem not_isTorsion_iff : ¬IsTorsion G ↔ ∃ g : G, ¬IsOfFinOrder g := +/-- An additive monoid is not a torsion additive monoid if it has an element of infinite order. -/] +theorem not_isMulTorsion_iff : ¬IsMulTorsion G ↔ ∃ g : G, ¬IsOfFinOrder g := not_forall -end Monoid +@[deprecated (since := "2026-07-01")] alias Monoid.not_isTorsion_iff := not_isMulTorsion_iff +@[deprecated (since := "2026-07-01")] alias AddMonoid.not_isTorsion_iff := not_isAddTorsion_iff + +end open Monoid /-- Torsion monoids are really groups. -/ @[to_additive (attr := instance_reducible) -/-- Torsion additive monoids are really additive groups -/] -noncomputable def IsTorsion.group [Monoid G] (tG : IsTorsion G) : Group G := +/-- Torsion additive monoids are really additive groups. -/] +noncomputable def IsMulTorsion.group [Monoid G] (tG : IsMulTorsion G) : Group G := { ‹Monoid G› with inv g := g ^ (orderOf g - 1) inv_mul_cancel g := by rw [← pow_succ, tsub_add_cancel_of_le, pow_orderOf_eq_one] exact (tG g).orderOf_pos } +@[deprecated (since := "2026-07-01")] alias IsTorsion.group := IsMulTorsion.group +@[deprecated (since := "2026-07-01")] alias IsTorsion.addGroup := IsAddTorsion.addGroup + section Group variable [Group G] {N : Subgroup G} [Group H] /-- Subgroups of torsion groups are torsion groups. -/ -@[to_additive /-- Subgroups of additive torsion groups are additive torsion groups. -/] -theorem IsTorsion.subgroup (tG : IsTorsion G) (H : Subgroup G) : IsTorsion H := fun h ↦ +@[to_additive /-- Additive subgroups of torsion additive groups are torsion additive groups. -/] +theorem IsMulTorsion.subgroup (tG : IsMulTorsion G) (H : Subgroup G) : IsMulTorsion H := fun h ↦ Submonoid.isOfFinOrder_coe.1 <| tG h +@[deprecated (since := "2026-07-01")] alias IsTorsion.subgroup := IsMulTorsion.subgroup +@[deprecated (since := "2026-07-01")] alias IsTorsion.addSubgroup := IsAddTorsion.addSubgroup + /-- The image of a surjective torsion group homomorphism is torsion. -/ -@[to_additive AddIsTorsion.of_surjective -/-- The image of a surjective additive torsion group homomorphism is torsion. -/] -theorem IsTorsion.of_surjective {f : G →* H} (hf : Function.Surjective f) (tG : IsTorsion G) : - IsTorsion H := fun h ↦ by +@[to_additive +/-- The image of a surjective torsion additive group homomorphism is torsion. -/] +theorem IsMulTorsion.of_surjective {f : G →* H} (hf : Function.Surjective f) (tG : IsMulTorsion G) : + IsMulTorsion H := fun h ↦ by obtain ⟨g, rfl⟩ := hf h exact f.isOfFinOrder (tG g) +@[deprecated (since := "2026-06-30")] alias IsTorsion.of_surjective := IsMulTorsion.of_surjective +@[deprecated (since := "2026-06-30")] alias AddIsTorsion.of_surjective := IsAddTorsion.of_surjective + /-- Torsion groups are closed under extensions. -/ -@[to_additive AddIsTorsion.extension_closed -/-- Additive torsion groups are closed under extensions. -/] -theorem IsTorsion.extension_closed {f : G →* H} (hN : N = f.ker) (tH : IsTorsion H) - (tN : IsTorsion N) : IsTorsion G := fun g ↦ by +@[to_additive +/-- Torsion additive groups are closed under extensions. -/] +theorem IsMulTorsion.extension_closed {f : G →* H} (hN : N = f.ker) (tH : IsMulTorsion H) + (tN : IsMulTorsion N) : IsMulTorsion G := fun g ↦ by obtain ⟨ngn, ngnpos, hngn⟩ := (tH <| f g).exists_pow_eq_one have hmem := MonoidHom.mem_ker.mpr ((f.map_pow g ngn).trans hngn) lift g ^ ngn to N using hN.symm ▸ hmem with gn h @@ -105,32 +120,49 @@ theorem IsTorsion.extension_closed {f : G →* H} (hN : N = f.ker) (tH : IsTorsi exact isOfFinOrder_iff_pow_eq_one.mpr <| ⟨ngn * nn, mul_pos ngnpos nnpos, by rw [pow_mul, ← h, ← Subgroup.coe_pow, hnn, Subgroup.coe_one]⟩ +@[deprecated (since := "2026-06-30")] alias IsTorsion.extension_closed := + IsMulTorsion.extension_closed +@[deprecated (since := "2026-06-30")] alias AddIsTorsion.extension_closed := + IsAddTorsion.extension_closed + /-- The image of a quotient is torsion iff the group is torsion. -/ -@[to_additive AddIsTorsion.quotient_iff -/-- The image of a quotient is additively torsion iff the group is torsion. -/] -theorem IsTorsion.quotient_iff {f : G →* H} (hf : Function.Surjective f) (hN : N = f.ker) - (tN : IsTorsion N) : IsTorsion H ↔ IsTorsion G := - ⟨fun tH ↦ IsTorsion.extension_closed hN tH tN, fun tG ↦ IsTorsion.of_surjective hf tG⟩ +@[to_additive +/-- The image of a quotient is torsion iff the additive group is torsion. -/] +theorem IsMulTorsion.quotient_iff {f : G →* H} (hf : Function.Surjective f) (hN : N = f.ker) + (tN : IsMulTorsion N) : IsMulTorsion H ↔ IsMulTorsion G := + ⟨fun tH ↦ IsMulTorsion.extension_closed hN tH tN, fun tG ↦ IsMulTorsion.of_surjective hf tG⟩ + +@[deprecated (since := "2026-06-30")] alias IsTorsion.quotient_iff := IsMulTorsion.quotient_iff +@[deprecated (since := "2026-06-30")] alias AddIsTorsion.quotient_iff := IsAddTorsion.quotient_iff /-- If a group exponent exists, the group is torsion. -/ -@[to_additive ExponentExists.is_add_torsion -/-- If a group exponent exists, the group is additively torsion. -/] -theorem ExponentExists.isTorsion (h : ExponentExists G) : IsTorsion G := fun g ↦ by +@[to_additive +/-- If a group exponent exists, the additive group is torsion. -/] +theorem ExponentExists.isMulTorsion (h : ExponentExists G) : IsMulTorsion G := fun g ↦ by obtain ⟨n, npos, hn⟩ := h exact isOfFinOrder_iff_pow_eq_one.mpr ⟨n, npos, hn g⟩ +@[deprecated (since := "2026-06-30")] alias ExponentExists.isTorsion := ExponentExists.isMulTorsion +@[deprecated (since := "2026-06-30")] alias ExponentExists.is_add_torsion := + ExponentExists.isAddTorsion + /-- The group exponent exists for any bounded torsion group. -/ -@[to_additive IsAddTorsion.exponentExists -/-- The group exponent exists for any bounded additive torsion group. -/] -theorem IsTorsion.exponentExists (tG : IsTorsion G) +@[to_additive +/-- The group exponent exists for any bounded torsion additive group. -/] +theorem IsMulTorsion.exponentExists (tG : IsMulTorsion G) (bounded : (Set.range fun g : G ↦ orderOf g).Finite) : ExponentExists G := exponent_ne_zero.mp <| (exponent_ne_zero_iff_range_orderOf_finite fun g ↦ (tG g).orderOf_pos).mpr bounded +@[deprecated (since := "2026-07-01")] alias IsTorsion.exponentExists := IsMulTorsion.exponentExists + /-- Finite groups are torsion groups. -/ -@[to_additive is_add_torsion_of_finite /-- Finite additive groups are additive torsion groups. -/] -theorem isTorsion_of_finite [Finite G] : IsTorsion G := - ExponentExists.isTorsion .of_finite +@[to_additive /-- Finite additive groups are torsion additive groups. -/] +theorem isMulTorsion_of_finite [Finite G] : IsMulTorsion G := + ExponentExists.isMulTorsion .of_finite + +@[deprecated (since := "2026-06-30")] alias isTorsion_of_finite := isMulTorsion_of_finite +@[deprecated (since := "2026-06-30")] alias is_add_torsion_of_finite := isAddTorsion_of_finite end Group @@ -138,14 +170,25 @@ section CommGroup variable [CommGroup G] /-- A nontrivial torsion abelian group is not torsion-free. -/ -@[to_additive /-- A nontrivial additive torsion abelian group is not torsion-free. -/] -lemma not_isMulTorsionFree_of_isTorsion [Nontrivial G] (hG : IsTorsion G) : ¬ IsMulTorsionFree G := +@[to_additive /-- A nontrivial torsion additive abelian group is not torsion-free. -/] +lemma not_isMulTorsionFree_of_isMulTorsion [Nontrivial G] (hG : IsMulTorsion G) : + ¬ IsMulTorsionFree G := not_isMulTorsionFree_iff_isOfFinOrder.2 <| let ⟨x, hx⟩ := exists_ne (1 : G); ⟨x, hx, hG x⟩ +@[deprecated (since := "2026-07-01")] alias not_isMulTorsionFree_of_isTorsion := + not_isMulTorsionFree_of_isMulTorsion +@[deprecated (since := "2026-07-01")] alias not_isAddTorsionFree_of_isTorsion := + not_isAddTorsionFree_of_isAddTorsion + /-- A nontrivial torsion-free abelian group is not torsion. -/ -@[to_additive /-- A nontrivial additive torsion-free abelian group is not torsion. -/] -lemma not_isTorsion_of_isMulTorsionFree [Nontrivial G] [IsMulTorsionFree G] : ¬ IsTorsion G := - (not_isMulTorsionFree_of_isTorsion · ‹_›) +@[to_additive /-- A nontrivial torsion-free additive abelian group is not torsion. -/] +lemma not_isMulTorsion_of_isMulTorsionFree [Nontrivial G] [IsMulTorsionFree G] : ¬ IsMulTorsion G := + (not_isMulTorsionFree_of_isMulTorsion · ‹_›) + +@[deprecated (since := "2026-07-01")] alias not_isTorsion_of_isMulTorsionFree := + not_isMulTorsion_of_isMulTorsionFree +@[deprecated (since := "2026-07-01")] alias not_isTorsion_of_isAddTorsionFree := + not_isAddTorsion_of_isAddTorsionFree end CommGroup @@ -154,19 +197,22 @@ section Module -- A (semi/)ring of scalars and a commutative monoid of elements variable (R M : Type*) [AddCommMonoid M] -namespace AddMonoid - -/-- A module whose scalars are additively torsion is additively torsion. -/ -theorem IsTorsion.module_of_torsion [Semiring R] [Module R M] (tR : IsTorsion R) : IsTorsion M := +/-- A module whose scalars are torsion is torsion. -/ +theorem IsAddTorsion.module_of_torsion [Semiring R] [Module R M] (tR : IsAddTorsion R) : + IsAddTorsion M := fun f ↦ isOfFinAddOrder_iff_nsmul_eq_zero.mpr <| by obtain ⟨n, npos, hn⟩ := (tR 1).exists_nsmul_eq_zero exact ⟨n, npos, by simp only [← Nat.cast_smul_eq_nsmul R _ f, ← nsmul_one, hn, zero_smul]⟩ -/-- A module with a finite ring of scalars is additively torsion. -/ -theorem IsTorsion.module_of_finite [Ring R] [Finite R] [Module R M] : IsTorsion M := - (is_add_torsion_of_finite : IsTorsion R).module_of_torsion _ _ +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion.module_of_torsion := + IsAddTorsion.module_of_torsion + +/-- A module with a finite ring of scalars is torsion. -/ +theorem IsAddTorsion.module_of_finite [Ring R] [Finite R] [Module R M] : IsAddTorsion M := + (isAddTorsion_of_finite : IsAddTorsion R).module_of_torsion _ _ -end AddMonoid +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion.module_of_finite := + IsAddTorsion.module_of_finite end Module @@ -178,9 +224,9 @@ namespace CommMonoid /-- The torsion submonoid of a commutative monoid. -(Note that by `Monoid.IsTorsion.group` torsion monoids are truthfully groups.) +(Note that by `IsMulTorsion.group` torsion monoids are truthfully groups.) -/ -@[to_additive addTorsion /-- The torsion submonoid of an additive commutative monoid. -/] +@[to_additive addTorsion /-- The torsion additive submonoid of an additive commutative monoid. -/] def torsion : Submonoid G where carrier := { x | IsOfFinOrder x } one_mem' := IsOfFinOrder.one @@ -197,8 +243,8 @@ variable {G} set_option backward.isDefEq.respectTransparency false in /-- Torsion submonoids are torsion. -/ -@[to_additive /-- Additive torsion submonoids are additively torsion. -/] -theorem torsion.isTorsion : IsTorsion <| torsion G := fun ⟨x, n, npos, hn⟩ ↦ +@[to_additive /-- Torsion additive submonoids are torsion. -/] +theorem torsion.isMulTorsion : IsMulTorsion <| torsion G := fun ⟨x, n, npos, hn⟩ ↦ ⟨n, npos, Subtype.ext <| by dsimp @@ -207,6 +253,10 @@ theorem torsion.isTorsion : IsTorsion <| torsion G := fun ⟨x, n, npos, hn⟩ rw [_root_.mul_one, SubmonoidClass.coe_pow, Subtype.coe_mk, (isPeriodicPt_mul_iff_pow_eq_one _).mp hn]⟩ +@[deprecated (since := "2026-07-01")] alias torsion.isTorsion := torsion.isMulTorsion +@[deprecated (since := "2026-07-01")] alias _root_.AddCommMonoid.addTorsion.isTorsion := + AddCommMonoid.addTorsion.isAddTorsion + variable (G) (p : ℕ) /-- The `p`-primary component is the submonoid of elements `g` such that `g ^ p ^ k = 1` @@ -262,38 +312,51 @@ end CommMonoid open CommMonoid (torsion) -namespace Monoid.IsTorsion +namespace IsMulTorsion variable {G} /-- The torsion submonoid of a torsion monoid is `⊤`. -/ @[to_additive (attr := simp) -/-- The additive torsion submonoid of an additive torsion monoid is `⊤`. -/] -theorem torsion_eq_top (tG : IsTorsion G) : torsion G = ⊤ := by ext; tauto +/-- The torsion additive submonoid of a torsion additive monoid is `⊤`. -/] +theorem torsion_eq_top (tG : IsMulTorsion G) : torsion G = ⊤ := by ext; tauto /-- A torsion monoid is isomorphic to its torsion submonoid. -/ -@[to_additive /-- An additive torsion monoid is isomorphic to its torsion submonoid. -/] -def torsionMulEquiv (tG : IsTorsion G) : torsion G ≃* G := +@[to_additive (attr := simps!) +/-- A torsion additive monoid is isomorphic to its torsion additive submonoid. -/] +def torsionMulEquiv (tG : IsMulTorsion G) : torsion G ≃* G := (MulEquiv.submonoidCongr tG.torsion_eq_top).trans Submonoid.topEquiv -@[to_additive] -theorem torsionMulEquiv_apply (tG : IsTorsion G) (a : torsion G) : - tG.torsionMulEquiv a = MulEquiv.submonoidCongr tG.torsion_eq_top a := - rfl +end IsMulTorsion -@[to_additive] -theorem torsionMulEquiv_symm_apply_coe (tG : IsTorsion G) (a : G) : - tG.torsionMulEquiv.symm a = ⟨Submonoid.topEquiv.symm a, tG _⟩ := - rfl +@[deprecated (since := "2026-07-01")] alias Monoid.IsTorsion.torsion_eq_top := + IsMulTorsion.torsion_eq_top +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion.torsion_eq_top := + IsAddTorsion.torsion_eq_top + +@[deprecated (since := "2026-07-01")] alias Monoid.IsTorsion.torsionMulEquiv := + IsMulTorsion.torsionMulEquiv +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion.torsionAddEquiv := + IsAddTorsion.torsionAddEquiv -end Monoid.IsTorsion +@[deprecated (since := "2026-07-01")] alias Monoid.IsTorsion.torsionMulEquiv_apply := + IsMulTorsion.torsionMulEquiv_apply +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion.torsionAddEquiv_apply := + IsAddTorsion.torsionAddEquiv_apply + +@[deprecated (since := "2026-07-01")] alias Monoid.IsTorsion.torsionMulEquiv_symm_apply_coe := + IsMulTorsion.torsionMulEquiv_symm_apply_coe +@[deprecated (since := "2026-07-01")] alias AddMonoid.IsTorsion.torsionAddEquiv_symm_apply_coe := + IsAddTorsion.torsionAddEquiv_symm_apply_coe /-- Torsion submonoids of a torsion submonoid are isomorphic to the submonoid. -/ -@[to_additive (attr := simp) AddCommMonoid.Torsion.ofTorsion -/-- Additive torsion submonoids of an additive torsion submonoid are -isomorphic to the submonoid. -/] -def Torsion.ofTorsion : torsion (torsion G) ≃* torsion G := - Monoid.IsTorsion.torsionMulEquiv CommMonoid.torsion.isTorsion +@[to_additive (attr := simp) +/-- Torsion additive submonoids of a torsion additive submonoid are +isomorphic to the additive submonoid. -/] +def CommMonoid.Torsion.ofTorsion : torsion (torsion G) ≃* torsion G := + IsMulTorsion.torsionMulEquiv CommMonoid.torsion.isMulTorsion + +@[deprecated (since := "2026-07-01")] alias Torsion.ofTorsion := CommMonoid.Torsion.ofTorsion end CommMonoid @@ -304,24 +367,28 @@ variable (G) [CommGroup G] [CommGroup H] namespace CommGroup /-- The torsion subgroup of an abelian group. -/ -@[to_additive /-- The torsion subgroup of an additive abelian group. -/] +@[to_additive /-- The torsion additive subgroup of an additive abelian group. -/] def torsion : Subgroup G := { CommMonoid.torsion G with inv_mem' := fun hx ↦ IsOfFinOrder.inv hx } /-- The torsion submonoid of an abelian group equals the torsion subgroup as a submonoid. -/ -@[to_additive add_torsion_eq_add_torsion_submonoid -/-- The additive torsion submonoid of an abelian group equals the torsion -subgroup as a submonoid. -/] +@[to_additive +/-- The torsion additive submonoid of an abelian group equals the torsion +additive subgroup as an additive submonoid. -/] theorem torsion_eq_torsion_submonoid : CommMonoid.torsion G = (torsion G).toSubmonoid := rfl +@[deprecated (since := "2026-07-01")] alias + _root_.AddCommGroup.add_torsion_eq_add_torsion_submonoid := + AddCommGroup.torsion_eq_torsion_addSubmonoid + variable {G} @[to_additive] theorem mem_torsion (g : G) : g ∈ torsion G ↔ IsOfFinOrder g := Iff.rfl @[to_additive] -lemma torsion_eq_top_iff : torsion G = ⊤ ↔ IsTorsion G := +lemma torsion_eq_top_iff : torsion G = ⊤ ↔ IsMulTorsion G := (torsion G).eq_top_iff' @[to_additive] @@ -359,13 +426,19 @@ lemma torsion_prod : torsion (G × H) = (torsion G).prod (torsion H) := by variable (G) @[to_additive] -lemma isTorsion_quotient_range_powMonoidHom {n : ℕ} (hn : n ≠ 0) : - Monoid.IsTorsion (G ⧸ (powMonoidHom (α := G) n).range) := by - simp only [Monoid.IsTorsion, isOfFinOrder_iff_pow_eq_one] +lemma isMulTorsion_quotient_range_powMonoidHom {n : ℕ} (hn : n ≠ 0) : + IsMulTorsion (G ⧸ (powMonoidHom (α := G) n).range) := by + simp only [IsMulTorsion, isOfFinOrder_iff_pow_eq_one] refine fun g ↦ QuotientGroup.induction_on g fun a ↦ ⟨n, hn.pos, ?_⟩ rw [← QuotientGroup.mk_pow, QuotientGroup.eq_one_iff] simp +@[deprecated (since := "2026-07-01")] alias isTorsion_quotient_range_powMonoidHom := + isMulTorsion_quotient_range_powMonoidHom +@[deprecated (since := "2026-07-01")] alias + _root_.AddCommGroup.isTorsion_quotient_range_nsmulAddMonoidHom := + AddCommGroup.isAddTorsion_quotient_range_nsmulAddMonoidHom + variable (p : ℕ) /-- The `p`-primary component is the subgroup of elements `g` such that `g ^ p ^ k = 1` @@ -411,16 +484,16 @@ theorem freeRank_def [Group.FG G] : freeRank G = Group.rank (G ⧸ torsion G) := variable {G H} @[to_additive] -theorem freeRank_eq_zero_iff [Group.FG G] : freeRank G = 0 ↔ IsTorsion G := by +theorem freeRank_eq_zero_iff [Group.FG G] : freeRank G = 0 ↔ IsMulTorsion G := by rw [freeRank, Group.rank_eq_zero_iff, QuotientGroup.subsingleton_iff, torsion_eq_top_iff] @[to_additive] -theorem freeRank_eq_zero (hG : IsTorsion G) [Group.FG G] : freeRank G = 0 := +theorem freeRank_eq_zero (hG : IsMulTorsion G) [Group.FG G] : freeRank G = 0 := freeRank_eq_zero_iff.mpr hG @[to_additive] theorem freeRank_eq_zero_of_finite [Finite G] : freeRank G = 0 := - freeRank_eq_zero isTorsion_of_finite + freeRank_eq_zero isMulTorsion_of_finite @[to_additive] theorem freeRank_congr [Group.FG G] [Group.FG H] (e : G ≃* H) : freeRank G = freeRank H := @@ -440,7 +513,8 @@ open CommGroup (torsion) /-- Quotienting a group by its torsion subgroup yields a torsion-free group. -/ @[to_additive -/-- Quotienting a group by its additive torsion subgroup yields an additive torsion-free group. -/] +/-- Quotienting an additive group by its torsion additive subgroup yields a torsion-free additive +group. -/] instance _root_.QuotientGroup.instIsMulTorsionFree : IsMulTorsionFree <| G ⧸ torsion G := by refine .of_not_isOfFinOrder fun g hne hfin ↦ hne ?_ obtain ⟨g⟩ := g From f61feab96298c65b11632a917d19ca10d5048ca0 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Fri, 24 Jul 2026 19:10:04 +0000 Subject: [PATCH 1000/1300] chore: no newline between public imports (#42064) Similar (motivation) to #42063. This PR removes all newlines between public imports. This is not important as standalone PR, but makes diffs of later PRs nicer and thus help reviewing. This includes space between ordinary public and `public meta` imports (and imports from Lean core). Maybe there should be a convention on there to be a newline for those cases, but this is not currently done in the vast majority of cases and not the scope of this PR. Also some import orders of affected files are not ordered alphabetically still, which I did not fix as this is again not the goal of this PR. Co-authored-by: Batixx --- Mathlib/Algebra/Group/End.lean | 1 - Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean | 1 - Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean | 1 - Mathlib/Logic/Basic.lean | 1 - Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean | 1 - Mathlib/RingTheory/SimpleModule/Basic.lean | 1 - Mathlib/RingTheory/Valuation/Extension.lean | 1 - Mathlib/Tactic/Common.lean | 1 - Mathlib/Topology/Algebra/Valued/ValuationTopology.lean | 1 - 9 files changed, 9 deletions(-) diff --git a/Mathlib/Algebra/Group/End.lean b/Mathlib/Algebra/Group/End.lean index d097f727d007bf..f2ad7a65fbacbf 100644 --- a/Mathlib/Algebra/Group/End.lean +++ b/Mathlib/Algebra/Group/End.lean @@ -11,7 +11,6 @@ public import Mathlib.Algebra.Group.Prod public import Mathlib.Algebra.Group.Units.Equiv public import Mathlib.Data.Set.Basic public import Mathlib.Tactic.Common - public import Mathlib.Tactic.Attr.Register /-! diff --git a/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean b/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean index 080431e447073f..0bbd1ed50c603b 100644 --- a/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean +++ b/Mathlib/AlgebraicGeometry/Sites/EtalePoint.lean @@ -10,7 +10,6 @@ public import Mathlib.AlgebraicGeometry.Sites.AffineEtale public import Mathlib.CategoryTheory.Functor.TypeValuedFlat public import Mathlib.CategoryTheory.Limits.Elements public import Mathlib.CategoryTheory.Sites.Point.Conservative - public import Mathlib.FieldTheory.SeparableClosure /-! diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index 8aa500bba2a819..199ab8efa6025d 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -7,7 +7,6 @@ module public import Mathlib.LinearAlgebra.AffineSpace.AffineEquiv public import Mathlib.LinearAlgebra.AffineSpace.AffineSubspace.Defs - public import Mathlib.Algebra.NoZeroSMulDivisors.Basic /-! diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index ebcd43198e0ad1..ddf2c7599e4a50 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -8,7 +8,6 @@ module public import Mathlib.Lean.Meta.Simp public import Batteries.Logic public import Batteries.Util.LibraryNote - public import Mathlib.Tactic.Attr.Register /-! diff --git a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean index 37d55774ebae66..4621f8f399acff 100644 --- a/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean +++ b/Mathlib/RingTheory/MvPowerSeries/GaussNorm.lean @@ -7,7 +7,6 @@ module public import Mathlib.Analysis.Normed.Ring.Basic public import Mathlib.RingTheory.MvPowerSeries.Basic - public import Mathlib.Algebra.Order.Ring.IsNonarchimedean /-! diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index d959b463994b1b..9d011b5a840eda 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -16,7 +16,6 @@ public import Mathlib.Order.JordanHolder public import Mathlib.RingTheory.Ideal.Colon public import Mathlib.RingTheory.Noetherian.Defs public import Mathlib.SetTheory.Cardinal.NatCard - public import Mathlib.Algebra.NoZeroSMulDivisors.Basic /-! diff --git a/Mathlib/RingTheory/Valuation/Extension.lean b/Mathlib/RingTheory/Valuation/Extension.lean index 2cd3a3fc4c5405..71f15d7604fca8 100644 --- a/Mathlib/RingTheory/Valuation/Extension.lean +++ b/Mathlib/RingTheory/Valuation/Extension.lean @@ -6,7 +6,6 @@ Authors: Jiedong Jiang, Bichang Lei, María Inés de Frutos-Fernández, Filippo module public import Mathlib.RingTheory.Valuation.ValuationSubring - public import Mathlib.Algebra.NoZeroSMulDivisors.Basic /-! diff --git a/Mathlib/Tactic/Common.lean b/Mathlib/Tactic/Common.lean index 01fa2cdc218664..77101da34d58a4 100644 --- a/Mathlib/Tactic/Common.lean +++ b/Mathlib/Tactic/Common.lean @@ -122,7 +122,6 @@ public import Mathlib.Util.CountHeartbeats public import Mathlib.Util.PrintSorries public import Mathlib.Util.TransImports public import Mathlib.Util.WhatsNew - public import Lean.Elab.Tactic.Try /-! diff --git a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean index 2eeaf86c8b915a..8cce79014c391e 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean @@ -9,7 +9,6 @@ public import Mathlib.Algebra.Order.Group.Units public import Mathlib.Topology.Algebra.Nonarchimedean.Bases public import Mathlib.Topology.Algebra.UniformFilterBasis public import Mathlib.RingTheory.Valuation.ValuationSubring - public import Mathlib.Algebra.Order.GroupWithZero.Range /-! From e90415aad1a8e8c66b0791d5d2ba5b881911fa68 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:04:34 +0000 Subject: [PATCH 1001/1300] feat(Data/Finset/Prod): count the number of ordered pairs in a set (#39558) Co-authored-by: Jon Eugster --- Mathlib/Data/Finset/Prod.lean | 11 +++++++++++ Mathlib/Data/Fintype/Prod.lean | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/Mathlib/Data/Finset/Prod.lean b/Mathlib/Data/Finset/Prod.lean index 26c600c391eadd..d74db48d69e592 100644 --- a/Mathlib/Data/Finset/Prod.lean +++ b/Mathlib/Data/Finset/Prod.lean @@ -8,6 +8,7 @@ module public import Mathlib.Data.Finset.Card public import Mathlib.Data.Finset.Union public import Mathlib.Data.List.OffDiag +public import Mathlib.Data.Nat.Choose.Basic /-! # Finsets in product types @@ -366,6 +367,16 @@ theorem offDiag_filter_lt_eq_filter_le {ι} [PartialOrder ι] [DecidableLE ι] [ ext simpa using fun _ _ a ↦ (Ne.le_iff_lt a).symm +/-- The number of strictly ordered pairs `(a, b)` with `a, b ∈ s` is `(#s).choose 2`. -/ +lemma card_product_filter_lt [LinearOrder α] : + #{x ∈ s ×ˢ s | x.1 < x.2} = (#s).choose 2 := by + set u : Finset (α × α) := {x ∈ s ×ˢ s | x.1 < x.2} + set v : Finset (α × α) := {x ∈ s ×ˢ s | x.2 < x.1} + have disj : Disjoint u v := by grind [disjoint_left] + have union : u.disjUnion v disj = s.offDiag := by grind + have swap : #u = #v := Finset.card_equiv (Equiv.prodComm α α) (by grind) + grind [Nat.mul_sub_one, offDiag_card, Nat.choose_two_right] + end Diag end Finset diff --git a/Mathlib/Data/Fintype/Prod.lean b/Mathlib/Data/Fintype/Prod.lean index 3af498bdeb3901..d385ab7979e860 100644 --- a/Mathlib/Data/Fintype/Prod.lean +++ b/Mathlib/Data/Fintype/Prod.lean @@ -60,6 +60,11 @@ theorem Fintype.card_prod (α β : Type*) [Fintype α] [Fintype β] : Fintype.card (α × β) = Fintype.card α * Fintype.card β := card_product _ _ +/-- The number of strictly ordered pairs `(a, b)` in `α` is `(Fintype.card α).choose 2`. -/ +lemma Fintype.card_product_filter_lt [Fintype α] [LinearOrder α] : + #{x : α × α | x.1 < x.2} = (Fintype.card α).choose 2 := by + simpa using Finset.card_product_filter_lt (s := univ) + section attribute [local instance] Fintype.ofFinite in From 5ef92af16e7e6bf9d2f50751f06de253bd132fdf Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Fri, 24 Jul 2026 21:04:26 +0000 Subject: [PATCH 1002/1300] chore(*): fix flexible linter exceptions (#41706) --- Mathlib/Algebra/Ring/BooleanRing.lean | 4 +--- .../EllipticCurve/Affine/Formula.lean | 6 ------ .../EllipticCurve/Jacobian/Formula.lean | 2 -- .../EllipticCurve/Projective/Formula.lean | 2 -- .../ContinuousFunctionalCalculus/PosPart/Basic.lean | 3 +-- .../SpecialFunctions/Integrability/Basic.lean | 4 +--- Mathlib/Combinatorics/SetFamily/FourFunctions.lean | 8 +++++--- .../Combinatorics/SimpleGraph/Regularity/Chunk.lean | 4 +--- Mathlib/Computability/TuringMachine/Config.lean | 8 +++----- Mathlib/Control/EquivFunctor/Instances.lean | 12 +----------- Mathlib/Geometry/Euclidean/Triangle.lean | 4 +--- Mathlib/InformationTheory/Coding/KraftMcMillan.lean | 5 +---- Mathlib/NumberTheory/LucasLehmer.lean | 5 +---- Mathlib/NumberTheory/PythagoreanTriples.lean | 6 +----- Mathlib/RingTheory/Nilpotent/Exp.lean | 4 ++-- 15 files changed, 19 insertions(+), 58 deletions(-) diff --git a/Mathlib/Algebra/Ring/BooleanRing.lean b/Mathlib/Algebra/Ring/BooleanRing.lean index 9f3f9f7c541b93..b4089404607b06 100644 --- a/Mathlib/Algebra/Ring/BooleanRing.lean +++ b/Mathlib/Algebra/Ring/BooleanRing.lean @@ -205,7 +205,6 @@ theorem le_sup_inf (a b c : α) : (a ⊔ b) ⊓ (a ⊔ c) ⊔ (a ⊔ b ⊓ c) = dsimp only [(· ⊔ ·), (· ⊓ ·)] rw [le_sup_inf_aux, add_self, mul_self, zero_add] -set_option linter.flexible false in -- TODO: fix non-terminal simp /-- The Boolean algebra structure on a Boolean ring. The data is defined so that: @@ -233,8 +232,7 @@ def toBooleanAlgebra : BooleanAlgebra α := change 1 + (a + (1 + a) + a * (1 + a)) + 1 * (a + (1 + a) + a * (1 + a)) = a + (1 + a) + a * (1 + a) - simp [mul_add, mul_self, add_self] - rw [← add_assoc, add_self] } + simp [mul_add, mul_self, add_self, ← add_assoc 1 a] } scoped[BooleanAlgebraOfBooleanRing] attribute [instance 100] BooleanRing.toBooleanAlgebra diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean index a65a2ff44f8272..b5bc73430cc2fc 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean @@ -266,8 +266,6 @@ section slope variable [DecidableEq F] --- Non-terminal simps, used to be field_simp -set_option linter.flexible false in lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂) (hxy : ¬(x₁ = x₂ ∧ y₁ = W.negY x₂ y₂)) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) = -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by @@ -359,8 +357,6 @@ lemma nonsingular_add {x₁ x₂ y₁ y₂ : F} (h₁ : W.Nonsingular x₁ y₁) W.Nonsingular (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) (W.addY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) := (nonsingular_neg ..).mpr <| nonsingular_negAdd h₁ h₂ hxy --- Non-terminal simp, used to be field_simp -set_option linter.flexible false in /-- The formula `x(P₁ + P₂) = x(P₁ - P₂) - ψ(P₁)ψ(P₂) / (x(P₂) - x(P₁))²`, where `ψ(x,y) = 2y + a₁x + a₃`. -/ lemma addX_eq_addX_negY_sub {x₁ x₂ : F} (y₁ y₂ : F) (hx : x₁ ≠ x₂) : @@ -370,8 +366,6 @@ lemma addX_eq_addX_negY_sub {x₁ x₂ : F} (y₁ y₂ : F) (hx : x₁ ≠ x₂) simp [field] ring1 --- Non-terminal simp, used to be field_simp -set_option linter.flexible false in /-- The formula `y(P₁)(x(P₂) - x(P₃)) + y(P₂)(x(P₃) - x(P₁)) + y(P₃)(x(P₁) - x(P₂)) = 0`, assuming that `P₁ + P₂ + P₃ = O`. -/ lemma cyclic_sum_Y_mul_X_sub_X {x₁ x₂ : F} (y₁ y₂ : F) (hx : x₁ ≠ x₂) : diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Formula.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Formula.lean index e7775b6530031e..ee1f7fef794efa 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Formula.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Formula.lean @@ -261,8 +261,6 @@ lemma dblX_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0) rw [dblX, Y_eq_negY_of_Y_eq hQz hx hy hy'] ring1 --- Non-terminal simp, used to be field_simp -set_option linter.flexible false in private lemma toAffine_addX_of_eq {P : Fin 3 → F} (hPz : P z ≠ 0) {n d : F} (hd : d ≠ 0) : W.toAffine.addX (P x / P z ^ 2) (P x / P z ^ 2) (-n / (P z * d)) = (n ^ 2 - W.a₁ * n * P z * d - W.a₂ * P z ^ 2 * d ^ 2 - 2 * P x * d ^ 2) / (P z * d) ^ 2 := by diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Formula.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Formula.lean index e2490e681b416d..703a6039c43ede 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Formula.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Formula.lean @@ -292,8 +292,6 @@ lemma dblX_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hP : W'.Equation P) ( rw [dblX_eq' hP, Y_eq_negY_of_Y_eq hQz hx hy hy'] ring1 --- Non-terminal simp, used to be field_simp -set_option linter.flexible false in private lemma toAffine_addX_of_eq {P : Fin 3 → F} (hPz : P z ≠ 0) {n d : F} (hd : d ≠ 0) : W.toAffine.addX (P x / P z) (P x / P z) (-n / P z / d) = (n ^ 2 - W.a₁ * n * P z * d - W.a₂ * P z ^ 2 * d ^ 2 - 2 * P x * P z * d ^ 2) * d / P z diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean index 2af2e998881d35..c3b553a997ded6 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/PosPart/Basic.lean @@ -211,7 +211,6 @@ open ContinuousMapZero variable [IsSemitopologicalRing A] [T2Space A] set_option backward.isDefEq.respectTransparency false in -set_option linter.flexible false in -- simp followed by `exact le_rfl` open NonUnitalContinuousFunctionalCalculus in /-- The positive and negative parts of a selfadjoint element `a` are unique. That is, if `a = b - c` is the difference of nonnegative elements whose product is zero, then these are @@ -276,7 +275,7 @@ lemma posPart_negPart_unique {a b c : A} (habc : a = b - c) (hbc : b * c = 0) `b = cfcₙ id b + cfcₙ 0 (-c) = cfcₙ (·⁺) b - cfcₙ (·⁺) (-c) = cfcₙ (·⁺) a = a⁺`, where the second equality follows because these functions are equal on the spectra of `b` and `-c`, respectively, since `0 ≤ b` and `-c ≤ 0`. -/ - let f : C(s, ℝ)₀ := ⟨⟨(·⁺), by fun_prop⟩, by simp; exact le_rfl⟩ + let f : C(s, ℝ)₀ := ⟨⟨(·⁺), by fun_prop⟩, by simp; norm_cast⟩ replace key := congr($key f) simp only [cfcₙHomSuperset_apply, NonUnitalStarAlgHom.coe_mk', NonUnitalAlgHom.coe_mk, ψ, Pi.add_apply, cfcₙHom_eq_cfcₙ_extend (·⁺)] at key diff --git a/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean index e77c76e334d3e1..ffc419956683f8 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrability/Basic.lean @@ -223,7 +223,6 @@ hypothesis on the interval, but assuming the measure is the volume. theorem intervalIntegrable_log (h : (0 : ℝ) ∉ [[a, b]]) : IntervalIntegrable log μ a b := IntervalIntegrable.log continuousOn_id fun _ hx => ne_of_mem_of_not_mem hx h -set_option linter.flexible false in -- TODO: fix non-terminal simp /-- The real logarithm is interval integrable (with respect to the volume measure) on every interval. See `intervalIntegrable_log` for a version applying to any locally finite measure, but with an @@ -245,8 +244,7 @@ theorem intervalIntegrable_log' : IntervalIntegrable log volume a b := by norm_num at * simpa using! (hasDerivAt_id s).sub (hasDerivAt_mul_log hs.ne.symm) · intro s ⟨hs₁, hs₂⟩ - simp at * - exact (log_nonpos_iff hs₁.le).mpr hs₂.le + grind [Pi.neg_apply, log_nonpos_iff] · -- Show integrability on [1…t] by continuity apply ContinuousOn.intervalIntegrable apply Real.continuousOn_log.mono diff --git a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean index 210d4d8c7d6d7e..b966aa3b362589 100644 --- a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean +++ b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean @@ -261,8 +261,6 @@ lemma sum_collapse (h𝒜 : 𝒜 ⊆ (insert a u).powerset) (hu : a ∉ u) : variable [ExistsAddOfLE β] --- In the non-terminal simp below, simp runs on four goals, but only needs `exact` once. -set_option linter.flexible false in /-- The **Four Functions Theorem** on a powerset algebra. See `four_functions_theorem` for the finite distributive lattice generalisation. -/ protected lemma Finset.four_functions_theorem (u : Finset α) @@ -273,7 +271,11 @@ protected lemma Finset.four_functions_theorem (u : Finset α) induction u using Finset.induction generalizing f₁ f₂ f₃ f₄ 𝒜 ℬ with | empty => simp only [Finset.powerset_empty, Finset.subset_singleton_iff] at h𝒜 hℬ - obtain rfl | rfl := h𝒜 <;> obtain rfl | rfl := hℬ <;> simp; exact h (subset_refl ∅) subset_rfl + obtain rfl | rfl := h𝒜 + · simp + obtain rfl | rfl := hℬ + · simp + simpa using h (subset_refl ∅) subset_rfl | insert a u hu ih => specialize ih (collapse_nonneg h₁) (collapse_nonneg h₂) (collapse_nonneg h₃) (collapse_nonneg h₄) (collapse_modular hu h₁ h₂ h₃ h₄ h 𝒜 ℬ) Subset.rfl Subset.rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Chunk.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Chunk.lean index a5757901105fa7..ec1a2b83b6d0f0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Chunk.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Chunk.lean @@ -449,7 +449,6 @@ private theorem edgeDensity_star_not_uniform [Nonempty α] simpa using pow_le_pow_of_le_one (by sz_positivity) hε₁ (show 1 ≤ 5 by simp) grind -set_option linter.flexible false in -- TODO: fix non-terminal simp /-- Lower bound on the edge densities between non-uniform parts of `SzemerediRegularity.increment`. -/ theorem edgeDensity_chunk_not_uniform [Nonempty α] (hPα : #P.parts * 16 ^ #P.parts ≤ card α) @@ -478,8 +477,7 @@ theorem edgeDensity_chunk_not_uniform [Nonempty α] (hPα : #P.parts * 16 ^ #P.p refine le_trans ?_ (mul_le_mul_of_nonneg_right UVl ?_) · norm_num nlinarith - · simp - positivity + · simp [pow_two_nonneg] _ ≤ (∑ ab ∈ (chunk hP G ε hU).parts.product (chunk hP G ε hV).parts, (G.edgeDensity ab.1 ab.2 : ℝ) ^ 2) / ↑16 ^ #P.parts := by have t : (star hP G ε hU V).product (star hP G ε hV U) ⊆ diff --git a/Mathlib/Computability/TuringMachine/Config.lean b/Mathlib/Computability/TuringMachine/Config.lean index dd621371498bdf..96491b4d837f85 100644 --- a/Mathlib/Computability/TuringMachine/Config.lean +++ b/Mathlib/Computability/TuringMachine/Config.lean @@ -269,8 +269,6 @@ theorem exists_code.comp {m n} {f : List.Vector ℕ n →. ℕ} {g : Fin n → L rfl⟩ set_option backward.isDefEq.respectTransparency false in --- TODO: fix non-terminal simp (operates on two goals, with long simp sets) -set_option linter.flexible false in theorem exists_code {n} {f : List.Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) : ∃ c : Code, ∀ v : List.Vector ℕ n, c.eval v.1 = pure <$> f v := by induction hf with @@ -294,11 +292,10 @@ theorem exists_code {n} {f : List.Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) : specialize hf v.tail replace hg := fun a b => hg (a ::ᵥ b ::ᵥ v.tail) simp only [Vector.cons_val, Vector.tail_val] at hf hg - simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, Vector.tail_cons, - Vector.head_cons, PFun.coe_val, Vector.tail_val] + simp only [Part.map_eq_map, Part.map_some, Vector.cons_val, PFun.coe_val, Vector.tail_val] simp only [← Part.pure_eq_some] at hf hg ⊢ induction v.head with - simp [prec, hf, Part.bind_assoc, ← Part.bind_some_eq_map, Part.bind_some, Bind.bind] + | zero => simp [prec, hf, Bind.bind] | succ n _ => suffices ∀ a b, a + b = n → (n.succ :: 0 :: @@ -313,6 +310,7 @@ theorem exists_code {n} {f : List.Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) : (v.headI.succ :: v.tail.headI.pred :: x.headI :: v.tail.tail.tail)))) (a :: b :: Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) a :: v.val.tail) by have := Part.eq_some_iff.mpr (this _ _ (zero_add _)) + simp [prec, Part.bind_assoc, Bind.bind] simp_all intro a b e induction b generalizing a with diff --git a/Mathlib/Control/EquivFunctor/Instances.lean b/Mathlib/Control/EquivFunctor/Instances.lean index 9ea26164668e85..ad99a872ce4fa1 100644 --- a/Mathlib/Control/EquivFunctor/Instances.lean +++ b/Mathlib/Control/EquivFunctor/Instances.lean @@ -29,22 +29,12 @@ instance EquivFunctorPerm : EquivFunctor Perm where map_refl' α := by ext; simp map_trans' _ _ := by ext; simp --- TODO: find a good way to fix the linter --- squeezing the simp makes the second subgoal fail -set_option linter.flexible false in -- There is a classical instance of `LawfulFunctor Finset` available, -- but we provide this computable alternative separately. instance EquivFunctorFinset : EquivFunctor Finset where map e s := s.map e.toEmbedding map_refl' α := by ext; simp - map_trans' k h := by - ext _ a - simp - constructor <;> intro h' - · let ⟨a, ha₁, ha₂⟩ := h' - rw [← ha₂]; simpa - · exists (Equiv.symm k) ((Equiv.symm h) a) - simp [h'] + map_trans' k h := by ext; simp [-trans_toEmbedding] instance EquivFunctorFintype : EquivFunctor Fintype where map e _ := Fintype.ofBijective e e.bijective diff --git a/Mathlib/Geometry/Euclidean/Triangle.lean b/Mathlib/Geometry/Euclidean/Triangle.lean index 30fe0c9dafd0b5..dbe7cff17317b6 100644 --- a/Mathlib/Geometry/Euclidean/Triangle.lean +++ b/Mathlib/Geometry/Euclidean/Triangle.lean @@ -264,14 +264,12 @@ theorem sin_angle_mul_dist_eq_sin_angle_mul_dist (p₁ p₂ p₃ : P) : alias law_sin := sin_angle_mul_dist_eq_sin_angle_mul_dist -set_option linter.flexible false in -- see https://github.com/leanprover-community/mathlib4/issues/29041 set_option linter.unusedSimpArgs false in /-- A variant of the law of sines, angle-at-point form. -/ theorem sin_angle_div_dist_eq_sin_angle_div_dist {p₁ p₂ p₃ : P} (h23 : p₂ ≠ p₃) (h31 : p₃ ≠ p₁) : Real.sin (∠ p₁ p₂ p₃) / dist p₃ p₁ = Real.sin (∠ p₃ p₁ p₂) / dist p₂ p₃ := by - simp [field, dist_ne_zero.mpr h23, dist_ne_zero.mpr h31, mul_comm (dist ..)] - exact law_sin _ _ _ + simp [field, dist_ne_zero.mpr h23, dist_ne_zero.mpr h31, mul_comm (dist ..), ← law_sin] /-- A variant of the law of sines, requiring that the points not be collinear. -/ theorem dist_eq_dist_mul_sin_angle_div_sin_angle {p₁ p₂ p₃ : P} diff --git a/Mathlib/InformationTheory/Coding/KraftMcMillan.lean b/Mathlib/InformationTheory/Coding/KraftMcMillan.lean index e960a8b2de9898..93f45d0b966236 100644 --- a/Mathlib/InformationTheory/Coding/KraftMcMillan.lean +++ b/Mathlib/InformationTheory/Coding/KraftMcMillan.lean @@ -90,7 +90,6 @@ private lemma concatFn_length_mem_Icc {S : Finset (List α)} · -- upper bound exact (Finset.sum_le_sum (fun i _ => Finset.le_sup (w i).prop)).trans_eq (by simp) -set_option linter.flexible false in -- TODO: fix non-terminal simp /-- Auxiliary bound for Kraft–McMillan. If `S` is a finite uniquely decodable code and `1 ≤ r`, then the `r`-th power of its Kraft sum @@ -137,9 +136,7 @@ private lemma kraft_mcmillan_inequality_aux {S : Finset (List α)} [Fintype α] -- Summing these bounds over the interval s ∈ [r, r * maxLen] multiplies the term -- by the number of lengths. Since r ≥ 1, this count is at most r * maxLen. rcases r with (_ | _ | r) <;> rcases maxLen with (_ | _ | maxLen) - all_goals try simp at * - · positivity - · rw [Nat.cast_sub] <;> push_cast <;> nlinarith only + <;> simp at * <;> norm_cast <;> simp open Filter diff --git a/Mathlib/NumberTheory/LucasLehmer.lean b/Mathlib/NumberTheory/LucasLehmer.lean index 314677e515db97..d3a82a41a7074b 100644 --- a/Mathlib/NumberTheory/LucasLehmer.lean +++ b/Mathlib/NumberTheory/LucasLehmer.lean @@ -514,13 +514,10 @@ theorem ω_pow_formula (p' : ℕ) (h : lucasLehmerResidue (p' + 2) = 0) : have : 1 ≤ 2 ^ (p' + 2) := Nat.one_le_pow _ _ (by decide) exact mod_cast h --- TODO: fix non-terminal simp (acting on two goals with different simp sets) -set_option linter.flexible false in set_option backward.isDefEq.respectTransparency false in /-- `q` is the minimum factor of `mersenne p`, so `M p = 0` in `X q`. -/ theorem mersenne_coe_X (p : ℕ) : (mersenne p : X (q p)) = 0 := by - ext <;> simp [mersenne, q, ZMod.natCast_eq_zero_iff, -pow_pos] - apply Nat.minFac_dvd + ext <;> simp [mersenne, q, ZMod.natCast_eq_zero_iff, Nat.minFac_dvd, -pow_pos] theorem ω_pow_eq_neg_one (p' : ℕ) (h : lucasLehmerResidue (p' + 2) = 0) : (ω : X (q (p' + 2))) ^ 2 ^ (p' + 1) = -1 := by diff --git a/Mathlib/NumberTheory/PythagoreanTriples.lean b/Mathlib/NumberTheory/PythagoreanTriples.lean index 4a3ccc22d77dc2..917922ab62291c 100644 --- a/Mathlib/NumberTheory/PythagoreanTriples.lean +++ b/Mathlib/NumberTheory/PythagoreanTriples.lean @@ -237,8 +237,6 @@ For the classification of Pythagorean triples, we will use a parametrization of variable {K : Type*} [Field K] --- Non-terminal simp, used to be field_simp -set_option linter.flexible false in -- see https://github.com/leanprover-community/mathlib4/issues/29041 set_option linter.unusedSimpArgs false in /-- A parameterization of the unit circle that is useful for classifying Pythagorean triples. @@ -269,9 +267,7 @@ def circleEquivGen (hk : ∀ x : K, 1 + x ^ 2 ≠ 0) : simp only [Prod.mk_inj, Subtype.mk_eq_mk] constructor · simp [field, h3] - · simp [field, h3] - rw [← add_neg_eq_iff_eq_add.mpr hxy.symm] - ring + · grind @[simp] theorem circleEquivGen_apply (hk : ∀ x : K, 1 + x ^ 2 ≠ 0) (x : K) : diff --git a/Mathlib/RingTheory/Nilpotent/Exp.lean b/Mathlib/RingTheory/Nilpotent/Exp.lean index 46934cfa2a115e..9a42547fcb9cd6 100644 --- a/Mathlib/RingTheory/Nilpotent/Exp.lean +++ b/Mathlib/RingTheory/Nilpotent/Exp.lean @@ -199,11 +199,11 @@ theorem exp_smul {G : Type*} [Monoid G] [MulSemiringAction G A] exp (g • a) = g • exp a := (map_exp ha (MulSemiringAction.toRingHom G A g)).symm -set_option linter.flexible false in -- TODO: fix non-terminal simp theorem isNilpotent_exp_sub_one {a : A} (ha : IsNilpotent a) : IsNilpotent (exp a - 1) := by nontriviality A rw [exp, ← Nat.sub_add_cancel (pos_nilpotencyClass_iff.2 ha), Finset.sum_range_succ'] - simp + simp only [Nat.succ_eq_add_one, zero_add, Nat.factorial_zero, Nat.cast_one, inv_one, pow_zero, + one_smul, add_sub_cancel_right] apply Commute.isNilpotent_sum fun _ _ ↦ smul (pow_of_pos ha <| by positivity) _ simp [Nat.factorial_ne_zero] From 9a281b3c552034717f23284f5cc07645d54d1192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Fri, 24 Jul 2026 21:19:34 +0000 Subject: [PATCH 1003/1300] feat(Topology/Sets): connectedness of `NonemptyCompacts` (#34278) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Topology/Connected/Basic.lean | 2 +- Mathlib/Topology/Sets/Compacts.lean | 8 ++ Mathlib/Topology/Sets/VietorisTopology.lean | 140 ++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 77f2be54b3eb9f..445fa61e0e137c 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -651,7 +651,7 @@ class PreconnectedSpace (α : Type u) [TopologicalSpace α] : Prop where export PreconnectedSpace (isPreconnected_univ) /-- A connected space is a nonempty one where there is no non-trivial open partition. -/ -@[wikidata Q1491995] +@[wikidata Q1491995, mk_iff] class ConnectedSpace (α : Type u) [TopologicalSpace α] : Prop extends PreconnectedSpace α where /-- A connected space is nonempty. -/ toNonempty : Nonempty α diff --git a/Mathlib/Topology/Sets/Compacts.lean b/Mathlib/Topology/Sets/Compacts.lean index eacdaf95b8ae77..bcac748c537c1a 100644 --- a/Mathlib/Topology/Sets/Compacts.lean +++ b/Mathlib/Topology/Sets/Compacts.lean @@ -623,6 +623,14 @@ theorem singleton_prod_singleton (x : α) (y : β) : ({x} ×ˢ {y} : NonemptyCompacts (α × β)) = {(x, y)} := NonemptyCompacts.ext Set.singleton_prod_singleton +/-- `TopologicalSpace.NonemptyCompacts.toCompacts` as an order embedding. -/ +def toCompactsOrderEmbedding : NonemptyCompacts α ↪o Compacts α := + .ofMapLEIff toCompacts fun _ _ => .rfl + +@[simp] +theorem coe_toCompactsOrderEmbedding : ⇑(toCompactsOrderEmbedding (α := α)) = toCompacts := + rfl + end NonemptyCompacts /-! ### Positive compact sets -/ diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index 921dec54209993..c7860354c9679b 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -330,6 +330,64 @@ instance [T1Space α] : T0Space (Set α) where t0 _ _ h := subset_antisymm (subset_of_specializes h.specializes) (subset_of_specializes h.specializes') +theorem isPreconnected_nonempty_finite_subsets {s : Set α} (hs : IsPreconnected s) : + IsPreconnected {t | t.Nonempty ∧ t.Finite ∧ t ⊆ s} := by + rcases eq_empty_or_nonempty s with rfl | ⟨x, hx⟩ + · convert isPreconnected_empty + grind [Set.not_nonempty_empty] + suffices {t | t.Nonempty ∧ t.Finite ∧ t ⊆ s} = + ⋃ n : ℕ+, range (ι := Fin n) '' Set.pi univ fun _ => s by + rw [this] + /- The family of nonempty subsets of `s` with at most `n` elements is connected, since it is the + image of `sⁿ` under the continuous map `(x₁, …, xₙ) ↦ {x₁, …, xₙ}`. It follows that their union + over `n ≥ 1` is also connected. -/ + exact isPreconnected_iUnion + ⟨{x}, mem_iInter_of_mem fun n => ⟨fun _ => x, by simpa⟩⟩ + (fun n => .image (isPreconnected_univ_pi fun _ => hs) _ (by fun_prop)) + refine subset_antisymm (fun t ht => ?_) + (iUnion_subset fun _ => image_subset_iff.mpr fun f hf => + ⟨range_nonempty _, finite_range _, by grind⟩) + obtain ⟨ht₁, ht₂, hts⟩ := ht + obtain ⟨n, f, -, rfl⟩ := ht₂.fin_param + rw [range_subset_iff] at hts + rw [range_nonempty_iff_nonempty] at ht₁ + lift n to ℕ+ using Fin.pos' + exact mem_iUnion_of_mem n <| mem_image_of_mem _ <| mem_univ_pi.mpr hts + +theorem isPreconnected_sUnion {s : Set (Set α)} (hs : IsPreconnected s) + (h : ∃ t ∈ s, IsPreconnected t) : IsPreconnected (⋃₀ s) := by + obtain ⟨t, hts, ht⟩ := h + have hts' := subset_sUnion_of_mem hts + /- Take open sets `U` and `V` covering `⋃₀ s`, and assume that they both intersect `⋃₀ s`. We have + to show that `U` and `V` intersect within `⋃₀ s` -/ + intro U V hU hV hUV + by_cases! ht' : t ⊆ U ∨ t ⊆ V + · -- Consider the case when one of them covers `t`, say `U`. + wlog htU : t ⊆ U generalizing U V + · grind + -- There is also some `u ∈ s` that intersects `V`. + rintro - hV' + rw [sUnion_eq_biUnion, iUnion₂_inter, nonempty_biUnion] at hV' + obtain ⟨u, hus, huV⟩ := hV' + -- Every set in `s` either is in `U` or intersects `V`. + have : s ⊆ U.powerset ∪ {v | (v ∩ V).Nonempty} := by + grind [=_ sdiff_subset_iff, =_ not_disjoint_iff_nonempty_inter] + -- Since `s` connects `t` and `u`, there is some `v ∈ s` that is in `U` and intersects `V`. + obtain ⟨v, hvs, hvU, hvV⟩ := + hs _ _ hU.powerset_vietoris (isOpen_inter_nonempty_of_isOpen hV) this + ⟨t, hts, htU⟩ ⟨u, hus, huV⟩ + -- `U` intersects `V` within `v`, and therefore also within `⋃₀ s`. + apply hvV.mono + grind + · -- If neither `U` nor `V` covers `t`, then they both intersect `t`, since `t ⊆ U ∪ V`. + rintro - - + have htU : ¬ Disjoint t U := by grind + have htV : ¬ Disjoint t V := by grind + rw [not_disjoint_iff_nonempty_inter] at htU htV + -- By the connectedness of `t`, `U` and `V` intersect within `t`, and therefore within `⋃₀ s`. + grw [← hts'] at hUV ⊢ + exact ht U V hU hV hUV htU htV + end vietoris namespace Compacts @@ -686,6 +744,35 @@ theorem separableSpace_iff : SeparableSpace (Compacts α) ↔ SeparableSpace α refine ⟨Classical.epsilon (· ∈ K), ?_, mem_image_of_mem _ hK₃⟩ exact hK₁ <| Classical.epsilon_spec (hK₂.mono inter_subset_left) +theorem isPreconnected_nonempty_finite_subsets {s : Set α} (hs : IsPreconnected s) : + IsPreconnected {K : Compacts α | (K : Set α).Nonempty ∧ (K : Set α).Finite ∧ ↑K ⊆ s} := by + rw [← isEmbedding_coe.isPreconnected_image] + convert vietoris.isPreconnected_nonempty_finite_subsets hs + exact subset_antisymm (image_subset_iff.mpr .rfl) (fun t ht => ⟨⟨t, ht.2.1.isCompact⟩, ht, rfl⟩) + +theorem isPreconnected_nonempty_subsets {s : Set α} (hs : IsPreconnected s) : + IsPreconnected {K : Compacts α | (K : Set α).Nonempty ∧ ↑K ⊆ s} := by + refine (isPreconnected_nonempty_finite_subsets hs).subset_closure (by grind) ?_ + rw [ofPred_and, ofPred_and] + simp_rw [Compacts.coe_nonempty, ← compl_singleton_eq] + grw [← isClopen_singleton_bot.compl.isOpen.inter_closure, closure_finite_subsets, + ← subset_closure] + +theorem isPreconnected_Icc {K L : Compacts α} (hK : K ≠ ⊥) (hL : IsPreconnected (L : Set α)) : + IsPreconnected (Icc K L) := by + wlog hKL : K ≤ L + · simpa [hKL] using isPreconnected_empty + convert (isPreconnected_nonempty_subsets hL).image (K ⊔ ·) (by fun_prop) + exact subset_antisymm + (fun M hM => ⟨M, ⟨Compacts.coe_nonempty.mpr (ne_bot_of_le_ne_bot hK hM.1), hM.2⟩, + sup_eq_right.mpr hM.1⟩) + (image_subset_iff.mpr fun M ⟨_, hM⟩ => ⟨le_sup_left, sup_le hKL hM⟩) + +theorem isPreconnected_Ioc {K L : Compacts α} (hL : IsPreconnected (L : Set α)) : + IsPreconnected (Ioc K L) := + isPreconnected_of_forall L fun M hM => ⟨Icc M L, Icc_subset_Ioc_left hM.1, right_mem_Icc.mpr hM.2, + left_mem_Icc.mpr hM.2, isPreconnected_Icc (ne_bot_of_gt hM.1) hL⟩ + end Compacts namespace NonemptyCompacts @@ -944,6 +1031,59 @@ theorem separableSpace_iff : SeparableSpace (NonemptyCompacts α) ↔ SeparableS ← range_toCompacts] exact (finite_singleton _).isSeparable.union (isSeparable_range continuous_toCompacts) +theorem isPreconnected_finite_subsets {s : Set α} (hs : IsPreconnected s) : + IsPreconnected {K : NonemptyCompacts α | (K : Set α).Finite ∧ ↑K ⊆ s} := by + rw [← isEmbedding_toCompacts.isPreconnected_image] + convert Compacts.isPreconnected_nonempty_finite_subsets hs + exact subset_antisymm + (image_subset_iff.mpr fun K hK => ⟨K.nonempty, hK⟩) + (fun K hK => ⟨⟨K, hK.1⟩, hK.2, rfl⟩) + +theorem isPreconnected_subsets {s : Set α} (hs : IsPreconnected s) : + IsPreconnected {K : NonemptyCompacts α | ↑K ⊆ s} := by + rw [← isEmbedding_toCompacts.isPreconnected_image] + convert Compacts.isPreconnected_nonempty_subsets hs + exact subset_antisymm + (image_subset_iff.mpr fun K hK => ⟨K.nonempty, hK⟩) + (fun K hK => ⟨⟨K, hK.1⟩, hK.2, rfl⟩) + +theorem isPreconnected_Icc {K L : NonemptyCompacts α} (hL : IsPreconnected (L : Set α)) : + IsPreconnected (Icc K L) := by + rw [← isEmbedding_toCompacts.isPreconnected_image, ← coe_toCompactsOrderEmbedding, + OrderEmbedding.image_Icc _ (by simpa [← Set.Ioi_bot] using ordConnected_Ioi)] + exact Compacts.isPreconnected_Icc (Compacts.coe_nonempty.mp K.nonempty) hL + +theorem isPreconnected_Ioc {K L : NonemptyCompacts α} (hL : IsPreconnected (L : Set α)) : + IsPreconnected (Ioc K L) := by + rw [← isEmbedding_toCompacts.isPreconnected_image, ← coe_toCompactsOrderEmbedding, + OrderEmbedding.image_Ioc _ (by simpa [← Set.Ioi_bot] using ordConnected_Ioi)] + exact Compacts.isPreconnected_Ioc hL + +theorem isPreconnected_Iic {K : NonemptyCompacts α} (hK : IsPreconnected (K : Set α)) : + IsPreconnected (Iic K) := + isPreconnected_subsets hK + +instance [PreconnectedSpace α] : PreconnectedSpace (NonemptyCompacts α) where + isPreconnected_univ := by simpa using isPreconnected_subsets isPreconnected_univ + +@[simp] +theorem preconnectedSpace_iff : PreconnectedSpace (NonemptyCompacts α) ↔ PreconnectedSpace α := by + refine ⟨fun h => ?_, fun h => inferInstance⟩ + rw [preconnectedSpace_iff_clopen] at h ⊢ + intro s hs + apply h _ ⟨isClosed_subsets_of_isClosed hs.isClosed, isOpen_subsets_of_isOpen hs.isOpen⟩ |>.imp + · simp only [Set.eq_empty_iff_forall_notMem] + exact fun h x hx => h {x} (Set.singleton_subset_iff.mpr hx) + · simp only [Set.eq_univ_iff_forall] + exact fun h x => Set.singleton_subset_iff.mp (h {x}) + +instance [ConnectedSpace α] : ConnectedSpace (NonemptyCompacts α) where + toNonempty := inferInstance + +@[simp] +protected theorem connectedSpace_iff : ConnectedSpace (NonemptyCompacts α) ↔ ConnectedSpace α := by + simp [connectedSpace_iff] + end NonemptyCompacts end TopologicalSpace From 8fbdbdc803350d7e935335da39dba9ba169c648b Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Fri, 24 Jul 2026 23:28:09 +0000 Subject: [PATCH 1004/1300] chore(RepresentationTheory/Rep/Res): fix malformed deprecation date (#41566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR fixes the malformed deprecation date `since := "26/06/2026"` on the `res_map_hom_toLinearMap` alias in `Mathlib/RepresentationTheory/Rep/Res.lean`, changing it to the standard `YYYY-MM-DD` form `"2026-06-26"`. It was the only deprecation date in Mathlib not in this format, which breaks date-based deprecation tooling. Follow-up to [#41054 (refactor(RepresentationTheory/Rep/Res): refactor resFunctor)](https://github.com/leanprover-community/mathlib4/pull/41054). 🤖 Prepared with Claude Code --- Mathlib/RepresentationTheory/Rep/Res.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/RepresentationTheory/Rep/Res.lean b/Mathlib/RepresentationTheory/Rep/Res.lean index def1ed7cfe31fb..8bb98274728e43 100644 --- a/Mathlib/RepresentationTheory/Rep/Res.lean +++ b/Mathlib/RepresentationTheory/Rep/Res.lean @@ -55,7 +55,7 @@ lemma res_obj_V : (res f M).V = M.V := rfl lemma resMap_hom_toLinearMap {M N : Rep k G} (p : M ⟶ N) : (resMap f p).hom.toLinearMap = p.hom.toLinearMap := rfl -@[deprecated (since := "26/06/2026")] +@[deprecated (since := "2026-06-26")] alias res_map_hom_toLinearMap := resMap_hom_toLinearMap @[simp] From c07d30b9c8f8fbb23fa6b01ee064d7dcc37d1d6f Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Fri, 24 Jul 2026 23:37:32 +0000 Subject: [PATCH 1005/1300] chore: small tweaks related to Subsingleton.eq_zero (#42060) Discovered while auditing the uses of that lemmas, for reviewing #42053. --- Mathlib/Algebra/Order/AbsoluteValue/Basic.lean | 2 +- Mathlib/Analysis/Analytic/OfScalars.lean | 2 +- Mathlib/Geometry/Euclidean/NinePointCircle.lean | 9 ++------- Mathlib/NumberTheory/LSeries/Dirichlet.lean | 2 +- Mathlib/RingTheory/Polynomial/ScaleRoots.lean | 2 +- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean index 7caaf3ed13c86c..04b1a4dacc86be 100644 --- a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean +++ b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean @@ -185,7 +185,7 @@ omit [Nontrivial R] in /-- An absolute value satisfies `f (n : R) ≤ n` for every `n : ℕ`. -/ lemma apply_nat_le_self [IsOrderedRing S] (n : ℕ) : abv n ≤ n := by cases subsingleton_or_nontrivial R - · simp [Subsingleton.eq_zero (n : R)] + · simp [Subsingleton.eq_zero (α := R)] induction n with | zero => simp | succ n ih => diff --git a/Mathlib/Analysis/Analytic/OfScalars.lean b/Mathlib/Analysis/Analytic/OfScalars.lean index b1465974ddfc62..f9f06964d5e244 100644 --- a/Mathlib/Analysis/Analytic/OfScalars.lean +++ b/Mathlib/Analysis/Analytic/OfScalars.lean @@ -143,7 +143,7 @@ theorem ofScalarsSum_zero : ofScalarsSum c (0 : E) = c 0 • 1 := by @[simp] theorem ofScalarsSum_of_subsingleton [Subsingleton E] {x : E} : ofScalarsSum c x = 0 := by - simp [Subsingleton.eq_zero x, Subsingleton.eq_zero (1 : E)] + simp [Subsingleton.eq_zero (α := E)] @[simp] theorem ofScalarsSum_op [T2Space E] (x : E) : diff --git a/Mathlib/Geometry/Euclidean/NinePointCircle.lean b/Mathlib/Geometry/Euclidean/NinePointCircle.lean index f0f77ee351ab70..f8647f77add529 100644 --- a/Mathlib/Geometry/Euclidean/NinePointCircle.lean +++ b/Mathlib/Geometry/Euclidean/NinePointCircle.lean @@ -139,7 +139,6 @@ theorem eulerPoint_restrict {n : ℕ} (s : Simplex ℝ P n) (S : AffineSubspace (hS : affineSpan ℝ (Set.range s.points) ≤ S) (i : Fin (n + 1)) : haveI := Nonempty.map (AffineSubspace.inclusion hS) inferInstance (s.restrict S hS).eulerPoint i = s.eulerPoint i := by - have := Nonempty.map (AffineSubspace.inclusion hS) inferInstance simp [eulerPoint] theorem points_vsub_eulerPoint {n : ℕ} (s : Simplex ℝ P n) (i : Fin (n + 1)) : @@ -147,15 +146,11 @@ theorem points_vsub_eulerPoint {n : ℕ} (s : Simplex ℝ P n) (i : Fin (n + 1)) rw [eulerPoint, vsub_vadd_eq_vsub_sub] by_cases hn : n = 0 · obtain rfl := hn - have : Subsingleton (Fin (0 + 1)) := inferInstanceAs (Subsingleton (Fin 1)) - have hi : i = 0 := Subsingleton.eq_zero i - have hrange : Set.range s.points = {s.points i} := by simp [hi] + have hrange : Set.range s.points = {s.points i} := by simp [Subsingleton.eq_zero (α := Fin 1) i] obtain hmonge := s.mongePoint_mem_affineSpan rw [hrange, mem_affineSpan_singleton] at hmonge simp [hmonge] - have : ((n - 1) / n : ℝ) = 1 - (n : ℝ)⁻¹ := by - rw [sub_div, div_self (by simpa using hn), one_div] - rw [this, sub_smul, one_smul] + rw [sub_div, div_self (by simpa using hn), one_div, sub_smul, one_smul] theorem midpoint_faceOppositeCentroid_eulerPoint {n : ℕ} [hn : NeZero n] (s : Simplex ℝ P n) (i : Fin (n + 1)) : diff --git a/Mathlib/NumberTheory/LSeries/Dirichlet.lean b/Mathlib/NumberTheory/LSeries/Dirichlet.lean index 07345140093274..f718ca1edc35ff 100644 --- a/Mathlib/NumberTheory/LSeries/Dirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/Dirichlet.lean @@ -429,7 +429,7 @@ of the L-series of the constant sequence `1` on its domain of convergence `re s lemma LSeries_vonMangoldt_eq {s : ℂ} (hs : 1 < s.re) : L ↗Λ s = - deriv (L 1) s / L 1 s := by refine (LSeries_congr (fun {n} _ ↦ ?_) s).trans <| LSeries_modOne_eq ▸ LSeries_twist_vonMangoldt_eq χ₁ hs - simp [Subsingleton.eq_one (n : ZMod 1)] + simp [Subsingleton.eq_one (α := ZMod 1)] /-- The L-series of the von Mangoldt function `Λ` equals the negative logarithmic derivative of the Riemann zeta function on its domain of convergence `re s > 1`. -/ diff --git a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean index baba79d9b534a5..eda00901954800 100644 --- a/Mathlib/RingTheory/Polynomial/ScaleRoots.lean +++ b/Mathlib/RingTheory/Polynomial/ScaleRoots.lean @@ -168,7 +168,7 @@ theorem scaleRoots_eval₂_eq_zero_of_eval₂_div_eq_zero {p : S[X]} {f : S →+ (hf : Function.Injective f) {r s : S} (hr : eval₂ f (f r / f s) p = 0) (hs : s ∈ nonZeroDivisors S) : eval₂ f (f r) (scaleRoots p s) = 0 := by -- if we don't specify the type with `(_ : S)`, the proof is much slower - nontriviality S using Subsingleton.eq_zero (_ : S) + nontriviality S using Subsingleton.eq_zero (α := S) convert! @scaleRoots_eval₂_eq_zero _ _ _ _ p f _ s hr rw [← mul_div_assoc, mul_comm, mul_div_cancel_right₀] exact map_ne_zero_of_mem_nonZeroDivisors _ hf hs From 3bc2a1801c2416549ba5ba0b3f5728a28b87e7d9 Mon Sep 17 00:00:00 2001 From: William Coram Date: Sat, 25 Jul 2026 02:01:06 +0000 Subject: [PATCH 1006/1300] refactor: change definition of restricted power series to align with restricted multivariate power series (#39583) Previously, restricted power series were defined in terms of a `tendsto atTop` this has been changed to be an abbrev of `MvPowerSeries.IsRestricted` with `isRestricted_iff` lemmas to convert to nicer usable definitions. Co-authored-by: WilliamCoram --- .../RingTheory/PowerSeries/Restricted.lean | 204 ++++++------------ 1 file changed, 66 insertions(+), 138 deletions(-) diff --git a/Mathlib/RingTheory/PowerSeries/Restricted.lean b/Mathlib/RingTheory/PowerSeries/Restricted.lean index aa9376d8e9906e..cdf394d9c98fb6 100644 --- a/Mathlib/RingTheory/PowerSeries/Restricted.lean +++ b/Mathlib/RingTheory/PowerSeries/Restricted.lean @@ -5,159 +5,87 @@ Authors: William Coram -/ module -public import Mathlib.Analysis.Normed.Group.Ultra -public import Mathlib.Analysis.RCLike.Basic +public import Mathlib.RingTheory.MvPowerSeries.Restricted public import Mathlib.RingTheory.PowerSeries.Basic -public import Mathlib.Tactic.Bound +public import Mathlib.Order.Filter.Cofinite /-! -# Restricted power series +# Univariate restricted power series -`IsRestricted` : We say a power series over a normed ring `R` is restricted for a parameter `c` if -`‖coeff R i f‖ * c ^ i → 0`. +`IsRestricted` : We say a univariate power series over a normed ring `R` is restricted for a +real number `c` if `‖coeff t f‖ * c i ^ t i → 0` under the cofinite filter. -/ @[expose] public section - namespace PowerSeries -variable {R : Type*} [NormedRing R] (c : ℝ) +open Filter +open scoped Topology Pointwise + +variable {R : Type*} [NormedRing R] (c : ℝ) (f : PowerSeries R) + +/-- Predicate for when `f` is a restricted power series. -/ +abbrev IsRestricted := + MvPowerSeries.IsRestricted (σ := Unit) (fun _ ↦ c) f + +private lemma isRestricted_comp_uniqueEquiv : + (fun (t : Unit →₀ ℕ) ↦ ‖MvPowerSeries.coeff t f‖ * t.prod (fun _ x ↦ c ^ x)) = + (fun (n : ℕ) ↦ ‖coeff n f‖ * c ^ n) ∘ Finsupp.uniqueEquiv () := by + funext t + simp only [Function.comp_apply, Finsupp.uniqueEquiv_apply, PUnit.default_eq_unit, + Finsupp.prod_pow, Finset.univ_unique, Finset.prod_singleton, coeff, + show (Finsupp.single () (t ())) = t by grind] + +lemma isRestricted_iff : IsRestricted c f ↔ + Tendsto (fun (t : ℕ) ↦ ‖coeff t f‖ * c ^ t) cofinite (𝓝 0) := by + rw [IsRestricted, MvPowerSeries.IsRestricted, isRestricted_comp_uniqueEquiv] + exact ⟨fun H ↦ (H.comp (Finsupp.uniqueEquiv ()).symm.injective.tendsto_cofinite).congr fun n ↦ + by simp, fun H ↦ H.comp (Finsupp.uniqueEquiv ()).injective.tendsto_cofinite⟩ + +lemma isRestricted_iff' : IsRestricted c f ↔ + Tendsto (fun (t : ℕ) ↦ ‖coeff t f‖ * c ^ t) atTop (𝓝 0) := by + simp_rw [isRestricted_iff, Nat.cofinite_eq_atTop] + +@[simp] +lemma isRestricted_abs_iff : IsRestricted |c| f ↔ IsRestricted c f := + MvPowerSeries.isRestricted_abs_iff (fun _ ↦ c) f -open PowerSeries Filter -open scoped Topology +lemma isRestricted_zero : IsRestricted c (0 : PowerSeries R) := + MvPowerSeries.isRestricted_zero (fun _ ↦ c) -/-- A power series over `R` is restricted of parameter `c` if we have -`‖coeff R i f‖ * c ^ i → 0`. -/ -def IsRestricted (f : PowerSeries R) := - Tendsto (fun (i : ℕ) ↦ (norm (coeff i f)) * c ^ i) atTop (𝓝 0) +lemma isRestricted_monomial (n : ℕ) (a : R) : IsRestricted c (monomial n a) := + MvPowerSeries.isRestricted_monomial (fun _ ↦ c) ((Finsupp.single () n)) a + +lemma isRestricted_one : IsRestricted c (1 : PowerSeries R) := + MvPowerSeries.isRestricted_monomial (fun _ ↦ c) 0 1 + +lemma isRestricted_C (a : R) : IsRestricted c (C a) := + MvPowerSeries.isRestricted_C (fun _ ↦ c) a + +variable {f} in +lemma isRestricted.add {g : PowerSeries R} (hf : IsRestricted c f) (hg : IsRestricted c g) : + IsRestricted c (f + g) := + MvPowerSeries.isRestricted.add (fun _ ↦ c) hf hg + +variable {f} in +lemma isRestricted.neg (hf : IsRestricted c f) : IsRestricted c (-f) := + MvPowerSeries.isRestricted.neg (fun _ ↦ c) hf + +lemma isRestricted.mul [IsUltrametricDist R] (c : ℝ) {f g : PowerSeries R} + (hf : IsRestricted c f) (hg : IsRestricted c g) : IsRestricted c (f * g) := + MvPowerSeries.isRestricted.mul (fun _ ↦ c) hf hg namespace IsRestricted -lemma isRestricted_iff {f : PowerSeries R} : IsRestricted c f ↔ - ∀ ε, 0 < ε → ∃ N, ∀ n, N ≤ n → ‖‖(coeff n) f‖ * c ^ n‖ < ε := by - simp [IsRestricted, NormedAddCommGroup.tendsto_atTop] - -lemma isRestricted_iff_abs (f : PowerSeries R) : IsRestricted c f ↔ IsRestricted |c| f := by - simp [isRestricted_iff] - -lemma zero : IsRestricted c (0 : PowerSeries R) := by - simp [IsRestricted] - -lemma one : IsRestricted c (1 : PowerSeries R) := by - simp only [isRestricted_iff, coeff_one, norm_mul, norm_pow, Real.norm_eq_abs] - refine fun _ _ ↦ ⟨1, fun n hn ↦ ?_ ⟩ - split - · lia - · simpa - -lemma monomial (n : ℕ) (a : R) : IsRestricted c (monomial n a) := by - simp only [monomial_eq_mk, isRestricted_iff, coeff_mk, norm_mul, norm_pow, - Real.norm_eq_abs, abs_norm] - refine fun _ _ ↦ ⟨n + 1, fun _ _ ↦ ?_⟩ - split - · lia - · simpa - -lemma C (a : R) : IsRestricted c (C a) := by - simpa [monomial_zero_eq_C_apply] using monomial c 0 a - -lemma add {f g : PowerSeries R} (hf : IsRestricted c f) (hg : IsRestricted c g) : - IsRestricted c (f + g) := by - simp only [isRestricted_iff, map_add, norm_mul, norm_pow, Real.norm_eq_abs] at ⊢ hf hg - intro ε hε - obtain ⟨fN, hfN⟩ := hf (ε / 2) (by positivity) - obtain ⟨gN, hgN⟩ := hg (ε / 2) (by positivity) - simp only [abs_norm] at hfN hgN ⊢ - refine ⟨max fN gN, fun n hn ↦ ?_ ⟩ - calc _ ≤ ‖(coeff n) f‖ * |c| ^ n + ‖(coeff n) g‖ * |c| ^ n := by grw [norm_add_le, add_mul] - _ < ε / 2 + ε / 2 := by gcongr <;> grind - _ = ε := by ring - -lemma neg {f : PowerSeries R} (hf : IsRestricted c f) : IsRestricted c (-f) := by - simpa [isRestricted_iff] using hf - -lemma smul {f : PowerSeries R} (hf : IsRestricted c f) (r : R) : IsRestricted c (r • f) := by - if h : r = 0 then simpa [h] using zero c else - simp_rw [isRestricted_iff, norm_mul, norm_pow, Real.norm_eq_abs, abs_norm] at ⊢ hf - intro ε _ - obtain ⟨n, hn⟩ := hf (ε / ‖r‖) (by positivity) - refine ⟨n, fun N hN ↦ ?_⟩ - calc _ ≤ ‖r‖ * ‖(coeff N) f‖ * |c| ^ N := - mul_le_mul_of_nonneg (norm_mul_le _ _) (by simp) (by simp) (by simp) - _ < ‖r‖ * (ε / ‖r‖) := by - rw [mul_assoc]; aesop - _ = ε := mul_div_cancel₀ _ (by aesop) - - -/-- The set of `‖coeff R i f‖ * c ^ i` for a given power series `f` and parameter `c`. -/ -def convergenceSet (f : PowerSeries R) : Set ℝ := {‖coeff i f‖ * c^i | i : ℕ} - -open Finset in -lemma convergenceSet_BddAbove {f : PowerSeries R} (hf : IsRestricted c f) : - BddAbove (convergenceSet c f) := by - simp_rw [isRestricted_iff] at hf - obtain ⟨N, hf⟩ := by simpa using (hf 1) - rw [bddAbove_def, convergenceSet] - use max 1 (max' (image (fun i ↦ ‖coeff i f‖ * c ^ i) (range (N + 1))) (by simp)) - simp only [Set.mem_ofPred_eq, le_sup_iff, forall_exists_index, forall_apply_eq_imp_iff] - intro i - rcases le_total i N with h | h - · right - apply le_max' - simp only [mem_image, mem_range] - exact ⟨i, by lia, rfl⟩ - · left - calc _ ≤ ‖(coeff i) f‖ * |c ^ i| := by bound - _ ≤ 1 := by simpa using (hf i h).le +/-- Restricted power series as an additive subgroup of `PowerSeries R`. -/ +def addSubgroup (c : ℝ) : AddSubgroup (PowerSeries R) := + MvPowerSeries.IsRestricted.addSubgroup (fun _ ↦ c) variable [IsUltrametricDist R] -open IsUltrametricDist - -lemma mul {f g : PowerSeries R} (hf : IsRestricted c f) (hg : IsRestricted c g) : - IsRestricted c (f * g) := by - obtain ⟨a, ha, fBound1⟩ := (bddAbove_iff_exists_ge 1).mp (convergenceSet_BddAbove _ - ((isRestricted_iff_abs c f).mp hf)) - obtain ⟨b, hb, gBound1⟩ := (bddAbove_iff_exists_ge 1).mp (convergenceSet_BddAbove _ - ((isRestricted_iff_abs c g).mp hg)) - simp only [convergenceSet, Set.mem_ofPred_eq, forall_exists_index, forall_apply_eq_imp_iff] - at fBound1 gBound1 - simp only [isRestricted_iff, norm_mul, norm_pow, Real.norm_eq_abs, abs_norm, - PowerSeries.coeff_mul] at ⊢ hf hg - intro ε hε - obtain ⟨Nf, fBound2⟩ := (hf (ε / (max a b))) (by positivity) - obtain ⟨Ng, gBound2⟩ := (hg (ε / (max a b))) (by positivity) - refine ⟨2 * max Nf Ng, fun n hn ↦ ?_⟩ - obtain ⟨⟨fst, snd⟩, hi, ultrametric⟩ := exists_norm_finsetSum_le (Finset.antidiagonal n) - (fun a ↦ (coeff a.1) f * (coeff a.2) g) - obtain ⟨rfl⟩ := by simpa using hi (⟨(0, n), by simp⟩) - calc _ ≤ ‖(coeff fst) f * (coeff snd) g‖ * |c| ^ (fst + snd) := by bound - _ ≤ ‖(coeff fst) f‖ * |c| ^ fst * (‖(coeff snd) g‖ * |c| ^ snd) := by - grw [norm_mul_le] - #adaptation_note - /-- - Broken in `nightly-2025-10-26`: this was by `grind`, but is now no longer supported. - See https://github.com/leanprover/lean4/pull/10970. - -/ - rw [pow_add] - grind - have : max Nf Ng ≤ fst ∨ max Nf Ng ≤ snd := by lia - rcases this with this | this - · calc _ < ε / max a b * b := by - grw [gBound1 snd] - gcongr - exact fBound2 fst (by omega) - _ ≤ ε := by - rw [div_mul_comm, mul_le_iff_le_one_left ‹_›] - bound - · calc _ < a * (ε / max a b) := by - grw [fBound1 fst] - gcongr - exact gBound2 snd (by omega) - _ ≤ ε := by - rw [mul_div_left_comm, mul_le_iff_le_one_right ‹_›] - bound - -end IsRestricted -end PowerSeries +/-- Restricted power series as an subring of `PowerSeries R`. -/ +def subring (c : ℝ) : Subring (PowerSeries R) := + MvPowerSeries.IsRestricted.subring (fun _ ↦ c) + +end PowerSeries.IsRestricted From c8830a1d9ceaffabd7c8c7493d9a9be3ead6ea74 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Sat, 25 Jul 2026 09:21:58 +0000 Subject: [PATCH 1007/1300] feat(Manifold/Instances/Icc): golf smoothness proof using immersions (#29077) Prove that the inclusion of an interval into the real numbers is a smooth embedding, and use this to golf the proof that this inclusion is smooth. While at it, rename the smoothness lemmas after the coercion `Subtype.val` they are using, as mandated by the naming convention. --- Mathlib/Geometry/Manifold/Instances/Icc.lean | 132 +++++++++++------- Mathlib/Geometry/Manifold/Instances/Real.lean | 38 +++++ 2 files changed, 119 insertions(+), 51 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Instances/Icc.lean b/Mathlib/Geometry/Manifold/Instances/Icc.lean index a7b42272c3f27e..41b2d5055e1790 100644 --- a/Mathlib/Geometry/Manifold/Instances/Icc.lean +++ b/Mathlib/Geometry/Manifold/Instances/Icc.lean @@ -9,25 +9,28 @@ public import Mathlib.Analysis.InnerProductSpace.Calculus public import Mathlib.Geometry.Manifold.ContMDiff.Basic public import Mathlib.Geometry.Manifold.Instances.Real import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv /-! # Manifold structure on real intervals The manifold structure on real intervals is defined in `Mathlib.Geometry.Manifold.Instances.Real`. We relate it to the manifold structure on the real line, by showing that the inclusion -(`contMDiff_subtype_coe_Icc`) and projection (`contMDiffOn_projIcc`) are smooth, and showing that +(`contMDiff_subtypeVal_Icc`) and projection (`contMDiffOn_projIcc`) are smooth, and showing that a function defined on the interval is smooth iff its composition with the projection is smooth on the interval in `ℝ` (see `contMDiffOn_comp_projIcc_iff` and friends). We also define `1 : TangentSpace (𝓡∂ 1) z`, and relate it to `1` in the real line. +- `isSmoothEmbedding_subtypeVal_Icc`: the inclusion `Icc x y → ℝ` is a smooth embedding, + and in particular smooth (`contMDiff_subtypeVal_Icc`) +- `contMDiff_iff_comp_subtypeVal_Icc`: a function `f : M → Icc x y` is smooth iff + its composition with the inclusion into `ℝ` is smooth + ## TODO -This file can be thoroughly rewritten once mathlib has a good theory of smooth immersions and -embeddings. Once this is done, -- the inclusion `Icc x y → ℝ` is a smooth embedding, and in particular smooth -- deduce the dual result: a function `f : M → Icc x y` is smooth iff - its composition with the inclusion into `ℝ` is smooth +This file can be thoroughly rewritten once mathlib has a good theory of smooth submersions. +Once this is done, - prove the projection `ℝ → Icc x y` is a smooth submersion, hence smooth - use this to simplify the proof that `f : Icc x y → M` is smooth iff the composition `ℝ → M` with the projection `ℝ → Icc x y` is @@ -50,7 +53,7 @@ instance (x : ℝ) : One (TangentSpace 𝓘(ℝ) x) where /-- Unit vector in the tangent space to a segment, as the image of the unit vector in the real line under the canonical projection. It is also mapped to the unit vector in the real line through -the canonical injection, see `mfderiv_subtype_coe_Icc_one`. +the canonical injection, see `mfderiv_subtypeVal_Icc_one`. Note that one cannot abuse defeqs for this definition: this is *not* the same as the vector `fun _ ↦ 1` in `EuclideanSpace ℝ (Fin 1)` through defeqs, as one of the charts of `Icc x y` is @@ -64,49 +67,73 @@ instance {x y : ℝ} [h : Fact (x < y)] (z : Icc x y) : One (TangentSpace (𝓡 variable {x y : ℝ} [h : Fact (x < y)] {n : WithTop ℕ∞} -set_option backward.isDefEq.respectTransparency false in -/-- The inclusion map from of a closed segment to `ℝ` is smooth in the manifold sense. -/ -lemma contMDiff_subtype_coe_Icc : CMDiff n (fun (z : Icc x y) ↦ (z : ℝ)) := by +open Manifold IsManifold + +/-- The inclusion map from a closed segment to `ℝ` is a smooth immersion -/ +lemma isImmersionOfComplement_subtypeVal_Icc : + IsImmersionOfComplement Unit (𝓡∂ 1) 𝓘(ℝ) n (fun (z : Icc x y) ↦ (z : ℝ)) := by intro z - rw [contMDiffAt_iff] - refine ⟨by fun_prop, ?_⟩ - -- We come back to the definition: we should check that, in each chart, the map is smooth. - -- There are two charts, and we check things separately in each of them using the - -- explicit formulas. - suffices ContDiffWithinAt ℝ n _ (range ↑(𝓡∂ 1)) _ by simpa - split_ifs with hz - · simp? [IccLeftChart, Function.comp_def, modelWithCornersEuclideanHalfSpace] says - simp only [IccLeftChart, Fin.isValue, OpenPartialHomeomorph.coe_mk_symm, - PartialEquiv.coe_symm_mk, modelWithCornersEuclideanHalfSpace, ModelWithCorners.mk_symm, - Function.comp_def, Function.update_self, ModelWithCorners.mk_coe, - OpenPartialHomeomorph.coe_mk] - rw [Subtype.range_val_subtype] - have : ContDiff ℝ n (fun (z : EuclideanSpace ℝ (Fin 1)) ↦ z 0 + x) := by fun_prop - apply this.contDiffWithinAt.congr_of_eventuallyEq_of_mem; swap - · simpa using z.2.1 - have : {w : EuclideanSpace ℝ (Fin 1) | w 0 < y - x} ∈ 𝓝 (toLp 2 fun i ↦ z - x) := by - apply (isOpen_lt (PiLp.continuous_apply 2 _ 0) continuous_const).mem_nhds - simpa using hz - filter_upwards [self_mem_nhdsWithin, nhdsWithin_le_nhds this] with w hw h'w - rw [max_eq_left hw, min_eq_left] - linarith - · simp only [not_lt] at hz - simp? [IccRightChart, Function.comp_def, modelWithCornersEuclideanHalfSpace] says - simp only [IccRightChart, Fin.isValue, OpenPartialHomeomorph.coe_mk_symm, - PartialEquiv.coe_symm_mk, modelWithCornersEuclideanHalfSpace, ModelWithCorners.mk_symm, - Function.comp_def, Function.update_self, ModelWithCorners.mk_coe, - OpenPartialHomeomorph.coe_mk] - rw [Subtype.range_val_subtype] - have : ContDiff ℝ n (fun (z : EuclideanSpace ℝ (Fin 1)) ↦ y - z 0) := by fun_prop - apply this.contDiffWithinAt.congr_of_eventuallyEq_of_mem; swap - · simpa using z.2.2 - have : {w : EuclideanSpace ℝ (Fin 1) | w 0 < y - x} ∈ 𝓝 (toLp 2 fun i ↦ y - z) := by - apply (isOpen_lt (PiLp.continuous_apply 2 _ 0) continuous_const).mem_nhds - simpa using h.out.trans_le hz - filter_upwards [self_mem_nhdsWithin, nhdsWithin_le_nhds this] with w hw h'w - rw [max_eq_left hw, max_eq_left] + letI φ₀ := ContinuousLinearEquiv.prodUnique ℝ (EuclideanSpace ℝ (Fin 1)) Unit + let φ : (EuclideanSpace ℝ (Fin 1) × Unit) ≃L[ℝ] ℝ := + φ₀.trans (PiLp.equivOfUnique 2 ℝ (fun (_ : Fin 1) ↦ ℝ)) + by_cases hz : ↑z < y + · -- At all points but `y`, the correct codomain chart maps `a` to `a + x`. + apply IsImmersionAtOfComplement.mk_of_continuousAt (by fun_prop) φ + (chartAt (EuclideanHalfSpace 1) z) (Homeomorph.addLeft (-x)).toOpenPartialHomeomorph + (mem_chart_source _ z) (by simp [Homeomorph.addLeft]) (chart_mem_maximalAtlas _) ?_; swap + · apply OpenPartialHomeomorph.mem_maximalAtlas_of_contMDiffOn + · have : ContDiff ℝ n (fun y ↦ -x + y) := by fun_prop + simpa [contMDiffOn_iff_contDiffOn, contDiffOn_univ] + · have : ContDiff ℝ n (fun y ↦ x + y) := by fun_prop + simpa [contMDiffOn_iff_contDiffOn, contDiffOn_univ, Homeomorph.addLeft] + intro z' hz' + obtain ⟨⟨u, rfl⟩, hu⟩ : + (∃ y, ⇑(𝓡∂ 1) y = z') ∧ ⇑(𝓡∂ 1).symm z' ∈ (IccLeftChart x y).target := by + simpa [hz] using! hz' + replace hu : ofLp u.val 0 ≤ y - x := by + apply le_of_lt + simpa [modelWithCornersEuclideanHalfSpace_symm_apply, max_eq_left u.property] using! hu + simp [hz, φ, φ₀, modelWithCornersEuclideanHalfSpace_symm_apply, u.property, + IccLeftChart_symm_apply_of_le hu] + · -- At the right boundary point, the correct codomain chart is mapping `a` to `y - a`. + apply IsImmersionAtOfComplement.mk_of_continuousAt (by fun_prop) φ + (chartAt (EuclideanHalfSpace 1) z) + (Homeomorph.pointReflection (y / 2)).toOpenPartialHomeomorph (mem_chart_source _ z) + (by simp [Homeomorph.pointReflection]) (chart_mem_maximalAtlas _) ?_; swap + · apply OpenPartialHomeomorph.mem_maximalAtlas_of_contMDiffOn + · have : ContDiff ℝ n ((fun v ↦ v + y / 2) ∘ fun x ↦ y / 2 - x) := by fun_prop + simpa [contMDiffOn_iff_contDiffOn, contDiffOn_univ] + · have : ContDiff ℝ n ((fun v ↦ -v + y / 2) ∘ fun p' ↦ p' - y / 2) := by fun_prop + simpa [contMDiffOn_iff_contDiffOn, contDiffOn_univ] + intro z' hz' + obtain ⟨⟨u, rfl⟩, hu⟩ : + (∃ y, ⇑(𝓡∂ 1) y = z') ∧ ⇑(𝓡∂ 1).symm z' ∈ (IccRightChart x y).target := by + simpa [hz] using! hz' + replace hu : ofLp u.val 0 ≤ y - x := by + apply le_of_lt + simpa [modelWithCornersEuclideanHalfSpace_symm_apply, max_eq_left u.property] using! hu + simp [hz, φ, φ₀, modelWithCornersEuclideanHalfSpace_symm_apply, u.property, + IccRightChart_symm_apply_of_le hu, Equiv.pointReflection_apply] linarith +/-- The inclusion map from a closed segment to `ℝ` is a smooth embedding -/ +lemma isSmoothEmbedding_subtypeVal_Icc : + IsSmoothEmbedding (𝓡∂ 1) 𝓘(ℝ) n (fun (z : Icc x y) ↦ (z : ℝ)) := + ⟨isImmersionOfComplement_subtypeVal_Icc.isImmersion, Topology.IsEmbedding.subtypeVal⟩ + +/-- The inclusion map from of a closed segment to `ℝ` is smooth in the manifold sense. -/ +lemma contMDiff_subtypeVal_Icc : CMDiff n (fun (z : Icc x y) ↦ (z : ℝ)) := + isImmersionOfComplement_subtypeVal_Icc.contMDiff.of_le (OrderTop.le_top n) + +@[deprecated (since := "2026-07-22")] +alias contMDiff_subtype_coe_Icc := contMDiff_subtypeVal_Icc + +/-- A function `f : M → Icc x y` is smooth iff its composition with the inclusion +into `ℝ` is smooth. -/ +lemma contMDiff_iff_comp_subtypeVal_Icc {f : M → Icc x y} : + CMDiff n f ↔ Continuous f ∧ CMDiff n ((fun (z : Icc x y) ↦ (z : ℝ)) ∘ f) := by + rw [← ContMDiff.iff_comp_isImmersionOfComplement isImmersionOfComplement_subtypeVal_Icc] + /-- The projection from `ℝ` to a closed segment is smooth on the segment, in the manifold sense. -/ lemma contMDiffOn_projIcc : CMDiff[Icc x y] n (Set.projIcc x y h.out.le) := by intro z hz @@ -143,7 +170,7 @@ lemma contMDiffOn_projIcc : CMDiff[Icc x y] n (Set.projIcc x y h.out.le) := by lemma contMDiffOn_comp_projIcc_iff {f : Icc x y → M} : CMDiff[Icc x y] n (f ∘ (Set.projIcc x y h.out.le)) ↔ CMDiff n f := by refine ⟨fun hf ↦ ?_, fun hf ↦ hf.comp_contMDiffOn contMDiffOn_projIcc⟩ - convert! hf.comp_contMDiff (contMDiff_subtype_coe_Icc (x := x) (y := y)) (fun z ↦ z.2) + convert! hf.comp_contMDiff (contMDiff_subtypeVal_Icc (x := x) (y := y)) (fun z ↦ z.2) ext z simp @@ -151,7 +178,7 @@ lemma contMDiffWithinAt_comp_projIcc_iff {f : Icc x y → M} {w : Icc x y} : CMDiffAt[Icc x y] n (f ∘ (Set.projIcc x y h.out.le)) w ↔ CMDiffAt n f w := by refine ⟨fun hf ↦ ?_, fun hf ↦ hf.comp_contMDiffWithinAt_of_eq (contMDiffOn_projIcc w w.2) (by simp)⟩ - have A := contMDiff_subtype_coe_Icc (x := x) (y := y) (n := n) w + have A := contMDiff_subtypeVal_Icc (x := x) (y := y) (n := n) w rw [← contMDiffWithinAt_univ] at A ⊢ convert! hf.comp _ A (fun z hz ↦ z.2) ext z @@ -160,7 +187,7 @@ lemma contMDiffWithinAt_comp_projIcc_iff {f : Icc x y → M} {w : Icc x y} : lemma mdifferentiableWithinAt_comp_projIcc_iff {f : Icc x y → M} {w : Icc x y} : MDiffAt[Icc x y] (f ∘ (Set.projIcc x y h.out.le)) w ↔ MDiffAt f w := by refine ⟨fun hf ↦ ?_, fun hf ↦ ?_⟩ - · have A := (contMDiff_subtype_coe_Icc (x := x) (y := y) w).mdifferentiableAt one_ne_zero + · have A := (contMDiff_subtypeVal_Icc (x := x) (y := y) w).mdifferentiableAt one_ne_zero rw [← mdifferentiableWithinAt_univ] at A ⊢ convert! hf.comp _ A (fun z hz ↦ z.2) ext z @@ -191,7 +218,7 @@ lemma mfderivWithin_comp_projIcc_one {f : Icc x y → M} {w : Icc x y} : congr 1 convert! mfderivWithin_projIcc_one w.2 -lemma mfderiv_subtype_coe_Icc_one (z : Icc x y) : +lemma mfderiv_subtypeVal_Icc_one (z : Icc x y) : mfderiv (𝓡∂ 1) 𝓘(ℝ) (Subtype.val : Icc x y → ℝ) z 1 = 1 := by have A : mfderiv[Icc x y] (Subtype.val ∘ (projIcc x y h.out.le)) z 1 = mfderiv[Icc x y] (@id ℝ) z 1 := by @@ -203,3 +230,6 @@ lemma mfderiv_subtype_coe_Icc_one (z : Icc x y) : simp only [id_eq, mfderivWithin_eq_fderivWithin] rw [fderivWithin_id (uniqueDiffOn_Icc h.out _ z.2)] rfl + +@[deprecated (since := "2026-07-22")] +alias mfderiv_subtype_coe_Icc_one := mfderiv_subtypeVal_Icc_one diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 1cf415f0bbeec8..00cba106e172eb 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -240,6 +240,13 @@ scoped[Manifold] (modelWithCornersEuclideanHalfSpace n : ModelWithCorners ℝ (EuclideanSpace ℝ (Fin n)) (EuclideanHalfSpace n)) +@[simp] lemma modelWithCornersEuclideanHalfSpace_toFun (n : ℕ) [NeZero n] : + (𝓡∂ n : _ → _) = Subtype.val := rfl + +lemma modelWithCornersEuclideanHalfSpace_symm_apply {n : ℕ} [NeZero n] + (x : EuclideanSpace ℝ (Fin n)) : + (𝓡∂ n).symm x = ⟨toLp 2 (update x 0 (max (x 0) 0)), by simp⟩ := rfl + lemma modelWithCornersEuclideanHalfSpace_zero {n : ℕ} [NeZero n] : (𝓡∂ n) 0 = 0 := rfl lemma range_modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] : @@ -299,6 +306,21 @@ def IccLeftChart (x y : ℝ) [h : Fact (x < y)] : variable {x y : ℝ} [hxy : Fact (x < y)] +lemma IccLeftChart_apply (z : Icc x y) : + IccLeftChart x y z = ⟨toLp 2 fun _ ↦ z.val - x, by aesop⟩ := + rfl + +lemma IccLeftChart_symm_apply (x y : ℝ) [h : Fact (x < y)] (z : EuclideanHalfSpace 1) : + (IccLeftChart x y).symm z = ⟨min (z.val 0 + x) y, by simp [z.prop, h.out.le]⟩ := + rfl + +lemma IccLeftChart_symm_apply_of_le {z : EuclideanHalfSpace 1} (hz : z.val 0 ≤ y - x) : + (IccLeftChart x y).symm z = + ⟨z.val 0 + x, by simpa [z.prop, hxy.out.le, ← le_add_neg_iff_add_le]⟩ := by + ext + simp only [IccLeftChart_symm_apply, inf_eq_left] + linarith + namespace Fact.Manifold scoped instance : Fact (x ≤ y) := Fact.mk hxy.out.le @@ -362,6 +384,22 @@ def IccRightChart (x y : ℝ) [h : Fact (x < y)] : continuousOn_toFun := by fun_prop continuousOn_invFun := by fun_prop +lemma IccRightChart_apply (z : Icc x y) : + IccRightChart x y z = ⟨toLp 2 fun _ ↦ y - z.val, by aesop⟩ := + rfl + +lemma IccRightChart_symm_apply (x y : ℝ) [h : Fact (x < y)] (z : EuclideanHalfSpace 1) : + (IccRightChart x y).symm z = + ⟨max (y - z.val 0) x, by simp [z.prop, h.out.le, sub_eq_add_neg]⟩ := + rfl + +lemma IccRightChart_symm_apply_of_le {z : EuclideanHalfSpace 1} (hz : z.val 0 ≤ y - x) : + (IccRightChart x y).symm z = + ⟨y - z.val 0, by simp [z.prop, sub_eq_add_neg, add_le_of_le_sub_left hz]⟩ := by + ext + simp only [IccRightChart_symm_apply, sup_eq_left] + linarith + lemma IccRightChart_extend_top : (IccRightChart x y).extend (𝓡∂ 1) ⊤ = 0 := by norm_num [IccRightChart, modelWithCornersEuclideanHalfSpace_zero] From 187167dcf4f37ad6b6e6a07e3dfc66674c9acfa7 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:12:15 +0000 Subject: [PATCH 1008/1300] chore: add gcongr attribute to Nat.ascFactorial_le and Nat.descFactorial_le (#41577) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds the `@[gcongr]` attribute to `Nat.ascFactorial_le` and to the identically-shaped `Nat.descFactorial_le`, so that `gcongr` can rewrite under `ascFactorial`/`descFactorial`. `Nat.factorial_le` in the same file is already tagged `@[mono, gcongr]`. Follow-up to [#40816 (feat(Data/Nat/Factorial/Basic): add `ascFactorial_le`)](https://github.com/leanprover-community/mathlib4/pull/40816). 🤖 Prepared with Claude Code --- Mathlib/Data/Nat/Factorial/Basic.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Data/Nat/Factorial/Basic.lean b/Mathlib/Data/Nat/Factorial/Basic.lean index 092a314777028b..13bbf81f1dd01b 100644 --- a/Mathlib/Data/Nat/Factorial/Basic.lean +++ b/Mathlib/Data/Nat/Factorial/Basic.lean @@ -267,6 +267,7 @@ theorem ascFactorial_of_sub {n k : ℕ} : (n - k) * (n - k + 1).ascFactorial k = (n - k).ascFactorial (k + 1) := by rw [succ_ascFactorial, ascFactorial_succ] +@[gcongr] theorem ascFactorial_le (k : ℕ) {n m : ℕ} (h : n ≤ m) : n.ascFactorial k ≤ m.ascFactorial k := by induction k with @@ -418,6 +419,7 @@ theorem descFactorial_eq_div {n k : ℕ} (h : k ≤ n) : n.descFactorial k = n ! rw [factorial_mul_descFactorial h] exact (Nat.mul_div_cancel' <| factorial_dvd_factorial <| Nat.sub_le n k).symm +@[gcongr] theorem descFactorial_le (n : ℕ) {k m : ℕ} (h : k ≤ m) : k.descFactorial n ≤ m.descFactorial n := by induction n with From 76ff15d5755d43b43757d5b50c0cd6510fc9eb01 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:55:17 +0000 Subject: [PATCH 1009/1300] chore: update Mathlib dependencies 2026-07-25 (#42097) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index ca62f89cbe2320..520b5c113f6e82 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "0a7a0cdc42f531e02361cb303b8cbf0e7d334f82", + "rev": "4950986f9d1271117f0af0aa978b5e68759a08a4", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 9cebae57f419f984d008f357605b2621a1d9f13b Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 01:16:20 +0000 Subject: [PATCH 1010/1300] chore: update Mathlib dependencies 2026-07-26 (#42098) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 520b5c113f6e82..f7e0737aa17c2b 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4950986f9d1271117f0af0aa978b5e68759a08a4", + "rev": "d60e6444e6fd881dfa077ff36e96de75753afa28", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From f47c13d7c7ba7d28f140a6492e4e7f019c6b879d Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sun, 26 Jul 2026 16:16:32 +0000 Subject: [PATCH 1011/1300] chore(CategoryTheory/Shift): avoid `backward.inferInstanceAs.wrap` (#42084) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently giving the proof explicitly allows us to remove the backward.inferInstanceAs.wrap`. Note that avoiding the defeq abuse by first doing `dsimp` still does not work (and interesting replacing the `:=` with `:= by exact` does not work as well). This removes the [last]([#mathlib4 > Technical Debt Counters @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Technical.20Debt.20Counters/near/611588552)) `backward.inferInstanceAs.wrap` exception from the technical debt counter. The solution was found with GPT 5.6 Sol high (fairly quickly) Co-authored-by: Batixx --- Mathlib/CategoryTheory/Shift/CommShiftTwo.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean b/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean index f9a6e802698e2e..daec21fca93942 100644 --- a/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean +++ b/Mathlib/CategoryTheory/Shift/CommShiftTwo.lean @@ -115,7 +115,6 @@ attribute [instance_reducible] commShiftObj commShiftFlipObj attribute [instance] commShiftObj commShiftFlipObj commShift_map commShift_flip_map set_option backward.defeqAttrib.useBackward true in -set_option backward.inferInstanceAs.wrap.data false in set_option backward.isDefEq.respectTransparency false in instance precomp₁ {M : Type*} [AddCommMonoid M] [HasShift C₁ M] [HasShift C₁' M] [HasShift C₂ M] [HasShift D M] (F : C₁' ⥤ C₁) [F.CommShift M] @@ -123,7 +122,7 @@ instance precomp₁ {M : Type*} [AddCommMonoid M] [HasShift C₁ M] [HasShift C (F ⋙ G).CommShift₂ h where commShiftObj (X₁' : C₁') := inferInstanceAs ((G.obj (F.obj X₁')).CommShift M) commShift_map {X₁' Y₁' : C₁'} (f : X₁' ⟶ Y₁') := by dsimp; infer_instance - commShiftFlipObj (X₂ : C₂) := inferInstanceAs ((F ⋙ G.flip.obj X₂).CommShift M) + commShiftFlipObj (X₂ : C₂) := CommShift.comp F (G.flip.obj X₂) commShift_flip_map {X₂ Y₂ : C₂} (g : X₂ ⟶ Y₂) := inferInstanceAs (NatTrans.CommShift (whiskerLeft F (G.flip.map g)) M) comm X₁' X₂ m n := by @@ -135,12 +134,11 @@ instance precomp₁ {M : Type*} [AddCommMonoid M] [HasShift C₁ M] [HasShift C set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in -set_option backward.inferInstanceAs.wrap false in instance precomp₂ {M : Type*} [AddCommMonoid M] [HasShift C₁ M] [HasShift C₂' M] [HasShift C₂ M] [HasShift D M] (F : C₂' ⥤ C₂) [F.CommShift M] (G : C₁ ⥤ C₂ ⥤ D) (h : CommShift₂Setup D M) [G.CommShift₂ h] : (G ⋙ (whiskeringLeft C₂' C₂ D).obj F).CommShift₂ h where - commShiftObj (X₁ : C₁) := inferInstanceAs ((F ⋙ G.obj X₁).CommShift M) + commShiftObj (X₁ : C₁) := CommShift.comp F (G.obj X₁) commShift_map {X₁ Y₁ : C₁} (f : X₁ ⟶ Y₁) := by dsimp; infer_instance commShiftFlipObj (X₂' : C₂') := inferInstanceAs ((G.flip.obj (F.obj X₂')).CommShift M) commShift_flip_map {X₂' Y₂' : C₂'} (g : X₂' ⟶ Y₂') := From 26ce42d2c8bebe479fe6248956b15d1fd4c4ebd3 Mon Sep 17 00:00:00 2001 From: Robin Carlier Date: Sun, 26 Jul 2026 16:26:29 +0000 Subject: [PATCH 1012/1300] chore(CategoryTheory): make more things implicit reducible (#42107) A test file is added to ensure that certain "dsimplifying" equalites in category theory are tagged with `@[defeq]` instead of `@[backward_defeq]`, so that `dsimp` can use them without `set_option backward.defeqAttrib.useBackward true`. To turn a `@[backward_defeq]` into a `@[defeq]`, definitions need to be made `implicit_reducible`. Now that `instance_reducible` is split off `implicit_reducible`, it is much safer to tag many declarations. There is still a ton of declarations that should be tagged, and I did not remove all `set_options` after this tagging (this should be an automated process), but we can already clear some. --- Mathlib/CategoryTheory/Functor/Category.lean | 10 +-- Mathlib/CategoryTheory/Functor/Currying.lean | 43 +++------- Mathlib/CategoryTheory/Iso.lean | 10 +-- Mathlib/CategoryTheory/NatIso.lean | 2 +- Mathlib/CategoryTheory/Products/Basic.lean | 71 ++++++---------- Mathlib/CategoryTheory/ShrinkYoneda.lean | 9 +-- Mathlib/CategoryTheory/Yoneda.lean | 8 +- Mathlib/Combinatorics/Quiver/Basic.lean | 4 +- MathlibTest/CategoryTheory/CheckDsimp.lean | 85 ++++++++++++++++++++ 9 files changed, 145 insertions(+), 97 deletions(-) create mode 100644 MathlibTest/CategoryTheory/CheckDsimp.lean diff --git a/Mathlib/CategoryTheory/Functor/Category.lean b/Mathlib/CategoryTheory/Functor/Category.lean index c157e508759662..d060ac1d7edfe4 100644 --- a/Mathlib/CategoryTheory/Functor/Category.lean +++ b/Mathlib/CategoryTheory/Functor/Category.lean @@ -150,7 +150,7 @@ end NatTrans namespace Functor /-- Flip the arguments of a bifunctor. See also `Currying.lean`. -/ -@[simps (attr := grind =) obj_obj obj_map] +@[implicit_reducible, simps (attr := grind =) obj_obj obj_map] protected def flip (F : C ⥤ D ⥤ E) : D ⥤ C ⥤ E where obj k := { obj := fun j => (F.obj j).obj k, @@ -164,7 +164,7 @@ protected def flip (F : C ⥤ D ⥤ E) : D ⥤ C ⥤ E where /-- The left unitor, a natural isomorphism `((𝟭 _) ⋙ F) ≅ F`. -/ -@[simps] +@[implicit_reducible, simps] def leftUnitor (F : C ⥤ D) : 𝟭 C ⋙ F ≅ F where hom := { app := fun X => 𝟙 (F.obj X) } @@ -172,7 +172,7 @@ def leftUnitor (F : C ⥤ D) : /-- The right unitor, a natural isomorphism `(F ⋙ (𝟭 B)) ≅ F`. -/ -@[simps] +@[implicit_reducible, simps] def rightUnitor (F : C ⥤ D) : F ⋙ 𝟭 D ≅ F where hom := { app := fun X => 𝟙 (F.obj X) } @@ -183,7 +183,7 @@ def rightUnitor (F : C ⥤ D) : (In fact, `iso.refl _` will work here, but it tends to make Lean slow later, and it's usually best to insert explicit associators.) -/ -@[simps] +@[implicit_reducible, simps] def associator (F : C ⥤ D) (G : D ⥤ E) (H : E ⥤ E') : (F ⋙ G) ⋙ H ≅ F ⋙ G ⋙ H where hom := { app := fun _ => 𝟙 _ } @@ -196,7 +196,7 @@ end Functor variable (C D E) in /-- The functor `(C ⥤ D ⥤ E) ⥤ D ⥤ C ⥤ E` which flips the variables. -/ -@[simps] +@[implicit_reducible, simps] def flipFunctor : (C ⥤ D ⥤ E) ⥤ D ⥤ C ⥤ E where obj F := F.flip map {F₁ F₂} φ := diff --git a/Mathlib/CategoryTheory/Functor/Currying.lean b/Mathlib/CategoryTheory/Functor/Currying.lean index d003000bce6b9b..7824fb6c39bf46 100644 --- a/Mathlib/CategoryTheory/Functor/Currying.lean +++ b/Mathlib/CategoryTheory/Functor/Currying.lean @@ -54,6 +54,7 @@ def uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E where /-- The object level part of the currying functor. (See `curry` for the functorial version.) -/ +@[implicit_reducible] def curryObj (F : C × D ⥤ E) : C ⥤ D ⥤ E where obj X := { obj := fun Y => F.obj (X, Y) @@ -68,7 +69,7 @@ def curryObj (F : C × D ⥤ E) : C ⥤ D ⥤ E where /-- The currying functor, taking a functor `(C × D) ⥤ E` and producing a functor `C ⥤ (D ⥤ E)`. -/ -@[simps! obj_obj_obj obj_obj_map obj_map_app map_app_app] +@[implicit_reducible, simps! obj_obj_obj obj_obj_map obj_map_app map_app_app] def curry : (C × D ⥤ E) ⥤ C ⥤ D ⥤ E where obj F := curryObj F map T := @@ -81,12 +82,10 @@ def curry : (C × D ⥤ E) ⥤ C ⥤ D ⥤ E where ext; dsimp [curryObj] rw [NatTrans.naturality] } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in -- create projection simp lemmas even though this isn't a `{ .. }`. /-- The equivalence of functor categories given by currying/uncurrying. -/ -@[simps!] +@[implicit_reducible, simps!] def currying : C ⥤ D ⥤ E ≌ C × D ⥤ E where functor := uncurry inverse := curry @@ -98,10 +97,8 @@ def currying : C ⥤ D ⥤ E ≌ C × D ⥤ E where dsimp at f₁ f₂ ⊢ simp only [← F.map_comp, prod_comp, Category.comp_id, Category.id_comp])) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The equivalence of functor categories given by flipping. -/ -@[simps!] +@[implicit_reducible, simps!] def flipping : C ⥤ D ⥤ E ≌ D ⥤ C ⥤ E where functor := flipFunctor _ _ _ inverse := flipFunctor _ _ _ @@ -132,8 +129,6 @@ instance : (uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E).Full := instance : (uncurry : (C ⥤ D ⥤ E) ⥤ C × D ⥤ E).Faithful := fullyFaithfulUncurry.faithful -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- Given functors `F₁ : C ⥤ D`, `F₂ : C' ⥤ D'` and `G : D × D' ⥤ E`, this is the isomorphism between `curry.obj ((F₁.prod F₂).comp G)` and `F₁ ⋙ curry.obj G ⋙ (whiskeringLeft C' D' E).obj F₂` in the category `C ⥤ C' ⥤ E`. -/ @@ -144,37 +139,29 @@ def curryObjProdComp {C' D' : Type*} [Category* C'] [Category* D'] F₁ ⋙ curry.obj G ⋙ (whiskeringLeft C' D' E).obj F₂ := NatIso.ofComponents (fun X₁ ↦ NatIso.ofComponents (fun X₂ ↦ Iso.refl _)) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- `F.flip` is isomorphic to uncurrying `F`, swapping the variables, and currying. -/ -@[simps!] +@[implicit_reducible, simps!] def flipIsoCurrySwapUncurry (F : C ⥤ D ⥤ E) : F.flip ≅ curry.obj (Prod.swap _ _ ⋙ uncurry.obj F) := NatIso.ofComponents fun d => NatIso.ofComponents fun _ => Iso.refl _ -set_option backward.defeqAttrib.useBackward true in /-- The uncurrying of `F.flip` is isomorphic to swapping the factors followed by the uncurrying of `F`. -/ -@[simps!] +@[implicit_reducible, simps!] def uncurryObjFlip (F : C ⥤ D ⥤ E) : uncurry.obj F.flip ≅ Prod.swap _ _ ⋙ uncurry.obj F := NatIso.ofComponents fun _ => Iso.refl _ variable (B C D E) -#adaptation_note -/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in /-- A version of `CategoryTheory.whiskeringRight` for bifunctors, obtained by uncurrying, applying `whiskeringRight` and currying back -/ -@[simps!] +@[implicit_reducible, simps!] def whiskeringRight₂ : (C ⥤ D ⥤ E) ⥤ (B ⥤ C) ⥤ (B ⥤ D) ⥤ B ⥤ E := uncurry ⋙ whiskeringRight _ _ _ ⋙ (whiskeringLeft _ _ _).obj (prodFunctorToFunctorProd _ _ _) ⋙ curry variable {B C D E} -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in lemma uncurry_obj_curry_obj (F : B × C ⥤ D) : uncurry.obj (curry.obj F) = F := Functor.ext (by simp) (fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ ⟨f₁, f₂⟩ => by dsimp @@ -184,8 +171,6 @@ lemma curry_obj_injective {F₁ F₂ : C × D ⥤ E} (h : curry.obj F₁ = curry F₁ = F₂ := by rw [← uncurry_obj_curry_obj F₁, ← uncurry_obj_curry_obj F₂, h] -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in lemma curry_obj_uncurry_obj (F : B ⥤ C ⥤ D) : curry.obj (uncurry.obj F) = F := Functor.ext (fun _ => Functor.ext (by simp) (by simp)) (by cat_disch) @@ -199,16 +184,12 @@ lemma flip_injective {F₁ F₂ : B ⥤ C ⥤ D} (h : F₁.flip = F₂.flip) : F₁ = F₂ := by rw [← flip_flip F₁, ← flip_flip F₂, h] -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in lemma uncurry_obj_curry_obj_flip_flip (F₁ : B ⥤ C) (F₂ : D ⥤ E) (G : C × E ⥤ H) : uncurry.obj (F₂ ⋙ (F₁ ⋙ curry.obj G).flip).flip = (F₁.prod F₂) ⋙ G := Functor.ext (by simp) (fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ ⟨f₁, f₂⟩ => by dsimp simp only [Category.id_comp, Category.comp_id, ← G.map_comp, prod_comp]) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in lemma uncurry_obj_curry_obj_flip_flip' (F₁ : B ⥤ C) (F₂ : D ⥤ E) (G : C × E ⥤ H) : uncurry.obj (F₁ ⋙ (F₂ ⋙ (curry.obj G).flip).flip) = (F₁.prod F₂) ⋙ G := Functor.ext (by simp) (fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ ⟨f₁, f₂⟩ => by @@ -216,7 +197,7 @@ lemma uncurry_obj_curry_obj_flip_flip' (F₁ : B ⥤ C) (F₂ : D ⥤ E) (G : C simp only [Category.id_comp, Category.comp_id, ← G.map_comp, prod_comp]) /-- Natural isomorphism witnessing `comp_flip_uncurry_eq`. -/ -@[simps!] +@[implicit_reducible, simps!] def compFlipUncurryIso (F : B ⥤ D) (G : D ⥤ C ⥤ E) : uncurry.obj (F ⋙ G).flip ≅ (𝟭 C).prod F ⋙ uncurry.obj G.flip := .refl _ @@ -224,7 +205,7 @@ lemma comp_flip_uncurry_eq (F : B ⥤ D) (G : D ⥤ C ⥤ E) : uncurry.obj (F ⋙ G).flip = (𝟭 C).prod F ⋙ uncurry.obj G.flip := rfl /-- Natural isomorphism witnessing `comp_flip_curry_eq`. -/ -@[simps!] +@[implicit_reducible, simps!] def curryObjCompIso (F : C × B ⥤ D) (G : D ⥤ E) : (curry.obj (F ⋙ G)).flip ≅ (curry.obj F).flip ⋙ (whiskeringRight _ _ _).obj G := .refl _ @@ -233,7 +214,7 @@ lemma curry_obj_comp_flip (F : C × B ⥤ D) (G : D ⥤ E) : (curry.obj F).flip ⋙ (whiskeringRight _ _ _).obj G := rfl /-- The equivalence of types of bifunctors giving by flipping the arguments. -/ -@[simps!] +@[implicit_reducible, simps!] def flippingEquiv : C ⥤ D ⥤ E ≃ D ⥤ C ⥤ E where toFun F := F.flip invFun F := F.flip @@ -241,7 +222,7 @@ def flippingEquiv : C ⥤ D ⥤ E ≃ D ⥤ C ⥤ E where right_inv _ := rfl /-- The equivalence of types of bifunctors given by currying. -/ -@[simps!] +@[implicit_reducible, simps!] def curryingEquiv : C ⥤ D ⥤ E ≃ C × D ⥤ E where toFun F := uncurry.obj F invFun G := curry.obj G @@ -249,7 +230,7 @@ def curryingEquiv : C ⥤ D ⥤ E ≃ C × D ⥤ E where right_inv := uncurry_obj_curry_obj /-- The flipped equivalence of types of bifunctors given by currying. -/ -@[simps!] +@[implicit_reducible, simps!] def curryingFlipEquiv : D ⥤ C ⥤ E ≃ C × D ⥤ E := flippingEquiv.trans curryingEquiv diff --git a/Mathlib/CategoryTheory/Iso.lean b/Mathlib/CategoryTheory/Iso.lean index 24aca085030435..2cb81200230cc2 100644 --- a/Mathlib/CategoryTheory/Iso.lean +++ b/Mathlib/CategoryTheory/Iso.lean @@ -83,7 +83,7 @@ theorem ext ⦃α β : X ≅ Y⦄ (w : α.hom = β.hom) : α = β := _ = β.inv := by grind /-- Inverse isomorphism. -/ -@[symm] +@[symm, implicit_reducible] def symm (I : X ≅ Y) : Y ≅ X where hom := I.inv inv := I.hom @@ -112,7 +112,7 @@ theorem nonempty_iso_symm (X Y : C) : Nonempty (X ≅ Y) ↔ Nonempty (Y ≅ X) ⟨fun h => ⟨h.some.symm⟩, fun h => ⟨h.some.symm⟩⟩ /-- Identity isomorphism. -/ -@[refl, simps (attr := grind =)] +@[refl, simps (attr := grind =), implicit_reducible] def refl (X : C) : X ≅ X where hom := 𝟙 X inv := 𝟙 X @@ -127,7 +127,7 @@ theorem nonempty_iso_refl (X : C) : Nonempty (X ≅ X) := ⟨default⟩ theorem refl_symm (X : C) : (Iso.refl X).symm = Iso.refl X := rfl /-- Composition of two isomorphisms -/ -@[simps (attr := grind =)] +@[simps (attr := grind =), implicit_reducible] def trans (α : X ≅ Y) (β : Y ≅ Z) : X ≅ Z where hom := α.hom ≫ β.hom inv := β.inv ≫ α.inv @@ -219,7 +219,7 @@ theorem hom_eq_inv (α : X ≅ Y) (β : Y ≅ X) : α.hom = β.inv ↔ β.hom = attribute [local grind] Function.LeftInverse Function.RightInverse /-- The bijection `(Z ⟶ X) ≃ (Z ⟶ Y)` induced by `α : X ≅ Y`. -/ -@[to_dual (attr := simps) homFromEquiv +@[implicit_reducible, to_dual (attr := simps) homFromEquiv /-- The bijection `(X ⟶ Z) ≃ (Y ⟶ Z)` induced by `α : X ≅ Y`. -/] def homToEquiv (α : X ≅ Y) {Z : C} : (Z ⟶ X) ≃ (Z ⟶ Y) where toFun f := f ≫ α.hom @@ -469,7 +469,7 @@ variable {D : Type u₂} variable [Category.{v₂} D] /-- A functor `F : C ⥤ D` sends isomorphisms `i : X ≅ Y` to isomorphisms `F.obj X ≅ F.obj Y` -/ -@[simps] +@[simps, implicit_reducible] def mapIso (F : C ⥤ D) {X Y : C} (i : X ≅ Y) : F.obj X ≅ F.obj Y where hom := F.map i.hom inv := F.map i.inv diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index f5393261e2531f..23a505d37e266e 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -176,7 +176,7 @@ set_option linter.translate.warnInvalid false in /-- Construct a natural isomorphism between functors by giving object level isomorphisms, and checking naturality only in the forward direction. -/ -@[to_dual (attr := simps (attr := grind =)) ofComponents' +@[implicit_reducible, to_dual (attr := simps (attr := grind =)) ofComponents' /-- The dual of `ofComponents` -/] def ofComponents (app : ∀ X : C, F.obj X ≅ G.obj X) (naturality : ∀ {X Y : C} (f : X ⟶ Y), diff --git a/Mathlib/CategoryTheory/Products/Basic.lean b/Mathlib/CategoryTheory/Products/Basic.lean index 67dcaa8d157946..b528e8fa568ef5 100644 --- a/Mathlib/CategoryTheory/Products/Basic.lean +++ b/Mathlib/CategoryTheory/Products/Basic.lean @@ -171,36 +171,34 @@ def sectR {C : Type u₁} [Category.{v₁} C] (Z : C) (D : Type u₂) [Category. variable (C : Type u₁) [Category.{v₁} C] (D : Type u₂) [Category.{v₂} D] /-- `fst` is the functor `(X, Y) ↦ X`. -/ -@[simps] +@[implicit_reducible, simps] def fst : C × D ⥤ C where obj X := X.1 map f := f.1 /-- `snd` is the functor `(X, Y) ↦ Y`. -/ -@[simps] +@[implicit_reducible, simps] def snd : C × D ⥤ D where obj X := X.2 map f := f.2 /-- The functor swapping the factors of a Cartesian product of categories, `C × D ⥤ D × C`. -/ -@[simps] +@[implicit_reducible, simps] def swap : C × D ⥤ D × C where obj X := (X.2, X.1) map f := f.2 ×ₘ f.1 -set_option backward.defeqAttrib.useBackward true in /-- Swapping the factors of a Cartesian product of categories twice is naturally isomorphic to the identity functor. -/ -@[simps] +@[implicit_reducible, simps] def symmetry : swap C D ⋙ swap D C ≅ 𝟭 (C × D) where hom := { app := fun X => 𝟙 X } inv := { app := fun X => 𝟙 X } -set_option backward.defeqAttrib.useBackward true in /-- The equivalence, given by swapping factors, between `C × D` and `D × C`. -/ -@[simps] +@[implicit_reducible, simps] def braiding : C × D ≌ D × C where functor := swap C D inverse := swap D C @@ -243,16 +241,15 @@ def evaluation : C ⥤ (C ⥤ D) ⥤ D where /-- The "evaluation of `F` at `X`" functor, as a functor `C × (C ⥤ D) ⥤ D`. -/ -@[simps] +@[implicit_reducible, simps] def evaluationUncurried : C × (C ⥤ D) ⥤ D where obj p := p.2.obj p.1 map := fun {x} {y} f => x.2.map f.1 ≫ f.2.app y.1 variable {C} -set_option backward.defeqAttrib.useBackward true in /-- The constant functor followed by the evaluation functor is just the identity. -/ -@[simps!] +@[implicit_reducible, simps!] def Functor.constCompEvaluationObj (X : C) : Functor.const C ⋙ (evaluation C D).obj X ≅ 𝟭 D := NatIso.ofComponents fun _ => Iso.refl _ @@ -272,20 +269,18 @@ def prod (F : A ⥤ B) (G : C ⥤ D) : A × C ⥤ B × D where /- Because of limitations in Lean 3's handling of notations, we do not setup a notation `F × G`. You can use `F.prod G` as a "poor man's infix", or just write `functor.prod F G`. -/ /-- Similar to `prod`, but both functors start from the same category `A` -/ -@[simps] +@[implicit_reducible, simps] def prod' (F : A ⥤ B) (G : A ⥤ C) : A ⥤ B × C where obj a := (F.obj a, G.obj a) map f := F.map f ×ₘ G.map f -set_option backward.defeqAttrib.useBackward true in /-- The product `F.prod' G` followed by projection on the first component is isomorphic to `F` -/ -@[simps!] +@[implicit_reducible, simps!] def prod'CompFst (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.fst B C ≅ F := NatIso.ofComponents fun _ => Iso.refl _ -set_option backward.defeqAttrib.useBackward true in /-- The product `F.prod' G` followed by projection on the second component is isomorphic to `G` -/ -@[simps!] +@[implicit_reducible, simps!] def prod'CompSnd (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.snd B C ≅ G := NatIso.ofComponents fun _ => Iso.refl _ @@ -294,7 +289,7 @@ section variable (C) /-- The diagonal functor. -/ -@[simps! obj map] +@[implicit_reducible, simps! obj map] def diag : C ⥤ C × C := (𝟭 C).prod' (𝟭 C) @@ -304,36 +299,32 @@ end Functor namespace NatTrans -set_option backward.defeqAttrib.useBackward true in /-- The Cartesian product of two natural transformations. -/ -@[simps! app_fst app_snd] +@[implicit_reducible, simps! app_fst app_snd] def prod {F G : A ⥤ B} {H I : C ⥤ D} (α : F ⟶ G) (β : H ⟶ I) : F.prod H ⟶ G.prod I where app X := α.app X.1 ×ₘ β.app X.2 /- Again, it is inadvisable in Lean 3 to setup a notation `α × β`; use instead `α.prod β` or `NatTrans.prod α β`. -/ -set_option backward.defeqAttrib.useBackward true in /-- The Cartesian product of two natural transformations where both functors have the same source. -/ -@[simps! app_fst app_snd] +@[implicit_reducible, simps! app_fst app_snd] def prod' {F G : A ⥤ B} {H K : A ⥤ C} (α : F ⟶ G) (β : H ⟶ K) : F.prod' H ⟶ G.prod' K where app X := α.app X ×ₘ β.app X end NatTrans /-- The Cartesian product functor between functor categories -/ -@[simps] +@[implicit_reducible, simps] def prodFunctor : (A ⥤ B) × (C ⥤ D) ⥤ A × C ⥤ B × D where obj FG := FG.1.prod FG.2 map nm := NatTrans.prod nm.1 nm.2 namespace NatIso -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The Cartesian product of two natural isomorphisms. -/ -@[simps] +@[implicit_reducible, simps] def prod {F F' : A ⥤ B} {G G' : C ⥤ D} (e₁ : F ≅ F') (e₂ : G ≅ G') : F.prod G ≅ F'.prod G' where hom := NatTrans.prod e₁.hom e₂.hom @@ -343,10 +334,8 @@ end NatIso namespace Equivalence -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The Cartesian product of two equivalences of categories. -/ -@[simps] +@[implicit_reducible, simps] def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D where functor := E₁.functor.prod E₂.functor inverse := E₁.inverse.prod E₂.inverse @@ -355,18 +344,16 @@ def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D where end Equivalence -set_option backward.defeqAttrib.useBackward true in /-- `F.flip` composed with evaluation is the same as evaluating `F`. -/ -@[simps!] +@[implicit_reducible, simps!] def flipCompEvaluation (F : A ⥤ B ⥤ C) (a) : F.flip ⋙ (evaluation _ _).obj a ≅ F.obj a := NatIso.ofComponents fun b => Iso.refl _ theorem flip_comp_evaluation (F : A ⥤ B ⥤ C) (a) : F.flip ⋙ (evaluation _ _).obj a = F.obj a := rfl -set_option backward.defeqAttrib.useBackward true in /-- `F` composed with evaluation is the same as evaluating `F.flip`. -/ -@[simps!] +@[implicit_reducible, simps!] def compEvaluation (F : A ⥤ B ⥤ C) (b) : F ⋙ (evaluation _ _).obj b ≅ F.flip.obj b := NatIso.ofComponents fun a => Iso.refl _ @@ -374,7 +361,7 @@ theorem comp_evaluation (F : A ⥤ B ⥤ C) (b) : F ⋙ (evaluation _ _).obj b = rfl /-- Whiskering by `F` and then evaluating at `a` is the same as evaluating at `F.obj a`. -/ -@[simps!] +@[implicit_reducible, simps!] def whiskeringLeftCompEvaluation (F : A ⥤ B) (a : A) : (whiskeringLeft A B C).obj F ⋙ (evaluation A C).obj a ≅ (evaluation B C).obj (F.obj a) := Iso.refl _ @@ -387,7 +374,7 @@ theorem whiskeringLeft_comp_evaluation (F : A ⥤ B) (a : A) : /-- Whiskering by `F` and then evaluating at `a` is the same as evaluating at `F` and then applying `F`. -/ -@[simps!] +@[implicit_reducible, simps!] def whiskeringRightCompEvaluation (F : B ⥤ C) (a : A) : (whiskeringRight A B C).obj F ⋙ (evaluation _ _).obj a ≅ (evaluation _ _).obj a ⋙ F := Iso.refl _ @@ -402,39 +389,33 @@ theorem whiskeringRight_comp_evaluation (F : B ⥤ C) (a : A) : variable (A B C) /-- The forward direction for `functorProdFunctorEquiv` -/ -@[simps] +@[implicit_reducible, simps] def prodFunctorToFunctorProd : (A ⥤ B) × (A ⥤ C) ⥤ A ⥤ B × C where obj F := F.1.prod' F.2 map {F G} f := NatTrans.prod' f.1 f.2 /-- The backward direction for `functorProdFunctorEquiv` -/ -@[simps] +@[implicit_reducible, simps] def functorProdToProdFunctor : (A ⥤ B × C) ⥤ (A ⥤ B) × (A ⥤ C) where obj F := ⟨F ⋙ CategoryTheory.Prod.fst B C, F ⋙ CategoryTheory.Prod.snd B C⟩ map α := whiskerRight α _ ×ₘ whiskerRight α _ -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The unit isomorphism for `functorProdFunctorEquiv` -/ -@[simps!] +@[implicit_reducible, simps!] def functorProdFunctorEquivUnitIso : 𝟭 _ ≅ prodFunctorToFunctorProd A B C ⋙ functorProdToProdFunctor A B C := NatIso.ofComponents (fun F => Functor.prod'CompFst F.fst F.snd |>.prod (Functor.prod'CompSnd F.fst F.snd) |>.trans (prod.etaIso F) |>.symm) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The counit isomorphism for `functorProdFunctorEquiv` -/ -@[simps!] +@[implicit_reducible, simps!] def functorProdFunctorEquivCounitIso : functorProdToProdFunctor A B C ⋙ prodFunctorToFunctorProd A B C ≅ 𝟭 _ := NatIso.ofComponents fun F => NatIso.ofComponents fun X => prod.etaIso (F.obj X) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/ -@[simps] +@[implicit_reducible, simps] def functorProdFunctorEquiv : (A ⥤ B) × (A ⥤ C) ≌ A ⥤ B × C := { functor := prodFunctorToFunctorProd A B C, inverse := functorProdToProdFunctor A B C, @@ -446,7 +427,7 @@ section Opposite open Opposite /-- The equivalence between the opposite of a product and the product of the opposites. -/ -@[simps!] +@[implicit_reducible, simps!] def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ where functor := { obj := fun X ↦ ⟨op X.unop.1, op X.unop.2⟩, diff --git a/Mathlib/CategoryTheory/ShrinkYoneda.lean b/Mathlib/CategoryTheory/ShrinkYoneda.lean index e73c03841d3008..02d6f534fee045 100644 --- a/Mathlib/CategoryTheory/ShrinkYoneda.lean +++ b/Mathlib/CategoryTheory/ShrinkYoneda.lean @@ -36,16 +36,15 @@ protected abbrev Small (F : C ⥤ Type w') := ∀ (X : C), _root_.Small.{w} (F.o /-- If a functor `F : C ⥤ Type w'` is `w`-small, this is the functor `C ⥤ Type w` obtained by shrinking `F.obj X` for all `X : C`. -/ -@[simps obj map, pp_with_univ] +@[implicit_reducible, simps obj map, pp_with_univ] noncomputable def shrink (F : C ⥤ Type w') [FunctorToTypes.Small.{w} F] : C ⥤ Type w where obj X := Shrink.{w} (F.obj X) map f := ↾(equivShrink.{w} _ ∘ F.map f ∘ (equivShrink.{w} _).symm) -set_option backward.defeqAttrib.useBackward true in /-- The natural transformation `shrink.{w} F ⟶ shrink.{w} G` induces by a natural transformation `τ : F ⟶ G` between `w`-small functors to types. -/ -@[simps] +@[implicit_reducible, simps] noncomputable def shrinkMap {F G : C ⥤ Type w'} (τ : F ⟶ G) [FunctorToTypes.Small.{w} F] [FunctorToTypes.Small.{w} G] : shrink.{w} F ⟶ shrink.{w} G where @@ -75,7 +74,6 @@ set_option backward.defeqAttrib.useBackward true in instance (X : C) : FunctorToTypes.Small.{w} (yoneda.obj X) := fun _ ↦ by dsimp; infer_instance -set_option backward.isDefEq.respectTransparency.types false in /-- The Yoneda embedding `C ⥤ Cᵒᵖ ⥤ Type w` for a locally `w`-small category `C`. -/ @[simps -isSimp obj map, pp_with_univ] noncomputable def shrinkYoneda : @@ -385,7 +383,8 @@ noncomputable def fullyFaithfulShrinkCoyoneda : map_preimage f := by obtain ⟨f, rfl⟩ := shrinkCoyonedaEquiv.symm.surjective f cat_disch - preimage_map f := by simp [shrinkCoyonedaEquiv_shrinkCoyoneda_map] + preimage_map f := by + simp [shrinkCoyonedaEquiv_shrinkCoyoneda_map f] instance : (shrinkCoyoneda.{w} (C := C)).Faithful := (fullyFaithfulShrinkCoyoneda C).faithful diff --git a/Mathlib/CategoryTheory/Yoneda.lean b/Mathlib/CategoryTheory/Yoneda.lean index 43e3c2454267f4..0f43ae85c1bfc3 100644 --- a/Mathlib/CategoryTheory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Yoneda.lean @@ -39,7 +39,7 @@ universe w v v₁ v₂ u₁ u₂ variable {C : Type u₁} [Category.{v₁} C] /-- The Yoneda embedding, as a functor from `C` into presheaves on `C`. -/ -@[simps obj_obj obj_map map_app, stacks 001O] +@[implicit_reducible, simps obj_obj obj_map map_app, stacks 001O] def yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁ where obj X := { obj Y := (unop Y) ⟶ X @@ -720,6 +720,7 @@ variable {C} /-- We have a type-level equivalence between natural transformations from the yoneda embedding and elements of `F.obj X`, without any universe switching. -/ +@[implicit_reducible] def yonedaEquiv {X : C} {F : Cᵒᵖ ⥤ Type v₁} : (yoneda.obj X ⟶ F) ≃ F.obj (op X) where toFun η := η.app (op X) (𝟙 X) invFun ξ := { app _ := ↾fun f ↦ F.map f.op ξ } @@ -739,7 +740,7 @@ theorem yonedaEquiv_symm_app {X : C} {F : Cᵒᵖ ⥤ Type v₁} (x : F.obj (op rfl theorem yonedaEquiv_symm_app_apply {X : C} {F : Cᵒᵖ ⥤ Type v₁} (x : F.obj (op X)) (Y : Cᵒᵖ) - (f : Y.unop ⟶ X) : (yonedaEquiv.symm x).app Y f = F.map f.op x := + (f : Y.unop ⟶ X) : dsimp% (yonedaEquiv.symm x).app Y f = F.map f.op x := rfl /-- See also `yonedaEquiv_naturality'` for a more general version. -/ @@ -1000,6 +1001,7 @@ variable {C} /-- We have a type-level equivalence between natural transformations from the coyoneda embedding and elements of `F.obj X.unop`, without any universe switching. -/ +@[implicit_reducible] def coyonedaEquiv {X : C} {F : C ⥤ Type v₁} : (coyoneda.obj (op X) ⟶ F) ≃ F.obj X where toFun η := η.app X (𝟙 X) invFun ξ := { app _ := ↾fun x ↦ F.map x ξ } @@ -1014,7 +1016,7 @@ theorem coyonedaEquiv_apply {X : C} {F : C ⥤ Type v₁} (f : coyoneda.obj (op @[simp] theorem coyonedaEquiv_symm_app_apply {X : C} {F : C ⥤ Type v₁} (x : F.obj X) (Y : C) - (f : X ⟶ Y) : (coyonedaEquiv.symm x).app Y f = F.map f x := + (f : X ⟶ Y) : dsimp% (coyonedaEquiv.symm x).app Y f = F.map f x := rfl lemma coyonedaEquiv_naturality {X Y : C} {F : C ⥤ Type v₁} (f : coyoneda.obj (op X) ⟶ F) diff --git a/Mathlib/Combinatorics/Quiver/Basic.lean b/Mathlib/Combinatorics/Quiver/Basic.lean index 85d637707603e5..0fa3bb7291bfc9 100644 --- a/Mathlib/Combinatorics/Quiver/Basic.lean +++ b/Mathlib/Combinatorics/Quiver/Basic.lean @@ -55,11 +55,11 @@ instance opposite {V} [Quiver V] : Quiver Vᵒᵖ := ⟨fun a b => (unop b ⟶ unop a)ᵒᵖ⟩ /-- The opposite of an arrow in `V`. -/ -@[to_dual self] +@[implicit_reducible, to_dual self] def Hom.op {V} [Quiver V] {X Y : V} (f : X ⟶ Y) : op Y ⟶ op X := ⟨f⟩ /-- Given an arrow in `Vᵒᵖ`, we can take the "unopposite" back in `V`. -/ -@[to_dual self] +@[implicit_reducible, to_dual self] def Hom.unop {V} [Quiver V] {X Y : Vᵒᵖ} (f : X ⟶ Y) : unop Y ⟶ unop X := Opposite.unop f /-- The bijection `(X ⟶ Y) ≃ (op Y ⟶ op X)`. -/ diff --git a/MathlibTest/CategoryTheory/CheckDsimp.lean b/MathlibTest/CategoryTheory/CheckDsimp.lean new file mode 100644 index 00000000000000..f650ae10284d97 --- /dev/null +++ b/MathlibTest/CategoryTheory/CheckDsimp.lean @@ -0,0 +1,85 @@ +import Mathlib.CategoryTheory.NatIso +import Mathlib.CategoryTheory.Functor.Currying + +/-! +# Testing the `@[defeq]` attribute on some important equalities in category theory + +Category theory in mathlib relies heavily on the `dsimp` tactic to simplify terms +in dependent position. The `dsimp` tactic makes use of the `@[defeq]` attribute. +In lean v4.31.0, automatic tagging for this attribute was restricted to theorems that are type-correct +at `implicit_reducible` transparency. +An attribute `@[backward_defeq]` was added for theorems that are definitional equalities +but that do not type-check at `implicit_reducible` transparency. + +In practice, this means that many lemma generated `@[simps]` on semi-reducible `def`s +are not seen by `dsimp`, unless the option `set_option backward.defeqAttrib.useBackward` +is set to true. This is usually an indicator that the definition needs to be implicit-reducible. + +This test file ensures that some of the important "dsimplification" equalities in category +theory are tagged with `@[defeq]`. + +You should feel free to add more here when tagging definitions with `@[implicit_reducible]`. +-/ + +/-- Throwaway command for this test: `#ensure_defeq foo` returns an error if +the declaration `foo` does not have the `@[defeq]` tag (e.g., if it has +the `@[backward_defeq]` tag instead). -/ +syntax (name := ensureDefeqCmd) "#ensure_defeq " ident : command + +open Lean in +elab_rules : command + | `(command| #ensure_defeq $ident:ident) => do + let name := ident.getId + let env ← getEnv + match env.find? name with + | ConstantInfo.thmInfo _ => + if defeqAttr.hasTag env name then + logInfo m!"`{.ofConstName name}` is tagged with @[defeq]" + return () + else if backwardDefeqAttr.hasTag env name then + throwError "`{.ofConstName name}` is tagged with @[backward_defeq] instead of @[defeq]!" + else + throwError "`{.ofConstName name}` is not tagged @[defeq] nor @[backward_defeq]!" + | none => throwError "Unknown identifier `{.ofConstName name}`" + | _ => throwError "#ensure_defeq can only be run on equality theorems." + +-- intentional error to test the command +/-- error: `CategoryTheory.Category.assoc` is not tagged @[defeq] nor @[backward_defeq]! -/ +#guard_msgs (error) in +#ensure_defeq CategoryTheory.Category.assoc + +/-- info: `CategoryTheory.NatIso.ofComponents_hom_app` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.NatIso.ofComponents_hom_app + +/-- info: `CategoryTheory.Iso.trans_hom` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Iso.trans_hom + +/-- info: `CategoryTheory.Functor.comp_map` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.comp_map + +/-- info: `CategoryTheory.Functor.comp_obj` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.comp_obj + +/-- info: `CategoryTheory.Functor.curry_obj_obj_obj` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.curry_obj_obj_obj + +/-- info: `CategoryTheory.Functor.uncurry_obj_obj` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.uncurry_obj_obj + +/-- info: `CategoryTheory.Functor.associator_hom_app` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.associator_hom_app + +/-- info: `CategoryTheory.Functor.leftUnitor_hom_app` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.leftUnitor_hom_app + +/-- info: `CategoryTheory.Functor.rightUnitor_hom_app` is tagged with @[defeq] -/ +#guard_msgs in +#ensure_defeq CategoryTheory.Functor.rightUnitor_hom_app From b44f89d15d463ede557bdf673707a8610210becf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Sun, 26 Jul 2026 17:38:35 +0000 Subject: [PATCH 1013/1300] chore(Tactic/Translate): remove the deprecated `@[to_additive "docstring"]` syntax (#41886) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Tactic/Translate/Core.lean | 32 ++++----------------- MathlibTest/Attribute/ToAdditive/Basic.lean | 27 ++--------------- 2 files changed, 8 insertions(+), 51 deletions(-) diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 2c7b61fedf3d9f..6e8393352184f4 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -111,7 +111,7 @@ syntax bracketedOption := "(" attrOption <|> reorderOption <|> syntax translationHint := (ppSpace (&"existing" <|> &"self" <|> &"none"))? syntax attrArgs := - translationHint (ppSpace bracketedOption)* (ppSpace ident)? (ppSpace (str <|> docComment))? + translationHint (ppSpace bracketedOption)* (ppSpace ident)? (ppSpace docComment)? -- We omit a doc-string on these syntaxes to instead show the `to_additive` or `to_dual` doc-string attribute [nolint docBlame] attrArgs bracketedOption @@ -319,7 +319,7 @@ structure Config : Type where and the translate tactic auto-generates a name instead -/ target : Name := Name.anonymous /-- An optional doc string. -/ - doc : Option String := .none + doc : Option (TSyntax ``Lean.Parser.Command.docComment) := .none /-- If `allowAutoName` is `false` (default) then we check whether the given name can be auto-generated. -/ allowAutoName : Bool := false @@ -1151,30 +1151,6 @@ def elabTranslationAttr (declName : Name) (stx : Syntax) : CoreM Config := do Instead, you can write the attributes in the usual way." trace[translate_detail] "attributes: {attrs}; reorder arguments: {reorder?.elim "none" (·.toString)}" - let doc ← doc.mapM fun - | `(str|$doc:str) => open Linter in do - -- Deprecate `str` docstring syntax (since := "2025-08-12") - if getLinterValue linter.deprecated (← getLinterOptions) then - let hintSuggestion := { - diffGranularity := .none - toTryThisSuggestion := { suggestion := "/-- " ++ doc.getString.trimAscii ++ " -/" } - } - let sugg ← Hint.mkSuggestionsMessage #[hintSuggestion] doc - (codeActionPrefix? := "Update to: ") (forceList := false) - logWarningAt doc <| .tagged ``Linter.deprecatedAttr - m!"String syntax for `to_additive` docstrings is deprecated: Use \ - docstring syntax instead (e.g. `@[to_additive /-- example -/]`)\n\ - \n\ - Update deprecated syntax to:{sugg}" - return doc.getString - | `(docComment|$doc:docComment) => do - -- TODO: rely on `addDocString`s call to `validateDocComment` after removing `str` support - validateDocComment doc - /- Note: the following replicates the behavior of `addDocString`. However, this means that - trailing whitespace might appear in docstrings added via `docComment` syntax when compared - to those added via `str` syntax. See this [Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Why.20do.20docstrings.20include.20trailing.20whitespace.3F/with/533553356). -/ - return (← getDocStringText doc).removeLeadingSpaces - | _ => throwUnsupportedSyntax return { trace := !stx[1].isNone target := match tgt with | some tgt => tgt.getId | _ => Name.anonymous @@ -1299,7 +1275,9 @@ partial def addTranslationAttr (t : TranslateData) (src : Name) (cfg : Config) -- tgt doesn't exist, so let's make it transformDeclRec t cfg src tgt src reorder cfg.rename if let some doc := cfg.doc then - addDocStringCore tgt doc + -- TODO: `Syntax.missing` means we do not add binders to the context, + -- so the docstring is going to have incomplete syntax highlighting. + addDocString tgt Syntax.missing doc |>.run'.run' let nestedNames ← copyMetaData t cfg src tgt -- add pop-up information when mousing over the given translated name -- (the information will be over the attribute if no translated name is given) diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index f9ee3c8b408e4a..2be7a076c0153c 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -691,35 +691,14 @@ warning: `to_additive` did not change the type of theorem `mulTrivial`. Please r Note: This linter can be disabled with `set_option linter.translateRedundant false` -/ #guard_msgs in -@[to_additive /-- (via `docComment` syntax) I am an additive docstring! -/] +@[to_additive /-- I am an additive docstring! -/] theorem mulTrivial : True := trivial -/-- info: (via `docComment` syntax) I am an additive docstring! -/ +/-- info: I am an additive docstring! -/ #guard_msgs in run_cmd let some doc ← findDocString? (← getEnv) ``addTrivial - | throwError "no `docComment` docstring found" - logInfo doc - -/-- -warning: String syntax for `to_additive` docstrings is deprecated: Use docstring syntax instead (e.g. `@[to_additive /-- example -/]`) - -Update deprecated syntax to: - [apply] /-- (via `str` syntax) I am an additive docstring! -/ ---- -warning: `to_additive` did not change the type of theorem `mulTrivial'`. Please remove the attribute. - -Note: This linter can be disabled with `set_option linter.translateRedundant false` --/ -#guard_msgs in -@[to_additive "(via `str` syntax) I am an additive docstring!"] -theorem mulTrivial' : True := trivial - -/-- info: (via `str` syntax) I am an additive docstring! -/ -#guard_msgs in -run_cmd - let some doc ← findDocString? (← getEnv) ``addTrivial' - | throwError "no `str` docstring found" + | throwError "no docstring found" logInfo doc /-! Test handling of noncomputability -/ From 6996953ff19302c064889c4d5f5c73671339c488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hagb=20=28Junyu=20Guo=20=E9=83=AD=E4=BF=8A=E4=BD=99=29?= Date: Sun, 26 Jul 2026 22:09:15 +0000 Subject: [PATCH 1014/1300] =?UTF-8?q?feat(RingTheory/MvPolynomial/Monomial?= =?UTF-8?q?Order):=20add=20degree=20with=20`=E2=8A=A5`=20as=20degree=20of?= =?UTF-8?q?=20`0`=20(#34759)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `withBotDegree` is to distinguish the degree of zero polynomial from the degree of non-zero constant polynomial. `MonomialOrder.degree` of both are 0, while `withBotDegree` is `⊥` for zero polynomial and 0 for non-zero constant polynomial. Some lemmas, such as $\mathrm{degree} (p * q) = \mathrm{degree}(p) + \mathrm{degree}(q)$, hold on edge cases where $p=0$ or $q=0$ under `MonomialOrder.withBotDegree` but not `MonomialOrder.degree`. `MonomialOrder.withBotDegree` is to `MonomialOrder.degree` as `Polynomial.degree` is to `Polynomial.natDegree`. It's upstreamized from https://github.com/WuProver/groebner_proj. --- Mathlib/Data/Finsupp/MonomialOrder.lean | 42 ++++ .../MvPolynomial/MonomialOrder.lean | 207 +++++++++++++++++- 2 files changed, 247 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Finsupp/MonomialOrder.lean b/Mathlib/Data/Finsupp/MonomialOrder.lean index 551bdf44f3d4e2..9e49002bae721c 100644 --- a/Mathlib/Data/Finsupp/MonomialOrder.lean +++ b/Mathlib/Data/Finsupp/MonomialOrder.lean @@ -8,6 +8,7 @@ module public import Mathlib.Data.Finsupp.Lex public import Mathlib.Data.Finsupp.WellFounded public import Mathlib.Data.List.TFAE +public import Mathlib.Algebra.Order.Monoid.Unbundled.WithTop /-! # Monomial orders @@ -95,6 +96,9 @@ instance isOrderedCancelAddMonoid_syn : IsOrderedCancelAddMonoid m.syn := @[deprecated (since := "2026-07-07")] alias iocam := MonomialOrder.isOrderedCancelAddMonoid_syn +/-- A `WithBot m.syn` version of `m.toSyn`. -/ +noncomputable def toWithBotSyn : WithBot (σ →₀ ℕ) ≃+ WithBot m.syn := m.toSyn.withBotCongr + lemma le_add_right (a b : σ →₀ ℕ) : m.toSyn a ≤ m.toSyn a + m.toSyn b := by rw [← map_add] @@ -123,6 +127,32 @@ lemma toSyn_lt_iff_ne_zero {a : m.syn} : lemma toSyn_strictMono : StrictMono (m.toSyn) := by apply m.toSyn_monotone.strictMono_of_injective m.toSyn.injective +@[simp] +lemma toWithBotSyn_apply_bot : m.toWithBotSyn ⊥ = ⊥ := rfl + +@[simp] +lemma toWithBotSyn_symm_apply_bot : m.toWithBotSyn.symm ⊥ = ⊥ := rfl + +@[simp] +lemma toWithBotSyn_apply_eq_bot_iff (a) : m.toWithBotSyn a = ⊥ ↔ a = ⊥ := by + simp [← m.toWithBotSyn.eq_symm_apply] + +lemma toWithBotSyn_apply_le_bot_iff (a) : m.toWithBotSyn a ≤ ⊥ ↔ a = ⊥ := by + simp + +@[simp] +lemma toWithBotSyn_apply_coe (a : σ →₀ ℕ) : m.toWithBotSyn a = m.toSyn a := rfl + +@[simp] +lemma bot_lt_toWithBotSyn_apply_iff (a) : ⊥ < m.toWithBotSyn a ↔ ⊥ < a := by + simp [bot_lt_iff_ne_bot] + +@[simp] +lemma toWithBotSyn_symm_apply_eq_bot (a) : m.toWithBotSyn.symm a = ⊥ ↔ a = ⊥ := by + simp [m.toWithBotSyn.symm_apply_eq] + +lemma toWithBotSyn_apply (a : WithBot (σ →₀ ℕ)) : m.toWithBotSyn a = a.map m.toSyn := rfl + /-- Given a monomial order, notation for the corresponding strict order relation on `σ →₀ ℕ` -/ scoped notation:50 c " ≺[" m:25 "] " d:50 => (MonomialOrder.toSyn m c < MonomialOrder.toSyn m d) @@ -131,6 +161,18 @@ notation:50 c " ≺[" m:25 "] " d:50 => (MonomialOrder.toSyn m c < MonomialOrder scoped notation:50 c " ≼[" m:25 "] " d:50 => (MonomialOrder.toSyn m c ≤ MonomialOrder.toSyn m d) +/-- Given a monomial order with bot, notation for the corresponding strict order relation on +`WithBot (σ →₀ ℕ)` -/ +scoped +notation:50 c " ≺'[" m:25 "] " d:50 => + (MonomialOrder.toWithBotSyn m c < MonomialOrder.toWithBotSyn m d) + +/-- Given a monomial order with bot, notation for the corresponding order relation on +`WithBot (σ →₀ ℕ)` -/ +scoped +notation:50 c " ≼'[" m:25 "] " d:50 => + (MonomialOrder.toWithBotSyn m c ≤ MonomialOrder.toWithBotSyn m d) + end MonomialOrder section Lex diff --git a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean index 049f199d565e02..4a110d6e962668 100644 --- a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean +++ b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean @@ -16,7 +16,9 @@ public import Mathlib.RingTheory.MvPolynomial.Homogeneous We consider a type `σ` of indeterminates and a commutative semiring `R` and a monomial order `m : MonomialOrder σ`. -* `m.degree f` is the degree of `f` for the monomial ordering `m`. +* `m.degree f` is the degree of `f` for the monomial ordering `m`, where the polynomial `0` has + degree `0`. For the variant mapping polynomial `0` to `⊥` which is less than `0`, see + `MonomialOrder.withBotDegree`. * `m.leadingCoeff f` is the leading coefficient of `f` for the monomial ordering `m`. @@ -26,6 +28,10 @@ and a monomial order `m : MonomialOrder σ`. * `m.sPolynomial f g` is S-polynomial of `f` and `g`. +* `m.withBotDegree f` is the degree of `f` for the monomial ordering `m`, where the polynomial `0` + has degree `⊥`, which is not equal to `0`. `MonomialOrder.withBotDegree` is to + `MonomialOrder.degree` as `Polynomial.degree` is to `Polynomial.natDegree`. + * `m.leadingCoeff_ne_zero_iff f` asserts that this coefficient is nonzero iff `f ≠ 0`. * in a field, `m.isUnit_leadingCoeff f` asserts that this coefficient is a unit iff `f ≠ 0`. @@ -104,7 +110,9 @@ section Semiring variable {R : Type*} [CommSemiring R] variable (m) in -/-- the degree of a multivariate polynomial with respect to a monomial ordering -/ +/-- the degree of a multivariate polynomial with respect to a monomial ordering, where the +polynomial `0` has degree `0`. For the variant mapping polynomial `0` to `⊥` which is less than +`0`, see `MonomialOrder.withBotDegree`. -/ noncomputable def degree (f : MvPolynomial σ R) : σ →₀ ℕ := m.toSyn.symm (f.support.sup m.toSyn) @@ -836,6 +844,195 @@ lemma mem_nonZeroDivisors_of_leadingCoeff_mem_nonZeroDivisors simp [← m.leadingCoeff_eq_zero_iff (f := f * g), m.leadingCoeff_mul_of_left_mem_nonZeroDivisors hf, mul_left_mem_nonZeroDivisors_eq_zero_iff hf] +section withBotDegree + +variable (f g : MvPolynomial σ R) + +variable (m) in +/-- the degree of a multivariate polynomial with respect to a monomial ordering, where polynomial +`0` has degree `⊥`, which is not equal to `0`. `MonomialOrder.withBotDegree` is to +`MonomialOrder.degree` as `Polynomial.degree` is to `Polynomial.natDegree`. -/ +noncomputable def withBotDegree : WithBot (σ →₀ ℕ) := + f.support.image m.toSyn |>.max.map m.toSyn.symm + +lemma withBotDegree_eq [Decidable (f = 0)] : + m.withBotDegree f = if f = 0 then ⊥ else ↑(m.degree f) := by + simp [withBotDegree, degree] + by_cases hf : f = 0 + · simp [hf] + · simp [hf, Finset.max_eq_sup_coe, ← Finset.coe_sup_of_nonempty _ (⇑m.toSyn)] + +@[simp] +lemma withBotDegree_eq_coe_degree_iff : m.withBotDegree f = m.degree f ↔ f ≠ 0 := by + classical + simp [withBotDegree_eq] + +@[simp] +lemma withBotDegree_eq_bot_iff : m.withBotDegree f = ⊥ ↔ f = 0 := by + classical + simp [withBotDegree_eq] + +lemma degree_eq_unbotD_withBotDegree : m.degree f = (m.withBotDegree f).unbotD 0 := by + classical + by_cases h : f = 0 <;> simp [withBotDegree_eq, h] + +@[simp] +lemma withBotDegree_zero : m.withBotDegree (R := R) 0 = ⊥ := rfl + +lemma withBotDegree_monomial (d) (c) [Decidable (c = 0)] : + m.withBotDegree (R := R) (monomial d c) = if c = 0 then ⊥ else ↑d := by + classical + split_ifs <;> simp [withBotDegree_eq, *, m.degree_monomial] + +lemma withBotDegree_C (c) [Decidable (c = 0)] : + m.withBotDegree (R := R) (C c) = if c = 0 then ⊥ else 0 := by + simp [← monomial_zero', withBotDegree_monomial] + +@[simp] +lemma withBotDegree_leadingTerm : m.withBotDegree (m.leadingTerm f) = m.withBotDegree f := by + classical + simp [withBotDegree_eq] + +@[simp] +lemma withBotDegree_one [Nontrivial R] : m.withBotDegree (R := R) 1 = 0 := by + classical + simp [withBotDegree_eq] + +variable {f g} in +lemma withBotDegree_mul_of_left_mem_nonZeroDivisors (hf : m.leadingCoeff f ∈ nonZeroDivisors _) : + m.withBotDegree (f * g) = m.withBotDegree f + m.withBotDegree g := by + classical + by_cases! h0 : f = 0 ∨ g = 0 + · rcases h0 with h0 | h0 <;> simp [h0] + suffices f * g ≠ 0 by simp [withBotDegree_eq, m.degree_mul_of_left_mem_nonZeroDivisors hf, *] + apply mem_nonZeroDivisors_of_leadingCoeff_mem_nonZeroDivisors at hf + rw [mem_nonZeroDivisors_iff_left] at hf + tauto + +variable {f g} in +lemma withBotDegree_mul_of_right_mem_nonZeroDivisors (hf : m.leadingCoeff g ∈ nonZeroDivisors _) : + m.withBotDegree (f * g) = m.withBotDegree f + m.withBotDegree g := by + rw [mul_comm, add_comm, withBotDegree_mul_of_left_mem_nonZeroDivisors (hf := hf)] + +@[simp] +lemma withBotDegree_mul [NoZeroDivisors R] : + m.withBotDegree (f * g) = m.withBotDegree f + m.withBotDegree g := by + nontriviality R using Subsingleton.eq_zero (α := MvPolynomial σ R) + by_cases! hf : f = 0 + · simp [hf] + rw [← m.leadingCoeff_ne_zero_iff, ← mem_nonZeroDivisors_iff_ne_zero] at hf + exact m.withBotDegree_mul_of_left_mem_nonZeroDivisors hf + +lemma withBotDegree_mul_le : + m.withBotDegree (f * g) ≼'[m] m.withBotDegree f + m.withBotDegree g := by + by_cases! h0 : f * g = 0 + · simp [h0] + simp [-map_add, m.withBotDegree_eq_coe_degree_iff _ |>.mpr h0, + m.withBotDegree_eq_coe_degree_iff f |>.mpr (by grind), + m.withBotDegree_eq_coe_degree_iff g |>.mpr (by grind), ← WithBot.coe_add, m.degree_mul_le] + +lemma toWithBotSyn_withBotDegree_mul_le : + m.toWithBotSyn (m.withBotDegree (f * g)) ≤ + m.toWithBotSyn (m.withBotDegree f) + m.toWithBotSyn (m.withBotDegree g) := by + by_cases h0 : f * g = 0 + · simp [h0] + simp [m.withBotDegree_eq_coe_degree_iff f |>.mpr (by grind), + m.withBotDegree_eq_coe_degree_iff g |>.mpr (by grind), + m.withBotDegree_eq_coe_degree_iff _ |>.mpr h0, ← WithBot.coe_add, + m.toSyn_degree_mul_le] + +lemma withBotDegree_le_withBotDegree_iff : + m.withBotDegree f ≼'[m] m.withBotDegree g ↔ + (m.degree f ≼[m] m.degree g ∧ (g = 0 → f = 0)) := by + classical + by_cases! +distrib h : f ≠ 0 ∧ g ≠ 0 + · simp [m.withBotDegree_eq, h, m.toWithBotSyn_apply] + rcases h with h | _ + · simp [h] + · aesop + +variable {g} in +lemma withBotDegree_le_withBotDegree_iff_of_ne_zero (hg : g ≠ 0) : + m.withBotDegree f ≼'[m] m.withBotDegree g ↔ m.degree f ≼[m] m.degree g := by + simp [withBotDegree_le_withBotDegree_iff, hg] + +lemma withBotDegree_lt_withBotDegree_iff : + m.withBotDegree f ≺'[m] m.withBotDegree g ↔ + (m.degree f ≺[m] m.degree g ∨ (f = 0 ∧ g ≠ 0)) := by + classical + by_cases! hg : g = 0 + · simp_rw [toWithBotSyn_apply] + aesop + by_cases! hf : f = 0 + · simp [hg, hf, bot_lt_iff_ne_bot, toWithBotSyn_apply] + simp [withBotDegree_eq, hf, hg, toWithBotSyn_apply] + +variable {f} in +lemma withBotDegree_lt_withBotDegree_iff_of_ne_zero (hf : f ≠ 0) : + m.withBotDegree f ≺'[m] m.withBotDegree g ↔ m.degree f ≺[m] m.degree g := by + simp [withBotDegree_lt_withBotDegree_iff, hf] + +lemma withBotDegree_eq_withBotDegree_iff : + m.withBotDegree f = m.withBotDegree g ↔ (m.degree f = m.degree g ∧ (f = 0 ↔ g = 0)) := by + classical + by_cases! +distrib h : f ≠ 0 ∧ g ≠ 0 + · simp [h, m.withBotDegree_eq] + rcases h with h | h + all_goals + simp_rw [h] + revert f g + simp [m.withBotDegree_eq, m.degree_zero] + +lemma withBotDegree_add_le : + (m.toWithBotSyn <| m.withBotDegree (f + g)) ≤ + (m.toWithBotSyn <| m.withBotDegree f) ⊔ (m.toWithBotSyn <| m.withBotDegree g) := by + by_cases! h : f = 0 ∨ g = 0 + · rcases h with h | h <;> simp [h, m.toWithBotSyn_apply] + simpa [withBotDegree_le_withBotDegree_iff, h] using degree_add_le (R := R) + +variable {f g} in +lemma withBotDegree_add_of_lt (h : m.withBotDegree g ≺'[m] m.withBotDegree f) : + m.withBotDegree (f + g) = m.withBotDegree f := by + by_cases hg : g = 0 + · simp [hg] + simp only [withBotDegree_lt_withBotDegree_iff, hg, ne_eq, false_and, or_false] at h + simp only [withBotDegree_eq_withBotDegree_iff, show f ≠ 0 by contrapose h; simp [h], iff_false] + apply (show ∀ {p q}, p → (p → q) → (p ∧ q) by tauto) (m.degree_add_of_lt h) + intro h' + contrapose! h + simp [← h', h] + +variable {f g} in +lemma withBotDegree_add_of_right_lt (h : m.withBotDegree f ≺'[m] m.withBotDegree g) : + m.withBotDegree (f + g) = m.withBotDegree g := by + rw [add_comm, withBotDegree_add_of_lt h] + +lemma withBotDegree_sum_le {α : Type*} {s : Finset α} {f : α → MvPolynomial σ R} : + (m.toWithBotSyn <| m.withBotDegree <| ∑ x ∈ s, f x) ≤ + s.sup fun x ↦ (m.toWithBotSyn <| m.withBotDegree <| f x) := by + induction s using Finset.cons_induction_on with + | empty => simp + | cons a s haA h => + rw [Finset.sum_cons, Finset.sup_cons] + exact le_trans (m.withBotDegree_add_le _ _) (max_le_max le_rfl h) + +variable {f} in +lemma le_withBotDegree {d : σ →₀ ℕ} (hd : d ∈ f.support) : + d ≼'[m] m.withBotDegree f := by + classical + simp [withBotDegree_eq, toWithBotSyn_apply, ne_zero_iff.mpr ⟨d, by simpa using hd⟩, le_degree hd] + +variable {f g} in +lemma withBotDegree_le_withBotDegree_of_support_subset + (h : f.support ⊆ g.support) : + m.withBotDegree f ≼'[m] m.withBotDegree g := by + by_cases hg : g = 0 + · simpa [hg] using h + rw [m.withBotDegree_le_withBotDegree_iff_of_ne_zero _ hg] + exact m.degree_le_degree_of_support_subset h + +end withBotDegree + end Semiring section Ring @@ -1090,6 +1287,12 @@ lemma sPolynomial_decomposition {d : m.syn} {ι : Type*} obtain (⟨h, -⟩ | h) := hd b' hb' <;> simp [h, ← smul_eq_C_mul, smul_sub, ← mul_smul, mul_comm (m.leadingCoeff (g b'))] +@[simp] +lemma withBotDegree_neg (f : MvPolynomial σ R) : + m.withBotDegree (-f) = m.withBotDegree f := by + classical + simp [m.withBotDegree_eq] + end Ring section Field From 65fe2a1f85b506b0ef7df1990697be5a1ad64317 Mon Sep 17 00:00:00 2001 From: JX-Mo <296066944+JX-Mo@users.noreply.github.com> Date: Mon, 27 Jul 2026 06:35:14 +0000 Subject: [PATCH 1015/1300] fix(CategoryTheory): correct docstring about preservation of epimorphisms (#42065) Correct docstring about preservation of epimorphisms. --- Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean b/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean index 8bd387dfa40524..e1cef58eecbba5 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective/Preserves.lean @@ -12,7 +12,7 @@ public import Mathlib.CategoryTheory.Preadditive.Projective.Basic We define a typeclass `Functor.PreservesProjectiveObjects`. -We restate the existing result that if `F ⊣ G` is an adjunction and `G` preserves monomorphisms, +We restate the existing result that if `F ⊣ G` is an adjunction and `G` preserves epimorphisms, then `F` preserves projective objects. We show that the converse is true if the domain of `F` has enough projectives. -/ From 1a1a7c154755bbd9c9c092cc41c820bbdbb79e66 Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Mon, 27 Jul 2026 08:26:22 +0000 Subject: [PATCH 1016/1300] fix(Tactic/NormDet): make norm_det proofs compatible with modules (#42119) The proofs produced by the `norm_det` / `eval_det` simproc (added in #42059) could not be checked from within a `module` because the generated proofs depended on kernel checking of equalities for definitions (`Array.ofFn`, and `certEntry`, `certIterStepEntry` from the Bird determinant certificate evaluator) which are not exposed. The existing tests in `MathlibTest/matrix.lean` did not detect this issue because it was not a `module` itself. This PR: * Fixes the issues resulting from non-exposed definitions * Makes the `MathlibTest/matrix.lean` file into a module * Adds proofs for the determinants of Cartan matrices `LinearAlgebra/Matrix/Cartan` using `norm_det` - showing that the simrproc can be used in mathlib modules. The function `normalizeDetFromEntries` generated a proof which related the matrix array literal to `Array.ofFn fun k => A k.divNat k.modNat` by an unchecked `=Q` equality. This cannot be checked by the kernel because `Array.ofFn` is not exposed. The solution here is to use `List.ofFn` instead, which is exposed. Similarly, the functions `certEntry` and `certIterStepEntry` in the Bird determinant certificate evaluator relied on definitional unfolding of `BirdDet.get` and `BirdDet.stepEntry` which are not exposed. The generated proofs now use the unfolding lemmas `BirdDet.get_eq` and `BirdDet.stepEntry_eq` instead. --- Mathlib/LinearAlgebra/Matrix/Cartan.lean | 15 ++++++++------- Mathlib/Tactic/Determinant/Bird/Cert.lean | 12 ++++++++---- Mathlib/Tactic/NormDet.lean | 16 ++++++++++------ MathlibTest/matrix.lean | 12 +++++++++--- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Cartan.lean b/Mathlib/LinearAlgebra/Matrix/Cartan.lean index c0fe19186c6bf3..bb65489455b596 100644 --- a/Mathlib/LinearAlgebra/Matrix/Cartan.lean +++ b/Mathlib/LinearAlgebra/Matrix/Cartan.lean @@ -10,6 +10,7 @@ public import Mathlib.LinearAlgebra.Matrix.Notation public import Mathlib.GroupTheory.Perm.Cycle.Concrete public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic public import Mathlib.LinearAlgebra.Matrix.Symmetric +import Mathlib.Tactic.NormDet /-! # Cartan matrices @@ -257,16 +258,16 @@ theorem G₂_det : G₂.det = 1 := by decide theorem F₄_det : F₄.det = 1 := by decide -/-! The determinants of E₆, E₇, E₈ are 3, 2, 1 respectively. -`decide` fails for these larger matrices without increasing the max recursion depth. -We could write manual proofs (e.g., expanding via `det_succ_column_zero`), -but prefer to wait for a more principled determinant tactic. -/ +/-! The determinants of E₆, E₇, E₈ are 3, 2, 1 respectively. -/ -proof_wanted E₆_det : E₆.det = 3 +theorem E₆_det : E₆.det = 3 := by + simp only [E₆, norm_det] -proof_wanted E₇_det : E₇.det = 2 +theorem E₇_det : E₇.det = 2 := by + simp only [E₇, norm_det] -proof_wanted E₈_det : E₈.det = 1 +theorem E₈_det : E₈.det = 1 := by + simp only [E₈, norm_det] /-- A Cartan matrix is simply laced if its off-diagonal entries are all `0` or `-1`. -/ def _root_.Matrix.IsSimplyLaced {ι : Type*} (A : Matrix ι ι ℤ) : Prop := diff --git a/Mathlib/Tactic/Determinant/Bird/Cert.lean b/Mathlib/Tactic/Determinant/Bird/Cert.lean index 4be7b7d4ab6fd0..33493a3b404957 100644 --- a/Mathlib/Tactic/Determinant/Bird/Cert.lean +++ b/Mathlib/Tactic/Determinant/Bird/Cert.lean @@ -235,9 +235,11 @@ def certEntry (i j : ℕ) : CertM rα (Cert rα) := do let idx := dim * i + j let entry := arrayEntries.getD idx q(0) let ce ← certEval entry - have : $lhs =Q $entry := ⟨⟩ - let h : Q($lhs = $entry) := q(rfl) - let cert := ce.chainProof h + let getD : Q($α) := q(Array.getD $A ($dimLit * $i + $j) 0) + let hGet : Q($lhs = $getD) := q(BirdDet.get_eq $dimLit $A $i $j) + have : $getD =Q $entry := ⟨⟩ + let hGetD : Q($getD = $entry) := q(rfl) + let cert := ce.chainProof q(Eq.trans $hGet $hGetD) modify fun s => {s with entryCache := s.entryCache.insert (i, j) cert} return cert @@ -316,10 +318,12 @@ partial def certIterStepEntry (t i j : ℕ) : CertM rα (Cert rα) := do -- sumFrom n (i + 1) fun k => F_t i k * get n A k j let tailSumCert ← certTail t' i j (i + 1) let rhsCert ← certAdd diagProdCert tailSumCert + let hStep := q(BirdDet.stepEntry_eq $dimLit $A $(ctx.iterStepEntry t') $i $j) + let stepCert := rhsCert.chainProof hStep let hIter := q(Function.iterate_succ_apply' (BirdDet.stepEntry $dimLit $A) $t' (BirdDet.get $dimLit $A)) let h := q(congrArg (fun F : ℕ → ℕ → $α ↦ F $i $j) $hIter) - pure (rhsCert.chainProof h) + pure (stepCert.chainProof h) modify fun s => {s with iterStepEntryCache := s.iterStepEntryCache.insert (t, i, j) cert} return cert diff --git a/Mathlib/Tactic/NormDet.lean b/Mathlib/Tactic/NormDet.lean index de5787fcd9efa6..f94552edc5052f 100644 --- a/Mathlib/Tactic/NormDet.lean +++ b/Mathlib/Tactic/NormDet.lean @@ -6,7 +6,7 @@ Authors: Paul Cadman module public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic -meta import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Correctness +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Correctness public meta import Mathlib.Tactic.Determinant.Bird.Cert /-! @@ -31,12 +31,16 @@ private def normalizeBirdDet (e : Expr) : MetaM Simp.Result := do private def normalizeDetFromEntries {u : Level} {α : Q(Type u)} {n : Q(ℕ)} (rα : Q(CommRing $α)) (A : Q(Matrix (Fin $n) (Fin $n) $α)) (entries : Array Q($α)) : MetaM Simp.Result := do - let arrayExpr : Q(Array $α) ← mkArrayLit α entries.toList - let hA ← mkDecideProofQ q(Array.size $arrayExpr = $n * $n) - have : $arrayExpr =Q Array.ofFn fun k : Fin ($n * $n) ↦ $A k.divNat k.modNat := ⟨⟩ - let ofArrayEqA := q(Matrix.ofArray_ofFn $A) + let xs : Q(List $α) ← mkListLit α entries.toList + let arrayExpr : Q(Array $α) := q(List.toArray $xs) + -- `List.ofFn` is exposed (unlike `Array.ofFn`) and so this reduction can be + -- checked by the kernel + have : (List.ofFn fun k : Fin ($n * $n) ↦ $A k.divNat k.modNat) =Q $xs := ⟨⟩ + let hlist : Q(List.ofFn (fun k : Fin ($n * $n) ↦ $A k.divNat k.modNat) = $xs) := q(rfl) + let hArray := q($hlist ▸ List.toArray_ofFn) let birdDet := q(BirdDet.birdDet $n $arrayExpr) - let detEqBirdDet := q($ofArrayEqA ▸ BirdDet.det_eq_birdDet $arrayExpr $hA) + let detEqBirdDet := q($hArray ▸ Matrix.ofArray_ofFn $A ▸ BirdDet.det_eq_birdDet + (Array.ofFn fun k : Fin ($n * $n) ↦ $A k.divNat k.modNat) Array.size_ofFn) let birdDetNorm ← normalizeBirdDet birdDet let detEqBirdDetRes : Simp.Result := ⟨birdDet, some detEqBirdDet, true⟩ detEqBirdDetRes.mkEqTrans birdDetNorm diff --git a/MathlibTest/matrix.lean b/MathlibTest/matrix.lean index 59a4cd34833e27..c503fc6ee10125 100644 --- a/MathlibTest/matrix.lean +++ b/MathlibTest/matrix.lean @@ -1,7 +1,11 @@ +module + /- manually ported from https://github.com/leanprover-community/mathlib/blob/4f4a1c875d0baa92ab5d92f3fb1bb258ad9f3e5b/test/matrix.lean -/ + +public import Lean import Mathlib.GroupTheory.Perm.Fin import Mathlib.LinearAlgebra.Matrix.Determinant.Basic import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Defs @@ -9,12 +13,12 @@ import Mathlib.LinearAlgebra.Matrix.Notation import Mathlib.RingTheory.Polynomial.Basic import Mathlib.Tactic.FieldSimp import Mathlib.Tactic.NormDet -import Qq +meta import Mathlib.Data.Fin.VecNotation +meta import Mathlib.Data.Matrix.Basic +meta import Qq open Qq -variable {α β : Type} [Semiring α] [Ring β] - namespace Matrix /-! Test that the dimensions are inferred correctly, even for empty matrices -/ @@ -114,6 +118,8 @@ section delaborators end delaborators +variable {α β : Type} [Semiring α] [Ring β] + example {a a' b b' c c' d d' : α} : !![a, b; c, d] + !![a', b'; c', d'] = !![a + a', b + b'; c + c', d + d'] := by simp From f424bc890c23f9fbe219c109f7f7304721f21e6f Mon Sep 17 00:00:00 2001 From: ZRTMRH <213117991+ZRTMRH@users.noreply.github.com> Date: Mon, 27 Jul 2026 09:41:04 +0000 Subject: [PATCH 1017/1300] feat(Combinatorics/Quiver/Path): add `Quiver.Reachable` (#41849) Add `Quiver.Reachable a b`, the existence of a directed path from `a` to `b`, together with its basic preorder API (`@[refl]`/`@[trans]`) and `Path.reachable`/`Hom.reachable`. Unlike `SimpleGraph.Reachable`, this is only a preorder, not an equivalence, since quiver paths are directed; the symmetric notion is reachability in `Symmetrify V`. Co-authored-by: Runtian Zhou --- Mathlib/Combinatorics/Quiver/Path.lean | 41 +++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Mathlib/Combinatorics/Quiver/Path.lean b/Mathlib/Combinatorics/Quiver/Path.lean index ddd9d524ee5a65..0795ef0ea0af95 100644 --- a/Mathlib/Combinatorics/Quiver/Path.lean +++ b/Mathlib/Combinatorics/Quiver/Path.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2021 David Wärn,. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: David Wärn, Kim Morrison, Matteo Cipollina +Authors: David Wärn, Kim Morrison, Matteo Cipollina, Runtian Zhou -/ module @@ -14,6 +14,8 @@ public import Batteries.Data.List.Basic Given a quiver `V`, we define the type of paths from `a : V` to `b : V` as an inductive family. We define composition of paths and the action of prefunctors on paths. + +We also define `Quiver.Reachable a b`, the existence of a directed path from `a` to `b`. -/ @[expose] public section @@ -309,6 +311,43 @@ end BoundedPath end Path +section Reachable + +variable {V : Type u} [Quiver V] + +/-- `Reachable a b` holds when there is a directed path from `a` to `b`. + +This is a preorder rather than an equivalence, since quiver paths are directed (compare the +symmetric `SimpleGraph.Reachable`). -/ +def Reachable (a b : V) : Prop := Nonempty (Path a b) + +variable {a b c : V} + +protected theorem Reachable.elim {p : Prop} (h : Reachable a b) (hp : Path a b → p) : p := + Nonempty.elim h hp + +@[refl] +protected theorem Reachable.refl (a : V) : Reachable a a := ⟨.nil⟩ + +@[simp] +protected theorem Reachable.rfl : Reachable a a := .refl _ + +@[trans] +protected theorem Reachable.trans (hab : Reachable a b) (hbc : Reachable b c) : Reachable a c := + hab.elim fun p => hbc.elim fun q => ⟨p.comp q⟩ + +instance : IsPreorder V Reachable where + refl := .refl + trans _ _ _ := .trans + +/-- A path witnesses that its target is reachable from its source. -/ +protected theorem Path.reachable (p : Path a b) : Reachable a b := ⟨p⟩ + +/-- An arrow witnesses that its target is reachable from its source. -/ +protected theorem Hom.reachable (e : a ⟶ b) : Reachable a b := ⟨e.toPath⟩ + +end Reachable + end Quiver namespace Prefunctor From d1ddae43a4db43e0acf2d9d9e18b54037dbe3ea0 Mon Sep 17 00:00:00 2001 From: Justus Springer <50165510+justus-springer@users.noreply.github.com> Date: Mon, 27 Jul 2026 11:22:57 +0000 Subject: [PATCH 1018/1300] feat(Analysis/InnerProductSpace): inner products on exterior powers (#40724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given a real inner product space `E`, we construct a canonical inner product on `⋀[ℝ]^n E` via the Gram determinant formula: on decomposable elements, `⟪v₁ ∧ ⋯ ∧ vₙ, w₁ ∧ ⋯ ∧ wₙ⟫ = det (⟪vⱼ, wᵢ⟫)ᵢⱼ`. There are two generalizations of this construction: Going from `ℝ` to `RCLike`, and getting rid of the `FiniteDimensional` assumption. Both would require some prerequisites, hence they are left as future work for now (see the future work section of the module docstring). Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: tb65536 --- Mathlib.lean | 1 + .../InnerProductSpace/ExteriorPower.lean | 155 ++++++++++++++++++ .../InnerProductSpace/GramMatrix.lean | 5 + 3 files changed, 161 insertions(+) create mode 100644 Mathlib/Analysis/InnerProductSpace/ExteriorPower.lean diff --git a/Mathlib.lean b/Mathlib.lean index 624f35d65fc813..9d8fe07ded62af 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2046,6 +2046,7 @@ public import Mathlib.Analysis.InnerProductSpace.Convex public import Mathlib.Analysis.InnerProductSpace.Defs public import Mathlib.Analysis.InnerProductSpace.Dual public import Mathlib.Analysis.InnerProductSpace.EuclideanDist +public import Mathlib.Analysis.InnerProductSpace.ExteriorPower public import Mathlib.Analysis.InnerProductSpace.GramMatrix public import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho public import Mathlib.Analysis.InnerProductSpace.Harmonic.Basic diff --git a/Mathlib/Analysis/InnerProductSpace/ExteriorPower.lean b/Mathlib/Analysis/InnerProductSpace/ExteriorPower.lean new file mode 100644 index 00000000000000..1bb7d526df2960 --- /dev/null +++ b/Mathlib/Analysis/InnerProductSpace/ExteriorPower.lean @@ -0,0 +1,155 @@ +/- +Copyright (c) 2026 Justus Springer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Justus Springer +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.GramMatrix +public import Mathlib.LinearAlgebra.ExteriorPower.Basis + +/-! +# Inner product space structure on exterior powers + +Given a real inner product space `E`, we construct a canonical inner product on `⋀[ℝ]^n E` +via the Gram determinant formula: on decomposable elements, +`⟪v₁ ∧ ⋯ ∧ vₙ, w₁ ∧ ⋯ ∧ wₙ⟫ = det (⟪vⱼ, wᵢ⟫)ᵢⱼ`. + +## Main results + +- `exteriorPower.inner_ιMulti_ιMulti`: The inner product on decomposable elements equals the + Gram determinant. +- `exteriorPower.inner_ιMulti_self`: `⟪v₁ ∧ ⋯ ∧ vₙ, v₁ ∧ ⋯ ∧ vₙ⟫ = det (gram ℝ v)`. +- `OrthonormalBasis.exteriorPower`: An orthonormal basis of `E` induces an orthonormal basis + of `⋀[ℝ]^n E`. + +## Future work + +- Generalize to `RCLike 𝕜`. To define `innerProductForm` in this case, we would probably + want a semilinear generalization of `exteriorPower.map`, which in turn requires + generalizing `AlternatingMap` to the semilinear setting. +- Remove the `FiniteDimensional` hypothesis from the `InnerProductSpace` instance. + Currently the proofs of `re_inner_nonneg` and `definite` require finite dimension, because + we need to choose an orthonormal basis of `E`. But we can reduce the general case to + the finite-dimensional case by noticing that any `x : ⋀[𝕜]^n E` is contained in some + `⋀[𝕜]^n F` for a finite-dimensional subspace `F ≤ E`. + +-/ + +@[expose] public noncomputable section + +namespace exteriorPower + +open RealInnerProductSpace Matrix + +variable {n : ℕ} {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] + +/-- The inner product on `⋀[ℝ]^n E` as a bilinear map. This is an implementation detail +for constructing the `InnerProductSpace` instance and should not be used directly. +Use `⟪·, ·⟫` instead. -/ +private def innerProductForm : ⋀[ℝ]^n E →ₗ[ℝ] ⋀[ℝ]^n E →ₗ[ℝ] ℝ := + pairingDual ℝ E n ∘ₗ map n (innerₗ E) + +private lemma innerProductForm_ιMulti_ιMulti (x y : Fin n → E) : + innerProductForm (ιMulti ℝ n x) (ιMulti ℝ n y) = det (of fun i j ↦ ⟪x j, y i⟫) := by + simp [innerProductForm] + +@[simp] +private lemma innerProductForm_ιMulti_self (x : Fin n → E) : + innerProductForm (ιMulti ℝ n x) (ιMulti ℝ n x) = det (gram ℝ x) := by + simp [gram, innerProductForm_ιMulti_ιMulti, real_inner_comm] + +private lemma flip_innerProductForm : + (innerProductForm (E := E) (n := n)).flip = innerProductForm := by + apply linearMap_ext + ext + simp only [LinearMap.compAlternatingMap_apply, LinearMap.flip_apply, + innerProductForm_ιMulti_ιMulti] + rw [← Matrix.det_transpose] + congr 1 + ext + exact real_inner_comm _ _ + +private lemma innerProductForm_symm (x y : ⋀[ℝ]^n E) : + innerProductForm y x = innerProductForm x y := + congr($flip_innerProductForm x y) + +@[simp] +private lemma innerProductForm_ιMulti_family_of_orthonormal {ι : Type*} [LinearOrder ι] {v : ι → E} + (hv : Orthonormal ℝ v) (s t : Set.powersetCard ι n) : + innerProductForm (ιMulti_family ℝ n v s) (ιMulti_family ℝ n v t) = if s = t then 1 else 0 := by + simp only [ιMulti_family] + split_ifs with h + · subst h + simp [gram_eq_one_iff_orthonormal.mpr (hv.comp _ (RelEmbedding.injective _))] + · rw [innerProductForm_ιMulti_ιMulti] + obtain ⟨x, hxt, hxs⟩ := (Set.powersetCard.exists_mem_notMem_iff_ne t s).mp (.symm h) + simp only [Set.mem_range, not_exists, + ← Set.powersetCard.mem_range_ofFinEmbEquiv_symm_iff_mem] at hxs hxt + obtain ⟨i, rfl⟩ := hxt + exact det_eq_zero_of_row_eq_zero i (fun j ↦ hv.inner_eq_zero (hxs j)) + +private lemma innerProductForm_eq_sum {ι : Type*} [Fintype ι] [LinearOrder ι] + (b : OrthonormalBasis ι ℝ E) (x y : ⋀[ℝ]^n E) : + innerProductForm x y = + ∑ s, (b.toBasis.exteriorPower n).repr y s * (b.toBasis.exteriorPower n).repr x s := by + conv_lhs => + rw [← (b.toBasis.exteriorPower n).sum_repr x, ← (b.toBasis.exteriorPower n).sum_repr y] + simp + +private lemma innerProductForm_self (x : ⋀[ℝ]^n E) {ι : Type*} [Fintype ι] [LinearOrder ι] + (b : OrthonormalBasis ι ℝ E) : + innerProductForm x x = ∑ s, (b.toBasis.exteriorPower n).repr x s ^ 2 := by + simp_rw [innerProductForm_eq_sum b, pow_two] + +@[no_expose] instance [FiniteDimensional ℝ E] : InnerProductSpace.Core ℝ (⋀[ℝ]^n E) where + inner x y := innerProductForm x y + conj_inner_symm := innerProductForm_symm + add_left := by simp + smul_left := by simp + re_inner_nonneg x := by + rw [innerProductForm_self x (stdOrthonormalBasis ℝ E)] + exact Finset.sum_nonneg (fun _ _ ↦ sq_nonneg _) + definite x h := by + rw [innerProductForm_self x (stdOrthonormalBasis ℝ E), + Finset.sum_eq_zero_iff_of_nonneg (fun _ _ ↦ sq_nonneg _)] at h + apply Module.Basis.ext_elem ((stdOrthonormalBasis ℝ E).toBasis.exteriorPower n) + simpa using h + +instance [FiniteDimensional ℝ E] : NormedAddCommGroup (⋀[ℝ]^n E) := + InnerProductSpace.Core.toNormedAddCommGroup (𝕜 := ℝ) + +instance [FiniteDimensional ℝ E] : InnerProductSpace ℝ (⋀[ℝ]^n E) := + InnerProductSpace.ofCore _ + +lemma inner_ιMulti_ιMulti [FiniteDimensional ℝ E] (x y : Fin n → E) : + ⟪ιMulti ℝ n x, ιMulti ℝ n y⟫ = det (of fun i j ↦ ⟪x j, y i⟫) := + innerProductForm_ιMulti_ιMulti x y + +lemma inner_ιMulti_self [FiniteDimensional ℝ E] (x : Fin n → E) : + ⟪ιMulti ℝ n x, ιMulti ℝ n x⟫ = det (gram ℝ x) := + innerProductForm_ιMulti_self x + +end exteriorPower + +section OrthonormalBasis + +variable {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] [FiniteDimensional ℝ E] +variable {I : Type*} [Fintype I] [LinearOrder I] + +/-- An orthonormal basis of a finite-dimensional real inner product space `E` induces an +orthonormal basis of `⋀[ℝ]^n E`, indexed by `n`-element subsets of the index type. -/ +def OrthonormalBasis.exteriorPower (b : OrthonormalBasis I ℝ E) (n : ℕ) : + OrthonormalBasis (Set.powersetCard I n) ℝ (⋀[ℝ]^n E) := + (b.toBasis.exteriorPower n).toOrthonormalBasis <| by + rw [orthonormal_iff_ite] + intro i j + rw [exteriorPower.coe_basis, OrthonormalBasis.coe_toBasis] + exact exteriorPower.innerProductForm_ιMulti_family_of_orthonormal b.orthonormal i j + +@[simp] +lemma OrthonormalBasis.toBasis_exteriorPower (b : OrthonormalBasis I ℝ E) (n : ℕ) : + (b.exteriorPower n).toBasis = b.toBasis.exteriorPower n := + (b.toBasis.exteriorPower n).toBasis_toOrthonormalBasis _ + +end OrthonormalBasis diff --git a/Mathlib/Analysis/InnerProductSpace/GramMatrix.lean b/Mathlib/Analysis/InnerProductSpace/GramMatrix.lean index 5137d3a797bf6b..7bc693a2ddb34c 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramMatrix.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramMatrix.lean @@ -134,6 +134,11 @@ theorem gram_eq_conjTranspose_mul {ι : Type*} [Fintype ι] (b : OrthonormalBasi ext i j simp [mul_apply, b.repr_apply_apply, b.sum_inner_mul_inner] +omit [Finite n] in +@[simp] +lemma gram_eq_one_iff_orthonormal [DecidableEq n] {v : n → E} : gram 𝕜 v = 1 ↔ Orthonormal 𝕜 v := by + simp [← Matrix.ext_iff, orthonormal_iff_ite, Matrix.one_apply] + omit [Finite n] in /-- Inequality `‖f x‖ ≤ ‖f‖ * ‖x‖` lifted to Gram matrices. -/ theorem posSemidef_opNorm_smul_gram_sub_gram {F} [NormedAddCommGroup F] [InnerProductSpace 𝕜 F] From 6561533f01498bdf9c6816f27fad181172ae2a0c Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 27 Jul 2026 12:03:06 +0000 Subject: [PATCH 1019/1300] chore(Counterexamples): remove stale porting note (#42121) Causes no slowdowns Co-authored-by: Batixx --- Counterexamples/Pseudoelement.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Counterexamples/Pseudoelement.lean b/Counterexamples/Pseudoelement.lean index fa640e6f0af98e..2bc8b8fc8a2a50 100644 --- a/Counterexamples/Pseudoelement.lean +++ b/Counterexamples/Pseudoelement.lean @@ -65,8 +65,6 @@ theorem snd_x_pseudo_eq_snd_y : PseudoEqual _ (app biprod.snd x) (app biprod.snd simp_rw [biprod.lift_snd]; rfl set_option backward.isDefEq.respectTransparency false in --- Porting note: locally disable instance to avoid inferred/synthesized clash -attribute [-instance] AddCommGroup.toIntModule in /-- `x` is not pseudoequal to `y`. -/ theorem x_not_pseudo_eq : ¬PseudoEqual _ x y := by intro h From dfdaed47fc39211259b8e0a45ee0b9f358d494aa Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Mon, 27 Jul 2026 12:15:36 +0000 Subject: [PATCH 1020/1300] feat(GroupTheory/FreeGroup/IsFreeGroup): to_additive'ize file (#42109) Add additive analogs of `FreeGroupBasis`/`IsFreeGroup` and apply `@[to_additive]` throughout the rest of the file. --- .../GroupTheory/FreeGroup/IsFreeGroup.lean | 87 +++++++++++++++++-- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean b/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean index cd6e4d4d04edce..465f87a833ccce 100644 --- a/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean +++ b/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean @@ -48,19 +48,39 @@ open Function Set noncomputable section +/-- A free group basis `FreeAddGroupBasis ι G` is a structure recording the isomorphism between an +additive group `G` and the additive free group over `ι`. One may think of such a basis as a function +from `ι` to `G` (which is registered through a `FunLike` instance) together with the fact that the +morphism induced by this function from `FreeAddGroup ι` to `G` is an isomorphism. -/ +structure FreeAddGroupBasis (ι : Type*) (G : Type*) [AddGroup G] where + /-- `FreeAddGroupBasis.ofRepr` constructs a basis given an equivalence with an additive free + group. -/ + ofRepr :: + /-- `repr` is the isomorphism between the additive group `G` and the additive free group + generated by `ι`. -/ + repr : G ≃+ FreeAddGroup ι + /-- A free group basis `FreeGroupBasis ι G` is a structure recording the isomorphism between a group `G` and the free group over `ι`. One may think of such a basis as a function from `ι` to `G` (which is registered through a `FunLike` instance) together with the fact that the morphism induced by this function from `FreeGroup ι` to `G` is an isomorphism. -/ +@[to_additive] structure FreeGroupBasis (ι : Type*) (G : Type*) [Group G] where /-- `FreeGroupBasis.ofRepr` constructs a basis given an equivalence with a free group. -/ ofRepr :: /-- `repr` is the isomorphism between the group `G` and the free group generated by `ι`. -/ repr : G ≃* FreeGroup ι +/-- An additive group is free if it admits an additive free group basis. In the definition, we +require the basis to be in the same universe as `G`, although this property follows from the +existence of a basis in any universe, see `FreeAddGroupBasis.isFreeAddGroup`. -/ +class IsFreeAddGroup (G : Type u) [AddGroup G] : Prop where + nonempty_basis : ∃ (ι : Type u), Nonempty (FreeAddGroupBasis ι G) + /-- A group is free if it admits a free group basis. In the definition, we require the basis to be in the same universe as `G`, although this property follows from the existence of a basis in any universe, see `FreeGroupBasis.isFreeGroup`. -/ +@[to_additive] class IsFreeGroup (G : Type u) [Group G] : Prop where nonempty_basis : ∃ (ι : Type u), Nonempty (FreeGroupBasis ι G) @@ -70,6 +90,9 @@ variable {ι ι' G H : Type*} [Group G] [Group H] /-- A free group basis for `G` over `ι` is associated to a map `ι → G` recording the images of the generators. -/ +@[to_additive +/-- An additive free group basis for `G` over `ι` is associated to a map `ι → G` recording the +images of the generators. -/] instance instFunLike : FunLike (FreeGroupBasis ι G) ι G where coe b := fun i ↦ b.repr.symm (FreeGroup.of i) coe_injective := by @@ -79,38 +102,49 @@ instance instFunLike : FunLike (FreeGroupBasis ι G) ι G where have : b.symm = b'.symm := by ext x; exact DFunLike.congr_fun H x rw [ofRepr.injEq, ← MulEquiv.symm_symm b, ← MulEquiv.symm_symm b', this] -@[simp] lemma repr_apply_coe (b : FreeGroupBasis ι G) (i : ι) : b.repr (b i) = FreeGroup.of i := by +@[to_additive (attr := simp)] +lemma repr_apply_coe (b : FreeGroupBasis ι G) (i : ι) : b.repr (b i) = FreeGroup.of i := by change b.repr (b.repr.symm (FreeGroup.of i)) = FreeGroup.of i simp /-- The canonical basis of the free group over `X`. -/ +@[to_additive /-- The canonical basis of the additive free group over `X`. -/] def ofFreeGroup (X : Type*) : FreeGroupBasis X (FreeGroup X) := ofRepr (MulEquiv.refl _) -@[simp] lemma ofFreeGroup_apply {X : Type*} (x : X) : +@[to_additive (attr := simp)] +lemma ofFreeGroup_apply {X : Type*} (x : X) : FreeGroupBasis.ofFreeGroup X x = FreeGroup.of x := rfl /-- Reindex a free group basis through a bijection of the indexing sets. -/ +@[to_additive /-- Reindex an additive free group basis through a bijection of the indexing sets. -/] protected def reindex (b : FreeGroupBasis ι G) (e : ι ≃ ι') : FreeGroupBasis ι' G := ofRepr (b.repr.trans (FreeGroup.freeGroupCongr e)) -@[simp] lemma reindex_apply (b : FreeGroupBasis ι G) (e : ι ≃ ι') (x : ι') : +@[to_additive (attr := simp)] +lemma reindex_apply (b : FreeGroupBasis ι G) (e : ι ≃ ι') (x : ι') : b.reindex e x = b (e.symm x) := rfl /-- Pushing a free group basis through a group isomorphism. -/ +@[to_additive /-- Pushing an additive free group basis through a group isomorphism. -/] protected def map (b : FreeGroupBasis ι G) (e : G ≃* H) : FreeGroupBasis ι H := ofRepr (e.symm.trans b.repr) -@[simp] lemma map_apply (b : FreeGroupBasis ι G) (e : G ≃* H) (x : ι) : +@[to_additive (attr := simp)] +lemma map_apply (b : FreeGroupBasis ι G) (e : G ≃* H) (x : ι) : b.map e x = e (b x) := rfl +@[to_additive] protected lemma injective (b : FreeGroupBasis ι G) : Injective b := b.repr.symm.injective.comp FreeGroup.of_injective /-- A group admitting a free group basis is a free group. -/ +@[to_additive +/-- An additive group admitting an additive free group basis is an additive free group. -/] lemma isFreeGroup (b : FreeGroupBasis ι G) : IsFreeGroup G := ⟨range b, ⟨b.reindex (Equiv.ofInjective (↑b) b.injective)⟩⟩ +@[to_additive] instance (X : Type*) : IsFreeGroup (FreeGroup X) := (ofFreeGroup X).isFreeGroup @@ -119,7 +153,9 @@ instance (X : Type*) : IsFreeGroup (FreeGroup X) := set_option backward.isDefEq.respectTransparency.types false in /-- Given a free group basis of `G` over `ι`, there is a canonical bijection between maps from `ι` to a group `H` and morphisms from `G` to `H`. -/ -@[simps!] +@[to_additive (attr := simps!) +/-- Given an additive free group basis of `G` over `ι`, there is a canonical bijection between +maps from `ι` to an additive group `H` and morphisms from `G` to `H`. -/] def lift (b : FreeGroupBasis ι G) : (ι → H) ≃ (G →* H) := FreeGroup.lift.trans { toFun := fun f => f.comp b.repr.toMonoidHom @@ -132,12 +168,18 @@ def lift (b : FreeGroupBasis ι G) : (ι → H) ≃ (G →* H) := simp } /-- If two morphisms on `G` coincide on the elements of a basis, then they coincide. -/ +@[to_additive +/-- If two morphisms on `G` coincide on the elements of a basis, then they coincide. -/] lemma ext_hom (b : FreeGroupBasis ι G) (f g : G →* H) (h : ∀ i, f (b i) = g (b i)) : f = g := b.lift.symm.injective <| funext h /-- If a group satisfies the universal property of a free group with respect to a given type, then it admits a free group basis based on this type. Here, the universal property is expressed as in `IsFreeGroup.lift` and its properties. -/ +@[to_additive +/-- If an additive group satisfies the universal property of an additive free group with respect to +a given type, then it admits an additive free group basis based on this type. Here, the universal +property is expressed as in `IsFreeAddGroup.lift` and its properties. -/] def ofLift {G : Type u} [Group G] (X : Type u) (of : X → G) (lift : ∀ {H : Type u} [Group H], (X → H) ≃ (G →* H)) (lift_of : ∀ {H : Type u} [Group H], ∀ (f : X → H) (a), lift f (of a) = f a) : @@ -157,6 +199,10 @@ def ofLift {G : Type u} [Group G] (X : Type u) (of : X → G) /-- If a group satisfies the universal property of a free group with respect to a given type, then it admits a free group basis based on this type. Here the universal property is expressed as in `IsFreeGroup.unique_lift`. -/ +@[to_additive +/-- If an additive group satisfies the universal property of an additive free group with respect to +a given type, then it admits an additive free group basis based on this type. Here +the universal property is expressed as in `IsFreeAddGroup.unique_lift`. -/] def ofUniqueLift {G : Type u} [Group G] (X : Type u) (of : X → G) (h : ∀ {H : Type u} [Group H] (f : X → H), ∃! F : G →* H, ∀ a, F (of a) = f a) : FreeGroupBasis X G := @@ -176,23 +222,29 @@ namespace IsFreeGroup variable (G : Type*) [Group G] [IsFreeGroup G] /-- A set of generators of a free group, chosen arbitrarily -/ +@[to_additive /-- A set of generators of an additive free group, chosen arbitrarily -/] def Generators : Type _ := (IsFreeGroup.nonempty_basis (G := G)).choose /-- Any free group is isomorphic to "the" free group. -/ +@[to_additive /-- Any additive free group is isomorphic to "the" additive free group. -/] irreducible_def mulEquiv : FreeGroup (Generators G) ≃* G := (IsFreeGroup.nonempty_basis (G := G)).choose_spec.some.repr.symm /-- A free group basis of a free group `G`, over the set `Generators G`. -/ +@[to_additive +/-- An additive free group basis of an additive free group `G`, over the set `Generators G`. -/] def basis : FreeGroupBasis (Generators G) G := FreeGroupBasis.ofRepr (mulEquiv G).symm /-- Any free group is isomorphic to "the" free group. -/ -@[simps!] +@[to_additive (attr := simps!) +/-- Any additive free group is isomorphic to "the" additive free group. -/] def toFreeGroup : G ≃* FreeGroup (Generators G) := (mulEquiv G).symm variable {G} /-- The canonical injection of G's generators into G -/ +@[to_additive /-- The canonical injection of G's generators into G -/] def of : Generators G → G := (mulEquiv G).toFun ∘ FreeGroup.of @@ -200,18 +252,22 @@ variable {H : Type*} [Group H] /-- The equivalence between functions on the generators and group homomorphisms from a free group given by those generators. -/ +@[to_additive +/-- The equivalence between functions on the generators and additive group homomorphisms from an +additive free group given by those generators. -/] def lift : (Generators G → H) ≃ (G →* H) := (basis G).lift -@[simp] +@[to_additive (attr := simp)] theorem lift_of (f : Generators G → H) (a : Generators G) : lift f (of a) = f a := congr_fun (lift.symm_apply_apply f) a -@[simp] +@[to_additive (attr := simp)] theorem lift_symm_apply (f : G →* H) (a : Generators G) : (lift.symm f) a = f (of a) := rfl /- Do not register this as an ext lemma, as `Generators G` is not canonical. -/ +@[to_additive /- Do not register this as an ext lemma, as `Generators G` is not canonical. -/] theorem ext_hom ⦃f g : G →* H⦄ (h : ∀ a : Generators G, f (of a) = g (of a)) : f = g := lift.symm.injective (funext h) @@ -220,12 +276,22 @@ group extends in a unique way to a homomorphism from `G`. Note that since `IsFreeGroup.lift` is expressed as a bijection, it already expresses the universal property. -/ +@[to_additive +/-- The universal property of an additive free group: A function from the generators of `G` to +another additive group extends in a unique way to a homomorphism from `G`. + +Note that since `IsFreeAddGroup.lift` is expressed as a bijection, it already +expresses the universal property. -/] theorem unique_lift (f : Generators G → H) : ∃! F : G →* H, ∀ a, F (of a) = f a := by simpa only [funext_iff] using! lift.symm.bijective.existsUnique f /-- If a group satisfies the universal property of a free group with respect to a given type, then it is free. Here, the universal property is expressed as in `IsFreeGroup.lift` and its properties. -/ +@[to_additive +/-- If an additive group satisfies the universal property of an additive free group with respect to +a given type, then it is free. Here, the universal property is expressed as in `IsFreeAddGroup.lift` +and its properties. -/] lemma ofLift {G : Type u} [Group G] (X : Type u) (of : X → G) (lift : ∀ {H : Type u} [Group H], (X → H) ≃ (G →* H)) (lift_of : ∀ {H : Type u} [Group H], ∀ (f : X → H) (a), lift f (of a) = f a) : @@ -234,11 +300,16 @@ lemma ofLift {G : Type u} [Group G] (X : Type u) (of : X → G) /-- If a group satisfies the universal property of a free group with respect to a given type, then it is free. Here the universal property is expressed as in `IsFreeGroup.unique_lift`. -/ +@[to_additive +/-- If an additive group satisfies the universal property of an additive free group with respect to +a given type, then it is free. Here the universal property is expressed as in +`IsFreeAddGroup.unique_lift`. -/] lemma ofUniqueLift {G : Type u} [Group G] (X : Type u) (of : X → G) (h : ∀ {H : Type u} [Group H] (f : X → H), ∃! F : G →* H, ∀ a, F (of a) = f a) : IsFreeGroup G := (FreeGroupBasis.ofUniqueLift X of h).isFreeGroup +@[to_additive] lemma ofMulEquiv (e : G ≃* H) : IsFreeGroup H := ((basis G).map e).isFreeGroup From b4cc8c681f11fc40314f36e797b3a1d18f5c522b Mon Sep 17 00:00:00 2001 From: Cody Mitchell <11943677+SproutSeeds@users.noreply.github.com> Date: Mon, 27 Jul 2026 13:22:28 +0000 Subject: [PATCH 1021/1300] feat: the inversion of a point tends to infinity as it approaches the center of an inversion. (#36313) Co-authored-by: Oliver Nash --- .../Geometry/Euclidean/Inversion/Basic.lean | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mathlib/Geometry/Euclidean/Inversion/Basic.lean b/Mathlib/Geometry/Euclidean/Inversion/Basic.lean index 08b9868f5dffbc..9ced846f557349 100644 --- a/Mathlib/Geometry/Euclidean/Inversion/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Inversion/Basic.lean @@ -230,3 +230,23 @@ protected theorem Continuous.inversion (hc : Continuous c) (hR : Continuous R) ( (hne : ∀ a, x a ≠ c a) : Continuous (fun a ↦ inversion (c a) (R a) (x a)) := continuous_iff_continuousAt.2 fun _ ↦ hc.continuousAt.inversion hR.continuousAt hx.continuousAt (hne _) + +namespace EuclideanGeometry + +open Filter in +/-- The inversion of a point tends to infinity as it approaches the center of an inversion. -/ +theorem tendsto_inversion_nhdsNE_center_cobounded {c : P} {R : ℝ} (hR : R ≠ 0) : + Tendsto (inversion c R) (𝓝[≠] c) (Bornology.cobounded P) := by + rw [← tendsto_dist_left_atTop_iff c] + have hdist : Tendsto (dist c) (𝓝[≠] c) (𝓝[>] (0 : ℝ)) := by + rw [tendsto_nhdsWithin_iff] + refine ⟨tendsto_nhdsWithin_of_tendsto_nhds ?_, eventually_nhdsWithin_of_forall ?_⟩ + · rw [← dist_self c] + exact ContinuousAt.tendsto <| by fun_prop + · aesop + have hratio : Tendsto (fun x : P ↦ dist c (inversion c R x)) (𝓝[≠] c) atTop := by + simp_rw [dist_center_inversion, div_eq_mul_inv] + exact hdist.inv_tendsto_nhdsGT_zero.const_mul_atTop <| by rwa [sq_pos_iff] + simpa using hratio + +end EuclideanGeometry From d868ca66a0a3f367e59b9eddb73deffff28b4845 Mon Sep 17 00:00:00 2001 From: teorth <199308+teorth@users.noreply.github.com> Date: Mon, 27 Jul 2026 13:45:31 +0000 Subject: [PATCH 1022/1300] feat (Order/Interval/Finset/Floor): Relating membership of an Int or Nat cast in intervals to intervals of floor and ceil functions (#41512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a `FloorRing` (resp. `FloorSemiring`) `α`, we relate membership of a cast `↑n` in an interval of `α` to membership of the integer (resp. natural number) `n` in the corresponding interval with floor/ceil endpoints, for instance `Int.coe_mem_Ioc_iff : ↑n ∈ Set.Ioc a b ↔ n ∈ Set.Ioc ⌊a⌋ ⌊b⌋`. If the right-hand side is finite, we express them as `Finset` instead. Co-authored-by: Terence Tao Co-authored-by: Oliver Nash --- Mathlib.lean | 1 + Mathlib/Order/Interval/Finset/Floor.lean | 84 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 Mathlib/Order/Interval/Finset/Floor.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9d8fe07ded62af..41cbea29ef64d5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6134,6 +6134,7 @@ public import Mathlib.Order.Interval.Finset.Box public import Mathlib.Order.Interval.Finset.Defs public import Mathlib.Order.Interval.Finset.DenselyOrdered public import Mathlib.Order.Interval.Finset.Fin +public import Mathlib.Order.Interval.Finset.Floor public import Mathlib.Order.Interval.Finset.Gaps public import Mathlib.Order.Interval.Finset.Nat public import Mathlib.Order.Interval.Finset.SuccPred diff --git a/Mathlib/Order/Interval/Finset/Floor.lean b/Mathlib/Order/Interval/Finset/Floor.lean new file mode 100644 index 00000000000000..242c5e36625a05 --- /dev/null +++ b/Mathlib/Order/Interval/Finset/Floor.lean @@ -0,0 +1,84 @@ +/- +Copyright (c) 2026 Terence Tao. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Terence Tao +-/ +module + +public import Mathlib.Algebra.Order.Floor.Semiring +public import Mathlib.Data.Int.Interval +public import Mathlib.Order.Interval.Finset.Nat + +/-! +# Membership in intervals via `Int.floor` / `Nat.floor` / `Int.ceil` / `Nat.ceil` + +For a `FloorRing` (resp. `FloorSemiring`) `α`, we relate membership of a cast `↑n` in an interval +of `α` to membership of the integer (resp. natural number) `n` in the corresponding interval with +floor/ceil endpoints, for instance `Int.cast_mem_Ioc_iff : ↑n ∈ Set.Ioc a b ↔ n ∈ Set.Ioc ⌊a⌋ ⌊b⌋`. +If the right-hand side set is finite, we express it as `Finset` instead. + +In the natural number case, non-negativity hypotheses are required when the `Nat.floor` function +is involved. In the `IsStrictOrderedRing` case, one of these hypotheses can be omitted. +-/ + +@[expose] public section + +namespace Int + +variable {α : Type*} [Ring α] [LinearOrder α] [FloorRing α] {a b : α} {n : ℤ} + +lemma cast_mem_Ioc_iff : ↑n ∈ Set.Ioc a b ↔ n ∈ Finset.Ioc ⌊a⌋ ⌊b⌋ := by + simp [floor_lt, le_floor] + +lemma cast_mem_Ico_iff : ↑n ∈ Set.Ico a b ↔ n ∈ Finset.Ico ⌈a⌉ ⌈b⌉ := by + simp [ceil_le, lt_ceil] + +lemma cast_mem_Icc_iff : ↑n ∈ Set.Icc a b ↔ n ∈ Finset.Icc ⌈a⌉ ⌊b⌋ := by + simp [ceil_le, le_floor] + +lemma cast_mem_Ioo_iff : ↑n ∈ Set.Ioo a b ↔ n ∈ Finset.Ioo ⌊a⌋ ⌈b⌉ := by + simp [floor_lt, lt_ceil] + +lemma cast_mem_Ioi_iff : ↑n ∈ Set.Ioi a ↔ n ∈ Set.Ioi ⌊a⌋ := by simp [floor_lt] + +lemma cast_mem_Ici_iff : ↑n ∈ Set.Ici a ↔ n ∈ Set.Ici ⌈a⌉ := by simp [ceil_le] + +lemma cast_mem_Iic_iff : ↑n ∈ Set.Iic b ↔ n ∈ Set.Iic ⌊b⌋ := by simp [le_floor] + +lemma cast_mem_Iio_iff : ↑n ∈ Set.Iio b ↔ n ∈ Set.Iio ⌈b⌉ := by simp [lt_ceil] + +end Int + +namespace Nat + +variable {α : Type*} [Semiring α] [LinearOrder α] [FloorSemiring α] {a b : α} {n : ℕ} + +lemma cast_mem_Ioc_iff (ha : 0 ≤ a) (hb : 0 ≤ b) : + ↑n ∈ Set.Ioc a b ↔ n ∈ Finset.Ioc ⌊a⌋₊ ⌊b⌋₊ := by simp [floor_lt ha, le_floor_iff hb] + +/-- The `0 ≤ b` hypothesis in `cast_mem_Ioc_iff` can be dropped if `IsStrictOrderedRing α`. -/ +lemma cast_mem_Ioc_iff' [IsStrictOrderedRing α] (ha : 0 ≤ a) : + ↑n ∈ Set.Ioc a b ↔ n ∈ Finset.Ioc ⌊a⌋₊ ⌊b⌋₊ := by + rcases le_or_gt 0 b with hb | hb + · exact cast_mem_Ioc_iff ha hb + · grind [floor_of_nonpos hb.le] + +lemma cast_mem_Ico_iff : ↑n ∈ Set.Ico a b ↔ n ∈ Finset.Ico ⌈a⌉₊ ⌈b⌉₊ := by + simp [ceil_le, lt_ceil] + +lemma cast_mem_Icc_iff (hb : 0 ≤ b) : ↑n ∈ Set.Icc a b ↔ n ∈ Finset.Icc ⌈a⌉₊ ⌊b⌋₊ := by + simp [ceil_le, le_floor_iff hb] + +lemma cast_mem_Ioo_iff (ha : 0 ≤ a) : ↑n ∈ Set.Ioo a b ↔ n ∈ Finset.Ioo ⌊a⌋₊ ⌈b⌉₊ := by + simp [floor_lt ha, lt_ceil] + +lemma cast_mem_Iic_iff (hb : 0 ≤ b) : ↑n ∈ Set.Iic b ↔ n ∈ Finset.Iic ⌊b⌋₊ := by + simp [le_floor_iff hb] + +lemma cast_mem_Iio_iff : ↑n ∈ Set.Iio b ↔ n ∈ Finset.Iio ⌈b⌉₊ := by simp [lt_ceil] + +lemma cast_mem_Ioi_iff (ha : 0 ≤ a) : ↑n ∈ Set.Ioi a ↔ n ∈ Set.Ioi ⌊a⌋₊ := by simp [floor_lt ha] + +lemma cast_mem_Ici_iff : ↑n ∈ Set.Ici a ↔ n ∈ Set.Ici ⌈a⌉₊ := by simp [ceil_le] + +end Nat From 2ec0166b31100827cd34bacca4d3b9ea3da9d618 Mon Sep 17 00:00:00 2001 From: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Date: Mon, 27 Jul 2026 13:55:53 +0000 Subject: [PATCH 1023/1300] feat(Combinatorics/SimpleGraph): neighborSet and neighborFinset of lattice operations (#40269) From the exponential-ramsey project Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 26 +++++++++++ Mathlib/Combinatorics/SimpleGraph/Finite.lean | 43 +++++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index c2b8107c55eb08..f6adc4c39b8f97 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -821,6 +821,32 @@ theorem disjoint_neighborSet : (∀ v, Disjoint (G.neighborSet v) (H.neighborSet v)) ↔ Disjoint G H := by simp_rw [← disjoint_edgeSet, Set.disjoint_left, mem_neighborSet, Sym2.forall, mem_edgeSet] +@[simp] +theorem neighborSet_sup {G₁ G₂ : SimpleGraph V} (v : V) : + (G₁ ⊔ G₂).neighborSet v = G₁.neighborSet v ∪ G₂.neighborSet v := + rfl + +@[simp] +theorem neighborSet_inf {G₁ G₂ : SimpleGraph V} (v : V) : + (G₁ ⊓ G₂).neighborSet v = G₁.neighborSet v ∩ G₂.neighborSet v := + rfl + +@[simp] +theorem neighborSet_sdiff {G₁ G₂ : SimpleGraph V} (v : V) : + (G₁ \ G₂).neighborSet v = G₁.neighborSet v \ G₂.neighborSet v := + rfl + +@[simp] +theorem neighborSet_iSup {s : ι → SimpleGraph V} (v : V) : + (⨆ i, s i).neighborSet v = ⋃ i, (s i).neighborSet v := by + ext; simp + +@[simp] +theorem neighborSet_iInf [Nonempty ι] {s : ι → SimpleGraph V} (v : V) : + (⨅ i, s i).neighborSet v = ⋂ i, (s i).neighborSet v := by + ext + simp_rw [Set.mem_iInter, mem_neighborSet, iInf_adj_of_nonempty] + @[simp] theorem mem_incidenceSet (v w : V) : s(v, w) ∈ G.incidenceSet v ↔ G.Adj v w := by simp [incidenceSet] diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index 7f557583f56e0a..395f6c67069a0f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -186,6 +186,45 @@ theorem neighborFinset_disjoint_singleton : Disjoint (G.neighborFinset v) {v} := theorem singleton_disjoint_neighborFinset : Disjoint {v} (G.neighborFinset v) := Finset.disjoint_singleton_left.mpr <| notMem_neighborFinset_self _ _ +theorem neighborFinset_bot [Fintype ((⊥ : SimpleGraph V).neighborSet v)] : + (⊥ : SimpleGraph V).neighborFinset v = ∅ := by + ext; simp + +@[simp] +theorem neighborFinset_top [Fintype V] [DecidableEq V] : + (⊤ : SimpleGraph V).neighborFinset v = {v}ᶜ := by + simp [← Finset.coe_inj] + +@[simp] +theorem neighborFinset_sup [DecidableEq V] {G₁ G₂ : SimpleGraph V} + [Fintype ((G₁ ⊔ G₂).neighborSet v)] [Fintype (G₁.neighborSet v)] [Fintype (G₂.neighborSet v)] : + (G₁ ⊔ G₂).neighborFinset v = G₁.neighborFinset v ∪ G₂.neighborFinset v := by + simp [← Finset.coe_inj] + +@[simp] +theorem neighborFinset_inf [DecidableEq V] {G₁ G₂ : SimpleGraph V} + [Fintype ((G₁ ⊓ G₂).neighborSet v)] [Fintype (G₁.neighborSet v)] [Fintype (G₂.neighborSet v)] : + (G₁ ⊓ G₂).neighborFinset v = G₁.neighborFinset v ∩ G₂.neighborFinset v := by + simp [← Finset.coe_inj] + +@[simp] +theorem neighborFinset_sdiff [DecidableEq V] {G₁ G₂ : SimpleGraph V} + [Fintype ((G₁ \ G₂).neighborSet v)] [Fintype (G₁.neighborSet v)] [Fintype (G₂.neighborSet v)] : + (G₁ \ G₂).neighborFinset v = G₁.neighborFinset v \ G₂.neighborFinset v := by + simp [← Finset.coe_inj] + +theorem disjoint_neighborFinset_of_disjoint [Fintype <| H.neighborSet v] (h : Disjoint G H) : + Disjoint (G.neighborFinset v) (H.neighborFinset v) := by + simp [← Finset.disjoint_coe, disjoint_neighborSet.mpr h v] + +theorem neighborFinset_sup_of_disjoint {G₁ G₂ : SimpleGraph V} + [Fintype ((G₁ ⊔ G₂).neighborSet v)] [Fintype (G₁.neighborSet v)] [Fintype (G₂.neighborSet v)] + (h : Disjoint G₁ G₂) : + (G₁ ⊔ G₂).neighborFinset v = + (G₁.neighborFinset v).disjUnion (G₂.neighborFinset v) + (disjoint_neighborFinset_of_disjoint G₁ G₂ v h) := by + simp [← Finset.coe_inj, Finset.coe_disjUnion] + @[simp] lemma neighborFinset_eq_empty : G.neighborFinset v = ∅ ↔ G.IsIsolated v := by simp [neighborFinset, IsIsolated, Set.ext_iff] @@ -197,10 +236,6 @@ protected alias ⟨IsIsolated.of_neighborFinset_eq_empty, IsIsolated.neighborFin attribute [simp] IsIsolated.neighborFinset_eq_empty -theorem disjoint_neighborFinset_of_disjoint [Fintype <| H.neighborSet v] (h : Disjoint G H) : - Disjoint (G.neighborFinset v) (H.neighborFinset v) := by - simp [← Finset.disjoint_coe, disjoint_neighborSet.mpr h v] - /-- `G.degree v` is the number of vertices adjacent to `v`. -/ def degree : ℕ := #(G.neighborFinset v) From a76bb818c9dd230c66c8c8a0ef60eebde1afc4e3 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:11:45 +0000 Subject: [PATCH 1024/1300] =?UTF-8?q?feat(Algebra/Algebra):=20reinterpret?= =?UTF-8?q?=20a=20RingEquiv=20as=20a=20=E2=84=95/=E2=84=A4/=E2=84=9A-algeb?= =?UTF-8?q?ra=20isomorphism=20(#40298)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the `RingEquiv` analogues of the `RingHom.to{Nat,Int,Rat}AlgHom` / `RingHom.equivRatAlgHom` constructions, over `ℕ`, `ℤ` and `ℚ`: - `RingEquiv.toNatAlgEquiv`, `RingEquiv.toIntAlgEquiv`, `RingEquiv.toRatAlgEquiv`: a `RingEquiv` is canonically an ℕ-, ℤ- or ℚ-algebra isomorphism. - `ringEquivEquivNatAlgEquiv`, `ringEquivEquivIntAlgEquiv`, `ringEquivEquivRatAlgEquiv`: the corresponding equivalences `(R ≃+* S) ≃ (R ≃ₐ[·] S)`. :robot: This PR was extracted from the [SKW project](https://github.com/xroblot/SKW) by Claude. Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Algebra/Algebra/Equiv.lean | 62 +++++++++++++++++++++++++++ Mathlib/Algebra/Algebra/Hom/Rat.lean | 63 +++++++++++++++++++++------- 2 files changed, 111 insertions(+), 14 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index 5ad24a529a6ae8..f423163bc8c611 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -777,6 +777,68 @@ end Semiring end AlgEquiv +namespace RingEquiv + +variable {R S : Type*} + +/-- Reinterpret a `RingEquiv` as an `ℕ`-algebra isomorphism. -/ +@[simps! -isSimp apply] +def toNatAlgEquiv [Semiring R] [Semiring S] (f : R ≃+* S) : R ≃ₐ[ℕ] S where + toEquiv := f + __ := f.toRingHom.toNatAlgHom + +@[simp] +lemma coe_toNatAlgEquiv [Semiring R] [Semiring S] (f : R ≃+* S) : + ⇑f.toNatAlgEquiv = ⇑f := rfl + +lemma toAlgHom_toNatAlgEquiv [Semiring R] [Semiring S] (f : R ≃+* S) : + f.toNatAlgEquiv.toAlgHom = (f : R →+* S).toNatAlgHom := rfl + +@[simp] +lemma symm_toNatAlgEquiv [Semiring R] [Semiring S] (f : R ≃+* S) : + f.toNatAlgEquiv.symm = f.symm.toNatAlgEquiv := rfl + +variable (R) (S) in +/-- The equivalence between `RingEquiv` and `ℕ`-algebra isomorphisms. -/ +@[simps apply symm_apply] +def equivNatAlgEquiv [Semiring R] [Semiring S] : (R ≃+* S) ≃ (R ≃ₐ[ℕ] S) where + toFun := toNatAlgEquiv + invFun := AlgEquiv.toRingEquiv + +lemma toNatAlgEquiv_injective [Semiring R] [Semiring S] : + Function.Injective (RingEquiv.toNatAlgEquiv : (R ≃+* S) → _) := + (equivNatAlgEquiv R S).injective + +/-- Reinterpret a `RingEquiv` as a `ℤ`-algebra isomorphism. -/ +@[simps! -isSimp apply] +def toIntAlgEquiv [Ring R] [Ring S] (f : R ≃+* S) : R ≃ₐ[ℤ] S where + toEquiv := f + __ := f.toRingHom.toIntAlgHom + +@[simp] +lemma coe_toIntAlgEquiv [Ring R] [Ring S] (f : R ≃+* S) : + ⇑f.toIntAlgEquiv = ⇑f := rfl + +lemma toAlgHom_toIntAlgEquiv [Ring R] [Ring S] (f : R ≃+* S) : + f.toIntAlgEquiv.toAlgHom = (f : R →+* S).toIntAlgHom := rfl + +@[simp] +lemma symm_toIntAlgEquiv [Ring R] [Ring S] (f : R ≃+* S) : + f.toIntAlgEquiv.symm = f.symm.toIntAlgEquiv := rfl + +variable (R) (S) in +/-- The equivalence between `RingEquiv` and `ℤ`-algebra isomorphisms. -/ +@[simps apply symm_apply] +def equivIntAlgEquiv [Ring R] [Ring S] : (R ≃+* S) ≃ (R ≃ₐ[ℤ] S) where + toFun := toIntAlgEquiv + invFun := AlgEquiv.toRingEquiv + +lemma toIntAlgEquiv_injective [Ring R] [Ring S] : + Function.Injective (RingEquiv.toIntAlgEquiv : (R ≃+* S) → _) := + (equivIntAlgEquiv R S).injective + +end RingEquiv + namespace MulSemiringAction variable {M G : Type*} (R A : Type*) [CommSemiring R] [Semiring A] [Algebra R A] diff --git a/Mathlib/Algebra/Algebra/Hom/Rat.lean b/Mathlib/Algebra/Algebra/Hom/Rat.lean index 41fcb31b9d4213..cef17b37693775 100644 --- a/Mathlib/Algebra/Algebra/Hom/Rat.lean +++ b/Mathlib/Algebra/Algebra/Hom/Rat.lean @@ -5,6 +5,7 @@ Authors: Kenny Lau, Yury Kudryashov -/ module +public import Mathlib.Algebra.Algebra.Equiv public import Mathlib.Algebra.Algebra.Hom public import Mathlib.Algebra.Algebra.Rat @@ -15,43 +16,77 @@ public import Mathlib.Algebra.Algebra.Rat @[expose] public section +variable {R S : Type*} [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] namespace RingHom -variable {R S : Type*} - /-- Reinterpret a `RingHom` as a `ℚ`-algebra homomorphism. This actually yields an equivalence, see `RingHom.equivRatAlgHom`. -/ -def toRatAlgHom [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] (f : R →+* S) : R →ₐ[ℚ] S := +def toRatAlgHom (f : R →+* S) : R →ₐ[ℚ] S := { f with commutes' := f.map_rat_algebraMap } @[simp] -theorem toRatAlgHom_toRingHom [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] (f : R →+* S) : +theorem toRatAlgHom_toRingHom (f : R →+* S) : ↑f.toRatAlgHom = f := RingHom.ext fun _x => rfl @[simp] -theorem toRatAlgHom_apply [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] (f : R →+* S) (x : R) : +theorem toRatAlgHom_apply (f : R →+* S) (x : R) : f.toRatAlgHom x = f x := rfl end RingHom -section - -variable {R S : Type*} - @[simp] -theorem AlgHom.toRingHom_toRatAlgHom [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] - (f : R →ₐ[ℚ] S) : (f : R →+* S).toRatAlgHom = f := +theorem AlgHom.toRingHom_toRatAlgHom (f : R →ₐ[ℚ] S) : (f : R →+* S).toRatAlgHom = f := AlgHom.ext fun _x => rfl variable (R) (S) in /-- The equivalence between `RingHom` and `ℚ`-algebra homomorphisms. -/ @[simps] -def RingHom.equivRatAlgHom [Ring R] [Ring S] [Algebra ℚ R] [Algebra ℚ S] : - (R →+* S) ≃ (R →ₐ[ℚ] S) where +def RingHom.equivRatAlgHom : (R →+* S) ≃ (R →ₐ[ℚ] S) where toFun := RingHom.toRatAlgHom invFun := AlgHom.toRingHom -end +namespace RingEquiv + +/-- Reinterpret a `RingEquiv` as a `ℚ`-algebra isomorphism. This actually yields an +equivalence, see `RingEquiv.equivRatAlgEquiv`. -/ +@[simps! -isSimp apply] +def toRatAlgEquiv (f : R ≃+* S) : R ≃ₐ[ℚ] S where + toEquiv := f + __ := f.toRingHom.toRatAlgHom + +@[simp] +theorem coe_toRatAlgEquiv (f : R ≃+* S) : ⇑f.toRatAlgEquiv = ⇑f := rfl + +@[simp] +theorem toRingEquiv_toRatAlgEquiv (f : R ≃+* S) : + f.toRatAlgEquiv = f := + rfl + +theorem toAlgHom_toRatAlgEquiv (f : R ≃+* S) : + f.toRatAlgEquiv.toAlgHom = (f : R →+* S).toRatAlgHom := + rfl + +@[simp] +theorem symm_toRatAlgEquiv (f : R ≃+* S) : + f.toRatAlgEquiv.symm = f.symm.toRatAlgEquiv := + rfl + +end RingEquiv + +@[simp] +theorem AlgEquiv.toRatAlgEquiv_toRingEquiv (f : R ≃ₐ[ℚ] S) : (f : R ≃+* S).toRatAlgEquiv = f := + rfl + +variable (R) (S) in +/-- The equivalence between `RingEquiv` and `ℚ`-algebra isomorphisms. -/ +@[simps apply symm_apply] +def RingEquiv.equivRatAlgEquiv : (R ≃+* S) ≃ (R ≃ₐ[ℚ] S) where + toFun := RingEquiv.toRatAlgEquiv + invFun := AlgEquiv.toRingEquiv + +lemma RingEquiv.toRatAlgEquiv_injective : + Function.Injective (RingEquiv.toRatAlgEquiv : (R ≃+* S) → _) := + (RingEquiv.equivRatAlgEquiv R S).injective From 4d80d5defb698161bd71f45ce4534400e09b15b0 Mon Sep 17 00:00:00 2001 From: Richard Osborn Date: Mon, 27 Jul 2026 15:46:53 +0000 Subject: [PATCH 1025/1300] feat(Algebra/Group/Subgroup): add sup/iSup/biSup/sSup_characteristic (#40282) The join of characteristic subgroups is characteristic. --- Mathlib/Algebra/Group/Subgroup/Basic.lean | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 18a69ab25d626f..5fa1fa1e91518a 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -316,6 +316,46 @@ instance botCharacteristic : Characteristic (⊥ : Subgroup G) := instance topCharacteristic : Characteristic (⊤ : Subgroup G) := characteristic_iff_map_le.mpr fun _ϕ => le_top +@[to_additive] +instance characteristic_sup [H.Characteristic] [K.Characteristic] : + (H ⊔ K).Characteristic := by + simp_all [characteristic_iff_map_eq, map_sup] + +@[to_additive] +instance characteristic_iSup {ι : Sort*} {H : ι → Subgroup G} [∀ i, (H i).Characteristic] : + (⨆ i, H i).Characteristic := by + simp_all [characteristic_iff_map_eq, map_iSup] + +@[to_additive] +theorem characteristic_biSup {ι : Type*} {s : Set ι} {H : ι → Subgroup G} + (h : ∀ i ∈ s, (H i).Characteristic) : (⨆ i ∈ s, H i).Characteristic := by + simp [← iSup_subtype'', characteristic_iSup, h] + +@[to_additive] +theorem characteristic_sSup {Hs : Set (Subgroup G)} (h : ∀ H ∈ Hs, H.Characteristic) : + (sSup Hs).Characteristic := by + simp [sSup_eq_iSup', characteristic_iSup, h] + +@[to_additive] +instance characteristic_inf [H.Characteristic] [K.Characteristic] : + (H ⊓ K).Characteristic := by + simp_all [characteristic_iff_comap_eq, comap_inf] + +@[to_additive] +instance characteristic_iInf {ι : Sort*} {H : ι → Subgroup G} [∀ i, (H i).Characteristic] : + (⨅ i, H i).Characteristic := by + simp_all [characteristic_iff_comap_eq, comap_iInf] + +@[to_additive] +theorem characteristic_biInf {ι : Type*} {s : Set ι} {H : ι → Subgroup G} + (h : ∀ i ∈ s, (H i).Characteristic) : (⨅ i ∈ s, H i).Characteristic := by + simp [← iInf_subtype'', characteristic_iInf, h] + +@[to_additive] +theorem characteristic_sInf {Hs : Set (Subgroup G)} (h : ∀ H ∈ Hs, H.Characteristic) : + (sInf Hs).Characteristic := by + simp [sInf_eq_iInf', characteristic_iInf, h] + /-- If `H` is a characteristic subgroup of `G`, then every automorphism of `G` induces an automorphism of `H`. -/ @[to_additive (attr := simps!) From 3156cad2c019b175e5772b24d034d7d44436a104 Mon Sep 17 00:00:00 2001 From: Brian Nugent Date: Mon, 27 Jul 2026 15:46:56 +0000 Subject: [PATCH 1026/1300] feat(Topology): sheafRestrict is a right adjoint (#41088) Co-authored-by: Brian-Nugent --- Mathlib/Topology/Sheaves/Over.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Topology/Sheaves/Over.lean b/Mathlib/Topology/Sheaves/Over.lean index b8e74aa67472db..376d5ecbea4b47 100644 --- a/Mathlib/Topology/Sheaves/Over.lean +++ b/Mathlib/Topology/Sheaves/Over.lean @@ -91,6 +91,11 @@ def overPullbackSheafEquivOver {X : TopCat} (U : Opens X) : (Opens.grothendieckTopology X).overPullback A U ⋙ U.sheafEquivOver.functor ≅ U.sheafRestrict := .refl _ +instance {X : TopCat} (U : Opens X) + [((Opens.grothendieckTopology X).overPullback A U).IsRightAdjoint] : + (U.sheafRestrict (C := A)).IsRightAdjoint := + Functor.isRightAdjoint_of_iso U.overPullbackSheafEquivOver + /-- `overPullback` and `sheafRestrict` are isomorphic under `sheafEquivOver`. -/ def sheafRestrictSheafEquivOver {X : TopCat} (U : Opens X) : U.sheafRestrict ⋙ U.sheafEquivOver.inverse ≅ From 346c31d924e2d794887034e200fb2300f40b0817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:46:58 +0000 Subject: [PATCH 1027/1300] feat(CategoryTheory): limits in Comma categories (#41181) Under suitable assumptions, `Comma.fst/snd` jointly reflect (co)limits. These additions allow to simplify the definition `coneOfPreservesIsLimit` and its dual. --- Mathlib/CategoryTheory/Limits/Comma.lean | 86 ++++++++++++++++-------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Comma.lean b/Mathlib/CategoryTheory/Limits/Comma.lean index 533ff3d5c66815..95a6c9e6df279b 100644 --- a/Mathlib/CategoryTheory/Limits/Comma.lean +++ b/Mathlib/CategoryTheory/Limits/Comma.lean @@ -72,24 +72,39 @@ noncomputable def coneOfPreserves [PreservesLimit (F ⋙ snd L R) R] (c₁ : Con · simp [← c₂.w t] } set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in +/-- Let `F : J ⥤ Comma L R`. If `R` preserves the limit of +`F ⋙ snd _ _`, then `Comma.fst L R` and `Comma.snd L R` jointly +reflect the limit of `F`, i.e. if `c` is a cone for `F` which +becomes a limit after applying `Comma.fst L R` and `Comma.snd L R`, +then `c` is a limit. -/ +def fstSndJointlyReflectLimit {F : J ⥤ Comma L R} {c : Cone F} + [PreservesLimit (F ⋙ snd _ _) R] + (h₁ : IsLimit ((fst _ _).mapCone c)) + (h₂ : IsLimit ((snd _ _).mapCone c)) : + IsLimit c where + lift s := + { left := h₁.lift ((fst _ _).mapCone s) + right := h₂.lift ((snd _ _).mapCone s) + w := (isLimitOfPreserves R h₂).hom_ext (fun j ↦ by + simp [← Functor.map_comp, ← Functor.map_comp_assoc, ← CommaMorphism.w, + dsimp% h₂.fac ((snd _ _).mapCone s) j, + dsimp% h₁.fac ((fst _ _).mapCone s) j]) } + fac s j := by + ext + · exact h₁.fac ((fst _ _).mapCone s) j + · exact h₂.fac ((snd _ _).mapCone s) j + uniq s _ hm := by + ext + · exact h₁.uniq ((fst _ _).mapCone s) _ (by simp [← hm]) + · exact h₂.uniq ((snd _ _).mapCone s) _ (by simp [← hm]) + /-- Provided that `R` preserves the appropriate limit, then the cone in `coneOfPreserves` is a limit. -/ noncomputable def coneOfPreservesIsLimit [PreservesLimit (F ⋙ snd L R) R] {c₁ : Cone (F ⋙ fst L R)} (t₁ : IsLimit c₁) {c₂ : Cone (F ⋙ snd L R)} (t₂ : IsLimit c₂) : - IsLimit (coneOfPreserves F c₁ t₂) where - lift s := - { left := t₁.lift ((fst L R).mapCone s) - right := t₂.lift ((snd L R).mapCone s) - w := - (isLimitOfPreserves R t₂).hom_ext fun j => by - rw [coneOfPreserves_pt_hom, assoc, assoc, (isLimitOfPreserves R t₂).fac, - limitAuxiliaryCone_π_app, ← L.map_comp_assoc, t₁.fac, R.mapCone_π_app, - ← R.map_comp, t₂.fac] - exact (s.π.app j).w } - uniq s m w := by - apply CommaMorphism.ext - · exact t₁.uniq ((fst L R).mapCone s) _ (fun j => by simp [← w]) - · exact t₂.uniq ((snd L R).mapCone s) _ (fun j => by simp [← w]) + IsLimit (coneOfPreserves F c₁ t₂) := + fstSndJointlyReflectLimit t₁ t₂ /-- (Implementation). An auxiliary cocone which is useful in order to construct colimits in the comma category. -/ @@ -121,25 +136,40 @@ noncomputable def coconeOfPreserves [PreservesColimit (F ⋙ fst L R) L] {c₁ : · simp [← c₂.w t] } set_option backward.isDefEq.respectTransparency false in +set_option backward.defeqAttrib.useBackward true in +/-- Let `F : J ⥤ Comma L R`. If `L` preserves the colimit of +`F ⋙ fst _ _`, then `Comma.fst L R` and `Comma.snd L R` jointly +reflect the colimit of `F`, i.e. if `c` is a cocone for `F` which +becomes a colimit after applying `Comma.fst L R` and `Comma.snd L R`, +then `c` is a colimit. -/ +def fstSndJointlyReflectColimit {F : J ⥤ Comma L R} {c : Cocone F} + [PreservesColimit (F ⋙ fst _ _) L] + (h₁ : IsColimit ((fst _ _).mapCocone c)) + (h₂ : IsColimit ((snd _ _).mapCocone c)) : + IsColimit c where + desc s := + { left := h₁.desc ((fst _ _).mapCocone s) + right := h₂.desc ((snd _ _).mapCocone s) + w := (isColimitOfPreserves L h₁).hom_ext (fun j ↦ by + simp [← Functor.map_comp_assoc, ← Functor.map_comp, + dsimp% h₁.fac ((fst _ _).mapCocone s) j, + dsimp% h₂.fac ((snd _ _).mapCocone s) j]) } + fac s j := by + ext + · exact h₁.fac ((fst _ _).mapCocone s) j + · exact h₂.fac ((snd _ _).mapCocone s) j + uniq s _ hm := by + ext + · exact h₁.uniq ((fst _ _).mapCocone s) _ (by simp [← hm]) + · exact h₂.uniq ((snd _ _).mapCocone s) _ (by simp [← hm]) + /-- Provided that `L` preserves the appropriate colimit, then the cocone in `coconeOfPreserves` is a colimit. -/ noncomputable def coconeOfPreservesIsColimit [PreservesColimit (F ⋙ fst L R) L] {c₁ : Cocone (F ⋙ fst L R)} (t₁ : IsColimit c₁) {c₂ : Cocone (F ⋙ snd L R)} (t₂ : IsColimit c₂) : - IsColimit (coconeOfPreserves F t₁ c₂) where - desc s := - { left := t₁.desc ((fst L R).mapCocone s) - right := t₂.desc ((snd L R).mapCocone s) - w := - (isColimitOfPreserves L t₁).hom_ext fun j => by - rw [coconeOfPreserves_pt_hom, (isColimitOfPreserves L t₁).fac_assoc, - colimitAuxiliaryCocone_ι_app, assoc, ← R.map_comp, t₂.fac, L.mapCocone_ι_app, ← - L.map_comp_assoc, t₁.fac] - exact (s.ι.app j).w } - uniq s m w := by - apply CommaMorphism.ext - · exact t₁.uniq ((fst L R).mapCocone s) _ (fun j => by simp [← w]) - · exact t₂.uniq ((snd L R).mapCocone s) _ (fun j => by simp [← w]) + IsColimit (coconeOfPreserves F t₁ c₂) := + fstSndJointlyReflectColimit t₁ t₂ instance hasLimit (F : J ⥤ Comma L R) [HasLimit (F ⋙ fst L R)] [HasLimit (F ⋙ snd L R)] [PreservesLimit (F ⋙ snd L R) R] : HasLimit F := From 54554e9b41ebd837c9b915cc96117c035446c36a Mon Sep 17 00:00:00 2001 From: JX-Mo <296066944+JX-Mo@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:47:00 +0000 Subject: [PATCH 1028/1300] refactor(RepresentationTheory): move instance Abelian (Rep k G) to Rep.Basic (#41616) This instance removes the commutativity assumption on k in the current instance Abelian (Rep k G) in Rep.Iso. --- Mathlib/RepresentationTheory/Rep/Basic.lean | 2 ++ Mathlib/RepresentationTheory/Rep/Iso.lean | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/RepresentationTheory/Rep/Basic.lean b/Mathlib/RepresentationTheory/Rep/Basic.lean index 09276744938c68..3233d4c0f6e041 100644 --- a/Mathlib/RepresentationTheory/Rep/Basic.lean +++ b/Mathlib/RepresentationTheory/Rep/Basic.lean @@ -570,6 +570,8 @@ instance : Limits.ReflectsLimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCa instance : Limits.ReflectsColimitsOfSize.{w, w} (forget₂ (Rep.{w} k G) (ModuleCat k)) := Limits.reflectsColimits_of_reflectsIsomorphisms +instance : Abelian (Rep.{w} k G) := abelianOfEquivalence (RepToAction k G) + variable {k G} in theorem epi_iff_surjective (f : A ⟶ B) : Epi f ↔ Function.Surjective f.hom := ⟨fun _ => (ModuleCat.epi_iff_surjective ((forget₂ _ _).map f)).1 inferInstance, diff --git a/Mathlib/RepresentationTheory/Rep/Iso.lean b/Mathlib/RepresentationTheory/Rep/Iso.lean index aa51648026bf75..4c3818e73a9c3b 100644 --- a/Mathlib/RepresentationTheory/Rep/Iso.lean +++ b/Mathlib/RepresentationTheory/Rep/Iso.lean @@ -168,8 +168,6 @@ instance : (toModuleMonoidAlgebra.{w} (k := k) (G := G)).IsEquivalence := instance : (ofModuleMonoidAlgebra (k := k) (G := G)).IsEquivalence := (equivalenceModuleMonoidAlgebra (k := k) (G := G)).isEquivalence_inverse -instance : Abelian (Rep.{w} k G) := abelianOfEquivalence toModuleMonoidAlgebra - -- TODO Verify that the equivalence with `ModuleCat k[G]` is a monoidal functor. variable {k G : Type u} [CommRing k] [Monoid G] in From fbced36456c215a7e3e546198e34a2e08b56c122 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:47:03 +0000 Subject: [PATCH 1029/1300] fix(LinearAlgebra/Matrix/Notation): fix defeq abuse in lemma (#42089) Co-authored-by: alreadydone <3064145+alreadydone@users.noreply.github.com> --- Mathlib/LinearAlgebra/Matrix/Notation.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Notation.lean b/Mathlib/LinearAlgebra/Matrix/Notation.lean index d0b88f3a65b8dc..6a2999b09b0318 100644 --- a/Mathlib/LinearAlgebra/Matrix/Notation.lean +++ b/Mathlib/LinearAlgebra/Matrix/Notation.lean @@ -401,7 +401,7 @@ section Submatrix @[simp] theorem submatrix_empty (A : Matrix m' n' α) (row : Fin 0 → m') (col : o' → n') : - submatrix A row col = ![] := + submatrix A row col = of ![] := empty_eq _ set_option backward.isDefEq.respectTransparency false in From 6f1c6456ee863edbcf96c4febc52cd1c8d07487f Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:47:05 +0000 Subject: [PATCH 1030/1300] chore(Analysis/InnerProductSpace): remove misleading comment (#42123) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The comment makes no sense any more: `noncomputable section` checks first if a def is computable, and only if not, makes it noncomputable. So `noncomputable section` wouldn't make a difference here (for an example where `noncomputable def` vs `noncomputable section` makes a difference see [#mathlib4 > noncomputable section @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/noncomputable.20section/near/609434583)). Looking at the git history, it used to be marked `noncomputable def`, but that was removed in #40091 without comment. This is not a performance issue any more, so the comment can just be removed. Co-authored-by: Batixx --- Mathlib/Analysis/InnerProductSpace/Adjoint.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index d9ed9660d2ea58..c7bddb218368d8 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -68,8 +68,6 @@ namespace ContinuousLinearMap variable [CompleteSpace E] [CompleteSpace G] --- Note: made noncomputable to stop excess compilation --- https://github.com/leanprover-community/mathlib4/issues/7103 /-- The adjoint, as a continuous conjugate-linear map. This is only meant as an auxiliary definition for the main definition `adjoint`, where this is bundled as a conjugate-linear isometric equivalence. -/ From 02705be94ef53769c3dbd28e0b2a883e49fbb7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= <4094732+RemyDegenne@users.noreply.github.com> Date: Mon, 27 Jul 2026 16:25:14 +0000 Subject: [PATCH 1031/1300] feat: data processing inequality for the Kullback-Leibler divergence (#35349) Co-authored-by: Remy Degenne --- Mathlib.lean | 1 + Mathlib/Analysis/Convex/Continuous.lean | 93 +++++++++ .../KullbackLeibler/DataProcessing.lean | 193 ++++++++++++++++++ .../Decomposition/IntegralRNDeriv.lean | 27 +-- 4 files changed, 290 insertions(+), 24 deletions(-) create mode 100644 Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean diff --git a/Mathlib.lean b/Mathlib.lean index 41cbea29ef64d5..952307f7e36481 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4904,6 +4904,7 @@ public import Mathlib.InformationTheory.Coding.UniquelyDecodable public import Mathlib.InformationTheory.Hamming public import Mathlib.InformationTheory.KullbackLeibler.Basic public import Mathlib.InformationTheory.KullbackLeibler.ChainRule +public import Mathlib.InformationTheory.KullbackLeibler.DataProcessing public import Mathlib.InformationTheory.KullbackLeibler.KLFun public import Mathlib.Init public import Mathlib.Lean.ContextInfo diff --git a/Mathlib/Analysis/Convex/Continuous.lean b/Mathlib/Analysis/Convex/Continuous.lean index b43a4a75640fa7..5c6ace7d827db2 100644 --- a/Mathlib/Analysis/Convex/Continuous.lean +++ b/Mathlib/Analysis/Convex/Continuous.lean @@ -233,3 +233,96 @@ protected lemma ConcaveOn.locallyLipschitz (hf : ConcaveOn ℝ univ f) : Locally -- proof_wanted ConcaveOn.continuousOn_intrinsicInterior (hf : ConcaveOn ℝ C f) : -- ContinuousOn f (intrinsicInterior ℝ C) + +section Intervals + +lemma ConvexOn.continuousOn_Ici {f : ℝ → ℝ} {y : ℝ} (hf_cvx : ConvexOn ℝ (Ici y) f) + (hf_cont : ContinuousWithinAt f (Ici y) y) : + ContinuousOn f (Ici y) := by + intro x hx + rcases eq_or_lt_of_le (α := ℝ) hx with rfl | hxy + · exact hf_cont + · have h := hf_cvx.continuousOn_interior x + simp only [nonempty_Iio, interior_Ici', mem_Ioi] at h + rw [continuousWithinAt_iff_continuousAt (Ioi_mem_nhds hxy)] at h + exact (h hxy).continuousWithinAt + +lemma ConcaveOn.continuousOn_Ici {f : ℝ → ℝ} {y : ℝ} (hf_cnv : ConcaveOn ℝ (Ici y) f) + (hf_cont : ContinuousWithinAt f (Ici y) y) : + ContinuousOn f (Ici y) := by + simpa using hf_cnv.neg.continuousOn_Ici hf_cont.neg + +lemma ConvexOn.continuousOn_Iic {f : ℝ → ℝ} {y : ℝ} (hf_cvx : ConvexOn ℝ (Iic y) f) + (hf_cont : ContinuousWithinAt f (Iic y) y) : + ContinuousOn f (Iic y) := by + intro x hx + rcases eq_or_lt_of_le (α := ℝ) hx with rfl | hxy + · exact hf_cont + · have h := hf_cvx.continuousOn_interior x + simp only [nonempty_Ioi, interior_Iic', mem_Iio] at h + rw [continuousWithinAt_iff_continuousAt (Iio_mem_nhds hxy)] at h + exact (h hxy).continuousWithinAt + +lemma ConcaveOn.continuousOn_Iic {f : ℝ → ℝ} {y : ℝ} (hf_cnv : ConcaveOn ℝ (Iic y) f) + (hf_cont : ContinuousWithinAt f (Iic y) y) : + ContinuousOn f (Iic y) := by + simpa using hf_cnv.neg.continuousOn_Iic hf_cont.neg + +lemma ConvexOn.continuousOn_Ioc {f : ℝ → ℝ} {y z : ℝ} (hf_cvx : ConvexOn ℝ (Ioc y z) f) + (hf_cont : ContinuousWithinAt f (Iic z) z) : + ContinuousOn f (Ioc y z) := by + intro x hx + rcases eq_or_lt_of_le (α := ℝ) hx.2 with rfl | hxz + · rw [continuousWithinAt_Ioc_iff_Iic hx.1] + exact hf_cont + · have h := hf_cvx.continuousOn_interior x + simp only [interior_Ioc, mem_Ioo, hx.1, hxz, and_self, forall_const] at h + rw [continuousWithinAt_iff_continuousAt (Ioo_mem_nhds hx.1 hxz)] at h + exact h.continuousWithinAt + +lemma ConcaveOn.continuousOn_Ioc {f : ℝ → ℝ} {y z : ℝ} (hf_cnv : ConcaveOn ℝ (Ioc y z) f) + (hf_cont : ContinuousWithinAt f (Iic z) z) : + ContinuousOn f (Ioc y z) := by + simpa using hf_cnv.neg.continuousOn_Ioc hf_cont.neg + +lemma ConvexOn.continuousOn_Ico {f : ℝ → ℝ} {y z : ℝ} (hf_cvx : ConvexOn ℝ (Ico y z) f) + (hf_cont : ContinuousWithinAt f (Ici y) y) : + ContinuousOn f (Ico y z) := by + intro x hx + rcases eq_or_lt_of_le (α := ℝ) hx.1 with rfl | hyx + · rw [continuousWithinAt_Ico_iff_Ici hx.2] + exact hf_cont + · have h := hf_cvx.continuousOn_interior x + simp only [interior_Ico, mem_Ioo, hyx, hx.2, and_self, forall_const] at h + rw [continuousWithinAt_iff_continuousAt (Ioo_mem_nhds hyx hx.2)] at h + exact h.continuousWithinAt + +lemma ConcaveOn.continuousOn_Ico {f : ℝ → ℝ} {y z : ℝ} (hf_cnv : ConcaveOn ℝ (Ico y z) f) + (hf_cont : ContinuousWithinAt f (Ici y) y) : + ContinuousOn f (Ico y z) := by + simpa using hf_cnv.neg.continuousOn_Ico hf_cont.neg + +lemma ConvexOn.continuousOn_Icc {f : ℝ → ℝ} {y z : ℝ} (hf_cvx : ConvexOn ℝ (Icc y z) f) + (hyz : y < z) + (hfy : ContinuousWithinAt f (Ici y) y) (hfz : ContinuousWithinAt f (Iic z) z) : + ContinuousOn f (Icc y z) := by + suffices ContinuousOn f (Ico y z) ∧ ContinuousOn f (Ioc y z) by + intro x hx + rcases eq_or_lt_of_le (α := ℝ) hx.1 with rfl | hyx + · exact hfy.mono (by grind) + rcases eq_or_lt_of_le (α := ℝ) hx.2 with rfl | hxz + · exact hfz.mono (by grind) + have hx := this.1 x (by grind) + rw [continuousWithinAt_iff_continuousAt (Ico_mem_nhds hyx hxz)] at hx + exact hx.continuousWithinAt + refine ⟨ConvexOn.continuousOn_Ico ?_ hfy, ConvexOn.continuousOn_Ioc ?_ hfz⟩ + · exact hf_cvx.subset Ico_subset_Icc_self (convex_Ico y z) + · exact hf_cvx.subset Ioc_subset_Icc_self (convex_Ioc y z) + +lemma ConcaveOn.continuousOn_Icc {f : ℝ → ℝ} {y z : ℝ} (hf_cnv : ConcaveOn ℝ (Icc y z) f) + (hyz : y < z) + (hfy : ContinuousWithinAt f (Ici y) y) (hfz : ContinuousWithinAt f (Iic z) z) : + ContinuousOn f (Icc y z) := by + simpa using hf_cnv.neg.continuousOn_Icc hyz hfy.neg hfz.neg + +end Intervals diff --git a/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean b/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean new file mode 100644 index 00000000000000..31a9e198b2b17e --- /dev/null +++ b/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean @@ -0,0 +1,193 @@ +/- +Copyright (c) 2026 Rémy Degenne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rémy Degenne, Lorenzo Luccioli +-/ +module + +public import Mathlib.MeasureTheory.Function.ConditionalExpectation.Basic +public import Mathlib.InformationTheory.KullbackLeibler.Basic +public import Mathlib.Probability.Kernel.Composition.MeasureComp + +import Mathlib.Analysis.Convex.Approximation +import Mathlib.Analysis.Convex.Deriv +import Mathlib.InformationTheory.KullbackLeibler.ChainRule +import Mathlib.MeasureTheory.Function.ConditionalExpectation.CondJensen +import Mathlib.MeasureTheory.Function.ConditionalExpectation.RadonNikodym + +/-! +# Data processing inequality for the Kullback-Leibler divergence + +The data processing inequality is a way to express the intuition that applying a (possibly random) +transformation to random variables cannot increase the information they contain. + +## Main statements + +We prove three versions of the data processing inequality for the Kullback-Leibler divergence, for +measurable maps, restrictions to sub-sigma-algebras, and composition with Markov kernels. +Let `μ, ν` be finite measures on `𝓧`, with sigma-algebra `m𝓧`. + +* `klDiv_map_le`: `klDiv (μ.map g) (ν.map g) ≤ klDiv μ ν` for a measurable function `g`. +* `klDiv_trim_le`: `klDiv (μ.trim hm) (ν.trim hm) ≤ klDiv μ ν` for a sub-sigma-algebra `m` of `m𝓧` + (with `hm : m ≤ m𝓧`). +* `klDiv_comp_right_le`: `klDiv (κ ∘ₘ μ) (κ ∘ₘ ν) ≤ klDiv μ ν` for a Markov kernel `κ`. + +-/ + +public section + +open Real MeasureTheory Set ProbabilityTheory +open scoped ENNReal + +namespace ConvexOn + +variable {𝓧 𝓨 : Type*} {m m𝓧 : MeasurableSpace 𝓧} {m𝓨 : MeasurableSpace 𝓨} + {μ ν : Measure 𝓧} [IsFiniteMeasure μ] [IsFiniteMeasure ν] {f : ℝ → ℝ} {g : 𝓧 → 𝓨} + +lemma map_condExp_rnDeriv_le (hm : m ≤ m𝓧) (hf : StronglyMeasurable f) + (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont_at : ContinuousWithinAt f (Ici 0) 0) + (h_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) : + (fun x ↦ f ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m]) x)) ≤ᵐ[ν.trim hm] + ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m] := + hf_cvx.map_condExp_le_trim hm (hf_cvx.continuousOn_Ici hf_cont_at).lowerSemicontinuousOn hf + (ae_of_all _ fun _ ↦ ENNReal.toReal_nonneg) isClosed_Ici Measure.integrable_toReal_rnDeriv h_int + +lemma comp_rnDeriv_map_le (hμν : μ ≪ ν) (hg : Measurable g) (hf : StronglyMeasurable f) + (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont_at : ContinuousWithinAt f (Ici 0) 0) + (h_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) : + (fun x ↦ f ((μ.map g).rnDeriv (ν.map g) (g x)).toReal) ≤ᵐ[ν] + ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m𝓨.comap g] := by + filter_upwards [toReal_rnDeriv_map hμν hg, + ae_of_ae_trim _ <| hf_cvx.map_condExp_rnDeriv_le hg.comap_le hf hf_cont_at h_int] with a ha1 ha2 + calc f ((μ.map g).rnDeriv (ν.map g) (g a)).toReal + = f ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m𝓨.comap g]) a) := by rw [ha1] + _ ≤ (ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m𝓨.comap g]) a := ha2 + +lemma integrable_comp_rnDeriv_map (hμν : μ ≪ ν) (hg : Measurable g) (hf : StronglyMeasurable f) + (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont_at : ContinuousWithinAt f (Ici 0) 0) + (h_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) : + Integrable (fun x ↦ f ((μ.map g).rnDeriv (ν.map g) x).toReal) (ν.map g) := by + have hf_cont : ContinuousOn f (Ici 0) := hf_cvx.continuousOn_Ici hf_cont_at + obtain ⟨c, c', h⟩ : ∃ c c', ∀ x, 0 ≤ x → c * x + c' ≤ f x := + hf_cvx.exists_affine_le_real isClosed_Ici hf_cont.lowerSemicontinuousOn + rw [integrable_map_measure (StronglyMeasurable.aestronglyMeasurable (by fun_prop)) + hg.aemeasurable] + refine integrable_of_le_of_le (f := fun x ↦ f ((∂μ.map g/∂ν.map g) (g x)).toReal) + (g₁ := fun x ↦ c * ((∂μ.map g/∂ν.map g) (g x)).toReal + c') + (g₂ := fun x ↦ (ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m𝓨.comap g]) x) + ?_ ?_ ?_ ?_ integrable_condExp + · exact StronglyMeasurable.aestronglyMeasurable (by fun_prop) + · exact ae_of_all _ (fun x ↦ h _ ENNReal.toReal_nonneg) + · exact hf_cvx.comp_rnDeriv_map_le hμν hg hf hf_cont_at h_int + · refine (Integrable.const_mul ?_ _).add (integrable_const _) + rw [integrable_congr (toReal_rnDeriv_map hμν hg)] + fun_prop + +lemma comp_rnDeriv_trim_le (hm : m ≤ m𝓧) (hμν : μ ≪ ν) (hf : StronglyMeasurable f) + (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont_at : ContinuousWithinAt f (Ici 0) 0) + (h_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) : + (fun x ↦ f ((∂μ.trim hm/∂ν.trim hm) x).toReal) ≤ᵐ[ν.trim hm] + ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m] := by + filter_upwards [toReal_rnDeriv_trim hm hμν, + hf_cvx.map_condExp_rnDeriv_le hm hf hf_cont_at h_int] with a ha1 ha2 + calc f ((∂μ.trim hm/∂ν.trim hm) a).toReal + = f ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m]) a) := by rw [ha1] + _ ≤ (ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m]) a := ha2 + +lemma integrable_comp_rnDeriv_trim (hm : m ≤ m𝓧) (hμν : μ ≪ ν) (hf : StronglyMeasurable f) + (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont_at : ContinuousWithinAt f (Ici 0) 0) + (h_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) : + Integrable (fun x ↦ f ((μ.trim hm).rnDeriv (ν.trim hm) x).toReal) (ν.trim hm) := by + have hf_cont : ContinuousOn f (Ici 0) := hf_cvx.continuousOn_Ici hf_cont_at + obtain ⟨c, c', h⟩ : ∃ c c', ∀ x, 0 ≤ x → c * x + c' ≤ f x := + hf_cvx.exists_affine_le_real isClosed_Ici hf_cont.lowerSemicontinuousOn + refine integrable_of_le_of_le (f := fun x ↦ f ((∂μ.trim hm/∂ν.trim hm) x).toReal) + (g₁ := fun x ↦ c * ((∂μ.trim hm/∂ν.trim hm) x).toReal + c') + (g₂ := fun x ↦ (ν[fun x ↦ f (μ.rnDeriv ν x).toReal | m]) x) + ?_ ?_ ?_ ?_ ?_ + · exact StronglyMeasurable.aestronglyMeasurable (by fun_prop) + · exact ae_of_all _ (fun x ↦ h _ ENNReal.toReal_nonneg) + · exact hf_cvx.comp_rnDeriv_trim_le hm hμν hf hf_cont_at h_int + · exact (Integrable.const_mul (by fun_prop) _).add (integrable_const _) + · exact integrable_condExp.trim hm stronglyMeasurable_condExp + +lemma integrable_comp_condExp_rnDeriv (hm : m ≤ m𝓧) (hμν : μ ≪ ν) (hf : StronglyMeasurable f) + (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont_at : ContinuousWithinAt f (Ici 0) 0) + (h_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) : + Integrable (fun x ↦ f ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m]) x)) ν := by + have h := integrable_comp_rnDeriv_trim hm hμν hf hf_cvx hf_cont_at h_int + refine integrable_of_integrable_trim hm ((integrable_congr ?_).mp h) + filter_upwards [toReal_rnDeriv_trim hm hμν] with a ha + rw [ha] + +end ConvexOn + +namespace InformationTheory + +variable {𝓧 𝓨 : Type*} {m m𝓧 : MeasurableSpace 𝓧} {m𝓨 : MeasurableSpace 𝓨} {μ ν : Measure 𝓧} + [IsFiniteMeasure μ] [IsFiniteMeasure ν] {g : 𝓧 → 𝓨} + +lemma integrable_llr_map (hμν : μ ≪ ν) (hg : Measurable g) + (h_int : Integrable (llr μ ν) μ) : + Integrable (llr (μ.map g) (ν.map g)) (μ.map g) := by + rw [← integrable_klFun_rnDeriv_iff (hμν.map hg)] + refine convexOn_klFun.integrable_comp_rnDeriv_map hμν hg (by fun_prop) (by fun_prop) ?_ + rwa [integrable_klFun_rnDeriv_iff hμν] + +lemma toReal_klDiv_map_of_ac (hμν : μ ≪ ν) (hg : Measurable g) : + (klDiv (μ.map g) (ν.map g)).toReal = + ∫ x, klFun ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m𝓨.comap g]) x) ∂ν := by + rw [toReal_klDiv_eq_integral_klFun (hμν.map hg), integral_map hg.aemeasurable + (StronglyMeasurable.aestronglyMeasurable (by fun_prop))] + refine integral_congr_ae ?_ + filter_upwards [toReal_rnDeriv_map hμν hg] with a ha using by rw [ha] + +lemma klDiv_map_of_ac (hμν : μ ≪ ν) (hg : Measurable g) (h_int : Integrable (llr μ ν) μ) : + klDiv (μ.map g) (ν.map g) = + ENNReal.ofReal (∫ x, klFun ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m𝓨.comap g]) x) ∂ν) := by + rw [klDiv_eq_integral_klFun, if_pos ⟨hμν.map hg, integrable_llr_map hμν hg h_int⟩] + congr + rw [← toReal_klDiv_eq_integral_klFun (hμν.map hg), toReal_klDiv_map_of_ac hμν hg] + +lemma toReal_klDiv_trim_of_ac (hm : m ≤ m𝓧) (hμν : μ ≪ ν) : + (klDiv (μ.trim hm) (ν.trim hm)).toReal = + ∫ x, klFun ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m]) x) ∂ν := by + simp [trim_eq_map, toReal_klDiv_map_of_ac hμν (measurable_id'' hm)] + +variable (μ ν) in +/-- **Data processing inequality** for the Kullback-Leibler divergence and measurable functions. -/ +theorem klDiv_map_le (hg : Measurable g) : klDiv (μ.map g) (ν.map g) ≤ klDiv μ ν := by + by_cases hμν : μ ≪ ν + swap; · simp [hμν] + by_cases h_int : Integrable (llr μ ν) μ + swap; · simp [klDiv_of_not_integrable h_int] + rw [klDiv_map_of_ac hμν hg h_int, klDiv_eq_integral_klFun] + simp only [hμν, h_int, and_self, ↓reduceIte] + conv_rhs => rw [← integral_condExp hg.comap_le] + gcongr 1 + have hf : StronglyMeasurable klFun := by fun_prop + have hf_cont : ContinuousWithinAt klFun (Ici 0) 0 := by fun_prop + have h_int' : Integrable (fun x ↦ klFun (μ.rnDeriv ν x).toReal) ν := by + rwa [integrable_klFun_rnDeriv_iff hμν] + refine integral_mono_ae ?_ integrable_condExp ?_ + · exact convexOn_klFun.integrable_comp_condExp_rnDeriv hg.comap_le hμν hf hf_cont h_int' + · refine ae_of_ae_trim hg.comap_le ?_ + exact convexOn_klFun.map_condExp_rnDeriv_le hg.comap_le hf hf_cont h_int' + +variable (μ ν) in +/-- **Data processing inequality** for the Kullback-Leibler divergence and sub-sigma-algebras. -/ +theorem klDiv_trim_le (hm : m ≤ m𝓧) : klDiv (μ.trim hm) (ν.trim hm) ≤ klDiv μ ν := by + simp_rw [trim_eq_map] + exact klDiv_map_le μ ν (measurable_id'' hm) + +variable (μ ν) in +/-- The **Data Processing Inequality** for the Kullback-Leibler divergence and a Markov kernel. -/ +theorem klDiv_comp_right_le (κ : Kernel 𝓧 𝓨) [IsMarkovKernel κ] : + klDiv (κ ∘ₘ μ) (κ ∘ₘ ν) ≤ klDiv μ ν := + calc klDiv (κ ∘ₘ μ) (κ ∘ₘ ν) + _ ≤ klDiv (μ ⊗ₘ κ) (ν ⊗ₘ κ) := by + rw [← Measure.snd_compProd, ← Measure.snd_compProd] + exact klDiv_map_le _ _ measurable_snd + _ = klDiv μ ν := klDiv_compProd_left μ ν κ + +end InformationTheory diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean b/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean index c0208fbb633ae9..5d5c670a5a17e3 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/IntegralRNDeriv.lean @@ -50,14 +50,7 @@ lemma le_integral_rnDeriv_of_ac [IsFiniteMeasure μ] [IsProbabilityMeasure ν] (hf_cvx : ConvexOn ℝ (Ici 0) f) (hf_cont : ContinuousWithinAt f (Ici 0) 0) (hf_int : Integrable (fun x ↦ f (μ.rnDeriv ν x).toReal) ν) (hμν : μ ≪ ν) : f (μ.real univ) ≤ ∫ x, f (μ.rnDeriv ν x).toReal ∂ν := by - have hf_cont' : ContinuousOn f (Ici 0) := by - intro x hx - rcases eq_or_lt_of_le (α := ℝ) (hx : 0 ≤ x) with rfl | hx_pos - · exact hf_cont - · have h := hf_cvx.continuousOn_interior x - simp only [nonempty_Iio, interior_Ici', mem_Ioi] at h - rw [continuousWithinAt_iff_continuousAt (Ioi_mem_nhds hx_pos)] at h - exact (h hx_pos).continuousWithinAt + have hf_cont' : ContinuousOn f (Ici 0) := hf_cvx.continuousOn_Ici hf_cont calc f (μ.real univ) = f (∫ x, (μ.rnDeriv ν x).toReal ∂ν) := by rw [Measure.integral_toReal_rnDeriv hμν] _ ≤ ∫ x, f (μ.rnDeriv ν x).toReal ∂ν := by @@ -140,14 +133,7 @@ lemma _root_.ConvexOn.apply_rnDeriv_ae_le_integral (hf : StronglyMeasurable f) (hκη : μ ⊗ₘ κ ≪ μ ⊗ₘ η) : (fun a ↦ f (μ.rnDeriv ν a).toReal) ≤ᵐ[ν] fun a ↦ ∫ b, f ((μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) (a, b)).toReal ∂(η a) := by - have hf_cont : ContinuousOn f (Ici 0) := by - intro x hx - rcases eq_or_lt_of_le (α := ℝ) (hx : 0 ≤ x) with rfl | hx_pos - · exact hf_cont_at - · have h := hf_cvx.continuousOn_interior x (by simpa) - simp only [nonempty_Iio, interior_Ici', - continuousWithinAt_iff_continuousAt (Ioi_mem_nhds hx_pos)] at h - exact h.continuousWithinAt + have hf_cont : ContinuousOn f (Ici 0) := hf_cvx.continuousOn_Ici hf_cont_at have h_lt_top : ∀ᵐ a ∂ν, ∀ᵐ b ∂η a, (μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) (a, b) < ∞ := Measure.ae_ae_of_ae_compProd <| (μ ⊗ₘ κ).rnDeriv_lt_top (ν ⊗ₘ η) have h_integrable : Integrable (fun x ↦ ((μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) x).toReal) (ν ⊗ₘ η) := @@ -193,14 +179,7 @@ lemma _root_.ConvexOn.integrable_apply_rnDeriv_of_integrable_compProd (hf : Stro (hf_int : Integrable (fun p ↦ f ((μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) p).toReal) (ν ⊗ₘ η)) (hκη : μ ⊗ₘ κ ≪ μ ⊗ₘ η) : Integrable (fun a ↦ f (μ.rnDeriv ν a).toReal) ν := by - have hf_cont : ContinuousOn f (Ici 0) := by - intro x hx - rcases eq_or_lt_of_le (α := ℝ) (hx : 0 ≤ x) with rfl | hx_pos - · exact hf_cont_at - · have h := hf_cvx.continuousOn_interior x (by simpa) - simp only [nonempty_Iio, interior_Ici', - continuousWithinAt_iff_continuousAt (Ioi_mem_nhds hx_pos)] at h - exact h.continuousWithinAt + have hf_cont : ContinuousOn f (Ici 0) := hf_cvx.continuousOn_Ici hf_cont_at obtain ⟨c, c', h⟩ : ∃ c c', ∀ x, 0 ≤ x → c * x + c' ≤ f x := hf_cvx.exists_affine_le_real isClosed_Ici hf_cont.lowerSemicontinuousOn refine integrable_of_le_of_le (f := fun a ↦ f (μ.rnDeriv ν a).toReal) From 1faf046ea0b85f32a1548e63f41bb1d1070ee115 Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Mon, 27 Jul 2026 16:25:17 +0000 Subject: [PATCH 1032/1300] chore(Data/FunLike): tag `IsApply` lemmas as simp (#42027) The new `IsApply` typeclasses allow many existing special-case `coe_xxx` lemmas to be unified; but the general lemmas currently do not have the simp tag. This tags them as simp. Other minor changes: - There were two lemmas with statements identical up to argument order: `FunLike.coe_smul` (directly written) and `FunLike.coe_smul'` (auto-generated by `to_additive`). I unified these using `to_additive existing`, with a deprecation alias for `FunLike.coe_smul'`. - Downstream code that uses `FunLike.coe_smul'` is adjusted appropriately (un-squeezing a couple of lengthy terminal `simp only`'s in the process). - One more specific simp lemma downstream (`ContinuousLinearMap.coe_pow'`) is removed, because `simp` can now prove it using the `FunLike` simp lemmas. A misnamed lemma in this file, `ContinuousLinearMap.coe_pow`, was re-named to `ContinuousLinearMap.toLinearMap_pow`. - There were just two simps (both in `Mathlib/Probability/Distributions/Gaussian/Basic.lean`) which broke, because they used an un-squeezed `simp` along with an additional explicitly provided lemma (not part of the default simp set) that conflicted with `FunLike.coe_zero`. These I fixed by explicitly removing `FunLike.coe_zero` from the simp set where necessary. --- .../Analysis/SpecialFunctions/Pow/Deriv.lean | 13 +----- Mathlib/Data/FunLike/IsApply.lean | 42 +++++++++++-------- .../Eigenspace/ContinuousLinearMap.lean | 3 +- .../VectorMeasure/SetIntegral.lean | 2 +- .../ModularForms/JacobiTheta/TwoVariable.lean | 14 +++---- .../Distributions/Gaussian/Basic.lean | 9 ++-- .../Module/ContinuousLinearMap/Basic.lean | 11 ++--- 7 files changed, 44 insertions(+), 50 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean index 6c642b86a86689..da5718034d2345 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Deriv.lean @@ -178,15 +178,6 @@ open Complex variable {f g : ℂ → ℂ} {s : Set ℂ} {f' g' x c : ℂ} -/-- A private lemma that rewrites the output of lemmas like `HasFDerivAt.cpow` to the form -expected by lemmas like `HasDerivAt.cpow`. -/ -private theorem aux : ((g x * f x ^ (g x - 1)) • (1 : ℂ →L[ℂ] ℂ).smulRight f' + - (f x ^ g x * log (f x)) • (1 : ℂ →L[ℂ] ℂ).smulRight g') 1 = - g x * f x ^ (g x - 1) * f' + f x ^ g x * log (f x) * g' := by - simp only [smul_eq_mul, one_mul, one_apply_eq_self, - ContinuousLinearMap.smulRight_apply, add_apply, Pi.smul_apply, - FunLike.coe_smul'] - nonrec theorem HasStrictDerivAt.cpow (hf : HasStrictDerivAt f f' x) (hg : HasStrictDerivAt g g' x) (h0 : f x ∈ slitPlane) : HasStrictDerivAt (fun x => f x ^ g x) (g x * f x ^ (g x - 1) * f' + f x ^ g x * Complex.log (f x) * g') x := by @@ -209,7 +200,7 @@ theorem HasStrictDerivAt.cpow_const (hf : HasStrictDerivAt f f' x) theorem HasDerivAt.cpow (hf : HasDerivAt f f' x) (hg : HasDerivAt g g' x) (h0 : f x ∈ slitPlane) : HasDerivAt (fun x => f x ^ g x) (g x * f x ^ (g x - 1) * f' + f x ^ g x * Complex.log (f x) * g') x := by - simpa [aux] using (hf.hasFDerivAt.cpow hg h0).hasDerivAt + simpa using (hf.hasFDerivAt.cpow hg h0).hasDerivAt theorem HasDerivAt.const_cpow (hf : HasDerivAt f f' x) (h0 : c ≠ 0 ∨ f x ≠ 0) : HasDerivAt (fun x => c ^ f x) (c ^ f x * Complex.log c * f') x := @@ -222,7 +213,7 @@ theorem HasDerivAt.cpow_const (hf : HasDerivAt f f' x) (h0 : f x ∈ slitPlane) theorem HasDerivWithinAt.cpow (hf : HasDerivWithinAt f f' s x) (hg : HasDerivWithinAt g g' s x) (h0 : f x ∈ slitPlane) : HasDerivWithinAt (fun x => f x ^ g x) (g x * f x ^ (g x - 1) * f' + f x ^ g x * Complex.log (f x) * g') s x := by - simpa [aux] using (hf.hasFDerivWithinAt.cpow hg h0).hasDerivWithinAt + simpa using (hf.hasFDerivWithinAt.cpow hg h0).hasDerivWithinAt theorem HasDerivWithinAt.const_cpow (hf : HasDerivWithinAt f f' s x) (h0 : c ≠ 0 ∨ f x ≠ 0) : HasDerivWithinAt (fun x => c ^ f x) (c ^ f x * Complex.log c * f') s x := diff --git a/Mathlib/Data/FunLike/IsApply.lean b/Mathlib/Data/FunLike/IsApply.lean index e8848acbcec5a7..8136659ac29305 100644 --- a/Mathlib/Data/FunLike/IsApply.lean +++ b/Mathlib/Data/FunLike/IsApply.lean @@ -204,7 +204,7 @@ variable {M M' F F' α β : Type*} [FunLike F α β] [FunLike F' α α] section Coercion -@[to_additive (attr := norm_cast)] +@[to_additive (attr := simp, norm_cast)] theorem coe_one [One F] [One β] [IsOneApply F α β] : ↑(1 : F) = (1 : α → β) := by ext; simp @[to_additive (attr := simp)] @@ -213,67 +213,73 @@ theorem coe_one_iff [One F] [One β] [IsOneApply F α β] (f : F) : (f : α → · intro h simp [DFunLike.ext_iff, h] · intro h - simp [funext_iff, h] + simp [h] -@[to_additive (attr := norm_cast)] +@[to_additive (attr := simp, norm_cast)] theorem coe_mul [Mul F] [Mul β] [IsMulApply F α β] (f g : F) : ↑(f * g) = (f : α → β) * g := by ext; simp -@[to_additive (attr := norm_cast)] +@[to_additive (attr := simp, norm_cast)] theorem coe_div [Div F] [Div β] [IsDivApply F α β] (f g : F) : ↑(f / g) = (f : α → β) / g := by ext; simp -@[to_additive (attr := norm_cast)] +@[to_additive (attr := simp, norm_cast)] theorem coe_inv [Inv F] [Inv β] [IsInvApply F α β] (f : F) : ↑(f⁻¹) = (f : α → β)⁻¹ := by ext; simp -@[to_additive (attr := norm_cast)] +@[to_additive (attr := simp, norm_cast)] theorem coe_smul [SMul M F] [SMul M β] [IsSMulApply M F α β] (n : M) (f : F) : ↑(n • f) = n • (f : α → β) := by ext; simp -@[to_additive coe_smul'] +@[deprecated (since := "2026-07-23")] alias coe_smul' := coe_smul + +@[simp, norm_cast, to_additive existing coe_smul] theorem coe_pow [Pow F M] [Pow β M] [IsPowApply M F α β] (f : F) (n : M) : ↑(f ^ n) = (f : α → β) ^ n := by ext; simp -attribute [norm_cast] coe_pow - -@[norm_cast] +@[simp, norm_cast] theorem coe_one_eq_id [One F'] [IsOneApplyEqSelf F' α] : ↑(1 : F') = id := by ext; simp -@[simp] +@[simp, norm_cast] theorem coe_one_eq_id_iff [One F'] [IsOneApplyEqSelf F' α] (f : F') : (f : α → α) = id ↔ f = 1 := by constructor · intro h simp [DFunLike.ext_iff, h] · intro h - simp [funext_iff, h] + simp [h] -@[norm_cast] +@[simp, norm_cast] theorem coe_mul_eq_comp [Mul F'] [IsMulApplyEqComp F' α] (f g : F') : ↑(f * g) = f ∘ g := by ext; simp -@[norm_cast] +@[simp, norm_cast] lemma coe_pow_eq_iterate [Monoid F'] [IsMulApplyEqComp F' α] [IsOneApplyEqSelf F' α] (f : F') (n : ℕ) : ⇑(f ^ n) = f^[n] := funext <| pow_apply_eq_iterate f n +-- this lemma cannot be `simp` since this creates loops @[norm_cast] -theorem coe_natCast [NatCast F'] [One F'] [SMul Nat α] [SMul Nat F'] [IsSMulApply Nat F' α α] - [IsNatCastApply F' α] [IsOneApplyEqSelf F' α] (n : Nat) : +theorem natCast_eq_nsmul_one [NatCast F'] [One F'] [SMul Nat α] [SMul Nat F'] + [IsSMulApply Nat F' α α] [IsNatCastApply F' α] [IsOneApplyEqSelf F' α] (n : ℕ) : (n : F') = n • (1 : F') := by apply DFunLike.ext simp +@[deprecated (since := "2026-07-24")] alias coe_natCast := natCast_eq_nsmul_one + +-- this lemma cannot be `simp` since this creates loops @[norm_cast] -theorem coe_intCast [IntCast F'] [One F'] [SMul Int α] [SMul Int F'] [IsSMulApply Int F' α α] - [IsIntCastApply F' α] [IsOneApplyEqSelf F' α] (n : Int) : +theorem intCast_eq_zsmul_one [IntCast F'] [One F'] [SMul Int α] [SMul Int F'] + [IsSMulApply Int F' α α] [IsIntCastApply F' α] [IsOneApplyEqSelf F' α] (n : ℤ) : (n : F') = n • (1 : F') := by apply DFunLike.ext simp +@[deprecated (since := "2026-07-24")] alias coe_intCast := intCast_eq_zsmul_one + end Coercion end FunLike diff --git a/Mathlib/LinearAlgebra/Eigenspace/ContinuousLinearMap.lean b/Mathlib/LinearAlgebra/Eigenspace/ContinuousLinearMap.lean index cd95994b29a597..e270d5292e1e61 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/ContinuousLinearMap.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/ContinuousLinearMap.lean @@ -26,8 +26,7 @@ variable {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] [TopologicalSp open Module End instance isClosed_genEigenspace : IsClosed (genEigenspace (f : End R M) μ n : Set M) := by - rw [genEigenspace_nat, one_eq_id, ← coe_id, ← toLinearMap_smul, ← toLinearMap_sub, ← coe_pow] - apply isClosed_ker + simpa [genEigenspace_nat] using isClosed_ker ↑((f - μ • 1) ^ n) instance isClosed_eigenspace : IsClosed (eigenspace (f : End R M) μ : Set M) := isClosed_genEigenspace f μ 1 diff --git a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean index a875cde597fe3f..27d13a7cedadf4 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/SetIntegral.lean @@ -252,7 +252,7 @@ theorem setIntegral_of_variation_apply_eq_zero (f : X → E) {s : Set X} rw [variation_restrict h's] apply Measure.restrict_eq_zero.2 hs have : μ.restrict s = 0 := variation_eq_zero.1 this - simpa [integral_eq_setToFun, this] using! setToFun_zero_left + simp [this] theorem setIntegral_dirac' {mX : MeasurableSpace X} [CompleteSpace G] {a : X} {v : F} (hf : StronglyMeasurable f) {s : Set X} (hs : MeasurableSet s) [Decidable (a ∈ s)] : diff --git a/Mathlib/NumberTheory/ModularForms/JacobiTheta/TwoVariable.lean b/Mathlib/NumberTheory/ModularForms/JacobiTheta/TwoVariable.lean index 390947d240021d..a7edac6433ba93 100644 --- a/Mathlib/NumberTheory/ModularForms/JacobiTheta/TwoVariable.lean +++ b/Mathlib/NumberTheory/ModularForms/JacobiTheta/TwoVariable.lean @@ -182,10 +182,9 @@ lemma norm_jacobiTheta₂_term_fderiv_ge (n : ℤ) (z τ : ℂ) : refine (ContinuousLinearMap.le_opNorm _ _).trans ?_ simp_rw [Prod.norm_def, norm_one, norm_zero, max_eq_right zero_le_one, mul_one, le_refl] refine le_trans ?_ this - simp_rw [jacobiTheta₂_term_fderiv, jacobiTheta₂_term, FunLike.coe_smul', - Pi.smul_apply, add_apply, FunLike.coe_smul', - ContinuousLinearMap.coe_fst', ContinuousLinearMap.coe_snd', Pi.smul_apply, smul_zero, zero_add, - smul_eq_mul, mul_one, mul_comm _ ‖cexp _‖, norm_mul] + simp_rw [jacobiTheta₂_term_fderiv, jacobiTheta₂_term, FunLike.coe_smul, Pi.smul_apply, add_apply, + FunLike.coe_smul, ContinuousLinearMap.coe_fst', ContinuousLinearMap.coe_snd', Pi.smul_apply, + smul_zero, zero_add, smul_eq_mul, mul_one, mul_comm _ ‖cexp _‖, norm_mul] refine mul_le_mul_of_nonneg_left (le_of_eq ?_) (norm_nonneg _) simp_rw [norm_real, norm_of_nonneg pi_pos.le, norm_I, mul_one, Int.cast_abs, ← norm_intCast, norm_pow] @@ -346,11 +345,8 @@ lemma hasDerivAt_jacobiTheta₂_fst (z : ℂ) {τ : ℂ} (hτ : 0 < im τ) : ((jacobiTheta₂_fderiv z τ) (1, 0)) := by apply eval_fst_CLM.hasSum (hasSum_jacobiTheta₂_term_fderiv z hτ) have step2 (n : ℤ) : (jacobiTheta₂_term_fderiv n z τ) (1, 0) = jacobiTheta₂'_term n z τ := by - simp only [jacobiTheta₂_term_fderiv, smul_add, add_apply, - FunLike.coe_smul', ContinuousLinearMap.coe_fst', Pi.smul_apply, smul_eq_mul, - mul_one, ContinuousLinearMap.coe_snd', mul_zero, add_zero, jacobiTheta₂'_term, - jacobiTheta₂_term, mul_comm _ (cexp _)] - rw [funext step2] at step1 + simp [jacobiTheta₂_term_fderiv, jacobiTheta₂'_term, jacobiTheta₂_term, mul_comm] + simp only [step2] at step1 have step3 : HasDerivAt (fun x ↦ jacobiTheta₂ x τ) ((jacobiTheta₂_fderiv z τ) (1, 0)) z := (((hasFDerivAt_jacobiTheta₂ z hτ).comp z (hasFDerivAt_prodMk_left z τ)).hasDerivAt :) rwa [← step1.tsum_eq] at step3 diff --git a/Mathlib/Probability/Distributions/Gaussian/Basic.lean b/Mathlib/Probability/Distributions/Gaussian/Basic.lean index 3163c58577d9df..8bf1f96a53a55a 100644 --- a/Mathlib/Probability/Distributions/Gaussian/Basic.lean +++ b/Mathlib/Probability/Distributions/Gaussian/Basic.lean @@ -51,8 +51,10 @@ instance IsGaussian.toIsProbabilityMeasure {E : Type*} [TopologicalSpace E] [Add [Module ℝ E] {mE : MeasurableSpace E} (μ : Measure E) [IsGaussian μ] : IsProbabilityMeasure μ where measure_univ := by - have : μ.map (0 : StrongDual ℝ E) Set.univ = 1 := by simp [IsGaussian.map_eq_gaussianReal] - simpa [Measure.map_apply (by fun_prop : Measurable (0 : StrongDual ℝ E)) .univ] using this + have : μ.map (0 : StrongDual ℝ E) Set.univ = 1 := by + simp [-FunLike.coe_zero, IsGaussian.map_eq_gaussianReal] + simpa [-FunLike.coe_zero, + Measure.map_apply (by fun_prop : Measurable (0 : StrongDual ℝ E)) .univ] using this /-- A real Gaussian measure is Gaussian. -/ instance isGaussian_gaussianReal (m : ℝ) (v : ℝ≥0) : IsGaussian (gaussianReal m v) where @@ -171,8 +173,7 @@ theorem isGaussian_iff_charFunDual_eq {μ : Measure E} [IsFiniteMeasure μ] : refine ⟨fun h ↦ h.charFunDual_eq, fun h ↦ ⟨fun L ↦ Measure.ext_of_charFun ?_⟩⟩ ext u rw [charFun_map_eq_charFunDual_smul L u, h (u • L), charFun_gaussianReal] - simp only [FunLike.coe_smul', Pi.smul_apply, smul_eq_mul, ofReal_mul, - Real.coe_toNNReal'] + simp only [smul_apply, smul_eq_mul, ofReal_mul, Real.coe_toNNReal'] congr · rw [integral_const_mul, integral_complex_ofReal] · rw [max_eq_left (variance_nonneg _ _), mul_comm, ← ofReal_pow, ← ofReal_mul, diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean index ed53c3f3e73580..2f0b3d8ffb97e1 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean @@ -589,13 +589,14 @@ theorem toLinearMap_mul (f g : M₁ →L[R₁] M₁) : (↑(f * g) : M₁ →ₗ instance monoidWithZero : MonoidWithZero (M₁ →L[R₁] M₁) := fast_instance% FunLike.monoidWithZero -@[simp, norm_cast] -theorem coe_pow' (f : M₁ →L[R₁] M₁) (n : ℕ) : ⇑(f ^ n) = f^[n] := - hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _ +@[deprecated (since := "2026-07-23")] alias coe_pow' := FunLike.coe_pow_eq_iterate @[simp, norm_cast] -theorem coe_pow (f : M₁ →L[R₁] M₁) (n : ℕ) : (↑(f ^ n) : M₁ →ₗ[R₁] M₁) = f ^ n := - DFunLike.ext' <| (coe_pow' f n).trans <| .symm <| hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _ +theorem toLinearMap_pow (f : M₁ →L[R₁] M₁) (n : ℕ) : (↑(f ^ n) : M₁ →ₗ[R₁] M₁) = f ^ n := + DFunLike.ext' <| (FunLike.coe_pow_eq_iterate f n).trans + <| .symm <| hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _ + +@[deprecated (since := "2026-07-24")] protected alias coe_pow := toLinearMap_pow instance instNatCast [ContinuousAdd M₁] : NatCast (M₁ →L[R₁] M₁) where natCast n := n • (1 : M₁ →L[R₁] M₁) From d732046e27b217ada79387287ede948126c8cf40 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Mon, 27 Jul 2026 16:25:21 +0000 Subject: [PATCH 1033/1300] refactor: generalize `Module.Finite.of_surjective` to arbitrary ring homomorphisms (#42054) --- Mathlib/RingTheory/Finiteness/Basic.lean | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Mathlib/RingTheory/Finiteness/Basic.lean b/Mathlib/RingTheory/Finiteness/Basic.lean index 48ec5fc228a02c..3f21935a1d41da 100644 --- a/Mathlib/RingTheory/Finiteness/Basic.lean +++ b/Mathlib/RingTheory/Finiteness/Basic.lean @@ -244,19 +244,18 @@ instance (priority := 100) of_finite [Finite M] : Module.Finite R M := by section -variable {S} {P : Type*} [Semiring S] [AddCommMonoid P] [Module S P] - {σ : R →+* S} [RingHomSurjective σ] +variable {S} {P : Type*} [Semiring S] [AddCommMonoid P] [Module S P] {σ : R →+* S} --- TODO: remove RingHomSurjective @[stacks 0519 "(3)"] theorem of_surjective [hM : Module.Finite R M] (f : M →ₛₗ[σ] P) (hf : Surjective f) : - Module.Finite S P := - ⟨by - rw [← LinearMap.range_eq_top.mpr hf, ← Submodule.map_top] - exact hM.fg_top.map f⟩ - -theorem _root_.LinearMap.finite_iff_of_bijective (f : M →ₛₗ[σ] P) (hf : Function.Bijective f) : - Module.Finite R M ↔ Module.Finite S P := + Module.Finite S P := by + rw [Module.finite_def, Submodule.fg_def] at hM ⊢ + obtain ⟨s, hsfin, hs⟩ := hM + refine ⟨f '' s, hsfin.image f, eq_top_iff.mpr fun p _ ↦ ?_⟩ + exact image_span_subset_span f s (by simpa [hs] using hf p) + +theorem _root_.LinearMap.finite_iff_of_bijective [RingHomSurjective σ] + (f : M →ₛₗ[σ] P) (hf : Function.Bijective f) : Module.Finite R M ↔ Module.Finite S P := ⟨fun _ ↦ of_surjective f hf.surjective, fun _ ↦ ⟨fg_of_fg_map_injective f hf.injective <| by rwa [Submodule.map_top, LinearMap.range_eq_top.mpr hf.surjective, ← Module.finite_def]⟩⟩ From 024a9ab3987d59c694a3c3900d9ac06b4f5d9b93 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 27 Jul 2026 17:36:02 +0000 Subject: [PATCH 1034/1300] chore(Geometry/Manifold): fix defs with underscores (#42115) This PR deprecates all definitions in differential geometry with underscores in their names, and renames it according to the naming convention. Co-authored-by: Batixx --- Mathlib/Geometry/Manifold/ChartedSpace.lean | 14 +- .../Geometry/Manifold/IsManifold/Basic.lean | 4 +- .../CovariantDerivative/Basic.lean | 31 ++- .../Manifold/VectorBundle/LocalFrame.lean | 177 +++++++++++------- .../Manifold/VectorBundle/Tensoriality.lean | 4 +- 5 files changed, 148 insertions(+), 82 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 09085d21806afb..7d8921e0f69e1f 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -359,7 +359,7 @@ We keep this as a definition (not an instance) to avoid instance search trying t `DiscreteTopology` or `Unique` instances. -/ @[instance_reducible] -def ChartedSpace.of_discreteTopology [TopologicalSpace M] [TopologicalSpace H] +def ChartedSpace.ofDiscreteTopology [TopologicalSpace M] [TopologicalSpace H] [DiscreteTopology M] [h : Unique H] : ChartedSpace H M where atlas := letI f := fun x : M ↦ OpenPartialHomeomorph.const @@ -369,11 +369,14 @@ def ChartedSpace.of_discreteTopology [TopologicalSpace M] [TopologicalSpace H] mem_chart_source x := by simp chart_mem_atlas x := by simp +@[deprecated (since := "2026-07-26")] +alias ChartedSpace.of_discreteTopology := ChartedSpace.ofDiscreteTopology + /-- A chart on the discrete space is the constant chart. -/ @[simp, mfld_simps] lemma chartedSpace_of_discreteTopology_chartAt [TopologicalSpace M] [TopologicalSpace H] [DiscreteTopology M] [h : Unique H] {x : M} : - haveI := ChartedSpace.of_discreteTopology (M := M) (H := H) + haveI := ChartedSpace.ofDiscreteTopology (M := M) (H := H) chartAt H x = OpenPartialHomeomorph.const (isOpen_discrete {x}) (isOpen_discrete {h.default}) := rfl @@ -496,7 +499,7 @@ variable [TopologicalSpace H] [TopologicalSpace M] [TopologicalSpace M'] /-- The disjoint union of two charted spaces modelled on a non-empty space `H` is a charted space over `H`. -/ @[instance_reducible] -def ChartedSpace.sum_of_nonempty [Nonempty H] : ChartedSpace H (M ⊕ M') where +def ChartedSpace.sumOfNonempty [Nonempty H] : ChartedSpace H (M ⊕ M') where atlas := ((fun e ↦ e.lift_openEmbedding IsOpenEmbedding.inl) '' cm.atlas) ∪ ((fun e ↦ e.lift_openEmbedding IsOpenEmbedding.inr) '' cm'.atlas) -- At `x : M`, the chart is the chart in `M`; at `x' ∈ M'`, it is the chart in `M'`. @@ -523,9 +526,12 @@ def ChartedSpace.sum_of_nonempty [Nonempty H] : ChartedSpace H (M ⊕ M') where right use ChartedSpace.chartAt x, cm'.chart_mem_atlas x +@[deprecated (since := "2026-07-26")] +alias ChartedSpace.sum_of_nonempty := ChartedSpace.sumOfNonempty + instance ChartedSpace.sum : ChartedSpace H (M ⊕ M') := by by_cases! h : Nonempty H - · exact ChartedSpace.sum_of_nonempty + · exact ChartedSpace.sumOfNonempty have : IsEmpty M := isEmpty_of_chartedSpace H have : IsEmpty M' := isEmpty_of_chartedSpace H exact empty H (M ⊕ M') diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 8e1ea40bbda521..7209dff92e77c7 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -912,14 +912,14 @@ instance empty [IsEmpty M] : IsManifold I n M := by _ = ∅ := empty_inter (range I) apply (this ▸ hx).elim -attribute [local instance] ChartedSpace.of_discreteTopology in +attribute [local instance] ChartedSpace.ofDiscreteTopology in variable (n) in /-- A discrete space `M` is a smooth manifold over the trivial model on a trivial normed space. -/ theorem of_discreteTopology [DiscreteTopology M] [Unique E] : IsManifold (modelWithCornersSelf 𝕜 E) n M := by apply isManifold_of_contDiffOn _ _ _ (fun _ _ _ _ ↦ contDiff_of_subsingleton.contDiffOn) -attribute [local instance] ChartedSpace.of_discreteTopology in +attribute [local instance] ChartedSpace.ofDiscreteTopology in example [Unique E] : IsManifold (𝓘(𝕜, E)) n (Fin 2) := of_discreteTopology _ set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index b110822d13f782..4b1a5ae99454b9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -387,17 +387,20 @@ lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 /-- If `cov` is a covariant derivative on each set in an open cover, it is a covariant derivative. -/ -def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} +def ofIsCovariantDerivativeOnOfOpenCover {ι : Type*} {s : ι → Set M} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) (hs : ⋃ i, s i = Set.univ) : CovariantDerivative I F V := ⟨cov, hs ▸ IsCovariantDerivativeOn.iUnion hcov⟩ +@[deprecated (since := "2026-07-26")] +alias of_isCovariantDerivativeOn_of_open_cover := ofIsCovariantDerivativeOnOfOpenCover + @[simp] lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set M} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) (hs : ⋃ i, s i = Set.univ) : - of_isCovariantDerivativeOn_of_open_cover hcov hs = cov := rfl + ofIsCovariantDerivativeOnOfOpenCover hcov hs = cov := rfl /-- A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a @@ -433,39 +436,51 @@ one-forms taking values in the endomorphisms of the bundle, but we don’t packa /-- An affine combination of covariant derivatives as a covariant derivative. -/ @[simps] -def affine_combination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : +def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : CovariantDerivative I F V where toFun := fun σ ↦ (g • (cov σ)) + (1 - g) • (cov' σ) isCovariantDerivativeOnUniv := cov.isCovariantDerivativeOn.affine_combination cov'.isCovariantDerivativeOn _ +@[deprecated (since := "2026-07-26")] alias affine_combination := affineCombination + /-- A finite affine combination of covariant derivatives as a covariant derivative. -/ -def finite_affine_combination {ι : Type*} {s : Finset ι} +def finiteAffineCombination {ι : Type*} {s : Finset ι} (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where toFun t x := ∑ i ∈ s, (f i x) • (cov i) t x isCovariantDerivativeOnUniv := IsCovariantDerivativeOn.finite_affine_combination (fun i ↦ (cov i).isCovariantDerivativeOn) hf +@[deprecated (since := "2026-07-26")] alias finite_affine_combination := finiteAffineCombination + /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.affineCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞ω} (hf : CMDiff n f) (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : - ContMDiffCovariantDerivative (affine_combination cov cov' f) n where + ContMDiffCovariantDerivative (affineCombination cov cov' f) n where contMDiff := ContMDiffCovariantDerivativeOn.affine_combination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff +@[deprecated (since := "2026-07-26")] +alias ContMDiffCovariantDerivative.affine_combination := + ContMDiffCovariantDerivative.affineCombination + /-- An affine combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.finite_affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.finiteAffineCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞ω} (hf' : ∀ i ∈ s, CMDiff n (f i)) (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : - ContMDiffCovariantDerivative (finite_affine_combination cov hf) n where + ContMDiffCovariantDerivative (finiteAffineCombination cov hf) n where contMDiff := ContMDiffCovariantDerivativeOn.finite_affine_combination (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) +@[deprecated (since := "2026-07-26")] +alias ContMDiffCovariantDerivative.finite_affine_combination := + ContMDiffCovariantDerivative.finiteAffineCombination + -- TODO: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index c0ffd9fd8f281c..9c437a587c3cb6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -66,18 +66,18 @@ the model fiber `F`. * `e.localFrame b`: the local frame on `V` induced by `e` and `b`. Use `e.localFrame b i` to access the i-th section in that frame. * `e.contMDiffOn_localFrame_baseSet`: each section `e.localFrame b i` is smooth on `e.baseSet` -* `e.localFrame_coeff b i` describes the `i`-th coefficient of sections of `V` w.r.t. +* `e.localFrameCoeff b i` describes the `i`-th coefficient of sections of `V` w.r.t. `e.localFrame b`: it is a family of fiberwise linear maps `Π x, V x →ₗ[𝕜] 𝕜`, and the coefficient - function of a section `s` is `(LinearMap.piApply (e.localFrame_coeff b i)) s`. + function of a section `s` is `(LinearMap.piApply (e.localFrameCoeff b i)) s`. * `e.eventually_eq_localFrame_sum_coeff_smul b`: near `x`, we have - `s = ∑ i, (LinearMap.piApply (e.localFrame_coeff b i) s) • e.localFrame b i` -* `e.localFrame_coeff_congr b`: the coefficient `e.localFrame_coeff b i` of `s` in the local frame + `s = ∑ i, (LinearMap.piApply (e.localFrameCoeff b i) s) • e.localFrame b i` +* `e.localFrameCoeff_congr b`: the coefficient `e.localFrameCoeff b i` of `s` in the local frame induced by `e` and `b` at `x` only depends on `s` at `x`. -* `e.contMDiffOn_localFrame_coeff`: if `s` is a `C^k` section, each coefficient - `(LinearMap.piApply (e.localFrame_coeff b i) s)` is `C^k` on `e.baseSet` -* `e.contMDiffAt_iff_localFrame_coeff b`: a section `s` is `C^k` at `x ∈ e.baseSet` +* `e.contMDiffOn_localFrameCoeff`: if `s` is a `C^k` section, each coefficient + `(LinearMap.piApply (e.localFrameCoeff b i) s)` is `C^k` on `e.baseSet` +* `e.contMDiffAt_iff_localFrameCoeff b`: a section `s` is `C^k` at `x ∈ e.baseSet` iff all of its frame coefficients are -* `e.contMDiffOn_iff_localFrame_coeff b`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` +* `e.contMDiffOn_iff_localFrameCoeff b`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` iff all of its frame coefficients are ## Note @@ -378,58 +378,73 @@ variable (I) in /-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i`. If x is outside of `e.baseSet`, this returns the junk value 0. -/ -def localFrame_coeff (i : ι) : Π x : M, (V x →ₗ[𝕜] 𝕜) := +def localFrameCoeff (i : ι) : Π x : M, (V x →ₗ[𝕜] 𝕜) := (e.isLocalFrameOn_localFrame_baseSet I 1 b).coeff i +@[deprecated (since := "2026-07-26")] alias localFrame_coeff := localFrameCoeff + variable {e b} variable {x x' : M} variable (e b) in @[simp] -lemma localFrame_coeff_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (i : ι) : - e.localFrame_coeff I b i x = 0 := by - simpa [localFrame_coeff] using +lemma localFrameCoeff_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (i : ι) : + e.localFrameCoeff I b i x = 0 := by + simpa [localFrameCoeff] using (e.isLocalFrameOn_localFrame_baseSet I 1 b).coeff_apply_of_notMem hx i +@[deprecated (since := "2026-07-26")] +alias localFrame_coeff_apply_of_notMem_baseSet := localFrameCoeff_apply_of_notMem_baseSet + variable (e b) in @[simp] -lemma localFrame_coeff_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : - (localFrame_coeff I e b i x) (s x) = (e.basisAt b hx).repr (s x) i := by +lemma localFrameCoeff_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : + (localFrameCoeff I e b i x) (s x) = (e.basisAt b hx).repr (s x) i := by have he := e.isLocalFrameOn_localFrame_baseSet I 1 b have hbasis : e.basisAt b hx = he.toBasisAt hx := by ext j simp [IsLocalFrameOn.toBasisAt, localFrame, basisAt, hx] - simp [localFrame_coeff, IsLocalFrameOn.coeff, hx, hbasis] + simp [localFrameCoeff, IsLocalFrameOn.coeff, hx, hbasis] + +@[deprecated (since := "2026-07-26")] +alias localFrame_coeff_apply_of_mem_baseSet := localFrameCoeff_apply_of_mem_baseSet variable {s s' : Π x : M, V x} -lemma eq_sum_localFrame_coeff_smul [Fintype ι] (hx : x' ∈ e.baseSet) : - s x' = ∑ i, e.localFrame_coeff I b i x' (s x') • e.localFrame b i x' := +lemma eq_sum_localFrameCoeff_smul [Fintype ι] (hx : x' ∈ e.baseSet) : + s x' = ∑ i, e.localFrameCoeff I b i x' (s x') • e.localFrame b i x' := (isLocalFrameOn_localFrame_baseSet I 1 e b).coeff_sum_eq s hx +@[deprecated (since := "2026-07-26")] +alias eq_sum_localFrame_coeff_smul := eq_sum_localFrameCoeff_smul + variable (e b) in /-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` of `V` around `x`, we have -`s = ∑ i, (LinearMap.piApply (b.localFrame_coeff e i) s) • b.localFrame e i` near `x`. -/ +`s = ∑ i, (LinearMap.piApply (b.localFrameCoeff e i) s) • b.localFrame e i` near `x`. -/ lemma eventually_eq_localFrame_sum_coeff_smul [Fintype ι] (hxe : x ∈ e.baseSet) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, e.localFrame_coeff I b i x' (s x') • e.localFrame b i x' := - eventually_nhds_iff.mpr ⟨e.baseSet, fun _ ↦ e.eq_sum_localFrame_coeff_smul, e.open_baseSet, hxe⟩ + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, e.localFrameCoeff I b i x' (s x') • e.localFrame b i x' := + eventually_nhds_iff.mpr ⟨e.baseSet, fun _ ↦ e.eq_sum_localFrameCoeff_smul, e.open_baseSet, hxe⟩ variable (e b) in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma localFrame_coeff_congr {i : ι} (hss' : s x = s' x) : - e.localFrame_coeff I b i x (s x) = e.localFrame_coeff I b i x (s' x) := by +lemma localFrameCoeff_congr {i : ι} (hss' : s x = s' x) : + e.localFrameCoeff I b i x (s x) = e.localFrameCoeff I b i x (s' x) := by simpa using! (isLocalFrameOn_localFrame_baseSet I 1 e b).coeff_congr hss' i +@[deprecated (since := "2026-07-26")] alias localFrame_coeff_congr := localFrameCoeff_congr + variable {n} variable (e) in /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the coefficient of "`s x` read in the trivialisation `e`" for `b i`. -/ -lemma localFrame_coeff_eq_coeff (hxe : x ∈ e.baseSet) {i : ι} : - e.localFrame_coeff I b i x (s x) = b.repr (e ((T% s) x)).2 i := by - simp [e.localFrame_coeff_apply_of_mem_baseSet b hxe, basisAt] +lemma localFrameCoeff_eq_coeff (hxe : x ∈ e.baseSet) {i : ι} : + e.localFrameCoeff I b i x (s x) = b.repr (e ((T% s) x)).2 i := by + simp [e.localFrameCoeff_apply_of_mem_baseSet b hxe, basisAt] + +@[deprecated (since := "2026-07-26")] alias localFrame_coeff_eq_coeff := localFrameCoeff_eq_coeff end Bundle.Trivialization @@ -446,10 +461,10 @@ variable [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle k F V I] set_option backward.isDefEq.respectTransparency false in -/-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame +/-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrameCoeff e i` in the local frame near `x` induced by `e` and `b` -/ -lemma contMDiffAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% s) x) (i : ι) : - CMDiffAt k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x := by +lemma contMDiffAt_localFrameCoeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% s) x) (i : ι) : + CMDiffAt k ((LinearMap.piApply (e.localFrameCoeff I b i)) s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. -- step 1: on e.baseSet, we know compute the coefficient very well let aux := fun x ↦ b.repr (e ((T% s) x)).2 i @@ -458,7 +473,7 @@ lemma contMDiffAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% apply this.congr_of_eventuallyEq ?_ apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, e.localFrame_coeff_eq_coeff hy] + simp [aux, e.localFrameCoeff_eq_coeff hy] simp only [aux] -- step 2: `s` read in trivialization `e` is `C^k` have h₁ : CMDiffAt k (fun x ↦ (e ((T% s) x)).2) x := by @@ -472,52 +487,70 @@ lemma contMDiffAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% contMDiffAt_iff_contDiffAt.mpr <| by fun_prop exact this.comp x h₁ -/-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_coeff e i` +@[deprecated (since := "2026-07-26")] +alias contMDiffAt_localFrame_coeff := contMDiffAt_localFrameCoeff + +/-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrameCoeff e i` in the local frame induced by `e` -/ -lemma contMDiffOn_localFrame_coeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) +lemma contMDiffOn_localFrameCoeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : CMDiff[t] k (T% s)) (i : ι) : - CMDiff[t] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := - fun _ hx ↦ (contMDiffAt_localFrame_coeff b (ht' hx) + CMDiff[t] k ((LinearMap.piApply (e.localFrameCoeff I b i)) s) := + fun _ hx ↦ (contMDiffAt_localFrameCoeff b (ht' hx) (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -/-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_coeff e i` +@[deprecated (since := "2026-07-26")] +alias contMDiffOn_localFrame_coeff := contMDiffOn_localFrameCoeff + +/-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrameCoeff e i` in the local frame induced by `e` -/ -lemma contMDiffOn_baseSet_localFrame_coeff (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : - CMDiff[e.baseSet] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := - contMDiffOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ +lemma contMDiffOn_baseSet_localFrameCoeff (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : + CMDiff[e.baseSet] k ((LinearMap.piApply (e.localFrameCoeff I b i)) s) := + contMDiffOn_localFrameCoeff b e.open_baseSet (subset_refl _) hs _ + +@[deprecated (since := "2026-07-26")] +alias contMDiffOn_baseSet_localFrame_coeff := contMDiffOn_baseSet_localFrameCoeff /-- A section `s` of `V` is `C^k` at `x ∈ e.baseSet` iff each of its -coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ -lemma contMDiffAt_iff_localFrame_coeff (hx : x' ∈ e.baseSet) : - CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x' := - ⟨fun h i ↦ contMDiffAt_localFrame_coeff b hx h i, +coefficients `(LinearMap.piApply (b.localFrameCoeff e i) s)` in a local frame near `x` is -/ +lemma contMDiffAt_iff_localFrameCoeff (hx : x' ∈ e.baseSet) : + CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k ((LinearMap.piApply (e.localFrameCoeff I b i)) s) x' := + ⟨fun h i ↦ contMDiffAt_localFrameCoeff b hx h i, fun hi ↦ (e.isLocalFrameOn_localFrame_baseSet I k b).contMDiffAt_of_coeff hi (e.open_baseSet.mem_nhds hx)⟩ +@[deprecated (since := "2026-07-26")] +alias contMDiffAt_iff_localFrame_coeff := contMDiffAt_iff_localFrameCoeff + /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its -coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ -lemma contMDiffOn_iff_localFrame_coeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := by - refine ⟨fun h i ↦ contMDiffOn_localFrame_coeff b ht ht' h _, fun h x hx ↦ ?_⟩ - exact (contMDiffAt_iff_localFrame_coeff b (ht' hx)).mpr +coefficients `(LinearMap.piApply (b.localFrameCoeff e i) s)` in a local frame near `x` is -/ +lemma contMDiffOn_iff_localFrameCoeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : + CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k ((LinearMap.piApply (e.localFrameCoeff I b i)) s) := by + refine ⟨fun h i ↦ contMDiffOn_localFrameCoeff b ht ht' h _, fun h x hx ↦ ?_⟩ + exact (contMDiffAt_iff_localFrameCoeff b (ht' hx)).mpr (fun i ↦ (h i x hx).contMDiffAt (ht.mem_nhds hx)) |>.contMDiffWithinAt +@[deprecated (since := "2026-07-26")] +alias contMDiffOn_iff_localFrame_coeff := contMDiffOn_iff_localFrameCoeff + /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its -coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ -lemma contMDiffOn_baseSet_iff_localFrame_coeff : +coefficients `(LinearMap.piApply (b.localFrameCoeff e i) s)` in a local frame near `x` is -/ +lemma contMDiffOn_baseSet_iff_localFrameCoeff : CMDiff[e.baseSet] k (T% s) ↔ - ∀ i, CMDiff[e.baseSet] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := by - rw [contMDiffOn_iff_localFrame_coeff b e.open_baseSet (subset_refl _)] + ∀ i, CMDiff[e.baseSet] k ((LinearMap.piApply (e.localFrameCoeff I b i)) s) := by + rw [contMDiffOn_iff_localFrameCoeff b e.open_baseSet (subset_refl _)] + +@[deprecated (since := "2026-07-26")] +alias contMDiffOn_baseSet_iff_localFrame_coeff := contMDiffOn_baseSet_iff_localFrameCoeff -- Differentiability of a section can be checked in terms of its local frame coefficients section MDifferentiable set_option backward.isDefEq.respectTransparency false in -/-- If `s` is differentiable at `x`, so is its coefficient `b.localFrame_coeff e i` in the local +/-- If `s` is differentiable at `x`, so is its coefficient `b.localFrameCoeff e i` in the local frame near `x` induced by `e` and `b` -/ -lemma mdifferentiableAt_localFrame_coeff +lemma mdifferentiableAt_localFrameCoeff (hxe : x ∈ e.baseSet) (hs : MDiffAt (T% s) x) (i : ι) : - MDiffAt ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x := by + MDiffAt ((LinearMap.piApply (e.localFrameCoeff I b i)) s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. -- step 1: on `e.baseSet`, we know the coefficient very well let aux := fun x ↦ b.repr (e ((T% s) x)).2 i @@ -526,7 +559,7 @@ lemma mdifferentiableAt_localFrame_coeff apply this.congr_of_eventuallyEq apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, e.localFrame_coeff_eq_coeff hy] + simp [aux, e.localFrameCoeff_eq_coeff hy] simp only [aux] -- step 2: `s` read in trivialization `e` is differentiable have h₁ : MDiffAt (fun x ↦ (e ((T% s) x)).2) x := by @@ -540,26 +573,38 @@ lemma mdifferentiableAt_localFrame_coeff mdifferentiableAt_iff_differentiableAt.mpr <| by fun_prop exact this.comp x h₁ -/-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_coeff e i` +@[deprecated (since := "2026-07-26")] +alias mdifferentiableAt_localFrame_coeff := mdifferentiableAt_localFrameCoeff + +/-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrameCoeff e i` in the local frame induced by `e` -/ -lemma mdifferentiableOn_localFrame_coeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) - (hs : MDiff[t] (T% s)) (i : ι) : MDiff[t] ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := - fun _ hx ↦ (mdifferentiableAt_localFrame_coeff b (ht' hx) +lemma mdifferentiableOn_localFrameCoeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + (hs : MDiff[t] (T% s)) (i : ι) : MDiff[t] ((LinearMap.piApply (e.localFrameCoeff I b i)) s) := + fun _ hx ↦ (mdifferentiableAt_localFrameCoeff b (ht' hx) (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt -/-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the +@[deprecated (since := "2026-07-26")] +alias mdifferentiableOn_localFrame_coeff := mdifferentiableOn_localFrameCoeff + +/-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrameCoeff e i` in the local frame induced by `e` -/ -lemma mdifferentiableOn_baseSet_localFrame_coeff (hs : MDiff[e.baseSet] (T% s)) (i : ι) : - MDiff[e.baseSet] ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := - mdifferentiableOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ +lemma mdifferentiableOn_baseSet_localFrameCoeff (hs : MDiff[e.baseSet] (T% s)) (i : ι) : + MDiff[e.baseSet] ((LinearMap.piApply (e.localFrameCoeff I b i)) s) := + mdifferentiableOn_localFrameCoeff b e.open_baseSet (subset_refl _) hs _ + +@[deprecated (since := "2026-07-26")] +alias mdifferentiableOn_baseSet_localFrame_coeff := mdifferentiableOn_baseSet_localFrameCoeff /-- A section `s` of `V` is differentiable at `x ∈ e.baseSet` iff each of its -coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ -lemma mdifferentiableAt_iff_localFrame_coeff (hx : x' ∈ e.baseSet) : - MDiffAt (T% s) x' ↔ ∀ i, MDiffAt ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x' := - ⟨fun h i ↦ mdifferentiableAt_localFrame_coeff b hx h i, fun hi ↦ +coefficients `(LinearMap.piApply (b.localFrameCoeff e i) s)` in a local frame near `x` is -/ +lemma mdifferentiableAt_iff_localFrameCoeff (hx : x' ∈ e.baseSet) : + MDiffAt (T% s) x' ↔ ∀ i, MDiffAt ((LinearMap.piApply (e.localFrameCoeff I b i)) s) x' := + ⟨fun h i ↦ mdifferentiableAt_localFrameCoeff b hx h i, fun hi ↦ (e.isLocalFrameOn_localFrame_baseSet I 1 b).mdifferentiableAt_of_coeff_aux hi e.open_baseSet hx⟩ +@[deprecated (since := "2026-07-26")] +alias mdifferentiableAt_iff_localFrame_coeff := mdifferentiableAt_iff_localFrameCoeff + end MDifferentiable end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index a4b1e190339b7c..f9650307d16a14 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -137,12 +137,12 @@ lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} have x_mem : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt F V x let b := Basis.ofVectorSpace 𝕜 F let s := t.localFrame b - let c := t.localFrame_coeff I b + let c := t.localFrameCoeff I b have hs (i) : MDiffAt (T% (s i)) x := (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt (by simp) have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : MDiffAt (LinearMap.piApply (c i) σ) x := - mdifferentiableAt_localFrame_coeff b x_mem hσ i + mdifferentiableAt_localFrameCoeff b x_mem hσ i -- By the locality of the operation `(Φ · x)`, its value on `σ` agrees with the value of `Φ` on -- the expansion of `σ` into coefficients relative to the frame. have hΦ_eq {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) : From 9eb53bdd74ebf424cf06479f11e55b695c7ed9d0 Mon Sep 17 00:00:00 2001 From: Chris Henson <46805207+chenson2018@users.noreply.github.com> Date: Mon, 27 Jul 2026 19:23:05 +0000 Subject: [PATCH 1035/1300] chore: remove uses of `Subrelation` (#41450) Following up on the description of #40792, this removes additional uses of `Subrelation` now that #30526 has been merged. --- Mathlib/Logic/Relation.lean | 39 ++++++++++++++++----------------- Mathlib/Order/JordanHolder.lean | 2 +- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 7e91e553f4e893..4b990aaa2e420f 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -56,9 +56,9 @@ open Function variable {α β γ δ ε ζ : Type*} -theorem Subrelation.antisymm {r r' : α → α → Prop} (h1 : Subrelation r r') (h2 : Subrelation r' r) : +theorem Subrelation.antisymm {r r' : α → α → Prop} (h1 : r ≤ r') (h2 : r' ≤ r) : r = r' := - funext₂ fun _ _ => propext ⟨h1, h2⟩ + funext₂ fun a b => propext ⟨h1 a b, h2 a b⟩ section NeImp @@ -816,34 +816,33 @@ theorem mono {r p : α → α → Prop} (hrp : r ≤ p) : EqvGen r ≤ EqvGen p | symm a b _ ih => exact EqvGen.symm _ _ ih | trans a b c _ _ hab hbc => exact EqvGen.trans _ _ _ hab hbc -lemma eqvGen_le {r r' : α → α → Prop} [IsEquiv α r'] (h : Subrelation r r') : - Subrelation (EqvGen r) r' +lemma eqvGen_le {r r' : α → α → Prop} [IsEquiv α r'] (h : r ≤ r') : EqvGen r ≤ r' | _, _, .refl _ => _root_.refl _ - | _, _, .symm _ _ hxy => _root_.symm (eqvGen_le h hxy :) - | _, _, .trans _ _ _ hxy hyz => _root_.trans (eqvGen_le h hxy :) (eqvGen_le h hyz :) - | _, _, .rel _ _ hab => h hab + | _, _, .symm _ _ hxy => _root_.symm (eqvGen_le h _ _ hxy) + | _, _, .trans _ _ _ hxy hyz => _root_.trans (eqvGen_le h _ _ hxy) (eqvGen_le h _ _ hyz) + | _, _, .rel _ _ hab => h _ _ hab -lemma eqvGen_mono {r r' : α → α → Prop} (h : Subrelation r r') : Subrelation (EqvGen r) (EqvGen r') +lemma eqvGen_mono {r r' : α → α → Prop} (h : r ≤ r') : EqvGen r ≤ EqvGen r' | _, _, .refl _ => .refl _ - | _, _, .symm _ _ hxy => .symm _ _ (eqvGen_mono h hxy) - | _, _, .trans _ _ _ hxy hyz => .trans _ _ _ (eqvGen_mono h hxy) (eqvGen_mono h hyz) - | _, _, .rel _ _ hab => .rel _ _ (h hab) + | _, _, .symm _ _ hxy => .symm _ _ (eqvGen_mono h _ _ hxy) + | _, _, .trans _ _ _ hxy hyz => .trans _ _ _ (eqvGen_mono h _ _ hxy) (eqvGen_mono h _ _ hyz) + | _, _, .rel _ _ hab => .rel _ _ (h _ _ hab) -lemma reflGen_le_eqvGen : Subrelation (ReflGen r) (EqvGen r) +lemma reflGen_le_eqvGen : ReflGen r ≤ EqvGen r | _, _, .refl => .refl _ | _, _, .single h => .rel _ _ h -lemma symmGen_le_eqvGen : Subrelation (SymmGen r) (EqvGen r) +lemma symmGen_le_eqvGen : SymmGen r ≤ EqvGen r | _, _, .inl h => .rel _ _ h | _, _, .inr h => _root_.symm <| .rel _ _ h -lemma transGen_le_eqvGen : Subrelation (TransGen r) (EqvGen r) := by +lemma transGen_le_eqvGen : TransGen r ≤ EqvGen r := by intro _ _ h induction h using TransGen.trans_induction_on with | trans _ _ h1 h2 => exact _root_.trans h1 h2 | single h => exact .rel _ _ h -lemma reflTransGen_le_eqvGen : Subrelation (ReflTransGen r) (EqvGen r) := by +lemma reflTransGen_le_eqvGen : ReflTransGen r ≤ EqvGen r := by intro _ _ h induction h using ReflTransGen.trans_induction_on with | refl => exact .refl _ @@ -853,27 +852,27 @@ lemma reflTransGen_le_eqvGen : Subrelation (ReflTransGen r) (EqvGen r) := by @[simp, grind =] lemma eqvGen_reflGen : EqvGen (ReflGen r) = EqvGen r := Subrelation.antisymm - (eqvGen_le (reflGen_le_eqvGen _)) (eqvGen_mono (.single)) + (eqvGen_le (reflGen_le_eqvGen _)) (eqvGen_mono fun _ _ => .single) @[simp, grind =] lemma eqvGen_transGen : EqvGen (TransGen r) = EqvGen r := Subrelation.antisymm - (eqvGen_le (transGen_le_eqvGen _)) (eqvGen_mono .single) + (eqvGen_le (transGen_le_eqvGen _)) (eqvGen_mono fun _ _ => .single) @[simp, grind =] lemma eqvGen_symmGen : EqvGen (SymmGen r) = EqvGen r := Subrelation.antisymm - (eqvGen_le (symmGen_le_eqvGen _)) (eqvGen_mono .inl) + (eqvGen_le (symmGen_le_eqvGen _)) (eqvGen_mono fun _ _ => .inl) @[simp, grind =] lemma eqvGen_reflTransGen : EqvGen (ReflTransGen r) = EqvGen r := Subrelation.antisymm - (eqvGen_le (reflTransGen_le_eqvGen _)) (eqvGen_mono .single) + (eqvGen_le (reflTransGen_le_eqvGen _)) (eqvGen_mono fun _ _ => .single) @[grind =] lemma eqvGen_eq_reflTransGen [Std.Symm r] : EqvGen r = ReflTransGen r := have : IsEquiv α (ReflTransGen r) := ⟨⟩ - Subrelation.antisymm (eqvGen_le .single) (reflTransGen_le_eqvGen _) + Subrelation.antisymm (eqvGen_le fun _ _ => .single) (reflTransGen_le_eqvGen _) lemma reflTransGen_symmGen : ReflTransGen (SymmGen r) = EqvGen r := by rw [← eqvGen_eq_reflTransGen, eqvGen_symmGen] diff --git a/Mathlib/Order/JordanHolder.lean b/Mathlib/Order/JordanHolder.lean index 7495b6259ca627..7b7671e89efcf2 100644 --- a/Mathlib/Order/JordanHolder.lean +++ b/Mathlib/Order/JordanHolder.lean @@ -116,7 +116,7 @@ theorem Iso.rel (h_rel : ∀ {x y}, IsMaximal x (x ⊔ y) → e (x, x ⊔ y) (x ⊓ y, y)) {x y : X × X} (h_iso : Iso x y) : e x y := by have : IsEquiv (X × X) e := { refl _ := h_refl, symm _ _ := h_symm, trans _ _ _ := h_trans } - refine Relation.EqvGen.eqvGen_le ?_ h_iso + refine Relation.EqvGen.eqvGen_le ?_ _ _ h_iso rintro ⟨a, b⟩ ⟨c, d⟩ ⟨h, rfl : b = a ⊔ d, rfl : c = a ⊓ d⟩ exact h_rel h From c997a2348009a318361f9be65dada8153f06f504 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Mon, 27 Jul 2026 20:26:54 +0000 Subject: [PATCH 1036/1300] feat: finrank is preserved by `IsFractionRing` (#41694) This PR gives a direct proof of `Algebra.IsAlgebraic.finrank_of_isFractionRing` which avoids any additional assumptions beyond those required for the statement (including `Algebra.IsAlgebraic`). Co-authored-by: tb65536 --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 3 +- .../LinearAlgebra/Dimension/Localization.lean | 58 ++++++++++++++++++- Mathlib/RingTheory/Algebraic/Integral.lean | 3 +- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index e02c00401d25c4..84ddfd8cf84d3c 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -122,9 +122,8 @@ theorem card_eq_finrank' : Nat.card G = Module.finrank A B := by have := IsDomain.of_faithfulSMul A B let := FractionRing.liftAlgebra A (FractionRing B) let := IsFractionRing.mulSemiringAction G B (FractionRing B) - have : Algebra.IsIntegral A B := IsGaloisGroup.isInvariant.isIntegral A B G rw [IsGaloisGroup.card_eq_finrank G (FractionRing A) (FractionRing B), - Algebra.IsAlgebraic.finrank_of_isFractionRing A (FractionRing A) B (FractionRing B)] + IsFractionRing.finrank_eq A (FractionRing A) B (FractionRing B)] @[simp] theorem map_mulEquivAlgEquiv_fixingSubgroup [IsGaloisGroup G K L] (F : IntermediateField K L) : diff --git a/Mathlib/LinearAlgebra/Dimension/Localization.lean b/Mathlib/LinearAlgebra/Dimension/Localization.lean index d1034e24765706..fb6dfbb307fc9a 100644 --- a/Mathlib/LinearAlgebra/Dimension/Localization.lean +++ b/Mathlib/LinearAlgebra/Dimension/Localization.lean @@ -5,11 +5,11 @@ Authors: Andrew Yang -/ module +public import Mathlib.Algebra.Group.Pointwise.Finset.Scalar public import Mathlib.Algebra.Module.LocalizedModule.Submodule public import Mathlib.LinearAlgebra.Dimension.DivisionRing -public import Mathlib.RingTheory.IsTensorProduct +public import Mathlib.LinearAlgebra.LinearIndependent.Algebra public import Mathlib.RingTheory.Localization.BaseChange -public import Mathlib.RingTheory.Localization.FractionRing public import Mathlib.RingTheory.OreLocalization.OreSet /-! @@ -77,6 +77,22 @@ theorem IsLocalization.finrank_eq : finrank S N = finrank R N := by end +variable {S} in +theorem IsLocalization.linearIndepOn_finsetIntegerMultiple {A : Type*} [CommRing A] [Algebra S A] + [Algebra R A] [IsScalarTower R S A] (M : Submonoid S) [IsLocalization M A] [FaithfulSMul S A] + {s : Finset A} (hs : LinearIndepOn R id (s : Set A)) [DecidableEq S] : + LinearIndepOn R id (finsetIntegerMultiple M s : Set S) := by + classical + rw [← LinearIndepOn.id_image_algebraMap_iff (A := A), + finsetIntegerMultiple_image, ← s.coe_smul_finset] + rw [linearIndepOn_finset_iff] at hs ⊢ + intro f h + rw [s.smul_finset_def, s.forall_mem_image] + apply hs + have inj := (IsLocalization.smul_bijective A (commonDenomOfFinset M s)).injective + rw [← inj.eq_iff, smul_zero, s.smul_sum, ← h, s.smul_finset_def, s.sum_image inj.injOn] + exact s.sum_congr rfl fun x hx ↦ smul_comm .. + section variable (R N) [IsFractionRing R S] @@ -91,12 +107,48 @@ theorem IsFractionRing.rank_right_eq : Module.rank S N = Module.rank R N := /-- Given `IsScalarTower R S N`, if `S` is the fraction ring of `R`, then the finrank `finrank S N` of the right part of the tower equals the finrank `finrank R N` of the whole tower. -See `IsFractionRing.rank_right_eq` for the rank version. -/ +See `IsFractionRing.rank_right_eq` for the rank version. +See `IsFractionRing.finrank_left_eq` for the left version. +See `IsFractionRing.finrank_eq` for the simultaneous version. -/ theorem IsFractionRing.finrank_right_eq : finrank S N = finrank R N := IsLocalization.finrank_eq S R⁰ le_rfl end +variable (R) in +open IsLocalization in +/-- Given `IsScalarTower R S A`, if `A` is the fraction ring of `S`, then the finrank `finrank R S` +of the left part of the tower equals the finrank `finrank R A` of the whole tower. + +See `IsFractionRing.finrank_right_eq` for the right version. +See `IsFractionRing.finrank_eq` for the simultaneous version. -/ +theorem IsFractionRing.finrank_left_eq (A : Type*) [CommRing A] [Algebra S A] [Algebra R A] + [IsScalarTower R S A] [IsFractionRing S A] : Module.finrank R S = Module.finrank R A := by + nontriviality R + classical + apply Cardinal.toNat_eq_of_forall_le_iff + intro n + simp_rw [Module.le_rank_iff_exists_finset, LinearIndepOn] + constructor + · rintro ⟨s, rfl, hs⟩ + let f : S ↪ A := ⟨algebraMap S A, FaithfulSMul.algebraMap_injective S A⟩ + exact ⟨s.map f, s.card_map f, + (linearIndependent_equiv (s.equivMap f)).mp (LinearIndependent.algebraMap_comp_iff.mpr hs)⟩ + · rintro ⟨s, rfl, hs⟩ + exact ⟨finsetIntegerMultiple S⁰ s, card_finsetIntegerMultiple S⁰ s, + linearIndepOn_finsetIntegerMultiple S⁰ hs⟩ + +/-- If `K` is the fraction ring of `A` and `L` is the fraction ring of `B`, then the finrank +`finrank K L` of the fraction rings equals the finrank `finrank A B` of the base rings. + +See `IsFractionRing.finrank_left_eq` and `IsFractionRing.finrank_right_eq` for one-sided versions. +See `Algebra.IsAlgebraic.rank_of_isFractionRing` for a rank version with additional assumptions. -/ +protected theorem IsFractionRing.finrank_eq (A K B L : Type*) + [CommRing A] [CommRing K] [CommRing B] [CommRing L] [Algebra A B] [Module K L] + [Algebra A K] [Algebra B L] [Algebra A L] [IsScalarTower A K L] [IsScalarTower A B L] + [IsFractionRing A K] [IsFractionRing B L] : Module.finrank K L = Module.finrank A B := + (finrank_right_eq A K L).trans (finrank_left_eq A B L).symm + variable (R M) in theorem exists_set_linearIndependent_of_isDomain [IsDomain R] : ∃ s : Set M, #s = Module.rank R M ∧ LinearIndepOn R id s := by diff --git a/Mathlib/RingTheory/Algebraic/Integral.lean b/Mathlib/RingTheory/Algebraic/Integral.lean index c62601e3593cc1..1dd7574f73f86e 100644 --- a/Mathlib/RingTheory/Algebraic/Integral.lean +++ b/Mathlib/RingTheory/Algebraic/Integral.lean @@ -547,8 +547,7 @@ theorem lift_rank_of_isFractionRing : rw [IsLocalization.rank_eq R' R⁰ le_rfl, IsLocalizedModule.lift_rank_eq R⁰ (IsScalarTower.toAlgHom R S S').toLinearMap le_rfl] -theorem finrank_of_isFractionRing : Module.finrank R' S' = Module.finrank R S := by - simpa using! congr_arg Cardinal.toNat (lift_rank_of_isFractionRing ..) +@[deprecated (since := "2026-07-13")] alias finrank_of_isFractionRing := IsFractionRing.finrank_eq theorem rank_of_isFractionRing (S' : Type u) [CommRing S'] [Algebra R S'] [Algebra S S'] [Module R' S'] [IsScalarTower R R' S'] [IsScalarTower R S S'] [IsFractionRing S S'] : From c0f1540fb3d67ea8e63bbd8e86501de46f212c59 Mon Sep 17 00:00:00 2001 From: mitchell-horner <29882987+mitchell-horner@users.noreply.github.com> Date: Mon, 27 Jul 2026 23:15:30 +0000 Subject: [PATCH 1037/1300] feat(Combinatorics/SimpleGraph): edges of an induced subgraph as a filter (#42135) Add two lemmas describing the edges of a finite simple graph `G` whose vertices all lie in a finset `s`. --- Mathlib/Combinatorics/SimpleGraph/Finite.lean | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index 395f6c67069a0f..3c7e0f856430c9 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -715,6 +715,20 @@ theorem le_minDegree_induce_of_support_subset (h : G.support ⊆ s) : grw [G.minDegree_le_degree v, degree_induce_of_neighborSet_subset] grw [neighborSet_subset_support, h] +theorem filter_edgeFinset_toFinset_subset [DecidableEq V] (s : Finset V) : + {e ∈ G.edgeFinset | e.toFinset ⊆ s} = G.edgeFinset ∩ s.sym2 := by + simp [subset_iff, ← mem_sym2_iff, filter_mem_eq_inter] + +/-- The edges whose vertices lie in `s` are in bijection with the edges of the induced +subgraph `G.induce s`. -/ +theorem card_filter_edgeFinset_toFinset_subset [DecidableEq V] (s : Finset V) : + #{e ∈ G.edgeFinset | e.toFinset ⊆ s} = #(G.induce ↑s).edgeFinset := by + have h := congrArg Finset.card (map_edgeFinset_induce (s := (↑s : Set V)) (G := G)) + rw [card_map, toFinset_coe] at h + rw [filter_edgeFinset_toFinset_subset] + convert h.symm using 1 + congr! + end Support section Map From 671e5520a2f31a6e2a7278f44fd51e07d922d523 Mon Sep 17 00:00:00 2001 From: Seewoo Lee <49933279+seewoo5@users.noreply.github.com> Date: Mon, 27 Jul 2026 23:30:55 +0000 Subject: [PATCH 1038/1300] feat(RingTheory/RootsOfUnity/Complex): `I` is a primitive root (#42124) $\pm I$ are primitive 4-th roots of unity. Arise from a personal project, and written with Claude Opus 5 + Fable 5. It is not clear for me if this is the best place to put this theorem (since the file is mostly about $\exp(2\pi I/n)$), but looks the closest choice. Co-Authored-By: Claude Opus 5 [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) Co-authored-by: Author Name --- Mathlib/RingTheory/RootsOfUnity/Complex.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/RingTheory/RootsOfUnity/Complex.lean b/Mathlib/RingTheory/RootsOfUnity/Complex.lean index 733daaab5a1e2a..2eeb4925fb841e 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Complex.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Complex.lean @@ -35,6 +35,13 @@ open Polynomial Real open scoped Nat Real +theorem isPrimitiveRoot_I : IsPrimitiveRoot I 4 := + .mk_of_lt I zero_lt_four I_pow_four fun l hl0 hl4 ↦ by + interval_cases l <;> norm_num [Complex.ext_iff] + +theorem isPrimitiveRoot_neg_I : IsPrimitiveRoot (-I) 4 := by + simpa only [inv_I] using isPrimitiveRoot_I.inv + theorem isPrimitiveRoot_exp_of_isCoprime (i : ℤ) (n : ℕ) (h0 : n ≠ 0) (hi : IsCoprime i n) : IsPrimitiveRoot (exp (2 * π * I * (i / n))) n := by rw [IsPrimitiveRoot.iff_def] From 5b3f719bf129e3cf48daf6ff76a2ec5cb6e9b1e3 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Mon, 27 Jul 2026 23:44:07 +0000 Subject: [PATCH 1039/1300] fix(LinearAlgebra/Matrix/Notation): fix defeq abuse in lemmas (#42090) --- Mathlib/LinearAlgebra/Matrix/Notation.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Notation.lean b/Mathlib/LinearAlgebra/Matrix/Notation.lean index 6a2999b09b0318..0508d8071067df 100644 --- a/Mathlib/LinearAlgebra/Matrix/Notation.lean +++ b/Mathlib/LinearAlgebra/Matrix/Notation.lean @@ -228,7 +228,7 @@ section ColRow variable {ι : Type*} @[simp] -theorem replicateCol_empty (v : Fin 0 → α) : replicateCol ι v = vecEmpty := +theorem replicateCol_empty (v : Fin 0 → α) : replicateCol ι v = of vecEmpty := empty_eq _ set_option backward.isDefEq.respectTransparency false in @@ -368,7 +368,7 @@ section VecMulVec variable [NonUnitalNonAssocSemiring α] @[simp] -theorem empty_vecMulVec (v : Fin 0 → α) (w : n' → α) : vecMulVec v w = ![] := +theorem empty_vecMulVec (v : Fin 0 → α) (w : n' → α) : vecMulVec v w = of ![] := empty_eq _ @[simp] From 996c094298abe6682d90e374ffc84b6419b6d2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 28 Jul 2026 04:48:45 +0000 Subject: [PATCH 1040/1300] feat(Geometry/Convex): bundled type of affine maps between convex spaces (#42126) --- Mathlib.lean | 1 + .../Convex/ConvexSpace/AffineMap.lean | 100 ++++++++++++++++++ Mathlib/Geometry/Convex/ConvexSpace/Defs.lean | 5 + 3 files changed, 106 insertions(+) create mode 100644 Mathlib/Geometry/Convex/ConvexSpace/AffineMap.lean diff --git a/Mathlib.lean b/Mathlib.lean index 952307f7e36481..9d183644120d06 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4598,6 +4598,7 @@ public import Mathlib.Geometry.Convex.Cone.Face.Basic public import Mathlib.Geometry.Convex.Cone.Pointed public import Mathlib.Geometry.Convex.Cone.Simplicial public import Mathlib.Geometry.Convex.Cone.TensorProduct +public import Mathlib.Geometry.Convex.ConvexSpace.AffineMap public import Mathlib.Geometry.Convex.ConvexSpace.AffineSpace public import Mathlib.Geometry.Convex.ConvexSpace.Defs public import Mathlib.Geometry.Convex.ConvexSpace.Module diff --git a/Mathlib/Geometry/Convex/ConvexSpace/AffineMap.lean b/Mathlib/Geometry/Convex/ConvexSpace/AffineMap.lean new file mode 100644 index 00000000000000..af917b6b5bdd9a --- /dev/null +++ b/Mathlib/Geometry/Convex/ConvexSpace/AffineMap.lean @@ -0,0 +1,100 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Geometry.Convex.ConvexSpace.Defs + +/-! +# Bundled affine maps between convex spaces + +If `X` and `Y` are convex spaces (over `R`), we introduce the type +`ConvexSpace.AffineMap R X Y` of bundled affine maps from `X` to `Y`. + +-/ + +@[expose] public section + +variable {R : Type*} [PartialOrder R] [Semiring R] [IsStrictOrderedRing R] + +namespace Convexity.ConvexSpace + +variable (R) in +/-- The type of (bundled) affine maps between two convex spaces. -/ +protected structure AffineMap + (X Y : Type*) [ConvexSpace R X] [ConvexSpace R Y] where + /-- The underlying map of an affine map between convex spaces. -/ + toFun : X → Y + isAffineMap_toFun : IsAffineMap R toFun := by fun_prop + +namespace AffineMap + +instance {X Y : Type*} [ConvexSpace R X] [ConvexSpace R Y] : + FunLike (ConvexSpace.AffineMap R X Y) X Y where + coe := ConvexSpace.AffineMap.toFun + coe_injective := fun ⟨f, _⟩ ⟨g, _⟩ h ↦ by simpa + +initialize_simps_projections ConvexSpace.AffineMap (toFun → apply) + +@[ext] +lemma ext {X Y : Type*} [ConvexSpace R X] [ConvexSpace R Y] + {f g : ConvexSpace.AffineMap R X Y} (h : (f : X → Y) = g) : f = g := + DFunLike.coe_injective h + +@[fun_prop] +lemma isAffineMap + {X Y : Type*} [ConvexSpace R X] [ConvexSpace R Y] + (f : ConvexSpace.AffineMap R X Y) : + IsAffineMap R f := + f.isAffineMap_toFun + +/-- The identity map, as a bundled affine map of convex spaces. -/ +@[simps, implicit_reducible] +def id (X : Type*) [ConvexSpace R X] : + ConvexSpace.AffineMap R X X where + toFun := _root_.id + +/-- The composition of bundled affine maps between convex spaces. -/ +@[simps, implicit_reducible] +def comp + {X Y Z : Type*} [ConvexSpace R X] [ConvexSpace R Y] [ConvexSpace R Z] + (g : ConvexSpace.AffineMap R Y Z) (f : ConvexSpace.AffineMap R X Y) : + ConvexSpace.AffineMap R X Z where + toFun := g ∘ f + +@[simp] +lemma coe_comp + {X Y Z : Type*} [ConvexSpace R X] [ConvexSpace R Y] [ConvexSpace R Z] + (g : ConvexSpace.AffineMap R Y Z) (f : ConvexSpace.AffineMap R X Y) : + ⇑(g.comp f) = g ∘ f := rfl + +@[simp] +lemma id_comp + {X Y : Type*} [ConvexSpace R X] [ConvexSpace R Y] + (f : ConvexSpace.AffineMap R X Y) : + (AffineMap.id _).comp f = f := rfl + +@[simp] +lemma comp_id + {X Y : Type*} [ConvexSpace R X] [ConvexSpace R Y] + (f : ConvexSpace.AffineMap R X Y) : + f.comp (.id _) = f := rfl + +lemma assoc {X Y Z T : Type*} + [ConvexSpace R X] [ConvexSpace R Y] [ConvexSpace R Z] [ConvexSpace R T] + (f₁ : ConvexSpace.AffineMap R Z T) (f₂ : ConvexSpace.AffineMap R Y Z) + (f₃ : ConvexSpace.AffineMap R X Y) : + (f₁.comp f₂).comp f₃ = f₁.comp (f₂.comp f₃) := + rfl + +/-- A constant map between convex spaces, as a bundled affine map. -/ +@[simps, implicit_reducible] +def const {X Y : Type*} [ConvexSpace R X] [ConvexSpace R Y] (y : Y) : + ConvexSpace.AffineMap R X Y where + toFun _ := y + +end AffineMap + +end Convexity.ConvexSpace diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean index 80016c836aa999..49aa134dd90065 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean @@ -339,6 +339,11 @@ lemma IsAffineMap.comp {g : N → P} (hg : IsAffineMap R g) {f : M → N} (hf : map_sConvexComb s := by simp [StdSimplex.map_comp, hf.map_sConvexComb, hg.map_sConvexComb] +@[fun_prop] +lemma IsAffineMap.const (x : N) : + IsAffineMap R (fun (_ : M) ↦ x) where + map_sConvexComb _ := by simp + variable (R) in @[fun_prop] lemma StdSimplex.isAffineMap_map (f : I → J) : IsAffineMap R (StdSimplex.map (R := R) f) := From bfc0bff5a036ddf63093b58716f09b074e9e360d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 28 Jul 2026 08:12:09 +0000 Subject: [PATCH 1041/1300] chore: finish renaming `setOf` to `Set.ofPred` (#42172) Follow-up to #41507 Generated by Claude Opus, then reviewed and cherry-picked line-by-line by myself. Assisted-by: Claude Opus 4.8 --- .../MeasurableSpace/Constructions.lean | 2 +- Mathlib/Order/Minimal.lean | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index 70a5380e22d166..858930635eb2b2 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -870,7 +870,7 @@ variable [MeasurableSpace α] {p q : α → Prop} @[simp] theorem measurable_mem : Measurable (· ∈ s) ↔ MeasurableSet s := measurableSet_setOfPred.symm -alias ⟨_, Measurable.setOf⟩ := measurableSet_setOf +alias ⟨_, Measurable.setOf⟩ := measurableSet_setOfPred @[fun_prop] alias ⟨_, MeasurableSet.mem⟩ := measurable_mem diff --git a/Mathlib/Order/Minimal.lean b/Mathlib/Order/Minimal.lean index acbd00836172ff..20dda2f2bd9cda 100644 --- a/Mathlib/Order/Minimal.lean +++ b/Mathlib/Order/Minimal.lean @@ -578,30 +578,34 @@ theorem map_minimal_mem (f : s ≃o t) (hx : Minimal (· ∈ s) x) : (f.toOrderEmbedding.trans (OrderEmbedding.subtype (· ∈ t))) (s := univ) (x := ⟨x, hx.prop⟩) /-- If two sets are order isomorphic, their minimals are also order isomorphic. -/ -def mapSetOfMinimal (f : s ≃o t) : {x | Minimal (· ∈ s) x} ≃o {x | Minimal (· ∈ t) x} where +def mapSetOfPredMinimal (f : s ≃o t) : {x | Minimal (· ∈ s) x} ≃o {x | Minimal (· ∈ t) x} where toFun x := ⟨f ⟨x, x.2.1⟩, f.map_minimal_mem x.2⟩ invFun x := ⟨f.symm ⟨x, x.2.1⟩, f.symm.map_minimal_mem x.2⟩ left_inv x := Subtype.ext (congr_arg Subtype.val <| f.left_inv ⟨x, x.2.1⟩ :) right_inv x := Subtype.ext (congr_arg Subtype.val <| f.right_inv ⟨x, x.2.1⟩ :) map_rel_iff' := f.map_rel_iff +@[deprecated (since := "2026-07-28")] alias mapSetOfMinimal := mapSetOfPredMinimal + /-- If two sets are order isomorphic, their maximals are also order isomorphic. -/ @[to_dual existing] -def mapSetOfMaximal (f : s ≃o t) : {x | Maximal (· ∈ s) x} ≃o {x | Maximal (· ∈ t) x} where +def mapSetOfPredMaximal (f : s ≃o t) : {x | Maximal (· ∈ s) x} ≃o {x | Maximal (· ∈ t) x} where toFun x := ⟨f ⟨x, x.2.1⟩, f.map_maximal_mem x.2⟩ invFun x := ⟨f.symm ⟨x, x.2.1⟩, f.symm.map_maximal_mem x.2⟩ left_inv x := Subtype.ext (congr_arg Subtype.val <| f.left_inv ⟨x, x.2.1⟩ :) right_inv x := Subtype.ext (congr_arg Subtype.val <| f.right_inv ⟨x, x.2.1⟩ :) map_rel_iff' := f.map_rel_iff +@[deprecated (since := "2026-07-28")] alias mapSetOfMaximal := mapSetOfPredMaximal + /-- If two sets are antitonically order isomorphic, their minimals/maximals are too. -/ @[to_dual /-- If two sets are antitonically order isomorphic, their maximals/minimals are too. -/] def setOfPredMinimalIsoSetOfPredMaximal (f : s ≃o tᵒᵈ) : {x | Minimal (· ∈ s) x} ≃o {x | Maximal (· ∈ t) (ofDual x)} where - toFun x := ⟨(f ⟨x.1, x.2.1⟩).1, ((show s ≃o ofDual ⁻¹' t from f).mapSetOfMinimal x).2⟩ + toFun x := ⟨(f ⟨x.1, x.2.1⟩).1, ((show s ≃o ofDual ⁻¹' t from f).mapSetOfPredMinimal x).2⟩ invFun x := ⟨(f.symm ⟨x.1, x.2.1⟩).1, - ((show ofDual ⁻¹' t ≃o s from f.symm).mapSetOfMinimal x).2⟩ - __ := (show s ≃o ofDual ⁻¹' t from f).mapSetOfMinimal + ((show ofDual ⁻¹' t ≃o s from f.symm).mapSetOfPredMinimal x).2⟩ + __ := (show s ≃o ofDual ⁻¹' t from f).mapSetOfPredMinimal @[deprecated (since := "2026-07-09")] alias setOfMinimalIsoSetOfMaximal := setOfPredMinimalIsoSetOfPredMaximal From cc3705d1b0e64a31eaceb8bf9fb22ef792db8dbf Mon Sep 17 00:00:00 2001 From: Jz Pan <3397779+acmepjz@users.noreply.github.com> Date: Tue, 28 Jul 2026 08:55:53 +0000 Subject: [PATCH 1042/1300] fix(RingTheory/Ideal/Height): mem_minimalPrimes_of_height_eq should be mem_minimalPrimes_of_height_le (#42088) According to the theorem statement and docstring, `Ideal.mem_minimalPrimes_of_height_eq` introduced in #21041 should be named `Ideal.mem_minimalPrimes_of_height_le`. This PR renames it accordingly. Co-authored-by: acmepjz Co-authored-by: Michael Rothgang --- Mathlib/RingTheory/Ideal/Height.lean | 11 +++++++---- Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/Ideal/Height.lean b/Mathlib/RingTheory/Ideal/Height.lean index 55b2fb28a0fea1..3835527e0f3295 100644 --- a/Mathlib/RingTheory/Ideal/Height.lean +++ b/Mathlib/RingTheory/Ideal/Height.lean @@ -210,7 +210,7 @@ lemma Ideal.finiteHeight_of_le {I J : Ideal R} (e : I ≤ J) (hJ : J ≠ ⊤) [F /-- If J is a prime ideal containing I, and its height is less than or equal to the height of I, then J is a minimal prime over I -/ -lemma Ideal.mem_minimalPrimes_of_height_eq {I J : Ideal R} (e : I ≤ J) [J.IsPrime] +lemma Ideal.mem_minimalPrimes_of_height_le {I J : Ideal R} (e : I ≤ J) [J.IsPrime] [FiniteHeight J] (e' : J.height ≤ I.height) : J ∈ I.minimalPrimes := by obtain ⟨p, h₁, h₂⟩ := Ideal.exists_minimalPrimes_le e convert! h₁ @@ -220,6 +220,9 @@ lemma Ideal.mem_minimalPrimes_of_height_eq {I J : Ideal R} (e : I ≤ J) [J.IsPr exact lt_irrefl _ ((height_strict_mono_of_isPrime h₃).trans_le (e'.trans <| height_mono h₁.le)) +@[deprecated (since := "2026-07-28")] +alias Ideal.mem_minimalPrimes_of_height_eq := Ideal.mem_minimalPrimes_of_height_le + /-- A prime ideal has height zero if and only if it is minimal -/ lemma Ideal.height_eq_zero_iff {I : Ideal R} [I.IsPrime] : height I = 0 ↔ I ∈ minimalPrimes R := by rw [Ideal.height_eq_primeHeight, Ideal.primeHeight, Order.height_eq_zero, @@ -432,11 +435,11 @@ lemma IsLocalization.height_map_of_disjoint {S : Type*} [CommRing S] [Algebra R rw [AtPrime.ringKrullDim_eq_height P, AtPrime.ringKrullDim_eq_height p] at this exact WithBot.coe_eq_coe.mp this -@[deprecated "Use `mem_minimalPrimes_of_height_eq` instead." (since := "2026-04-02")] +@[deprecated "Use `mem_minimalPrimes_of_height_le` instead." (since := "2026-04-02")] private lemma mem_minimalPrimes_of_primeHeight_eq_height {I J : Ideal R} [J.IsPrime] (e : I ≤ J) (e' : J.primeHeight = I.height) [J.FiniteHeight] : J ∈ I.minimalPrimes := by rw [← J.height_eq_primeHeight] at e' - exact mem_minimalPrimes_of_height_eq e (e' ▸ le_refl _) + exact mem_minimalPrimes_of_height_le e (e' ▸ le_refl _) lemma exists_spanRank_le_and_le_height_of_le_height [IsNoetherianRing R] (I : Ideal R) (r : ℕ) (hr : r ≤ I.height) : ∃ J ≤ I, J.spanRank ≤ r ∧ r ≤ J.height := by @@ -477,7 +480,7 @@ lemma exists_spanRank_le_and_le_height_of_le_height [IsNoetherianRing R] (I : Id exact Order.add_one_le_of_lt (lt_of_le_of_ne (h₃.trans this) h) intro e apply hx₂ p - · refine ⟨mem_minimalPrimes_of_height_eq (le_sup_left.trans hp.le) (e.symm.trans_le h₃), + · refine ⟨mem_minimalPrimes_of_height_le (le_sup_left.trans hp.le) (e.symm.trans_le h₃), e.symm⟩ · apply hp.le <| Ideal.mem_sup_right <| mem_span_singleton_self x diff --git a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean index 40ad2a3e8f8c53..21e9d6d1b81922 100644 --- a/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean +++ b/Mathlib/RingTheory/Ideal/KrullsHeightTheorem.lean @@ -303,7 +303,7 @@ lemma Ideal.height_le_iff_exists_minimalPrimes (p : Ideal R) [p.IsPrime] constructor · intro h obtain ⟨I, hI, e₁, e₂⟩ := exists_spanRank_eq_and_height_eq p (IsPrime.ne_top ‹_›) - refine ⟨I, Ideal.mem_minimalPrimes_of_height_eq hI e₂.ge, e₁.symm ▸ ?_⟩ + refine ⟨I, Ideal.mem_minimalPrimes_of_height_le hI e₂.ge, e₁.symm ▸ ?_⟩ norm_cast · rintro ⟨I, hp, hI⟩ exact le_trans From c7e4bc625eceee28a62a2c852148eb4c14cef1d8 Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Tue, 28 Jul 2026 09:13:16 +0000 Subject: [PATCH 1043/1300] perf(Algebra/Category/ModuleCat/Presheaf): speed up the monoidal pushforward instance (#41753) This was one of the slowest declarations to typecheck in mathlib. Replacing an `Iso.refl` with something more explicit yields something which the kernel finds far easier to swallow. As a bonus we can remove a `set_option backward.isDefEq.respectTransparency false`. --- .../Presheaf/PushforwardZeroMonoidal.lean | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/PushforwardZeroMonoidal.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/PushforwardZeroMonoidal.lean index bb80f36f6ad207..f0e1b12584b1ca 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/PushforwardZeroMonoidal.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/PushforwardZeroMonoidal.lean @@ -29,12 +29,21 @@ namespace PresheafOfModules variable {C D : Type*} [Category* C] [Category* D] (F : C ⥤ D) (R : Dᵒᵖ ⥤ CommRingCat.{u}) -set_option backward.isDefEq.respectTransparency false in +open ModuleCat.MonoidalCategory in noncomputable instance : (pushforward₀OfCommRingCat F R).Monoidal := Functor.CoreMonoidal.toMonoidal { εIso := Iso.refl _ - μIso _ _ := Iso.refl _ - left_unitality _ := by rw [← cancel_epi (λ_ _).inv]; cat_disch - right_unitality _ := by rw [← cancel_epi (ρ_ _).inv]; cat_disch } + -- using `Iso.refl _` for `μIso` directly hurts kernel typechecking + μIso _ _ := isoMk (fun _ ↦ Iso.refl _) (fun _ _ _ ↦ tensor_ext fun _ _ ↦ rfl) + associativity _ _ _ := by + ext1 + exact tensor_ext₃' fun m₁ m₂ m₃ ↦ rfl + left_unitality _ := by + ext1 + exact tensor_ext fun m₁ m₂ ↦ rfl + right_unitality _ := by + ext1 + exact tensor_ext fun m₁ m₂ ↦ rfl + } end PresheafOfModules From 8ae3f0490e68a64918e70beddcdefc2fd33c085c Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Tue, 28 Jul 2026 10:53:23 +0000 Subject: [PATCH 1044/1300] chore(RingTheory/Ideal/Norm/RelNorm): use `Module.finrank` on base rings (#42175) In light of #41694, we can remove `FractionRing` from `Module.firank` in `RingTheory/Ideal/Norm/RelNorm.lean`. Co-authored-by: tb65536 --- .../NumberField/Discriminant/Different.lean | 12 ++---------- Mathlib/RingTheory/Ideal/Norm/RelNorm.lean | 15 +++++++-------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean index a587564c84f2c8..91e335d14d6698 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant/Different.lean @@ -96,11 +96,7 @@ theorem natAbs_discr_eq_absNorm_differentIdeal_mul_natAbs_discr_pow (L 𝒪' : T have := congr_arg Ideal.absNorm (differentIdeal_eq_differentIdeal_mul_differentIdeal ℤ 𝒪 𝒪') rwa [absNorm_differentIdeal L, map_mul, Ideal.absNorm_algebraMap, - absNorm_differentIdeal K, Algebra.finrank_eq_of_equiv_equiv - (FractionRing.algEquiv 𝒪 K).toRingEquiv (FractionRing.algEquiv 𝒪' L).toRingEquiv] at this - ext - exact IsFractionRing.algEquiv_commutes (FractionRing.algEquiv 𝒪 K) - (FractionRing.algEquiv 𝒪' L) _ + absNorm_differentIdeal K, ← IsFractionRing.finrank_eq 𝒪 K 𝒪' L] at this variable (L : Type*) [Field L] @@ -163,11 +159,7 @@ theorem natAbs_discr_eq_natAbs_discr_pow_mul_natAbs_discr_pow (K₁ K₂ : Inter rwa [differentIdeal_eq_map_differentIdeal ℤ (𝓞 L) (𝓞 K₂) (𝓞 K₁) (F₁ := K₂) (F₂ := K₁) (by rwa [linearDisjoint_comm]) (by rwa [sup_comm]) (by rwa [isCoprime_comm]), Ideal.absNorm_algebraMap, absNorm_differentIdeal K₁, h₁.finrank_right_eq_finrank h₂, - Algebra.finrank_eq_of_equiv_equiv (FractionRing.algEquiv _ K₁).toRingEquiv - (FractionRing.algEquiv _ L).toRingEquiv, h₁.finrank_left_eq_finrank h₂] at h_main - ext - exact IsFractionRing.algEquiv_commutes (FractionRing.algEquiv (𝓞 K₁) K₁) - (FractionRing.algEquiv (𝓞 L) L) _ + ← IsFractionRing.finrank_eq (𝓞 K₁) K₁ (𝓞 L) L, h₁.finrank_left_eq_finrank h₂] at h_main end diff --git a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean index 797eee4c5e494c..081bdfc7f92b17 100644 --- a/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean +++ b/Mathlib/RingTheory/Ideal/Norm/RelNorm.lean @@ -352,8 +352,7 @@ variable {R} (S) attribute [local instance] Localization.AtPrime.liftAlgebra in theorem relNorm_algebraMap (I : Ideal R) : - relNorm R (I.map (algebraMap R S)) = - I ^ Module.finrank (FractionRing R) (FractionRing S) := by + relNorm R (I.map (algebraMap R S)) = I ^ finrank R S := by rw [← spanNorm_eq] refine eq_of_localization_maximal (fun P hPd ↦ ?_) let P' := Algebra.algebraMapSubmonoid S P.primeCompl @@ -366,14 +365,15 @@ theorem relNorm_algebraMap (I : Ideal R) : congr 2 apply IsFractionRing.injective Rₚ K rw [Algebra.algebraMap_intNorm (L := FractionRing S), ← IsScalarTower.algebraMap_apply, - IsScalarTower.algebraMap_apply Rₚ K, Algebra.norm_algebraMap, map_pow] + IsScalarTower.algebraMap_apply Rₚ K, Algebra.norm_algebraMap, map_pow, + IsFractionRing.finrank_eq R (FractionRing R) S (FractionRing S)] variable (R) /-- A version of `relNorm_algebraMap` involving a tower of algebras `S/R/R'`. -/ theorem relNorm_algebraMap' {R'} [CommRing R'] (I : Ideal R') [Algebra R' R] - [Algebra R' S] [IsScalarTower R' R S] : relNorm R (I.map (algebraMap R' S)) = - I.map (algebraMap R' R) ^ Module.finrank (FractionRing R) (FractionRing S) := by + [Algebra R' S] [IsScalarTower R' R S] : + relNorm R (I.map (algebraMap R' S)) = I.map (algebraMap R' R) ^ finrank R S := by rw [← relNorm_algebraMap, Ideal.map_map, IsScalarTower.algebraMap_eq R' R S] section relNorm_prime @@ -425,7 +425,7 @@ theorem relNorm_eq_pow_of_isPrime_isGalois [p.IsMaximal] [P.IsPrime] have h := (congr_arg (relNorm R ·) <| map_algebraMap_eq_finsetProd_pow hp).symm.trans <| relNorm_algebraMap S p simp +contextual only [map_prod, map_pow, h₀, Finset.prod_const, ← pow_mul] at h - rwa [← IsGaloisGroup.card_eq_finrank G (FractionRing R) (FractionRing S), + rwa [← IsGaloisGroup.card_eq_finrank' G R S, ← Ideal.ncard_primesOver_mul_ramificationIdxIn_mul_inertiaDegIn p S G, mul_comm, ← Set.ncard_eq_toFinset_card', ((IsLeftCancelMulZero.mul_left_cancel_of_ne_zero hp).pow_injective _).eq_iff, @@ -478,8 +478,7 @@ theorem relNorm_int (I : Ideal S) : rw [← Int.ideal_span_absNorm_eq_self (relNorm ℤ I), absNorm_relNorm] theorem absNorm_algebraMap (I : Ideal R) [Module.Finite ℤ R] : - absNorm (I.map (algebraMap R S)) = - (absNorm I) ^ Module.finrank (FractionRing R) (FractionRing S) := by + absNorm (I.map (algebraMap R S)) = absNorm I ^ finrank R S := by rw [← absNorm_relNorm ℤ, ← relNorm_relNorm ℤ R, relNorm_algebraMap, absNorm_relNorm, map_pow] end absNorm From 767b2da0c502f5eb9b730915705ce5a0634a60af Mon Sep 17 00:00:00 2001 From: Scott Carnahan <128885296+ScottCarnahan@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:03:04 +0000 Subject: [PATCH 1045/1300] feat(Algebra/Lie): grading on loop algebras (#38594) In this PR we introduce a decomposition of a tensor product of modules induced by a decomposition of the module on the left side. This is used to produce the canonical "energy" grading on a loop Lie algebra. This will (eventually) give us the "energy" grading on smooth representations of affine algebras. Co-authored-by: Oliver Nash --- Mathlib/Algebra/Lie/Loop.lean | 37 ++++++++ .../DirectSum/TensorProduct.lean | 8 ++ .../TensorProduct/Decomposition.lean | 95 +++++++++++++++++-- 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/Lie/Loop.lean b/Mathlib/Algebra/Lie/Loop.lean index 2b9b690e70e189..7ce93dfbdcfb0c 100644 --- a/Mathlib/Algebra/Lie/Loop.lean +++ b/Mathlib/Algebra/Lie/Loop.lean @@ -7,8 +7,11 @@ module public import Mathlib.Algebra.Group.EvenFunction public import Mathlib.Algebra.Lie.Cochain +public import Mathlib.Algebra.Lie.Graded public import Mathlib.Algebra.Lie.InvariantForm +public import Mathlib.Algebra.MonoidAlgebra.Grading public import Mathlib.Algebra.Polynomial.Laurent +public import Mathlib.LinearAlgebra.TensorProduct.Decomposition /-! # Loop Lie algebras and their central extensions @@ -70,6 +73,40 @@ def loopAlgebraEquivLaurent : namespace LoopAlgebra +open DirectSum in +noncomputable instance [DecidableEq A] [AddCommMonoid A] : + GradedLieAlgebra (fun a : A ↦ (decomposeTensor (AddMonoidAlgebra.grade R) L a)) where + bracket_mem i j xi xj hi hj := by + rw [decomposeTensor_apply] at hi hj ⊢ + obtain ⟨xi, rfl⟩ := hi + obtain ⟨xj, rfl⟩ := hj + induction xi using TensorProduct.induction_on with + | zero => simp + | tmul x y => + simp only [LinearMap.rTensor_tmul, Submodule.subtype_apply] + induction xj using TensorProduct.induction_on with + | zero => simp + | tmul u v => + obtain ⟨x, hx⟩ := x + obtain ⟨u, hu⟩ := u + use ⟨x * u, SetLike.mul_mem_graded hx hu⟩ ⊗ₜ ⁅y, v⁆ + simp + | add u v hu hv => + rw [LinearMap.map_add, lie_add] + obtain ⟨u', hu'⟩ := hu + obtain ⟨v', hv'⟩ := hv + use u' + v' + simp [← hu', ← hv'] + | add x y hx hy => + rw [LinearMap.map_add, add_lie] + obtain ⟨u, hu⟩ := hx + obtain ⟨v, hv⟩ := hy + use u + v + simp [← hu, ← hv] + decompose' := (tensorDecomposition (fun a : A ↦ AddMonoidAlgebra.grade R a) L).decompose' + left_inv := (tensorDecomposition _ L).left_inv + right_inv := (tensorDecomposition _ L).right_inv + open scoped Classical in /-- A linear isomorphism to finitely supported functions. -/ def toFinsupp : loopAlgebra R A L ≃ₗ[R] A →₀ L := diff --git a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean index 15174666a8cd4d..10d530acea821e 100644 --- a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean @@ -118,6 +118,14 @@ lemma directSumLeft_tmul (m : ⨁ i, M₁ i) (n : M₂') (i : ι₁) : · subst hj; simp · simp [DirectSum.component.of, hj] +lemma directSumLeft_symm_of {i : ι₁} (x : (M₁ i) ⊗[R] M₂') : + (directSumLeft R S M₁ M₂').symm ((of (fun i ↦ M₁ i ⊗[R] M₂') i) x) = + rTensor M₂' (lof R ι₁ M₁ i) x := by + induction x using TensorProduct.induction_on with + | zero => simp + | tmul x y => rw [← lof_eq_of S, directSumLeft_symm_lof_tmul, rTensor_tmul, lof_eq_of, lof_eq_of] + | add x y h₁ h₂ => simp [h₁, h₂] + set_option backward.isDefEq.respectTransparency false in @[simp] theorem directSumRight_tmul_lof (x : M₁') (i : ι₂) (y : M₂ i) : diff --git a/Mathlib/LinearAlgebra/TensorProduct/Decomposition.lean b/Mathlib/LinearAlgebra/TensorProduct/Decomposition.lean index 19034038b799ec..2b87d3687f83e7 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Decomposition.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Decomposition.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kenny Lau +Authors: Kenny Lau, Scott Carnahan -/ module @@ -10,9 +10,11 @@ public import Mathlib.LinearAlgebra.DirectSum.TensorProduct /-! # Decomposition of tensor product -In this file we show that if `ℳ` is a decomposition of an `R`-module `M` indexed by a type `ι`, -then the `S`-module `S ⊗[R] M` has a decomposition `fun i ↦ (ℳ i).baseChange S` indexed by the -same `ι`. +In this file, we describe the properties of decomposition under tensor product. Suppose `ℳ` is a +decomposition of an `R`-module `M` indexed by a type `ι`. Given an `R`-module `N`, the `R`-module +`M ⊗[R] N` has a decomposition into pieces `fun i ↦ (ℳ i) ⊗[R] N`. Given a commutative `R`-algebra +`S`, the `S`-module `S ⊗[R] M` has a decomposition `fun i ↦ (ℳ i).baseChange S`. + -/ public section @@ -21,13 +23,13 @@ open TensorProduct LinearMap namespace DirectSum -variable {ι R M S : Type*} [DecidableEq ι] +variable {ι R M S : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M] (ℳ : ι → Submodule R M) - [CommSemiring S] [Algebra R S] -section Decomposition -variable [Decomposition ℳ] +section BaseChange + +variable [DecidableEq ι] [Decomposition ℳ] [CommSemiring S] [Algebra R S] instance Decomposition.baseChange : Decomposition fun i ↦ (ℳ i).baseChange S := by refine .ofLinearMap _ (lmap (ℳ · |>.toBaseChange S) ∘ₗ @@ -52,10 +54,85 @@ theorem toBaseChange_injective (i : ι) : Function.Injective ((ℳ i).toBaseChan theorem toBaseChange_bijective (i : ι) : Function.Bijective ((ℳ i).toBaseChange S) := ⟨toBaseChange_injective ℳ i, (ℳ i).toBaseChange_surjective S⟩ -end Decomposition +end BaseChange + +section TensorModule + +variable (N : Type*) [AddCommMonoid N] [Module R N] + +/-- The submodule of a tensor product corresponding to a decomposition on the left. -/ +def decomposeTensor (i : ι) : Submodule R (M ⊗[R] N) := + ((ℳ i).subtype.rTensor N).range + +lemma decomposeTensor_apply {i : ι} : + decomposeTensor ℳ N i = ((ℳ i).subtype.rTensor N).range := + Submodule.toSubMulAction_inj.mp rfl + +variable [DecidableEq ι] [Decomposition ℳ] + +lemma subtype_rTensor_injective (i : ι) : + Function.Injective ((ℳ i).subtype.rTensor N) := + injective_of_comp_eq_id ((ℳ i).subtype.rTensor N) + ((component R ι (fun i ↦ ℳ i) i ∘ₗ DirectSum.decomposeLinearEquiv ℳ).rTensor N) + (by ext; simp) + +/-- The linear isomorphism to the submodule from the tensor product with a summand. -/ +noncomputable def decomposeTensorEquiv (i : ι) : + (ℳ i) ⊗[R] N ≃ₗ[R] decomposeTensor ℳ N i := + LinearEquiv.ofInjective ((ℳ i).subtype.rTensor N) (subtype_rTensor_injective ℳ N i) + +lemma decomposeTensorEquiv_apply {i : ι} (x : (ℳ i) ⊗[R] N) : + decomposeTensorEquiv ℳ N i x = + ⟨(ℳ i).subtype.rTensor N x, by convert (decomposeTensorEquiv ℳ N i x).property; rfl⟩ := by + rfl + +@[simp] +lemma val_decomposeTensorEquiv_apply {i : ι} (x : (ℳ i) ⊗[R] N) : + decomposeTensorEquiv ℳ N i x = (ℳ i).subtype.rTensor N x := by rfl + +lemma decomposeTensorEquiv_of_apply {i : ι} (x : (ℳ i) ⊗[R] N) : + congrLinearEquiv (fun i ↦ decomposeTensorEquiv ℳ N i) (of (fun i ↦ ↥(ℳ i) ⊗[R] N) i x) = + of (fun i ↦ decomposeTensor ℳ N i) i (decomposeTensorEquiv ℳ N i x) := by + ext; simp [coe_congrLinearEquiv] + +lemma decomposeLinearEquiv_comp_subtype {i : ι} : + decomposeLinearEquiv ℳ ∘ₗ (ℳ i).subtype = lof R ι (fun i ↦ ℳ i) i := by + ext; simp + +lemma coe_decomposeTensor_apply (x : (⨁ i, decomposeTensor ℳ N i)) : + DirectSum.coeAddMonoidHom (decomposeTensor ℳ N) x = + (DirectSum.decomposeLinearEquiv ℳ).symm.rTensor N + ((TensorProduct.directSumLeft R R (fun i ↦ ℳ i) N).symm <| + (DirectSum.congrLinearEquiv <| decomposeTensorEquiv ℳ N).symm x) := by + rw [← LinearEquiv.symm_rTensor, LinearEquiv.eq_symm_apply] + induction x using DirectSum.induction_on with + | zero => simp + | of i x => + obtain ⟨-, y, rfl⟩ := x + have : (rTensor N (lof R ι (fun i ↦ ℳ i) i)) y = + (directSumLeft R R (fun i ↦ ℳ i) N).symm ((of (fun i ↦ ℳ i ⊗[R] N) i) y) := + (TensorProduct.directSumLeft_symm_of R R (M₁ := fun i ↦ ℳ i) y).symm + rw [coeAddMonoidHom_of, LinearEquiv.eq_symm_apply, LinearEquiv.eq_symm_apply, + ← (LinearEquiv.rTensor N _).coe_coe, LinearEquiv.coe_rTensor, ← rTensor_comp_apply, + decomposeLinearEquiv_comp_subtype, this, LinearEquiv.apply_symm_apply, + decomposeTensorEquiv_of_apply, decomposeTensorEquiv_apply] + | add x y hx hy => simp [hx, hy] + +/-- The decomposition of a tensor product induced by a decomposition of the left module. -/ +@[reducible] +noncomputable def tensorDecomposition (N : Type*) [AddCommGroup N] [Module R N] : + DirectSum.Decomposition (decomposeTensor ℳ N) where + decompose' x := (DirectSum.congrLinearEquiv <| decomposeTensorEquiv ℳ N) + (directSumLeft R R (fun i ↦ ℳ i) N <| (DirectSum.decomposeLinearEquiv ℳ).rTensor N x) + left_inv x := by simp [coe_decomposeTensor_apply ℳ N _, ← LinearEquiv.symm_rTensor] + right_inv x := by simp [coe_decomposeTensor_apply ℳ N _, ← LinearEquiv.symm_rTensor] + +end TensorModule namespace IsInternal +variable [DecidableEq ι] [CommSemiring S] [Algebra R S] + theorem baseChange (hm : IsInternal ℳ) : IsInternal fun i ↦ (ℳ i).baseChange S := haveI := hm.chooseDecomposition Decomposition.isInternal _ From 3be53ac28f0f6374ed0cb4ae6aa6801b0b13d554 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck <56166236+CBirkbeck@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:40:44 +0000 Subject: [PATCH 1046/1300] feat(NumberTheory/ModularForms): API lemmas for level-1 graded ring (#38908) Adds API lemmas extracted from #38813 to keep that PR reviewable: `DirectSum.of_eq_of_eq`, `DirectSum.of_eq_sub_add_smul`, `ModularForm.cast_apply`, `ModularForm.mul_ne_zero`, `ModularForm.sub_smul_isCuspForm`. --- Mathlib/NumberTheory/ModularForms/Basic.lean | 4 ++++ .../NumberTheory/ModularForms/CuspFormSubmodule.lean | 11 +++++++++++ Mathlib/NumberTheory/ModularForms/QExpansion.lean | 10 ++++++++++ 3 files changed, 25 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/Basic.lean b/Mathlib/NumberTheory/ModularForms/Basic.lean index 5cc5a365590183..021cce87507a20 100644 --- a/Mathlib/NumberTheory/ModularForms/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/Basic.lean @@ -559,6 +559,10 @@ def mcast {a b : ℤ} {Γ Γ' : Subgroup (GL (Fin 2) ℝ)} (h : a = b) (f : Modu holo' := f.holo' bdd_at_cusps' hc := h ▸ f.bdd_at_cusps' (hΓ ▸ hc) +/-- `mcast` does not change the pointwise values of a modular form. -/ +theorem mcast_apply {a b : ℤ} {Γ Γ' : Subgroup (GL (Fin 2) ℝ)} (h : a = b) (f : ModularForm Γ a) + (hΓ : Γ' = Γ := by rfl) (z : ℍ) : mcast h f hΓ z = f z := rfl + @[simp] lemma mcast_eq_zero_iff {a b : ℤ} {Γ Γ' : Subgroup (GL (Fin 2) ℝ)} (h : a = b) (hΓ : Γ' = Γ) (f : ModularForm Γ a) : mcast h f hΓ = 0 ↔ f = 0 := by diff --git a/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean b/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean index e2726fc0b67137..321e1a927c087e 100644 --- a/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean +++ b/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean @@ -141,6 +141,17 @@ lemma isCuspForm_iff_coeffZero_eq_zero (f : ModularForm 𝒮ℒ k) : (periodic_comp_ofComplex _ one_mem_strictPeriods_SL)] exact (CuspFormClass.zero_at_infty g).valueAtInfty_eq_zero +/-- Subtracting `(qExpansion 1 f).coeff 0 • g` from `f` (where `g` has constant qExpansion 1) +gives a cusp form. -/ +lemma sub_smul_isCuspForm (f g : ModularForm 𝒮ℒ k) + (hg : (qExpansion 1 g).coeff 0 = 1) : + ModularForm.IsCuspForm (f - (qExpansion 1 f).coeff 0 • g) := by + rw [isCuspForm_iff_coeffZero_eq_zero, ModularForm.coe_sub, + ModularForm.qExpansion_sub one_pos one_mem_strictPeriods_SL, IsGLPos.coe_smul, + ModularForm.qExpansion_smul one_pos one_mem_strictPeriods_SL, + map_sub, PowerSeries.coeff_smul] + simp [hg] + end SL2Z end ModularForm diff --git a/Mathlib/NumberTheory/ModularForms/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/QExpansion.lean index 7fda871e61b063..d0c96069ab15e3 100644 --- a/Mathlib/NumberTheory/ModularForms/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/QExpansion.lean @@ -10,6 +10,7 @@ public import Mathlib.Analysis.Complex.UpperHalfPlane.Exp public import Mathlib.NumberTheory.ModularForms.Basic public import Mathlib.NumberTheory.ModularForms.Identities public import Mathlib.RingTheory.PowerSeries.Basic +public import Mathlib.RingTheory.MvPowerSeries.NoZeroDivisors /-! # q-expansions of functions on the upper half plane @@ -628,6 +629,15 @@ protected lemma qExpansion_pow [Γ.HasDetPlusMinusOne] (hh : 0 < h) rw [coe_pow, pow_succ, ← coe_pow, ← coe_mul, ModularForm.qExpansion_mul hh hΓ, ih, pow_succ] +/-- The product of two non-zero modular forms is non-zero. -/ +protected lemma mul_ne_zero [Γ.HasDetPlusMinusOne] (hΓ : ∃ h ∈ Γ.strictPeriods, 0 < h) + {a b : ℤ} {f : ModularForm Γ a} {g : ModularForm Γ b} (hf : f ≠ 0) (hg : g ≠ 0) : + f.mul g ≠ 0 := by + obtain ⟨h, hΓ, hh⟩ := hΓ + simp only [ne_eq, ← ModularForm.qExpansion_eq_zero_iff hh hΓ, + ModularForm.qExpansion_mul hh hΓ] at hf hg ⊢ + exact mul_ne_zero hf hg + /-- The qExpansion map as an additive group hom. to power series over `ℂ`. -/ def qExpansionAddHom (hh : 0 < h) (hΓ : h ∈ Γ.strictPeriods) (k : ℤ) : ModularForm Γ k →+ PowerSeries ℂ where From 3b6f23172a994dc739dfcc974199fe05c44f691d Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Tue, 28 Jul 2026 11:40:46 +0000 Subject: [PATCH 1047/1300] feat(LinearAlgebra): commutative semirings satisfy strong rank condition (#39161) Thanks to ChatGPT and Gemini for converting part of Yi-Jia Tan's paper into LaTeX, which served as solutions provided to Aristotle. - [x] depends on: #40875 Co-authored-by: Aristotle (Harmonic) Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> Co-authored-by: Oliver Nash --- Mathlib.lean | 1 + .../LinearAlgebra/Matrix/Nondegenerate.lean | 4 +- Mathlib/LinearAlgebra/Matrix/Nonsingular.lean | 163 ++++++++++++++++++ .../LinearAlgebra/Matrix/SemiringInverse.lean | 112 +++++++++++- docs/references.bib | 14 ++ 5 files changed, 290 insertions(+), 4 deletions(-) create mode 100644 Mathlib/LinearAlgebra/Matrix/Nonsingular.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9d183644120d06..29db19960dc526 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5155,6 +5155,7 @@ public import Mathlib.LinearAlgebra.Matrix.Kronecker public import Mathlib.LinearAlgebra.Matrix.Module public import Mathlib.LinearAlgebra.Matrix.MvPolynomial public import Mathlib.LinearAlgebra.Matrix.Nondegenerate +public import Mathlib.LinearAlgebra.Matrix.Nonsingular public import Mathlib.LinearAlgebra.Matrix.NonsingularInverse public import Mathlib.LinearAlgebra.Matrix.Notation public import Mathlib.LinearAlgebra.Matrix.Orthogonal diff --git a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean index 3a8f262c4f5e2f..14a74a2c31d76e 100644 --- a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean @@ -38,7 +38,9 @@ def SeparatingRight : Prop := def SeparatingLeft : Prop := (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0) → v = 0) -/-- A matrix `M` is nondegenerate if it is both left-separating and right-separating. -/ +/-- A matrix `M` is nondegenerate if it is both left-separating and right-separating. + +See also `Matrix.Nonsingular`. -/ @[mk_iff] structure Nondegenerate (M : Matrix m n R) : Prop where separatingLeft : SeparatingLeft M diff --git a/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean b/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean new file mode 100644 index 00000000000000..68ef3c3b93a3d5 --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean @@ -0,0 +1,163 @@ +/- +Copyright (c) 2026 Junyan Xu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Junyan Xu, Aristotle AI +-/ +module + +public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic + +import Mathlib.LinearAlgebra.InvariantBasisNumber +import Mathlib.LinearAlgebra.Matrix.SemiringInverse +import Mathlib.LinearAlgebra.Matrix.ToLin + +/-! +# Linear independence and nonsingularity of matrices + +In this file we formalize several theorems proved by Yi-Jia Tan in his paper [Tan2016] +*Free sets and free subsemimodules in a semimodule*. As consequences, we show that +commutative semirings satisfy the strong rank condition, and that the columns of a square matrix +are linearly independent if and only if the matrix is nonsingular (over a commutative ring, +a matrix is nonsingular if and only if its determinant is not a zero divisor). + +## Main theorems + +* `Matrix.Nonsingular.of_linearIndependent_col`: if the columns of a square matrix are linearly + independent, then the matrix is nonsingular. Corollary 3.2(1) of [Tan2016]. + +* `Matrix.Nonsingular.linearIndependent_col`: if a matrix over a commutative semiring with + cancellative addition is nonsingular, then its columns are linearly independent. + Corollary 3.2(2) of [Tan2016]. + +* `CommSemiring.strongRankCondition_of_nontrivial`: a commutative semiring satisfies the strong + rank condition. +-/ + +variable {R m n : Type*} [CommSemiring R] [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n] +variable {A : Matrix n n R} + +namespace Matrix + +public section + +lemma isDetpBalanced_iff_sub_mul_det_eq_zero {R : Type*} [CommRing R] {A : Matrix n n R} {a b : R} : + A.IsDetpBalanced a b ↔ (a - b) * A.det = 0 := by + grind [IsDetpBalanced, det_eq_detp_sub_detp] + +lemma nonsingular_iff_det_mem_nonZeroDivisors {R : Type*} [CommRing R] + {A : Matrix n n R} : A.Nonsingular ↔ A.det ∈ nonZeroDivisors R := by + simp_rw [Nonsingular, isDetpBalanced_iff_sub_mul_det_eq_zero, mem_nonZeroDivisors_iff_right] + exact ⟨fun h x eq ↦ h x 0 (by simpa), fun h a b eq ↦ sub_eq_zero.mp <| h _ (by simpa)⟩ + +lemma nonsingular_iff_det_ne_zero {R : Type*} [CommRing R] [IsDomain R] + {A : Matrix n n R} : A.Nonsingular ↔ A.det ≠ 0 := by + rw [nonsingular_iff_det_mem_nonZeroDivisors, mem_nonZeroDivisors_iff_ne_zero] + +/-- If the columns of a square matrix are linearly independent, then the matrix is nonsingular. -/ +theorem Nonsingular.of_linearIndependent_col (ind : LinearIndependent R A.col) : A.Nonsingular := by + intro a b bal + let P (r : ℕ) : Prop := ∀ f g : Fin r → n, (A.submatrix f g).IsDetpBalanced a b + suffices h : P 0 by simpa [IsDetpBalanced] using h Fin.elim0 Fin.elim0 + refine Nat.decreasingInduction' (n := Fintype.card n) (fun r _ _ ih f g ↦ ?_) (Nat.zero_le _) <| + bal.submatrix_of_card_le (Fintype.card_fin _).ge + by_cases hg : g.Surjective + · exact bal.submatrix_of_card_le (Fintype.card_le_of_surjective g hg) f g + obtain ⟨j₀, h₀⟩ := by simpa [Function.Surjective] using hg + let D := A.submatrix f g + let Aj (j : Fin r) := A.submatrix f (Function.update g j j₀) + let v (a b : R) : n →₀ R := ∑ j, .single (g j) (a * (Aj j).detp (-1) + b * (Aj j).detp 1) + + .single j₀ (a * D.detp 1 + b * D.detp (-1)) + suffices h : v a b = v b a by simpa [IsDetpBalanced, v, h₀] using congr($h j₀) + refine ind (funext fun i ↦ ?_) + let Ai := A.submatrix (Option.rec i f) (Option.rec j₀ g) + have (s : ℤˣ) : Ai.detp s = ∑ j, (Aj j).detp (-s) * A.col (g j) i + D.detp s * A.col j₀ i := by + simp_rw [mul_comm]; rw [detp_option_expand_row_none, add_comm] + congr!; aesop (add simp Function.update) + have (a b : R) : (v a b).linearCombination R A.col i = a * Ai.detp 1 + b * Ai.detp (-1) := by + simp [v, Finset.sum_add_distrib, mul_assoc, ← Finset.mul_sum, add_add_add_comm, mul_add, this] + simpa [this, IsDetpBalanced, ← submatrix_submatrix] using + ih (Option.rec i f ∘ finSuccEquiv r) (Option.rec j₀ g ∘ finSuccEquiv r) + +theorem Nonsingular.of_linearIndependent_row (ind : LinearIndependent R A.row) : A.Nonsingular := by + simpa using Nonsingular.of_linearIndependent_col (A := Aᵀ) ind + +theorem Nonsingular.of_leftRegular (h : IsLeftRegular A) : A.Nonsingular := + .of_linearIndependent_col (by rwa [← mulVec_injective_iff, ← isLeftRegular_iff_mulVec_injective]) + +theorem Nonsingular.of_rightRegular (h : IsRightRegular A) : A.Nonsingular := + .of_linearIndependent_row (by rwa [← vecMul_injective_iff, ← isRightRegular_iff_vecMul_injective]) + +variable [IsCancelAdd R] + +/-- If a matrix over a commutative semiring with cancellative addition is nonsingular, then its +columns are linearly independent. Generalizes `Matrix.linearIndependent_cols_of_det_ne_zero`. -/ +theorem Nonsingular.linearIndependent_col (hA : A.Nonsingular) : LinearIndependent R A.col := + mulVec_injective_iff.mp fun x y eq ↦ funext fun k ↦ hA _ _ <| show _ = _ by + have h v : ((A.adjp 1 * A + A.detp (-1) • 1) *ᵥ v) k = + ((A.adjp (-1) * A + A.detp 1 • 1) *ᵥ v) k := by + congr 1; ext k i + obtain (h | h) := eq_or_ne k i <;> simp [adjp_mul_apply_eq, add_comm, adjp_mul_apply_ne, h] + simp [add_mulVec, smul_mulVec, ← mulVec_mulVec] at h; grind + +theorem Nonsingular.linearIndependent_row (hA : A.Nonsingular) : LinearIndependent R A.row := + hA.transpose.linearIndependent_col + +theorem linearIndependent_col_iff : LinearIndependent R A.col ↔ A.Nonsingular := + ⟨.of_linearIndependent_col, (·.linearIndependent_col)⟩ + +theorem linearIndependent_row_iff : LinearIndependent R A.row ↔ A.Nonsingular := + ⟨.of_linearIndependent_row, (·.linearIndependent_row)⟩ + +theorem isLeftRegular_iff_nonsingular : IsLeftRegular A ↔ A.Nonsingular := by + rw [isLeftRegular_iff_mulVec_injective, mulVec_injective_iff, linearIndependent_col_iff] + +theorem isRightRegular_iff_nonsingular : IsRightRegular A ↔ A.Nonsingular := by + rw [isRightRegular_iff_vecMul_injective, vecMul_injective_iff, linearIndependent_row_iff] + +lemma Nonsingular.mul {B : Matrix n n R} (hA : A.Nonsingular) (hB : B.Nonsingular) : + (A * B).Nonsingular := by + rw [← isLeftRegular_iff_nonsingular] at * + exact hA.mul hB + +lemma nonsingular_mul_iff {A B : Matrix n n R} : + (A * B).Nonsingular ↔ A.Nonsingular ∧ B.Nonsingular where + mp h := ⟨isRightRegular_iff_nonsingular.mp <| .of_mul <| isRightRegular_iff_nonsingular.mpr h, + isLeftRegular_iff_nonsingular.mp <| .of_mul <| isLeftRegular_iff_nonsingular.mpr h⟩ + mpr h := h.1.mul h.2 + +lemma Nonsingular.pow (hA : A.Nonsingular) : ∀ k, (A ^ k).Nonsingular + | 0 => by simp + | k + 1 => by simp [pow_succ, (hA.pow k).mul hA] + +omit [DecidableEq n] in +theorem isLeftRegular_iff_isRightRegular : IsLeftRegular A ↔ IsRightRegular A := by + classical rw [isLeftRegular_iff_nonsingular, isRightRegular_iff_nonsingular] + +omit [DecidableEq n] [Fintype n] in +/-- https://mathoverflow.net/questions/511862/transpose-symmetry-of-injectivity-of-linear-maps-over-semirings +asks whether this is still true without `IsCancelAdd R`. -/ +theorem linearIndependent_col_iff_row [Finite n] : + LinearIndependent R A.col ↔ LinearIndependent R A.row := by + have := Fintype.ofFinite + classical rw [linearIndependent_col_iff, linearIndependent_row_iff] + +end + +end Matrix + +open Matrix + +/-- A nontrivial commutative semiring satisfies the strong rank condition. -/ +instance (priority := 100) CommSemiring.strongRankCondition_of_nontrivial [Nontrivial R] : + StrongRankCondition R where + le_of_fin_injective {n m} f hf := by + let g : (Fin m → R) →ₗ[R] (Fin n → R) := .pi fun i ↦ if h : i < m then .proj ⟨i, h⟩ else 0 + by_contra! hnm + have hg : Function.Injective g := fun x y eq ↦ funext fun i ↦ by + simpa [g] using congr($eq ⟨i, i.prop.trans hnm⟩) + let A := (g ∘ₗ f).toMatrix' + have hA : A.Nonsingular := .of_linearIndependent_col <| mulVec_injective_iff.mp <| by + convert hg.comp hf; ext; simp [A, g] + have : A.row ⟨m, hnm⟩ = 0 := by ext; simp [A, g] + exact not_subsingleton R + ⟨by simpa [Nonsingular, IsDetpBalanced, detp_eq_of_row_eq_zero _ this] using hA⟩ diff --git a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean index 11b3a0500088fb..c88a6e455f8181 100644 --- a/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean +++ b/Mathlib/LinearAlgebra/Matrix/SemiringInverse.lean @@ -11,6 +11,7 @@ public import Mathlib.GroupTheory.Perm.Sign import Mathlib.Algebra.Module.End import Mathlib.GroupTheory.Perm.Option +import Mathlib.Tactic.Abel import Mathlib.LinearAlgebra.Matrix.RowCol /-! @@ -37,6 +38,8 @@ def detp : R := ∑ σ ∈ ofSign s, ∏ k, A k (σ k) @[simp] lemma detp_transpose : A.transpose.detp s = A.detp s := sum_equiv (.inv _) (by simp) fun σ _ ↦ prod_equiv σ (by simp) (by simp) +@[simp] lemma detp_zero [Nonempty n] : (0 : Matrix n n R).detp s = 0 := by simp [detp] + @[simp] lemma detp_one_diagonal (d : n → R) : detp 1 (diagonal d) = ∏ i, d i := by rw [detp, sum_eq_single_of_mem 1] @@ -80,14 +83,100 @@ lemma detp_neg_one_one : detp (-1) (1 : Matrix n n R) = 0 := by lemma detp_submatrix_equiv_self (e : m ≃ n) : (A.submatrix e e).detp s = A.detp s := by simp -variable {A} +lemma detp_smul (c : R) : (c • A).detp s = c ^ Fintype.card n * A.detp s := by + simp [detp, Finset.mul_sum, Finset.prod_mul_distrib] + +lemma detp_map {S : Type*} [CommSemiring S] (f : R →+* S) : + (A.map f).detp s = f (A.detp s) := by simp [detp] + +/-- A square matrix `A` over a commutative semiring `R` is "determinant balanced" +with respect to `a b : R` if `a|A|⁺ + b|A|⁻ = b|A|⁺ + a|A|⁻`. Over a commutative ring, +this is equivalent to `(a - b)|A| = 0`, see `Matrix.isDetpBalanced_iff_sub_mul_det_eq_zero`. -/ +def IsDetpBalanced (a b : R) : Prop := + a * A.detp 1 + b * A.detp (-1) = b * A.detp 1 + a * A.detp (-1) + +lemma IsDetpBalanced.refl (a : R) : A.IsDetpBalanced a a := rfl + +variable {A} {a b c : R} + +lemma IsDetpBalanced.of_eq (eq : A.detp 1 = A.detp (-1)) : A.IsDetpBalanced a b := by + rw [IsDetpBalanced, eq, add_comm] + +lemma IsDetpBalanced.symm : A.IsDetpBalanced a b → A.IsDetpBalanced b a := Eq.symm + +lemma IsDetpBalanced_comm : A.IsDetpBalanced a b ↔ A.IsDetpBalanced b a := Eq.comm + +lemma IsDetpBalanced.trans [IsCancelAdd R] + (hab : A.IsDetpBalanced a b) (hbc : A.IsDetpBalanced b c) : + A.IsDetpBalanced a c := by + rw [IsDetpBalanced] at * + apply add_left_cancel (a := b * detp 1 A + b * detp (-1) A) + convert congr($hab + $hbc) using 1 <;> abel + +lemma IsDetpBalanced.mul_add_mul_eq (h : A.IsDetpBalanced a b) (s t : ℤˣ) : + a * A.detp s + b * A.detp t = b * A.detp s + a * A.detp t := by + obtain rfl | rfl := Int.units_eq_one_or s <;> obtain rfl | rfl := Int.units_eq_one_or t + · rw [add_comm] + · rw [h] + · rw [add_comm, ← h, add_comm] + · rw [add_comm] + +@[simp] lemma isDetpBalanced_transpose_iff : Aᵀ.IsDetpBalanced a b ↔ A.IsDetpBalanced a b := by + simp [IsDetpBalanced] + +alias ⟨IsDetpBalanced.of_transpose, IsDetpBalanced.transpose⟩ := isDetpBalanced_transpose_iff + +lemma IsDetpBalanced.submatrix_equiv (e₁ e₂ : m ≃ n) (h : A.IsDetpBalanced a b) : + (A.submatrix e₁ e₂).IsDetpBalanced a b := by + simp_rw [IsDetpBalanced, detp_submatrix_equiv_equiv] + apply h.mul_add_mul_eq + +@[simp] lemma isDetpBalanced_submatrix_equiv_iff {e₁ e₂ : m ≃ n} : + (A.submatrix e₁ e₂).IsDetpBalanced a b ↔ A.IsDetpBalanced a b where + mp h := by simpa using h.submatrix_equiv e₁.symm e₂.symm + mpr := (·.submatrix_equiv ..) + +lemma IsDetpBalanced.smul (h : A.IsDetpBalanced a b) (c : R) : + (c • A).IsDetpBalanced a b := by + simp_rw [IsDetpBalanced, detp_smul, ← mul_assoc, mul_comm _ (c ^ _), mul_assoc, + ← mul_add, h.mul_add_mul_eq] + +variable (A) in +/-- A square matrix `A` over a commutative semiring `R` is called nonsingular if it is +only determinant balanced with respect to equal elements. + +See also See also `Matrix.Nondegenerate`. -/ +def Nonsingular : Prop := ∀ a b : R, A.IsDetpBalanced a b → a = b + +lemma Nonsingular.eq_of_IsDetpBalanced (hA : A.Nonsingular) (hAd : A.IsDetpBalanced a b) : + a = b := hA a b hAd + +lemma IsDetpBalanced.eq_of_nonsingular (hA : A.IsDetpBalanced a b) (hAn : A.Nonsingular) : + a = b := hAn.eq_of_IsDetpBalanced hA + +@[simp] lemma nonsingular_one : (1 : Matrix n n R).Nonsingular := + fun a b h ↦ by simpa [IsDetpBalanced] using h + +variable (A) in +@[simp] lemma Nonsingular.of_isEmpty [IsEmpty n] : A.Nonsingular := by + simp [Nonsingular, IsDetpBalanced] + +@[simp] lemma nonsingular_transpose_iff : Aᵀ.Nonsingular ↔ A.Nonsingular := by simp [Nonsingular] + +alias ⟨Nonsingular.of_transpose, Nonsingular.transpose⟩ := nonsingular_transpose_iff + +@[simp] lemma nonsingular_submatrix_equiv_iff {e₁ e₂ : m ≃ n} : + (A.submatrix e₁ e₂).Nonsingular ↔ A.Nonsingular := by simp [Nonsingular] + +alias ⟨_, Nonsingular.submatrix_equiv⟩ := nonsingular_submatrix_equiv_iff lemma detp_eq_of_row_eq {p q : n} (hpq : p ≠ q) (hrow : A.row p = A.row q) (s : ℤˣ := 1) (t : ℤˣ := -1) : A.detp s = A.detp t := by have : A.detp 1 = A.detp (-1) := sum_equiv (.mulRight <| swap p q) (by simp [hpq]) fun _ _ ↦ prod_equiv (swap p q) (by simp) (by aesop (add simp row)) - obtain rfl | rfl := Int.units_eq_one_or s <;> obtain rfl | rfl := Int.units_eq_one_or t <;> - first | rfl | rw [this] + obtain rfl | rfl := Int.units_eq_one_or s <;> + obtain rfl | rfl := Int.units_eq_one_or t <;> + first | rfl | rw [this] lemma detp_eq_of_col_eq {p q : n} (hpq : p ≠ q) (hcol : A.col p = A.col q) (s : ℤˣ := 1) (t : ℤˣ := -1) : A.detp s = A.detp t := by @@ -99,6 +188,23 @@ lemma detp_eq_of_row_eq_zero {p : n} (hrow : A.row p = 0) : A.detp s = 0 := lemma detp_eq_of_col_eq_zero {p : n} (hcol : A.col p = 0) : A.detp s = 0 := by simpa using detp_eq_of_row_eq_zero (A := Aᵀ) s hcol +/-- If `A` is determinant balanced with respect to `a` and `b`, any submatrix of +the same or bigger size (possibly with repeated rows or columns) is also. -/ +lemma IsDetpBalanced.submatrix_of_card_le {a b : R} (h : A.IsDetpBalanced a b) + (le : Fintype.card n ≤ Fintype.card m) (f g : m → n) : + (A.submatrix f g).IsDetpBalanced a b := by + by_cases hf : f.Injective; swap + · obtain ⟨p, q, eq, ne⟩ := Function.not_injective_iff.mp hf + exact .of_eq (detp_eq_of_row_eq ne <| by ext; simp [eq]) + by_cases hg : g.Injective; swap + · obtain ⟨p, q, eq, ne⟩ := Function.not_injective_iff.mp hg + exact .of_eq (detp_eq_of_col_eq ne <| by ext; simp [eq]) + let f' := Equiv.ofBijective f <| (Fintype.bijective_iff_injective_and_card _).mpr + ⟨hf, (Fintype.card_le_of_injective f hf).antisymm le⟩ + let g' := Equiv.ofBijective g <| (Fintype.bijective_iff_injective_and_card _).mpr + ⟨hg, (Fintype.card_le_of_injective g hg).antisymm le⟩ + rwa [show f = f' by rfl, show g = g' by rfl, isDetpBalanced_submatrix_equiv_iff] + variable (A) /-- The adjugate matrix, but only the terms of a given sign. -/ diff --git a/docs/references.bib b/docs/references.bib index c72b34d1b8d66a..0864bf21e7930c 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -5771,6 +5771,20 @@ @Book{ talagrand2014 url = {https://doi.org/10.1007/978-3-642-54075-2} } +@Article{ Tan2016, + title = {Free sets and free subsemimodules in a semimodule}, + journal = {Linear Algebra and its Applications}, + volume = {496}, + pages = {527-548}, + year = {2016}, + issn = {0024-3795}, + doi = {https://doi.org/10.1016/j.laa.2016.02.006}, + url = {https://www.sciencedirect.com/science/article/pii/S0024379516000975}, + author = {Yi-Jia Tan}, + keywords = {Semiring, Semimodule, Free set, Free subsemimodule, Rank + of semimodule} +} + @Book{ tao-vu, author = {Tao, Terence and Vu, Van H.}, title = {Additive combinatorics}, From af9aa73bb32239930d95e21a424be73477c6d440 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 28 Jul 2026 13:26:44 +0000 Subject: [PATCH 1048/1300] refactor(RingTheory): use `Submodule.localized'` and kill TODO (#42174) --- Mathlib/RingTheory/Localization/Ideal.lean | 44 +++++++--------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/Mathlib/RingTheory/Localization/Ideal.lean b/Mathlib/RingTheory/Localization/Ideal.lean index bff31f90b3274c..2db80ee49e5b13 100644 --- a/Mathlib/RingTheory/Localization/Ideal.lean +++ b/Mathlib/RingTheory/Localization/Ideal.lean @@ -8,10 +8,10 @@ module public import Mathlib.GroupTheory.MonoidLocalization.Away public import Mathlib.RingTheory.Ideal.IsPrimary public import Mathlib.RingTheory.Ideal.Over -public import Mathlib.RingTheory.Ideal.Quotient.Operations public import Mathlib.RingTheory.Localization.Defs public import Mathlib.RingTheory.Spectrum.Prime.Defs -public import Mathlib.Algebra.Algebra.Tower + +import Mathlib.Algebra.Module.LocalizedModule.Submodule /-! # Ideals in localizations of commutative rings @@ -49,39 +49,21 @@ theorem mk'_mem_iff {x} {y : M} {I : Ideal S} : mk' S x y ∈ I ↔ algebraMap R In practice, this ideal differs only in that the carrier set is defined explicitly. This definition is only meant to be used in proving `mem_map_algebraMap_iff`, and any proof that needs to refer to the explicit carrier set should use that theorem. -/ --- TODO: golf this using `Submodule.localized'` -private def map_ideal (I : Ideal R) : Ideal S where - carrier := { z : S | ∃ x : I × M, z * algebraMap R S x.2 = algebraMap R S x.1 } - zero_mem' := ⟨⟨0, 1⟩, by simp⟩ - add_mem' := by - rintro a b ⟨a', ha⟩ ⟨b', hb⟩ - let Z : { x // x ∈ I } := ⟨(a'.2 : R) * (b'.1 : R) + (b'.2 : R) * (a'.1 : R), - I.add_mem (I.mul_mem_left _ b'.1.2) (I.mul_mem_left _ a'.1.2)⟩ - use ⟨Z, a'.2 * b'.2⟩ - simp only [Z, map_add, Submonoid.coe_mul, map_mul] - rw [add_mul, ← mul_assoc a, ha, mul_comm (algebraMap R S a'.2) (algebraMap R S b'.2), ← - mul_assoc b, hb] - ring - smul_mem' := by - rintro c x ⟨x', hx⟩ - obtain ⟨c', hc⟩ := IsLocalization.surj M c - let Z : { x // x ∈ I } := ⟨c'.1 * x'.1, I.mul_mem_left c'.1 x'.1.2⟩ - use ⟨Z, c'.2 * x'.2⟩ - simp only [Z, ← hx, ← hc, smul_eq_mul, Submonoid.coe_mul, map_mul] - ring +private def map_ideal (I : Ideal R) : Ideal S := + Submodule.localized' S M (Algebra.linearMap R S) I theorem mem_map_algebraMap_iff {I : Ideal R} {z} : z ∈ Ideal.map (algebraMap R S) I ↔ ∃ x : I × M, z * algebraMap R S x.2 = algebraMap R S x.1 := by + rw [← show map_ideal M S I = Ideal.map (algebraMap R S) I by + rw [map_ideal, Ideal.map, Ideal.span, Submodule.localized'_eq_span, Algebra.coe_linearMap], + map_ideal, Submodule.mem_localized'] constructor - · change _ → z ∈ map_ideal M S I - refine fun h => Ideal.mem_sInf.1 h fun z hz => ?_ - obtain ⟨y, hy⟩ := hz - let Z : { x // x ∈ I } := ⟨y, hy.left⟩ - use ⟨Z, 1⟩ - simp [Z, hy.right] - · rintro ⟨⟨a, s⟩, h⟩ - rw [← Ideal.unit_mul_mem_iff_mem _ (map_units S s), mul_comm] - exact h.symm ▸ Ideal.mem_map_of_mem _ a.2 + · rintro ⟨x, hx, s, rfl⟩ + exact ⟨⟨⟨x, hx⟩, s⟩, by rw [← IsLocalization.mk'_eq_mk', IsLocalization.mk'_spec]⟩ + · rintro ⟨⟨⟨x, hx⟩, s⟩, h⟩ + refine ⟨x, hx, s, ?_⟩ + rw [← IsLocalization.mk'_eq_mk', eq_comm, IsLocalization.eq_mk'_iff_mul_eq] + exact h lemma mk'_mem_map_algebraMap_iff (I : Ideal R) (x : R) (s : M) : IsLocalization.mk' S x s ∈ I.map (algebraMap R S) ↔ ∃ s ∈ M, s * x ∈ I := by From 5b1613e1dad7f22558b292d8accde4f7800362f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 28 Jul 2026 13:45:38 +0000 Subject: [PATCH 1049/1300] =?UTF-8?q?chore:=20reduce=20the=20abuse=20of=20?= =?UTF-8?q?the=20defeq=20`Set=20=CE=B1=20:=3D=20=CE=B1=20=E2=86=92=20Prop`?= =?UTF-8?q?=20(#42169)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All these changes fix issues of the form "A function is expecting `Set α` but is given `α → Prop`, or vice-versa". Generated by Claude Opus, then reviewed and cherry-picked line-by-line by myself. Assisted-by: Claude Opus 4.8 --- Archive/Imo/Imo1987Q1.lean | 2 +- Archive/Sensitivity.lean | 10 +++++----- Mathlib/Algebra/DirectSum/Module.lean | 3 +-- Mathlib/Algebra/FreeAlgebra.lean | 2 +- .../Analysis/Calculus/UniformLimitsDeriv.lean | 4 ++-- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 2 +- .../MorphismProperty/Concrete.lean | 7 ++----- .../Presentable/CardinalDirectedPoset.lean | 4 ++-- .../CategoryTheory/Sites/JointlySurjective.lean | 2 +- Mathlib/Data/QPF/Multivariate/Basic.lean | 2 +- Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean | 2 +- Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean | 12 +++++------- Mathlib/MeasureTheory/Measure/Restrict.lean | 5 +++-- Mathlib/MeasureTheory/PiSystem.lean | 7 +++---- Mathlib/ModelTheory/Substructures.lean | 2 +- Mathlib/NumberTheory/Dioph.lean | 4 ++-- .../EisensteinSeries/UniformConvergence.lean | 2 +- Mathlib/NumberTheory/WellApproximable.lean | 2 +- Mathlib/Order/CountableSupClosed.lean | 2 +- Mathlib/Order/Filter/CardinalInter.lean | 3 +-- Mathlib/Order/Filter/Cocardinal.lean | 2 +- Mathlib/Order/Filter/CountableInter.lean | 5 ++--- Mathlib/Order/Filter/ZeroAndBoundedAtFilter.lean | 6 +++--- .../Independence/Kernel/IndepFun.lean | 4 ++-- Mathlib/RingTheory/MvPowerSeries/Restricted.lean | 2 +- .../Multiseries/Corecursion.lean | 5 ++--- .../Compactness/CompactlyCoherentSpace.lean | 2 +- Mathlib/Topology/List.lean | 2 +- MathlibTest/congr.lean | 16 ++++++++-------- 29 files changed, 57 insertions(+), 66 deletions(-) diff --git a/Archive/Imo/Imo1987Q1.lean b/Archive/Imo/Imo1987Q1.lean index 83dfe9fe4d4f0c..d04f11049c12d5 100644 --- a/Archive/Imo/Imo1987Q1.lean +++ b/Archive/Imo/Imo1987Q1.lean @@ -39,7 +39,7 @@ def fixedPointsEquiv : { σx : α × Perm α // σx.2 σx.1 = σx.1 } ≃ Σ x : { σx : α × Perm α // σx.2 σx.1 = σx.1 } ≃ Σ x : α, { σ : Perm α // σ x = x } := setProdEquivSigma _ _ ≃ Σ x : α, { σ : Perm α // ∀ y : ({x} : Set α), σ y = Equiv.refl (↥({x} : Set α)) y } := - (sigmaCongrRight fun x => Equiv.setCongr <| by simp only [SetCoe.forall]; simp) + sigmaCongrRight fun x => Equiv.subtypeEquivRight (by simp) _ ≃ Σ x : α, Perm ({x}ᶜ : Set α) := sigmaCongrRight fun x => by apply Equiv.Set.compl set_option backward.isDefEq.respectTransparency false in diff --git a/Archive/Sensitivity.lean b/Archive/Sensitivity.lean index 6c5dc359e204d0..eb881605a2132f 100644 --- a/Archive/Sensitivity.lean +++ b/Archive/Sensitivity.lean @@ -437,13 +437,13 @@ theorem huang_degree_theorem (H : Set (Q m.succ)) (hH : Card H ≥ 2 ^ m + 1) : (norm_sum_le _ fun p => coeffs y p * _) _ = ∑ p ∈ (coeffs y).support, |coeffs y p| * ite (p ∈ q.adjacent) 1 0 := by simp only [abs_mul, f_matrix] - _ = ∑ p ∈ (coeffs y).support with q.adjacent p, |coeffs y p| := by - simp [sum_filter]; rfl - _ ≤ ∑ p ∈ (coeffs y).support with q.adjacent p, |coeffs y q| := sum_le_sum fun p _ ↦ H_max p - _ = #{p ∈ (coeffs y).support | q.adjacent p} * |coeffs y q| := by + _ = ∑ p ∈ (coeffs y).support with p ∈ q.adjacent, |coeffs y p| := by + simp [sum_filter] + _ ≤ ∑ p ∈ (coeffs y).support with p ∈ q.adjacent, |coeffs y q| := sum_le_sum fun p _ ↦ H_max p + _ = #{p ∈ (coeffs y).support | p ∈ q.adjacent} * |coeffs y q| := by rw [sum_const, nsmul_eq_mul] _ = #((coeffs y).support ∩ q.adjacent.toFinset) * |coeffs y q| := by - congr with x; simp; rfl + congr with x; simp _ ≤ #(H ∩ q.adjacent).toFinset * |ε q y| := by refine (mul_le_mul_iff_left₀ H_q_pos).2 ?_ norm_cast diff --git a/Mathlib/Algebra/DirectSum/Module.lean b/Mathlib/Algebra/DirectSum/Module.lean index 13d425782230c6..c8301a8fadfc4a 100644 --- a/Mathlib/Algebra/DirectSum/Module.lean +++ b/Mathlib/Algebra/DirectSum/Module.lean @@ -137,11 +137,10 @@ theorem linearMap_ext ⦃ψ ψ' : (⨁ i, M i) →ₗ[R] N⦄ (H : ∀ i, ψ.comp (lof R ι M i) = ψ'.comp (lof R ι M i)) : ψ = ψ' := DFinsupp.lhom_ext' H -set_option backward.isDefEq.respectTransparency false in /-- The inclusion of a subset of the direct summands into a larger subset of the direct summands, as a linear map. -/ def lsetToSet (S T : Set ι) (H : S ⊆ T) : (⨁ i : S, M i) →ₗ[R] ⨁ i : T, M i := - toModule R _ _ fun i ↦ lof R T (fun i : Subtype T ↦ M i) ⟨i, H i.prop⟩ + toModule R _ _ fun i ↦ lof R T (fun i : T ↦ M i) ⟨i, H i.prop⟩ variable (ι M) diff --git a/Mathlib/Algebra/FreeAlgebra.lean b/Mathlib/Algebra/FreeAlgebra.lean index e1e915d3040767..125967838c2514 100644 --- a/Mathlib/Algebra/FreeAlgebra.lean +++ b/Mathlib/Algebra/FreeAlgebra.lean @@ -550,7 +550,7 @@ theorem induction {motive : FreeAlgebra R X → Prop} (a : FreeAlgebra R X) : motive a := by -- the arguments are enough to construct a subalgebra, and a mapping into it from X let s : Subalgebra R (FreeAlgebra R X) := - { carrier := motive + { carrier := {x | motive x} mul_mem' := mul _ _ add_mem' := add _ _ algebraMap_mem' := grade0 } diff --git a/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean b/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean index 56d6e1172fca6e..2d9d0d7f90cf23 100644 --- a/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean +++ b/Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean @@ -147,7 +147,7 @@ theorem uniformCauchySeqOnFilter_of_fderiv (hf' : UniformCauchySeqOnFilter f' l -- With a small ball in hand, apply the mean value theorem refine eventually_prod_iff.mpr - ⟨_, b, fun e : E => Metric.ball x r e, + ⟨_, b, (· ∈ Metric.ball x r), eventually_mem_set.mpr (Metric.nhds_basis_ball.mem_of_mem hr), fun {n} hn {y} hy => ?_⟩ simp only [Pi.zero_apply, dist_zero_left, norm_neg_add] at e ⊢ refine lt_of_le_of_lt ?_ (hxyε y hy) @@ -283,7 +283,7 @@ theorem difference_quotients_converge_uniformly obtain ⟨r, hr, hr'⟩ := Metric.nhds_basis_ball.eventually_iff.mp d rw [eventually_prod_iff] refine - ⟨_, b, fun e : E => Metric.ball x r e, + ⟨_, b, (· ∈ Metric.ball x r), eventually_mem_set.mpr (Metric.nhds_basis_ball.mem_of_mem hr), fun {n} hn {y} hy => ?_⟩ simp only [Pi.zero_apply, dist_zero_left] rw [norm_neg_add, ← smul_sub, norm_smul, norm_inv, RCLike.norm_coe_norm] diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index f4d0e0e1968fc5..360c64995326b7 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -511,7 +511,7 @@ theorem norm_eq_zero_iff {f : lp E p} : ‖f‖ = 0 ↔ f = 0 := by rcases p.trichotomy with (rfl | rfl | hp) · ext i have : { i : α | ¬f i = 0 } = ∅ := by simpa [lp.norm_eq_card_dsupport f] using! h - have : (¬f i = 0) = False := congr_fun this i + have : ¬¬f i = 0 := Set.eq_empty_iff_forall_notMem.mp this i tauto · rcases isEmpty_or_nonempty α with _i | _i · simp [eq_iff_true_of_subsingleton] diff --git a/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean b/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean index 1890aabc2c4718..520afd79679c0f 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean @@ -119,11 +119,8 @@ set_option backward.isDefEq.respectTransparency.types false in map followed by an injective map. -/ def functorialSurjectiveInjectiveFactorizationData : FunctorialSurjectiveInjectiveFactorizationData (Type u) where - Z := - { obj := fun f => Subtype (Set.range f.hom.hom) - map := fun φ => ↾fun y => ⟨φ.right y.1, by - obtain ⟨_, x, rfl⟩ := y - exact ⟨φ.left x, congr_hom φ.w x⟩ ⟩ } + Z.obj f := Set.range f.hom.hom + Z.map φ := ↾fun y ↦ ⟨φ.right y.1, by obtain ⟨_, x, rfl⟩ := y; exact ⟨φ.left x, congr_hom φ.w x⟩⟩ i := { app := fun f => ↾fun x => ⟨f.hom x, ⟨x, rfl⟩⟩ naturality := fun f g φ => by diff --git a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean index 4be69fc9b42ae8..c9dc2049367d99 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalDirectedPoset.lean @@ -339,11 +339,11 @@ protected lemma isCardinalPresentable_iff (h : κ ≤ κ') : obtain ⟨X, f, hf⟩ := IsCardinalPresentable.exists_hom_of_isColimit κ' (isColimitCoconeWithTop J κ') (ObjectProperty.homMk (PartOrdEmb.ofHom WithTop.coeOrderHom)) - replace hf : OrderEmbedding.subtype X.1 ∘ f = WithTop.coeOrderHom := by + replace hf : OrderEmbedding.subtype (· ∈ X.1) ∘ f = WithTop.coeOrderHom := by ext x exact ConcreteCategory.congr_hom hf x refine X.2.1.of_injective f (Function.Injective.of_comp - (f := OrderEmbedding.subtype X.1) ?_) + (f := OrderEmbedding.subtype (· ∈ X.1)) ?_) dsimp at hf ⊢ rw [hf] exact WithTop.coe_injective diff --git a/Mathlib/CategoryTheory/Sites/JointlySurjective.lean b/Mathlib/CategoryTheory/Sites/JointlySurjective.lean index 83220bdea62b09..f52f295d7560cb 100644 --- a/Mathlib/CategoryTheory/Sites/JointlySurjective.lean +++ b/Mathlib/CategoryTheory/Sites/JointlySurjective.lean @@ -33,7 +33,7 @@ namespace Types /-- The jointly surjective precoverage in the category of types has the jointly surjective families as coverings. -/ def jointlySurjectivePrecoverage : Precoverage (Type u) where - coverings X R := ∀ x : X, ∃ (Y : Type u) (g : Y ⟶ X), R g ∧ x ∈ Set.range g + coverings X := {R | ∀ x : X, ∃ (Y : Type u) (g : Y ⟶ X), R g ∧ x ∈ Set.range g} lemma mem_jointlySurjectivePrecoverage_iff {X : Type u} {R : Presieve X} : R ∈ jointlySurjectivePrecoverage X ↔ diff --git a/Mathlib/Data/QPF/Multivariate/Basic.lean b/Mathlib/Data/QPF/Multivariate/Basic.lean index db6cc797aaa84f..86de61af0295e2 100644 --- a/Mathlib/Data/QPF/Multivariate/Basic.lean +++ b/Mathlib/Data/QPF/Multivariate/Basic.lean @@ -177,7 +177,7 @@ theorem has_good_supp_iff {α : TypeVec n} (x : F α) : ∃ a f, abs ⟨a, f⟩ = x ∧ ∀ i a' f', abs ⟨a', f'⟩ = x → f i '' univ ⊆ f' i '' univ := by constructor · intro h - have : LiftP (supp x) x := by rw [h]; introv; exact id + have : LiftP (fun i u => u ∈ supp x i) x := by rw [h]; introv; exact id rw [liftP_iff] at this rcases this with ⟨a, f, xeq, h'⟩ refine ⟨a, f, xeq.symm, ?_⟩ diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean index 98fe5755ddda76..ba26f573905ee9 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Basic.lean @@ -204,7 +204,7 @@ theorem induction {C : CliffordAlgebra Q → Prop} (a : CliffordAlgebra Q) : C a := by -- the arguments are enough to construct a subalgebra, and a mapping into it from M let s : Subalgebra R (CliffordAlgebra Q) := - { carrier := C + { carrier := {a | C a} mul_mem' := @mul add_mem' := @add algebraMap_mem' := algebraMap } diff --git a/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean b/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean index 404843b420bb82..bf058b9e05dfda 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean @@ -98,12 +98,10 @@ theorem hasEigenvalue_iff_isRoot : f.HasEigenvalue μ ↔ (minpoly R f).IsRoot variable (f) set_option backward.isDefEq.respectTransparency.types false in -lemma finite_hasEigenvalue : Set.Finite f.HasEigenvalue := by +lemma finite_hasEigenvalue : Set.Finite {μ | f.HasEigenvalue μ} := by have h : minpoly R f ≠ 0 := minpoly.ne_zero (Algebra.IsIntegral.isIntegral (R := R) f) - convert! (minpoly R f).rootSet_finite R - ext μ - change f.HasEigenvalue μ ↔ _ - rw [hasEigenvalue_iff_isRoot, mem_rootSet_of_ne h, IsRoot, coe_aeval_eq_eval] + refine ((minpoly R f).rootSet_finite R).subset ?_ + simp [Set.subset_def, hasEigenvalue_iff_isRoot, mem_rootSet, h] /-- An endomorphism of a finite-dimensional vector space has finitely many eigenvalues. -/ noncomputable instance : Fintype f.Eigenvalues := @@ -142,8 +140,8 @@ set_option backward.isDefEq.respectTransparency.types false in theorem Module.End.finite_spectrum {K : Type v} {V : Type w} [Field K] [AddCommGroup V] [Module K V] [FiniteDimensional K V] (f : Module.End K V) : Set.Finite (spectrum K f) := by - convert! f.finite_hasEigenvalue - ext f x + convert! f.finite_hasEigenvalue using 1 + ext x exact Module.End.hasEigenvalue_iff_mem_spectrum.symm variable {n R : Type*} [Field R] [Fintype n] [DecidableEq n] diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index 0d3653212c0910..1c0d3412b2148b 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -124,11 +124,12 @@ theorem forall_measure_inter_isCountablySpanning_eq_zero {C : Set (Set α)} mpr h t _ := measure_inter_null_of_null_left t h theorem _root_.IsCountablySpanning.null_of_forall_restrict_null {C : Set (Set α)} - (hC : IsCountablySpanning C) (hm : C ⊆ MeasurableSet) (ht : ∀ t ∈ C, μ.restrict t s = 0) : + (hC : IsCountablySpanning C) (hm : ∀ t ∈ C, MeasurableSet t) + (ht : ∀ t ∈ C, μ.restrict t s = 0) : μ s = 0 := by rw [← forall_measure_inter_isCountablySpanning_eq_zero hC] intro t htc - simpa [← μ.restrict_apply' (hm htc)] using ht t htc + simpa [← μ.restrict_apply' (hm _ htc)] using ht t htc theorem restrict_apply₀' (hs : NullMeasurableSet s μ) : μ.restrict s t = μ (t ∩ s) := by rw [← restrict_congr_set hs.toMeasurable_ae_eq, diff --git a/Mathlib/MeasureTheory/PiSystem.lean b/Mathlib/MeasureTheory/PiSystem.lean index 819bd8dbc23dda..74558cbd57bd72 100644 --- a/Mathlib/MeasureTheory/PiSystem.lean +++ b/Mathlib/MeasureTheory/PiSystem.lean @@ -315,12 +315,11 @@ theorem mem_generatePiSystem_iUnion_elim' {α β} {g : β → Set (Set α)} {s : (h_pi : ∀ b ∈ s, IsPiSystem (g b)) (t : Set α) (h_t : t ∈ generatePiSystem (⋃ b ∈ s, g b)) : ∃ (T : Finset β) (f : β → Set α), ↑T ⊆ s ∧ (t = ⋂ b ∈ T, f b) ∧ ∀ b ∈ T, f b ∈ g b := by classical - have : t ∈ generatePiSystem (⋃ b : Subtype s, (g ∘ Subtype.val) b) := by - suffices h1 : ⋃ b : Subtype s, (g ∘ Subtype.val) b = ⋃ b ∈ s, g b by rwa [h1] + have : t ∈ generatePiSystem (⋃ b : s, (g ∘ Subtype.val) b) := by + suffices h1 : ⋃ b : s, (g ∘ Subtype.val) b = ⋃ b ∈ s, g b by rwa [h1] ext x simp only [exists_prop, Set.mem_iUnion, Function.comp_apply, Subtype.exists] - rfl - rcases @mem_generatePiSystem_iUnion_elim α (Subtype s) (g ∘ Subtype.val) + rcases @mem_generatePiSystem_iUnion_elim α s (g ∘ Subtype.val) (fun b => h_pi b.val b.property) t this with ⟨T, ⟨f, ⟨rfl, h_t'⟩⟩⟩ refine diff --git a/Mathlib/ModelTheory/Substructures.lean b/Mathlib/ModelTheory/Substructures.lean index 5894696c33d143..52ed82bf92bcc2 100644 --- a/Mathlib/ModelTheory/Substructures.lean +++ b/Mathlib/ModelTheory/Substructures.lean @@ -246,7 +246,7 @@ theorem notMem_of_notMem_closure {P : M} (hP : P ∉ closure L s) : P ∉ s := f hP (subset_closure h) @[simp] -theorem closed (S : L.Substructure M) : (closure L).closed (S : Set M) := +theorem closed (S : L.Substructure M) : (S : Set M) ∈ (closure L).closed := congr rfl ((closure L).eq_of_le Set.Subset.rfl fun _x xS => mem_closure.2 fun _T hT => hT xS) open Set diff --git a/Mathlib/NumberTheory/Dioph.lean b/Mathlib/NumberTheory/Dioph.lean index 00b5e723a5fbca..2e72abbbf9a0ca 100644 --- a/Mathlib/NumberTheory/Dioph.lean +++ b/Mathlib/NumberTheory/Dioph.lean @@ -394,7 +394,7 @@ theorem proj_dioph (i : α) : DiophFn fun v => v i := abs_poly_dioph (Poly.proj i) theorem diophPFun_comp1 {S : Set (Option α → ℕ)} (d : Dioph S) {f} (df : DiophPFun f) : - Dioph {v : α → ℕ | ∃ h : f.Dom v, f.fn v h ::ₒ v ∈ S} := + Dioph {v : α → ℕ | ∃ h : v ∈ f.Dom, f.fn v h ::ₒ v ∈ S} := ext (ex1_dioph (d.inter df)) fun v => ⟨fun ⟨x, hS, (h : Exists _)⟩ => by rw [show (x ::ₒ v) ∘ some = v from funext fun s => rfl] at h @@ -467,7 +467,7 @@ theorem diophFn_compn : congr! 1 ext x; obtain _ | _ | _ := x <;> rfl have : Dioph {v | (v ⊗ f v::fun i : Fin2 n => fl i v) ∈ S} := - @diophFn_compn n (fun v => (v ∘ inl ⊗ f (v ∘ inl) :: v ∘ inr) ∈ S) this _ dfl + @diophFn_compn n {v | (v ∘ inl ⊗ f (v ∘ inl) :: v ∘ inr) ∈ S} this _ dfl ext this fun v => by dsimp congr! 3 with x diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean index e8ce2ce084d52c..ed7e30c74894cd 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean @@ -45,7 +45,7 @@ theorem eisensteinSeries_tendstoLocallyUniformly {k : ℤ} (hk : 3 ≤ k) {N : (eisensteinSeries a k ·) Filter.atTop := by have hk' : (2 : ℝ) < k := by norm_cast have p_sum : Summable fun x : gammaSet N 1 a ↦ ‖x.val‖ ^ (-k) := - mod_cast (summable_one_div_norm_rpow hk').subtype (gammaSet N 1 a) + mod_cast (summable_one_div_norm_rpow hk').subtype (· ∈ gammaSet N 1 a) simp only [tendstoLocallyUniformly_iff_forall_isCompact, eisensteinSeries] intro K hK obtain ⟨A, B, hB, HABK⟩ := subset_verticalStrip_of_isCompact hK diff --git a/Mathlib/NumberTheory/WellApproximable.lean b/Mathlib/NumberTheory/WellApproximable.lean index bbfa1ce69699db..fcccae7507e9fd 100644 --- a/Mathlib/NumberTheory/WellApproximable.lean +++ b/Mathlib/NumberTheory/WellApproximable.lean @@ -190,7 +190,7 @@ local notation "𝕊" => AddCircle T set_option backward.isDefEq.respectTransparency.types false in /-- **Gallagher's ergodic theorem** on Diophantine approximation. -/ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto δ atTop (𝓝 0)) : - (∀ᵐ x, ¬addWellApproximable 𝕊 δ x) ∨ ∀ᵐ x, addWellApproximable 𝕊 δ x := by + (∀ᵐ x, x ∉ addWellApproximable 𝕊 δ) ∨ ∀ᵐ x, x ∈ addWellApproximable 𝕊 δ := by /- Sketch of proof: Let `E := addWellApproximable 𝕊 δ`. For each prime `p : ℕ`, we can partition `E` into three diff --git a/Mathlib/Order/CountableSupClosed.lean b/Mathlib/Order/CountableSupClosed.lean index 84fe705e22325f..af52f5ee79e99a 100644 --- a/Mathlib/Order/CountableSupClosed.lean +++ b/Mathlib/Order/CountableSupClosed.lean @@ -180,7 +180,7 @@ variable [Preorder α] /-- Every set generates a set closed under countable supremum. -/ @[to_dual /-- Every set generates a set closed under countable infimum. -/] def countableSupClosure : ClosureOperator (Set α) := .ofPred - (fun s a ↦ ∃ (A : Set α) (_ : A ⊆ s) (_ : A.Nonempty) (_ : A.Countable), IsLUB A a) + (fun s ↦ {a | ∃ (A : Set α) (_ : A ⊆ s) (_ : A.Nonempty) (_ : A.Countable), IsLUB A a}) CountableSupClosed (fun s x hxs ↦ ⟨{x}, by simp; grind, by simp, by simp, by simp⟩) (fun s ↦ by diff --git a/Mathlib/Order/Filter/CardinalInter.lean b/Mathlib/Order/Filter/CardinalInter.lean index eb423ae9003c7d..0009d7743423c7 100644 --- a/Mathlib/Order/Filter/CardinalInter.lean +++ b/Mathlib/Order/Filter/CardinalInter.lean @@ -291,8 +291,7 @@ inductive CardinalGenerateSets : Set α → Prop /-- Assuming `2 < c`, `Filter.cardinalGenerate c g` is the greatest `CardinalInterFilter c` containing `g`. -/ def cardinalGenerate (hc : 2 < c) : Filter α := - ofCardinalInter (CardinalGenerateSets g) hc (fun _ => CardinalGenerateSets.sInter) fun _ _ => - CardinalGenerateSets.superset + ofCardinalInter {s | CardinalGenerateSets g s} hc (fun _ => .sInter) fun _ _ => .superset lemma cardinalInter_ofCardinalGenerate (hc : 2 < c) : CardinalInterFilter (cardinalGenerate g hc) c := by diff --git a/Mathlib/Order/Filter/Cocardinal.lean b/Mathlib/Order/Filter/Cocardinal.lean index 8c1efdd22ce138..e4777e9b0b7bde 100644 --- a/Mathlib/Order/Filter/Cocardinal.lean +++ b/Mathlib/Order/Filter/Cocardinal.lean @@ -59,7 +59,7 @@ instance instCardinalInterFilter_cocardinal : CardinalInterFilter (cocardinal ( theorem eventually_cocardinal {p : α → Prop} : (∀ᶠ x in cocardinal α hreg, p x) ↔ #{ x | ¬p x } < c := Iff.rfl -theorem hasBasis_cocardinal : HasBasis (cocardinal α hreg) {s : Set α | #s < c} compl := +theorem hasBasis_cocardinal : HasBasis (cocardinal α hreg) (fun s : Set α ↦ #s < c) compl := ⟨fun s => ⟨fun h => ⟨sᶜ, h, (compl_compl s).subset⟩, fun ⟨_t, htf, hts⟩ => by have : #↑sᶜ < c := by diff --git a/Mathlib/Order/Filter/CountableInter.lean b/Mathlib/Order/Filter/CountableInter.lean index 45629d38f463ee..f516d148951496 100644 --- a/Mathlib/Order/Filter/CountableInter.lean +++ b/Mathlib/Order/Filter/CountableInter.lean @@ -192,7 +192,7 @@ instance countableInter_ofCountableUnion (l : Set (Set α)) (h₁ h₂) : @[simp] theorem mem_ofCountableUnion {l : Set (Set α)} {hunion hmono s} : - s ∈ ofCountableUnion l hunion hmono ↔ l sᶜ := + s ∈ ofCountableUnion l hunion hmono ↔ sᶜ ∈ l := Iff.rfl end Filter @@ -262,8 +262,7 @@ inductive CountableGenerateSets : Set α → Prop set_option backward.isDefEq.respectTransparency false in /-- `Filter.countableGenerate g` is the greatest `countableInterFilter` containing `g`. -/ def countableGenerate : Filter α := - ofCountableInter (CountableGenerateSets g) (fun _ => CountableGenerateSets.sInter) fun _ _ => - CountableGenerateSets.superset + ofCountableInter {s | CountableGenerateSets g s} (fun _ ↦ .sInter) fun _ _ ↦ .superset deriving CountableInterFilter variable {g} diff --git a/Mathlib/Order/Filter/ZeroAndBoundedAtFilter.lean b/Mathlib/Order/Filter/ZeroAndBoundedAtFilter.lean index fa5ab3d3360876..363073675d6e02 100644 --- a/Mathlib/Order/Filter/ZeroAndBoundedAtFilter.lean +++ b/Mathlib/Order/Filter/ZeroAndBoundedAtFilter.lean @@ -57,7 +57,7 @@ def zeroAtFilterSubmodule [TopologicalSpace β] [Semiring 𝕜] [AddCommMonoid β] [Module 𝕜 β] [ContinuousAdd β] [ContinuousConstSMul 𝕜 β] (l : Filter α) : Submodule 𝕜 (α → β) where - carrier := ZeroAtFilter l + carrier := {f | ZeroAtFilter l f} zero_mem' := zero_zeroAtFilter l add_mem' ha hb := ha.add hb smul_mem' c _ hf := hf.smul c @@ -66,7 +66,7 @@ def zeroAtFilterSubmodule which tend to zero along `l`. -/ def zeroAtFilterAddSubmonoid [TopologicalSpace β] [AddZeroClass β] [ContinuousAdd β] (l : Filter α) : AddSubmonoid (α → β) where - carrier := ZeroAtFilter l + carrier := {f | ZeroAtFilter l f} add_mem' ha hb := ha.add hb zero_mem' := zero_zeroAtFilter l @@ -119,7 +119,7 @@ variable (𝕜) in def boundedFilterSubmodule [SeminormedRing 𝕜] [SeminormedAddCommGroup β] [Module 𝕜 β] [IsBoundedSMul 𝕜 β] (l : Filter α) : Submodule 𝕜 (α → β) where - carrier := BoundedAtFilter l + carrier := {f | BoundedAtFilter l f} zero_mem' := const_boundedAtFilter l 0 add_mem' hf hg := hf.add hg smul_mem' c _ hf := hf.smul c diff --git a/Mathlib/Probability/Independence/Kernel/IndepFun.lean b/Mathlib/Probability/Independence/Kernel/IndepFun.lean index d8fe6035c66539..42b36162d5e834 100644 --- a/Mathlib/Probability/Independence/Kernel/IndepFun.lean +++ b/Mathlib/Probability/Independence/Kernel/IndepFun.lean @@ -234,8 +234,8 @@ theorem IndepFun.congr' {mβ : MeasurableSpace β} {mβ' : MeasurableSpace β'} IndepFun f' g' κ μ := by rintro _ _ ⟨A, hA, rfl⟩ ⟨B, hB, rfl⟩ filter_upwards [hf, hg, hfg _ _ ⟨_, hA, rfl⟩ ⟨_, hB, rfl⟩] with a hf' hg' hfg' - have h1 : f ⁻¹' A =ᵐ[κ a] f' ⁻¹' A := hf'.fun_comp A - have h2 : g ⁻¹' B =ᵐ[κ a] g' ⁻¹' B := hg'.fun_comp B + have h1 : f ⁻¹' A =ᵐ[κ a] f' ⁻¹' A := hf'.fun_comp (· ∈ A) + have h2 : g ⁻¹' B =ᵐ[κ a] g' ⁻¹' B := hg'.fun_comp (· ∈ B) rwa [← measure_congr h1, ← measure_congr h2, ← measure_congr (h1.inter h2)] theorem IndepFun.comp {mβ : MeasurableSpace β} {mβ' : MeasurableSpace β'} diff --git a/Mathlib/RingTheory/MvPowerSeries/Restricted.lean b/Mathlib/RingTheory/MvPowerSeries/Restricted.lean index 72d90d9acdcb90..55fd208e1867e5 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Restricted.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Restricted.lean @@ -96,7 +96,7 @@ namespace IsRestricted /-- Restricted power series as an additive subgroup of `MvPowerSeries σ R`. -/ protected def addSubgroup (c : σ → ℝ) : AddSubgroup (MvPowerSeries σ R) where - carrier := IsRestricted c + carrier := {f | IsRestricted c f} zero_mem' := isRestricted_zero c add_mem' := isRestricted.add c neg_mem' := isRestricted.neg c diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean index 373a33001da998..73090a8af4ba6d 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean @@ -85,9 +85,8 @@ local instance : CompleteSpace (Stream' α) := set_option backward.isDefEq.respectTransparency false in local instance : CompleteSpace (Seq α) := by - suffices IsClosed (X := Stream' (Option α)) - (fun x ↦ ∀ {n : ℕ}, x n = none → x (n + 1) = none) by - apply IsClosed.completeSpace_coe + suffices IsClosed (X := Stream' (Option α)) {x | ∀ {n : ℕ}, x n = none → x (n + 1) = none} by + exact this.completeSpace_coe rw [isClosed_iff_clusterPt] intro s hs n hn rw [clusterPt_principal_iff] at hs diff --git a/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean b/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean index 0c2ee518a18fcc..47a4ad332bdbd4 100644 --- a/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean +++ b/Mathlib/Topology/Compactness/CompactlyCoherentSpace.lean @@ -146,7 +146,7 @@ variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] instance instTopologicalSpace : TopologicalSpace (𝐤X) := .coinduced (.mk X) - (⨆ (K : Set X) (_ : IsCompact K), .coinduced (Subtype.val (p := K)) + (⨆ (K : Set X) (_ : IsCompact K), .coinduced (Subtype.val (p := (· ∈ K))) (inferInstanceAs <| TopologicalSpace K)) /-- A set `A` in the compact coherentification is open iff for all compact sets `K`, diff --git a/Mathlib/Topology/List.lean b/Mathlib/Topology/List.lean index 706123c7bd2038..d5c8e09a708c56 100644 --- a/Mathlib/Topology/List.lean +++ b/Mathlib/Topology/List.lean @@ -53,7 +53,7 @@ theorem nhds_list (as : List α) : 𝓝 as = traverse 𝓝 as := by ⟨u::v, List.Forall₂.cons hu hv, Subset.trans (Set.seq_mono (Set.image_mono hut) hvss) hus⟩ rcases this with ⟨v, hv, hvs⟩ - have : ∀ᶠ y in traverse 𝓝 l, sequence v y := + have : ∀ᶠ y in traverse 𝓝 l, y ∈ sequence v := mem_traverse _ _ <| hv.imp fun a s ⟨hs, ha⟩ => IsOpen.mem_nhds hs ha refine Eventually.mono this fun u hu ↦ ?_ have hu := (List.mem_traverse _ _).1 hu diff --git a/MathlibTest/congr.lean b/MathlibTest/congr.lean index b64a91a55b125a..56b39d9a0b5427 100644 --- a/MathlibTest/congr.lean +++ b/MathlibTest/congr.lean @@ -74,19 +74,19 @@ theorem ex15 (p q : Nat → Prop) : set_option backward.isDefEq.respectTransparency false in /- Generating type equalities is OK if it's possible they're the same type. -/ -example (s t : Set α) : (ℕ × Subtype s) = (ℕ × Subtype t) := by +example {α : Type*} (p q : α → Prop) : (ℕ × Subtype p) = (ℕ × Subtype q) := by congr! 1 - guard_target = Subtype s = Subtype t + guard_target = Subtype p = Subtype q congr! 1 - guard_target = s = t + guard_target = p = q exact test_sorry set_option backward.isDefEq.respectTransparency false in -/- `Subtype s = Subtype t` is plausible -/ -example (s t : Set α) (f : Subtype s → α) (g : Subtype t → α) : +/- `Subtype p = Subtype q` is plausible -/ +example (p q : α → Prop) (f : Subtype p → α) (g : Subtype q → α) : Set.image f Set.univ = Set.image g Set.univ := by congr! - · guard_target = s = t + · guard_target = p = q exact test_sorry · guard_target = f ≍ g exact test_sorry @@ -108,9 +108,9 @@ example {ι κ : Type u} (f : ι → α) (g : κ → α) : exact test_sorry /- Generating type equalities is not OK if they're not likely to be the same type. -/ -example (s : Set α) (t : Set β) : (ℕ × Subtype s) = (ℕ × Subtype t) := by +example {α β : Type u} (p : α → Prop) (q : β → Prop) : (ℕ × Subtype p) = (ℕ × Subtype q) := by congr! - guard_target = Subtype s = Subtype t + guard_target = Subtype p = Subtype q exact test_sorry /- Congruence here is OK since `Fin m = Fin n` is plausible to prove. -/ From c9a84caef3d682b3e8403b5555e1c90eaa06c400 Mon Sep 17 00:00:00 2001 From: Nailin Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Tue, 28 Jul 2026 14:29:39 +0000 Subject: [PATCH 1050/1300] feat(Algebra): `Hom` commute with flat base change (#31222) In this PR, we proved `Hom_S (M \tensor S, N \tensor S)` is base change of `Hom_R (M, N)` with respect to `LinearMap.baseChangeHom`. Co-authored-by: Wang Jingting Co-authored-by: Johan Commelin --- .../Algebra/Module/FinitePresentation.lean | 55 +++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Module/FinitePresentation.lean b/Mathlib/Algebra/Module/FinitePresentation.lean index 375402f1d9763b..f706ac8c5364aa 100644 --- a/Mathlib/Algebra/Module/FinitePresentation.lean +++ b/Mathlib/Algebra/Module/FinitePresentation.lean @@ -5,13 +5,11 @@ Authors: Andrew Yang -/ module -public import Mathlib.LinearAlgebra.FreeModule.Finite.Basic -public import Mathlib.LinearAlgebra.Isomorphisms -public import Mathlib.LinearAlgebra.TensorProduct.RightExactness +public import Mathlib.LinearAlgebra.LeftExact +public import Mathlib.LinearAlgebra.TensorProduct.Pi public import Mathlib.RingTheory.Finiteness.Projective +public import Mathlib.RingTheory.Flat.IsBaseChange public import Mathlib.RingTheory.Localization.BaseChange -public import Mathlib.RingTheory.Noetherian.Basic -public import Mathlib.RingTheory.TensorProduct.Finite /-! @@ -92,6 +90,16 @@ theorem Module.FinitePresentation.exists_fin [fp : Module.FinitePresentation R M · simpa [range_linearCombination] using hι₁ · simpa [LinearMap.ker_comp, Submodule.comap_equiv_eq_map_symm] using hι₂.map _ +/-- An alternative version of `Module.FinitePresentation.exists_fin` that provides a right exact +sequence. -/ +theorem Module.FinitePresentation.exists_fin' [fp : Module.FinitePresentation R M] : + ∃ (n m : ℕ) (f : (Fin n → R) →ₗ[R] M) (g : (Fin m → R) →ₗ[R] (Fin n → R)), + Function.Surjective f ∧ Function.Exact g f := by + obtain ⟨n, K, e, h⟩ := exists_fin R M + obtain ⟨m, g', hg'⟩ := K.fg_iff_exists_fin_linearMap.mp h + exact ⟨n, m, e.symm ∘ₗ K.mkQ, g', by simpa using K.mkQ_surjective, + e.symm.injective.comp_exact_iff_exact.mpr (by simp [LinearMap.exact_iff, hg'])⟩ + /-- A finitely presented module is isomorphic to the quotient of a finite free module by a finitely generated submodule. -/ theorem Module.FinitePresentation.equiv_quotient [Module.FinitePresentation R M] [Small.{v} R] : @@ -666,4 +674,41 @@ lemma Module.FinitePresentation.linearEquivMapExtendScalars_symm_apply (LocalizedModule.mkLinearMap S (M →ₗ[R] N)) f := IsLocalizedModule.linearEquiv_symm_apply S _ _ f +open TensorProduct LinearMap + +variable (N) in +lemma Module.isBaseChange_map_of_finite_free (S ι : Type*) [Finite ι] [CommRing S] [Algebra R S] : + IsBaseChange S (LinearMap.baseChangeHom R S (ι → R) N) := by + classical + have : Fintype ι := Fintype.ofFinite ι + let e₁ := TensorProduct.piRight R S S (fun _ : ι ↦ R) + let e₂ := (LinearEquiv.piCongrRight (fun _ ↦ (LinearMap.ringLmapEquivSelf S S _).symm ≪≫ₗ + (LinearEquiv.congrLeft (S ⊗[R] N) S (AlgebraTensorModule.rid R S S).symm))) ≪≫ₗ + (LinearMap.lsum S (fun _ : ι ↦ _) S) ≪≫ₗ (e₁.symm.congrLeft (S ⊗[R] N) S) + let e₃ := (LinearMap.lsum R (fun _ : ι ↦ R) R).symm ≪≫ₗ + LinearEquiv.piCongrRight (fun _ ↦ LinearMap.ringLmapEquivSelf R R N) + refine IsBaseChange.of_equiv ((e₃.baseChange R S) ≪≫ₗ (TensorProduct.piRight R S S _) ≪≫ₗ e₂) + (fun f ↦ TensorProduct.AlgebraTensorModule.curry_injective (LinearMap.ext fun s ↦ ?_)) + ext i + simpa [e₃, e₂, e₁] using (tmul_eq_smul_one_tmul s (f (Pi.single i 1))).symm + +variable (R M N) in +theorem Module.FinitePresentation.isBaseChange_map (S : Type*) [CommRing S] [Algebra R S] + [Module.Flat R S] [Module.FinitePresentation R M] : + IsBaseChange S (LinearMap.baseChangeHom R S M N) := by + obtain ⟨n, m, f, g, hf, hfg⟩ := Module.FinitePresentation.exists_fin' R M + refine IsBaseChange.of_left_exact S (f' := (f.baseChange S).lcomp S (S ⊗[R] N)) + (g' := (g.baseChange S).lcomp S (S ⊗[R] N)) _ _ _ ?_ ?_ + (Module.isBaseChange_map_of_finite_free N S _) (Module.isBaseChange_map_of_finite_free N S _) + (exact_lcomp_of_exact_of_surjective _ hfg hf) (lcomp_injective_of_surjective f hf) ?_ ?_ + · exact LinearMap.ext fun φ ↦ TensorProduct.AlgebraTensorModule.curry_injective + (LinearMap.ext fun s ↦ (LinearMap.ext fun m ↦ (by simp))) + · exact LinearMap.ext fun φ ↦ TensorProduct.AlgebraTensorModule.curry_injective + (LinearMap.ext fun s ↦ (LinearMap.ext fun m ↦ (by simp))) + · apply exact_lcomp_of_exact_of_surjective + · exact lTensor_exact S hfg hf + · exact LinearMap.lTensor_surjective S hf + · apply lcomp_injective_of_surjective + exact LinearMap.lTensor_surjective S hf + end CommRing From e011717410c13033a6fe4bebafe078835d9d3b30 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck <56166236+CBirkbeck@users.noreply.github.com> Date: Tue, 28 Jul 2026 14:29:42 +0000 Subject: [PATCH 1051/1300] feat(RingTheory/MvPolynomial/WeightedHomogeneous): sub, eq_zero_of_no_monomials, eq_monomial_of_unique_weight (#38909) API on MvPolynomials split off from the level-1 modular forms graded ring project (#38813) to keep that PR reviewable. Co-Authored-By: Claude Fable 5 --- Mathlib/Algebra/MvPolynomial/Basic.lean | 10 ++++++ Mathlib/Algebra/MvPolynomial/Coeff.lean | 5 +++ Mathlib/Algebra/MvPolynomial/CommRing.lean | 31 +++++++++++++++++++ .../Order/BigOperators/Group/Finset.lean | 30 ++++++++++++++++++ Mathlib/Data/Finsupp/Weight.lean | 3 ++ .../MvPolynomial/WeightedHomogeneous.lean | 30 ++++++++++++++++++ 6 files changed, 109 insertions(+) diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 995bcd5ebce741..57a2fdbe1d1080 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -590,6 +590,16 @@ theorem coeff_monomial [DecidableEq σ] (m n) (a) : coeff m (monomial n a : MvPolynomial σ R) = if n = m then a else 0 := Finsupp.single_apply +/-- A polynomial all of whose support degrees equal a fixed `d₀` is the single monomial +`monomial d₀ (coeff d₀ φ)`. -/ +theorem eq_monomial_of_support_subset_singleton {φ : MvPolynomial σ R} {d₀ : σ →₀ ℕ} + (h : ∀ d ∈ φ.support, d = d₀) : φ = monomial d₀ (coeff d₀ φ) := by + classical + ext d + rcases eq_or_ne d d₀ with rfl | hd + · rw [coeff_monomial, if_pos rfl] + · rw [notMem_support_iff.mp fun hmem ↦ hd (h d hmem), coeff_monomial, if_neg fun e ↦ hd e.symm] + @[simp] theorem coeff_C [DecidableEq σ] (m) (a) : coeff m (C a : MvPolynomial σ R) = if 0 = m then a else 0 := diff --git a/Mathlib/Algebra/MvPolynomial/Coeff.lean b/Mathlib/Algebra/MvPolynomial/Coeff.lean index b2be27a1ccab0b..9e9048fef94724 100644 --- a/Mathlib/Algebra/MvPolynomial/Coeff.lean +++ b/Mathlib/Algebra/MvPolynomial/Coeff.lean @@ -110,4 +110,9 @@ theorem coeff_add_pow (d : Fin 2 →₀ ℕ) (n : ℕ) : Nat.binomial_eq_choose Fin.zero_ne_one, hd] · rfl +/-- A monomial in two variables equals `C a * X 0 ^ d 0 * X 1 ^ d 1`. -/ +theorem monomial_fin_two (d : Fin 2 →₀ ℕ) (a : R) : + monomial d a = C a * X 0 ^ d 0 * X 1 ^ d 1 := by + rw [monomial_eq, mul_assoc, d.prod_fintype _ fun _ ↦ pow_zero _, Fin.prod_univ_two] + end MvPolynomial diff --git a/Mathlib/Algebra/MvPolynomial/CommRing.lean b/Mathlib/Algebra/MvPolynomial/CommRing.lean index 269611dec10106..fcdaade15b39df 100644 --- a/Mathlib/Algebra/MvPolynomial/CommRing.lean +++ b/Mathlib/Algebra/MvPolynomial/CommRing.lean @@ -80,6 +80,37 @@ theorem support_sub [DecidableEq σ] (p q : MvPolynomial σ R) : variable {σ} (p) +/-- Subtracting `monomial d c - monomial d' c` from `p`, where `c = coeff d p` and `d ≠ d'`, +removes `d` from the support. -/ +theorem notMem_support_sub_monomial_sub_monomial (d d' : σ →₀ ℕ) (c : R) + (hdd' : d ≠ d') (hc : coeff d p = c) : + d ∉ (p - (monomial d c - monomial d' c)).support := by + classical + rw [notMem_support_iff, coeff_sub, coeff_sub, coeff_monomial, coeff_monomial, + if_pos rfl, if_neg hdd'.symm, sub_zero, hc, sub_self] + +/-- Subtracting `monomial d c - monomial d' c` from `p`, where `c = coeff d p` and `d ≠ d'`, +leaves the support inside `p.support.erase d ∪ {d'}`. -/ +theorem support_sub_monomial_sub_monomial_subset [DecidableEq σ] (d d' : σ →₀ ℕ) (c : R) + (hdd' : d ≠ d') (hc : coeff d p = c) : + (p - (monomial d c - monomial d' c)).support ⊆ p.support.erase d ∪ {d'} := by + classical + intro x hx + have hd_not := notMem_support_sub_monomial_sub_monomial p d d' c hdd' hc + rcases Finset.mem_union.mp (support_sub σ p _ hx) with hp | hdelta + · by_cases hxd : x = d + · exact absurd (hxd ▸ hx) hd_not + exact Finset.mem_union_left _ (Finset.mem_erase.mpr ⟨hxd, hp⟩) + rcases Finset.mem_union.mp (support_sub σ _ _ hdelta) with h1 | h2 + · rw [support_monomial] at h1 + split_ifs at h1 + · exact absurd h1 (Finset.notMem_empty _) + exact absurd ((Finset.mem_singleton.mp h1) ▸ hx) hd_not + rw [support_monomial] at h2 + split_ifs at h2 + · exact absurd h2 (Finset.notMem_empty _) + exact Finset.mem_union_right _ (by rwa [Finset.mem_singleton] at h2 ⊢) + section Degrees @[simp] diff --git a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean index b716bb73a6d7bd..3745e5cb7ff4b1 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean @@ -472,6 +472,36 @@ lemma one_lt_prod_iff {ι M : Type*} [CommMonoid M] [PartialOrder M] [Canonicall have := CanonicallyOrderedMul.toIsOrderedMonoid (α := M) Finset.one_lt_prod_iff_of_one_le <| fun _ _ => one_le +/-- In a canonically-ordered monoid, if `S'` is contained in `(S.erase d) ∪ {d'}` and +`f d' < f d` for some `d ∈ S`, then the product of `f` over `S'` is strictly less than over `S`. -/ +@[to_additive /-- In a canonically-ordered additive monoid, if `S'` is contained in +`(S.erase d) ∪ {d'}` and `f d' < f d` for some `d ∈ S`, then the sum of `f` over `S'` is +strictly less than over `S`. -/] +lemma prod_lt_prod_of_subset_erase_union_singleton {ι M : Type*} [DecidableEq ι] [CommMonoid M] + [PartialOrder M] [CanonicallyOrderedMul M] [MulLeftStrictMono M] {S S' : Finset ι} {f : ι → M} + {d d' : ι} (hd_mem : d ∈ S) (hS' : S' ⊆ S.erase d ∪ {d'}) (hlt : f d' < f d) : + ∏ x ∈ S', f x < ∏ x ∈ S, f x := by + have hd_not : d ∉ S' := fun hd ↦ (Finset.mem_union.mp (hS' hd)).elim + (fun h ↦ (Finset.mem_erase.mp h).1 rfl) + (fun h ↦ hlt.ne' (congrArg f (Finset.mem_singleton.mp h))) + by_cases hd'S : d' ∈ S + · calc ∏ x ∈ S', f x + ≤ ∏ x ∈ S.erase d, f x := Finset.prod_le_prod_of_subset' (fun x hx ↦ + Finset.mem_erase.mpr ⟨fun h ↦ hd_not (h ▸ hx), + match Finset.mem_union.mp (hS' hx) with + | .inl h => Finset.mem_of_mem_erase h + | .inr h => Finset.mem_singleton.mp h ▸ hd'S⟩) + _ < (∏ x ∈ S.erase d, f x) * f d := + lt_mul_of_one_lt_right' _ (one_le.trans_lt hlt) + _ = ∏ x ∈ S, f x := Finset.prod_erase_mul S f hd_mem + · calc ∏ x ∈ S', f x + ≤ ∏ x ∈ S.erase d ∪ {d'}, f x := Finset.prod_le_prod_of_subset' hS' + _ = (∏ x ∈ S.erase d, f x) * f d' := by + rw [Finset.prod_union (Finset.disjoint_singleton_right.mpr + (fun h ↦ hd'S (Finset.mem_of_mem_erase h))), Finset.prod_singleton] + _ < (∏ x ∈ S.erase d, f x) * f d := mul_lt_mul_right hlt _ + _ = ∏ x ∈ S, f x := Finset.prod_erase_mul S f hd_mem + end CanonicallyOrderedMul section OrderedCancelCommMonoid diff --git a/Mathlib/Data/Finsupp/Weight.lean b/Mathlib/Data/Finsupp/Weight.lean index 5d35b796e8ce5b..405331b461fda7 100644 --- a/Mathlib/Data/Finsupp/Weight.lean +++ b/Mathlib/Data/Finsupp/Weight.lean @@ -97,6 +97,9 @@ theorem weight_single (s : σ) (r : R) : weight w (Finsupp.single s r) = r • w s := Finsupp.linearCombination_single _ _ _ +theorem weight_eq_sum [Fintype σ] (f : σ →₀ R) : weight w f = ∑ i, f i • w i := by + rw [weight_apply, f.sum_fintype (fun i c ↦ c • w i) fun _ ↦ zero_smul _ _] + variable (R) in /-- A weight function is nontorsion if its values are not torsion. -/ class NonTorsionWeight (w : σ → M) : Prop where diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index b76f313a3f73a3..57b18a0573ea7e 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -258,6 +258,36 @@ theorem add {w : σ → M} (hφ : IsWeightedHomogeneous w φ n) (hψ : IsWeighte IsWeightedHomogeneous w (φ + ψ) n := (weightedHomogeneousSubmodule R w n).add_mem hφ hψ +section CommRing + +-- In this section we shadow the semiring `R` with a ring `R`. +variable {R : Type*} [CommRing R] {w : σ → M} {φ ψ : MvPolynomial σ R} + +/-- The negation of a weighted homogeneous polynomial of degree `n` is weighted homogeneous + of weighted degree `n`. -/ +theorem neg (hφ : IsWeightedHomogeneous w φ n) : IsWeightedHomogeneous w (-φ) n := + (weightedHomogeneousSubmodule R w n).neg_mem hφ + +/-- The difference of two weighted homogeneous polynomials of degree `n` is weighted homogeneous + of weighted degree `n`. -/ +theorem sub (hφ : IsWeightedHomogeneous w φ n) (hψ : IsWeightedHomogeneous w ψ n) : + IsWeightedHomogeneous w (φ - ψ) n := + (weightedHomogeneousSubmodule R w n).sub_mem hφ hψ + +end CommRing + +/-- A weighted homogeneous polynomial of degree `n` is zero if no monomial has weight `n`. -/ +theorem eq_zero_of_no_monomials {w : σ → M} (hφ : IsWeightedHomogeneous w φ n) + (hno : ∀ d : σ →₀ ℕ, weight w d ≠ n) : φ = 0 := + support_eq_empty.mp <| Finset.eq_empty_of_forall_notMem + fun _ hd ↦ hno _ (hφ (mem_support_iff.mp hd)) + +/-- A weighted homogeneous polynomial of degree `n` whose support degrees are all equal to a +fixed `d₀` is a single monomial. -/ +theorem eq_monomial_of_unique_weight {w : σ → M} {d₀ : σ →₀ ℕ} (hφ : IsWeightedHomogeneous w φ n) + (huniq : ∀ d, weight w d = n → d = d₀) : φ = monomial d₀ (coeff d₀ φ) := + eq_monomial_of_support_subset_singleton fun d hd ↦ huniq d (hφ (mem_support_iff.mp hd)) + /-- The sum of weighted homogeneous polynomials of degree `n` is weighted homogeneous of weighted degree `n`. -/ theorem sum {ι : Type*} (s : Finset ι) (φ : ι → MvPolynomial σ R) (n : M) {w : σ → M} From 9d302fc708aa85d820df824fccefbb90d9b3e567 Mon Sep 17 00:00:00 2001 From: Alain Chavarri <109701917+alainchmt@users.noreply.github.com> Date: Tue, 28 Jul 2026 14:29:44 +0000 Subject: [PATCH 1052/1300] feat(FieldTheory/Finite): irreducible polynomial divides X^q^n - X iff degree divides n (#39239) Co-authored-by: Oliver Nash --- Mathlib/FieldTheory/Finite/Extension.lean | 48 +++++++++++++++++------ Mathlib/FieldTheory/Minpoly/Field.lean | 8 ++++ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/Mathlib/FieldTheory/Finite/Extension.lean b/Mathlib/FieldTheory/Finite/Extension.lean index 328fc12eeb24f6..ab81c1beb9c2df 100644 --- a/Mathlib/FieldTheory/Finite/Extension.lean +++ b/Mathlib/FieldTheory/Finite/Extension.lean @@ -152,27 +152,49 @@ theorem exists_forall_apply_eq_pow (l : Type*) [Field l] [Algebra k l] [Finite l end FiniteField -section Polynomial +namespace Irreducible -open FiniteField Polynomial +open FiniteField -variable {K : Type*} [Field K] +variable {k} +variable {f : k[X]} (hi : Irreducible f) +include hi -theorem Irreducible.natDegree_dvd_of_dvd_X_pow_card_pow_sub_X {n : ℕ} {f : K[X]} - (hi : Irreducible f) (h : f ∣ X ^ (Nat.card K) ^ n - X) : f.natDegree ∣ n := by +omit [Finite k] in -- Junk for `Nat.card` allows us to omit the finiteness assumption here. +theorem natDegree_dvd_of_dvd_X_pow_card_pow_sub_X {n : ℕ} (h : f ∣ X ^ (Nat.card k) ^ n - X) : + f.natDegree ∣ n := by rcases eq_or_ne n 0 with rfl | hn · simp - cases finite_or_infinite K; swap + cases finite_or_infinite k; swap · rw [Nat.card_eq_zero_of_infinite, zero_pow hn, pow_zero, ← dvd_neg, neg_sub] at h rw [((Splits.X_sub_C 1).of_dvd (X_sub_C_ne_zero 1) h).natDegree_eq_one_of_irreducible hi] exact one_dvd n - let ⟨p, hp⟩ := CharP.exists K - have : Fact (Nat.Prime p) := ⟨CharP.char_is_prime K p⟩ + let ⟨p, hp⟩ := CharP.exists k + have : Fact (Nat.Prime p) := ⟨CharP.char_is_prime k p⟩ have : NeZero n := ⟨hn⟩ - rw [← finrank_extension K p n] + rw [← finrank_extension k p n] apply Irreducible.natDegree_dvd_finrank hi - refine Splits.of_dvd ?_ ?_ (map_dvd (algebraMap K (Extension K p n)) h) + refine Splits.of_dvd ?_ ?_ (map_dvd (algebraMap _ (Extension _ p n)) h) · apply IsSplittingField.splits - · exact map_ne_zero (X_pow_card_pow_sub_X_ne_zero K hn Finite.one_lt_card) - -end Polynomial + · exact map_ne_zero (X_pow_card_pow_sub_X_ne_zero _ hn Finite.one_lt_card) + +theorem natDegree_dvd_iff_dvd_X_pow_card_pow_sub_X {n : ℕ} : + f.natDegree ∣ n ↔ f ∣ X ^ (Nat.card k) ^ n - X := by + refine ⟨fun hdvd ↦ dvd_trans ?_ (dvd_pow_pow_sub_self_of_dvd hdvd), + hi.natDegree_dvd_of_dvd_X_pow_card_pow_sub_X⟩ + let a := AdjoinRoot.root f + have : NeZero f.natDegree := NeZero.of_pos (Irreducible.natDegree_pos hi) + have : Fact <| Irreducible f := ⟨hi⟩ + rw [← hi.dvd_iff_aeval_eq_zero (b := a) (by aesop)] + let ⟨p, hp⟩ := CharP.exists k + have : Fact (Nat.Prime p) := ⟨CharP.char_is_prime k p⟩ + let e := FiniteField.algEquivExtension k p f.natDegree (AdjoinRoot f) + (finrank_quotient_span_eq_natDegree (f := f)) + have hpeval : (e a) ^ (Nat.card k) ^ f.natDegree - (e a) = 0 := by + have := Fintype.ofFinite (Extension k p f.natDegree) + rw [← (natCard_extension k p f.natDegree), ← Fintype.card_eq_nat_card, + pow_card (e a), sub_self] + apply_fun e.symm at hpeval + simpa using hpeval + +end Irreducible diff --git a/Mathlib/FieldTheory/Minpoly/Field.lean b/Mathlib/FieldTheory/Minpoly/Field.lean index da148a2c393d57..fe6101bdb4fe87 100644 --- a/Mathlib/FieldTheory/Minpoly/Field.lean +++ b/Mathlib/FieldTheory/Minpoly/Field.lean @@ -163,6 +163,14 @@ theorem Irreducible.eq_minpoly [Nontrivial B] {p : A[X]} (hi : Irreducible p) rw [← minpoly.eq_of_irreducible hi hx, mul_comm, mul_assoc, ← C_mul, inv_mul_cancel₀ (leadingCoeff_ne_zero.mpr hi.ne_zero), C_1, mul_one] +theorem _root_.Irreducible.dvd_iff_aeval_eq_zero [Nontrivial B] {p q : A[X]} (hi : Irreducible p) + {b : B} (hfa : p.aeval b = 0) : q.aeval b = 0 ↔ p ∣ q := by + refine ⟨fun hga ↦ dvd_trans ?_ (minpoly.dvd A b hga), ?_⟩ + · rw [← minpoly.eq_of_irreducible hi hfa] + exact dvd_mul_right _ _ + · rintro ⟨g, rfl⟩ + simp [hfa] + theorem add_algebraMap {B : Type*} [CommRing B] [Algebra A B] (x : B) (a : A) : minpoly A (x + algebraMap A B a) = (minpoly A x).comp (X - C a) := by by_cases hx : IsIntegral A x From 06b6563c29f7cdb3d910b1703a6deaca0c634fd6 Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Tue, 28 Jul 2026 15:02:36 +0000 Subject: [PATCH 1053/1300] feat: add assume tactic (#39026) Teaching tactic: `assume p` is short for `intro (_ : p)`. Co-authored-by: Jon Eugster --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + Mathlib/Tactic/Assume.lean | 50 ++++++++++++++++++++++++++ MathlibTest/Assume.lean | 73 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 Mathlib/Tactic/Assume.lean create mode 100644 MathlibTest/Assume.lean diff --git a/Mathlib.lean b/Mathlib.lean index 29db19960dc526..334165ab555e39 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7240,6 +7240,7 @@ public import Mathlib.Tactic.ApplyFun public import Mathlib.Tactic.ApplyWith public import Mathlib.Tactic.ArithMult public import Mathlib.Tactic.ArithMult.Init +public import Mathlib.Tactic.Assume public import Mathlib.Tactic.Attr.Core public import Mathlib.Tactic.Attr.Register public import Mathlib.Tactic.BDSimp diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 8cdb1fb50331d3..2b01d7d338d08e 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -12,6 +12,7 @@ public import Mathlib.Tactic.ApplyFun public import Mathlib.Tactic.ApplyWith public import Mathlib.Tactic.ArithMult public import Mathlib.Tactic.ArithMult.Init +public import Mathlib.Tactic.Assume public import Mathlib.Tactic.Attr.Core public import Mathlib.Tactic.Attr.Register public import Mathlib.Tactic.BDSimp diff --git a/Mathlib/Tactic/Assume.lean b/Mathlib/Tactic/Assume.lean new file mode 100644 index 00000000000000..bd95ba50c30d85 --- /dev/null +++ b/Mathlib/Tactic/Assume.lean @@ -0,0 +1,50 @@ +/- +Copyright (c) 2026 Floris van Doorn. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Floris van Doorn +-/ +module + +public import Lean.Elab.Tactic.ElabTerm +public import Mathlib.Init + +/-! +# The `assume` tactic +-/ + +/-- `assume e` introduces a new (unnamed) hypothesis of type `e`. +It is equivalent to `intro (_ : e)`. + +The argument `e` is required to be a proposition, definitionally equal to the hypothesis +(or domain of a dependent function) in the goal. The introduced hypothesis will have +the exact form the user wrote. + +Example: + +```lean +example {α} (f : α → α) (h : Function.Injective f) : ∀ x y, f x = f y → x = y := by + intro x y + assume f x = f y + apply h + assumption +``` +-/ +syntax (name := assume) &"assume " (ppSpace colGt term)? : tactic + +open Lean Meta Elab Tactic +elab_rules : tactic + | `(tactic| assume $[$t?:term]?) => do + let some t := t? + | throwError "Tactic 'assume' failed: No hypotheses given." + withMainContext do + let e ← elabTerm t (some (.sort .zero)) + let eType ← inferType e + let .true ← isDefEq eType (.sort .zero) | + throwErrorAt t "Tactic 'assume' failed: Given type{indentExpr e}\nis not a proposition." + let tgt ← getMainTarget + let .forallE _ b _ _ ← whnf tgt | + throwErrorAt t "Tactic 'assume' failed: Goal{indentExpr tgt}\nis not an implication." + let .true ← isDefEq b e | + throwErrorAt t "Tactic 'assume' failed: Given type{indentExpr e}\ndoes not match the \ + type{indentExpr b}\nof the hypothesis in the goal." + evalTactic (← `(tactic | intro (_ : $t))) diff --git a/MathlibTest/Assume.lean b/MathlibTest/Assume.lean new file mode 100644 index 00000000000000..21adee73b73a6b --- /dev/null +++ b/MathlibTest/Assume.lean @@ -0,0 +1,73 @@ +module + +import Mathlib.Tactic.Assume + +example {α β γ} {g : β → γ} {f : α → β} (hg : g.Injective) (hf : f.Injective) : + (g ∘ f).Injective := by + intro x y + assume g (f x) = g (f y) + rename_i h + guard_hyp h :ₛ g (f x) = g (f y) + exact hf (hg ‹_›) + +/- A nice "teaching" example -/ +open Function +example {α β γ} {g : β → γ} {f : α → β} (hg : Injective g) (hf : Injective f) : + Injective (g ∘ f) := by + intro x y + assume g (f x) = g (f y) + have : f x = f y := by grind + show x = y + grind + +example {α β γ} {g : β → γ} {f : α → β} (hg : g.Injective) (hf : f.Injective) : + (g ∘ f).Injective := by + intro x y + assume _ + rename_i h + guard_hyp h :ₛ (g ∘ f) x = (g ∘ f) y + exact hf (hg ‹_›) + +/-- error: Tactic 'assume' failed: No hypotheses given. -/ +#guard_msgs in +example (p : Prop) : p → p := by + assume + +/-- +error: Tactic 'assume' failed: Given type + q +does not match the type + p +of the hypothesis in the goal. +-/ +#guard_msgs in +example (p q : Prop) : p → p := by + assume q + +/-- +error: Tactic 'assume' failed: Goal + p +is not an implication. +-/ +#guard_msgs in +example (p q : Prop) : p → p := by + assume p + assume p + +/-- +error: Tactic 'assume' failed: Given type + Nat +is not a proposition. +-/ +#guard_msgs in +example : ∀ n, n < 5 → Fin 5 := by + assume Nat + +example (n : Nat) : n < 5 → Fin 5 := by + assume n < 5 + -- this style is discouraged/disallowed in Mathlib: an explicit name should be given. + exact ⟨n, ‹_›⟩ + +example {p : Prop} (α : p → Type) (α_intro : ∀ h, α h) : ∀ h : p, α h := by + assume p + apply α_intro From 1908d50c60ab1867a250ef2d4c7263dfd6e7ed81 Mon Sep 17 00:00:00 2001 From: Abhishek Shivakumar Date: Tue, 28 Jul 2026 15:02:39 +0000 Subject: [PATCH 1054/1300] feat(Algebra/Spectrum): add the second resolvent identity (#39269) Adds `spectrum.resolvent_sub_resolvent`: For `a b : A` in an `R`-algebra and `r` in the resolvent set of both, `resolvent a r - resolvent b r = resolvent a r * (a - b) * resolvent b r`. Companion to `spectrum.resolvent_eq`. --- Mathlib/Algebra/Algebra/Spectrum/Basic.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean index 218fdf28feb528..0ba3995b292d3a 100644 --- a/Mathlib/Algebra/Algebra/Spectrum/Basic.lean +++ b/Mathlib/Algebra/Algebra/Spectrum/Basic.lean @@ -33,6 +33,7 @@ This theory will serve as the foundation for spectral theory in Banach algebras. * `spectrum.left_add_coset_eq`: elements of the scalar ring commute (addition) with the spectrum. * `spectrum.unit_mem_mul_comm` and `spectrum.preimage_units_mul_comm`: the units (of `R`) in `σ (a*b)` coincide with those in `σ (b*a)`. +* `spectrum.resolvent_sub_resolvent`: the second resolvent identity. * `spectrum.scalar_eq`: in a nontrivial algebra over a field, the spectrum of a scalar is a singleton. @@ -167,6 +168,17 @@ theorem of_subsingleton [Subsingleton A] (a : A) : spectrum R a = ∅ := by theorem resolvent_eq {a : A} {r : R} (h : r ∈ resolventSet R a) : resolvent a r = ↑h.unit⁻¹ := Ring.inverse_unit h.unit +/-- The second resolvent identity: for `r` in the resolvent set of both +`a` and `b`, +`resolvent a r - resolvent b r = resolvent a r * (a - b) * resolvent b r`. -/ +theorem resolvent_sub_resolvent {a b : A} {r : R} + (ha : r ∈ resolventSet R a) (hb : r ∈ resolventSet R b) : + resolvent a r - resolvent b r = resolvent a r * (a - b) * resolvent b r := by + rw [resolvent_eq ha, resolvent_eq hb, Units.eq_mul_inv_iff_mul_eq, Units.eq_inv_mul_iff_mul_eq, + sub_mul, Units.inv_mul, mul_sub, ← mul_assoc, Units.mul_inv, one_mul, mul_one, + hb.unit_spec, ha.unit_spec] + abel + theorem units_smul_resolvent {r : Rˣ} {s : R} {a : A} : r • resolvent a (s : R) = resolvent (r⁻¹ • a) (r⁻¹ • s : R) := by by_cases h : s ∈ spectrum R a From fb2c2f59cbbf1a6118b401fe85bcfbf849f4bdda Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Tue, 28 Jul 2026 15:02:42 +0000 Subject: [PATCH 1055/1300] feat: tag lemmas with compactness and closedness (#39371) --- Mathlib/Topology/Basic.lean | 16 +++++++- Mathlib/Topology/Closure.lean | 5 ++- Mathlib/Topology/Compactness/Compact.lean | 18 ++++++++- Mathlib/Topology/MetricSpace/ProperSpace.lean | 2 + Mathlib/Topology/Order/Compact.lean | 2 + Mathlib/Topology/Order/OrderClosed.lean | 11 +++--- Mathlib/Topology/Separation/Basic.lean | 2 + Mathlib/Topology/Separation/Hausdorff.lean | 6 ++- MathlibTest/Compactness.lean | 37 +++++++++++++++++++ 9 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 MathlibTest/Compactness.lean diff --git a/Mathlib/Topology/Basic.lean b/Mathlib/Topology/Basic.lean index 342ef7ab77603e..e7713e564a954f 100644 --- a/Mathlib/Topology/Basic.lean +++ b/Mathlib/Topology/Basic.lean @@ -128,22 +128,29 @@ alias ⟨_, TopologicalSpace.ext_isClosed⟩ := TopologicalSpace.ext_iff_isClose theorem isClosed_const {p : Prop} : IsClosed { _x : X | p } := ⟨isOpen_const (p := ¬p)⟩ -@[simp] theorem isClosed_empty : IsClosed (∅ : Set X) := isClosed_const +@[simp, closedness ., grind .] +theorem isClosed_empty : IsClosed (∅ : Set X) := isClosed_const -@[simp] theorem isClosed_univ : IsClosed (univ : Set X) := isClosed_const +@[simp, closedness ., grind .] +theorem isClosed_univ : IsClosed (univ : Set X) := isClosed_const +@[closedness .] lemma IsOpen.isLocallyClosed (hs : IsOpen s) : IsLocallyClosed s := ⟨_, _, hs, isClosed_univ, (inter_univ _).symm⟩ +@[closedness .] lemma IsClosed.isLocallyClosed (hs : IsClosed s) : IsLocallyClosed s := ⟨_, _, isOpen_univ, hs, (univ_inter _).symm⟩ +@[closedness .] theorem IsClosed.union : IsClosed s₁ → IsClosed s₂ → IsClosed (s₁ ∪ s₂) := by simpa only [← isOpen_compl_iff, compl_union] using IsOpen.inter +@[closedness .] theorem isClosed_sInter {s : Set (Set X)} : (∀ t ∈ s, IsClosed t) → IsClosed (⋂₀ s) := by simpa only [← isOpen_compl_iff, compl_sInter, sUnion_image] using isOpen_biUnion +@[closedness .] theorem isClosed_iInter {f : ι → Set X} (h : ∀ i, IsClosed (f i)) : IsClosed (⋂ i, f i) := isClosed_sInter <| forall_mem_range.2 h @@ -160,11 +167,13 @@ alias ⟨_, IsOpen.isClosed_compl⟩ := isClosed_compl_iff theorem IsOpen.sdiff (h₁ : IsOpen s) (h₂ : IsClosed t) : IsOpen (s \ t) := IsOpen.inter h₁ h₂.isOpen_compl +@[closedness .] theorem IsClosed.inter (h₁ : IsClosed s₁) (h₂ : IsClosed s₂) : IsClosed (s₁ ∩ s₂) := by rw [← isOpen_compl_iff] at * rw [compl_inter] exact IsOpen.union h₁ h₂ +@[closedness .] theorem IsClosed.sdiff (h₁ : IsClosed s) (h₂ : IsOpen t) : IsClosed (s \ t) := IsClosed.inter h₁ (isClosed_compl_iff.mpr h₂) @@ -178,11 +187,13 @@ lemma isClosed_biUnion_finset {s : Finset α} {f : α → Set X} (h : ∀ i ∈ IsClosed (⋃ i ∈ s, f i) := s.finite_toSet.isClosed_biUnion h +@[closedness .] theorem isClosed_iUnion_of_finite [Finite ι] {s : ι → Set X} (h : ∀ i, IsClosed (s i)) : IsClosed (⋃ i, s i) := by simp only [← isOpen_compl_iff, compl_iUnion] at * exact isOpen_iInter_of_finite h +@[closedness .] theorem isClosed_imp {p q : X → Prop} (hp : IsOpen { x | p x }) (hq : IsClosed { x | q x }) : IsClosed { x | p x → q x } := by simpa only [imp_iff_not_or] using! hp.isClosed_compl.union hq @@ -190,6 +201,7 @@ theorem isClosed_imp {p q : X → Prop} (hp : IsOpen { x | p x }) (hq : IsClosed theorem IsClosed.not : IsClosed { a | p a } → IsOpen { a | ¬p a } := isOpen_compl_iff.mpr +@[closedness .] theorem IsClosed.and : IsClosed { x | p₁ x } → IsClosed { x | p₂ x } → IsClosed { x | p₁ x ∧ p₂ x } := IsClosed.inter diff --git a/Mathlib/Topology/Closure.lean b/Mathlib/Topology/Closure.lean index 1c1594198d825f..a69a307267e848 100644 --- a/Mathlib/Topology/Closure.lean +++ b/Mathlib/Topology/Closure.lean @@ -186,7 +186,7 @@ end Interior section Closure -@[simp] +@[simp, closedness ., grind .] theorem isClosed_closure : IsClosed (closure s) := isClosed_sInter fun _ => And.left @@ -207,7 +207,8 @@ theorem Disjoint.closure_right (hd : Disjoint s t) (hs : IsOpen s) : Disjoint s (closure t) := (hd.symm.closure_left hs).symm -@[simp] theorem IsClosed.closure_eq (h : IsClosed s) : closure s = s := +@[simp, closedness =] +theorem IsClosed.closure_eq (h : IsClosed s) : closure s = s := Subset.antisymm (closure_minimal (Subset.refl s) h) subset_closure theorem forall_isClosed_iff {p : Set X → Prop} : diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index bf7020f23175f6..fa86ecf5d550b9 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -83,6 +83,7 @@ theorem IsCompact.induction_on (hs : IsCompact s) {p : Set X → Prop} (he : p rwa [← compl_compl s] /-- The intersection of a compact set and a closed set is a compact set. -/ +@[compactness .] theorem IsCompact.inter_right (hs : IsCompact s) (ht : IsClosed t) : IsCompact (s ∩ t) := by intro f hnf hstf obtain ⟨x, hsx, hx⟩ : ∃ x ∈ s, ClusterPt x f := @@ -92,10 +93,12 @@ theorem IsCompact.inter_right (hs : IsCompact s) (ht : IsClosed t) : IsCompact ( exact ⟨x, ⟨hsx, this⟩, hx⟩ /-- The intersection of a closed set and a compact set is a compact set. -/ +@[compactness .] theorem IsCompact.inter_left (ht : IsCompact t) (hs : IsClosed s) : IsCompact (s ∩ t) := inter_comm t s ▸ ht.inter_right hs /-- The set difference of a compact set and an open set is a compact set. -/ +@[compactness .] theorem IsCompact.diff (hs : IsCompact s) (ht : IsOpen t) : IsCompact (s \ t) := hs.inter_right (isClosed_compl_iff.mpr ht) @@ -104,6 +107,7 @@ theorem IsCompact.of_isClosed_subset (hs : IsCompact s) (ht : IsClosed t) (h : t IsCompact t := inter_eq_self_of_subset_right h ▸ hs.inter_right ht +@[compactness .] theorem IsCompact.image_of_continuousOn {f : X → Y} (hs : IsCompact s) (hf : ContinuousOn f s) : IsCompact (f '' s) := by intro l lne ls @@ -463,9 +467,11 @@ theorem IsCompact.eventually_forall_of_forall_eventually {x₀ : X} {K : Set Y} simp only [nhds_prod_eq, ← eventually_iSup, ← hK.prod_nhdsSet_eq_biSup] at hP exact hP.curry.mono fun _ h ↦ h.self_of_nhdsSet +@[compactness ., grind .] theorem isCompact_empty : IsCompact (∅ : Set X) := fun _f hnf hsf => Not.elim hnf.ne <| empty_mem_iff_bot.1 <| le_principal_iff.1 hsf +@[compactness ., grind .] theorem isCompact_singleton {x : X} : IsCompact ({x} : Set X) := fun _ hf hfa => ⟨x, rfl, ClusterPt.of_le_nhds' (hfa.trans <| by simpa only [principal_singleton] using pure_le_nhds x) hf⟩ @@ -485,19 +491,22 @@ theorem Finset.isCompact_biUnion (s : Finset ι) {f : ι → Set X} (hf : ∀ i IsCompact (⋃ i ∈ s, f i) := s.finite_toSet.isCompact_biUnion hf +@[compactness .] theorem isCompact_accumulate {K : ℕ → Set X} (hK : ∀ n, IsCompact (K n)) (n : ℕ) : IsCompact (accumulate K n) := (finite_le_nat n).isCompact_biUnion fun k _ => hK k +@[compactness .] theorem Set.Finite.isCompact_sUnion {S : Set (Set X)} (hf : S.Finite) (hc : ∀ s ∈ S, IsCompact s) : IsCompact (⋃₀ S) := by rw [sUnion_eq_biUnion]; exact hf.isCompact_biUnion hc +@[compactness .] theorem isCompact_iUnion {ι : Sort*} {f : ι → Set X} [Finite ι] (h : ∀ i, IsCompact (f i)) : IsCompact (⋃ i, f i) := (finite_range f).isCompact_sUnion <| forall_mem_range.2 h -@[simp] theorem Set.Finite.isCompact (hs : s.Finite) : IsCompact s := +@[simp, compactness .] theorem Set.Finite.isCompact (hs : s.Finite) : IsCompact s := biUnion_of_singleton s ▸ hs.isCompact_biUnion fun _ _ => isCompact_singleton @[simp] theorem Set.sUnion_isCompact_eq_univ : ⋃₀ {(s : Set X) | IsCompact s} = univ := @@ -512,9 +521,11 @@ theorem IsCompact.finite_of_discrete [DiscreteTopology X] (hs : IsCompact s) : s theorem isCompact_iff_finite [DiscreteTopology X] : IsCompact s ↔ s.Finite := ⟨fun h => h.finite_of_discrete, fun h => h.isCompact⟩ +@[compactness .] theorem IsCompact.union (hs : IsCompact s) (ht : IsCompact t) : IsCompact (s ∪ t) := by rw [union_eq_iUnion]; exact isCompact_iUnion fun b => by cases b <;> assumption +@[compactness .] protected theorem IsCompact.insert (hs : IsCompact s) (a) : IsCompact (insert a s) := isCompact_singleton.union hs @@ -784,6 +795,7 @@ instance (priority := 10) Subsingleton.compactSpace [Subsingleton X] : CompactSp theorem isCompact_univ_iff : IsCompact (univ : Set X) ↔ CompactSpace X := ⟨fun h => ⟨h⟩, fun h => h.1⟩ +@[compactness ., grind .] theorem isCompact_univ [h : CompactSpace X] : IsCompact (univ : Set X) := h.isCompact_univ @@ -958,6 +970,7 @@ theorem disjoint_map_cocompact {g : X → Y} {f : Filter X} (hg : Continuous g) _ ≤ f ⊓ Filter.cocompact X := inf_le_inf_left f (Filter.comap_cocompact_le hg) _ = ⊥ := disjoint_iff.mp hf +@[compactness .] theorem isCompact_range [CompactSpace X] {f : X → Y} (hf : Continuous f) : IsCompact (range f) := by rw [← image_univ]; exact isCompact_univ.image hf @@ -967,6 +980,7 @@ lemma Function.Surjective.compactSpace {f : X → Y} (hf : Continuous f) [Compac rw [← hf'.range_eq] exact isCompact_range hf +@[compactness .] theorem isCompact_diagonal [CompactSpace X] : IsCompact (diagonal X) := @range_diag X ▸ isCompact_range (continuous_id.prodMk continuous_id) @@ -1059,6 +1073,7 @@ protected theorem Topology.IsClosedEmbedding.compactSpace [h : CompactSpace Y] { (hf : IsClosedEmbedding f) : CompactSpace X := ⟨by rw [hf.isInducing.isCompact_iff, image_univ]; exact hf.isClosed_range.isCompact⟩ +@[compactness .] theorem IsCompact.prod {t : Set Y} (hs : IsCompact s) (ht : IsCompact t) : IsCompact (s ×ˢ t) := by rw [isCompact_iff_ultrafilter_le_nhds'] at hs ht ⊢ @@ -1099,6 +1114,7 @@ instance {X : ι → Type*} [Finite ι] [∀ i, TopologicalSpace (X i)] [∀ i, rw [Sigma.univ] exact isCompact_iUnion fun i => isCompact_range continuous_sigmaMk +@[compactness .] lemma Set.isCompact_sigma {X : ι → Type*} [∀ i, TopologicalSpace (X i)] {s : Set ι} {t : ∀ i, Set (X i)} (hs : s.Finite) (ht : ∀ i ∈ s, IsCompact (t i)) : IsCompact (s.sigma t) := by diff --git a/Mathlib/Topology/MetricSpace/ProperSpace.lean b/Mathlib/Topology/MetricSpace/ProperSpace.lean index df09f99da0f759..818ccb53b6b04d 100644 --- a/Mathlib/Topology/MetricSpace/ProperSpace.lean +++ b/Mathlib/Topology/MetricSpace/ProperSpace.lean @@ -40,8 +40,10 @@ class ProperSpace (α : Type u) [PseudoMetricSpace α] : Prop where isCompact_closedBall : ∀ x : α, ∀ r, IsCompact (closedBall x r) export ProperSpace (isCompact_closedBall) +attribute [compactness .] isCompact_closedBall /-- In a proper pseudometric space, all spheres are compact. -/ +@[compactness .] theorem isCompact_sphere {α : Type*} [PseudoMetricSpace α] [ProperSpace α] (x : α) (r : ℝ) : IsCompact (sphere x r) := (isCompact_closedBall x r).of_isClosed_subset isClosed_sphere sphere_subset_closedBall diff --git a/Mathlib/Topology/Order/Compact.lean b/Mathlib/Topology/Order/Compact.lean index 36108625e44d6b..676c1bf5eb219a 100644 --- a/Mathlib/Topology/Order/Compact.lean +++ b/Mathlib/Topology/Order/Compact.lean @@ -54,6 +54,7 @@ class CompactIccSpace (α : Type*) [TopologicalSpace α] [Preorder α] : Prop wh isCompact_Icc : ∀ {a b : α}, IsCompact (Icc a b) export CompactIccSpace (isCompact_Icc) +attribute [compactness .] isCompact_Icc variable {α : Type*} @@ -91,6 +92,7 @@ instance {α β : Type*} [Preorder α] [TopologicalSpace α] [CompactIccSpace α ⟨fun {a b} => (Icc_prod_eq a b).symm ▸ isCompact_Icc.prod isCompact_Icc⟩ /-- An unordered closed interval is compact. -/ +@[compactness .] theorem isCompact_uIcc {α : Type*} [LinearOrder α] [TopologicalSpace α] [CompactIccSpace α] {a b : α} : IsCompact (uIcc a b) := isCompact_Icc diff --git a/Mathlib/Topology/Order/OrderClosed.lean b/Mathlib/Topology/Order/OrderClosed.lean index d00a24b8265d16..9603945a9c797c 100644 --- a/Mathlib/Topology/Order/OrderClosed.lean +++ b/Mathlib/Topology/Order/OrderClosed.lean @@ -112,7 +112,7 @@ section Preorder variable [TopologicalSpace α] [Preorder α] [ClosedIicTopology α] {f : β → α} {a b : α} {s : Set α} -@[to_dual] +@[to_dual (attr := closedness .)] theorem isClosed_Iic : IsClosed (Iic a) := ClosedIicTopology.isClosed_Iic a @@ -120,7 +120,7 @@ theorem isClosed_Iic : IsClosed (Iic a) := instance : ClosedIciTopology αᵒᵈ where isClosed_Ici _ := isClosed_Iic (α := α) -@[to_dual (attr := simp)] +@[to_dual (attr := simp, closedness =)] theorem closure_Iic (a : α) : closure (Iic a) = Iic a := isClosed_Iic.closure_eq @@ -435,10 +435,11 @@ end Subtype -- The binder info on both theorems is slightly different, see -- https://github.com/leanprover/lean4/issues/9727 +@[closedness .] theorem isClosed_le_prod : IsClosed { p : α × α | p.1 ≤ p.2 } := t.isClosed_le' -@[to_dual existing isClosed_le_prod] +@[to_dual existing isClosed_le_prod, closedness .] theorem isClosed_le_prod' : IsClosed { p : α × α | p.2 ≤ p.1 } := (isClosed_le_prod (α := α)).preimage continuous_swap @@ -454,11 +455,11 @@ instance : ClosedIicTopology α where instance : OrderClosedTopology αᵒᵈ := ⟨isClosed_le_prod' (α := α)⟩ -@[to_dual self] +@[to_dual self, closedness .] theorem isClosed_Icc {a b : α} : IsClosed (Icc a b) := IsClosed.inter isClosed_Ici isClosed_Iic -@[to_dual self, simp] +@[to_dual self, simp, closedness =] theorem closure_Icc (a b : α) : closure (Icc a b) = Icc a b := isClosed_Icc.closure_eq diff --git a/Mathlib/Topology/Separation/Basic.lean b/Mathlib/Topology/Separation/Basic.lean index d95b92339eefc2..4067fcf49e0f6d 100644 --- a/Mathlib/Topology/Separation/Basic.lean +++ b/Mathlib/Topology/Separation/Basic.lean @@ -348,6 +348,7 @@ class T1Space (X : Type u) [TopologicalSpace X] : Prop where /-- A singleton in a T₁ space is a closed set. -/ t1 : ∀ x, IsClosed ({x} : Set X) +@[closedness .] theorem isClosed_singleton [T1Space X] {x : X} : IsClosed ({x} : Set X) := T1Space.t1 x @@ -568,6 +569,7 @@ theorem compl_singleton_mem_nhds_iff [T1Space X] {x y : X} : {x}ᶜ ∈ 𝓝 y theorem compl_singleton_mem_nhds [T1Space X] {x y : X} (h : y ≠ x) : {x}ᶜ ∈ 𝓝 y := compl_singleton_mem_nhds_iff.mpr h +@[closedness =] theorem closure_singleton [T1Space X] {x : X} : closure ({x} : Set X) = {x} := isClosed_singleton.closure_eq diff --git a/Mathlib/Topology/Separation/Hausdorff.lean b/Mathlib/Topology/Separation/Hausdorff.lean index 4998e1f32113a6..035464532dbc48 100644 --- a/Mathlib/Topology/Separation/Hausdorff.lean +++ b/Mathlib/Topology/Separation/Hausdorff.lean @@ -164,6 +164,7 @@ theorem t2_iff_isClosed_diagonal : T2Space X ↔ IsClosed (diagonal X) := by simp only [t2Space_iff_disjoint_nhds, ← isOpen_compl_iff, isOpen_iff_mem_nhds, Prod.forall, nhds_prod_eq, compl_diagonal_mem_prod, mem_compl_iff, mem_diagonal_iff, Pairwise] +@[closedness ., grind .] theorem isClosed_diagonal [T2Space X] : IsClosed (diagonal X) := t2_iff_isClosed_diagonal.mp ‹_› @@ -490,6 +491,7 @@ theorem isClosed_eq [T2Space X] {f g : Y → X} (hf : Continuous f) (hg : Contin /-- If functions `f` and `g` are continuous on a closed set `s`, then the set of points `x ∈ s` such that `f x = g x` is a closed set. -/ +@[closedness .] protected theorem IsClosed.isClosed_eq [T2Space Y] {f g : X → Y} {s : Set X} (hs : IsClosed s) (hf : ContinuousOn f s) (hg : ContinuousOn g s) : IsClosed {x ∈ s | f x = g x} := (hf.prodMk hg).preimage_isClosed_of_isClosed hs isClosed_diagonal @@ -586,12 +588,13 @@ theorem SeparatedNhds.of_singleton_finset [T2Space X] {x : X} {s : Finset X} (h end SeparatedFinset /-- In a `T2Space`, every compact set is closed. -/ -@[aesop 50% apply, grind ←] +@[aesop 50% apply, grind ←, closedness .] theorem IsCompact.isClosed [T2Space X] {s : Set X} (hs : IsCompact s) : IsClosed s := isClosed_iff_forall_filter.2 fun _x _f _ hfs hfx => let ⟨_y, hy, hfy⟩ := hs.exists_clusterPt hfs mem_of_eq_of_mem (eq_of_nhds_neBot (hfy.mono hfx).neBot).symm hy +@[compactness .] theorem IsCompact.preimage_continuous [CompactSpace X] [T2Space Y] {f : X → Y} {s : Set Y} (hs : IsCompact s) (hf : Continuous f) : IsCompact (f ⁻¹' s) := (hs.isClosed.preimage hf).isCompact @@ -620,6 +623,7 @@ theorem exists_subset_nhds_of_isCompact [T2Space X] {ι : Type*} [Nonempty ι] { theorem CompactExhaustion.isClosed [T2Space X] (K : CompactExhaustion X) (n : ℕ) : IsClosed (K n) := (K.isCompact n).isClosed +@[compactness .] theorem IsCompact.inter [T2Space X] {s t : Set X} (hs : IsCompact s) (ht : IsCompact t) : IsCompact (s ∩ t) := hs.inter_right <| ht.isClosed diff --git a/MathlibTest/Compactness.lean b/MathlibTest/Compactness.lean new file mode 100644 index 00000000000000..bd60f2d0a78a90 --- /dev/null +++ b/MathlibTest/Compactness.lean @@ -0,0 +1,37 @@ +module + +public import Mathlib + +open Set MeasureTheory + +example : IsCompact <| Icc (1 : ℝ) (3 : ℝ) := by compactness + +example : IsCompact <| Metric.closedBall (0 : Fin 5 → ℝ) 7 := by compactness + +example {a b c d : ℝ} : IsCompact (Icc a b ∩ Icc c d) := by compactness + +example : IsCompact {0} := by compactness + +example {a b c : ℝ} : IsCompact {a, b, c} := by compactness + +example {a b c d e : ℝ} : IsCompact {a, b, c, d, e} := by compactness + +example {s : Set ℝ} (h : s.Finite) : IsCompact s := by compactness + +example : IsCompact <| closure (Icc (1 : ℝ) (3 : ℝ)) := by + grind only [compactness, closedness] + +example : closure (Icc (1 : ℝ) (3 : ℝ)) = Icc (1 : ℝ) (3 : ℝ) := by + grind only [compactness, closedness] + +example : IsCompact <| closure (Metric.closedBall (0 : Fin 5 → ℝ) 7) := by + grind only [compactness, closedness] + +example {a b c : ℝ} : IsCompact (Icc a b ∩ Ici c) := by + grind only [compactness, closedness] + +example {a b c d : ℝ} : IsCompact (closure (Icc a b ∩ Icc c d)) := by + grind only [compactness, closedness] + +example {a b : ℝ} : IsCompact (closure (Ici a ∩ Iic b)) := by + grind only [compactness, closedness, Ici_inter_Iic] From 5b20aff7a4c34e27374611707081e3586186769d Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Tue, 28 Jul 2026 15:02:45 +0000 Subject: [PATCH 1056/1300] feat(Algebra/Lie): use `IsApply` for `Weight` (#42129) --- Mathlib/Algebra/Lie/Weights/Basic.lean | 9 +++++---- Mathlib/Algebra/Lie/Weights/RootSystem.lean | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Lie/Weights/Basic.lean b/Mathlib/Algebra/Lie/Weights/Basic.lean index e9e42df896bd58..d7a5aac9171ab7 100644 --- a/Mathlib/Algebra/Lie/Weights/Basic.lean +++ b/Mathlib/Algebra/Lie/Weights/Basic.lean @@ -238,10 +238,12 @@ instance [Subsingleton M] : IsEmpty (Weight R L M) := instance [Nontrivial (genWeightSpace M (0 : L → R))] : Zero (Weight R L M) := ⟨0, fun e ↦ not_nontrivial (⊥ : LieSubmodule R L M) (e ▸ ‹_›)⟩ -@[simp] -lemma coe_zero [Nontrivial (genWeightSpace M (0 : L → R))] : ((0 : Weight R L M) : L → R) = 0 := rfl +instance [Nontrivial (genWeightSpace M (0 : L → R))] : IsZeroApply (Weight R L M) L R where + zero_apply _ := rfl + +@[deprecated (since := "2026-07-27")] alias coe_zero := FunLike.coe_zero -lemma zero_apply [Nontrivial (genWeightSpace M (0 : L → R))] (x) : (0 : Weight R L M) x = 0 := rfl +@[deprecated (since := "2026-07-27")] protected alias zero_apply := zero_apply /-- The proposition that a weight of a Lie module is zero. @@ -266,7 +268,6 @@ lemma isNonZero_iff_ne_zero [Nontrivial (genWeightSpace M (0 : L → R))] {χ : noncomputable instance : DecidablePred (IsNonZero (R := R) (L := L) (M := M)) := Classical.decPred _ -set_option backward.isDefEq.respectTransparency.types false in variable (R L M) in /-- The set of weights is equivalent to a subtype. -/ def equivSetOfPred : Weight R L M ≃ {χ : L → R | genWeightSpace M χ ≠ ⊥} where diff --git a/Mathlib/Algebra/Lie/Weights/RootSystem.lean b/Mathlib/Algebra/Lie/Weights/RootSystem.lean index 15e5b3055a9dff..7f6c53376e8164 100644 --- a/Mathlib/Algebra/Lie/Weights/RootSystem.lean +++ b/Mathlib/Algebra/Lie/Weights/RootSystem.lean @@ -263,7 +263,7 @@ lemma chainTopCoeff_zero_right [Nontrivial L] (hα : α.IsNonZero) : apply eq_of_le_of_not_lt · rw [Nat.one_le_iff_ne_zero] intro e - exact α.2 (by simpa [e, Weight.coe_zero] using! + exact α.2 (by simpa [e] using! genWeightSpace_chainTopCoeff_add_one_nsmul_add α (0 : Weight K H L) hα) obtain ⟨x, hx, x_ne0⟩ := (chainTop α (0 : Weight K H L)).exists_ne_zero obtain ⟨h, e, f, isSl2, he, hf⟩ := exists_isSl2Triple_of_weight_isNonZero hα @@ -275,7 +275,7 @@ lemma chainTopCoeff_zero_right [Nontrivial L] (hα : α.IsNonZero) : (toEnd K L L f ^ (chainTopCoeff α (0 : Weight K H L) + 1)) x := by have : (toEnd K L L f ^ (chainTopCoeff α (0 : Weight K H L) + 1)) x ∈ rootSpace H (-α) := by convert toEnd_pow_apply_mem hf hx (chainTopCoeff α (0 : Weight K H L) + 1) - rw [coe_chainTop', Weight.coe_zero, add_zero, succ_nsmul', + rw [coe_chainTop', FunLike.coe_zero, add_zero, succ_nsmul', add_assoc, smul_neg, neg_add_cancel, add_zero] simpa using! (finrank_eq_one_iff_of_nonzero' ⟨f, hf⟩ (by simpa using! isSl2.f_ne_zero)).mp (finrank_rootSpace_eq_one _ hα.neg) ⟨_, this⟩ @@ -284,7 +284,7 @@ lemma chainTopCoeff_zero_right [Nontrivial L] (hα : α.IsNonZero) : intro e refine prim.pow_toEnd_f_ne_zero_of_eq_nat rfl ?_ hk.symm have := (apply_coroot_eq_cast' α 0).symm - simp only [← @Nat.cast_two ℤ, ← Nat.cast_mul, Weight.zero_apply, Int.cast_eq_zero, sub_eq_zero, + simp only [← @Nat.cast_two ℤ, ← Nat.cast_mul, zero_apply, Int.cast_eq_zero, sub_eq_zero, Nat.cast_inj] at this rwa [this, Nat.succ_le_iff, two_mul, add_lt_add_iff_left] @@ -328,7 +328,7 @@ lemma eq_neg_one_or_eq_zero_or_eq_one_of_eq_smul mul_eq_mul_left_iff, OfNat.ofNat_ne_zero, or_false] at H rw [← Int.cast_natCast, ← Int.cast_natCast (chainTopCoeff α β), ← Int.cast_sub] at H have := (rootSpace_zsmul_add_ne_bot_iff_mem α 0 hα (n - chainTopCoeff α β)).mp - (by rw [← Int.cast_smul_eq_zsmul K, ← H, ← h, Weight.coe_zero, add_zero]; exact β.2) + (by rw [← Int.cast_smul_eq_zsmul K, ← H, ← h, FunLike.coe_zero, add_zero]; exact β.2) rw [chainTopCoeff_zero_right α hα, chainBotCoeff_zero_right α hα, Nat.cast_one] at this set k' : ℤ := n - chainTopCoeff α β subst H From b595917dfbaca78471c6afc8c9db44415e86ba78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 28 Jul 2026 15:02:47 +0000 Subject: [PATCH 1057/1300] chore(LinearAlgebra/Pi): use `Codisjoint`, `IsCompl` (#42173) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... and syntactically generalise `{I : Finset ι}` to `{I : Set ι} (hI : I.Finite)`. The new proofs also happen to not abuse the `Set α := α → Prop` defeq. --- Mathlib/LinearAlgebra/Matrix/Diagonal.lean | 17 +++----- Mathlib/LinearAlgebra/Pi.lean | 48 +++++++++------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Diagonal.lean b/Mathlib/LinearAlgebra/Matrix/Diagonal.lean index b7e00ee95e303e..97be0a9a936f62 100644 --- a/Mathlib/LinearAlgebra/Matrix/Diagonal.lean +++ b/Mathlib/LinearAlgebra/Matrix/Diagonal.lean @@ -56,12 +56,10 @@ variable {m : Type*} [Fintype m] {K : Type u} [Semifield K] theorem ker_diagonal_toLin' [DecidableEq m] (w : m → K) : ker (toLin' (diagonal w)) = ⨆ i ∈ { i | w i = 0 }, LinearMap.range (LinearMap.single K (fun _ => K) i) := by - rw [← comap_bot, ← iInf_ker_proj, comap_iInf] + rw [← comap_bot] have := fun i : m => ker_comp (toLin' (diagonal w)) (proj i) - simp only [← this, proj_diagonal, ker_smul'] - have : univ ⊆ { i : m | w i = 0 } ∪ { i : m | w i = 0 }ᶜ := by rw [Set.union_compl_self] - exact (iSup_range_single_eq_iInf_ker_proj K (fun _ : m => K) disjoint_compl_right this - (Set.toFinite _)).symm + simpa [← this, proj_diagonal, ker_smul', ← iInf_ker_proj] using + (iSup_range_single_eq_iInf_ker_proj K _ isCompl_compl {i | w i = 0}.toFinite).symm theorem range_diagonal [DecidableEq m] (w : m → K) : LinearMap.range (toLin' (diagonal w)) = @@ -83,13 +81,10 @@ variable {m : Type*} [Fintype m] {K : Type u} [Field K] theorem rank_diagonal [DecidableEq m] [DecidableEq K] (w : m → K) : LinearMap.rank (toLin' (diagonal w)) = Fintype.card { i // w i ≠ 0 } := by - have hu : univ ⊆ { i : m | w i = 0 }ᶜ ∪ { i : m | w i = 0 } := by rw [Set.compl_union_self] - have hd : Disjoint { i : m | w i ≠ 0 } { i : m | w i = 0 } := disjoint_compl_left - have B₁ := iSup_range_single_eq_iInf_ker_proj K (fun _ : m => K) hd hu (Set.toFinite _) - have B₂ := iInfKerProjEquiv K (fun _ ↦ K) hd hu + have hIJ : IsCompl { i : m | w i ≠ 0 } { i : m | w i = 0 } := isCompl_compl.symm + have B₁ := iSup_range_single_eq_iInf_ker_proj K (fun _ : m => K) hIJ (Set.toFinite _) rw [LinearMap.rank, range_diagonal, B₁, ← @rank_fun' K] - apply LinearEquiv.rank_eq - apply B₂ + exact iInfKerProjEquiv K (fun _ ↦ K) hIJ.disjoint hIJ.codisjoint.top_le |>.rank_eq end Field diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index 9c59ef302875bd..6d3599687b9be9 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -200,36 +200,28 @@ theorem iSup_range_single_le_iInf_ker_proj (I J : Set ι) (h : Disjoint I J) : rintro rfl exact h.le_bot ⟨hi, hj⟩ -theorem iInf_ker_proj_le_iSup_range_single {I : Finset ι} {J : Set ι} (hu : Set.univ ⊆ ↑I ∪ J) : - ⨅ i ∈ J, ker (proj i : (∀ i, φ i) →ₗ[R] φ i) ≤ ⨆ i ∈ I, range (single R φ i) := - SetLike.le_def.2 - (by - intro b hb - simp only [mem_iInf, mem_ker, proj_apply] at hb - rw [← - show (∑ i ∈ I, Pi.single i (b i)) = b by - ext i - rw [Finset.sum_apply, ← Pi.single_eq_same i (b i)] - refine Finset.sum_eq_single i (fun j _ ne => Pi.single_eq_of_ne ne.symm _) ?_ - intro hiI - rw [Pi.single_eq_same] - exact hb _ ((hu trivial).resolve_left hiI)] - exact sum_mem_biSup fun i _ => mem_range_self (single R φ i) (b i)) - -theorem iSup_range_single_eq_iInf_ker_proj {I J : Set ι} (hd : Disjoint I J) - (hu : Set.univ ⊆ I ∪ J) (hI : Set.Finite I) : - ⨆ i ∈ I, range (single R φ i) = ⨅ i ∈ J, ker (proj i : (∀ i, φ i) →ₗ[R] φ i) := by - refine le_antisymm (iSup_range_single_le_iInf_ker_proj _ _ _ _ hd) ?_ - have : Set.univ ⊆ ↑hI.toFinset ∪ J := by rwa [hI.coe_toFinset] - refine le_trans (iInf_ker_proj_le_iSup_range_single R φ this) (iSup_mono fun i => ?_) - rw [Set.Finite.mem_toFinset] +theorem iInf_ker_proj_le_iSup_range_single {I J : Set ι} (hI : I.Finite) (hIJ : Codisjoint I J) : + ⨅ i ∈ J, ker (proj i : (∀ i, φ i) →ₗ[R] φ i) ≤ ⨆ i ∈ I, range (single R φ i) := by + lift I to Finset ι using hI + intro b hb + simp only [mem_iInf, mem_ker, proj_apply] at hb + rw [← + show (∑ i ∈ I, Pi.single i (b i)) = b by + ext i + rw [Finset.sum_apply, ← Pi.single_eq_same i (b i)] + refine Finset.sum_eq_single i (fun j _ ne => Pi.single_eq_of_ne ne.symm _) ?_ + intro hiI + rw [Pi.single_eq_same] + exact hb _ ((hIJ.top_le trivial).resolve_left hiI)] + exact sum_mem_biSup fun i _ => mem_range_self (single R φ i) (b i) + +theorem iSup_range_single_eq_iInf_ker_proj {I J : Set ι} (hIJ : IsCompl I J) (hI : I.Finite) : + ⨆ i ∈ I, range (single R φ i) = ⨅ i ∈ J, ker (proj i : (∀ i, φ i) →ₗ[R] φ i) := + le_antisymm (iSup_range_single_le_iInf_ker_proj _ _ _ _ hIJ.disjoint) <| + iInf_ker_proj_le_iSup_range_single R φ hI hIJ.codisjoint theorem iSup_range_single [Finite ι] : ⨆ i, range (single R φ i) = ⊤ := by - cases nonempty_fintype ι - convert! top_unique (iInf_emptyset.ge.trans <| iInf_ker_proj_le_iSup_range_single R φ _) - · rename_i i - exact ((@iSup_pos _ _ _ fun _ => range <| single R φ i) <| Finset.mem_univ i).symm - · rw [Finset.coe_univ, Set.union_empty] + simpa using iInf_ker_proj_le_iSup_range_single R φ Set.finite_univ isCompl_top_bot.codisjoint theorem disjoint_single_single (I J : Set ι) (h : Disjoint I J) : Disjoint (⨆ i ∈ I, range (single R φ i)) (⨆ i ∈ J, range (single R φ i)) := by From 4660688d529f8b813a214daf3845e6c3a970d455 Mon Sep 17 00:00:00 2001 From: Leonid Ryvkin <24719821+Ljon4ik4@users.noreply.github.com> Date: Tue, 28 Jul 2026 15:41:37 +0000 Subject: [PATCH 1058/1300] feat: Transferring Lie Algebra structures along Equivalences (#39818) This pr adds the functionality to transfer Lie brackets along equivalences (additive, linear and plain ones). I followed the scheme of the existing `TransferInstance.lean` file. For one of the proofs, I also needed `linearEquiv_apply `, which seemed missing so I added it. AI use disclaimer: I used claude to search for lemmas/ understand error messages / proofreading and feedback, but wrote the whole code myself. --- Mathlib.lean | 1 + Mathlib/Algebra/Lie/TransferInstance.lean | 112 +++++++++++++++++++ Mathlib/Algebra/Module/TransferInstance.lean | 10 ++ 3 files changed, 123 insertions(+) create mode 100644 Mathlib/Algebra/Lie/TransferInstance.lean diff --git a/Mathlib.lean b/Mathlib.lean index 334165ab555e39..4f8048b995b19c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -763,6 +763,7 @@ public import Mathlib.Algebra.Lie.Subalgebra public import Mathlib.Algebra.Lie.Submodule public import Mathlib.Algebra.Lie.TensorProduct public import Mathlib.Algebra.Lie.TraceForm +public import Mathlib.Algebra.Lie.TransferInstance public import Mathlib.Algebra.Lie.UniversalEnveloping public import Mathlib.Algebra.Lie.Weights.Basic public import Mathlib.Algebra.Lie.Weights.Cartan diff --git a/Mathlib/Algebra/Lie/TransferInstance.lean b/Mathlib/Algebra/Lie/TransferInstance.lean new file mode 100644 index 00000000000000..c5f8ac587ca792 --- /dev/null +++ b/Mathlib/Algebra/Lie/TransferInstance.lean @@ -0,0 +1,112 @@ +/- +Copyright (c) 2026 Leonid Ryvkin. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Leonid Ryvkin +-/ + +module + +public import Mathlib.Algebra.Lie.Basic +public import Mathlib.Algebra.Module.TransferInstance + +/-! +# Transfer Lie brackets along AddEquiv, LinearEquiv and Equiv + +Main definitions: +* `AddEquiv.lieRing` transferring a LieRing structure along an additive equivalence. +* `LinearEquiv.lieAlgebra` transferring a Lie algebra structure along a linear equivalence. +* `Equiv.lieRing` transferring a LieRing structure along an equivalence (transfers the additive + structure using `Equiv.addCommGroup` and then the bracket using `AddEquiv.lieRing`) +* `Equiv.lieAlgebra` transferring a Lie algebra structure along an equivalence + +-/ + +@[expose] public section + +section + +variable {R M L : Type*} [CommRing R] [AddCommGroup M] [Module R M] [LieRing L] [LieAlgebra R L] + +/-- Transfer `LieRing` across an `AddEquiv` -/ +protected abbrev AddEquiv.lieRing (e : M ≃+ L) : LieRing M where + bracket x y := e.symm ⁅e x, e y⁆ + add_lie _ _ _ := by simp + lie_add _ _ _ := by simp + lie_self _ := by simp + leibniz_lie _ _ _ := by simp + +lemma AddEquiv.bracket_def (e : M ≃+ L) (x y : M) : + letI := e.lieRing + ⁅x, y⁆ = e.symm ⁅e x, e y⁆ := rfl + +/-- Transfer `LieAlgebra` across a `LinearEquiv` -/ +protected abbrev LinearEquiv.lieAlgebra (e : M ≃ₗ[R] L) : + letI := e.toAddEquiv.lieRing + LieAlgebra R M := + letI := e.toAddEquiv.lieRing + { lie_smul _ _ _ := by simp [AddEquiv.bracket_def] } + +variable (R) in +/-- An equivalence `e : M ≃ₗ[R] L` gives a Lie algebra equivalence `M ≃ₗ⁅R⁆ L` where the Lie bracket +on `M` is the one obtained by transporting a Lie Bracket on `L` back along `e`. -/ +def LinearEquiv.lieEquiv (e : M ≃ₗ[R] L) : + letI := e.toAddEquiv.lieRing + letI := e.lieAlgebra + M ≃ₗ⁅R⁆ L := + letI := e.toAddEquiv.lieRing + letI := e.lieAlgebra + { e with map_lie' := by simp [AddEquiv.bracket_def] } + +@[simp] +lemma LinearEquiv.lieEquiv_apply (e : M ≃ₗ[R] L) (a : M) : + e.lieEquiv R a = e a := rfl + +@[simp] +lemma LinearEquiv.lieEquiv_symm_apply (e : M ≃ₗ[R] L) (b : L) : + letI := e.toAddEquiv.lieRing + letI := e.lieAlgebra + (e.lieEquiv R).symm b = e.symm b := rfl + +end + +namespace Equiv + +variable {R L' L : Type*} [CommRing R] [LieRing L] [LieAlgebra R L] (e : L' ≃ L) + +/-- Transfer `LieRing` across an `Equiv` -/ +protected abbrev lieRing : LieRing L' := + letI := e.addCommGroup + e.addEquiv.lieRing + +lemma bracket_def (x y : L') : + letI := e.lieRing + ⁅x, y⁆ = e.symm ⁅e x, e y⁆ := rfl + +variable (R) in +/-- Transfer `LieAlgebra` across an `Equiv` -/ +protected abbrev lieAlgebra : + letI := e.lieRing + LieAlgebra R L' := + letI := e.lieRing + letI := e.module R + { lie_smul _ _ _ := by simp [Equiv.smul_def, AddEquiv.bracket_def] } + +variable (R) in +/-- An equivalence `e : L' ≃ L` gives a Lie algebra equivalence `L' ≃ₗ⁅R⁆ L` where the algebraic +structures on `L'` are obtained by transporting the structures on `L` back along `e`. -/ +def lieEquiv : + letI := e.lieRing + letI := e.lieAlgebra R + L' ≃ₗ⁅R⁆ L := + letI := e.lieRing + letI := e.lieAlgebra R + { e.linearEquiv R with map_lie' {x y} := by simp [AddEquiv.bracket_def] } + +@[simp] lemma lieEquiv_apply (a : L') : e.lieEquiv R a = e a := rfl + +@[simp] lemma lieEquiv_symm_apply (b : L) : + letI := e.lieRing + letI := e.lieAlgebra R + (e.lieEquiv R).symm b = e.symm b := rfl + +end Equiv diff --git a/Mathlib/Algebra/Module/TransferInstance.lean b/Mathlib/Algebra/Module/TransferInstance.lean index f41ca4f27218fb..39c5d5b392dde4 100644 --- a/Mathlib/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Algebra/Module/TransferInstance.lean @@ -63,6 +63,16 @@ def linearEquiv (e : α ≃ β) [AddCommMonoid β] [Module R β] : simp only [toFun_as_coe, RingHom.id_apply, EmbeddingLike.apply_eq_iff_eq] exact Iff.mpr (apply_eq_iff_eq_symm_apply _) rfl } +@[simp] +lemma linearEquiv_apply (a : α) [AddCommMonoid β] [Module R β] : + e.linearEquiv R a = e a := rfl + +@[simp] +lemma linearEquiv_symm_apply (b : β) [AddCommMonoid β] [Module R β] : + letI := Equiv.addCommMonoid e + letI := Equiv.module R e + (e.linearEquiv R).symm b = e.symm b := rfl + set_option backward.isDefEq.respectTransparency false in variable (R) in /-- Transfer `Module.IsTorsionFree` across an `Equiv` -/ From cdc4a098a5e8c3b234f61f1529f752cfb7df8714 Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Tue, 28 Jul 2026 15:41:39 +0000 Subject: [PATCH 1059/1300] perf: golf Ideal.powQuotSuccInclusion_injective (#41701) The old proof abuses defeq in a subtle way, which makes painful reading for the kernel. This one is easier to swallow. --- Mathlib/NumberTheory/RamificationInertia/Basic.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 34f7097773c5ca..39a7c21aa4add5 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -309,10 +309,8 @@ noncomputable def powQuotSuccInclusion (i : ℕ) : theorem powQuotSuccInclusion_injective (i : ℕ) : Function.Injective (powQuotSuccInclusion p P i) := by - rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot'] - rintro ⟨x, hx⟩ hx0 - rw [Subtype.ext_iff] at hx0 ⊢ - rwa [powQuotSuccInclusion_apply_coe] at hx0 + rintro ⟨_, _⟩ ⟨_, _⟩ h + rwa [Subtype.ext_iff] at h ⊢ /-- `S ⧸ P` embeds into the quotient by `P^(i+1) ⧸ P^e` as a subspace of `P^i ⧸ P^e`. See `quotientToQuotientRangePowQuotSucc` for this as a linear map, From 9e47bf70e26518025a5db9598f5368c23360150e Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Tue, 28 Jul 2026 16:20:25 +0000 Subject: [PATCH 1060/1300] fix(cache): carry decompression pipeline state across download rounds (#41707) `cache get` downloads files in multiple rounds (corresponding to azure containers, e.g. `master` then `forks` for a fork PR) and decompresses them in a pipeline while the download streams. Each round started from a fresh pipeline state and the round loop kept only the last round's state, so some files queued for decompression plus the in-flight leantar batch was dropped: the .ltars were on disk but never unpacked, and the next lake build recompiled those modules. The in-flight leantar was also never awaited, so it could still be writing build outputs while lake build read them. Reported in https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/cache.20issues/with/609923362 The fix makes the pipeline state an explicit value threaded through the rounds: a DecompState structure (pending files, in-flight batch, counters) embedded in TransferState, and finalizeDecomp drain after the last round. Also adds related tests in Cache/Test.lean. --- Cache/Requests.lean | 139 ++++++++++++++++++++++++++------------------ Cache/Test.lean | 83 +++++++++++++++++++++++++- 2 files changed, 164 insertions(+), 58 deletions(-) diff --git a/Cache/Requests.lean b/Cache/Requests.lean index 708ca2515f4c46..783ab6e27ea012 100644 --- a/Cache/Requests.lean +++ b/Cache/Requests.lean @@ -500,18 +500,30 @@ structure DecompConfig where isMathlibRoot : Bool mathlibDepPath : FilePath -private structure TransferState where - last : Nat - success : Nat - failed : Nat - done : Nat - speed : Nat - -- Decompression state (only used when decompConfig is set) - pending : Array (FilePath × Lean.Name) -- files waiting to be decompressed - currentTask : Option (Task (Except IO.Error Unit)) -- current leantar task - lastBatchSize : Nat -- size of the last dispatched batch - decompressed : Nat -- total files decompressed - decompFailed : Nat -- total decompression failures +/-- Decompression pipeline state, carried from each download round into the +next. A round can end with downloads queued (`pending`) or in a running +leantar batch (`currentTask`); `downloadFiles` hands each round's final state +to the next, and `finalizeDecomp` drains what remains after the last round. -/ +structure DecompState where + /-- Downloaded files waiting to be dispatched in a leantar batch. -/ + pending : Array (FilePath × Lean.Name) := #[] + /-- The in-flight leantar batch, if any. -/ + currentTask : Option (Task (Except IO.Error Unit)) := none + /-- Size of the batch `currentTask` is processing. -/ + lastBatchSize : Nat := 0 + /-- Files decompressed, cumulative across rounds. -/ + decompressed : Nat := 0 + /-- Decompression failures, cumulative across rounds. -/ + decompFailed : Nat := 0 + +structure TransferState where + last : Nat := 0 + success : Nat := 0 + failed : Nat := 0 + done : Nat := 0 + speed : Nat := 0 + /-- Decompression pipeline state; used only when a `DecompConfig` is set. -/ + decomp : DecompState := {} /-- Harvest the result of a completed decompression task, updating counters. Returns `(successful, failed, error?)`. -/ @@ -528,6 +540,26 @@ def dispatchDecompBatch (pending : Array (FilePath × Lean.Name)) (config : Deco let task ← IO.asTask (decompressBatch pending config.force config.isMathlibRoot config.mathlibDepPath) return some task +/-- Drain the decompression pipeline after the last download round: harvest the +in-flight leantar batch, then decompress the pending files. Returns the final +`(decompressed, decompFailed)` counters. -/ +def finalizeDecomp (state : DecompState) (config : DecompConfig) : IO (Nat × Nat) := do + let mut {pending, currentTask, lastBatchSize, decompressed, decompFailed} := state + if let some task := currentTask then + let (d, f, err?) := harvestDecompTask task lastBatchSize decompressed decompFailed + decompressed := d + decompFailed := f + if let some e := err? then + IO.eprintln s!"Decompression error: {e}" + if !pending.isEmpty then + try + decompressBatch pending config.force config.isMathlibRoot config.mathlibDepPath + decompressed := decompressed + pending.size + catch e => + IO.eprintln s!"Decompression error: {e}" + decompFailed := decompFailed + pending.size + return (decompressed, decompFailed) + /-- Whether an HTTP status is the one Azure returns for a blob that already exists, which a non-overwrite `put` (`If-None-Match: *`) hits when it declines to @@ -542,6 +574,7 @@ def isAlreadyPresentStatus (httpCode : Nat) : Bool := def monitorCurl (args : Array String) (size : Nat) (caption : String) (speedVar : String) (removeOnError := false) (decompConfig : Option DecompConfig := none) + (decompState : DecompState := {}) (treatForbiddenAsMiss : Bool := false) (treatExistsAsSkip : Bool := false) : IO (TransferState × Std.HashSet UInt64) := do let useAnsi := (← IO.getEnv "TERM").isSome @@ -556,18 +589,19 @@ def monitorCurl (args : Array String) (size : Nat) let mut msg := s!"\r{caption}: {s.success} file(s) [attempted {s.done}/{size} = {100*s.done/size}%{speedStr}]" -- Add decompression progress if enabled if decompConfig.isSome then - msg := msg ++ s!", Decompressed: {s.decompressed}" - if s.decompFailed != 0 then - msg := msg ++ s!" ({s.decompFailed} failed)" + msg := msg ++ s!", Decompressed: {s.decomp.decompressed}" + if s.decomp.decompFailed != 0 then + msg := msg ++ s!" ({s.decomp.decompFailed} failed)" if s.failed != 0 then msg := msg ++ s!", {s.failed} download failed" -- Clear to end of line to avoid remnants from longer previous messages if useAnsi then msg := msg ++ "\x1b[K" return msg - let init : TransferState := ⟨← IO.monoMsNow, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ + let init : TransferState := { last := (← IO.monoMsNow), decomp := decompState } let s ← IO.runCurlStreaming args init fun a line => do - let mut {last, success, failed, done, speed, pending, currentTask, lastBatchSize, decompressed, decompFailed} := a + let mut {last, success, failed, done, speed, decomp} := a + let mut {pending, currentTask, lastBatchSize, decompressed, decompFailed} := decomp -- output errors other than 404 and remove corresponding partial downloads let line := line.trimAscii if !line.isEmpty then @@ -646,26 +680,32 @@ def monitorCurl (args : Array String) (size : Nat) if now - last ≥ 100 then -- max 10/s update rate speed := match result.getObjValAs? Nat speedVar with | .ok speed => speed | .error _ => speed - IO.eprint (mkStatus {last, success, failed, done, speed, pending, currentTask, lastBatchSize, decompressed, decompFailed}) + let decompNow : DecompState := + {pending, currentTask, lastBatchSize, decompressed, decompFailed} + IO.eprint (mkStatus {last, success, failed, done, speed, decomp := decompNow}) last := now | .error e => IO.println s!"Non-JSON output from curl:\n {line}\n{e}" - pure {last, success, failed, done, speed, pending, currentTask, lastBatchSize, decompressed, decompFailed} + let decompNow : DecompState := + {pending, currentTask, lastBatchSize, decompressed, decompFailed} + pure {last, success, failed, done, speed, decomp := decompNow} if s.done > 0 then -- to avoid confusingly moving on without finishing the count IO.eprintln (mkStatus s) return (s, ← servedRef.get) /-- Run one container's download pass for the given hash map. Returns the -`TransferState` from `monitorCurl` (synthesized in serial mode, where it carries -only the transfer-failure count) and the set of hashes it fetched, so the caller -can carry the rest to the next container. Side effect: any files successfully -fetched are written to `CACHEDIR` with their final names. -/ +`TransferState` from `monitorCurl` (synthesized in serial mode, where it +carries only the transfer-failure count) and the set of hashes it fetched, so +the caller can carry the rest to the next container. `decompState` is the +previous round's decompression pipeline state; the returned state's `decomp` +continues it. Serial mode never pipelines and passes it through untouched. +Side effect: fetched files are written to `CACHEDIR` with their final names. -/ private def downloadFilesFromContainer (container : Option Container) (repo containerURL : String) (hashMap : IO.ModuleHashMap) (parallel : Bool) (decompConfig : Option DecompConfig) - (scope? : Option String) : + (scope? : Option String) (decompState : DecompState) : IO (TransferState × Std.HashSet UInt64) := do let size := hashMap.size if parallel then @@ -680,7 +720,7 @@ private def downloadFilesFromContainer -- whose chain still lists it. let treatForbiddenAsMiss := container == some Container.legacy let (s, served) ← monitorCurl args size "Downloaded" "speed_download" (removeOnError := true) - decompConfig (treatForbiddenAsMiss := treatForbiddenAsMiss) + decompConfig decompState (treatForbiddenAsMiss := treatForbiddenAsMiss) IO.FS.removeFile IO.CURLCFG return (s, served) else @@ -699,7 +739,7 @@ private def downloadFilesFromContainer | .ok .served => (served.insert hash, failed) | .ok .miss => (served, failed) | _ => (served, failed + 1) - return (⟨0, 0, failed, 0, 0, #[], none, 0, 0, 0⟩, served) + return ({ failed, decomp := decompState }, served) /-- Expand the trust-ordered container list into the concrete download rounds to run, each carrying the SHA scope to read at. A round is @@ -758,8 +798,8 @@ def downloadFiles IO.eprintln "No container URLs configured for download" return hashMap.size - -- Set up decompression config if enabled. We keep one config across all - -- container rounds so pipelined decompression continues across them. + -- Set up decompression config if enabled: one config shared by all container + -- rounds, with the pipeline state carried between them via `decompState`. let decompConfig ← if decompress then let hashToMod : Std.HashMap UInt64 Lean.Name := hashMap.fold (init := ∅) fun acc mod hash => acc.insert hash mod @@ -781,9 +821,13 @@ def downloadFiles let rounds := expandDownloadRounds containerURLs scope? unsafeScopes headScope? let unsafeMode := !unsafeScopes.isEmpty let mut remaining := hashMap - let mut finalState : TransferState := ⟨0, 0, 0, 0, 0, #[], none, 0, 0, 0⟩ + -- Decompression pipeline state, carried from each round into the next (see + -- `DecompState`); `finalizeDecomp` below drains what the last round leaves. + let mut decompState : DecompState := {} -- Hard transfer failures (not 404 misses) drive the exit code; misses are -- normal and instead surface as the "not found" hint keyed on `remaining`. + -- Accumulated across rounds: a failure in an early container counts even + -- when a later round serves the file. let mut downloadFailed := 0 -- For the `--unsafe` summary: how many files each scoped (forks) round supplied, -- attributed by the drop in `remaining` across that round. @@ -793,13 +837,14 @@ def downloadFiles let scopeNote := match roundScope? with | some s => s!" (scope {s})" | none => "" IO.println s!"Attempting to download {remaining.size} file(s) from {repo} cache at {url}{scopeNote}" let before := remaining.size - let (s, served) ← downloadFilesFromContainer container? repo url remaining parallel decompConfig roundScope? - -- Keep the latest round's pipeline state and transfer-failure count for the - -- finalization and exit-code logic below. Drop the files this round served so - -- the next container only retries genuine misses, regardless of what is - -- already on disk. - finalState := s - downloadFailed := s.failed + let (s, served) ← downloadFilesFromContainer container? repo url remaining parallel + decompConfig roundScope? decompState + -- Carry the decompression pipeline into the next round and the drain + -- below: files left behind here are never decompressed. Drop the files + -- this round served so the next container only retries genuine misses, + -- regardless of what is already on disk. + decompState := s.decomp + downloadFailed := downloadFailed + s.failed remaining := remaining.filter fun _ hash => !served.contains hash if unsafeMode then if let some sha := roundScope? then @@ -828,27 +873,9 @@ def downloadFiles IO.eprintln " * If you have already opened a PR, this may mean" IO.eprintln " the CI build has failed part-way through building." - -- Finalize decompression: wait for current task and process any remaining files + -- Drain the decompression pipeline accumulated across all rounds. if let some config := decompConfig then - let mut {pending, currentTask, lastBatchSize, decompressed, decompFailed, ..} := finalState - - -- Wait for current task to complete if any - if let some task := currentTask then - let (d, f, err?) := harvestDecompTask task lastBatchSize decompressed decompFailed - decompressed := d - decompFailed := f - if let some e := err? then - IO.eprintln s!"Decompression error: {e}" - - -- Process any remaining pending files - if !pending.isEmpty then - try - decompressBatch pending config.force config.isMathlibRoot config.mathlibDepPath - decompressed := decompressed + pending.size - catch e => - IO.eprintln s!"Decompression error: {e}" - decompFailed := decompFailed + pending.size - + let (decompressed, decompFailed) ← finalizeDecomp decompState config IO.println s!"Decompressed {decompressed} file(s)" if decompFailed > 0 then IO.println s!"{decompFailed} decompression(s) failed" diff --git a/Cache/Test.lean b/Cache/Test.lean index e9aa2298bdefd9..dd8e7eebf19d11 100644 --- a/Cache/Test.lean +++ b/Cache/Test.lean @@ -21,10 +21,14 @@ These tests cover the pure logic of the cache system, including: - CLI flag parsing (`--cache-from`, `--scope`, `--unsafe`, `--repo`, etc.) - `--unsafe` download-round expansion (`expandDownloadRounds`) and the non-default-scope security warning it triggers +- Decompression-pipeline carry across download rounds (`DecompState`, + `finalizeDecomp`, `monitorCurl`) - Utility functions (URL extraction, filename hashing, etc.) -Anything that touches `curl` or the network is left to CI, which exercises the -`cache get`/`put` paths end-to-end on real containers. +Anything that touches the network is left to CI, which exercises the +`cache get`/`put` paths end-to-end on real containers. The unit tests spawn +two local processes, `curl --version` and one leantar run on a nonexistent +archive; neither makes a network request. ## Invariants these tests defend @@ -40,6 +44,10 @@ Anything that touches `curl` or the network is left to CI, which exercises the collide. 5. `legacy` stays readable with its mixed layout (flat for the canonical repo, prefixed for forks) so older clients keep working. +6. Multi-round downloads decompress every file they fetch: the decompression + pipeline state is carried from each container round into the next and + drained after the last one, so a fork-PR `get` leaves no downloaded file + compressed on disk. ## Running the tests @@ -974,6 +982,75 @@ def test_expandDownloadRounds : IO Unit := do end UnsafeRounds +section DecompPipeline + +/-- Shared `DecompConfig` for the pipeline tests. `hashToMod` is unused here; +`isMathlibRoot := true` makes `decompressBatch` treat pending paths as plain +entries, so `mathlibDepPath` is unused too. -/ +private def testDecompConfig : DecompConfig := + { hashToMod := ∅, force := false, isMathlibRoot := true, mathlibDepPath := "." } + +/-- `finalizeDecomp` drains the decompression pipeline after the last download +round: it harvests the in-flight leantar batch, then decompresses the pending +files. A pipeline dropped at a round boundary leaves downloaded files +compressed on disk, forcing a rebuild. This test pins the harvest/counter +logic and the pending-drain failure path; successful pending decompression +needs real archives and is covered by CI. -/ +def test_finalizeDecomp : IO Unit := do + IO.println "finalizeDecomp:" + -- An empty pipeline passes the counters through unchanged. + let (d, f) ← withSuppressedOutput <| + finalizeDecomp { decompressed := 5, decompFailed := 2 } testDecompConfig + assert "empty pipeline passes counters through" (d == 5 && f == 2) + + -- A finished successful batch is harvested into the success counter. + let okTask : Task (Except IO.Error Unit) := Task.pure (.ok ()) + let (d, f) ← withSuppressedOutput <| finalizeDecomp + { currentTask := some okTask, lastBatchSize := 3, decompressed := 5 } testDecompConfig + assert "successful in-flight batch adds its size to decompressed" (d == 8 && f == 0) + + -- A failed batch is harvested into the failure counter, not the success one. + let errTask : Task (Except IO.Error Unit) := Task.pure (.error (IO.userError "boom")) + let (d, f) ← withSuppressedOutput <| finalizeDecomp + { currentTask := some errTask, lastBatchSize := 4, decompressed := 5, decompFailed := 1 } + testDecompConfig + assert "failed in-flight batch adds its size to decompFailed" (d == 5 && f == 5) + + -- Pending files are drained even with no in-flight task; a batch whose + -- leantar invocation fails lands in the failure counter. + let (d, f) ← withSuppressedOutput <| finalizeDecomp + { pending := #[(System.FilePath.mk "cache-test-missing-dir/bogus.ltar", `Mathlib.Bogus)] + decompressed := 5 } testDecompConfig + assert "failed pending drain adds its size to decompFailed" (d == 5 && f == 1) + +/-- A download round returns its decompression pipeline state in +`TransferState.decomp` so `downloadFiles` can hand it to the next round and +the final drain. A round in which curl transfers nothing, e.g. a container +missing every requested file, must return the carried state intact; otherwise +a prior round's queued files would be lost at the round boundary. +`curl --version` drives `monitorCurl` through a real curl spawn with no +downloads and no network. This pins `monitorCurl`'s half of the carry; the +round loop's half is exercised by the CI integration tests. -/ +def test_monitorCurl_carries_decomp_state : IO Unit := do + IO.println "monitorCurl carries decompression state:" + let okTask : Task (Except IO.Error Unit) := Task.pure (.ok ()) + let carried : DecompState := { + pending := #[(System.FilePath.mk "some/file.ltar", `Mathlib.SomeModule)] + currentTask := some okTask + lastBatchSize := 7 + decompressed := 42 + decompFailed := 1 } + let (s, served) ← withSuppressedOutput <| + monitorCurl #["--version"] 1 "Downloaded" "speed_download" (decompState := carried) + assert "no transfers → an empty served set" served.isEmpty + assert "pending files survive the round" (s.decomp.pending.size == 1) + assert "the in-flight task survives the round" s.decomp.currentTask.isSome + assert "the batch size survives the round" (s.decomp.lastBatchSize == 7) + assert "the decompressed counter survives the round" (s.decomp.decompressed == 42) + assert "the decompFailed counter survives the round" (s.decomp.decompFailed == 1) + +end DecompPipeline + def runAll : IO Unit := do test_Container_name test_Container_parse @@ -1002,6 +1079,8 @@ def runAll : IO Unit := do test_isCacheMissStatus test_isAlreadyPresentStatus test_expandDownloadRounds + test_finalizeDecomp + test_monitorCurl_carries_decomp_state end Cache.Test From b56bbad0d9523068b60cf470df47d73e04a9a3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Tue, 28 Jul 2026 16:50:12 +0000 Subject: [PATCH 1061/1300] feat(Tactic/Translate): warn when adding a docstring to an existing declaration (#41883) --- Mathlib/Algebra/Free.lean | 2 +- .../GroupAction/MultiplePrimitivity.lean | 6 +-- Mathlib/Tactic/Translate/Core.lean | 6 +++ .../Topology/Algebra/ContinuousMonoidHom.lean | 5 +- Mathlib/Topology/Algebra/OpenSubgroup.lean | 6 +-- MathlibTest/Attribute/ToAdditive/Basic.lean | 49 +++++++++++++++++++ 6 files changed, 62 insertions(+), 12 deletions(-) diff --git a/Mathlib/Algebra/Free.lean b/Mathlib/Algebra/Free.lean index 92518530e644c4..e337f4ed9af258 100644 --- a/Mathlib/Algebra/Free.lean +++ b/Mathlib/Algebra/Free.lean @@ -319,7 +319,7 @@ inductive AddMagma.AssocRel (α : Type u) [Add α] : α → α → Prop | left : ∀ w x y z, AddMagma.AssocRel α (w + (x + y + z)) (w + (x + (y + z))) /-- Associativity relations for a magma. -/ -@[to_additive AddMagma.AssocRel /-- Associativity relations for an additive magma. -/] +@[to_additive AddMagma.AssocRel] inductive Magma.AssocRel (α : Type u) [Mul α] : α → α → Prop | intro : ∀ x y z, Magma.AssocRel α (x * y * z) (x * (y * z)) | left : ∀ w x y z, Magma.AssocRel α (w * (x * y * z)) (w * (x * (y * z))) diff --git a/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean b/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean index 94543ff1b6bf12..24473cd78efde0 100644 --- a/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean +++ b/Mathlib/GroupTheory/GroupAction/MultiplePrimitivity.lean @@ -94,11 +94,7 @@ class _root_.AddAction.IsMultiplyPreprimitive pretransitive and if, when `n ≥ 1`, for every set `s` of cardinality `n - 1`, the action of `fixingSubgroup M s` on the complement of `s` is preprimitive. -/ -@[mk_iff, to_additive existing -/-- A group action is `n`-multiply preprimitive if it is `n`-multiply -pretransitive and if, when `n ≥ 1`, for every set `s` of cardinality -`n - 1`, the action of `fixingSubgroup M s` on the complement of `s` -is preprimitive. -/] +@[mk_iff, to_additive existing] class IsMultiplyPreprimitive (M α : Type*) [Group M] [MulAction M α] (n : ℕ) where /-- An `n`-preprimitive action is `n`-pretransitive. -/ isMultiplyPretransitive (M α n) : IsMultiplyPretransitive M α n diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index 6e8393352184f4..f4696a0fa9bfe5 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -1275,6 +1275,12 @@ partial def addTranslationAttr (t : TranslateData) (src : Name) (cfg : Config) -- tgt doesn't exist, so let's make it transformDeclRec t cfg src tgt src reorder cfg.rename if let some doc := cfg.doc then + if alreadyExists then + logWarningAt doc <| + if (← findInternalDocString? (← getEnv) tgt).isSome then + m!"The target declaration `{.ofConstName tgt}` already has a docstring." + else + m!"This docstring should be added directly to `{.ofConstName tgt}`." -- TODO: `Syntax.missing` means we do not add binders to the context, -- so the docstring is going to have incomplete syntax highlighting. addDocString tgt Syntax.missing doc |>.run'.run' diff --git a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean index d123cdc9bed642..a824a427214ad4 100644 --- a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean +++ b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean @@ -53,7 +53,7 @@ over `(F : Type*) [FunLike F A B] [ContinuousMapClass F A B] [MonoidHomClass F A When you extend this structure, make sure to extend `ContinuousMapClass` and/or `MonoidHomClass`, if needed. -/ -@[to_additive /-- The type of continuous additive monoid homomorphisms from `A` to `B`. -/] +@[to_additive] structure ContinuousMonoidHom extends A →* B, C(A, B) /-- Reinterpret a `ContinuousMonoidHom` as a `MonoidHom`. -/ @@ -306,8 +306,7 @@ structure ContinuousAddEquiv [Add G] [Add H] extends G ≃+ H, G ≃ₜ H /-- The structure of two-sided continuous isomorphisms between groups. Note that both the map and its inverse have to be continuous. -/ -@[to_additive /-- The structure of two-sided continuous isomorphisms between additive groups. -Note that both the map and its inverse have to be continuous. -/] +@[to_additive] structure ContinuousMulEquiv [Mul G] [Mul H] extends G ≃* H, G ≃ₜ H /-- The homeomorphism induced from a two-sided continuous isomorphism of groups. -/ diff --git a/Mathlib/Topology/Algebra/OpenSubgroup.lean b/Mathlib/Topology/Algebra/OpenSubgroup.lean index 2497511b78960e..f11c46f8ac78a1 100644 --- a/Mathlib/Topology/Algebra/OpenSubgroup.lean +++ b/Mathlib/Topology/Algebra/OpenSubgroup.lean @@ -450,6 +450,8 @@ open scoped Pointwise variable {G : Type*} [TopologicalSpace G] +/-- For a set `W`, `T` is a neighborhood of `0` which is open, stable under negation and satisfies +`T + W ⊆ W`. -/ structure IsTopologicalAddGroup.addNegClosureNhd (T W : Set G) [AddGroup G] : Prop where nhds : T ∈ 𝓝 0 neg : -T = T @@ -458,9 +460,7 @@ structure IsTopologicalAddGroup.addNegClosureNhd (T W : Set G) [AddGroup G] : Pr /-- For a set `W`, `T` is a neighborhood of `1` which is open, stable under inverse and satisfies `T * W ⊆ W`. -/ -@[to_additive -/-- For a set `W`, `T` is a neighborhood of `0` which is open, stable under negation and satisfies -`T + W ⊆ W`. -/] +@[to_additive] structure IsTopologicalGroup.mulInvClosureNhd (T W : Set G) [Group G] : Prop where nhds : T ∈ 𝓝 1 inv : T⁻¹ = T diff --git a/MathlibTest/Attribute/ToAdditive/Basic.lean b/MathlibTest/Attribute/ToAdditive/Basic.lean index 2be7a076c0153c..0aed4e4bcdb321 100644 --- a/MathlibTest/Attribute/ToAdditive/Basic.lean +++ b/MathlibTest/Attribute/ToAdditive/Basic.lean @@ -1023,3 +1023,52 @@ info: @add_comm_alias : ∀ {G : Type u_1} [inst : AddCommMagma G] (a b : G), a -/ #guard_msgs in #check @add_comm_alias + +/-! Warning when adding docstrings to existing declarations -/ + +namespace ExistingDeclDocstring + +/-- Existing docstring -/ +opaque add (G : Type*) [AddGroup G] : Prop + +/-- warning: The target declaration `add` already has a docstring. -/ +#guard_msgs in +@[to_additive existing /-- New docstring -/] +opaque mul (G : Type*) [Group G] : Prop + +/-- warning: The target declaration `self` already has a docstring. -/ +#guard_msgs in +/-- Existing docstring -/ +@[to_additive self (reorder := x y) /-- New docstring -/] +opaque self (x y : Nat) : Prop + +/-- Existing docstring -/ +structure addStruct (G : Type*) [AddGroup G] where + +/-- warning: The target declaration `addStruct` already has a docstring. -/ +#guard_msgs in +@[to_additive /-- New docstring -/] +structure mulStruct (G : Type*) [Group G] where + +-- Examples with no pre-existing docstring + +opaque add' (G : Type*) [AddGroup G] : Prop + +/-- warning: This docstring should be added directly to `add'`. -/ +#guard_msgs in +@[to_additive existing /-- New docstring -/] +opaque mul' (G : Type*) [Group G] : Prop + +/-- warning: This docstring should be added directly to `self'`. -/ +#guard_msgs in +@[to_additive self (reorder := x y) /-- New docstring -/] +opaque self' (x y : Nat) : Prop + +structure addStruct' (G : Type*) [AddGroup G] where + +/-- warning: This docstring should be added directly to `addStruct'`. -/ +#guard_msgs in +@[to_additive /-- New docstring -/] +structure mulStruct' (G : Type*) [Group G] where + +end ExistingDeclDocstring From c7202db459de001e1f4dcbe9cc244a2be198010f Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Tue, 28 Jul 2026 17:44:16 +0000 Subject: [PATCH 1062/1300] feat: define Fredholm operators between TVSs (#41189) Project started during the May 2026 workshop "Techniques and Tools for the Formalization of Analysis" at ICERM. Co-authored-by: Jon Bannon Co-authored-by: Yongxi (Aaron) Lin Co-authored-by: Patrick Massot Co-authored-by: Oliver Nash Co-authored-by: Filippo A. E. Nuccio Co-authored-by: Oliver Nash Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib.lean | 1 + .../Algebra/Module/LinearMap/FiniteRange.lean | 4 + .../Normed/Operator/Fredholm/Basic.lean | 374 ++++++++++++++++++ 3 files changed, 379 insertions(+) create mode 100644 Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4f8048b995b19c..d5e389a4ee4b99 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2256,6 +2256,7 @@ public import Mathlib.Analysis.Normed.Operator.Conformal public import Mathlib.Analysis.Normed.Operator.ContinuousAlgEquiv public import Mathlib.Analysis.Normed.Operator.ContinuousLinearMap public import Mathlib.Analysis.Normed.Operator.Extend +public import Mathlib.Analysis.Normed.Operator.Fredholm.Basic public import Mathlib.Analysis.Normed.Operator.FredholmAlternative public import Mathlib.Analysis.Normed.Operator.LinearIsometry public import Mathlib.Analysis.Normed.Operator.Mul diff --git a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean index c3109ab524ca7b..b3d308793cfde2 100644 --- a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean +++ b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean @@ -336,6 +336,10 @@ lemma IsLeftQuasiInverse.equiv {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V lemma IsRightQuasiInverse.equiv {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} (h : u.IsRightQuasiInverse v) : v ∘ₗ u ≈ .id := h +lemma _root_.LinearEquiv.isQuasiInverse (e : V ≃ₗ[K] V₂) : + e.symm.IsQuasiInverse e := by + simp [IsQuasiInverse, IsLeftQuasiInverse, IsRightQuasiInverse] + @[symm] lemma IsQuasiInverse.symm {u : V₃ →ₗ[K] V₂} {v : V₂ →ₗ[K] V₃} (h : u.IsQuasiInverse v) : v.IsQuasiInverse u := diff --git a/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean b/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean new file mode 100644 index 00000000000000..63dec73d83bd64 --- /dev/null +++ b/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean @@ -0,0 +1,374 @@ +/- +Copyright (c) 2026 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jon Bannon, Anatole Dedecker, Yongxi Lin, Patrick Massot, Oliver Nash, Filippo A. E. Nuccio +-/ +module + +public import Mathlib.Analysis.Normed.Operator.Perturbation.StrictByFinite + +/-! +# Fredholm operators between topological vector spaces + +Fix `𝕜` a complete `NontriviallyNormedField`, and let `E`, `F` be two Hausdorff topological vector +spaces over `𝕜`. + +We say that a continuous linear map `T : E →L[𝕜] F` is a **Fredholm operator** if it satisfies +the following four equivalent conditions: + +1. `T` is strict, its range is closed and has finite codimension, and its kernel is (topologically) + complemented and has finite dimension. This is chosen as the definition, see `IsFredholm`. +2. `T` admits a continuous **quasi-inverse**, in the sense of `LinearMap.IsQuasiInverse`. +3. There are closed finite-codimension subspaces `E₁` and `F₁` of `E` and `F` between which `T` + induces an isomorphism. +4. `T` admits a `FredholmPackage`: there are topological decompositions `E = E₁ ⊕ E₀`, + `F = F₁ ⊕ F₀`, where `E₀` and `F₀` are finite dimensional, and an isomorphism `Φ : E₁ ≃L[𝕜] F₁` + such that `T` is zero on `E₀` and coincides with `Φ` on `E₁`; in other words, in these + decompositions, `T` is given by the matrix $\begin{pmatrix} Φ & 0 \cr 0 & 0 \end{pmatrix}$. + +## Main definitions + +* `ContinuousLinearMap.IsFredholm`: a continuous linear map `u : E →L[𝕜] F` is a + **Fredholm operator** if it is strict, its range is closed and has finite codimension, and its + kernel is (topologically) complemented and has finite dimension. +* `FredholmDecomposition`: a **Fredholm decomposition** of a topological vector space `E` is the + data of two subspaces `X₀` and `X₁` which are topological complements, and where `X₀` is finite + dimensional. +* `ContinuousLinearMap.FredholmPackage`: a **Fredholm package** for `u : E →L[𝕜] F` is the data of + Fredholm decompositions `decDom` and `decCodom` of `E` and `F` respectively, together with + a continuous linear equivalence `equiv : decDom.X₁ ≃L[𝕜] decCodom.X₁` between the "essential" + (i.e. finite codimension) parts of these decompositions, such that `u` equals the composition + `decCodom.X₁.subtypeL ∘L equiv ∘L decDom.proj`. + +Note that the data of a `FredholmPackage` for an operator is morally the strongest of the +equivalent ways to assume that `u` is Fredholm (for example, it is clear how to build a canonical +continuous quasi-inverse of `u` from such a package). + +Hence, you should not typically prove that an operator is Fredholm by building a Fredholm package +(consider using `IsFredholm.of_isInvertible_restrict`); instead, when you know that an operator is +Fredholm, you can obtain a `FredholmPackage` from `IsFredholm.nonempty_fredholmPackage` +in order to conveniently use the full strength of Fredholmness. + +## Main statements + +### Equivalent criteria + +* `ContinuousLinearMap.isFredholm_tfae`: the equivalence between conditions 1, 2, 3 and 4 above. + In practice, most of the interesting directions should be covered by specific API lemmas. +* `ContinuousLinearMap.FredholmPackage.isQuasiInverse`: given a `FredholmPackage` for `u`, + one can build a canonical continuous quasi-inverse of `u`. +* `ContinuousLinearMap.IsFredholm.of_isInvertible_restrict`: if a continuous linear map induces + an isomorphism between finite codimension subspaces, then it is Fredholm. +* `ContinuousLinearMap.IsFredholm.of_restrict` (not in Mathlib yet) is a generalization + of the above: if a continuous linear map induces a Fredholm operator between finite codimension + subspaces, then the original map is Fredholm as well. +* `IsFredholm.nonempty_fredholmPackage`: every Fredholm operator admits a Fredholm package. + This is the primary way to obtain Fredholm packages. + +## Implementation details + +We largely follow [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 2][bourbaki2023], +in particular for the proof of equivalence of the four conditions above. +Here are some notable changes: + +* Bourbaki restricts itself to locally convex spaces over `ℝ` or `ℂ`. Yet, under close inspection, + this assumption plays very little role in the beginning of the theory. In fact, at the very mild + cost of assuming that the kernel is complemented in the definition of `IsFredholm` (which follows + from the finiteness assumption if Hahn-Banach is available), we generalize the beginning of the + theory to topological vector spaces over any complete nontrivially normed field. In particular, + our theory naturally captures p-adic Fredholm operators. +* Bourbaki chooses the existence of a continuous quasi-inverse as the definition of being Fredholm. + Our choice differs for a very practical reason: it is much simpler to spell out formally + "`u` has a continuous quasi-inverse" than "`u` is strict, its range is closed and has finite + codimension, and its kernel is complemented and has finite dimension". Hence we prefer to give + a name to the latter. + +## References + +* [N. Bourbaki, *Théories Spectrales*, Chapitre III, § 3, n° 2][bourbaki2023] +-/ + +@[expose] public noncomputable section + +open Topology Submodule LinearMap +open Set (MapsTo) +open LinearMap.FiniteRangeSetoid + +namespace ContinuousLinearMap +section TVS + +variable {𝕜 E F : Type*} [NontriviallyNormedField 𝕜] [AddCommGroup E] [AddCommGroup F] + [Module 𝕜 E] [Module 𝕜 F] [TopologicalSpace E] [TopologicalSpace F] + +/-! +## Definition and equivalent conditions +-/ + +section DefTFAE + +section IsFredholm + +/-- A continuous linear map `u : E →L[𝕜] F` is a **Fredholm operator** if it is strict, +its range is closed and has finite codimension, and its kernel is (topologically) complemented and +has finite dimension. + +See also `isFredholm_tfae` for other equivalent characterizations. +We will also prove later (not in Mathlib yet) that for maps between Banach (or even Fréchet) +spaces over `ℝ` or `ℂ`, all the conditions follow from the kernel and cokernel having finite +dimension. -/ +structure IsFredholm (u : E →L[𝕜] F) : Prop where + isStrictMap : IsStrictMap u + isClosed_range : IsClosed (u.range : Set F) + finite_ker : FiniteDimensional 𝕜 u.ker + finite_coker : u.range.CoFG + closedComplemented_ker : u.ker.ClosedComplemented + +variable [CompleteSpace 𝕜] [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] in +/-- A Fredholm operator has (topologically) complemented range. -/ +lemma IsFredholm.closedComplemented_range {u : E →L[𝕜] F} (u_fred : IsFredholm u) : + u.range.ClosedComplemented := + have := u_fred.finite_coker + ClosedComplemented.of_finiteDimensional_quotient u_fred.isClosed_range + +end IsFredholm + +section FredholmPackage + +variable (𝕜 E) in +/-- A **Fredholm decomposition** of a topological vector space `E` is the data of two subspaces +`X₀` and `X₁` which are topological complements, and where `X₀` is finite dimensional. + +Note that we purposefully use the index `₀` for the "inessential" (i.e. finite dimensional) +part of the decomposition. -/ +structure _root_.FredholmDecomposition where + /-- The inessential (i.e. finite dimensional) part of a Fredholm decomposition. -/ + X₀ : Submodule 𝕜 E + /-- The essential (i.e. finite codimensional) part of a Fredholm decomposition. -/ + X₁ : Submodule 𝕜 E + isTopCompl : IsTopCompl X₁ X₀ + finite_X₀ : FiniteDimensional 𝕜 X₀ + +/-- Given a Fredholm decomposition `dec` of the space `E`, `dec.proj` is the (continuous linear) +projection onto the "essential part" `dec.X₁` along the "inessential part" `dec.X₀`. +This is a Fredholm operator. -/ +abbrev _root_.FredholmDecomposition.proj (dec : FredholmDecomposition 𝕜 E) : + E →L[𝕜] dec.X₁ := dec.X₁.projectionOntoL dec.X₀ dec.isTopCompl + +/-- Let `u : E →L[𝕜] F` be a continuous linear map. A **Fredholm package** for `u` is the data of +Fredholm decompositions `decDom` and `decCodom` of `E` and `F` respectively, together with +a continuous linear equivalence `equiv : decDom.X₁ ≃L[𝕜] decCodom.X₁` between the "essential" +(i.e. finite codimension) parts of these decompositions, such that `u` equals the composition +`decCodom.X₁.subtypeL ∘L equiv ∘L decDom.proj`. In other words, in these +"essential ⊕ inessential" decompositions, the matrix of `u` is +$\begin{pmatrix} \texttt{equiv} & 0 \cr 0 & 0 \end{pmatrix}$. + +We will show in `isFredholm_tfae` that an operator is Fredholm if and only if it admits +a Fredholm package. In practice, the condition that `u` is Fredholm (`IsFredholm`) is always easier +to prove, so if you need a Fredholm package you should probably get it from +`IsFredholm.nonempty_fredholmPackage` or `IsFredholm.fredholmPackage`. -/ +structure FredholmPackage (u : E →L[𝕜] F) where + /-- A `FredholmDecomposition` of the domain. -/ + decDom : FredholmDecomposition 𝕜 E + /-- A `FredholmDecomposition` of the codomain. -/ + decCodom : FredholmDecomposition 𝕜 F + /-- An isomorphism between the essential parts of `decDom` and `decCodom`. -/ + equiv : decDom.X₁ ≃L[𝕜] decCodom.X₁ + eq_equiv : u = decCodom.X₁.subtypeL ∘L equiv ∘L decDom.proj + +lemma FredholmPackage.ker_eq {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + u.ker = pkg.decDom.X₀ := by simp [pkg.eq_equiv, ker_comp] + +lemma FredholmPackage.range_eq {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + u.range = pkg.decCodom.X₁ := by + simp [pkg.eq_equiv, range_comp] + +lemma FredholmPackage.mapsTo {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + MapsTo u pkg.decDom.X₁ pkg.decCodom.X₁ := by + simpa [← FredholmPackage.range_eq, LinearMap.coe_range] using Set.mapsTo_range _ _ + +lemma FredholmPackage.equiv_eq_restrict {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + pkg.equiv = u.restrict pkg.mapsTo := by + ext x + simp [pkg.eq_equiv] + +lemma FredholmPackage.isInvertible_restrict {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + u.restrict pkg.mapsTo |>.IsInvertible := + ⟨pkg.equiv, pkg.equiv_eq_restrict⟩ + +/-- The data of a Fredholm package for `u` determines a canonical quasi-inverse of `u`. -/ +def FredholmPackage.quasiInverse {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + F →L[𝕜] E := + pkg.decDom.X₁.subtypeL ∘L pkg.equiv.symm ∘L pkg.decCodom.proj + +/-- The data of a Fredholm package for `u` determines a canonical quasi-inverse of `u`. -/ +lemma FredholmPackage.isQuasiInverse {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + pkg.quasiInverse.IsQuasiInverse u := by + nth_rw 2 [pkg.eq_equiv] + have hdom : IsQuasiInverse pkg.decDom.X₁.subtype pkg.decDom.proj := + have := pkg.decDom.finite_X₀ + isQuasiInverse_subtype_projectionOnto _ + have hcodom : IsQuasiInverse pkg.decCodom.X₁.subtype pkg.decCodom.proj := + have := pkg.decCodom.finite_X₀ + isQuasiInverse_subtype_projectionOnto _ + -- For some reason `exact` and `refine` are slow here! + apply hdom.comp (pkg.equiv.isQuasiInverse.comp hcodom.symm) + +end FredholmPackage + +variable [T2Space E] [T2Space F] in +/-- Assume that `u : E →L[𝕜] F` has a continuous quasi-inverse. Then there are closed +subspaces of finite codimensions `E₁` and `F₁` between which `u` induces an isomorphism. + +This statement is private because it is superseded by later results: using `isFredholm_tfae`, +you can build a `FredholmPackage` for `u`, and then apply `FredholmPackage.isInvertible_restrict`. +-/ +private theorem exists_restrict_isInvertible_of_isQuasiInverse {u : E →L[𝕜] F} + {v : F →L[𝕜] E} (hvu : v.IsQuasiInverse u) : + ∃ (E₁ : Submodule 𝕜 E) (F₁ : Submodule 𝕜 F), + IsClosed (E₁ : Set E) ∧ IsClosed (F₁ : Set F) ∧ + E₁.CoFG ∧ F₁.CoFG ∧ + ∃ h : MapsTo u E₁ F₁, (u.restrict h).IsInvertible := by + obtain ⟨hvu, huv⟩ := hvu + rw [IsRightQuasiInverse, Setoid.comm, equiv_iff_eqLocus_coFG] at huv + rw [IsLeftQuasiInverse, Setoid.comm, equiv_iff_eqLocus_coFG] at hvu + set E₁ := (ContinuousLinearMap.id 𝕜 E).eqLocus (v ∘L u) + set F₁ := (ContinuousLinearMap.id 𝕜 F).eqLocus (u ∘L v) + have u_mapsto : MapsTo u E₁ F₁ := fun x hx ↦ congr(u $hx) + have v_mapsto : MapsTo v F₁ E₁ := fun x hx ↦ congr(v $hx) + refine ⟨E₁, F₁, isClosed_eqLocus _ _, isClosed_eqLocus _ _, hvu, huv, u_mapsto, ?_⟩ + refine .of_inverse (g := v.restrict v_mapsto) ?_ ?_ + · ext ⟨x, hx : x = u (v x)⟩ + simp [coe_restrict_apply u_mapsto, coe_restrict_apply v_mapsto, ← hx] + · ext ⟨x, hx : x = v (u x)⟩ + simp [coe_restrict_apply u_mapsto, coe_restrict_apply v_mapsto, ← hx] + +variable [CompleteSpace 𝕜] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] + +/-- Assume that `u : E →L[𝕜] F` restricts to an isomorphism between closed finite codimension +subspaces `E₁` and `F₁`. Then `u` is Fredholm. + +In fact it is enough to assume that the restriction `E₁ →L[𝕜] F₁` is Fredholm, see +`IsFredholm.of_restrict` (not in Mathlib yet). -/ +theorem IsFredholm.of_isInvertible_restrict {u : E →L[𝕜] F} + {E₁ : Submodule 𝕜 E} (E₁_closed : IsClosed (E₁ : Set E)) [E₁_coFG : E₁.CoFG] + {F₁ : Submodule 𝕜 F} (F₁_closed : IsClosed (F₁ : Set F)) [F₁_coFG : F₁.CoFG] + (h_mapsto : MapsTo u E₁ F₁) (h_inv : (u.restrict h_mapsto).IsInvertible) : + IsFredholm u := by + obtain ⟨e, he⟩ := h_inv + have eqL : u.domRestrict E₁ = F₁.subtypeL ∘L e := congr(F₁.subtypeL ∘L $he).symm + have eqₗ : u.toLinearMap.domRestrict E₁ = F₁.subtype ∘ₗ e := congr(($eqL).toLinearMap) + have h : Topology.IsStrictMap u ∧ IsClosed (u.range : Set F) := by + rw [u.isStrictMap_isClosed_range_iff_restrict E₁ E₁_closed, eqL] + exact ⟨F₁.isEmbedding_subtype.comp e.isHomeomorph.isEmbedding |>.isStrictMap, by simpa⟩ + have disj : Disjoint E₁ u.ker := by + rw [disjoint_iff_comap_eq_bot, ← LinearMap.ker_domRestrict, eqₗ, + LinearMap.ker_comp, ker_subtype, comap_bot, LinearEquiv.ker] + refine ⟨h.1, h.2, ?_, ?_, ?_⟩ + · rw [← Submodule.fg_iff_finiteDimensional] + exact E₁_coFG.fg_of_disjoint disj.symm + · refine F₁_coFG.of_le (le_trans ?_ (u.range_domRestrict_le_range E₁)) + rw [eqₗ, LinearMap.range_comp, LinearEquiv.range, Submodule.map_top, range_subtype] + · exact .of_disjoint_of_finiteDimensional_quotient E₁_closed disj.symm + +omit [ContinuousSMul 𝕜 E] in +/-- Let `u : E →L[𝕜] F` be a Fredholm operator. Given `dom₁` (resp. `codom₀`) an arbitrary +topological complement of `u.ker` (resp. `u.range`), we get a `FredholmPackage` for `u` +by considering the decompositions `E = dom₁ ⊕ u.ker`, `F = u.range ⊕ codom₀`, and the isomorphism +`dom₁ ≃L[𝕜] u.range` induced by `u`. + +If you need control over the decompositions, this is the primary way to get a `FredholmPackage`. +Otherwise, see `IsFredholm.nonempty_fredholmPackage`. -/ +def IsFredholm.fredholmPackage {u : E →L[𝕜] F} + (u_fred : IsFredholm u) {dom₁ : Submodule 𝕜 E} {codom₀ : Submodule 𝕜 F} + (h_dom : IsTopCompl u.ker dom₁) (h_codom : IsTopCompl u.range codom₀) : + FredholmPackage u where + decDom := + { X₀ := u.ker + X₁ := dom₁ + isTopCompl := h_dom.symm + finite_X₀ := u_fred.finite_ker } + decCodom := + { X₀ := codom₀ + X₁ := u.range + isTopCompl := h_codom + finite_X₀ := .of_fg <| u_fred.finite_coker.fg_of_isCompl h_codom.isCompl } + equiv := + letI Φ : dom₁ ≃L[𝕜] E ⧸ u.ker := u.ker.quotientEquivOfIsTopCompl dom₁ h_dom |>.symm + letI Ψ : (E ⧸ u.ker) ≃L[𝕜] u.range := .quotKerEquivRange u_fred.isStrictMap + Φ.trans Ψ + eq_equiv := by + refine LinearMap.ext_on_codisjoint h_dom.isCompl.codisjoint ?_ ?_ + · intro x (hx : u x = 0) + simp [hx, projection_apply_of_mem_right] + · intro x (hx : x ∈ dom₁) + simp [hx, projection_apply_of_mem_left, ContinuousLinearEquiv.quotKerEquivRange] + +omit [ContinuousSMul 𝕜 E] in +/-- Every Fredholm operator admits a `FredholmPackage`. + +This is the primary way to get a `FredholmPackage` if you don't need control of the decompositions. +If you do, see `IsFredholm.fredholmPackage`. -/ +theorem IsFredholm.nonempty_fredholmPackage {u : E →L[𝕜] F} + (u_fred : IsFredholm u) : Nonempty (FredholmPackage u) := by + obtain ⟨codom₀, h_codom⟩ := u_fred.closedComplemented_range.exists_isTopCompl + obtain ⟨dom₁, h_dom⟩ := u_fred.closedComplemented_ker.exists_isTopCompl + exact ⟨u_fred.fredholmPackage h_dom h_codom⟩ + +variable [T2Space E] [T2Space F] + +/-- +Let `E`, `F` be two Hausdorff topological vector spaces over a complete `NontriviallyNormedField` +denoted `𝕜`, and `u : E →L[𝕜] F` a continuous linear map. The following conditions are equivalent: + +1. `u` is a **Fredholm operator**, in the sense of `ContinuousLinearMap.IsFredholm`. +2. `u` admits a continuous **quasi-inverse**, in the sense of `LinearMap.IsQuasiInverse`. +3. There are closed finite-codimension subspaces `E₁` and `F₁` of `E` and `F` between which `u` + induces an isomorphism. +4. `u` admits a `FredholmPackage`. + +In practice, condition `4` is the "strongest", so you should probably not use it to *prove* that an +operator is Fredholm. +-/ +theorem isFredholm_tfae (u : E →L[𝕜] F) : + [ IsFredholm u, + ∃ v : F →L[𝕜] E, v.IsQuasiInverse u, + ∃ (E₁ : Submodule 𝕜 E) (F₁ : Submodule 𝕜 F), + IsClosed (E₁ : Set E) ∧ IsClosed (F₁ : Set F) ∧ + E₁.CoFG ∧ F₁.CoFG ∧ + ∃ h : MapsTo u E₁ F₁, (u.restrict h).IsInvertible, + Nonempty (FredholmPackage u) ].TFAE := by + tfae_have 1 → 4 := IsFredholm.nonempty_fredholmPackage + tfae_have 4 → 2 := by + rintro ⟨dec⟩ + exact ⟨dec.quasiInverse, dec.isQuasiInverse⟩ + tfae_have 2 → 3 := by + rintro ⟨v, huv⟩ + exact exists_restrict_isInvertible_of_isQuasiInverse huv + tfae_have 3 → 1 := by + rintro ⟨E₁, F₁, E₁_closed, F₁_closed, E₁_coFG, F₁_coFG, u_mapsto, u_invertible⟩ + exact .of_isInvertible_restrict E₁_closed F₁_closed u_mapsto u_invertible + tfae_finish + +/-- If `u` has a Fredholm package, it is Fredholm. -/ +theorem FredholmPackage.isFredholm {u : E →L[𝕜] F} (pkg : FredholmPackage u) : + IsFredholm u := + isFredholm_tfae u |>.out 3 0 |>.mp (Nonempty.intro pkg) + +theorem isFredholm_iff_exists_isQuasiInverse {u : E →L[𝕜] F} : + IsFredholm u ↔ ∃ v : F →L[𝕜] E, v.IsQuasiInverse u := + isFredholm_tfae u |>.out 0 1 + +alias ⟨IsFredholm.exists_isQuasiInverse, _⟩ := isFredholm_iff_exists_isQuasiInverse + +theorem IsFredholm.of_isQuasiInverse {u : E →L[𝕜] F} {v : F →L[𝕜] E} (h : v.IsQuasiInverse u) : + IsFredholm u := + isFredholm_iff_exists_isQuasiInverse.mpr ⟨v, h⟩ + +end DefTFAE + +end TVS +end ContinuousLinearMap + +end From 01cceef4309e0b28bde5dd951c72960f5282a1ac Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:44:18 +0000 Subject: [PATCH 1063/1300] chore: make `ModelProd` and `ModelPi` implicit_reducible (#42038) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They should not be instance reducible (their entire raison d'être is to be a type synonym to disambiguate typeclass synthesis), but they can be implicit_reducible just fine. This allows removing another 10-20 backcompat options. --- Mathlib/Geometry/Manifold/Algebra/Structures.lean | 3 +-- Mathlib/Geometry/Manifold/ChartedSpace.lean | 3 ++- Mathlib/Geometry/Manifold/Immersion.lean | 2 -- Mathlib/Geometry/Manifold/IsManifold/Basic.lean | 8 ++------ Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean | 2 -- .../Geometry/Manifold/IsManifold/InteriorBoundary.lean | 1 - Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean | 1 - Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean | 1 - Mathlib/Geometry/Manifold/Submersion.lean | 1 - 9 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Algebra/Structures.lean b/Mathlib/Geometry/Manifold/Algebra/Structures.lean index c9936acb6eca2a..c215bd92f33704 100644 --- a/Mathlib/Geometry/Manifold/Algebra/Structures.lean +++ b/Mathlib/Geometry/Manifold/Algebra/Structures.lean @@ -48,7 +48,6 @@ instance (priority := 100) ContMDiffRing.toLieAddGroup (I : ModelWithCorners end ContMDiffRing -set_option backward.isDefEq.respectTransparency false in -- see Note [lower instance priority] instance (priority := 100) instFieldContMDiffRing {𝕜 : Type*} [NontriviallyNormedField 𝕜] {n : ℕ∞ω} : @@ -57,7 +56,7 @@ instance (priority := 100) instFieldContMDiffRing contMDiff_mul := by rw [contMDiff_iff] refine ⟨continuous_mul, fun x y => ?_⟩ - simp only [mfld_simps] + simp only [mfld_simps, chartAt_self_eq] rw [contDiffOn_univ] exact contDiff_mul } diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 7d8921e0f69e1f..54b6df43372fdd 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -400,11 +400,13 @@ solves this problem. -/ /-- Same thing as `H × H'`. We introduce it for technical reasons, see note [Manifold type tags]. -/ +@[implicit_reducible] def ModelProd (H : Type*) (H' : Type*) := H × H' /-- Same thing as `∀ i, H i`. We introduce it for technical reasons, see note [Manifold type tags]. -/ +@[implicit_reducible] def ModelPi {ι : Type*} (H : ι → Type*) := ∀ i, H i @@ -462,7 +464,6 @@ theorem prodChartedSpace_chartAt : chartAt (ModelProd H H') x = (chartAt H x.fst).prod (chartAt H' x.snd) := rfl -set_option backward.isDefEq.respectTransparency false in theorem chartedSpaceSelf_prod : prodChartedSpace H H H' H' = chartedSpaceSelf (H × H') := by ext1 · simp [atlas, ChartedSpace.atlas] diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index e5833d62e83de1..fa4107315b6225 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -360,7 +360,6 @@ lemma _root_.IsOpen.isImmersionAtOfComplement : IsOpen {x | IsImmersionAtOfComplement F I J n f x} := IsOpen.liftSourceTargetPropertyAt -set_option backward.isDefEq.respectTransparency false in /-- If `f: M → N` and `g: M' × N'` are immersions at `x` and `x'`, respectively, then `f × g: M × N → M' × N'` is an immersion at `(x, x')`. -/ theorem prodMap {f : M → N} {g : M' → N'} {x' : M'} @@ -631,7 +630,6 @@ lemma congr_iff (hfg : f =ᶠ[𝓝 x] g) : IsImmersionAt I J n f x ↔ IsImmersionAt I J n g x := ⟨fun h ↦ h.congr_of_eventuallyEq hfg, fun h ↦ h.congr_of_eventuallyEq hfg.symm⟩ -set_option backward.isDefEq.respectTransparency false in /- The set of points where `IsImmersionAt` holds is open. -/ lemma _root_.IsOpen.isImmersionAt : IsOpen {x | IsImmersionAt I J n f x} := by diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 7209dff92e77c7..6e654a9d851628 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -517,7 +517,6 @@ def ModelWithCorners.prod {𝕜 : Type u} [NontriviallyNormedField 𝕜] {E : Ty continuous_toFun := I.continuous_toFun.prodMap I'.continuous_toFun continuous_invFun := I.continuous_invFun.prodMap I'.continuous_invFun } -set_option backward.isDefEq.respectTransparency false in /-- Given a finite family of `ModelWithCorners` `I i` on `(E i, H i)`, we define the model with corners `pi I` on `(Π i, E i, ModelPi H)`. See note [Manifold type tags] for explanation about `ModelPi H`. -/ @@ -609,7 +608,6 @@ instance modelWithCornersSelf_boundaryless (𝕜 : Type*) [NontriviallyNormedFie [NormedAddCommGroup E] [NormedSpace 𝕜 E] : (modelWithCornersSelf 𝕜 E).Boundaryless := ⟨by simp⟩ -set_option backward.isDefEq.respectTransparency false in /-- If two model with corners are boundaryless, their product also is -/ instance ModelWithCorners.range_eq_univ_prod {𝕜 : Type u} [NontriviallyNormedField 𝕜] {E : Type v} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type w} [TopologicalSpace H] @@ -617,8 +615,8 @@ instance ModelWithCorners.range_eq_univ_prod {𝕜 : Type u} [NontriviallyNormed [NormedSpace 𝕜 E'] {H' : Type w'} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 E' H') [I'.Boundaryless] : (I.prod I').Boundaryless := by constructor - dsimp [ModelWithCorners.prod, ModelProd] - rw [← prod_range_range_eq, ModelWithCorners.Boundaryless.range_eq_univ, + dsimp + rw [Set.range_prodMap, ModelWithCorners.Boundaryless.range_eq_univ, ModelWithCorners.Boundaryless.range_eq_univ, univ_prod_univ] end Boundaryless @@ -922,7 +920,6 @@ theorem of_discreteTopology [DiscreteTopology M] [Unique E] : attribute [local instance] ChartedSpace.ofDiscreteTopology in example [Unique E] : IsManifold (𝓘(𝕜, E)) n (Fin 2) := of_discreteTopology _ -set_option backward.isDefEq.respectTransparency false in /-- The product of two `C^n` manifolds is naturally a `C^n` manifold. -/ instance prod {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H : Type*} @@ -944,7 +941,6 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {n : ℕ∞ω} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] -set_option backward.isDefEq.respectTransparency false in lemma mem_maximalAtlas_prod [IsManifold I n M] [IsManifold I' n M'] {e : OpenPartialHomeomorph M H} (he : e ∈ maximalAtlas I n M) {e' : OpenPartialHomeomorph M' H'} (he' : e' ∈ maximalAtlas I' n M') : diff --git a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean index 01b4fd14994758..3836a3093b75ff 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean @@ -835,7 +835,6 @@ variable {G G' F F' N N' : Type*} {J : ModelWithCorners 𝕜 F G} {J' : ModelWithCorners 𝕜 F' G'} [ChartedSpace G N] [ChartedSpace G' N'] -set_option backward.isDefEq.respectTransparency false in lemma writtenInExtChartAt_prod {f : M → N} {g : M' → N'} {x : M} {x' : M'} : (writtenInExtChartAt (I.prod I') (J.prod J') (x, x') (Prod.map f g)) = Prod.map (writtenInExtChartAt I J x f) (writtenInExtChartAt I' J' x' g) := by @@ -865,7 +864,6 @@ theorem ext_chart_model_space_apply {x y : E} : extChartAt 𝓘(𝕜, E) x y = y variable {𝕜} -set_option backward.isDefEq.respectTransparency false in theorem extChartAt_prod (x : M × M') : extChartAt (I.prod I') x = (extChartAt I x.1).prod (extChartAt I' x.2) := by simp only [mfld_simps] diff --git a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean index 41b394ff59a95d..276e294f609477 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean @@ -491,7 +491,6 @@ variable {N : Type*} [TopologicalSpace N] [ChartedSpace H' N] {J : ModelWithCorners 𝕜 E' H'} {x : M} {y : N} -set_option backward.isDefEq.respectTransparency false in /-- The interior of `M × N` is the product of the interiors of `M` and `N`. -/ lemma interior_prod : (I.prod J).interior (M × N) = (I.interior M) ×ˢ (J.interior N) := by diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index a3ba6c2a79321c..05bd236682c653 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -479,7 +479,6 @@ theorem MDifferentiableOn.prodMap (hf : MDiff[s] f) (hg : MDiff[r] g) : theorem MDifferentiable.prodMap (hf : MDiff f) (hg : MDiff g) : MDiff (Prod.map f g) := fun p ↦ (hf p.1).prodMap' (hg p.2) -set_option backward.isDefEq.respectTransparency false in lemma HasMFDerivWithinAt.prodMap {s : Set <| M × M'} {p : M × M'} {f : M → N} {g : M' → N'} {df : TangentSpace% p.1 →L[𝕜] TangentSpace% (f p.1)} (hf : HasMFDerivAt[Prod.fst '' s] f p.1 df) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean index f85c3efacc4755..35e2dac56bd170 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean @@ -136,7 +136,6 @@ open Bundle variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {Z : M → Type*} [TopologicalSpace (TotalSpace F Z)] [∀ b, TopologicalSpace (Z b)] [FiberBundle F Z] -set_option backward.isDefEq.respectTransparency false in private lemma UniqueMDiffWithinAt.bundle_preimage_aux {p : TotalSpace F Z} (hs : UniqueMDiffAt[s] p.proj) (h's : s ⊆ (trivializationAt F Z p.proj).baseSet) : UniqueMDiffAt[π F Z ⁻¹' s] p := by diff --git a/Mathlib/Geometry/Manifold/Submersion.lean b/Mathlib/Geometry/Manifold/Submersion.lean index 3396a8f134e912..b3653286e2b5e4 100644 --- a/Mathlib/Geometry/Manifold/Submersion.lean +++ b/Mathlib/Geometry/Manifold/Submersion.lean @@ -335,7 +335,6 @@ lemma _root_.isOpen_isSubmersionAtOfComplement : IsOpen {x | IsSubmersionAtOfComplement F I J n f x} := by exact IsOpen.liftSourceTargetPropertyAt -set_option backward.isDefEq.respectTransparency false in /-- If `f: M → N` and `g: M' → N'` are submersions at `x` and `x'`, respectively, then `f × g: M × M' → N × N'` is a submersion at `(x, x')`. -/ theorem prodMap {f : M → N} {g : M' → N'} {x' : M'} From 0ce898f5af28a9a72054a68b7f6331224e7dc767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Tue, 28 Jul 2026 19:54:07 +0000 Subject: [PATCH 1064/1300] =?UTF-8?q?feat(RingTheory):=20bialgebra=20homs?= =?UTF-8?q?=20`R[G]=20=E2=86=92=20R[H]`=20are=20in=20bijection=20with=20gr?= =?UTF-8?q?oup=20homs=20`G=20=E2=86=92=20H`=20(#41995)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... for abelian groups `G` and `H`. Furthermore, the convolution product on bialgebra homs corresponds to pointwise addition on group homs. Also generate more lemmas through `to_additive`, remove some unused `set_option`s and relocate `MonoidAlgebra.toAdditive`/`AddMonoidAlgebra.toMultiplicative` to existing sections. From Toric --- Mathlib/Algebra/Category/CommHopfAlgCat.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Basic.lean | 2 +- .../RingTheory/Bialgebra/MonoidAlgebra.lean | 384 ++++++++++++++++-- 3 files changed, 342 insertions(+), 46 deletions(-) diff --git a/Mathlib/Algebra/Category/CommHopfAlgCat.lean b/Mathlib/Algebra/Category/CommHopfAlgCat.lean index dcc9eaf20357b6..5e8027f5890233 100644 --- a/Mathlib/Algebra/Category/CommHopfAlgCat.lean +++ b/Mathlib/Algebra/Category/CommHopfAlgCat.lean @@ -140,7 +140,7 @@ def isoMk {X Y : Type v} {_ : CommRing X} {_ : CommRing Y} {_ : HopfAlgebra R X} inv := ofHom (e.symm : Y →ₐc[R] X) /-- Build a `BialgEquiv` from an isomorphism in the category `CommHopfAlgCat R`. -/ --- TODO: Make simp once `BialgEquiv.toCoalgEquiv_eq_coe` is gone. +-- TODO: Make `BialgEquiv.toCoalgEquiv` the simp normal form so that this can be simp @[expose, simps -isSimp] def ofIso (i : A ≅ B) : A ≃ₐc[R] B where __ := i.hom.hom diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index 23fc281e997a9b..99de88ae276954 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -212,7 +212,7 @@ values on the functions `single m 1` and `single 1 a`. See note [partially-applied ext lemmas]. Note that the first assumption isn't written as an equality of `MonoidHom`s because `of` doesn't additivise. -/ @[to_additive (dont_translate := R A B) (attr := ext high) /-- -A `R`-algebra homomorphism from `R[M]` is uniquely defined by its +A `R`-algebra homomorphism from `A[M]` is uniquely defined by its values on the functions `single m 1` and `single 1 a`. See note [partially-applied ext lemmas]. Note that the first assumption isn't written as an diff --git a/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean index f1f82a6b59b6c7..a974bdfd29b33c 100644 --- a/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/Bialgebra/MonoidAlgebra.lean @@ -5,7 +5,9 @@ Authors: Amelia Livingston, Yaël Dillies, Michał Mrugała -/ module +public import Mathlib.RingTheory.Bialgebra.Convolution public import Mathlib.RingTheory.Bialgebra.Equiv +public import Mathlib.RingTheory.Bialgebra.GroupLike public import Mathlib.RingTheory.Coalgebra.MonoidAlgebra /-! @@ -22,18 +24,37 @@ coalgebra structure. monoid and `A` is an `R`-bialgebra. * `LaurentPolynomial.instBialgebra`: the `R`-bialgebra structure on the Laurent polynomials `A[T;T⁻¹]` when `A` is an `R`-bialgebra. +* `(Add)MonoidAlgebra.mapDomainBialgHomEquiv`: isomorphism between `R`-bialgebra homs `A[G] → A[H]` + and groups homs `G → H` when `G` and `H` are an (add) group and `A` is an `R`-bialgebra. -/ -@[expose] public section +public noncomputable section -noncomputable section +open TensorProduct Bialgebra Coalgebra Function WithConv -open Bialgebra - -variable {R A M N O : Type*} +variable {R S A B G H I M N O : Type*} namespace MonoidAlgebra -variable [CommSemiring R] [Semiring A] [Bialgebra R A] [Monoid M] [Monoid N] [Monoid O] +section CommSemiring +variable [CommSemiring R] [CommSemiring S] + +section Semiring +variable [Semiring A] [Semiring B] [Bialgebra R A] [Bialgebra R B] + +@[to_additive (dont_translate := R A) (attr := simp) isGroupLikeElem_single_one] +lemma isGroupLikeElem_single_one (g : G) : IsGroupLikeElem R (single g 1 : A[G]) where + counit_eq_one := by simp + comul_eq_tmul_self := by simp [Algebra.TensorProduct.one_def] + +/-- A group algebra is spanned by its group-like elements. -/ +@[to_additive (dont_translate := R A) (attr := simp) span_isGroupLikeElem] +lemma span_isGroupLikeElem : Submodule.span A {a : A[G] | IsGroupLikeElem R a} = ⊤ := + eq_top_mono (Submodule.span_mono <| Set.range_subset_iff.2 isGroupLikeElem_single_one) <| by + rw [← Finsupp.range_linearCombination] + exact LinearMap.range_eq_top_of_surjective _ fun x ↦ + ⟨x.coeff, by simp [Finsupp.linearCombination_apply]⟩ + +variable [Monoid M] [Monoid N] [Monoid O] variable (R A M) in @[to_additive (dont_translate := R A)] @@ -52,29 +73,19 @@ instance instBialgebra : Bialgebra R A[M] where LinearMap.compl₁₂_apply, LinearMap.coe_sum, Finset.sum_apply, Finset.sum_comm (s := (Coalgebra.Repr.arbitrary R b).index)] -set_option backward.isDefEq.respectTransparency false in --- TODO: Generalise to `A[M] →ₐc[R] A[N]` under `Bialgebra R A` -variable (R) [AddMonoid M] [AddMonoid N] in -/-- If `f : M → N` is a monoid hom, then `AddMonoidAlgebra.mapDomain f` is a bialgebra hom between -their additive monoid algebras. -/ -noncomputable def _root_.AddMonoidAlgebra.mapDomainBialgHom (f : M →+ N) : - AddMonoidAlgebra R M →ₐc[R] AddMonoidAlgebra R N := - .ofAlgHom (AddMonoidAlgebra.mapDomainAlgHom R R f) (by ext; simp) (by ext; simp) - -set_option backward.isDefEq.respectTransparency false in -- TODO: Generalise to `A[M] →ₐc[R] A[N]` under `Bialgebra R A` variable (R) in /-- If `f : M → N` is a monoid hom, then `MonoidAlgebra.mapDomain f` is a bialgebra hom between their monoid algebras. -/ -@[to_additive existing (attr := simps!)] -noncomputable def mapDomainBialgHom (f : M →* N) : R[M] →ₐc[R] R[N] := +@[expose, to_additive (attr := simps!) (dont_translate := R) +/-- If `f : M → N` is an additive monoid hom, then `MonoidAlgebra.mapDomain f` is a bialgebra hom +between their additive monoid algebras. -/] +def mapDomainBialgHom (f : M →* N) : R[M] →ₐc[R] R[N] := .ofAlgHom (mapDomainAlgHom R R f) (by ext; simp) (by ext; simp) -set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapDomainBialgHom_id : mapDomainBialgHom R (.id M) = .id R R[M] := by ext; simp -set_option backward.isDefEq.respectTransparency false in @[to_additive (attr := simp)] lemma mapDomainBialgHom_comp (f : N →* O) (g : M →* N) : mapDomainBialgHom R (f.comp g) = (mapDomainBialgHom R f).comp (mapDomainBialgHom R g) := by @@ -85,41 +96,80 @@ lemma mapDomainBialgHom_mapDomainBialgHom (f : N →* O) (g : M →* N) (x : R[M mapDomainBialgHom R f (mapDomainBialgHom R g x) = mapDomainBialgHom R (f.comp g) x := by ext; simp -end MonoidAlgebra +@[to_additive (attr := simp)] +lemma mapDomainBialgHom_single (f : M →* N) (m : M) (r : R) : + mapDomainBialgHom R f (single m r) = single (f m) r := mapDomain_single + +/-- A `R`-bialgebra homomorphism from `A[M]` is uniquely defined by its +values on the functions `single m 1` and `single 1 a`. + +See note [partially-applied ext lemmas]. Note that the first assumption isn't written as an +equality of `MonoidHom`s because `of` doesn't additivise. -/ +@[to_additive (dont_translate := A) (attr := ext high) +/-- A `R`-bialgebra homomorphism from `A[M]` is uniquely defined by its +values on the functions `single m 1` and `single 1 a`. + +See note [partially-applied ext lemmas]. Note that the first assumption isn't written as an +equality of `AddMonoidHom`s because `of` doesn't multiplicativise. -/] +lemma bialgHom_ext ⦃φ₁ φ₂ : A[M] →ₐc[R] B⦄ + (single_one_right : ∀ (m : M), φ₁ (single m 1) = φ₂ (single m 1)) + (single_one_left : (φ₁ : A[M] →ₐ[R] B).comp singleOneAlgHom = + (φ₂ : A[M] →ₐ[R] B).comp singleOneAlgHom) : φ₁ = φ₂ := + BialgHom.coe_toAlgHom_injective <| algHom_ext single_one_right single_one_left + +/-- Version of `bialgHom_ext` where both assumptions are written as equalities of bundled homs. -/ +lemma bialgHom_ext' ⦃φ₁ φ₂ : A[M] →ₐc[R] B⦄ + (single_one_right : (φ₁ : A[M] →* B).comp (of A M) = (φ₂ : A[M] →* B).comp (of A M)) + (single_one_left : (φ₁ : A[M] →ₐ[R] B).comp singleOneAlgHom = + (φ₂ : A[M] →ₐ[R] B).comp singleOneAlgHom) : φ₁ = φ₂ := + BialgHom.coe_toAlgHom_injective <| algHom_ext' single_one_right single_one_left -namespace AddMonoidAlgebra -variable [CommSemiring R] [Semiring A] [Bialgebra R A] [AddMonoid M] +@[to_additive (attr := simp)] +lemma counit_domCongr (e : M ≃* N) (x : A[M]) : counit (R := R) (domCongr R A e x) = counit x := by + induction x using MonoidAlgebra.induction_linear <;> simp [*] -variable (R A M) in -/-- The bialgebra equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of -`Multiplicative`. -/ +variable (R A) in -- TODO: Make `BialgEquiv.toCoalgEquiv` the simp normal form so that this can be simp -@[simps! -isSimp] -def toMultiplicativeBialgEquiv : A[M] ≃ₐc[R] MonoidAlgebra A (Multiplicative M) := - .ofAlgEquiv (toMultiplicativeAlgEquiv R A M) (by ext <;> simp) <| by +/-- Isomorphic monoids have isomorphic monoid algebras. -/ +@[expose, to_additive (attr := simps! -isSimp) (dont_translate := R A) +/-- Isomorphic monoids have isomorphic monoid algebras. -/] +def domCongrBialgEquiv (e : M ≃* N) : A[M] ≃ₐc[R] A[N] := + .ofAlgEquiv (domCongr R A e) (by ext <;> simp) <| by ext a - · simp [Algebra.TensorProduct.one_def] + · simp · simp [← (Coalgebra.Repr.arbitrary R a).eq] -@[simp] -lemma toMultiplicativeBialgEquiv_single (m : M) (a : A) : - toMultiplicativeBialgEquiv R A M (single m a) = .single (.ofAdd m) a := by - simp [toMultiplicativeBialgEquiv] - -end AddMonoidAlgebra - -namespace MonoidAlgebra -variable [CommSemiring R] [Semiring A] [Bialgebra R A] [Monoid M] +variable (M) in +/-- The trivial monoid algebra is isomorphic to the base ring. -/ +@[expose, to_additive (dont_translate := R) +/-- The trivial monoid algebra is isomorphic to the base ring. -/] +def bialgEquivOfSubsingleton [Subsingleton M] : R[M] ≃ₐc[R] R where + __ := counitBialgHom .. + invFun := algebraMap _ _ + left_inv r := by + change (Algebra.ofId _ _).comp (Bialgebra.counitAlgHom R _) r = AlgHom.id R _ r + congr 1 + ext g : 2 + simp [Subsingleton.elim g 1] + right_inv := (Bialgebra.counitAlgHom R R[M]).commutes + +lemma isGroupLikeElem_of (m : M) : IsGroupLikeElem R (of A M m) := isGroupLikeElem_single_one .. + +/-- The `R`-bialgebra map from the group algebra on the group-like elements of `A` to `A`. -/ +@[expose, simps!] +def liftGroupLikeBialgHom : R[GroupLike R A] →ₐc[R] A := + .ofAlgHom (lift R A (GroupLike R A) { toFun g := g.1, map_one' := by simp, map_mul' := by simp }) + (by ext; simp) (by ext; simp) variable (R A M) in /-- The bialgebra equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive`. -/ -- TODO: Make `BialgEquiv.toCoalgEquiv` the simp normal form so that this can be simp -@[simps! -isSimp] +@[expose, simps! -isSimp] def toAdditiveBialgEquiv : A[M] ≃ₐc[R] AddMonoidAlgebra A (Additive M) := .ofAlgEquiv (toAdditiveAlgEquiv R A M) (by ext <;> simp) <| by ext a - · simp [Algebra.TensorProduct.one_def] + · simp · simp [← (Coalgebra.Repr.arbitrary R a).eq] @[simp] @@ -127,8 +177,256 @@ lemma toAdditiveBialgEquiv_single (m : M) (a : A) : toAdditiveBialgEquiv R A M (single m a) = .single (.ofMul m) a := by simp [toAdditiveBialgEquiv] +end Semiring + +section CommSemiring +variable [CommSemiring A] + +section Algebra +variable [Algebra R A] [Monoid M] + +variable (R M A) in +/-- `MonoidAlgebra.lift` as a `MulEquiv`. -/ +def liftMulEquiv : (M →* A) ≃* WithConv (R[M] →ₐ[R] A) where + toEquiv := (lift R A M).trans (WithConv.equiv _).symm + map_mul' f g := by ext; simp [AlgHom.convMul_apply] + +@[to_additive (dont_translate := R A) (attr := simp) convMul_algHom_single_one] +lemma convMul_algHom_single_one (f g : WithConv <| R[M] →ₐ[R] A) (x : M) : + (f * g) (single x 1) = f (single x 1) * g (single x 1) := by simp [AlgHom.convMul_apply] + +end Algebra + +variable [Bialgebra R A] + +@[to_additive (dont_translate := R A) (attr := simp) convMul_bialgHom_single_one] +lemma convMul_bialgHom_single_one [CommMonoid M] (f g : WithConv <| R[M] →ₐc[R] A) (x : M) : + (f * g) (single x 1) = f (single x 1) * g (single x 1) := by + simp only [BialgHom.convMul_def, BialgHom.coe_comp, Function.comp_apply] + change mulBialgHom R A (Bialgebra.TensorProduct.map f.ofConv g.ofConv (comul (single x 1))) = _ + simp [Bialgebra.TensorProduct.map_tmul] + +end CommSemiring + +section CommMonoid +variable [CommMonoid M] [CommMonoid N] + +@[to_additive (dont_translate := R) (attr := simp)] +lemma mapDomainBialgHom_mul (f g : M →* N) : + mapDomainBialgHom R (f * g) = + ofConv ((toConv <| mapDomainBialgHom R f) * (toConv <| mapDomainBialgHom R g)) := by ext; simp + +lemma comulAlgHom_comp_mapRingHom (f : R →+* S) : + (comulAlgHom S (MonoidAlgebra S M)).toRingHom.comp (mapRingHom M f) = + .comp (Algebra.TensorProduct.mapRingHom f (mapRingHom M f) (mapRingHom M f) (by simp) + (by simp)) (comulAlgHom R R[M]).toRingHom := by ext <;> simp + +lemma counitAlgHom_comp_mapRingHom (f : R →+* S) : + (counitAlgHom S (MonoidAlgebra S M)).toRingHom.comp (mapRingHom M f) = + f.comp (counitAlgHom R R[M]).toRingHom := by ext <;> simp + +end CommMonoid +end CommSemiring + +section CommRing +variable [CommRing R] [IsDomain R] + +open Submodule in +@[to_additive (dont_translate := R) isGroupLikeElem_iff_mem_range_single_one] +lemma isGroupLikeElem_iff_mem_range_single_one {x : R[M]} : + IsGroupLikeElem R x ↔ x ∈ Set.range (single · 1) where + mp hx := by + by_contra h + have : LinearIndepOn R id (insert x <| .range (single · 1)) := + linearIndepOn_isGroupLikeElem.mono <| by simp [Set.subset_def, hx] + have : x.coeff.sum single ∉ span R (.range (single · 1)) := by + simpa using this.notMem_span_of_insert h + refine this <| sum_mem fun g hg ↦ ?_ + rw [← mul_one (x.coeff g), ← smul_eq_mul, ← smul_single] + exact smul_mem _ _ <| subset_span <| Set.mem_range_self _ + mpr := by rintro ⟨g, rfl⟩; exact isGroupLikeElem_single_one _ + +section MulOneClass +variable [MulOneClass M] {x : R[M]} + +lemma isGroupLikeElem_iff_mem_range_of : IsGroupLikeElem R x ↔ x ∈ Set.range (of R M) := + isGroupLikeElem_iff_mem_range_single_one + +end MulOneClass + +section Group +variable [Group G] [Group H] [Group I] + +@[to_additive (dont_translate := R)] +private def mapDomainOfBialgHomFun (f : R[G] →ₐc[R] R[H]) (g : G) : H := + (isGroupLikeElem_iff_mem_range_single_one.1 <| (isGroupLikeElem_single_one g).map f).choose + +@[to_additive (dont_translate := R) (attr := simp)] +private lemma single_mapDomainOfBialgHomFun_one (f : R[G] →ₐc[R] R[H]) (g : G) : + single (mapDomainOfBialgHomFun f g) 1 = f (single g 1) := + (isGroupLikeElem_iff_mem_range_single_one.1 <| (isGroupLikeElem_single_one g).map f).choose_spec + +/-- A bialgebra homomorphism `R[G] → R[H]` between group algebras over a domain `R` comes from a +group hom `G → H`. + +See `MonoidAlgebra.mapDomainBialgHom` for the forward map. -/ +@[to_additive (dont_translate := R) +/-- A bialgebra homomorphism `R[G] → R[H]` between group algebras over a domain `R` comes from a +group hom `G → H`. + +See `MonoidAlgebra.mapDomainBialgHom` for the forward map. -/] +def mapDomainOfBialgHom (f : R[G] →ₐc[R] R[H]) : G →* H where + toFun := mapDomainOfBialgHomFun f + map_one' := single_left_injective (R := R) one_ne_zero <| by simp [← one_def] + map_mul' g₁ g₂ := by + refine single_left_injective (R := R) one_ne_zero ?_ + simp only [single_mapDomainOfBialgHomFun_one] + rw [← mul_one (1 : R), ← single_mul_single, ← single_mul_single, map_mul] + simp + +@[to_additive (dont_translate := R) (attr := simp)] +lemma single_mapDomainOfBialgHom (f : R[G] →ₐc[R] R[H]) (g : G) (r : R) : + single (mapDomainOfBialgHom f g) r = f (single g r) := by + rw [← mul_one r, ← smul_eq_mul, ← smul_single, ← smul_single, map_smul] + exact congr(r • $(single_mapDomainOfBialgHomFun_one f g)) + +@[to_additive (dont_translate := R) (attr := simp)] +lemma mapDomainBialgHom_mapDomainOfBialgHom (f : R[G] →ₐc[R] R[H]) : + mapDomainBialgHom R (mapDomainOfBialgHom f) = f := by + ext x : 1 + · rw [mapDomainBialgHom_single] + exact single_mapDomainOfBialgHomFun_one f x + · ext + +@[to_additive (dont_translate := R) (attr := simp)] +lemma mapDomainOfBialgHom_mapDomainBialgHom (f : G →* H) : + mapDomainOfBialgHom (mapDomainBialgHom (R := R) f) = f := by + ext g; refine single_left_injective (R := R) one_ne_zero ?_; simp [single_mapDomainOfBialgHom] + +@[to_additive (attr := simp)] +lemma mapDomainOfBialgHom_id : mapDomainOfBialgHom (.id R R[G]) = .id _ := by + simp [← mapDomainBialgHom_id] + +@[to_additive (attr := simp)] +lemma mapDomainOfBialgHom_comp (f : R[H] →ₐc[R] R[I]) (g : R[G] →ₐc[R] R[H]) : + mapDomainOfBialgHom (f.comp g) = (mapDomainOfBialgHom f).comp (mapDomainOfBialgHom g) := by + rw [← mapDomainOfBialgHom_mapDomainBialgHom (R := R) + ((mapDomainOfBialgHom f).comp (mapDomainOfBialgHom g)), + mapDomainBialgHom_comp, mapDomainBialgHom_mapDomainOfBialgHom, + mapDomainBialgHom_mapDomainOfBialgHom] + +/-- The equivalence between group homs `G → H` and bialgebra homs `R[G] → R[H]` of group algebras +over a domain. -/ +@[expose, to_additive (attr := simps) +/-- The equivalence between group homs `G → H` and bialgebra homs `R[G] → R[H]` of group algebras +over a domain. -/] +def mapDomainBialgHomEquiv : (G →* H) ≃ (R[G] →ₐc[R] R[H]) where + toFun := mapDomainBialgHom R + invFun := mapDomainOfBialgHom + left_inv := mapDomainOfBialgHom_mapDomainBialgHom + right_inv := mapDomainBialgHom_mapDomainOfBialgHom + +end Group + +section CommGroup +variable [CommGroup G] [CommGroup H] + +/-- The group isomorphism between group homs `G → H` and bialgebra homs `R[G] → R[H]` of group +algebras over a domain. -/ +@[expose, simps!] +def mapDomainBialgHomMulEquiv : (G →* H) ≃* WithConv (R[G] →ₐc[R] R[H]) where + toEquiv := mapDomainBialgHomEquiv.trans (WithConv.equiv _).symm + map_mul' f g := by simp + +end CommGroup +end CommRing end MonoidAlgebra +namespace AddMonoidAlgebra +section CommSemiring +variable [CommSemiring R] [CommSemiring S] + +section Semiring +variable [Semiring A] [Semiring B] [Bialgebra R A] [Bialgebra R B] [AddMonoid M] [AddMonoid N] + +/-- See note [partially-applied ext lemmas]. -/ +lemma bialgHom_ext' ⦃φ₁ φ₂ : A[M] →ₐc[R] B⦄ + (single_one_right : (φ₁ : A[M] →* B).comp (of A M) = (φ₂ : A[M] →* B).comp (of A M)) + (single_one_left : (φ₁ : A[M] →ₐ[R] B).comp singleZeroAlgHom = + (φ₂ : A[M] →ₐ[R] B).comp singleZeroAlgHom) : φ₁ = φ₂ := + BialgHom.coe_toAlgHom_injective <| algHom_ext' single_one_right single_one_left + +lemma isGroupLikeElem_of (m : M) : IsGroupLikeElem R (of A M m) := isGroupLikeElem_single_one .. + +variable (R A M) in +/-- The bialgebra equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of +`Multiplicative`. -/ +-- TODO: Make `BialgEquiv.toCoalgEquiv` the simp normal form so that this can be simp +@[expose, simps! -isSimp] +def toMultiplicativeBialgEquiv : A[M] ≃ₐc[R] MonoidAlgebra A (Multiplicative M) := + .ofAlgEquiv (toMultiplicativeAlgEquiv R A M) (by ext <;> simp) <| by + ext a + · simp + · simp [← (Coalgebra.Repr.arbitrary R a).eq] + +@[simp] +lemma toMultiplicativeBialgEquiv_single (m : M) (a : A) : + toMultiplicativeBialgEquiv R A M (single m a) = .single (.ofAdd m) a := by + simp [toMultiplicativeBialgEquiv] + +end Semiring + +section CommSemiring +variable [CommSemiring A] [Algebra R A] [AddMonoid M] + +variable (R M A) in +/-- `AddMonoidAlgebra.lift` as a `MulEquiv`. -/ +def liftMulEquiv : (Multiplicative M →* A) ≃* WithConv (R[M] →ₐ[R] A) where + toEquiv := (lift R A M).trans (WithConv.equiv _).symm + map_mul' f g := by ext; simp [AlgHom.convMul_apply] + +end CommSemiring + +section AddCommMonoid +variable [AddCommMonoid M] [AddCommMonoid N] + +lemma comulAlgHom_comp_mapRingHom (f : R →+* S) : + (comulAlgHom S S[M]).toRingHom.comp (mapRingHom M f) = + .comp (Algebra.TensorProduct.mapRingHom f (mapRingHom M f) (mapRingHom M f) + (by ext; simp) (by ext; simp)) + (comulAlgHom R R[M]).toRingHom := by ext <;> simp + +lemma counitAlgHom_comp_mapRingHom (f : R →+* S) : + (counitAlgHom S S[M]).toRingHom.comp (mapRingHom M f) = + f.comp (counitAlgHom R R[M]).toRingHom := by ext <;> simp + +end AddCommMonoid +end CommSemiring + +section CommRing +variable [CommRing R] [IsDomain R] + +section AddZeroClass +variable [AddZeroClass M] {x : R[M]} + +lemma isGroupLikeElem_iff_mem_range_of : IsGroupLikeElem R x ↔ x ∈ Set.range (of R M) := + isGroupLikeElem_iff_mem_range_single_one + +end AddZeroClass + +section AddCommGroup +variable [AddCommGroup G] [AddCommGroup H] + +/-- The group isomorphism between group homs `G → H` and bialgebra homs `R[G] → R[H]` of group +algebras over a domain. -/ +def mapDomainBialgHomAddEquiv : (G →+ H) ≃+ Additive (WithConv <| R[G] →ₐc[R] R[H]) where + toEquiv := mapDomainBialgHomEquiv.trans <| (WithConv.equiv _).symm.trans Additive.ofMul + map_add' f g := by simp + +end AddCommGroup +end CommRing +end AddMonoidAlgebra + namespace LaurentPolynomial open AddMonoidAlgebra @@ -139,9 +437,7 @@ instance instBialgebra : Bialgebra R A[T;T⁻¹] := inferInstanceAs <| Bialgebra R A[ℤ] @[simp] -theorem comul_T (n : ℤ) : - Coalgebra.comul (R := R) (T n : A[T;T⁻¹]) = T n ⊗ₜ[R] T n := by - simp [T, -single_eq_C_mul_T, Algebra.TensorProduct.one_def] +theorem comul_T (n : ℤ) : comul (T n : A[T;T⁻¹]) = T n ⊗ₜ[R] T n := by simp [T, -single_eq_C_mul_T] @[simp] theorem counit_T (n : ℤ) : From 5eec30bc56ed5a23be2e27c544a949ba0bceddeb Mon Sep 17 00:00:00 2001 From: Chris Henson <46805207+chenson2018@users.noreply.github.com> Date: Tue, 28 Jul 2026 21:06:33 +0000 Subject: [PATCH 1065/1300] perf(LinearAlgebra/Pi): golf `Matrix.ker_diagonal_toLin'` (#42199) In the review of #42173, it was asked if the `have` in `Matrix.ker_diagonal_toLin'` could be removed. This PR does so, and is a bit faster. --- Mathlib/LinearAlgebra/Matrix/Diagonal.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Diagonal.lean b/Mathlib/LinearAlgebra/Matrix/Diagonal.lean index 97be0a9a936f62..2a5a5d58dc83fc 100644 --- a/Mathlib/LinearAlgebra/Matrix/Diagonal.lean +++ b/Mathlib/LinearAlgebra/Matrix/Diagonal.lean @@ -57,8 +57,7 @@ theorem ker_diagonal_toLin' [DecidableEq m] (w : m → K) : ker (toLin' (diagonal w)) = ⨆ i ∈ { i | w i = 0 }, LinearMap.range (LinearMap.single K (fun _ => K) i) := by rw [← comap_bot] - have := fun i : m => ker_comp (toLin' (diagonal w)) (proj i) - simpa [← this, proj_diagonal, ker_smul', ← iInf_ker_proj] using + simpa [← ker_comp, proj_diagonal, ker_smul', ← iInf_ker_proj] using (iSup_range_single_eq_iInf_ker_proj K _ isCompl_compl {i | w i = 0}.toFinite).symm theorem range_diagonal [DecidableEq m] (w : m → K) : From 12ab8e82f8447fa639dabe9ffeda74436b72be31 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 29 Jul 2026 03:39:05 +0000 Subject: [PATCH 1066/1300] feat(Topology/Order/Basic): add `isOpen_Ioo'` (#42114) This complements the existing `isOpen_Ioo`. Co-authored-by: NoahW314 --- Mathlib/Topology/Order/Basic.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index da0e355670a44f..1c668250cd8c44 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -117,6 +117,10 @@ theorem isOpen_lt' [OrderTopology α] (a : α) : IsOpen { b : α | a < b } := @[to_dual] theorem isOpen_Ioi' [OrderTopology α] (a : α) : IsOpen (Ioi a) := isOpen_lt' a +@[to_dual self] +theorem isOpen_Ioo' [OrderTopology α] (a b : α) : IsOpen (Ioo a b) := + IsOpen.inter (isOpen_Ioi' a) (isOpen_Iio' b) + @[to_dual gt_mem_nhds] theorem lt_mem_nhds [OrderTopology α] {a b : α} (h : a < b) : ∀ᶠ x in 𝓝 b, a < x := (isOpen_lt' _).mem_nhds h From 21da9fc40346c3663f0ecad16e2198748a5ba1ca Mon Sep 17 00:00:00 2001 From: Salvatore Mercuri <47568553+smmercuri@users.noreply.github.com> Date: Wed, 29 Jul 2026 08:07:23 +0000 Subject: [PATCH 1067/1300] feat: notation for adele rings (#40535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Notation: - `K∞` : `NumberField.InfiniteAdeleRing K`; - `𝔸ᶠ[R, K]`: `IsDedekindDomain.FiniteAdeleRing R K`; - `𝔸[R, K]` : `NumberField.AdeleRing R K`; - specialisations `𝔸ᶠ[K]` and `𝔸[K]` to `R = RingOfIntegers K`. --- .../NumberTheory/NumberField/AdeleRing.lean | 19 +++++++---- .../NumberField/InfiniteAdeleRing.lean | 32 +++++++++---------- .../DedekindDomain/FiniteAdeleRing.lean | 29 +++++++++-------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/AdeleRing.lean b/Mathlib/NumberTheory/NumberField/AdeleRing.lean index fc0c7267779aa4..c88b4583107e9e 100644 --- a/Mathlib/NumberTheory/NumberField/AdeleRing.lean +++ b/Mathlib/NumberTheory/NumberField/AdeleRing.lean @@ -50,24 +50,31 @@ deriving CommRing, TopologicalSpace, IsTopologicalRing, Algebra K namespace AdeleRing +/-- `𝔸ᶠ[K]` is notation for `IsDedekindDomain.FiniteAdeleRing (𝓞 K) K`. -/ +scoped notation:max "𝔸ᶠ[" K "]" => FiniteAdeleRing (𝓞 K) K +/-- `𝔸[R, K]` is notation for `NumberField.AdeleRing R K`. -/ +scoped notation:max "𝔸[" R ", " K "]" => AdeleRing R K +/-- `𝔸[K]` is notation for `NumberField.AdeleRing (𝓞 K) K`. -/ +scoped notation:max "𝔸[" K "]" => AdeleRing (𝓞 K) K + variable (R K : Type*) [CommRing R] [IsDedekindDomain R] [Field K] [Algebra R K] [IsFractionRing R K] -instance : Inhabited (AdeleRing R K) := ⟨0⟩ +instance : Inhabited 𝔸[R, K] := ⟨0⟩ @[simp] theorem algebraMap_fst_apply (x : K) (v : InfinitePlace K) : - (algebraMap K (AdeleRing R K) x).1 v = x := rfl + (algebraMap K 𝔸[R, K] x).1 v = x := rfl @[simp] theorem algebraMap_snd_apply (x : K) (v : HeightOneSpectrum R) : - (algebraMap K (AdeleRing R K) x).2 v = x := rfl + (algebraMap K 𝔸[R, K] x).2 v = x := rfl -theorem algebraMap_injective [NumberField K] : Function.Injective (algebraMap K (AdeleRing R K)) := - fun _ _ hxy => (algebraMap K _).injective (Prod.ext_iff.1 hxy).1 +theorem algebraMap_injective [NumberField K] : Function.Injective (algebraMap K 𝔸[R, K]) := + fun _ _ hxy => (algebraMap K K∞).injective (Prod.ext_iff.1 hxy).1 /-- The subgroup of principal adeles `(x)ᵥ` where `x ∈ K`. -/ -abbrev principalSubgroup : AddSubgroup (AdeleRing R K) := (algebraMap K _).range.toAddSubgroup +abbrev principalSubgroup : AddSubgroup 𝔸[R, K] := (algebraMap K 𝔸[R, K]).range.toAddSubgroup end AdeleRing diff --git a/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean b/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean index a1cd977f3b3738..e2e126fb6046c5 100644 --- a/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean +++ b/Mathlib/NumberTheory/NumberField/InfiniteAdeleRing.lean @@ -54,24 +54,26 @@ deriving CommRing, Inhabited, TopologicalSpace, IsTopologicalRing, Algebra K namespace InfiniteAdeleRing +/-- `K∞` is notation for `NumberField.InfiniteAdeleRing K`. -/ +scoped[NumberField.AdeleRing] notation:max K "∞" => InfiniteAdeleRing K + +open scoped AdeleRing + variable (K : Type*) [Field K] -instance [NumberField K] : Nontrivial (InfiniteAdeleRing K) := +instance [NumberField K] : Nontrivial K∞ := (inferInstance : Nonempty (InfinitePlace K)).elim fun w => Pi.nontrivial_at w -@[simp] -theorem algebraMap_apply (x : K) (v : InfinitePlace K) : - algebraMap K (InfiniteAdeleRing K) x v = x := rfl +@[simp] theorem algebraMap_apply (x : K) (v : InfinitePlace K) : algebraMap K K∞ x v = x := rfl /-- The infinite adele ring is locally compact. -/ -instance locallyCompactSpace [NumberField K] : LocallyCompactSpace (InfiniteAdeleRing K) := +instance locallyCompactSpace [NumberField K] : LocallyCompactSpace K∞ := Pi.locallyCompactSpace_of_finite open scoped Classical in /-- The ring isomorphism between the infinite adele ring of a number field and the space `ℝ ^ r₁ × ℂ ^ r₂`, where `(r₁, r₂)` is the signature of the number field. -/ -abbrev ringEquiv_mixedSpace : - InfiniteAdeleRing K ≃+* mixedEmbedding.mixedSpace K := +abbrev ringEquiv_mixedSpace : K∞ ≃+* mixedEmbedding.mixedSpace K := RingEquiv.trans (RingEquiv.piEquivPiSubtypeProd (fun (v : InfinitePlace K) => IsReal v) (fun (v : InfinitePlace K) => v.Completion)) @@ -84,7 +86,7 @@ abbrev ringEquiv_mixedSpace : Equiv.subtypeEquivRight (fun _ => not_isReal_iff_isComplex)))) @[simp] -theorem ringEquiv_mixedSpace_apply (x : InfiniteAdeleRing K) : +theorem ringEquiv_mixedSpace_apply (x : K∞) : ringEquiv_mixedSpace K x = (fun (v : {w : InfinitePlace K // IsReal w}) => extensionEmbeddingOfIsReal v.2 (x v), fun (v : {w : InfinitePlace K // IsComplex w}) => extensionEmbedding v.1 (x v)) := rfl @@ -93,7 +95,7 @@ theorem ringEquiv_mixedSpace_apply (x : InfiniteAdeleRing K) : ring to the mixed embedding `x ↦ (φᵢ(x))ᵢ` of `K` into the space `ℝ ^ r₁ × ℂ ^ r₂`, where `(r₁, r₂)` is the signature of `K` and `φᵢ` are the complex embeddings of `K`. -/ theorem mixedEmbedding_eq_algebraMap_comp {x : K} : - mixedEmbedding K x = ringEquiv_mixedSpace K (algebraMap K _ x) := by + mixedEmbedding K x = ringEquiv_mixedSpace K (algebraMap K K∞ x) := by ext v <;> simp /-- @@ -101,23 +103,21 @@ theorem mixedEmbedding_eq_algebraMap_comp {x : K} : The number field $K$ is dense in the infinite adele ring $\prod_v K_v$. -/ -theorem denseRange_algebraMap [NumberField K] : DenseRange <| algebraMap K (InfiniteAdeleRing K) := +theorem denseRange_algebraMap [NumberField K] : DenseRange <| algebraMap K K∞ := (DenseRange.piMap fun v => Completion.denseRange_coe v).comp (InfinitePlace.denseRange_algebraMap_pi K) (.piMap fun v => Completion.continuous_coe v) /-- The norm on the infinite adele ring is given by the product of the normalized norms across infinite places. The normalized norm is the real norm at real places and the square of the complex norm at complex places. -/ -instance [NumberField K] : Norm (InfiniteAdeleRing K) where - norm x := ∏ v, ‖x v‖ ^ v.mult +instance [NumberField K] : Norm K∞ where norm x := ∏ v, ‖x v‖ ^ v.mult variable {K} -theorem norm_def [NumberField K] (x : InfiniteAdeleRing K) : - ‖x‖ = ∏ v, ‖x v‖ ^ v.mult := rfl +theorem norm_def [NumberField K] (x : K∞) : ‖x‖ = ∏ v, ‖x v‖ ^ v.mult := rfl set_option backward.isDefEq.respectTransparency false in -theorem norm_eq_zero_of_not_isUnit [NumberField K] {x : InfiniteAdeleRing K} (hx : ¬IsUnit x) : +theorem norm_eq_zero_of_not_isUnit [NumberField K] {x : K∞} (hx : ¬IsUnit x) : ‖x‖ = 0 := by rw [Pi.isUnit_iff, not_forall] at hx obtain ⟨v, hv⟩ := hx @@ -126,7 +126,7 @@ theorem norm_eq_zero_of_not_isUnit [NumberField K] {x : InfiniteAdeleRing K} (hx /-- The product formula for the infinite adele ring. This is the adelic version of `NumberField.InfinitePlace.prod_eq_abs_norm`. -/ theorem coe_norm_eq_abs_norm [NumberField K] (x : K) : - ‖algebraMap K (InfiniteAdeleRing K) x‖ = |Algebra.norm ℚ x| := by + ‖algebraMap K K∞ x‖ = |Algebra.norm ℚ x| := by simpa [-Rat.cast_abs, norm_def] using! InfinitePlace.prod_eq_abs_norm x end InfiniteAdeleRing diff --git a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean index 0cda4b73f6bdbb..7d3a06d38fc1ec 100644 --- a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean +++ b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean @@ -106,13 +106,16 @@ instance : DFunLike (FiniteAdeleRing R K) (HeightOneSpectrum R) (adicCompletion namespace FiniteAdeleRing +/-- `𝔸ᶠ[R, K]` is notation for `IsDedekindDomain.FiniteAdeleRing R K`. -/ +scoped notation:max "𝔸ᶠ[" R ", " K "]" => FiniteAdeleRing R K + /-- The canonical map from `K` to the finite adeles of `K`. The content of the existence of this map is the fact that an element `k` of `K` is integral at all but finitely many places, which is `IsDedekindDomain.HeightOneSpectrum.Support.finite R k`. -/ -protected def algebraMap : K →+* FiniteAdeleRing R K where +protected def algebraMap : K →+* 𝔸ᶠ[R, K] where toFun k := ⟨fun i ↦ k, by simp only [Filter.eventually_cofinite, SetLike.mem_coe, mem_adicCompletionIntegers R K, valuedAdicCompletion_eq_valuation', not_le] @@ -122,25 +125,25 @@ protected def algebraMap : K →+* FiniteAdeleRing R K where map_zero' := Subtype.ext <| funext fun _ ↦ adicCompletion.coe_zero .. map_add' x y := Subtype.ext <| funext fun _ ↦ adicCompletion.coe_add .. -instance : Algebra K (FiniteAdeleRing R K) := (FiniteAdeleRing.algebraMap R K).toAlgebra +instance : Algebra K 𝔸ᶠ[R, K] := (FiniteAdeleRing.algebraMap R K).toAlgebra @[simp] theorem algebraMap_apply (k : K) (v : HeightOneSpectrum R) : - algebraMap K (FiniteAdeleRing R K) k v = k := rfl + algebraMap K 𝔸ᶠ[R, K] k v = k := rfl -instance : Algebra R (FiniteAdeleRing R K) := Algebra.compHom _ (algebraMap R K) +instance : Algebra R 𝔸ᶠ[R, K] := Algebra.compHom _ (algebraMap R K) -instance : IsScalarTower R K (FiniteAdeleRing R K) := +instance : IsScalarTower R K 𝔸ᶠ[R, K] := IsScalarTower.of_algebraMap_eq' rfl variable {R} in @[ext] -lemma ext {a₁ a₂ : FiniteAdeleRing R K} (h : ∀ v, a₁ v = a₂ v) : a₁ = a₂ := +lemma ext {a₁ a₂ : 𝔸ᶠ[R, K]} (h : ∀ v, a₁ v = a₂ v) : a₁ = a₂ := Subtype.ext <| funext h section Topology -instance : IsTopologicalRing (FiniteAdeleRing R K) := +instance : IsTopologicalRing 𝔸ᶠ[R, K] := haveI : Fact (∀ v : HeightOneSpectrum R, IsOpen (v.adicCompletionIntegers K : Set (v.adicCompletion K))) := ⟨fun _ ↦ Valued.isOpen_valuationSubring _⟩ @@ -153,19 +156,19 @@ section Units variable {R K} set_option backward.isDefEq.respectTransparency false in -theorem isUnit_iff {a : FiniteAdeleRing R K} : +theorem isUnit_iff {a : 𝔸ᶠ[R, K]} : IsUnit a ↔ (∀ v, a v ≠ 0) ∧ ∀ᶠ v in Filter.cofinite, Valued.v (a v) = 1 := by rw [RestrictedProduct.isUnit_iff] simp only [isUnit_iff_ne_zero, adicCompletionIntegers.isUnit_iff_valued_eq_one, exists_prop, Filter.eventually_cofinite, not_and_or, Set.ofPred_or] simpa using! fun _ _ ↦ a.2 -theorem unitsEquiv_finite_valued_eq_one (a : (FiniteAdeleRing R K)ˣ) : +theorem unitsEquiv_finite_valued_eq_one (a : 𝔸ᶠ[R, K]ˣ) : ∀ᶠ v in Filter.cofinite, Valued.v (RestrictedProduct.unitsEquiv _ a v).1 = 1 := by filter_upwards [(RestrictedProduct.unitsEquiv _ a).2] using fun _ h ↦ adicCompletionIntegers.mem_units_iff_valued_eq_one.1 h -theorem infinite_valued_ne_one_of_not_isUnit {a : FiniteAdeleRing R K} (ha₀ : ∀ v, a v ≠ 0) +theorem infinite_valued_ne_one_of_not_isUnit {a : 𝔸ᶠ[R, K]} (ha₀ : ∀ v, a v ≠ 0) (ha : ¬IsUnit a) : {v | Valued.v (a v) ≠ 1}.Infinite := by contrapose! ha rw [isUnit_iff] @@ -175,11 +178,9 @@ variable (R) variable (K) in /-- The global embedding of the units of `K` into the units of `FiniteAdeleRing R K`. -/ -def unitEmbedding : Kˣ →* (FiniteAdeleRing R K)ˣ := Units.map (algebraMap K (FiniteAdeleRing R K)) +def unitEmbedding : Kˣ →* 𝔸ᶠ[R, K]ˣ := Units.map (algebraMap K 𝔸ᶠ[R, K]) -@[simp] -theorem unitEmbedding_apply (k : Kˣ) : - unitEmbedding R K k = algebraMap K (FiniteAdeleRing R K) k := rfl +@[simp] theorem unitEmbedding_apply (k : Kˣ) : unitEmbedding R K k = algebraMap K 𝔸ᶠ[R, K] k := rfl end Units From be4fe8f18dc36f2938ae3ec16af35008bd0d6224 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 29 Jul 2026 08:16:47 +0000 Subject: [PATCH 1068/1300] fix(LinearAlgebra/Matrix): make accidental private instance public (#42212) Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/LinearAlgebra/Matrix/Nonsingular.lean | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean b/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean index 68ef3c3b93a3d5..4bd03428237104 100644 --- a/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean +++ b/Mathlib/LinearAlgebra/Matrix/Nonsingular.lean @@ -5,9 +5,9 @@ Authors: Junyan Xu, Aristotle AI -/ module +public import Mathlib.LinearAlgebra.InvariantBasisNumber public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic -import Mathlib.LinearAlgebra.InvariantBasisNumber import Mathlib.LinearAlgebra.Matrix.SemiringInverse import Mathlib.LinearAlgebra.Matrix.ToLin @@ -33,13 +33,13 @@ a matrix is nonsingular if and only if its determinant is not a zero divisor). rank condition. -/ +public section + variable {R m n : Type*} [CommSemiring R] [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n] variable {A : Matrix n n R} namespace Matrix -public section - lemma isDetpBalanced_iff_sub_mul_det_eq_zero {R : Type*} [CommRing R] {A : Matrix n n R} {a b : R} : A.IsDetpBalanced a b ↔ (a - b) * A.det = 0 := by grind [IsDetpBalanced, det_eq_detp_sub_detp] @@ -141,8 +141,6 @@ theorem linearIndependent_col_iff_row [Finite n] : have := Fintype.ofFinite classical rw [linearIndependent_col_iff, linearIndependent_row_iff] -end - end Matrix open Matrix From 69538871db6b37033c369f63feadb1559ab1f2d8 Mon Sep 17 00:00:00 2001 From: Richard Osborn Date: Wed, 29 Jul 2026 08:26:23 +0000 Subject: [PATCH 1069/1300] feat(SetTheory/Cardinal): strong induction on Nat.card for finite types (#41978) Add the `Finite` analogue for `induction_subsingleton_or_nontrivial`. --- Mathlib/GroupTheory/Nilpotent.lean | 26 +++++++++---------------- Mathlib/SetTheory/Cardinal/NatCard.lean | 18 +++++++++++++++++ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 5306d9a770513c..2e510e6fa9fc65 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -1207,23 +1207,15 @@ variable {G : Type*} [hG : Group G] /-- A p-group is nilpotent -/ theorem IsPGroup.isNilpotent [Finite G] {p : ℕ} [hp : Fact (Nat.Prime p)] (h : IsPGroup p G) : IsNilpotent G := by - cases nonempty_fintype G - classical - revert hG - apply @Fintype.induction_subsingleton_or_nontrivial _ G _ - · intro _ _ _ _ - infer_instance - · intro G _ _ ih _ h - have hcq : Fintype.card (G ⧸ center G) < Fintype.card G := by - simp only [← Nat.card_eq_fintype_card] - rw [card_eq_card_quotient_mul_card_subgroup (center G)] - simp only [Nat.card_eq_fintype_card] - apply lt_mul_of_one_lt_right - · exact Fintype.card_pos_iff.mpr One.instNonempty - · simp only [← Nat.card_eq_fintype_card] - exact (Subgroup.one_lt_card_iff_ne_bot _).mpr (ne_of_gt h.bot_lt_center) - have hnq : IsNilpotent (G ⧸ center G) := ih _ hcq (h.to_quotient (center G)) - exact of_quotient_center_nilpotent hnq + induction G using Finite.induction_subsingleton_or_nontrivial generalizing hG with + | hbase => infer_instance + | hstep G ih => + have hcq : Nat.card (G ⧸ center G) < Nat.card G := by + rw [card_eq_card_quotient_mul_card_subgroup (center G)] + apply lt_mul_of_one_lt_right Nat.card_pos + exact (Subgroup.one_lt_card_iff_ne_bot _).mpr (ne_of_gt h.bot_lt_center) + have hnq : IsNilpotent (G ⧸ center G) := ih _ hcq (h.to_quotient (center G)) + exact of_quotient_center_nilpotent hnq variable [Finite G] diff --git a/Mathlib/SetTheory/Cardinal/NatCard.lean b/Mathlib/SetTheory/Cardinal/NatCard.lean index ee56380d8b6bd2..c238a719a3a6e4 100644 --- a/Mathlib/SetTheory/Cardinal/NatCard.lean +++ b/Mathlib/SetTheory/Cardinal/NatCard.lean @@ -146,6 +146,24 @@ theorem card_subtype_lt [Finite α] {p : α → Prop} {x : α} (hx : ¬p x) : have := Fintype.ofFinite α simpa only [Nat.card_eq_fintype_card, gt_iff_lt] using Fintype.card_subtype_lt hx +/-- A custom induction principle for finite types, by strong induction on `Nat.card`: +the base case is a subsingleton type, and the induction step is for nontrivial types, +where one can assume the hypothesis for all types of smaller cardinality. -/ +@[elab_as_elim] +theorem induction_subsingleton_or_nontrivial {P : Type* → Prop} (α) [Finite α] + (hbase : ∀ (α) [Finite α] [Subsingleton α], P α) + (hstep : ∀ (α) [Finite α] [Nontrivial α], + (∀ (β) [Finite β], Nat.card β < Nat.card α → P β) → P α) : + P α := by + obtain ⟨n, hn⟩ : ∃ n, Nat.card α = n := ⟨Nat.card α, rfl⟩ + induction n using Nat.strong_induction_on generalizing α with | _ n ih + rcases subsingleton_or_nontrivial α with hsing | hnontriv + · apply hbase + · apply hstep + intro β _ hlt + rw [hn] at hlt + exact ih (Nat.card β) hlt _ rfl + end Finite namespace ENat From e91869b3f7e43297eb8ecae06142b0e1c163a475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Wed, 29 Jul 2026 08:56:56 +0000 Subject: [PATCH 1070/1300] feat: lemmas about the `smallInductiveDimension` (#40879) We prove various lemmas about the `smallInductiveDimension` of a topological space, as well as interactions with the `HasSmallInductiveDimensionLT` and `HasSmallInductiveDimensionLE` typeclasses. --- Mathlib/Topology/SmallInductiveDimension.lean | 76 +++++++++++++++++-- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/Mathlib/Topology/SmallInductiveDimension.lean b/Mathlib/Topology/SmallInductiveDimension.lean index 811b88bf42dbe9..b5087dd23ef3fa 100644 --- a/Mathlib/Topology/SmallInductiveDimension.lean +++ b/Mathlib/Topology/SmallInductiveDimension.lean @@ -33,7 +33,7 @@ In this file we formalize this notion, and characterize the cases `n = 0` and `n @[expose] public section -open Set TopologicalSpace +open Set Topology TopologicalSpace /-- For a topological space, the property of having small inductive dimension less than `n : ℕ` is @@ -45,7 +45,7 @@ class inductive HasSmallInductiveDimensionLT.{u} : ∀ (X : Type u) [TopologicalSpace X], ℕ → Prop where | zero {X : Type u} [TopologicalSpace X] [IsEmpty X] : HasSmallInductiveDimensionLT X 0 | succ {X : Type u} [TopologicalSpace X] (n : ℕ) (s : Set (Set X)) (hs : IsTopologicalBasis s) - (h : ∀ U ∈ s, HasSmallInductiveDimensionLT ↑(frontier U) n) : + (h : ∀ U ∈ s, HasSmallInductiveDimensionLT (frontier U) n) : HasSmallInductiveDimensionLT X (n + 1) variable {X : Type*} [TopologicalSpace X] @@ -55,12 +55,8 @@ variable (X) in abbrev HasSmallInductiveDimensionLE (n : ℕ) := HasSmallInductiveDimensionLT X (n + 1) -variable (X) in -/-- The small inductive dimension of a topological space. -/ -noncomputable def smallInductiveDimension : WithBot ℕ∞ := - sInf {n : WithBot ℕ∞ | ∀ (i : ℕ), n < i → HasSmallInductiveDimensionLT X i} - -lemma hasSmallInductiveDimensionLT_zero_iff : HasSmallInductiveDimensionLT X 0 ↔ IsEmpty X := +@[simp] +theorem hasSmallInductiveDimensionLT_zero_iff : HasSmallInductiveDimensionLT X 0 ↔ IsEmpty X := ⟨fun h ↦ by cases h; assumption, fun _ ↦ .zero⟩ @[deprecated (since := "2026-06-21")] @@ -101,3 +97,67 @@ theorem HasSmallInductiveDimensionLT.hasSmallInductiveDimensionLE {n : ℕ} instance (n : ℕ) [IsEmpty X] : HasSmallInductiveDimensionLT X n := .mono zero_le <| hasSmallInductiveDimensionLT_zero_iff.2 ‹_› + +/-! ### Small inductive dimension -/ + +variable (X) in +/-- The small inductive dimension of a topological space. -/ +noncomputable def smallInductiveDimension : WithBot ℕ∞ := + sInf {n | ∀ i : ℕ, n < i → HasSmallInductiveDimensionLT X i} + +private theorem hasSmallInductiveDimensionLT_of_smallInductiveDimension_lt {n : ℕ} + (h : smallInductiveDimension X < n) : HasSmallInductiveDimensionLT X n := by + contrapose! h + simp only [smallInductiveDimension, le_sInf_iff, mem_ofPred_eq] + intro a ha + contrapose! ha + exact ⟨n, ha, h⟩ + +private theorem hasSmallInductiveDimensionLE_of_smallInductiveDimension_le {n : ℕ} + (h : smallInductiveDimension X ≤ n) : HasSmallInductiveDimensionLE X n := by + apply hasSmallInductiveDimensionLT_of_smallInductiveDimension_lt (h.trans_lt _) + exact_mod_cast n.lt_add_one + +theorem smallInductiveDimension_le_iff {n : ℕ} : + smallInductiveDimension X ≤ n ↔ HasSmallInductiveDimensionLE X n where + mp := hasSmallInductiveDimensionLE_of_smallInductiveDimension_le + mpr h := sInf_le fun m hm ↦ .mono (by simpa using hm) h + +theorem smallInductiveDimension_lt_iff {n : ℕ} : + smallInductiveDimension X < n ↔ HasSmallInductiveDimensionLT X n where + mp := hasSmallInductiveDimensionLT_of_smallInductiveDimension_lt + mpr h := by + cases n with + | zero => + rw [smallInductiveDimension, csInf_eq_bot_of_bot_mem] + · simp + · exact fun _ _ ↦ h.mono zero_le + | succ n => + apply (smallInductiveDimension_le_iff.2 h).trans_lt + exact_mod_cast n.lt_add_one + +variable (X) in +theorem smallInductiveDimension_le (n : ℕ) [H : HasSmallInductiveDimensionLE X n] : + smallInductiveDimension X ≤ n := + smallInductiveDimension_le_iff.2 H + +variable (X) in +theorem smallInductiveDimension_lt (n : ℕ) [H : HasSmallInductiveDimensionLT X n] : + smallInductiveDimension X < n := + smallInductiveDimension_lt_iff.2 H + +theorem smallInductiveDimension_eq (n : ℕ) + (hle : HasSmallInductiveDimensionLE X n) (hlt : ¬ HasSmallInductiveDimensionLT X n) : + smallInductiveDimension X = n := by + apply (smallInductiveDimension_le_iff.2 hle).antisymm + rwa [← not_lt, smallInductiveDimension_lt_iff] + +@[simp] +theorem smallInductiveDimension_eq_bot : smallInductiveDimension X = ⊥ ↔ IsEmpty X := by + simp_rw [← hasSmallInductiveDimensionLT_zero_iff, ← smallInductiveDimension_lt_iff, + WithBot.lt_coe_bot.symm, bot_eq_zero', Nat.cast_zero, WithBot.coe_zero] + +variable (X) in +@[simp] +theorem smallInductiveDimension_of_isEmpty [IsEmpty X] : smallInductiveDimension X = ⊥ := + smallInductiveDimension_eq_bot.2 ‹_› From 6d8afdba83d18ca3e6c8a5838ef7d5d5d548cb09 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 29 Jul 2026 08:56:59 +0000 Subject: [PATCH 1071/1300] chore: remove some (triple) underscore soup (#42208) Inspired by #42205. I searched for ` _ _ _]` in vscode and manually went through all ~25 and see if they could be removed (and in some cases some minor style improvement). For ` _ _]` it is already over 100, so that work ought to be automatised Co-authored-by: Batixx --- Mathlib/Algebra/Group/Defs.lean | 2 +- Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean | 6 +++--- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 2 +- Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean | 2 +- Mathlib/Data/Finset/Density.lean | 2 +- Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean | 2 +- Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean | 2 +- Mathlib/Topology/UniformSpace/Ascoli.lean | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 3111721ff63fc4..72942dc5428ad4 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -1117,7 +1117,7 @@ theorem inv_eq_one_div (x : G) : x⁻¹ = 1 / x := by rw [div_eq_mul_inv, one_mu @[to_additive] theorem mul_div_assoc (a b c : G) : a * b / c = a * (b / c) := by - rw [div_eq_mul_inv, div_eq_mul_inv, mul_assoc _ _ _] + rw [div_eq_mul_inv, div_eq_mul_inv, mul_assoc] @[to_additive (attr := simp)] theorem one_div (a : G) : 1 / a = a⁻¹ := diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean index 1defc05fd53742..ce9b8010738ccc 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean @@ -811,7 +811,7 @@ instance [AddMonoid k] [SMul S₁ S₂] [SMulZeroClass S₁ k] [SMulZeroClass S instance [AddMonoid k] [SMulZeroClass S₁ k] [SMulZeroClass S₂ k] [SMulCommClass S₁ S₂ k] : SMulCommClass S₁ S₂ (SkewMonoidAlgebra k G) := - ⟨fun _ _ ⟨_⟩ ↦ by simp_rw [← ofCoeff_smul, smul_comm _ _ _]⟩ + ⟨fun _ _ ⟨_⟩ ↦ by simp_rw [← ofCoeff_smul, smul_comm]⟩ instance [AddMonoid k] [SMulZeroClass S k] [SMulZeroClass Sᵐᵒᵖ k] [IsCentralScalar S k] : IsCentralScalar S (SkewMonoidAlgebra k G) := @@ -897,7 +897,7 @@ theorem coeff_mul_antidiagonal_of_finset (f g : SkewMonoidAlgebra k G) (x : G) let F : G × G → k := fun p ↦ if p.1 * p.2 = x then f.coeff p.1 * p.1 • g.coeff p.2 else 0 calc (f * g).coeff x = ∑ a₁ ∈ f.support, ∑ a₂ ∈ g.support, F (a₁, a₂) := coeff_mul f g x - _ = ∑ p ∈ f.support ×ˢ g.support, F p := by rw [← Finset.sum_product _ _ _] + _ = ∑ p ∈ f.support ×ˢ g.support, F p := by rw [Finset.sum_product] _ = ∑ p ∈ (f.support ×ˢ g.support).filter fun p : G × G ↦ p.1 * p.2 = x, f.coeff p.1 * p.1 • g.coeff p.2 := (Finset.sum_filter _ _).symm _ = ∑ p ∈ s.filter fun p : G × G ↦ p.1 ∈ f.support ∧ p.2 ∈ g.support, @@ -923,7 +923,7 @@ theorem coeff_mul_antidiagonal_finsum (f g : SkewMonoidAlgebra k G) (x : G) : let F : G × G → k := fun p ↦ if p.1 * p.2 = x then f.coeff p.1 * p.1 • g.coeff p.2 else 0 calc (f * g).coeff x = ∑ a₁ ∈ f.support, ∑ a₂ ∈ g.support, F (a₁, a₂) := coeff_mul f g x - _ = ∑ p ∈ f.support ×ˢ g.support, F p := by rw [← Finset.sum_product _ _ _] + _ = ∑ p ∈ f.support ×ˢ g.support, F p := by rw [Finset.sum_product] _ = ∑ p ∈ (f.support ×ˢ g.support).filter fun p : G × G ↦ p.1 * p.2 = x, f.coeff p.1 * p.1 • g.coeff p.2 := (Finset.sum_filter _ _).symm _ = ∑ p ∈ s.filter fun p : G × G ↦ p.1 ∈ f.support ∧ p.2 ∈ g.support, diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index eef257f5abbe4e..b7d7e35ae75a0f 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -745,7 +745,7 @@ theorem eq_σ_comp_of_not_injective' {n : ℕ} {Δ' : SimplexCategory} (θ : ⦋ by_cases h' : x ≤ Fin.castSucc i · rw [Fin.predAbove_of_le_castSucc i x h'] dsimp [δ] - rw [Fin.succAbove_of_castSucc_lt _ _ _] + rw [Fin.succAbove_of_castSucc_lt] · rw [Fin.castSucc_castPred] · exact (Fin.castSucc_lt_succ_iff.mpr h') · simp only [not_le] at h' diff --git a/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean b/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean index f847a89d7e6491..92375dd9017580 100644 --- a/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean +++ b/Mathlib/CategoryTheory/ConcreteCategory/ReflectsIso.lean @@ -36,7 +36,7 @@ instance reflectsIsomorphisms_forget₂ [HasForget₂ C D] [(forget C).ReflectsI { reflects := fun X Y f {i} => by have i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _ have : IsIso ((forget C).map f) := by - rwa [← @HasForget₂.forget_comp C _ _ _ _ _ D _ _ _ _ _] + rwa [← @HasForget₂.forget_comp (C := C) (D := D)] apply isIso_of_reflects_iso f (forget C) } end CategoryTheory diff --git a/Mathlib/Data/Finset/Density.lean b/Mathlib/Data/Finset/Density.lean index 847080985a91f1..3c837b046b56fd 100644 --- a/Mathlib/Data/Finset/Density.lean +++ b/Mathlib/Data/Finset/Density.lean @@ -167,7 +167,7 @@ lemma dens_inter_add_dens_union (s t : Finset α) : dens (s ∩ t) + dens (s ∪ t) = dens s + dens t := by rw [add_comm, dens_union_add_dens_inter] @[simp] lemma dens_union_of_disjoint (h : Disjoint s t) : dens (s ∪ t) = dens s + dens t := by - rw [← disjUnion_eq_union s t h, dens_disjUnion _ _ _] + rw [← disjUnion_eq_union s t h, dens_disjUnion] lemma dens_sdiff_add_dens_eq_dens (h : s ⊆ t) : dens (t \ s) + dens s = dens t := by simp [dens, ← card_sdiff_add_card_eq_card h, add_div] diff --git a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean index 3b52650f79da2d..970a536cb95257 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean @@ -152,7 +152,7 @@ theorem one_left (b : ℕ) : J(1 | b) = 1 := /-- The Jacobi symbol is multiplicative in its first argument. -/ theorem mul_left (a₁ a₂ : ℤ) (b : ℕ) : J(a₁ * a₂ | b) = J(a₁ | b) * J(a₂ | b) := by - simp_rw [jacobiSym, List.pmap_eq_map_attach, legendreSym.mul _ _ _] + simp_rw [jacobiSym, List.pmap_eq_map_attach, legendreSym.mul] exact List.prod_map_mul (l := (primeFactorsList b).attach) (f := fun x ↦ @legendreSym x { out := prime_of_mem_primeFactorsList x.2 } a₁) (g := fun x ↦ @legendreSym x { out := prime_of_mem_primeFactorsList x.2 } a₂) diff --git a/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean b/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean index 3c893ab7a53aa8..2e66a2bfa54cac 100644 --- a/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean +++ b/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean @@ -139,7 +139,7 @@ theorem norm_nonneg (x : ℤ[i]) : 0 ≤ norm x := Zsqrtd.norm_nonneg (by simp) _ @[simp] -theorem norm_eq_zero {x : ℤ[i]} : norm x = 0 ↔ x = 0 := by rw [← @Int.cast_inj ℝ _ _ _]; simp +theorem norm_eq_zero {x : ℤ[i]} : norm x = 0 ↔ x = 0 := by rw [← Int.cast_inj (α := ℝ)]; simp theorem norm_pos {x : ℤ[i]} : 0 < norm x ↔ x ≠ 0 := by rw [lt_iff_le_and_ne, Ne, eq_comm, norm_eq_zero]; simp [norm_nonneg] diff --git a/Mathlib/Topology/UniformSpace/Ascoli.lean b/Mathlib/Topology/UniformSpace/Ascoli.lean index 716a7b82de3960..5c7c248f62fcc5 100644 --- a/Mathlib/Topology/UniformSpace/Ascoli.lean +++ b/Mathlib/Topology/UniformSpace/Ascoli.lean @@ -501,7 +501,7 @@ theorem ArzelaAscoli.isCompact_of_equicontinuous suffices h : IsInducing (Equiv.Set.image _ S DFunLike.coe_injective) by rw [isCompact_iff_compactSpace] at hS1 ⊢ exact (Equiv.toHomeomorphOfIsInducing _ h).symm.compactSpace - rw [← IsInducing.subtypeVal.of_comp_iff, ← EquicontinuousOn.isInducing_uniformOnFun_iff_pi _ _ _] + rw [← IsInducing.subtypeVal.of_comp_iff, ← EquicontinuousOn.isInducing_uniformOnFun_iff_pi] · exact ContinuousMap.isUniformEmbedding_toUniformOnFunIsCompact.isInducing.comp .subtypeVal · exact eq_univ_iff_forall.mpr (fun x ↦ mem_sUnion_of_mem (mem_singleton x) isCompact_singleton) · exact fun _ ↦ id From 7630dcddf054c350d73150d536390a15dbd1afc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 29 Jul 2026 08:57:01 +0000 Subject: [PATCH 1072/1300] chore(AlgebraicTopology/SimplexCategory): delete synthesizable instances (#42222) `inferInstance` works in place of `inferInstanceAs` in both places. [Zulip](https://leanprover.zulipchat.com/#narrow/channel/583339-AI-authored-projects/topic/Comparator-related.20import.20subtleties/with/613349677) --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index b7d7e35ae75a0f..fef916f767c589 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -596,12 +596,6 @@ instance : ConcreteCategory SimplexCategory (fun i j => Fin (i.len + 1) →o Fin hom := Hom.toOrderHom ofHom f := Hom.mk f -instance (x : SimplexCategory) : Fintype (ToType x) := - inferInstanceAs (Fintype (Fin _)) - -instance (x : SimplexCategory) (n : ℕ) : OfNat (ToType x) n := - inferInstanceAs (OfNat (Fin _) n) - lemma toType_apply (x : SimplexCategory) : ToType x = Fin (x.len + 1) := rfl @[simp] From 53a560fefea0a9525485d49d9f1c811ed89ae6f0 Mon Sep 17 00:00:00 2001 From: damiano Date: Wed, 29 Jul 2026 11:09:52 +0000 Subject: [PATCH 1073/1300] chore: rename `QuotientAddGroup.mk_out_eq_mul` to `mk_out_eq_add` (#41654) The additive lemma states `(mk g).out = g + h`, so by the `to_additive` naming convention its name should end in `add`, not `mul`. Rename it to `QuotientAddGroup.mk_out_eq_add` (a copy-paste error inherited from mathlib3) and deprecate the old name. --- Mathlib/GroupTheory/Coset/Defs.lean | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mathlib/GroupTheory/Coset/Defs.lean b/Mathlib/GroupTheory/Coset/Defs.lean index 2af03b2d5f21d5..e50fde599d2ed3 100644 --- a/Mathlib/GroupTheory/Coset/Defs.lean +++ b/Mathlib/GroupTheory/Coset/Defs.lean @@ -209,7 +209,7 @@ variable (s) /-- It can be useful to write `obtain ⟨h, H⟩ := mk_out_eq_mul ...`, and then `rw [H]` or `simp_rw [H]` or `simp only [H]`. In order for `simp_rw` and `simp only` to work, this lemma is stated in terms of an arbitrary `h : s`, rather than the specific `h = g⁻¹ * (mk g).out`. -/ -@[to_additive QuotientAddGroup.mk_out_eq_mul] +@[to_additive] theorem mk_out_eq_mul (g : α) : ∃ h : s, (mk g : α ⧸ s).out = g * h := ⟨⟨g⁻¹ * (mk g).out, QuotientGroup.eq.mp (mk g).out_eq'.symm⟩, by rw [mul_inv_cancel_left]⟩ @@ -249,6 +249,9 @@ theorem preimage_mk_one (N : Subgroup α) : end QuotientGroup +@[deprecated (since := "2026-07-12")] +alias QuotientAddGroup.mk_out_eq_mul := QuotientAddGroup.mk_out_eq_add + namespace Subgroup open QuotientGroup From d160677fd383cf76893d1cba56bf84f251052956 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 29 Jul 2026 12:40:37 +0000 Subject: [PATCH 1074/1300] chore(Archive): convert to the module system (#42010) This is just a general good practice these days. Two specific reasons are: - the module system makes thing faster, for example by reducing how much stuff has to be imported. - In the long run, we want to only support the module system, and not any non-module system uses of mathlib. #41950 signals this. That way, we can use no_expose, without needing to worry about uses without the module system where the definition will be exposed anyways. The migration is mostly mechanical, akin to what `modulize.lean` would do: make all imports `public`, and add `@[expose] public section` at the beginning of each file. (In a few cases of files without definitions, omit the expose attribute.) Inspired by #36236; re-done by hand. All files omitted there are actually fine to hand-convert. --- Counterexamples.lean | 60 ++++++++++--------- Counterexamples/AharoniKorman.lean | 16 +++-- .../CanonicallyOrderedCommSemiringTwoMul.lean | 8 ++- Counterexamples/CharPZeroNeCharZero.lean | 7 ++- .../CliffordAlgebraNotInjective.lean | 19 +++--- Counterexamples/Cyclotomic105.lean | 8 ++- Counterexamples/DimensionPolynomial.lean | 12 ++-- Counterexamples/DirectSumIsInternal.lean | 12 ++-- ...DiscreteTopologyNonDiscreteUniformity.lean | 6 +- Counterexamples/EulerSumOfPowers.lean | 5 +- Counterexamples/Girard.lean | 7 ++- Counterexamples/HeawoodUnitDistance.lean | 8 ++- Counterexamples/HomogeneousPrimeNotPrime.lean | 12 ++-- Counterexamples/InvertibleModuleNotIdeal.lean | 10 +++- .../IrrationalPowerOfIrrational.lean | 9 +-- Counterexamples/MapFloor.lean | 15 +++-- Counterexamples/MonicNonRegular.lean | 6 +- Counterexamples/Motzkin.lean | 8 ++- Counterexamples/NowhereDifferentiable.lean | 11 ++-- .../OrderedCancelAddCommMonoidWithBounds.lean | 6 +- Counterexamples/PeanoCurve.lean | 10 +++- Counterexamples/Phillips.lean | 15 +++-- Counterexamples/PolynomialIsDomain.lean | 14 +++-- Counterexamples/Pseudoelement.lean | 11 ++-- Counterexamples/QuadraticForm.lean | 6 +- .../SeminormLatticeNotDistrib.lean | 7 ++- .../SeparableNotSecondCountable.lean | 6 +- Counterexamples/SorgenfreyLine.lean | 23 ++++--- Counterexamples/TopologistsSineCurve.lean | 8 ++- .../ZeroDivisorsInAddMonoidAlgebras.lean | 14 +++-- 30 files changed, 216 insertions(+), 143 deletions(-) diff --git a/Counterexamples.lean b/Counterexamples.lean index 7a514ba1e05c20..80c2aea1aec1e6 100644 --- a/Counterexamples.lean +++ b/Counterexamples.lean @@ -1,29 +1,31 @@ -import Counterexamples.AharoniKorman -import Counterexamples.CanonicallyOrderedCommSemiringTwoMul -import Counterexamples.CharPZeroNeCharZero -import Counterexamples.CliffordAlgebraNotInjective -import Counterexamples.Cyclotomic105 -import Counterexamples.DimensionPolynomial -import Counterexamples.DirectSumIsInternal -import Counterexamples.DiscreteTopologyNonDiscreteUniformity -import Counterexamples.EulerSumOfPowers -import Counterexamples.Girard -import Counterexamples.HeawoodUnitDistance -import Counterexamples.HomogeneousPrimeNotPrime -import Counterexamples.InvertibleModuleNotIdeal -import Counterexamples.IrrationalPowerOfIrrational -import Counterexamples.MapFloor -import Counterexamples.MonicNonRegular -import Counterexamples.Motzkin -import Counterexamples.NowhereDifferentiable -import Counterexamples.OrderedCancelAddCommMonoidWithBounds -import Counterexamples.PeanoCurve -import Counterexamples.Phillips -import Counterexamples.PolynomialIsDomain -import Counterexamples.Pseudoelement -import Counterexamples.QuadraticForm -import Counterexamples.SeminormLatticeNotDistrib -import Counterexamples.SeparableNotSecondCountable -import Counterexamples.SorgenfreyLine -import Counterexamples.TopologistsSineCurve -import Counterexamples.ZeroDivisorsInAddMonoidAlgebras +module -- shake: keep-all --deprecated_module: ignore + +public import Counterexamples.AharoniKorman +public import Counterexamples.CanonicallyOrderedCommSemiringTwoMul +public import Counterexamples.CharPZeroNeCharZero +public import Counterexamples.CliffordAlgebraNotInjective +public import Counterexamples.Cyclotomic105 +public import Counterexamples.DimensionPolynomial +public import Counterexamples.DirectSumIsInternal +public import Counterexamples.DiscreteTopologyNonDiscreteUniformity +public import Counterexamples.EulerSumOfPowers +public import Counterexamples.Girard +public import Counterexamples.HeawoodUnitDistance +public import Counterexamples.HomogeneousPrimeNotPrime +public import Counterexamples.InvertibleModuleNotIdeal +public import Counterexamples.IrrationalPowerOfIrrational +public import Counterexamples.MapFloor +public import Counterexamples.MonicNonRegular +public import Counterexamples.Motzkin +public import Counterexamples.NowhereDifferentiable +public import Counterexamples.OrderedCancelAddCommMonoidWithBounds +public import Counterexamples.PeanoCurve +public import Counterexamples.Phillips +public import Counterexamples.PolynomialIsDomain +public import Counterexamples.Pseudoelement +public import Counterexamples.QuadraticForm +public import Counterexamples.SeminormLatticeNotDistrib +public import Counterexamples.SeparableNotSecondCountable +public import Counterexamples.SorgenfreyLine +public import Counterexamples.TopologistsSineCurve +public import Counterexamples.ZeroDivisorsInAddMonoidAlgebras diff --git a/Counterexamples/AharoniKorman.lean b/Counterexamples/AharoniKorman.lean index a7f42ed111cf6c..25abfb4d362143 100644 --- a/Counterexamples/AharoniKorman.lean +++ b/Counterexamples/AharoniKorman.lean @@ -3,12 +3,14 @@ Copyright (c) 2024 Bhavik Mehta. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Bhavik Mehta -/ -import Mathlib.Algebra.Order.Field.Basic -import Mathlib.Algebra.Order.Field.Rat -import Mathlib.Data.Setoid.Partition -import Mathlib.Order.Filter.AtTopBot.Basic -import Mathlib.Order.Interval.Set.Infinite -import Mathlib.Order.WellFoundedSet +module + +public import Mathlib.Algebra.Order.Field.Basic +public import Mathlib.Algebra.Order.Field.Rat +public import Mathlib.Data.Setoid.Partition +public import Mathlib.Order.Filter.AtTopBot.Basic +public import Mathlib.Order.Interval.Set.Infinite +public import Mathlib.Order.WellFoundedSet /-! # Disproof of the Aharoni–Korman conjecture @@ -67,6 +69,8 @@ aim of reaching a contradiction (as then, no such partition can exist). We may f we have a contradiction (`no_spinalMap`), and therefore show that no spinal map exists. -/ +@[expose] public section + attribute [aesop 2 simp] Set.subset_def Finset.subset_iff /-- A type synonym on ℕ³ on which we will construct Hollom's partial order P_5. -/ diff --git a/Counterexamples/CanonicallyOrderedCommSemiringTwoMul.lean b/Counterexamples/CanonicallyOrderedCommSemiringTwoMul.lean index 16029d0bd999c6..fc6001a2079117 100644 --- a/Counterexamples/CanonicallyOrderedCommSemiringTwoMul.lean +++ b/Counterexamples/CanonicallyOrderedCommSemiringTwoMul.lean @@ -3,8 +3,10 @@ Copyright (c) 2021 Damiano Testa. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Damiano Testa -/ -import Mathlib.Algebra.Ring.Subsemiring.Order -import Mathlib.Data.ZMod.Basic +module + +public import Mathlib.Algebra.Ring.Subsemiring.Order +public import Mathlib.Data.ZMod.Basic /-! # A canonically ordered commutative semiring where multiplication by 2 is not injective @@ -24,7 +26,7 @@ Reference: https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/canonically_ordered.20pathology -/ - +@[expose] public section namespace Counterexample diff --git a/Counterexamples/CharPZeroNeCharZero.lean b/Counterexamples/CharPZeroNeCharZero.lean index fcb0eb5e258ee4..4532e2e779d8a8 100644 --- a/Counterexamples/CharPZeroNeCharZero.lean +++ b/Counterexamples/CharPZeroNeCharZero.lean @@ -3,8 +3,10 @@ Copyright (c) 2022 Damiano Testa. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Damiano Testa, Eric Wieser -/ -import Mathlib.Algebra.CharP.Lemmas -import Mathlib.Algebra.Ring.PUnit +module + +public import Mathlib.Algebra.CharP.Lemmas +public import Mathlib.Algebra.Ring.PUnit /-! # `CharP R 0` and `CharZero R` need not coincide for semirings @@ -19,6 +21,7 @@ This file shows that there are semirings `R` for which `CharP R 0` holds and `Ch The example is `{0, 1}` with saturating addition. -/ +@[expose] public section namespace Counterexample diff --git a/Counterexamples/CliffordAlgebraNotInjective.lean b/Counterexamples/CliffordAlgebraNotInjective.lean index f47f319b0e9f62..f6c2d63855131e 100644 --- a/Counterexamples/CliffordAlgebraNotInjective.lean +++ b/Counterexamples/CliffordAlgebraNotInjective.lean @@ -3,12 +3,14 @@ Copyright (c) 2021 Eric Wieser. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Wieser -/ -import Mathlib.Algebra.CharP.Pi -import Mathlib.Algebra.CharP.Quotient -import Mathlib.LinearAlgebra.CliffordAlgebra.Contraction -import Mathlib.RingTheory.MvPolynomial.Basic -import Mathlib.RingTheory.MvPolynomial.Ideal -import Mathlib.Tactic.Ring.NamePolyVars +module + +public import Mathlib.Algebra.CharP.Pi +public import Mathlib.Algebra.CharP.Quotient +public import Mathlib.LinearAlgebra.CliffordAlgebra.Contraction +public import Mathlib.RingTheory.MvPolynomial.Basic +public import Mathlib.RingTheory.MvPolynomial.Ideal +public import Mathlib.Tactic.Ring.NamePolyVars /-! # `algebraMap R (CliffordAlgebra Q)` is not always injective. @@ -30,10 +32,9 @@ As a bonus result, we also show `BilinMap.not_forall_toQuadraticMap_surjective`: are quadratic forms that cannot be expressed via even non-symmetric bilinear forms. -/ -noncomputable section +@[expose] public noncomputable section -open LinearMap (BilinForm) -open LinearMap (BilinMap) +open LinearMap (BilinForm BilinMap) name_poly_vars X, Y, Z over ZMod 2 diff --git a/Counterexamples/Cyclotomic105.lean b/Counterexamples/Cyclotomic105.lean index 8d32ce2328ec6f..abf3c54a2e3a5e 100644 --- a/Counterexamples/Cyclotomic105.lean +++ b/Counterexamples/Cyclotomic105.lean @@ -3,8 +3,10 @@ Copyright (c) 2021 Riccardo Brasca. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Riccardo Brasca -/ -import Mathlib.RingTheory.Polynomial.Cyclotomic.Basic -import Mathlib.Tactic.NormNum.Prime +module + +public import Mathlib.RingTheory.Polynomial.Cyclotomic.Basic +public import Mathlib.Tactic.NormNum.Prime /-! # Not all coefficients of cyclotomic polynomials are -1, 0, or 1 @@ -14,9 +16,9 @@ theorem `not_forall_coeff_cyclotomic_neg_one_zero_one`. We prove this with the c `coeff_cyclotomic_105 : coeff (cyclotomic 105 ℤ) 7 = -2`. -/ +@[expose] public section open Nat (properDivisors) - open Finset namespace Counterexample diff --git a/Counterexamples/DimensionPolynomial.lean b/Counterexamples/DimensionPolynomial.lean index e3b0ec0ba20cc3..7777b22e58ad77 100644 --- a/Counterexamples/DimensionPolynomial.lean +++ b/Counterexamples/DimensionPolynomial.lean @@ -3,10 +3,12 @@ Copyright (c) 2025 Jingting Wang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jingting Wang -/ -import Mathlib.RingTheory.KrullDimension.Polynomial -import Mathlib.RingTheory.KrullDimension.LocalRing -import Mathlib.FieldTheory.RatFunc.AsPolynomial -import Mathlib.RingTheory.PowerSeries.Inverse +module + +public import Mathlib.RingTheory.KrullDimension.Polynomial +public import Mathlib.RingTheory.KrullDimension.LocalRing +public import Mathlib.FieldTheory.RatFunc.AsPolynomial +public import Mathlib.RingTheory.PowerSeries.Inverse /-! # Krull dimension of polynomial ring @@ -22,6 +24,8 @@ We define the commutative ring `A` as `{f ∈ k(t)⟦Y⟧ | f(0) ∈ k}` for a f -/ +@[expose] public section + namespace Counterexample namespace DimensionPolynomial diff --git a/Counterexamples/DirectSumIsInternal.lean b/Counterexamples/DirectSumIsInternal.lean index b2f95cb70a44d2..638eaae576dc66 100644 --- a/Counterexamples/DirectSumIsInternal.lean +++ b/Counterexamples/DirectSumIsInternal.lean @@ -3,10 +3,12 @@ Copyright (c) 2021 Eric Wieser. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Wieser, Kevin Buzzard -/ -import Mathlib.Algebra.DirectSum.Module -import Mathlib.Algebra.Group.ConjFinite -import Mathlib.Data.Fintype.Lattice -import Mathlib.Tactic.FinCases +module + +public import Mathlib.Algebra.DirectSum.Module +public import Mathlib.Algebra.Group.ConjFinite +public import Mathlib.Data.Fintype.Lattice +public import Mathlib.Tactic.FinCases /-! # Not all complementary decompositions of a module over a semiring make up a direct sum @@ -19,6 +21,8 @@ This file demonstrates why `DirectSum.isInternal_submodule_of_iSupIndep_of_iSup_ take `Ring R` and not `Semiring R`. -/ +public section + namespace Counterexample theorem UnitsInt.one_ne_neg_one : (1 : ℤˣ) ≠ -1 := by decide diff --git a/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean b/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean index bd6548b6cf585d..1458342e806767 100644 --- a/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean +++ b/Counterexamples/DiscreteTopologyNonDiscreteUniformity.lean @@ -3,7 +3,9 @@ Copyright (c) 2024 Filippo A. E. Nuccio. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Filippo A. E. Nuccio -/ -import Mathlib.Analysis.SpecificLimits.Basic +module + +public import Mathlib.Analysis.SpecificLimits.Basic /-! # Discrete uniformities and discrete topology @@ -75,6 +77,8 @@ inequality) to explicit subsets, many proofs are easily closed by `aesop` or `om * [N. Bourbaki, *General Topology*, Chapter II][bourbaki1966] -/ +@[expose] public section + open Set Function Filter Metric /- We remove the "usual" instances of (discrete) topological space and of (discrete) uniform space diff --git a/Counterexamples/EulerSumOfPowers.lean b/Counterexamples/EulerSumOfPowers.lean index 69b1fba2b18bcd..1e8e2baef705d1 100644 --- a/Counterexamples/EulerSumOfPowers.lean +++ b/Counterexamples/EulerSumOfPowers.lean @@ -3,7 +3,9 @@ Copyright (c) 2025 Snir Broshi. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Snir Broshi, Michael Stoll -/ -import Mathlib.NumberTheory.FLT.Three +module + +public import Mathlib.NumberTheory.FLT.Three /-! # Euler's sum of powers conjecture @@ -27,6 +29,7 @@ http://euler.free.fr/ https://www.ams.org/journals/mcom/1988-51-184/S0025-5718-1988-0930224-9/S0025-5718-1988-0930224-9.pdf -/ +@[expose] public section namespace Counterexample diff --git a/Counterexamples/Girard.lean b/Counterexamples/Girard.lean index 16ea6890ecf9a7..961031ec7d9fb6 100644 --- a/Counterexamples/Girard.lean +++ b/Counterexamples/Girard.lean @@ -3,8 +3,10 @@ Copyright (c) 2021 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ -import Mathlib.Logic.Basic -import Mathlib.Data.Set.Defs +module + +public import Mathlib.Logic.Basic +public import Mathlib.Data.Set.Defs /-! # Girard's paradox @@ -25,6 +27,7 @@ Based on Watkins' LF implementation of Hurkens' simplification of Girard's parad * `girard`: there are no Girard universes. -/ +@[expose] public section namespace Counterexample diff --git a/Counterexamples/HeawoodUnitDistance.lean b/Counterexamples/HeawoodUnitDistance.lean index 0d199e6a6a4820..a909e32afb4e85 100644 --- a/Counterexamples/HeawoodUnitDistance.lean +++ b/Counterexamples/HeawoodUnitDistance.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Jeremy Tan. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Tan -/ -import Mathlib.Analysis.InnerProductSpace.PiL2 -import Mathlib.Combinatorics.SimpleGraph.UnitDistance.Basic +module + +public import Mathlib.Analysis.InnerProductSpace.PiL2 +public import Mathlib.Combinatorics.SimpleGraph.UnitDistance.Basic /-! # A simple planar unit-distance embedding of the Heawood graph @@ -25,6 +27,8 @@ and Jeremy Tan [in August 2025](https://github.com/Parcly-Taxel/Shibuya/commit/b Its coordinates are polynomials in the unique real root of `2c^3 + 3c + 1`. -/ +@[expose] public section + namespace SimpleGraph open Finset diff --git a/Counterexamples/HomogeneousPrimeNotPrime.lean b/Counterexamples/HomogeneousPrimeNotPrime.lean index f6ad1b8b76c8ed..7b997682cd816b 100644 --- a/Counterexamples/HomogeneousPrimeNotPrime.lean +++ b/Counterexamples/HomogeneousPrimeNotPrime.lean @@ -3,10 +3,12 @@ Copyright (c) 2022 Jujian Zhang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Eric Wieser, Jujian Zhang -/ -import Mathlib.Algebra.Divisibility.Finite -import Mathlib.Algebra.Divisibility.Prod -import Mathlib.Algebra.GroupWithZero.Units.Fintype -import Mathlib.RingTheory.GradedAlgebra.Homogeneous.Ideal +module + +public import Mathlib.Algebra.Divisibility.Finite +public import Mathlib.Algebra.Divisibility.Prod +public import Mathlib.Algebra.GroupWithZero.Units.Fintype +public import Mathlib.RingTheory.GradedAlgebra.Homogeneous.Ideal /-! # A homogeneous ideal that is homogeneously prime but not prime @@ -25,12 +27,12 @@ structure of linear ordered additive commutative monoid by setting `0 + 0 = 0` a and not prime. But it is homogeneously prime, i.e. if `(a, b), (c, d)` are two homogeneous elements then `(a, b) * (c, d) ∈ I` implies either `(a, b) ∈ I` or `(c, d) ∈ I`. - ## Tags homogeneous, prime -/ +@[expose] public section namespace Counterexample diff --git a/Counterexamples/InvertibleModuleNotIdeal.lean b/Counterexamples/InvertibleModuleNotIdeal.lean index bf54f34f6c1f77..8fb5981cf31567 100644 --- a/Counterexamples/InvertibleModuleNotIdeal.lean +++ b/Counterexamples/InvertibleModuleNotIdeal.lean @@ -3,9 +3,11 @@ Copyright (c) 2025 Junyan Xu. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Junyan Xu -/ -import Mathlib.Algebra.TrivSqZeroExt.Basic -import Mathlib.Data.DFinsupp.Module -import Mathlib.RingTheory.PicardGroup +module + +public import Mathlib.Algebra.TrivSqZeroExt.Basic +public import Mathlib.Data.DFinsupp.Module +public import Mathlib.RingTheory.PicardGroup /-! # A class of examples of invertible modules that are not isomorphic to ideals @@ -13,6 +15,8 @@ import Mathlib.RingTheory.PicardGroup References: https://math.stackexchange.com/a/5090562 or https://mathoverflow.net/a/499258 -/ +public section + variable (R : Type*) [CommRing R] /-- The trivial square-zero extension of a commutative ring R given by the direct sum diff --git a/Counterexamples/IrrationalPowerOfIrrational.lean b/Counterexamples/IrrationalPowerOfIrrational.lean index f61b83cdfcbbc0..1598c78874e60d 100644 --- a/Counterexamples/IrrationalPowerOfIrrational.lean +++ b/Counterexamples/IrrationalPowerOfIrrational.lean @@ -3,8 +3,10 @@ Copyright (c) 2024 Seewoo Lee. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Seewoo Lee -/ -import Mathlib.Analysis.SpecialFunctions.Pow.NNReal -import Mathlib.NumberTheory.Real.Irrational +module + +public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal +public import Mathlib.NumberTheory.Real.Irrational /-! # An irrational power of an irrational number need not be irrational @@ -16,7 +18,6 @@ Consider `c = √2^√2`. If `c` is rational, we are done. If `c` is irrational, then `c^√2 = 2` is rational, so we are done. -/ - open Real namespace Counterexample @@ -26,7 +27,7 @@ There exist irrational `a`, `b` with rational `a^b`. Note that the positivity assumption on `a` is imposed because of the definition of `rpow` for negative bases. See `Real.rpow_def_of_neg` for more details. -/ -theorem not_irrational_rpow : +public theorem not_irrational_rpow : ¬ ∀ a b : ℝ, Irrational a → Irrational b → 0 < a → Irrational (a ^ b) := by push Not by_cases hc : Irrational (√2 ^ √2) diff --git a/Counterexamples/MapFloor.lean b/Counterexamples/MapFloor.lean index 9edd2ddce521df..ccd46ac7f452e0 100644 --- a/Counterexamples/MapFloor.lean +++ b/Counterexamples/MapFloor.lean @@ -3,10 +3,12 @@ Copyright (c) 2022 Yaël Dillies. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yaël Dillies -/ -import Mathlib.Algebra.Order.Round -import Mathlib.Algebra.Order.Group.PiLex -import Mathlib.Algebra.Order.Hom.Ring -import Mathlib.Algebra.Polynomial.Reverse +module + +public import Mathlib.Algebra.Order.Round +public import Mathlib.Algebra.Order.Group.PiLex +public import Mathlib.Algebra.Order.Hom.Ring +public import Mathlib.Algebra.Polynomial.Reverse /-! # Floors and ceils aren't preserved under ordered ring homomorphisms @@ -35,11 +37,10 @@ But it does not preserve floors (nor ceils) as `⌊-ε⌋ = -1` while `⌊f (-ε (`IntWithEpsilon.forgetEpsilons_floor_lt`, `IntWithEpsilon.lt_forgetEpsilons_ceil`). -/ +@[expose] public noncomputable section namespace Counterexample -noncomputable section - open Function Int Polynomial /-- The integers with infinitesimals adjoined. Higher powers of `ε` are smaller than lower @@ -130,6 +131,4 @@ theorem lt_forgetEpsilons_ceil (n : ℤ) : end IntWithEpsilon -end - end Counterexample diff --git a/Counterexamples/MonicNonRegular.lean b/Counterexamples/MonicNonRegular.lean index 7efe730dd03c2e..d32455f99d0202 100644 --- a/Counterexamples/MonicNonRegular.lean +++ b/Counterexamples/MonicNonRegular.lean @@ -3,8 +3,9 @@ Copyright (c) 2023 Damiano Testa. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Damiano Testa -/ +module -import Mathlib.Algebra.Polynomial.Monic +public import Mathlib.Algebra.Polynomial.Monic /-! # `Monic` does not necessarily imply `IsRegular` in a `Semiring` with no opposites @@ -23,6 +24,9 @@ The products `(X + 2) * (X + 2)` and `(X + 2) * (X + 3)` are equal to By truncation, `4, 5, 6` all mean `3` in `N`. It follows that multiplication by `(X + 2)` is not injective. -/ + +@[expose] public section + open Polynomial namespace Counterexample.NonRegular diff --git a/Counterexamples/Motzkin.lean b/Counterexamples/Motzkin.lean index 77498fd6603aa5..f7b96bf226c42b 100644 --- a/Counterexamples/Motzkin.lean +++ b/Counterexamples/Motzkin.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Jeremy Tan. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Tan, Heather Macbeth -/ -import Mathlib.Tactic.LinearCombination -import Mathlib.Tactic.Positivity +module + +public import Mathlib.Tactic.LinearCombination +public import Mathlib.Tactic.Positivity /-! # The Motzkin polynomial @@ -21,7 +23,7 @@ variable {K : Type*} [CommRing K] [LinearOrder K] [IsStrictOrderedRing K] /-- The **Motzkin polynomial** is nonnegative. This bivariate polynomial cannot be written as a sum of squares. -/ -lemma motzkin_polynomial_nonneg (x y : K) : +public lemma motzkin_polynomial_nonneg (x y : K) : 0 ≤ x ^ 4 * y ^ 2 + x ^ 2 * y ^ 4 - 3 * x ^ 2 * y ^ 2 + 1 := by by_cases hx : x = 0 · simp [hx] diff --git a/Counterexamples/NowhereDifferentiable.lean b/Counterexamples/NowhereDifferentiable.lean index 2e1abcba12e4e7..ec3671ccf3e4a8 100644 --- a/Counterexamples/NowhereDifferentiable.lean +++ b/Counterexamples/NowhereDifferentiable.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Weiyi Wang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Weiyi Wang -/ -import Mathlib.Analysis.Real.Pi.Bounds -import Mathlib.Topology.Algebra.InfiniteSum.TsumUniformlyOn +module + +public import Mathlib.Analysis.Real.Pi.Bounds +public import Mathlib.Topology.Algebra.InfiniteSum.TsumUniformlyOn /-! # Weierstrass function: a function that is continuous everywhere but differentiable nowhere @@ -29,6 +31,8 @@ which is the original bound given by Karl Weierstrass. There is a better bound $ -/ +@[expose] public section + namespace NowhereDifferentiable open Real Topology Filter @@ -39,8 +43,7 @@ For real parameter $a$ and $b$, define the Weierstrass function as $$f(x) = \sum_{n=0}^\infty a^n \cos (b^n\pi x)$$ -/ -noncomputable -def weierstrass (a b x : ℝ) := ∑' n, a ^ n * cos (b ^ n * π * x) +noncomputable def weierstrass (a b x : ℝ) := ∑' n, a ^ n * cos (b ^ n * π * x) /-! ### Continuity diff --git a/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean b/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean index b5346725242b49..c1d6097a05c6c7 100644 --- a/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean +++ b/Counterexamples/OrderedCancelAddCommMonoidWithBounds.lean @@ -3,8 +3,10 @@ Copyright (c) 2023 Martin Dvorak. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Martin Dvorak -/ -import Mathlib.Algebra.Order.Monoid.Defs -import Mathlib.Order.BoundedOrder.Lattice +module + +public import Mathlib.Algebra.Order.Monoid.Defs +public import Mathlib.Order.BoundedOrder.Lattice /-! # Do not combine `IsOrderedCancelAddMonoid` with `BoundedOrder` diff --git a/Counterexamples/PeanoCurve.lean b/Counterexamples/PeanoCurve.lean index cf1843125341fa..87c36c62a51d72 100644 --- a/Counterexamples/PeanoCurve.lean +++ b/Counterexamples/PeanoCurve.lean @@ -3,16 +3,20 @@ Copyright (c) 2025 Vasilii Nesterov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Vasilii Nesterov -/ -import Mathlib.Analysis.Complex.Tietze -import Mathlib.Topology.MetricSpace.HausdorffAlexandroff +module + +public import Mathlib.Analysis.Complex.Tietze +public import Mathlib.Topology.MetricSpace.HausdorffAlexandroff /-! # Peano curve -This file proves the existence of a Peano curve -- continuous surjective map from the interval +This file proves the existence of a Peano curve -- a continuous surjective map from the interval `[0, 1]` onto the square `[0, 1] × [0, 1]`. -/ +public section + open scoped unitInterval /-- There is a continuous function on `ℝ` that maps the Cantor set to the square. -/ diff --git a/Counterexamples/Phillips.lean b/Counterexamples/Phillips.lean index 53f57c8e18628f..f45f6e352eb1e1 100644 --- a/Counterexamples/Phillips.lean +++ b/Counterexamples/Phillips.lean @@ -3,10 +3,12 @@ Copyright (c) 2021 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ -import Mathlib.Analysis.Normed.Module.HahnBanach -import Mathlib.MeasureTheory.Integral.Bochner.Set -import Mathlib.MeasureTheory.Measure.Lebesgue.Basic -import Mathlib.Topology.ContinuousMap.Bounded.Star +module + +public import Mathlib.Analysis.Normed.Module.HahnBanach +public import Mathlib.MeasureTheory.Integral.Bochner.Set +public import Mathlib.MeasureTheory.Measure.Lebesgue.Basic +public import Mathlib.Topology.ContinuousMap.Bounded.Star /-! # A counterexample on Pettis integrability @@ -72,6 +74,7 @@ on a discrete copy of the original type, as mathlib only contains the space of a continuous functions (which is the useful one). -/ +@[expose] public noncomputable section namespace Counterexample @@ -85,8 +88,6 @@ open Cardinal (aleph) open scoped Cardinal BoundedContinuousFunction -noncomputable section - /-- A copy of a type, endowed with the discrete topology -/ def DiscreteCopy (α : Type u) : Type u := α @@ -583,6 +584,4 @@ theorem no_pettis_integral (Hcont : #ℝ = ℵ₁) : end Phillips1940 -end - end Counterexample diff --git a/Counterexamples/PolynomialIsDomain.lean b/Counterexamples/PolynomialIsDomain.lean index 5f0ecfbb6be36d..4e24bff1a26cb4 100644 --- a/Counterexamples/PolynomialIsDomain.lean +++ b/Counterexamples/PolynomialIsDomain.lean @@ -3,10 +3,12 @@ Copyright (c) 2025 Junyan Xu. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Junyan Xu -/ -import Mathlib.Algebra.GroupWithZero.TransferInstance -import Mathlib.Algebra.Order.Ring.Nat -import Mathlib.Algebra.Ring.Equiv -import Mathlib.RingTheory.Polynomial.Opposites +module + +public import Mathlib.Algebra.GroupWithZero.TransferInstance +public import Mathlib.Algebra.Order.Ring.Nat +public import Mathlib.Algebra.Ring.Equiv +public import Mathlib.RingTheory.Polynomial.Opposites /-! # A commutative semiring that is a domain whose polynomial semiring is not a domain @@ -18,8 +20,10 @@ As a consequence, the polynomial semiring `NatMaxAdd[X]` is not a domain, even though it has no zero-divisors other than 0. -/ +public section + /-- A type synonym for ℕ equipped with maximum as addition. -/ -def NatMaxAdd := ℕ +@[expose] def NatMaxAdd := ℕ open scoped Polynomial diff --git a/Counterexamples/Pseudoelement.lean b/Counterexamples/Pseudoelement.lean index 2bc8b8fc8a2a50..0924871e0c3226 100644 --- a/Counterexamples/Pseudoelement.lean +++ b/Counterexamples/Pseudoelement.lean @@ -3,8 +3,10 @@ Copyright (c) 2022 Riccardo Brasca. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Riccardo Brasca -/ -import Mathlib.CategoryTheory.Abelian.Pseudoelements -import Mathlib.Algebra.Category.ModuleCat.Biproducts +module + +public import Mathlib.CategoryTheory.Abelian.Pseudoelements +public import Mathlib.Algebra.Category.ModuleCat.Biproducts /-! # Pseudoelements and pullbacks @@ -29,13 +31,12 @@ given by `t ↦ (t, 2 * t)` and `y : ℚ ⟶ ℚ ⊞ ℚ` given by `t ↦ (t, t) * [F. Borceux, *Handbook of Categorical Algebra 2*][borceux-vol2] -/ +@[expose] public noncomputable section open CategoryTheory.Abelian CategoryTheory CategoryTheory.Limits ModuleCat LinearMap namespace Counterexample -noncomputable section - open CategoryTheory.Abelian.Pseudoelement /-- `x` is given by `t ↦ (t, 2 * t)`. -/ @@ -118,6 +119,4 @@ theorem exist_ne_and_fst_eq_fst_and_snd_eq_snd : pseudoApply biprod.snd x = pseudoApply biprod.snd y := ⟨⟦x⟧, ⟦y⟧, mk'_x_ne_mk'_y, fst_mk'_x_eq_fst_mk'_y, snd_mk'_x_eq_snd_mk'_y⟩ -end - end Counterexample diff --git a/Counterexamples/QuadraticForm.lean b/Counterexamples/QuadraticForm.lean index b6466778a9e980..16210d6f984098 100644 --- a/Counterexamples/QuadraticForm.lean +++ b/Counterexamples/QuadraticForm.lean @@ -3,7 +3,9 @@ Copyright (c) 2023 Eric Wieser. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Wieser -/ -import Mathlib.LinearAlgebra.QuadraticForm.Basic +module + +public import Mathlib.LinearAlgebra.QuadraticForm.Basic /-! # `QuadraticForm R M` and `Subtype LinearMap.IsSymm` are distinct notions in characteristic 2 @@ -13,6 +15,7 @@ The main result of this file is `LinearMap.BilinForm.not_injOn_toQuadraticForm_i The counterexample we use is $B (x, y) (x', y') ↦ xy' + x'y$ where `x y x' y' : ZMod 2`. -/ +@[expose] public section variable (F : Type*) [CommRing F] @@ -23,7 +26,6 @@ open LinearMap.BilinMap namespace Counterexample - /-- The bilinear form we will use as a counterexample, over some field `F` of characteristic two. -/ def B : BilinForm F (F × F) := (mul F F).compl₁₂ (fst _ _ _) (snd _ _ _) + (mul F F).compl₁₂ (snd _ _ _) (fst _ _ _) diff --git a/Counterexamples/SeminormLatticeNotDistrib.lean b/Counterexamples/SeminormLatticeNotDistrib.lean index 536a6c30ea007a..5ea73a444e107c 100644 --- a/Counterexamples/SeminormLatticeNotDistrib.lean +++ b/Counterexamples/SeminormLatticeNotDistrib.lean @@ -3,7 +3,9 @@ Copyright (c) 2022 Pierre-Alexandre Bazin. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Pierre-Alexandre Bazin -/ -import Mathlib.Analysis.Seminorm +module + +public import Mathlib.Analysis.Seminorm /-! # The lattice of seminorms is not distributive @@ -18,8 +20,9 @@ This proves the lattice `Seminorm ℝ (ℝ × ℝ)` is not distributive. * https://en.wikipedia.org/wiki/Seminorm#Examples -/ -open Seminorm +@[expose] public section +open Seminorm open scoped NNReal namespace Counterexample diff --git a/Counterexamples/SeparableNotSecondCountable.lean b/Counterexamples/SeparableNotSecondCountable.lean index bdc8853b913742..a3a19c7f0f330e 100644 --- a/Counterexamples/SeparableNotSecondCountable.lean +++ b/Counterexamples/SeparableNotSecondCountable.lean @@ -3,7 +3,9 @@ Copyright (c) 2025 Yury G. Kudryashov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury G. Kudryashov -/ -import Mathlib.Analysis.Real.Cardinality +module + +public import Mathlib.Analysis.Real.Cardinality /-! # Example of a linear order which is a separable space but is not a second countable topology @@ -16,6 +18,8 @@ so that the duplicate is greater than the original point and points with different real values are compared by these values. -/ +public section + open Set TopologicalSpace namespace RealProdLexBool diff --git a/Counterexamples/SorgenfreyLine.lean b/Counterexamples/SorgenfreyLine.lean index 6618e73e90a815..40a7a881d66b8f 100644 --- a/Counterexamples/SorgenfreyLine.lean +++ b/Counterexamples/SorgenfreyLine.lean @@ -3,14 +3,16 @@ Copyright (c) 2022 Yury Kudryashov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov -/ -import Mathlib.Analysis.Real.Cardinality -import Mathlib.Order.Interval.Set.Monotone -import Mathlib.Topology.Baire.Lemmas -import Mathlib.Topology.Baire.LocallyCompactRegular -import Mathlib.Topology.EMetricSpace.Paracompact -import Mathlib.Topology.Instances.Irrational -import Mathlib.Topology.Metrizable.Urysohn -import Mathlib.Topology.Separation.NotNormal +module + +public import Mathlib.Analysis.Real.Cardinality +public import Mathlib.Order.Interval.Set.Monotone +public import Mathlib.Topology.Baire.Lemmas +public import Mathlib.Topology.Baire.LocallyCompactRegular +public import Mathlib.Topology.EMetricSpace.Paracompact +public import Mathlib.Topology.Instances.Irrational +public import Mathlib.Topology.Metrizable.Urysohn +public import Mathlib.Topology.Separation.NotNormal /-! # Sorgenfrey line @@ -32,14 +34,13 @@ Prove that the Sorgenfrey line is a paracompact space. -/ +@[expose] public noncomputable section open Set Filter TopologicalSpace open scoped Topology Cardinal namespace Counterexample -noncomputable section - /-- The Sorgenfrey line (denoted as `ℝₗ` within the `SorgenfreyLine` namespace). It is the real line with the topology space structure generated by half-open intervals `Set.Ico a b`. -/ @@ -321,6 +322,4 @@ theorem not_secondCountableTopology : ¬SecondCountableTopology ℝₗ := end SorgenfreyLine -end - end Counterexample diff --git a/Counterexamples/TopologistsSineCurve.lean b/Counterexamples/TopologistsSineCurve.lean index 15f0293b588fc8..218afac81a1db9 100644 --- a/Counterexamples/TopologistsSineCurve.lean +++ b/Counterexamples/TopologistsSineCurve.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Daniele Bolla. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Daniele Bolla, David Loeffler -/ -import Mathlib.Analysis.SpecialFunctions.Trigonometric.Inverse -import Mathlib.Topology.Connected.PathConnected +module + +public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Inverse +public import Mathlib.Topology.Connected.PathConnected /-! # The "topologist's sine curve" is connected but not path-connected @@ -22,6 +24,8 @@ similar result has also been independently formalized by Vlad Tsyrklevich (https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/golf.20request.3A.20Topologist's.20sine.20curve). -/ +@[expose] public section + open Topology Filter Set Real namespace TopologistsSineCurve diff --git a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean index 5b0f8d98d00373..8243f4b33ddeef 100644 --- a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean +++ b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean @@ -3,11 +3,13 @@ Copyright (c) 2022 Damiano Testa. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Damiano Testa -/ -import Mathlib.Algebra.Group.UniqueProds.Basic -import Mathlib.Algebra.MonoidAlgebra.Defs -import Mathlib.Algebra.Ring.GeomSum -import Mathlib.Data.Finsupp.Lex -import Mathlib.Data.ZMod.Basic +module + +public import Mathlib.Algebra.Group.UniqueProds.Basic +public import Mathlib.Algebra.MonoidAlgebra.Defs +public import Mathlib.Algebra.Ring.GeomSum +public import Mathlib.Data.Finsupp.Lex +public import Mathlib.Data.ZMod.Basic /-! # Examples of zero-divisors in `AddMonoidAlgebra`s @@ -40,7 +42,7 @@ finitely supported function is lexicographic, matching the list notation. The i `[1, 1] > [1, 0]`. -/ - +@[expose] public section open Finsupp hiding single open AddMonoidAlgebra From e631b64438d263de54e682d9ee63d84dbb010473 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:38:42 +0000 Subject: [PATCH 1075/1300] chore(Combinatorics/SimpleGraph/StronglyRegular): fix statement of `conway_99` (#42233) Kevin's Claude noticed that the `proof_wanted` for `conway_99` is misformalized. It asserts the existence of a simple graph `g` but then refers to the variable `G`. Co-authored-by: tb65536 --- Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean index f982dd2b27d756..9bea39c519e742 100644 --- a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean +++ b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -82,7 +82,8 @@ theorem IsSRGWith.ediam_eq_two [Nontrivial V] (h : G.IsSRGWith n k ℓ μ) (ht : /-- **Conway's 99-graph problem** (from https://oeis.org/A248380/a248380.pdf) can be reformulated as the existence of a strongly regular graph with params (99, 14, 1, 2). This is an open problem, and has no known proof of existence. -/ -proof_wanted conway_99 : ∃ α : Type*, ∃ (g : SimpleGraph α), IsSRGWith G 99 14 1 2 +proof_wanted conway_99 : ∃ (α : Type) (_ : Fintype α) (g : SimpleGraph α) (_ : DecidableRel g.Adj), + IsSRGWith g 99 14 1 2 variable [DecidableEq V] From edc39bf7bcc706ba243ae824adaa60fff00416db Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:56:48 +0000 Subject: [PATCH 1076/1300] chore(NumberTheory/RamificationInertia/Basic): deprecate file (#41248) This PR deprecates `NumberTheory/RamificationInertia/Basic.lean` in favor of `RingTheory/RamificationInertia/Basic.lean`. Co-authored-by: tb65536 --- .../RamificationInertia/Basic.lean | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 39a7c21aa4add5..508511d23463fb 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -43,6 +43,8 @@ leaving `p` and `P` implicit. -/ +deprecated_module "Use RingTheory.RamificationInertia.Basic" (since := "2026-07-01") + @[expose] public section @@ -87,6 +89,7 @@ Here, More precisely, we avoid quotients in this statement and instead require that `b ∪ pS` spans `S`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem FinrankQuotientMap.span_eq_top [IsDomain R] [IsDomain S] [Algebra K L] [Module.Finite R S] [Algebra R L] [IsScalarTower R S L] [IsScalarTower R K L] [Algebra.IsAlgebraic R S] [IsTorsionFree R K] (hp : p ≠ ⊤) (b : Set S) @@ -185,6 +188,7 @@ The statement we prove is actually slightly more general: * it suffices that the inclusion `algebraMap R S : R → S` is nontrivial * the function `f' : V'' → V'` doesn't need to be injective -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem FinrankQuotientMap.linearIndependent_of_nontrivial [IsDedekindDomain R] (hRS : RingHom.ker (algebraMap R S) ≠ ⊤) (F : V'' →ₗ[R] V) (hf : Function.Injective F) (f' : V'' →ₗ[R] V') {ι : Type*} {b : ι → V''} (hb' : LinearIndependent S (f' ∘ b)) : @@ -221,6 +225,7 @@ variable (L) /-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`, then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem finrank_quotient_map [IsDomain S] [IsDedekindDomain R] [Algebra K L] [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [hp : p.IsMaximal] [Module.Finite R S] : @@ -275,10 +280,11 @@ local notation "e" => ramificationIdx' p P /-- `R / p` has a canonical map to `S / (P ^ e)`, where `e` is the ramification index of `P` over `p`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable instance Quotient.algebraQuotientPowRamificationIdx : Algebra (R ⧸ p) (S ⧸ P ^ e) := Quotient.algebraQuotientOfLEComap (Ideal.map_le_iff_le_comap.mp le_pow_ramificationIdx') -@[simp] +@[simp, deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Quotient.algebraMap_quotient_pow_ramificationIdx (x : R) : algebraMap (R ⧸ p) (S ⧸ P ^ e) (Ideal.Quotient.mk p x) = Ideal.Quotient.mk (P ^ e) (f x) := rfl @@ -286,20 +292,21 @@ theorem Quotient.algebraMap_quotient_pow_ramificationIdx (x : R) : This can't be an instance since the map `f : R → S` is generally not inferable. -/ -@[instance_reducible] +@[instance_reducible, + deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] def Quotient.algebraQuotientOfRamificationIdxNeZero [hfp : NeZero e] : Algebra (R ⧸ p) (S ⧸ P) := Quotient.algebraQuotientOfLEComap (le_comap_of_ramificationIdx'_ne_zero hfp.out) attribute [local instance] Ideal.Quotient.algebraQuotientOfRamificationIdxNeZero -@[simp] +@[simp, deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Quotient.algebraMap_quotient_of_ramificationIdx_neZero [NeZero e] (x : R) : algebraMap (R ⧸ p) (S ⧸ P) (Ideal.Quotient.mk p x) = Ideal.Quotient.mk P (f x) := rfl /-- The inclusion `(P^(i + 1) / P^e) ⊂ (P^i / P^e)`. -/ -@[simps] +@[simps, deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable def powQuotSuccInclusion (i : ℕ) : Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ (i + 1)) →ₗ[R ⧸ p] Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i) where @@ -307,6 +314,7 @@ noncomputable def powQuotSuccInclusion (i : ℕ) : map_add' _ _ := rfl map_smul' _ _ := rfl +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem powQuotSuccInclusion_injective (i : ℕ) : Function.Injective (powQuotSuccInclusion p P i) := by rintro ⟨_, _⟩ ⟨_, _⟩ h @@ -316,6 +324,7 @@ theorem powQuotSuccInclusion_injective (i : ℕ) : See `quotientToQuotientRangePowQuotSucc` for this as a linear map, and `quotientRangePowQuotSuccInclusionEquiv` for this as a linear equivalence. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable def quotientToQuotientRangePowQuotSuccAux {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) : S ⧸ P → (P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion p P i) := @@ -328,6 +337,7 @@ noncomputable def quotientToQuotientRangePowQuotSuccAux {i : ℕ} {a : S} (a_mem rw [powQuotSuccInclusion_apply_coe, Subtype.coe_mk, Submodule.coe_sub, Subtype.coe_mk, Subtype.coe_mk, map_mul, map_sub, mul_sub] +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem quotientToQuotientRangePowQuotSuccAux_mk {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) (x : S) : quotientToQuotientRangePowQuotSuccAux p P a_mem (Submodule.Quotient.mk x) = Submodule.Quotient.mk ⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_right x _ a_mem)⟩ := by @@ -337,6 +347,7 @@ section variable [hfp : NeZero (ramificationIdx' p P)] /-- `S ⧸ P` embeds into the quotient by `P^(i+1) ⧸ P^e` as a subspace of `P^i ⧸ P^e`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable def quotientToQuotientRangePowQuotSucc {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) : S ⧸ P →ₗ[R ⧸ p] @@ -356,12 +367,14 @@ noncomputable def quotientToQuotientRangePowQuotSucc Algebra.smul_def, Quotient.algebraMap_quotient_pow_ramificationIdx] ring +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem quotientToQuotientRangePowQuotSucc_mk {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) (x : S) : quotientToQuotientRangePowQuotSucc p P a_mem (Submodule.Quotient.mk x) = Submodule.Quotient.mk ⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_right x _ a_mem)⟩ := quotientToQuotientRangePowQuotSuccAux_mk p P a_mem x set_option backward.isDefEq.respectTransparency.types false in +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem quotientToQuotientRangePowQuotSucc_injective [IsDedekindDomain S] [P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i) (a_notMem : a ∉ P ^ (i + 1)) : Function.Injective (quotientToQuotientRangePowQuotSucc p P a_mem) := fun x => @@ -381,6 +394,7 @@ theorem quotientToQuotientRangePowQuotSucc_injective [IsDedekindDomain S] [P.IsP ((Submodule.sub_mem_iff_right _ hz).mp (Pe_le_Pi1 h))).resolve_left a_notMem +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem quotientToQuotientRangePowQuotSucc_surjective [IsDedekindDomain S] (hP0 : P ≠ ⊥) [hP : P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i) (a_notMem : a ∉ P ^ (i + 1)) : @@ -406,6 +420,7 @@ theorem quotientToQuotientRangePowQuotSucc_surjective [IsDedekindDomain S] /-- Quotienting `P^i / P^e` by its subspace `P^(i+1) ⧸ P^e` is `R ⧸ p`-linearly isomorphic to `S ⧸ P`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDedekindDomain S] [P.IsPrime] (hP : P ≠ ⊥) {i : ℕ} (hi : i < e) : ((P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion p P i)) @@ -420,6 +435,7 @@ noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDedekindDomain S] /-- Since the inclusion `(P^(i + 1) / P^e) ⊂ (P^i / P^e)` has a kernel isomorphic to `P / S`, `[P^i / P^e : R / p] = [P^(i+1) / P^e : R / p] + [P / S : R / p]` -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem rank_pow_quot_aux [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥) {i : ℕ} (hi : i < e) : Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) = @@ -429,6 +445,7 @@ theorem rank_pow_quot_aux [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : (quotientRangePowQuotSuccInclusionEquiv p P hP0 hi).symm.rank_eq] exact (Submodule.rank_quotient_add_rank (LinearMap.range (powQuotSuccInclusion p P i))).symm +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem rank_pow_quot [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥) (i : ℕ) (hi : i ≤ e) : Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) = @@ -449,6 +466,7 @@ end /-- If `p` is a maximal ideal of `R`, `S` extends `R` and `P^e` lies over `p`, then the dimension `[S/(P^e) : R/p]` is equal to `e * [S/P : R/p]`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem rank_prime_pow_ramificationIdx [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥) (he : e ≠ 0) : Module.rank (R ⧸ p) (S ⧸ P ^ e) = @@ -463,6 +481,7 @@ theorem rank_prime_pow_ramificationIdx [IsDedekindDomain S] [p.IsMaximal] [P.IsP /-- If `p` is a maximal ideal of `R`, `S` extends `R` and `P^e` lies over `p`, then the dimension `[S/(P^e) : R/p]`, as a natural number, is equal to `e * [S/P : R/p]`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem finrank_prime_pow_ramificationIdx [IsDedekindDomain S] (hP0 : P ≠ ⊥) [p.IsMaximal] [P.IsPrime] (he : e ≠ 0) : finrank (R ⧸ p) (S ⧸ P ^ e) = @@ -490,32 +509,39 @@ section FactorsMap variable [IsDedekindDomain S] +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Factors.ne_bot (P : (factors (map (algebraMap R S) p)).toFinset) : (P : Ideal S) ≠ ⊥ := (prime_of_factor _ (Multiset.mem_toFinset.mp P.2)).ne_zero +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] instance Factors.isPrime (P : (factors (map (algebraMap R S) p)).toFinset) : IsPrime (P : Ideal S) := Ideal.isPrime_of_prime (prime_of_factor _ (Multiset.mem_toFinset.mp P.2)) +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Factors.ramificationIdx_ne_zero (P : (factors (map (algebraMap R S) p)).toFinset) : ramificationIdx' p P.1 ≠ 0 := IsDedekindDomain.ramificationIdx'_ne_zero (ne_zero_of_mem_factors (Multiset.mem_toFinset.mp P.2)) (Factors.isPrime p P) (Ideal.le_of_dvd (dvd_of_mem_factors (Multiset.mem_toFinset.mp P.2))) +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] instance Factors.fact_ramificationIdx_neZero (P : (factors (map (algebraMap R S) p)).toFinset) : NeZero (ramificationIdx' p P.1) := ⟨Factors.ramificationIdx_ne_zero p P⟩ attribute [local instance] Quotient.algebraQuotientOfRamificationIdxNeZero +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] instance Factors.isScalarTower (P : (factors (map (algebraMap R S) p)).toFinset) : IsScalarTower R (R ⧸ p) (S ⧸ (P : Ideal S)) := IsScalarTower.of_algebraMap_eq' rfl +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] instance Factors.liesOver [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : P.1.LiesOver p := ⟨(comap_eq_of_scalar_tower_quotient (algebraMap (R ⧸ p) (S ⧸ P.1)).injective).symm⟩ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Factors.finrank_pow_ramificationIdx [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : finrank (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) = @@ -523,6 +549,7 @@ theorem Factors.finrank_pow_ramificationIdx [p.IsMaximal] rw [finrank_prime_pow_ramificationIdx, inertiaDeg'_algebraMap] exacts [Factors.ne_bot p P, NeZero.ne _] +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] instance Factors.finiteDimensional_quotient_pow [Module.Finite R S] [p.IsMaximal] (P : (factors (map (algebraMap R S) p)).toFinset) : FiniteDimensional (R ⧸ p) (S ⧸ (P : Ideal S) ^ ramificationIdx' p P.1) := by @@ -534,6 +561,7 @@ universe w /-- **Chinese remainder theorem** for a ring of integers: if the prime ideal `p : Ideal R` factors in `S` as `∏ i, P i ^ e i`, then `S ⧸ I` factors as `Π i, R ⧸ (P i ^ e i)`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable def Factors.piQuotientEquiv (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) : S ⧸ map (algebraMap R S) p ≃+* ∀ P : (factors (map (algebraMap R S) p)).toFinset, @@ -547,11 +575,11 @@ noncomputable def Factors.piQuotientEquiv (p : Ideal R) (hp : map (algebraMap R rw [IsDedekindDomain.ramificationIdx'_eq_factors_count hp (Factors.isPrime p P) (Factors.ne_bot p P)] -@[simp] +@[simp, deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Factors.piQuotientEquiv_mk (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) (x : S) : Factors.piQuotientEquiv p hp (Ideal.Quotient.mk _ x) = fun _ => Ideal.Quotient.mk _ x := rfl -@[simp] +@[simp, deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem Factors.piQuotientEquiv_map (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) (x : R) : Factors.piQuotientEquiv p hp (algebraMap _ _ x) = fun _ => Ideal.Quotient.mk _ (algebraMap _ _ x) := rfl @@ -561,6 +589,7 @@ variable (S) /-- **Chinese remainder theorem** for a ring of integers: if the prime ideal `p : Ideal R` factors in `S` as `∏ i, P i ^ e i`, then `S ⧸ I` factors `R ⧸ I`-linearly as `Π i, R ⧸ (P i ^ e i)`. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] noncomputable def Factors.piQuotientLinearEquiv (p : Ideal R) (hp : map (algebraMap R S) p ≠ ⊥) : (S ⧸ map (algebraMap R S) p) ≃ₗ[R ⧸ p] ∀ P : (factors (map (algebraMap R S) p)).toFinset, @@ -581,6 +610,7 @@ variable (K L : Type*) [Field K] [Field L] [IsDedekindDomain R] [Algebra R K] [I for `P` ranging over the primes lying over `p`, `∑ P, e P * f P = [Frac(S) : Frac(R)]`; here `S` is a finite `R`-module (and thus `Frac(S) : Frac(R)` is a finite extension) and `p` is maximal. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem sum_ramification_inertia {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : ∑ P ∈ IsDedekindDomain.primesOverFinset p S, ramificationIdx' p P * inertiaDeg' p P = finrank K L := by @@ -602,6 +632,7 @@ theorem sum_ramification_inertia {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : algebraMap_injective_of_field_isFractionRing R S K L, le_bot_iff] · exact finrank_quotient_map p K L +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem inertiaDeg_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (P : Ideal S) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver p] (hp0 : p ≠ ⊥) : p.inertiaDeg' P ≤ Module.finrank K L := by @@ -611,6 +642,7 @@ theorem inertiaDeg_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaxima refine le_trans (Nat.le_mul_of_pos_left _ ?_) (Nat.le_add_right _ _) exact Nat.pos_iff_ne_zero.mpr <| IsDedekindDomain.ramificationIdx'_ne_zero_of_liesOver _ hp0 +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem ramificationIdx_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (P : Ideal S) [hP₁ : P.IsPrime] [hP₂ : P.LiesOver p] : p.ramificationIdx' P ≤ Module.finrank K L := by @@ -622,6 +654,7 @@ theorem ramificationIdx_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsM refine le_trans (Nat.le_mul_of_pos_right _ ?_) (Nat.le_add_right _ _) exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg'_ne_zero p P +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] theorem card_primesOverFinset_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : Finset.card (IsDedekindDomain.primesOverFinset p S) ≤ Module.finrank K L := by rw [← sum_ramification_inertia S K L hp0, Finset.card_eq_sum_ones] @@ -633,6 +666,7 @@ theorem card_primesOverFinset_le_finrank [NoZeroSMulDivisors R S] {p : Ideal R} · exact Nat.pos_iff_ne_zero.mpr <| inertiaDeg'_ne_zero p P /-- `Ideal.sum_ramification_inertia`, in the local (DVR) case. -/ +@[deprecated "Use results of RingTheory.RamificationInertia.Basic" (since := "2026-07-01")] lemma ramificationIdx_mul_inertiaDeg_of_isLocalRing [IsLocalRing S] {p : Ideal R} [p.IsMaximal] (hp0 : p ≠ ⊥) : ramificationIdx' p (IsLocalRing.maximalIdeal S) * From 3edb3c0658f69f197b1e501b1f7623f3f7b3898c Mon Sep 17 00:00:00 2001 From: Fabrizio Barroero <23321199+fbarroero@users.noreply.github.com> Date: Wed, 29 Jul 2026 15:39:30 +0000 Subject: [PATCH 1077/1300] feat(Algebra/GroupWithZero/WithZero): `toAdd_unzero_eq_log` and simplify proofs (#42149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds the lemma ```lean lemma toAdd_unzero_eq_log {x : Mᵐ⁰} (hx : x ≠ 0) : (unzero hx).toAdd = log x ``` and uses it to simplify some proofs involving `log`, `exp`, and rank-one discrete valuations. Co-authored-by: fbarroero --- Mathlib/Algebra/GroupWithZero/WithZero.lean | 12 ++++----- .../Order/GroupWithZero/Canonical.lean | 20 +++++++-------- .../Valuation/Discrete/RankOne.lean | 25 +++++-------------- 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/WithZero.lean b/Mathlib/Algebra/GroupWithZero/WithZero.lean index 5b62e51974c245..508b4790bfe152 100644 --- a/Mathlib/Algebra/GroupWithZero/WithZero.lean +++ b/Mathlib/Algebra/GroupWithZero/WithZero.lean @@ -10,7 +10,6 @@ public import Mathlib.Algebra.Group.WithOne.Defs public import Mathlib.Algebra.GroupWithZero.Equiv public import Mathlib.Algebra.GroupWithZero.Units.Basic public import Mathlib.Data.Nat.Cast.Defs -public import Mathlib.Data.Option.Basic public import Mathlib.Data.Option.NAry /-! @@ -422,6 +421,10 @@ lemma log_pow : ∀ (x : Mᵐ⁰) (n : ℕ), log (x ^ n) = n • log x | 0, n + 1 => by simp | (x : Multiplicative M), n => rfl +lemma toAdd_unzero_eq_log {x : Mᵐ⁰} (hx : x ≠ 0) : (unzero hx).toAdd = log x := by + lift x to Multiplicative M using hx + simp [log] + end AddMonoid section AddGroup @@ -438,12 +441,7 @@ def logEquiv : (Gᵐ⁰)ˣ ≃ G := unitsWithZeroEquiv.toEquiv.trans Multiplicat @[simp] lemma coe_expEquiv_apply (a : G) : expEquiv a = exp a := rfl -@[simp] lemma logEquiv_apply (x : (Gᵐ⁰)ˣ) : logEquiv x = log x := by - obtain ⟨_ | a, _ | b, hab, hba⟩ := x - · cases hab - · cases hab - · cases hab - · rfl +@[simp] lemma logEquiv_apply (x : (Gᵐ⁰)ˣ) : logEquiv x = log x := toAdd_unzero_eq_log x.ne_zero lemma logEquiv_unitsMk0 (x : Gᵐ⁰) (hx) : logEquiv (.mk0 x hx) = log x := logEquiv_apply _ diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 5928ae2e20b0ff..e6ec658728efca 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -527,23 +527,23 @@ variable {G : Type*} [Preorder G] {a b : G} variable [AddGroup G] {x y : Gᵐ⁰} -@[simp] lemma log_le_log (hx : x ≠ 0) (hy : y ≠ 0) : log x ≤ log y ↔ x ≤ y := by - lift x to Multiplicative G using hx; lift y to Multiplicative G using hy; simp [log] - -@[simp] lemma log_lt_log (hx : x ≠ 0) (hy : y ≠ 0) : log x < log y ↔ x < y := by - lift x to Multiplicative G using hx; lift y to Multiplicative G using hy; simp [log] - lemma log_le_iff_le_exp (hx : x ≠ 0) : log x ≤ a ↔ x ≤ exp a := by - lift x to Multiplicative G using hx; simpa [log, exp] using .rfl + rw [← toAdd_unzero_eq_log hx, ← le_ofAdd_iff hx, exp] lemma log_lt_iff_lt_exp (hx : x ≠ 0) : log x < a ↔ x < exp a := by - lift x to Multiplicative G using hx; simpa [log, exp] using .rfl + rw [← toAdd_unzero_eq_log hx, ← lt_ofAdd_iff hx, exp] + +@[simp] lemma log_le_log (hx : x ≠ 0) (hy : y ≠ 0) : log x ≤ log y ↔ x ≤ y := by + rw [log_le_iff_le_exp hx, exp_log hy] + +@[simp] lemma log_lt_log (hx : x ≠ 0) (hy : y ≠ 0) : log x < log y ↔ x < y := by + rw [log_lt_iff_lt_exp hx, exp_log hy] lemma le_log_iff_exp_le (hx : x ≠ 0) : a ≤ log x ↔ exp a ≤ x := by - lift x to Multiplicative G using hx; simpa [log, exp] using .rfl + rw [← log_le_log exp_ne_zero hx, log_exp] lemma lt_log_iff_exp_lt (hx : x ≠ 0) : a < log x ↔ exp a < x := by - lift x to Multiplicative G using hx; simpa [log, exp] using .rfl + rw [← log_lt_log exp_ne_zero hx, log_exp] lemma le_exp_of_log_le (hxa : log x ≤ a) : x ≤ exp a := by obtain rfl | hx := eq_or_ne x 0 <;> simp [← log_le_iff_le_exp, *] diff --git a/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean b/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean index b969772f948a56..4d2f68028c6980 100644 --- a/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean +++ b/Mathlib/RingTheory/Valuation/Discrete/RankOne.lean @@ -53,10 +53,7 @@ lemma valueGroup₀_equiv_withZeroMulInt_apply_zero : lemma valueGroup₀_equiv_withZeroMulInt_apply_zpow (k : ℤ) : valueGroup₀_equiv_withZeroMulInt v (hv.generator' ^ k) = WithZero.exp (- k) := by - simp only [map_zpow₀, valueGroup₀_equiv_withZeroMulInt_apply, WithZero.map'_coe, - MonoidHom.coe_coe] - rw [← WithZero.coe_zpow, WithZero.exp, WithZero.coe_inj, ← map_zpow] - simp [← mulintEquivOfZPowersEqTop_symm_apply_zpow + simp [WithZero.exp, ← mulintEquivOfZPowersEqTop_symm_apply_zpow (Subgroup.zpowers_inv (g := hv.generator') ▸ hv.generator'_zpowers_eq_top)] lemma valueGroup₀_equiv_withZeroMulInt_strictMono : @@ -88,22 +85,12 @@ lemma valueGroup₀_equiv_withZeroMulInt_restrict_apply_of_surjective (hsurj : F split_ifs with h0 <;> simp only [MonoidWithZeroHom.coe_ofClass] at h0 · simp [h0] - · simp only [WithZero.map'_coe, MonoidHom.coe_coe] - conv_rhs => rw [← coe_unzero h0] - rw [WithZero.coe_inj, ← (MulEquiv.injective (intEquivOfZPowersEqTop _ - (Subgroup.zpowers_inv (g := hv.generator') ▸ hv.generator'_zpowers_eq_top))).eq_iff, - MulEquiv.apply_symm_apply] + · rw [WithZero.map'_coe, ← coe_unzero h0, WithZero.coe_inj, + ← (MulEquiv.injective (intEquivOfZPowersEqTop _ + (Subgroup.zpowers_inv (g := hv.generator') ▸ hv.generator'_zpowers_eq_top))).eq_iff] ext - simp only [Units.val_mk0, intEquivOfZPowersEqTop_apply, inv_zpow', generator', - SubgroupClass.coe_zpow] - have hg : hv.generator = Units.mk0 (WithZero.exp (-1 : ℤ) : ℤᵐ⁰) (by simp) := - generator_eq_exp_neg_one_of_surjective hsurj - rw [hg] - conv_lhs => rw [MonoidWithZeroHom.coe_ofClass, ← coe_unzero h0] - simp only [coe_unzero, Int.reduceNeg, exp_neg, zpow_neg, Units.val_inv_eq_inv_val, - Units.val_zpow_eq_zpow_val, Units.val_mk0, inv_zpow', ← exp_zsmul, Int.zsmul_eq_mul, mul_one, - inv_inv] - simp [WithZero.exp] + simp [generator', generator_eq_exp_neg_one_of_surjective hsurj, toAdd_unzero_eq_log h0, + exp_log h0] end WithZeroMulInt From 077102ea18686f6e3bfd60206f5b6c12adfd1859 Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Wed, 29 Jul 2026 18:35:49 +0000 Subject: [PATCH 1078/1300] feat(LinearAlgebra/Dimension/Free): isomorphic to base ring iff rank is one (#37959) Co-authored-by: artie2000 --- Mathlib/LinearAlgebra/Dimension/Free.lean | 29 +++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index 151eb9748caf3b..73bcc777f8d337 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -219,15 +219,12 @@ theorem FiniteDimensional.nonempty_linearEquiv_iff_finrank_eq [Module.Finite R M [Module.Finite R M'] : Nonempty (M ≃ₗ[R] M') ↔ finrank R M = finrank R M' := ⟨fun ⟨h⟩ => h.finrank_eq, fun h => nonempty_linearEquiv_of_finrank_eq h⟩ -variable (M M') - +variable (M M') in /-- Two finite and free modules are isomorphic if they have the same (finite) rank. -/ noncomputable def LinearEquiv.ofFinrankEq [Module.Finite R M] [Module.Finite R M'] (cond : finrank R M = finrank R M') : M ≃ₗ[R] M' := Classical.choice <| FiniteDimensional.nonempty_linearEquiv_of_finrank_eq cond -variable {M M'} - namespace Module /-- A free module of rank zero is trivial. -/ @@ -286,6 +283,24 @@ lemma finrank_bot_le_finrank_of_isScalarTower_of_free (S T : Type*) [Semiring S] · exact zero_le · rwa [← not_lt, Module.rank_lt_aleph0_iff] +theorem nonempty_linearEquiv_iff_rank_eq_one : + Nonempty (R ≃ₗ[R] M) ↔ Module.rank R M = 1 := by + simp [nonempty_linearEquiv_iff_lift_rank_eq, eq_comm] + +/-- See also `finrank_eq_one_iff` -/ +theorem nonempty_linearEquiv_iff_finrank_eq_one : + Nonempty (R ≃ₗ[R] M) ↔ finrank R M = 1 := by + simp [nonempty_linearEquiv_iff_rank_eq_one, finrank] + +alias ⟨_, nonempty_linearEquiv_of_finrank_eq_one⟩ := nonempty_linearEquiv_iff_finrank_eq_one + +theorem nonempty_algEquiv_iff_finrank_eq_one + {R S : Type*} [CommSemiring R] [StrongRankCondition R] [Semiring S] [Algebra R S] + [Free R S] : Nonempty (R ≃ₐ[R] S) ↔ finrank R S = 1 := by + rw [← nonempty_linearEquiv_iff_finrank_eq_one] + exact ⟨fun ⟨e⟩ ↦ ⟨e⟩, fun ⟨e⟩ ↦ + ⟨.ofBijective (Algebra.ofId R S) (bijective_algebraMap_of_linearEquiv e)⟩⟩ + variable (R M) /-- A finite rank free module has a basis indexed by `Fin (finrank R M)`. -/ @@ -320,12 +335,6 @@ theorem Basis.nonempty_unique_index_of_finrank_eq_one have : Fintype ι := Fintype.ofFinite ι rwa [Module.finrank_eq_card_basis b, Fintype.card_eq_one_iff_nonempty_unique] at d1 -theorem nonempty_linearEquiv_of_finrank_eq_one (d1 : Module.finrank R M = 1) : - Nonempty (R ≃ₗ[R] M) := by - let ⟨ι, b⟩ := (Module.Free.exists_basis R M).some - have : Unique ι := (b.nonempty_unique_index_of_finrank_eq_one d1).some - exact ⟨((b.equivFun).trans (LinearEquiv.funUnique ι R R)).symm⟩ - @[simp] theorem basisUnique_repr_eq_zero_iff {ι : Type*} [Unique ι] {h : finrank R M = 1} {v : M} {i : ι} : From af3493fa1f9bd52f91089dcb38f12301c2948b30 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:03:52 +0000 Subject: [PATCH 1079/1300] feat(MeasureTheory): prove regular measures have conull support (#41473) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR proves in `MeasureTheory.Measure.Support` that any measure which is compact-inner-regular on open sets has conull support. It also records the consequences for `[μ.InnerRegular]` on spaces with `[OpensMeasurableSpace X]` and for `[μ.Regular]`. It first proves compact subsets of `μ.supportᶜ` have measure zero, then applies `InnerRegularWRT IsCompact IsOpen`. The inner-regular and regular statements are corollaries. Created with the help of codex. Co-authored-by: Yongxi Lin --- Mathlib/MeasureTheory/Measure/Support.lean | 55 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Support.lean b/Mathlib/MeasureTheory/Measure/Support.lean index 37c3278a70dab6..168de187f782a7 100644 --- a/Mathlib/MeasureTheory/Measure/Support.lean +++ b/Mathlib/MeasureTheory/Measure/Support.lean @@ -6,6 +6,7 @@ Authors: Jon Bannon, Jireh Loreaux module public import Mathlib.MeasureTheory.Measure.OpenPos +public import Mathlib.MeasureTheory.Measure.Regular /-! # Support of a Measure @@ -14,7 +15,7 @@ This file develops the theory of the **support** of a measure `μ` on a topological measurable space. The support is defined as the set of points whose every open neighborhood has positive measure. We give equivalent characterizations, prove basic measure-theoretic properties, and study interactions with sums, restrictions, and -absolute continuity. Under various Lindelöf conditions, the support is conull, +absolute continuity. Under various Lindelöf or regularity conditions, the support is conull, and various descriptions of the complement of the support are provided. ## Main definitions @@ -31,6 +32,9 @@ and various descriptions of the complement of the support are provided. * `isClosed_support` : the support is a closed set. * `support_mem_ae_of_isLindelof` and `support_mem_ae` : under Lindelöf (or hereditarily Lindelöf) hypotheses, the support is conull. +* `support_mem_ae_of_innerRegularWRT_isCompact_isOpen` and + `measure_compl_support_of_innerRegularWRT_isCompact_isOpen` : inner regularity by compact + sets on open sets imply that the support is conull. ## Tags @@ -45,7 +49,7 @@ namespace MeasureTheory namespace Measure -open scoped Topology +open scoped Topology ENNReal variable {X : Type*} [TopologicalSpace X] [MeasurableSpace X] @@ -133,6 +137,53 @@ lemma support_eq_sInter : μ.support = ⋂₀ {t : Set X | IsClosed t ∧ μ t convert! congr($(compl_support_eq_sUnion (μ := μ))ᶜ) all_goals simp [Set.compl_sUnion, compl_involutive.image_eq_preimage_symm] +section Regular + +/-- Any compact set contained in the complement of the support has zero measure. -/ +lemma measure_eq_zero_of_isCompact_subset_compl_support {K : Set X} (hK : IsCompact K) + (hKsub : K ⊆ μ.supportᶜ) : μ K = 0 := by + refine hK.induction_on measure_empty ?_ ?_ ?_ + · exact fun _ _ hst ht ↦ measure_mono_null hst ht + · exact fun _ _ hs ht ↦ measure_union_null hs ht + · intro x hxK + obtain ⟨U, hUnhds, hU0⟩ := notMem_support_iff_exists.1 (hKsub hxK) + exact ⟨U, mem_nhdsWithin_of_mem_nhds hUnhds, hU0⟩ + +/-- A measure which is compact-inner-regular on open sets has conull support. -/ +lemma support_mem_ae_of_innerRegularWRT_isCompact_isOpen + (hμ : μ.InnerRegularWRT IsCompact IsOpen) : μ.support ∈ ae μ := by + by_contra hne + obtain ⟨K, hKsub, hKcompact, hKpos⟩ := hμ isOpen_compl_support 0 (pos_iff_ne_zero.2 hne) + simp [measure_eq_zero_of_isCompact_subset_compl_support hKcompact hKsub] at hKpos + +/-- A measure which is compact-inner-regular on open sets has conull support. -/ +@[simp] +lemma measure_compl_support_of_innerRegularWRT_isCompact_isOpen + (hμ : μ.InnerRegularWRT IsCompact IsOpen) : μ μ.supportᶜ = 0 := + support_mem_ae_of_innerRegularWRT_isCompact_isOpen hμ + +/-- An inner regular measure has conull support when open sets are measurable. -/ +lemma support_mem_ae_of_innerRegular [OpensMeasurableSpace X] [μ.InnerRegular] : + μ.support ∈ ae μ := + support_mem_ae_of_innerRegularWRT_isCompact_isOpen fun _ hU r hr => + InnerRegular.innerRegular hU.measurableSet r hr + +/-- An inner regular measure has conull support when open sets are measurable. -/ +@[simp] +lemma measure_compl_support_of_innerRegular [OpensMeasurableSpace X] [μ.InnerRegular] : + μ μ.supportᶜ = 0 := support_mem_ae_of_innerRegular + +/-- A regular measure has conull support. -/ +lemma support_mem_ae_of_regular [μ.Regular] : μ.support ∈ ae μ := + support_mem_ae_of_innerRegularWRT_isCompact_isOpen Regular.innerRegular + +/-- A regular measure has conull support. -/ +@[simp] +lemma measure_compl_support_of_regular [μ.Regular] : μ μ.supportᶜ = 0 := + support_mem_ae_of_regular + +end Regular + section Lindelof /-- If the complement of the support is Lindelöf, then the support of a measure is conull. -/ From 30696563acb0596ab44d272bc5dfee96b2e72263 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Wed, 29 Jul 2026 20:08:20 +0000 Subject: [PATCH 1080/1300] feat: `haveI`/`letI` tactic linter (#41657) This PR implements a variation on the linter that was written by Claude in #41562. It suggest to use `have`/`let` instead of `haveI`/`letI` whenever the goal is a proposition. See also https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/surprising.20have.2FhaveI.20kernel.20phenomenon/with/609718493 --- Archive/Imo/Imo2008Q3.lean | 2 +- Archive/Imo/Imo2019Q2.lean | 8 +- Archive/Wiedijk100Theorems/BallotProblem.lean | 6 +- Archive/Wiedijk100Theorems/CubingACube.lean | 2 +- .../Wiedijk100Theorems/FriendshipGraphs.lean | 2 +- .../CliffordAlgebraNotInjective.lean | 2 +- Counterexamples/Phillips.lean | 2 +- Counterexamples/SorgenfreyLine.lean | 4 +- .../ZeroDivisorsInAddMonoidAlgebras.lean | 4 +- Mathlib.lean | 1 + Mathlib/Analysis/Convex/Side.lean | 2 +- Mathlib/Geometry/Manifold/Instances/Icc.lean | 2 +- Mathlib/GroupTheory/CommutingProbability.lean | 2 +- Mathlib/Init.lean | 1 + .../MeasureTheory/VectorMeasure/Basic.lean | 2 +- Mathlib/Tactic.lean | 1 + Mathlib/Tactic/Linter/HaveILetI.lean | 78 +++++++++++++++++++ MathlibTest/InstanceDiamonds.lean | 2 +- MathlibTest/Linter/HaveILetI.lean | 28 +++++++ MathlibTest/Tactic/ITauto.lean | 6 +- MathlibTest/TransImports.lean | 4 +- 21 files changed, 135 insertions(+), 26 deletions(-) create mode 100644 Mathlib/Tactic/Linter/HaveILetI.lean create mode 100644 MathlibTest/Linter/HaveILetI.lean diff --git a/Archive/Imo/Imo2008Q3.lean b/Archive/Imo/Imo2008Q3.lean index fcb23b005b7df6..3542bbdbf4bada 100644 --- a/Archive/Imo/Imo2008Q3.lean +++ b/Archive/Imo/Imo2008Q3.lean @@ -34,7 +34,7 @@ namespace Imo2008Q3 theorem p_lemma (p : ℕ) (hpp : Nat.Prime p) (hp_mod_4_eq_1 : p ≡ 1 [MOD 4]) (hp_gt_20 : p > 20) : ∃ n : ℕ, p ∣ n ^ 2 + 1 ∧ (p : ℝ) > 2 * n + sqrt (2 * n) := by - haveI := Fact.mk hpp + have := Fact.mk hpp have hp_mod_4_ne_3 : p % 4 ≠ 3 := by linarith [show p % 4 = 1 from hp_mod_4_eq_1] obtain ⟨y, hy⟩ := ZMod.exists_sq_eq_neg_one_iff.mpr hp_mod_4_ne_3 let m := ZMod.valMinAbs y diff --git a/Archive/Imo/Imo2019Q2.lean b/Archive/Imo/Imo2019Q2.lean index e8d16c06c9097f..c6aedbb22468e3 100644 --- a/Archive/Imo/Imo2019Q2.lean +++ b/Archive/Imo/Imo2019Q2.lean @@ -275,7 +275,7 @@ theorem A₁_ne_B : cfg.A₁ ≠ cfg.B := by rw [AffineSubspace.eq_iff_direction_eq_of_mem (left_mem_affineSpan_pair _ _ _) hwbtw.mem_affineSpan] exact cfg.PQ_parallel_AB.direction_eq - haveI := someOrientation V + have := someOrientation V have haQ : (2 : ℤ) • ∡ cfg.C cfg.B cfg.Q = (2 : ℤ) • ∡ cfg.C cfg.B cfg.A := by rw [Collinear.two_zsmul_oangle_eq_right _ cfg.A_ne_B cfg.Q_ne_B] rw [Set.pair_comm, Set.insert_comm] @@ -389,7 +389,7 @@ end Oriented theorem not_collinear_QPA₂ : ¬Collinear ℝ ({cfg.Q, cfg.P, cfg.A₂} : Set Pt) := by - haveI := someOrientation V + have := someOrientation V rw [collinear_iff_of_two_zsmul_oangle_eq cfg.two_zsmul_oangle_QPA₂_eq_two_zsmul_oangle_BAA₂, ← affineIndependent_iff_not_collinear_set] have h : Cospherical ({cfg.B, cfg.A, cfg.A₂} : Set Pt) := by @@ -515,13 +515,13 @@ end Oriented theorem not_collinear_CA₂A₁ : ¬Collinear ℝ ({cfg.C, cfg.A₂, cfg.A₁} : Set Pt) := by - haveI := someOrientation V + have := someOrientation V rw [collinear_iff_of_two_zsmul_oangle_eq cfg.two_zsmul_oangle_CA₂A₁_eq_two_zsmul_oangle_CBA, Set.pair_comm, Set.insert_comm, Set.pair_comm] exact cfg.not_collinear_ABC theorem cospherical_A₁Q₁CA₂ : Cospherical ({cfg.A₁, cfg.Q₁, cfg.C, cfg.A₂} : Set Pt) := by - haveI := someOrientation V + have := someOrientation V rw [Set.insert_comm cfg.Q₁, Set.insert_comm cfg.A₁, Set.pair_comm, Set.insert_comm cfg.A₁, Set.pair_comm] exact cospherical_of_two_zsmul_oangle_eq_of_not_collinear diff --git a/Archive/Wiedijk100Theorems/BallotProblem.lean b/Archive/Wiedijk100Theorems/BallotProblem.lean index 3d65be551a90cd..77c891c0bd2927 100644 --- a/Archive/Wiedijk100Theorems/BallotProblem.lean +++ b/Archive/Wiedijk100Theorems/BallotProblem.lean @@ -315,9 +315,9 @@ theorem ballot_problem' : rw [div_self] exact Nat.cast_add_one_ne_zero p · intro q p qp h₁ h₂ - haveI := isProbabilityMeasure_uniformOn + have := isProbabilityMeasure_uniformOn (countedSequence_finite p (q + 1)) (countedSequence_nonempty _ _) - haveI := isProbabilityMeasure_uniformOn + have := isProbabilityMeasure_uniformOn (countedSequence_finite (p + 1) q) (countedSequence_nonempty _ _) have h₃ : 0 < p + 1 + (q + 1) := Nat.add_pos_left (Nat.succ_pos _) _ rw [← uniformOn_add_compl_eq {l : List ℤ | l.headI = 1} _ (countedSequence_finite _ _), @@ -344,7 +344,7 @@ theorem ballot_problem' : theorem ballot_problem : ∀ q p, q < p → uniformOn (countedSequence p q) staysPositive = (p - q) / (p + q) := by intro q p qp - haveI := + have := isProbabilityMeasure_uniformOn (countedSequence_finite p q) (countedSequence_nonempty _ _) have : (uniformOn (countedSequence p q) staysPositive).toReal = diff --git a/Archive/Wiedijk100Theorems/CubingACube.lean b/Archive/Wiedijk100Theorems/CubingACube.lean index b9fa47e86abaf7..079d3ddb65844c 100644 --- a/Archive/Wiedijk100Theorems/CubingACube.lean +++ b/Archive/Wiedijk100Theorems/CubingACube.lean @@ -378,7 +378,7 @@ variable (h v) direction will intersect one of the neighbouring cubes on the same boundary as `mi`. -/ theorem mi_not_onBoundary (j : Fin n) : ¬OnBoundary (mi_mem_bcubes : mi h v ∈ _) j := by let i := mi h v; have hi : i ∈ bcubes cs c := mi_mem_bcubes - haveI := h.nontrivial_fin + have := h.nontrivial_fin rcases exists_ne j with ⟨j', hj'⟩ intro hj rcases smallest_onBoundary hj with ⟨x, ⟨hx, h2x⟩, h3x⟩ diff --git a/Archive/Wiedijk100Theorems/FriendshipGraphs.lean b/Archive/Wiedijk100Theorems/FriendshipGraphs.lean index 7c4c125c004b73..506a8f6f9f8585 100644 --- a/Archive/Wiedijk100Theorems/FriendshipGraphs.lean +++ b/Archive/Wiedijk100Theorems/FriendshipGraphs.lean @@ -250,7 +250,7 @@ theorem false_of_three_le_degree (hd : G.IsRegularOfDegree d) (h : 3 ≤ d) : Fa have p_dvd_d_pred := (ZMod.natCast_eq_zero_iff _ _).mpr (d - 1).minFac_dvd have dpos : 1 ≤ d := by lia have d_cast : ↑(d - 1) = (d : ℤ) - 1 := by norm_cast - haveI : Fact p.Prime := ⟨Nat.minFac_prime (by lia)⟩ + have : Fact p.Prime := ⟨Nat.minFac_prime (by lia)⟩ have hp2 : 2 ≤ p := (Fact.out (p := p.Prime)).two_le have dmod : (d : ZMod p) = 1 := by rw [← Nat.succ_pred_eq_of_pos dpos, Nat.succ_eq_add_one, Nat.pred_eq_sub_one] diff --git a/Counterexamples/CliffordAlgebraNotInjective.lean b/Counterexamples/CliffordAlgebraNotInjective.lean index f6c2d63855131e..d06713dea372d6 100644 --- a/Counterexamples/CliffordAlgebraNotInjective.lean +++ b/Counterexamples/CliffordAlgebraNotInjective.lean @@ -155,7 +155,7 @@ theorem sq_map_add_char_two {ι R : Type*} [CommRing R] [CharP R 2] (i : ι) (a theorem sq_map_sub_char_two {ι R : Type*} [CommRing R] [CharP R 2] (i : ι) (a b : ι → R) : sq i (a - b) = sq i a - sq i b := by - haveI : Nonempty ι := ⟨i⟩ + have : Nonempty ι := ⟨i⟩ rw [CharTwo.sub_eq_add, CharTwo.sub_eq_add, sq_map_add_char_two] /-- The quadratic form (metric) is just Euclidean -/ diff --git a/Counterexamples/Phillips.lean b/Counterexamples/Phillips.lean index f45f6e352eb1e1..84de25c1c14096 100644 --- a/Counterexamples/Phillips.lean +++ b/Counterexamples/Phillips.lean @@ -248,7 +248,7 @@ theorem exists_discrete_support_nonpos (f : BoundedAdditiveMeasure α) : -- convenient to formalize the inductive construction. let A : Set (Set α) := {t | t.Countable} let empty : A := ⟨∅, countable_empty⟩ - haveI : Nonempty A := ⟨empty⟩ + have : Nonempty A := ⟨empty⟩ -- given a countable set `s`, one can find a set `t` in its complement with measure close to -- maximal. have : ∀ s : A, ∃ t : A, ∀ u : A, f (↑u \ ↑s) ≤ 2 * f (↑t \ ↑s) := by diff --git a/Counterexamples/SorgenfreyLine.lean b/Counterexamples/SorgenfreyLine.lean index 40a7a881d66b8f..2a90671722166c 100644 --- a/Counterexamples/SorgenfreyLine.lean +++ b/Counterexamples/SorgenfreyLine.lean @@ -68,7 +68,7 @@ theorem isOpen_Ici (a : ℝₗ) : IsOpen (Ici a) := theorem nhds_basis_Ico (a : ℝₗ) : (𝓝 a).HasBasis (a < ·) (Ico a ·) := by rw [TopologicalSpace.nhds_generateFrom] - haveI : Nonempty { x // x ≤ a } := Set.nonempty_Iic_subtype + have : Nonempty { x // x ≤ a } := Set.nonempty_Iic_subtype have : (⨅ x : { i // i ≤ a }, 𝓟 (Ici ↑x)) = 𝓟 (Ici a) := by refine (IsLeast.isGLB ?_).iInf_eq exact ⟨⟨⟨a, le_rfl⟩, rfl⟩, forall_mem_range.2 fun b => principal_mono.2 <| Ici_subset_Ici.2 b.2⟩ @@ -313,7 +313,7 @@ theorem not_separatedNhds_rat_irrational_antidiag : /-- Topology on the Sorgenfrey line is not metrizable. -/ theorem not_metrizableSpace : ¬MetrizableSpace ℝₗ := by intro - letI := metrizableSpaceMetric ℝₗ + let := metrizableSpaceMetric ℝₗ exact not_normalSpace_prod inferInstance /-- Topology on the Sorgenfrey line is not second countable. -/ diff --git a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean index 8243f4b33ddeef..16fa954c1dea6b 100644 --- a/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean +++ b/Counterexamples/ZeroDivisorsInAddMonoidAlgebras.lean @@ -244,8 +244,8 @@ example : ¬UniqueProds ℕ := by /-- Some Types that do not have `UniqueSums`. -/ example (n : ℕ) (n2 : 2 ≤ n) : ¬UniqueSums (ZMod n) := by - haveI : Fintype (ZMod n) := @ZMod.fintype n ⟨(zero_lt_two.trans_le n2).ne'⟩ - haveI : Nontrivial (ZMod n) := CharP.nontrivial_of_char_ne_one (one_lt_two.trans_le n2).ne' + have : Fintype (ZMod n) := @ZMod.fintype n ⟨(zero_lt_two.trans_le n2).ne'⟩ + have : Nontrivial (ZMod n) := CharP.nontrivial_of_char_ne_one (one_lt_two.trans_le n2).ne' rintro ⟨h⟩ refine not_not.mpr (h Finset.univ_nonempty Finset.univ_nonempty) ?_ suffices ∀ x y : ZMod n, ∃ x' y' : ZMod n, x' + y' = x + y ∧ (x' = x → ¬y' = y) by diff --git a/Mathlib.lean b/Mathlib.lean index d5e389a4ee4b99..3afd48340dc9f5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7421,6 +7421,7 @@ public import Mathlib.Tactic.Linter.FindDeprecations public import Mathlib.Tactic.Linter.FlexibleLinter public import Mathlib.Tactic.Linter.GlobalAttributeIn public import Mathlib.Tactic.Linter.HashCommandLinter +public import Mathlib.Tactic.Linter.HaveILetI public import Mathlib.Tactic.Linter.HaveLetLinter public import Mathlib.Tactic.Linter.Header public import Mathlib.Tactic.Linter.Lint diff --git a/Mathlib/Analysis/Convex/Side.lean b/Mathlib/Analysis/Convex/Side.lean index 91a26699bf8f45..46445050bec550 100644 --- a/Mathlib/Analysis/Convex/Side.lean +++ b/Mathlib/Analysis/Convex/Side.lean @@ -882,7 +882,7 @@ alias isPreconnected_setOf_wOppSide := isPreconnected_setOfPred_wOppSide theorem isConnected_setOfPred_sOppSide {s : AffineSubspace ℝ P} {x : P} (hx : x ∉ s) (h : (s : Set P).Nonempty) : IsConnected { y | s.SOppSide x y } := by obtain ⟨p, hp⟩ := h - haveI : Nonempty s := ⟨⟨p, hp⟩⟩ + have : Nonempty s := ⟨⟨p, hp⟩⟩ rw [setOfPred_sOppSide_eq_image2 hx hp, ← Set.image_prod] refine (isConnected_Iio.prod (isConnected_iff_connectedSpace.2 ?_)).image _ ((continuous_fst.smul continuous_const).vadd continuous_snd).continuousOn diff --git a/Mathlib/Geometry/Manifold/Instances/Icc.lean b/Mathlib/Geometry/Manifold/Instances/Icc.lean index 41b2d5055e1790..c25eb932b6f487 100644 --- a/Mathlib/Geometry/Manifold/Instances/Icc.lean +++ b/Mathlib/Geometry/Manifold/Instances/Icc.lean @@ -73,7 +73,7 @@ open Manifold IsManifold lemma isImmersionOfComplement_subtypeVal_Icc : IsImmersionOfComplement Unit (𝓡∂ 1) 𝓘(ℝ) n (fun (z : Icc x y) ↦ (z : ℝ)) := by intro z - letI φ₀ := ContinuousLinearEquiv.prodUnique ℝ (EuclideanSpace ℝ (Fin 1)) Unit + let φ₀ := ContinuousLinearEquiv.prodUnique ℝ (EuclideanSpace ℝ (Fin 1)) Unit let φ : (EuclideanSpace ℝ (Fin 1) × Unit) ≃L[ℝ] ℝ := φ₀.trans (PiLp.equivOfUnique 2 ℝ (fun (_ : Fin 1) ↦ ℝ)) by_cases hz : ↑z < y diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index 08069325e3a9c6..f9814addf3e62e 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -81,7 +81,7 @@ variable {M} theorem commProb_eq_one_iff [h : Nonempty M] : commProb M = 1 ↔ IsMulCommutative M := by classical - haveI := Fintype.ofFinite M + have := Fintype.ofFinite M rw [commProb, ← Set.coe_ofPred, Nat.card_eq_fintype_card, Nat.card_eq_fintype_card] rw [div_eq_one_iff_eq, ← Nat.cast_pow, Nat.cast_inj, sq, ← card_prod, set_fintype_card_eq_univ_iff, Set.eq_univ_iff_forall] diff --git a/Mathlib/Init.lean b/Mathlib/Init.lean index be658564cb7a98..f80c0643d8d9d6 100644 --- a/Mathlib/Init.lean +++ b/Mathlib/Init.lean @@ -13,6 +13,7 @@ public import Mathlib.Tactic.Linter.DocString public import Mathlib.Tactic.Linter.EmptyLine public import Mathlib.Tactic.Linter.GlobalAttributeIn public import Mathlib.Tactic.Linter.HashCommandLinter +public import Mathlib.Tactic.Linter.HaveILetI public import Mathlib.Tactic.Linter.Header public import Mathlib.Tactic.Linter.FlexibleLinter public import Mathlib.Tactic.Linter.Multigoal diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index 223244e95bddee..3d94406c186689 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -146,7 +146,7 @@ theorem of_disjoint_iUnion (hm : ∀ i, MeasurableSet (f i)) (hd : Pairwise (Dis theorem of_biUnion {ι : Type*} {s : Set ι} {f : ι → Set α} (hs : s.Countable) (hd : s.Pairwise (Disjoint on f)) (h : ∀ b ∈ s, MeasurableSet (f b)) : v (⋃ b ∈ s, f b) = ∑' p : s, v (f p) := by - haveI := hs.toEncodable + have := hs.toEncodable rw [biUnion_eq_iUnion] apply of_disjoint_iUnion · exact fun x ↦ h x x.2 diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 2b01d7d338d08e..506ca9ab5e4963 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -191,6 +191,7 @@ public import Mathlib.Tactic.Linter.FindDeprecations public import Mathlib.Tactic.Linter.FlexibleLinter public import Mathlib.Tactic.Linter.GlobalAttributeIn public import Mathlib.Tactic.Linter.HashCommandLinter +public import Mathlib.Tactic.Linter.HaveILetI public import Mathlib.Tactic.Linter.HaveLetLinter public import Mathlib.Tactic.Linter.Header public import Mathlib.Tactic.Linter.Lint diff --git a/Mathlib/Tactic/Linter/HaveILetI.lean b/Mathlib/Tactic/Linter/HaveILetI.lean new file mode 100644 index 00000000000000..91f579fa41c4fe --- /dev/null +++ b/Mathlib/Tactic/Linter/HaveILetI.lean @@ -0,0 +1,78 @@ +/- +Copyright (c) 2026 Jovan Gerbscheid. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jovan Gerbscheid +-/ +module + +public meta import Lean.Meta.Hint +-- Import this linter explicitly to ensure that +-- this file has a valid copyright header and module docstring. +public import Mathlib.Tactic.Linter.Header -- shake: keep + +/-! +# The `haveI`/`letI` linter + +The tactics `haveI` and `letI` differ from `have` and `let` only in that they inline +the given value into the term being constructed, instead of binding it with a +`have`/`let` binder. (In Lean 3, `haveI`/`letI` were additionally needed to make the new +hypothesis available to instance resolution; in Lean 4, `have` and `let` register local +instances themselves, so inlining is the only remaining difference.) + +Inside the proof of a proposition this difference is invisible: proofs are irrelevant, +so nothing can depend on whether a value was inlined into the proof term. Hence +`haveI`/`letI` are never needed in tactic proofs of propositions, and `have`/`let` +should be used instead. + +This linter flags every use of the `haveI` or `letI` tactic whose main goal is a +proposition. + +TODO: +* also lint the term-mode `haveI`/`letI` +-/ + +meta section + +open Lean Elab Meta Parser.Term Tactic Linter + +namespace Mathlib.Linter.HaveILetI + +/-- The `haveILetI` linter flags uses of the `haveI` or `letI` tactic in a proof of a +proposition. Since proofs are irrelevant, the value-inlining behaviour of `haveI`/`letI` +can have no effect there, and `have`/`let` should be used instead. -/ +public register_option linter.style.haveILetI : Bool := { + defValue := true + descr := "enable the `haveILetI` linter" +} + +/-- Run the `haveI` tactic, with a try this suggestion when the goal is a `Prop`. -/ +def runHaveI (tk : Syntax) (c : TSyntax ``letConfig) (d : TSyntax ``letDecl) : TacticM Unit := do + evalTactic (← `(tactic| haveI $c:letConfig $d:letDecl)) + if getLinterValue linter.style.haveILetI (← getLinterOptions) then + withMainContext do + if ← isProp (← getMainTarget) then + let suggs ← Hint.mkSuggestionsMessage #[{toTryThisSuggestion := "have"}] tk none false + logLint linter.style.haveILetI (← getRef) m!"Try this: {suggs}\n\n\ + The goal is a proposition, so `have` is preferred over `haveI`.\n\ + The difference between `have` and `haveI` is that `haveI` inlines the value.\n\ + But this is not relevant for proofs because of proof irrelevance." + +@[tactic_alt Parser.Tactic.tacticHaveI__] +elab (priority := high) tk:"haveI" c:letConfig d:letDecl : tactic => runHaveI tk c d + +/-- Run the `letI` tactic, with a try this suggestion when the goal is a `Prop`. -/ +def runLetI (tk : Syntax) (c : TSyntax ``letConfig) (d : TSyntax ``letDecl) : TacticM Unit := do + evalTactic (← `(tactic| letI $c:letConfig $d:letDecl)) + if getLinterValue linter.style.haveILetI (← getLinterOptions) then + withMainContext do + if ← isProp (← getMainTarget) then + let suggs ← Hint.mkSuggestionsMessage #[{toTryThisSuggestion := "let"}] tk none false + logLint linter.style.haveILetI (← getRef) m!"Try this: {suggs}\n\n\ + The goal is a proposition, so `let` is preferred over `letI`.\n\ + The difference between `let` and `letI` is that `letI` inlines the value.\n\ + But this is not relevant for proofs because of proof irrelevance." + +@[tactic_alt Parser.Tactic.tacticLetI__] +elab (priority := high) tk:"letI" c:letConfig d:letDecl : tactic => runLetI tk c d + +end Mathlib.Linter.HaveILetI diff --git a/MathlibTest/InstanceDiamonds.lean b/MathlibTest/InstanceDiamonds.lean index 1e75f7ca3ceaf6..327a41be8d4623 100644 --- a/MathlibTest/InstanceDiamonds.lean +++ b/MathlibTest/InstanceDiamonds.lean @@ -154,7 +154,7 @@ the domain is a group. -/ example {k : Type _} [Semiring k] [Nontrivial kˣ] : (Finsupp.comapSMul : SMul kˣ (kˣ →₀ k)) ≠ Finsupp.smulZeroClass.toSMul := by obtain ⟨u : kˣ, hu⟩ := exists_ne (1 : kˣ) - haveI : Nontrivial k := Units.val_injective.nontrivial + have : Nontrivial k := Units.val_injective.nontrivial intro h simp only [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), funext_iff, DFunLike.ext_iff] at h replace h := h u (Finsupp.single 1 1) u diff --git a/MathlibTest/Linter/HaveILetI.lean b/MathlibTest/Linter/HaveILetI.lean new file mode 100644 index 00000000000000..793d3d2f5cca60 --- /dev/null +++ b/MathlibTest/Linter/HaveILetI.lean @@ -0,0 +1,28 @@ +module + +public import Mathlib.Tactic.Linter.HaveILetI + +/-- +warning: Try this: ⏎ + haveI̵ + +The goal is a proposition, so `have` is preferred over `haveI`. +The difference between `have` and `haveI` is that `haveI` inlines the value. +But this is not relevant for proofs because of proof irrelevance. + +Note: This linter can be disabled with `set_option linter.style.haveILetI false` +--- +warning: Try this: ⏎ + letI̵ + +The goal is a proposition, so `let` is preferred over `letI`. +The difference between `let` and `letI` is that `letI` inlines the value. +But this is not relevant for proofs because of proof irrelevance. + +Note: This linter can be disabled with `set_option linter.style.haveILetI false` +-/ +#guard_msgs in +example : True := by + haveI : True := trivial + letI : True := trivial + trivial diff --git a/MathlibTest/Tactic/ITauto.lean b/MathlibTest/Tactic/ITauto.lean index 177ded212ae726..d18466aad26831 100644 --- a/MathlibTest/Tactic/ITauto.lean +++ b/MathlibTest/Tactic/ITauto.lean @@ -60,9 +60,9 @@ set_option linter.unusedVariables false in set_option linter.unusedTactic false in -- failure tests example (p q r : Prop) : True := by - haveI : p ∨ ¬p := by (fail_if_success itauto); sorry - clear this; haveI : ¬(p ↔ q) → ¬p → q := by (fail_if_success itauto); sorry - clear this; haveI : ¬(p ↔ q) → (r ↔ q) → (p ↔ ¬r) := by (fail_if_success itauto); sorry + have : p ∨ ¬p := by (fail_if_success itauto); grind + clear this; have : ¬(p ↔ q) → ¬p → q := by (fail_if_success itauto); grind + clear this; have : ¬(p ↔ q) → (r ↔ q) → (p ↔ ¬r) := by (fail_if_success itauto); grind trivial example (P : Nat → Prop) (n : Nat) diff --git a/MathlibTest/TransImports.lean b/MathlibTest/TransImports.lean index 3f91b2bfb62744..3bcad6d0bbfc3d 100644 --- a/MathlibTest/TransImports.lean +++ b/MathlibTest/TransImports.lean @@ -3,8 +3,8 @@ import Mathlib.Util.TransImports /-- info: 'MathlibTest.TransImports' has at most 2000 transitive imports -2 starting with "Mathlib.Tactic.Linter.H": -[Mathlib.Tactic.Linter.HashCommandLinter, Mathlib.Tactic.Linter.Header] +3 starting with "Mathlib.Tactic.Linter.H": +[Mathlib.Tactic.Linter.HashCommandLinter, Mathlib.Tactic.Linter.HaveILetI, Mathlib.Tactic.Linter.Header] -/ #guard_msgs in #trans_imports "Mathlib.Tactic.Linter.H" at_most 2000 From 8f845ad22e5caace30bf431f91c084bb309bec77 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 21:14:39 +0000 Subject: [PATCH 1081/1300] chore: update Mathlib dependencies 2026-07-29 (#42259) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index f7e0737aa17c2b..43aaa30cab5f96 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "d60e6444e6fd881dfa077ff36e96de75753afa28", + "rev": "41bd267b3f6b7252f6676af46d4ffc6783b64de9", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 80a3b5d91985b3c50e59239bbe5fa08613b5ec31 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 29 Jul 2026 22:06:16 +0000 Subject: [PATCH 1082/1300] chore: address comments from #42114 (#42257) Addresses comments from #42114. In particular, we add docstrings for `isOpen_Ioo'` (and `isOpen_Iio'`, `isOpen_Ioi'`) and use dot notation. Co-authored-by: NoahW314 --- Mathlib/Topology/Order/Basic.lean | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index 1c668250cd8c44..66db37930cd711 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -114,12 +114,14 @@ theorem isOpen_iff_generate_intervals [t : OrderTopology α] {s : Set α} : theorem isOpen_lt' [OrderTopology α] (a : α) : IsOpen { b : α | a < b } := isOpen_iff_generate_intervals.2 <| .basic _ ⟨a, .inl rfl⟩ -@[to_dual] +/-- A version of `isOpen_Ioi` that doesn't require a `LinearOrder`. -/ +@[to_dual /-- A version of `isOpen_Iio` that doesn't require a `LinearOrder`. -/] theorem isOpen_Ioi' [OrderTopology α] (a : α) : IsOpen (Ioi a) := isOpen_lt' a +/-- A version of `isOpen_Ioo` that doesn't require a `LinearOrder`. -/ @[to_dual self] theorem isOpen_Ioo' [OrderTopology α] (a b : α) : IsOpen (Ioo a b) := - IsOpen.inter (isOpen_Ioi' a) (isOpen_Iio' b) + (isOpen_Ioi' a).inter (isOpen_Iio' b) @[to_dual gt_mem_nhds] theorem lt_mem_nhds [OrderTopology α] {a b : α} (h : a < b) : ∀ᶠ x in 𝓝 b, a < x := From ad7bd8f3609cf7c05fa69c804ec1a0e7de25dbaf Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:30:22 +0000 Subject: [PATCH 1083/1300] chore(Analysis/Convex/Continuous): fix proof wanted (#42234) Kevin's Claude noticed that the first two commented out `proof_wanted`s should say `LocallyLipschitzOn` (currently they are identical to the last two commented out `proof_wanted`s which say `ContinuousOn`). Co-authored-by: tb65536 --- Mathlib/Analysis/Convex/Continuous.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Convex/Continuous.lean b/Mathlib/Analysis/Convex/Continuous.lean index 5c6ace7d827db2..da39705b256ca2 100644 --- a/Mathlib/Analysis/Convex/Continuous.lean +++ b/Mathlib/Analysis/Convex/Continuous.lean @@ -223,10 +223,10 @@ protected lemma ConcaveOn.locallyLipschitz (hf : ConcaveOn ℝ univ f) : Locally -- Commented out since `intrinsicInterior` is not imported (but should be once these are proved) -- proof_wanted ConvexOn.locallyLipschitzOn_intrinsicInterior (hf : ConvexOn ℝ C f) : --- ContinuousOn f (intrinsicInterior ℝ C) +-- LocallyLipschitzOn (intrinsicInterior ℝ C) f -- proof_wanted ConcaveOn.locallyLipschitzOn_intrinsicInterior (hf : ConcaveOn ℝ C f) : --- ContinuousOn f (intrinsicInterior ℝ C) +-- LocallyLipschitzOn (intrinsicInterior ℝ C) f -- proof_wanted ConvexOn.continuousOn_intrinsicInterior (hf : ConvexOn ℝ C f) : -- ContinuousOn f (intrinsicInterior ℝ C) From 481daa6fe9ab148e2cc3f9a667298edbbcba3ee0 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Thu, 30 Jul 2026 00:05:45 +0000 Subject: [PATCH 1084/1300] feat(RingTheory/Algebraic): tower law for Module.finrank over domains (#41614) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `Module.finrank_mul_finrank'`, a variant of the tower law `finrank R S * finrank S T = finrank R T` for a tower of domains `R → S → T`. --- Mathlib/LinearAlgebra/Dimension/Free.lean | 5 ++++- Mathlib/RingTheory/Algebraic/Integral.lean | 24 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index 73bcc777f8d337..691e13d49d4fed 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -61,7 +61,10 @@ theorem rank_mul_rank (A : Type v) [AddCommMonoid A] convert! lift_rank_mul_lift_rank F K A <;> rw [lift_id] /-- Tower law: if `A` is a `K`-module and `K` is an extension of `F` then -$\operatorname{rank}_F(A) = \operatorname{rank}_F(K) * \operatorname{rank}_K(A)$. -/ +$\operatorname{rank}_F(A) = \operatorname{rank}_F(K) * \operatorname{rank}_K(A)$. + +See `Module.finrank_mul_finrank'` for a variant over a tower of domains that assumes the rings are +module-finite rather than the modules being free. -/ theorem Module.finrank_mul_finrank : finrank F K * finrank K A = finrank F A := by simp_rw [finrank] rw [← toNat_lift.{w} (Module.rank F K), ← toNat_lift.{v} (Module.rank K A), ← toNat_mul, diff --git a/Mathlib/RingTheory/Algebraic/Integral.lean b/Mathlib/RingTheory/Algebraic/Integral.lean index 1dd7574f73f86e..9ef1db23b5da56 100644 --- a/Mathlib/RingTheory/Algebraic/Integral.lean +++ b/Mathlib/RingTheory/Algebraic/Integral.lean @@ -5,12 +5,11 @@ Authors: Johan Commelin -/ module +public import Mathlib.Algebra.Ring.Hom.InjSurj public import Mathlib.LinearAlgebra.Dimension.Localization public import Mathlib.RingTheory.Algebraic.Basic public import Mathlib.RingTheory.IntegralClosure.IsIntegralClosure.Basic -public import Mathlib.RingTheory.Localization.BaseChange - -import Mathlib.RingTheory.Polynomial.Subring +public import Mathlib.RingTheory.Polynomial.Subring /-! # Algebraic elements and integral elements @@ -563,6 +562,25 @@ theorem rank_fractionRing [IsDomain S] : end Algebra.IsAlgebraic +attribute [local instance] FractionRing.liftAlgebra in +/-- Tower law for `Module.finrank` in a tower of domains `R → S → T`. This is a variant of +`Module.finrank_mul_finrank` that assumes the rings are domains instead of the modules being +free. -/ +theorem Module.finrank_mul_finrank' (T : Type*) [CommRing T] [IsDomain T] + [Algebra S T] [Algebra R T] [IsScalarTower R S T] [FaithfulSMul S T] : + Module.finrank R S * Module.finrank S T = Module.finrank R T := by + by_cases h : FaithfulSMul R S + · have : FaithfulSMul R T := .trans R S T + have : IsDomain R := (FaithfulSMul.algebraMap_injective R T).isDomain + have : IsDomain S := (FaithfulSMul.algebraMap_injective S T).isDomain + rw [← IsFractionRing.finrank_eq R (FractionRing R) S (FractionRing S), + ← IsFractionRing.finrank_eq S (FractionRing S) T (FractionRing T), + ← IsFractionRing.finrank_eq R (FractionRing R) T (FractionRing T), + Module.finrank_mul_finrank (FractionRing R) (FractionRing S) (FractionRing T)] + · rw [Module.finrank_eq_zero_of_not_faithfulSMul h, zero_mul, + Module.finrank_eq_zero_of_not_faithfulSMul] + exact fun _ ↦ h (FaithfulSMul.tower_bot R S T) + section Polynomial attribute [local instance] Polynomial.algebra MvPolynomial.algebraMvPolynomial From ccedd504126da4c77960a5c726b90ef554156fdd Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 30 Jul 2026 03:14:59 +0000 Subject: [PATCH 1085/1300] chore(CategoryTheory/Monoidal/Cartesian/Over): remove most backward options (#42267) This PR uses `implicit_reducible` to remove some backward options that currently block the use of `scripts/rm_set_option.py`. --- .../Limits/Constructions/Over/Products.lean | 7 +-- Mathlib/CategoryTheory/Limits/HasLimits.lean | 2 + .../Monoidal/Cartesian/Over.lean | 52 ------------------- 3 files changed, 3 insertions(+), 58 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean b/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean index 41d85225189a37..215af2517495b8 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean @@ -56,10 +56,9 @@ namespace CategoryTheory.Limits section Over variable {f : Y ⟶ X} {g : Z ⟶ X} -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in /-- Pullback cones to `X` are the same thing as binary fans in `Over X`. -/ -@[simps] +@[implicit_reducible, simps] def pullbackConeEquivBinaryFan : PullbackCone f g ≌ BinaryFan (Over.mk f) (.mk g) where functor.obj c := .mk (Over.homMk (U := .mk (c.fst ≫ f)) (V := .mk f) c.fst rfl) (Over.homMk (U := .mk (c.fst ≫ f)) (V := .mk g) c.snd c.condition.symm) @@ -94,9 +93,6 @@ def IsLimit.pullbackConeEquivBinaryFanFunctor {c : PullbackCone f g} (hc : IsLim · simpa using! congr(($e₁).left) · simpa using! congr(($e₂).left) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency.types false in /-- A pullback cone to `X` is a limit if its corresponding binary fan in `Over X` is a limit. -/ -- This could also be `(IsLimit.ofConeEquiv pullbackConeEquivBinaryFan.symm).symm hc`, but possibly -- bad defeqs? @@ -186,7 +182,6 @@ variable {X : C} {Y Z : Over X} open Limits set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in lemma isPullback_of_binaryFan_isLimit (c : BinaryFan Y Z) (hc : IsLimit c) : IsPullback c.fst.left c.snd.left Y.hom Z.hom := ⟨by simp, ⟨hc.pullbackConeEquivBinaryFanInverse⟩⟩ diff --git a/Mathlib/CategoryTheory/Limits/HasLimits.lean b/Mathlib/CategoryTheory/Limits/HasLimits.lean index daf22dcd488b58..b92a031ebd32a5 100644 --- a/Mathlib/CategoryTheory/Limits/HasLimits.lean +++ b/Mathlib/CategoryTheory/Limits/HasLimits.lean @@ -142,6 +142,7 @@ def limit (F : J ⥤ C) [HasLimit F] := (limit.cone F).pt /-- The projection from the limit object to a value of the functor. -/ +@[implicit_reducible] def limit.π (F : J ⥤ C) [HasLimit F] (j : J) : limit F ⟶ F.obj j := (limit.cone F).π.app j @@ -704,6 +705,7 @@ def colimit (F : J ⥤ C) [HasColimit F] := (colimit.cocone F).pt /-- The coprojection from a value of the functor to the colimit object. -/ +@[implicit_reducible] def colimit.ι (F : J ⥤ C) [HasColimit F] (j : J) : F.obj j ⟶ colimit F := (colimit.cocone F).ι.app j diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean index 1d995fe3a4337d..04966938bfeaa1 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Over.lean @@ -29,8 +29,6 @@ open CategoryTheory.Functor Limits CartesianMonoidalCategory variable {C : Type*} [Category* C] [HasPullbacks C] -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- A choice of finite products of `Over X` given by `Limits.pullback`. -/ abbrev cartesianMonoidalCategory (X : C) : CartesianMonoidalCategory (Over X) := .ofChosenFiniteProducts @@ -41,7 +39,6 @@ abbrev cartesianMonoidalCategory (X : C) : CartesianMonoidalCategory (Over X) := attribute [local instance] cartesianMonoidalCategory -set_option backward.isDefEq.respectTransparency.types false in /-- `Over X` is braided w.r.t. the Cartesian monoidal structure given by `Limits.pullback`. -/ abbrev braidedCategory (X : C) : BraidedCategory (Over X) := .ofCartesianMonoidalCategory @@ -52,200 +49,162 @@ open MonoidalCategory variable {X : C} -set_option backward.isDefEq.respectTransparency.types false in @[ext] lemma tensorObj_ext {R : C} {S T : Over X} (f₁ f₂ : R ⟶ (S ⊗ T).left) (e₁ : f₁ ≫ pullback.fst _ _ = f₂ ≫ pullback.fst _ _) (e₂ : f₁ ≫ pullback.snd _ _ = f₂ ≫ pullback.snd _ _) : f₁ = f₂ := pullback.hom_ext e₁ e₂ -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorObj_left (R S : Over X) : (R ⊗ S).left = Limits.pullback R.hom S.hom := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorObj_hom (R S : Over X) : (R ⊗ S).hom = pullback.fst R.hom S.hom ≫ R.hom := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorUnit_left : (𝟙_ (Over X)).left = X := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma tensorUnit_hom : (𝟙_ (Over X)).hom = 𝟙 X := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma lift_left {R S T : Over X} (f : R ⟶ S) (g : R ⟶ T) : (lift f g).left = pullback.lift f.left g.left (f.w.trans g.w.symm) := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma fst_left {R S : Over X} : (fst R S).left = pullback.fst _ _ := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma snd_left {R S : Over X} : (snd R S).left = pullback.snd _ _ := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma toUnit_left {R : Over X} : (toUnit R).left = R.hom := rfl -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_fst (R S T : Over X) : (α_ R S T).hom.left ≫ pullback.fst _ (pullback.fst _ _ ≫ _) = pullback.fst _ _ ≫ pullback.fst _ _ := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_snd_fst (R S T : Over X) : (α_ R S T).hom.left ≫ pullback.snd _ (pullback.fst _ _ ≫ _) ≫ pullback.fst _ _ = pullback.fst _ _ ≫ pullback.snd _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_hom_left_snd_snd (R S T : Over X) : (α_ R S T).hom.left ≫ pullback.snd _ (pullback.fst _ _ ≫ _) ≫ pullback.snd _ _ = pullback.snd _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_fst_fst (R S T : Over X) : (α_ R S T).inv.left ≫ pullback.fst (pullback.fst _ _ ≫ _) _ ≫ pullback.fst _ _ = pullback.fst _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_fst_snd (R S T : Over X) : (α_ R S T).inv.left ≫ pullback.fst (pullback.fst _ _ ≫ _) _ ≫ pullback.snd _ _ = pullback.snd _ _ ≫ pullback.fst _ _ := (limit.lift_π_assoc _ _ _).trans (limit.lift_π _ _) -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma associator_inv_left_snd (R S T : Over X) : (α_ R S T).inv.left ≫ pullback.snd (pullback.fst _ _ ≫ _) _ = pullback.snd _ _ ≫ pullback.snd _ _ := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma leftUnitor_hom_left (Y : Over X) : (λ_ Y).hom.left = pullback.snd _ _ := rfl -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma leftUnitor_inv_left_fst (Y : Over X) : (λ_ Y).inv.left ≫ pullback.fst (𝟙 X) _ = Y.hom := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma leftUnitor_inv_left_snd (Y : Over X) : (λ_ Y).inv.left ≫ pullback.snd (𝟙 X) _ = 𝟙 Y.left := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma rightUnitor_hom_left (Y : Over X) : (ρ_ Y).hom.left = pullback.fst _ (𝟙 X) := rfl -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma rightUnitor_inv_left_fst (Y : Over X) : (ρ_ Y).inv.left ≫ pullback.fst _ (𝟙 X) = 𝟙 _ := limit.lift_π _ _ -#adaptation_note -/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma rightUnitor_inv_left_snd (Y : Over X) : (ρ_ Y).inv.left ≫ pullback.snd _ (𝟙 X) = Y.hom := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in lemma whiskerLeft_left {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left = pullback.map _ _ _ _ (𝟙 _) f.left (𝟙 _) (by simp) (by simp) := rfl -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerLeft_left_fst {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left ≫ pullback.fst _ _ = pullback.fst _ _ := (limit.lift_π _ _).trans (Category.comp_id _) -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerLeft_left_snd {R S T : Over X} (f : S ⟶ T) : (R ◁ f).left ≫ pullback.snd _ _ = pullback.snd _ _ ≫ f.left := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in lemma whiskerRight_left {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left = pullback.map _ _ _ _ f.left (𝟙 _) (𝟙 _) (by simp) (by simp) := rfl -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerRight_left_fst {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left ≫ pullback.fst _ _ = pullback.fst _ _ ≫ f.left := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma whiskerRight_left_snd {R S T : Over X} (f : S ⟶ T) : (f ▷ R).left ≫ pullback.snd _ _ = pullback.snd _ _ := (limit.lift_π _ _).trans (Category.comp_id _) -set_option backward.isDefEq.respectTransparency.types false in lemma tensorHom_left {R S T U : Over X} (f : R ⟶ S) (g : T ⟶ U) : (f ⊗ₘ g).left = pullback.map _ _ _ _ f.left g.left (𝟙 _) (by simp) (by simp) := rfl -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma tensorHom_left_fst {S U : C} {R T : Over X} (fS : S ⟶ X) (fU : U ⟶ X) (f : R ⟶ mk fS) (g : T ⟶ mk fU) : (f ⊗ₘ g).left ≫ pullback.fst fS fU = pullback.fst R.hom T.hom ≫ f.left := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] lemma tensorHom_left_snd {S U : C} {R T : Over X} (fS : S ⟶ X) (fU : U ⟶ X) (f : R ⟶ mk fS) (g : T ⟶ mk fU) : (f ⊗ₘ g).left ≫ pullback.snd fS fU = pullback.snd R.hom T.hom ≫ g.left := limit.lift_π _ _ -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma braiding_hom_left {R S : Over X} : (β_ R S).hom.left = (pullbackSymmetry _ _).hom := rfl -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma braiding_inv_left {R S : Over X} : (β_ R S).inv.left = (pullbackSymmetry _ _).hom := rfl variable {A B R S Y Z : C} {f : R ⟶ X} {g : S ⟶ X} -set_option backward.isDefEq.respectTransparency.types false in instance : (Over.pullback f).Braided := .ofChosenFiniteProducts _ -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma η_pullback_left : (OplaxMonoidal.η (Over.pullback f)).left = (pullback.snd (𝟙 _) f) := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] lemma ε_pullback_left : (LaxMonoidal.ε (Over.pullback f)).left = inv (pullback.snd (𝟙 _) f) := by apply IsIso.eq_inv_of_hom_inv_id rw [← η_pullback_left, ← Over.comp_left, Monoidal.η_ε, Over.id_left] -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in lemma μ_pullback_left_fst_fst (R S : Over X) : (LaxMonoidal.μ (Over.pullback f) R S).left ≫ @@ -255,7 +214,6 @@ lemma μ_pullback_left_fst_fst (R S : Over X) : Iso.hom_inv_id] simp [CartesianMonoidalCategory.prodComparison, fst] -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in lemma μ_pullback_left_fst_snd (R S : Over X) : (LaxMonoidal.μ (Over.pullback f) R S).left ≫ @@ -274,7 +232,6 @@ lemma μ_pullback_left_snd (R S : Over X) : ← Over.comp_left_assoc, Iso.hom_inv_id] simp [CartesianMonoidalCategory.prodComparison] -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma μ_pullback_left_fst_fst' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : (LaxMonoidal.μ (Over.pullback f) (.mk g₁) (.mk g₂)).left ≫ @@ -282,7 +239,6 @@ lemma μ_pullback_left_fst_fst' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : pullback.fst _ _ ≫ pullback.fst _ _ := μ_pullback_left_fst_fst .. -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma μ_pullback_left_fst_snd' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : (LaxMonoidal.μ (Over.pullback f) (.mk g₁) (.mk g₂)).left ≫ @@ -290,21 +246,18 @@ lemma μ_pullback_left_fst_snd' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : pullback.snd _ _ ≫ pullback.fst _ _ := μ_pullback_left_fst_snd .. -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma μ_pullback_left_snd' (g₁ : Y ⟶ X) (g₂ : Z ⟶ X) : (LaxMonoidal.μ (Over.pullback f) (.mk g₁) (.mk g₂)).left ≫ pullback.snd (pullback.fst g₁ g₂ ≫ g₁) f = pullback.snd _ _ ≫ pullback.snd _ _ := μ_pullback_left_snd .. -set_option backward.isDefEq.respectTransparency false in @[simp] lemma preservesTerminalIso_pullback (f : R ⟶ S) : preservesTerminalIso (Over.pullback f) = Over.isoMk (asIso (pullback.snd (𝟙 _) f)) (by simp) := by ext1; exact toUnit_unique _ _ -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @[simp] lemma prodComparisonIso_pullback_inv_left_fst_fst (f : X ⟶ Y) (A B : Over Y) : @@ -315,7 +268,6 @@ lemma prodComparisonIso_pullback_inv_left_fst_fst (f : X ⟶ Y) (A B : Over Y) : Over.hom_left_inv_left_assoc] simp [CartesianMonoidalCategory.prodComparison, fst] -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma prodComparisonIso_pullback_Spec_inv_left_fst_fst' (f : X ⟶ Y) (gA : A ⟶ Y) (gB : B ⟶ Y) : (prodComparisonIso (Over.pullback f) (.mk gA) (.mk gB)).inv.left ≫ @@ -323,7 +275,6 @@ lemma prodComparisonIso_pullback_Spec_inv_left_fst_fst' (f : X ⟶ Y) (gA : A pullback.fst (pullback.snd gA f) (pullback.snd gB f) ≫ pullback.fst _ _ := prodComparisonIso_pullback_inv_left_fst_fst .. -set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @[simp] lemma prodComparisonIso_pullback_inv_left_fst_snd' (f : X ⟶ Y) (gA : A ⟶ Y) (gB : B ⟶ Y) : @@ -343,7 +294,6 @@ lemma prodComparisonIso_pullback_inv_left_snd' (f : X ⟶ Y) (gA : A ⟶ Y) (gB Over.hom_left_inv_left_assoc] simp [CartesianMonoidalCategory.prodComparison] -set_option backward.isDefEq.respectTransparency.types false in /-- The pullback of a monoid object is a monoid object. -/ @[simps! -isSimp mul one] abbrev monObjMkPullbackSnd [MonObj (Over.mk f)] : MonObj (Over.mk <| pullback.snd f g) := @@ -351,12 +301,10 @@ abbrev monObjMkPullbackSnd [MonObj (Over.mk f)] : MonObj (Over.mk <| pullback.sn attribute [local instance] monObjMkPullbackSnd -set_option backward.isDefEq.respectTransparency.types false in instance isCommMonObj_mk_pullbackSnd [MonObj (Over.mk f)] [IsCommMonObj (Over.mk f)] : IsCommMonObj (Over.mk <| pullback.snd f g) := ((Over.pullback g).mapCommMon.obj <| .mk <| .mk f).comm -set_option backward.isDefEq.respectTransparency.types false in /-- The pullback of a monoid object is a monoid object. -/ @[simps! -isSimp mul one] abbrev grpObjMkPullbackSnd [GrpObj (Over.mk f)] : GrpObj (Over.mk (pullback.snd f g)) := From 60af7185ecf32ed5cab100f9960f1d588b9a6cab Mon Sep 17 00:00:00 2001 From: Chris Henson <46805207+chenson2018@users.noreply.github.com> Date: Thu, 30 Jul 2026 04:22:55 +0000 Subject: [PATCH 1086/1300] fix: increase priority of show elaboration (#42264) See [this thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Performance.20cost.20of.20info.20tree.20traversal/with/610705175) for discussion. This prevents a confusing lack of messages for the `show` tactic introduced in #41761. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Tactic/Linter/Style.lean | 4 +++- MathlibTest/Linter/Show.lean | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 MathlibTest/Linter/Show.lean diff --git a/Mathlib/Tactic/Linter/Style.lean b/Mathlib/Tactic/Linter/Style.lean index 8e1d4af6bcdea4..ccfca84e020510 100644 --- a/Mathlib/Tactic/Linter/Style.lean +++ b/Mathlib/Tactic/Linter/Style.lean @@ -647,8 +647,10 @@ def elabShow (newType : Term) : TacticM Unit := do readability.\nHowever, this tactic invocation changed the goal. Please use `change` \ instead for these purposes." +-- `(priority := high)` ensures we avoid producing choice nodes, and thereby avoid unexpected +-- behavior arising from choice node elaboration @[tactic_alt Tactic.show] -elab (name := «show») "show " newType:term : tactic => elabShow newType +elab (name := «show») (priority := high) "show " newType:term : tactic => elabShow newType end Style diff --git a/MathlibTest/Linter/Show.lean b/MathlibTest/Linter/Show.lean new file mode 100644 index 00000000000000..ae04e466c8319e --- /dev/null +++ b/MathlibTest/Linter/Show.lean @@ -0,0 +1,21 @@ +module +import Mathlib.Tactic.Linter.Style + +set_option linter.style.show true + +/- +Check that logged messages appear when errors with synthetic `sorry` are thrown. + +If a choice node is produced, `evalChoice` (currently) resets the state, erasing logs, and +re-throwing the produced error. And if the error contains a synthetic sorry, Lean will not log it, +trusting that the (now-erased) logged errors that preceded it are sufficient. As such, a choice +node may ultimately produce a state with no visible errors at the tactic, since the logged ones +have been erased and the thrown ones are not rendered in expectation of the logged ones appearing. + +This test fails correctly now because the parser avoids producing a choice node in the first place, +via `(priority := high)`. +-/ + +/-- error: Unknown identifier `arbitrary_ident` -/ +#guard_msgs in +example : False := by show arbitrary_ident From 2b4f1fd3b3fd72117ba25a906f40d5021e3b44a6 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Thu, 30 Jul 2026 08:11:18 +0000 Subject: [PATCH 1087/1300] feat: generalize `range_lt_top_of_det_eq_zero` (#42055) --- Mathlib/LinearAlgebra/Determinant.lean | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index b0f09a2f994ce0..8c3b6d97e0749b 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -365,17 +365,13 @@ theorem det_eq_zero_iff_ker_ne_bot [IsDomain R] [Free R M] [Module.Finite R M] { rw [← det_toMatrix b, ← Matrix.exists_mulVec_eq_zero_iff] refine ⟨fun i => b.repr v i, by simpa, by simpa [toMatrix_mulVec_repr]⟩ -/-- -If the determinant of a map vanishes, then the map is not onto. -TODO: This should only require `[IsDomain R] [Free R M]`, which we get if we generalize -`Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean`, which includes -`LinearMap.ker_eq_bot_iff_range_eq_top`. --/ -theorem range_lt_top_of_det_eq_zero {𝕜 : Type*} [Field 𝕜] [Module 𝕜 M] {f : M →ₗ[𝕜] M} +/-- If the determinant of a map vanishes, then the map is not onto. -/ +theorem range_lt_top_of_det_eq_zero [IsDomain R] [Free R M] {f : M →ₗ[R] M} (hf : f.det = 0) : range f < ⊤ := by - have : Module.Finite 𝕜 M := by simp [finite_of_det_ne_one (f := f), hf] - rw [lt_top_iff_ne_top, ne_eq, ← ker_eq_bot_iff_range_eq_top, ← ne_eq, ← bot_lt_iff_ne_bot] - exact bot_lt_ker_of_det_eq_zero hf + rw [lt_top_iff_ne_top] + intro h + obtain ⟨g, hg⟩ := f.exists_rightInverse_of_surjective h + simpa [hf] using congr_arg LinearMap.det hg /-- When the function is over the base ring, the determinant is the evaluation at `1`. -/ @[simp] lemma det_ring (f : R →ₗ[R] R) : f.det = f 1 := by From e4c91783ca8e6a7c693ae624ade32fd22d4e43c1 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:12:33 +0000 Subject: [PATCH 1088/1300] =?UTF-8?q?chore:=20use=20`=3D=E1=B5=90[=CE=BC]`?= =?UTF-8?q?=20notation=20more=20(#42263)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Batixx --- Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean | 2 +- Mathlib/MeasureTheory/Integral/Layercake.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean index 240e9dcf911178..3662f5e0037daf 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean @@ -1387,7 +1387,7 @@ theorem denseRange_toLpCLM [FiniteDimensional ℝ E] [BorelSpace E] {p : ℝ≥0 refine (mem_closure_iff_nhds_basis Metric.nhds_basis_closedBall).2 fun ε hε ↦ ?_ obtain ⟨g, hg₁, hg₂, hg₃⟩ := MemLp.exist_eLpNorm_sub_le hp hp'.out (Lp.memLp f) hε use (hg₁.toSchwartzMap hg₂).toLp p μ - have : (f : E → F) - ((hg₁.toSchwartzMap hg₂).toLp p μ : E → F) =ᶠ[ae μ] (f : E → F) - g := by + have : (f : E → F) - ((hg₁.toSchwartzMap hg₂).toLp p μ : E → F) =ᵐ[μ] (f : E → F) - g := by filter_upwards [(hg₁.toSchwartzMap hg₂).coeFn_toLp p μ] simp simp only [Set.mem_range, toLpCLM_apply, exists_apply_eq_apply, Metric.mem_closedBall', true_and, diff --git a/Mathlib/MeasureTheory/Integral/Layercake.lean b/Mathlib/MeasureTheory/Integral/Layercake.lean index 15f41be5cefab4..4f8b92fe2c989e 100644 --- a/Mathlib/MeasureTheory/Integral/Layercake.lean +++ b/Mathlib/MeasureTheory/Integral/Layercake.lean @@ -290,7 +290,7 @@ theorem lintegral_comp_eq_lintegral_meas_le_mul_of_measurable (μ : Measure α) exists_seq_strictMono_tendsto M have I : ∀ n, g =ᵐ[volume.restrict (Ioc (0 : ℝ) (u n))] 0 := by intro n - obtain ⟨s, hs, uns⟩ : ∃ s, g =ᶠ[ae (Measure.restrict volume (Ioc 0 s))] 0 ∧ u n < s := + obtain ⟨s, hs, uns⟩ : ∃ s, g =ᵐ[Measure.restrict volume (Ioc 0 s)] 0 ∧ u n < s := exists_lt_of_lt_csSup (Set.nonempty_of_mem zero_mem) (uM n) exact ae_restrict_of_ae_restrict_of_subset (Ioc_subset_Ioc_right uns.le) hs have : g =ᵐ[volume.restrict (⋃ n, Ioc (0 : ℝ) (u n))] 0 := (ae_restrict_iUnion_iff _ _).2 I From ccb5ed4c017083b250e5618e8523cfce4d26239d Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 30 Jul 2026 13:54:46 +0000 Subject: [PATCH 1089/1300] chore: change docstrings when they should be docComments (#42269) Change `/- ` to `/-- ` when it is arguably meant to be. In a few cases, it wasn't 100% clear to me which is preferable. This was just done with regex search, so probably not exhaustive. Co-authored-by: Batixx --- Mathlib/Algebra/Group/Submonoid/Support.lean | 4 ++-- Mathlib/Algebra/GroupWithZero/Range.lean | 3 ++- Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean | 2 +- Mathlib/CategoryTheory/Adjunction/Mates.lean | 2 +- Mathlib/CategoryTheory/Galois/Basic.lean | 2 +- Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean | 2 +- Mathlib/Order/KrullDimension.lean | 4 ++-- Mathlib/Order/LiminfLimsup.lean | 2 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 3 ++- Mathlib/Order/ScottContinuity/Complete.lean | 2 +- Mathlib/Probability/BrownianMotion/Basic.lean | 2 +- Mathlib/RingTheory/LaurentSeries.lean | 4 ++-- 12 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Mathlib/Algebra/Group/Submonoid/Support.lean b/Mathlib/Algebra/Group/Submonoid/Support.lean index 3b0cf85dae7af5..5fcb000f641cd7 100644 --- a/Mathlib/Algebra/Group/Submonoid/Support.lean +++ b/Mathlib/Algebra/Group/Submonoid/Support.lean @@ -54,8 +54,8 @@ theorem mem_mulSupport {x} : x ∈ M.mulSupport ↔ x ∈ M ∧ x⁻¹ ∈ M := @[to_additive (attr := simp)] theorem mulSupport_toSubmonoid : M.mulSupport.toSubmonoid = M ⊓ M⁻¹ := rfl -@[to_additive] -/- The support of a submonoid is the largest subgroup it contains. -/ +/-- The support of a submonoid is the largest subgroup it contains. -/ +@[to_additive /-- The support of a submonoid is the largest subgroup it contains. -/] theorem _root_.Subgroup.gc_toSubmonoid_mulSupport : GaloisConnection (α := Subgroup G) Subgroup.toSubmonoid mulSupport := fun _ _ ↦ ⟨fun _ _ ↦ by aesop, fun h _ hx ↦ (h hx).1⟩ diff --git a/Mathlib/Algebra/GroupWithZero/Range.lean b/Mathlib/Algebra/GroupWithZero/Range.lean index c656abccc958d6..41eb80908b517f 100644 --- a/Mathlib/Algebra/GroupWithZero/Range.lean +++ b/Mathlib/Algebra/GroupWithZero/Range.lean @@ -176,7 +176,8 @@ noncomputable section GroupWithZero variable [GroupWithZero A] [GroupWithZero B] {f : A →*₀ B} -/- When the *domain* is itself a group with zero, the `valueMonoid` and the `valueGroup` coincide.-/ +/-- +When the *domain* is itself a group with zero, the `valueMonoid` and the `valueGroup` coincide. -/ lemma valueMonoid_eq_valueGroup : (valueMonoid f) = (valueGroup f).toSubmonoid := by rw [valueGroup_def, Subgroup.closure_toSubmonoid, Eq.comm] apply Submonoid.closure_eq_of_le diff --git a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean index 8f444fe996e9a4..42fc2904160ec0 100644 --- a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean +++ b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean @@ -239,7 +239,7 @@ lemma hasSum_weierstrassPExcept (l₀ : ℂ) (z : ℂ) : (℘[L - l₀] z) := (L.hasSumLocallyUniformly_weierstrassPExcept l₀).hasSum -/- `weierstrassPExcept l₀` is differentiable on non-lattice points and `l₀`. -/ +/-- `weierstrassPExcept l₀` is differentiable on non-lattice points and `l₀`. -/ lemma differentiableOn_weierstrassPExcept (l₀ : ℂ) : DifferentiableOn ℂ ℘[L - l₀] (L.lattice \ {l₀})ᶜ := by refine (L.hasSumLocallyUniformly_weierstrassPExcept l₀).hasSumLocallyUniformlyOn.differentiableOn diff --git a/Mathlib/CategoryTheory/Adjunction/Mates.lean b/Mathlib/CategoryTheory/Adjunction/Mates.lean index a46895413dd9e3..6e603086cb6478 100644 --- a/Mathlib/CategoryTheory/Adjunction/Mates.lean +++ b/Mathlib/CategoryTheory/Adjunction/Mates.lean @@ -132,7 +132,7 @@ theorem mateEquiv_counit_symm (α : TwoSquare R₁ H G R₂) (d : D) : exact (mateEquiv_counit adj₁ adj₂ ((mateEquiv adj₁ adj₂).symm α) d) set_option backward.defeqAttrib.useBackward true in -/- A component of a transposed version of the mates correspondence. -/ +/-- A component of a transposed version of the mates correspondence. -/ theorem unit_mateEquiv (α : TwoSquare G L₁ L₂ H) (c : C) : G.map (adj₁.unit.app c) ≫ (mateEquiv adj₁ adj₂ α).app _ = adj₂.unit.app _ ≫ R₂.map (α.app _) := by diff --git a/Mathlib/CategoryTheory/Galois/Basic.lean b/Mathlib/CategoryTheory/Galois/Basic.lean index caa99925ca4147..36a41aab863f40 100644 --- a/Mathlib/CategoryTheory/Galois/Basic.lean +++ b/Mathlib/CategoryTheory/Galois/Basic.lean @@ -330,7 +330,7 @@ lemma epi_of_nonempty_of_isConnected {X A : C} [IsConnected A] [h : Nonempty (F. lemma surjective_on_fiber_of_epi {X Y : C} (f : X ⟶ Y) [Epi f] : Function.Surjective (F.map f) := surjective_of_epi (FintypeCat.incl.map (F.map f)) -/- A morphism from an object with non-empty fiber to a connected object is surjective on fibers. -/ +/-- A morphism from an object with non-empty fiber to a connected object is surjective on fibers. -/ lemma surjective_of_nonempty_fiber_of_isConnected {X A : C} [Nonempty (F.obj X)] [IsConnected A] (f : X ⟶ A) : Function.Surjective (F.map f) := by diff --git a/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean b/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean index d01d85c505d2c5..ada6574d2ed7e3 100644 --- a/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean +++ b/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean @@ -314,7 +314,7 @@ lemma isStrongFEPair_toStrongFEPair : IsStrongFEPair P.toStrongFEPair where hf₀ := rfl hg₀ := rfl -/- Alternative form for the difference between `f - f₀` and its modified term. -/ +/-- Alternative form for the difference between `f - f₀` and its modified term. -/ lemma f_modif_aux1 : EqOn (fun x ↦ P.f_modif x - P.f x + P.f₀) ((Ioo 0 1).indicator (fun x : ℝ ↦ P.f₀ - (P.ε * ↑(x ^ (-P.k))) • P.g₀) + ({1} : Set ℝ).indicator (fun _ ↦ P.f₀ - P.f 1)) (Ioi 0) := by diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index 5d637a67b8c2af..fdedd7636603f3 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -277,7 +277,7 @@ private lemma height_add_const (a : α) (n : ℕ∞) : have hne : Nonempty { p : LTSeries α // p.last = a } := ⟨RelSeries.singleton _ a, rfl⟩ rw [height_eq_iSup_last_eq, iSup_subtype', iSup_subtype', ENat.iSup_add] -/- For elements of finite height, `height` is strictly monotone. -/ +/-- For elements of finite height, `height` is strictly monotone. -/ @[gcongr] lemma height_strictMono {x y : α} (hxy : x < y) (hfin : height x < ⊤) : height x < height y := by rw [← ENat.add_one_le_iff hfin.ne, height_add_const, iSup₂_le_iff] @@ -298,7 +298,7 @@ lemma height_add_one_le {a b : α} (hab : a < b) : height a + 1 ≤ height b := gcongr simp [hfin] -/- For elements of finite height, `coheight` is strictly antitone. -/ +/-- For elements of finite height, `coheight` is strictly antitone. -/ @[gcongr] lemma coheight_strictAnti {x y : α} (hyx : y < x) (hfin : coheight x < ⊤) : coheight x < coheight y := height_strictMono (α := αᵒᵈ) hyx hfin diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index 0294720f9cad97..d641dd5a6a1f61 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -881,7 +881,7 @@ theorem limsup_le_iff {x : β} (h₁ : f.IsCoboundedUnder (· ≤ ·) u := by is rcases h' with ⟨z, x_z, hz⟩ exact (h z x_z).mono <| fun w hw ↦ (or_iff_left (not_le_of_gt hw)).1 (hz (u w)) -/- A version of `limsup_le_iff` with large inequalities in densely ordered spaces.-/ +/-- A version of `limsup_le_iff` with large inequalities in densely ordered spaces -/ lemma limsup_le_iff' [DenselyOrdered β] {x : β} (h₁ : IsCoboundedUnder (· ≤ ·) f u := by isBoundedDefault) (h₂ : IsBoundedUnder (· ≤ ·) f u := by isBoundedDefault) : diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 83026896b3da13..099f11bdb9715e 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -294,7 +294,8 @@ lemma ωScottContinuous_iff_monotone_map_ωSup : alias ⟨ωScottContinuous.monotone_map_ωSup, ωScottContinuous.of_monotone_map_ωSup⟩ := ωScottContinuous_iff_monotone_map_ωSup -/- A monotone function `f : α →o β` is ωScott continuous if and only if it distributes over ωSup. -/ +/-- +A monotone function `f : α →o β` is ωScott continuous if and only if it distributes over ωSup. -/ lemma ωScottContinuous_iff_map_ωSup_of_orderHom {f : α →o β} : ωScottContinuous f ↔ ∀ c : Chain α, f (ωSup c) = ωSup (c.map f) := by rw [ωScottContinuous_iff_monotone_map_ωSup] diff --git a/Mathlib/Order/ScottContinuity/Complete.lean b/Mathlib/Order/ScottContinuity/Complete.lean index fbb3fa352c3e69..cb7ee9fe4b046f 100644 --- a/Mathlib/Order/ScottContinuity/Complete.lean +++ b/Mathlib/Order/ScottContinuity/Complete.lean @@ -26,7 +26,7 @@ section CompleteLattice variable [CompleteLattice α] [CompleteLattice β] -/- `f` is Scott continuous if and only if it commutes with `sSup` on directed sets -/ +/-- `f` is Scott continuous if and only if it commutes with `sSup` on directed sets -/ lemma scottContinuous_iff_map_sSup {f : α → β} : ScottContinuous f ↔ ∀ ⦃d : Set α⦄, d.Nonempty → DirectedOn (· ≤ ·) d → f (sSup d) = sSup (f '' d) where diff --git a/Mathlib/Probability/BrownianMotion/Basic.lean b/Mathlib/Probability/BrownianMotion/Basic.lean index a2cb37d6c0f2cb..2ad458612b3625 100644 --- a/Mathlib/Probability/BrownianMotion/Basic.lean +++ b/Mathlib/Probability/BrownianMotion/Basic.lean @@ -77,7 +77,7 @@ structure IsPreBrownianReal (X : ℝ≥0 → Ω → ℝ) (P : Measure Ω := by v mk' :: hasLaw : ∀ I : Finset ℝ≥0, HasLaw (fun ω ↦ I.restrict (X · ω)) (projectiveFamily I) P -/- A modification of a pre-Brownian is pre-Brownian. -/ +/-- A modification of a pre-Brownian process is pre-Brownian. -/ lemma IsPreBrownianReal.congr {C : ℝ≥0 → Ω → ℝ} (hB : IsPreBrownianReal B P) (h : ∀ t, B t =ᵐ[P] C t) : IsPreBrownianReal C P where diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index f167b704b1dc4e..858772ec012a59 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -501,7 +501,7 @@ theorem valuation_single_zpow (s : ℤ) : · rw [Int.negSucc_eq, ← inv_inj, ← map_inv₀, inv_single, neg_neg, ← Int.natCast_succ, inv_one, ← HahnSeries.ofPowerSeries_X_pow, PowerSeries.coe_pow, valuation_X_pow, exp_neg] -/- The coefficients of a power series vanish in degree strictly less than its valuation. -/ +/-- The coefficients of a power series vanish in degree strictly less than its valuation. -/ theorem coeff_zero_of_lt_intValuation {n d : ℕ} {f : K⟦X⟧} (H : Valued.v (f : K⸨X⸩) ≤ exp (-d : ℤ)) : n < d → coeff n f = 0 := by @@ -511,7 +511,7 @@ theorem coeff_zero_of_lt_intValuation {n d : ℕ} {f : K⟦X⟧} intValuation_le_pow_iff_dvd (PowerSeries.idealX K) f d, PowerSeries.idealX, Ideal.span_singleton_pow, Ideal.span_singleton_dvd_span_singleton_iff_dvd] at H -/- The valuation of a power series is the order of the first non-zero coefficient. -/ +/-- The valuation of a power series is the order of the first non-zero coefficient. -/ theorem intValuation_le_iff_coeff_lt_eq_zero {d : ℕ} (f : K⟦X⟧) : Valued.v (f : K⸨X⸩) ≤ exp (-d : ℤ) ↔ ∀ n : ℕ, n < d → coeff n f = 0 := by From 62f3addadd0f6b58ac6ddd85c0ceec85012d64a9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Thu, 30 Jul 2026 14:46:42 +0000 Subject: [PATCH 1090/1300] chore: golf using fun_prop (#40019) Partially enabled through #35683. --- Counterexamples/TopologistsSineCurve.lean | 2 +- Mathlib/Analysis/Convex/Contractible.lean | 2 +- .../Condensed/Discrete/LocallyConstant.lean | 4 +-- Mathlib/Condensed/Light/Sequence.lean | 2 +- .../Constructions/Polish/Basic.lean | 2 +- .../Function/SpecialFunctions/Basic.lean | 34 ++++++------------- 6 files changed, 15 insertions(+), 31 deletions(-) diff --git a/Counterexamples/TopologistsSineCurve.lean b/Counterexamples/TopologistsSineCurve.lean index 218afac81a1db9..f1373a7b729490 100644 --- a/Counterexamples/TopologistsSineCurve.lean +++ b/Counterexamples/TopologistsSineCurve.lean @@ -111,7 +111,7 @@ is a continuous image of the positive real line). -/ theorem isConnected_T : IsConnected T := by rw [← closure_S] refine (isConnected_Ioi.image _ <| continuousOn_id.prodMk ?_).closure - exact continuous_sin.comp_continuousOn <| continuousOn_inv₀.mono fun _ hx ↦ hx.ne' + fun_prop (discharger := grind) /-! ## `T` is not path-connected diff --git a/Mathlib/Analysis/Convex/Contractible.lean b/Mathlib/Analysis/Convex/Contractible.lean index 83ad22aafc2674..78b3005642ebb4 100644 --- a/Mathlib/Analysis/Convex/Contractible.lean +++ b/Mathlib/Analysis/Convex/Contractible.lean @@ -28,7 +28,7 @@ protected theorem StarConvex.contractibleSpace (h : StarConvex ℝ x s) (hne : s (contractible_iff_id_nullhomotopic s).2 ⟨⟨x, h.mem hne⟩, ⟨⟨⟨fun p ↦ ⟨p.1.1 • x + (1 - p.1.1) • (p.2 : E), ?_⟩, ?_⟩, fun x ↦ by simp, fun x ↦ by simp⟩⟩⟩ · exact h p.2.2 p.1.2.1 (sub_nonneg.2 p.1.2.2) (add_sub_cancel _ _) - · exact Continuous.subtype_mk (by fun_prop) _ + · fun_prop /-- A non-empty convex set is a contractible space. -/ protected theorem Convex.contractibleSpace (hs : Convex ℝ s) (hne : s.Nonempty) : diff --git a/Mathlib/Condensed/Discrete/LocallyConstant.lean b/Mathlib/Condensed/Discrete/LocallyConstant.lean index e30e86dab9c30e..58d06717aef32d 100644 --- a/Mathlib/Condensed/Discrete/LocallyConstant.lean +++ b/Mathlib/Condensed/Discrete/LocallyConstant.lean @@ -190,9 +190,7 @@ noncomputable def componentHom (a : Fiber (f.comap g.hom.hom)) : simp only [Fiber.mk, Set.mem_preimage, Set.mem_singleton_iff] convert! map_eq_image _ _ x exact map_preimage_eq_image_map _ _ a⟩ - continuous_toFun := by - -- term mode gives "unknown free variable" error. - exact Continuous.subtype_mk (by fun_prop) _ } + continuous_toFun := by fun_prop } lemma incl_comap {S T : (CompHausLike P)ᵒᵖ} (f : LocallyConstant S.unop (Y.obj (op (CompHausLike.of P PUnit.{u + 1})))) diff --git a/Mathlib/Condensed/Light/Sequence.lean b/Mathlib/Condensed/Light/Sequence.lean index 3b9d812f0b7599..406aff7aa5097c 100644 --- a/Mathlib/Condensed/Light/Sequence.lean +++ b/Mathlib/Condensed/Light/Sequence.lean @@ -290,7 +290,7 @@ lemma aux {S T : LightProfinite} (π : T ⟶ S ⊗ ℕ∪{∞}) [Epi π] : rwa [← LightProfinite.epi_iff_surjective] · simp [π', pullback.condition] · exact ⟨ConcreteCategory.ofHom ⟨(sectionOfFibreIncl π' σ' hσ'), - (.subtype_mk (.subtype_mk (by fun_prop) _) _)⟩, rfl⟩ + (.subtype_mk (by fun_prop) _)⟩, rfl⟩ · rw [LightProfinite.epi_iff_surjective] exact coverToFun_surjective _ _ hσ hσ' diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index 9a3f69f3e301b5..274477f4af5eb1 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -576,7 +576,7 @@ if and only if the set is measurable in `Set.range f`. -/ theorem measurableSet_preimage_iff_preimage_val {f : X → Z} [CountablySeparated (range f)] (hf : Measurable f) {s : Set Z} : MeasurableSet (f ⁻¹' s) ↔ MeasurableSet ((↑) ⁻¹' s : Set (range f)) := - have hf' : Measurable (rangeFactorization f) := hf.subtype_mk + have hf' : Measurable (rangeFactorization f) := by fun_prop hf'.measurableSet_preimage_iff_of_surjective (s := Subtype.val ⁻¹' s) rangeFactorization_surjective diff --git a/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean b/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean index cadcb50ba1bb02..00364325dd72b8 100644 --- a/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean +++ b/Mathlib/MeasureTheory/Function/SpecialFunctions/Basic.lean @@ -109,13 +109,8 @@ theorem measurable_cosh : Measurable cosh := continuous_cosh.measurable theorem measurable_arg : Measurable arg := - have A : Measurable fun x : ℂ => Real.arcsin (x.im / ‖x‖) := - Real.measurable_arcsin.comp (measurable_im.div measurable_norm) - have B : Measurable fun x : ℂ => Real.arcsin ((-x).im / ‖x‖) := - Real.measurable_arcsin.comp ((measurable_im.comp measurable_neg).div measurable_norm) - Measurable.ite (isClosed_le continuous_const continuous_re).measurableSet A <| - Measurable.ite (isClosed_le continuous_const continuous_im).measurableSet (B.add_const _) - (B.sub_const _) + Measurable.ite (by measurability) (by fun_prop) <| + Measurable.ite (by measurability) (by fun_prop) (by fun_prop) theorem measurable_log : Measurable log := (measurable_ofReal.comp <| Real.measurable_log.comp measurable_norm).add <| @@ -269,37 +264,28 @@ end ComplexComposition @[fun_prop] protected theorem Measurable.complex_ofReal {α : Type*} {m : MeasurableSpace α} {f : α → ℝ} (hf : Measurable f) : - Measurable fun x ↦ (f x : ℂ) := - Complex.measurable_ofReal.comp hf + Measurable fun x ↦ (f x : ℂ) := by fun_prop @[fun_prop] protected theorem AEMeasurable.complex_ofReal {α : Type*} {m : MeasurableSpace α} {μ : Measure α} {f : α → ℝ} (hf : AEMeasurable f μ) : - AEMeasurable (fun x ↦ (f x : ℂ)) μ := - Complex.measurable_ofReal.comp_aemeasurable hf + AEMeasurable (fun x ↦ (f x : ℂ)) μ := by + fun_prop section PowInstances instance Complex.hasMeasurablePow : MeasurablePow ℂ ℂ := - ⟨Measurable.ite (measurable_fst (measurableSet_singleton 0)) - (Measurable.ite (measurable_snd (measurableSet_singleton 0)) measurable_one measurable_zero) - (measurable_fst.clog.mul measurable_snd).cexp⟩ + ⟨Measurable.ite (by measurability) + (Measurable.ite (by measurability) measurable_one measurable_zero) (by fun_prop)⟩ -instance Real.hasMeasurablePow : MeasurablePow ℝ ℝ := - ⟨Complex.measurable_re.comp <| - (Complex.measurable_ofReal.comp measurable_fst).pow - (Complex.measurable_ofReal.comp measurable_snd)⟩ +instance Real.hasMeasurablePow : MeasurablePow ℝ ℝ := ⟨Complex.measurable_re.comp <| by fun_prop⟩ -instance NNReal.hasMeasurablePow : MeasurablePow ℝ≥0 ℝ := - ⟨(measurable_fst.coe_nnreal_real.pow measurable_snd).subtype_mk⟩ +instance NNReal.hasMeasurablePow : MeasurablePow ℝ≥0 ℝ := ⟨Measurable.subtype_mk (by fun_prop)⟩ instance ENNReal.hasMeasurablePow : MeasurablePow ℝ≥0∞ ℝ := by refine ⟨ENNReal.measurable_of_measurable_nnreal_prod ?_ ?_⟩ · simp_rw [ENNReal.coe_rpow_def] - refine Measurable.ite ?_ measurable_const (measurable_fst.pow measurable_snd).coe_nnreal_ennreal - exact - MeasurableSet.inter (measurable_fst (measurableSet_singleton 0)) - (measurable_snd measurableSet_Iio) + exact Measurable.ite (by measurability) measurable_const (by fun_prop) · simp_rw [ENNReal.top_rpow_def] refine Measurable.ite measurableSet_Ioi measurable_const ?_ exact Measurable.ite (measurableSet_singleton 0) measurable_const measurable_const From 3b3cdbb692938d509d6fb29fc5e50638985aecf1 Mon Sep 17 00:00:00 2001 From: Rao Xiaojia <7247037+raoxiaojia@users.noreply.github.com> Date: Thu, 30 Jul 2026 16:24:28 +0000 Subject: [PATCH 1091/1300] feat(LinearAlgebra/Matrix): add definitions and theory for the echelon form and pivots of matrices (#42236) We add definitions for the row echelon form and pivots of matrices. We also add some more API about matrix ranks and add abbreviations for upper/lower-triangular matrices based on the current block triangular definition. Co-authored-by: raoxiaojia --- Mathlib.lean | 2 + .../InnerProductSpace/GramSchmidtOrtho.lean | 10 +- Mathlib/LinearAlgebra/Matrix/Block.lean | 27 ++- .../LinearAlgebra/Matrix/Charpoly/Basic.lean | 7 +- .../Matrix/Determinant/Basic.lean | 4 +- .../LinearAlgebra/Matrix/Echelon/Basic.lean | 103 ++++++++++ .../LinearAlgebra/Matrix/Echelon/Pivot.lean | 182 ++++++++++++++++++ .../LinearAlgebra/Matrix/Nondegenerate.lean | 10 + Mathlib/LinearAlgebra/Matrix/Rank.lean | 94 +++++++-- Mathlib/RingTheory/Polynomial/DegreeLT.lean | 2 +- 10 files changed, 416 insertions(+), 25 deletions(-) create mode 100644 Mathlib/LinearAlgebra/Matrix/Echelon/Basic.lean create mode 100644 Mathlib/LinearAlgebra/Matrix/Echelon/Pivot.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3afd48340dc9f5..58520b10d348ad 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5135,6 +5135,8 @@ public import Mathlib.LinearAlgebra.Matrix.Diagonal public import Mathlib.LinearAlgebra.Matrix.DotProduct public import Mathlib.LinearAlgebra.Matrix.Dual public import Mathlib.LinearAlgebra.Matrix.DualNumber +public import Mathlib.LinearAlgebra.Matrix.Echelon.Basic +public import Mathlib.LinearAlgebra.Matrix.Echelon.Pivot public import Mathlib.LinearAlgebra.Matrix.FiniteDimensional public import Mathlib.LinearAlgebra.Matrix.FixedDetMatrices public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Basic diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 829ac9dff79616..7a3f5b97335cf7 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -364,14 +364,18 @@ theorem gramSchmidtOrthonormalBasis_inv_triangular' {i j : ι} (hij : i < j) : /-- Given an indexed family `f : ι → E` of vectors in an inner product space `E`, for which the size of the index set is the dimension of `E`, the matrix of coefficients of `f` with respect to the orthonormal basis `gramSchmidtOrthonormalBasis` constructed from `f` is upper-triangular. -/ -theorem gramSchmidtOrthonormalBasis_inv_blockTriangular : - ((gramSchmidtOrthonormalBasis h f).toBasis.toMatrix f).BlockTriangular id := fun _ _ => +theorem gramSchmidtOrthonormalBasis_inv_isUpperTriangular : + ((gramSchmidtOrthonormalBasis h f).toBasis.toMatrix f).IsUpperTriangular := fun _ _ => gramSchmidtOrthonormalBasis_inv_triangular' h f +@[deprecated (since := "2026-07-30")] +alias gramSchmidtOrthonormalBasis_inv_blockTriangular := + gramSchmidtOrthonormalBasis_inv_isUpperTriangular + theorem gramSchmidtOrthonormalBasis_det [DecidableEq ι] : (gramSchmidtOrthonormalBasis h f).toBasis.det f = ∏ i, ⟪gramSchmidtOrthonormalBasis h f i, f i⟫ := by - convert! Matrix.det_of_upperTriangular (gramSchmidtOrthonormalBasis_inv_blockTriangular h f) + convert! Matrix.det_of_isUpperTriangular (gramSchmidtOrthonormalBasis_inv_isUpperTriangular h f) exact ((gramSchmidtOrthonormalBasis h f).repr_apply_apply (f _) _).symm end OrthonormalBasis diff --git a/Mathlib/LinearAlgebra/Matrix/Block.lean b/Mathlib/LinearAlgebra/Matrix/Block.lean index b5c4fdb43f8c23..cf57df9e3131b2 100644 --- a/Mathlib/LinearAlgebra/Matrix/Block.lean +++ b/Mathlib/LinearAlgebra/Matrix/Block.lean @@ -25,7 +25,7 @@ matrices built out of blocks. * `Matrix.det_of_blockTriangular`: the determinant of a block triangular matrix is equal to the product of the determinants of all the blocks -* `Matrix.det_of_upperTriangular` and `Matrix.det_of_lowerTriangular`: the determinant of +* `Matrix.det_of_isUpperTriangular` and `Matrix.det_of_isLowerTriangular`: the determinant of a triangular matrix is the product of the entries along the diagonal ## Tags @@ -61,6 +61,14 @@ variable [Zero R] def BlockTriangular (M : Matrix m m R) (b : m → α) : Prop := ∀ ⦃i j⦄, b j < b i → M i j = 0 +/-- `M` is upper triangular: entries below the diagonal vanish. -/ +abbrev IsUpperTriangular [LT m] (M : Matrix m m R) : Prop := + M.BlockTriangular id + +/-- `M` is lower triangular: entries above the diagonal vanish. -/ +abbrev IsLowerTriangular [LT m] (M : Matrix m m R) : Prop := + M.BlockTriangular toDual + @[simp] protected theorem BlockTriangular.submatrix {f : n → m} (h : M.BlockTriangular b) : (M.submatrix f f).BlockTriangular (b ∘ f) := fun _ _ hij => h hij @@ -85,6 +93,11 @@ protected theorem blockTriangular_transpose_iff {b : m → αᵒᵈ} : @[simp] theorem blockTriangular_zero : BlockTriangular (0 : Matrix m m R) b := fun _ _ _ => rfl +instance decidableBlockTriangular [DecidableEq R] [Fintype m] [DecidableLT α] : + Decidable (M.BlockTriangular b) := + decidable_of_iff (∀ ij : m × m, b ij.2 < b ij.1 → M ij.1 ij.2 = 0) + ⟨fun h i j hij => h (i, j) hij, fun h _ hij => h hij⟩ + end Zero protected theorem BlockTriangular.neg [NegZeroClass R] {M : Matrix m m R} @@ -321,15 +334,19 @@ theorem BlockTriangular.det_fintype [DecidableEq α] [Fintype α] [LinearOrder have : IsEmpty { i // b i = a } := ⟨fun i => ha <| mem_image.2 ⟨i, mem_univ _, i.2⟩⟩ exact det_isEmpty -theorem det_of_upperTriangular [LinearOrder m] (h : M.BlockTriangular id) : +theorem det_of_isUpperTriangular [LinearOrder m] (h : M.IsUpperTriangular) : M.det = ∏ i : m, M i i := by have : DecidableEq R := Classical.decEq _ simp_rw [h.det, image_id, det_toSquareBlock_id] -theorem det_of_lowerTriangular [LinearOrder m] (M : Matrix m m R) (h : M.BlockTriangular toDual) : +@[deprecated (since := "2026-07-30")] alias det_of_upperTriangular := det_of_isUpperTriangular + +theorem det_of_isLowerTriangular [LinearOrder m] (M : Matrix m m R) (h : M.IsLowerTriangular) : M.det = ∏ i : m, M i i := by rw [← det_transpose] - exact det_of_upperTriangular h.transpose + exact det_of_isUpperTriangular h.transpose + +@[deprecated (since := "2026-07-30")] alias det_of_lowerTriangular := det_of_isLowerTriangular open Polynomial @@ -342,7 +359,7 @@ theorem matrixOfPolynomials_blockTriangular {R} [Semiring R] {n : ℕ} (p : Fin theorem det_matrixOfPolynomials {n : ℕ} (p : Fin n → R[X]) (h_deg : ∀ i, (p i).natDegree = i) (h_monic : ∀ i, Monic <| p i) : (Matrix.of (fun (i j : Fin n) => (p j).coeff i)).det = 1 := by - rw [Matrix.det_of_upperTriangular (Matrix.matrixOfPolynomials_blockTriangular p (fun i ↦ + rw [Matrix.det_of_isUpperTriangular (Matrix.matrixOfPolynomials_blockTriangular p (fun i ↦ Nat.le_of_eq (h_deg i)))] convert! prod_const_one with x _ rw [Matrix.of_apply, ← h_deg, coeff_natDegree, (h_monic x).leadingCoeff] diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean index c65cd9f4530b4e..24a8db834ce856 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean @@ -196,9 +196,12 @@ lemma BlockTriangular.charpoly {α : Type*} {b : n → α} [LinearOrder α] (h : M.charpoly = ∏ a ∈ image b univ, (M.toSquareBlock b a).charpoly := by simp only [Matrix.charpoly, h.charmatrix.det, charmatrix_toSquareBlock] -lemma charpoly_of_upperTriangular [LinearOrder n] (M : Matrix n n R) (h : M.BlockTriangular id) : +lemma charpoly_of_isUpperTriangular [LinearOrder n] (M : Matrix n n R) (h : M.IsUpperTriangular) : M.charpoly = ∏ i : n, (X - C (M i i)) := by - simp [charpoly, det_of_upperTriangular h.charmatrix] + simp [charpoly, det_of_isUpperTriangular h.charmatrix] + +@[deprecated (since := "2026-07-30")] +alias charpoly_of_upperTriangular := charpoly_of_isUpperTriangular -- This proof follows http://drorbn.net/AcademicPensieve/2015-12/CayleyHamilton.pdf /-- The **Cayley-Hamilton Theorem**, that the characteristic polynomial of a matrix, diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean index 7a1cfad31cccbe..9f47c32c8ab7db 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean @@ -670,7 +670,7 @@ theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Mat set_option backward.isDefEq.respectTransparency false in /-- The determinant of a 2×2 block matrix with the lower-left block equal to zero is the product of the determinants of the diagonal blocks. For the generalization to any number of blocks, see -`Matrix.det_of_upperTriangular`. -/ +`Matrix.det_of_isUpperTriangular`. -/ @[simp] theorem det_fromBlocks_zero₂₁ (A : Matrix m m R) (B : Matrix m n R) (D : Matrix n n R) : (Matrix.fromBlocks A B 0 D).det = A.det * D.det := by @@ -721,7 +721,7 @@ theorem det_fromBlocks_zero₂₁ (A : Matrix m m R) (B : Matrix m n R) (D : Mat /-- The determinant of a 2×2 block matrix with the upper-right block equal to zero is the product of the determinants of the diagonal blocks. For the generalization to any number of blocks, see -`Matrix.det_of_lowerTriangular`. -/ +`Matrix.det_of_isLowerTriangular`. -/ @[simp] theorem det_fromBlocks_zero₁₂ (A : Matrix m m R) (C : Matrix n m R) (D : Matrix n n R) : (Matrix.fromBlocks A 0 C D).det = A.det * D.det := by diff --git a/Mathlib/LinearAlgebra/Matrix/Echelon/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Echelon/Basic.lean new file mode 100644 index 00000000000000..ab540d7bd3f937 --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Echelon/Basic.lean @@ -0,0 +1,103 @@ +/- +Copyright (c) 2026 Rao Xiaojia. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rao Xiaojia +-/ +module + +public import Mathlib.Data.Fintype.Defs +public import Mathlib.LinearAlgebra.Matrix.Defs +public import Mathlib.Order.Defs.LinearOrder +public import Mathlib.Order.RelClasses + +import Mathlib.Order.WellFounded + + +/-! +# Row echelon forms + +This file defines the row echelon form of matrices and the leading entries of their rows. + +## Main definitions + +- `Matrix.IsRowEchelon` expresses that `A` is in row echelon form: an entry of a lower row + vanishes whenever a higher row is zero at every column strictly to its left. +- `Matrix.IsLeadingEntry`: `c : n` is the leading position of row `i` of `A`. +- `Matrix.IsReducedRowEchelon` additionally requires each leading entry to be `1` and the + entries above it to vanish. + +## Tags + +matrix, echelon form + +-/ + +@[expose] public section + +universe v + +variable {m n : Type*} +variable {R : Type v} {A : Matrix m n R} + +namespace Matrix + +variable [Zero R] + +/-- `A` is in row echelon form: for rows `i₁ < i₂`, if the higher row `i₁` is zero at every +column strictly left of `j₂`, then the lower row `i₂` is zero at `j₂`. -/ +def IsRowEchelon [LT m] [LT n] (A : Matrix m n R) : Prop := + ∀ ⦃i₁ i₂⦄, i₁ < i₂ → ∀ ⦃j₂⦄, (∀ j₁ < j₂, A i₁ j₁ = 0) → A i₂ j₂ = 0 + +/-- In an echelon matrix, rows below a zero row are zero. -/ +theorem IsRowEchelon.row_eq_zero_of_lt [LT m] [LT n] {i₁ i₂ : m} (he : A.IsRowEchelon) + (hlt : i₁ < i₂) (h0 : A i₁ = 0) : A i₂ = 0 := by + funext j + exact he hlt fun j₁ _ => congrFun h0 j₁ + +/-! ### Leading entries -/ + +/-- `c` is the leading position of row `i`. -/ +def IsLeadingEntry [LT n] (A : Matrix m n R) (i : m) (c : n) : Prop := + (∀ j < c, A i j = 0) ∧ A i c ≠ 0 + +theorem IsLeadingEntry.row_ne_zero [LT n] {i : m} {c : n} (hc : A.IsLeadingEntry i c) : + A i ≠ 0 := + fun contra => hc.2 (congrFun contra c) + +theorem row_ne_zero_iff_exists_isLeadingEntry [LT n] [WellFoundedLT n] {i : m} : + A i ≠ 0 ↔ ∃ c, A.IsLeadingEntry i c := by + refine ⟨fun h => ?_, fun ⟨c, hc⟩ => hc.row_ne_zero⟩ + obtain ⟨c, hc, hmin⟩ := wellFounded_lt.has_min {j | A i j ≠ 0} <| Function.ne_iff.mp h + refine ⟨c, ?_, hc⟩ + by_contra + aesop + +/-- If column indices have a linear order, then there's at most one leading position per row. -/ +theorem IsLeadingEntry.unique [LinearOrder n] {i : m} {c₁ c₂ : n} + (h₁ : A.IsLeadingEntry i c₁) (h₂ : A.IsLeadingEntry i c₂) : c₁ = c₂ := + le_antisymm (not_lt.mp fun hlt => h₂.2 (h₁.1 c₂ hlt)) (not_lt.mp fun hlt => h₁.2 (h₂.1 c₁ hlt)) + +instance [DecidableEq R] [Fintype n] [LT n] [DecidableLT n] + (A : Matrix m n R) (i : m) (c : n) : Decidable (A.IsLeadingEntry i c) := + decidable_of_iff ((∀ j < c, A i j = 0) ∧ A i c ≠ 0) Iff.rfl + +/-! ### Reduced row echelon form -/ + +/-- `A` is in reduced row echelon form: it is in row echelon form, each leading entry is +`1`, and entries above a leading entry vanish (entries below one vanish by +`isRowEchelon`). -/ +structure IsReducedRowEchelon [LT m] [LT n] [One R] (A : Matrix m n R) : Prop where + isRowEchelon : A.IsRowEchelon + eq_one ⦃i : m⦄ ⦃c : n⦄ (hA : A.IsLeadingEntry i c) : A i c = 1 + eq_zero ⦃i₁ i₂ : m⦄ ⦃c : n⦄ (hlt : i₁ < i₂) (hA : A.IsLeadingEntry i₂ c) : A i₁ c = 0 + +/-- If the row indices have a linear order, then every entry in a pivot column vanishes +except for the pivot. -/ +theorem IsReducedRowEchelon.eq_zero_of_ne_of_isLeadingEntry [LinearOrder m] [LT n] [One R] + {i₁ i₂ : m} {c : n} (hA : A.IsReducedRowEchelon) (hne : i₁ ≠ i₂) + (hlead : A.IsLeadingEntry i₂ c) : A i₁ c = 0 := by + rcases hne.lt_or_gt with hlt | hlt + · exact hA.eq_zero hlt hlead + · exact hA.isRowEchelon hlt hlead.1 + +end Matrix diff --git a/Mathlib/LinearAlgebra/Matrix/Echelon/Pivot.lean b/Mathlib/LinearAlgebra/Matrix/Echelon/Pivot.lean new file mode 100644 index 00000000000000..2224c13b7ffb0a --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Echelon/Pivot.lean @@ -0,0 +1,182 @@ +/- +Copyright (c) 2026 Rao Xiaojia. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rao Xiaojia +-/ +module + +public import Mathlib.LinearAlgebra.Matrix.Echelon.Basic +public import Mathlib.LinearAlgebra.Matrix.Rank +public import Mathlib.Order.WithBot + +/-! +# Pivots of a matrix + +`Matrix.IsPivotedBy A l` defines a map-based representation `l` for the pivot, stating that +`l i` is the pivot column of each row `i` of `A`, with `⊤` for a zero row. + +## Main definitions + +- `Matrix.IsPivotedBy`: `l i : WithTop n` is the pivot column of each row `i` of `A`. + +## Main results + +- `Matrix.IsPivotedBy.rank_eq`: the rank of a matrix is its number of pivots. +- `Matrix.IsPivotedBy.unique`: the pivot of a matrix is unique if the column indices have a + linear order. +- `Matrix.isPivotedBy_iff`: the map-structural characterisation of pivots. + +## Tags + +matrix, echelon form, pivot +-/ + +@[expose] public section + +namespace Matrix + +open Finset + +variable {m n : Type*} {R : Type*} + +section Zero + +variable [Zero R] {A : Matrix m n R} {l : m → WithTop n} + +/-- `A` is in row echelon form and `l i` is the leading position of each row `i`, +with `⊤` for a zero row. -/ +structure IsPivotedBy [LT m] [LT n] (A : Matrix m n R) (l : m → WithTop n) : Prop where + isRowEchelon : A.IsRowEchelon + isPivotEntry (i : m) : + (∀ j : n, (j : WithTop n) < l i → A i j = 0) ∧ ∀ c : n, l i = c → A i c ≠ 0 + +namespace IsPivotedBy + +theorem isLeadingEntry [LT m] [LT n] {i : m} {c : n} (hA : A.IsPivotedBy l) (hc : l i = c) : + A.IsLeadingEntry i c := by + refine ⟨fun j hj => (hA.isPivotEntry i).1 j ?_, (hA.isPivotEntry i).2 c hc⟩ + rw [hc] + exact_mod_cast hj + +theorem eq_top_iff [LT m] [LT n] {i : m} (hA : A.IsPivotedBy l) : + l i = ⊤ ↔ A i = 0 := by + cases hc : l i with + | top => + have h := (hA.isPivotEntry i).1 + rw [hc] at h + simpa [funext_iff] using fun j => h j (WithTop.coe_lt_top j) + | coe c => simpa using fun h0 => (hA.isPivotEntry i).2 c hc (congrFun h0 c) + +variable [LinearOrder n] + +theorem lt_of_lt_of_ne_top [LT m] {i₁ i₂ : m} + (hA : A.IsPivotedBy l) (hlt : i₁ < i₂) (h₁ : l i₁ ≠ ⊤) : l i₁ < l i₂ := by + by_contra! hle + obtain ⟨c₂, hc₂⟩ := WithTop.ne_top_iff_exists.mp (hle.trans_lt h₁.lt_top).ne + refine (hA.isPivotEntry i₂).2 c₂ hc₂.symm (hA.isRowEchelon hlt fun j₁ hj₁ => ?_) + exact (hA.isPivotEntry i₁).1 j₁ ((WithTop.coe_lt_coe.mpr hj₁).trans_le (hc₂.le.trans hle)) + +/-- The pivots of a matrix are unique. -/ +theorem unique [LT m] {l' : m → WithTop n} + (hl : A.IsPivotedBy l) (hl' : A.IsPivotedBy l') : l = l' := by + funext i + cases hc' : l' i with + | top => + rw [hl.eq_top_iff, ← hl'.eq_top_iff] + exact hc' + | coe c' => + cases hc : l i with + | top => + rw [hl.eq_top_iff] at hc + exact absurd (congrFun hc c') (hl'.isLeadingEntry hc').2 + | coe c => exact_mod_cast (hl.isLeadingEntry hc).unique (hl'.isLeadingEntry hc') + +theorem strictMonoOn [Preorder m] (hA : A.IsPivotedBy l) : + StrictMonoOn l {i | l i ≠ ⊤} := + fun _ h₁ _ _ hlt => hA.lt_of_lt_of_ne_top hlt h₁ + +variable [PartialOrder m] + +theorem monotone (hA : A.IsPivotedBy l) : + Monotone l := by + refine monotone_iff_forall_lt.mpr ?_ + intro i₁ i₂ hlt + by_cases h₁ : l i₁ = ⊤ + · simp [hA.eq_top_iff.mpr (hA.isRowEchelon.row_eq_zero_of_lt hlt (hA.eq_top_iff.mp h₁))] + · exact (hA.lt_of_lt_of_ne_top hlt h₁).le + +end IsPivotedBy + +/-- The map-structural characterisation of pivots. This is useful for proving that +a matrix is in row echelon form. -/ +theorem isPivotedBy_iff [PartialOrder m] [LinearOrder n] : + A.IsPivotedBy l ↔ + Monotone l ∧ StrictMonoOn l {i | l i ≠ ⊤} ∧ ∀ i : m, + (∀ j : n, (j : WithTop n) < l i → A i j = 0) ∧ ∀ c : n, l i = c → A i c ≠ 0 := by + refine ⟨fun hA => ⟨hA.monotone, hA.strictMonoOn, hA.isPivotEntry⟩, ?_⟩ + refine fun ⟨hmono, hstrict, hlead⟩ ↦ ⟨fun i₁ i₂ hlt j₂ hz ↦ (hlead i₂).1 j₂ ?_, hlead⟩ + rcases eq_or_ne (l i₂) ⊤ with h₂ | h₂ + · rw [h₂] + exact WithTop.coe_lt_top j₂ + · have h₁ : l i₁ ≠ ⊤ := fun ht => h₂ (top_le_iff.mp (ht.symm.le.trans (hmono hlt.le))) + obtain ⟨c₁, hc₁⟩ := WithTop.ne_top_iff_exists.mp h₁ + have hj : (j₂ : WithTop n) ≤ c₁ := + WithTop.coe_le_coe.mpr <| le_of_not_gt fun hgt => (hlead i₁).2 c₁ hc₁.symm (hz c₁ hgt) + exact lt_of_le_of_lt (hj.trans hc₁.le) (hstrict h₁ h₂ hlt) + +/-- A variant of `isPivotedBy_iff` phrased with `Matrix.IsLeadingEntry`. -/ +theorem isPivotedBy_iff' [PartialOrder m] [LinearOrder n] : + A.IsPivotedBy l ↔ + Monotone l ∧ StrictMonoOn l {i | l i ≠ ⊤} ∧ + ∀ i : m, (l i = ⊤ ∧ A i = 0) ∨ (∃ c : n, l i = c ∧ A.IsLeadingEntry i c) := by + rw [isPivotedBy_iff] + refine and_congr_right' <| and_congr_right' <| forall_congr' fun i => ?_ + cases l i <;> simp [IsLeadingEntry, funext_iff] + +end Zero + +section Rank + +variable [Fintype m] [Fintype n] [LinearOrder m] [LinearOrder n] [CommRing R] [IsDomain R] + {A : Matrix m n R} {l : m → WithTop n} + +namespace IsPivotedBy + +theorem rank_eq (hA : A.IsPivotedBy l) : A.rank = #{i | l i ≠ ⊤} := by + refine le_antisymm (A.rank_le_card_of_support_subset _ + (Function.support_subset_iff'.mpr fun i hi => hA.eq_top_iff.mp (by aesop))) ?_ + let g : {i // l i ≠ ⊤} → n := fun i => (l i.1).untop i.2 + have hlead : ∀ i : {i // l i ≠ ⊤}, A.IsLeadingEntry i.1 (g i) := fun i => + hA.isLeadingEntry (WithTop.coe_untop (l i.1) i.2).symm + have htri : (A.submatrix Subtype.val g).IsUpperTriangular := by + intro i j hij + exact (hlead i).1 _ ((WithTop.untop_lt_untop_iff _ _).mpr (hA.strictMonoOn j.2 i.2 hij)) + have hdet : (A.submatrix Subtype.val g).det ≠ 0 := by + rw [det_of_isUpperTriangular htri] + exact prod_ne_zero_iff.mpr fun i _ => (hlead i).2 + calc #{i | l i ≠ ⊤} + = (A.submatrix Subtype.val g).rank := by + rw [rank_of_det_ne_zero hdet, Fintype.card_subtype] + _ ≤ A.rank := rank_submatrix_le A Subtype.val g + +end IsPivotedBy + +end Rank + +/-! ## Decidability -/ + +section Decidability + +variable [Zero R] [DecidableEq R] + +instance [Fintype m] [LinearOrder m] [Fintype n] [LinearOrder n] + (A : Matrix m n R) (l : m → WithTop n) : Decidable (A.IsPivotedBy l) := + -- instance resolution cannot nest `Fintype.decidableForallFintype` under another binder + have : DecidablePred fun i : m => + (∀ j : n, (j : WithTop n) < l i → A i j = 0) ∧ ∀ c : n, l i = c → A i c ≠ 0 := + fun _ => inferInstance + decidable_of_iff' _ isPivotedBy_iff + +end Decidability + +end Matrix diff --git a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean index 14a74a2c31d76e..c5e738e779ccc1 100644 --- a/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean +++ b/Mathlib/LinearAlgebra/Matrix/Nondegenerate.lean @@ -181,6 +181,16 @@ theorem eq_zero_of_mulVec_eq_zero [NoZeroDivisors R] (hM : M.det ≠ 0) {v : m (hv : M *ᵥ v = 0) : v = 0 := nondegenerate_of_det_ne_zero hM |>.separatingRight.eq_zero_of_mulVec_eq_zero hv +/-- See also `Matrix.mulVec_injective_iff_isUnit` when working over a field. -/ +theorem mulVec_injective_of_det_mem_nonZeroDivisors (hM : M.det ∈ R⁰) : + Function.Injective M.mulVec := + fun _ _ hxy => sub_eq_zero.mp + (eq_zero_of_det_mem_nonZeroDivisors_of_mulVec_eq_zero hM (by rw [mulVec_sub, hxy, sub_self])) + +theorem mulVec_injective_of_det_ne_zero [NoZeroDivisors R] (hM : M.det ≠ 0) : + Function.Injective M.mulVec := + mulVec_injective_of_det_mem_nonZeroDivisors (mem_nonZeroDivisors_of_ne_zero hM) + end Determinant end Matrix diff --git a/Mathlib/LinearAlgebra/Matrix/Rank.lean b/Mathlib/LinearAlgebra/Matrix/Rank.lean index e3213bfcf6fe1c..a3385c40b95566 100644 --- a/Mathlib/LinearAlgebra/Matrix/Rank.lean +++ b/Mathlib/LinearAlgebra/Matrix/Rank.lean @@ -9,6 +9,7 @@ public import Mathlib.LinearAlgebra.Determinant public import Mathlib.LinearAlgebra.Dimension.OrzechProperty public import Mathlib.LinearAlgebra.Dual.Lemmas public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas +public import Mathlib.LinearAlgebra.Matrix.Block public import Mathlib.LinearAlgebra.Matrix.Diagonal public import Mathlib.LinearAlgebra.Matrix.DotProduct public import Mathlib.LinearAlgebra.Matrix.Dual @@ -213,25 +214,75 @@ theorem rank_of_isUnit [DecidableEq n] [CommSemiring R] [StrongRankCondition R] obtain ⟨A, rfl⟩ := h exact rank_unit A +theorem rank_of_det_mem_nonZeroDivisors {R : Type*} [CommRing R] [Nontrivial R] + [Fintype m] [DecidableEq m] {A : Matrix m m R} (hA : A.det ∈ nonZeroDivisors R) : + A.rank = Fintype.card m := by + rw [rank, LinearMap.finrank_range_of_inj (mulVec_injective_of_det_mem_nonZeroDivisors hA), + Module.finrank_eq_card_basis (Pi.basisFun R m)] + +theorem rank_of_det_ne_zero {R : Type*} [CommRing R] [IsDomain R] [Fintype m] [DecidableEq m] + {A : Matrix m m R} (h : A.det ≠ 0) : A.rank = Fintype.card m := + rank_of_det_mem_nonZeroDivisors (mem_nonZeroDivisors_of_ne_zero h) + +lemma rank_smul_of_mem_nonZeroDivisors {R : Type*} [CommRing R] {c : R} (B : Matrix m n R) + (hc : c ∈ nonZeroDivisors R) : (c • B).rank = B.rank := by + have hc' : IsSMulRegular R c := isSMulRegular_iff_mem_nonZeroSMulDivisors.mpr hc.1 + have hreg : IsSMulRegular (m → R) c := IsSMulRegular.pi fun _ => hc' + let f := LinearMap.lsmul R (m → R) c + have hcomp : (c • B).mulVecLin = f.comp B.mulVecLin := by aesop + rw [rank, rank, hcomp, LinearMap.range_comp] + exact (Submodule.equivMapOfInjective f hreg _).finrank_eq.symm + +lemma rank_mul_eq_left_of_det_mem_nonZeroDivisors {R : Type*} [CommRing R] [DecidableEq n] + (A : Matrix n n R) (B : Matrix m n R) (hA : A.det ∈ nonZeroDivisors R) : + (B * A).rank = B.rank := by + nontriviality R + refine le_antisymm (rank_mul_le_left B A) ?_ + have key : (B * A) * A.adjugate = A.det • B := by + rw [Matrix.mul_assoc, Matrix.mul_adjugate, Matrix.mul_smul, Matrix.mul_one] + calc B.rank = (A.det • B).rank := (rank_smul_of_mem_nonZeroDivisors B hA).symm + _ = ((B * A) * A.adjugate).rank := by rw [key] + _ ≤ (B * A).rank := rank_mul_le_left _ _ + +lemma rank_mul_eq_left_of_det_ne_zero {R : Type*} [CommRing R] [IsDomain R] [DecidableEq n] + (A : Matrix n n R) (B : Matrix m n R) (h : A.det ≠ 0) : (B * A).rank = B.rank := + rank_mul_eq_left_of_det_mem_nonZeroDivisors A B (mem_nonZeroDivisors_of_ne_zero h) + /-- Right multiplying by an invertible matrix does not change the rank -/ @[simp] lemma rank_mul_eq_left_of_isUnit_det {R : Type*} [CommRing R] [DecidableEq n] (A : Matrix n n R) - (B : Matrix m n R) (hA : IsUnit A.det) : (B * A).rank = B.rank := by - suffices Function.Surjective A.mulVecLin by - rw [rank, mulVecLin_mul, LinearMap.range_comp_of_range_eq_top _ - (LinearMap.range_eq_top.mpr this), ← rank] - intro v - exact ⟨(A⁻¹).mulVecLin v, by simp [mul_nonsing_inv _ hA]⟩ + (B : Matrix m n R) (hA : IsUnit A.det) : (B * A).rank = B.rank := + rank_mul_eq_left_of_det_mem_nonZeroDivisors A B hA.mem_nonZeroDivisors + +lemma rank_mul_eq_right_of_det_mem_nonZeroDivisors {R : Type*} [CommRing R] + [Fintype m] [DecidableEq m] (A : Matrix m m R) (B : Matrix m n R) + (hA : A.det ∈ nonZeroDivisors R) : (A * B).rank = B.rank := by + rw [rank, rank, mulVecLin_mul, LinearMap.range_comp, + ← (Submodule.equivMapOfInjective A.mulVecLin + (mulVec_injective_of_det_mem_nonZeroDivisors hA) _).finrank_eq] + +lemma rank_mul_eq_right_of_det_ne_zero {R : Type*} [CommRing R] [IsDomain R] + [Fintype m] [DecidableEq m] (A : Matrix m m R) (B : Matrix m n R) (h : A.det ≠ 0) : + (A * B).rank = B.rank := + rank_mul_eq_right_of_det_mem_nonZeroDivisors A B (mem_nonZeroDivisors_of_ne_zero h) /-- Left multiplying by an invertible matrix does not change the rank -/ @[simp] lemma rank_mul_eq_right_of_isUnit_det {R : Type*} [CommRing R] [Fintype m] [DecidableEq m] - (A : Matrix m m R) (B : Matrix m n R) (hA : IsUnit A.det) : (A * B).rank = B.rank := by - let b : Basis m R (m → R) := Pi.basisFun R m - replace hA : IsUnit (LinearMap.toMatrix b b A.mulVecLin).det := by - convert! hA; rw [← LinearEquiv.eq_symm_apply]; rfl - have hAB : mulVecLin (A * B) = (LinearEquiv.ofIsUnitDet hA).comp (mulVecLin B) := by ext; simp - rw [rank, rank, hAB, LinearMap.range_comp, LinearEquiv.finrank_map_eq] + (A : Matrix m m R) (B : Matrix m n R) (hA : IsUnit A.det) : (A * B).rank = B.rank := + rank_mul_eq_right_of_det_mem_nonZeroDivisors A B hA.mem_nonZeroDivisors + +lemma rank_mul_eq_right_of_isLowerTriangular {R : Type*} [CommRing R] [IsDomain R] + [Fintype m] [LinearOrder m] (A : Matrix m m R) (B : Matrix m n R) + (hA : A.IsLowerTriangular) (hd : ∀ i, A.diag i ≠ 0) : (A * B).rank = B.rank := by + have hdet : A.det ≠ 0 := by simpa [det_of_isLowerTriangular A hA, Finset.prod_ne_zero_iff] + exact rank_mul_eq_right_of_det_ne_zero A B hdet + +lemma rank_mul_eq_right_of_isUpperTriangular {R : Type*} [CommRing R] [IsDomain R] + [Fintype m] [LinearOrder m] (A : Matrix m m R) (B : Matrix m n R) + (hA : A.IsUpperTriangular) (hd : ∀ i, A.diag i ≠ 0) : (A * B).rank = B.rank := by + have hdet : A.det ≠ 0 := by simpa [det_of_isUpperTriangular hA, Finset.prod_ne_zero_iff] + exact rank_mul_eq_right_of_det_ne_zero A B hdet /-- Taking a subset of the rows and columns reduces the rank. -/ theorem rank_submatrix_le [CommSemiring R] [StrongRankCondition R] [Fintype n₀] (A : Matrix m n R) @@ -320,6 +371,25 @@ theorem rank_le_card_height [Fintype m] [CommSemiring R] [StrongRankCondition R] (A : Matrix m n R) : A.rank ≤ Fintype.card m := (Submodule.finrank_le _).trans (finrank_pi R).le +/-- The rank of a matrix is at most the size of any finset containing all its nonzero rows. -/ +theorem rank_le_card_of_support_subset [CommSemiring R] [StrongRankCondition R] (A : Matrix m n R) + (s : Finset m) (hz : Function.support A.row ⊆ s) : A.rank ≤ s.card := by + rw [Function.support_subset_iff'] at hz + classical + set B : Matrix m {x // x ∈ s} R := Matrix.of fun i a => if (a : m) = i then 1 else 0 with hBdef + have hB : B * A.submatrix Subtype.val id = A := by + ext i j + simp only [hBdef, mul_apply, of_apply, submatrix_apply, id_eq] + by_cases hi : i ∈ s + · rw [Fintype.sum_eq_single (⟨i, hi⟩ : {x // x ∈ s}) + fun a ha => by rw [if_neg fun he => ha (Subtype.ext he), zero_mul], if_pos rfl, one_mul] + · have h0 : A i = 0 := hz i hi + aesop + calc A.rank = (B * A.submatrix Subtype.val id).rank := by rw [hB] + _ ≤ (A.submatrix Subtype.val id).rank := rank_mul_le_right _ _ + _ ≤ Fintype.card {x // x ∈ s} := rank_le_card_height _ + _ = s.card := Fintype.card_coe s + theorem rank_le_height [CommSemiring R] [StrongRankCondition R] {m n : ℕ} (A : Matrix (Fin m) (Fin n) R) : A.rank ≤ m := A.rank_le_card_height.trans (Fintype.card_fin m).le diff --git a/Mathlib/RingTheory/Polynomial/DegreeLT.lean b/Mathlib/RingTheory/Polynomial/DegreeLT.lean index 6a74613781c1ef..c0d28c96fada0a 100644 --- a/Mathlib/RingTheory/Polynomial/DegreeLT.lean +++ b/Mathlib/RingTheory/Polynomial/DegreeLT.lean @@ -179,7 +179,7 @@ noncomputable def taylorLinearEquiv (r : R) (n : ℕ) : R[X]_n ≃ₗ[R] R[X]_n (taylorLinearEquiv r n).toLinearMap.det = 1 := by nontriviality R rw [← LinearMap.det_toMatrix (degreeLT.basis R n), - Matrix.det_of_upperTriangular, Fintype.prod_eq_one] + Matrix.det_of_isUpperTriangular, Fintype.prod_eq_one] · intro i rw [LinearMap.toMatrix_apply, degreeLT.basis_repr, ← natDegree_X_pow (R := R) (i : ℕ)] change (taylor r (degreeLT.basis R n i)).coeff _ = 1 From 190aaa2a4c0e9ff8391bea04ab1d70cb0cabc111 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Thu, 30 Jul 2026 17:51:45 +0000 Subject: [PATCH 1092/1300] doc(Algebra/Category/Grp): fix after renaming of categories (#42287) --- Mathlib/Algebra/Category/Grp/Basic.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Category/Grp/Basic.lean b/Mathlib/Algebra/Category/Grp/Basic.lean index 13e4f84c68f9e6..581eb7e9536795 100644 --- a/Mathlib/Algebra/Category/Grp/Basic.lean +++ b/Mathlib/Algebra/Category/Grp/Basic.lean @@ -259,7 +259,7 @@ attribute [instance] AddCommGrpCat.str CommGrpCat.str initialize_simps_projections AddCommGrpCat (carrier → coe, -str) initialize_simps_projections CommGrpCat (carrier → coe, -str) -/-- `Ab` is an abbreviation for `AddCommGroup`, for the sake of mathematicians' sanity. -/ +/-- `Ab` is an abbreviation for `AddCommGrpCat`, for the sake of mathematicians' sanity. -/ abbrev Ab := AddCommGrpCat namespace CommGrpCat @@ -471,7 +471,7 @@ end CommGrpCat namespace AddCommGrpCat --- Note that because `ℤ : Type 0`, this forces `G : AddCommGroup.{0}`, +-- Note that because `ℤ : Type 0`, this forces `G : AddCommGrpCat.{0}`, -- so we write this explicitly to be clear. -- TODO generalize this, requiring a `ULiftInstances.lean` file /-- Any element of an abelian group gives a unique morphism from `ℤ` sending @@ -504,7 +504,7 @@ def MulEquiv.toGrpIso {X Y : GrpCat} (e : X ≃* Y) : X ≅ Y where hom := GrpCat.ofHom e.toMonoidHom inv := GrpCat.ofHom e.symm.toMonoidHom -/-- Build an isomorphism in the category `AddGroup` from an `AddEquiv` between `AddGroup`s. -/ +/-- Build an isomorphism in the category `AddGrpCat` from an `AddEquiv` between `AddGroup`s. -/ add_decl_doc AddEquiv.toAddGrpIso /-- Build an isomorphism in the category `CommGrpCat` from a `MulEquiv` @@ -525,15 +525,15 @@ namespace CategoryTheory.Iso def groupIsoToMulEquiv {X Y : GrpCat} (i : X ≅ Y) : X ≃* Y := MonoidHom.toMulEquiv i.hom.hom i.inv.hom (by ext; simp) (by ext; simp) -/-- Build an `addEquiv` from an isomorphism in the category `AddGroup` -/ +/-- Build an `addEquiv` from an isomorphism in the category `AddGrpCat` -/ add_decl_doc addGroupIsoToAddEquiv -/-- Build a `MulEquiv` from an isomorphism in the category `CommGroup`. -/ +/-- Build a `MulEquiv` from an isomorphism in the category `CommGrpCat`. -/ @[to_additive (attr := simps!)] def commGroupIsoToMulEquiv {X Y : CommGrpCat} (i : X ≅ Y) : X ≃* Y := MonoidHom.toMulEquiv i.hom.hom i.inv.hom (by ext; simp) (by ext; simp) -/-- Build an `AddEquiv` from an isomorphism in the category `AddCommGroup`. -/ +/-- Build an `AddEquiv` from an isomorphism in the category `AddCommGrpCat`. -/ add_decl_doc addCommGroupIsoToAddEquiv end CategoryTheory.Iso From 2705f824bb8992af68a1f3e311fd0356d0eb15fb Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Thu, 30 Jul 2026 20:37:57 +0000 Subject: [PATCH 1093/1300] chore(Util/CountHeartbeats): deprecate the global `#count_heartbeats` command (#42274) This PR deprecates the global `#count_heartbeats` command. (Not to be confused with `#count_heartbeats in`, which we want to keep). The reason is that `#count_heartbeats` doesn't work in its current implementation. A useful alternative is to use `set_option trace.profiler true` with `set_option trace.profiler.useHeartbeats` true. As discussed in https://leanprover.zulipchat.com/#narrow/channel/263328-triage/topic/issue.20.214.2323905.3A.20linter.2EcountHeartbeats.20is.20broken/with/538006069 --- Mathlib/Util/CountHeartbeats.lean | 14 ++++++++++++-- MathlibTest/Util/CountHeartbeats.lean | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Mathlib/Util/CountHeartbeats.lean b/Mathlib/Util/CountHeartbeats.lean index 72c4fe8b668c19..22ca20328bc9a5 100644 --- a/Mathlib/Util/CountHeartbeats.lean +++ b/Mathlib/Util/CountHeartbeats.lean @@ -242,6 +242,8 @@ it looks inside `set_option ... in`, but not, for instance, inside `mutual` bloc There is a convenience notation `#count_heartbeats` that simply sets the linter option to true. -/ +@[deprecated "use `#count_heartbeats in` or `set_option trace.profiler true` with \ + `set_option trace.profiler.useHeartbeats true`" (since := "2026-07-30")] register_option linter.countHeartbeats : Bool := { defValue := false descr := "enable the countHeartbeats linter" @@ -251,6 +253,8 @@ register_option linter.countHeartbeats : Bool := { An option used by the `countHeartbeats` linter: if set to `true`, then the countHeartbeats linter rounds down to the nearest 1000 the heartbeat count. -/ +@[deprecated "use `#count_heartbeats in` or `set_option trace.profiler true` with \ + `set_option trace.profiler.useHeartbeats true`" (since := "2026-07-30")] register_option linter.countHeartbeatsApprox : Bool := { defValue := false descr := "if set to `true`, then the countHeartbeats linter rounds down \ @@ -259,7 +263,9 @@ register_option linter.countHeartbeatsApprox : Bool := { namespace CountHeartbeats -@[inherit_doc Mathlib.Linter.linter.countHeartbeats] +@[inherit_doc Mathlib.Linter.linter.countHeartbeats, +deprecated "use `#count_heartbeats in` or `set_option trace.profiler true` with \ + `set_option trace.profiler.useHeartbeats true`" (since := "2026-07-30")] def countHeartbeatsLinter : Linter where run := withSetOptionIn fun stx ↦ do unless getLinterValue linter.countHeartbeats (← getLinterOptions) do return @@ -280,10 +286,11 @@ def countHeartbeatsLinter : Linter where run := withSetOptionIn fun stx ↦ do | none => for msg in msgs do logInfoAt stx m!"{← msg.toString}" +set_option linter.deprecated false in initialize addLinter countHeartbeatsLinter @[inherit_doc Mathlib.Linter.linter.countHeartbeats] -macro "#count_heartbeats" approx:(&" approximately")? : command => do +macro (name := countHeartbeats) "#count_heartbeats" approx:(&" approximately")? : command => do let approx ← if approx.isSome then `(set_option linter.countHeartbeatsApprox true) else @@ -292,6 +299,9 @@ macro "#count_heartbeats" approx:(&" approximately")? : command => do #[← `(command| set_option linter.countHeartbeats true), approx]⟩ +deprecated_syntax countHeartbeats "use `#count_heartbeats in` or \ + `set_option trace.profiler true` with `set_option trace.profiler.useHeartbeats true`" + (since := "2026-07-30") end CountHeartbeats diff --git a/MathlibTest/Util/CountHeartbeats.lean b/MathlibTest/Util/CountHeartbeats.lean index 33f1107255bb8e..044f069bf77485 100644 --- a/MathlibTest/Util/CountHeartbeats.lean +++ b/MathlibTest/Util/CountHeartbeats.lean @@ -26,6 +26,12 @@ example (a : Nat) : a = a := rfl section using_count_heartbeats -- sets the `countHeartbeats` both linter option and the `approximate` option to `true` +/-- +warning: syntax 'Mathlib.Linter.CountHeartbeats.countHeartbeats' has been deprecated: use `#count_heartbeats in` or `set_option trace.profiler true` with `set_option trace.profiler.useHeartbeats true` + +Note: This linter can be disabled with `set_option linter.deprecated.syntax false` +-/ +#guard_msgs in #count_heartbeats approximately mutual -- mutual declarations get ignored From f60ac0eb466a8db04f36381155dd58b1a213374e Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Fri, 31 Jul 2026 05:53:23 +0000 Subject: [PATCH 1094/1300] feat: add lemmas about products over Finset.Iio (#39078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mostly useful for `ℕ` * I added the `Finset.Iic` lemmas by symmetry, but I'm happy to remove them if we think they are redundant. --- .../BigOperators/Group/LocallyFinite.lean | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean b/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean index 0ccb893cdef688..160df874e13737 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean @@ -113,6 +113,33 @@ lemma prod_Ico_mul_eq_prod_Ico_add_one (hab : a ≤ b) (f : α → M) : end LocallyFiniteOrder +section LocallyFiniteOrderBot +variable [LocallyFiniteOrderBot α] + +@[to_additive (dont_translate := α)] +lemma prod_Iio_add_one_comm [Add α] [One α] [SuccAddOrder α] [NoMaxOrder α] + (a : α) (f : α → M) : ∏ i < a + 1, f i = f a * (∏ i < a, f i) := by + simp [Iio_add_one_eq_Iic, ← Iio_insert, Finset.prod_insert] + +@[to_additive (dont_translate := α) (attr := simp)] +lemma prod_Iio_add_one [Add α] [One α] [SuccAddOrder α] [NoMaxOrder α] + (a : α) (f : α → M) : ∏ i < a + 1, f i = (∏ i < a, f i) * f a := by + simp_rw [prod_Iio_add_one_comm, mul_comm] + +@[to_additive (dont_translate := α)] +lemma prod_Iic_add_one_comm [Add α] [One α] [SuccAddOrder α] [NoMaxOrder α] + (a : α) (f : α → M) : ∏ i ≤ a + 1, f i = f (a + 1) * (∏ i ≤ a, f i) := by + simp only [← Iio_insert, mem_Iio, lt_self_iff_false, not_false_eq_true, prod_insert, + prod_Iio_add_one_comm] + +@[to_additive (dont_translate := α) (attr := simp)] +lemma prod_Iic_add_one [Add α] [One α] [SuccAddOrder α] [NoMaxOrder α] + (a : α) (f : α → M) : ∏ i ≤ a + 1, f i = (∏ i ≤ a, f i) * f (a + 1) := by + simp_rw [prod_Iic_add_one_comm, mul_comm] + +end LocallyFiniteOrderBot + +section LocallyFiniteOrderTopBot variable [Fintype α] [LocallyFiniteOrderTop α] [LocallyFiniteOrderBot α] @[to_additive] @@ -123,6 +150,8 @@ lemma prod_prod_Ioi_mul_eq_prod_prod_off_diag (f : α → α → M) : rw [prod_sigma', prod_sigma'] refine prod_nbij' (fun i ↦ ⟨i.2, i.1⟩) (fun i ↦ ⟨i.2, i.1⟩) ?_ ?_ ?_ ?_ ?_ <;> simp +end LocallyFiniteOrderTopBot + end LinearOrder set_option backward.isDefEq.respectTransparency false in From 0f0a217d5d731dad8a22f3f7095634784d30ac14 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 31 Jul 2026 08:20:33 +0000 Subject: [PATCH 1095/1300] chore(CategoryTheory): remove `backward` options using `implicit_reducible` (#42161) This PR removes a lot of the transparency related `set_option`. I did this by using `#defeq_abuse in` to determine which definition was not being unfolded, and then tagging such definitions with `implicit_reducible`. In particular `backward.isDefEq.respectTransparency` can almost always be removed like this, but `backward.defeqAttrib.useBackward` is still sometimes tricky to remove. Presumably, the changes from this PR will let us remove many more `set_option` in further files that this PR doesn't touch. --- Mathlib/CategoryTheory/Adjunction/Basic.lean | 13 +--- Mathlib/CategoryTheory/Comma/Basic.lean | 26 +------ Mathlib/CategoryTheory/EqToHom.lean | 2 - Mathlib/CategoryTheory/Equivalence.lean | 25 ++----- Mathlib/CategoryTheory/EssentialImage.lean | 8 +- Mathlib/CategoryTheory/Functor/Category.lean | 2 - .../CategoryTheory/Functor/FullyFaithful.lean | 3 - Mathlib/CategoryTheory/Limits/Cones.lean | 75 +++++-------------- Mathlib/CategoryTheory/Limits/HasLimits.lean | 35 --------- Mathlib/CategoryTheory/Limits/IsLimit.lean | 28 +------ .../Limits/Shapes/Equalizers.lean | 44 ++--------- .../Limits/Shapes/IsTerminal.lean | 32 ++------ .../Limits/Shapes/Products.lean | 55 +------------- .../Limits/Shapes/Terminal.lean | 13 ---- Mathlib/CategoryTheory/NatIso.lean | 2 +- Mathlib/CategoryTheory/Opposites.lean | 75 ++++--------------- Mathlib/CategoryTheory/Whiskering.lean | 39 ++-------- 17 files changed, 74 insertions(+), 403 deletions(-) diff --git a/Mathlib/CategoryTheory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Adjunction/Basic.lean index f0e132087a6b1f..fb5b3de90ebebe 100644 --- a/Mathlib/CategoryTheory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Adjunction/Basic.lean @@ -79,8 +79,6 @@ Conversely `Equivalence.toAdjunction` recovers the underlying adjunction from an isomorphism `L ⋙ R ≅ 𝟭 C`, the unit is an isomorphism, and similarly for the counit. -/ -set_option backward.defeqAttrib.useBackward true - @[expose] public section namespace CategoryTheory @@ -314,7 +312,6 @@ def corepresentableBy (X : C) : homEquiv := adj.homEquiv _ _ homEquiv_comp := by simp -set_option backward.isDefEq.respectTransparency false in /-- If `adj : F ⊣ G`, and `Y : D`, then `G.obj Y` represents `X ↦ (F.obj X ⟶ Y)`. -/ @[simps] def representableBy (Y : D) : @@ -538,7 +535,6 @@ lemma homEquiv_ofNatIsoRight_symm_apply {F : C ⥤ D} {G H : D ⥤ C} (adj : F (adj.homEquiv _ _).symm (f ≫ iso.inv.app _) := by simp -set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism which an adjunction `F ⊣ G` induces on `G ⋙ yoneda`. This states that `Adjunction.homEquiv` is natural in both arguments. -/ @[simps!] @@ -547,7 +543,6 @@ def compYonedaIso {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category. G ⋙ yoneda ≅ yoneda ⋙ (whiskeringLeft _ _ _).obj F.op := NatIso.ofComponents fun X => NatIso.ofComponents fun Y => (adj.homEquiv Y.unop X).toIso.symm -set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism which an adjunction `F ⊣ G` induces on `F.op ⋙ coyoneda`. This states that `Adjunction.homEquiv` is natural in both arguments. -/ @[simps!] @@ -556,7 +551,7 @@ def compCoyonedaIso {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Categor F.op ⋙ coyoneda ≅ coyoneda ⋙ (whiskeringLeft _ _ _).obj G := NatIso.ofComponents fun X => NatIso.ofComponents fun Y => (adj.homEquiv X.unop Y).toIso -set_option backward.isDefEq.respectTransparency.types false in +set_option backward.defeqAttrib.useBackward true in /-- The isomorphism which an adjunction `F ⊣ G` induces on `F.op ⋙ uliftCoyoneda`. This states that `Adjunction.homEquiv` is natural in both arguments. -/ @[simps!] @@ -611,7 +606,7 @@ variable (e : ∀ X Y, (F_obj X ⟶ Y) ≃ (X ⟶ G.obj Y)) a bijection `e` between `F_obj X ⟶ Y` and `X ⟶ G.obj Y` satisfying a naturality law `he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g`. Dual to `rightAdjointOfEquiv`. -/ -@[simps!] +@[implicit_reducible, simps!] def leftAdjointOfEquiv (he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g) : C ⥤ D where obj := F_obj map {X} {X'} f := (e X (F_obj X')).symm (f ≫ e X' (F_obj X') (𝟙 _)) @@ -624,7 +619,6 @@ def leftAdjointOfEquiv (he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.ma variable (he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g) -set_option backward.isDefEq.respectTransparency false in /-- Show that the functor given by `leftAdjointOfEquiv` is indeed left adjoint to `G`. Dual to `adjunctionOfEquivRight`. -/ @[simps!] @@ -653,7 +647,7 @@ private theorem he'' (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y a bijection `e` between `F.obj X ⟶ Y` and `X ⟶ G_obj Y` satisfying a naturality law `he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g`. Dual to `leftAdjointOfEquiv`. -/ -@[simps!] +@[implicit_reducible, simps!] def rightAdjointOfEquiv (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) : D ⥤ C where obj := G_obj map {Y} {Y'} g := (e (G_obj Y) Y') ((e (G_obj Y) Y).symm (𝟙 _) ≫ g) @@ -664,7 +658,6 @@ def rightAdjointOfEquiv (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X rw [← assoc, he'' e he, comp_id, Equiv.symm_apply_apply] simp -set_option backward.isDefEq.respectTransparency false in /-- Show that the functor given by `rightAdjointOfEquiv` is indeed right adjoint to `F`. Dual to `adjunctionOfEquivLeft`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index 70748bb0d45d38..8a3cde979b9675 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -265,7 +265,6 @@ attribute [to_dual existing] map_obj_left attribute [to_dual existing (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, X Y)] map_map_left -set_option backward.isDefEq.respectTransparency false in @[to_dual existing (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β) map_obj_hom] theorem map_obj_hom' (X : Comma L R) : ((map α β).obj X).hom = (α.app X.left ≫ F.map X.hom) ≫ β.app X.right := by simp @@ -277,7 +276,6 @@ instance faithful_map [F₁.Faithful] [F₂.Faithful] : (map α β).Faithful whe · exact F₁.map_injective (congr_arg CommaMorphism.left h) · exact F₂.map_injective (congr_arg CommaMorphism.right h) -set_option backward.isDefEq.respectTransparency false in @[to_dual self (reorder := A B, 2 4, A' B', 8 10, L R, L' R', F₁ F₂, α β, 23 24, 25 26)] instance full_map [F.Faithful] [F₁.Full] [F₂.Full] [IsIso α] [IsIso β] : (map α β).Full where map_surjective {X Y} φ := @@ -349,8 +347,6 @@ def mapLeft (l : L₁ ⟶ L₂) : Comma L₂ R ⥤ Comma L₁ R where attribute [to_dual existing] mapLeft_map_left attribute [to_dual existing] mapLeft_map_right -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- The functor `Comma L R ⥤ Comma L R` induced by the identity natural transformation on `L` is naturally isomorphic to the identity functor. -/ @@ -360,8 +356,6 @@ naturally isomorphic to the identity functor. -/] def mapLeftId : mapLeft R (𝟙 L) ≅ 𝟭 _ := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- The functor `Comma L₁ R ⥤ Comma L₃ R` induced by the composition of two natural transformations `l : L₁ ⟶ L₂` and `l' : L₂ ⟶ L₃` is naturally isomorphic to the composition of the two functors @@ -383,7 +377,6 @@ set_option linter.translate.warnInvalid false in def mapLeftEq (l l' : L₁ ⟶ L₂) (h : l = l') : mapLeft R l ≅ mapLeft R l' := NatIso.ofComponents (fun X => isoMk (Iso.refl _) (Iso.refl _)) -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- A natural isomorphism `L₁ ≅ L₂` induces an equivalence of categories @@ -417,7 +410,6 @@ def preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) : Comma (F ⋙ L) R ⥤ Co right := f.right w := by simpa using! f.w } -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- `Comma.preLeft` is a particular case of `Comma.map`, but with better definitional properties. -/ @@ -445,9 +437,8 @@ instance (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) [F.EssSurj] : (preLeft F L R) instance isEquivalence_preLeft (F : C ⥤ A) (L : A ⥤ T) (R : B ⥤ T) [F.IsEquivalence] : (preLeft F L R).IsEquivalence where -set_option backward.isDefEq.respectTransparency false in /-- The functor `(L, R) ⥤ (L ⋙ F, R ⋙ F)` -/ -@[to_dual self, simps] +@[implicit_reducible, to_dual self, simps] def post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : Comma L R ⥤ Comma (L ⋙ F) (R ⋙ F) where obj X := { left := X.left @@ -461,8 +452,6 @@ def post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : Comma L R ⥤ Comma (L ⋙ attribute [to_dual existing] post_obj_left attribute [to_dual self] post_obj_hom -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- `Comma.post` is a particular case of `Comma.map`, but with better definitional properties. -/ @[to_dual self] def postIso (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) : @@ -488,7 +477,7 @@ instance isEquivalence_post (L : A ⥤ T) (R : B ⥤ T) (F : T ⥤ C) [F.IsEquiv /-- The canonical functor from the product of two categories to the comma category of their respective functors into `Discrete PUnit`. -/ -@[simps] +@[implicit_reducible, simps] def fromProd (L : A ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : A × B ⥤ Comma L R where obj X := @@ -499,7 +488,6 @@ def fromProd (L : A ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : { left := f.1 right := f.2 } -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Taking the comma category of two functors into `Discrete PUnit` results in something is equivalent to their product. -/ @@ -511,28 +499,24 @@ def equivProd (L : A ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : unitIso := Iso.refl _ counitIso := Iso.refl _ -set_option backward.isDefEq.respectTransparency.types false in /-- Taking the comma category of a functor into `A ⥤ Discrete PUnit` and the identity `Discrete PUnit ⥤ Discrete PUnit` results in a category equivalent to `A`. -/ def toPUnitIdEquiv (L : A ⥤ Discrete PUnit) (R : Discrete PUnit ⥤ Discrete PUnit) : Comma L R ≌ A := (equivProd L _).trans (prod.rightUnitorEquivalence A) -set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toPUnitIdEquiv_functor_iso {L : A ⥤ Discrete PUnit} {R : Discrete PUnit ⥤ Discrete PUnit} : (toPUnitIdEquiv L R).functor = fst L R := rfl -set_option backward.isDefEq.respectTransparency.types false in /-- Taking the comma category of the identity `Discrete PUnit ⥤ Discrete PUnit` and a functor `B ⥤ Discrete PUnit` results in a category equivalent to `B`. -/ def toIdPUnitEquiv (L : Discrete PUnit ⥤ Discrete PUnit) (R : B ⥤ Discrete PUnit) : Comma L R ≌ B := (equivProd _ R).trans (prod.leftUnitorEquivalence B) -set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem toIdPUnitEquiv_functor_iso {L : Discrete PUnit ⥤ Discrete PUnit} {R : B ⥤ Discrete PUnit} : @@ -547,7 +531,7 @@ open Opposite set_option backward.defeqAttrib.useBackward true in /-- The canonical functor from `Comma L R` to `(Comma R.op L.op)ᵒᵖ`. -/ -@[simps] +@[implicit_reducible, simps] def opFunctor : Comma L R ⥤ (Comma R.op L.op)ᵒᵖ where obj X := ⟨op X.right, op X.left, op X.hom⟩ map f := ⟨op f.right, op f.left, Quiver.Hom.unop_inj (by simp)⟩ @@ -565,7 +549,7 @@ def opFunctorCompSnd : (opFunctor L R).leftOp ⋙ snd _ _ ≅ (fst _ _).op := Iso.refl _ /-- The canonical functor from `Comma L.op R.op` to `(Comma R L)ᵒᵖ`. -/ -@[simps] +@[implicit_reducible, simps] def unopFunctor : Comma L.op R.op ⥤ (Comma R L)ᵒᵖ where obj X := ⟨X.right.unop, X.left.unop, X.hom.unop⟩ map f := ⟨f.right.unop, f.left.unop, Quiver.Hom.op_inj (by simpa using! f.w.symm)⟩ @@ -580,8 +564,6 @@ def unopFunctorCompFst : unopFunctor L R ⋙ (fst _ _).op ≅ snd _ _ := def unopFunctorCompSnd : unopFunctor L R ⋙ (snd _ _).op ≅ fst _ _ := Iso.refl _ -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The canonical equivalence between `Comma L R` and `(Comma R.op L.op)ᵒᵖ`. -/ @[simps] def opEquiv : Comma L R ≌ (Comma R.op L.op)ᵒᵖ where diff --git a/Mathlib/CategoryTheory/EqToHom.lean b/Mathlib/CategoryTheory/EqToHom.lean index 8af05f699ff947..fba7c0c44b2e5f 100644 --- a/Mathlib/CategoryTheory/EqToHom.lean +++ b/Mathlib/CategoryTheory/EqToHom.lean @@ -390,8 +390,6 @@ lemma ObjectProperty.eqToHom_hom {C : Type*} [Category C] {P : ObjectProperty C} subst h rfl -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- If `T ≃ D` is a bijection and `D` is a category, then `InducedCategory D e` is equivalent to `D`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Equivalence.lean b/Mathlib/CategoryTheory/Equivalence.lean index 24f7948bf55643..a1c1e527f13aee 100644 --- a/Mathlib/CategoryTheory/Equivalence.lean +++ b/Mathlib/CategoryTheory/Equivalence.lean @@ -57,8 +57,6 @@ if it is full, faithful and essentially surjective. We write `C ≌ D` (`\backcong`, not to be confused with `≅`/`\cong`) for a bundled equivalence. -/ -set_option backward.defeqAttrib.useBackward true -set_option backward.isDefEq.respectTransparency.types false @[expose] public section @@ -109,7 +107,6 @@ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] namespace Equivalence -set_option backward.isDefEq.respectTransparency false in @[to_dual existing functor_unitIso_comp] theorem counitIso_functor_comp (e : C ≌ D) (X : C) : dsimp% e.counitIso.inv.app (e.functor.obj X) ≫ e.functor.map (e.unitIso.inv.app X) = @@ -117,7 +114,6 @@ theorem counitIso_functor_comp (e : C ≌ D) (X : C) : simpa [functor_unitIso_comp] using Iso.inv_eq_inv (e.functor.mapIso (e.unitIso.app X) ≪≫ e.counitIso.app (e.functor.obj X)) (Iso.refl _) -set_option backward.isDefEq.respectTransparency false in /-- `Equivalence.mk'` is the dual of `Equivalence.mk`, which we need for `to_dual`. Please avoid using this directly. -/ @[to_dual existing mk'] @@ -265,7 +261,6 @@ theorem functor_unit_comp (e : C ≌ D) (X : C) : dsimp% e.functor.map (e.unit.app X) ≫ e.counit.app (e.functor.obj X) = 𝟙 (e.functor.obj X) := e.functor_unitIso_comp X -set_option backward.isDefEq.respectTransparency false in @[to_dual counitInv_app_functor] theorem counit_app_functor (e : C ≌ D) (X : C) : e.counit.app (e.functor.obj X) = e.functor.map (e.unitInv.app X) := by @@ -306,7 +301,6 @@ theorem unit_inverse_comp (e : C ≌ D) (Y : D) : rw [← map_comp e.inverse, e.counitInv_naturality, e.counitIso.hom_inv_id_app] simp -set_option backward.isDefEq.respectTransparency false in @[to_dual unitInv_app_inverse] theorem unit_app_inverse (e : C ≌ D) (Y : D) : e.unit.app (e.inverse.obj Y) = e.inverse.map (e.counitInv.app Y) := by @@ -340,7 +334,6 @@ def adjointifyη : 𝟭 C ≅ F ⋙ G := by _ ≅ 𝟭 C ⋙ F ⋙ G := isoWhiskerRight η.symm (F ⋙ G) _ ≅ F ⋙ G := leftUnitor (F ⋙ G) -set_option backward.isDefEq.respectTransparency false in @[reassoc] theorem adjointify_η_ε (X : C) : F.map ((adjointifyη η ε).hom.app X) ≫ ε.hom.app (F.obj X) = 𝟙 (F.obj X) := by @@ -369,7 +362,7 @@ instance : Inhabited (C ≌ C) := ⟨refl⟩ /-- Equivalence of categories is symmetric. -/ -@[symm, simps] +@[implicit_reducible, symm, simps] def symm (e : C ≌ D) : D ≌ C := ⟨e.inverse, e.functor, e.counitIso.symm, e.unitIso.symm, e.inverse_counitInv_comp⟩ @@ -482,7 +475,6 @@ theorem cancel_counit_right {X Y : D} (f f' : X ⟶ e.functor.obj (e.inverse.obj /- `cancel_counit_left` is not a `simp` lemma because it would be redundant. -/ -set_option backward.isDefEq.respectTransparency false in @[to_dual cancel_counit_left, simp] theorem cancel_counitInv_right {X Y : D} (f f' : X ⟶ Y) : f ≫ e.counitInv.app Y = f' ≫ e.counitInv.app Y ↔ f = f' := by simp only [cancel_mono] @@ -581,7 +573,7 @@ instance full_inverse (e : C ≌ E) : e.inverse.Full := /-- If `e : C ≌ D` is an equivalence of categories, and `iso : e.functor ≅ G` is an isomorphism, then there is an equivalence of categories whose functor is `G`. -/ -@[simps!] +@[implicit_reducible, simps!] def changeFunctor (e : C ≌ D) {G : C ⥤ D} (iso : e.functor ≅ G) : C ≌ D where functor := G inverse := e.inverse @@ -597,7 +589,7 @@ theorem changeFunctor_trans (e : C ≌ D) {G G' : C ⥤ D} (iso₁ : e.functor /-- If `e : C ≌ D` is an equivalence of categories, and `iso : e.functor ≅ G` is an isomorphism, then there is an equivalence of categories whose inverse is `G`. -/ -@[simps!] +@[implicit_reducible, simps!] def changeInverse (e : C ≌ D) {G : D ⥤ C} (iso : e.inverse ≅ G) : C ≌ D where functor := e.functor inverse := G @@ -637,13 +629,13 @@ end IsEquivalence /-- A quasi-inverse `D ⥤ C` to a functor that `F : C ⥤ D` that is an equivalence, i.e. faithful, full, and essentially surjective. -/ +@[implicit_reducible] noncomputable def inv (F : C ⥤ D) [F.IsEquivalence] : D ⥤ C where obj X := F.objPreimage X map {X Y} f := F.preimage ((F.objObjPreimageIso X).hom ≫ f ≫ (F.objObjPreimageIso Y).inv) map_id X := by apply F.map_injective; simp map_comp {X Y Z} f g := by apply F.map_injective; simp -set_option backward.isDefEq.respectTransparency false in /-- Interpret a functor that is an equivalence as an equivalence. -/ @[simps functor, simps -isSimp inverse, simps! -isSimp unitIso_hom_app unitIso_inv_app counitIso_hom_app counitIso_inv_app, stacks 02C3] @@ -676,16 +668,15 @@ end Functor namespace Functor - @[simp] theorem fun_inv_map (F : C ⥤ D) [IsEquivalence F] (X Y : D) (f : X ⟶ Y) : - F.map (F.inv.map f) = F.asEquivalence.counit.app X ≫ f ≫ F.asEquivalence.counitInv.app Y := by - simpa using! (NatIso.naturality_2 (α := F.asEquivalence.counitIso) (f := f)).symm + F.map (F.inv.map f) = F.asEquivalence.counit.app X ≫ f ≫ F.asEquivalence.counitInv.app Y := + (NatIso.naturality_2 (α := F.asEquivalence.counitIso) (f := f)).symm @[simp] theorem inv_fun_map (F : C ⥤ D) [IsEquivalence F] (X Y : C) (f : X ⟶ Y) : - F.inv.map (F.map f) = F.asEquivalence.unitInv.app X ≫ f ≫ F.asEquivalence.unit.app Y := by - simpa using! (NatIso.naturality_1 (α := F.asEquivalence.unitIso) (f := f)).symm + F.inv.map (F.map f) = F.asEquivalence.unitInv.app X ≫ f ≫ F.asEquivalence.unit.app Y := + (NatIso.naturality_1 (α := F.asEquivalence.unitIso) (f := f)).symm lemma isEquivalence_of_iso {F G : C ⥤ D} (e : F ≅ G) [F.IsEquivalence] : G.IsEquivalence := ((asEquivalence F).changeFunctor e).isEquivalence_functor diff --git a/Mathlib/CategoryTheory/EssentialImage.lean b/Mathlib/CategoryTheory/EssentialImage.lean index 03c782c1703628..f00e504e9e74b0 100644 --- a/Mathlib/CategoryTheory/EssentialImage.lean +++ b/Mathlib/CategoryTheory/EssentialImage.lean @@ -89,7 +89,7 @@ lemma essImage_ext (F : C ⥤ D) {X Y : F.EssImageSubcategory} (f g : X ⟶ Y) Given a functor `F : C ⥤ D`, we have an (essentially surjective) functor from `C` to the essential image of `F`. -/ -@[simps!] +@[implicit_reducible, simps!] def toEssImage (F : C ⥤ D) : C ⥤ F.EssImageSubcategory := F.essImage.lift F (obj_mem_essImage _) @@ -173,11 +173,10 @@ section variable {J C D : Type*} [Category* J] [Category* C] [Category* D] (G : J ⥤ D) (F : C ⥤ D) [F.Full] [F.Faithful] (hG : ∀ j, F.essImage (G.obj j)) -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Lift a functor `G : J ⥤ D` to the essential image of a fully faithful functor `F : C ⥤ D` to a functor `G' : J ⥤ C` such that `G' ⋙ F ≅ G`. See `essImage.liftFunctorCompIso`. -/ -@[simps] def essImage.liftFunctor : J ⥤ C where +@[implicit_reducible, simps] +def essImage.liftFunctor : J ⥤ C where obj j := F.toEssImage.objPreimage ⟨G.obj j, hG j⟩ map {i j} f := F.preimage <| @@ -186,7 +185,6 @@ functor `G' : J ⥤ C` such that `G' ⋙ F ≅ G`. See `essImage.liftFunctorComp map_id _ := F.map_injective (by simp) map_comp _ _ := F.map_injective (by simp) -set_option backward.isDefEq.respectTransparency false in /-- A functor `G : J ⥤ D` to the essential image of a fully faithful functor `F : C ⥤ D` does factor through `essImage.liftFunctor G F hG`. -/ @[simps!] def essImage.liftFunctorCompIso : essImage.liftFunctor G F hG ⋙ F ≅ G := diff --git a/Mathlib/CategoryTheory/Functor/Category.lean b/Mathlib/CategoryTheory/Functor/Category.lean index d060ac1d7edfe4..82a4d0afbdc160 100644 --- a/Mathlib/CategoryTheory/Functor/Category.lean +++ b/Mathlib/CategoryTheory/Functor/Category.lean @@ -127,12 +127,10 @@ to_dual_insert_cast hcomp := by ext x; exact β.naturality' (α.app x) /-- Notation for horizontal composition of natural transformations. -/ infixl:80 " ◫ " => hcomp -set_option backward.defeqAttrib.useBackward true in @[to_dual self] theorem hcomp_id_app {H : D ⥤ E} (α : F ⟶ G) (X : C) : (α ◫ 𝟙 H).app X = H.map (α.app X) := by simp -set_option backward.defeqAttrib.useBackward true in @[to_dual self] theorem id_hcomp_app {H : E ⥤ C} (α : F ⟶ G) (X : E) : (𝟙 H ◫ α).app X = α.app _ := by simp diff --git a/Mathlib/CategoryTheory/Functor/FullyFaithful.lean b/Mathlib/CategoryTheory/Functor/FullyFaithful.lean index d7b7098026f9a8..df388bbf5931f1 100644 --- a/Mathlib/CategoryTheory/Functor/FullyFaithful.lean +++ b/Mathlib/CategoryTheory/Functor/FullyFaithful.lean @@ -217,7 +217,6 @@ def isoEquiv {X Y : C} : (X ≅ Y) ≃ (F.obj X ≅ F.obj Y) where left_inv := by cat_disch right_inv := by cat_disch -set_option backward.isDefEq.respectTransparency false in /-- Fully faithful functors are stable by composition. -/ @[simps] def comp {G : D ⥤ E} (hG : G.FullyFaithful) : (F ⋙ G).FullyFaithful where @@ -351,7 +350,6 @@ theorem Faithful.div_faithful (F : C ⥤ E) [F.Faithful] (G : D ⥤ E) [G.Faithf Functor.Faithful (Faithful.div F G obj @h_obj @map @h_map) := (Faithful.div_comp F G _ h_obj _ @h_map).faithful_of_comp -set_option backward.isDefEq.respectTransparency false in instance Full.comp [Full F] [Full G] : Full (F ⋙ G) where map_surjective f := ⟨F.preimage (G.preimage f), by simp⟩ @@ -365,7 +363,6 @@ lemma Full.of_comp_faithful_iso {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} [Full have := Full.of_iso h.symm exact Full.of_comp_faithful F G -set_option backward.isDefEq.respectTransparency false in /-- Given a natural isomorphism between `F ⋙ H` and `G ⋙ H` for a fully faithful functor `H`, we can 'cancel' it to give a natural iso between `F` and `G`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 209218a4748d90..4b3d2d4e4ad678 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -32,8 +32,6 @@ And, of course, we dualise all this to cocones as well. For more results about the category of cones, see `cone_category.lean`. -/ -set_option backward.defeqAttrib.useBackward true - @[expose] public section -- morphism levels before object levels. See note [category theory universes]. @@ -65,7 +63,7 @@ variable (F : J ⥤ C) type of natural transformations from the constant functor with value `X` to `F`. An object representing this functor is a limit of `F`. -/ -@[simps! obj map] +@[implicit_reducible, simps! obj map] def cones : Cᵒᵖ ⥤ Type (max u₁ v₃) := (const J).op ⋙ yoneda.obj F @@ -73,7 +71,7 @@ def cones : Cᵒᵖ ⥤ Type (max u₁ v₃) := the type of natural transformations from `F` to the constant functor with value `X`. An object corepresenting this functor is a colimit of `F`. -/ -@[simps! obj map] +@[implicit_reducible, simps! obj map] def cocones : C ⥤ Type (max u₁ v₃) := const J ⋙ coyoneda.obj (op F) @@ -150,8 +148,6 @@ instance inhabitedCone (F : Discrete PUnit ⥤ C) : Inhabited (Cone F) := } }⟩ -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in @[to_dual (attr := reassoc), elementwise] theorem Cone.w {F : J ⥤ C} (c : Cone F) {j j' : J} (f : j ⟶ j') : dsimp% c.π.app j ≫ F.map f = c.π.app j' := by @@ -201,14 +197,14 @@ def extensions (c : Cone F) : uliftYoneda.obj c.pt ⟶ F.cones where app _ := ↾fun f ↦ (const J).map f.down ≫ c.π /-- A map to the vertex of a cone induces a cone by composition. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- A map from the vertex of a cocone induces a cocone by composition. -/] def extend (c : Cone F) {X : C} (f : X ⟶ c.pt) : Cone F where pt := X π := (const J).map f ≫ c.π /-- Whisker a cone by precomposition of a functor. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Whisker a cocone by precomposition of a functor. See `whiskering` for a functorial version. -/] @@ -262,12 +258,10 @@ structure CoconeMorphism (A B : Cocone F) where attribute [reassoc (attr := simp)] ConeMorphism.w CoconeMorphism.w attribute [to_dual existing] ConeMorphism.casesOn -set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance inhabitedConeMorphism (A : Cone F) : Inhabited (ConeMorphism A A) := ⟨{ hom := 𝟙 _ }⟩ -set_option backward.isDefEq.respectTransparency.types false in /-- The category of cones on a given diagram. -/ @[to_dual (attr := simps) /-- The category of cocones on a given diagram. -/] instance Cone.category : Category (Cone F) where @@ -275,7 +269,6 @@ instance Cone.category : Category (Cone F) where comp f g := { hom := f.hom ≫ g.hom } id B := { hom := 𝟙 B.pt } -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := ext) /- We do not want `simps` automatically generate the lemma for simplifying the hom field of a category. So we need to write the `ext` lemma in terms of the @@ -285,25 +278,20 @@ theorem ConeMorphism.ext {c c' : Cone F} (f g : c ⟶ c') (w : f.hom = g.hom) : cases g congr -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp))] lemma ConeMorphism.hom_inv_id {c d : Cone F} (f : c ≅ d) : f.hom.hom ≫ f.inv.hom = 𝟙 _ := by simp [← Cone.category_comp_hom] -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp))] lemma ConeMorphism.inv_hom_id {c d : Cone F} (f : c ≅ d) : f.inv.hom ≫ f.hom.hom = 𝟙 _ := by simp [← Cone.category_comp_hom] -set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance {c d : Cone F} (f : c ≅ d) : IsIso f.hom.hom := ⟨f.inv.hom, by simp⟩ -set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance {c d : Cone F} (f : c ≅ d) : IsIso f.inv.hom := ⟨f.hom.hom, by simp⟩ -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp))] lemma ConeMorphism.map_w {c c' : Cone F} (f : c ⟶ c') (G : C ⥤ D) (j : J) : G.map f.hom ≫ G.map (c'.π.app j) = G.map (c.π.app j) := by @@ -311,7 +299,6 @@ lemma ConeMorphism.map_w {c c' : Cone F} (f : c ⟶ c') (G : C ⥤ D) (j : J) : namespace Cone -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ @@ -328,7 +315,6 @@ def ext {c c' : Cone F} (φ : c.pt ≅ c'.pt) attribute [to_dual existing extInv_inv_hom] ext_hom_hom attribute [to_dual existing extInv_hom_hom] ext_inv_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ @@ -344,7 +330,6 @@ attribute [to_dual existing ext_inv_hom] extInv_hom_hom attribute [aesop apply safe (rule_sets := [CategoryTheory])] Limits.Cone.ext Limits.Cocone.ext -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Eta rule for cones. -/ @[to_dual (attr := simps!) /-- Eta rule for cocones. -/] @@ -365,13 +350,11 @@ theorem cone_iso_of_hom_iso {K : J ⥤ C} {c d : Cone K} (f : c ⟶ d) [i : IsIs ⟨⟨{ hom := inv f.hom w := fun j => (asIso f.hom).inv_comp_eq.2 (f.w j).symm }, by cat_disch⟩⟩ -set_option backward.isDefEq.respectTransparency.types false in /-- There is a morphism from an extended cone to the original cone. -/ @[to_dual (attr := simps) /-- There is a morphism from a cocone to its extension. -/] def extendHom (s : Cone F) {X : C} (f : X ⟶ s.pt) : s.extend f ⟶ s where hom := f -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Extending a cone by the identity does nothing. -/ @[to_dual (attr := simps!) /-- Extending a cocone by the identity does nothing. -/] @@ -381,7 +364,6 @@ def extendId (s : Cone F) : s.extend (𝟙 s.pt) ≅ s := attribute [to_dual existing extendId_inv_hom] extendId_hom_hom attribute [to_dual existing extendId_hom_hom] extendId_inv_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Extending a cone by a composition is the same as extending the cone twice. -/ @[to_dual (attr := simps!) (reorder := f g) @@ -393,7 +375,6 @@ def extendComp (s : Cone F) {X Y : C} (f : X ⟶ Y) (g : Y ⟶ s.pt) : attribute [to_dual existing extendComp_inv_hom] extendComp_hom_hom attribute [to_dual existing extendComp_hom_hom] extendComp_inv_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- A cone extended by an isomorphism is isomorphic to the original cone. -/ @[to_dual (attr := simps) @@ -409,11 +390,10 @@ attribute [to_dual existing extendIso_hom_hom] extendIso_inv_hom instance {s : Cone F} {X : C} (f : X ⟶ s.pt) [IsIso f] : IsIso (s.extendHom f) := ⟨(extendIso s (asIso' f)).hom, by cat_disch⟩ -set_option backward.isDefEq.respectTransparency.types false in /-- Functorially postcompose a cone for `F` by a natural transformation `F ⟶ G` to give a cone for `G`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Functorially precompose a cocone for `F` by a natural transformation `G ⟶ F` to give a cocone for `G`. -/] def postcompose {G : J ⥤ C} (α : F ⟶ G) : Cone F ⥤ Cone G where @@ -422,7 +402,6 @@ def postcompose {G : J ⥤ C} (α : F ⟶ G) : Cone F ⥤ Cone G where π := c.π ≫ α } map f := { hom := f.hom } -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Postcomposing a cone by the composite natural transformation `α ≫ β` is the same as postcomposing by `α` and then by `β`. -/ @@ -436,7 +415,6 @@ def postcomposeComp {G H : J ⥤ C} (α : F ⟶ G) (β : G ⟶ H) : attribute [to_dual existing precomposeComp_inv_app_hom] postcomposeComp_hom_app_hom attribute [to_dual existing precomposeComp_hom_app_hom] postcomposeComp_inv_app_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- Postcomposing by the identity does not change the cone up to isomorphism. -/ @[to_dual (attr := simps!) @@ -447,11 +425,10 @@ def postcomposeId : postcompose (𝟙 F) ≅ 𝟭 (Cone F) := attribute [to_dual existing precomposeId_inv_app_hom] postcomposeId_hom_app_hom attribute [to_dual existing precomposeId_hom_app_hom] postcomposeId_inv_app_hom -set_option backward.isDefEq.respectTransparency.types false in /-- If `F` and `G` are naturally isomorphic functors, then they have equivalent categories of cones. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- If `F` and `G` are naturally isomorphic functors, then they have equivalent categories of cocones. -/] @@ -463,14 +440,13 @@ def postcomposeEquivalence {G : J ⥤ C} (α : F ≅ G) : Cone F ≌ Cone G wher /-- Whiskering on the left by `E : K ⥤ J` gives a functor from `Cone F` to `Cone (E ⋙ F)`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Whiskering on the left by `E : K ⥤ J` gives a functor from `Cocone F` to `Cocone (E ⋙ F)`. -/] def whiskering (E : K ⥤ J) : Cone F ⥤ Cone (E ⋙ F) where obj c := c.whisker E map f := { hom := f.hom } -set_option backward.isDefEq.respectTransparency.types false in /-- Whiskering by an equivalence gives an equivalence between categories of cones. -/ @[to_dual (attr := simps) @@ -510,9 +486,8 @@ def forget : Cone F ⥤ C where variable (G : C ⥤ D) -set_option backward.isDefEq.respectTransparency.types false in /-- A functor `G : C ⥤ D` sends cones over `F` to cones over `F ⋙ G` functorially. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- A functor `G : C ⥤ D` sends cocones over `F` to cocones over `F ⋙ G` functorially. -/] def functoriality : Cone F ⥤ Cone (F ⋙ G) where obj A := @@ -524,14 +499,12 @@ def functoriality : Cone F ⥤ Cone (F ⋙ G) where { hom := G.map f.hom w := ConeMorphism.map_w f G } -set_option backward.isDefEq.respectTransparency.types false in /-- Functoriality is functorial. -/ @[to_dual /-- Functoriality is functorial. -/] def functorialityCompFunctoriality (H : D ⥤ E) : functoriality F G ⋙ functoriality (F ⋙ G) H ≅ functoriality F (G ⋙ H) := NatIso.ofComponents (fun _ ↦ Iso.refl _) -set_option backward.isDefEq.respectTransparency.types false in @[to_dual] instance functoriality_full [G.Full] [G.Faithful] : (functoriality F G).Full where map_surjective t := @@ -597,7 +570,6 @@ namespace Cones @[deprecated (since := "2026-03-06")] alias equivalenceOfReindexing := Cone.equivalenceOfReindexing @[deprecated (since := "2026-03-06")] alias forget := Cone.forget @[deprecated (since := "2026-03-06")] alias functoriality := Cone.functoriality -set_option backward.isDefEq.respectTransparency.types false in @[deprecated (since := "2026-03-06")] alias functorialityCompFunctoriality := Cone.functorialityCompFunctoriality @[deprecated (since := "2026-03-06")] alias functoriality_full := Cone.functoriality_full @@ -628,7 +600,6 @@ namespace Cocones alias equivalenceOfReindexing := Cocone.equivalenceOfReindexing @[deprecated (since := "2026-03-06")] alias forget := Cocone.forget @[deprecated (since := "2026-03-06")] alias functoriality := Cocone.functoriality -set_option backward.isDefEq.respectTransparency.types false in @[deprecated (since := "2026-03-06")] alias functorialityCompFunctoriality := Cocone.functorialityCompFunctoriality @[deprecated (since := "2026-03-06")] alias functoriality_full := Cocone.functoriality_full @@ -649,12 +620,11 @@ variable (H : C ⥤ D) {F : J ⥤ C} {G : J ⥤ C} open CategoryTheory.Limits /-- The image of a cone in C under a functor G : C ⥤ D is a cone in D. -/ -@[to_dual (attr := simps!) +@[to_dual (attr := implicit_reducible, simps!) /-- The image of a cocone in C under a functor G : C ⥤ D is a cocone in D. -/] def mapCone (c : Cone F) : Cone (F ⋙ H) := (Cone.functoriality F H).obj c -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- The construction `mapCone` respects functor composition. -/ @[to_dual (attr := simps!) @@ -693,7 +663,6 @@ noncomputable def mapConeInvMapCone {F : J ⥤ D} (H : D ⥤ C) [IsEquivalence H mapConeInv H (mapCone H c) ≅ c := (Limits.Cone.functorialityEquivalence F (asEquivalence H)).unitIso.symm.app c -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `functoriality F _ ⋙ postcompose (whisker_left F _)` simplifies to `functoriality F _`. -/ @[to_dual (attr := simps!) @@ -707,7 +676,6 @@ attribute [to_dual existing functorialityCompPrecompose_inv_app_hom] attribute [to_dual existing functorialityCompPrecompose_hom_app_hom] functorialityCompPostcompose_inv_app_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- For `F : J ⥤ C`, given a cone `c : Cone F`, and a natural isomorphism `α : H ≅ H'` for functors `H H' : C ⥤ D`, the postcomposition of the cone `H.mapCone` using the isomorphism `α` is @@ -728,7 +696,6 @@ attribute [to_dual existing precomposeWhiskerLeftMapCocone_inv_hom] attribute [to_dual existing precomposeWhiskerLeftMapCocone_hom_hom] postcomposeWhiskerLeftMapCone_inv_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `postcompose`. In particular, for `F : J ⥤ C`, given a cone `c : Cone F`, a @@ -748,7 +715,6 @@ def mapConePostcompose {α : F ⟶ G} {c} : attribute [to_dual existing mapCoconePrecompose_inv_hom] mapConePostcompose_hom_hom attribute [to_dual existing mapCoconePrecompose_hom_hom] mapConePostcompose_inv_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `postcomposeEquivalence` -/ @[to_dual (attr := simps!) /-- `mapCocone` commutes with `precomposeEquivalence` -/] @@ -762,7 +728,6 @@ attribute [to_dual existing mapCoconePrecomposeEquivalenceFunctor_inv_hom] attribute [to_dual existing mapCoconePrecomposeEquivalenceFunctor_hom_hom] mapConePostcomposeEquivalenceFunctor_inv_hom -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- `mapCone` commutes with `whisker` -/ @[to_dual (attr := simps!) /-- `mapCocone` commutes with `whisker` -/] @@ -781,20 +746,19 @@ section variable {F : J ⥤ C} /-- Change a `Cone F` into a `Cocone F.op`. -/ -@[to_dual (attr := simps) /-- Change a `Cocone F` into a `Cone F.op`. -/] +@[to_dual (attr := implicit_reducible, simps) /-- Change a `Cocone F` into a `Cone F.op`. -/] def Cone.op (c : Cone F) : Cocone F.op where pt := Opposite.op c.pt ι := NatTrans.op c.π /-- Change a `Cone F.op` into a `Cocone F`. -/ -@[to_dual (attr := simps) /-- Change a `Cocone F.op` into a `Cone F`. -/] +@[to_dual (attr := implicit_reducible, simps) /-- Change a `Cocone F.op` into a `Cone F`. -/] def Cone.unop (c : Cone F.op) : Cocone F where pt := Opposite.unop c.pt ι := NatTrans.removeOp c.π variable (F) -set_option backward.isDefEq.respectTransparency false in /-- The category of cocones on `F` is equivalent to the opposite category of the category of cones on the opposite of `F`. -/ @@ -823,7 +787,6 @@ def coconeEquivalenceOpConeOp : Cocone F ≌ (Cone F.op)ᵒᵖ where unitIso := Iso.refl _ counitIso := Iso.refl _ -set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : J ⥤ C` are equivalent to cocones on `F.op : Jᵒᵖ ⥤ Cᵒᵖ`. -/ @[to_dual (attr := simps) /-- Cocones on `F : J ⥤ C` are equivalent to cones on `F.op : Jᵒᵖ ⥤ Cᵒᵖ`. -/] @@ -842,20 +805,19 @@ section variable {F : J ⥤ Cᵒᵖ} /-- Change a cocone on `F.leftOp : Jᵒᵖ ⥤ C` to a cocone on `F : J ⥤ Cᵒᵖ`. -/ -@[to_dual (attr := simps!) +@[to_dual (attr := implicit_reducible, simps!) /-- Change a cone on `F.leftOp : Jᵒᵖ ⥤ C` to a cocone on `F : J ⥤ Cᵒᵖ`. -/] def coneOfCoconeLeftOp (c : Cocone F.leftOp) : Cone F where pt := op c.pt π := NatTrans.removeLeftOp c.ι /-- Change a cone on `F : J ⥤ Cᵒᵖ` to a cocone on `F.leftOp : Jᵒᵖ ⥤ C`. -/ -@[to_dual (attr := simps!) +@[to_dual (attr := implicit_reducible, simps!) /-- Change a cocone on `F : J ⥤ Cᵒᵖ` to a cone on `F.leftOp : Jᵒᵖ ⥤ C`. -/] def coconeLeftOpOfCone (c : Cone F) : Cocone F.leftOp where pt := unop c.pt ι := NatTrans.leftOp c.π -set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : J ⥤ Cᵒᵖ` are equivalent to cocones on `F.leftOp : Jᵒᵖ ⥤ C`. -/ @[to_dual (attr := simps) /-- Cocones on `F : J ⥤ Cᵒᵖ` are equivalent to cones on `F.leftOp : Jᵒᵖ ⥤ C`. -/] @@ -874,20 +836,19 @@ section variable {F : Jᵒᵖ ⥤ C} /-- Change a cocone on `F.rightOp : J ⥤ Cᵒᵖ` to a cone on `F : Jᵒᵖ ⥤ C`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Change a cone on `F.rightOp : J ⥤ Cᵒᵖ` to a cocone on `F : Jᵒᵖ ⥤ C`. -/] def coneOfCoconeRightOp (c : Cocone F.rightOp) : Cone F where pt := unop c.pt π := NatTrans.removeRightOp c.ι /-- Change a cone on `F : Jᵒᵖ ⥤ C` to a cocone on `F.rightOp : Jᵒᵖ ⥤ C`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Change a cocone on `F : Jᵒᵖ ⥤ C` to a cone on `F.rightOp : J ⥤ Cᵒᵖ`. -/] def coconeRightOpOfCone (c : Cone F) : Cocone F.rightOp where pt := op c.pt ι := NatTrans.rightOp c.π -set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : Jᵒᵖ ⥤ C` are equivalent to cocones on `F.rightOp : J ⥤ Cᵒᵖ`. -/ @[to_dual (attr := simps) /-- Cocones on `F : Jᵒᵖ ⥤ C` are equivalent to cones on `F.rightOp : J ⥤ Cᵒᵖ`. -/] @@ -906,20 +867,19 @@ section variable {F : Jᵒᵖ ⥤ Cᵒᵖ} /-- Change a cocone on `F.unop : J ⥤ C` into a cone on `F : Jᵒᵖ ⥤ Cᵒᵖ`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Change a cone on `F.unop : J ⥤ C` into a cocone on `F : Jᵒᵖ ⥤ Cᵒᵖ`. -/] def coneOfCoconeUnop (c : Cocone F.unop) : Cone F where pt := op c.pt π := NatTrans.removeUnop c.ι /-- Change a cone on `F : Jᵒᵖ ⥤ Cᵒᵖ` into a cocone on `F.unop : J ⥤ C`. -/ -@[to_dual (attr := simps) +@[to_dual (attr := implicit_reducible, simps) /-- Change a cocone on `F : Jᵒᵖ ⥤ Cᵒᵖ` into a cone on `F.unop : J ⥤ C`. -/] def coconeUnopOfCone (c : Cone F) : Cocone F.unop where pt := unop c.pt ι := NatTrans.unop c.π -set_option backward.isDefEq.respectTransparency.types false in /-- Cones on `F : Jᵒᵖ ⥤ Cᵒᵖ` are equivalent to cocones on `F.unop : J ⥤ C`. -/ @[to_dual (attr := simps) /-- Cocones on `F : Jᵒᵖ ⥤ Cᵒᵖ` are equivalent to cones on `F.unop : J ⥤ C`. -/] @@ -941,7 +901,6 @@ open CategoryTheory.Limits variable {F : J ⥤ C} (G : C ⥤ D) -set_option backward.isDefEq.respectTransparency.types false in set_option linter.translate.warnInvalid false in /-- The opposite cocone of the image of a cone is the image of the opposite cocone. -/ @[to_dual (attr := simps!) diff --git a/Mathlib/CategoryTheory/Limits/HasLimits.lean b/Mathlib/CategoryTheory/Limits/HasLimits.lean index b92a031ebd32a5..de2746e77dc133 100644 --- a/Mathlib/CategoryTheory/Limits/HasLimits.lean +++ b/Mathlib/CategoryTheory/Limits/HasLimits.lean @@ -228,7 +228,6 @@ theorem limit.existsUnique {F : J ⥤ C} [HasLimit F] (t : Cone F) : def limit.isoLimitCone {F : J ⥤ C} [HasLimit F] (t : LimitCone F) : limit F ≅ t.cone.pt := IsLimit.conePointUniqueUpToIso (limit.isLimit F) t.isLimit -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem limit.isoLimitCone_hom_π {F : J ⥤ C} [HasLimit F] (t : LimitCone F) (j : J) : (limit.isoLimitCone t).hom ≫ t.cone.π.app j = limit.π F j := by @@ -250,7 +249,6 @@ instance isIso_limMap {F G : J ⥤ C} [HasLimit F] [HasLimit G] (α : F ⟶ G) [ IsIso (limMap α) := ⟨limMap (inv α), by cat_disch , by cat_disch⟩ -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem limit.lift_map {F G : J ⥤ C} [HasLimit F] [HasLimit G] (c : Cone F) (α : F ⟶ G) : limit.lift F c ≫ limMap α = limit.lift G ((Cone.postcompose α).obj c) := by @@ -284,7 +282,6 @@ def limit.homIso' (F : J ⥤ C) [HasLimit F] (W : C) : { p : ∀ j, W ⟶ F.obj j // ∀ {j j' : J} (f : j ⟶ j'), p j ≫ F.map f = p j' } := (limit.isLimit F).homIso' W -set_option backward.isDefEq.respectTransparency false in theorem limit.lift_extend {F : J ⥤ C} [HasLimit F] (c : Cone F) {X : C} (f : X ⟶ c.pt) : limit.lift F (c.extend f) = f ≫ limit.lift F c := by cat_disch @@ -344,7 +341,6 @@ def HasLimit.isoOfEquivalence {F : J ⥤ C} [HasLimit F] {G : K ⥤ C} [HasLimit IsLimit.conePointsIsoOfEquivalence (limit.isLimit F) (limit.isLimit G) e w set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem HasLimit.isoOfEquivalence_hom_π {F : J ⥤ C} [HasLimit F] {G : K ⥤ C} [HasLimit G] (e : J ≌ K) (w : e.functor ⋙ G ≅ F) (k : K) : @@ -354,7 +350,6 @@ theorem HasLimit.isoOfEquivalence_hom_π {F : J ⥤ C} [HasLimit F] {G : K ⥤ C simp set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem HasLimit.isoOfEquivalence_inv_π {F : J ⥤ C} [HasLimit F] {G : K ⥤ C} [HasLimit G] (e : J ≌ K) (w : e.functor ⋙ G ≅ F) (j : J) : @@ -373,12 +368,10 @@ variable [HasLimit F] (E : K ⥤ J) [HasLimit (E ⋙ F)] def limit.pre : limit F ⟶ limit (E ⋙ F) := limit.lift (E ⋙ F) ((limit.cone F).whisker E) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem limit.pre_π (k : K) : limit.pre F E ≫ limit.π (E ⋙ F) k = limit.π F (E.obj k) := by simp [limit.pre] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem limit.lift_pre (c : Cone F) : limit.lift F c ≫ limit.pre F E = limit.lift (E ⋙ F) (c.whisker E) := by ext; simp @@ -394,7 +387,6 @@ theorem limit.pre_pre [h : HasLimit (D ⋙ E ⋙ F)] : haveI : HasLimit ((D ⋙ variable {E F} -set_option backward.isDefEq.respectTransparency false in /-- If we have particular limit cones available for `E ⋙ F` and for `F`, we obtain a formula for `limit.pre F E`. @@ -415,12 +407,10 @@ variable (F : J ⥤ C) [HasLimit F] (G : C ⥤ D) [HasLimit (F ⋙ G)] def limit.post : G.obj (limit F) ⟶ limit (F ⋙ G) := limit.lift (F ⋙ G) (G.mapCone (limit.cone F)) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem limit.post_π (j : J) : limit.post F G ≫ limit.π (F ⋙ G) j = G.map (limit.π F j) := by simp [limit.post] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem limit.lift_post (c : Cone F) : G.map (limit.lift F c) ≫ limit.post F G = limit.lift (F ⋙ G) (G.mapCone c) := by @@ -488,7 +478,6 @@ def lim : (J ⥤ C) ⥤ C where apply Limits.limit.hom_ext; intro j simp [assoc] -set_option backward.isDefEq.respectTransparency false in /-- The natural transformation induced by `limit.π`. -/ @[simps] def lim.π (j : J) : lim ⟶ (evaluation J C).obj j where @@ -500,13 +489,11 @@ variable {G : J ⥤ C} (α : F ⟶ G) theorem limMap_eq : limMap α = lim.map α := rfl -set_option backward.isDefEq.respectTransparency false in theorem limit.map_pre [HasLimitsOfShape K C] (E : K ⥤ J) : lim.map α ≫ limit.pre G E = limit.pre F E ≫ lim.map (whiskerLeft E α) := by ext simp -set_option backward.isDefEq.respectTransparency false in theorem limit.map_pre' [HasLimitsOfShape K C] (F : J ⥤ C) {E₁ E₂ : K ⥤ J} (α : E₁ ⟶ E₂) : limit.pre F E₂ = limit.pre F E₁ ≫ lim.map (whiskerRight α F) := by ext1; simp @@ -532,8 +519,6 @@ def limYoneda : lim ⋙ yoneda ⋙ (whiskeringRight _ _ _).obj uliftFunctor.{u₁} ≅ CategoryTheory.cones J C := NatIso.ofComponents fun F => NatIso.ofComponents fun W => limit.homIso F (unop W) -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The constant functor and limit functor are adjoint to each other -/ def constLimAdj : (const J : C ⥤ J ⥤ C) ⊣ lim := Adjunction.mk' { homEquiv := fun c g ↦ @@ -811,7 +796,6 @@ theorem colimit.isoColimitCocone_ι_hom {F : J ⥤ C} [HasColimit F] (t : Colimi dsimp [colimit.isoColimitCocone, IsColimit.coconePointUniqueUpToIso] simp -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem colimit.isoColimitCocone_ι_inv {F : J ⥤ C} [HasColimit F] (t : ColimitCocone F) (j : J) : t.cocone.ι.app j ≫ (colimit.isoColimitCocone t).inv = colimit.ι F j := by @@ -855,7 +839,6 @@ def colimit.homIso' (F : J ⥤ C) [HasColimit F] (W : C) : { p : ∀ j, F.obj j ⟶ W // ∀ {j j'} (f : j ⟶ j'), F.map f ≫ p j' = p j } := (colimit.isColimit F).homIso' W -set_option backward.isDefEq.respectTransparency false in theorem colimit.desc_extend (F : J ⥤ C) [HasColimit F] (c : Cocone F) {X : C} (f : c.pt ⟶ X) : colimit.desc F (c.extend f) = colimit.desc F c ≫ f := by ext; simp @@ -916,7 +899,6 @@ def HasColimit.isoOfEquivalence {F : J ⥤ C} [HasColimit F] {G : K ⥤ C} [HasC IsColimit.coconePointsIsoOfEquivalence (colimit.isColimit F) (colimit.isColimit G) e w set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem HasColimit.ι_isoOfEquivalence_hom {F : J ⥤ C} [HasColimit F] {G : K ⥤ C} [HasColimit G] (e : J ≌ K) (w : e.functor ⋙ G ≅ F) (j : J) : @@ -925,7 +907,6 @@ theorem HasColimit.ι_isoOfEquivalence_hom {F : J ⥤ C} [HasColimit F] {G : K simp [HasColimit.isoOfEquivalence] set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem HasColimit.ι_isoOfEquivalence_inv {F : J ⥤ C} [HasColimit F] {G : K ⥤ C} [HasColimit G] (e : J ≌ K) (w : e.functor ⋙ G ≅ F) (k : K) : @@ -949,7 +930,6 @@ variable [HasColimit F] (E : K ⥤ J) [HasColimit (E ⋙ F)] def colimit.pre : colimit (E ⋙ F) ⟶ colimit F := colimit.desc (E ⋙ F) ((colimit.cocone F).whisker E) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem colimit.ι_pre (k : K) : colimit.ι (E ⋙ F) k ≫ colimit.pre F E = colimit.ι F (E.obj k) := by simp [colimit.pre] @@ -959,7 +939,6 @@ theorem colimit.ι_inv_pre [IsIso (pre F E)] (k : K) : colimit.ι F (E.obj k) ≫ inv (colimit.pre F E) = colimit.ι (E ⋙ F) k := by simp [IsIso.comp_inv_eq] -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem colimit.pre_desc (c : Cocone F) : colimit.pre F E ≫ colimit.desc F c = colimit.desc (E ⋙ F) (c.whisker E) := by @@ -980,7 +959,6 @@ theorem colimit.pre_pre [h : HasColimit (D ⋙ E ⋙ F)] : variable {E F} -set_option backward.isDefEq.respectTransparency false in /-- If we have particular colimit cocones available for `E ⋙ F` and for `F`, we obtain a formula for `colimit.pre F E`. @@ -1005,13 +983,11 @@ to `G` applied to the colimit of `F`. def colimit.post : colimit (F ⋙ G) ⟶ G.obj (colimit F) := colimit.desc (F ⋙ G) (G.mapCocone (colimit.cocone F)) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem colimit.ι_post (j : J) : colimit.ι (F ⋙ G) j ≫ colimit.post F G = G.map (colimit.ι F j) := by simp [colimit.post] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem colimit.post_desc (c : Cocone F) : colimit.post F G ≫ G.map (colimit.desc F c) = colimit.desc (F ⋙ G) (G.mapCocone c) := by @@ -1076,7 +1052,6 @@ def colim : (J ⥤ C) ⥤ C where obj F := colimit F map α := colimMap α -set_option backward.isDefEq.respectTransparency false in /-- The natural transformation induced by `colimit.ι`. -/ @[simps] def colim.ι (j : J) : (evaluation J C).obj j ⟶ colim where @@ -1088,35 +1063,29 @@ variable {G : J ⥤ C} (α : F ⟶ G) theorem colimMap_eq : colimMap α = colim.map α := rfl -set_option backward.isDefEq.respectTransparency false in -- This seems to be needed in downstream files. @[reassoc] theorem colimit.ι_map (j : J) : colimit.ι F j ≫ colim.map α = α.app j ≫ colimit.ι G j := by simp -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem colimit.map_desc (c : Cocone G) : colimMap α ≫ colimit.desc G c = colimit.desc F ((Cocone.precompose α).obj c) := by ext j simp [colimit.ι_desc, colimit.ι_desc] -set_option backward.isDefEq.respectTransparency false in theorem colimit.pre_map [HasColimitsOfShape K C] (E : K ⥤ J) : colimit.pre F E ≫ colim.map α = colim.map (whiskerLeft E α) ≫ colimit.pre G E := by ext rw [← assoc, colimit.ι_pre, colimit.ι_map, ← assoc, colimit.ι_map, assoc, colimit.ι_pre] rfl -set_option backward.isDefEq.respectTransparency false in theorem colimit.pre_map' [HasColimitsOfShape K C] (F : J ⥤ C) {E₁ E₂ : K ⥤ J} (α : E₁ ⟶ E₂) : colimit.pre F E₁ = colim.map (whiskerRight α F) ≫ colimit.pre F E₂ := by ext1 simp -set_option backward.defeqAttrib.useBackward true in theorem colimit.pre_id (F : J ⥤ C) : colimit.pre F (𝟭 _) = colim.map (Functor.leftUnitor F).hom := by cat_disch -set_option backward.isDefEq.respectTransparency false in theorem colimit.map_post {D : Type u'} [Category.{v'} D] [HasColimitsOfShape J D] (H : C ⥤ D) : /- H (colimit F) ⟶ H (colimit G) ⟶ colimit (G ⋙ H) vs @@ -1139,8 +1108,6 @@ def colimCoyoneda : colim.op ⋙ coyoneda ⋙ (whiskeringRight _ _ _).obj uliftF ≅ CategoryTheory.cocones J C := NatIso.ofComponents fun F => NatIso.ofComponents fun W => colimit.homIso (unop F) W -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The colimit functor and constant functor are adjoint to each other -/ def colimConstAdj : (colim : (J ⥤ C) ⥤ C) ⊣ const J := Adjunction.mk' { @@ -1212,7 +1179,6 @@ end Colimit section Opposite -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `t : Cone F` is a limit cone, then `t.op : Cocone F.op` is a colimit cocone. -/ @@ -1228,7 +1194,6 @@ def IsLimit.op {t : Cone F} (P : IsLimit t) : IsColimit t.op where rw [← w] rfl -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- If `t : Cocone F` is a colimit cocone, then `t.op : Cone F.op` is a limit cone. -/ diff --git a/Mathlib/CategoryTheory/Limits/IsLimit.lean b/Mathlib/CategoryTheory/Limits/IsLimit.lean index 76d8b75138b394..74de4a1b949df8 100644 --- a/Mathlib/CategoryTheory/Limits/IsLimit.lean +++ b/Mathlib/CategoryTheory/Limits/IsLimit.lean @@ -61,7 +61,6 @@ structure IsLimit (t : Cone F) where uniq : ∀ (s : Cone F) (m : s.pt ⟶ t.pt) (_ : ∀ j : J, m ≫ t.π.app j = s.π.app j), m = lift s := by cat_disch -set_option backward.defeqAttrib.useBackward true in /-- A cocone `t` on `F` is a colimit cocone if each cocone on `F` admits a unique cocone morphism from `t`. -/ @[stacks 002F, to_dual] @@ -93,9 +92,6 @@ of a colimit cocone over `F` to the cocone point of any cocone over `G`. -/] def map {F G : J ⥤ C} (s : Cone F) {t : Cone G} (P : IsLimit t) (α : F ⟶ G) : s.pt ⟶ t.pt := P.lift ((Cone.postcompose α).obj s) -#adaptation_note -/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) (reorder := c hd d) ι_map] theorem map_π {F G : J ⥤ C} (c : Cone F) {d : Cone G} (hd : IsLimit d) (α : F ⟶ G) (j : J) : hd.map c α ≫ d.π.app j = c.π.app j ≫ α.app j := @@ -178,13 +174,11 @@ theorem conePointUniqueUpToIso_inv_comp {s t : Cone F} (P : IsLimit s) (Q : IsLi (conePointUniqueUpToIso P Q).inv ≫ s.π.app j = t.π.app j := (uniqueUpToIso P Q).inv.w _ -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) coconePointUniqueUpToIso_inv_desc] theorem lift_comp_conePointUniqueUpToIso_hom {r s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : P.lift r ≫ (conePointUniqueUpToIso P Q).hom = Q.lift r := Q.uniq _ _ (by simp) -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) coconePointUniqueUpToIso_hom_desc] theorem lift_comp_conePointUniqueUpToIso_inv {r s t : Cone F} (P : IsLimit s) (Q : IsLimit t) : Q.lift r ≫ (conePointUniqueUpToIso P Q).inv = P.lift r := @@ -236,14 +230,11 @@ def ofPointIso {r t : Cone F} (P : IsLimit r) [i : IsIso (P.lift t)] : IsLimit t variable {t : Cone F} -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in @[to_dual] theorem hom_lift (h : IsLimit t) {W : C} (m : W ⟶ t.pt) : m = h.lift { pt := W, π := { app := fun b => m ≫ t.π.app b } } := h.uniq { pt := W, π := { app := fun b => m ≫ t.π.app b } } m fun _ => rfl -set_option backward.isDefEq.respectTransparency.types false in /-- Two morphisms into a limit are equal if their compositions with each cone morphism are equal. -/ @[to_dual /-- Two morphisms out of a colimit are equal if their compositions with @@ -253,7 +244,6 @@ theorem hom_ext (h : IsLimit t) {W : C} {f f' : W ⟶ t.pt} f = f' := by rw [h.hom_lift f, h.hom_lift f']; congr; exact funext w -set_option backward.isDefEq.respectTransparency.types false in @[to_dual] lemma nonempty_isLimit_iff_isIso_lift {s t : Cone F} (hs : IsLimit s) : Nonempty (IsLimit t) ↔ IsIso (hs.lift t) := @@ -347,7 +337,6 @@ def equivOfNatIsoOfIso {F G : J ⥤ C} (α : F ≅ G) (c : Cone F) (d : Cone G) (w : (Cone.postcompose α.hom).obj c ≅ d) : IsLimit c ≃ IsLimit d := (postcomposeHomEquiv α _).symm.trans (equivIsoLimit w) -set_option backward.defeqAttrib.useBackward true in set_option linter.translate.warnInvalid false in /-- The cone points of two limit cones for naturally isomorphic functors are themselves isomorphic. @@ -368,7 +357,6 @@ attribute [to_dual existing coconePointsIsoOfNatIso_hom] conePointsIsoOfNatIso_i #adaptation_note /-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_inv] theorem conePointsIsoOfNatIso_hom_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) (j : J) : @@ -376,7 +364,6 @@ theorem conePointsIsoOfNatIso_hom_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} #adaptation_note /-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc) comp_coconePointsIsoOfNatIso_hom] theorem conePointsIsoOfNatIso_inv_comp {F G : J ⥤ C} {s : Cone F} {t : Cone G} (P : IsLimit s) (Q : IsLimit t) (w : F ≅ G) (j : J) : @@ -445,7 +432,6 @@ def extendIsoEquiv {s : Cone F} {X : C} (i : X ⟶ s.pt) [IsIso i] : equivOfSubsingletonOfSubsingleton (extendIso i) (ofExtendIso i) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in set_option linter.translate.warnInvalid false in /-- We can prove two cone points `(s : Cone F).pt` and `(t : Cone G).pt` are isomorphic if * both cones are limit cones @@ -487,7 +473,6 @@ attribute [to_dual existing coconePointsIsoOfEquivalence_hom] conePointsIsoOfEqu end Equivalence -set_option backward.defeqAttrib.useBackward true in /-- The universal property of a limit cone: a map `W ⟶ t.pt` is the same as a cone on `F` with cone point `W`. -/ @[to_dual (attr := simps apply) @@ -499,14 +484,12 @@ def homEquiv (h : IsLimit t) {W : C} : (W ⟶ t.pt) ≃ ((Functor.const J).obj W left_inv f := h.hom_ext (by simp) right_inv π := by cat_disch -set_option backward.isDefEq.respectTransparency.types false in @[to_dual (attr := reassoc (attr := simp)) ι_app_homEquiv_symm] lemma homEquiv_symm_π_app (h : IsLimit t) {W : C} (f : (const J).obj W ⟶ F) (j : J) : h.homEquiv.symm f ≫ t.π.app j = f.app j := by simp [homEquiv] -set_option backward.defeqAttrib.useBackward true in @[to_dual] lemma homEquiv_symm_naturality (h : IsLimit t) {W W' : C} (f : (const J).obj W ⟶ F) (g : W' ⟶ W) : @@ -533,7 +516,6 @@ set_option backward.defeqAttrib.useBackward true in def natIso (h : IsLimit t) : yoneda.obj t.pt ⋙ uliftFunctor.{u₁} ≅ F.cones := by refine NatIso.ofComponents (fun W => IsLimit.homIso h (unop W)) -set_option backward.defeqAttrib.useBackward true in /-- Another, more explicit, formulation of the universal property of a limit cone. See also `homIso`. -/ def homIso' (h : IsLimit t) (W : C) : @@ -594,6 +576,7 @@ variable {X : C} (h : F.cones.RepresentableBy X) /-- If `F.cones` is represented by `X`, each morphism `f : Y ⟶ X` gives a cone with cone point `Y`. -/ +@[implicit_reducible] def coneOfHom {Y : C} (f : Y ⟶ X) : Cone F where pt := Y π := h.homEquiv f @@ -610,13 +593,13 @@ theorem coneOfHom_homOfCone (s : Cone F) : coneOfHom h (homOfCone h s) = s := by congr exact h.homEquiv.apply_symm_apply s_π -set_option backward.isDefEq.respectTransparency false in @[simp] theorem homOfCone_coneOfHom {Y : C} (f : Y ⟶ X) : homOfCone h (coneOfHom h f) = f := by simp [coneOfHom, homOfCone] /-- If `F.cones` is represented by `X`, the cone corresponding to the identity morphism on `X` will be a limit cone. -/ +@[implicit_reducible] def limitCone : Cone F := coneOfHom h (𝟙 X) @@ -641,7 +624,6 @@ section open OfNatIso -set_option backward.isDefEq.respectTransparency.types false in /-- If `F.cones` is representable, then the cone corresponding to the identity morphism on the representing object is a limit cone. -/ @@ -689,7 +671,6 @@ set_option backward.defeqAttrib.useBackward true in def natIso (h : IsColimit t) : coyoneda.obj (op t.pt) ⋙ uliftFunctor.{u₁} ≅ F.cocones := NatIso.ofComponents (IsColimit.homIso h) -set_option backward.defeqAttrib.useBackward true in /-- Another, more explicit, formulation of the universal property of a colimit cocone. See also `homIso`. -/ def homIso' (h : IsColimit t) (W : C) : @@ -703,7 +684,6 @@ def homIso' (h : IsColimit t) (W : C) : naturality := fun j j' f => by dsimp; rw [comp_id]; exact p.2 f } } -set_option backward.defeqAttrib.useBackward true in /-- A cocone is a colimit cocone exactly if there is a unique cocone morphism from any other cocone. -/ @@ -722,6 +702,7 @@ variable {X : C} (h : F.cocones.CorepresentableBy X) /-- If `F.cocones` is corepresented by `X`, each morphism `f : X ⟶ Y` gives a cocone with cone point `Y`. -/ +@[implicit_reducible] def coconeOfHom {Y : C} (f : X ⟶ Y) : Cocone F where pt := Y ι := h.homEquiv f @@ -738,13 +719,13 @@ theorem coconeOfHom_homOfCocone (s : Cocone F) : coconeOfHom h (homOfCocone h s) congr exact h.homEquiv.apply_symm_apply s_ι -set_option backward.isDefEq.respectTransparency false in @[simp] theorem homOfCocone_coconeOfHom {Y : C} (f : X ⟶ Y) : homOfCocone h (coconeOfHom h f) = f := by simp [homOfCocone, coconeOfHom] /-- If `F.cocones` is corepresented by `X`, the cocone corresponding to the identity morphism on `X` will be a colimit cocone. -/ +@[implicit_reducible] def colimitCocone : Cocone F := coconeOfHom h (𝟙 X) @@ -769,7 +750,6 @@ section open OfNatIso -set_option backward.isDefEq.respectTransparency.types false in /-- If `F.cocones` is corepresentable, then the cocone corresponding to the identity morphism on the representing object is a colimit cocone. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean index 350bffea6953f0..0435283dd9e285 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean @@ -114,8 +114,9 @@ theorem walkingParallelPairHom_id (X : WalkingParallelPair) : WalkingParallelPai /-- The functor `WalkingParallelPair ⥤ WalkingParallelPairᵒᵖ` sending left to left and right to right. -/ +@[implicit_reducible] def walkingParallelPairOp : WalkingParallelPair ⥤ WalkingParallelPairᵒᵖ where - obj x := op <| by cases x; exacts [one, zero] + obj x := op <| match x with | zero => one | one => zero map f := by cases f <;> apply Quiver.Hom.op exacts [left, right, WalkingParallelPairHom.id _] @@ -135,8 +136,6 @@ theorem walkingParallelPairOp_left : theorem walkingParallelPairOp_right : walkingParallelPairOp.map right = @Quiver.Hom.op _ _ zero one right := rfl -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The equivalence `WalkingParallelPair ⥤ WalkingParallelPairᵒᵖ` sending left to left and right to right. @@ -253,6 +252,7 @@ variable [Category.{v} C] open parallelPair in /-- `parallelPair f g` is the diagram in `C` consisting of the two morphisms `f` and `g` with common domain and codomain. -/ +@[implicit_reducible] def parallelPair (f g : X ⟶ Y) : WalkingParallelPair ⥤ C where obj x := parallelPairObj X Y x map h := parallelPairHom f g h @@ -274,7 +274,6 @@ theorem parallelPair_map_right (f g : X ⟶ Y) : (parallelPair f g).map right = theorem parallelPair_functor_obj {F : WalkingParallelPair ⥤ C} (j : WalkingParallelPair) : (parallelPair (F.map left) (F.map right)).obj j = F.obj j := by cases j <;> rfl -set_option backward.isDefEq.respectTransparency.types false in /-- Every functor indexing a (co)equalizer is naturally isomorphic (actually, equal) to a `parallelPair` -/ @[simps!] @@ -374,27 +373,22 @@ def Cofork.π (t : Cofork f g) : Y ⟶ t.pt := theorem Cofork.app_one_eq_π (t : Cofork f g) : t.ι.app one = t.π := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] theorem Fork.app_one_eq_ι_comp_left (s : Fork f g) : s.π.app one = s.ι ≫ f := by rw [← s.app_zero_eq_ι, ← s.w left, parallelPair_map_left] -set_option backward.isDefEq.respectTransparency false in @[reassoc] theorem Fork.app_one_eq_ι_comp_right (s : Fork f g) : s.π.app one = s.ι ≫ g := by rw [← s.app_zero_eq_ι, ← s.w right, parallelPair_map_right] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem Cofork.app_zero_eq_comp_π_left (s : Cofork f g) : s.ι.app zero = f ≫ s.π := by rw [← s.app_one_eq_π, ← s.w left, parallelPair_map_left] -set_option backward.isDefEq.respectTransparency false in @[reassoc] theorem Cofork.app_zero_eq_comp_π_right (s : Cofork f g) : s.ι.app zero = g ≫ s.π := by rw [← s.app_one_eq_π, ← s.w right, parallelPair_map_right] -set_option backward.defeqAttrib.useBackward true in /-- A fork on `f g : X ⟶ Y` is determined by the morphism `ι : P ⟶ X` satisfying `ι ≫ f = ι ≫ g`. -/ @[simps, implicit_reducible] @@ -408,7 +402,6 @@ def Fork.ofι {P : C} (ι : P ⟶ X) (w : ι ≫ f = ι ≫ g) : Fork f g where naturality := fun {X} {Y} f => by cases X <;> cases Y <;> cases f <;> simp [w] } -set_option backward.defeqAttrib.useBackward true in /-- A cofork on `f g : X ⟶ Y` is determined by the morphism `π : Y ⟶ P` satisfying `f ≫ π = g ≫ π`. -/ @[simps, implicit_reducible] @@ -434,7 +427,6 @@ theorem Fork.condition (t : Fork f g) : t.ι ≫ f = t.ι ≫ g := by theorem Cofork.condition (t : Cofork f g) : f ≫ t.π = g ≫ t.π := by rw [← t.app_zero_eq_comp_π_left, ← t.app_zero_eq_comp_π_right] -set_option backward.isDefEq.respectTransparency false in /-- To check whether two maps are equalized by both maps of a fork, it suffices to check it for the first map -/ theorem Fork.equalizer_ext (s : Fork f g) {W : C} {k l : W ⟶ s.pt} (h : k ≫ s.ι = l ≫ s.ι) : @@ -445,7 +437,6 @@ theorem Fork.equalizer_ext (s : Fork f g) {W : C} {k l : W ⟶ s.pt} (h : k ≫ simp only [← Category.assoc]; exact congrArg (· ≫ f) h rw [s.app_one_eq_ι_comp_left, this] -set_option backward.isDefEq.respectTransparency false in /-- To check whether two maps are coequalized by both maps of a cofork, it suffices to check it for the second map -/ theorem Cofork.coequalizer_ext (s : Cofork f g) {W : C} {k l : s.pt ⟶ W} @@ -538,7 +529,6 @@ def Fork.IsLimit.mk' {X Y : C} {f g : X ⟶ Y} (t : Fork f g) (create : ∀ s : Fork f g, { l // l ≫ t.ι = s.ι ∧ ∀ {m}, m ≫ t.ι = s.ι → m = l }) : IsLimit t := Fork.IsLimit.mk t (fun s => (create s).1) (fun s => (create s).2.1) fun s _ w => (create s).2.2 w -set_option backward.defeqAttrib.useBackward true in /-- This is a slightly more convenient method to verify that a cofork is a colimit cocone. It only asks for a proof of facts that carry any mathematical content -/ def Cofork.IsColimit.mk (t : Cofork f g) (desc : ∀ s : Cofork f g, t.pt ⟶ s.pt) @@ -610,7 +600,6 @@ theorem Cofork.IsColimit.homIso_natural {X Y : C} {f g : X ⟶ Y} {t : Cofork f (Cofork.IsColimit.homIso ht _ k : Y ⟶ Z) ≫ q := (Category.assoc _ _ _).symm -set_option backward.defeqAttrib.useBackward true in /-- This is a helper construction that can be useful when verifying that a category has all equalizers. Given `F : WalkingParallelPair ⥤ C`, which is really the same as `parallelPair (F.map left) (F.map right)`, and a fork on `F.map left` and `F.map right`, @@ -624,8 +613,6 @@ def Cone.ofFork {F : WalkingParallelPair ⥤ C} (t : Fork (F.map left) (F.map ri { app := fun X => t.π.app X ≫ eqToHom (by simp) naturality := by rintro _ _ (_ | _ | _) <;> simp [t.condition] } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- This is a helper construction that can be useful when verifying that a category has all coequalizers. Given `F : WalkingParallelPair ⥤ C`, which is really the same as `parallelPair (F.map left) (F.map right)`, and a cofork on `F.map left` and `F.map right`, @@ -649,7 +636,6 @@ theorem Cone.ofFork_π {F : WalkingParallelPair ⥤ C} (t : Fork (F.map left) (F theorem Cocone.ofCofork_ι {F : WalkingParallelPair ⥤ C} (t : Cofork (F.map left) (F.map right)) (j) : (Cocone.ofCofork t).ι.app j = eqToHom (by simp) ≫ t.ι.app j := rfl -set_option backward.defeqAttrib.useBackward true in /-- Given `F : WalkingParallelPair ⥤ C`, which is really the same as `parallelPair (F.map left) (F.map right)` and a cone on `F`, we get a fork on `F.map left` and `F.map right`. -/ @@ -658,8 +644,6 @@ def Fork.ofCone {F : WalkingParallelPair ⥤ C} (t : Cone F) : Fork (F.map left) π := { app := fun X => t.π.app X ≫ eqToHom (by simp) naturality := by rintro _ _ (_ | _ | _) <;> simp } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- Given `F : WalkingParallelPair ⥤ C`, which is really the same as `parallelPair (F.map left) (F.map right)` and a cocone on `F`, we get a cofork on `F.map left` and `F.map right`. -/ @@ -687,7 +671,6 @@ theorem Cofork.π_precompose {f' g' : X ⟶ Y} {α : parallelPair f g ⟶ parall {c : Cofork f' g'} : Cofork.π ((Cocone.precompose α).obj c) = α.app .one ≫ c.π := rfl -set_option backward.isDefEq.respectTransparency false in /-- Helper function for constructing morphisms between equalizer forks. -/ @[simps] @@ -709,13 +692,11 @@ def Fork.ext {s t : Fork f g} (i : s.pt ≅ t.pt) (w : i.hom ≫ t.ι = s.ι := hom := Fork.mkHom i.hom w inv := Fork.mkHom i.inv (by rw [← w, Iso.inv_hom_id_assoc]) -set_option backward.defeqAttrib.useBackward true in /-- Two forks of the form `ofι` are isomorphic whenever their `ι`'s are equal. -/ def ForkOfι.ext {P : C} {ι ι' : P ⟶ X} (w : ι ≫ f = ι ≫ g) (w' : ι' ≫ f = ι' ≫ g) (h : ι = ι') : Fork.ofι ι w ≅ Fork.ofι ι' w' := Fork.ext (Iso.refl _) (by simp [h]) -set_option backward.defeqAttrib.useBackward true in /-- Every fork is isomorphic to one of the form `Fork.of_ι _ _`. -/ @[simps!] def Fork.isoForkOfι (c : Fork f g) : c ≅ Fork.ofι c.ι c.condition := @@ -804,13 +785,11 @@ def Cofork.ext {s t : Cofork f g} (i : s.pt ≅ t.pt) (w : s.π ≫ i.hom = t.π hom := Cofork.mkHom i.hom w inv := Cofork.mkHom i.inv (by rw [Iso.comp_inv_eq, w]) -set_option backward.defeqAttrib.useBackward true in /-- Two coforks of the form `ofπ` are isomorphic whenever their `π`'s are equal. -/ def CoforkOfπ.ext {P : C} {π π' : Y ⟶ P} (w : f ≫ π = g ≫ π) (w' : f ≫ π' = g ≫ π') (h : π = π') : Cofork.ofπ π w ≅ Cofork.ofπ π' w' := Cofork.ext (Iso.refl _) (by simp [h]) -set_option backward.defeqAttrib.useBackward true in /-- Every cofork is isomorphic to one of the form `Cofork.ofπ _ _`. -/ def Cofork.isoCoforkOfπ (c : Cofork f g) : c ≅ Cofork.ofπ c.π c.condition := Cofork.ext (Iso.refl _) @@ -879,7 +858,6 @@ theorem equalizer.fork_π_app_zero : (equalizer.fork f g).π.app zero = equalize theorem equalizer.condition : equalizer.ι f g ≫ f = equalizer.ι f g ≫ g := Fork.condition <| limit.cone <| parallelPair f g -set_option backward.defeqAttrib.useBackward true in /-- The equalizer built from `equalizer.ι f g` is limiting. -/ noncomputable def equalizerIsEqualizer : IsLimit (Fork.ofι (equalizer.ι f g) (equalizer.condition f g)) := @@ -934,17 +912,16 @@ section variable {f g} /-- The identity determines a cone on the equalizer diagram of `f` and `g` if `f = g`. -/ +@[implicit_reducible] def idFork (h : f = g) : Fork f g := Fork.ofι (𝟙 X) <| h ▸ rfl -set_option backward.isDefEq.respectTransparency.types false in /-- The identity on `X` is an equalizer of `(f, g)`, if `f = g`. -/ def isLimitIdFork (h : f = g) : IsLimit (idFork h) := Fork.IsLimit.mk _ (fun s => Fork.ι s) (fun _ => Category.comp_id _) fun s m h => by convert! h exact (Category.comp_id _).symm -set_option backward.isDefEq.respectTransparency.types false in /-- Every equalizer of `(f, g)`, where `f = g`, is an isomorphism. -/ theorem isIso_limit_cone_parallelPair_of_eq (h₀ : f = g) {c : Fork f g} (h : IsLimit c) : IsIso c.ι := @@ -989,7 +966,6 @@ noncomputable def equalizer.isoSourceOfSelf : equalizer f f ≅ X := theorem equalizer.isoSourceOfSelf_hom : (equalizer.isoSourceOfSelf f).hom = equalizer.ι f f := rfl -set_option backward.isDefEq.respectTransparency false in @[simp] theorem equalizer.isoSourceOfSelf_inv : (equalizer.isoSourceOfSelf f).inv = equalizer.lift (𝟙 X) (by simp) := by @@ -1089,7 +1065,6 @@ theorem coequalizer.cofork_ι_app_one : (coequalizer.cofork f g).ι.app one = co theorem coequalizer.condition : f ≫ coequalizer.π f g = g ≫ coequalizer.π f g := Cofork.condition <| colimit.cocone <| parallelPair f g -set_option backward.defeqAttrib.useBackward true in /-- The cofork built from `coequalizer.π f g` is colimiting. -/ noncomputable def coequalizerIsCoequalizer : IsColimit (Cofork.ofπ (coequalizer.π f g) (coequalizer.condition f g)) := @@ -1108,7 +1083,6 @@ theorem coequalizer.π_desc {W : C} (k : Y ⟶ W) (h : f ≫ k = g ≫ k) : coequalizer.π f g ≫ coequalizer.desc k h = k := colimit.ι_desc _ _ -set_option backward.isDefEq.respectTransparency false in theorem coequalizer.π_colimMap_desc {X' Y' Z : C} (f' g' : X' ⟶ Y') [HasCoequalizer f' g'] (p : X ⟶ X') (q : Y ⟶ Y') (wf : f ≫ q = p ≫ f') (wg : g ≫ q = p ≫ g') (h : Y' ⟶ Z) (wh : f' ≫ h = g' ≫ h) : @@ -1154,17 +1128,16 @@ section variable {f g} /-- The identity determines a cocone on the coequalizer diagram of `f` and `g`, if `f = g`. -/ +@[implicit_reducible] def idCofork (h : f = g) : Cofork f g := Cofork.ofπ (𝟙 Y) <| h ▸ rfl -set_option backward.isDefEq.respectTransparency.types false in /-- The identity on `Y` is a coequalizer of `(f, g)`, where `f = g`. -/ def isColimitIdCofork (h : f = g) : IsColimit (idCofork h) := Cofork.IsColimit.mk _ (fun s => Cofork.π s) (fun _ => Category.id_comp _) fun s m h => by convert! h exact (Category.id_comp _).symm -set_option backward.isDefEq.respectTransparency.types false in /-- Every coequalizer of `(f, g)`, where `f = g`, is an isomorphism. -/ theorem isIso_colimit_cocone_parallelPair_of_eq (h₀ : f = g) {c : Cofork f g} (h : IsColimit c) : IsIso c.π := @@ -1206,7 +1179,6 @@ instance coequalizer.π_of_self : IsIso (coequalizer.π f f) := noncomputable def coequalizer.isoTargetOfSelf : coequalizer f f ≅ Y := (asIso (coequalizer.π f f)).symm -set_option backward.isDefEq.respectTransparency false in @[simp] theorem coequalizer.isoTargetOfSelf_hom : (coequalizer.isoTargetOfSelf f).hom = coequalizer.desc (𝟙 Y) (by simp) := by @@ -1235,7 +1207,6 @@ theorem equalizerComparison_comp_π [HasEqualizer f g] [HasEqualizer (G.map f) ( equalizerComparison f g G ≫ equalizer.ι (G.map f) (G.map g) = G.map (equalizer.ι f g) := equalizer.lift_ι _ _ -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem map_lift_equalizerComparison [HasEqualizer f g] [HasEqualizer (G.map f) (G.map g)] {Z : C} {h : Z ⟶ X} (w : h ≫ f = h ≫ g) : @@ -1255,7 +1226,6 @@ theorem ι_comp_coequalizerComparison [HasCoequalizer f g] [HasCoequalizer (G.ma coequalizer.π _ _ ≫ coequalizerComparison f g G = G.map (coequalizer.π _ _) := coequalizer.π_desc _ _ -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem coequalizerComparison_map_desc [HasCoequalizer f g] [HasCoequalizer (G.map f) (G.map g)] {Z : C} {h : Y ⟶ Z} (w : f ≫ h = g ≫ h) : @@ -1327,7 +1297,6 @@ def splitMonoOfEqualizer {X Y : C} {f : X ⟶ Y} {r : Y ⟶ X} (hr : f ≫ r ≫ variable {C f g} -set_option backward.isDefEq.respectTransparency false in /-- The fork obtained by postcomposing an equalizer fork with a monomorphism is an equalizer. -/ def isEqualizerCompMono {c : Fork f g} (i : IsLimit c) {Z : C} (h : Y ⟶ Z) [hm : Mono h] : have : Fork.ι c ≫ f ≫ h = Fork.ι c ≫ g ≫ h := by @@ -1348,7 +1317,6 @@ theorem hasEqualizer_comp_mono [HasEqualizer f g] {Z : C} (h : Y ⟶ Z) [Mono h] ⟨⟨{ cone := _ isLimit := isEqualizerCompMono (limit.isLimit _) h }⟩⟩ -set_option backward.isDefEq.respectTransparency false in /-- An equalizer of an idempotent morphism and the identity is split mono. -/ @[simps] def splitMonoOfIdempotentOfIsLimitFork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Fork (𝟙 X) f} @@ -1406,7 +1374,6 @@ def splitEpiOfCoequalizer {X Y : C} {f : X ⟶ Y} {s : Y ⟶ X} (hs : f ≫ s variable {C f g} -set_option backward.isDefEq.respectTransparency false in /-- The cofork obtained by precomposing a coequalizer cofork with an epimorphism is a coequalizer. -/ def isCoequalizerEpiComp {c : Cofork f g} (i : IsColimit c) {W : C} (h : W ⟶ X) [hm : Epi h] : @@ -1428,7 +1395,6 @@ theorem hasCoequalizer_epi_comp [HasCoequalizer f g] {W : C} (h : W ⟶ X) [Epi variable (C f g) -set_option backward.isDefEq.respectTransparency false in /-- A coequalizer of an idempotent morphism and the identity is split epi. -/ @[simps] def splitEpiOfIdempotentOfIsColimitCofork {X : C} {f : X ⟶ X} (hf : f ≫ f = f) {c : Cofork (𝟙 X) f} diff --git a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean index 2d149581f8a085..9af0efb66f76d6 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean @@ -39,7 +39,6 @@ variable {C : Type u₁} [Category.{v₁} C] #adaptation_note /-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in /-- Construct a cone for the empty diagram given an object. -/ @[simps, implicit_reducible] def asEmptyCone (X : C) : Cone (Functor.empty.{0} C) := @@ -49,9 +48,8 @@ def asEmptyCone (X : C) : Cone (Functor.empty.{0} C) := #adaptation_note /-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in /-- Construct a cocone for the empty diagram given an object. -/ -@[simps] +@[implicit_reducible, simps] def asEmptyCocone (X : C) : Cocone (Functor.empty.{0} C) := { pt := X ι := @@ -80,7 +78,6 @@ def isTerminalEquivUnique (F : Discrete.{0} PEmpty.{1} ⥤ C) (Y : C) : dsimp [Function.RightInverse, Function.LeftInverse] subsingleton -set_option backward.defeqAttrib.useBackward true in /-- An object `Y` is terminal if for every `X` there is a unique morphism `X ⟶ Y` (as an instance). -/ def IsTerminal.ofUnique (Y : C) [h : ∀ X : C, Unique (X ⟶ Y)] : IsTerminal Y where @@ -98,7 +95,6 @@ def IsTerminal.ofUniqueHom {Y : C} (h : ∀ X : C, X ⟶ Y) (uniq : ∀ (X : C) def isTerminalTop {α : Type*} [Preorder α] [OrderTop α] : IsTerminal (⊤ : α) := IsTerminal.ofUnique _ -set_option backward.isDefEq.respectTransparency.types false in /-- Transport a term of type `IsTerminal` across an isomorphism. -/ def IsTerminal.ofIso {Y Z : C} (hY : IsTerminal Y) (i : Y ≅ Z) : IsTerminal Z := IsLimit.ofIsoLimit hY @@ -125,7 +121,6 @@ def isInitialEquivUnique (F : Discrete.{0} PEmpty.{1} ⥤ C) (X : C) : left_inv := by dsimp [Function.LeftInverse]; intro; simp only [eq_iff_true_of_subsingleton] right_inv := by grind -set_option backward.defeqAttrib.useBackward true in /-- An object `X` is initial if for every `Y` there is a unique morphism `X ⟶ Y` (as an instance). -/ def IsInitial.ofUnique (X : C) [h : ∀ Y : C, Unique (X ⟶ Y)] : IsInitial X where @@ -143,7 +138,6 @@ def IsInitial.ofUniqueHom {X : C} (h : ∀ Y : C, X ⟶ Y) (uniq : ∀ (Y : C) ( def isInitialBot {α : Type*} [Preorder α] [OrderBot α] : IsInitial (⊥ : α) := IsInitial.ofUnique _ -set_option backward.isDefEq.respectTransparency.types false in /-- Transport a term of type `IsInitial` across an isomorphism. -/ def IsInitial.ofIso {X Y : C} (hX : IsInitial X) (i : X ≅ Y) : IsInitial Y := IsColimit.ofIsoColimit hX @@ -344,10 +338,9 @@ theorem InitialMonoClass.of_isTerminal {I T : C} (hI : IsInitial I) (hT : IsTerm variable {J : Type u} [Category.{v} J] -set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given an initial object of `J`, construct a cone for `J`. In `limitOfDiagramInitial` we show it is a limit cone. -/ -@[simps] +@[implicit_reducible, simps] def coneOfDiagramInitial {X : J} (tX : IsInitial X) (F : J ⥤ C) : Cone F where pt := F.obj X π := @@ -356,8 +349,6 @@ def coneOfDiagramInitial {X : J} (tX : IsInitial X) (F : J ⥤ C) : Cone F where dsimp rw [← F.map_comp, Category.id_comp, tX.hom_ext (tX.to j ≫ k) (tX.to j')] } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given an initial object of `J`, show the cone `coneOfDiagramInitial` is a limit. -/ def limitOfDiagramInitial {X : J} (tX : IsInitial X) (F : J ⥤ C) : @@ -368,12 +359,10 @@ def limitOfDiagramInitial {X : J} (tX : IsInitial X) (F : J ⥤ C) : simp_rw [← w X, coneOfDiagramInitial_π_app, tX.hom_ext (tX.to X) (𝟙 _)] simp -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- From a functor `F : J ⥤ C`, given a terminal object of `J`, construct a cone for `J`, provided that the morphisms in the diagram are isomorphisms. In `limitOfDiagramTerminal` we show it is a limit cone. -/ -@[simps] +@[implicit_reducible, simps] def coneOfDiagramTerminal {X : J} (hX : IsTerminal X) (F : J ⥤ C) [∀ (i j : J) (f : i ⟶ j), IsIso (F.map f)] : Cone F where pt := F.obj X @@ -385,18 +374,15 @@ def coneOfDiagramTerminal {X : J} (hX : IsTerminal X) (F : J ⥤ C) simp only [IsIso.eq_inv_comp, IsIso.comp_inv_eq, Category.id_comp, ← F.map_comp, hX.hom_ext (hX.from i) (f ≫ hX.from j)] } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given a terminal object of `J` and that the morphisms in the diagram are isomorphisms, show the cone `coneOfDiagramTerminal` is a limit. -/ def limitOfDiagramTerminal {X : J} (hX : IsTerminal X) (F : J ⥤ C) [∀ (i j : J) (f : i ⟶ j), IsIso (F.map f)] : IsLimit (coneOfDiagramTerminal hX F) where lift S := S.π.app _ -set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given a terminal object of `J`, construct a cocone for `J`. In `colimitOfDiagramTerminal` we show it is a colimit cocone. -/ -@[simps] +@[implicit_reducible, simps] def coconeOfDiagramTerminal {X : J} (tX : IsTerminal X) (F : J ⥤ C) : Cocone F where pt := F.obj X ι := @@ -405,8 +391,6 @@ def coconeOfDiagramTerminal {X : J} (tX : IsTerminal X) (F : J ⥤ C) : Cocone F dsimp rw [← F.map_comp, Category.comp_id, tX.hom_ext (k ≫ tX.from j') (tX.from j)] } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given a terminal object of `J`, show the cocone `coconeOfDiagramTerminal` is a colimit. -/ def colimitOfDiagramTerminal {X : J} (tX : IsTerminal X) (F : J ⥤ C) : @@ -420,12 +404,10 @@ lemma IsColimit.isIso_ι_app_of_isTerminal {F : J ⥤ C} {c : Cocone F} (hc : Is change IsIso (coconePointUniqueUpToIso (colimitOfDiagramTerminal hX F) hc).hom infer_instance -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- From a functor `F : J ⥤ C`, given an initial object of `J`, construct a cocone for `J`, provided that the morphisms in the diagram are isomorphisms. In `colimitOfDiagramInitial` we show it is a colimit cocone. -/ -@[simps] +@[implicit_reducible, simps] def coconeOfDiagramInitial {X : J} (hX : IsInitial X) (F : J ⥤ C) [∀ (i j : J) (f : i ⟶ j), IsIso (F.map f)] : Cocone F where pt := F.obj X @@ -437,8 +419,6 @@ def coconeOfDiagramInitial {X : J} (hX : IsInitial X) (F : J ⥤ C) simp only [IsIso.eq_inv_comp, IsIso.comp_inv_eq, Category.comp_id, ← F.map_comp, hX.hom_ext (hX.to i ≫ f) (hX.to j)] } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- From a functor `F : J ⥤ C`, given an initial object of `J` and that the morphisms in the diagram are isomorphisms, show the cone `coconeOfDiagramInitial` is a colimit. -/ def colimitOfDiagramInitial {X : J} (hX : IsInitial X) (F : J ⥤ C) @@ -493,7 +473,6 @@ namespace Functor open Limits variable (C : Type*) [Category* C] {D : Type*} [Category* D] -set_option backward.defeqAttrib.useBackward true in /-- The constant functor returning a specific terminal object is indeed terminal. -/ def isTerminalConst {X : D} (hX : IsTerminal X) : IsTerminal ((Functor.const C).obj X) := @@ -503,7 +482,6 @@ def isTerminalConst {X : D} (hX : IsTerminal X) : lemma isTerminalConst_from_app {X : D} (hX : IsTerminal X) (F : C ⥤ D) (Y : C) : ((isTerminalConst C hX).from F).app Y = hX.from (F.obj Y) := rfl -set_option backward.defeqAttrib.useBackward true in /-- The constant functor returning a specific initial object is indeed initial. -/ def isInitialConst {X : D} (hX : IsInitial X) : IsInitial ((Functor.const C).obj X) := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index 8985bf1198fc4e..277c61c75b79f1 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -228,13 +228,10 @@ lemma Sigma.hom_ext {f : β → C} [HasCoproduct f] {X : C} (g₁ g₂ : ∐ f (h : ∀ (b : β), Sigma.ι f b ≫ g₁ = Sigma.ι f b ≫ g₂) : g₁ = g₂ := colimit.hom_ext (fun ⟨j⟩ => h j) -set_option backward.defeqAttrib.useBackward true in /-- The fan constructed of the projections from the product is limiting. -/ def productIsProduct (f : β → C) [HasProduct f] : IsLimit (Fan.mk _ (Pi.π f)) := IsLimit.ofIsoLimit (limit.isLimit (Discrete.functor f)) (Cone.ext (Iso.refl _)) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The cofan constructed of the inclusions from the coproduct is colimiting. -/ def coproductIsCoproduct (f : β → C) [HasCoproduct f] : IsColimit (Cofan.mk _ (Sigma.ι f)) := IsColimit.ofIsoColimit (colimit.isColimit (Discrete.functor f)) (Cocone.ext (Iso.refl _)) @@ -256,7 +253,6 @@ theorem Sigma.eqToHom_comp_ι {J : Type*} (f : J → C) [HasCoproduct f] {j j' : abbrev Pi.lift {f : β → C} [HasProduct f] {P : C} (p : ∀ b, P ⟶ f b) : P ⟶ ∏ᶜ f := limit.lift _ (Fan.mk P p) -set_option backward.isDefEq.respectTransparency false in @[reassoc, elementwise] theorem Pi.lift_π {β : Type w} {f : β → C} [HasProduct f] {P : C} (p : ∀ b, P ⟶ f b) (b : β) : Pi.lift p ≫ Pi.π f b = p b := by @@ -282,13 +278,11 @@ lemma Fan.nonempty_isLimit_iff_isIso_piLift {f : β → C} [HasProduct f] (c : F abbrev Sigma.desc {f : β → C} [HasCoproduct f] {P : C} (p : ∀ b, f b ⟶ P) : ∐ f ⟶ P := colimit.desc _ (Cofan.mk P p) -set_option backward.isDefEq.respectTransparency false in @[reassoc] theorem Sigma.ι_desc {β : Type w} {f : β → C} [HasCoproduct f] {P : C} (p : ∀ b, f b ⟶ P) (b : β) : Sigma.ι f b ≫ Sigma.desc p = p b := by simp only [colimit.ι_desc, Cofan.mk_ι_app] -set_option backward.isDefEq.respectTransparency false in instance {f : β → C} [HasCoproduct f] : IsIso (Sigma.desc (fun a ↦ Sigma.ι f a)) := by convert! IsIso.id _ ext @@ -313,8 +307,6 @@ lemma Cofan.nonempty_isColimit_iff_isIso_sigmaDesc {f : β → C} [HasCoproduct @[deprecated (since := "2026-01-21")] alias Cofan.isColimit_iff_isIso_sigmaDesc := Cofan.nonempty_isColimit_iff_isIso_sigmaDesc -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- A coproduct of coproducts is a coproduct -/ def Cofan.isColimitTrans {X : α → C} (c : Cofan X) (hc : IsColimit c) {β : α → Type*} {Y : (a : α) → β a → C} (π : (a : α) → (b : β a) → Y a b ⟶ X a) @@ -338,7 +330,6 @@ from a family of morphisms between the factors. def Pi.map {f g : β → C} [HasProduct f] [HasProduct g] (p : ∀ b, f b ⟶ g b) : ∏ᶜ f ⟶ ∏ᶜ g := limMap (Discrete.natTrans fun X => p X.as) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp), elementwise nosimp] lemma Pi.map_π {f g : β → C} [HasProduct f] [HasProduct g] (p : ∀ b, f b ⟶ g b) (b : β) : Pi.map p ≫ Pi.π g b = Pi.π f b ≫ p b := by simp [Pi.map] @@ -352,8 +343,6 @@ lemma Pi.map_comp_map {f g h : α → C} [HasProduct f] [HasProduct g] [HasProdu Pi.map q ≫ Pi.map q' = Pi.map (fun a => q a ≫ q' a) := by ext; simp -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in instance Pi.map_mono {f g : β → C} [HasProduct f] [HasProduct g] (p : ∀ b, f b ⟶ g b) [∀ i, Mono (p i)] : Mono <| Pi.map p := @Limits.limMap_mono _ _ _ _ (Discrete.functor f) (Discrete.functor g) _ _ @@ -434,7 +423,6 @@ def Pi.cone : Cone X where π := Discrete.natTrans (fun _ => Pi.π _ _) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The cone `Pi.cone X` is a limit cone. -/ def productIsProduct' : IsLimit (Pi.cone X) where @@ -472,7 +460,6 @@ def Sigma.map {f g : β → C} [HasCoproduct f] [HasCoproduct g] (p : ∀ b, f b ∐ f ⟶ ∐ g := colimMap (Discrete.natTrans fun X => p X.as) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] lemma Sigma.ι_map {f g : β → C} [HasCoproduct f] [HasCoproduct g] (p : ∀ b, f b ⟶ g b) (b : β) : Sigma.ι f b ≫ Sigma.map p = p b ≫ Sigma.ι g b := by simp [Sigma.map] @@ -486,8 +473,6 @@ lemma Sigma.map_comp_map {f g h : α → C} [HasCoproduct f] [HasCoproduct g] [H Sigma.map q ≫ Sigma.map q' = Sigma.map (fun a => q a ≫ q' a) := by ext; simp -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in instance Sigma.map_epi {f g : β → C} [HasCoproduct f] [HasCoproduct g] (p : ∀ b, f b ⟶ g b) [∀ i, Epi (p i)] : Epi <| Sigma.map p := @Limits.colimMap_epi _ _ _ _ (Discrete.functor f) (Discrete.functor g) _ _ @@ -571,7 +556,6 @@ def Sigma.cocone : Cocone X where ι := Discrete.natTrans (fun _ => Sigma.ι (fun j ↦ X.obj ⟨j⟩) _) set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The cocone `Sigma.cocone X` is a colimit cocone. -/ def coproductIsCoproduct' : IsColimit (Sigma.cocone X) where @@ -620,8 +604,6 @@ def Sigma.whiskerEquiv {J K : Type*} {f : J → C} {g : K → C} (e : J ≃ K) ( hom := Sigma.map' e fun j => (w j).inv inv := Sigma.map' e.symm fun k => eqToHom (by simp) ≫ (w (e.symm k)).hom -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) [∀ i, HasProduct (g i)] [HasProduct fun i => ∏ᶜ g i] : HasProduct fun p : Σ i, f i => g p.1 p.2 where @@ -631,7 +613,6 @@ instance {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) (by simp) (by intro s (m : _ ⟶ (∏ᶜ fun i ↦ ∏ᶜ g i)) w; aesop (add norm simp Sigma.forall)) } -set_option backward.isDefEq.respectTransparency false in /-- An iterated product is a product over a sigma type. -/ @[simps] def piPiIso {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) @@ -640,8 +621,6 @@ def piPiIso {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) hom := Pi.lift fun ⟨i, x⟩ => Pi.π _ i ≫ Pi.π _ x inv := Pi.lift fun i => Pi.lift fun x => Pi.π _ (⟨i, x⟩ : Σ i, f i) -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in instance {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) [∀ i, HasCoproduct (g i)] [HasCoproduct fun i => ∐ g i] : HasCoproduct fun p : Σ i, f i => g p.1 p.2 where @@ -653,7 +632,6 @@ instance {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) (by simp) (by intro s (m : (∐ fun i ↦ ∐ g i) ⟶ _) w; aesop_cat (add norm simp Sigma.forall)) } -set_option backward.isDefEq.respectTransparency false in /-- An iterated coproduct is a coproduct over a sigma type. -/ @[simps] def sigmaSigmaIso {ι : Type*} (f : ι → Type*) (g : (i : ι) → (f i) → C) @@ -678,7 +656,6 @@ theorem piComparison_comp_π [HasProduct f] [HasProduct fun b => G.obj (f b)] (b piComparison G f ≫ Pi.π _ b = G.map (Pi.π f b) := limit.lift_π _ (Discrete.mk b) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem map_lift_piComparison [HasProduct f] [HasProduct fun b => G.obj (f b)] (P : C) (g : ∀ j, P ⟶ f j) : G.map (Pi.lift g) ≫ piComparison G f = Pi.lift fun j => G.map (g j) := by @@ -697,7 +674,6 @@ theorem ι_comp_sigmaComparison [HasCoproduct f] [HasCoproduct fun b => G.obj (f Sigma.ι _ b ≫ sigmaComparison G f = G.map (Sigma.ι f b) := colimit.ι_desc _ (Discrete.mk b) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem sigmaComparison_map_desc [HasCoproduct f] [HasCoproduct fun b => G.obj (f b)] (P : C) (g : ∀ j, f j ⟶ P) : @@ -705,16 +681,12 @@ theorem sigmaComparison_map_desc [HasCoproduct f] [HasCoproduct fun b => G.obj ( ext j simp only [ι_comp_sigmaComparison_assoc, ← G.map_comp, colimit.ι_desc, Cofan.mk_ι_app] -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- `F.mapCone c` being limiting is the same as the induced fan being limiting. -/ def Fan.isLimitMapConeEquiv (F : C ⥤ D) {ι : Type*} (X : ι → C) (c : Fan X) : IsLimit (F.mapCone c) ≃ IsLimit (Fan.mk _ fun i ↦ F.map (c.proj i)) := (IsLimit.postcomposeHomEquiv Discrete.natIsoFunctor (F.mapCone c)).symm.trans <| IsLimit.equivIsoLimit (Cone.ext (Iso.refl _)) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- `F.mapCocone c` being colimiting is the same as the induced cofan being colimiting. -/ def Cofan.isColimitMapCoconeEquiv (F : C ⥤ D) {ι : Type*} (X : ι → C) (c : Cofan X) : IsColimit (F.mapCocone c) ≃ IsColimit (Cofan.mk _ fun i ↦ F.map (c.inj i)) := @@ -771,13 +743,11 @@ instance (priority := 100) hasCoproductsOfShape_of_hasCoproducts [HasCoproducts. open Opposite in /-- The functor sending `(X, n)` to the product of copies of `X` indexed by `n`. -/ -@[simps] +@[implicit_reducible, simps] def piConst [Limits.HasProducts.{w} C] : C ⥤ Type wᵒᵖ ⥤ C where obj X := { obj n := ∏ᶜ fun _ : (unop n :) ↦ X, map f := Limits.Pi.map' f.unop fun _ ↦ 𝟙 _ } map f := { app n := Limits.Pi.map fun _ ↦ f } -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- `n ↦ ∏ₙ X` is left adjoint to `Hom(-, X)`. -/ def piConstAdj [Limits.HasProducts.{v} C] (X : C) : (piConst.obj X).rightOp ⊣ yoneda.obj X where @@ -788,13 +758,11 @@ def piConstAdj [Limits.HasProducts.{v} C] (X : C) : left_triangle_components _ := by apply Quiver.Hom.unop_inj; cat_disch /-- The functor sending `(X, n)` to the coproduct of copies of `X` indexed by `n`. -/ -@[simps] +@[implicit_reducible, simps] def sigmaConst [Limits.HasCoproducts.{w} C] : C ⥤ Type w ⥤ C where obj X := { obj n := ∐ fun _ : n ↦ X, map f := Limits.Sigma.map' f fun _ ↦ 𝟙 _ } map f := { app n := Limits.Sigma.map fun _ ↦ f } -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- `n ↦ ∐ₙ X` is left adjoint to `Hom(X, -)`. -/ def sigmaConstAdj [Limits.HasCoproducts.{v} C] (X : C) : sigmaConst.obj X ⊣ coyoneda.obj (Opposite.op X) where @@ -808,8 +776,6 @@ def sigmaConstAdj [Limits.HasCoproducts.{v} C] (X : C) : section Unique -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The limit cone for the product over an index type with exactly one term. -/ @[simps] def limitConeOfUnique [Unique β] (f : β → C) : LimitCone (Discrete.functor f) where @@ -848,8 +814,6 @@ lemma productUniqueIso_inv_π [Unique β] (f : β → C) (b : β) : @[deprecated (since := "2026-06-30")] alias productUniqueIso_inv := productUniqueIso_inv_π -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism is the projection from a single object product. -/ def Fan.isLimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : IsLimit (Fan.mk X fun _ : J ↦ e.hom) := by @@ -858,8 +822,6 @@ def Fan.isLimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : simp · simpa [← cancel_mono e.hom] using hm default -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The colimit cocone for the coproduct over an index type with exactly one term. -/ @[simps] def colimitCoconeOfUnique [Unique β] (f : β → C) : ColimitCocone (Discrete.functor f) where @@ -900,8 +862,6 @@ lemma ι_coproductUniqueIso_hom [Unique β] (f : β → C) (b : β) : @[deprecated (since := "2026-06-30")] alias coproductUniqueIso_hom := ι_coproductUniqueIso_hom -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- Any isomorphism is the projection from a single object product. -/ def Cofan.isColimitMkOfUnique {X Y : C} (e : X ≅ Y) (J : Type*) [Unique J] : IsColimit (Cofan.mk Y fun _ : J ↦ e.hom) := by @@ -968,7 +928,6 @@ theorem Sigma.ι_reindex_hom (b : β) : erw [← h, eqToHom_map, eqToHom_map, eqToHom_trans_assoc] all_goals { simp } -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem Sigma.ι_reindex_inv (b : β) : Sigma.ι f (ε b) ≫ (Sigma.reindex ε f).inv = Sigma.ι (f ∘ ε) b := by simp [Iso.comp_inv_eq] @@ -987,13 +946,11 @@ section variable {J : Type u₂} [Category.{v₂} J] (F : J ⥤ C) -set_option backward.isDefEq.respectTransparency false in instance [HasLimit F] [HasProduct F.obj] : Mono (Pi.lift (limit.π F)) where right_cancellation _ _ h := by refine limit.hom_ext fun j => ?_ simpa using h =≫ Pi.π _ j -set_option backward.isDefEq.respectTransparency false in instance [HasColimit F] [HasCoproduct F.obj] : Epi (Sigma.desc (colimit.ι F)) where left_cancellation _ _ h := by refine colimit.hom_ext fun j => ?_ @@ -1026,8 +983,6 @@ section Fubini variable {ι ι' : Type*} {X : ι → ι' → C} -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- A product over products is a product indexed by a product. -/ def Fan.IsLimit.prod (c : ∀ i : ι, Fan (fun j : ι' ↦ X i j)) (hc : ∀ i : ι, IsLimit (c i)) (c' : Fan (fun i : ι ↦ (c i).pt)) (hc' : IsLimit c') : @@ -1038,8 +993,6 @@ def Fan.IsLimit.prod (c : ∀ i : ι, Fan (fun j : ι' ↦ X i j)) (hc : ∀ i : · refine Fan.IsLimit.hom_ext hc' _ _ fun i ↦ ?_ exact Fan.IsLimit.hom_ext (hc i) _ _ fun j ↦ (by simpa using hm (i, j)) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- A coproduct over coproducts is a coproduct indexed by a product. -/ def Cofan.IsColimit.prod (c : ∀ i : ι, Cofan (fun j : ι' ↦ X i j)) (hc : ∀ i : ι, IsColimit (c i)) (c' : Cofan (fun i : ι ↦ (c i).pt)) (hc' : IsColimit c') : @@ -1074,7 +1027,6 @@ def piEquivalenceFunctorDiscreteCompLim [HasProductsOfShape α C] : (piEquivalenceFunctorDiscrete α C).functor ⋙ lim ≅ Pi.functor _ := NatIso.ofComponents fun _ ↦ Iso.refl _ -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma piEquivalenceFunctorDiscreteCompLim_comp_functorπ [HasProductsOfShape α C] (a : α) : @@ -1083,7 +1035,6 @@ lemma piEquivalenceFunctorDiscreteCompLim_comp_functorπ [HasProductsOfShape α (piEquivalenceFunctorDiscreteCompEvaluationIso _ _).hom := by cat_disch -set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.pi in /-- The `∏ᶜ` functor composed with the pointwise constant functor `Π i, I i ⥤ (α → C)` is isomorphic to the constant functor with value `∏ᶜ X`. -/ @@ -1117,7 +1068,6 @@ def piEquivalenceFunctorDiscreteCompColim [HasCoproductsOfShape α C] : (piEquivalenceFunctorDiscrete α C).functor ⋙ colim ≅ Sigma.functor _ := NatIso.ofComponents fun _ ↦ Iso.refl _ -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in @[reassoc] lemma piEquivalenceFunctorDiscreteCompColim_comp_functorι [HasCoproductsOfShape α C] (a : α) : @@ -1129,7 +1079,6 @@ lemma piEquivalenceFunctorDiscrete_functor_comp_colim [HasCoproductsOfShape α C (piEquivalenceFunctorDiscrete α C).functor ⋙ colim = Sigma.functor _ := rfl -set_option backward.defeqAttrib.useBackward true in attribute [local simp] Functor.pi in /-- The `∐` functor composed with the pointwise constant functor `Π i, I i ⥤ (α → C)` is isomorphic to the constant functor with value `∐ X`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean index 8122b68b9f2152..71e5a10957ed39 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean @@ -118,12 +118,10 @@ abbrev terminal.from [HasTerminal C] (P : C) : P ⟶ ⊤_ C := abbrev initial.to [HasInitial C] (P : C) : ⊥_ C ⟶ P := colimit.desc (Functor.empty C) (asEmptyCocone P) -set_option backward.defeqAttrib.useBackward true in /-- A terminal object is terminal. -/ def terminalIsTerminal [HasTerminal C] : IsTerminal (⊤_ C) where lift _ := terminal.from _ -set_option backward.defeqAttrib.useBackward true in /-- An initial object is initial. -/ def initialIsInitial [HasInitial C] : IsInitial (⊥_ C) where desc _ := initial.to _ @@ -178,7 +176,6 @@ theorem hasTerminal_of_hasInitial_op [HasInitial Cᵒᵖ] : HasTerminal C := theorem hasInitial_of_hasTerminal_op [HasTerminal Cᵒᵖ] : HasInitial C := (initialUnopOfTerminal terminalIsTerminal).hasInitial -set_option backward.defeqAttrib.useBackward true in instance {J : Type*} [Category* J] {C : Type*} [Category* C] [HasTerminal C] : HasLimit ((CategoryTheory.Functor.const J).obj (⊤_ C)) := HasLimit.mk @@ -187,7 +184,6 @@ instance {J : Type*} [Category* J] {C : Type*} [Category* C] [HasTerminal C] : π := { app := fun _ => terminal.from _ } } isLimit := { lift := fun _ => terminal.from _ } } -set_option backward.defeqAttrib.useBackward true in /-- The limit of the constant `⊤_ C` functor is `⊤_ C`. -/ @[simps hom] def limitConstTerminal {J : Type*} [Category* J] {C : Type*} [Category* C] [HasTerminal C] : @@ -198,14 +194,12 @@ def limitConstTerminal {J : Type*} [Category* J] {C : Type*} [Category* C] [HasT { pt := ⊤_ C π := { app := fun _ => terminal.from _ } } -set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] theorem limitConstTerminal_inv_π {J : Type*} [Category* J] {C : Type*} [Category* C] [HasTerminal C] {j : J} : limitConstTerminal.inv ≫ limit.π ((CategoryTheory.Functor.const J).obj (⊤_ C)) j = terminal.from _ := by cat_disch -set_option backward.defeqAttrib.useBackward true in instance {J : Type*} [Category* J] {C : Type*} [Category* C] [HasInitial C] : HasColimit ((CategoryTheory.Functor.const J).obj (⊥_ C)) := HasColimit.mk @@ -214,7 +208,6 @@ instance {J : Type*} [Category* J] {C : Type*} [Category* C] [HasInitial C] : ι := { app := fun _ => initial.to _ } } isColimit := { desc := fun _ => initial.to _ } } -set_option backward.defeqAttrib.useBackward true in /-- The colimit of the constant `⊥_ C` functor is `⊥_ C`. -/ @[simps inv] def colimitConstInitial {J : Type*} [Category* J] {C : Type*} [Category* C] [HasInitial C] : @@ -225,7 +218,6 @@ def colimitConstInitial {J : Type*} [Category* J] {C : Type*} [Category* C] [Has ι := { app := fun _ => initial.to _ } } inv := initial.to _ -set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] theorem ι_colimitConstInitial_hom {J : Type*} [Category* J] {C : Type*} [Category* C] [HasInitial C] {j : J} : @@ -314,7 +306,6 @@ abbrev colimitOfInitial (F : J ⥤ C) [HasInitial J] [∀ (i j : J) (f : i ⟶ j IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) (colimitOfDiagramInitial initialIsInitial _) -set_option backward.isDefEq.respectTransparency false in /-- If `j` is initial in the index category, then the map `limit.π F j` is an isomorphism. -/ theorem isIso_π_of_isInitial {j : J} (I : IsInitial j) (F : J ⥤ C) [HasLimit F] : @@ -324,7 +315,6 @@ theorem isIso_π_of_isInitial {j : J} (I : IsInitial j) (F : J ⥤ C) [HasLimit instance isIso_π_initial [HasInitial J] (F : J ⥤ C) : IsIso (limit.π F (⊥_ J)) := isIso_π_of_isInitial initialIsInitial F -set_option backward.isDefEq.respectTransparency false in theorem isIso_π_of_isTerminal {j : J} (I : IsTerminal j) (F : J ⥤ C) [HasLimit F] [∀ (i j : J) (f : i ⟶ j), IsIso (F.map f)] : IsIso (limit.π F j) := ⟨⟨limit.lift _ (coneOfDiagramTerminal I F), by ext; simp, by simp⟩⟩ @@ -333,7 +323,6 @@ instance isIso_π_terminal [HasTerminal J] (F : J ⥤ C) [∀ (i j : J) (f : i IsIso (limit.π F (⊤_ J)) := isIso_π_of_isTerminal terminalIsTerminal F -set_option backward.isDefEq.respectTransparency false in /-- If `j` is terminal in the index category, then the map `colimit.ι F j` is an isomorphism. -/ theorem isIso_ι_of_isTerminal {j : J} (I : IsTerminal j) (F : J ⥤ C) [HasColimit F] : @@ -343,8 +332,6 @@ theorem isIso_ι_of_isTerminal {j : J} (I : IsTerminal j) (F : J ⥤ C) [HasColi instance isIso_ι_terminal [HasTerminal J] (F : J ⥤ C) : IsIso (colimit.ι F (⊤_ J)) := isIso_ι_of_isTerminal terminalIsTerminal F -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in theorem isIso_ι_of_isInitial {j : J} (I : IsInitial j) (F : J ⥤ C) [HasColimit F] [∀ (i j : J) (f : i ⟶ j), IsIso (F.map f)] : IsIso (colimit.ι F j) := ⟨⟨colimit.desc _ (coconeOfDiagramInitial I F), by diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index 23a505d37e266e..b4547cad3b4d9b 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -49,7 +49,7 @@ namespace Iso /-- The application of a natural isomorphism to an object. We put this definition in a different namespace, so that we can use `α.app` -/ -@[simps (attr := grind =)] +@[implicit_reducible, simps (attr := grind =)] def app {F G : C ⥤ D} (α : F ≅ G) (X : C) : F.obj X ≅ G.obj X where hom := α.hom.app X diff --git a/Mathlib/CategoryTheory/Opposites.lean b/Mathlib/CategoryTheory/Opposites.lean index 3433aa65b65f55..59d0dbd4c2ddeb 100644 --- a/Mathlib/CategoryTheory/Opposites.lean +++ b/Mathlib/CategoryTheory/Opposites.lean @@ -135,18 +135,17 @@ section variable (C) /-- The functor from the double-opposite of a category to the underlying category. -/ -@[simps] +@[implicit_reducible, simps] def unopUnop : Cᵒᵖᵒᵖ ⥤ C where obj X := unop (unop X) map f := f.unop.unop /-- The functor from a category to its double-opposite. -/ -@[simps] +@[implicit_reducible, simps] def opOp : C ⥤ Cᵒᵖᵒᵖ where obj X := op (op X) map f := f.op.op -set_option backward.defeqAttrib.useBackward true in /-- The double opposite category is equivalent to the original. -/ @[simps] def opOpEquivalence : Cᵒᵖᵒᵖ ≌ C where @@ -218,13 +217,11 @@ protected def unop (F : Cᵒᵖ ⥤ Dᵒᵖ) : C ⥤ D where obj X := unop (F.obj (op X)) map f := (F.map f.op).unop -set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between `F.op.unop` and `F`. -/ @[simps!] def opUnopIso (F : C ⥤ D) : F.op.unop ≅ F := NatIso.ofComponents fun _ => Iso.refl _ -set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between `F.unop.op` and `F`. -/ @[simps!] def unopOpIso (F : Cᵒᵖ ⥤ Dᵒᵖ) : F.unop.op ≅ F := @@ -234,7 +231,7 @@ variable (C D) /-- Taking the opposite of a functor is functorial. -/ -@[simps] +@[implicit_reducible, simps] def opHom : (C ⥤ D)ᵒᵖ ⥤ Cᵒᵖ ⥤ Dᵒᵖ where obj F := (unop F).op map α := @@ -243,7 +240,7 @@ def opHom : (C ⥤ D)ᵒᵖ ⥤ Cᵒᵖ ⥤ Dᵒᵖ where /-- Take the "unopposite" of a functor is functorial. -/ -@[simps] +@[implicit_reducible, simps] def opInv : (Cᵒᵖ ⥤ Dᵒᵖ) ⥤ (C ⥤ D)ᵒᵖ where obj F := op F.unop map α := @@ -281,7 +278,7 @@ end Compositions Another variant of the opposite of functor, turning a functor `C ⥤ Dᵒᵖ` into a functor `Cᵒᵖ ⥤ D`. In informal mathematics no distinction is made. -/ -@[simps] +@[implicit_reducible, simps] protected def leftOp (F : C ⥤ Dᵒᵖ) : Cᵒᵖ ⥤ D where obj X := unop (F.obj (unop X)) map f := (F.map f.unop).unop @@ -290,7 +287,7 @@ protected def leftOp (F : C ⥤ Dᵒᵖ) : Cᵒᵖ ⥤ D where Another variant of the opposite of functor, turning a functor `Cᵒᵖ ⥤ D` into a functor `C ⥤ Dᵒᵖ`. In informal mathematics no distinction is made. -/ -@[simps] +@[implicit_reducible, simps] protected def rightOp (F : Cᵒᵖ ⥤ D) : C ⥤ Dᵒᵖ where obj X := op (F.obj (op X)) map f := (F.map f.op).op @@ -298,20 +295,16 @@ protected def rightOp (F : Cᵒᵖ ⥤ D) : C ⥤ Dᵒᵖ where lemma rightOp_map_unop {F : Cᵒᵖ ⥤ D} {X Y} (f : X ⟶ Y) : (F.rightOp.map f).unop = F.map f.op := rfl -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in instance {F : C ⥤ D} [Full F] : Full F.op where map_surjective f := ⟨(F.preimage f.unop).op, by simp⟩ instance {F : C ⥤ D} [Faithful F] : Faithful F.op where map_injective h := Quiver.Hom.unop_inj <| by simpa using map_injective F (Quiver.Hom.op_inj h) -set_option backward.defeqAttrib.useBackward true in /-- The opposite of a fully faithful functor is fully faithful. -/ protected def FullyFaithful.op {F : C ⥤ D} (hF : F.FullyFaithful) : F.op.FullyFaithful where preimage {X Y} f := .op <| hF.preimage f.unop -set_option backward.defeqAttrib.useBackward true in /-- A functor is fully faithful when its opposite is fully faithful. -/ protected def FullyFaithful.unop {F : Cᵒᵖ ⥤ Dᵒᵖ} (hF : F.FullyFaithful) : F.unop.FullyFaithful where @@ -325,23 +318,17 @@ instance rightOp_faithful {F : Cᵒᵖ ⥤ D} [Faithful F] : Faithful F.rightOp instance leftOp_faithful {F : C ⥤ Dᵒᵖ} [Faithful F] : Faithful F.leftOp where map_injective h := Quiver.Hom.unop_inj (map_injective F (Quiver.Hom.unop_inj h)) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in instance rightOp_full {F : Cᵒᵖ ⥤ D} [Full F] : Full F.rightOp where map_surjective f := ⟨(F.preimage f.unop).unop, by simp⟩ -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in instance leftOp_full {F : C ⥤ Dᵒᵖ} [Full F] : Full F.leftOp where map_surjective f := ⟨(F.preimage f.op).op, by simp⟩ -set_option backward.defeqAttrib.useBackward true in /-- The opposite of a fully faithful functor is fully faithful. -/ protected def FullyFaithful.leftOp {F : C ⥤ Dᵒᵖ} (hF : F.FullyFaithful) : F.leftOp.FullyFaithful where preimage {X Y} f := .op <| hF.preimage f.op -set_option backward.defeqAttrib.useBackward true in /-- The opposite of a fully faithful functor is fully faithful. -/ protected def FullyFaithful.rightOp {F : Cᵒᵖ ⥤ D} (hF : F.FullyFaithful) : F.rightOp.FullyFaithful where @@ -372,13 +359,11 @@ def leftOpId : (𝟭 Cᵒᵖ).leftOp ≅ unopUnop C := Iso.refl _ end -set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between `F.leftOp.rightOp` and `F`. -/ @[simps!] def leftOpRightOpIso (F : C ⥤ Dᵒᵖ) : F.leftOp.rightOp ≅ F := NatIso.ofComponents fun _ => Iso.refl _ -set_option backward.defeqAttrib.useBackward true in /-- The isomorphism between `F.rightOp.leftOp` and `F`. -/ @[simps!] def rightOpLeftOpIso (F : Cᵒᵖ ⥤ D) : F.rightOp.leftOp ≅ F := @@ -402,9 +387,8 @@ section variable {F G : C ⥤ D} -set_option backward.defeqAttrib.useBackward true in /-- The opposite of a natural transformation. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def op (α : F ⟶ G) : G.op ⟶ F.op where app X := (α.app (unop X)).op naturality X Y f := Quiver.Hom.unop_inj (by simp) @@ -418,23 +402,20 @@ theorem op_comp {H : C ⥤ D} (α : F ⟶ G) (β : G ⟶ H) : NatTrans.op (α ≫ β) = NatTrans.op β ≫ NatTrans.op α := rfl -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] lemma op_whiskerRight {E : Type*} [Category* E] {H : D ⥤ E} (α : F ⟶ G) : NatTrans.op (whiskerRight α H) = (Functor.opComp _ _).hom ≫ whiskerRight (NatTrans.op α) H.op ≫ (Functor.opComp _ _).inv := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] lemma op_whiskerLeft {E : Type*} [Category* E] {H : E ⥤ C} (α : F ⟶ G) : NatTrans.op (whiskerLeft H α) = (Functor.opComp _ _).hom ≫ whiskerLeft H.op (NatTrans.op α) ≫ (Functor.opComp _ _).inv := by cat_disch -set_option backward.defeqAttrib.useBackward true in /-- The "unopposite" of a natural transformation. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def unop {F G : Cᵒᵖ ⥤ Dᵒᵖ} (α : F ⟶ G) : G.unop ⟶ F.unop where app X := (α.app (op X)).unop naturality X Y f := Quiver.Hom.op_inj (by simp) @@ -448,7 +429,6 @@ theorem unop_comp {F G H : Cᵒᵖ ⥤ Dᵒᵖ} (α : F ⟶ G) (β : G ⟶ H) : NatTrans.unop (α ≫ β) = NatTrans.unop β ≫ NatTrans.unop α := rfl -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] lemma unop_whiskerRight {F G : Cᵒᵖ ⥤ Dᵒᵖ} {E : Type*} [Category* E] {H : Dᵒᵖ ⥤ Eᵒᵖ} (α : F ⟶ G) : NatTrans.unop (whiskerRight α H) = @@ -456,7 +436,6 @@ lemma unop_whiskerRight {F G : Cᵒᵖ ⥤ Dᵒᵖ} {E : Type*} [Category* E] {H (Functor.unopComp _ _).inv := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] lemma unop_whiskerLeft {F G : Cᵒᵖ ⥤ Dᵒᵖ} {E : Type*} [Category* E] {H : Eᵒᵖ ⥤ Cᵒᵖ} (α : F ⟶ G) : NatTrans.unop (whiskerLeft H α) = @@ -467,7 +446,7 @@ lemma unop_whiskerLeft {F G : Cᵒᵖ ⥤ Dᵒᵖ} {E : Type*} [Category* E] {H /-- Given a natural transformation `α : F.op ⟶ G.op`, we can take the "unopposite" of each component obtaining a natural transformation `G ⟶ F`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def removeOp (α : F.op ⟶ G.op) : G ⟶ F where app X := (α.app (op X)).unop naturality X Y f := @@ -479,7 +458,7 @@ theorem removeOp_id (F : C ⥤ D) : NatTrans.removeOp (𝟙 F.op) = 𝟙 F := /-- Given a natural transformation `α : F.unop ⟶ G.unop`, we can take the opposite of each component obtaining a natural transformation `G ⟶ F`. -/ -@[simps, to_dual self] +@[implicit_reducible, simps, to_dual self] protected def removeUnop {F G : Cᵒᵖ ⥤ Dᵒᵖ} (α : F.unop ⟶ G.unop) : G ⟶ F where app X := (α.app (unop X)).op naturality X Y f := @@ -495,11 +474,10 @@ section variable {F G H : C ⥤ Dᵒᵖ} -set_option backward.defeqAttrib.useBackward true in /-- Given a natural transformation `α : F ⟶ G`, for `F G : C ⥤ Dᵒᵖ`, taking `unop` of each component gives a natural transformation `G.leftOp ⟶ F.leftOp`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def leftOp (α : F ⟶ G) : G.leftOp ⟶ F.leftOp where app X := (α.app (unop X)).unop naturality X Y f := Quiver.Hom.op_inj (by simp) @@ -513,7 +491,6 @@ theorem leftOp_comp (α : F ⟶ G) (β : G ⟶ H) : NatTrans.leftOp (α ≫ β) NatTrans.leftOp β ≫ NatTrans.leftOp α := rfl -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] lemma leftOpWhiskerRight {E : Type*} [Category* E] {H : E ⥤ C} (α : F ⟶ G) : (whiskerLeft H α).leftOp = (Functor.leftOpComp H G).hom ≫ whiskerLeft _ α.leftOp ≫ @@ -523,7 +500,7 @@ lemma leftOpWhiskerRight {E : Type*} [Category* E] {H : E ⥤ C} (α : F ⟶ G) /-- Given a natural transformation `α : F.leftOp ⟶ G.leftOp`, for `F G : C ⥤ Dᵒᵖ`, taking `op` of each component gives a natural transformation `G ⟶ F`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def removeLeftOp (α : F.leftOp ⟶ G.leftOp) : G ⟶ F where app X := (α.app (op X)).op naturality X Y f := @@ -539,11 +516,10 @@ section variable {F G H : Cᵒᵖ ⥤ D} -set_option backward.defeqAttrib.useBackward true in /-- Given a natural transformation `α : F ⟶ G`, for `F G : Cᵒᵖ ⥤ D`, taking `op` of each component gives a natural transformation `G.rightOp ⟶ F.rightOp`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def rightOp (α : F ⟶ G) : G.rightOp ⟶ F.rightOp where app _ := (α.app _).op naturality X Y f := Quiver.Hom.unop_inj (by simp) @@ -557,7 +533,6 @@ theorem rightOp_comp (α : F ⟶ G) (β : G ⟶ H) : NatTrans.rightOp (α ≫ β NatTrans.rightOp β ≫ NatTrans.rightOp α := rfl -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] lemma rightOpWhiskerRight {E : Type*} [Category* E] {H : D ⥤ E} (α : F ⟶ G) : (whiskerRight α H).rightOp = (Functor.rightOpComp G H).hom ≫ whiskerRight α.rightOp H.op ≫ @@ -567,7 +542,7 @@ lemma rightOpWhiskerRight {E : Type*} [Category* E] {H : D ⥤ E} (α : F ⟶ G) /-- Given a natural transformation `α : F.rightOp ⟶ G.rightOp`, for `F G : Cᵒᵖ ⥤ D`, taking `unop` of each component gives a natural transformation `G ⟶ F`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] protected def removeRightOp (α : F.rightOp ⟶ G.rightOp) : G ⟶ F where app X := (α.app X.unop).unop naturality X Y f := @@ -652,7 +627,6 @@ namespace NatIso variable {D : Type u₂} [Category.{v₂} D] variable {F G : C ⥤ D} -set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism between opposite functors `G.op ≅ F.op` induced by a natural isomorphism between the original functors `F ≅ G`. -/ @[simps] @@ -673,7 +647,6 @@ theorem op_trans {H : C ⥤ D} (α : F ≅ G) (β : G ≅ H) : @[simp] theorem op_symm (α : F ≅ G) : NatIso.op α.symm = (NatIso.op α).symm := rfl -set_option backward.isDefEq.respectTransparency false in /-- The natural isomorphism between functors `G ≅ F` induced by a natural isomorphism between the opposite functors `F.op ≅ G.op`. -/ @[simps] @@ -681,7 +654,6 @@ protected def removeOp (α : F.op ≅ G.op) : G ≅ F where hom := NatTrans.removeOp α.hom inv := NatTrans.removeOp α.inv -set_option backward.defeqAttrib.useBackward true in /-- The natural isomorphism between functors `G.unop ≅ F.unop` induced by a natural isomorphism between the original functors `F ≅ G`. -/ @[simps] @@ -700,33 +672,28 @@ theorem unop_trans {F G H : Cᵒᵖ ⥤ Dᵒᵖ} (α : F ≅ G) (β : G ≅ H) : @[simp] theorem unop_symm {F G : Cᵒᵖ ⥤ Dᵒᵖ} (α : F ≅ G) : NatIso.unop α.symm = (NatIso.unop α).symm := rfl -set_option backward.defeqAttrib.useBackward true in lemma op_isoWhiskerRight {E : Type*} [Category* E] {H : D ⥤ E} (α : F ≅ G) : NatIso.op (isoWhiskerRight α H) = (Functor.opComp _ _) ≪≫ isoWhiskerRight (NatIso.op α) H.op ≪≫ (Functor.opComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma op_isoWhiskerLeft {E : Type*} [Category* E] {H : E ⥤ C} (α : F ≅ G) : NatIso.op (isoWhiskerLeft H α) = (Functor.opComp _ _) ≪≫ isoWhiskerLeft H.op (NatIso.op α) ≪≫ (Functor.opComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma unop_whiskerRight {F G : Cᵒᵖ ⥤ Dᵒᵖ} {E : Type*} [Category* E] {H : Dᵒᵖ ⥤ Eᵒᵖ} (α : F ≅ G) : NatIso.unop (isoWhiskerRight α H) = (Functor.unopComp _ _) ≪≫ isoWhiskerRight (NatIso.unop α) H.unop ≪≫ (Functor.unopComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma unop_whiskerLeft {F G : Cᵒᵖ ⥤ Dᵒᵖ} {E : Type*} [Category* E] {H : Eᵒᵖ ⥤ Cᵒᵖ} (α : F ≅ G) : NatIso.unop (isoWhiskerLeft H α) = (Functor.unopComp _ _) ≪≫ isoWhiskerLeft H.unop (NatIso.unop α) ≪≫ (Functor.unopComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma op_leftUnitor : NatIso.op F.leftUnitor = F.op.leftUnitor.symm ≪≫ @@ -734,7 +701,6 @@ lemma op_leftUnitor : (Functor.opComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma op_rightUnitor : NatIso.op F.rightUnitor = F.op.rightUnitor.symm ≪≫ @@ -742,7 +708,6 @@ lemma op_rightUnitor : (Functor.opComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma op_associator {E E' : Type*} [Category* E] [Category* E'] {F : C ⥤ D} {G : D ⥤ E} {H : E ⥤ E'} : NatIso.op (Functor.associator F G H) = @@ -751,7 +716,6 @@ lemma op_associator {E E' : Type*} [Category* E] [Category* E'] isoWhiskerRight (Functor.opComp _ _).symm H.op ≪≫ (Functor.opComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma unop_leftUnitor {F : Cᵒᵖ ⥤ Dᵒᵖ} : NatIso.unop F.leftUnitor = F.unop.leftUnitor.symm ≪≫ @@ -759,7 +723,6 @@ lemma unop_leftUnitor {F : Cᵒᵖ ⥤ Dᵒᵖ} : (Functor.unopComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma unop_rightUnitor {F : Cᵒᵖ ⥤ Dᵒᵖ} : NatIso.unop F.rightUnitor = F.unop.rightUnitor.symm ≪≫ @@ -767,7 +730,6 @@ lemma unop_rightUnitor {F : Cᵒᵖ ⥤ Dᵒᵖ} : (Functor.unopComp _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in lemma unop_associator {E E' : Type*} [Category* E] [Category* E'] {F : Cᵒᵖ ⥤ Dᵒᵖ} {G : Dᵒᵖ ⥤ Eᵒᵖ} {H : Eᵒᵖ ⥤ E'ᵒᵖ} : NatIso.unop (Functor.associator F G H) = @@ -797,7 +759,6 @@ namespace Equivalence variable {D : Type u₂} [Category.{v₂} D] -set_option backward.defeqAttrib.useBackward true in /-- An equivalence between categories gives an equivalence between the opposite categories. -/ @[simps] @@ -810,7 +771,6 @@ def op (e : C ≌ D) : Cᵒᵖ ≌ Dᵒᵖ where apply Quiver.Hom.unop_inj simp -set_option backward.defeqAttrib.useBackward true in /-- An equivalence between opposite categories gives an equivalence between the original categories. -/ @[simps] @@ -823,15 +783,9 @@ def unop (e : Cᵒᵖ ≌ Dᵒᵖ) : C ≌ D where apply Quiver.Hom.op_inj simp -#adaptation_note -/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in /-- An equivalence between `C` and `Dᵒᵖ` gives an equivalence between `Cᵒᵖ` and `D`. -/ @[simps!] def leftOp (e : C ≌ Dᵒᵖ) : Cᵒᵖ ≌ D := e.op.trans (opOpEquivalence D) -#adaptation_note -/-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ -set_option backward.isDefEq.respectTransparency.types false in /-- An equivalence between `Cᵒᵖ` and `D` gives an equivalence between `C` and `Dᵒᵖ`. -/ @[simps!] def rightOp (e : Cᵒᵖ ≌ D) : C ≌ Dᵒᵖ := (opOpEquivalence C).symm.trans e.op @@ -881,7 +835,6 @@ namespace Functor variable (C) variable (D : Type u₂) [Category.{v₂} D] -set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- The equivalence of functor categories induced by `op` and `unop`. -/ diff --git a/Mathlib/CategoryTheory/Whiskering.lean b/Mathlib/CategoryTheory/Whiskering.lean index 2398d24cc69cda..bece8bde3f50e7 100644 --- a/Mathlib/CategoryTheory/Whiskering.lean +++ b/Mathlib/CategoryTheory/Whiskering.lean @@ -42,27 +42,25 @@ variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] [Category.{v₃} E] /-- If `α : G ⟶ H` then `whiskerLeft F α : F ⋙ G ⟶ F ⋙ H` has components `α.app (F.obj X)`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] def whiskerLeft (F : C ⥤ D) {G H : D ⥤ E} (α : G ⟶ H) : F ⋙ G ⟶ F ⋙ H where app X := α.app (F.obj X) naturality X Y f := by rw [Functor.comp_map, Functor.comp_map, α.naturality] -set_option backward.defeqAttrib.useBackward true in @[simp, to_dual self] lemma id_hcomp (F : C ⥤ D) {G H : D ⥤ E} (α : G ⟶ H) : 𝟙 F ◫ α = whiskerLeft F α := by ext simp /-- If `α : G ⟶ H` then `whiskerRight α F : G ⋙ F ⟶ H ⋙ F` has components `F.map (α.app X)`. -/ -@[to_dual self, simps (attr := to_dual self)] +@[implicit_reducible, to_dual self, simps (attr := to_dual self)] def whiskerRight {G H : C ⥤ D} (α : G ⟶ H) (F : D ⥤ E) : G ⋙ F ⟶ H ⋙ F where app X := F.map (α.app X) naturality X Y f := by rw [Functor.comp_map, Functor.comp_map, ← F.map_comp, ← F.map_comp, α.naturality] -set_option backward.defeqAttrib.useBackward true in @[simp, to_dual self] lemma hcomp_id {G H : C ⥤ D} (α : G ⟶ H) (F : D ⥤ E) : α ◫ 𝟙 F = whiskerRight α F := by ext @@ -112,7 +110,6 @@ instance faithful_whiskeringRight_obj {F : D ⥤ E} [F.Faithful] : ext X exact F.map_injective <| congr_fun (congr_arg NatTrans.app hαβ) X -set_option backward.isDefEq.respectTransparency false in /-- If `F : D ⥤ E` is fully faithful, then so is `(whiskeringRight C D E).obj F : (C ⥤ D) ⥤ C ⥤ E`. -/ @[simps] @@ -202,7 +199,6 @@ theorem whiskerRight_comp {G H K : C ⥤ D} (α : G ⟶ H) (β : H ⟶ K) (F : D whiskerRight (α ≫ β) F = whiskerRight α F ≫ whiskerRight β F := ((whiskeringRight C D E).obj F).map_comp α β -set_option backward.defeqAttrib.useBackward true in @[to_dual none, reassoc] theorem whiskerLeft_comp_whiskerRight {F G : C ⥤ D} {H K : D ⥤ E} (α : F ⟶ G) (β : H ⟶ K) : whiskerLeft F β ≫ whiskerRight α K = whiskerRight α H ≫ whiskerLeft G β := by @@ -300,7 +296,6 @@ theorem isoWhiskerRight_trans {G H K : C ⥤ D} (α : G ≅ H) (β : H ≅ K) (F isoWhiskerRight (α ≪≫ β) F = isoWhiskerRight α F ≪≫ isoWhiskerRight β F := ((whiskeringRight C D E).obj F).mapIso_trans α β -set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem isoWhiskerLeft_trans_isoWhiskerRight {F G : C ⥤ D} {H K : D ⥤ E} (α : F ≅ G) (β : H ≅ K) : isoWhiskerLeft F β ≪≫ isoWhiskerRight α K = isoWhiskerRight α H ≪≫ isoWhiskerLeft G β := by @@ -309,21 +304,18 @@ theorem isoWhiskerLeft_trans_isoWhiskerRight {F G : C ⥤ D} {H K : D ⥤ E} (α variable {B : Type u₄} [Category.{v₄} B] -set_option backward.defeqAttrib.useBackward true in @[simp, to_dual none] theorem whiskerLeft_twice (F : B ⥤ C) (G : C ⥤ D) {H K : D ⥤ E} (α : H ⟶ K) : whiskerLeft F (whiskerLeft G α) = (Functor.associator _ _ _).inv ≫ whiskerLeft (F ⋙ G) α ≫ (Functor.associator _ _ _).hom := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[simp, to_dual none] theorem whiskerRight_twice {H K : B ⥤ C} (F : C ⥤ D) (G : D ⥤ E) (α : H ⟶ K) : whiskerRight (whiskerRight α F) G = (Functor.associator _ _ _).hom ≫ whiskerRight α (F ⋙ G) ≫ (Functor.associator _ _ _).inv := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[to_dual none] theorem whiskerRight_left (F : B ⥤ C) {G H : C ⥤ D} (α : G ⟶ H) (K : D ⥤ E) : whiskerRight (whiskerLeft F α) K = @@ -343,7 +335,6 @@ theorem isoWhiskerRight_twice {H K : B ⥤ C} (F : C ⥤ D) (G : D ⥤ E) (α : Functor.associator _ _ _ ≪≫ isoWhiskerRight α (F ⋙ G) ≪≫ (Functor.associator _ _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem isoWhiskerRight_left (F : B ⥤ C) {G H : C ⥤ D} (α : G ≅ H) (K : D ⥤ E) : isoWhiskerRight (isoWhiskerLeft F α) K = @@ -351,7 +342,6 @@ theorem isoWhiskerRight_left (F : B ⥤ C) {G H : C ⥤ D} (α : G ≅ H) (K : D (Functor.associator _ _ _).symm := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem isoWhiskerLeft_right (F : B ⥤ C) {G H : C ⥤ D} (α : G ≅ H) (K : D ⥤ E) : isoWhiskerLeft F (isoWhiskerRight α K) = @@ -367,25 +357,21 @@ variable {A : Type u₁} [Category.{v₁} A] {B : Type u₂} [Category.{v₂} B] {C : Type u₃} [Category.{v₃} C] {D : Type u₄} [Category.{v₄} D] {E : Type u₅} [Category.{v₅} E] (F : A ⥤ B) (G : B ⥤ C) (H : C ⥤ D) (K : D ⥤ E) -set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem triangleIso : associator F (𝟭 B) G ≪≫ isoWhiskerLeft F (leftUnitor G) = isoWhiskerRight (rightUnitor F) G := by cat_disch -set_option backward.defeqAttrib.useBackward true in @[reassoc] theorem pentagonIso : isoWhiskerRight (associator F G H) K ≪≫ associator F (G ⋙ H) K ≪≫ isoWhiskerLeft F (associator G H K) = associator (F ⋙ G) H K ≪≫ associator F G (H ⋙ K) := by cat_disch -set_option backward.defeqAttrib.useBackward true in theorem triangle : (associator F (𝟭 B) G).hom ≫ whiskerLeft F (leftUnitor G).hom = whiskerRight (rightUnitor F).hom G := by cat_disch -set_option backward.defeqAttrib.useBackward true in theorem pentagon : whiskerRight (associator F G H).hom K ≫ (associator F (G ⋙ H) K).hom ≫ whiskerLeft F (associator G H K).hom = @@ -394,8 +380,6 @@ theorem pentagon : variable {C₁ C₂ C₃ D₁ D₂ D₃ : Type*} [Category* C₁] [Category* C₂] [Category* C₃] [Category* D₁] [Category* D₂] [Category* D₃] (E : Type*) [Category* E] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- The obvious functor `(C₁ ⥤ D₁) ⥤ (C₂ ⥤ D₂) ⥤ (D₁ ⥤ D₂ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ E)`. -/ @[simps!, implicit_reducible] def whiskeringLeft₂ : @@ -410,52 +394,45 @@ def whiskeringLeft₂ : { app := fun F₂ ↦ whiskerLeft _ ((whiskeringLeft C₁ D₁ (C₂ ⥤ E)).map ψ) } /-- Auxiliary definition for `whiskeringLeft₃`. -/ -@[simps!] +@[implicit_reducible, simps!] def whiskeringLeft₃ObjObjObj (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) (F₃ : C₃ ⥤ D₃) : (D₁ ⥤ D₂ ⥤ D₃ ⥤ E) ⥤ C₁ ⥤ C₂ ⥤ C₃ ⥤ E := (whiskeringRight _ _ _).obj (((whiskeringLeft₂ E).obj F₂).obj F₃) ⋙ (whiskeringLeft C₁ D₁ _).obj F₁ -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Auxiliary definition for `whiskeringLeft₃`. -/ -@[simps] +@[implicit_reducible, simps] def whiskeringLeft₃ObjObjMap (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) {F₃ F₃' : C₃ ⥤ D₃} (τ₃ : F₃ ⟶ F₃') : whiskeringLeft₃ObjObjObj E F₁ F₂ F₃ ⟶ whiskeringLeft₃ObjObjObj E F₁ F₂ F₃' where app F := whiskerLeft _ (whiskerLeft _ (((whiskeringLeft₂ E).obj F₂).map τ₃)) -set_option backward.isDefEq.respectTransparency false in variable (C₃ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ -@[simps] +@[implicit_reducible, simps] def whiskeringLeft₃ObjObj (F₁ : C₁ ⥤ D₁) (F₂ : C₂ ⥤ D₂) : (C₃ ⥤ D₃) ⥤ (D₁ ⥤ D₂ ⥤ D₃ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ C₃ ⥤ E) where obj F₃ := whiskeringLeft₃ObjObjObj E F₁ F₂ F₃ map τ₃ := whiskeringLeft₃ObjObjMap E F₁ F₂ τ₃ -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in variable (C₃ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ -@[simps] +@[implicit_reducible, simps] def whiskeringLeft₃ObjMap (F₁ : C₁ ⥤ D₁) {F₂ F₂' : C₂ ⥤ D₂} (τ₂ : F₂ ⟶ F₂') : whiskeringLeft₃ObjObj C₃ D₃ E F₁ F₂ ⟶ whiskeringLeft₃ObjObj C₃ D₃ E F₁ F₂' where app F₃ := whiskerRight ((whiskeringRight _ _ _).map (((whiskeringLeft₂ E).map τ₂).app F₃)) _ variable (C₂ C₃ D₂ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ -@[simps] +@[implicit_reducible, simps] def whiskeringLeft₃Obj (F₁ : C₁ ⥤ D₁) : (C₂ ⥤ D₂) ⥤ (C₃ ⥤ D₃) ⥤ (D₁ ⥤ D₂ ⥤ D₃ ⥤ E) ⥤ (C₁ ⥤ C₂ ⥤ C₃ ⥤ E) where obj F₂ := whiskeringLeft₃ObjObj C₃ D₃ E F₁ F₂ map τ₂ := whiskeringLeft₃ObjMap C₃ D₃ E F₁ τ₂ -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in variable (C₂ C₃ D₂ D₃) in /-- Auxiliary definition for `whiskeringLeft₃`. -/ -@[simps] +@[implicit_reducible, simps] def whiskeringLeft₃Map {F₁ F₁' : C₁ ⥤ D₁} (τ₁ : F₁ ⟶ F₁') : whiskeringLeft₃Obj C₂ C₃ D₂ D₃ E F₁ ⟶ whiskeringLeft₃Obj C₂ C₃ D₂ D₃ E F₁' where app F₂ := { app F₃ := whiskerLeft _ ((whiskeringLeft _ _ _).map τ₁) } From ca6d69cc839e29503761f6c9b60c6b1a0bb3cc91 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Fri, 31 Jul 2026 08:53:46 +0000 Subject: [PATCH 1096/1300] feat(Algebra/QuadraticAlgebra): add the trace (#42207) Add `QuadraticAlgebra.trace`, the trace of a quadratic algebra as an `R`-linear map. (Also fixes two typos in docstrings.) --- Mathlib/Algebra/QuadraticAlgebra/Basic.lean | 76 ++++++++++++++++++++- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean index 659edf8b3748fa..d4c878ac16f678 100644 --- a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean +++ b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean @@ -11,7 +11,7 @@ public import Mathlib.Algebra.Star.Unitary import Mathlib.Tactic.FieldSimp /-! -# Quadratic algebras: involution and norm. +# Quadratic algebras: involution, norm, and trace. Let `R` be a commutative ring. We define: @@ -19,12 +19,14 @@ Let `R` be a commutative ring. We define: * `QuadraticAlgebra.norm`: the norm +* `QuadraticAlgebra.trace`: the trace, as an `R`-linear map + We prove: * `QuadraticAlgebra.isUnit_iff_norm_isUnit`: `w : QuadraticAlgebra R a b` is a unit iff `w.norm` is a unit in `R`. -* `QuadraticAlgebra.norm_mem_nonZero_divisors_iff`: +* `QuadraticAlgebra.norm_mem_nonZeroDivisors_iff`: `w : QuadraticAlgebra R a b` isn't a zero divisor iff `w.norm` isn't a zero divisor in `R`. @@ -148,7 +150,7 @@ section star variable [CommRing R] /-- Conjugation in `QuadraticAlgebra R a b`. -The conjugate of `x + y ω` is `x + y ω' = (x - a * y) - y ω`. -/ +The conjugate of `x + y ω` is `x + y ω' = (x + b * y) - y ω`. -/ instance : Star (QuadraticAlgebra R a b) where star z := ⟨z.re + b * z.im, -z.im⟩ @@ -180,6 +182,11 @@ instance : StarRing (QuadraticAlgebra R a b) where simp only [re_star, re_mul, im_mul, im_star, mul_neg, neg_mul, neg_neg] <;> ring star_add _ _ := QuadraticAlgebra.ext (by simp only [re_star, re_add, im_add]; ring) (neg_add _ _) +/-- `z - star z` is a multiple of the difference `ω - star ω`. -/ +theorem sub_star (z : QuadraticAlgebra R a b) : + z - star z = z.im • (ω - star ω) := by + ext <;> simp <;> ring + end star section norm @@ -302,6 +309,69 @@ theorem norm_mem_nonZeroDivisors_iff {z : QuadraticAlgebra R a b} : end norm +section trace + +variable [CommRing R] + +attribute [local grind =] re_add im_add im_star re_star re_smul im_smul RingHom.id_apply + algebraMap_re algebraMap_im + +/-- The trace in a quadratic algebra, as an `R`-linear map. -/ +def trace : QuadraticAlgebra R a b →ₗ[R] R where + toFun z := 2 * z.re + b * z.im + map_add' := by grind + map_smul' := by grind [smul_eq_mul] + +variable (z : QuadraticAlgebra R a b) + +theorem trace_def : trace z = 2 * z.re + b * z.im := rfl + +@[simp] +theorem trace_algebraMap (r : R) : + trace (algebraMap R (QuadraticAlgebra R a b) r) = 2 * r := by + grind [trace_def] + +@[simp] +theorem trace_natCast (n : ℕ) : trace (n : QuadraticAlgebra R a b) = 2 * n := by + simp [trace_def, re_natCast, im_natCast] + +@[simp] +theorem trace_intCast (n : ℤ) : trace (n : QuadraticAlgebra R a b) = 2 * n := by + simp [trace_def, re_intCast, im_intCast] + +@[simp] +theorem trace_omega : trace (ω : QuadraticAlgebra R a b) = b := by + simp [trace_def] + +@[simp] +theorem trace_one : trace (1 : QuadraticAlgebra R a b) = 2 := by + simp [trace_def] + +@[simp] +theorem trace_star : trace (star z) = trace z := by + grind [trace_def] + +/-- `z + star z` is the trace of `z`. -/ +theorem algebraMap_trace_eq_add_star : + algebraMap R (QuadraticAlgebra R a b) (trace z) = z + star z := by + ext <;> grind [trace_def] + +/-- The conjugate of `z` is `trace z - z`. -/ +theorem star_eq : + star z = algebraMap R (QuadraticAlgebra R a b) (trace z) - z := by + rw [algebraMap_trace_eq_add_star, add_sub_cancel_left] + +/-- Every element of a quadratic algebra satisfies its characteristic equation. -/ +theorem sq_sub_trace_smul_add_norm_eq_zero : + z ^ 2 - trace z • z + algebraMap R _ (norm z) = 0 := by + rw [Algebra.smul_def, algebraMap_trace_eq_add_star, algebraMap_norm_eq_mul_star]; ring + +theorem sq_eq_trace_smul_sub_norm : + z ^ 2 = trace z • z - algebraMap R _ (norm z) := by + rw [← sub_eq_zero, ← sub_add, sq_sub_trace_smul_add_norm_eq_zero] + +end trace + section field variable [Field K] {a b : K} [Hab : Fact (∀ r, r ^ 2 ≠ a + b * r)] From d1906c820ac33cb410531db7a6277980309262db Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:32:19 +0000 Subject: [PATCH 1097/1300] chore(Translate/ToDual): remove redundant entry from `abbreviationDict` (#42251) This PR removes the `setOfSucc` -> `setOfPred` translation from the `to_dual` abbreviation dictionary, since the `ofSucc` -> `ofPred` translation already implies it. --- Mathlib/Tactic/Translate/ToDual.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index b1b34fed7d7d26..44bca9494aada3 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -256,11 +256,10 @@ def abbreviationDict : Std.HashMap String String := .ofList [ ("leftOrdContinuous", "RightOrdContinuous"), ("rightOrdContinuous", "LeftOrdContinuous"), + -- Revert translations if they should not happen in certain word combinations: ("neTop", "NeBot"), ("decidableSucc", "DecidablePred"), - -- `Set.ofPred` is not dual to `Set.ofSucc` ("ofSucc", "OfPred"), - ("setOfSucc", "SetOfPred"), ] @[inherit_doc GuessName.GuessNameExt] From b2933a1c2279654385ef57ab547bc221f9b30365 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:23:30 +0000 Subject: [PATCH 1098/1300] chore(Analysis/Seminorm): generalize typeclasses slightly (#42300) This is in preparation for disallowing `NormedSpace` in `Analysis.Seminorm`. --- Mathlib/Analysis/LocallyConvex/Basic.lean | 5 ++++- Mathlib/Analysis/Seminorm.lean | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/LocallyConvex/Basic.lean b/Mathlib/Analysis/LocallyConvex/Basic.lean index 4ce40495bb0431..98c9ae59a8f4e9 100644 --- a/Mathlib/Analysis/LocallyConvex/Basic.lean +++ b/Mathlib/Analysis/LocallyConvex/Basic.lean @@ -6,7 +6,8 @@ Authors: Jean Lo, Bhavik Mehta, Yaël Dillies module public import Mathlib.Analysis.Convex.Hull -public import Mathlib.Analysis.Normed.Module.Basic +public import Mathlib.Analysis.Normed.Field.Lemmas +public import Mathlib.Analysis.Normed.MulAction public import Mathlib.Topology.Bornology.Absorbs /-! # Local convexity @@ -45,6 +46,8 @@ absorbent, balanced, locally convex, LCTVS @[expose] public section +assert_not_exists NormedSpace + open Set open scoped Pointwise Topology diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index b6cc241ca2857d..cdf425bd708050 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -977,7 +977,7 @@ end NormedField section Convex -variable [NormedField 𝕜] [AddCommGroup E] [NormedSpace ℝ 𝕜] [Module 𝕜 E] +variable [NormedField 𝕜] [AddCommGroup E] [SMul ℝ 𝕜] [NormSMulClass ℝ 𝕜] [Module 𝕜 E] section SMul @@ -1018,7 +1018,7 @@ end Convex section RestrictScalars -variable (𝕜) {𝕜' : Type*} [NormedField 𝕜] [SeminormedRing 𝕜'] [NormedAlgebra 𝕜 𝕜'] +variable (𝕜) {𝕜' : Type*} [NormedField 𝕜] [SeminormedRing 𝕜'] [SMul 𝕜 𝕜'] [NormSMulClass 𝕜 𝕜'] [NormOneClass 𝕜'] [AddCommGroup E] [Module 𝕜' E] [SMul 𝕜 E] [IsScalarTower 𝕜 𝕜' E] /-- Reinterpret a seminorm over a field `𝕜'` as a seminorm over a smaller field `𝕜`. This will From 6ecc792a56a1f1287b2135eba94a3fb2ce2d01f7 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Fri, 31 Jul 2026 12:00:48 +0000 Subject: [PATCH 1099/1300] chore(GroupTheory): fix non-terminal simp (#42302) --- Mathlib/GroupTheory/SpecificGroups/Alternating.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating.lean index 9a59091907c5a9..2fe9015e1bc901 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating.lean @@ -318,7 +318,6 @@ theorem nontrivial_of_three_le_card (h3 : 3 ≤ Nat.card α) : Nontrivial (alter instance {n : ℕ} : Nontrivial (alternatingGroup (Fin (n + 3))) := nontrivial_of_three_le_card (by simp) -set_option linter.flexible false in -- TODO: fix non-terminal simp /-- Shows that any non-identity element of $A_5$ whose cycle decomposition consists only of swaps is conjugate to $(04)(13)$. This is used to show that the normal closure of such a permutation in $A_5$ is $A_5$. -/ @@ -332,9 +331,8 @@ theorem isConj_swap_mul_swap_of_cycleType_two {g : Perm (Fin 5)} (ha : g ∈ alt rw [← sum_cycleType, h2, Multiset.sum_replicate, smul_eq_mul] at h have h : Multiset.card g.cycleType ≤ 3 := le_of_mul_le_mul_right (le_trans h (by norm_num only [card_fin])) (by simp) - rw [mem_alternatingGroup, sign_of_cycleType, h2] at ha - simp at ha - rw [pow_add, pow_mul, Int.units_pow_two, one_mul, neg_one_pow_eq_one_iff_even] at ha + rw [mem_alternatingGroup, sign_of_cycleType, h2, Multiset.sum_replicate, Multiset.card_replicate, + smul_eq_mul, pow_add, pow_mul, Int.units_pow_two, one_mul, neg_one_pow_eq_one_iff_even] at ha swap; · decide rw [isConj_iff_cycleType_eq, h2] interval_cases h_1 : Multiset.card g.cycleType From 232b5fd2613910bc74c3f6372b0fb2b9ea677df8 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 31 Jul 2026 12:20:37 +0000 Subject: [PATCH 1100/1300] fix(Translate): support structures where a universe level doesn't appear in the type (#42228) This PR fixes a bug in `to_dual`/`to_additive` that makes it impossible to use it on a structure where a universe level doesn't appear in its type. --- Mathlib/Tactic/Translate/Core.lean | 11 ++++++++--- MathlibTest/Attribute/ToDual.lean | 8 ++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index f4696a0fa9bfe5..a7e4bb221eb5dc 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -1004,10 +1004,15 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config type{indentExpr tgtType}" -- Process any remaining universe contraints, to assign all universe metavariables. discard <| processPostponed (mayPostpone := false) (exceptionOnFailure := true) - let params ← levels.mapM fun level ↦ do match ← instantiateLevelMVars level with + let tgtParams := tgtDecl.levelParams.toArray + let params ← levels.mapIdxM fun i level ↦ do + match ← instantiateLevelMVars level with | .param u => return u - | _ => throwError "inferred universe `{level}` in `{srcType}` is not a parameter." - let some univReorder := getPermutation params.toArray tgtDecl.levelParams.toArray | + | _ => + -- For example in `HasLimitsOfSize`, not all universe levels appear in the type. + -- In that case, default to not permuting the universe levels. + return tgtParams[i]! + let some univReorder := getPermutation params.toArray tgtParams | throwError "inferred universe parameters {params} \ are not a reordering of {srcDecl.levelParams}." return ({ univReorder, reorder }, ← getRelevantArg t cfg relevantArg? src lint) diff --git a/MathlibTest/Attribute/ToDual.lean b/MathlibTest/Attribute/ToDual.lean index 539ba3e99d00b5..8b928456b9b4f2 100644 --- a/MathlibTest/Attribute/ToDual.lean +++ b/MathlibTest/Attribute/ToDual.lean @@ -447,3 +447,11 @@ to_dual_name_hint Left Right, Epi Mono /-- info: "right_epi" -/ #guard_msgs in #eval return GuessName.guessName (data.guessNameExt.getState (← getEnv)) "left_mono" + +-- A structure with a universe not appearing in its type +structure HasLimitsOfSize where + foo : ∀ _ : Type u, True + +@[to_dual] +structure HasColimitsOfSize where + cofoo : ∀ _ : Type u, True From 45e3065c10669f3a91349ec140e6f218cfc162cd Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 31 Jul 2026 13:14:11 +0000 Subject: [PATCH 1101/1300] perf(AlgebraicGeometry/Group/Affine): specify the universe explicitly (#42303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a universe annotation in `algΓAlgSpecAdjunction`, which was seemingly forgotten. This speeds it up by more that 10x. In the rest of the file, the universe is already specified everywhere. For an explanation of why a universe metavariable can cause such an enormous slowdown, see https://github.com/leanprover/lean4/issues/10414 --- Mathlib/AlgebraicGeometry/Group/Affine.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/Group/Affine.lean b/Mathlib/AlgebraicGeometry/Group/Affine.lean index f35aa382472e43..8fc001b4a80655 100644 --- a/Mathlib/AlgebraicGeometry/Group/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Group/Affine.lean @@ -298,7 +298,7 @@ def Spec.mapMulEquiv {R S T : Type u} [CommRing R] [CommRing S] [CommRing T] [Bi /-- The adjunction between `Spec` and `Γ` as functors between commutative `R`-algebras and schemes over `Spec R`. -/ -def algΓAlgSpecAdjunction (R : CommRingCat) : algΓ R ⊣ algSpec R := by +def algΓAlgSpecAdjunction (R : CommRingCat.{u}) : algΓ R ⊣ algSpec R := by have overAdjunction := Over.postAdjunctionRight (Y := .op <| R) ΓSpec.adjunction have overEquivAlg := ((Over.opEquivOpUnder R).trans (commAlgCatEquivUnder R).op.symm).toAdjunction simpa using! overAdjunction.comp overEquivAlg From 6a58949cc7b3db2cc8045f904fa21b9fc0954657 Mon Sep 17 00:00:00 2001 From: JX-Mo <296066944+JX-Mo@users.noreply.github.com> Date: Fri, 31 Jul 2026 13:35:12 +0000 Subject: [PATCH 1102/1300] feat(RepresentationTheory): add a surjectivity lemma for irreducible representations (#42151) Add a missing surjectivity lemma `surjective_or_eq_zero` for irreducible representations, parallel to the existing `injective_or_eq_zero` `bijective_or_eq_zero`. --- Mathlib/RepresentationTheory/Irreducible.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/RepresentationTheory/Irreducible.lean b/Mathlib/RepresentationTheory/Irreducible.lean index 85891bec9b62f0..df11ceb7d94f17 100644 --- a/Mathlib/RepresentationTheory/Irreducible.lean +++ b/Mathlib/RepresentationTheory/Irreducible.lean @@ -57,6 +57,10 @@ theorem injective_or_eq_zero : Injective f ∨ f = 0 := by rw [← LinearEquiv.map_eq_zero_iff (equivLinearMapAsModule ρ σ)] exact LinearMap.injective_or_eq_zero (equivLinearMapAsModule ρ σ f) +theorem surjective_or_eq_zero (g : IntertwiningMap σ ρ) : Surjective g ∨ g = 0 := by + rw [← LinearEquiv.map_eq_zero_iff (equivLinearMapAsModule σ ρ)] + exact LinearMap.surjective_or_eq_zero (equivLinearMapAsModule σ ρ g) + theorem bijective_or_eq_zero [IsIrreducible σ] : Bijective f ∨ f = 0 := by rw [← LinearEquiv.map_eq_zero_iff (equivLinearMapAsModule ρ σ)] exact LinearMap.bijective_or_eq_zero (equivLinearMapAsModule ρ σ f) From a366f8766595f1297c03ef38b8d7ee326d75377a Mon Sep 17 00:00:00 2001 From: Fawad Haider <153737+FawadHa1der@users.noreply.github.com> Date: Fri, 31 Jul 2026 13:44:39 +0000 Subject: [PATCH 1103/1300] perf(MeasureTheory/Integral/IntervalIntegral/Periodic): explicit proof instead of aesop (#41870) The file speeds up by 25%, with significant impact on readability. --- .../MeasureTheory/Integral/IntervalIntegral/Periodic.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean index 2a6fd7c4acb662..cd33a5430f23b8 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Periodic.lean @@ -285,7 +285,7 @@ theorem intervalIntegrable {t : ℝ} (h₁f : Function.Periodic f T) wlog hT : 0 < T · rcases (not_lt.1 hT).eq_or_lt with h | h · tauto - · have hnT : 0 < -T := by aesop + · have hnT : 0 < -T := neg_pos.mpr h nth_rw 1 [(by ring : t = (t + T) + (-T))] at h₂f apply this h₁f.neg hnT.ne' h₂f.symm _ _ hnT -- Replace [a₁, a₂] by [t - n₁ * T, t + n₂ * T], where n₁ and n₂ are natural numbers @@ -307,7 +307,7 @@ theorem intervalIntegrable {t : ℝ} (h₁f : Function.Periodic f T) apply IntervalIntegrable.trans_iterate -- Show integrability over a shifted period intro k hk - convert! (IntervalIntegrable.comp_sub_right h₂f ((k - n₁) * T) (by aesop)) using 1 + convert! (IntervalIntegrable.comp_sub_right h₂f ((k - n₁) * T) enorm_ne_top) using 1 · funext x simpa using (h₁f.sub_int_mul_eq (k - n₁)).symm · simp [a, Nat.cast_add] @@ -347,10 +347,10 @@ theorem intervalIntegral_add_eq (hf : Periodic f T) (t s : ℝ) : ∫ x in t..t + T, f x = ∫ x in s..s + T, f x := by wlog hT : 0 < T · rcases (not_lt.1 hT).eq_or_lt with hT | hT - · aesop + · simp [hT] · rw [← neg_inj, ← integral_symm, ← integral_symm] simpa only [← sub_eq_add_neg, add_sub_cancel_right] using - this hf.neg (t + T) (s + T) (by aesop : 0 < -T) + this hf.neg (t + T) (s + T) (neg_pos.mpr hT) simp only [integral_of_le, hT.le, le_add_iff_nonneg_right] have : VAddInvariantMeasure (AddSubgroup.zmultiples T) ℝ volume := ⟨fun c s _ => measure_preimage_add _ _ _⟩ From ff4f94af10d0da3316c454c98b48cd7cb97f9ef7 Mon Sep 17 00:00:00 2001 From: Oliver Butterley <51876429+oliver-butterley@users.noreply.github.com> Date: Fri, 31 Jul 2026 13:44:42 +0000 Subject: [PATCH 1104/1300] feat (Linter/Header): add config for custom copyright (#41876) This PR adds the config option `linter.style.header.license` to the header linter. This allows downstream projects to use the linter on their projects even if they need to specify a different license or a different filename for the license. --- Mathlib/Tactic/Linter/Header.lean | 16 +++++++++++---- MathlibTest/Linter/Header/Basic.lean | 29 +++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Mathlib/Tactic/Linter/Header.lean b/Mathlib/Tactic/Linter/Header.lean index 40b79e7b281843..cf0a040112910e 100644 --- a/Mathlib/Tactic/Linter/Header.lean +++ b/Mathlib/Tactic/Linter/Header.lean @@ -175,11 +175,13 @@ The input is the copyright string, the output is an array of `Syntax × String` The linter checks that * the first and last line of the copyright are a `("/-", "-/")` pair, each on its own line; * the first line is begins with `Copyright (c) 20` and ends with `. All rights reserved.`; -* the second line is `Released under Apache 2.0 license as described in the file LICENSE.`; +* the second line equals `expectedLicense` (determined by the `linter.style.header.license` option, + defaults to the Mathlib default); * the remainder of the string begins with `Authors: `, does not end with `.` and contains no ` and ` nor a double space, except possibly after a line break. -/ -public def copyrightHeaderChecks (copyright : String) : Array (Syntax × String) := Id.run do +public def copyrightHeaderChecks (copyright : String) (expectedLicense : String) : + Array (Syntax × String) := Id.run do -- First, we merge lines ending in `,`: two spaces after the line-break are ok, -- but so is only one or none. We take care of *not* adding more consecutive spaces, though. -- This is to allow the copyright or authors' lines to span several lines. @@ -240,7 +242,6 @@ public def copyrightHeaderChecks (copyright : String) : Array (Syntax × String) "If an authors line spans multiple lines, \ each line but the last must end with a trailing comma") output := output.append (authorsLineChecks authorsLine authorsStart) - let expectedLicense := "Released under Apache 2.0 license as described in the file LICENSE." if license != expectedLicense then output := output.push (toSyntax copyright license, s!"Second copyright line should be \"{expectedLicense}\"") @@ -299,6 +300,12 @@ public register_option linter.style.header : Bool := { descr := "enable the header style linter" } +/-- The text required by `linter.style.header` as the second line of the header. -/ +public register_option linter.style.header.license : String := { + defValue := "Released under Apache 2.0 license as described in the file LICENSE." + descr := "The text required as the second line of the copyright header." +} + namespace Style.header /-- Check the `Syntax` `imports` for broad imports: @@ -437,7 +444,8 @@ def headerLinter : Linter where run := withSetOptionIn fun stx ↦ do | _ => "" -- Report any errors about the copyright line. if mainModule != `Mathlib.Init && mainModule != `Mathlib.Tactic then - for (stx, m) in copyrightHeaderChecks copyright do + let expectedLicense := linter.style.header.license.get (← getOptions) + for (stx, m) in copyrightHeaderChecks copyright expectedLicense do Linter.logLint linter.style.header stx m!"* '{stx.getAtomVal}':\n{m}\n" -- Report a missing module doc-string. match afterImports with diff --git a/MathlibTest/Linter/Header/Basic.lean b/MathlibTest/Linter/Header/Basic.lean index 714f3240c91f8e..1fb89a5e845f93 100644 --- a/MathlibTest/Linter/Header/Basic.lean +++ b/MathlibTest/Linter/Header/Basic.lean @@ -58,7 +58,8 @@ It logs details of what the linter would report if the `cop` is "malformed". elab "#check_copyright " copStx:str : command => do let cop := copStx.getString let offset := copStx.raw.getPos?.get!.increaseBy 1 - for (s, m) in Mathlib.Linter.copyrightHeaderChecks cop do + let expectedLicense := Mathlib.Linter.linter.style.header.license.get (← getOptions) + for (s, m) in Mathlib.Linter.copyrightHeaderChecks cop expectedLicense do if let some rg := s.getRange? then logInfoAt (.ofRange ({start := rg.start.offsetBy offset, stop := rg.stop.offsetBy offset})) m!"Text: `{replaceMultilineComments s.getAtomVal}`\n\ @@ -211,6 +212,32 @@ Authors: Name LastName -/ " +-- The required second line is configurable via the `linter.style.header.license` option. +/-- +info: Text: `Released under Apache 2.0 license as described in the file LICENSE.` +Range: (49, 116) +Message: 'Second copyright line should be "Released under the Custom License."' +-/ +#guard_msgs in +set_option linter.style.header.license "Released under the Custom License." in +#check_copyright +"/- +Copyright (c) 2026 Name. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name +-/ +" + +-- A header whose second line matches the custom license is accepted. +set_option linter.style.header.license "Released under the Custom License." in +#check_copyright +"/- +Copyright (c) 2026 Name. All rights reserved. +Released under the Custom License. +Authors: Name +-/ +" + /-- info: Text: `A uthors:` Range: (126, 135) From d222514f99b0055e82a912e7e9e5cdb72e6abcfe Mon Sep 17 00:00:00 2001 From: ybenmeur <180416181+ybenmeur@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:37:55 +0000 Subject: [PATCH 1105/1300] chore(FGModuleCat/EssentiallySmall): generalize to `Ring` (#42006) Replace the `CommRing` instance with `Ring`. --- Mathlib/Algebra/Category/FGModuleCat/EssentiallySmall.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Category/FGModuleCat/EssentiallySmall.lean b/Mathlib/Algebra/Category/FGModuleCat/EssentiallySmall.lean index 5f569b9d613185..e8aae510b9afcf 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/EssentiallySmall.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/EssentiallySmall.lean @@ -21,7 +21,7 @@ recommended to use the standard `CategoryTheory.SmallModel (FGModuleCat R)` inst universe v w u -variable (R : Type u) [CommRing R] +variable (R : Type u) [Ring R] open CategoryTheory From ce88332a27540b49d649b17a9d1a8c1cdfb9f193 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:37:57 +0000 Subject: [PATCH 1106/1300] feat(LinearAlgebra): use `IsApply` for `QuadraticMap` (#42134) --- .../CliffordAlgebraNotInjective.lean | 4 +- .../CliffordAlgebra/Contraction.lean | 3 +- .../LinearAlgebra/CliffordAlgebra/Equivs.lean | 2 +- .../CliffordAlgebra/EvenEquiv.lean | 10 +- .../LinearAlgebra/QuadraticForm/Basic.lean | 117 ++++++------------ Mathlib/LinearAlgebra/QuadraticForm/Dual.lean | 8 +- 6 files changed, 51 insertions(+), 93 deletions(-) diff --git a/Counterexamples/CliffordAlgebraNotInjective.lean b/Counterexamples/CliffordAlgebraNotInjective.lean index d06713dea372d6..391f689833da0d 100644 --- a/Counterexamples/CliffordAlgebraNotInjective.lean +++ b/Counterexamples/CliffordAlgebraNotInjective.lean @@ -163,10 +163,10 @@ def Q' : QuadraticForm K (Fin 3 → K) := ∑ i, sq i theorem Q'_add (x y : Fin 3 → K) : Q' (x + y) = Q' x + Q' y := by - simp only [Q', QuadraticMap.sum_apply, sq_map_add_char_two, Finset.sum_add_distrib] + simp only [Q', sum_apply, sq_map_add_char_two, Finset.sum_add_distrib] theorem Q'_sub (x y : Fin 3 → K) : Q' (x - y) = Q' x - Q' y := by - simp only [Q', QuadraticMap.sum_apply, sq_map_sub_char_two, Finset.sum_sub_distrib] + simp only [Q', sum_apply, sq_map_sub_char_two, Finset.sum_sub_distrib] theorem Q'_apply (a : Fin 3 → K) : Q' a = a 0 * a 0 + a 1 * a 1 + a 2 * a 2 := calc diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean index 75e22d61ca3c93..1cf62573ab4202 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Contraction.lean @@ -242,8 +242,7 @@ def changeForm (h : B.toQuadraticMap = Q' - Q) : CliffordAlgebra Q →ₗ[R] Cli foldr Q (changeFormAux Q' B) (fun m x => (changeFormAux_changeFormAux Q' B m x).trans <| by - dsimp only [← BilinMap.toQuadraticMap_apply] - rw [h, QuadraticMap.sub_apply, sub_sub_cancel]) + rw [← BilinMap.toQuadraticMap_apply, h, sub_apply, sub_sub_cancel]) 1 /-- Auxiliary lemma used as an argument to `CliffordAlgebra.changeForm` -/ diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean index cc95bd4a21cdfb..69383a1c5d08c9 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean @@ -341,7 +341,7 @@ variable {R : Type*} [CommRing R] theorem ι_mul_ι (r₁ r₂) : ι (0 : QuadraticForm R R) r₁ * ι (0 : QuadraticForm R R) r₂ = 0 := by rw [← mul_one r₁, ← mul_one r₂, ← smul_eq_mul r₁, ← smul_eq_mul r₂, map_smul, map_smul, - smul_mul_smul_comm, ι_sq_scalar, QuadraticMap.zero_apply, map_zero, smul_zero] + smul_mul_smul_comm, ι_sq_scalar, zero_apply, map_zero, smul_zero] set_option backward.isDefEq.respectTransparency.types false in /-- The clifford algebra over a 1-dimensional vector space with 0 quadratic form is isomorphic to diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean index fc30d6145d90b5..5dbfba9992d349 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean @@ -74,9 +74,7 @@ theorem v_sq_scalar (m : M) : v Q m * v Q m = algebraMap _ _ (Q m) := set_option backward.defeqAttrib.useBackward true in theorem neg_e0_mul_v (m : M) : -(e0 Q * v Q m) = v Q m * e0 Q := by refine neg_eq_of_add_eq_zero_right ((ι_mul_ι_add_swap _ _).trans ?_) - dsimp [QuadraticMap.polar] - simp only [add_zero, mul_zero, mul_one, zero_add, neg_zero, - add_sub_cancel_right, sub_self, map_zero] + simp [QuadraticMap.polar] theorem neg_v_mul_e0 (m : M) : -(v Q m * e0 Q) = e0 Q * v Q m := by rw [neg_eq_iff_eq_neg] @@ -228,10 +226,10 @@ def evenToNeg (Q' : QuadraticForm R M) (h : Q' = -Q) : even.lift Q <| { bilin := -(even.ι Q' :).bilin contract := fun m => by - simp_rw [LinearMap.neg_apply, EvenHom.contract, h, QuadraticMap.neg_apply, map_neg, neg_neg] + simp_rw [LinearMap.neg_apply, EvenHom.contract, h, neg_apply, map_neg, neg_neg] contract_mid := fun m₁ m₂ m₃ => by - simp_rw [LinearMap.neg_apply, neg_mul_neg, EvenHom.contract_mid, h, - QuadraticMap.neg_apply, smul_neg, neg_smul] } + simp_rw [LinearMap.neg_apply, neg_mul_neg, EvenHom.contract_mid, h, neg_apply, smul_neg, + neg_smul] } @[simp] theorem evenToNeg_ι (Q' : QuadraticForm R M) (h : Q' = -Q) (m₁ m₂ : M) : diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index ecbafd2a2f869b..a89e55fcc8c95c 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -408,19 +408,18 @@ instance : SMul S (QuadraticMap R M N) := letI := SMulCommClass.symm S R N ⟨a • B, by simp [h]⟩ }⟩ -@[simp, norm_cast] -theorem coeFn_smul (a : S) (Q : QuadraticMap R M N) : ⇑(a • Q) = a • ⇑Q := - rfl +instance : IsSMulApply S (QuadraticMap R M N) M N where + smul_apply _ _ _ := rfl -@[simp] -theorem smul_apply (a : S) (Q : QuadraticMap R M N) (x : M) : (a • Q) x = a • Q x := - rfl +@[deprecated (since := "2026-07-27")] alias coeFn_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-27")] protected alias smul_apply := smul_apply -instance [SMulCommClass S T N] : SMulCommClass S T (QuadraticMap R M N) where - smul_comm _s _t _q := ext fun _ => smul_comm _ _ _ +instance [SMulCommClass S T N] : SMulCommClass S T (QuadraticMap R M N) := + FunLike.smulCommClass -instance [SMul S T] [IsScalarTower S T N] : IsScalarTower S T (QuadraticMap R M N) where - smul_assoc _s _t _q := ext fun _ => smul_assoc _ _ _ +instance [SMul S T] [IsScalarTower S T N] : IsScalarTower S T (QuadraticMap R M N) := + FunLike.isScalarTower end SMul @@ -429,13 +428,12 @@ instance : Zero (QuadraticMap R M N) := toFun_smul := fun a _ => by simp only [smul_zero] exists_companion' := ⟨0, fun _ _ => by simp only [add_zero, LinearMap.zero_apply]⟩ }⟩ -@[simp, norm_cast] -theorem coeFn_zero : ⇑(0 : QuadraticMap R M N) = 0 := - rfl +instance : IsZeroApply (QuadraticMap R M N) M N where + zero_apply _ := rfl -@[simp] -theorem zero_apply (x : M) : (0 : QuadraticMap R M N) x = 0 := - rfl +@[deprecated (since := "2026-07-27")] alias coeFn_zero := FunLike.coe_zero + +@[deprecated (since := "2026-07-27")] protected alias zero_apply := zero_apply instance : Inhabited (QuadraticMap R M N) := ⟨0⟩ @@ -450,64 +448,33 @@ instance : Add (QuadraticMap R M N) := ⟨B + B', fun x y => by simp_rw [Pi.add_apply, h, h', LinearMap.add_apply, add_add_add_comm]⟩ }⟩ -@[simp, norm_cast] -theorem coeFn_add (Q Q' : QuadraticMap R M N) : ⇑(Q + Q') = Q + Q' := - rfl +instance : IsAddApply (QuadraticMap R M N) M N where + add_apply _ _ _ := rfl -@[simp] -theorem add_apply (Q Q' : QuadraticMap R M N) (x : M) : (Q + Q') x = Q x + Q' x := - rfl +@[deprecated (since := "2026-07-27")] alias coeFn_add := FunLike.coe_add -instance : AddCommMonoid (QuadraticMap R M N) := - DFunLike.coe_injective.addCommMonoid _ coeFn_zero coeFn_add fun _ _ => coeFn_smul _ _ +@[deprecated (since := "2026-07-27")] protected alias add_apply := add_apply -/-- `@CoeFn (QuadraticMap R M)` as an `AddMonoidHom`. +instance : AddCommMonoid (QuadraticMap R M N) := fast_instance% FunLike.addCommMonoid -This API mirrors `AddMonoidHom.coeFn`. -/ -@[simps apply] -def coeFnAddMonoidHom : QuadraticMap R M N →+ M → N where - toFun := DFunLike.coe - map_zero' := coeFn_zero - map_add' := coeFn_add +@[deprecated (since := "2026-07-27")] alias coeFnAddMonoidHom := FunLike.coeAddMonoidHom + +@[deprecated (since := "2026-07-27")] alias coeFnAddMonoidHom_apply := FunLike.coeAddMonoidHom_apply /-- Evaluation on a particular element of the module `M` is an additive map on quadratic maps. -/ @[simps! apply] def evalAddMonoidHom (m : M) : QuadraticMap R M N →+ N := - (Pi.evalAddMonoidHom _ m).comp coeFnAddMonoidHom + (Pi.evalAddMonoidHom _ m).comp (FunLike.coeAddMonoidHom _ _ _) -section Sum +@[deprecated (since := "2026-07-27")] alias coeFn_sum := FunLike.coe_sum -@[simp, norm_cast] -theorem coeFn_sum {ι : Type*} (Q : ι → QuadraticMap R M N) (s : Finset ι) : - ⇑(∑ i ∈ s, Q i) = ∑ i ∈ s, ⇑(Q i) := - map_sum coeFnAddMonoidHom Q s - -@[simp] -theorem sum_apply {ι : Type*} (Q : ι → QuadraticMap R M N) (s : Finset ι) (x : M) : - (∑ i ∈ s, Q i) x = ∑ i ∈ s, Q i x := - map_sum (evalAddMonoidHom x : _ →+ N) Q s - -end Sum +@[deprecated (since := "2026-07-27")] protected alias sum_apply := sum_apply instance [Monoid S] [DistribMulAction S N] [SMulCommClass S R N] : - DistribMulAction S (QuadraticMap R M N) where - mul_smul a b Q := ext fun x => by simp only [smul_apply, mul_smul] - one_smul Q := ext fun x => by simp only [QuadraticMap.smul_apply, one_smul] - smul_add a Q Q' := by - ext - simp only [add_apply, smul_apply, smul_add] - smul_zero a := by - ext - simp only [zero_apply, smul_apply, smul_zero] + DistribMulAction S (QuadraticMap R M N) := fast_instance% FunLike.distribMulAction instance [Semiring S] [Module S N] [SMulCommClass S R N] : - Module S (QuadraticMap R M N) where - zero_smul Q := by - ext - simp only [zero_apply, smul_apply, zero_smul] - add_smul a b Q := by - ext - simp only [add_apply, smul_apply, add_smul] + Module S (QuadraticMap R M N) := fast_instance% FunLike.module end SemiringOperators @@ -523,28 +490,24 @@ instance : Neg (QuadraticMap R M N) := let ⟨B, h⟩ := Q.exists_companion ⟨-B, fun x y => by simp_rw [Pi.neg_apply, h, LinearMap.neg_apply, neg_add]⟩ }⟩ -@[simp, norm_cast] -theorem coeFn_neg (Q : QuadraticMap R M N) : ⇑(-Q) = -Q := - rfl +instance : IsNegApply (QuadraticMap R M N) M N where + neg_apply _ _ := rfl -@[simp] -theorem neg_apply (Q : QuadraticMap R M N) (x : M) : (-Q) x = -Q x := - rfl +@[deprecated (since := "2026-07-27")] alias coeFn_neg := FunLike.coe_neg + +@[deprecated (since := "2026-07-27")] protected alias neg_apply := neg_apply instance : Sub (QuadraticMap R M N) := ⟨fun Q Q' => (Q + -Q').copy (Q - Q') (sub_eq_add_neg _ _)⟩ -@[simp, norm_cast] -theorem coeFn_sub (Q Q' : QuadraticMap R M N) : ⇑(Q - Q') = Q - Q' := - rfl +instance : IsSubApply (QuadraticMap R M N) M N where + sub_apply _ _ _ := rfl -@[simp] -theorem sub_apply (Q Q' : QuadraticMap R M N) (x : M) : (Q - Q') x = Q x - Q' x := - rfl +@[deprecated (since := "2026-07-27")] alias coeFn_sub := FunLike.coe_sub -instance : AddCommGroup (QuadraticMap R M N) := - DFunLike.coe_injective.addCommGroup _ coeFn_zero coeFn_add coeFn_neg coeFn_sub - (fun _ _ => coeFn_smul _ _) fun _ _ => coeFn_smul _ _ +@[deprecated (since := "2026-07-27")] protected alias sub_apply := sub_apply + +instance : AddCommGroup (QuadraticMap R M N) := fast_instance% FunLike.addCommGroup end RingOperators @@ -573,7 +536,6 @@ section Comp variable [CommSemiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] variable [AddCommMonoid P] [Module R P] -set_option backward.isDefEq.respectTransparency false in /-- Compose the quadratic map with a linear function on the right. -/ def comp (Q : QuadraticMap R N P) (f : M →ₗ[R] N) : QuadraticMap R M P where toFun x := Q (f x) @@ -586,7 +548,6 @@ def comp (Q : QuadraticMap R N P) (f : M →ₗ[R] N) : QuadraticMap R M P where theorem comp_apply (Q : QuadraticMap R N P) (f : M →ₗ[R] N) (x : M) : (Q.comp f) x = Q (f x) := rfl -set_option backward.isDefEq.respectTransparency false in /-- Compose a quadratic map with a linear function on the left. -/ @[simps +simpRhs] def _root_.LinearMap.compQuadraticMap (f : N →ₗ[R] P) (Q : QuadraticMap R M N) : @@ -1465,7 +1426,7 @@ end theorem weightedSumSquares_apply [Monoid S] [DistribMulAction S R] [SMulCommClass S R R] (w : ι → S) (v : ι → R) : weightedSumSquares R w v = ∑ i : ι, w i • (v i * v i) := - QuadraticMap.sum_apply _ _ _ + sum_apply _ _ _ /-- On an orthogonal basis, the basis representation of `Q` is just a sum of squares. -/ theorem basisRepr_eq_of_iIsOrtho {R M} [CommRing R] [AddCommGroup M] [Module R M] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean b/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean index fe0a872ae49e73..0f63ac84e22910 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Dual.lean @@ -141,10 +141,10 @@ def toDualProd (Q : QuadraticForm R M) [Invertible (2 : R)] : dsimp only [LinearMap.smul_apply, LinearMap.coe_mk, AddHom.coe_mk, AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearMap.prod_apply, Function.prod_apply, LinearMap.add_apply, LinearMap.coe_comp, Function.comp_apply, LinearMap.fst_apply, LinearMap.snd_apply, - LinearMap.sub_apply, dualProd_apply, polarBilin_apply_apply, QuadraticMap.prod_apply, - QuadraticMap.neg_apply] - simp only [polar_sub_right, polar_self, nsmul_eq_mul, Nat.cast_ofNat, polar_comm _ x.1 x.2, - smul_sub, Module.End.smul_def, sub_add_sub_cancel, ← sub_eq_add_neg (Q x.1) (Q x.2)] + LinearMap.sub_apply, dualProd_apply, polarBilin_apply_apply, QuadraticMap.prod_apply] + simp only [neg_apply, polar_sub_right, polar_self, nsmul_eq_mul, Nat.cast_ofNat, + polar_comm _ x.1 x.2, smul_sub, Module.End.smul_def, sub_add_sub_cancel, + ← sub_eq_add_neg (Q x.1) (Q x.2)] rw [← map_sub (⅟2 : Module.End R R), ← mul_sub, ← Module.End.smul_def] simp only [Module.End.smul_def, half_moduleEnd_apply_eq_half_smul, smul_eq_mul, invOf_mul_cancel_left'] From f4570dc2f3c801ed0c0edd5867f943e2b84e4dec Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:06:37 +0000 Subject: [PATCH 1107/1300] chore(RingTheory/*): remove domain assumptions by generalizing from torsion free to faithful smul (#41379) This PR removes some `IsDomain` assumptions by generalizing `Module.IsTorsionFree` to `FaithfulSMul`. (As @SnirBroshi pointed out in the comments, this is not quite a generalization when the top ring is the zero ring, but this never arises in practice). Co-authored-by: tb65536 --- Mathlib/RingTheory/Conductor.lean | 4 +--- Mathlib/RingTheory/Ideal/Maps.lean | 4 ++-- Mathlib/RingTheory/Ideal/Over.lean | 11 ++++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Mathlib/RingTheory/Conductor.lean b/Mathlib/RingTheory/Conductor.lean index e858142535f2eb..01c6d097802771 100644 --- a/Mathlib/RingTheory/Conductor.lean +++ b/Mathlib/RingTheory/Conductor.lean @@ -63,11 +63,9 @@ theorem conductor_eq_top_iff_adjoin_eq_top {x : S} : open IsLocalization in lemma mem_coeSubmodule_conductor {L} [CommRing L] [Algebra S L] [Algebra R L] - [IsScalarTower R S L] [IsDomain S] [IsTorsionFree S L] {x : S} {y : L} : + [IsScalarTower R S L] [FaithfulSMul S L] {x : S} {y : L} : y ∈ coeSubmodule L (conductor R x) ↔ ∀ z : S, y * (algebraMap S L) z ∈ R[algebraMap S L x] := by - cases subsingleton_or_nontrivial L - · rw [Subsingleton.elim (coeSubmodule L _) ⊤, Subsingleton.elim (Algebra.adjoin R _) ⊤]; simp trans ∀ z, y * (algebraMap S L) z ∈ (R[x]).map (IsScalarTower.toAlgHom R S L) · simp only [coeSubmodule, Submodule.mem_map, linearMap_apply, Subalgebra.mem_map, IsScalarTower.coe_toAlgHom'] diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 042bd37972fd1a..2dd5b25132441b 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -1128,8 +1128,8 @@ section CommRing variable [CommRing R] [CommRing S] -theorem map_ne_bot_of_ne_bot [IsDomain R] {S : Type*} [Ring S] [Nontrivial S] [Algebra R S] - [Module.IsTorsionFree R S] {I : Ideal R} (h : I ≠ ⊥) : map (algebraMap R S) I ≠ ⊥ := +theorem map_ne_bot_of_ne_bot {R S : Type*} [CommSemiring R] [Semiring S] [Algebra R S] + [FaithfulSMul R S] {I : Ideal R} (h : I ≠ ⊥) : map (algebraMap R S) I ≠ ⊥ := (map_eq_bot_iff_of_injective (FaithfulSMul.algebraMap_injective R S)).mp.mt h theorem map_eq_iff_sup_ker_eq_of_surjective {I J : Ideal R} (f : R →+* S) diff --git a/Mathlib/RingTheory/Ideal/Over.lean b/Mathlib/RingTheory/Ideal/Over.lean index cc305ab486e261..00575891528501 100644 --- a/Mathlib/RingTheory/Ideal/Over.lean +++ b/Mathlib/RingTheory/Ideal/Over.lean @@ -256,8 +256,8 @@ end CommSemiring section CommRing -variable (A B : Type*) [CommRing A] [IsDomain A] [Ring B] [Nontrivial B] - [Algebra A B] [Module.IsTorsionFree A B] {p : Ideal A} +variable (A B : Type*) [CommSemiring A] [Semiring B] + [Algebra A B] [FaithfulSMul A B] {p : Ideal A} @[simp] theorem under_bot : under A (⊥ : Ideal B) = ⊥ := @@ -389,9 +389,10 @@ abbrev primesOver.mk (P : Ideal B) [hPp : P.IsPrime] [hp : P.LiesOver p] : prime ⟨P, ⟨hPp, hp⟩⟩ variable {p} in -theorem ne_bot_of_mem_primesOver [IsDomain R] {S : Type*} [Ring S] [Algebra R S] [Nontrivial S] - [Module.IsTorsionFree R S] {p : Ideal R} (hp : p ≠ ⊥) {P : Ideal S} (hP : P ∈ p.primesOver S) : - P ≠ ⊥ := by have : P.LiesOver p := hP.2; exact ne_bot_of_liesOver_of_ne_bot hp P +theorem ne_bot_of_mem_primesOver [FaithfulSMul A B] (hp : p ≠ ⊥) {P : Ideal B} + (hP : P ∈ p.primesOver B) : P ≠ ⊥ := by + have : P.LiesOver p := hP.2 + exact ne_bot_of_liesOver_of_ne_bot hp P end primesOver From 1f8806b67d6f09e6d2552c031e6d3a3171016116 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Fri, 31 Jul 2026 22:26:39 +0000 Subject: [PATCH 1108/1300] fix: adaptations for batteries #1927 (#42229) After [batteries#1927](https://github.com/leanprover-community/batteries/pull/1927) is merged: - [x] Merge leanprover-community/mathlib4:master - [x] Edit the lakefile to point to leanprover-community/batteries:main - [x] Run lake update batteries - [ ] Wait for CI and merge Co-authored-by: mathlib-nightly-testing[bot] --- Mathlib/Data/Fintype/Perm.lean | 3 ++- Mathlib/Data/List/Destutter.lean | 3 ++- Mathlib/Data/List/Lookmap.lean | 6 +++--- Mathlib/Data/List/Sublists.lean | 2 +- Mathlib/GroupTheory/Perm/ClosureSwap.lean | 8 ++++---- Mathlib/GroupTheory/Perm/List.lean | 18 +++++++++--------- lake-manifest.json | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Mathlib/Data/Fintype/Perm.lean b/Mathlib/Data/Fintype/Perm.lean index 49f2a6858afe5e..eba49a680980b1 100644 --- a/Mathlib/Data/Fintype/Perm.lean +++ b/Mathlib/Data/Fintype/Perm.lean @@ -64,7 +64,8 @@ theorem mem_permsOfList_of_mem {l : List α} {f : Perm α} (h : ∀ x, f x ≠ x simpa only [permsOfList, exists_prop, List.mem_map, mem_append, List.mem_flatMap] refine or_iff_not_imp_left.2 fun _hfl => ⟨f a, ?_, Equiv.swap a (f a) * f, IH this, ?_⟩ · exact mem_of_ne_of_mem hfa (h _ hfa') - · rw [← mul_assoc, mul_def (swap a (f a)) (swap a (f a)), swap_swap, ← Perm.one_def, one_mul] + · rw [← mul_assoc, mul_def (Equiv.swap a (f a)) (Equiv.swap a (f a)), Equiv.swap_swap, + ← Perm.one_def, one_mul] theorem mem_of_mem_permsOfList : ∀ {l : List α} {f : Perm α}, f ∈ permsOfList l → {x : α} → f x ≠ x → x ∈ l diff --git a/Mathlib/Data/List/Destutter.lean b/Mathlib/Data/List/Destutter.lean index 389ba61aef577b..17264eea64df55 100644 --- a/Mathlib/Data/List/Destutter.lean +++ b/Mathlib/Data/List/Destutter.lean @@ -89,7 +89,8 @@ theorem isChain_destutter' (l : List α) (a : α) : (l.destutter' R a).IsChain R simp_rw [destutter'_cons, apply_ite (IsChain R ·), apply_ite (IsChain R <| a :: ·), IH, isChain_cons_cons, if_true_right, ite_prop_iff_and, imp_and] - exact ⟨⟨⟨swap <| fun _ => id, fun _ => IH2 c b⟩, swap <| fun _ => IH2 b a⟩, fun _ => IH2 c a⟩ + exact ⟨⟨⟨Function.swap <| fun _ => id, fun _ => IH2 c b⟩, + Function.swap <| fun _ => IH2 b a⟩, fun _ => IH2 c a⟩ theorem isChain_cons_destutter'_of_rel (l : List α) {a b} (hab : R a b) : (a :: l.destutter' R b).IsChain R := by diff --git a/Mathlib/Data/List/Lookmap.lean b/Mathlib/Data/List/Lookmap.lean index bf9569cdc72e5e..6f230a97b1f05d 100644 --- a/Mathlib/Data/List/Lookmap.lean +++ b/Mathlib/Data/List/Lookmap.lean @@ -102,9 +102,9 @@ theorem perm_lookmap (f : α → Option α) {l₁ l₂ : List α} · simp [lookmap_cons_some _ _ h, p] | swap a b l => rcases h₁ : f a with - | c <;> rcases h₂ : f b with - | d - · simpa [h₁, h₂] using swap _ _ _ - · simpa [h₁, lookmap_cons_some _ _ h₂] using swap _ _ _ - · simpa [lookmap_cons_some _ _ h₁, h₂] using swap _ _ _ + · simpa [h₁, h₂] using Perm.swap _ _ _ + · simpa [h₁, lookmap_cons_some _ _ h₂] using Perm.swap _ _ _ + · simpa [lookmap_cons_some _ _ h₁, h₂] using Perm.swap _ _ _ · rcases (pairwise_cons.1 H).1 _ (mem_cons.2 (Or.inl rfl)) _ h₂ _ h₁ with ⟨rfl, rfl⟩ exact Perm.refl _ | trans p₁ _ IH₁ IH₂ => diff --git a/Mathlib/Data/List/Sublists.lean b/Mathlib/Data/List/Sublists.lean index e41e39c15a6b50..f7d84b0635155f 100644 --- a/Mathlib/Data/List/Sublists.lean +++ b/Mathlib/Data/List/Sublists.lean @@ -301,7 +301,7 @@ theorem sublistsLen_length : ∀ l : List α, sublistsLen l.length l = [l] open Function theorem Pairwise.sublists' {R} : - ∀ {l : List α}, Pairwise R l → Pairwise (Lex (swap R)) (sublists' l) + ∀ {l : List α}, Pairwise R l → Pairwise (Lex (Function.swap R)) (sublists' l) | _, Pairwise.nil => pairwise_singleton _ _ | _, @Pairwise.cons _ _ a l H₁ H₂ => by simp only [sublists'_cons, pairwise_append, pairwise_map, mem_sublists', mem_map, exists_imp, diff --git a/Mathlib/GroupTheory/Perm/ClosureSwap.lean b/Mathlib/GroupTheory/Perm/ClosureSwap.lean index 7a8cb3d3f0dd39..333bcdfe2e2baa 100644 --- a/Mathlib/GroupTheory/Perm/ClosureSwap.lean +++ b/Mathlib/GroupTheory/Perm/ClosureSwap.lean @@ -75,7 +75,7 @@ theorem SubmonoidClass.swap_mem_trans {a b c : α} {C} [SetLike C (Perm α)] · exact hbc obtain rfl | hac := eq_or_ne a c · exact swap_self a ▸ one_mem M - rw [swap_comm, ← swap_mul_swap_mul_swap hab' hac] + rw [Equiv.swap_comm, ← swap_mul_swap_mul_swap hab' hac] exact mul_mem (mul_mem hbc hab) hbc /-- If a subgroup is generated by transpositions, then a transposition `swap x y` lies in the @@ -91,10 +91,10 @@ theorem swap_mem_closure_isSwap {S : Set (Perm α)} (hS : ∀ f ∈ S, f.IsSwap) have := ne_of_mem_of_not_mem ha hσa rw [Perm.smul_def, ne_comm, swap_apply_ne_self_iff, and_iff_right hzw] at this refine hσa (SubmonoidClass.swap_mem_trans (closure S) ?_ ha) - obtain rfl | rfl := this <;> simpa [swap_comm] using subset_closure hσ + obtain rfl | rfl := this <;> simpa [Equiv.swap_comm] using subset_closure hσ · obtain ⟨x, y, -, rfl⟩ := hS f hf; rwa [swap_inv] · exact orbit_eq_iff.mpr hf ▸ ⟨⟨swap z y, hz⟩, swap_apply_right z y⟩ - · rw [mem_ofPred, swap_self]; apply one_mem + · rw [mem_ofPred, Equiv.swap_self]; apply one_mem /-- If a subgroup is generated by transpositions, then a permutation `f` lies in the subgroup if and only if `f` has finite support and `f x` always lies in the same orbit as `x`. -/ @@ -128,7 +128,7 @@ theorem mem_closure_isSwap' {f : Perm α} : refine (mem_closure_isSwap fun _ ↦ id).trans (and_iff_left fun x ↦ ⟨⟨swap x (f x), ?_⟩, swap_apply_left x (f x)⟩) by_cases h : x = f x - · rw [← h, swap_self] + · rw [← h, Equiv.swap_self] apply Subgroup.one_mem · exact subset_closure ⟨x, f x, h, rfl⟩ diff --git a/Mathlib/GroupTheory/Perm/List.lean b/Mathlib/GroupTheory/Perm/List.lean index 0fc68bae8567f6..a0435100d48614 100644 --- a/Mathlib/GroupTheory/Perm/List.lean +++ b/Mathlib/GroupTheory/Perm/List.lean @@ -60,31 +60,31 @@ theorem formPerm_singleton (x : α) : formPerm [x] = 1 := @[simp] theorem formPerm_cons_cons (x y : α) (l : List α) : - formPerm (x :: y :: l) = swap x y * formPerm (y :: l) := + formPerm (x :: y :: l) = Equiv.swap x y * formPerm (y :: l) := rfl -theorem formPerm_pair (x y : α) : formPerm [x, y] = swap x y := +theorem formPerm_pair (x y : α) : formPerm [x, y] = Equiv.swap x y := rfl theorem mem_or_mem_of_zipWith_swap_prod_ne : ∀ {l l' : List α} {x : α}, - (zipWith swap l l').prod x ≠ x → x ∈ l ∨ x ∈ l' + (zipWith Equiv.swap l l').prod x ≠ x → x ∈ l ∨ x ∈ l' | [], _, _ => by simp | _, [], _ => by simp | a::l, b::l', x => fun hx ↦ - if h : (zipWith swap l l').prod x = x then + if h : (zipWith Equiv.swap l l').prod x = x then (eq_or_eq_of_swap_apply_ne_self (a := a) (b := b) (x := x) (by simpa [h] using hx)).imp (by rintro rfl; exact .head _) (by rintro rfl; exact .head _) else (mem_or_mem_of_zipWith_swap_prod_ne h).imp (.tail _) (.tail _) theorem zipWith_swap_prod_support' (l l' : List α) : - { x | (zipWith swap l l').prod x ≠ x } ≤ l.toFinset ⊔ l'.toFinset := fun _ h ↦ by + { x | (zipWith Equiv.swap l l').prod x ≠ x } ≤ l.toFinset ⊔ l'.toFinset := fun _ h ↦ by simpa using mem_or_mem_of_zipWith_swap_prod_ne h theorem zipWith_swap_prod_support [Fintype α] (l l' : List α) : - (zipWith swap l l').prod.support ≤ l.toFinset ⊔ l'.toFinset := by + (zipWith Equiv.swap l l').prod.support ≤ l.toFinset ⊔ l'.toFinset := by intro x hx - have hx' : x ∈ { x | (zipWith swap l l').prod x ≠ x } := by simpa using hx + have hx' : x ∈ { x | (zipWith Equiv.swap l l').prod x ≠ x } := by simpa using hx simpa using zipWith_swap_prod_support' _ _ hx' theorem support_formPerm_le' : { x | formPerm l x ≠ x } ≤ l.toFinset := by @@ -239,7 +239,7 @@ theorem formPerm_eq_of_isRotated {l l' : List α} (hd : Nodup l) (h : l ~r l') : exact (formPerm_rotate l hd n).symm theorem formPerm_append_pair : ∀ (l : List α) (a b : α), - formPerm (l ++ [a, b]) = formPerm (l ++ [a]) * swap a b + formPerm (l ++ [a, b]) = formPerm (l ++ [a]) * Equiv.swap a b | [], _, _ => rfl | [_], _, _ => rfl | x::y::l, a, b => by @@ -249,7 +249,7 @@ theorem formPerm_reverse : ∀ l : List α, formPerm l.reverse = (formPerm l)⁻ | [] => rfl | [_] => rfl | a::b::l => by - simp [formPerm_append_pair, swap_comm, ← formPerm_reverse (b::l)] + simp [formPerm_append_pair, Equiv.swap_comm, ← formPerm_reverse (b::l)] theorem formPerm_pow_apply_getElem (l : List α) (w : Nodup l) (n : ℕ) (i : ℕ) (h : i < l.length) : (formPerm l ^ n) l[i] = diff --git a/lake-manifest.json b/lake-manifest.json index 43aaa30cab5f96..3ac6d313b04b9c 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "41bd267b3f6b7252f6676af46d4ffc6783b64de9", + "rev": "ae82a25d0eb1259a7044d6b77adb21475ff13233", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From d8908563c14546213b56d8b2d44ecd7809c1722f Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Fri, 31 Jul 2026 19:10:14 -0700 Subject: [PATCH 1109/1300] chore: extract `Finset.monotone_sup` and `BddAbove.range_finsetSup` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review comments. The statements `Monotone fun F : Finset ι => F.sup a` and `BddAbove (range fun F : Finset ι => F.sup a)` were repeated inline across `ciSup_eq_ciSup_finset`, `tendsto_finset_sup_ciSup` and `tendsto_finset_sup_iSup`, so pull them out into `Mathlib/Data/Finset/Lattice/Fold.lean` as `Finset.monotone_sup` and `BddAbove.range_finsetSup` (the latter dualised by `to_dual` to `BddBelow.range_finsetInf`). Also make `a` implicit in `tendsto_finset_inf_ciInf`, matching its `sup` counterpart. Co-Authored-By: Claude Opus 5 (1M context) --- Mathlib/Data/Finset/Lattice/Fold.lean | 10 ++++++++++ .../Order/ConditionallyCompleteLattice/Finset.lean | 12 +++--------- Mathlib/Topology/Order/MonotoneConvergence.lean | 13 ++++--------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index 399d42aaf91c1b..94b690fba7eaf9 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -104,6 +104,14 @@ protected theorem sup_le_iff {a : α} : s.sup f ≤ a ↔ ∀ b ∈ s, f b ≤ a @[to_dual le_inf] protected alias ⟨_, sup_le⟩ := Finset.sup_le_iff +@[to_dual] +theorem _root_.BddAbove.range_finsetSup (hf : BddAbove (.range f)) : + BddAbove (.range fun s : Finset β => s.sup f) := by + obtain ⟨a, ha⟩ := hf + refine ⟨a, ?_⟩ + rintro _ ⟨s, rfl⟩ + exact Finset.sup_le fun b _ => ha ⟨b, rfl⟩ + @[to_dual le_inf_const] theorem sup_const_le : (s.sup fun _ => a) ≤ a := Finset.sup_le fun _ _ => le_rfl @@ -151,6 +159,8 @@ theorem sup_mono_fun {g : β → α} (h : ∀ b ∈ s, f b ≤ g b) : s.sup f theorem sup_mono (h : s₁ ⊆ s₂) : s₁.sup f ≤ s₂.sup f := Finset.sup_le (fun _ hb => le_sup (h hb)) +theorem monotone_sup : Monotone fun s : Finset β => s.sup f := fun _ _ h => sup_mono h + @[to_dual] protected theorem sup_comm (s : Finset β) (t : Finset γ) (f : β → γ → α) : (s.sup fun b => t.sup (f b)) = t.sup fun c => s.sup fun b => f b c := diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 0d174163817071..2c0ffbc21fea15 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -26,20 +26,14 @@ section ConditionallyCompleteLattice variable [ConditionallyCompleteLattice α] /-- Supremum of `a i`, `i : ι`, is equal to the supremum over finite suprema of `a`. -/ -theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} - (ha : BddAbove (range a)) : +theorem ciSup_eq_ciSup_finset [OrderBot α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : ⨆ i, a i = ⨆ F : Finset ι, F.sup a := by - have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by - refine ⟨⨆ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.sup_le fun i _ => le_ciSup ha i refine le_antisymm ?_ ?_ - · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup hbdd {i}) + · exact ciSup_le fun i => (Finset.le_sup (by simp)).trans (le_ciSup ha.range_finsetSup {i}) · exact ciSup_le fun F => Finset.sup_le fun i _ => le_ciSup ha i /-- Infimum of `a i`, `i : ι`, is equal to the infimum over finite infima of `a`. -/ -theorem ciInf_eq_ciInf_finset [OrderTop α] [Nonempty ι] {a : ι → α} - (ha : BddBelow (range a)) : +theorem ciInf_eq_ciInf_finset [OrderTop α] [Nonempty ι] {a : ι → α} (ha : BddBelow (range a)) : ⨅ i, a i = ⨅ F : Finset ι, F.inf a := ciSup_eq_ciSup_finset (α := αᵒᵈ) ha diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index cbffa7c8e44d96..ee0a1ff3ae208a 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -133,12 +133,7 @@ section ConditionallyCompleteLattice theorem tendsto_finset_sup_ciSup {ι} [ConditionallyCompleteLattice α] [OrderBot α] [SupConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG - have hbdd : BddAbove (Set.range fun F : Finset ι => F.sup a) := by - refine ⟨⨆ i, a i, ?_⟩ - rintro _ ⟨F, rfl⟩ - exact Finset.sup_le fun i _ => le_ciSup ha i - simpa [ciSup_eq_ciSup_finset ha] using tendsto_atTop_ciSup hmono hbdd + simpa [ciSup_eq_ciSup_finset ha] using tendsto_atTop_ciSup Finset.monotone_sup ha.range_finsetSup end ConditionallyCompleteLattice @@ -161,7 +156,7 @@ end ConditionallyCompletePartialOrder section ConditionallyCompleteLattice theorem tendsto_finset_inf_ciInf {ι} [ConditionallyCompleteLattice α] [OrderTop α] - [InfConvergenceClass α] [Nonempty ι] (a : ι → α) (ha : BddBelow (range a)) : + [InfConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddBelow (range a)) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := tendsto_finset_sup_ciSup (α := αᵒᵈ) ha @@ -178,8 +173,8 @@ theorem tendsto_atTop_iSup (h_mono : Monotone f) : Tendsto f atTop (𝓝 (⨆ i, theorem tendsto_finset_sup_iSup {ι} (a : ι → α) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - have hmono : Monotone (fun F : Finset ι => F.sup a) := fun F G hFG => Finset.sup_mono hFG - simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup hmono + simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using + tendsto_atTop_iSup (Finset.monotone_sup (f := a)) theorem tendsto_atBot_iSup (h_anti : Antitone f) : Tendsto f atBot (𝓝 (⨆ i, f i)) := tendsto_atBot_ciSup h_anti (OrderTop.bddAbove _) From cf556b8b029148b3fb5035705637ff9633e779a4 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Fri, 31 Jul 2026 19:36:13 -0700 Subject: [PATCH 1110/1300] address comments --- Mathlib/Data/Finset/Lattice/Fold.lean | 2 +- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index 94b690fba7eaf9..6b01f42e26e9f7 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -159,7 +159,7 @@ theorem sup_mono_fun {g : β → α} (h : ∀ b ∈ s, f b ≤ g b) : s.sup f theorem sup_mono (h : s₁ ⊆ s₂) : s₁.sup f ≤ s₂.sup f := Finset.sup_le (fun _ hb => le_sup (h hb)) -theorem monotone_sup : Monotone fun s : Finset β => s.sup f := fun _ _ h => sup_mono h +theorem monotone_sup (f : β → α) : Monotone fun s : Finset β => s.sup f := fun _ _ h => sup_mono h @[to_dual] protected theorem sup_comm (s : Finset β) (t : Finset γ) (f : β → γ → α) : diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index ee0a1ff3ae208a..541525eb3832a0 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -174,7 +174,7 @@ theorem tendsto_atTop_iSup (h_mono : Monotone f) : Tendsto f atTop (𝓝 (⨆ i, theorem tendsto_finset_sup_iSup {ι} (a : ι → α) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using - tendsto_atTop_iSup (Finset.monotone_sup (f := a)) + tendsto_atTop_iSup (Finset.monotone_sup a) theorem tendsto_atBot_iSup (h_anti : Antitone f) : Tendsto f atBot (𝓝 (⨆ i, f i)) := tendsto_atBot_ciSup h_anti (OrderTop.bddAbove _) From 7768e06a9817e8aaf90124fd4339ad5d740a67f8 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Fri, 31 Jul 2026 19:40:10 -0700 Subject: [PATCH 1111/1300] complete API --- Mathlib/Data/Finset/Lattice/Fold.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Data/Finset/Lattice/Fold.lean b/Mathlib/Data/Finset/Lattice/Fold.lean index 6b01f42e26e9f7..b317e891bed52c 100644 --- a/Mathlib/Data/Finset/Lattice/Fold.lean +++ b/Mathlib/Data/Finset/Lattice/Fold.lean @@ -161,6 +161,9 @@ theorem sup_mono (h : s₁ ⊆ s₂) : s₁.sup f ≤ s₂.sup f := theorem monotone_sup (f : β → α) : Monotone fun s : Finset β => s.sup f := fun _ _ h => sup_mono h +theorem antitone_inf {α} [SemilatticeInf α] [OrderTop α] (f : β → α) : + Antitone fun s : Finset β => s.inf f := monotone_sup (α := αᵒᵈ) f + @[to_dual] protected theorem sup_comm (s : Finset β) (t : Finset γ) (f : β → γ → α) : (s.sup fun b => t.sup (f b)) = t.sup fun c => s.sup fun b => f b c := From a0eb2b12e8bd562d2d13492bdecff1d3cf8b3c82 Mon Sep 17 00:00:00 2001 From: Yongxi Lin Date: Fri, 31 Jul 2026 19:43:42 -0700 Subject: [PATCH 1112/1300] minor --- Mathlib/Topology/Order/MonotoneConvergence.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 541525eb3832a0..afd4d9864168c1 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -133,7 +133,8 @@ section ConditionallyCompleteLattice theorem tendsto_finset_sup_ciSup {ι} [ConditionallyCompleteLattice α] [OrderBot α] [SupConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by - simpa [ciSup_eq_ciSup_finset ha] using tendsto_atTop_ciSup Finset.monotone_sup ha.range_finsetSup + simpa [ciSup_eq_ciSup_finset ha] using + tendsto_atTop_ciSup (Finset.monotone_sup a) ha.range_finsetSup end ConditionallyCompleteLattice From 932a58b04d345d516adb54545493f5b3a59d0f33 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 07:42:51 +0000 Subject: [PATCH 1113/1300] chore: update Mathlib dependencies 2026-08-01 (#42268) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 3ac6d313b04b9c..e8e2d9aa793ee1 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "ae82a25d0eb1259a7044d6b77adb21475ff13233", + "rev": "2963c249dabd57512a2e101901777e381eb40350", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 40cb31be4a51505f4a25060b8e0c775dcb537dac Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Sat, 1 Aug 2026 08:36:57 +0000 Subject: [PATCH 1114/1300] feat(LinearAlgebra/Dimension/Free): division version of tower law (#41488) Split from #37959 Co-authored-by: artie2000 --- .../IntermediateField/Algebraic.lean | 4 ++-- Mathlib/LinearAlgebra/Dimension/Free.lean | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean index 89785371530833..fecdb84e631c4e 100644 --- a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean @@ -124,11 +124,11 @@ lemma finrank_lt_of_gt [FiniteDimensional F L] (H : F < E) : theorem finrank_dvd_of_le_left (h : F ≤ E) : finrank E L ∣ finrank F L := by let _ := (inclusion h).toRingHom.toAlgebra have : IsScalarTower F E L := IsScalarTower.of_algebraMap_eq fun x ↦ rfl - exact Dvd.intro_left (finrank F E) (finrank_mul_finrank F E L) + exact Module.finrank_dvd_finrank_left F E L theorem finrank_dvd_of_le_right (h : F ≤ E) : finrank K F ∣ finrank K E := by let _ := (inclusion h).toRingHom.toAlgebra - exact Dvd.intro (finrank F E) (finrank_mul_finrank K F E) + exact Module.finrank_dvd_finrank_right K F E theorem finrank_le_of_le_left [FiniteDimensional F L] (h : F ≤ E) : finrank E L ≤ finrank F L := Nat.le_of_dvd Module.finrank_pos (finrank_dvd_of_le_left h) diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index 691e13d49d4fed..0f0b6dcf881b1e 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -70,6 +70,30 @@ theorem Module.finrank_mul_finrank : finrank F K * finrank K A = finrank F A := rw [← toNat_lift.{w} (Module.rank F K), ← toNat_lift.{v} (Module.rank K A), ← toNat_mul, lift_rank_mul_lift_rank, toNat_lift] +theorem Module.finrank_dvd_finrank_left : + Module.finrank K A ∣ Module.finrank F A := + Dvd.intro_left (finrank F K) (finrank_mul_finrank ..) + +theorem Module.finrank_dvd_finrank_right : + Module.finrank F K ∣ Module.finrank F A := + Dvd.intro (finrank K A) (finrank_mul_finrank ..) + +theorem Module.finrank_div_finrank_cancel_right (h : Module.finrank K A ≠ 0) : + Module.finrank F A / Module.finrank K A = Module.finrank F K := + Nat.div_eq_of_eq_mul_left h.bot_lt (finrank_mul_finrank ..).symm + +theorem Module.finrank_div_finrank_cancel_left (h : Module.finrank F K ≠ 0) : + Module.finrank F A / Module.finrank F K = Module.finrank K A := + Nat.div_eq_of_eq_mul_right h.bot_lt (finrank_mul_finrank ..).symm + +theorem Module.finrank_div_finrank_cancel_right_of_nontrivial [Nontrivial A] [Module.Finite K A] : + Module.finrank F A / Module.finrank K A = Module.finrank F K := + finrank_div_finrank_cancel_right F K A ((finrank_pos_iff_of_free ..).mpr ‹_›).ne' + +theorem Module.finrank_div_finrank_cancel_left_of_nontrivial [Nontrivial K] [Module.Finite F K] : + Module.finrank F A / Module.finrank F K = Module.finrank K A := + finrank_div_finrank_cancel_left F K A ((finrank_pos_iff_of_free ..).mpr ‹_›).ne' + end Tower variable {R : Type u} {S : Type*} {M M₁ : Type v} {M' : Type v'} From 62244e5ddb2bb0c35e3500acb5730ad8fb4b17aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Sat, 1 Aug 2026 08:36:59 +0000 Subject: [PATCH 1115/1300] feat(Algebra/Homology): homotopy equivalences satisfy the two out of three property (#42321) --- Mathlib/Algebra/Homology/Homotopy.lean | 66 +++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Homology/Homotopy.lean b/Mathlib/Algebra/Homology/Homotopy.lean index 9459cf7dc9c6f3..16cb0345f8b25f 100644 --- a/Mathlib/Algebra/Homology/Homotopy.lean +++ b/Mathlib/Algebra/Homology/Homotopy.lean @@ -714,9 +714,12 @@ def HomologicalComplex.homotopyEquivalences : namespace HomotopyEquiv +variable {C D E : HomologicalComplex V c} + +variable (C) in /-- Any complex is homotopy equivalent to itself. -/ -@[refl] -def refl (C : HomologicalComplex V c) : HomotopyEquiv C C where +@[refl, simps] +def refl : HomotopyEquiv C C where hom := 𝟙 C inv := 𝟙 C homotopyHomInvId := Homotopy.ofEq (by simp) @@ -726,16 +729,16 @@ instance : Inhabited (HomotopyEquiv C C) := ⟨refl C⟩ /-- Being homotopy equivalent is a symmetric relation. -/ -@[symm] -def symm {C D : HomologicalComplex V c} (f : HomotopyEquiv C D) : HomotopyEquiv D C where +@[symm, simps] +def symm (f : HomotopyEquiv C D) : HomotopyEquiv D C where hom := f.inv inv := f.hom homotopyHomInvId := f.homotopyInvHomId homotopyInvHomId := f.homotopyHomInvId /-- Homotopy equivalence is a transitive relation. -/ -@[trans] -def trans {C D E : HomologicalComplex V c} (f : HomotopyEquiv C D) (g : HomotopyEquiv D E) : +@[trans, simps] +def trans (f : HomotopyEquiv C D) (g : HomotopyEquiv D E) : HomotopyEquiv C E where hom := f.hom ≫ g.hom inv := g.inv ≫ f.inv @@ -749,8 +752,59 @@ def ofIso {ι : Type*} {V : Type u} [Category.{v} V] [Preadditive V] {c : Comple {C D : HomologicalComplex V c} (f : C ≅ D) : HomotopyEquiv C D := ⟨f.hom, f.inv, Homotopy.ofEq f.3, Homotopy.ofEq f.4⟩ +lemma homotopyEquivalences_hom (f : HomotopyEquiv C D) : + homotopyEquivalences _ _ f.hom := ⟨f, rfl⟩ + +lemma homotopyEquivalences_inv (f : HomotopyEquiv C D) : + homotopyEquivalences _ _ f.inv := f.symm.homotopyEquivalences_hom + +/-- If `f` if a homotopy equivalence and `h` is a homotopy from `f.hom` to +a morphism `g`, then this is a homotopy equivalence whose `hom` field is `g`. -/ +@[simps hom inv] +def copy (f : HomotopyEquiv C D) {g : C ⟶ D} (h : Homotopy f.hom g) : + HomotopyEquiv C D where + hom := g + inv := f.inv + homotopyHomInvId := (h.symm.compRight _).trans f.homotopyHomInvId + homotopyInvHomId := (h.symm.compLeft _).trans f.homotopyInvHomId + end HomotopyEquiv +namespace HomologicalComplex + +lemma homotopyEquivalences.of_isIso (f : C ⟶ D) [IsIso f] : homotopyEquivalences _ _ f := + ⟨.ofIso (asIso f), rfl⟩ + +lemma homotopyEquivalences.of_homotopy {f g : C ⟶ D} (h : homotopyEquivalences _ _ f) + (hfg : Homotopy f g) : + homotopyEquivalences _ _ g := by + obtain ⟨e, rfl⟩ := h + exact ⟨e.copy hfg, by simp⟩ + +instance : (homotopyEquivalences V c).IsMultiplicative where + id_mem K := ⟨.refl _, rfl⟩ + comp_mem f g := by + rintro ⟨f, rfl⟩ ⟨g, rfl⟩ + exact ⟨f.trans g, rfl⟩ + +instance : (homotopyEquivalences V c).HasTwoOutOfThreeProperty where + of_postcomp f _ := by + rintro ⟨g, rfl⟩ ⟨e, he⟩ + refine (e.trans g.symm).homotopyEquivalences_hom.of_homotopy ?_ + simp only [HomotopyEquiv.trans_hom, HomotopyEquiv.symm_hom, he, Category.assoc] + exact g.homotopyHomInvId.compLeftId f + of_precomp _ g := by + rintro ⟨f, rfl⟩ ⟨e, he⟩ + refine (f.symm.trans e).homotopyEquivalences_hom.of_homotopy ?_ + simp only [HomotopyEquiv.trans_hom, HomotopyEquiv.symm_hom, he, ← Category.assoc] + exact f.homotopyInvHomId.compRightId g + +instance : (homotopyEquivalences V c).RespectsIso := + MorphismProperty.respectsIso_of_isStableUnderComposition + (fun _ _ _ _ ↦ .of_isIso _) + +end HomologicalComplex + end namespace CategoryTheory From 32beea3cad9021f3904958d54eddddba078a6aca Mon Sep 17 00:00:00 2001 From: Marcus Zibrowius Date: Sat, 1 Aug 2026 11:51:30 +0000 Subject: [PATCH 1116/1300] =?UTF-8?q?feat(Algebra/DirectSum):=20equivalenc?= =?UTF-8?q?e=20between=20direct=20sum=20indexed=20by=20=CE=B9=E2=82=81=20a?= =?UTF-8?q?nd=20double=20sum=20indexed=20by=20=CE=B9=E2=82=82=20and=20fibr?= =?UTF-8?q?es=20of=20f=20:=20=CE=B9=E2=82=81=20=E2=86=92=20=CE=B9=E2=82=82?= =?UTF-8?q?=20(#39607)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add variant `equivCongrLeft'` of `equivCongrLeft`, and corresponding `…_apply` lemma. 2. Add `…_of lemmas` for both `equivCongrLeft` and `equivCongrLeft'`. 3. Add `…of lemma` for `sigmaCurry`, i.e. `sigmaCurry_of`. 4. Add `sigmaFiberAddEquiv`: the equivalence between a direct sum indexed by a type `ι₁` and the double sum indexed by a type `ι₂` and the fibres of a map `f : ι₁ → ι₂`. Add two `…_apply` lemmas and an `…_of` lemma. Co-authored-by: TentativeConvert --- Mathlib/Algebra/DirectSum/Basic.lean | 49 ++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/DirectSum/Basic.lean b/Mathlib/Algebra/DirectSum/Basic.lean index 90cac152dc70cd..e9d35aa911a984 100644 --- a/Mathlib/Algebra/DirectSum/Basic.lean +++ b/Mathlib/Algebra/DirectSum/Basic.lean @@ -305,14 +305,20 @@ section CongrLeft variable {κ : Type*} -/-- Reindexing terms of a direct sum. -/ +/-- Reindexing terms of a direct sum: change indexing type from `ι` to `κ` along an equivalence +`h : ι ≃ κ`. -/ def equivCongrLeft (h : ι ≃ κ) : (⨁ i, β i) ≃+ ⨁ k, β (h.symm k) := { DFinsupp.equivCongrLeft h with map_add' := DFinsupp.comapDomain'_add _ h.right_inv } @[simp] theorem equivCongrLeft_apply (h : ι ≃ κ) (f : ⨁ i, β i) (k : κ) : - equivCongrLeft h f k = f (h.symm k) := by - exact DFinsupp.comapDomain'_apply _ h.right_inv _ _ + equivCongrLeft h f k = f (h.symm k) := + DFinsupp.comapDomain'_apply _ h.right_inv _ _ + +@[simp] +theorem equivCongrLeft_of [DecidableEq ι] [DecidableEq κ] (h : ι ≃ κ) (k : κ) (x : β (h.symm k)) : + equivCongrLeft h (of β (h.symm k) x) = of (fun k ↦ β (h.symm k)) k x := + DFinsupp.comapDomain'_single h.symm h.right_inv _ _ end CongrLeft @@ -342,6 +348,12 @@ theorem sigmaCurry_apply (f : ⨁ i : Σ _i, _, δ i.1 i.2) (i : ι) (j : α i) sigmaCurry f i j = f ⟨i, j⟩ := DFinsupp.sigmaCurry_apply (δ := δ) _ i j +@[simp] +theorem sigmaCurry_of [∀ i : ι, DecidableEq (α i)] (k : (i : ι) × α i) (x : δ k.1 k.2) : + sigmaCurry (of (fun k ↦ δ k.1 k.2) k x) = + of (fun i' ↦ ⨁ (j' : α i'), δ i' j') k.1 (of (fun j' ↦ δ k.1 j') k.2 x) := + DFinsupp.sigmaCurry_single k x + /-- The natural map between `⨁ i (j : α i), δ i j` and `Π₀ (i : Σ i, α i), δ i.1 i.2`, inverse of `curry`. -/ def sigmaUncurry : (⨁ (i) (j), δ i j) →+ ⨁ i : Σ _i, _, δ i.1 i.2 where @@ -360,6 +372,37 @@ def sigmaCurryEquiv : (⨁ i : Σ _i, _, δ i.1 i.2) ≃+ ⨁ (i) (j), δ i j := end Sigma +section SigmaFiber + +variable {ι₁ ι₂ : Type v} [DecidableEq ι₂] (f : ι₁ → ι₂) +variable {β : ι₁ → Type w} [Π i, AddCommMonoid (β i)] + +/-- The equivalence between a direct sum indexed by a type `ι₁` and the double sum indexed by a type +`ι₂` together with the fibres of a map `f : ι₁ → ι₂`. -/ +def sigmaFiberAddEquiv : (⨁ i, β i) ≃+ ⨁ (j : ι₂) (i : { i : ι₁ // f i = j}), β ↑i := + (equivCongrLeft (Equiv.sigmaFiberEquiv f).symm).trans + (sigmaCurryEquiv (δ := fun j ↦ (fun (i : { i : ι₁ // f i = j}) ↦ β i))) + +theorem sigmaFiberAddEquiv_apply (x : ⨁ i, β i) : + sigmaFiberAddEquiv f x = sigmaCurry (equivCongrLeft (Equiv.sigmaFiberEquiv f).symm x) := rfl + +@[simp] +theorem sigmaFiberAddEquiv_apply_apply (x : ⨁ i, β i) (j : ι₂) (i' : { i : ι₁ // f i = j}) : + sigmaFiberAddEquiv f x j i' = x i' := rfl + +@[simp] +theorem sigmaFiberAddEquiv_of [DecidableEq ι₁] (i : ι₁) (x : β i) : + sigmaFiberAddEquiv f (of _ i x) = of _ (f i) (of _ ⟨i, rfl⟩ x) := + let h := Equiv.sigmaFiberEquiv f + let k : (j : ι₂) × {i₁ : ι₁ // f i₁ = j} := ⟨f i, ⟨i, rfl⟩⟩ + calc sigmaFiberAddEquiv f (of β (h k) x) + _ = sigmaCurry (of (fun k : (j' : ι₂) × {i // f i = j'} ↦ β k.2) k x) := by + rw [sigmaFiberAddEquiv_apply] + exact congrArg sigmaCurry (equivCongrLeft_of (h := h.symm) _ _) + _ = of _ k.1 (of _ k.2 x) := by simp + +end SigmaFiber + /-- The canonical embedding from `⨁ i, A i` to `M` where `A` is a collection of `AddSubmonoid M` indexed by `ι`. From 294355479299d19d1e1c759cef58e9e5e94e51b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sat, 1 Aug 2026 13:03:27 +0000 Subject: [PATCH 1117/1300] chore({Archive,Counterexamples}): add missing `noncomputable` (#42170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All these definitions are noncomputable (because they use choice/produce sets), but the computability checker doesn't spot this until I try making `Set` a one-field structure. This is because the computability checker doesn't even try to compute sorts, but it doesn't see that `s : Set α` is (equivalent to) a family of sorts. Follow-up to #41446. Generated by Claude Opus, then reviewed and cherry-picked line-by-line by myself. Assisted-by: Claude Opus 4.8 --- Archive/Wiedijk100Theorems/BuffonsNeedle.lean | 4 ++-- Counterexamples/TopologistsSineCurve.lean | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Archive/Wiedijk100Theorems/BuffonsNeedle.lean b/Archive/Wiedijk100Theorems/BuffonsNeedle.lean index c0b0dd62158b83..f5c08f4df5a0b0 100644 --- a/Archive/Wiedijk100Theorems/BuffonsNeedle.lean +++ b/Archive/Wiedijk100Theorems/BuffonsNeedle.lean @@ -96,7 +96,7 @@ Projection of a needle onto the x-axis. The needle's center is at x-coordinate ` `l` and angle `θ`. Note, `θ` is measured relative to the y-axis, that is, a vertical needle has `θ = 0`. -/ -def needleProjX (x θ : ℝ) : Set ℝ := Set.Icc (x - θ.sin * l / 2) (x + θ.sin * l / 2) +noncomputable def needleProjX (x θ : ℝ) : Set ℝ := Set.Icc (x - θ.sin * l / 2) (x + θ.sin * l / 2) /-- The indicator function of whether a needle at position `⟨x, θ⟩ : ℝ × ℝ` crosses the line `x = 0`. @@ -120,7 +120,7 @@ noncomputable def N : Ω → ℝ := needleCrossesIndicator l ∘ B /-- The possible x-positions and angle relative to the y-axis of a needle. -/ -abbrev needleSpace : Set (ℝ × ℝ) := Set.Icc (-d / 2) (d / 2) ×ˢ Set.Icc 0 π +noncomputable abbrev needleSpace : Set (ℝ × ℝ) := Set.Icc (-d / 2) (d / 2) ×ˢ Set.Icc 0 π include hd in lemma volume_needleSpace : ℙ (needleSpace d) = ENNReal.ofReal (d * π) := by diff --git a/Counterexamples/TopologistsSineCurve.lean b/Counterexamples/TopologistsSineCurve.lean index f1373a7b729490..a552ce3ba8f697 100644 --- a/Counterexamples/TopologistsSineCurve.lean +++ b/Counterexamples/TopologistsSineCurve.lean @@ -31,14 +31,14 @@ open Topology Filter Set Real namespace TopologistsSineCurve /-- The topologist's sine curve, i.e. the graph of `y = sin (x⁻¹)` for `0 < x`. -/ -def S : Set (ℝ × ℝ) := (fun x ↦ (x, sin x⁻¹)) '' Ioi 0 +noncomputable def S : Set (ℝ × ℝ) := (fun x ↦ (x, sin x⁻¹)) '' Ioi 0 /-- The vertical line segment `{ (0, y) | -1 ≤ y ≤ 1 }`, which is the set of limit points of `S` not contained in `S` itself. -/ def Z : Set (ℝ × ℝ) := (fun y ↦ (0, y)) '' Icc (-1) 1 /-- The union of `S` and `Z` (which we will show is the closure of `S`). -/ -def T : Set (ℝ × ℝ) := S ∪ Z +noncomputable def T : Set (ℝ × ℝ) := S ∪ Z /-- A sequence of `x`-values tending to 0 at which the sine curve has a given `y`-coordinate. -/ noncomputable def xSeq (y : ℝ) (k : ℕ) := 1 / (arcsin y + (k + 1) * (2 * π)) From f4f85c2fcf7946e12ddc6ea21639d953b62d1284 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sat, 1 Aug 2026 13:14:38 +0000 Subject: [PATCH 1118/1300] chore: fix various typos (#42232) This PR probably removes most existing typos in mathlib docstrings. They were found by first extracting docstrings and putting them in a seperate txt file, then run a spell checker on in (in this case: https://github.com/codespell-project/codespell) and finally checking the output (many false ositives from names...) Co-authored-by: Batixx --- .../DerivedCategory/RightDerivedFunctorPlus.lean | 2 +- Mathlib/Algebra/Order/Star/Basic.lean | 2 +- .../DoldKan/SplitSimplicialObject.lean | 2 +- .../Analysis/Complex/UpperHalfPlane/FixedPoints.lean | 2 +- Mathlib/CategoryTheory/IsoCat.lean | 2 +- .../CategoryTheory/Sites/Precoverage/Generates.lean | 2 +- Mathlib/Condensed/Discrete/Colimit.lean | 2 +- Mathlib/Geometry/Convex/Cone/Face/Basic.lean | 4 ++-- .../VectorBundle/CovariantDerivative/Metric.lean | 2 +- Mathlib/Lean/Meta/RefinedDiscrTree/Lookup.lean | 2 +- Mathlib/Probability/Distributions/Binomial.lean | 2 +- Mathlib/Probability/Distributions/Geometric.lean | 2 +- Mathlib/RingTheory/RingHomProperties.lean | 4 ++-- Mathlib/Tactic/Algebra/AlgebraNF.lean | 2 +- Mathlib/Tactic/Algebra/Basic.lean | 2 +- Mathlib/Tactic/ClickSuggestions/FindPremises.lean | 2 +- Mathlib/Tactic/ClickSuggestions/TryPremises.lean | 2 +- .../Tactic/ComputeAsymptotics/Multiseries/Basis.lean | 2 +- .../Tactic/ComputeAsymptotics/Multiseries/Defs.lean | 2 +- Mathlib/Tactic/Ring/Basic.lean | 4 ++-- Mathlib/Tactic/Ring/Common.lean | 6 +++--- Mathlib/Tactic/SetNotationForOrder.lean | 2 +- Mathlib/Tactic/Translate/Core.lean | 2 +- Mathlib/Topology/Algebra/Module/IsWeak.lean | 2 +- Mathlib/Topology/Algebra/Valued/ValuedField.lean | 2 +- Mathlib/Topology/CWComplex/Classical/Basic.lean | 4 ++-- Mathlib/Topology/Sets/Compacts.lean | 10 +++++----- 27 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean b/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean index 1fbd95aa538737..b257a9a34359e6 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/RightDerivedFunctorPlus.lean @@ -16,7 +16,7 @@ where `C` has enough injectives, we define the right derived functor between the corresponding bounded below derived categories. TODO(@joelriou): show that this functor is triangulated and refactor -the definiton of `Functor.rightDerived` +the definition of `Functor.rightDerived` -/ diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index 5ba1bd85cc6b43..5e9a7191d7334b 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -472,7 +472,7 @@ instance (priority := 100) StarRingEquivClass.instOrderIsoClass [EquivLike F R S /-- While `IsSelfAdjoint.map` assumes the map is star-preserving, this lemma instead assumes the map is an order-preserving additive map from a space where self-adjoint elements can be expressed as -differences of nonnegative elemens, and whose codomain is a star-ordered ring. When such maps are +differences of nonnegative elements, and whose codomain is a star-ordered ring. When such maps are linear over `ℂ`, they are also star-preserving, and this lemma is used to establish that one by splitting into real and imaginary parts. -/ @[aesop safe apply (rule_sets := [CStarAlgebra])] diff --git a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean index dda65810f8dbe1..c3e2fbbed0b211 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean @@ -254,7 +254,7 @@ noncomputable def toNondegComplex : K[X] ⟶ s.nondegComplex := set_option backward.defeqAttrib.useBackward true in /-- Given a splitting `s` of a simplicial object `X` in a preadditive category, this is the split monomormphism from the chain complex `s.nondegComplex` to -the alternating face map complex fo `X`. -/ +the alternating face map complex of `X`. -/ @[no_expose] noncomputable def fromNondegComplex : s.nondegComplex ⟶ K[X] := (fullyFaithfulToKaroubi _).preimage diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean index d89e7b6c83fc1e..52510c6ad4970e 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean @@ -117,7 +117,7 @@ theorem gl_smul_eq_self_iff_quadratic (h : 0 < g.val.det) : simp [gl_smul_eq_iff_num_eq, σ, h, num, denom] grind -/-- If `g` is a non-scalar orientation perserving matrix with a fixed point in `ℍ`, +/-- If `g` is a non-scalar orientation preserving matrix with a fixed point in `ℍ`, then it's an elliptic matrix. -/ theorem isElliptic_of_exists_smul_eq_self (h : 0 < g.val.det) (hgc : g ∉ Subgroup.center _) (hfix : ∃ z : ℍ, g • z = z) : g.IsElliptic := by diff --git a/Mathlib/CategoryTheory/IsoCat.lean b/Mathlib/CategoryTheory/IsoCat.lean index b1bb84307ce055..5912c5c4839c9f 100644 --- a/Mathlib/CategoryTheory/IsoCat.lean +++ b/Mathlib/CategoryTheory/IsoCat.lean @@ -17,7 +17,7 @@ This is a strict notion, stronger than an equivalence of categories `C ≌ D`. We also define `Functor.IsIso` as a property saying that a functor is fully faithful and bijective on objects. We develop basic api for these two concepts. -Unless the application explicitely demands an isomorphism, the equivalence of categories is +Unless the application explicitly demands an isomorphism, the equivalence of categories is to be preferred. ## Main definitions diff --git a/Mathlib/CategoryTheory/Sites/Precoverage/Generates.lean b/Mathlib/CategoryTheory/Sites/Precoverage/Generates.lean index 3fc9fe92ea4dbb..f47f5e23b949c6 100644 --- a/Mathlib/CategoryTheory/Sites/Precoverage/Generates.lean +++ b/Mathlib/CategoryTheory/Sites/Precoverage/Generates.lean @@ -74,7 +74,7 @@ lemma Generates.isSheaf_of_forall (h : K.Generates J) (F : Cᵒᵖ ⥤ Type w) /- By assumption, the statement holds for `w = max u v`. The idea of the proof is to construct a suitable `Type max u v` valued subsheaf of `F` for each covering sieve `S` in `J` and every family of sections over `S` to check the necessary conditions. - We explain existence below, uniqueness works similary. -/ + We explain existence below, uniqueness works similarly. -/ intro X S hS rw [← Presieve.isSeparatedFor_and_exists_isAmalgamation_iff_isSheafFor] refine ⟨?_, ?_⟩ diff --git a/Mathlib/Condensed/Discrete/Colimit.lean b/Mathlib/Condensed/Discrete/Colimit.lean index 7579e7ecc282d2..4614a900107d06 100644 --- a/Mathlib/Condensed/Discrete/Colimit.lean +++ b/Mathlib/Condensed/Discrete/Colimit.lean @@ -40,7 +40,7 @@ abbrev locallyConstantPresheaf : Profinite.{u}ᵒᵖ ⥤ Type (u + 1) := #adaptation_note /-- In this declaration and `isColimitLocallyConstantPresheaf`, `coe_comp` interferes with rewriting via -`Cone.w`, so we needed to manualy exclude it. +`Cone.w`, so we needed to manually exclude it. -/ set_option backward.defeqAttrib.useBackward true in /-- diff --git a/Mathlib/Geometry/Convex/Cone/Face/Basic.lean b/Mathlib/Geometry/Convex/Cone/Face/Basic.lean index c99b7852c9fa02..922db36ac93c7c 100644 --- a/Mathlib/Geometry/Convex/Cone/Face/Basic.lean +++ b/Mathlib/Geometry/Convex/Cone/Face/Basic.lean @@ -23,8 +23,8 @@ in `F` are also in `F`. ## Implementation notes * We do not use `IsExtreme` as a definition because this is an affine notion and does not allow the - flexibility necessary to deal wth cones over general rings. E.g. the cone of positive integers has - no proper subset that are extreme. We prove that every face is an extreme set of its cone. + flexibility necessary to deal with cones over general rings. E.g. the cone of positive integers + has no proper subset that are extreme. We prove that every face is an extreme set of its cone. * Most results proven over a division ring hold more generally over an Archimedean ring. In particular, `iff_mem_of_add_mem_left` holds whenever for every `x ∈ R` there is a `y ∈ R` with `1 ≤ x * y`. diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 021464573225ca..c6f77447d370fd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -36,7 +36,7 @@ metric `g` if and only if the differentiated metric tensor `∇ g` (defined by `CovariantDerivative.IsMetricCompatible` with the characterisation that parallel transport be an isometry. -* Given connections on bundles `V` and `W`, there is an induced connnection on the bundle +* Given connections on bundles `V` and `W`, there is an induced connection on the bundle `Hom(V, W)`. When this induced connection has been defined in Mathlib, rephrase the definition of `CovariantDerivative.derivMetricTensor`, to be simply the covariant derivative of the metric tensor (considered as a section of `Hom(V, Hom(V, ℝ))`). diff --git a/Mathlib/Lean/Meta/RefinedDiscrTree/Lookup.lean b/Mathlib/Lean/Meta/RefinedDiscrTree/Lookup.lean index 3589e93ce409bf..74b492056d1aa8 100644 --- a/Mathlib/Lean/Meta/RefinedDiscrTree/Lookup.lean +++ b/Mathlib/Lean/Meta/RefinedDiscrTree/Lookup.lean @@ -80,7 +80,7 @@ and returning the `Trie α`. Performance note: In the `apply` search discrimination tree, after root node `⟨Eq, 3⟩`, there are about `150,000` entries in the `pending` array. -To deal with this smoothly, we parallellize the computation into chunks of `5000` entries. +To deal with this smoothly, we parallelize the computation into chunks of `5000` entries. -/ private def evalNode (trie : TrieIndex) : TreeM α (Trie α) := do let node := (← get)[trie]! diff --git a/Mathlib/Probability/Distributions/Binomial.lean b/Mathlib/Probability/Distributions/Binomial.lean index 29b4531403e147..7c124b3f604628 100644 --- a/Mathlib/Probability/Distributions/Binomial.lean +++ b/Mathlib/Probability/Distributions/Binomial.lean @@ -36,7 +36,7 @@ Results should be proven for both `Bin(n, p)` and `Bin(R, n, p)` when possible, one to prove the second. Note that results concerning `Bin(R, n, p)` may require `[MeasurableSingletonClass R]` and/or `[CharZero R]`. -When refering to `Bin(n, p)` in names, use `binomial`. When refering to `Bin(R, n, p)`, +When referring to `Bin(n, p)` in names, use `binomial`. When referring to `Bin(R, n, p)`, use `map_cast_binomial`. ## Notation diff --git a/Mathlib/Probability/Distributions/Geometric.lean b/Mathlib/Probability/Distributions/Geometric.lean index dd685d47ad0df3..a73c3605ea835a 100644 --- a/Mathlib/Probability/Distributions/Geometric.lean +++ b/Mathlib/Probability/Distributions/Geometric.lean @@ -19,7 +19,7 @@ As the parameter `p` needs to lie between `0` and `1`, we define `geometricMeasu `p : unitInterval`. Imagine a certain experience which has success probability `p`. If you repeat this experience -infintely many times and independently, the number of failures before the first success +infinitely many times and independently, the number of failures before the first success follows a geometric distribution with parameter `p`. ## Main definition diff --git a/Mathlib/RingTheory/RingHomProperties.lean b/Mathlib/RingTheory/RingHomProperties.lean index 2e55dbc25f0ef4..e4b392180f2b75 100644 --- a/Mathlib/RingTheory/RingHomProperties.lean +++ b/Mathlib/RingTheory/RingHomProperties.lean @@ -279,7 +279,7 @@ lemma CodescendsAlong.and (hP : CodescendsAlong P Q) (hP' : CodescendsAlong P' Q end Descent /-- A property of ring homomorphisms `P` is said to have equalizers, if the equalizer of algebra -maps between algebras satisfiying `P` also satisfies `P`. -/ +maps between algebras satisfying `P` also satisfies `P`. -/ def HasEqualizers (P : ∀ {R S : Type u} [CommRing R] [CommRing S], (R →+* S) → Prop) : Prop := ∀ {R S T : Type u} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] (f g : S →ₐ[R] T), P (algebraMap R S) → P (algebraMap R T) → @@ -290,7 +290,7 @@ lemma HasEqualizers.and (hP : HasEqualizers P) (hQ : HasEqualizers Q) : fun f g hf hg ↦ ⟨hP f g hf.1 hg.1, hQ f g hf.2 hg.2⟩ /-- A property of ring homomorphisms `P` is said to have finite products, if a finite product of -algebras satisfiying `Q` also satisfies `P`. -/ +algebras satisfying `Q` also satisfies `P`. -/ def HasFiniteProducts (P : ∀ {R S : Type u} [CommRing R] [CommRing S], (R →+* S) → Prop) : Prop := ∀ {R : Type u} [CommRing R] {ι : Type u} [_root_.Finite ι] (S : ι → Type u) [∀ i, CommRing (S i)] [∀ i, Algebra R (S i)], diff --git a/Mathlib/Tactic/Algebra/AlgebraNF.lean b/Mathlib/Tactic/Algebra/AlgebraNF.lean index 04730c671c32ba..1ceaa5e51d73fb 100644 --- a/Mathlib/Tactic/Algebra/AlgebraNF.lean +++ b/Mathlib/Tactic/Algebra/AlgebraNF.lean @@ -11,7 +11,7 @@ public import Mathlib.Tactic.Algebra.Basic This file contains helper functions for the (currently unimplemented) `algebra_nf` tactic. -The defnitions in this file are currently only used by `polynomial_nf`. +The definitions in this file are currently only used by `polynomial_nf`. -/ public meta section diff --git a/Mathlib/Tactic/Algebra/Basic.lean b/Mathlib/Tactic/Algebra/Basic.lean index 8f111bbc098d17..1b15b769a38d7e 100644 --- a/Mathlib/Tactic/Algebra/Basic.lean +++ b/Mathlib/Tactic/Algebra/Basic.lean @@ -34,7 +34,7 @@ The main limitation of the current implementation is that it does not handle rat when the algebra `A` is a field but the base ring `R` is not. This is never an issue when working with polynomials, but would be an issue when working with a number field over its ring of integers. -When inferring the base ring, we assum that any two rings `R` and `S` that appear are comparable, +When inferring the base ring, we assume that any two rings `R` and `S` that appear are comparable, in the sense that either `R` is an `S`-algebra or `S` is an `R`-algebra. -/ diff --git a/Mathlib/Tactic/ClickSuggestions/FindPremises.lean b/Mathlib/Tactic/ClickSuggestions/FindPremises.lean index de12bedf7964dc..fed54c353df7a5 100644 --- a/Mathlib/Tactic/ClickSuggestions/FindPremises.lean +++ b/Mathlib/Tactic/ClickSuggestions/FindPremises.lean @@ -269,7 +269,7 @@ public def computeModuleDiscrTrees (choice : Choice) (parentDecl? : Option Name) return .append {} pre /-- Compute the discrimination trees for the local variables in `lctx`. -We restrict to the varaibles in `lctx` to avoid using introduced bound variables. -/ +We restrict to the variables in `lctx` to avoid using introduced bound variables. -/ public def computeLCtxDiscrTrees (choice : Choice) (lctx : LocalContext) (fvarId? : Option FVarId) : MetaM PreDiscrTrees := do let mut entries : Entries := {} diff --git a/Mathlib/Tactic/ClickSuggestions/TryPremises.lean b/Mathlib/Tactic/ClickSuggestions/TryPremises.lean index 02beae1c075c08..306662fe4b976f 100644 --- a/Mathlib/Tactic/ClickSuggestions/TryPremises.lean +++ b/Mathlib/Tactic/ClickSuggestions/TryPremises.lean @@ -157,7 +157,7 @@ def findRflTarget? (root subExpr : Expr) (rwKind : RwKind) : ClickSuggestionsM ( catch _ => return none -/-- Compute the library rearch suggestions. This uses `token` to incrementally udpate the output. -/ +/-- Compute the library rearch suggestions. This uses `token` to incrementally update the output. -/ public def librarySearchSuggestions (rootExpr subExpr : Expr) (lctx : LocalContext) (rwKind : RwKind) (parentDecl? : Option Name) (token : RefreshToken) : ClickSuggestionsM Unit := do diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean index 81f1baed725e6f..866fc879080c9b 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean @@ -155,7 +155,7 @@ theorem push_log_last {basis_hd : ℝ → ℝ} {basis_tl : Basis} simpa [List.getLast_of_getLast?_eq_some hg] using Real.isLittleO_log_id_atTop.comp_tendsto <| Real.tendsto_log_atTop.comp <| h_basis.tendsto_atTop <| List.mem_of_getLast? hg -/-- Auxillary lemma. If function `f` is eventually positive, `g` tends to `atTop`, and +/-- Auxiliary lemma. If function `f` is eventually positive, `g` tends to `atTop`, and `log f =o[atTop] log g` then for any `a` and `b > 0`, then `f^a =o[atTop] g^b`. -/ theorem pow_isLittleO_pow_of_log {f g : ℝ → ℝ} (a b : ℝ) (hf : ∀ᶠ x in atTop, 0 < f x) (hg : Tendsto g atTop atTop) (h : (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) (hb : 0 < b) : diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean index 51a86e98978f5e..c504e032b5cd09 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean @@ -882,7 +882,7 @@ theorem elim_cons {exp : ℝ} generalize h_ms : (mk (.cons exp coef tl) f) = ms at h cases h <;> simp at h_ms; grind -/-- One can replace `f` in `Approximates` with the funcion that eventually equals `f`. -/ +/-- One can replace `f` in `Approximates` with the function that eventually equals `f`. -/ theorem replaceFun {ms : MultiseriesExpansion (basis_hd :: basis_tl)} {f : ℝ → ℝ} (h_equiv : ms.toFun =ᶠ[atTop] f) (h_approx : ms.Approximates) : (ms.replaceFun f).Approximates := by diff --git a/Mathlib/Tactic/Ring/Basic.lean b/Mathlib/Tactic/Ring/Basic.lean index ea4a8ac1fb1c2c..50ccb8044745a1 100644 --- a/Mathlib/Tactic/Ring/Basic.lean +++ b/Mathlib/Tactic/Ring/Basic.lean @@ -33,7 +33,7 @@ even though it is not strictly speaking an equation in the language of commutati The basic approach to prove equalities is to normalise both sides and check for equality. We use `Mathlib.Tactic.Ring.Common` to implement the normal forms and normalization procedure. -This file defines the evaluation of basic operations such as addition and multipication of the +This file defines the evaluation of basic operations such as addition and multiplication of the rational coefficients as embedded inside the (semi)ring. This is done using `norm_num`. It further implements the core `ring1` tactic. @@ -479,7 +479,7 @@ partial def isOne {u : Lean.Level} {α : Q(Type u)} (sα : Q(CommSemiring $α)) else failure -/-- The comarisons on the basetype used to compare normalized ring expressions. -/ +/-- The comparisons on the basetype used to compare normalized ring expressions. -/ partial def _root_.Mathlib.Tactic.Ring.ringCompare {u : Lean.Level} {α : Q(Type u)} : Common.RingCompare (α := α) RatCoeff where eq zx zy := zx.value == zy.value diff --git a/Mathlib/Tactic/Ring/Common.lean b/Mathlib/Tactic/Ring/Common.lean index d5b432a833389a..1e801aaa615a82 100644 --- a/Mathlib/Tactic/Ring/Common.lean +++ b/Mathlib/Tactic/Ring/Common.lean @@ -272,7 +272,7 @@ instance {α : Q(Type u)} {E : Q($α) → Type} {e : Q($α)} [Inhabited (Σ e, E let ⟨e', v⟩ : Σ e, E e := default; ⟨e', v, default⟩ -/-- Defines how comparisons and binary equality are computed in the base type. These are seperated +/-- Defines how comparisons and binary equality are computed in the base type. These are separated from RingCompute because they can often be defined without using instance caches. -/ structure RingCompare {u : Lean.Level} {α : Q(Type u)} (BaseType : Q($α) → Type) where /-- Returns whether two coefficients are equal -/ @@ -286,12 +286,12 @@ structure RingCompare {u : Lean.Level} {α : Q(Type u)} (BaseType : Q($α) → T `algebra` will implement these using `ring` -/ structure RingCompute {u : Lean.Level} {α : Q(Type u)} (BaseType : Q($α) → Type) (sα : Q(CommSemiring $α)) extends RingCompare BaseType where - /-- Evaluate the sum of two coefficents. + /-- Evaluate the sum of two coefficients. If the result is zero returns a proof of this fact, which is used to remove zero terms. -/ add {x y : Q($α)} : BaseType x → BaseType y → MetaM ((Result BaseType q($x + $y)) × (Option Q(IsNat ($x + $y) 0))) - /-- Evaluate the product of two coefficents. -/ + /-- Evaluate the product of two coefficients. -/ mul {x y : Q($α)} : BaseType x → BaseType y → MetaM (Result BaseType q($x * $y)) /-- Given a commutative ring `β` with a scalar multiplication action on `α` and a `x : β`, cast `x` to `α` such that the scalar multiplication turns into normal multiplication. Typically one diff --git a/Mathlib/Tactic/SetNotationForOrder.lean b/Mathlib/Tactic/SetNotationForOrder.lean index b8a5b03d200ae9..48c149854bc08b 100644 --- a/Mathlib/Tactic/SetNotationForOrder.lean +++ b/Mathlib/Tactic/SetNotationForOrder.lean @@ -26,7 +26,7 @@ tagged with `@[use_set_notation_for_order]`. This tag is used for `Set`, `Finset`, `PSet` and `ZFSet`. It is not used for `Multiset` and `List`, since they have both `≤` and `⊆` defined on them, with different meanings. -TODO: Unify more order operations suh as `∪`/`⊔` and `∩`/`⊓`. +TODO: Unify more order operations such as `∪`/`⊔` and `∩`/`⊓`. -/ /-- `UsesSetNotationForOrder` is used to track whether a type is tagged with diff --git a/Mathlib/Tactic/Translate/Core.lean b/Mathlib/Tactic/Translate/Core.lean index a7e4bb221eb5dc..aedaa43e71627b 100644 --- a/Mathlib/Tactic/Translate/Core.lean +++ b/Mathlib/Tactic/Translate/Core.lean @@ -1002,7 +1002,7 @@ partial def checkExistingType (t : TranslateData) (src tgt : Name) (cfg : Config unless ← withReducible <| isDefEq srcType tgtType do throwError "`{t.attrName}` validation failed: expected{indentExpr srcType}\nbut '{tgt}' has \ type{indentExpr tgtType}" - -- Process any remaining universe contraints, to assign all universe metavariables. + -- Process any remaining universe constraints, to assign all universe metavariables. discard <| processPostponed (mayPostpone := false) (exceptionOnFailure := true) let tgtParams := tgtDecl.levelParams.toArray let params ← levels.mapIdxM fun i level ↦ do diff --git a/Mathlib/Topology/Algebra/Module/IsWeak.lean b/Mathlib/Topology/Algebra/Module/IsWeak.lean index 841dc9ef2932b4..a3bd4fe91935b3 100644 --- a/Mathlib/Topology/Algebra/Module/IsWeak.lean +++ b/Mathlib/Topology/Algebra/Module/IsWeak.lean @@ -36,7 +36,7 @@ example (y : F) : Continuous (fun x : E ↦ B' x y) := sorry ``` However, this statement contains an abuse of the the definitional equality `E := E'` since `x : E`, -but `B'` has domain `E'`. Morever, one might be tempted to say that `B'.IsWeak`, but this is +but `B'` has domain `E'`. Moreover, one might be tempted to say that `B'.IsWeak`, but this is impossible because the domain of `B'` is `E'`, which is equipped with the incorrect topology. Instead, what one should do is to first define a new bilinear form `B : E →ₗ[𝕜] F →ₗ[𝕜] 𝕜` by composing `B'` with the linear equivalence between `E` and `E'`, and then establish `B.IsWeak`. diff --git a/Mathlib/Topology/Algebra/Valued/ValuedField.lean b/Mathlib/Topology/Algebra/Valued/ValuedField.lean index a61856d733f391..235700f18d270d 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuedField.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuedField.lean @@ -421,7 +421,7 @@ theorem closure_coe_completion_v_mul_v_lt {r s : K} (hr : r ≠ 0) (hs : s ≠ 0 all_goals simp [← lt_div_iff₀, zero_lt_iff, hr] /-- The zero-preserving monoid homomorphism from the `ValueGroup₀` of the valuation on `K` to -that of the extension to its completion. TODO: Split out the definiton of `(restrict₀_surjective +that of the extension to its completion. TODO: Split out the definition of `(restrict₀_surjective (.ofClass hv.v) x).choose` and prove a spec lemma of it. Remove tactic `set` in the proof. -/ noncomputable def valueGroup₀_hom_extensionValuation : ValueGroup₀ (.ofClass hv.v) →*₀ ValueGroup₀ (.ofClass hv.extensionValuation) where diff --git a/Mathlib/Topology/CWComplex/Classical/Basic.lean b/Mathlib/Topology/CWComplex/Classical/Basic.lean index 3d5c0296936294..5b66d66c1ceeba 100644 --- a/Mathlib/Topology/CWComplex/Classical/Basic.lean +++ b/Mathlib/Topology/CWComplex/Classical/Basic.lean @@ -71,10 +71,10 @@ together. below for a restriction on when we want to create aliases. * For types and definitions relevant to CW complexes like `cell`, `openCell`, `closedCell`, `cellFrontier`, `skeletonLT` and similar, we want there to exist only one actually used version, - namely the version in the `RelCWComplex` namespace (and thus no seperate definition in the + namely the version in the `RelCWComplex` namespace (and thus no separate definition in the `CWComplex` namespace.) This is to avoid unnecessary duplication of lemmas. To achieve this, definitions from the `RelCWComplex` namespace should be added to the `CWComplex` namespace with - `export` intead of `alias_in`/`alias`. These will then apply to the absolute CW complex through + `export` instead of `alias_in`/`alias`. These will then apply to the absolute CW complex through the instance `CWComplex.instRelCWComplex`. * For statements, the auxiliary construction `skeletonLT` is preferred over `skeleton` as it makes the base case of inductions easier. The statement about `skeleton` should then be derived from the diff --git a/Mathlib/Topology/Sets/Compacts.lean b/Mathlib/Topology/Sets/Compacts.lean index bcac748c537c1a..1663594972ba34 100644 --- a/Mathlib/Topology/Sets/Compacts.lean +++ b/Mathlib/Topology/Sets/Compacts.lean @@ -284,7 +284,7 @@ theorem singleton_prod_singleton (x : α) (y : β) : open Topology -/-- The compacts neigbourhoods of a compact -/ +/-- The compacts neighbourhoods of a compact -/ def compactNhds (K : Compacts α) : Set (Compacts α) := {K' | ∀ (x : K), (K': Set α) ∈ 𝓝 x.val} @@ -301,7 +301,7 @@ lemma exists_open_set_nhds_of_mem_compactsNhds {K K' : Compacts α} (h : K' ∈ ∃ U : Opens α, (K : Set α) ⊆ U ∧ (U : Set α) ⊆ K' := exists_open_set_nhds_of_compactsNhds ⟨K', h⟩ -/-- The compact neigbourhood induced by the existence of an open subset between two compacts -/ +/-- The compact neighbourhood induced by the existence of an open subset between two compacts -/ def compactNhdsMkOfOpens {K : Compacts α} (L : Compacts α) (U : Opens α) (h1 : (K : Set α) ⊆ U) (h2 : (U : Set α) ⊆ L) : K.compactNhds := @@ -322,7 +322,7 @@ instance (K : Compacts α) : IsCodirectedOrder K.openNhds where ⟨Subtype.mk_le_mk.2 inf_le_left, Subtype.mk_le_mk.2 inf_le_right⟩⟩ instance (K : Compacts α) : Top K.openNhds := ⟨⊤, Set.subset_univ _⟩ --- in particular `K.openNhds` is not empty and thus the induced catgory is cofiltered +-- in particular `K.openNhds` is not empty and thus the induced category is cofiltered instance : Bot (⊥ : Compacts α).openNhds := ⟨⊥, fun _ h ↦ h⟩ @@ -378,14 +378,14 @@ namespace Opens /-- The set of compacts inside an open subset -/ def compactsInside (U : Opens α) : Set (Compacts α) := {K | (K : Set α) ⊆ U} -/-- For `K` a compact subset insde an open subset `U`, `U` has a structure of open neighbourhood +/-- For `K` a compact subset inside an open subset `U`, `U` has a structure of open neighbourhood of `K` -/ def openNhdsOfCompactsInside {U : Opens α} (K : U.compactsInside) : (K.val).openNhds := ⟨U, K.property⟩ end Opens -/-- For `U` an open neighbourhood of `K`, `K` has a structure of compact insde `U` -/ +/-- For `U` an open neighbourhood of `K`, `K` has a structure of compact inside `U` -/ def Compacts.compactsInsideOfOpenNhds {K : Compacts α} (U : K.openNhds) : (U.val).compactsInside := ⟨K, U.property⟩ From d5c40f0b612031a266692bc719fa5fef659fb7fa Mon Sep 17 00:00:00 2001 From: Francesco Chotuck <101644758+FrankieNC@users.noreply.github.com> Date: Sat, 1 Aug 2026 13:56:11 +0000 Subject: [PATCH 1119/1300] feat(MeasureTheory): pushforward of Hausdorff measure under a homothety (#41798) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove `Measure.map (AffineMap.homothety x c) μH[d] = ‖c‖₊⁻¹ ^ d • μH[d]` for `c ≠ 0`, resolving the TODO in `Mathlib/MeasureTheory/Measure/Hausdorff.lean`: the generalisation of `AffineMap.homothety_continuous` it was waiting for has since been merged, so the result follows from `hausdorffMeasure_homothety_preimage` via `Measure.ext`. --- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index da41388c14e8c8..40c6cffbbc9303 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -1065,9 +1065,11 @@ theorem hausdorffMeasure_homothety_preimage {d : ℝ} (hd : 0 ≤ d) (x : P) {c hausdorffMeasure_homothety_image hd x (_ : 𝕜ˣ).isUnit.ne_zero, Units.val_inv_eq_inv_val, Units.val_mk0, nnnorm_inv] -/-! TODO: prove `Measure.map (AffineMap.homothety x c) μH[d] = ‖c‖₊⁻¹ ^ d • μH[d]`, which needs a -more general version of `AffineMap.homothety_continuous`. -/ - +theorem map_homothety_hausdorffMeasure {d : ℝ} (hd : 0 ≤ d) (x : P) {c : 𝕜} (hc : c ≠ 0) : + Measure.map (AffineMap.homothety x c) μH[d] = ‖c‖₊⁻¹ ^ d • μH[d] := by + ext s hs + rw [Measure.map_apply (AffineMap.homothety_continuous x c).measurable hs, + hausdorffMeasure_homothety_preimage hd x hc s, Measure.smul_apply] end NormedFieldAffine From cb48454af87fbe318fc368e6eb02c9156e1936c1 Mon Sep 17 00:00:00 2001 From: Whysoserioushah <109107491+Whysoserioushah@users.noreply.github.com> Date: Sat, 1 Aug 2026 16:40:17 +0000 Subject: [PATCH 1120/1300] chore(RingTheory/Valuation/Basic): remove all `set_option`s in this file (#42335) Co-authored-by: Whysoseriourhah --- Mathlib/RingTheory/Valuation/Basic.lean | 117 ++++++++++-------- .../Valuation/ValuativeRel/Basic.lean | 6 +- 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index 01cd74bc421dbb..0c0dcca687ef30 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -351,12 +351,17 @@ theorem map_one_sub_of_lt (h : v x < 1) : v (1 - x) = 1 := by rw [sub_eq_add_neg 1 x] simpa only [v.map_one, v.map_neg] using v.map_add_eq_of_lt_left h -set_option backward.isDefEq.respectTransparency false in +lemma OrderMonoidWithZeroHom.ofClass_monotone {F : Type u_1} {α : Type u_2} {β : Type u_3} + [LinearOrderedCommMonoidWithZero α] [LinearOrderedCommMonoidWithZero β] [FunLike F α β] + [MonoidWithZeroHomClass F α β] {f : F} (hf : Monotone f) : + Monotone (MonoidWithZeroHom.ofClass f) := hf + /-- An ordered monoid isomorphism `Γ₀ ≃ Γ'₀` induces an equivalence `Valuation R Γ₀ ≃ Valuation R Γ'₀`. -/ def congr (f : Γ₀ ≃*o Γ'₀) : Valuation R Γ₀ ≃ Valuation R Γ'₀ where - toFun := map (.ofClass f) f.toOrderIso.monotone - invFun := map (.ofClass f.symm) f.toOrderIso.symm.monotone + toFun := map (.ofClass f) (OrderMonoidWithZeroHom.ofClass_monotone f.toOrderIso.monotone) + invFun := map (.ofClass f.symm) + (OrderMonoidWithZeroHom.ofClass_monotone f.symm.toOrderIso.monotone) left_inv _ := by ext; simp right_inv _ := by ext; simp @@ -457,20 +462,32 @@ lemma leAddSubgroup_monotone (v : Valuation R Γ₀) : Monotone v.leAddSubgroup open MonoidWithZeroHom MonoidWithZeroHom.ValueGroup₀ -set_option backward.isDefEq.respectTransparency.types false in /-- The restriction of a valuation so that it takes values in its `valueGroup₀`. -/ def restrict : Valuation R (ValueGroup₀ (.ofClass v)) where __ := restrict₀ (.ofClass v) map_add_le_max' x y := by by_cases H : v x ≠ 0 ∨ v y ≠ 0 - · rcases H with h | h <;> - simp only [ZeroHom.toFun_eq_coe, toZeroHom_coe, restrict₀_apply, coe_ofClass, h, - reduceDIte, le_sup_iff] <;> - · split_ifs with H _ hy - all_goals simp [← Units.val_le_val] - simpa using map_add_le _ (by simp_all) (by simp_all) + · rcases H with h | h + all_goals simp only [ZeroHom.toFun_eq_coe, toZeroHom_coe, restrict₀_apply, coe_ofClass, h, + reduceDIte, le_sup_iff] + all_goals split_ifs with H + · simp [H] + · simp only [H, ↓reduceDIte, WithZero.coe_le_coe, Subtype.mk_le_mk, ← Units.val_le_val, + Units.val_mk0] + split_ifs with hy + · simpa [hy] using map_add_le _ (le_rfl (a := v x)) (hy ▸ zero_le) + · simp [hy, ← Units.val_le_val] + · simp [H] + · simp only [H, ↓reduceDIte, WithZero.coe_le_coe, Subtype.mk_le_mk] + split_ifs with hx + · simpa [hx, ← Units.val_le_val] using map_add_le _ (hx ▸ zero_le) (le_rfl (a := v y)) + · simp [hx, ← Units.val_le_val] · simp only [ne_eq, not_or, Decidable.not_not] at H - simpa [restrict₀_apply, H] using map_add_le _ (le_of_eq H.1) (le_of_eq H.2) + simp only [ZeroHom.toFun_eq_coe, toZeroHom_coe, restrict₀_apply, + MonoidWithZeroHom.coe_ofClass, H, ↓reduceDIte, max_self, nonpos_iff_eq_zero] + replace H : v (x + y) = 0 := + le_antisymm (map_add_le _ (le_of_eq H.1) (le_of_eq H.2)) zero_le + simp [H] lemma restrict_def (x : R) : v.restrict x = restrict₀ (.ofClass v) x := rfl @@ -478,34 +495,36 @@ lemma restrict_def (x : R) : v.restrict x = restrict₀ (.ofClass v) x := rfl lemma embedding_restrict (x : R) : embedding (v.restrict x) = v x := embedding_restrict₀ x -set_option backward.isDefEq.respectTransparency false in +lemma restrict_lt_iff_lt_embedding {x : R} {g : ValueGroup₀ (.ofClass v)} : + v.restrict x < g ↔ v x < embedding g := + embedding_strictMono.lt_iff_lt.symm.trans (by simp) + +lemma restrict_le_iff_le_embedding {x : R} {g : ValueGroup₀ (.ofClass v)} : + v.restrict x ≤ g ↔ v x ≤ embedding g := + embedding_strictMono.le_iff_le.symm.trans (by simp) + lemma restrict_eq_mk {x : R} (hx : v x ≠ 0) : v.restrict x = (valueGroup.mk (.ofClass v) 1 x (by simp) hx : ValueGroup₀ (.ofClass v)) := by - simp [restrict_def, restrict₀_apply, dif_neg hx, valueGroup.mk] + simp [restrict_def, restrict₀_apply, valueGroup.mk, hx] @[simp] lemma restrict_pos_iff (x : R) : 0 < v.restrict x ↔ 0 < v x := by simp only [restrict_def, restrict₀_apply] split_ifs with h <;> simpa [zero_lt_iff] -set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma restrict_lt_iff {x y : R} : v.restrict x < v.restrict y ↔ v x < v y := by - simp [restrict_def, restrict₀_apply] - split_ifs with hx hy <;> simp_all [zero_lt_iff.mpr, ← Units.val_lt_val] + rw [restrict_lt_iff_lt_embedding, embedding_restrict] -set_option backward.isDefEq.respectTransparency.types false in -theorem isEquiv_restrict : v.IsEquiv v.restrict := by - intro x y - aesop (add norm [restrict_def, restrict₀_apply]) +@[simp] +lemma restrict_le_iff {x y : R} : v.restrict x ≤ v.restrict y ↔ v x ≤ v y := by + rw [restrict_le_iff_le_embedding, embedding_restrict] -lemma restrict_lt_iff_lt_embedding {x : R} {g : ValueGroup₀ (.ofClass v)} : - v.restrict x < g ↔ v x < embedding g := - embedding_strictMono.lt_iff_lt.symm.trans (by simp) +@[simp] +lemma restrict_inj {x y : R} : v.restrict x = v.restrict y ↔ v x = v y := + embedding_inj.symm.trans (by simp) -lemma restrict_le_iff_le_embedding {x : R} {g : ValueGroup₀ (.ofClass v)} : - v.restrict x ≤ g ↔ v x ≤ embedding g := - embedding_strictMono.le_iff_le.symm.trans (by simp) +theorem isEquiv_restrict : v.IsEquiv v.restrict := fun _ _ ↦ v.restrict_le_iff.symm @[simp] lemma restrict_lt_one_iff {x : R} : v.restrict x < 1 ↔ v x < 1 := by @@ -523,18 +542,6 @@ lemma restrict_eq_zero_iff {x : R} : v.restrict x = 0 ↔ v x = 0 := by lemma restrict_eq_one_iff {x : R} : v.restrict x = 1 ↔ v x = 1 := by simp [restrict_def, restrict₀_eq_one_iff] -set_option backward.isDefEq.respectTransparency.types false in -@[simp] -lemma restrict_le_iff {x y : R} : v.restrict x ≤ v.restrict y ↔ v x ≤ v y := by - simp only [restrict_def, restrict₀_apply, MonoidWithZeroHom.coe_ofClass] - split_ifs with hx hy <;> simp_all [← Units.val_le_val] - -set_option backward.isDefEq.respectTransparency.types false in -@[simp] -lemma restrict_inj {x y : R} : v.restrict x = v.restrict y ↔ v x = v y := by - simp only [restrict_def, restrict₀_apply, MonoidWithZeroHom.coe_ofClass] - aesop - lemma exists_div_eq_of_unit (γ : (ValueGroup₀ (.ofClass v))ˣ) : ∃ r s, 0 < v r ∧ 0 < v s ∧ v.restrict r / v.restrict s = γ.1 := by set u := WithZero.unzero (Units.ne_zero γ) with hu_def @@ -725,6 +732,9 @@ theorem eq_zero (h : v₁.IsEquiv v₂) {r : R} : v₁ r = 0 ↔ v₂ r = 0 := b have : v₁ r = v₁ 0 ↔ v₂ r = v₂ 0 := h.eq_iff rwa [v₁.map_zero, v₂.map_zero] at this +lemma ofClass_eq_zero (h : v₁.IsEquiv v₂) {r : R} : (MonoidWithZeroHom.ofClass v₁) r = 0 ↔ + (MonoidWithZeroHom.ofClass v₂) r = 0 := eq_zero h + @[deprecated "use `(eq_zero _).ne` instead." (since := "2026-01-05")] theorem ne_zero (h : v₁.IsEquiv v₂) {r : R} : v₁ r ≠ 0 ↔ v₂ r ≠ 0 := (eq_zero h).ne @@ -797,6 +807,7 @@ section LinearOrderedCommGroupWithZero variable [LinearOrderedCommGroupWithZero Γ₀] [LinearOrderedCommGroupWithZero Γ'₀] [LinearOrderedCommGroupWithZero Γ''₀] + section Ring variable [Ring R] {v : Valuation R Γ₀} {w : Valuation R Γ'₀} {u : Valuation R Γ''₀} @@ -814,10 +825,12 @@ noncomputable def valueGroup₀Fun (h : v.IsEquiv w) (x : ValueGroup₀ (.ofClas haveI c := (x.zero_or_exists_mk'.resolve_left hx).choose valueGroup.mk (.ofClass w) c.1.1 c.1.2 (h.eq_zero.ne.mp c.2.1) (h.eq_zero.ne.mp c.2.2) -set_option backward.isDefEq.respectTransparency.types false in -theorem valueGroup₀Fun_spec (h : v.IsEquiv w) {r s : R} (hr : v r ≠ 0) (hs : v s ≠ 0) : +theorem valueGroup₀Fun_spec (h : v.IsEquiv w) {r s : R} (hr : (MonoidWithZeroHom.ofClass v) r ≠ 0) + (hs : (MonoidWithZeroHom.ofClass v) s ≠ 0) + (hr' : (MonoidWithZeroHom.ofClass w) r ≠ 0 := h.ofClass_eq_zero.ne.1 hr) + (hs' : (MonoidWithZeroHom.ofClass w) s ≠ 0 := h.ofClass_eq_zero.ne.1 hs) : valueGroup₀Fun h (valueGroup.mk (.ofClass v) r s hr hs) = - valueGroup.mk (.ofClass w) r s (h.eq_zero.ne.mp hr) (h.eq_zero.ne.mp hs) := by + valueGroup.mk (.ofClass w) r s hr' hs' := by rw [valueGroup₀Fun, dif_neg (by simp)] generalize_proofs _ _ _ _ H _ have c_spec := H.choose_spec @@ -826,7 +839,6 @@ theorem valueGroup₀Fun_spec (h : v.IsEquiv w) {r s : R} (hr : v r ≠ 0) (hs : theorem valueGroup₀Fun_zero (h : v.IsEquiv w) : valueGroup₀Fun h 0 = 0 := by simp [valueGroup₀Fun] -set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism between the `ValueGroup₀`'s of two equivalent valuations. -/ noncomputable def orderMonoidIso (h : v.IsEquiv w) : ValueGroup₀ (.ofClass v) ≃*o ValueGroup₀ (.ofClass w) where @@ -837,15 +849,15 @@ noncomputable def orderMonoidIso (h : v.IsEquiv w) : · simp_all [valueGroup₀Fun_zero] obtain _ | ⟨r₂, s₂, hr₂, hs₂, rfl⟩ := y.zero_or_exists_mk · simp_all [valueGroup₀Fun_zero] - simp [← WithZero.coe_mul, valueGroup.mk_mul, valueGroup₀Fun_spec] + simp [← WithZero.coe_mul, valueGroup.mk_mul, valueGroup₀Fun_spec h] left_inv x := by obtain _ | ⟨r₁, s₁, hr₁, hs₁, rfl⟩ := x.zero_or_exists_mk · simp_all [valueGroup₀Fun_zero] - simp [valueGroup₀Fun_spec] + rw [valueGroup₀Fun_spec h, valueGroup₀Fun_spec h.symm] right_inv x := by obtain _ | ⟨r₁, s₁, hr₁, hs₁, rfl⟩ := x.zero_or_exists_mk · simp_all [valueGroup₀Fun_zero] - simp [valueGroup₀Fun_spec] + rw [valueGroup₀Fun_spec h.symm, valueGroup₀Fun_spec h] map_le_map_iff' {x} {y} := by simp only [valueGroup₀Fun, ne_eq] split_ifs with hx0 hy0 hy0 @@ -880,30 +892,33 @@ theorem orderMonoidIso_spec (h : v.IsEquiv w) (a : R) : · rw [← restrict_eq_zero_iff] at ha rwa [ha, map_zero, Eq.comm, ← h_res.eq_zero] · rw [(v.restrict_eq_mk ha)] - convert! valueGroup₀Fun_spec (h := h) (hs := ha) (r := 1) (by simp) - exact w.restrict_eq_mk ((eq_zero h.symm).ne.mpr ha) + simp [orderMonoidIso, valueGroup₀Fun_spec h (hs := ha), + w.restrict_eq_mk ((eq_zero h.symm).ne.mpr ha)] + +lemma orderMonoidIso_spec₀ (h : v.IsEquiv w) (a : R) : + h.orderMonoidIso (restrict₀ (.ofClass v) a) = restrict₀ (.ofClass w) a := + orderMonoidIso_spec h a theorem orderMonoidIso_symm (h : v.IsEquiv w) (h' : w.IsEquiv v) : h.orderMonoidIso.symm = h'.orderMonoidIso := by rfl -set_option backward.isDefEq.respectTransparency false in @[simp] theorem orderMonoidIso_eq_refl (h : v.IsEquiv v) : h.orderMonoidIso = .refl _ := by ext x obtain (rfl | ⟨x, y, _, _, rfl⟩) := x.zero_or_exists_mk · simp - · simp [orderMonoidIso, valueGroup₀Fun_spec] + · simp [orderMonoidIso, valueGroup₀Fun_spec h] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem orderMonoidIso_trans (h : v.IsEquiv w) (h' : w.IsEquiv u) : h.orderMonoidIso.trans h'.orderMonoidIso = (h.trans h').orderMonoidIso := by ext x obtain (rfl | ⟨x, y, _, _, rfl⟩) := x.zero_or_exists_mk · simp - · simp [orderMonoidIso, valueGroup₀Fun_spec] + · simp [orderMonoidIso, valueGroup₀Fun_spec h, valueGroup₀Fun_spec h', + valueGroup₀Fun_spec (trans h h')] end IsEquiv diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 2fe43093426cbc..12d87ad0c614f7 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -1149,7 +1149,6 @@ lemma embed_strictMono [v.Compatible] : StrictMono (embed v) := by · simp [restrict₀_apply, embed] · simp [restrict₀_apply, embed] -set_option backward.isDefEq.respectTransparency false in /-- When we have `h : w.IsEquiv v`, the image group (with zero) of `v` is isomorphic to that of `w` via `h.orderMonoidIso`. Then the following diagram is commutative: @@ -1170,10 +1169,9 @@ theorem orderMonoidIso_embed [v.Compatible] {Γ' : Type*} [LinearOrderedCommGrou (w : Valuation R Γ') [w.Compatible] (x : ValueGroupWithZero R) (h : w.IsEquiv v) : h.orderMonoidIso (embed w x) = embed v x := by - simp only [embed, ← Valuation.restrict_def, coe_mk, ZeroHom.coe_mk] + simp only [embed, coe_mk, ZeroHom.coe_mk] induction x using ValueGroupWithZero.ind with - | mk r s => - simp + | mk r s => simp [Valuation.IsEquiv.orderMonoidIso_spec₀] /-- If a valuation `v` is compatible with the valuative relation, then `ValueGroupWithZero R` is isomorphic to the image group (with zero) of `v` as an ordered group with zero. -/ From 0419afcbb9cf185587c9caf12e0cd4408f517127 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sat, 1 Aug 2026 21:09:15 +0000 Subject: [PATCH 1121/1300] chore(Combinatorics/SimpleGraph/Operations): golf `edge` lemmas (#41873) Also tags `Subgraph.Adj.adj_sub`/`spanningCoe_adj`/`sup_adj`/`edge_adj` with `grind`. --- .../Combinatorics/SimpleGraph/Acyclic.lean | 4 +-- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 2 +- .../Combinatorics/SimpleGraph/Operations.lean | 26 +++++++------------ .../Combinatorics/SimpleGraph/Subgraph.lean | 5 +++- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index 47fd0de04d4595..1cab39f71980da 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -402,9 +402,9 @@ lemma reachable_eq_of_maximal_isAcyclic (F : SimpleGraph V) have : ∃ d ∈ p.darts, d.fst ∈ s ∧ d.snd ∉ s := p.exists_boundary_dart s rfl this rcases this with ⟨⟨⟨u', v'⟩, huv⟩, _, hu, hv⟩ have : ¬F.Reachable v' u' := mt ConnectedComponent.sound <| s.mem_supp_iff u' |>.mp hu ▸ hv - suffices F ⊔ edge v' u' ≤ F by grind [Adj.reachable, sup_le_iff, le_iff_adj, edge_adj] + suffices F ⊔ edge v' u' ≤ F by grind [Adj.reachable, sup_le_iff, le_iff_adj] refine h.le_of_ge ⟨?_, h.prop.right.sup_edge_of_not_reachable this⟩ le_sup_left - grind [Maximal, sup_le, le_iff_adj, edge_adj, huv.symm] + grind [Maximal, sup_le, le_iff_adj, huv.symm] /-- A subgraph is maximal acyclic iff its reachability relation agrees with the larger graph. -/ theorem maximal_isAcyclic_iff_reachable_eq {F : SimpleGraph V} (hle : F ≤ G) (hF : F.IsAcyclic) : diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index f6adc4c39b8f97..8ce12ed2ddcb40 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -221,7 +221,7 @@ instance : Max (SimpleGraph V) where { Adj := x.Adj ⊔ y.Adj symm.symm v w h := by rwa [Pi.sup_apply, Pi.sup_apply, x.adj_comm, y.adj_comm] } -@[simp] +@[simp, grind =] theorem sup_adj (x y : SimpleGraph V) (v w : V) : (x ⊔ y).Adj v w ↔ x.Adj v w ∨ y.Adj v w := Iff.rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Operations.lean b/Mathlib/Combinatorics/SimpleGraph/Operations.lean index 19ba94a37b0bfa..726a7875608e34 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Operations.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Operations.lean @@ -136,13 +136,12 @@ section AddEdge /-- The graph with a single `s-t` edge. It is empty iff `s = t`. -/ def edge : SimpleGraph V := fromEdgeSet {s(s, t)} +@[grind =] lemma edge_adj (v w : V) : (edge s t).Adj v w ↔ (v = s ∧ w = t ∨ v = t ∧ w = s) ∧ v ≠ w := by rw [edge, fromEdgeSet_adj, Set.mem_singleton_iff, Sym2.eq_iff] lemma adj_edge {v w : V} : (edge s t).Adj v w ↔ s(s, t) = s(v, w) ∧ v ≠ w := by - simp only [edge_adj, ne_eq, Sym2.eq, Sym2.rel_iff', Prod.mk.injEq, Prod.swap_prod_mk, - and_congr_left_iff] - tauto + grind lemma edge_comm : edge s t = edge t s := by rw [edge, edge, Sym2.eq_swap] @@ -166,7 +165,7 @@ lemma edge_le_iff {v w : V} : edge v w ≤ G ↔ v = w ∨ G.Adj v w := by obtain h | h := eq_or_ne v w · simp [h] · refine ⟨fun h ↦ .inr <| h (by simp_all [edge_adj]), fun hadj v' w' hvw' ↦ ?_⟩ - aesop (add simp [edge_adj, adj_symm]) + grind [adj_symm] @[simp] lemma edgeSet_edge (v w : V) : (edge v w).edgeSet = {s(v, w)} \ Sym2.diagSet := by simp [edge] @@ -180,16 +179,14 @@ lemma edgeSet_edge_of_ne (h : s ≠ t) : (edge s t).edgeSet = {s(s, t)} := by si @[deprecated (since := "2026-03-18")] alias edge_edgeSet_of_ne := edgeSet_edge_of_ne lemma sup_edge_of_adj (h : G.Adj s t) : G ⊔ edge s t = G := by - rwa [sup_eq_left, ← edgeSet_subset_edgeSet, edgeSet_edge_of_ne h.ne, Set.singleton_subset_iff, - mem_edgeSet] + simp [h] @[simp] lemma deleteEdges_edge {u v : V} {s : Set (Sym2 V)} (h : s(u, v) ∈ s) : (edge u v).deleteEdges s = ⊥ := by simp [edge, Set.sdiff_subset_iff, h] lemma disjoint_edge {u v : V} : Disjoint G (edge u v) ↔ ¬G.Adj u v := by - by_cases h : u = v - · subst h - simp [edge_self_eq_bot] + rcases eq_or_ne u v with rfl | h + · simp [edge_self_eq_bot] simp [← disjoint_edgeSet, edgeSet_edge_of_ne h] lemma sdiff_edge {u v : V} (h : ¬G.Adj u v) : G \ edge u v = G := by @@ -207,11 +204,7 @@ theorem sSup_edge_eq : sSup { edge u v | (u : V) (v : V) (_ : G.Adj u v) } = G : theorem Subgraph.spanningCoe_sup_edge_le {H : Subgraph (G ⊔ edge s t)} (h : ¬ H.Adj s t) : H.spanningCoe ≤ G := by intro v w hvw - have := hvw.adj_sub - simp only [Subgraph.spanningCoe_adj, SimpleGraph.sup_adj, SimpleGraph.edge_adj] at * - by_cases hs : s(v, w) = s(s, t) - · exact (h ((Subgraph.adj_congr_of_sym2 hs).mp hvw)).elim - · aesop + grind [adj_congr_of_sym2] variable [Fintype V] [DecidableRel G.Adj] @@ -220,9 +213,8 @@ instance : Fintype (edge s t).edgeSet := by rw [edge]; infer_instance theorem edgeFinset_sup_edge [Fintype (edgeSet (G ⊔ edge s t))] (hn : ¬G.Adj s t) (h : s ≠ t) : (G ⊔ edge s t).edgeFinset = G.edgeFinset.cons s(s, t) (by simp_all) := by - let := Classical.decEq V - rw [edgeFinset_sup, cons_eq_insert, insert_eq, union_comm] - simp_rw [edgeFinset, edgeSet_edge_of_ne h]; rfl + classical + simp [edgeFinset, edgeSet_edge_of_ne h] theorem card_edgeFinset_sup_edge [Fintype (edgeSet (G ⊔ edge s t))] (hn : ¬G.Adj s t) (h : s ≠ t) : #(G ⊔ edge s t).edgeFinset = #G.edgeFinset + 1 := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean index 62efb7fbfc8f5d..6799d9a54b00d0 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean @@ -111,6 +111,7 @@ theorem adj_symm (G' : Subgraph G) {u v : V} (h : G'.Adj u v) : G'.Adj v u := protected theorem Adj.symm {G' : Subgraph G} {u v : V} (h : G'.Adj u v) : G'.Adj v u := G'.adj_symm h +@[grind →] protected theorem Adj.adj_sub {H : G.Subgraph} {u v : V} (h : H.Adj u v) : G.Adj u v := H.adj_sub h @@ -169,11 +170,13 @@ protected def spanningCoe (G' : Subgraph G) : SimpleGraph V where symm := G'.symm loopless.irrefl _ hadj := G.irrefl hadj.adj_sub +attribute [grind =] Subgraph.spanningCoe_adj + @[simp] lemma spanningCoe_coe (G' : G.Subgraph) : G'.coe.spanningCoe = G'.spanningCoe := by ext simp only [map_adj, Function.Embedding.subtype_apply, Subtype.exists] - grind [spanningCoe_adj, coe_adj, edge_vert, adj_symm] + grind [coe_adj, edge_vert, adj_symm] theorem Adj.of_spanningCoe {G' : Subgraph G} {u v : G'.verts} (h : G'.spanningCoe.Adj u v) : G.Adj u v := From 54df8a3f96ac6f0b356728db732feb977d017aab Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 21:19:44 +0000 Subject: [PATCH 1122/1300] chore: update Mathlib dependencies 2026-08-01 (#42347) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index e8e2d9aa793ee1..71d2d1d50d8f0c 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "2963c249dabd57512a2e101901777e381eb40350", + "rev": "0ecf8993df88c044962426c2cbca0de5717d6150", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 18f56bef5344cefb0563662c495e3eb3824a2589 Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Sun, 2 Aug 2026 03:03:54 +0000 Subject: [PATCH 1123/1300] feat(Analysis/CStarAlgebra/Basic): `star (ball x r) = ball (star x) r` (#42309) --- Mathlib/Analysis/CStarAlgebra/Basic.lean | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mathlib/Analysis/CStarAlgebra/Basic.lean b/Mathlib/Analysis/CStarAlgebra/Basic.lean index 59c88f4ea228c1..3ecd3338d80bc0 100644 --- a/Mathlib/Analysis/CStarAlgebra/Basic.lean +++ b/Mathlib/Analysis/CStarAlgebra/Basic.lean @@ -77,6 +77,26 @@ instance [NormedField 𝕜] [NormedSpace 𝕜 E] [Star 𝕜] [TrivialStar 𝕜] NormedSpace 𝕜 (selfAdjoint E) where norm_smul_le _ _ := norm_smul_le _ (_ : E) +variable (x : E) (r : ℝ) + +@[simp] lemma Metric.star_ball : star (ball x r) = ball (star x) r := by + simpa using star_isometry.preimage_ball (star x) r + +@[simp] lemma Metric.star_closedBall : star (closedBall x r) = closedBall (star x) r := by + simpa using star_isometry.preimage_closedBall (star x) r + +@[simp] lemma Metric.star_sphere : star (sphere x r) = sphere (star x) r := by + simpa using star_isometry.preimage_sphere (star x) r + +@[simp] lemma dist_star_star (x y : E) : dist (star x) (star y) = dist x y := + star_isometry.dist_eq x y + +@[simp] lemma edist_star_star (x y : E) : edist (star x) (star y) = edist x y := + star_isometry.edist_eq x y + +@[simp] lemma nndist_star_star (x y : E) : nndist (star x) (star y) = nndist x y := + star_isometry.nndist_eq x y + end NormedStarGroup instance RingHomIsometric.starRingEnd [NormedCommRing E] [StarRing E] [NormedStarGroup E] : From ae0d973d69b779efa724095bd41793b8cf233831 Mon Sep 17 00:00:00 2001 From: Emily Riehl <19517483+emilyriehl@users.noreply.github.com> Date: Sun, 2 Aug 2026 05:59:39 +0000 Subject: [PATCH 1124/1300] feat(CategoryTheory): initial object implies corepresentable (#41994) If the category of elements of a covariant functor has an initial object, then the functor is corepresentable. Co-authored-by: emilyriehl --- Mathlib/CategoryTheory/Limits/Elements.lean | 55 +++++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Elements.lean b/Mathlib/CategoryTheory/Limits/Elements.lean index 4648d35aba364c..04b8205c1588e6 100644 --- a/Mathlib/CategoryTheory/Limits/Elements.lean +++ b/Mathlib/CategoryTheory/Limits/Elements.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2024 Markus Himmel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Markus Himmel +Authors: Markus Himmel, Emily Riehl -/ module @@ -22,10 +22,6 @@ the category of elements of `A` has limits of shape `I` and the forgetful functo - If `A` is (co)representable, then `A.Elements` has an initial object. -## TODOs - -- Show that `A` is (co)representable if `A.Elements` has an initial object. - -/ set_option backward.defeqAttrib.useBackward true @@ -135,4 +131,53 @@ end Initial end CategoryOfElements +namespace Functor.Elements + +/-- An initial object in the category `F.Elements` of a covariant functor defines a +corepresentation for that functor. -/ +def corepresentableByOfIsInitial {F : C ⥤ Type w} {E : Elements F} (he : IsInitial E) : + CorepresentableBy F E.fst where + homEquiv := + { toFun f := F.map f E.snd + invFun y := (he.to ⟨_, y⟩).val + left_inv f := Subtype.ext_iff.mp (he.hom_ext (he.to ⟨_, F.map f E.snd⟩) ⟨f, rfl⟩) + right_inv y := (he.to ⟨_, y⟩).prop } + +lemma isCorepresentable_of_hasInitial (F : C ⥤ Type w) [HasInitial (Elements F)] : + IsCorepresentable F where + has_corepresentation := + ⟨(⊥_ F.Elements).fst, + (Nonempty.intro (corepresentableByOfIsInitial initialIsInitial))⟩ + +theorem hasInitial_iff_isCorepresentable (F : C ⥤ Type w) : + HasInitial (Elements F) ↔ IsCorepresentable F where + mp _ := isCorepresentable_of_hasInitial F + mpr _ := inferInstance + +/-- An initial object in the category `F.Elements` of a contravariant functor defines a +representation for that functor. -/ +def representableByOfIsInitial {F : Cᵒᵖ ⥤ Type w} {E : Elements F} (he : IsInitial E) : + RepresentableBy F (E.fst.unop) where + homEquiv := + { toFun f := F.map f.op E.snd + invFun y := (he.to ⟨_, y⟩).val.unop + left_inv f := by + have := + Subtype.ext_iff.mp (he.hom_ext (he.to ⟨_, F.map f.op E.snd⟩) ⟨f.op, rfl⟩) + simp only [this, Quiver.Hom.unop_op] + right_inv y := (he.to ⟨_, y⟩).prop } + +lemma isRepresentable_of_hasInitial (F : Cᵒᵖ ⥤ Type w) [HasInitial (Elements F)] : + IsRepresentable F where + has_representation := + ⟨(⊥_ F.Elements).fst.unop, + (Nonempty.intro (representableByOfIsInitial initialIsInitial))⟩ + +theorem hasInitial_iff_isRepresentable (F : Cᵒᵖ ⥤ Type w) : + HasInitial (Elements F) ↔ IsRepresentable F where + mp _ := isRepresentable_of_hasInitial F + mpr _ := inferInstance + +end Functor.Elements + end CategoryTheory From e75dd8437c8d32385c65a341f67a7cb1d82ccef1 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Sun, 2 Aug 2026 09:28:48 +0000 Subject: [PATCH 1125/1300] chore(CategoryTheory/Limits/HasLimit): use `to_dual` (#41017) This PR uses `to_dual` to generate stuff about `HasColimit` from `HasLimit`. --- Mathlib/CategoryTheory/Functor/Const.lean | 3 +- .../FiniteProductsOfBinaryProducts.lean | 1 + Mathlib/CategoryTheory/Limits/HasLimits.lean | 346 +++++------------- Mathlib/CategoryTheory/Limits/IsLimit.lean | 5 - .../Limits/Shapes/Reflexive.lean | 2 +- Mathlib/Tactic/Translate/ToDual.lean | 2 + 6 files changed, 106 insertions(+), 253 deletions(-) diff --git a/Mathlib/CategoryTheory/Functor/Const.lean b/Mathlib/CategoryTheory/Functor/Const.lean index e530356200e8e9..63e02f3b85fa5e 100644 --- a/Mathlib/CategoryTheory/Functor/Const.lean +++ b/Mathlib/CategoryTheory/Functor/Const.lean @@ -37,9 +37,10 @@ def const : C ⥤ J ⥤ C where obj X := { obj := fun _ => X map := fun _ => 𝟙 X } - map f := { app := fun _ => f } + map {X Y} f := { app := fun _ => f } attribute [to_dual self] const_obj_map +attribute [to_dual self (reorder := X Y)] const_map_app namespace const diff --git a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean index 6519554b70f0d9..149da5f4782a7e 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/FiniteProductsOfBinaryProducts.lean @@ -276,6 +276,7 @@ lemma preserves_fin_of_preserves_binary_and_initial : · rintro i _ dsimp [extendCofan_ι_app, Iso.refl_hom, Cofan.mk_ι_app] rw [comp_id, ← F.map_comp] + rfl /-- If `F` preserves the initial object and binary coproducts, then it preserves colimits of shape `Discrete (Fin n)`. diff --git a/Mathlib/CategoryTheory/Limits/HasLimits.lean b/Mathlib/CategoryTheory/Limits/HasLimits.lean index de2746e77dc133..05e795bd8dc5a9 100644 --- a/Mathlib/CategoryTheory/Limits/HasLimits.lean +++ b/Mathlib/CategoryTheory/Limits/HasLimits.lean @@ -45,11 +45,6 @@ and then a result in terms of `HasLimit` derived from this. At this point, however, this is far from uniformly achieved in mathlib --- often statements are only written in terms of `HasLimit`. -## Implementation -At present we simply say everything twice, in order to handle both limits and colimits. -It would be highly desirable to have some automation support, -e.g. a `@[dualize]` attribute that behaves similarly to `@[to_additive]`. - ## References * [Stacks: Limits and colimits](https://stacks.math.columbia.edu/tag/002D) @@ -71,6 +66,8 @@ variable {J : Type u₁} [Category.{v₁} J] {K : Type u₂} [Category.{v₂} K] variable {C : Type u} [Category.{v} C] variable {F : J ⥤ C} +to_dual_name_hint Lift Desc + section Limit /-- `LimitCone F` contains a cone over `F` together with the information that it is a limit. -/ @@ -80,15 +77,33 @@ structure LimitCone (F : J ⥤ C) where /-- The proof that is the limit cone -/ isLimit : IsLimit cone +/-- `ColimitCocone F` contains a cocone over `F` together with the information that it is a +colimit. -/ +@[to_dual] +structure ColimitCocone (F : J ⥤ C) where + /-- The cocone itself -/ + cocone : Cocone F + /-- The proof that it is the colimit cocone -/ + isColimit : IsColimit cocone + /-- `HasLimit F` represents the mere existence of a limit for `F`. -/ class HasLimit (F : J ⥤ C) : Prop where mk' :: /-- There is some limit cone for `F` -/ exists_limit : Nonempty (LimitCone F) +/-- `HasColimit F` represents the mere existence of a colimit for `F`. -/ +@[to_dual] +class HasColimit (F : J ⥤ C) : Prop where mk' :: + /-- There exists a colimit for `F` -/ + exists_colimit : Nonempty (ColimitCocone F) + +@[to_dual] theorem HasLimit.mk {F : J ⥤ C} (d : LimitCone F) : HasLimit F := ⟨Nonempty.intro d⟩ /-- Use the axiom of choice to extract explicit `LimitCone F` from `HasLimit F`. -/ +@[no_expose, to_dual +/-- Use the axiom of choice to extract explicit `ColimitCocone F` from `HasColimit F`. -/] def getLimitCone (F : J ⥤ C) [HasLimit F] : LimitCone F := Classical.choice <| HasLimit.exists_limit @@ -99,6 +114,12 @@ class HasLimitsOfShape : Prop where /-- All functors `F : J ⥤ C` from `J` have limits -/ has_limit : ∀ F : J ⥤ C, HasLimit F := by infer_instance +/-- `C` has colimits of shape `J` if there exists a colimit for every functor `F : J ⥤ C`. -/ +@[to_dual] +class HasColimitsOfShape : Prop where + /-- All `F : J ⥤ C` have colimits for a fixed `J` -/ + has_colimit : ∀ F : J ⥤ C, HasColimit F := by infer_instance + /-- `C` has all limits of size `v₁ u₁` (`HasLimitsOfSize.{v₁ u₁} C`) if it has limits of every shape `J : Type u₁` with `[Category.{v₁} J]`. -/ @@ -111,10 +132,26 @@ class HasLimitsOfSize (C : Type u) [Category.{v} C] : Prop where has_limits_of_shape : ∀ (J : Type u₁) [Category.{v₁} J], HasLimitsOfShape J C := by infer_instance +/-- `C` has all colimits of size `v₁ u₁` (`HasColimitsOfSize.{v₁ u₁} C`) +if it has colimits of every shape `J : Type u₁` with `[Category.{v₁} J]`. +-/ +-- After https://github.com/leanprover/lean4/pull/12286 and +-- https://github.com/leanprover/lean4/pull/12423, the shape universes `v₁, u₁` would default +-- to universe output parameters. See Note [universe output parameters and typeclass caching]. +@[to_dual, univ_out_params, pp_with_univ] +class HasColimitsOfSize (C : Type u) [Category.{v} C] : Prop where + /-- All `F : J ⥤ C` have colimits for all small `J` -/ + has_colimits_of_shape : ∀ (J : Type u₁) [Category.{v₁} J], HasColimitsOfShape J C := by + infer_instance + /-- `C` has all (small) limits if it has limits of every shape that is as big as its hom-sets. -/ +@[to_dual +/-- `C` has all (small) colimits if it has colimits of every shape that is as big as its hom-sets. +-/] abbrev HasLimits (C : Type u) [Category.{v} C] : Prop := HasLimitsOfSize.{v, v} C +@[to_dual] theorem HasLimits.has_limits_of_shape {C : Type u} [Category.{v} C] [HasLimits C] (J : Type v) [Category.{v} J] : HasLimitsOfShape J C := HasLimitsOfSize.has_limits_of_shape J @@ -122,63 +159,76 @@ theorem HasLimits.has_limits_of_shape {C : Type u} [Category.{v} C] [HasLimits C variable {J C} -- see Note [lower instance priority] -instance (priority := 100) hasLimitOfHasLimitsOfShape {J : Type u₁} [Category.{v₁} J] +@[to_dual] +instance (priority := 100) {J : Type u₁} [Category.{v₁} J] [HasLimitsOfShape J C] (F : J ⥤ C) : HasLimit F := HasLimitsOfShape.has_limit F -- see Note [lower instance priority] -instance (priority := 100) hasLimitsOfShapeOfHasLimits {J : Type u₁} [Category.{v₁} J] +@[to_dual] +instance (priority := 100) {J : Type u₁} [Category.{v₁} J] [HasLimitsOfSize.{v₁, u₁} C] : HasLimitsOfShape J C := HasLimitsOfSize.has_limits_of_shape J -- Interface to the `HasLimit` class. /-- An arbitrary choice of limit cone for a functor. -/ +@[to_dual colimit.cocone /-- An arbitrary choice of colimit cocone of a functor. -/] def limit.cone (F : J ⥤ C) [HasLimit F] : Cone F := (getLimitCone F).cone /-- An arbitrary choice of limit object of a functor. -/ -@[implicit_reducible] +@[to_dual (attr := implicit_reducible) /-- An arbitrary choice of colimit object of a functor. -/] def limit (F : J ⥤ C) [HasLimit F] := (limit.cone F).pt /-- The projection from the limit object to a value of the functor. -/ -@[implicit_reducible] +@[to_dual (attr := implicit_reducible) ι +/-- The coprojection from a value of the functor to the colimit object. -/] def limit.π (F : J ⥤ C) [HasLimit F] (j : J) : limit F ⟶ F.obj j := (limit.cone F).π.app j -@[reassoc] theorem limit.π_comp_eqToHom (F : J ⥤ C) [HasLimit F] {j j' : J} (hj : j = j') : limit.π F j ≫ eqToHom (by subst hj; rfl) = limit.π F j' := by subst hj simp -@[simp] +@[to_dual existing (attr := reassoc) π_comp_eqToHom] +theorem colimit.eqToHom_comp_ι (F : J ⥤ C) [HasColimit F] {j j' : J} (hj : j = j') : + eqToHom (by subst hj; rfl) ≫ colimit.ι F j = colimit.ι F j' := by + subst hj + simp + +@[to_dual (attr := simp)] theorem limit.cone_x {F : J ⥤ C} [HasLimit F] : (limit.cone F).pt = limit F := rfl -@[simp] +@[to_dual (attr := simp) cocone_ι] theorem limit.cone_π {F : J ⥤ C} [HasLimit F] : (limit.cone F).π.app = limit.π _ := rfl -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp))] theorem limit.w (F : J ⥤ C) [HasLimit F] {j j' : J} (f : j ⟶ j') : limit.π F j ≫ F.map f = limit.π F j' := (limit.cone F).w f /-- Evidence that the arbitrary choice of cone provided by `limit.cone F` is a limit cone. -/ +@[to_dual +/-- Evidence that the arbitrary choice of cocone is a colimit cocone. -/] def limit.isLimit (F : J ⥤ C) [HasLimit F] : IsLimit (limit.cone F) := (getLimitCone F).isLimit /-- The morphism from the cone point of any other cone to the limit object. -/ +@[to_dual +/-- The morphism from the colimit object to the cone point of any other cocone. -/] def limit.lift (F : J ⥤ C) [HasLimit F] (c : Cone F) : c.pt ⟶ limit F := (limit.isLimit F).lift c -@[simp] +@[to_dual (attr := simp)] theorem limit.isLimit_lift {F : J ⥤ C} [HasLimit F] (c : Cone F) : (limit.isLimit F).lift c = limit.lift F c := rfl -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) ι_desc] theorem limit.lift_π {F : J ⥤ C} [HasLimit F] (c : Cone F) (j : J) : limit.lift F c ≫ limit.π F j = c.π.app j := IsLimit.fac _ c j @@ -189,77 +239,91 @@ Usually this morphism should be accessed through `lim.map`, but may be needed separately when you have specified limits for the source and target functors, but not necessarily for all functors of shape `J`. -/ +@[to_dual +/-- Functoriality of colimits. + +Usually this morphism should be accessed through `colim.map`, +but may be needed separately when you have specified colimits for the source and target functors, +but not necessarily for all functors of shape `J`. +-/] def limMap {F G : J ⥤ C} [HasLimit F] [HasLimit G] (α : F ⟶ G) : limit F ⟶ limit G := IsLimit.map _ (limit.isLimit G) α -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) ι_colimMap] theorem limMap_π {F G : J ⥤ C} [HasLimit F] [HasLimit G] (α : F ⟶ G) (j : J) : limMap α ≫ limit.π G j = limit.π F j ≫ α.app j := limit.lift_π _ j /-- The cone morphism from any cone to the arbitrary choice of limit cone. -/ +@[to_dual /-- The cocone morphism from the arbitrary choice of colimit cocone to any cocone. -/] def limit.coneMorphism {F : J ⥤ C} [HasLimit F] (c : Cone F) : c ⟶ limit.cone F := (limit.isLimit F).liftConeMorphism c -@[simp] +@[to_dual (attr := simp)] theorem limit.coneMorphism_hom {F : J ⥤ C} [HasLimit F] (c : Cone F) : (limit.coneMorphism c).hom = limit.lift F c := rfl +@[to_dual ι_coconeMorphism] theorem limit.coneMorphism_π {F : J ⥤ C} [HasLimit F] (c : Cone F) (j : J) : (limit.coneMorphism c).hom ≫ limit.π F j = c.π.app j := by simp -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) comp_coconePointUniqueUpToIso_inv] theorem limit.conePointUniqueUpToIso_hom_comp {F : J ⥤ C} [HasLimit F] {c : Cone F} (hc : IsLimit c) (j : J) : (IsLimit.conePointUniqueUpToIso hc (limit.isLimit _)).hom ≫ limit.π F j = c.π.app j := IsLimit.conePointUniqueUpToIso_hom_comp _ _ _ -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) comp_coconePointUniqueUpToIso_hom] theorem limit.conePointUniqueUpToIso_inv_comp {F : J ⥤ C} [HasLimit F] {c : Cone F} (hc : IsLimit c) (j : J) : (IsLimit.conePointUniqueUpToIso (limit.isLimit _) hc).inv ≫ limit.π F j = c.π.app j := IsLimit.conePointUniqueUpToIso_inv_comp _ _ _ +@[to_dual] theorem limit.existsUnique {F : J ⥤ C} [HasLimit F] (t : Cone F) : ∃! l : t.pt ⟶ limit F, ∀ j, l ≫ limit.π F j = t.π.app j := (limit.isLimit F).existsUnique _ -/-- Given any other limit cone for `F`, the chosen `limit F` is isomorphic to the cone point. --/ +/-- Given any other limit cone for `F`, the chosen `limit F` is isomorphic to the cone point. -/ +@[to_dual +/-- Given any other colimit cocone for `F`, the chosen `colimit F` is isomorphic to the cocone +point. -/] def limit.isoLimitCone {F : J ⥤ C} [HasLimit F] (t : LimitCone F) : limit F ≅ t.cone.pt := IsLimit.conePointUniqueUpToIso (limit.isLimit F) t.isLimit -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) isoColimitCocone_ι_inv] theorem limit.isoLimitCone_hom_π {F : J ⥤ C} [HasLimit F] (t : LimitCone F) (j : J) : (limit.isoLimitCone t).hom ≫ t.cone.π.app j = limit.π F j := by dsimp [limit.isoLimitCone, IsLimit.conePointUniqueUpToIso] simp -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) isoColimitCocone_ι_hom] theorem limit.isoLimitCone_inv_π {F : J ⥤ C} [HasLimit F] (t : LimitCone F) (j : J) : (limit.isoLimitCone t).inv ≫ limit.π F j = t.cone.π.app j := by dsimp [limit.isoLimitCone, IsLimit.conePointUniqueUpToIso] simp -@[ext] +@[to_dual (attr := ext)] theorem limit.hom_ext {F : J ⥤ C} [HasLimit F] {X : C} {f f' : X ⟶ limit F} (w : ∀ j, f ≫ limit.π F j = f' ≫ limit.π F j) : f = f' := (limit.isLimit F).hom_ext w +@[to_dual] instance isIso_limMap {F G : J ⥤ C} [HasLimit F] [HasLimit G] (α : F ⟶ G) [IsIso α] : IsIso (limMap α) := ⟨limMap (inv α), by cat_disch , by cat_disch⟩ -@[reassoc (attr := simp)] +@[to_dual (attr := reassoc (attr := simp)) map_desc] theorem limit.lift_map {F G : J ⥤ C} [HasLimit F] [HasLimit G] (c : Cone F) (α : F ⟶ G) : limit.lift F c ≫ limMap α = limit.lift G ((Cone.postcompose α).obj c) := by ext rw [assoc, limMap_π, limit.lift_π_assoc, limit.lift_π] rfl -@[simp] +@[to_dual (attr := simp)] theorem limit.lift_cone {F : J ⥤ C} [HasLimit F] : limit.lift F (limit.cone F) = 𝟙 (limit F) := (limit.isLimit _).lift_self +-- TODO: `to_dual` doesn't yet know that it shouldn't translate the category on `Type _`. /-- The isomorphism (in `Type`) between morphisms from a specified object `W` to the limit object, and cones with cone point `W`. @@ -282,16 +346,18 @@ def limit.homIso' (F : J ⥤ C) [HasLimit F] (W : C) : { p : ∀ j, W ⟶ F.obj j // ∀ {j j' : J} (f : j ⟶ j'), p j ≫ F.map f = p j' } := (limit.isLimit F).homIso' W +@[to_dual] theorem limit.lift_extend {F : J ⥤ C} [HasLimit F] (c : Cone F) {X : C} (f : X ⟶ c.pt) : limit.lift F (c.extend f) = f ≫ limit.lift F c := by cat_disch -/-- If a functor `F` has a limit, so does any naturally isomorphic functor. --/ +/-- If a functor `F` has a limit, so does any naturally isomorphic functor. -/ +@[to_dual none] theorem hasLimit_of_iso {F G : J ⥤ C} [HasLimit F] (α : F ≅ G) : HasLimit G := HasLimit.mk { cone := (Cone.postcompose α.hom).obj (limit.cone F) isLimit := (IsLimit.postcomposeHomEquiv _ _).symm (limit.isLimit F) } +@[to_dual] theorem hasLimit_iff_of_iso {F G : J ⥤ C} (α : F ≅ G) : HasLimit F ↔ HasLimit G := ⟨fun _ ↦ hasLimit_of_iso α, fun _ ↦ hasLimit_of_iso α.symm⟩ @@ -306,6 +372,10 @@ theorem HasLimit.ofConesIso {J K : Type u₁} [Category.{v₁} J] [Category.{v /-- The limits of `F : J ⥤ C` and `G : J ⥤ C` are isomorphic, if the functors are naturally isomorphic. -/ +@[to_dual +/-- The colimits of `F : J ⥤ C` and `G : J ⥤ C` are isomorphic, +if the functors are naturally isomorphic. +-/] def HasLimit.isoOfNatIso {F G : J ⥤ C} [HasLimit F] [HasLimit G] (w : F ≅ G) : limit F ≅ limit G := IsLimit.conePointsIsoOfNatIso (limit.isLimit F) (limit.isLimit G) w @@ -619,203 +689,6 @@ end Limit section Colimit -/-- `ColimitCocone F` contains a cocone over `F` together with the information that it is a - colimit. -/ -structure ColimitCocone (F : J ⥤ C) where - /-- The cocone itself -/ - cocone : Cocone F - /-- The proof that it is the colimit cocone -/ - isColimit : IsColimit cocone - -/-- `HasColimit F` represents the mere existence of a colimit for `F`. -/ -class HasColimit (F : J ⥤ C) : Prop where mk' :: - /-- There exists a colimit for `F` -/ - exists_colimit : Nonempty (ColimitCocone F) - -theorem HasColimit.mk {F : J ⥤ C} (d : ColimitCocone F) : HasColimit F := - ⟨Nonempty.intro d⟩ - -/-- Use the axiom of choice to extract explicit `ColimitCocone F` from `HasColimit F`. -/ -def getColimitCocone (F : J ⥤ C) [HasColimit F] : ColimitCocone F := - Classical.choice <| HasColimit.exists_colimit - -variable (J C) - -/-- `C` has colimits of shape `J` if there exists a colimit for every functor `F : J ⥤ C`. -/ -class HasColimitsOfShape : Prop where - /-- All `F : J ⥤ C` have colimits for a fixed `J` -/ - has_colimit : ∀ F : J ⥤ C, HasColimit F := by infer_instance - -/-- `C` has all colimits of size `v₁ u₁` (`HasColimitsOfSize.{v₁ u₁} C`) -if it has colimits of every shape `J : Type u₁` with `[Category.{v₁} J]`. --/ --- After https://github.com/leanprover/lean4/pull/12286 and --- https://github.com/leanprover/lean4/pull/12423, the shape universes `v₁, u₁` would default --- to universe output parameters. See Note [universe output parameters and typeclass caching]. -@[univ_out_params, pp_with_univ] -class HasColimitsOfSize (C : Type u) [Category.{v} C] : Prop where - /-- All `F : J ⥤ C` have colimits for all small `J` -/ - has_colimits_of_shape : ∀ (J : Type u₁) [Category.{v₁} J], HasColimitsOfShape J C := by - infer_instance - -/-- `C` has all (small) colimits if it has colimits of every shape that is as big as its hom-sets. --/ -abbrev HasColimits (C : Type u) [Category.{v} C] : Prop := - HasColimitsOfSize.{v, v} C - -theorem HasColimits.hasColimitsOfShape {C : Type u} [Category.{v} C] [HasColimits C] (J : Type v) - [Category.{v} J] : HasColimitsOfShape J C := - HasColimitsOfSize.has_colimits_of_shape J - -variable {J C} - --- see Note [lower instance priority] -instance (priority := 100) hasColimitOfHasColimitsOfShape {J : Type u₁} [Category.{v₁} J] - [HasColimitsOfShape J C] (F : J ⥤ C) : HasColimit F := - HasColimitsOfShape.has_colimit F - --- see Note [lower instance priority] -instance (priority := 100) hasColimitsOfShapeOfHasColimitsOfSize {J : Type u₁} [Category.{v₁} J] - [HasColimitsOfSize.{v₁, u₁} C] : HasColimitsOfShape J C := - HasColimitsOfSize.has_colimits_of_shape J - --- Interface to the `HasColimit` class. -/-- An arbitrary choice of colimit cocone of a functor. -/ -def colimit.cocone (F : J ⥤ C) [HasColimit F] : Cocone F := - (getColimitCocone F).cocone - -/-- An arbitrary choice of colimit object of a functor. -/ -@[implicit_reducible] -def colimit (F : J ⥤ C) [HasColimit F] := - (colimit.cocone F).pt - -/-- The coprojection from a value of the functor to the colimit object. -/ -@[implicit_reducible] -def colimit.ι (F : J ⥤ C) [HasColimit F] (j : J) : F.obj j ⟶ colimit F := - (colimit.cocone F).ι.app j - -@[reassoc] -theorem colimit.eqToHom_comp_ι (F : J ⥤ C) [HasColimit F] {j j' : J} (hj : j = j') : - eqToHom (by subst hj; rfl) ≫ colimit.ι F j = colimit.ι F j' := by - subst hj - simp - -@[simp] -theorem colimit.cocone_ι {F : J ⥤ C} [HasColimit F] (j : J) : - (colimit.cocone F).ι.app j = colimit.ι _ j := - rfl - -@[simp] -theorem colimit.cocone_x {F : J ⥤ C} [HasColimit F] : (colimit.cocone F).pt = colimit F := - rfl - -@[reassoc (attr := simp)] -theorem colimit.w (F : J ⥤ C) [HasColimit F] {j j' : J} (f : j ⟶ j') : - F.map f ≫ colimit.ι F j' = colimit.ι F j := - (colimit.cocone F).w f - -/-- Evidence that the arbitrary choice of cocone is a colimit cocone. -/ -def colimit.isColimit (F : J ⥤ C) [HasColimit F] : IsColimit (colimit.cocone F) := - (getColimitCocone F).isColimit - -/-- The morphism from the colimit object to the cone point of any other cocone. -/ -def colimit.desc (F : J ⥤ C) [HasColimit F] (c : Cocone F) : colimit F ⟶ c.pt := - (colimit.isColimit F).desc c - -@[simp] -theorem colimit.isColimit_desc {F : J ⥤ C} [HasColimit F] (c : Cocone F) : - (colimit.isColimit F).desc c = colimit.desc F c := - rfl - -/-- We have lots of lemmas describing how to simplify `colimit.ι F j ≫ _`, -and combined with `colimit.ext` we rely on these lemmas for many calculations. - -However, since `Category.assoc` is a `@[simp]` lemma, often expressions are -right associated, and it's hard to apply these lemmas about `colimit.ι`. - -We thus use `reassoc` to define additional `@[simp]` lemmas, with an arbitrary extra morphism. -(see `Mathlib/Tactic/CategoryTheory/Reassoc.lean`) --/ -@[reassoc (attr := simp)] -theorem colimit.ι_desc {F : J ⥤ C} [HasColimit F] (c : Cocone F) (j : J) : - colimit.ι F j ≫ colimit.desc F c = c.ι.app j := - IsColimit.fac _ c j - -/-- Functoriality of colimits. - -Usually this morphism should be accessed through `colim.map`, -but may be needed separately when you have specified colimits for the source and target functors, -but not necessarily for all functors of shape `J`. --/ -def colimMap {F G : J ⥤ C} [HasColimit F] [HasColimit G] (α : F ⟶ G) : colimit F ⟶ colimit G := - IsColimit.map (colimit.isColimit F) _ α - -@[reassoc (attr := simp)] -theorem ι_colimMap {F G : J ⥤ C} [HasColimit F] [HasColimit G] (α : F ⟶ G) (j : J) : - colimit.ι F j ≫ colimMap α = α.app j ≫ colimit.ι G j := - colimit.ι_desc _ j - -/-- The cocone morphism from the arbitrary choice of colimit cocone to any cocone. -/ -def colimit.coconeMorphism {F : J ⥤ C} [HasColimit F] (c : Cocone F) : colimit.cocone F ⟶ c := - (colimit.isColimit F).descCoconeMorphism c - -@[simp] -theorem colimit.coconeMorphism_hom {F : J ⥤ C} [HasColimit F] (c : Cocone F) : - (colimit.coconeMorphism c).hom = colimit.desc F c := - rfl - -theorem colimit.ι_coconeMorphism {F : J ⥤ C} [HasColimit F] (c : Cocone F) (j : J) : - colimit.ι F j ≫ (colimit.coconeMorphism c).hom = c.ι.app j := by simp - -@[reassoc (attr := simp)] -theorem colimit.comp_coconePointUniqueUpToIso_hom {F : J ⥤ C} [HasColimit F] {c : Cocone F} - (hc : IsColimit c) (j : J) : - colimit.ι F j ≫ (IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) hc).hom = c.ι.app j := - IsColimit.comp_coconePointUniqueUpToIso_hom _ _ _ - -@[reassoc (attr := simp)] -theorem colimit.comp_coconePointUniqueUpToIso_inv {F : J ⥤ C} [HasColimit F] {c : Cocone F} - (hc : IsColimit c) (j : J) : - colimit.ι F j ≫ (IsColimit.coconePointUniqueUpToIso hc (colimit.isColimit _)).inv = c.ι.app j := - IsColimit.comp_coconePointUniqueUpToIso_inv _ _ _ - -theorem colimit.existsUnique {F : J ⥤ C} [HasColimit F] (t : Cocone F) : - ∃! d : colimit F ⟶ t.pt, ∀ j, colimit.ι F j ≫ d = t.ι.app j := - (colimit.isColimit F).existsUnique _ - -/-- -Given any other colimit cocone for `F`, the chosen `colimit F` is isomorphic to the cocone point. --/ -def colimit.isoColimitCocone {F : J ⥤ C} [HasColimit F] (t : ColimitCocone F) : - colimit F ≅ t.cocone.pt := - IsColimit.coconePointUniqueUpToIso (colimit.isColimit F) t.isColimit - -@[reassoc (attr := simp)] -theorem colimit.isoColimitCocone_ι_hom {F : J ⥤ C} [HasColimit F] (t : ColimitCocone F) (j : J) : - colimit.ι F j ≫ (colimit.isoColimitCocone t).hom = t.cocone.ι.app j := by - dsimp [colimit.isoColimitCocone, IsColimit.coconePointUniqueUpToIso] - simp - -@[reassoc (attr := simp)] -theorem colimit.isoColimitCocone_ι_inv {F : J ⥤ C} [HasColimit F] (t : ColimitCocone F) (j : J) : - t.cocone.ι.app j ≫ (colimit.isoColimitCocone t).inv = colimit.ι F j := by - dsimp [colimit.isoColimitCocone, IsColimit.coconePointUniqueUpToIso] - simp - -@[ext] -theorem colimit.hom_ext {F : J ⥤ C} [HasColimit F] {X : C} {f f' : colimit F ⟶ X} - (w : ∀ j, colimit.ι F j ≫ f = colimit.ι F j ≫ f') : f = f' := - (colimit.isColimit F).hom_ext w - -instance isIso_colimMap {F G : J ⥤ C} [HasColimit F] [HasColimit G] (α : F ⟶ G) [IsIso α] : - IsIso (colimMap α) := - ⟨colimMap (inv α), by cat_disch , by cat_disch⟩ - -@[simp] -theorem colimit.desc_cocone {F : J ⥤ C} [HasColimit F] : - colimit.desc F (colimit.cocone F) = 𝟙 (colimit F) := - (colimit.isColimit _).desc_self - /-- The isomorphism (in `Type`) between morphisms from the colimit object to a specified object `W`, and cocones with cone point `W`. @@ -839,34 +712,21 @@ def colimit.homIso' (F : J ⥤ C) [HasColimit F] (W : C) : { p : ∀ j, F.obj j ⟶ W // ∀ {j j'} (f : j ⟶ j'), F.map f ≫ p j' = p j } := (colimit.isColimit F).homIso' W -theorem colimit.desc_extend (F : J ⥤ C) [HasColimit F] (c : Cocone F) {X : C} (f : c.pt ⟶ X) : - colimit.desc F (c.extend f) = colimit.desc F c ≫ f := by ext; simp - -- This has the isomorphism pointing in the opposite direction than in `has_limit_of_iso`. -- This is intentional; it seems to help with elaboration. -/-- If `F` has a colimit, so does any naturally isomorphic functor. --/ +/-- If `F` has a colimit, so does any naturally isomorphic functor. -/ +@[to_dual none] theorem hasColimit_of_iso {F G : J ⥤ C} [HasColimit F] (α : G ≅ F) : HasColimit G := HasColimit.mk { cocone := (Cocone.precompose α.hom).obj (colimit.cocone F) isColimit := (IsColimit.precomposeHomEquiv _ _).symm (colimit.isColimit F) } -theorem hasColimit_iff_of_iso {F G : J ⥤ C} (α : F ≅ G) : HasColimit F ↔ HasColimit G := - ⟨fun _ ↦ hasColimit_of_iso α.symm, fun _ ↦ hasColimit_of_iso α⟩ - /-- If a functor `G` has the same collection of cocones as a functor `F` which has a colimit, then `G` also has a colimit. -/ theorem HasColimit.ofCoconesIso {K : Type u₁} [Category.{v₂} K] (F : J ⥤ C) (G : K ⥤ C) (h : F.cocones ≅ G.cocones) [HasColimit F] : HasColimit G := HasColimit.mk ⟨_, IsColimit.ofCorepresentableBy ((colimit.isColimit F).corepresentableBy.ofIso h)⟩ -/-- The colimits of `F : J ⥤ C` and `G : J ⥤ C` are isomorphic, -if the functors are naturally isomorphic. --/ -def HasColimit.isoOfNatIso {F G : J ⥤ C} [HasColimit F] [HasColimit G] (w : F ≅ G) : - colimit F ≅ colimit G := - IsColimit.coconePointsIsoOfNatIso (colimit.isColimit F) (colimit.isColimit G) w - @[reassoc (attr := simp)] theorem HasColimit.isoOfNatIso_ι_hom {F G : J ⥤ C} [HasColimit F] [HasColimit G] (w : F ≅ G) (j : J) : colimit.ι F j ≫ (HasColimit.isoOfNatIso w).hom = w.hom.app j ≫ colimit.ι G j := @@ -1066,12 +926,6 @@ theorem colimMap_eq : colimMap α = colim.map α := rfl @[reassoc] theorem colimit.ι_map (j : J) : colimit.ι F j ≫ colim.map α = α.app j ≫ colimit.ι G j := by simp -@[reassoc (attr := simp)] -theorem colimit.map_desc (c : Cocone G) : - colimMap α ≫ colimit.desc G c = colimit.desc F ((Cocone.precompose α).obj c) := by - ext j - simp [colimit.ι_desc, colimit.ι_desc] - theorem colimit.pre_map [HasColimitsOfShape K C] (E : K ⥤ J) : colimit.pre F E ≫ colim.map α = colim.map (whiskerLeft E α) ≫ colimit.pre G E := by ext diff --git a/Mathlib/CategoryTheory/Limits/IsLimit.lean b/Mathlib/CategoryTheory/Limits/IsLimit.lean index 74de4a1b949df8..2f6bb0153f8bfb 100644 --- a/Mathlib/CategoryTheory/Limits/IsLimit.lean +++ b/Mathlib/CategoryTheory/Limits/IsLimit.lean @@ -23,11 +23,6 @@ See also `CategoryTheory.Limits.HasLimits` which further builds: * `LimitCone F`, which consists of a choice of cone for `F` and the fact it is a limit cone, and * `HasLimit F`, asserting the mere existence of some limit cone for `F`. -## Implementation -At present we simply say everything twice, in order to handle both limits and colimits. -It would be highly desirable to have some automation support, -e.g. a `@[dualize]` attribute that behaves similarly to `@[to_additive]`. - ## References * [Stacks: Limits and colimits](https://stacks.math.columbia.edu/tag/002D) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean index 3d27e96c8e7bf8..2336380eeb615f 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean @@ -618,7 +618,7 @@ lemma π_reflexiveCoequalizerIsoCoequalizer_inv : coequalizer.π _ _ ≫ (reflexiveCoequalizerIsoCoequalizer F).inv = colimit.ι F _ := by rw [reflexiveCoequalizerIsoCoequalizer] simp only [colimit.comp_coconePointUniqueUpToIso_inv, - Cofork.ofπ_ι_app, colimit.cocone_ι] + Cofork.ofπ_ι_app, ReflexiveCofork.π, colimit.cocone_ι] end diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index 44bca9494aada3..8f8aa6e95074cd 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -211,6 +211,8 @@ def nameDict : Std.HashMap String (List String) := .ofList [ ("cofan", ["Fan"]), ("limit", ["Colimit"]), ("colimit", ["Limit"]), + ("lim", ["Colim"]), + ("colim", ["Lim"]), ("limits", ["Colimits"]), ("colimits", ["Limits"]), ("product", ["Coproduct"]), From 375d54da29680b0a33d5b2f3281b11009e079081 Mon Sep 17 00:00:00 2001 From: Dennj Date: Sun, 2 Aug 2026 10:21:36 +0000 Subject: [PATCH 1126/1300] =?UTF-8?q?feat(MeasureTheory):=20generalize=20r?= =?UTF-8?q?pow=C2=B7exp=20and=20scalar-multiplication=20integrability=20le?= =?UTF-8?q?mmas=20(#40587)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalization PR: - IntervalIntegrable.{smul_continuousOn, continuousOn_smul}, IntegrableOn.{continuousOn_smul, smul_continuousOn} (+ _of_subset forms), and the LocallyIntegrableOn analogues now need only IsBoundedSMul 𝕜 E instead of NormSMulClass 𝕜 E. (Every NormSMulClass is an IsBoundedSMul, so all existing uses still apply; over a NormedDivisionRing they coincide.) This works because these reduce to Integrable.bdd_smul/bdd_mul, which only need IsBoundedSMul, using IntegrableOn f s μ = Integrable f (μ.restrict s). - integrableOn_rpow_mul_exp_neg_rpow / …_mul_rpow are generalized from 1 ≤ p to 0 < p (via u = xᵖ), matching the 0 < p of integral_rpow_mul_exp_neg_rpow. --- .../SpecialFunctions/Gamma/Basic.lean | 10 ++--- .../Gaussian/GaussianIntegral.lean | 41 ++++++------------- .../Function/LocallyIntegrable.lean | 6 +-- .../Integral/IntervalIntegral/Basic.lean | 2 +- 4 files changed, 21 insertions(+), 38 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index a57539a4f3e2de..84f88af50e4fc2 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -68,11 +68,11 @@ theorem GammaIntegral_convergent {s : ℝ} (h : 0 < s) : rw [← Ioc_union_Ioi_eq_Ioi (@zero_le_one ℝ _ _ _ _), integrableOn_union] constructor · rw [← integrableOn_Icc_iff_integrableOn_Ioc] - refine IntegrableOn.continuousOn_mul continuousOn_id.neg.rexp ?_ isCompact_Icc - refine (intervalIntegrable_iff_integrableOn_Icc_of_le zero_le_one).mp ?_ - exact intervalIntegrable_rpow' (by linarith) - · refine integrable_of_isBigO_exp_neg one_half_pos ?_ (Gamma_integrand_isLittleO _).isBigO - exact continuousOn_id.neg.rexp.mul (continuousOn_id.rpow_const (by grind)) + exact (intervalIntegrable_iff_integrableOn_Icc_of_le zero_le_one).mp + ((intervalIntegrable_rpow' (by linarith)).continuousOn_mul continuousOn_id.neg.rexp) + · exact integrable_of_isBigO_exp_neg one_half_pos + (continuousOn_id.neg.rexp.mul (continuousOn_id.rpow_const (by grind))) + (Gamma_integrand_isLittleO _).isBigO end Real diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean index d5530157c7cded..13927ae74e7ce6 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean @@ -60,35 +60,18 @@ theorem rpow_mul_exp_neg_mul_sq_isLittleO_exp_neg {b : ℝ} (hb : 0 < b) (s : simp_rw [← rpow_two] exact rpow_mul_exp_neg_mul_rpow_isLittleO_exp_neg s one_lt_two hb -theorem integrableOn_rpow_mul_exp_neg_rpow {p s : ℝ} (hs : -1 < s) (hp : 1 ≤ p) : +theorem integrableOn_rpow_mul_exp_neg_rpow {p s : ℝ} (hs : -1 < s) (hp : 0 < p) : IntegrableOn (fun x : ℝ => x ^ s * exp (- x ^ p)) (Ioi 0) := by - obtain hp | hp := le_iff_lt_or_eq.mp hp - · have h_exp : ∀ x, ContinuousAt (fun x => exp (-x)) x := fun x => continuousAt_neg.rexp - rw [← Ioc_union_Ioi_eq_Ioi zero_le_one, integrableOn_union] - constructor - · rw [← integrableOn_Icc_iff_integrableOn_Ioc] - refine IntegrableOn.mul_continuousOn ?_ ?_ isCompact_Icc - · refine (intervalIntegrable_iff_integrableOn_Icc_of_le zero_le_one).mp ?_ - exact intervalIntegral.intervalIntegrable_rpow' hs - · intro x _ - rw [← Function.comp_def (fun x => exp (-x)) (· ^ p)] - refine ContinuousAt.comp_continuousWithinAt (h_exp _) ?_ - exact continuousWithinAt_id.rpow_const (Or.inr (le_of_lt (lt_trans zero_lt_one hp))) - · have h_rpow : ∀ (x r : ℝ), x ∈ Ici 1 → ContinuousWithinAt (fun x => x ^ r) (Ici 1) x := by - intro _ _ hx - refine continuousWithinAt_id.rpow_const (Or.inl ?_) - exact ne_of_gt (lt_of_lt_of_le zero_lt_one hx) - refine integrable_of_isBigO_exp_neg (by simp : (0 : ℝ) < 1 / 2) - (ContinuousOn.mul (fun x hx => h_rpow x s hx) (fun x hx => ?_)) (IsLittleO.isBigO ?_) - · rw [← Function.comp_def (fun x => exp (-x)) (· ^ p)] - exact ContinuousAt.comp_continuousWithinAt (h_exp _) (h_rpow x p hx) - · convert! rpow_mul_exp_neg_mul_rpow_isLittleO_exp_neg s hp (by simp : (0 : ℝ) < 1) using 3 - rw [neg_mul, one_mul] - · simp_rw [← hp, Real.rpow_one] - convert! Real.GammaIntegral_convergent (by linarith : 0 < s + 1) using 2 - rw [add_sub_cancel_right, mul_comm] - -theorem integrableOn_rpow_mul_exp_neg_mul_rpow {p s b : ℝ} (hs : -1 < s) (hp : 1 ≤ p) (hb : 0 < b) : + -- Substitute `u = x ^ p`, reducing to convergence of the `Γ`-integral at `(s + 1) / p`. + have ht : (0 : ℝ) < (s + 1) / p := div_pos (by linarith) hp + refine ((integrableOn_Ioi_comp_rpow_iff' _ hp.ne').mpr + (GammaIntegral_convergent ht)).congr_fun (fun x hx => ?_) measurableSet_Ioi + simp only [smul_eq_mul] + rw [mul_comm (exp (-x ^ p)), ← mul_assoc, ← rpow_mul hx.le, ← rpow_add hx] + field_simp + ring_nf + +theorem integrableOn_rpow_mul_exp_neg_mul_rpow {p s b : ℝ} (hs : -1 < s) (hp : 0 < p) (hb : 0 < b) : IntegrableOn (fun x : ℝ => x ^ s * exp (- b * x ^ p)) (Ioi 0) := by have hib : 0 < b ^ (-p⁻¹) := rpow_pos_of_pos hb _ suffices IntegrableOn (fun x ↦ (b ^ (-p⁻¹)) ^ s * (x ^ s * exp (-x ^ p))) (Ioi 0) by @@ -109,7 +92,7 @@ theorem integrableOn_rpow_mul_exp_neg_mul_rpow {p s b : ℝ} (hs : -1 < s) (hp : theorem integrableOn_rpow_mul_exp_neg_mul_sq {b : ℝ} (hb : 0 < b) {s : ℝ} (hs : -1 < s) : IntegrableOn (fun x : ℝ => x ^ s * exp (-b * x ^ 2)) (Ioi 0) := by simp_rw [← rpow_two] - exact integrableOn_rpow_mul_exp_neg_mul_rpow hs one_le_two hb + exact integrableOn_rpow_mul_exp_neg_mul_rpow hs two_pos hb theorem integrable_rpow_mul_exp_neg_mul_sq {b : ℝ} (hb : 0 < b) {s : ℝ} (hs : -1 < s) : Integrable fun x : ℝ => x ^ s * exp (-b * x ^ 2) := by diff --git a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean index ca5624ada9cfd6..dc00e515b31d96 100644 --- a/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/LocallyIntegrable.lean @@ -749,7 +749,7 @@ end Mul section SMul -variable {𝕜 : Type*} [NormedRing 𝕜] [Module 𝕜 E] [NormSMulClass 𝕜 E] +variable {𝕜 : Type*} [NormedRing 𝕜] [Module 𝕜 E] [IsBoundedSMul 𝕜 E] theorem IntegrableOn.continuousOn_smul_of_subset [SecondCountableTopologyEither X 𝕜] {f : X → 𝕜} (hf : ContinuousOn f K) {g : X → E} (hg : IntegrableOn g A μ) @@ -796,14 +796,14 @@ theorem mul_continuousOn [LocallyCompactSpace X] [T2Space X] [NormedRing R] exact fun k hk_sub hk_c => (hf k hk_sub hk_c).mul_continuousOn (hg.mono hk_sub) hk_c theorem continuousOn_smul [LocallyCompactSpace X] [T2Space X] {𝕜 : Type*} [NormedRing 𝕜] - [SecondCountableTopologyEither X 𝕜] [Module 𝕜 E] [NormSMulClass 𝕜 E] {f : X → E} {g : X → 𝕜} + [SecondCountableTopologyEither X 𝕜] [Module 𝕜 E] [IsBoundedSMul 𝕜 E] {f : X → E} {g : X → 𝕜} {s : Set X} (hs : IsLocallyClosed s) (hf : LocallyIntegrableOn f s μ) (hg : ContinuousOn g s) : LocallyIntegrableOn (fun x => g x • f x) s μ := by rw [MeasureTheory.locallyIntegrableOn_iff hs] at hf ⊢ exact fun k hk_sub hk_c => (hf k hk_sub hk_c).continuousOn_smul (hg.mono hk_sub) hk_c theorem smul_continuousOn [LocallyCompactSpace X] [T2Space X] {𝕜 : Type*} [NormedRing 𝕜] - [SecondCountableTopologyEither X E] [Module 𝕜 E] [NormSMulClass 𝕜 E] {f : X → 𝕜} {g : X → E} + [SecondCountableTopologyEither X E] [Module 𝕜 E] [IsBoundedSMul 𝕜 E] {f : X → 𝕜} {g : X → E} {s : Set X} (hs : IsLocallyClosed s) (hf : LocallyIntegrableOn f s μ) (hg : ContinuousOn g s) : LocallyIntegrableOn (fun x => f x • g x) s μ := by rw [MeasureTheory.locallyIntegrableOn_iff hs] at hf ⊢ diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean index 89cf34cb5387b2..4092210205f534 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/Basic.lean @@ -371,7 +371,7 @@ end Mul section SMul -variable {f : ℝ → 𝕜} {g : ℝ → E} [NormedRing 𝕜] [Module 𝕜 E] [NormSMulClass 𝕜 E] +variable {f : ℝ → 𝕜} {g : ℝ → E} [NormedRing 𝕜] [Module 𝕜 E] [IsBoundedSMul 𝕜 E] theorem smul_continuousOn (hf : IntervalIntegrable f μ a b) (hg : ContinuousOn g [[a, b]]) : IntervalIntegrable (fun x => f x • g x) μ a b := by From 68302e4c4fd7938be53021dd6fa92f4b9b44fabb Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Sun, 2 Aug 2026 21:32:01 +0000 Subject: [PATCH 1127/1300] feat(Combinatorics/SimpleGraph/Acyclic): a nontrivial finite tree has at least two leaves (#41669) Generalizes [`IsTree.exists_vert_degree_one_of_nontrivial`](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Combinatorics/SimpleGraph/Acyclic.html#SimpleGraph.IsTree.exists_vert_degree_one_of_nontrivial). Co-authored-by: robo7179 --- .../Combinatorics/SimpleGraph/Acyclic.lean | 23 +++++++++++++++---- Mathlib/Combinatorics/SimpleGraph/Paths.lean | 2 +- .../Combinatorics/SimpleGraph/Walk/Basic.lean | 3 ++- .../SimpleGraph/Walk/Counting.lean | 2 +- .../SimpleGraph/Walk/Traversal.lean | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean index 1cab39f71980da..1f92dae32ab4a5 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Acyclic.lean @@ -510,10 +510,25 @@ lemma IsTree.minDegree_eq_one_of_nontrivial (h : G.IsTree) [Fintype V] [Nontrivi /-- A nontrivial tree has a vertex of degree one. -/ lemma IsTree.exists_vert_degree_one_of_nontrivial [Fintype V] [Nontrivial V] [DecidableRel G.Adj] (h : G.IsTree) : ∃ v, G.degree v = 1 := by - obtain ⟨v, hv⟩ := G.exists_minimal_degree_vertex - use v - rw [← hv] - exact h.minDegree_eq_one_of_nontrivial + grind [G.exists_minimal_degree_vertex, minDegree_eq_one_of_nontrivial] + +/-- A nontrivial finite tree has at least two leaves. -/ +theorem IsTree.exists_ne_and_degree_eq_one [Nontrivial V] [Finite G.edgeSet] [G.LocallyFinite] + (h : G.IsTree) : ∃ u v, u ≠ v ∧ G.degree u = 1 ∧ G.degree v = 1 := by + have ⟨u, v, p, hp, hmax⟩ := exists_isPath_forall_isPath_length_le_length G + have ⟨u', v', hne⟩ := exists_pair_ne V + have ⟨p', hp'⟩ := h.connected.exists_isPath u' v' + have hnil : ¬p.Nil := by grind + refine ⟨u, v, hp.nil_iff_eq.not.mp hnil, ?_, ?_⟩ <;> + rw [degree_eq_one_iff_existsUnique_adj] + · refine ⟨_, p.adj_snd hnil, fun w hadj ↦ ?_⟩ + apply h.isAcyclic.eq_snd_of_adj_start hp hadj + have : ¬(p.cons hadj.symm).IsPath := by grind [length_cons] + grind [hp.cons] + · refine ⟨_, p.adj_penultimate hnil |>.symm, fun w hadj ↦ ?_⟩ + apply h.isAcyclic.eq_penultimate_of_adj_end hp hadj + have : ¬(p.concat hadj).IsPath := by grind [length_concat] + grind [hp.concat] /-- The graph resulting from removing a vertex of degree one from a connected graph is connected. -/ lemma Connected.induce_compl_singleton_of_degree_eq_one (hconn : G.Connected) {v : V} diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 3e6c2fba4cecab..72c20270bc7c13 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -778,7 +778,7 @@ lemma IsPath.isCycle_append {p : G.Walk u v} {q : G.Walk v u} (hp : p.IsPath) (h rw [isCycle_def, isTrail_append] refine ⟨⟨hp.isTrail, hq.isTrail, ?_⟩, ?_, ?_⟩ · grind [IsPath.disjoint_edges_of_disjoint_support, List.Disjoint.symm] - · grind [nil_append_iff, length_eq_zero_iff] + · grind [nil_append_iff] · rw [tail_support_append, List.nodup_append'] exact ⟨hp.support_nodup.tail, hq.support_nodup.tail, h⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean index 60a1eac384d4d0..5c3c979940fe1d 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Basic.lean @@ -379,6 +379,7 @@ instance (p : G.Walk v w) : Decidable p.Nil := | nil => isTrue .nil | cons _ _ => isFalse nofun +@[grind .] protected lemma Nil.eq {p : G.Walk v w} : p.Nil → v = w | .nil => rfl lemma not_nil_of_ne {p : G.Walk v w} : v ≠ w → ¬ p.Nil := mt Nil.eq @@ -394,7 +395,7 @@ lemma darts_eq_nil {p : G.Walk v w} : p.darts = [] ↔ p.Nil := by lemma edges_eq_nil {p : G.Walk v w} : p.edges = [] ↔ p.Nil := by cases p <;> simp -@[simp] +@[simp, grind .] theorem length_eq_zero_iff {p : G.Walk u v} : p.length = 0 ↔ p.Nil := by cases p <;> simp diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean index 7500d2d91af7e0..f26704384f277c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Counting.lean @@ -100,7 +100,7 @@ def finsetWalkLength (n : ℕ) (u v : V) : Finset (G.Walk u v) := theorem coe_finsetWalkLength_eq (n : ℕ) (u v : V) : (G.finsetWalkLength n u v : Set (G.Walk u v)) = {p : G.Walk u v | p.length = n} := by induction n generalizing u v with - | zero => grind [finsetWalkLength, Walk.length_eq_zero_iff, Walk.eq_nil_iff_nil, Walk.Nil.eq] + | zero => grind [finsetWalkLength, Walk.eq_nil_iff_nil] | succ n ih => simp only [finsetWalkLength, Walk.setOfPred_length_eq_add_one, Finset.coe_biUnion, Finset.mem_coe, Finset.mem_univ, Set.iUnion_true, Finset.coe_map, Set.iUnion_coe_set] diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean index 1580d0c9dca043..bbc80bf95952c8 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Traversal.lean @@ -187,7 +187,7 @@ lemma penultimate_cons_of_not_nil (h : G.Adj u v) (p : G.Walk v w) (hp : ¬ p.Ni @[simp] lemma adj_penultimate {p : G.Walk v w} (hp : ¬ p.Nil) : G.Adj p.penultimate w := by - grind [getVert_length, length_eq_zero_iff, adj_getVert_succ] + grind [getVert_length, adj_getVert_succ] lemma penultimate_mem_dropLast_support {p : G.Walk u v} (h : ¬p.Nil) : p.penultimate ∈ p.support.dropLast := by From 9c0c555bde5a8277cd36dc4dc6dfe2a5a77a2b11 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Mon, 3 Aug 2026 00:07:34 +0000 Subject: [PATCH 1128/1300] feat(NumberTheory): use `IsApply` for `ModularForm` etc (#41561) We use `IsApply` classes for `SlashInvariantForm`, `ModularForm` and `CuspForm` at the same time to avoid temporary name clashes and since they are not used as widely as `LinearMap` and `ContinuousLinearMap` for example. --- Mathlib/NumberTheory/ModularForms/Basic.lean | 192 ++++++++---------- .../ModularForms/CuspFormSubmodule.lean | 7 +- .../ModularForms/LevelOne/Basic.lean | 2 +- .../LevelOne/DimensionFormula.lean | 4 +- .../ModularForms/LevelOne/GradedRing.lean | 2 +- .../NumberTheory/ModularForms/NormTrace.lean | 4 +- .../ModularForms/SlashInvariantForms.lean | 81 ++++---- 7 files changed, 124 insertions(+), 168 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/Basic.lean b/Mathlib/NumberTheory/ModularForms/Basic.lean index 021cce87507a20..f0088951dab59e 100644 --- a/Mathlib/NumberTheory/ModularForms/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/Basic.lean @@ -200,32 +200,26 @@ instance add : Add (ModularForm Γ k) where add f g := holo' := f.holo'.add g.holo' bdd_at_cusps' hc := by simpa using (f.bdd_at_cusps' hc).add (g.bdd_at_cusps' hc) } -@[simp] -theorem coe_add (f g : ModularForm Γ k) : ⇑(f + g) = f + g := - rfl +instance : IsAddApply (ModularForm Γ k) ℍ ℂ where + add_apply _ _ _ := rfl -@[simp] -theorem add_apply (f g : ModularForm Γ k) (z : ℍ) : (f + g) z = f z + g z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_add := FunLike.coe_add + +@[deprecated (since := "2026-07-10")] protected alias add_apply := add_apply instance instZero : Zero (ModularForm Γ k) := ⟨ { toSlashInvariantForm := 0 holo' := fun _ => mdifferentiableAt_const - bdd_at_cusps' hc g hg := by - simp only [SlashInvariantForm.toFun_eq_coe, coe_zero, SlashAction.zero_slash] - exact zero_form_isBoundedAtImInfty } ⟩ + bdd_at_cusps' hc g hg := by simpa using zero_form_isBoundedAtImInfty } ⟩ -@[simp] -theorem coe_zero : ⇑(0 : ModularForm Γ k) = (0 : ℍ → ℂ) := - rfl +instance : IsZeroApply (ModularForm Γ k) ℍ ℂ where + zero_apply _ := rfl -@[simp] -theorem zero_apply (z : ℍ) : (0 : ModularForm Γ k) z = 0 := - rfl +@[deprecated (since := "2026-07-10")] alias coe_zero := FunLike.coe_zero + +@[deprecated (since := "2026-07-10")] protected alias zero_apply := zero_apply -@[simp] lemma coe_eq_zero_iff (f : ModularForm Γ k) : - (f : ℍ → ℂ) = 0 ↔ f = 0 := by - rw [← coe_zero, DFunLike.coe_fn_eq] +@[deprecated (since := "2026-07-10")] alias coe_eq_zero_iff := FunLike.coe_zero_iff /-- If `-1 ∈ Γ` and `k` is odd, then every modular form of weight `k` for `Γ` is zero. -/ lemma eq_zero_of_neg_one_mem [Γ.HasDetOne] (h_neg_one : -1 ∈ Γ) (hk : Odd k) @@ -248,18 +242,17 @@ instance instSMulℝ : SMul α (ModularForm Γ k) where smul c f := { toSlashInvariantForm := c • f.1 holo' := by simpa using f.holo'.const_smul (c • (1 : ℂ)) - bdd_at_cusps' := fun hc g hg ↦ by + bdd_at_cusps' hc g hg := by simpa only [IsBoundedAtImInfty, Filter.BoundedAtFilter, SlashInvariantForm.toFun_eq_coe, - SlashInvariantForm.coe_smulℝ, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] + FunLike.coe_smul, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] using (f.bdd_at_cusps' hc g hg).const_smul_left _ } -@[simp] -theorem coe_smul (f : ModularForm Γ k) (n : α) : ⇑(n • f) = n • ⇑f := - rfl +instance instIsSMulApplyℝ : IsSMulApply α (ModularForm Γ k) ℍ ℂ where + smul_apply _ _ _ := rfl -@[simp] -theorem smul_apply (f : ModularForm Γ k) (n : α) (z : ℍ) : (n • f) z = n • f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias smul_apply := smul_apply end @@ -271,18 +264,17 @@ instance instSMulℂ : SMul α (ModularForm Γ k) where smul c f := { toSlashInvariantForm := c • f.1 holo' := by simpa using f.holo'.const_smul (c • (1 : ℂ)) - bdd_at_cusps' := fun hc g hg ↦ by + bdd_at_cusps' hc g hg := by simp_rw [IsBoundedAtImInfty, Filter.BoundedAtFilter, SlashInvariantForm.toFun_eq_coe, - SlashInvariantForm.coe_smul, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] + FunLike.coe_smul, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] exact (f.bdd_at_cusps' hc g hg).const_smul_left (σ g (c • (1 : ℂ))) } -@[simp] -theorem IsGLPos.coe_smul (f : ModularForm Γ k) (n : α) : ⇑(n • f) = n • ⇑f := - rfl +instance instIsSMulApplyℂ : IsSMulApply α (ModularForm Γ k) ℍ ℂ where + smul_apply _ _ _ := rfl -@[simp] -theorem IsGLPos.smul_apply (f : ModularForm Γ k) (n : α) (z : ℍ) : (n • f) z = n • f z := - rfl +@[deprecated (since := "2026-07-10")] alias IsGLPos.coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias IsGLPos.smul_apply := smul_apply end @@ -290,42 +282,32 @@ instance instNeg : Neg (ModularForm Γ k) := ⟨fun f => { toSlashInvariantForm := -f.1 holo' := f.holo'.neg - bdd_at_cusps' := fun hc g hg => by simpa using! (f.bdd_at_cusps' hc g hg).neg }⟩ + bdd_at_cusps' hc g hg := by simpa using! (f.bdd_at_cusps' hc g hg).neg }⟩ -@[simp] -theorem coe_neg (f : ModularForm Γ k) : ⇑(-f) = -f := - rfl +instance : IsNegApply (ModularForm Γ k) ℍ ℂ where + neg_apply _ _ := rfl -@[simp] -theorem neg_apply (f : ModularForm Γ k) (z : ℍ) : (-f) z = -f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_neg := FunLike.coe_neg + +@[deprecated (since := "2026-07-10")] protected alias neg_apply := neg_apply instance instSub : Sub (ModularForm Γ k) := ⟨fun f g => f + -g⟩ -@[simp] -theorem coe_sub (f g : ModularForm Γ k) : ⇑(f - g) = f - g := - rfl +instance : IsSubApply (ModularForm Γ k) ℍ ℂ where + sub_apply _ _ _ := rfl -@[simp] -theorem sub_apply (f g : ModularForm Γ k) (z : ℍ) : (f - g) z = f z - g z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_sub := FunLike.coe_sub + +@[deprecated (since := "2026-07-10")] protected alias sub_apply := sub_apply -instance : AddCommGroup (ModularForm Γ k) := - DFunLike.coe_injective.addCommGroup _ rfl coe_add coe_neg coe_sub coe_smul coe_smul +instance : AddCommGroup (ModularForm Γ k) := fast_instance% FunLike.addCommGroup -/-- Additive coercion from `ModularForm` to `ℍ → ℂ`. -/ -@[simps] -def coeHom : ModularForm Γ k →+ ℍ → ℂ where - toFun f := f - map_zero' := coe_zero - map_add' _ _ := rfl +@[deprecated (since := "2026-07-10")] alias coeHom := FunLike.coeMonoidHom -instance : Module ℝ (ModularForm Γ k) := - Function.Injective.module ℝ coeHom DFunLike.coe_injective fun _ _ => rfl +instance : Module ℝ (ModularForm Γ k) := fast_instance% FunLike.module -instance [Γ.HasDetOne] : Module ℂ (ModularForm Γ k) := - Function.Injective.module ℂ coeHom DFunLike.coe_injective fun _ _ => rfl +instance [Γ.HasDetOne] : Module ℂ (ModularForm Γ k) := fast_instance% FunLike.module instance : Inhabited (ModularForm Γ k) := ⟨0⟩ @@ -401,28 +383,26 @@ instance hasAdd : Add (CuspForm Γ k) := ⟨fun f g => { toSlashInvariantForm := f + g holo' := f.holo'.add g.holo' - zero_at_cusps' := fun A => by simpa using (f.zero_at_cusps' A).add (g.zero_at_cusps' A) }⟩ + zero_at_cusps' A := by simpa using (f.zero_at_cusps' A).add (g.zero_at_cusps' A) }⟩ -@[simp] -theorem coe_add (f g : CuspForm Γ k) : ⇑(f + g) = f + g := - rfl +instance : IsAddApply (CuspForm Γ k) ℍ ℂ where + add_apply _ _ _ := rfl -@[simp] -theorem add_apply (f g : CuspForm Γ k) (z : ℍ) : (f + g) z = f z + g z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_add := FunLike.coe_add + +@[deprecated (since := "2026-07-10")] protected alias add_apply := add_apply instance instZero : Zero (CuspForm Γ k) := ⟨ { toSlashInvariantForm := 0 holo' := fun _ => mdifferentiableAt_const zero_at_cusps' hc g hg := by simpa using! Filter.zero_zeroAtFilter _ } ⟩ -@[simp] -theorem coe_zero : ⇑(0 : CuspForm Γ k) = (0 : ℍ → ℂ) := - rfl +instance : IsZeroApply (CuspForm Γ k) ℍ ℂ where + zero_apply _ := rfl -@[simp] -theorem zero_apply (z : ℍ) : (0 : CuspForm Γ k) z = 0 := - rfl +@[deprecated (since := "2026-07-10")] alias coe_zero := FunLike.coe_zero + +@[deprecated (since := "2026-07-10")] protected alias zero_apply := zero_apply section -- scalar multiplication by real types (no assumption on `Γ`) @@ -437,16 +417,15 @@ instance instSMul : SMul α (CuspForm Γ k) where smul c f := holo' := by simpa using f.holo'.const_smul (c • (1 : ℂ)) zero_at_cusps' hc g hg := by simp_rw [IsZeroAtImInfty, Filter.ZeroAtFilter, SlashInvariantForm.toFun_eq_coe, - SlashInvariantForm.coe_smulℝ, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] + FunLike.coe_smul, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] exact (f.zero_at_cusps' hc g hg).smul _ } -@[simp] -theorem coe_smul (f : CuspForm Γ k) (n : α) : ⇑(n • f) = n • ⇑f := - rfl +instance instSMulApply : IsSMulApply α (CuspForm Γ k) ℍ ℂ where + smul_apply _ _ _ := rfl -@[simp] -theorem smul_apply (f : CuspForm Γ k) (n : α) {z : ℍ} : (n • f) z = n • f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias smul_apply := smul_apply end @@ -460,17 +439,16 @@ instance IsGLPos.instSMul : SMul α (CuspForm Γ k) where smul c f := holo' := by simpa using f.holo'.const_smul (c • (1 : ℂ)) zero_at_cusps' hc g hg := by simp_rw [IsZeroAtImInfty, Filter.ZeroAtFilter, SlashInvariantForm.toFun_eq_coe, - SlashInvariantForm.coe_smul, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, + FunLike.coe_smul, toSlashInvariantForm_coe, ← smul_one_smul ℂ c ⇑f, smul_slash] exact (f.zero_at_cusps' hc g hg).smul _ } -@[simp] -theorem IsGLPos.coe_smul (f : CuspForm Γ k) (n : α) : ⇑(n • f) = n • ⇑f := - rfl +instance IsGLPos.instSMulApply : IsSMulApply α (CuspForm Γ k) ℍ ℂ where + smul_apply _ _ _ := rfl -@[simp] -theorem IsGLPos.smul_apply (f : CuspForm Γ k) (n : α) {z : ℍ} : (n • f) z = n • f z := - rfl +@[deprecated (since := "2026-07-10")] alias IsGLPos.coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias IsGLPos.smul_apply := smul_apply end @@ -480,40 +458,32 @@ instance instNeg : Neg (CuspForm Γ k) := holo' := f.holo'.neg zero_at_cusps' hc g hg := by simpa using! (f.zero_at_cusps' hc g hg).neg }⟩ -@[simp] -theorem coe_neg (f : CuspForm Γ k) : ⇑(-f) = -f := - rfl +instance : IsNegApply (CuspForm Γ k) ℍ ℂ where + neg_apply _ _ := rfl -@[simp] -theorem neg_apply (f : CuspForm Γ k) (z : ℍ) : (-f) z = -f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_neg := FunLike.coe_neg + +@[deprecated (since := "2026-07-10")] protected alias neg_apply := neg_apply instance instSub : Sub (CuspForm Γ k) := ⟨fun f g => f + -g⟩ -@[simp] -theorem coe_sub (f g : CuspForm Γ k) : ⇑(f - g) = f - g := - rfl +instance : IsSubApply (CuspForm Γ k) ℍ ℂ where + sub_apply _ _ _ := rfl -@[simp] -theorem sub_apply (f g : CuspForm Γ k) (z : ℍ) : (f - g) z = f z - g z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_sub := FunLike.coe_sub + +@[deprecated (since := "2026-07-10")] protected alias sub_apply := sub_apply + +instance : AddCommGroup (CuspForm Γ k) := fast_instance% FunLike.addCommGroup -instance : AddCommGroup (CuspForm Γ k) := - DFunLike.coe_injective.addCommGroup _ rfl coe_add coe_neg coe_sub coe_smul coe_smul +@[deprecated (since := "2026-07-10")] alias coeHom := FunLike.coeMonoidHom -/-- Additive coercion from `CuspForm` to `ℍ → ℂ`. -/ -@[simps] -def coeHom : CuspForm Γ k →+ ℍ → ℂ where - toFun f := f - map_zero' := CuspForm.coe_zero - map_add' _ _ := rfl +@[deprecated (since := "2026-07-10")] alias coeHom_apply := FunLike.coeMonoidHom_apply -instance : Module ℝ (CuspForm Γ k) := - Function.Injective.module ℝ coeHom DFunLike.coe_injective fun _ _ => rfl +instance : Module ℝ (CuspForm Γ k) := fast_instance% FunLike.module -instance [Γ.HasDetOne] : Module ℂ (CuspForm Γ k) := - Function.Injective.module ℂ coeHom DFunLike.coe_injective fun _ _ => rfl +instance [Γ.HasDetOne] : Module ℂ (CuspForm Γ k) := fast_instance% FunLike.module instance : Inhabited (CuspForm Γ k) := ⟨0⟩ @@ -566,7 +536,7 @@ theorem mcast_apply {a b : ℤ} {Γ Γ' : Subgroup (GL (Fin 2) ℝ)} (h : a = b) @[simp] lemma mcast_eq_zero_iff {a b : ℤ} {Γ Γ' : Subgroup (GL (Fin 2) ℝ)} (h : a = b) (hΓ : Γ' = Γ) (f : ModularForm Γ a) : mcast h f hΓ = 0 ↔ f = 0 := by - simp [← coe_eq_zero_iff, ← coe_eq_zero_iff (f := f)] + simp [← FunLike.coe_zero_iff] @[ext (iff := false)] theorem gradedMonoid_eq_of_cast {Γ : Subgroup (GL (Fin 2) ℝ)} {a b : GradedMonoid (ModularForm Γ)} diff --git a/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean b/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean index 321e1a927c087e..16557bc7bb67a1 100644 --- a/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean +++ b/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean @@ -146,10 +146,9 @@ gives a cusp form. -/ lemma sub_smul_isCuspForm (f g : ModularForm 𝒮ℒ k) (hg : (qExpansion 1 g).coeff 0 = 1) : ModularForm.IsCuspForm (f - (qExpansion 1 f).coeff 0 • g) := by - rw [isCuspForm_iff_coeffZero_eq_zero, ModularForm.coe_sub, - ModularForm.qExpansion_sub one_pos one_mem_strictPeriods_SL, IsGLPos.coe_smul, - ModularForm.qExpansion_smul one_pos one_mem_strictPeriods_SL, - map_sub, PowerSeries.coeff_smul] + rw [isCuspForm_iff_coeffZero_eq_zero, FunLike.coe_sub, + ModularForm.qExpansion_sub one_pos one_mem_strictPeriods_SL, FunLike.coe_smul, + ModularForm.qExpansion_smul one_pos one_mem_strictPeriods_SL, map_sub, PowerSeries.coeff_smul] simp [hg] end SL2Z diff --git a/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean b/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean index 64cece13f17d6a..11b80ad358269d 100644 --- a/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/LevelOne/Basic.lean @@ -114,4 +114,4 @@ lemma ModularForm.levelOne_weight_zero_rank_one : Module.rank ℂ (ModularForm lemma ModularForm.levelOne_neg_weight_rank_zero (hk : k < 0) : Module.rank ℂ (ModularForm 𝒮ℒ k) = 0 := by refine rank_eq_zero_iff.mpr fun f ↦ ⟨_, one_ne_zero, ?_⟩ - simpa [← coe_eq_zero_iff] using levelOne_neg_weight_eq_zero hk f + simpa [← FunLike.coe_zero_iff] using levelOne_neg_weight_eq_zero hk f diff --git a/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean b/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean index 9e0d76ea087884..d64e0c83bf96cb 100644 --- a/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean +++ b/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean @@ -178,8 +178,8 @@ lemma ModularForm.rank_eq_one_add_rank_cuspForm {k : ℕ} (hk : 3 ≤ k) (hk2 : exact one_ne_zero <| hE.symm.trans <| (isCuspForm_iff_coeffZero_eq_zero _).mp h · refine (Submodule.Quotient.forall _).mpr fun f ↦ ⟨(qExpansion 1 f).coeff 0, ?_⟩ rw [← Submodule.Quotient.mk_smul, Submodule.Quotient.eq, mem_cuspFormSubmodule_iff, - isCuspForm_iff_coeffZero_eq_zero, ModularForm.coe_sub, ModularForm.qExpansion_sub, - IsGLPos.coe_smul, ModularForm.qExpansion_smul, map_sub, + isCuspForm_iff_coeffZero_eq_zero, FunLike.coe_sub, ModularForm.qExpansion_sub, + FunLike.coe_smul, ModularForm.qExpansion_smul, map_sub, PowerSeries.coeff_smul, E_qExpansion_coeff_zero hk hk2, smul_eq_mul, mul_one, sub_self] all_goals simp diff --git a/Mathlib/NumberTheory/ModularForms/LevelOne/GradedRing.lean b/Mathlib/NumberTheory/ModularForms/LevelOne/GradedRing.lean index 6fba210898a963..7b3a3e06424cf0 100644 --- a/Mathlib/NumberTheory/ModularForms/LevelOne/GradedRing.lean +++ b/Mathlib/NumberTheory/ModularForms/LevelOne/GradedRing.lean @@ -38,7 +38,7 @@ private lemma E₄CubeSubE₆SqForm_apply (z : ℍ) : private lemma E₄CubeSubE₆SqForm_qExpansion_eq : qExpansion 1 E₄CubeSubE₆SqForm = qExpansion 1 E₄ * qExpansion 1 E₄ * qExpansion 1 E₄ - qExpansion 1 E₆ * qExpansion 1 E₆ := by - simp only [E₄CubeSubE₆SqForm, coe_sub, coe_mcast, + simp only [E₄CubeSubE₆SqForm, FunLike.coe_sub, coe_mcast, ModularForm.qExpansion_sub one_pos one_mem_strictPeriods_SL, ModularForm.qExpansion_pow one_pos one_mem_strictPeriods_SL] ring diff --git a/Mathlib/NumberTheory/ModularForms/NormTrace.lean b/Mathlib/NumberTheory/ModularForms/NormTrace.lean index aa5f90ed15ac95..c23e12f649be8b 100644 --- a/Mathlib/NumberTheory/ModularForms/NormTrace.lean +++ b/Mathlib/NumberTheory/ModularForms/NormTrace.lean @@ -123,7 +123,7 @@ variable {f} in lemma ModularForm.norm_ne_zero [ℋ.HasDetPlusMinusOne] [ModularFormClass F 𝒢 k] (hf : (f : ℍ → ℂ) ≠ 0) : ModularForm.norm ℋ f ≠ 0 := by contrapose hf - rw [← DFunLike.coe_injective.eq_iff, coe_norm, coe_zero, prod_eq_zero_iff] at hf + rw [← DFunLike.coe_injective.eq_iff, coe_norm, FunLike.coe_zero, prod_eq_zero_iff] at hf · simpa [QuotientGroup.exists_mk] using hf · exact Quotient.forall.mpr fun r _ ↦ (translate f r.val⁻¹).holo' @@ -158,7 +158,7 @@ private lemma ModularForm.eq_const_of_weight_zero₀ [𝒢.IsArithmetic] [𝒢.H simpa [Finset.prod_eq_zero_iff, QuotientGroup.exists_mk] using ⟨1, by simp⟩ obtain rfl : c = 0 := by simpa [hc] -- So `f - f I` has zero norm, hence it's the zero form. - simp only [Function.const_zero, coe_eq_zero_iff, norm_eq_zero_iff, sub_eq_zero] at hc + simp only [Function.const_zero, FunLike.coe_zero_iff, norm_eq_zero_iff, sub_eq_zero] at hc exact ⟨f I, by rw [hc, ModularForm.coe_const, Function.const_apply]⟩ lemma ModularForm.eq_const_of_weight_zero [𝒢.IsArithmetic] (f : ModularForm 𝒢 0) : diff --git a/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean b/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean index c6e068784ff198..b19f13a9d90701 100644 --- a/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean +++ b/Mathlib/NumberTheory/ModularForms/SlashInvariantForms.lean @@ -117,21 +117,21 @@ instance instAdd : Add (SlashInvariantForm Γ k) := slash_action_eq' := fun γ hγ ↦ by rw [SlashAction.add_slash, slash_action_eqn f γ hγ, slash_action_eqn g γ hγ] }⟩ -@[simp] -theorem coe_add (f g : SlashInvariantForm Γ k) : ⇑(f + g) = f + g := - rfl +instance : IsAddApply (SlashInvariantForm Γ k) ℍ ℂ where + add_apply _ _ _ := rfl -@[simp] -theorem add_apply (f g : SlashInvariantForm Γ k) (z : ℍ) : (f + g) z = f z + g z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_add := FunLike.coe_add + +@[deprecated (since := "2026-07-10")] protected alias add_apply := add_apply instance instZero : Zero (SlashInvariantForm Γ k) := ⟨{toFun := 0 slash_action_eq' := fun _ _ ↦ SlashAction.zero_slash _ _}⟩ -@[simp] -theorem coe_zero : ⇑(0 : SlashInvariantForm Γ k) = (0 : ℍ → ℂ) := - rfl +instance : IsZeroApply (SlashInvariantForm Γ k) ℍ ℂ where + zero_apply _ := rfl + +@[deprecated (since := "2026-07-10")] alias coe_zero := FunLike.coe_zero section smul @@ -145,13 +145,12 @@ instance instSMul : SMul α (SlashInvariantForm Γ k) where rw [← smul_one_smul ℂ] simp [-smul_assoc, smul_slash, slash_action_eqn _ _ hγ, σ, Subgroup.HasDetOne.det_eq hγ] } -@[simp] -theorem coe_smul (f : SlashInvariantForm Γ k) (n : α) : ⇑(n • f) = n • ⇑f := - rfl +instance : IsSMulApply α (SlashInvariantForm Γ k) ℍ ℂ where + smul_apply _ _ _ := rfl -@[simp] -theorem smul_apply (f : SlashInvariantForm Γ k) (n : α) (z : ℍ) : (n • f) z = n • f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_smul := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias smul_apply := smul_apply end smul @@ -167,14 +166,12 @@ instance instSMulℝ : SMul α (SlashInvariantForm Γ k) where rw [← smul_one_smul ℝ, ← smul_one_smul ℂ, smul_slash, Complex.real_smul, mul_one, σ_ofReal, slash_action_eqn _ _ hγ] } -@[simp] -theorem coe_smulℝ (f : SlashInvariantForm Γ k) (n : α) : ⇑(n • f) = n • ⇑f := - rfl +instance : IsSMulApply α (SlashInvariantForm Γ k) ℍ ℂ where + smul_apply _ _ _ := rfl -@[simp] -theorem smul_applyℝ (f : SlashInvariantForm Γ k) (n : α) (z : ℍ) : - (n • f) z = n • f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_smulℝ := FunLike.coe_smul + +@[deprecated (since := "2026-07-10")] protected alias smul_applyℝ := smul_apply end smulℝ @@ -183,44 +180,34 @@ instance instNeg : Neg (SlashInvariantForm Γ k) := { toFun := -f slash_action_eq' := fun γ hγ => by rw [SlashAction.neg_slash, slash_action_eqn f γ hγ] }⟩ -@[simp] -theorem coe_neg (f : SlashInvariantForm Γ k) : ⇑(-f) = -f := - rfl +instance : IsNegApply (SlashInvariantForm Γ k) ℍ ℂ where + neg_apply _ _ := rfl -@[simp] -theorem neg_apply (f : SlashInvariantForm Γ k) (z : ℍ) : (-f) z = -f z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_neg := FunLike.coe_neg + +@[deprecated (since := "2026-07-10")] protected alias neg_apply := neg_apply instance instSub : Sub (SlashInvariantForm Γ k) := ⟨fun f g => f + -g⟩ -@[simp] -theorem coe_sub (f g : SlashInvariantForm Γ k) : ⇑(f - g) = f - g := - rfl +instance : IsSubApply (SlashInvariantForm Γ k) ℍ ℂ where + sub_apply _ _ _ := rfl -@[simp] -theorem sub_apply (f g : SlashInvariantForm Γ k) (z : ℍ) : (f - g) z = f z - g z := - rfl +@[deprecated (since := "2026-07-10")] alias coe_sub := FunLike.coe_sub + +@[deprecated (since := "2026-07-10")] protected alias sub_apply := sub_apply -instance : AddCommGroup (SlashInvariantForm Γ k) := - DFunLike.coe_injective.addCommGroup _ rfl coe_add coe_neg coe_sub coe_smulℝ coe_smulℝ +instance : AddCommGroup (SlashInvariantForm Γ k) := fast_instance% FunLike.addCommGroup -/-- Additive coercion from `SlashInvariantForm` to `ℍ → ℂ`. -/ -def coeHom : SlashInvariantForm Γ k →+ ℍ → ℂ where - toFun f := f - map_zero' := rfl - map_add' _ _ := rfl +@[deprecated (since := "2026-07-10")] alias coeHom := FunLike.coeMonoidHom -theorem coeHom_injective : Function.Injective (@coeHom Γ k) := - DFunLike.coe_injective +@[deprecated (since := "2026-07-10")] alias coeHom_injective := FunLike.coeMonoidHom_injective instance instModuleComplex [Γ.HasDetOne] {α : Type*} [Semiring α] [Module α ℂ] - [IsScalarTower α ℂ ℂ] : Module α (SlashInvariantForm Γ k) := - coeHom_injective.module α _ (fun _ _ ↦ rfl) + [IsScalarTower α ℂ ℂ] : Module α (SlashInvariantForm Γ k) := FunLike.module instance instModuleReal {α : Type*} [Semiring α] [Module α ℝ] [Module α ℂ] [IsScalarTower α ℝ ℂ] : - Module α (SlashInvariantForm Γ k) := - coeHom_injective.module α _ (fun _ _ ↦ rfl) + Module α (SlashInvariantForm Γ k) := FunLike.module /-- The `SlashInvariantForm` corresponding to `Function.const _ x`. -/ @[simps -fullyApplied] From c10d9bc1c8e481eb623c555f57897eab3a1fb24d Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:23:08 +0000 Subject: [PATCH 1129/1300] chore: rename `FiniteMultiplicity.not_unit` to `FiniteMultiplicity.not_isUnit` (#42390) Co-authored-by: NoahW314 --- Mathlib/RingTheory/Multiplicity.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index 32e3fff999f4ea..307d2ecda3bdc4 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -185,10 +185,13 @@ theorem FiniteMultiplicity.not_iff_forall : ¬FiniteMultiplicity a b ↔ ∀ n : (by simpa [FiniteMultiplicity] using h), by simp [FiniteMultiplicity]; tauto⟩ -theorem FiniteMultiplicity.not_unit (h : FiniteMultiplicity a b) : ¬IsUnit a := +theorem FiniteMultiplicity.not_isUnit (h : FiniteMultiplicity a b) : ¬IsUnit a := let ⟨n, hn⟩ := h hn ∘ IsUnit.dvd ∘ IsUnit.pow (n + 1) +@[deprecated (since := "2026-08-02")] +alias FiniteMultiplicity.not_unit := FiniteMultiplicity.not_isUnit + theorem FiniteMultiplicity.mul_left {c : α} : FiniteMultiplicity a (b * c) → FiniteMultiplicity a b := fun ⟨n, hn⟩ => ⟨n, fun h => hn (h.trans (dvd_mul_right _ _))⟩ @@ -290,7 +293,7 @@ theorem emultiplicity_eq_ofNat {a b n : ℕ} [n.AtLeastTwo] : @[simp] theorem FiniteMultiplicity.not_of_isUnit_left (b : α) (ha : IsUnit a) : ¬FiniteMultiplicity a b := - (·.not_unit ha) + (·.not_isUnit ha) theorem FiniteMultiplicity.not_of_one_left (b : α) : ¬ FiniteMultiplicity 1 b := by simp @@ -667,7 +670,7 @@ theorem multiplicity_self {a : α} : multiplicity a a = 1 := by simp only [sq, mul_assoc, mul_eq_mul_left_iff] at hv obtain hv | rfl := hv · have : IsUnit a := .of_mul_eq_one v hv.symm - simpa [this] using ha.not_unit + simpa [this] using ha.not_isUnit · simpa using ha.ne_zero · simp [ha] From 64e0afda5236d382ce3267152e03fe3f2ef46944 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:55:58 +0000 Subject: [PATCH 1130/1300] doc(Topology): fix typo in weak space docstring (#42379) Co-authored-by: Batixx --- Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean b/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean index 2651255c982d3f..5ccc1d3c8d7ef0 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/WeakDual.lean @@ -196,7 +196,7 @@ end Ring end WeakDual -/-- The weak topology is the topology coarsest topology on `E` such that all functionals +/-- The weak topology is the coarsest topology on `E` such that all functionals `fun x => v x` are continuous. -/ def WeakSpace (𝕜 E) [CommSemiring 𝕜] [TopologicalSpace 𝕜] [ContinuousAdd 𝕜] [ContinuousConstSMul 𝕜 𝕜] [AddCommMonoid E] [Module 𝕜 E] [TopologicalSpace E] := From c0032752b47af314b015a7b411123fa4ac99bbaf Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:56:01 +0000 Subject: [PATCH 1131/1300] chore: rename `Prime.not_unit` to `Prime.not_isUnit` (#42385) Co-authored-by: NoahW314 --- Mathlib/Algebra/BigOperators/Associated.lean | 2 +- Mathlib/Algebra/GroupWithZero/Associated.lean | 2 +- Mathlib/Algebra/IsPrimePow.lean | 2 +- Mathlib/Algebra/Prime/Defs.lean | 13 ++++++++----- Mathlib/Algebra/Squarefree/Basic.lean | 2 +- Mathlib/Data/Nat/Multiplicity.lean | 4 ++-- Mathlib/NumberTheory/FLT/Three.lean | 2 +- Mathlib/RingTheory/ChainOfDivisors.lean | 6 +++--- Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean | 2 +- Mathlib/RingTheory/Multiplicity.lean | 8 ++++---- .../Polynomial/Cyclotomic/Factorization.lean | 2 +- Mathlib/RingTheory/Polynomial/RationalRoot.lean | 4 ++-- .../RingTheory/UniqueFactorizationDomain/Basic.lean | 7 ++++--- .../RingTheory/UniqueFactorizationDomain/Defs.lean | 2 +- .../UniqueFactorizationDomain/FactorSet.lean | 2 +- .../UniqueFactorizationDomain/Multiplicity.lean | 2 +- .../NormalizedFactors.lean | 4 ++-- Mathlib/RingTheory/Unramified/LocalStructure.lean | 2 +- Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean | 5 +++-- 19 files changed, 39 insertions(+), 34 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Associated.lean b/Mathlib/Algebra/BigOperators/Associated.lean index e87c5cd6348a1f..1c2fd5b82267a4 100644 --- a/Mathlib/Algebra/BigOperators/Associated.lean +++ b/Mathlib/Algebra/BigOperators/Associated.lean @@ -73,7 +73,7 @@ theorem Associated.prod {M : Type*} [CommMonoid M] {ι : Type*} (s : Finset ι) theorem exists_associated_mem_of_dvd_prod [CommMonoidWithZero M₀] [IsCancelMulZero M₀] {p : M₀} (hp : Prime p) {s : Multiset M₀} : (∀ r ∈ s, Prime r) → p ∣ s.prod → ∃ q ∈ s, p ~ᵤ q := - Multiset.induction_on s (by simp [mt isUnit_iff_dvd_one.2 hp.not_unit]) fun a s ih hs hps => by + Multiset.induction_on s (by simp [mt isUnit_iff_dvd_one.2 hp.not_isUnit]) fun a s ih hs hps => by rw [Multiset.prod_cons] at hps rcases hp.dvd_or_dvd hps with h | h · have hap := hs a (Multiset.mem_cons.2 (Or.inl rfl)) diff --git a/Mathlib/Algebra/GroupWithZero/Associated.lean b/Mathlib/Algebra/GroupWithZero/Associated.lean index de3d8bd0385611..e3ffb429a6396f 100644 --- a/Mathlib/Algebra/GroupWithZero/Associated.lean +++ b/Mathlib/Algebra/GroupWithZero/Associated.lean @@ -234,7 +234,7 @@ protected theorem Associated.prime [CommMonoidWithZero M] {p q : M} (h : p ~ᵤ Prime q := ⟨h.ne_zero_iff.1 hp.ne_zero, let ⟨u, hu⟩ := h - ⟨fun ⟨v, hv⟩ => hp.not_unit ⟨v * u⁻¹, by simp [hv, hu.symm]⟩, by + ⟨fun ⟨v, hv⟩ => hp.not_isUnit ⟨v * u⁻¹, by simp [hv, hu.symm]⟩, by rw [← hu] simp only [Units.isUnit, IsUnit.mul_right_dvd] intro a b diff --git a/Mathlib/Algebra/IsPrimePow.lean b/Mathlib/Algebra/IsPrimePow.lean index 2db84a2c509af6..54089849ddb00d 100644 --- a/Mathlib/Algebra/IsPrimePow.lean +++ b/Mathlib/Algebra/IsPrimePow.lean @@ -45,7 +45,7 @@ theorem not_isPrimePow_zero [NoZeroDivisors R] : ¬IsPrimePow (0 : R) := by theorem IsPrimePow.not_unit {n : R} (h : IsPrimePow n) : ¬IsUnit n := let ⟨_p, _k, hp, hk, hn⟩ := h - hn ▸ (isUnit_pow_iff hk.ne').not.mpr hp.not_unit + hn ▸ (isUnit_pow_iff hk.ne').not.mpr hp.not_isUnit theorem IsUnit.not_isPrimePow {n : R} (h : IsUnit n) : ¬IsPrimePow n := fun h' => h'.not_unit h diff --git a/Mathlib/Algebra/Prime/Defs.lean b/Mathlib/Algebra/Prime/Defs.lean index 47228fb3dd48c6..dd31ae97589115 100644 --- a/Mathlib/Algebra/Prime/Defs.lean +++ b/Mathlib/Algebra/Prime/Defs.lean @@ -51,11 +51,14 @@ include hp theorem ne_zero : p ≠ 0 := hp.1 -theorem not_unit : ¬IsUnit p := +theorem not_isUnit : ¬IsUnit p := hp.2.1 +@[deprecated (since := "2026-08-02")] +alias not_unit := not_isUnit + theorem not_dvd_one : ¬p ∣ 1 := - mt (isUnit_of_dvd_one ·) hp.not_unit + mt (isUnit_of_dvd_one ·) hp.not_isUnit theorem ne_one : p ≠ 1 := fun h => hp.2.1 (h.symm ▸ isUnit_one) @@ -76,7 +79,7 @@ theorem dvd_of_dvd_pow {a : M} {n : ℕ} (h : p ∣ a ^ n) : p ∣ a := by | zero => rw [pow_zero] at h have := isUnit_of_dvd_one h - have := not_unit hp + have := not_isUnit hp contradiction | succ n ih => rw [pow_succ'] at h @@ -93,7 +96,7 @@ end Prime theorem not_prime_zero : ¬Prime (0 : M) := fun h => h.ne_zero rfl @[simp] -theorem not_prime_one : ¬Prime (1 : M) := fun h => h.not_unit isUnit_one +theorem not_prime_one : ¬Prime (1 : M) := fun h => h.not_isUnit isUnit_one end Prime @@ -147,7 +150,7 @@ section CancelCommMonoidWithZero variable [CommMonoidWithZero M] [IsCancelMulZero M] {p : M} protected theorem Prime.irreducible (hp : Prime p) : Irreducible p := - ⟨hp.not_unit, fun a b ↦ by + ⟨hp.not_isUnit, fun a b ↦ by rintro rfl exact (hp.dvd_or_dvd dvd_rfl).symm.imp (isUnit_of_dvd_one <| (mul_dvd_mul_iff_right <| right_ne_zero_of_mul hp.ne_zero).mp <| diff --git a/Mathlib/Algebra/Squarefree/Basic.lean b/Mathlib/Algebra/Squarefree/Basic.lean index 0730696dc86763..a3fb87e99d1b42 100644 --- a/Mathlib/Algebra/Squarefree/Basic.lean +++ b/Mathlib/Algebra/Squarefree/Basic.lean @@ -185,7 +185,7 @@ theorem pow_dvd_of_squarefree_of_pow_succ_dvd_mul_right {k : ℕ} p ^ k ∣ y := by by_cases hxp : p ∣ x · obtain ⟨x', rfl⟩ := hxp - have hx' : ¬ p ∣ x' := fun contra ↦ hp.not_unit <| hx p (mul_dvd_mul_left p contra) + have hx' : ¬ p ∣ x' := fun contra ↦ hp.not_isUnit <| hx p (mul_dvd_mul_left p contra) replace h : p ^ k ∣ x' * y := by rw [pow_succ', mul_assoc] at h exact (mul_dvd_mul_iff_left hp.ne_zero).mp h diff --git a/Mathlib/Data/Nat/Multiplicity.lean b/Mathlib/Data/Nat/Multiplicity.lean index 9a65a42698a4c8..46024dc2133dd1 100644 --- a/Mathlib/Data/Nat/Multiplicity.lean +++ b/Mathlib/Data/Nat/Multiplicity.lean @@ -79,7 +79,7 @@ theorem emultiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) namespace Prime theorem emultiplicity_one {p : ℕ} (hp : p.Prime) : emultiplicity p 1 = 0 := - emultiplicity_of_one_right hp.prime.not_unit + emultiplicity_of_one_right hp.prime.not_isUnit theorem emultiplicity_mul {p m n : ℕ} (hp : p.Prime) : emultiplicity p (m * n) = emultiplicity p m + emultiplicity p n := @@ -93,7 +93,7 @@ theorem emultiplicity_self {p : ℕ} (hp : p.Prime) : emultiplicity p p = 1 := (Nat.finiteMultiplicity_iff.2 ⟨hp.ne_one, hp.pos⟩).emultiplicity_self theorem emultiplicity_pow_self {p n : ℕ} (hp : p.Prime) : emultiplicity p (p ^ n) = n := - _root_.emultiplicity_pow_self hp.ne_zero hp.prime.not_unit n + _root_.emultiplicity_pow_self hp.ne_zero hp.prime.not_isUnit n /-- **Legendre's Theorem** diff --git a/Mathlib/NumberTheory/FLT/Three.lean b/Mathlib/NumberTheory/FLT/Three.lean index 3741a513e20ae3..272b0dff8b0449 100644 --- a/Mathlib/NumberTheory/FLT/Three.lean +++ b/Mathlib/NumberTheory/FLT/Three.lean @@ -212,7 +212,7 @@ variable [NumberField K] [IsCyclotomicExtension {3} ℚ K] /-- For any `S' : Solution'`, the multiplicity of `λ` in `S'.c` is finite. -/ lemma Solution'.multiplicity_lambda_c_finite : FiniteMultiplicity (hζ.toInteger - 1) S'.c := - .of_not_isUnit hζ.zeta_sub_one_prime'.not_unit S'.hc + .of_not_isUnit hζ.zeta_sub_one_prime'.not_isUnit S'.hc /-- Given `S' : Solution'`, `S'.multiplicity` is the multiplicity of `λ` in `S'.c`, as a natural number. -/ diff --git a/Mathlib/RingTheory/ChainOfDivisors.lean b/Mathlib/RingTheory/ChainOfDivisors.lean index 908e92259e985d..90fcb0b18eaae4 100644 --- a/Mathlib/RingTheory/ChainOfDivisors.lean +++ b/Mathlib/RingTheory/ChainOfDivisors.lean @@ -75,7 +75,7 @@ theorem exists_chain_of_prime_pow {p : Associates M} {n : ℕ} (hn : n ≠ 0) (h exact Nat.lt_succ_of_le (Nat.one_le_iff_ne_zero.mpr hn) · exact Associates.dvdNotUnit_iff_lt.mp ⟨pow_ne_zero n hp.ne_zero, p ^ (m - n : ℕ), - not_isUnit_of_not_isUnit_dvd hp.not_unit (dvd_pow dvd_rfl (Nat.sub_pos_of_lt h).ne'), + not_isUnit_of_not_isUnit_dvd hp.not_isUnit (dvd_pow dvd_rfl (Nat.sub_pos_of_lt h).ne'), (pow_mul_pow_sub p h.le).symm⟩ · obtain ⟨i, i_le, hi⟩ := (dvd_prime_pow hp n).1 h rw [associated_iff_eq] at hi @@ -118,7 +118,7 @@ theorem eq_second_of_chain_of_prime_dvd {p q r : Associates M} {n : ℕ} (hn : n · rw [Fin.le_iff_val_le_val, Fin.val_one, Nat.succ_le_iff, ← Fin.val_zero (n.succ + 1), ← Fin.lt_def, Fin.pos_iff_ne_zero] rintro rfl - exact hp.not_unit (first_of_chain_isUnit h₁ @h₂) + exact hp.not_isUnit (first_of_chain_isUnit h₁ @h₂) obtain rfl | ⟨j, rfl⟩ := i.eq_zero_or_eq_succ · cases hi refine @@ -289,7 +289,7 @@ theorem map_prime_of_factor_orderIso {m p : Associates M} {n : Associates N} (hn · rw [Ne, ← Associates.isUnit_iff_eq_bot, Associates.isUnit_iff_eq_one, coe_factor_orderIso_map_eq_one_iff _ d] rintro rfl - exact (prime_of_normalized_factor 1 hp).not_unit isUnit_one + exact (prime_of_normalized_factor 1 hp).not_isUnit isUnit_one · have : b ≤ n := le_trans (le_of_lt hb) (d ⟨p, dvd_of_mem_normalizedFactors hp⟩).prop obtain ⟨x, hx⟩ := d.surjective ⟨b, this⟩ rw [← Subtype.coe_mk (p := (· ≤ n)) b this, ← hx] at hb diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index b80abb2c4a4035..5bec1fe98c3ed3 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -102,7 +102,7 @@ theorem isPrime_of_prime {P : Ideal A} (h : Prime P) : IsPrime P := by refine ⟨?_, fun hxy => ?_⟩ · rintro rfl rw [← one_eq_top] at h - exact h.not_unit isUnit_one + exact h.not_isUnit isUnit_one · simp only [← dvd_span_singleton, ← span_singleton_mul_span_singleton] at hxy ⊢ exact h.dvd_or_dvd hxy diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index 307d2ecda3bdc4..3738ea2d55ed6c 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -709,13 +709,13 @@ theorem Finset.emultiplicity_prod {β : Type*} {p : α} (hp : Prime p) (s : Fins induction s using Finset.induction with | empty => simp only [Finset.sum_empty, Finset.prod_empty] - exact emultiplicity_of_one_right hp.not_unit + exact emultiplicity_of_one_right hp.not_isUnit | insert a s has ih => simpa [has, ← ih] using emultiplicity_mul hp theorem emultiplicity_pow {p a : α} (hp : Prime p) {k : ℕ} : emultiplicity p (a ^ k) = k * emultiplicity p a := by induction k with - | zero => simp [emultiplicity_of_one_right hp.not_unit] + | zero => simp [emultiplicity_of_one_right hp.not_isUnit] | succ k hk => simp [pow_succ, emultiplicity_mul hp, hk, add_mul] protected theorem FiniteMultiplicity.multiplicity_pow {p a : α} (hp : Prime p) @@ -736,11 +736,11 @@ theorem multiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ theorem emultiplicity_pow_self_of_prime {p : α} (hp : Prime p) (n : ℕ) : emultiplicity p (p ^ n) = n := - emultiplicity_pow_self hp.ne_zero hp.not_unit n + emultiplicity_pow_self hp.ne_zero hp.not_isUnit n theorem multiplicity_pow_self_of_prime {p : α} (hp : Prime p) (n : ℕ) : multiplicity p (p ^ n) = n := - multiplicity_pow_self hp.ne_zero hp.not_unit n + multiplicity_pow_self hp.ne_zero hp.not_isUnit n end CancelCommMonoidWithZero diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean index 2d1410358a3ebb..431665ffb36163 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Factorization.lean @@ -159,7 +159,7 @@ theorem normalizedFactors_cyclotomic_card : (normalizedFactors (cyclotomic n K)) (pos_of_ne_zero <| f_ne_zero hK) _ _).mp (hn.pow_left f)) ((CharP.cast_eq_zero_iff K p _).mp H) have hP : P ∈ normalizedFactors (cyclotomic n K) := count_pos.mp (by lia) - refine (prime_of_normalized_factor _ hP).not_unit (squarefree_cyclotomic n K P ?_) + refine (prime_of_normalized_factor _ hP).not_isUnit (squarefree_cyclotomic n K P ?_) have : {P, P} ≤ normalizedFactors (cyclotomic n K) := by refine le_iff_count.mpr (fun Q ↦ ?_) by_cases hQ : Q = P diff --git a/Mathlib/RingTheory/Polynomial/RationalRoot.lean b/Mathlib/RingTheory/Polynomial/RationalRoot.lean index ce4be7bb114adf..5afbbad9796a0e 100644 --- a/Mathlib/RingTheory/Polynomial/RationalRoot.lean +++ b/Mathlib/RingTheory/Polynomial/RationalRoot.lean @@ -74,7 +74,7 @@ theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ · simp_all [nonZeroDivisors.coe_ne_zero] · refine dvd_of_dvd_mul_left_of_no_prime_factors hr ?_ this intro q dvd_num dvd_denom_pow hq - apply hq.not_unit + apply hq.not_isUnit exact num_den_reduced A r dvd_num (hq.dvd_of_dvd_pow dvd_denom_pow) convert! dvd_term_of_isRoot_of_dvd_terms 0 (num_isRoot_scaleRoots_of_aeval_eq_zero hr) _ · rw [pow_zero, mul_one] @@ -93,7 +93,7 @@ theorem den_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : dvd_of_dvd_mul_left_of_no_prime_factors (mem_nonZeroDivisors_iff_ne_zero.mp (den A r).2) ?_ this intro q dvd_den dvd_num_pow hq - apply hq.not_unit + apply hq.not_isUnit exact num_den_reduced A r (hq.dvd_of_dvd_pow dvd_num_pow) dvd_den rw [← coeff_scaleRoots_natDegree] apply dvd_term_of_isRoot_of_dvd_terms _ (num_isRoot_scaleRoots_of_aeval_eq_zero hr) diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index 9481b12ea06a52..cf1ec92d32d910 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -80,7 +80,7 @@ theorem prime_factors_unique [CommMonoidWithZero α] [IsCancelMulZero α] : exact Multiset.rel_zero_left.2 <| Multiset.eq_zero_of_forall_notMem fun x hx => have : IsUnit g.prod := by simpa [associated_one_iff_isUnit] using h.symm - (hg x hx).not_unit <| + (hg x hx).not_isUnit <| isUnit_iff_dvd_one.2 <| (Multiset.dvd_prod hx).trans (isUnit_iff_dvd_one.1 this) | cons p f ih => intro g hf hg hfg @@ -420,8 +420,9 @@ variable {R : Type*} [CommMonoidWithZero R] [UniqueFactorizationMonoid R] theorem isRelPrime_iff_no_prime_factors {a b : R} (ha : a ≠ 0) : IsRelPrime a b ↔ ∀ ⦃d⦄, d ∣ a → d ∣ b → ¬Prime d := - ⟨fun h _ ha hb ↦ (·.not_unit <| h ha hb), fun h ↦ WfDvdMonoid.isRelPrime_of_no_irreducible_factors - (ha ·.1) fun _ irr ha hb ↦ h ha hb (UniqueFactorizationMonoid.irreducible_iff_prime.mp irr)⟩ + ⟨fun h _ ha hb ↦ (·.not_isUnit <| h ha hb), + fun h ↦ WfDvdMonoid.isRelPrime_of_no_irreducible_factors + (ha ·.1) fun _ irr ha hb ↦ h ha hb (UniqueFactorizationMonoid.irreducible_iff_prime.mp irr)⟩ /-- Euclid's lemma: if `a ∣ b * c` and `a` and `c` have no common prime factors, `a ∣ b`. Compare `IsCoprime.dvd_of_dvd_mul_left`. -/ diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean index 38d0e574bfe275..96559aad31efc4 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean @@ -153,7 +153,7 @@ theorem exists_prime_factors (a : α) : lemma exists_prime_iff : (∃ (p : α), Prime p) ↔ ∃ (x : α), x ≠ 0 ∧ ¬ IsUnit x := by - refine ⟨fun ⟨p, hp⟩ ↦ ⟨p, hp.ne_zero, hp.not_unit⟩, fun ⟨x, hx₀, hxu⟩ ↦ ?_⟩ + refine ⟨fun ⟨p, hp⟩ ↦ ⟨p, hp.ne_zero, hp.not_isUnit⟩, fun ⟨x, hx₀, hxu⟩ ↦ ?_⟩ obtain ⟨f, hf, -⟩ := WfDvdMonoid.exists_irreducible_factor hxu hx₀ exact ⟨f, UniqueFactorizationMonoid.irreducible_iff_prime.mp hf⟩ diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean index 813990ae38a3af..ea862e1026214c 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean @@ -412,7 +412,7 @@ theorem coprime_iff_inf_one {a b : α} (ha0 : a ≠ 0) (hb0 : b ≠ 0) : Associates.mk a ⊓ Associates.mk b = 1 ↔ ∀ {d : α}, d ∣ a → d ∣ b → ¬Prime d := by constructor · intro hg p ha hb hp - refine (Associates.prime_mk.mpr hp).not_unit (isUnit_of_dvd_one ?_) + refine (Associates.prime_mk.mpr hp).not_isUnit (isUnit_of_dvd_one ?_) rw [← hg] exact le_inf (mk_le_mk_of_dvd ha) (mk_le_mk_of_dvd hb) · contrapose diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean index 00bd185a998460..9b279f43beb805 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Multiplicity.lean @@ -48,7 +48,7 @@ theorem FiniteMultiplicity.of_not_isUnit [CommMonoidWithZero α] [IsCancelMulZer theorem FiniteMultiplicity.of_prime_left [CommMonoidWithZero α] [IsCancelMulZero α] [WfDvdMonoid α] {a b : α} (ha : Prime a) (hb : b ≠ 0) : FiniteMultiplicity a b := - .of_not_isUnit ha.not_unit hb + .of_not_isUnit ha.not_isUnit hb namespace UniqueFactorizationMonoid diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean index fda34bb2a0870b..13ba0a3bee8196 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean @@ -252,7 +252,7 @@ theorem disjoint_normalizedFactors {a b : α} (hc : IsRelPrime a b) : intro x hxa hxb have x_dvd_a := dvd_of_mem_normalizedFactors hxa have x_dvd_b := dvd_of_mem_normalizedFactors hxb - exact (prime_of_normalized_factor x hxa).not_unit (hc x_dvd_a x_dvd_b) + exact (prime_of_normalized_factor x hxa).not_isUnit (hc x_dvd_a x_dvd_b) theorem exists_associated_prime_pow_of_unique_normalized_factor {p r : α} (h : ∀ {m}, m ∈ normalizedFactors r → m = p) (hr : r ≠ 0) : ∃ i : ℕ, Associated (p ^ i) r := by @@ -283,7 +283,7 @@ theorem normalizedFactors_pos (x : α) (hx : x ≠ 0) : 0 < normalizedFactors x · intro h hx obtain ⟨p, hp⟩ := Multiset.exists_mem_of_ne_zero h.ne' exact - (prime_of_normalized_factor _ hp).not_unit + (prime_of_normalized_factor _ hp).not_isUnit (isUnit_of_dvd_unit (dvd_of_mem_normalizedFactors hp) hx) · intro h obtain ⟨p, hp⟩ := exists_mem_normalizedFactors hx h diff --git a/Mathlib/RingTheory/Unramified/LocalStructure.lean b/Mathlib/RingTheory/Unramified/LocalStructure.lean index 65e65f19a04fcd..3aa963a14f1343 100644 --- a/Mathlib/RingTheory/Unramified/LocalStructure.lean +++ b/Mathlib/RingTheory/Unramified/LocalStructure.lean @@ -196,7 +196,7 @@ private lemma exists_hasStandardEtaleSurjectionOn_of_exists_adjoin_singleton_eq_ ring · rw [dvd_add_left (dvd_mul_of_dvd_right (dvd_pow (by simp [m, minpoly.dvd_iff]) (by simp)) _), ← isUnit_iff_dvd_one] - exact hm.not_unit + exact hm.not_isUnit have hm' : derivative m ≠ 0 := (separable_iff_derivative_ne_zero hm.irreducible).mp (IsSeparable.isSeparable ..) suffices ¬m ∣ derivative (q.map (algebraMap R _)) by diff --git a/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean b/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean index 24b07c6462f452..7c4c875b72ee4d 100644 --- a/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean +++ b/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean @@ -18,8 +18,9 @@ variable {R : Type*} [CommRing R] [IsDomain R] {p : R} /-- `multiplicity` of a prime in an integral domain as an additive valuation to `ℕ∞`. -/ noncomputable def multiplicity_addValuation (hp : Prime p) : AddValuation R ℕ∞ := - AddValuation.of (emultiplicity p) (emultiplicity_zero _) (emultiplicity_of_one_right hp.not_unit) - (fun _ _ => min_le_emultiplicity_add) fun _ _ => emultiplicity_mul hp + AddValuation.of (emultiplicity p) (emultiplicity_zero _) + (emultiplicity_of_one_right hp.not_isUnit) + (fun _ _ => min_le_emultiplicity_add) fun _ _ => emultiplicity_mul hp @[simp] theorem multiplicity_addValuation_apply {hp : Prime p} {r : R} : From 533312790e4cb6b1a2b6e999cd48e52d7184bfb6 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:56:03 +0000 Subject: [PATCH 1132/1300] chore: rename a lemma containing `not_unit` (#42387) Co-authored-by: NoahW314 --- Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean | 2 +- Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean b/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean index f4c1f0e4f5cbde..dc8da4b5591c21 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/TFAE.lean @@ -56,7 +56,7 @@ theorem exists_maximalIdeal_pow_eq_of_principal [IsNoetherianRing R] [IsLocalRin have hx' := IsDiscreteValuationRing.irreducible_of_span_eq_maximalIdeal x this hx have H' : ∀ r : R, r ≠ 0 → r ∈ nonunits R → ∃ n : ℕ, Associated (x ^ n) r := by intro r hr₁ hr₂ - obtain ⟨f, hf₁, rfl, hf₂⟩ := (WfDvdMonoid.not_unit_iff_exists_factors_eq r hr₁).mp hr₂ + obtain ⟨f, hf₁, rfl, hf₂⟩ := (WfDvdMonoid.not_isUnit_iff_exists_factors_eq r hr₁).mp hr₂ have : ∀ b ∈ f, Associated x b := by intro b hb exact Irreducible.associated_of_dvd hx' (hf₁ b hb) ((H b).mp (hf₁ b hb).1) diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean index 96559aad31efc4..1b734daf5621bb 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean @@ -84,7 +84,7 @@ theorem exists_factors (a : α) : rw [s.prod_cons i] exact hs.2.mul_left i⟩ -theorem not_unit_iff_exists_factors_eq (a : α) (hn0 : a ≠ 0) : +theorem not_isUnit_iff_exists_factors_eq (a : α) (hn0 : a ≠ 0) : ¬IsUnit a ↔ ∃ f : Multiset α, (∀ b ∈ f, Irreducible b) ∧ f.prod = a ∧ f ≠ ∅ := ⟨fun hnu => by obtain ⟨f, hi, u, rfl⟩ := exists_factors a hn0 @@ -98,6 +98,9 @@ theorem not_unit_iff_exists_factors_eq (a : α) (hn0 : a ≠ 0) : let ⟨b, h⟩ := Multiset.exists_mem_of_ne_zero hne not_isUnit_of_not_isUnit_dvd (hi b h).not_isUnit <| he ▸ Multiset.dvd_prod h⟩ +@[deprecated (since := "2026-08-02")] +alias not_unit_iff_exists_factors_eq := not_isUnit_iff_exists_factors_eq + theorem isRelPrime_of_no_irreducible_factors {x y : α} (nonzero : ¬(x = 0 ∧ y = 0)) (H : ∀ z : α, Irreducible z → z ∣ x → ¬z ∣ y) : IsRelPrime x y := isRelPrime_of_no_nonunits_factors nonzero fun _z znu znz zx zy ↦ From d586c71e87ddf1c4fef06a739cdd3b733fd8b64d Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:56:05 +0000 Subject: [PATCH 1133/1300] chore: rename `IsPrimePow.not_unit` to `IsPrimePow.not_isUnit` (#42389) Co-authored-by: NoahW314 --- Mathlib/Algebra/IsPrimePow.lean | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/IsPrimePow.lean b/Mathlib/Algebra/IsPrimePow.lean index 54089849ddb00d..25d76180c60aa2 100644 --- a/Mathlib/Algebra/IsPrimePow.lean +++ b/Mathlib/Algebra/IsPrimePow.lean @@ -43,11 +43,14 @@ theorem not_isPrimePow_zero [NoZeroDivisors R] : ¬IsPrimePow (0 : R) := by rw [eq_zero_of_pow_eq_zero hx] simp -theorem IsPrimePow.not_unit {n : R} (h : IsPrimePow n) : ¬IsUnit n := +theorem IsPrimePow.not_isUnit {n : R} (h : IsPrimePow n) : ¬IsUnit n := let ⟨_p, _k, hp, hk, hn⟩ := h hn ▸ (isUnit_pow_iff hk.ne').not.mpr hp.not_isUnit -theorem IsUnit.not_isPrimePow {n : R} (h : IsUnit n) : ¬IsPrimePow n := fun h' => h'.not_unit h +@[deprecated (since := "2026-08-02")] +alias IsPrimePow.not_unit := IsPrimePow.not_isUnit + +theorem IsUnit.not_isPrimePow {n : R} (h : IsUnit n) : ¬IsPrimePow n := fun h' => h'.not_isUnit h theorem not_isPrimePow_one : ¬IsPrimePow (1 : R) := isUnit_one.not_isPrimePow From 49c3708b8696eca37c065f6f9612d48fb53d19fd Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 3 Aug 2026 10:53:42 +0000 Subject: [PATCH 1134/1300] chore: remove unused `have`/`let` (#42395) This PR removes some unused `have`/`let` that have been caught using the `unusedHavesSuffices` linter from batteries. Unfortunately, the linter has quite a few false positives as well. See also https://github.com/leanprover-community/batteries/pull/1932 --- Mathlib/AlgebraicGeometry/Modules/Sheaf.lean | 3 --- Mathlib/CategoryTheory/Limits/Types/Products.lean | 1 - Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean | 3 --- Mathlib/CategoryTheory/Sites/LeftExact.lean | 1 - Mathlib/Data/Fin/VecNotation.lean | 1 - Mathlib/LinearAlgebra/FreeModule/ModN.lean | 1 - Mathlib/Tactic/Ring/Common.lean | 1 - 7 files changed, 11 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean b/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean index 3f59592d592126..c1a0de32bf3daa 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Sheaf.lean @@ -476,9 +476,6 @@ set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in /-- Restriction along the composition is isomorphic to the composition of restrictions. -/ def restrictFunctorComp : restrictFunctor (f ≫ g) ≅ restrictFunctor g ⋙ restrictFunctor f := - have : (f.opensFunctor ⋙ g.opensFunctor).IsContinuous - (Opens.grothendieckTopology X) (Opens.grothendieckTopology Z) := - Functor.isContinuous_comp _ _ _ (Opens.grothendieckTopology _) _ SheafOfModules.pushforwardNatIso _ (NatIso.ofComponents fun _ ↦ eqToIso (by simp)) ≪≫ SheafOfModules.pushforwardCongr (by ext : 3; simp [← Functor.map_comp, SheafedSpace.sheaf]) ≪≫ (SheafOfModules.pushforwardComp _ _).symm diff --git a/Mathlib/CategoryTheory/Limits/Types/Products.lean b/Mathlib/CategoryTheory/Limits/Types/Products.lean index 812c6398819220..426d1d10ba01a9 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Products.lean @@ -229,7 +229,6 @@ noncomputable def productLimitCone : π := Discrete.natTrans (fun ⟨j⟩ => ↾fun f => (equivShrink (∀ j, F j)).symm f j) } isLimit := - have : Small.{u} (∀ j, F j) := inferInstance { lift := fun s => ↾fun x => (equivShrink _) (fun j => s.π.app ⟨j⟩ x) uniq := fun s m w => ConcreteCategory.hom_ext _ _ fun x => Shrink.ext (funext fun j => by simpa using! ConcreteCategory.congr_hom (w ⟨j⟩) x) } diff --git a/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean b/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean index 7c09039b9dde8d..b8c38dff4bf052 100644 --- a/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean +++ b/Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean @@ -45,9 +45,6 @@ def PreZeroHypercover.isLimitSigmaOfIsColimitEquiv (E : PreZeroHypercover.{w} S) [PreservesLimit (Discrete.functor fun i ↦ op (E.toPreOneHypercover.Y' i)) F] : IsLimit ((E.sigmaOfIsColimit hc).toPreOneHypercover.multifork F) ≃ IsLimit (E.toPreOneHypercover.multifork F) := by - have : HasPullback (Cofan.IsColimit.desc hc E.f) (Cofan.IsColimit.desc hc E.f) := - inferInstanceAs <| HasPullback - ((E.sigmaOfIsColimit hc).f ⟨⟩) ((E.sigmaOfIsColimit hc).f ⟨⟩) let c' : Cofan E.toPreOneHypercover.Y' := Cofan.mk ((E.sigmaOfIsColimit hc).toPreOneHypercover.Y (i₁ := ⟨⟩) (i₂ := ⟨⟩) ⟨⟩) diff --git a/Mathlib/CategoryTheory/Sites/LeftExact.lean b/Mathlib/CategoryTheory/Sites/LeftExact.lean index 6b603310282077..67dc248a006044 100644 --- a/Mathlib/CategoryTheory/Sites/LeftExact.lean +++ b/Mathlib/CategoryTheory/Sites/LeftExact.lean @@ -135,7 +135,6 @@ def liftToPlusObjLimitObj {K : Type s} [SmallCategory K] [FinCategory K] [ReflectsLimitsOfShape K (forget D)] (F : K ⥤ Cᵒᵖ ⥤ D) (X : C) (S : Cone (F ⋙ J.plusFunctor D ⋙ (evaluation Cᵒᵖ D).obj (op X))) : S.pt ⟶ (J.plusObj (limit F)).obj (op X) := - let x := (J.Cover X)ᵒᵖ let F' := F ⋙ J.diagramFunctor D X let e := colimitLimitIso (F ⋙ J.diagramFunctor D X) let t : J.diagram (limit F) X ≅ limit (F ⋙ J.diagramFunctor D X) := diff --git a/Mathlib/Data/Fin/VecNotation.lean b/Mathlib/Data/Fin/VecNotation.lean index eb4325f5b30e99..d1173584d10105 100644 --- a/Mathlib/Data/Fin/VecNotation.lean +++ b/Mathlib/Data/Fin/VecNotation.lean @@ -197,7 +197,6 @@ dsimproc cons_val (Matrix.vecCons _ _ _) := fun e => do if let Expr.lit (.natVal length) := etailn_whnf then pure (length, false, q(OfNat.ofNat $etailn_whnf)) else if let some ((base : Q(ℕ)), offset) ← (Meta.isOffset? etailn_whnf).run then - let offset_e : Q(ℕ) := mkNatLit offset pure (offset, true, q($base + $offset)) else pure (0, true, etailn) diff --git a/Mathlib/LinearAlgebra/FreeModule/ModN.lean b/Mathlib/LinearAlgebra/FreeModule/ModN.lean index 7efba9a166552d..5328a0db8fe53a 100644 --- a/Mathlib/LinearAlgebra/FreeModule/ModN.lean +++ b/Mathlib/LinearAlgebra/FreeModule/ModN.lean @@ -63,7 +63,6 @@ set_option backward.isDefEq.respectTransparency false in /-- Given a free module `G` over `ℤ`, construct the corresponding basis of `G / ⟨n⟩` over `ℤ / nℤ`. -/ noncomputable def basis {ι : Type*} (b : Basis ι ℤ G) : Basis ι (ZMod n) (ModN G n) := by - set ψ : G →+ G := zsmulAddGroupHom n set nG := LinearMap.range (LinearMap.lsmul ℤ G n) set H := G ⧸ nG set φ : G →ₗ[ℤ] H := nG.mkQ diff --git a/Mathlib/Tactic/Ring/Common.lean b/Mathlib/Tactic/Ring/Common.lean index 1e801aaa615a82..59b90ac16b357b 100644 --- a/Mathlib/Tactic/Ring/Common.lean +++ b/Mathlib/Tactic/Ring/Common.lean @@ -481,7 +481,6 @@ section /-- Get the leading coefficient of an `ExProd`. -/ def ExProd.coeff {e : Q($α)} : - have : Inhabited <| Σ c, bt c := ⟨default, default⟩ ExProd bt sα e → Σ c, bt c | .const q => ⟨_, q⟩ | .mul _ _ v => v.coeff From e76b996718f27fb278e4f046c7e94537e033fb92 Mon Sep 17 00:00:00 2001 From: Akhil Mathew <269628265+j2d9w5xtjn-png@users.noreply.github.com> Date: Mon, 3 Aug 2026 11:34:52 +0000 Subject: [PATCH 1135/1300] feat(Counterexamples): a finite free group scheme of order four not killed by four (#41748) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a `Counterexamples/` file resolving a question of Grothendieck in the negative. ## Statement Grothendieck asked whether a finite locally free group scheme of order `n` is killed by `n`. Deligne proved this holds for **commutative** group schemes. This file gives a counterexample in the non-commutative case. Over the base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)`, the coordinate algebra A = R[U, V] / (U² − abU + b²V, V² − a²V) is a Hopf algebra, finite free of rank four over `R`, whose associated affine group scheme has order four but is **not killed by four**. Concretely, the fourth convolution power of the identity is not the convolution unit: `Counterexample.GrothendieckPower.counterexample : Nontrivial R ∧ Module.Free R A ∧ Module.Finite R A ∧ Module.finrank R A = 4 ∧ powerMap 4 ≠ (Algebra.ofId R A).comp counit` ## Disclosure As stated in the module docstring, and per mathlib policy: the construction of this group scheme and its formalization were carried out with the AI assistants Codex (OpenAI) and Claude (Anthropic), under the direction of the author, who takes responsibility for the contribution. Co-authored-by: Yaël Dillies Co-authored-by: Kevin Buzzard --- Counterexamples.lean | 1 + Counterexamples/GrothendieckPower.lean | 1000 +++++++++++++++++++ Mathlib/Algebra/QuadraticAlgebra/Basic.lean | 4 + docs/references.bib | 19 + 4 files changed, 1024 insertions(+) create mode 100644 Counterexamples/GrothendieckPower.lean diff --git a/Counterexamples.lean b/Counterexamples.lean index 80c2aea1aec1e6..9534f98b13c235 100644 --- a/Counterexamples.lean +++ b/Counterexamples.lean @@ -10,6 +10,7 @@ public import Counterexamples.DirectSumIsInternal public import Counterexamples.DiscreteTopologyNonDiscreteUniformity public import Counterexamples.EulerSumOfPowers public import Counterexamples.Girard +public import Counterexamples.GrothendieckPower public import Counterexamples.HeawoodUnitDistance public import Counterexamples.HomogeneousPrimeNotPrime public import Counterexamples.InvertibleModuleNotIdeal diff --git a/Counterexamples/GrothendieckPower.lean b/Counterexamples/GrothendieckPower.lean new file mode 100644 index 00000000000000..d407bdbdb979fd --- /dev/null +++ b/Counterexamples/GrothendieckPower.lean @@ -0,0 +1,1000 @@ +/- +Copyright (c) 2026 Akhil Mathew. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Akhil Mathew +-/ +module + +public import Mathlib.Algebra.Category.CommHopfAlgCat +public import Mathlib.Algebra.QuadraticAlgebra.Basic +public import Mathlib.Algebra.Ring.GeomSum +public import Mathlib.Data.FunLike.Fintype +public import Mathlib.LinearAlgebra.Dimension.Free +public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition +public import Mathlib.RingTheory.Coalgebra.GroupLike +public import Mathlib.Tactic.LinearCombination +public import Mathlib.Tactic.NormNum.BigOperators + +/-! +# A finite free group scheme of rank four that is not killed by four + +Grothendieck asked whether a finite locally free group scheme of order `n` is killed by `n`; +Deligne proved that this holds for commutative group schemes. This file formalizes a +counterexample in the non-commutative case: an affine group scheme, finite free of rank four +over the base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)`, whose fourth power map is not trivial. +Note that `R` is a finite ring of size `2^9` satisfying `4 = 0` but `2 ≠ 0`. + +The coordinate Hopf algebra of the counterexample is `A = R[U, V] / (U² - abU + b²V, V² - a²V)`, +built as a `QuadraticAlgebra` over the `QuadraticAlgebra` `B := R[V] / (V² - a²V)`. +It is finite free of rank four over `R`. With +`lambda = (1 + aU) * (1 + bV)`, the comultiplication is determined by + +* `Δ(U) = U ⊗ 1 + lambda ⊗ U`, +* `Δ(V) = V ⊗ lambda + 1 ⊗ V`, + +and `lambda` is group-like (that is, `Δ(lambda) = lambda ⊗ lambda`). +The counit sends both `U` and `V` to zero. The `n`th convolution power of +the identity — the coordinate map of the pointwise `n`th power `x ↦ xⁿ` of the +group scheme — sends `U` to `(1 + lambda + ⋯ + lambdaⁿ⁻¹) · U`. For `n = 4` this +is `2bUV ≠ 0`, while the eighth convolution power is the convolution unit +(the composite of the counit with the unit map of `A`) and in particular sends `U` to `0`. +In particular the seventh convolution power supplies an antipode, so `A` is a Hopf +algebra, and the associated group scheme has order four but is not killed by four. + +## Main definitions + +* `Counterexample.GrothendieckPower.R`: the base ring `ℤ[a, b] / (a³, b³, a²b + 2)`. +* `Counterexample.GrothendieckPower.A`: the coordinate algebra, finite free of rank four + over `R`. +* `Counterexample.GrothendieckPower.instHopfAlgebra`: the Hopf algebra structure on `A`. +* `Counterexample.GrothendieckPower.powerMap`: the `n`-th convolution power of the identity + of `A`, i.e. the coordinate map of the pointwise `n`-th power of the group scheme. +* `Counterexample.GrothendieckPower.affineGroupScheme`: the counterexample as a group object + in the opposite of the category of commutative `R`-algebras, through Mathlib's + antiequivalence with commutative Hopf algebras. + +## Main results + +* `Counterexample.GrothendieckPower.finrank_A`: `A` has rank four over `R`. Note that + `A` is also finite and free over `R`, so `A ≅ R⁴` as an `R`-module. +* `Counterexample.GrothendieckPower.powerMap_four_U_ne_zero`: the fourth power map is not + the convolution unit, since it sends `U` to `2bUV ≠ 0`. +* `Counterexample.GrothendieckPower.powerMap_eight`: the eighth power map is the convolution + unit. +* `Counterexample.GrothendieckPower.counterexample`: the combined statement: over the + nontrivial ring `R`, the algebra `A` is finite free of rank four and its fourth power map + is not the convolution unit. +* `Counterexample.GrothendieckPower.exists_hopfAlgebra_not_killed_by_finrank`: the negative + answer to Grothendieck's question, spelled out as an existence statement: there is a + nontrivial commutative ring and a commutative Hopf algebra, free of finite rank over it, + whose convolution power map at the exponent equal to its rank is not the convolution unit. +* `Counterexample.GrothendieckPower.orderOf_universalPoint`: the universal `A`-valued point + of the group scheme has order exactly eight. +* `Counterexample.GrothendieckPower.not_isCocomm`: `A` is not cocommutative, i.e. the group + scheme is noncommutative, as forced by Deligne's theorem for commutative group schemes. +* `Counterexample.GrothendieckPower.id_pow_affineGroupScheme_four_ne_one`: the group-scheme + formulation, through Mathlib's antiequivalence between commutative Hopf algebras and + affine group schemes: on the corresponding group object in `(CommAlgCat R)ᵒᵖ`, the + pointwise fourth power map — the fourth power `𝟙 _ ^ 4` of the identity in the convolution + monoid of endomorphisms — is not the constant-unit endomorphism. + +## Implementation notes + +Nontriviality of the base ring (concretely, `2b ≠ 0` in `R`) is certified by an explicit +model: the regular representation of `R` on `M = ℤ/4 × ℤ/4 × (ℤ/2)⁵`, with the actions of +`a` and `b` given by explicit additive endomorphisms and all relations checked +by `decide +kernel`. + +The polynomial identities underlying the comultiplication and the power-map computations are +proved once in an arbitrary commutative ring satisfying the relations of `R` +(`law_relations_generic`, `law_lambda_generic`, `theta_identities_generic`) using +`linear_combination`, and then transported along algebra maps. + +The generators are given short names in each successive algebra (`aB`, `bB`, `aA`, `bA`) and +in the tensor square (`a₁`, `b₁`, `u₁`, `v₁`, `u₂`, `v₂`, `l₁`, `l₂`). These are `abbrev`s, +so that they unfold definitionally; their only purpose is to keep the statements of the +polynomial certificates and of the coproduct construction readable. + +The construction of this group scheme as well as its formalization were carried out by the +AI assistants Codex (OpenAI) and Claude (Anthropic). + +## References + +* [F. Oort, J. Tate, *Group schemes of prime order*][oorttate1970]: Deligne's proof that a + commutative finite locally free group scheme is killed by its order is reproduced in §1, + and the question for possibly non-commutative group schemes is raised on p. 5. +* [J. Tate, *Finite flat group schemes*][tate1997]: records the question as open in §3.8. + +## Tags + +group scheme, Hopf algebra, counterexample +-/ + +@[expose] public section + +namespace Counterexample.GrothendieckPower + +private theorem quadratic_lift_omega {C S : Type*} [CommSemiring C] [Ring S] + {c l : C} [Algebra C S] (x : S) (hx : x * x = c • 1 + l • x) : + QuadraticAlgebra.lift (R := C) ⟨x, hx⟩ QuadraticAlgebra.omega = x := + congr_arg Subtype.val + (QuadraticAlgebra.lift.symm_apply_apply ⟨x, hx⟩) + +/-! +### An explicit faithful model of the base ring + +The base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)` is nontrivial, but this is not syntactically +obvious from its presentation. We certify it by exhibiting an explicit `R`-module: the +regular representation of `R` on `ℤ/4 × ℤ/4 × (ℤ/2)⁵`, with `a` and `b` acting through +explicit commuting additive endomorphisms. All required relations are closed by `decide +kernel`. +-/ + +/-- Reduction modulo `2`, as a ring homomorphism `ℤ/4 → ℤ/2`. -/ +def reduce : ZMod 4 →+* ZMod 2 := ZMod.castHom (by norm_num : 2 ∣ 4) _ + +/-- The additive map `ℤ/2 → ℤ/4` sending `1` to `2`. -/ +def double : ZMod 2 →+ ZMod 4 := ZMod.lift 2 ⟨2 • Int.castAddHom (ZMod 4), by decide⟩ + +@[simp] theorem reduce_double (x : ZMod 2) : reduce (double x) = 0 := by + fin_cases x <;> decide + +@[simp] theorem double_reduce (x : ZMod 4) : double (reduce x) = 2 * x := by + fin_cases x <;> decide + +/-- The additive group `ℤ/4 × ℤ/4 × (ℤ/2)⁵`, carrier of the regular representation of the +base ring `R := ℤ[a, b] / (a³, b³, a²b + 2)` (and in particular isomorphic to `R` +as an additive group). -/ +abbrev M := ZMod 4 × ZMod 4 × (Fin 5 → ZMod 2) + +/-- The additive endomorphism of `M` realizing multiplication by the generator `a` (the class +of the first variable) of the base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)`, in its regular +representation. -/ +def aEnd : AddMonoid.End M where + toFun x := + (double (x.2.2 2), double (x.2.2 4), + ![reduce x.1, x.2.2 0, reduce x.2.1, 0, x.2.2 3]) + map_zero' := by simp + map_add' x y := by simp + +/-- The additive endomorphism of `M` realizing multiplication by the generator `b` (the class +of the second variable) of the base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)`, in its regular +representation. -/ +def bEnd : AddMonoid.End M where + toFun x := + (double (x.2.2 1), x.1, + ![0, 0, x.2.2 0, reduce x.2.1, x.2.2 2]) + map_zero' := by simp + map_add' x y := by simp + +theorem aEnd_bEnd_comm : aEnd * bEnd = bEnd * aEnd := by decide +kernel + +theorem aEnd_cube : aEnd ^ 3 = 0 := by decide +kernel + +theorem bEnd_cube : bEnd ^ 3 = 0 := by decide +kernel + +theorem aEnd_sq_mul_bEnd : aEnd ^ 2 * bEnd + 2 = 0 := by decide +kernel + +theorem two_mul_bEnd_ne_zero : 2 * bEnd ≠ 0 := by decide +kernel + +private theorem generators_commute {x y : AddMonoid.End M} + (hx : x ∈ ({aEnd, bEnd} : Set (AddMonoid.End M))) + (hy : y ∈ ({aEnd, bEnd} : Set (AddMonoid.End M))) : x * y = y * x := by + simp only [Set.mem_insert_iff, Set.mem_singleton_iff] at hx hy + rcases hx with rfl | rfl <;> rcases hy with rfl | rfl <;> simp [aEnd_bEnd_comm] + +/-- The commutative subring of `AddMonoid.End M` generated by `aEnd` and `bEnd`. -/ +def WitnessRing := Subring.closure ({aEnd, bEnd} : Set (AddMonoid.End M)) + +open scoped IsMulCommutative + +instance : IsMulCommutative WitnessRing := + Subring.isMulCommutative_closure fun _ hx _ hy ↦ generators_commute hx hy + +/-- The element `aEnd`, as an element of `WitnessRing`. -/ +def aw : WitnessRing := ⟨aEnd, Subring.subset_closure (Set.mem_insert _ _)⟩ + +/-- The element `bEnd`, as an element of `WitnessRing`. -/ +def bw : WitnessRing := + ⟨bEnd, Subring.subset_closure (Set.mem_insert_of_mem _ (Set.mem_singleton _))⟩ + +@[simp] theorem aw_cube : aw ^ 3 = 0 := Subtype.ext aEnd_cube + +@[simp] theorem bw_cube : bw ^ 3 = 0 := Subtype.ext bEnd_cube + +@[simp] theorem witness_relation : aw ^ 2 * bw + 2 = 0 := + Subtype.ext aEnd_sq_mul_bEnd + +theorem two_bw_ne_zero : (2 : WitnessRing) * bw ≠ 0 := fun h ↦ + two_mul_bEnd_ne_zero (congr_arg Subtype.val h) + +instance : Nontrivial WitnessRing := ⟨⟨(2 : WitnessRing) * bw, 0, two_bw_ne_zero⟩⟩ + +/-! +### The base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)` +-/ + +noncomputable section + +open MvPolynomial + +/-- The polynomial ring `ℤ[a, b]`. -/ +abbrev P := MvPolynomial (Fin 2) ℤ + +/-- The polynomial variable `a`. -/ +abbrev ap : P := X 0 + +/-- The polynomial variable `b`. -/ +abbrev bp : P := X 1 + +/-- The ideal `(a³, b³, a²b + 2)` of `ℤ[a, b]`. -/ +def baseIdeal : Ideal P := + Ideal.span ({ap ^ 3, bp ^ 3, ap ^ 2 * bp + C 2} : Set P) + +/-- The base ring `R = ℤ[a, b] / (a³, b³, a²b + 2)`. -/ +abbrev R := P ⧸ baseIdeal + +/-- The class of the variable `a` in the base ring `R`. -/ +def a : R := Ideal.Quotient.mk baseIdeal ap + +/-- The class of the variable `b` in the base ring `R`. -/ +def b : R := Ideal.Quotient.mk baseIdeal bp + +@[simp] theorem a_cube : a ^ 3 = 0 := + Ideal.Quotient.eq_zero_iff_mem.2 <| Ideal.subset_span (by simp) + +@[simp] theorem b_cube : b ^ 3 = 0 := + Ideal.Quotient.eq_zero_iff_mem.2 <| Ideal.subset_span (by simp) + +@[simp] theorem base_relation : a ^ 2 * b + 2 = 0 := + Ideal.Quotient.eq_zero_iff_mem.2 <| Ideal.subset_span (by simp) + +/-- Evaluation of integer polynomials at `(aw, bw)` in `WitnessRing`. -/ +def evalWitness : P →+* WitnessRing := + eval₂Hom (Int.castRingHom WitnessRing) ![aw, bw] + +theorem baseIdeal_le_ker_evalWitness : baseIdeal ≤ RingHom.ker evalWitness := by + rw [baseIdeal, Ideal.span_le] + intro p hp + simp only [Set.mem_insert_iff, Set.mem_singleton_iff] at hp + rcases hp with rfl | rfl | rfl <;> simp [evalWitness, ap, bp] + +/-- The ring map `R → WitnessRing`, giving an action of `R` on `M`. -/ +def witnessHom : R →+* WitnessRing := + Ideal.Quotient.lift baseIdeal evalWitness baseIdeal_le_ker_evalWitness + +@[simp] theorem witnessHom_b : witnessHom b = bw := by + simp [witnessHom, b, evalWitness, bp] + +theorem two_b_ne_zero : (2 : R) * b ≠ 0 := by + intro h + apply two_bw_ne_zero + simpa [map_ofNat] using congr_arg witnessHom h + +instance : Nontrivial R := ⟨⟨(2 : R) * b, 0, two_b_ne_zero⟩⟩ + +/-! +### The coordinate algebra `A = R[U, V] / (U² - abU + b²V, V² - a²V)` + +The algebra `A` is realized as two nested `QuadraticAlgebra`s, so that its finite freeness of +rank four over `R` follows from the corresponding facts for each step of the tower. +-/ + +open scoped QuadraticAlgebra + +/-- The intermediate quadratic algebra `B = R[V] / (V² - a²V)`. -/ +abbrev B := QuadraticAlgebra R 0 (a ^ 2) + +/-- The generator `VB` of `B`, satisfying `VB² = a²·VB`. -/ +abbrev VB : B := ω + +@[simp] theorem VB_relation : VB ^ 2 = algebraMap R B (a ^ 2) * VB := by + simp [pow_two, QuadraticAlgebra.omega_mul_omega_eq_algebraMap] + +/-- The image of `a` in `B`. -/ +abbrev aB : B := algebraMap R B a + +/-- The image of `b` in `B`. -/ +abbrev bB : B := algebraMap R B b + +/-- The coordinate algebra `A = B[U] / (U² - abU + b²V) = R[U, V] / (U² - abU + b²V, V² - a²V)`, +finite free of rank four over the base ring `R`. -/ +abbrev A := QuadraticAlgebra B (-(bB ^ 2) * VB) (aB * bB) + +/-- The generator `U` of `A`, satisfying `U² = abU - b²V`. -/ +abbrev U : A := ω + +/-- The image `V` of `VB` in `A`. -/ +abbrev V : A := algebraMap B A VB + +/-- The image `aA` of `a` in `A`. -/ +abbrev aA : A := algebraMap R A a + +/-- The image `bA` of `b` in `A`. -/ +abbrev bA : A := algebraMap R A b + +@[simp] theorem U_relation : + U ^ 2 = algebraMap R A (a * b) * U - algebraMap R A (b ^ 2) * V := by + rw [pow_two] + unfold U V + rw [QuadraticAlgebra.omega_mul_omega_eq_mk] + ext <;> simp [VB, aB, bB, pow_two, IsScalarTower.algebraMap_apply R B A] + +@[simp] theorem V_relation : V ^ 2 = algebraMap R A (a ^ 2) * V := by + change (algebraMap B A VB) ^ 2 = algebraMap R A (a ^ 2) * algebraMap B A VB + rw [← map_pow, VB_relation, map_mul, IsScalarTower.algebraMap_apply R B A] + +instance : Module.Free R A := + Module.Free.trans (S := B) + +instance : Module.Finite R A := + Module.Finite.trans B A + +theorem finrank_B : Module.finrank R B = 2 := + QuadraticAlgebra.finrank_eq_two _ _ + +theorem finrank_A_over_B : Module.finrank B A = 2 := + QuadraticAlgebra.finrank_eq_two _ _ + +theorem finrank_A : Module.finrank R A = 4 := by + rw [← Module.finrank_mul_finrank R B A, finrank_B, finrank_A_over_B] + +/-! +### The universal property of `A` + +An `R`-algebra map out of `A = R[U, V] / (U² - abU + b²V, V² - a²V)` amounts to a pair of +elements of the target satisfying the two defining relations. The construction goes through +the tower `R → B → A`: the image of `V` determines an `R`-algebra map out of +`B = R[V] / (V² - a²V)`, which makes the target a `B`-algebra, and the image of `U` then +determines a quadratic lift out of `A`. The `B`-algebra structure depends on the chosen +image of `V`, so it is kept local to the construction and never becomes an instance: the +coproduct below, for example, uses a `B`-algebra structure on `A ⊗[R] A` different from the +canonical one through the left tensor factor. +-/ + +section UniversalProperty + +variable {S : Type*} [CommRing S] [Algebra R S] + +/-- The `R`-algebra map `B →ₐ[R] S` sending `VB` to a root of `X² - a²X`. -/ +def mkAlgHomB (v : S) (hv : v ^ 2 = algebraMap R S (a ^ 2) * v) : + B →ₐ[R] S := + QuadraticAlgebra.lift ⟨v, by rw [zero_smul, zero_add, Algebra.smul_def, ← pow_two, hv]⟩ + +theorem mkAlgHomB_VB (v : S) (hv : v ^ 2 = algebraMap R S (a ^ 2) * v) : + mkAlgHomB v hv VB = v := + quadratic_lift_omega v _ + +/-- If `S` is an arbitrary `R`-algebra, then to give an `R`-algebra map `A →ₐ[R] S` +it suffices to give a pair of elements `u` and `v` in `S` satisfying the +equations `v²=a²v` and `u²=abu-b²v`. -/ +def mkAlgHom (u v : S) (hv : v ^ 2 = algebraMap R S (a ^ 2) * v) + (hu : u ^ 2 = algebraMap R S (a * b) * u - algebraMap R S (b ^ 2) * v) : + A →ₐ[R] S := + let : Algebra B S := (mkAlgHomB v hv).toRingHom.toAlgebra + have : IsScalarTower R B S := + .of_algebraMap_eq fun r ↦ ((mkAlgHomB v hv).commutes r).symm + AlgHom.restrictScalars R (QuadraticAlgebra.lift + ⟨u, show u * u = mkAlgHomB v hv (-(bB ^ 2) * VB) * 1 + mkAlgHomB v hv (aB * bB) * u by + rw [mul_one, map_mul, map_mul, map_neg, map_pow, mkAlgHomB_VB, + (mkAlgHomB v hv).commutes, (mkAlgHomB v hv).commutes] + linear_combination hu + u * map_mul (algebraMap R S) a b - + v * map_pow (algebraMap R S) b 2⟩ : A →ₐ[B] S) + +theorem mkAlgHom_U {u v : S} (hv : v ^ 2 = algebraMap R S (a ^ 2) * v) + (hu : u ^ 2 = algebraMap R S (a * b) * u - algebraMap R S (b ^ 2) * v) : + mkAlgHom u v hv hu U = u := by + let : Algebra B S := (mkAlgHomB v hv).toRingHom.toAlgebra + exact quadratic_lift_omega u _ + +theorem mkAlgHom_V {u v : S} (hv : v ^ 2 = algebraMap R S (a ^ 2) * v) + (hu : u ^ 2 = algebraMap R S (a * b) * u - algebraMap R S (b ^ 2) * v) : + mkAlgHom u v hv hu V = v := by + let : Algebra B S := (mkAlgHomB v hv).toRingHom.toAlgebra + exact ((QuadraticAlgebra.lift _ : A →ₐ[B] S).commutes VB).trans (mkAlgHomB_VB v hv) + +end UniversalProperty + +/-! +### The comultiplication + +The polynomial identities behind the coproduct are proved once, in an arbitrary commutative +ring whose distinguished elements satisfy the relations of `R`, by `linear_combination` +certificates; they are then transported to the tensor square along the two inclusions. +-/ + +private theorem law_relations_generic {S : Type*} [CommRing S] + {a b u₁ v₁ u₂ v₂ : S} + (ha : a ^ 3 = 0) (hb : b ^ 3 = 0) (hab : a ^ 2 * b + 2 = 0) + (hv₁ : v₁ ^ 2 = a ^ 2 * v₁) (hu₁ : u₁ ^ 2 = a * b * u₁ - b ^ 2 * v₁) + (hv₂ : v₂ ^ 2 = a ^ 2 * v₂) (hu₂ : u₂ ^ 2 = a * b * u₂ - b ^ 2 * v₂) : + let l₁ := (1 + a * u₁) * (1 + b * v₁) + let l₂ := (1 + a * u₂) * (1 + b * v₂) + let dv := v₁ * l₂ + v₂ + let du := u₁ + l₁ * u₂ + dv ^ 2 = a ^ 2 * dv ∧ du ^ 2 = a * b * du - b ^ 2 * dv := by + grind + +private theorem law_lambda_generic {S : Type*} [CommRing S] + {a b u₁ v₁ u₂ v₂ : S} + (ha : a ^ 3 = 0) (hb : b ^ 3 = 0) (hab : a ^ 2 * b + 2 = 0) + (hv₁ : v₁ ^ 2 = a ^ 2 * v₁) + (hv₂ : v₂ ^ 2 = a ^ 2 * v₂) (hu₂ : u₂ ^ 2 = a * b * u₂ - b ^ 2 * v₂) : + letI l₁ := (1 + a * u₁) * (1 + b * v₁) + letI l₂ := (1 + a * u₂) * (1 + b * v₂) + letI dv := v₁ * l₂ + v₂ + letI du := u₁ + l₁ * u₂ + (1 + a * du) * (1 + b * dv) = l₁ * l₂ := by + grind + +/-- The group-like unit `(1+aU)(1+bV)` of `A` controlling the semidirect-product law. -/ +def lambda : A := (1 + aA * U) * (1 + bA * V) + +private theorem mapped_relations {S : Type*} [CommRing S] [Algebra R S] + (f : A →ₐ[R] S) : + letI aa := f aA + letI bb := f bA + letI uu := f U + letI vv := f V + aa ^ 3 = 0 ∧ bb ^ 3 = 0 ∧ aa ^ 2 * bb + 2 = 0 ∧ + vv ^ 2 = aa ^ 2 * vv ∧ uu ^ 2 = aa * bb * uu - bb ^ 2 * vv := by + split_ands + · simp [aA, ← map_pow, a_cube] + · simp [bA, ← map_pow, b_cube] + · rw [← map_ofNat f] + suffices f (aA ^ 2 * bA + 2) = 0 by simpa + suffices aA ^ 2 * bA + 2 = 0 by simp [this] + suffices algebraMap R A (a ^ 2 * b + 2) = 0 by simpa [aA, bA, -base_relation] + simp + · rw [← map_pow, V_relation, map_mul] + simp [aA, ← map_pow] + · have h : U ^ 2 = aA * bA * U - bA ^ 2 * V := by + simp [aA, bA, map_pow, map_mul] + simpa only [map_pow, map_sub, map_mul] using congr_arg f h + +open scoped TensorProduct + +/-- The inclusion of the left tensor factor `A → A ⊗[R] A`. -/ +abbrev left : A →ₐ[R] A ⊗[R] A := Algebra.TensorProduct.includeLeft + +/-- The inclusion of the right tensor factor `A → A ⊗[R] A`. -/ +abbrev right : A →ₐ[R] A ⊗[R] A := Algebra.TensorProduct.includeRight + +/-- The image of `a` in `A ⊗[R] A`. -/ +abbrev a₁ : A ⊗[R] A := left aA + +/-- The image of `b` in `A ⊗[R] A`. -/ +abbrev b₁ : A ⊗[R] A := left bA + +private theorem right_aA : right aA = a₁ := by + change (1 : A) ⊗ₜ[R] aA = aA ⊗ₜ[R] (1 : A) + rw [show aA = a • (1 : A) from Algebra.algebraMap_eq_smul_one a] + exact (TensorProduct.tmul_smul a 1 1).trans (TensorProduct.smul_tmul' a 1 1).symm + +private theorem right_bA : right bA = b₁ := by + change (1 : A) ⊗ₜ[R] bA = bA ⊗ₜ[R] (1 : A) + rw [show bA = b • (1 : A) from Algebra.algebraMap_eq_smul_one b] + exact (TensorProduct.tmul_smul b 1 1).trans (TensorProduct.smul_tmul' b 1 1).symm + +/-- The element `U ⊗ₜ 1` in `A ⊗ A`. -/ +abbrev u₁ : A ⊗[R] A := left U + +/-- The element `V ⊗ₜ 1` in `A ⊗ A`. -/ +abbrev v₁ : A ⊗[R] A := left V + +/-- The element `1 ⊗ₜ U` in `A ⊗ A`. -/ +abbrev u₂ : A ⊗[R] A := right U + +/-- The element `1 ⊗ₜ V` in `A ⊗ A`. -/ +abbrev v₂ : A ⊗[R] A := right V + +/-- The element `λ ⊗ₜ 1 = (1+aU)(1+bV) ⊗ₜ 1` in `A ⊗ A`. -/ +abbrev l₁ : A ⊗[R] A := (1 + a₁ * u₁) * (1 + b₁ * v₁) + +/-- The element `1 ⊗ₜ λ = 1 ⊗ₜ (1+aU)(1+bV)` in `A ⊗ A`. -/ +abbrev l₂ : A ⊗[R] A := (1 + a₁ * u₂) * (1 + b₁ * v₂) + +/-- The element `δ_V := V ⊗ₜ λ + 1 ⊗ₜ V` which will be the image of V under the comultiplication +on A. -/ +def deltaV : A ⊗[R] A := v₁ * l₂ + v₂ + +/-- The element `δ_U := U ⊗ₜ 1 + λ ⊗ₜ U` which will be the image of U under the comultiplication +on A. -/ +def deltaU : A ⊗[R] A := u₁ + l₁ * u₂ + +/-- The proof that `δ_V` and `δ_U` satisfy the same relations as `V` and `U`. -/ +private theorem delta_relations : + deltaV ^ 2 = a₁ ^ 2 * deltaV ∧ + deltaU ^ 2 = a₁ * b₁ * deltaU - b₁ ^ 2 * deltaV := by + obtain ⟨ha₁, hb₁, hab₁, hv₁', hu₁'⟩ := mapped_relations (S := A ⊗[R] A) left + obtain ⟨_, _, _, hv₂', hu₂'⟩ := mapped_relations (S := A ⊗[R] A) right + simp only [right_aA, right_bA] at hv₂' hu₂' + exact law_relations_generic ha₁ hb₁ hab₁ hv₁' hu₁' hv₂' hu₂' + +/-- The proof that `δ_λ := (1+aδ_U)(1+bδ_V) = λ ⊗ₜ λ` in `A ⊗ A`. -/ +private theorem delta_lambda : + (1 + a₁ * deltaU) * (1 + b₁ * deltaV) = l₁ * l₂ := by + obtain ⟨ha₁, hb₁, hab₁, hv₁', -⟩ := mapped_relations (S := A ⊗[R] A) left + obtain ⟨-, -, -, hv₂', hu₂'⟩ := mapped_relations (S := A ⊗[R] A) right + simp only [right_aA, right_bA] at hv₂' hu₂' + exact law_lambda_generic ha₁ hb₁ hab₁ hv₁' hv₂' hu₂' + +private theorem a₁_smul : a₁ = a • 1 := by + change (aA ⊗ₜ[R] (1 : A)) = a • 1 + rw [show aA = a • (1 : A) from Algebra.algebraMap_eq_smul_one a] + exact TensorProduct.smul_tmul' a 1 1 + +private theorem b₁_smul : b₁ = b • 1 := by + change (bA ⊗ₜ[R] (1 : A)) = b • 1 + rw [show bA = b • (1 : A) from Algebra.algebraMap_eq_smul_one b] + exact TensorProduct.smul_tmul' b 1 1 + +/-- The coproduct algebra homomorphism, sending `U` to `δ_U` and `V` to `δ_V`. -/ +def comul : A →ₐ[R] A ⊗[R] A := + mkAlgHom deltaU deltaV + (by rw [← left.commutes (a ^ 2), map_pow, map_pow]; exact delta_relations.1) + (by rw [← left.commutes (a * b), ← left.commutes (b ^ 2), map_mul, map_mul, map_pow, + map_pow]; exact delta_relations.2) + +theorem comul_U : comul U = deltaU := mkAlgHom_U _ _ + +theorem comul_V : comul V = deltaV := mkAlgHom_V _ _ + +theorem comul_aA : comul aA = a₁ := by + rw [comul.commutes, Algebra.algebraMap_eq_smul_one, ← a₁_smul] + +theorem comul_bA : comul bA = b₁ := by + rw [comul.commutes, Algebra.algebraMap_eq_smul_one, ← b₁_smul] + +theorem left_lambda : left lambda = l₁ := by + simp only [lambda, map_mul, map_add, map_one] + +theorem right_lambda : right lambda = l₂ := by + simp only [lambda, map_mul, map_add, map_one, right_aA, right_bA] + +@[simp] theorem comul_lambda : comul lambda = left lambda * right lambda := by + rw [left_lambda, right_lambda] + simpa [lambda, map_mul, map_add, comul_aA, comul_bA, comul_U, comul_V] using delta_lambda + +@[simp] theorem comul_U_formula : + comul U = left U + left lambda * right U := by + rw [comul_U, left_lambda] + rfl + +@[simp] theorem comul_V_formula : + comul V = left V * right lambda + right V := by + rw [comul_V, right_lambda] + rfl + +/-- Two `R`-algebra maps out of `A` agree if they agree on `U` and `V`. -/ +theorem algHom_ext {S : Type*} [Semiring S] [Algebra R S] + {f g : A →ₐ[R] S} (hU : f U = g U) (hv : f V = g V) : f = g := by + ext x + have h_embed (z : B) : + algebraMap B A z = algebraMap R A z.re + algebraMap R A z.im * V := by + have hz : z = algebraMap R B z.re + algebraMap R B z.im * VB := by + calc + z = ⟨z.re, z.im⟩ := rfl + _ = algebraMap R B z.re + z.im • VB := + QuadraticAlgebra.mk_eq_add_smul_omega z.re z.im + _ = algebraMap R B z.re + algebraMap R B z.im * VB := by + apply QuadraticAlgebra.ext <;> simp [VB] + calc + algebraMap B A z = algebraMap B A + (algebraMap R B z.re + algebraMap R B z.im * VB) := congr_arg _ hz + _ = algebraMap R A z.re + algebraMap R A z.im * V := by + rw [map_add, map_mul, ← IsScalarTower.algebraMap_apply R B A, + ← IsScalarTower.algebraMap_apply R B A] + have hB (z : B) : f (algebraMap B A z) = g (algebraMap B A z) := by + rw [h_embed] + simp only [map_add, map_mul] + rw [f.commutes, f.commutes, g.commutes, g.commutes, hv] + have hx : x = algebraMap B A x.re + algebraMap B A x.im * U := by + apply QuadraticAlgebra.ext <;> simp [U] + rw [hx, map_add, map_mul, map_add, map_mul, hB x.re, hB x.im, hU] + +/-! +### The counit and the bialgebra structure +-/ + +/-- The counit algebra homomorphism, sending `U` and `V` to zero. -/ +def counit : A →ₐ[R] R := + mkAlgHom 0 0 (by simp) (by simp) + +@[simp] theorem counit_V : counit V = 0 := mkAlgHom_V _ _ + +@[simp] theorem counit_U : counit U = 0 := mkAlgHom_U _ _ + +@[simp] theorem counit_lambda : counit lambda = 1 := by + simp [lambda] + +theorem comul_coassoc : + (Algebra.TensorProduct.assoc R R R A A A).toAlgHom.comp + ((Algebra.TensorProduct.map comul (.id R A)).comp comul) = + (Algebra.TensorProduct.map (.id R A) comul).comp comul := by + apply algHom_ext + · simp [comul_U_formula, comul_lambda, Algebra.TensorProduct.one_def, + TensorProduct.add_tmul, TensorProduct.tmul_add, add_assoc] + · simp [comul_V_formula, comul_lambda, Algebra.TensorProduct.one_def, + TensorProduct.add_tmul, TensorProduct.tmul_add, add_assoc] + +theorem counit_left : + (Algebra.TensorProduct.map counit (.id R A)).comp comul = + (Algebra.TensorProduct.lid R A).symm := by + apply algHom_ext + · simp [counit_lambda] + · simp + +theorem counit_right : + (Algebra.TensorProduct.map (.id R A) counit).comp comul = + (Algebra.TensorProduct.rid R R A).symm := by + apply algHom_ext + · simp + · simp [counit_lambda] + +/-- The bialgebra structure underlying the counterexample. -/ +instance instBialgebra : Bialgebra R A := + Bialgebra.ofAlgHom comul counit comul_coassoc counit_left counit_right + +private theorem bialgebra_comulAlgHom : Bialgebra.comulAlgHom R A = comul := rfl +private theorem bialgebra_counitAlgHom : Bialgebra.counitAlgHom R A = counit := rfl + +/-- The coordinate `lambda` is a group-like element of `A`. -/ +theorem isGroupLikeElem_lambda : IsGroupLikeElem R lambda where + counit_eq_one := by + rw [← Bialgebra.counitAlgHom_apply (R := R), bialgebra_counitAlgHom] + exact counit_lambda + comul_eq_tmul_self := by + rw [← Bialgebra.comulAlgHom_apply (R := R), bialgebra_comulAlgHom, comul_lambda] + simp + +/-! +### The convolution power maps + +The `n`-th power map of the group scheme (pointwise `x ↦ xⁿ`) corresponds, on coordinate +rings, to the `n`th convolution power of the identity of `A`. On the skew-primitive +coordinates it is controlled by the geometric sum +`1 + lambda + ⋯ + lambdaⁿ⁻¹`, which we compute from the square-zero element +`theta = lambda - 1`. +-/ + +/-- The square-zero part of the group-like coordinate. -/ +def theta : A := lambda - 1 + +private theorem theta_identities_generic {S : Type*} [CommRing S] + {aa bb uu vv : S} + (ha : aa ^ 3 = 0) (hb : bb ^ 3 = 0) (hab : aa ^ 2 * bb + 2 = 0) + (hv : vv ^ 2 = aa ^ 2 * vv) + (hu : uu ^ 2 = aa * bb * uu - bb ^ 2 * vv) : + letI th := (1 + aa * uu) * (1 + bb * vv) - 1 + th ^ 2 = 0 ∧ 2 * th = 2 * bb * vv := by + grind + +theorem theta_sq : theta ^ 2 = 0 := by + obtain ⟨ha, hb, hab, hv, hu⟩ := mapped_relations (AlgHom.id R A) + exact (theta_identities_generic ha hb hab hv hu).1 + +theorem two_theta : 2 * theta = 2 * bA * V := by + obtain ⟨ha, hb, hab, hv, hu⟩ := mapped_relations (AlgHom.id R A) + exact (theta_identities_generic ha hb hab hv hu).2 + +open WithConv + +/-- The universal point, in the convolution monoid of `R`-algebra endomorphisms. -/ +def universalPoint : WithConv (A →ₐ[R] A) := + toConv (AlgHom.id R A) + +/-- The `n`th convolution power of the identity of `A`: the coordinate ring map of the +pointwise `n`th power map of the group scheme. -/ +def powerMap (n : ℕ) : A →ₐ[R] A := + (universalPoint ^ n).ofConv + +@[simp] theorem powerMap_zero_apply (x : A) : powerMap 0 x = algebraMap R A (counit x) := by + rfl + +@[simp] theorem powerMap_one_apply (x : A) : powerMap 1 x = x := + congr_arg (fun f : WithConv (A →ₐ[R] A) ↦ f.ofConv x) (pow_one universalPoint) + +theorem powerMap_succ_U (n : ℕ) : + powerMap (n + 1) U = powerMap n U + powerMap n lambda * U := by + change (universalPoint ^ (n + 1)).ofConv U = _ + rw [pow_succ universalPoint n, AlgHom.convMul_apply, ← Bialgebra.comulAlgHom_apply, + bialgebra_comulAlgHom, comul_U_formula] + simp [universalPoint, powerMap] + +theorem powerMap_succ_V (n : ℕ) : + powerMap (n + 1) V = powerMap n V * lambda + V := by + change (universalPoint ^ (n + 1)).ofConv V = _ + rw [pow_succ universalPoint n, AlgHom.convMul_apply, ← Bialgebra.comulAlgHom_apply, + bialgebra_comulAlgHom, comul_V_formula] + simp [universalPoint, powerMap] + +theorem powerMap_succ_lambda (n : ℕ) : + powerMap (n + 1) lambda = powerMap n lambda * lambda := by + change (universalPoint ^ (n + 1)).ofConv lambda = _ + rw [pow_succ universalPoint n, AlgHom.convMul_apply, ← Bialgebra.comulAlgHom_apply, + bialgebra_comulAlgHom, comul_lambda] + simp [universalPoint, powerMap] + +theorem four_eq_zero : (4 : A) = 0 := by + obtain ⟨ha, _, hab, _, _⟩ := mapped_relations (AlgHom.id R A) + change aA ^ 3 = 0 at ha + change aA ^ 2 * bA + 2 = 0 at hab + linear_combination -(aA ^ 2 * bA - 2) * hab + aA * bA ^ 2 * ha + +theorem lambda_eq_one_add_theta : lambda = 1 + theta := by + unfold theta + ring + +theorem lambda_pow_four : lambda ^ 4 = 1 := by + have ht (k : ℕ) (hk : 2 ≤ k) : theta ^ k = 0 := pow_eq_zero_of_le hk theta_sq + rw [lambda_eq_one_add_theta] + linear_combination theta * four_eq_zero + 6 * theta_sq + 4 * ht 3 (by norm_num) + + ht 4 (by norm_num) + +theorem powerMap_lambda (n : ℕ) : powerMap n lambda = lambda ^ n := by + induction n with + | zero => simp [powerMap_zero_apply, counit_lambda] + | succ n ih => rw [powerMap_succ_lambda, ih, pow_succ lambda n] + +theorem powerMap_U (n : ℕ) : powerMap n U = (∑ i ∈ Finset.range n, lambda ^ i) * U := by + induction n with + | zero => simp [powerMap_zero_apply, counit_U] + | succ n ih => rw [powerMap_succ_U, ih, powerMap_lambda, geom_sum_succ']; ring + +theorem powerMap_V (n : ℕ) : powerMap n V = V * ∑ i ∈ Finset.range n, lambda ^ i := by + induction n with + | zero => simp [powerMap_zero_apply, counit_V] + | succ n ih => rw [powerMap_succ_V, ih, geom_sum_succ]; ring + +theorem geom_sum_four : ∑ i ∈ Finset.range 4, lambda ^ i = 2 * bA * V := by + have ht (k : ℕ) (hk : 2 ≤ k) : theta ^ k = 0 := pow_eq_zero_of_le hk theta_sq + simp only [Finset.sum_range_succ, Finset.sum_range_zero, zero_add, lambda_eq_one_add_theta] + linear_combination two_theta + (1 + theta) * four_eq_zero + 4 * theta_sq + ht 3 (by norm_num) + +theorem powerMap_four_U : powerMap 4 U = 2 * bA * U * V := by + rw [powerMap_U, geom_sum_four] + ring + +theorem two_b_U_V_ne_zero : 2 * bA * U * V ≠ 0 := by + intro h + have hOuter := congr_arg (fun x : A ↦ x.im) h + have hInner := congr_arg (fun x : B ↦ x.im) hOuter + apply two_b_ne_zero + simpa [bA, U, V, VB, IsScalarTower.algebraMap_apply R B A] using hInner + +theorem powerMap_four_U_ne_zero : powerMap 4 U ≠ 0 := by + rw [powerMap_four_U] + exact two_b_U_V_ne_zero + +theorem powerMap_four_V : powerMap 4 V = 0 := by + rw [powerMap_V, geom_sum_four] + have hv : V ^ 2 = aA ^ 2 * V := by + simp [aA, map_pow] + have hab : aA ^ 2 * bA + 2 = 0 := by + obtain ⟨_, _, hab, _, _⟩ := mapped_relations (AlgHom.id R A) + simpa using hab + rw [show V * (2 * bA * V) = 2 * bA * V ^ 2 by ring, hv] + linear_combination 2 * V * hab - V * four_eq_zero + +theorem geom_sum_eight : ∑ i ∈ Finset.range 8, lambda ^ i = 0 := by + have ht (k : ℕ) (hk : 2 ≤ k) : theta ^ k = 0 := pow_eq_zero_of_le hk theta_sq + simp only [Finset.sum_range_succ, Finset.sum_range_zero, zero_add, lambda_eq_one_add_theta] + linear_combination (2 + 7 * theta) * four_eq_zero + 56 * theta_sq + + 70 * ht 3 (by norm_num) + 56 * ht 4 (by norm_num) + 28 * ht 5 (by norm_num) + + 8 * ht 6 (by norm_num) + ht 7 (by norm_num) + +theorem powerMap_eight_U : powerMap 8 U = 0 := by + rw [powerMap_U, geom_sum_eight, zero_mul] + +theorem powerMap_eight_V : powerMap 8 V = 0 := by + rw [powerMap_V, geom_sum_eight, mul_zero] + +theorem powerMap_eight : powerMap 8 = (Algebra.ofId R A).comp counit := by + apply algHom_ext + · simp [powerMap_eight_U] + · simp [powerMap_eight_V] + +theorem universalPoint_pow_eight : universalPoint ^ 8 = 1 := + WithConv.ext powerMap_eight + +theorem universalPoint_pow_four_ne_one : universalPoint ^ 4 ≠ 1 := by + intro h + have h' : powerMap 4 = powerMap 0 := congr_arg WithConv.ofConv h + exact powerMap_four_U_ne_zero (by simpa using DFunLike.congr_fun h' U) + +/-- In the group of `A`-valued points of the group scheme, the universal point has order +exactly eight: an element of order eight on a group scheme of order four. -/ +theorem orderOf_universalPoint : orderOf universalPoint = 8 := by + simpa using orderOf_eq_prime_pow (p := 2) (n := 2) universalPoint_pow_four_ne_one + universalPoint_pow_eight + +/-! +### The Hopf algebra structure and the main statement + +Since the eighth convolution power of the identity is the convolution unit, the seventh +convolution power is a two-sided convolution inverse of the identity, that is, an antipode. +-/ + +private theorem powerMap_seven_mul_universalPoint : + toConv (powerMap 7) * universalPoint = 1 := by + simpa [powerMap, ← pow_succ] using universalPoint_pow_eight + +private theorem universalPoint_mul_powerMap_seven : + universalPoint * toConv (powerMap 7) = 1 := by + simpa [powerMap, ← pow_succ'] using universalPoint_pow_eight + +theorem antipode_right_identity : + ((Algebra.TensorProduct.lift (powerMap 7) (.id R A) fun _ ↦ Commute.all _).comp + (Bialgebra.comulAlgHom R A)) = + (Algebra.ofId R A).comp (Bialgebra.counitAlgHom R A) := by + have h := congr_arg WithConv.ofConv powerMap_seven_mul_universalPoint + change + (Algebra.TensorProduct.lmul' R).comp + ((Algebra.TensorProduct.map (powerMap 7) (.id R A)).comp + (Bialgebra.comulAlgHom R A)) = + (Algebra.ofId R A).comp (Bialgebra.counitAlgHom R A) at h + rw [← AlgHom.comp_assoc, Algebra.TensorProduct.lmul'_comp_map] at h + exact h + +theorem antipode_left_identity : + ((Algebra.TensorProduct.lift (.id R A) (powerMap 7) fun _ _ ↦ Commute.all _ _).comp + (Bialgebra.comulAlgHom R A)) = + (Algebra.ofId R A).comp (Bialgebra.counitAlgHom R A) := by + have h := congr_arg WithConv.ofConv universalPoint_mul_powerMap_seven + change + (Algebra.TensorProduct.lmul' R).comp + ((Algebra.TensorProduct.map (.id R A) (powerMap 7)).comp + (Bialgebra.comulAlgHom R A)) = + (Algebra.ofId R A).comp (Bialgebra.counitAlgHom R A) at h + rw [← AlgHom.comp_assoc, Algebra.TensorProduct.lmul'_comp_map] at h + exact h + +/-- The Hopf `R`-algebra structure on `A`. -/ +instance instHopfAlgebra : HopfAlgebra R A := + HopfAlgebra.ofAlgHom (powerMap 7) antipode_right_identity antipode_left_identity + +/-- The bundled commutative Hopf algebra representing the affine group scheme. -/ +def coordinateHopfAlgebra : CommHopfAlgCat R := + CommHopfAlgCat.of R A + +/-- The formal counterexample: over the nontrivial base ring `R`, the commutative Hopf +algebra `A` is finite free of rank four, and its fourth power map is not the convolution +unit. + +The freeness and finiteness conjuncts guarantee that the `Module.finrank` conjunct expresses +the honest rank of `A` over `R`. -/ +theorem counterexample : + Nontrivial R ∧ Module.Free R A ∧ Module.Finite R A ∧ Module.finrank R A = 4 ∧ + powerMap 4 ≠ (Algebra.ofId R A).comp counit := by + refine ⟨inferInstance, inferInstance, inferInstance, finrank_A, ?_⟩ + intro h + apply powerMap_four_U_ne_zero + simp [h] + +/-- **Grothendieck's question has a negative answer.** Grothendieck asked whether every finite +locally free group scheme of order `n` is killed by `n` — equivalently, whether the `n`-th +convolution power of the identity of a commutative Hopf algebra that is free of rank `n` over +the base ring is always the convolution unit `1` (the composite of the counit with the unit). +This is false: there is a nontrivial commutative ring `S` and a commutative `S`-Hopf algebra +`H`, free of finite rank over `S`, whose `(Module.finrank S H)`-th convolution power of the +identity is not the convolution unit. The witness is the rank-four Hopf algebra `A` over `R`; +see `counterexample`. -/ +theorem exists_hopfAlgebra_not_killed_by_finrank : + ∃ (S : Type) (_ : CommRing S) (_ : Nontrivial S) (H : Type) (_ : CommRing H) + (_ : HopfAlgebra S H) (_ : Module.Free S H) (_ : Module.Finite S H), + 0 < Module.finrank S H ∧ + WithConv.toConv (AlgHom.id S H) ^ Module.finrank S H ≠ 1 := by + refine ⟨R, inferInstance, inferInstance, A, inferInstance, inferInstance, inferInstance, + inferInstance, ?_, ?_⟩ + · rw [finrank_A]; norm_num + · rw [finrank_A] + have h8 : orderOf (WithConv.toConv (AlgHom.id R A)) = 8 := orderOf_universalPoint + exact pow_ne_one_of_lt_orderOf (by norm_num) (by rw [h8]; norm_num) + +/-! +### Non-cocommutativity + +By Deligne's theorem, a commutative finite locally free group scheme is killed by its order, +so the group scheme represented by `A` is necessarily noncommutative; equivalently, `A` is +not cocommutative. We verify this directly: the coefficient functional of `U` distinguishes +`Δ(U)` from its swap. +-/ + +/-- The `R`-linear coefficient functional of `U` in the basis `1, V, U, U * V` of `A`. -/ +private def coeffU : A →ₗ[R] R where + toFun x := x.im.re + map_add' _ _ := rfl + map_smul' _ _ := rfl + +/-- The `R`-linear coefficient functional of `V` in the basis `1, V, U, U * V` of `A`. -/ +private def coeffV : A →ₗ[R] R where + toFun x := x.re.im + map_add' _ _ := rfl + map_smul' _ _ := rfl + +/-- The Hopf algebra `A` is not cocommutative; equivalently, the affine group scheme it +represents is noncommutative. This is forced by Deligne's theorem, which affirms +Grothendieck's question for commutative group schemes. -/ +theorem not_isCocomm : ¬Coalgebra.IsCocomm R A := by + intro h + have hU := DFunLike.congr_fun h.comm_comp_comul U + simp only [LinearMap.coe_comp, LinearEquiv.coe_coe, Function.comp_apply, + ← Bialgebra.comulAlgHom_apply (R := R), bialgebra_comulAlgHom] at hU + rw [comul_U_formula] at hU + simp only [map_add, Algebra.TensorProduct.includeLeft_apply, + Algebra.TensorProduct.includeRight_apply, Algebra.TensorProduct.tmul_mul_tmul, one_mul, + mul_one, TensorProduct.comm_tmul] at hU + have h2 := congr_arg (fun z ↦ TensorProduct.lid R R (TensorProduct.map coeffU coeffV z)) hU + have hV1 : coeffV 1 = 0 := rfl + have hVU : coeffV U = 0 := rfl + have hU1 : coeffU 1 = 0 := rfl + have hUU : coeffU U = 1 := rfl + have hVlam : coeffV lambda = b := by + change lambda.re.im = b + simp [lambda, aA, bA, U, V, VB, IsScalarTower.algebraMap_apply R B A] + simp only [map_add, TensorProduct.map_tmul, TensorProduct.lid_tmul, hV1, hVU, hVlam, hU1, + hUU, smul_eq_mul, one_mul, mul_zero, add_zero, zero_add] at h2 + exact two_b_ne_zero (by rw [h2, mul_zero]) + +/-! +### The group-scheme formulation + +Mathlib's antiequivalence `commHopfAlgCatEquivCogrpCommAlgCat` identifies commutative Hopf +algebras over `R` with group objects in `(CommAlgCat R)ᵒᵖ`, the opposite of the category of +commutative `R`-algebras. This opposite category is the category of affine schemes over `R` +(via the `Spec` antiequivalence), so these group objects are exactly the affine group schemes +over `R`; here the group object is `op A`, the algebraic incarnation of `Spec A`. We work +entirely on the algebra side and do not use `AlgebraicGeometry.Spec`, as Mathlib does not yet +connect commutative Hopf algebras to group objects in `AlgebraicGeometry.Scheme`. This +section transports the counterexample across that equivalence: the pointwise fourth power map +of the resulting group object is not the constant-unit endomorphism. +-/ + +open CategoryTheory MonObj Opposite + +/-- On the group object `op A` in `(CommAlgCat R)ᵒᵖ` — the affine group scheme corresponding +to `A` — the pointwise `n`-th power map `𝟙 _ ^ n` (the `n`-th power of the identity in the +convolution monoid `CategoryTheory.Hom.monoid` of endomorphisms; for a group scheme, the +morphism `x ↦ xⁿ`, which is not in general a homomorphism) corresponds to the `n`-th +convolution power of the identity of `A`. -/ +theorem id_pow_op_unop_hom (n : ℕ) : + (𝟙 (op (CommAlgCat.of R A)) ^ n).unop.hom = powerMap n := by + induction n with + | zero => rfl + | succ n ih => + have h : (𝟙 (op (CommAlgCat.of R A)) ^ (n + 1)).unop.hom = + (Algebra.TensorProduct.lift (powerMap n) (AlgHom.id R A) + fun _ _ ↦ Commute.all _ _).comp + (Bialgebra.comulAlgHom R A) := by + simp only [pow_succ, Hom.mul_def, unop_comp, CommAlgCat.hom_comp, + CommAlgCat.mul_op_of_unop_hom, CommAlgCat.lift_unop_hom, unop_id, CommAlgCat.hom_id, + ih] + rw [h, ← Algebra.TensorProduct.lmul'_comp_map, AlgHom.comp_assoc] + rfl + +/-- The pointwise fourth power map of the group object `op A` in `(CommAlgCat R)ᵒᵖ` — the +affine group scheme corresponding to `A` — is not the constant-unit endomorphism `1`. -/ +theorem id_pow_op_four_ne_one : 𝟙 (op (CommAlgCat.of R A)) ^ 4 ≠ 1 := by + intro h + have h' : powerMap 4 = powerMap 0 := by + rw [← id_pow_op_unop_hom, ← id_pow_op_unop_hom, pow_zero, h] + exact powerMap_four_U_ne_zero (by simpa using DFunLike.congr_fun h' U) + +/-- The rank-four counterexample as an affine group scheme: the group object in the opposite +of the category of commutative `R`-algebras corresponding to `coordinateHopfAlgebra` under +Mathlib's antiequivalence `commHopfAlgCatEquivCogrpCommAlgCat`. -/ +def affineGroupScheme : Grp (CommAlgCat R)ᵒᵖ := + ((commHopfAlgCatEquivCogrpCommAlgCat R).functor.obj coordinateHopfAlgebra).unop + +theorem affineGroupScheme_X : affineGroupScheme.X = op (CommAlgCat.of R A) := rfl + +/-- The order-four affine group scheme corresponding to `A` (the group object in +`(CommAlgCat R)ᵒᵖ`) is not killed by four: its pointwise fourth power map — the fourth power +of the identity in the convolution monoid of endomorphisms — is not the constant-unit +endomorphism `1`. -/ +theorem id_pow_affineGroupScheme_four_ne_one : 𝟙 affineGroupScheme.X ^ 4 ≠ 1 := + id_pow_op_four_ne_one + +end + +end Counterexample.GrothendieckPower diff --git a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean index d4c878ac16f678..9eed3c5bf45a09 100644 --- a/Mathlib/Algebra/QuadraticAlgebra/Basic.lean +++ b/Mathlib/Algebra/QuadraticAlgebra/Basic.lean @@ -71,6 +71,10 @@ theorem omega_mul_omega_eq_add : (ω : QuadraticAlgebra R a b) * ω = a • 1 + b • ω := by ext <;> simp +theorem omega_mul_omega_eq_algebraMap : + (ω : QuadraticAlgebra R a b) * ω = algebraMap R _ a + algebraMap R _ b * ω := by + simp [omega_mul_omega_eq_add, Algebra.algebraMap_eq_smul_one] + @[simp] theorem omega_mul_mk (x y : R) : (ω : QuadraticAlgebra R a b) * ⟨x, y⟩ = ⟨a * y, x + b * y⟩ := by ext <;> simp diff --git a/docs/references.bib b/docs/references.bib index 0864bf21e7930c..a5c810a59628ba 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -4680,6 +4680,15 @@ @Book{ Okninski1991 year = {1991} } +@Article{ oorttate1970, + author = {Oort, Frans and Tate, John}, + title = {Group schemes of prime order}, + journal = {Ann. Sci. \'{E}cole Norm. Sup. (4)}, + volume = {3}, + year = {1970}, + pages = {1--21} +} + @Article{ ore33, issn = {0003486X, 19398980}, url = {http://www.jstor.org/stable/1968173}, @@ -5809,6 +5818,16 @@ @Book{ tao2010 url = {https://terrytao.files.wordpress.com/2010/02/epsilon.pdf} } +@InCollection{ tate1997, + author = {Tate, John}, + title = {Finite flat group schemes}, + booktitle = {Modular forms and {F}ermat's last theorem ({B}oston, {MA}, + 1995)}, + pages = {121--154}, + publisher = {Springer, New York}, + year = {1997} +} + @Article{ Taylor-Wiles-FLT, author = {Taylor, Richard and Wiles, Andrew}, title = {Ring-theoretic properties of certain {H}ecke algebras}, From 8d2ab6981b5112e5f3e7cde2f37d2996a7865e45 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 3 Aug 2026 13:47:15 +0000 Subject: [PATCH 1136/1300] refactor(RingTheory/DedekindDomain): make `IsDedekindDomainInv` private (#42392) Make `IsDedekindDomainInv` private, because is the same as `IsDedekindDomain`. See [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/three.20dedekind.20domains/near/574535735). --- .../DedekindDomain/Ideal/Basic.lean | 287 +++++++++--------- 1 file changed, 144 insertions(+), 143 deletions(-) diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean index e328c4ba9d3ad6..fa2d336e1527a5 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Basic.lean @@ -20,14 +20,12 @@ Further results on the structure of ideals in a Dedekind domain are found in ## Main definitions -- `IsDedekindDomainInv` alternatively defines a Dedekind domain as an integral domain where - every nonzero fractional ideal is invertible. -- `isDedekindDomainInv_iff` shows that this does not depend on the choice of field of - fractions. +- `isDedekindDomain_iff_mul_inv_cancel` shows an integral domain is + a Dedekind domain iff every nonzero fractional ideal is invertible. ## Main results: -- `isDedekindDomain_iff_isDedekindDomainInv` +- `isDedekindDomain_iff_mul_inv_cancel` - `Ideal.uniqueFactorizationMonoid` ## Implementation notes @@ -49,40 +47,18 @@ to add a `(h : ¬ IsField A)` assumption whenever this is explicitly needed. dedekind domain, dedekind ring -/ -@[expose] public section - variable (R A K : Type*) [CommRing R] [CommRing A] [Field K] open scoped nonZeroDivisors Polynomial -section Inverse - -section IsDedekindDomainInv - -variable [IsDomain A] -/-- A Dedekind domain is an integral domain such that every fractional ideal has an inverse. - -This is equivalent to `IsDedekindDomain`. -In particular we provide a `CommGroupWithZero` instance, -assuming `IsDedekindDomain A`, which implies `IsDedekindDomainInv`. For **integral** domain, -`IsDedekindDomain`(`Inv`) implies only `Ideal.isCancelMulZero`. --/ -def IsDedekindDomainInv : Prop := - ∀ I ≠ (⊥ : FractionalIdeal A⁰ (FractionRing A)), I * I⁻¹ = 1 - -open FractionalIdeal +public section Inverse -variable {R A K} +variable [Algebra A K] [IsFractionRing A K] -theorem isDedekindDomainInv_iff [Algebra A K] [IsFractionRing A K] : - IsDedekindDomainInv A ↔ ∀ I ≠ (⊥ : FractionalIdeal A⁰ K), I * I⁻¹ = 1 := by - let h : FractionalIdeal A⁰ (FractionRing A) ≃+* FractionalIdeal A⁰ K := - FractionalIdeal.mapEquiv (FractionRing.algEquiv A K) - refine h.toEquiv.forall_congr (fun {x} => ?_) - rw [← h.toEquiv.apply_eq_iff_eq] - simp [h] +variable {A K} -theorem FractionalIdeal.adjoinIntegral_eq_one_of_isUnit [Algebra A K] [IsFractionRing A K] (x : K) +variable {R} [IsDomain A] in +theorem FractionalIdeal.adjoinIntegral_eq_one_of_isUnit (x : K) (hx : IsIntegral A x) (hI : IsUnit (adjoinIntegral A⁰ x hx)) : adjoinIntegral A⁰ x hx = 1 := by set I := adjoinIntegral A⁰ x hx have mul_self : IsIdempotentElem I := by @@ -92,92 +68,6 @@ theorem FractionalIdeal.adjoinIntegral_eq_one_of_isUnit [Algebra A K] [IsFractio convert! congr_arg (· * I⁻¹) mul_self <;> simp only [(mul_inv_cancel_iff_isUnit K).mpr hI, mul_assoc, mul_one] -namespace IsDedekindDomainInv - -variable [Algebra A K] [IsFractionRing A K] (h : IsDedekindDomainInv A) {I J : FractionalIdeal A⁰ K} -include h - -/-- `IsDedekindDomainInv A` implies that fractional ideals over it form a commutative group with -zero. -/ -noncomputable abbrev commGroupWithZero : CommGroupWithZero (FractionalIdeal A⁰ K) where - inv_zero := inv_zero' _ - mul_inv_cancel := isDedekindDomainInv_iff.mp h - div_eq_mul_inv I J := by - obtain rfl | hJ := eq_or_ne J 0 - · simp [inv_zero'] - refine le_antisymm ?_ ((FractionalIdeal.le_div_iff_mul_le hJ).2 ?_) - · suffices I / J * J ≤ I by - simpa [mul_assoc, isDedekindDomainInv_iff.mp h _ hJ] using mul_left_mono (a := J⁻¹) this - simp [FractionalIdeal.mul_le, mem_div_iff_of_ne_zero hJ] - · rw [mul_assoc, mul_comm _ J, isDedekindDomainInv_iff.mp h _ hJ, mul_one] - -theorem isNoetherianRing : IsNoetherianRing A := by - let := h.commGroupWithZero (K := FractionRing A) - refine isNoetherianRing_iff.mpr ⟨fun I : Ideal A => ?_⟩ - by_cases hI : I = ⊥ - · rw [hI]; apply Submodule.fg_bot - have hI : (I : FractionalIdeal A⁰ (FractionRing A)) ≠ 0 := coeIdeal_ne_zero.mpr hI - exact I.fg_of_isUnit (IsFractionRing.injective A (FractionRing A)) hI.isUnit - -theorem integrallyClosed : IsIntegrallyClosed A := by - let := h.commGroupWithZero (K := FractionRing A) - -- It suffices to show that for integral `x`, - -- `A[x]` (which is a fractional ideal) is in fact equal to `A`. - refine (isIntegrallyClosed_iff (FractionRing A)).mpr (fun {x hx} => ?_) - rw [← Set.mem_range, ← Algebra.mem_bot, ← Subalgebra.mem_toSubmodule, Algebra.toSubmodule_bot, - Submodule.one_eq_span, ← coe_spanSingleton A⁰ (1 : FractionRing A), spanSingleton_one, ← - FractionalIdeal.adjoinIntegral_eq_one_of_isUnit x hx (Ne.isUnit _)] - · exact mem_adjoinIntegral_self A⁰ x hx - · exact fun h => one_ne_zero (eq_zero_iff.mp h 1 (Algebra.adjoin A {x}).one_mem) - -open Ring - -theorem dimensionLEOne : DimensionLEOne A := by - -- We're going to show that `P` is maximal because any (maximal) ideal `M` - -- that is strictly larger would be `⊤`. - let := h.commGroupWithZero (K := FractionRing A) - constructor - rintro P P_ne hP - refine Ideal.isMaximal_def.mpr ⟨hP.ne_top, fun M hM => ?_⟩ - -- We may assume `P` and `M` (as fractional ideals) are nonzero. - have P'_ne : (P : FractionalIdeal A⁰ (FractionRing A)) ≠ 0 := coeIdeal_ne_zero.mpr P_ne - have M'_ne : (M : FractionalIdeal A⁰ (FractionRing A)) ≠ 0 := coeIdeal_ne_zero.mpr hM.ne_bot - -- In particular, we'll show `M⁻¹ * P ≤ P` - suffices (M⁻¹ : FractionalIdeal A⁰ (FractionRing A)) * P ≤ P by - rw [eq_top_iff, ← coeIdeal_le_coeIdeal (FractionRing A), coeIdeal_top] - calc - (1 : FractionalIdeal A⁰ (FractionRing A)) = (↑M)⁻¹ * P * ((↑P)⁻¹ * M) := by - simp [mul_assoc, *] - _ ≤ P * ((↑P)⁻¹ * M) := by gcongr - _ = M := by simp [*] - -- Suppose we have `x ∈ M⁻¹ * P`, then in fact `x = algebraMap _ _ y` for some `y`. - intro x hx - have le_one : (M⁻¹ : FractionalIdeal A⁰ (FractionRing A)) * P ≤ 1 := by - rw [← inv_mul_cancel₀ M'_ne]; gcongr - obtain ⟨y, _hy, rfl⟩ := (mem_coeIdeal _).mp (le_one hx) - -- Since `M` is strictly greater than `P`, let `z ∈ M \ P`. - obtain ⟨z, hzM, hzp⟩ := SetLike.exists_of_lt hM - -- We have `z * y ∈ M * (M⁻¹ * P) = P`. - have zy_mem := mul_mem_mul (mem_coeIdeal_of_mem A⁰ hzM) hx - rw [← map_mul, ← mul_assoc, mul_inv_cancel₀ M'_ne, one_mul] at zy_mem - obtain ⟨zy, hzy, zy_eq⟩ := (mem_coeIdeal A⁰).mp zy_mem - rw [IsFractionRing.injective A (FractionRing A) zy_eq] at hzy - -- But `P` is a prime ideal, so `z ∉ P` implies `y ∈ P`, as desired. - exact mem_coeIdeal_of_mem A⁰ (Or.resolve_left (hP.mem_or_mem hzy) hzp) - -/-- Showing one side of the equivalence between the definitions -`IsDedekindDomainInv` and `IsDedekindDomain` of Dedekind domains. -/ -theorem isDedekindDomain : IsDedekindDomain A := - { h.isNoetherianRing, h.dimensionLEOne, h.integrallyClosed with } - -end IsDedekindDomainInv - -end IsDedekindDomainInv - -variable [Algebra A K] [IsFractionRing A K] - -variable {A K} - theorem FractionalIdeal.one_mem_inv_coe_ideal [IsDomain A] {I : Ideal A} (hI : I ≠ ⊥) : (1 : K) ∈ (I : FractionalIdeal A⁰ K)⁻¹ := by rw [mem_inv_iff (coeIdeal_ne_zero.mpr hI)] @@ -324,19 +214,145 @@ theorem coe_ideal_mul_inv (I : Ideal A) (hI0 : I ≠ ⊥) : I * (I : FractionalI | zero => rw [pow_zero]; exact one_mem_inv_coe_ideal hI0 | succ i ih => rw [pow_succ']; exact x_mul_mem _ ih +end FractionalIdeal + +end Inverse + +section IsDedekindDomainInv + +/-- An integral domain is a Dedekind domain if every fractional ideal has an inverse. +This is an auxiliary definition used to +prove `isDedekindDomain_iff_mul_inv_cancel` and `FractionalIdeal.semifield`. -/ +def IsDedekindDomainInv [IsDomain A] : Prop := + ∀ I ≠ (⊥ : FractionalIdeal A⁰ (FractionRing A)), I * I⁻¹ = 1 + +open FractionalIdeal + +variable {A K} [Algebra A K] [IsFractionRing A K] + +variable {R} in +theorem isDedekindDomainInv_iff [IsDomain A] : + IsDedekindDomainInv A ↔ ∀ I ≠ (⊥ : FractionalIdeal A⁰ K), I * I⁻¹ = 1 := by + let h : FractionalIdeal A⁰ (FractionRing A) ≃+* FractionalIdeal A⁰ K := + FractionalIdeal.mapEquiv (FractionRing.algEquiv A K) + refine h.toEquiv.forall_congr (fun {x} => ?_) + rw [← h.toEquiv.apply_eq_iff_eq] + simp [h] + +namespace IsDedekindDomainInv + +variable (K) [IsDomain A] (h : IsDedekindDomainInv A) {I J : FractionalIdeal A⁰ K} +include h + +/-- `IsDedekindDomainInv A` implies that fractional ideals over it form a commutative group with +zero. -/ +noncomputable abbrev commGroupWithZero : CommGroupWithZero (FractionalIdeal A⁰ K) where + inv_zero := inv_zero' _ + mul_inv_cancel := isDedekindDomainInv_iff.mp h + div_eq_mul_inv I J := by + obtain rfl | hJ := eq_or_ne J 0 + · simp [inv_zero'] + refine le_antisymm ?_ ((FractionalIdeal.le_div_iff_mul_le hJ).2 ?_) + · suffices I / J * J ≤ I by + simpa [mul_assoc, isDedekindDomainInv_iff.mp h _ hJ] using mul_left_mono (a := J⁻¹) this + simp [FractionalIdeal.mul_le, mem_div_iff_of_ne_zero hJ] + · rw [mul_assoc, mul_comm _ J, isDedekindDomainInv_iff.mp h _ hJ, mul_one] + +theorem isNoetherianRing : IsNoetherianRing A := by + let := h.commGroupWithZero (FractionRing A) + refine isNoetherianRing_iff.mpr ⟨fun I : Ideal A => ?_⟩ + by_cases hI : I = ⊥ + · rw [hI]; apply Submodule.fg_bot + have hI : (I : FractionalIdeal A⁰ (FractionRing A)) ≠ 0 := coeIdeal_ne_zero.mpr hI + exact I.fg_of_isUnit (IsFractionRing.injective A (FractionRing A)) hI.isUnit + +theorem integrallyClosed : IsIntegrallyClosed A := by + let := h.commGroupWithZero (FractionRing A) + -- It suffices to show that for integral `x`, + -- `A[x]` (which is a fractional ideal) is in fact equal to `A`. + refine (isIntegrallyClosed_iff (FractionRing A)).mpr (fun {x hx} => ?_) + rw [← Set.mem_range, ← Algebra.mem_bot, ← Subalgebra.mem_toSubmodule, Algebra.toSubmodule_bot, + Submodule.one_eq_span, ← coe_spanSingleton A⁰ (1 : FractionRing A), spanSingleton_one, ← + FractionalIdeal.adjoinIntegral_eq_one_of_isUnit x hx (Ne.isUnit _)] + · exact mem_adjoinIntegral_self A⁰ x hx + · exact fun h => one_ne_zero (eq_zero_iff.mp h 1 (Algebra.adjoin A {x}).one_mem) + +open Ring + +theorem dimensionLEOne : DimensionLEOne A := by + -- We're going to show that `P` is maximal because any (maximal) ideal `M` + -- that is strictly larger would be `⊤`. + let := h.commGroupWithZero (K := FractionRing A) + constructor + rintro P P_ne hP + refine Ideal.isMaximal_def.mpr ⟨hP.ne_top, fun M hM => ?_⟩ + -- We may assume `P` and `M` (as fractional ideals) are nonzero. + have P'_ne : (P : FractionalIdeal A⁰ (FractionRing A)) ≠ 0 := coeIdeal_ne_zero.mpr P_ne + have M'_ne : (M : FractionalIdeal A⁰ (FractionRing A)) ≠ 0 := coeIdeal_ne_zero.mpr hM.ne_bot + -- In particular, we'll show `M⁻¹ * P ≤ P` + suffices (M⁻¹ : FractionalIdeal A⁰ (FractionRing A)) * P ≤ P by + rw [eq_top_iff, ← coeIdeal_le_coeIdeal (FractionRing A), coeIdeal_top] + calc + (1 : FractionalIdeal A⁰ (FractionRing A)) = (↑M)⁻¹ * P * ((↑P)⁻¹ * M) := by + simp [mul_assoc, *] + _ ≤ P * ((↑P)⁻¹ * M) := by gcongr + _ = M := by simp [*] + -- Suppose we have `x ∈ M⁻¹ * P`, then in fact `x = algebraMap _ _ y` for some `y`. + intro x hx + have le_one : (M⁻¹ : FractionalIdeal A⁰ (FractionRing A)) * P ≤ 1 := by + rw [← inv_mul_cancel₀ M'_ne]; gcongr + obtain ⟨y, _hy, rfl⟩ := (mem_coeIdeal _).mp (le_one hx) + -- Since `M` is strictly greater than `P`, let `z ∈ M \ P`. + obtain ⟨z, hzM, hzp⟩ := SetLike.exists_of_lt hM + -- We have `z * y ∈ M * (M⁻¹ * P) = P`. + have zy_mem := mul_mem_mul (mem_coeIdeal_of_mem A⁰ hzM) hx + rw [← map_mul, ← mul_assoc, mul_inv_cancel₀ M'_ne, one_mul] at zy_mem + obtain ⟨zy, hzy, zy_eq⟩ := (mem_coeIdeal A⁰).mp zy_mem + rw [IsFractionRing.injective A (FractionRing A) zy_eq] at hzy + -- But `P` is a prime ideal, so `z ∉ P` implies `y ∈ P`, as desired. + exact mem_coeIdeal_of_mem A⁰ (Or.resolve_left (hP.mem_or_mem hzy) hzp) + +end IsDedekindDomainInv + +/-- `IsDedekindDomain` and `IsDedekindDomainInv` are equivalent ways +to express that an integral domain is a Dedekind domain. -/ +theorem isDedekindDomain_iff_isDedekindDomainInv [IsDomain A] : + IsDedekindDomain A ↔ IsDedekindDomainInv A := by + refine ⟨fun _ I hI => ?_, fun h => + { h.isNoetherianRing, h.dimensionLEOne, h.integrallyClosed with }⟩ + obtain ⟨a, J, ha, hJ⟩ := exists_eq_spanSingleton_mul (K := FractionRing A) I + suffices h₂ : I * (spanSingleton A⁰ (algebraMap _ _ a) * (J : FractionalIdeal A⁰ _)⁻¹) = 1 by + rw [mul_inv_cancel_iff] + exact ⟨spanSingleton A⁰ (algebraMap _ _ a) * (J : FractionalIdeal A⁰ _)⁻¹, h₂⟩ + subst hJ + rw [mul_assoc, mul_left_comm (J : FractionalIdeal A⁰ _), coe_ideal_mul_inv, mul_one, + spanSingleton_mul_spanSingleton, inv_mul_cancel₀, spanSingleton_one] + · exact mt ((injective_iff_map_eq_zero (algebraMap A _)).mp (IsFractionRing.injective A _) _) ha + · exact coeIdeal_ne_zero.mp (right_ne_zero_of_mul hI) + +public theorem isDedekindDomain_iff_mul_inv_cancel [IsDomain A] : + IsDedekindDomain A ↔ ∀ I ≠ (⊥ : FractionalIdeal A⁰ K), I * I⁻¹ = 1 := + isDedekindDomain_iff_isDedekindDomainInv.trans isDedekindDomainInv_iff + +end IsDedekindDomainInv + +public section IsDedekindDomain + +variable {R A} +variable [IsDedekindDomain A] [Algebra A K] [IsFractionRing A K] + +open FractionalIdeal Ideal + +namespace FractionalIdeal + noncomputable instance semifield : Semifield (FractionalIdeal A⁰ K) where __ := coeIdeal_injective.nontrivial __ : CommSemiring (FractionalIdeal A⁰ K) := inferInstance - __ := IsDedekindDomainInv.commGroupWithZero fun I hI ↦ by - obtain ⟨a, J, ha, hJ⟩ := exists_eq_spanSingleton_mul (K := FractionRing A) I - suffices h₂ : I * (spanSingleton A⁰ (algebraMap _ _ a) * (J : FractionalIdeal A⁰ _)⁻¹) = 1 by - rw [mul_inv_cancel_iff] - exact ⟨spanSingleton A⁰ (algebraMap _ _ a) * (J : FractionalIdeal A⁰ _)⁻¹, h₂⟩ - subst hJ - rw [mul_assoc, mul_left_comm (J : FractionalIdeal A⁰ _), coe_ideal_mul_inv, mul_one, - spanSingleton_mul_spanSingleton, inv_mul_cancel₀, spanSingleton_one] - · exact mt ((injective_iff_map_eq_zero (algebraMap A _)).mp (IsFractionRing.injective A _) _) ha - · exact coeIdeal_ne_zero.mp (right_ne_zero_of_mul hI) + inv_zero := inv_zero' K + mul_inv_cancel := isDedekindDomain_iff_mul_inv_cancel.mp ‹_› + div_eq_mul_inv := by + let := (isDedekindDomain_iff_isDedekindDomainInv.mp ‹_›).commGroupWithZero K + exact div_eq_mul_inv nnqsmul := _ instance : PosMulStrictMono (FractionalIdeal A⁰ K) := PosMulMono.toPosMulStrictMono @@ -365,21 +381,6 @@ instance : PosMulReflectLE (Ideal A) where end FractionalIdeal -/-- `IsDedekindDomain` and `IsDedekindDomainInv` are equivalent ways -to express that an integral domain is a Dedekind domain. -/ -theorem isDedekindDomain_iff_isDedekindDomainInv [IsDomain A] : - IsDedekindDomain A ↔ IsDedekindDomainInv A := - ⟨fun _h _I => mul_inv_cancel₀, fun h => h.isDedekindDomain⟩ - -end Inverse - -section IsDedekindDomain - -variable {R A} -variable [IsDedekindDomain A] [Algebra A K] [IsFractionRing A K] - -open FractionalIdeal Ideal - noncomputable instance Ideal.isCancelMulZero : IsCancelMulZero (Ideal A) := Function.Injective.isCancelMulZero (coeIdealHom A⁰ (FractionRing A)) coeIdeal_injective (map_zero _) (map_mul _) From 93594942ef3b93fae5272d7bf368676ff40f8eb1 Mon Sep 17 00:00:00 2001 From: Kevin Wilson <1527442+khwilson@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:17:52 +0000 Subject: [PATCH 1137/1300] feat(Topology/Semicontinuity/Hemicontinuity): sequential characterizations of hemicontinuity (#40377) We prove two things: First, we prove a sequential characterization of lower hemicontinuity in terms of sequences. `LowerHemicontinuousAt.of_sequences` Second, we show that upper and lower hemicontinuity are preserved under uniform limits in the Hausdorff uniformity. N.B. the increase in imports comes from importing uniformity structures (including the Hausdorff uniformity). If preferred, I can break these uniform convergence lemmas out into their own file to minimize imports in this file. AI Disclosure: Initial proof outlined by me, lean statement written by me, initial draft of lean proof provided by claude code, then I provided edits, comments, and docstrings - [x] depends on: #38601 Co-authored-by: Kevin H Wilson --- .../Semicontinuity/Hemicontinuity.lean | 179 +++++++++++++++++- 1 file changed, 174 insertions(+), 5 deletions(-) diff --git a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean index b7271bbeb3fcdd..818c5ace8171f0 100644 --- a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean +++ b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean @@ -9,6 +9,9 @@ public import Mathlib.Topology.Semicontinuity.Defs public import Mathlib.Topology.NhdsWithin public import Mathlib.Topology.Separation.Regular public import Mathlib.Topology.Defs.Sequences +public import Mathlib.Topology.UniformSpace.Closeds +public import Mathlib.Topology.UniformSpace.UniformConvergence +import Mathlib.Topology.UniformSpace.Compact import Mathlib.Topology.Sequences /-! # Hemicontinuity @@ -21,9 +24,13 @@ public section open Set Filter Topology -variable {α β : Type*} [TopologicalSpace α] [TopologicalSpace β] +variable {α β : Type*} [TopologicalSpace α] variable {f g : α → Set β} {s : Set α} {x : α} +section facts + +variable [TopologicalSpace β] + /-! ### Basic facts -/ lemma upperHemicontinuousWithinAt_iff_forall_isOpen : @@ -392,18 +399,84 @@ lemma UpperHemicontinuousAt.mem_of_tendsto {ι : Type*} [RegularSpace β] {x₀ simp only [← subset_interior_iff_mem_nhdsSet, preimage_ofPred_eq, mem_ofPred_eq] at hn exact interior_subset <| hn hyn +/-- **Sequential characterization of lower hemicontinuity**: +A set-valued function `f : α → Set β` is lower hemicontinuous at `x₀ : α` if for every sequence +`x : ℕ → α` tending to `x₀` and every `y₀ ∈ f x₀`, there exists a sequence `y : ℕ → β` with +`y n ∈ f (x n)` for all `n` that tends to `y₀`. -/ +lemma LowerHemicontinuousAt.of_sequences {x₀ : α} [(𝓝 x₀).IsCountablyGenerated] + (h : ∀ x : ℕ → α, Tendsto x atTop (𝓝 x₀) → + ∀ y₀ ∈ f x₀, ∃ y : ℕ → β, (∀ n, y n ∈ f (x n)) ∧ Tendsto y atTop (𝓝 y₀)) : + LowerHemicontinuousAt f x₀ := by + rw [lowerHemicontinuousAt_iff] + intro U hU ⟨y₀, hy₀f, hy₀U⟩ + by_contra hc + rw [Filter.not_eventually] at hc + obtain ⟨x, hx, hxU⟩ := exists_seq_forall_of_frequently hc + obtain ⟨y, hy_mem, hy_lim⟩ := h x hx y₀ hy₀f + obtain ⟨n, hn⟩ := (hy_lim.eventually (hU.mem_nhds hy₀U)).exists + exact hxU n ⟨y n, hy_mem n, hn⟩ + +/-- **Sequential characterization of lower hemicontinuity**: +If `f : α → Set β` is lower hemicontinuous at `x₀`, `y₀ ∈ f x₀`, `𝓝 y₀` is countably generated, and +`x : ℕ → α` tends to `x₀`, then there is a companion sequence `y : ℕ → β` that tends to `y₀` with +`y n ∈ f (x n)` for all sufficiently large `n`. + +This is a partial converse of `LowerHemicontinuousAt.of_sequences`. -/ +lemma LowerHemicontinuousAt.exists_seq_tendsto {x₀ : α} (hf : LowerHemicontinuousAt f x₀) + {x : ℕ → α} (hx : Tendsto x atTop (𝓝 x₀)) {y₀ : β} (hy₀ : y₀ ∈ f x₀) + [(𝓝 y₀).IsCountablyGenerated] : + ∃ y : ℕ → β, (∀ᶠ n in atTop, y n ∈ f (x n)) ∧ Tendsto y atTop (𝓝 y₀) := by + classical + obtain ⟨U, hU, hUbasis⟩ := (nhds_basis_opens y₀).exists_antitone_subbasis + have hev (k) : ∀ᶠ n in atTop, (f (x n) ∩ U k).Nonempty := + hx.eventually <| (lowerHemicontinuousAt_iff.mp hf) (U k) (hU k).2 ⟨y₀, hy₀, (hU k).1⟩ + -- For each `n`, find the largest `k ≤ n` where `U k` intersects `f (x n)`. + let g : ℕ → ℕ := fun n ↦ Nat.findGreatest (fun k ↦ (f (x n) ∩ U k).Nonempty) n + have key (n k) (hkn : k ≤ n) (hk : (f (x n) ∩ U k).Nonempty) : (f (x n) ∩ U (g n)).Nonempty := + Nat.findGreatest_spec (P := fun k ↦ (f (x n) ∩ U k).Nonempty) hkn hk + -- Define `y n` to be some element of `f (x n) ∩ U (g n)` (or be arbitrary) + let y : ℕ → β := fun n ↦ if h : (f (x n) ∩ U (g n)).Nonempty then h.some else y₀ + have hy (n) (h : (f (x n) ∩ U (g n)).Nonempty) : y n ∈ f (x n) ∩ U (g n) := by + simpa only [y, dif_pos h] using h.some_mem + refine ⟨y, (hev 0).mono (by grind), ?_⟩ + -- Have to show for all `k`, eventually, all `y n ∈ U k`. + rw [hUbasis.tendsto_right_iff] + intro k _ + filter_upwards [hev k, eventually_ge_atTop k] with n hk hkn + exact hUbasis.antitone (Nat.le_findGreatest hkn hk) (hy n (key n k hkn hk)).2 + +/-- **Lower hemicontinuity along a countably generated filter** (subsequence form): +if `f : α → Set β` is lower hemicontinuous at `x₀`, `y₀ ∈ f x₀`, `𝓝 y₀` is countably generated and +`x : ι → α` tends to `x₀` along a nontrivial countably generated filter `l`, then some sequence +`u : ℕ → ι` converging to `l` admits a companion `y : ℕ → β` tending to `y₀` with +`y k ∈ f (x (u k))` eventually. + +For a general filter one must pass to the subsequence `u`: the "same-index" conclusion already +fails for `l = pure i₀` (which is `NeBot` and countably generated). When `l = atTop` one may take +`u = id`, recovering `LowerHemicontinuousAt.exists_seq_tendsto`. -/ +lemma LowerHemicontinuousAt.exists_subseq_tendsto {ι : Type*} {l : Filter ι} [l.NeBot] + [l.IsCountablyGenerated] {x₀ : α} (hf : LowerHemicontinuousAt f x₀) {x : ι → α} + (hx : Tendsto x l (𝓝 x₀)) {y₀ : β} (hy₀ : y₀ ∈ f x₀) [(𝓝 y₀).IsCountablyGenerated] : + ∃ (u : ℕ → ι) (y : ℕ → β), Tendsto u atTop l ∧ + (∀ᶠ k in atTop, y k ∈ f (x (u k))) ∧ Tendsto y atTop (𝓝 y₀) := by + obtain ⟨u, hu⟩ := Filter.exists_seq_tendsto l + obtain ⟨y, hy_mem, hy_lim⟩ := hf.exists_seq_tendsto (hx.comp hu) hy₀ + exact ⟨u, y, hu, hy_mem, hy_lim⟩ + + + +end facts + /-! ### Open lower sections -/ -omit [TopologicalSpace β] in /-- A correspondence `f : α → Set β` has open lower sections if and only if its *lower inverse* -(i.e., `b : β ↦ (f ⁻¹' (Iic {b}ᶜ))ᶜ = {x | b ∈ f x}`) sends every point to an open set. -/ +(i.e., `b : β ↦ (f ⁻¹' Iic {b}ᶜ)ᶜ = {x | b ∈ f x}`) sends every point to an open set. -/ lemma hasOpenLowerSections_iff_isOpen_compl_preimage_Iic_compl : HasOpenLowerSections f ↔ ∀ b, IsOpen (f ⁻¹' Iic {b}ᶜ)ᶜ := by have h (b : β) : (f ⁻¹' (Iic {b}ᶜ))ᶜ = {x | b ∈ f x} := by simp [Set.ext_iff, Iic, Set.mem_compl_iff] simp_rw [h, hasOpenLowerSections_iff_isOpen] -omit [TopologicalSpace β] in /-- A correspondence `f : α → Set β` has open lower sections if and only if its *upper inverse* (i.e., `b : β ↦ f ⁻¹' (Iic {b}ᶜ) = {x | b ∉ f x}`) sends every point to a closed set. -/ lemma hasOpenLowerSections_iff_isClosed_preimage_Iic : @@ -415,7 +488,7 @@ lemma hasOpenLowerSections_iff_isClosed_preimage_Iic : /-- A lower hemicontinuous function intersected with a function with an open graph is lower hemicontinuous. -/ -lemma LowerHemicontinuous.inter_hasOpenCGraph {f g : α → Set β} +lemma LowerHemicontinuous.inter_hasOpenCGraph [TopologicalSpace β] {f g : α → Set β} (hf : LowerHemicontinuous f) (hg : HasOpenCGraph g) : LowerHemicontinuous (fun x ↦ f x ∩ g x) := by simp_rw [lowerHemicontinuous_iff_isOpen_inter_nonempty] at ⊢ hf @@ -427,3 +500,99 @@ lemma LowerHemicontinuous.inter_hasOpenCGraph {f g : α → Set β} ⟨hxU, y, hyf, hyt, hyV⟩⟩ intro x' ⟨hx'U, z, hzf, hzt, hzV⟩ exact ⟨z, ⟨hzf, hUV (Set.mk_mem_prod hx'U hzV)⟩, hzt⟩ + +/-! ### Uniform Limits + +Like continuity, hemicontinuity is preserved under certain uniform limits, where the uniformity on +the target `Set β` is the Hausdorff uniformity. In this section, we prove this result for both +lower hemicontinuous and upper hemicontinuous limits. +-/ + +section limits + +variable {ι : Type*} {F : ι → α → Set β} {l : Filter ι} [NeBot l] +variable [UniformSpace β] +open UniformSpace +attribute [local instance] UniformSpace.hausdorff + +/-- A net of lower hemicontinuous set-valued functions converging uniformly on `s` (along a +filter `l`) in the Hausdorff uniformity has a lower hemicontinuous limit on `s` -/ +theorem TendstoUniformlyOn.lowerHemicontinuousOn (htendsto : TendstoUniformlyOn F f l s) + (hF : ∀ n, LowerHemicontinuousOn (F n) s) : LowerHemicontinuousOn f s := by + rw [lowerHemicontinuousOn_iff] + intro x₀ hx₀s + rw [lowerHemicontinuousWithinAt_iff] + intro V hV ⟨y₀, hy₀f, hy₀V⟩ + -- Obtain entourages W, U ∈ 𝓤 β with U ○ U ○ U ⊆ W + obtain ⟨W, hW, hWsub⟩ := UniformSpace.mem_nhds_iff.mp (hV.mem_nhds hy₀V) + obtain ⟨U₁, hU₁, hU₁sym, hU₁comp⟩ := comp_symm_mem_uniformity_sets hW + obtain ⟨U, hU, hUsym, hUcomp⟩ := comp_symm_mem_uniformity_sets hU₁ + have hU_le_U₁ : U ⊆ U₁ := fun _p hp => hUcomp ⟨_, refl_mem_uniformity hU, hp⟩ + -- Eventually, ⟨f x, F N x⟩ ∈ hausdorffEntourage U for all x ∈ s + have hHU : hausdorffEntourage U ∈ @uniformity (Set β) (UniformSpace.hausdorff (α := β)) := + (mem_lift'_sets monotone_hausdorffEntourage).mpr ⟨U, hU, le_refl _⟩ + obtain ⟨N, hN⟩ := (htendsto (hausdorffEntourage U) hHU).exists + -- In which case, ⟨y₀, z₀⟩ ∈ U for some z₀ ∈ F N x₀ + obtain ⟨z₀, hz₀FN, hz₀y₀⟩ := + ((mem_hausdorffEntourage U (f x₀) (F N x₀)).mp (hN x₀ hx₀s)).1 hy₀f + -- By lower hemicontinuity, a ball around z₀ intersects all x in a neighborhood of x₀ + obtain ⟨U', ⟨hU'mem, hU'open⟩, hU'sub⟩ := uniformity_hasBasis_open.mem_iff.mp hU + have hmeet₀ : (F N x₀ ∩ ball z₀ U').Nonempty := ⟨z₀, hz₀FN, mem_ball_self z₀ hU'mem⟩ + have hSmeet : ∀ᶠ x in 𝓝[s] x₀, (F N x ∩ ball z₀ U').Nonempty := + lowerHemicontinuousWithinAt_iff.mp (hF _ _ hx₀s) _ (isOpen_ball _ hU'open) hmeet₀ + filter_upwards [hSmeet, self_mem_nhdsWithin] with x ⟨w, hwFN, hwball⟩ hx_s + obtain ⟨v, hvf, hvw⟩ := ((mem_hausdorffEntourage U (f x) (F N x)).mp (hN x hx_s)).2 hwFN + exact ⟨v, hvf, hWsub <| hU₁comp + ⟨w, hUcomp ⟨z₀, hz₀y₀, hU'sub hwball⟩, hU_le_U₁ (hUsym.symm _ _ hvw)⟩⟩ + +/-- If a net of upper hemicontinuous set-valued functions converges uniformly +(along a filter `l`) in the Hausdorff uniformity to a set-valued function `f` with +compact values, then `f` is upper hemicontinuous -/ +theorem TendstoUniformlyOn.upperHemicontinuousOn (htendsto : TendstoUniformlyOn F f l s) + (hF : ∀ n, UpperHemicontinuousOn (F n) s) (hf_compact : ∀ x ∈ s, IsCompact (f x)) : + UpperHemicontinuousOn f s := by + -- A function `f` is upper hemicontinuous at `x₀` if for all open `u` with `f x₀ ⊆ u`, then + -- `f x ⊆ u` for all `x` near `x₀` + rw [upperHemicontinuousOn_iff_forall_isOpen] + intro x₀ hx₀s u hu hx₀u + -- Find an open entourage `U` such that `U ○ U.symm ⊆ u` + obtain ⟨W, hW, _, hWu⟩ := lebesgue_number_of_compact_open (hf_compact x₀ hx₀s) hu hx₀u + obtain ⟨V, hV, hVsym, hVcomp⟩ := comp_symm_mem_uniformity_sets hW + obtain ⟨U, ⟨hUmem, hUopen⟩, hUsub⟩ := uniformity_hasBasis_open.mem_iff.mp hV + -- Then choose a sufficiently large `N` such that `⟨f x, F N x⟩ ∈ hausdorffEntourage U` + -- for all `x ∈ s` + have hHU : hausdorffEntourage U ∈ @uniformity _ (UniformSpace.hausdorff (α := β)) := + (mem_lift'_sets monotone_hausdorffEntourage).mpr ⟨U, hUmem, le_refl _⟩ + obtain ⟨N, hN⟩ := (htendsto (hausdorffEntourage U) hHU).exists + have hFN_image : F N x₀ ⊆ U.image (f x₀) := ((mem_hausdorffEntourage ..).mp (hN x₀ hx₀s)).2 + -- Upper hemicontinuity implies `F N x ⊆ U.image (f x₀)` for `x` near `x₀` + simp_rw [upperHemicontinuousOn_iff] at hF + have hFN_uhc : ∀ᶠ x in 𝓝[s] x₀, F N x ⊆ U.image (f x₀) := + (hF N x₀ hx₀s).forall_isOpen _ hUopen.relImage hFN_image + -- For such a nearby `x`, show `f x ⊆ u` by taking `y ∈ f x`, + filter_upwards [hFN_uhc, self_mem_nhdsWithin] with x hFNx hx_s + intro y hy + -- finding a `z ∈ F N x` such that `(y, z) ∈ U` and then some `y₀ ∈ f x₀` such that `⟨y₀, z⟩ ∈ U` + obtain ⟨z, hzFN, hyz⟩ := ((mem_hausdorffEntourage U (f x) (F N x)).mp (hN x hx_s)).1 hy + obtain ⟨y₀, hy₀f, hy₀z⟩ := hFNx hzFN + -- then use that `U ○ U.symm ⊆ u` to conclude + exact hWu y₀ hy₀f (hVcomp ⟨z, hUsub hy₀z, hVsym.symm _ _ (hUsub hyz)⟩) + +/-- A net of lower hemicontinuous set-valued functions converging uniformly (along a +filter `l`) in the Hausdorff uniformity has a lower hemicontinuous limit -/ +theorem TendstoUniformly.lowerHemicontinuous (htendsto : TendstoUniformly F f l) + (hF : ∀ n, LowerHemicontinuous (F n)) : LowerHemicontinuous f := by + rw [← lowerHemicontinuousOn_univ_iff] + exact htendsto.tendstoUniformlyOn.lowerHemicontinuousOn (fun n ↦ (hF n).lowerHemicontinuousOn _) + +/-- If a net of upper hemicontinuous set-valued functions converges uniformly +(along a filter `l`) in the Hausdorff uniformity to a set-valued function `f` with +compact values, then `f` is upper hemicontinuous -/ +theorem TendstoUniformly.upperHemicontinuous (htendsto : TendstoUniformly F f l) + (hF : ∀ n, UpperHemicontinuous (F n)) (hf_compact : ∀ x, IsCompact (f x)) : + UpperHemicontinuous f := by + rw [← upperHemicontinuousOn_univ_iff] + exact htendsto.tendstoUniformlyOn.upperHemicontinuousOn + (fun n ↦ (hF n).upperHemicontinuousOn _) (fun x _ ↦ hf_compact x) + +end limits From 51e6992efd06126df61a496bebf8f49482a4e129 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:29:46 +0000 Subject: [PATCH 1138/1300] chore: bump toolchain to v4.33.0-rc2 (#42401) Co-authored-by: Joscha --- lake-manifest.json | 18 +++++++++--------- lean-toolchain | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 71d2d1d50d8f0c..1f8331b1fe5aa9 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b1c4a69a7e247ab7df20460212001673d74f08c0", + "rev": "123d15766ba49356c02ebad2a4462dfe12d79899", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "0498c7c070c143a3bf7379f4d99a2c63bb9d9715", + "rev": "f5c090429dff3cf66cb65562526c9ea6e8edfbcb", "name": "LeanSearchClient", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "18a90119a5d316358fde6c86e0ca24e59212e32c", + "rev": "bb3469a87774349fe01898d8bf2fc6a1ce6411ca", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b1436dc749e722c9920036b52cdc43b3451d0b69", + "rev": "222c58dad7706a6e7cae46c0edd65ea881d3ee27", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "57d3325be72a842920813bcb40f96a6f7393c185", + "rev": "7db8190085343afde2f5d2cdcc9bac719b6ec02c", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "ee41917ae11d38479fb8fb24745f7ca4bf0a784d", + "rev": "ef42f8944eaf5b6cbfbe75d1917d824c7dd6cf33", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "0ecf8993df88c044962426c2cbca0de5717d6150", + "rev": "76e1c118b0700b4ceafe99532e887d6431625e1a", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "da07ca808b6718cb2aed14dba154e5a08b8f8ecf", + "rev": "1319485273bf87833fa472afbcefdedecb16b45f", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.33.0-rc1", + "inputRev": "v4.33.0-rc2", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lean-toolchain b/lean-toolchain index fd85b262bf1c73..c084c7fbe586b0 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.33.0-rc1 +leanprover/lean4:v4.33.0-rc2 From 8cbb95e6e08446476813711ab8f45e59d4fda94d Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 15:25:41 +0000 Subject: [PATCH 1139/1300] chore: update Mathlib dependencies 2026-08-03 (#42403) This PR updates the Mathlib dependencies. From a89f32337e6e90d086e57fb05e6faa29ea288a80 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 3 Aug 2026 20:51:17 +0000 Subject: [PATCH 1140/1300] feat(Topology/InfiniteSum): non-negativity of tprod (#42184) --- Mathlib/Algebra/BigOperators/Finprod.lean | 4 ++-- .../Topology/Algebra/InfiniteSum/Order.lean | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index 1619e29b840153..c6a54e43662234 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -256,8 +256,8 @@ theorem finprod_induction {f : α → M} (p : M → Prop) (hp₀ : p 1) split_ifs exacts [Finset.prod_induction _ _ hp₁ hp₀ fun i _ => hp₂ _, hp₀] -theorem finprod_nonneg {R : Type*} [CommSemiring R] [PartialOrder R] [IsOrderedRing R] - {f : α → R} (hf : ∀ x, 0 ≤ f x) : +theorem finprod_nonneg {R : Type*} [CommMonoidWithZero R] [Preorder R] [ZeroLEOneClass R] + [PosMulMono R] {f : α → R} (hf : ∀ x, 0 ≤ f x) : 0 ≤ ∏ᶠ x, f x := finprod_induction (fun x => 0 ≤ x) zero_le_one (fun _ _ => mul_nonneg) hf diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean index c12a5cce20054b..b4f1deac691bc8 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Order.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Order.lean @@ -234,6 +234,25 @@ protected theorem Multipliable.one_lt_tprod [L.LeAtTop] [L.NeBot] (hsum : Multip end OrderedCommGroup +section WithZero + +variable [CommMonoidWithZero α] [TopologicalSpace α] [Preorder α] [ZeroLEOneClass α] + [PosMulMono α] [ClosedIciTopology α] + +theorem HasProd.nonneg [L.NeBot] {f : ι → α} (hf : ∀ i, 0 ≤ f i) {a : α} (h : HasProd f a L) : + 0 ≤ a := + ge_of_tendsto' h fun s ↦ s.prod_nonneg fun i _ ↦ hf i + +theorem tprod_nonneg {f : ι → α} (hf : ∀ i, 0 ≤ f i) : + 0 ≤ ∏'[L] x, f x := by + by_cases h : Multipliable f L + · by_cases hbot : L.NeBot + · exact h.hasProd.nonneg hf + · simpa [tprod_bot hbot] using finprod_nonneg hf + · simp [tprod_eq_one_of_not_multipliable h] + +end WithZero + section CanonicallyOrderedMul variable [CommMonoid α] [PartialOrder α] [IsOrderedMonoid α] From 17d24e4dd354e256108f135211c73430e6b1e771 Mon Sep 17 00:00:00 2001 From: TJHeeringa <16029718+TJHeeringa@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:26:50 +0000 Subject: [PATCH 1141/1300] refactor(Algebra/Module/Equiv): update name and refactor API ofLinearEquiv (#40865) Change the name of `LinearEquiv.ofLinear` to `LinearEquiv.ofLinearMap` and change the API. This replaces `_apply` by `coe_`, introduces `_symm`, which makes `_symm_apply` and `_symm_toLinearMap` redundant, and changes `_toLinearMap` to `toLinearMap_`. --- Mathlib/Algebra/Category/ModuleCat/Basic.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/Semi.lean | 2 +- Mathlib/Algebra/Colimit/Module.lean | 4 +- Mathlib/Algebra/Module/CharacterModule.lean | 4 +- Mathlib/Algebra/Module/Equiv/Basic.lean | 39 +++++++++++++------ .../Algebra/Module/Presentation/Basic.lean | 4 +- Mathlib/Algebra/Star/Module.lean | 2 +- .../Normed/Operator/LinearIsometry.lean | 2 +- Mathlib/LinearAlgebra/Contraction.lean | 4 +- .../DirectSum/TensorProduct.lean | 2 +- Mathlib/LinearAlgebra/Dual/Lemmas.lean | 2 +- .../LinearAlgebra/ExteriorPower/Basic.lean | 34 ++++++++-------- .../Finsupp/LinearCombination.lean | 2 +- .../Matrix/SpecialLinearGroup.lean | 2 +- .../LinearAlgebra/Multilinear/DFinsupp.lean | 2 +- Mathlib/LinearAlgebra/Pi.lean | 2 +- .../LinearAlgebra/PiTensorProduct/Basic.lean | 13 ++++--- .../PiTensorProduct/DFinsupp.lean | 2 +- .../LinearAlgebra/PiTensorProduct/Dual.lean | 2 +- Mathlib/LinearAlgebra/Projection.lean | 2 +- Mathlib/LinearAlgebra/Quotient/Basic.lean | 2 +- .../TensorProduct/Associator.lean | 11 ++++-- .../LinearAlgebra/TensorProduct/Basic.lean | 2 +- .../TensorProduct/DirectLimit.lean | 2 +- .../TensorProduct/Graded/External.lean | 4 +- Mathlib/LinearAlgebra/TensorProduct/Map.lean | 2 +- Mathlib/LinearAlgebra/TensorProduct/Pi.lean | 4 +- Mathlib/LinearAlgebra/TensorProduct/Prod.lean | 2 +- .../LinearAlgebra/TensorProduct/Quotient.lean | 2 +- .../TensorProduct/Subalgebra.lean | 2 +- .../TensorProduct/Submodule.lean | 4 +- .../LinearAlgebra/TensorProduct/Tower.lean | 10 ++--- Mathlib/LinearAlgebra/Trace.lean | 2 +- .../RepresentationTheory/Coinvariants.lean | 6 +-- Mathlib/RepresentationTheory/FiniteIndex.lean | 2 +- .../Homological/GroupHomology/LowDegree.lean | 2 +- .../AdicCompletion/AsTensorProduct.lean | 2 +- .../AdicCompletion/Functoriality.lean | 4 +- .../RingTheory/Extension/Cotangent/Basis.lean | 2 +- Mathlib/RingTheory/Flat/Equalizer.lean | 4 +- Mathlib/RingTheory/IsTensorProduct.lean | 2 +- Mathlib/RingTheory/Localization/Module.lean | 4 +- Mathlib/RingTheory/MatrixAlgebra.lean | 2 +- Mathlib/RingTheory/PicardGroup.lean | 4 +- 44 files changed, 114 insertions(+), 97 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Basic.lean index 9965a3a3fd951e..2688ce98df58ab 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Basic.lean @@ -287,7 +287,7 @@ variable {X Y : ModuleCat R} /-- Build a `LinearEquiv` from an isomorphism in the category `ModuleCat R`. -/ def toLinearEquiv (i : X ≅ Y) : X ≃ₗ[R] Y := - .ofLinear i.hom.hom i.inv.hom (by aesop) (by aesop) + .ofLinearMap i.hom.hom i.inv.hom (by aesop) (by aesop) @[simp] lemma toLinearEquiv_apply (i : X ≅ Y) (x : X) : i.toLinearEquiv x = i.hom x := rfl @[simp] lemma toLinearEquiv_symm (i : X ≅ Y) : i.toLinearEquiv.symm = i.symm.toLinearEquiv := rfl diff --git a/Mathlib/Algebra/Category/ModuleCat/Semi.lean b/Mathlib/Algebra/Category/ModuleCat/Semi.lean index 13ac4f283f9a36..d2a9e36b3f0b69 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Semi.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Semi.lean @@ -263,7 +263,7 @@ namespace CategoryTheory.Iso /-- Build a `LinearEquiv` from an isomorphism in the category `SemimoduleCat R`. -/ def toLinearEquivₛ {X Y : SemimoduleCat R} (i : X ≅ Y) : X ≃ₗ[R] Y := - LinearEquiv.ofLinear i.hom.hom i.inv.hom (by aesop) (by aesop) + LinearEquiv.ofLinearMap i.hom.hom i.inv.hom (by aesop) (by aesop) end CategoryTheory.Iso diff --git a/Mathlib/Algebra/Colimit/Module.lean b/Mathlib/Algebra/Colimit/Module.lean index 97586ab60c675a..9e4d148fa1445b 100644 --- a/Mathlib/Algebra/Colimit/Module.lean +++ b/Mathlib/Algebra/Colimit/Module.lean @@ -211,7 +211,7 @@ family of equivalences `eᵢ : Gᵢ ≅ G'ᵢ` such that `e ∘ f = f' ∘ e` in -/ def congr (e : (i : ι) → G i ≃ₗ[R] G' i) (he : ∀ i j h, e j ∘ₗ f i j h = f' i j h ∘ₗ e i) : DirectLimit G f ≃ₗ[R] DirectLimit G' f' := - LinearEquiv.ofLinear (map (e ·) he) + LinearEquiv.ofLinearMap (map (e ·) he) (map (fun i ↦ (e i).symm) fun i j h ↦ by rw [toLinearMap_symm_comp_eq, ← comp_assoc, he i, comp_assoc, comp_coe, symm_trans_self, refl_toLinearMap, comp_id]) @@ -242,7 +242,7 @@ open _root_.DirectLimit /-- The direct limit constructed as a quotient of the direct sum is isomorphic to the direct limit constructed as a quotient of the disjoint union. -/ def linearEquiv : DirectLimit G f ≃ₗ[R] _root_.DirectLimit G f := - .ofLinear + .ofLinearMap (lift _ _ _ _ (Module.of _ _ _ _) fun _ _ _ _ ↦ .symm <| eq_of_le ..) (Module.lift _ _ _ _ (of _ _ _ _) fun _ _ _ _ ↦ of_f ..) (by ext; simp) diff --git a/Mathlib/Algebra/Module/CharacterModule.lean b/Mathlib/Algebra/Module/CharacterModule.lean index 74223e75f94778..2cf6f59f89c433 100644 --- a/Mathlib/Algebra/Module/CharacterModule.lean +++ b/Mathlib/Algebra/Module/CharacterModule.lean @@ -108,7 +108,7 @@ lemma dual_surjective_of_injective (f : A →ₗ[R] B) (hf : Function.Injective Two isomorphic modules have isomorphic character modules. -/ def congr (e : A ≃ₗ[R] B) : CharacterModule A ≃ₗ[R] CharacterModule B := - .ofLinear (dual e.symm) (dual e) + .ofLinearMap (dual e.symm) (dual e) (by ext c _; exact congr(c $(e.right_inv _))) (by ext c _; exact congr(c $(e.left_inv _))) @@ -144,7 +144,7 @@ Linear maps into a character module are exactly characters of the tensor product -/ @[simps!] noncomputable def homEquiv : (A →ₗ[R] CharacterModule B) ≃ₗ[R] CharacterModule (A ⊗[R] B) := - .ofLinear uncurry curry (by ext _ z; refine z.induction_on ?_ ?_ ?_ <;> aesop) (by aesop) + .ofLinearMap uncurry curry (by ext _ z; refine z.induction_on ?_ ?_ ?_ <;> aesop) (by aesop) theorem dual_rTensor_conj_homEquiv (f : A →ₗ[R] A') : homEquiv.symm.toLinearMap ∘ₗ dual (f.rTensor B) ∘ₗ homEquiv.toLinearMap = f.lcomp R _ := rfl diff --git a/Mathlib/Algebra/Module/Equiv/Basic.lean b/Mathlib/Algebra/Module/Equiv/Basic.lean index 566923c75a50ea..93a26c2d2ec3e7 100644 --- a/Mathlib/Algebra/Module/Equiv/Basic.lean +++ b/Mathlib/Algebra/Module/Equiv/Basic.lean @@ -481,25 +481,40 @@ variable (f : M →ₛₗ[σ₁₂] M₂) (g : M₂ →ₛₗ[σ₂₁] M) /-- If a linear map has an inverse, it is a linear equivalence. -/ -def ofLinear (h₁ : f.comp g = LinearMap.id) (h₂ : g.comp f = LinearMap.id) : M ≃ₛₗ[σ₁₂] M₂ := - { f with - invFun := g - left_inv := LinearMap.ext_iff.1 h₂ - right_inv := LinearMap.ext_iff.1 h₁ } +def ofLinearMap (h₁ : f.comp g = .id) (h₂ : g.comp f = .id) : M ≃ₛₗ[σ₁₂] M₂ where + __ := f + invFun := g + left_inv := LinearMap.ext_iff.1 h₂ + right_inv := LinearMap.ext_iff.1 h₁ -@[simp] +@[simp low] +theorem coe_ofLinearMap (h₁ h₂) : ⇑(ofLinearMap f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂) = f := rfl + +@[simp low] +theorem symm_ofLinearMap (h₁ h₂) : + (ofLinearMap f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm = (ofLinearMap g f h₂ h₁) := + rfl + +/-- If a linear map has an inverse, it is a linear equivalence. -/ +@[deprecated ofLinearMap (since := "2026-06-23")] +abbrev ofLinear (h₁ : f.comp g = .id) (h₂ : g.comp f = .id) : M ≃ₛₗ[σ₁₂] M₂ := ofLinearMap f g h₁ h₂ + +@[deprecated coe_ofLinearMap (since := "2026-06-23")] theorem ofLinear_apply {h₁ h₂} (x : M) : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂) x = f x := rfl -@[simp] -theorem ofLinear_symm_apply {h₁ h₂} (x : M₂) : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm x = g x := +@[deprecated "Follows from simp lemmas `symm_ofLinearMap` and `coe_ofLinearMap`" + (since := "2026-06-23")] +theorem ofLinear_symm_apply {h₁ h₂} (x : M₂) : + (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm x = g x := rfl -@[simp] -theorem ofLinear_toLinearMap {h₁ h₂} : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂) = f := rfl +@[deprecated "Follows from simp lemmas `symm_ofLinearMap` and `ofLinear_toLinearMap`" + (since := "2026-06-23")] +theorem ofLinear_symm_toLinearMap {h₁ h₂} : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm = g := rfl @[simp] -theorem ofLinear_symm_toLinearMap {h₁ h₂} : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm = g := rfl +theorem ofLinear_toLinearMap (h₁ h₂) : (ofLinearMap f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂) = f := rfl end @@ -833,7 +848,7 @@ open LinearMap /-- Given an `R`-module `M` and an equivalence `m ≃ n` between arbitrary types, construct a linear equivalence `(n → M) ≃ₗ[R] (m → M)` -/ def funCongrLeft (e : m ≃ n) : (n → M) ≃ₗ[R] m → M := - LinearEquiv.ofLinear (funLeft R M e) (funLeft R M e.symm) + LinearEquiv.ofLinearMap (funLeft R M e) (funLeft R M e.symm) (LinearMap.ext fun x ↦ funext fun i ↦ by rw [id_apply, ← funLeft_comp, Equiv.symm_comp_self, LinearMap.funLeft_id]) (LinearMap.ext fun x ↦ diff --git a/Mathlib/Algebra/Module/Presentation/Basic.lean b/Mathlib/Algebra/Module/Presentation/Basic.lean index 4f372e7e6ee899..11b5b38e1e727e 100644 --- a/Mathlib/Algebra/Module/Presentation/Basic.lean +++ b/Mathlib/Algebra/Module/Presentation/Basic.lean @@ -364,7 +364,7 @@ variable {solution' : relations.Solution N} (h' : solution'.IsPresentation) /-- Uniqueness (up to a unique linear equivalence) of the module defined by generators and relations. -/ -def uniq : M ≃ₗ[A] N := LinearEquiv.ofLinear +def uniq : M ≃ₗ[A] N := LinearEquiv.ofLinearMap (h.desc solution') (h'.desc solution) (h'.postcomp_injective (by simp)) (h.postcomp_injective (by simp)) @@ -459,7 +459,7 @@ lemma isPresentation {solution : relations.Solution M} solution.IsPresentation where bijective := by let e : relations.Quotient ≃ₗ[A] M := - LinearEquiv.ofLinear solution.fromQuotient + LinearEquiv.ofLinearMap solution.fromQuotient ((down.{v} h).desc (ofQuotient relations)) ((down.{max u w₀} h).postcomp_injective (by aesop)) (by aesop) exact e.bijective diff --git a/Mathlib/Algebra/Star/Module.lean b/Mathlib/Algebra/Star/Module.lean index 3d5047d9080155..928ae94243f3fa 100644 --- a/Mathlib/Algebra/Star/Module.lean +++ b/Mathlib/Algebra/Star/Module.lean @@ -221,7 +221,7 @@ set_option backward.isDefEq.respectTransparency false in as a linear equivalence. -/ @[simps!] def StarModule.decomposeProdAdjoint : A ≃ₗ[R] selfAdjoint A × skewAdjoint A := by - refine LinearEquiv.ofLinear ((selfAdjointPart R).prod (skewAdjointPart R)) + refine LinearEquiv.ofLinearMap ((selfAdjointPart R).prod (skewAdjointPart R)) (LinearMap.coprod ((selfAdjoint.submodule R A).subtype) (skewAdjoint.submodule R A).subtype) ?_ (LinearMap.ext <| StarModule.selfAdjointPart_add_skewAdjointPart R) -- Note: with https://github.com/leanprover-community/mathlib4/pull/6965 `Submodule.coe_subtype` doesn't fire in `dsimp` or `simp` diff --git a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean index fc839187ae9144..db0ab09034bdbe 100644 --- a/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean +++ b/Mathlib/Analysis/Normed/Operator/LinearIsometry.lean @@ -962,7 +962,7 @@ theorem coe_ofSurjective (f : F →ₛₗᵢ[σ₁₂] E₂) (hfr : Function.Sur def ofLinearIsometry (f : E →ₛₗᵢ[σ₁₂] E₂) (g : E₂ →ₛₗ[σ₂₁] E) (h₁ : f.toLinearMap.comp g = LinearMap.id) (h₂ : g.comp f.toLinearMap = LinearMap.id) : E ≃ₛₗᵢ[σ₁₂] E₂ := - { toLinearEquiv := LinearEquiv.ofLinear f.toLinearMap g h₁ h₂ + { toLinearEquiv := LinearEquiv.ofLinearMap f.toLinearMap g h₁ h₂ norm_map' := fun x => f.norm_map x } @[simp] diff --git a/Mathlib/LinearAlgebra/Contraction.lean b/Mathlib/LinearAlgebra/Contraction.lean index 417f29cd82bd57..d6a838fd4b4754 100644 --- a/Mathlib/LinearAlgebra/Contraction.lean +++ b/Mathlib/LinearAlgebra/Contraction.lean @@ -168,7 +168,7 @@ attribute [-ext] AlgebraTensorModule.curry_injective in provides this equivalence in return for a basis of `M`. -/ -- We manually create simp-lemmas because `@[simps]` generates a malformed lemma noncomputable def dualTensorHomEquivOfBasis : Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N := - LinearEquiv.ofLinear (dualTensorHom R M N) + LinearEquiv.ofLinearMap (dualTensorHom R M N) (∑ i, TensorProduct.mk R _ N (b.dualBasis i) ∘ₗ (LinearMap.applyₗ (R := R) (b i))) (by ext f m @@ -446,7 +446,7 @@ isomorphism `R ⊗ R ≃ R`. @[simps!] noncomputable def dualDistribEquivOfBasis (b : Basis ι R M) (c : Basis κ R N) : Dual R M ⊗[R] Dual R N ≃ₗ[R] Dual R (M ⊗[R] N) := by - refine LinearEquiv.ofLinear (dualDistrib R M N) (dualDistribInvOfBasis b c) ?_ ?_ + refine LinearEquiv.ofLinearMap (dualDistrib R M N) (dualDistribInvOfBasis b c) ?_ ?_ · exact dualDistrib_dualDistribInvOfBasis_left_inverse _ _ · exact dualDistrib_dualDistribInvOfBasis_right_inverse _ _ diff --git a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean index 10d530acea821e..374a08ed1f4868 100644 --- a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean @@ -49,7 +49,7 @@ variable [Module S M₁'] [IsScalarTower R S M₁'] "tensor product distributes over direct sum". -/ protected def directSum : ((⨁ i₁, M₁ i₁) ⊗[R] ⨁ i₂, M₂ i₂) ≃ₗ[S] ⨁ i : ι₁ × ι₂, M₁ i.1 ⊗[R] M₂ i.2 := by - refine LinearEquiv.ofLinear ?toFun ?invFun ?left ?right + refine LinearEquiv.ofLinearMap ?toFun ?invFun ?left ?right · exact AlgebraTensorModule.lift <| toModule S _ _ fun i₁ => flip <| toModule R _ _ fun i₂ => flip <| AlgebraTensorModule.curry <| DirectSum.lof S (ι₁ × ι₂) (fun i => M₁ i.1 ⊗[R] M₂ i.2) (i₁, i₂) diff --git a/Mathlib/LinearAlgebra/Dual/Lemmas.lean b/Mathlib/LinearAlgebra/Dual/Lemmas.lean index 0d17ea7dce9a3c..580046e9239464 100644 --- a/Mathlib/LinearAlgebra/Dual/Lemmas.lean +++ b/Mathlib/LinearAlgebra/Dual/Lemmas.lean @@ -620,7 +620,7 @@ vanish on `W`. The inverse of this is `Submodule.dualCopairing`. -/ def dualQuotEquivDualAnnihilator (W : Submodule R M) : Module.Dual R (M ⧸ W) ≃ₗ[R] W.dualAnnihilator := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (W.mkQ.dualMap.codRestrict W.dualAnnihilator fun φ => W.range_dualMap_mkQ_eq ▸ LinearMap.mem_range_self W.mkQ.dualMap φ) W.dualCopairing (by ext; rfl) (by ext; rfl) diff --git a/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean b/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean index eacd609d238d82..d2a91ef943380b 100644 --- a/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean +++ b/Mathlib/LinearAlgebra/ExteriorPower/Basic.lean @@ -412,8 +412,7 @@ variable (R M) in /-- The linear equivalence ` ⋀[R]^0 M ≃ₗ[R] R`. -/ @[simps! -isSimp symm_apply] noncomputable def zeroEquiv : ⋀[R]^0 M ≃ₗ[R] R := - LinearEquiv.ofLinear - (alternatingMapLinearEquiv (AlternatingMap.constOfIsEmpty R _ _ 1)) + .ofLinearMap (alternatingMapLinearEquiv (AlternatingMap.constOfIsEmpty R _ _ 1)) { toFun := fun r ↦ r • (ιMulti _ _ (by rintro ⟨i, hi⟩; simp at hi)) map_add' := by intros; simp only [add_smul] map_smul' := by intros; simp only [smul_eq_mul, mul_smul, RingHom.id_apply] } @@ -431,22 +430,21 @@ variable (R M) in /-- The linear equivalence `M ≃ₗ[R] ⋀[R]^1 M`. -/ @[simps! -isSimp symm_apply] noncomputable def oneEquiv : ⋀[R]^1 M ≃ₗ[R] M := - LinearEquiv.ofLinear - (alternatingMapLinearEquiv (AlternatingMap.ofSubsingleton R M M (0 : Fin 1) .id)) (by - have h (m : M) : (fun (_ : Fin 1) ↦ m) = update (fun _ ↦ 0) 0 m := by - ext i - fin_cases i - rfl - exact - { toFun := fun m ↦ ιMulti _ _ (fun _ ↦ m) - map_add' := fun m₁ m₂ ↦ by - rw [h]; nth_rw 2 [h]; nth_rw 3 [h] - simp only [Fin.isValue, AlternatingMap.map_update_add] - map_smul' := fun r m ↦ by - dsimp - rw [h]; nth_rw 2 [h] - simp only [Fin.isValue, AlternatingMap.map_update_smul] }) - (by aesop) (by aesop) + .ofLinearMap (alternatingMapLinearEquiv (AlternatingMap.ofSubsingleton R M M (0 : Fin 1) .id)) (by + have h (m : M) : (fun (_ : Fin 1) ↦ m) = update (fun _ ↦ 0) 0 m := by + ext i + fin_cases i + rfl + exact + { toFun := fun m ↦ ιMulti _ _ (fun _ ↦ m) + map_add' := fun m₁ m₂ ↦ by + rw [h]; nth_rw 2 [h]; nth_rw 3 [h] + simp only [Fin.isValue, AlternatingMap.map_update_add] + map_smul' := fun r m ↦ by + dsimp + rw [h]; nth_rw 2 [h] + simp only [Fin.isValue, AlternatingMap.map_update_smul] }) + (by aesop) (by aesop) @[simp] lemma oneEquiv_ιMulti (f : Fin 1 → M) : diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index 9b3442cd4109ad..0b39c121234c53 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -530,7 +530,7 @@ variable {R M ι : Type*} [Ring R] [AddCommGroup M] [Module R M] (i : ι) (c : the `j`-th standard basis vector to itself plus `c j` multiplied with the `i`-th standard basis vector (in particular, the `i`-th standard basis vector is kept invariant). -/ def Finsupp.addSingleEquiv : (ι →₀ R) ≃ₗ[R] (ι →₀ R) := by - refine .ofLinear (linearCombination _ fun j ↦ single j 1 + single i (c j)) + refine .ofLinearMap (linearCombination _ fun j ↦ single j 1 + single i (c j)) (linearCombination _ fun j ↦ single j 1 - single i (c j)) ?_ ?_ <;> ext j k <;> obtain rfl | hk := eq_or_ne i k · simp [h₀] diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index cbb6fad7f6e145..32864908aec4bc 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -191,7 +191,7 @@ instance : Group (SpecialLinearGroup n R) := /-- A version of `Matrix.toLin' A` that produces linear equivalences. -/ def toLin' : SpecialLinearGroup n R →* (n → R) ≃ₗ[R] n → R where toFun A := - LinearEquiv.ofLinear (Matrix.toLin' ↑ₘA) (Matrix.toLin' ↑ₘA⁻¹) + LinearEquiv.ofLinearMap (Matrix.toLin' ↑ₘA) (Matrix.toLin' ↑ₘA⁻¹) (by rw [← toLin'_mul, ← coe_mul, mul_inv_cancel, coe_one, toLin'_one]) (by rw [← toLin'_mul, ← coe_mul, inv_mul_cancel, coe_one, toLin'_one]) map_one' := LinearEquiv.toLinearMap_injective Matrix.toLin'_one diff --git a/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean b/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean index c246005765dadd..18309fef90089f 100644 --- a/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/Multilinear/DFinsupp.lean @@ -208,7 +208,7 @@ on the `fun i ↦ M i (p i)` and the space of multilinear map on `fun i ↦ Π def fromDFinsuppEquiv : ((p : Π i, κ i) → MultilinearMap R (fun i ↦ M i (p i)) N) ≃ₗ[R] MultilinearMap R (fun i ↦ Π₀ j : κ i, M i j) N := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap ((DFinsupp.lsum ℕ fun _ ↦ .id).compMultilinearMapₗ R ∘ₗ MultilinearMap.dfinsuppFamilyₗ) (LinearMap.pi fun p ↦ MultilinearMap.compLinearMapₗ fun i ↦ DFinsupp.lsingle (p i)) (by ext f x; simp) diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index 6d3599687b9be9..cb62852d4dfebd 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -303,7 +303,7 @@ def iInfKerProjEquiv {I J : Set ι} [DecidablePred fun i => i ∈ I] (hd : Disjo (⨅ i ∈ J, ker (proj i : ((i : ι) → φ i) →ₗ[R] φ i) : Submodule R ((i : ι) → φ i)) ≃ₗ[R] (i : I) → φ i := by refine - LinearEquiv.ofLinear (pi fun i => (proj (i : ι)).comp (Submodule.subtype _)) + LinearEquiv.ofLinearMap (pi fun i => (proj (i : ι)).comp (Submodule.subtype _)) (codRestrict _ (pi fun i => if h : i ∈ I then proj (⟨i, h⟩ : I) else 0) ?_) ?_ ?_ · intro b simp only [mem_iInf, mem_ker, proj_apply, pi_apply] diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean index 30f274638e5728..b6900cd03eca08 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Basic.lean @@ -599,7 +599,7 @@ This is the n-ary version of `TensorProduct.congr` -/ noncomputable def congr (f : Π i, s i ≃ₗ[R] t i) : (⨂[R] i, s i) ≃ₗ[R] ⨂[R] i, t i := - .ofLinear + .ofLinearMap (map (fun i ↦ f i)) (map (fun i ↦ (f i).symm)) (by ext; simp) @@ -608,12 +608,13 @@ noncomputable def congr (f : Π i, s i ≃ₗ[R] t i) : @[simp] theorem congr_tprod (f : Π i, s i ≃ₗ[R] t i) (m : Π i, s i) : congr f (tprod R m) = tprod R (fun (i : ι) ↦ (f i) (m i)) := by - simp only [congr, LinearEquiv.ofLinear_apply, map_tprod, LinearEquiv.coe_coe] + simp only [congr, LinearEquiv.coe_ofLinearMap, map_tprod, LinearEquiv.coe_coe] @[simp] theorem congr_symm_tprod (f : Π i, s i ≃ₗ[R] t i) (p : Π i, t i) : (congr f).symm (tprod R p) = tprod R (fun (i : ι) ↦ (f i).symm (p i)) := by - simp only [congr, LinearEquiv.ofLinear_symm_apply, map_tprod, LinearEquiv.coe_coe] + simp only [congr, LinearEquiv.symm_ofLinearMap, LinearEquiv.coe_ofLinearMap, map_tprod, + LinearEquiv.coe_coe] /-- Let `sᵢ`, `tᵢ` and `t'ᵢ` be families of `R`-modules, then `f : Πᵢ sᵢ → tᵢ → t'ᵢ` induces an @@ -680,7 +681,7 @@ variable (s) in def reindex (e : ι ≃ ι₂) : (⨂[R] i : ι, s i) ≃ₗ[R] ⨂[R] i : ι₂, s (e.symm i) := let f := domDomCongrLinearEquiv' R R s (⨂[R] (i : ι₂), s (e.symm i)) e let g := domDomCongrLinearEquiv' R R s (⨂[R] (i : ι), s i) e - LinearEquiv.ofLinear (lift <| f.symm <| tprod R) (lift <| g <| tprod R) (by aesop) (by aesop) + LinearEquiv.ofLinearMap (lift <| f.symm <| tprod R) (lift <| g <| tprod R) (by aesop) (by aesop) end @@ -805,7 +806,7 @@ variable [Subsingleton ι] (i₀ : ι) /-- Tensor product over a singleton type with element `i₀` is equivalent to `s i₀`. -/ def subsingletonEquiv : (⨂[R] i : ι, s i) ≃ₗ[R] s i₀ := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift { toFun f := f i₀ map_update_add' m i := by rw [Subsingleton.elim i i₀]; simp @@ -845,7 +846,7 @@ set_option backward.isDefEq.respectTransparency false in modules, use the non-dependent version `PiTensorProduct.tmulEquiv` instead. -/ def tmulEquivDep : (⨂[R] i₁, N (.inl i₁)) ⊗[R] (⨂[R] i₂, N (.inr i₂)) ≃ₗ[R] ⨂[R] i, N i := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (TensorProduct.lift { toFun a := PiTensorProduct.lift (PiTensorProduct.lift (MultilinearMap.currySumEquiv (tprod R)) a) diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean b/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean index 88c01be9919241..a42f94413b1b76 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/DFinsupp.lean @@ -33,7 +33,7 @@ variable {R ι : Type*} {κ : ι → Type*} {M : (i : ι) → κ i → Type*} /-- The `ι`-ary tensor product distributes over `κ i`-ary finitely supported functions. -/ def ofDFinsuppEquiv : (⨂[R] i, (Π₀ j : κ i, M i j)) ≃ₗ[R] Π₀ p : Π i, κ i, ⨂[R] i, M i (p i) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift <| MultilinearMap.fromDFinsuppEquiv κ R fun p ↦ (DFinsupp.lsingle p).compMultilinearMap (tprod R)) (DFinsupp.lsum R fun p ↦ lift <| diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean index eb6fc3f8c96cf2..d94e560f27ea12 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Dual.lean @@ -104,7 +104,7 @@ isomorphism `⨂[R] i, R ≃ R` given by multiplication (`constantBaseRingEquiv` @[simps!] noncomputable def dualDistribEquivOfBasis [Finite ι] [∀ i, Finite (κ i)] (b : Π i, Basis (κ i) R (M i)) : (⨂[R] i, Dual R (M i)) ≃ₗ[R] Dual R (⨂[R] i, M i) := - LinearEquiv.ofLinear dualDistrib (dualDistribInvOfBasis b) + LinearEquiv.ofLinearMap dualDistrib (dualDistribInvOfBasis b) (dualDistrib_dualDistribInvOfBasis_left_inverse _) (dualDistrib_dualDistribInvOfBasis_right_inverse _) diff --git a/Mathlib/LinearAlgebra/Projection.lean b/Mathlib/LinearAlgebra/Projection.lean index ce2883ee8ff818..04b8f4e112f5df 100644 --- a/Mathlib/LinearAlgebra/Projection.lean +++ b/Mathlib/LinearAlgebra/Projection.lean @@ -286,7 +286,7 @@ to its projection onto `q` along `p`; the backward direction sends an element of in `M ⧸ p`. -/ @[simps! symm_apply] def quotientEquivOfIsCompl (h : IsCompl p q) : (E ⧸ p) ≃ₗ[R] q := - .ofLinear + .ofLinearMap (p.liftQ (q.projectionOnto p h.symm) (by simp)) (p.mkQ ∘ₗ q.subtype) (by ext; simp) diff --git a/Mathlib/LinearAlgebra/Quotient/Basic.lean b/Mathlib/LinearAlgebra/Quotient/Basic.lean index 261bc284bcf553..d7616ee73dc6c9 100644 --- a/Mathlib/LinearAlgebra/Quotient/Basic.lean +++ b/Mathlib/LinearAlgebra/Quotient/Basic.lean @@ -404,7 +404,7 @@ variable (p p' : Submodule R M) /-- If `p = ⊥`, then `M / p ≃ₗ[R] M`. -/ def quotEquivOfEqBot (hp : p = ⊥) : (M ⧸ p) ≃ₗ[R] M := - LinearEquiv.ofLinear (p.liftQ id <| hp.symm ▸ bot_le) p.mkQ (liftQ_mkQ _ _ _) <| + LinearEquiv.ofLinearMap (p.liftQ id <| hp.symm ▸ bot_le) p.mkQ (liftQ_mkQ _ _ _) <| p.quot_hom_ext _ LinearMap.id fun _ => rfl @[simp] diff --git a/Mathlib/LinearAlgebra/TensorProduct/Associator.lean b/Mathlib/LinearAlgebra/TensorProduct/Associator.lean index 7bb8c73ec41975..7f9e9738aa27e3 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Associator.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Associator.lean @@ -39,7 +39,10 @@ variable (R M) /-- The base ring is a left identity for the tensor product of modules, up to linear equivalence. -/ protected def lid : R ⊗[R] M ≃ₗ[R] M := - LinearEquiv.ofLinear (lift <| LinearMap.lsmul R M) (mk R R M 1) (LinearMap.ext fun _ => by simp) + LinearEquiv.ofLinearMap + (lift <| LinearMap.lsmul R M) + (mk R R M 1) + (LinearMap.ext fun _ => by simp) (ext' fun r m => by simp [← tmul_smul, ← smul_tmul, smul_eq_mul, mul_one]) end @@ -69,7 +72,7 @@ variable (R M) /-- The base ring is a right identity for the tensor product of modules, up to linear equivalence. -/ protected def rid : M ⊗[R] R ≃ₗ[R] M := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift <| .flip (LinearMap.lsmul R M)) (mk R M R |>.flip 1) (LinearMap.ext <| one_smul _) @@ -142,7 +145,7 @@ variable (R M N P) attribute [local ext high] ext in /-- The associator for tensor product of R-modules, as a linear equivalence. -/ protected def assoc : M ⊗[R] N ⊗[R] P ≃ₗ[R] M ⊗[R] (N ⊗[R] P) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift <| lift <| lcurry _ _ _ _ ∘ₗ mk _ _ _) (lift <| uncurry _ _ _ _ ∘ₗ curry (mk R _ _)) (by ext; rfl) @@ -245,7 +248,7 @@ variable (M N P) in attribute [local ext high] ext in /-- A tensor product analogue of `mul_right_comm`. -/ def rightComm : M ⊗[R] N ⊗[R] P ≃ₗ[R] M ⊗[R] P ⊗[R] N := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift (lift (LinearMap.lflip.toLinearMap ∘ₗ (mk _ _ _).compr₂ (mk _ _ _)))) (lift (lift (LinearMap.lflip.toLinearMap ∘ₗ (mk _ _ _).compr₂ (mk _ _ _)))) (by ext; rfl) (by ext; rfl) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean index 132f843798ef38..d88d19595a26d9 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean @@ -263,7 +263,7 @@ variable (R M N) /-- The tensor product of modules is commutative, up to linear equivalence. -/ protected def comm : M ⊗[R] N ≃ₗ[R] N ⊗[R] M := - LinearEquiv.ofLinear (lift (mk R N M).flip) (lift (mk R M N).flip) (ext' fun _ _ => rfl) + LinearEquiv.ofLinearMap (lift (mk R N M).flip) (lift (mk R M N).flip) (ext' fun _ _ => rfl) (ext' fun _ _ => rfl) @[simp] diff --git a/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean b/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean index 5e43b9eb9e92b3..9ba33ac8443f72 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean @@ -77,7 +77,7 @@ attribute [local ext] TensorProduct.ext in -/ noncomputable def directLimitLeft : DirectLimit G f ⊗[R] M ≃ₗ[R] DirectLimit (G · ⊗[R] M) (f ▷ M) := - LinearEquiv.ofLinear (toDirectLimit f M) (fromDirectLimit f M) (by ext; simp) (by ext; simp) + LinearEquiv.ofLinearMap (toDirectLimit f M) (fromDirectLimit f M) (by ext; simp) (by ext; simp) @[simp] lemma directLimitLeft_tmul_of {i : ι} (g : G i) (m : M) : directLimitLeft f M (of _ _ _ _ _ g ⊗ₜ m) = of _ _ _ (f ▷ M) _ (g ⊗ₜ m) := diff --git a/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean b/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean index b26fafbc838363..1b7efccfcc1ecd 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean @@ -103,7 +103,7 @@ This sends $a ⊗ b$ to $(-1)^{\deg a' \deg b} (b ⊗ a)$. -/ def gradedComm : (⨁ i, 𝒜 i) ⊗[R] (⨁ i, ℬ i) ≃ₗ[R] (⨁ i, ℬ i) ⊗[R] (⨁ i, 𝒜 i) := by refine TensorProduct.directSum R R 𝒜 ℬ ≪≫ₗ ?_ ≪≫ₗ (TensorProduct.directSum R R ℬ 𝒜).symm - exact LinearEquiv.ofLinear (gradedCommAux _ _ _) (gradedCommAux _ _ _) + exact LinearEquiv.ofLinearMap (gradedCommAux _ _ _) (gradedCommAux _ _ _) (gradedCommAux_comp_gradedCommAux _ _ _) (gradedCommAux_comp_gradedCommAux _ _ _) /-- The braiding is symmetric. -/ @@ -115,7 +115,7 @@ theorem gradedComm_of_tmul_of (i j : ι) (a : 𝒜 i) (b : ℬ j) : gradedComm R 𝒜 ℬ (lof R _ 𝒜 i a ⊗ₜ lof R _ ℬ j b) = (-1 : ℤˣ) ^ (j * i) • (lof R _ ℬ _ b ⊗ₜ lof R _ 𝒜 _ a) := by rw [gradedComm] - dsimp only [LinearEquiv.trans_apply, LinearEquiv.ofLinear_apply] + dsimp only [LinearEquiv.trans_apply, LinearEquiv.coe_ofLinearMap] rw [TensorProduct.directSum_lof_tmul_lof, gradedCommAux_lof_tmul, Units.smul_def, -- Note: https://github.com/leanprover-community/mathlib4/pull/8386 specialized `map_smul` to `LinearEquiv.map_smul` to avoid timeouts. ← Int.cast_smul_eq_zsmul R, LinearEquiv.map_smul, TensorProduct.directSum_symm_lof_tmul, diff --git a/Mathlib/LinearAlgebra/TensorProduct/Map.lean b/Mathlib/LinearAlgebra/TensorProduct/Map.lean index ac9e7ae0a5aafc..60b3091201c93e 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Map.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Map.lean @@ -246,7 +246,7 @@ variable {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomIn /-- If `M` and `P` are semilinearly equivalent and `N` and `Q` are semilinearly equivalent then `M ⊗ N` and `P ⊗ Q` are semilinearly equivalent. -/ def congr (f : M ≃ₛₗ[σ₁₂] M₂) (g : N ≃ₛₗ[σ₁₂] N₂) : M ⊗[R] N ≃ₛₗ[σ₁₂] M₂ ⊗[R₂] N₂ := - LinearEquiv.ofLinear (map f g) (map f.symm g.symm) + LinearEquiv.ofLinearMap (map f g) (map f.symm g.symm) (ext' fun m n => by simp) (ext' fun m n => by simp) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean index 781eed9016964a..406b79e5182f60 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean @@ -89,7 +89,7 @@ private lemma piRightInv_single (x : N) (i : ι) (m : M i) : /-- Tensor product commutes with finite products on the right. -/ def piRight : N ⊗[R] (∀ i, M i) ≃ₗ[S] ∀ i, N ⊗[R] M i := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (piRightHom R S N M) (piRightInv R S N M) (by ext i x m j; simp [tmul_single]) @@ -161,7 +161,7 @@ private lemma piScalarRightInv_single (x : N) (i : ι) : /-- For any `R`-module `N` and finite index type `ι`, `N ⊗[R] (ι → R)` is canonically isomorphic to `ι → N`. -/ def piScalarRight : N ⊗[R] (ι → R) ≃ₗ[S] (ι → N) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (piScalarRightHom R S N ι) (piScalarRightInv R S N ι) (by ext i x j; simp [Pi.single_apply]) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Prod.lean b/Mathlib/LinearAlgebra/TensorProduct/Prod.lean index ef54c68077180f..1a2225ab23abe7 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Prod.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Prod.lean @@ -39,7 +39,7 @@ attribute [ext] TensorProduct.ext set_option backward.isDefEq.respectTransparency false in /-- Tensor products distribute over a product on the right. -/ def prodRight : M₁ ⊗[R] (M₂ × M₃) ≃ₗ[S] (M₁ ⊗[R] M₂) × (M₁ ⊗[R] M₃) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (TensorProduct.AlgebraTensorModule.lift <| LinearMap.prodMapLinear R M₂ M₃ (M₁ ⊗[R] M₂) (M₁ ⊗[R] M₃) S ∘ₗ LinearMap.prod (AlgebraTensorModule.mk R S M₁ M₂) (AlgebraTensorModule.mk R S M₁ M₃)) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean b/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean index d0595a460fb70d..b604a7a2363aa5 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean @@ -58,7 +58,7 @@ noncomputable def quotientTensorQuotientEquiv (m : Submodule R M) (n : Submodule (M ⊗[R] N) ⧸ (LinearMap.range (map m.subtype LinearMap.id) ⊔ LinearMap.range (map LinearMap.id n.subtype)) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift <| Submodule.liftQ _ (LinearMap.flip <| Submodule.liftQ _ ((mk R (M := M) (N := N)).flip.compr₂ (Submodule.mkQ _)) fun x hx => by ext y diff --git a/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean b/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean index b4f1a8718ed701..81bd5f8865691c 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Subalgebra.lean @@ -135,7 +135,7 @@ set_option backward.isDefEq.respectTransparency false in This is promoted to an `R`-algebra isomorphism `Algebra.TensorProduct.algEquivIncludeRange`. -/ def linearEquivIncludeRange : S ⊗[R] T ≃ₗ[R] (includeLeft : S →ₐ[R] S ⊗[R] T).range ⊗[R] - (includeRight : T →ₐ[R] S ⊗[R] T).range := .ofLinear + (includeRight : T →ₐ[R] S ⊗[R] T).range := .ofLinearMap (_root_.TensorProduct.map includeLeft.toLinearMap.rangeRestrict includeRight.toLinearMap.rangeRestrict) (includeLeft.toLinearMap.range.mulMap includeRight.toLinearMap.range) diff --git a/Mathlib/LinearAlgebra/TensorProduct/Submodule.lean b/Mathlib/LinearAlgebra/TensorProduct/Submodule.lean index cb790fb68c5164..2a3973c205e24d 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Submodule.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Submodule.lean @@ -163,7 +163,7 @@ there is the natural isomorphism of `R`-modules between `i(R) ⊗[R] N` and `N` induced by multiplication in `S`, here `i : R → S` is the structure map. This generalizes `TensorProduct.lid` as `i(R)` is not necessarily isomorphic to `R`. -/ def lTensorOne : (⊥ : Subalgebra R S) ⊗[R] N ≃ₗ[R] N := - LinearEquiv.ofLinear N.lTensorOne' (TensorProduct.mk R (⊥ : Subalgebra R S) N 1) + LinearEquiv.ofLinearMap N.lTensorOne' (TensorProduct.mk R (⊥ : Subalgebra R S) N 1) (by ext; simp) <| TensorProduct.ext' fun r n ↦ by change 1 ⊗ₜ[R] lTensorOne' N _ = r ⊗ₜ[R] n obtain ⟨x, h⟩ := Algebra.mem_bot.1 r.2 @@ -215,7 +215,7 @@ there is the natural isomorphism of `R`-modules between `M ⊗[R] i(R)` and `M` induced by multiplication in `S`, here `i : R → S` is the structure map. This generalizes `TensorProduct.rid` as `i(R)` is not necessarily isomorphic to `R`. -/ def rTensorOne : M ⊗[R] (⊥ : Subalgebra R S) ≃ₗ[R] M := - LinearEquiv.ofLinear M.rTensorOne' ((TensorProduct.comm R _ _).toLinearMap ∘ₗ + LinearEquiv.ofLinearMap M.rTensorOne' ((TensorProduct.comm R _ _).toLinearMap ∘ₗ TensorProduct.mk R (⊥ : Subalgebra R S) M 1) (by ext; simp) <| TensorProduct.ext' fun n r ↦ by change rTensorOne' M _ ⊗ₜ[R] 1 = n ⊗ₜ[R] r obtain ⟨x, h⟩ := Algebra.mem_bot.1 r.2 diff --git a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean index 1a388d0358d181..07943192bd8f7a 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean @@ -161,7 +161,7 @@ A linear equivalence constructing a linear map `M ⊗[R] N →[A] P` given a bilinear map `M →[A] N →[R] P` with the property that its composition with the canonical bilinear map `M →[A] N →[R] M ⊗[R] N` is the given bilinear map `M →[A] N →[R] P`. -/ def lift.equiv : (M →ₗ[A] N →ₗ[R] P) ≃ₗ[B] M ⊗[R] N →ₗ[A] P := - LinearEquiv.ofLinear (uncurry R A B M N P) (lcurry R A B M N P) + LinearEquiv.ofLinearMap (uncurry R A B M N P) (lcurry R A B M N P) (LinearMap.ext fun _ => ext fun x y => lift_tmul _ x y) (LinearMap.ext fun f => LinearMap.ext fun x => LinearMap.ext fun y => lift_tmul f x y) @@ -320,7 +320,7 @@ variable {R A B M N P Q} /-- Heterobasic version of `TensorProduct.congr` -/ def congr (f : M ≃ₗ[A] P) (g : N ≃ₗ[R] Q) : (M ⊗[R] N) ≃ₗ[A] (P ⊗[R] Q) := - LinearEquiv.ofLinear (map f g) (map f.symm g.symm) + LinearEquiv.ofLinearMap (map f g) (map f.symm g.symm) (ext fun _m _n => congr_arg₂ (· ⊗ₜ ·) (f.apply_symm_apply _) (g.apply_symm_apply _)) (ext fun _m _n => congr_arg₂ (· ⊗ₜ ·) (f.symm_apply_apply _) (g.symm_apply_apply _)) @@ -355,7 +355,7 @@ variable (R A M) /-- Heterobasic version of `TensorProduct.rid`. -/ protected def rid : M ⊗[R] R ≃ₗ[A] M := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift <| Algebra.lsmul _ _ _ |>.toLinearMap |>.flip) (mk R A M R |>.flip 1) (LinearMap.ext <| one_smul _) @@ -400,7 +400,7 @@ variable [Algebra A B] [IsScalarTower A B M] Note this is especially useful with `A = R` (where it is a "more linear" version of `TensorProduct.assoc`), or with `B = A`. -/ def assoc : (M ⊗[A] P) ⊗[R] Q ≃ₗ[B] M ⊗[A] (P ⊗[R] Q) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift <| lift <| lcurry R A B P Q _ ∘ₗ mk A B M (P ⊗[R] Q)) (lift <| uncurry R A B P Q _ ∘ₗ curry (mk R B _ Q)) (by ext; rfl) @@ -532,7 +532,7 @@ and a `B`-module `M`, `S`-module `P`, `R`-module `Q`, then ``` -/ def rightComm : (M ⊗[S] P) ⊗[R] Q ≃ₗ[B] (M ⊗[R] Q) ⊗[S] P := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (lift (lift (LinearMap.lflip.toLinearMap ∘ₗ (AlgebraTensorModule.mk _ _ _ _).compr₂ (AlgebraTensorModule.mk _ _ _ _)))) (lift (lift (LinearMap.lflip.toLinearMap ∘ₗ diff --git a/Mathlib/LinearAlgebra/Trace.lean b/Mathlib/LinearAlgebra/Trace.lean index 6c4239c9efa6e6..2e916eca8f2b72 100644 --- a/Mathlib/LinearAlgebra/Trace.lean +++ b/Mathlib/LinearAlgebra/Trace.lean @@ -402,6 +402,6 @@ lemma Module.Free.bijective_algebraMap_of_finrank_eq_one {R S : Type*} [CommRing have h2 : (f ∘ₗ Algebra.linearMap R S) ∘ₗ LinearMap.trace R S = LinearMap.id := b.ext fun i ↦ (basisUnique Unit h).ext fun j ↦ (by simp [f, b, Basis.tensorProduct]) - let eq : R ≃ₗ[R] End R S := .ofLinear (f ∘ₗ Algebra.linearMap R S) (.trace R S) h2 h1 + let eq : R ≃ₗ[R] End R S := .ofLinearMap (f ∘ₗ Algebra.linearMap R S) (.trace R S) h2 h1 have hf : Function.Bijective f := ⟨Algebra.lmul_injective, .of_comp eq.surjective⟩ exact (Function.Bijective.of_comp_iff' hf _).mp eq.bijective diff --git a/Mathlib/RepresentationTheory/Coinvariants.lean b/Mathlib/RepresentationTheory/Coinvariants.lean index 88834570e1c71c..f4f63afbda0be6 100644 --- a/Mathlib/RepresentationTheory/Coinvariants.lean +++ b/Mathlib/RepresentationTheory/Coinvariants.lean @@ -237,7 +237,7 @@ variable (ρ α) in @[simps! symm_apply] noncomputable def coinvariantsFinsuppLEquiv : Coinvariants (ρ.finsupp α) ≃ₗ[k] α →₀ Coinvariants ρ := - LinearEquiv.ofLinear (coinvariantsToFinsupp ρ α) (finsuppToCoinvariants ρ α) + LinearEquiv.ofLinearMap (coinvariantsToFinsupp ρ α) (finsuppToCoinvariants ρ α) (by ext; simp) (by ext; simp) @[simp] @@ -283,7 +283,7 @@ lemma ofCoinvariantsTprodLeftRegular_mk_tmul_single (x : V) (g : G) (r : k) : @[simps! symm_apply] noncomputable def coinvariantsTprodLeftRegularLEquiv : Coinvariants (ρ.tprod (leftRegular k G)) ≃ₗ[k] V := - LinearEquiv.ofLinear (ofCoinvariantsTprodLeftRegular ρ) + LinearEquiv.ofLinearMap (ofCoinvariantsTprodLeftRegular ρ) (Coinvariants.mk _ ∘ₗ (TensorProduct.mk k V k[G]).flip (.single 1 1)) (by ext; simp) (by ext; simp) @@ -502,7 +502,7 @@ variable (A α) @[simps! symm_apply] noncomputable abbrev coinvariantsTensorFreeLEquiv : Coinvariants (A ⊗ free k G α).ρ ≃ₗ[k] (α →₀ A) := - LinearEquiv.ofLinear (coinvariantsTensorFreeToFinsupp A α) (finsuppToCoinvariantsTensorFree A α) + .ofLinearMap (coinvariantsTensorFreeToFinsupp A α) (finsuppToCoinvariantsTensorFree A α) (lhom_ext fun i x => by simp [finsuppToCoinvariantsTensorFree_single, coinvariantsTensorFreeToFinsupp_mk_tmul_single]) <| diff --git a/Mathlib/RepresentationTheory/FiniteIndex.lean b/Mathlib/RepresentationTheory/FiniteIndex.lean index 3d7fc7f106f3e5..e97c51615fae59 100644 --- a/Mathlib/RepresentationTheory/FiniteIndex.lean +++ b/Mathlib/RepresentationTheory/FiniteIndex.lean @@ -177,7 +177,7 @@ The forward map sends `(⟦g ⊗ₜ[k] a⟧, sg) ↦ ρ(s)(a)`, and the inverse @[simps! hom_hom_toLinearMap inv_hom_toLinearMap] noncomputable def indCoindIso (A : Rep.{max w u} k S) : ind S.subtype A ≅ coind S.subtype A := - mkIso (.mk (.ofLinear (indToCoind A) (coindToInd A) + mkIso (.mk (.ofLinearMap (indToCoind A) (coindToInd A) (coindToInd_indToCoind A) (indToCoind_coindToInd A)) <| fun g ↦ by ext; simp) variable (k S) diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean index 5fda00c63b437f..8041e0c71510b8 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/LowDegree.lean @@ -1022,7 +1022,7 @@ set_option backward.isDefEq.respectTransparency false in @[simps! -isSimp] def H1AddEquivOfIsTrivial : H1 A ≃+ (Additive <| Abelianization G) ⊗[ℤ] A := - LinearEquiv.toAddEquiv <| LinearEquiv.ofLinear + LinearEquiv.toAddEquiv <| LinearEquiv.ofLinearMap (H1ToTensorOfIsTrivial A) (lift <| mkH1OfIsTrivial A) (ext <| LinearMap.toAddMonoidHom_injective <| by ext g a diff --git a/Mathlib/RingTheory/AdicCompletion/AsTensorProduct.lean b/Mathlib/RingTheory/AdicCompletion/AsTensorProduct.lean index ff051e312747b9..5c3185b279c744 100644 --- a/Mathlib/RingTheory/AdicCompletion/AsTensorProduct.lean +++ b/Mathlib/RingTheory/AdicCompletion/AsTensorProduct.lean @@ -179,7 +179,7 @@ lemma ofTensorProduct_comp_ofTensorProductInvOfPiFintype : /-- `ofTensorProduct` as an equiv in the case of `M = R^ι` where `ι` is finite. -/ def ofTensorProductEquivOfPiFintype : AdicCompletion I R ⊗[R] (ι → R) ≃ₗ[AdicCompletion I R] AdicCompletion I (ι → R) := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (ofTensorProduct I (ι → R)) (ofTensorProductInvOfPiFintype I ι) (ofTensorProduct_comp_ofTensorProductInvOfPiFintype I ι) diff --git a/Mathlib/RingTheory/AdicCompletion/Functoriality.lean b/Mathlib/RingTheory/AdicCompletion/Functoriality.lean index fa6e85c52187ef..b71da44356dfd7 100644 --- a/Mathlib/RingTheory/AdicCompletion/Functoriality.lean +++ b/Mathlib/RingTheory/AdicCompletion/Functoriality.lean @@ -178,7 +178,7 @@ theorem map_of (f : M →ₗ[R] N) (x : M) : map I f (of I M x) = of I N (f x) : /-- A linear equiv induces a linear equiv on adic completions. -/ def congr (f : M ≃ₗ[R] N) : AdicCompletion I M ≃ₗ[AdicCompletion I R] AdicCompletion I N := - LinearEquiv.ofLinear (map I f) + LinearEquiv.ofLinearMap (map I f) (map I f.symm) (by simp [map_comp]) (by simp [map_comp]) @[simp] @@ -292,7 +292,7 @@ theorem sum_comp_sumInv : sum I M ∘ₗ sumInv I M = LinearMap.id := by /-- If `ι` is finite, `sum` has `sumInv` as inverse. -/ def sumEquivOfFintype : (⨁ j, (AdicCompletion I (M j))) ≃ₗ[AdicCompletion I R] AdicCompletion I (⨁ j, M j) := - LinearEquiv.ofLinear (sum I M) (sumInv I M) (sum_comp_sumInv I M) (sumInv_comp_sum I M) + LinearEquiv.ofLinearMap (sum I M) (sumInv I M) (sum_comp_sumInv I M) (sumInv_comp_sum I M) @[simp] theorem sumEquivOfFintype_apply (x : ⨁ j, (AdicCompletion I (M j))) : diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index 6a4cc4ce7b839a..43b653c5d808e2 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -168,7 +168,7 @@ set_option backward.isDefEq.respectTransparency false in /-- The linear isomorphism `S ⊗[T] J/J² ≃ₗ[S] I/I²`. -/ def tensorCotangentEquiv : S ⊗[D.T] D.presLeft.toExtension.Cotangent ≃ₗ[S] P.toExtension.Cotangent := by - refine LinearEquiv.ofLinear D.tensorCotangentHom D.tensorCotangentInv ?_ ?_ + refine LinearEquiv.ofLinearMap D.tensorCotangentHom D.tensorCotangentInv ?_ ?_ · refine b.ext fun i ↦ ?_ simpa only [LinearMap.coe_comp, Function.comp_apply, tensorCotangentInv_apply, tensorCotangentHom_tmul] using! D.hf (b i) diff --git a/Mathlib/RingTheory/Flat/Equalizer.lean b/Mathlib/RingTheory/Flat/Equalizer.lean index 766fec0bfe871c..25ac6637151c1f 100644 --- a/Mathlib/RingTheory/Flat/Equalizer.lean +++ b/Mathlib/RingTheory/Flat/Equalizer.lean @@ -139,7 +139,7 @@ private lemma LinearMap.lTensor_eqLocus_subtype_tensorEqLocusInv [Module.Flat R /-- If `M` is `R`-flat, the canonical map `M ⊗[R] ker f →ₗ[R] ker (𝟙 ⊗ f)` is an isomorphism. -/ def LinearMap.tensorKerEquiv [Module.Flat R M] : M ⊗[R] LinearMap.ker f ≃ₗ[S] LinearMap.ker (AlgebraTensorModule.lTensor S M f) := - LinearEquiv.ofLinear (LinearMap.tensorKer S M f) (LinearMap.tensorKerInv S M f) + LinearEquiv.ofLinearMap (LinearMap.tensorKer S M f) (LinearMap.tensorKerInv S M f) (by ext x; simp) (by ext m x @@ -164,7 +164,7 @@ def LinearMap.tensorEqLocusEquiv [Module.Flat R M] : M ⊗[R] eqLocus f g ≃ₗ[S] eqLocus (AlgebraTensorModule.lTensor S M f) (AlgebraTensorModule.lTensor S M g) := - LinearEquiv.ofLinear (LinearMap.tensorEqLocus S M f g) (LinearMap.tensorEqLocusInv S M f g) + LinearEquiv.ofLinearMap (LinearMap.tensorEqLocus S M f g) (LinearMap.tensorEqLocusInv S M f g) (by ext; simp) (by ext m x diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index 6d880f1416b26b..108f9bb12ac682 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -496,7 +496,7 @@ theorem IsBaseChange.of_lift_unique · dsimp at *; rw [smul_add, map_add, map_add, smul_add, hx, hy] simp_rw [DFunLike.ext_iff, LinearMap.comp_apply, LinearMap.restrictScalars_apply] at hg let fe : S ⊗[R] M ≃ₗ[S] N := - LinearEquiv.ofLinear f'' (ULift.moduleEquiv.toLinearMap.comp g) ?_ ?_ + LinearEquiv.ofLinearMap f'' (ULift.moduleEquiv.toLinearMap.comp g) ?_ ?_ · exact fe.bijective · rw [← LinearMap.cancel_left (ULift.moduleEquiv : ULift.{max v₁ v₃} N ≃ₗ[S] N).symm.injective] refine (h (ULift.{max v₁ v₃} N) <| ULift.moduleEquiv.symm.toLinearMap.comp f).unique ?_ rfl diff --git a/Mathlib/RingTheory/Localization/Module.lean b/Mathlib/RingTheory/Localization/Module.lean index 05e0c8bd548057..a7ae587f655690 100644 --- a/Mathlib/RingTheory/Localization/Module.lean +++ b/Mathlib/RingTheory/Localization/Module.lean @@ -239,7 +239,7 @@ def LinearMap.extendScalarsOfIsLocalizationEquiv : (M →ₗ[R] N) ≃ₗ[A] (M /-- An `R`-linear isomorphism between `S⁻¹R`-modules is actually `S⁻¹R`-linear. -/ @[simps!] def LinearEquiv.extendScalarsOfIsLocalization (f : M ≃ₗ[R] N) : M ≃ₗ[A] N := - .ofLinear (LinearMap.extendScalarsOfIsLocalization S A f) + .ofLinearMap (LinearMap.extendScalarsOfIsLocalization S A f) (LinearMap.extendScalarsOfIsLocalization S A f.symm) (by ext; simp) (by ext; simp) @@ -277,7 +277,7 @@ def mapExtendScalars : (M →ₗ[R] N) →ₗ[R] (M' →ₗ[Rₛ] N') := @[simps!] noncomputable def mapEquiv (e : M ≃ₗ[R] N) : M' ≃ₗ[Rₛ] N' := - LinearEquiv.ofLinear + LinearEquiv.ofLinearMap (IsLocalizedModule.mapExtendScalars S f g Rₛ e) (IsLocalizedModule.mapExtendScalars S g f Rₛ e.symm) (by diff --git a/Mathlib/RingTheory/MatrixAlgebra.lean b/Mathlib/RingTheory/MatrixAlgebra.lean index 6b41a99a0d7c73..73830fa293be3c 100644 --- a/Mathlib/RingTheory/MatrixAlgebra.lean +++ b/Mathlib/RingTheory/MatrixAlgebra.lean @@ -44,7 +44,7 @@ attribute [local ext] ext_linearMap /-- `Matrix.kroneckerTMul` as a linear equivalence, when the two arguments are tensored. -/ def kroneckerTMulLinearEquiv : Matrix l m M ⊗[R] Matrix n p N ≃ₗ[S] Matrix (l × n) (m × p) (M ⊗[R] N) := - .ofLinear + .ofLinearMap (AlgebraTensorModule.lift <| kroneckerTMulBilinear R S) (Matrix.liftLinear R fun ii jj => AlgebraTensorModule.map (singleLinearMap S ii.1 jj.1) (singleLinearMap R ii.2 jj.2)) diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 6b62b5e7dd218b..3c5c3e09051c97 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -301,7 +301,7 @@ theorem leftInverse_iff_rightInverse : a left inverse of `g`, then in fact `f` is also the right inverse of `g`, and we promote this to an `R`-module isomorphism. -/ def linearEquivOfLeftInverse (hfg : Function.LeftInverse f g) : M ≃ₗ[R] N := - .ofLinear f g (LinearMap.ext hfg) (LinearMap.ext <| rightInverse_of_leftInverse hfg) + .ofLinearMap f g (LinearMap.ext hfg) (LinearMap.ext <| rightInverse_of_leftInverse hfg) @[simp] lemma linearEquivOfLeftInverse_apply (hfg : Function.LeftInverse f g) (x : M) : linearEquivOfLeftInverse hfg x = f x := rfl @@ -313,7 +313,7 @@ def linearEquivOfLeftInverse (hfg : Function.LeftInverse f g) : M ≃ₗ[R] N := a right inverse of `g`, then in fact `f` is also the left inverse of `g`, and we promote this to an `R`-module isomorphism. -/ def linearEquivOfRightInverse (hfg : Function.RightInverse f g) : M ≃ₗ[R] N := - .ofLinear f g (LinearMap.ext <| leftInverse_of_rightInverse hfg) (LinearMap.ext hfg) + .ofLinearMap f g (LinearMap.ext <| leftInverse_of_rightInverse hfg) (LinearMap.ext hfg) @[simp] lemma linearEquivOfRightInverse_apply (hfg : Function.RightInverse f g) (x : M) : linearEquivOfRightInverse hfg x = f x := rfl From 0232cac95945a83b27da8b5785bfd152d9b5faec Mon Sep 17 00:00:00 2001 From: Alex Korbonits <5281694+korbonits@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:26:53 +0000 Subject: [PATCH 1142/1300] feat(Topology/Connected): local (path-)connectedness of products and pi types (#41663) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add product and pi instances for `LocallyConnectedSpace` and `LocallyPathConnectedSpace`, together with a full characterization of local (path-)connectedness of pi types: - `Prod.locallyConnectedSpace` / `Prod.locallyPathConnectedSpace`: binary products. - `Pi.locallyConnectedSpace_of_finite_not_preconnectedSpace` / `Pi.locallyPathConnectedSpace_of_finite_not_pathConnectedSpace`: a product of locally (path-)connected spaces is locally (path-)connected provided all but finitely many factors are preconnected (resp. path-connected). The `Finite ι` and all-factors-preconnected (resp. path-connected) instances are corollaries. - `Pi.locallyConnectedSpace_iff` / `Pi.locallyPathConnectedSpace_iff`: a product is locally (path-)connected iff it is empty or the above conditions hold. - Topology.IsCoinducing.locallyConnectedSpace: a topology coinduced by a locally connected topology is locally connected (used for the forward direction via the projections). Since IsQuotientMap is by definition IsCoinducing, this covers quotient maps; the analogous IsQuotientMap.locallyPathConnectedSpace already existed. Supporting API in Topology/Connected/Basic.lean: - ContinuousOn.image_connectedComponentIn_subset, ContinuousOn.mapsTo_connectedComponentIn, ContinuousOn.preimage_connectedComponentIn: ContinuousOn generalizations of the existing Continuous lemmas. - Continuous.preimage_connectedComponent: the connectedComponent form of the preimage lemma. - Deprecates Continuous.image_connectedComponentIn_subset and Continuous.mapsTo_connectedComponentIn in favor of the ContinuousOn versions. Co-authored-by: Yongxi (Aaron) Lin <97214596+CoolRmal@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Topology/Connected/Basic.lean | 40 ++++++++- .../Topology/Connected/LocallyConnected.lean | 83 ++++++++++++++++++ .../Connected/LocallyPathConnected.lean | 84 +++++++++++++++++++ Mathlib/Topology/Homeomorph/Lemmas.lean | 4 +- 4 files changed, 205 insertions(+), 6 deletions(-) diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 445fa61e0e137c..131d9f3b85c7b0 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -613,21 +613,33 @@ theorem Continuous.image_connectedComponent_subset [TopologicalSpace β] {f : α (isConnected_connectedComponent.image f h.continuousOn).subset_connectedComponent ((mem_image f (connectedComponent a) (f a)).2 ⟨a, mem_connectedComponent, rfl⟩) +theorem ContinuousOn.image_connectedComponentIn_subset [TopologicalSpace β] {f : α → β} {s : Set α} + {a : α} (hf : ContinuousOn f s) (hx : a ∈ s) : + f '' connectedComponentIn s a ⊆ connectedComponentIn (f '' s) (f a) := + (isPreconnected_connectedComponentIn.image _ <| hf.mono <| connectedComponentIn_subset _ _) + |>.subset_connectedComponentIn (mem_image_of_mem _ <| mem_connectedComponentIn hx) + (image_mono <| connectedComponentIn_subset _ _) + +@[deprecated ContinuousOn.image_connectedComponentIn_subset (since := "2026-07-27")] theorem Continuous.image_connectedComponentIn_subset [TopologicalSpace β] {f : α → β} {s : Set α} {a : α} (hf : Continuous f) (hx : a ∈ s) : f '' connectedComponentIn s a ⊆ connectedComponentIn (f '' s) (f a) := - (isPreconnected_connectedComponentIn.image _ hf.continuousOn).subset_connectedComponentIn - (mem_image_of_mem _ <| mem_connectedComponentIn hx) - (image_mono <| connectedComponentIn_subset _ _) + hf.continuousOn.image_connectedComponentIn_subset hx theorem Continuous.mapsTo_connectedComponent [TopologicalSpace β] {f : α → β} (h : Continuous f) (a : α) : MapsTo f (connectedComponent a) (connectedComponent (f a)) := mapsTo_iff_image_subset.2 <| h.image_connectedComponent_subset a +theorem ContinuousOn.mapsTo_connectedComponentIn [TopologicalSpace β] {f : α → β} {s : Set α} + (h : ContinuousOn f s) {a : α} (hx : a ∈ s) : + MapsTo f (connectedComponentIn s a) (connectedComponentIn (f '' s) (f a)) := + mapsTo_iff_image_subset.2 <| h.image_connectedComponentIn_subset hx + +@[deprecated ContinuousOn.mapsTo_connectedComponentIn (since := "2026-07-27")] theorem Continuous.mapsTo_connectedComponentIn [TopologicalSpace β] {f : α → β} {s : Set α} (h : Continuous f) {a : α} (hx : a ∈ s) : MapsTo f (connectedComponentIn s a) (connectedComponentIn (f '' s) (f a)) := - mapsTo_iff_image_subset.2 <| image_connectedComponentIn_subset h hx + h.continuousOn.mapsTo_connectedComponentIn hx theorem irreducibleComponent_subset_connectedComponent {x : α} : irreducibleComponent x ⊆ connectedComponent x := @@ -643,6 +655,26 @@ theorem connectedComponentIn_mono (x : α) {F G : Set α} (h : F ⊆ G) : · rw [connectedComponentIn_eq_empty hx] exact Set.empty_subset _ +/-- The preimage of a connected component of `F` is the union of the connected components of +`f ⁻¹' F` at the points of that preimage. -/ +theorem ContinuousOn.preimage_connectedComponentIn [TopologicalSpace β] {f : α → β} {F : Set β} + (hf : ContinuousOn f (f ⁻¹' F)) (y : β) : + f ⁻¹' connectedComponentIn F y = + ⋃ x ∈ f ⁻¹' connectedComponentIn F y, connectedComponentIn (f ⁻¹' F) x := by + refine subset_antisymm (fun z hz ↦ ?_) (iUnion₂_subset fun x hx z hz ↦ ?_) + · exact mem_biUnion hz (mem_connectedComponentIn (connectedComponentIn_subset F y hz)) + · rw [mem_preimage, connectedComponentIn_eq hx] + exact connectedComponentIn_mono _ (image_preimage_subset f F) + (hf.mapsTo_connectedComponentIn (connectedComponentIn_subset F y hx) hz) + +/-- The preimage of a connected component is the union of the connected components at the points +of that preimage. -/ +theorem Continuous.preimage_connectedComponent [TopologicalSpace β] {f : α → β} + (hf : Continuous f) (y : β) : + f ⁻¹' connectedComponent y = ⋃ x ∈ f ⁻¹' connectedComponent y, connectedComponent x := by + simpa [connectedComponentIn_univ] using + hf.continuousOn.preimage_connectedComponentIn (F := univ) y + /-- A preconnected space is one where there is no non-trivial open partition. -/ class PreconnectedSpace (α : Type u) [TopologicalSpace α] : Prop where /-- The universal set `Set.univ` in a preconnected space is a preconnected set. -/ diff --git a/Mathlib/Topology/Connected/LocallyConnected.lean b/Mathlib/Topology/Connected/LocallyConnected.lean index b634ba83b6634b..9b57ca543bc018 100644 --- a/Mathlib/Topology/Connected/LocallyConnected.lean +++ b/Mathlib/Topology/Connected/LocallyConnected.lean @@ -151,6 +151,13 @@ theorem IsOpen.locallyConnectedSpace [LocallyConnectedSpace α] {U : Set α} (hU LocallyConnectedSpace U := hU.isOpenEmbedding_subtypeVal.locallyConnectedSpace +/-- Any topology coinduced by a locally connected topology is locally connected. -/ +theorem Topology.IsCoinducing.locallyConnectedSpace [LocallyConnectedSpace α] + [TopologicalSpace β] {f : α → β} (hf : IsCoinducing f) : LocallyConnectedSpace β := by + refine locallyConnectedSpace_iff_connectedComponentIn_open.2 fun F hF y _ ↦ ?_ + rw [← hf.isOpen_preimage, hf.continuous.continuousOn.preimage_connectedComponentIn] + exact isOpen_biUnion fun x _ ↦ (hF.preimage hf.continuous).connectedComponentIn + /-- If a space is locally connected, the topology of its connected components is discrete. -/ instance [LocallyConnectedSpace α] : DiscreteTopology <| ConnectedComponents α := by refine discreteTopology_iff_isOpen_singleton.mpr fun c ↦ ?_ @@ -162,4 +169,80 @@ instance [LocallyConnectedSpace α] : DiscreteTopology <| ConnectedComponents α instance [LocallyConnectedSpace α] [CompactSpace α] : Finite <| ConnectedComponents α := finite_of_compact_of_discrete +/-- The product of two locally connected spaces is locally connected. -/ +instance Prod.locallyConnectedSpace [TopologicalSpace β] [LocallyConnectedSpace α] + [LocallyConnectedSpace β] : LocallyConnectedSpace (α × β) := by + rw [locallyConnectedSpace_iff_connected_subsets] + rintro ⟨x, y⟩ U hU + obtain ⟨u, hu, v, hv, huv⟩ := mem_nhds_prod_iff.mp hU + exact ⟨connectedComponentIn u x ×ˢ connectedComponentIn v y, + prod_mem_nhds (connectedComponentIn_mem_nhds hu) (connectedComponentIn_mem_nhds hv), + isPreconnected_connectedComponentIn.prod isPreconnected_connectedComponentIn, + (prod_mono (connectedComponentIn_subset _ _) (connectedComponentIn_subset _ _)).trans huv⟩ + +/-- If each `X i` is locally connected and all but finitely many are preconnected, then +`∀ i, X i` is locally connected. -/ +theorem Pi.locallyConnectedSpace_of_finite_not_preconnectedSpace [∀ i, TopologicalSpace (X i)] + [∀ i, LocallyConnectedSpace (X i)] (hfinite : {i | ¬PreconnectedSpace (X i)}.Finite) : + LocallyConnectedSpace (∀ i, X i) := by + refine locallyConnectedSpace_iff_connected_subsets.2 fun x U hU ↦ ?_ + rw [nhds_pi, Filter.mem_pi] at hU + obtain ⟨J, hJ, t, ht, htU⟩ := hU + let K := J ∪ {i | ¬PreconnectedSpace (X i)} + refine ⟨K.pi fun i ↦ connectedComponentIn (t i) (x i), + set_pi_mem_nhds (hJ.union hfinite) fun i _ ↦ connectedComponentIn_mem_nhds (ht i), ?_, + fun f hf ↦ htU fun i hiJ ↦ connectedComponentIn_subset _ _ (hf i (mem_union_left _ hiJ))⟩ + classical + rw [← univ_pi_piecewise_univ] + refine isPreconnected_univ_pi fun i ↦ ?_ + by_cases hi : i ∈ K + · rw [piecewise_eq_of_mem _ _ _ hi] + exact isPreconnected_connectedComponentIn + · rw [piecewise_eq_of_notMem _ _ _ hi] + have : PreconnectedSpace (X i) := not_not.mp (not_or.1 hi).2 + exact isPreconnected_univ + +/-- A finite product of locally connected spaces is locally connected. -/ +instance Pi.locallyConnectedSpace_of_finite [Finite ι] [∀ i, TopologicalSpace (X i)] + [∀ i, LocallyConnectedSpace (X i)] : LocallyConnectedSpace (∀ i, X i) := + locallyConnectedSpace_of_finite_not_preconnectedSpace (toFinite _) + +/-- A product of preconnected, locally connected spaces is locally connected. Note that an +arbitrary product of locally connected spaces need not be locally connected, so the +preconnectedness assumption cannot be dropped entirely (though it can be dropped for finitely +many factors, see `Pi.locallyConnectedSpace_of_finite_not_preconnectedSpace`). -/ +instance Pi.locallyConnectedSpace [∀ i, TopologicalSpace (X i)] + [∀ i, LocallyConnectedSpace (X i)] [∀ i, PreconnectedSpace (X i)] : + LocallyConnectedSpace (∀ i, X i) := + locallyConnectedSpace_of_finite_not_preconnectedSpace + (finite_empty.subset fun _ hi ↦ hi inferInstance) + +/-- A product of spaces is locally connected iff it is empty, or every factor is locally +connected and all but finitely many factors are preconnected. -/ +theorem Pi.locallyConnectedSpace_iff [∀ i, TopologicalSpace (X i)] : + LocallyConnectedSpace (∀ i, X i) ↔ + IsEmpty (∀ i, X i) ∨ + (∀ i, LocallyConnectedSpace (X i)) ∧ {i | ¬PreconnectedSpace (X i)}.Finite := by + refine ⟨fun h ↦ ?_, ?_⟩ + · rcases isEmpty_or_nonempty (∀ i, X i) with he | hne + · exact .inl he + obtain ⟨x⟩ := hne + classical + have : ∀ i, Nonempty (X i) := Classical.nonempty_pi.mp ⟨x⟩ + refine .inr ⟨fun i ↦ ((isOpenMap_eval i).isQuotientMap (continuous_apply i) + (Function.surjective_eval i)).locallyConnectedSpace, ?_⟩ + have hVn : connectedComponent x ∈ 𝓝 x := + isOpen_connectedComponent.mem_nhds mem_connectedComponent + rw [nhds_pi, Filter.mem_pi] at hVn + obtain ⟨J, hJ, t, ht, htV⟩ := hVn + refine hJ.subset fun i hi ↦ by_contra fun hiJ ↦ hi ?_ + suffices himg : Function.eval i '' connectedComponent x = univ from + ⟨himg ▸ isPreconnected_connectedComponent.image _ (continuous_apply i).continuousOn⟩ + refine (subset_univ _).antisymm fun z _ ↦ ⟨Function.update x i z, htV fun j hj ↦ ?_, by simp⟩ + rw [Function.update_of_ne (ne_of_mem_of_not_mem hj hiJ)] + exact mem_of_mem_nhds (ht j) + · rintro (he | ⟨hloc, hfin⟩) + · exact ⟨he.elim⟩ + · exact locallyConnectedSpace_of_finite_not_preconnectedSpace hfin + end LocallyConnectedSpace diff --git a/Mathlib/Topology/Connected/LocallyPathConnected.lean b/Mathlib/Topology/Connected/LocallyPathConnected.lean index b5ff93d8531de0..14d2f01fbdc4c3 100644 --- a/Mathlib/Topology/Connected/LocallyPathConnected.lean +++ b/Mathlib/Topology/Connected/LocallyPathConnected.lean @@ -29,6 +29,12 @@ path-connected, in that each point has a basis of path-connected neighborhoods. path-connected spaces are locally path-connected. * `Sum.locallyPathConnectedSpace` / `Sigma.locallyPathConnectedSpace`: disjoint unions of locally path-connected spaces are locally path-connected. +* `Prod.locallyPathConnectedSpace` / `Pi.locallyPathConnectedSpace`: binary products of locally + path-connected spaces are locally path-connected; likewise for pi types when the index type is + finite or all factors are path-connected. +* `Pi.locallyPathConnectedSpace_iff`: a product of spaces is locally path-connected iff it is + empty, or every factor is locally path-connected and all but finitely many factors are + path-connected. Abstractly, this also shows that locally path-connected spaces form a coreflective subcategory of the category of topological spaces, although we do not prove that in this form here. @@ -299,6 +305,84 @@ instance Sigma.locallyPathConnectedSpace {X : ι → Type*} @[deprecated (since := "2026-06-21")] alias Sigma.locPathConnectedSpace := Sigma.locallyPathConnectedSpace +/-- The product of two locally path-connected spaces is locally path-connected. -/ +instance Prod.locallyPathConnectedSpace [LocallyPathConnectedSpace Y] : + LocallyPathConnectedSpace (X × Y) where + path_connected_basis := fun (x, y) ↦ hasBasis_self.mpr fun U hU ↦ by + obtain ⟨u, hu, v, hv, huv⟩ := mem_nhds_prod_iff.mp hU + exact ⟨pathComponentIn u x ×ˢ pathComponentIn v y, + prod_mem_nhds (pathComponentIn_mem_nhds hu) (pathComponentIn_mem_nhds hv), + (isPathConnected_pathComponentIn (mem_of_mem_nhds hu)).prod + (isPathConnected_pathComponentIn (mem_of_mem_nhds hv)), + (Set.prod_mono pathComponentIn_subset pathComponentIn_subset).trans huv⟩ + +/-- If each `Z i` is locally path-connected and all but finitely many are path-connected, then +`∀ i, Z i` is locally path-connected. -/ +theorem Pi.locallyPathConnectedSpace_of_finite_not_pathConnectedSpace {Z : ι → Type*} + [∀ i, TopologicalSpace (Z i)] [∀ i, LocallyPathConnectedSpace (Z i)] + (hfinite : {i | ¬PathConnectedSpace (Z i)}.Finite) : + LocallyPathConnectedSpace (∀ i, Z i) where + path_connected_basis x := hasBasis_self.mpr fun U hU ↦ by + rw [nhds_pi, Filter.mem_pi] at hU + obtain ⟨J, hJ, t, ht, htU⟩ := hU + let K := J ∪ {i | ¬PathConnectedSpace (Z i)} + refine ⟨K.pi fun i ↦ pathComponentIn (t i) (x i), + set_pi_mem_nhds (hJ.union hfinite) fun i _ ↦ pathComponentIn_mem_nhds (ht i), ?_, + fun f hf ↦ htU fun i hiJ ↦ pathComponentIn_subset (hf i (mem_union_left _ hiJ))⟩ + classical + rw [← univ_pi_piecewise_univ] + refine .pi fun i ↦ ?_ + by_cases hi : i ∈ K + · rw [piecewise_eq_of_mem _ _ _ hi] + exact isPathConnected_pathComponentIn (mem_of_mem_nhds (ht i)) + · rw [piecewise_eq_of_notMem _ _ _ hi] + have : PathConnectedSpace (Z i) := not_not.mp (not_or.1 hi).2 + exact isPathConnected_univ + +/-- A finite product of locally path-connected spaces is locally path-connected. -/ +instance Pi.locallyPathConnectedSpace_of_finite [Finite ι] {Z : ι → Type*} + [∀ i, TopologicalSpace (Z i)] [∀ i, LocallyPathConnectedSpace (Z i)] : + LocallyPathConnectedSpace (∀ i, Z i) := + locallyPathConnectedSpace_of_finite_not_pathConnectedSpace (toFinite _) + +/-- A product of path-connected, locally path-connected spaces is locally path-connected. Note +that an arbitrary product of locally path-connected spaces need not be locally path-connected, so +the path-connectedness assumption cannot be dropped entirely (though it can be dropped for +finitely many factors, see `Pi.locallyPathConnectedSpace_of_finite_not_pathConnectedSpace`). -/ +instance Pi.locallyPathConnectedSpace {Z : ι → Type*} [∀ i, TopologicalSpace (Z i)] + [∀ i, LocallyPathConnectedSpace (Z i)] [∀ i, PathConnectedSpace (Z i)] : + LocallyPathConnectedSpace (∀ i, Z i) := + locallyPathConnectedSpace_of_finite_not_pathConnectedSpace + (finite_empty.subset fun _ hi ↦ hi inferInstance) + +/-- A product of spaces is locally path-connected iff it is empty, or every factor is locally +path-connected and all but finitely many factors are path-connected. -/ +theorem Pi.locallyPathConnectedSpace_iff {Z : ι → Type*} [∀ i, TopologicalSpace (Z i)] : + LocallyPathConnectedSpace (∀ i, Z i) ↔ + IsEmpty (∀ i, Z i) ∨ + (∀ i, LocallyPathConnectedSpace (Z i)) ∧ {i | ¬PathConnectedSpace (Z i)}.Finite := by + refine ⟨fun h ↦ ?_, ?_⟩ + · rcases isEmpty_or_nonempty (∀ i, Z i) with he | hne + · exact .inl he + obtain ⟨x⟩ := hne + classical + have : ∀ i, Nonempty (Z i) := Classical.nonempty_pi.mp ⟨x⟩ + refine .inr ⟨fun i ↦ ((isOpenMap_eval i).isQuotientMap (continuous_apply i) + (surjective_eval i)).locallyPathConnectedSpace, ?_⟩ + have hVn : pathComponent x ∈ 𝓝 x := + (IsOpen.pathComponent x).mem_nhds (mem_pathComponent_self x) + rw [nhds_pi, Filter.mem_pi] at hVn + obtain ⟨J, hJ, t, ht, htV⟩ := hVn + refine hJ.subset fun i hi ↦ by_contra fun hiJ ↦ hi ?_ + suffices himg : eval i '' pathComponent x = univ from pathConnectedSpace_iff_univ.mpr + (himg ▸ isPathConnected_pathComponent.image (continuous_apply i)) + refine (subset_univ _).antisymm fun z _ ↦ ⟨update x i z, htV fun j hj ↦ ?_, by simp⟩ + rw [update_of_ne (ne_of_mem_of_not_mem hj hiJ)] + exact mem_of_mem_nhds (ht j) + · rintro (he | ⟨hloc, hfin⟩) + · exact ⟨he.elim⟩ + · exact locallyPathConnectedSpace_of_finite_not_pathConnectedSpace hfin + instance AlexandrovDiscrete.locallyPathConnectedSpace [AlexandrovDiscrete X] : LocallyPathConnectedSpace X := by apply LocallyPathConnectedSpace.of_bases nhds_basis_nhdsKer_singleton diff --git a/Mathlib/Topology/Homeomorph/Lemmas.lean b/Mathlib/Topology/Homeomorph/Lemmas.lean index 4257d91ebbd659..37889e18b3cb37 100644 --- a/Mathlib/Topology/Homeomorph/Lemmas.lean +++ b/Mathlib/Topology/Homeomorph/Lemmas.lean @@ -87,8 +87,8 @@ theorem isConnected_preimage {s : Set Y} (h : X ≃ₜ Y) : theorem image_connectedComponentIn {s : Set X} (h : X ≃ₜ Y) {x : X} (hx : x ∈ s) : h '' connectedComponentIn s x = connectedComponentIn (h '' s) (h x) := by - refine (h.continuous.image_connectedComponentIn_subset hx).antisymm ?_ - have := h.symm.continuous.image_connectedComponentIn_subset (mem_image_of_mem h hx) + refine (h.continuous.continuousOn.image_connectedComponentIn_subset hx).antisymm ?_ + have := h.symm.continuous.continuousOn.image_connectedComponentIn_subset (mem_image_of_mem h hx) rwa [image_subset_iff, h.preimage_symm, h.image_symm, h.preimage_image, h.symm_apply_apply] at this From 899f7e5fd0f3d35015ae969135f529db8878a920 Mon Sep 17 00:00:00 2001 From: mpacholski <227430665+mpacholski@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:26:56 +0000 Subject: [PATCH 1143/1300] =?UTF-8?q?feat(Topology/Algebra/Module/Spaces/C?= =?UTF-8?q?ontinuousLinearMap):=20convert=20`toLinearMap=E2=82=81=E2=82=82?= =?UTF-8?q?`=20to=20a=20linear=20map=20(#41731)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the projection `toLinearMap₁₂` (which strips the topology from a continuous semibilinear map) to a linear map, by showing that it preserves addition and scalar multiplication. We also rename `toLinearMap₁₂_apply` to `toLinearMap₁₂_apply_apply_apply` without deprecation so that we can have `_apply` be a different lemma. Co-authored-by: Joël Riou <37772949+joelriou@users.noreply.github.com> Co-authored-by: JX-Mo <296066944+JX-Mo@users.noreply.github.com> Co-authored-by: mathlib-splicebot[bot] <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Co-authored-by: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Co-authored-by: Rémy Degenne <4094732+RemyDegenne@users.noreply.github.com> Co-authored-by: David Loeffler Co-authored-by: Yi.Yuan Co-authored-by: Chris Henson <46805207+chenson2018@users.noreply.github.com> Co-authored-by: Thomas Browning <13339017+tb65536@users.noreply.github.com> Co-authored-by: mitchell-horner <29882987+mitchell-horner@users.noreply.github.com> Co-authored-by: Seewoo Lee <49933279+seewoo5@users.noreply.github.com> Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> Co-authored-by: Yaël Dillies Co-authored-by: Jz Pan <3397779+acmepjz@users.noreply.github.com> Co-authored-by: Kevin Buzzard Co-authored-by: Michał Pacholski Co-authored-by: Bhavik Mehta <29959226+b-mehta@users.noreply.github.com> Co-authored-by: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Co-authored-by: Richard Osborn Co-authored-by: Brian Nugent --- Mathlib/Analysis/Fourier/FourierTransformDeriv.lean | 4 ++-- .../CharacteristicFunction/TaylorExpansion.lean | 5 ++--- .../Algebra/Module/Spaces/ContinuousLinearMap.lean | 11 +++++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean index 01d43a1b8b62e8..0a07d00935193c 100644 --- a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean +++ b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean @@ -263,8 +263,8 @@ theorem fourierIntegral_fderiv [MeasurableSpace V] [BorelSpace V] [FiniteDimensi /- First rewrite things in a simplified form, without any real change. -/ suffices ∫ x, g x • fderiv ℝ f x y ∂μ = ∫ x, (2 * ↑π * I * L y w * g x) • f x ∂μ by rw [fourierIntegral_continuousLinearMap_apply' hf'] - simpa only [fourierIntegral, ContinuousLinearMap.toLinearMap₁₂_apply, fourierSMulRight_apply, - neg_apply, ContinuousLinearMap.flip_apply, ← integral_smul, neg_smul, + simpa only [fourierIntegral, ContinuousLinearMap.toLinearMap₁₂_apply_apply_apply, + fourierSMulRight_apply, neg_apply, ContinuousLinearMap.flip_apply, ← integral_smul, neg_smul, smul_neg, ← smul_smul, coe_smul, neg_neg] -- Key step: integrate by parts with respect to `y` to switch the derivative from `f` to `g`. have A x : fderiv ℝ g x y = - 2 * ↑π * I * L y w * g x := diff --git a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean index 2c5f7e64be0c71..e11fe18fba5c33 100644 --- a/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean +++ b/Mathlib/MeasureTheory/Measure/CharacteristicFunction/TaylorExpansion.lean @@ -66,7 +66,6 @@ lemma continuous_charFun : Continuous (charFun μ) := by refine contDiff_zero.1 (contDiff_charFun ?_) simpa using by fun_prop -set_option backward.isDefEq.respectTransparency false in theorem iteratedFDeriv_charFun {n : ℕ} {t : E} (hint : MemLp id n μ) (x : Fin n → E) : iteratedFDeriv ℝ n (charFun μ) t x = I ^ n * ∫ y, (∏ i, ⟪y, x i⟫) * exp (⟪y, t⟫ * I) ∂μ := by have h : innerₗ E = (innerSL ℝ).toLinearMap₁₂ := rfl @@ -85,8 +84,8 @@ theorem iteratedFDeriv_charFun {n : ℕ} {t : E} (hint : MemLp id n μ) (x : Fin rw [fourierIntegral_continuousMultilinearMap_apply Real.continuous_fourierChar] swap; · exact integrable_fourierPowSMulRight _ (by simpa using hint.integrable_norm_pow') (by fun_prop) - simp only [fourierIntegral, Real.fourierChar, Circle.exp, ContinuousMap.coe_mk, ofReal_mul, - ofReal_ofNat, innerSL, map_neg, map_smul, ContinuousLinearMap.toLinearMap₁₂_apply, + simp only [fourierIntegral, Real.fourierChar, Circle.coe_exp, ofReal_mul, + ofReal_ofNat, innerSL, map_neg, map_smul, ContinuousLinearMap.toLinearMap₁₂_apply_apply_apply, LinearMap.mkContinuous₂_apply, innerₛₗ_apply_apply, smul_eq_mul, neg_neg, AddChar.coe_mk, ofReal_inv, fourierPowSMulRight_apply, Pi.ofNat_apply, real_smul, ofReal_prod, mul_one, Circle.smul_def] diff --git a/Mathlib/Topology/Algebra/Module/Spaces/ContinuousLinearMap.lean b/Mathlib/Topology/Algebra/Module/Spaces/ContinuousLinearMap.lean index f0a3681fab4122..a59c26385477df 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/ContinuousLinearMap.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/ContinuousLinearMap.lean @@ -299,14 +299,17 @@ theorem map_smulₛₗ₂ (f : E →SL[σ₁₃] F →SL[σ₂₃] G) (c : R) (x f (c • x) y = σ₁₃ c • f x y := by rw [f.map_smulₛₗ, smul_apply] /-- Send a continuous sesquilinear map to an abstract sesquilinear map (forgetting continuity). -/ -def toLinearMap₁₂ (L : E →SL[σ₁₃] F →SL[σ₂₃] G) : E →ₛₗ[σ₁₃] F →ₛₗ[σ₂₃] G := - (coeLMₛₗ σ₂₃).comp L.toLinearMap +@[simps -isSimp apply] +def toLinearMap₁₂ : (E →SL[σ₁₃] F →SL[σ₂₃] G) →ₗ[𝕜₃] E →ₛₗ[σ₁₃] F →ₛₗ[σ₂₃] G where + toFun L := (coeLMₛₗ σ₂₃).comp L.toLinearMap + map_add' _ _ := rfl + map_smul' _ _ := rfl -@[simp] lemma toLinearMap₁₂_apply (L : E →SL[σ₁₃] F →SL[σ₂₃] G) (v : E) (w : F) : +@[simp] lemma toLinearMap₁₂_apply_apply_apply (L : E →SL[σ₁₃] F →SL[σ₂₃] G) (v : E) (w : F) : L.toLinearMap₁₂ v w = L v w := rfl lemma toLinearMap₁₂_injective : - (toLinearMap₁₂ (E := E) (F := F) (G := G) (σ₁₃ := σ₁₃) (σ₂₃ := σ₂₃)).Injective := by + (toLinearMap₁₂ (E := E) (F := F) (G := G) (σ₁₃ := σ₁₃) (σ₂₃ := σ₂₃) : _ → _).Injective := by simp [Function.Injective, LinearMap.ext_iff, ← ContinuousLinearMap.ext_iff] lemma toLinearMap₁₂_inj (L₁ L₂ : E →SL[σ₁₃] F →SL[σ₂₃] G) : From 9fb10993c11c9e7abfa291e86fb499b6e1f4da82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Mon, 3 Aug 2026 21:26:58 +0000 Subject: [PATCH 1144/1300] feat(Topology/Order): the bornology of an unbounded order is non-trivial (#42030) Also generalise the fact that cobounded sets tend to top/bot from linear orders to preorders (without a max/min element). --- Mathlib/Order/Filter/Basic.lean | 4 ++++ Mathlib/Topology/Order/Bornology.lean | 33 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 1fb22e6f63d079..98f4c29e9ba60b 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -260,6 +260,7 @@ theorem NeBot.ne {f : Filter α} (hf : NeBot f) : f ≠ ⊥ := hf.ne' @[simp, push] theorem not_neBot {f : Filter α} : ¬f.NeBot ↔ f = ⊥ := neBot_iff.not_left +@[gcongr] theorem NeBot.mono {f g : Filter α} (hf : NeBot f) (hg : f ≤ g) : NeBot g := ⟨ne_bot_of_le_ne_bot hf.1 hg⟩ @@ -269,6 +270,9 @@ theorem neBot_of_le {f g : Filter α} [hf : NeBot f] (hg : f ≤ g) : NeBot g := @[simp] theorem sup_neBot {f g : Filter α} : NeBot (f ⊔ g) ↔ NeBot f ∨ NeBot g := by simp only [neBot_iff, not_and_or, Ne, sup_eq_bot_iff] +instance neBot_sup_of_left {f g : Filter α} [f.NeBot] : NeBot (f ⊔ g) := by simp [*] +instance neBot_sup_of_right {f g : Filter α} [g.NeBot] : NeBot (f ⊔ g) := by simp [*] + theorem not_disjoint_self_iff : ¬Disjoint f f ↔ f.NeBot := by rw [disjoint_self, neBot_iff] theorem bot_sets_eq : (⊥ : Filter α).sets = univ := rfl diff --git a/Mathlib/Topology/Order/Bornology.lean b/Mathlib/Topology/Order/Bornology.lean index bcb58e3988f495..f7abb517fa382d 100644 --- a/Mathlib/Topology/Order/Bornology.lean +++ b/Mathlib/Topology/Order/Bornology.lean @@ -99,27 +99,37 @@ instance Pi.instIsOrderBornology {ι : Type*} {α : ι → Type*} [∀ i, Preord simp_rw [← forall_isBounded_image_eval_iff, bddBelow_pi, bddAbove_pi, ← forall_and, isBounded_iff_bddBelow_bddAbove] -end Preorder +variable (α) in +lemma Nonempty.of_isOrderBornology : Nonempty α := Bornology.isBounded_empty.bddBelow.nonempty -section LinearOrder +instance IsOrderBornology.neBot_cobounded_of_noBotOrder [NoBotOrder α] : (cobounded α).NeBot := by + simp [Filter.neBot_iff, cobounded_eq_bot_iff, ← isBounded_univ, isBounded_iff_bddBelow_bddAbove] -variable [Nonempty α] [LinearOrder α] [IsOrderBornology α] +instance IsOrderBornology.neBot_cobounded_of_noTopOrder [NoTopOrder α] : (cobounded α).NeBot := + neBot_cobounded_of_noBotOrder (α := αᵒᵈ) lemma IsOrderBornology.atTop_le_cobounded [NoMaxOrder α] : .atTop ≤ Bornology.cobounded α := by - intro s - rw [← compl_compl s, ← isBounded_def, isBounded_iff_bddBelow_bddAbove, compl_compl s, - Filter.atTop_basis_Ioi.mem_iff] - intro ⟨_, b, hb⟩ - rw [mem_upperBounds_iff_subset_Iic, ← compl_compl (Iic b), compl_subset_compl, compl_Iic] at hb - use b + intro s hs + rw [← compl_compl s, ← isBounded_def, isBounded_iff_bddBelow_bddAbove] at hs + obtain ⟨b, hb⟩ := hs.2 + obtain ⟨c, hbc⟩ := exists_gt b + refine Filter.mem_of_superset (Filter.mem_atTop c) fun x hx ↦ ?_ + by_contra hx' + exact hbc.not_ge <| hx.trans <| hb <| mem_compl hx' -- TODO (khw): Generate this in the future with `to_dual` -- See https://github.com/leanprover-community/mathlib4/pull/37738 lemma IsOrderBornology.atBot_le_cobounded [NoMinOrder α] : .atBot ≤ Bornology.cobounded α := atTop_le_cobounded (α := αᵒᵈ) -lemma IsOrderBornology.cobounded_le_atBot_sup_atTop : - cobounded α ≤ .atBot ⊔ .atTop := by +end Preorder + +section LinearOrder + +variable [LinearOrder α] [IsOrderBornology α] + +lemma IsOrderBornology.cobounded_le_atBot_sup_atTop : cobounded α ≤ .atBot ⊔ .atTop := by + have := Nonempty.of_isOrderBornology α intro s rw [Filter.mem_sup, Filter.atTop_basis.mem_iff, Filter.atBot_basis.mem_iff, ← compl_compl s, ← isBounded_def, isBounded_iff_bddBelow_bddAbove, compl_compl s] @@ -145,6 +155,7 @@ lemma IsOrderBornology.cobounded_eq_atTop [NoMaxOrder α] [OrderBot α] : -- TODO (khw): Generate this in the future with `to_dual` -- See https://github.com/leanprover-community/mathlib4/pull/37738 +@[to_dual existing] lemma IsOrderBornology.cobounded_eq_atBot [NoMinOrder α] [OrderTop α] : Bornology.cobounded α = .atBot := cobounded_eq_atTop (α := αᵒᵈ) From 1c3257b287ab86713ef4c1ae68a4a39c249b8468 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Tue, 4 Aug 2026 14:32:19 +0000 Subject: [PATCH 1145/1300] =?UTF-8?q?chore(Topology):=20state=20Heine?= =?UTF-8?q?=E2=80=93Borel=20theorem=20for=20metric=20spaces=20(#42241)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes the assumptions of `isCompact_iff_isClosed_bounded` from `[PseudoMetricSpace α] [T2Space α]` to `[MetricSpace α]`, giving the usual metric-space formulation of the Heine–Borel theorem. This requires importing `Mathlib.Topology.MetricSpace.Basic`, which provides `MetricSpace.instT0Space`. Together with the regularity of uniform spaces, this allows `T2Space α` to be inferred from `MetricSpace α`, as needed to show that compact sets are closed. ```lean instance (priority := 100) _root_.MetricSpace.instT0Space : T0Space γ where t0 _ _ h := eq_of_dist_eq_zero <| Metric.inseparable_iff.1 h ``` --- Mathlib/Topology/MetricSpace/Bounded.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/MetricSpace/Bounded.lean b/Mathlib/Topology/MetricSpace/Bounded.lean index b8c98c6936ff4e..21b9c3843d5a62 100644 --- a/Mathlib/Topology/MetricSpace/Bounded.lean +++ b/Mathlib/Topology/MetricSpace/Bounded.lean @@ -9,7 +9,7 @@ public import Mathlib.Topology.Order.Bornology public import Mathlib.Topology.Order.Compact public import Mathlib.Topology.MetricSpace.ProperSpace public import Mathlib.Topology.MetricSpace.Cauchy -public import Mathlib.Topology.MetricSpace.Defs +public import Mathlib.Topology.MetricSpace.Basic public import Mathlib.Topology.EMetricSpace.Diam /-! @@ -329,11 +329,10 @@ theorem _root_.Bornology.IsBounded.isCompact_closure [ProperSpace α] (h : IsBou IsCompact (closure s) := isCompact_of_isClosed_isBounded isClosed_closure h.closure --- TODO: assume `[MetricSpace α]` instead of `[PseudoMetricSpace α] [T2Space α]` /-- The **Heine–Borel theorem**: -In a proper Hausdorff space, a set is compact if and only if it is closed and bounded. -/ +In a proper metric space, a set is compact if and only if it is closed and bounded. -/ @[wikidata Q253214] -theorem isCompact_iff_isClosed_bounded [T2Space α] [ProperSpace α] : +theorem isCompact_iff_isClosed_bounded {α : Type*} {s : Set α} [MetricSpace α] [ProperSpace α] : IsCompact s ↔ IsClosed s ∧ IsBounded s := ⟨fun h => ⟨h.isClosed, h.isBounded⟩, fun h => isCompact_of_isClosed_isBounded h.1 h.2⟩ From a4b006456e26f4d2de94fc8aa21f20c357a83f04 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:58:09 +0000 Subject: [PATCH 1146/1300] feat(Analysis): open half planes are open (#42325) Specializing existing lemmas for EReal to to real numbers to simplify using them. Found while reviewing #41120 Co-authored-by: Batixx --- Mathlib/Analysis/Complex/HalfPlane.lean | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Complex/HalfPlane.lean b/Mathlib/Analysis/Complex/HalfPlane.lean index 009b9704f593d1..33066827055629 100644 --- a/Mathlib/Analysis/Complex/HalfPlane.lean +++ b/Mathlib/Analysis/Complex/HalfPlane.lean @@ -12,7 +12,7 @@ public import Mathlib.Topology.Instances.EReal.Lemmas # Half-planes in ℂ are open We state that open left, right, upper and lower half-planes in the complex numbers are open sets, -where the bounding value of the real or imaginary part is given by an `EReal` `x`. +where the bounding value of the real or imaginary part is given by a real or `EReal` `x`. So this includes the full plane and the empty set for `x = ⊤`/`x = ⊥`. -/ @@ -40,4 +40,20 @@ in the complex plane. -/ lemma isOpen_im_gt_EReal (x : EReal) : IsOpen {z : ℂ | x < z.im} := isOpen_lt continuous_const <| EReal.continuous_coe_iff.mpr continuous_im +/-- An open left half-plane is an open set in the complex plane. -/ +lemma isOpen_re_lt (x : ℝ) : IsOpen {z : ℂ | z.re < x} := by + simpa using isOpen_re_lt_EReal x + +/-- An open right half-plane is an open set in the complex plane. -/ +lemma isOpen_re_gt (x : ℝ) : IsOpen {z : ℂ | x < z.re} := by + simpa using isOpen_re_gt_EReal x + +/-- An open lower half-plane is an open set in the complex plane. -/ +lemma isOpen_im_lt (x : ℝ) : IsOpen {z : ℂ | z.im < x} := by + simpa using isOpen_im_lt_EReal x + +/-- An open upper half-plane is an open set in the complex plane. -/ +lemma isOpen_im_gt (x : ℝ) : IsOpen {z : ℂ | x < z.im} := by + simpa using isOpen_im_gt_EReal x + end Complex From ce533466c45a1273a8a5cb302c5d81a50047f564 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:58:12 +0000 Subject: [PATCH 1147/1300] chore(RingTheory/IsGaloisGroup/Basic): automated extraction from #42430 (#42433) This PR was automatically created from PR #42430 by @vihdzp via a [review comment](https://github.com/leanprover-community/mathlib4/pull/42430#discussion_r3711030239) by @grunweg. Co-authored-by: vihdzp <65465670+vihdzp@users.noreply.github.com> --- Mathlib/RingTheory/IsGaloisGroup/Basic.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean index 8dd8974d9fb075..97c8d4a5c277d4 100644 --- a/Mathlib/RingTheory/IsGaloisGroup/Basic.lean +++ b/Mathlib/RingTheory/IsGaloisGroup/Basic.lean @@ -232,10 +232,8 @@ instance isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDi ⟨fun g q b ↦ Quotient.inductionOn' q fun h ↦ by simp [mul_smul, mulSemiringActionQuotient_smul_def]⟩ -set_option linter.defProp false in /-- If `G` acts on `C` commuting with `A`, then the action of `G ⧸ N` on `B` commutes with `A`. -/ -@[implicit_reducible] -def smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCommClass G A C] +theorem smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCommClass G A C] [MulSemiringAction G B] [MulAction (G ⧸ N) B] [SMulDistribClass G B C] [IsScalarTower G (G ⧸ N) B] : SMulCommClass (G ⧸ N) A B := From 98d2c1d1cfc83510faf337915e038395fe11d55b Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 4 Aug 2026 16:19:27 +0000 Subject: [PATCH 1148/1300] feat(SimpleGraph/Walk/Operations): more operations API (#41460) Tags `Hom.ofLE` as `@[implicit_reducible]` to let `rw`/`simp` use `map` API on `mapLe`. --- Mathlib/Combinatorics/SimpleGraph/Maps.lean | 1 + Mathlib/Combinatorics/SimpleGraph/Paths.lean | 2 +- .../SimpleGraph/Walk/Decomp.lean | 2 +- .../Combinatorics/SimpleGraph/Walk/Maps.lean | 23 ++++-- .../SimpleGraph/Walk/Operations.lean | 72 ++++++++++++++++--- 5 files changed, 84 insertions(+), 16 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index 79ab2b98e6486c..3768ec77d9fbff 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -377,6 +377,7 @@ theorem mapDart_apply (d : G.Dart) : f.mapDart d = ⟨d.1.map f f, f.map_adj d.2 rfl /-- The graph homomorphism from a smaller graph to a bigger one. -/ +@[implicit_reducible] def ofLE (h : G₁ ≤ G₂) : G₁ →g G₂ := ⟨id, @h⟩ @[simp, norm_cast] lemma coe_ofLE (h : G₁ ≤ G₂) : ⇑(ofLE h) = id := rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Paths.lean b/Mathlib/Combinatorics/SimpleGraph/Paths.lean index 72c20270bc7c13..3897513af01175 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Paths.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Paths.lean @@ -373,7 +373,7 @@ theorem IsCycle.isPath_drop {u n} {p : G.Walk u u} (h : p.IsCycle) (hn : 0 < n) (p.drop n).IsPath := by replace h : (p.drop 1).IsPath := h.isPath_tail rw [← Nat.add_sub_of_le hn, drop_add_eq] - simp [h.drop (n - 1)] + simp [h.drop (n - 1), -drop_drop] theorem IsCycle.isPath_take {u n} {p : G.Walk u u} (h : p.IsCycle) (hn : n < p.length) : (p.take n).IsPath := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean index 818eeb1e01be55..f74b63651bbed1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Decomp.lean @@ -117,7 +117,7 @@ lemma dropUntil_eq_drop (p : G.Walk u v) (h : w ∈ p.support) : | @cons a _ _ _ p ih => by_cases! h' : w = a · subst h' - simp [dropUntil_first, drop_support_eq_support_drop_min] + simp [dropUntil_first] · rw [drop_cons_eq _ _ _ (by grind), support_copy, dropUntil] grind diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean index bfb974927be9d2..36bffe5606e240 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Maps.lean @@ -86,6 +86,7 @@ theorem map_eq_nil_iff {p : G.Walk u u} : p.map f = nil ↔ p = nil := by cases @[simp] theorem length_map : (p.map f).length = p.length := by induction p <;> simp [*] +@[simp] theorem map_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) : (p.append q).map f = (p.map f).append (q.map f) := by induction p <;> simp [*] @@ -129,14 +130,24 @@ variable {G' : SimpleGraph V} (h : G ≤ G') {u v : V} (p : G.Walk u v) abbrev mapLe : G'.Walk u v := p.map (.ofLE h) -set_option backward.isDefEq.respectTransparency false in -lemma support_mapLe_eq_support : (p.mapLe h).support = p.support := by simp +theorem length_mapLe : (p.mapLe h).length = p.length := by + simp + +lemma support_mapLe_eq_support : (p.mapLe h).support = p.support := by + simp + +lemma edges_mapLe_eq_edges : (p.mapLe h).edges = p.edges := by + simp + +lemma edgeSet_mapLe_eq_edgeSet : (p.mapLe h).edgeSet = p.edgeSet := by + simp -set_option backward.isDefEq.respectTransparency false in -lemma edges_mapLe_eq_edges : (p.mapLe h).edges = p.edges := by simp +theorem reverse_mapLe : (p.mapLe h).reverse = p.reverse.mapLe h := by + simp -set_option backward.isDefEq.respectTransparency false in -lemma edgeSet_mapLe_eq_edgeSet : (p.mapLe h).edgeSet = p.edgeSet := by simp +theorem mapLe_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) : + (p.append q).mapLe h = (p.mapLe h).append (q.mapLe h) := by + simp end mapLe diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean index aea91e0f61c68b..b028a0cc114ec1 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean @@ -246,6 +246,11 @@ theorem getVert_append {u v w : V} (p : G.Walk u v) (q : G.Walk v w) (i : ℕ) : (p.append q).getVert i = if i < p.length then p.getVert i else q.getVert (i - p.length) := by induction p generalizing i <;> cases i <;> simp [*] +/-- This uses `p` instead of `q` when `i = p.length` unlike the unprimed version. -/ +theorem getVert_append' (p : G.Walk u v) (q : G.Walk v w) (i : ℕ) : + (p.append q).getVert i = if i ≤ p.length then p.getVert i else q.getVert (i - p.length) := by + induction p generalizing i <;> cases i <;> simp [*] + theorem getVert_reverse {u v : V} (p : G.Walk u v) (i : ℕ) : p.reverse.getVert i = p.getVert (p.length - i) := by induction p with @@ -626,6 +631,7 @@ lemma support_take {u v} (p : G.Walk u v) (n : ℕ) : @[deprecated (since := "2026-05-20")] alias take_support_eq_support_take_succ := support_take +@[simp] lemma take_take (p : G.Walk u v) (n m : ℕ) : (p.take n).take m = (p.take (min n m)).copy rfl (p.take_getVert n m).symm := by apply ext_support @@ -667,6 +673,14 @@ lemma penultimate_reverse (p : G.Walk u v) : p.reverse.penultimate = p.snd := by /-- The walk obtained by removing the first dart of a walk. A nil walk stays nil. -/ def tail (p : G.Walk u v) : G.Walk (p.snd) v := p.drop 1 +@[simp] +theorem darts_tail {p : G.Walk u v} : p.tail.darts = p.darts.tail := by + simp [tail, darts_drop] + +@[simp] +theorem edges_tail {p : G.Walk u v} : p.tail.edges = p.edges.tail := by + simp [tail, edges_drop] + @[simp] lemma drop_zero {u v} (p : G.Walk u v) : p.drop 0 = p.copy (getVert_zero p).symm rfl := by @@ -676,10 +690,17 @@ lemma nil_drop_of_length_le {u v n} {p : G.Walk u v} (h : p.length ≤ n) : (p.drop n).Nil := by rw [← length_eq_zero_iff, drop_length, Nat.sub_eq_zero_of_le h] +@[simp] lemma drop_support_eq_support_drop_min {u v} (p : G.Walk u v) (n : ℕ) : (p.drop n).support = p.support.drop (n ⊓ p.length) := by induction p generalizing n <;> cases n <;> simp [*, drop] +@[simp] +theorem drop_drop (p : G.Walk u v) (n m : ℕ) : + (p.drop n).drop m = (p.drop (n + m)).copy (drop_getVert ..).symm rfl := by + apply ext_support + grind [support_copy, drop_support_eq_support_drop_min, drop_length, List.drop_drop] + @[simp] theorem append_take_drop_eq (p : G.Walk u v) (n : ℕ) : (p.take n).append (p.drop n) = p := by apply ext_support @@ -718,6 +739,14 @@ lemma dropLast_cons_of_not_nil (h : G.Adj u v) (p : G.Walk v w) (hp : ¬ p.Nil) (cons h p).dropLast = cons h (p.dropLast.copy rfl (penultimate_cons_of_not_nil _ _ hp).symm) := p.notNilRec (by simp) hp h +@[simp] +theorem darts_dropLast {p : G.Walk u v} : p.dropLast.darts = p.darts.dropLast := by + simp [dropLast, darts_take, List.dropLast_eq_take] + +@[simp] +theorem edges_dropLast {p : G.Walk u v} : p.dropLast.edges = p.edges.dropLast := by + simp [dropLast, edges_take, List.dropLast_eq_take] + @[simp] lemma dropLast_concat {t u v} (p : G.Walk u v) (h : G.Adj v t) : (p.concat h).dropLast = p.copy rfl (by simp) := by @@ -741,9 +770,13 @@ lemma concat_dropLast {p : G.Walk u v} (hp : G.Adj p.penultimate v) : p.dropLast | nil => rfl | _ => simp [hind] -@[simp] lemma cons_support_tail {p : G.Walk u v} (hp : ¬p.Nil) : - u :: p.tail.support = p.support := by - rw [← support_cons (p.adj_snd hp), cons_tail_eq _ hp] +@[simp] +lemma support_tail_of_not_nil (p : G.Walk u v) (hp : ¬ p.Nil) : + p.tail.support = p.support.tail := by + simp [← p.cons_tail_eq hp] + +lemma cons_support_tail {p : G.Walk u v} (hp : ¬p.Nil) : u :: p.tail.support = p.support := by + simp [hp] theorem support_dropLast_concat {p : G.Walk u v} (hp : ¬p.Nil) : p.dropLast.support ++ [v] = p.support := by @@ -754,7 +787,11 @@ theorem support_dropLast {p : G.Walk u v} (hp : ¬p.Nil) : p.dropLast.support = p.support.dropLast := by simp [← support_dropLast_concat hp] -@[simp] lemma length_tail_add_one {p : G.Walk u v} (hp : ¬ p.Nil) : +@[simp] +theorem length_tail (p : G.Walk u v) : p.tail.length = p.length - 1 := by + cases p <;> simp + +lemma length_tail_add_one {p : G.Walk u v} (hp : ¬ p.Nil) : p.tail.length + 1 = p.length := by rw [← length_cons (p.adj_snd hp), cons_tail_eq _ hp] @@ -766,6 +803,29 @@ lemma length_dropLast_add_one {p : G.Walk u v} (hp : ¬p.Nil) : lemma length_dropLast (p : G.Walk u v) : p.dropLast.length = p.length - 1 := by cases p <;> simp [← length_dropLast_add_one not_nil_cons] +theorem getVert_dropLast {n} {p : G.Walk u v} (h : n < p.length) : + p.dropLast.getVert n = p.getVert n := by + grind [getVert_eq_support_getElem, length_dropLast, support_dropLast] + +@[simp] +theorem reverse_tail (p : G.Walk u v) : + p.tail.reverse = p.reverse.dropLast.copy rfl p.penultimate_reverse := by + match p with + | nil => simp + | cons hadj p => + apply ext_support + rw [support_copy] + simp [-reverse_cons] + +@[simp] +theorem reverse_dropLast (p : G.Walk u v) : + p.dropLast.reverse = p.reverse.tail.copy p.snd_reverse rfl := by + match p with + | nil => simp + | cons hadj p => + apply ext_support + simp [-reverse_cons, List.dropLast_cons_of_ne_nil p.support_ne_nil] + protected lemma Nil.tail {p : G.Walk v w} (hp : p.Nil) : p.tail.Nil := by cases p <;> simp at hp ⊢ @@ -786,10 +846,6 @@ lemma drop_of_length_le {u v n} {p : G.Walk u v} (h : p.length ≤ n) : p.drop n = nil.copy rfl (p.getVert_of_length_le h) := (nil_drop_of_length_le h).eq_copy_nil -lemma support_tail_of_not_nil (p : G.Walk u v) (hp : ¬ p.Nil) : - p.tail.support = p.support.tail := by - rw [← cons_support_tail hp, List.tail_cons] - @[simp] lemma getVert_copy {u v w x : V} (p : G.Walk u v) (i : ℕ) (h : u = w) (h' : v = x) : (p.copy h h').getVert i = p.getVert i := by subst_vars From 881e56ce95fd143789278c765d1949021164cb2e Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 4 Aug 2026 16:35:48 +0000 Subject: [PATCH 1149/1300] chore: golf some proofs with `grw` (#42440) Use `grw`/`gcongr` to golf some proofs. Additionally, deprecate `ENNReal.coe_le_coe_of_le`/`ENNReal.coe_lt_coe_of_lt`, as `gcongr` can now be used on iff lemmas. --- Mathlib/Analysis/Calculus/FDeriv/Extend.lean | 2 +- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 11 +++-------- Mathlib/Data/ENNReal/Basic.lean | 12 ++++-------- Mathlib/Data/Set/NAry.lean | 11 +++-------- Mathlib/Dynamics/OmegaLimit.lean | 4 +--- Mathlib/Geometry/Manifold/ChartedSpace.lean | 5 +++-- .../MeasureTheory/Function/LpSeminorm/Basic.lean | 10 +++++----- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 16 +++++++--------- .../MeasureTheory/VectorMeasure/Integral.lean | 3 ++- 9 files changed, 29 insertions(+), 45 deletions(-) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Extend.lean b/Mathlib/Analysis/Calculus/FDeriv/Extend.lean index ade989ad91a672..c7dc9d0400def8 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Extend.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Extend.lean @@ -84,7 +84,7 @@ theorem hasFDerivWithinAt_closure_of_tendsto_fderiv {f : E → F} {s : Set E} {x refine ContinuousWithinAt.closure_le uv_in ?_ ?_ key all_goals -- common start for both continuity proofs - have : (B ∩ s) ×ˢ (B ∩ s) ⊆ s ×ˢ s := by gcongr <;> exact inter_subset_right + have : (B ∩ s) ×ˢ (B ∩ s) ⊆ s ×ˢ s := by grw [inter_subset_right] obtain ⟨u_in, v_in⟩ : u ∈ closure s ∧ v ∈ closure s := by simpa [closure_prod_eq] using closure_mono this uv_in apply ContinuousWithinAt.mono _ this diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index ce61033d88f4d3..a65c8239c4c96b 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -545,8 +545,7 @@ lemma Subalgebra.frontier_subset_frontier : (spectrum.isClosed (x : A)).closure_eq] apply subset_inter (frontier_spectrum S x) rw [frontier_eq_closure_inter_closure] - exact inter_subset_right |>.trans <| - closure_mono <| compl_subset_compl.mpr <| spectrum.subset_subalgebra x + grw [inter_subset_right, spectrum.subset_subalgebra] open Set Notation @@ -568,12 +567,8 @@ lemma Subalgebra.spectrum_sUnion_connectedComponentIn : suffices h_frontier : frontier (σ 𝕜 x \ σ 𝕜 (x : A)) ⊆ frontier (σ 𝕜 (x : A)) from disjoint_of_subset_left h_frontier <| disjoint_compl_right.frontier_left (spectrum.isClosed _).isOpen_compl - rw [sdiff_eq_compl_inter] - apply (frontier_inter_subset _ _).trans - rw [frontier_compl] - apply union_subset <| inter_subset_left - refine inter_subset_inter_right _ ?_ |>.trans <| inter_subset_right - exact frontier_subset_frontier S x + grw [sdiff_eq_compl_inter, frontier_inter_subset, inter_subset_left, inter_subset_right, + frontier_compl, frontier_subset_frontier, union_self] /-- Let `S` be a closed subalgebra of a Banach algebra `A`, and let `x : S`. If `z` is in the spectrum of `x`, then the connected component of `z` in the complement of the spectrum of `↑x : A` diff --git a/Mathlib/Data/ENNReal/Basic.lean b/Mathlib/Data/ENNReal/Basic.lean index 218392836d7fad..1a0a1261a3c53c 100644 --- a/Mathlib/Data/ENNReal/Basic.lean +++ b/Mathlib/Data/ENNReal/Basic.lean @@ -369,17 +369,13 @@ theorem toReal_ofReal_eq_iff {a : ℝ} : (ENNReal.ofReal a).toReal = a ↔ 0 ≤ @[simp] theorem zero_lt_top : 0 < ∞ := coe_lt_top -@[simp, norm_cast] theorem coe_le_coe : (↑r : ℝ≥0∞) ≤ ↑q ↔ r ≤ q := WithTop.coe_le_coe +@[simp, norm_cast, gcongr] theorem coe_le_coe : (↑r : ℝ≥0∞) ≤ ↑q ↔ r ≤ q := WithTop.coe_le_coe -@[simp, norm_cast] theorem coe_lt_coe : (↑r : ℝ≥0∞) < ↑q ↔ r < q := WithTop.coe_lt_coe +@[simp, norm_cast, gcongr] theorem coe_lt_coe : (↑r : ℝ≥0∞) < ↑q ↔ r < q := WithTop.coe_lt_coe --- Needed until `@[gcongr]` accepts iff statements -alias ⟨_, coe_le_coe_of_le⟩ := coe_le_coe -attribute [gcongr] ENNReal.coe_le_coe_of_le +@[deprecated (since := "2026-08-04")] alias ⟨_, coe_le_coe_of_le⟩ := coe_le_coe --- Needed until `@[gcongr]` accepts iff statements -alias ⟨_, coe_lt_coe_of_lt⟩ := coe_lt_coe -attribute [gcongr] ENNReal.coe_lt_coe_of_lt +@[deprecated (since := "2026-08-04")] alias ⟨_, coe_lt_coe_of_lt⟩ := coe_lt_coe theorem coe_mono : Monotone ofNNReal := fun _ _ => coe_le_coe.2 diff --git a/Mathlib/Data/Set/NAry.lean b/Mathlib/Data/Set/NAry.lean index 0dc5b5f0fd1d07..6cac5450f6e7af 100644 --- a/Mathlib/Data/Set/NAry.lean +++ b/Mathlib/Data/Set/NAry.lean @@ -316,21 +316,16 @@ lemma image2_right_identity {f : α → β → α} {b : β} (h : ∀ a, f a b = theorem image2_inter_union_subset_union : image2 f (s ∩ s') (t ∪ t') ⊆ image2 f s t ∪ image2 f s' t' := by rw [image2_union_right] - exact - union_subset_union (image2_subset_right inter_subset_left) - (image2_subset_right inter_subset_right) + nth_grw 1 [inter_subset_left, inter_subset_right] theorem image2_union_inter_subset_union : image2 f (s ∪ s') (t ∩ t') ⊆ image2 f s t ∪ image2 f s' t' := by rw [image2_union_left] - exact - union_subset_union (image2_subset_left inter_subset_left) - (image2_subset_left inter_subset_right) + nth_grw 1 [inter_subset_left, inter_subset_right] theorem image2_inter_union_subset {f : α → α → β} {s t : Set α} (hf : ∀ a b, f a b = f b a) : image2 f (s ∩ t) (s ∪ t) ⊆ image2 f s t := by - rw [inter_comm] - exact image2_inter_union_subset_union.trans (union_subset (image2_comm hf).subset Subset.rfl) + grw [inter_comm, image2_inter_union_subset_union, image2_comm hf, union_self] theorem image2_union_inter_subset {f : α → α → β} {s t : Set α} (hf : ∀ a b, f a b = f b a) : image2 f (s ∪ t) (s ∩ t) ⊆ image2 f s t := by diff --git a/Mathlib/Dynamics/OmegaLimit.lean b/Mathlib/Dynamics/OmegaLimit.lean index 870d7fcb88d7fb..38670371154c17 100644 --- a/Mathlib/Dynamics/OmegaLimit.lean +++ b/Mathlib/Dynamics/OmegaLimit.lean @@ -291,9 +291,7 @@ theorem nonempty_omegaLimit_of_isCompact_absorbing [NeBot f] {c : Set β} (hc₁ exact hn.mono subset_closure · intro apply hc₁.of_isClosed_subset isClosed_closure - calc - _ ⊆ closure (image2 ϕ v s) := closure_mono (image2_subset inter_subset_right Subset.rfl) - _ ⊆ c := hv₂ + grw [inter_subset_right, hv₂] · exact fun _ ↦ isClosed_closure theorem nonempty_omegaLimit [CompactSpace β] [NeBot f] (hs : s.Nonempty) : (ω f ϕ s).Nonempty := diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 54b6df43372fdd..a67a10b439f9bc 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -276,8 +276,9 @@ theorem ChartedSpace.locallyPathConnectedSpace [LocallyPathConnectedSpace H] : apply e.symm.image_mem_nhds (by simp [e]) exact pathComponentIn_mem_nhds <| e.image_mem_nhds (mem_chart_source _ _) ht · refine (isPathConnected_pathComponentIn <| mem_image_of_mem e (mem_of_mem_nhds ht)).image' ?_ - refine e.continuousOn_symm.mono <| subset_trans ?_ e.image_source_subset - exact (pathComponentIn_mono <| image_mono inter_subset_right).trans pathComponentIn_subset + refine e.continuousOn_symm.mono ?_ + unfold t + grw [pathComponentIn_subset, inter_subset_right, e.image_source_subset] · exact (image_mono pathComponentIn_subset).trans (PartialEquiv.symm_image_image_of_subset_source _ inter_subset_right).subset diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index f22688a5976fb8..4d153c2f027492 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -689,7 +689,7 @@ theorem eLpNorm_one_smul_measure {f : α → ε} (c : ℝ≥0∞) : theorem eLpNorm_le_of_measure_le_smul {c : ℝ≥0∞} {μ μ' : Measure α} (h : μ' ≤ c • μ) {f : α → ε} {p : ℝ≥0∞} : eLpNorm f p μ' ≤ c ^ (1 / p).toReal • eLpNorm f p μ := by - grw [eLpNorm_mono_measure f h, eLpNorm_smul_measure_le] + grw [h, eLpNorm_smul_measure_le] theorem MemLp.of_measure_le_smul {μ' : Measure α} {c : ℝ≥0∞} (hc : c ≠ ∞) (hμ'_le : μ' ≤ c • μ) {f : α → ε} (hf : MemLp f p μ) : MemLp f p μ' := by @@ -708,12 +708,12 @@ theorem eLpNorm_one_add_measure (f : α → ε) (μ ν : Measure α) : rw [lintegral_add_measure _ μ ν] theorem eLpNorm_le_add_measure_right (f : α → ε) (μ ν : Measure α) {p : ℝ≥0∞} : - eLpNorm f p μ ≤ eLpNorm f p (μ + ν) := - eLpNorm_mono_measure f <| Measure.le_add_right <| le_refl _ + eLpNorm f p μ ≤ eLpNorm f p (μ + ν) := by + grw [← Measure.le_add_right le_rfl] theorem eLpNorm_le_add_measure_left (f : α → ε) (μ ν : Measure α) {p : ℝ≥0∞} : - eLpNorm f p ν ≤ eLpNorm f p (μ + ν) := - eLpNorm_mono_measure f <| Measure.le_add_left <| le_refl _ + eLpNorm f p ν ≤ eLpNorm f p (μ + ν) := by + grw [← Measure.le_add_left le_rfl] variable {ε : Type*} [ENorm ε] in lemma eLpNormEssSup_eq_iSup (hμ : ∀ a, μ {a} ≠ 0) (f : α → ε) : eLpNormEssSup f μ = ⨆ a, ‖f a‖ₑ := diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index abbd8b02fc8ddc..98fb38f6865f26 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -131,6 +131,7 @@ initialize_simps_projections StieltjesFunction (toFun → apply) variable (f : StieltjesFunction R) +@[gcongr] theorem mono : Monotone f := f.mono' @@ -296,13 +297,14 @@ theorem length_Ioc (a b : R) : f.length (Ioc a b) = ofReal (f b - f a) := by apply zero_le simp only [Ioc_sdiff_botSet] at h obtain ⟨h₁, h₂⟩ := (Ioc_subset_Ioc_iff ab).1 h - exact Real.toNNReal_le_toNNReal (sub_le_sub (f.mono h₁) (f.mono h₂)) + grw [h₁, h₂] +@[gcongr] theorem length_mono {s₁ s₂ : Set R} (h : s₁ ⊆ s₂) : f.length s₁ ≤ f.length s₂ := by rcases isEmpty_or_nonempty R with hR | hR · simp [length_eq_of_isEmpty] simp only [length_eq] - exact iInf_mono fun a => biInf_mono fun b h' => (sdiff_subset_sdiff_left h).trans h' + exact iInf_mono fun a => biInf_mono fun b => by gcongr theorem length_sdiff_botSet {s : Set R} : f.length (s \ botSet) = f.length s := by rcases isEmpty_or_nonempty R with hR | hR @@ -355,9 +357,8 @@ theorem length_subadditive_Icc_Ioo {a b : R} {c d : ℕ → R} (ss : Icc a b ⊆ rw [Finset.sum_insert (Finset.notMem_erase _ _)] replace bcd : b ∈ Ioc (c i) (d i) := Iotop_subset_Ioc bcd grw [← IH _ (Finset.erase_ssubset is) (c i), ← ENNReal.ofReal_add_le] - · gcongr - rw [sub_add_sub_cancel] - exact sub_le_sub_right (f.mono bcd.2) _ + · rw [sub_add_sub_cancel] + grw [bcd.2] · rintro x ⟨h₁, h₂⟩ apply (cv ⟨h₁, le_trans h₂ (le_of_lt bcd.1)⟩).resolve_left (fun h ↦ ?_) order [(Iotop_subset_Ioc h).1] @@ -450,10 +451,7 @@ theorem measurableSet_Ioi {c : R} : MeasurableSet[f.outer.caratheodory] (Ioi c) simp only [← length_eq] rw [← length_sdiff_botSet, inter_sdiff_right_comm, ← length_sdiff_botSet (s := t \ Ioi c), sdiff_sdiff_comm] - refine - le_trans - (add_le_add (f.length_mono <| inter_subset_inter_left _ h) - (f.length_mono <| sdiff_subset_sdiff_left h)) ?_ + grw [h] rcases le_total a c with hac | hac <;> rcases le_total b c with hbc | hbc · simp only [Ioc_inter_Ioi, f.length_Ioc, hac, hbc, le_refl, Ioc_eq_empty, max_eq_right, min_eq_left, Ioc_sdiff_Ioi, f.length_empty, zero_add, not_lt] diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index b52330580af1fb..e6ec621e482108 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -211,7 +211,8 @@ lemma variation_transpose_eq_smul [Nontrivial E] {C : ℝ≥0} simp only [flip_apply, hB] at this rw [mul_right_comm, mul_le_mul_iff_left₀ (by simpa), ← le_div_iff₀' (by positivity), div_eq_inv_mul] at this - exact ENNReal.coe_le_coe_of_le this + change ENNReal.ofNNReal _ ≤ ENNReal.ofNNReal _ + gcongr grw [this, enorm_measure_le_variation, Measure.smul_apply] lemma variation_transpose_eq [Nontrivial E] (hB : ∀ x y, ‖B x y‖₊ = ‖x‖₊ * ‖y‖₊) : From 9fbe925e59669dd8968ad6fc1bb614bc02d2bbe0 Mon Sep 17 00:00:00 2001 From: Luigi Massacci <48868075+luigi-massacci@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:34:55 +0000 Subject: [PATCH 1150/1300] feat: multiplication by a regular function in D^n_{K} as CLM (bilinear form version) (#41324) Preliminary lemma for multiplication of a classical distribution by a regular function. The proof is essentially the same as that for `TemperedDistribution`, modulo details. --- .../Distribution/ContDiffMapSupportedIn.lean | 121 ++++++++++++++++-- 1 file changed, 110 insertions(+), 11 deletions(-) diff --git a/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean b/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean index 0ccb13f47c2c04..e033d86ed22bd5 100644 --- a/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean +++ b/Mathlib/Analysis/Distribution/ContDiffMapSupportedIn.lean @@ -5,12 +5,10 @@ Authors: Anatole Dedecker, Luigi Massacci -/ module -public import Mathlib.Analysis.Calculus.ContDiff.Operations -public import Mathlib.MeasureTheory.Function.LocallyIntegrable +public import Mathlib.Analysis.Calculus.ContDiff.Bounds +public import Mathlib.Analysis.InnerProductSpace.Basic public import Mathlib.MeasureTheory.Function.Holder public import Mathlib.MeasureTheory.Integral.Bochner.Set -public import Mathlib.Topology.ContinuousMap.Bounded.Normed -public import Mathlib.Topology.Sets.Compacts /-! # Continuously differentiable functions supported in a given compact set @@ -715,6 +713,45 @@ theorem norm_toBoundedContinuousFunction (f : 𝓓^{n}_{K}(E, F)) : simp [BoundedContinuousFunction.norm_eq_iSup_norm, ContDiffMapSupportedIn.seminorm_apply, structureMapCLM_apply] +/-- Define a continuous `𝕜`-linear map from `𝓓^{n₁}_{K₁}(E, F)` to `𝓓^{n₂}_{K₂}(E, F')`. -/ +protected noncomputable def mkCLM (A : 𝓓^{n₁}_{K₁}(E, F) → E → F') + (hadd : ∀ f g x, A (f + g) x = A f x + A g x) + (hsmul : ∀ (c : 𝕜) f x, A (c • f) x = c • A f x) + (hsmooth : ∀ f, ContDiff ℝ n₂ (A f)) + (hsupp : ∀ f, EqOn (A f) 0 K₂ᶜ) + (hbound : ∀ i : ℕ, i ≤ n₂ → ∃ (s : Finset ℕ) (C : ℝ), 0 ≤ C ∧ ∀ f, ∀ x ∈ K₂, + ‖iteratedFDeriv ℝ i (A f) x‖ ≤ C * (s.sup fun j ↦ N[𝕜]_{K₁, n₁, j}) f) : + 𝓓^{n₁}_{K₁}(E, F) →L[𝕜] 𝓓^{n₂}_{K₂}(E, F') := + letI Φ : 𝓓^{n₁}_{K₁}(E, F) →ₗ[𝕜] 𝓓^{n₂}_{K₂}(E, F') := + { toFun f := ⟨A f, hsmooth f, hsupp f⟩ + map_add' f g := ext (hadd f g) + map_smul' c f := ext (hsmul c f) } + { toLinearMap := Φ + cont := show Continuous Φ by + refine continuous_of_isBounded (ContDiffMapSupportedIn.withSeminorms ..) + (ContDiffMapSupportedIn.withSeminorms ..) _ (.of_real fun i ↦ ?_) + by_cases hi : i ≤ n₂ + · obtain ⟨s, C, hC, h⟩ := hbound i hi + exact ⟨s, C, fun f ↦ ((Φ f).seminorm_le_iff 𝕜 (mul_nonneg hC (apply_nonneg _ _)) i).2 + fun _ x hx ↦ h f x hx⟩ + · exact ⟨∅, 0, fun f ↦ by + simp [ContDiffMapSupportedIn.seminorm_eq_bot_of_gt 𝕜 (not_le.1 hi)]⟩ } + +/-- Define a continous `𝕜`-linear map fom `𝓓^{n}_{K}(E, F)` to a normed space. -/ +protected noncomputable def mkCLMtoNormedSpace {G : Type*} [NormedAddCommGroup G] + [NormedSpace 𝕜 G] (A : 𝓓^{n}_{K}(E, F) → G) + (hadd : ∀ f g, A (f + g) = A f + A g) + (hsmul : ∀ (c : 𝕜) f, A (c • f) = c • A f) + (hbound : ∃ (s : Finset ℕ) (C : ℝ), 0 ≤ C ∧ ∀ f, + ‖A f‖ ≤ C * (s.sup fun i ↦ N[𝕜]_{K, n, i}) f) : + 𝓓^{n}_{K}(E, F) →L[𝕜] G := + letI Φ : 𝓓^{n}_{K}(E, F) →ₗ[𝕜] G := ⟨⟨A, hadd⟩, hsmul⟩ + { toLinearMap := Φ + cont := show Continuous Φ by + obtain ⟨s, C, hC, h⟩ := hbound + exact continuous_normedSpace_rng G (ContDiffMapSupportedIn.withSeminorms 𝕜 E F n K) + Φ ⟨s, ⟨C, hC⟩, h⟩ } + /-- The inclusion of the space `𝓓^{n}_{K}(E, F)` into the space `E →ᵇ F` of bounded continuous functions as a continuous `𝕜`-linear map. -/ noncomputable def toBoundedContinuousFunctionCLM : 𝓓^{n}_{K}(E, F) →L[𝕜] E →ᵇ F where @@ -974,13 +1011,11 @@ lemma norm_integralAgainstBilinLM_le {B : F₁ →L[𝕜] F₂ →L[𝕜] F₃} and a function `φ : E → F₂` which is integrable on `K`, this is the *continuous* `𝕜`-linear map `f ↦ ∫ x, B (f x) (φ x) ∂μ` from `𝓓^{n}_{K}(E, F₁)` to `F₃`. Otherwise, this is the zero map. -/ noncomputable def integralAgainstBilinCLM (B : F₁ →L[𝕜] F₂ →L[𝕜] F₃) (μ : Measure E) (φ : E → F₂) : - 𝓓^{n}_{K}(E, F₁) →L[𝕜] F₃ where - toLinearMap := integralAgainstBilinLM B μ φ - cont := show Continuous (integralAgainstBilinLM B μ φ) by - refine continuous_of_isBounded (ContDiffMapSupportedIn.withSeminorms ..) - (norm_withSeminorms 𝕜 _) _ - (.of_real fun _ ↦ ⟨{0}, (∫ x in K, ‖φ x‖ ∂μ) * ‖B‖, fun f ↦ ?_⟩) - simpa using! norm_integralAgainstBilinLM_le + 𝓓^{n}_{K}(E, F₁) →L[𝕜] F₃ := + ContDiffMapSupportedIn.mkCLMtoNormedSpace 𝕜 (integralAgainstBilinLM B μ φ) + (integralAgainstBilinLM B μ φ).map_add (integralAgainstBilinLM B μ φ).map_smul + ⟨{0}, (∫ x in K, ‖φ x‖ ∂μ) * ‖B‖, by positivity, + fun f ↦ by simpa using! norm_integralAgainstBilinLM_le⟩ @[simp] lemma integralAgainstBilinCLM_apply {B : F₁ →L[𝕜] F₂ →L[𝕜] F₃} {μ : Measure E} {φ : E → F₂} @@ -1001,4 +1036,68 @@ lemma integralAgainstBilinCLM_eq_setIntegral {B : F₁ →L[𝕜] F₂ →L[𝕜 end Integral +section Multiplication + +section bilin + +open ContDiffMapSupportedIn + +variable {F₁ F₂ F₃ G : Type*} [NormedAlgebra ℝ 𝕜] + [NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] [NormedSpace ℝ F₁] + [NormedAddCommGroup F₂] [NormedSpace 𝕜 F₂] [NormedSpace ℝ F₂] + [NormedAddCommGroup F₃] [NormedSpace 𝕜 F₃] [NormedSpace ℝ F₃] + +open ContinuousLinearMap Finset + +variable {𝕜} +/-- The map `f ↦ (x ↦ B (f x) (g x))` as a continuous `𝕜`-linear map on 𝓓^{n}_{K}(E, F₁), +where `B` is a continuous `𝕜`-linear map and `g` is a C^n function. + +TODO: Introduce a type of bundled C^k functions. -/ +noncomputable def bilinLeftCLM (B : F₁ →L[𝕜] F₂ →L[𝕜] F₃) {g : E → F₂} (hg : ContDiff ℝ n g) : + 𝓓^{n}_{K}(E, F₁) →L[𝕜] 𝓓^{n}_{K}(E, F₃) := + ContDiffMapSupportedIn.mkCLM 𝕜 (fun φ x ↦ B (φ x) (g x)) ?hadd ?hsmul (fun φ ↦ ?hsmooth) + (fun φ x hx ↦ ?hsupp) (fun k hk ↦ ?hbound) +where finally + case hadd | hsmul => intros; simp + case hsmooth => + exact (B.bilinearRestrictScalars ℝ).isBoundedBilinearMap.contDiff.comp (φ.contDiff.prodMk hg) + case hsupp => simp only [φ.zero_on_compl hx, Pi.zero_apply, map_zero, zero_apply] + case hbound => + have hcont : Continuous fun x ↦ (Finset.range (k + 1)).sup' Finset.nonempty_range_add_one + (fun i ↦ ‖iteratedFDeriv ℝ i g x‖) := + Continuous.finset_sup'_apply Finset.nonempty_range_add_one fun i hi ↦ + (hg.continuous_iteratedFDeriv (WithTop.coe_le_coe.2 + (le_trans (WithTop.coe_le_coe.2 (mem_range_succ_iff.mp hi)) hk))).norm + obtain ⟨C₀, hC₀⟩ := K.isCompact.exists_bound_of_continuousOn hcont.continuousOn + have hgC₀ : ∀ i ≤ k, ∀ x ∈ K, ‖iteratedFDeriv ℝ i g x‖ ≤ ‖C₀‖ := fun i hi x hx ↦ + (Finset.le_sup' _ (Finset.mem_range_succ_iff.2 hi)).trans + ((Real.le_norm_self _).trans ((hC₀ x hx).trans (Real.le_norm_self C₀))) + refine ⟨Finset.Iic k, ‖B‖ * 2 ^ k * ‖C₀‖, by positivity, fun φ x hx ↦ ?_⟩ + calc + ‖iteratedFDeriv ℝ k (fun y ↦ B (φ y) (g y)) x‖ + ≤ ‖B‖ * ∑ i ∈ Finset.range (k + 1), (k.choose i : ℝ) * ‖iteratedFDeriv ℝ i φ x‖ * + ‖iteratedFDeriv ℝ (k - i) g x‖ := by + simpa using (B.bilinearRestrictScalars ℝ).norm_iteratedFDeriv_le_of_bilinear + φ.contDiff hg x (mod_cast hk) + _ ≤ ‖B‖ * ∑ i ∈ Finset.range (k + 1), (k.choose i : ℝ) * + ((Finset.Iic k).sup fun m ↦ N[𝕜]_{K, n, m}) φ * ‖C₀‖ := by + gcongr with i hi + · exact (norm_iteratedFDeriv_apply_le_seminorm 𝕜 + ((WithTop.coe_le_coe.2 (mem_range_succ_iff.mp hi)).trans hk)).trans + (Seminorm.le_finset_sup_apply (Finset.mem_Iic.2 (mem_range_succ_iff.mp hi))) + · exact hgC₀ (k - i) (Nat.sub_le k i) x hx + _ = ‖B‖ * 2 ^ k * ‖C₀‖ * ((Finset.Iic k).sup fun m ↦ N[𝕜]_{K, n, m}) φ := by + simp_rw [← Finset.sum_mul, ← Nat.cast_sum, Nat.sum_range_choose] + push_cast + ring + +@[simp] +theorem bilinLeftCLM_apply (B : F₁ →L[𝕜] F₂ →L[𝕜] F₃) {g : E → F₂} (hg : ContDiff ℝ n g) + (φ : 𝓓^{n}_{K}(E, F₁)) : bilinLeftCLM B hg φ = fun x => B (φ x) (g x) := rfl + +end bilin + +end Multiplication + end ContDiffMapSupportedIn From a6180e1994004a7c705114bcbebaf5fff4b8384d Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:34:57 +0000 Subject: [PATCH 1151/1300] chore(Counterexamples/DirectSumIsInternal): automated extraction from #42430 (#42431) This PR was automatically created from PR #42430 by @vihdzp via a [review comment](https://github.com/leanprover-community/mathlib4/pull/42430#discussion_r3711034802) by @grunweg. Co-authored-by: vihdzp <65465670+vihdzp@users.noreply.github.com> --- Counterexamples/DirectSumIsInternal.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Counterexamples/DirectSumIsInternal.lean b/Counterexamples/DirectSumIsInternal.lean index 638eaae576dc66..2b50b5a7d2f2fe 100644 --- a/Counterexamples/DirectSumIsInternal.lean +++ b/Counterexamples/DirectSumIsInternal.lean @@ -60,8 +60,7 @@ theorem withSign.isCompl : IsCompl ℤ≥0 ℤ≤0 := by · exact Submodule.mem_sup_left (mem_withSign_one.mpr hp) · exact Submodule.mem_sup_right (mem_withSign_neg_one.mpr hn) -set_option linter.defProp false in -def withSign.independent : iSupIndep withSign := by +theorem withSign.independent : iSupIndep withSign := by apply (iSupIndep_pair UnitsInt.one_ne_neg_one _).mpr withSign.isCompl.disjoint intro i From 4d6f98930f48b11c2b668bd0f37cb0c76c1f2ef1 Mon Sep 17 00:00:00 2001 From: TJHeeringa <16029718+TJHeeringa@users.noreply.github.com> Date: Tue, 4 Aug 2026 19:56:42 +0000 Subject: [PATCH 1152/1300] feat(Topology/Algebra): add ContinuousLinearMap.fromCompletion (#40151) `Uniform.Completion.extension` maps a map $f:\alpha\to\beta$ to $f:\text{Completion }\alpha \to \beta$. There are theorems that show that this operations preserves continuous, uniformly, continuous and LipschitzWith, but not linearity. This adds that theorem. --- Mathlib/Topology/Algebra/GroupCompletion.lean | 2 +- .../Topology/Algebra/LinearMapCompletion.lean | 38 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Algebra/GroupCompletion.lean b/Mathlib/Topology/Algebra/GroupCompletion.lean index 82cc3cda791079..0ead91986c5b44 100644 --- a/Mathlib/Topology/Algebra/GroupCompletion.lean +++ b/Mathlib/Topology/Algebra/GroupCompletion.lean @@ -228,7 +228,7 @@ theorem AddMonoidHom.extension_coe [CompleteSpace β] [T0Space β] (f : α →+ (hf : Continuous f) (a : α) : f.extension hf a = f a := UniformSpace.Completion.extension_coe (uniformContinuous_addMonoidHom_of_continuous hf) a -@[continuity] +@[continuity, fun_prop] theorem AddMonoidHom.continuous_extension [CompleteSpace β] [T0Space β] (f : α →+ β) (hf : Continuous f) : Continuous (f.extension hf) := UniformSpace.Completion.continuous_extension diff --git a/Mathlib/Topology/Algebra/LinearMapCompletion.lean b/Mathlib/Topology/Algebra/LinearMapCompletion.lean index fd01363aa3c3be..87254b8eee558f 100644 --- a/Mathlib/Topology/Algebra/LinearMapCompletion.lean +++ b/Mathlib/Topology/Algebra/LinearMapCompletion.lean @@ -17,7 +17,9 @@ lifted to a continuous semilinear map between the completions of those modules. ## Main declarations: * `ContinuousLinearMap.completion`: promotes a continuous semilinear map - from `G` to `H` to a continuous semilinear map from `Completion G` to `Completion H`. + from `α` to `β` to a continuous semilinear map from `Completion α` to `Completion β`. +* `ContinuousLinearMap.fromCompletion`: promotes a continuous semilinear map + from `α` to `β` to a continuous semilinear map from `Completion α` to `β`. -/ @[expose] public section @@ -31,6 +33,8 @@ variable {α β : Type*} {R₁ R₂ : Type*} [UniformSpace α] [AddCommGroup α] [AddCommGroup β] [IsUniformAddGroup β] [Module R₂ β] [UniformContinuousConstSMul R₂ β] {σ : R₁ →+* R₂} +section completion + set_option backward.isDefEq.respectTransparency false in /-- Lift a continuous semilinear map to a continuous semilinear map between the @@ -57,4 +61,36 @@ lemma coe_completion (f : α →SL[σ] β) : theorem completion_apply_coe (f : α →SL[σ] β) (a : α) : f.completion a = f a := by simp [coe_completion, map_coe] +end completion + +section fromCompletion + +variable [T0Space β] [CompleteSpace β] + +/-- Extension of a linear function to a linear function over the completion. This is the continuous +linear version of `UniformSpace.Completion.extension`. -/ +noncomputable def fromCompletion (f : α →SL[σ] β) : + Completion α →SL[σ] β where + __ := f.toAddMonoidHom.extension f.continuous + map_smul' c a := induction_on a + (isClosed_eq (continuous_extension.comp (continuous_const_smul c)) (by dsimp; fun_prop)) <| by + simp [← Completion.coe_smul, AddMonoidHom.extension_coe f.toAddMonoidHom f.continuous] + +@[simp] +lemma toAddMonoidHom_fromCompletion (f : α →SL[σ] β) : + f.fromCompletion.toAddMonoidHom = f.toAddMonoidHom.extension f.continuous := rfl + +lemma coe_fromCompletion (f : α →SL[σ] β) : + f.fromCompletion = Completion.extension f := rfl + +@[simp] +lemma fromCompletion_apply_coe (f : α →SL[σ] β) (e : α) : + f.fromCompletion e = f e := by simp [coe_fromCompletion, extension_coe] + +lemma fromCompletion_unique (f : α →SL[σ] β) (g : Completion α →SL[σ] β) + (h : ∀ (e : α), f e = g e) : f.fromCompletion = g := by + ext; simp [coe_fromCompletion, extension_unique f.uniformContinuous g.uniformContinuous h] + +end fromCompletion + end ContinuousLinearMap From 95068925690de8ac9e81cf177dff9ce1d056e9f4 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:02:01 +0000 Subject: [PATCH 1153/1300] chore(Data/List/ModifyLast): remove `import all` (#42458) --- Mathlib/Data/List/ModifyLast.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/List/ModifyLast.lean b/Mathlib/Data/List/ModifyLast.lean index b19f1307d20eef..ca3533feac20f1 100644 --- a/Mathlib/Data/List/ModifyLast.lean +++ b/Mathlib/Data/List/ModifyLast.lean @@ -6,9 +6,7 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M module public import Batteries.Data.List.Basic -public import Batteries.Tactic.Alias public import Mathlib.Init -import all Init.Data.Array.Basic /-! ### List.modifyLast -/ @@ -22,7 +20,7 @@ private theorem modifyLast.go_concat (f : α → α) (a : α) (tl : List α) (r modifyLast.go f (tl ++ [a]) r = (r.toListAppend <| modifyLast.go f (tl ++ [a]) #[]) := by cases tl with | nil => - simp only [nil_append, modifyLast.go]; rfl + simp only [nil_append, modifyLast.go]; simp | cons hd tl => simp only [cons_append] rw [modifyLast.go, modifyLast.go] @@ -50,7 +48,9 @@ theorem modifyLast_append_of_right_ne_nil (f : α → α) (l₁ l₂ : List α) | nil => contradiction | cons hd tl => cases tl with - | nil => exact modifyLast_concat _ hd _ + | nil => + simp only [modifyLast, modifyLast.go, Array.toListAppend_eq, nil_append] + exact modifyLast_concat _ hd _ | cons hd' tl' => rw [append_cons, ← nil_append (hd :: hd' :: tl'), append_cons [], nil_append, modifyLast_append_of_right_ne_nil _ (l₁ ++ [hd]) (hd' :: tl') _, From b2418b04047e1da8b7dd99534965d44fc1de9288 Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:02:02 +0000 Subject: [PATCH 1154/1300] chore(Data/List/Sort): remove `import all` (#42459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes an `import all` by switching an `example` that relies on unfolding to a `#guard`. Technically this is testing a different thing—the IR of `mergeSort`, not the expression's unfolding rules—but seeing as this is just an example to demonstrate `mergeSort`, assuming alignment between the compiler and kernel is probably worth the `import all` reduction. --- Mathlib/Data/List/Sort.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/List/Sort.lean b/Mathlib/Data/List/Sort.lean index 1ad915e253bce7..a7c527dfe7a23a 100644 --- a/Mathlib/Data/List/Sort.lean +++ b/Mathlib/Data/List/Sort.lean @@ -10,7 +10,6 @@ public import Batteries.Data.List.Perm public import Mathlib.Data.List.OfFn public import Mathlib.Data.List.Nodup public import Mathlib.Order.Fin.Basic -import all Init.Data.List.Sort.Basic -- for exposing `mergeSort` /-! # Sorting algorithms on lists @@ -289,9 +288,9 @@ which rather than using explicit hypotheses for transitivity and totality, use Mathlib order typeclasses instead. -/ -example : - mergeSort [5, 27, 221, 95, 17, 43, 7, 2, 98, 567, 23, 12] (fun m n => m / 10 ≤ n / 10) = - [5, 7, 2, 17, 12, 27, 23, 43, 95, 98, 221, 567] := by simp [mergeSort] +set_option linter.hashCommand false in +#guard mergeSort [5, 27, 221, 95, 17, 43, 7, 2, 98, 567, 23, 12] (fun m n => m / 10 ≤ n / 10) = + [5, 7, 2, 17, 12, 27, 23, 43, 95, 98, 221, 567] section MergeSort From 2eecc3c0eca7c3cb8e06897c1effecd073e4149b Mon Sep 17 00:00:00 2001 From: Monica Omar <23701951+themathqueen@users.noreply.github.com> Date: Wed, 5 Aug 2026 02:09:39 +0000 Subject: [PATCH 1155/1300] chore(Algebra/Module/Equiv/Basic): fix lemma name (#42441) --- Mathlib/Algebra/Module/Equiv/Basic.lean | 6 ++++-- Mathlib/RingTheory/Coalgebra/Equiv.lean | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Module/Equiv/Basic.lean b/Mathlib/Algebra/Module/Equiv/Basic.lean index 93a26c2d2ec3e7..a805a427a61688 100644 --- a/Mathlib/Algebra/Module/Equiv/Basic.lean +++ b/Mathlib/Algebra/Module/Equiv/Basic.lean @@ -509,12 +509,14 @@ theorem ofLinear_symm_apply {h₁ h₂} (x : M₂) : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm x = g x := rfl -@[deprecated "Follows from simp lemmas `symm_ofLinearMap` and `ofLinear_toLinearMap`" +@[deprecated "Follows from simp lemmas `symm_ofLinearMap` and `toLinearMap_ofLinearMap`" (since := "2026-06-23")] theorem ofLinear_symm_toLinearMap {h₁ h₂} : (ofLinear f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂).symm = g := rfl @[simp] -theorem ofLinear_toLinearMap (h₁ h₂) : (ofLinearMap f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂) = f := rfl +theorem toLinearMap_ofLinearMap (h₁ h₂) : (ofLinearMap f g h₁ h₂ : M ≃ₛₗ[σ₁₂] M₂) = f := rfl + +@[deprecated (since := "2026-08-04")] alias ofLinear_toLinearMap := toLinearMap_ofLinearMap end diff --git a/Mathlib/RingTheory/Coalgebra/Equiv.lean b/Mathlib/RingTheory/Coalgebra/Equiv.lean index 660c33828b309f..c8e5ddacfb2f56 100644 --- a/Mathlib/RingTheory/Coalgebra/Equiv.lean +++ b/Mathlib/RingTheory/Coalgebra/Equiv.lean @@ -174,7 +174,7 @@ def symm (e : A ≃ₗc[R] B) : B ≃ₗc[R] A := = comul ∘ₗ (e : A ≃ₗ[R] B).symm rw [LinearEquiv.toLinearMap_symm_comp_eq] simp only [TensorProduct.congr, toCoalgHom_eq_coe, CoalgHom.toLinearMap_eq_coe, - LinearEquiv.ofLinear_toLinearMap, ← LinearMap.comp_assoc, CoalgHomClass.map_comp_comul] + LinearEquiv.toLinearMap_ofLinearMap, ← LinearMap.comp_assoc, CoalgHomClass.map_comp_comul] rw [← toLinearEquiv_toLinearMap, LinearEquiv.comp_symm_cancel_right] } /-- See Note [custom simps projection] -/ From 060b244276aa46de92c8a706b5236b3f8349657a Mon Sep 17 00:00:00 2001 From: Michail Karatarakis <40603357+mkaratarakis@users.noreply.github.com> Date: Wed, 5 Aug 2026 06:41:48 +0000 Subject: [PATCH 1156/1300] feat(RingTheory/Algebraic): add natDenominator API (#39872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `Algebra.denominator` and `Algebra.natDenominator`. For an element `x` of an `R`-algebra `S` with `R` a principal ideal ring, the denominator is a generator of the colon ideal, i.e. of the ideal of scalars `r : R` with `r • x` integral over `R`; over `ℤ`, its absolute value is the natural-number denominator. Part of the Gelfond–Schneider formalization. This PR is self-contained and is itself a prerequisite of the rest of the series. I use Claude code for merging `master` into the branch and for fixing build errors and for moving content around multiple files and for the docstrings. The original formalization was not LLM generated. Co-authored-by: mkaratarakis --- Mathlib.lean | 1 + Mathlib/RingTheory/Algebraic/Denominator.lean | 100 ++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Mathlib/RingTheory/Algebraic/Denominator.lean diff --git a/Mathlib.lean b/Mathlib.lean index 58520b10d348ad..808fbf72d011c0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6483,6 +6483,7 @@ public import Mathlib.RingTheory.AlgebraTower public import Mathlib.RingTheory.Algebraic.Basic public import Mathlib.RingTheory.Algebraic.Cardinality public import Mathlib.RingTheory.Algebraic.Defs +public import Mathlib.RingTheory.Algebraic.Denominator public import Mathlib.RingTheory.Algebraic.Integral public import Mathlib.RingTheory.Algebraic.LinearIndependent public import Mathlib.RingTheory.Algebraic.MvPolynomial diff --git a/Mathlib/RingTheory/Algebraic/Denominator.lean b/Mathlib/RingTheory/Algebraic/Denominator.lean new file mode 100644 index 00000000000000..b044cd9d04991f --- /dev/null +++ b/Mathlib/RingTheory/Algebraic/Denominator.lean @@ -0,0 +1,100 @@ +/- +Copyright (c) 2026 Michail Karatarakis. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michail Karatarakis +-/ +module + +public import Mathlib.RingTheory.Algebraic.Integral +public import Mathlib.RingTheory.Ideal.Colon + +/-! +# Denominators of elements of an algebra + +For an element `x` of an `R`-algebra `S`, with `R` a principal ideal ring, the **denominator** +`Algebra.denominator R x` is a generator of the colon ideal `(integralClosure R S).colon {x}`, +that is, of the ideal of scalars `r : R` clearing the denominators of `x`, in the sense that +`r • x` is integral over `R`. When `R = ℤ`, its absolute value is the natural-number denominator +`Algebra.natDenominator x`. + +The definition needs no hypothesis on `x`, but it is only meaningful for `x` algebraic over `R`: +`IsAlgebraic.denominator_ne_zero` shows the denominator is then nonzero, whereas no nonzero +multiple of a transcendental element is integral, so that the colon ideal is trivial and the +denominator is `0`. See the `example` below, taking `x` to be the variable in `ℤ[X]`. + +## Main definitions + +* `Algebra.denominator`: the denominator of an element, over a principal ideal ring +* `Algebra.natDenominator`: the natural-number denominator of an element, over `ℤ` + +## Main results + +* `Algebra.denominator_dvd_iff`: `denominator R x` divides exactly the `r : R` with `r • x` + integral over `R` +* `IsAlgebraic.denominator_ne_zero`: the denominator of an algebraic element is nonzero +-/ + +public section + +variable (R : Type*) {S : Type*} [CommRing R] +variable [IsPrincipalIdealRing R] [CommRing S] [Algebra R S] +namespace Algebra + +/-- The denominator of an element `x` of an `R`-algebra: a generator of the ideal of scalars +`r : R` such that `r • x` is integral over `R`. It is nonzero as soon as `x` is algebraic over +`R`; see `IsAlgebraic.denominator_ne_zero`. -/ +noncomputable def denominator (x : S) : R := + Submodule.IsPrincipal.generator ((integralClosure R S).toSubmodule.colon {x}) + +lemma denominator_def (x : S) : + denominator R x = + Submodule.IsPrincipal.generator ((integralClosure R S).toSubmodule.colon {x}) := by + rfl + +variable {R} + +theorem denominator_dvd_iff {r : R} {x : S} : + denominator R x ∣ r ↔ IsIntegral R (r • x) := by + rw [denominator_def, ← Submodule.IsPrincipal.mem_iff_generator_dvd, + Submodule.mem_colon_singleton, Subalgebra.mem_toSubmodule, mem_integralClosure_iff] + +theorem isIntegral_denominator_smul (x : S) : IsIntegral R (denominator R x • x) := + denominator_dvd_iff.mp dvd_rfl + +/-- The natural-number denominator of an element `x` of a ring: it is the absolute value of the +denominator of `x` over `ℤ`. -/ +noncomputable def natDenominator (x : S) : ℕ := + (denominator ℤ x).natAbs + +theorem natDenominator_def (x : S) : natDenominator x = (denominator ℤ x).natAbs := by + rfl + +theorem natDenominator_dvd_iff {n : ℕ} {x : S} : + natDenominator x ∣ n ↔ IsIntegral ℤ (n • x) := by + rw [natDenominator_def, ← Int.ofNat_dvd_right, denominator_dvd_iff, natCast_zsmul] + +theorem isIntegral_natDenominator_smul (x : S) : IsIntegral ℤ (natDenominator x • x) := + natDenominator_dvd_iff.mp dvd_rfl + +end Algebra + +namespace IsAlgebraic + +theorem denominator_ne_zero {x : S} (hx : IsAlgebraic R x) : Algebra.denominator R x ≠ 0 := by + obtain ⟨r, hr0, hr⟩ := hx.exists_integral_multiple + exact ne_zero_of_dvd_ne_zero hr0 (Algebra.denominator_dvd_iff.mpr hr) + +theorem natDenominator_ne_zero {x : S} (hx : IsAlgebraic ℤ x) : Algebra.natDenominator x ≠ 0 := by + rw [Algebra.natDenominator_def, Int.natAbs_ne_zero] + exact hx.denominator_ne_zero + +end IsAlgebraic + +/- The algebraicity hypothesis in `IsAlgebraic.denominator_ne_zero` cannot be dropped: the +variable `X` of `ℤ[X]` is transcendental over `ℤ`, so no nonzero multiple of it is integral and +its denominator vanishes. -/ +example : Algebra.denominator ℤ (Polynomial.X : Polynomial ℤ) = 0 := by + by_contra h + exact Polynomial.transcendental_X ℤ + ((Algebra.isIntegral_denominator_smul _).isAlgebraic.of_smul + (mem_nonZeroDivisors_of_ne_zero h)) From 8a92a130608033b9cee9a988d3af5baaafded015 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 5 Aug 2026 06:56:26 +0000 Subject: [PATCH 1157/1300] feat: characterize mermorphic functions with finite set of poles in terms of logarithmic counting function (#40957) Deliver on an open TODO. showing that a meromorphic function has a finite set of poles if and only if its logarithmic counting function is big-O of log. This material will later be used to characterize rational and algebraic functions among all meromorphic functions in terms of their characteristic (a.k.a. Nevanlinna height) Claude Code was used in the preparation of this PR. --- Mathlib/Analysis/Asymptotics/Defs.lean | 13 +-- .../Calculus/ContDiff/FaaDiBruno.lean | 2 +- .../LogCounting/Asymptotic.lean | 96 ++++++++++++++++++- .../Distribution/TemperateGrowth.lean | 2 +- Mathlib/Analysis/Polynomial/Basic.lean | 4 +- Mathlib/NumberTheory/ModularForms/Bounds.lean | 2 +- .../NumberTheory/ModularForms/NormTrace.lean | 2 +- Mathlib/Topology/LocallyFinsupp.lean | 16 ++++ 8 files changed, 120 insertions(+), 17 deletions(-) diff --git a/Mathlib/Analysis/Asymptotics/Defs.lean b/Mathlib/Analysis/Asymptotics/Defs.lean index cd88403ddedceb..11d00735f6e010 100644 --- a/Mathlib/Analysis/Asymptotics/Defs.lean +++ b/Mathlib/Analysis/Asymptotics/Defs.lean @@ -1407,21 +1407,22 @@ section Sum variable {ι : Type*} {A : ι → α → E'} {C : ι → ℝ} {s : Finset ι} -theorem IsBigOWith.sum (h : ∀ i ∈ s, IsBigOWith (C i) l (A i) g) : - IsBigOWith (∑ i ∈ s, C i) l (fun x => ∑ i ∈ s, A i x) g := by +@[to_fun] theorem IsBigOWith.sum (h : ∀ i ∈ s, IsBigOWith (C i) l (A i) g) : + IsBigOWith (∑ i ∈ s, C i) l (∑ i ∈ s, A i) g := by induction s using Finset.cons_induction with - | empty => simp only [isBigOWith_zero', Finset.sum_empty] + | empty => + rw [Finset.sum_empty] + apply isBigOWith_zero' | cons i s is IH => simp only [Finset.sum_cons, Finset.forall_mem_cons] at h ⊢ exact h.1.add (IH h.2) -theorem IsBigO.sum (h : ∀ i ∈ s, A i =O[l] g) : (fun x => ∑ i ∈ s, A i x) =O[l] g := by +@[to_fun] theorem IsBigO.sum (h : ∀ i ∈ s, A i =O[l] g) : (∑ i ∈ s, A i) =O[l] g := by simp only [IsBigO_def] at * choose! C hC using h exact ⟨_, IsBigOWith.sum hC⟩ -theorem IsLittleO.sum (h : ∀ i ∈ s, A i =o[l] g') : (fun x => ∑ i ∈ s, A i x) =o[l] g' := by - simp only [← Finset.sum_apply] +@[to_fun] theorem IsLittleO.sum (h : ∀ i ∈ s, A i =o[l] g') : (∑ i ∈ s, A i) =o[l] g' := by exact Finset.sum_induction A (· =o[l] g') (fun _ _ ↦ .add) (isLittleO_zero ..) h variable {B : ι → α → ℝ} diff --git a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean index 570b0ff650c60e..e01b40b3fa16fc 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean @@ -930,7 +930,7 @@ theorem taylorComp_sub_taylorComp_isBigO (hqf : ∀ k ≤ n, (fun a ↦ q₁ a k - q₂ a k) =O[l] f) : (fun a ↦ (p₁ a).taylorComp (q₁ a) n - (p₂ a).taylorComp (q₂ a) n) =O[l] f := by simp only [FormalMultilinearSeries.taylorComp, ← Finset.sum_sub_distrib] - refine .sum fun c _ ↦ ?_ + refine .fun_sum fun c _ ↦ ?_ refine .trans (.of_norm_le fun _ ↦ c.norm_compAlongOrderedFinpartition_sub_compAlongOrderedFinpartition_le ..) ?_ refine .add ?_ ?_ diff --git a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean index 6c1d5ecc89d496..d3056e8b6b9679 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean @@ -15,16 +15,14 @@ poles of `f` is asymptotically bounded if and only if `f` has only removable sin Page 170f of [Lang, *Introduction to Complex Hyperbolic Spaces*][MR886677] for a detailed discussion. +Analogously, characterize meromorphic functions with finite set of poles, as functions whose +logarithmic counting function is big-O of `log`. + ## Implementation Notes We establish the result first for the logarithmic counting function for functions with locally finite support on `𝕜` and then specialize to the setting where the function with locally finite support is the pole or zero-divisor of a meromorphic function. - -## TODO - -Establish the analogous characterization of meromorphic functions with finite set of poles, as -functions whose logarithmic counting function is big-O of `log`. -/ public section @@ -89,6 +87,85 @@ lemma zero_iff_logCounting_bounded [ProperSpace E] abs_of_nonneg (logCounting_nonneg h (by grind))] apply logCounting_strictMono he <;> grind +/-- +The logarithmic counting function of a singleton is big-O of `log`. This is the qualitative +consequence of `logCounting_single_eq_log_sub_const`. +-/ +lemma logCounting_single_isBigO_log [DecidableEq E] [ProperSpace E] {e : E} {n : ℤ} : + logCounting (single e n) =O[atTop] Real.log := by + have h₁ : logCounting (single e n) =ᶠ[atTop] (n * log · - n * log ‖e‖) := by + filter_upwards [eventually_ge_atTop ‖e‖] with r hr + rw [logCounting_single_eq_log_sub_const hr] + ring + have hb : (n * log ·) =O[atTop] Real.log := isBigO_const_mul_self (n : ℝ) log atTop + exact (hb.sub isLittleO_const_log_atTop.isBigO).congr' h₁.symm EventuallyEq.rfl + +/-- +A function with finite support has a logarithmic counting function that is big-O of `log`. +-/ +lemma logCounting_isBigO_log_of_finite_support [ProperSpace E] {D : locallyFinsupp E ℤ} + (h : D.support.Finite) : + logCounting D =O[atTop] Real.log := by + classical + rw [← sum_apply_smul_single_eq_self_on_univ h, map_sum] + exact Asymptotics.IsBigO.sum fun _ _ ↦ logCounting_single_isBigO_log + +/-- +A non-negative function whose logarithmic counting function is big-O of `log` has finite support. +-/ +lemma finite_support_of_logCounting_isBigO_log [ProperSpace E] + {D : locallyFinsupp E ℤ} (h : 0 ≤ D) (hO : logCounting D =O[atTop] Real.log) : + D.support.Finite := by + classical + -- Let (N : ℕ) be a number such that ‖logCounting D x‖ ≤ N * ‖log x‖ + obtain ⟨C, hC⟩ := isBigO_iff.1 hO + obtain ⟨N, hCN⟩ := exists_nat_gt (max C 0) + have hCN' : C < N := lt_of_le_of_lt (le_max_left C 0) hCN + -- Argue by contradiction, let t be a cardinality=N finite subset in the (infinite) support of D + -- and let D' be the divisor for the indicator function of t + by_contra! hInf + obtain ⟨t, htsub, htcard⟩ := hInf.exists_subset_card_eq N + set D' := ∑ z ∈ t, single z (1 : ℤ) with hD' + -- The auxiliary divisor `D'` is bounded above by `D`. + have hle : D' ≤ D := by + rw [le_def, Pi.le_def] + intro w + simp only [hD', coe_sum, Finset.sum_apply, single_apply, Finset.sum_ite_eq] + by_cases hw : w ∈ t + · simp only [hw, if_true] + have h₁ : D w ≠ 0 := mem_support.mp (htsub (Finset.mem_coe.2 hw)) + have h₂ : (0 : ℤ) ≤ D w := by simpa using (le_def.1 h) w + omega + · simpa [hw, if_false] using (le_def.1 h) w + -- A uniform bound on the norms of points in `t`. + obtain ⟨R₀, hR₀⟩ : ∃ R₀ : ℝ, ∀ z ∈ t, ‖z‖ ≤ R₀ := t.finite_toSet.isBounded.exists_norm_le + set K := ∑ z ∈ t, log ‖z‖ with hK + -- Eventually, `logCounting D' = N * log - K`. + have hEq : ∀ᶠ r in atTop, logCounting D' r = (N : ℝ) * log r - K := by + filter_upwards [eventually_ge_atTop R₀] with r hr using calc + logCounting D' r = ∑ c ∈ t, logCounting (single c 1) r := by simp [hD'] + _ = ∑ z ∈ t, (log r - log ‖z‖) := by + congr! 1 with z hz; + simpa using logCounting_single_eq_log_sub_const (e := z) (n := 1) ((hR₀ z hz).trans hr) + _ = (N : ℝ) * log r - K := by simp [Finset.sum_sub_distrib, hK, htcard] + -- Combine the bounds into a contradiction with `log → ∞`. + have hFinal : ∀ᶠ r in atTop, ((N : ℝ) - C) * log r ≤ K := by + filter_upwards [hEq, eventually_ge_atTop (1 : ℝ), hC] with r hr₁ hr₂ hr₃ + grind [logCounting_le hle hr₂, norm_eq_abs, abs_of_nonneg, log_nonneg, logCounting_nonneg] + have hTendsto : Tendsto (fun r ↦ ((N : ℝ) - C) * log r) atTop atTop := + tendsto_log_atTop.const_mul_atTop (sub_pos.mpr hCN') + obtain ⟨r, hr₁, hr₂⟩ := (hFinal.and (hTendsto.eventually_gt_atTop K)).exists + linarith + +/-- +A non-negative function with locally finite support has finite support if and only if its +logarithmic counting function is big-O of `log`. +-/ +theorem finite_support_iff_logCounting_isBigO_log [ProperSpace E] + {D : locallyFinsupp E ℤ} (h : 0 ≤ D) : + D.support.Finite ↔ logCounting D =O[atTop] Real.log := + ⟨logCounting_isBigO_log_of_finite_support, finite_support_of_logCounting_isBigO_log h⟩ + end Function.locallyFinsuppWithin namespace ValueDistribution @@ -113,4 +190,13 @@ theorem logCounting_isBigO_one_iff_analyticOnNhd {f : 𝕜 → E} (h : Meromorph ← h.meromorphicOn.divisor_of_toMeromorphicNFOn, (meromorphicNFOn_toMeromorphicNFOn _ _).divisor_nonneg_iff_analyticOnNhd] +/-- +A meromorphic function has a finite set of poles if and only if the logarithmic counting function +for its pole-divisor is big-O of `log`. +-/ +theorem logCounting_isBigO_log_iff_finite_support {f : 𝕜 → E} : + logCounting f ⊤ =O[atTop] Real.log ↔ (MeromorphicOn.divisor f univ)⁻.support.Finite := by + rw [logCounting_top] + exact (locallyFinsuppWithin.finite_support_iff_logCounting_isBigO_log (negPart_nonneg _)).symm + end ValueDistribution diff --git a/Mathlib/Analysis/Distribution/TemperateGrowth.lean b/Mathlib/Analysis/Distribution/TemperateGrowth.lean index da91903523ff34..06f67664fb41bd 100644 --- a/Mathlib/Analysis/Distribution/TemperateGrowth.lean +++ b/Mathlib/Analysis/Distribution/TemperateGrowth.lean @@ -248,7 +248,7 @@ theorem _root_.ContinuousLinearMap.bilinear_hasTemperateGrowth [NormedSpace 𝕜 ‖B‖ * ∑ i ∈ Finset.range (n + 1), (n.choose i) * ‖iteratedFDeriv ℝ i f x‖ * ‖iteratedFDeriv ℝ (n - i) g x‖ := (B.bilinearRestrictScalars ℝ).norm_iteratedFDeriv_le_of_bilinear hf.1 hg.1 x (mod_cast le_top) - refine (IsBigO.of_norm_le estimate).trans (.const_mul_left (.sum fun i hi ↦ ?_) _) + refine (IsBigO.of_norm_le estimate).trans (.const_mul_left (.fun_sum fun i hi ↦ ?_) _) simp_rw [mul_assoc, pow_add] refine .const_mul_left (.mul (h1 i ?_).norm_left (h2 (n - i) ?_).norm_left) _ <;> grind diff --git a/Mathlib/Analysis/Polynomial/Basic.lean b/Mathlib/Analysis/Polynomial/Basic.lean index 0fc260912dd989..ea68cb00773b1b 100644 --- a/Mathlib/Analysis/Polynomial/Basic.lean +++ b/Mathlib/Analysis/Polynomial/Basic.lean @@ -52,7 +52,7 @@ theorem isEquivalent_atTop_lead : · simp only [Polynomial.eval_eq_sum_range, sum_range_succ] exact IsLittleO.add_isEquivalent - (IsLittleO.sum fun i hi => + (IsLittleO.fun_sum fun i hi => IsLittleO.const_mul_left ((IsLittleO.const_mul_right fun hz => h <| leadingCoeff_eq_zero.mp hz) <| isLittleO_pow_pow_atTop_of_lt (mem_range.mp hi)) @@ -345,7 +345,7 @@ lemma isEquivalent_cobounded_leading_monomial : by_cases h : P = 0 · simp [h, IsEquivalent.refl] · simp only [eval_eq_sum_range, sum_range_succ] - exact (IsLittleO.sum fun i hi ↦ + exact (IsLittleO.fun_sum fun i hi ↦ ((isLittleO_pow_pow_cobounded_of_lt (mem_range.mp hi)).const_mul_right (leadingCoeff_ne_zero.mpr h)).const_mul_left _).add_isEquivalent .refl diff --git a/Mathlib/NumberTheory/ModularForms/Bounds.lean b/Mathlib/NumberTheory/ModularForms/Bounds.lean index 98e86ddf4c42ff..0f692041c22d11 100644 --- a/Mathlib/NumberTheory/ModularForms/Bounds.lean +++ b/Mathlib/NumberTheory/ModularForms/Bounds.lean @@ -130,7 +130,7 @@ lemma exists_bound_of_subgroup_invariant_of_isBigO have : Fintype (SL(2, ℤ) ⧸ Γ) := Subgroup.fintypeQuotientOfFiniteIndex -- Now the conclusion is very simple. obtain ⟨C, hC⟩ := exists_bound_of_invariant_of_isBigO (by fun_prop) ht - (.sum fun i _ ↦ (hf'_infty i).norm_left) + (.fun_sum fun i _ ↦ (hf'_infty i).norm_left) (fun g τ ↦ (Fintype.sum_equiv (MulAction.toPerm g) _ _ (by simp [-sl_moeb, hf'_inv])).symm) refine ⟨C, fun τ ↦ le_trans ?_ (hC τ)⟩ simpa [Real.norm_of_nonneg <| show 0 ≤ ∑ γ, ‖f' τ γ‖ by positivity, -sl_moeb, f'] using diff --git a/Mathlib/NumberTheory/ModularForms/NormTrace.lean b/Mathlib/NumberTheory/ModularForms/NormTrace.lean index c23e12f649be8b..004dfc2499da3c 100644 --- a/Mathlib/NumberTheory/ModularForms/NormTrace.lean +++ b/Mathlib/NumberTheory/ModularForms/NormTrace.lean @@ -86,7 +86,7 @@ protected def ModularForm.trace [ModularFormClass F 𝒢 k] : ModularForm ℋ k rintro rfl rw [SlashInvariantForm.trace, IsBoundedAtImInfty, Filter.BoundedAtFilter, SlashAction.sum_slash, Finset.sum_fn] - refine .sum (Quotient.forall.mpr fun ⟨r, hr⟩ _ ↦ (translate f _).bdd_at_cusps' ?_ γ rfl) + refine .fun_sum (Quotient.forall.mpr fun ⟨r, hr⟩ _ ↦ (translate f _).bdd_at_cusps' ?_ γ rfl) simpa using h.of_isFiniteRelIndex_conj hr /-- The trace of a cusp form, as a cusp form. -/ diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 658bf3dce78d73..87ec3958a456cc 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -656,6 +656,22 @@ Present a function with with finite support as a finsum of singleton indicator f · aesop · aesop +/-- +Represent a function (of locally finite support) that in fact has finite support as a `finsum` of +singleton indicator functions. +-/ +@[simp] lemma sum_apply_smul_single_eq_self_on_univ [DecidableEq X] {D : locallyFinsupp X ℤ} + (h : D.support.Finite) : + ∑ z ∈ h.toFinset, single z (D z) = D := by + ext w + simp only [coe_sum, Finset.sum_apply, single_apply, Finset.sum_ite_eq] + set s := h.toFinset with hs + by_cases hw : w ∈ s + · simp [hw] + · simp only [hw, if_false] + have : w ∉ support D := by simpa only [hs, Set.Finite.mem_toFinset] using hw + exact (notMem_support.mp this).symm + /-- Restriction as a lattice morphism -/ noncomputable def restrictLatticeHom [AddCommGroup Y] [Lattice Y] {V : Set X} (h : V ⊆ U) : LatticeHom (locallyFinsuppWithin U Y) (locallyFinsuppWithin V Y) where From 503b1a2818938506db0e99d814816c83e9c054a9 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 5 Aug 2026 07:19:05 +0000 Subject: [PATCH 1158/1300] feat: companion lemmas to `MeromorphicOn.exists_ecanonicalDecomp`, API for the extended canonical decomposition (#41496) To prepare for the proof of the classic Poisson-Jensen formula in the next PR, establish several companion lemmas to `MeromorphicOn.exists_ecanonicalDecomp` that provide an API for using the extended canonical decomposition introduced in #40191. This material is used in [Project VD](https://github.com/kebekus/ProjectVD), formalizing Value Distribution Theory for meromorphic functions on the complex plane. --- .../Complex/CanonicalDecomposition.lean | 158 +++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Complex/CanonicalDecomposition.lean b/Mathlib/Analysis/Complex/CanonicalDecomposition.lean index 720009514bed75..f76d9401391553 100644 --- a/Mathlib/Analysis/Complex/CanonicalDecomposition.lean +++ b/Mathlib/Analysis/Complex/CanonicalDecomposition.lean @@ -72,7 +72,7 @@ variable (R w) in /-- Canonical factors are meromorphic. -/ -theorem meromorphic_canonicalFactor : Meromorphic (canonicalFactor R w) := by +@[fun_prop] theorem meromorphic_canonicalFactor : Meromorphic (canonicalFactor R w) := by intro x unfold canonicalFactor fun_prop @@ -512,4 +512,160 @@ theorem _root_.MeromorphicOn.exists_ecanonicalDecomp (h₁f : MeromorphicOn f (c simp_all [← smul_assoc] } +private lemma mulSupport_pow_subset_support {α β : Type*} [DivInvMonoid α] (f : β → α) + (g : β → ℤ) : (fun x ↦ f x ^ g x).mulSupport ⊆ g.support := by + simp only [mulSupport_subset_iff, ne_eq, mem_support] + intro + contrapose! + simp +contextual + +/-- +Companion lemma to `MeromorphicOn.exists_ecanonicalDecomp`: In the setting of the extended canonical +decomposition, write the function `h` entirely in terms of `f`. +-/ +lemma ECanonicalDecomp.eq_smul_meromorphicTrailingCoeffAt + {f h : ℂ → E} (D : ECanonicalDecomp f h R) (hw : w ∈ closedBall 0 R) (hR : 0 < R) : + h w + = ((∏ᶠ i, meromorphicTrailingCoeffAt (canonicalFactor R i) w ^ (divisor f (ball 0 R) i)) + * (∏ᶠ i, meromorphicTrailingCoeffAt (· - i) w ^ (-divisor f (sphere 0 R)) i)) + • meromorphicTrailingCoeffAt f w := by + -- Finiteness properties and side results used throughout the proof + let B₀R := ball (0 : ℂ) R + let S₀R := sphere (0 : ℂ) R + lift (divisor f S₀R).support to Finset ℂ using divisor_sphere_support_finite with t₁ ht₁ + lift (divisor f B₀R).support to Finset ℂ using D.meromorphicOn.divisor_ball_support_finite + with t₂ ht₂ + have := (D.analyticOnNhd w hw).meromorphicAt + rw [Eq.comm] + -- Proof body: Substitute `f` using `h₁f` and compute + calc ((∏ᶠ (i : ℂ), meromorphicTrailingCoeffAt (canonicalFactor R i) w ^ (divisor f B₀R) i) + * ∏ᶠ (i : ℂ), meromorphicTrailingCoeffAt (· - i) w ^ (-divisor f S₀R) i) + • meromorphicTrailingCoeffAt f w + _ = ((∏ᶠ (i : ℂ), meromorphicTrailingCoeffAt (canonicalFactor R i) w ^ (divisor f B₀R) i) + * ∏ᶠ (i : ℂ), meromorphicTrailingCoeffAt (· - i) w ^ (-divisor f S₀R) i) + • meromorphicTrailingCoeffAt (((∏ᶠ (u : ℂ), canonicalFactor R u ^ (-(divisor f B₀R) u)) + * ∏ᶠ (v : ℂ), (· - v) ^ (divisor f S₀R) v) • h) w := by + rw [meromorphicTrailingCoeffAt_congr_nhdsNE + ((D.meromorphicOn w hw).eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin_preperfect + (by fun_prop) hw ?η₁ D.eventuallyEq)] + case η₁ => + rw [← closure_ball _ hR.ne'] + exact isOpen_ball.perfect_closure.2 + _ = ((∏ i ∈ t₂, meromorphicTrailingCoeffAt (canonicalFactor R i) w ^ (divisor f B₀R) i) + * ∏ i ∈ t₁, meromorphicTrailingCoeffAt (· - i) w ^ (-divisor f S₀R) i) + • meromorphicTrailingCoeffAt (((∏ i ∈ t₂, canonicalFactor R i ^ (-(divisor f B₀R) i)) + * ∏ i ∈ t₁, (· - i) ^ (divisor f S₀R) i) • h) w := by + rw [finprod_eq_prod_of_mulSupport_subset (s := t₂) _ _, + finprod_eq_prod_of_mulSupport_subset (s := t₁) _ _, + finprod_eq_prod_of_mulSupport_subset (s := t₂) _ _, + finprod_eq_prod_of_mulSupport_subset (s := t₁) _ _] + <;> simpa [ht₁, ht₂] using mulSupport_pow_subset_support .. + _ = ((∏ i ∈ t₂, meromorphicTrailingCoeffAt (canonicalFactor R i) w ^ (divisor f B₀R) i) + * ∏ i ∈ t₁, meromorphicTrailingCoeffAt (· - i) w ^ (-divisor f S₀R) i) + • ((∏ n ∈ t₂, meromorphicTrailingCoeffAt (canonicalFactor R n ^ (-(divisor f B₀R) n)) w) + * ∏ n ∈ t₁, meromorphicTrailingCoeffAt ((· - n) ^ (divisor f S₀R) n) w) + • h w := by + rw [MeromorphicAt.meromorphicTrailingCoeffAt_smul (by fun_prop) + (D.analyticOnNhd w hw).meromorphicAt, + MeromorphicAt.meromorphicTrailingCoeffAt_mul (by fun_prop) (by fun_prop), + meromorphicTrailingCoeffAt_prod (by fun_prop), + meromorphicTrailingCoeffAt_prod (by fun_prop), + (D.analyticOnNhd w hw).meromorphicTrailingCoeffAt_of_ne_zero (D.ne_zero w hw)] + _ = h w := by + rw [smul_smul, mul_mul_mul_comm, ← Finset.prod_mul_distrib, ← Finset.prod_mul_distrib, + Finset.prod_eq_one ?η₁, Finset.prod_eq_one ?η₂, mul_one, one_smul] + case η₁ => + intro x hx + rw [MeromorphicAt.meromorphicTrailingCoeffAt_zpow (by fun_prop), ← zpow_add₀, + add_neg_cancel, zpow_zero] + apply MeromorphicAt.meromorphicTrailingCoeffAt_ne_zero (by fun_prop) + (meromorphicOrderAt_canonicalFactor_ne_top x hR) + case η₂ => + intro x hx + rw [MeromorphicAt.meromorphicTrailingCoeffAt_zpow (by fun_prop), ← zpow_add₀, + locallyFinsuppWithin.coe_neg, Pi.neg_apply, neg_add_cancel, zpow_zero] + rw [meromorphicTrailingCoeffAt_id_sub_const] + grind + +/-- +Companion lemma to `MeromorphicOn.exists_ecanonicalDecomp`: In the setting of the extended canonical +decomposition, write the function `h` entirely in terms of `f`, under the assumption that `f` has +order zero. +-/ +lemma ECanonicalDecomp.eq_smul_meromorphicTrailingCoeffAt_of_meromorphicOrderAt + {f h : ℂ → E} (D : ECanonicalDecomp f h R) (h₁w : w ∈ closedBall 0 R) + (h₂w : meromorphicOrderAt f w = 0) (hR : 0 < R) : + h w = ((∏ᶠ i, (canonicalFactor R i w) ^ (divisor f (ball 0 R) i)) + * (∏ᶠ i, (w - i) ^ (-divisor f (sphere 0 R)) i)) + • meromorphicTrailingCoeffAt f w := by + rw [D.eq_smul_meromorphicTrailingCoeffAt h₁w hR] + congr! 4 with x x + · by_cases h₃x : (divisor f (ball 0 R)) x = 0 + · simp [h₃x] + have h₁x : x ∈ ball 0 R := (divisor f (ball 0 R)).supportWithinDomain h₃x + have h₂x : w ≠ x := by + rintro rfl + exact h₃x (by simp [(D.meromorphicOn.mono_set ball_subset_closedBall).divisor_apply h₁x, h₂w]) + rw [AnalyticAt.meromorphicTrailingCoeffAt_of_ne_zero + (Complex.analyticOnNhd_canonicalFactor R x w h₂x) + (Complex.canonicalFactor_ne_zero h₁x h₁w h₂x)] + · by_cases h : x = w + · simp_all [meromorphicTrailingCoeffAt_id_sub_const, divisor_def] + grind [meromorphicTrailingCoeffAt_id_sub_const] + +/-- +Companion lemma to `MeromorphicOn.exists_ecanonicalDecomp`: In the setting of the extended canonical +decomposition, write the function `log ‖h‖` entirely in terms of `f`, under the assumption that `f` +has order zero. +-/ +lemma ECanonicalDecomp.log_norm_eq + {f h : ℂ → E} (D : ECanonicalDecomp f h R) (h₁w : w ∈ closedBall 0 R) + (h₂w : meromorphicOrderAt f w = 0) + (hR : 0 < R) : + Real.log ‖h w‖ = ((∑ᶠ i, (divisor f (ball 0 R) i) * Real.log ‖canonicalFactor R i w‖) + - (∑ᶠ i, (divisor f (sphere 0 R) i) * Real.log ‖w - i‖)) + + Real.log ‖meromorphicTrailingCoeffAt f w‖ := by + -- Finiteness properties and side results used throughout the proof + let B₀R := ball (0 : ℂ) R + let S₀R := sphere (0 : ℂ) R + lift (divisor f S₀R).support to Finset ℂ using divisor_sphere_support_finite with t₁ ht₁ + lift (divisor f B₀R).support to Finset ℂ using D.meromorphicOn.divisor_ball_support_finite + with t₂ ht₂ + calc Real.log ‖h w‖ + _ = log ‖((∏ᶠ (i : ℂ), canonicalFactor R i w ^ (divisor f B₀R) i) + * ∏ᶠ (i : ℂ), (w - i) ^ (-divisor f S₀R) i) • meromorphicTrailingCoeffAt f w‖ := by + rw [D.eq_smul_meromorphicTrailingCoeffAt_of_meromorphicOrderAt + h₁w h₂w hR, finprod_eq_prod_of_mulSupport_subset (s := t₂) _ (by aesop)] + _ = log ‖((∏ i ∈ t₂, canonicalFactor R i w ^ (divisor f B₀R) i) + * ∏ i ∈ t₁, (w - i) ^ (-divisor f S₀R) i) • meromorphicTrailingCoeffAt f w‖ := by + rw [finprod_eq_prod_of_mulSupport_subset (s := t₂) _ _, + finprod_eq_prod_of_mulSupport_subset (s := t₁) _ _] + <;> simpa [ht₁, ht₂] using mulSupport_pow_subset_support .. + _ = ∑ i ∈ t₂, log (‖canonicalFactor R i w‖ ^ (divisor f B₀R) i) + + ∑ i ∈ t₁, log (‖w - i‖ ^ (-divisor f S₀R) i) + log ‖meromorphicTrailingCoeffAt f w‖ := by + have η₀ (x) (hx : x ∈ t₁) : ‖w - x‖ ^ (-divisor f S₀R) x ≠ 0 := by + refine zpow_ne_zero _ ?_ + rw [norm_ne_zero_iff, sub_ne_zero] + rintro rfl + simp_all [divisor_def, ← Finset.mem_coe] + have η₁ (x) (hx : x ∈ t₂) : ‖canonicalFactor R x w‖ ^ (divisor f B₀R) x ≠ 0 := by + refine zpow_ne_zero _ ?_ + rw [norm_ne_zero_iff] + have h₁x : x ∈ ball 0 R := (divisor f B₀R).supportWithinDomain (ht₂ ▸ hx) + refine canonicalFactor_ne_zero h₁x h₁w fun _ ↦ ?_ + simp_all [divisor_def, ← Finset.mem_coe] + simp_rw [norm_smul, norm_mul, norm_prod, norm_zpow] + rw [Real.log_mul (mul_ne_zero_iff.2 ⟨Finset.prod_ne_zero_iff.2 η₁, + Finset.prod_ne_zero_iff.2 η₀⟩) ?_, Real.log_mul (Finset.prod_ne_zero_iff.2 η₁) + (Finset.prod_ne_zero_iff.2 η₀), Real.log_prod η₁, Real.log_prod η₀] + simpa using (D.meromorphicOn w h₁w).meromorphicTrailingCoeffAt_ne_zero (by simp [h₂w]) + _ = ((∑ᶠ i, (divisor f B₀R i) * Real.log ‖canonicalFactor R i w‖) + - (∑ᶠ i, (divisor f S₀R i) * Real.log ‖w - i‖)) + + Real.log ‖meromorphicTrailingCoeffAt f w‖ := by + rw [finsum_eq_sum_of_support_subset (s := t₂) _ ?η₀, + finsum_eq_sum_of_support_subset (s := t₁) _ ?η₁] + case η₀ | η₁ => intro _ _; simp_all [S₀R, B₀R] + rw [sub_eq_add_neg, ← Finset.sum_neg_distrib] + congr! 3 with i hi i hi <;> simp + end Complex From 20a3b032e0b14df9937cc80cda9d00b2093fb4c8 Mon Sep 17 00:00:00 2001 From: Hang Lu Su Date: Wed, 5 Aug 2026 11:07:39 +0000 Subject: [PATCH 1159/1300] feat(GroupTheory/Generators): define a group generators as a structure (#42437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generators of a group are given by a generating family indexed by `α` and an assignment `val : α → G` such that `Subgroup.closure (Set.range val) = ⊤`. Implementation details: * The index type `α` is a parameter, not a field. An index stored inside a term has transparency issues with `rw`, `simp`, and instance search. `Algebra.Generators` unbundled its `vars` field for these reasons (#25085). [See report](https://gist.github.com/homeowmorphism/6781c347083cd35695fd8ab5e2b15f66). * The generating condition is the closure equation. Terms of this structure are built from mathlib's generation results, and those tend to end in `closure … = ⊤`. The lemma `lift_val_surjective` bridges with the alternative characterization by `Function.Surjective (FreeGroup.lift P.val)`. [See report](https://gist.github.com/homeowmorphism/d69a7b48cd7b87edee595cd3bdee7a71). * Unlike `Algebra.Generators`, this structure bundles no section of `FreeGroup.lift val`. A section earns its keep when elements have a standard form, as `a / rⁿ` does in `Algebra.Generators.localizationAway`. Groups have no such form in general, since the word problem is undecidable. [See report](https://gist.github.com/homeowmorphism/59840e8f40b9f300e4bfcac87ebb4b8f). On a lesser note, I also generated (lower effort) reports for whether the [`val` projection lemmas were necessary](https://gist.github.com/homeowmorphism/49894649a025870e97f6a4aa22e3d400) and [whether the homomorphisms should be implicit or explicit arguments](https://gist.github.com/homeowmorphism/b97779872d8275f086ec7b5ab7327b07). --- Mathlib.lean | 1 + Mathlib/GroupTheory/FreeGroup/Basic.lean | 5 ++ Mathlib/GroupTheory/Generators.lean | 109 +++++++++++++++++++++++ docs/references.bib | 12 +++ 4 files changed, 127 insertions(+) create mode 100644 Mathlib/GroupTheory/Generators.lean diff --git a/Mathlib.lean b/Mathlib.lean index 808fbf72d011c0..2c27b615282531 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4785,6 +4785,7 @@ public import Mathlib.GroupTheory.FreeGroup.IsFreeGroup public import Mathlib.GroupTheory.FreeGroup.NielsenSchreier public import Mathlib.GroupTheory.FreeGroup.Orbit public import Mathlib.GroupTheory.FreeGroup.Reduce +public import Mathlib.GroupTheory.Generators public import Mathlib.GroupTheory.Goursat public import Mathlib.GroupTheory.GroupAction.Basic public import Mathlib.GroupTheory.GroupAction.Blocks diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index fe01d48e4b619d..54acdc29b3dd21 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -719,6 +719,11 @@ theorem range_lift_eq_closure : (lift f).range = Subgroup.closure (Set.range f) rintro _ ⟨a, rfl⟩ exact ⟨FreeGroup.of a, by simp only [lift_apply_of]⟩ +@[to_additive] +theorem lift_surjective_iff_closure_range_eq_top : + Function.Surjective (lift f) ↔ Subgroup.closure (Set.range f) = ⊤ := by + rw [← MonoidHom.range_eq_top, range_lift_eq_closure] + @[to_additive] theorem closure_eq_range (s : Set β) : Subgroup.closure s = (lift ((↑) : s → β)).range := by rw [FreeGroup.range_lift_eq_closure, Subtype.range_coe] diff --git a/Mathlib/GroupTheory/Generators.lean b/Mathlib/GroupTheory/Generators.lean new file mode 100644 index 00000000000000..b5ae532d0e9808 --- /dev/null +++ b/Mathlib/GroupTheory/Generators.lean @@ -0,0 +1,109 @@ +/- +Copyright (c) 2026 Hang Lu Su. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Hang Lu Su +-/ +module + +public import Mathlib.GroupTheory.Finiteness +public import Mathlib.GroupTheory.FreeGroup.Basic + +/-! +# Group generators as data + +## Main definitions + +* `Group.Generators G ι`: The generators of a group are given by a generating family indexed by `ι` +and an assignment `val : ι → G` such that `Subgroup.closure (Set.range val) = ⊤`. + +## Main results + +* `Group.Generators.hom_ext`: if two homomorphisms coincide on the elements of a generating family, + then they are equal. +* `Group.fg_iff_nonempty_finite_generators`: a group is finitely generated if and only if it + admits a finite generating family. + +## Implementation notes + +* The index type `ι` is a parameter, not a field, following the pattern of `Algebra.Generators`. +* Unlike `Algebra.Generators`, this structure bundles no section of `FreeGroup.lift val`, + it just bundles a proof of surjectivity. + +## References + +* [D. F. Holt, S. Rees, C. E. Röver, *Groups, Languages and Automata*][HoltReesRover2017], §1 + +## Tags + +group generators, generating set, finitely generated +-/ + +@[expose] public section + +variable {G H ι ι' : Type*} [Group G] [Group H] + +/-- The generators of a group are given by a generating family indexed by `ι` and an assignment +`val : ι → G` such that `Subgroup.closure (Set.range val) = ⊤`. -/ +structure Group.Generators (G : Type*) [Group G] (ι : Type*) where + /-- The generating family itself: `val i` is the element of `G` indexed by `i : ι`. -/ + val : ι → G + /-- The subgroup closure of the generators is the whole group. -/ + closure_eq_top : Subgroup.closure (Set.range val) = ⊤ + +namespace Group.Generators + +variable (P : Group.Generators G ι) + +theorem lift_val_surjective : Function.Surjective (FreeGroup.lift P.val) := + FreeGroup.lift_surjective_iff_closure_range_eq_top.mpr P.closure_eq_top + +/-- If two homomorphisms coincide on the elements of a generating family, then they are equal. -/ +theorem hom_ext {M : Type*} [Monoid M] (f g : G →* M) (h : ∀ i, f (P.val i) = g (P.val i)) : + f = g := MonoidHom.eq_of_eqOn_dense P.closure_eq_top (Set.forall_mem_range.mpr h) + +/-- The generating family obtained using a generating set `S : Set G`. -/ +def ofSet {S : Set G} (h : Subgroup.closure S = ⊤) : Group.Generators G S where + val := Subtype.val + closure_eq_top := by rwa [Subtype.range_coe] + +@[simp] +lemma ofSet_val {S : Set G} (hS : Subgroup.closure S = ⊤) : + (Group.Generators.ofSet hS).val = Subtype.val := + rfl + +/-- The transport of a generating family along a surjective homomorphism. -/ +protected def map (f : G →* H) (hf : Function.Surjective f) : Group.Generators H ι where + val := f ∘ P.val + closure_eq_top := by + rw [Set.range_comp, ← MonoidHom.map_closure, P.closure_eq_top, + Subgroup.map_top_of_surjective f hf] + +@[simp] +lemma map_val (P : Group.Generators G ι) (f : G →* H) (hf : Function.Surjective f) : + (P.map f hf).val = f ∘ P.val := + rfl + +/-- The transport of a generating family along an equivalence of index types. -/ +def reindex (P : Group.Generators G ι) (e : ι' ≃ ι) : Group.Generators G ι' where + val := P.val ∘ e + closure_eq_top := by + rw [Set.range_comp, EquivLike.range_eq_univ, Set.image_univ, P.closure_eq_top] + +@[simp] +lemma reindex_val (P : Group.Generators G ι) (e : ι' ≃ ι) : (P.reindex e).val = P.val ∘ e := + rfl + +/-- If `G` has a finite generating family, then `G` is finitely generated. -/ +theorem fg [Finite ι] (P : Group.Generators G ι) : Group.FG G := + Group.fg_of_surjective P.lift_val_surjective + +end Group.Generators + +/-- A group is finitely generated if and only if it admits a finite generating family. -/ +theorem Group.fg_iff_nonempty_finite_generators : + Group.FG G ↔ ∃ n : ℕ, Nonempty (Group.Generators G (Fin n)) := by + constructor + · rintro ⟨S, hS⟩ + exact ⟨S.card, ⟨(Group.Generators.ofSet hS).reindex S.equivFin.symm⟩⟩ + · rintro ⟨n, ⟨P⟩⟩ + exact P.fg diff --git a/docs/references.bib b/docs/references.bib index a5c810a59628ba..1f2db4c712f809 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -3069,6 +3069,18 @@ @Article{ hollom2025 url = {https://arxiv.org/abs/2411.16844} } +@Book{ HoltReesRover2017, + author = {Holt, Derek F. and Rees, Sarah and R\"over, Claas E.}, + title = {Groups, languages and automata}, + series = {London Mathematical Society Student Texts}, + volume = {88}, + publisher = {Cambridge University Press, Cambridge}, + year = {2017}, + pages = {xi+294}, + isbn = {978-1-107-15235-9; 978-1-316-60652-0}, + doi = {10.1017/9781316588246} +} + @Article{ hong2014, title = {On the Euclidean dimension of graphs}, author = {Jin Hyup Hong and Dan Ismailescu}, From 60a586d3137d3e98d822532339add74a0c0b73b0 Mon Sep 17 00:00:00 2001 From: Pepa Montero Jimena Date: Wed, 5 Aug 2026 13:16:06 +0000 Subject: [PATCH 1160/1300] feat: add `orbitRel.Quotient.quotient_smul_eq` and `Homeomorph.smul_symm` (#41835) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * `orbitRel.Quotient.quotient_smul_eq`: in the quotient by `MulAction.orbitRel`, `⟦g • a⟧ = ⟦a⟧` for any `g`. * `Homeomorph.smul_symm`: the inverse of the homeomorphism `Homeomorph.smul g` is `Homeomorph.smul g⁻¹`. Split out from #40727. --- Mathlib/GroupTheory/GroupAction/Defs.lean | 4 ++++ Mathlib/Topology/Algebra/ConstMulAction.lean | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Mathlib/GroupTheory/GroupAction/Defs.lean b/Mathlib/GroupTheory/GroupAction/Defs.lean index 1e8459e5c76e51..c1536f63ac54b1 100644 --- a/Mathlib/GroupTheory/GroupAction/Defs.lean +++ b/Mathlib/GroupTheory/GroupAction/Defs.lean @@ -346,6 +346,10 @@ abbrev orbitRel.Quotient : Type _ := variable {G α} +@[to_additive (attr := simp)] +lemma orbitRel.Quotient.quotient_smul_eq {g : G} {a : α} : + ⟦g • a⟧ = (⟦a⟧ : orbitRel.Quotient G α) := Quotient.eq.mpr ⟨g, rfl⟩ + /-- The orbit corresponding to an element of the quotient by `MulAction.orbitRel` -/ @[to_additive /-- The orbit corresponding to an element of the quotient by `AddAction.orbitRel` -/] nonrec def orbitRel.Quotient.orbit (x : orbitRel.Quotient G α) : Set α := diff --git a/Mathlib/Topology/Algebra/ConstMulAction.lean b/Mathlib/Topology/Algebra/ConstMulAction.lean index 4d70c0264fba55..a5b309fbc7b303 100644 --- a/Mathlib/Topology/Algebra/ConstMulAction.lean +++ b/Mathlib/Topology/Algebra/ConstMulAction.lean @@ -243,6 +243,10 @@ theorem continuous_const_smul_iff (c : G) : (Continuous fun x => c • f x) ↔ def Homeomorph.smul (γ : G) : α ≃ₜ α where toEquiv := MulAction.toPerm γ +@[to_additive] +lemma Homeomorph.smul_symm {g : G} : (Homeomorph.smul (α := α) g).symm = Homeomorph.smul g⁻¹ := + Homeomorph.ext_iff.mpr <| smul_symm_apply g + /-- The homeomorphism given by affine-addition by an element of an additive group `Γ` acting on `T` is a homeomorphism from `T` to itself. -/ add_decl_doc Homeomorph.vadd From be0a82e700d28d74a5455ce2b25ca01fd1022d25 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Wed, 5 Aug 2026 13:53:59 +0000 Subject: [PATCH 1161/1300] feat(Algebra/Field): `MulEquiv.isField_congr` (#42334) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove theorem that if `A ≃* B` then `A` is a field iff `B` is a field. --- Mathlib/Algebra/Field/Equiv.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Algebra/Field/Equiv.lean b/Mathlib/Algebra/Field/Equiv.lean index 0a6c2c102a838f..2d7a9645477ee3 100644 --- a/Mathlib/Algebra/Field/Equiv.lean +++ b/Mathlib/Algebra/Field/Equiv.lean @@ -30,3 +30,6 @@ protected theorem IsLocalHom.isField [FunLike F A B] [MonoidWithZeroHomClass F A protected theorem MulEquiv.isField (hB : IsField B) (e : A ≃* B) : IsField A := IsLocalHom.isField e.injective hB + +protected theorem MulEquiv.isField_congr (e : A ≃* B) : IsField A ↔ IsField B := + ⟨e.symm.isField, e.isField⟩ From 89e65db4586e5b2cc7ca1ef8d7af99b06cc56731 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Wed, 5 Aug 2026 13:54:01 +0000 Subject: [PATCH 1162/1300] chore: deduplicate theorem `Polynomial.not_isField` (#42337) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deduplicate the theorem stating `¬IsField (Polynomial R)` which is duplicated as `Polynomial.not_isField` and `Ideal.polynomial_not_isField`. --- Mathlib/Algebra/Polynomial/Div.lean | 7 ------- Mathlib/RingTheory/Jacobson/Ring.lean | 6 +++--- Mathlib/RingTheory/KrullDimension/Polynomial.lean | 3 ++- Mathlib/RingTheory/Polynomial/Basic.lean | 6 +++++- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index 83d5f1a482e89a..23d7825e3eeeaa 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -481,13 +481,6 @@ theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) : rw [natDegree_divByMonic p (monic_X_sub_C a), natDegree_X_sub_C] exact (Nat.pred_lt hp).trans_le h -variable (R) in -theorem not_isField : ¬IsField R[X] := by - nontriviality R - intro h - let := h.toField - simpa using congr_arg natDegree (monic_X.eq_one_of_isUnit <| monic_X (R := R).ne_zero.isUnit) - section multiplicity /-- An algorithm for deciding polynomial divisibility. diff --git a/Mathlib/RingTheory/Jacobson/Ring.lean b/Mathlib/RingTheory/Jacobson/Ring.lean index a9cc0fb1bb631a..b047e420f7319a 100644 --- a/Mathlib/RingTheory/Jacobson/Ring.lean +++ b/Mathlib/RingTheory/Jacobson/Ring.lean @@ -435,7 +435,7 @@ theorem isMaximal_comap_C_of_isMaximal [IsJacobsonRing R] [Nontrivial R] let P' := comap (C : R →+* R[X]) P have hP'_prime : P'.IsPrime := comap_isPrime C P obtain ⟨⟨m, hmem_P⟩, hm⟩ := - Submodule.nonzero_mem_of_bot_lt (bot_lt_of_maximal P polynomial_not_isField) + Submodule.nonzero_mem_of_bot_lt (bot_lt_of_maximal P (Polynomial.not_isField R)) have hm' : m ≠ 0 := by simpa [Submodule.coe_eq_zero] using hm let φ : R ⧸ P' →+* R[X] ⧸ P := quotientMap P (C : R →+* R[X]) le_rfl @@ -478,8 +478,8 @@ private theorem quotient_mk_comp_C_isIntegral_of_jacobson' [Nontrivial R] (hR : ((Ideal.Quotient.mk P).comp C : R →+* R[X] ⧸ P).IsIntegral := by refine (isIntegral_quotientMap_iff _).mp ?_ let P' : Ideal R := P.comap C - obtain ⟨pX, hpX, hp0⟩ := - exists_nonzero_mem_of_ne_bot (ne_of_lt (bot_lt_of_maximal P polynomial_not_isField)).symm hP' + obtain ⟨pX, hpX, hp0⟩ := exists_nonzero_mem_of_ne_bot + (ne_of_lt (bot_lt_of_maximal P (Polynomial.not_isField R))).symm hP' let a : R ⧸ P' := (pX.map (Ideal.Quotient.mk P')).leadingCoeff let M : Submonoid (R ⧸ P') := Submonoid.powers a let φ : R ⧸ P' →+* R[X] ⧸ P := quotientMap P C le_rfl diff --git a/Mathlib/RingTheory/KrullDimension/Polynomial.lean b/Mathlib/RingTheory/KrullDimension/Polynomial.lean index e7a74a3b40a9b9..675c9013d2ed2a 100644 --- a/Mathlib/RingTheory/KrullDimension/Polynomial.lean +++ b/Mathlib/RingTheory/KrullDimension/Polynomial.lean @@ -65,7 +65,8 @@ private lemma height_eq_height_add_one_of_isMaximal (p : Ideal R) [p.IsMaximal] rw [mk_ker, LiesOver.over (P := P) (p := p)] exact map_comap_le have : P'.IsMaximal := map_isMaximal_of_equiv e - have : P'.height = 1 := IsPrincipalIdealRing.height_eq_one_of_isMaximal P' polynomial_not_isField + have : P'.height = 1 := + IsPrincipalIdealRing.height_eq_one_of_isMaximal P' (Polynomial.not_isField (R ⧸ p)) rwa [← e.height_map <| P.map (Ideal.Quotient.mk <| p.map (algebraMap R R[X]))] /-- Let `p` be a maximal ideal of `R`. Then the height of `p[X]` equals the height of `p`. -/ diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index 0572fe353a160f..a84540a4409d58 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -540,8 +540,9 @@ section Ring variable [Ring R] +variable (R) in /-- `R[X]` is never a field for any ring `R`. -/ -theorem polynomial_not_isField : ¬IsField R[X] := by +theorem _root_.Polynomial.not_isField : ¬IsField R[X] := by nontriviality R intro hR obtain ⟨p, hp⟩ := hR.mul_inv_cancel X_ne_zero @@ -550,6 +551,9 @@ theorem polynomial_not_isField : ¬IsField R[X] := by rw [← X_mul, congr_arg degree hp, degree_one, Nat.WithBot.lt_zero_iff, degree_eq_bot] at this exact hp0 this +@[deprecated (since := "2026-08-01")] +alias polynomial_not_isField := Polynomial.not_isField + /-- The only constant in a maximal ideal over a field is `0`. -/ theorem eq_zero_of_constant_mem_of_maximal (hR : IsField R) (I : Ideal R[X]) [hI : I.IsMaximal] (x : R) (hx : C x ∈ I) : x = 0 := by From 550612a8ead6b270d197c727eb666402f3b571b7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Wed, 5 Aug 2026 16:39:34 +0000 Subject: [PATCH 1163/1300] refactor(Geometry/Manifold/Instances/Sphere): use mvfderiv when appropriate (#42374) Fixes a TODO in the file, and some pre-existing defeq abuse. While at it, rename the affected lemmas to follow the naming convention. There is some remaining defeq abuse in the proofs, which we comment on and localise more. While at it, we also remove three defeq abuse options which are simply superfluous now. --- .../Geometry/Manifold/Instances/Sphere.lean | 49 +++++++++++-------- .../Manifold/MFDeriv/NormedSpace.lean | 11 +++++ 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Instances/Sphere.lean b/Mathlib/Geometry/Manifold/Instances/Sphere.lean index ea27f5a75ea293..7c5f1327d29946 100644 --- a/Mathlib/Geometry/Manifold/Instances/Sphere.lean +++ b/Mathlib/Geometry/Manifold/Instances/Sphere.lean @@ -13,7 +13,7 @@ public import Mathlib.Analysis.InnerProductSpace.Calculus public import Mathlib.Analysis.InnerProductSpace.PiL2 public import Mathlib.Geometry.Manifold.Algebra.LieGroup public import Mathlib.Geometry.Manifold.Instances.Real -public import Mathlib.Geometry.Manifold.MFDeriv.Basic +public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace public import Mathlib.LinearAlgebra.Complex.FiniteDimensional public import Mathlib.Tactic.Module @@ -232,7 +232,6 @@ theorem stereo_left_inv (hv : ‖v‖ = 1) {x : sphere (0 : E) 1} (hx : (x : E) · field_simp linear_combination 4 * (a - 1) * pythag -set_option backward.isDefEq.respectTransparency false in theorem stereo_right_inv (hv : ‖v‖ = 1) (w : (ℝ ∙ v)ᗮ) : stereoToFun v (stereoInvFun hv w) = w := by simp only [stereoToFun, stereoInvFun, stereoInvFunAux, smul_add, map_add, map_smul, innerSL_apply_apply, Submodule.orthogonalProjectionOnto_mem_subspace_eq_self] @@ -341,12 +340,10 @@ def stereographic' (n : ℕ) [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) (OrthonormalBasis.fromOrthogonalSpanSingleton n (ne_zero_of_mem_unit_sphere v)).repr.toHomeomorph.toOpenPartialHomeomorph -set_option backward.isDefEq.respectTransparency false in @[simp] theorem stereographic'_source {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : (stereographic' n v).source = {v}ᶜ := by simp [stereographic'] -set_option backward.isDefEq.respectTransparency false in @[simp] theorem stereographic'_target {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : (stereographic' n v).target = Set.univ := by simp [stereographic'] @@ -481,26 +478,24 @@ private lemma stereographic'_neg {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : s simp only [EmbeddingLike.map_eq_zero_iff] apply stereographic_neg_apply --- TODO: rephrase this using `mvfderiv`, avoiding the defeq abuse +-- Without this option, the lemmas `EmbeddingLike.map_eq_zero_iff` and `Submodule.range_subtype` +-- are not applied by simp below. set_option backward.isDefEq.respectTransparency false in /-- Consider the differential of the inclusion of the sphere in `E` at the point `v` as a continuous linear map from `TangentSpace (𝓡 n) v` to `E`. The range of this map is the orthogonal complement of `v` in `E`. - -Note that there is an abuse here of the defeq between `E` and the tangent space to `E` at `(v:E)`. -In general this defeq is not canonical, but in this case (the tangent space of a vector space) it is -canonical. -/ -theorem range_mfderiv_coe_sphere {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : - (mfderiv (𝓡 n) 𝓘(ℝ, E) ((↑) : sphere (0 : E) 1 → E) v : TangentSpace (𝓡 n) v →L[ℝ] E).range = - (ℝ ∙ (v : E))ᗮ := by - rw [((contMDiff_coe_sphere v).mdifferentiableAt one_ne_zero).mfderiv] +-/ +theorem range_mvfderiv_subtypeVal {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : + (mvfderiv (𝓡 n) ((↑) : sphere (0 : E) 1 → E) v).range = (ℝ ∙ (v : E))ᗮ := by + rw [((contMDiff_coe_sphere v).mdifferentiableAt one_ne_zero).mvfderiv] dsimp [chartAt] simp only [fderivWithin_univ, mfld_simps] let U := (OrthonormalBasis.fromOrthogonalSpanSingleton (𝕜 := ℝ) n (ne_zero_of_mem_unit_sphere (-v))).repr suffices (fderiv ℝ ((stereoInvFunAux (-v : E) ∘ (↑)) ∘ U.symm) 0).range = (ℝ ∙ (v : E))ᗮ by - convert! this using 4 + rw [← this] + congr 3 apply stereographic'_neg have : HasFDerivAt (stereoInvFunAux (-v : E) ∘ (Subtype.val : (ℝ ∙ (↑(-v) : E))ᗮ → E)) @@ -523,28 +518,42 @@ theorem range_mfderiv_coe_sphere {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : s rw [Submodule.neg_mem_iff] exact Submodule.mem_span_singleton_self (v : E) --- TODO: rephrase this using `mvfderiv`, avoiding the defeq abuse -set_option backward.isDefEq.respectTransparency false in +@[deprecated range_mvfderiv_subtypeVal (since := "2026-08-02")] +theorem range_mfderiv_coe_sphere {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : + (mfderiv (𝓡 n) 𝓘(ℝ, E) ((↑) : sphere (0 : E) 1 → E) v : TangentSpace (𝓡 n) v →L[ℝ] E).range = + (ℝ ∙ (v : E))ᗮ := by + convert! range_mvfderiv_subtypeVal v + /-- Consider the differential of the inclusion of the sphere in `E` at the point `v` as a continuous linear map from `TangentSpace (𝓡 n) v` to `E`. This map is injective. -/ -theorem mfderiv_coe_sphere_injective {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : - Injective (mfderiv (𝓡 n) 𝓘(ℝ, E) ((↑) : sphere (0 : E) 1 → E) v) := by - rw [((contMDiff_coe_sphere v).mdifferentiableAt one_ne_zero).mfderiv] +theorem injective_mvfderiv_subtypeVal_sphere {n : ℕ} [Fact (finrank ℝ E = n + 1)] + (v : sphere (0 : E) 1) : + Injective (mvfderiv (𝓡 n) ((↑) : sphere (0 : E) 1 → E) v) := by + rw [((contMDiff_coe_sphere v).mdifferentiableAt one_ne_zero).mvfderiv] simp only [chartAt, fderivWithin_univ, mfld_simps] let U := (OrthonormalBasis.fromOrthogonalSpanSingleton (𝕜 := ℝ) n (ne_zero_of_mem_unit_sphere (-v))).repr suffices Injective (fderiv ℝ ((stereoInvFunAux (-v : E) ∘ (↑)) ∘ U.symm) 0) by convert! this using 3 - apply stereographic'_neg + congr 2 + apply stereographic'_neg (v := v) have : HasFDerivAt (stereoInvFunAux (-v : E) ∘ (Subtype.val : (ℝ ∙ (↑(-v) : E))ᗮ → E)) (ℝ ∙ (↑(-v) : E))ᗮ.subtypeL (U.symm 0) := by convert! hasFDerivAt_stereoInvFunAux_comp_coe (-v : E) + -- Otherwise, the lemma `EmbeddingLike.map_eq_zero_iff` is not applied. + set_option backward.isDefEq.respectTransparency false in simp have := congr_arg DFunLike.coe <| (this.comp 0 U.symm.toContinuousLinearEquiv.hasFDerivAt).fderiv refine Eq.subst this.symm ?_ rw [ContinuousLinearMap.coe_comp, ContinuousLinearEquiv.coe_coe] + set_option backward.isDefEq.respectTransparency false in simpa [-Subtype.val_injective] using Subtype.val_injective +@[deprecated injective_mvfderiv_subtypeVal_sphere (since := "2026-08-02")] +theorem mfderiv_coe_sphere_injective {n : ℕ} [Fact (finrank ℝ E = n + 1)] (v : sphere (0 : E) 1) : + Injective (mfderiv (𝓡 n) 𝓘(ℝ, E) ((↑) : sphere (0 : E) 1 → E) v) := by + convert! injective_mvfderiv_subtypeVal_sphere v + end ContMDiffManifold section Circle diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 1112728ab1ba4a..39d5c7eee30870 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -593,3 +593,14 @@ lemma mvfderiv_zero {x : M} : d% (0 : M → F) x = 0 := by simp simpa using this @[deprecated (since := "2026-05-17")] alias extDerivFun_zero := mvfderiv_zero + +-- TODO: the next two lemmas are more type correct than their `mvfderiv` cousins, but not entirely: +-- the right hand side should be of the form `fderiv ∘SL TangentSpaceCastModel`. +protected theorem MDifferentiableWithinAt.mvfderivWithin {f : M → E'} (h : MDiffAt[s] f x) : + d[s] f x = fderivWithin 𝕜 (writtenInExtChartAt I 𝓘(𝕜, E') x f) + ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by + convert! h.mfderivWithin + +protected theorem MDifferentiableAt.mvfderiv {f : M → E'} (h : MDiffAt f x) : + d% f x = fderivWithin 𝕜 (writtenInExtChartAt I 𝓘(𝕜, E') x f) (range I) (extChartAt I x x) := by + convert! h.mfderiv From 3dd956ad3d5bc5dbf49ed1875f430add38a742ca Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Wed, 5 Aug 2026 20:53:43 +0000 Subject: [PATCH 1164/1300] feat: translation invariance of meromorphicity (#40533) Establish a host of elementary simplifier lemmas, showing that all notions associated with the word "meromorphic" are invariant under translation. --- Mathlib/Analysis/Analytic/Order.lean | 12 +++ Mathlib/Analysis/Meromorphic/Basic.lean | 77 ++++++++++++++++++- Mathlib/Analysis/Meromorphic/Divisor.lean | 61 +++++++++++++-- Mathlib/Analysis/Meromorphic/NormalForm.lean | 57 +++++++++++++- Mathlib/Analysis/Meromorphic/Order.lean | 17 ++++ .../Meromorphic/TrailingCoefficient.lean | 48 ++++++++++++ Mathlib/Analysis/Normed/Group/Basic.lean | 25 ++++++ Mathlib/Analysis/Normed/Group/Pointwise.lean | 36 +++++++++ 8 files changed, 324 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Order.lean b/Mathlib/Analysis/Analytic/Order.lean index 2c16752f28d89b..43cc6d88cb0ecb 100644 --- a/Mathlib/Analysis/Analytic/Order.lean +++ b/Mathlib/Analysis/Analytic/Order.lean @@ -484,6 +484,18 @@ lemma analyticOrderAt_centeredMonomial {z₀ : 𝕜} {n : ℕ} : rw [AnalyticAt.analyticOrderAt_eq_natCast (by fun_prop)] exact ⟨1, by simp [Pi.one_def, analyticAt_const]⟩ +/-- The analytic order of the function `(· - c)` at `x` is one if `x = c`. -/ +@[simp] theorem analyticOrderAt_id_sub_const_self {c : 𝕜} : + analyticOrderAt (· - c) c = 1 := by + have := analyticOrderAt_centeredMonomial (n := 1) (z₀ := c) + simp_all [pow_one] + +/-- The analytic order of the function `(· - c)` at `x` is zero if `x ≠ c`. -/ +@[simp] theorem analyticOrderAt_id_sub_const_of_ne {c x : 𝕜} (h : x ≠ c) : + analyticOrderAt (· - c) x = 0 := by + apply analyticOrderAt_eq_zero.2 + grind + section NontriviallyNormedField variable {f g : 𝕜 → 𝕜} {z₀ : 𝕜} diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 560e866ba86d6c..5189416bb0018b 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -23,9 +23,9 @@ Main statements: @[expose] public section -open Filter Set +open Filter Metric Set -open scoped Topology +open scoped Pointwise Topology variable {𝕜 𝕜' : Type*} [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] @@ -457,6 +457,22 @@ lemma meromorphicAt_comp_iff_of_deriv_ne_zero [CompleteSpace 𝕜] [CharZero refine (hf.comp_analyticAt hra).congr (.filter_mono ?_ nhdsWithin_le_nhds) exact EventuallyEq.fun_comp (HasStrictDerivAt.eventually_right_inverse ..) f +/-- `MeromorphicAt` is invariant under translation. -/ +@[to_fun meromorphicAt_fun_comp_add_const_iff_meromorphicAt] +theorem meromorphicAt_comp_add_const_iff_meromorphicAt {c : 𝕜} {f : 𝕜 → E} : + MeromorphicAt (f ∘ (· + c)) x ↔ MeromorphicAt f (x + c) := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · rw [show f = ((f ∘ fun x ↦ x + c) ∘ fun z ↦ z - c) by aesop] + rw [show x = (x + c) - c by ring] at h + exact h.comp_analyticAt (g := fun z ↦ z - c) (by fun_prop) + · exact h.comp_analyticAt (g := fun z ↦ z + c) (by fun_prop) + +/-- `MeromorphicAt` is invariant under translation. -/ +@[to_fun meromorphicAt_fun_comp_sub_const_iff_meromorphicAt] +theorem meromorphicAt_comp_sub_const_iff_meromorphicAt {c : 𝕜} {f : 𝕜 → E} : + MeromorphicAt (f ∘ (· - c)) x ↔ MeromorphicAt f (x - c) := by + simp_rw [sub_eq_add_neg, meromorphicAt_comp_add_const_iff_meromorphicAt] + end composition @@ -608,6 +624,41 @@ include hf in theorem iterated_deriv [CompleteSpace E] {n : ℕ} : MeromorphicOn (_root_.deriv^[n] f) U := fun z hz ↦ (hf z hz).iterated_deriv +/-- `MeromorphicOn` is invariant under translation. -/ +@[to_fun meromorphicOn_fun_comp_add_const_iff_meromorphicOn] +theorem meromorphicOn_comp_add_const_iff_meromorphicOn {c : 𝕜} {U : Set 𝕜} : + MeromorphicOn (f ∘ (· + c)) U ↔ MeromorphicOn f (U + {c}) := by + refine ⟨fun h y hy ↦ ?_, fun h y hy ↦ ?_⟩ + · rw [add_singleton, mem_image] at hy + obtain ⟨x, h₁x, h₂x⟩ := hy + simpa [← h₂x, ← meromorphicAt_comp_add_const_iff_meromorphicAt] using h x h₁x + · rw [meromorphicAt_comp_add_const_iff_meromorphicAt] + aesop + +/-- `MeromorphicOn` is invariant under translation. -/ +@[to_fun meromorphicOn_fun_comp_sub_const_iff_meromorphicOn] +theorem meromorphicOn_comp_sub_const_iff_meromorphicOn {c : 𝕜} {U : Set 𝕜} : + MeromorphicOn (f ∘ (· - c)) U ↔ MeromorphicOn f (U - {c}) := by + simp_rw [sub_eq_add_neg, meromorphicOn_comp_add_const_iff_meromorphicOn, neg_singleton] + +/-- `MeromorphicOn` is invariant under translation, special case where the set is a ball. -/ +@[to_fun (attr := simp) meromorphicOn_ball_fun_comp_sub_const_iff_meromorphicOn_ball] +theorem meromorphicOn_ball_comp_sub_const_iff_meromorphicOn_ball {c : 𝕜} {R : ℝ} : + MeromorphicOn (f ∘ (· - c)) (ball c R) ↔ MeromorphicOn f (ball 0 R) := by + rw [meromorphicOn_comp_sub_const_iff_meromorphicOn, ball_sub_singleton, sub_self] + +/-- `MeromorphicOn` is invariant under translation, special case where the set is a closed ball. -/ +@[to_fun (attr := simp) meromorphicOn_closedBall_fun_comp_sub_const_iff_meromorphicOn_closedBall] +theorem meromorphicOn_closedBall_comp_sub_const_iff_meromorphicOn_closedBall {c : 𝕜} {R : ℝ} : + MeromorphicOn (f ∘ (· - c)) (closedBall c R) ↔ MeromorphicOn f (closedBall 0 R) := by + rw [meromorphicOn_comp_sub_const_iff_meromorphicOn, closedBall_sub_singleton, sub_self] + +/-- `MeromorphicOn` is invariant under translation, special case where the set is a sphere. -/ +@[to_fun (attr := simp) meromorphicOn_sphere_fun_comp_sub_const_iff_meromorphicOn_sphere] +theorem meromorphicOn_sphere_comp_sub_const_iff_meromorphicOn_sphere {c : 𝕜} {R : ℝ} : + MeromorphicOn (f ∘ (· - c)) (sphere c R) ↔ MeromorphicOn f (sphere 0 R) := by + rw [meromorphicOn_comp_sub_const_iff_meromorphicOn, sphere_sub_singleton, sub_self] + end arithmetic include hf in @@ -757,4 +808,26 @@ Meromorphic functions are measurable. exact .of_union_range_cover (.subtype_coe h₂.measurableSet) (.subtype_coe h₁.measurableSet) (by simp [-mem_compl_iff]) h₃.domRestrict.measurable (measurable_of_countable _) +/-- `Meromorphic` is invariant under translation. -/ +@[simp] theorem meromorphic_comp_add_const_iff_meromorphic {c : 𝕜} : + Meromorphic (f ∘ (· + c)) ↔ Meromorphic f := by + rw [Meromorphic, Meromorphic, (Equiv.subRight c).surjective.forall] + simp [meromorphicAt_comp_add_const_iff_meromorphicAt] + +/-- `Meromorphic` is invariant under translation. -/ +@[simp] theorem meromorphic_fun_comp_add_const_iff_meromorphic {c : 𝕜} : + Meromorphic (fun z ↦ f (z + c)) ↔ Meromorphic f := + meromorphic_comp_add_const_iff_meromorphic + +/-- `Meromorphic` is invariant under translation. -/ +@[simp] theorem meromorphic_comp_sub_const_iff_meromorphic {c : 𝕜} : + Meromorphic (f ∘ (· - c)) ↔ Meromorphic f := by + nth_rw 2 [← meromorphic_comp_add_const_iff_meromorphic (c := -c)] + simp_rw [sub_eq_add_neg] + +/-- `Meromorphic` is invariant under translation. -/ +@[simp] theorem meromorphic_fun_comp_sub_const_iff_meromorphic {c : 𝕜} : + Meromorphic (fun z ↦ f (z - c)) ↔ Meromorphic f := + meromorphic_comp_sub_const_iff_meromorphic + end Meromorphic diff --git a/Mathlib/Analysis/Meromorphic/Divisor.lean b/Mathlib/Analysis/Meromorphic/Divisor.lean index 543dc8e84cdd7e..7a261b40486bff 100644 --- a/Mathlib/Analysis/Meromorphic/Divisor.lean +++ b/Mathlib/Analysis/Meromorphic/Divisor.lean @@ -23,7 +23,7 @@ of divisors and of meromorphic functions to subsets of their domain of definitio variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {U : Set 𝕜} {z : 𝕜} {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -open Filter Topology +open Filter Metric Topology namespace MeromorphicOn @@ -68,6 +68,12 @@ Simplifier lemma: on `U`, the divisor of a function `f` that is meromorphic on ` lemma divisor_apply {f : 𝕜 → E} (hf : MeromorphicOn f U) (hz : z ∈ U) : divisor f U z = (meromorphicOrderAt f z).untop₀ := by simp_all [MeromorphicOn.divisor_def] +/-- The divisor of a function `f` evaluates to zero if `f` is not meromorphic. -/ +@[simp] theorem divisor_eq_zero_of_not_meromorphicOn {f : 𝕜 → E} (hf : ¬ MeromorphicOn f U) : + divisor f U z = 0 := by + unfold divisor + aesop + lemma AnalyticOnNhd.divisor_apply {f : 𝕜 → E} (hf : AnalyticOnNhd 𝕜 f U) (hz : z ∈ U) : divisor f U z = ((analyticOrderAt f z).map (↑)).untop₀ := by rw [hf.meromorphicOn.divisor_apply hz, (hf z hz).meromorphicOrderAt_eq] @@ -81,8 +87,8 @@ Special case of `Function.locallyFinsuppWithin.finiteSupport` that frequently sh analysis: Divisors on spheres have finite support. -/ lemma _root_.divisor_sphere_support_finite [ProperSpace 𝕜] {f : 𝕜 → E} {R : ℝ} {c : 𝕜} : - (divisor f (Metric.sphere c R)).support.Finite := - (divisor f (Metric.sphere c R)).finiteSupport (isCompact_sphere c R) + (divisor f (sphere c R)).support.Finite := + (divisor f (sphere c R)).finiteSupport (isCompact_sphere c R) /-- If `f` is meromorphic on a compact set `U` and `V ⊆ U`, then the divisor of `f` on `V` has finite @@ -102,9 +108,9 @@ Special case of `MeromorphicOn.divisor_subset_finiteSupport` that frequently sho analysis, where `U` is a closed ball and `V` is its interior. -/ lemma divisor_ball_support_finite [ProperSpace 𝕜] {f : 𝕜 → E} {R : ℝ} {c : 𝕜} - (hf : MeromorphicOn f (Metric.closedBall c R)) : - (divisor f (Metric.ball c R)).support.Finite := - hf.divisor_support_finite_of_subset (isCompact_closedBall c R) Metric.ball_subset_closedBall + (hf : MeromorphicOn f (closedBall c R)) : + (divisor f (ball c R)).support.Finite := + hf.divisor_support_finite_of_subset (isCompact_closedBall c R) ball_subset_closedBall /-! ## Congruence Lemmas @@ -463,4 +469,47 @@ lemma divisor_sub_const_self {z₀ : 𝕜} {U : Set 𝕜} (h : z₀ ∈ U) : div congr exact (meromorphicOrderAt_eq_int_iff (by fun_prop)).mpr ⟨fun _ ↦ 1, analyticAt_const, by simp⟩ +open scoped Pointwise + +/-- Divisors are invariant under translation. -/ +@[to_fun divisor_fun_comp_add_const_eq_divisor] +theorem divisor_comp_add_const_eq_divisor {c x : 𝕜} {f : 𝕜 → E} : + divisor (f ∘ (· + c)) U (x - c) = divisor f (U + {c}) x := by + by_cases h : ¬ MeromorphicOn f (U + {c}) + · have := meromorphicOn_comp_add_const_iff_meromorphicOn.not.2 h + simp_all + rw [not_not] at h + have := meromorphicOn_comp_add_const_iff_meromorphicOn.2 h + by_cases h₁ : ¬ x ∈ (U + {c}) + · rw [Function.locallyFinsuppWithin.apply_eq_zero_of_notMem, + Function.locallyFinsuppWithin.apply_eq_zero_of_notMem] + <;> simp_all [← sub_eq_add_neg] + rw [divisor_apply, divisor_apply] + <;> simp_all [← sub_eq_add_neg, meromorphicOrderAt_comp_add_const_eq_meromorphicOrderAt] + +/-- Divisors are invariant under translation. -/ +@[to_fun divisor_fun_comp_sub_const_eq_divisor] +theorem divisor_comp_sub_const_eq_divisor {c : 𝕜} {f : 𝕜 → E} : + divisor (f ∘ (· - c)) U (z + c) = divisor f (U - {c}) z := by + rw [sub_eq_add_neg, Set.neg_singleton, ← divisor_comp_add_const_eq_divisor] + simp_rw [← sub_eq_add_neg, sub_neg_eq_add] + +/-- Divisors are invariant under translation, special case where the set is a ball.. -/ +@[to_fun (attr := simp) divisor_ball_fun_comp_sub_const_eq_divisor_ball] +theorem divisor_ball_comp_sub_const_eq_divisor_ball {c : 𝕜} {R : ℝ} {f : 𝕜 → E} : + divisor (f ∘ (· - c)) (ball c R) (z + c) = divisor f (ball 0 R) z := by + rw [divisor_comp_sub_const_eq_divisor, ball_sub_singleton, sub_self] + +/-- Divisors are invariant under translation, special case where the set is a closed ball. -/ +@[to_fun (attr := simp) divisor_closedBall_fun_comp_sub_const_eq_divisor_closedBall] +theorem divisor_closedBall_comp_sub_const_eq_divisor_closedBall {c : 𝕜} {R : ℝ} {f : 𝕜 → E} : + divisor (f ∘ (· - c)) (closedBall c R) (z + c) = divisor f (closedBall 0 R) z := by + rw [divisor_comp_sub_const_eq_divisor, closedBall_sub_singleton, sub_self] + +/-- Divisors are invariant under translation, special case where the set is a sphere. -/ +@[to_fun (attr := simp) divisor_sphere_fun_comp_sub_const_eq_divisor_sphere] +theorem divisor_sphere_comp_sub_const_eq_divisor_sphere {c : 𝕜} {R : ℝ} {f : 𝕜 → E} : + divisor (f ∘ (· - c)) (sphere c R) (z + c) = divisor f (sphere 0 R) z := by + rw [divisor_comp_sub_const_eq_divisor, sphere_sub_singleton, sub_self] + end MeromorphicOn diff --git a/Mathlib/Analysis/Meromorphic/NormalForm.lean b/Mathlib/Analysis/Meromorphic/NormalForm.lean index d3c63eaa3ab74e..1c64648a355648 100644 --- a/Mathlib/Analysis/Meromorphic/NormalForm.lean +++ b/Mathlib/Analysis/Meromorphic/NormalForm.lean @@ -25,7 +25,8 @@ form at a single point and along a set, respectively. @[expose] public section -open Topology WithTop +open Metric Set Topology WithTop +open scoped Pointwise variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @@ -409,6 +410,22 @@ theorem meromorphicNFAt_comp_iff_of_deriv_ne_zero [CompleteSpace 𝕜] [CharZero meromorphicAt_comp_iff_of_deriv_ne_zero hg hg', meromorphicOrderAt_comp_of_deriv_ne_zero hg hg'] +/-- `MeromorphicNFAt` is invariant under translation. -/ +@[to_fun meromorphicNFAt_fun_comp_add_const_iff_meromorphicNFAt] +theorem meromorphicNFAt_comp_add_const_iff_meromorphicNFAt {c : 𝕜} {f : 𝕜 → E} : + MeromorphicNFAt (f ∘ (· + c)) x ↔ MeromorphicNFAt f (x + c) := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · rw [show f = ((f ∘ fun x ↦ x + c) ∘ fun z ↦ z - c) by aesop] + rw [show x = (x + c) - c by ring] at h + exact h.comp_analyticAt (g := fun z ↦ z - c) (by fun_prop) + · exact h.comp_analyticAt (g := fun z ↦ z + c) (by fun_prop) + +/-- `MeromorphicNFAt` is invariant under translation. -/ +@[to_fun meromorphicNFAt_fun_comp_sub_const_iff_meromorphicNFAt] +theorem meromorphicNFAt_comp_sub_const_iff_meromorphicNFAt {c : 𝕜} {f : 𝕜 → E} : + MeromorphicNFAt (f ∘ (· - c)) x ↔ MeromorphicNFAt f (x - c) := by + simp_rw [sub_eq_add_neg, meromorphicNFAt_comp_add_const_iff_meromorphicNFAt] + /-! ### Continuous extension and conversion to normal form -/ @@ -723,6 +740,44 @@ theorem meromorphicNFOn_fun_inv {f : 𝕜 → 𝕜} : MeromorphicNFOn (fun x ↦ (f x)⁻¹) U ↔ MeromorphicNFOn f U := meromorphicNFOn_inv +/-- `MeromorphicNFOn` is invariant under translation. -/ +@[to_fun meromorphicNFOn_fun_comp_add_const_iff_meromorphicNFOn] +theorem meromorphicNFOn_comp_add_const_iff_meromorphicNFOn {c : 𝕜} {U : Set 𝕜} : + MeromorphicNFOn (f ∘ (· + c)) U ↔ MeromorphicNFOn f (U + {c}) := by + refine ⟨fun h y hy ↦ ?_, fun h y hy ↦ ?_⟩ + · rw [add_singleton, mem_image] at hy + obtain ⟨x, h₁x, h₂x⟩ := hy + simpa [← h₂x, ← meromorphicNFAt_comp_add_const_iff_meromorphicNFAt] using h h₁x + · rw [meromorphicNFAt_comp_add_const_iff_meromorphicNFAt] + aesop + +/-- `MeromorphicNFOn` is invariant under translation. -/ +@[to_fun meromorphicNFOn_fun_comp_sub_const_iff_meromorphicNFOn] +theorem meromorphicNFOn_comp_sub_const_iff_meromorphicNFOn {c : 𝕜} {U : Set 𝕜} : + MeromorphicNFOn (f ∘ (· - c)) U ↔ MeromorphicNFOn f (U - {c}) := by + simp_rw [sub_eq_add_neg, meromorphicNFOn_comp_add_const_iff_meromorphicNFOn, neg_singleton] + +/-- `MeromorphicNFOn` is invariant under translation, special case where the set is a ball. -/ +@[to_fun (attr := simp) meromorphicNFOn_ball_fun_comp_sub_const_iff_meromorphicNFOn_ball] +theorem meromorphicNFOn_ball_comp_sub_const_iff_meromorphicNFOn_ball {c : 𝕜} {R : ℝ} : + MeromorphicNFOn (f ∘ (· - c)) (ball c R) ↔ MeromorphicNFOn f (ball 0 R) := by + rw [meromorphicNFOn_comp_sub_const_iff_meromorphicNFOn, ball_sub_singleton, sub_self] + +/-- +`MeromorphicNFOn` is invariant under translation, special case where the set is a closed ball. +-/ +@[to_fun (attr := simp) + meromorphicNFOn_closedBall_fun_comp_sub_const_iff_meromorphicNFOn_closedBall] +theorem meromorphicNFOn_closedBall_comp_sub_const_iff_meromorphicNFOn_closedBall {c : 𝕜} {R : ℝ} : + MeromorphicNFOn (f ∘ (· - c)) (closedBall c R) ↔ MeromorphicNFOn f (closedBall 0 R) := by + rw [meromorphicNFOn_comp_sub_const_iff_meromorphicNFOn, closedBall_sub_singleton, sub_self] + +/-- `MeromorphicNFOn` is invariant under translation, special case where the set is a sphere. -/ +@[to_fun (attr := simp) meromorphicNFOn_sphere_fun_comp_sub_const_iff_meromorphicNFOn_sphere] +theorem meromorphicNFOn_sphere_comp_sub_const_iff_meromorphicNFOn_sphere {c : 𝕜} {R : ℝ} : + MeromorphicNFOn (f ∘ (· - c)) (sphere c R) ↔ MeromorphicNFOn f (sphere 0 R) := by + rw [meromorphicNFOn_comp_sub_const_iff_meromorphicNFOn, sphere_sub_singleton, sub_self] + /-! ### Continuous extension and conversion to normal form -/ diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index c6c76d27223ebb..b3efa50bacce06 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -900,6 +900,23 @@ lemma meromorphicOrderAt_comp_of_deriv_ne_zero (hg : AnalyticAt 𝕜 g x) (hg' : · rw [meromorphicOrderAt_of_not_meromorphicAt hf, meromorphicOrderAt_of_not_meromorphicAt] rwa [meromorphicAt_comp_iff_of_deriv_ne_zero hg hg'] +/-- `meromorphicOrderAt` is invariant under translation. -/ +@[to_fun meromorphicOrderAt_fun_comp_add_const_eq_meromorphicOrderAt] +theorem meromorphicOrderAt_comp_add_const_eq_meromorphicOrderAt {c : 𝕜} {f : 𝕜 → E} : + meromorphicOrderAt (f ∘ (· + c)) x = meromorphicOrderAt f (x + c) := by + classical + by_cases h : ¬ MeromorphicAt f (x + c) + · simp_all [meromorphicAt_comp_add_const_iff_meromorphicAt.not.2 h] + rw [MeromorphicAt.meromorphicOrderAt_comp (by simp_all) (by fun_prop) + (by simp [eventuallyConst_iff_analyticOrderAt_sub_eq_top])] + simp + +/-- `meromorphicOrderAt` is invariant under translation. -/ +@[to_fun meromorphicOrderAt_fun_comp_sub_const_eq_meromorphicOrderAt] +theorem meromorphicOrderAt_comp_sub_const_eq_meromorphicOrderAt {c : 𝕜} {f : 𝕜 → E} : + meromorphicOrderAt (f ∘ (· - c)) x = meromorphicOrderAt f (x - c) := by + simp_rw [sub_eq_add_neg, ← meromorphicOrderAt_comp_add_const_eq_meromorphicOrderAt] + end comp section smul diff --git a/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean b/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean index 506bc6c0e52653..fc7ee610c667ed 100644 --- a/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean +++ b/Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean @@ -504,3 +504,51 @@ lemma MeromorphicAt.meromorphicTrailingCoeffAt_fun_pow {n : ℕ} {f : 𝕜 → (h₁ : MeromorphicAt f x) : meromorphicTrailingCoeffAt (fun z ↦ f z ^ n) x = (meromorphicTrailingCoeffAt f x) ^ n := MeromorphicAt.meromorphicTrailingCoeffAt_pow h₁ + +/-! +## Behavior under Composition +-/ + +/-- +If `g` is analytic at `x` and not locally constant, and `f` is meromorphic at `g x`, express the +trailing coefficient of `f ∘ g` at `x` in terms of `g` and `f`. +-/ +theorem MeromorphicAt.meromorphicTrailingCoeffAt_comp {g : 𝕜 → 𝕜} (hf : MeromorphicAt f (g x)) + (hg : AnalyticAt 𝕜 g x) (hg_nc : ¬EventuallyConst g (𝓝 x)) : + meromorphicTrailingCoeffAt (f ∘ g) x = + (meromorphicTrailingCoeffAt (g · - g x) x) ^ (meromorphicOrderAt f (g x)).untop₀ • + meromorphicTrailingCoeffAt f (g x) := by + by_cases h : meromorphicOrderAt f (g x) = ⊤ + · have : meromorphicTrailingCoeffAt (f ∘ g) x = 0 := by + apply MeromorphicAt.meromorphicTrailingCoeffAt_of_order_eq_top + rw [meromorphicOrderAt_eq_top_iff] at * + exact (hg.map_nhdsNE hg_nc) h + aesop + · set r := (meromorphicOrderAt f (g x)).untop₀ + obtain ⟨F, h₁F, h₂F, h₃F⟩ := (meromorphicOrderAt_ne_top_iff hf).1 h + have h₁ : meromorphicTrailingCoeffAt (f ∘ g) x + = meromorphicTrailingCoeffAt ((g · - g x) ^ r • (F ∘ g)) x := by + apply meromorphicTrailingCoeffAt_congr_nhdsNE + apply Filter.Tendsto.eventually (hg.map_nhdsNE hg_nc) h₃F + rw [h₁, MeromorphicAt.meromorphicTrailingCoeffAt_smul (by fun_prop) (by fun_prop), + (h₁F.comp hg).meromorphicTrailingCoeffAt_of_ne_zero h₂F, + h₁F.meromorphicTrailingCoeffAt_of_ne_zero_of_eq_nhdsNE h₂F h₃F] + simp_all only [ne_eq, Function.comp_apply, not_false_eq_true, smul_left_inj] + apply MeromorphicAt.meromorphicTrailingCoeffAt_zpow (by fun_prop) + +/-- `meromorphicTrailingCoefficientAt` is invariant under translation. -/ +@[to_fun meromorphicTrailingCoeffAt_fun_comp_add_const_eq_meromorphicTrailingCoeffAt] +theorem meromorphicTrailingCoeffAt_comp_add_const_eq_meromorphicTrailingCoeffAt {c : 𝕜} : + meromorphicTrailingCoeffAt (f ∘ (· + c)) x = meromorphicTrailingCoeffAt f (x + c) := by + classical + by_cases h : ¬ MeromorphicAt f (x + c) + · simp_all [meromorphicAt_comp_add_const_iff_meromorphicAt.not.2 h] + rw [MeromorphicAt.meromorphicTrailingCoeffAt_comp (by simp_all) (by fun_prop) + (by simp [eventuallyConst_iff_analyticOrderAt_sub_eq_top])] + simp [meromorphicTrailingCoeffAt_id_sub_const] + +/-- `meromorphicTrailingCoefficientAt` is invariant under translation. -/ +@[to_fun meromorphicTrailingCoeffAt_fun_comp_sub_const_eq_meromorphicTrailingCoeffAt] +theorem meromorphicTrailingCoeffAt_comp_sub_const_eq_meromorphicTrailingCoeffAt {c : 𝕜} : + meromorphicTrailingCoeffAt (f ∘ (· - c)) x = meromorphicTrailingCoeffAt f (x - c) := by + simp [sub_eq_add_neg, ← meromorphicTrailingCoeffAt_comp_add_const_eq_meromorphicTrailingCoeffAt] diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index 0d4b45e5fb3d1e..0e3933a6fd8ffc 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -873,6 +873,14 @@ theorem mem_ball_iff_norm'' : b ∈ ball a r ↔ ‖b / a‖ < r := by theorem mem_ball_iff_norm''' : b ∈ ball a r ↔ ‖a / b‖ < r := by rw [mem_ball', dist_eq_norm_div] +/-- A scaled ball is a ball. -/ +@[to_additive setOf_sub_mem_ball_eq_ball /-- A translated ball is a ball. -/] +theorem setOf_div_mem_ball_eq_ball'' : + {x | x / a ∈ ball 1 r} = Metric.ball a r := by + ext x + rw [mem_ball_iff_norm''] + simp + @[to_additive mem_closedBall_iff_norm] theorem mem_closedBall_iff_norm'' : b ∈ closedBall a r ↔ ‖b / a‖ ≤ r := by rw [mem_closedBall, dist_eq_norm_div] @@ -881,10 +889,27 @@ theorem mem_closedBall_iff_norm'' : b ∈ closedBall a r ↔ ‖b / a‖ ≤ r : theorem mem_closedBall_iff_norm''' : b ∈ closedBall a r ↔ ‖a / b‖ ≤ r := by rw [mem_closedBall', dist_eq_norm_div] +/-- A scaled closed ball is a closed ball. -/ +@[to_additive setOf_sub_mem_closedBall_eq_closedBall + /-- A translated closed ball is a closed ball. -/] +theorem setOf_div_mem_closedBall_eq_closedBall'' : + {x | x / a ∈ closedBall 1 r} = Metric.closedBall a r := by + ext x + rw [mem_closedBall_iff_norm''] + simp + -- Higher priority to fire before `mem_sphere`. @[to_additive (attr := simp high) mem_sphere_iff_norm] theorem mem_sphere_iff_norm' : b ∈ sphere a r ↔ ‖b / a‖ = r := by simp [dist_eq_norm_div] +/-- A scaled sphere is a sphere. -/ +@[to_additive setOf_sub_mem_sphere_eq_sphere /-- A translated sphere is a sphere. -/] +theorem setOf_div_mem_sphere_eq_sphere'' : + {x | x / a ∈ sphere 1 r} = Metric.sphere a r := by + ext x + rw [mem_sphere_iff_norm'] + simp + @[to_additive] theorem mul_mem_ball_iff_norm : a * b ∈ ball a r ↔ ‖b‖ < r := by rw [mem_ball_iff_norm''] diff --git a/Mathlib/Analysis/Normed/Group/Pointwise.lean b/Mathlib/Analysis/Normed/Group/Pointwise.lean index 2bcb46700978cd..263bdd2a9378ce 100644 --- a/Mathlib/Analysis/Normed/Group/Pointwise.lean +++ b/Mathlib/Analysis/Normed/Group/Pointwise.lean @@ -110,6 +110,10 @@ theorem inv_ball : (ball x δ)⁻¹ = ball x⁻¹ δ := (IsometryEquiv.inv E).pr theorem inv_closedBall : (closedBall x δ)⁻¹ = closedBall x⁻¹ δ := (IsometryEquiv.inv E).preimage_closedBall x δ +@[to_additive (attr := simp)] +theorem inv_sphere : (sphere x δ)⁻¹ = sphere x⁻¹ δ := + (IsometryEquiv.inv E).preimage_sphere x δ + @[to_additive] theorem singleton_mul_ball : {x} * ball y δ = ball (x * y) δ := by simp only [preimage_mul_ball, image_mul_left, singleton_mul, div_inv_eq_mul, mul_comm y x] @@ -176,6 +180,38 @@ theorem closedBall_one_div_singleton : closedBall 1 δ / {x} = closedBall x⁻¹ @[to_additive (attr := simp 1100)] theorem smul_closedBall_one : x • closedBall (1 : E) δ = closedBall x δ := by simp +@[to_additive (attr := simp 1100)] +theorem singleton_mul_sphere : {x} * sphere y δ = sphere (x * y) δ := by + simp_rw [singleton_mul, ← smul_eq_mul, image_smul, smul_sphere] + +@[to_additive (attr := simp 1100)] +theorem singleton_div_sphere : {x} / sphere y δ = sphere (x / y) δ := by + simp_rw [div_eq_mul_inv, inv_sphere, singleton_mul_sphere] + +@[to_additive (attr := simp 1100)] +theorem sphere_mul_singleton : sphere x δ * {y} = sphere (x * y) δ := by + simp [mul_comm _ {y}, mul_comm y] + +@[to_additive (attr := simp 1100)] +theorem sphere_div_singleton : sphere x δ / {y} = sphere (x / y) δ := by + simp [div_eq_mul_inv] + +@[to_additive] +theorem singleton_mul_sphere_one : {x} * sphere 1 δ = sphere x δ := by simp + +@[to_additive] +theorem singleton_div_sphere_one : {x} / sphere 1 δ = sphere x δ := by + rw [singleton_div_sphere, div_one] + +@[to_additive] +theorem sphere_one_mul_singleton : sphere 1 δ * {x} = sphere x δ := by simp + +@[to_additive] +theorem sphere_one_div_singleton : sphere 1 δ / {x} = sphere x⁻¹ δ := by simp + +@[to_additive (attr := simp 1100)] +theorem smul_sphere_one : x • sphere (1 : E) δ = sphere x δ := by simp + @[to_additive] theorem mul_ball_one : s * ball 1 δ = thickening δ s := by rw [thickening_eq_biUnion_ball] From c22d6367f2817e66a49dee474968ba326cc851bf Mon Sep 17 00:00:00 2001 From: Bo Cowgill <1121490+bocowgill@users.noreply.github.com> Date: Wed, 5 Aug 2026 22:18:56 +0000 Subject: [PATCH 1165/1300] feat(Analysis/InnerProductSpace/Adjoint): characterize least-squares minimizers (#42122) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds two theorems about least-squares minimizers for a continuous linear map `A`. The first theorem states that the fitted value `A x` minimizes the distance to `y` over `A.range` if and only if the adjoint maps the residual `y - A x` to zero. The second theorem restates the result in coefficient-space. That is, `x` minimizes `‖y - A z‖` over all `z : E` if and only if the same adjoint condition holds. This result is useful because it makes the range-level characterization applicable for least-squares problems (which are often stated in terms of coefficients). These results provide a characterization of least-squares minimizers. The theorems use the existing APIs for range, orthogonal-complement, and adjoints. The PR adds them to `Mathlib/Analysis/InnerProductSpace/Adjoint.lean`. These results were added to `Mathlib/Analysis/InnerProductSpace/Adjoint.lean` because a least-squares residual is orthogonal to `A.range`, while the orthogonal complement of `A.range` is the kernel of the adjoint. --- Mathlib/Analysis/InnerProductSpace/Adjoint.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index c7bddb218368d8..6276f3325d4dc9 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -200,6 +200,23 @@ theorem orthogonal_range (T : E →L[𝕜] F) : T.rangeᗮ = T†.ker := by rw [← T†.ker.orthogonal_orthogonal, T†.orthogonal_ker] simp +/-- The fitted value `A x` minimizes the distance to `y` among points in `A.range` +if and only if the adjoint of `A` sends the residual `y - A x` to zero. -/ +theorem norm_eq_iInf_range_iff_adjoint_apply_eq_zero (A : E →L[𝕜] F) (y : F) (x : E) : + (‖y - A x‖ = ⨅ z : A.range, ‖y - z‖) ↔ (A†) (y - A x) = 0 := by + rw [A.range.norm_eq_iInf_iff_inner_eq_zero (by simp), + ← Submodule.mem_orthogonal', A.orthogonal_range, LinearMap.mem_ker, coe_coe] + +/-- The residual norm at `x` is minimal among all points of `E` if and only if +the adjoint of `A` sends the residual `y - A x` to zero. -/ +theorem forall_norm_sub_apply_le_iff_adjoint_apply_sub_eq_zero + (A : E →L[𝕜] F) (y : F) (x : E) : + (∀ z : E, ‖y - A x‖ ≤ ‖y - A z‖) ↔ (A†) (y - A x) = 0 := by + have hb : BddBelow (Set.range fun w : A.range => ‖y - w‖) := ⟨0, by rintro - ⟨_, rfl⟩; positivity⟩ + rw [← A.norm_eq_iInf_range_iff_adjoint_apply_eq_zero y x, le_antisymm_iff, + and_iff_left (ciInf_le hb ⟨A x, x, rfl⟩), le_ciInf_iff hb] + simp + omit [CompleteSpace E] in theorem ker_le_ker_iff_range_le_range [FiniteDimensional 𝕜 E] {T U : E →L[𝕜] E} (hT : T.IsSymmetric) (hU : U.IsSymmetric) : From a7a52d7610138440e518d6adc923cd7ced74781d Mon Sep 17 00:00:00 2001 From: "Thomas R. Murrills" <68410468+thorimur@users.noreply.github.com> Date: Wed, 5 Aug 2026 22:52:14 +0000 Subject: [PATCH 1166/1300] chore(Data/List/Lookmap): remove `import all` (#42454) This PR removes an unnecessary `import all` and further minimizes imports in `Mathlib.Data.List.Lookmap`. Found while exploring uses of `import all` in mathlib. --- Mathlib/Data/List/Lookmap.lean | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Mathlib/Data/List/Lookmap.lean b/Mathlib/Data/List/Lookmap.lean index 6f230a97b1f05d..7e85fc38e83f3b 100644 --- a/Mathlib/Data/List/Lookmap.lean +++ b/Mathlib/Data/List/Lookmap.lean @@ -5,10 +5,8 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M -/ module -public import Batteries.Logic public import Batteries.Data.List.Basic public import Mathlib.Init -import all Init.Data.Array.Basic /-! ### lookmap -/ @@ -30,7 +28,7 @@ private theorem lookmap.go_append (l : List α) (acc : Array α) : | none => simp only [go_append tl _, Array.toListAppend_eq, append_assoc, Array.toList_push] rfl - | some a => rfl + | some a => simp @[simp, grind =] theorem lookmap_nil : [].lookmap f = [] := @@ -40,7 +38,7 @@ theorem lookmap_nil : [].lookmap f = [] := theorem lookmap_cons_none {a : α} (l : List α) (h : f a = none) : (a :: l).lookmap f = a :: l.lookmap f := by simp only [lookmap, lookmap.go, Array.toListAppend_eq, nil_append] - rw [lookmap.go_append, h]; rfl + rw [lookmap.go_append, lookmap, h]; simp @[simp] theorem lookmap_cons_some {a b : α} (l : List α) (h : f a = some b) : @@ -57,11 +55,11 @@ theorem lookmap_cons {a : α} {l : List α} : theorem lookmap_some : ∀ l : List α, l.lookmap some = l | [] => rfl - | _ :: _ => rfl + | _ :: rest => lookmap_cons_some some rest rfl theorem lookmap_none : ∀ l : List α, (l.lookmap fun _ => none) = l | [] => rfl - | a :: l => (lookmap_cons_none _ l rfl).trans (congr_arg (cons a) (lookmap_none l)) + | a :: l => (lookmap_cons_none _ l rfl).trans (congrArg (cons a) (lookmap_none l)) theorem lookmap_congr {f g : α → Option α} : ∀ {l : List α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g From 6a36f7fd032c9b8218810fffd37130c2ed097c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20G=C3=A1sp=C3=A1r?= <58485900+gasparattila@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:02:22 +0000 Subject: [PATCH 1167/1300] feat(Topology/Sets): local connectedness of `(Nonempty)Compacts` (#34280) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Topology/Sets/VietorisTopology.lean | 60 +++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/Mathlib/Topology/Sets/VietorisTopology.lean b/Mathlib/Topology/Sets/VietorisTopology.lean index c7860354c9679b..e94a9f701053cd 100644 --- a/Mathlib/Topology/Sets/VietorisTopology.lean +++ b/Mathlib/Topology/Sets/VietorisTopology.lean @@ -388,6 +388,12 @@ theorem isPreconnected_sUnion {s : Set (Set α)} (hs : IsPreconnected s) grw [← hts'] at hUV ⊢ exact ht U V hU hV hUV htU htV +theorem isPreconnected_biUnion {s : Set α} {f : α → Set β} (hs : IsPreconnected s) + (hf : ContinuousOn f s) (h : ∃ x ∈ s, IsPreconnected (f x)) : + IsPreconnected (⋃ x ∈ s, f x) := by + rw [← sUnion_image] + exact isPreconnected_sUnion (hs.image _ hf) (by grind) + end vietoris namespace Compacts @@ -773,6 +779,36 @@ theorem isPreconnected_Ioc {K L : Compacts α} (hL : IsPreconnected (L : Set α) isPreconnected_of_forall L fun M hM => ⟨Icc M L, Icc_subset_Ioc_left hM.1, right_mem_Icc.mpr hM.2, left_mem_Icc.mpr hM.2, isPreconnected_Icc (ne_bot_of_gt hM.1) hL⟩ +instance [LocallyConnectedSpace α] : LocallyConnectedSpace (Compacts α) := by + rw [locallyConnectedSpace_iff_isTopologicalBasis_isOpen_isPreconnected] + have basis := IsTopologicalBasis.isOpen_isPreconnected.compacts (α := α) + -- We show that the basic open sets induced by a connected basis are connected. + refine basis.of_isOpen_of_subset (by grind) (fun U hU => ⟨basis.isOpen hU, ?_⟩) + -- By density, it is enough to show connectedness for finite sets in the basic open set. + suffices IsPreconnected (U ∩ {K | (K : Set α).Finite}) by + refine this.subset_closure inter_subset_left ?_ + grw [← (basis.isOpen hU).inter_closure, dense_setOfPred_finite.closure_eq, inter_univ] + obtain ⟨u, ⟨hu', hu⟩, rfl⟩ := hU + simp_rw [← ofPred_and, and_assoc] + let := hu'.fintype + /- The finite sets in the basic open set are can be written as the unions of finite sets from + each connected neighborhood. By the continuity of union, these form a connected set. -/ + suffices {K : Compacts α | ↑K ⊆ ⋃₀ u ∧ (∀ U ∈ u, (↑K ∩ U).Nonempty) ∧ (K : Set α).Finite} = + Finset.univ.sup '' Set.pi univ fun U : u => + {K : Compacts α | (K : Set α).Nonempty ∧ (K : Set α).Finite ∧ (K : Set α) ⊆ U} by + rw [this] + exact .image + (isPreconnected_univ_pi fun U => isPreconnected_nonempty_finite_subsets (hu U.2).2) + _ (by fun_prop) + apply subset_antisymm + · exact fun K ⟨hK₁, hK₂, hK₃⟩ => ⟨fun U => ⟨K ∩ U, (hK₃.inter_of_left _).isCompact⟩, + fun U _ => ⟨hK₂ U U.2, hK₃.inter_of_left _, inter_subset_right⟩, by aesop⟩ + · simp_rw [image_subset_iff, preimage_ofPred_eq, coe_finset_sup, Finset.sup_eq_iSup, + iSup_eq_iUnion, Finset.mem_univ, iUnion_true, iUnion_subset_iff] + refine fun f hf => ⟨by grind, fun U hU => ?_, finite_iUnion (by grind)⟩ + obtain ⟨h₁, -, h₂⟩ := hf ⟨U, hU⟩ trivial + exact h₁.mono (subset_inter (subset_iUnion _ _) h₂) + end Compacts namespace NonemptyCompacts @@ -1084,6 +1120,30 @@ instance [ConnectedSpace α] : ConnectedSpace (NonemptyCompacts α) where protected theorem connectedSpace_iff : ConnectedSpace (NonemptyCompacts α) ↔ ConnectedSpace α := by simp [connectedSpace_iff] +instance [LocallyConnectedSpace α] : LocallyConnectedSpace (NonemptyCompacts α) := + isOpenEmbedding_toCompacts.locallyConnectedSpace + +@[simp] +theorem locallyConnectedSpace_iff : + LocallyConnectedSpace (NonemptyCompacts α) ↔ LocallyConnectedSpace α := by + refine ⟨fun h => locallyConnectedSpace_iff_connected_basis.2 fun x ↦ ?_, fun _ => inferInstance⟩ + refine (nhds_basis_opens x).to_hasBasis' (fun U ⟨hx, hU⟩ => ?_) (by grind) + obtain ⟨V, ⟨hV₁, hV₂⟩, hxV, hKV⟩ := + IsTopologicalBasis.isOpen_isPreconnected.exists_subset_of_mem_open + (show {x} ∈ {K : NonemptyCompacts α | ↑K ⊆ U} by simpa) + (isOpen_subsets_of_isOpen hU) + refine ⟨⋃ L ∈ V, ↑L, ⟨?_, ?_⟩, ?_⟩ + · filter_upwards [continuous_singleton.tendsto x (hV₁.mem_nhds hxV)] with y hy + exact mem_iUnion₂_of_mem hy rfl + · exact vietoris.isPreconnected_biUnion hV₂ (by fun_prop) ⟨{x}, hxV, isPreconnected_singleton⟩ + · rwa [id, iUnion₂_subset_iff] + +@[simp] +theorem _root_.TopologicalSpace.Compacts.locallyConnectedSpace_iff : + LocallyConnectedSpace (Compacts α) ↔ LocallyConnectedSpace α := + ⟨fun _ => NonemptyCompacts.locallyConnectedSpace_iff.mp + isOpenEmbedding_toCompacts.locallyConnectedSpace, fun _ => inferInstance⟩ + end NonemptyCompacts end TopologicalSpace From 6dba1823ef98ded377f7cad0f4ad0c832021e346 Mon Sep 17 00:00:00 2001 From: Artie Khovanov <17950993+artie2000@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:02:25 +0000 Subject: [PATCH 1168/1300] feat(Algebra/Polynomial/Degree): add variation of `degree_sub_lt` (#41214) * Add `_right` variation of `Polynomial.degree_sub_lt`. * Rename `Polynomial.degree_sub_lt` to `Polynomial.degree_sub_lt_left` Co-authored-by: artie2000 --- Mathlib/Algebra/Polynomial/Degree/Defs.lean | 9 ++++++++- Mathlib/Algebra/Polynomial/Div.lean | 2 +- Mathlib/Algebra/Polynomial/Sequence.lean | 2 +- Mathlib/FieldTheory/Minpoly/Field.lean | 2 +- Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean | 2 +- Mathlib/LinearAlgebra/Lagrange.lean | 4 ++-- Mathlib/RingTheory/Polynomial/Basic.lean | 2 +- .../RingTheory/PowerSeries/WeierstrassPreparation.lean | 3 ++- 8 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Degree/Defs.lean b/Mathlib/Algebra/Polynomial/Degree/Defs.lean index a4e225ff874b5c..f98f77c66b3085 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Defs.lean @@ -537,7 +537,7 @@ theorem natDegree_sub_le_of_le (hp : natDegree p ≤ m) (hq : natDegree q ≤ n) natDegree (p - q) ≤ max m n := (p.natDegree_sub_le q).trans <| max_le_max ‹_› ‹_› -theorem degree_sub_lt (hd : degree p = degree q) (hp0 : p ≠ 0) +theorem degree_sub_lt_left (hd : degree p = degree q) (hp0 : p ≠ 0) (hlc : leadingCoeff p = leadingCoeff q) : degree (p - q) < degree p := have hp : monomial (natDegree p) (leadingCoeff p) + p.erase (natDegree p) = p := monomial_add_erase _ _ @@ -554,6 +554,13 @@ theorem degree_sub_lt (hd : degree p = degree q) (hp0 : p ≠ 0) (degree_neg (erase (natDegree q) q) ▸ degree_add_le _ _) _ < degree p := max_lt_iff.2 ⟨hd' ▸ degree_erase_lt hp0, hd.symm ▸ degree_erase_lt hq0⟩ +@[deprecated (since := "2026-06-30")] alias degree_sub_lt := degree_sub_lt_left + +theorem degree_sub_lt_right (hd : degree p = degree q) (hq0 : q ≠ 0) + (hlc : p.leadingCoeff = q.leadingCoeff) : degree (p - q) < degree q := by + rw [← degree_neg, neg_sub] + exact degree_sub_lt_left hd.symm hq0 hlc.symm + theorem degree_X_sub_C_le (r : R) : (X - C r).degree ≤ 1 := (degree_sub_le _ _).trans (max_le degree_X_le (degree_C_le.trans zero_le_one)) diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index 23d7825e3eeeaa..2101c4063f5628 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -110,7 +110,7 @@ theorem div_wf_lemma (h : degree q ≤ degree p ∧ p ≠ 0) (hq : Monic q) : have hlt : natDegree q ≤ natDegree p := (Nat.cast_le (α := WithBot ℕ)).1 (by rw [← degree_eq_natDegree h.2, ← degree_eq_natDegree hq0]; exact h.1) - degree_sub_lt + degree_sub_lt_left (by rw [hq.degree_mul_comm, hq.degree_mul, degree_C_mul_X_pow _ hp, degree_eq_natDegree h.2, degree_eq_natDegree hq0, ← Nat.cast_add, tsub_add_cancel_of_le hlt]) diff --git a/Mathlib/Algebra/Polynomial/Sequence.lean b/Mathlib/Algebra/Polynomial/Sequence.lean index fa7c4361348825..63718f3e1e4bb0 100644 --- a/Mathlib/Algebra/Polynomial/Sequence.lean +++ b/Mathlib/Algebra/Polynomial/Sequence.lean @@ -153,7 +153,7 @@ lemma span_degreeLT {m : ℕ} (hCoeff : ∀ i < m, IsUnit (S i).leadingCoeff) : rw [coeff_smul, coeff_smul, coeff_natDegree, smul_eq_mul, smul_eq_mul, rightinv, mul_one] -- which we can now combine to show that `P - head` must have strictly lower degree, -- as its leading term has been cancelled, completing our proof. - have tail_degree_lt := P.degree_sub_lt head_degree_eq p_ne_zero hPhead + have tail_degree_lt := P.degree_sub_lt_left head_degree_eq p_ne_zero hPhead rwa [degree_eq_natDegree p_ne_zero, hp] at tail_degree_lt /-- The first `m + 1` polynomials of a polynomial sequence span all polynomials of degree `≤ m` if diff --git a/Mathlib/FieldTheory/Minpoly/Field.lean b/Mathlib/FieldTheory/Minpoly/Field.lean index fe6101bdb4fe87..1be91b8eee2d34 100644 --- a/Mathlib/FieldTheory/Minpoly/Field.lean +++ b/Mathlib/FieldTheory/Minpoly/Field.lean @@ -55,7 +55,7 @@ theorem unique {p : A[X]} (pmonic : p.Monic) (hp : Polynomial.aeval x p = 0) symm; apply eq_of_sub_eq_zero by_contra hnz apply degree_le_of_ne_zero A x hnz (by simp [hp]) |>.not_gt - apply degree_sub_lt _ (minpoly.ne_zero hx) + apply degree_sub_lt_left _ (minpoly.ne_zero hx) · rw [(monic hx).leadingCoeff, pmonic.leadingCoeff] · exact le_antisymm (min A x pmonic hp) (pmin (minpoly A x) (monic hx) (aeval A x)) diff --git a/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean b/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean index 1e33ebb30378d6..060ea4e7820e12 100644 --- a/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean +++ b/Mathlib/FieldTheory/Minpoly/IsIntegrallyClosed.lean @@ -132,7 +132,7 @@ theorem _root_.IsIntegrallyClosed.minpoly.unique {s : S} {P : R[X]} (hmo : P.Mon symm; apply eq_of_sub_eq_zero by_contra hnz refine IsIntegrallyClosed.degree_le_of_ne_zero (s := s) hnz (by simp [hP]) |>.not_gt ?_ - refine degree_sub_lt ?_ (ne_zero hs) ?_ + refine degree_sub_lt_left ?_ (ne_zero hs) ?_ · exact le_antisymm (min R s hmo hP) (Pmin (minpoly R s) (monic hs) (aeval R s)) · rw [(monic hs).leadingCoeff, hmo.leadingCoeff] diff --git a/Mathlib/LinearAlgebra/Lagrange.lean b/Mathlib/LinearAlgebra/Lagrange.lean index 0a7fcc873a46ba..d4d69cbc4623ef 100644 --- a/Mathlib/LinearAlgebra/Lagrange.lean +++ b/Mathlib/LinearAlgebra/Lagrange.lean @@ -81,7 +81,7 @@ theorem eq_of_degree_le_of_eval_finset_eq rcases eq_or_ne f 0 with rfl | hf · rwa [degree_zero, eq_comm, degree_eq_bot, eq_comm] at h_deg_eq · exact eq_of_degree_sub_lt_of_eval_finset_eq s - (lt_of_lt_of_le (degree_sub_lt h_deg_eq hf hlc) h_deg_le) h_eval + (lt_of_lt_of_le (degree_sub_lt_left h_deg_eq hf hlc) h_deg_le) h_eval end Finset @@ -122,7 +122,7 @@ theorem eq_of_degree_le_of_eval_index_eq (hvs : Set.InjOn v s) rcases eq_or_ne f 0 with rfl | hf · rwa [degree_zero, eq_comm, degree_eq_bot, eq_comm] at h_deg_eq · exact eq_of_degree_sub_lt_of_eval_index_eq s hvs - (lt_of_lt_of_le (degree_sub_lt h_deg_eq hf hlc) h_deg_le) + (lt_of_lt_of_le (degree_sub_lt_left h_deg_eq hf hlc) h_deg_le) h_eval end Indexed diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index a84540a4409d58..34316182227831 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -817,7 +817,7 @@ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNo exact mt Polynomial.leadingCoeff_eq_zero.1 hq0 have h2 : p.leadingCoeff = (q * Polynomial.X ^ (k - q.natDegree)).leadingCoeff := by rw [← hlqp, Polynomial.leadingCoeff_mul_X_pow] - have := Polynomial.degree_sub_lt h1 hp0 h2 + have := Polynomial.degree_sub_lt_left h1 hp0 h2 rw [Polynomial.degree_eq_natDegree hp0] at this rw [← sub_add_cancel p (q * Polynomial.X ^ (k - q.natDegree))] convert! (Ideal.span ↑s).add_mem _ ((Ideal.span (s : Set R[X])).mul_mem_right _ _) diff --git a/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean b/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean index ac4b409fb6d2a3..4b1d186e22b259 100644 --- a/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean +++ b/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean @@ -778,7 +778,8 @@ theorem IsWeierstrassFactorization.isWeierstrassDivision (Polynomial.X ^ (g.map (IsLocalRing.residue A)).order.toNat - f) := by set n := (g.map (IsLocalRing.residue A)).order.toNat with hn constructor - · refine (Polynomial.degree_sub_lt ?_ (Polynomial.monic_X_pow n).ne_zero ?_).trans_eq (by simpa) + · refine (Polynomial.degree_sub_lt_left ?_ (Polynomial.monic_X_pow n).ne_zero ?_).trans_eq + (by simpa) · simp_rw [H.degree_eq_coe_lift_order_map, Polynomial.degree_X_pow, n, ENat.lift_eq_toNat_of_lt_top] · rw [(Polynomial.monic_X_pow n).leadingCoeff, H.isDistinguishedAt.monic.leadingCoeff] From b2e1dc033002dd5f1c82ec2f5633aaec15ea64df Mon Sep 17 00:00:00 2001 From: Pepa Montero Jimena Date: Wed, 5 Aug 2026 23:02:27 +0000 Subject: [PATCH 1169/1300] feat: restriction lemmas for `OpenPartialHomeomorph.EqOnSource` (#42436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two restriction lemmas for `EqOnSource` - `restr_eqOnSource_of_eqOn`: if `e` and `e'` agree on `e.source ∩ interior s`, then `e.restr s ≈ e'.restr (e.source ∩ interior s)`. - restr_eqOnSource_of_eqOn': version for open sets. If `s` is open, and `e` and `e'` agree on `s`, then `e.restr s ≈ e'.restr (e.source ∩ s)`. and use these to deduce `StructureGroupoid.restr_mem_of_eqOn`: if `G` is closed under restriction and some `e' ∈ G` agrees with `e` on an open set `s`, then `e.restr s ∈ G`. The latter is used in #40727 to show that quotient chart transition maps are compatible, by showing the transition map locally agrees with `g0 • ·` composed with charts. --- Mathlib/Geometry/Manifold/StructureGroupoid.lean | 6 ++++++ Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/Mathlib/Geometry/Manifold/StructureGroupoid.lean b/Mathlib/Geometry/Manifold/StructureGroupoid.lean index b1639f21861cd2..001bbfc8d402b3 100644 --- a/Mathlib/Geometry/Manifold/StructureGroupoid.lean +++ b/Mathlib/Geometry/Manifold/StructureGroupoid.lean @@ -384,6 +384,12 @@ theorem closedUnderRestriction' {G : StructureGroupoid H} [ClosedUnderRestrictio {e : OpenPartialHomeomorph H H} (he : e ∈ G) {s : Set H} (hs : IsOpen s) : e.restr s ∈ G := ClosedUnderRestriction.closedUnderRestriction he s hs +lemma StructureGroupoid.restr_mem_of_eqOn {G : StructureGroupoid H} [ClosedUnderRestriction G] + {e e' : OpenPartialHomeomorph H H} (he : e ∈ G) {s : Set H} (hs : IsOpen s) + (heq : EqOn e e' s) (hsub : e'.source ∩ s ⊆ e.source) : e'.restr s ∈ G := + G.mem_of_eqOnSource (closedUnderRestriction' he (e'.open_source.inter hs)) + (Setoid.symm (restr_eqOnSource_of_eqOn' hs heq hsub)) + /-- The trivial restriction-closed groupoid, containing only open partial homeomorphisms equivalent to the restriction of the identity to the various open subsets. -/ def idRestrGroupoid : StructureGroupoid H where diff --git a/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean b/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean index fe21e40169ee0f..48dc62ba1dc3a4 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean @@ -358,6 +358,18 @@ theorem Set.EqOn.restr_eqOn_source {e e' : OpenPartialHomeomorph X Y} · rw [e.restr_source' _ e'.open_source] refine (EqOn.trans ?_ h).trans ?_ <;> simp only [mfld_simps, eqOn_refl] +theorem restr_eqOnSource_of_eqOn {e e' : OpenPartialHomeomorph X Y} {s : Set X} + (heq : EqOn e e' (e'.source ∩ interior s)) (hsub : e'.source ∩ interior s ⊆ e.source) : + e.restr (e'.source ∩ interior s) ≈ e'.restr s := by + refine ⟨?_, fun z hz ↦ heq (by simpa [e'.open_source.interior_eq] using hz.2)⟩ + rw [e'.restr_source s, e.restr_source' _ (e'.open_source.inter isOpen_interior), + inter_eq_right.mpr hsub] + +theorem restr_eqOnSource_of_eqOn' {e e' : OpenPartialHomeomorph X Y} {s : Set X} (hs : IsOpen s) + (heq : EqOn e e' s) (hsub : e'.source ∩ s ⊆ e.source) : + e.restr (e'.source ∩ s) ≈ e'.restr s := + (hs.interior_eq ▸ restr_eqOnSource_of_eqOn) (heq.mono Set.inter_subset_right) hsub + theorem eq_of_eqOnSource_univ {e e' : OpenPartialHomeomorph X Y} (h : e ≈ e') (s : e.source = univ) (t : e.target = univ) : e = e' := toPartialEquiv_injective <| PartialEquiv.eq_of_eqOnSource_univ _ _ h s t From 4a8fe96bb5f61a749a622d5429ab3eac11ca501b Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:02:28 +0000 Subject: [PATCH 1170/1300] feat: multiplying by an almost-everywhere invertible scalar function preserves a.e. strong measurability (#42445) This PR was automatically created from PR #40582 by @dennj via a [review comment](https://github.com/leanprover-community/mathlib4/pull/40582#discussion_r3714395165) by @EtienneC30. Co-authored-by: dennj <2945710+dennj@users.noreply.github.com> --- .../AEStronglyMeasurable.lean | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean index e668c596342d7d..6ea6fa20830981 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/AEStronglyMeasurable.lean @@ -831,23 +831,43 @@ theorem smul_measure {R : Type*} [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ section MulAction variable {M G G₀ : Type*} -variable [Monoid M] [MulAction M β] [ContinuousConstSMul M β] -variable [Group G] [MulAction G β] [ContinuousConstSMul G β] -variable [GroupWithZero G₀] [MulAction G₀ β] [ContinuousConstSMul G₀ β] +variable [Monoid M] [MulAction M β] +variable [Group G] [MulAction G β] +variable [GroupWithZero G₀] [MulAction G₀ β] -theorem _root_.aestronglyMeasurable_const_smul_iff (c : G) : +theorem _root_.aestronglyMeasurable_const_smul_iff [ContinuousConstSMul G β] (c : G) : AEStronglyMeasurable (fun x => c • f x) μ ↔ AEStronglyMeasurable f μ := ⟨fun h => by simpa only [inv_smul_smul] using h.fun_const_smul c⁻¹, fun h => h.const_smul c⟩ -nonrec theorem _root_.IsUnit.aestronglyMeasurable_const_smul_iff {c : M} (hc : IsUnit c) : +/-- Multiplying by an a.e. strongly measurable scalar *function* with values in a group preserves +a.e. strong measurability. This is the varying-scalar analogue of +`aestronglyMeasurable_const_smul_iff`. -/ +theorem _root_.aestronglyMeasurable_smul_iff [TopologicalSpace G] [ContinuousInv G] + [ContinuousSMul G β] {c : α → G} (hc : AEStronglyMeasurable c μ) : + AEStronglyMeasurable (fun x => c x • f x) μ ↔ AEStronglyMeasurable f μ := + ⟨fun h => (hc.fun_inv.fun_smul h).congr (by simp), fun h => hc.fun_smul h⟩ + +nonrec theorem _root_.IsUnit.aestronglyMeasurable_const_smul_iff [ContinuousConstSMul M β] {c : M} + (hc : IsUnit c) : AEStronglyMeasurable (fun x => c • f x) μ ↔ AEStronglyMeasurable f μ := let ⟨u, hu⟩ := hc hu ▸ aestronglyMeasurable_const_smul_iff u -theorem _root_.aestronglyMeasurable_const_smul_iff₀ {c : G₀} (hc : c ≠ 0) : +theorem _root_.aestronglyMeasurable_const_smul_iff₀ [ContinuousConstSMul G₀ β] {c : G₀} + (hc : c ≠ 0) : AEStronglyMeasurable (fun x => c • f x) μ ↔ AEStronglyMeasurable f μ := (IsUnit.mk0 _ hc).aestronglyMeasurable_const_smul_iff +/-- Multiplying by an almost-everywhere nonzero scalar *function* preserves a.e. strong +measurability. This is the varying-scalar analogue of `aestronglyMeasurable_const_smul_iff₀`. -/ +theorem _root_.aestronglyMeasurable_smul_iff₀ [TopologicalSpace G₀] [ContinuousInv₀ G₀] + [MetrizableSpace G₀] [ContinuousSMul G₀ β] {c : α → G₀} + (hc : AEStronglyMeasurable c μ) (hc0 : ∀ᵐ x ∂μ, c x ≠ 0) : + AEStronglyMeasurable (fun x => c x • f x) μ ↔ AEStronglyMeasurable f μ := by + refine ⟨fun h => (hc.fun_inv₀.fun_smul h).congr ?_, fun h => hc.fun_smul h⟩ + filter_upwards [hc0] with x hx + simp [hx] + end MulAction end AEStronglyMeasurable From 68b2582e619b59419feb441ede8845abd5bf7ae9 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:31:59 +0000 Subject: [PATCH 1171/1300] chore(MeasureTheory/Group): remove an erw (#40405) Extracted from #40348 Co-authored-by: Batixx Co-authored-by: Etienne Marion --- Mathlib/MeasureTheory/Group/GeometryOfNumbers.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/MeasureTheory/Group/GeometryOfNumbers.lean b/Mathlib/MeasureTheory/Group/GeometryOfNumbers.lean index b0eef7a4e5160f..112f74faefc753 100644 --- a/Mathlib/MeasureTheory/Group/GeometryOfNumbers.lean +++ b/Mathlib/MeasureTheory/Group/GeometryOfNumbers.lean @@ -106,7 +106,9 @@ theorem exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure [NormedAddC -- it follows that `s` contains a nonzero point of `L`. have h_zero : 0 ∈ K := K.zero_mem_of_symmetric h_symm suffices Set.Nonempty (⋂ n, Z n) by - erw [← Set.iInter_inter, K.iInter_smul_eq_self h_zero] at this + simp_rw [Z, S, ConvexBody.coe_smul', NNReal.smul_def, ← Set.iInter_inter, NNReal.coe_add, + NNReal.coe_one] at this + rw [K.iInter_smul_eq_self h_zero] at this · obtain ⟨x, hx⟩ := this exact ⟨⟨x, by simp_all⟩, by aesop⟩ · exact (exists_seq_strictAnti_tendsto (0 : ℝ≥0)).choose_spec.2.2 From e0c964f971d7c111d774b88bbcaedbd6e0460a4c Mon Sep 17 00:00:00 2001 From: Bolton Bailey Date: Wed, 5 Aug 2026 23:32:02 +0000 Subject: [PATCH 1172/1300] feat(Data/Nat/Choose/Multinomial): add positivity support (#40468) This PR adds `positivity` tactic support for `Multiset.multinomial`, by adding a `_pos` theorem and an extension. This was done as a part of Project Numina's LeanTriathlon project. AI was used as an assistant in the creation of this PR. --- Mathlib/Data/Nat/Choose/Multinomial.lean | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Mathlib/Data/Nat/Choose/Multinomial.lean b/Mathlib/Data/Nat/Choose/Multinomial.lean index c064602ac4840a..589dc794165ac3 100644 --- a/Mathlib/Data/Nat/Choose/Multinomial.lean +++ b/Mathlib/Data/Nat/Choose/Multinomial.lean @@ -500,4 +500,28 @@ theorem multinomial_nsmul_singleton (k n : ℕ) : (k • {n} : Multiset ℕ).multinomial = Nat.multinomial (Finset.range k) (fun _ ↦ n) := by simp [multinomial_nsmul] +theorem multinomial_pos (m : Multiset ℕ) : 0 < m.multinomial := by + induction m using Multiset.induction_on with + | empty => simp + | cons x m h => + simp only [multinomial_cons, h, mul_pos_iff_of_pos_right] + exact Nat.choose_pos (Nat.le_add_right x m.sum) + +section PositivityExtension + +open Mathlib.Meta.Positivity Qq in +/-- +Positivity extension for `Multiset.multinomial`. +-/ +@[positivity multinomial (_ : Multiset ℕ)] +meta def evalMultinomial : PositivityExt where eval {u α} _zα pα? e := + match pα? with | none => throwError "not PartialOrder ℕ" | some _ => do + match u, α, e with + | 0, ~q(ℕ), ~q(multinomial $a) => + assertInstancesCommute + return .positive q(multinomial_pos $a) + | _, _, _ => throwError "not multinomial" + +end PositivityExtension + end Multiset From 9722f1efae8d4101d2e9818fac973cd7bdd5632c Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:32:04 +0000 Subject: [PATCH 1173/1300] chore(Dynamics): fix defs with underscore (#42074) This PR deprecates all (1) defs with underscore in Dynamics and renames it according to the naming convention. Co-authored-by: Batixx --- Mathlib/Dynamics/TopologicalEntropy/Subset.lean | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Mathlib/Dynamics/TopologicalEntropy/Subset.lean b/Mathlib/Dynamics/TopologicalEntropy/Subset.lean index 77992ea71884af..4a95b2667bd15c 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/Subset.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/Subset.lean @@ -196,20 +196,23 @@ lemma coverEntropy_biUnion_le (s : Set ι) (T : X → X) (F : ι → Set X) : iSup₂_le fun _ i_s ↦ coverEntropy_monotone T (subset_biUnion_of_mem i_s) /-- Topological entropy `CoverEntropy T` as a `SupBotHom` function of the subset. -/ -noncomputable def coverEntropy_supBotHom (T : X → X) : +noncomputable def coverEntropySupBotHom (T : X → X) : SupBotHom (Set X) EReal where toFun := coverEntropy T map_sup' := fun _ _ ↦ coverEntropy_union map_bot' := coverEntropy_empty +@[deprecated (since := "2026-07-25")] +alias coverEntropy_supBotHom := coverEntropySupBotHom + lemma coverEntropy_iUnion_of_finite [Finite ι] {T : X → X} {F : ι → Set X} : coverEntropy T (⋃ i : ι, F i) = ⨆ i : ι, coverEntropy T (F i) := - map_finite_iSup (coverEntropy_supBotHom T) F + map_finite_iSup (coverEntropySupBotHom T) F lemma coverEntropy_biUnion_finset {T : X → X} {F : ι → Set X} {s : Finset ι} : coverEntropy T (⋃ i ∈ s, F i) = ⨆ i ∈ s, coverEntropy T (F i) := by - have := map_finset_sup (coverEntropy_supBotHom T) s F - rw [s.sup_set_eq_biUnion, s.sup_eq_iSup, coverEntropy_supBotHom, SupBotHom.coe_mk, + have := map_finset_sup (coverEntropySupBotHom T) s F + rw [s.sup_set_eq_biUnion, s.sup_eq_iSup, coverEntropySupBotHom, SupBotHom.coe_mk, SupHom.coe_mk] at this rw [this] congr From ab2f81c7876d584c940f4edee46ecc1364082366 Mon Sep 17 00:00:00 2001 From: Evgenia Karunus Date: Wed, 5 Aug 2026 23:32:06 +0000 Subject: [PATCH 1174/1300] feat(Data/Real/ConjExponents): add toReal_of_ne_top (#42260) From the Carleson project. --- Mathlib/Data/Real/ConjExponents.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Data/Real/ConjExponents.lean b/Mathlib/Data/Real/ConjExponents.lean index e923a5955d86f6..10fe83a6761854 100644 --- a/Mathlib/Data/Real/ConjExponents.lean +++ b/Mathlib/Data/Real/ConjExponents.lean @@ -507,6 +507,10 @@ lemma toReal (hp : 1 < p.toReal) [HolderConjugate p q] : p.toReal.HolderConjugate q.toReal := toReal_iff hp |>.mpr ‹_› +lemma toReal_of_ne_top (hp : p ≠ ∞) (hq : q ≠ ∞) [HolderConjugate p q] : + p.toReal.HolderConjugate q.toReal := + toReal ((toReal_lt_toReal one_ne_top hp).mpr ((lt_top_iff_one_lt q p).mp hq.lt_top)) + lemma of_toNNReal (h : NNReal.HolderConjugate p.toNNReal q.toNNReal) : HolderConjugate p q := .of_toReal <| by simpa only [coe_toNNReal_eq_toReal] using h.coe From e8d3e7a9f6b6bb651618702b88ab8d1f4159af30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Wed, 5 Aug 2026 23:32:08 +0000 Subject: [PATCH 1175/1300] chore(Imo/Imo1986Q6): small golf (#42361) It's often easier to use `WellFounded.has_min` in proofs, abstracting over the properties of a minimal element, rather than constructing it "explicitly". --- Archive/Imo/Imo1988Q6.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Archive/Imo/Imo1988Q6.lean b/Archive/Imo/Imo1988Q6.lean index 808ba4e04a4a8b..ab573624c94460 100644 --- a/Archive/Imo/Imo1988Q6.lean +++ b/Archive/Imo/Imo1988Q6.lean @@ -126,9 +126,7 @@ theorem constant_descent_vieta_jumping (x y : ℕ) {claim : Prop} {H : ℕ → rwa [exceptional_empty, Set.sdiff_empty] -- We are now set for an infinite descent argument. -- Let m be the smallest element of the nonempty set S. - let m : ℕ := WellFounded.min Nat.lt_wfRel.wf S S_nonempty - have m_mem : m ∈ S := WellFounded.min_mem Nat.lt_wfRel.wf S S_nonempty - have m_min : ∀ k ∈ S, ¬k < m := fun k hk => WellFounded.not_lt_min Nat.lt_wfRel.wf S hk + obtain ⟨m, m_mem, m_min⟩ := Nat.lt_wfRel.wf.has_min S S_nonempty -- It suffices to show that there is point (a,b) with b ∈ S and b < m. rsuffices ⟨p', p'_mem, p'_small⟩ : ∃ p' : ℕ × ℕ, p'.2 ∈ S ∧ p'.2 < m · solve_by_elim From 8be9d5143c50038b7cd014cf0cad245530f3d39b Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:32:10 +0000 Subject: [PATCH 1176/1300] chore: generalize `NoZeroDivisors` to `IsReduced` when possible (#42417) Follow-up to #33775. In several places where `eq_zero_of_pow_eq_zero` or related lemmas are being used, we can generalize from `NoZeroDivisors` to `IsReduced` without changing anything else. Co-authored-by: NoahW314 --- Mathlib/Algebra/GroupWithZero/Indicator.lean | 2 +- Mathlib/Algebra/GroupWithZero/Torsion.lean | 3 +-- Mathlib/Algebra/IsPrimePow.lean | 4 ++-- Mathlib/Algebra/Order/GroupWithZero/Canonical.lean | 2 +- Mathlib/Algebra/Order/Ring/Canonical.lean | 2 +- Mathlib/Tactic/LinearCombinationPrime.lean | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/Indicator.lean b/Mathlib/Algebra/GroupWithZero/Indicator.lean index fc6fa7031b3bdd..c648e0f33eac40 100644 --- a/Mathlib/Algebra/GroupWithZero/Indicator.lean +++ b/Mathlib/Algebra/GroupWithZero/Indicator.lean @@ -126,7 +126,7 @@ lemma support_mul_of_ne_zero_right (f : ι → M₀) {g : ι → M₀} (hg : ∀ end MulZeroClass section MonoidWithZero -variable [MonoidWithZero M₀] [NoZeroDivisors M₀] {n : ℕ} +variable [MonoidWithZero M₀] [IsReduced M₀] {n : ℕ} @[simp] lemma support_pow (f : ι → M₀) (hn : n ≠ 0) : support (fun a ↦ f a ^ n) = support f := by ext; exact (pow_eq_zero_iff hn).not diff --git a/Mathlib/Algebra/GroupWithZero/Torsion.lean b/Mathlib/Algebra/GroupWithZero/Torsion.lean index 88571448b9f07b..286d99906d9145 100644 --- a/Mathlib/Algebra/GroupWithZero/Torsion.lean +++ b/Mathlib/Algebra/GroupWithZero/Torsion.lean @@ -22,13 +22,12 @@ public section variable {M : Type*} [CommMonoidWithZero M] -theorem IsMulTorsionFree.mk' [NoZeroDivisors M] +theorem IsMulTorsionFree.mk' [IsReduced M] (ih : ∀ x ≠ 0, ∀ y ≠ 0, ∀ n ≠ 0, (x ^ n : M) = y ^ n → x = y) : IsMulTorsionFree M := by refine ⟨fun n hn x y hxy ↦ ?_⟩ by_cases h : x ≠ 0 ∧ y ≠ 0 · exact ih x h.1 y h.2 n hn hxy - have : IsReduced M := inferInstance grind [eq_zero_of_pow_eq_zero, zero_pow] variable [UniqueFactorizationMonoid M] [NormalizationMonoid M] [IsMulTorsionFree Mˣ] diff --git a/Mathlib/Algebra/IsPrimePow.lean b/Mathlib/Algebra/IsPrimePow.lean index 25d76180c60aa2..aba6e238990d62 100644 --- a/Mathlib/Algebra/IsPrimePow.lean +++ b/Mathlib/Algebra/IsPrimePow.lean @@ -37,7 +37,7 @@ theorem isPrimePow_iff_pow_succ : IsPrimePow n ↔ ∃ (p : R) (k : ℕ), Prime ⟨fun ⟨p, k, hp, hk, hn⟩ => ⟨p, k - 1, hp, by rwa [Nat.sub_add_cancel hk]⟩, fun ⟨_, _, hp, hn⟩ => ⟨_, _, hp, Nat.succ_pos', hn⟩⟩ -theorem not_isPrimePow_zero [NoZeroDivisors R] : ¬IsPrimePow (0 : R) := by +theorem not_isPrimePow_zero [IsReduced R] : ¬IsPrimePow (0 : R) := by simp only [isPrimePow_def, not_exists, not_and', and_imp] intro x n _hn hx rw [eq_zero_of_pow_eq_zero hx] @@ -62,7 +62,7 @@ theorem IsPrimePow.pow {n : R} (hn : IsPrimePow n) {k : ℕ} (hk : k ≠ 0) : Is let ⟨p, k', hp, hk', hn⟩ := hn ⟨p, k * k', hp, mul_pos hk.bot_lt hk', by rw [pow_mul', hn]⟩ -theorem IsPrimePow.ne_zero [NoZeroDivisors R] {n : R} (h : IsPrimePow n) : n ≠ 0 := fun t => +theorem IsPrimePow.ne_zero [IsReduced R] {n : R} (h : IsPrimePow n) : n ≠ 0 := fun t => not_isPrimePow_zero (t ▸ h) theorem IsPrimePow.ne_one {n : R} (h : IsPrimePow n) : n ≠ 1 := fun t => diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index e6ec658728efca..b93ffa55d75b1e 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -104,7 +104,7 @@ instance instLinearOrderedAddCommMonoidWithTopOrderDualAdditive : top_add' a := by ext; simp; simp [bot_eq_zero (α := α)] isAddLeftRegular_of_ne_top := by simp; simp +contextual [bot_eq_zero, IsRegular.of_ne_zero] -variable [NoZeroDivisors α] +variable [IsReduced α] lemma pow_pos_iff (hn : n ≠ 0) : 0 < a ^ n ↔ 0 < a := by simp_rw [pos_iff_ne_zero, pow_ne_zero_iff hn] diff --git a/Mathlib/Algebra/Order/Ring/Canonical.lean b/Mathlib/Algebra/Order/Ring/Canonical.lean index 3f01fe4f1501ab..514bcae7ee03c2 100644 --- a/Mathlib/Algebra/Order/Ring/Canonical.lean +++ b/Mathlib/Algebra/Order/Ring/Canonical.lean @@ -68,7 +68,7 @@ protected theorem mul_pos [NoZeroDivisors R] {a b : R} : 0 < a * b ↔ 0 < a ∧ 0 < b := by simp only [pos_iff_ne_zero, ne_eq, mul_eq_zero, not_or] -lemma pow_pos [NoZeroDivisors R] {a : R} (ha : 0 < a) (n : ℕ) : 0 < a ^ n := +lemma pow_pos [IsReduced R] {a : R} (ha : 0 < a) (n : ℕ) : 0 < a ^ n := pos_iff_ne_zero.2 <| pow_ne_zero _ ha.ne' protected lemma mul_lt_mul_of_lt_of_lt diff --git a/Mathlib/Tactic/LinearCombinationPrime.lean b/Mathlib/Tactic/LinearCombinationPrime.lean index 530e066e78ee2e..7fcf74c67c8b36 100644 --- a/Mathlib/Tactic/LinearCombinationPrime.lean +++ b/Mathlib/Tactic/LinearCombinationPrime.lean @@ -130,7 +130,7 @@ theorem eq_trans₃ (p : (a : α) = b) (p₁ : a = a') (p₂ : b = b') : a' = b' theorem eq_of_add [AddGroup α] (p : (a : α) = b) (H : (a' - b') - (a - b) = 0) : a' = b' := by rw [← sub_eq_zero] at p ⊢; rwa [sub_eq_zero, p] at H -theorem eq_of_add_pow [Ring α] [NoZeroDivisors α] (n : ℕ) (p : (a : α) = b) +theorem eq_of_add_pow [Ring α] [IsReduced α] (n : ℕ) (p : (a : α) = b) (H : (a' - b') ^ n - (a - b) = 0) : a' = b' := by rw [← sub_eq_zero] at p ⊢; apply eq_zero_of_pow_eq_zero (n := n); rwa [sub_eq_zero, p] at H From 99458cf1f3559c7090a53203fb8c9092fe975ebd Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:32:12 +0000 Subject: [PATCH 1177/1300] chore(RingTheory/Ideal/Operations): deprecate duplicate theorem (#42420) Deprecate `isRadical_bot_of_noZeroDivisors` in favor of the more general `isRadical_bot`, which only requires `IsReduced`. Making the replacement also allows for a generalization of `radical_bot_of_noZeroDivisors` to `radical_bot_of_isReduced`. Co-authored-by: NoahW314 --- Mathlib/RingTheory/Ideal/Operations.lean | 10 +++++++--- Mathlib/RingTheory/Jacobson/Ring.lean | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 5c0fc693c8946a..24e38b0ab03ee8 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -965,13 +965,17 @@ theorem radical_eq_sInf (I : Ideal R) : radical I = sInf { J : Ideal R | I ≤ J hrm <| this.radical.symm ▸ (sInf_le ⟨hIm, this⟩ : sInf { J : Ideal R | I ≤ J ∧ IsPrime J } ≤ m) hr +@[deprecated isRadical_bot (since := "2026-08-03")] theorem isRadical_bot_of_noZeroDivisors {R} [CommSemiring R] [NoZeroDivisors R] : - (⊥ : Ideal R).IsRadical := fun _ hx => hx.recOn fun _ hn => eq_zero_of_pow_eq_zero hn + (⊥ : Ideal R).IsRadical := isRadical_bot @[simp] -theorem radical_bot_of_noZeroDivisors {R : Type u} [CommSemiring R] [NoZeroDivisors R] : +theorem radical_bot_of_isReduced {R : Type u} [CommSemiring R] [IsReduced R] : radical (⊥ : Ideal R) = ⊥ := - eq_bot_iff.2 isRadical_bot_of_noZeroDivisors + eq_bot_iff.2 isRadical_bot + +@[deprecated (since := "2026-08-03")] +alias radical_bot_of_noZeroDivisors := radical_bot_of_isReduced instance : IdemCommSemiring (Ideal R) := inferInstance diff --git a/Mathlib/RingTheory/Jacobson/Ring.lean b/Mathlib/RingTheory/Jacobson/Ring.lean index b047e420f7319a..f28d8b17cbdb67 100644 --- a/Mathlib/RingTheory/Jacobson/Ring.lean +++ b/Mathlib/RingTheory/Jacobson/Ring.lean @@ -338,7 +338,7 @@ theorem jacobson_bot_of_integral_localization have hRₘ : IsJacobsonRing Rₘ := isJacobsonRing_localization x have hSₘ : IsJacobsonRing Sₘ := isJacobsonRing_of_isIntegral' φ' hφ' refine eq_bot_iff.mpr (le_trans ?_ (le_of_eq hϕ')) - rw [← hSₘ.out isRadical_bot_of_noZeroDivisors, comap_jacobson] + rw [← hSₘ.out isRadical_bot, comap_jacobson] exact sInf_le_sInf fun j hj => ⟨bot_le, let ⟨J, hJ⟩ := hj hJ.2 ▸ this J hJ.1.2⟩ @@ -370,7 +370,7 @@ private theorem isJacobsonRing_polynomial_of_domain (R : Type*) [CommRing R] [Is P.jacobson = P := by by_cases Pb : P = ⊥ · exact Pb.symm ▸ - jacobson_bot_polynomial_of_jacobson_bot (hR.out isRadical_bot_of_noZeroDivisors) + jacobson_bot_polynomial_of_jacobson_bot (hR.out isRadical_bot) · rw [jacobson_eq_iff_jacobson_quotient_eq_bot] let P' := P.comap (C : R →+* R[X]) have : P'.IsPrime := comap_isPrime C P From 77dbaac87c8aa5b1ff404a7e4e8548fa1b6b1eb4 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Thu, 6 Aug 2026 00:12:07 +0000 Subject: [PATCH 1178/1300] feat: tag circle integrability as fun_prop (#41225) On a suggestion of @j-loreaux, tag circle integrability as `fun_prop` to aid proof automatization. Note: Experiments show that much of the automatization benefit is realized only if `MeromorphicOn` will also become `fun_prop`. This is out of scope here, but will be addressed in a follow-up PR. Disclaimer: Clode Code was used in the preparation of this PR. --- Mathlib/Analysis/Complex/Poisson.lean | 4 +- .../ValueDistribution/Proximity/Basic.lean | 2 +- .../Integrability/LogMeromorphic.lean | 1 + .../Integrals/PosLogEqCircleAverage.lean | 1 + .../Integral/CircleIntegral.lean | 63 ++++++++++++++----- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/Mathlib/Analysis/Complex/Poisson.lean b/Mathlib/Analysis/Complex/Poisson.lean index 66d882e3164f42..6d8634acf6e171 100644 --- a/Mathlib/Analysis/Complex/Poisson.lean +++ b/Mathlib/Analysis/Complex/Poisson.lean @@ -162,7 +162,7 @@ theorem re_circleAverage_herglotzRieszKernel_smul {g : ℂ → ℝ} simp only [CircleIntegrable, intervalIntegrable_iff] at hg ⊢ exact Complex.ofRealCLM.integrable_comp hg have h₂ : CircleIntegrable (fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R := - h₁.smul_of_continuousOn (continuousOn_herglotzRieszKernel_sphere hw) + h₁.continuousOn_smul (continuousOn_herglotzRieszKernel_sphere hw) calc (circleAverage (fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R).re = circleAverage (Complex.reCLM ∘ fun ζ ↦ herglotzRieszKernel 0 w ζ • (g ζ : ℂ)) 0 R := (Complex.reCLM.circleAverage_comp_comm h₂).symm @@ -334,7 +334,7 @@ theorem hasDerivAt_circleAverage_herglotzRieszKernel_smul (hg : CircleIntegrable -- Integrability of the integrand at `w` case int => have h₁ : CircleIntegrable (herglotzRieszKernel 0 w • f) 0 R := - hg.smul_of_continuousOn (continuousOn_herglotzRieszKernel_sphere hw) + hg.continuousOn_smul (continuousOn_herglotzRieszKernel_sphere hw) simpa only [CircleIntegrable, Pi.smul_apply'] using h₁ -- Measurability of the differentiated integrand case meas2 => diff --git a/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean b/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean index 4af4060485c837..1dc49e168a284c 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/Proximity/Basic.lean @@ -180,7 +180,7 @@ theorem proximity_sum_top_le [NormedSpace ℂ E] {α : Type*} (s : Finset α) (f _ ≤ circleAverage (∑ c ∈ s, log⁺ ‖f c ·‖ + log s.card) 0 r := by apply circleAverage_mono · apply (Meromorphic.fun_sum hf).meromorphicOn.circleIntegrable_posLog_norm - · apply (CircleIntegrable.fun_sum s h₂f).add (circleIntegrable_const _ _ _) + · fun_prop · intro x hx rw [add_comm] apply posLog_norm_sum_le diff --git a/Mathlib/Analysis/SpecialFunctions/Integrability/LogMeromorphic.lean b/Mathlib/Analysis/SpecialFunctions/Integrability/LogMeromorphic.lean index 5260e2f25a1184..92ed663d9178ac 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrability/LogMeromorphic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrability/LogMeromorphic.lean @@ -184,6 +184,7 @@ alias circleIntegrable_log_norm_meromorphicOn_of_nonneg := /-- Variant of `MeromorphicOn.circleIntegrable_log_norm` for factorized rational functions. -/ +@[fun_prop] theorem circleIntegrable_log_norm_factorizedRational {R : ℝ} {c : ℂ} (D : ℂ → ℤ) : CircleIntegrable (∑ᶠ u, ((D u) * log ‖· - u‖)) c R := CircleIntegrable.finsum (fun _ ↦ diff --git a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean index 6a490053138507..74b9392e3c7c59 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean @@ -31,6 +31,7 @@ variable {a c : ℂ} {R : ℝ} /-- If `a` is any complex number, the function `(log ‖· - a‖)` is circle integrable over every circle. -/ +@[fun_prop] lemma circleIntegrable_log_norm_sub_const (r : ℝ) : CircleIntegrable (log ‖· - a‖) c r := MeromorphicOn.circleIntegrable_log_norm (fun z hz ↦ by fun_prop) diff --git a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean index be51d85b30cd1a..03eddc0ee2aa1a 100644 --- a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean @@ -173,16 +173,21 @@ the function `f ∘ circleMap c R` is integrable on `[0, 2π]`. Note that the actual function used in the definition of `circleIntegral` is `(deriv (circleMap c R) θ) • f (circleMap c R θ)`. Integrability of this function is equivalent to integrability of `f ∘ circleMap c R` whenever `R ≠ 0`. -/ +@[fun_prop] def CircleIntegrable (f : ℂ → E) (c : ℂ) (R : ℝ) : Prop := IntervalIntegrable (fun θ : ℝ ↦ f (circleMap c R θ)) volume 0 (2 * π) theorem circleIntegrable_def (f : ℂ → E) (c : ℂ) (R : ℝ) : CircleIntegrable f c R ↔ IntervalIntegrable (fun θ : ℝ ↦ f (circleMap c R θ)) volume 0 (2 * π) := Iff.rfl -@[simp] +@[simp, fun_prop] theorem circleIntegrable_const (a : E) (c : ℂ) (R : ℝ) : CircleIntegrable (fun _ => a) c R := intervalIntegrable_const +@[fun_prop] +theorem circleIntegrable_id (c : ℂ) (R : ℝ) : CircleIntegrable (fun z => z) c R := + (continuous_circleMap c R).intervalIntegrable 0 (2 * π) + namespace CircleIntegrable variable {f g : ℂ → E} {c : ℂ} {R : ℝ} {A : Type*} [NormedRing A] {a : A} @@ -191,18 +196,22 @@ variable {f g : ℂ → E} {c : ℂ} {R : ℝ} {A : Type*} [NormedRing A] {a : A Analogue of `IntervalIntegrable.abs`: If a real-valued function `f` is circle integrable, then so is `|f|`. -/ +@[to_fun (attr := fun_prop)] theorem abs {f : ℂ → ℝ} (hf : CircleIntegrable f c R) : CircleIntegrable |f| c R := IntervalIntegrable.abs hf -@[to_fun] theorem add (hf : CircleIntegrable f c R) (hg : CircleIntegrable g c R) : +@[to_fun (attr := fun_prop)] +theorem add (hf : CircleIntegrable f c R) (hg : CircleIntegrable g c R) : CircleIntegrable (f + g) c R := IntervalIntegrable.add hf hg -@[to_fun] theorem sub (hf : CircleIntegrable f c R) (hg : CircleIntegrable g c R) : +@[to_fun (attr := fun_prop)] +theorem sub (hf : CircleIntegrable f c R) (hg : CircleIntegrable g c R) : CircleIntegrable (f - g) c R := IntervalIntegrable.sub hf hg /-- Sums of circle integrable functions are circle integrable. -/ +@[to_fun (attr := fun_prop)] protected theorem sum {ι : Type*} (s : Finset ι) {f : ι → ℂ → E} (h : ∀ i ∈ s, CircleIntegrable (f i) c R) : CircleIntegrable (∑ i ∈ s, f i) c R := by @@ -210,14 +219,8 @@ protected theorem sum {ι : Type*} (s : Finset ι) {f : ι → ℂ → E} = ∑ i ∈ s, fun θ ↦ f i (circleMap c R θ))] at * exact IntervalIntegrable.sum s h -/-- Sums of circle integrable functions are circle integrable. -/ -theorem fun_sum {c : ℂ} {R : ℝ} {ι : Type*} (s : Finset ι) {f : ι → ℂ → E} - (h : ∀ i ∈ s, CircleIntegrable (f i) c R) : - CircleIntegrable (fun z ↦ ∑ i ∈ s, f i z) c R := by - convert! CircleIntegrable.sum s h - simp - /-- `finsum`s of circle integrable functions are circle integrable. -/ +@[fun_prop] protected theorem finsum {ι : Type*} {f : ι → ℂ → E} (h : ∀ i, CircleIntegrable (f i) c R) : CircleIntegrable (∑ᶠ i, f i) c R := by by_cases h₁ : (Function.support f).Finite @@ -226,17 +229,15 @@ protected theorem finsum {ι : Type*} {f : ι → ℂ → E} (h : ∀ i, CircleI · rw [finsum_of_infinite_support h₁] apply circleIntegrable_const +@[to_fun (attr := fun_prop)] nonrec theorem neg (hf : CircleIntegrable f c R) : CircleIntegrable (-f) c R := hf.neg /-- If `f` is circle integrable, then so are its scalar multiples. -/ +@[to_fun (attr := fun_prop) const_fun_smul] theorem const_smul {f : ℂ → A} (h : CircleIntegrable f c R) : CircleIntegrable (a • f) c R := IntervalIntegrable.const_mul h _ -/-- If `f` is circle integrable, then so are its scalar multiples. -/ -theorem const_fun_smul {f : ℂ → A} (h : CircleIntegrable f c R) : - CircleIntegrable (fun z ↦ a • f z) c R := const_smul h - variable {𝕜 F : Type*} [NormedRing 𝕜] [NormedAddCommGroup F] [Module 𝕜 F] [NormSMulClass 𝕜 F] @@ -244,22 +245,51 @@ variable If `g` is continuous on the circle `sphere c |R|` and `f` is circle integrable, then `g • f` is circle integrable. -/ -@[to_fun] theorem smul_of_continuousOn {f : ℂ → F} {g : ℂ → 𝕜} (hf : CircleIntegrable f c R) +@[to_fun (attr := fun_prop)] +theorem continuousOn_smul {f : ℂ → F} {g : ℂ → 𝕜} (hf : CircleIntegrable f c R) (hg : ContinuousOn g (sphere c |R|)) : CircleIntegrable (g • f) c R := IntervalIntegrable.continuousOn_smul hf (hg.comp (by fun_prop) (fun x hx ↦ circleMap_mem_sphere' c R x)) +/-- +If `f` is circle integrable and `g` is continuous on the circle `sphere c |R|`, then `f • g` is +circle integrable. +-/ +@[to_fun (attr := fun_prop)] +theorem smul_continuousOn {f : ℂ → 𝕜} {g : ℂ → F} (hf : CircleIntegrable f c R) + (hg : ContinuousOn g (sphere c |R|)) : + CircleIntegrable (f • g) c R := + IntervalIntegrable.smul_continuousOn hf + (hg.comp (by fun_prop) (fun x hx ↦ circleMap_mem_sphere' c R x)) + /-- If `g` is continuous on the circle `sphere c |R|` and `f` is circle integrable, then `g * f` is circle integrable. -/ -@[to_fun] theorem mul_of_continuousOn {f g : ℂ → 𝕜} (hf : CircleIntegrable f c R) +@[to_fun (attr := fun_prop)] +theorem continuousOn_mul {f g : ℂ → 𝕜} (hf : CircleIntegrable f c R) (hg : ContinuousOn g (sphere c |R|)) : CircleIntegrable (g * f) c R := IntervalIntegrable.continuousOn_mul hf (hg.comp (by fun_prop) (fun x hx ↦ circleMap_mem_sphere' c R x)) +/-- +If `f` is circle integrable and `g` is continuous on the circle `sphere c |R|`, then `f * g` is +circle integrable. +-/ +@[to_fun (attr := fun_prop)] +theorem mul_continuousOn {f g : ℂ → 𝕜} (hf : CircleIntegrable f c R) + (hg : ContinuousOn g (sphere c |R|)) : + CircleIntegrable (f * g) c R := + IntervalIntegrable.mul_continuousOn hf + (hg.comp (by fun_prop) (fun x hx ↦ circleMap_mem_sphere' c R x)) + +@[deprecated (since := "2026-07-01")] alias smul_of_continuousOn := continuousOn_smul +@[deprecated (since := "2026-07-01")] alias mul_of_continuousOn := continuousOn_mul +@[deprecated (since := "2026-07-01")] alias fun_smul_of_continuousOn := fun_continuousOn_smul +@[deprecated (since := "2026-07-01")] alias fun_mul_of_continuousOn := fun_continuousOn_mul + /-- The function we actually integrate over `[0, 2π]` in the definition of `circleIntegral` is integrable. -/ theorem out [NormedSpace ℂ E] (hf : CircleIntegrable f c R) : @@ -330,6 +360,7 @@ theorem circleIntegrable_iff [NormedSpace ℂ E] {f : ℂ → E} {c : ℂ} (R : I).aemeasurable.fun_inv.aestronglyMeasurable.fun_smul h.aestronglyMeasurable · simp [norm_smul, h₀] +@[fun_prop] theorem ContinuousOn.circleIntegrable' {f : ℂ → E} {c : ℂ} {R : ℝ} (hf : ContinuousOn f (sphere c |R|)) : CircleIntegrable f c R := (hf.comp_continuous (continuous_circleMap _ _) (circleMap_mem_sphere' _ _)).intervalIntegrable _ _ From 7492625a36d9f2fec11042adea9b7eaf9cc22846 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Thu, 6 Aug 2026 00:12:10 +0000 Subject: [PATCH 1179/1300] chore(Analysis/Seminorm): generalize various lemmas (#42280) --- .../Analysis/LocallyConvex/WithSeminorms.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 32 +++++++++++-------- Mathlib/Topology/Algebra/FilterBasis.lean | 21 +++++++++--- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean index 84382a377250a0..c483bd0e38e773 100644 --- a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean +++ b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean @@ -163,7 +163,7 @@ theorem basisSets_smul (U) (hU : U ∈ p.basisSets) : refine Set.Subset.trans (ball_smul_ball (s.sup p) √r √r) ?_ rw [hU, Real.mul_self_sqrt (le_of_lt hr)] -variable [NormedField 𝕜] [AddCommGroup F] [Module 𝕜 F] (p : SeminormFamily 𝕜 F ι) +variable [NormedDivisionRing 𝕜] [AddCommGroup F] [Module 𝕜 F] (p : SeminormFamily 𝕜 F ι) theorem basisSets_smul_left (x : 𝕜) (U : Set F) (hU : U ∈ p.basisSets) : ∃ V ∈ p.addGroupFilterBasis.sets, V ⊆ (fun y : F => x • y) ⁻¹' U := by diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index cdf425bd708050..9c16d46c947377 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -881,18 +881,9 @@ end AddCommGroup end SeminormedRing -section NormedField +section NormedDivisionRing -variable [NormedField 𝕜] [AddCommGroup E] [Module 𝕜 E] (p : Seminorm 𝕜 E) {r : ℝ} {x : E} - -theorem closedBall_iSup {ι : Sort*} {p : ι → Seminorm 𝕜 E} (hp : BddAbove (range p)) (e : E) - {r : ℝ} (hr : 0 < r) : closedBall (⨆ i, p i) e r = ⋂ i, closedBall (p i) e r := by - cases isEmpty_or_nonempty ι - · rw [iSup_of_empty', iInter_of_empty, Seminorm.sSup_empty] - exact closedBall_bot _ hr - · ext x - have := Seminorm.bddAbove_range_iff.mp hp (x - e) - simp only [mem_closedBall, mem_iInter, Seminorm.iSup_apply hp, ciSup_le_iff this] +variable [NormedDivisionRing 𝕜] [AddCommGroup E] [Module 𝕜 E] (p : Seminorm 𝕜 E) {r : ℝ} {x : E} theorem ball_norm_mul_subset {p : Seminorm 𝕜 E} {k : 𝕜} {r : ℝ} : p.ball 0 (‖k‖ * r) ⊆ k • p.ball 0 r := by @@ -973,6 +964,21 @@ theorem smul_closedBall_preimage (p : Seminorm 𝕜 E) (y : E) (r : ℝ) (a : rw [mem_preimage, mem_closedBall, mem_closedBall, le_div_iff₀ (norm_pos_iff.mpr ha), mul_comm, ← map_smul_eq_mul p, smul_sub, smul_inv_smul₀ ha] +end NormedDivisionRing + +section NormedField + +variable [NormedField 𝕜] [AddCommGroup E] [Module 𝕜 E] (p : Seminorm 𝕜 E) {r : ℝ} {x : E} + +theorem closedBall_iSup {ι : Sort*} {p : ι → Seminorm 𝕜 E} (hp : BddAbove (range p)) (e : E) + {r : ℝ} (hr : 0 < r) : closedBall (⨆ i, p i) e r = ⋂ i, closedBall (p i) e r := by + cases isEmpty_or_nonempty ι + · rw [iSup_of_empty', iInter_of_empty, Seminorm.sSup_empty] + exact closedBall_bot _ hr + · ext x + have := Seminorm.bddAbove_range_iff.mp hp (x - e) + simp only [mem_closedBall, mem_iInter, Seminorm.iSup_apply hp, ciSup_le_iff this] + end NormedField section Convex @@ -1333,12 +1339,12 @@ variable {𝕜 E} {x : E} /-- Balls at the origin are absorbent. -/ theorem absorbent_ball_zero (hr : 0 < r) : Absorbent 𝕜 (Metric.ball (0 : E) r) := by rw [← ball_normSeminorm 𝕜] - exact (normSeminorm _ _).absorbent_ball_zero hr + exact (normSeminorm 𝕜 _).absorbent_ball_zero hr /-- Balls containing the origin are absorbent. -/ theorem absorbent_ball (hx : ‖x‖ < r) : Absorbent 𝕜 (Metric.ball x r) := by rw [← ball_normSeminorm 𝕜] - exact (normSeminorm _ _).absorbent_ball hx + exact (normSeminorm 𝕜 _).absorbent_ball hx /-- Balls at the origin are balanced. -/ theorem balanced_ball_zero : Balanced 𝕜 (Metric.ball (0 : E) r) := by diff --git a/Mathlib/Topology/Algebra/FilterBasis.lean b/Mathlib/Topology/Algebra/FilterBasis.lean index 33f18777ab10a7..421e9edbebe510 100644 --- a/Mathlib/Topology/Algebra/FilterBasis.lean +++ b/Mathlib/Topology/Algebra/FilterBasis.lean @@ -291,7 +291,7 @@ end RingFilterBasis Example : if `M` is a topological module then the neighbourhoods of zero are a `ModuleFilterBasis`. Conversely given a `ModuleFilterBasis` one can define a topology compatible with the module structure on `M`. -/ -structure ModuleFilterBasis (R M : Type*) [CommRing R] [TopologicalSpace R] [AddCommGroup M] +structure ModuleFilterBasis (R M : Type*) [Semiring R] [TopologicalSpace R] [AddCommGroup M] [Module R M] extends AddGroupFilterBasis M where smul' : ∀ {U}, U ∈ sets → ∃ V ∈ 𝓝 (0 : R), ∃ W ∈ sets, V • W ⊆ U smul_left' : ∀ (x₀ : R) {U}, U ∈ sets → ∃ V ∈ sets, V ⊆ (fun x ↦ x₀ • x) ⁻¹' U @@ -299,7 +299,9 @@ structure ModuleFilterBasis (R M : Type*) [CommRing R] [TopologicalSpace R] [Add namespace ModuleFilterBasis -variable {R M : Type*} [CommRing R] [TopologicalSpace R] [AddCommGroup M] [Module R M] +section Semiring + +variable {R M : Type*} [Semiring R] [TopologicalSpace R] [AddCommGroup M] [Module R M] (B : ModuleFilterBasis R M) instance GroupFilterBasis.hasMem : Membership (Set M) (ModuleFilterBasis R M) := @@ -345,10 +347,17 @@ def topology : TopologicalSpace M := It has the given basis as a basis of neighborhoods of zero. This version gets the ring topology by unification instead of type class inference. -/ @[instance_reducible] -def topology' {R M : Type*} [CommRing R] {_ : TopologicalSpace R} [AddCommGroup M] [Module R M] +def topology' {R M : Type*} [Semiring R] {_ : TopologicalSpace R} [AddCommGroup M] [Module R M] (B : ModuleFilterBasis R M) : TopologicalSpace M := B.toAddGroupFilterBasis.topology +end Semiring + +section Ring + +variable {R M : Type*} [Ring R] [TopologicalSpace R] [AddCommGroup M] [Module R M] + (B : ModuleFilterBasis R M) + /-- A topological additive group with a basis of `𝓝 0` satisfying the axioms of `ModuleFilterBasis` is a topological module. @@ -391,8 +400,8 @@ instance (priority := 100) continuousSMul [IsTopologicalRing R] : (by simpa using! B.smul_left) B.smul_right /-- Build a module filter basis from compatible ring and additive group filter bases. -/ -def ofBases {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] (BR : RingFilterBasis R) - (BM : AddGroupFilterBasis M) (smul : ∀ {U}, U ∈ BM → ∃ V ∈ BR, ∃ W ∈ BM, V • W ⊆ U) +def ofBases (BR : RingFilterBasis R) (BM : AddGroupFilterBasis M) + (smul : ∀ {U}, U ∈ BM → ∃ V ∈ BR, ∃ W ∈ BM, V • W ⊆ U) (smul_left : ∀ (x₀ : R) {U}, U ∈ BM → ∃ V ∈ BM, V ⊆ (fun x ↦ x₀ • x) ⁻¹' U) (smul_right : ∀ (m₀ : M) {U}, U ∈ BM → ∃ V ∈ BR, V ⊆ (fun x ↦ x • m₀) ⁻¹' U) : @ModuleFilterBasis R M _ BR.topology _ _ := @@ -408,4 +417,6 @@ def ofBases {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M] (BR : RingF rcases smul_right m₀ U_in with ⟨V, V_in, H⟩ exact mem_of_superset (BR.toAddGroupFilterBasis.mem_nhds_zero V_in) H } +end Ring + end ModuleFilterBasis From 73b73320d7faac86c74410d7ef1c9f30fab2e12f Mon Sep 17 00:00:00 2001 From: Bolton Bailey Date: Thu, 6 Aug 2026 00:34:06 +0000 Subject: [PATCH 1180/1300] feat(Algebra/Order/Floor/Ring): `positivity` for `Int.fract` (#41877) This PR adds a positivity extension for `Int.fract`, which is always nonnegative. I used Claude Code to prepare this PR. --- Mathlib/Algebra/Order/Floor/Ring.lean | 14 ++++++++++++++ MathlibTest/positivity.lean | 2 ++ 2 files changed, 16 insertions(+) diff --git a/Mathlib/Algebra/Order/Floor/Ring.lean b/Mathlib/Algebra/Order/Floor/Ring.lean index d144ebe830a32c..49904a0d6ade8e 100644 --- a/Mathlib/Algebra/Order/Floor/Ring.lean +++ b/Mathlib/Algebra/Order/Floor/Ring.lean @@ -910,3 +910,17 @@ theorem subsingleton_floorRing {R} [Ring R] [LinearOrder R] : Subsingleton (Floo funext fun a => (H₁.gc_coe_floor.u_unique H₂.gc_coe_floor) fun _ => rfl have : H₁.ceil = H₂.ceil := funext fun a => (H₁.gc_ceil_coe.l_unique H₂.gc_ceil_coe) fun _ => rfl cases H₁; cases H₂; congr + +namespace Mathlib.Meta.Positivity + +open Lean.Meta Qq + +/-- Extension for the `positivity` tactic: `Int.fract` is always nonnegative. -/ +@[positivity Int.fract _] +meta def evalIntFract : PositivityExt where eval {_u} (_α _zα pα?) e := + match pα? with | none => pure .none | some pα' => do + let ~q(@Int.fract _ (_) (_) (_) $a) := e | throwError "not Int.fract" + let pa' ← mkAppM ``Int.fract_nonneg #[a] + pure (.nonnegative (pα := pα') pa') + +end Mathlib.Meta.Positivity diff --git a/MathlibTest/positivity.lean b/MathlibTest/positivity.lean index 8c86757d4a6c9b..0970c2a235ba9a 100644 --- a/MathlibTest/positivity.lean +++ b/MathlibTest/positivity.lean @@ -399,6 +399,8 @@ example {a : ℝ} (ha : 0 < a) : 0 < ⌈a⌉₊ := by positivity example {a : ℝ} (ha : 0 < a) : 0 < ⌈a⌉ := by positivity example {a : ℝ} (ha : 0 ≤ a) : 0 ≤ ⌈a⌉ := by positivity +example (a : ℝ) : 0 ≤ Int.fract a := by positivity + end FloorCeil section Abs From 8b3ded7849276dbf027e31170b435a2440e4556e Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Thu, 6 Aug 2026 00:34:08 +0000 Subject: [PATCH 1181/1300] chore(FieldTheory): fix defs with underscores (#42073) This PR deprecates all (1) defs with underscore in FieldTheory and renames it according to the naming convention. Co-authored-by: Batixx --- Mathlib/FieldTheory/Differential/Liouville.lean | 2 +- Mathlib/FieldTheory/Galois/Basic.lean | 2 +- Mathlib/FieldTheory/IntermediateField/Basic.lean | 5 ++++- Mathlib/FieldTheory/LinearDisjoint.lean | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Mathlib/FieldTheory/Differential/Liouville.lean b/Mathlib/FieldTheory/Differential/Liouville.lean index 284d70fa8567fe..7792e633f4a878 100644 --- a/Mathlib/FieldTheory/Differential/Liouville.lean +++ b/Mathlib/FieldTheory/Differential/Liouville.lean @@ -206,7 +206,7 @@ instance isLiouville_of_finiteDimensional [FiniteDimensional F K] : let B : IntermediateField F K'' := IntermediateField.restrict (F := K') (IntermediateField.le_normalClosure ..) have kequiv : K ≃ₐ[F] ↥B := (show K ≃ₐ[F] K' from AlgEquiv.ofInjectiveField map).trans - (IntermediateField.restrict_algEquiv _) + (IntermediateField.restrictAlgEquiv _) IsLiouville.equiv kequiv.symm end Algebraic diff --git a/Mathlib/FieldTheory/Galois/Basic.lean b/Mathlib/FieldTheory/Galois/Basic.lean index ca7c4c787c1f51..2e094fd9f18736 100644 --- a/Mathlib/FieldTheory/Galois/Basic.lean +++ b/Mathlib/FieldTheory/Galois/Basic.lean @@ -695,7 +695,7 @@ theorem finrank_eq_fixingSubgroup_index (L : IntermediateField F E') [IsGalois F classical rw [← IsGalois.card_fixingSubgroup_eq_finrank L', ← IsGalois.card_aut_eq_finrank F E] at h rw [← L'.fixingSubgroup.index_mul_card, Nat.mul_left_inj Finite.card_pos.ne'] at h - rw [(restrict_algEquiv hle).toLinearEquiv.finrank_eq, h, ← L'.map_fixingSubgroup_index E'] + rw [(restrictAlgEquiv hle).toLinearEquiv.finrank_eq, h, ← L'.map_fixingSubgroup_index E'] congr 2 exact lift_restrict hle diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index 32c932c6c3b446..70b6e979f673c4 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -911,10 +911,13 @@ theorem lift_restrict : lift (restrict h) = F := by /-- `F` is equivalent to `F` as an intermediate field of `E / K`. -/ -noncomputable def restrict_algEquiv : +noncomputable def restrictAlgEquiv : F ≃ₐ[K] ↥(IntermediateField.restrict h) := AlgEquiv.ofInjectiveField _ +@[deprecated (since := "2026-07-25")] +alias restrict_algEquiv := restrictAlgEquiv + end Restrict end Tower diff --git a/Mathlib/FieldTheory/LinearDisjoint.lean b/Mathlib/FieldTheory/LinearDisjoint.lean index 5405cd8891701d..69d967cea75c6c 100644 --- a/Mathlib/FieldTheory/LinearDisjoint.lean +++ b/Mathlib/FieldTheory/LinearDisjoint.lean @@ -461,7 +461,7 @@ theorem of_inf_eq_bot [IsGalois F A] [FiniteDimensional F A] [FiniteDimensional rw [← lift_inj, lift_top, lift_sup, lift_restrict le_sup_left, lift_restrict le_sup_right] have h₂ : A' ⊓ B' = ⊥ := by rw [← lift_inj, lift_bot, lift_inf, lift_restrict le_sup_left, lift_restrict le_sup_right, h] - have : IsGalois F A' := IsGalois.of_algEquiv <| restrict_algEquiv .. + have : IsGalois F A' := IsGalois.of_algEquiv <| restrictAlgEquiv .. exact of_inf_eq_bot_aux h₁ h₂ @[simp] From e900b02601380aeb32841cbfe68d868bb0c0c59c Mon Sep 17 00:00:00 2001 From: TJHeeringa <16029718+TJHeeringa@users.noreply.github.com> Date: Thu, 6 Aug 2026 00:34:10 +0000 Subject: [PATCH 1182/1300] chore: deprecate apply_eq_iff_eq_symm_apply (#42094) `apply_eq_iff_eq_symm_apply` is `Iff.symm` of `eq_symm_apply`. This deprecates the former in favour of the latter. --- Mathlib/Algebra/BigOperators/Finsupp/Basic.lean | 2 +- Mathlib/Algebra/Category/Grp/Adjunctions.lean | 4 ++-- Mathlib/Algebra/Group/Action/Basic.lean | 2 +- Mathlib/Algebra/Group/Equiv/Defs.lean | 8 ++++---- Mathlib/Algebra/Group/Units/Equiv.lean | 2 +- Mathlib/Algebra/Lie/Basic.lean | 9 +++++---- Mathlib/Algebra/Lie/Extension.lean | 2 +- Mathlib/Algebra/Lie/Submodule.lean | 2 +- Mathlib/Algebra/Module/TransferInstance.lean | 2 +- Mathlib/Algebra/Order/Hom/Monoid.lean | 8 ++++---- Mathlib/Algebra/Torsor/Defs.lean | 2 +- Mathlib/Algebra/Tropical/Basic.lean | 4 ++-- .../AlgebraicTopology/SimplicialSet/StdSimplex.lean | 3 +-- Mathlib/Analysis/Real/Sqrt.lean | 2 +- Mathlib/CategoryTheory/FintypeCat.lean | 3 +-- Mathlib/CategoryTheory/Preadditive/Biproducts.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Maps.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Subgraph.lean | 2 +- Mathlib/Data/DFinsupp/BigOperators.lean | 2 +- Mathlib/Data/Fin/Tuple/Sort.lean | 2 +- Mathlib/Data/Finsupp/Basic.lean | 2 +- Mathlib/Data/Finsupp/Multiset.lean | 2 +- Mathlib/Data/Finsupp/Option.lean | 2 +- Mathlib/Data/Matrix/PEquiv.lean | 4 ++-- Mathlib/Data/Opposite.lean | 4 ++-- Mathlib/Data/ZMod/QuotientGroup.lean | 2 +- Mathlib/FieldTheory/PolynomialGaloisGroup.lean | 2 +- Mathlib/GroupTheory/Complement.lean | 6 +++--- Mathlib/GroupTheory/CoprodI.lean | 2 +- Mathlib/GroupTheory/Perm/ConjAct.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean | 11 +++++++++-- Mathlib/LinearAlgebra/Matrix/Transvection.lean | 2 +- Mathlib/LinearAlgebra/TensorProduct/Tower.lean | 2 +- Mathlib/Logic/Basic.lean | 2 +- Mathlib/Logic/Equiv/Defs.lean | 6 ++++-- Mathlib/Logic/Equiv/Fin/Basic.lean | 8 ++++---- Mathlib/Logic/Equiv/Option.lean | 2 +- Mathlib/Logic/Equiv/Set.lean | 4 ++-- .../NumberField/Units/DirichletTheorem.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 10 +++++++--- Mathlib/Order/RelIso/Basic.lean | 8 ++++---- Mathlib/Order/SymmDiff.lean | 2 +- Mathlib/RingTheory/Perfection.lean | 4 ++-- Mathlib/RingTheory/PicardGroup.lean | 2 +- Mathlib/Topology/Algebra/AffineSubspace.lean | 2 +- Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean | 7 ++++--- Mathlib/Topology/Algebra/ContinuousMonoidHom.lean | 8 ++++---- Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean | 2 +- Mathlib/Topology/Covering/Quotient.lean | 2 +- Mathlib/Topology/Instances/AddCircle/Defs.lean | 4 ++-- 50 files changed, 98 insertions(+), 85 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean index 2638c57300dbc9..927d687ccb9b31 100644 --- a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean @@ -409,7 +409,7 @@ theorem liftAddHom_symm_apply_apply [AddZeroClass M] [AddCommMonoid N] (F : (α theorem liftAddHom_singleAddHom [AddCommMonoid M] : (liftAddHom (α := α) (M := M) (N := α →₀ M)) (singleAddHom : α → M →+ α →₀ M) = AddMonoidHom.id _ := - liftAddHom.toEquiv.apply_eq_iff_eq_symm_apply.2 rfl + liftAddHom.toEquiv.eq_symm_apply.1 rfl @[simp] theorem sum_single [AddCommMonoid M] (f : α →₀ M) : f.sum single = f := diff --git a/Mathlib/Algebra/Category/Grp/Adjunctions.lean b/Mathlib/Algebra/Category/Grp/Adjunctions.lean index d2da151db06a44..4ee851883266c5 100644 --- a/Mathlib/Algebra/Category/Grp/Adjunctions.lean +++ b/Mathlib/Algebra/Category/Grp/Adjunctions.lean @@ -146,12 +146,12 @@ def abelianize : GrpCat.{u} ⥤ CommGrpCat.{u} where map_id := by intros ext : 1 - apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr + apply (Equiv.eq_symm_apply Abelianization.lift).mp rfl map_comp := by intros ext : 1 - apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr + apply (Equiv.eq_symm_apply Abelianization.lift).mp rfl /-- The abelianization-forgetful adjunction from `Group` to `CommGroup`. -/ diff --git a/Mathlib/Algebra/Group/Action/Basic.lean b/Mathlib/Algebra/Group/Action/Basic.lean index 7990462bc9f6b7..80f99ffbf45836 100644 --- a/Mathlib/Algebra/Group/Action/Basic.lean +++ b/Mathlib/Algebra/Group/Action/Basic.lean @@ -64,7 +64,7 @@ lemma smul_left_cancel_iff (g : α) {x y : β} : g • x = g • y ↔ x = y := @[to_additive] lemma smul_eq_iff_eq_inv_smul (g : α) {x y : β} : g • x = y ↔ x = g⁻¹ • y := - (MulAction.toPerm g).apply_eq_iff_eq_symm_apply + eq_inv_smul_iff.symm @[to_additive] lemma isCancelSMul_iff_eq_one_of_smul_eq : diff --git a/Mathlib/Algebra/Group/Equiv/Defs.lean b/Mathlib/Algebra/Group/Equiv/Defs.lean index a7dcd315164b64..b402c811f685be 100644 --- a/Mathlib/Algebra/Group/Equiv/Defs.lean +++ b/Mathlib/Algebra/Group/Equiv/Defs.lean @@ -336,10 +336,6 @@ theorem symm_comp_self (e : M ≃* N) : e.symm ∘ e = id := theorem self_comp_symm (e : M ≃* N) : e ∘ e.symm = id := funext e.apply_symm_apply -@[to_additive] -theorem apply_eq_iff_symm_apply (e : M ≃* N) {x : M} {y : N} : e x = y ↔ x = e.symm y := - e.toEquiv.apply_eq_iff_eq_symm_apply - @[to_additive] theorem symm_apply_eq (e : M ≃* N) {x y} : e.symm x = y ↔ x = e y := e.toEquiv.symm_apply_eq @@ -348,6 +344,10 @@ theorem symm_apply_eq (e : M ≃* N) {x y} : e.symm x = y ↔ x = e y := theorem eq_symm_apply (e : M ≃* N) {x y} : y = e.symm x ↔ e y = x := e.toEquiv.eq_symm_apply +@[to_additive (attr := deprecated eq_symm_apply (since := "2026-07-26"))] +theorem apply_eq_iff_symm_apply (e : M ≃* N) {x : M} {y : N} : e x = y ↔ x = e.symm y := + e.eq_symm_apply.symm + @[to_additive] theorem eq_comp_symm {α : Type*} (e : M ≃* N) (f : N → α) (g : M → α) : f = g ∘ e.symm ↔ f ∘ e = g := diff --git a/Mathlib/Algebra/Group/Units/Equiv.lean b/Mathlib/Algebra/Group/Units/Equiv.lean index bb64621692dd45..a3e6506332e9d3 100644 --- a/Mathlib/Algebra/Group/Units/Equiv.lean +++ b/Mathlib/Algebra/Group/Units/Equiv.lean @@ -28,7 +28,7 @@ def toUnits [Group G] : G ≃* Gˣ where @[to_additive (attr := simp)] lemma toUnits_val_apply {G : Type*} [Group G] (x : Gˣ) : toUnits (x : G) = x := by - simp_rw [MulEquiv.apply_eq_iff_symm_apply, toUnits_symm_apply] + simp_rw [← MulEquiv.eq_symm_apply, toUnits_symm_apply] namespace Units diff --git a/Mathlib/Algebra/Lie/Basic.lean b/Mathlib/Algebra/Lie/Basic.lean index 381271a197b485..73fd9763feb76f 100644 --- a/Mathlib/Algebra/Lie/Basic.lean +++ b/Mathlib/Algebra/Lie/Basic.lean @@ -986,16 +986,17 @@ theorem apply_symm_apply (e : M ≃ₗ⁅R,L⁆ N) : ∀ x, e (e.symm x) = x := theorem symm_apply_apply (e : M ≃ₗ⁅R,L⁆ N) : ∀ x, e.symm (e x) = x := e.toLinearEquiv.symm_apply_apply -theorem apply_eq_iff_eq_symm_apply {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : - e m = n ↔ m = e.symm n := - e.toEquiv.apply_eq_iff_eq_symm_apply - theorem symm_apply_eq {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : e.symm n = m ↔ n = e m := e.toEquiv.symm_apply_eq theorem eq_symm_apply {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : m = e.symm n ↔ e m = n := e.toEquiv.eq_symm_apply +@[deprecated eq_symm_apply (since := "2026-07-26")] +theorem apply_eq_iff_eq_symm_apply {m : M} {n : N} (e : M ≃ₗ⁅R,L⁆ N) : + e m = n ↔ m = e.symm n := + e.eq_symm_apply.symm + @[simp] theorem symm_symm (e : M ≃ₗ⁅R,L⁆ N) : e.symm.symm = e := rfl diff --git a/Mathlib/Algebra/Lie/Extension.lean b/Mathlib/Algebra/Lie/Extension.lean index 80fbb9a4f0df9e..b4f425933eec7a 100644 --- a/Mathlib/Algebra/Lie/Extension.lean +++ b/Mathlib/Algebra/Lie/Extension.lean @@ -223,7 +223,7 @@ def LieEquiv.ofCoboundary (c' : twoCocycle R L M) (x : oneCochain R L M) ofProd c (y.1, y.2 + x y.1) map_add' _ _ := by simp [← of_add]; abel map_smul' := by simp [← of_smul, smul_sub] - map_lie' := ((ofProd c').apply_eq_iff_eq_symm_apply).2 <| by simp [bracket_ofTwoCocycle, h]; abel + map_lie' := ((ofProd c').eq_symm_apply).1 <| by simp [bracket_ofTwoCocycle, h]; abel left_inv y := by simp right_inv z := by simp diff --git a/Mathlib/Algebra/Lie/Submodule.lean b/Mathlib/Algebra/Lie/Submodule.lean index c7d9b6bfbbec78..f204149fe9ae85 100644 --- a/Mathlib/Algebra/Lie/Submodule.lean +++ b/Mathlib/Algebra/Lie/Submodule.lean @@ -851,7 +851,7 @@ Submodules. -/ toFun := map e invFun := comap e left_inv := fun N ↦ by ext; simp - right_inv := fun N ↦ by ext; simp [e.apply_eq_iff_eq_symm_apply] + right_inv := fun N ↦ by ext; simp [← e.eq_symm_apply] map_rel_iff' := fun {_ _} ↦ Set.image_subset_image_iff e.injective end LieSubmodule diff --git a/Mathlib/Algebra/Module/TransferInstance.lean b/Mathlib/Algebra/Module/TransferInstance.lean index 39c5d5b392dde4..11c1737f4af533 100644 --- a/Mathlib/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Algebra/Module/TransferInstance.lean @@ -61,7 +61,7 @@ def linearEquiv (e : α ≃ β) [AddCommMonoid β] [Module R β] : map_smul' := fun r x => by apply e.symm.injective simp only [toFun_as_coe, RingHom.id_apply, EmbeddingLike.apply_eq_iff_eq] - exact Iff.mpr (apply_eq_iff_eq_symm_apply _) rfl } + exact Iff.mp (eq_symm_apply _) rfl } @[simp] lemma linearEquiv_apply (a : α) [AddCommMonoid β] [Module R β] : diff --git a/Mathlib/Algebra/Order/Hom/Monoid.lean b/Mathlib/Algebra/Order/Hom/Monoid.lean index e9156ad8f34a22..528fc48627f69b 100644 --- a/Mathlib/Algebra/Order/Hom/Monoid.lean +++ b/Mathlib/Algebra/Order/Hom/Monoid.lean @@ -686,10 +686,6 @@ theorem symm_comp_self (e : α ≃*o β) : e.symm ∘ e = id := theorem self_comp_symm (e : α ≃*o β) : e ∘ e.symm = id := funext e.apply_symm_apply -@[to_additive] -theorem apply_eq_iff_symm_apply (e : α ≃*o β) {x : α} {y : β} : e x = y ↔ x = e.symm y := - e.toEquiv.apply_eq_iff_eq_symm_apply - @[to_additive] theorem symm_apply_eq (e : α ≃*o β) {x y} : e.symm x = y ↔ x = e y := e.toEquiv.symm_apply_eq @@ -698,6 +694,10 @@ theorem symm_apply_eq (e : α ≃*o β) {x y} : e.symm x = y ↔ x = e y := theorem eq_symm_apply (e : α ≃*o β) {x y} : y = e.symm x ↔ e y = x := e.toEquiv.eq_symm_apply +@[to_additive (attr := deprecated eq_symm_apply (since := "2026-07-26"))] +theorem apply_eq_iff_symm_apply (e : α ≃*o β) {x : α} {y : β} : e x = y ↔ x = e.symm y := + e.eq_symm_apply.symm + @[to_additive] theorem eq_comp_symm (e : α ≃*o β) (f : β → α) (g : α → α) : f = g ∘ e.symm ↔ f ∘ e = g := diff --git a/Mathlib/Algebra/Torsor/Defs.lean b/Mathlib/Algebra/Torsor/Defs.lean index 2d01b44831703f..c10da7bb7b2c0f 100644 --- a/Mathlib/Algebra/Torsor/Defs.lean +++ b/Mathlib/Algebra/Torsor/Defs.lean @@ -281,7 +281,7 @@ theorem pointReflection_self (x : P) : pointReflection x x = x := vsub_vadd _ _ theorem pointReflection_involutive (x : P) : Involutive (pointReflection x : P → P) := fun y => - (Equiv.apply_eq_iff_eq_symm_apply _).2 <| by rw [pointReflection_symm] + (Equiv.eq_symm_apply _).1 <| by rw [pointReflection_symm] end Equiv diff --git a/Mathlib/Algebra/Tropical/Basic.lean b/Mathlib/Algebra/Tropical/Basic.lean index e79672ef90f364..0d56254ba8da1a 100644 --- a/Mathlib/Algebra/Tropical/Basic.lean +++ b/Mathlib/Algebra/Tropical/Basic.lean @@ -119,10 +119,10 @@ theorem tropEquiv_symm_coe_fn : (tropEquiv.symm : Tropical R → R) = untrop := rfl theorem trop_eq_iff_eq_untrop {x : R} {y} : trop x = y ↔ x = untrop y := - tropEquiv.apply_eq_iff_eq_symm_apply + tropEquiv.eq_symm_apply.symm theorem untrop_eq_iff_eq_trop {x} {y : R} : untrop x = y ↔ x = trop y := - tropEquiv.symm.apply_eq_iff_eq_symm_apply + tropEquiv.symm.eq_symm_apply.symm theorem injective_trop : Function.Injective (trop : R → Tropical R) := tropEquiv.injective diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 4daed92d919f28..17c4d7197502ca 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -319,8 +319,7 @@ lemma yonedaEquiv_naturality {X : SSet} {m n : SimplexCategory} lemma yonedaEquiv_symm_naturality_left {X : SSet} {m n : SimplexCategory} (f : m ⟶ n) (g : X.obj (Opposite.op n)) : stdSimplex.map f ≫ yonedaEquiv.symm g = yonedaEquiv.symm (X.map f.op g) := by - rw [← yonedaEquiv.apply_eq_iff_eq_symm_apply, ← yonedaEquiv_naturality, - yonedaEquiv.apply_symm_apply] + rw [yonedaEquiv.eq_symm_apply, ← yonedaEquiv_naturality, yonedaEquiv.apply_symm_apply] namespace Subcomplex diff --git a/Mathlib/Analysis/Real/Sqrt.lean b/Mathlib/Analysis/Real/Sqrt.lean index ebd06fcb895a4b..e111a1394cab20 100644 --- a/Mathlib/Analysis/Real/Sqrt.lean +++ b/Mathlib/Analysis/Real/Sqrt.lean @@ -58,7 +58,7 @@ lemma sqrt_le_sqrt : sqrt x ≤ sqrt y ↔ x ≤ y := sqrt.le_iff_le lemma sqrt_lt_sqrt : sqrt x < sqrt y ↔ x < y := sqrt.lt_iff_lt -lemma sqrt_eq_iff_eq_sq : sqrt x = y ↔ x = y ^ 2 := sqrt.toEquiv.apply_eq_iff_eq_symm_apply +lemma sqrt_eq_iff_eq_sq : sqrt x = y ↔ x = y ^ 2 := sqrt.toEquiv.eq_symm_apply.symm lemma sqrt_le_iff_le_sq : sqrt x ≤ y ↔ x ≤ y ^ 2 := sqrt.to_galoisConnection _ _ diff --git a/Mathlib/CategoryTheory/FintypeCat.lean b/Mathlib/CategoryTheory/FintypeCat.lean index 4fa0b1cc0a68c6..012767958abd7f 100644 --- a/Mathlib/CategoryTheory/FintypeCat.lean +++ b/Mathlib/CategoryTheory/FintypeCat.lean @@ -277,8 +277,7 @@ lemma uSwitchEquiv_naturality {X Y : FintypeCat.{u}} (f : X ⟶ Y) lemma uSwitchEquiv_symm_naturality {X Y : FintypeCat.{u}} (f : X ⟶ Y) (x : X) : uSwitch.map f (X.uSwitchEquiv.symm x) = Y.uSwitchEquiv.symm (f x) := by - rw [← Equiv.apply_eq_iff_eq_symm_apply, ← uSwitchEquiv_naturality f, - Equiv.apply_symm_apply] + rw [Equiv.eq_symm_apply, ← uSwitchEquiv_naturality f, Equiv.apply_symm_apply] lemma uSwitch_map_uSwitch_map {X Y : FintypeCat.{u}} (f : X ⟶ Y) : uSwitch.map (uSwitch.map f) = diff --git a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean index a799508ba79409..84b92f63fa31bf 100644 --- a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean +++ b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean @@ -301,7 +301,7 @@ def biproduct.reindex {β γ : Type} [Finite β] (ε : β ≃ γ) ext g g' by_cases h : g' = g <;> simp [Preadditive.sum_comp, biproduct.lift_desc, biproduct.ι_π, comp_dite, - Equiv.apply_eq_iff_eq_symm_apply, h] + ← Equiv.eq_symm_apply, h] set_option backward.isDefEq.respectTransparency.types false in set_option backward.defeqAttrib.useBackward true in diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index 3768ec77d9fbff..f3d3129244c99f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -146,7 +146,7 @@ instance instDecidableComapAdj (f : V → W) (G : SimpleGraph W) [DecidableRel G lemma comap_symm (G : SimpleGraph V) (e : V ≃ W) : G.comap e.symm.toEmbedding = G.map e.toEmbedding := by - ext; simp only [Equiv.apply_eq_iff_eq_symm_apply, comap_adj, map_adj, Equiv.toEmbedding_apply, + ext; simp only [← Equiv.eq_symm_apply, comap_adj, map_adj, Equiv.toEmbedding_apply, exists_eq_right_right, exists_eq_right] lemma map_symm (G : SimpleGraph W) (e : V ≃ W) : diff --git a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean index 6799d9a54b00d0..a8b7f3675c729f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean @@ -666,7 +666,7 @@ theorem map_sup (f : G →g G') (H₁ H₂ : G.Subgraph) : (H₁ ⊔ H₂).map f ext <;> simp [Set.image_union, map_adj, sup_adj, Relation.Map, or_and_right, exists_or] @[simp] lemma map_iso_top {H : SimpleGraph W} (e : G ≃g H) : Subgraph.map e.toHom ⊤ = ⊤ := by - ext <;> simp [Relation.Map, e.apply_eq_iff_eq_symm_apply, ← e.map_rel_iff] + ext <;> simp [Relation.Map, ← e.eq_symm_apply, ← e.map_rel_iff] @[simp] lemma edgeSet_map (f : G →g G') (H : G.Subgraph) : (H.map f).edgeSet = Sym2.map f '' H.edgeSet := Sym2.fromRel_relationMap .. diff --git a/Mathlib/Data/DFinsupp/BigOperators.lean b/Mathlib/Data/DFinsupp/BigOperators.lean index d367aacfd43097..3563ccd629421e 100644 --- a/Mathlib/Data/DFinsupp/BigOperators.lean +++ b/Mathlib/Data/DFinsupp/BigOperators.lean @@ -386,7 +386,7 @@ def liftAddHom [∀ i, AddZeroClass (β i)] [AddCommMonoid γ] : /-- The `DFinsupp` version of `Finsupp.liftAddHom_singleAddHom` -/ theorem liftAddHom_singleAddHom [∀ i, AddCommMonoid (β i)] : liftAddHom (singleAddHom β) = AddMonoidHom.id (Π₀ i, β i) := - liftAddHom.toEquiv.apply_eq_iff_eq_symm_apply.2 rfl + liftAddHom.toEquiv.eq_symm_apply.1 rfl /-- The `DFinsupp` version of `Finsupp.liftAddHom_apply_single` -/ theorem liftAddHom_apply_single [∀ i, AddZeroClass (β i)] [AddCommMonoid γ] (f : ∀ i, β i →+ γ) diff --git a/Mathlib/Data/Fin/Tuple/Sort.lean b/Mathlib/Data/Fin/Tuple/Sort.lean index 72c8d02bf9c1e2..a622f342828f3f 100644 --- a/Mathlib/Data/Fin/Tuple/Sort.lean +++ b/Mathlib/Data/Fin/Tuple/Sort.lean @@ -153,7 +153,7 @@ theorem eq_sort_iff' : σ = sort f ↔ StrictMono (σ.trans <| graphEquiv₁ f) exact (graphEquiv₂ f).strictMono · have := Subsingleton.elim (graphEquiv₂ f) (h.orderIsoOfSurjective _ <| Equiv.surjective _) ext1 x - exact (graphEquiv₁ f).apply_eq_iff_eq_symm_apply.1 (DFunLike.congr_fun this x).symm + exact (graphEquiv₁ f).eq_symm_apply.2 (DFunLike.congr_fun this x).symm /-- A permutation `σ` equals `sort f` if and only if `f ∘ σ` is monotone and whenever `i < j` and `f (σ i) = f (σ j)`, then `σ i < σ j`. This means that `sort f` is the lexicographically diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 47bd35a3a4940a..777ee5ee3df887 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -173,7 +173,7 @@ theorem equivMapDomain_single (f : α ≃ β) (a : α) (b : M) : equivMapDomain f (single a b) = single (f a) b := by classical ext x - simp only [single_apply, Equiv.apply_eq_iff_eq_symm_apply, equivMapDomain_apply] + simp only [single_apply, ← Equiv.eq_symm_apply, equivMapDomain_apply] @[simp] theorem equivMapDomain_zero {f : α ≃ β} : equivMapDomain f (0 : α →₀ M) = (0 : β →₀ M) := by diff --git a/Mathlib/Data/Finsupp/Multiset.lean b/Mathlib/Data/Finsupp/Multiset.lean index 99989ae82e98a6..deb70f5487adb9 100644 --- a/Mathlib/Data/Finsupp/Multiset.lean +++ b/Mathlib/Data/Finsupp/Multiset.lean @@ -166,7 +166,7 @@ theorem toFinsupp_toMultiset (s : Multiset α) : Finsupp.toMultiset (toFinsupp s theorem toFinsupp_eq_iff {s : Multiset α} {f : α →₀ ℕ} : toFinsupp s = f ↔ s = Finsupp.toMultiset f := - Multiset.toFinsupp.apply_eq_iff_symm_apply + Multiset.toFinsupp.eq_symm_apply.symm theorem toFinsupp_union (s t : Multiset α) : toFinsupp (s ∪ t) = toFinsupp s ⊔ toFinsupp t := by ext diff --git a/Mathlib/Data/Finsupp/Option.lean b/Mathlib/Data/Finsupp/Option.lean index 3ac4384db4ae11..e62a92d206769a 100644 --- a/Mathlib/Data/Finsupp/Option.lean +++ b/Mathlib/Data/Finsupp/Option.lean @@ -187,7 +187,7 @@ theorem optionElim_ne_zero_iff (y : M) (f : α →₀ M) : theorem eq_option_embedding_update_none_iff {n : Option α →₀ M} {m : α →₀ M} {i : M} : n = (embDomain Embedding.some m).update none i ↔ n none = i ∧ n.some = m := - (optionEquiv.apply_eq_iff_eq_symm_apply (y := (_, _))).symm.trans Prod.ext_iff + (optionEquiv.eq_symm_apply (x := (_, _))).trans Prod.ext_iff end Zero diff --git a/Mathlib/Data/Matrix/PEquiv.lean b/Mathlib/Data/Matrix/PEquiv.lean index dbf7e898046de6..7ccbc470564996 100644 --- a/Mathlib/Data/Matrix/PEquiv.lean +++ b/Mathlib/Data/Matrix/PEquiv.lean @@ -101,7 +101,7 @@ theorem transpose_toMatrix_toPEquiv_apply [DecidableEq m] [DecidableEq n] [Zero α] [One α] (f : m ≃ n) (j) : f.toPEquiv.toMatrixᵀ j = Pi.single (f.symm j) (1 : α) := by ext - simp [toMatrix_apply, Pi.single_apply, eq_comm, ← Equiv.apply_eq_iff_eq_symm_apply] + simp [toMatrix_apply, Pi.single_apply, eq_comm, Equiv.eq_symm_apply] theorem toMatrix_toPEquiv_mul [Fintype m] [DecidableEq m] [NonAssocSemiring α] (f : l ≃ m) (M : Matrix m n α) : @@ -127,7 +127,7 @@ lemma vecMul_toMatrix_toPEquiv [DecidableEq n] [Fintype m] a ᵥ* σ.toPEquiv.toMatrix = a ∘ σ.symm := by classical ext j - simp [toMatrix, σ.apply_eq_iff_eq_symm_apply, vecMul, dotProduct] + simp [toMatrix, ← σ.eq_symm_apply, vecMul, dotProduct] theorem toMatrix_trans [Fintype m] [DecidableEq m] [DecidableEq n] [NonAssocSemiring α] (f : l ≃. m) (g : m ≃. n) : ((f.trans g).toMatrix : Matrix l n α) = f.toMatrix * g.toMatrix := by diff --git a/Mathlib/Data/Opposite.lean b/Mathlib/Data/Opposite.lean index 7c80f4c9e214e7..543f949bfd318b 100644 --- a/Mathlib/Data/Opposite.lean +++ b/Mathlib/Data/Opposite.lean @@ -93,10 +93,10 @@ theorem equivToOpposite_symm_coe : (equivToOpposite.symm : αᵒᵖ → α) = un rfl theorem op_eq_iff_eq_unop {x : α} {y} : op x = y ↔ x = unop y := - equivToOpposite.apply_eq_iff_eq_symm_apply + equivToOpposite.eq_symm_apply.symm theorem unop_eq_iff_eq_op {x} {y : α} : unop x = y ↔ x = op y := - equivToOpposite.symm.apply_eq_iff_eq_symm_apply + equivToOpposite.symm.eq_symm_apply.symm instance [Inhabited α] : Inhabited αᵒᵖ := ⟨op default⟩ diff --git a/Mathlib/Data/ZMod/QuotientGroup.lean b/Mathlib/Data/ZMod/QuotientGroup.lean index 9501f74a766c66..8bc4da37e8cfef 100644 --- a/Mathlib/Data/ZMod/QuotientGroup.lean +++ b/Mathlib/Data/ZMod/QuotientGroup.lean @@ -194,7 +194,7 @@ lemma quotientEquivSigmaZMod_symm_apply (q : orbitRel.Quotient (zpowers g) (G lemma quotientEquivSigmaZMod_apply (q : orbitRel.Quotient (zpowers g) (G ⧸ H)) (k : ℤ) : quotientEquivSigmaZMod H g (g ^ k • q.out) = ⟨q, k⟩ := by - rw [apply_eq_iff_eq_symm_apply, quotientEquivSigmaZMod_symm_apply, ZMod.coe_intCast, + rw [← eq_symm_apply, quotientEquivSigmaZMod_symm_apply, ZMod.coe_intCast, zpow_smul_mod_minimalPeriod] set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean index ff6b43f8c4c4f2..93bb362c78fc35 100644 --- a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean +++ b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean @@ -177,7 +177,7 @@ lemma galAction_isPretransitive [Fact ((p.map (algebraMap F E)).Splits)] (hp : I have hx := minpoly.eq_of_irreducible hp (mem_rootSet.mp ((rootsEquivRoots p E).symm x).2).2 have hy := minpoly.eq_of_irreducible hp (mem_rootSet.mp ((rootsEquivRoots p E).symm y).2).2 obtain ⟨g, hg⟩ := (Normal.minpoly_eq_iff_mem_orbit p.SplittingField).mp (hy.symm.trans hx) - exact ⟨g, (rootsEquivRoots p E).apply_eq_iff_eq_symm_apply.mpr (Subtype.ext hg)⟩ + exact ⟨g, (rootsEquivRoots p E).eq_symm_apply.mp (Subtype.ext hg)⟩ variable {p E} diff --git a/Mathlib/GroupTheory/Complement.lean b/Mathlib/GroupTheory/Complement.lean index e349da7968f410..b637ad28cc68ea 100644 --- a/Mathlib/GroupTheory/Complement.lean +++ b/Mathlib/GroupTheory/Complement.lean @@ -435,7 +435,7 @@ theorem equiv_mul_left_of_mem {h g : G} (hh : h ∈ H) : set_option backward.isDefEq.respectTransparency false in theorem equiv_one (hs1 : 1 ∈ S) (ht1 : 1 ∈ T) : hST.equiv 1 = (⟨1, hs1⟩, ⟨1, ht1⟩) := by - rw [Equiv.apply_eq_iff_eq_symm_apply]; simp [equiv] + rw [← Equiv.eq_symm_apply]; simp [equiv] theorem equiv_fst_eq_self_iff_mem {g : G} (h1 : 1 ∈ T) : ((hST.equiv g).fst : G) = g ↔ g ∈ S := by @@ -486,7 +486,7 @@ theorem quotientGroupMk_leftQuotientEquiv (hS : IsComplement S H) (q : G ⧸ H) theorem leftQuotientEquiv_apply {f : G ⧸ H → G} (hf : ∀ q, (f q : G ⧸ H) = q) (q : G ⧸ H) : (leftQuotientEquiv (isComplement_range_left hf) q : G) = f q := by refine (Subtype.ext_iff.mp ?_).trans (Subtype.coe_mk (f q) ⟨q, rfl⟩) - exact (leftQuotientEquiv (isComplement_range_left hf)).apply_eq_iff_eq_symm_apply.mpr (hf q).symm + exact (leftQuotientEquiv (isComplement_range_left hf)).eq_symm_apply.mp (hf q).symm /-- A left transversal can be viewed as a function mapping each element of the group to the chosen representative from that left coset. -/ @@ -530,7 +530,7 @@ theorem rightQuotientEquiv_apply {f : Quotient (QuotientGroup.rightRel H) → G} (hf : ∀ q, Quotient.mk'' (f q) = q) (q : Quotient (QuotientGroup.rightRel H)) : (rightQuotientEquiv (isComplement_range_right hf) q : G) = f q := by refine (Subtype.ext_iff.mp ?_).trans (Subtype.coe_mk (f q) ⟨q, rfl⟩) - exact (rightQuotientEquiv (isComplement_range_right hf)).apply_eq_iff_eq_symm_apply.2 (hf q).symm + exact (rightQuotientEquiv (isComplement_range_right hf)).eq_symm_apply.1 (hf q).symm /-- A right transversal can be viewed as a function mapping each element of the group to the chosen representative from that right coset. -/ diff --git a/Mathlib/GroupTheory/CoprodI.lean b/Mathlib/GroupTheory/CoprodI.lean index 1419429b37cdd4..076e3760fcdeb3 100644 --- a/Mathlib/GroupTheory/CoprodI.lean +++ b/Mathlib/GroupTheory/CoprodI.lean @@ -434,7 +434,7 @@ theorem equivPair_symm (i) (p : Pair M i) : (equivPair i).symm p = rcons p := theorem equivPair_eq_of_fstIdx_ne {i} {w : Word M} (h : fstIdx w ≠ some i) : equivPair i w = ⟨1, w, h⟩ := - (equivPair i).apply_eq_iff_eq_symm_apply.mpr <| Eq.symm (dif_pos rfl) + (equivPair i).eq_symm_apply.mp <| Eq.symm (dif_pos rfl) theorem mem_equivPair_tail_iff {i j : ι} {w : Word M} (m : M i) : (⟨i, m⟩ ∈ (equivPair j w).tail.toList) ↔ ⟨i, m⟩ ∈ w.toList.tail diff --git a/Mathlib/GroupTheory/Perm/ConjAct.lean b/Mathlib/GroupTheory/Perm/ConjAct.lean index c6cf130f93d57a..c4ea9b5f048e47 100644 --- a/Mathlib/GroupTheory/Perm/ConjAct.lean +++ b/Mathlib/GroupTheory/Perm/ConjAct.lean @@ -37,7 +37,7 @@ theorem mem_conj_support (k : ConjAct (Perm α)) (g : Perm α) (a : α) : a ∈ (k • g).support ↔ ConjAct.ofConjAct k⁻¹ a ∈ g.support := by simp only [mem_support, ConjAct.smul_def, not_iff_not, coe_mul, Function.comp_apply, ConjAct.ofConjAct_inv] - apply Equiv.apply_eq_iff_eq_symm_apply + exact eq_inv_iff_eq.symm theorem support_conj_eq_smul_support (k : ConjAct (Perm α)) (g : Equiv.Perm α) : (k • g).support = k.ofConjAct • g.support := by diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean index ecfbea3c309f8f..f9c2964c6f1875 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean @@ -164,7 +164,7 @@ def symm (e : P₁ ≃ᵃ[k] P₂) : P₂ ≃ᵃ[k] P₁ where toEquiv := e.toEquiv.symm linear := e.linear.symm map_vadd' p v := - e.toEquiv.symm.apply_eq_iff_eq_symm_apply.2 <| by + e.toEquiv.symm.eq_symm_apply.1 <| by rw [Equiv.symm_symm, e.map_vadd' ((Equiv.symm e.toEquiv) p) ((LinearEquiv.symm e.linear) v), LinearEquiv.apply_symm_apply, Equiv.apply_symm_apply] @@ -221,8 +221,15 @@ theorem apply_symm_apply (e : P₁ ≃ᵃ[k] P₂) (p : P₂) : e (e.symm p) = p theorem symm_apply_apply (e : P₁ ≃ᵃ[k] P₂) (p : P₁) : e.symm (e p) = p := e.toEquiv.symm_apply_apply p +theorem symm_apply_eq (e : P₁ ≃ᵃ[k] P₂) {p₁ p₂} : e.symm p₁ = p₂ ↔ p₁ = e p₂ := + e.toEquiv.symm_apply_eq + +theorem eq_symm_apply (e : P₁ ≃ᵃ[k] P₂) {p₁ p₂} : p₂ = e.symm p₁ ↔ e p₂ = p₁ := + e.toEquiv.eq_symm_apply + +@[deprecated eq_symm_apply (since := "2026-07-26")] theorem apply_eq_iff_eq_symm_apply (e : P₁ ≃ᵃ[k] P₂) {p₁ p₂} : e p₁ = p₂ ↔ p₁ = e.symm p₂ := - e.toEquiv.apply_eq_iff_eq_symm_apply + e.eq_symm_apply.symm theorem apply_eq_iff_eq (e : P₁ ≃ᵃ[k] P₂) {p₁ p₂ : P₁} : e p₁ = e p₂ ↔ p₁ = p₂ := by simp diff --git a/Mathlib/LinearAlgebra/Matrix/Transvection.lean b/Mathlib/LinearAlgebra/Matrix/Transvection.lean index ea69c434b9e2ca..08f4f013afe3e8 100644 --- a/Mathlib/LinearAlgebra/Matrix/Transvection.lean +++ b/Mathlib/LinearAlgebra/Matrix/Transvection.lean @@ -298,7 +298,7 @@ theorem toMatrix_reindexEquiv (e : n ≃ p) (t : TransvectionStruct n R) : ext a b simp only [reindexEquiv, transvection, toMatrix_mk] by_cases ha : e t_i = a <;> by_cases hb : e t_j = b <;> by_cases hab : a = b <;> - simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, single] + simp [ha, hb, hab, e.eq_symm_apply, single] theorem toMatrix_reindexEquiv_prod (e : n ≃ p) (L : List (TransvectionStruct n R)) : (L.map (toMatrix ∘ reindexEquiv e)).prod = reindexAlgEquiv R _ e (L.map toMatrix).prod := by diff --git a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean index 07943192bd8f7a..4fbd614497eb5f 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean @@ -467,7 +467,7 @@ theorem distribBaseChange_tmul (n : N) (q : Q) (a : A) : theorem distribBaseChange_symm_tmul (n : N) (q : Q) (a b : A) : (distribBaseChange R A N Q).symm ((a ⊗ₜ n) ⊗ₜ (b ⊗ₜ q)) = (a * b) ⊗ₜ (n ⊗ₜ q) := by - apply ((distribBaseChange R A N Q).apply_eq_iff_symm_apply.mp ?_).symm + apply ((distribBaseChange R A N Q).eq_symm_apply.mpr ?_).symm rw [tmul_eq_smul_one_tmul b, ← smul_tmul, smul_tmul', mul_comm] simp diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index ddf2c7599e4a50..25b21d2024a9ec 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -46,7 +46,7 @@ simproc_decl eqComm (_ = _) := fun e => do -- These theorems would cause an infinite loop: ``eq_comm, ``Bool.not_eq_eq_eq_not, `inv_eq_iff_eq_inv, `eq_inv_mul_iff_mul_eq, `eq_mul_inv_iff_mul_eq, `neg_eq_iff_eq_neg, `Function.Involutive.eq_iff, - `vadd_eq_iff_eq_neg_vadd, `Equiv.apply_eq_iff_eq_symm_apply, + `vadd_eq_iff_eq_neg_vadd, `Equiv.eq_symm_apply, -- These theorems aren't commute-resistant (they turn an equality into a non-equality in a -- non-commutative way.) ``beq_iff_eq, ``funext_iff, ``eq_iff_iff, `Prod.swap_eq_iff_eq_swap, ``left_eq_dite_iff, diff --git a/Mathlib/Logic/Equiv/Defs.lean b/Mathlib/Logic/Equiv/Defs.lean index 54fb7aee272d45..63063f27c56b65 100644 --- a/Mathlib/Logic/Equiv/Defs.lean +++ b/Mathlib/Logic/Equiv/Defs.lean @@ -281,8 +281,6 @@ theorem symm_symm_apply (f : α ≃ β) (b : α) : f.symm.symm b = f b := rfl theorem apply_eq_iff_eq (f : α ≃ β) {x y : α} : f x = f y ↔ x = y := EquivLike.apply_eq_iff_eq f -theorem apply_eq_iff_eq_symm_apply {x : α} {y : β} (f : α ≃ β) : f x = y ↔ x = f.symm y := by grind - @[simp] theorem cast_apply {α β} (h : α = β) (x : α) : Equiv.cast h x = cast h x := rfl theorem cast_symm {α β} (h : α = β) : Equiv.cast h.symm = (Equiv.cast h).symm := rfl @@ -300,6 +298,10 @@ theorem symm_apply_eq {α β} (e : α ≃ β) {x y} : e.symm x = y ↔ x = e y : theorem eq_symm_apply {α β} (e : α ≃ β) {x y} : y = e.symm x ↔ e y = x := by grind +@[deprecated eq_symm_apply (since := "2026-07-26")] +theorem apply_eq_iff_eq_symm_apply {x : α} {y : β} (f : α ≃ β) : f x = y ↔ x = f.symm y := + f.eq_symm_apply.symm + @[simp, grind =] theorem symm_symm (e : α ≃ β) : e.symm.symm = e := rfl theorem symm_bijective : Function.Bijective (Equiv.symm : (α ≃ β) → β ≃ α) := diff --git a/Mathlib/Logic/Equiv/Fin/Basic.lean b/Mathlib/Logic/Equiv/Fin/Basic.lean index e6ba761f91e688..f91c461d1443e6 100644 --- a/Mathlib/Logic/Equiv/Fin/Basic.lean +++ b/Mathlib/Logic/Equiv/Fin/Basic.lean @@ -92,11 +92,11 @@ theorem finSuccEquiv'_symm_some (i : Fin (n + 1)) (j : Fin n) : @[simp] theorem finSuccEquiv'_eq_some {i j : Fin (n + 1)} {k : Fin n} : finSuccEquiv' i j = k ↔ j = i.succAbove k := - (finSuccEquiv' i).apply_eq_iff_eq_symm_apply + (finSuccEquiv' i).eq_symm_apply.symm @[simp] theorem finSuccEquiv'_eq_none {i j : Fin (n + 1)} : finSuccEquiv' i j = none ↔ i = j := - (finSuccEquiv' i).apply_eq_iff_eq_symm_apply.trans eq_comm + (finSuccEquiv' i).eq_symm_apply.symm.trans eq_comm theorem finSuccEquiv'_symm_some_below {i : Fin (n + 1)} {m : Fin n} (h : Fin.castSucc m < i) : (finSuccEquiv' i).symm (some m) = Fin.castSucc m := @@ -142,11 +142,11 @@ theorem finSuccEquiv_symm_some (m : Fin n) : (finSuccEquiv n).symm (some m) = m. @[simp] theorem finSuccEquiv_eq_some {i : Fin (n + 1)} {j : Fin n} : finSuccEquiv n i = j ↔ i = j.succ := - (finSuccEquiv n).apply_eq_iff_eq_symm_apply + (finSuccEquiv n).eq_symm_apply.symm @[simp] theorem finSuccEquiv_eq_none {i : Fin (n + 1)} : finSuccEquiv n i = none ↔ i = 0 := - (finSuccEquiv n).apply_eq_iff_eq_symm_apply + (finSuccEquiv n).eq_symm_apply.symm /-- The equiv version of `Fin.predAbove_zero`. -/ theorem finSuccEquiv'_zero : finSuccEquiv' (0 : Fin (n + 1)) = finSuccEquiv n := diff --git a/Mathlib/Logic/Equiv/Option.lean b/Mathlib/Logic/Equiv/Option.lean index af0cade210219a..613304a927d412 100644 --- a/Mathlib/Logic/Equiv/Option.lean +++ b/Mathlib/Logic/Equiv/Option.lean @@ -163,7 +163,7 @@ def optionSubtype [DecidableEq β] (x : β) : get _ (ne_none_iff_isSome.1 (((EquivLike.injective _).ne_iff' - ((apply_eq_iff_eq_symm_apply _).1 e.property).symm).2 b.property)), + ((eq_symm_apply _).2 e.property).symm).2 b.property)), left_inv := fun a => by rw [← some_inj, some_get] exact symm_apply_apply (e : Option α ≃ β) a, diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index 7668c425ab9e4e..93b898d2de8102 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -276,12 +276,12 @@ theorem insert_symm_apply_inr {α} {s : Set.{u} α} [DecidablePred (· ∈ s)] { @[simp] theorem insert_apply_left {α} {s : Set.{u} α} [DecidablePred (· ∈ s)] {a : α} (H : a ∉ s) : Equiv.Set.insert H ⟨a, Or.inl rfl⟩ = Sum.inr PUnit.unit := - (Equiv.Set.insert H).apply_eq_iff_eq_symm_apply.2 rfl + (Equiv.Set.insert H).eq_symm_apply.1 rfl @[simp] theorem insert_apply_right {α} {s : Set.{u} α} [DecidablePred (· ∈ s)] {a : α} (H : a ∉ s) (b : s) : Equiv.Set.insert H ⟨b, Or.inr b.2⟩ = Sum.inl b := - (Equiv.Set.insert H).apply_eq_iff_eq_symm_apply.2 rfl + (Equiv.Set.insert H).eq_symm_apply.1 rfl /-- If `s : Set α` is a set with decidable membership, then `s ⊕ sᶜ` is equivalent to `α`. diff --git a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean index 9e37588ae15ce3..e9435de3e30a37 100644 --- a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean +++ b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean @@ -479,7 +479,7 @@ def fundSystem : Fin (rank K) → (𝓞 K)ˣ := theorem fundSystem_mk (i : Fin (rank K)) : Additive.ofMul (QuotientGroup.mk (fundSystem K i)) = (basisModTorsion K i) := by - simp_rw [fundSystem, Equiv.apply_eq_iff_eq_symm_apply, Additive.ofMul_symm_eq, Quotient.out_eq'] + simp_rw [fundSystem, ← Equiv.eq_symm_apply, Additive.ofMul_symm_eq, Quotient.out_eq'] theorem logEmbedding_fundSystem (i : Fin (rank K)) : logEmbedding K (Additive.ofMul (fundSystem K i)) = basisUnitLattice K i := by diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index da7e91b478e0b7..c67d0ab9562107 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -844,12 +844,16 @@ theorem symm_apply_apply (e : α ≃o β) (x : α) : e.symm (e x) = x := theorem symm_refl (α : Type*) [LE α] : (refl α).symm = refl α := rfl -theorem apply_eq_iff_eq_symm_apply (e : α ≃o β) (x : α) (y : β) : e x = y ↔ x = e.symm y := - e.toEquiv.apply_eq_iff_eq_symm_apply - theorem symm_apply_eq (e : α ≃o β) {x : α} {y : β} : e.symm y = x ↔ y = e x := e.toEquiv.symm_apply_eq +theorem eq_symm_apply (e : α ≃o β) {x : α} {y : β} : x = e.symm y ↔ e x = y := + e.toEquiv.eq_symm_apply + +@[deprecated eq_symm_apply (since := "2026-07-26")] +theorem apply_eq_iff_eq_symm_apply (e : α ≃o β) (x : α) (y : β) : e x = y ↔ x = e.symm y := + e.eq_symm_apply.symm + @[simp] theorem symm_symm (e : α ≃o β) : e.symm.symm = e := rfl diff --git a/Mathlib/Order/RelIso/Basic.lean b/Mathlib/Order/RelIso/Basic.lean index dfa611212be01c..8a0e924fa22292 100644 --- a/Mathlib/Order/RelIso/Basic.lean +++ b/Mathlib/Order/RelIso/Basic.lean @@ -662,13 +662,13 @@ lemma symm_symm_apply (f : r ≃r s) (b : α) : f.symm.symm b = f b := rfl lemma apply_eq_iff_eq (f : r ≃r s) {x y : α} : f x = f y ↔ x = y := EquivLike.apply_eq_iff_eq f -lemma apply_eq_iff_eq_symm_apply {x : α} {y : β} (f : r ≃r s) : f x = y ↔ x = f.symm y := by - conv_lhs => rw [← apply_symm_apply f y] - rw [apply_eq_iff_eq] - lemma symm_apply_eq (e : r ≃r s) {x y} : e.symm x = y ↔ x = e y := e.toEquiv.symm_apply_eq lemma eq_symm_apply (e : r ≃r s) {x y} : y = e.symm x ↔ e y = x := e.toEquiv.eq_symm_apply +@[deprecated eq_symm_apply (since := "2026-07-26")] +lemma apply_eq_iff_eq_symm_apply {x : α} {y : β} (f : r ≃r s) : f x = y ↔ x = f.symm y := + f.eq_symm_apply.symm + @[simp] lemma symm_symm (e : r ≃r s) : e.symm.symm = e := rfl lemma symm_bijective : Bijective (.symm : (r ≃r s) → s ≃r r) := diff --git a/Mathlib/Order/SymmDiff.lean b/Mathlib/Order/SymmDiff.lean index 63d6ff5603f02b..bc60ab8f1087f4 100644 --- a/Mathlib/Order/SymmDiff.lean +++ b/Mathlib/Order/SymmDiff.lean @@ -473,7 +473,7 @@ protected theorem Disjoint.symmDiff_right (ha : Disjoint a b) (hb : Disjoint a c theorem symmDiff_eq_iff_sdiff_eq (ha : a ≤ c) : a ∆ b = c ↔ c \ a = b := by rw [← symmDiff_of_le ha] - exact ((symmDiff_right_involutive a).toPerm _).apply_eq_iff_eq_symm_apply.trans eq_comm + exact ((symmDiff_right_involutive a).toPerm _).eq_symm_apply.symm.trans eq_comm end GeneralizedBooleanAlgebra diff --git a/Mathlib/RingTheory/Perfection.lean b/Mathlib/RingTheory/Perfection.lean index a37d0ffd9d0d77..91e6fa8901bfd9 100644 --- a/Mathlib/RingTheory/Perfection.lean +++ b/Mathlib/RingTheory/Perfection.lean @@ -423,7 +423,7 @@ variable (p R P) /-- The canonical perfection map from the perfection of a ring. -/ theorem of : PerfectionMap p (Perfection.coeff R p 0) := - mk' (RingEquiv.refl _) <| (Equiv.apply_eq_iff_eq_symm_apply _).2 rfl + mk' (RingEquiv.refl _) <| (Equiv.eq_symm_apply _).1 rfl /-- For a perfect ring, it itself is the perfection. -/ theorem id [PerfectRing R p] : PerfectionMap p (RingHom.id R) := @@ -478,7 +478,7 @@ noncomputable def lift [PerfectRing R p] (S : Type u₂) [CommSemiring S] [CharP right_inv f := by exact RingHom.ext fun x => m.equiv.injective <| (m.equiv.apply_symm_apply _).trans <| show Perfection.lift p R S (π.comp f) x = RingHom.comp (↑m.equiv) f x from - RingHom.ext_iff.1 (by rw [Equiv.apply_eq_iff_eq_symm_apply]; rfl) _ + RingHom.ext_iff.1 (by rw [← Equiv.eq_symm_apply]; rfl) _ variable {R p} diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 3c5c3e09051c97..0638f4bb3d9bf6 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -475,7 +475,7 @@ variable {R M N} theorem mk_eq_iff {N : Pic R} : Pic.mk R M = N ↔ Nonempty (M ≃ₗ[R] N) where mp := (· ▸ ⟨(mk.linearEquiv R M).symm⟩) - mpr := fun ⟨e⟩ ↦ ((equivShrink _).apply_eq_iff_eq_symm_apply).mpr <| + mpr := fun ⟨e⟩ ↦ ((equivShrink _).eq_symm_apply).mp <| Units.ext <| Quotient.mk_eq_iff_out.mpr ⟨(Finite.reprEquivₛ R M ≪≫ₗ e).toModuleIsoₛ⟩ theorem mk_eq_self {M : Pic R} : Pic.mk R M = M := mk_eq_iff.mpr ⟨.refl ..⟩ diff --git a/Mathlib/Topology/Algebra/AffineSubspace.lean b/Mathlib/Topology/Algebra/AffineSubspace.lean index 13729236824ec7..ce8ed6fca359b3 100644 --- a/Mathlib/Topology/Algebra/AffineSubspace.lean +++ b/Mathlib/Topology/Algebra/AffineSubspace.lean @@ -71,7 +71,7 @@ noncomputable def affineSubspaceMap (e : P ≃ᴬ[R] Q) (s : AffineSubspace R P) (e.continuous.comp continuous_subtype_val).congr fun _ => rfl continuous_invFun := by simpa [Topology.IsEmbedding.subtypeVal.continuous_iff] using! (e.continuous_invFun.comp continuous_subtype_val).congr fun x ↦ - (e.apply_eq_iff_eq_symm_apply.mp + (e.eq_symm_apply.mpr (AffineEquiv.affineSubspaceMap_apply_symm_apply e.toAffineEquiv s x)).symm } @[simp] diff --git a/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean b/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean index e0f4fb8983310f..ada1624ab1fdab 100644 --- a/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean +++ b/Mathlib/Topology/Algebra/ContinuousAffineEquiv.lean @@ -199,9 +199,6 @@ theorem apply_symm_apply (e : P₁ ≃ᴬ[k] P₂) (p : P₂) : e (e.symm p) = p theorem symm_apply_apply (e : P₁ ≃ᴬ[k] P₂) (p : P₁) : e.symm (e p) = p := e.toEquiv.symm_apply_apply p -theorem apply_eq_iff_eq_symm_apply (e : P₁ ≃ᴬ[k] P₂) {p₁ p₂} : e p₁ = p₂ ↔ p₁ = e.symm p₂ := - e.toEquiv.apply_eq_iff_eq_symm_apply - theorem apply_eq_iff_eq (e : P₁ ≃ᴬ[k] P₂) {p₁ p₂ : P₁} : e p₁ = e p₂ ↔ p₁ = p₂ := e.toEquiv.apply_eq_iff_eq @@ -220,6 +217,10 @@ theorem symm_apply_eq (e : P₁ ≃ᴬ[k] P₂) {x y} : e.symm x = y ↔ x = e y theorem eq_symm_apply (e : P₁ ≃ᴬ[k] P₂) {x y} : y = e.symm x ↔ e y = x := e.toAffineEquiv.eq_symm_apply +@[deprecated eq_symm_apply (since := "2026-07-26")] +theorem apply_eq_iff_eq_symm_apply (e : P₁ ≃ᴬ[k] P₂) {p₁ p₂} : e p₁ = p₂ ↔ p₁ = e.symm p₂ := + e.eq_symm_apply.symm + @[simp] theorem image_symm (f : P₁ ≃ᴬ[k] P₂) (s : Set P₂) : f.symm '' s = f ⁻¹' s := f.symm.toEquiv.image_eq_preimage_symm _ diff --git a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean index a824a427214ad4..9e09e4146624ce 100644 --- a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean +++ b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean @@ -481,10 +481,6 @@ theorem symm_comp_self (e : M ≃ₜ* N) : e.symm ∘ e = id := theorem self_comp_symm (e : M ≃ₜ* N) : e ∘ e.symm = id := funext e.apply_symm_apply -@[to_additive] -theorem apply_eq_iff_symm_apply (e : M ≃ₜ* N) {x : M} {y : N} : e x = y ↔ x = e.symm y := - e.toEquiv.apply_eq_iff_eq_symm_apply - @[to_additive] theorem symm_apply_eq (e : M ≃ₜ* N) {x y} : e.symm x = y ↔ x = e y := e.toEquiv.symm_apply_eq @@ -493,6 +489,10 @@ theorem symm_apply_eq (e : M ≃ₜ* N) {x y} : e.symm x = y ↔ x = e y := theorem eq_symm_apply (e : M ≃ₜ* N) {x y} : y = e.symm x ↔ e y = x := e.toEquiv.eq_symm_apply +@[to_additive (attr := deprecated eq_symm_apply (since := "2026-07-26"))] +theorem apply_eq_iff_symm_apply (e : M ≃ₜ* N) {x : M} {y : N} : e x = y ↔ x = e.symm y := + e.eq_symm_apply.symm + @[to_additive] theorem eq_comp_symm {α : Type*} (e : M ≃ₜ* N) (f : N → α) (g : M → α) : f = g ∘ e.symm ↔ f ∘ e = g := diff --git a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean index ce0246b22432be..005e747d4e878d 100644 --- a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean +++ b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean @@ -411,7 +411,7 @@ lemma isUniformEmbedding_comp {Y : Type*} [UniformSpace Y] [Zero Y] (g : C(Y, R) sending `0 : X` to `0 : Y`. -/ def _root_.UniformEquiv.arrowCongrLeft₀ {Y : Type*} [TopologicalSpace Y] [Zero Y] (f : X ≃ₜ Y) (hf : f 0 = 0) : C(X, R)₀ ≃ᵤ C(Y, R)₀ where - toFun g := g.comp ⟨f.symm, (f.toEquiv.apply_eq_iff_eq_symm_apply.eq ▸ hf).symm⟩ + toFun g := g.comp ⟨f.symm, (f.eq_symm_apply.eq ▸ hf).symm⟩ invFun g := g.comp ⟨f, hf⟩ left_inv g := ext fun _ ↦ congrArg g <| f.left_inv _ right_inv g := ext fun _ ↦ congrArg g <| f.right_inv _ diff --git a/Mathlib/Topology/Covering/Quotient.lean b/Mathlib/Topology/Covering/Quotient.lean index b231b4ac28fed6..278603a2b6d3e3 100644 --- a/Mathlib/Topology/Covering/Quotient.lean +++ b/Mathlib/Topology/Covering/Quotient.lean @@ -101,7 +101,7 @@ noncomputable def fiberEquivGroup {x : X} (e : f ⁻¹' {x}) : f ⁻¹' {x} ≃ have ⟨g, eq⟩ := hf.apply_eq_iff_mem_orbit.mp (e'.2.trans e.2.symm); ⟨g, Subtype.ext eq⟩⟩ @[simp] theorem fiberEquivGroup_self {x : X} (e : f ⁻¹' {x}) : hf.fiberEquivGroup e e = 1 := - (Equiv.apply_eq_iff_eq_symm_apply _).mpr <| Subtype.ext (one_smul ..).symm + (Equiv.eq_symm_apply _).mp <| Subtype.ext (one_smul ..).symm set_option backward.isDefEq.respectTransparency.types false in @[simp] theorem fiberEquivGroup_eq_iff {x : X} (e e' : f ⁻¹' {x}) (g : G) : diff --git a/Mathlib/Topology/Instances/AddCircle/Defs.lean b/Mathlib/Topology/Instances/AddCircle/Defs.lean index 961fd112f6bbe1..1d16654533c69e 100644 --- a/Mathlib/Topology/Instances/AddCircle/Defs.lean +++ b/Mathlib/Topology/Instances/AddCircle/Defs.lean @@ -327,10 +327,10 @@ def liftIoc (f : 𝕜 → B) : AddCircle p → B := variable {p a} theorem equivIco_coe_eq {x : 𝕜} (hx : x ∈ Ico a (a + p)) : (equivIco p a) x = ⟨x, hx⟩ := by - rw [Equiv.apply_eq_iff_eq_symm_apply, equivIco, QuotientAddGroup.equivIcoMod_symm_apply] + rw [← Equiv.eq_symm_apply, equivIco, QuotientAddGroup.equivIcoMod_symm_apply] theorem equivIoc_coe_eq {x : 𝕜} (hx : x ∈ Ioc a (a + p)) : (equivIoc p a) x = ⟨x, hx⟩ := by - rw [Equiv.apply_eq_iff_eq_symm_apply, equivIoc, QuotientAddGroup.equivIocMod_symm_apply] + rw [← Equiv.eq_symm_apply, equivIoc, QuotientAddGroup.equivIocMod_symm_apply] @[simp] lemma coe_equivIco {y : AddCircle p} : From f6dc05e369aa1c3b6a70f416c4b299cf26e9dd38 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Thu, 6 Aug 2026 00:34:12 +0000 Subject: [PATCH 1183/1300] chore(Topology/UniformSpace): rename `complete_univ` to `isComplete_univ` (#42163) Rename `complete_univ` to `isComplete_univ` since the statement of the theorem is `IsComplete Set.univ`, there is no predicate called `complete`. --- Mathlib/Analysis/Calculus/FDeriv/Measurable.lean | 6 +++--- Mathlib/NumberTheory/Padics/ProperSpace.lean | 2 +- Mathlib/Topology/UniformSpace/Cauchy.lean | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean index ff064c774c6fe5..305bb401e14bca 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean @@ -372,7 +372,7 @@ variable [CompleteSpace F] /-- The set of differentiability points of a function taking values in a complete space is Borel-measurable. -/ theorem measurableSet_of_differentiableAt : MeasurableSet { x | DifferentiableAt 𝕜 f x } := by - have : IsComplete (univ : Set (E →L[𝕜] F)) := complete_univ + have : IsComplete (univ : Set (E →L[𝕜] F)) := isComplete_univ convert! measurableSet_of_differentiableAt_of_isComplete 𝕜 f this simp @@ -700,7 +700,7 @@ variable [CompleteSpace F] Borel-measurable. -/ theorem measurableSet_of_differentiableWithinAt_Ici : MeasurableSet { x | DifferentiableWithinAt ℝ f (Ici x) x } := by - have : IsComplete (univ : Set F) := complete_univ + have : IsComplete (univ : Set F) := isComplete_univ convert! measurableSet_of_differentiableWithinAt_Ici_of_isComplete f this simp @@ -893,7 +893,7 @@ variable [CompleteSpace F] values in a complete space is Borel-measurable. -/ theorem measurableSet_of_differentiableAt_with_param (hf : Continuous f.uncurry) : MeasurableSet {p : α × E | DifferentiableAt 𝕜 (f p.1) p.2} := by - have : IsComplete (univ : Set (E →L[𝕜] F)) := complete_univ + have : IsComplete (univ : Set (E →L[𝕜] F)) := isComplete_univ convert! measurableSet_of_differentiableAt_of_isComplete_with_param hf this simp diff --git a/Mathlib/NumberTheory/Padics/ProperSpace.lean b/Mathlib/NumberTheory/Padics/ProperSpace.lean index db68867d9bb6f2..2fe8af00160a22 100644 --- a/Mathlib/NumberTheory/Padics/ProperSpace.lean +++ b/Mathlib/NumberTheory/Padics/ProperSpace.lean @@ -54,7 +54,7 @@ theorem totallyBounded_univ : TotallyBounded (Set.univ : Set ℤ_[p]) := by /-- The set of p-adic integers `ℤ_[p]` is a compact topological space. -/ instance compactSpace : CompactSpace ℤ_[p] := by rw [← isCompact_univ_iff, isCompact_iff_totallyBounded_isComplete] - exact ⟨totallyBounded_univ p, complete_univ⟩ + exact ⟨totallyBounded_univ p, isComplete_univ⟩ end PadicInt diff --git a/Mathlib/Topology/UniformSpace/Cauchy.lean b/Mathlib/Topology/UniformSpace/Cauchy.lean index e32c38af6b5a53..146088998669cd 100644 --- a/Mathlib/Topology/UniformSpace/Cauchy.lean +++ b/Mathlib/Topology/UniformSpace/Cauchy.lean @@ -371,11 +371,13 @@ class CompleteSpace (α : Type u) [UniformSpace α] : Prop where /-- In a complete uniform space, every Cauchy filter converges. -/ complete : ∀ {f : Filter α}, Cauchy f → ∃ x, f ≤ 𝓝 x -theorem complete_univ {α : Type u} [UniformSpace α] [CompleteSpace α] : +theorem isComplete_univ {α : Type u} [UniformSpace α] [CompleteSpace α] : IsComplete (univ : Set α) := fun f hf _ => by rcases CompleteSpace.complete hf with ⟨x, hx⟩ exact ⟨x, mem_univ x, hx⟩ +@[deprecated (since := "2026-07-27")] alias complete_univ := isComplete_univ + instance CompleteSpace.prod [UniformSpace β] [CompleteSpace α] [CompleteSpace β] : CompleteSpace (α × β) where complete hf := @@ -413,7 +415,7 @@ theorem completeSpace_of_isComplete_univ (h : IsComplete (univ : Set α)) : Comp ⟨fun hf => let ⟨x, _, hx⟩ := h _ hf ((@principal_univ α).symm ▸ le_top); ⟨x, hx⟩⟩ theorem completeSpace_iff_isComplete_univ : CompleteSpace α ↔ IsComplete (univ : Set α) := - ⟨@complete_univ α _, completeSpace_of_isComplete_univ⟩ + ⟨@isComplete_univ α _, completeSpace_of_isComplete_univ⟩ theorem completeSpace_iff_ultrafilter : CompleteSpace α ↔ ∀ l : Ultrafilter α, Cauchy (l : Filter α) → ∃ x : α, ↑l ≤ 𝓝 x := by From 6064d46fbaaac6e10ba9a3046b1630ce415017ef Mon Sep 17 00:00:00 2001 From: Gian Sanjaya <43656481+mortarsanjaya@users.noreply.github.com> Date: Thu, 6 Aug 2026 01:28:40 +0000 Subject: [PATCH 1184/1300] feat(Data/Nat/ModEq): add a new congruence to divisibility lemma (#42230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we only have `modEq_iff_dvd'` which assumes `a ≤ b`. However, the `→` direction does not need this assumption. --- Mathlib/Data/Nat/ModEq.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Data/Nat/ModEq.lean b/Mathlib/Data/Nat/ModEq.lean index 22f5deb78a5c55..7ed514139042c6 100644 --- a/Mathlib/Data/Nat/ModEq.lean +++ b/Mathlib/Data/Nat/ModEq.lean @@ -118,6 +118,15 @@ alias ⟨ModEq.dvd, modEq_of_dvd⟩ := modEq_iff_dvd theorem modEq_iff_dvd' (h : a ≤ b) : a ≡ b [MOD n] ↔ n ∣ b - a := by rw [modEq_iff_dvd, ← Int.natCast_dvd_natCast, Int.ofNat_sub h] +/-- The forward direction of `modEq_iff_dvd'`, which does not require the `a ≤ b` assumption. -/ +theorem ModEq.dvd' (h : a ≡ b [MOD n]) : n ∣ b - a := by + obtain h0 | h0 : a ≤ b ∨ b ≤ a := le_total a b + · exact (modEq_iff_dvd' h0).mp h + · rw [Nat.sub_eq_zero_of_le h0] + exact Nat.dvd_zero n + +alias ⟨_, modEq_of_dvd'⟩ := modEq_iff_dvd' + theorem mod_modEq (a n) : a % n ≡ a [MOD n] := mod_mod _ _ From df0e56f998cbd44160a55f013bef8c30755e0885 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Thu, 6 Aug 2026 01:28:42 +0000 Subject: [PATCH 1185/1300] chore(Analysis/Seminorm): generalize `smul_le_smul` to arbitrary scalar multiplication (#42294) Co-authored-by: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> --- Mathlib/Analysis/LocallyConvex/WithSeminorms.lean | 8 ++++---- Mathlib/Analysis/Seminorm.lean | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean index c483bd0e38e773..1c6541d4bf0b9a 100644 --- a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean +++ b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean @@ -251,9 +251,9 @@ theorem const_isBounded (ι : Type*) [Nonempty ι] {p : Seminorm 𝕜 E} {q : ι (f : E →ₛₗ[σ₁₂] F) : IsBounded (fun _ : ι => p) q f ↔ ∀ i, ∃ C : ℝ≥0, (q i).comp f ≤ C • p := by constructor <;> intro h i · rcases h i with ⟨s, C, h⟩ - exact ⟨C, le_trans h (smul_le_smul (Finset.sup_le fun _ _ => le_rfl) le_rfl)⟩ - use {Classical.arbitrary ι} - simp only [h, Finset.sup_singleton] + exact ⟨C, h.trans (IsOrderedSMul.smul_le_smul_left _ p (Finset.sup_le fun _ _ ↦ le_rfl) C)⟩ + · use {Classical.arbitrary ι} + simp only [h, Finset.sup_singleton] theorem isBounded_sup {p : ι → Seminorm 𝕜 E} {q : ι' → Seminorm 𝕜₂ F} {f : E →ₛₗ[σ₁₂] F} (hf : IsBounded p q f) (s' : Finset ι') : @@ -265,7 +265,7 @@ theorem isBounded_sup {p : ι → Seminorm 𝕜 E} {q : ι' → Seminorm 𝕜₂ use s'.card • s'.sup fC, Finset.biUnion s' fₛ have hs : ∀ i : ι', i ∈ s' → (q i).comp f ≤ s'.sup fC • (Finset.biUnion s' fₛ).sup p := by intro i hi - refine (hf i).trans (smul_le_smul ?_ (Finset.le_sup hi)) + refine (hf i).trans (IsOrderedSMul.smul_le_smul (Finset.le_sup hi) ?_) exact Finset.sup_mono (Finset.subset_biUnion_of_mem fₛ hi) refine (comp_mono f (finset_sup_le_sum q s')).trans ?_ simp_rw [← pullback_apply, map_sum, pullback_apply] diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index 9c16d46c947377..eafc0f88c844ff 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -5,6 +5,7 @@ Authors: Jean Lo, Yaël Dillies, Moritz Doll -/ module +public import Mathlib.Algebra.Order.AddTorsor public import Mathlib.Algebra.Order.Pi public import Mathlib.Analysis.Convex.Function public import Mathlib.Analysis.LocallyConvex.Basic @@ -248,6 +249,14 @@ theorem lt_def {p q : Seminorm 𝕜 E} : p < q ↔ p ≤ q ∧ ∃ x, p x < q x instance instSemilatticeSup : SemilatticeSup (Seminorm 𝕜 E) := DFunLike.coe_injective.semilatticeSup _ .rfl .rfl coe_sup +instance [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] [Preorder R] [Zero R] + [IsOrderedModule R ℝ] : IsOrderedSMul R (Seminorm 𝕜 E) where + smul_le_smul_left p q hpq c x := calc + _ ≤ (c • (1 : ℝ≥0)) • p x := by simp + _ ≤ _ := by grw [hpq x]; simp + smul_le_smul_right a b hab p x := by + grw [smul_apply, hab, smul_apply] + end SMul end AddGroup @@ -324,7 +333,8 @@ theorem coe_bot : ⇑(⊥ : Seminorm 𝕜 E) = 0 := theorem bot_eq_zero : (⊥ : Seminorm 𝕜 E) = 0 := rfl -theorem smul_le_smul {p q : Seminorm 𝕜 E} {a b : ℝ≥0} (hpq : p ≤ q) (hab : a ≤ b) : +@[deprecated IsOrderedSMul.smul_le_smul (since := "2026-07-31")] +protected theorem smul_le_smul {p q : Seminorm 𝕜 E} {a b : ℝ≥0} (hpq : p ≤ q) (hab : a ≤ b) : a • p ≤ b • q := by simp_rw [le_def] intro x From 7bd8067d23d893d876aa24274d595be9ba72dfa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Thu, 6 Aug 2026 01:28:45 +0000 Subject: [PATCH 1186/1300] chore(Order/Bounds/Basic): use `to_dual` more (#42362) --- Mathlib/Order/Bounds/Basic.lean | 63 ++++++++++----------------------- 1 file changed, 19 insertions(+), 44 deletions(-) diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index a00caaa768c552..260314ac9038b1 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -513,55 +513,44 @@ theorem upperBounds_singleton : upperBounds {a} = Ici a := -/ -@[simp] lemma bddAbove_Icc : BddAbove (Icc a b) := ⟨b, fun _ => And.right⟩ -@[simp] lemma bddBelow_Icc : BddBelow (Icc a b) := ⟨a, fun _ => And.left⟩ -@[simp] lemma bddAbove_Ico : BddAbove (Ico a b) := bddAbove_Icc.mono Ico_subset_Icc_self -@[simp] lemma bddBelow_Ico : BddBelow (Ico a b) := bddBelow_Icc.mono Ico_subset_Icc_self -@[simp] lemma bddAbove_Ioc : BddAbove (Ioc a b) := bddAbove_Icc.mono Ioc_subset_Icc_self -@[simp] lemma bddBelow_Ioc : BddBelow (Ioc a b) := bddBelow_Icc.mono Ioc_subset_Icc_self -@[simp] lemma bddAbove_Ioo : BddAbove (Ioo a b) := bddAbove_Icc.mono Ioo_subset_Icc_self -@[simp] lemma bddBelow_Ioo : BddBelow (Ioo a b) := bddBelow_Icc.mono Ioo_subset_Icc_self +@[to_dual (attr := simp)] +lemma bddAbove_Icc : BddAbove (Icc a b) := ⟨b, fun _ => And.right⟩ +@[to_dual (attr := simp)] +lemma bddAbove_Ico : BddAbove (Ico a b) := bddAbove_Icc.mono Ico_subset_Icc_self +@[to_dual (attr := simp)] +lemma bddBelow_Ico : BddBelow (Ico a b) := bddBelow_Icc.mono Ico_subset_Icc_self +@[to_dual (attr := simp)] +lemma bddAbove_Ioo : BddAbove (Ioo a b) := bddAbove_Icc.mono Ioo_subset_Icc_self +@[to_dual] theorem isGreatest_Icc (h : a ≤ b) : IsGreatest (Icc a b) b := ⟨right_mem_Icc.2 h, fun _ => And.right⟩ +@[to_dual] theorem isLUB_Icc (h : a ≤ b) : IsLUB (Icc a b) b := (isGreatest_Icc h).isLUB +@[to_dual] theorem upperBounds_Icc (h : a ≤ b) : upperBounds (Icc a b) = Ici b := (isLUB_Icc h).upperBounds_eq -theorem isLeast_Icc (h : a ≤ b) : IsLeast (Icc a b) a := - ⟨left_mem_Icc.2 h, fun _ => And.left⟩ - -theorem isGLB_Icc (h : a ≤ b) : IsGLB (Icc a b) a := - (isLeast_Icc h).isGLB - -theorem lowerBounds_Icc (h : a ≤ b) : lowerBounds (Icc a b) = Iic a := - (isGLB_Icc h).lowerBounds_eq - +@[to_dual] theorem isGreatest_Ioc (h : a < b) : IsGreatest (Ioc a b) b := ⟨right_mem_Ioc.2 h, fun _ => And.right⟩ +@[to_dual] theorem isLUB_Ioc (h : a < b) : IsLUB (Ioc a b) b := (isGreatest_Ioc h).isLUB +@[to_dual] theorem upperBounds_Ioc (h : a < b) : upperBounds (Ioc a b) = Ici b := (isLUB_Ioc h).upperBounds_eq -theorem isLeast_Ico (h : a < b) : IsLeast (Ico a b) a := - ⟨left_mem_Ico.2 h, fun _ => And.left⟩ - -theorem isGLB_Ico (h : a < b) : IsGLB (Ico a b) a := - (isLeast_Ico h).isGLB - -theorem lowerBounds_Ico (h : a < b) : lowerBounds (Ico a b) = Iic a := - (isGLB_Ico h).lowerBounds_eq - section variable [SemilatticeSup γ] [DenselyOrdered γ] +@[to_dual] theorem isGLB_Ioo {a b : γ} (h : a < b) : IsGLB (Ioo a b) a := ⟨fun _ hx => hx.1.le, fun x hx => by rcases eq_or_lt_of_le (le_sup_right : a ≤ x ⊔ a) with h₁ | h₂ @@ -571,39 +560,25 @@ theorem isGLB_Ioo {a b : γ} (h : a < b) : IsGLB (Ioo a b) a := obtain ⟨u, au, ub⟩ := exists_between h apply (hx ⟨au, ub⟩).trans ub.le⟩ +@[to_dual] theorem lowerBounds_Ioo {a b : γ} (hab : a < b) : lowerBounds (Ioo a b) = Iic a := (isGLB_Ioo hab).lowerBounds_eq +@[to_dual] theorem isGLB_Ioc {a b : γ} (hab : a < b) : IsGLB (Ioc a b) a := (isGLB_Ioo hab).of_subset_of_superset (isGLB_Icc hab.le) Ioo_subset_Ioc_self Ioc_subset_Icc_self +@[to_dual] theorem lowerBounds_Ioc {a b : γ} (hab : a < b) : lowerBounds (Ioc a b) = Iic a := (isGLB_Ioc hab).lowerBounds_eq end -section - -variable [SemilatticeInf γ] [DenselyOrdered γ] - -theorem isLUB_Ioo {a b : γ} (hab : a < b) : IsLUB (Ioo a b) b := by - simpa only [Ioo_toDual] using! isGLB_Ioo hab.dual - -theorem upperBounds_Ioo {a b : γ} (hab : a < b) : upperBounds (Ioo a b) = Ici b := - (isLUB_Ioo hab).upperBounds_eq - -theorem isLUB_Ico {a b : γ} (hab : a < b) : IsLUB (Ico a b) b := by - simpa only [Ioc_toDual] using! isGLB_Ioc hab.dual - -theorem upperBounds_Ico {a b : γ} (hab : a < b) : upperBounds (Ico a b) = Ici b := - (isLUB_Ico hab).upperBounds_eq - -end - @[to_dual] theorem bddBelow_iff_subset_Ici : BddBelow s ↔ ∃ a, s ⊆ Ici a := Iff.rfl +@[to_dual none] theorem bddBelow_bddAbove_iff_subset_Icc : BddBelow s ∧ BddAbove s ↔ ∃ a b, s ⊆ Icc a b := by simp [Ici_inter_Iic.symm, subset_inter_iff, bddBelow_iff_subset_Ici, bddAbove_iff_subset_Iic, exists_and_left, exists_and_right] From 0e98674e03da6696b2d8036cf608b2a428bffac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Thu, 6 Aug 2026 01:28:47 +0000 Subject: [PATCH 1187/1300] chore: golf `exists_wellFoundedGT` (#42368) We avoid a weird usage of `simpa`, and rewrite the docstrings. --- Mathlib/SetTheory/Cardinal/Order.lean | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index ffe413a7841ced..36d8df03d5479c 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -547,19 +547,17 @@ instance IsWellOrder.subtype_nonempty : Nonempty { r // IsWellOrder α r } := ⟨⟨WellOrderingRel, inferInstance⟩⟩ variable (α) in -/-- The **well-ordering theorem** (or **Zermelo's theorem**): -every type has a linear order which satisfies `WellFoundedGT` -/ -lemma exists_wellFoundedGT : ∃ (_ : LinearOrder α), WellFoundedGT α := by +/-- The **well-ordering theorem** (or **Zermelo's theorem**): every type can be well-ordered. -/ +theorem exists_wellFoundedLT : ∃ (_ : LinearOrder α), WellFoundedLT α := by classical - exact ⟨linearOrderOfSTO (Function.swap WellOrderingRel), - by simpa [isWellFounded_iff] using! WellOrderingRel.isWellOrder.wf⟩ + exact ⟨linearOrderOfSTO WellOrderingRel, ⟨WellOrderingRel.isWellOrder.wf⟩⟩ variable (α) in -/-- The **well-ordering theorem** (or **Zermelo's theorem**): every type has a well-order -/ +/-- The **well-ordering theorem** (or **Zermelo's theorem**): every type can be co-well-ordered. -/ @[to_dual existing] -theorem exists_wellFoundedLT : ∃ (_ : LinearOrder α), WellFoundedLT α := by +lemma exists_wellFoundedGT : ∃ (_ : LinearOrder α), WellFoundedGT α := by classical - exact ⟨linearOrderOfSTO WellOrderingRel, WellOrderingRel.isWellOrder.toIsWellFounded⟩ + exact ⟨linearOrderOfSTO (Function.swap WellOrderingRel), ⟨WellOrderingRel.isWellOrder.wf⟩⟩ @[deprecated (since := "2026-04-12")] alias exists_wellOrder := exists_wellFoundedLT From bf6473c670ffb5e8c347f90881f0eebbbb3d4ec3 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Thu, 6 Aug 2026 01:28:49 +0000 Subject: [PATCH 1188/1300] chore: rename some lemmas containing `not_unit` (#42386) Co-authored-by: NoahW314 --- Mathlib/Algebra/Prime/Lemmas.lean | 13 ++++++++++--- Mathlib/RingTheory/ChainOfDivisors.lean | 6 +++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Prime/Lemmas.lean b/Mathlib/Algebra/Prime/Lemmas.lean index 0095606c2e6a93..70beb3f1460d26 100644 --- a/Mathlib/Algebra/Prime/Lemmas.lean +++ b/Mathlib/Algebra/Prime/Lemmas.lean @@ -161,14 +161,21 @@ theorem DvdNotUnit.isUnit_of_irreducible_right [CommMonoidWithZero M] {p q : M} obtain ⟨_, x, hx, hx'⟩ := h exact ((irreducible_iff.1 hq).right hx').resolve_right hx -theorem not_irreducible_of_not_unit_dvdNotUnit [CommMonoidWithZero M] {p q : M} (hp : ¬IsUnit p) - (h : DvdNotUnit p q) : ¬Irreducible q := +theorem not_irreducible_of_not_isUnit_of_dvdNotUnit [CommMonoidWithZero M] {p q : M} + (hp : ¬IsUnit p) (h : DvdNotUnit p q) : ¬Irreducible q := mt h.isUnit_of_irreducible_right hp -theorem DvdNotUnit.not_unit [CommMonoidWithZero M] {p q : M} (hp : DvdNotUnit p q) : ¬IsUnit q := by +@[deprecated (since := "2026-08-02")] +alias not_irreducible_of_not_unit_dvdNotUnit := not_irreducible_of_not_isUnit_of_dvdNotUnit + +theorem DvdNotUnit.not_isUnit [CommMonoidWithZero M] {p q : M} (hp : DvdNotUnit p q) : + ¬IsUnit q := by obtain ⟨-, x, hx, rfl⟩ := hp exact fun hc => hx (isUnit_iff_dvd_one.mpr (dvd_of_mul_left_dvd (isUnit_iff_dvd_one.mp hc))) +@[deprecated (since := "2026-08-02")] +alias DvdNotUnit.not_unit := DvdNotUnit.not_isUnit + end CommMonoidWithZero section CancelCommMonoidWithZero diff --git a/Mathlib/RingTheory/ChainOfDivisors.lean b/Mathlib/RingTheory/ChainOfDivisors.lean index 90fcb0b18eaae4..c34c03db228902 100644 --- a/Mathlib/RingTheory/ChainOfDivisors.lean +++ b/Mathlib/RingTheory/ChainOfDivisors.lean @@ -85,7 +85,7 @@ theorem exists_chain_of_prime_pow {p : Associates M} {n : ℕ} (hn : n ≠ 0) (h theorem element_of_chain_not_isUnit_of_index_ne_zero {n : ℕ} {i : Fin (n + 1)} (i_pos : i ≠ 0) {c : Fin (n + 1) → Associates M} (h₁ : StrictMono c) : ¬IsUnit (c i) := - DvdNotUnit.not_unit + DvdNotUnit.not_isUnit (Associates.dvdNotUnit_iff_lt.2 (h₁ <| show (0 : Fin (n + 1)) < i from Fin.pos_iff_ne_zero.mpr i_pos)) @@ -122,8 +122,8 @@ theorem eq_second_of_chain_of_prime_dvd {p q r : Associates M} {n : ℕ} (hn : n obtain rfl | ⟨j, rfl⟩ := i.eq_zero_or_eq_succ · cases hi refine - not_irreducible_of_not_unit_dvdNotUnit - (DvdNotUnit.not_unit + not_irreducible_of_not_isUnit_of_dvdNotUnit + (DvdNotUnit.not_isUnit (Associates.dvdNotUnit_iff_lt.2 (h₁ (show (0 : Fin (n + 2)) < j.castSucc from ?_)))) ?_ hp.irreducible · simpa using Fin.lt_def.mp hi From 944508abf2681c73ca4a6618fe3bcea94ad03c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Thu, 6 Aug 2026 01:28:51 +0000 Subject: [PATCH 1189/1300] chore: golf `IsSupClosedCompact.wellFoundedGT` (#42422) --- Mathlib/Order/CompactlyGenerated/Basic.lean | 30 +++++++-------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/Mathlib/Order/CompactlyGenerated/Basic.lean b/Mathlib/Order/CompactlyGenerated/Basic.lean index 07739d090dcd85..3f2f4def8459d9 100644 --- a/Mathlib/Order/CompactlyGenerated/Basic.lean +++ b/Mathlib/Order/CompactlyGenerated/Basic.lean @@ -230,26 +230,16 @@ theorem IsSupFiniteCompact.isSupClosedCompact (h : IsSupFiniteCompact α) : · rw [ht₂] exact hsc.finsetSup_mem h ht₁ -theorem IsSupClosedCompact.wellFoundedGT (h : IsSupClosedCompact α) : - WellFoundedGT α where - wf := by - refine RelEmbedding.wellFounded_iff_isEmpty.mpr ⟨fun a => ?_⟩ - suffices sSup (Set.range a) ∈ Set.range a by - obtain ⟨n, hn⟩ := Set.mem_range.mp this - have h' : sSup (Set.range a) < a (n + 1) := by - change _ > _ - simp [← hn, a.map_rel_iff] - apply lt_irrefl (a (n + 1)) - apply lt_of_le_of_lt _ h' - apply le_sSup - apply Set.mem_range_self - apply h (Set.range a) - · use a 37 - apply Set.mem_range_self - · rintro x ⟨m, hm⟩ y ⟨n, hn⟩ - use m ⊔ n - rw [← hm, ← hn] - apply RelHomClass.map_sup a +theorem IsSupClosedCompact.wellFoundedGT (h : IsSupClosedCompact α) : WellFoundedGT α := by + rw [wellFoundedGT_iff_monotone_chain_condition'] + intro a + obtain ⟨n, hn⟩ : sSup (range a) ∈ range a := by + apply h _ (range_nonempty a) + rintro x ⟨m, rfl⟩ y ⟨n, rfl⟩ + exact ⟨_, map_sup a m n⟩ + refine ⟨n, fun m hm ↦ ?_⟩ + rw [hn] + exact (le_sSup (mem_range_self m)).not_gt theorem isSupFiniteCompact_iff_all_elements_compact : IsSupFiniteCompact α ↔ ∀ k : α, IsCompactElement k := by From 640b05473b7bdf75970ec4c175b6915d3d8e60cf Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Thu, 6 Aug 2026 01:28:53 +0000 Subject: [PATCH 1190/1300] =?UTF-8?q?chore(Algebra/Group/Action/Opposite):?= =?UTF-8?q?=20fix=20copy-paste=20error=20in=20+=E1=B5=A5>=20docstring=20(#?= =?UTF-8?q?42460)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docstring for the `+ᵥ>` notation said it unfolds to `r • m`; it actually unfolds to `r +ᵥ m`. --- Mathlib/Algebra/Group/Action/Opposite.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Action/Opposite.lean b/Mathlib/Algebra/Group/Action/Opposite.lean index 0725bd5184a37f..1992f05d04b5d3 100644 --- a/Mathlib/Algebra/Group/Action/Opposite.lean +++ b/Mathlib/Algebra/Group/Action/Opposite.lean @@ -90,7 +90,7 @@ scoped notation3:74 r:75 " •> " m:74 => r • m In lemma names this is still called `op_smul`. -/ scoped notation3:73 m:73 " <• " r:74 => MulOpposite.op r • m -/-- With `open scoped RightActions`, an alternative symbol for left actions, `r • m`. +/-- With `open scoped RightActions`, an alternative symbol for left actions, `r +ᵥ m`. In lemma names this is still called `vadd`. -/ scoped notation3:74 r:75 " +ᵥ> " m:74 => r +ᵥ m From f4a20a0e0d8a29d2421fd9d042efe34d920f50c0 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Thu, 6 Aug 2026 01:28:55 +0000 Subject: [PATCH 1191/1300] feat: `Nat.add_div_le_div_add_div_add_one` (#42481) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove natural number division inequality `(a + b) / c ≤ a / c + b / c + 1`. Also deprecate `Nat.add_div_le_add_div` because it is a duplicate of `Nat.div_add_div_le_add_div`. --- Mathlib/Data/Nat/ModEq.lean | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Nat/ModEq.lean b/Mathlib/Data/Nat/ModEq.lean index 7ed514139042c6..1ffd68b0527a5b 100644 --- a/Mathlib/Data/Nat/ModEq.lean +++ b/Mathlib/Data/Nat/ModEq.lean @@ -554,9 +554,15 @@ protected theorem add_div_of_dvd_left {a b c : ℕ} (hca : c ∣ b) : (a + b) / theorem add_div_eq_of_le_mod_add_mod {a b c : ℕ} (hc : c ≤ a % c + b % c) (hc0 : 0 < c) : (a + b) / c = a / c + b / c + 1 := by rw [Nat.add_div hc0, if_pos hc] +@[deprecated Nat.div_add_div_le_add_div (since := "2026-08-05")] theorem add_div_le_add_div (a b c : ℕ) : a / c + b / c ≤ (a + b) / c := - if hc0 : c = 0 then by simp [hc0] - else by rw [Nat.add_div (Nat.pos_of_ne_zero hc0)]; exact Nat.le_add_right _ _ + Nat.div_add_div_le_add_div + +theorem add_div_le_div_add_div_add_one (a b c : ℕ) : (a + b) / c ≤ a / c + b / c + 1 := by + by_cases h : c = 0 + · simp [h] + · rw [Nat.add_div (Nat.pos_of_ne_zero h), Nat.add_le_add_iff_left] + split <;> decide theorem le_mod_add_mod_of_dvd_add_of_not_dvd {a b c : ℕ} (h : c ∣ a + b) (ha : ¬c ∣ a) : c ≤ a % c + b % c := From 7a1f8433f11599aee71a0dcb0fc6277c4495f82e Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 03:10:40 +0000 Subject: [PATCH 1192/1300] chore: update Mathlib dependencies 2026-08-06 (#42484) This PR updates the Mathlib dependencies. --- .github/actions/get-mathlib-ci/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index ef96111a926264..14214c6e6b6feb 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -10,7 +10,7 @@ inputs: # Default pinned commit used by workflows unless they explicitly override. # Update this ref as needed to pick up changes to mathlib-ci scripts # This is also updated automatically by .github/workflows/update_dependencies.yml - default: 5668fbbccf0fecefdfcddf539b8406db197dfc59 + default: dae5b1a4c7d1d5fef3247bfe708eb0c7e4dadaa5 path: description: Checkout destination path. required: false From ce1cc649d9e549333943c5cc18bbf1af5030635c Mon Sep 17 00:00:00 2001 From: damiano Date: Thu, 6 Aug 2026 03:41:47 +0000 Subject: [PATCH 1193/1300] chore(CI): keep the previous Lean declarations diff visible while a new build runs (#40486) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the previous Lean declarations diff visible (relabelled *stale*) while a new build runs, instead of resetting the PR-summary comment to *pending* on every push. Companion: leanprover-community/mathlib-ci#56 · details in the **Reference** / **Explanation** / **How-to** comments below. --- .github/workflows/PR_summary.yml | 23 +++++++++++++++++------ .github/workflows/decls-diff.yml | 3 +++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index c3350f3ed27589..b0f7781f525ae7 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -220,12 +220,23 @@ jobs: else declDiff="$(printf '#### Declarations diff (regex)\n\n%s\n' "${declDiff}")" fi - # Append a placeholder for the post-build, Lean-aware diff. The - # `decls-diff.yml` workflow replaces the region between the markers (see - # mathlib-ci's `updateDeclsDiffSection.py`); the regex block above is left - # as-is. The markers are HTML comments (invisible when rendered), and the - # heading carries the status (`pending` → `(Lean)` / `(Lean -- unavailable)`). - declDiff="$(printf '%s\n\n\n#### Declarations diff (Lean -- pending)\n\n_Computed after the build finishes._\n\n' "${declDiff}")" + # Append the post-build, Lean-aware diff region. The `decls-diff.yml` + # workflow later replaces the content between the markers (see mathlib-ci's + # `updateDeclsDiffSection.py`); the regex block above is left as-is. The + # markers are HTML comments (invisible when rendered), and the heading + # carries the status (`pending` → `(Lean)` / `(Lean -- unavailable)`). + # + # Because this pre-build step rewrites the whole comment, it would otherwise + # blank a previously-shown diff back to `pending` on every push. Instead we + # ask `updateDeclsDiffSection.py` (MODE=emit) to carry the existing real diff + # forward — relabelled stale — so it stays visible until the new build lands; + # on the first run (or with no prior diff) it prints the pending placeholder. + leanRegion="$(MODE=emit \ + NEW_HEADING='#### Declarations diff (Lean -- stale, waiting for the new build)' \ + REPO="${{ github.repository }}" PR_NUMBER="${PR}" PR_HEAD_SHA="${currentHash}" \ + python3 "${CI_SCRIPTS_DIR}/pr_summary/updateDeclsDiffSection.py" \ + || printf '#### Declarations diff (Lean -- pending)\n\n_Computed after the build finishes._')" + declDiff="$(printf '%s\n\n\n%s\n\n' "${declDiff}" "${leanRegion}")" git checkout "${currentHash}" -- hashURL="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}/commits/${currentHash}" printf 'hashURL: %s' "${hashURL}" diff --git a/.github/workflows/decls-diff.yml b/.github/workflows/decls-diff.yml index d4405ca5107524..3b12118d7e805a 100644 --- a/.github/workflows/decls-diff.yml +++ b/.github/workflows/decls-diff.yml @@ -181,6 +181,9 @@ jobs: PR_NUMBER: ${{ steps.pr.outputs.pr-number }} MODE: warning DEFAULT_BRANCH: master + # If a real diff is already shown, keep it (relabelled) rather than + # blanking it to "unavailable" and give an actionable remedy. + NEW_HEADING: '#### Declarations diff (Lean -- stale; merge master and push to refresh)' run: | # Record the cache miss in the step summary first, so a later patcher # error (e.g. a transient GitHub failure) still leaves this run-local From b7ca352dd16d2d28b9c8f45b0af96f6da5c23106 Mon Sep 17 00:00:00 2001 From: damiano Date: Thu, 6 Aug 2026 03:51:09 +0000 Subject: [PATCH 1194/1300] chore: add missing `to_additive` docstrings (Normed, TransferInstance) (#41647) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out of #41642. These three additive doc-strings need closer review than a mechanical translation: - `Analysis/Normed/Group/Constructions.lean` — `Prod.nnnorm_def'`/`Prod.nnnorm_mk'` (primed↔unprimed naming with `to_additive`; needs double-checking). - `Analysis/Normed/Group/Continuity.lean` — `comap_norm_nhdsGT_zero'` (freshly worded additive doc-string). - `Topology/Algebra/Module/TransferInstance.lean` — `ContinuousMulEquiv.isTopologicalGroup` (the pre-existing multiplicative doc-string already reads as additive — likely needs fixing on both sides). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Mathlib/Analysis/Normed/Group/Constructions.lean | 5 +++-- Mathlib/Analysis/Normed/Group/Continuity.lean | 7 +++++-- Mathlib/Topology/Algebra/Module/TransferInstance.lean | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/Normed/Group/Constructions.lean b/Mathlib/Analysis/Normed/Group/Constructions.lean index 030fcae76666bb..a257743f2b88dd 100644 --- a/Mathlib/Analysis/Normed/Group/Constructions.lean +++ b/Mathlib/Analysis/Normed/Group/Constructions.lean @@ -256,11 +256,12 @@ instance Prod.seminormedGroup : SeminormedGroup (E × F) where /-- Multiplicative version of `Prod.nnnorm_def`. Earlier, this name was used for the additive version. -/ -@[to_additive Prod.nnnorm_def] +@[to_additive Prod.nnnorm_def /-- Additive version of `Prod.nnnorm_def'`. +Earlier, this name was used for the multiplicative version. -/] lemma Prod.nnnorm_def' (x : E × F) : ‖x‖₊ = max ‖x.1‖₊ ‖x.2‖₊ := rfl /-- Multiplicative version of `Prod.nnnorm_mk`. -/ -@[to_additive (attr := simp) Prod.nnnorm_mk] +@[to_additive (attr := simp) Prod.nnnorm_mk /-- Additive version of `Prod.nnnorm_mk'`. -/] lemma Prod.nnnorm_mk' (x : E) (y : F) : ‖(x, y)‖₊ = max ‖x‖₊ ‖y‖₊ := rfl end SeminormedGroup diff --git a/Mathlib/Analysis/Normed/Group/Continuity.lean b/Mathlib/Analysis/Normed/Group/Continuity.lean index 062cd64a5c88bf..cb8b0096449194 100644 --- a/Mathlib/Analysis/Normed/Group/Continuity.lean +++ b/Mathlib/Analysis/Normed/Group/Continuity.lean @@ -402,8 +402,11 @@ theorem tendsto_norm_inv_mul_self_nhdsNE (a : E) : variable (E) -/-- A version of `comap_norm_nhdsGT_zero` for a multiplicative normed group. -/ -@[to_additive comap_norm_nhdsGT_zero] +/-- In a normed group, the pullback under the norm of `𝓝[>] 0` is the punctured neighborhood +of `1`. -/ +@[to_additive comap_norm_nhdsGT_zero +/-- In a normed additive group, the pullback under the norm of `𝓝[>] 0` is the punctured +neighborhood of `0`. -/] lemma comap_norm_nhdsGT_zero' : comap norm (𝓝[>] 0) = 𝓝[≠] (1 : E) := by simp [nhdsWithin, comap_norm_nhds_one, Set.preimage, Set.compl_def] diff --git a/Mathlib/Topology/Algebra/Module/TransferInstance.lean b/Mathlib/Topology/Algebra/Module/TransferInstance.lean index 4e1f9e606f6404..dfdbf05b9d7ad0 100644 --- a/Mathlib/Topology/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Topology/Algebra/Module/TransferInstance.lean @@ -66,9 +66,11 @@ section ContinuousLinearEquiv variable [Semiring R] -/-- Given a continuous additive equivalence `e : α ≃ₜ+ β`, if `β` is a topological additive group, +/-- Given a continuous multiplicative equivalence `e : α ≃ₜ* β`, if `β` is a topological group, then so is `α`. -/ -@[to_additive] +@[to_additive +/-- Given a continuous additive equivalence `e : α ≃ₜ+ β`, if `β` is a topological additive group, +then so is `α`. -/] lemma ContinuousMulEquiv.isTopologicalGroup [TopologicalSpace β] [Group β] [IsTopologicalGroup β] [TopologicalSpace α] [Group α] (e : α ≃ₜ* β) : IsTopologicalGroup α where From 046187e5bbad80fe0429eecbe033946fe5b00903 Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Thu, 6 Aug 2026 04:14:13 +0000 Subject: [PATCH 1195/1300] feat(Analysis): the inverse fourier transform from L1 to BCF (#42427) API is the same as for the Fourier transform, proofs follow trivially from the FT itself. Material taken from github.com/mcdoll/DirichletProblem --- .../Analysis/Fourier/FourierTransform.lean | 38 ++++++++++++++++ .../ContinuousMap/Bounded/Normed.lean | 43 ++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Fourier/FourierTransform.lean b/Mathlib/Analysis/Fourier/FourierTransform.lean index 0c2af6da809eaf..afb0c9ea45eb72 100644 --- a/Mathlib/Analysis/Fourier/FourierTransform.lean +++ b/Mathlib/Analysis/Fourier/FourierTransform.lean @@ -566,4 +566,42 @@ def Lp.fourierTransformCLM : Lp (α := V) E 1 →L[ℂ] V →ᵇ E := theorem Lp.fourierTransformCLM_apply (f : Lp (α := V) E 1) : Lp.fourierTransformCLM V E f = Lp.fourierTransform f := rfl +/-- The inverse Fourier transform from `L1` functions to bounded continuous functions. -/ +def Lp.fourierTransformInv (f : Lp (α := V) E 1) : V →ᵇ E := + (Lp.fourierTransform f).compContinuous (-ContinuousMap.id V) + +theorem fourierInv_congr_ae {f₁ f₂ : V → E} (hf : f₁ =ᵐ[volume] f₂) (x : V) : + 𝓕⁻ f₁ x = 𝓕⁻ f₂ x := by + apply integral_congr_ae + filter_upwards [hf] with _ hf' + rw [hf'] + +@[simp] +theorem Lp.fourierTransformInv_apply (f : Lp (α := V) E 1) (x : V) : + Lp.fourierTransformInv f x = 𝓕⁻ (f : V → E) x := by + simp [Lp.fourierTransformInv, fourierInv_eq_fourier_neg] + +@[norm_cast] +theorem Lp.coe_fourierTransformInv (f : Lp (α := V) E 1) : + (Lp.fourierTransformInv f : V → E) = 𝓕⁻ (f : V → E) := by + ext x + simp + +@[simp] +theorem Lp.fourierTransformInv_toLp {f : V → E} (hf : MemLp f 1) : + (Lp.fourierTransformInv hf.toLp : V → E) = 𝓕⁻ f := by + ext x + simpa using (Real.fourierInv_congr_ae hf.coeFn_toLp) x + +variable (V E) in +/-- The inverse Fourier transform from `L1` functions to bounded continuous functions as a +continuous linear map. -/ +def Lp.fourierTransformInvCLM : Lp (α := V) E 1 →L[ℂ] V →ᵇ E := + BoundedContinuousFunction.compContinuousCLM _ ℂ (-.id V) ∘L Lp.fourierTransformCLM V E + +@[simp] +theorem Lp.fourierTransformInvCLM_apply (f : Lp (α := V) E 1) : + Lp.fourierTransformInvCLM V E f = Lp.fourierTransformInv f := by + simp [Lp.fourierTransformInvCLM, Lp.fourierTransformInv] + end Real diff --git a/Mathlib/Topology/ContinuousMap/Bounded/Normed.lean b/Mathlib/Topology/ContinuousMap/Bounded/Normed.lean index 609b034fba192a..91b9900c6017ab 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/Normed.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/Normed.lean @@ -261,9 +261,12 @@ instance instNormedSpace [NormedField 𝕜] [NormedSpace 𝕜 β] : NormedSpace norm_smul c (f x) ▸ mul_le_mul_of_nonneg_left (f.norm_coe_le_norm _) (norm_nonneg _)⟩ variable [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 β] + +section compLeftContinuousBounded + variable [SeminormedAddCommGroup γ] [NormedSpace 𝕜 γ] -variable (α) +variable (α) in -- TODO does this work in the `IsBoundedSMul` setting, too? /-- Postcomposition of bounded continuous functions into a normed module by a continuous linear map is a continuous linear map. @@ -283,6 +286,44 @@ protected def _root_.ContinuousLinearMap.compLeftContinuousBounded (g : β →L[ theorem _root_.ContinuousLinearMap.compLeftContinuousBounded_apply (g : β →L[𝕜] γ) (f : α →ᵇ β) (x : α) : (g.compLeftContinuousBounded α f) x = g (f x) := rfl +end compLeftContinuousBounded + +section compContinuousCLM + +variable {𝕜 : Type*} + +section NormedField + +variable [TopologicalSpace γ] [NormedField 𝕜] [NormedSpace 𝕜 β] + +variable (β 𝕜) in +/-- Precomposition with a continuous map is a continuous linear map from bounded continuous +functions to bounded continuous functions. -/ +def compContinuousCLM (g : C(γ, α)) : (α →ᵇ β) →L[𝕜] γ →ᵇ β := + LinearMap.mkContinuous + { toFun f := f.compContinuous g, + map_add' := by intros; ext; simp, + map_smul' := by intros; ext; simp } + 1 (by simpa using norm_compContinuous_le · g) + +@[simp] +theorem compContinuousCLM_apply (f : α →ᵇ β) (g : C(γ, α)) : + f.compContinuousCLM β 𝕜 g = f.compContinuous g := rfl + +end NormedField + +section NontriviallyNormedField + +variable [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 β] [SeminormedAddCommGroup γ] + +theorem norm_compContinuousCLM_le_one (g : C(γ, α)) : ‖compContinuousCLM β 𝕜 g‖ ≤ 1 := by + refine (compContinuousCLM β 𝕜 g).opNorm_le_bound zero_le_one (fun x ↦ ?_) + simpa using norm_compContinuous_le x g + +end NontriviallyNormedField + +end compContinuousCLM + end NormedSpace section NormedRing From 92f866971c22d14420e745016d5b6e22af9c4279 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Thu, 6 Aug 2026 08:23:27 +0000 Subject: [PATCH 1196/1300] feat: API for logarithmic derivatives of meromorphic functions (#41684) Provide API for logarithmic derivatives of meromorphic functions. This material is used in [Project VD](https://github.com/kebekus/ProjectVD), formalizing Value Distribution Theory for meromorphic functions on the complex plane. Claude Code was used to create this PR. --- Mathlib.lean | 1 + Mathlib/Analysis/Calculus/LogDeriv.lean | 30 +++ Mathlib/Analysis/Meromorphic/Basic.lean | 12 ++ Mathlib/Analysis/Meromorphic/LogDeriv.lean | 183 ++++++++++++++++++ Mathlib/Analysis/Meromorphic/Order.lean | 42 ++++ .../SpecialFunctions/Complex/LogDeriv.lean | 10 - 6 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 Mathlib/Analysis/Meromorphic/LogDeriv.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2c27b615282531..6e41a8ddc14e25 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2123,6 +2123,7 @@ public import Mathlib.Analysis.Meromorphic.Complex public import Mathlib.Analysis.Meromorphic.Divisor public import Mathlib.Analysis.Meromorphic.FactorizedRational public import Mathlib.Analysis.Meromorphic.IsolatedZeros +public import Mathlib.Analysis.Meromorphic.LogDeriv public import Mathlib.Analysis.Meromorphic.NormalForm public import Mathlib.Analysis.Meromorphic.Order public import Mathlib.Analysis.Meromorphic.RCLike diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index a83c1b6a95c470..6ae0d79a0c3262 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -40,6 +40,36 @@ lemma logDeriv_eq_zero_of_not_differentiableAt (f : 𝕜 → 𝕜') (x : 𝕜) ( logDeriv f x = 0 := by simp only [logDeriv_apply, deriv_zero_of_not_differentiableAt h, zero_div] +/-- If two functions agree in a neighborhood of `x`, then so do their logarithmic derivatives. -/ +lemma logDeriv_congr_nhds {f g : 𝕜 → 𝕜'} {x : 𝕜} (h : f =ᶠ[𝓝 x] g) : + logDeriv f =ᶠ[𝓝 x] logDeriv g := h.deriv.div h + +/-- +If two functions agree in a punctured neighborhood of `x`, then so do their logarithmic derivatives. +-/ +lemma logDeriv_congr_nhdsNE {f g : 𝕜 → 𝕜'} {x : 𝕜} (h : f =ᶠ[𝓝[≠] x] g) : + logDeriv f =ᶠ[𝓝[≠] x] logDeriv g := h.nhdsNE_deriv.div h + +/-- +If two functions agree on a codiscrete subset of an open set `U`, then so do their logarithmic +derivatives. +-/ +theorem logDeriv_congr_codiscreteWithin {f g : 𝕜 → 𝕜'} {U : Set 𝕜} (hU : IsOpen U) + (h : f =ᶠ[codiscreteWithin U] g) : + logDeriv f =ᶠ[codiscreteWithin U] logDeriv g := by + refine mem_codiscreteWithin_iff_forall_mem_nhdsNE.2 fun x hx ↦ ?_ + refine mem_of_superset (logDeriv_congr_nhdsNE ?_) Set.subset_union_left + filter_upwards [mem_codiscreteWithin_iff_forall_mem_nhdsNE.1 h x hx, + nhdsWithin_le_nhds (hU.mem_nhds hx)] with z hz hzU + exact hz.resolve_right (not_not_intro hzU) + +/-- +If two functions agree on a codiscrete subset of `𝕜`, then so do their logarithmic derivatives. +-/ +theorem logDeriv_congr_codiscrete {f g : 𝕜 → 𝕜'} (h : f =ᶠ[codiscrete 𝕜] g) : + logDeriv f =ᶠ[codiscrete 𝕜] logDeriv g := + logDeriv_congr_codiscreteWithin isOpen_univ h + @[simp] theorem logDeriv_id (x : 𝕜) : logDeriv id x = 1 / x := by simp [logDeriv_apply] diff --git a/Mathlib/Analysis/Meromorphic/Basic.lean b/Mathlib/Analysis/Meromorphic/Basic.lean index 5189416bb0018b..687bf41ab709b0 100644 --- a/Mathlib/Analysis/Meromorphic/Basic.lean +++ b/Mathlib/Analysis/Meromorphic/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.Analytic.Order public import Mathlib.Analysis.Analytic.IsolatedZeros public import Mathlib.Analysis.Calculus.Deriv.ZPow +public import Mathlib.Analysis.Calculus.LogDeriv public import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic /-! @@ -396,6 +397,10 @@ Iterated derivatives of meromorphic functions are meromorphic. | zero => exact h | succ n IH => simpa only [Function.iterate_succ', Function.comp_apply] using IH.deriv +/-- If `f` is meromorphic at a point, then so is its logarithmic derivative. -/ +@[fun_prop] theorem logDeriv [CompleteSpace 𝕜'] {f : 𝕜 → 𝕜'} (hf : MeromorphicAt f x) : + MeromorphicAt (logDeriv f) x := hf.deriv.div hf + end MeromorphicAt section smul_iff @@ -624,6 +629,9 @@ include hf in theorem iterated_deriv [CompleteSpace E] {n : ℕ} : MeromorphicOn (_root_.deriv^[n] f) U := fun z hz ↦ (hf z hz).iterated_deriv +/-- If `f` is meromorphic on a set, then so is its logarithmic derivative. -/ +protected theorem logDeriv [CompleteSpace 𝕜'] {f : 𝕜 → 𝕜'} {hf : MeromorphicOn f U} : + MeromorphicOn (logDeriv f) U := hf.deriv.div hf /-- `MeromorphicOn` is invariant under translation. -/ @[to_fun meromorphicOn_fun_comp_add_const_iff_meromorphicOn] theorem meromorphicOn_comp_add_const_iff_meromorphicOn {c : 𝕜} {U : Set 𝕜} : @@ -771,6 +779,10 @@ protected lemma deriv [CompleteSpace E] (hf : Meromorphic f) : Meromorphic (deri lemma iterated_deriv [CompleteSpace E] {n : ℕ} (hf : Meromorphic f) : Meromorphic (deriv^[n] f) := fun x ↦ (hf x).iterated_deriv +/-- If `f` is meromorphic, then so is its logarithmic derivative. -/ +@[fun_prop] protected theorem logDeriv [CompleteSpace 𝕜'] {f : 𝕜 → 𝕜'} (hf : Meromorphic f) : + Meromorphic (logDeriv f) := hf.deriv.div hf + /-- If `f` is meromorphic, if `g` agrees with `f` on a codiscrete set, then `g` is also meromorphic. -/ diff --git a/Mathlib/Analysis/Meromorphic/LogDeriv.lean b/Mathlib/Analysis/Meromorphic/LogDeriv.lean new file mode 100644 index 00000000000000..b101003fa5b421 --- /dev/null +++ b/Mathlib/Analysis/Meromorphic/LogDeriv.lean @@ -0,0 +1,183 @@ +/- +Copyright (c) 2026 Stefan Kebekus. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Stefan Kebekus using Claude Code +-/ +module + +public import Mathlib.Analysis.Meromorphic.Order + +/-! +# Meromorphic API for the Logarithmic Derivative +-/ + +@[expose] public section + +open Filter Function Set Topology + +variable + {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {𝕜' : Type*} [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] + {f g : 𝕜 → 𝕜'} {x : 𝕜} {U : Set 𝕜} + +/-! +## Arithmetic on Codiscrete Sets + +The pointwise lemma `logDeriv_mul` requires differentiability and nonvanishing of the factors at the +point in question. For meromorphic functions whose order is nowhere `⊤`, both conditions hold away +from a codiscrete set, turning the pointwise arithmetic into arithmetic of codiscrete equivalence +classes. +-/ + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `U`, the +logarithmic derivative of a product of two meromorphic functions is the sum of the logarithmic +derivatives. +-/ +@[to_fun MeromorphicOn.logDeriv_fun_mul_eventuallyEq] +theorem MeromorphicOn.logDeriv_mul_eventuallyEq (hf : MeromorphicOn f U) (hg : MeromorphicOn g U) + (h'f : ∀ x ∈ U, meromorphicOrderAt f x ≠ ⊤) (h'g : ∀ x ∈ U, meromorphicOrderAt g x ≠ ⊤) : + logDeriv (f * g) =ᶠ[codiscreteWithin U] logDeriv f + logDeriv g := by + filter_upwards [hf.analyticAt_mem_codiscreteWithin, hg.analyticAt_mem_codiscreteWithin, + hf.eventually_codiscreteWithin_apply_ne_zero h'f, + hg.eventually_codiscreteWithin_apply_ne_zero h'g] + with y h₁y h₂y h₃y h₄y + rw [Pi.add_apply, Pi.mul_def] + exact logDeriv_mul y h₃y h₄y h₁y.differentiableAt h₂y.differentiableAt + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `𝕜`, the +logarithmic derivative of a product of two meromorphic functions is the sum of the logarithmic +derivatives. +-/ +@[to_fun Meromorphic.logDeriv_fun_mul_eventuallyEq] +theorem Meromorphic.logDeriv_mul_eventuallyEq (hf : Meromorphic f) (hg : Meromorphic g) + (h'f : ∀ x, meromorphicOrderAt f x ≠ ⊤) (h'g : ∀ x, meromorphicOrderAt g x ≠ ⊤) : + logDeriv (f * g) =ᶠ[codiscrete 𝕜] logDeriv f + logDeriv g := + (meromorphicOn_univ.2 hf).logDeriv_mul_eventuallyEq (meromorphicOn_univ.2 hg) + (fun x _ ↦ h'f x) (fun x _ ↦ h'g x) + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `U`, the +logarithmic derivative of a finite product of meromorphic functions is the sum of the logarithmic +derivatives. +-/ +@[to_fun MeromorphicOn.logDeriv_fun_prod_eventuallyEq] +theorem MeromorphicOn.logDeriv_prod_eventuallyEq {ι : Type*} {s : Finset ι} {F : ι → 𝕜 → 𝕜'} + (h : ∀ i ∈ s, MeromorphicOn (F i) U) + (h' : ∀ i ∈ s, ∀ x ∈ U, meromorphicOrderAt (F i) x ≠ ⊤) : + logDeriv (∏ i ∈ s, F i) =ᶠ[codiscreteWithin U] ∑ i ∈ s, logDeriv (F i) := by + have hA : ∀ᶠ y in codiscreteWithin U, ∀ i ∈ s, AnalyticAt 𝕜 (F i) y := + (eventually_all_finset s).2 fun i hi ↦ (h i hi).analyticAt_mem_codiscreteWithin + have hN : ∀ᶠ y in codiscreteWithin U, ∀ i ∈ s, F i y ≠ 0 := + (eventually_all_finset s).2 fun i hi ↦ (h i hi).eventually_codiscreteWithin_apply_ne_zero + (h' i hi) + filter_upwards [hA, hN] with y h₁y h₂y + rw [Finset.sum_apply, Finset.prod_fn] + exact logDeriv_prod h₂y fun i hi ↦ (h₁y i hi).differentiableAt + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `𝕜`, the +logarithmic derivative of a finite product of meromorphic functions is the sum of the logarithmic +derivatives. +-/ +@[to_fun Meromorphic.logDeriv_fun_prod_eventuallyEq] +theorem Meromorphic.logDeriv_prod_eventuallyEq {ι : Type*} {s : Finset ι} {F : ι → 𝕜 → 𝕜'} + (h : ∀ i ∈ s, Meromorphic (F i)) (h' : ∀ i ∈ s, ∀ x, meromorphicOrderAt (F i) x ≠ ⊤) : + logDeriv (∏ i ∈ s, F i) =ᶠ[codiscrete 𝕜] ∑ i ∈ s, logDeriv (F i) := by + apply MeromorphicOn.logDeriv_prod_eventuallyEq (fun i hi ↦ meromorphicOn_univ.mpr (h i hi)) + aesop + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `U`, the +logarithmic derivative of a finite product of meromorphic functions is the sum of the logarithmic +derivatives. +-/ +theorem MeromorphicOn.logDeriv_finprod_eventuallyEq {ι : Type*} {F : ι → 𝕜 → 𝕜'} + (hF : (mulSupport F).Finite) (h : ∀ i, MeromorphicOn (F i) U) + (h' : ∀ i, ∀ x ∈ U, meromorphicOrderAt (F i) x ≠ ⊤) : + logDeriv (∏ᶠ i, F i) =ᶠ[codiscreteWithin U] ∑ᶠ i, logDeriv (F i) := by + have hsub : support (fun i ↦ logDeriv (F i)) ⊆ hF.toFinset := by + simp +contextual [Set.subset_def, not_imp_not, Pi.one_def] + rw [finprod_eq_prod_of_mulSupport_subset F (s := hF.toFinset) (by simp), + finsum_eq_sum_of_support_subset _ hsub] + exact logDeriv_prod_eventuallyEq (fun i _ ↦ h i) (fun i _ ↦ h' i) + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `𝕜`, the +logarithmic derivative of a finite product of meromorphic functions is the sum of the logarithmic +derivatives. +-/ +theorem Meromorphic.logDeriv_finprod_eventuallyEq {ι : Type*} {F : ι → 𝕜 → 𝕜'} + (hF : (mulSupport F).Finite) (h : ∀ i, Meromorphic (F i)) + (h' : ∀ i x, meromorphicOrderAt (F i) x ≠ ⊤) : + logDeriv (∏ᶠ i, F i) =ᶠ[codiscrete 𝕜] ∑ᶠ i, logDeriv (F i) := by + apply MeromorphicOn.logDeriv_finprod_eventuallyEq hF (fun i ↦ meromorphicOn_univ.mpr (h i)) + aesop + +/-- +Away from a codiscrete subset of `U`, the logarithmic derivative of the `n`-th power of a +meromorphic function is `n` times the logarithmic derivative. +-/ +@[to_fun MeromorphicOn.logDeriv_fun_zpow_eventuallyEq] +theorem MeromorphicOn.logDeriv_zpow_eventuallyEq (hf : MeromorphicOn f U) (n : ℤ) : + logDeriv (f ^ n) =ᶠ[codiscreteWithin U] n • logDeriv f := by + filter_upwards [hf.analyticAt_mem_codiscreteWithin] with y hy + rw [Pi.smul_apply, zsmul_eq_mul, show f ^ n = (f · ^ n) from rfl] + exact logDeriv_fun_zpow hy.differentiableAt n + +/-- +Away from a codiscrete subset of `𝕜`, the logarithmic derivative of the `n`-th power of a +meromorphic function is `n` times the logarithmic derivative. +-/ +@[to_fun Meromorphic.logDeriv_fun_zpow_eventuallyEq] +theorem Meromorphic.logDeriv_zpow_eventuallyEq (hf : Meromorphic f) (n : ℤ) : + logDeriv (f ^ n) =ᶠ[codiscrete 𝕜] n • logDeriv f := by + apply MeromorphicOn.logDeriv_zpow_eventuallyEq (meromorphicOn_univ.mpr hf) + + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `U`, the +logarithmic derivative of a finite product of integer powers of meromorphic functions is the +corresponding weighted sum of logarithmic derivatives. This is the shape of statement used in the +differentiated Poisson–Jensen formula, where the exponents are given by a divisor. +-/ +theorem MeromorphicOn.logDeriv_finprod_zpow_eventuallyEq {ι : Type*} {F : ι → 𝕜 → 𝕜'} {d : ι → ℤ} + (hd : (support d).Finite) (h : ∀ i, MeromorphicOn (F i) U) + (h' : ∀ i, ∀ x ∈ U, meromorphicOrderAt (F i) x ≠ ⊤) : + logDeriv (∏ᶠ i, F i ^ d i) + =ᶠ[codiscreteWithin U] fun z ↦ ∑ᶠ i, d i • logDeriv (F i) z := by + have hA : ∀ᶠ y in codiscreteWithin U, ∀ i ∈ hd.toFinset, AnalyticAt 𝕜 (F i) y := + (eventually_all_finset hd.toFinset).2 fun i _ ↦ (h i).analyticAt_mem_codiscreteWithin + have hN : ∀ᶠ y in codiscreteWithin U, ∀ i ∈ hd.toFinset, F i y ≠ 0 := + (eventually_all_finset hd.toFinset).2 fun i _ ↦ (h i).eventually_codiscreteWithin_apply_ne_zero + (h' i) + filter_upwards [hA, hN] with y h₁y h₂y + have h₀ : ∏ᶠ i, F i ^ d i = ∏ i ∈ hd.toFinset, F i ^ d i := + finprod_eq_prod_of_mulSupport_subset _ <| by simp +contextual [Set.subset_def, not_imp_not] + have hsub : support (fun i ↦ d i • logDeriv (F i) y) ⊆ hd.toFinset := by + simp +contextual [-support_mul, -mul_eq_zero, Set.subset_def, not_imp_not] + calc logDeriv (∏ᶠ i, F i ^ d i) y + = logDeriv (fun z ↦ ∏ i ∈ hd.toFinset, (F i ^ d i) z) y := by rw [h₀, Finset.prod_fn] + _ = ∑ i ∈ hd.toFinset, logDeriv (F i ^ d i) y := + logDeriv_prod (fun i hi ↦ zpow_ne_zero _ (h₂y i hi)) + (fun i hi ↦ ((h₁y i hi).zpow (h₂y i hi)).differentiableAt) + _ = ∑ i ∈ hd.toFinset, d i • logDeriv (F i) y := by + congr! with i hi + rw [zsmul_eq_mul, Pi.pow_def] + exact logDeriv_fun_zpow (h₁y i hi).differentiableAt (d i) + _ = ∑ᶠ i, d i • logDeriv (F i) y := (finsum_eq_sum_of_support_subset _ hsub).symm + +/-- +The logarithmic derivative converts products into sums: away from a codiscrete subset of `𝕜`, the +logarithmic derivative of a finite product of integer powers of meromorphic functions is the +corresponding weighted sum of logarithmic derivatives. This is the shape of statement used in the +differentiated Poisson–Jensen formula, where the exponents are given by a divisor. +-/ +theorem Meromorphic.logDeriv_finprod_zpow_eventuallyEq {ι : Type*} {F : ι → 𝕜 → 𝕜'} {d : ι → ℤ} + (hd : (support d).Finite) (h : ∀ i, Meromorphic (F i)) + (h' : ∀ i x, meromorphicOrderAt (F i) x ≠ ⊤) : + logDeriv (∏ᶠ i, F i ^ d i) + =ᶠ[codiscrete 𝕜] fun z ↦ ∑ᶠ i, d i • logDeriv (F i) z := by + apply MeromorphicOn.logDeriv_finprod_zpow_eventuallyEq hd (fun i ↦ meromorphicOn_univ.mpr (h i)) + aesop diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index b3efa50bacce06..72860fac7141a4 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -147,6 +147,19 @@ theorem meromorphicOrderAt_ne_top_iff_eventually_ne_zero {f : 𝕜 → E} (hf : simp_all [zpow_ne_zero, sub_ne_zero] · simp_all [meromorphicOrderAt_eq_top_iff, Eventually.frequently] +/-- +A function meromorphic on `U`, with meromorphic order nowhere `⊤`, is nonvanishing away from a +codiscrete subset of `U`. +-/ +theorem MeromorphicOn.eventually_codiscreteWithin_apply_ne_zero {U : Set 𝕜} {f : 𝕜 → E} + (hf : MeromorphicOn f U) (h'f : ∀ x ∈ U, meromorphicOrderAt f x ≠ ⊤) : + ∀ᶠ x in codiscreteWithin U, f x ≠ 0 := by + simp_rw [eventually_iff, mem_codiscreteWithin, disjoint_principal_right] + intro x hx + filter_upwards [(meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf x hx)).1 (h'f x hx)] + with y hy + simp [hy] + /-- If the order of a meromorphic function is negative, then this function converges to infinity at this point. See also the iff version `tendsto_cobounded_iff_meromorphicOrderAt_neg`. -/ lemma tendsto_cobounded_of_meromorphicOrderAt_neg (ho : meromorphicOrderAt f x < 0) : @@ -974,5 +987,34 @@ lemma meromorphicOrderAt_deriv [CompleteSpace E] {f : 𝕜 → E} {x : 𝕜} {n (hn : (↑(n + 1) : 𝕜) ≠ 0) (hf : meromorphicOrderAt f x = ↑(n + 1)) : meromorphicOrderAt (deriv f) x = ↑n := by simpa using meromorphicOrderAt_deriv_eq_sub_one hn hf +variable [CompleteSpace 𝕜] {f : 𝕜 → 𝕜} + +/-- +At zeros and poles of a meromorphic function `f`, the logarithmic derivative has a simple pole: its +meromorphic order equals `-1`. +-/ +theorem meromorphicOrderAt_logDeriv_eq_neg_one [CharZero 𝕜] (hf : MeromorphicAt f x) + (h₁ : meromorphicOrderAt f x ≠ 0) (h₂ : meromorphicOrderAt f x ≠ ⊤) : + meromorphicOrderAt (logDeriv f) x = -1 := by + lift meromorphicOrderAt f x to ℤ using h₂ with n hn + rw [logDeriv, meromorphicOrderAt_div hf.deriv hf, + meromorphicOrderAt_deriv_eq_sub_one (Int.cast_ne_zero.mpr (by exact_mod_cast h₁)) hn.symm, + ← hn] + norm_cast + simp + +/-- +At points where a meromorphic function has order zero, the meromorphic order of the logarithmic +derivative is nonnegative. +-/ +theorem meromorphicOrderAt_logDeriv_nonneg (hf : MeromorphicAt f x) + (h : meromorphicOrderAt f x = 0) : + 0 ≤ meromorphicOrderAt (logDeriv f) x := by + obtain ⟨g, h₁g, h₂g, h₃g⟩ := + (meromorphicOrderAt_eq_int_iff (n := 0) hf).1 (by exact_mod_cast h) + have h₄ : f =ᶠ[𝓝[≠] x] g := by + filter_upwards [h₃g] with z hz using by simpa using hz + rw [meromorphicOrderAt_congr (logDeriv_congr_nhdsNE h₄)] + exact (h₁g.deriv.div h₁g h₂g).meromorphicOrderAt_nonneg end deriv diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean b/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean index 7160749ecac46b..ac76b43547faea 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean @@ -130,14 +130,4 @@ lemma Complex.deriv_log_comp_eq_logDeriv {f : ℂ → ℂ} {x : ℂ} (h₁ : Dif rw [← h₁.hasDerivAt.deriv] at A simp only [logDeriv, Pi.div_apply, ← A, Function.comp_def] -protected theorem MeromorphicOn.logDeriv {𝕜 𝕜' : Type*} [NontriviallyNormedField 𝕜] - [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] [CompleteSpace 𝕜'] - {f : 𝕜 → 𝕜'} {s : Set 𝕜} (h : MeromorphicOn f s) : MeromorphicOn (logDeriv f) s := - h.deriv.div h - -protected theorem Meromorphic.logDeriv {𝕜 𝕜' : Type*} [NontriviallyNormedField 𝕜] - [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] [CompleteSpace 𝕜'] - {f : 𝕜 → 𝕜'} (h : Meromorphic f) : Meromorphic (logDeriv f) := - h.deriv.div h - end LogDeriv From e506e4611dd4a29e4e045f676a822bd314056e72 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Thu, 6 Aug 2026 08:36:46 +0000 Subject: [PATCH 1197/1300] perf(SimpleGraph/Walk/Operations): avoid costly `grind` in `drop_drop` (#42479) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#rss > Significant commits to mathlib4 @ 💬](https://leanprover.zulipchat.com/#narrow/channel/116290-rss/topic/Significant.20commits.20to.20mathlib4/near/614840976) Something in v4.33.0 seems to have made this `grind` call ~25x slower, taking about 5 seconds now. --- Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean b/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean index b028a0cc114ec1..444d1508e49932 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Walk/Operations.lean @@ -699,7 +699,8 @@ lemma drop_support_eq_support_drop_min {u v} (p : G.Walk u v) (n : ℕ) : theorem drop_drop (p : G.Walk u v) (n m : ℕ) : (p.drop n).drop m = (p.drop (n + m)).copy (drop_getVert ..).symm rfl := by apply ext_support - grind [support_copy, drop_support_eq_support_drop_min, drop_length, List.drop_drop] + simp_rw [support_copy, drop_support_eq_support_drop_min, drop_length, List.drop_drop] + grind @[simp] theorem append_take_drop_eq (p : G.Walk u v) (n : ℕ) : (p.take n).append (p.drop n) = p := by From 5c483963eff2f5f632b8e5a3f12887ad708b357e Mon Sep 17 00:00:00 2001 From: Hannah Scholz <70071345+scholzhannah@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:00:18 +0000 Subject: [PATCH 1198/1300] feat: composition lemmas about `mvfderiv` and `mvfderivWithin` (#42478) These are analogous to existing lemmas about `mfderiv(Within)`. --- .../Manifold/MFDeriv/NormedSpace.lean | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 39d5c7eee30870..3e700f91ea2f2f 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -35,7 +35,8 @@ In addition to the above, this file provides two important definitions. This file contains * results about the differentiability of scalar multiplication (`mfderiv_smul` and friends), * basic lemmas about `mvfderiv` (such as addition, subtraction, multiplication and constants), -* analogous lemmas about `mvfderivWithin`. +* analogous lemmas about `mvfderivWithin`, +* composition lemmas about `mvfderivWithin` and `mvfderiv`. -/ @@ -604,3 +605,58 @@ protected theorem MDifferentiableWithinAt.mvfderivWithin {f : M → E'} (h : MDi protected theorem MDifferentiableAt.mvfderiv {f : M → E'} (h : MDiffAt f x) : d% f x = fderivWithin 𝕜 (writtenInExtChartAt I 𝓘(𝕜, E') x f) (range I) (extChartAt I x x) := by convert! h.mfderiv + +/-! ## Composition lemmas for `mvfderiv(Within)` -/ +section + +variable {f : M' → M} {g : M → 𝕜} {x : M'} {y : M} {u : Set M} {s : Set M'} + +theorem mvfderivWithin_comp (x : M') (hg : MDiffAt[u] g (f x)) (hf : MDiffAt[s] f x) + (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) : + d[s] (g ∘ f) x = (d[u] g (f x)).comp (mfderiv[s] f x) := + mfderivWithin_comp x hg hf h hxs + +theorem mvfderivWithin_comp_of_eq (hg : MDiffAt[u] g y) (hf : MDiffAt[s] f x) + (h : s ⊆ f ⁻¹' u) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : + d[s] (g ∘ f) x = (d[u] g y).comp (mfderiv[s] f x) := + mfderivWithin_comp_of_eq hg hf h hxs hy + +theorem mvfderivWithin_comp_of_preimage_mem_nhdsWithin (x : M') (hg : MDiffAt[u] g (f x)) + (hf : MDiffAt[s] f x) (h : f ⁻¹' u ∈ 𝓝[s] x) (hxs : UniqueMDiffAt[s] x) : + d[s] (g ∘ f) x = (d[u] g (f x)).comp (mfderiv[s] f x) := + mfderivWithin_comp_of_preimage_mem_nhdsWithin x hg hf h hxs + +theorem mvfderivWithin_comp_of_preimage_mem_nhdsWithin_of_eq (x : M') (hg : MDiffAt[u] g y) + (hf : MDiffAt[s] f x) (h : f ⁻¹' u ∈ 𝓝[s] x) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : + d[s] (g ∘ f) x = (d[u] g y).comp (mfderiv[s] f x) := + mfderivWithin_comp_of_preimage_mem_nhdsWithin_of_eq x hg hf h hxs hy + +theorem mvfderiv_comp_mfderivWithin + (x : M') (hg : MDiffAt g (f x)) (hf : MDiffAt[s] f x) (hxs : UniqueMDiffAt[s] x) : + d[s] (g ∘ f) x = (d% g (f x)).comp (mfderiv[s] f x) := + mfderiv_comp_mfderivWithin x hg hf hxs + +theorem mvfderiv_comp_mfderivWithin_of_eq + (hg : MDiffAt g y) (hf : MDiffAt[s] f x) (hxs : UniqueMDiffAt[s] x) (hy : f x = y) : + d[s] (g ∘ f) x = (d% g y).comp (mfderiv[s] f x) := + mfderiv_comp_mfderivWithin_of_eq hg hf hxs hy + +theorem mvfderiv_comp (x : M') (hg : MDiffAt g (f x)) (hf : MDiffAt f x) : + d% (g ∘ f) x = (d% g (f x)).comp (mfderiv% f x) := + mfderiv_comp x hg hf + +theorem mvfderiv_comp_of_eq {y : M} (hg : MDiffAt g y) (hf : MDiffAt f x) (hy : f x = y) : + d% (g ∘ f) x = (d% g (f x)).comp (mfderiv% f x) := + mfderiv_comp_of_eq hg hf hy + +theorem mvfderiv_comp_apply + (x : M') (hg : MDiffAt g (f x)) (hf : MDiffAt f x) (v : TangentSpace% x) : + d% (g ∘ f) x v = (d% g (f x)) ((mfderiv% f x) v) := + mfderiv_comp_apply x hg hf v + +theorem mvfderiv_comp_apply_of_eq + (x : M') (hg : MDiffAt g y) (hf : MDiffAt f x) (hy : f x = y) (v : TangentSpace% x) : + d% (g ∘ f) x v = (d% g y) ((mfderiv% f x) v) := + mfderiv_comp_apply_of_eq x hg hf hy v + +end From 1aa85dfb910a0fedb00c60eb8768ee5f781c855d Mon Sep 17 00:00:00 2001 From: Stefan Kebekus <5110976+kebekus@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:10:35 +0000 Subject: [PATCH 1199/1300] doc: update docstring in Cartan.lean (#42486) Update a docstring to reflect recent progress in mathlib. --- .../Complex/ValueDistribution/Cartan.lean | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean b/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean index 1c44cf7fabd4a0..ca8a1ad15387d2 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean @@ -12,17 +12,19 @@ public import Mathlib.Analysis.Complex.ValueDistribution.Proximity.IntegralPrese /-! # Cartan's Formula -This file will, in the future, establish Cartan's classic formula, describing the characteristic -function `characteristic f ⊤ r` as a sum of two circle averages, +This file establishes Cartan's classic formula, +`ValueDistribution.characteristic_top_eq_circleAverage_add_circleAverage`, describing the +characteristic function `characteristic f ⊤ r` as a sum of two circle averages, - `circleAverage (logCounting f · r) 0 1` and - `circleAverage (fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖) 0 1`. -As a corollary, Cartan's formula implies the (surprising, non-trival) fact that the characteristic -function is monotone. +As a corollary, Cartan's formula implies the (surprisingly non-trivial) fact that the +characteristic function is monotone; this is stated in +`ValueDistribution.characteristic_monotoneOn`. -At present, this file establishes circle integrability of the function -`a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖` and computes values of the circle integral. +This file also establishes circle integrability of the function +`a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖` and computes values of the circle average. ## References @@ -90,7 +92,7 @@ theorem circleIntegrable_log_meromorphicTrailingCoeffAt : /-- Circle average of the function `fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖` that appears -in Cartan's formula, in case where `f` has a zero at the origin. +in Cartan's formula, in the case where `f` has a zero at the origin. -/ theorem circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_pos (h : 0 < meromorphicOrderAt f 0) : @@ -99,7 +101,7 @@ theorem circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_ /-- Circle average of the function `fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖` that appears -in Cartan's formula, in case where `f` has order zero at the origin. +in Cartan's formula, in the case where `f` has order zero at the origin. -/ theorem circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_eq_zero (h : meromorphicOrderAt f 0 = 0) : @@ -116,7 +118,7 @@ theorem circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_ /-- Circle average of the function `fun a ↦ log ‖meromorphicTrailingCoeffAt (f · - a) 0‖` that appears -in Cartan's formula, in case where `f` has a pole at the origin. +in Cartan's formula, in the case where `f` has a pole at the origin. -/ theorem circleAverage_log_norm_meromorphicTrailingCoeffAt_of_meromorphicOrderAt_lt_zero (h : meromorphicOrderAt f 0 < 0) : @@ -163,7 +165,7 @@ theorem circleIntegrable_logCounting (h : Meromorphic f) : **Cartan's formula** with the additive constant written explicitly as a circle average of the logarithm of the first nonzero Laurent coefficient of `f - a` at the origin. -See `circleIntegrable_logCounting` and `circleIntegrable_log_trailingCoeff_of_meromorphic` for the +See `circleIntegrable_logCounting` and `circleIntegrable_log_meromorphicTrailingCoeffAt` for the facts that the summands are actually circle integrable. -/ theorem characteristic_top_eq_circleAverage_add_circleAverage (h : Meromorphic f) (hR : R ≠ 0) : @@ -183,7 +185,7 @@ theorem characteristic_top_eq_circleAverage_add_circleAverage (h : Meromorphic f simp [logCounting_add_log_trailingCoeff_eq_circleAverage_add_logCounting_top h hR a] /-- -**Cartan's formula** in case where `0 < meromorphicOrderAt f 0`. +**Cartan's formula** in the case where `0 < meromorphicOrderAt f 0`. -/ theorem characteristic_top_eq_circleAverage_of_meromorphicOrderAt_pos (h₁f : Meromorphic f) (h₂f : 0 < meromorphicOrderAt f 0) (hR : R ≠ 0) : @@ -193,9 +195,9 @@ theorem characteristic_top_eq_circleAverage_of_meromorphicOrderAt_pos /-- Qualitative version of **Cartan's formula**: Away from the point `0`, the difference between -`characteristic f ⊤` and `circleAverage (logCounting f · ·) 0 1` is constant. This qualitative -version of Cartan's formula exists because the specific value of the constant does not matter in -practise. +`characteristic f ⊤` and `fun R ↦ circleAverage (logCounting f · R) 0 1` is constant. This +qualitative version of Cartan's formula exists because the specific value of the constant does not +matter in practice. -/ theorem characteristic_top_eq_circleAverage_add_const (h : Meromorphic f) : ∃ const, ∀ R ≠ 0, characteristic f ⊤ R = circleAverage (logCounting f · R) 0 1 + const := From 3c2d12d66f728a5a247a127559909d65e8e0988a Mon Sep 17 00:00:00 2001 From: Fabrizio Barroero <23321199+fbarroero@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:40:35 +0000 Subject: [PATCH 1200/1300] chore(NumberTheory/Ostrowski): simplify and golf proofs (#42183) Co-authored-by: fbarroero --- Mathlib/NumberTheory/Ostrowski.lean | 171 ++++++++++++---------------- 1 file changed, 70 insertions(+), 101 deletions(-) diff --git a/Mathlib/NumberTheory/Ostrowski.lean b/Mathlib/NumberTheory/Ostrowski.lean index e9dc909e070c12..27b4819c259a38 100644 --- a/Mathlib/NumberTheory/Ostrowski.lean +++ b/Mathlib/NumberTheory/Ostrowski.lean @@ -112,13 +112,12 @@ def padic (p : ℕ) [Fact p.Prime] : AbsoluteValue ℚ ℝ where toFun x := (padicNorm p x : ℝ) map_mul' := by simp only [padicNorm.mul, Rat.cast_mul, forall_const] nonneg' x := cast_nonneg.mpr <| padicNorm.nonneg x - eq_zero' x := + eq_zero' _ := ⟨fun H ↦ padicNorm.zero_of_padicNorm_eq_zero <| cast_eq_zero.mp H, fun H ↦ cast_eq_zero.mpr <| H ▸ padicNorm.zero (p := p)⟩ - add_le' x y := by exact_mod_cast padicNorm.triangle_ineq x y + add_le' := mod_cast padicNorm.triangle_ineq -@[simp] lemma padic_eq_padicNorm (p : ℕ) [Fact p.Prime] (r : ℚ) : - padic p r = padicNorm p r := rfl +@[simp] lemma padic_eq_padicNorm (p : ℕ) [Fact p.Prime] (r : ℚ) : padic p r = padicNorm p r := rfl lemma padic_le_one (p : ℕ) [Fact p.Prime] (n : ℤ) : padic p n ≤ 1 := by simp only [padic_eq_padicNorm] @@ -142,7 +141,7 @@ lemma exists_minimal_nat_zero_lt_and_lt_one : set P := {m : ℕ | 0 < f ↑m ∧ f ↑m < 1} -- p is going to be the minimum of this set. have hP : P.Nonempty := ⟨n, map_pos_of_ne_zero f (Nat.cast_ne_zero.mpr hn1), lt_of_le_of_ne (bdd n) hn2⟩ - exact ⟨sInf P, Nat.sInf_mem hP, fun m hm ↦ Nat.sInf_le hm⟩ + exact ⟨sInf P, Nat.sInf_mem hP, fun _ hm ↦ Nat.sInf_le hm⟩ -- ## Step 2: p is prime @@ -151,25 +150,18 @@ variable {p : ℕ} (hp0 : 0 < f p) (hp1 : f p < 1) (hmin : ∀ m : ℕ, 0 < f m include hp0 hp1 hmin in /-- The minimal positive integer with absolute value smaller than 1 is a prime number. -/ lemma is_prime_of_minimal_nat_zero_lt_and_lt_one : p.Prime := by - rw [← Nat.irreducible_iff_nat_prime] - constructor -- Two goals: p is not a unit and any product giving p must contain a unit. - · rw [Nat.isUnit_iff] - rintro rfl - simp only [Nat.cast_one, map_one, lt_self_iff_false] at hp1 - · rintro a b rfl - rw [Nat.isUnit_iff, Nat.isUnit_iff] - by_contra! ⟨ha₁, hb₁⟩ - obtain ⟨ha₀, hb₀⟩ : a ≠ 0 ∧ b ≠ 0 := by - refine mul_ne_zero_iff.mp fun h ↦ ?_ - rwa [h, Nat.cast_zero, map_zero, lt_self_iff_false] at hp0 - have hap : a < a * b := lt_mul_of_one_lt_right (by lia) (by lia) - have hbp : b < a * b := lt_mul_of_one_lt_left (by lia) (by lia) - have ha := - le_of_not_gt <| not_and.mp ((hmin a).mt hap.not_ge) (map_pos_of_ne_zero f (mod_cast ha₀)) - have hb := - le_of_not_gt <| not_and.mp ((hmin b).mt hbp.not_ge) (map_pos_of_ne_zero f (mod_cast hb₀)) - rw [Nat.cast_mul, map_mul] at hp1 - exact ((one_le_mul_of_one_le_of_one_le ha hb).trans_lt hp1).false + have hp2 : 2 ≤ p := by + by_contra! hp + interval_cases p <;> grind + rw [Nat.prime_iff_not_exists_mul_eq] + refine ⟨hp2, ?_⟩ + rintro ⟨a, b, ha, hb, rfl⟩ + obtain ⟨ha₀, hb₀⟩ := mul_ne_zero_iff.mp (by omega : a * b ≠ 0) + have h {n : ℕ} (hn₀ : n ≠ 0) (hn : n < a * b) : 1 ≤ f n := by + by_contra! hn₁ + exact (not_le_of_gt hn) <| hmin n ⟨map_pos_of_ne_zero f (mod_cast hn₀), hn₁⟩ + rw [Nat.cast_mul, map_mul] at hp1 + exact not_le_of_gt hp1 <| one_le_mul_of_one_le_of_one_le (h ha₀ ha) (h hb₀ hb) -- ## Step 3: if p does not divide m, then f m = 1 @@ -207,9 +199,7 @@ lemma eq_one_of_not_dvd {m : ℕ} (hpm : ¬ p ∣ m) : f m = 1 := by _ ≤ f (a * p ^ k) + f (b * m ^ k) := f.add_le' .. _ ≤ 1 * (f p) ^ k + 1 * (f m) ^ k := by simp only [map_mul, map_pow] - gcongr - all_goals rw [← apply_natAbs_eq]; apply bdd - _ = (f p) ^ k + (f m) ^ k := by simp only [one_mul] + gcongr <;> simpa only [← apply_natAbs_eq] using bdd _ _ < 1 := by have hm₀ : 0 < f m := f.pos <| Nat.cast_ne_zero.mpr fun H ↦ hpm <| H ▸ dvd_zero p linarith only [le_half hp0 hp1 le_sup_left, le_half hm₀ hm le_sup_right] @@ -219,10 +209,10 @@ lemma eq_one_of_not_dvd {m : ℕ} (hpm : ¬ p ∣ m) : f m = 1 := by include hp0 hp1 hmin in /-- The absolute value of `p` is `p ^ (-t)` for some positive real number `t`. -/ lemma exists_pos_eq_pow_neg : ∃ t : ℝ, 0 < t ∧ f p = p ^ (-t) := by - have pprime := is_prime_of_minimal_nat_zero_lt_and_lt_one hp0 hp1 hmin - refine ⟨- logb p (f p), Left.neg_pos_iff.mpr <| logb_neg (mod_cast pprime.one_lt) hp0 hp1, ?_⟩ - rw [neg_neg] - exact (rpow_logb (mod_cast pprime.pos) (mod_cast pprime.ne_one) hp0).symm + have hp : (1 : ℝ) < p := + mod_cast (is_prime_of_minimal_nat_zero_lt_and_lt_one hp0 hp1 hmin).one_lt + exact ⟨-logb p (f p), neg_pos.mpr <| logb_neg hp hp0 hp1, by + simpa using (rpow_logb (zero_lt_one.trans hp) hp.ne' hp0).symm⟩ -- ## Non-archimedean case: end goal @@ -230,30 +220,23 @@ include hf_nontriv bdd in /-- If `f` is bounded and not trivial, then it is equivalent to a p-adic absolute value. -/ theorem equiv_padic_of_bounded : ∃! p, ∃ (_ : Fact p.Prime), f.IsEquiv (padic p) := by - obtain ⟨p, hfp, hmin⟩ := exists_minimal_nat_zero_lt_and_lt_one hf_nontriv bdd - have hprime := is_prime_of_minimal_nat_zero_lt_and_lt_one hfp.1 hfp.2 hmin - have hprime_fact : Fact p.Prime := ⟨hprime⟩ - obtain ⟨t, h⟩ := exists_pos_eq_pow_neg hfp.1 hfp.2 hmin + obtain ⟨p, ⟨hp0, hp1⟩, hmin⟩ := exists_minimal_nat_zero_lt_and_lt_one hf_nontriv bdd + have hp := is_prime_of_minimal_nat_zero_lt_and_lt_one hp0 hp1 hmin + have : Fact p.Prime := ⟨hp⟩ + obtain ⟨t, ht, hpt⟩ := exists_pos_eq_pow_neg hp0 hp1 hmin simp_rw [← exists_nat_rpow_iff_isEquiv] - refine ⟨p, ⟨hprime_fact, t⁻¹, inv_pos_of_pos h.1, fun n ↦ ?_⟩, fun q ⟨hq_prime, h_equiv⟩ ↦ ?_⟩ - · have ht : t⁻¹ ≠ 0 := inv_ne_zero h.1.ne' - rcases eq_or_ne n 0 with rfl | hn -- Separate cases n = 0 and n ≠ 0 - · simp [ht] - · /- Any natural number can be written as a power of p times a natural number not divisible - by p -/ - rcases Nat.exists_eq_pow_mul_and_not_dvd hn p hprime.ne_one with ⟨e, m, hpm, rfl⟩ - simp only [Nat.cast_mul, Nat.cast_pow, map_mul, map_pow, h.2, - eq_one_of_not_dvd bdd hfp.1 hfp.2 hmin hpm, padic_eq_padicNorm, - padicNorm.padicNorm_p_of_prime, cast_inv, cast_natCast, inv_pow] - rw [← padicNorm.nat_eq_one_iff] at hpm - simp only [← rpow_natCast, p.cast_nonneg, ← rpow_mul, neg_mul, mul_one, ← rpow_neg, hpm, - cast_one] - field_simp [h.1.ne'] - · by_contra! hne - apply hq_prime.elim.ne_one - rw [ne_comm, ← Nat.coprime_primes hprime hq_prime.elim, hprime.coprime_iff_not_dvd] at hne - rcases h_equiv with ⟨c, _, h_eq⟩ - simpa [eq_one_of_not_dvd bdd hfp.1 hfp.2 hmin hne] using h_eq q + refine ⟨p, ⟨inferInstance, t⁻¹, inv_pos.mpr ht, fun n ↦ ?_⟩, fun q ⟨hq, heq⟩ ↦ ?_⟩ + · rcases eq_or_ne n 0 with rfl | hn + · simp [ht.ne'] + · rcases Nat.exists_eq_pow_mul_and_not_dvd hn p hp.ne_one with ⟨_, m, hpm, rfl⟩ + have := (padicNorm.nat_eq_one_iff m).mpr hpm + simp_all [← rpow_natCast, ← rpow_mul, mul_comm t, mul_inv_cancel_right₀ ht.ne', + eq_one_of_not_dvd bdd hp0 hp1 hmin hpm] + · by_contra! hpq + apply hq.elim.ne_one + rw [ne_comm, ← Nat.coprime_primes hp hq.elim, hp.coprime_iff_not_dvd] at hpq + rcases heq with ⟨_, _, heq⟩ + simpa [eq_one_of_not_dvd bdd hp0 hp1 hmin hpq] using heq q end Non_archimedean @@ -269,13 +252,12 @@ Every unbounded absolute value on `ℚ` is equivalent to the standard absolute v unique real place of `ℚ`. -/ def real : AbsoluteValue ℚ ℝ where toFun x := |x| - map_mul' x y := by simp - nonneg' x := by simp - eq_zero' x := by simp - add_le' x y := by simpa using abs_add_le (x : ℝ) (y : ℝ) + map_mul' := by simp + nonneg' := by simp + eq_zero' := by simp + add_le' := by simp [abs_add_le] -@[simp] lemma real_eq_abs (r : ℚ) : real r = |r| := - (cast_abs r).symm +@[simp] lemma real_eq_abs (r : ℚ) : real r = |r| := (cast_abs r).symm -- ## Preliminary result @@ -285,21 +267,20 @@ expansion of `n` in base `m`. -/ lemma apply_le_sum_digits (n : ℕ) {m : ℕ} (hm : 1 < m) : f n ≤ ((Nat.digits m n).mapIdx fun i _ ↦ m * (f m) ^ i).sum := by set L := Nat.digits m n - set L' : List ℚ := List.map Nat.cast (L.mapIdx fun i a ↦ (a * m ^ i)) with hL' + set L' : List ℚ := List.map Nat.cast (L.mapIdx fun i a ↦ a * m ^ i) -- If `c` is a digit in the expansion of `n` in base `m`, then `f c` is less than `m`. have hcoef {c : ℕ} (hc : c ∈ Nat.digits m n) : f c < m := lt_of_le_of_lt (f.apply_nat_le_self c) (mod_cast Nat.digits_lt_base hm hc) calc f n = f ((Nat.ofDigits m L : ℕ) : ℚ) := by rw [Nat.ofDigits_digits m n] - _ = f L'.sum := by rw [Nat.ofDigits_eq_sum_mapIdx]; norm_cast + _ = f L'.sum := by simp [L', Nat.ofDigits_eq_sum_mapIdx] _ ≤ (L'.map f).sum := listSum_le f L' _ ≤ (L.mapIdx fun i _ ↦ m * (f m) ^ i).sum := ?_ - simp only [hL', List.mapIdx_eq_zipIdx_map, List.map_map] + simp only [List.mapIdx_eq_zipIdx_map, List.map_map, L'] refine List.sum_le_sum fun ⟨a, i⟩ hia ↦ ?_ - dsimp only [Function.comp_apply, Function.uncurry_apply_pair] replace hia := List.mem_zipIdx hia - push_cast - rw [map_mul, map_pow] + simp only [Function.comp_apply, Nat.cast_mul, Nat.cast_pow, AbsoluteValue.map_mul, + AbsoluteValue.map_pow] refine mul_le_mul_of_nonneg_right ?_ <| pow_nonneg (f.nonneg _) i simp only [zero_le, zero_add, true_and] at hia exact (hcoef (List.mem_iff_get.mpr ⟨⟨i, hia.1⟩, hia.2.symm⟩)).le @@ -318,21 +299,21 @@ lemma one_lt_of_not_bounded (notbdd : ¬ ∀ n : ℕ, f n ≤ 1) {n₀ : ℕ} (h _ ≤ (L.mapIdx fun _ _ ↦ (n₀ : ℝ)).sum := by simp only [List.mapIdx_eq_zipIdx_map] refine List.sum_le_sum fun ⟨i, a⟩ _ ↦ ?_ - simp only - exact (mul_le_mul_of_nonneg_right (mod_cast le_refl n₀) (by positivity)).trans <| - mul_le_of_le_one_right (by positivity) (pow_le_one₀ (by positivity) h) + exact mul_le_of_le_one_right (by positivity) (pow_le_one₀ (by positivity) h) _ = n₀ * (Nat.log n₀ m + 1) := by rw [List.mapIdx_eq_zipIdx_map, List.eq_replicate_of_mem (a := (n₀ : ℝ)) (l := L.zipIdx.map _), List.sum_replicate, List.length_map, List.length_zipIdx, nsmul_eq_mul, mul_comm, Nat.length_digits n₀ m hn₀ (ne_zero_of_lt hm), Nat.cast_add_one] simp +contextual - _ ≤ n₀ * (logb n₀ m + 1) := by gcongr; exact natLog_le_logb .. + _ ≤ n₀ * (logb n₀ m + 1) := by + gcongr + exact natLog_le_logb .. -- For h_ineq2 we need to exclude the case n = 0. rcases eq_or_ne n 0 with rfl | h₀ · simp have h_ineq2 (k : ℕ) (hk : 0 < k) : f n ≤ (n₀ * (logb n₀ n + 1)) ^ (k : ℝ)⁻¹ * k ^ (k : ℝ)⁻¹ := by - have : 0 ≤ logb n₀ n := logb_nonneg (one_lt_cast.mpr hn₀) (mod_cast Nat.one_le_of_lt h₀.bot_lt) + have : 0 ≤ logb n₀ n := logb_nonneg (mod_cast hn₀) (mod_cast one_le_iff_ne_zero.mpr h₀) calc f n = (f ↑(n ^ k)) ^ (k : ℝ)⁻¹ := by rw [Nat.cast_pow, map_pow, ← rpow_natCast, rpow_rpow_inv (by positivity) (by positivity)] @@ -351,9 +332,8 @@ lemma one_lt_of_not_bounded (notbdd : ¬ ∀ n : ℕ, f n ≤ 1) {n₀ : ℕ} (h rcases eq_or_ne n 1 with rfl | h₁ · simp refine le_of_tendsto_of_tendsto tendsto_const_nhds ?_ (eventually_atTop.mpr ⟨1, h_ineq2⟩) - nth_rw 2 [← mul_one 1] have : 0 < logb n₀ n := logb_pos (mod_cast hn₀) (by norm_cast; lia) - exact (tendsto_const_rpow_inv (by positivity)).mul tendsto_nat_rpow_inv + simpa using (tendsto_const_rpow_inv (by positivity)).mul tendsto_nat_rpow_inv -- ## Step 2: given m, n ≥ 2 and |m| = m^s, |n| = n^t for s, t > 0, we have t ≤ s @@ -370,27 +350,23 @@ private lemma param_upperbound {k : ℕ} (hk : k ≠ 0) : have h_ineq1 {m n : ℕ} (hm : 1 < m) (hn : 1 < n) : f n ≤ (m * f m / (f m - 1)) * f m ^ logb m n := by let d := Nat.log m n + have hfm := one_lt_of_not_bounded notbdd hm calc f n ≤ ((Nat.digits m n).mapIdx fun i _ ↦ m * f m ^ i).sum := apply_le_sum_digits n hm _ = m * ((Nat.digits m n).mapIdx fun i _ ↦ f m ^ i).sum := list_mul_sum (m.digits n) (f m) m _ = m * ((f m ^ (d + 1) - 1) / (f m - 1)) := by - rw [list_geom _ (ne_of_gt (one_lt_of_not_bounded notbdd hm)), - ← Nat.length_digits m n hm (ne_zero_of_lt hn)] + rw [list_geom _ hfm.ne', ← Nat.length_digits m n hm (ne_zero_of_lt hn)] _ ≤ m * ((f m ^ (d + 1)) / (f m - 1)) := by - gcongr - · linarith only [one_lt_of_not_bounded notbdd hm] - · simp + gcongr; linarith _ = ↑m * f ↑m / (f ↑m - 1) * f ↑m ^ d := by ring _ ≤ ↑m * f ↑m / (f ↑m - 1) * f ↑m ^ logb ↑m ↑n := by gcongr - · exact (expr_pos hm notbdd).le - · rw [← rpow_natCast, rpow_le_rpow_left_iff (one_lt_of_not_bounded notbdd hm)] - exact natLog_le_logb n m - apply le_of_pow_le_pow_left₀ hk <| mul_nonneg (rpow_nonneg (expr_pos hm notbdd).le _) - (rpow_nonneg (apply_nonneg f ↑m) _) + rw [← rpow_natCast, rpow_le_rpow_left_iff hfm] + exact natLog_le_logb n m + have he := expr_pos hm notbdd + apply le_of_pow_le_pow_left₀ hk (by positivity) nth_rewrite 2 [← rpow_natCast] - rw [mul_rpow (rpow_nonneg (expr_pos hm notbdd).le _) (rpow_nonneg (apply_nonneg f ↑m) _), - ← rpow_mul (expr_pos hm notbdd).le, ← rpow_mul (apply_nonneg f ↑m), + rw [mul_rpow (by positivity) (by positivity), ← rpow_mul he.le, ← rpow_mul (apply_nonneg f ↑m), inv_mul_cancel₀ (mod_cast hk), rpow_one, mul_comm (logb ..)] calc (f n) ^ k = f ↑(n ^ k) := by simp @@ -426,33 +402,26 @@ include notbdd in `ℚ`. -/ theorem equiv_real_of_unbounded : f.IsEquiv real := by obtain ⟨m, hm⟩ := Classical.exists_not_of_not_forall notbdd + have hfm1 : 1 < f m := lt_of_not_ge hm have oneltm : 1 < m := by contrapose! hm rcases le_one_iff_eq_zero_or_eq_one.mp hm with rfl | rfl <;> simp rw [← exists_nat_rpow_iff_isEquiv] set s := logb m (f m) with hs - refine ⟨s⁻¹, - inv_pos.mpr (logb_pos (Nat.one_lt_cast.mpr oneltm) (one_lt_of_not_bounded notbdd oneltm)), - fun n ↦ ?_⟩ + have hs0 : 0 < s := hs ▸ logb_pos (mod_cast oneltm) hfm1 + refine ⟨s⁻¹, inv_pos.mpr hs0, fun n ↦ ?_⟩ rcases lt_trichotomy n 1 with h | rfl | h · obtain rfl : n = 0 := by lia - have : (logb (↑m) (f ↑m))⁻¹ ≠ 0 := by - simp only [ne_eq, inv_eq_zero, logb_eq_zero, Nat.cast_eq_zero, Nat.cast_eq_one, map_eq_zero, - not_or] - exact ⟨ne_zero_of_lt oneltm, oneltm.ne', by norm_cast, - ne_zero_of_lt oneltm, ne_of_not_le hm, by linarith only [apply_nonneg f ↑m]⟩ - simp [hs, this] + simp [hs0.ne'] · simp · simp only [real_eq_abs, abs_cast, Rat.cast_natCast] - rw [rpow_inv_eq (apply_nonneg f ↑n) (Nat.cast_nonneg n) - (logb_ne_zero_of_pos_of_ne_one (one_lt_cast.mpr oneltm) (by linarith only [hm]) - (by linarith only [hm]))] + rw [rpow_inv_eq (by positivity) (by positivity) hs0.ne'] have hfm : f m = m ^ s := by - rw [rpow_logb (mod_cast zero_lt_of_lt oneltm) (mod_cast oneltm.ne') (by linarith only [hm])] + rw [rpow_logb (by positivity) (by norm_cast; omega) (zero_lt_one.trans hfm1)] have hfn : f n = n ^ logb n (f n) := by - rw [rpow_logb (mod_cast zero_lt_of_lt h) (mod_cast h.ne') - (by apply map_pos_of_ne_zero; exact_mod_cast ne_zero_of_lt h)] - rwa [← hs, eq_of_eq_pow oneltm h notbdd hfm hfn] + rw [rpow_logb (by positivity) (by norm_cast; omega) + (map_pos_of_ne_zero f (by exact_mod_cast ne_zero_of_lt h))] + rw [hfn, ← eq_of_eq_pow oneltm h notbdd hfm hfn] end Archimedean From 5edf93c0f3d1f3d509c42c888931b49be5c06816 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:50:20 +0000 Subject: [PATCH 1201/1300] chore(RingTheory): fix left/right convention on `Ideal.mul_le_{left,right}` (#42112) Swap `Ideal.mul_le_left` and `Ideal.mul_le_right` so that they follow the left/right naming convention. Co-authored-by: NoahW314 --- .../RingTheory/AdicCompletion/Algebra.lean | 2 +- .../RingTheory/DedekindDomain/Different.lean | 8 +++--- .../DedekindDomain/Factorization.lean | 2 +- .../DedekindDomain/Ideal/Lemmas.lean | 2 +- Mathlib/RingTheory/DividedPowers/Basic.lean | 4 +-- .../RingTheory/DividedPowers/SubDPIdeal.lean | 4 +-- Mathlib/RingTheory/Extension/Basic.lean | 2 +- .../RingTheory/Extension/Cotangent/Basis.lean | 2 +- Mathlib/RingTheory/Finiteness/Ideal.lean | 6 ++--- .../RingTheory/Finiteness/NilpotentKer.lean | 2 +- Mathlib/RingTheory/Ideal/IsPrimary.lean | 2 +- Mathlib/RingTheory/Ideal/Operations.lean | 26 +++++++++---------- Mathlib/RingTheory/Ideal/Pure.lean | 2 +- .../RingTheory/Ideal/Quotient/Operations.lean | 8 +++--- .../Ideal/Quotient/PowTransition.lean | 2 +- Mathlib/RingTheory/Kaehler/JacobiZariski.lean | 2 +- Mathlib/RingTheory/PicardGroup.lean | 2 +- .../RingTheory/Polynomial/ContentIdeal.lean | 4 +-- .../PrincipalIdealDomainOfPrime.lean | 2 +- Mathlib/RingTheory/Smooth/Quotient.lean | 8 +++--- Mathlib/RingTheory/Spectrum/Prime/Basic.lean | 8 +++--- 21 files changed, 50 insertions(+), 50 deletions(-) diff --git a/Mathlib/RingTheory/AdicCompletion/Algebra.lean b/Mathlib/RingTheory/AdicCompletion/Algebra.lean index 07afcc4ab70450..6c460f5c90fc5a 100644 --- a/Mathlib/RingTheory/AdicCompletion/Algebra.lean +++ b/Mathlib/RingTheory/AdicCompletion/Algebra.lean @@ -158,7 +158,7 @@ theorem surjective_evalₐ (n : ℕ) : Function.Surjective (evalₐ I n) := by simp only [evalₐ, smul_eq_mul, Ideal.quotientEquivAlgOfEq_coe_eq_factorₐ, AlgHom.coe_comp] apply Function.Surjective.comp - · exact factor_surjective Ideal.mul_le_right + · exact factor_surjective Ideal.mul_le_left · exact eval_surjective I R n set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index 630a7421db36a6..058f424ca2cb47 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -676,7 +676,7 @@ lemma aeval_derivative_mem_differentIdeal aeval x (derivative (minpoly A x)) ∈ differentIdeal A B := by refine SetLike.le_def.mp ?_ (Ideal.mem_span_singleton_self _) rw [← conductor_mul_differentIdeal A K L x hx] - exact Ideal.mul_le_left + exact Ideal.mul_le_right end IsIntegrallyClosed section @@ -762,7 +762,7 @@ theorem not_dvd_differentIdeal_of_intTrace_not_mem simp at hx let : Algebra (A ⧸ p) (B ⧸ Q) := Ideal.Quotient.algebraQuotientOfLEComap (by rw [← Ideal.map_le_iff_le_comap, ← hP] - exact Ideal.mul_le_left) + exact Ideal.mul_le_right) let K := FractionRing A let L := FractionRing B have : IsLocalization (Algebra.algebraMapSubmonoid B A⁰) L := @@ -815,7 +815,7 @@ theorem not_dvd_differentIdeal_of_isCoprime_of_isSeparable ¬ P ∣ differentIdeal A B := by let : Algebra (A ⧸ p) (B ⧸ Q) := Ideal.Quotient.algebraQuotientOfLEComap (by rw [← Ideal.map_le_iff_le_comap, ← hP] - exact Ideal.mul_le_left) + exact Ideal.mul_le_right) have : IsScalarTower A (A ⧸ p) (B ⧸ Q) := .of_algebraMap_eq' rfl have : Module.Finite (A ⧸ p) (B ⧸ Q) := Module.Finite.of_restrictScalars_finite A (A ⧸ p) (B ⧸ Q) @@ -843,7 +843,7 @@ theorem not_dvd_differentIdeal_of_isCoprime refine ‹p.IsMaximal›.eq_of_le ?_ ?_ · simpa using ‹P.IsMaximal›.ne_top · rw [← Ideal.map_le_iff_le_comap, ← hP] - exact Ideal.mul_le_right + exact Ideal.mul_le_left exact not_dvd_differentIdeal_of_isCoprime_of_isSeparable A P Q hPQ hP lemma dvd_differentIdeal_of_not_isSeparable diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 0e65d551e18789..14c51c10eac37a 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -630,7 +630,7 @@ lemma IsDedekindDomain.exists_sup_span_eq {I J : Ideal R} (hIJ : I ≤ J) (hI : choose! a ha ha' using fun p hps ↦ SetLike.exists_of_lt (this p hps) obtain ⟨K, hK⟩ : J ∣ Ideal.span {∑ p ∈ s, a p} := by rw [Ideal.dvd_iff_le, Ideal.span_singleton_le_iff_mem] - exact sum_mem fun p hp ↦ Ideal.mul_le_right (ha p hp) + exact sum_mem fun p hp ↦ Ideal.mul_le_left (ha p hp) refine ⟨_, _, hK.symm, ?_⟩ by_contra H obtain ⟨p, hp, h⟩ := Ideal.exists_le_maximal _ H diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean index 5bec1fe98c3ed3..be1ea5737ab1af 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal/Lemmas.lean @@ -267,7 +267,7 @@ lemma mul_iInf (I : Ideal A) {ι : Type*} [Nonempty ι] (J : ι → Ideal A) : by_cases hI : I = 0 · simp [hI] refine (le_iInf fun i ↦ mul_mono_right (iInf_le _ _)).antisymm ?_ - have H : ⨅ i, I * J i ≤ I := (iInf_le _ (Nonempty.some ‹_›)).trans mul_le_right + have H : ⨅ i, I * J i ≤ I := (iInf_le _ (Nonempty.some ‹_›)).trans mul_le_left obtain ⟨K, hK⟩ := dvd_iff_le.mpr H grw [hK, le_iInf (a := K) fun i ↦ ?_] rw [← mul_le_mul_iff_of_pos_left (a := I), ← hK] diff --git a/Mathlib/RingTheory/DividedPowers/Basic.lean b/Mathlib/RingTheory/DividedPowers/Basic.lean index ed93b1f1f92b75..dfcd7b6c18d184 100644 --- a/Mathlib/RingTheory/DividedPowers/Basic.lean +++ b/Mathlib/RingTheory/DividedPowers/Basic.lean @@ -247,8 +247,8 @@ theorem coincide_on_smul {J : Ideal A} (hJ : DividedPowers J) {n : ℕ} (ha : a ← hJ.factorial_mul_dpow_eq_pow hb, ← hI.factorial_mul_dpow_eq_pow ha] ring | add x hx y hy hx' hy' => - rw [hI.dpow_add (mul_le_right hx) (mul_le_right hy), - hJ.dpow_add (mul_le_left hx) (mul_le_left hy)] + rw [hI.dpow_add (mul_le_left hx) (mul_le_left hy), + hJ.dpow_add (mul_le_right hx) (mul_le_right hy)] apply sum_congr rfl intro k _ rw [hx', hy'] diff --git a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean index a9253e9a6fa94b..1702ec941f74b1 100644 --- a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean +++ b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean @@ -261,7 +261,7 @@ See [P. Berthelot, *Cohomologie cristalline des schémas de caractéristique $p$ (Proposition 1.6.1 (i))][Berthelot-1974] -/ def prod (J : Ideal A) : SubDPIdeal hI where carrier := I • J - isSubideal := mul_le_right + isSubideal := mul_le_left dpow_mem m hm x hx := by induction hx using Submodule.smul_induction_on' generalizing m with | smul a ha b hb => @@ -269,7 +269,7 @@ def prod (J : Ideal A) : SubDPIdeal hI where exact Submodule.mul_mem_mul (J.pow_mem_of_mem hb m (zero_lt_iff.mpr hm)) (hI.dpow_mem hm ha) | add x hx y hy hx' hy' => - rw [hI.dpow_add' (mul_le_right hx) (mul_le_right hy)] + rw [hI.dpow_add' (mul_le_left hx) (mul_le_left hy)] apply Submodule.sum_mem (I • J) intro k _ by_cases hk0 : k = 0 diff --git a/Mathlib/RingTheory/Extension/Basic.lean b/Mathlib/RingTheory/Extension/Basic.lean index d47b5ad3073e0b..9d6bafbb761322 100644 --- a/Mathlib/RingTheory/Extension/Basic.lean +++ b/Mathlib/RingTheory/Extension/Basic.lean @@ -550,7 +550,7 @@ noncomputable def cotangentEquiv : S ⊗[P.Ring] P.ker ≃ₗ[S] P.Cotangent := simp only [mk_apply, LinearMap.liftBaseChange_tmul, one_smul, Cotangent.mk_eq_zero_iff, pow_two] at hx ⊢ refine Submodule.smul_induction_on' (p := fun x (hx : x ∈ P.ker * P.ker) ↦ - (1 : S) ⊗ₜ[P.Ring] (⟨x, Ideal.mul_le_right hx⟩ : P.ker) = 0) (hx := hx) ?_ ?_ + (1 : S) ⊗ₜ[P.Ring] (⟨x, Ideal.mul_le_left hx⟩ : P.ker) = 0) (hx := hx) ?_ ?_ · intro r hr s hs trans (r • 1) ⊗ₜ[P.Ring] ⟨s, hs⟩ · rw [smul_tmul]; rfl diff --git a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean index 43b653c5d808e2..71f00c3082f357 100644 --- a/Mathlib/RingTheory/Extension/Cotangent/Basis.lean +++ b/Mathlib/RingTheory/Extension/Cotangent/Basis.lean @@ -314,7 +314,7 @@ public lemma exists_presentation_of_basis_cotangent [Algebra.FinitePresentation rw [← Submodule.comap_le_comap_iff_of_le_range (f := P.ker.subtype) (by simp), Submodule.comap_subtype_self, Submodule.comap_sup_of_injective P.ker.subtype_injective (by simpa using hJ) - (by simp [Ideal.mul_le_left]), + (by simp [Ideal.mul_le_right]), Submodule.comap_smul'' P.ker.subtype_injective (by simp)] simp only [Submodule.comap_subtype_self, J] rw [← Submodule.coe_subtype, Ideal.span, Set.range_comp, ← Submodule.map_span, diff --git a/Mathlib/RingTheory/Finiteness/Ideal.lean b/Mathlib/RingTheory/Finiteness/Ideal.lean index d672469d49a5a8..8f122bb341c221 100644 --- a/Mathlib/RingTheory/Finiteness/Ideal.lean +++ b/Mathlib/RingTheory/Finiteness/Ideal.lean @@ -68,10 +68,10 @@ theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) ( obtain ⟨m, hm⟩ := hK fun x hx => hJK <| mem_sup_right hx use n + m rw [← add_eq_sup, add_pow, sum_eq_sup, Finset.sup_le_iff] - refine fun i _ => mul_le_right.trans ?_ + refine fun i _ => mul_le_left.trans ?_ obtain h | h := le_or_gt n i - · exact mul_le_right.trans ((pow_le_pow_right h).trans hn) - · exact mul_le_left.trans ((pow_le_pow_right (by lia)).trans hm) + · exact mul_le_left.trans ((pow_le_pow_right h).trans hn) + · exact mul_le_right.trans ((pow_le_pow_right (by lia)).trans hm) theorem exists_pow_le_of_le_radical_of_fg_radical {R : Type*} [CommSemiring R] {I J : Ideal R} (hIJ : I ≤ J.radical) (hJ : J.radical.FG) : diff --git a/Mathlib/RingTheory/Finiteness/NilpotentKer.lean b/Mathlib/RingTheory/Finiteness/NilpotentKer.lean index e33b8a92bd02e4..1a4e49e1486ee8 100644 --- a/Mathlib/RingTheory/Finiteness/NilpotentKer.lean +++ b/Mathlib/RingTheory/Finiteness/NilpotentKer.lean @@ -54,7 +54,7 @@ lemma Module.finite_of_surjective_of_ker_le_nilradical refine Submodule.liftQ _ ((Submodule.mkQ _).comp (I ^ n).subtype) ?_ rw [LinearMap.ker_comp, ← Submodule.map_le_map_iff_of_injective (I ^ n).subtype_injective, Submodule.map_smul'', Submodule.map_comap_eq] - simpa [pow_succ'] using Ideal.mul_le_left (I := I) (J := I ^ n) + simpa [pow_succ'] using Ideal.mul_le_right (I := I) (J := I ^ n) convert! Module.Finite.fg_top.map (ψ.restrictScalars R) using 1 suffices LinearMap.ker φ.toLinearMap = Submodule.map (I ^ (n + 1)).mkQ (I ^ n) by simpa [LinearMap.range_restrictScalars, ψ, LinearMap.range_comp, Submodule.range_liftQ] diff --git a/Mathlib/RingTheory/Ideal/IsPrimary.lean b/Mathlib/RingTheory/Ideal/IsPrimary.lean index 632664ee9441df..698106b6d3cb2e 100644 --- a/Mathlib/RingTheory/Ideal/IsPrimary.lean +++ b/Mathlib/RingTheory/Ideal/IsPrimary.lean @@ -58,7 +58,7 @@ theorem isPrimary_of_isMaximal_radical {I : Ideal R} (hi : IsMaximal (radical I) by_cases h : I + span {y} = ⊤ · rw [← span_singleton_le_iff_mem, ← mul_top (span {x}), ← h, mul_add, span_singleton_mul_span_singleton, add_le_iff, span_singleton_le_iff_mem] - exact Or.inl ⟨mul_le_left, hxy⟩ + exact Or.inl ⟨mul_le_right, hxy⟩ · obtain ⟨m, hm, hy⟩ := exists_le_maximal (I + span {y}) h rw [add_le_iff, span_singleton_le_iff_mem, ← hm.isPrime.radical_le_iff] at hy exact Or.inr (hi.eq_of_le hm.ne_top hy.1 ▸ hy.2) diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 24e38b0ab03ee8..e203e721574254 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -284,27 +284,27 @@ theorem pow_mem_pow {x : R} (hx : x ∈ I) (n : ℕ) : x ^ n ∈ I ^ n := theorem mul_le : I * J ≤ K ↔ ∀ r ∈ I, ∀ s ∈ J, r * s ∈ K := Submodule.smul_le -theorem mul_le_left : I * J ≤ J := +theorem mul_le_right : I * J ≤ J := mul_le.2 fun _ _ _ => J.mul_mem_left _ @[simp] theorem sup_mul_left_self : I ⊔ J * I = I := - sup_eq_left.2 mul_le_left + sup_eq_left.2 mul_le_right @[simp] theorem mul_left_self_sup : J * I ⊔ I = I := - sup_eq_right.2 mul_le_left + sup_eq_right.2 mul_le_right -theorem mul_le_right [I.IsTwoSided] : I * J ≤ I := +theorem mul_le_left [I.IsTwoSided] : I * J ≤ I := mul_le.2 fun _ hr _ _ ↦ I.mul_mem_right _ hr @[simp] theorem sup_mul_right_self [I.IsTwoSided] : I ⊔ I * J = I := - sup_eq_left.2 mul_le_right + sup_eq_left.2 mul_le_left @[simp] theorem mul_right_self_sup [I.IsTwoSided] : I * J ⊔ I = I := - sup_eq_right.2 mul_le_right + sup_eq_right.2 mul_le_left protected theorem mul_assoc : I * J * K = I * (J * K) := Submodule.smul_assoc I J K @@ -353,7 +353,7 @@ theorem pow_le_pow_right {m n : ℕ} (h : m ≤ n) : I ^ n ≤ I ^ m := by · rw [Submodule.pow_zero, one_eq_top]; exact le_top obtain ⟨n, rfl⟩ := Nat.exists_eq_add_of_le h rw [add_comm, Submodule.pow_add _ m.add_one_ne_zero] - exact mul_le_left + exact mul_le_right theorem pow_le_self {n : ℕ} (hn : n ≠ 0) : I ^ n ≤ I := calc @@ -382,7 +382,7 @@ instance (priority := low) : (I ^ n).IsTwoSided := (fun _ _ ↦ by rw [Submodule.pow_succ]; infer_instance) protected theorem mul_one : I * 1 = I := - mul_le_right.antisymm + mul_le_left.antisymm fun i hi ↦ mul_one i ▸ mul_mem_mul hi (one_eq_top (R := R) ▸ Submodule.mem_top) protected theorem pow_add : I ^ (m + n) = I ^ m * I ^ n := by @@ -445,14 +445,14 @@ lemma inf_ne_bot_of_ne_bot [NoZeroDivisors R] {I J : Ideal R} [I.IsTwoSided] exact not_or_intro hI hJ theorem sup_mul_eq_of_coprime_left [I.IsTwoSided] (h : I ⊔ J = ⊤) : I ⊔ J * K = I ⊔ K := - le_antisymm (sup_le_sup_left mul_le_left _) fun i hi => by + le_antisymm (sup_le_sup_left mul_le_right _) fun i hi => by rw [eq_top_iff_one] at h; rw [Submodule.mem_sup] at h hi ⊢ obtain ⟨i1, hi1, j, hj, h⟩ := h; obtain ⟨i', hi', k, hk, rfl⟩ := hi refine ⟨_, add_mem hi' (mul_mem_right k _ hi1), _, mul_mem_mul hj hk, ?_⟩ rw [add_assoc, ← add_mul, h, one_mul] theorem sup_mul_eq_of_coprime_right [J.IsTwoSided] (h : I ⊔ K = ⊤) : I ⊔ J * K = I ⊔ J := - le_antisymm (sup_le_sup_left mul_le_right _) fun i hi ↦ by + le_antisymm (sup_le_sup_left mul_le_left _) fun i hi ↦ by rw [eq_top_iff_one] at h; rw [Submodule.mem_sup] at h hi ⊢ obtain ⟨i1, hi1, k, hk, h⟩ := h; obtain ⟨i', hi', j, hj, rfl⟩ := hi refine ⟨_, add_mem hi' (mul_mem_left _ j hi1), _, mul_mem_mul hj hk, ?_⟩ @@ -565,9 +565,9 @@ lemma sup_pow_add_le_pow_sup_pow {n m : ℕ} : (I ⊔ J) ^ (n + m) ≤ I ^ n ⊔ apply Finset.sup_le intro i hi by_cases hn : n ≤ i - · exact (Ideal.mul_le_right.trans (Ideal.mul_le_right.trans + · exact (Ideal.mul_le_left.trans (Ideal.mul_le_left.trans ((Ideal.pow_le_pow_right hn).trans le_sup_left))) - · refine (Ideal.mul_le_right.trans (Ideal.mul_le_left.trans + · refine (Ideal.mul_le_left.trans (Ideal.mul_le_right.trans ((Ideal.pow_le_pow_right ?_).trans le_sup_right))) lia @@ -715,7 +715,7 @@ theorem isCoprime_iff_codisjoint : IsCoprime I J ↔ Codisjoint I J := by · rintro ⟨x, y, hxy⟩ rw [eq_top_iff_one] apply (show x * I + y * J ≤ I ⊔ J from - sup_le (mul_le_left.trans le_sup_left) (mul_le_left.trans le_sup_right)) + sup_le (mul_le_right.trans le_sup_left) (mul_le_right.trans le_sup_right)) rw [hxy] simp only [one_eq_top, Submodule.mem_top] · intro h diff --git a/Mathlib/RingTheory/Ideal/Pure.lean b/Mathlib/RingTheory/Ideal/Pure.lean index 5be8d2628701f5..a379ce71d5cfb3 100644 --- a/Mathlib/RingTheory/Ideal/Pure.lean +++ b/Mathlib/RingTheory/Ideal/Pure.lean @@ -44,7 +44,7 @@ lemma injective_lTensor_quotient_iff_inf_eq_mul (I J : Ideal R) : Function.Injective (J.subtype.lTensor (R ⧸ I)) ↔ I ⊓ J = I * J := by let f : J ⧸ (I • ⊤ : Submodule R J) →ₗ[R] R ⧸ I := Submodule.mapQ _ _ J.subtype <| by - simp [← Submodule.map_le_iff_le_comap, Ideal.mul_le_right] + simp [← Submodule.map_le_iff_le_comap, Ideal.mul_le_left] have : J.subtype.lTensor (R ⧸ I) = (TensorProduct.rid R (R ⧸ I)).symm ∘ₗ f ∘ₗ TensorProduct.quotTensorEquivQuotSMul J I := by ext diff --git a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean index f576ed3892b35a..225f9102da2566 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Operations.lean @@ -319,27 +319,27 @@ noncomputable def quotientMulEquivQuotientProd (I J : Ideal R) (coprime : IsCopr @[simp] theorem quotientMulEquivQuotientProd_fst (I J : Ideal R) (coprime : IsCoprime I J) (x : R ⧸ I * J) : (quotientMulEquivQuotientProd I J coprime x).fst = - Ideal.Quotient.factor mul_le_right x := + Ideal.Quotient.factor mul_le_left x := Quot.inductionOn x fun _ => rfl @[simp] theorem quotientMulEquivQuotientProd_snd (I J : Ideal R) (coprime : IsCoprime I J) (x : R ⧸ I * J) : (quotientMulEquivQuotientProd I J coprime x).snd = - Ideal.Quotient.factor mul_le_left x := + Ideal.Quotient.factor mul_le_right x := Quot.inductionOn x fun _ => rfl @[simp] theorem fst_comp_quotientMulEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) : (RingHom.fst _ _).comp (quotientMulEquivQuotientProd I J coprime : R ⧸ I * J →+* (R ⧸ I) × R ⧸ J) = - Ideal.Quotient.factor mul_le_right := by + Ideal.Quotient.factor mul_le_left := by apply Quotient.ringHom_ext; ext; rfl @[simp] theorem snd_comp_quotientMulEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) : (RingHom.snd _ _).comp (quotientMulEquivQuotientProd I J coprime : R ⧸ I * J →+* (R ⧸ I) × R ⧸ J) = - Ideal.Quotient.factor mul_le_left := by + Ideal.Quotient.factor mul_le_right := by apply Quotient.ringHom_ext; ext; rfl end ChineseRemainder diff --git a/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean b/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean index 627c8d4d425f24..de985b71298f67 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/PowTransition.lean @@ -179,7 +179,7 @@ lemma factorPowSucc.isUnit_of_isUnit_image {n : ℕ} (npos : n > 0) {a : R ⧸ I _ = 1 := by rw [← eq, mul_sub, mul_one, sub_add_sub_cancel', sub_eq_self, ← map_mul, Ideal.Quotient.eq_zero_iff_mem, pow_add] - apply Ideal.mul_mem_mul hc (Ideal.mul_le_left (I := I ^ (n - 1)) _) + apply Ideal.mul_mem_mul hc (Ideal.mul_le_right (I := I ^ (n - 1)) _) simpa only [← pow_add, Nat.sub_add_cancel npos] using! hc section powSMulQuotInclusion diff --git a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean index ee13f7d06e5376..acf2697702d771 100644 --- a/Mathlib/RingTheory/Kaehler/JacobiZariski.lean +++ b/Mathlib/RingTheory/Kaehler/JacobiZariski.lean @@ -120,7 +120,7 @@ lemma Cotangent.exact : obtain ⟨y, hy, e⟩ := hx rw [eq_comm, ← sub_eq_zero, ← map_sub, ← RingHom.mem_ker, ← map_toComp_ker] at e rw [LinearMap.range_liftBaseChange] - let z : (Q.comp P).ker := ⟨x - y, Ideal.sub_mem _ hx' (Ideal.mul_le_left hy)⟩ + let z : (Q.comp P).ker := ⟨x - y, Ideal.sub_mem _ hx' (Ideal.mul_le_right hy)⟩ have hz : z.1 ∈ P.ker.map (Q.toComp P).toAlgHom.toRingHom := e have : Extension.Cotangent.mk (P := (Q.comp P).toExtension) ⟨x, hx'⟩ = Extension.Cotangent.mk z := by diff --git a/Mathlib/RingTheory/PicardGroup.lean b/Mathlib/RingTheory/PicardGroup.lean index 0638f4bb3d9bf6..40727023523d01 100644 --- a/Mathlib/RingTheory/PicardGroup.lean +++ b/Mathlib/RingTheory/PicardGroup.lean @@ -930,6 +930,6 @@ theorem Ideal.eq_top_of_mk_tensor_eq_one [IsFractionRing R R] (I J : Ideal R) convert! Subtype.val_injective.comp e.injective using 2 rw [← smul_eq_mul, ← Submodule.coe_smul, ← map_smul, smul_eq_mul, mul_one, Function.comp_apply] constructor <;> refine eq_top_of_isUnit_mem _ ?_ this - exacts [mul_le_right (e 1).2, mul_le_left (e 1).2] + exacts [mul_le_left (e 1).2, mul_le_right (e 1).2] end Ideal diff --git a/Mathlib/RingTheory/Polynomial/ContentIdeal.lean b/Mathlib/RingTheory/Polynomial/ContentIdeal.lean index 4bc689bd797578..54dc951ec22a4b 100644 --- a/Mathlib/RingTheory/Polynomial/ContentIdeal.lean +++ b/Mathlib/RingTheory/Polynomial/ContentIdeal.lean @@ -111,7 +111,7 @@ variable {R : Type*} [CommSemiring R] {p q : R[X]} theorem contentIdeal_le_contentIdeal_of_dvd (hpq : p ∣ q) : q.contentIdeal ≤ p.contentIdeal := by obtain ⟨p', rfl⟩ := hpq - exact le_trans (p.contentIdeal_mul_le_mul_contentIdeal p') mul_le_right + exact le_trans (p.contentIdeal_mul_le_mul_contentIdeal p') mul_le_left theorem _root_.Submodule.IsPrincipal.contentIdeal_generator_dvd_coeff (h_prin : p.contentIdeal.IsPrincipal) (n : ℕ) : h_prin.generator ∣ p.coeff n := by @@ -162,7 +162,7 @@ theorem contentIdeal_eq_top_of_contentIdeal_mul_eq_top calc ⊤ = (p * q).contentIdeal := h.symm _ ≤ p.contentIdeal * q.contentIdeal := contentIdeal_mul_le_mul_contentIdeal p q - _ ≤ p.contentIdeal := mul_le_right + _ ≤ p.contentIdeal := mul_le_left end CommSemiring diff --git a/Mathlib/RingTheory/PrincipalIdealDomainOfPrime.lean b/Mathlib/RingTheory/PrincipalIdealDomainOfPrime.lean index 5935b10e83d0fc..abdabb223a2240 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomainOfPrime.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomainOfPrime.lean @@ -41,7 +41,7 @@ theorem isOka_isPrincipal : IsOka (Submodule.IsPrincipal (R := R)) where exact mem_span_singleton'.2 ⟨z, by rw [mul_assoc, mul_comm y]⟩ · rw [← span_singleton_mul_span_singleton, ← hx, Ideal.sup_mul, sup_le_iff, span_singleton_mul_span_singleton, mul_comm a, span_singleton_le_iff_mem] - exact ⟨mul_le_right, mem_colon_span_singleton.1 <| hy ▸ mem_span_singleton_self y⟩ + exact ⟨mul_le_left, mem_colon_span_singleton.1 <| hy ▸ mem_span_singleton_self y⟩ end Ideal diff --git a/Mathlib/RingTheory/Smooth/Quotient.lean b/Mathlib/RingTheory/Smooth/Quotient.lean index ab8e81d729982e..57733197c8cef7 100644 --- a/Mathlib/RingTheory/Smooth/Quotient.lean +++ b/Mathlib/RingTheory/Smooth/Quotient.lean @@ -77,18 +77,18 @@ private lemma mul_le_ker_of_range_le_mul_of_sq_zero {J I : Ideal R} (sq : I ^ 2 (le : f.range ≤ (Submodule.comap J.subtype (I * J)).map J.toCotangent) : (Submodule.comap J.subtype (I * J)).map J.toCotangent ≤ f.ker := by rw [pow_two] at sq - have {x : R} (h : x ∈ I * J) : f (J.toCotangent ⟨x, Ideal.mul_le_left h⟩) = 0 := by + have {x : R} (h : x ∈ I * J) : f (J.toCotangent ⟨x, Ideal.mul_le_right h⟩) = 0 := by induction h using Submodule.mul_induction_on' with | mem_mul_mem y hy z hz => rcases Submodule.mem_map.mp (le (f.mem_range_self (J.toCotangent ⟨z, hz⟩))) with ⟨w, hw, eqz⟩ have mem_bot := Ideal.mul_mem_mul hy (Submodule.mem_comap.mp hw) simp only [← mul_assoc, sq, Submodule.bot_mul, Submodule.mem_bot] at mem_bot have eq0 : y • w = 0 := SetCoe.ext mem_bot - have : ⟨y * z, Ideal.mul_le_left (Submodule.mul_mem_mul hy hz)⟩ = y • (⟨z, hz⟩ : J) := rfl + have : ⟨y * z, Ideal.mul_le_right (Submodule.mul_mem_mul hy hz)⟩ = y • (⟨z, hz⟩ : J) := rfl rw [this, map_smul, map_smul, ← eqz, ← map_smul, eq0, map_zero] | add y ymem z zmem hy hz => - have : (⟨y + z, Ideal.mul_le_left (add_mem ymem zmem)⟩ : J) = - ⟨y, Ideal.mul_le_left ymem⟩ + ⟨z, Ideal.mul_le_left zmem⟩ := rfl + have : (⟨y + z, Ideal.mul_le_right (add_mem ymem zmem)⟩ : J) = + ⟨y, Ideal.mul_le_right ymem⟩ + ⟨z, Ideal.mul_le_right zmem⟩ := rfl rw [this, map_add, map_add, hy, hz, add_zero] intro x hx rcases Submodule.mem_map.mp hx with ⟨x', hx', eq⟩ diff --git a/Mathlib/RingTheory/Spectrum/Prime/Basic.lean b/Mathlib/RingTheory/Spectrum/Prime/Basic.lean index 7252458688b3ba..e65676f31e91bf 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Basic.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Basic.lean @@ -455,9 +455,9 @@ theorem exists_primeSpectrum_prod_le (I : Ideal R) : rw [Multiset.map_add, Multiset.prod_add] apply le_trans (mul_le_mul' h_Wx h_Wy) rw [add_mul] - apply sup_le (show M * (M + span R {y}) ≤ M from Ideal.mul_le_right) + apply sup_le (show M * (M + span R {y}) ≤ M from Ideal.mul_le_left) rw [mul_add] - apply sup_le (show span R {x} * M ≤ M from Ideal.mul_le_left) + apply sup_le (show span R {x} * M ≤ M from Ideal.mul_le_right) rwa [span_mul_span, Set.singleton_mul_singleton, span_singleton_le_iff_mem] /-- In a Noetherian integral domain which is not a field, every non-zero ideal contains a non-zero @@ -492,9 +492,9 @@ theorem exists_primeSpectrum_prod_le_and_ne_bot_of_domain (h_fA : ¬IsField A) { rw [Multiset.map_add, Multiset.prod_add] refine ⟨le_trans (mul_le_mul' h_Wx_le h_Wy_le) ?_, mt Ideal.mul_eq_bot.mp ?_⟩ · rw [add_mul] - apply sup_le (show M * (M + span A {y}) ≤ M from Ideal.mul_le_right) + apply sup_le (show M * (M + span A {y}) ≤ M from Ideal.mul_le_left) rw [mul_add] - apply sup_le (show span A {x} * M ≤ M from Ideal.mul_le_left) + apply sup_le (show span A {x} * M ≤ M from Ideal.mul_le_right) rwa [span_mul_span, Set.singleton_mul_singleton, span_singleton_le_iff_mem] · rintro (hx | hy) <;> contradiction From 1f0fbd1ad9ff6e4751ab4564fc70cc4f2a1fadf9 Mon Sep 17 00:00:00 2001 From: Kim Morrison <477956+kim-em@users.noreply.github.com> Date: Thu, 6 Aug 2026 14:24:35 +0000 Subject: [PATCH 1202/1300] chore: use uniqueDiffOn_uIcc at existing call sites (#41576) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace five inline proofs of `uniqueDiffOn_uIcc` with using the lemma directly, and performs some small by-hand cleanup nearby. Follow-up to #40702. 🤖 Prepared with Claude Code Co-authored-by: Michael Rothgang --- Mathlib/Analysis/Calculus/Taylor.lean | 8 +++----- .../Integral/IntervalIntegral/TrapezoidalRule.lean | 6 ++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Taylor.lean b/Mathlib/Analysis/Calculus/Taylor.lean index 0a6d490a2fc651..3e3e885eeeb33d 100644 --- a/Mathlib/Analysis/Calculus/Taylor.lean +++ b/Mathlib/Analysis/Calculus/Taylor.lean @@ -349,7 +349,7 @@ lemma taylor_mean_remainder_lagrange_iteratedDeriv {f : ℝ → ℝ} {x x₀ : (hf : ContDiffOn ℝ (n + 1) f (uIcc x₀ x)) : ∃ x' ∈ uIoo x₀ x, f x - taylorWithinEval f n (uIcc x₀ x) x₀ x = iteratedDeriv (n + 1) f x' * (x - x₀) ^ (n + 1) / (n + 1)! := by - have hu : UniqueDiffOn ℝ (uIcc x₀ x) := uniqueDiffOn_Icc (by grind) + have hu : UniqueDiffOn ℝ (uIcc x₀ x) := uniqueDiffOn_uIcc hx have hd : DifferentiableOn ℝ (iteratedDerivWithin n f (uIcc x₀ x)) (uIcc x₀ x) := by refine hf.differentiableOn_iteratedDerivWithin ?_ hu norm_cast @@ -476,7 +476,6 @@ theorem taylor_integral_remainder_aux [NormedAddCommGroup F] [NormedSpace ℝ F] rw [← derivWithin_of_mem_nhds <| Icc_mem_nhds h1 h2] rfl | succ n ih => - have : UniqueDiffOn ℝ [[x₀, x]] := uniqueDiffOn_Icc (by grind) specialize ih (by grind) simp only [taylorWithinEval_succ, mul_inv_rev] rw [sub_add_eq_sub_sub, ih] @@ -522,9 +521,8 @@ theorem taylor_integral_remainder_of_absolutelyContinuous {f : ℝ → ℝ} {x x fun_prop · rcases hk.eq_or_lt with rfl | hk · exact hf₂ - have : UniqueDiffOn ℝ [[x₀, x]] := uniqueDiffOn_Icc (by grind) replace hf₁ := hf₁.of_le (m := k.succ) (by norm_cast) - grind [ContDiffOn.absolutelyContinuousOnInterval, + grind [ContDiffOn.absolutelyContinuousOnInterval, uniqueDiffOn_uIcc, contDiffOn_nat_succ_iff_contDiffOn_one_iteratedDerivWithin] /-- **Taylor's theorem** with the Integral form of the remainder. @@ -540,7 +538,7 @@ theorem taylor_integral_remainder [NormedAddCommGroup F] [NormedSpace ℝ F] ∫ t in x₀..x, ((x - t) ^ n / n !) • iteratedDerivWithin (n + 1) f (uIcc x₀ x) t := by rcases eq_or_ne x₀ x with rfl | this · simp - have : UniqueDiffOn ℝ [[x₀, x]] := uniqueDiffOn_Icc (by grind) + have : UniqueDiffOn ℝ [[x₀, x]] := uniqueDiffOn_uIcc this apply taylor_integral_remainder_aux intro k hk apply intervalIntegral.integral_smul_deriv_eq_deriv_smul_of_hasDerivAt diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean index 0fe73938b60340..f49e0f3c766b40 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/TrapezoidalRule.lean @@ -252,9 +252,7 @@ theorem trapezoidal_error_le_of_c2 {f : ℝ → ℝ} {a b : ℝ} (h_f_c2 : ContD · simp [h_eq] -- Once we have a ≠ b, all the necessary assumptions on f follow pretty quickly from its being -- C^2. - have ud : UniqueDiffOn ℝ [[a, b]] := uniqueDiffOn_Icc (inf_lt_sup.mpr h_ne) - have h_df : DifferentiableOn ℝ f [[a, b]] := ContDiffOn.differentiableOn h_f_c2 two_ne_zero have h_ddf : DifferentiableOn ℝ (derivWithin f [[a, b]]) [[a, b]] := by rw [← iteratedDerivWithin_one] - exact ContDiffOn.differentiableOn_iteratedDerivWithin h_f_c2 (by norm_cast) ud - exact trapezoidal_error_le h_df h_ddf fpp_bound N_nonzero + exact h_f_c2.differentiableOn_iteratedDerivWithin (by norm_cast) (uniqueDiffOn_uIcc h_ne) + exact trapezoidal_error_le (h_f_c2.differentiableOn two_ne_zero) h_ddf fpp_bound N_nonzero From 639a4248d45ecca40d981218990f9f2f33987ecd Mon Sep 17 00:00:00 2001 From: Alex Korbonits <5281694+korbonits@users.noreply.github.com> Date: Fri, 7 Aug 2026 00:50:08 +0000 Subject: [PATCH 1203/1300] feat(Topology/Connected): connected and path components of products and pi types (#41661) Add `connectedComponent_prod/pi` and `pathComponent_prod/pi`: the (path) component of a point in a product is the product of the components of its coordinates. Also add the missing `Joined.map`, `Joined.prod`, `Joined.pi` along the way. --- Mathlib/Topology/Connected/Basic.lean | 18 +++++++++++ Mathlib/Topology/Connected/PathConnected.lean | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 131d9f3b85c7b0..9b301f937a5563 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -641,6 +641,24 @@ theorem Continuous.mapsTo_connectedComponentIn [TopologicalSpace β] {f : α → MapsTo f (connectedComponentIn s a) (connectedComponentIn (f '' s) (f a)) := h.continuousOn.mapsTo_connectedComponentIn hx +/-- The connected component of `(x, y)` in the product space is the product of the connected +components of `x` and `y`. -/ +theorem connectedComponent_prod [TopologicalSpace β] (x : α) (y : β) : + connectedComponent (x, y) = connectedComponent x ×ˢ connectedComponent y := + subset_antisymm + (fun _ hp ↦ ⟨continuous_fst.mapsTo_connectedComponent (x, y) hp, + continuous_snd.mapsTo_connectedComponent (x, y) hp⟩) + (isPreconnected_connectedComponent.prod isPreconnected_connectedComponent + |>.subset_connectedComponent ⟨mem_connectedComponent, mem_connectedComponent⟩) + +/-- The connected component of `x` in a product space is the product of the connected components +of its coordinates. -/ +theorem connectedComponent_pi [∀ i, TopologicalSpace (X i)] (x : ∀ i, X i) : + connectedComponent x = univ.pi fun i ↦ connectedComponent (x i) := + subset_antisymm (fun _ hy i _ ↦ (continuous_apply i).mapsTo_connectedComponent x hy) + (isPreconnected_univ_pi (fun _ ↦ isPreconnected_connectedComponent) + |>.subset_connectedComponent fun _ _ ↦ mem_connectedComponent) + theorem irreducibleComponent_subset_connectedComponent {x : α} : irreducibleComponent x ⊆ connectedComponent x := isIrreducible_irreducibleComponent.isConnected.subset_connectedComponent mem_irreducibleComponent diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index 0f5e74fbe2fcd1..9654cc6d77187a 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -78,6 +78,10 @@ theorem Joined.symm {x y : X} (h : Joined x y) : Joined y x := theorem Joined.trans {x y z : X} (hxy : Joined x y) (hyz : Joined y z) : Joined x z := ⟨hxy.somePath.trans hyz.somePath⟩ +theorem Joined.map {x y : X} {f : X → Y} (h : Joined x y) (hf : Continuous f) : + Joined (f x) (f y) := + ⟨h.somePath.map hf⟩ + @[to_additive] theorem Joined.mul {M : Type*} [Mul M] [TopologicalSpace M] [ContinuousMul M] {a b c d : M} (hs : Joined a b) (ht : Joined c d) : Joined (a * c) (b * d) := @@ -607,12 +611,26 @@ section Prod variable {s : Set X} {t : Set Y} +/-- If `x₁` is joined to `x₂` and `y₁` is joined to `y₂`, then `(x₁, y₁)` is joined to +`(x₂, y₂)` in the product space. -/ +theorem Joined.prod {x₁ x₂ : X} {y₁ y₂ : Y} (hx : Joined x₁ x₂) (hy : Joined y₁ y₂) : + Joined (x₁, y₁) (x₂, y₂) := + ⟨hx.somePath.prod hy.somePath⟩ + /-- If `x₁` is joined to `x₂` within `s` and `y₁` to `y₂` within `t`, then `(x₁, y₁)` is joined to `(x₂, y₂)` within `s ×ˢ t`. -/ theorem JoinedIn.prod {x₁ x₂ : X} {y₁ y₂ : Y} (hx : JoinedIn s x₁ x₂) (hy : JoinedIn t y₁ y₂) : JoinedIn (s ×ˢ t) (x₁, y₁) (x₂, y₂) := ⟨hx.somePath.prod hy.somePath, by simp⟩ +/-- The path component of `(x, y)` in the product space is the product of the path components +of `x` and `y`. -/ +theorem pathComponent_prod (x : X) (y : Y) : + pathComponent (x, y) = pathComponent x ×ˢ pathComponent y := by + ext ⟨a, b⟩ + simp only [Set.mem_prod, mem_pathComponent_iff] + exact ⟨fun h ↦ ⟨h.map continuous_fst, h.map continuous_snd⟩, fun ⟨h₁, h₂⟩ ↦ h₁.prod h₂⟩ + /-- The product of two path-connected sets is path-connected. -/ theorem IsPathConnected.prod (hs : IsPathConnected s) (ht : IsPathConnected t) : IsPathConnected (s ×ˢ t) := by @@ -631,12 +649,24 @@ section Pi variable {Z : ι → Type*} [∀ i, TopologicalSpace (Z i)] +/-- If for each `i`, `x i` is joined to `y i`, then `x` is joined to `y` in the product space. -/ +theorem Joined.pi {x y : ∀ i, Z i} (h : ∀ i, Joined (x i) (y i)) : Joined x y := + ⟨.pi fun i ↦ (h i).somePath⟩ + /-- If for each `i`, `x i` is joined to `y i` within `s i`, then `x` is joined to `y` within the product set `Set.univ.pi s`. -/ theorem JoinedIn.pi {s : ∀ i, Set (Z i)} {x y : ∀ i, Z i} (h : ∀ i, JoinedIn (s i) (x i) (y i)) : JoinedIn (Set.univ.pi s) x y := ⟨.pi (fun i ↦ (h i).somePath), by simp⟩ +/-- The path component of `x` in a product space is the product of the path components of its +coordinates. -/ +theorem pathComponent_pi (x : ∀ i, Z i) : + pathComponent x = Set.univ.pi fun i ↦ pathComponent (x i) := by + ext y + simp only [Set.mem_univ_pi, mem_pathComponent_iff] + exact ⟨fun h i ↦ h.map (continuous_apply i), fun h ↦ .pi h⟩ + /-- The product of a family of path-connected sets is path-connected. -/ theorem IsPathConnected.pi {s : ∀ i, Set (Z i)} (h : ∀ i, IsPathConnected (s i)) : IsPathConnected (Set.univ.pi s) := by From 62f22e634429cc88061613bf3a5058fb97e3ac5c Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Fri, 7 Aug 2026 00:50:10 +0000 Subject: [PATCH 1204/1300] feat: add Mathlib.NumberTheory.NumberField.DirichletDensity (#41765) This PR defines the Dirichlet density of a set of ideals. Co-authored-by: Xavier Roblot <46200072+xroblot@users.noreply.github.com> --- Mathlib.lean | 1 + .../NumberField/DirichletDensity.lean | 146 ++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 Mathlib/NumberTheory/NumberField/DirichletDensity.lean diff --git a/Mathlib.lean b/Mathlib.lean index 6e41a8ddc14e25..5f7b2044a6311c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5889,6 +5889,7 @@ public import Mathlib.NumberTheory.NumberField.Cyclotomic.Ideal public import Mathlib.NumberTheory.NumberField.Cyclotomic.PID public import Mathlib.NumberTheory.NumberField.Cyclotomic.Three public import Mathlib.NumberTheory.NumberField.DedekindZeta +public import Mathlib.NumberTheory.NumberField.DirichletDensity public import Mathlib.NumberTheory.NumberField.Discriminant.Basic public import Mathlib.NumberTheory.NumberField.Discriminant.Defs public import Mathlib.NumberTheory.NumberField.Discriminant.Different diff --git a/Mathlib/NumberTheory/NumberField/DirichletDensity.lean b/Mathlib/NumberTheory/NumberField/DirichletDensity.lean new file mode 100644 index 00000000000000..bd4e0c1e04bdb6 --- /dev/null +++ b/Mathlib/NumberTheory/NumberField/DirichletDensity.lean @@ -0,0 +1,146 @@ +/- +Copyright (c) 2026 Riccardo Brasca. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck, Riccardo Brasca, Xavier Roblot +-/ +module + +public import Mathlib.Analysis.SpecialFunctions.Pow.Real +public import Mathlib.NumberTheory.NumberField.Basic +public import Mathlib.RingTheory.Ideal.Norm.AbsNorm + +/-! +# Dirichlet density of a set of prime ideals + +Let `K` be a number field. Given a set `S` of nonzero prime ideals of `𝓞 K`, its Dirichlet +density is +$$ +\delta(S) = \lim_{s \to 1^+} + \frac{\sum_{\mathfrak p \in S} \operatorname{N} \mathfrak p^{-s}} + {\sum_{\mathfrak p} \operatorname{N} \mathfrak p^{-s}}, +$$ +when this limit exists. The sum in the denominator runs over all nonzero prime ideals of `𝓞 K`. + +This is captured by the predicate `HasDirichletDensity S δ`, stating that the ratio tends to `δ`, +and by the definition `dirichletDensity S`, the density as a real number (with junk value `0` when +it does not exist). + +## Main results + +* `NumberField.primeIdealZetaSum_le_card_of_finite` — for a finite `S`, the partial sum is bounded + above by the number of elements of `S`. +* `NumberField.hasDirichletDensity_empty` — the empty set has Dirichlet density `0`. +* `NumberField.dirichletDensity_nonneg` — the Dirichlet density is nonnegative. +* `NumberField.dirichletDensity_le_one` — the Dirichlet density is at most `1`. + +-/ + +public section + +noncomputable section + +open Filter IsDedekindDomain Topology Set + +namespace NumberField.Set + +open NumberField + +variable {K : Type*} [Field K] [NumberField K] (S : Set (HeightOneSpectrum (𝓞 K))) + +/-- The partial Dirichlet series $\sum_{\mathfrak p \in S} \operatorname{N} \mathfrak p^{-s}$. -/ +def primeIdealZetaSum (S : Set (HeightOneSpectrum (𝓞 K))) (s : ℝ) : ℝ := + ∑' 𝔭 : S, (Ideal.absNorm 𝔭.1.asIdeal : ℝ) ^ (-s) + +theorem primeIdealZetaSum_def (s : ℝ) : + S.primeIdealZetaSum s = ∑' 𝔭 : S, (Ideal.absNorm 𝔭.1.asIdeal : ℝ) ^ (-s) := by rfl + +theorem primeIdealZetaSum_nonneg (s : ℝ) : + 0 ≤ S.primeIdealZetaSum s := + tsum_nonneg fun _ ↦ by positivity + +variable {S} in +/-- For a finite set `S` of prime ideals, the partial sum +$\sum_{\mathfrak p \in S} \operatorname{N} \mathfrak p^{-s}$ is bounded above by the number of +elements of `S`. -/ +theorem primeIdealZetaSum_le_card_of_finite (hS : S.Finite) {s : ℝ} (hs : 0 ≤ s) : + S.primeIdealZetaSum s ≤ S.ncard := by + replace hS := hS.to_subtype + grw [primeIdealZetaSum_def, Real.rpow_le_one_of_one_le_of_nonpos] <;> + simp [Summable.of_finite, Nat.one_le_iff_ne_zero, + Ideal.absNorm_eq_zero_iff, hs, HeightOneSpectrum.ne_bot] + +/-- `S` has Dirichlet density `δ` when the ratio of the partial sum over `S` to the sum over all +nonzero prime ideals, +$$ +\frac{\sum_{\mathfrak p \in S} \operatorname{N} \mathfrak p^{-s}} + {\sum_{\mathfrak p} \operatorname{N} \mathfrak p^{-s}}, +$$ +tends to `δ` as $s \to 1^+$. -/ +def HasDirichletDensity (δ : ℝ) : Prop := + Tendsto (fun s : ℝ ↦ S.primeIdealZetaSum s / + primeIdealZetaSum (univ : Set (HeightOneSpectrum (𝓞 K))) s) (𝓝[>] 1) (𝓝 δ) + +open scoped Classical in +/-- The Dirichlet density of `S` as a real number, taking the junk value `0` when `S` has no +density. As with `tsum`, this value only has content when `S` has a density; the genuine statement +that `S` has density `0` is `HasDirichletDensity S 0`. -/ +def dirichletDensity : ℝ := + if h : ∃ δ, S.HasDirichletDensity δ then h.choose else 0 + +variable {S} + +/-- If `S` has no Dirichlet density, then `dirichletDensity S = 0`. -/ +theorem dirichletDensity_eq_zero_of_not_hasDirichletDensity + (h : ∀ δ, ¬ S.HasDirichletDensity δ) : S.dirichletDensity = 0 := by + rw [dirichletDensity, dif_neg (not_exists.mpr h)] + +/-- If `S` has Dirichlet density `δ`, then `dirichletDensity S = δ`. -/ +theorem HasDirichletDensity.dirichletDensity_eq {δ : ℝ} (h : S.HasDirichletDensity δ) : + S.dirichletDensity = δ := by + rw [dirichletDensity, dif_pos ⟨δ, h⟩, tendsto_nhds_unique (Exists.choose_spec ⟨δ, h⟩) h] + +/-- The empty set has Dirichlet density `0`. -/ +theorem hasDirichletDensity_empty : + HasDirichletDensity (∅ : Set (HeightOneSpectrum (𝓞 K))) 0 := by + simp [HasDirichletDensity, primeIdealZetaSum_def] + +/-- The Dirichlet density of the empty set is `0`. -/ +@[simp] +theorem dirichletDensity_empty : + dirichletDensity (∅ : Set (HeightOneSpectrum (𝓞 K))) = 0 := + hasDirichletDensity_empty.dirichletDensity_eq + +/-- The Dirichlet density is nonnegative. -/ +theorem HasDirichletDensity.nonneg {δ : ℝ} (h : S.HasDirichletDensity δ) : + 0 ≤ δ := + ge_of_tendsto h <| Eventually.of_forall fun s ↦ + div_nonneg (S.primeIdealZetaSum_nonneg s) (univ.primeIdealZetaSum_nonneg s) + +variable (S) in +/-- The Dirichlet density of `S` is nonnegative. -/ +theorem dirichletDensity_nonneg : 0 ≤ S.dirichletDensity := by + rw [dirichletDensity] + split_ifs with h + · exact h.choose_spec.nonneg + · exact le_rfl + +/-- The Dirichlet density is at most `1`. -/ +theorem HasDirichletDensity.le_one {δ : ℝ} (h : S.HasDirichletDensity δ) : + δ ≤ 1 := by + refine le_of_tendsto h (Eventually.of_forall fun s ↦ ?_) + rw [primeIdealZetaSum_def, primeIdealZetaSum_def, + tsum_univ fun 𝔭 : HeightOneSpectrum (𝓞 K) ↦ (𝔭.asIdeal.absNorm : ℝ) ^ (-s)] + by_cases hs : Summable fun 𝔭 : HeightOneSpectrum (𝓞 K) ↦ (𝔭.asIdeal.absNorm : ℝ) ^ (-s) + · exact div_le_one_of_le₀ (hs.tsum_subtype_le _ S (fun _ ↦ by positivity)) + (tsum_nonneg fun _ ↦ by positivity) + · grw [tsum_eq_zero_of_not_summable hs, div_zero, zero_le_one] + +variable (S) in +/-- The Dirichlet density of `S` is at most `1`. -/ +theorem dirichletDensity_le_one : S.dirichletDensity ≤ 1 := by + rw [dirichletDensity] + split_ifs with h + · exact h.choose_spec.le_one + · exact zero_le_one + +end NumberField.Set From 39122a64484ce32b5fdb6f005e5c2da61773e225 Mon Sep 17 00:00:00 2001 From: "Yi.Yuan" Date: Fri, 7 Aug 2026 02:57:56 +0000 Subject: [PATCH 1205/1300] feat(Complex): generalize harmonic mean value properties to Banach-valued functions (#42328) This generalizes `HarmonicOnNhd.circleAverage_eq` and `HarmonicContOnCl.circleAverage_eq` to functions with values in a real Banach space. --- .../Analysis/Complex/Harmonic/MeanValue.lean | 97 +++++++++++++++---- Mathlib/Analysis/Complex/JensenFormula.lean | 3 +- .../Integrals/PosLogEqCircleAverage.lean | 4 +- 3 files changed, 81 insertions(+), 23 deletions(-) diff --git a/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean b/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean index c45e7fd829991e..77cde76ed7c985 100644 --- a/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean +++ b/Mathlib/Analysis/Complex/Harmonic/MeanValue.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Stefan Kebekus. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Stefan Kebekus +Authors: Stefan Kebekus, Yi Yuan -/ module @@ -10,31 +10,76 @@ public import Mathlib.Analysis.Complex.MeanValue public import Mathlib.Analysis.InnerProductSpace.Harmonic.HarmonicContOnCl /-! -# The Mean Value Property of Harmonic Functions on the Complex Plane +# The Mean Value Property of Vector-Valued Harmonic Functions + +This file establishes the mean value property for harmonic functions `f : ℂ → F`, where `F` is an +arbitrary complete real normed vector space. This generalizes the mean value property for +real-valued harmonic functions. + +Completeness of `F` cannot be dropped: `circleAverage` is defined in terms of the Bochner integral, +which is junk (zero) whenever the target space is incomplete. + +The proof reduces to the real-valued case. Circle averages commute with continuous linear maps, and +composition with continuous linear maps preserves harmonicity. Thus, `g (circleAverage f c R)` +equals `circleAverage (g ∘ f) c R = g (f c)` for every continuous linear functional `g : F →L[ℝ] ℝ`. +Since continuous linear functionals separate the points of a normed space (Hahn-Banach, in the form +of `SeparatingDual.eq_iff_forall_dual_eq`), this suffices. -/ public section open InnerProductSpace Metric Real -variable {f : ℂ → ℝ} {c : ℂ} {R : ℝ} +namespace InnerProductSpace + +/-! +## Compatibility of `HarmonicContOnCl` with Linear Maps +-/ + +section + +variable {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] [FiniteDimensional ℝ E] +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {G : Type*} [NormedAddCommGroup G] [NormedSpace ℝ G] /-- -The **Mean Value Property** of harmonic functions: If `f : ℂ → ℝ` is harmonic in a neighborhood of a -closed disc of radius `R` and center `c`, then the circle average `circleAverage f c R` equals -`f c`. +Compositions of continuous ℝ-linear maps with functions that are harmonic on a set and continuous +on its closure are again harmonic on the set and continuous on its closure. +-/ +theorem HarmonicContOnCl.comp_CLM {f : E → F} {s : Set E} (h : HarmonicContOnCl f s) + (l : F →L[ℝ] G) : HarmonicContOnCl (l ∘ f) s := + ⟨h.1.comp_CLM l, l.continuous.comp_continuousOn h.2⟩ + +end + +/-! +## The Mean Value Property +-/ + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] +variable {f : ℂ → F} {c : ℂ} {R : ℝ} + +/-- +The Mean Value Property of harmonic functions: If f : ℂ → F is harmonic in a neighborhood of a +closed disc of radius R and center c, then the circle average circleAverage f c R equals +f c. -/ theorem HarmonicOnNhd.circleAverage_eq (hf : HarmonicOnNhd f (closedBall c |R|)) : circleAverage f c R = f c := by + have h : CircleIntegrable f c R := + (hf.continuousOn.mono sphere_subset_closedBall).circleIntegrable' + rw [SeparatingDual.eq_iff_forall_dual_eq (R := ℝ)] + intro g + rw [← g.circleAverage_comp_comm h] obtain ⟨e, h₁e, h₂e⟩ := (isCompact_closedBall c |R|).exists_thickening_subset_open - (isOpen_setOfPred_harmonicAt f) hf + (isOpen_setOfPred_harmonicAt (g ∘ f)) (hf.comp_CLM g) rw [thickening_closedBall h₁e (abs_nonneg R)] at h₂e obtain ⟨F, h₁F, h₂F⟩ := InnerProductSpace.HarmonicOnNhd.exists_analyticOnNhd_ball_re_eq h₂e have h₃F : DifferentiableOn ℂ F (closure (ball c |R|)) := by intro x hx apply (h₁F x _).differentiableWithinAt grind [mem_ball, mem_closedBall.1 (closure_ball_subset_closedBall hx)] - have h₄F : Set.EqOn (Complex.reCLM ∘ F) f (sphere c |R|) := + have h₄F : Set.EqOn (Complex.reCLM ∘ F) (⇑g ∘ f) (sphere c |R|) := fun x hx ↦ h₂F (sphere_subset_ball (lt_add_of_pos_left |R| h₁e) hx) rw [← circleAverage_congr_sphere h₄F, Complex.reCLM.circleAverage_comp_comm, h₃F.diffContOnCl.circleAverage] @@ -43,24 +88,36 @@ theorem HarmonicOnNhd.circleAverage_eq (hf : HarmonicOnNhd f (closedBall c |R|)) · apply (h₁F.continuousOn.mono (fun _ _ ↦ by simp_all [dist_eq_norm])).circleIntegrable' /-- -The **Mean Value Property** of harmonic functions: If `f : ℂ → ℝ` is harmonic on a disc of radius -`|R|` and center `c` and continuous on its closure, then the circle average `circleAverage f c R` -equals `f c`. +The Mean Value Property of harmonic functions: If f : ℂ → F is harmonic on a disc of radius +|R| and center c and continuous on its closure, then the circle average circleAverage f c R +equals f c. -/ -theorem HarmonicContOnCl.circleAverage_eq {f : ℂ → ℝ} {c : ℂ} {R : ℝ} - (h₁f : HarmonicContOnCl f (ball c |R|)) : +theorem HarmonicContOnCl.circleAverage_eq (hf : HarmonicContOnCl f (ball c |R|)) : circleAverage f c R = f c := by + have h : CircleIntegrable f c R := + (hf.continuousOn_ball.mono sphere_subset_closedBall).circleIntegrable' + rw [SeparatingDual.eq_iff_forall_dual_eq (R := ℝ)] + intro g + rw [← g.circleAverage_comp_comm h] by_cases hR : R = 0 · simp_all - have H : ContinuousOn (circleAverage f c) (Set.Ioc 0 |R|) := by - refine (h₁f.2.mono ?_).circleAverage (fun z hz ↦ hz.1.le) + have H : ContinuousOn (circleAverage (g ∘ f) c) (Set.Ioc 0 |R|) := by + refine ((hf.comp_CLM g).2.mono ?_).circleAverage (fun z hz ↦ hz.1.le) intro x hx rw [closure_ball _ (by aesop), mem_closedBall_iff_norm] exact hx.2 rw [← circleAverage_abs_radius] apply H.eq_of_eqOn_Ioo (by aesop) - · intro r hr - apply HarmonicOnNhd.circleAverage_eq - · apply h₁f.1.mono - rw [abs_of_pos hr.1] - exact closedBall_subset_ball hr.2 + intro r hr + apply HarmonicOnNhd.circleAverage_eq + apply (hf.comp_CLM g).1.mono + rw [abs_of_pos hr.1] + exact closedBall_subset_ball hr.2 + +end InnerProductSpace + +@[deprecated InnerProductSpace.HarmonicOnNhd.circleAverage_eq (since := "2026-08-04")] +alias HarmonicOnNhd.circleAverage_eq := InnerProductSpace.HarmonicOnNhd.circleAverage_eq + +@[deprecated InnerProductSpace.HarmonicContOnCl.circleAverage_eq (since := "2026-08-04")] +alias HarmonicContOnCl.circleAverage_eq := InnerProductSpace.HarmonicContOnCl.circleAverage_eq diff --git a/Mathlib/Analysis/Complex/JensenFormula.lean b/Mathlib/Analysis/Complex/JensenFormula.lean index 2a77d6e24c4392..30f876358168c0 100644 --- a/Mathlib/Analysis/Complex/JensenFormula.lean +++ b/Mathlib/Analysis/Complex/JensenFormula.lean @@ -265,7 +265,8 @@ circle average `circleAverage (log ‖g ·‖) c R` equals `log ‖g c‖`. lemma AnalyticOnNhd.circleAverage_log_norm_of_ne_zero {R : ℝ} {c : ℂ} {g : ℂ → ℂ} (h₁g : AnalyticOnNhd ℂ g (closedBall c |R|)) (h₂g : ∀ u ∈ closedBall c |R|, g u ≠ 0) : circleAverage (Real.log ‖g ·‖) c R = Real.log ‖g c‖ := - HarmonicOnNhd.circleAverage_eq (fun x hx ↦ (h₁g x hx).harmonicAt_log_norm (h₂g x hx)) + InnerProductSpace.HarmonicOnNhd.circleAverage_eq + (fun x hx ↦ (h₁g x hx).harmonicAt_log_norm (h₂g x hx)) set_option backward.isDefEq.respectTransparency.types false in /-- diff --git a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean index 74b9392e3c7c59..b9062880dcb48e 100644 --- a/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean +++ b/Mathlib/Analysis/SpecialFunctions/Integrals/PosLogEqCircleAverage.lean @@ -56,7 +56,7 @@ theorem circleAverage_log_norm_sub_const₀ (h : ‖a‖ < 1) : circleAverage (l _ = ‖1 - z⁻¹ * a‖ := by field_simp _ = 0 := by rw [circleAverage_zero_one_congr_inv (f := fun x ↦ log ‖1 - x * a‖), - HarmonicOnNhd.circleAverage_eq, zero_mul, sub_zero, + InnerProductSpace.HarmonicOnNhd.circleAverage_eq, zero_mul, sub_zero, CStarRing.norm_of_mem_unitary (unitary ℂ).one_mem, log_one] intro x hx have : ‖x * a‖ < 1 := by @@ -160,7 +160,7 @@ If `a : ℂ` has norm greater than one, then `circleAverage (log ‖· - a‖) 0 @[simp] theorem circleAverage_log_norm_sub_const₂ (h : 1 < ‖a‖) : circleAverage (log ‖· - a‖) 0 1 = log ‖a‖ := by - rw [HarmonicOnNhd.circleAverage_eq, zero_sub, norm_neg] + rw [InnerProductSpace.HarmonicOnNhd.circleAverage_eq, zero_sub, norm_neg] intro x hx apply AnalyticAt.harmonicAt_log_norm (by fun_prop) rw [sub_ne_zero] From fcdfe229949f10f534f4627c2c8035d77406f8fa Mon Sep 17 00:00:00 2001 From: damiano Date: Fri, 7 Aug 2026 03:32:20 +0000 Subject: [PATCH 1206/1300] chore: add missing `to_additive` docstrings in MeasureTheory.Group (#41639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing additive doc-strings (multiplicative side has a hand-written doc-string, additive side did not) across 3 file(s) in **MeasureTheory.Group**. The additive doc-strings are simple-minded translations of the multiplicative ones, with referenced lemma names replaced by their `to_additive` counterparts. These gaps were found by an environment linter that pairs each declaration with its `to_additive` counterpart and checks that both or neither is documented. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Mathlib/MeasureTheory/Group/Arithmetic.lean | 6 ++- .../Group/FundamentalDomain.lean | 38 +++++++++++++------ Mathlib/MeasureTheory/Group/Measure.lean | 8 +++- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/Mathlib/MeasureTheory/Group/Arithmetic.lean b/Mathlib/MeasureTheory/Group/Arithmetic.lean index b0cd42cb597c94..24a3bad3593341 100644 --- a/Mathlib/MeasureTheory/Group/Arithmetic.lean +++ b/Mathlib/MeasureTheory/Group/Arithmetic.lean @@ -522,7 +522,8 @@ instance Pi.instMeasurableConstSMul {ι : Type*} {α : ι → Type*} [∀ i, SMu measurable_const_smul _ := measurable_pi_iff.2 fun i ↦ (measurable_pi_apply i).const_smul _ /-- If a scalar is central, then its right action is measurable when its left action is. -/ -@[to_additive] +@[to_additive /-- If a vector is central, then its right action is measurable when its left +action is. -/] nonrec instance MulOpposite.instMeasurableConstSMul [SMul M α] [SMul Mᵐᵒᵖ α] [IsCentralScalar M α] [MeasurableConstSMul M α] : MeasurableConstSMul Mᵐᵒᵖ α where measurable_const_smul := by simpa using measurable_const_smul @@ -723,7 +724,8 @@ instance MulOpposite.instMeasurableMul₂ {M : Type*} [Mul M] [MeasurableSpace M ((measurable_mul_unop.comp measurable_snd).mul (measurable_mul_unop.comp measurable_fst))⟩ /-- If a scalar is central, then its right action is measurable when its left action is. -/ -@[to_additive] +@[to_additive /-- If a vector is central, then its right action is measurable when its left +action is. -/] nonrec instance MeasurableSMul.op {M α} [MeasurableSpace M] [MeasurableSpace α] [SMul M α] [SMul Mᵐᵒᵖ α] [IsCentralScalar M α] [MeasurableSMul M α] : MeasurableSMul Mᵐᵒᵖ α where measurable_smul_const x := diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index 94f37e9880c9a4..5a9f2aedca566a 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -684,13 +684,15 @@ noncomputable def covolume (G α : Type*) [One G] [SMul G α] [MeasurableSpace variable [Group G] [MulAction G α] [MeasurableSpace α] /-- If there is a fundamental domain `s`, then `HasFundamentalDomain` holds. -/ -@[to_additive] +@[to_additive /-- If there is an additive fundamental domain `s`, then `HasAddFundamentalDomain` +holds. -/] lemma IsFundamentalDomain.hasFundamentalDomain (ν : Measure α) {s : Set α} (fund_dom_s : IsFundamentalDomain G s ν) : HasFundamentalDomain G α ν := ⟨⟨s, fund_dom_s⟩⟩ /-- The `covolume` can be computed by taking the `volume` of any given fundamental domain `s`. -/ -@[to_additive] +@[to_additive /-- The `addCovolume` can be computed by taking the `volume` of any given additive +fundamental domain `s`. -/] lemma IsFundamentalDomain.covolume_eq_volume (ν : Measure α) [Countable G] [MeasurableConstSMul G α] [SMulInvariantMeasure G α ν] {s : Set α} (fund_dom_s : IsFundamentalDomain G s ν) : covolume G α ν = ν s := by @@ -766,7 +768,7 @@ lemma IsFundamentalDomain.projection_respects_measure_apply {ν : Measure α} variable {ν : Measure α} /-- Any two measures satisfying `QuotientMeasureEqMeasurePreimage` are equal. -/ -@[to_additive] +@[to_additive /-- Any two measures satisfying `AddQuotientMeasureEqMeasurePreimage` are equal. -/] lemma QuotientMeasureEqMeasurePreimage.unique [hasFun : HasFundamentalDomain G α ν] (μ μ' : Measure (Quotient α_mod_G)) [QuotientMeasureEqMeasurePreimage ν μ] [QuotientMeasureEqMeasurePreimage ν μ'] : @@ -776,7 +778,10 @@ lemma QuotientMeasureEqMeasurePreimage.unique /-- The quotient map to `α ⧸ G` is measure-preserving between the restriction of `volume` to a fundamental domain in `α` and a related measure satisfying `QuotientMeasureEqMeasurePreimage`. -/ -@[to_additive IsAddFundamentalDomain.measurePreserving_add_quotient_mk] +@[to_additive IsAddFundamentalDomain.measurePreserving_add_quotient_mk /-- The quotient map to +the additive quotient of `α` by `G` is measure-preserving between the restriction of `volume` to +an additive fundamental domain in `α` and a related measure satisfying +`AddQuotientMeasureEqMeasurePreimage`. -/] theorem IsFundamentalDomain.measurePreserving_quotient_mk {𝓕 : Set α} (h𝓕 : IsFundamentalDomain G 𝓕 ν) (μ : Measure (Quotient α_mod_G)) [QuotientMeasureEqMeasurePreimage ν μ] : @@ -791,7 +796,9 @@ variable [SMulInvariantMeasure G α ν] [Countable G] [MeasurableConstSMul G α] /-- Given a measure upstairs (i.e., on `α`), and a choice `s` of fundamental domain, there's always an artificial way to generate a measure downstairs such that the pair satisfies the `QuotientMeasureEqMeasurePreimage` typeclass. -/ -@[to_additive] +@[to_additive /-- Given a measure upstairs (i.e., on `α`), and a choice `s` of additive +fundamental domain, there's always an artificial way to generate a measure downstairs such that +the pair satisfies the `AddQuotientMeasureEqMeasurePreimage` typeclass. -/] lemma IsFundamentalDomain.quotientMeasureEqMeasurePreimage_quotientMeasure {s : Set α} (fund_dom_s : IsFundamentalDomain G s ν) : QuotientMeasureEqMeasurePreimage ν ((ν.restrict s).map π) where @@ -799,7 +806,8 @@ lemma IsFundamentalDomain.quotientMeasureEqMeasurePreimage_quotientMeasure /-- One can prove `QuotientMeasureEqMeasurePreimage` by checking behavior with respect to a single fundamental domain. -/ -@[to_additive] +@[to_additive /-- One can prove `AddQuotientMeasureEqMeasurePreimage` by checking behavior with +respect to a single additive fundamental domain. -/] lemma IsFundamentalDomain.quotientMeasureEqMeasurePreimage {μ : Measure (Quotient α_mod_G)} {s : Set α} (fund_dom_s : IsFundamentalDomain G s ν) (h : μ = (ν.restrict s).map π) : QuotientMeasureEqMeasurePreimage ν μ := by @@ -807,7 +815,8 @@ lemma IsFundamentalDomain.quotientMeasureEqMeasurePreimage {μ : Measure (Quotie /-- If a fundamental domain has volume 0, then `QuotientMeasureEqMeasurePreimage` holds. -/ -@[to_additive] +@[to_additive /-- If an additive fundamental domain has volume 0, then +`AddQuotientMeasureEqMeasurePreimage` holds. -/] theorem IsFundamentalDomain.quotientMeasureEqMeasurePreimage_of_zero {s : Set α} (fund_dom_s : IsFundamentalDomain G s ν) (vol_s : ν s = 0) : @@ -820,7 +829,8 @@ theorem IsFundamentalDomain.quotientMeasureEqMeasurePreimage_of_zero /-- If a measure `μ` on a quotient satisfies `QuotientMeasureEqMeasurePreimage` with respect to a sigma-finite measure `ν`, then it is itself `SigmaFinite`. -/ -@[to_additive] +@[to_additive /-- If a measure `μ` on a quotient satisfies `AddQuotientMeasureEqMeasurePreimage` +with respect to a sigma-finite measure `ν`, then it is itself `SigmaFinite`. -/] lemma QuotientMeasureEqMeasurePreimage.sigmaFiniteQuotient [i : SigmaFinite ν] [i' : HasFundamentalDomain G α ν] (μ : Measure (Quotient α_mod_G)) [QuotientMeasureEqMeasurePreimage ν μ] : @@ -844,7 +854,8 @@ lemma QuotientMeasureEqMeasurePreimage.sigmaFiniteQuotient /-- A measure `μ` on `α ⧸ G` satisfying `QuotientMeasureEqMeasurePreimage` and having finite covolume is a finite measure. -/ -@[to_additive] +@[to_additive /-- A measure `μ` on the additive quotient of `α` by `G` satisfying +`AddQuotientMeasureEqMeasurePreimage` and having finite covolume is a finite measure. -/] theorem QuotientMeasureEqMeasurePreimage.isFiniteMeasure_quotient (μ : Measure (Quotient α_mod_G)) [QuotientMeasureEqMeasurePreimage ν μ] [hasFun : HasFundamentalDomain G α ν] (h : covolume G α ν ≠ ∞) : @@ -859,7 +870,8 @@ theorem QuotientMeasureEqMeasurePreimage.isFiniteMeasure_quotient /-- A finite measure `μ` on `α ⧸ G` satisfying `QuotientMeasureEqMeasurePreimage` has finite covolume. -/ -@[to_additive] +@[to_additive /-- A finite measure `μ` on the additive quotient of `α` by `G` satisfying +`AddQuotientMeasureEqMeasurePreimage` has finite covolume. -/] theorem QuotientMeasureEqMeasurePreimage.covolume_ne_top (μ : Measure (Quotient α_mod_G)) [QuotientMeasureEqMeasurePreimage ν μ] [IsFiniteMeasure μ] : covolume G α ν < ∞ := by @@ -882,9 +894,11 @@ local notation "α_mod_G" => MulAction.orbitRel G α local notation "π" => @Quotient.mk _ α_mod_G -/-- If a measure `μ` on a quotient satisfies `QuotientVolumeEqVolumePreimage` with respect to a +/-- If a measure `μ` on a quotient satisfies `QuotientMeasureEqMeasurePreimage` with respect to a sigma-finite measure, then it is itself `SigmaFinite`. -/ -@[to_additive MeasureTheory.instSigmaFiniteAddQuotientOrbitRelInstMeasurableSpaceToMeasurableSpace] +@[to_additive MeasureTheory.instSigmaFiniteAddQuotientOrbitRelInstMeasurableSpaceToMeasurableSpace +/-- If a measure `μ` on a quotient satisfies `AddQuotientMeasureEqMeasurePreimage` with respect to a +sigma-finite measure, then it is itself `SigmaFinite`. -/] instance [SigmaFinite (volume : Measure α)] [HasFundamentalDomain G α] (μ : Measure (Quotient α_mod_G)) [QuotientMeasureEqMeasurePreimage volume μ] : SigmaFinite μ := diff --git a/Mathlib/MeasureTheory/Group/Measure.lean b/Mathlib/MeasureTheory/Group/Measure.lean index 8686ad446ae983..b1c9cd3d3004b3 100644 --- a/Mathlib/MeasureTheory/Group/Measure.lean +++ b/Mathlib/MeasureTheory/Group/Measure.lean @@ -542,7 +542,9 @@ theorem innerRegular_inv_iff : μ.inv.InnerRegular ↔ μ.InnerRegular := /-- Continuity of the measure of translates of a compact set: Given a compact set `k` in a topological group, for `g` close enough to the origin, `μ (g • k \ k)` is arbitrarily small. -/ -@[to_additive] +@[to_additive /-- Continuity of the measure of translates of a compact set: Given a compact set `k` +in an additive topological group, for `g` close enough to the origin, `μ (g +ᵥ k \ k)` is +arbitrarily small. -/] lemma eventually_nhds_one_measure_smul_sdiff_lt [LocallyCompactSpace G] [IsFiniteMeasureOnCompacts μ] [InnerRegularCompactLTTop μ] {k : Set G} (hk : IsCompact k) (h'k : IsClosed k) {ε : ℝ≥0∞} (hε : ε ≠ 0) : @@ -563,7 +565,9 @@ alias eventually_nhds_one_measure_smul_diff_lt := eventually_nhds_one_measure_sm /-- Continuity of the measure of translates of a compact set: Given a closed compact set `k` in a topological group, the measure of `g • k \ k` tends to zero as `g` tends to `1`. -/ -@[to_additive] +@[to_additive /-- Continuity of the measure of translates of a compact set: +Given a closed compact set `k` in an additive topological group, +the measure of `g +ᵥ k \ k` tends to zero as `g` tends to `0`. -/] lemma tendsto_measure_smul_sdiff_isCompact_isClosed [LocallyCompactSpace G] [IsFiniteMeasureOnCompacts μ] [InnerRegularCompactLTTop μ] {k : Set G} (hk : IsCompact k) (h'k : IsClosed k) : From daa38bd533b3d7661a1d44f8cc9c904306b335e9 Mon Sep 17 00:00:00 2001 From: damiano Date: Fri, 7 Aug 2026 03:47:42 +0000 Subject: [PATCH 1207/1300] chore: add missing `to_additive` docstrings in Combinatorics and Dynamics (#41645) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing additive doc-strings (multiplicative side has a hand-written doc-string, additive side did not) across 5 file(s) in **Combinatorics and Dynamics**. The additive doc-strings are simple-minded translations of the multiplicative ones, with referenced lemma names replaced by their `to_additive` counterparts. These gaps were found by an environment linter that pairs each declaration with its `to_additive` counterpart and checks that both or neither is documented. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Mathlib/Combinatorics/Additive/FreimanHom.lean | 12 ++++++++++-- Mathlib/Combinatorics/Hindman.lean | 3 ++- Mathlib/Combinatorics/SimpleGraph/Cayley.lean | 2 +- Mathlib/Data/Finset/NoncommProd.lean | 2 +- Mathlib/Dynamics/SymbolicDynamics/Basic.lean | 12 ++++++++---- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Mathlib/Combinatorics/Additive/FreimanHom.lean b/Mathlib/Combinatorics/Additive/FreimanHom.lean index 8c79ce0b64639a..0caa4eb8e07d97 100644 --- a/Mathlib/Combinatorics/Additive/FreimanHom.lean +++ b/Mathlib/Combinatorics/Additive/FreimanHom.lean @@ -138,7 +138,11 @@ lemma IsMulFreimanIso.congr (hf₁ : IsMulFreimanIso n A B f₁) (h : EqOn f₁ Given a Freiman isomorphism `f` from `A` to `B`, if `g` maps `B` into `A`, and is a right inverse to `f` on `B`, then `g` is a Freiman isomorphism from `B` to `A`. -/ -@[to_additive] +@[to_additive +/-- +Given an additive Freiman isomorphism `f` from `A` to `B`, if `g` maps `B` into `A`, and is a +right inverse to `f` on `B`, then `g` is an additive Freiman isomorphism from `B` to `A`. +-/] lemma IsMulFreimanIso.symm {g : β → α} (hg₁ : MapsTo g B A) (hg₂ : RightInvOn g f B) (hf : IsMulFreimanIso n A B f) : IsMulFreimanIso n B A g where @@ -152,7 +156,11 @@ lemma IsMulFreimanIso.symm {g : β → α} (hg₁ : MapsTo g B A) (hg₂ : Right If the inverse of a Freiman homomorphism is itself a Freiman homomorphism, then it is a Freiman isomorphism. -/ -@[to_additive] +@[to_additive +/-- +If the inverse of a Freiman homomorphism is itself a Freiman homomorphism, then it is a Freiman +isomorphism. +-/] lemma IsMulFreimanHom.to_isMulFreimanIso {g : β → α} (h : InvOn g f A B) (hf : IsMulFreimanHom n A B f) (hg : IsMulFreimanHom n B A g) : IsMulFreimanIso n A B f where diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index a0676d26cc1069..bf9a75e82362f4 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -57,7 +57,8 @@ attribute [local instance] Ultrafilter.mul Ultrafilter.add /-- We could have taken this as the definition of `U * V`, but then we would have to prove that it defines an ultrafilter. -/ -@[to_additive] +@[to_additive /-- We could have taken this as the definition of `U + V`, but then we would have to +prove that it defines an ultrafilter. -/] theorem Ultrafilter.eventually_mul {M} [Mul M] (U V : Ultrafilter M) (p : M → Prop) : (∀ᶠ m in ↑(U * V), p m) ↔ ∀ᶠ m in U, ∀ᶠ m' in V, p (m * m') := Iff.rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Cayley.lean b/Mathlib/Combinatorics/SimpleGraph/Cayley.lean index 6d2f3ca78c0c31..1c16c88849526e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Cayley.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Cayley.lean @@ -66,7 +66,7 @@ instance [Fintype M] [DecidableEq M] [DecidablePred (· ∈ s)] : variable (M) in /-- `mulCayley` is a left (order-)adjoint. -/ -@[to_additive] +@[to_additive /-- `addCayley` is a left (order-)adjoint. -/] lemma mulCayley_gc : GaloisConnection (mulCayley ·) ({g : M | ∀ a, a * g ≠ a → ·.Adj (a * g) a}) := by intro S G diff --git a/Mathlib/Data/Finset/NoncommProd.lean b/Mathlib/Data/Finset/NoncommProd.lean index 08af78bf0a4589..7ad1a75b91714e 100644 --- a/Mathlib/Data/Finset/NoncommProd.lean +++ b/Mathlib/Data/Finset/NoncommProd.lean @@ -234,7 +234,7 @@ variable [Monoid β] [Monoid γ] open scoped Function -- required for scoped `on` notation /-- Proof used in definition of `Finset.noncommProd` -/ -@[to_additive] +@[to_additive /-- Proof used in definition of `Finset.noncommSum` -/] theorem noncommProd_lemma (s : Finset α) (f : α → β) (comm : (s : Set α).Pairwise (Commute on f)) : Set.Pairwise { x | x ∈ Multiset.map f s.val } Commute := Multiset.map_set_pairwise comm diff --git a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean index 72e5102b5e7191..be64434cf5e88c 100644 --- a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean +++ b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean @@ -157,14 +157,18 @@ def mulShift (g : G) (x : G → A) : G → A := ext h; simp [mulShift] /-- Composition of left-translation shifts corresponds to multiplication in the monoid `G`. -/ -@[to_additive] lemma mulShift_mul (g₁ g₂ : G) (x : G → A) : +@[to_additive +/-- Composition of left-translation shifts corresponds to addition in the additive monoid `G`. -/] +lemma mulShift_mul (g₁ g₂ : G) (x : G → A) : mulShift (g₁ * g₂) x = mulShift g₂ (mulShift g₁ x) := by ext h; simp [mulShift, mul_assoc] variable [TopologicalSpace A] /-- The left-translation shift is continuous. -/ -@[to_additive (attr := fun_prop)] lemma continuous_mulShift (g : G) : +@[to_additive (attr := fun_prop) +/-- The left-translation shift is continuous. -/] +lemma continuous_mulShift (g : G) : Continuous (mulShift (A := A) g) := by -- coordinate projections are continuous; composition preserves continuity unfold mulShift @@ -511,7 +515,7 @@ variable {A : Type*} [TopologicalSpace A] [Inhabited A] variable {G : Type*} [Monoid G] [IsLeftCancelMul G] /-- Occurrence sets are open. -/ -@[to_additive isOpen_occursInAt] +@[to_additive isOpen_occursInAt /-- Occurrence sets are open. -/] lemma isOpen_mulOccursInAt [DiscreteTopology A] (p : Pattern A G) (g : G) : IsOpen { x | p.mulOccursInAt x g } := by simpa [mulOccursInAt_eq_cylinder] using isOpen_cylinder _ _ @@ -543,7 +547,7 @@ lemma isClosed_mulForbidden [DiscreteTopology A] (F : Set (Pattern A G)) : simpa [this, isClosed_compl_iff] using isOpen_mulOccursInAt (A := A) (G := G) p v /-- Occurrence sets are closed. -/ -@[to_additive isClosed_occursInAt] +@[to_additive isClosed_occursInAt /-- Occurrence sets are closed. -/] lemma isClosed_mulOccursInAt [T1Space A] (p : Pattern A G) (g : G) : IsClosed { x | p.mulOccursInAt x g } := by simpa [mulOccursInAt_eq_cylinder] using isClosed_cylinder _ _ From 4dfbeb6dfa69a6b2c28277a4b0dff2df999761bf Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Fri, 7 Aug 2026 07:33:59 +0000 Subject: [PATCH 1208/1300] feat: add_group tactic (#37067) Written by Claude Code, additivising the `group` tactic, although there were some problems which needed human input. --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + Mathlib/Tactic/AddGroup.lean | 139 +++++++++++++++++++++++++++++++ MathlibTest/Tactic/AddGroup.lean | 92 ++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 Mathlib/Tactic/AddGroup.lean create mode 100644 MathlibTest/Tactic/AddGroup.lean diff --git a/Mathlib.lean b/Mathlib.lean index 5f7b2044a6311c..d75aa9be19bf0d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7238,6 +7238,7 @@ public import Mathlib.SetTheory.ZFC.VonNeumann public import Mathlib.Tactic public import Mathlib.Tactic.Abel public import Mathlib.Tactic.AdaptationNote +public import Mathlib.Tactic.AddGroup public import Mathlib.Tactic.Algebra.AlgebraNF public import Mathlib.Tactic.Algebra.Basic public import Mathlib.Tactic.Algebra.Lemmas diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 506ca9ab5e4963..32e81e1659ee12 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -2,6 +2,7 @@ module -- shake: keep-all --deprecated_module: ignore public import Mathlib.Tactic.Abel public import Mathlib.Tactic.AdaptationNote +public import Mathlib.Tactic.AddGroup public import Mathlib.Tactic.Algebra.AlgebraNF public import Mathlib.Tactic.Algebra.Basic public import Mathlib.Tactic.Algebra.Lemmas diff --git a/Mathlib/Tactic/AddGroup.lean b/Mathlib/Tactic/AddGroup.lean new file mode 100644 index 00000000000000..372dfd82a87f69 --- /dev/null +++ b/Mathlib/Tactic/AddGroup.lean @@ -0,0 +1,139 @@ +/- +Copyright (c) 2026 Kevin Buzzard. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kevin Buzzard +-/ +module + +public import Mathlib.Tactic.Group + +/-! +# `add_group` tactic + +Normalizes expressions in the language of additive groups. The basic idea is to use the simplifier +to put everything into a sum of integer scalar multiples (`zsmul` which takes an integer and an +additive group element), then simplify the scalars using the `ring_nf` tactic. The process needs +to be repeated since `ring_nf` can normalize a scalar to zero, leading to a summand that can be +removed before collecting scalars again. The simplifier step also uses some extra lemmas to avoid +some `ring_nf` invocations. + +Note: Unlike the multiplicative `group` tactic which uses `← zpow_neg_one` to convert `a⁻¹` to +`a ^ (-1 : ℤ)`, the additive version cannot use `← neg_one_zsmul` to convert `-a` to +`(-1 : ℤ) • a` because `(-1 : ℤ)` is itself `-(1 : ℤ)`, causing simp to loop (since `ℤ` is also +an `AddGroup`). Instead, we handle negation via `neg_add_rev` to distribute negation over sums, +`zsmul_neg`/`neg_zsmul` for `n • (-a)`, and custom trick lemmas for combining `-b` with adjacent +`zsmul` terms. We also use `neg_one_zsmul` in the forward direction to normalize `(-1) • b` +to `-b`. + +For the same reason (`ℤ` is itself an `AddGroup`), `sub_eq_add_neg` is applied once as a +preprocessing step rather than being part of the main simp set: inside the loop it would also +rewrite the subtractions that `ring_nf` reintroduces in `ℤ` scalars (e.g. `k - n` in +`(k - n) • a`), and the two would undo each other forever. That cycle is harmless in goal mode, +where `fail_if_no_progress` compares goal types, but rewriting a hypothesis allocates a fresh +`fvarId` each round, which counts as progress, so `add_group at h` would never terminate. +Preprocessing loses no proving power because nothing in the loop ever creates a new subtraction +of group elements. + +Other than this issue, the strategy parallels Thomas Browning and Patrick Massot's `group` +tactic. + +## TODO + +- Surface non-progress-related errors from `repeat`. +- Allow `add_group`s `ifUnchanged` behavior to be configurable. + +## Tags + +group theory, additive group +-/ + +public meta section + +namespace Mathlib.Tactic.AddGroup + +open Lean Meta Parser Tactic + +-- The next six lemmas are not general purpose lemmas; they are intended for use only by +-- the `add_group` tactic, and so are prefixed with `_` to keep them out of autocomplete. +-- They handle the case where a negated element `-b` appears adjacent to a `zsmul` of the same +-- element, or adjacent to another negated copy. +-- This means we also want to convert `(-1) • b` to `-b` in order to apply these lemmas. +theorem _zsmul_neg_trick {G : Type*} [AddGroup G] (b : G) (n : ℤ) : + n • b + (-b) = (n + (-1)) • b := by + rw [← neg_one_zsmul b, ← add_zsmul] + +theorem _neg_zsmul_trick {G : Type*} [AddGroup G] (b : G) (n : ℤ) : + (-b) + n • b = ((-1) + n) • b := by + rw [← neg_one_zsmul b, ← add_zsmul] + +theorem _neg_neg_trick {G : Type*} [AddGroup G] (b : G) : + (-b) + (-b) = (-2 : ℤ) • b := by + have h : -b = (-1 : ℤ) • b := (neg_one_zsmul b).symm + rw [h, ← add_zsmul]; norm_num + +theorem _add_zsmul_neg_trick {G : Type*} [AddGroup G] (a b : G) (n : ℤ) : + a + n • b + (-b) = a + (n + (-1)) • b := by + rw [add_assoc, _zsmul_neg_trick] + +theorem _add_neg_zsmul_trick {G : Type*} [AddGroup G] (a b : G) (n : ℤ) : + a + (-b) + n • b = a + ((-1) + n) • b := by + rw [add_assoc, _neg_zsmul_trick] + +theorem _add_neg_neg_trick {G : Type*} [AddGroup G] (a b : G) : + a + (-b) + (-b) = a + (-2 : ℤ) • b := by + rw [add_assoc, _neg_neg_trick] + +/-- +`add_group` normalizes expressions in additive groups without assuming commutativity. Unlike +`abel`, which does take advantage of commutativity, `add_group` instead only uses the additive +group axioms without any information about which group is manipulated. If the goal is an equality, +and after normalization the two sides are equal, `add_group` closes the goal. + +`add_group at l1 l2 ...` normalizes at the given locations. + +For additive commutative groups, use the `abel` tactic instead. +For multiplicative groups, use the `group` tactic instead. + +Example: +```lean +example {G : Type} [AddGroup G] (a b c d : G) (h : c = (a + 2 • b) + (-(b + b) + (-a)) + d) : + a + c + (-d) = a := by + add_group at h -- normalizes `h` which becomes `h : c = d` + rw [h] -- the goal is now `a + d + (-d) = a` + add_group -- which is then normalized and closed +``` +-/ +syntax (name := addGroup) "add_group" (location)? : tactic + +macro_rules +| `(tactic| add_group $[$loc]?) => + `(tactic| first + | fail_if_no_progress + simp -decide -failIfUnchanged only [sub_eq_add_neg] $[$loc]? + repeat fail_if_no_progress + (simp -decide -failIfUnchanged only + [addCommutatorElement_def, add_zero, zero_add, + neg_add_rev, neg_zero, zsmul_neg, ← neg_zsmul, + ← natCast_zsmul, ← mul_zsmul', + Int.natCast_add, Int.natCast_mul, neg_neg, + zsmul_zero, zero_zsmul, one_zsmul, neg_one_zsmul, + ← add_assoc, + ← add_zsmul, ← add_one_zsmul, ← one_add_zsmul, + Mathlib.Tactic.Group._zsmul_trick, + Mathlib.Tactic.Group._zsmul_trick_one, + Mathlib.Tactic.Group._zsmul_trick_one', + _zsmul_neg_trick, _neg_zsmul_trick, _neg_neg_trick, + _add_zsmul_neg_trick, _add_neg_zsmul_trick, _add_neg_neg_trick, + add_neg_cancel_right, neg_add_cancel_right, + tsub_self, sub_self, add_neg_cancel, neg_add_cancel] + $[$loc]? + <;> ring_nf (ifUnchanged := .silent) $[$loc]?) + | fail "`add_group` made no progress") + +end Mathlib.Tactic.AddGroup + +/-! +We register `add_group` with the `hint` tactic. +-/ + +register_hint 900 add_group diff --git a/MathlibTest/Tactic/AddGroup.lean b/MathlibTest/Tactic/AddGroup.lean new file mode 100644 index 00000000000000..e65f435a374720 --- /dev/null +++ b/MathlibTest/Tactic/AddGroup.lean @@ -0,0 +1,92 @@ +module +import Mathlib.Tactic.AddGroup + +open scoped addCommutatorElement + +variable {G : Type} [AddGroup G] + +example (a b c : G) : c + (a + b) + (-b + -a) + c = c + c := by add_group + +example (a b c : G) : (b + -c) + c + (a + b) + (-b + -a) + c = b + c := by add_group + +example (a b c : G) : -c + (b + -c) + c + (a + b) + (-b + -a + -b) + c = 0 := by add_group + +-- The following is known as the Hall-Witt identity, +-- see e.g. +-- https://en.wikipedia.org/wiki/Three_subgroups_lemma#Proof_and_the_Hall%E2%80%93Witt_identity +example (g h k : G) : + g + ⁅⁅-g, h⁆, k⁆ + -g + k + ⁅⁅-k, g⁆, h⁆ + -k + h + ⁅⁅-h, k⁆, g⁆ + -h = 0 := by add_group + +example (a : G) : 2 • a + a = 3 • a := by add_group + +example (n m : ℕ) (a : G) : n • a + m • a = (n + m) • a := by add_group + +example (a b c : G) : c + (a + 2 • b) + (-(b + b) + -a) + c = c + c := by add_group + +example (n : ℕ) (a : G) : n • a + n • (-a) = 0 := by add_group + +example (a : G) : 2 • a + -a + -a = 0 := by add_group + +example (n m : ℕ) (a : G) : n • a + m • a = (m + n) • a := by add_group + +example (n : ℕ) (a : G) : (n - n) • a = 0 := by add_group + +example (n : ℤ) (a : G) : (n - n) • a = 0 := by add_group + +example (b : G) {n : ℤ} : (-b) + n • b = (n - 1) • b := by add_group + +example (b : G) : (-b) + (-b) = (-2) • b := by add_group + +example (b : G) {n : ℤ} : n • b + (-b) = (n - 1) • b := by add_group + +example (b : G) : -b = (-1) • b := by add_group + +example (n : ℤ) (a : G) (h : (n * (n + 1) - n - n ^ 2) • a = a) : a = 0 := by + add_group at h + exact h.symm + +example (a b c d : G) (h : c = (a + 2 • b) + (-(b + b) + -a) + d) : a + c + -d = a := by + add_group at h + rw [h] + add_group + +-- The next example can be expanded to require an arbitrarily high number of alternations +-- between simp and ring + +example (n m : ℤ) (a b : G) : (m - n) • a + (m - n) • b + (n - m) • b + (n - m) • a = 0 := by + add_group + +example (n : ℤ) (a b : G) : + n • a + n • b + n • a + n • a + (-n) • a + (-n) • a + (-n) • b + (-n) • a = 0 := by add_group + +-- Test that add_group deals with `-(0)` properly + +example (x y : G) : -((-x) + (x + y) + (-y)) = 0 := by add_group + +/- The next three example check that `add_group at h` does not loop forever when there's +an integer subtraction. `sub_eq_add_neg` is applied only as a preprocessing step +in `add_group` (rather than in the main loop) to ensure that these work. -/ + +example (n k : ℤ) (x : G) (h : (k - n) • x = 0) : (k - n) • x = 0 := by + add_group at h + exact h + +example (n k : ℤ) (x : G) (h : (k - n) • x + 0 = 0) : (k - n) • x = 0 := by + add_group at h + exact h + +example (m k : ℤ) (x : G) (h : k • (m • x + -(k • x)) = 0) : k • (m • x + -(k • x)) = 0 := by + add_group at h ⊢ + exact h + +/-- +error: `add_group` made no progress +G : Type +inst✝ : AddGroup G +x : G +h : x = 0 +⊢ x = 0 +-/ +#guard_msgs in +example (x : G) (h : x = 0) : x = 0 := by + add_group From 38c06cd7f3512c1a75917dd29ed435b7bdfa67cf Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 7 Aug 2026 10:05:42 +0000 Subject: [PATCH 1209/1300] chore: make arguments explicit in `nonempty_of_nonempty_constants` (#42508) Make arguments `L` and `M` explicit in `FirstOrder.Language.nonempty_of_nonempty_constants`, since `L` is never inferable and `M` is only inferable from the expected type. Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/ModelTheory/Basic.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/ModelTheory/Basic.lean b/Mathlib/ModelTheory/Basic.lean index a35bc74f7b8a5e..b9bfcec65745e6 100644 --- a/Mathlib/ModelTheory/Basic.lean +++ b/Mathlib/ModelTheory/Basic.lean @@ -236,6 +236,7 @@ instance : CoeTC L.Constants M := theorem funMap_eq_coe_constants {c : L.Constants} {x : Fin 0 → M} : funMap c x = c := congr rfl (funext finZeroElim) +variable (L M) in /-- Given a language with a nonempty type of constants, any structure will be nonempty. This cannot be a global instance, because `L` becomes a metavariable. -/ theorem nonempty_of_nonempty_constants [h : Nonempty L.Constants] : Nonempty M := From 50a1a3609f97d1a965d8eaba5088d846dab11dce Mon Sep 17 00:00:00 2001 From: Rao Xiaojia <7247037+raoxiaojia@users.noreply.github.com> Date: Fri, 7 Aug 2026 12:48:53 +0000 Subject: [PATCH 1210/1300] feat(LinearAlgebra/Matrix): add echelon form decomposition certificate structure (#42525) This PR adds the structure of the echelon form decomposition certificate and provides one lemma that derives the rank of a matrix from the pivot. Co-authored-by: raoxiaojia --- Mathlib.lean | 1 + .../Matrix/Echelon/Decomposition.lean | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 Mathlib/LinearAlgebra/Matrix/Echelon/Decomposition.lean diff --git a/Mathlib.lean b/Mathlib.lean index d75aa9be19bf0d..4d9172b86e4052 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5138,6 +5138,7 @@ public import Mathlib.LinearAlgebra.Matrix.DotProduct public import Mathlib.LinearAlgebra.Matrix.Dual public import Mathlib.LinearAlgebra.Matrix.DualNumber public import Mathlib.LinearAlgebra.Matrix.Echelon.Basic +public import Mathlib.LinearAlgebra.Matrix.Echelon.Decomposition public import Mathlib.LinearAlgebra.Matrix.Echelon.Pivot public import Mathlib.LinearAlgebra.Matrix.FiniteDimensional public import Mathlib.LinearAlgebra.Matrix.FixedDetMatrices diff --git a/Mathlib/LinearAlgebra/Matrix/Echelon/Decomposition.lean b/Mathlib/LinearAlgebra/Matrix/Echelon/Decomposition.lean new file mode 100644 index 00000000000000..c3f338c695b7fc --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Echelon/Decomposition.lean @@ -0,0 +1,63 @@ +/- +Copyright (c) 2026 Rao Xiaojia. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Rao Xiaojia +-/ +module + +public import Mathlib.LinearAlgebra.Matrix.Echelon.Pivot + +/-! +# Echelon decomposition certificates + +`Echelon.Decomposition A` certifies an echelon decomposition of the matrix `A`. + +## Main definitions + +- `Echelon.Decomposition`: the certificate structure. + +## Main results + +- `Echelon.Decomposition.rank_eq`: `A.rank` is the pivot count of any certificate for `A`. + +## Tags + +matrix, echelon form +-/ + +public section + +variable + {m : Type*} [Fintype m] [LinearOrder m] + {n : Type*} [Fintype n] [LinearOrder n] + {R : Type*} [CommRing R] [IsDomain R] + +namespace Echelon + +open scoped Finset + +/-- A certificate of an echelon form decomposition of `A`, certifying that +`L * (A.submatrix σ id)` is in echelon form by providing a pivot, where `L` +is lower triangular with nonzero diagonal, and `σ` the permutation on the rows +of `A`. +This version does not store the final echelon form itself as it can be computed +by the data enclosed. +-/ +structure Decomposition (A : Matrix m n R) where + /-- The transformation matrix. -/ + L : Matrix m m R + /-- The row permutation on the rows of `A`. -/ + σ : Equiv.Perm m + /-- The pivot of the resulting echelon form. -/ + pivot : m → WithTop n + isPivotedBy : (L * (A.submatrix σ id)).IsPivotedBy pivot + L_lowerTriangular : L.IsLowerTriangular + L_diag_ne_zero (i : m) : L.diag i ≠ 0 + +theorem Decomposition.rank_eq {A : Matrix m n R} (cert : Decomposition A) : + A.rank = #{i | cert.pivot i ≠ ⊤} := by + rw [← cert.isPivotedBy.rank_eq, + cert.L.rank_mul_eq_right_of_isLowerTriangular _ cert.L_lowerTriangular cert.L_diag_ne_zero] + exact (A.rank_submatrix cert.σ (.refl _)).symm + +end Echelon From ac10dc7e9a3d44afd90aaeab0b5246310ac3c787 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:02:47 +0000 Subject: [PATCH 1211/1300] feat(Tactic/Linter/UnusedTactic): also lint inside `conv =>` (#42416) This PR extends the unused tactic linter to also lint inside `conv =>`/`conv_lhs =>`/`slice_lhs i j =>`. It is sometimes neccessary to use the `skip` conv mode tactic to skip goals you don't want to conv into, so I added the conv mode skip to the list of exception tactics. I also added a test, and did some general cleanup: - The warning message of the linter is improved. - The hard-coded exception that `#show_kind` had, is replaced with just adding it to the list of exceptions. After this, the unused tactic linter will (almost entirely) subsume the unreachable tactic linter. So, we will be able to turn it off, which will gain us quite a bit of performance. --- Mathlib/CategoryTheory/Limits/Fubini.lean | 8 ++--- .../Limits/Shapes/IsTerminal.lean | 1 - Mathlib/CategoryTheory/Monoidal/Hopf_.lean | 4 --- Mathlib/Tactic/Linter/UnusedTactic.lean | 19 +++++----- .../Tactic/Linter/UnusedTacticExtension.lean | 8 +++-- MathlibTest/Linter/UnusedTactic.lean | 35 +++++++++++++++++-- MathlibTest/TacticAnalysis.lean | 2 +- 7 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Fubini.lean b/Mathlib/CategoryTheory/Limits/Fubini.lean index 1dad10d3e098ef..21003d60bffaca 100644 --- a/Mathlib/CategoryTheory/Limits/Fubini.lean +++ b/Mathlib/CategoryTheory/Limits/Fubini.lean @@ -591,7 +591,7 @@ theorem colimitFlipCompColimIsoColimitCompColim_ι_ι_hom (j) (k) : (colimitFlipCompColimIsoColimitCompColim F).hom = (colimit.ι _ k ≫ colimit.ι (F ⋙ colim) j : _ ⟶ colimit (F ⋙ colim)) := by dsimp [colimitFlipCompColimIsoColimitCompColim] - slice_lhs 1 3 => simp only + conv_lhs => slice 1 3 simp [Equivalence.unit] set_option backward.defeqAttrib.useBackward true in @@ -602,7 +602,7 @@ theorem colimitFlipCompColimIsoColimitCompColim_ι_ι_inv (k) (j) : (colimitFlipCompColimIsoColimitCompColim F).inv = (colimit.ι _ j ≫ colimit.ι (F.flip ⋙ colim) k : _ ⟶ colimit (F.flip ⋙ colim)) := by dsimp [colimitFlipCompColimIsoColimitCompColim] - slice_lhs 1 3 => simp only + conv_lhs => slice 1 3 simp [Equivalence.counitInv] end @@ -737,7 +737,7 @@ theorem colimitCurrySwapCompColimIsoColimitCurryCompColim_ι_ι_hom {j} {k} : (colimit.ι _ k ≫ colimit.ι (curry.obj G ⋙ colim) j : _ ⟶ colimit (curry.obj G ⋙ colim)) := by dsimp [colimitCurrySwapCompColimIsoColimitCurryCompColim] - slice_lhs 1 3 => simp only + conv_lhs => slice 1 3 simp set_option backward.defeqAttrib.useBackward true in @@ -750,7 +750,7 @@ theorem colimitCurrySwapCompColimIsoColimitCurryCompColim_ι_ι_inv {j} {k} : colimit.ι (curry.obj _ ⋙ colim) k : _ ⟶ colimit (curry.obj (Prod.swap K J ⋙ G) ⋙ colim)) := by dsimp [colimitCurrySwapCompColimIsoColimitCurryCompColim] - slice_lhs 1 3 => simp only + conv_lhs => slice 1 3 rw [colimitIsoColimitCurryCompColim_ι_ι_inv, HasColimit.ι_isoOfEquivalence_inv] dsimp [Equivalence.counitInv] rw [CategoryTheory.Bifunctor.map_id] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean index 9af0efb66f76d6..a90d47c2ce42fa 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/IsTerminal.lean @@ -355,7 +355,6 @@ def limitOfDiagramInitial {X : J} (tX : IsInitial X) (F : J ⥤ C) : IsLimit (coneOfDiagramInitial tX F) where lift s := s.π.app X uniq s m w := by - conv_lhs => dsimp simp_rw [← w X, coneOfDiagramInitial_π_app, tX.hom_ext (tX.to X) (𝟙 _)] simp diff --git a/Mathlib/CategoryTheory/Monoidal/Hopf_.lean b/Mathlib/CategoryTheory/Monoidal/Hopf_.lean index f0d268a1ff1cf1..ac547ae9def757 100644 --- a/Mathlib/CategoryTheory/Monoidal/Hopf_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Hopf_.lean @@ -238,7 +238,6 @@ theorem antipode_comul₂ (A : C) [HopfObj A] : slice_lhs 2 3 => simp only [← whiskerLeft_comp] rw [ComonObj.counit_comul] - simp only [whiskerLeft_comp] slice_lhs 3 4 => simp only [← whiskerLeft_comp] rw [BraidedCategory.braiding_naturality_left] @@ -386,7 +385,6 @@ theorem mul_antipode₂ (A : C) [HopfObj A] : slice_lhs 6 7 => simp only [← whiskerLeft_comp] rw [MonObj.one_mul] - simp only [whiskerLeft_comp] slice_lhs 3 4 => simp only [← whiskerLeft_comp] rw [← BraidedCategory.braiding_naturality_left] @@ -400,7 +398,6 @@ theorem mul_antipode₂ (A : C) [HopfObj A] : slice_lhs 6 7 => simp only [← whiskerLeft_comp] rw [Iso.inv_hom_id] - simp only [whiskerLeft_comp] simp only [whiskerLeft_id, Category.id_comp] slice_lhs 5 6 => rw [whiskerLeft_rightUnitor, Category.assoc, ← rightUnitor_naturality] @@ -414,7 +411,6 @@ theorem mul_antipode₂ (A : C) [HopfObj A] : slice_lhs 2 3 => rw [← whisker_exchange] slice_lhs 1 2 => - dsimp rw [← tensorHom_def] slice_lhs 2 3 => rw [rightUnitor_naturality] diff --git a/Mathlib/Tactic/Linter/UnusedTactic.lean b/Mathlib/Tactic/Linter/UnusedTactic.lean index 1127477501760d..b2a8fad95429b8 100644 --- a/Mathlib/Tactic/Linter/UnusedTactic.lean +++ b/Mathlib/Tactic/Linter/UnusedTactic.lean @@ -36,8 +36,6 @@ before and after and see if there is some change. ## Notable exclusions -* `conv` is completely ignored by the linter. - * The linter does not enter a "sequence tactic": upon finding `tac <;> [tac1, tac2, ...]` the linter assumes that the tactic is doing something and does not recurse into each `tac1, tac2, ...`. @@ -82,12 +80,14 @@ abbrev M := StateRefT (Std.HashMap Lean.Syntax.Range Syntax) IO Lean.Parser.Tactic.tacticTry_ -- the following `SyntaxNodeKind`s play a role in silencing `test`s Lean.Parser.Tactic.guardHyp + Lean.Parser.Tactic.guardHypConv Lean.Parser.Tactic.guardTarget + Lean.Parser.Tactic.guardTargetConv Lean.Parser.Tactic.failIfSuccess /-- A list of blocklisted syntax kinds, which are expected to have subterms that contain -unevaluated tactics. +unused tactics. -/ initialize ignoreTacticKindsRef : IO.Ref NameHashSet ← IO.mkRef <| .ofArray #[ @@ -99,7 +99,6 @@ initialize ignoreTacticKindsRef : IO.Ref NameHashSet ← ``Lean.Parser.Command.notation, ``Lean.Parser.Command.mixfix, ``Lean.Parser.Tactic.discharger, - ``Lean.Parser.Tactic.Conv.conv, ``Lean.Parser.Command.registerTryTactic, `Batteries.Tactic.seq_focus, `Mathlib.Tactic.Hint.registerHintStx, @@ -108,6 +107,7 @@ initialize ignoreTacticKindsRef : IO.Ref NameHashSet ← `Aesop.Frontend.Parser.addRules, `Aesop.Frontend.Parser.aesopTactic, `Aesop.Frontend.Parser.aesopTactic?, + ``Mathlib.Linter.UnusedTactic.«command#show_kind_», -- the following `SyntaxNodeKind`s play a role in silencing `test`s ``Lean.Parser.Tactic.failIfSuccess, `Mathlib.Tactic.successIfFailWithMsg, @@ -116,8 +116,6 @@ initialize ignoreTacticKindsRef : IO.Ref NameHashSet ← /-- Is this a syntax kind that contains intentionally unused tactic subterms? -/ def isIgnoreTacticKind (ignoreTacticKinds : NameHashSet) (k : SyntaxNodeKind) : Bool := - k.components.contains `Conv || - "slice".isPrefixOf k.toString || k matches .str _ "quot" || ignoreTacticKinds.contains k @@ -128,12 +126,12 @@ This should be called from an `initialize` block. def addIgnoreTacticKind (kind : SyntaxNodeKind) : IO Unit := ignoreTacticKindsRef.modify (·.insert kind) -variable (ignoreTacticKinds : NameHashSet) (isTacKind : SyntaxNodeKind → Bool) in /-- Accumulates the set of tactic syntaxes that should be evaluated at least once. -/ -@[specialize] partial def getTactics (stx : Syntax) : M Unit := do +@[specialize] partial def getTactics (ignoreTacticKinds : NameHashSet) + (isTacKind : SyntaxNodeKind → Bool) (stx : Syntax) : M Unit := do if let .node _ k args := stx then if !isIgnoreTacticKind ignoreTacticKinds k then - args.forM getTactics + args.forM (getTactics ignoreTacticKinds isTacKind) if isTacKind k then if let some r := stx.getRange? true then modify fun m => m.insert r stx @@ -175,7 +173,6 @@ def unusedTacticLinter : Linter where run := withSetOptionIn fun stx => do return if (← get).messages.hasErrors then return - if stx.isOfKind ``Mathlib.Linter.UnusedTactic.«command#show_kind_» then return let env ← getEnv let cats := (Parser.parserExtension.getState env).categories -- These lookups may fail when the linter is run in a fresh, empty environment @@ -196,7 +193,7 @@ def unusedTacticLinter : Linter where run := withSetOptionIn fun stx => do if stx.getKind ∈ [``Batteries.Tactic.unreachable, ``Batteries.Tactic.unreachableConv] then continue if last.start ≤ r.start && r.stop ≤ last.stop then continue - Linter.logLint linter.unusedTactic stx m!"'{stx}' tactic does nothing" + Linter.logLint linter.unusedTactic stx m!"Unused tactic linter: `{stx}` does nothing" last := r initialize addLinter unusedTacticLinter diff --git a/Mathlib/Tactic/Linter/UnusedTacticExtension.lean b/Mathlib/Tactic/Linter/UnusedTacticExtension.lean index 2847580ed63e20..364c00bbb849aa 100644 --- a/Mathlib/Tactic/Linter/UnusedTacticExtension.lean +++ b/Mathlib/Tactic/Linter/UnusedTacticExtension.lean @@ -58,17 +58,19 @@ public initialize allowedRef : IO.Ref (Std.HashSet SyntaxNodeKind) ← `by, `null, `«]», - `Lean.Parser.Tactic.show, + ``Lean.Parser.Tactic.show, -- the following `SyntaxNodeKind`s play a role in silencing `test`s `Mathlib.Tactic.successIfFailWithMsg, `Mathlib.Tactic.failIfNoProgress, `Mathlib.Tactic.ExtractGoal.extractGoal, - `Lean.Parser.Tactic.traceState, + ``Lean.Parser.Tactic.traceState, + ``Lean.Parser.Tactic.Conv.convTrace_state, `Mathlib.Tactic.tacticMatch_target_, `change?, `«tactic#adaptation_note_», `tacticSleep_heartbeats_, - `Mathlib.Tactic.«tacticRename_bvar_→__» + `Mathlib.Tactic.«tacticRename_bvar_→__», + ``Lean.Parser.Tactic.Conv.skip ] /-- diff --git a/MathlibTest/Linter/UnusedTactic.lean b/MathlibTest/Linter/UnusedTactic.lean index 2991ffbb29eaca..a6bc6c480fe93d 100644 --- a/MathlibTest/Linter/UnusedTactic.lean +++ b/MathlibTest/Linter/UnusedTactic.lean @@ -11,7 +11,7 @@ example : 0 + 1 = 1 := by rfl /-- -warning: 'change 1 = 1' tactic does nothing +warning: Unused tactic linter: `change 1 = 1` does nothing Note: This linter can be disabled with `set_option linter.unusedTactic false` -/ @@ -33,11 +33,11 @@ example : True ∧ True := by set_option linter.unusedTactic true /-- -warning: 'congr' tactic does nothing +warning: Unused tactic linter: `congr` does nothing Note: This linter can be disabled with `set_option linter.unusedTactic false` --- -warning: 'done' tactic does nothing +warning: Unused tactic linter: `done` does nothing Note: This linter can be disabled with `set_option linter.unusedTactic false` -/ @@ -48,6 +48,35 @@ example : True := by constructor done +/-- +warning: Unused tactic linter: `show False` does nothing + +Note: This linter can be disabled with `set_option linter.unusedTactic false` +-/ +#guard_msgs in +example : True := by + show True -- `show` does not warn. + guard_target = True -- `guard_target` also does not warn + trivial <;> show False -- But, if it doesn't run at all, `show` does warn. + +/-- +warning: Unused tactic linter: `simp` does nothing + +Note: This linter can be disabled with `set_option linter.unusedTactic false` +-/ +#guard_msgs in +example : True := by + conv => + skip -- `skip` in `conv` mode does not warn. + guard_target = True -- `guard_target` also does not warn + simp -- other tactics in `conv` mode do warn + trivial + +example (a b : Nat) (h : a + 1 ≤ b + 1) : max a b ≤ b := by + -- The linter does not look inside of dischargers, no matter whether it's actually used or not. + have : True := by simp (disch := grind) + simp (disch := grind) [Nat.max_eq_right] + section allowing_more_unused_tactics /-- info: The `SyntaxNodeKind` is 'Lean.Parser.Tactic.refine'. -/ diff --git a/MathlibTest/TacticAnalysis.lean b/MathlibTest/TacticAnalysis.lean index 102dcc1d42e91b..79a59dd11601df 100644 --- a/MathlibTest/TacticAnalysis.lean +++ b/MathlibTest/TacticAnalysis.lean @@ -363,7 +363,7 @@ info: `skip` (+1 later steps) can be replaced with `grind` --- info: `rfl` can be replaced with `grind` --- -warning: 'skip' tactic does nothing +warning: Unused tactic linter: `skip` does nothing Note: This linter can be disabled with `set_option linter.unusedTactic false` -/ From 87adeaebd370a3b6a41ac4f044fddd4bf81803ad Mon Sep 17 00:00:00 2001 From: Robin Carlier Date: Fri, 7 Aug 2026 18:34:25 +0000 Subject: [PATCH 1212/1300] chore: namespace `CategoryTheory.isoMk` to `CategoryTheory.WideSubcategory.isoMk` (#42532) --- Mathlib/CategoryTheory/Widesubcategory.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Widesubcategory.lean b/Mathlib/CategoryTheory/Widesubcategory.lean index cfd6f292c8d188..4d122d6f5edcfc 100644 --- a/Mathlib/CategoryTheory/Widesubcategory.lean +++ b/Mathlib/CategoryTheory/Widesubcategory.lean @@ -137,11 +137,13 @@ instance wideSubcategory.faithful : (wideSubcategoryInclusion P).Faithful := variable {P} in /-- Build an isomorphism in `WideSubcategory P` from an isomorphism in `C`. -/ @[simps!] -def isoMk {X Y : WideSubcategory P} (e : X.obj ≅ Y.obj) +def WideSubcategory.isoMk {X Y : WideSubcategory P} (e : X.obj ≅ Y.obj) (h₁ : P e.hom) (h₂ : P e.inv) : X ≅ Y where hom := ⟨e.hom, h₁⟩ inv := ⟨e.inv, h₂⟩ +@[deprecated (since := "2026-08-07")] alias isoMk := WideSubcategory.isoMk + end WideSubcategory end CategoryTheory From 641fbd329d4ffb62bef83c51f54088469056bd36 Mon Sep 17 00:00:00 2001 From: Wrenna Robson Date: Sat, 8 Aug 2026 15:51:43 +0000 Subject: [PATCH 1213/1300] feat(Logic/Function/Defs): add `Function.diag` (#41082) Adds a name for the function `fun x => (x, x)`. --- Mathlib/Data/Finset/Prod.lean | 3 +- Mathlib/Data/Set/Prod.lean | 11 ++-- Mathlib/Logic/Function/Defs.lean | 51 +++++++++++++++++-- .../MeasurableSpace/Constructions.lean | 7 +++ Mathlib/NumberTheory/Height/Basic.lean | 2 +- Mathlib/Order/Filter/Prod.lean | 2 +- .../Probability/Independence/Conditional.lean | 5 +- Mathlib/Probability/Kernel/Basic.lean | 2 +- .../Kernel/Composition/MeasureComp.lean | 6 +-- .../Kernel/Composition/MeasureCompProd.lean | 6 +-- Mathlib/Probability/Kernel/Condexp.lean | 28 +++++----- Mathlib/Probability/Kernel/Deterministic.lean | 2 +- Mathlib/Probability/Moments/SubGaussian.lean | 4 +- .../Topology/Algebra/ProperAction/Basic.lean | 2 +- Mathlib/Topology/Compactness/Compact.lean | 2 +- Mathlib/Topology/Constructions/SumProd.lean | 4 ++ .../UniformSpace/UniformConvergence.lean | 6 +-- 17 files changed, 95 insertions(+), 48 deletions(-) diff --git a/Mathlib/Data/Finset/Prod.lean b/Mathlib/Data/Finset/Prod.lean index d74db48d69e592..097e44badb751d 100644 --- a/Mathlib/Data/Finset/Prod.lean +++ b/Mathlib/Data/Finset/Prod.lean @@ -249,8 +249,7 @@ variable (s t : Finset α) /-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for `a ∈ s`. -/ -def diag : Finset (α × α) := - s.map ⟨fun a ↦ (a, a), by simp [Function.Injective]⟩ +def diag : Finset (α × α) := s.map ⟨Function.diag, Function.diag_injective⟩ -- TODO: define `Multiset.offDiag`, provide basic API, use it here /-- Given a finite set `s`, the off-diagonal, `s.offDiag` is the set of pairs `(a, b)` with `a ≠ b` diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 468ac76a1c6526..84643529d5f2e0 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -430,25 +430,24 @@ theorem preimage_coe_coe_diagonal (s : Set α) : simp [Set.diagonal] @[simp] -theorem range_diag : (range fun x => (x, x)) = diagonal α := by +theorem range_diag : range Function.diag = diagonal α := by ext ⟨x, y⟩ simp [diagonal, eq_comm] -theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, (x, x) ∈ s := by - rw [← range_diag, range_subset_iff] +theorem diagonal_subset_iff {s} : diagonal α ⊆ s ↔ ∀ x, (x, x) ∈ s := by grind @[simp] theorem prod_subset_compl_diagonal_iff_disjoint : s ×ˢ t ⊆ (diagonal α)ᶜ ↔ Disjoint s t := prod_subset_iff.trans disjoint_iff_forall_ne.symm @[simp] -theorem diag_preimage_prod (s t : Set α) : (fun x => (x, x)) ⁻¹' s ×ˢ t = s ∩ t := +theorem diag_preimage_prod (s t : Set α) : Function.diag ⁻¹' s ×ˢ t = s ∩ t := rfl -theorem diag_preimage_prod_self (s : Set α) : (fun x => (x, x)) ⁻¹' s ×ˢ s = s := +theorem diag_preimage_prod_self (s : Set α) : Function.diag ⁻¹' s ×ˢ s = s := inter_self s -theorem diag_image (s : Set α) : (fun x => (x, x)) '' s = diagonal α ∩ s ×ˢ s := by +theorem diag_image (s : Set α) : Function.diag '' s = diagonal α ∩ s ×ˢ s := by rw [← range_diag, ← image_preimage_eq_range_inter, diag_preimage_prod_self] theorem diagonal_eq_univ_iff : diagonal α = univ ↔ Subsingleton α := by diff --git a/Mathlib/Logic/Function/Defs.lean b/Mathlib/Logic/Function/Defs.lean index 0c3098fed6abe8..4d7d04b3821653 100644 --- a/Mathlib/Logic/Function/Defs.lean +++ b/Mathlib/Logic/Function/Defs.lean @@ -23,6 +23,13 @@ variable {α : Sort u₁} {β : Sort u₂} {φ : Sort u₃} {δ : Sort u₄} {ζ lemma flip_def {f : α → β → φ} : flip f = fun b a => f a b := rfl +attribute [mfld_simps] id_comp comp_id + +theorem comp_assoc (f : φ → δ) (g : β → φ) (h : α → β) : (f ∘ g) ∘ h = f ∘ g ∘ h := + rfl + +/- ### Dependent composition -/ + /-- Composition of dependent functions: `(f ∘' g) x = f (g x)`, where type of `g x` depends on `x` and type of `f (g x)` depends on `x` and `g x`. -/ @[inline, reducible] @@ -44,6 +51,8 @@ theorem dcomp_apply : dcomp @f g i = f (g i) := rfl end DComp +/- ### The product of functions -/ + /-- Product of functions: `Function.prod f g i = (f i, g i)`, where the types of `f i` and `g i` may depend on `i`. -/ protected def prod {ι} {α β : ι → Type*} (f : ∀ i, α i) (g : ∀ i, β i) (i : ι) : @@ -101,6 +110,35 @@ theorem prod_comp_prod {γ δ} (h : α × β → γ) (k : α × β → δ) : end Prod +/- ### The diagonal map -/ + +/-- The diagonal map into `Prod`. -/ +@[inline] protected def diag {α} : α → α × α := fun a : α ↦ (a, a) + +section Diag + +variable {α β γ : Type*} (f : α → β) (g : α → γ) (a b : α) + +theorem diag_def : Function.diag = fun a : α ↦ (a, a) := rfl + +@[simp, grind =] theorem diag_apply : Function.diag a = (a, a) := rfl + +theorem diag_injective : Injective (α := α) Function.diag := fun _ _ ↦ congrArg Prod.fst + +@[simp] theorem prod_id_id : Function.prod (@id α) id = Function.diag := rfl +@[simp] theorem fst_comp_diag : Prod.fst ∘ Function.diag = @id α := rfl +@[simp] theorem snd_comp_diag : Prod.snd ∘ Function.diag = @id α := rfl + +@[simp] theorem diag_comp : Function.diag ∘ f = Function.prod f f := rfl + +@[simp] theorem map_comp_diag : Prod.map f g ∘ Function.diag = Function.prod f g := rfl + +@[simp] theorem swap_comp_diag : Prod.swap ∘ Function.diag = Function.diag (α := α) := rfl + +end Diag + +/- ### `onFun` function -/ + /-- Given functions `f : β → β → φ` and `g : α → β`, produce a function `α → α → φ` that evaluates `g` on each argument, then applies `f` to the results. Can be used, e.g., to transfer a relation from `β` to `α`. -/ @@ -109,6 +147,8 @@ abbrev onFun (f : β → β → φ) (g : α → β) : α → α → φ := fun x @[inherit_doc onFun] scoped infixl:2 " on " => onFun +/- ### The argument-reversing map -/ + /-- For a two-argument function `f`, `swap f` is the same function but taking the arguments in the reverse order. `swap f y x = f x y`. -/ abbrev swap {φ : α → β → Sort u₃} (f : ∀ x y, φ x y) : ∀ y x, φ x y := fun y x => f x y @@ -117,10 +157,7 @@ theorem swap_def {φ : α → β → Sort u₃} (f : ∀ x y, φ x y) : swap f = theorem onFun_swap_comm (f : β → β → φ) (g : α → β) : (swap f on g) = swap (f on g) := rfl -attribute [mfld_simps] id_comp comp_id - -theorem comp_assoc (f : φ → δ) (g : β → φ) (h : α → β) : (f ∘ g) ∘ h = f ∘ g ∘ h := - rfl +/- ### Bijective functions -/ /-- A function is called bijective if it is both injective and surjective. -/ def Bijective (f : α → β) := @@ -138,6 +175,8 @@ theorem Injective.beq_eq {α β : Type*} [BEq α] [LawfulBEq α] [BEq β] [Lawfu (I : Injective f) {a b : α} : (f a == f b) = (a == b) := by by_cases h : a == b <;> simp [h] <;> simpa [I.eq_iff] using h +/- ### Bicomposition -/ + section Bicomp variable {α β γ δ ε : Sort*} @@ -169,6 +208,8 @@ namespace Function variable {α : Type u₁} {β : Type u₂} +/- ### Fixed points of functions -/ + /-- A point `x` is a fixed point of `f : α → α` if `f x = x`. -/ def IsFixedPt (f : α → α) (x : α) := f x = x @@ -197,6 +238,8 @@ namespace Pi variable {ι : Sort*} {α β : ι → Sort*} +/- ### `Pi.map` function -/ + /-- Sends a dependent function `a : ∀ i, α i` to a dependent function `Pi.map f a : ∀ i, β i` by applying `f i` to `i`-th component. -/ protected def map (f : ∀ i, α i → β i) : (∀ i, α i) → (∀ i, β i) := fun a i ↦ f i (a i) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index 858930635eb2b2..6e3db0bada0198 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -422,6 +422,13 @@ theorem measurable_prodMk_left {x : α} : Measurable (@Prod.mk _ β x) := theorem measurable_prodMk_right {y : β} : Measurable fun x : α => (x, y) := measurable_id.prodMk measurable_const +@[fun_prop] +theorem measurable_diag : @Measurable α (α × α) m (m.prod m) Function.diag := + measurable_id.prodMk measurable_id + +theorem measurable_diag' {m'} (h : m' ≤ m) : @Measurable α (α × α) m (m.prod m') Function.diag := + measurable_id.prodMk (measurable_id'' h) + theorem Measurable.of_uncurry_left {f : α → β → γ} (hf : Measurable (uncurry f)) {x : α} : Measurable (f x) := hf.comp measurable_prodMk_left diff --git a/Mathlib/NumberTheory/Height/Basic.lean b/Mathlib/NumberTheory/Height/Basic.lean index e5bdeb555ef6a8..006f6c2cfae7ee 100644 --- a/Mathlib/NumberTheory/Height/Basic.lean +++ b/Mathlib/NumberTheory/Height/Basic.lean @@ -759,7 +759,7 @@ lemma mulHeight_mul_le (x y : ι → K) : mulHeight (x * y) ≤ mulHeight x * mu rcases eq_or_ne y 0 with rfl | hy · simpa using one_le_mulHeight x rw [← mulHeight_fun_mul_eq hx hy, - show x * y = (fun a ↦ x a.1 * y a.2) ∘ fun i ↦ (i, i) by ext1; simp] + show x * y = (fun a ↦ x a.1 * y a.2) ∘ Function.diag by ext1; simp] exact mulHeight_comp_le .. open Real in diff --git a/Mathlib/Order/Filter/Prod.lean b/Mathlib/Order/Filter/Prod.lean index 077557f410efef..9ba0b26e290fe8 100644 --- a/Mathlib/Order/Filter/Prod.lean +++ b/Mathlib/Order/Filter/Prod.lean @@ -203,7 +203,7 @@ theorem Eventually.diag_of_prod_right {f : Filter α} {g : Filter γ} {p : α × obtain ⟨t, ht, s, hs, hst⟩ := eventually_prod_iff.1 h exact (ht.prod_mk hs.diag_of_prod).mono fun x hx => by simp only [hst hx.1 hx.2] -theorem tendsto_diag : Tendsto (fun i => (i, i)) f (f ×ˢ f) := +theorem tendsto_diag : Tendsto Function.diag f (f ×ˢ f) := tendsto_iff_eventually.mpr fun _ hpr => hpr.diag_of_prod theorem prod_iInf_left [Nonempty ι] {f : ι → Filter α} {g : Filter β} : diff --git a/Mathlib/Probability/Independence/Conditional.lean b/Mathlib/Probability/Independence/Conditional.lean index 6d834c8d87db06..7f28cf57c2fdd8 100644 --- a/Mathlib/Probability/Independence/Conditional.lean +++ b/Mathlib/Probability/Independence/Conditional.lean @@ -804,9 +804,8 @@ lemma condIndepFun_iff_map_prod_eq_prod_comp_trim ∘ₘ μ.trim hm' := by rw [condIndepFun_iff_compProd_map_prod_eq_compProd_prod_map_map hf hg] congr! - · rw [Measure.compProd_map (by fun_prop), compProd_trim_condExpKernel, - Measure.map_map (by fun_prop) ((measurable_id.mono le_rfl hm').prodMk measurable_id)] - rfl + · rw [Measure.compProd_map (by fun_prop), compProd_trim_condExpKernel] + exact Measure.map_map (by fun_prop) ((measurable_id.mono le_rfl hm').prodMk measurable_id) · rw [Measure.compProd_eq_comp_prod] /-- Two random variables `f, g` are conditionally independent given a third `k` iff the diff --git a/Mathlib/Probability/Kernel/Basic.lean b/Mathlib/Probability/Kernel/Basic.lean index 7fd840d064c9c2..3ce4b6dc6ffad7 100644 --- a/Mathlib/Probability/Kernel/Basic.lean +++ b/Mathlib/Probability/Kernel/Basic.lean @@ -130,7 +130,7 @@ section Copy /-- The deterministic kernel that maps `x : α` to the Dirac measure at `(x, x) : α × α`. -/ noncomputable def copy (α : Type*) [MeasurableSpace α] : Kernel α (α × α) := - Kernel.deterministic (fun x ↦ (x, x)) (measurable_id.prod measurable_id) + Kernel.deterministic Function.diag (measurable_id.prod measurable_id) instance : IsMarkovKernel (copy α) := by rw [copy]; infer_instance diff --git a/Mathlib/Probability/Kernel/Composition/MeasureComp.lean b/Mathlib/Probability/Kernel/Composition/MeasureComp.lean index 6f705017349bd3..aee8a1147edd5c 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureComp.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureComp.lean @@ -94,9 +94,9 @@ lemma discard_comp (μ : Measure α) : Kernel.discard α ∘ₘ μ = μ .univ ext s hs; simp [Measure.bind_apply hs (Kernel.aemeasurable _), mul_comm] lemma copy_comp_map {f : α → β} (hf : AEMeasurable f μ) : - Kernel.copy β ∘ₘ (μ.map f) = μ.map (fun a ↦ (f a, f a)) := by - rw [Kernel.copy, deterministic_comp_eq_map, AEMeasurable.map_map_of_aemeasurable (by fun_prop) hf] - rfl + Kernel.copy β ∘ₘ (μ.map f) = μ.map (Function.prod f f) := by + rw [Kernel.copy, deterministic_comp_eq_map] + exact (aemeasurable_id.prodMk aemeasurable_id).map_map_of_aemeasurable hf section CompProd diff --git a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean index 4bb790b943df9e..7850baf70980da 100644 --- a/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean +++ b/Mathlib/Probability/Kernel/Composition/MeasureCompProd.lean @@ -99,14 +99,14 @@ lemma _root_.ProbabilityTheory.Kernel.compProd_apply_eq_compProd_sectR {γ : Typ ext s hs simp_rw [Kernel.compProd_apply hs, compProd_apply hs, Kernel.sectR_apply] -lemma compProd_id [SFinite μ] : μ ⊗ₘ Kernel.id = μ.map (fun x ↦ (x, x)) := by +lemma compProd_id [SFinite μ] : μ ⊗ₘ Kernel.id = μ.map Function.diag := by ext s hs rw [compProd_apply hs, map_apply (measurable_id.prod measurable_id) hs] have h_meas a : MeasurableSet (Prod.mk a ⁻¹' s) := measurable_prodMk_left hs simp_rw [Kernel.id_apply, dirac_apply' _ (h_meas _)] calc ∫⁻ a, (Prod.mk a ⁻¹' s).indicator 1 a ∂μ - _ = ∫⁻ a, ((fun x ↦ (x, x)) ⁻¹' s).indicator 1 a ∂μ := rfl - _ = μ ((fun x ↦ (x, x)) ⁻¹' s) := by + _ = ∫⁻ a, (Function.diag ⁻¹' s).indicator 1 a ∂μ := rfl + _ = μ (Function.diag ⁻¹' s) := by rw [lintegral_indicator_one] exact (measurable_id.prod measurable_id) hs diff --git a/Mathlib/Probability/Kernel/Condexp.lean b/Mathlib/Probability/Kernel/Condexp.lean index 264ccaece12745..462b291681886f 100644 --- a/Mathlib/Probability/Kernel/Condexp.lean +++ b/Mathlib/Probability/Kernel/Condexp.lean @@ -46,15 +46,14 @@ section AuxLemmas variable {Ω F : Type*} {m mΩ : MeasurableSpace Ω} {μ : Measure Ω} {f : Ω → F} theorem _root_.MeasureTheory.AEStronglyMeasurable.comp_snd_map_prod_id [TopologicalSpace F] - (hm : m ≤ mΩ) (hf : AEStronglyMeasurable f μ) : + (hf : AEStronglyMeasurable f μ) : AEStronglyMeasurable[m.prod mΩ] (fun x : Ω × Ω => f x.2) - (@Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) (fun ω => (id ω, id ω)) μ) := by - simpa using (aestronglyMeasurable_comp_snd_map_prodMk_iff hm).mpr hf + (@Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) Function.diag μ) := hf.comp_snd_map_prodMk id theorem _root_.MeasureTheory.Integrable.comp_snd_map_prod_id [NormedAddCommGroup F] (hf : Integrable f μ) : Integrable (fun x : Ω × Ω => f x.2) - (@Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) (fun ω => (id ω, id ω)) μ) := by - simpa using Integrable.comp_snd_map_prodMk id hf + (@Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) Function.diag μ) := + hf.comp_snd_map_prodMk id end AuxLemmas @@ -92,21 +91,19 @@ instance : IsMarkovKernel (condExpKernel μ m) := by lemma compProd_trim_condExpKernel (hm : m ≤ mΩ) : (μ.trim hm) ⊗ₘ condExpKernel μ m - = @Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) (fun ω ↦ (id ω, id ω)) μ := by + = @Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) Function.diag μ := by rcases isEmpty_or_nonempty Ω with h | h · simp [Measure.eq_zero_of_isEmpty μ] - rw [condExpKernel_eq] + rw [condExpKernel_eq, trim_eq_map hm] have : m ⊓ mΩ = m := inf_of_le_left hm - have h := compProd_map_condDistrib (mβ := m) (μ := μ) (X := id) measurable_id.aemeasurable - rw [← h, trim_eq_map hm] - congr 1 - ext a s hs + refine (congrArg _ (Kernel.ext fun a => Measure.ext fun s hs => ?_)).trans + (compProd_map_condDistrib measurable_id.aemeasurable) simp only [Kernel.coe_comap, Function.comp_apply, id_eq] congr lemma condExpKernel_comp_trim (hm : m ≤ mΩ) : condExpKernel μ m ∘ₘ μ.trim hm = μ := by - rw [← Measure.snd_compProd, compProd_trim_condExpKernel, @Measure.snd_map_prodMk, Measure.map_id] - exact measurable_id'' hm + rw [← Measure.snd_compProd, compProd_trim_condExpKernel] + exact (@Measure.snd_map_prodMk Ω Ω Ω mΩ m mΩ id id μ (measurable_id'' hm)).trans Measure.map_id section Measurability @@ -139,7 +136,7 @@ theorem _root_.MeasureTheory.AEStronglyMeasurable.integral_condExpKernel [Normed simp_rw [condExpKernel_apply_eq_condDistrib] exact AEStronglyMeasurable.integral_condDistrib (aemeasurable_id'' μ (inf_le_right : m ⊓ mΩ ≤ mΩ)) aemeasurable_id - (hf.comp_snd_map_prod_id inf_le_right) + hf.comp_snd_map_prod_id theorem aestronglyMeasurable_integral_condExpKernel [NormedSpace ℝ F] (hf : AEStronglyMeasurable f μ) : @@ -147,8 +144,7 @@ theorem aestronglyMeasurable_integral_condExpKernel [NormedSpace ℝ F] nontriviality Ω rw [condExpKernel_eq] have h := aestronglyMeasurable_integral_condDistrib - (aemeasurable_id'' μ (inf_le_right : m ⊓ mΩ ≤ mΩ)) aemeasurable_id - (hf.comp_snd_map_prod_id (inf_le_right : m ⊓ mΩ ≤ mΩ)) + (aemeasurable_id'' μ (inf_le_right : m ⊓ mΩ ≤ mΩ)) aemeasurable_id hf.comp_snd_map_prod_id rw [MeasurableSpace.comap_id] at h exact h.mono inf_le_left diff --git a/Mathlib/Probability/Kernel/Deterministic.lean b/Mathlib/Probability/Kernel/Deterministic.lean index 5515b6afd758ad..3d12c909087b15 100644 --- a/Mathlib/Probability/Kernel/Deterministic.lean +++ b/Mathlib/Probability/Kernel/Deterministic.lean @@ -68,7 +68,7 @@ lemma parallelComp_self_comp_copy {κ : Kernel α β} [IsDeterministic κ] : instance {f : α → β} (hf : Measurable f) : IsDeterministic (deterministic f hf) where parallelComp_self_comp_copy' := by simp_rw [parallelComp_comp_copy, deterministic_prod_deterministic, copy, - deterministic_comp_deterministic, Function.comp_def] + deterministic_comp_deterministic, Function.comp_def, Function.diag_def] instance : IsDeterministic (mβ := mα) (Kernel.id (α := α)) := by unfold Kernel.id; infer_instance diff --git a/Mathlib/Probability/Moments/SubGaussian.lean b/Mathlib/Probability/Moments/SubGaussian.lean index 18a8eb31d4b636..040fc9790b7c21 100644 --- a/Mathlib/Probability/Moments/SubGaussian.lean +++ b/Mathlib/Probability/Moments/SubGaussian.lean @@ -882,8 +882,8 @@ lemma HasSubgaussianMGF.add_of_hasCondSubgaussianMGF [IsFiniteMeasure μ] (hX : HasSubgaussianMGF X cX (μ.trim hm)) (hY : HasCondSubgaussianMGF m hm Y cY μ) : HasSubgaussianMGF (X + Y) (cX + cY) μ := by suffices HasSubgaussianMGF (fun p ↦ X p.1 + Y p.2) (cX + cY) - (@Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) (fun ω ↦ (id ω, id ω)) μ) by - have h_eq : X + Y = (fun p ↦ X p.1 + Y p.2) ∘ (fun ω ↦ (id ω, id ω)) := rfl + (@Measure.map Ω (Ω × Ω) mΩ (m.prod mΩ) Function.diag μ) by + have h_eq : X + Y = (fun p ↦ X p.1 + Y p.2) ∘ Function.diag := rfl rw [h_eq] refine HasSubgaussianMGF.of_map ?_ this exact @Measurable.aemeasurable _ _ _ (m.prod mΩ) _ _ diff --git a/Mathlib/Topology/Algebra/ProperAction/Basic.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean index 175b8c6a90b523..5d1bb022a33002 100644 --- a/Mathlib/Topology/Algebra/ProperAction/Basic.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -139,7 +139,7 @@ theorem t2Space_of_properSMul_of_t1Group [h_proper : ProperSMul G X] [T1Space G] rw [t2_iff_isClosed_diagonal] let g := fun gx : G × X ↦ (gx.1 • gx.2, gx.2) have proper_g : IsProperMap g := (properSMul_iff G X).1 h_proper - have : g ∘ f = fun x ↦ (x, x) := by ext x <;> simp [f, g] + have : g ∘ f = Function.diag := by ext x <;> simp [f, g] have range_gf : range (g ∘ f) = diagonal X := by simp [this] rw [← range_gf] exact (proper_g.comp proper_f).isClosed_range diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index fa86ecf5d550b9..aa698bfb12cd1f 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -432,7 +432,7 @@ theorem IsCompact.mem_prod_nhdsSet_of_forall {K : Set Y} {X} {l : Filter X} {s : -- That would seem a bit more natural. theorem IsCompact.nhdsSet_inf_eq_biSup {K : Set X} (hK : IsCompact K) (l : Filter X) : (𝓝ˢ K) ⊓ l = ⨆ x ∈ K, 𝓝 x ⊓ l := by - have : ∀ f : Filter X, f ⊓ l = comap (fun x ↦ (x, x)) (f ×ˢ l) := fun f ↦ by + have : ∀ f : Filter X, f ⊓ l = comap Function.diag (f ×ˢ l) := fun f ↦ by simpa only [comap_prod] using! congrArg₂ (· ⊓ ·) comap_id.symm comap_id.symm simp_rw [this, ← comap_iSup, hK.nhdsSet_prod_eq_biSup] diff --git a/Mathlib/Topology/Constructions/SumProd.lean b/Mathlib/Topology/Constructions/SumProd.lean index 80c90689295441..ff2a20dc397df5 100644 --- a/Mathlib/Topology/Constructions/SumProd.lean +++ b/Mathlib/Topology/Constructions/SumProd.lean @@ -147,6 +147,10 @@ theorem Continuous.prodMk_right (x : X) : Continuous fun y : Y => (x, y) := by f @[continuity] theorem Continuous.prodMk_left (y : Y) : Continuous fun x : X => (x, y) := by fun_prop +@[continuity, fun_prop] +theorem continuous_diag : Continuous (Function.diag : X → X × X) := + continuous_id.prodMk continuous_id + /-- If `f x y` is continuous in `x` for all `y ∈ s`, then the set of `x` such that `f x` maps `s` to `t` is closed. -/ lemma IsClosed.setOfPred_mapsTo {α : Type*} {f : X → α → Z} {s : Set α} {t : Set Z} diff --git a/Mathlib/Topology/UniformSpace/UniformConvergence.lean b/Mathlib/Topology/UniformSpace/UniformConvergence.lean index 62a4ecaeba2d06..0919a9842bfd93 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergence.lean @@ -292,12 +292,12 @@ protected theorem TendstoUniformlyOn.prodMk {ι' β' : Type*} [UniformSpace β'] (h' : TendstoUniformlyOn F' f' p' s) : TendstoUniformlyOn (fun (i : ι × ι') a => (F i.1 a, F' i.2 a)) (fun a => (f a, f' a)) (p ×ˢ p') s := - (congr_arg _ s.inter_self).mp ((h.prodMap h').comp fun a => (a, a)) + (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Function.diag) theorem TendstoUniformly.prodMk {ι' β' : Type*} [UniformSpace β'] {F' : ι' → α → β'} {f' : α → β'} {p' : Filter ι'} (h : TendstoUniformly F f p) (h' : TendstoUniformly F' f' p') : TendstoUniformly (fun (i : ι × ι') a => (F i.1 a, F' i.2 a)) (fun a => (f a, f' a)) (p ×ˢ p') := - (h.prodMap h').comp fun a => (a, a) + (h.prodMap h').comp Function.diag /-- Uniform convergence on a filter `p'` to a constant function is equivalent to convergence in `p ×ˢ p'`. -/ @@ -550,7 +550,7 @@ theorem UniformCauchySeqOn.prodMap {ι' α' β' : Type*} [UniformSpace β'] {F' theorem UniformCauchySeqOn.prod {ι' β' : Type*} [UniformSpace β'] {F' : ι' → α → β'} {p' : Filter ι'} (h : UniformCauchySeqOn F p s) (h' : UniformCauchySeqOn F' p' s) : UniformCauchySeqOn (fun (i : ι × ι') a => (F i.fst a, F' i.snd a)) (p ×ˢ p') s := - (congr_arg _ s.inter_self).mp ((h.prodMap h').comp fun a => (a, a)) + (congr_arg _ s.inter_self).mp ((h.prodMap h').comp Function.diag) theorem UniformCauchySeqOn.prod' {β' : Type*} [UniformSpace β'] {F' : ι → α → β'} (h : UniformCauchySeqOn F p s) (h' : UniformCauchySeqOn F' p s) : From e13dd6052c9cd13288ffa9e5ccc13381b812b42f Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Sat, 8 Aug 2026 16:47:48 +0000 Subject: [PATCH 1214/1300] chore: reduce `import all` (#41389) Removes `import all` whenever possible. I also tried to "downgrade" by changing to `import` from `import all`, but that never made a difference. Excludes MathlibTest. For a related PR, see #41222. Co-authored-by: Batixx --- Mathlib/Control/Monad/Cont.lean | 1 - Mathlib/Data/Fintype/Parity.lean | 1 - Mathlib/Data/Int/Bitwise.lean | 1 - Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean | 1 - Mathlib/Tactic/Cases.lean | 2 +- Mathlib/Tactic/FieldSimp/Discharger.lean | 2 +- Mathlib/Tactic/GCongr/Core.lean | 2 -- Mathlib/Tactic/PNatToNat.lean | 1 - Mathlib/Tactic/WLOG.lean | 2 +- 9 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Mathlib/Control/Monad/Cont.lean b/Mathlib/Control/Monad/Cont.lean index 906e9ddf4c1911..e5aabdb181c9d0 100644 --- a/Mathlib/Control/Monad/Cont.lean +++ b/Mathlib/Control/Monad/Cont.lean @@ -10,7 +10,6 @@ public import Mathlib.Control.Monad.Writer public import Mathlib.Control.Lawful public import Batteries.Tactic.Congr public import Batteries.Lean.Except -import all Init.Control.Option -- for unfolding `Option.lift` /-! # Continuation Monad diff --git a/Mathlib/Data/Fintype/Parity.lean b/Mathlib/Data/Fintype/Parity.lean index 0a07ce544820e3..975e1df7f3d097 100644 --- a/Mathlib/Data/Fintype/Parity.lean +++ b/Mathlib/Data/Fintype/Parity.lean @@ -7,7 +7,6 @@ module public import Mathlib.Data.Fintype.Card public import Mathlib.Algebra.Group.Even -import all Init.Data.Fin.Fold -- for exposing `Fin.foldr` /-! # The cardinality of `Fin 2` is even. diff --git a/Mathlib/Data/Int/Bitwise.lean b/Mathlib/Data/Int/Bitwise.lean index b73a414e798de8..5b65326ece0b7b 100644 --- a/Mathlib/Data/Int/Bitwise.lean +++ b/Mathlib/Data/Int/Bitwise.lean @@ -10,7 +10,6 @@ public import Mathlib.Data.Nat.Bitwise public import Mathlib.Data.Nat.Size public import Batteries.Data.Int import all Init.Data.Nat.Bitwise.Basic -- for unfolding `Nat.bitwise` -import all Init.Data.Int.Bitwise.Basic -- for unfolding `Int.bitwise` /-! # Bitwise operations on integers diff --git a/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean b/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean index 4650ebd053cd21..eaedd01ff9c5b7 100644 --- a/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean +++ b/Mathlib/Lean/Meta/RefinedDiscrTree/Encode.lean @@ -8,7 +8,6 @@ module public import Mathlib.Lean.Meta.RefinedDiscrTree.Basic public import Lean.Meta.DiscrTree public import Lean.Meta.LazyDiscrTree -import all Lean.Meta.DiscrTree /-! # Encoding an `Expr` as a sequence of `Key`s diff --git a/Mathlib/Tactic/Cases.lean b/Mathlib/Tactic/Cases.lean index 73e72b74a5388a..d55b876b043776 100644 --- a/Mathlib/Tactic/Cases.lean +++ b/Mathlib/Tactic/Cases.lean @@ -8,7 +8,7 @@ module public meta import Lean.Elab.Tactic.Induction public meta import Batteries.Data.List.Basic public meta import Batteries.Lean.Expr -import all Lean.Elab.Tactic.Induction +import all Lean.Elab.Tactic.Induction -- for `getElimNameInfo` public import Mathlib.Init /-! diff --git a/Mathlib/Tactic/FieldSimp/Discharger.lean b/Mathlib/Tactic/FieldSimp/Discharger.lean index 097f9a35d5087f..dbba1bc25883e4 100644 --- a/Mathlib/Tactic/FieldSimp/Discharger.lean +++ b/Mathlib/Tactic/FieldSimp/Discharger.lean @@ -5,7 +5,7 @@ Authors: Sébastien Gouëzel, David Renshaw -/ module -import all Lean.Meta.Tactic.Simp.Rewrite +import all Lean.Meta.Tactic.Simp.Rewrite -- for `Simp.dischargeUsingAssumption?` public import Mathlib.Tactic.Positivity.Core public import Mathlib.Util.DischargerAsTactic diff --git a/Mathlib/Tactic/GCongr/Core.lean b/Mathlib/Tactic/GCongr/Core.lean index d3cea22abb7fe8..55c704e050626e 100644 --- a/Mathlib/Tactic/GCongr/Core.lean +++ b/Mathlib/Tactic/GCongr/Core.lean @@ -13,8 +13,6 @@ public import Mathlib.Order.Defs.Unbundled public import Mathlib.Tactic.Core public import Mathlib.Tactic.GCongr.ForwardAttr -import all Lean.Meta.Tactic.Apply - /-! # The `gcongr` ("generalized congruence") tactic diff --git a/Mathlib/Tactic/PNatToNat.lean b/Mathlib/Tactic/PNatToNat.lean index c4576d1f2c99b4..53722f7f20fd50 100644 --- a/Mathlib/Tactic/PNatToNat.lean +++ b/Mathlib/Tactic/PNatToNat.lean @@ -5,7 +5,6 @@ Authors: Vasilii Nesterov -/ module -import all Lean.Elab.Tactic.Induction public import Mathlib.Data.PNat.Basic public meta import Mathlib.Tactic.ToAdditive diff --git a/Mathlib/Tactic/WLOG.lean b/Mathlib/Tactic/WLOG.lean index f689340b80ff2b..67b8d195d363a7 100644 --- a/Mathlib/Tactic/WLOG.lean +++ b/Mathlib/Tactic/WLOG.lean @@ -6,7 +6,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Johan Commelin, Reid Barton, Thomas Mu module public meta import Lean.Meta.Tactic.Cases -import all Lean.MetavarContext +import all Lean.MetavarContext -- for `mkAuxMVarType` public import Mathlib.Tactic.Core public import Mathlib.Tactic.Push From 639923353ff2a58e9976a254e0d40f4bebae36bc Mon Sep 17 00:00:00 2001 From: Xingyu Zhong Date: Sun, 9 Aug 2026 06:08:39 +0000 Subject: [PATCH 1215/1300] feat(Mathlib/RingTheory/Ideal/Cotangent): dimension of cotangent spaces (#33247) It is shown that the span rank of the maximal ideal of a local ring equals the dimension of the cotangent space if the maximal ideal is finitely generated. Co-authored-by: sun123zxy <44888975+sun123zxy@users.noreply.github.com> --- Mathlib/RingTheory/Ideal/Cotangent.lean | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Mathlib/RingTheory/Ideal/Cotangent.lean b/Mathlib/RingTheory/Ideal/Cotangent.lean index 1a2e1331fd47d6..ddfebb5eaabca9 100644 --- a/Mathlib/RingTheory/Ideal/Cotangent.lean +++ b/Mathlib/RingTheory/Ideal/Cotangent.lean @@ -6,6 +6,7 @@ Authors: Andrew Yang module public import Mathlib.Algebra.Module.Torsion.Basic +public import Mathlib.Algebra.Module.SpanRank public import Mathlib.Algebra.Ring.Idempotent public import Mathlib.LinearAlgebra.Dimension.Finite public import Mathlib.LinearAlgebra.Dimension.FreeAndStrongRankCondition @@ -340,6 +341,47 @@ lemma CotangentSpace.span_image_eq_top_iff [IsNoetherianRing R] {s : Set (maxima · simp · exact Ideal.Quotient.mk_surjective +/-- +In a local ring with its maximal ideal finitely generated, +the dimension of the cotangent space is equal to the span rank of the maximal ideal. +-/ +theorem rank_cotangentSpace_eq_spanrank_maximalIdeal_of_fg (fg : (maximalIdeal R).FG) : + Module.rank (ResidueField R) (CotangentSpace R) = (maximalIdeal R).spanRank := by + rw [Submodule.rank_eq_spanRank_of_free, ← Submodule.spanRank_top (maximalIdeal R)] + apply le_antisymm + · obtain ⟨s, hs_card, hs_span⟩ := + (⊤ : Submodule R (maximalIdeal R)).exists_span_set_card_eq_spanRank + have hs_span' : Submodule.span (ResidueField R) ((maximalIdeal R).toCotangent '' s) = ⊤ := by + rw [← Submodule.restrictScalars_eq_top_iff R, + Submodule.restrictScalars_span R (ResidueField R) Ideal.Quotient.mk_surjective, + ← Submodule.map_span, hs_span, Submodule.map_top, Ideal.toCotangent_range] + rw [← hs_card, ← hs_span'] + grw [Submodule.spanRank_span_le_card, Cardinal.mk_image_le] + · obtain ⟨s, hs_card, hs_span⟩ := + (⊤ : Submodule (ResidueField R) (CotangentSpace R)).exists_span_set_card_eq_spanRank + have hs_span' : Submodule.span R s = + Submodule.map (Submodule.mkQ (maximalIdeal R • (⊤ : Submodule R (maximalIdeal R)))) ⊤ := by + rw [Submodule.map_top, Submodule.range_mkQ] + change Submodule.span R s = ⊤ + rw [← Submodule.restrictScalars_span R (ResidueField R) + Ideal.Quotient.mk_surjective, hs_span, Submodule.restrictScalars_top] + obtain ⟨t, ht_inj, ht_image, ht_span⟩ := + Submodule.exists_injOn_mkQ_image_span_eq_of_span_eq_map_mkQ_of_le_jacobson_bot s + ((Submodule.fg_top (maximalIdeal R)).mpr fg) + (IsLocalRing.jacobson_eq_maximalIdeal _ bot_ne_top).ge + hs_span' + rw [← hs_card, ← ht_span, ← ht_image] + exact le_of_le_of_eq (Submodule.spanRank_span_le_card t) + (Cardinal.mk_image_eq_of_injOn _ _ ht_inj).symm + +/-- +In a Noetherian local ring, +the dimension of the cotangent space is equal to the span rank of the maximal ideal. +-/ +theorem rank_cotangentSpace_eq_spanrank_maximalIdeal [IsNoetherianRing R] : + Module.rank (ResidueField R) (CotangentSpace R) = (maximalIdeal R).spanRank := + rank_cotangentSpace_eq_spanrank_maximalIdeal_of_fg (maximalIdeal R).fg_of_isNoetherianRing + open Module lemma finrank_cotangentSpace_eq_zero_iff [IsNoetherianRing R] : From 6d605ae1ac45de240cdb83ce104fe60b3c1d9237 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Sun, 9 Aug 2026 19:18:37 +0000 Subject: [PATCH 1216/1300] doc(CategoryTheory): fix three typos (#42409) --- Mathlib/CategoryTheory/Functor/Derived/LeftDerived.lean | 2 +- Mathlib/CategoryTheory/Functor/Derived/RightDerived.lean | 2 +- .../Limits/Shapes/Pullback/Categorical/Basic.lean | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Functor/Derived/LeftDerived.lean b/Mathlib/CategoryTheory/Functor/Derived/LeftDerived.lean index a4ddb232276509..33d8c906dc2e5d 100644 --- a/Mathlib/CategoryTheory/Functor/Derived/LeftDerived.lean +++ b/Mathlib/CategoryTheory/Functor/Derived/LeftDerived.lean @@ -187,7 +187,7 @@ section variable (F) [F.HasLeftDerivedFunctor W] (L W) -/-- Given a functor `F : C ⥤ H`, and a localization functor `L : D ⥤ H` for `W`, +/-- Given a functor `F : C ⥤ H`, and a localization functor `L : C ⥤ D` for `W`, this is the left derived functor `D ⥤ H` of `F`, i.e. the right Kan extension of `F` along `L`. -/ noncomputable def totalLeftDerived : D ⥤ H := diff --git a/Mathlib/CategoryTheory/Functor/Derived/RightDerived.lean b/Mathlib/CategoryTheory/Functor/Derived/RightDerived.lean index b678890ad7a4b3..48ff45bb8bd0b1 100644 --- a/Mathlib/CategoryTheory/Functor/Derived/RightDerived.lean +++ b/Mathlib/CategoryTheory/Functor/Derived/RightDerived.lean @@ -190,7 +190,7 @@ section variable (F) [F.HasRightDerivedFunctor W] (L W) -/-- Given a functor `F : C ⥤ H`, and a localization functor `L : D ⥤ H` for `W`, +/-- Given a functor `F : C ⥤ H`, and a localization functor `L : C ⥤ D` for `W`, this is the right derived functor `D ⥤ H` of `F`, i.e. the left Kan extension of `F` along `L`. -/ noncomputable def totalRightDerived : D ⥤ H := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean index f8beea8ae6d7ad..c222ca9effcfca 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Categorical/Basic.lean @@ -203,7 +203,7 @@ variable (X : Type u₄) [Category.{v₄} X] variable (F G) in /-- The data of a categorical commutative square over a cospan `F, G` with cone point `X` is -that of a functor `T : X ⥤ A`, a functor `L : X ⥤ C`, and a `CatCommSqOver T L F G`. +that of a functor `T : X ⥤ A`, a functor `L : X ⥤ C`, and a `CatCommSq T L F G`. Note that this is *exactly* what an object of `((whiskeringRight X A B).obj F) ⊡ ((whiskeringRight X C B).obj G)` is, so `CatCommSqOver F G X` is in equivalent to From 239cf0d8f369c5edcd85d2ad9c1bddbc2f3ea5fa Mon Sep 17 00:00:00 2001 From: Moritz Doll <21366319+mcdoll@users.noreply.github.com> Date: Mon, 10 Aug 2026 00:21:27 +0000 Subject: [PATCH 1217/1300] feat(Analysis): the generalized hypergeometric function (#41980) We define the (regularized) generalized hypergeometric function and prove convergence in the cases `p < q + 1` and `p = q + 1`. This includes the Gaussian hypergeometric function (`p = 2` and `q = 1`) and the Bessel functions (`p = 0` and `q = 1`). --- Mathlib.lean | 1 + .../Analysis/Analytic/ConvergenceRadius.lean | 16 +- .../SpecialFunctions/Gamma/Basic.lean | 1 + .../Analysis/SpecialFunctions/Gamma/Beta.lean | 13 + .../SpecialFunctions/Gamma/Deriv.lean | 2 +- .../RegularizedHypergeometric.lean | 357 ++++++++++++++++++ 6 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4d9172b86e4052..961a2e701bcac8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2408,6 +2408,7 @@ public import Mathlib.Analysis.SpecialFunctions.Pow.Integral public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal public import Mathlib.Analysis.SpecialFunctions.Pow.NthRootLemmas public import Mathlib.Analysis.SpecialFunctions.Pow.Real +public import Mathlib.Analysis.SpecialFunctions.RegularizedHypergeometric public import Mathlib.Analysis.SpecialFunctions.Sigmoid public import Mathlib.Analysis.SpecialFunctions.SmoothTransition public import Mathlib.Analysis.SpecialFunctions.Sqrt diff --git a/Mathlib/Analysis/Analytic/ConvergenceRadius.lean b/Mathlib/Analysis/Analytic/ConvergenceRadius.lean index 93d86c5059f1a5..d22a06958c3212 100644 --- a/Mathlib/Analysis/Analytic/ConvergenceRadius.lean +++ b/Mathlib/Analysis/Analytic/ConvergenceRadius.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.Calculus.FormalMultilinearSeries public import Mathlib.Analysis.SpecificLimits.Normed +public import Mathlib.Topology.Algebra.InfiniteSum.Module /-! # Radius of convergence of a power series @@ -42,7 +43,7 @@ build the general theory. We do not define it here. noncomputable section -variable {𝕜 E F G : Type*} +variable {𝕜 𝕜' E F G : Type*} open Topology NNReal Filter ENNReal Set Asymptotics open scoped Pointwise @@ -65,6 +66,19 @@ theorem sum_mem {S : Type*} {s : S} [SetLike S F] [AddSubmonoidClass S F] p.sum x ∈ s := tsum_mem h_closed h +variable {𝕜' : Type} [DivisionSemiring 𝕜'] [Module 𝕜' F] [ContinuousConstSMul 𝕜' F] + [SMulCommClass 𝕜 𝕜' F] + +theorem const_smul_sum_apply [T2Space F] (a : 𝕜') (f : FormalMultilinearSeries 𝕜 E F) (z : E) : + a • f.sum z = (a • f).sum z := by + unfold FormalMultilinearSeries.sum + simp [tsum_const_smul''] + +theorem const_smul_sum [T2Space F] (a : 𝕜') (f : FormalMultilinearSeries 𝕜 E F) : + a • f.sum = (a • f).sum := by + ext z + apply const_smul_sum_apply + /-- Given a formal multilinear series `p` and a vector `x`, then `p.partialSum n x` is the sum `Σ pₖ xᵏ` for `k ∈ {0,..., n-1}`. -/ def partialSum (p : FormalMultilinearSeries 𝕜 E F) (n : ℕ) (x : E) : F := diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index 84f88af50e4fc2..8aea69baf71696 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -308,6 +308,7 @@ private theorem Gamma_eq_GammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : Gamm · linarith /-- The recurrence relation for the `Γ` function. -/ +@[grind =] theorem Gamma_add_one (s : ℂ) (h2 : s ≠ 0) : Gamma (s + 1) = s * Gamma s := by let n := ⌊1 - s.re⌋₊ have t1 : -s.re < n := by simpa only [sub_sub_cancel_left] using Nat.sub_one_lt_floor (1 - s.re) diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean index 40edeb5bc6a42d..612bc27a5af0f7 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean @@ -444,6 +444,7 @@ theorem Gamma_ne_zero {s : ℂ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 := rw [← Complex.Gamma_mul_Gamma_one_sub s, mul_ne_zero_iff] at A exact A.1 +@[grind =] theorem Gamma_eq_zero_iff (s : ℂ) : Gamma s = 0 ↔ ∃ m : ℕ, s = -m := by constructor · contrapose!; exact Gamma_ne_zero @@ -455,6 +456,18 @@ theorem Gamma_ne_zero_of_re_pos {s : ℂ} (hs : 0 < re s) : Gamma s ≠ 0 := by contrapose! hs simpa only [hs, neg_re, ← ofReal_natCast, ofReal_re, neg_nonpos] using Nat.cast_nonneg _ +/-- The ascending Pochhammer symbol is given by the ratio of `Γ` functions. -/ +theorem Gamma_add_nat_div_Gamma_eq {n : ℕ} (z : ℂ) (hz : ∀ k : ℕ, z ≠ -k) : + Gamma (z + n) / Gamma z = (ascPochhammer ℂ n).eval z := by + induction n generalizing z with + | zero => + simp + grind + | succ n ih => + suffices h : Gamma (z + n + 1) = Gamma (z + n) * (z + n) by + simp [ascPochhammer_succ_right, ← ih z hz, div_mul_eq_mul_div, h, ← add_assoc] + grind + end Complex namespace Real diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean index c6aca65300a203..e188f3792f45ab 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean @@ -80,7 +80,7 @@ theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen specialize IH (s + 1) (by grind [add_re, one_re]) (fun m ↦ by grind [hs (m + 1)]) have := IH.comp s (show DifferentiableAt ℂ (fun s ↦ s + 1) s by fun_prop) apply (this.fun_div differentiableAt_id hsne).congr_of_eventuallyEq - filter_upwards [isOpen_ne.mem_nhds hsne] using by grind [Gamma_add_one] + filter_upwards [isOpen_ne.mem_nhds hsne] using by grind theorem differentiableAt_Gamma_one : DifferentiableAt ℂ Gamma 1 := differentiableAt_Gamma 1 (by norm_cast; simp) diff --git a/Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean b/Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean new file mode 100644 index 00000000000000..fda1858f6cd222 --- /dev/null +++ b/Mathlib/Analysis/SpecialFunctions/RegularizedHypergeometric.lean @@ -0,0 +1,357 @@ +/- +Copyright (c) 2026 Moritz Doll. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Moritz Doll +-/ +module + +public import Mathlib.Analysis.SpecialFunctions.Gamma.Digamma +public import Mathlib.Analysis.SpecialFunctions.OrdinaryHypergeometric + +/-! # Generalized hypergeometric function + +In this file we define the generalized hypergeometric function as well as the Gaussian +hypergeometric function. + +The hypergeometric function is a function with parameters `a : Fin p → ℂ` and `b : Fin q → ℂ`. + +Note that in this file, we use the *regularized* version of the hypergeometric function, that is +the coefficients are divides by `∏ i, Gamma (b i)`, giving in the case of the Gaussian +hypergeometric function the series representation +$$\sum_j \frac{(a)^n (b)^n}{\Gamma(c + n) n!} z^ n,$$ +where `(a)^n` denotes the rising Pochhammer symbol. + +This definition is valid for all values of `c`, whereas the usual hypergeometric function has a +pole for `c = -k` and `k : ℕ`. To our knowledge the regularized hypergeometric function only appears +in the literature only for the Gaussian case, it is implicit in the definition of the Bessel +function (`p = 0` and `q = 1`). +To recover the usual hypergeometric function, simply multiply by `∏ i, Gamma (b i)`. + +## Definitions +For the general case we have +* `Complex.regularizedHGFunCoeff`: the coefficients +* `Complex.regularizedHGFunSeries`: the formal multilinear series +* `Complex.regularizedHGFun`: the function + +For the Gaussian case (`p = 2` and `q = 1`), we define +* `Complex.regularizedGaussHGFunSeries`: the formal multilinear series +* `Complex.regularizedGaussHGFun`: the function + +## Results + +Convergence: +* `radius_regularizedHGFunSeries_eq_top_of_finite`: in the case that the series reduces to a + polynomial, the radius of convergence is infinite. +* `radius_regularizedHGFunSeries_eq_top`: if `p < q + 1`, then the series has infinite convergence + radius. +* `radius_regularizedHGFunSeries_eq_one`: if `p = q + 1`, then the series has convergence radius + `1`. +* `Complex.radius_regularizedGaussHGFunSeries_eq_one`: the Gaussian hypergeometric series has + convergence radius `1`. + +-/ + +@[expose] public noncomputable section + +namespace Complex + +open scoped Nat Real +open Topology Filter + +variable {p q : ℕ} + +variable {a : Multiset ℂ} {b : Multiset ℂ} {n m : ℕ} {j k : ℂ} + +/-- The coefficients of the regularized hypergeometric series. -/ +def regularizedHGFunCoeff (a : Multiset ℂ) (b : Multiset ℂ) (n : ℕ) : ℂ := + (a.map (ascPochhammer ℂ n).eval).prod / (n ! * (b.map (Gamma <| · + n)).prod) + +attribute [grind .] Nat.factorial_ne_zero + +@[grind =] +theorem regularizedHGFunCoeff_eq_zero_iff : + regularizedHGFunCoeff a b n = 0 ↔ + (∃ j ∈ a, ∃ k < n, j = -k) ∨ ∃ j ∈ b, ∃ (m : ℕ), j + n = -m := by + unfold regularizedHGFunCoeff + simp + grind + +variable (a b n m) in +theorem regularizedHGFunCoeff_eq_zero_right (hb : -(n : ℂ) - m ∈ b := by grind) : + regularizedHGFunCoeff a b n = 0 := by grind + +variable (a b n m) in +theorem regularizedHGFunCoeff_eq_zero_left (ha : -(m : ℂ) ∈ a := by grind) + (hm : m < n := by grind) : + regularizedHGFunCoeff a b n = 0 := by grind + +/-- Recursion formula for the coefficients of the hypergeometric series. + +This is mainly used to calculate the convergence radius. -/ +theorem regularizedHGFunCoeff_add_one (hb : ∀ k ∈ b, k ≠ -n) : + regularizedHGFunCoeff a b (n + 1) = regularizedHGFunCoeff a b n * + ((a.map (· + (n : ℂ))).prod / ((b.map (· + (n : ℂ))).prod * (n + 1))) := calc + _ = (a.map fun i ↦ ((ascPochhammer ℂ n).eval i) * (i + n)).prod / + (n ! * (n + 1) * (b.map fun j ↦ Gamma (j + n) * (j + n)).prod) := by + unfold regularizedHGFunCoeff + congrm ((a.map ?_).prod / (?_ * Multiset.prod ?_)) + · ext j + simp [ascPochhammer_succ_right] + · rw [Nat.factorial_succ] + grind + · refine Multiset.map_congr rfl (fun j hj ↦ ?_) + simp only [Nat.cast_add, Nat.cast_one, ← add_assoc] + grind + _ = _ := by + unfold regularizedHGFunCoeff + simp_rw [div_mul_div_comm, Multiset.prod_map_mul] + ring + +/-- Recursion formula for the coefficients of the hypergeometric series. + +This is mainly used to calculate the convergence radius. -/ +theorem regularizedHGFunCoeff_add_one_div_self (h : regularizedHGFunCoeff a b n ≠ 0) : + regularizedHGFunCoeff a b (n + 1) / regularizedHGFunCoeff a b n = + (a.map (· + (n : ℂ))).prod / ((b.map (· + (n : ℂ))).prod * (n + 1)) := by + by_cases! hb : ∀ k ∈ b, k ≠ -n + · rw [regularizedHGFunCoeff_add_one hb] + field_simp + · obtain ⟨j, hj⟩ := hb + have h₁ : (b.map (· + (n : ℂ))).prod = 0 := by + grind [Multiset.prod_eq_zero, Multiset.mem_map] + simp [regularizedHGFunCoeff_eq_zero_right a b n 0, h₁] + +private theorem multiset_prod_eq_pow_mul_multiset_prod (a : Multiset ℂ) (hn : n ≠ 0) : + (a.map (· + (n : ℂ))).prod = n ^ a.card * (a.map (· / (n : ℂ) + 1)).prod := calc + _ = (a.map (fun j ↦ n * (j / (n : ℂ) + 1))).prod := by + congr; ext; field_simp + _ = _ := by + simp [Multiset.prod_map_mul] + +private +theorem multiset_prod_div_multiset_prod_mul (a : Multiset ℂ) (b : Multiset ℂ) (hn : n ≠ 0) : + (a.map (· + (n : ℂ))).prod / ((b.map (· + (n : ℂ))).prod * (n + 1)) = + n ^ (a.card - (b.card : ℤ) - 1) * (a.map (· / (n : ℂ) + 1)).prod / + ((b.map (· / (n : ℂ) + 1)).prod * (1 + (n : ℂ)⁻¹)) := by + rw [multiset_prod_eq_pow_mul_multiset_prod a hn, multiset_prod_eq_pow_mul_multiset_prod b hn] + field_simp + congr 1 + calc + _ = n * n ^ b.card * n ^ (a.card - b.card - (1 : ℤ)) * + (a.map (fun x : ℂ ↦ (x + n) / n)).prod := by + congr 1 + rw [← pow_succ', ← zpow_natCast, ← zpow_natCast, ← zpow_add' (by left; norm_cast)] + grind + _ = _ := by ring + +variable (a b) in +/-- The regularized hypergeometric series. -/ +def regularizedHGFunSeries : FormalMultilinearSeries ℂ ℂ ℂ := + .ofScalars ℂ (regularizedHGFunCoeff a b) + +@[simp] +theorem regularizedHGFunSeries_coeff : + (regularizedHGFunSeries a b).coeff = regularizedHGFunCoeff a b := by + unfold regularizedHGFunSeries + ext; simp + +@[simp, grind =] +theorem regularizedHGFunSeries_eq_zero : + regularizedHGFunSeries a b n = 0 ↔ regularizedHGFunCoeff a b n = 0 := by + apply FormalMultilinearSeries.ofScalars_eq_zero + +variable (a b) in +/-- The regularized hypergeometric function. -/ +def regularizedHGFun (z : ℂ) : ℂ := (regularizedHGFunSeries a b).sum z + +/-- If there exists `j` and `k : ℕ`, such that `a j = -k`, then the hypergeometric series is finite +and has convergence radius `∞`. -/ +theorem radius_regularizedHGFunSeries_eq_top_of_finite (ha : j ∈ a) (hj : j = -n) : + (regularizedHGFunSeries a b).radius = ⊤ := by + apply FormalMultilinearSeries.radius_eq_top_of_eventually_eq_zero + apply eventually_atTop.mpr + use n + 1 + grind + +variable (b) in +/-- If for all `j` and `k : ℕ`, `a j ≠ -k`, then the coefficients of the hypergeometric series +are eventually non-vanishing. -/ +theorem eventually_atTop_regularizedHGFunCoeff_ne_zero (h : ∀ j ∈ a, ∀ (k : ℕ), j ≠ -↑k) : + ∀ᶠ (n : ℕ) in atTop, regularizedHGFunCoeff a b n ≠ 0 := by + rw [Filter.eventually_atTop] + use b.toFinset.sup (⌈-re ·⌉₊) + 1 + intro n hn h' + rw [regularizedHGFunCoeff_eq_zero_iff] at h' + rcases h' with (h' | ⟨j, hj, m, h'⟩) + · grind + · suffices (m : ℝ) < 0 by grind + suffices -j.re < n by + have h : j = -m - n := by grind + simpa [h] using this + calc + -j.re ≤ ⌈-j.re⌉₊ := Nat.le_ceil (-j.re) + _ ≤ b.toFinset.sup (⌈-re ·⌉₊) := mod_cast Finset.le_sup (by grind) (f := (⌈-re ·⌉₊)) + _ < n := by norm_cast + +variable (a) in +private theorem tendsto_multiset_prod_div_add_one : + Tendsto (fun n : ℕ ↦ (a.map (· / (n : ℂ) + 1)).prod) atTop (𝓝 1) := by + suffices ∀ i ∈ a, Tendsto (fun n : ℕ ↦ (i / n + 1)) atTop (𝓝 <| (fun _ : _ ↦ 1) i) by + simpa using tendsto_multiset_prod _ this + intro i hi + simpa using (tendsto_const_div_atTop_nhds_zero_nat i).add_const 1 + +variable (a b) in +private theorem tendsto_multiset_prod_div_multiset_prod_mul : + Tendsto (fun n : ℕ ↦ (a.map (· / (n : ℂ) + 1)).prod / + ((b.map (· / (n : ℂ) + 1)).prod * (1 + (n : ℂ)⁻¹))) atTop (𝓝 1) := by + have h : Tendsto (fun n : ℕ ↦ (n : ℂ)⁻¹) atTop (𝓝 0) := tendsto_inv_atTop_nhds_zero_nat + have := (tendsto_multiset_prod_div_add_one a).div + ((tendsto_multiset_prod_div_add_one b).mul <| h.const_add 1) (by simp) + simp only [add_zero, mul_one, ne_eq, one_ne_zero, not_false_eq_true, div_self] at this + apply this.congr + simp + +/-- If `a.card ≤ b.card`, then the hypergeometric series has infinite convergence radius. -/ +@[grind =] +theorem radius_regularizedHGFunSeries_eq_top (h : a.card ≤ b.card) : + (regularizedHGFunSeries a b).radius = ⊤ := by + by_cases! ha : ∃ j ∈ a, ∃ k : ℕ, j = -k + · obtain ⟨j, hj, k, ha⟩ := ha + apply radius_regularizedHGFunSeries_eq_top_of_finite hj ha + apply FormalMultilinearSeries.ofScalars_radius_eq_top_of_tendsto + · apply eventually_atTop_regularizedHGFunCoeff_ne_zero b ha + · simp only [Nat.succ_eq_add_one] + have h₁ : Tendsto (fun (n : ℕ) ↦ (n : ℂ) ^ (a.card - (b.card : ℤ) - 1)) atTop (𝓝 0) := by + have := (tendsto_one_div_atTop_nhds_zero_nat (𝕜 := ℂ)).pow (b.card + 1 - a.card) + rw [zero_pow (by grind)] at this + apply this.congr + intro n + rw [one_div, inv_pow, ← zpow_natCast, ← zpow_neg, Int.ofNat_sub (by grind), + Int.natCast_add_one] + ring_nf + have := (h₁.mul (tendsto_multiset_prod_div_multiset_prod_mul a b)).norm + simp only [mul_one, norm_zero] at this + apply this.congr' + have h_ne := eventually_atTop_regularizedHGFunCoeff_ne_zero b ha + filter_upwards [h_ne, Filter.eventually_ne_atTop 0] with n hn₁ hn₂ + rw [← Complex.norm_div, regularizedHGFunCoeff_add_one_div_self hn₁, + multiset_prod_div_multiset_prod_mul a b hn₂, mul_div] + +/-- If `a.card = b.card + 1`, then the hypergeometric series has convergence radius `1`, unless it +is a polynomial. -/ +@[grind =] +theorem radius_regularizedHGFunSeries_eq_one (h : a.card = b.card + 1) + (h' : ∀ j ∈ a, ∀ k : ℕ, j ≠ -k) : + (regularizedHGFunSeries a b).radius = 1 := by + have : Tendsto (fun n ↦ ‖regularizedHGFunCoeff a b n.succ‖ / ‖regularizedHGFunCoeff a b n‖) atTop + (𝓝 1) := by + have := (tendsto_multiset_prod_div_multiset_prod_mul a b).norm + simp only [norm_one] at this + apply this.congr' + have h_ne := eventually_atTop_regularizedHGFunCoeff_ne_zero b h' + filter_upwards [h_ne, Filter.eventually_ne_atTop 0] with n hn₁ hn₂ + simp [Nat.succ_eq_add_one, ← Complex.norm_div, regularizedHGFunCoeff_add_one_div_self hn₁, + multiset_prod_div_multiset_prod_mul a b hn₂, h] + have := FormalMultilinearSeries.ofScalars_radius_eq_inv_of_tendsto (r := 1) ℂ _ (by simp) this + simpa + +/-- If `a.card = b.card + 1`, then the hypergeometric series has convergence radius greater or equal +to `1`. -/ +theorem radius_regularizedHGFunSeries_ge_one (h : a.card = b.card + 1) : + 1 ≤ (regularizedHGFunSeries a b).radius := by + by_cases! h' : ∀ j ∈ a, ∀ k : ℕ, j ≠ -k + · grind + · obtain ⟨j, hj, k, h'⟩ := h' + rw [radius_regularizedHGFunSeries_eq_top_of_finite hj h'] + simp + +section ZeroZero + +/-- The regularized hypergeometric series with `a = b = 0` is exponential series. -/ +@[simp, grind =] +theorem regularizedHGFunSeries_zero_zero : + regularizedHGFunSeries 0 0 = NormedSpace.expSeries ℂ ℂ := by + ext n + simp [regularizedHGFunCoeff, NormedSpace.expSeries] + +/-- The regularized hypergeometric function `₀F₀` is the complex exponential. -/ +@[simp, grind =] +theorem regularizedHGFun_zero_zero : regularizedHGFun 0 0 = exp := by + rw [exp_eq_exp_ℂ, NormedSpace.exp_eq_expSeries_sum (𝕂 := ℂ)] + unfold regularizedHGFun + simp + +end ZeroZero + +section Gaussian + +/-- The regularized Gaussian hypergeometric function. -/ +def regularizedGaussHGFunSeries (a b c : ℂ) : FormalMultilinearSeries ℂ ℂ ℂ := + regularizedHGFunSeries {a, b} {c} + +/-- The regularized Gaussian hypergeometric function. -/ +def regularizedGaussHGFun (a b c z : ℂ) : ℂ := + (regularizedGaussHGFunSeries a b c).sum z + +variable {a b c z : ℂ} + +variable (a b c) in +theorem regularizedGaussHGFunSeries_symm : + regularizedGaussHGFunSeries a b c = regularizedGaussHGFunSeries b a c := by + unfold regularizedGaussHGFunSeries + rw [Multiset.pair_comm] + +variable (a b c) in +theorem regularizedGaussHGFun_symm : + regularizedGaussHGFun a b c = regularizedGaussHGFun b a c := by + unfold regularizedGaussHGFun + rw [regularizedGaussHGFunSeries_symm] + +theorem coeff_regularizedGaussHGFunSeries : + (a.regularizedGaussHGFunSeries b c).coeff n = + ((ascPochhammer ℂ n).eval a * (ascPochhammer ℂ n).eval b) / (n ! * Gamma (c + n)) := by + simp [regularizedGaussHGFunSeries, regularizedHGFunCoeff] + +theorem Gamma_inv_mul_ordinaryHypergeometricSeries_eq (hc : ∀ k : ℕ, c ≠ -k) {n : ℕ} : + (Gamma c)⁻¹ * (ordinaryHypergeometricSeries ℂ a b c).coeff n = + (a.regularizedGaussHGFunSeries b c).coeff n := by + rw [coeff_regularizedGaussHGFunSeries, ordinaryHypergeometricSeries, + FormalMultilinearSeries.coeff_ofScalars, ordinaryHypergeometricCoefficient, + ← Gamma_add_nat_div_Gamma_eq c hc] + grind + +theorem ordinaryHypergeometric_div_Gamma_eq (hc : ∀ k : ℕ, c ≠ -k) : + ordinaryHypergeometric a b c z / Gamma c = regularizedGaussHGFun a b c z := by + rw [regularizedGaussHGFun, ordinaryHypergeometric, div_eq_inv_mul, ← smul_eq_mul, + FormalMultilinearSeries.const_smul_sum_apply] + congr + ext n + simp [Gamma_inv_mul_ordinaryHypergeometricSeries_eq hc] + +variable (b c) in +@[simp] +theorem radius_regularizedGaussHGFunSeries_eq_top_of_left (k : ℕ) : + (regularizedGaussHGFunSeries (-k) b c).radius = ⊤ := + radius_regularizedHGFunSeries_eq_top_of_finite (j := -(k : ℂ)) (by simp) rfl + +variable (a c) in +@[simp] +theorem radius_regularizedGaussHGFunSeries_eq_top_of_right (k : ℕ) : + (regularizedGaussHGFunSeries a (-k) c).radius = ⊤ := + radius_regularizedHGFunSeries_eq_top_of_finite (j := -(k : ℂ)) (by simp) rfl + +variable (c) in +@[grind =] +theorem radius_regularizedGaussHGFunSeries_eq_one (h : ∀ k : ℕ, a ≠ -k ∧ b ≠ -k) : + (regularizedGaussHGFunSeries a b c).radius = 1 := + radius_regularizedHGFunSeries_eq_one rfl (by simp; grind) + +variable (a b c) in +theorem radius_regularizedGaussHGFunSeries_ge_one : + 1 ≤ (regularizedGaussHGFunSeries a b c).radius := + radius_regularizedHGFunSeries_ge_one rfl + +end Gaussian + +end Complex From 985d97018f12d5ac61a60f551da15d7a4b1e7ac1 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 07:28:34 +0000 Subject: [PATCH 1218/1300] chore(Order/Filter/IsBounded): use `to_dual` (#37751) use `to_dual` for `Filter.IsBounded` --- .../Algebra/Order/Monoid/Unbundled/Basic.lean | 40 +-- Mathlib/Order/Filter/IsBounded.lean | 268 ++++-------------- 2 files changed, 81 insertions(+), 227 deletions(-) diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean index 8879ea063dc1d4..0c4966c2040c1b 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean @@ -66,29 +66,29 @@ variable [LE α] -- Note: in this section, we use `@[gcongr high]` so that these lemmas have a higher priority than -- lemmas like `mul_le_mul_of_nonneg_left`, which have an extra side condition. -@[to_additive (attr := gcongr high - 1)] +@[to_additive (attr := gcongr high - 1, to_dual self)] theorem mul_le_mul_right [MulLeftMono α] {b c : α} (bc : b ≤ c) (a : α) : a * b ≤ a * c := CovariantClass.elim _ bc -@[to_additive le_of_add_le_add_left] +@[to_additive (attr := to_dual self) le_of_add_le_add_left] theorem le_of_mul_le_mul_left' [MulLeftReflectLE α] {a b c : α} (bc : a * b ≤ a * c) : b ≤ c := MulLeftReflectLE.le_of_mul_le_mul_left' bc -@[to_additive (attr := gcongr high - 1)] +@[to_additive (attr := gcongr high - 1, to_dual self)] theorem mul_le_mul_left [i : MulRightMono α] {b c : α} (bc : b ≤ c) (a : α) : b * a ≤ c * a := i.elim a bc -@[to_additive le_of_add_le_add_right] +@[to_additive (attr := to_dual self) le_of_add_le_add_right] theorem le_of_mul_le_mul_right' [MulRightReflectLE α] {a b c : α} (bc : b * a ≤ c * a) : b ≤ c := MulRightReflectLE.le_of_mul_le_mul_right' bc -@[to_additive (attr := simp)] +@[to_additive (attr := simp, to_dual self)] theorem mul_le_mul_iff_left [MulLeftMono α] [MulLeftReflectLE α] (a : α) {b c : α} : a * b ≤ a * c ↔ b ≤ c := rel_iff_cov' ‹MulLeftMono α›.elim fun _ ↦ MulLeftReflectLE.le_of_mul_le_mul_left' -@[to_additive (attr := simp)] +@[to_additive (attr := simp, to_dual self)] theorem mul_le_mul_iff_right [MulRightMono α] [MulRightReflectLE α] (a : α) {b c : α} : b * a ≤ c * a ↔ b ≤ c := rel_iff_cov' ‹MulRightMono α›.elim fun _ ↦ MulRightReflectLE.le_of_mul_le_mul_right' @@ -99,13 +99,13 @@ section LT variable [LT α] -@[to_additive (attr := simp)] +@[to_additive (attr := simp, to_dual self)] theorem mul_lt_mul_iff_left [MulLeftStrictMono α] [MulLeftReflectLT α] (a : α) {b c : α} : a * b < a * c ↔ b < c := rel_iff_cov α α (· * ·) (· < ·) a -@[to_additive (attr := simp)] +@[to_additive (attr := simp, to_dual self)] theorem mul_lt_mul_iff_right [MulRightStrictMono α] [MulRightReflectLT α] (a : α) {b c : α} : b * a < c * a ↔ b < c := @@ -114,24 +114,24 @@ theorem mul_lt_mul_iff_right [MulRightStrictMono α] -- Note: in this section, we use `@[gcongr high]` so that these lemmas have a higher priority than -- lemmas like `mul_lt_mul_of_pos_left`, which have an extra side condition. -@[to_additive (attr := gcongr high)] +@[to_additive (attr := gcongr high, to_dual self)] theorem mul_lt_mul_right [MulLeftStrictMono α] {b c : α} (bc : b < c) (a : α) : a * b < a * c := CovariantClass.elim _ bc -@[to_additive lt_of_add_lt_add_left] +@[to_additive (attr := to_dual self) lt_of_add_lt_add_left] theorem lt_of_mul_lt_mul_left' [MulLeftReflectLT α] {a b c : α} (bc : a * b < a * c) : b < c := ContravariantClass.elim _ bc -@[to_additive (attr := gcongr high)] +@[to_additive (attr := gcongr high, to_dual self)] theorem mul_lt_mul_left [i : MulRightStrictMono α] {b c : α} (bc : b < c) (a : α) : b * a < c * a := i.elim a bc -@[to_additive lt_of_add_lt_add_right] +@[to_additive (attr := to_dual self) lt_of_add_lt_add_right] theorem lt_of_mul_lt_mul_right' [i : MulRightReflectLT α] {a b c : α} (bc : b * a < c * a) : b < c := @@ -162,7 +162,7 @@ lemma mul_left_strictMono [MulRightStrictMono α] {a : α} : StrictMono (· * a) -- Note: in this section, we use `@[gcongr high]` so that these lemmas have a higher priority than -- lemmas like `mul_le_mul_of_nonneg`, which have an extra side condition. -@[to_additive (attr := gcongr high)] +@[to_additive (attr := gcongr high, to_dual self)] theorem mul_lt_mul_of_lt_of_lt [MulLeftStrictMono α] [MulRightStrictMono α] {a b c d : α} (h₁ : a < b) (h₂ : c < d) : a * c < b * d := @@ -170,41 +170,41 @@ theorem mul_lt_mul_of_lt_of_lt [MulLeftStrictMono α] a * c < a * d := mul_lt_mul_right h₂ a _ < b * d := mul_lt_mul_left h₁ d -alias add_lt_add := add_lt_add_of_lt_of_lt +@[to_dual self] alias add_lt_add := add_lt_add_of_lt_of_lt -@[to_additive] +@[to_additive (attr := to_dual self)] theorem mul_lt_mul_of_le_of_lt [MulLeftStrictMono α] [MulRightMono α] {a b c d : α} (h₁ : a ≤ b) (h₂ : c < d) : a * c < b * d := (mul_le_mul_left h₁ _).trans_lt (mul_lt_mul_right h₂ b) -@[to_additive] +@[to_additive (attr := to_dual self)] theorem mul_lt_mul_of_lt_of_le [MulLeftMono α] [MulRightStrictMono α] {a b c d : α} (h₁ : a < b) (h₂ : c ≤ d) : a * c < b * d := (mul_le_mul_right h₂ _).trans_lt (mul_lt_mul_left h₁ d) /-- Only assumes left strict covariance. -/ -@[to_additive /-- Only assumes left strict covariance -/] +@[to_additive (attr := to_dual self) /-- Only assumes left strict covariance -/] theorem Left.mul_lt_mul [MulLeftStrictMono α] [MulRightMono α] {a b c d : α} (h₁ : a < b) (h₂ : c < d) : a * c < b * d := mul_lt_mul_of_le_of_lt h₁.le h₂ /-- Only assumes right strict covariance. -/ -@[to_additive /-- Only assumes right strict covariance -/] +@[to_additive (attr := to_dual self) /-- Only assumes right strict covariance -/] theorem Right.mul_lt_mul [MulLeftMono α] [MulRightStrictMono α] {a b c d : α} (h₁ : a < b) (h₂ : c < d) : a * c < b * d := mul_lt_mul_of_lt_of_le h₁ h₂.le -@[to_additive (attr := gcongr high) add_le_add] +@[to_additive (attr := gcongr high, to_dual self) add_le_add] theorem mul_le_mul' [MulLeftMono α] [MulRightMono α] {a b c d : α} (h₁ : a ≤ b) (h₂ : c ≤ d) : a * c ≤ b * d := by grw [h₁, h₂] -@[to_additive] +@[to_additive (attr := to_dual self)] theorem mul_le_mul_three [MulLeftMono α] [MulRightMono α] {a b c d e f : α} (h₁ : a ≤ d) (h₂ : b ≤ e) (h₃ : c ≤ f) : diff --git a/Mathlib/Order/Filter/IsBounded.lean b/Mathlib/Order/Filter/IsBounded.lean index 66a0d929650c80..3b3daebdae0303 100644 --- a/Mathlib/Order/Filter/IsBounded.lean +++ b/Mathlib/Order/Filter/IsBounded.lean @@ -60,15 +60,12 @@ theorem IsBounded.mono (h : f ≤ g) : IsBounded r g → IsBounded r f theorem IsBoundedUnder.mono {f g : Filter β} {u : β → α} (h : f ≤ g) : g.IsBoundedUnder r u → f.IsBoundedUnder r u := fun hg => IsBounded.mono (map_mono h) hg +@[to_dual mono_ge] theorem IsBoundedUnder.mono_le [Preorder β] {l : Filter α} {u v : α → β} (hu : IsBoundedUnder (· ≤ ·) l u) (hv : v ≤ᶠ[l] u) : IsBoundedUnder (· ≤ ·) l v := by apply hu.imp exact fun b hb => (eventually_map.1 hb).mp <| hv.mono fun x => le_trans -theorem IsBoundedUnder.mono_ge [Preorder β] {l : Filter α} {u v : α → β} - (hu : IsBoundedUnder (· ≥ ·) l u) (hv : u ≤ᶠ[l] v) : IsBoundedUnder (· ≥ ·) l v := - IsBoundedUnder.mono_le (β := βᵒᵈ) hu hv - theorem isBoundedUnder_const [Std.Refl r] {l : Filter β} {a : α} : IsBoundedUnder r l fun _ => a := ⟨a, eventually_map.2 <| Eventually.of_forall fun _ => refl _⟩ @@ -93,20 +90,16 @@ lemma Tendsto.isBoundedUnder_comp {ι κ X : Type*} {r : X → X → Prop} {f : section Preorder variable [Preorder α] {f : Filter β} {u : β → α} {s : Set β} +@[to_dual eventually_ge] lemma IsBoundedUnder.eventually_le (h : IsBoundedUnder (· ≤ ·) f u) : ∃ a, ∀ᶠ x in f, u x ≤ a := by tauto -lemma IsBoundedUnder.eventually_ge (h : IsBoundedUnder (· ≥ ·) f u) : - ∃ a, ∀ᶠ x in f, a ≤ u x := - IsBoundedUnder.eventually_le (α := αᵒᵈ) h - +@[to_dual isBoundedUnder_of_eventually_ge] lemma isBoundedUnder_of_eventually_le {a : α} (h : ∀ᶠ x in f, u x ≤ a) : IsBoundedUnder (· ≤ ·) f u := ⟨a, h⟩ -lemma isBoundedUnder_of_eventually_ge {a : α} (h : ∀ᶠ x in f, a ≤ u x) : - IsBoundedUnder (· ≥ ·) f u := ⟨a, h⟩ - +@[to_dual] lemma isBoundedUnder_iff_eventually_bddAbove : f.IsBoundedUnder (· ≤ ·) u ↔ ∃ s, BddAbove (u '' s) ∧ ∀ᶠ x in f, x ∈ s := by constructor @@ -115,54 +108,35 @@ lemma isBoundedUnder_iff_eventually_bddAbove : · rintro ⟨s, ⟨b, hb⟩, hs⟩ exact ⟨b, hs.mono <| by simpa [upperBounds] using hb⟩ -lemma isBoundedUnder_iff_eventually_bddBelow : - f.IsBoundedUnder (· ≥ ·) u ↔ ∃ s, BddBelow (u '' s) ∧ ∀ᶠ x in f, x ∈ s := - isBoundedUnder_iff_eventually_bddAbove (α := αᵒᵈ) - +@[to_dual] lemma _root_.BddAbove.isBoundedUnder (hs : s ∈ f) (hu : BddAbove (u '' s)) : f.IsBoundedUnder (· ≤ ·) u := isBoundedUnder_iff_eventually_bddAbove.2 ⟨_, hu, hs⟩ /-- A bounded above function `u` is in particular eventually bounded above. -/ +@[to_dual /-- A bounded below function `u` is in particular eventually bounded below. -/] lemma _root_.BddAbove.isBoundedUnder_of_range (hu : BddAbove (Set.range u)) : f.IsBoundedUnder (· ≤ ·) u := BddAbove.isBoundedUnder (s := univ) f.univ_mem (by simpa) -lemma _root_.BddBelow.isBoundedUnder (hs : s ∈ f) (hu : BddBelow (u '' s)) : - f.IsBoundedUnder (· ≥ ·) u := isBoundedUnder_iff_eventually_bddBelow.2 ⟨_, hu, hs⟩ - -/-- A bounded below function `u` is in particular eventually bounded below. -/ -lemma _root_.BddBelow.isBoundedUnder_of_range (hu : BddBelow (Set.range u)) : - f.IsBoundedUnder (· ≥ ·) u := BddBelow.isBoundedUnder (s := univ) f.univ_mem (by simpa) - +@[to_dual ge_of_finite] lemma IsBoundedUnder.le_of_finite [Nonempty α] [IsDirectedOrder α] [Finite β] {f : Filter β} {u : β → α} : IsBoundedUnder (· ≤ ·) f u := (Set.toFinite _).bddAbove.isBoundedUnder_of_range -lemma IsBoundedUnder.ge_of_finite [Nonempty α] [IsCodirectedOrder α] [Finite β] - {f : Filter β} {u : β → α} : IsBoundedUnder (· ≥ ·) f u := - (Set.toFinite _).bddBelow.isBoundedUnder_of_range - end Preorder +@[to_dual isBoundedUnder_ge_comp] theorem _root_.Monotone.isBoundedUnder_le_comp [Preorder α] [Preorder β] {l : Filter γ} {u : γ → α} {v : α → β} (hv : Monotone v) (hl : l.IsBoundedUnder (· ≤ ·) u) : l.IsBoundedUnder (· ≤ ·) (v ∘ u) := hl.comp hv -theorem _root_.Monotone.isBoundedUnder_ge_comp [Preorder α] [Preorder β] {l : Filter γ} {u : γ → α} - {v : α → β} (hv : Monotone v) (hl : l.IsBoundedUnder (· ≥ ·) u) : - l.IsBoundedUnder (· ≥ ·) (v ∘ u) := - hl.comp (swap hv) - +@[to_dual isBoundedUnder_ge_comp] theorem _root_.Antitone.isBoundedUnder_le_comp [Preorder α] [Preorder β] {l : Filter γ} {u : γ → α} - {v : α → β} (hv : Antitone v) (hl : l.IsBoundedUnder (· ≥ ·) u) : + {v : α → β} (hv : Antitone v) (hl : l.IsBoundedUnder (fun x1 x2 ↦ x2 ≤ x1) u) : l.IsBoundedUnder (· ≤ ·) (v ∘ u) := hl.comp (swap hv) -theorem _root_.Antitone.isBoundedUnder_ge_comp [Preorder α] [Preorder β] {l : Filter γ} {u : γ → α} - {v : α → β} (hv : Antitone v) (hl : l.IsBoundedUnder (· ≤ ·) u) : - l.IsBoundedUnder (· ≥ ·) (v ∘ u) := - hl.comp hv - +@[to_dual] theorem not_isBoundedUnder_of_tendsto_atTop [Preorder β] [NoMaxOrder β] {f : α → β} {l : Filter α} [l.NeBot] (hf : Tendsto f l atTop) : ¬IsBoundedUnder (· ≤ ·) l f := by rintro ⟨b, hb⟩ @@ -173,10 +147,7 @@ theorem not_isBoundedUnder_of_tendsto_atTop [Preorder β] [NoMaxOrder β] {f : eq_empty_of_subset_empty fun x hx => (not_le_of_gt h) (le_trans hx.2 hx.1) exact (nonempty_of_mem (hb.and hb')).ne_empty this -theorem not_isBoundedUnder_of_tendsto_atBot [Preorder β] [NoMinOrder β] {f : α → β} {l : Filter α} - [l.NeBot] (hf : Tendsto f l atBot) : ¬IsBoundedUnder (· ≥ ·) l f := - not_isBoundedUnder_of_tendsto_atTop (β := βᵒᵈ) hf - +@[to_dual] theorem IsBoundedUnder.bddAbove_range_of_cofinite [Preorder β] [IsDirectedOrder β] {f : α → β} (hf : IsBoundedUnder (· ≤ ·) cofinite f) : BddAbove (range f) := by rcases hf with ⟨b, hb⟩ @@ -184,19 +155,12 @@ theorem IsBoundedUnder.bddAbove_range_of_cofinite [Preorder β] [IsDirectedOrder rw [← image_univ, ← union_compl_self { x | f x ≤ b }, image_union, bddAbove_union] exact ⟨⟨b, forall_mem_image.2 fun x => id⟩, (hb.image f).bddAbove⟩ -theorem IsBoundedUnder.bddBelow_range_of_cofinite [Preorder β] [IsCodirectedOrder β] {f : α → β} - (hf : IsBoundedUnder (· ≥ ·) cofinite f) : BddBelow (range f) := - IsBoundedUnder.bddAbove_range_of_cofinite (β := βᵒᵈ) hf - +@[to_dual] theorem IsBoundedUnder.bddAbove_range [Preorder β] [IsDirectedOrder β] {f : ℕ → β} (hf : IsBoundedUnder (· ≤ ·) atTop f) : BddAbove (range f) := by rw [← Nat.cofinite_eq_atTop] at hf exact hf.bddAbove_range_of_cofinite -theorem IsBoundedUnder.bddBelow_range [Preorder β] [IsCodirectedOrder β] {f : ℕ → β} - (hf : IsBoundedUnder (· ≥ ·) atTop f) : BddBelow (range f) := - IsBoundedUnder.bddAbove_range (β := βᵒᵈ) hf - /-- To check that a filter is frequently bounded, it suffices to have a witness which bounds `f` at some point for every admissible set. @@ -214,11 +178,8 @@ theorem IsBounded.isCobounded_flip [IsTrans α r] [NeBot f] : f.IsBounded r → let ⟨_, rxa, rbx⟩ := (ha.and hb).exists show r b a from _root_.trans rbx rxa⟩ -theorem IsBounded.isCobounded_ge [Preorder α] [NeBot f] (h : f.IsBounded (· ≤ ·)) : - f.IsCobounded (· ≥ ·) := - h.isCobounded_flip - -theorem IsBounded.isCobounded_le [Preorder α] [NeBot f] (h : f.IsBounded (· ≥ ·)) : +@[to_dual isCobounded_ge] +theorem IsBounded.isCobounded_le [Preorder α] [NeBot f] (h : f.IsBounded (fun x1 x2 ↦ x2 ≤ x1)) : f.IsCobounded (· ≤ ·) := h.isCobounded_flip @@ -226,33 +187,23 @@ theorem IsBoundedUnder.isCoboundedUnder_flip {u : γ → α} {l : Filter γ} [Is (h : l.IsBoundedUnder r u) : l.IsCoboundedUnder (flip r) u := h.isCobounded_flip +@[to_dual isCoboundedUnder_ge] theorem IsBoundedUnder.isCoboundedUnder_le {u : γ → α} {l : Filter γ} [Preorder α] [NeBot l] - (h : l.IsBoundedUnder (· ≥ ·) u) : l.IsCoboundedUnder (· ≤ ·) u := - h.isCoboundedUnder_flip - -theorem IsBoundedUnder.isCoboundedUnder_ge {u : γ → α} {l : Filter γ} [Preorder α] [NeBot l] - (h : l.IsBoundedUnder (· ≤ ·) u) : l.IsCoboundedUnder (· ≥ ·) u := + (h : l.IsBoundedUnder (fun x1 x2 ↦ x2 ≤ x1) u) : l.IsCoboundedUnder (· ≤ ·) u := h.isCoboundedUnder_flip +@[to_dual isCoboundedUnder_ge_of_eventually_le] lemma isCoboundedUnder_le_of_eventually_le [Preorder α] (l : Filter ι) [NeBot l] {f : ι → α} {x : α} (hf : ∀ᶠ i in l, x ≤ f i) : IsCoboundedUnder (· ≤ ·) l f := IsBoundedUnder.isCoboundedUnder_le ⟨x, hf⟩ -lemma isCoboundedUnder_ge_of_eventually_le [Preorder α] (l : Filter ι) [NeBot l] {f : ι → α} {x : α} - (hf : ∀ᶠ i in l, f i ≤ x) : - IsCoboundedUnder (· ≥ ·) l f := - IsBoundedUnder.isCoboundedUnder_ge ⟨x, hf⟩ - +@[to_dual isCoboundedUnder_ge_of_le] lemma isCoboundedUnder_le_of_le [Preorder α] (l : Filter ι) [NeBot l] {f : ι → α} {x : α} (hf : ∀ i, x ≤ f i) : IsCoboundedUnder (· ≤ ·) l f := isCoboundedUnder_le_of_eventually_le l (Eventually.of_forall hf) -lemma isCoboundedUnder_ge_of_le [Preorder α] (l : Filter ι) [NeBot l] {f : ι → α} {x : α} - (hf : ∀ i, f i ≤ x) : - IsCoboundedUnder (· ≥ ·) l f := - isCoboundedUnder_ge_of_eventually_le l (Eventually.of_forall hf) theorem isCobounded_bot : IsCobounded r ⊥ ↔ ∃ b, ∀ x, r b x := by simp [IsCobounded] @@ -268,6 +219,9 @@ theorem IsCobounded.mono (h : f ≤ g) : f.IsCobounded r → g.IsCobounded r /-- For nontrivial filters in linear orders, coboundedness for `≤` implies frequent boundedness from below. -/ +@[to_dual frequently_le +/-- For nontrivial filters in linear orders, coboundedness for `≥` implies frequent boundedness +from above. -/] lemma IsCobounded.frequently_ge [LinearOrder α] [NeBot f] (cobdd : IsCobounded (· ≤ ·) f) : ∃ l, ∃ᶠ x in f, l ≤ x := by obtain ⟨t, ht⟩ := cobdd @@ -277,14 +231,9 @@ lemma IsCobounded.frequently_ge [LinearOrder α] [NeBot f] (cobdd : IsCobounded specialize ht t' (by filter_upwards [ev] with _ h using (not_le.mp h).le) exact not_lt_of_ge ht ht' -set_option backward.isDefEq.respectTransparency false in -/-- For nontrivial filters in linear orders, coboundedness for `≥` implies frequent boundedness -from above. -/ -lemma IsCobounded.frequently_le [LinearOrder α] [NeBot f] (cobdd : IsCobounded (· ≥ ·) f) : - ∃ u, ∃ᶠ x in f, x ≤ u := - cobdd.frequently_ge (α := αᵒᵈ) - /-- In linear orders, frequent boundedness from below implies coboundedness for `≤`. -/ +@[to_dual of_frequently_le +/-- In linear orders, frequent boundedness from above implies coboundedness for `≥`. -/] lemma IsCobounded.of_frequently_ge [LinearOrder α] {l : α} (freq_ge : ∃ᶠ x in f, l ≤ x) : IsCobounded (· ≤ ·) f := by rcases isBot_or_exists_lt l with lbot | ⟨l', hl'⟩ @@ -293,31 +242,18 @@ lemma IsCobounded.of_frequently_ge [LinearOrder α] {l : α} (freq_ge : ∃ᶠ x obtain ⟨w, l_le_w, w_le_u⟩ := (freq_ge.and_eventually hu).exists exact hl'.le.trans (l_le_w.trans w_le_u) -/-- In linear orders, frequent boundedness from above implies coboundedness for `≥`. -/ -lemma IsCobounded.of_frequently_le [LinearOrder α] {u : α} (freq_le : ∃ᶠ r in f, r ≤ u) : - IsCobounded (· ≥ ·) f := - IsCobounded.of_frequently_ge (α := αᵒᵈ) freq_le - +@[to_dual frequently_le] lemma IsCoboundedUnder.frequently_ge [LinearOrder α] {f : Filter ι} [NeBot f] {u : ι → α} (h : IsCoboundedUnder (· ≤ ·) f u) : ∃ a, ∃ᶠ x in f, a ≤ u x := IsCobounded.frequently_ge h -lemma IsCoboundedUnder.frequently_le [LinearOrder α] {f : Filter ι} [NeBot f] {u : ι → α} - (h : IsCoboundedUnder (· ≥ ·) f u) : - ∃ a, ∃ᶠ x in f, u x ≤ a := - IsCobounded.frequently_le h - +@[to_dual of_frequently_le] lemma IsCoboundedUnder.of_frequently_ge [LinearOrder α] {f : Filter ι} {u : ι → α} {a : α} (freq_ge : ∃ᶠ x in f, a ≤ u x) : IsCoboundedUnder (· ≤ ·) f u := IsCobounded.of_frequently_ge freq_ge -lemma IsCoboundedUnder.of_frequently_le [LinearOrder α] {f : Filter ι} {u : ι → α} - {a : α} (freq_le : ∃ᶠ x in f, u x ≤ a) : - IsCoboundedUnder (· ≥ ·) f u := - IsCobounded.of_frequently_le freq_le - end Relation section add_and_sum @@ -342,15 +278,7 @@ lemma isBoundedUnder_sum {κ : Type*} [AddCommMonoid R] {r : R → R → Prop} variable [Preorder R] -lemma isBoundedUnder_ge_add [Add R] [AddLeftMono R] [AddRightMono R] - {u v : α → R} (u_bdd_ge : f.IsBoundedUnder (· ≥ ·) u) (v_bdd_ge : f.IsBoundedUnder (· ≥ ·) v) : - f.IsBoundedUnder (· ≥ ·) (u + v) := by - obtain ⟨U, hU⟩ := u_bdd_ge - obtain ⟨V, hV⟩ := v_bdd_ge - use U + V - simp only [eventually_map, Pi.add_apply] at hU hV ⊢ - filter_upwards [hU, hV] with a hu hv using add_le_add hu hv - +@[to_dual isBoundedUnder_ge_add] lemma isBoundedUnder_le_add [Add R] [AddLeftMono R] [AddRightMono R] {u v : α → R} (u_bdd_le : f.IsBoundedUnder (· ≤ ·) u) (v_bdd_le : f.IsBoundedUnder (· ≤ ·) v) : f.IsBoundedUnder (· ≤ ·) (u + v) := by @@ -360,34 +288,22 @@ lemma isBoundedUnder_le_add [Add R] [AddLeftMono R] [AddRightMono R] simp only [eventually_map, Pi.add_apply] at hU hV ⊢ filter_upwards [hU, hV] with a hu hv using add_le_add hu hv +@[to_dual isBoundedUnder_ge_sum] lemma isBoundedUnder_le_sum {κ : Type*} [AddCommMonoid R] [AddLeftMono R] [AddRightMono R] {u : κ → α → R} (s : Finset κ) : (∀ k ∈ s, f.IsBoundedUnder (· ≤ ·) (u k)) → f.IsBoundedUnder (· ≤ ·) (∑ k ∈ s, u k) := fun h ↦ isBoundedUnder_sum (fun _ _ ↦ isBoundedUnder_le_add) le_rfl s h -lemma isBoundedUnder_ge_sum {κ : Type*} [AddCommMonoid R] [AddLeftMono R] [AddRightMono R] - {u : κ → α → R} (s : Finset κ) : - (∀ k ∈ s, f.IsBoundedUnder (· ≥ ·) (u k)) → - f.IsBoundedUnder (· ≥ ·) (∑ k ∈ s, u k) := - fun h ↦ isBoundedUnder_sum (fun _ _ ↦ isBoundedUnder_ge_add) le_rfl s h - end add_and_sum section add_and_sum -variable {α : Type*} {R : Type*} [LinearOrder R] [Add R] {f : Filter α} [f.NeBot] +variable {α R : Type*} [LinearOrder R] [Add R] {f : Filter α} [f.NeBot] [AddLeftMono R] [AddRightMono R] {u v : α → R} -lemma isCoboundedUnder_ge_add (hu : f.IsBoundedUnder (· ≤ ·) u) - (hv : f.IsCoboundedUnder (· ≥ ·) v) : - f.IsCoboundedUnder (· ≥ ·) (u + v) := by - obtain ⟨U, hU⟩ := hu.eventually_le - obtain ⟨V, hV⟩ := hv.frequently_le - apply IsCoboundedUnder.of_frequently_le (a := U + V) - exact (hV.and_eventually hU).mono fun x hx ↦ add_le_add hx.2 hx.1 - -lemma isCoboundedUnder_le_add (hu : f.IsBoundedUnder (· ≥ ·) u) +@[to_dual isCoboundedUnder_ge_add] +lemma isCoboundedUnder_le_add (hu : f.IsBoundedUnder (fun x1 x2 ↦ x2 ≤ x1) u) (hv : f.IsCoboundedUnder (· ≤ ·) v) : f.IsCoboundedUnder (· ≤ ·) (u + v) := by obtain ⟨U, hU⟩ := hu.eventually_ge @@ -401,9 +317,9 @@ section mul lemma isBoundedUnder_le_mul_of_nonneg [Preorder α] [Mul α] [Zero α] [PosMulMono α] [MulPosMono α] {f : Filter ι} {u v : ι → α} (h₁ : ∃ᶠ x in f, 0 ≤ u x) - (h₂ : IsBoundedUnder (fun x1 x2 ↦ x1 ≤ x2) f u) (h₃ : 0 ≤ᶠ[f] v) - (h₄ : IsBoundedUnder (fun x1 x2 ↦ x1 ≤ x2) f v) : - IsBoundedUnder (fun x1 x2 ↦ x1 ≤ x2) f (u * v) := by + (h₂ : IsBoundedUnder (· ≤ ·) f u) (h₃ : 0 ≤ᶠ[f] v) + (h₄ : IsBoundedUnder (· ≤ ·) f v) : + IsBoundedUnder (· ≤ ·) f (u * v) := by obtain ⟨U, hU⟩ := h₂.eventually_le obtain ⟨V, hV⟩ := h₄.eventually_le refine isBoundedUnder_of_eventually_le (a := U * V) ?_ @@ -415,10 +331,10 @@ lemma isBoundedUnder_le_mul_of_nonneg [Preorder α] [Mul α] [Zero α] [PosMulMo lemma isCoboundedUnder_ge_mul_of_nonneg [LinearOrder α] [Mul α] [Zero α] [PosMulMono α] [MulPosMono α] {f : Filter ι} [f.NeBot] {u v : ι → α} (h₁ : 0 ≤ᶠ[f] u) - (h₂ : IsBoundedUnder (fun x1 x2 ↦ x1 ≤ x2) f u) + (h₂ : IsBoundedUnder (· ≤ ·) f u) (h₃ : 0 ≤ᶠ[f] v) - (h₄ : IsCoboundedUnder (fun x1 x2 ↦ x1 ≥ x2) f v) : - IsCoboundedUnder (fun x1 x2 ↦ x1 ≥ x2) f (u * v) := by + (h₄ : IsCoboundedUnder (fun x1 x2 ↦ x2 ≤ x1) f v) : + IsCoboundedUnder (fun x1 x2 ↦ x2 ≤ x1) f (u * v) := by obtain ⟨U, hU⟩ := h₂.eventually_le obtain ⟨V, hV⟩ := h₄.frequently_le refine IsCoboundedUnder.of_frequently_le (a := U * V) ?_ @@ -431,18 +347,15 @@ end mul section Nonempty variable [Preorder α] [Nonempty α] {f : Filter β} {u : β → α} +@[to_dual isBounded_ge_atTop] theorem isBounded_le_atBot : (atBot : Filter α).IsBounded (· ≤ ·) := ‹Nonempty α›.elim fun a => ⟨a, eventually_le_atBot _⟩ -theorem isBounded_ge_atTop : (atTop : Filter α).IsBounded (· ≥ ·) := - ‹Nonempty α›.elim fun a => ⟨a, eventually_ge_atTop _⟩ - +@[to_dual isBoundedUnder_ge_atTop] theorem Tendsto.isBoundedUnder_le_atBot (h : Tendsto u f atBot) : f.IsBoundedUnder (· ≤ ·) u := isBounded_le_atBot.mono h -theorem Tendsto.isBoundedUnder_ge_atTop (h : Tendsto u f atTop) : f.IsBoundedUnder (· ≥ ·) u := - isBounded_ge_atTop.mono h - +@[to_dual] theorem bddAbove_range_of_tendsto_atTop_atBot [IsDirectedOrder α] {u : ℕ → α} (hx : Tendsto u atTop atBot) : BddAbove (Set.range u) := hx.isBoundedUnder_le_atBot.bddAbove_range @@ -453,29 +366,21 @@ theorem bddBelow_range_of_tendsto_atTop_atTop [IsCodirectedOrder α] {u : ℕ end Nonempty +@[to_dual isCobounded_ge_of_top] theorem isCobounded_le_of_bot [LE α] [OrderBot α] {f : Filter α} : f.IsCobounded (· ≤ ·) := ⟨⊥, fun _ _ => bot_le⟩ -theorem isCobounded_ge_of_top [LE α] [OrderTop α] {f : Filter α} : f.IsCobounded (· ≥ ·) := - ⟨⊤, fun _ _ => le_top⟩ - +@[to_dual isBounded_ge_of_bot] theorem isBounded_le_of_top [LE α] [OrderTop α] {f : Filter α} : f.IsBounded (· ≤ ·) := ⟨⊤, Eventually.of_forall fun _ => le_top⟩ -theorem isBounded_ge_of_bot [LE α] [OrderBot α] {f : Filter α} : f.IsBounded (· ≥ ·) := - ⟨⊥, Eventually.of_forall fun _ => bot_le⟩ - -@[simp] +@[to_dual (attr := simp) isBoundedUnder_ge_comp] theorem _root_.OrderIso.isBoundedUnder_le_comp [LE α] [LE β] (e : α ≃o β) {l : Filter γ} {u : γ → α} : (IsBoundedUnder (· ≤ ·) l fun x => e (u x)) ↔ IsBoundedUnder (· ≤ ·) l u := (Function.Surjective.exists e.surjective).trans <| exists_congr fun a => by simp only [eventually_map, e.le_iff_le] -@[simp] -theorem _root_.OrderIso.isBoundedUnder_ge_comp [LE α] [LE β] (e : α ≃o β) {l : Filter γ} - {u : γ → α} : (IsBoundedUnder (· ≥ ·) l fun x => e (u x)) ↔ IsBoundedUnder (· ≥ ·) l u := - OrderIso.isBoundedUnder_le_comp e.dual - +-- TODO: use `to_dual` in combination with `to_additive` @[to_additive (attr := simp)] theorem isBoundedUnder_le_inv [CommGroup α] [Preorder α] [IsOrderedMonoid α] {l : Filter β} {u : β → α} : @@ -488,6 +393,7 @@ theorem isBoundedUnder_ge_inv [CommGroup α] [Preorder α] [IsOrderedMonoid α] (IsBoundedUnder (· ≥ ·) l fun x => (u x)⁻¹) ↔ IsBoundedUnder (· ≤ ·) l u := (OrderIso.inv α).isBoundedUnder_le_comp +@[to_dual] theorem IsBoundedUnder.sup [SemilatticeSup α] {f : Filter β} {u v : β → α} : f.IsBoundedUnder (· ≤ ·) u → f.IsBoundedUnder (· ≤ ·) v → f.IsBoundedUnder (· ≤ ·) fun a => u a ⊔ v a @@ -495,7 +401,7 @@ theorem IsBoundedUnder.sup [SemilatticeSup α] {f : Filter β} {u v : β → α} ⟨bu ⊔ bv, show ∀ᶠ x in f, u x ⊔ v x ≤ bu ⊔ bv by filter_upwards [hu, hv] with _ using sup_le_sup⟩ -@[simp] +@[to_dual (attr := simp) isBoundedUnder_ge_inf] theorem isBoundedUnder_le_sup [SemilatticeSup α] {f : Filter β} {u v : β → α} : (f.IsBoundedUnder (· ≤ ·) fun a => u a ⊔ v a) ↔ f.IsBoundedUnder (· ≤ ·) u ∧ f.IsBoundedUnder (· ≤ ·) v := @@ -504,21 +410,10 @@ theorem isBoundedUnder_le_sup [SemilatticeSup α] {f : Filter β} {u v : β → h.mono_le <| Eventually.of_forall fun _ => le_sup_right⟩, fun h => h.1.sup h.2⟩ -theorem IsBoundedUnder.inf [SemilatticeInf α] {f : Filter β} {u v : β → α} : - f.IsBoundedUnder (· ≥ ·) u → - f.IsBoundedUnder (· ≥ ·) v → f.IsBoundedUnder (· ≥ ·) fun a => u a ⊓ v a := - IsBoundedUnder.sup (α := αᵒᵈ) - -@[simp] -theorem isBoundedUnder_ge_inf [SemilatticeInf α] {f : Filter β} {u v : β → α} : - (f.IsBoundedUnder (· ≥ ·) fun a => u a ⊓ v a) ↔ - f.IsBoundedUnder (· ≥ ·) u ∧ f.IsBoundedUnder (· ≥ ·) v := - isBoundedUnder_le_sup (α := αᵒᵈ) - theorem isBoundedUnder_le_abs [AddCommGroup α] [LinearOrder α] [IsOrderedAddMonoid α] {f : Filter β} {u : β → α} : (f.IsBoundedUnder (· ≤ ·) fun a => |u a|) ↔ - f.IsBoundedUnder (· ≤ ·) u ∧ f.IsBoundedUnder (· ≥ ·) u := + f.IsBoundedUnder (· ≤ ·) u ∧ f.IsBoundedUnder (fun x1 x2 ↦ x2 ≤ x1) u := isBoundedUnder_le_sup.trans <| and_congr Iff.rfl isBoundedUnder_le_neg /-- Filters are automatically bounded or cobounded in complete lattices. To use the same statements @@ -539,6 +434,7 @@ open Filter section Order +@[to_dual isBoundedUnder_ge_comp_iff] theorem Monotone.isBoundedUnder_le_comp_iff [Nonempty β] [LinearOrder β] [Preorder γ] [NoMaxOrder γ] {g : β → γ} {f : α → β} {l : Filter α} (hg : Monotone g) (hg' : Tendsto g atTop atTop) : IsBoundedUnder (· ≤ ·) l (g ∘ f) ↔ IsBoundedUnder (· ≤ ·) l f := by @@ -547,21 +443,12 @@ theorem Monotone.isBoundedUnder_le_comp_iff [Nonempty β] [LinearOrder β] [Preo obtain ⟨b, hb⟩ : ∃ b, ∀ a ≥ b, c < g a := eventually_atTop.1 (hg'.eventually_gt_atTop c) exact ⟨b, hc.mono fun x hx => not_lt.1 fun h => (hb _ h.le).not_ge hx⟩ -theorem Monotone.isBoundedUnder_ge_comp_iff [Nonempty β] [LinearOrder β] [Preorder γ] [NoMinOrder γ] - {g : β → γ} {f : α → β} {l : Filter α} (hg : Monotone g) (hg' : Tendsto g atBot atBot) : - IsBoundedUnder (· ≥ ·) l (g ∘ f) ↔ IsBoundedUnder (· ≥ ·) l f := - hg.dual.isBoundedUnder_le_comp_iff hg' - +@[to_dual isBoundedUnder_ge_comp_iff] theorem Antitone.isBoundedUnder_le_comp_iff [Nonempty β] [LinearOrder β] [Preorder γ] [NoMaxOrder γ] {g : β → γ} {f : α → β} {l : Filter α} (hg : Antitone g) (hg' : Tendsto g atBot atTop) : - IsBoundedUnder (· ≤ ·) l (g ∘ f) ↔ IsBoundedUnder (· ≥ ·) l f := + IsBoundedUnder (· ≤ ·) l (g ∘ f) ↔ IsBoundedUnder (fun x1 x2 ↦ x2 ≤ x1) l f := hg.dual_right.isBoundedUnder_ge_comp_iff hg' -theorem Antitone.isBoundedUnder_ge_comp_iff [Nonempty β] [LinearOrder β] [Preorder γ] [NoMinOrder γ] - {g : β → γ} {f : α → β} {l : Filter α} (hg : Antitone g) (hg' : Tendsto g atTop atBot) : - IsBoundedUnder (· ≥ ·) l (g ∘ f) ↔ IsBoundedUnder (· ≤ ·) l f := - hg.dual_right.isBoundedUnder_le_comp_iff hg' - end Order section MinMax @@ -580,6 +467,7 @@ theorem isCoboundedUnder_le_max [LinearOrder β] {f : Filter α} {u v : α → open Finset +@[to_dual isBoundedUnder_ge_finset_inf'] theorem isBoundedUnder_le_finset_sup' [LinearOrder β] [Nonempty β] {f : Filter α} {F : ι → α → β} {s : Finset ι} (hs : s.Nonempty) (h : ∀ i ∈ s, f.IsBoundedUnder (· ≤ ·) (F i)) : f.IsBoundedUnder (· ≤ ·) (fun a ↦ sup' s hs (fun i ↦ F i a)) := by @@ -591,6 +479,7 @@ theorem isBoundedUnder_le_finset_sup' [LinearOrder β] [Nonempty β] {f : Filter simp only [sup'_le_iff] exact fun i i_s ↦ le_trans (h i i_s) (le_sup' m i_s) +@[to_dual isCoboundedUnder_ge_finset_inf'] theorem isCoboundedUnder_le_finset_sup' [LinearOrder β] {f : Filter α} {F : ι → α → β} {s : Finset ι} (hs : s.Nonempty) (h : ∃ i ∈ s, f.IsCoboundedUnder (· ≤ ·) (F i)) : f.IsCoboundedUnder (· ≤ ·) (fun a ↦ sup' s hs (fun i ↦ F i a)) := by @@ -602,6 +491,7 @@ theorem isCoboundedUnder_le_finset_sup' [LinearOrder β] {f : Filter α} {F : ι simp only [sup'_le_iff] at h ⊢ exact h i i_s +@[to_dual isBoundedUnder_ge_finset_inf] theorem isBoundedUnder_le_finset_sup [LinearOrder β] [OrderBot β] {f : Filter α} {F : ι → α → β} {s : Finset ι} (h : ∀ i ∈ s, f.IsBoundedUnder (· ≤ ·) (F i)) : f.IsBoundedUnder (· ≤ ·) (fun a ↦ sup s (fun i ↦ F i a)) := by @@ -611,27 +501,13 @@ theorem isBoundedUnder_le_finset_sup [LinearOrder β] [OrderBot β] {f : Filter rw [← eventually_all_finset s] at hm exact hm.mono fun _ h ↦ sup_mono_fun h -theorem isBoundedUnder_ge_finset_inf' [LinearOrder β] [Nonempty β] {f : Filter α} {F : ι → α → β} - {s : Finset ι} (hs : s.Nonempty) (h : ∀ i ∈ s, f.IsBoundedUnder (· ≥ ·) (F i)) : - f.IsBoundedUnder (· ≥ ·) (fun a ↦ inf' s hs (fun i ↦ F i a)) := - isBoundedUnder_le_finset_sup' (β := βᵒᵈ) hs h - -theorem isCoboundedUnder_ge_finset_inf' [LinearOrder β] {f : Filter α} {F : ι → α → β} - {s : Finset ι} (hs : s.Nonempty) (h : ∃ i ∈ s, f.IsCoboundedUnder (· ≥ ·) (F i)) : - f.IsCoboundedUnder (· ≥ ·) (fun a ↦ inf' s hs (fun i ↦ F i a)) := - isCoboundedUnder_le_finset_sup' (β := βᵒᵈ) hs h - -theorem isBoundedUnder_ge_finset_inf [LinearOrder β] [OrderTop β] {f : Filter α} {F : ι → α → β} - {s : Finset ι} (h : ∀ i ∈ s, f.IsBoundedUnder (· ≥ ·) (F i)) : - f.IsBoundedUnder (· ≥ ·) (fun a ↦ inf s (fun i ↦ F i a)) := - isBoundedUnder_le_finset_sup (β := βᵒᵈ) h - end MinMax section FrequentlyBounded variable {R S : Type*} {F : Filter R} [LinearOrder R] [LinearOrder S] +@[to_dual frequently_le_map_of_frequently_le] lemma Monotone.frequently_ge_map_of_frequently_ge {f : R → S} (f_incr : Monotone f) {l : R} (freq_ge : ∃ᶠ x in F, l ≤ x) : ∃ᶠ x' in F.map f, f l ≤ x' := by @@ -641,46 +517,24 @@ lemma Monotone.frequently_ge_map_of_frequently_ge {f : R → S} (f_incr : Monoto by_contra con exact lt_irrefl (f l) <| lt_of_le_of_lt (f_incr <| not_lt.mp con) hz -lemma Monotone.frequently_le_map_of_frequently_le {f : R → S} (f_incr : Monotone f) - {u : R} (freq_le : ∃ᶠ x in F, x ≤ u) : - ∃ᶠ y in F.map f, y ≤ f u := by - refine fun ev ↦ freq_le ?_ - simp only [not_le] at ev freq_le ⊢ - filter_upwards [ev] with z hz - by_contra con - apply lt_irrefl (f u) <| lt_of_lt_of_le hz <| f_incr (not_lt.mp con) - +@[to_dual frequently_ge_map_of_frequently_le] lemma Antitone.frequently_le_map_of_frequently_ge {f : R → S} (f_decr : Antitone f) {l : R} (frbdd : ∃ᶠ x in F, l ≤ x) : ∃ᶠ y in F.map f, y ≤ f l := Monotone.frequently_ge_map_of_frequently_ge (S := Sᵒᵈ) f_decr frbdd -lemma Antitone.frequently_ge_map_of_frequently_le {f : R → S} (f_decr : Antitone f) - {u : R} (frbdd : ∃ᶠ x in F, x ≤ u) : - ∃ᶠ y in F.map f, f u ≤ y := - Monotone.frequently_le_map_of_frequently_le (S := Sᵒᵈ) f_decr frbdd - +@[to_dual isCoboundedUnder_ge_of_isCobounded] lemma Monotone.isCoboundedUnder_le_of_isCobounded {f : R → S} (f_incr : Monotone f) [NeBot F] (cobdd : IsCobounded (· ≤ ·) F) : F.IsCoboundedUnder (· ≤ ·) f := by obtain ⟨l, hl⟩ := IsCobounded.frequently_ge cobdd exact IsCobounded.of_frequently_ge <| f_incr.frequently_ge_map_of_frequently_ge hl -set_option backward.isDefEq.respectTransparency false in -lemma Monotone.isCoboundedUnder_ge_of_isCobounded {f : R → S} (f_incr : Monotone f) - [NeBot F] (cobdd : IsCobounded (· ≥ ·) F) : - F.IsCoboundedUnder (· ≥ ·) f := - Monotone.isCoboundedUnder_le_of_isCobounded (R := Rᵒᵈ) (S := Sᵒᵈ) f_incr.dual cobdd - -set_option backward.isDefEq.respectTransparency false in +@[to_dual isCoboundedUnder_ge_of_isCobounded] lemma Antitone.isCoboundedUnder_le_of_isCobounded {f : R → S} (f_decr : Antitone f) - [NeBot F] (cobdd : IsCobounded (· ≥ ·) F) : - F.IsCoboundedUnder (· ≤ ·) f := - Monotone.isCoboundedUnder_le_of_isCobounded (R := Rᵒᵈ) f_decr.dual cobdd - -lemma Antitone.isCoboundedUnder_ge_of_isCobounded {f : R → S} (f_decr : Antitone f) - [NeBot F] (cobdd : IsCobounded (· ≤ ·) F) : - F.IsCoboundedUnder (· ≥ ·) f := - Monotone.isCoboundedUnder_le_of_isCobounded (S := Sᵒᵈ) f_decr cobdd + [NeBot F] (cobdd : IsCobounded (fun x1 x2 ↦ x2 ≤ x1) F) : + F.IsCoboundedUnder (· ≤ ·) f := by + obtain ⟨l, hl⟩ := IsCobounded.frequently_le cobdd + exact IsCobounded.of_frequently_ge <| f_decr.frequently_ge_map_of_frequently_le hl end FrequentlyBounded From 1f5dc56d5f67ec1d794189902c9b5edccae0c99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:21 +0000 Subject: [PATCH 1219/1300] feat(AlgebraicTopology/SimplicialSet): more API for `SSet.op` (#38664) --- .../SimplexCategory/Rev.lean | 20 +---- .../SimplicialObject/Op.lean | 17 ++-- .../SimplicialSet/KanComplex/MulStruct.lean | 85 +++++++++++++++++++ .../AlgebraicTopology/SimplicialSet/Op.lean | 22 +++-- .../SimplicialSet/StdSimplex.lean | 28 ++++++ 5 files changed, 136 insertions(+), 36 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean index 2504a8f2b88e73..424b29b062c674 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Rev.lean @@ -30,7 +30,7 @@ category of nonempty finite linearly ordered types, corresponds to the *covariant* functor which sends a type `α` to `αᵒᵈ`. This functor sends the object `⦋n⦌` to `⦋n⦌` and a map `f : ⦋n⦌ ⟶ ⦋m⦌` is sent to the monotone map `(i : Fin (n + 1)) ↦ (f i.rev).rev`. -/ -@[simps obj] +@[simps obj, simps -isSimp map, implicit_reducible] def rev : SimplexCategory ⥤ SimplexCategory where obj n := n map {n m} f := Hom.mk ⟨fun i ↦ (f i.rev).rev, fun i j hij ↦ by @@ -39,44 +39,32 @@ def rev : SimplexCategory ⥤ SimplexCategory where @[simp] lemma rev_map_apply {n m : SimplexCategory} (f : n ⟶ m) (i : Fin (n.len + 1)) : - (rev.map f).toOrderHom (a := n) (b := m) i = (f.toOrderHom i.rev).rev := by + (rev.map f).toOrderHom (a := n) (b := m) i = (f.toOrderHom i.rev).rev := rfl -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] lemma rev_map_δ {n : ℕ} (i : Fin (n + 2)) : rev.map (δ i) = δ i.rev := by ext j : 3 - rw [rev_map_apply] - dsimp [δ] - rw [Fin.succAbove_rev_right, Fin.rev_rev] + simp [δ, Fin.succAbove_rev_right, Fin.rev_rev, rev_map_apply] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] lemma rev_map_σ {n : ℕ} (i : Fin (n + 1)) : rev.map (σ i) = σ i.rev := by ext j : 3 - rw [rev_map_apply] - dsimp [σ] - rw [Fin.predAbove_rev_right, Fin.rev_rev] + simp [σ, Fin.predAbove_rev_right, Fin.rev_rev, rev_map_apply] -set_option backward.isDefEq.respectTransparency false in /-- The functor `SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory` is a covariant involution. -/ @[simps! hom_app inv_app] def revCompRevIso : rev ⋙ rev ≅ 𝟭 _ := NatIso.ofComponents (fun _ ↦ Iso.refl _) -set_option backward.isDefEq.respectTransparency false in @[simp] lemma rev_map_rev_map {n m : SimplexCategory} (f : n ⟶ m) : rev.map (rev.map f) = f := by aesop -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The functor `SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory` as an equivalence of category. -/ @[simps] diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean index 338e1a8be37c03..1ff36d221bb09f 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Op.lean @@ -29,7 +29,10 @@ variable {C : Type*} [Category.{v} C] /-- The covariant involution of the category of simplicial objects that is induced by the involution -`SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory`. -/ +`SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory`. +This functor is purposely not made `implicit_reducible` so as to avoid +confusion between `(opFunctor.obj X) _⦋n⦌` and `X _⦋n⦌`: use the +isomorphism `opObjIso`. -/ def opFunctor : SimplicialObject C ⥤ SimplicialObject C := (Functor.whiskeringLeft _ _ _).obj SimplexCategory.rev.op @@ -37,30 +40,26 @@ def opFunctor : SimplicialObject C ⥤ SimplicialObject C := def opObjIso {X : SimplicialObject C} {n : SimplexCategoryᵒᵖ} : (opFunctor.obj X).obj n ≅ X.obj n := Iso.refl _ -set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctor_map_app {X Y : SimplicialObject C} (f : X ⟶ Y) (n : SimplexCategoryᵒᵖ) : (opFunctor.map f).app n = opObjIso.hom ≫ f.app n ≫ opObjIso.inv := by simp [opFunctor, opObjIso] -set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctor_obj_map (X : SimplicialObject C) {n m : SimplexCategoryᵒᵖ} (f : n ⟶ m) : (opFunctor.obj X).map f = opObjIso.hom ≫ X.map (SimplexCategory.rev.map f.unop).op ≫ opObjIso.inv := by simp [opFunctor, opObjIso] -set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctor_obj_δ (X : SimplicialObject C) {n : ℕ} (i : Fin (n + 2)) : (opFunctor.obj X).δ i = opObjIso.hom ≫ X.δ i.rev ≫ opObjIso.inv := by - simp [SimplicialObject.δ] + simp [opObjIso, SimplicialObject.δ] -set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctor_obj_σ (X : SimplicialObject C) {n : ℕ} (i : Fin (n + 1)) : (opFunctor.obj X).σ i = opObjIso.hom ≫ X.σ i.rev ≫ opObjIso.inv := by - simp [SimplicialObject.σ] + simp [opObjIso, SimplicialObject.σ] /-- The functor `opFunctor : SimplicialObject C ⥤ SimplicialObject C` is a covariant involution. -/ @@ -70,15 +69,11 @@ def opFunctorCompOpFunctorIso : opFunctor (C := C) ⋙ opFunctor ≅ 𝟭 _ := ((Functor.opHom _ _).mapIso (SimplexCategory.revCompRevIso).symm.op) ≪≫ Functor.whiskeringLeftObjIdIso -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctorCompOpFunctorIso_hom_app_app (X : SimplicialObject C) (n : SimplexCategoryᵒᵖ) : (opFunctorCompOpFunctorIso.hom.app X).app n = opObjIso.hom ≫ opObjIso.hom := by simp [opFunctorCompOpFunctorIso, opObjIso, opFunctor] -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in @[simp] lemma opFunctorCompOpFunctorIso_inv_app_app (X : SimplicialObject C) (n : SimplexCategoryᵒᵖ) : (opFunctorCompOpFunctorIso.inv.app X).app n = opObjIso.inv ≫ opObjIso.inv := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/KanComplex/MulStruct.lean b/Mathlib/AlgebraicTopology/SimplicialSet/KanComplex/MulStruct.lean index 826aabe6467a4b..a684a9a9a2d554 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/KanComplex/MulStruct.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/KanComplex/MulStruct.lean @@ -53,6 +53,41 @@ lemma δ_map (f : X.PtSimplex (n + 1) x) (i : Fin (n + 2)) : stdSimplex.δ i ≫ f.map = const x := comp_map_eq_const _ _ +/-- The bijection between `n`-simplices of `X.op` and of `X` +that are constant on the boundary. -/ +@[simps] +def opEquiv : X.op.PtSimplex n (opObjEquiv.symm x) ≃ X.PtSimplex n x where + toFun f := + { map := yonedaEquiv.symm (opObjEquiv (yonedaEquiv f.map)) + comm := by + obtain _ | n := n + · ext + · refine boundary.hom_ext (fun i ↦ ?_) + simp [stdSimplex.δ_comp_yonedaEquiv_symm, + δ_opObjEquiv, ← stdSimplex.yonedaEquiv_δ_comp, + opObjEquiv_yonedaEquiv_const] } + invFun g := + { map := yonedaEquiv.symm (opObjEquiv.symm (yonedaEquiv g.map)) + comm := by + obtain _ | n := n + · ext + · refine boundary.hom_ext (fun i ↦ ?_) + simp [stdSimplex.δ_comp_yonedaEquiv_symm, op_δ, + ← stdSimplex.yonedaEquiv_δ_comp, + opObjEquiv_symm_yonedaEquiv_const] } + left_inv _ := by simp + right_inv _ := by simp + +/-- Given a `n`-simplex of `X` that is constant on the boundary, this +is the corresponding `n`-simplex of `X.op`. -/ +abbrev op (f : X.PtSimplex n x) : X.op.PtSimplex n (opObjEquiv.symm x) := + opEquiv.symm f + +/-- Given a `n`-simplex of `X.op` that is constant on the boundary, this +is the corresponding `n`-simplex of `X`. -/ +abbrev unop (f : X.op.PtSimplex n (opObjEquiv.symm x)) : X.PtSimplex n x := + opEquiv f + /-- For each `i : Fin (n + 1)`, this is a variant of the homotopy relation on `n`-simplices that are constant on the boundary. Simplices `f` and `g` are related if they appear respectively as the `i.castSucc` and `i.succ` faces of a @@ -134,6 +169,56 @@ namespace MulStruct attribute [reassoc (attr := simp)] δ_castSucc_castSucc_map δ_succ_castSucc_map δ_succ_succ_map δ_map_of_lt δ_map_of_gt +/-- The `MulStruct` for `X.op` that is deduced from a `MulStruct` for the simplicial +set `X`. -/ +@[simps] +def op {f g fg : X.PtSimplex n x} {i : Fin n} (h : MulStruct f g fg i) {j : Fin n} + (hij : i.rev = j := by grind) : + MulStruct g.op f.op fg.op j where + map := yonedaEquiv.symm (opObjEquiv.symm (yonedaEquiv h.map)) + δ_castSucc_castSucc_map := by + rw [stdSimplex.δ_comp_yonedaEquiv_symm, op_δ, Equiv.apply_symm_apply, + ← stdSimplex.yonedaEquiv_δ_comp, opEquiv_symm_apply_map, ← h.δ_succ_succ_map, + Fin.rev_castSucc, Fin.rev_castSucc, ← hij, Fin.rev_rev] + δ_succ_castSucc_map := by + rw [stdSimplex.δ_comp_yonedaEquiv_symm, op_δ, Equiv.apply_symm_apply, + ← stdSimplex.yonedaEquiv_δ_comp, opEquiv_symm_apply_map, ← h.δ_succ_castSucc_map, + Fin.rev_succ, Fin.rev_castSucc, Fin.castSucc_succ, ← hij, Fin.rev_rev] + δ_succ_succ_map := by + rw [stdSimplex.δ_comp_yonedaEquiv_symm, op_δ, Equiv.apply_symm_apply, + ← stdSimplex.yonedaEquiv_δ_comp, opEquiv_symm_apply_map, ← h.δ_castSucc_castSucc_map, + Fin.rev_succ, Fin.rev_succ, ← hij, Fin.rev_rev] + δ_map_of_lt k hk := by + simp [stdSimplex.δ_comp_yonedaEquiv_symm, ← stdSimplex.yonedaEquiv_δ_comp, + opObjEquiv_symm_yonedaEquiv_const, h.δ_map_of_gt k.rev (by grind)] + δ_map_of_gt k hk := by + simp [stdSimplex.δ_comp_yonedaEquiv_symm, ← stdSimplex.yonedaEquiv_δ_comp, + opObjEquiv_symm_yonedaEquiv_const, h.δ_map_of_lt k.rev (by grind)] + +/-- The `Mulstruct` for a simplicial set `X` that is deduced from a `Mulstruct` for `X.op`. -/ +@[simps] +def unop {f g fg : X.PtSimplex n x} {i : Fin n} (h : MulStruct g.op f.op fg.op i) {j : Fin n} + (hij : i.rev = j := by grind) : + MulStruct f g fg j where + map := yonedaEquiv.symm (opObjEquiv (yonedaEquiv h.map)) + δ_castSucc_castSucc_map := by + simp [stdSimplex.δ_comp_yonedaEquiv_symm, δ_opObjEquiv, + ← stdSimplex.yonedaEquiv_δ_comp, ← hij, Fin.rev_castSucc] + δ_succ_castSucc_map := by + simp [stdSimplex.δ_comp_yonedaEquiv_symm, δ_opObjEquiv, + ← stdSimplex.yonedaEquiv_δ_comp, ← hij, Fin.rev_castSucc, Fin.rev_succ] + δ_succ_succ_map := by + simp [stdSimplex.δ_comp_yonedaEquiv_symm, δ_opObjEquiv, + ← stdSimplex.yonedaEquiv_δ_comp, ← hij, Fin.rev_succ] + δ_map_of_lt k hk := by + rw [stdSimplex.δ_comp_yonedaEquiv_symm, δ_opObjEquiv, + ← stdSimplex.yonedaEquiv_δ_comp, h.δ_map_of_gt _ (by grind)] + simp [opObjEquiv_yonedaEquiv_const] + δ_map_of_gt k hk := by + rw [stdSimplex.δ_comp_yonedaEquiv_symm, δ_opObjEquiv, + ← stdSimplex.yonedaEquiv_δ_comp, h.δ_map_of_lt _ (by grind)] + simp [opObjEquiv_yonedaEquiv_const] + end MulStruct /-- If `f` and `g` are in `X.PtSimplex n x`, then `RelStruct f g i.castSucc` diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Op.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Op.lean index c470f8e3566c1f..aacc21016dacc1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Op.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Op.lean @@ -36,7 +36,9 @@ open CategoryTheory Simplicial namespace SSet /-- The covariant involution of the category of simplicial sets that -is induced by `SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory`. -/ +is induced by `SimplexCategory.rev : SimplexCategory ⥤ SimplexCategory`. +This functor is purposely not made `implicit_reducible` so as to avoid +confusion between `X.op _⦋n⦌` and `X _⦋n⦌`: use the bijection `opObjEquiv`. -/ def opFunctor : SSet.{u} ⥤ SSet.{u} := SimplicialObject.opFunctor /-- The image of a simplicial set by the involution `opFunctor : SSet ⥤ SSet`. -/ @@ -55,22 +57,24 @@ lemma op_map (X : SSet.{u}) {n m : SimplexCategoryᵒᵖ} (f : n ⟶ m) (x : X.o opObjEquiv.symm (X.map (SimplexCategory.rev.map f.unop).op (opObjEquiv x)) := rfl -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] -lemma op_δ (X : SSet.{u}) {n : ℕ} (i : Fin (n + 2)) (x : X _⦋n + 1⦌) : +lemma op_δ (X : SSet.{u}) {n : ℕ} (i : Fin (n + 2)) (x : X.op _⦋n + 1⦌) : X.op.δ i x = opObjEquiv.symm (X.δ i.rev (opObjEquiv x)) := by simp [SimplicialObject.δ, op_map] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in @[simp] -lemma op_σ (X : SSet.{u}) {n : ℕ} (i : Fin (n + 1)) (x : X _⦋n⦌) : +lemma op_σ (X : SSet.{u}) {n : ℕ} (i : Fin (n + 1)) (x : X.op _⦋n⦌) : X.op.σ i x = opObjEquiv.symm (X.σ i.rev (opObjEquiv x)) := by simp [SimplicialObject.σ, op_map] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in +lemma δ_opObjEquiv (X : SSet.{u}) {n : ℕ} (i : Fin (n + 2)) (x : X.op _⦋n + 1⦌) : + X.δ i (opObjEquiv x) = opObjEquiv (X.op.δ i.rev x) := by + simp + +lemma σ_opObjEquiv (X : SSet.{u}) {n : ℕ} (i : Fin (n + 1)) (x : X.op _⦋n⦌) : + X.σ i (opObjEquiv x) = opObjEquiv (X.op.σ i.rev x) := by + simp + attribute [local simp] op_map in /-- The functor `opFunctor : SSet ⥤ SSet` is an involution. -/ @[simps!] diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 17c4d7197502ca..8e8cc0ccb732ac 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -203,6 +203,14 @@ lemma yonedaEquiv_symm_app_objEquiv_symm {X : SSet.{u}} {n : SimplexCategory} X.map f.op x := rfl +lemma opObjEquiv_yonedaEquiv_const {X : SSet.{u}} {n : SimplexCategory} (x : X.op _⦋0⦌) : + opObjEquiv (n := op n) (yonedaEquiv (const x)) = + yonedaEquiv (const (opObjEquiv x)) := rfl + +lemma opObjEquiv_symm_yonedaEquiv_const {X : SSet.{u}} {n : SimplexCategory} (x : X _⦋0⦌) : + (opObjEquiv (n := op n)).symm (yonedaEquiv (const x)) = + yonedaEquiv (const (opObjEquiv.symm x)) := rfl + namespace stdSimplex lemma δ_apply {n d : ℕ} (x : (Δ[n] _⦋d + 1⦌ : Type u)) (i : Fin (d + 2)) (j : Fin (d + 1)) : @@ -321,6 +329,26 @@ lemma yonedaEquiv_symm_naturality_left {X : SSet} {m n : SimplexCategory} stdSimplex.map f ≫ yonedaEquiv.symm g = yonedaEquiv.symm (X.map f.op g) := by rw [yonedaEquiv.eq_symm_apply, ← yonedaEquiv_naturality, yonedaEquiv.apply_symm_apply] +lemma stdSimplex.δ_comp_yonedaEquiv_symm + {X : SSet.{u}} {n : ℕ} (x : X _⦋n + 1⦌) (i : Fin (n + 2)) : + stdSimplex.δ i ≫ yonedaEquiv.symm x = yonedaEquiv.symm (X.δ i x) := + yonedaEquiv_symm_naturality_left .. + +lemma stdSimplex.σ_comp_yonedaEquiv_symm + {X : SSet.{u}} {n : ℕ} (x : X _⦋n⦌) (i : Fin (n + 1)) : + stdSimplex.σ i ≫ yonedaEquiv.symm x = yonedaEquiv.symm (X.σ i x) := + yonedaEquiv_symm_naturality_left .. + +lemma stdSimplex.yonedaEquiv_δ_comp + {X : SSet.{u}} {n : ℕ} (g : Δ[n + 1] ⟶ X) (i : Fin (n + 2)) : + yonedaEquiv (stdSimplex.δ i ≫ g) = X.δ i (yonedaEquiv g) := + (yonedaEquiv_naturality ..).symm + +lemma stdSimplex.yonedaEquiv_σ_comp + {X : SSet.{u}} {n : ℕ} (g : Δ[n] ⟶ X) (i : Fin (n + 1)) : + yonedaEquiv (stdSimplex.σ i ≫ g) = X.σ i (yonedaEquiv g) := + (yonedaEquiv_naturality ..).symm + namespace Subcomplex variable {X : SSet.{u}} From d390e9b73ccc924893467342a62b37ff545bd162 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:23 +0000 Subject: [PATCH 1220/1300] chore(Order/Bounds/Basic): add missing `to_dual` tags (#40040) This PR adds some `to_dual` tags that weren't added in #35208 --- Mathlib/Order/Bounds/Basic.lean | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index 260314ac9038b1..d1d39f236d70ce 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -714,34 +714,24 @@ section Minimal variable [Preorder α] {s : Set α} {a b : α} +@[to_dual] theorem DirectedOn.le_of_minimal (h : DirectedOn (fun x y ↦ y ≤ x) s) (hMin : Minimal (· ∈ s) a) (hb : b ∈ s) : a ≤ b := by obtain ⟨z, hz, hza, hzb⟩ := h a hMin.1 b hb exact (hMin.2 hz hza).trans hzb -theorem DirectedOn.le_of_maximal (h : DirectedOn (· ≤ ·) s) (hMax : Maximal (· ∈ s) a) - (hb : b ∈ s) : b ≤ a := by - obtain ⟨z, hz, haz, hbz⟩ := h a hMax.1 b hb - exact hbz.trans (hMax.2 hz haz) - +@[to_dual] theorem DirectedOn.minimal_iff_isLeast (h : DirectedOn (fun x y ↦ y ≤ x) s) : Minimal (· ∈ s) a ↔ IsLeast s a := ⟨fun hMin ↦ ⟨hMin.1, fun _ hy ↦ h.le_of_minimal hMin hy⟩, fun h ↦ ⟨h.1, fun _ hy _ ↦ h.2 hy⟩⟩ -theorem DirectedOn.maximal_iff_isGreatest (h : DirectedOn (· ≤ ·) s) : - Maximal (· ∈ s) a ↔ IsGreatest s a := - minimal_iff_isLeast (α := αᵒᵈ) h - end Minimal +@[to_dual] theorem minimal_iff_isLeast [LinearOrder α] {s : Set α} {a : α} : Minimal (· ∈ s) a ↔ IsLeast s a := (Std.Total.directedOn s).minimal_iff_isLeast -theorem maximal_iff_isGreatest [LinearOrder α] {s : Set α} {a : α} : - Maximal (· ∈ s) a ↔ IsGreatest s a := - (Std.Total.directedOn s).maximal_iff_isGreatest - /-! ### (In)equalities with the least upper bound and the greatest lower bound -/ @@ -751,18 +741,22 @@ section Preorder variable [Preorder α] [Preorder β] {s s' : Set α} {t : Set β} {a b : α} +@[to_dual self (reorder := a b, ha hb)] theorem lowerBounds_le_upperBounds (ha : a ∈ lowerBounds s) (hb : b ∈ upperBounds s) : s.Nonempty → a ≤ b | ⟨_, hc⟩ => le_trans (ha hc) (hb hc) +@[to_dual none] theorem lowerBounds_le_upperBounds_of_nonempty_inter (h : (s ∩ s').Nonempty) (ha : a ∈ lowerBounds s) (hb : b ∈ upperBounds s') : a ≤ b := by have ⟨x, hx, hx'⟩ := h exact le_trans (ha hx) (hb hx') +@[to_dual self (reorder := a b, ha hb)] theorem isGLB_le_isLUB (ha : IsGLB s a) (hb : IsLUB s b) (hs : s.Nonempty) : a ≤ b := lowerBounds_le_upperBounds ha.1 hb.1 hs +@[to_dual none] theorem isGLB_le_isLUB_of_nonempty_inter (h : (s ∩ s').Nonempty) (ha : IsGLB s a) (hb : IsLUB s' b) : a ≤ b := lowerBounds_le_upperBounds_of_nonempty_inter h ha.left hb.left @@ -771,6 +765,7 @@ theorem isGLB_le_isLUB_of_nonempty_inter (h : (s ∩ s').Nonempty) (ha : IsGLB s theorem isLUB_lt_iff (ha : IsLUB s a) : a < b ↔ ∃ c ∈ upperBounds s, c < b := ⟨fun hb => ⟨a, ha.1, hb⟩, fun ⟨_, hcs, hcb⟩ => lt_of_le_of_lt (ha.2 hcs) hcb⟩ +@[to_dual self (reorder := a b, x y, ha hb, hx hy)] theorem le_of_isLUB_le_isGLB {x y} (ha : IsGLB s a) (hb : IsLUB s b) (hab : b ≤ a) (hx : x ∈ s) (hy : y ∈ s) : x ≤ y := calc @@ -778,7 +773,8 @@ theorem le_of_isLUB_le_isGLB {x y} (ha : IsGLB s a) (hb : IsLUB s b) (hab : b _ ≤ a := hab _ ≤ y := ha.1 hy -@[to_dual (attr := simp)] lemma upperBounds_prod (hs : s.Nonempty) (ht : t.Nonempty) : +@[to_dual (attr := simp)] +lemma upperBounds_prod (hs : s.Nonempty) (ht : t.Nonempty) : upperBounds (s ×ˢ t) = upperBounds s ×ˢ upperBounds t := by ext; rw [← nonempty_coe_sort] at hs ht; aesop (add simp [upperBounds, Prod.le_def, forall_and]) @@ -813,10 +809,12 @@ theorem IsLeast.isLeast_iff_eq (Ha : IsLeast s a) : IsLeast s b ↔ a = b := theorem IsLUB.unique (Ha : IsLUB s a) (Hb : IsLUB s b) : a = b := IsLeast.unique Ha Hb +@[to_dual self (reorder := a b, Ha Hb)] theorem Set.subsingleton_of_isLUB_le_isGLB (Ha : IsGLB s a) (Hb : IsLUB s b) (hab : b ≤ a) : s.Subsingleton := fun _ hx _ hy => le_antisymm (le_of_isLUB_le_isGLB Ha Hb hab hx hy) (le_of_isLUB_le_isGLB Ha Hb hab hy hx) +@[to_dual self (reorder := a b, Ha Hb)] theorem isGLB_lt_isLUB_of_ne (Ha : IsGLB s a) (Hb : IsLUB s b) {x y} (Hx : x ∈ s) (Hy : y ∈ s) (Hxy : x ≠ y) : a < b := lt_iff_le_not_ge.2 From 06db9b26510b2f2c29e30ecd7bb61db5acba81df Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:25 +0000 Subject: [PATCH 1221/1300] chore(CategoryTheory/Functor/EpiMono): use `to_dual` (#41015) This PR uses `to_dual` to translate some declarations about `Epimorphisms` and `Monomorphisms`. Various prerequisites have also been tagged in this PR. The namespace of some lemmas has been fixed that should have been capitalized. A few lemmas about `Epimorphisms` didn't have a corresponding `Monomorphisms` version, so they have been added in this PR. --- Mathlib/CategoryTheory/Adjunction/Basic.lean | 73 +++--- Mathlib/CategoryTheory/EpiMono.lean | 3 + Mathlib/CategoryTheory/Functor/EpiMono.lean | 212 +++++++----------- .../CategoryTheory/Functor/FullyFaithful.lean | 7 +- .../LiftingProperties/Adjunction.lean | 62 ++--- .../Preadditive/Injective/Basic.lean | 2 +- .../Preadditive/Projective/Internal.lean | 2 +- Mathlib/Tactic/Translate/ToDual.lean | 2 + 8 files changed, 138 insertions(+), 225 deletions(-) diff --git a/Mathlib/CategoryTheory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Adjunction/Basic.lean index fb5b3de90ebebe..e0f1b3c88ac75d 100644 --- a/Mathlib/CategoryTheory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Adjunction/Basic.lean @@ -157,7 +157,6 @@ namespace Adjunction attribute [reassoc (attr := simp)] left_triangle_components right_triangle_components /-- The hom set equivalence associated to an adjunction. -/ -@[to_dual none, simps (attr := to_dual none) -isSimp] def homEquiv {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) (X : C) (Y : D) : (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y) where toFun := fun f => adj.unit.app X ≫ G.map f @@ -171,6 +170,14 @@ def homEquiv {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) (X : C) (Y : D) : rw [← assoc, ← Functor.comp_map, ← adj.unit.naturality] simp +/-- `homEquiv'` is the dual of `homEquiv`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing homEquiv] +abbrev homEquiv' {F : C ⥤ D} {G : D ⥤ C} (adj : G ⊣ F) (X : C) (Y : D) : + (Y ⟶ F.obj X) ≃ (G.obj Y ⟶ X) := (homEquiv adj Y X).symm + +attribute [simps (attr := to_dual none) -isSimp] homEquiv + @[to_dual none] alias homEquiv_unit := homEquiv_apply @[to_dual none] alias homEquiv_counit := homEquiv_symm_apply @@ -474,7 +481,8 @@ instance : Inhabited (Adjunction (𝟭 C) (𝟭 C)) := ⟨id⟩ /-- If F and G are naturally isomorphic functors, establish an equivalence of hom-sets. -/ -@[simps] +@[to_dual (attr := simps) +/-- If G and H are naturally isomorphic functors, establish an equivalence of hom-sets. -/] def equivHomsetLeftOfNatIso {F F' : C ⥤ D} (iso : F ≅ F') {X : C} {Y : D} : (F.obj X ⟶ Y) ≃ (F'.obj X ⟶ Y) where toFun f := iso.inv.app _ ≫ f @@ -482,17 +490,10 @@ def equivHomsetLeftOfNatIso {F F' : C ⥤ D} (iso : F ≅ F') {X : C} {Y : D} : left_inv f := by simp right_inv g := by simp -/-- If G and H are naturally isomorphic functors, establish an equivalence of hom-sets. -/ -@[simps] -def equivHomsetRightOfNatIso {G G' : D ⥤ C} (iso : G ≅ G') {X : C} {Y : D} : - (X ⟶ G.obj Y) ≃ (X ⟶ G'.obj Y) where - toFun f := f ≫ iso.hom.app _ - invFun g := g ≫ iso.inv.app _ - left_inv f := by simp - right_inv g := by simp - +set_option linter.translate.warnInvalid false in /-- Transport an adjunction along a natural isomorphism on the left. -/ -@[simps] +@[to_dual (attr := simps) +/-- Transport an adjunction along a natural isomorphism on the right. -/] def ofNatIsoLeft {F G : C ⥤ D} {H : D ⥤ C} (adj : F ⊣ H) (iso : F ≅ G) : G ⊣ H where unit := adj.unit ≫ Functor.whiskerRight iso.hom _ counit := Functor.whiskerLeft _ iso.inv ≫ adj.counit @@ -502,33 +503,27 @@ def ofNatIsoLeft {F G : C ⥤ D} {H : D ⥤ C} (adj : F ⊣ H) (iso : F ≅ G) : simp [← Functor.comp_map] right_triangle_components := by simp [← Functor.map_comp] +attribute [to_dual existing] ofNatIsoLeft_unit ofNatIsoLeft_counit + +@[to_dual none] lemma homEquiv_ofNatIsoLeft_apply {F G : C ⥤ D} {H : D ⥤ C} (adj : F ⊣ H) (iso : F ≅ G) {X : C} {Y : D} (f : G.obj X ⟶ Y) : (ofNatIsoLeft adj iso).homEquiv X Y f = adj.homEquiv _ _ (iso.hom.app _ ≫ f) := by simp +@[to_dual none] lemma homEquiv_ofNatIsoLeft_symm_apply {F G : C ⥤ D} {H : D ⥤ C} (adj : F ⊣ H) (iso : F ≅ G) {X : C} {Y : D} (f : X ⟶ H.obj Y) : ((ofNatIsoLeft adj iso).homEquiv X Y).symm f = iso.inv.app _ ≫ (adj.homEquiv _ _).symm f := by simp -/-- Transport an adjunction along a natural isomorphism on the right. -/ -@[simps] -def ofNatIsoRight {F : C ⥤ D} {G H : D ⥤ C} (adj : F ⊣ G) (iso : G ≅ H) : F ⊣ H where - unit := adj.unit ≫ Functor.whiskerLeft _ iso.hom - counit := Functor.whiskerRight iso.inv _ ≫ adj.counit - left_triangle_components X := by simp [← Functor.map_comp_assoc] - right_triangle_components Y := by - simp only [id_obj, comp_obj, NatTrans.comp_app, whiskerLeft_app, whiskerRight_app, map_comp, - assoc, ← iso.hom.naturality_assoc, ← iso.hom.naturality, unit_naturality_assoc, - adj.right_triangle_components_assoc] - simp - +@[to_dual none] lemma homEquiv_ofNatIsoRight_apply {F : C ⥤ D} {G H : D ⥤ C} (adj : F ⊣ G) (iso : G ≅ H) {X : C} {Y : D} (f : F.obj X ⟶ Y) : (ofNatIsoRight adj iso).homEquiv X Y f = adj.homEquiv _ _ f ≫ iso.hom.app _ := by simp +@[to_dual none] lemma homEquiv_ofNatIsoRight_symm_apply {F : C ⥤ D} {G H : D ⥤ C} (adj : F ⊣ G) (iso : G ≅ H) {X : C} {Y : D} (f : X ⟶ H.obj Y) : ((ofNatIsoRight adj iso).homEquiv X Y).symm f = @@ -721,23 +716,26 @@ variable (e : C ≌ D) /-- The adjunction given by an equivalence of categories. (To obtain the opposite adjunction, simply use `e.symm.toAdjunction`.) -/ -@[simps] def toAdjunction : e.functor ⊣ e.inverse where unit := e.unit counit := e.counit +/-- `toAdjunction'` is the dual of `ToAdjunction`, which we need for `to_dual`. +Please avoid using this directly. -/ +@[to_dual existing toAdjunction] +abbrev toAdjunction' : e.inverse ⊣ e.functor := e.symm.toAdjunction + +attribute [simps (attr := to_dual none)] toAdjunction + +@[to_dual] lemma isLeftAdjoint_functor : e.functor.IsLeftAdjoint where exists_rightAdjoint := ⟨_, ⟨e.toAdjunction⟩⟩ +@[to_dual] lemma isRightAdjoint_inverse : e.inverse.IsRightAdjoint where exists_leftAdjoint := ⟨_, ⟨e.toAdjunction⟩⟩ -lemma isLeftAdjoint_inverse : e.inverse.IsLeftAdjoint := - e.symm.isLeftAdjoint_functor - -lemma isRightAdjoint_functor : e.functor.IsRightAdjoint := - e.symm.isRightAdjoint_inverse - +@[to_dual none] lemma refl_toAdjunction : (refl (C := C)).toAdjunction = Adjunction.id := rfl lemma trans_toAdjunction {E : Type*} [Category* E] (e' : D ≌ E) : @@ -760,30 +758,21 @@ instance isRightAdjoint_comp {E : Type u₃} [Category.{v₃} E] {F : C ⥤ D} { ⟨_, ⟨(Adjunction.ofIsRightAdjoint G).comp (Adjunction.ofIsRightAdjoint F)⟩⟩ /-- Transport being a right adjoint along a natural isomorphism. -/ +@[to_dual /-- Transport being a left adjoint along a natural isomorphism. -/] lemma isRightAdjoint_of_iso {F G : C ⥤ D} (h : F ≅ G) [F.IsRightAdjoint] : IsRightAdjoint G where exists_leftAdjoint := ⟨_, ⟨(Adjunction.ofIsRightAdjoint F).ofNatIsoRight h⟩⟩ -/-- Transport being a left adjoint along a natural isomorphism. -/ -lemma isLeftAdjoint_of_iso {F G : C ⥤ D} (h : F ≅ G) [IsLeftAdjoint F] : - IsLeftAdjoint G where - exists_rightAdjoint := ⟨_, ⟨(Adjunction.ofIsLeftAdjoint F).ofNatIsoLeft h⟩⟩ - - /-- An equivalence `E` is left adjoint to its inverse. -/ noncomputable def adjunction (E : C ⥤ D) [IsEquivalence E] : E ⊣ E.inv := E.asEquivalence.toAdjunction /-- If `F` is an equivalence, it's a left adjoint. -/ +@[to_dual /-- If `F` is an equivalence, it's a right adjoint. -/] instance (priority := 10) isLeftAdjoint_of_isEquivalence {F : C ⥤ D} [F.IsEquivalence] : IsLeftAdjoint F := F.asEquivalence.isLeftAdjoint_functor -/-- If `F` is an equivalence, it's a right adjoint. -/ -instance (priority := 10) isRightAdjoint_of_isEquivalence {F : C ⥤ D} [F.IsEquivalence] : - IsRightAdjoint F := - F.asEquivalence.isRightAdjoint_functor - lemma isLeftAdjoint_comp_iff_right {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) (G : D ⥤ E) [F.IsEquivalence] : (F ⋙ G).IsLeftAdjoint ↔ G.IsLeftAdjoint := by diff --git a/Mathlib/CategoryTheory/EpiMono.lean b/Mathlib/CategoryTheory/EpiMono.lean index 5679b8476d9fc7..73bfb8686a5da9 100644 --- a/Mathlib/CategoryTheory/EpiMono.lean +++ b/Mathlib/CategoryTheory/EpiMono.lean @@ -71,6 +71,9 @@ structure SplitEpi {X Y : C} (f : X ⟶ Y) where /-- `section_` composed with `f` is the identity -/ id : section_ ≫ f = 𝟙 Y := by cat_disch +-- TODO: `to_dual` should add these automatically: +attribute [to_dual existing] SplitEpi.ext SplitEpi.ext_iff + /-- `IsSplitEpi f` is the assertion that `f` admits a section -/ @[to_dual] class IsSplitEpi {X Y : C} (f : X ⟶ Y) : Prop where diff --git a/Mathlib/CategoryTheory/Functor/EpiMono.lean b/Mathlib/CategoryTheory/Functor/EpiMono.lean index 7908da42e8d1bc..312b756e190313 100644 --- a/Mathlib/CategoryTheory/Functor/EpiMono.lean +++ b/Mathlib/CategoryTheory/Functor/EpiMono.lean @@ -27,20 +27,20 @@ namespace CategoryTheory.Functor variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] {E : Type u₃} [Category.{v₃} E] +to_dual_name_hint Left Right + /-- A functor preserves monomorphisms if it maps monomorphisms to monomorphisms. -/ class PreservesMonomorphisms (F : C ⥤ D) : Prop where /-- A functor preserves monomorphisms if it maps monomorphisms to monomorphisms. -/ preserves : ∀ {X Y : C} (f : X ⟶ Y) [Mono f], Mono (F.map f) -instance map_mono (F : C ⥤ D) [PreservesMonomorphisms F] {X Y : C} (f : X ⟶ Y) [Mono f] : - Mono (F.map f) := - PreservesMonomorphisms.preserves f - /-- A functor preserves epimorphisms if it maps epimorphisms to epimorphisms. -/ +@[to_dual] class PreservesEpimorphisms (F : C ⥤ D) : Prop where /-- A functor preserves epimorphisms if it maps epimorphisms to epimorphisms. -/ preserves : ∀ {X Y : C} (f : X ⟶ Y) [Epi f], Epi (F.map f) +@[to_dual] instance map_epi (F : C ⥤ D) [PreservesEpimorphisms F] {X Y : C} (f : X ⟶ Y) [Epi f] : Epi (F.map f) := PreservesEpimorphisms.preserves f @@ -52,58 +52,43 @@ class ReflectsMonomorphisms (F : C ⥤ D) : Prop where monomorphisms. -/ reflects : ∀ {X Y : C} (f : X ⟶ Y), Mono (F.map f) → Mono f -theorem mono_of_mono_map (F : C ⥤ D) [ReflectsMonomorphisms F] {X Y : C} {f : X ⟶ Y} - (h : Mono (F.map f)) : Mono f := - ReflectsMonomorphisms.reflects f h - /-- A functor reflects epimorphisms if morphisms that are mapped to epimorphisms are themselves epimorphisms. -/ +@[to_dual] class ReflectsEpimorphisms (F : C ⥤ D) : Prop where /-- A functor reflects epimorphisms if morphisms that are mapped to epimorphisms are themselves epimorphisms. -/ reflects : ∀ {X Y : C} (f : X ⟶ Y), Epi (F.map f) → Epi f +@[to_dual] theorem epi_of_epi_map (F : C ⥤ D) [ReflectsEpimorphisms F] {X Y : C} {f : X ⟶ Y} (h : Epi (F.map f)) : Epi f := ReflectsEpimorphisms.reflects f h +@[to_dual] instance preservesMonomorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesMonomorphisms F] [PreservesMonomorphisms G] : PreservesMonomorphisms (F ⋙ G) where preserves f h := by rw [comp_map] exact inferInstance -instance preservesEpimorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesEpimorphisms F] - [PreservesEpimorphisms G] : PreservesEpimorphisms (F ⋙ G) where - preserves f h := by - rw [comp_map] - exact inferInstance - +@[to_dual] instance reflectsMonomorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [ReflectsMonomorphisms F] [ReflectsMonomorphisms G] : ReflectsMonomorphisms (F ⋙ G) where reflects _ h := F.mono_of_mono_map (G.mono_of_mono_map h) -instance reflectsEpimorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [ReflectsEpimorphisms F] - [ReflectsEpimorphisms G] : ReflectsEpimorphisms (F ⋙ G) where - reflects _ h := F.epi_of_epi_map (G.epi_of_epi_map h) - +@[to_dual] theorem preservesEpimorphisms_of_preserves_of_reflects (F : C ⥤ D) (G : D ⥤ E) [PreservesEpimorphisms (F ⋙ G)] [ReflectsEpimorphisms G] : PreservesEpimorphisms F := ⟨fun f _ => G.epi_of_epi_map <| show Epi ((F ⋙ G).map f) from inferInstance⟩ -theorem preservesMonomorphisms_of_preserves_of_reflects (F : C ⥤ D) (G : D ⥤ E) - [PreservesMonomorphisms (F ⋙ G)] [ReflectsMonomorphisms G] : PreservesMonomorphisms F := - ⟨fun f _ => G.mono_of_mono_map <| show Mono ((F ⋙ G).map f) from inferInstance⟩ - +@[to_dual] theorem reflectsEpimorphisms_of_preserves_of_reflects (F : C ⥤ D) (G : D ⥤ E) [PreservesEpimorphisms G] [ReflectsEpimorphisms (F ⋙ G)] : ReflectsEpimorphisms F := ⟨fun f _ => (F ⋙ G).epi_of_epi_map <| show Epi (G.map (F.map f)) from inferInstance⟩ -theorem reflectsMonomorphisms_of_preserves_of_reflects (F : C ⥤ D) (G : D ⥤ E) - [PreservesMonomorphisms G] [ReflectsMonomorphisms (F ⋙ G)] : ReflectsMonomorphisms F := - ⟨fun f _ => (F ⋙ G).mono_of_mono_map <| show Mono (G.map (F.map f)) from inferInstance⟩ - -lemma preservesMonomorphisms.of_natTrans {F G : C ⥤ D} [PreservesMonomorphisms F] +@[to_dual] +lemma PreservesMonomorphisms.of_natTrans {F G : C ⥤ D} [PreservesMonomorphisms F] (f : G ⟶ F) [∀ X, Mono (f.app X)] : PreservesMonomorphisms G where preserves {X Y} π hπ := by @@ -111,109 +96,92 @@ lemma preservesMonomorphisms.of_natTrans {F G : C ⥤ D} [PreservesMonomorphisms rw [f.naturality π] infer_instance -theorem preservesMonomorphisms.of_iso {F G : C ⥤ D} [PreservesMonomorphisms F] (α : F ≅ G) : +@[to_dual] +theorem PreservesMonomorphisms.of_iso {F G : C ⥤ D} [PreservesMonomorphisms F] (α : F ≅ G) : PreservesMonomorphisms G := of_natTrans α.inv -theorem preservesMonomorphisms.iso_iff {F G : C ⥤ D} (α : F ≅ G) : +@[to_dual] +theorem PreservesMonomorphisms.iso_iff {F G : C ⥤ D} (α : F ≅ G) : PreservesMonomorphisms F ↔ PreservesMonomorphisms G := - ⟨fun _ => preservesMonomorphisms.of_iso α, fun _ => preservesMonomorphisms.of_iso α.symm⟩ - -lemma preservesEpimorphisms.of_natTrans {F G : C ⥤ D} [PreservesEpimorphisms F] - (f : F ⟶ G) [∀ X, Epi (f.app X)] : - PreservesEpimorphisms G where - preserves {X Y} π hπ := by - suffices Epi (f.app X ≫ G.map π) from epi_of_epi (f.app X) (G.map π) - rw [← f.naturality π] - infer_instance - -theorem preservesEpimorphisms.of_iso {F G : C ⥤ D} [PreservesEpimorphisms F] (α : F ≅ G) : - PreservesEpimorphisms G := - of_natTrans α.hom - -theorem preservesEpimorphisms.iso_iff {F G : C ⥤ D} (α : F ≅ G) : - PreservesEpimorphisms F ↔ PreservesEpimorphisms G := - ⟨fun _ => preservesEpimorphisms.of_iso α, fun _ => preservesEpimorphisms.of_iso α.symm⟩ - -theorem reflectsMonomorphisms.of_iso {F G : C ⥤ D} [ReflectsMonomorphisms F] (α : F ≅ G) : - ReflectsMonomorphisms G := - { reflects := fun {X} {Y} f h => by - apply F.mono_of_mono_map - suffices F.map f = (α.app X).hom ≫ G.map f ≫ (α.app Y).inv from this ▸ mono_comp _ _ - simp } - -theorem reflectsMonomorphisms.iso_iff {F G : C ⥤ D} (α : F ≅ G) : + ⟨fun _ => of_iso α, fun _ => of_iso α.symm⟩ + +@[to_dual] +theorem ReflectsMonomorphisms.of_iso {F G : C ⥤ D} [ReflectsMonomorphisms F] (α : F ≅ G) : + ReflectsMonomorphisms G where + reflects {X Y} f h := by + apply F.mono_of_mono_map + suffices F.map f = (α.app X).hom ≫ G.map f ≫ (α.app Y).inv from this ▸ mono_comp _ _ + simp + +@[to_dual] +theorem ReflectsMonomorphisms.iso_iff {F G : C ⥤ D} (α : F ≅ G) : ReflectsMonomorphisms F ↔ ReflectsMonomorphisms G := - ⟨fun _ => reflectsMonomorphisms.of_iso α, fun _ => reflectsMonomorphisms.of_iso α.symm⟩ - -theorem reflectsEpimorphisms.of_iso {F G : C ⥤ D} [ReflectsEpimorphisms F] (α : F ≅ G) : - ReflectsEpimorphisms G := - { reflects := fun {X} {Y} f h => by - apply F.epi_of_epi_map - suffices F.map f = (α.app X).hom ≫ G.map f ≫ (α.app Y).inv from this ▸ epi_comp _ _ - simp } - -theorem reflectsEpimorphisms.iso_iff {F G : C ⥤ D} (α : F ≅ G) : - ReflectsEpimorphisms F ↔ ReflectsEpimorphisms G := - ⟨fun _ => reflectsEpimorphisms.of_iso α, fun _ => reflectsEpimorphisms.of_iso α.symm⟩ - + ⟨fun _ => of_iso α, fun _ => of_iso α.symm⟩ + +@[deprecated (since := "2026-06-25")] +alias preservesMonomorphisms.of_natTrans := PreservesMonomorphisms.of_natTrans +@[deprecated (since := "2026-06-25")] +alias preservesMonomorphisms.of_iso := PreservesMonomorphisms.of_iso +@[deprecated (since := "2026-06-25")] +alias preservesMonomorphisms.iso_iff := PreservesMonomorphisms.iso_iff +@[deprecated (since := "2026-06-25")] +alias reflectsMonomorphisms.of_iso := ReflectsMonomorphisms.of_iso +@[deprecated (since := "2026-06-25")] +alias reflectsMonomorphisms.iso_iff := ReflectsMonomorphisms.iso_iff +@[deprecated (since := "2026-06-25")] +alias preservesEpimorphisms.of_natTrans := PreservesEpimorphisms.of_natTrans +@[deprecated (since := "2026-06-25")] +alias preservesEpimorphisms.of_iso := PreservesEpimorphisms.of_iso +@[deprecated (since := "2026-06-25")] +alias preservesEpimorphisms.iso_iff := PreservesEpimorphisms.iso_iff +@[deprecated (since := "2026-06-25")] +alias reflectsEpimorphisms.of_iso := ReflectsEpimorphisms.of_iso +@[deprecated (since := "2026-06-25")] +alias reflectsEpimorphisms.iso_iff := ReflectsEpimorphisms.iso_iff + +@[to_dual] theorem preservesEpimorphisms_of_adjunction {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) : - PreservesEpimorphisms F := - { preserves := fun {X} {Y} f hf => - ⟨by - intro Z g h H - replace H := congr_arg (adj.homEquiv X Z) H - rwa [adj.homEquiv_naturality_left, adj.homEquiv_naturality_left, cancel_epi, - Equiv.apply_eq_iff_eq] at H⟩ } - + PreservesEpimorphisms F where + preserves {X Y} f hf := ⟨by + intro Z g h H + replace H := congr_arg (adj.homEquiv X Z) H + rwa [adj.homEquiv_naturality_left, adj.homEquiv_naturality_left, cancel_epi, + Equiv.apply_eq_iff_eq] at H⟩ + +@[to_dual] instance (priority := 100) preservesEpimorphisms_of_isLeftAdjoint (F : C ⥤ D) [IsLeftAdjoint F] : PreservesEpimorphisms F := preservesEpimorphisms_of_adjunction (Adjunction.ofIsLeftAdjoint F) -theorem preservesMonomorphisms_of_adjunction {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) : - PreservesMonomorphisms G := - { preserves := fun {X} {Y} f hf => - ⟨by - intro Z g h H - replace H := congr_arg (adj.homEquiv Z Y).symm H - rwa [adj.homEquiv_naturality_right_symm, adj.homEquiv_naturality_right_symm, cancel_mono, - Equiv.apply_eq_iff_eq] at H⟩ } - -instance (priority := 100) preservesMonomorphisms_of_isRightAdjoint (F : C ⥤ D) [IsRightAdjoint F] : - PreservesMonomorphisms F := - preservesMonomorphisms_of_adjunction (Adjunction.ofIsRightAdjoint F) - +@[to_dual] instance (priority := 100) reflectsMonomorphisms_of_faithful (F : C ⥤ D) [Faithful F] : ReflectsMonomorphisms F where reflects {X} {Y} f _ := ⟨fun {Z} g h hgh => F.map_injective ((cancel_mono (F.map f)).1 (by rw [← F.map_comp, hgh, F.map_comp]))⟩ -instance (priority := 100) reflectsEpimorphisms_of_faithful (F : C ⥤ D) [Faithful F] : - ReflectsEpimorphisms F where - reflects {X} {Y} f _ := - ⟨fun {Z} g h hgh => - F.map_injective ((cancel_epi (F.map f)).1 (by rw [← F.map_comp, hgh, F.map_comp]))⟩ - +@[to_dual] instance {F G : C ⥤ D} (f : F ⟶ G) [IsSplitEpi f] (X : C) : IsSplitEpi (f.app X) := inferInstanceAs (IsSplitEpi (((evaluation C D).obj X).map f)) -instance {F G : C ⥤ D} (f : F ⟶ G) [IsSplitMono f] (X : C) : IsSplitMono (f.app X) := - inferInstanceAs (IsSplitMono (((evaluation C D).obj X).map f)) - -lemma preservesEpimorphisms.ofRetract {F G : C ⥤ D} (r : Retract G F) [F.PreservesEpimorphisms] : +@[to_dual] +lemma PreservesEpimorphisms.ofRetract {F G : C ⥤ D} (r : Retract G F) [F.PreservesEpimorphisms] : G.PreservesEpimorphisms where - preserves := (preservesEpimorphisms.of_natTrans r.r).preserves + preserves := (PreservesEpimorphisms.of_natTrans r.r).preserves -lemma preservesMonomorphisms.ofRetract {F G : C ⥤ D} (r : Retract G F) [F.PreservesMonomorphisms] : - G.PreservesMonomorphisms where - preserves := (preservesMonomorphisms.of_natTrans r.i).preserves +@[deprecated (since := "2026-06-25")] +alias preservesEpimorphisms.ofRetract := PreservesEpimorphisms.ofRetract +@[deprecated (since := "2026-06-25")] +alias preservesMonomorphisms.ofRetract := PreservesMonomorphisms.ofRetract section variable (F : C ⥤ D) {X Y : C} (f : X ⟶ Y) /-- If `F` is a fully faithful functor, split epimorphisms are preserved and reflected by `F`. -/ +@[to_dual +/-- If `F` is a fully faithful functor, split monomorphisms are preserved and reflected by `F`. -/] noncomputable def splitEpiEquiv [Full F] [Faithful F] : SplitEpi f ≃ SplitEpi (F.map f) where toFun f := f.map F invFun s := ⟨F.preimage s.section_, by @@ -223,7 +191,7 @@ noncomputable def splitEpiEquiv [Full F] [Faithful F] : SplitEpi f ≃ SplitEpi left_inv := by cat_disch right_inv x := by cat_disch -@[simp] +@[to_dual (attr := simp)] theorem isSplitEpi_iff [Full F] [Faithful F] : IsSplitEpi (F.map f) ↔ IsSplitEpi f := by constructor · intro h @@ -231,25 +199,7 @@ theorem isSplitEpi_iff [Full F] [Faithful F] : IsSplitEpi (F.map f) ↔ IsSplitE · intro h exact IsSplitEpi.mk' ((splitEpiEquiv F f).toFun h.exists_splitEpi.some) -/-- If `F` is a fully faithful functor, split monomorphisms are preserved and reflected by `F`. -/ -noncomputable def splitMonoEquiv [Full F] [Faithful F] : SplitMono f ≃ SplitMono (F.map f) where - toFun f := f.map F - invFun s := ⟨F.preimage s.retraction, by - apply F.map_injective - simp only [map_comp, map_preimage, map_id] - apply SplitMono.id⟩ - left_inv := by cat_disch - right_inv x := by cat_disch - -@[simp] -theorem isSplitMono_iff [Full F] [Faithful F] : IsSplitMono (F.map f) ↔ IsSplitMono f := by - constructor - · intro h - exact IsSplitMono.mk' ((splitMonoEquiv F f).invFun h.exists_splitMono.some) - · intro h - exact IsSplitMono.mk' ((splitMonoEquiv F f).toFun h.exists_splitMono.some) - -@[simp] +@[to_dual (attr := simp)] theorem epi_map_iff_epi [hF₁ : PreservesEpimorphisms F] [hF₂ : ReflectsEpimorphisms F] : Epi (F.map f) ↔ Epi f := by constructor @@ -257,16 +207,11 @@ theorem epi_map_iff_epi [hF₁ : PreservesEpimorphisms F] [hF₂ : ReflectsEpimo · intro h exact F.map_epi f -@[simp] -theorem mono_map_iff_mono [hF₁ : PreservesMonomorphisms F] [hF₂ : ReflectsMonomorphisms F] : - Mono (F.map f) ↔ Mono f := by - constructor - · exact F.mono_of_mono_map - · intro h - exact F.map_mono f - /-- If `F : C ⥤ D` is an equivalence of categories and `C` is a `SplitEpiCategory`, then `D` also is. -/ +@[to_dual +/-- If `F : C ⥤ D` is an equivalence of categories and `C` is a `SplitMonoCategory`, +then `D` also is. -/] theorem splitEpiCategoryImpOfIsEquivalence [IsEquivalence F] [SplitEpiCategory C] : SplitEpiCategory D := ⟨fun {X} {Y} f => by @@ -282,6 +227,7 @@ namespace CategoryTheory.Adjunction variable {C D : Type*} [Category* C] [Category* D] {F : C ⥤ D} {F' : D ⥤ C} {A B : C} +@[to_dual] theorem strongEpi_map_of_strongEpi (adj : F ⊣ F') (f : A ⟶ B) [F'.PreservesMonomorphisms] [F.PreservesEpimorphisms] [StrongEpi f] : StrongEpi (F.map f) := ⟨inferInstance, fun X Y Z => by @@ -289,10 +235,12 @@ theorem strongEpi_map_of_strongEpi (adj : F ⊣ F') (f : A ⟶ B) [F'.PreservesM rw [adj.hasLiftingProperty_iff] infer_instance⟩ +@[to_dual] instance strongEpi_map_of_isEquivalence [F.IsEquivalence] (f : A ⟶ B) [_h : StrongEpi f] : StrongEpi (F.map f) := F.asEquivalence.toAdjunction.strongEpi_map_of_strongEpi f +@[to_dual] instance (adj : F ⊣ F') {X : C} {Y : D} (f : F.obj X ⟶ Y) [hf : Mono f] [F.ReflectsMonomorphisms] : Mono (adj.homEquiv _ _ f) := F.mono_of_mono_map <| by @@ -305,7 +253,7 @@ namespace CategoryTheory.Functor variable {C D : Type*} [Category* C] [Category* D] {F : C ⥤ D} {A B : C} (f : A ⟶ B) -@[simp] +@[to_dual (attr := simp)] theorem strongEpi_map_iff_strongEpi_of_isEquivalence [IsEquivalence F] : StrongEpi (F.map f) ↔ StrongEpi f := by constructor diff --git a/Mathlib/CategoryTheory/Functor/FullyFaithful.lean b/Mathlib/CategoryTheory/Functor/FullyFaithful.lean index df388bbf5931f1..ca6d802156e9cd 100644 --- a/Mathlib/CategoryTheory/Functor/FullyFaithful.lean +++ b/Mathlib/CategoryTheory/Functor/FullyFaithful.lean @@ -80,6 +80,9 @@ theorem map_surjective (F : C ⥤ D) [Full F] : noncomputable def preimage (F : C ⥤ D) [Full F] (f : F.obj X ⟶ F.obj Y) : X ⟶ Y := (F.map_surjective f).choose +-- TODO: `to_dual` should deal with this automatically: +attribute [to_dual self] preimage.congr_simp + @[simp, to_dual self] theorem map_preimage (F : C ⥤ D) [Full F] {X Y : C} (f : F.obj X ⟶ F.obj Y) : F.map (preimage F f) = f := @@ -94,12 +97,12 @@ variable [Full F] [F.Faithful] theorem preimage_id : F.preimage (𝟙 (F.obj X)) = 𝟙 X := F.map_injective (by simp) -@[simp] +@[simp, to_dual self] theorem preimage_comp (f : F.obj X ⟶ F.obj Y) (g : F.obj Y ⟶ F.obj Z) : F.preimage (f ≫ g) = F.preimage f ≫ F.preimage g := F.map_injective (by simp) -@[simp] +@[simp, to_dual self] theorem preimage_map (f : X ⟶ Y) : F.preimage (F.map f) = f := F.map_injective (by simp) diff --git a/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean b/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean index 96817d254b26d4..8847b8c08a2437 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/Adjunction.lean @@ -29,6 +29,8 @@ open Category variable {C D : Type*} [Category* C] [Category* D] {G : C ⥤ D} {F : D ⥤ C} +to_dual_name_hint Left Right + namespace CommSq section @@ -38,6 +40,10 @@ variable {A B : C} {X Y : D} {i : A ⟶ B} {p : X ⟶ Y} {u : G.obj A ⟶ X} {v /-- When we have an adjunction `G ⊣ F`, any commutative square where the left map is of the form `G.map i` and the right map is `p` has an "adjoint" commutative square whose left map is `i` and whose right map is `F.map p`. -/ +@[to_dual +/-- When we have an adjunction `G ⊣ F`, any commutative square where the left +map is of the form `i` and the right map is `F.map p` has an "adjoint" commutative +square whose left map is `G.map i` and whose right map is `p`. -/] theorem right_adjoint (sq : CommSq u (G.map i) p v) (adj : G ⊣ F) : CommSq (adj.homEquiv _ _ u) i (F.map p) (adj.homEquiv _ _ v) := ⟨by @@ -48,6 +54,9 @@ variable (sq : CommSq u (G.map i) p v) (adj : G ⊣ F) /-- The liftings of a commutative are in bijection with the liftings of its (right) adjoint square. -/ +@[to_dual +/-- The liftings of a commutative are in bijection with the liftings of its (left) +adjoint square. -/] def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct where toFun l := { l := adj.homEquiv _ _ l.l @@ -64,66 +73,25 @@ def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftS left_inv := by cat_disch right_inv := by cat_disch -/-- A square has a lifting if and only if its (right) adjoint square has a lifting. -/ +/-- A (right) adjoint square has a lifting if and only if the original square has a lifting. -/ +@[to_dual +/-- A (left) adjoint square has a lifting if and only if the original square has a lifting. -/] theorem right_adjoint_hasLift_iff : HasLift (sq.right_adjoint adj) ↔ HasLift sq := by simp only [HasLift.iff] exact Equiv.nonempty_congr (sq.rightAdjointLiftStructEquiv adj).symm -instance [HasLift sq] : HasLift (sq.right_adjoint adj) := by +@[to_dual] +instance instHasLiftRightAdjoin [HasLift sq] : HasLift (sq.right_adjoint adj) := by rw [right_adjoint_hasLift_iff] infer_instance end -section - -variable {A B : C} {X Y : D} {i : A ⟶ B} {p : X ⟶ Y} {u : A ⟶ F.obj X} {v : B ⟶ F.obj Y} - -/-- When we have an adjunction `G ⊣ F`, any commutative square where the left -map is of the form `i` and the right map is `F.map p` has an "adjoint" commutative -square whose left map is `G.map i` and whose right map is `p`. -/ -theorem left_adjoint (sq : CommSq u i (F.map p) v) (adj : G ⊣ F) : - CommSq ((adj.homEquiv _ _).symm u) (G.map i) p ((adj.homEquiv _ _).symm v) := - ⟨by - simp only [Adjunction.homEquiv_counit, assoc, ← G.map_comp_assoc, ← sq.w] - rw [G.map_comp, assoc, Adjunction.counit_naturality]⟩ - -variable (sq : CommSq u i (F.map p) v) (adj : G ⊣ F) - -/-- The liftings of a commutative are in bijection with the liftings of its (left) -adjoint square. -/ -def leftAdjointLiftStructEquiv : - sq.LiftStruct ≃ (sq.left_adjoint adj).LiftStruct where - toFun l := - { l := (adj.homEquiv _ _).symm l.l - fac_left := by rw [← adj.homEquiv_naturality_left_symm, l.fac_left] - fac_right := by rw [← adj.homEquiv_naturality_right_symm, l.fac_right] } - invFun l := - { l := (adj.homEquiv _ _) l.l - fac_left := by - rw [← adj.homEquiv_naturality_left, l.fac_left] - apply (adj.homEquiv _ _).right_inv - fac_right := by - rw [← adj.homEquiv_naturality_right, l.fac_right] - apply (adj.homEquiv _ _).right_inv } - left_inv := by cat_disch - right_inv := by cat_disch - -/-- A (left) adjoint square has a lifting if and only if the original square has a lifting. -/ -theorem left_adjoint_hasLift_iff : HasLift (sq.left_adjoint adj) ↔ HasLift sq := by - simp only [HasLift.iff] - exact Equiv.nonempty_congr (sq.leftAdjointLiftStructEquiv adj).symm - -instance [HasLift sq] : HasLift (sq.left_adjoint adj) := by - rw [left_adjoint_hasLift_iff] - infer_instance - -end - end CommSq namespace Adjunction +@[to_dual none] theorem hasLiftingProperty_iff (adj : G ⊣ F) {A B : C} {X Y : D} (i : A ⟶ B) (p : X ⟶ Y) : HasLiftingProperty (G.map i) p ↔ HasLiftingProperty i (F.map p) := by constructor <;> intro <;> constructor <;> intro f g sq diff --git a/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean index 0deeb6c92c94ed..611088f2311e76 100644 --- a/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Injective/Basic.lean @@ -182,7 +182,7 @@ theorem projective_iff_injective_op {P : C} : Projective P ↔ Injective (op P) theorem injective_iff_preservesEpimorphisms_yoneda_obj (J : C) : Injective J ↔ (yoneda.obj J).PreservesEpimorphisms := by rw [injective_iff_projective_op, Projective.projective_iff_preservesEpimorphisms_coyoneda_obj] - exact Functor.preservesEpimorphisms.iso_iff (Coyoneda.objOpOp _) + exact Functor.PreservesEpimorphisms.iso_iff (Coyoneda.objOpOp _) section Adjunction diff --git a/Mathlib/CategoryTheory/Preadditive/Projective/Internal.lean b/Mathlib/CategoryTheory/Preadditive/Projective/Internal.lean index ee04c3c01d315f..f209f3e638f7a6 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective/Internal.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective/Internal.lean @@ -54,7 +54,7 @@ instance : (isInternallyProjective (C := C)).IsStableUnderRetracts where of_retract {Y X} r h := have : InternallyProjective X := ⟨h⟩ have : Retract (ihom Y) (ihom X) := r.op.map internalHom - preservesEpimorphisms.ofRetract this + PreservesEpimorphisms.ofRetract this namespace InternallyProjective diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index 8f8aa6e95074cd..e1693f2cb87f4e 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -199,6 +199,8 @@ def nameDict : Std.HashMap String (List String) := .ofList [ ("epi", ["Mono"]), /- `mono` can also refer to monotone, so we don't translate it. -/ -- ("mono", ["Epi"]), + ("epimorphisms", ["Monomorphisms"]), + ("monomorphisms", ["Epimorphisms"]), ("terminal", ["Initial"]), ("initial", ["Terminal"]), ("precompose", ["Postcompose"]), From f51bdaa4219c3d0de7b586222534ec9c8304d50b Mon Sep 17 00:00:00 2001 From: Jack McCarthy <37917934+Deicyde@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:28 +0000 Subject: [PATCH 1222/1300] doc: add wikidata attributes (#41139) This PR adds a batch of 20 `@[wikidata]` attributes. Claude helped generate the list of crossrefs (by scanning Wikidata + Mathlib). Comments are generated by [crossref-report](https://github.com/jcommelin/mathlib-crossref-report) and Wikilean. See https://wikilean.jackmccarthy.org/review?pr=41139 for reviewer UI. Co-authored-by: wikilean-bot --- Mathlib/Algebra/IsPrimePow.lean | 2 ++ Mathlib/Analysis/Complex/Circle.lean | 2 ++ Mathlib/Analysis/InnerProductSpace/Adjoint.lean | 2 ++ Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 2 ++ Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean | 2 ++ Mathlib/Combinatorics/SimpleGraph/Clique.lean | 2 ++ Mathlib/Combinatorics/SimpleGraph/Finite.lean | 2 ++ Mathlib/Data/Set/Operations.lean | 2 ++ Mathlib/Geometry/Manifold/Instances/Real.lean | 3 ++- Mathlib/LinearAlgebra/BilinearMap.lean | 2 ++ Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean | 2 ++ Mathlib/LinearAlgebra/Matrix/Symmetric.lean | 2 ++ Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean | 2 ++ Mathlib/MeasureTheory/Function/L1Space/Integrable.lean | 3 ++- Mathlib/MeasureTheory/OuterMeasure/AE.lean | 2 ++ Mathlib/NumberTheory/NumberField/Basic.lean | 2 ++ Mathlib/RingTheory/ClassGroup/Basic.lean | 2 ++ Mathlib/Topology/Defs/Basic.lean | 1 + 18 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/IsPrimePow.lean b/Mathlib/Algebra/IsPrimePow.lean index aba6e238990d62..e173af2f72b7cd 100644 --- a/Mathlib/Algebra/IsPrimePow.lean +++ b/Mathlib/Algebra/IsPrimePow.lean @@ -10,6 +10,7 @@ public import Mathlib.Order.Nat public import Mathlib.Data.Nat.Prime.Basic public import Mathlib.Data.Nat.Log public import Mathlib.Data.Nat.Prime.Pow +public import Mathlib.Tactic.CrossRefAttribute /-! # Prime powers @@ -24,6 +25,7 @@ variable {R : Type*} [CommMonoidWithZero R] (n p : R) (k : ℕ) /-- `n` is a prime power if there is a prime `p` and a positive natural `k` such that `n` can be written as `p^k`. -/ +@[wikidata Q1667469] def IsPrimePow : Prop := ∃ (p : R) (k : ℕ), Prime p ∧ 0 < k ∧ p ^ k = n diff --git a/Mathlib/Analysis/Complex/Circle.lean b/Mathlib/Analysis/Complex/Circle.lean index 86571cd5e4bc74..fd426d4f6c2ebc 100644 --- a/Mathlib/Analysis/Complex/Circle.lean +++ b/Mathlib/Analysis/Complex/Circle.lean @@ -7,6 +7,7 @@ module public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Basic public import Mathlib.Analysis.Normed.Field.UnitBall +public import Mathlib.Tactic.CrossRefAttribute /-! # The circle @@ -47,6 +48,7 @@ noncomputable section open Complex Function Metric ComplexConjugate /-- The unit circle in `ℂ`. -/ +@[wikidata Q203425] def Circle : Type := Submonoid.unitSphere ℂ deriving TopologicalSpace diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index 6276f3325d4dc9..7fb5103bd57a79 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -9,6 +9,7 @@ public import Mathlib.Algebra.Star.UnitaryStarAlgAut public import Mathlib.Analysis.InnerProductSpace.Dual public import Mathlib.Analysis.InnerProductSpace.PiL2 public import Mathlib.Analysis.LocallyConvex.SeparatingDual +public import Mathlib.Tactic.CrossRefAttribute /-! @@ -109,6 +110,7 @@ public section /-- The adjoint of a bounded operator `A` from a Hilbert space `E` to another Hilbert space `F`, denoted as `A†`. -/ +@[wikidata Q1509647] def adjoint : (E →L[𝕜] F) ≃ₗᵢ⋆[𝕜] F →L[𝕜] E := LinearIsometryEquiv.ofSurjective { adjointAux with norm_map' := adjointAux_norm } fun A => ⟨adjointAux A, adjointAux_adjointAux A⟩ diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index a65c8239c4c96b..38a9866de67d6c 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -12,6 +12,7 @@ public import Mathlib.Analysis.Normed.Algebra.UnitizationL1 public import Mathlib.Analysis.Normed.Ring.Units public import Mathlib.Analysis.SpecialFunctions.Pow.Continuity public import Mathlib.FieldTheory.IsAlgClosed.Spectrum +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Topology.Algebra.Module.Spaces.CharacterSpace public import Mathlib.Topology.Semicontinuity.Hemicontinuity @@ -50,6 +51,7 @@ coerced into an element of `ℝ≥0∞`. Note that it is possible for `spectrum case, `spectralRadius a = 0`. It is also possible that `spectrum 𝕜 a` be unbounded (though not for Banach algebras, see `spectrum.isBounded`, below). In this case, `spectralRadius a = ∞`. -/ +@[wikidata Q249748] noncomputable def spectralRadius (𝕜 : Type*) {A : Type*} [NormedField 𝕜] [Ring A] [Algebra 𝕜 A] (a : A) : ℝ≥0∞ := ⨆ k ∈ spectrum 𝕜 a, ‖k‖₊ diff --git a/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean b/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean index 7607b3481dc65f..b14f659d85e0a8 100644 --- a/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean +++ b/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.Normed.Module.Multilinear.Basic public import Mathlib.Analysis.Normed.Ring.Units public import Mathlib.Analysis.Normed.Operator.Mul +public import Mathlib.Tactic.CrossRefAttribute /-! # Bounded linear maps @@ -76,6 +77,7 @@ inequality `‖f x‖ ≤ M * ‖x‖` for some positive constant `M`. (We put only the typeclasses strictly necessary for the definition, although the main case of interest is when `𝕜` itself is a normed ring and `E, F` are normed modules.) -/ +@[wikidata Q2342396] structure IsBoundedLinearMap : Prop extends IsLinearMap 𝕜 f where bound : ∃ M, 0 < M ∧ ∀ x : E, ‖f x‖ ≤ M * ‖x‖ diff --git a/Mathlib/Combinatorics/SimpleGraph/Clique.lean b/Mathlib/Combinatorics/SimpleGraph/Clique.lean index 1d5fb21740d941..6d7e79588587ee 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Clique.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Clique.lean @@ -13,6 +13,7 @@ public import Mathlib.Data.Fintype.Pigeonhole public import Mathlib.Data.Fintype.Powerset public import Mathlib.Order.Lattice.Nat public import Mathlib.SetTheory.Cardinal.Finite +public import Mathlib.Tactic.CrossRefAttribute /-! # Graph cliques @@ -842,6 +843,7 @@ section IndepSet variable {s : Set α} /-- An independent set in a graph is a set of vertices that are pairwise not adjacent. -/ +@[wikidata Q1060343] abbrev IsIndepSet (s : Set α) : Prop := s.Pairwise (fun v w ↦ ¬G.Adj v w) diff --git a/Mathlib/Combinatorics/SimpleGraph/Finite.lean b/Mathlib/Combinatorics/SimpleGraph/Finite.lean index 3c7e0f856430c9..68bc2a4e5783e6 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Finite.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Finite.lean @@ -8,6 +8,7 @@ module public import Mathlib.Combinatorics.SimpleGraph.Maps public import Mathlib.Data.Finset.Max public import Mathlib.Data.Sym.Card +public import Mathlib.Tactic.CrossRefAttribute /-! # Definitions for finite and locally finite graphs @@ -362,6 +363,7 @@ abbrev LocallyFinite := variable [LocallyFinite G] /-- A locally finite simple graph is regular of degree `d` if every vertex has degree `d`. -/ +@[wikidata Q826467] def IsRegularOfDegree (d : ℕ) : Prop := ∀ v : V, G.degree v = d diff --git a/Mathlib/Data/Set/Operations.lean b/Mathlib/Data/Set/Operations.lean index be88d70e1d77e1..61b806b37f6981 100644 --- a/Mathlib/Data/Set/Operations.lean +++ b/Mathlib/Data/Set/Operations.lean @@ -10,6 +10,7 @@ public import Mathlib.Data.Set.CoeSort public import Mathlib.Data.SProd public import Mathlib.Data.Subtype public import Mathlib.Order.Notation +public import Mathlib.Tactic.CrossRefAttribute public import Mathlib.Tactic.Push.Attr import Mathlib.Tactic.Attr.Register @@ -219,6 +220,7 @@ lemma Subtype.range_coind (f : α → β) {p : β → Prop} (h : ∀ (a : α), p section Prod /-- The Cartesian product `Set.prod s t` is the set of `(a, b)` such that `a ∈ s` and `b ∈ t`. -/ +@[wikidata Q173740] def prod (s : Set α) (t : Set β) : Set (α × β) := {p | p.1 ∈ s ∧ p.2 ∈ t} @[default_instance] diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 00cba106e172eb..8d93500db37d4f 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -8,6 +8,7 @@ module public import Mathlib.Analysis.Calculus.ContDiff.WithLp public import Mathlib.Analysis.InnerProductSpace.PiL2 public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Tactic.CrossRefAttribute /-! # Constructing examples of manifolds over ℝ @@ -55,7 +56,7 @@ open scoped Manifold ContDiff ENNReal /-- The half-space in `ℝ^n`, used to model manifolds with boundary. We only define it when `1 ≤ n`, as the definition only makes sense in this case. -/ -@[implicit_reducible] +@[implicit_reducible, wikidata Q644719] def EuclideanHalfSpace (n : ℕ) [NeZero n] : Type := { x : EuclideanSpace ℝ (Fin n) // 0 ≤ x 0 } deriving TopologicalSpace diff --git a/Mathlib/LinearAlgebra/BilinearMap.lean b/Mathlib/LinearAlgebra/BilinearMap.lean index 2e69802b24b089..3e8b3394998a39 100644 --- a/Mathlib/LinearAlgebra/BilinearMap.lean +++ b/Mathlib/LinearAlgebra/BilinearMap.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Module.Submodule.Equiv public import Mathlib.Algebra.Module.Torsion.Free +public import Mathlib.Tactic.CrossRefAttribute /-! # Basics on bilinear maps @@ -526,6 +527,7 @@ protected abbrev BilinMap : Type _ := M →ₗ[R] M →ₗ[R] Nₗ variable (R M) in /-- For convenience, a shorthand for the type of bilinear forms from `M` to `R`. -/ +@[wikidata Q837924] protected abbrev BilinForm : Type _ := LinearMap.BilinMap R M R end CommSemiring diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean index 24a8db834ce856..b8c844402db45a 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/Basic.lean @@ -9,6 +9,7 @@ public import Mathlib.Algebra.Polynomial.Eval.SMul public import Mathlib.LinearAlgebra.Matrix.Adjugate public import Mathlib.LinearAlgebra.Matrix.Block public import Mathlib.RingTheory.MatrixPolynomialAlgebra +public import Mathlib.Tactic.CrossRefAttribute /-! # Characteristic polynomials and the Cayley-Hamilton theorem @@ -129,6 +130,7 @@ lemma charmatrix_blockTriangular_iff {α : Type*} [Preorder α] {M : Matrix n n alias ⟨BlockTriangular.of_charmatrix, BlockTriangular.charmatrix⟩ := charmatrix_blockTriangular_iff /-- The characteristic polynomial of a matrix `M` is given by $\det (t I - M)$. -/ +@[wikidata Q849705] def charpoly (M : Matrix n n R) : R[X] := (charmatrix M).det diff --git a/Mathlib/LinearAlgebra/Matrix/Symmetric.lean b/Mathlib/LinearAlgebra/Matrix/Symmetric.lean index d2ceb1ad4fcff3..b2565b85eb878f 100644 --- a/Mathlib/LinearAlgebra/Matrix/Symmetric.lean +++ b/Mathlib/LinearAlgebra/Matrix/Symmetric.lean @@ -7,6 +7,7 @@ module public import Mathlib.Data.Matrix.Basic public import Mathlib.Data.Matrix.Block +public import Mathlib.Tactic.CrossRefAttribute /-! # Symmetric matrices @@ -30,6 +31,7 @@ variable {α β n m R : Type*} namespace Matrix /-- A matrix `A : Matrix n n α` is "symmetric" if `Aᵀ = A`. -/ +@[wikidata Q339011] def IsSymm (A : Matrix n n α) : Prop := Aᵀ = A diff --git a/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean b/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean index 106295ce5620c9..716e4e5b615bdc 100644 --- a/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean +++ b/Mathlib/LinearAlgebra/RootSystem/WeylGroup.lean @@ -7,6 +7,7 @@ module public import Mathlib.LinearAlgebra.RootSystem.Hom public import Mathlib.RepresentationTheory.Basic +public import Mathlib.Tactic.CrossRefAttribute /-! # The Weyl group of a root pairing @@ -51,6 +52,7 @@ variable [CommRing R] [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N /-- The `Weyl group` of a root pairing is the group of automorphisms of the root pairing generated by reflections. -/ +@[wikidata Q768074] def weylGroup : Subgroup (Aut P) := Subgroup.closure (range (Equiv.reflection P)) diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 05ba349d0edc6e..5895b55e6d15c6 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -8,6 +8,7 @@ module public import Mathlib.MeasureTheory.Function.L1Space.HasFiniteIntegral public import Mathlib.MeasureTheory.Function.LpOrder public import Mathlib.MeasureTheory.Function.StronglyMeasurable.Lemmas +public import Mathlib.Tactic.CrossRefAttribute /-! # Integrable functions @@ -54,7 +55,7 @@ namespace MeasureTheory /-- `Integrable f μ` means that `f` is measurable and that the integral `∫⁻ a, ‖f a‖ ∂μ` is finite. `Integrable f` means `Integrable f volume`. -/ -@[fun_prop] +@[fun_prop, wikidata Q3153745] def Integrable {α} {_ : MeasurableSpace α} (f : α → ε) (μ : Measure α := by volume_tac) : Prop := AEStronglyMeasurable f μ ∧ HasFiniteIntegral f μ diff --git a/Mathlib/MeasureTheory/OuterMeasure/AE.lean b/Mathlib/MeasureTheory/OuterMeasure/AE.lean index bd19ff9369da89..91d5ba1b16877b 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/AE.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/AE.lean @@ -6,6 +6,7 @@ Authors: Mario Carneiro, Yury Kudryashov module public import Mathlib.MeasureTheory.OuterMeasure.Basic +public import Mathlib.Tactic.CrossRefAttribute /-! # The “almost everywhere” filter of co-null sets. @@ -44,6 +45,7 @@ namespace MeasureTheory variable {α β F : Type*} [FunLike F (Set α) ℝ≥0∞] [OuterMeasureClass F α] {μ : F} {s t : Set α} /-- The “almost everywhere” filter of co-null sets. -/ +@[wikidata Q1139334] def ae (μ : F) : Filter α := .ofCountableUnion (μ · = 0) (fun _S hSc ↦ (measure_sUnion_null_iff hSc).2) fun _t ht _s hs ↦ measure_mono_null hs ht diff --git a/Mathlib/NumberTheory/NumberField/Basic.lean b/Mathlib/NumberTheory/NumberField/Basic.lean index 8d7e89242bb11a..241f20aa14f5f0 100644 --- a/Mathlib/NumberTheory/NumberField/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Basic.lean @@ -10,6 +10,7 @@ public import Mathlib.Algebra.CharZero.AddMonoidHom public import Mathlib.Algebra.Ring.Int.Parity public import Mathlib.Algebra.Ring.Int.Units public import Mathlib.RingTheory.DedekindDomain.IntegralClosure +public import Mathlib.Tactic.CrossRefAttribute /-! # Number fields @@ -98,6 +99,7 @@ much more effective use of the discrimination tree than instances of the form `SMul (Subtype _) (Subtype _)`. The drawback is we have to copy over instances manually. -/ +@[wikidata Q1358313] def RingOfIntegers : Type _ := integralClosure ℤ K deriving CommRing, IsDomain, Nontrivial diff --git a/Mathlib/RingTheory/ClassGroup/Basic.lean b/Mathlib/RingTheory/ClassGroup/Basic.lean index e91fe290266922..d74fafaf5019f0 100644 --- a/Mathlib/RingTheory/ClassGroup/Basic.lean +++ b/Mathlib/RingTheory/ClassGroup/Basic.lean @@ -6,6 +6,7 @@ Authors: Anne Baanen module public import Mathlib.RingTheory.DedekindDomain.Ideal.Basic +public import Mathlib.Tactic.CrossRefAttribute /-! # The ideal class group @@ -85,6 +86,7 @@ variable [IsDomain R] /-- The ideal class group of `R` is the group of invertible fractional ideals modulo the principal ideals. -/ +@[wikidata Q912083] def ClassGroup := (FractionalIdeal R⁰ (FractionRing R))ˣ ⧸ (toPrincipalIdeal R (FractionRing R)).range deriving CommGroup, Inhabited diff --git a/Mathlib/Topology/Defs/Basic.lean b/Mathlib/Topology/Defs/Basic.lean index 25731ef39ec5b2..5d4bc0697dafcf 100644 --- a/Mathlib/Topology/Defs/Basic.lean +++ b/Mathlib/Topology/Defs/Basic.lean @@ -103,6 +103,7 @@ theorem isOpen_sUnion {s : Set (Set X)} (h : ∀ t ∈ s, IsOpen t) : IsOpen ( TopologicalSpace.isOpen_sUnion s h /-- A set is closed if its complement is open -/ +@[wikidata Q320357] class IsClosed (s : Set X) : Prop where /-- The complement of a closed set is an open set. -/ isOpen_compl : IsOpen sᶜ From 2b34bbd75b57df00230ea8bec63b2b25c50abddb Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:30 +0000 Subject: [PATCH 1223/1300] chore(order/ConditionallyCompleteLattice): use `to_dual` more (#41558) This PR uses `to_dual` in most remaining places in `Mathlib.Order.ConditionallyCompleteLattice.Basic`. --- .../ConditionallyCompleteLattice/Basic.lean | 260 +++++------------- .../ConditionallyCompleteLattice/Defs.lean | 2 + 2 files changed, 77 insertions(+), 185 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index fc72050567fcc3..f55de6c4523038 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -39,6 +39,8 @@ variable {α β γ : Type*} {ι : Sort*} section LE +namespace WithTop + /-! Extension of `sSup` and `sInf` from a preorder `α` to `WithTop α` and `WithBot α` -/ @@ -47,57 +49,56 @@ variable [LE α] open scoped Classical in @[to_dual] -noncomputable instance WithTop.instSupSet [SupSet α] : - SupSet (WithTop α) := +noncomputable instance [SupSet α] : SupSet (WithTop α) := ⟨fun S => if ⊤ ∈ S then ⊤ else if BddAbove ((fun (a : α) ↦ ↑a) ⁻¹' S : Set α) then ↑(sSup ((fun (a : α) ↦ (a : WithTop α)) ⁻¹' S : Set α)) else ⊤⟩ open scoped Classical in @[to_dual] -noncomputable instance WithTop.instInfSet [InfSet α] : InfSet (WithTop α) := +noncomputable instance instInfSet [InfSet α] : InfSet (WithTop α) := ⟨fun S => if S ⊆ {⊤} ∨ ¬BddBelow S then ⊤ else ↑(sInf ((fun (a : α) ↦ ↑a) ⁻¹' S : Set α))⟩ @[to_dual] -theorem WithTop.sSup_eq [SupSet α] {s : Set (WithTop α)} (hs : ⊤ ∉ s) +theorem sSup_eq [SupSet α] {s : Set (WithTop α)} (hs : ⊤ ∉ s) (hs' : BddAbove ((↑) ⁻¹' s : Set α)) : sSup s = ↑(sSup ((↑) ⁻¹' s) : α) := (if_neg hs).trans <| if_pos hs' @[to_dual] -theorem WithTop.sInf_eq [InfSet α] {s : Set (WithTop α)} (hs : ¬s ⊆ {⊤}) (h's : BddBelow s) : +theorem sInf_eq [InfSet α] {s : Set (WithTop α)} (hs : ¬s ⊆ {⊤}) (h's : BddBelow s) : sInf s = ↑(sInf ((↑) ⁻¹' s) : α) := if_neg <| by simp [hs, h's] -@[simp] -theorem WithTop.sInf_empty [InfSet α] : sInf (∅ : Set (WithTop α)) = ⊤ := +@[to_dual (attr := simp)] +theorem sInf_empty [InfSet α] : sInf (∅ : Set (WithTop α)) = ⊤ := if_pos <| by simp @[to_dual (attr := simp)] -theorem WithTop.sInf_singleton_top [InfSet α] : sInf ({⊤} : Set (WithTop α)) = ⊤ := +theorem sInf_singleton_top [InfSet α] : sInf ({⊤} : Set (WithTop α)) = ⊤ := if_pos <| .inl subset_rfl @[to_dual (attr := simp)] -theorem WithTop.sSup_of_top_mem [SupSet α] {s : Set (WithTop α)} (h : ⊤ ∈ s) : sSup s = ⊤ := +theorem sSup_of_top_mem [SupSet α] {s : Set (WithTop α)} (h : ⊤ ∈ s) : sSup s = ⊤ := if_pos h @[to_dual] -theorem WithTop.sSup_singleton_top [SupSet α] : sSup ({⊤} : Set (WithTop α)) = ⊤ := by +theorem sSup_singleton_top [SupSet α] : sSup ({⊤} : Set (WithTop α)) = ⊤ := by simp @[to_dual] -theorem WithTop.sSup_of_not_bddAbove [SupSet α] {s : Set (WithTop α)} +theorem sSup_of_not_bddAbove [SupSet α] {s : Set (WithTop α)} (h : ¬BddAbove ((↑) ⁻¹' s : Set α)) : sSup s = ⊤ := by by_cases hmem : ⊤ ∈ s · exact sSup_of_top_mem hmem · exact if_neg hmem |>.trans <| if_neg h @[to_dual (attr := simp)] -theorem WithTop.sInf_of_not_bddBelow [InfSet α] {s : Set (WithTop α)} (h : ¬BddBelow s) : +theorem sInf_of_not_bddBelow [InfSet α] {s : Set (WithTop α)} (h : ¬BddBelow s) : sInf s = ⊤ := if_pos <| .inr h @[to_dual (attr := norm_cast)] -theorem WithTop.coe_sSup' [SupSet α] {s : Set α} (hs : BddAbove s) : +theorem coe_sSup' [SupSet α] {s : Set α} (hs : BddAbove s) : ↑(sSup s) = (sSup ((fun (a : α) ↦ ↑a) '' s) : WithTop α) := by classical change _ = ite _ _ _ @@ -105,14 +106,12 @@ theorem WithTop.coe_sSup' [SupSet α] {s : Set α} (hs : BddAbove s) : · exact Option.some_injective _ · rintro ⟨x, _, ⟨⟩⟩ -@[simp] -theorem WithBot.sSup_empty [SupSet α] : sSup (∅ : Set (WithBot α)) = ⊥ := - WithTop.sInf_empty (α := αᵒᵈ) - @[to_dual] -theorem WithTop.sSup_empty (α : Type*) [CompleteLattice α] : (sSup ∅ : WithTop α) = ⊥ := by +theorem sSup_empty (α : Type*) [CompleteLattice α] : (sSup ∅ : WithTop α) = ⊥ := by rw [sSup_eq (by simp) (OrderTop.bddAbove _), Set.preimage_empty, _root_.sSup_empty, coe_bot] +end WithTop + end LE section Preorder @@ -206,21 +205,14 @@ theorem csSup_le (h₁ : s.Nonempty) (h₂ : ∀ b ∈ s, b ≤ a) : sSup s ≤ theorem le_csSup_of_le (hs : BddAbove s) (hb : b ∈ s) (h : a ≤ b) : a ≤ sSup s := le_trans h (le_csSup hs hb) -@[gcongr low] +@[to_dual (attr := gcongr low)] theorem csSup_le_csSup (ht : BddAbove t) (hs : s.Nonempty) (h : s ⊆ t) : sSup s ≤ sSup t := csSup_le hs fun _ ha => le_csSup ht (h ha) -@[gcongr low] -theorem csInf_le_csInf (ht : BddBelow t) (hs : s.Nonempty) (h : s ⊆ t) : sInf t ≤ sInf s := - le_csInf hs fun _ ha => csInf_le ht (h ha) - -theorem le_csSup_iff (h : BddAbove s) (hs : s.Nonempty) : - a ≤ sSup s ↔ ∀ b, b ∈ upperBounds s → a ≤ b := +@[to_dual csInf_le_iff] +theorem le_csSup_iff (h : BddAbove s) (hs : s.Nonempty) : a ≤ sSup s ↔ ∀ b ∈ upperBounds s, a ≤ b := ⟨fun h _ hb => le_trans h (csSup_le hs hb), fun hb => hb _ fun _ => le_csSup h⟩ -theorem csInf_le_iff (h : BddBelow s) (hs : s.Nonempty) : sInf s ≤ a ↔ ∀ b ∈ lowerBounds s, b ≤ a := - ⟨fun h _ hb => le_trans (le_csInf hs hb) h, fun hb => hb _ fun _ => csInf_le h⟩ - @[to_dual] theorem IsLUB.csSup_eq (H : IsLUB s a) (ne : s.Nonempty) : sSup s = a := (isLUB_csSup ne ⟨a, H.1⟩).unique H @@ -233,80 +225,65 @@ instance (priority := 100) ConditionallyCompleteLattice.toConditionallyCompleteP theorem subset_Icc_csInf_csSup (hb : BddBelow s) (ha : BddAbove s) : s ⊆ Icc (sInf s) (sSup s) := fun _ hx => ⟨csInf_le hb hx, le_csSup ha hx⟩ +@[to_dual le_csInf_iff] theorem csSup_le_iff (hb : BddAbove s) (hs : s.Nonempty) : sSup s ≤ a ↔ ∀ b ∈ s, b ≤ a := isLUB_le_iff (isLUB_csSup hs hb) -theorem le_csInf_iff (hb : BddBelow s) (hs : s.Nonempty) : a ≤ sInf s ↔ ∀ b ∈ s, a ≤ b := - le_isGLB_iff (isGLB_csInf hs hb) - +@[to_dual] theorem csSup_lowerBounds_eq_csInf {s : Set α} (h : BddBelow s) (hs : s.Nonempty) : sSup (lowerBounds s) = sInf s := (isLUB_csSup h <| hs.mono fun _ hx _ hy => hy hx).unique (isGLB_csInf hs h).isLUB -theorem csInf_upperBounds_eq_csSup {s : Set α} (h : BddAbove s) (hs : s.Nonempty) : - sInf (upperBounds s) = sSup s := - (isGLB_csInf h <| hs.mono fun _ hx _ hy => hy hx).unique (isLUB_csSup hs h).isGLB - +@[to_dual] theorem csSup_lowerBounds_range [Nonempty β] {f : β → α} (hf : BddBelow (range f)) : sSup (lowerBounds (range f)) = ⨅ i, f i := csSup_lowerBounds_eq_csInf hf <| range_nonempty _ -theorem csInf_upperBounds_range [Nonempty β] {f : β → α} (hf : BddAbove (range f)) : - sInf (upperBounds (range f)) = ⨆ i, f i := - csInf_upperBounds_eq_csSup hf <| range_nonempty _ - +@[to_dual notMem_of_csSup_lt] theorem notMem_of_lt_csInf {x : α} {s : Set α} (h : x < sInf s) (hs : BddBelow s) : x ∉ s := fun hx => lt_irrefl _ (h.trans_le (csInf_le hs hx)) -theorem notMem_of_csSup_lt {x : α} {s : Set α} (h : sSup s < x) (hs : BddAbove s) : x ∉ s := - notMem_of_lt_csInf (α := αᵒᵈ) h hs - /-- Introduction rule to prove that `b` is the supremum of `s`: it suffices to check that `b` is larger than all elements of `s`, and that this is not the case of any `wb`. +See `sInf_eq_of_forall_ge_of_forall_gt_exists_lt` for a version in complete lattices. -/] theorem csSup_eq_of_forall_le_of_forall_lt_exists_gt (hs : s.Nonempty) (H : ∀ a ∈ s, a ≤ b) (H' : ∀ w, w < b → ∃ a ∈ s, w < a) : sSup s = b := (eq_of_le_of_not_lt (csSup_le hs H)) fun hb => let ⟨_, ha, ha'⟩ := H' _ hb lt_irrefl _ <| ha'.trans_le <| le_csSup ⟨b, H⟩ ha -/-- Introduction rule to prove that `b` is the infimum of `s`: it suffices to check that `b` -is smaller than all elements of `s`, and that this is not the case of any `w>b`. -See `sInf_eq_of_forall_ge_of_forall_gt_exists_lt` for a version in complete lattices. -/ -theorem csInf_eq_of_forall_ge_of_forall_gt_exists_lt : - s.Nonempty → (∀ a ∈ s, b ≤ a) → (∀ w, b < w → ∃ a ∈ s, a < w) → sInf s = b := - csSup_eq_of_forall_le_of_forall_lt_exists_gt (α := αᵒᵈ) - /-- `b < sSup s` when there is an element `a` in `s` with `b < a`, when `s` is bounded above. This is essentially an iff, except that the assumptions for the two implications are slightly different (one needs boundedness above for one direction, nonemptiness and linear order for the other one), so we formulate separately the two implications, contrary to the `CompleteLattice` case. -/ -theorem lt_csSup_of_lt (hs : BddAbove s) (ha : a ∈ s) (h : b < a) : b < sSup s := - lt_of_lt_of_le h (le_csSup hs ha) - +@[to_dual csInf_lt_of_lt /-- `sInf s < b` when there is an element `a` in `s` with `a < b`, when `s` is bounded below. This is essentially an iff, except that the assumptions for the two implications are slightly different (one needs boundedness below for one direction, nonemptiness and linear order for the other one), so we formulate separately the two implications, contrary to -the `CompleteLattice` case. -/ -theorem csInf_lt_of_lt : BddBelow s → a ∈ s → a < b → sInf s < b := - lt_csSup_of_lt (α := αᵒᵈ) +the `CompleteLattice` case. -/] +theorem lt_csSup_of_lt (hs : BddAbove s) (ha : a ∈ s) (h : b < a) : b < sSup s := + lt_of_lt_of_le h (le_csSup hs ha) /-- If all elements of a nonempty set `s` are less than or equal to all elements of a nonempty set `t`, then there exists an element between these sets. -/ +@[to_dual none] theorem exists_between_of_forall_le (sne : s.Nonempty) (tne : t.Nonempty) (hst : ∀ x ∈ s, ∀ y ∈ t, x ≤ y) : (upperBounds s ∩ lowerBounds t).Nonempty := ⟨sInf t, fun x hx => le_csInf tne <| hst x hx, fun _ hy => csInf_le (sne.mono hst) hy⟩ +@[to_dual] theorem csSup_pair (a b : α) : sSup {a, b} = a ⊔ b := (@isLUB_pair _ _ a b).csSup_eq (insert_nonempty _ _) -theorem csInf_pair (a b : α) : sInf {a, b} = a ⊓ b := - (@isGLB_pair _ _ a b).csInf_eq (insert_nonempty _ _) - /-- If a set is bounded below and above, and nonempty, its infimum is less than or equal to its supremum. -/ +@[to_dual self (reorder := hb ha)] theorem csInf_le_csSup (ne : s.Nonempty) (hb : BddBelow s := by bddDefault) (ha : BddAbove s := by bddDefault) : sInf s ≤ sSup s := isGLB_le_isLUB (isGLB_csInf ne hb) (isLUB_csSup ne ha) ne @@ -317,63 +294,40 @@ theorem csInf_le_csSup_of_nonempty_inter (h : (s ∩ t).Nonempty) (hs : BddBelow /-- The `sSup` of a union of two sets is the max of the suprema of each subset, under the assumptions that all sets are bounded above and nonempty. -/ +@[to_dual +/-- The `sInf` of a union of two sets is the min of the infima of each subset, under the assumptions +that all sets are bounded below and nonempty. -/] theorem csSup_union (hs : BddAbove s) (sne : s.Nonempty) (ht : BddAbove t) (tne : t.Nonempty) : sSup (s ∪ t) = sSup s ⊔ sSup t := ((isLUB_csSup sne hs).union (isLUB_csSup tne ht)).csSup_eq sne.inl -/-- The `sInf` of a union of two sets is the min of the infima of each subset, under the assumptions -that all sets are bounded below and nonempty. -/ -theorem csInf_union (hs : BddBelow s) (sne : s.Nonempty) (ht : BddBelow t) (tne : t.Nonempty) : - sInf (s ∪ t) = sInf s ⊓ sInf t := - csSup_union (α := αᵒᵈ) hs sne ht tne - /-- The supremum of an intersection of two sets is bounded by the minimum of the suprema of each set, if all sets are bounded above and nonempty. -/ +@[to_dual le_csInf_inter +/-- The infimum of an intersection of two sets is bounded below by the maximum of the +infima of each set, if all sets are bounded below and nonempty. -/] theorem csSup_inter_le (hs : BddAbove s) (ht : BddAbove t) (hst : (s ∩ t).Nonempty) : sSup (s ∩ t) ≤ sSup s ⊓ sSup t := (csSup_le hst) fun _ hx => le_inf (le_csSup hs hx.1) (le_csSup ht hx.2) -/-- The infimum of an intersection of two sets is bounded below by the maximum of the -infima of each set, if all sets are bounded below and nonempty. -/ -theorem le_csInf_inter : - BddBelow s → BddBelow t → (s ∩ t).Nonempty → sInf s ⊔ sInf t ≤ sInf (s ∩ t) := - csSup_inter_le (α := αᵒᵈ) - /-- The supremum of `insert a s` is the maximum of `a` and the supremum of `s`, if `s` is nonempty and bounded above. -/ -@[simp] +@[to_dual (attr := simp) +/-- The infimum of `insert a s` is the minimum of `a` and the infimum of `s`, if `s` is +nonempty and bounded below. -/] theorem csSup_insert (hs : BddAbove s) (sne : s.Nonempty) : sSup (insert a s) = a ⊔ sSup s := ((isLUB_csSup sne hs).insert a).csSup_eq (insert_nonempty a s) -/-- The infimum of `insert a s` is the minimum of `a` and the infimum of `s`, if `s` is -nonempty and bounded below. -/ -@[simp] -theorem csInf_insert (hs : BddBelow s) (sne : s.Nonempty) : sInf (insert a s) = a ⊓ sInf s := - csSup_insert (α := αᵒᵈ) hs sne - -@[simp] -theorem csInf_Ioc [DenselyOrdered α] (h : a < b) : sInf (Ioc a b) = a := - (isGLB_Ioc h).csInf_eq (nonempty_Ioc.2 h) - -@[simp] -theorem csInf_Ioi [NoMaxOrder α] [DenselyOrdered α] : sInf (Ioi a) = a := - csInf_eq_of_forall_ge_of_forall_gt_exists_lt nonempty_Ioi (fun _ => le_of_lt) fun w hw => by - simpa using exists_between hw - -@[simp] -theorem csInf_Ioo [DenselyOrdered α] (h : a < b) : sInf (Ioo a b) = a := - (isGLB_Ioo h).csInf_eq (nonempty_Ioo.2 h) - -@[simp] +@[to_dual (attr := simp)] theorem csSup_Ico [DenselyOrdered α] (h : a < b) : sSup (Ico a b) = b := (isLUB_Ico h).csSup_eq (nonempty_Ico.2 h) -@[simp] +@[to_dual (attr := simp)] theorem csSup_Iio [NoMinOrder α] [DenselyOrdered α] : sSup (Iio a) = a := csSup_eq_of_forall_le_of_forall_lt_exists_gt nonempty_Iio (fun _ => le_of_lt) fun w hw => by simpa [and_comm] using exists_between hw -@[simp] +@[to_dual (attr := simp)] theorem csSup_Ioo [DenselyOrdered α] (h : a < b) : sSup (Ioo a b) = b := (isLUB_Ioo h).csSup_eq (nonempty_Ioo.2 h) @@ -401,50 +355,40 @@ variable [ConditionallyCompleteLinearOrder α] {f : ι → α} {s : Set α} {a b /-- When `b < sSup s`, there is an element `a` in `s` with `b < a`, if `s` is nonempty and the order is a linear order. -/ +@[to_dual exists_lt_of_csInf_lt +/-- When `sInf s < b`, there is an element `a` in `s` with `a < b`, if `s` is nonempty and the order +is a linear order. -/] theorem exists_lt_of_lt_csSup (hs : s.Nonempty) (hb : b < sSup s) : ∃ a ∈ s, b < a := by contrapose! hb exact csSup_le hs hb -/-- When `sInf s < b`, there is an element `a` in `s` with `a < b`, if `s` is nonempty and the order -is a linear order. -/ -@[to_dual existing exists_lt_of_lt_csSup] -theorem exists_lt_of_csInf_lt (hs : s.Nonempty) (hb : sInf s < b) : ∃ a ∈ s, a < b := - exists_lt_of_lt_csSup (α := αᵒᵈ) hs hb - +@[to_dual csInf_lt_iff] theorem lt_csSup_iff (hb : BddAbove s) (hs : s.Nonempty) : a < sSup s ↔ ∃ b ∈ s, a < b := lt_isLUB_iff <| isLUB_csSup hs hb -theorem csInf_lt_iff (hb : BddBelow s) (hs : s.Nonempty) : sInf s < a ↔ ∃ b ∈ s, b < a := - isGLB_lt_iff <| isGLB_csInf hs hb - -@[simp] lemma csSup_of_not_bddAbove (hs : ¬BddAbove s) : sSup s = sSup ∅ := +@[to_dual (attr := simp)] +lemma csSup_of_not_bddAbove (hs : ¬BddAbove s) : sSup s = sSup ∅ := ConditionallyCompleteLinearOrder.csSup_of_not_bddAbove s hs -@[simp] lemma ciSup_of_not_bddAbove (hf : ¬BddAbove (range f)) : ⨆ i, f i = sSup ∅ := +@[to_dual (attr := simp)] +lemma ciSup_of_not_bddAbove (hf : ¬BddAbove (range f)) : ⨆ i, f i = sSup ∅ := csSup_of_not_bddAbove hf +@[to_dual] lemma csSup_eq_univ_of_not_bddAbove (hs : ¬BddAbove s) : sSup s = sSup univ := by rw [csSup_of_not_bddAbove hs, csSup_of_not_bddAbove (s := univ)] contrapose hs exact hs.mono (subset_univ _) +@[to_dual] lemma ciSup_eq_univ_of_not_bddAbove (hf : ¬BddAbove (range f)) : ⨆ i, f i = sSup univ := csSup_eq_univ_of_not_bddAbove hf -@[simp] lemma csInf_of_not_bddBelow (hs : ¬BddBelow s) : sInf s = sInf ∅ := - ConditionallyCompleteLinearOrder.csInf_of_not_bddBelow s hs - -@[simp] lemma ciInf_of_not_bddBelow (hf : ¬BddBelow (range f)) : ⨅ i, f i = sInf ∅ := - csInf_of_not_bddBelow hf - -lemma csInf_eq_univ_of_not_bddBelow (hs : ¬BddBelow s) : sInf s = sInf univ := - csSup_eq_univ_of_not_bddAbove (α := αᵒᵈ) hs - -lemma ciInf_eq_univ_of_not_bddBelow (hf : ¬BddBelow (range f)) : ⨅ i, f i = sInf univ := - csInf_eq_univ_of_not_bddBelow hf - /-- When every element of a set `s` is bounded by an element of a set `t`, and conversely, then `s` and `t` have the same supremum. This holds even when the sets may be empty or unbounded. -/ +@[to_dual +/-- When every element of a set `s` is bounded by an element of a set `t`, and conversely, then +`s` and `t` have the same infimum. This holds even when the sets may be empty or unbounded. -/] theorem csSup_eq_csSup_of_forall_exists_le {s t : Set α} (hs : ∀ x ∈ s, ∃ y ∈ t, x ≤ y) (ht : ∀ y ∈ t, ∃ x ∈ s, y ≤ x) : sSup s = sSup t := by @@ -476,13 +420,7 @@ theorem csSup_eq_csSup_of_forall_exists_le {s t : Set α} exact hyx.trans (le_csSup Bs xs) · simp [csSup_of_not_bddAbove, (not_or.1 B).1, (not_or.1 B).2] -/-- When every element of a set `s` is bounded by an element of a set `t`, and conversely, then -`s` and `t` have the same infimum. This holds even when the sets may be empty or unbounded. -/ -theorem csInf_eq_csInf_of_forall_exists_le {s t : Set α} - (hs : ∀ x ∈ s, ∃ y ∈ t, y ≤ x) (ht : ∀ y ∈ t, ∃ x ∈ s, x ≤ y) : - sInf s = sInf t := - csSup_eq_csSup_of_forall_exists_le (α := αᵒᵈ) hs ht - +@[to_dual le_csInf_union] theorem csSup_union_le (s t : Set α) : sSup (s ∪ t) ≤ sSup s ⊔ sSup t := by rcases s.eq_empty_or_nonempty with (rfl | hs) · simp @@ -491,6 +429,7 @@ theorem csSup_union_le (s t : Set α) : sSup (s ∪ t) ≤ sSup s ⊔ sSup t := by_cases BddAbove (s ∪ t) <;> grind [csSup_union, bddAbove_union, csSup_of_not_bddAbove] +@[to_dual] lemma sSup_iUnion_Iic (f : ι → α) : sSup (⋃ (i : ι), Iic (f i)) = ⨆ i, f i := by apply csSup_eq_csSup_of_forall_exists_le · rintro x ⟨-, ⟨i, rfl⟩, hi⟩ @@ -498,14 +437,9 @@ lemma sSup_iUnion_Iic (f : ι → α) : sSup (⋃ (i : ι), Iic (f i)) = ⨆ i, · rintro x ⟨i, rfl⟩ exact ⟨f i, mem_iUnion_of_mem i le_rfl, le_rfl⟩ -lemma sInf_iUnion_Ici (f : ι → α) : sInf (⋃ (i : ι), Ici (f i)) = ⨅ i, f i := - sSup_iUnion_Iic (α := αᵒᵈ) f - -theorem csInf_eq_bot_of_bot_mem [OrderBot α] {s : Set α} (hs : ⊥ ∈ s) : sInf s = ⊥ := - eq_bot_iff.2 <| csInf_le (OrderBot.bddBelow s) hs - +@[to_dual] theorem csSup_eq_top_of_top_mem [OrderTop α] {s : Set α} (hs : ⊤ ∈ s) : sSup s = ⊤ := - csInf_eq_bot_of_bot_mem (α := αᵒᵈ) hs + eq_top_iff.2 <| le_csSup (OrderTop.bddAbove s) hs open Function @@ -770,18 +704,16 @@ variable [ConditionallyCompleteLattice α] variable {f : α → β} {s : Set α} (hs : s.Nonempty) (hf : Monotone f) include hs hf +@[to_dual map_csInf_le_csInf_image] theorem csSup_image_le_map_csSup (hbdd : BddAbove s := by bddDefault) : sSup (f '' s) ≤ f (sSup s) := csSup_image_le hf hs <| isLUB_csSup hs hbdd |>.left -theorem map_csInf_le_csInf_image (hbdd : BddBelow s := by bddDefault) : - f (sInf s) ≤ sInf (f '' s) := - le_csInf_image hf hs <| isGLB_csInf hs hbdd |>.left - end ConditionallyCompleteLattice end Monotone +@[to_dual] lemma MonotoneOn.csInf_eq_of_subset_of_forall_exists_le [Preorder α] [ConditionallyCompleteLattice β] {f : α → β} {s t : Set α} (ht : BddBelow (f '' t)) (hf : MonotoneOn f t) @@ -797,13 +729,7 @@ lemma MonotoneOn.csInf_eq_of_subset_of_forall_exists_le obtain ⟨x, hxs, hxa⟩ := h a ha exact csInf_le_of_le (ht.mono (image_mono hst)) ⟨x, hxs, rfl⟩ (hf (hst hxs) ha hxa) -lemma MonotoneOn.csSup_eq_of_subset_of_forall_exists_le - [Preorder α] [ConditionallyCompleteLattice β] {f : α → β} - {s t : Set α} (ht : BddAbove (f '' t)) (hf : MonotoneOn f t) - (hst : s ⊆ t) (h : ∀ y ∈ t, ∃ x ∈ s, y ≤ x) : - sSup (f '' s) = sSup (f '' t) := - MonotoneOn.csInf_eq_of_subset_of_forall_exists_le (α := αᵒᵈ) (β := βᵒᵈ) ht hf.dual hst h - +@[to_dual] theorem MonotoneOn.sInf_image_Icc [Preorder α] [ConditionallyCompleteLattice β] {f : α → β} {a b : α} (hab : a ≤ b) (h' : MonotoneOn f (Icc a b)) : sInf (f '' Icc a b) = f a := by @@ -814,13 +740,7 @@ theorem MonotoneOn.sInf_image_Icc [Preorder α] [ConditionallyCompleteLattice β exact hb'.trans <| h' (left_mem_Icc.mpr hab) hx hx.1 · exact fun hb' ↦ hb' ⟨a, by simp [hab]⟩ -theorem MonotoneOn.sSup_image_Icc [Preorder α] [ConditionallyCompleteLattice β] - {f : α → β} {a b : α} (hab : a ≤ b) - (h' : MonotoneOn f (Icc a b)) : sSup (f '' Icc a b) = f b := by - have : Icc a b = Icc (α := αᵒᵈ) (toDual b) (toDual a) := by rw [Icc_toDual]; rfl - rw [this] at h' ⊢ - exact h'.dual_right.dual_left.sInf_image_Icc (β := βᵒᵈ) (α := αᵒᵈ) hab - +@[to_dual] theorem AntitoneOn.sInf_image_Icc [Preorder α] [ConditionallyCompleteLattice β] {f : α → β} {a b : α} (hab : a ≤ b) (h' : AntitoneOn f (Icc a b)) : sInf (f '' Icc a b) = f b := by @@ -828,11 +748,6 @@ theorem AntitoneOn.sInf_image_Icc [Preorder α] [ConditionallyCompleteLattice β rw [this] at h' ⊢ exact h'.dual_left.sInf_image_Icc (α := αᵒᵈ) hab -theorem AntitoneOn.sSup_image_Icc [Preorder α] [ConditionallyCompleteLattice β] - {f : α → β} {a b : α} (hab : a ≤ b) - (h' : AntitoneOn f (Icc a b)) : sSup (f '' Icc a b) = f a := - h'.dual_right.sInf_image_Icc hab - /-! ### Supremum/infimum of `Set.image2` @@ -846,49 +761,33 @@ variable [ConditionallyCompleteLattice α] [ConditionallyCompleteLattice β] [ConditionallyCompleteLattice γ] {s : Set α} {t : Set β} variable {l u : α → β → γ} {l₁ u₁ : β → γ → α} {l₂ u₂ : α → γ → β} +to_dual_name_hint L U, L₁ U₁, L₂ U₂ +@[to_dual] theorem csSup_image2_eq_csSup_csSup (h₁ : ∀ b, GaloisConnection (swap l b) (u₁ b)) (h₂ : ∀ a, GaloisConnection (l a) (u₂ a)) (hs₀ : s.Nonempty) (hs₁ : BddAbove s) (ht₀ : t.Nonempty) (ht₁ : BddAbove t) : sSup (image2 l s t) = l (sSup s) (sSup t) := isLUB_image2_of_isLUB_isLUB h₁ h₂ (isLUB_csSup hs₀ hs₁) (isLUB_csSup ht₀ ht₁) |>.csSup_eq (hs₀.image2 ht₀) +@[to_dual] theorem csSup_image2_eq_csSup_csInf (h₁ : ∀ b, GaloisConnection (swap l b) (u₁ b)) (h₂ : ∀ a, GaloisConnection (l a ∘ ofDual) (toDual ∘ u₂ a)) : s.Nonempty → BddAbove s → t.Nonempty → BddBelow t → sSup (image2 l s t) = l (sSup s) (sInf t) := csSup_image2_eq_csSup_csSup (β := βᵒᵈ) h₁ h₂ +@[to_dual] theorem csSup_image2_eq_csInf_csSup (h₁ : ∀ b, GaloisConnection (swap l b ∘ ofDual) (toDual ∘ u₁ b)) (h₂ : ∀ a, GaloisConnection (l a) (u₂ a)) : s.Nonempty → BddBelow s → t.Nonempty → BddAbove t → sSup (image2 l s t) = l (sInf s) (sSup t) := csSup_image2_eq_csSup_csSup (α := αᵒᵈ) h₁ h₂ +@[to_dual] theorem csSup_image2_eq_csInf_csInf (h₁ : ∀ b, GaloisConnection (swap l b ∘ ofDual) (toDual ∘ u₁ b)) (h₂ : ∀ a, GaloisConnection (l a ∘ ofDual) (toDual ∘ u₂ a)) : s.Nonempty → BddBelow s → t.Nonempty → BddBelow t → sSup (image2 l s t) = l (sInf s) (sInf t) := csSup_image2_eq_csSup_csSup (α := αᵒᵈ) (β := βᵒᵈ) h₁ h₂ -theorem csInf_image2_eq_csInf_csInf (h₁ : ∀ b, GaloisConnection (l₁ b) (swap u b)) - (h₂ : ∀ a, GaloisConnection (l₂ a) (u a)) (hs₀ : s.Nonempty) (hs₁ : BddBelow s) - (ht₀ : t.Nonempty) (ht₁ : BddBelow t) : sInf (image2 u s t) = u (sInf s) (sInf t) := - isGLB_image2_of_isGLB_isGLB h₁ h₂ (isGLB_csInf hs₀ hs₁) (isGLB_csInf ht₀ ht₁) - |>.csInf_eq (hs₀.image2 ht₀) - -theorem csInf_image2_eq_csInf_csSup (h₁ : ∀ b, GaloisConnection (l₁ b) (swap u b)) - (h₂ : ∀ a, GaloisConnection (toDual ∘ l₂ a) (u a ∘ ofDual)) : - s.Nonempty → BddBelow s → t.Nonempty → BddAbove t → sInf (image2 u s t) = u (sInf s) (sSup t) := - csInf_image2_eq_csInf_csInf (β := βᵒᵈ) h₁ h₂ - -theorem csInf_image2_eq_csSup_csInf (h₁ : ∀ b, GaloisConnection (toDual ∘ l₁ b) (swap u b ∘ ofDual)) - (h₂ : ∀ a, GaloisConnection (l₂ a) (u a)) : - s.Nonempty → BddAbove s → t.Nonempty → BddBelow t → sInf (image2 u s t) = u (sSup s) (sInf t) := - csInf_image2_eq_csInf_csInf (α := αᵒᵈ) h₁ h₂ - -theorem csInf_image2_eq_csSup_csSup (h₁ : ∀ b, GaloisConnection (toDual ∘ l₁ b) (swap u b ∘ ofDual)) - (h₂ : ∀ a, GaloisConnection (toDual ∘ l₂ a) (u a ∘ ofDual)) : - s.Nonempty → BddAbove s → t.Nonempty → BddAbove t → sInf (image2 u s t) = u (sSup s) (sSup t) := - csInf_image2_eq_csInf_csInf (α := αᵒᵈ) (β := βᵒᵈ) h₁ h₂ - end section WithTopBot @@ -918,18 +817,13 @@ noncomputable instance WithTop.conditionallyCompleteLattice {α : Type*} isLUB_csSup _ hS _ := WithTop.isLUB_sSup' hS isGLB_csInf _ _ hS := WithTop.isGLB_sInf' hS +@[to_dual] noncomputable instance [CompleteLattice α] : CompleteLattice (WithTop α) where isLUB_sSup s := ⟨fun _ ↦ le_csSup (OrderTop.bddAbove _), fun _ has ↦ s.eq_empty_or_nonempty.elim (by simp [·, WithTop.sSup_empty]) (csSup_le · has)⟩ isGLB_sInf s := ⟨fun _ ↦ csInf_le (OrderBot.bddBelow _), fun _ hsa ↦ s.eq_empty_or_nonempty.elim (by simp [·]) (le_csInf · hsa)⟩ -noncomputable instance [CompleteLattice α] : CompleteLattice (WithBot α) where - isLUB_sSup s := ⟨fun _ ↦ le_csSup (OrderTop.bddAbove _), fun _ hsa ↦ - s.eq_empty_or_nonempty.elim (by simp [·]) (csSup_le · hsa)⟩ - isGLB_sInf s := ⟨fun _ ↦ csInf_le (OrderBot.bddBelow _), fun _ has ↦ - s.eq_empty_or_nonempty.elim (by simp [·, WithBot.sInf_empty]) (le_csInf · has)⟩ - noncomputable instance [CompleteLinearOrder α] : CompleteLinearOrder (WithBot α) where __ := WithBot.linearOrder __ := WithBot.linearOrder.toBiheytingAlgebra @@ -955,6 +849,7 @@ noncomputable instance [ConditionallyCompleteLinearOrder α] : csSup_empty := WithBot.sSup_empty open scoped Classical in +@[to_dual WithBot.WithTop.completeLattice] noncomputable instance WithTop.WithBot.completeLattice {α : Type*} [ConditionallyCompleteLattice α] : CompleteLattice (WithTop (WithBot α)) where isLUB_sSup S := ⟨fun a haS ↦ (WithTop.isLUB_sSup' ⟨a, haS⟩).1 haS, fun a ha ↦ by @@ -978,11 +873,6 @@ noncomputable instance WithTop.WithBot.completeLattice {α : Type*} exact bot_le, fun a haS ↦ (WithTop.isGLB_sInf' ⟨a, haS⟩).2 haS⟩ -noncomputable instance WithBot.WithTop.completeLattice {α : Type*} - [ConditionallyCompleteLattice α] : CompleteLattice (WithBot (WithTop α)) where - isLUB_sSup := (WithTop.WithBot.completeLattice (α := αᵒᵈ)).isGLB_sInf - isGLB_sInf := (WithTop.WithBot.completeLattice (α := αᵒᵈ)).isLUB_sSup - noncomputable instance WithBot.WithTop.completeLinearOrder {α : Type*} [ConditionallyCompleteLinearOrder α] : CompleteLinearOrder (WithBot (WithTop α)) where __ := completeLattice diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean b/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean index 57b7624b40b3e7..c534b3172d6739 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean @@ -81,6 +81,8 @@ class ConditionallyCompleteLinearOrder (α : Type*) compare_eq_compareOfLessAndEq : ∀ a b, compare a b = compareOfLessAndEq a b := by compareOfLessAndEq_rfl +attribute [to_dual existing] ConditionallyCompleteLinearOrder.csSup_of_not_bddAbove + /-- A conditionally complete linear order with `Bot` is a linear order with least element, in which every nonempty subset which is bounded above has a supremum, and every nonempty subset (necessarily bounded below) has an infimum. A typical example is the natural numbers. From f7442295c4cd7cf1001828d1ce326e335a4ecf45 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:33 +0000 Subject: [PATCH 1224/1300] chore(Data/List/MinMax): use `to_dual` (#41559) This PR uses `to_dual` to translate some theorems about maxima and minima on lists. --- Mathlib/Data/List/MinMax.lean | 224 ++++++--------------------- Mathlib/Tactic/ToDual.lean | 6 +- Mathlib/Tactic/Translate/ToDual.lean | 10 +- 3 files changed, 61 insertions(+), 179 deletions(-) diff --git a/Mathlib/Data/List/MinMax.lean b/Mathlib/Data/List/MinMax.lean index c9d03269f411d7..420af3ab5fc1ff 100644 --- a/Mathlib/Data/List/MinMax.lean +++ b/Mathlib/Data/List/MinMax.lean @@ -82,75 +82,51 @@ variable [Preorder β] [DecidableLT β] {f : α → β} {l : List α} {a m : α} /-- `argmax f l` returns `some a`, where `f a` is maximal among the elements of `l`, in the sense that there is no `b ∈ l` with `f a < f b`. If `a`, `b` are such that `f a = f b`, it returns whichever of `a` or `b` comes first in the list. `argmax f [] = none`. -/ -def argmax (f : α → β) (l : List α) : Option α := - l.foldl (argAux fun b c => f c < f b) none - +@[to_dual /-- `argmin f l` returns `some a`, where `f a` is minimal among the elements of `l`, in the sense that there is no `b ∈ l` with `f b < f a`. If `a`, `b` are such that `f a = f b`, it returns -whichever of `a` or `b` comes first in the list. `argmin f [] = none`. -/ -def argmin (f : α → β) (l : List α) := - l.foldl (argAux fun b c => f b < f c) none +whichever of `a` or `b` comes first in the list. `argmin f [] = none`. -/] +def argmax (f : α → β) (l : List α) : Option α := + l.foldl (argAux fun b c => f c < f b) none -@[simp] +@[to_dual (attr := simp)] theorem argmax_nil (f : α → β) : argmax f [] = none := rfl -@[simp] -theorem argmin_nil (f : α → β) : argmin f [] = none := - rfl - -@[simp] +@[to_dual (attr := simp)] theorem argmax_singleton {f : α → β} {a : α} : argmax f [a] = a := rfl -@[simp] -theorem argmin_singleton {f : α → β} {a : α} : argmin f [a] = a := - rfl - +@[to_dual] theorem not_lt_of_mem_argmax : a ∈ l → m ∈ argmax f l → ¬f m < f a := not_of_mem_foldl_argAux _ ⟨fun x h => lt_irrefl (f x) h⟩ ⟨fun _ _ z hxy hyz => lt_trans (a := f z) hyz hxy⟩ -theorem not_lt_of_mem_argmin : a ∈ l → m ∈ argmin f l → ¬f a < f m := - not_of_mem_foldl_argAux _ ⟨fun x h => lt_irrefl (f x) h⟩ - ⟨fun x _ _ hxy hyz => lt_trans (a := f x) hxy hyz⟩ - +@[to_dual] theorem argmax_concat (f : α → β) (a : α) (l : List α) : argmax f (l ++ [a]) = Option.casesOn (argmax f l) (some a) fun c => if f c < f a then some a else some c := by rw [argmax, argmax]; simp [argAux] -theorem argmin_concat (f : α → β) (a : α) (l : List α) : - argmin f (l ++ [a]) = - Option.casesOn (argmin f l) (some a) fun c => if f a < f c then some a else some c := - @argmax_concat _ βᵒᵈ _ _ _ _ _ - +@[to_dual] theorem argmax_mem : ∀ {l : List α} {m : α}, m ∈ argmax f l → m ∈ l | [], m => by simp | hd :: tl, m => by simpa [argmax, argAux] using foldl_argAux_mem _ tl hd m -theorem argmin_mem : ∀ {l : List α} {m : α}, m ∈ argmin f l → m ∈ l := - @argmax_mem _ βᵒᵈ _ _ _ - -@[simp] +@[to_dual (attr := simp)] theorem argmax_eq_none : l.argmax f = none ↔ l = [] := by simp [argmax] -@[simp] -theorem argmin_eq_none : l.argmin f = none ↔ l = [] := - @argmax_eq_none _ βᵒᵈ _ _ _ _ - end Preorder section LinearOrder variable [LinearOrder β] {f : α → β} {l : List α} {a m : α} +@[to_dual] theorem le_of_mem_argmax : a ∈ l → m ∈ argmax f l → f a ≤ f m := fun ha hm => le_of_not_gt <| not_lt_of_mem_argmax ha hm -theorem le_of_mem_argmin : a ∈ l → m ∈ argmin f l → f m ≤ f a := - @le_of_mem_argmax _ βᵒᵈ _ _ _ _ _ - +@[to_dual] theorem argmax_cons (f : α → β) (a : α) (l : List α) : argmax f (a :: l) = Option.casesOn (argmax f l) (some a) fun c => if f a < f c then some c else some a := @@ -160,15 +136,11 @@ theorem argmax_cons (f : α → β) (a : α) (l : List α) : · simp dsimp rw [← apply_ite, ← apply_ite] - grind - -theorem argmin_cons (f : α → β) (a : α) (l : List α) : - argmin f (a :: l) = - Option.casesOn (argmin f l) (some a) fun c => if f c < f a then some c else some a := - @argmax_cons α βᵒᵈ _ _ _ _ + grind -abstractProof -- Without `-abstractProof`, `to_dual` gives an error. variable [DecidableEq α] +@[to_dual] theorem index_of_argmax : ∀ {l : List α} {m : α}, m ∈ argmax f l → ∀ {a}, a ∈ l → f m ≤ f a → l.idxOf m ≤ l.idxOf a | [], m, _, _, _, _ => by simp @@ -190,10 +162,7 @@ theorem index_of_argmax : · rw [if_pos rfl] exact Nat.zero_le _ -theorem index_of_argmin : - ∀ {l : List α} {m : α}, m ∈ argmin f l → ∀ {a}, a ∈ l → f a ≤ f m → l.idxOf m ≤ l.idxOf a := - @index_of_argmax _ βᵒᵈ _ _ _ - +@[to_dual] theorem mem_argmax_iff : m ∈ argmax f l ↔ m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.idxOf m ≤ l.idxOf a := @@ -207,21 +176,12 @@ theorem mem_argmax_iff : (index_of_argmax harg hml (ham _ (argmax_mem harg))) rw [(idxOf_inj hml).1 this, Option.mem_def]⟩ +@[to_dual] theorem argmax_eq_some_iff : argmax f l = some m ↔ m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.idxOf m ≤ l.idxOf a := mem_argmax_iff -theorem mem_argmin_iff : - m ∈ argmin f l ↔ - m ∈ l ∧ (∀ a ∈ l, f m ≤ f a) ∧ ∀ a ∈ l, f a ≤ f m → l.idxOf m ≤ l.idxOf a := - @mem_argmax_iff _ βᵒᵈ _ _ _ _ _ - -theorem argmin_eq_some_iff : - argmin f l = some m ↔ - m ∈ l ∧ (∀ a ∈ l, f m ≤ f a) ∧ ∀ a ∈ l, f a ≤ f m → l.idxOf m ≤ l.idxOf a := - mem_argmin_iff - end LinearOrder section MaximumMinimum @@ -232,56 +192,36 @@ variable [Preorder α] [DecidableLT α] {l : List α} {a m : α} /-- `maximum l` returns a `WithBot α`, the largest element of `l` for nonempty lists, and `⊥` for `[]` -/ +@[to_dual +/-- `minimum l` returns a `WithTop α`, the smallest element of `l` for nonempty lists, and `⊤` for +`[]` -/] def maximum (l : List α) : WithBot α := argmax id l -/-- `minimum l` returns a `WithTop α`, the smallest element of `l` for nonempty lists, and `⊤` for -`[]` -/ -def minimum (l : List α) : WithTop α := - argmin id l - -@[simp] +@[to_dual (attr := simp)] theorem maximum_nil : maximum ([] : List α) = ⊥ := rfl -@[simp] -theorem minimum_nil : minimum ([] : List α) = ⊤ := - rfl - -@[simp] +@[to_dual (attr := simp)] theorem maximum_singleton (a : α) : maximum [a] = a := rfl -@[simp] -theorem minimum_singleton (a : α) : minimum [a] = a := - rfl - +@[to_dual] theorem maximum_mem {l : List α} {m : α} : (maximum l : WithTop α) = m → m ∈ l := argmax_mem -theorem minimum_mem {l : List α} {m : α} : (minimum l : WithBot α) = m → m ∈ l := - argmin_mem - -@[simp] +@[to_dual (attr := simp)] theorem maximum_eq_bot {l : List α} : l.maximum = ⊥ ↔ l = [] := argmax_eq_none -@[simp] -theorem minimum_eq_top {l : List α} : l.minimum = ⊤ ↔ l = [] := - argmin_eq_none - +@[to_dual not_lt_minimum_of_mem] theorem not_maximum_lt_of_mem : a ∈ l → (maximum l : WithBot α) = m → ¬m < a := not_lt_of_mem_argmax -theorem not_lt_minimum_of_mem : a ∈ l → (minimum l : WithTop α) = m → ¬a < m := - not_lt_of_mem_argmin - +@[to_dual not_lt_minimum_of_mem'] theorem not_maximum_lt_of_mem' (ha : a ∈ l) : ¬maximum l < (a : WithBot α) := by cases h : l.maximum <;> simp_all [not_maximum_lt_of_mem ha] -theorem not_lt_minimum_of_mem' (ha : a ∈ l) : ¬(a : WithTop α) < minimum l := by - cases h : l.minimum <;> simp_all [not_lt_minimum_of_mem ha] - end Preorder section LinearOrder @@ -289,42 +229,33 @@ section LinearOrder variable [LinearOrder α] {l : List α} {a m : α} set_option backward.isDefEq.respectTransparency false in +@[to_dual] theorem maximum_concat (a : α) (l : List α) : maximum (l ++ [a]) = max (maximum l) a := by simp only [maximum, argmax_concat, id] cases argmax id l · exact (max_eq_right bot_le).symm · simp [WithBot.some_eq_coe, max_def_lt, WithBot.coe_lt_coe] +@[to_dual minimum_le_of_mem] theorem le_maximum_of_mem : a ∈ l → (maximum l : WithBot α) = m → a ≤ m := le_of_mem_argmax -theorem minimum_le_of_mem : a ∈ l → (minimum l : WithTop α) = m → m ≤ a := - le_of_mem_argmin - +@[to_dual minimum_le_of_mem'] theorem le_maximum_of_mem' (ha : a ∈ l) : (a : WithBot α) ≤ maximum l := le_of_not_gt <| not_maximum_lt_of_mem' ha -theorem minimum_le_of_mem' (ha : a ∈ l) : minimum l ≤ (a : WithTop α) := - le_of_not_gt <| not_lt_minimum_of_mem' ha - -theorem minimum_concat (a : α) (l : List α) : minimum (l ++ [a]) = min (minimum l) a := - @maximum_concat αᵒᵈ _ _ _ - +@[to_dual] theorem maximum_cons (a : α) (l : List α) : maximum (a :: l) = max ↑a (maximum l) := List.reverseRecOn l (by simp) fun tl hd ih => by rw [← cons_append, maximum_concat, ih, maximum_concat, max_assoc] -theorem minimum_cons (a : α) (l : List α) : minimum (a :: l) = min ↑a (minimum l) := - @maximum_cons αᵒᵈ _ _ _ - +@[to_dual] lemma maximum_append (l₁ l₂ : List α) : (l₁ ++ l₂).maximum = max l₁.maximum l₂.maximum := by induction l₁ with | nil => simp | cons _ _ ih => rw [maximum_cons, cons_append, maximum_cons, ih, ← max_assoc] -lemma minimum_append (l₁ l₂ : List α) : (l₁ ++ l₂).minimum = min l₁.minimum l₂.minimum := - @maximum_append αᵒᵈ _ _ _ - +@[to_dual le_minimum_of_forall_le] theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l.maximum ≤ b := by induction l with | nil => simp @@ -332,110 +263,70 @@ theorem maximum_le_of_forall_le {b : WithBot α} (h : ∀ a ∈ l, a ≤ b) : l. simp only [maximum_cons, max_le_iff] exact ⟨h a (by simp), ih fun a w => h a (mem_cons.mpr (Or.inr w))⟩ -theorem le_minimum_of_forall_le {b : WithTop α} (h : ∀ a ∈ l, b ≤ a) : b ≤ l.minimum := by - induction l with - | nil => simp - | cons a l ih => - simp only [minimum_cons, le_min_iff] - exact ⟨h a (by simp), ih fun a w => h a (mem_cons.mpr (Or.inr w))⟩ - +@[to_dual minimum_anti] theorem maximum_mono {l₁ l₂ : List α} (h : l₁ ⊆ l₂) : l₁.maximum ≤ l₂.maximum := maximum_le_of_forall_le fun _ ↦ (le_maximum_of_mem' <| h ·) -theorem minimum_anti {l₁ l₂ : List α} (h : l₁ ⊆ l₂) : l₂.minimum ≤ l₁.minimum := - @maximum_mono αᵒᵈ _ _ _ h - set_option backward.isDefEq.respectTransparency false in +@[to_dual] theorem maximum_eq_coe_iff : maximum l = m ↔ m ∈ l ∧ ∀ a ∈ l, a ≤ m := by rw [maximum, ← WithBot.some_eq_coe, argmax_eq_some_iff] simp only [id_eq, and_congr_right_iff, and_iff_left_iff_imp] intro _ h a hal hma rw [_root_.le_antisymm hma (h a hal)] -theorem minimum_eq_coe_iff : minimum l = m ↔ m ∈ l ∧ ∀ a ∈ l, m ≤ a := - @maximum_eq_coe_iff αᵒᵈ _ _ _ - +@[to_dual minimum_le_coe_iff] theorem coe_le_maximum_iff : a ≤ l.maximum ↔ ∃ b, b ∈ l ∧ a ≤ b := by induction l <;> simp [maximum_cons, *] -theorem minimum_le_coe_iff : l.minimum ≤ a ↔ ∃ b, b ∈ l ∧ b ≤ a := by - induction l <;> simp [minimum_cons, *] - +@[to_dual] theorem maximum_ne_bot_of_ne_nil (h : l ≠ []) : l.maximum ≠ ⊥ := match l, h with | _ :: _, _ => by simp [maximum_cons] -theorem minimum_ne_top_of_ne_nil (h : l ≠ []) : l.minimum ≠ ⊤ := - @maximum_ne_bot_of_ne_nil αᵒᵈ _ _ h - +@[to_dual] theorem maximum_ne_bot_of_length_pos (h : 0 < l.length) : l.maximum ≠ ⊥ := match l, h with | _ :: _, _ => by simp [maximum_cons] -theorem minimum_ne_top_of_length_pos (h : 0 < l.length) : l.minimum ≠ ⊤ := - maximum_ne_bot_of_length_pos (α := αᵒᵈ) h - /-- The maximum value in a non-empty `List`. -/ +@[to_dual /-- The minimum value in a non-empty `List`. -/] def maximum_of_length_pos (h : 0 < l.length) : α := WithBot.unbot l.maximum (maximum_ne_bot_of_length_pos h) -/-- The minimum value in a non-empty `List`. -/ -def minimum_of_length_pos (h : 0 < l.length) : α := - maximum_of_length_pos (α := αᵒᵈ) h - -@[simp] +@[to_dual (attr := simp)] lemma coe_maximum_of_length_pos (h : 0 < l.length) : (l.maximum_of_length_pos h : α) = l.maximum := WithBot.coe_unbot _ _ -@[simp] -lemma coe_minimum_of_length_pos (h : 0 < l.length) : - (l.minimum_of_length_pos h : α) = l.minimum := - WithTop.coe_untop _ _ - -@[simp] +@[to_dual (attr := simp) minimum_of_length_pos_le_iff] theorem le_maximum_of_length_pos_iff {b : α} (h : 0 < l.length) : b ≤ maximum_of_length_pos h ↔ b ≤ l.maximum := WithBot.le_unbot_iff _ -@[simp] -theorem minimum_of_length_pos_le_iff {b : α} (h : 0 < l.length) : - minimum_of_length_pos h ≤ b ↔ l.minimum ≤ b := - WithTop.untop_le_iff _ - +@[to_dual] theorem maximum_of_length_pos_mem (h : 0 < l.length) : maximum_of_length_pos h ∈ l := by apply maximum_mem simp only [coe_maximum_of_length_pos] -theorem minimum_of_length_pos_mem (h : 0 < l.length) : - minimum_of_length_pos h ∈ l := - maximum_of_length_pos_mem (α := αᵒᵈ) h - +@[to_dual minimum_of_length_pos_le_of_mem] theorem le_maximum_of_length_pos_of_mem (h : a ∈ l) (w : 0 < l.length) : a ≤ l.maximum_of_length_pos w := by simp only [le_maximum_of_length_pos_iff] exact le_maximum_of_mem' h -theorem minimum_of_length_pos_le_of_mem (h : a ∈ l) (w : 0 < l.length) : - l.minimum_of_length_pos w ≤ a := - le_maximum_of_length_pos_of_mem (α := αᵒᵈ) h w - +@[to_dual minimum_of_length_pos_le_getElem] theorem getElem_le_maximum_of_length_pos {i : ℕ} (w : i < l.length) (h := (Nat.zero_lt_of_lt w)) : l[i] ≤ l.maximum_of_length_pos h := by apply le_maximum_of_length_pos_of_mem exact getElem_mem _ -theorem minimum_of_length_pos_le_getElem {i : ℕ} (w : i < l.length) (h := (Nat.zero_lt_of_lt w)) : - l.minimum_of_length_pos h ≤ l[i] := - getElem_le_maximum_of_length_pos (α := αᵒᵈ) w - +@[to_dual] theorem Perm.maximum_eq {l l' : List α} (h : l ~ l') : l.maximum = l'.maximum := by induction h with grind [maximum_cons] -theorem Perm.minimum_eq {l l' : List α} (h : l ~ l') : - l.minimum = l'.minimum := by - induction h with grind [minimum_cons] +@[to_dual] lemma getD_max?_eq_unbotD_maximum (l : List α) (d : α) : l.max?.getD d = l.maximum.unbotD d := by cases hy : l.maximum with | bot => simp [List.maximum_eq_bot.mp hy] @@ -450,9 +341,6 @@ lemma getD_max?_eq_unbotD_maximum (l : List α) (d : α) : l.max?.getD d = l.max · rw [Option.getD_some] exact _root_.le_antisymm (hy.right _ hz.left) (hz.right _ hy.left) -lemma getD_min?_eq_untopD_minimum (l : List α) (d : α) : l.min?.getD d = l.minimum.untopD d := - getD_max?_eq_unbotD_maximum (α := αᵒᵈ) _ _ - end LinearOrder end MaximumMinimum @@ -465,7 +353,7 @@ section OrderBot variable [OrderBot α] {l : List α} -@[simp] +@[to_dual (attr := simp)] theorem foldr_max_of_ne_nil (h : l ≠ []) : ↑(l.foldr max ⊥) = l.maximum := by induction l with | nil => contradiction @@ -475,11 +363,13 @@ theorem foldr_max_of_ne_nil (h : l ≠ []) : ↑(l.foldr max ⊥) = l.maximum := · simp [h] · simp [IH h] +@[to_dual le_min_of_forall_le] theorem max_le_of_forall_le (l : List α) (a : α) (h : ∀ x ∈ l, x ≤ a) : l.foldr max ⊥ ≤ a := by induction l with | nil => simp | cons y l IH => simpa [h y mem_cons_self] using IH fun x hx => h x <| mem_cons_of_mem _ hx +@[to_dual min_le_of_le] theorem le_max_of_le {l : List α} {a x : α} (hx : x ∈ l) (h : a ≤ x) : a ≤ l.foldr max ⊥ := by induction l with | nil => exact absurd hx not_mem_nil @@ -491,23 +381,8 @@ theorem le_max_of_le {l : List α} {a x : α} (hx : x ∈ l) (h : a ≤ x) : a end OrderBot -section OrderTop - -variable [OrderTop α] {l : List α} - -@[simp] -theorem foldr_min_of_ne_nil (h : l ≠ []) : ↑(l.foldr min ⊤) = l.minimum := - @foldr_max_of_ne_nil αᵒᵈ _ _ _ h - -theorem le_min_of_forall_le (l : List α) (a : α) (h : ∀ x ∈ l, a ≤ x) : a ≤ l.foldr min ⊤ := - @max_le_of_forall_le αᵒᵈ _ _ _ _ h - -theorem min_le_of_le (l : List α) (a : α) {x : α} (hx : x ∈ l) (h : x ≤ a) : l.foldr min ⊤ ≤ a := - @le_max_of_le αᵒᵈ _ _ _ _ _ hx h - -end OrderTop - /-- If `a ≤ x` for some `x` in the list `l`, and `b : α`, then `a ≤ l.foldr max b`. -/ +@[to_dual min_le_of_le'] theorem le_max_of_le' {l : List α} {a x : α} (b : α) (hx : x ∈ l) (h : a ≤ x) : a ≤ l.foldr max b := by induction l with @@ -518,9 +393,6 @@ theorem le_max_of_le' {l : List α} {a x : α} (b : α) (hx : x ∈ l) (h : a · exact le_max_of_le_left h · exact le_max_of_le_right (IH hl) -theorem min_le_of_le' {l : List α} {a x : α} (b : α) (hx : x ∈ l) (h : x ≤ a) : l.foldr min b ≤ a := - @le_max_of_le' αᵒᵈ _ _ _ _ _ hx h - end Fold end List diff --git a/Mathlib/Tactic/ToDual.lean b/Mathlib/Tactic/ToDual.lean index 525c314bac9394..f4c84763a825d9 100644 --- a/Mathlib/Tactic/ToDual.lean +++ b/Mathlib/Tactic/ToDual.lean @@ -33,7 +33,11 @@ attribute [to_dual lt_of_lt_of_eq''] lt_of_lt_of_eq attribute [to_dual] Max -attribute [to_dual existing] Std.LawfulOrderSup +attribute [to_dual existing] Std.MaxEqOr Std.LawfulOrderSup Std.LawfulOrderMax + Std.LawfulOrderLeftLeaningMax + Std.instLawfulOrderMaxOfIsLinearPreorderOfLawfulOrderLeftLeaningMax + Std.instLawfulOrderLeftLeaningMaxOfIsLinearOrderOfLawfulOrderSup + List.max? List.max?_eq_none_iff List.max?_eq_some_iff -- We need to tag the lemmas used by `grind` in order to translate `grind` proofs. namespace Lean.Grind.Order diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index e1693f2cb87f4e..e1e4f427d62382 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -151,6 +151,8 @@ initialize translations : NameMapExtension TranslationInfo ← registerNameMapEx def nameDict : Std.HashMap String (List String) := .ofList [ ("top", ["Bot"]), ("bot", ["Top"]), + ("untop", ["Unbot"]), + ("unbot", ["Untop"]), ("inf", ["Sup"]), ("sup", ["Inf"]), ("inf₂", ["Sup₂"]), @@ -159,8 +161,12 @@ def nameDict : Std.HashMap String (List String) := .ofList [ ("ssup", ["SInf"]), ("min", ["Max"]), ("max", ["Min"]), - ("untop", ["Unbot"]), - ("unbot", ["Untop"]), + ("min?", ["Max?"]), + ("max?", ["Min?"]), + ("argmin", ["Argmax"]), + ("argmax", ["Argmin"]), + ("minimum", ["Maximum"]), + ("maximum", ["Minimum"]), ("minimal", ["Maximal"]), ("maximal", ["Minimal"]), ("lower", ["Upper"]), From 035c18ddc9f565ffd3990185ccf2e72e9d3bc1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:35 +0000 Subject: [PATCH 1225/1300] feat(Order/Fin): conditions for `Fin.insertNth` to be monotone or strictly monotone (#41617) --- Mathlib.lean | 1 + Mathlib/Order/Fin/InsertNth.lean | 85 ++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 Mathlib/Order/Fin/InsertNth.lean diff --git a/Mathlib.lean b/Mathlib.lean index 961a2e701bcac8..4aac5224fd24fa 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6116,6 +6116,7 @@ public import Mathlib.Order.Filter.ZeroAndBoundedAtFilter public import Mathlib.Order.Fin.Basic public import Mathlib.Order.Fin.Clamp public import Mathlib.Order.Fin.Finset +public import Mathlib.Order.Fin.InsertNth public import Mathlib.Order.Fin.SuccAboveOrderIso public import Mathlib.Order.Fin.Tuple public import Mathlib.Order.FixedPoints diff --git a/Mathlib/Order/Fin/InsertNth.lean b/Mathlib/Order/Fin/InsertNth.lean new file mode 100644 index 00000000000000..a87e0ae988bcb4 --- /dev/null +++ b/Mathlib/Order/Fin/InsertNth.lean @@ -0,0 +1,85 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Data.Fin.Tuple.Basic + +/-! +# Conditions for `Fin.insertNth` to be monotone or strictly monotone + +-/ + +public section + +namespace Fin + +variable {n : ℕ} {α : Type*} [Preorder α] + +lemma insertNth_zero_monotone + {f : Fin (n + 1) → α} (hf : Monotone f) (x : α) (hx : x ≤ f 0) : + Monotone (Fin.insertNth 0 (α := fun _ ↦ α) x f) := by + rw [Fin.monotone_iff_le_succ] + intro i + obtain rfl | ⟨i, rfl⟩ := i.eq_zero_or_eq_succ + · simpa + · simpa using hf i.castSucc_le_succ + +lemma strictMono_insertNth_zero + {f : Fin (n + 1) → α} (hf : StrictMono f) (x : α) (hx : x < f 0) : + StrictMono (Fin.insertNth 0 (α := fun _ ↦ α) x f) := by + rw [Fin.strictMono_iff_lt_succ] at hf ⊢ + intro i + obtain rfl | ⟨i, rfl⟩ := i.eq_zero_or_eq_succ + · simpa + · simpa using hf i + +lemma insertNth_monotone + {f : Fin (n + 1) → α} (hf : Monotone f) (i : Fin n) (x : α) + (hx₁ : f i.castSucc ≤ x) (hx₂ : x ≤ f i.succ) : + Monotone (Fin.insertNth i.castSucc.succ (α := fun _ ↦ α) x f) := by + rw [Fin.monotone_iff_le_succ] + intro j + obtain hj | rfl | hj := lt_trichotomy j i.castSucc + · obtain ⟨j, rfl⟩ := j.eq_castSucc_of_ne_last (Fin.ne_last_of_lt hj) + grind [insertNth_apply_below, castPred_castSucc, hf j.castSucc_le_succ] + · rwa [← succAbove_succ_self i.castSucc, insertNth_apply_succAbove, insertNth_apply_same] + · obtain ⟨j, rfl⟩ := j.eq_succ_of_ne_zero (Fin.ne_zero_of_lt hj) + grind [insertNth_apply_same, insertNth_apply_above, hf j.castSucc_le_succ] + +lemma strictMono_insertNth + {f : Fin (n + 1) → α} (hf : StrictMono f) (i : Fin n) (x : α) + (hx₁ : f i.castSucc < x) (hx₂ : x < f i.succ) : + StrictMono (Fin.insertNth i.castSucc.succ (α := fun _ ↦ α) x f) := by + rw [Fin.strictMono_iff_lt_succ] at hf ⊢ + intro j + obtain hj | rfl | hj := lt_trichotomy j i.castSucc + · obtain ⟨j, rfl⟩ := j.eq_castSucc_of_ne_last (Fin.ne_last_of_lt hj) + grind [insertNth_apply_below, castPred_castSucc] + · rwa [← succAbove_succ_self i.castSucc, insertNth_apply_succAbove, insertNth_apply_same] + · obtain ⟨j, rfl⟩ := j.eq_succ_of_ne_zero (Fin.ne_zero_of_lt hj) + grind [insertNth_apply_same, insertNth_apply_above] + +lemma insertNth_last_monotone + {f : Fin (n + 1) → α} (hf : Monotone f) (x : α) (hx : f (Fin.last n) ≤ x) : + Monotone (Fin.insertNth (Fin.last (n + 1)) (α := fun _ ↦ α) x f) := by + rw [Fin.monotone_iff_le_succ] + intro i + obtain ⟨i, rfl⟩ | rfl := i.eq_castSucc_or_eq_last + · simpa only [insertNth_last', snoc_castSucc, Fin.succ_castSucc] + using hf i.castSucc_le_succ + · simpa + +lemma strictMono_insertNth_last + {f : Fin (n + 1) → α} (hf : StrictMono f) (x : α) (hx : f (Fin.last n) < x) : + StrictMono (Fin.insertNth (Fin.last (n + 1)) (α := fun _ ↦ α) x f) := by + rw [Fin.strictMono_iff_lt_succ] at hf ⊢ + intro i + obtain ⟨i, rfl⟩ | rfl := i.eq_castSucc_or_eq_last + · simpa only [insertNth_last', snoc_castSucc, Fin.succ_castSucc] + using hf i + · simpa + +end Fin From 5ff60493b53fed3d147da87a319574b5b3a6d93c Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:37 +0000 Subject: [PATCH 1226/1300] chore(Order/SymmDiff): use `to_dual` (#41775) This PR generates `bihimp` from `symmDiff` using `to_dual`. --- Mathlib/Order/SymmDiff.lean | 217 ++++++--------------------- Mathlib/Tactic/Translate/ToDual.lean | 2 + 2 files changed, 50 insertions(+), 169 deletions(-) diff --git a/Mathlib/Order/SymmDiff.lean b/Mathlib/Order/SymmDiff.lean index bc60ab8f1087f4..c5d81d84edb3c2 100644 --- a/Mathlib/Order/SymmDiff.lean +++ b/Mathlib/Order/SymmDiff.lean @@ -59,15 +59,15 @@ open Function OrderDual variable {ι α β : Type*} {π : ι → Type*} +to_dual_name_hint Compl HNot, SDiff HImp + /-- The symmetric difference operator on a type with `⊔` and `\` is `(A \ B) ⊔ (B \ A)`. -/ +@[to_dual +/-- The Heyting bi-implication is `(b ⇨ a) ⊓ (a ⇨ b)`. This generalizes equivalence of +propositions. -/] def symmDiff [Max α] [SDiff α] (a b : α) : α := a \ b ⊔ b \ a -/-- The Heyting bi-implication is `(b ⇨ a) ⊓ (a ⇨ b)`. This generalizes equivalence of -propositions. -/ -def bihimp [Min α] [HImp α] (a b : α) : α := - (b ⇨ a) ⊓ (a ⇨ b) - /-- Notation for symmDiff -/ scoped[symmDiff] infixl:100 " ∆ " => symmDiff @@ -76,12 +76,10 @@ scoped[symmDiff] infixl:100 " ⇔ " => bihimp open scoped symmDiff +@[to_dual] theorem symmDiff_def [Max α] [SDiff α] (a b : α) : a ∆ b = a \ b ⊔ b \ a := rfl -theorem bihimp_def [Min α] [HImp α] (a b : α) : a ⇔ b = (b ⇨ a) ⊓ (a ⇨ b) := - rfl - theorem symmDiff_eq_xor (p q : Prop) : p ∆ q = Xor p q := rfl @@ -98,73 +96,82 @@ section GeneralizedCoheytingAlgebra variable [GeneralizedCoheytingAlgebra α] (a b c : α) -@[simp] +@[to_dual (attr := simp)] theorem toDual_symmDiff : toDual (a ∆ b) = toDual a ⇔ toDual b := rfl -@[simp] +@[to_dual (attr := simp)] theorem ofDual_bihimp (a b : αᵒᵈ) : ofDual (a ⇔ b) = ofDual a ∆ ofDual b := rfl +@[to_dual] theorem symmDiff_comm : a ∆ b = b ∆ a := by simp only [symmDiff, sup_comm] +@[to_dual] instance symmDiff_isCommutative : Std.Commutative (α := α) (· ∆ ·) := ⟨symmDiff_comm⟩ -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_self : a ∆ a = ⊥ := by rw [symmDiff, sup_idem, sdiff_self] -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_bot : a ∆ ⊥ = a := by rw [symmDiff, sdiff_bot, bot_sdiff, sup_bot_eq] -@[simp] +@[to_dual (attr := simp)] theorem bot_symmDiff : ⊥ ∆ a = a := by rw [symmDiff_comm, symmDiff_bot] -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_eq_bot {a b : α} : a ∆ b = ⊥ ↔ a = b := by simp_rw [symmDiff, sup_eq_bot_iff, sdiff_eq_bot_iff, le_antisymm_iff] +@[to_dual] theorem symmDiff_of_le {a b : α} (h : a ≤ b) : a ∆ b = b \ a := by rw [symmDiff, sdiff_eq_bot_iff.2 h, bot_sup_eq] +@[to_dual] theorem symmDiff_of_ge {a b : α} (h : b ≤ a) : a ∆ b = a \ b := by rw [symmDiff, sdiff_eq_bot_iff.2 h, sup_bot_eq] +@[to_dual le_bihimp] theorem symmDiff_le {a b c : α} (ha : a ≤ b ⊔ c) (hb : b ≤ a ⊔ c) : a ∆ b ≤ c := sup_le (sdiff_le_iff.2 ha) <| sdiff_le_iff.2 hb +@[to_dual le_bihimp_iff] theorem symmDiff_le_iff {a b c : α} : a ∆ b ≤ c ↔ a ≤ b ⊔ c ∧ b ≤ a ⊔ c := by simp_rw [symmDiff, sup_le_iff, sdiff_le_iff] -@[simp] +@[to_dual (attr := simp) inf_le_bihimp] theorem symmDiff_le_sup {a b : α} : a ∆ b ≤ a ⊔ b := sup_le_sup sdiff_le sdiff_le +@[to_dual bihimp_eq_sup_himp_inf] theorem symmDiff_eq_sup_sdiff_inf : a ∆ b = (a ⊔ b) \ (a ⊓ b) := by simp [sup_sdiff, symmDiff] +@[to_dual] theorem Disjoint.symmDiff_eq_sup {a b : α} (h : Disjoint a b) : a ∆ b = a ⊔ b := by rw [symmDiff, h.sdiff_eq_left, h.sdiff_eq_right] +@[to_dual himp_bihimp] theorem symmDiff_sdiff : a ∆ b \ c = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) := by rw [symmDiff, sup_sdiff_distrib, sdiff_sdiff_left, sdiff_sdiff_left] -@[simp] +@[to_dual (attr := simp) sup_himp_bihimp] theorem symmDiff_sdiff_inf : a ∆ b \ (a ⊓ b) = a ∆ b := by rw [symmDiff_sdiff] simp [symmDiff] -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_sdiff_eq_sup : a ∆ (b \ a) = a ⊔ b := by rw [symmDiff, sdiff_idem] exact le_antisymm (sup_le_sup sdiff_le sdiff_le) (sup_le le_sdiff_sup <| le_sdiff_sup.trans <| sup_le le_sup_right le_sdiff_sup) -@[simp] +@[to_dual (attr := simp)] theorem sdiff_symmDiff_eq_sup : (a \ b) ∆ b = a ⊔ b := by rw [symmDiff_comm, symmDiff_sdiff_eq_sup, sup_comm] -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by refine le_antisymm (sup_le symmDiff_le_sup inf_le_sup) ?_ rw [sup_inf_left, symmDiff] @@ -174,163 +181,61 @@ theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by · rw [sup_assoc] exact le_sup_of_le_right le_sdiff_sup -@[simp] +@[to_dual (attr := simp)] theorem inf_sup_symmDiff : a ⊓ b ⊔ a ∆ b = a ⊔ b := by rw [sup_comm, symmDiff_sup_inf] -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_symmDiff_inf : a ∆ b ∆ (a ⊓ b) = a ⊔ b := by rw [← symmDiff_sdiff_inf a, sdiff_symmDiff_eq_sup, symmDiff_sup_inf] -@[simp] +@[to_dual (attr := simp)] theorem inf_symmDiff_symmDiff : (a ⊓ b) ∆ (a ∆ b) = a ⊔ b := by rw [symmDiff_comm, symmDiff_symmDiff_inf] +@[to_dual] theorem symmDiff_triangle : a ∆ c ≤ a ∆ b ⊔ b ∆ c := by refine (sup_le_sup (sdiff_triangle a b c) <| sdiff_triangle _ b _).trans_eq ?_ rw [sup_comm (c \ b), sup_sup_sup_comm, symmDiff, symmDiff] +@[to_dual] theorem le_symmDiff_sup_right (a b : α) : a ≤ (a ∆ b) ⊔ b := by convert! symmDiff_triangle a b ⊥ <;> rw [symmDiff_bot] +@[to_dual] theorem le_symmDiff_sup_left (a b : α) : b ≤ (a ∆ b) ⊔ a := symmDiff_comm a b ▸ le_symmDiff_sup_right .. end GeneralizedCoheytingAlgebra -section GeneralizedHeytingAlgebra - -variable [GeneralizedHeytingAlgebra α] (a b c : α) - -@[simp] -theorem toDual_bihimp : toDual (a ⇔ b) = toDual a ∆ toDual b := - rfl - -@[simp] -theorem ofDual_symmDiff (a b : αᵒᵈ) : ofDual (a ∆ b) = ofDual a ⇔ ofDual b := - rfl - -theorem bihimp_comm : a ⇔ b = b ⇔ a := by simp only [(· ⇔ ·), inf_comm] - -instance bihimp_isCommutative : Std.Commutative (α := α) (· ⇔ ·) := - ⟨bihimp_comm⟩ - -@[simp] -theorem bihimp_self : a ⇔ a = ⊤ := by rw [bihimp, inf_idem, himp_self] - -@[simp] -theorem bihimp_top : a ⇔ ⊤ = a := by rw [bihimp, himp_top, top_himp, inf_top_eq] - -@[simp] -theorem top_bihimp : ⊤ ⇔ a = a := by rw [bihimp_comm, bihimp_top] - -@[simp] -theorem bihimp_eq_top {a b : α} : a ⇔ b = ⊤ ↔ a = b := - @symmDiff_eq_bot αᵒᵈ _ _ _ - -theorem bihimp_of_le {a b : α} (h : a ≤ b) : a ⇔ b = b ⇨ a := by - rw [bihimp, himp_eq_top_iff.2 h, inf_top_eq] - -theorem bihimp_of_ge {a b : α} (h : b ≤ a) : a ⇔ b = a ⇨ b := by - rw [bihimp, himp_eq_top_iff.2 h, top_inf_eq] - -theorem le_bihimp {a b c : α} (hb : a ⊓ b ≤ c) (hc : a ⊓ c ≤ b) : a ≤ b ⇔ c := - le_inf (le_himp_iff.2 hc) <| le_himp_iff.2 hb - -theorem le_bihimp_iff {a b c : α} : a ≤ b ⇔ c ↔ a ⊓ b ≤ c ∧ a ⊓ c ≤ b := by - simp_rw [bihimp, le_inf_iff, le_himp_iff, and_comm] - -@[simp] -theorem inf_le_bihimp {a b : α} : a ⊓ b ≤ a ⇔ b := - inf_le_inf le_himp le_himp - -theorem bihimp_eq_sup_himp_inf : a ⇔ b = a ⊔ b ⇨ a ⊓ b := by simp [himp_inf_distrib, bihimp] - -theorem Codisjoint.bihimp_eq_inf {a b : α} (h : Codisjoint a b) : a ⇔ b = a ⊓ b := by - rw [bihimp, h.himp_eq_left, h.himp_eq_right] - -theorem himp_bihimp : a ⇨ b ⇔ c = (a ⊓ c ⇨ b) ⊓ (a ⊓ b ⇨ c) := by - rw [bihimp, himp_inf_distrib, himp_himp, himp_himp] - -@[simp] -theorem sup_himp_bihimp : a ⊔ b ⇨ a ⇔ b = a ⇔ b := by - rw [himp_bihimp] - simp [bihimp] - -@[simp] -theorem bihimp_himp_eq_inf : a ⇔ (a ⇨ b) = a ⊓ b := - @symmDiff_sdiff_eq_sup αᵒᵈ _ _ _ - -@[simp] -theorem himp_bihimp_eq_inf : (b ⇨ a) ⇔ b = a ⊓ b := - @sdiff_symmDiff_eq_sup αᵒᵈ _ _ _ - -@[simp] -theorem bihimp_inf_sup : a ⇔ b ⊓ (a ⊔ b) = a ⊓ b := - @symmDiff_sup_inf αᵒᵈ _ _ _ - -@[simp] -theorem sup_inf_bihimp : (a ⊔ b) ⊓ a ⇔ b = a ⊓ b := - @inf_sup_symmDiff αᵒᵈ _ _ _ - -@[simp] -theorem bihimp_bihimp_sup : a ⇔ b ⇔ (a ⊔ b) = a ⊓ b := - @symmDiff_symmDiff_inf αᵒᵈ _ _ _ - -@[simp] -theorem sup_bihimp_bihimp : (a ⊔ b) ⇔ (a ⇔ b) = a ⊓ b := - @inf_symmDiff_symmDiff αᵒᵈ _ _ _ - -theorem bihimp_triangle : a ⇔ b ⊓ b ⇔ c ≤ a ⇔ c := - @symmDiff_triangle αᵒᵈ _ _ _ _ - -end GeneralizedHeytingAlgebra - section CoheytingAlgebra variable [CoheytingAlgebra α] (a : α) -@[simp] -theorem symmDiff_top' : a ∆ ⊤ = ¬a := by simp [symmDiff] +@[to_dual (attr := simp)] +theorem symmDiff_top : a ∆ ⊤ = ¬a := by simp [symmDiff] -@[simp] -theorem top_symmDiff' : ⊤ ∆ a = ¬a := by simp [symmDiff] +@[to_dual (attr := simp)] +theorem top_symmDiff : ⊤ ∆ a = ¬a := by simp [symmDiff] -@[simp] +@[deprecated (since := "2026-08-04")] alias symmDiff_top' := symmDiff_top +@[deprecated (since := "2026-08-04")] alias top_symmDiff' := top_symmDiff + +@[to_dual (attr := simp)] theorem hnot_symmDiff_self : (¬a) ∆ a = ⊤ := by rw [eq_top_iff, symmDiff, hnot_sdiff, sup_sdiff_self] exact Codisjoint.top_le codisjoint_hnot_left -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_hnot_self : a ∆ (¬a) = ⊤ := by rw [symmDiff_comm, hnot_symmDiff_self] +@[deprecated (since := "2026-07-15")] alias bihimp_hnot_self := bihimp_compl_self + +@[to_dual] theorem IsCompl.symmDiff_eq_top {a b : α} (h : IsCompl a b) : a ∆ b = ⊤ := by rw [h.eq_hnot, hnot_symmDiff_self] end CoheytingAlgebra -section HeytingAlgebra - -variable [HeytingAlgebra α] (a : α) - -@[simp] -theorem bihimp_bot : a ⇔ ⊥ = aᶜ := by simp [bihimp] - -@[simp] -theorem bot_bihimp : ⊥ ⇔ a = aᶜ := by simp [bihimp] - -@[simp] -theorem compl_bihimp_self : aᶜ ⇔ a = ⊥ := - @hnot_symmDiff_self αᵒᵈ _ _ - -@[simp] -theorem bihimp_hnot_self : a ⇔ aᶜ = ⊥ := - @symmDiff_hnot_self αᵒᵈ _ _ - -theorem IsCompl.bihimp_eq_bot {a b : α} (h : IsCompl a b) : a ⇔ b = ⊥ := by - rw [h.eq_compl, compl_bihimp_self] - -end HeytingAlgebra - section GeneralizedBooleanAlgebra variable [GeneralizedBooleanAlgebra α] (a b c d : α) @@ -598,12 +503,6 @@ theorem symmDiff_eq' : a ∆ b = (a ⊔ b) ⊓ (aᶜ ⊔ bᶜ) := by theorem bihimp_eq' : a ⇔ b = a ⊓ b ⊔ aᶜ ⊓ bᶜ := @symmDiff_eq' αᵒᵈ _ _ _ -theorem symmDiff_top : a ∆ ⊤ = aᶜ := - symmDiff_top' _ - -theorem top_symmDiff : ⊤ ∆ a = aᶜ := - top_symmDiff' _ - @[simp] theorem compl_symmDiff : (a ∆ b)ᶜ = a ⇔ b := by simp_rw [symmDiff, compl_sup_distrib, compl_sdiff, bihimp, inf_comm] @@ -676,26 +575,16 @@ end BooleanAlgebra section Prod -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_fst [GeneralizedCoheytingAlgebra α] [GeneralizedCoheytingAlgebra β] (a b : α × β) : (a ∆ b).1 = a.1 ∆ b.1 := rfl -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_snd [GeneralizedCoheytingAlgebra α] [GeneralizedCoheytingAlgebra β] (a b : α × β) : (a ∆ b).2 = a.2 ∆ b.2 := rfl -@[simp] -theorem bihimp_fst [GeneralizedHeytingAlgebra α] [GeneralizedHeytingAlgebra β] (a b : α × β) : - (a ⇔ b).1 = a.1 ⇔ b.1 := - rfl - -@[simp] -theorem bihimp_snd [GeneralizedHeytingAlgebra α] [GeneralizedHeytingAlgebra β] (a b : α × β) : - (a ⇔ b).2 = a.2 ⇔ b.2 := - rfl - end Prod /-! ### Pi -/ @@ -703,24 +592,14 @@ end Prod namespace Pi -@[push ←] +@[to_dual (attr := push ←)] theorem symmDiff_def [∀ i, GeneralizedCoheytingAlgebra (π i)] (a b : ∀ i, π i) : a ∆ b = fun i => a i ∆ b i := rfl -@[push ←] -theorem bihimp_def [∀ i, GeneralizedHeytingAlgebra (π i)] (a b : ∀ i, π i) : - a ⇔ b = fun i => a i ⇔ b i := - rfl - -@[simp] +@[to_dual (attr := simp)] theorem symmDiff_apply [∀ i, GeneralizedCoheytingAlgebra (π i)] (a b : ∀ i, π i) (i : ι) : (a ∆ b) i = a i ∆ b i := rfl -@[simp] -theorem bihimp_apply [∀ i, GeneralizedHeytingAlgebra (π i)] (a b : ∀ i, π i) (i : ι) : - (a ⇔ b) i = a i ⇔ b i := - rfl - end Pi diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index e1e4f427d62382..8be53641e43fec 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -265,6 +265,8 @@ def abbreviationDict : Std.HashMap String String := .ofList [ ("galoisCoinsertion", "GaloisInsertion"), ("leftOrdContinuous", "RightOrdContinuous"), ("rightOrdContinuous", "LeftOrdContinuous"), + ("bihimp", "SymmDiff"), + ("symmDiff", "Bihimp"), -- Revert translations if they should not happen in certain word combinations: ("neTop", "NeBot"), From b8d43c430c6bd3c785f434ec8720b49904fd3f86 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:40 +0000 Subject: [PATCH 1227/1300] chore(Order/CompleteBooleanAlgebra): use `to_dual` (#41792) This PR uses `to_dual` in `Mathlib/Order/CompleteBooleanAlgebra`. - `Frame.mk` and `Coframe.mk` are annoyingly not dual to eachother due to the way in which `GeneralizedHeytingAlgebra` and `GeneralizedCoheytingAlgebra` are not dual to eachother. - The `MinimalAxioms` structures have been refactored into a more natural form. Firstly, they should not be classes since they should not be used in type class search. Additionally, instead of extending `CompleteLattice`, they now take it as a parameter, so that we can easily talk about the order operations. As a result, the `MinimalAxioms` structures live in `Prop`. Some lemmas about `MinimalAxioms` have been marked `private`, since these are not meant to be used anywhere else. --- .../Combinatorics/SimpleGraph/Subgraph.lean | 16 +- Mathlib/Data/Fintype/Order.lean | 3 +- Mathlib/Order/CompleteBooleanAlgebra.lean | 308 +++++++----------- Mathlib/Order/CompleteLattice/Defs.lean | 2 +- Mathlib/Order/Nucleus.lean | 6 +- Mathlib/Order/Sublocale.lean | 7 +- Mathlib/Order/UpperLower/CompleteLattice.lean | 4 +- Mathlib/Tactic/Translate/ToDual.lean | 1 + Mathlib/Topology/Sets/Closeds.lean | 8 +- Mathlib/Topology/Sets/Opens.lean | 8 +- 10 files changed, 131 insertions(+), 232 deletions(-) diff --git a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean index a8b7f3675c729f..1baa1c3d47c1e9 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean @@ -469,11 +469,8 @@ instance : BoundedOrder (Subgraph G) where le_top x := ⟨Set.subset_univ _, fun _ _ => x.adj_sub⟩ bot_le _ := ⟨Set.empty_subset _, fun _ _ => False.elim⟩ -/-- Note that subgraphs do not form a Boolean algebra, because of `verts`. -/ -@[instance_reducible] -def completelyDistribLatticeMinimalAxioms : CompletelyDistribLattice.MinimalAxioms G.Subgraph where - le_top G' := ⟨Set.subset_univ _, fun _ _ => G'.adj_sub⟩ - bot_le _ := ⟨Set.empty_subset _, fun _ _ => False.elim⟩ +set_option linter.unusedVariables false in +instance : CompleteLattice (Subgraph G) where isLUB_sSup _ := ⟨fun G' hG' ↦ ⟨Set.subset_biUnion_of_mem hG', fun _ _ hab => ⟨G', hG', hab⟩⟩, fun G' hG' ↦ @@ -482,12 +479,13 @@ def completelyDistribLatticeMinimalAxioms : CompletelyDistribLattice.MinimalAxio ⟨fun G' hG' ↦ ⟨Set.iInter₂_subset G' hG', fun _ _ hab => hab.1 hG'⟩, fun G' hG' ↦ ⟨Set.subset_iInter₂ fun _ hH => (hG' hH).1, fun _ _ hab => - ⟨fun _ hH => (hG' hH).2 hab, G'.adj_sub hab⟩⟩⟩ - iInf_iSup_eq f := Subgraph.ext (by simpa using! iInf_iSup_eq) - (by ext; simp [Classical.skolem]) + ⟨fun _ hH => (hG' hH).2 hab, G'.adj_sub hab⟩⟩⟩ +/-- Note that subgraphs do not form a Boolean algebra, because of `verts`. -/ instance : CompletelyDistribLattice G.Subgraph := - fast_instance% .ofMinimalAxioms completelyDistribLatticeMinimalAxioms + fast_instance% .ofMinimalAxioms { + iInf_iSup_eq f := Subgraph.ext (by simpa using! iInf_iSup_eq) + (by ext; simp [Classical.skolem]) } @[gcongr] lemma verts_mono {H H' : G.Subgraph} (h : H ≤ H') : H.verts ⊆ H'.verts := h.1 lemma verts_monotone : Monotone (verts : G.Subgraph → Set V) := fun _ _ h ↦ h.1 diff --git a/Mathlib/Data/Fintype/Order.lean b/Mathlib/Data/Fintype/Order.lean index d7cbdccb30b258..d301cc22e0571d 100644 --- a/Mathlib/Data/Fintype/Order.lean +++ b/Mathlib/Data/Fintype/Order.lean @@ -96,11 +96,11 @@ noncomputable abbrev toCompleteLattice [Lattice α] [BoundedOrder α] : Complete isLUB_sSup s := Set.coe_toFinset s ▸ Finset.isLUB_sup_id isGLB_sInf s := Set.coe_toFinset s ▸ Finset.isGLB_inf_id +attribute [local instance] toCompleteLattice in -- See note [reducible non-instances] /-- A finite bounded distributive lattice is completely distributive. -/ noncomputable abbrev toCompleteDistribLatticeMinimalAxioms [DistribLattice α] [BoundedOrder α] : CompleteDistribLattice.MinimalAxioms α where - __ := toCompleteLattice α iInf_sup_le_sup_sInf := fun a s => by convert! (Finset.inf_sup_distrib_left s.toFinset id a).ge using 1 rw [Finset.inf_eq_iInf] @@ -112,6 +112,7 @@ noncomputable abbrev toCompleteDistribLatticeMinimalAxioms [DistribLattice α] [ simp_rw [Set.mem_toFinset] rfl +attribute [local instance] toCompleteLattice in -- See note [reducible non-instances] /-- A finite bounded distributive lattice is completely distributive. -/ noncomputable abbrev toCompleteDistribLattice [DistribLattice α] [BoundedOrder α] : diff --git a/Mathlib/Order/CompleteBooleanAlgebra.lean b/Mathlib/Order/CompleteBooleanAlgebra.lean index f79cc154081879..2019a30c496d56 100644 --- a/Mathlib/Order/CompleteBooleanAlgebra.lean +++ b/Mathlib/Order/CompleteBooleanAlgebra.lean @@ -63,7 +63,7 @@ except for implementing `Order.Frame` via `Order.Frame.ofMinimalAxioms`. This structure omits the `himp`, `compl` fields, which can be recovered using `Order.Frame.ofMinimalAxioms`. -/ -class Order.Frame.MinimalAxioms (α : Type u) extends CompleteLattice α where +structure Order.Frame.MinimalAxioms (α : Type u) [CompleteLattice α] where inf_sSup_le_iSup_inf (a : α) (s : Set α) : a ⊓ sSup s ≤ ⨆ b ∈ s, a ⊓ b /-- Structure containing the minimal axioms required to check that an order is a coframe. Do NOT @@ -71,44 +71,40 @@ use, except for implementing `Order.Coframe` via `Order.Coframe.ofMinimalAxioms` This structure omits the `sdiff`, `hnot` fields, which can be recovered using `Order.Coframe.ofMinimalAxioms`. -/ -class Order.Coframe.MinimalAxioms (α : Type u) extends CompleteLattice α where +@[to_dual Frame.MinimalAxioms] +structure Order.Coframe.MinimalAxioms (α : Type u) [CompleteLattice α] where iInf_sup_le_sup_sInf (a : α) (s : Set α) : ⨅ b ∈ s, a ⊔ b ≤ a ⊔ sInf s /-- A frame, aka complete Heyting algebra, is a complete lattice whose `⊓` distributes over `⨆`. -/ class Order.Frame (α : Type*) extends CompleteLattice α, HeytingAlgebra α where -/-- `⊓` distributes over `⨆`. -/ -theorem inf_sSup_eq {α : Type*} [Order.Frame α] {s : Set α} {a : α} : - a ⊓ sSup s = ⨆ b ∈ s, a ⊓ b := - gc_inf_himp.l_sSup - set_option linter.translate.warnInvalid false in /-- A coframe, aka complete Brouwer algebra or complete co-Heyting algebra, is a complete lattice whose `⊔` distributes over `⨅`. -/ @[to_dual] class Order.Coframe (α : Type*) extends CompleteLattice α, CoheytingAlgebra α where -/-- `⊔` distributes over `⨅`. -/ -theorem sup_sInf_eq {α : Type*} [Order.Coframe α] {s : Set α} {a : α} : - a ⊔ sInf s = ⨅ b ∈ s, a ⊔ b := - gc_sdiff_sup.u_sInf - open Order +/-- `⊓` distributes over `⨆`. -/ +@[to_dual /-- `⊔` distributes over `⨅`. -/] +theorem inf_sSup_eq [Frame α] {s : Set α} {a : α} : a ⊓ sSup s = ⨆ b ∈ s, a ⊓ b := + gc_inf_himp.l_sSup + /-- Structure containing the minimal axioms required to check that an order is a complete distributive lattice. Do NOT use, except for implementing `CompleteDistribLattice` via `CompleteDistribLattice.ofMinimalAxioms`. This structure omits the `himp`, `compl`, `sdiff`, `hnot` fields, which can be recovered using `CompleteDistribLattice.ofMinimalAxioms`. -/ -structure CompleteDistribLattice.MinimalAxioms (α : Type u) - extends CompleteLattice α, - toFrameMinimalAxioms : Frame.MinimalAxioms α, - toCoframeMinimalAxioms : Coframe.MinimalAxioms α where +structure CompleteDistribLattice.MinimalAxioms (α : Type u) [CompleteLattice α] extends + toFrame : Frame.MinimalAxioms α, toCoframe : Coframe.MinimalAxioms α where + +/-- Turn minimal axioms for `CompleteDistribLattice` into minimal axioms for `Order.Frame`. -/ +add_decl_doc CompleteDistribLattice.MinimalAxioms.toFrame --- We give those projections better name further down -attribute [nolint docBlame] CompleteDistribLattice.MinimalAxioms.toFrameMinimalAxioms - CompleteDistribLattice.MinimalAxioms.toCoframeMinimalAxioms +/-- Turn minimal axioms for `CompleteDistribLattice` into minimal axioms for `Order.Coframe`. -/ +add_decl_doc CompleteDistribLattice.MinimalAxioms.toCoframe /-- A complete distributive lattice is a complete lattice whose `⊔` and `⊓` respectively distribute over `⨅` and `⨆`. -/ @@ -122,7 +118,7 @@ distributive. Do NOT use, except for implementing `CompletelyDistribLattice` via This structure omits the `himp`, `compl`, `sdiff`, `hnot` fields, which can be recovered using `CompletelyDistribLattice.ofMinimalAxioms`. -/ -structure CompletelyDistribLattice.MinimalAxioms (α : Type u) extends CompleteLattice α where +structure CompletelyDistribLattice.MinimalAxioms (α : Type u) [CompleteLattice α] where protected iInf_iSup_eq {ι : Type u} {κ : ι → Type u} (f : ∀ a, κ a → α) : (⨅ a, ⨆ b, f a b) = ⨆ g : ∀ a, κ a, ⨅ a, f a (g a) @@ -141,26 +137,38 @@ lemma iSup_iInf_le [CompleteLattice α] {f : ∀ a, κ a → α} : le_iInf_iSup (α := αᵒᵈ) namespace Order.Frame.MinimalAxioms -variable (minAx : MinimalAxioms α) {s : Set α} {a b : α} +variable (s : Set α) (a b : α) -lemma inf_sSup_eq : a ⊓ sSup s = ⨆ b ∈ s, a ⊓ b := - (minAx.inf_sSup_le_iSup_inf _ _).antisymm iSup_inf_le_inf_sSup +section +variable [CompleteLattice α] (minAx : MinimalAxioms α) +include minAx -lemma sSup_inf_eq : sSup s ⊓ b = ⨆ a ∈ s, a ⊓ b := by - simpa only [inf_comm] using @inf_sSup_eq α _ s b +@[to_dual] +private lemma inf_sSup_eq : a ⊓ sSup s = ⨆ b ∈ s, a ⊓ b := + le_antisymm (minAx.inf_sSup_le_iSup_inf _ _) iSup_inf_le_inf_sSup -lemma iSup_inf_eq (f : ι → α) (a : α) : (⨆ i, f i) ⊓ a = ⨆ i, f i ⊓ a := by - rw [iSup, sSup_inf_eq, iSup_range] +@[to_dual] +private lemma sSup_inf_eq : sSup s ⊓ b = ⨆ a ∈ s, a ⊓ b := by + simpa only [inf_comm] using inf_sSup_eq s b minAx + +@[to_dual] +private lemma iSup_inf_eq (f : ι → α) (a : α) : (⨆ i, f i) ⊓ a = ⨆ i, f i ⊓ a := by + rw [iSup, minAx.sSup_inf_eq, iSup_range] -lemma inf_iSup_eq (a : α) (f : ι → α) : (a ⊓ ⨆ i, f i) = ⨆ i, a ⊓ f i := by +@[to_dual] +private lemma inf_iSup_eq (a : α) (f : ι → α) : (a ⊓ ⨆ i, f i) = ⨆ i, a ⊓ f i := by simpa only [inf_comm] using minAx.iSup_inf_eq f a -lemma inf_iSup₂_eq {f : ∀ i, κ i → α} (a : α) : (a ⊓ ⨆ i, ⨆ j, f i j) = ⨆ i, ⨆ j, a ⊓ f i j := by - simp only [inf_iSup_eq] +@[to_dual] +private lemma inf_iSup₂_eq {f : ∀ i, κ i → α} (a : α) : + (a ⊓ ⨆ i, ⨆ j, f i j) = ⨆ i, ⨆ j, a ⊓ f i j := by + simp only [minAx.inf_iSup_eq] + +end /-- The `Order.Frame.MinimalAxioms` element corresponding to a frame. -/ -@[instance_reducible] -def of [Frame α] : MinimalAxioms α where +@[to_dual /-- The `Order.Coframe.MinimalAxioms` element corresponding to a frame. -/] +theorem of [Frame α] : MinimalAxioms α where __ := ‹Frame α› inf_sSup_le_iSup_inf a s := _root_.inf_sSup_eq.le @@ -170,8 +178,7 @@ end MinimalAxioms This sets `a ⇨ b := sSup {c | c ⊓ a ≤ b}` and `aᶜ := a ⇨ ⊥`. -/ -- See note [reducible non-instances] -abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Frame α where - __ := minAx +abbrev ofMinimalAxioms [CompleteLattice α] (minAx : MinimalAxioms α) : Frame α where compl a := sSup {c | c ⊓ a ≤ ⊥} himp a b := sSup {c | c ⊓ a ≤ b} le_himp_iff _ b c := @@ -180,38 +187,14 @@ abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Frame α where end Order.Frame -namespace Order.Coframe.MinimalAxioms -variable (minAx : MinimalAxioms α) {s : Set α} {a b : α} - -lemma sup_sInf_eq : a ⊔ sInf s = ⨅ b ∈ s, a ⊔ b := - sup_sInf_le_iInf_sup.antisymm (minAx.iInf_sup_le_sup_sInf _ _) - -lemma sInf_sup_eq : sInf s ⊔ b = ⨅ a ∈ s, a ⊔ b := by - simpa only [sup_comm] using @sup_sInf_eq α _ s b - -lemma iInf_sup_eq (f : ι → α) (a : α) : (⨅ i, f i) ⊔ a = ⨅ i, f i ⊔ a := by - rw [iInf, sInf_sup_eq, iInf_range] - -lemma sup_iInf_eq (a : α) (f : ι → α) : (a ⊔ ⨅ i, f i) = ⨅ i, a ⊔ f i := by - simpa only [sup_comm] using minAx.iInf_sup_eq f a - -lemma sup_iInf₂_eq {f : ∀ i, κ i → α} (a : α) : (a ⊔ ⨅ i, ⨅ j, f i j) = ⨅ i, ⨅ j, a ⊔ f i j := by - simp only [sup_iInf_eq] - -/-- The `Order.Coframe.MinimalAxioms` element corresponding to a frame. -/ -@[instance_reducible] -def of [Coframe α] : MinimalAxioms α where - __ := ‹Coframe α› - iInf_sup_le_sup_sInf a s := _root_.sup_sInf_eq.ge - -end MinimalAxioms +namespace Order.Coframe /-- Construct a coframe instance using the minimal amount of work needed. This sets `a \ b := sInf {c | a ≤ b ⊔ c}` and `¬a := ⊤ \ a`. -/ -- See note [reducible non-instances] -abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Coframe α where - __ := minAx +@[to_dual existing] +abbrev ofMinimalAxioms [CompleteLattice α] (minAx : MinimalAxioms α) : Coframe α where hnot a := sInf {c | ⊤ ≤ a ⊔ c} sdiff a b := sInf {c | a ≤ b ⊔ c} sdiff_le_iff a b _ := @@ -221,21 +204,15 @@ abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Coframe α where end Order.Coframe namespace CompleteDistribLattice.MinimalAxioms -variable (minAx : MinimalAxioms α) /-- The `CompleteDistribLattice.MinimalAxioms` element corresponding to a complete distrib lattice. -/ -@[instance_reducible] -def of [CompleteDistribLattice α] : MinimalAxioms α where +theorem of [CompleteDistribLattice α] : MinimalAxioms α where __ := ‹CompleteDistribLattice α› inf_sSup_le_iSup_inf a s := inf_sSup_eq.le iInf_sup_le_sup_sInf a s := sup_sInf_eq.ge -/-- Turn minimal axioms for `CompleteDistribLattice` into minimal axioms for `Order.Frame`. -/ -abbrev toFrame : Frame.MinimalAxioms α := minAx.toFrameMinimalAxioms - -/-- Turn minimal axioms for `CompleteDistribLattice` into minimal axioms for `Order.Coframe`. -/ -abbrev toCoframe : Coframe.MinimalAxioms α where __ := minAx +variable [CompleteLattice α] (minAx : MinimalAxioms α) end MinimalAxioms @@ -244,19 +221,17 @@ end MinimalAxioms This sets `a ⇨ b := sSup {c | c ⊓ a ≤ b}`, `aᶜ := a ⇨ ⊥`, `a \ b := sInf {c | a ≤ b ⊔ c}` and `¬a := ⊤ \ a`. -/ -- See note [reducible non-instances] -abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : CompleteDistribLattice α where +abbrev ofMinimalAxioms [CompleteLattice α] (minAx : MinimalAxioms α) : + CompleteDistribLattice α where __ := Frame.ofMinimalAxioms minAx.toFrame __ := Coframe.ofMinimalAxioms minAx.toCoframe end CompleteDistribLattice namespace CompletelyDistribLattice.MinimalAxioms -variable (minAx : MinimalAxioms α) -lemma iInf_iSup_eq' (f : ∀ a, κ a → α) : - let _ := minAx.toCompleteLattice +private lemma iInf_iSup_eq' [CompleteLattice α] (minAx : MinimalAxioms α) (f : ∀ a, κ a → α) : ⨅ i, ⨆ j, f i j = ⨆ g : ∀ i, κ i, ⨅ i, f i (g i) := by - let _ := minAx.toCompleteLattice refine le_antisymm ?_ le_iInf_iSup calc _ = ⨅ a : range (range <| f ·), ⨆ b : a.1, b.1 := by @@ -267,10 +242,9 @@ lemma iInf_iSup_eq' (f : ∀ a, κ a → α) : refine le_iInf fun a => le_trans (iInf_le _ ⟨range (f a), a, rfl⟩) ?_ rw [← Classical.choose_spec (g ⟨_, a, rfl⟩).2] -lemma iSup_iInf_eq (f : ∀ i, κ i → α) : - let _ := minAx.toCompleteLattice +@[to_dual existing iInf_iSup_eq'] +private lemma iSup_iInf_eq [CompleteLattice α] (minAx : MinimalAxioms α) (f : ∀ i, κ i → α) : ⨆ i, ⨅ j, f i j = ⨅ g : ∀ i, κ i, ⨆ i, f i (g i) := by - let _ := minAx.toCompleteLattice refine le_antisymm iSup_iInf_le ?_ rw [minAx.iInf_iSup_eq'] refine iSup_le fun g => ?_ @@ -286,10 +260,9 @@ lemma iSup_iInf_eq (f : ∀ i, κ i → α) : /-- Turn minimal axioms for `CompletelyDistribLattice` into minimal axioms for `CompleteDistribLattice`. -/ -abbrev toCompleteDistribLattice : CompleteDistribLattice.MinimalAxioms α where - __ := minAx +theorem toCompleteDistribLattice [CompleteLattice α] (minAx : MinimalAxioms α) : + CompleteDistribLattice.MinimalAxioms α where inf_sSup_le_iSup_inf a s := by - let _ := minAx.toCompleteLattice calc _ = ⨅ i : ULift.{u} Bool, ⨆ j : match i with | .up true => PUnit.{u + 1} | .up false => s, match i with @@ -299,7 +272,6 @@ abbrev toCompleteDistribLattice : CompleteDistribLattice.MinimalAxioms α where simp only [minAx.iInf_iSup_eq, iInf_ulift, iInf_bool_eq, iSup_le_iff] exact fun x ↦ le_biSup _ (x (.up false)).2 iInf_sup_le_sup_sInf a s := by - let _ := minAx.toCompleteLattice calc _ ≤ ⨆ i : ULift.{u} Bool, ⨅ j : match i with | .up true => PUnit.{u + 1} | .up false => s, match i with @@ -310,8 +282,7 @@ abbrev toCompleteDistribLattice : CompleteDistribLattice.MinimalAxioms α where _ = _ := by simp [sInf_eq_iInf', iInf_unique, iSup_bool_eq] /-- The `CompletelyDistribLattice.MinimalAxioms` element corresponding to a frame. -/ -@[instance_reducible] -def of [CompletelyDistribLattice α] : MinimalAxioms α := { ‹CompletelyDistribLattice α› with } +theorem of [CompletelyDistribLattice α] : MinimalAxioms α := { ‹CompletelyDistribLattice α› with } end MinimalAxioms @@ -320,20 +291,17 @@ end MinimalAxioms This sets `a ⇨ b := sSup {c | c ⊓ a ≤ b}`, `aᶜ := a ⇨ ⊥`, `a \ b := sInf {c | a ≤ b ⊔ c}` and `¬a := ⊤ \ a`. -/ -- See note [reducible non-instances] -abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : CompletelyDistribLattice α where - __ := minAx - __ := CompleteDistribLattice.ofMinimalAxioms minAx.toCompleteDistribLattice +abbrev ofMinimalAxioms [CompleteLattice α] (minAx : MinimalAxioms α) : + CompletelyDistribLattice α := fast_instance% + { CompleteDistribLattice.ofMinimalAxioms minAx.toCompleteDistribLattice, minAx with } end CompletelyDistribLattice +@[to_dual] theorem iInf_iSup_eq [CompletelyDistribLattice α] {f : ∀ a, κ a → α} : (⨅ a, ⨆ b, f a b) = ⨆ g : ∀ a, κ a, ⨅ a, f a (g a) := CompletelyDistribLattice.MinimalAxioms.of.iInf_iSup_eq' _ -theorem iSup_iInf_eq [CompletelyDistribLattice α] {f : ∀ a, κ a → α} : - (⨆ a, ⨅ b, f a b) = ⨅ g : ∀ a, κ a, ⨆ a, f a (g a) := - CompletelyDistribLattice.MinimalAxioms.of.iSup_iInf_eq _ - theorem biSup_iInter_of_pairwise_disjoint [CompletelyDistribLattice α] {ι κ : Type*} [hκ : Nonempty κ] {f : ι → α} (h : Pairwise (Disjoint on f)) (s : κ → Set ι) : (⨆ i ∈ (⋂ j, s j), f i) = ⨅ j, (⨆ i ∈ s j, f i) := by @@ -391,41 +359,54 @@ instance OrderDual.instCoframe : Coframe αᵒᵈ where __ := instCompleteLattice __ := instCoheytingAlgebra +@[to_dual] theorem sSup_inf_eq : sSup s ⊓ b = ⨆ a ∈ s, a ⊓ b := by simpa only [inf_comm] using @inf_sSup_eq α _ s b +@[to_dual] theorem iSup_inf_eq (f : ι → α) (a : α) : (⨆ i, f i) ⊓ a = ⨆ i, f i ⊓ a := by rw [iSup, sSup_inf_eq, iSup_range] +@[to_dual] theorem inf_iSup_eq (a : α) (f : ι → α) : (a ⊓ ⨆ i, f i) = ⨆ i, a ⊓ f i := by simpa only [inf_comm] using iSup_inf_eq f a +@[to_dual] theorem iSup₂_inf_eq {f : ∀ i, κ i → α} (a : α) : (⨆ (i) (j), f i j) ⊓ a = ⨆ (i) (j), f i j ⊓ a := by simp only [iSup_inf_eq] +@[to_dual] theorem inf_iSup₂_eq {f : ∀ i, κ i → α} (a : α) : (a ⊓ ⨆ (i) (j), f i j) = ⨆ (i) (j), a ⊓ f i j := by simp only [inf_iSup_eq] +@[to_dual iSup_sdiff_eq] theorem himp_iInf_eq {f : ι → α} : a ⇨ (⨅ x, f x) = ⨅ x, a ⇨ f x := eq_of_forall_le_iff fun b => by simp +@[to_dual sdiff_iInf_eq] theorem iSup_himp_eq {f : ι → α} : (⨆ x, f x) ⇨ a = ⨅ x, f x ⇨ a := eq_of_forall_le_iff fun b => by simp [inf_iSup_eq] +@[deprecated (since := "2026-07-30")] alias sdiff_iSup_eq := sdiff_iInf_eq + +@[to_dual] theorem iSup_inf_iSup {ι ι' : Type*} {f : ι → α} {g : ι' → α} : ((⨆ i, f i) ⊓ ⨆ j, g j) = ⨆ i : ι × ι', f i.1 ⊓ g i.2 := by simp_rw [iSup_inf_eq, inf_iSup_eq, iSup_prod] +@[to_dual] theorem biSup_inf_biSup {ι ι' : Type*} {f : ι → α} {g : ι' → α} {s : Set ι} {t : Set ι'} : ((⨆ i ∈ s, f i) ⊓ ⨆ j ∈ t, g j) = ⨆ p ∈ s ×ˢ t, f (p : ι × ι').1 ⊓ g p.2 := by simp only [iSup_subtype', iSup_inf_iSup] exact (Equiv.surjective _).iSup_congr (Equiv.Set.prod s t).symm fun x => rfl +@[to_dual] theorem sSup_inf_sSup : sSup s ⊓ sSup t = ⨆ p ∈ s ×ˢ t, (p : α × α).1 ⊓ p.2 := by simp only [sSup_eq_iSup, biSup_inf_biSup] +@[to_dual] theorem biSup_inter_of_pairwise_disjoint {ι : Type*} {f : ι → α} (h : Pairwise (Disjoint on f)) (s t : Set ι) : (⨆ i ∈ (s ∩ t), f i) = (⨆ i ∈ s, f i) ⊓ (⨆ i ∈ t, f i) := by @@ -437,26 +418,33 @@ theorem biSup_inter_of_pairwise_disjoint {ι : Type*} {f : ι → α} · exact le_iSup₂_of_le i ⟨his, hij ▸ hjs⟩ inf_le_left · simp [h hij |>.eq_bot] +@[to_dual] theorem iSup_disjoint_iff {f : ι → α} : Disjoint (⨆ i, f i) a ↔ ∀ i, Disjoint (f i) a := by simp only [disjoint_iff, iSup_inf_eq, iSup_eq_bot] +@[to_dual] theorem disjoint_iSup_iff {f : ι → α} : Disjoint a (⨆ i, f i) ↔ ∀ i, Disjoint a (f i) := by simpa only [disjoint_comm] using @iSup_disjoint_iff +@[to_dual] theorem iSup₂_disjoint_iff {f : ∀ i, κ i → α} : Disjoint (⨆ (i) (j), f i j) a ↔ ∀ i j, Disjoint (f i j) a := by simp_rw [iSup_disjoint_iff] +@[to_dual] theorem disjoint_iSup₂_iff {f : ∀ i, κ i → α} : Disjoint a (⨆ (i) (j), f i j) ↔ ∀ i j, Disjoint a (f i j) := by simp_rw [disjoint_iSup_iff] +@[to_dual] theorem sSup_disjoint_iff {s : Set α} : Disjoint (sSup s) a ↔ ∀ b ∈ s, Disjoint b a := by simp only [disjoint_iff, sSup_inf_eq, iSup_eq_bot] +@[to_dual] theorem disjoint_sSup_iff {s : Set α} : Disjoint a (sSup s) ↔ ∀ b ∈ s, Disjoint a b := by simpa only [disjoint_comm] using @sSup_disjoint_iff +@[to_dual] theorem iSup_inf_of_monotone {ι : Type*} [Preorder ι] [IsDirectedOrder ι] {f g : ι → α} (hf : Monotone f) (hg : Monotone g) : ⨆ i, f i ⊓ g i = (⨆ i, f i) ⊓ ⨆ i, g i := by refine (le_iSup_inf_iSup f g).antisymm ?_ @@ -465,6 +453,7 @@ theorem iSup_inf_of_monotone {ι : Type*} [Preorder ι] [IsDirectedOrder ι] {f rcases directed_of (· ≤ ·) i.1 i.2 with ⟨j, h₁, h₂⟩ exact ⟨j, inf_le_inf (hf h₁) (hg h₂)⟩ +@[to_dual] theorem iSup_inf_of_antitone {ι : Type*} [Preorder ι] [IsCodirectedOrder ι] {f g : ι → α} (hf : Antitone f) (hg : Antitone g) : ⨆ i, f i ⊓ g i = (⨆ i, f i) ⊓ ⨆ i, g i := @iSup_inf_of_monotone α _ ιᵒᵈ _ _ f g hf.dual_left hg.dual_left @@ -478,7 +467,8 @@ theorem compl_eq_sSup_disjoint : aᶜ = sSup {w | Disjoint w a} := lemma himp_le_iff : a ⇨ b ≤ c ↔ ∀ d, d ⊓ a ≤ b → d ≤ c := by simp [himp_eq_sSup] -- see Note [lower instance priority] -instance (priority := 100) Frame.toDistribLattice : DistribLattice α := +@[to_dual] +instance (priority := 100) Order.Frame.toDistribLattice : DistribLattice α := DistribLattice.ofInfSupLe fun a b c => by rw [← sSup_pair, ← sSup_pair, inf_sSup_eq, ← sSup_image, image_pair] @@ -496,52 +486,11 @@ section Coframe variable [Coframe α] {s t : Set α} {a b c d : α} +@[to_dual existing] instance OrderDual.instFrame : Frame αᵒᵈ where __ := instCompleteLattice __ := instHeytingAlgebra -theorem sInf_sup_eq : sInf s ⊔ b = ⨅ a ∈ s, a ⊔ b := - @sSup_inf_eq αᵒᵈ _ _ _ - -theorem iInf_sup_eq (f : ι → α) (a : α) : (⨅ i, f i) ⊔ a = ⨅ i, f i ⊔ a := - @iSup_inf_eq αᵒᵈ _ _ _ _ - -theorem sup_iInf_eq (a : α) (f : ι → α) : (a ⊔ ⨅ i, f i) = ⨅ i, a ⊔ f i := - @inf_iSup_eq αᵒᵈ _ _ _ _ - -theorem iInf₂_sup_eq {f : ∀ i, κ i → α} (a : α) : (⨅ (i) (j), f i j) ⊔ a = ⨅ (i) (j), f i j ⊔ a := - @iSup₂_inf_eq αᵒᵈ _ _ _ _ _ - -theorem sup_iInf₂_eq {f : ∀ i, κ i → α} (a : α) : (a ⊔ ⨅ (i) (j), f i j) = ⨅ (i) (j), a ⊔ f i j := - @inf_iSup₂_eq αᵒᵈ _ _ _ _ _ - -theorem iSup_sdiff_eq {f : ι → α} : (⨆ x, f x) \ a = ⨆ x, f x \ a := - eq_of_forall_ge_iff fun _ => by simp - -theorem sdiff_iSup_eq {f : ι → α} : a \ ⨅ x, f x = ⨆ x, a \ f x := - eq_of_forall_ge_iff fun _ => by simp [iInf_sup_eq] - -@[to_dual existing] -theorem iInf_sup_iInf {ι ι' : Type*} {f : ι → α} {g : ι' → α} : - ((⨅ i, f i) ⊔ ⨅ i, g i) = ⨅ i : ι × ι', f i.1 ⊔ g i.2 := - @iSup_inf_iSup αᵒᵈ _ _ _ _ _ - -theorem biInf_sup_biInf {ι ι' : Type*} {f : ι → α} {g : ι' → α} {s : Set ι} {t : Set ι'} : - ((⨅ i ∈ s, f i) ⊔ ⨅ j ∈ t, g j) = ⨅ p ∈ s ×ˢ t, f (p : ι × ι').1 ⊔ g p.2 := - @biSup_inf_biSup αᵒᵈ _ _ _ _ _ _ _ - -theorem sInf_sup_sInf : sInf s ⊔ sInf t = ⨅ p ∈ s ×ˢ t, (p : α × α).1 ⊔ p.2 := - @sSup_inf_sSup αᵒᵈ _ _ _ - -@[to_dual existing] -theorem iInf_sup_of_monotone {ι : Type*} [Preorder ι] [IsCodirectedOrder ι] {f g : ι → α} - (hf : Monotone f) (hg : Monotone g) : ⨅ i, f i ⊔ g i = (⨅ i, f i) ⊔ ⨅ i, g i := - @iSup_inf_of_antitone αᵒᵈ _ _ _ _ _ _ hf.dual_right hg.dual_right - -theorem iInf_sup_of_antitone {ι : Type*} [Preorder ι] [IsDirectedOrder ι] {f g : ι → α} - (hf : Antitone f) (hg : Antitone g) : ⨅ i, f i ⊔ g i = (⨅ i, f i) ⊔ ⨅ i, g i := - @iSup_inf_of_monotone αᵒᵈ _ _ _ _ _ _ hf.dual_right hg.dual_right - theorem sdiff_eq_sInf : a \ b = sInf {w | a ≤ b ⊔ w} := (isLeast_sdiff a b).isGLB.sInf_eq.symm @@ -550,16 +499,12 @@ theorem hnot_eq_sInf_codisjoint : ¬a = sInf {w | Codisjoint a w} := lemma le_sdiff_iff : a ≤ b \ c ↔ ∀ d, b ≤ c ⊔ d → a ≤ d := by simp [sdiff_eq_sInf] --- see Note [lower instance priority] -instance (priority := 100) Coframe.toDistribLattice : DistribLattice α where - __ := ‹Coframe α› - le_sup_inf a b c := by - rw [← sInf_pair, ← sInf_pair, sup_sInf_eq, ← sInf_image, image_pair] - +@[to_dual existing] instance Prod.instCoframe [Coframe β] : Coframe (α × β) where __ := instCompleteLattice __ := instCoheytingAlgebra +@[to_dual existing] instance Pi.instCoframe {ι : Type*} {π : ι → Type*} [∀ i, Coframe (π i)] : Coframe (∀ i, π i) where __ := instCompleteLattice __ := instCoheytingAlgebra @@ -742,35 +687,20 @@ instance Prop.instCompleteBooleanAlgebra : CompleteBooleanAlgebra Prop := inferI section lift --- See note [reducible non-instances] /-- Pullback an `Order.Frame.MinimalAxioms` along an injection. -/ -protected abbrev Function.Injective.frameMinimalAxioms [Max α] [Min α] [LE α] [LT α] - [SupSet α] [InfSet α] [Top α] [Bot α] (minAx : Frame.MinimalAxioms β) - (f : α → β) (hf : Injective f) - (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) - (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b) - (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) (map_sInf : ∀ s, f (sInf s) = ⨅ a ∈ s, f a) - (map_top : f ⊤ = ⊤) (map_bot : f ⊥ = ⊥) : Frame.MinimalAxioms α where - __ := hf.completeLattice f le lt map_sup map_inf map_sSup map_sInf map_top map_bot +@[to_dual /-- Pullback an `Order.Coframe.MinimalAxioms` along a function. -/] +protected theorem Function.frameMinimalAxioms [CompleteLattice α] [CompleteLattice β] + (minAx : Frame.MinimalAxioms β) (f : α → β) + (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) + (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b) + (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) : Frame.MinimalAxioms α where inf_sSup_le_iSup_inf a s := by rw [← le, ← sSup_image, map_inf, map_sSup s, minAx.inf_iSup₂_eq] simp_rw [← map_inf] exact ((map_sSup _).trans iSup_image).ge --- See note [reducible non-instances] -/-- Pullback an `Order.Coframe.MinimalAxioms` along an injection. -/ -protected abbrev Function.Injective.coframeMinimalAxioms [Max α] [Min α] [LE α] [LT α] - [SupSet α] [InfSet α] [Top α] [Bot α] (minAx : Coframe.MinimalAxioms β) - (f : α → β) (hf : Injective f) - (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) - (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b) - (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) (map_sInf : ∀ s, f (sInf s) = ⨅ a ∈ s, f a) - (map_top : f ⊤ = ⊤) (map_bot : f ⊥ = ⊥) : Coframe.MinimalAxioms α where - __ := hf.completeLattice f le lt map_sup map_inf map_sSup map_sInf map_top map_bot - iInf_sup_le_sup_sInf a s := by - rw [← le, ← sInf_image, map_sup, map_sInf s, minAx.sup_iInf₂_eq] - simp_rw [← map_sup] - exact ((map_sInf _).trans iInf_image).le +@[to_dual (attr := deprecated (since := "2026-07-30"))] +alias Function.Injective.frameMinimalAxioms := Function.frameMinimalAxioms -- See note [reducible non-instances] /-- Pullback an `Order.Frame` along an injection. -/ @@ -781,7 +711,7 @@ protected abbrev Function.Injective.frame [Max α] [Min α] [LE α] [LT α] [Sup (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) (map_sInf : ∀ s, f (sInf s) = ⨅ a ∈ s, f a) (map_top : f ⊤ = ⊤) (map_bot : f ⊥ = ⊥) (map_compl : ∀ a, f aᶜ = (f a)ᶜ) (map_himp : ∀ a b, f (a ⇨ b) = f a ⇨ f b) : Frame α where - __ := hf.frameMinimalAxioms .of f le lt map_sup map_inf map_sSup map_sInf map_top map_bot + __ := hf.completeLattice f le lt map_sup map_inf map_sSup map_sInf map_top map_bot __ := hf.heytingAlgebra f le lt map_sup map_inf map_top map_bot map_compl map_himp -- See note [reducible non-instances] @@ -793,27 +723,23 @@ protected abbrev Function.Injective.coframe [Max α] [Min α] [LE α] [LT α] [S (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) (map_sInf : ∀ s, f (sInf s) = ⨅ a ∈ s, f a) (map_top : f ⊤ = ⊤) (map_bot : f ⊥ = ⊥) (map_hnot : ∀ a, f (¬a) = ¬f a) (map_sdiff : ∀ a b, f (a \ b) = f a \ f b) : Coframe α where - __ := hf.coframeMinimalAxioms .of f le lt map_sup map_inf map_sSup map_sInf map_top map_bot + __ := hf.completeLattice f le lt map_sup map_inf map_sSup map_sInf map_top map_bot __ := hf.coheytingAlgebra f le lt map_sup map_inf map_top map_bot map_hnot map_sdiff --- See note [reducible non-instances] /-- Pullback a `CompleteDistribLattice.MinimalAxioms` along an injection. -/ -protected abbrev Function.Injective.completeDistribLatticeMinimalAxioms [Max α] [Min α] - [LE α] [LT α] [SupSet α] [InfSet α] [Top α] [Bot α] - (minAx : CompleteDistribLattice.MinimalAxioms β) (f : α → β) (hf : Injective f) - (le : let _ := minAx.toCompleteLattice; ∀ {x y}, f x ≤ f y ↔ x ≤ y) - (lt : let _ := minAx.toCompleteLattice; ∀ {x y}, f x < f y ↔ x < y) - (map_sup : let _ := minAx.toCompleteLattice; ∀ a b, f (a ⊔ b) = f a ⊔ f b) - (map_inf : let _ := minAx.toCompleteLattice; ∀ a b, f (a ⊓ b) = f a ⊓ f b) - (map_sSup : let _ := minAx.toCompleteLattice; ∀ s, f (sSup s) = ⨆ a ∈ s, f a) - (map_sInf : let _ := minAx.toCompleteLattice; ∀ s, f (sInf s) = ⨅ a ∈ s, f a) - (map_top : let _ := minAx.toCompleteLattice; f ⊤ = ⊤) - (map_bot : let _ := minAx.toCompleteLattice; f ⊥ = ⊥) : +protected theorem Function.completeDistribLatticeMinimalAxioms + [CompleteLattice α] [CompleteLattice β] + (minAx : CompleteDistribLattice.MinimalAxioms β) (f : α → β) + (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) + (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b) + (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) (map_sInf : ∀ s, f (sInf s) = ⨅ a ∈ s, f a) : CompleteDistribLattice.MinimalAxioms α where - __ := hf.frameMinimalAxioms minAx.toFrame f - le lt map_sup map_inf map_sSup map_sInf map_top map_bot - __ := hf.coframeMinimalAxioms minAx.toCoframe f - le lt map_sup map_inf map_sSup map_sInf map_top map_bot + __ := f.frameMinimalAxioms minAx.toFrame le map_inf map_sSup + __ := f.coframeMinimalAxioms minAx.toCoframe le map_sup map_sInf + +@[deprecated (since := "2026-07-30")] +alias Function.Injective.completeDistribLatticeMinimalAxioms := + Function.completeDistribLatticeMinimalAxioms -- See note [reducible non-instances] /-- Pullback a `CompleteDistribLattice` along an injection. -/ @@ -830,22 +756,12 @@ protected abbrev Function.Injective.completeDistribLattice [Max α] [Min α] __ := hf.frame f le lt map_sup map_inf map_sSup map_sInf map_top map_bot map_compl map_himp __ := hf.coframe f le lt map_sup map_inf map_sSup map_sInf map_top map_bot map_hnot map_sdiff --- See note [reducible non-instances] /-- Pullback a `CompletelyDistribLattice.MinimalAxioms` along an injection. -/ -protected abbrev Function.Injective.completelyDistribLatticeMinimalAxioms [Max α] [Min α] - [LE α] [LT α] [SupSet α] [InfSet α] [Top α] [Bot α] +protected theorem Function.Injective.completelyDistribLatticeMinimalAxioms + [CompleteLattice α] [CompleteLattice β] (minAx : CompletelyDistribLattice.MinimalAxioms β) (f : α → β) (hf : Injective f) - (le : let _ := minAx.toCompleteLattice; ∀ {x y}, f x ≤ f y ↔ x ≤ y) - (lt : let _ := minAx.toCompleteLattice; ∀ {x y}, f x < f y ↔ x < y) - (map_sup : let _ := minAx.toCompleteLattice; ∀ a b, f (a ⊔ b) = f a ⊔ f b) - (map_inf : let _ := minAx.toCompleteLattice; ∀ a b, f (a ⊓ b) = f a ⊓ f b) - (map_sSup : let _ := minAx.toCompleteLattice; ∀ s, f (sSup s) = ⨆ a ∈ s, f a) - (map_sInf : let _ := minAx.toCompleteLattice; ∀ s, f (sInf s) = ⨅ a ∈ s, f a) - (map_top : let _ := minAx.toCompleteLattice; f ⊤ = ⊤) - (map_bot : let _ := minAx.toCompleteLattice; f ⊥ = ⊥) : + (map_sSup : ∀ s, f (sSup s) = ⨆ a ∈ s, f a) (map_sInf : ∀ s, f (sInf s) = ⨅ a ∈ s, f a) : CompletelyDistribLattice.MinimalAxioms α where - __ := hf.completeDistribLatticeMinimalAxioms minAx.toCompleteDistribLattice f - le lt map_sup map_inf map_sSup map_sInf map_top map_bot iInf_iSup_eq g := hf <| by simp_rw [iInf, map_sInf, iInf_range, iSup, map_sSup, iSup_range, map_sInf, iInf_range, minAx.iInf_iSup_eq'] @@ -954,12 +870,8 @@ instance instCompleteBooleanAlgebra : CompleteBooleanAlgebra PUnit where instance instCompleteAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra PUnit where iInf_iSup_eq _ := rfl -@[simp] +@[to_dual (attr := simp)] theorem sSup_eq : sSup s = unit := rfl -@[simp] -theorem sInf_eq : sInf s = unit := - rfl - end PUnit diff --git a/Mathlib/Order/CompleteLattice/Defs.lean b/Mathlib/Order/CompleteLattice/Defs.lean index 18741feeb3b5e3..86abda9d041f21 100644 --- a/Mathlib/Order/CompleteLattice/Defs.lean +++ b/Mathlib/Order/CompleteLattice/Defs.lean @@ -137,7 +137,7 @@ instance {α : Type*} [CompleteSemilatticeInf α] : CompleteSemilatticeSup αᵒ class CompleteLattice (α : Type*) extends Lattice α, CompleteSemilatticeSup α, CompleteSemilatticeInf α, BoundedOrder α -attribute [to_dual existing] CompleteLattice.toCompleteSemilatticeInf +attribute [to_dual existing] CompleteLattice.toCompleteSemilatticeInf CompleteLattice.toInfSet attribute [to_dual self (reorder := toSupSet toInfSet, isLUB_sSup isGLB_sInf)] CompleteLattice.mk -- Shortcut instance to ensure that the path diff --git a/Mathlib/Order/Nucleus.lean b/Mathlib/Order/Nucleus.lean index cc518b3a99cdf0..1aca7f95e1a2fa 100644 --- a/Mathlib/Order/Nucleus.lean +++ b/Mathlib/Order/Nucleus.lean @@ -250,15 +250,13 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in instance : CompleteLattice (range n) := n.giAux.liftCompleteLattice -instance range.instFrameMinimalAxioms : Frame.MinimalAxioms (range n) where +instance : Frame (range n) := .ofMinimalAxioms { inf_sSup_le_iSup_inf a s := by simp_rw [← Subtype.coe_le_coe, iSup_subtype', iSup, sSup, n.giAux.gc.u_inf] rw [rangeFactorization_coe, ← mem_range.1 a.prop, ← map_inf] apply n.monotone simp_rw [inf_sSup_eq, sSup_image, iSup_range, iSup_image, iSup_subtype', n.giAux.gc.u_inf, - le_rfl] - -instance : Frame (range n) := .ofMinimalAxioms range.instFrameMinimalAxioms + le_rfl] } /-- Restrict a nucleus to its range. -/ @[simps] def restrict (n : Nucleus X) : FrameHom X (range n) where diff --git a/Mathlib/Order/Sublocale.lean b/Mathlib/Order/Sublocale.lean index 02ae6cdf9f8cc3..aa2dfda9e82b35 100644 --- a/Mathlib/Order/Sublocale.lean +++ b/Mathlib/Order/Sublocale.lean @@ -233,10 +233,7 @@ instance Sublocale.instCompleteLattice : CompleteLattice (Sublocale X) := nucleusIsoSublocale.toGaloisInsertion.liftCompleteLattice set_option backward.isDefEq.respectTransparency false in -instance Sublocale.instCoframeMinimalAxioms : Order.Coframe.MinimalAxioms (Sublocale X) where +instance Sublocale.instCoframe : Order.Coframe (Sublocale X) := .ofMinimalAxioms { iInf_sup_le_sup_sInf a s := by simp [← toNucleus_le_toNucleus, nucleusIsoSublocale.symm_eq_toNucleus, nucleusIsoSublocale.symm.map_sup, - nucleusIsoSublocale.symm.map_sInf, sup_iInf_eq, nucleusIsoSublocale.symm.map_iInf] - -instance Sublocale.instCoframe : Order.Coframe (Sublocale X) := - .ofMinimalAxioms instCoframeMinimalAxioms + nucleusIsoSublocale.symm.map_sInf, sup_iInf_eq, nucleusIsoSublocale.symm.map_iInf] } diff --git a/Mathlib/Order/UpperLower/CompleteLattice.lean b/Mathlib/Order/UpperLower/CompleteLattice.lean index 1c0cbbbe629193..994b58417d9fff 100644 --- a/Mathlib/Order/UpperLower/CompleteLattice.lean +++ b/Mathlib/Order/UpperLower/CompleteLattice.lean @@ -98,7 +98,7 @@ instance completeLattice : CompleteLattice (UpperSet α) := instance completelyDistribLattice : CompletelyDistribLattice (UpperSet α) := .ofMinimalAxioms <| (toDual.injective.comp SetLike.coe_injective).completelyDistribLatticeMinimalAxioms .of _ - .rfl .rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) rfl rfl + (fun _ ↦ rfl) (fun _ ↦ rfl) @[to_dual existing] instance _root_.LowerSet.instPartialOrder : PartialOrder (LowerSet α) := @@ -112,7 +112,7 @@ instance _root_.LowerSet.completeLattice : CompleteLattice (LowerSet α) := @[to_dual existing] instance _root_.LowerSet.completelyDistribLattice : CompletelyDistribLattice (LowerSet α) := .ofMinimalAxioms <| SetLike.coe_injective.completelyDistribLatticeMinimalAxioms .of _ - .rfl .rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) rfl rfl + (fun _ ↦ rfl) (fun _ ↦ rfl) @[to_dual] instance : Inhabited (UpperSet α) := diff --git a/Mathlib/Tactic/Translate/ToDual.lean b/Mathlib/Tactic/Translate/ToDual.lean index 8be53641e43fec..39f34ddc4893c3 100644 --- a/Mathlib/Tactic/Translate/ToDual.lean +++ b/Mathlib/Tactic/Translate/ToDual.lean @@ -272,6 +272,7 @@ def abbreviationDict : Std.HashMap String String := .ofList [ ("neTop", "NeBot"), ("decidableSucc", "DecidablePred"), ("ofSucc", "OfPred"), + ("maximalAxioms", "MinimalAxioms"), ] @[inherit_doc GuessName.GuessNameExt] diff --git a/Mathlib/Topology/Sets/Closeds.lean b/Mathlib/Topology/Sets/Closeds.lean index e869ee8e83191a..0528efb04105c6 100644 --- a/Mathlib/Topology/Sets/Closeds.lean +++ b/Mathlib/Topology/Sets/Closeds.lean @@ -182,13 +182,9 @@ theorem iInf_mk {ι} (s : ι → Set α) (h : ∀ i, IsClosed (s i)) : (⨅ i, ⟨s i, h i⟩ : Closeds α) = ⟨⋂ i, s i, isClosed_iInter h⟩ := iInf_def _ -/-- Closed sets in a topological space form a coframe. -/ -@[instance_reducible] -def coframeMinimalAxioms : Coframe.MinimalAxioms (Closeds α) where +instance instCoframe : Coframe (Closeds α) := fast_instance% .ofMinimalAxioms { iInf_sup_le_sup_sInf a s := - (SetLike.coe_injective <| by simp only [coe_sup, coe_iInf, coe_sInf, Set.union_iInter₂]).le - -instance instCoframe : Coframe (Closeds α) := fast_instance% .ofMinimalAxioms coframeMinimalAxioms + (SetLike.coe_injective <| by simp only [coe_sup, coe_iInf, coe_sInf, Set.union_iInter₂]).le } @[simps] instance [T1Space α] : Singleton α (Closeds α) where diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index 7e789d277caf22..afc8e565fd3629 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -257,13 +257,9 @@ theorem mem_iSup {ι} {x : α} {s : ι → Opens α} : x ∈ iSup s ↔ ∃ i, x theorem mem_sSup {Us : Set (Opens α)} {x : α} : x ∈ sSup Us ↔ ∃ u ∈ Us, x ∈ u := by simp_rw [sSup_eq_iSup, mem_iSup, exists_prop] -/-- Open sets in a topological space form a frame. -/ -@[instance_reducible] -def frameMinimalAxioms : Frame.MinimalAxioms (Opens α) where +instance instFrame : Frame (Opens α) := fast_instance% .ofMinimalAxioms { inf_sSup_le_iSup_inf a s := - (ext <| by simp only [coe_inf, coe_iSup, coe_sSup, Set.inter_iUnion₂]).le - -instance instFrame : Frame (Opens α) := fast_instance% .ofMinimalAxioms frameMinimalAxioms + (ext <| by simp only [coe_inf, coe_iSup, coe_sSup, Set.inter_iUnion₂]).le } theorem mem_himp {U V : Opens α} {x : α} : x ∈ U ⇨ V ↔ ∃ W : Opens α, W ⊓ U ≤ V ∧ x ∈ W := by simp [himp_eq_sSup] From 6cf26736859c0f0a57cc556c9872cdecdceb76ce Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 10 Aug 2026 08:17:42 +0000 Subject: [PATCH 1228/1300] feat(FieldTheory): typeclass for field extension with finite transcendence degree (#42152) Make a new typeclass for field extensions with finite transcendence degree. See [Zulip](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/typeclass.20for.20finite.20transcendence.20basis/near/612845827). --- Mathlib.lean | 1 + Mathlib/FieldTheory/FinTrdeg.lean | 91 +++++++++++++++++++ .../IntermediateField/Adjoin/Basic.lean | 12 +++ .../TranscendenceBasis.lean | 2 +- 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 Mathlib/FieldTheory/FinTrdeg.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4aac5224fd24fa..e5c0e22680d50c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4522,6 +4522,7 @@ public import Mathlib.FieldTheory.ChevalleyWarning public import Mathlib.FieldTheory.Differential.Basic public import Mathlib.FieldTheory.Differential.Liouville public import Mathlib.FieldTheory.Extension +public import Mathlib.FieldTheory.FinTrdeg public import Mathlib.FieldTheory.Finite.Basic public import Mathlib.FieldTheory.Finite.Extension public import Mathlib.FieldTheory.Finite.GaloisField diff --git a/Mathlib/FieldTheory/FinTrdeg.lean b/Mathlib/FieldTheory/FinTrdeg.lean new file mode 100644 index 00000000000000..ee0c7d64506441 --- /dev/null +++ b/Mathlib/FieldTheory/FinTrdeg.lean @@ -0,0 +1,91 @@ +/- +Copyright (c) 2026 Aaron Liu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Aaron Liu +-/ +module + +public import Mathlib.RingTheory.AlgebraicIndependent.TranscendenceBasis +public import Mathlib.FieldTheory.IntermediateField.Adjoin.Algebra +public import Mathlib.FieldTheory.IntermediateField.Adjoin.Basic + +/-! +# Extensions with Finite Transcendence Degree + +A field extension L/K has finite transcendence degree if +the transcendence degree of L over K is finite. +Equivalently, if L is an algebraic extension of a finitely generated field extension of K. +-/ + +public section + +open IntermediateField + +/-- A field extension L/K is said to have finite transcendence degree if there is some +intermediate extension L/E/K with E/K finitely generated and L/E algebraic. -/ +class FinTrdeg (K L : Type*) [Field K] [Field L] [Algebra K L] where + exists_fg_isAlgebraic (K L) : ∃ E : IntermediateField K L, E.FG ∧ Algebra.IsAlgebraic E L + +variable {K L : Type*} [Field K] [Field L] [Algebra K L] + +variable (K L) in +instance [Algebra.IsAlgebraic K L] : FinTrdeg K L where + exists_fg_isAlgebraic := ⟨⊥, IntermediateField.fg_bot, inferInstance⟩ + +variable (K L) in +instance [Algebra.EssFiniteType K L] : FinTrdeg K L where + exists_fg_isAlgebraic := ⟨⊤, IntermediateField.fg_top_iff.mpr ‹_›, inferInstance⟩ + +theorem finTrdeg_iff_trdeg : FinTrdeg K L ↔ Algebra.trdeg K L < .aleph0 := by + constructor + · intro ⟨E, fg, alg⟩ + rw [← trdeg_add_eq K E, trdeg_eq_zero_iff.2 alg, add_zero] + rw [← essFiniteType_iff, Algebra.essFiniteType_iff_exists_subalgebra] at fg + obtain ⟨S₀, M, fin, islocal⟩ := fg + rw [← trdeg_add_eq K S₀, trdeg_eq_zero_iff.2 islocal.isAlgebraic, add_zero] + exact trdeg_lt_aleph0_of_finiteType + · intro h + obtain ⟨s, hs⟩ := exists_isTranscendenceBasis K L + have fin : s.Finite := Cardinal.lt_aleph0_iff_set_finite.1 (hs.cardinalMk_eq_trdeg.trans_lt h) + constructor + refine ⟨adjoin K s, fg_adjoin_of_finite fin, ?_⟩ + have alg := hs.isAlgebraic_field + rwa [Subtype.range_coe] at alg + +alias ⟨_, FinTrdeg.of_trdeg⟩ := finTrdeg_iff_trdeg + +variable (K L) in +theorem trdeg_lt_aleph0 [FinTrdeg K L] : Algebra.trdeg K L < .aleph0 := + finTrdeg_iff_trdeg.mp ‹_› + +theorem FinTrdeg.trans (K E L : Type*) [Field K] [Field E] [Field L] + [Algebra K E] [Algebra K L] [Algebra E L] [IsScalarTower K E L] + [FinTrdeg K E] [FinTrdeg E L] : FinTrdeg K L := by + rw [finTrdeg_iff_trdeg, ← Cardinal.lift_lt_aleph0, ← lift_trdeg_add_eq K E L, + Cardinal.add_lt_aleph0_iff, Cardinal.lift_lt_aleph0, Cardinal.lift_lt_aleph0] + exact ⟨trdeg_lt_aleph0 K E, trdeg_lt_aleph0 E L⟩ + +theorem finite_of_isTranscendenceBasis [FinTrdeg K L] {ι : Type*} {x : ι → L} + (hx : IsTranscendenceBasis K x) : Finite ι := by + rw [← Cardinal.mk_lt_aleph0_iff, ← Cardinal.lift_lt_aleph0, + hx.lift_cardinalMk_eq_trdeg, Cardinal.lift_lt_aleph0] + exact trdeg_lt_aleph0 K L + +theorem finite_of_algebraicIndependent [FinTrdeg K L] {ι : Type*} {x : ι → L} + (hx : AlgebraicIndependent K x) : Finite ι := by + rw [← Cardinal.mk_lt_aleph0_iff, ← Cardinal.lift_lt_aleph0] + exact hx.lift_cardinalMk_le_trdeg.trans_lt (Cardinal.lift_lt_aleph0.mpr (trdeg_lt_aleph0 K L)) + +theorem FinTrdeg.of_isTranscendenceBasis {ι : Type*} [Finite ι] {x : ι → L} + (hx : IsTranscendenceBasis K x) : FinTrdeg K L := by + rw [finTrdeg_iff_trdeg, ← Cardinal.lift_lt_aleph0, + ← hx.lift_cardinalMk_eq_trdeg, Cardinal.lift_lt_aleph0] + exact Cardinal.mk_lt_aleph0 + +variable (K L) in +theorem exists_finset_isTranscendenceBasis [FinTrdeg K L] : + ∃ s : Finset L, IsTranscendenceBasis K ((↑) : s → L) := by + obtain ⟨s, hs⟩ := exists_isTranscendenceBasis K L + obtain ⟨s, rfl⟩ := Finset.mem_range_coe_iff.2 + (Set.finite_coe_iff.1 (finite_of_isTranscendenceBasis hs)) + exact ⟨s, hs⟩ diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean index e29255c21b390a..e02ae0d68e269b 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Basic.lean @@ -554,6 +554,18 @@ theorem _root_.Polynomial.Irreducible.natDegree_dvd_finrank {f : K[X]} (hi : Irr contrapose hi rwa [hi, mul_zero] at key +instance : Algebra.IsAlgebraic K (⊥ : IntermediateField K L) where + isAlgebraic := by + intro ⟨x, hx⟩ + obtain ⟨c, rfl⟩ := hx + exact isAlgebraic_algebraMap c + +instance : Algebra.IsAlgebraic (⊤ : IntermediateField K L) L where + isAlgebraic := by + intro x + let xt : (⊤ : IntermediateField K L) := ⟨x, mem_top⟩ + exact isAlgebraic_algebraMap xt + -- TODO: generalize to `Sort` /-- A compositum of algebraic extensions is algebraic -/ theorem isAlgebraic_iSup {ι : Type*} {t : ι → IntermediateField K L} diff --git a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean index 3fc6d888aef1fc..4fbff1f01e5b53 100644 --- a/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean +++ b/Mathlib/RingTheory/AlgebraicIndependent/TranscendenceBasis.lean @@ -451,7 +451,7 @@ theorem Polynomial.trdeg_of_isDomain [IsDomain R] : trdeg R (Polynomial R) = 1 : simpa using (IsTranscendenceBasis.polynomial Unit R).lift_cardinalMk_eq_trdeg.symm -- TODO: generalize to Nontrivial S -theorem trdeg_lt_aleph0 [IsDomain R] [fin : FiniteType R S] : trdeg R S < ℵ₀ := +theorem trdeg_lt_aleph0_of_finiteType [IsDomain R] [fin : FiniteType R S] : trdeg R S < ℵ₀ := have ⟨n, f, surj⟩ := FiniteType.iff_quotient_mvPolynomial''.mp fin lift_lt.mp <| (lift_trdeg_le_of_surjective f surj).trans_lt <| by simp From 7089d5260553c32efbce682e4448c5cb53fffcb5 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 10 Aug 2026 08:17:44 +0000 Subject: [PATCH 1229/1300] feat: principal ideal is maximal iff generator is irreducible (#42332) Prove the theorem that if a principal ideal is maximal and not generated by an idempotent, then the generator is irreducible. Prove that in a domain if a principal ideal is maximal and its generator is nonzero then it is irreducible. Prove that in a principal ideal domain a principal ideal is maximal iff its generator is irreducible. --- Mathlib/RingTheory/Ideal/Maximal.lean | 34 ++++++++++++++++++++ Mathlib/RingTheory/PrincipalIdealDomain.lean | 5 +++ 2 files changed, 39 insertions(+) diff --git a/Mathlib/RingTheory/Ideal/Maximal.lean b/Mathlib/RingTheory/Ideal/Maximal.lean index f4cfefe052d189..5d7eb16cfa9833 100644 --- a/Mathlib/RingTheory/Ideal/Maximal.lean +++ b/Mathlib/RingTheory/Ideal/Maximal.lean @@ -227,6 +227,40 @@ theorem exists_le_prime_notMem_of_isIdempotentElem (a : α) (ha : IsIdempotentEl have ⟨p, h1, h2, h3⟩ := exists_le_prime_disjoint _ _ this ⟨p, h1, h2, Set.disjoint_right.mp h3 (Submonoid.mem_powers a)⟩ +/-- If a maximal principal ideal is not generated by an idempotent, +then every generator is irreducible. -/ +theorem irreducible_of_isMaximal_of_eq_span_singleton_of_not_isIdempotentElem {a : α} + (max : (Ideal.span {a}).IsMaximal) + (idem : ∀ x, Ideal.span {a} = Ideal.span {x} → ¬IsIdempotentElem x) : + Irreducible a := by + constructor + · intro ha + apply max.ne_top + rw [span_singleton_eq_top.2 ha] + · intro u v ha + by_contra! huv + have hu : span {u} ≤ span {a} := + (max.eq_of_le (span_singleton_ne_top huv.1) + (span_singleton_le_span_singleton.2 ((dvd_mul_right u v).trans ha.symm.dvd))).ge + have hv : span {v} ≤ span {a} := + (max.eq_of_le (span_singleton_ne_top huv.2) + (span_singleton_le_span_singleton.2 ((dvd_mul_left v u).trans ha.symm.dvd))).ge + rw [span_singleton_le_span_singleton] at hu hv + obtain ⟨c, rfl⟩ := hu + obtain ⟨d, rfl⟩ := hv + refine idem (a * (c * d)) ?_ ?_ + · apply le_antisymm <;> rw [span_singleton_le_span_singleton] + · exact (dvd_mul_right (a * (c * d)) a).trans (ha.trans (by ring)).symm.dvd + · apply dvd_mul_right + · rw [isIdempotentElem_iff] + refine Eq.trans ?_ (congrArg (· * (c * d)) ha.symm) + ring + +theorem irreducible_of_isMaximal_span_singleton [IsDomain α] {a : α} + (ha : a ≠ 0) (max : (Ideal.span {a}).IsMaximal) : + Irreducible a := + ((Ideal.span_singleton_prime ha).1 max.isPrime).irreducible + section IsPrincipalIdealRing variable [IsPrincipalIdealRing α] diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index 82cef431407d2e..a3857b75db71ae 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -330,6 +330,11 @@ theorem isMaximal_of_irreducible [CommSemiring R] [IsPrincipalIdealRing R] {p : rw [Ideal.submodule_span_eq, Ideal.submodule_span_eq, Ideal.span_singleton_le_span_singleton, IsUnit.mul_right_dvd hb]⟩⟩ +theorem _root_.Ideal.irreducible_iff_isMaximal_span_singleton + [CommSemiring R] [IsPrincipalIdealRing R] [IsDomain R] {p : R} (hp : p ≠ 0) : + Irreducible p ↔ Ideal.IsMaximal (span R ({p} : Set R)) := + ⟨isMaximal_of_irreducible, Ideal.irreducible_of_isMaximal_span_singleton hp⟩ + variable [CommRing R] [IsDomain R] [IsPrincipalIdealRing R] section From 3cf9c0a79c84574b37b77b7031cd56e9d0760fea Mon Sep 17 00:00:00 2001 From: Attila Vajda <46789083+attilavjda@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:47 +0000 Subject: [PATCH 1230/1300] chore(GroupTheory/Complement): deduplicate IsComplement.card_mul (#42493) IsComplement.card_mul restated IsComplement.card_mul_card. Keep the latter (conventional name, has to_additive), deprecate the former, rename IsComplement'.card_mul to match, update the call site. Aristotle helped with finding the duplicates, generating and verifing the code, understanding the proofs, preparing the PR and reasoning. --- Mathlib/GroupTheory/Complement.lean | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Mathlib/GroupTheory/Complement.lean b/Mathlib/GroupTheory/Complement.lean index b637ad28cc68ea..3612796da5a4f4 100644 --- a/Mathlib/GroupTheory/Complement.lean +++ b/Mathlib/GroupTheory/Complement.lean @@ -653,13 +653,15 @@ noncomputable def IsComplement'.QuotientMulEquiv [K.Normal] (h : H.IsComplement' { h.leftQuotientEquiv.symm with map_mul' := fun _ _ ↦ rfl } -theorem IsComplement.card_mul (h : IsComplement S T) : - Nat.card S * Nat.card T = Nat.card G := - (Nat.card_prod _ _).symm.trans (Nat.card_eq_of_bijective _ h) - -theorem IsComplement'.card_mul (h : IsComplement' H K) : +theorem IsComplement'.card_mul_card (h : IsComplement' H K) : Nat.card H * Nat.card K = Nat.card G := - IsComplement.card_mul h + IsComplement.card_mul_card h + +@[deprecated (since := "2026-08-06")] +alias IsComplement.card_mul := IsComplement.card_mul_card + +@[deprecated (since := "2026-08-06")] +alias IsComplement'.card_mul := IsComplement'.card_mul_card theorem isComplement'_of_disjoint_and_mul_eq_univ (h1 : Disjoint H K) (h2 : ↑H * ↑K = (Set.univ : Set G)) : IsComplement' H K := by @@ -675,7 +677,7 @@ theorem isComplement'_of_card_mul_and_disjoint [Finite G] theorem isComplement'_iff_card_mul_and_disjoint [Finite G] : IsComplement' H K ↔ Nat.card H * Nat.card K = Nat.card G ∧ Disjoint H K := - ⟨fun h => ⟨h.card_mul, h.disjoint⟩, fun h => isComplement'_of_card_mul_and_disjoint h.1 h.2⟩ + ⟨fun h => ⟨h.card_mul_card, h.disjoint⟩, fun h => isComplement'_of_card_mul_and_disjoint h.1 h.2⟩ theorem isComplement'_of_coprime [Finite G] (h1 : Nat.card H * Nat.card K = Nat.card G) From 3ef2c2e23a8b5a46554fa771969b89287972b616 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 08:17:49 +0000 Subject: [PATCH 1231/1300] chore(WhatsNew): rename `whatsnew` to `#whats_new` (#42537) This PR renames `whatsnew` to `#whats_new`, following the naming convention. See https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.60whatsnew.20in.60.20rename/with/615003669 --- Mathlib/Util/WhatsNew.lean | 13 ++++++++++--- MathlibTest/BasicFiles/TacticCommon.lean | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Mathlib/Util/WhatsNew.lean b/Mathlib/Util/WhatsNew.lean index b833d1f05b79f0..10f83461a8c1d9 100644 --- a/Mathlib/Util/WhatsNew.lean +++ b/Mathlib/Util/WhatsNew.lean @@ -12,7 +12,7 @@ Defines a command wrapper that prints the changes the command makes to the environment. ``` -whatsnew in +#whats_new in theorem foo : 42 = 6 * 7 := rfl ``` -/ @@ -115,9 +115,9 @@ def whatsNew (old new : Environment) : CoreM MessageData := do pure <| MessageData.joinSep diffs.toList "\n\n" -/-- `whatsnew in $command` executes the command and then prints the +/-- `#whats_new in` executes the following command and then prints the declarations that were added to the environment. -/ -elab "whatsnew " "in" ppLine cmd:command : command => do +elab "#whats_new " "in" ppLine cmd:command : command => do let oldEnv ← getEnv try elabCommand cmd @@ -125,4 +125,11 @@ elab "whatsnew " "in" ppLine cmd:command : command => do let newEnv ← getEnv logInfo (← liftCoreM <| whatsNew oldEnv newEnv) +/-- `#whats_new in` executes the following command and then prints the +declarations that were added to the environment. -/ +macro (name := oldStx) "whatsnew " "in" ppLine cmd:command : command => + `(command| #whats_new in $cmd) + +deprecated_syntax oldStx "use `#whats_new` instead of `whatsnew`" (since := "2026-08-07") + end Mathlib.WhatsNew diff --git a/MathlibTest/BasicFiles/TacticCommon.lean b/MathlibTest/BasicFiles/TacticCommon.lean index 3ae7c274824d68..4b6dedb827a3c1 100644 --- a/MathlibTest/BasicFiles/TacticCommon.lean +++ b/MathlibTest/BasicFiles/TacticCommon.lean @@ -20,7 +20,7 @@ theorem test_check_tactic : True := by #simp only [] => 0 #guard_msgs (substring := true) in -whatsnew in +#whats_new in theorem test_whatsnew : True := trivial #guard_msgs (substring := true) in From db584cd6d46c92f209a44c0f1c829460d327499d Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Mon, 10 Aug 2026 09:12:31 +0000 Subject: [PATCH 1232/1300] chore: bump toolchain to v4.33.0 (#42604) Co-authored-by: Joscha --- Mathlib/Tactic/Linter/Style.lean | 7 +++++-- lake-manifest.json | 18 +++++++++--------- lean-toolchain | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Mathlib/Tactic/Linter/Style.lean b/Mathlib/Tactic/Linter/Style.lean index ccfca84e020510..fdf363f002d7df 100644 --- a/Mathlib/Tactic/Linter/Style.lean +++ b/Mathlib/Tactic/Linter/Style.lean @@ -554,12 +554,15 @@ such names violate the naming convention. -/ noErrorsFound := "no definitions with an underscore in their name found." errorsFound := "FOUND definitions with an underscore in their name." test declName := do - unless ((← getEnv).find? declName).get!.isDefinition && !(← isAutoDecl declName) do return none + unless ((← getEnv).find? declName).get!.isDefinition && + -- TODO: lint private definitions with underscores for readability. + !(← isPrivateOrAutoDecl declName) do + return none -- We also exclude simprocs: these should be named like normal lemmas. -- check if their type is `Lean.Meta.Simp.Simproc`. if ((← getEnv).find? declName).get!.type.isConstOf `Lean.Meta.Simp.Simproc then return none if isBadNameWithUnderscore declName then - return m!"The definition `{declName}` contains an underscore. \ + return m!"The definition `{.ofConstName declName true}` contains an underscore. \ This almost surely violates mathlib's naming convention; \ use lowerCamelCase or UpperCamelCase instead." else return none diff --git a/lake-manifest.json b/lake-manifest.json index 1f8331b1fe5aa9..1a4cd1dbe61cb8 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "123d15766ba49356c02ebad2a4462dfe12d79899", + "rev": "b7eb3304aeae834b12dda98993a37f6a41f6f0bb", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f5c090429dff3cf66cb65562526c9ea6e8edfbcb", + "rev": "5f4d51b81cbd3f6b32b156bfad9056621a040404", "name": "LeanSearchClient", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "bb3469a87774349fe01898d8bf2fc6a1ce6411ca", + "rev": "16f02aa7642864af59f1ff0e384a015994db9118", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "222c58dad7706a6e7cae46c0edd65ea881d3ee27", + "rev": "4be2e3d5087eeb272cf5a8853b8f9dd025ef5957", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "7db8190085343afde2f5d2cdcc9bac719b6ec02c", + "rev": "3448c0bcc5ce01b2d1546e483ec3620e32df3d0e", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "ef42f8944eaf5b6cbfbe75d1917d824c7dd6cf33", + "rev": "92c15be17b7caf78c2ad767ec40f89052d908d81", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "76e1c118b0700b4ceafe99532e887d6431625e1a", + "rev": "4488d40d070b9700d4d5a6aa342f0d40c31b2a2d", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "1319485273bf87833fa472afbcefdedecb16b45f", + "rev": "6130a47896ce867c6a4a55373441e59e565bad0f", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.33.0-rc2", + "inputRev": "v4.33.0", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lean-toolchain b/lean-toolchain index c084c7fbe586b0..025e59548e48cf 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.33.0-rc2 +leanprover/lean4:v4.33.0 From 5d2a6a322723360b7094f2ed1b9774e0fc7da21d Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 10 Aug 2026 10:19:04 +0000 Subject: [PATCH 1233/1300] chore: remove `IsDedekindDomainDvr` (#42367) Remove `IsDedekindDomainDvr`, because is the same as `IsDedekindDomain`. See [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/three.20dedekind.20domains/near/574535735). Co-authored-by: Oliver Nash --- .../NumberField/ExistsRamified.lean | 2 +- Mathlib/RingTheory/DedekindDomain/Basic.lean | 5 +- Mathlib/RingTheory/DedekindDomain/Dvr.lean | 101 ++++++++---------- Mathlib/RingTheory/Trace/Quotient.lean | 21 +--- Mathlib/RingTheory/Unramified/Dedekind.lean | 18 ++-- 5 files changed, 56 insertions(+), 91 deletions(-) diff --git a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean index 39c74954022c07..78064d079d6bdf 100644 --- a/Mathlib/NumberTheory/NumberField/ExistsRamified.lean +++ b/Mathlib/NumberTheory/NumberField/ExistsRamified.lean @@ -58,7 +58,7 @@ lemma NumberField.finrank_eq_one_of_unramified [Algebra.Unramified ℤ 𝒪] : lemma bijective_algebraMap_int_of_finite_of_unramified [Module.Finite ℤ 𝒪] [Algebra.Unramified ℤ 𝒪] [IsDomain 𝒪] [FaithfulSMul ℤ 𝒪] : Function.Bijective (algebraMap ℤ 𝒪) := by - have := isDedekindDomain.of_formallyUnramified ℤ 𝒪 + have := IsDedekindDomain.of_formallyUnramified ℤ 𝒪 let K := FractionRing 𝒪 let : Algebra ℤ K := Ring.toIntAlgebra K have : CharZero 𝒪 := Algebra.charZero_of_charZero ℤ _ diff --git a/Mathlib/RingTheory/DedekindDomain/Basic.lean b/Mathlib/RingTheory/DedekindDomain/Basic.lean index 836e591313a5c6..28b2a8468ebf11 100644 --- a/Mathlib/RingTheory/DedekindDomain/Basic.lean +++ b/Mathlib/RingTheory/DedekindDomain/Basic.lean @@ -139,9 +139,8 @@ This is exactly `IsDedekindRing` plus the `IsDomain` hypothesis. The integral closure condition is independent of the choice of field of fractions: use `isDedekindDomain_iff` to prove `IsDedekindDomain` for a given `fraction_map`. -This is the default implementation, but there are equivalent definitions, -`IsDedekindDomainDvr` and `IsDedekindDomainInv`. --/ +See also `isDedekindDomain_iff_isDiscreteValuationRing_atPrime` and +`isDedekindDomain_iff_mul_inv_cancel`. -/ class IsDedekindDomain : Prop extends IsDomain A, IsDedekindRing A diff --git a/Mathlib/RingTheory/DedekindDomain/Dvr.lean b/Mathlib/RingTheory/DedekindDomain/Dvr.lean index 0117b1b8ebd0c9..bdf27f19775cf3 100644 --- a/Mathlib/RingTheory/DedekindDomain/Dvr.lean +++ b/Mathlib/RingTheory/DedekindDomain/Dvr.lean @@ -14,16 +14,11 @@ public import Mathlib.RingTheory.LocalProperties.IntegrallyClosed This file defines an equivalent notion of a Dedekind domain (or Dedekind ring), namely a Noetherian integral domain where the localization at every nonzero prime ideal is a DVR. -## Main definitions - -- `IsDedekindDomainDvr` alternatively defines a Dedekind domain as an integral domain that - is Noetherian, and the localization at every nonzero prime ideal is a DVR. - ## Main results - `IsLocalization.AtPrime.isDiscreteValuationRing_of_dedekind_domain` shows that `IsDedekindDomain` implies the localization at each nonzero prime ideal is a DVR. -- `IsDedekindDomain.isDedekindDomainDvr` is one direction of the equivalence of definitions - of a Dedekind domain +- `isDedekindDomain_iff_isDiscreteValuationRing_atPrime` proves the equivalence of + the two notions of Dedekind domain ## Implementation notes @@ -44,21 +39,11 @@ to add a `(h : ¬ IsField A)` assumption whenever this is explicitly needed. dedekind domain, dedekind ring -/ -public section - - -variable (A : Type*) [CommRing A] [IsDomain A] +variable (A : Type*) [CommRing A] open scoped nonZeroDivisors Polynomial -/-- A Dedekind domain is an integral domain that is Noetherian, and the -localization at every nonzero prime is a discrete valuation ring. - -This is equivalent to `IsDedekindDomain`. --/ -class IsDedekindDomainDvr : Prop extends IsNoetherian A A where - is_dvr_at_nonzero_prime : ∀ P ≠ (⊥ : Ideal A), ∀ _ : P.IsPrime, - IsDiscreteValuationRing (Localization.AtPrime P) +public section /-- Localizing a domain of Krull dimension `≤ 1` gives another ring of Krull dimension `≤ 1`. @@ -75,8 +60,6 @@ theorem Ring.DimensionLEOne.localization {R : Type*} (Rₘ : Type*) [CommRing R] refine h.not_lt_lt ⊥ (p.under R) (P.under R) ⟨?_, hpP'⟩ exact IsLocalization.bot_lt_under_prime _ _ hM _ hp0⟩ -set_option linter.overlappingInstances false - /-- The localization of a Dedekind domain is a Dedekind domain. -/ theorem IsLocalization.isDedekindDomain [IsDedekindDomain A] {M : Submonoid A} (hM : M ≤ A⁰) (Aₘ : Type*) [CommRing Aₘ] [IsDomain Aₘ] [Algebra A Aₘ] [IsLocalization M Aₘ] : @@ -110,7 +93,8 @@ instance Localization.AtPrime.isDedekindDomain [IsDedekindDomain A] (P : Ideal A IsDedekindDomain (Localization.AtPrime P) := IsLocalization.AtPrime.isDedekindDomain A P _ -theorem IsLocalization.AtPrime.not_isField {P : Ideal A} (hP : P ≠ ⊥) [pP : P.IsPrime] (Aₘ : Type*) +theorem IsLocalization.AtPrime.not_isField [IsDomain A] + {P : Ideal A} (hP : P ≠ ⊥) [pP : P.IsPrime] (Aₘ : Type*) [CommRing Aₘ] [Algebra A Aₘ] [IsLocalization.AtPrime Aₘ P] : ¬ IsField Aₘ := by intro h let := h.toField @@ -136,39 +120,40 @@ theorem IsLocalization.AtPrime.isDiscreteValuationRing_of_dedekind_domain [IsDed ((IsDiscreteValuationRing.TFAE Aₘ hnf).out 0 2).mpr (IsLocalization.AtPrime.isDedekindDomain A P _) -/-- Dedekind domains, in the sense of Noetherian integrally closed domains of Krull dimension ≤ 1, -are also Dedekind domains in the sense of Noetherian domains where the localization at every -nonzero prime ideal is a DVR. -/ -instance IsDedekindDomain.isDedekindDomainDvr [IsDedekindDomain A] : IsDedekindDomainDvr A where - is_dvr_at_nonzero_prime := fun _ hP _ => - IsLocalization.AtPrime.isDiscreteValuationRing_of_dedekind_domain A hP _ - -instance IsDedekindDomainDvr.ring_dimensionLEOne [h : IsDedekindDomainDvr A] : - Ring.DimensionLEOne A where - maximalOfPrime := by - intro p hp hpp - rcases p.exists_le_maximal (Ideal.IsPrime.ne_top hpp) with ⟨q, hq, hpq⟩ - let f := (IsLocalization.orderIsoOfPrime q.primeCompl (Localization.AtPrime q)).symm - let P := f ⟨p, hpp, hpq.disjoint_compl_left⟩ - let Q := f ⟨q, hq.isPrime, Set.disjoint_left.mpr fun _ a => a⟩ - have hinj : Function.Injective (algebraMap A (Localization.AtPrime q)) := - IsLocalization.injective (Localization.AtPrime q) q.primeCompl_le_nonZeroDivisors - have hp1 : P.1 ≠ ⊥ := fun x => hp ((p.map_eq_bot_iff_of_injective hinj).mp x) - have hq1 : Q.1 ≠ ⊥ := - fun x => (ne_bot_of_le_ne_bot hp hpq) ((q.map_eq_bot_iff_of_injective hinj).mp x) - rcases (IsDiscreteValuationRing.iff_pid_with_one_nonzero_prime (Localization.AtPrime q)).mp - (h.is_dvr_at_nonzero_prime q (ne_bot_of_le_ne_bot hp hpq) hq.isPrime) with ⟨_, huq⟩ - rw [show p = q from Subtype.val_inj.mpr <| f.injective <| - Subtype.val_inj.mp (huq.unique ⟨hp1, P.2⟩ ⟨hq1, Q.2⟩)] - exact hq - -instance IsDedekindDomainDvr.isIntegrallyClosed [h : IsDedekindDomainDvr A] : - IsIntegrallyClosed A := - IsIntegrallyClosed.of_localization_maximal <| fun p hp0 hpm ↦ - let ⟨_, _⟩ := (IsDiscreteValuationRing.iff_pid_with_one_nonzero_prime - (Localization.AtPrime p)).mp (h.is_dvr_at_nonzero_prime p hp0 hpm.isPrime) - inferInstance - -/-- If an integral domain is Noetherian, and the localization at every nonzero prime is -a discrete valuation ring, then it is a Dedekind domain. -/ -instance IsDedekindDomainDvr.isDedekindDomain [IsDedekindDomainDvr A] : IsDedekindDomain A where +end + +variable {A} + +/-- An integral domain is a Dedekind domain iff it is Noetherian and +the localization at every nonzero prime is a discrete valuation ring. -/ +public theorem isDedekindDomain_iff_isDiscreteValuationRing_atPrime [IsDomain A] : + IsDedekindDomain A ↔ IsNoetherian A A ∧ + ∀ P ≠ (⊥ : Ideal A), ∀ _ : P.IsPrime, IsDiscreteValuationRing (Localization.AtPrime P) := by + constructor + · intro + exact ⟨inferInstance, fun P hP _ => + IsLocalization.AtPrime.isDiscreteValuationRing_of_dedekind_domain A hP _⟩ + · intro ⟨_i1, h⟩ + have _i2 : Ring.DimensionLEOne A := by + constructor + intro p hp hpp + rcases p.exists_le_maximal (Ideal.IsPrime.ne_top hpp) with ⟨q, hq, hpq⟩ + let f := (IsLocalization.orderIsoOfPrime q.primeCompl (Localization.AtPrime q)).symm + let P := f ⟨p, hpp, hpq.disjoint_compl_left⟩ + let Q := f ⟨q, hq.isPrime, Set.disjoint_left.mpr fun _ a => a⟩ + have hinj : Function.Injective (algebraMap A (Localization.AtPrime q)) := + IsLocalization.injective (Localization.AtPrime q) q.primeCompl_le_nonZeroDivisors + have hp1 : P.1 ≠ ⊥ := fun x => hp ((p.map_eq_bot_iff_of_injective hinj).mp x) + have hq1 : Q.1 ≠ ⊥ := + fun x => (ne_bot_of_le_ne_bot hp hpq) ((q.map_eq_bot_iff_of_injective hinj).mp x) + rcases (IsDiscreteValuationRing.iff_pid_with_one_nonzero_prime (Localization.AtPrime q)).mp + (h q (ne_bot_of_le_ne_bot hp hpq) hq.isPrime) with ⟨_, huq⟩ + rw [show p = q from Subtype.val_inj.mpr <| f.injective <| + Subtype.val_inj.mp (huq.unique ⟨hp1, P.2⟩ ⟨hq1, Q.2⟩)] + exact hq + have _i3 : IsIntegrallyClosed A := + IsIntegrallyClosed.of_localization_maximal <| fun p hp0 hpm ↦ + let ⟨_, _⟩ := (IsDiscreteValuationRing.iff_pid_with_one_nonzero_prime + (Localization.AtPrime p)).mp (h p hp0 hpm.isPrime) + inferInstance + exact {} diff --git a/Mathlib/RingTheory/Trace/Quotient.lean b/Mathlib/RingTheory/Trace/Quotient.lean index c81fa8f70d60b1..de76e73dc4a406 100644 --- a/Mathlib/RingTheory/Trace/Quotient.lean +++ b/Mathlib/RingTheory/Trace/Quotient.lean @@ -92,36 +92,17 @@ lemma Algebra.trace_quotient_eq_of_isDedekindDomain (x) [IsDedekindDomain R] [Is Ideal.Quotient.mk p (Algebra.intTrace R S x) := by let Rₚ := Localization.AtPrime p let Sₚ := Localization (Algebra.algebraMapSubmonoid S p.primeCompl) - let : Algebra Rₚ Sₚ := localizationAlgebra p.primeCompl S - have : IsScalarTower R Rₚ Sₚ := IsScalarTower.of_algebraMap_eq' - (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, ← IsScalarTower.algebraMap_eq]) - have : IsLocalization (Submonoid.map (algebraMap R S) (Ideal.primeCompl p)) Sₚ := - inferInstanceAs (IsLocalization (Algebra.algebraMapSubmonoid S p.primeCompl) Sₚ) have e : Algebra.algebraMapSubmonoid S p.primeCompl ≤ S⁰ := Submonoid.map_le_of_le_comap _ <| p.primeCompl_le_nonZeroDivisors.trans (nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ (FaithfulSMul.algebraMap_injective _ _)) - have : IsDomain Sₚ := IsLocalization.isDomain_of_le_nonZeroDivisors _ e - have : IsTorsionFree Rₚ Sₚ := by - rw [isTorsionFree_iff_algebraMap_injective, RingHom.injective_iff_ker_eq_bot, - RingHom.ker_eq_bot_iff_eq_zero] - simp - have : Module.Finite Rₚ Sₚ := .of_isLocalization R S p.primeCompl have : IsIntegrallyClosed Sₚ := isIntegrallyClosed_of_isLocalization _ _ e - have : IsPrincipalIdealRing Rₚ := by - by_cases hp : p = ⊥ - · infer_instance - · have := (IsDedekindDomain.isDedekindDomainDvr R).2 p hp inferInstance - infer_instance - have : Module.Free Rₚ Sₚ := Module.free_of_finite_type_torsion_free' apply (equivQuotMaximalIdeal p Rₚ).injective rw [trace_quotient_eq_trace_localization_quotient S p Rₚ Sₚ, IsScalarTower.algebraMap_eq S Sₚ, RingHom.comp_apply, Ideal.Quotient.algebraMap_eq, Algebra.trace_quotient_mk, RingEquiv.apply_symm_apply, ← Algebra.intTrace_eq_trace, ← Algebra.intTrace_eq_of_isLocalization R S p.primeCompl (Aₘ := Rₚ) (Bₘ := Sₚ) x, ← Ideal.Quotient.algebraMap_eq, ← IsScalarTower.algebraMap_apply] - simp only [equivQuotMaximalIdeal, RingHom.quotientKerEquivOfSurjective, RingEquiv.coe_trans, - Function.comp_apply, Ideal.quotEquivOfEq_mk, RingHom.quotientKerEquivOfRightInverse.apply, - RingHom.kerLift_mk] + simp end IsDedekindDomain diff --git a/Mathlib/RingTheory/Unramified/Dedekind.lean b/Mathlib/RingTheory/Unramified/Dedekind.lean index 61fc2be78f10a1..ec28b4258212f7 100644 --- a/Mathlib/RingTheory/Unramified/Dedekind.lean +++ b/Mathlib/RingTheory/Unramified/Dedekind.lean @@ -21,9 +21,9 @@ variable (A B : Type*) [CommRing A] [CommRing B] [Algebra A B] [Module.Finite A [IsDedekindDomain A] [IsDomain B] [Algebra.FormallyUnramified A B] include A in -theorem isDedekindDomainDvr.of_formallyUnramified : IsDedekindDomainDvr B where - __ := IsNoetherianRing.of_finite A B - is_dvr_at_nonzero_prime := by +theorem IsDedekindDomain.of_formallyUnramified : IsDedekindDomain B := + have noetherian := IsNoetherianRing.of_finite A B + isDedekindDomain_iff_isDiscreteValuationRing_atPrime.2 ⟨noetherian, by intro q hq hqp let q' := IsLocalRing.maximalIdeal (Localization.AtPrime q) suffices q'.IsPrincipal from ((IsDiscreteValuationRing.TFAE (Localization.AtPrime q) @@ -44,10 +44,10 @@ theorem isDedekindDomainDvr.of_formallyUnramified : IsDedekindDomainDvr B where Localization.AtPrime.map_eq_maximalIdeal] rw [Ideal.minimalPrimes_eq_comap] exact ⟨q.map (Ideal.Quotient.mk (p.map (algebraMap A B))), - IsArtinianRing.mem_minimalPrimes bot_le, Ideal.comap_map_mk Ideal.map_comap_le⟩ + IsArtinianRing.mem_minimalPrimes bot_le, Ideal.comap_map_mk Ideal.map_comap_le⟩⟩ -include A in -/-- A domain finite and unramified over a Dedekind domain is a Dedekind domain. -/ -theorem isDedekindDomain.of_formallyUnramified : IsDedekindDomain B := - have := isDedekindDomainDvr.of_formallyUnramified A B - inferInstance +@[deprecated (since := "2026-08-01")] +alias isDedekindDomainDvr.of_formallyUnramified := IsDedekindDomain.of_formallyUnramified + +@[deprecated (since := "2026-08-01")] +alias isDedekindDomain.of_formallyUnramified := IsDedekindDomain.of_formallyUnramified From 5b210d51481ca525052f7baec785ec4f86dbf11f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:24:55 +0000 Subject: [PATCH 1234/1300] chore(deps): bump the actions-version-updates group across 1 directory with 11 updates (#42329) Bumps the actions-version-updates group with 11 updates in the /.github/workflows directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `6.0.3` | `7.0.1` | | [actions/setup-python](https://github.com/actions/setup-python) | `6.3.0` | `7.0.0` | | [reviewdog/action-actionlint](https://github.com/reviewdog/action-actionlint) | `1.72.0` | `1.73.0` | | [GrantBirki/comment](https://github.com/grantbirki/comment) | `3.0.0` | `3.0.3` | | [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) | `3.0.4` | `3.0.5` | | [zulip/github-actions-zulip/send-message](https://github.com/zulip/github-actions-zulip) | `2.0.1` | `2.0.2` | | [docker/login-action](https://github.com/docker/login-action) | `4.2.0` | `4.6.0` | | [docker/metadata-action](https://github.com/docker/metadata-action) | `6.1.0` | `6.2.0` | | [docker/build-push-action](https://github.com/docker/build-push-action) | `7.2.0` | `7.3.0` | | [corentinmusard/otel-cicd-action](https://github.com/corentinmusard/otel-cicd-action) | `4.0.1` | `4.1.0` | | [softprops/action-gh-release](https://github.com/softprops/action-gh-release) | `3.0.1` | `3.0.2` | --- .github/workflows/PR_summary.yml | 6 +++--- .github/workflows/actionlint.yml | 6 +++--- .github/workflows/add_label_from_diff.yaml | 4 ++-- .github/workflows/build_template.yml | 14 +++++++------- .github/workflows/cache_test.yml | 2 +- .github/workflows/check_pr_titles.yaml | 6 +++--- .github/workflows/commit_verification.yml | 4 ++-- .github/workflows/daily-master-tag.yml | 2 +- .github/workflows/daily.yml | 18 +++++++++--------- .github/workflows/decls-diff.yml | 4 ++-- .github/workflows/docker_build.yml | 8 ++++---- .github/workflows/export_crossrefs.yml | 4 ++-- .github/workflows/export_telemetry.yaml | 2 +- .github/workflows/label_new_contributor.yml | 2 +- .github/workflows/lake_cache_shadow.yml | 8 ++++---- .github/workflows/latest_import.yml | 4 ++-- .github/workflows/long_file_report.yml | 4 ++-- .github/workflows/maintainer_bors_wf_run.yml | 4 ++-- .github/workflows/maintainer_merge_wf_run.yml | 4 ++-- .github/workflows/nightly_bump_and_merge.yml | 4 ++-- .github/workflows/nightly_detect_failure.yml | 8 ++++---- .github/workflows/nightly_merge_master.yml | 2 +- .github/workflows/nolints.yml | 2 +- .github/workflows/olean_report.yaml | 8 ++++---- .github/workflows/pr_check_downstream.yml | 2 +- .github/workflows/pre-commit.yml | 4 ++-- .github/workflows/publish_tools.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/release_cache.yml | 2 +- .github/workflows/remove_deprecated_decls.yml | 2 +- .github/workflows/rm_set_option.yml | 2 +- .github/workflows/shake.yaml | 2 +- .github/workflows/technical_debt_metrics.yml | 4 ++-- .github/workflows/update_dependencies.yml | 2 +- .../workflows/update_dependencies_zulip.yml | 12 ++++++------ .../workflows/validate_mathlib_ci_paths.yml | 4 ++-- .github/workflows/weekly-lints.yml | 4 ++-- .github/workflows/zulip_emoji_ci_status.yaml | 4 ++-- .github/workflows/zulip_emoji_closed_pr.yaml | 4 ++-- .github/workflows/zulip_emoji_labelling.yaml | 4 ++-- .../workflows/zulip_emoji_merge_delegate.yaml | 6 +++--- .github/workflows/zulip_emoji_reconcile.yml | 2 +- 42 files changed, 97 insertions(+), 97 deletions(-) diff --git a/.github/workflows/PR_summary.yml b/.github/workflows/PR_summary.yml index b0f7781f525ae7..28650c4b79bfe2 100644 --- a/.github/workflows/PR_summary.yml +++ b/.github/workflows/PR_summary.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -29,7 +29,7 @@ jobs: allow-unsafe-pr-checkout: true - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -67,7 +67,7 @@ jobs: fi - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: 3.12 diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml index 0320272d125fcc..9d6dc8bb58b228 100644 --- a/.github/workflows/actionlint.yml +++ b/.github/workflows/actionlint.yml @@ -9,10 +9,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: suggester / actionlint - uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1.72.0 + uses: reviewdog/action-actionlint@50842263c20a7c46bd0065b9e624d3c569db061e # v1.73.0 with: tool_name: actionlint fail_level: any @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Using our fork's PR branch until upstream merges the improved error reporting: # https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/pull/288 diff --git a/.github/workflows/add_label_from_diff.yaml b/.github/workflows/add_label_from_diff.yaml index 3e79bd0b360971..54bca363e5fd9a 100644 --- a/.github/workflows/add_label_from_diff.yaml +++ b/.github/workflows/add_label_from_diff.yaml @@ -18,7 +18,7 @@ jobs: if: github.repository == 'leanprover-community/mathlib4' steps: - name: Checkout master branch to build autolabel from - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master path: tools @@ -34,7 +34,7 @@ jobs: run: | lake build autolabel - name: Checkout branch to label - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} fetch-depth: 0 diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 51a6dde611dac2..5ca82877f1e83b 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -80,7 +80,7 @@ jobs: # We just populate the env vars for this step to make them viewable in the logs - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -395,7 +395,7 @@ jobs: shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} steps: - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -605,7 +605,7 @@ jobs: # `build_template` via `pull_request_target`, never this one — so # `pr_branch_ref` is always a trusted ref here. Fork PRs keep `master`. - name: Checkout tools branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.tools_branch_ref != '' && inputs.tools_branch_ref || (github.event.pull_request.head.repo.fork && 'master' || inputs.pr_branch_ref) }} fetch-depth: 1 @@ -675,7 +675,7 @@ jobs: contents: read steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.pr_branch_ref }} # Untrusted (potentially fork) checkout: don't persist the GITHUB_TOKEN into its .git/config. @@ -692,7 +692,7 @@ jobs: # miss. `github.workflow_sha` is the base ref the workflow runs from, # master for fork PRs, whose `cache` binary wrote the cache. - name: Checkout local actions and Cache baseline - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -802,7 +802,7 @@ jobs: lake exe graph - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -1015,7 +1015,7 @@ jobs: contains(steps.actorTeams.outputs.teams, 'bot-users') ) name: If `auto-merge-after-CI` is present, add a `bors merge` comment. - uses: GrantBirki/comment@3439715f0cf3b8fc29bf47be0e3226679c06c41a # v3.0.0 + uses: GrantBirki/comment@937820f3623fd0e300294bcc64ac7577fc0ad4cc # v3.0.3 with: # This token is masked by the token minting action and will not be logged accidentally. token: ${{ steps.auto-merge-app-token.outputs.token }} diff --git a/.github/workflows/cache_test.yml b/.github/workflows/cache_test.yml index 69a965e6678d62..f64b93714b3953 100644 --- a/.github/workflows/cache_test.yml +++ b/.github/workflows/cache_test.yml @@ -41,7 +41,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Install elan and the toolchain cross-platform. Build/test/lint, the # Mathlib cache, and the GitHub cache are all disabled, so this is a diff --git a/.github/workflows/check_pr_titles.yaml b/.github/workflows/check_pr_titles.yaml index 7d995d59b2c69c..c85643bf42f044 100644 --- a/.github/workflows/check_pr_titles.yaml +++ b/.github/workflows/check_pr_titles.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master - name: Configure Lean @@ -70,7 +70,7 @@ jobs: fi - name: Add comment to fix PR title - uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 if: failure() && steps.pr-title-check.outputs.errors with: header: 'PR Title Check' @@ -120,7 +120,7 @@ jobs: - name: Add comment that PR title is fixed if: steps.pr-title-check.outcome == 'success' - uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 with: header: 'PR Title Check' # should do nothing if a 'PR Title Check' comment does not exist diff --git a/.github/workflows/commit_verification.yml b/.github/workflows/commit_verification.yml index d62c03386f5ba2..5c9636db0988cc 100644 --- a/.github/workflows/commit_verification.yml +++ b/.github/workflows/commit_verification.yml @@ -33,14 +33,14 @@ jobs: # This is a quick check to avoid unnecessary runs steps: - name: Checkout PR head - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Checkout the actual PR head, not the merge commit GitHub creates ref: ${{ github.event.pull_request.head.sha }} # Fetch full history to access all PR commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/daily-master-tag.yml b/.github/workflows/daily-master-tag.yml index 96aeefcb3382ae..0eafd638e4c8e3 100644 --- a/.github/workflows/daily-master-tag.yml +++ b/.github/workflows/daily-master-tag.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'leanprover-community/mathlib4' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 3865c77fd5e2b4..591e4704b061d0 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -31,7 +31,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -52,7 +52,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -82,7 +82,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Get job status and URLs id: get-status @@ -156,7 +156,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -177,7 +177,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -205,7 +205,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Get job status and URLs id: get-status @@ -279,7 +279,7 @@ jobs: steps: # Checkout repository, so that we can fetch tags to decide which branch we want. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Fetch latest tags (if nightly) if: matrix.branch_type == 'nightly' @@ -300,7 +300,7 @@ jobs: # Checkout the branch or tag we want to test. - name: Checkout branch or tag - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ matrix.branch_type == 'nightly' && 'leanprover-community/mathlib4-nightly-testing' || github.repository }} ref: ${{ env.BRANCH_REF }} @@ -370,7 +370,7 @@ jobs: branch_type: [master, nightly] steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Get job status and URLs id: get-status diff --git a/.github/workflows/decls-diff.yml b/.github/workflows/decls-diff.yml index 3b12118d7e805a..730b6b74bedfd9 100644 --- a/.github/workflows/decls-diff.yml +++ b/.github/workflows/decls-diff.yml @@ -58,7 +58,7 @@ jobs: } | tee -a "$GITHUB_OUTPUT" - name: Checkout new commit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ steps.meta.outputs.new-sha }} fetch-depth: 0 @@ -139,7 +139,7 @@ jobs: # Tooling is checked out unconditionally: the patcher (from CI_SCRIPTS_DIR) # is needed on the cache-miss path too, to post the warning notice. - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 3e0c28a07aaa7c..5189f4807d8c19 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -27,9 +27,9 @@ jobs: steps: # documentation at # https://docs.github.com/en/actions/use-cases-and-examples/publishing-packages/publishing-docker-images - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Log in to the container registry - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: registry: ${{ env.REGISTRY }} # might need set as `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` @@ -38,7 +38,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for docker id: meta - uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 + uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: images: ${{ env.REGISTRY }}/${{ env.REPO_NAME }}/${{ matrix.image }} tags: | @@ -51,7 +51,7 @@ jobs: org.opencontainers.image.licenses=Apache-2.0 - name: Build and push docker image id: push - uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 with: context: . file: .docker/${{ matrix.image }}/Dockerfile diff --git a/.github/workflows/export_crossrefs.yml b/.github/workflows/export_crossrefs.yml index fa12a8e457553d..82cbc30b38e2b3 100644 --- a/.github/workflows/export_crossrefs.yml +++ b/.github/workflows/export_crossrefs.yml @@ -47,7 +47,7 @@ jobs: || github.event.workflow_run.conclusion == 'success') steps: - name: Checkout the built commit - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # The exact commit CI validated; for manual runs, the dispatched ref. @@ -149,7 +149,7 @@ jobs: - name: Post failure message on Zulip if: failure() - uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa # v2.0.1 + uses: zulip/github-actions-zulip/send-message@f675f2b4eb2a95fae974215476dcb7ad8dfeff6b # v2.0.2 with: api-key: ${{ secrets.ZULIP_API_KEY }} email: 'github-mathlib4-bot@leanprover.zulipchat.com' diff --git a/.github/workflows/export_telemetry.yaml b/.github/workflows/export_telemetry.yaml index cefbac3eed80f4..3d799d783ca4bd 100644 --- a/.github/workflows/export_telemetry.yaml +++ b/.github/workflows/export_telemetry.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Export workflow telemetry - uses: corentinmusard/otel-cicd-action@f2d88ecf54d9dd3e01ea95e25f93603212ee93d3 # v4.0.1 + uses: corentinmusard/otel-cicd-action@6022e68732c1cab4d2c8218b810f69006ee5cc34 # v4.1.0 with: otlpEndpoint: ${{ vars.OTLP_ENDPOINT }} otlpHeaders: ${{ secrets.OTLP_HEADERS }} diff --git a/.github/workflows/label_new_contributor.yml b/.github/workflows/label_new_contributor.yml index 8518886509841e..9e64636bb119b0 100644 --- a/.github/workflows/label_new_contributor.yml +++ b/.github/workflows/label_new_contributor.yml @@ -99,7 +99,7 @@ jobs: - name: Post welcome comment for new contributor if: steps.contributor-check.outputs.should_welcome == 'true' - uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 with: header: 'New Contributor Welcome' message: | diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 489b364a216ef3..02cb18cc33ef0e 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -131,13 +131,13 @@ jobs: uses: dcarbone/install-jq-action@4fcb5062d7ce9bc4382d1a352d19ba3ba2c317c1 # v4.0.1 - name: Checkout tools branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master path: tools-branch - name: Checkout mathlib (pr-branch) - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.mathlib_ref || 'master' }} fetch-depth: 2 @@ -359,7 +359,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT }} steps: - name: Checkout mathlib (workspace for put-staged) - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch @@ -503,7 +503,7 @@ jobs: LAKE_CACHE_REVISION_ENDPOINT: ${{ vars.LAKE_CACHE_REVISION_ENDPOINT_PUBLIC }} steps: - name: Checkout mathlib - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.build_and_stage.outputs.sha }} path: pr-branch diff --git a/.github/workflows/latest_import.yml b/.github/workflows/latest_import.yml index 8aacc26bd9584d..6a788efce8a11b 100644 --- a/.github/workflows/latest_import.yml +++ b/.github/workflows/latest_import.yml @@ -26,10 +26,10 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/long_file_report.yml b/.github/workflows/long_file_report.yml index 03e0a37bf3400c..e8aff1f404bfc1 100644 --- a/.github/workflows/long_file_report.yml +++ b/.github/workflows/long_file_report.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/maintainer_bors_wf_run.yml b/.github/workflows/maintainer_bors_wf_run.yml index b257787bb9fda2..a57de570b64830 100644 --- a/.github/workflows/maintainer_bors_wf_run.yml +++ b/.github/workflows/maintainer_bors_wf_run.yml @@ -130,7 +130,7 @@ jobs: if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -146,7 +146,7 @@ jobs: if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' diff --git a/.github/workflows/maintainer_merge_wf_run.yml b/.github/workflows/maintainer_merge_wf_run.yml index 14a3673cffc39c..e85cc8d696981e 100644 --- a/.github/workflows/maintainer_merge_wf_run.yml +++ b/.github/workflows/maintainer_merge_wf_run.yml @@ -163,7 +163,7 @@ jobs: - name: Checkout local actions if: ${{ steps.authorized.outputs.authorized == 'true' }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -246,7 +246,7 @@ jobs: - name: Add comment to PR if: ${{ steps.authorized.outputs.authorized == 'true' }} continue-on-error: true - uses: GrantBirki/comment@3439715f0cf3b8fc29bf47be0e3226679c06c41a # v3.0.0 + uses: GrantBirki/comment@937820f3623fd0e300294bcc64ac7577fc0ad4cc # v3.0.3 with: # if a comment triggers the action, then `issue.number` is set # if a review or review comment triggers the action, then `pull_request.number` is set diff --git a/.github/workflows/nightly_bump_and_merge.yml b/.github/workflows/nightly_bump_and_merge.yml index 1a344d7a134d50..537d8be1293378 100644 --- a/.github/workflows/nightly_bump_and_merge.yml +++ b/.github/workflows/nightly_bump_and_merge.yml @@ -39,14 +39,14 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing branch - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: nightly-testing fetch-depth: 0 # Fetch all branches and history token: ${{ steps.app-token.outputs.token }} - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_detect_failure.yml b/.github/workflows/nightly_detect_failure.yml index f887e968f7413c..21f9a788cb5ce1 100644 --- a/.github/workflows/nightly_detect_failure.yml +++ b/.github/workflows/nightly_detect_failure.yml @@ -122,7 +122,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Pin to the SHA whose CI just succeeded, not the current tip of `nightly-testing`, # which may have advanced while CI was running. Without this, the tag and @@ -216,7 +216,7 @@ jobs: # The create-github-app-token README states that this token is masked and will not be logged accidentally. - name: Checkout Lean repository if: steps.tag.outputs.is_nightly == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: leanprover/lean4 token: ${{ steps.lean-pr-testing-token.outputs.token }} @@ -418,7 +418,7 @@ jobs: azure-client-id: ${{ vars.GH_APP_AZURE_CLIENT_ID_NIGHTLY_TESTING }} azure-tenant-id: ${{ secrets.LPC_AZ_TENANT_ID }} - name: Checkout Mathlib4 repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' with: ref: nightly-testing # checkout nightly-testing branch (shouldn't matter which) @@ -427,7 +427,7 @@ jobs: - name: Checkout local actions if: steps.tag.outputs.is_nightly == 'true' && steps.check_branch.outputs.result == 'false' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/nightly_merge_master.yml b/.github/workflows/nightly_merge_master.yml index 39725897ccfa3e..8fe65b948a965f 100644 --- a/.github/workflows/nightly_merge_master.yml +++ b/.github/workflows/nightly_merge_master.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout nightly-testing from fork - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: leanprover-community/mathlib4-nightly-testing ref: nightly-testing diff --git a/.github/workflows/nolints.yml b/.github/workflows/nolints.yml index e1addcf674c915..75db6f41e10f7f 100644 --- a/.github/workflows/nolints.yml +++ b/.github/workflows/nolints.yml @@ -14,7 +14,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/olean_report.yaml b/.github/workflows/olean_report.yaml index aaa1ecb18c9d66..8427497eabe981 100644 --- a/.github/workflows/olean_report.yaml +++ b/.github/workflows/olean_report.yaml @@ -48,7 +48,7 @@ jobs: - name: Checkout local actions if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -82,7 +82,7 @@ jobs: # We fetch full depth so that we can compute the merge base. - name: Checkout PR head if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ github.repository }} ref: refs/pull/${{ github.event.issue.number }}/head @@ -95,7 +95,7 @@ jobs: # here so that a single binary can fetch oleans for both checkouts. - name: Checkout tools branch (master) if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ github.repository }} ref: master @@ -117,7 +117,7 @@ jobs: - name: Checkout merge base if: steps.check_trigger.outputs.triggered == 'true' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ github.repository }} ref: ${{ steps.merge_base.outputs.sha }} diff --git a/.github/workflows/pr_check_downstream.yml b/.github/workflows/pr_check_downstream.yml index b099ba488b7c4b..7a67bf7203f927 100644 --- a/.github/workflows/pr_check_downstream.yml +++ b/.github/workflows/pr_check_downstream.yml @@ -170,7 +170,7 @@ jobs: # via a sparse checkout so we can run it; we never need the # rest of the mathlib4 working tree on this runner. - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 6e5aaceeb2a4ce..70e0fa115a4992 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -20,8 +20,8 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: 3.x - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 diff --git a/.github/workflows/publish_tools.yml b/.github/workflows/publish_tools.yml index 999cd7a8c676e9..25037f561bf496 100644 --- a/.github/workflows/publish_tools.yml +++ b/.github/workflows/publish_tools.yml @@ -40,7 +40,7 @@ jobs: # Build under `tools-branch/`, the same directory `build_template.yml` unpacks # the tools into, in case the build bakes its own location into the binary. - name: Checkout master - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master path: tools-branch diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b35bdf8ac3a34a..94b0ad43a1fa07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: if: github.repository == 'leanprover-community/mathlib4' steps: - name: Create GitHub Release - uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1 + uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 with: prerelease: ${{ contains(github.ref, 'rc') }} make_latest: ${{ !contains(github.ref, 'rc') }} diff --git a/.github/workflows/release_cache.yml b/.github/workflows/release_cache.yml index 242874105ab702..4de6346b0a6ff7 100644 --- a/.github/workflows/release_cache.yml +++ b/.github/workflows/release_cache.yml @@ -57,7 +57,7 @@ jobs: outputs: off_master: ${{ steps.check.outputs.off_master }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # `merge-base` needs history, so fetch all of it. fetch-depth: 0 diff --git a/.github/workflows/remove_deprecated_decls.yml b/.github/workflows/remove_deprecated_decls.yml index fb2a6fc98f37d8..152441dba2f298 100644 --- a/.github/workflows/remove_deprecated_decls.yml +++ b/.github/workflows/remove_deprecated_decls.yml @@ -112,7 +112,7 @@ jobs: echo "from_date=$from_date" >> "$GITHUB_OUTPUT" echo "to_date=$to_date" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/rm_set_option.yml b/.github/workflows/rm_set_option.yml index 8b21d6604ec0d3..39583ec7345e7e 100644 --- a/.github/workflows/rm_set_option.yml +++ b/.github/workflows/rm_set_option.yml @@ -31,7 +31,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/shake.yaml b/.github/workflows/shake.yaml index 47c77eb10be4d4..62e03d05b6e70a 100644 --- a/.github/workflows/shake.yaml +++ b/.github/workflows/shake.yaml @@ -26,7 +26,7 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Configure Lean uses: leanprover/lean-action@38fbc41a8c28c4cbaec22d7f7de508ec2e7c0dd9 # v1.5.0 diff --git a/.github/workflows/technical_debt_metrics.yml b/.github/workflows/technical_debt_metrics.yml index 6d102888c511c9..704a854e623ffc 100644 --- a/.github/workflows/technical_debt_metrics.yml +++ b/.github/workflows/technical_debt_metrics.yml @@ -12,12 +12,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # checkout all history so that we can compare across commits fetch-depth: 0 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/update_dependencies.yml b/.github/workflows/update_dependencies.yml index 5974d14528aab1..9dc25234da0c55 100644 --- a/.github/workflows/update_dependencies.yml +++ b/.github/workflows/update_dependencies.yml @@ -27,7 +27,7 @@ jobs: # This token is masked by the token minting action and will not be logged accidentally. - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/update_dependencies_zulip.yml b/.github/workflows/update_dependencies_zulip.yml index f0520210cfa84d..99d079d6c1624c 100644 --- a/.github/workflows/update_dependencies_zulip.yml +++ b/.github/workflows/update_dependencies_zulip.yml @@ -17,13 +17,13 @@ jobs: id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -33,7 +33,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' @@ -108,12 +108,12 @@ jobs: id-token: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 # Need previous commit for diff - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -123,7 +123,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' diff --git a/.github/workflows/validate_mathlib_ci_paths.yml b/.github/workflows/validate_mathlib_ci_paths.yml index 96731cdcd805ca..421ecbbbcc67a8 100644 --- a/.github/workflows/validate_mathlib_ci_paths.yml +++ b/.github/workflows/validate_mathlib_ci_paths.yml @@ -29,10 +29,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/weekly-lints.yml b/.github/workflows/weekly-lints.yml index 515906d8713e11..fcaf163ae4251b 100644 --- a/.github/workflows/weekly-lints.yml +++ b/.github/workflows/weekly-lints.yml @@ -26,12 +26,12 @@ jobs: : # Do nothing on failure, but suppress errors fi - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: master - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 diff --git a/.github/workflows/zulip_emoji_ci_status.yaml b/.github/workflows/zulip_emoji_ci_status.yaml index 8ab30ec4c2ef23..a0a25cc738cdb1 100644 --- a/.github/workflows/zulip_emoji_ci_status.yaml +++ b/.github/workflows/zulip_emoji_ci_status.yaml @@ -74,7 +74,7 @@ jobs: - name: Checkout local actions if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -86,7 +86,7 @@ jobs: - name: Set up Python if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_closed_pr.yaml b/.github/workflows/zulip_emoji_closed_pr.yaml index 2dbf54efff0875..d5b7ce696d0e43 100644 --- a/.github/workflows/zulip_emoji_closed_pr.yaml +++ b/.github/workflows/zulip_emoji_closed_pr.yaml @@ -33,7 +33,7 @@ jobs: - name: Checkout local actions if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || github.event_name == 'reopened' }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -47,7 +47,7 @@ jobs: - name: Set up Python if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || github.event_name == 'reopened' }} - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_labelling.yaml b/.github/workflows/zulip_emoji_labelling.yaml index 5a019050928fdc..9d9ada427ff46f 100644 --- a/.github/workflows/zulip_emoji_labelling.yaml +++ b/.github/workflows/zulip_emoji_labelling.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -27,7 +27,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_merge_delegate.yaml b/.github/workflows/zulip_emoji_merge_delegate.yaml index 9883c1f0263082..0e30202664a80a 100644 --- a/.github/workflows/zulip_emoji_merge_delegate.yaml +++ b/.github/workflows/zulip_emoji_merge_delegate.yaml @@ -15,12 +15,12 @@ jobs: steps: - name: Checkout mathlib4 repository history - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # download the full repository - name: Checkout local actions - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.workflow_sha }} fetch-depth: 1 @@ -30,7 +30,7 @@ jobs: uses: ./workflow-actions/.github/actions/get-mathlib-ci - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' diff --git a/.github/workflows/zulip_emoji_reconcile.yml b/.github/workflows/zulip_emoji_reconcile.yml index ddc3f36959d1d3..c71ba0309eeee4 100644 --- a/.github/workflows/zulip_emoji_reconcile.yml +++ b/.github/workflows/zulip_emoji_reconcile.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out reconcile config - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: sparse-checkout: .github/zulip-emoji-config.json sparse-checkout-cone-mode: false From 5e5cca6719ae2f225b1c323009b1a994ea5d824c Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:39:14 +0000 Subject: [PATCH 1235/1300] chore: update Mathlib dependencies 2026-08-10 (#42609) This PR updates the Mathlib dependencies. --- .github/actions/get-mathlib-ci/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/get-mathlib-ci/action.yml b/.github/actions/get-mathlib-ci/action.yml index 14214c6e6b6feb..adebc3820789e8 100644 --- a/.github/actions/get-mathlib-ci/action.yml +++ b/.github/actions/get-mathlib-ci/action.yml @@ -10,7 +10,7 @@ inputs: # Default pinned commit used by workflows unless they explicitly override. # Update this ref as needed to pick up changes to mathlib-ci scripts # This is also updated automatically by .github/workflows/update_dependencies.yml - default: dae5b1a4c7d1d5fef3247bfe708eb0c7e4dadaa5 + default: 57c68e7faac5aea96e58a94ca4a334a1999f0d31 path: description: Checkout destination path. required: false From d1e20d726ab1203194dc40ce2c635a5dada4e06b Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:54:40 +0000 Subject: [PATCH 1236/1300] fix(CategoryTheory/Limits/VanKampen): backport fix for lean#8883 (#41814) This PR contains the fix that I had to make to get https://github.com/leanprover/lean4/pull/8883 working. When looking into this, I had concluded that the original proof should not have worked in the first place. This was the only such failure that was present in mathlib. I think having this fix will be helpful when work on the unification performance issue is resumed. --- Mathlib/CategoryTheory/Limits/VanKampen.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Limits/VanKampen.lean b/Mathlib/CategoryTheory/Limits/VanKampen.lean index 877f75e8f1c146..a4b8eeff9ea07f 100644 --- a/Mathlib/CategoryTheory/Limits/VanKampen.lean +++ b/Mathlib/CategoryTheory/Limits/VanKampen.lean @@ -671,7 +671,7 @@ theorem isVanKampenColimit_extendCofan {n : ℕ} (f : Fin (n + 1) → C) induction j using Fin.inductionOn with | zero => exact t₂' ⟨WalkingPair.left⟩ | succ j _ => - have t₁' := (@t₁ (Discrete.functor (fun j ↦ F.obj ⟨j.succ⟩)) (Cofan.mk _ _) (Discrete.natTrans + have t₁' := (t₁ (Cofan.mk _ (Sigma.ι fun j : Fin n ↦ F.obj ⟨j.succ⟩)) (Discrete.natTrans fun i ↦ α.app _) (Sigma.desc (fun j ↦ α.app _ ≫ c₁.inj _)) ?_ (.of_discrete _)).mp ⟨coproductIsCoproduct _⟩ ⟨j⟩ rotate_left From f46a87e8e1b7fd68c94b6e16cad91d47bcc0cc93 Mon Sep 17 00:00:00 2001 From: "mathlib-splicebot[bot]" <261196803+mathlib-splicebot[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:07:30 +0000 Subject: [PATCH 1237/1300] =?UTF-8?q?chore(Algebra/Order):=20bound=20on=20?= =?UTF-8?q?`|n=20/=20m|=E2=82=98`=20and=20`|n=20-=20m|`=20(#37232)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR was automatically created from PR #34722 by @GrigorenkoPV via a [review comment](https://github.com/leanprover-community/mathlib4/pull/34722#discussion_r2996870566) by @Vierkantor. Co-authored-by: GrigorenkoPV <82285787+GrigorenkoPV@users.noreply.github.com> Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Algebra/Order/Group/Unbundled/Abs.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean index e45ec70e41eee1..86f4b2ffae45a8 100644 --- a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean +++ b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean @@ -276,6 +276,11 @@ variable [MulRightMono α] @[to_additive] lemma max_div_min_eq_mabs (a b : α) : max a b / min a b = |b / a|ₘ := by rw [mabs_div_comm, max_div_min_eq_mabs'] +@[to_additive] lemma mabs_div_lt_of_lt_lt {N M n m : α} (hn : 1 ≤ n) (hm : 1 ≤ m) (hnN : n < N) + (hmM : m < M) : |n / m|ₘ < N ⊔ M := by + rw [← max_div_min_eq_mabs', div_lt_iff_lt_mul] + exact lt_of_le_of_lt' (le_mul_of_one_le_right' (le_min hn hm)) (max_lt_max hnN hmM) + end LinearOrder namespace LatticeOrderedAddCommGroup From b0f879696f350a2db0660e13525306be48fbd322 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:07:32 +0000 Subject: [PATCH 1238/1300] feat(Data/ENNReal): add `sum_div` (#40855) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Finset.sum_div` does not apply since `ℝ≥0∞` is not a `DivisionSemiring`. Although the proof of `Finset.sum_div` (and of this lemma) only needs `DivInvMonoid` and `NonUnitalNonAssocSemiring`, the best typeclass including these is `DivisionSemiring`. Co-authored-by: NoahW314 --- Mathlib/Analysis/MeanInequalities.lean | 2 +- Mathlib/Data/ENNReal/BigOperators.lean | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/MeanInequalities.lean b/Mathlib/Analysis/MeanInequalities.lean index 0c75954dab6fd2..d6be96e1337180 100644 --- a/Mathlib/Analysis/MeanInequalities.lean +++ b/Mathlib/Analysis/MeanInequalities.lean @@ -111,7 +111,7 @@ public section universe u v -open Finset NNReal ENNReal +open Finset NNReal open scoped BigOperators noncomputable section diff --git a/Mathlib/Data/ENNReal/BigOperators.lean b/Mathlib/Data/ENNReal/BigOperators.lean index f1043d0e20b688..c7b60b47f50fcd 100644 --- a/Mathlib/Data/ENNReal/BigOperators.lean +++ b/Mathlib/Data/ENNReal/BigOperators.lean @@ -138,6 +138,12 @@ theorem exists_le_of_sum_le {s : Finset α} (hs : s.Nonempty) {f g : α → ℝ contrapose! Hle apply ENNReal.sum_lt_sum_of_nonempty hs Hle +/-- `Finset.sum_div` does not apply since `ℝ≥0∞` is not a `DivisionSemiring`. Although + the proof of `Finset.sum_div` only needs `DivInvMonoid` and `NonUnitalNonAssocSemiring`, the best + typeclass including these is `DivisionSemiring`. -/ +lemma sum_div (a : ℝ≥0∞) : (∑ i ∈ s, f i) / a = ∑ i ∈ s, f i / a := by + simp_rw [div_eq_mul_inv, Finset.sum_mul] + end Sum section Inv From bcbf492c34a082ce5a96588cd7a70ea4ebc992f9 Mon Sep 17 00:00:00 2001 From: Fanping Jiang <35282973+jiangf13@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:07:35 +0000 Subject: [PATCH 1239/1300] chore(Algebra/Group/WithOne): remove stale TODO (#40904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TODO claimed that `WithOne.coe_mul` and `WithZero.coe_mul` have inconsistent implicit parameters. Their current signatures are both of the form `{α} [Mul α] (a b : α)`, so the TODO is stale. --- Mathlib/Algebra/Group/WithOne/Defs.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/Algebra/Group/WithOne/Defs.lean b/Mathlib/Algebra/Group/WithOne/Defs.lean index 3c850ff484721e..b5394d8dc214f0 100644 --- a/Mathlib/Algebra/Group/WithOne/Defs.lean +++ b/Mathlib/Algebra/Group/WithOne/Defs.lean @@ -21,10 +21,6 @@ this provides an example of an adjunction is proved in Another result says that adjoining to a group an element `zero` gives a `GroupWithZero`. For more information about these structures (which are not that standard in informal mathematics, see `Mathlib/Algebra/GroupWithZero/Basic.lean`) - -## TODO - -`WithOne.coe_mul` and `WithZero.coe_mul` have inconsistent use of implicit parameters -/ @[expose] public section From cfcc13573e637ca0cab6f40fd0076c11c19278e5 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 10 Aug 2026 13:07:37 +0000 Subject: [PATCH 1240/1300] doc: add theorem 8 (straightedge-and-compass construction) to 100.yaml (#41757) Adding my repo as an external proof to the theorems. --- docs/100.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/100.yaml b/docs/100.yaml index 90e3fc0709d52c..39a1bc7826b25b 100644 --- a/docs/100.yaml +++ b/docs/100.yaml @@ -43,6 +43,9 @@ authors: Chris Hughes (first) and Michael Stoll (second) 8: title : The Impossibility of Trisecting the Angle and Doubling the Cube + authors: Weiyi Wang + links : + result: https://github.com/wwylele/Compass/blob/master/Solution.lean 9: title : The Area of a Circle decl : Theorems100.area_disc From c8f7cbf30772d58331540deca8bf38aea7418aec Mon Sep 17 00:00:00 2001 From: Aditya Menon <63695868+menon-codes@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:07:40 +0000 Subject: [PATCH 1241/1300] refactor: making trans usage explicit with kerLift (#42266) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Slightly simplifies the argument used in `exists_integral_inj_algHom_of_quotient` for clarity. This is also needed to fix a small edge case present in a linter I am making as discussed here: [#mathlib4 > Linter for ellipsis @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Linter.20for.20ellipsis/near/613523943) --- Mathlib/RingTheory/NoetherNormalization.lean | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/NoetherNormalization.lean b/Mathlib/RingTheory/NoetherNormalization.lean index c30969e30f41e9..c2d6983b2ef217 100644 --- a/Mathlib/RingTheory/NoetherNormalization.lean +++ b/Mathlib/RingTheory/NoetherNormalization.lean @@ -258,11 +258,8 @@ theorem exists_integral_inj_algHom_of_quotient (I : Ideal (MvPolynomial (Fin n) set ϕ := kerLiftAlg <| hom2 f I have := Quotient.nontrivial_iff.mpr hi obtain ⟨s, _, g, injg, intg⟩ := hd (ker <| hom2 f I) (ker_ne_top <| hom2 f I) - have comp : (kerLiftAlg (hom2 f I)).comp (Quotient.mkₐ k <| ker <| hom2 f I) = (hom2 f I) := - AlgHom.ext fun a ↦ by - simp only [AlgHom.coe_comp, Quotient.mkₐ_eq_mk, Function.comp_apply, kerLiftAlg_mk] - exact ⟨s, by lia, ϕ.comp g, (ϕ.coe_comp g) ▸ (kerLiftAlg_injective _).comp injg, - intg.trans _ _ <| (comp ▸ hom2_isIntegral f I fne fi).tower_top _ _⟩ + exact ⟨s, by lia, ϕ.comp g, (ϕ.coe_comp g) ▸ (kerLiftAlg_injective _).comp injg, + intg.trans g.toRingHom ϕ.toRingHom (hom2_isIntegral f I fne fi).kerLift⟩ variable (k R : Type*) [Field k] [CommRing R] [Nontrivial R] [a : Algebra k R] [fin : Algebra.FiniteType k R] From 1c6e94193fdde9efb39255989a4214ea8da576a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:07:42 +0000 Subject: [PATCH 1242/1300] chore(CategoryTheory): `implicit_reducible` for compositions of natural transformations (#42528) --- Mathlib/CategoryTheory/NatTrans.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/NatTrans.lean b/Mathlib/CategoryTheory/NatTrans.lean index 59483ebf883559..b919dae13f2647 100644 --- a/Mathlib/CategoryTheory/NatTrans.lean +++ b/Mathlib/CategoryTheory/NatTrans.lean @@ -97,7 +97,7 @@ section variable {F G H : C ⥤ D} /-- `vcomp α β` is the vertical compositions of natural transformations. -/ -@[to_dual self (reorder := F H, α β)] +@[implicit_reducible, to_dual self (reorder := F H, α β)] def vcomp (α : NatTrans F G) (β : NatTrans G H) : NatTrans F H where app X := α.app X ≫ β.app X From f7699dd3e2e2f90ab1a45531bbd84b2bcbc8f76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:07:44 +0000 Subject: [PATCH 1243/1300] chore(CategoryTheory): composition implicit reducible in `Type` (#42529) This is meant to be used in combination with #42528 in order to have better "defeq" for categories of functors to types. --- Mathlib/CategoryTheory/Types/Basic.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Types/Basic.lean b/Mathlib/CategoryTheory/Types/Basic.lean index 9846c88ea99172..5da7cd112b496b 100644 --- a/Mathlib/CategoryTheory/Types/Basic.lean +++ b/Mathlib/CategoryTheory/Types/Basic.lean @@ -69,11 +69,11 @@ lemma Fun.coe_mk {X Y : Type*} (f : X → Y) : (Fun.mk f : X → Y) = f := rfl /-- The identity function as a `Fun`. -/ -@[simps! +dsimpLhs] +@[implicit_reducible, simps!] def Fun.id (X : Type*) : Fun X X := Fun.mk _root_.id /-- Composition of `Fun`s. -/ -@[simps! +dsimpLhs] +@[implicit_reducible, simps!] def Fun.comp {X Y Z : Type*} (f : Fun Y Z) (g : Fun X Y) : Fun X Z := mk (f.toFun ∘ g.toFun) /-- The equivalence between `Fun`s and functions between types. -/ From 06c279834470de3461b4f3618b6f56146be9e998 Mon Sep 17 00:00:00 2001 From: Laurance <60111599+LLaurance@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:11 +0000 Subject: [PATCH 1244/1300] feat(Probability): expectation of a binomial random variable (#40613) Co-authored-by: LLaurance Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib/Probability/Distributions/Binomial.lean | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Mathlib/Probability/Distributions/Binomial.lean b/Mathlib/Probability/Distributions/Binomial.lean index 7c124b3f604628..60685f1760f7cd 100644 --- a/Mathlib/Probability/Distributions/Binomial.lean +++ b/Mathlib/Probability/Distributions/Binomial.lean @@ -188,7 +188,20 @@ variable {X : Ω → ℝ} /-- **Expectation of a binomial random variable**. The expectation of a binomial random variable with parameters `n` and `p` is `pn`. -/ -proof_wanted integral_of_hasLaw_binomial (hX : HasLaw X Bin(ℝ, n, p) P) : P[X] = p.val * n +theorem integral_of_hasLaw_binomial (hX : HasLaw X Bin(ℝ, n, p) P) : P[X] = p.val * n := by + rw [hX.integral_eq, integral_map_cast_binomial, ← n.range_succ_eq_Iic, Finset.sum_range_succ'] + cases n with norm_num | succ n + calc + _ = p * ∑ x ∈ Finset.range (n + 1), (n + 1).choose (x + 1) * (x + 1) * + p.val ^ x * (1 - p) ^ (n - x) := by grind [Finset.mul_sum] + _ = p * ∑ x ∈ Finset.range (n + 1), n.choose x * (n + 1) * p.val ^ x * (1 - p) ^ (n - x) := by + congrm p * ∑ x ∈ Finset.range (n + 1), ?_ * p.val ^ x * (1 - p) ^ (n - x) + norm_cast + rw [← Nat.add_one_mul_choose_eq n x, mul_comm] + _ = p * (n + 1) * ∑ x ∈ Finset.range (n + 1), n.choose x * p.val ^ x * (1 - p) ^ (n - x) := by + rw [mul_assoc, Finset.mul_sum (a := (n : ℝ) + 1)] + group + _ = p * (n + 1) := by grind [add_pow p.val (1 - p) n, one_pow] /-- **Variance of a binomial random variable**. From d19d9a552aada4300fa9cfe0c907ee3664f351c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carles=20Mar=C3=ADn=20Mu=C3=B1oz?= <44897797+karlesmarin@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:14 +0000 Subject: [PATCH 1245/1300] feat(RingTheory/HopfAlgebra): antipode is the unique convolution inverse of the identity (#40812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `HopfAlgebra.eq_antipode_of_convMul_id_eq_one` and `HopfAlgebra.eq_antipode_of_id_convMul_eq_one`: an `R`-linear map that is a one-sided convolution inverse of the identity equals the antipode. Either side suffices. The proof is `left_inv_eq_right_inv` in the convolution monoid `WithConv (A →ₗ[R] A)` together with the two antipode axioms, transported by `toConv_injective`. It closes the "uniqueness of Hopf algebra structure on a bialgebra" TODO in this file, and is the uniqueness companion to the existing `ofConvInverse` (existence). Co-authored-by: Carles Marín Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/RingTheory/HopfAlgebra/Basic.lean | 3 --- Mathlib/RingTheory/HopfAlgebra/Convolution.lean | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/HopfAlgebra/Basic.lean b/Mathlib/RingTheory/HopfAlgebra/Basic.lean index 8383ce9c30b151..ab4dcb8ff74a24 100644 --- a/Mathlib/RingTheory/HopfAlgebra/Basic.lean +++ b/Mathlib/RingTheory/HopfAlgebra/Basic.lean @@ -30,9 +30,6 @@ In this file we define `HopfAlgebra`, and provide instances for: ## TODO -* Uniqueness of Hopf algebra structure on a bialgebra (i.e. if the algebra and coalgebra structures - agree then the antipodes must also agree). - * If `A` is commutative then `antipode` is an algebra homomorphism. * If `A` is commutative then `antipode` is necessarily a bijection and its square is diff --git a/Mathlib/RingTheory/HopfAlgebra/Convolution.lean b/Mathlib/RingTheory/HopfAlgebra/Convolution.lean index aae1f434c68830..4c416fb70304cb 100644 --- a/Mathlib/RingTheory/HopfAlgebra/Convolution.lean +++ b/Mathlib/RingTheory/HopfAlgebra/Convolution.lean @@ -95,6 +95,23 @@ variable [Semiring C] [HopfAlgebra R C] end LinearMap +namespace HopfAlgebra +variable [Semiring A] [HopfAlgebra R A] {f : A →ₗ[R] A} + +/-- The antipode is the unique left convolution inverse of the identity: any `R`-linear map `f` +with `f * id = 1` in the convolution monoid equals the antipode. -/ +theorem eq_antipode_of_convMul_id_eq_one (h : toConv f * toConv LinearMap.id = 1) : + f = antipode R := + toConv_injective (left_inv_eq_right_inv h LinearMap.id_mul_antipode) + +/-- The antipode is the unique right convolution inverse of the identity: any `R`-linear map `f` +with `id * f = 1` in the convolution monoid equals the antipode. -/ +theorem eq_antipode_of_id_convMul_eq_one (h : toConv LinearMap.id * toConv f = 1) : + f = antipode R := + toConv_injective (left_inv_eq_right_inv LinearMap.antipode_mul_id h).symm + +end HopfAlgebra + namespace LinearMap variable [Semiring C] [HopfAlgebra R C] From 425ea606d60875daf8d92acd09eab5a16742fe16 Mon Sep 17 00:00:00 2001 From: Evgenia Karunus Date: Mon, 10 Aug 2026 13:55:16 +0000 Subject: [PATCH 1246/1300] feat(Order/ConditionallyCompleteLattice/Finset): add `sup_eq_ciSup` (#41361) From the Carleson project. ___ **Upstreaming from Carleson: [/Carleson/ToMathlib/Data/Finset/Lattice/Fold.lean](https://github.com/fpvandoorn/carleson/blob/a3e427dc0f23f6b818c7f7d32f2b1d2ccfab1f21/Carleson/ToMathlib/Data/Finset/Lattice/Fold.lean)** Changes from the Carleson version: 1. `sup_eq_iSup'` is refactored (to shorten the proof & to make some of the imports unnecessary) 2. `sup_eq_iSup'` is renamed to `sup_eq_ciSup` 3. Carleson-suggested file was `/Data/Finset/Lattice/Fold.lean`, but we placed the theorem into `/Order/ConditionallyCompleteLattice/Finset.lean` --- .../ConditionallyCompleteLattice/Finset.lean | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index d509ed4ec1e65d..8cd07c85b9babd 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -272,18 +272,17 @@ end ConditionallyCompleteLattice section ConditionallyCompleteLinearOrderBot variable [ConditionallyCompleteLinearOrderBot α] -lemma sup_univ_eq_ciSup [Fintype ι] (f : ι → α) : univ.sup f = ⨆ i, f i := - le_antisymm - (Finset.sup_le fun _ _ => le_ciSup (finite_range _).bddAbove _) - (ciSup_le' fun _ => Finset.le_sup (mem_univ _)) +theorem sup_eq_ciSup (s : Finset ι) (f : ι → α) : s.sup f = ⨆ x ∈ s, f x := by + apply (ciSup_le' fun _ ↦ ciSup_le' s.le_sup).antisymm' + refine s.sup_le fun a ha ↦ le_ciSup_of_le ?_ a <| by simp [ha] + exact ⟨s.sup f, fun _ ⟨_, hx⟩ ↦ hx ▸ ciSup_le' s.le_sup⟩ + +lemma sup_univ_eq_ciSup [Fintype ι] (f : ι → α) : univ.sup f = ⨆ i, f i := by + simp [sup_eq_ciSup] theorem ciSup_union [DecidableEq ι] {f : ι → α} {s t : Finset ι} : (⨆ x ∈ s ∪ t, f x) = (⨆ x ∈ s, f x) ⊔ (⨆ x ∈ t, f x) := by - suffices ∀ st : Finset ι, BddAbove <| .range fun x ↦ ⨆ (_ : x ∈ st), f x by - simp [ciSup_or', ciSup_sup_eq, this] - refine fun st ↦ ⟨st.sup f, fun a ⟨i, ha⟩ ↦ ha ▸ ?_⟩ - by_cases h : i ∈ st <;> - simp [h, le_sup] + simp_rw [← sup_eq_ciSup, sup_union] end ConditionallyCompleteLinearOrderBot From 06b00bfa6f4aefe4a569810f5485671b56ef9295 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Mon, 10 Aug 2026 13:55:20 +0000 Subject: [PATCH 1247/1300] feat(Analysis/Normed/Affine): mapping dist with homothety (#41910) --- Mathlib/Analysis/Normed/Affine/AddTorsor.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsor.lean b/Mathlib/Analysis/Normed/Affine/AddTorsor.lean index 217cd410576753..ad55eec21840bb 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsor.lean @@ -37,6 +37,19 @@ variable {𝕜 : Type*} [NormedField 𝕜] [NormedSpace 𝕜 V] [NormedSpace open AffineMap +@[simp] +theorem dist_homothety (p₁ p₂ p : P) (c : 𝕜) : + dist (homothety p c p₁) (homothety p c p₂) = ‖c‖ * dist p₁ p₂ := by + simp [dist_eq_norm_vsub, ← (homothety p c).linearMap_vsub, homothety_linear, norm_smul] + +@[simp] +theorem nndist_homothety (p₁ p₂ p : P) (c : 𝕜) : + nndist (homothety p c p₁) (homothety p c p₂) = ‖c‖₊ * nndist p₁ p₂ := + NNReal.eq <| dist_homothety p₁ p₂ p c + +theorem lipschitzWith_homothety (p : P) (c : 𝕜) : LipschitzWith ‖c‖₊ (homothety p c) := + LipschitzWith.of_dist_le_mul fun p₁ p₂ ↦ (dist_homothety p₁ p₂ p c).le + @[simp] theorem dist_center_homothety (p₁ p₂ : P) (c : 𝕜) : dist p₁ (homothety p₁ c p₂) = ‖c‖ * dist p₁ p₂ := by From e662f417a91ca629ad934cca6536e621b499d67c Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:23 +0000 Subject: [PATCH 1248/1300] chore(Geometry/Manifold): avoid some underscore soup (#42205) --- Mathlib/Geometry/Manifold/ContMDiff/Basic.lean | 8 ++++---- Mathlib/Geometry/Manifold/HasGroupoid.lean | 4 +++- Mathlib/Geometry/Manifold/IsManifold/Basic.lean | 10 ++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean index d1b3aac7cfe91b..0ae1af229babb1 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean @@ -417,7 +417,7 @@ then `e` is `C^n`. -/ lemma contMDiff_isOpenEmbedding [Nonempty M] : haveI := h.singletonChartedSpace; ContMDiff I I n e := by have := h.isManifold_singleton (I := I) (n := ω) - rw [@contMDiff_iff _ _ _ _ _ _ _ _ _ _ h.singletonChartedSpace] + rw [@contMDiff_iff] use h.continuous intro x y -- show the function is actually the identity on the range of I ∘ e @@ -431,7 +431,7 @@ lemma contMDiff_isOpenEmbedding [Nonempty M] : exact letI := h.singletonChartedSpace; extChartAt_target_subset_range (I := I) x · -- `hz` implies that `z ∈ range (I ∘ e)` have := hz.1 - rw [@extChartAt_target _ _ _ _ _ _ _ _ _ _ h.singletonChartedSpace] at this + rw [extChartAt_target] at this have := this.1 rw [mem_preimage, OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, h.toOpenPartialHomeomorph_target] at this @@ -474,8 +474,8 @@ lemma ContMDiff.of_comp_isOpenEmbedding {f : M → M'} (hf : ContMDiff I I' n (e ext rw [Function.comp_apply, Function.comp_apply, IsOpenEmbedding.toOpenPartialHomeomorph_left_inv] rw [this] - apply @ContMDiffOn.comp_contMDiff _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - h'.singletonChartedSpace _ _ (range e') _ (contMDiffOn_isOpenEmbedding_symm h') hf + let := h'.singletonChartedSpace + apply ContMDiffOn.comp_contMDiff (t := range e') (contMDiffOn_isOpenEmbedding_symm h') hf simp end diff --git a/Mathlib/Geometry/Manifold/HasGroupoid.lean b/Mathlib/Geometry/Manifold/HasGroupoid.lean index c29f626e9d4923..5c72caa7800af6 100644 --- a/Mathlib/Geometry/Manifold/HasGroupoid.lean +++ b/Mathlib/Geometry/Manifold/HasGroupoid.lean @@ -235,7 +235,9 @@ theorem singletonChartedSpace_mem_atlas_eq (h : e.source = Set.univ) whole space `α`, then the induced charted space structure on `α` is `HasGroupoid G` for any structure groupoid `G` which is closed under restrictions. -/ theorem singleton_hasGroupoid (h : e.source = Set.univ) (G : StructureGroupoid H) - [ClosedUnderRestriction G] : @HasGroupoid _ _ _ _ (e.singletonChartedSpace h) G := + [ClosedUnderRestriction G] : + letI := e.singletonChartedSpace h + HasGroupoid α G := { __ := e.singletonChartedSpace h compatible := by intro e' e'' he' he'' diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 6e654a9d851628..67f8c443522412 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -990,15 +990,17 @@ theorem OpenPartialHomeomorph.isManifold_singleton {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {n : ℕ∞ω} {M : Type*} [TopologicalSpace M] (e : OpenPartialHomeomorph M H) (h : e.source = Set.univ) : - @IsManifold 𝕜 _ E _ _ H _ I n M _ (e.singletonChartedSpace h) := - @IsManifold.mk' _ _ _ _ _ _ _ _ _ _ _ (id _) <| - e.singleton_hasGroupoid h (contDiffGroupoid n I) + letI := e.singletonChartedSpace h + IsManifold I n M := + let := e.singletonChartedSpace h + IsManifold.mk' (gr := e.singleton_hasGroupoid h (contDiffGroupoid n I)) theorem Topology.IsOpenEmbedding.isManifold_singleton {𝕜 E H : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] [NormedSpace 𝕜 E] [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {n : ℕ∞ω} {M : Type*} [TopologicalSpace M] [Nonempty M] {f : M → H} (h : IsOpenEmbedding f) : - @IsManifold 𝕜 _ E _ _ H _ I n M _ h.singletonChartedSpace := + letI := h.singletonChartedSpace + IsManifold I n M := (h.toOpenPartialHomeomorph f).isManifold_singleton (by simp) namespace TopologicalSpace.Opens From 4171fb412ebc3792af3f7fbb86c3c91f69fbaa42 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:25 +0000 Subject: [PATCH 1249/1300] chore: tweak API for modelWithCornersEuclideanHalfSpace (#42281) - un-simp `modelWithCornersEuclideanHalfSpace_toFun`: in applications, this is not always the change you want to make. - instead, add an _apply lemma (and make that simp); that's much better - add `modelWithCornersEuclideanHalfSpace_symm_apply_of_le`, a more useful version of `modelWithCornersEuclideanHalfSpace_symm_apply`. It cannot be used to golf proofs easily, but it's a *much* more useful rewrite lemma. - add analogous lemmas for `modelWithCornersEuclideanQuadrant` Inspired by questions arising in `scholzhannah`'s master's thesis. --- Mathlib/Geometry/Manifold/Instances/Real.lean | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 8d93500db37d4f..55e1e0f500a57d 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -241,13 +241,22 @@ scoped[Manifold] (modelWithCornersEuclideanHalfSpace n : ModelWithCorners ℝ (EuclideanSpace ℝ (Fin n)) (EuclideanHalfSpace n)) -@[simp] lemma modelWithCornersEuclideanHalfSpace_toFun (n : ℕ) [NeZero n] : +lemma modelWithCornersEuclideanHalfSpace_toFun (n : ℕ) [NeZero n] : (𝓡∂ n : _ → _) = Subtype.val := rfl +@[simp] +lemma modelWithCornersEuclideanHalfSpace_apply (n : ℕ) [NeZero n] {p : EuclideanHalfSpace n} : + (𝓡∂ n) p = p.val := rfl + lemma modelWithCornersEuclideanHalfSpace_symm_apply {n : ℕ} [NeZero n] (x : EuclideanSpace ℝ (Fin n)) : (𝓡∂ n).symm x = ⟨toLp 2 (update x 0 (max (x 0) 0)), by simp⟩ := rfl +lemma modelWithCornersEuclideanHalfSpace_symm_apply_of_le {n : ℕ} [NeZero n] + {x : EuclideanSpace ℝ (Fin n)} (hx : 0 ≤ x 0) : + (𝓡∂ n).symm x = ⟨x, hx⟩ := by + simp [modelWithCornersEuclideanHalfSpace_symm_apply, hx] + lemma modelWithCornersEuclideanHalfSpace_zero {n : ℕ} [NeZero n] : (𝓡∂ n) 0 = 0 := rfl lemma range_modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] : @@ -269,6 +278,19 @@ lemma frontier_range_modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] : apply range_euclideanHalfSpace _ = { y | 0 = y 0 } := frontier_halfSpace 2 _ _ +@[simp] +lemma modelWithCornersEuclideanQuadrant_apply (n : ℕ) {p : EuclideanQuadrant n} : + (modelWithCornersEuclideanQuadrant n) p = p.val := rfl + +lemma modelWithCornersEuclideanQuadrant_symm_apply {n : ℕ} (x : EuclideanSpace ℝ (Fin n)) : + (modelWithCornersEuclideanQuadrant n).symm x = ⟨toLp 2 fun i ↦ max (x i) 0, + fun i ↦ by simp only [le_sup_right]⟩ := rfl + +lemma modelWithCornersEuclideanQuadrant_symm_apply_of_le {n : ℕ} + {x : EuclideanSpace ℝ (Fin n)} (hx : ∀ i, 0 ≤ x i) : + (modelWithCornersEuclideanQuadrant n).symm x = ⟨x, hx⟩ := by + simp [modelWithCornersEuclideanQuadrant_symm_apply, hx] + /-- The left chart for the topological space `[x, y]`, defined on `[x,y)` and sending `x` to `0` in `EuclideanHalfSpace 1`. -/ From 8a6925df86cb87eb564459b1f2d54a13816d490c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Serr=C3=A9?= <56162277+gaetanserre@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:28 +0000 Subject: [PATCH 1250/1300] feat(Kernel/Deterministic): any deterministic kernel is s-finite (#42341) Any deterministic kernel is s-finite. --- Mathlib/Probability/Kernel/Deterministic.lean | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Mathlib/Probability/Kernel/Deterministic.lean b/Mathlib/Probability/Kernel/Deterministic.lean index 3d12c909087b15..fed6949d0f5b1f 100644 --- a/Mathlib/Probability/Kernel/Deterministic.lean +++ b/Mathlib/Probability/Kernel/Deterministic.lean @@ -177,4 +177,15 @@ lemma comp_parallelComp_comp_copy {γ : Type*} [MeasurableSpace γ] {κ : Kernel _ = 0 := by rw [measure_compl hs (by simp), measure_univ h₁, h₁, tsub_self] +instance (κ : Kernel α β) [IsDeterministic κ] : IsSFiniteKernel κ := by + by_contra hκ + obtain ⟨a, ha⟩ : ∃ a, 0 < (κ a) univ := by + by_contra! h + let : IsFiniteKernel κ := ⟨⟨0, by simp, h⟩⟩ + exact hκ inferInstance + have h := DFunLike.congr_fun (DFunLike.congr_fun κ.parallelComp_self_comp_copy a) (univ ×ˢ univ) + simp only [parallelComp_of_not_isSFiniteKernel_left κ hκ, zero_comp, zero_apply, + copy_comp_apply_prod κ a .univ .univ, inter_self] at h + exact ha.ne h + end ProbabilityTheory.Kernel From 3f69b1bad1693a2905ff8e9254744fa21ef5f57f Mon Sep 17 00:00:00 2001 From: Francesco Chotuck <101644758+FrankieNC@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:30 +0000 Subject: [PATCH 1251/1300] chore(Data/Finset/Prod): state `singleton_product`/`product_singleton` via `sectR`/`sectL` (#42418) The embeddings in the statements of `Finset.singleton_product` and `Finset.product_singleton` are `Function.Embedding.sectR`/`sectL` written out as anonymous constructors. Restate them via the named embeddings (the statements are definitionally unchanged), so call sites can rewrite with the `sectR_apply`/`sectL_apply` simp lemmas instead of `Embedding.coeFn_mk`. Update the two call sites that did the latter, and golf `singleton_product_singleton`, which is now `rfl`. Preparation for a follow-up PR replacing the `aesop` proofs of the `{Icc,Ico,Ioc,Ioo,uIcc}_map_{sectL,sectR}` lemmas in `Order/Interval/Finset/Basic`. --- Mathlib/Analysis/Fourier/FourierTransformDeriv.lean | 2 +- Mathlib/Data/Finset/Prod.lean | 9 +++------ Mathlib/Topology/EMetricSpace/PairReduction.lean | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean index 0a07d00935193c..ac4f30c5d3d9fe 100644 --- a/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean +++ b/Mathlib/Analysis/Fourier/FourierTransformDeriv.lean @@ -745,7 +745,7 @@ lemma pow_mul_norm_iteratedFDeriv_fourier_le rwa [pow_two, mul_pow, mul_assoc] at this rcases eq_or_ne n 0 with rfl | hn · simp only [pow_zero, one_mul, mul_one, zero_add, Finset.range_one, Finset.product_singleton, - Finset.sum_map, Function.Embedding.coeFn_mk, norm_iteratedFDeriv_zero] at Z ⊢ + Finset.sum_map, Function.Embedding.sectL_apply] at Z ⊢ apply Z.trans conv_rhs => rw [← mul_one π] gcongr diff --git a/Mathlib/Data/Finset/Prod.lean b/Mathlib/Data/Finset/Prod.lean index 097e44badb751d..3a331ec6ea3915 100644 --- a/Mathlib/Data/Finset/Prod.lean +++ b/Mathlib/Data/Finset/Prod.lean @@ -201,19 +201,16 @@ theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ˢ t = ∅ ↔ s contrapose!; exact nonempty_product @[simp] -theorem singleton_product {a : α} : - ({a} : Finset α) ×ˢ t = t.map ⟨Prod.mk a, Prod.mk_right_injective _⟩ := by +theorem singleton_product {a : α} : ({a} : Finset α) ×ˢ t = t.map (.sectR a _) := by ext ⟨x, y⟩ simp [and_left_comm, eq_comm] @[simp] -lemma product_singleton : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod.mk_left_injective _⟩ := by +lemma product_singleton : s ×ˢ {b} = s.map (.sectL _ b) := by ext ⟨x, y⟩ simp [and_left_comm, eq_comm] -theorem singleton_product_singleton {a : α} {b : β} : - ({a} ×ˢ {b} : Finset _) = {(a, b)} := by - simp only [product_singleton, Function.Embedding.coeFn_mk, map_singleton] +theorem singleton_product_singleton {a : α} {b : β} : ({a} ×ˢ {b} : Finset _) = {(a, b)} := rfl @[simp] theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ˢ t = s ×ˢ t ∪ s' ×ˢ t := by grind diff --git a/Mathlib/Topology/EMetricSpace/PairReduction.lean b/Mathlib/Topology/EMetricSpace/PairReduction.lean index a2c61a6f533307..086bc71c47430a 100644 --- a/Mathlib/Topology/EMetricSpace/PairReduction.lean +++ b/Mathlib/Topology/EMetricSpace/PairReduction.lean @@ -387,7 +387,7 @@ lemma edist_le_of_mem_pairSet (ha : 1 < a) (hJ_card : #J ≤ a ^ n) {s t : T} have ⟨hs, ht⟩ := Finset.mem_product.mp (pairSet_subset h) exact Finset.card_le_one_iff.mp hJ_card hs ht simp only [pairSetSeq, hJ, ↓reduceDIte, logSizeBallStruct.ball, Finset.product_eq_sprod, - Finset.singleton_product, Finset.mem_map, Finset.mem_filter, Function.Embedding.coeFn_mk, + Finset.singleton_product, Finset.mem_map, Finset.mem_filter, Function.Embedding.sectR_apply, Prod.mk.injEq, exists_eq_right_right] at h' obtain ⟨⟨ht, hdist⟩, rfl⟩ := h' grw [hdist, radius_logSizeBallSeq_le hJ ha hn hJ_card i] From 4f8e21b9993734158e689236bea7878363a69a1d Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Mon, 10 Aug 2026 13:55:33 +0000 Subject: [PATCH 1252/1300] feat(LocalRing): trivial generalization of RingEquiv.isLocalRing to non-commutative semirings (#42429) Currently `RingEquiv.isLocalRing` is stated only for the case when one of the rings is commutative, but generalizing it to non-commutative rings only involves generalizing type classes. --- Mathlib/RingTheory/LocalRing/Basic.lean | 8 ++------ Mathlib/RingTheory/LocalRing/RingHom/Basic.lean | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Mathlib/RingTheory/LocalRing/Basic.lean b/Mathlib/RingTheory/LocalRing/Basic.lean index 63430eac95cd99..4372d484f4753c 100644 --- a/Mathlib/RingTheory/LocalRing/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/Basic.lean @@ -97,11 +97,7 @@ theorem of_isUnit_or_isUnit_one_sub_self [Nontrivial R] (h : ∀ a : R, IsUnit a IsLocalRing R := ⟨fun {a b} hab => add_sub_cancel_left a b ▸ hab.symm ▸ h a⟩ -end Ring - -section CommRing - -variable [CommRing R] [IsLocalRing R] +variable [IsLocalRing R] theorem isUnit_or_isUnit_one_sub_self (a : R) : IsUnit a ∨ IsUnit (1 - a) := isUnit_or_isUnit_of_isUnit_add <| (add_sub_cancel a 1).symm ▸ isUnit_one @@ -121,7 +117,7 @@ theorem of_surjective' [Ring S] [Nontrivial S] (f : R →+* S) (hf : Function.Su rw [← f.map_one, ← f.map_sub] apply f.isUnit_map) -end CommRing +end Ring end IsLocalRing diff --git a/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean b/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean index deeaae7fdb0531..782a17937fb2b3 100644 --- a/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean @@ -104,7 +104,7 @@ theorem map_maximalIdeal_lt_top (f : R →+* S) [IsLocalHom f] : (maximalIdeal R end -theorem of_surjective [CommSemiring R] [IsLocalRing R] [Semiring S] [Nontrivial S] (f : R →+* S) +theorem of_surjective [Semiring R] [IsLocalRing R] [Semiring S] [Nontrivial S] (f : R →+* S) [IsLocalHom f] (hf : Function.Surjective f) : IsLocalRing S := of_isUnit_or_isUnit_of_isUnit_add (by intro a b hab @@ -156,7 +156,7 @@ end IsLocalRing namespace RingEquiv -protected theorem isLocalRing {A B : Type*} [CommSemiring A] [IsLocalRing A] [Semiring B] +protected theorem isLocalRing {A B : Type*} [Semiring A] [IsLocalRing A] [Semiring B] (e : A ≃+* B) : IsLocalRing B := haveI := e.symm.toEquiv.nontrivial IsLocalRing.of_surjective (e : A →+* B) e.surjective From f51789c952c8445ca120c8107aee04b3956058e9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang <10105016+grunweg@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:35 +0000 Subject: [PATCH 1253/1300] =?UTF-8?q?chore(Geometry/Manifold/Notation):=20?= =?UTF-8?q?avoid=20more=20superfluous=20work=20in=20cus=E2=80=A6=20(#42491?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …tom elaborators We can use mkAppOptM instead of passing from an expression to syntax and re-elaborating that. Continuation of #40933. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Geometry/Manifold/Notation.lean | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index a3d519596a8156..b94531fe4a2169 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -517,9 +517,7 @@ where trace[Elab.DiffGeo.MDiff] "Couldn't find a normed space structure on {H}` either: \ assuming it is a non-trivially normed field" -- Return the trivial model with corners: this will work if `H` is a normed field. - let eT : Term ← Term.exprToSyntax H - let iTerm : Term ← ``(𝓘($eT)) - Term.elabTerm iTerm none + mkAppOptM ``modelWithCornersSelf #[H, none, H, none, none] return m /-- Attempt to find a model with corners on a space of continuous linear maps -/ -- Note that (continuous) linear equivalences are not an abelian group, so are not a model with @@ -569,8 +567,7 @@ where fromUpperHalfPlane : TermElabM Expr := do -- We don't use `match_expr` to avoid importing `UpperHalfPlane`. if (← instantiateMVars e).cleanupAnnotations.isConstOf `UpperHalfPlane then - let c ← Term.exprToSyntax (mkConst `Complex) - Term.elabTerm (← `(𝓘($c))) none + mkAppOptM ``modelWithCornersSelf #[mkConst `Complex, none, mkConst `Complex, none, none] else throwError "`{e}` is not the complex upper half plane" /-- Attempt to find a model with corners on the units in a normed algebra -/ fromUnitsOfAlgebra : TermElabM Expr := do @@ -638,9 +635,8 @@ where -- We don't use `match_expr` to avoid importing `Circle`. if (← instantiateMVars e).cleanupAnnotations.isConstOf `Circle then -- We have not imported `EuclideanSpace` yet, so build an expression by hand. - let r ← Term.exprToSyntax q(ℝ) - let eE ← Term.exprToSyntax <| ← mkAppM `EuclideanSpace #[q(ℝ), q(Fin 1)] - Term.elabTerm (← ``(𝓘($r, $eE))) none + let euclE ← mkAppM `EuclideanSpace #[q(ℝ), q(Fin 1)] + mkAppOptM ``modelWithCornersSelf #[q(ℝ), none, euclE, none, none] else throwError "`{e}` is not the complex unit circle" /-- Attempt to find a model with corners on a metric sphere in a real normed space -/ fromSphere : TermElabM Expr := do @@ -704,9 +700,8 @@ where let some nE ← factFinder E | throwError "Found no fact `finrank ℝ {E} = n + 1` in the local context" -- We have not imported `EuclideanSpace` yet, so build an expression by hand. - let r ← Term.exprToSyntax q(ℝ) - let eE ← Term.exprToSyntax <| ← mkAppM `EuclideanSpace #[q(ℝ), q(Fin $nE)] - Term.elabTerm (← ``(𝓘($r, $eE))) none + let euclE ← mkAppM `EuclideanSpace #[q(ℝ), q(Fin $nE)] + mkAppOptM ``modelWithCornersSelf #[q(ℝ), none, euclE, none, none] else throwError "found no real normed space instance on `{α}`" | _ => throwError "`{e}` is not a sphere in a real normed space" /-- Attempt to find a model with corners from a normed field. From 4a3cbc9c7606e4706507e1c2e3af21c148b72d63 Mon Sep 17 00:00:00 2001 From: Attila Vajda <46789083+attilavjda@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:55:38 +0000 Subject: [PATCH 1254/1300] chore(Algebra/BigOperators): generate sum_Ico_reflect/sum_range_reflect with to_additive (#42592) Tag `prod_Ico_reflect`/`prod_range_reflect` `@[to_additive]` and delete the hand-written twins. Generated statements are identical. I used Aristotle AI to find and solve these patterns --- Mathlib/Algebra/BigOperators/Intervals.lean | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Intervals.lean b/Mathlib/Algebra/BigOperators/Intervals.lean index ca21305873a8e0..9a022e28002378 100644 --- a/Mathlib/Algebra/BigOperators/Intervals.lean +++ b/Mathlib/Algebra/BigOperators/Intervals.lean @@ -132,6 +132,7 @@ theorem prod_Ico_eq_prod_range (f : ℕ → M) (m n : ℕ) : · replace h := h.le rw [Ico_eq_empty_of_le h, tsub_eq_zero_iff_le.mpr h, range_zero, prod_empty, prod_empty] +@[to_additive] theorem prod_Ico_reflect (f : ℕ → M) (k : ℕ) {m n : ℕ} (h : m ≤ n + 1) : (∏ j ∈ Ico k m, f (n - j)) = ∏ j ∈ Ico (n + 1 - m) (n + 1 - k), f j := by have : ∀ i < m, i ≤ n := by @@ -148,10 +149,7 @@ theorem prod_Ico_reflect (f : ℕ → M) (k : ℕ) {m n : ℕ} (h : m ≤ n + 1) exact hkm simp only [hkm, Ico_eq_empty_of_le, prod_empty, Ico_eq_empty_of_le this] -theorem sum_Ico_reflect {δ : Type*} [AddCommMonoid δ] (f : ℕ → δ) (k : ℕ) {m n : ℕ} - (h : m ≤ n + 1) : (∑ j ∈ Ico k m, f (n - j)) = ∑ j ∈ Ico (n + 1 - m) (n + 1 - k), f j := - @prod_Ico_reflect (Multiplicative δ) _ f k m n h - +@[to_additive] theorem prod_range_reflect (f : ℕ → M) (n : ℕ) : (∏ j ∈ range n, f (n - 1 - j)) = ∏ j ∈ range n, f j := by cases n @@ -160,10 +158,6 @@ theorem prod_range_reflect (f : ℕ → M) (n : ℕ) : rw [prod_Ico_reflect _ _ le_rfl] simp -theorem sum_range_reflect {δ : Type*} [AddCommMonoid δ] (f : ℕ → δ) (n : ℕ) : - (∑ j ∈ range n, f (n - 1 - j)) = ∑ j ∈ range n, f j := - @prod_range_reflect (Multiplicative δ) _ f n - @[simp] theorem prod_Ico_id_eq_factorial : ∀ n : ℕ, (∏ x ∈ Ico 1 (n + 1), x) = n ! | 0 => rfl From 64f19e7068d432daae06604b912b2c6278595dbb Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:40:46 +0000 Subject: [PATCH 1255/1300] =?UTF-8?q?feat(GRewrite):=20support=20strict=20?= =?UTF-8?q?rewriting=20in=20`>`/`=E2=89=A5`=20(#41503)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds `gcongr strict` tags in order to support strict rewriting in `≥`/`>`. Previously this only worked in `≤`/`<`. --- Mathlib/Order/Basic.lean | 3 +++ MathlibTest/Tactic/GRewrite.lean | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 8d2b62def97f62..98b2befe5cdbb4 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -179,6 +179,9 @@ theorem gt_imp_gt_of_le_of_le (h₁ : a ≤ c) (h₂ : d ≤ b) : a > b → c > attribute [gcongr strict] lt_of_lt_of_le lt_of_lt_of_le' +@[to_dual (attr := gcongr strict) ge_imp_gt_of_lt'] +theorem ge_imp_gt_of_lt (h : a < b) : a ≥ c → b > c := lt_of_lt_of_le' h + namespace Mathlib.Tactic.GCongr open Lean Meta diff --git a/MathlibTest/Tactic/GRewrite.lean b/MathlibTest/Tactic/GRewrite.lean index db429d3cbca5af..dc889d6e3e2e8b 100644 --- a/MathlibTest/Tactic/GRewrite.lean +++ b/MathlibTest/Tactic/GRewrite.lean @@ -488,6 +488,12 @@ example (h₁ : a ≤ b) (h₂ : b < c) : a < c := by example (h₁ : a ≤ b) (h₂ : b < c) : a < c := by by_contra!; grw [← h₂, ← h₁] at this; contrapose! this; rfl +example (h₁ : a < b) (h₂ : b ≤ c) : c > a := by + grw [h₁, h₂] + +example (h₁ : a < b) (h₂ : b ≤ c) : c > a := by + grw [← h₂, ← h₁] + -- Strict inequalities can also be used as non-strict ones: example (h₁ : a < b) (h₂ : b < c) : a ≤ c := by grw [h₁, h₂] From 6bb0d815ead7cf9e231062bf5b359989bd62ed08 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:40:49 +0000 Subject: [PATCH 1256/1300] ci: retire legacy zulip emoji workflows, enable emojis on mathlib4-nightly-testing (#41965) This PR replaces our existing zulip emoji reaction workflows with new triggers in the new "reconciliation" workflow (`zulip_emoji_reconcile.yml`) added in #41852. Deleted workflows: - `zulip_emoji_ci_status.yaml`: handles CI status reactions. Replaced with `workflow_run` trigger. - `zulip_emoji_closed_pr.yaml`: handles reactions for closed / reopened PRs. Replaced with `pull_request_target` `closed` and `reopened` triggers. - `zulip_emoji_labelling.yaml`: handles reactions for awaiting-author and maintainer-merge labels. Replaced with `pull_request_target` `labeled` and `unlabeled` triggers. - `zulip_emoji_merge_delegate.yaml`: handles reactions for PRs merged into `master`. Replaced with `pull_request_target` `closed` and `reopened` triggers. The Zulip reaction steps have also been removed from `maintainer_bors_wf_run.yml` which now just handles labels: that label event then triggers the reconciliation workflow rather than handling the reactions on its own. This PR also adds and wires in a configuration file for `mathlib4-nightly-testing` so that reactions for `nightly#XXX` PRs are also managed. Prepared with Claude code. --- .github/workflows/maintainer_bors_wf_run.yml | 48 +------- .github/workflows/zulip_emoji_ci_status.yaml | 107 ----------------- .github/workflows/zulip_emoji_closed_pr.yaml | 73 ------------ .github/workflows/zulip_emoji_labelling.yaml | 51 -------- .../workflows/zulip_emoji_merge_delegate.yaml | 57 --------- .github/workflows/zulip_emoji_reconcile.yml | 110 ++++++++++++++++-- .github/zulip-emoji-config-nightly.json | 55 +++++++++ docs/workflows.md | 6 +- 8 files changed, 159 insertions(+), 348 deletions(-) delete mode 100644 .github/workflows/zulip_emoji_ci_status.yaml delete mode 100644 .github/workflows/zulip_emoji_closed_pr.yaml delete mode 100644 .github/workflows/zulip_emoji_labelling.yaml delete mode 100644 .github/workflows/zulip_emoji_merge_delegate.yaml create mode 100644 .github/zulip-emoji-config-nightly.json diff --git a/.github/workflows/maintainer_bors_wf_run.yml b/.github/workflows/maintainer_bors_wf_run.yml index a57de570b64830..76c0d5d74803bb 100644 --- a/.github/workflows/maintainer_bors_wf_run.yml +++ b/.github/workflows/maintainer_bors_wf_run.yml @@ -110,8 +110,8 @@ jobs: # The `ready-to-merge` / `delegated` lifecycle labels are managed by bors # itself (see the `[labels]` table in bors.toml); this workflow no longer # adds or removes them. It still removes the `awaiting-author` and - # `maintainer-merge` labels and updates the Zulip emoji on a merge/delegate - # command. + # `maintainer-merge` labels on a merge/delegate command. (Zulip emoji + # reactions are kept in sync by the `zulip_emoji_reconcile` workflow.) - if: ${{ ! steps.inputs.outputs.mOrD == '' && ( steps.user_permission.outputs.require-result == 'true' || steps.inputs.outputs.bot == 'true' ) }} @@ -125,47 +125,3 @@ jobs: --url "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.inputs.outputs.pr_number }}/labels/${label}" \ --header 'authorization: Bearer ${{ steps.app-token.outputs.token }}' done - - - name: Checkout local actions - if: ${{ ! steps.inputs.outputs.mOrD == '' && - ( steps.user_permission.outputs.require-result == 'true' || - steps.inputs.outputs.bot == 'true' ) }} - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ github.workflow_sha }} - fetch-depth: 1 - sparse-checkout: .github/actions - path: workflow-actions - - name: Get mathlib-ci - if: ${{ ! steps.inputs.outputs.mOrD == '' && - ( steps.user_permission.outputs.require-result == 'true' || - steps.inputs.outputs.bot == 'true' ) }} - uses: ./workflow-actions/.github/actions/get-mathlib-ci - - - name: Set up Python - if: ${{ ! steps.inputs.outputs.mOrD == '' && - ( steps.user_permission.outputs.require-result == 'true' || - steps.inputs.outputs.bot == 'true' ) }} - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: '3.x' - - - name: Install dependencies - if: ${{ ! steps.inputs.outputs.mOrD == '' && - ( steps.user_permission.outputs.require-result == 'true' || - steps.inputs.outputs.bot == 'true' ) }} - run: | - python -m pip install --upgrade pip - pip install -r "$CI_SCRIPTS_DIR/zulip/requirements.txt" - - - name: update zulip emoji reactions - if: ${{ ! steps.inputs.outputs.mOrD == '' && - ( steps.user_permission.outputs.require-result == 'true' || - steps.inputs.outputs.bot == 'true' ) }} - continue-on-error: true - env: - ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }} - ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com - ZULIP_SITE: https://leanprover.zulipchat.com - run: | - python "${CI_SCRIPTS_DIR}/zulip/zulip_emoji_reactions.py" "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "${{ steps.inputs.outputs.mOrD }}" "${{ steps.inputs.outputs.mOrD }}" "${{ steps.inputs.outputs.pr_number }}" diff --git a/.github/workflows/zulip_emoji_ci_status.yaml b/.github/workflows/zulip_emoji_ci_status.yaml deleted file mode 100644 index a0a25cc738cdb1..00000000000000 --- a/.github/workflows/zulip_emoji_ci_status.yaml +++ /dev/null @@ -1,107 +0,0 @@ -name: Zulip emoji CI status - -on: - workflow_run: - workflows: ["continuous integration", "continuous integration (mathlib forks)"] - types: [requested, completed] - -# Limit permissions for GITHUB_TOKEN for the entire workflow -permissions: - contents: read - pull-requests: read - # All other permissions are implicitly 'none' - -jobs: - update_ci_emoji: - runs-on: ubuntu-latest - if: github.repository == 'leanprover-community/mathlib4' || - github.repository == 'leanprover-community/mathlib4-nightly-testing' - steps: - - name: Determine PR number - id: pr - env: - GH_TOKEN: ${{ github.token }} - HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} - HEAD_REPO_OWNER: ${{ github.event.workflow_run.head_repository.owner.login }} - HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - run: | - # Try to get PR number from the workflow_run event - PR_NUMBER=$(echo '${{ toJSON(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number // empty') - # For push-triggered CI (non-fork PRs), pull_requests may be empty; - # fall back to looking up the PR by branch name. - # Use owner:branch format to avoid matching the wrong PR when - # multiple forks use the same branch name. - if [ -z "$PR_NUMBER" ]; then - PR_NUMBER=$(gh pr list --repo "${{ github.repository }}" --head "$HEAD_REPO_OWNER:$HEAD_BRANCH" --state open --json number,headRefOid --jq ".[] | select(.headRefOid == \"$HEAD_SHA\") | .number" 2>/dev/null || true) - fi - # If owner-qualified lookup failed, try without owner (for same-repo branches) - if [ -z "$PR_NUMBER" ]; then - PR_NUMBER=$(gh pr list --repo "${{ github.repository }}" --head "$HEAD_BRANCH" --state open --json number,headRefOid --jq ".[] | select(.headRefOid == \"$HEAD_SHA\") | .number" 2>/dev/null || true) - fi - if [ -z "$PR_NUMBER" ]; then - echo "No PR found for branch $HEAD_REPO_OWNER:$HEAD_BRANCH at $HEAD_SHA, skipping" - echo "skip=true" >> "$GITHUB_OUTPUT" - else - echo "Found PR #$PR_NUMBER" - echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" - echo "skip=false" >> "$GITHUB_OUTPUT" - fi - - - name: Determine CI action - id: action - if: steps.pr.outputs.skip != 'true' - run: | - EVENT_ACTION="${{ github.event.action }}" - CONCLUSION="${{ github.event.workflow_run.conclusion }}" - echo "Event action: $EVENT_ACTION, conclusion: $CONCLUSION" - if [ "$EVENT_ACTION" = "requested" ]; then - echo "ci_action=ci-running" >> "$GITHUB_OUTPUT" - elif [ "$EVENT_ACTION" = "completed" ]; then - case "$CONCLUSION" in - success) - echo "ci_action=ci-success" >> "$GITHUB_OUTPUT" - ;; - cancelled) - # Clear the running emoji. A new run may or may not follow - # (manual cancel, branch deleted, etc.), so don't leave stale 🟡. - echo "ci_action=ci-cancelled" >> "$GITHUB_OUTPUT" - ;; - *) - echo "ci_action=ci-failure" >> "$GITHUB_OUTPUT" - ;; - esac - fi - - - name: Checkout local actions - if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ github.workflow_sha }} - fetch-depth: 1 - sparse-checkout: .github/actions - path: workflow-actions - - name: Checkout mathlib-ci - if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: ./workflow-actions/.github/actions/get-mathlib-ci - - - name: Set up Python - if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: '3.x' - - - name: Install dependencies - if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - run: | - python -m pip install --upgrade pip - pip install -r "$CI_SCRIPTS_DIR/zulip/requirements.txt" - - - name: Update CI emoji - if: steps.pr.outputs.skip != 'true' && steps.action.outputs.ci_action != 'skip' - continue-on-error: true - env: - ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }} - ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com - ZULIP_SITE: https://leanprover.zulipchat.com - run: | - python "${CI_SCRIPTS_DIR}/zulip/zulip_emoji_reactions.py" "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "${{ steps.action.outputs.ci_action }}" "none" "${{ steps.pr.outputs.pr_number }}" diff --git a/.github/workflows/zulip_emoji_closed_pr.yaml b/.github/workflows/zulip_emoji_closed_pr.yaml deleted file mode 100644 index d5b7ce696d0e43..00000000000000 --- a/.github/workflows/zulip_emoji_closed_pr.yaml +++ /dev/null @@ -1,73 +0,0 @@ -name: Add "closed-pr" emoji in Zulip -# adds a reaction to Zulip messages that refer to a PR that was closed, but not merged - -# triggers the action when -on: - pull_request_target: - # the pull request is closed or reopened, to add or remove the emoji - types: [closed, reopened] - -# Limit permissions for GITHUB_TOKEN for the entire workflow -permissions: - contents: read # minimum permissions for actions/checkout & actions/setup-python - # All other permissions are implicitly 'none' - -jobs: - add_closed_pr_emoji: - # we set the `TITLE` of the PR as a variable, this shields from possible code injection - env: - TITLE: ${{ github.event.pull_request.title }} - - name: Add closed-pr emoji in Zulip - runs-on: ubuntu-latest - if: github.repository == 'leanprover-community/mathlib4' || - github.repository == 'leanprover-community/mathlib4-nightly-testing' - steps: - - name: Debugging information - run: | - # may be superfluous: GitHub may print the values of the environment variables by default - printf '%s' "${TITLE}" | hexdump -cC - printf 'PR title:"%s"\n' "${TITLE}" - printf 'issue number: "%s"\npull request number: "%s"\n' "${{ github.event.issue.number }}" "${{ github.event.pull_request.number }}" - - - name: Checkout local actions - if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || - github.event_name == 'reopened' }} - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ github.workflow_sha }} - fetch-depth: 1 - sparse-checkout: .github/actions - path: workflow-actions - - name: Checkout mathlib-ci - if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || - github.event_name == 'reopened' }} - uses: ./workflow-actions/.github/actions/get-mathlib-ci - - - name: Set up Python - if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || - github.event_name == 'reopened' }} - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: '3.x' - - - name: Install dependencies - if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || - github.event_name == 'reopened' }} - run: | - python -m pip install --upgrade pip - pip install -r "$CI_SCRIPTS_DIR/zulip/requirements.txt" - - - name: Update zulip emoji reactions - if: ${{ ! startsWith(github.event.pull_request.title, '[Merged by Bors]') || - github.event_name == 'reopened' }} - continue-on-error: true - env: - ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }} - ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com - ZULIP_SITE: https://leanprover.zulipchat.com - run: | - # ${{ github.event.action }} is either "closed" or "reopened" - # We add the "closed-pr" emoji to the message, if it is "closed" - # and remove the emoji if the action is "reopen". - python "${CI_SCRIPTS_DIR}/zulip/zulip_emoji_reactions.py" "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "${{ github.event.action }}" "none" "${{ github.event.pull_request.number }}" diff --git a/.github/workflows/zulip_emoji_labelling.yaml b/.github/workflows/zulip_emoji_labelling.yaml deleted file mode 100644 index 9d9ada427ff46f..00000000000000 --- a/.github/workflows/zulip_emoji_labelling.yaml +++ /dev/null @@ -1,51 +0,0 @@ -on: - pull_request_target: - types: [labeled, unlabeled] - -# Limit permissions for GITHUB_TOKEN for the entire workflow -permissions: - contents: read # minimum permissions for actions/checkout & actions/setup-python - # All other permissions are implicitly 'none' - -jobs: - # When a PR is (un)labelled with awaiting-author or maintainer-merge, - # add resp. remove the matching emoji reaction from zulip messages. - set_pr_emoji: - if: (github.event.label.name == 'awaiting-author' || github.event.label.name == 'maintainer-merge') && - (github.repository == 'leanprover-community/mathlib4' || - github.repository == 'leanprover-community/mathlib4-nightly-testing') - runs-on: ubuntu-latest - steps: - - name: Checkout local actions - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ github.workflow_sha }} - fetch-depth: 1 - sparse-checkout: .github/actions - path: workflow-actions - - name: Checkout mathlib-ci - uses: ./workflow-actions/.github/actions/get-mathlib-ci - - - name: Set up Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: '3.x' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r "$CI_SCRIPTS_DIR/zulip/requirements.txt" - - - name: Add or remove emoji - continue-on-error: true # Emoji updates are cosmetic; never fail CI over them - env: - ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }} - ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com - ZULIP_SITE: https://leanprover.zulipchat.com - PR_NUMBER: ${{ github.event.number}} - LABEL_STATUS: ${{ github.event.action }} - LABEL_NAME: ${{ github.event.label.name }} - PR_LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }} - run: | - printf $'Running the python script with:\nPR number: "%s"\nlabel status: "%s"\nlabel: "%s"\nPR labels: "%s"\n' "$PR_NUMBER" "$LABEL_STATUS" "$LABEL" "$PR_LABELS" - python "${CI_SCRIPTS_DIR}/zulip/zulip_emoji_reactions.py" "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "$LABEL_STATUS" "$LABEL_NAME" "$PR_NUMBER" "$PR_LABELS" diff --git a/.github/workflows/zulip_emoji_merge_delegate.yaml b/.github/workflows/zulip_emoji_merge_delegate.yaml deleted file mode 100644 index 0e30202664a80a..00000000000000 --- a/.github/workflows/zulip_emoji_merge_delegate.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: Zulip emoji merge update - -on: - push: - branches: - - master - - nightly-testing - - bump/* - -jobs: - zulip-emoji-merged: - runs-on: ubuntu-latest - if: github.repository == 'leanprover-community/mathlib4' || - github.repository == 'leanprover-community/mathlib4-nightly-testing' - - steps: - - name: Checkout mathlib4 repository history - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - fetch-depth: 0 # download the full repository - - - name: Checkout local actions - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ github.workflow_sha }} - fetch-depth: 1 - sparse-checkout: .github/actions - path: workflow-actions - - name: Checkout mathlib-ci - uses: ./workflow-actions/.github/actions/get-mathlib-ci - - - name: Set up Python - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: '3.x' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r "$CI_SCRIPTS_DIR/zulip/requirements.txt" - - - name: Update zulip emoji reactions - continue-on-error: true # Emoji updates are cosmetic; never fail CI over them - env: - ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }} - ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com - ZULIP_SITE: https://leanprover.zulipchat.com - run: | - # scan the commits of the past 10 minutes, assuming that the timezone of the current machine - # is the same that performed the commit - git log --since="10 minutes ago" --pretty=oneline - - printf $'Scanning commits:\n%s\n\nContinuing\n' "$(git log --since="10 minutes ago" --pretty=oneline)" - while read -r pr_number; do - printf $'Running the python script with pr "%s"\n' "${pr_number}" - python "${CI_SCRIPTS_DIR}/zulip/zulip_emoji_reactions.py" "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "[Merged by Bors]" "none" "${pr_number}" - done < <(git log --oneline -n 10 | grep -oP '.*\(#\K\d+(?=\))') diff --git a/.github/workflows/zulip_emoji_reconcile.yml b/.github/workflows/zulip_emoji_reconcile.yml index c71ba0309eeee4..229bf544c41148 100644 --- a/.github/workflows/zulip_emoji_reconcile.yml +++ b/.github/workflows/zulip_emoji_reconcile.yml @@ -1,8 +1,16 @@ -# Periodic safety net that keeps the Zulip emoji reactions on PR-related messages -# in sync with each PR's actual state (open/closed/merged, labels, CI result). -# The event-driven zulip_emoji_* workflows react to individual label/close/CI -# events; this sweep repairs any drift they miss (dropped webhooks, outages, -# state changes while a workflow was broken). See +# Keeps the Zulip emoji reactions on PR-related messages in sync with each PR's +# actual state (open/closed/merged, labels, CI result). One job, fed by three +# kinds of trigger: +# - schedule: hourly sweep — the self-healing safety net that repairs +# any drift the event triggers miss (dropped webhooks, +# outages, state changes while a run was broken). +# - pull_request_target: label/close/merge/reopen changes, reflected in seconds. +# - workflow_run: CI start/finish, so the CI emoji updates promptly. +# This same workflow serves both leanprover-community/mathlib4 and its +# leanprover-community/mathlib4-nightly-testing mirror (whose adaptation PRs are +# announced in the `nightly-testing-mathlib` Zulip channel); the "Select config" +# step picks the matching config per repo. Everything repo-specific lives in +# those JSON configs; the engine and its docs are in mathlib-ci: # https://github.com/leanprover-community/mathlib-ci/blob/master/docs/zulip-emoji-reconcile.md name: Zulip emoji reconcile @@ -11,12 +19,29 @@ on: - cron: "37 * * * *" # hourly, offset to dodge top-of-hour runner load workflow_dispatch: inputs: + pr: + description: PR number(s), space-separated; leave empty to sweep recent messages + required: false + default: "" dry-run: description: Log planned reaction changes without modifying Zulip type: boolean default: false + pull_request_target: # label/close/merge/reopen changes, within seconds + types: [labeled, unlabeled, closed, reopened] + workflow_run: # CI start/finish, so the CI emoji updates promptly + workflows: ["continuous integration", "continuous integration (mathlib forks)"] + types: [requested, completed] concurrency: + # Serialize runs: the reconciler reads live PR state and then writes reactions, + # so two interleaved runs could re-assert stale state. GitHub keeps only the + # newest queued run per group (earlier pending runs are canceled), which suits a + # level-triggered tool — the last run recomputes everything from live state and + # converges to the final answer. One *shared* group is deliberate: the same PR + # reaches this workflow under different keys (pull_request.number, + # workflow_run.head_sha, nothing on a sweep), so per-PR groups would leave + # exactly those cross-trigger races open. group: ${{ github.workflow }} cancel-in-progress: false @@ -26,20 +51,85 @@ permissions: jobs: reconcile: - if: github.repository == 'leanprover-community/mathlib4' + if: github.repository == 'leanprover-community/mathlib4' || + github.repository == 'leanprover-community/mathlib4-nightly-testing' runs-on: ubuntu-latest steps: + # On pull_request_target / workflow_run this checks out the *default* + # branch, so the config (and everything else in this job) is never + # PR-controlled. - name: Check out reconcile config uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - sparse-checkout: .github/zulip-emoji-config.json + sparse-checkout: | + .github/zulip-emoji-config.json + .github/zulip-emoji-config-nightly.json sparse-checkout-cone-mode: false + - name: Select config for this repository + id: cfg + env: + REPO: ${{ github.repository }} + run: | + set -euo pipefail + case "$REPO" in + leanprover-community/mathlib4-nightly-testing) + config=.github/zulip-emoji-config-nightly.json ;; + *) + config=.github/zulip-emoji-config.json ;; + esac + if [ -f "$config" ]; then + echo "config=${config}" >> "$GITHUB_OUTPUT" + echo "present=true" >> "$GITHUB_OUTPUT" + else + # The nightly config reaches mathlib4-nightly-testing only after the + # next master -> nightly-testing sync; until then, no-op rather than + # fail a scheduled run. + echo "::notice::reconcile config ${config} not present yet; skipping." + echo "present=false" >> "$GITHUB_OUTPUT" + fi + + - name: Determine PR number(s) + id: target + env: + GH_TOKEN: ${{ github.token }} + EVENT: ${{ github.event_name }} + INPUT_PR: ${{ inputs.pr }} + EVENT_PR: ${{ github.event.pull_request.number }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + run: | + set -euo pipefail + case "$EVENT" in + workflow_dispatch) pr="$INPUT_PR" ;; + pull_request_target) pr="$EVENT_PR" ;; + workflow_run) + # PR(s) at the CI run's head commit (works for fork PRs too). + pr=$(gh api "repos/${GITHUB_REPOSITORY}/commits/${HEAD_SHA}/pulls" \ + --jq 'map(.number) | join(" ")') + ;; + *) pr="" ;; # schedule -> sweep + esac + echo "pr=${pr}" >> "$GITHUB_OUTPUT" + - name: Reconcile + # Emoji reactions are cosmetic: a Zulip or API hiccup must never put a + # red X (or send a failure email) on a contributor's PR or a CI run. So + # the two contributor-facing event triggers swallow failures, matching + # the `continue-on-error` the retired event-driven workflows carried. + # The hourly `schedule` sweep and manual `workflow_dispatch` runs stay + # loud: the sweep is the health signal for the reconciler itself, and a + # manual run is someone actively debugging who wants to see the error. + continue-on-error: ${{ github.event_name == 'pull_request_target' || github.event_name == 'workflow_run' }} + # Skip when no config is present (nightly, pre-sync), and skip only a + # workflow_run whose head commit no longer maps to a PR; schedule and + # PR-less dispatches sweep instead. + if: steps.cfg.outputs.present == 'true' && + (steps.target.outputs.pr != '' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') uses: leanprover-community/mathlib-ci/.github/actions/zulip-emoji-reconcile@5668fbbccf0fecefdfcddf539b8406db197dfc59 with: - config: .github/zulip-emoji-config.json - sweep: true - dry-run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry-run }} + config: ${{ steps.cfg.outputs.config }} + pr: ${{ steps.target.outputs.pr }} + sweep: ${{ !steps.target.outputs.pr }} + dry-run: ${{ inputs.dry-run == true }} zulip-api-key: ${{ secrets.ZULIP_API_KEY }} github-token: ${{ github.token }} diff --git a/.github/zulip-emoji-config-nightly.json b/.github/zulip-emoji-config-nightly.json new file mode 100644 index 00000000000000..93a179343dfe98 --- /dev/null +++ b/.github/zulip-emoji-config-nightly.json @@ -0,0 +1,55 @@ +{ + "_comment": "The mathlib4 config (.github/zulip-emoji-config.json) retargeted at the leanprover-community/mathlib4-nightly-testing repo and its 'nightly-testing-mathlib' channel (where adaptation PRs are announced, one topic per PR), with the unused 'maintainer-merge' state and 'reviewers' channel dropped. Keep otherwise in sync with that file. Docs: https://github.com/leanprover-community/mathlib-ci/blob/master/docs/zulip-emoji-reconcile.md", + + "github_repo": "leanprover-community/mathlib4-nightly-testing", + + "merged_title_prefix": "[Merged by Bors] -", + + "zulip": { + "site": "https://leanprover.zulipchat.com", + "email": "github-mathlib4-bot@leanprover.zulipchat.com" + }, + + "channels": { + "pr_reviews": "nightly-testing-mathlib", + "rss_allow": ["mathlib bors notifications"] + }, + + "ci": { + "check_names": ["Build", "Lint style", "Post-Build Step", "Check workflows"] + }, + + "states": [ + { + "name": "merged", "group": "pr", "priority": 30, + "source": {"state": "merged"}, "emoji": "merge" + }, + { + "name": "closed", "group": "pr", "priority": 20, + "source": {"state": "closed"}, + "emoji": "closed-pr", "emoji_code": "61293", "reaction_type": "realm_emoji" + }, + { + "name": "ready-to-merge", "group": "pr", "priority": 12, + "source": {"label": "ready-to-merge"}, + "emoji": "bors", "emoji_code": "22134", "reaction_type": "realm_emoji" + }, + { + "name": "delegated", "group": "pr", "priority": 11, + "source": {"label": "delegated"}, "emoji": "peace_sign" + }, + { + "name": "awaiting-author", "group": "pr", "priority": 10, + "source": {"label": "awaiting-author"}, "emoji": "writing" + }, + + {"name": "ci-running", "group": "ci", "source": {"ci": "running"}, "emoji": "yellow"}, + {"name": "ci-success", "group": "ci", "source": {"ci": "success"}, "emoji": "check"}, + {"name": "ci-failure", "group": "ci", "source": {"ci": "failure"}, "emoji": "cross_mark"}, + + { + "name": "migrated", "group": null, "sticky": true, + "source": {"label": "migrated-from-branch"}, "emoji": "skip_forward" + } + ] +} diff --git a/docs/workflows.md b/docs/workflows.md index 45afc95ad2e788..b310acf147335b 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -52,8 +52,7 @@ Primary trigger for this section: PR/merge-queue events (`pull_request`, `pull_r | [`PR_summary.yml`](../.github/workflows/PR_summary.yml) | Post PR summary comment
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/PR_summary.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/PR_summary.yml) | Low | `pull_request_target` | On `pull_request_target`, computes PR summary data (imports/declarations/tech debt), manages related labels, and updates PR comments. | | [`add_label_from_diff.yaml`](../.github/workflows/add_label_from_diff.yaml) | Autolabel PRs
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/add_label_from_diff.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/add_label_from_diff.yaml) | Low | `pull_request_target, push` | Applies an inferred topic label to newly opened PRs using `lake exe autolabel`. | | [`label_new_contributor.yml`](../.github/workflows/label_new_contributor.yml) | Label New Contributors
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/label_new_contributor.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/label_new_contributor.yml) | Low | `pull_request_target` | Labels PRs from new contributors (based on the number of their PRs merged). | -| [`zulip_emoji_closed_pr.yaml`](../.github/workflows/zulip_emoji_closed_pr.yaml) | Add "closed-pr" emoji in Zulip
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/zulip_emoji_closed_pr.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/zulip_emoji_closed_pr.yaml) | Low | `pull_request_target` | Updates Zulip emoji reactions for PR close/reopen events. | -| [`zulip_emoji_labelling.yaml`](../.github/workflows/zulip_emoji_labelling.yaml) | zulip_emoji_labelling.yaml
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/zulip_emoji_labelling.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/zulip_emoji_labelling.yaml) | Low | `pull_request_target` | Updates Zulip emoji reactions in response to PR label changes. | +| [`zulip_emoji_reconcile.yml`](../.github/workflows/zulip_emoji_reconcile.yml) | Zulip emoji reconcile
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/zulip_emoji_reconcile.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/zulip_emoji_reconcile.yml) | Low | `schedule, pull_request_target, workflow_run, workflow_dispatch` | Keeps the Zulip emoji reactions on PR-related messages in sync with each PR's state (open/closed/merged, labels, CI result). The event triggers update within seconds; the hourly `schedule` sweep is a self-healing safety net. Repo-specific rules live in `.github/zulip-emoji-config.json`; the engine is in mathlib-ci. Also runs on the `mathlib4-nightly-testing` mirror, using `.github/zulip-emoji-config-nightly.json`. | ## Maintainer commands @@ -64,7 +63,6 @@ Primary trigger for this section: PR/merge-queue events (`pull_request`, `pull_r | [`labels_from_comment.yml`](../.github/workflows/labels_from_comment.yml) | Label PR based on Comment
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/labels_from_comment.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/labels_from_comment.yml) | Medium | `issue_comment, pull_request_review, pull_request_review_comment` | Adds/removes an allowlisted set of labels based on comment/review text commands. | | [`bot_fix_style.yaml`](../.github/workflows/bot_fix_style.yaml) | bot fix style
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/bot_fix_style.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/bot_fix_style.yaml) | Low | `issue_comment, pull_request_review, pull_request_review_comment` | Responds to review/comment events and runs `lint-style-action` in `fix` mode. | | [`olean_report.yaml`](../.github/workflows/olean_report.yaml) | olean report
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/olean_report.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/olean_report.yaml) | Low | `issue_comment` | On-demand olean diff for a PR, triggered by `!olean_report` at the start of a comment line. Fetches oleans for the PR head and its merge base, runs a diff, and emits a bridge artifact for the companion workflow to post as a PR comment. | -| [`zulip_emoji_merge_delegate.yaml`](../.github/workflows/zulip_emoji_merge_delegate.yaml) | Zulip emoji merge update
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/zulip_emoji_merge_delegate.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/zulip_emoji_merge_delegate.yaml) | Low | `push` | On push to `master`, detects merged PR context and updates Zulip emoji state. | | [`sync_closed_tasks.yaml`](../.github/workflows/sync_closed_tasks.yaml) | Cross off linked issues
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/sync_closed_tasks.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/sync_closed_tasks.yaml) | Low | `issues, pull_request` | Updates the dependent PR checkboxes when issues/PRs are closed or reopened. | ## Scheduled CI maintenance @@ -100,7 +98,7 @@ Primary trigger for this section: completion of other workflows (`workflow_run`) |---|---|---|---|---| | [`nightly_detect_failure.yml`](../.github/workflows/nightly_detect_failure.yml) | Post to zulip if the nightly-testing branch is failing.
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/nightly_detect_failure.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/nightly_detect_failure.yml) | High | `workflow_run` | Reacts to nightly-testing CI outcomes; posts status updates and performs branch/tag maintenance on success. | | [`update_dependencies_zulip.yml`](../.github/workflows/update_dependencies_zulip.yml) | Monitor Dependency Update Failures
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/update_dependencies_zulip.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/update_dependencies_zulip.yml) | High | `workflow_run` | Watches dependency-update CI runs and sends Zulip success/failure messages with PR/label handling. | -| [`maintainer_bors_wf_run.yml`](../.github/workflows/maintainer_bors_wf_run.yml) | Bors merge/delegate follow-up (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_bors_wf_run.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_bors_wf_run.yml) | Medium | `workflow_run` | Privileged companion: removes `awaiting-author`/`maintainer-merge` and updates Zulip emoji reactions on bors merge/delegate commands. The `ready-to-merge`/`delegated` lifecycle labels are managed by bors itself. | +| [`maintainer_bors_wf_run.yml`](../.github/workflows/maintainer_bors_wf_run.yml) | Bors merge/delegate follow-up (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_bors_wf_run.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_bors_wf_run.yml) | Medium | `workflow_run` | Privileged companion: removes `awaiting-author`/`maintainer-merge` on bors merge/delegate commands. The `ready-to-merge`/`delegated` lifecycle labels are managed by bors itself, and Zulip emoji reactions by `zulip_emoji_reconcile.yml`. | | [`maintainer_merge_wf_run.yml`](../.github/workflows/maintainer_merge_wf_run.yml) | Maintainer merge (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/maintainer_merge_wf_run.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/maintainer_merge_wf_run.yml) | Medium | `workflow_run` | Manages labels and posts on Zulip for maintainer merge/delegate commands. | | [`olean_report_wf_run.yaml`](../.github/workflows/olean_report_wf_run.yaml) | olean report (workflow_run)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/olean_report_wf_run.yaml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/olean_report_wf_run.yaml) | Low | `workflow_run` | Privileged companion to `olean_report.yaml`. Downloads the bridge artifact and posts or updates the olean diff as a comment on the PR. | | [`decls-diff.yml`](../.github/workflows/decls-diff.yml) | Declarations diff (post-build)
[![passed/failed](https://img.shields.io/github/actions/workflow/status/leanprover-community/mathlib4/decls-diff.yml?label=status)](https://github.com/leanprover-community/mathlib4/actions/workflows/decls-diff.yml) | Low | `workflow_run` | Post-build companion to `ci` that diffs the `import-graph` artifact of a PR build against its master merge-base and patches the `### PR summary` comment's declarations-diff section with the Lean-aware result (or a cache-miss notice). | From 5c9bdaee33e9273ef6b8207fba3bbf97ad2a8492 Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Mon, 10 Aug 2026 15:36:16 +0000 Subject: [PATCH 1257/1300] refactor(simps): centralize notation_class and initialize_simps_projections (#41976) * Create a single file that declares all `notation_class` attributes and `initialize_simps_projections` calls for many structures in Core. * Some of these notation classes were previously declared in `Tactic.Simps.Basic` or in other Mathlib files. The latter was problematic, because then you could have files that import `simps` and a Core structure, but not generate the right simp lemmas. * Make sure that we import this file instead of the internal `Tactic.Simps.Basic` file throughout Mathlib. Not importing this file can cause `simps` to generate wrong lemmas. * Also call `initialize_simps_projections` for (some) classes that are declared in Mathlib. (This is not super important, but ensures that these projections have to be only generated once, instead of in every file that imports it.) * This was prompted by observing faulty behavior in #40653. --- Mathlib.lean | 1 + Mathlib/Algebra/Group/Defs.lean | 2 +- Mathlib/Algebra/Notation/Defs.lean | 7 +- .../Monoidal/Functor/Types.lean | 2 +- Mathlib/Data/FunLike/Basic.lean | 4 +- Mathlib/Data/Subtype.lean | 4 +- Mathlib/Data/TwoPointing.lean | 2 +- Mathlib/Logic/Equiv/Defs.lean | 2 +- Mathlib/Order/Defs/LinearOrder.lean | 2 +- Mathlib/Order/Notation.lean | 7 +- Mathlib/Tactic.lean | 1 + Mathlib/Tactic/Common.lean | 2 +- Mathlib/Tactic/ProdAssoc.lean | 2 +- Mathlib/Tactic/ProxyType.lean | 2 +- Mathlib/Tactic/Simps.lean | 130 ++++++++++++++++++ Mathlib/Tactic/Simps/Basic.lean | 15 -- Mathlib/Tactic/Simps/NotationClass.lean | 3 +- MathlibTest/Simps.lean | 16 ++- MathlibTest/TacticCheckInstancesSimps.lean | 2 +- 19 files changed, 170 insertions(+), 36 deletions(-) create mode 100644 Mathlib/Tactic/Simps.lean diff --git a/Mathlib.lean b/Mathlib.lean index e5c0e22680d50c..d03e6bafadcf88 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7551,6 +7551,7 @@ public import Mathlib.Tactic.Simproc.ExistsAndEq public import Mathlib.Tactic.Simproc.Factors public import Mathlib.Tactic.Simproc.FinsetInterval public import Mathlib.Tactic.Simproc.VecPerm +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.Simps.Basic public import Mathlib.Tactic.Simps.NotationClass public import Mathlib.Tactic.SplitIfs diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 72942dc5428ad4..e520df2ce65f16 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -14,7 +14,7 @@ public import Mathlib.Data.Nat.BinaryRec public import Mathlib.Tactic.MkIffOfInductiveProp public import Mathlib.Tactic.OfNat public import Mathlib.Data.Nat.Notation -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.AdaptationNote public import Mathlib.Tactic.CrossRefAttribute diff --git a/Mathlib/Algebra/Notation/Defs.lean b/Mathlib/Algebra/Notation/Defs.lean index 281afb2937ae4c..800f1bf2161ea5 100644 --- a/Mathlib/Algebra/Notation/Defs.lean +++ b/Mathlib/Algebra/Notation/Defs.lean @@ -5,7 +5,7 @@ Authors: Jeremy Avigad, Leonardo de Moura, Simon Hudon, Mario Carneiro -/ module -public import Mathlib.Tactic.Simps.NotationClass +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.ToAdditive /-! @@ -47,9 +47,6 @@ class HVAdd (α : Type u) (β : Type v) (γ : outParam (Type w)) where The meaning of this notation is type-dependent. -/ hVAdd : α → β → γ -attribute [notation_class smul Simps.copySecond] HSMul -attribute [notation_class nsmul Simps.nsmulArgs] HSMul -attribute [notation_class zsmul Simps.zsmulArgs] HSMul attribute [notation_class vadd Simps.copySecond] HVAdd /-- Type class for the `+ᵥ` notation. -/ @@ -74,6 +71,8 @@ class SDiv (G : outParam Type*) (P : Type*) where attribute [to_additive existing] SMul HSMul attribute [to_additive (attr := default_instance)] instHSMul +initialize_simps_projections VAdd + attribute [ext] SMul VAdd @[inherit_doc] infixr:65 " +ᵥ " => HVAdd.hVAdd diff --git a/Mathlib/CategoryTheory/Monoidal/Functor/Types.lean b/Mathlib/CategoryTheory/Monoidal/Functor/Types.lean index d5fcdd5bbcbc56..ad30255469d9b4 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor/Types.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor/Types.lean @@ -8,7 +8,7 @@ module public import Mathlib.CategoryTheory.Monoidal.Functor public import Mathlib.CategoryTheory.Monoidal.Types.Basic public import Mathlib.CategoryTheory.Types.Basic -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps public import Mathlib.Control.Basic /-! diff --git a/Mathlib/Data/FunLike/Basic.lean b/Mathlib/Data/FunLike/Basic.lean index d2162dd8f1a92f..77e8cb25394ed3 100644 --- a/Mathlib/Data/FunLike/Basic.lean +++ b/Mathlib/Data/FunLike/Basic.lean @@ -9,7 +9,7 @@ public meta import Lean.Meta.CoeAttr public import Mathlib.Logic.Function.Basic public import Mathlib.Logic.Unique public import Mathlib.Util.CompileInductive -public import Mathlib.Tactic.Simps.NotationClass +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.SplitIfs /-! @@ -156,6 +156,8 @@ such as `ZeroHomClass`, `MulHomClass`, `MonoidHomClass`, .... -/ abbrev FunLike F α β := DFunLike F α fun _ => β +initialize_simps_projections DFunLike + section Dependent /-! ### `DFunLike F α β` where `β` depends on `a : α` -/ diff --git a/Mathlib/Data/Subtype.lean b/Mathlib/Data/Subtype.lean index abce50412ff816..7acce8951a1394 100644 --- a/Mathlib/Data/Subtype.lean +++ b/Mathlib/Data/Subtype.lean @@ -7,7 +7,7 @@ module public import Mathlib.Logic.Function.Basic public import Mathlib.Tactic.AdaptationNote -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps /-! # Subtypes @@ -35,8 +35,6 @@ variable {α β γ : Sort*} {p q : α → Prop} attribute [coe] Subtype.val -initialize_simps_projections Subtype (val → coe) - /-- A version of `x.property` or `x.2` where `p` is syntactically applied to the coercion of `x` instead of `x.1`. A similar result is `Subtype.mem` in `Mathlib/Data/Set/Basic.lean`. -/ -- This is a leftover from Lean 3: it is identical to `Subtype.property`, and should be deprecated. diff --git a/Mathlib/Data/TwoPointing.lean b/Mathlib/Data/TwoPointing.lean index 53a3240d04a9f9..128cfd9798a475 100644 --- a/Mathlib/Data/TwoPointing.lean +++ b/Mathlib/Data/TwoPointing.lean @@ -7,7 +7,7 @@ module public import Mathlib.Logic.Nontrivial.Defs public import Mathlib.Logic.Nonempty -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps public import Batteries.Logic /-! diff --git a/Mathlib/Logic/Equiv/Defs.lean b/Mathlib/Logic/Equiv/Defs.lean index 63063f27c56b65..7902c392061684 100644 --- a/Mathlib/Logic/Equiv/Defs.lean +++ b/Mathlib/Logic/Equiv/Defs.lean @@ -9,7 +9,7 @@ public import Mathlib.Data.FunLike.Equiv public import Mathlib.Data.Quot public import Mathlib.Data.Subtype public import Mathlib.Logic.Unique -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.Substs import Mathlib.Tactic.Attr.Register diff --git a/Mathlib/Order/Defs/LinearOrder.lean b/Mathlib/Order/Defs/LinearOrder.lean index added074b73791..be180250724fee 100644 --- a/Mathlib/Order/Defs/LinearOrder.lean +++ b/Mathlib/Order/Defs/LinearOrder.lean @@ -10,7 +10,7 @@ public import Batteries.Tactic.Trans public import Mathlib.Data.Ordering.Basic public import Mathlib.Tactic.ExtendDoc public import Mathlib.Tactic.Push.Attr -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.SplitIfs public import Mathlib.Order.Defs.PartialOrder diff --git a/Mathlib/Order/Notation.lean b/Mathlib/Order/Notation.lean index f63f62501b3d16..a9cc7495f656de 100644 --- a/Mathlib/Order/Notation.lean +++ b/Mathlib/Order/Notation.lean @@ -7,7 +7,7 @@ module public import Qq public meta import Mathlib.Lean.PrettyPrinter.Delaborator -public import Mathlib.Tactic.Simps.NotationClass +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.ToDual public import Lean.PrettyPrinter.Delaborator.Builtins @@ -58,6 +58,9 @@ attribute [deprecated Compl.compl (since := "2026-01-04")] HasCompl.compl @[inherit_doc] postfix:1024 "ᶜ" => compl +initialize_simps_projections Compl +initialize_simps_projections HasCompl + /-! ### `Sup` and `Inf` -/ attribute [ext] Min Max @@ -176,6 +179,8 @@ infixr:60 " ⇨ " => himp /-- Heyting negation -/ prefix:72 "¬" => hnot +initialize_simps_projections HImp +initialize_simps_projections HNot /-- Typeclass for the `⊤` (`\top`) notation -/ @[notation_class, ext] diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 32e81e1659ee12..a4e13e14d0203b 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -311,6 +311,7 @@ public import Mathlib.Tactic.Simproc.ExistsAndEq public import Mathlib.Tactic.Simproc.Factors public import Mathlib.Tactic.Simproc.FinsetInterval public import Mathlib.Tactic.Simproc.VecPerm +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.Simps.Basic public import Mathlib.Tactic.Simps.NotationClass public import Mathlib.Tactic.SplitIfs diff --git a/Mathlib/Tactic/Common.lean b/Mathlib/Tactic/Common.lean index 77101da34d58a4..3664028ba69f27 100644 --- a/Mathlib/Tactic/Common.lean +++ b/Mathlib/Tactic/Common.lean @@ -94,7 +94,7 @@ public import Mathlib.Tactic.Set public import Mathlib.Tactic.SimpIntro public import Mathlib.Tactic.SimpRw public import Mathlib.Tactic.Simproc.ExistsAndEq -public import Mathlib.Tactic.Simps.Basic +public import Mathlib.Tactic.Simps public import Mathlib.Tactic.SplitIfs public import Mathlib.Tactic.Spread public import Mathlib.Tactic.Subsingleton diff --git a/Mathlib/Tactic/ProdAssoc.lean b/Mathlib/Tactic/ProdAssoc.lean index 74c96efa2bceca..fc622839ec2927 100644 --- a/Mathlib/Tactic/ProdAssoc.lean +++ b/Mathlib/Tactic/ProdAssoc.lean @@ -7,7 +7,7 @@ module public meta import Mathlib.Lean.Expr.Basic public import Mathlib.Logic.Equiv.Defs -public meta import Mathlib.Tactic.Simps.Basic +public meta import Mathlib.Tactic.Simps /-! # Associativity of products diff --git a/Mathlib/Tactic/ProxyType.lean b/Mathlib/Tactic/ProxyType.lean index 83491e71d78ce0..6bbb7a3b051263 100644 --- a/Mathlib/Tactic/ProxyType.lean +++ b/Mathlib/Tactic/ProxyType.lean @@ -6,7 +6,7 @@ Authors: Kyle Miller module public import Mathlib.Logic.Equiv.Defs -public meta import Mathlib.Tactic.Simps.Basic +public meta import Mathlib.Tactic.Simps /-! # Generating "proxy types" diff --git a/Mathlib/Tactic/Simps.lean b/Mathlib/Tactic/Simps.lean new file mode 100644 index 00000000000000..df0aba4c434cba --- /dev/null +++ b/Mathlib/Tactic/Simps.lean @@ -0,0 +1,130 @@ +/- +Copyright (c) 2022 Floris van Doorn. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Floris van Doorn +-/ +module + +public import Mathlib.Tactic.Simps.Basic + +/-! +# Simps attribute + +This file initializes notation classes and `simps`-projections for structures defined in the core +library. + +For documentation about `simps`, see `Mathlib.Tactic.Simps.Basic`. +-/ + +attribute [notation_class add] HAdd +attribute [notation_class mul] HMul +attribute [notation_class sub] HSub +attribute [notation_class div] HDiv +attribute [notation_class mod] HMod +attribute [notation_class append] HAppend +attribute [notation_class andThen] HAndThen +attribute [notation_class orElse] HOrElse +attribute [notation_class and] HAnd +attribute [notation_class xor] HXor +attribute [notation_class or] HOr +attribute [notation_class shiftLeft] HShiftLeft +attribute [notation_class shiftRight] HShiftRight +attribute [notation_class] Neg Inv Dvd LE LT HasEquiv HasSubset HasSSubset Union Inter SDiff Insert + Singleton Sep Membership EmptyCollection +attribute [notation_class pow Simps.copyFirst] HPow +attribute [notation_class one Simps.findOneArgs] OfNat +attribute [notation_class zero Simps.findZeroArgs] OfNat +attribute [notation_class smul Simps.copySecond] HSMul +attribute [notation_class nsmul Simps.nsmulArgs] HSMul +attribute [notation_class zsmul Simps.zsmulArgs] HSMul + +initialize_simps_projections BEq +initialize_simps_projections OfNat +initialize_simps_projections LE +initialize_simps_projections LT +initialize_simps_projections Max +initialize_simps_projections Min +initialize_simps_projections Trans +initialize_simps_projections HAdd +initialize_simps_projections HSub +initialize_simps_projections HMul +initialize_simps_projections HDiv +initialize_simps_projections HMod +initialize_simps_projections HPow +initialize_simps_projections HSMul +initialize_simps_projections HAppend +initialize_simps_projections HOrElse +initialize_simps_projections HAndThen +initialize_simps_projections HAnd +initialize_simps_projections HXor +initialize_simps_projections HOr +initialize_simps_projections HShiftLeft +initialize_simps_projections HShiftRight +initialize_simps_projections Zero +initialize_simps_projections One +initialize_simps_projections Add +initialize_simps_projections Sub +initialize_simps_projections Mul +initialize_simps_projections Neg +initialize_simps_projections Div +initialize_simps_projections Inv +initialize_simps_projections Mod +initialize_simps_projections Dvd +initialize_simps_projections Pow +initialize_simps_projections NatPow +initialize_simps_projections SMul +initialize_simps_projections Append +initialize_simps_projections OrElse +initialize_simps_projections AndThen +initialize_simps_projections AndOp +initialize_simps_projections XorOp +initialize_simps_projections OrOp +initialize_simps_projections Complement +initialize_simps_projections ShiftLeft +initialize_simps_projections ShiftRight +initialize_simps_projections Membership +initialize_simps_projections Bind +initialize_simps_projections Pure +initialize_simps_projections Functor +initialize_simps_projections Seq +initialize_simps_projections SeqLeft +initialize_simps_projections SeqRight +initialize_simps_projections Applicative +initialize_simps_projections Monad +initialize_simps_projections MonadLift +initialize_simps_projections MonadLiftT +initialize_simps_projections MonadFunctor +initialize_simps_projections MonadFunctorT +initialize_simps_projections MonadExceptOf +initialize_simps_projections MonadExcept + +initialize_simps_projections Prod +initialize_simps_projections PProd +initialize_simps_projections MProd +initialize_simps_projections Subtype (val → coe) +initialize_simps_projections PLift +initialize_simps_projections ULift +initialize_simps_projections PULift +initialize_simps_projections Fin +initialize_simps_projections BitVec +initialize_simps_projections UInt8 +initialize_simps_projections UInt16 +initialize_simps_projections UInt32 +initialize_simps_projections UInt64 +initialize_simps_projections USize +initialize_simps_projections Char + +initialize_simps_projections HasEquiv +initialize_simps_projections HasSubset +initialize_simps_projections HasSSubset +initialize_simps_projections Union +initialize_simps_projections Inter +initialize_simps_projections SDiff +initialize_simps_projections EmptyCollection +initialize_simps_projections Insert +initialize_simps_projections Singleton +initialize_simps_projections Sep +initialize_simps_projections Setoid + +initialize_simps_projections Sigma +initialize_simps_projections PSigma diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 88d658e5cd3084..b6059d59f72267 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -135,21 +135,6 @@ end Lean.Meta namespace Lean.Parser namespace Attr - -/-! Declare notation classes. -/ -attribute [notation_class add] HAdd -attribute [notation_class mul] HMul -attribute [notation_class sub] HSub -attribute [notation_class div] HDiv -attribute [notation_class mod] HMod -attribute [notation_class append] HAppend -attribute [notation_class pow Simps.copyFirst] HPow -attribute [notation_class andThen] HAndThen -attribute [notation_class] Neg Inv Dvd LE LT HasEquiv HasSubset HasSSubset Union Inter SDiff Insert - Singleton Sep Membership -attribute [notation_class one Simps.findOneArgs] OfNat -attribute [notation_class zero Simps.findZeroArgs] OfNat - /-- `@[simps (attr := attr1, attr2, ...)]` adds additional attributes to all lemmas generated by `simps`. -/ syntax simpsConfigAttrItem := atomic(" (" &"attr" " := ") Parser.Term.attrInstance,* ")" diff --git a/Mathlib/Tactic/Simps/NotationClass.lean b/Mathlib/Tactic/Simps/NotationClass.lean index a9141a5f50f127..ca342ece00fa00 100644 --- a/Mathlib/Tactic/Simps/NotationClass.lean +++ b/Mathlib/Tactic/Simps/NotationClass.lean @@ -15,8 +15,7 @@ public meta import Batteries.Lean.NameMapAttribute This declares the `@[notation_class]` attribute, which is used to give smarter default projections for `@[simps]`. -We put this in a separate file so that we can already tag some declarations with this attribute -in the file where we declare `@[simps]`. For further documentation, see `Tactic.Simps.Basic`. +For further documentation, see `Tactic.Simps.Basic`. -/ public meta section diff --git a/MathlibTest/Simps.lean b/MathlibTest/Simps.lean index e37261b0427cc4..851404520f8ac9 100644 --- a/MathlibTest/Simps.lean +++ b/MathlibTest/Simps.lean @@ -1,5 +1,5 @@ import Mathlib.Algebra.Group.Defs -import Mathlib.Tactic.Simps.Basic +import Mathlib.Tactic.Simps import Mathlib.Lean.Exception import Mathlib.Logic.Equiv.Defs import Mathlib.Data.Prod.Basic @@ -1361,3 +1361,17 @@ set_option pp.explicit true in /-- info: zero_n : @Eq MyNat zero.n MyNat.zero -/ #guard_msgs in #check zero_n + +section SMul +/-! Check that we have initialized `simps` correctly for `smul`/`vadd`. -/ +@[simps] instance smul_bool : SMul Bool Bool where + smul _ b := b + +example (b₁ b₂ : Bool) : b₁ • b₂ = b₂ := by simp + +@[simps] instance vadd_bool : VAdd Bool Bool where + vadd b _ := b + +example (b₁ b₂ : Bool) : b₁ +ᵥ b₂ = b₁ := by simp + +end SMul diff --git a/MathlibTest/TacticCheckInstancesSimps.lean b/MathlibTest/TacticCheckInstancesSimps.lean index 86abf922ba6c11..811874cae1ded2 100644 --- a/MathlibTest/TacticCheckInstancesSimps.lean +++ b/MathlibTest/TacticCheckInstancesSimps.lean @@ -1,4 +1,4 @@ -import Mathlib.Tactic.Simps.Basic +import Mathlib.Tactic.Simps set_option linter.tacticCheckInstances true From c92631ba4b8bf02ff7be7ed128d9dbdebc232d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Serr=C3=A9?= <56162277+gaetanserre@users.noreply.github.com> Date: Mon, 10 Aug 2026 15:36:20 +0000 Subject: [PATCH 1258/1300] feat(Matrix/Order): `OrderClosedTopology` instance for square `RCLike` matrices (#42340) Add an `OrderClosedTopology` instance for square `RCLike` matrices (see [#mathlib4 > `OrderClosedTopology` for Matrix](#narrow/channel/287929-mathlib4/topic/.60OrderClosedTopology.60.20for.20Matrix)). Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- Mathlib/Analysis/Matrix/Order.lean | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mathlib/Analysis/Matrix/Order.lean b/Mathlib/Analysis/Matrix/Order.lean index b6fbcb31433461..a2604911a370e3 100644 --- a/Mathlib/Analysis/Matrix/Order.lean +++ b/Mathlib/Analysis/Matrix/Order.lean @@ -88,6 +88,21 @@ lemma instIsOrderedAddMonoid : IsOrderedAddMonoid (Matrix n n 𝕜) where scoped[MatrixOrder] attribute [instance] Matrix.instIsOrderedAddMonoid +lemma posSemidef_is_closed : IsClosed {A : Matrix n n 𝕜 | A.PosSemidef} := by + rw [show {A | A.PosSemidef} = {A : Matrix n n 𝕜 | A.IsHermitian} ∩ + ⋂ x : n →₀ 𝕜, {A | 0 ≤ x.sum fun i xi ↦ x.sum fun j xj ↦ star xi * A i j * xj} by aesop] + refine IsClosed.inter ?_ ?_ + · exact isClosed_eq (by fun_prop) (by fun_prop) + · refine isClosed_iInter <| fun _ ↦ isClosed_le continuous_const ?_ + simp only [Finsupp.sum] + fun_prop + +lemma instOrderClosedTopology : OrderClosedTopology (Matrix n n 𝕜) where + isClosed_le' := isClosed_le_of_isClosed_nonneg <| by + simpa [nonneg_iff_posSemidef] using posSemidef_is_closed + +scoped[MatrixOrder] attribute [instance] Matrix.instOrderClosedTopology + variable [Fintype n] lemma instNonnegSpectrumClass : NonnegSpectrumClass ℝ (Matrix n n 𝕜) where From bf0fb2bec1edadddcb31d779fedc80ac8754c5ad Mon Sep 17 00:00:00 2001 From: damiano Date: Mon, 10 Aug 2026 16:29:45 +0000 Subject: [PATCH 1259/1300] chore: add missing `to_additive` docstrings in GroupTheory (#41641) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing additive doc-strings (multiplicative side has a hand-written doc-string, additive side did not) across 17 file(s) in **GroupTheory**. The additive doc-strings are simple-minded translations of the multiplicative ones, with referenced lemma names replaced by their `to_additive` counterparts. These gaps were found by an environment linter that pairs each declaration with its `to_additive` counterpart and checks that both or neither is documented. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Mathlib/GroupTheory/Congruence/Hom.lean | 1 + Mathlib/GroupTheory/Coset/Defs.lean | 5 ++++- Mathlib/GroupTheory/CosetCover.lean | 21 +++++++++++++------ Mathlib/GroupTheory/Exponent.lean | 12 ++++++----- .../GroupTheory/FinitelyPresentedGroup.lean | 2 +- Mathlib/GroupTheory/FreeGroup/Basic.lean | 3 ++- .../MonoidLocalization/Lemmas.lean | 3 ++- Mathlib/GroupTheory/Nilpotent.lean | 14 ++++++++----- Mathlib/GroupTheory/NoncommPiCoprod.lean | 4 +++- .../GroupTheory/OreLocalization/Basic.lean | 6 ++++-- .../GroupTheory/OreLocalization/OreSet.lean | 9 +++++--- Mathlib/GroupTheory/Perm/Cycle/Type.lean | 3 ++- Mathlib/GroupTheory/QuotientGroup/Defs.lean | 3 ++- Mathlib/GroupTheory/ResiduallyFinite.lean | 7 +++++-- .../GroupTheory/SpecificGroups/Cyclic.lean | 3 ++- .../GroupTheory/SpecificGroups/KleinFour.lean | 3 ++- Mathlib/GroupTheory/Submonoid/Center.lean | 2 +- 17 files changed, 68 insertions(+), 33 deletions(-) diff --git a/Mathlib/GroupTheory/Congruence/Hom.lean b/Mathlib/GroupTheory/Congruence/Hom.lean index 362c11bc32f728..91967b7850818f 100644 --- a/Mathlib/GroupTheory/Congruence/Hom.lean +++ b/Mathlib/GroupTheory/Congruence/Hom.lean @@ -64,6 +64,7 @@ theorem ker_coeMulHom (f : F) : ker (f : MulHom M N) = ker f := rfl theorem ker_rel (f : F) {x y} : ker f x y ↔ f x = f y := Iff.rfl +/-- The kernel of the quotient map induced by a congruence relation `c` equals `c`. -/ @[to_additive (attr := simp) /-- The kernel of the quotient map induced by an additive congruence relation `c` equals `c`. -/] theorem ker_mkMulHom_eq (c : Con M) : ker (mkMulHom c) = c := diff --git a/Mathlib/GroupTheory/Coset/Defs.lean b/Mathlib/GroupTheory/Coset/Defs.lean index e50fde599d2ed3..08d06c5e363c72 100644 --- a/Mathlib/GroupTheory/Coset/Defs.lean +++ b/Mathlib/GroupTheory/Coset/Defs.lean @@ -209,7 +209,10 @@ variable (s) /-- It can be useful to write `obtain ⟨h, H⟩ := mk_out_eq_mul ...`, and then `rw [H]` or `simp_rw [H]` or `simp only [H]`. In order for `simp_rw` and `simp only` to work, this lemma is stated in terms of an arbitrary `h : s`, rather than the specific `h = g⁻¹ * (mk g).out`. -/ -@[to_additive] +@[to_additive /-- It can be useful to write +`obtain ⟨h, H⟩ := mk_out_eq_add ...`, and then `rw [H]` or `simp_rw [H]` or `simp only [H]`. In +order for `simp_rw` and `simp only` to work, this lemma is stated in terms of an arbitrary `h : s`, +rather than the specific `h = -g + (mk g).out`. -/] theorem mk_out_eq_mul (g : α) : ∃ h : s, (mk g : α ⧸ s).out = g * h := ⟨⟨g⁻¹ * (mk g).out, QuotientGroup.eq.mp (mk g).out_eq'.symm⟩, by rw [mul_inv_cancel_left]⟩ diff --git a/Mathlib/GroupTheory/CosetCover.lean b/Mathlib/GroupTheory/CosetCover.lean index 1edf638d1565fc..72c5b48c85634e 100644 --- a/Mathlib/GroupTheory/CosetCover.lean +++ b/Mathlib/GroupTheory/CosetCover.lean @@ -87,7 +87,8 @@ include hcovers /-- If `H` is a subgroup of `G` and `G` is the union of a finite family of left cosets of `H` then `H` has finite index. -/ -@[to_additive] +@[to_additive /-- If `H` is an additive subgroup of `G` and `G` is the union of a finite family +of left cosets of `H` then `H` has finite index. -/] theorem finiteIndex_of_leftCoset_cover_const : H.FiniteIndex := by simp_rw [leftCoset_cover_const_iff_surjOn] at hcovers have := Set.finite_univ_iff.mp <| Set.Finite.of_surjOn _ hcovers s.finite_toSet @@ -195,7 +196,8 @@ theorem exists_finiteIndex_of_leftCoset_cover_aux [DecidableEq (Subgroup G)] /-- Let the group `G` be the union of finitely many left cosets `g i • H i`. Then at least one subgroup `H i` has finite index in `G`. -/ -@[to_additive] +@[to_additive /-- Let the additive group `G` be the union of finitely many left cosets `g i +ᵥ H i`. +Then at least one additive subgroup `H i` has finite index in `G`. -/] theorem exists_finiteIndex_of_leftCoset_cover : ∃ k ∈ s, (H k).FiniteIndex := by classical have ⟨j, hj⟩ : s.Nonempty := by @@ -308,7 +310,8 @@ theorem leftCoset_cover_filter_FiniteIndex_aux /-- Let the group `G` be the union of finitely many left cosets `g i • H i`. Then the cosets of subgroups of infinite index may be omitted from the covering. -/ -@[to_additive] +@[to_additive /-- Let the additive group `G` be the union of finitely many left cosets `g i +ᵥ H i`. +Then the cosets of additive subgroups of infinite index may be omitted from the covering. -/] theorem leftCoset_cover_filter_FiniteIndex [DecidablePred (FiniteIndex : Subgroup G → Prop)] : ⋃ k ∈ s.filter (fun i => (H i).FiniteIndex), g k • (H k : Set G) = Set.univ := @@ -316,7 +319,9 @@ theorem leftCoset_cover_filter_FiniteIndex /-- Let the group `G` be the union of finitely many left cosets `g i • H i`. Then the sum of the inverses of the indexes of the subgroups `H i` is greater than or equal to 1. -/ -@[to_additive one_le_sum_inv_index_of_leftCoset_cover] +@[to_additive one_le_sum_inv_index_of_leftCoset_cover /-- Let the additive group `G` be the union +of finitely many left cosets `g i +ᵥ H i`. Then the sum of the inverses of the indexes of the +additive subgroups `H i` is greater than or equal to 1. -/] theorem one_le_sum_inv_index_of_leftCoset_cover : 1 ≤ ∑ i ∈ s, ((H i).index : ℚ)⁻¹ := have := Classical.decPred (FiniteIndex : Subgroup G → Prop) @@ -325,7 +330,9 @@ theorem one_le_sum_inv_index_of_leftCoset_cover : /-- Let the group `G` be the union of finitely many left cosets `g i • H i`. If the sum of the inverses of the indexes of the subgroups `H i` is equal to 1, then the cosets of the subgroups of finite index are pairwise disjoint. -/ -@[to_additive] +@[to_additive /-- Let the additive group `G` be the union of finitely many left cosets `g i +ᵥ H i`. +If the sum of the inverses of the indexes of the additive subgroups `H i` is equal to 1, +then the cosets of the additive subgroups of finite index are pairwise disjoint. -/] theorem pairwiseDisjoint_leftCoset_cover_of_sum_inv_index_eq_one [DecidablePred (FiniteIndex : Subgroup G → Prop)] : ∑ i ∈ s, ((H i).index : ℚ)⁻¹ = 1 → @@ -336,7 +343,9 @@ theorem pairwiseDisjoint_leftCoset_cover_of_sum_inv_index_eq_one /-- B. H. Neumann Lemma : If a finite family of cosets of subgroups covers the group, then at least one of these subgroups has index not exceeding the number of cosets. -/ -@[to_additive] +@[to_additive /-- B. H. Neumann Lemma : +If a finite family of cosets of additive subgroups covers the additive group, then at least one +of these additive subgroups has index not exceeding the number of cosets. -/] theorem exists_index_le_card_of_leftCoset_cover : ∃ i ∈ s, (H i).FiniteIndex ∧ (H i).index ≤ s.card := by by_contra! h diff --git a/Mathlib/GroupTheory/Exponent.lean b/Mathlib/GroupTheory/Exponent.lean index f10d903e952b4e..512803052b67bb 100644 --- a/Mathlib/GroupTheory/Exponent.lean +++ b/Mathlib/GroupTheory/Exponent.lean @@ -300,7 +300,8 @@ theorem _root_.Commute.exists_orderOf_eq_lcm {x y : G} (h : Commute x y) : /-- A nontrivial monoid has prime exponent `p` if and only if every non-identity element has order `p`. -/ -@[to_additive] +@[to_additive /-- A nontrivial additive monoid has prime exponent `p` if and only if every +non-identity element has order `p`. -/] lemma exponent_eq_prime_iff {G : Type*} [Monoid G] [Nontrivial G] {p : ℕ} (hp : p.Prime) : Monoid.exponent G = p ↔ ∀ g : G, g ≠ 1 → orderOf g = p := by refine ⟨fun hG g hg ↦ ?_, fun h ↦ dvd_antisymm ?_ ?_⟩ @@ -572,7 +573,8 @@ theorem Monoid.exponent_pi_eq_zero {ι : Type*} {M : ι → Type*} [∀ i, Monoi simpa using congr_fun h j /-- If `f : M₁ →⋆ M₂` is surjective, then the exponent of `M₂` divides the exponent of `M₁`. -/ -@[to_additive] +@[to_additive /-- If `f : M₁ →+ M₂` is surjective, then the exponent of `M₂` divides the exponent of +`M₁`. -/] theorem MonoidHom.exponent_dvd {F M₁ M₂ : Type*} [Monoid M₁] [Monoid M₂] [FunLike F M₁ M₂] [MonoidHomClass F M₁ M₂] {f : F} (hf : Function.Surjective f) : exponent M₂ ∣ exponent M₁ := by @@ -640,7 +642,7 @@ theorem Commute.of_orderOf_dvd_two [IsCancelMul G] (h : ∀ g : G, orderOf g ∣ _ = a * (b * a) * b := by simp [pow_two, mul_assoc] /-- In a cancellative monoid of exponent two, all elements commute. -/ -@[to_additive] +@[to_additive /-- In a cancellative additive monoid of exponent two, all elements commute. -/] lemma mul_comm_of_exponent_two [IsCancelMul G] (hG : Monoid.exponent G = 2) (a b : G) : a * b = b * a := Commute.of_orderOf_dvd_two (fun g => hG ▸ Monoid.order_dvd_exponent g) a b @@ -667,13 +669,13 @@ theorem Group.exponent_quotient_dvd (H : Subgroup G) [H.Normal] : MonoidHom.exponent_dvd (QuotientGroup.mk'_surjective H) /-- In a group of exponent two, every element is its own inverse. -/ -@[to_additive] +@[to_additive /-- In an additive group of exponent two, every element is its own negation. -/] lemma inv_eq_self_of_exponent_two (hG : Monoid.exponent G = 2) (x : G) : x⁻¹ = x := inv_eq_of_mul_eq_one_left <| pow_two (a := x) ▸ hG ▸ Monoid.pow_exponent_eq_one x /-- If an element in a group has order two, then it is its own inverse. -/ -@[to_additive] +@[to_additive /-- If an element in an additive group has order two, then it is its own negation. -/] lemma inv_eq_self_of_orderOf_eq_two {x : G} (hx : orderOf x = 2) : x⁻¹ = x := inv_eq_of_mul_eq_one_left <| pow_two (a := x) ▸ hx ▸ pow_orderOf_eq_one x diff --git a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean index 449ec578624bd0..077cf62d952fce 100644 --- a/Mathlib/GroupTheory/FinitelyPresentedGroup.lean +++ b/Mathlib/GroupTheory/FinitelyPresentedGroup.lean @@ -172,7 +172,7 @@ instance [IsFinitelyPresented G] [IsFinitelyPresented H] : variable (G) /-- Any finite group is finitely presented. -/ -@[to_additive] +@[to_additive /-- Any finite additive group is finitely presented. -/] instance [Finite G] : IsFinitelyPresented G := of_surjective FreeGroup.prod FreeGroup.prod_surjective (.of_FG FreeGroup.prod.ker) diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 54acdc29b3dd21..75e90313f82451 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -730,7 +730,8 @@ theorem closure_eq_range (s : Set β) : Subgroup.closure s = (lift ((↑) : s /-- The generators of `FreeGroup α` generate `FreeGroup α`. That is, the subgroup closure of the set of generators equals `⊤`. -/ -@[to_additive (attr := simp)] +@[to_additive (attr := simp) /-- The generators of `FreeAddGroup α` generate `FreeAddGroup α`. That +is, the additive subgroup closure of the set of generators equals `⊤`. -/] theorem closure_range_of (α) : Subgroup.closure (Set.range (FreeGroup.of : α → FreeGroup α)) = ⊤ := by rw [← range_lift_eq_closure, lift_of_eq_id] diff --git a/Mathlib/GroupTheory/MonoidLocalization/Lemmas.lean b/Mathlib/GroupTheory/MonoidLocalization/Lemmas.lean index 60a4982214b1f4..078168c23e86d0 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Lemmas.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Lemmas.lean @@ -21,7 +21,8 @@ namespace Submonoid.IsLocalizationMap open Finset in /-- See also the analogous `IsLocalization.map_integerMultiple`. -/ -@[to_additive] theorem surj_pi_of_finite {M N F ι : Type*} [Finite ι] +@[to_additive /-- See also the analogous `IsLocalization.map_integerMultiple`. -/] +theorem surj_pi_of_finite {M N F ι : Type*} [Finite ι] [CommMonoid M] [CommMonoid N] [FunLike F M N] [MulHomClass F M N] {f : F} {S : Submonoid M} (hf : IsLocalizationMap S f) (n : ι → N) : ∃ (s : S) (x : ι → M), ∀ i, n i * f s = f (x i) := by diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 2e510e6fa9fc65..4d177f2e6036a3 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -469,7 +469,8 @@ theorem descending_central_series_ge_lower (H : ℕ → Subgroup G) (hH : IsDesc hH.2 x n (descending_central_series_ge_lower H hH n hx) q /-- The lower central series commutes with images under a group homomorphism. -/ -@[to_additive] +@[to_additive +/-- The lower central series commutes with images under an additive group homomorphism. -/] theorem map_lowerCentralSeries {K : Type*} [Group K] (f : G →* K) (n : ℕ) : (S.lowerCentralSeries n).map f = (S.map f).lowerCentralSeries n := by induction n with @@ -479,7 +480,10 @@ theorem map_lowerCentralSeries {K : Type*} [Group K] (f : G →* K) (n : ℕ) : /-- The lower central series of `H : Subgroup G` computed in the ambient group `G` coincides with the lower central series of `H` viewed as its own group, mapped back to `G`. -/ -@[to_additive (attr := simp)] +@[to_additive (attr := simp) +/-- The lower central series of `H : AddSubgroup G` computed in the ambient additive group `G` +coincides with the lower central series of `H` viewed as its own additive group, mapped back +to `G`. -/] theorem top_subtype_lowerCentralSeries (H : Subgroup G) (n : ℕ) : (lowerCentralSeries ⊤ n).map H.subtype = H.lowerCentralSeries n := by rw [map_lowerCentralSeries, ← MonoidHom.range_eq_map, subtype_range] @@ -1052,7 +1056,7 @@ theorem Subgroup.lowerCentralSeries_prod (S₁ : Subgroup G₁) (S₂ : Subgroup | succ n ih => simp_rw [lowerCentralSeries_succ, ih, commutator_prod_prod] /-- The ⊤-specialization of `lowerCentralSeries_prod`. -/ -@[to_additive] +@[to_additive /-- The ⊤-specialization of `lowerCentralSeries_sum`. -/] theorem Subgroup.top_lowerCentralSeries_prod (n : ℕ) : (⊤ : Subgroup (G₁ × G₂)).lowerCentralSeries n = ((⊤ : Subgroup G₁).lowerCentralSeries n).prod ((⊤ : Subgroup G₂).lowerCentralSeries n) := by @@ -1095,7 +1099,7 @@ theorem Subgroup.lowerCentralSeries_pi_le (Ss : ∀ i, Subgroup (Gs i)) (n : ℕ grw [commutator_mono ih le_rfl, commutator_pi_pi_le] /-- The ⊤-specialization of `lowerCentralSeries_pi_le`. -/ -@[to_additive] +@[to_additive /-- The ⊤-specialization of `lowerCentralSeries_pi_le`. -/] theorem Subgroup.top_lowerCentralSeries_pi_le (n : ℕ) : (⊤ : Subgroup (∀ i, Gs i)).lowerCentralSeries n ≤ Subgroup.pi Set.univ fun i => (⊤ : Subgroup (Gs i)).lowerCentralSeries n := by @@ -1128,7 +1132,7 @@ theorem Subgroup.lowerCentralSeries_pi_of_finite [Finite η] (Ss : ∀ i, Subgro | succ n ih => simp_rw [lowerCentralSeries_succ, ih, commutator_pi_pi_of_finite] /-- The ⊤-specialization of `lowerCentralSeries_pi_of_finite`. -/ -@[to_additive] +@[to_additive /-- The ⊤-specialization of `lowerCentralSeries_pi_of_finite`. -/] theorem Subgroup.top_lowerCentralSeries_pi_of_finite [Finite η] (n : ℕ) : (⊤ : Subgroup (∀ i, Gs i)).lowerCentralSeries n = Subgroup.pi Set.univ fun i => (⊤ : Subgroup (Gs i)).lowerCentralSeries n := by diff --git a/Mathlib/GroupTheory/NoncommPiCoprod.lean b/Mathlib/GroupTheory/NoncommPiCoprod.lean index eaefb0041e3b0b..32297327e2f3da 100644 --- a/Mathlib/GroupTheory/NoncommPiCoprod.lean +++ b/Mathlib/GroupTheory/NoncommPiCoprod.lean @@ -189,7 +189,9 @@ set_option backward.isDefEq.respectTransparency false in /-- Given monoid morphisms `φᵢ : Nᵢ → M` and `f : M → P`, if we have sufficient commutativity, then `f ∘ (∐ᵢ φᵢ) = ∐ᵢ (f ∘ φᵢ)` -/ -@[to_additive] +@[to_additive /-- +Given additive monoid morphisms `φᵢ : Nᵢ → M` and `f : M → P`, if we have sufficient commutativity, +then `f ∘ (∐ᵢ φᵢ) = ∐ᵢ (f ∘ φᵢ)` -/] theorem comp_noncommPiCoprod {P : Type*} [Monoid P] {f : M →* P} (hcomm' : Pairwise fun i j => ∀ x y, Commute (f.comp (ϕ i) x) (f.comp (ϕ j) y) := Pairwise.mono hcomm (fun i j ↦ forall_imp (fun x h y ↦ by diff --git a/Mathlib/GroupTheory/OreLocalization/Basic.lean b/Mathlib/GroupTheory/OreLocalization/Basic.lean index 3173e53231d26e..f72ab6180104d7 100644 --- a/Mathlib/GroupTheory/OreLocalization/Basic.lean +++ b/Mathlib/GroupTheory/OreLocalization/Basic.lean @@ -242,7 +242,7 @@ private theorem smul'_char (r₁ : R) (r₂ : X) (s₁ s₂ : S) (u : S) (v : R) set_option backward.privateInPublic true in /-- The multiplication on the Ore localization of monoids. -/ -@[to_additive] +@[to_additive /-- The addition on the Ore localization of additive monoids. -/] private abbrev smul'' (r : R) (s : S) : X[S⁻¹] → X[S⁻¹] := liftExpand (smul' r s) fun r₁ r₂ s' hs => by rcases oreCondition r s' with ⟨r₁', s₁', h₁⟩ @@ -560,7 +560,9 @@ set_option linter.overlappingInstances false in at the same monoid twice. -/ /- Although the definition does not require `IsScalarTower R M X`, it does not make sense without it. -/ -@[to_additive (attr := nolint unusedArguments)] +@[to_additive (attr := nolint unusedArguments) +/-- Warning: This gives a diamond on `VAdd R[S⁻¹] M[S⁻¹][S⁻¹]`, but we will almost never localize +at the same additive monoid twice. -/] instance [IsScalarTower R M X] [IsScalarTower R M M] : SMul R (X[S⁻¹]) where smul := OreLocalization.hsmul diff --git a/Mathlib/GroupTheory/OreLocalization/OreSet.lean b/Mathlib/GroupTheory/OreLocalization/OreSet.lean index 2829f98073cdbc..8e11df20354356 100644 --- a/Mathlib/GroupTheory/OreLocalization/OreSet.lean +++ b/Mathlib/GroupTheory/OreLocalization/OreSet.lean @@ -67,7 +67,9 @@ variable {R : Type*} [Monoid R] {S : Submonoid R} [OreSet S] /-- Common factors on the right can be turned into common factors on the left, a weak form of cancellability. -/ -@[to_additive AddOreLocalization.ore_right_cancel] +@[to_additive AddOreLocalization.ore_right_cancel +/-- Common summands on the right can be turned into common summands on the left, a weak form of +cancellability. -/] theorem ore_right_cancel (r₁ r₂ : R) (s : S) (h : r₁ * s = r₂ * s) : ∃ s' : S, s' * r₁ = s' * r₂ := OreSet.ore_right_cancel r₁ r₂ s h @@ -96,7 +98,7 @@ def oreCondition (r : R) (s : S) : Σ' r' : R, Σ' s' : S, s' * r = r' * s := ⟨oreNum r s, oreDenom r s, ore_eq r s⟩ /-- The trivial submonoid is an Ore set. -/ -@[to_additive AddOreLocalization.addOreSetBot] +@[to_additive AddOreLocalization.addOreSetBot /-- The trivial submonoid is an Ore set. -/] instance oreSetBot : OreSet (⊥ : Submonoid R) where ore_right_cancel _ _ s h := ⟨s, by @@ -114,7 +116,8 @@ instance oreSetBot : OreSet (⊥ : Submonoid R) where simp [hs] /-- Every submonoid of a commutative monoid is an Ore set. -/ -@[to_additive AddOreLocalization.addOreSetComm] +@[to_additive AddOreLocalization.addOreSetComm +/-- Every submonoid of an additive commutative monoid is an Ore set. -/] instance (priority := 100) oreSetComm {R} [CommMonoid R] (S : Submonoid R) : OreSet S where ore_right_cancel m n s h := ⟨s, by rw [mul_comm (s : R) n, mul_comm (s : R) m, h]⟩ oreNum r _ := r diff --git a/Mathlib/GroupTheory/Perm/Cycle/Type.lean b/Mathlib/GroupTheory/Perm/Cycle/Type.lean index bceb5e928f1b22..9dfc4debbd6acc 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Type.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Type.lean @@ -540,7 +540,8 @@ attribute [to_additive existing] exists_prime_orderOf_dvd_card -- TODO: Make the `Finite` version of this theorem the default /-- For every prime `p` dividing the order of a finite group `G` there exists an element of order `p` in `G`. This is known as Cauchy's theorem. -/ -@[to_additive] +@[to_additive /-- For every prime `p` dividing the order of a finite additive group `G` there exists +an element of order `p` in `G`. This is the additive version of Cauchy's theorem. -/] theorem _root_.exists_prime_orderOf_dvd_card' {G : Type*} [Group G] [Finite G] (p : ℕ) [hp : Fact p.Prime] (hdvd : p ∣ Nat.card G) : ∃ x : G, orderOf x = p := by have := Fintype.ofFinite G diff --git a/Mathlib/GroupTheory/QuotientGroup/Defs.lean b/Mathlib/GroupTheory/QuotientGroup/Defs.lean index dcec9bc41d43c6..1754237fcc3b4a 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Defs.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Defs.lean @@ -127,7 +127,8 @@ lemma mk'_comp_subtype : (mk' N).comp N.subtype = 1 := by ext; simp set_option linter.docPrime false in /-- Note: `range_mk'` is a lemma about the primed constructor `QuotientGroup.mk'`, not a modified version of some `range_mk`. -/ -@[to_additive (attr := simp)] +@[to_additive (attr := simp) /-- Note: `range_mk'` is a lemma about the primed constructor + `QuotientAddGroup.mk'`, not a modified version of some `range_mk`. -/] theorem range_mk' : (QuotientGroup.mk' N).range = ⊤ := MonoidHom.range_eq_top.mpr (mk'_surjective N) diff --git a/Mathlib/GroupTheory/ResiduallyFinite.lean b/Mathlib/GroupTheory/ResiduallyFinite.lean index 343b0bea5d8758..30b1b5027c3f6c 100644 --- a/Mathlib/GroupTheory/ResiduallyFinite.lean +++ b/Mathlib/GroupTheory/ResiduallyFinite.lean @@ -78,7 +78,9 @@ theorem residuallyFinite_iff_exists_finiteIndex : /-- If `G` is residually finite, for every pair of distinct elements `g`, `h` there exists a finite index normal subgroup `H` such that `g` and `h` differ in the quotient `G ⧸ H`. -/ -@[to_additive] +@[to_additive /-- If `G` is residually finite, for every pair of distinct elements `g`, `h` there +exists a finite index normal additive subgroup `H` such that `g` and `h` differ in the quotient +`G ⧸ H`. -/] theorem exists_finiteIndexNormalSubgroup_of_residuallyFinite [ResiduallyFinite G] (g h : G) (hgh : g ≠ h) : ∃ H : FiniteIndexNormalSubgroup G, (g : G ⧸ H.toSubgroup) ≠ ↑h := by obtain ⟨H, hH⟩ := @@ -87,7 +89,8 @@ theorem exists_finiteIndexNormalSubgroup_of_residuallyFinite [ResiduallyFinite G /-- `G` is residually finite if for every element `g` not equal to `1` there exists a group homomorphism `f` to a finite group `H` such that `f g ≠ 1`. -/ -@[to_additive] +@[to_additive /-- `G` is residually finite if for every element `g` not equal to `0` there exists an +additive group homomorphism `f` to a finite additive group `H` such that `f g ≠ 0`. -/] theorem residuallyFinite_of_forall_exists_finite_monoidHom.{u} (h : ∀ g : G, g ≠ 1 → ∃ (H : Type u) (_ : Group H) (_ : Finite H) (f : G →* H), f g ≠ 1) : ResiduallyFinite G := by diff --git a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean index 866caf78318751..3f9ae0e2a5e54c 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Cyclic.lean @@ -351,7 +351,8 @@ protected theorem ZMod.exponent (n : ℕ) : AddMonoid.exponent (ZMod n) = n := b rw [IsAddCyclic.exponent_eq_card, Nat.card_zmod] /-- A group of order `p ^ 2` is not cyclic if and only if its exponent is `p`. -/ -@[to_additive] +@[to_additive /-- An additive group of order `p ^ 2` is not cyclic if and only if its exponent is +`p`. -/] lemma not_isCyclic_iff_exponent_eq_prime [Group α] {p : ℕ} (hp : p.Prime) (hα : Nat.card α = p ^ 2) : ¬ IsCyclic α ↔ Monoid.exponent α = p := by -- G is a nontrivial fintype of cardinality `p ^ 2` diff --git a/Mathlib/GroupTheory/SpecificGroups/KleinFour.lean b/Mathlib/GroupTheory/SpecificGroups/KleinFour.lean index b49edd0e7e4d85..99548037819cd6 100644 --- a/Mathlib/GroupTheory/SpecificGroups/KleinFour.lean +++ b/Mathlib/GroupTheory/SpecificGroups/KleinFour.lean @@ -80,7 +80,8 @@ theorem isMulCommutative {G : Type*} [Group G] [IsKleinFour G] : /-- This instance is scoped, because it always applies (which makes linting and typeclass inference potentially *a lot* slower). -/ -@[to_additive] +@[to_additive /-- This instance is scoped, because it always applies (which makes linting and +typeclass inference potentially *a lot* slower). -/] scoped instance instFinite {G : Type*} [Group G] [IsKleinFour G] : Finite G := Nat.finite_of_card_ne_zero <| by simp [IsKleinFour.card_four] diff --git a/Mathlib/GroupTheory/Submonoid/Center.lean b/Mathlib/GroupTheory/Submonoid/Center.lean index 92dbe17ae4318e..5d75f8f5ad9e0f 100644 --- a/Mathlib/GroupTheory/Submonoid/Center.lean +++ b/Mathlib/GroupTheory/Submonoid/Center.lean @@ -86,7 +86,7 @@ section Monoid variable {M} [Monoid M] /-- The center of a monoid is commutative. -/ -@[to_additive] +@[to_additive /-- The center of an additive monoid is additively commutative. -/] instance center.commMonoid : CommMonoid (center M) := { (center M).toMonoid, Subsemigroup.center.commSemigroup with } From 42e9cfadd9bfddbef816efd72513be70100ccd80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Mon, 10 Aug 2026 16:29:48 +0000 Subject: [PATCH 1260/1300] feat(AlgebraicTopology): order relation between simplices of the nerve of a partial order (#41656) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is applied to the characterization of the order relation between simplices of `Δ[p] ⊗ Δ[q]`. --- .../SimplicialSet/NerveNondegenerate.lean | 31 +++++++++++++++++-- .../SimplicialSet/ProdStdSimplex.lean | 18 +++++++++++ .../SimplicialSet/Subcomplex.lean | 17 ++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean index 9d5146b0968cd7..e77ed3f6c39c54 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NerveNondegenerate.lean @@ -21,11 +21,11 @@ public section universe u -open CategoryTheory Simplicial +open CategoryTheory Simplicial SSet namespace PartialOrder -variable {X : Type*} [PartialOrder X] {n : ℕ} +variable {X : Type*} [PartialOrder X] {n m : ℕ} set_option backward.isDefEq.respectTransparency.types false in lemma mem_range_nerve_σ_iff (s : (nerve X) _⦋n + 1⦌) (i : Fin (n + 1)) : @@ -73,4 +73,31 @@ lemma mem_nerve_nonDegenerate_iff_injective (s : (nerve X) _⦋n⦌) : · exact h' · exact ((h h').not_lt hij).elim +lemma nerve_ofSimplex_le_ofSimplex_iff + (s : (nerve X) _⦋n⦌) (t : (nerve X) _⦋m⦌) : + Subcomplex.ofSimplex s ≤ Subcomplex.ofSimplex t ↔ + Set.range s.obj ⊆ Set.range t.obj := by + refine ⟨?_, ?_⟩ + · rintro hst _ ⟨i, rfl⟩ + rw [Subcomplex.ofSimplex_le_iff] at hst + obtain ⟨⟨f⟩, rfl⟩ := hst + exact ⟨_, rfl⟩ + · wlog ht : t ∈ (nerve X).nonDegenerate m generalizing m t + · intro hst + obtain ⟨m', f, _, ⟨t', h₁⟩, rfl⟩ := exists_nonDegenerate _ t + rw [Subcomplex.ofSimplex_map_of_epi] + refine this _ h₁ ?_ + rintro _ ⟨i, rfl⟩ + obtain ⟨j, hj⟩ := hst (Set.mem_range_self i) + aesop + rw [mem_nerve_nonDegenerate_iff_strictMono] at ht + intro hst + rw [Subcomplex.ofSimplex_le_iff] + have (i : Fin (n + 1)) : ∃ (j : Fin (m + 1)), t.obj j = s.obj i := by aesop + choose f hf using this + have hf' : Monotone f := fun i₁ i₂ hi ↦ by + rw [← ht.le_iff_le, hf, hf] + exact s.monotone hi + exact ⟨Quiver.Hom.op (SimplexCategory.Hom.mk ⟨f, hf'⟩), by aesop⟩ + end PartialOrder diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean index 5d4e6ee08bba79..26e30e03604122 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/ProdStdSimplex.lean @@ -92,6 +92,24 @@ lemma nonDegenerate_iff_strictMono_objEquiv {n : ℕ} (z : (Δ[p] ⊗ Δ[q] : SS PartialOrder.mem_nerve_nonDegenerate_iff_strictMono] rfl +lemma isoNerve_hom_app_obj {n : ℕ} (x : (Δ[p] ⊗ Δ[q] : SSet.{u}) _⦋n⦌) : + ((isoNerve p q).hom.app _ x).obj = ULift.up ∘ objEquiv x := rfl + +lemma range_isoNerve_hom_app_obj {n : ℕ} (x : (Δ[p] ⊗ Δ[q] : SSet.{u}) _⦋n⦌) : + Set.range ((isoNerve p q).hom.app _ x).obj = ULift.down ⁻¹' Set.range (objEquiv x) := by + rw [isoNerve_hom_app_obj] + refine (Equiv.ulift.eq_preimage_iff_image_eq ..).2 ?_ + simp [Set.range_comp, ← Set.image_comp] + +lemma ofSimplex_le_ofSimplex_iff + {n m : ℕ} (s : (Δ[p] ⊗ Δ[q] : SSet.{u}) _⦋n⦌) (t : (Δ[p] ⊗ Δ[q] : SSet.{u}) _⦋m⦌) : + Subcomplex.ofSimplex s ≤ Subcomplex.ofSimplex t ↔ + Set.range (objEquiv s) ⊆ Set.range (objEquiv t) := by + simp only [← Subcomplex.image_le_image_iff (isoNerve p q).hom, + Subcomplex.image_ofSimplex, PartialOrder.nerve_ofSimplex_le_ofSimplex_iff, + range_isoNerve_hom_app_obj] + exact ⟨Set.preimage_mono (f := ULift.up), Set.preimage_mono⟩ + /-- Given a `n`-simplex `x` in `Δ[p] ⊗ Δ[q]`, this is the order preserving map `Fin (n + 1) →o Fin (m + 1)` (with `p + q = m`) which corresponds to the sum of the two components of `objEquiv x : Fin (n + 1) →o Fin (p + 1) × Fin (q + 1)`. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean index a7eb9ac446a547..b46fd394c5de36 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean @@ -262,6 +262,9 @@ set_option backward.isDefEq.respectTransparency false in @[simp] lemma preimage_ι (A : X.Subcomplex) : A.preimage A.ι = ⊤ := by aesop +lemma preimage_monotone (f : Y ⟶ X) : Monotone (fun (S : X.Subcomplex) ↦ S.preimage f) := + fun _ _ h _ _ hx ↦ h _ hx + end section @@ -342,6 +345,20 @@ lemma image_preimage_le (B : X.Subcomplex) (f : Y ⟶ X) : (B.preimage f).image f ≤ B := by rw [image_le_iff] +@[simp] +lemma preimage_image (S : X.Subcomplex) (f : X ⟶ Y) [Mono f] : + (S.image f).preimage f = S := by + refine le_antisymm ?_ (by rw [← image_le_iff]) + intro n x ⟨y, hy, h⟩ + rwa [← injective_of_mono (f.app n) h] + +@[simp] +lemma image_le_image_iff (f : X ⟶ Y) [Mono f] {S₁ S₂ : X.Subcomplex} : + S₁.image f ≤ S₂.image f ↔ S₁ ≤ S₂ := by + refine ⟨fun h ↦ ?_, fun h ↦ image_monotone f h⟩ + rw [← S₁.preimage_image f, ← S₂.preimage_image f] + exact preimage_monotone f h + @[simp] lemma preimage_image_of_isIso (f : X ⟶ Y) (B : Y.Subcomplex) [IsIso f] : (B.preimage f).image f = B := by From fc1ac65c1edb75868a979b4cd67b2939191bbef5 Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Mon, 10 Aug 2026 16:29:50 +0000 Subject: [PATCH 1261/1300] feat: a base for the root system of a Lie algebra can be promoted to a basis (#42500) --- Mathlib/Algebra/Lie/Basis/Base.lean | 142 +++++++++++++++++++- Mathlib/Algebra/Lie/Subalgebra.lean | 4 + Mathlib/Algebra/Lie/Weights/Killing.lean | 23 ++++ Mathlib/Algebra/Lie/Weights/RootSystem.lean | 35 +++++ Mathlib/Algebra/Module/LinearMap/Defs.lean | 2 + 5 files changed, 201 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Lie/Basis/Base.lean b/Mathlib/Algebra/Lie/Basis/Base.lean index 7960cb04f2ec11..38ddb8e84e4789 100644 --- a/Mathlib/Algebra/Lie/Basis/Base.lean +++ b/Mathlib/Algebra/Lie/Basis/Base.lean @@ -5,7 +5,7 @@ Authors: Oliver Nash -/ module -public import Mathlib.Algebra.Lie.Basis.Basic +public import Mathlib.Algebra.Lie.Basis.Prod public import Mathlib.Algebra.Lie.Weights.RootSystem public import Mathlib.LinearAlgebra.RootSystem.BaseExists public import Mathlib.LinearAlgebra.RootSystem.CartanMatrix @@ -20,12 +20,17 @@ public import Mathlib.LinearAlgebra.RootSystem.CartanMatrix noncomputable section -namespace LieAlgebra.Basis +namespace LieAlgebra open AddSubmonoid Function IsKilling LieModule LieSubalgebra Matrix Set -variable {ι K L : Type*} [Fintype ι] [Field K] [CharZero K] [LieRing L] [LieAlgebra K L] - [FiniteDimensional K L] {H : LieSubalgebra K L} (b : Basis ι H) +variable {K L : Type*} [Field K] [CharZero K] + [LieRing L] [LieAlgebra K L] [FiniteDimensional K L] + {H : LieSubalgebra K L} + +namespace Basis + +variable {ι : Type*} [Fintype ι] (b : Basis ι H) /-- The elements `LieAlgebra.Basis.baseSupp` as roots in the sense of `LieSubalgebra.root`. -/ def baseSupp' (i : ι) : @@ -121,4 +126,131 @@ lemma cartanMatrix_base_eq : rw [reindex_apply, submatrix_apply, RootPairing.Base.algebraMap_cartanMatrixIn_apply] simp [← Weight.coe_coe] -end LieAlgebra.Basis +end Basis + +variable [H.IsCartanSubalgebra] [IsTriangularizable K H L] + +private lemma cartan_eq_lieSpan [IsKilling K L] (b : (rootSystem H).Base) : + H = lieSpan K L (range fun i : b.support ↦ (rootSystem H).coroot i) := by + suffices lieSpan K H (range fun i : b.support ↦ (rootSystem H).coroot i) = ⊤ by + refine le_antisymm ?_ ?_ + · rwa [← H.comap_lieSpan_range_eq, comap_incl_eq_top] at this + · simp_rw [lieSpan_le, Set.range_subset_iff, Subtype.coe_prop, implies_true] + simp_rw [← RootPairing.Base.toCoweightBasis_apply, ← LieSubalgebra.toSubmodule_inj, + top_toSubmodule, eq_top_iff, ← b.toCoweightBasis.span_eq] + exact submodule_span_le_lieSpan + +private lemma exists_mem_rootSpace_lie_ne_zero' [IsKilling K L] + {α β : Weight K H L} (hα : α.IsNonZero) (h_ne_bot : rootSpace H (α + β) ≠ ⊥) + {a : L} (ha : a ∈ rootSpace H α) (ha₀ : a ≠ 0) : + ∃ b ∈ rootSpace H β, ⁅a, b⁆ ≠ 0 := by + obtain ⟨a', ha', b, hb, hab⟩ := exists_mem_rootSpace_lie_ne_zero hα h_ne_bot + obtain ⟨t, rfl⟩ : ∃ t : K, t • a = a' := + Submodule.mem_span_singleton.mp <| by rwa [← toSubmodule_rootSpace_eq_span α hα a ha₀ ha] + exact ⟨b, hb, by contrapose! hab; simp [hab]⟩ + +lemma lieSpan_range_union_eq_top_of_mem_rootSpace [IsKilling K L] (b : (rootSystem H).Base) + (e f : b.support → L) + (ef_sl2 : ∀ α : b.support, IsSl2Triple ((rootSystem H).coroot α : L) (e α) (f α)) + (e_mem : ∀ α : b.support, e α ∈ rootSpace H α) + (f_mem : ∀ α : b.support, f α ∈ rootSpace H (-↑α)) : + lieSpan K L (range e ∪ range f) = ⊤ := by + set S := lieSpan K L (range e ∪ range f) with S_def + have e_mem_S (i : b.support) : e i ∈ S := subset_lieSpan (mem_union_left _ ⟨i, rfl⟩) + have f_mem_S (i : b.support) : f i ∈ S := subset_lieSpan (mem_union_right _ ⟨i, rfl⟩) + suffices ∀ α : H.root, rootSpace H α ≤ S.toSubmodule by + replace this (α : Weight K H L) (hα : α.IsNonZero) : rootSpace H α ≤ S.toSubmodule := + this ⟨α, by simpa⟩ + rw [eq_top_iff, ← toSubmodule_le_toSubmodule, top_toSubmodule, + ← LieSubmodule.top_toSubmodule (L := H), ← cartan_sup_iSup_rootSpace_eq_top H] + have H_le : H ≤ S := by + nth_rw 1 [cartan_eq_lieSpan b, lieSpan_le] + rintro - ⟨i, rfl⟩ + simpa only [← (ef_sl2 i).lie_e_f, SetLike.mem_coe] using lie_mem _ (e_mem_S i) (f_mem_S i) + simpa [H_le] + suffices h : ∀ α : H.root, + rootSpace H α ≤ S.toSubmodule ∧ rootSpace H (-α : Weight K H L) ≤ S.toSubmodule by grind + refine fun α ↦ b.induction_add (p := fun α ↦ + rootSpace H α ≤ S.toSubmodule ∧ rootSpace H (-α : Weight K H L) ≤ S.toSubmodule) α ?_ ?_ ?_ + · rintro β hβ + simpa [rootSystem_reflectionPerm_self_eq_neg] using hβ.symm + · rintro β hβ + set β' : b.support := ⟨β, hβ⟩ + have hβp : β.val.IsNonZero := H.isNonZero_coe_root β + have hβn : (-β.val).IsNonZero := by simpa [Weight.isNonZero_neg] using H.isNonZero_coe_root β + simpa only [Weight.coe_coe, + toSubmodule_rootSpace_eq_span _ hβp (e β') (ef_sl2 β').e_ne_zero (e_mem β'), + toSubmodule_rootSpace_eq_span _ hβn (f β') (ef_sl2 β').f_ne_zero (f_mem β'), + Submodule.span_singleton_le_iff_mem, mem_toSubmodule] using ⟨e_mem_S β', f_mem_S β'⟩ + · rintro i j k hk ⟨hip, hin⟩ hj + constructor + · have h_ne_bot : rootSpace H ((rootSystem H).root j + (rootSystem H).root i) ≠ ⊥ := by + convert (k : Weight K H L).genWeightSpace_ne_bot + rw [← LinearMap.coe_add, add_comm, ← hk, rootSystem_root_apply, Weight.coe_coe] + obtain ⟨x, hx, hlie⟩ := exists_mem_rootSpace_lie_ne_zero' + (H.isNonZero_coe_root j) h_ne_bot (e_mem ⟨j, hj⟩) (ef_sl2 ⟨j, hj⟩).e_ne_zero + have hmem : ⁅e ⟨j, hj⟩, x⁆ ∈ rootSpace H ((rootSystem H).root k) := by + rw [hk, add_comm] + exact mapsTo_toEnd_genWeightSpace_add_of_mem_rootSpace K L H L _ _ (e_mem ⟨j, hj⟩) hx + simpa [toSubmodule_rootSpace_eq_span _ (H.isNonZero_coe_root k) _ hlie hmem] using + lie_mem S (e_mem_S ⟨j, hj⟩) (hip hx) + · replace hk : ⇑k.val = ⇑i.val + ⇑j.val := by ext x; simpa using DFunLike.congr_fun hk x + replace hk : (⇑(-i).val + ⇑(-j).val) = ⇑(-k).val := by simp [hk, -neg_add_rev, neg_add] + have h_ne_bot : rootSpace H (⇑(-j).val + ⇑(-i).val) ≠ ⊥ := by + rw [add_comm, hk]; exact (-k).val.genWeightSpace_ne_bot + obtain ⟨x, hx, hlie⟩ := exists_mem_rootSpace_lie_ne_zero' + (H.isNonZero_coe_root (-j)) h_ne_bot (f_mem ⟨j, hj⟩) (ef_sl2 ⟨j, hj⟩).f_ne_zero + have hmem : ⁅f ⟨j, hj⟩, x⁆ ∈ rootSpace H ⇑(-k).val := by + rw [← hk, add_comm] + exact mapsTo_toEnd_genWeightSpace_add_of_mem_rootSpace K L H L _ _ (f_mem ⟨j, hj⟩) hx + simpa [toSubmodule_rootSpace_eq_span _ (H.isNonZero_coe_root (-k)) _ hlie hmem, + ← val_neg_root] using lie_mem S (f_mem_S ⟨j, hj⟩) (hin hx) + +open RootPairing in +lemma exists_basis_of_base [IsKilling K L] (b : (rootSystem H).Base) : + ∃ B : Basis b.support H, B.A = b.cartanMatrix ∧ (∀ i, B.h i = (rootSystem H).coroot i) := by + have nonZero (α : b.support) : (α : Weight K H L).IsNonZero := by + obtain ⟨⟨α, hα⟩, -⟩ := α + simpa using hα + choose h e f ef_sl2 e_mem f_mem using fun α ↦ exists_isSl2Triple_of_weight_isNonZero (nonZero α) + have h_coroot (i : b.support) : h i = (rootSystem H).coroot i := + (ef_sl2 i).h_eq_coroot (nonZero i) (e_mem i) (f_mem i) + simp_rw [h_coroot] at ef_sl2 + let B : Basis b.support H := + { A := b.cartanMatrix + h i := (rootSystem H).coroot i + e i := e i + f i := f i + cartan_eq_lieSpan := cartan_eq_lieSpan b + linInd := b.linearIndepOn_coroot.map_injOn H.incl.toLinearMap <| by simp + nondegen := b.cartanMatrix_nondegenerate + sl2 i := ef_sl2 i + lie_h_h := by simp [← coe_bracket, trivial_lie_zero] + span_ef := lieSpan_range_union_eq_top_of_mem_rootSpace b e f ef_sl2 e_mem f_mem + lie_h_e i j := by + have : (b.cartanMatrix i j : K) = algebraMap ℤ K (b.cartanMatrix i j) := by simp + rw [← LieSubalgebra.coe_bracket_of_module, lie_eq_smul_of_mem_rootSpace (e_mem i), + ← Int.cast_smul_eq_zsmul K, this, Base.cartanMatrix, Base.cartanMatrixIn_def, + algebraMap_pairingIn, rootSystem_coroot_apply, rootSystem_pairing_apply] + lie_h_f i j := by + have : (b.cartanMatrix i j : K) = algebraMap ℤ K (b.cartanMatrix i j) := by simp + rw [neg_smul, ← LieSubalgebra.coe_bracket_of_module, lie_eq_smul_of_mem_rootSpace (f_mem i), + ← Int.cast_smul_eq_zsmul K, this, Base.cartanMatrix, Base.cartanMatrixIn_def, + algebraMap_pairingIn, rootSystem_coroot_apply, rootSystem_pairing_apply, Pi.neg_apply, + neg_smul] + lie_e_f_ne i j hij := by + set χ : H → K := ⇑i.val.val - ⇑j.val.val with hχ + suffices rootSpace H χ = ⊥ by + have aux : ⁅e i, f j⁆ ∈ rootSpace H χ := by + rw [hχ, sub_eq_add_neg] + exact mapsTo_toEnd_genWeightSpace_add_of_mem_rootSpace K L H L _ _ (e_mem i) (f_mem j) + simpa [this] using aux + replace hij : χ ≠ 0 := by contrapose hij; rw [hχ, sub_eq_zero] at hij; aesop + have := b.sub_notMem_range_root i.property j.property + simp only [rootSystem_root_apply, mem_range, Subtype.exists, Finset.mem_filter, + Finset.mem_univ, true_and, exists_prop, not_exists, not_and, ne_eq] at this + contrapose! this + exact ⟨⟨χ, this⟩, hij, LinearMap.ext fun x ↦ by simp [hχ]⟩ } + exact ⟨B, rfl, by simp [B]⟩ + +end LieAlgebra diff --git a/Mathlib/Algebra/Lie/Subalgebra.lean b/Mathlib/Algebra/Lie/Subalgebra.lean index 08df1c027dd3e2..34578613e48572 100644 --- a/Mathlib/Algebra/Lie/Subalgebra.lean +++ b/Mathlib/Algebra/Lie/Subalgebra.lean @@ -774,6 +774,10 @@ lemma comap_lieSpan_range_eq {ι : Type*} (f : ι → K) : simp only [SetLike.mem_coe, mem_comap, coe_incl] exact subset_lieSpan <| by simp +@[simp] theorem comap_incl_eq_top : K'.comap K.incl = ⊤ ↔ K ≤ K' := by + simp only [SetLike.ext_iff, mem_comap, coe_incl, mem_top, iff_true, le_def, Set.subset_def, + SetLike.mem_coe, Subtype.forall] + end LieSpan end LieSubalgebra diff --git a/Mathlib/Algebra/Lie/Weights/Killing.lean b/Mathlib/Algebra/Lie/Weights/Killing.lean index 5913e4f432d863..e791bdea83445f 100644 --- a/Mathlib/Algebra/Lie/Weights/Killing.lean +++ b/Mathlib/Algebra/Lie/Weights/Killing.lean @@ -629,6 +629,19 @@ lemma finrank_rootSpace_eq_one (α : Weight K H L) (hα : α.IsNonZero) : obtain ⟨n, hn⟩ := P.exists_nat assumption_mod_cast +lemma toSubmodule_rootSpace_eq_span (α : Weight K H L) (hα : α.IsNonZero) (x : L) + (hx₀ : x ≠ 0) (hx : x ∈ rootSpace H α) : + (rootSpace H α).toSubmodule = K ∙ x := by + have := (finrank_eq_one_iff_of_nonzero' ⟨x, hx⟩ (by simpa)).mp (finrank_rootSpace_eq_one α hα) + ext y + rw [Submodule.mem_span_singleton] + refine ⟨fun hy ↦ ?_, ?_⟩ + · obtain ⟨t, ht⟩ := this ⟨y, hy⟩ + use t + aesop + · rintro ⟨t, rfl⟩ + exact SMulMemClass.smul_mem t hx + /-- The embedded `sl₂` associated to a root. -/ noncomputable def sl2SubalgebraOfRoot {α : Weight K H L} (hα : α.IsNonZero) : LieSubalgebra K L := by @@ -734,6 +747,16 @@ lemma sl2SubmoduleOfRoot_ne_bot (α : Weight K H L) (hα : α.IsNonZero) : /-- The collection of roots as a `Finset`. -/ noncomputable abbrev _root_.LieSubalgebra.root : Finset (Weight K H L) := {α | α.IsNonZero} +instance : InvolutiveNeg H.root where + neg i := ⟨-i, by aesop⟩ + neg_neg i := by aesop + +omit [CharZero K] in +lemma neg_root_eq {i : H.root} : -i = ⟨-i, by aesop⟩ := rfl + +omit [CharZero K] in +@[simp] lemma val_neg_root {i : H.root} : (-i).val = -i.val := rfl + omit [IsKilling K L] [IsTriangularizable K H L] [CharZero K] in @[simp] lemma _root_.LieSubalgebra.isNonZero_coe_root (α : H.root) : (α : Weight K H L).IsNonZero := by diff --git a/Mathlib/Algebra/Lie/Weights/RootSystem.lean b/Mathlib/Algebra/Lie/Weights/RootSystem.lean index 7f6c53376e8164..0605916ff57771 100644 --- a/Mathlib/Algebra/Lie/Weights/RootSystem.lean +++ b/Mathlib/Algebra/Lie/Weights/RootSystem.lean @@ -229,6 +229,33 @@ lemma rootSpace_zsmul_add_ne_bot_iff_mem (hα : α.IsNonZero) (n : ℤ) : rootSpace H (n • α + β) ≠ ⊥ ↔ n ∈ Finset.Icc (-chainBotCoeff α β : ℤ) (chainTopCoeff α β) := by rw [rootSpace_zsmul_add_ne_bot_iff α β hα n, Finset.mem_Icc, and_comm, neg_le] +lemma exists_mem_rootSpace_lie_ne_zero + {α β : Weight K H L} (hα : α.IsNonZero) (h_ne_bot : rootSpace H (α + β) ≠ ⊥) : + ∃ a ∈ rootSpace H α, ∃ b ∈ rootSpace H β, ⁅a, b⁆ ≠ 0 := by + obtain ⟨_, e, f, ef_sl2, he, hf⟩ := exists_isSl2Triple_of_weight_isNonZero hα + obtain rfl := ef_sl2.h_eq_coroot hα he hf + obtain ⟨x, hx, hx₀⟩ := (chainTop α β).exists_ne_zero + refine ⟨e, he, (toEnd K L L f ^ chainTopCoeff α β) x, ?_, ?_⟩ + · have : chainTopCoeff α β • (-⇑α) + chainTop α β = β := by rw [coe_chainTop', smul_neg]; abel + rw [← this] + exact toEnd_pow_apply_mem hf hx (chainTopCoeff α β) + · have hq₀ : 0 < chainTopCoeff α β := by + have := (rootSpace_zsmul_add_ne_bot_iff α β hα 1).mp <| by rwa [one_smul] + exact_mod_cast this.1 + obtain ⟨n, hn⟩ : ∃ n, chainTopCoeff α β = n + 1 := ⟨chainTopCoeff α β - 1, by lia⟩ + have h_prim : ef_sl2.HasPrimitiveVectorWith x (chainLength α β : K) := + { ne_zero := hx₀ + lie_h := (chainLength_smul α β hx).symm + lie_e := by + have hmem := lie_mem_genWeightSpace_of_mem_genWeightSpace he hx + rwa [genWeightSpace_add_chainTop α β hα] at hmem } + rw [hn, h_prim.lie_e_pow_succ_toEnd_f n] + have : chainTopCoeff α β ≤ chainLength α β := chainTopCoeff_le_chainLength α β + refine smul_ne_zero (mul_ne_zero (by exact_mod_cast n.succ_ne_zero) ?_) + (h_prim.pow_toEnd_f_ne_zero_of_eq_nat rfl (by lia)) + rw [sub_ne_zero, Nat.cast_injective.ne_iff] + lia + lemma chainTopCoeff_of_eq_zsmul_add (hα : α.IsNonZero) (β' : Weight K H L) (n : ℤ) (hβ' : (β' : H → K) = n • α + β) : chainTopCoeff α β' = chainTopCoeff α β - n := by @@ -449,4 +476,12 @@ instance : (rootSystem H).IsReduced where · right; ext x; simpa [neg_eq_iff_eq_neg] using DFunLike.congr_fun h.symm x · left; ext x; simpa using DFunLike.congr_fun h.symm x +variable {H} + +lemma rootSystem_reflectionPerm_self_eq_neg (i : H.root) : + (rootSystem H).reflectionPerm i i = - i := by + apply (rootSystem H).root.injective + rw [RootPairing.root_reflectionPerm, RootPairing.reflection_apply_self] + simp + end LieAlgebra.IsKilling diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index a56f661b2103e5..7d1b21d447da75 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -831,6 +831,8 @@ instance : Add (M →ₛₗ[σ₁₂] M₂) := map_add' := by simp [add_comm, add_left_comm] map_smul' := by simp [smul_add] }⟩ +@[simp] protected theorem coe_add (f g : M →ₛₗ[σ₁₂] M₂) : ⇑(f + g) = ⇑f + ⇑g := rfl + @[simp] theorem add_apply (f g : M →ₛₗ[σ₁₂] M₂) (x : M) : (f + g) x = f x + g x := rfl From d0048ccd8c3f44a63dc9b797355916c292345ccf Mon Sep 17 00:00:00 2001 From: Paul Cadman <92877+paulcadman@users.noreply.github.com> Date: Mon, 10 Aug 2026 16:29:53 +0000 Subject: [PATCH 1262/1300] chore(Tactic/Module): remove backward.isDefEq.respectTransparency (#42613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove all `set_option backward.isDefEq.respectTransparency false` flags from `Tactic/Module` that were added in the v4.33.0-rc1 bump (#41779) by making the `NF / List` type synonym boundary explicit. * The transparency changes meant that lean cannot automatically infer termination for `qNF` using `::ᵣ` (notation for `NF.cons`). This is fixed by matching on plain `::` instead. I also define `reduceCoefficientwise` using plain `::` for consistency, even though it is marked `partial` so didn't have this problem. * I remove the now unused `@[match_pattern]` on `NF.cons` * The proofs of the three `NF.eval_*` theorems fail after the transparency changes because they unfold `NF.eval` into terms involving `List.map` over lists using the `NF` alias and `simp` has to unify the `List` and `NF` types. This worked before because `isDefEq` bumped this type of unification to `.default` transparency. These are now proved by induction by a new `induction_eliminator` in a similar way to `FreeMonoid.inductionOn`) and three `rfl` lemmas for `NF.cons`. --- Mathlib/Tactic/Module.lean | 80 ++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/Mathlib/Tactic/Module.lean b/Mathlib/Tactic/Module.lean index c894df925e9394..bad9a94ad136cb 100644 --- a/Mathlib/Tactic/Module.lean +++ b/Mathlib/Tactic/Module.lean @@ -56,11 +56,17 @@ variable {S : Type*} {R : Type*} {M : Type*} /-- Augment a `Module.NF R M` object `l`, i.e. a list of pairs in `R × M`, by prepending another pair `p : R × M`. -/ -@[match_pattern] def cons (p : R × M) (l : NF R M) : NF R M := p :: l @[inherit_doc cons] infixl:100 " ::ᵣ " => cons +/-- An induction principle for `NF` which mirrors induction on lists, with cases +for `[]` and `NF.cons` -/ +@[elab_as_elim, induction_eliminator] +protected theorem inductionOn {motive : NF R M → Prop} (l : NF R M) (nil : motive []) + (cons : ∀ (p : R × M) (l : NF R M), motive l → motive (p ::ᵣ l)) : motive l := + List.rec nil cons l + /-- Evaluate a `Module.NF R M` object `l`, i.e. a list of pairs in `R × M`, to an element of `M`, by forming the "linear combination" it specifies: scalar-multiply each `R` term to the corresponding `M` term, then add them all up. -/ @@ -138,12 +144,12 @@ theorem sub_eq_eval {R₁ R₂ S₁ S₂ : Type*} [AddCommGroup M] [Ring R] [Mod instance [Neg R] : Neg (NF R M) where neg l := l.map fun (a, x) ↦ (-a, x) -set_option backward.isDefEq.respectTransparency false in +theorem neg_cons [Neg R] (p : R × M) (l : NF R M) : -(p ::ᵣ l) = (-p.1, p.2) ::ᵣ (-l) := rfl + theorem eval_neg [AddCommGroup M] [Ring R] [Module R M] (l : NF R M) : (-l).eval = - l.eval := by - simp +instances only [NF.eval, List.map_map, List.sum_neg, NF.instNeg] - congr - ext p - simp + induction l with + | nil => exact neg_zero.symm + | cons p l ih => simp only [eval_cons, neg_add, neg_cons, ih, neg_smul] theorem zero_sub_eq_eval [AddCommGroup M] [Ring R] [Module R M] (l : NF R M) : 0 - l.eval = (-l).eval := by @@ -160,14 +166,15 @@ instance [Mul R] : SMul R (NF R M) where @[simp] theorem smul_apply [Mul R] (r : R) (l : NF R M) : r • l = l.map fun (a, x) ↦ (r * a, x) := rfl -set_option backward.isDefEq.respectTransparency false in +theorem smul_cons [Mul R] (r : R) (p : R × M) (l : NF R M) : + r • (p ::ᵣ l) = (r * p.1, p.2) ::ᵣ (r • l) := rfl + theorem eval_smul [AddCommMonoid M] [Semiring R] [Module R M] {l : NF R M} {x : M} (h : x = l.eval) (r : R) : (r • l).eval = r • x := by - unfold NF.eval at h ⊢ - simp only [h, smul_sum, map_map, NF.smul_apply] - congr - ext p - simp [mul_smul] + subst h + induction l with + | nil => exact (smul_zero r).symm + | cons p l ih => simp only [smul_cons, eval_cons, ih, smul_add, mul_smul] theorem smul_eq_eval {R₀ : Type*} [AddCommMonoid M] [Semiring R] [Module R M] [Semiring R₀] [Module R₀ M] [Semiring S] [Module S M] {l : NF R M} {l₀ : NF R₀ M} {s : S} {r : R} @@ -206,14 +213,15 @@ commutative semiring, by applying to each `S`-component the algebra-map from `S` def algebraMap [CommSemiring S] [Semiring R] [Algebra S R] (l : NF S M) : NF R M := l.map (fun ⟨s, x⟩ ↦ (Algebra.algebraMap S R s, x)) -set_option backward.isDefEq.respectTransparency false in +theorem algebraMap_cons [CommSemiring S] [Semiring R] [Algebra S R] (p : S × M) (l : NF S M) : + (p ::ᵣ l).algebraMap R = (Algebra.algebraMap S R p.1, p.2) ::ᵣ (l.algebraMap R) := rfl + theorem eval_algebraMap [CommSemiring S] [Semiring R] [Algebra S R] [AddMonoid M] [SMul S M] [MulAction R M] [IsScalarTower S R M] (l : NF S M) : (l.algebraMap R).eval = l.eval := by - simp only [NF.eval, algebraMap, map_map] - congr - ext - simp [IsScalarTower.algebraMap_smul] + induction l with + | nil => rfl + | cons p l ih => simp only [algebraMap_cons, eval_cons, ih, IsScalarTower.algebraMap_smul] end NF end @@ -257,7 +265,6 @@ def onScalar {u₁ u₂ : Level} {R₁ : Q(Type u₁)} {R₂ : Q(Type u₂)} (l qNF R₂ M := l.map fun ((a, x), k) ↦ ((q($f $a), x), k) -set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), construct another such term `l`, which will have the property that in the `$R`-module `$M`, the sum of the "linear combinations" represented by `l₁` and `l₂` is the linear @@ -273,15 +280,14 @@ appear in `l₁`, `l₂` respectively with the same `ℕ`-component `k`, then co meta def add (iR : Q(Semiring $R)) : qNF R M → qNF R M → qNF R M | [], l => l | l, [] => l - | ((a₁, x₁), k₁) ::ᵣ t₁, ((a₂, x₂), k₂) ::ᵣ t₂ => + | ((a₁, x₁), k₁) :: t₁, ((a₂, x₂), k₂) :: t₂ => if k₁ < k₂ then - ((a₁, x₁), k₁) ::ᵣ add iR t₁ (((a₂, x₂), k₂) ::ᵣ t₂) + ((a₁, x₁), k₁) :: add iR t₁ (((a₂, x₂), k₂) :: t₂) else if k₁ = k₂ then - ((q($a₁ + $a₂), x₁), k₁) ::ᵣ add iR t₁ t₂ + ((q($a₁ + $a₂), x₁), k₁) :: add iR t₁ t₂ else - ((a₂, x₂), k₂) ::ᵣ add iR (((a₁, x₁), k₁) ::ᵣ t₁) t₂ + ((a₂, x₂), k₂) :: add iR (((a₁, x₁), k₁) :: t₁) t₂ -set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), recursively construct a proof that in the `$R`-module `$M`, the sum of the "linear combinations" represented by `l₁` and `l₂` is the linear combination represented by @@ -292,18 +298,17 @@ meta def mkAddProof {iR : Q(Semiring $R)} {iM : Q(AddCommMonoid $M)} (iRM : Q(Mo match l₁, l₂ with | [], l => (q(zero_add (NF.eval $(l.toNF))):) | l, [] => (q(add_zero (NF.eval $(l.toNF))):) - | ((a₁, x₁), k₁) ::ᵣ t₁, ((a₂, x₂), k₂) ::ᵣ t₂ => + | ((a₁, x₁), k₁) :: t₁, ((a₂, x₂), k₂) :: t₂ => if k₁ < k₂ then - let pf := mkAddProof iRM t₁ (((a₂, x₂), k₂) ::ᵣ t₂) + let pf := mkAddProof iRM t₁ (((a₂, x₂), k₂) :: t₂) (q(NF.add_eq_eval₁ ($a₁, $x₁) $pf):) else if k₁ = k₂ then let pf := mkAddProof iRM t₁ t₂ (q(NF.add_eq_eval₂ $a₁ $a₂ $x₁ $pf):) else - let pf := mkAddProof iRM (((a₁, x₁), k₁) ::ᵣ t₁) t₂ + let pf := mkAddProof iRM (((a₁, x₁), k₁) :: t₁) t₂ (q(NF.add_eq_eval₃ ($a₂, $x₂) $pf):) -set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), construct another such term `l`, which will have the property that in the `$R`-module `$M`, the difference of the "linear combinations" represented by `l₁` and `l₂` is the @@ -320,15 +325,14 @@ that if pairs `(a₁, x₁)` and `(a₂, x₂)` appear in `l₁`, `l₂` respect def sub (iR : Q(Ring $R)) : qNF R M → qNF R M → qNF R M | [], l => l.onScalar q(Neg.neg) | l, [] => l - | ((a₁, x₁), k₁) ::ᵣ t₁, ((a₂, x₂), k₂) ::ᵣ t₂ => + | ((a₁, x₁), k₁) :: t₁, ((a₂, x₂), k₂) :: t₂ => if k₁ < k₂ then - ((a₁, x₁), k₁) ::ᵣ sub iR t₁ (((a₂, x₂), k₂) ::ᵣ t₂) + ((a₁, x₁), k₁) :: sub iR t₁ (((a₂, x₂), k₂) :: t₂) else if k₁ = k₂ then - ((q($a₁ - $a₂), x₁), k₁) ::ᵣ sub iR t₁ t₂ + ((q($a₁ - $a₂), x₁), k₁) :: sub iR t₁ t₂ else - ((q(-$a₂), x₂), k₂) ::ᵣ sub iR (((a₁, x₁), k₁) ::ᵣ t₁) t₂ + ((q(-$a₂), x₂), k₂) :: sub iR (((a₁, x₁), k₁) :: t₁) t₂ -set_option backward.isDefEq.respectTransparency false in /-- Given two terms `l₁`, `l₂` of type `qNF R M`, i.e. lists of `(Q($R) × Q($M)) × ℕ`s (two `Expr`s and a natural number), recursively construct a proof that in the `$R`-module `$M`, the difference of the "linear combinations" represented by `l₁` and `l₂` is the linear combination represented by @@ -339,15 +343,15 @@ def mkSubProof (iR : Q(Ring $R)) (iM : Q(AddCommGroup $M)) (iRM : Q(Module $R $M match l₁, l₂ with | [], l => (q(NF.zero_sub_eq_eval $(l.toNF)):) | l, [] => (q(sub_zero (NF.eval $(l.toNF))):) - | ((a₁, x₁), k₁) ::ᵣ t₁, ((a₂, x₂), k₂) ::ᵣ t₂ => + | ((a₁, x₁), k₁) :: t₁, ((a₂, x₂), k₂) :: t₂ => if k₁ < k₂ then - let pf := mkSubProof iR iM iRM t₁ (((a₂, x₂), k₂) ::ᵣ t₂) + let pf := mkSubProof iR iM iRM t₁ (((a₂, x₂), k₂) :: t₂) (q(NF.sub_eq_eval₁ ($a₁, $x₁) $pf):) else if k₁ = k₂ then let pf := mkSubProof iR iM iRM t₁ t₂ (q(NF.sub_eq_eval₂ $a₁ $a₂ $x₁ $pf):) else - let pf := mkSubProof iR iM iRM (((a₁, x₁), k₁) ::ᵣ t₁) t₂ + let pf := mkSubProof iR iM iRM (((a₁, x₁), k₁) :: t₁) t₂ (q(NF.sub_eq_eval₃ ($a₂, $x₂) $pf):) variable {iM : Q(AddCommMonoid $M)} @@ -496,18 +500,18 @@ partial def reduceCoefficientwise {R : Q(Type u)} {_ : Q(AddCommMonoid $M)} {_ : /- if one of the lists is empty and the other one is not, recurse down the nonempty one, forming goals that each of the listed coefficients is equal to zero -/ - | [], ((a, x), _) ::ᵣ L => + | [], ((a, x), _) :: L => let mvar : Q((0:$R) = $a) ← mkFreshExprMVar q((0:$R) = $a) let (mvars, pf) ← reduceCoefficientwise iRM [] L pure (mvar.mvarId! :: mvars, (q(NF.eq_const_cons $x $mvar $pf):)) - | ((a, x), _) ::ᵣ L, [] => + | ((a, x), _) :: L, [] => let mvar : Q($a = (0:$R)) ← mkFreshExprMVar q($a = (0:$R)) let (mvars, pf) ← reduceCoefficientwise iRM L [] pure (mvar.mvarId! :: mvars, (q(NF.eq_cons_const $x $mvar $pf):)) /- if both lists are nonempty, then deal with the numerically-smallest term in either list, forming a goal that it is equal to zero (if it appears in only one list) or that its coefficients in the two lists are the same (if it appears in both lists); then recurse -/ - | ((a₁, x₁), k₁) ::ᵣ L₁, ((a₂, x₂), k₂) ::ᵣ L₂ => + | ((a₁, x₁), k₁) :: L₁, ((a₂, x₂), k₂) :: L₂ => if k₁ < k₂ then let mvar : Q($a₁ = (0:$R)) ← mkFreshExprMVar q($a₁ = (0:$R)) let (mvars, pf) ← reduceCoefficientwise iRM L₁ l₂ From 55b267748a771c1a50c2abbeae061e849f8f7373 Mon Sep 17 00:00:00 2001 From: Harald Husum Date: Mon, 10 Aug 2026 17:17:11 +0000 Subject: [PATCH 1263/1300] chore(AlgebraicTopology/MooreComplex): tidy docs (#42595) This PR: - Aligns markdown header usage with the style guide - Fixes two small typos - Updates a stale claim about the state of the Dold-Kan equivalence Prepared by Claude Opus 5 --- Mathlib/AlgebraicTopology/MooreComplex.lean | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Mathlib/AlgebraicTopology/MooreComplex.lean b/Mathlib/AlgebraicTopology/MooreComplex.lean index d8a3344110ada6..a277f19c694d80 100644 --- a/Mathlib/AlgebraicTopology/MooreComplex.lean +++ b/Mathlib/AlgebraicTopology/MooreComplex.lean @@ -10,21 +10,23 @@ public import Mathlib.AlgebraicTopology.SimplicialObject.Basic public import Mathlib.CategoryTheory.Abelian.Basic /-! -## Moore complex +# Moore complex We construct the normalized Moore complex, as a functor `SimplicialObject C ⥤ ChainComplex C ℕ`, for any abelian category `C`. -The `n`-th object is intersection of +The `n`-th object is the intersection of the kernels of `X.δ i : X.obj n ⟶ X.obj (n-1)`, for `i = 1, ..., n`. The differentials are induced from `X.δ 0`, which maps each of these intersections of kernels to the next. -This functor is one direction of the Dold-Kan equivalence, which we're still working towards. +This functor is one direction of the Dold-Kan equivalence +`CategoryTheory.Abelian.DoldKan.equivalence`, the other being `CategoryTheory.Abelian.DoldKan.Γ`. +See `Mathlib/AlgebraicTopology/DoldKan/Equivalence.lean`. -### References +## References * https://stacks.math.columbia.edu/tag/0194 * https://ncatlab.org/nlab/show/Moore+complex @@ -146,7 +148,7 @@ set_option backward.defeqAttrib.useBackward true in variable (C) in /-- The (normalized) Moore complex of a simplicial object `X` in an abelian category `C`. -The `n`-th object is intersection of +The `n`-th object is the intersection of the kernels of `X.δ i : X.obj n ⟶ X.obj (n-1)`, for `i = 1, ..., n`. The differentials are induced from `X.δ 0`, From b9c78720b2b4a8c5d207a85b4f64a54f54771a45 Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Mon, 10 Aug 2026 18:00:53 +0000 Subject: [PATCH 1264/1300] =?UTF-8?q?feat(Algebra/Module/Submodule/Pointwi?= =?UTF-8?q?se):=20`u=20=E2=80=A2=20N=20=3D=20N`=20if=20`u`=20is=20a=20unit?= =?UTF-8?q?=20(#41104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Algebra/Module/Submodule/Pointwise.lean | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/Pointwise.lean b/Mathlib/Algebra/Module/Submodule/Pointwise.lean index f2da05bf463249..36f659c93e4e14 100644 --- a/Mathlib/Algebra/Module/Submodule/Pointwise.lean +++ b/Mathlib/Algebra/Module/Submodule/Pointwise.lean @@ -71,8 +71,6 @@ protected def pointwiseNeg : Neg (Submodule R M) where scoped[Pointwise] attribute [instance] Submodule.pointwiseNeg -open scoped Pointwise - @[simp] theorem coe_set_neg (S : Submodule R M) : ↑(-S) = -(S : Set M) := rfl @@ -139,8 +137,6 @@ variable {S : Type*} [Semiring S] [SMul S R] [Module S M] [IsScalarTower S R M] end Semiring -open scoped Pointwise - @[simp] theorem neg_eq_self [Ring R] [AddCommGroup M] [Module R M] (p : Submodule R M) : -p = p := ext fun _ => p.neg_mem_iff @@ -201,8 +197,6 @@ scoped[Pointwise] attribute [instance] Submodule.pointwiseDistribMulAction theorem pointwise_smul_def {a : α} {S : Submodule R M} : a • S = S.map (DistribSMul.toLinearMap R M a) := rfl -open scoped Pointwise - @[simp, norm_cast] theorem coe_pointwise_smul (a : α) (S : Submodule R M) : ↑(a • S) = a • (S : Set M) := rfl @@ -252,6 +246,16 @@ theorem smul_le_self_of_tower {α : Type*} [Monoid α] [SMul α R] [DistribMulAc rintro y ⟨x, hx, rfl⟩ exact smul_of_tower_mem _ a hx +theorem smul_eq_self_of_isUnit [SMul α R] [IsScalarTower α R M] {N : Submodule R M} + {u : α} (hu : IsUnit u) : u • N = N := by + refine le_antisymm (N.smul_le_self_of_tower u) ?_ + grw [← (u • N).smul_le_self_of_tower hu.unit⁻¹.val, ← mul_smul, IsUnit.val_inv_mul, one_smul] + +@[simp] +theorem smul_eq_self {α : Type*} [Group α] [SMul α R] [DistribMulAction α M] [SMulCommClass α R M] + [IsScalarTower α R M] {N : Submodule R M} (u : α) : u • N = N := + smul_eq_self_of_isUnit (Group.isUnit u) + end section From c3a9a08f698aab9788592d1efa32383bdda23396 Mon Sep 17 00:00:00 2001 From: Thomas Browning <13339017+tb65536@users.noreply.github.com> Date: Mon, 10 Aug 2026 20:33:26 +0000 Subject: [PATCH 1265/1300] doc(Algebra/Module/ZLattice/Basic): fix `ZLattice.comap` docstring (#42156) The linear map in the `ZLattice.comap` docstring was the wrong way around. Co-authored-by: tb65536 --- Mathlib/Algebra/Module/ZLattice/Basic.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index ffc98f30f3f956..6e25ccef62b4eb 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -36,9 +36,9 @@ point of view are in the `ZLattice` namespace. `ℤ`-module * `ZLattice.rank`: a `ℤ`-submodule of `E` that is discrete and spans `E` over `K` is free of `ℤ`-rank equal to the `K`-rank of `E` -* `ZLattice.comap`: for `e : E → F` a linear map and `L : Submodule ℤ E`, define the pullback of - `L` by `e`. If `L` is a `IsZLattice` and `e` is a continuous linear equiv, then it is also a - `IsZLattice`, see `instIsZLatticeComap`. +* `ZLattice.comap`: for `e : F → E` a linear map and `L : Submodule ℤ E`, `L.comap e` is the + `Submodule ℤ F` that is the pullback of `L` by `e`. If `IsZLattice L` and `e` is a continuous + linear equiv, then it is a `IsZLattice` of `F`, see `instIsZLatticeComap`. ## Note @@ -691,9 +691,9 @@ section comap variable (K : Type*) [NormedField K] {E F : Type*} [NormedAddCommGroup E] [NormedSpace K E] [NormedAddCommGroup F] [NormedSpace K F] (L : Submodule ℤ E) -/-- Let `e : E → F` a linear map, the map that sends a `L : Submodule ℤ E` to the +/-- For `e : F → E` a linear map and `L : Submodule ℤ E`, `L.comap e` is the `Submodule ℤ F` that is the pullback of `L` by `e`. If `IsZLattice L` and `e` is a continuous -linear equiv, then it is a `IsZLattice` of `E`, see `instIsZLatticeComap`. -/ +linear equiv, then it is a `IsZLattice` of `F`, see `instIsZLatticeComap`. -/ protected def ZLattice.comap (e : F →ₗ[K] E) := L.comap (e.restrictScalars ℤ) @[simp] From 6f1ef4e5dd604a435bddba4747b13970cd65d2a1 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:43:46 +0000 Subject: [PATCH 1266/1300] feat: generalize transfer instance type class assumptions (#42291) This PR refactors various declarations that are used for transporting instances or definitions along equivalences. The idea is to avoid using local instances with `letI` in places where we can assume an arbitrary instance instead, because otherwise these declarations can only be used in situations where the global instance is defeq to the one introduced by `letI`. In many cases this means that the equivalence needs to be an `AddEquiv` or `LinearEquiv` instead of an `Equiv`. This is not an issue in practice, because it is typically easy to construct this richer equivalence. It would be possible to keep both styles of transporting declarations, but I think that would be more confusing. This PR is a prerequisite for #41362 (no_exposing some operations in `MonoidAlgebra`), because to use the old `Equiv.distribMulAction` we need the `MonoidAlgebra` instances to be exposed. --- Mathlib/Algebra/Algebra/Unitization.lean | 16 +-- Mathlib/Algebra/Category/Grp/Colimits.lean | 6 +- .../Category/ModuleCat/Topology/Basic.lean | 6 +- Mathlib/Algebra/Group/Shrink.lean | 2 +- .../Action/TransferInstance.lean | 70 ++++++------ Mathlib/Algebra/GroupWithZero/Shrink.lean | 2 +- .../Homology/DerivedCategory/Ext/Linear.lean | 4 +- Mathlib/Algebra/Lie/Extension.lean | 3 +- Mathlib/Algebra/Lie/SemiDirect.lean | 3 +- Mathlib/Algebra/Lie/TransferInstance.lean | 35 +----- Mathlib/Algebra/Module/Shrink.lean | 4 +- Mathlib/Algebra/Module/TransferInstance.lean | 105 +++++++----------- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 5 +- Mathlib/Algebra/MonoidAlgebra/Module.lean | 11 +- Mathlib/Algebra/Polynomial/Module/Basic.lean | 6 +- Mathlib/Algebra/Quaternion.lean | 2 +- Mathlib/Algebra/WithConv.lean | 9 +- .../LocallyConvex/WeakOperatorTopology.lean | 15 +-- Mathlib/Analysis/Normed/Lp/WithLp.lean | 9 +- Mathlib/Analysis/Normed/Module/Shrink.lean | 3 +- .../Normed/Module/TransferInstance.lean | 15 +-- Mathlib/Analysis/Normed/Ring/WithAbs.lean | 4 +- Mathlib/CategoryTheory/Linear/Basic.lean | 2 +- Mathlib/Geometry/Manifold/Immersion.lean | 2 +- Mathlib/Geometry/Manifold/Submersion.lean | 2 +- .../TensorProduct/Associator.lean | 26 ++--- Mathlib/LinearAlgebra/TensorProduct/Map.lean | 21 ++-- .../Continuous/TopRep.lean | 4 +- Mathlib/RingTheory/Coalgebra/Basic.lean | 82 ++++++-------- .../RingTheory/Coalgebra/MonoidAlgebra.lean | 4 +- Mathlib/RingTheory/OrzechProperty.lean | 5 +- .../Algebra/Module/TransferInstance.lean | 27 +++-- Mathlib/Topology/Algebra/Valued/WithVal.lean | 4 +- 33 files changed, 227 insertions(+), 287 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Unitization.lean b/Mathlib/Algebra/Algebra/Unitization.lean index 430cf20882785a..d6a93f70bec1ea 100644 --- a/Mathlib/Algebra/Algebra/Unitization.lean +++ b/Mathlib/Algebra/Algebra/Unitization.lean @@ -265,14 +265,6 @@ instance instIsCentralScalar [SMul S R] [SMul S A] [SMul Sᵐᵒᵖ R] [SMul S instance instMulAction [Monoid S] [MulAction S R] [MulAction S A] : MulAction S (Unitization R A) := fast_instance% equiv.mulAction S -instance instDistribMulAction [Monoid S] [AddMonoid R] [AddMonoid A] [DistribMulAction S R] - [DistribMulAction S A] : DistribMulAction S (Unitization R A) := - fast_instance% equiv.distribMulAction S - -instance instModule [Semiring S] [AddCommMonoid R] [AddCommMonoid A] [Module S R] [Module S A] : - Module S (Unitization R A) := - fast_instance% equiv.module S - variable (R A) in /-- The identity map between `Unitization R A` and `R × A` as an `AddEquiv`. -/ @[simps! apply symm_apply] @@ -280,6 +272,14 @@ def addEquiv [Add R] [Add A] : Unitization R A ≃+ R × A where toEquiv := equiv map_add' _ _ := rfl +instance instDistribMulAction [Monoid S] [AddMonoid R] [AddMonoid A] [DistribMulAction S R] + [DistribMulAction S A] : DistribMulAction S (Unitization R A) := + fast_instance% (addEquiv _ _).distribMulAction S + +instance instModule [Semiring S] [AddCommMonoid R] [AddCommMonoid A] [Module S R] [Module S A] : + Module S (Unitization R A) := + fast_instance% (addEquiv _ _).module S + -- not marked `simp` because the LHS would not be in simp normal form. lemma toEquiv_addEquiv [Add R] [Add A] : (addEquiv R A).toEquiv = equiv := rfl diff --git a/Mathlib/Algebra/Category/Grp/Colimits.lean b/Mathlib/Algebra/Category/Grp/Colimits.lean index bcef27d14efa93..ad8f228263a35e 100644 --- a/Mathlib/Algebra/Category/Grp/Colimits.lean +++ b/Mathlib/Algebra/Category/Grp/Colimits.lean @@ -248,11 +248,7 @@ noncomputable def colimitCocone [DecidableEq J] [Small.{w} (Quot.{w} F)] : Cocon ι := { app j := AddCommGrpCat.ofHom (Shrink.addEquiv.symm.toAddMonoidHom.comp (Quot.ι F j)) - naturality _ _ _ := by - ext - dsimp - change Shrink.addEquiv.symm _ = _ - rw [Quot.map_ι] } + naturality _ _ _ := by ext; simp } @[simp] theorem Quot.desc_colimitCocone [DecidableEq J] (F : J ⥤ AddCommGrpCat.{w}) [Small.{w} (Quot F)] : diff --git a/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean index 71a5dfc5d55c77..1257723662b36c 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Topology/Basic.lean @@ -155,9 +155,11 @@ section CommRing variable {S : Type*} [CommRing S] [TopologicalSpace S] -instance {X Y : TopModuleCat S} : Module S (X ⟶ Y) where +instance {X Y : TopModuleCat S} : SMul S (X ⟶ Y) where smul r f := ofHom (r • f.hom) - __ := Equiv.module _ CategoryTheory.ConcreteCategory.homEquiv + +instance {X Y : TopModuleCat S} : Module S (X ⟶ Y) := fast_instance% + { homEquiv (Y := Y) with map_add' _ _ := rfl : (X ⟶ Y) ≃+ (X →L[S] Y) }.module S instance : Linear S (TopModuleCat S) where smul_comp _ _ _ _ _ _ := ConcreteCategory.ext (ContinuousLinearMap.comp_smul _ _ _) diff --git a/Mathlib/Algebra/Group/Shrink.lean b/Mathlib/Algebra/Group/Shrink.lean index 91885b0ebca2fe..e135a047c0db21 100644 --- a/Mathlib/Algebra/Group/Shrink.lean +++ b/Mathlib/Algebra/Group/Shrink.lean @@ -72,7 +72,7 @@ lemma equivShrink_inv [Inv α] (x : α) : equivShrink α x⁻¹ = (equivShrink namespace Shrink /-- Shrink `α` to a smaller universe preserves multiplication. -/ -@[to_additive /-- Shrink `α` to a smaller universe preserves addition. -/] +@[to_additive (attr := simps!) /-- Shrink `α` to a smaller universe preserves addition. -/] def mulEquiv [Mul α] : Shrink.{v} α ≃* α := (equivShrink α).symm.mulEquiv @[to_additive] diff --git a/Mathlib/Algebra/GroupWithZero/Action/TransferInstance.lean b/Mathlib/Algebra/GroupWithZero/Action/TransferInstance.lean index 989181e085def5..d65e36d2e96b3e 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/TransferInstance.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/TransferInstance.lean @@ -9,7 +9,7 @@ public import Mathlib.Algebra.Group.Action.TransferInstance public import Mathlib.Algebra.GroupWithZero.Action.Defs /-! -# Transfer algebraic structures across `Equiv`s +# Transfer algebraic structures across `Equiv`s or `AddEquiv`s This continues the pattern set in `Mathlib/Algebra/Group/TransferInstance.lean`. -/ @@ -24,52 +24,44 @@ namespace Equiv variable (M) in /-- Transfer `SMulZeroClass` across an `Equiv` -/ -protected abbrev smulZeroClass (e : A ≃ B) [Zero B] [SMulZeroClass M B] : - letI := e.zero - SMulZeroClass M A := by - letI := e.zero - exact { - e.smul M with - smul_zero := by simp [smul_def, zero_def] - } +protected abbrev smulZeroClass (e : A ≃ B) [Zero A] [Zero B] [SMulZeroClass M B] + (map_zero : e 0 = 0) : SMulZeroClass M A where + __ := e.smul M + smul_zero := by simp [smul_def, symm_apply_eq, map_zero] variable (M₀) in /-- Transfer `SMulWithZero` across an `Equiv` -/ -protected abbrev smulWithZero (e : A ≃ B) [Zero M₀] [Zero B] [SMulWithZero M₀ B] : - letI := e.zero - SMulWithZero M₀ A := by - letI := e.zero - exact { - e.smulZeroClass M₀ with - zero_smul := by simp [smul_def, zero_def] - } +protected abbrev smulWithZero (e : A ≃ B) [Zero M₀] [Zero A] [Zero B] [SMulWithZero M₀ B] + (map_zero : e 0 = 0) : SMulWithZero M₀ A where + __ := e.smulZeroClass M₀ map_zero + zero_smul := by simp [smul_def, symm_apply_eq, map_zero] variable (M₀) in /-- Transfer `MulActionWithZero` across an `Equiv` -/ -protected abbrev mulActionWithZero (e : A ≃ B) [MonoidWithZero M₀] [Zero B] - [MulActionWithZero M₀ B] : - letI := e.zero - MulActionWithZero M₀ A := by - letI := e.zero - exact { e.smulWithZero M₀, e.mulAction M₀ with } +protected abbrev mulActionWithZero (e : A ≃ B) [MonoidWithZero M₀] [Zero A] [Zero B] + [MulActionWithZero M₀ B] (map_zero : e 0 = 0) : MulActionWithZero M₀ A where + __ := e.smulWithZero M₀ map_zero + __ := e.mulAction M₀ + +end Equiv + +namespace AddEquiv variable (M) in -/-- Transfer `DistribSMul` across an `Equiv` -/ -protected abbrev distribSMul (e : A ≃ B) [AddZeroClass B] [DistribSMul M B] : - letI := e.addZeroClass - DistribSMul M A := by - letI := e.addZeroClass - exact { - e.smulZeroClass M with - smul_add := by simp [add_def, smul_def, smul_add] - } +/-- Transfer `DistribSMul` across an `AddEquiv` -/ +protected abbrev distribSMul [AddZeroClass A] [AddZeroClass B] [DistribSMul M B] (e : A ≃+ B) : + DistribSMul M A where + __ := e.smulZeroClass M e.map_zero + smul_add := by simp [e.smul_def, smul_add] variable (M) in -/-- Transfer `DistribMulAction` across an `Equiv` -/ -protected abbrev distribMulAction (e : A ≃ B) [Monoid M] [AddMonoid B] [DistribMulAction M B] : - letI := e.addMonoid - DistribMulAction M A := by - letI := e.addMonoid - exact { e.distribSMul M, e.mulAction M with } +/-- Transfer `DistribMulAction` across an `AddEquiv` -/ +protected abbrev distribMulAction [Monoid M] [AddMonoid A] [AddMonoid B] [DistribMulAction M B] + (e : A ≃+ B) : DistribMulAction M A where + __ := e.distribSMul M + __ := e.mulAction M -end Equiv +end AddEquiv + +@[deprecated (since := "2026-07-30")] alias Equiv.distribSMul := AddEquiv.distribSMul +@[deprecated (since := "2026-07-30")] alias Equiv.distribMulAction := AddEquiv.distribMulAction diff --git a/Mathlib/Algebra/GroupWithZero/Shrink.lean b/Mathlib/Algebra/GroupWithZero/Shrink.lean index a04c9a771eb46b..f63ef98b50d4ff 100644 --- a/Mathlib/Algebra/GroupWithZero/Shrink.lean +++ b/Mathlib/Algebra/GroupWithZero/Shrink.lean @@ -26,4 +26,4 @@ instance [MulZeroClass α] : MulZeroClass (Shrink α) := (equivShrink _).symm.mu instance [MulZeroOneClass α] : MulZeroOneClass (Shrink α) := (equivShrink _).symm.mulZeroOneClass instance [Monoid M] [AddCommMonoid α] [DistribMulAction M α] : DistribMulAction M (Shrink.{v} α) := - (equivShrink α).symm.distribMulAction M + Shrink.addEquiv.distribMulAction M diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Linear.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Linear.lean index 29c7db554d593e..5c37be084fc24a 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Linear.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Linear.lean @@ -38,13 +38,13 @@ variable {X Y : C} {n : ℕ} noncomputable instance : Module R (Ext X Y n) := letI := HasDerivedCategory.standard C - Equiv.module R homEquiv + homAddEquiv.module R lemma smul_eq_comp_mk₀ (x : Ext X Y n) (r : R) : r • x = x.comp (mk₀ (r • 𝟙 Y)) (add_zero _) := by let := HasDerivedCategory.standard C ext - apply ((Equiv.linearEquiv R homEquiv).map_smul r x).trans + apply ((homAddEquiv.linearEquiv R).map_smul r x).trans change r • homEquiv x = (x.comp (mk₀ (r • 𝟙 Y)) (add_zero _)).hom rw [comp_hom, mk₀_hom, Functor.map_smul, Functor.map_id, ShiftedHom.mk₀_smul, ShiftedHom.comp_smul, ShiftedHom.comp_mk₀_id] diff --git a/Mathlib/Algebra/Lie/Extension.lean b/Mathlib/Algebra/Lie/Extension.lean index b4f425933eec7a..4fcc2be373511e 100644 --- a/Mathlib/Algebra/Lie/Extension.lean +++ b/Mathlib/Algebra/Lie/Extension.lean @@ -151,7 +151,8 @@ def ofProd : L × M ≃ ofTwoCocycle c where -- transport instances along the equivalence instance : AddCommGroup (ofTwoCocycle c) := (ofProd c).symm.addCommGroup -instance : Module R (ofTwoCocycle c) := (ofProd c).symm.module R +instance : Module R (ofTwoCocycle c) := + ({ (ofProd c).symm with map_add' _ _ := rfl : ofTwoCocycle c ≃+ L × M}).module R @[simp] lemma of_zero : ofProd c (0 : L × M) = 0 := rfl @[simp] lemma of_add (x y : L × M) : ofProd c (x + y) = ofProd c x + ofProd c y := rfl diff --git a/Mathlib/Algebra/Lie/SemiDirect.lean b/Mathlib/Algebra/Lie/SemiDirect.lean index 0532ebe7a19e85..762f35e6b7bb22 100644 --- a/Mathlib/Algebra/Lie/SemiDirect.lean +++ b/Mathlib/Algebra/Lie/SemiDirect.lean @@ -68,7 +68,8 @@ def toProd : K ⋊⁅ψ⁆ L ≃ K × L where instance : AddCommGroup (K ⋊⁅ψ⁆ L) := toProd.addCommGroup -instance : Module R (K ⋊⁅ψ⁆ L) := toProd.module R +instance : Module R (K ⋊⁅ψ⁆ L) := + { toProd with map_add' _ _ := rfl : (K ⋊⁅ψ⁆ L) ≃+ K × L }.module R /-- `LieAlgebra.SemiDirectSum.toProd` as a linear equivalence. -/ def toProdl : (K ⋊⁅ψ⁆ L) ≃ₗ[R] K × L := diff --git a/Mathlib/Algebra/Lie/TransferInstance.lean b/Mathlib/Algebra/Lie/TransferInstance.lean index c5f8ac587ca792..da0999093972ee 100644 --- a/Mathlib/Algebra/Lie/TransferInstance.lean +++ b/Mathlib/Algebra/Lie/TransferInstance.lean @@ -15,9 +15,6 @@ public import Mathlib.Algebra.Module.TransferInstance Main definitions: * `AddEquiv.lieRing` transferring a LieRing structure along an additive equivalence. * `LinearEquiv.lieAlgebra` transferring a Lie algebra structure along a linear equivalence. -* `Equiv.lieRing` transferring a LieRing structure along an equivalence (transfers the additive - structure using `Equiv.addCommGroup` and then the bracket using `AddEquiv.lieRing`) -* `Equiv.lieAlgebra` transferring a Lie algebra structure along an equivalence -/ @@ -74,39 +71,19 @@ namespace Equiv variable {R L' L : Type*} [CommRing R] [LieRing L] [LieAlgebra R L] (e : L' ≃ L) /-- Transfer `LieRing` across an `Equiv` -/ +@[deprecated AddEquiv.lieRing (since := "2026-07-30")] protected abbrev lieRing : LieRing L' := letI := e.addCommGroup e.addEquiv.lieRing +@[deprecated AddEquiv.bracket_def (since := "2026-07-30")] lemma bracket_def (x y : L') : letI := e.lieRing ⁅x, y⁆ = e.symm ⁅e x, e y⁆ := rfl -variable (R) in -/-- Transfer `LieAlgebra` across an `Equiv` -/ -protected abbrev lieAlgebra : - letI := e.lieRing - LieAlgebra R L' := - letI := e.lieRing - letI := e.module R - { lie_smul _ _ _ := by simp [Equiv.smul_def, AddEquiv.bracket_def] } - -variable (R) in -/-- An equivalence `e : L' ≃ L` gives a Lie algebra equivalence `L' ≃ₗ⁅R⁆ L` where the algebraic -structures on `L'` are obtained by transporting the structures on `L` back along `e`. -/ -def lieEquiv : - letI := e.lieRing - letI := e.lieAlgebra R - L' ≃ₗ⁅R⁆ L := - letI := e.lieRing - letI := e.lieAlgebra R - { e.linearEquiv R with map_lie' {x y} := by simp [AddEquiv.bracket_def] } - -@[simp] lemma lieEquiv_apply (a : L') : e.lieEquiv R a = e a := rfl - -@[simp] lemma lieEquiv_symm_apply (b : L) : - letI := e.lieRing - letI := e.lieAlgebra R - (e.lieEquiv R).symm b = e.symm b := rfl +@[deprecated (since := "2026-07-30")] alias lieAlgebra := LinearEquiv.lieAlgebra +@[deprecated (since := "2026-07-30")] alias lieEquiv := LinearEquiv.lieEquiv +@[deprecated (since := "2026-07-30")] alias lieEquiv_apply := LinearEquiv.lieEquiv_apply +@[deprecated (since := "2026-07-30")] alias lieEquiv_symm_apply := LinearEquiv.lieEquiv_symm_apply end Equiv diff --git a/Mathlib/Algebra/Module/Shrink.lean b/Mathlib/Algebra/Module/Shrink.lean index e3ee90709a7482..cca69a978adbda 100644 --- a/Mathlib/Algebra/Module/Shrink.lean +++ b/Mathlib/Algebra/Module/Shrink.lean @@ -19,11 +19,11 @@ variable {R α : Type*} [Small.{v} α] [Semiring R] [AddCommMonoid α] [Module R namespace Shrink -instance : Module R (Shrink.{v} α) := (equivShrink α).symm.module R +instance : Module R (Shrink.{v} α) := addEquiv.module R variable (R α) in /-- Shrinking `α` to a smaller universe preserves module structure. -/ @[simps!] -def linearEquiv : Shrink.{v} α ≃ₗ[R] α := (equivShrink α).symm.linearEquiv _ +def linearEquiv : Shrink.{v} α ≃ₗ[R] α := (addEquiv (α := α)).linearEquiv R end Shrink diff --git a/Mathlib/Algebra/Module/TransferInstance.lean b/Mathlib/Algebra/Module/TransferInstance.lean index 11c1737f4af533..b5ea58515e39ba 100644 --- a/Mathlib/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Algebra/Module/TransferInstance.lean @@ -11,7 +11,7 @@ public import Mathlib.Algebra.Module.Torsion.Free public import Mathlib.Algebra.NoZeroSMulDivisors.Defs /-! -# Transfer algebraic structures across `Equiv`s +# Transfer algebraic structures across `Equiv`s or `AddEquiv`s This continues the pattern set in `Mathlib/Algebra/Group/TransferInstance.lean`. -/ @@ -28,81 +28,72 @@ variable (e : α ≃ β) variable (R : Type*) [Zero R] in /-- Transfer `NoZeroSMulDivisors` across an `Equiv` -/ -protected lemma noZeroSMulDivisors [Zero β] [SMul R β] [NoZeroSMulDivisors R β] : - let := e.zero - let := e.smul R +protected lemma noZeroSMulDivisors [Zero α] [Zero β] [SMul R β] [NoZeroSMulDivisors R β] + (e : α ≃ β) (map_zero : e 0 = 0) : + letI := e.smul R NoZeroSMulDivisors R α := by - extract_lets + let := e.smul R refine ⟨fun {r} m ↦ ?_⟩ - simpa [smul_def, zero_def, Equiv.eq_symm_apply] using eq_zero_or_eq_zero_of_smul_eq_zero + simp_rw [e.eq_symm_apply.2 map_zero, eq_symm_apply, smul_def, apply_symm_apply] + exact eq_zero_or_eq_zero_of_smul_eq_zero + +end Equiv + +variable [AddCommMonoid α] [AddCommMonoid β] [Module R β] + +namespace AddEquiv + +variable (e : α ≃+ β) variable (R) in /-- Transfer `Module` across an `Equiv` -/ -protected abbrev module (e : α ≃ β) [AddCommMonoid β] [Module R β] : - letI := Equiv.addCommMonoid e - Module R α := - letI := Equiv.addCommMonoid e - { Equiv.distribMulAction R e with - zero_smul := by simp [smul_def, zero_smul, zero_def] - add_smul := by simp [add_def, smul_def, add_smul] } +protected abbrev module : Module R α where + __ := e.distribMulAction R + zero_smul := by simp [e.smul_def, zero_smul] + add_smul := by simp [e.smul_def, add_smul] variable (R) in -/-- An equivalence `e : α ≃ β` gives a linear equivalence `α ≃ₗ[R] β` -where the `R`-module structure on `α` is -the one obtained by transporting an `R`-module structure on `β` back along `e`. --/ -def linearEquiv (e : α ≃ β) [AddCommMonoid β] [Module R β] : - letI := Equiv.addCommMonoid e - letI := Equiv.module R e +/-- When `α` is equipped with the `A`-module structure transferred via `e : α ≃+ β`, +this isomorphism is `A`-linear. -/ +def linearEquiv : + letI := e.module R α ≃ₗ[R] β := - letI := Equiv.addCommMonoid e - letI module := Equiv.module R e - { Equiv.addEquiv e with + letI := e.module R + { e with map_smul' := fun r x => by apply e.symm.injective - simp only [toFun_as_coe, RingHom.id_apply, EmbeddingLike.apply_eq_iff_eq] + simp only [RingHom.id_apply, EmbeddingLike.apply_eq_iff_eq] exact Iff.mp (eq_symm_apply _) rfl } @[simp] -lemma linearEquiv_apply (a : α) [AddCommMonoid β] [Module R β] : - e.linearEquiv R a = e a := rfl +lemma linearEquiv_apply (a : α) : e.linearEquiv R a = e a := rfl @[simp] -lemma linearEquiv_symm_apply (b : β) [AddCommMonoid β] [Module R β] : - letI := Equiv.addCommMonoid e - letI := Equiv.module R e - (e.linearEquiv R).symm b = e.symm b := rfl +lemma linearEquiv_symm_apply (b : β) : (e.linearEquiv R).symm b = e.symm b := rfl -set_option backward.isDefEq.respectTransparency false in variable (R) in /-- Transfer `Module.IsTorsionFree` across an `Equiv` -/ -protected lemma moduleIsTorsionFree (e : α ≃ β) [AddCommMonoid β] [Module R β] - [Module.IsTorsionFree R β] : - let := e.addCommMonoid - let := e.module R - Module.IsTorsionFree R α := by - extract_lets; exact (e.linearEquiv R).injective.moduleIsTorsionFree _ (by simp) +protected lemma moduleIsTorsionFree [Module.IsTorsionFree R β] : + letI := e.module R + Module.IsTorsionFree R α := + letI := e.module R + (e.linearEquiv R).injective.moduleIsTorsionFree _ (by simp) -end Equiv +end AddEquiv -variable (A) [Semiring A] [Module R A] [AddCommMonoid α] [AddCommMonoid β] [Module A β] +@[deprecated (since := "2026-08-10")] alias Equiv.module := AddEquiv.module +@[deprecated (since := "2026-08-10")] alias Equiv.linearEquiv := AddEquiv.linearEquiv +@[deprecated (since := "2026-08-10")] alias Equiv.linearEquiv_apply := AddEquiv.linearEquiv_apply +@[deprecated (since := "2026-08-10")] +alias Equiv.linearEquiv_symm_apply := AddEquiv.linearEquiv_symm_apply +@[deprecated (since := "2026-08-10")] +alias Equiv.moduleIsTorsionFree := AddEquiv.moduleIsTorsionFree -/-- Transport a module instance via an isomorphism of the underlying abelian groups. -This has better definitional properties than `Equiv.module` since here -the abelian group structure remains unmodified. -/ -abbrev AddEquiv.module (e : α ≃+ β) : Module A α where - toSMul := e.toEquiv.smul A - one_smul := by simp [Equiv.smul_def] - mul_smul := by simp [Equiv.smul_def, mul_smul] - smul_zero := by simp [Equiv.smul_def] - smul_add := by simp [Equiv.smul_def] - add_smul := by simp [Equiv.smul_def, add_smul] - zero_smul := by simp [Equiv.smul_def] +variable [Module R α] (A : Type*) [Semiring A] [Module R A] [Module A β] /-- The module instance from `AddEquiv.module` is compatible with the `R`-module structures, if the `AddEquiv` is induced by an `R`-module isomorphism. -/ -lemma LinearEquiv.isScalarTower [Module R α] [Module R β] [IsScalarTower R A β] - (e : α ≃ₗ[R] β) : +lemma LinearEquiv.isScalarTower [IsScalarTower R A β] (e : α ≃ₗ[R] β) : letI := e.toAddEquiv.module A IsScalarTower R A α := by let := e.toAddEquiv.module A @@ -110,13 +101,3 @@ lemma LinearEquiv.isScalarTower [Module R α] [Module R β] [IsScalarTower R A intro x y z simp only [Equiv.smul_def, smul_assoc] apply e.symm.map_smul - -/-- When `α` is equipped with the `A`-module structure transferred via `e : α ≃+ β`, -this isomorphism is `A`-linear. -/ -@[simps] -def AddEquiv.linearEquiv (e : α ≃+ β) : - letI := e.module A - α ≃ₗ[A] β := - letI := e.module A - { __ := e - map_smul' _ _ := e.apply_symm_apply _ } diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index 17a0cca0379ccd..55bcff56e2118a 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -299,7 +299,8 @@ Further results on scalar multiplication can be found in variable {A : Type*} [SMulZeroClass A R] @[to_additive (dont_translate := A) smulZeroClass] -instance smulZeroClass : SMulZeroClass A R[M] := fast_instance% coeffEquiv.smulZeroClass _ +instance smulZeroClass : SMulZeroClass A R[M] := + fast_instance% coeffEquiv.smulZeroClass _ coeff_zero section -- Ensure that the different smul instances do not create a diamond. @@ -333,7 +334,7 @@ lemma smul_single' (r' : R) (m : M) (r : R) : r' • single m r = single m (r' * @[to_additive (dont_translate := N) distribSMul] instance distribSMul [DistribSMul N R] : DistribSMul N R[M] := - fast_instance% coeffEquiv.distribSMul _ + fast_instance% coeffAddEquiv.distribSMul _ @[to_additive (dont_translate := N) isScalarTower] instance isScalarTower [SMulZeroClass N R] [SMulZeroClass O R] [SMul N O] [IsScalarTower N O R] : diff --git a/Mathlib/Algebra/MonoidAlgebra/Module.lean b/Mathlib/Algebra/MonoidAlgebra/Module.lean index f543912d3e6e0e..28910db7a1a4b0 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Module.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Module.lean @@ -49,7 +49,8 @@ section DistribMulAction variable [Monoid S] [Semiring R] [DistribMulAction S R] @[to_additive (dont_translate := S) distribMulAction] -instance distribMulAction : DistribMulAction S R[M] := fast_instance% coeffEquiv.distribMulAction _ +instance distribMulAction : DistribMulAction S R[M] := + fast_instance% coeffAddEquiv.distribMulAction _ @[to_additive (dont_translate := S) (attr := simp)] lemma mapDomain_smul (f : M → N) (s : S) (x : R[M]) : mapDomain f (s • x) = s • mapDomain f x := by @@ -61,17 +62,17 @@ section Module variable [Semiring R] [Semiring S] [Module R S] {s t : Set M} {x : S[M]} @[to_additive (dont_translate := R)] -instance : Module R S[M] := fast_instance% coeffEquiv.module _ +instance : Module R S[M] := fast_instance% coeffAddEquiv.module _ @[to_additive] instance instIsTorsionFree [IsTorsionFree R S] : IsTorsionFree R S[M] := - coeffEquiv.moduleIsTorsionFree _ + coeffAddEquiv.moduleIsTorsionFree _ variable (R) in /-- `MonoidAlgebra.coeff` as a linear equiv. -/ @[to_additive (attr := simps! apply symm_apply) /-- `MonoidAlgebra.coeff` as a linear equiv. -/] -def coeffLinearEquiv : S[M] ≃ₗ[R] M →₀ S := coeffEquiv.linearEquiv _ +def coeffLinearEquiv : S[M] ≃ₗ[R] M →₀ S := coeffAddEquiv.linearEquiv _ variable (R S) in /-- `MonoidAlgebra.mapDomain` as a linear map. -/ @@ -203,7 +204,7 @@ TODO: Generalise to a group acting on another, instead of just the left multipli @[implicit_reducible] def comapDistribMulActionSelf [Group G] [Semiring S] : DistribMulAction G S[G] := have := Finsupp.comapDistribMulAction (G := G) (α := G) (M := S) - fast_instance% coeffEquiv.distribMulAction _ + fast_instance% coeffAddEquiv.distribMulAction _ set_option backward.isDefEq.respectTransparency.types false in @[to_additive (dont_translate := R)] diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index 480708b1aa4e45..865f251e7720b8 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -142,15 +142,15 @@ lemma single_add (n : ℕ) (m₁ m₂ : M) : single R n (m₁ + m₂) = single R n m₁ + single R n m₂ := by ext; simp /-- This is required to have the `IsScalarTower S R M` instance to avoid diamonds. -/ -instance : Module S (PolynomialModule R M) := (coeffEquiv R).module _ +instance : Module S (PolynomialModule R M) := coeffAddEquiv.module _ instance (M : Type u) [AddCommGroup M] [Module R M] [Module S M] [IsScalarTower S R M] : - IsScalarTower S R (PolynomialModule R M) := (coeffEquiv R).isScalarTower _ _ + IsScalarTower S R (PolynomialModule R M) := coeffAddEquiv.isScalarTower _ _ variable (R S) in /-- `PolynomialModule.coeff` as a linear equiv. -/ @[simps! apply symm_apply] -def coeffLinearEquiv : PolynomialModule R M ≃ₗ[S] ℕ →₀ M := (coeffEquiv _).linearEquiv _ +def coeffLinearEquiv : PolynomialModule R M ≃ₗ[S] ℕ →₀ M := (coeffAddEquiv (M := M)).linearEquiv S variable (R) in /-- `PolynomialModule.single` as a linear map. -/ diff --git a/Mathlib/Algebra/Quaternion.lean b/Mathlib/Algebra/Quaternion.lean index ae9cd00586702e..60910c2c713c8e 100644 --- a/Mathlib/Algebra/Quaternion.lean +++ b/Mathlib/Algebra/Quaternion.lean @@ -506,7 +506,7 @@ def imKₗ : ℍ[R,c₁,c₂,c₃] →ₗ[R] R where map_smul' _ _ := rfl /-- `QuaternionAlgebra.equivTuple` as a linear equivalence. -/ -def linearEquivTuple : ℍ[R,c₁,c₂,c₃] ≃ₗ[R] Fin 4 → R := (equivTuple ..).linearEquiv _ +def linearEquivTuple : ℍ[R,c₁,c₂,c₃] ≃ₗ[R] Fin 4 → R := (addEquivTuple c₁ c₂ c₃).linearEquiv R @[simp] theorem coe_linearEquivTuple : diff --git a/Mathlib/Algebra/WithConv.lean b/Mathlib/Algebra/WithConv.lean index 1d7600ee547c31..131bea49a69748 100644 --- a/Mathlib/Algebra/WithConv.lean +++ b/Mathlib/Algebra/WithConv.lean @@ -82,10 +82,6 @@ instance [AddGroup A] : AddGroup (WithConv A) := (WithConv.equiv A).addGroup instance [AddCommGroup A] : AddCommGroup (WithConv A) := (WithConv.equiv A).addCommGroup @[to_additive] instance [Monoid R] [MulAction R A] : MulAction R (WithConv A) := fast_instance% (WithConv.equiv A).mulAction R -instance [Monoid R] [AddCommMonoid A] [DistribMulAction R A] : DistribMulAction R (WithConv A) := - fast_instance% (WithConv.equiv A).distribMulAction R -instance [Semiring R] [AddCommMonoid A] [Module R A] : Module R (WithConv A) := - fast_instance% (WithConv.equiv A).module R /-- Lift an equivalence between `A` and `B` to `WithConv A` and `WithConv B`. -/ protected def congr (f : A ≃ B) : WithConv A ≃ WithConv B := @@ -132,6 +128,11 @@ variable (A) in end +instance [Monoid R] [AddCommMonoid A] [DistribMulAction R A] : DistribMulAction R (WithConv A) := + fast_instance% (WithConv.addEquiv A).distribMulAction R +instance [Semiring R] [AddCommMonoid A] [Module R A] : Module R (WithConv A) := + fast_instance% (WithConv.addEquiv A).module R + variable [AddCommMonoid A] variable (R A) in diff --git a/Mathlib/Analysis/LocallyConvex/WeakOperatorTopology.lean b/Mathlib/Analysis/LocallyConvex/WeakOperatorTopology.lean index efadd1d53388e1..e97463ea879ff7 100644 --- a/Mathlib/Analysis/LocallyConvex/WeakOperatorTopology.lean +++ b/Mathlib/Analysis/LocallyConvex/WeakOperatorTopology.lean @@ -133,6 +133,12 @@ instance instAddCommGroup [IsTopologicalAddGroup F] : AddCommGroup (E →SWOT[σ] F) := equiv.addCommGroup +/-- The additive group equivalence between `ContinuousLinearMapWOT` and `ContinuousLinearMap`. -/ +@[implicit_reducible, simps!] +def addEquiv [IsTopologicalAddGroup F] : (E →SWOT[σ] F) ≃+ (E →SL[σ] F) where + __ := equiv + map_add' _ _ := rfl + instance instSMul {S : Type*} [DistribSMul S F] [SMulCommClass 𝕜₂ S F] [ContinuousConstSMul S F] : SMul S (E →SWOT[σ] F) := equiv.smul S @@ -140,7 +146,7 @@ instance instSMul {S : Type*} [DistribSMul S F] [SMulCommClass 𝕜₂ S F] [Con instance instModule {S : Type*} [Semiring S] [Module S F] [SMulCommClass 𝕜₂ S F] [ContinuousConstSMul S F] [IsTopologicalAddGroup F] : Module S (E →SWOT[σ] F) := - equiv.module S + addEquiv.module S instance instIsScalarTower {S T : Type*} [DistribSMul S F] [SMulCommClass 𝕜₂ S F] [ContinuousConstSMul S F] [DistribSMul T F] [SMulCommClass 𝕜₂ T F] @@ -167,17 +173,12 @@ instance instAlgebra {S : Type*} [CommSemiring S] [Module S E] [SMulCommClass Algebra S (E →WOT[𝕜₁] E) := equiv.algebra S -/-- The additive group equivalence between `ContinuousLinearMapWOT` and `ContinuousLinearMap`. -/ -@[simps!] -def addEquiv [IsTopologicalAddGroup F] : (E →SWOT[σ] F) ≃+ (E →SL[σ] F) := - equiv.addEquiv - /-- The linear equivalence between `ContinuousLinearMapWOT` and `ContinuousLinearMap`. -/ @[simps!] def linearEquiv (S : Type*) [Semiring S] [Module S F] [SMulCommClass 𝕜₂ S F] [ContinuousConstSMul S F] [IsTopologicalAddGroup F] : (E →SWOT[σ] F) ≃ₗ[S] (E →SL[σ] F) := - equiv.linearEquiv S + (addEquiv (F := F)).linearEquiv S /-- The ring equivalence between `ContinuousLinearMapWOT` and `ContinuousLinearMap`. -/ @[simps!] diff --git a/Mathlib/Analysis/Normed/Lp/WithLp.lean b/Mathlib/Analysis/Normed/Lp/WithLp.lean index cbf50d3dfae4e3..7cf85f423bf707 100644 --- a/Mathlib/Analysis/Normed/Lp/WithLp.lean +++ b/Mathlib/Analysis/Normed/Lp/WithLp.lean @@ -91,10 +91,6 @@ instance instAddCommGroup [AddCommGroup V] : AddCommGroup (WithLp p V) := (WithLp.equiv p V).smul K @[to_additive] instance instMulAction [Monoid K] [MulAction K V] : MulAction K (WithLp p V) := fast_instance% (WithLp.equiv p V).mulAction K -instance instDistribMulAction [Monoid K] [AddCommGroup V] [DistribMulAction K V] : - DistribMulAction K (WithLp p V) := fast_instance% (WithLp.equiv p V).distribMulAction K -instance instModule [Semiring K] [AddCommGroup V] [Module K V] : Module K (WithLp p V) := - fast_instance% (WithLp.equiv p V).module K variable {K V} @@ -231,6 +227,11 @@ lemma toLp_multisetSum [AddCommGroup V] (s : Multiset V) : toLp p s.sum = (s.map (toLp p)).sum := map_multiset_sum (WithLp.addEquiv _ _).symm _ +instance instDistribMulAction [Monoid K] [AddCommGroup V] [DistribMulAction K V] : + DistribMulAction K (WithLp p V) := fast_instance% (WithLp.addEquiv p V).distribMulAction K +instance instModule [Semiring K] [AddCommGroup V] [Module K V] : Module K (WithLp p V) := + fast_instance% (WithLp.addEquiv p V).module K + /-- `WithLp.equiv` as a linear equivalence. -/ @[simps apply symm_apply] protected def linearEquiv [Semiring K] [AddCommGroup V] [Module K V] : WithLp p V ≃ₗ[K] V where diff --git a/Mathlib/Analysis/Normed/Module/Shrink.lean b/Mathlib/Analysis/Normed/Module/Shrink.lean index 80135c036d91ea..5ba9c437b0acbc 100644 --- a/Mathlib/Analysis/Normed/Module/Shrink.lean +++ b/Mathlib/Analysis/Normed/Module/Shrink.lean @@ -6,6 +6,7 @@ Authors: Michael Rothgang module public import Mathlib.Analysis.Normed.Module.TransferInstance +public import Mathlib.Algebra.Group.Shrink /-! # Transfer normed algebraic structures from `α` to `Shrink α` @@ -27,6 +28,6 @@ instance [NormedAddCommGroup α] : NormedAddCommGroup (Shrink.{v} α) := (equivShrink α).symm.normedAddCommGroup instance [SeminormedAddCommGroup α] [NormedSpace 𝕜 α] : NormedSpace 𝕜 (Shrink.{v} α) := - (equivShrink α).symm.normedSpace 𝕜 + (Shrink.addEquiv (α := α)).normedSpace 𝕜 end Shrink diff --git a/Mathlib/Analysis/Normed/Module/TransferInstance.lean b/Mathlib/Analysis/Normed/Module/TransferInstance.lean index d4453ec1b02c34..1c6af88fa85958 100644 --- a/Mathlib/Analysis/Normed/Module/TransferInstance.lean +++ b/Mathlib/Analysis/Normed/Module/TransferInstance.lean @@ -11,7 +11,7 @@ public import Mathlib.Algebra.Module.TransferInstance public import Mathlib.Topology.MetricSpace.TransferInstance /-! -# Transfer normed algebraic structures across `Equiv`s +# Transfer normed algebraic structures across `Equiv`s or `AddEquiv`s In this file, we transfer a (semi-)normed (additive) commutative group and normed space structures across an equivalence. @@ -40,13 +40,14 @@ protected abbrev normedCommGroup [NormedCommGroup β] (e : α ≃ β) : NormedCo { NormedCommGroup.induced _ _ e.mulEquiv e.injective with toPseudoMetricSpace := e.pseudometricSpace } -/-- Transfer `NormedSpace` across an `Equiv` -/ -protected abbrev normedSpace (𝕜 : Type*) [NormedField 𝕜] - [SeminormedAddCommGroup β] [NormedSpace 𝕜 β] (e : α ≃ β) : - letI := Equiv.seminormedAddCommGroup e +end Equiv + +/-- Transfer `NormedSpace` across an `AddEquiv` -/ +protected abbrev AddEquiv.normedSpace (𝕜 : Type*) [NormedField 𝕜] + [AddCommGroup α] [SeminormedAddCommGroup β] [NormedSpace 𝕜 β] (e : α ≃+ β) : + letI : SeminormedAddCommGroup α := .induced _ _ e NormedSpace 𝕜 α := - letI := e.seminormedAddCommGroup letI := e.module 𝕜 .induced _ _ _ (e.linearEquiv _) -end Equiv +@[deprecated (since := "2026-07-30")] alias Equiv.normedSpace := AddEquiv.normedSpace diff --git a/Mathlib/Analysis/Normed/Ring/WithAbs.lean b/Mathlib/Analysis/Normed/Ring/WithAbs.lean index 5b717c5e8f9ecd..5a19b8b32bd085 100644 --- a/Mathlib/Analysis/Normed/Ring/WithAbs.lean +++ b/Mathlib/Analysis/Normed/Ring/WithAbs.lean @@ -244,7 +244,7 @@ instance moduleLeft [AddCommMonoid T] [Module R T] : Module (WithAbs v) T := @[deprecated (since := "2026-03-02")] alias instModule_left := moduleLeft instance [Semiring T] [Module T R] : Module T (WithAbs v) := - fast_instance% (equiv v).module T + fast_instance% (equiv v).toAddEquiv.module T @[deprecated (since := "2026-03-02")] alias instModule_right := instModule @@ -253,7 +253,7 @@ variable [Semiring T] [Module R T] (v : AbsoluteValue T S) variable (R) in /-- The canonical `R`-linear isomorphism between `WithAbs v` and `T`, when `v : AbsoluteValue T S`. -/ -def linearEquiv : WithAbs v ≃ₗ[R] T := (equiv v).linearEquiv R +def linearEquiv : WithAbs v ≃ₗ[R] T := (equiv v).toAddEquiv.linearEquiv R variable {v} diff --git a/Mathlib/CategoryTheory/Linear/Basic.lean b/Mathlib/CategoryTheory/Linear/Basic.lean index d612353d79e24d..6c51e2c5320a45 100644 --- a/Mathlib/CategoryTheory/Linear/Basic.lean +++ b/Mathlib/CategoryTheory/Linear/Basic.lean @@ -98,7 +98,7 @@ universe u' variable {D : Type u'} (F : D → C) instance inducedCategory : Linear.{w, v} R (InducedCategory C F) where - homModule X Y := Equiv.module _ InducedCategory.homEquiv + homModule X Y := InducedCategory.homAddEquiv.module _ smul_comp _ _ _ _ _ _ := by ext; apply smul_comp comp_smul _ _ _ _ _ _ := by ext; apply comp_smul diff --git a/Mathlib/Geometry/Manifold/Immersion.lean b/Mathlib/Geometry/Manifold/Immersion.lean index fa4107315b6225..d31a3f0bde1acc 100644 --- a/Mathlib/Geometry/Manifold/Immersion.lean +++ b/Mathlib/Geometry/Manifold/Immersion.lean @@ -339,7 +339,7 @@ mathematically, this is just the identity map; however, this is technically usef us to always work with `hf.smallComplement`. -/ def smallEquiv (hf : IsImmersionAtOfComplement F I J n f x) : F ≃L[𝕜] hf.smallComplement := haveI := hf.small - ((equivShrink F).symm.continuousLinearEquiv 𝕜).symm + ((Shrink.addEquiv (α := F)).continuousLinearEquiv 𝕜).symm lemma trans_F (h : IsImmersionAtOfComplement F I J n f x) (e : F ≃L[𝕜] F') : IsImmersionAtOfComplement F' I J n f x := by diff --git a/Mathlib/Geometry/Manifold/Submersion.lean b/Mathlib/Geometry/Manifold/Submersion.lean index b3653286e2b5e4..714cde96f90589 100644 --- a/Mathlib/Geometry/Manifold/Submersion.lean +++ b/Mathlib/Geometry/Manifold/Submersion.lean @@ -314,7 +314,7 @@ mathematically, this is just the identity map; however, this is technically usef us to always work with `hf.smallComplement`. -/ def smallEquiv (hf : IsSubmersionAtOfComplement F I J n f x) : F ≃L[𝕜] hf.smallComplement := haveI := hf.small - ((equivShrink F).symm.continuousLinearEquiv 𝕜).symm + ((Shrink.addEquiv (α := F)).continuousLinearEquiv 𝕜).symm lemma trans_F (h : IsSubmersionAtOfComplement F I J n f x) (e : F ≃L[𝕜] F') : IsSubmersionAtOfComplement F' I J n f x := by diff --git a/Mathlib/LinearAlgebra/TensorProduct/Associator.lean b/Mathlib/LinearAlgebra/TensorProduct/Associator.lean index 7f9e9738aa27e3..6c4ed95ffcd023 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Associator.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Associator.lean @@ -378,28 +378,24 @@ lemma rTensor_lTensor_comp_assoc_symm (x : M →ₗ[R] N) : end LinearMap -namespace Equiv +namespace LinearEquiv variable {R A A' B B' C C' : Type*} -variable [CommSemiring R] [AddCommMonoid A'] [AddCommMonoid B'] [AddCommMonoid C'] -variable [Module R A'] [Module R B'] [Module R C'] +variable [CommSemiring R] [AddCommMonoid A] [AddCommMonoid B] [AddCommMonoid C] +variable [AddCommMonoid A'] [AddCommMonoid B'] [AddCommMonoid C'] +variable [Module R A] [Module R B] [Module R C] [Module R A'] [Module R B'] [Module R C'] variable (R) in open TensorProduct in -lemma tensorProductAssoc_def (eA : A ≃ A') (eB : B ≃ B') (eC : C ≃ C') : - letI := eA.addCommMonoid - letI := eB.addCommMonoid - letI := eC.addCommMonoid - letI := eA.module R - letI := eB.module R - letI := eC.module R - TensorProduct.assoc R A B C = .trans - (congr (congr (eA.linearEquiv R) (eB.linearEquiv R)) (eC.linearEquiv R)) (.trans - (TensorProduct.assoc R A' B' C') <| congr (eA.linearEquiv R).symm <| - congr (eB.linearEquiv R).symm (eC.linearEquiv R).symm) := by +lemma tensorProductAssoc_def (eA : A ≃ₗ[R] A') (eB : B ≃ₗ[R] B') (eC : C ≃ₗ[R] C') : + TensorProduct.assoc R A B C = .trans (congr (congr eA eB) eC) (.trans + (TensorProduct.assoc R A' B' C') <| congr eA.symm <| congr eB.symm (eC).symm) := by ext x induction x with | zero => simp | add => simp [*] | tmul x a => induction x <;> simp [*, add_tmul] -end Equiv +end LinearEquiv + +@[deprecated (since := "2026-07-30")] +alias Equiv.tensorProductAssoc_def := LinearEquiv.tensorProductAssoc_def diff --git a/Mathlib/LinearAlgebra/TensorProduct/Map.lean b/Mathlib/LinearAlgebra/TensorProduct/Map.lean index 60b3091201c93e..19e68a92575d03 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Map.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Map.lean @@ -732,20 +732,19 @@ end LinearMap end Ring -namespace Equiv +namespace LinearEquiv variable {R A A' B B' : Type*} [CommSemiring R] - [AddCommMonoid A'] [AddCommMonoid B'] [Module R A'] [Module R B'] + [AddCommMonoid A] [AddCommMonoid B] [AddCommMonoid A'] [AddCommMonoid B'] + [Module R A] [Module R B] [Module R A'] [Module R B'] variable (R) in open TensorProduct in -lemma tensorProductComm_def (eA : A ≃ A') (eB : B ≃ B') : - letI := eA.addCommMonoid - letI := eB.addCommMonoid - letI := eA.module R - letI := eB.module R - TensorProduct.comm R A B = .trans - (congr (eA.linearEquiv R) (eB.linearEquiv R)) (.trans - (TensorProduct.comm R A' B') <| congr (eB.linearEquiv R).symm (eA.linearEquiv R).symm) := by +lemma tensorProductComm_def (eA : A ≃ₗ[R] A') (eB : B ≃ₗ[R] B') : + TensorProduct.comm R A B = .trans (congr eA eB) (.trans + (TensorProduct.comm R A' B') <| congr eB.symm eA.symm) := by ext x; induction x <;> simp [*] -end Equiv +end LinearEquiv + +@[deprecated (since := "2026-07-30")] +alias Equiv.tensorProductComm_def := LinearEquiv.tensorProductComm_def diff --git a/Mathlib/RepresentationTheory/Continuous/TopRep.lean b/Mathlib/RepresentationTheory/Continuous/TopRep.lean index 68277800b92d83..a20ed338335844 100644 --- a/Mathlib/RepresentationTheory/Continuous/TopRep.lean +++ b/Mathlib/RepresentationTheory/Continuous/TopRep.lean @@ -163,7 +163,9 @@ variable {k : Type u} {G : Type v} {X Y : Type w} [TopologicalSpace k] [CommRing [IsTopologicalAddGroup Y] [ContinuousSMul k Y] {ρ : ContRepresentation k G X} {σ : ContRepresentation k G Y} {A B C : TopRep k G} -instance : Module k (A ⟶ B) := fast_instance% ConcreteCategory.homEquiv.module k +instance : Module k (A ⟶ B) := fast_instance% + { ConcreteCategory.homEquiv (X := A) with + map_add' := hom_add A B : (A ⟶ B) ≃+ (A.ρ →ⁱL B.ρ) }.module k lemma hom_smul (r : k) (f : A ⟶ B) : (r • f).hom = r • f.hom := rfl diff --git a/Mathlib/RingTheory/Coalgebra/Basic.lean b/Mathlib/RingTheory/Coalgebra/Basic.lean index 0a67d142795a46..375dbb969e5b6d 100644 --- a/Mathlib/RingTheory/Coalgebra/Basic.lean +++ b/Mathlib/RingTheory/Coalgebra/Basic.lean @@ -542,62 +542,48 @@ instance instIsCocomm [∀ i, IsCocomm R (A i)] : IsCocomm R (Π i, A i) where end Pi -namespace Equiv +namespace LinearEquiv variable {R A B : Type*} [CommSemiring R] + [AddCommMonoid A] [Module R A] [AddCommMonoid B] [Module R B] variable (R) in -/-- Transfer `CoalgebraStruct` across an `Equiv`. -/ -abbrev coalgebraStruct [AddCommMonoid B] [Module R B] [CoalgebraStruct R B] (e : A ≃ B) : - letI := e.addCommMonoid - letI := e.module R - CoalgebraStruct R A := - letI := e.addCommMonoid - letI := e.module R - { comul := - TensorProduct.map (e.linearEquiv R).symm.toLinearMap (e.linearEquiv R).symm.toLinearMap ∘ₗ - comul ∘ₗ (e.linearEquiv R).toLinearMap - counit := counit ∘ₗ (e.linearEquiv R).toLinearMap } +/-- Transfer `CoalgebraStruct` across a `LinearEquiv`. -/ +abbrev coalgebraStruct [CoalgebraStruct R B] (e : A ≃ₗ[R] B) : CoalgebraStruct R A where + comul := TensorProduct.map e.symm e.symm ∘ₗ comul ∘ₗ e.toLinearMap + counit := counit ∘ₗ e.toLinearMap variable (R) in -/-- Transfer `Coalgebra` across an `Equiv`. -/ -abbrev coalgebra [AddCommMonoid B] [Module R B] [Coalgebra R B] (e : A ≃ B) : - letI := e.addCommMonoid - letI := e.module R - Coalgebra R A := - letI := e.addCommMonoid - letI := e.module R - { __ := e.coalgebraStruct R - rTensor_counit_comp_comul := by - ext - apply (TensorProduct.map_bijective (f := .id) Function.bijective_id - (e.linearEquiv R).bijective).injective - simpa +instances [coalgebraStruct, LinearMap.comp_assoc, TensorProduct.map_map, - LinearMap.rTensor] using! Coalgebra.rTensor_counit_comul _ - lTensor_counit_comp_comul := by - ext - apply (TensorProduct.map_bijective (g := .id) (e.linearEquiv R).bijective - Function.bijective_id).injective - simpa +instances [coalgebraStruct, LinearMap.comp_assoc, TensorProduct.map_map, - LinearMap.lTensor] using! Coalgebra.lTensor_counit_comul _ - coassoc := by - ext - apply (TensorProduct.map_bijective (e.linearEquiv R).bijective <| - TensorProduct.map_bijective (e.linearEquiv R).bijective - (e.linearEquiv R).bijective).injective - simp +instances [coalgebraStruct, e.tensorProductAssoc_def R, TensorProduct.congr, - ← LinearMap.comp_assoc, TensorProduct.map_map, ← TensorProduct.map_comp] - simpa [LinearMap.comp_assoc, -coassoc_apply] using! coassoc_apply (R := R) (A := B) _ } +/-- Transfer `Coalgebra` across a `LinearEquiv`. -/ +abbrev coalgebra [Coalgebra R B] (e : A ≃ₗ[R] B) : Coalgebra R A where + __ := e.coalgebraStruct R + rTensor_counit_comp_comul := by + ext + apply (TensorProduct.map_bijective (f := .id) Function.bijective_id e.bijective).injective + simpa +instances [coalgebraStruct, LinearMap.comp_assoc, TensorProduct.map_map, + LinearMap.rTensor] using! Coalgebra.rTensor_counit_comul _ + lTensor_counit_comp_comul := by + ext + apply (TensorProduct.map_bijective (g := .id) e.bijective Function.bijective_id).injective + simpa +instances [coalgebraStruct, LinearMap.comp_assoc, TensorProduct.map_map, + LinearMap.lTensor] using! Coalgebra.lTensor_counit_comul _ + coassoc := by + ext + apply (TensorProduct.map_bijective e.bijective <| + TensorProduct.map_bijective e.bijective e.bijective).injective + simp +instances [coalgebraStruct, e.tensorProductAssoc_def R e e, TensorProduct.congr, + ← LinearMap.comp_assoc, TensorProduct.map_map, ← TensorProduct.map_comp] + simpa [LinearMap.comp_assoc, -coassoc_apply] using! coassoc_apply (R := R) (A := B) _ variable (R) in -/-- Transfer `Coalgebra.IsCocomm` across an `Equiv`. -/ -lemma coalgebraIsCocomm [AddCommMonoid B] [Module R B] [Coalgebra R B] [IsCocomm R B] (e : A ≃ B) : - letI := e.addCommMonoid - letI := e.module R +/-- Transfer `Coalgebra.IsCocomm` across a `LinearEquiv`. -/ +lemma coalgebraIsCocomm [Coalgebra R B] [IsCocomm R B] (e : A ≃ₗ[R] B) : letI := e.coalgebra R IsCocomm R A := - letI := e.addCommMonoid - letI := e.module R - letI := e.coalgebra R + let := e.coalgebra R { comm_comp_comul := by ext; simp [comul, ← TensorProduct.map_comm] } -end Equiv +end LinearEquiv + +@[deprecated (since := "2026-08-10")] alias Equiv.coalgebraStruct := LinearEquiv.coalgebraStruct +@[deprecated (since := "2026-08-10")] alias Equiv.coalgebra := LinearEquiv.coalgebra +@[deprecated (since := "2026-08-10")] alias Equiv.coalgebraIsCocomm := LinearEquiv.coalgebraIsCocomm diff --git a/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean index a088eb39fe0904..5aa726b1460cde 100644 --- a/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/Coalgebra/MonoidAlgebra.lean @@ -36,10 +36,10 @@ variable {R : Type*} [CommSemiring R] {A : Type*} [Semiring A] variable (R A X) in @[to_additive] -instance instCoalgebra : Coalgebra R A[X] := coeffEquiv.coalgebra _ +instance instCoalgebra : Coalgebra R A[X] := (coeffLinearEquiv R).coalgebra _ @[to_additive] -instance instIsCocomm [IsCocomm R A] : IsCocomm R A[X] := coeffEquiv.coalgebraIsCocomm _ +instance instIsCocomm [IsCocomm R A] : IsCocomm R A[X] := (coeffLinearEquiv R).coalgebraIsCocomm _ @[to_additive (attr := simp)] lemma counit_single (x : X) (a : A) : diff --git a/Mathlib/RingTheory/OrzechProperty.lean b/Mathlib/RingTheory/OrzechProperty.lean index facc0d1a7bd74d..fd1c61c51e5874 100644 --- a/Mathlib/RingTheory/OrzechProperty.lean +++ b/Mathlib/RingTheory/OrzechProperty.lean @@ -81,10 +81,7 @@ theorem injective_of_surjective_of_injective (i f : N →ₗ[R] M) (hi : Injective i) (hf : Surjective f) : Injective f := by obtain ⟨n, g, hg⟩ := Module.Finite.exists_fin' R M have := small_of_surjective hg - let := Equiv.addCommMonoid (equivShrink M).symm - let := Equiv.module R (equivShrink M).symm - let j : Shrink.{u} M ≃ₗ[R] M := Equiv.linearEquiv R (equivShrink M).symm - have := Module.Finite.equiv j.symm + let j : Shrink.{u} M ≃ₗ[R] M := (Shrink.addEquiv (α := M)).linearEquiv R let i' := j.symm.toLinearMap ∘ₗ i replace hi : Injective i' := by simpa [i'] using hi let f' := j.symm.toLinearMap ∘ₗ f ∘ₗ (LinearEquiv.ofInjective i' hi).symm.toLinearMap diff --git a/Mathlib/Topology/Algebra/Module/TransferInstance.lean b/Mathlib/Topology/Algebra/Module/TransferInstance.lean index dfdbf05b9d7ad0..fc92434cb9eacb 100644 --- a/Mathlib/Topology/Algebra/Module/TransferInstance.lean +++ b/Mathlib/Topology/Algebra/Module/TransferInstance.lean @@ -13,7 +13,7 @@ public import Mathlib.Data.EReal.Operations public import Mathlib.Topology.MetricSpace.Bounded /-! -# Transfer topological algebraic structures across `Equiv`s +# Transfer topological algebraic structures across `AddEquiv`s or `ContinuousLinearEquiv`s In this file, we construct a continuous linear equivalence `α ≃L[R] β` from an equivalence `α ≃ β`, where the continuous `R`-module structure on `α` is the one obtained by transporting an @@ -27,40 +27,43 @@ This continues the pattern set in `Mathlib/Algebra/Module/TransferInstance.lean` variable {R α β : Type*} -namespace Equiv +namespace AddEquiv variable (e : α ≃ β) -variable [TopologicalSpace β] [AddCommMonoid β] [Semiring R] [Module R β] +variable [AddCommMonoid α] [TopologicalSpace β] [AddCommMonoid β] [Semiring R] [Module R β] variable (R) in -/-- An equivalence `e : α ≃ β` gives a continuous linear equivalence `α ≃L[R] β` +/-- An additive equivalence `e : α ≃+ β` gives a continuous linear equivalence `α ≃L[R] β` where the continuous `R`-module structure on `α` is the one obtained by transporting an `R`-module structure on `β` back along `e`. This is `e.linearEquiv` as a continuous linear equivalence. -/ -def continuousLinearEquiv (e : α ≃ β) : +def continuousLinearEquiv (e : α ≃+ β) : letI := e.topologicalSpace - letI := e.addCommMonoid letI := e.module R α ≃L[R] β := letI := e.topologicalSpace - letI := e.addCommMonoid letI := e.module R { toLinearEquiv := e.linearEquiv _ continuous_toFun := continuous_induced_dom continuous_invFun := by - simp +instances only [Equiv.topologicalSpace, toFun_as_coe, ← coinduced_symm] + simp +instances only [Equiv.topologicalSpace, e.toFun_as_coe, ← e.coinduced_symm] exact continuous_coinduced_rng } @[simp] -lemma toLinearEquiv_continuousLinearEquiv (e : α ≃ β) : +lemma toLinearEquiv_continuousLinearEquiv (e : α ≃+ β) : letI := e.topologicalSpace - letI := e.addCommMonoid letI := e.module R (e.continuousLinearEquiv R).toLinearEquiv = e.linearEquiv R := rfl -end Equiv +end AddEquiv + +@[deprecated (since := "2026-08-10")] +alias Equiv.continuousLinearEquiv := AddEquiv.continuousLinearEquiv + +@[deprecated (since := "2026-08-10")] +alias Equiv.toLinearEquiv_continuousLinearEquiv := AddEquiv.toLinearEquiv_continuousLinearEquiv section ContinuousLinearEquiv @@ -104,4 +107,4 @@ variable (R α) in noncomputable def Shrink.continuousLinearEquiv [Small.{v} α] [AddCommMonoid α] [TopologicalSpace α] [Semiring R] [Module R α] : Shrink.{v} α ≃L[R] α := - (equivShrink α).symm.continuousLinearEquiv R + (Shrink.addEquiv (α := α)).continuousLinearEquiv R diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index 09cf269950aa83..f45c2985d075a9 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -273,13 +273,13 @@ instance [AddCommMonoid S] [Module R S] [Module.Finite R S] : Module.Finite (WithVal v) S := .of_restrictScalars_finite R (WithVal v) S instance [Semiring S] [Module S R] : Module S (WithVal v) := - fast_instance% (equiv v).module S + fast_instance% (equiv v).toAddEquiv.module S variable [Ring S] [Module R S] (v : Valuation S Γ₀) variable (R) in /-- The canonical `R`-linear isomorphism between `WithVal v` and `S`, when `v : Valuation S Γ₀`. -/ -def linearEquiv : WithVal v ≃ₗ[R] S := (equiv v).linearEquiv R +def linearEquiv : WithVal v ≃ₗ[R] S := (equiv v).toAddEquiv.linearEquiv R @[simp] theorem linearEquiv_apply (x : WithVal v) : linearEquiv R v x = x.ofVal := rfl From de5ce8a9a66a4aa68a9bdbb35b63a06d34d9ca11 Mon Sep 17 00:00:00 2001 From: Garmelon <11077553+Garmelon@users.noreply.github.com> Date: Tue, 11 Aug 2026 00:21:07 +0000 Subject: [PATCH 1267/1300] chore: bump toolchain to v4.34.0-rc1 (#42619) Co-authored-by: Rob23oba Co-authored-by: mathlib4-bot Co-authored-by: mathlib-nightly-testing[bot] Co-authored-by: Joscha Co-authored-by: Kim Morrison --- Archive/Arithcc.lean | 2 +- .../IfNormalization/WithoutAesop.lean | 4 +- Archive/Imo/Imo2013Q1.lean | 4 +- Archive/Imo/Imo2024Q5.lean | 28 +- Archive/Imo/Imo2024Q6.lean | 6 +- Archive/MiuLanguage/DecisionSuf.lean | 4 +- Archive/Wiedijk100Theorems/AbelRuffini.lean | 2 +- Archive/Wiedijk100Theorems/BallotProblem.lean | 16 +- Archive/Wiedijk100Theorems/BuffonsNeedle.lean | 4 +- Archive/Wiedijk100Theorems/CubingACube.lean | 22 +- .../Wiedijk100Theorems/FriendshipGraphs.lean | 4 +- Cache/Test.lean | 298 +++++++++--------- Counterexamples/AharoniKorman.lean | 16 +- .../CliffordAlgebraNotInjective.lean | 2 +- Counterexamples/MapFloor.lean | 2 +- Mathlib/Algebra/BigOperators/Expect.lean | 2 +- Mathlib/Algebra/BigOperators/Finprod.lean | 16 +- .../BigOperators/Group/Finset/Basic.lean | 6 +- .../BigOperators/Group/Finset/Piecewise.lean | 31 +- Mathlib/Algebra/BigOperators/Ring/Finset.lean | 6 +- Mathlib/Algebra/Colimit/Ring.lean | 4 +- Mathlib/Algebra/DirectSum/Basic.lean | 5 +- Mathlib/Algebra/EuclideanDomain/Defs.lean | 6 +- Mathlib/Algebra/EuclideanDomain/Field.lean | 4 +- Mathlib/Algebra/Field/IsField.lean | 6 +- Mathlib/Algebra/Field/Rat.lean | 4 +- Mathlib/Algebra/FreeAlgebra.lean | 4 +- Mathlib/Algebra/GCDMonoid/Basic.lean | 27 +- Mathlib/Algebra/GCDMonoid/Finset.lean | 2 +- Mathlib/Algebra/GCDMonoid/Nat.lean | 10 +- Mathlib/Algebra/Group/Defs.lean | 2 +- Mathlib/Algebra/Group/End.lean | 8 +- Mathlib/Algebra/Group/ForwardDiff.lean | 6 +- Mathlib/Algebra/GroupWithZero/Hom.lean | 4 +- .../Algebra/GroupWithZero/Units/Basic.lean | 10 +- Mathlib/Algebra/GroupWithZero/WithZero.lean | 4 +- Mathlib/Algebra/Homology/Bifunctor.lean | 4 +- .../Algebra/Homology/BifunctorAssociator.lean | 8 +- Mathlib/Algebra/Homology/ComplexShape.lean | 4 +- .../Homology/DerivedCategory/Ext/Basic.lean | 4 +- .../Algebra/Homology/DifferentialObject.lean | 2 +- Mathlib/Algebra/Homology/Double.lean | 36 +-- Mathlib/Algebra/Homology/Embedding/Basic.lean | 4 +- .../Algebra/Homology/Embedding/TruncGE.lean | 30 +- .../Algebra/Homology/HomologicalComplex.lean | 32 +- Mathlib/Algebra/Homology/Homotopy.lean | 8 +- .../Homology/HomotopyCategory/HomComplex.lean | 10 +- .../HomotopyCategory/SingleFunctors.lean | 2 +- Mathlib/Algebra/Homology/HomotopyCofiber.lean | 48 +-- Mathlib/Algebra/Homology/Monoidal.lean | 4 +- Mathlib/Algebra/Homology/Single.lean | 18 +- .../SpectralObject/SpectralSequence.lean | 8 +- Mathlib/Algebra/Homology/TotalComplex.lean | 4 +- Mathlib/Algebra/Lie/CartanExists.lean | 2 +- Mathlib/Algebra/Lie/Classical.lean | 4 +- Mathlib/Algebra/Lie/DirectSum.lean | 2 +- Mathlib/Algebra/Lie/Weights/Chain.lean | 6 +- Mathlib/Algebra/Lie/Weights/RootSystem.lean | 8 +- Mathlib/Algebra/LinearRecurrence.lean | 2 +- .../Algebra/Module/LinearMap/Polynomial.lean | 4 +- Mathlib/Algebra/Module/ZLattice/Basic.lean | 4 +- Mathlib/Algebra/MonoidAlgebra/Degree.lean | 16 +- .../Algebra/MonoidAlgebra/NoZeroDivisors.lean | 5 +- Mathlib/Algebra/MvPolynomial/Basic.lean | 13 +- Mathlib/Algebra/MvPolynomial/Coeff.lean | 2 +- Mathlib/Algebra/MvPolynomial/CommRing.lean | 2 +- Mathlib/Algebra/MvPolynomial/Degrees.lean | 8 +- Mathlib/Algebra/MvPolynomial/Division.lean | 2 +- Mathlib/Algebra/MvPolynomial/Equiv.lean | 16 +- Mathlib/Algebra/MvPolynomial/Funext.lean | 2 +- Mathlib/Algebra/MvPolynomial/PDeriv.lean | 2 +- Mathlib/Algebra/MvPolynomial/Rename.lean | 2 +- Mathlib/Algebra/Notation/Indicator.lean | 4 +- Mathlib/Algebra/Notation/Support.lean | 2 +- .../Algebra/Order/AbsoluteValue/Basic.lean | 2 +- Mathlib/Algebra/Order/Antidiag/Finsupp.lean | 2 +- Mathlib/Algebra/Order/Antidiag/Nat.lean | 2 +- .../Algebra/Order/Archimedean/Real/Basic.lean | 6 +- Mathlib/Algebra/Order/CauSeq/Completion.lean | 4 +- .../Order/GroupWithZero/Canonical.lean | 2 +- .../Algebra/Order/Module/HahnEmbedding.lean | 7 +- Mathlib/Algebra/Order/Ring/GeomSum.lean | 8 +- Mathlib/Algebra/Order/Ring/StandardPart.lean | 24 +- Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean | 2 +- Mathlib/Algebra/Order/Ring/WithTop.lean | 22 +- Mathlib/Algebra/Order/Round.lean | 6 +- Mathlib/Algebra/Polynomial/Basic.lean | 10 +- Mathlib/Algebra/Polynomial/BigOperators.lean | 2 +- Mathlib/Algebra/Polynomial/Coeff.lean | 17 +- .../Polynomial/Degree/CardPowDegree.lean | 8 +- Mathlib/Algebra/Polynomial/Degree/Defs.lean | 6 +- .../Algebra/Polynomial/Degree/Operations.lean | 4 +- .../Polynomial/Degree/TrailingDegree.lean | 12 +- Mathlib/Algebra/Polynomial/Derivative.lean | 4 +- Mathlib/Algebra/Polynomial/Div.lean | 41 +-- Mathlib/Algebra/Polynomial/EraseLead.lean | 27 +- Mathlib/Algebra/Polynomial/Eval/Degree.lean | 4 +- Mathlib/Algebra/Polynomial/Expand.lean | 12 +- Mathlib/Algebra/Polynomial/FieldDivision.lean | 4 +- Mathlib/Algebra/Polynomial/HasseDeriv.lean | 4 +- Mathlib/Algebra/Polynomial/Laurent.lean | 2 +- Mathlib/Algebra/Polynomial/Mirror.lean | 8 +- Mathlib/Algebra/Polynomial/Monic.lean | 2 +- Mathlib/Algebra/Polynomial/Reverse.lean | 4 +- Mathlib/Algebra/Polynomial/RingDivision.lean | 6 +- Mathlib/Algebra/Polynomial/Roots.lean | 6 +- Mathlib/Algebra/Polynomial/RuleOfSigns.lean | 2 +- .../Polynomial/SumIteratedDerivative.lean | 2 +- Mathlib/Algebra/Polynomial/UnitTrinomial.lean | 12 +- Mathlib/Algebra/Ring/Parity.lean | 4 +- Mathlib/Algebra/SkewMonoidAlgebra/Single.lean | 4 +- Mathlib/Algebra/SkewPolynomial/Basic.lean | 10 +- .../EllipticCurve/Affine/Formula.lean | 4 +- .../EllipticCurve/Affine/Point.lean | 8 +- .../DivisionPolynomial/Basic.lean | 26 +- .../DivisionPolynomial/Degree.lean | 4 +- .../EllipticCurve/Jacobian/Point.lean | 10 +- .../EllipticCurve/ModelsWithJ.lean | 17 +- .../EllipticCurve/NormalForms.lean | 4 +- .../EllipticCurve/Projective/Point.lean | 10 +- Mathlib/AlgebraicGeometry/Morphisms/Flat.lean | 2 +- .../AlgebraicGeometry/OrderOfVanishing.lean | 4 +- .../DoldKan/FunctorGamma.lean | 4 +- .../DoldKan/SplitSimplicialObject.lean | 2 +- .../SimplexCategory/DeltaZeroIter.lean | 4 +- .../SimplexCategory/ToMkOne.lean | 4 +- .../SimplicialObject/ChainHomotopy.lean | 2 +- .../AnodyneExtensions/UnionProd.lean | 6 +- Mathlib/Analysis/Analytic/Binomial.lean | 2 +- Mathlib/Analysis/Analytic/CPolynomial.lean | 12 +- Mathlib/Analysis/Analytic/Order.lean | 4 +- Mathlib/Analysis/BoxIntegral/Basic.lean | 16 +- .../Analysis/BoxIntegral/Partition/Basic.lean | 6 +- .../BoxIntegral/Partition/Tagged.lean | 5 +- .../Analysis/BoxIntegral/UnitPartition.lean | 6 +- .../NonUnital.lean | 12 +- .../ContinuousFunctionalCalculus/Unital.lean | 10 +- .../BumpFunction/FiniteDimension.lean | 6 +- .../Calculus/ContDiff/FaaDiBruno.lean | 4 +- .../Analysis/Calculus/FDeriv/Analytic.lean | 4 +- Mathlib/Analysis/Calculus/FDeriv/Basic.lean | 4 +- Mathlib/Analysis/Calculus/FDeriv/Const.lean | 2 +- Mathlib/Analysis/Complex/Hadamard.lean | 4 +- .../Complex/Polynomial/GaussLucas.lean | 6 +- .../Complex/UpperHalfPlane/FixedPoints.lean | 6 +- .../Complex/UpperHalfPlane/MoebiusAction.lean | 2 +- .../LogCounting/Asymptotic.lean | 4 +- Mathlib/Analysis/Convex/Combination.lean | 14 +- Mathlib/Analysis/Fourier/AddCircleMulti.lean | 2 +- .../FiniteAbelian/PontryaginDuality.lean | 2 +- .../InnerProductSpace/LinearPMap.lean | 4 +- .../InnerProductSpace/Orientation.lean | 6 +- .../InnerProductSpace/Orthonormal.lean | 2 +- .../Analysis/InnerProductSpace/Subspace.lean | 6 +- Mathlib/Analysis/MeanInequalitiesPow.lean | 6 +- Mathlib/Analysis/Meromorphic/Order.lean | 2 +- .../Normed/Affine/AddTorsorBases.lean | 2 +- .../Analysis/Normed/Algebra/Exponential.lean | 4 +- .../Normed/Algebra/GelfandFormula.lean | 2 +- Mathlib/Analysis/Normed/Group/AddCircle.lean | 4 +- Mathlib/Analysis/Normed/Group/Seminorm.lean | 18 +- Mathlib/Analysis/Normed/Lp/PiLp.lean | 12 +- Mathlib/Analysis/Normed/Lp/ProdLp.lean | 12 +- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 16 +- .../Normed/Module/Ball/Homeomorph.lean | 4 +- Mathlib/Analysis/Normed/Module/Bases.lean | 2 +- .../Normed/Module/FiniteDimension.lean | 2 +- .../Normed/Unbundled/RingSeminorm.lean | 6 +- .../Normed/Unbundled/SpectralNorm.lean | 33 +- Mathlib/Analysis/ODE/ExistUnique.lean | 6 +- Mathlib/Analysis/ODE/Gronwall.lean | 8 +- Mathlib/Analysis/RCLike/Sqrt.lean | 4 +- Mathlib/Analysis/Real/Hyperreal.lean | 4 +- Mathlib/Analysis/Seminorm.lean | 2 +- .../SpecialFunctions/Complex/Analytic.lean | 2 +- .../SpecialFunctions/Complex/Arg.lean | 22 +- .../SpecialFunctions/Complex/Log.lean | 5 +- .../Elliptic/Weierstrass.lean | 10 +- .../Analysis/SpecialFunctions/Log/Basic.lean | 6 +- .../SpecialFunctions/Log/ENNRealLog.lean | 8 +- .../SpecialFunctions/Log/ENNRealLogExp.lean | 2 +- .../SpecialFunctions/Pow/Complex.lean | 11 +- .../Analysis/SpecialFunctions/Pow/NNReal.lean | 2 +- .../Analysis/SpecialFunctions/Pow/Real.lean | 4 +- Mathlib/Analysis/SpecificLimits/Basic.lean | 2 +- Mathlib/Analysis/SpecificLimits/Normed.lean | 2 +- .../EnoughInjectives.lean | 6 +- Mathlib/CategoryTheory/Extensive.lean | 2 +- Mathlib/CategoryTheory/GlueData.lean | 18 +- Mathlib/CategoryTheory/GradedObject.lean | 4 +- .../CategoryTheory/GradedObject/Single.lean | 8 +- .../Limits/Preserves/SigmaConst.lean | 4 +- .../Limits/Shapes/Biproducts.lean | 20 +- .../Limits/Shapes/MultiequalizerPullback.lean | 4 +- .../CategoryTheory/Limits/Shapes/PiProd.lean | 4 +- .../Limits/Shapes/SequentialProduct.lean | 20 +- Mathlib/CategoryTheory/Limits/VanKampen.lean | 19 +- .../Monoidal/FunctorCategory.lean | 2 + Mathlib/CategoryTheory/Monoidal/Mon.lean | 4 +- .../CategoryTheory/Monoidal/Preadditive.lean | 4 +- .../Preadditive/Biproducts.lean | 2 +- Mathlib/CategoryTheory/Preadditive/Mat.lean | 14 +- Mathlib/CategoryTheory/Preadditive/Schur.lean | 4 +- .../Presentable/SharplyLT/Basic.lean | 2 +- .../SmallObject/Iteration/ExtendToSucc.lean | 20 +- .../Iteration/FunctorOfCocone.lean | 20 +- .../Enumerative/IncidenceAlgebra.lean | 27 +- .../Enumerative/Pentagonal/PowerSeries.lean | 2 +- Mathlib/Combinatorics/Matroid/Basic.lean | 2 +- Mathlib/Combinatorics/Schnirelmann.lean | 2 +- .../SetFamily/AhlswedeZhang.lean | 8 +- .../SetFamily/Compression/UV.lean | 2 +- .../SetFamily/FourFunctions.lean | 6 +- Mathlib/Combinatorics/SetFamily/Kleitman.lean | 2 +- .../SetFamily/KruskalKatona.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Copy.lean | 4 +- Mathlib/Combinatorics/SimpleGraph/Hall.lean | 4 +- Mathlib/Combinatorics/SimpleGraph/Prod.lean | 4 +- .../SimpleGraph/Regularity/Equitabilise.lean | 10 +- .../SimpleGraph/Regularity/Uniform.lean | 14 +- .../Young/SemistandardTableau.lean | 6 +- Mathlib/Computability/Encoding.lean | 4 +- Mathlib/Computability/Primrec/List.lean | 4 +- Mathlib/Computability/RegularExpressions.lean | 4 +- .../Computability/TuringMachine/Config.lean | 12 +- .../TuringMachine/StackTuringMachine.lean | 3 +- Mathlib/Computability/TuringMachine/Tape.lean | 6 +- .../TuringMachine/ToPartrec.lean | 16 +- Mathlib/Data/Bool/Count.lean | 2 +- Mathlib/Data/DFinsupp/Defs.lean | 24 +- Mathlib/Data/DFinsupp/Sigma.lean | 3 +- Mathlib/Data/DFinsupp/WellFounded.lean | 16 +- Mathlib/Data/ENat/Pow.lean | 2 +- Mathlib/Data/EReal/Basic.lean | 20 +- Mathlib/Data/EReal/Operations.lean | 16 +- Mathlib/Data/Fin/SuccPred.lean | 8 +- Mathlib/Data/Fin/Tuple/Basic.lean | 15 +- Mathlib/Data/Fin/Tuple/Embedding.lean | 4 +- Mathlib/Data/Finset/Fold.lean | 2 +- Mathlib/Data/Finset/Functor.lean | 8 +- Mathlib/Data/Finset/Lattice/Pi.lean | 3 +- Mathlib/Data/Finset/Sigma.lean | 6 +- Mathlib/Data/Finset/Update.lean | 9 +- Mathlib/Data/Finsupp/Antidiagonal.lean | 4 +- Mathlib/Data/Finsupp/Basic.lean | 14 +- Mathlib/Data/Finsupp/Indicator.lean | 4 +- Mathlib/Data/Finsupp/Multiset.lean | 2 +- Mathlib/Data/Finsupp/Single.lean | 2 +- Mathlib/Data/Finsupp/ToDFinsupp.lean | 5 +- Mathlib/Data/Fintype/BigOperators.lean | 2 +- Mathlib/Data/Int/Basic.lean | 2 +- Mathlib/Data/Int/Bitwise.lean | 10 +- .../Data/Int/ConditionallyCompleteOrder.lean | 20 +- Mathlib/Data/Int/Init.lean | 2 +- Mathlib/Data/Int/Log.lean | 18 +- Mathlib/Data/Int/WithZero.lean | 9 +- Mathlib/Data/List/Basic.lean | 8 +- Mathlib/Data/List/Cycle.lean | 14 +- Mathlib/Data/List/Destutter.lean | 24 +- Mathlib/Data/List/DropRight.lean | 8 +- Mathlib/Data/List/MinMax.lean | 10 +- Mathlib/Data/List/Sigma.lean | 8 +- Mathlib/Data/List/Sort.lean | 6 +- Mathlib/Data/Matrix/Basis.lean | 4 +- Mathlib/Data/Matrix/Block.lean | 12 +- Mathlib/Data/Multiset/AddSub.lean | 4 +- Mathlib/Data/Multiset/Filter.lean | 2 +- Mathlib/Data/Multiset/Pi.lean | 4 +- Mathlib/Data/Multiset/UnionInter.lean | 4 +- Mathlib/Data/Nat/BinaryRec.lean | 13 +- Mathlib/Data/Nat/Bitwise.lean | 2 +- Mathlib/Data/Nat/Cast/Defs.lean | 5 +- Mathlib/Data/Nat/Choose/Multinomial.lean | 16 +- Mathlib/Data/Nat/Choose/Sum.lean | 4 +- Mathlib/Data/Nat/Digits/Defs.lean | 4 +- Mathlib/Data/Nat/Digits/Lemmas.lean | 1 + Mathlib/Data/Nat/Init.lean | 4 +- Mathlib/Data/Nat/Log.lean | 10 +- Mathlib/Data/Nat/ModEq.lean | 11 +- Mathlib/Data/Nat/Multiplicity.lean | 2 +- Mathlib/Data/Nat/Nth.lean | 13 +- Mathlib/Data/Nat/Pairing.lean | 4 +- Mathlib/Data/Nat/Totient.lean | 5 +- Mathlib/Data/Num/Lemmas.lean | 6 +- Mathlib/Data/Num/Prime.lean | 4 +- Mathlib/Data/Ordering/Lemmas.lean | 5 +- Mathlib/Data/Ordmap/Invariants.lean | 14 +- Mathlib/Data/PEquiv.lean | 10 +- Mathlib/Data/PFunctor/Univariate/Basic.lean | 2 +- Mathlib/Data/PFunctor/Univariate/M.lean | 4 +- Mathlib/Data/PNat/Basic.lean | 6 +- Mathlib/Data/PNat/Defs.lean | 12 +- Mathlib/Data/PNat/Xgcd.lean | 4 +- Mathlib/Data/Part.lean | 10 +- Mathlib/Data/Rat/Cast/Lemmas.lean | 2 +- Mathlib/Data/Real/Sign.lean | 8 +- Mathlib/Data/Set/Card.lean | 4 +- Mathlib/Data/Set/Function.lean | 4 +- Mathlib/Data/Set/Piecewise.lean | 4 +- Mathlib/Data/Set/Restrict.lean | 4 +- Mathlib/Data/Setoid/Partition/Card.lean | 2 +- Mathlib/Data/Sigma/Interval.lean | 8 +- Mathlib/Data/Sign/Defs.lean | 7 +- Mathlib/Data/String/Basic.lean | 8 +- Mathlib/Data/SubtypeNeLift.lean | 4 +- Mathlib/Data/Sym/Basic.lean | 8 +- Mathlib/Data/ZMod/Basic.lean | 8 +- Mathlib/Data/ZMod/Defs.lean | 2 +- Mathlib/Data/ZMod/ValMinAbs.lean | 4 +- Mathlib/Dynamics/PeriodicPts/Defs.lean | 8 +- Mathlib/Dynamics/SymbolicDynamics/Basic.lean | 2 +- Mathlib/FieldTheory/CardinalEmb.lean | 2 +- Mathlib/FieldTheory/Finite/Basic.lean | 2 +- .../IsAlgClosed/AlgebraicClosure.lean | 2 +- Mathlib/FieldTheory/IsPerfectClosure.lean | 8 +- Mathlib/FieldTheory/KummerExtension.lean | 5 +- Mathlib/FieldTheory/Minpoly/Basic.lean | 4 +- Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean | 2 +- .../FieldTheory/PolynomialGaloisGroup.lean | 4 +- Mathlib/FieldTheory/RatFunc/Basic.lean | 12 +- Mathlib/FieldTheory/RatFunc/Luroth.lean | 4 +- Mathlib/FieldTheory/RatFunc/Valuation.lean | 15 +- Mathlib/FieldTheory/Separable.lean | 2 +- Mathlib/FieldTheory/SeparablyGenerated.lean | 2 +- .../SplittingField/Construction.lean | 2 +- Mathlib/Geometry/Convex/Set.lean | 2 +- Mathlib/Geometry/Euclidean/Circumcenter.lean | 4 +- Mathlib/Geometry/Euclidean/MongePoint.lean | 2 +- .../Geometry/Manifold/ContMDiffMFDeriv.lean | 2 +- Mathlib/Geometry/Manifold/Instances/Real.lean | 4 +- .../Manifold/IntegralCurve/UniformTime.lean | 20 +- .../Geometry/Manifold/IsManifold/Basic.lean | 2 +- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 12 +- Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean | 4 +- .../Manifold/MFDeriv/SpecificFunctions.lean | 2 +- .../Geometry/Manifold/MFDeriv/Tangent.lean | 4 +- .../VectorBundle/FiberwiseLinear.lean | 2 +- Mathlib/GroupTheory/CommutingProbability.lean | 5 +- Mathlib/GroupTheory/Complement.lean | 4 +- Mathlib/GroupTheory/CoprodI.lean | 14 +- Mathlib/GroupTheory/CosetCover.lean | 6 +- Mathlib/GroupTheory/Coxeter/Basic.lean | 11 +- Mathlib/GroupTheory/Divisible.lean | 8 +- Mathlib/GroupTheory/Exponent.lean | 8 +- Mathlib/GroupTheory/FiniteAbelian/Basic.lean | 2 +- Mathlib/GroupTheory/FreeAbelianGroup.lean | 4 +- Mathlib/GroupTheory/FreeGroup/Basic.lean | 1 + .../FreeGroup/NielsenSchreier.lean | 6 +- Mathlib/GroupTheory/HNNExtension.lean | 15 +- Mathlib/GroupTheory/Nilpotent.lean | 4 +- Mathlib/GroupTheory/OrderOfElement.lean | 2 +- Mathlib/GroupTheory/Perm/Centralizer.lean | 8 +- Mathlib/GroupTheory/Perm/ClosureSwap.lean | 19 +- Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 2 +- Mathlib/GroupTheory/Perm/Cycle/Factors.lean | 10 +- Mathlib/GroupTheory/Perm/Cycle/Type.lean | 10 +- Mathlib/GroupTheory/Perm/Fin.lean | 8 +- Mathlib/GroupTheory/Perm/Sign.lean | 18 +- .../Alternating/Centralizer.lean | 6 +- Mathlib/GroupTheory/Transfer.lean | 8 +- .../KullbackLeibler/Basic.lean | 12 +- .../KullbackLeibler/DataProcessing.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/Basis.lean | 4 +- .../AffineSpace/Combination.lean | 4 +- .../AffineSpace/Independent.lean | 8 +- Mathlib/LinearAlgebra/Basis/Basic.lean | 4 +- Mathlib/LinearAlgebra/Coevaluation.lean | 4 +- Mathlib/LinearAlgebra/Determinant.lean | 10 +- Mathlib/LinearAlgebra/Dimension/Finite.lean | 10 +- .../LinearAlgebra/Dimension/Localization.lean | 2 +- Mathlib/LinearAlgebra/Dual/Basis.lean | 2 +- .../Eigenspace/Triangularizable.lean | 2 +- .../FiniteDimensional/Basic.lean | 4 +- .../FiniteDimensional/Lemmas.lean | 2 +- .../Finsupp/LinearCombination.lean | 2 +- Mathlib/LinearAlgebra/Finsupp/Supported.lean | 2 +- .../LinearAlgebra/Finsupp/VectorSpace.lean | 2 +- Mathlib/LinearAlgebra/FreeModule/Norm.lean | 2 +- Mathlib/LinearAlgebra/Lagrange.lean | 4 +- .../LinearAlgebra/LinearIndependent/Defs.lean | 8 +- Mathlib/LinearAlgebra/LinearPMap.lean | 2 +- .../LinearAlgebra/Matrix/Charpoly/Coeff.lean | 8 +- .../Matrix/Determinant/Basic.lean | 6 +- .../Matrix/Determinant/Misc.lean | 2 +- .../Matrix/FixedDetMatrices.lean | 6 +- Mathlib/LinearAlgebra/Matrix/Permanent.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Rank.lean | 3 +- Mathlib/LinearAlgebra/Matrix/RowCol.lean | 8 +- .../Matrix/SpecialLinearGroup.lean | 2 +- Mathlib/LinearAlgebra/Matrix/ToLin.lean | 2 +- .../LinearAlgebra/Matrix/Transvection.lean | 16 +- Mathlib/LinearAlgebra/Multilinear/Basic.lean | 12 +- Mathlib/LinearAlgebra/Pi.lean | 4 +- .../Projectivization/Constructions.lean | 4 +- .../LinearAlgebra/QuadraticForm/Basic.lean | 4 +- .../LinearAlgebra/QuadraticForm/Basis.lean | 2 +- .../GeckConstruction/Relations.lean | 23 +- Mathlib/LinearAlgebra/Trace.lean | 8 +- Mathlib/Logic/Basic.lean | 9 +- Mathlib/Logic/Embedding/Basic.lean | 4 +- Mathlib/Logic/Equiv/Basic.lean | 15 +- Mathlib/Logic/Equiv/Fin/Basic.lean | 12 +- Mathlib/Logic/Equiv/Fin/Rotate.lean | 4 +- Mathlib/Logic/Equiv/Option.lean | 2 +- Mathlib/Logic/Equiv/Prod.lean | 4 +- Mathlib/Logic/Equiv/Set.lean | 4 +- Mathlib/Logic/Equiv/Sum.lean | 10 +- Mathlib/Logic/Function/Basic.lean | 22 +- Mathlib/Logic/Hydra.lean | 2 +- .../Constructions/BorelSpace/Order.lean | 8 +- .../Constructions/Cylinders.lean | 6 +- .../ProjectiveFamilyContent.lean | 2 +- .../MeasureTheory/Covering/Besicovitch.lean | 14 +- .../Covering/BesicovitchVectorSpace.lean | 6 +- .../MeasureTheory/Covering/LiminfLimsup.lean | 4 +- .../Function/AEMeasurableSequence.lean | 6 +- .../ConditionalExpectation/Basic.lean | 19 +- .../ConditionalExpectation/CondexpL1.lean | 6 +- .../Function/ConditionalLExpectation.lean | 4 +- .../Function/L1Space/Integrable.lean | 2 +- .../Function/LpSeminorm/Basic.lean | 2 +- .../Function/LpSeminorm/Count.lean | 2 +- .../Function/LpSeminorm/LpNorm.lean | 4 +- .../LpSeminorm/TriangleInequality.lean | 2 +- .../MeasureTheory/Function/SimpleFunc.lean | 6 +- Mathlib/MeasureTheory/Group/Measure.lean | 2 +- .../MeasureTheory/Integral/Bochner/Basic.lean | 6 +- .../MeasureTheory/Integral/Lebesgue/Add.lean | 6 +- .../Lebesgue/DominatedConvergence.lean | 4 +- .../MeasureTheory/Integral/Lebesgue/Sub.lean | 2 +- Mathlib/MeasureTheory/Integral/Prod.lean | 2 +- Mathlib/MeasureTheory/Integral/SetToL1.lean | 4 +- .../MeasurableSpace/Constructions.lean | 6 +- .../MeasureTheory/MeasurableSpace/Defs.lean | 2 +- Mathlib/MeasureTheory/Measure/Comap.lean | 10 +- .../Measure/Decomposition/Exhaustion.lean | 2 +- .../Measure/Decomposition/Lebesgue.lean | 17 +- Mathlib/MeasureTheory/Measure/Dirac.lean | 4 +- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 8 +- .../Measure/LogLikelihoodRatio.lean | 6 +- Mathlib/MeasureTheory/Measure/Map.lean | 4 +- .../MeasureTheory/Measure/MeasureSpace.lean | 4 +- .../MeasureTheory/Measure/NullMeasurable.lean | 2 +- .../Measure/ProbabilityMeasure.lean | 2 +- Mathlib/MeasureTheory/Measure/Restrict.lean | 4 +- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 2 +- .../Measure/WithDensityFinite.lean | 2 +- Mathlib/MeasureTheory/SetSemiring.lean | 2 +- .../MeasureTheory/VectorMeasure/Basic.lean | 62 ++-- .../VectorMeasure/Decomposition/Hahn.lean | 10 +- .../VectorMeasure/Decomposition/Jordan.lean | 14 +- .../VectorMeasure/Decomposition/Lebesgue.lean | 4 +- .../VectorMeasure/WithDensity.lean | 18 +- Mathlib/ModelTheory/Algebra/Field/Basic.lean | 4 +- .../Algebra/Field/IsAlgClosed.lean | 2 +- Mathlib/ModelTheory/Encoding.lean | 6 +- Mathlib/ModelTheory/LanguageMap.lean | 4 +- Mathlib/ModelTheory/Semantics.lean | 2 +- Mathlib/NumberTheory/AbelSummation.lean | 7 +- .../NumberTheory/ArithmeticFunction/Defs.lean | 8 +- .../ArithmeticFunction/LFunction.lean | 4 +- .../ArithmeticFunction/Liouville.lean | 2 +- .../NumberTheory/ArithmeticFunction/Misc.lean | 4 +- .../ArithmeticFunction/Moebius.lean | 32 +- .../ArithmeticFunction/VonMangoldt.lean | 4 +- .../NumberTheory/ArithmeticFunction/Zeta.lean | 6 +- Mathlib/NumberTheory/Bernoulli.lean | 12 +- .../NumberTheory/BernoulliPolynomials.lean | 4 +- Mathlib/NumberTheory/ClassNumber/Finite.lean | 2 +- .../Cyclotomic/CyclotomicCharacter.lean | 8 +- Mathlib/NumberTheory/Divisors.lean | 2 +- .../EllipticDivisibilitySequence.lean | 18 +- .../EulerProduct/DirichletLSeries.lean | 4 +- Mathlib/NumberTheory/GaussSum.lean | 2 +- .../Harmonic/EulerMascheroni.lean | 6 +- Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean | 2 +- Mathlib/NumberTheory/JacobiSum/Basic.lean | 2 +- Mathlib/NumberTheory/LSeries/Basic.lean | 4 +- Mathlib/NumberTheory/LSeries/Convergence.lean | 2 +- Mathlib/NumberTheory/LSeries/Dirichlet.lean | 2 +- .../NumberTheory/LSeries/HurwitzZetaEven.lean | 2 +- Mathlib/NumberTheory/LSeries/Injectivity.lean | 4 +- Mathlib/NumberTheory/LSeries/RiemannZeta.lean | 6 +- Mathlib/NumberTheory/LSeries/SumCoeff.lean | 14 +- .../LegendreSymbol/GaussEisensteinLemmas.lean | 4 +- .../LegendreSymbol/JacobiSymbol.lean | 4 +- .../LegendreSymbol/QuadraticChar/Basic.lean | 24 +- .../NumberTheory/LegendreSymbol/ZModChar.lean | 2 +- Mathlib/NumberTheory/ModularForms/Cusps.lean | 4 +- .../ModularForms/JacobiTheta/Bounds.lean | 2 +- Mathlib/NumberTheory/MulChar/Basic.lean | 20 +- Mathlib/NumberTheory/MulChar/Duality.lean | 2 +- .../NumberField/CanonicalEmbedding/Basic.lean | 20 +- .../CanonicalEmbedding/ConvexBody.lean | 16 +- .../CanonicalEmbedding/NormLeOne.lean | 28 +- .../CanonicalEmbedding/PolarCoord.lean | 6 +- .../NumberField/Completion/Ramification.lean | 2 +- .../NumberField/Cyclotomic/Basic.lean | 4 +- .../NumberField/DirichletDensity.lean | 4 +- .../NumberField/InfinitePlace/Basic.lean | 4 +- .../InfinitePlace/Ramification.lean | 4 +- .../NumberTheory/NumberField/Units/Basic.lean | 2 +- .../NumberField/Units/Regulator.lean | 12 +- .../NumberTheory/Padics/PadicIntegers.lean | 2 +- Mathlib/NumberTheory/Padics/PadicNorm.lean | 4 +- Mathlib/NumberTheory/Padics/PadicNumbers.lean | 41 +-- Mathlib/NumberTheory/Primorial.lean | 2 +- .../RamificationInertia/Basic.lean | 2 +- .../RamificationInertia/Galois.lean | 4 +- .../RamificationInertia/Inertia.lean | 12 +- .../RamificationInertia/Ramification.lean | 4 +- Mathlib/NumberTheory/RatFunc/Ostrowski.lean | 4 +- Mathlib/NumberTheory/ZetaValues.lean | 11 +- Mathlib/Order/Atoms.lean | 26 +- Mathlib/Order/CompleteLatticeIntervals.lean | 4 +- .../ConditionallyCompleteLattice/Basic.lean | 16 +- .../ConditionallyCompleteLattice/Defs.lean | 2 +- Mathlib/Order/DirectedInverseSystem.lean | 4 +- Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Order/Filter/Finite.lean | 4 +- Mathlib/Order/Filter/Germ/Basic.lean | 2 +- Mathlib/Order/Interval/Basic.lean | 2 +- Mathlib/Order/Lattice.lean | 2 +- Mathlib/Order/Lattice/Nat.lean | 10 +- Mathlib/Order/LiminfLimsup.lean | 12 +- Mathlib/Order/Monotone/Extension.lean | 4 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 6 +- Mathlib/Order/OrderIsoNat.lean | 2 +- Mathlib/Order/Partition/Basic.lean | 2 +- Mathlib/Order/Preorder/Chain.lean | 4 +- Mathlib/Order/Std.lean | 6 +- Mathlib/Order/SuccPred/Basic.lean | 8 +- Mathlib/Order/SuccPred/Limit.lean | 18 +- .../Order/SuccPred/LinearLocallyFinite.lean | 12 +- Mathlib/Order/WellFoundedSet.lean | 8 +- Mathlib/Probability/Distributions/Beta.lean | 6 +- Mathlib/Probability/Distributions/Cauchy.lean | 4 +- .../Distributions/Exponential.lean | 6 +- Mathlib/Probability/Distributions/Gamma.lean | 8 +- .../Distributions/Gaussian/Real.lean | 4 +- .../Probability/Distributions/Geometric.lean | 2 +- Mathlib/Probability/Distributions/Pareto.lean | 8 +- .../Probability/Distributions/Uniform.lean | 6 +- Mathlib/Probability/IdentDistrib.lean | 4 +- .../Probability/Independence/Conditional.lean | 4 +- .../Independence/Kernel/Indep.lean | 6 +- .../Independence/Kernel/IndepFun.lean | 16 +- .../HasIndepIncrements/IsGaussianProcess.lean | 2 +- .../Kernel/Composition/ParallelComp.lean | 6 +- .../Disintegration/MeasurableStieltjes.lean | 10 +- .../Kernel/Disintegration/StandardBorel.lean | 2 +- .../Kernel/IonescuTulcea/Maps.lean | 4 +- .../Kernel/IonescuTulcea/PartialTraj.lean | 6 +- .../Kernel/IonescuTulcea/Traj.lean | 6 +- Mathlib/Probability/Kernel/WithDensity.lean | 4 +- .../Probability/Martingale/Convergence.lean | 4 +- .../Moments/CovarianceBilinDual.lean | 4 +- .../ProbabilityMassFunction/Basic.lean | 4 +- .../ProbabilityMassFunction/Binomial.lean | 2 +- .../ProbabilityMassFunction/Monad.lean | 8 +- Mathlib/Probability/Process/Filtration.lean | 16 +- Mathlib/Probability/Process/HittingTime.lean | 32 +- Mathlib/Probability/ProductMeasure.lean | 11 +- Mathlib/RepresentationTheory/FiniteIndex.lean | 10 +- .../Homological/FiniteCyclic.lean | 15 +- .../Homological/Resolution.lean | 2 +- Mathlib/RingTheory/Adjoin/PowerBasis.lean | 2 +- Mathlib/RingTheory/AdjoinRoot.lean | 3 +- Mathlib/RingTheory/Algebraic/Basic.lean | 2 +- .../RingTheory/Coalgebra/CoassocSimps.lean | 6 +- Mathlib/RingTheory/Coprime/Ideal.lean | 9 +- Mathlib/RingTheory/Coprime/Lemmas.lean | 4 +- .../DedekindDomain/AdicValuation.lean | 14 +- .../RingTheory/DedekindDomain/Different.lean | 8 +- .../DedekindDomain/Factorization.lean | 19 +- .../DedekindDomain/SelmerGroup.lean | 4 +- .../RingTheory/DividedPowerAlgebra/Init.lean | 6 +- Mathlib/RingTheory/DividedPowers/Basic.lean | 10 +- Mathlib/RingTheory/DividedPowers/Padic.lean | 23 +- .../RingTheory/DividedPowers/RatAlgebra.lean | 6 +- .../RingTheory/DividedPowers/SubDPIdeal.lean | 25 +- Mathlib/RingTheory/Filtration.lean | 4 +- Mathlib/RingTheory/Finiteness/Finsupp.lean | 4 +- .../FractionalIdeal/Operations.lean | 6 +- Mathlib/RingTheory/FreeCommRing.lean | 7 +- Mathlib/RingTheory/HahnSeries/Basic.lean | 16 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 14 +- Mathlib/RingTheory/Ideal/Operations.lean | 2 +- Mathlib/RingTheory/Ideal/Quotient/Basic.lean | 4 +- .../IntegralClosure/Algebra/Ideal.lean | 2 +- Mathlib/RingTheory/IntegralDomain.lean | 2 +- Mathlib/RingTheory/LaurentSeries.lean | 6 +- Mathlib/RingTheory/LocalRing/Module.lean | 6 +- .../RingTheory/Localization/Away/Basic.lean | 4 +- .../RingTheory/Localization/FractionRing.lean | 6 +- Mathlib/RingTheory/MvPolynomial/Groebner.lean | 2 +- .../MvPolynomial/IrreducibleQuadratic.lean | 2 +- .../MvPolynomial/MonomialOrder.lean | 4 +- .../Symmetric/FundamentalTheorem.lean | 13 +- .../MvPolynomial/WeightedHomogeneous.lean | 18 +- Mathlib/RingTheory/MvPowerSeries/Basic.lean | 16 +- .../RingTheory/MvPowerSeries/Derivative.lean | 6 +- Mathlib/RingTheory/MvPowerSeries/Equiv.lean | 8 +- .../RingTheory/MvPowerSeries/Evaluation.lean | 2 +- Mathlib/RingTheory/MvPowerSeries/Expand.lean | 18 +- Mathlib/RingTheory/MvPowerSeries/Inverse.lean | 12 +- .../RingTheory/MvPowerSeries/LexOrder.lean | 4 +- .../MvPowerSeries/NoZeroDivisors.lean | 4 +- Mathlib/RingTheory/MvPowerSeries/Order.lean | 18 +- .../RingTheory/MvPowerSeries/PiTopology.lean | 2 +- .../MvPowerSeries/Substitution.lean | 2 +- Mathlib/RingTheory/MvPowerSeries/Trunc.lean | 8 +- Mathlib/RingTheory/Nilpotent/Basic.lean | 4 +- Mathlib/RingTheory/NoetherNormalization.lean | 7 +- Mathlib/RingTheory/Norm/Transitivity.lean | 13 +- .../RingTheory/OrderOfVanishing/Basic.lean | 4 +- .../OreLocalization/NonZeroDivisors.lean | 2 +- Mathlib/RingTheory/Perfection.lean | 8 +- Mathlib/RingTheory/Polynomial/Basic.lean | 6 +- Mathlib/RingTheory/Polynomial/Content.lean | 6 +- .../Polynomial/Cyclotomic/Basic.lean | 10 +- .../Polynomial/Eisenstein/Criterion.lean | 2 +- .../Polynomial/Eisenstein/IsIntegral.lean | 2 +- .../Polynomial/IntegralNormalization.lean | 4 +- Mathlib/RingTheory/Polynomial/Pochhammer.lean | 2 +- .../Polynomial/Resultant/Basic.lean | 6 +- .../Polynomial/UniqueFactorization.lean | 2 +- .../UniversalFactorizationRing.lean | 10 +- Mathlib/RingTheory/PowerBasis.lean | 7 +- Mathlib/RingTheory/PowerSeries/Basic.lean | 22 +- Mathlib/RingTheory/PowerSeries/Catalan.lean | 4 +- .../RingTheory/PowerSeries/Derivative.lean | 4 +- Mathlib/RingTheory/PowerSeries/Inverse.lean | 10 +- Mathlib/RingTheory/PowerSeries/Order.lean | 12 +- Mathlib/RingTheory/PowerSeries/Schroder.lean | 2 +- .../RingTheory/PowerSeries/Substitution.lean | 8 +- Mathlib/RingTheory/PowerSeries/Trunc.lean | 8 +- .../PowerSeries/WeierstrassPreparation.lean | 20 +- Mathlib/RingTheory/PrincipalIdealDomain.lean | 2 +- .../RamificationInertia/Inertia.lean | 4 +- .../RamificationInertia/Ramification.lean | 4 +- .../RootsOfUnity/PrimitiveRoots.lean | 4 +- Mathlib/RingTheory/SimpleModule/Basic.lean | 4 +- .../Spectrum/Maximal/Localization.lean | 2 +- Mathlib/RingTheory/Trace/Basic.lean | 4 +- .../UniqueFactorizationDomain/Basic.lean | 4 +- .../UniqueFactorizationDomain/Defs.lean | 4 +- .../UniqueFactorizationDomain/FactorSet.lean | 14 +- .../UniqueFactorizationDomain/Moebius.lean | 4 +- .../UniqueFactorizationDomain/Nat.lean | 2 +- .../NormalizedFactors.lean | 4 +- Mathlib/RingTheory/Valuation/Basic.lean | 4 +- Mathlib/RingTheory/Valuation/RankOne.lean | 2 +- .../Valuation/ValuativeRel/Basic.lean | 6 +- Mathlib/RingTheory/WittVector/Identities.lean | 4 +- Mathlib/RingTheory/WittVector/InitTail.lean | 6 +- Mathlib/RingTheory/WittVector/IsPoly.lean | 6 +- Mathlib/RingTheory/WittVector/Truncated.lean | 2 +- .../RingTheory/WittVector/Verschiebung.lean | 6 +- .../RingTheory/WittVector/WittPolynomial.lean | 2 +- Mathlib/SetTheory/Cardinal/Arithmetic.lean | 6 +- Mathlib/SetTheory/Cardinal/Divisibility.lean | 2 +- Mathlib/SetTheory/Cardinal/NatCard.lean | 2 +- Mathlib/SetTheory/Cardinal/Order.lean | 2 +- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 4 +- Mathlib/SetTheory/Ordinal/Basic.lean | 2 +- .../SetTheory/Ordinal/CantorNormalForm.lean | 4 +- Mathlib/SetTheory/Ordinal/Exponential.lean | 4 +- Mathlib/SetTheory/Ordinal/Veblen.lean | 4 +- .../ComputeAsymptotics/Multiseries/Defs.lean | 2 +- Mathlib/Tactic/Lift.lean | 2 +- Mathlib/Tactic/Linter/Whitespace.lean | 2 +- Mathlib/Tactic/NormNum/LegendreSymbol.lean | 8 +- Mathlib/Tactic/NormNum/OfScientific.lean | 4 +- Mathlib/Testing/Plausible/Functions.lean | 4 +- .../Topology/Algebra/InfiniteSum/Basic.lean | 19 +- .../Topology/Algebra/InfiniteSum/Defs.lean | 8 +- .../Topology/Algebra/InfiniteSum/ENNReal.lean | 7 +- .../Topology/Algebra/InfiniteSum/Group.lean | 2 +- .../Topology/Algebra/InfiniteSum/NatInt.lean | 4 +- Mathlib/Topology/Algebra/Module/Equiv.lean | 2 +- Mathlib/Topology/Algebra/UniformField.lean | 6 +- .../Algebra/Valued/LocallyCompact.lean | 2 +- .../Topology/Algebra/Valued/ValuedField.lean | 10 +- Mathlib/Topology/Bases.lean | 6 +- Mathlib/Topology/Basic.lean | 2 +- .../Category/LightProfinite/Basic.lean | 4 +- .../Topology/Category/Profinite/Basic.lean | 4 +- .../Category/Profinite/CofilteredLimit.lean | 10 +- .../Category/Profinite/Nobeling/Basic.lean | 14 +- .../Category/Profinite/Nobeling/Span.lean | 13 +- .../Profinite/Nobeling/Successor.lean | 2 +- Mathlib/Topology/Category/Stonean/Basic.lean | 4 +- .../Category/TopCat/Limits/Cofiltered.lean | 4 +- .../Category/TopCat/Limits/Konig.lean | 3 +- .../Category/TopCat/Limits/Products.lean | 6 +- .../OnePoint/ProjectiveLine.lean | 6 +- .../Topology/Compactness/LocallyCompact.lean | 4 +- Mathlib/Topology/Connected/Basic.lean | 4 +- Mathlib/Topology/Constructions.lean | 4 +- .../ContinuousMap/CompactlySupported.lean | 4 +- Mathlib/Topology/Covering/Basic.lean | 14 +- .../Topology/EMetricSpace/PairReduction.lean | 6 +- .../EMetricSpace/VariationOnFromTo.lean | 10 +- .../Topology/FiberBundle/Trivialization.lean | 16 +- Mathlib/Topology/Homotopy/HSpaces.lean | 2 +- Mathlib/Topology/Homotopy/HomotopyGroup.lean | 8 +- Mathlib/Topology/Homotopy/Lifting.lean | 8 +- Mathlib/Topology/Instances/CantorSet.lean | 2 +- Mathlib/Topology/LocallyConstant/Basic.lean | 6 +- Mathlib/Topology/LocallyFinsupp.lean | 2 +- Mathlib/Topology/MetricSpace/Dilation.lean | 6 +- Mathlib/Topology/MetricSpace/Gluing.lean | 4 +- Mathlib/Topology/MetricSpace/Infsep.lean | 10 +- Mathlib/Topology/MetricSpace/PiNat.lean | 17 +- Mathlib/Topology/Metrizable/Uniformity.lean | 4 +- Mathlib/Topology/Order/LeftRightLim.lean | 2 +- Mathlib/Topology/Path.lean | 2 +- Mathlib/Topology/Piecewise.lean | 4 +- .../Semicontinuity/Hemicontinuity.lean | 2 +- .../Sheaves/SheafCondition/UniqueGluing.lean | 2 +- Mathlib/Topology/Sheaves/Skyscraper.lean | 58 ++-- .../UniformSpace/AbstractCompletion.lean | 4 +- Mathlib/Topology/UniformSpace/Completion.lean | 6 +- Mathlib/Topology/UniformSpace/Separation.lean | 6 +- Mathlib/Topology/VectorBundle/Basic.lean | 26 +- MathlibTest/LibraryRewrite.lean | 2 +- MathlibTest/Linter/Whitespace.lean | 4 +- MathlibTest/Util/CountHeartbeats.lean | 70 +--- lake-manifest.json | 18 +- lean-toolchain | 2 +- 731 files changed, 2780 insertions(+), 2730 deletions(-) diff --git a/Archive/Arithcc.lean b/Archive/Arithcc.lean index 954999af9f55b6..1aa569935e7ab9 100644 --- a/Archive/Arithcc.lean +++ b/Archive/Arithcc.lean @@ -262,7 +262,7 @@ theorem write_eq_implies_stateEq {t : Register} {v : Word} {ζ₁ ζ₂ : State} intro r hr obtain ⟨_, h⟩ := h specialize h r (lt_trans hr (Register.lt_succ_self _)) - rwa [if_neg (ne_of_lt hr)] at h + rwa [ite_eq_right (ne_of_lt hr)] at h set_option linter.flexible false in set_option linter.style.whitespace false in -- manual alignment is not recognised diff --git a/Archive/Examples/IfNormalization/WithoutAesop.lean b/Archive/Examples/IfNormalization/WithoutAesop.lean index 63a48089d0181b..24c9b1c2e8d2ab 100644 --- a/Archive/Examples/IfNormalization/WithoutAesop.lean +++ b/Archive/Examples/IfNormalization/WithoutAesop.lean @@ -60,7 +60,7 @@ def normalize' (l : AList (fun _ : ℕ => Bool)) : refine ⟨fun f => ?_, ?_, fun w b => ?_⟩ · simp only [eval, apply_ite, ite_eq_iff'] cases hfv : f v - · simp +contextual only [cond_false, h, he₁] + · simp +contextual only [Bool.cond_false, h, he₁] refine ⟨fun _ => ?_, fun _ => ?_⟩ · congr ext w @@ -74,7 +74,7 @@ def normalize' (l : AList (fun _ : ℕ => Bool)) : · subst h simp_all · simp_all - · simp only [cond_true, h, ht₁] + · simp only [Bool.cond_true, h, ht₁] refine ⟨fun _ => ?_, fun _ => ?_⟩ · congr ext w diff --git a/Archive/Imo/Imo2013Q1.lean b/Archive/Imo/Imo2013Q1.lean index c495c9dc7573c9..bc73647160bb08 100644 --- a/Archive/Imo/Imo2013Q1.lean +++ b/Archive/Imo/Imo2013Q1.lean @@ -59,7 +59,7 @@ theorem imo2013_q1 (n : ℕ+) (k : ℕ) : let m i := if i < pk then pm i else ⟨2 * t + 2 ^ pk.succ, arith_lemma pk t⟩ use m have hmpk : (m pk : ℚ) = 2 * t + 2 ^ pk.succ := by - have : m pk = ⟨2 * t + 2 ^ pk.succ, _⟩ := if_neg (irrefl pk); simp [this] + have : m pk = ⟨2 * t + 2 ^ pk.succ, _⟩ := ite_eq_right (irrefl pk); simp [this] calc ((1 : ℚ) + (2 ^ pk.succ - 1) / (n : ℚ) : ℚ) = 1 + (2 * 2 ^ pk - 1) / (2 * (t + 1) : ℕ) := by rw [ht, pow_succ'] @@ -77,7 +77,7 @@ theorem imo2013_q1 (n : ℕ+) (k : ℕ) : let m i := if i < pk then pm i else ⟨2 * t + 1, Nat.succ_pos _⟩ use m have hmpk : (m pk : ℚ) = 2 * t + 1 := by - have : m pk = ⟨2 * t + 1, _⟩ := if_neg (irrefl pk) + have : m pk = ⟨2 * t + 1, _⟩ := ite_eq_right (irrefl pk) simp [this] calc ((1 : ℚ) + (2 ^ pk.succ - 1) / ↑n : ℚ) = 1 + (2 * 2 ^ pk - 1) / (2 * t + 1 : ℕ) := by diff --git a/Archive/Imo/Imo2024Q5.lean b/Archive/Imo/Imo2024Q5.lean index 24017a321eed86..d44b219c427d0a 100644 --- a/Archive/Imo/Imo2024Q5.lean +++ b/Archive/Imo/Imo2024Q5.lean @@ -302,14 +302,14 @@ lemma Path.tail_induction {motive : Path N → Prop} (ind : ∀ p, motive p.tail case cons head tail hi => by_cases h : (p'.cells[1]'p'.one_lt_length_cells).1 = 0 · refine ind p' ?_ - simp_rw [Path.tail, if_pos h, p', List.tail_cons] + simp_rw [Path.tail, ite_eq_left h, p', List.tail_cons] exact hi _ _ _ _ · exact base p' h lemma Path.tail_findFstEq (p : Path N) {r : Fin (N + 2)} (hr : r ≠ 0) : p.tail.findFstEq r = p.findFstEq r := by by_cases h : (p.cells[1]'p.one_lt_length_cells).1 = 0 - · simp_rw [Path.tail, if_pos h] + · simp_rw [Path.tail, ite_eq_left h] nth_rw 2 [Path.findFstEq] rcases p with ⟨cells, nonempty, head_first_row, last_last_row, valid_move_seq⟩ rcases cells with ⟨⟩ | ⟨head, tail⟩ @@ -317,19 +317,19 @@ lemma Path.tail_findFstEq (p : Path N) {r : Fin (N + 2)} (hr : r ≠ 0) : · simp only [List.head_cons] at head_first_row simp only [List.find?_cons, head_first_row, hr.symm, decide_false] rfl - · simp_rw [Path.tail, if_neg h] + · simp_rw [Path.tail, ite_eq_right h] lemma Path.tail_firstMonster (p : Path N) (m : MonsterData N) : p.tail.firstMonster m = p.firstMonster m := by by_cases h : (p.cells[1]'p.one_lt_length_cells).1 = 0 - · simp_rw [Path.tail, if_pos h] + · simp_rw [Path.tail, ite_eq_left h] nth_rw 2 [Path.firstMonster] rcases p with ⟨cells, nonempty, head_first_row, last_last_row, valid_move_seq⟩ rcases cells with ⟨⟩ | ⟨head, tail⟩ · simp at nonempty · simp only [List.head_cons] at head_first_row simp [m.notMem_monsterCells_of_fst_eq_zero head_first_row, firstMonster] - · simp_rw [Path.tail, if_neg h] + · simp_rw [Path.tail, ite_eq_right h] lemma Path.firstMonster_eq_of_findFstEq_mem {p : Path N} {m : MonsterData N} (h : p.findFstEq 1 ∈ m.monsterCells) : p.firstMonster m = some (p.findFstEq 1) := by @@ -890,7 +890,7 @@ lemma path2OfEdge0_firstMonster_eq_none_of_path1OfEdge0_firstMonster_eq_some (hN split_ifs at hix <;> simp [Prod.ext_iff, Fin.ext_iff] at hix <;> lia have hi' : (i : ℕ) ≠ 2 * N := by intro h - rw [← hix, fn1OfEdge0, dif_pos h] at hx + rw [← hix, fn1OfEdge0, dite_eq_left h] at hx have h' := MonsterData.le_N_of_mem_monsterCells hx simp at h' intro j @@ -900,7 +900,7 @@ lemma path2OfEdge0_firstMonster_eq_none_of_path1OfEdge0_firstMonster_eq_some (hN refine hnm _ ?_ simp only lia - · rw [fn2OfEdge0, dif_neg h] + · rw [fn2OfEdge0, dite_eq_right h] split_ifs with h' · have hx1 : 1 ≤ x.1 := by rw [Fin.le_def, Fin.val_one] @@ -929,7 +929,7 @@ lemma winningStrategy_play_one_eq_none_or_play_two_eq_none_of_edge_zero (hN : 2 rcases h with ⟨x, hx⟩ rw [winningStrategy_play_one] at hx rw [winningStrategy_play_two, ← hx, Option.getD_some] - rw [path1, dif_pos hc₁0] at hx + rw [path1, dite_eq_left hc₁0] at hx have h1 := Path.mem_of_firstMonster_eq_some (hx.symm) have hx2N : 2 ≤ (x.1 : ℕ) ∧ (x.1 : ℕ) ≤ N := by rw [path1OfEdge0, Path.ofFn_cells, List.mem_ofFn] at h1 @@ -959,7 +959,7 @@ lemma winningStrategy_play_one_eq_none_or_play_two_eq_none_of_edge_zero (hN : 2 simp at hc₁0 rw [fn1OfEdge0] split_ifs <;> simp <;> lia - rw [path2, if_pos hc₁0, path2OfEdge0Def, dif_pos hx2N] + rw [path2, ite_eq_left hc₁0, path2OfEdge0Def, dite_eq_left hx2N] exact path2OfEdge0_firstMonster_eq_none_of_path1OfEdge0_firstMonster_eq_some hN hx2N.1 hx2N.2 hc₁0 hx.symm @@ -975,8 +975,8 @@ lemma winningStrategy_play_one_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} ← Fin.rev_last, Fin.rev_inj] rw [Fin.ext_iff] exact hc₁N - simp_rw [winningStrategy_play_one hN, path1, path1OfEdgeN, dif_neg hc₁0, if_pos hc₁N, - dif_pos hc₁r0, ← Path.firstMonster_reflect, MonsterData.reflect_reflect] + simp_rw [winningStrategy_play_one hN, path1, path1OfEdgeN, dite_eq_right hc₁0, ite_eq_left hc₁N, + dite_eq_left hc₁r0, ← Path.firstMonster_reflect, MonsterData.reflect_reflect] set_option backward.isDefEq.respectTransparency false in lemma winningStrategy_play_two_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} @@ -990,9 +990,9 @@ lemma winningStrategy_play_two_of_edge_N (hN : 2 ≤ N) {m : MonsterData N} ← Fin.rev_last, Fin.rev_inj] rw [Fin.ext_iff] exact hc₁N - simp_rw [winningStrategy_play_two hN, path1, path1OfEdgeN, path2, path2OfEdgeNDef, if_neg hc₁0, - dif_neg hc₁0, if_pos hc₁N, dif_pos hc₁N, if_pos hc₁r0, dif_pos hc₁r0, - ← Path.firstMonster_reflect, MonsterData.reflect_reflect] + simp_rw [winningStrategy_play_two hN, path1, path1OfEdgeN, path2, path2OfEdgeNDef, + ite_eq_right hc₁0, dite_eq_right hc₁0, ite_eq_left hc₁N, dite_eq_left hc₁N, ite_eq_left hc₁r0, + dite_eq_left hc₁r0, ← Path.firstMonster_reflect, MonsterData.reflect_reflect] convert! rfl using 4 nth_rw 2 [← m.reflect_reflect] rw [Path.firstMonster_reflect] diff --git a/Archive/Imo/Imo2024Q6.lean b/Archive/Imo/Imo2024Q6.lean index 84fc79eb2061d0..bf3df55361f9e2 100644 --- a/Archive/Imo/Imo2024Q6.lean +++ b/Archive/Imo/Imo2024Q6.lean @@ -214,10 +214,10 @@ lemma fract_fExample (x : ℚ) : lemma floor_fExample (x : ℚ) : ⌊fExample x⌋ = if Int.fract x = 0 then x else ⌊x⌋ - 1 := by by_cases h : Int.fract x = 0 - · simp only [h, if_true, fExample, sub_zero, Int.floor_intCast] + · simp only [h, ite_true, fExample, sub_zero, Int.floor_intCast] rw [Int.fract, sub_eq_zero] at h exact h.symm - · simp only [h, if_false, fExample, sub_eq_add_neg, Int.floor_intCast_add, Int.cast_add, + · simp only [h, ite_false, fExample, sub_eq_add_neg, Int.floor_intCast_add, Int.cast_add, add_right_inj] suffices ⌊-Int.fract x⌋ = -1 from mod_cast this rw [Int.floor_eq_iff] @@ -233,7 +233,7 @@ lemma card_range_fExample : #(Set.range (fun x ↦ fExample x + fExample (-x))) by_cases h : Int.fract y = 0 · simp [fract_fExample, floor_fExample, h] · refine .inr ?_ - simp only [fract_fExample, floor_fExample, h, if_false, sub_add_sub_cancel, + simp only [fract_fExample, floor_fExample, h, ite_false, sub_add_sub_cancel, Int.fract_neg_eq_zero] rw [Int.fract_neg h, Int.floor_neg, Int.cast_neg, Int.ceil_eq_add_one_sub_fract h, ← Int.self_sub_fract] diff --git a/Archive/MiuLanguage/DecisionSuf.lean b/Archive/MiuLanguage/DecisionSuf.lean index 5cc67b253b8bfc..fe1e3f42c7e600 100644 --- a/Archive/MiuLanguage/DecisionSuf.lean +++ b/Archive/MiuLanguage/DecisionSuf.lean @@ -254,7 +254,7 @@ theorem count_I_eq_length_of_count_U_zero_and_neg_mem {ys : Miustr} (hu : count · -- case `x = M` gives a contradiction. exfalso; exact hm mem_cons_self · -- case `x = I` - rw [count_cons, beq_self_eq_true, if_pos rfl, length, succ_inj] + rw [count_cons, beq_self_eq_true, ite_eq_left rfl, length, succ_inj] apply hxs · simpa only [count] · rw [mem_cons, not_or] at hm; exact hm.2 @@ -311,7 +311,7 @@ theorem ind_hyp_suf (k : ℕ) (ys : Miustr) (hu : count U ys = succ k) (hdec : D rcases eq_append_cons_U_of_count_U_pos hu with ⟨as, bs, rfl⟩ use as, bs refine ⟨rfl, ?_, ?_, ?_⟩ - · simp_rw [count_append, count_cons, beq_self_eq_true, if_true, add_succ, beq_iff_eq, + · simp_rw [count_append, count_cons, beq_self_eq_true, ite_true, add_succ, beq_iff_eq, reduceCtorEq, reduceIte, add_zero, succ_inj] at hu rwa [count_append, count_append] · apply And.intro rfl diff --git a/Archive/Wiedijk100Theorems/AbelRuffini.lean b/Archive/Wiedijk100Theorems/AbelRuffini.lean index 36cad23bca78d9..a4585a2edbc7ec 100644 --- a/Archive/Wiedijk100Theorems/AbelRuffini.lean +++ b/Archive/Wiedijk100Theorems/AbelRuffini.lean @@ -81,7 +81,7 @@ theorem irreducible_Phi (p : ℕ) (hp : p.Prime) (hpa : p ∣ a) (hpb : p ∣ b) rw [degree_Phi] at hn; norm_cast at hn interval_cases n <;> simp +decide only [Φ, coeff_X_pow, coeff_C, Int.natCast_dvd_natCast.mpr, - hpb, if_true, coeff_C_mul, if_false, coeff_X_zero, hpa, coeff_add, zero_add, mul_zero, + hpb, ite_true, coeff_C_mul, ite_false, coeff_X_zero, hpa, coeff_add, zero_add, mul_zero, coeff_sub, add_zero, zero_sub, dvd_neg, neg_zero, dvd_mul_of_dvd_left] · simp only [degree_Phi, ← WithBot.coe_zero] decide diff --git a/Archive/Wiedijk100Theorems/BallotProblem.lean b/Archive/Wiedijk100Theorems/BallotProblem.lean index 77c891c0bd2927..0161e3ef1306b2 100644 --- a/Archive/Wiedijk100Theorems/BallotProblem.lean +++ b/Archive/Wiedijk100Theorems/BallotProblem.lean @@ -115,28 +115,28 @@ theorem counted_succ_succ (p q : ℕ) : obtain hlast | hlast := hl₂ (l.head hlnil) (List.head_mem hlnil) · refine Or.inl ⟨l.tail, ⟨?_, ?_, ?_⟩, ?_⟩ · rw [List.count_tail, hl₀, List.head?_eq_some_head hlnil, hlast, beq_self_eq_true, - if_pos rfl, Nat.add_sub_cancel] - · rw [List.count_tail, hl₁, List.head?_eq_some_head hlnil, hlast, if_neg (by decide), + ite_eq_left rfl, Nat.add_sub_cancel] + · rw [List.count_tail, hl₁, List.head?_eq_some_head hlnil, hlast, ite_eq_right (by decide), Nat.sub_zero] · exact fun x hx => hl₂ x (List.mem_of_mem_tail hx) · rw [← hlast, List.cons_head_tail] · refine Or.inr ⟨l.tail, ⟨?_, ?_, ?_⟩, ?_⟩ - · rw [List.count_tail, hl₀, List.head?_eq_some_head hlnil, hlast, if_neg (by decide), + · rw [List.count_tail, hl₀, List.head?_eq_some_head hlnil, hlast, ite_eq_right (by decide), Nat.sub_zero] · rw [List.count_tail, hl₁, List.head?_eq_some_head hlnil, hlast, beq_self_eq_true, - if_pos rfl, Nat.add_sub_cancel] + ite_eq_left rfl, Nat.add_sub_cancel] · exact fun x hx => hl₂ x (List.mem_of_mem_tail hx) · rw [← hlast, List.cons_head_tail] · rintro (⟨t, ⟨ht₀, ht₁, ht₂⟩, rfl⟩ | ⟨t, ⟨ht₀, ht₁, ht₂⟩, rfl⟩) · refine ⟨?_, ?_, ?_⟩ - · rw [List.count_cons, beq_self_eq_true, if_pos rfl, ht₀] - · rw [List.count_cons, if_neg, ht₁] + · rw [List.count_cons, beq_self_eq_true, ite_eq_left rfl, ht₀] + · rw [List.count_cons, ite_eq_right, ht₁] norm_num · simpa · refine ⟨?_, ?_, ?_⟩ - · rw [List.count_cons, if_neg, ht₀] + · rw [List.count_cons, ite_eq_right, ht₀] norm_num - · rw [List.count_cons, beq_self_eq_true, if_pos rfl, ht₁] + · rw [List.count_cons, beq_self_eq_true, ite_eq_left rfl, ht₁] · simpa theorem countedSequence_finite : ∀ p q : ℕ, (countedSequence p q).Finite diff --git a/Archive/Wiedijk100Theorems/BuffonsNeedle.lean b/Archive/Wiedijk100Theorems/BuffonsNeedle.lean index f5c08f4df5a0b0..656a3b476c2fcc 100644 --- a/Archive/Wiedijk100Theorems/BuffonsNeedle.lean +++ b/Archive/Wiedijk100Theorems/BuffonsNeedle.lean @@ -221,8 +221,8 @@ lemma buffon_integral : -(Real.sin θ * l) / 2 ≤ x ∧ x ≤ Real.sin θ * l / 2 := by rw [neg_div, and_comm, ← tsub_le_iff_right, zero_sub] by_cases h : x ≤ Real.sin θ * l / 2 ∧ 0 ≤ x + Real.sin θ * l / 2 - · rw [if_pos h, if_pos (this.mp h)] - · rw [if_neg h, if_neg (this.not.mp h)] + · rw [ite_eq_left h, ite_eq_left (this.mp h)] + · rw [ite_eq_right h, ite_eq_right (this.not.mp h)] simp_rw [indicator_eq, MeasureTheory.setIntegral_indicator measurableSet_Icc, Pi.one_apply] include hl in diff --git a/Archive/Wiedijk100Theorems/CubingACube.lean b/Archive/Wiedijk100Theorems/CubingACube.lean index 079d3ddb65844c..a215259de8e24e 100644 --- a/Archive/Wiedijk100Theorems/CubingACube.lean +++ b/Archive/Wiedijk100Theorems/CubingACube.lean @@ -283,18 +283,18 @@ theorem nontrivial_bcubes : (bcubes cs c).Nontrivial := by let p : Fin (n + 1) → ℝ := fun j' => if j' = j then c.b j + (cs i).w else c.b j' have hp : p ∈ c.bottom := by constructor - · simp only [p, if_neg hj] + · simp only [p, ite_eq_right hj] intro j'; simp only [tail, side_tail] by_cases hj' : j'.succ = j - · simp [p, if_pos, side, hj', hw', w_lt_w h v h2i] - · simp [p, if_neg hj'] + · simp [p, ite_eq_left, side, hj', hw', w_lt_w h v h2i] + · simp [p, ite_eq_right hj'] rcases v.1 hp with ⟨_, ⟨i', rfl⟩, hi'⟩ have h2i' : i' ∈ bcubes cs c := ⟨hi'.1.symm, v.2.1 i' hi'.1.symm ⟨tail p, hi'.2, hp.2⟩⟩ refine ⟨i, h2i, i', h2i', ?_⟩ rintro rfl apply not_le_of_gt (hi'.2 ⟨1, Nat.le_of_succ_le_succ h.three_le⟩).2 simp only [tail, Cube.tail, p] - rw [if_pos] + rw [ite_eq_left] · gcongr exact (hi.2 _).1 simp [j] @@ -389,7 +389,7 @@ theorem mi_not_onBoundary (j : Fin n) : ¬OnBoundary (mi_mem_bcubes : mi h v ∈ intro j₂ by_cases hj₂ : j₂ = j · simp [hj₂, hx] - simp only [hj₂, if_false]; apply tail_sub hi; apply b_mem_side + simp only [hj₂, ite_false]; apply tail_sub hi; apply b_mem_side rcases v.1 hp with ⟨_, ⟨i', rfl⟩, hi'⟩ have h2i' : i' ∈ bcubes cs c := ⟨hi'.1.symm, v.2.1 i' hi'.1.symm ⟨tail p, hi'.2, hp.2⟩⟩ have i_i' : i ≠ i' := by rintro rfl; simpa [i, p, side_tail, h2x] using hi'.2 j @@ -404,7 +404,7 @@ theorem mi_not_onBoundary (j : Fin n) : ¬OnBoundary (mi_mem_bcubes : mi h v ∈ simpa [p', bottom, toSet, tail, side_tail] intro j₂ by_cases hj₂ : j₂ = j'; · simpa [hj₂] using! tail_sub h2i' _ hx'.1 - simp only [if_false, hj₂]; apply tail_sub hi; apply b_mem_side + simp only [ite_false, hj₂]; apply tail_sub hi; apply b_mem_side rcases v.1 hp' with ⟨_, ⟨i'', rfl⟩, hi''⟩ have h2i'' : i'' ∈ bcubes cs c := ⟨hi''.1.symm, v.2.1 i'' hi''.1.symm ⟨tail p', hi''.2, hp'.2⟩⟩ have i'_i'' : i' ≠ i'' := by @@ -463,12 +463,12 @@ theorem valley_mi : Valley cs (cs (mi h v)).shiftUp := by ⟨w, hw, h2w, h3w⟩ refine ⟨fun j' => if j' = j then w else p2 j', ?_, ?_, ?_⟩ · intro j'; by_cases h : j' = j - · simp only [if_pos h]; exact h ▸ h3w - · simp only [if_neg h]; exact hp2 j' - · simp only [toSet, not_forall, mem_ofPred_eq]; use j; rw [if_pos rfl]; convert! h2w + · simp only [ite_eq_left h]; exact h ▸ h3w + · simp only [ite_eq_right h]; exact hp2 j' + · simp only [toSet, not_forall, mem_ofPred_eq]; use j; rw [ite_eq_left rfl]; convert! h2w · intro j'; by_cases h : j' = j - · simp only [if_pos h, side_tail]; exact h ▸ hw - · simp only [if_neg h]; apply hi.2; apply h2p2 + · simp only [ite_eq_left h, side_tail]; exact h ▸ hw + · simp only [ite_eq_right h]; apply hi.2; apply h2p2 rcases this with ⟨p3, h1p3, h2p3, h3p3⟩ let p := @cons n (fun _ => ℝ) (c.b 0) p3 have hp : p ∈ c.bottom := by refine ⟨rfl, ?_⟩; rwa [tail_cons] diff --git a/Archive/Wiedijk100Theorems/FriendshipGraphs.lean b/Archive/Wiedijk100Theorems/FriendshipGraphs.lean index 506a8f6f9f8585..1eb229e58c4635 100644 --- a/Archive/Wiedijk100Theorems/FriendshipGraphs.lean +++ b/Archive/Wiedijk100Theorems/FriendshipGraphs.lean @@ -125,7 +125,7 @@ theorem adjMatrix_sq_of_regular (hd : G.IsRegularOfDegree d) : G.adjMatrix R ^ 2 = of fun v w => if v = w then (d : R) else (1 : R) := by ext (v w); by_cases h : v = w · rw [h, sq, adjMatrix_mul_self_apply_self, hd]; simp - · rw [adjMatrix_sq_of_ne R hG h, of_apply, if_neg h] + · rw [adjMatrix_sq_of_ne R hG h, of_apply, ite_eq_right h] open scoped Classical in include hG in @@ -183,7 +183,7 @@ theorem card_of_regular (hd : G.IsRegularOfDegree d) : d + (Fintype.card V - 1) have v := Classical.arbitrary V trans ((G.adjMatrix ℕ ^ 2) *ᵥ (fun _ => 1)) v · rw [adjMatrix_sq_of_regular hG hd, mulVec, dotProduct, ← insert_erase (mem_univ v)] - simp only [sum_insert, mul_one, if_true, Nat.cast_id, mem_erase, not_true, + simp only [sum_insert, mul_one, ite_true, Nat.cast_id, mem_erase, not_true, Ne, not_false_iff, add_right_inj, false_and, of_apply] rw [Finset.sum_const_nat, card_erase_of_mem (mem_univ v), mul_one]; · rfl intro x hx; simp [(ne_of_mem_erase hx).symm] diff --git a/Cache/Test.lean b/Cache/Test.lean index dd8e7eebf19d11..2d1681e85d4c9f 100644 --- a/Cache/Test.lean +++ b/Cache/Test.lean @@ -67,7 +67,7 @@ open Cache.Requests initialize failures : IO.Ref Nat ← IO.mkRef 0 /-- A single named assertion. On failure, prints details and bumps the counter. -/ -def assert (name : String) (cond : Bool) : IO Unit := do +def assertTrue (name : String) (cond : Bool) : IO Unit := do if cond then IO.println s!" ok: {name}" else @@ -123,18 +123,18 @@ def test_Container_name : IO Unit := do def test_Container_parse : IO Unit := do IO.println "Container.parse?:" -- Every canonical name round-trips back to its enum case. - assert "master parses" (Container.parse? "master" == some .master) - assert "forks parses" (Container.parse? "forks" == some .forks) - assert "nightly-testing parses" (Container.parse? "nightly-testing" == some .nightlyTesting) - assert "pr-toolchain-tests parses" + assertTrue "master parses" (Container.parse? "master" == some .master) + assertTrue "forks parses" (Container.parse? "forks" == some .forks) + assertTrue "nightly-testing parses" (Container.parse? "nightly-testing" == some .nightlyTesting) + assertTrue "pr-toolchain-tests parses" (Container.parse? "pr-toolchain-tests" == some .prToolchainTests) - assert "legacy parses" (Container.parse? "legacy" == some .legacy) + assertTrue "legacy parses" (Container.parse? "legacy" == some .legacy) -- Matching is case-insensitive, so `--container=Master` canonicalizes too. - assert "case-insensitive" (Container.parse? "Master" == some .master) + assertTrue "case-insensitive" (Container.parse? "Master" == some .master) -- An unknown name returns `none` so `--container=bogus` errors out rather than -- defaulting to some container the user didn't ask for. - assert "unknown rejected" (Container.parse? "bogus" == none) - assert "empty rejected" (Container.parse? "" == none) + assertTrue "unknown rejected" (Container.parse? "bogus" == none) + assertTrue "empty rejected" (Container.parse? "" == none) /-- The Azure URL each container resolves to: `mathlib4-{name}` for the trust-level containers, bare `mathlib4` for `legacy`. These URLs go into every @@ -170,23 +170,23 @@ container's writers stay on non-colliding paths: -/ def test_Container_flatPath : IO Unit := do IO.println "Container.flatPath:" - assert "master is flat for the canonical repo" + assertTrue "master is flat for the canonical repo" (Container.master.flatPath MATHLIBREPO == true) - assert "master is flat for a fork repo too" + assertTrue "master is flat for a fork repo too" (Container.master.flatPath "alice/mathlib4" == true) - assert "legacy is flat for the canonical repo" + assertTrue "legacy is flat for the canonical repo" (Container.legacy.flatPath MATHLIBREPO == true) - assert "legacy is prefixed for a fork repo" + assertTrue "legacy is prefixed for a fork repo" (Container.legacy.flatPath "alice/mathlib4" == false) - assert "forks is prefixed for the canonical repo" + assertTrue "forks is prefixed for the canonical repo" (Container.forks.flatPath MATHLIBREPO == false) - assert "forks is prefixed for a fork repo" + assertTrue "forks is prefixed for a fork repo" (Container.forks.flatPath "alice/mathlib4" == false) - assert "nightly-testing is prefixed for the nightly-testing repo" + assertTrue "nightly-testing is prefixed for the nightly-testing repo" (Container.nightlyTesting.flatPath NIGHTLY_TESTING_REPO == false) - assert "nightly-testing is prefixed for the canonical repo" + assertTrue "nightly-testing is prefixed for the canonical repo" (Container.nightlyTesting.flatPath MATHLIBREPO == false) - assert "pr-toolchain-tests is prefixed for the nightly-testing repo" + assertTrue "pr-toolchain-tests is prefixed for the nightly-testing repo" (Container.prToolchainTests.flatPath NIGHTLY_TESTING_REPO == false) end ContainerModel @@ -206,20 +206,20 @@ the trust boundary. Key points the tests pin: -/ def test_defaultContainersForRepo : IO Unit := do IO.println "defaultContainersForRepo:" - assert "canonical repo → [master, legacy]" + assertTrue "canonical repo → [master, legacy]" (defaultContainersForRepo MATHLIBREPO == [.master, .legacy]) - assert "nightly-testing repo → [nightly-testing, forks, legacy], no pr-toolchain-tests" + assertTrue "nightly-testing repo → [nightly-testing, forks, legacy], no pr-toolchain-tests" (defaultContainersForRepo NIGHTLY_TESTING_REPO == [.nightlyTesting, .forks, .legacy]) - assert "fork repo → [master, forks, legacy]" + assertTrue "fork repo → [master, forks, legacy]" (defaultContainersForRepo "alice/mathlib4" == [.master, .forks, .legacy]) - assert "unknown repo falls back to the fork chain" + assertTrue "unknown repo falls back to the fork chain" (defaultContainersForRepo "some/other-repo" == [.master, .forks, .legacy]) -- Every chain ends with `legacy`; dropping it would quietly shrink hit rates. - assert "fork chain ends with legacy" + assertTrue "fork chain ends with legacy" ((defaultContainersForRepo "alice/mathlib4").getLast? == some .legacy) - assert "canonical chain ends with legacy" + assertTrue "canonical chain ends with legacy" ((defaultContainersForRepo MATHLIBREPO).getLast? == some .legacy) - assert "nightly-testing chain ends with legacy" + assertTrue "nightly-testing chain ends with legacy" ((defaultContainersForRepo NIGHTLY_TESTING_REPO).getLast? == some .legacy) end PerRepoAllowlist @@ -303,24 +303,24 @@ or empty input fails the whole list rather than degrading to a default, so a typo surfaces instead of silently changing where the cache is read. -/ def test_parseCacheFromList : IO Unit := do IO.println "parseCacheFromList:" - assert "single container" + assertTrue "single container" (parseCacheFromList "master" == some [.master]) - assert "two containers" + assertTrue "two containers" (parseCacheFromList "master,forks" == some [.master, .forks]) - assert "all five containers" + assertTrue "all five containers" (parseCacheFromList "master,forks,nightly-testing,pr-toolchain-tests,legacy" == some [.master, .forks, .nightlyTesting, .prToolchainTests, .legacy]) - assert "master,legacy" + assertTrue "master,legacy" (parseCacheFromList "master,legacy" == some [.master, .legacy]) -- Order is preserved, not normalized: `forks,master` reverses the priority. - assert "preserves the given order" + assertTrue "preserves the given order" (parseCacheFromList "forks,master" == some [.forks, .master]) -- Whitespace around commas is tolerated, so the flag survives shell expansion. - assert "whitespace around names is tolerated" + assertTrue "whitespace around names is tolerated" (parseCacheFromList " master , forks " == some [.master, .forks]) - assert "one unknown name rejects the whole list" + assertTrue "one unknown name rejects the whole list" (parseCacheFromList "master,bogus" == none) - assert "empty input is rejected" + assertTrue "empty input is rejected" (parseCacheFromList "" == none) end ParseCacheFromList @@ -334,20 +334,20 @@ direct remote (e.g. `gh pr checkout`). Unparseable input returns `none`, and the caller falls back to `MATHLIBREPO`. -/ def test_extractRepoFromUrl : IO Unit := do IO.println "extractRepoFromUrl:" - assert "ssh URL with .git suffix" + assertTrue "ssh URL with .git suffix" (extractRepoFromUrl "git@github.com:alice/mathlib4.git" == some "alice/mathlib4") - assert "ssh URL without .git suffix" + assertTrue "ssh URL without .git suffix" (extractRepoFromUrl "git@github.com:alice/mathlib4" == some "alice/mathlib4") - assert "https URL with .git suffix" + assertTrue "https URL with .git suffix" (extractRepoFromUrl "https://github.com/alice/mathlib4.git" == some "alice/mathlib4") - assert "https URL without .git suffix" + assertTrue "https URL without .git suffix" (extractRepoFromUrl "https://github.com/alice/mathlib4" == some "alice/mathlib4") -- A hyphenated owner is part of the repo identity and must survive intact. - assert "hyphenated owner is preserved" + assertTrue "hyphenated owner is preserved" (extractRepoFromUrl "https://github.com/leanprover-community/mathlib4.git" == some "leanprover-community/mathlib4") - assert "empty input returns none" + assertTrue "empty input returns none" (extractRepoFromUrl "" == none) - assert "a token with no slash or colon returns none" + assertTrue "a token with no slash or colon returns none" (extractRepoFromUrl "norepo" == none) end ExtractRepoFromUrl @@ -359,22 +359,22 @@ segment must be `pr`, last must be a Nat". -/ def test_extractPRNumber : IO Unit := do IO.println "extractPRNumber:" -- The shape git produces for fetched PR refs. - assert "standard PR ref format" + assertTrue "standard PR ref format" (extractPRNumber "refs/remotes/upstream/pr/1234" == some 1234) -- Branch refs are not PR refs; must not match. - assert "master branch returns none" + assertTrue "master branch returns none" (extractPRNumber "refs/heads/master" == none) -- Minimal `pr/N` is also accepted — the parser only inspects the trailing two segments. - assert "simple pr number" + assertTrue "simple pr number" (extractPRNumber "pr/42" == some 42) -- The tail must be a valid Nat; non-numeric tails are rejected (no partial parsing). - assert "non-numeric tail returns none" + assertTrue "non-numeric tail returns none" (extractPRNumber "refs/remotes/upstream/pr/foo" == none) -- `0` is a valid Nat; pin down that it isn't special-cased. - assert "zero PR number" + assertTrue "zero PR number" (extractPRNumber "refs/remotes/upstream/pr/0" == some 0) -- A numeric tail without the `pr/` parent must not be mistaken for a PR ref. - assert "missing pr segment returns none" + assertTrue "missing pr segment returns none" (extractPRNumber "refs/remotes/upstream/42" == none) end ExtractPRNumber @@ -387,17 +387,17 @@ a download — where `.part` must be stripped before `.ltar`. A regression here corrupts cache lookups, so both suffixes and a non-hex stem are covered. -/ def test_hashFromFileName : IO Unit := do IO.println "hashFromFileName:" - assert "plain .ltar file" + assertTrue "plain .ltar file" (hashFromFileName "abc123def.ltar" == String.parseHexToUInt64? "000000abc123def") - assert "in-flight .ltar.part file strips both suffixes" + assertTrue "in-flight .ltar.part file strips both suffixes" (hashFromFileName "abc123def.ltar.part" == String.parseHexToUInt64? "000000abc123def") - assert "full 16-digit hex stem" + assertTrue "full 16-digit hex stem" (hashFromFileName "deadbeef00112233.ltar" == String.parseHexToUInt64? "deadbeef00112233") -- A non-hex stem returns none rather than a garbage hash. - assert "non-hex stem returns none" + assertTrue "non-hex stem returns none" (hashFromFileName "nothexa.ltar" == none) -- Directory components are ignored; only the basename's stem is parsed. - assert "leading path is ignored" + assertTrue "leading path is ignored" (hashFromFileName "/path/to/abc123def.ltar" == String.parseHexToUInt64? "000000abc123def") end HashFromFileName @@ -409,20 +409,20 @@ Used to decide whether to short-circuit `git remote get-url` lookups. -/ def test_isRemoteURL : IO Unit := do IO.println "isRemoteURL:" -- The three protocols accepted by the cache tool. - assert "https URL is remote" + assertTrue "https URL is remote" (isRemoteURL "https://github.com/alice/mathlib4.git" == true) - assert "http URL is remote" + assertTrue "http URL is remote" (isRemoteURL "http://github.com/alice/mathlib4" == true) - assert "ssh URL is remote" + assertTrue "ssh URL is remote" (isRemoteURL "git@github.com:alice/mathlib4.git" == true) -- Absolute and relative local paths must be classified as not-remote so they -- get routed through `git remote get-url`. - assert "local path is not remote" + assertTrue "local path is not remote" (isRemoteURL "/local/path/to/repo" == false) - assert "relative path is not remote" + assertTrue "relative path is not remote" (isRemoteURL "./local/repo" == false) -- Defensive — empty input shouldn't accidentally match the predicate. - assert "empty string is not remote" + assertTrue "empty string is not remote" (isRemoteURL "" == false) end IsRemoteURL @@ -461,11 +461,11 @@ read a file back as a different hash, causing misses or collisions. -/ def test_hash_roundtrip : IO Unit := do IO.println "hash roundtrip (asLTar then hashFromFileName):" let h1 : UInt64 := 0xdeadbeef00112233 - assert "full-width hash round-trips" + assertTrue "full-width hash round-trips" (hashFromFileName h1.asLTar == some h1) -- A short hash exercises both pad-on-write and trim-on-read. let h2 : UInt64 := 0xabc123 - assert "padded hash round-trips" + assertTrue "padded hash round-trips" (hashFromFileName h2.asLTar == some h2) end RoundTrip @@ -511,18 +511,18 @@ def test_getRepoScope : IO Unit := do let saved ← scopeOverride.get try scopeOverride.set none - assert "no scope set returns none" ((← withSuppressedOutput getRepoScope) == none) + assertTrue "no scope set returns none" ((← withSuppressedOutput getRepoScope) == none) scopeOverride.set (some "abc123") - assert "the flag value is returned" ((← withSuppressedOutput getRepoScope) == some "abc123") + assertTrue "the flag value is returned" ((← withSuppressedOutput getRepoScope) == some "abc123") -- The flag value is returned as-is, without trimming or normalization. scopeOverride.set (some "deadbeef") - assert "the flag value is returned verbatim" + assertTrue "the flag value is returned verbatim" ((← withSuppressedOutput getRepoScope) == some "deadbeef") scopeOverride.set none - assert "clearing the flag returns none" ((← withSuppressedOutput getRepoScope) == none) + assertTrue "clearing the flag returns none" ((← withSuppressedOutput getRepoScope) == none) finally scopeOverride.set saved @@ -551,11 +551,11 @@ def test_shouldWarnNonDefaultScope : IO Unit := do try scopeOverride.set none - assert "plain get with no flags does not warn" + assertTrue "plain get with no flags does not warn" (!(← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO))) scopeOverride.set (some "abc123") - assert "a set scope warns" + assertTrue "a set scope warns" (← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO)) scopeOverride.set none @@ -564,44 +564,44 @@ def test_shouldWarnNonDefaultScope : IO Unit := do let head? ← try some <$> withSuppressedOutput getGitCommitHash catch _ => pure none if let some head := head? then scopeOverride.set (some head) - assert "a scope equal to HEAD does not warn" + assertTrue "a scope equal to HEAD does not warn" (!(← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO))) scopeOverride.set none -- --cache-from equal to the repo's default chain is not widening. let mathlibDefault := defaultContainersForRepo MATHLIBREPO - assert "--cache-from equal to the default does not warn" + assertTrue "--cache-from equal to the default does not warn" (!(← withSuppressedOutput (shouldWarnNonDefaultScope none none (some mathlibDefault) MATHLIBREPO))) - assert "--cache-from widening the chain warns" + assertTrue "--cache-from widening the chain warns" (← withSuppressedOutput (shouldWarnNonDefaultScope none none (some [.master, .forks, .legacy]) MATHLIBREPO)) -- A fork checkout (remote ≠ resolved repo) stays silent without an explicit --repo. - assert "a fork checkout without --repo does not warn" + assertTrue "a fork checkout without --repo does not warn" (!(← withSuppressedOutput (shouldWarnNonDefaultScope none (some "alice/mathlib4") none "alice/mathlib4"))) - assert "--repo differing from the remote warns" + assertTrue "--repo differing from the remote warns" (← withSuppressedOutput (shouldWarnNonDefaultScope (some "bob/mathlib4") (some "alice/mathlib4") none "bob/mathlib4")) - assert "--repo matching the remote does not warn" + assertTrue "--repo matching the remote does not warn" (!(← withSuppressedOutput (shouldWarnNonDefaultScope (some "alice/mathlib4") (some "alice/mathlib4") none "alice/mathlib4"))) -- With no detectable remote there is nothing to compare --repo against. - assert "--repo with no detectable remote does not warn" + assertTrue "--repo with no detectable remote does not warn" (!(← withSuppressedOutput (shouldWarnNonDefaultScope (some "bob/mathlib4") none none "bob/mathlib4"))) -- `--unsafe` (any window) always warns; it walks several untrusted scopes. - assert "--unsafe warns regardless of other inputs" + assertTrue "--unsafe warns regardless of other inputs" (← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO (unsafeWindow? := some 5))) - assert "no --unsafe (none window) does not warn on its own" + assertTrue "no --unsafe (none window) does not warn on its own" (!(← withSuppressedOutput (shouldWarnNonDefaultScope none none none MATHLIBREPO (unsafeWindow? := none)))) finally @@ -619,16 +619,16 @@ def test_getNonDefaultScopeReason : IO Unit := do -- A placeholder rather than a crash if nothing matches. let reason ← withSuppressedOutput (getNonDefaultScopeReason none none none MATHLIBREPO) - assert "no trigger yields a placeholder reason" (reason == "unknown reason") + assertTrue "no trigger yields a placeholder reason" (reason == "unknown reason") scopeOverride.set (some "abc123") let reason ← withSuppressedOutput (getNonDefaultScopeReason none none none MATHLIBREPO) - assert "scope reason names the flag and SHA" + assertTrue "scope reason names the flag and SHA" (reason == "--scope=abc123 (explicit per-commit scope)") -- Scope outranks cache-from when both apply. let reason ← withSuppressedOutput (getNonDefaultScopeReason none none (some [.forks]) MATHLIBREPO) - assert "scope is reported ahead of cache-from" + assertTrue "scope is reported ahead of cache-from" (reason == "--scope=abc123 (explicit per-commit scope)") scopeOverride.set none @@ -639,24 +639,24 @@ def test_getNonDefaultScopeReason : IO Unit := do scopeOverride.set (some head) let reason ← withSuppressedOutput (getNonDefaultScopeReason none none (some [.forks, .legacy]) MATHLIBREPO) - assert "a HEAD scope yields the cache-from reason" + assertTrue "a HEAD scope yields the cache-from reason" (reason == "--cache-from=forks, legacy (explicit container override)") scopeOverride.set none let reason ← withSuppressedOutput (getNonDefaultScopeReason none none (some [.forks, .legacy]) MATHLIBREPO) - assert "cache-from reason names the container list" + assertTrue "cache-from reason names the container list" (reason == "--cache-from=forks, legacy (explicit container override)") let reason ← withSuppressedOutput (getNonDefaultScopeReason (some "bob/mathlib4") (some "alice/mathlib4") none "bob/mathlib4") - assert "repo reason names the override and the detected remote" + assertTrue "repo reason names the override and the detected remote" (reason == "--repo=bob/mathlib4 (overrides detected git remote: alice/mathlib4)") -- --cache-from equal to the default is not a trigger, so no reason applies. let reason ← withSuppressedOutput (getNonDefaultScopeReason none none (some [.master, .legacy]) MATHLIBREPO) - assert "cache-from equal to the default yields the placeholder" + assertTrue "cache-from equal to the default yields the placeholder" (reason == "unknown reason") -- `--unsafe` outranks every other trigger and names its window. @@ -664,7 +664,7 @@ def test_getNonDefaultScopeReason : IO Unit := do let reason ← withSuppressedOutput (getNonDefaultScopeReason (some "bob/mathlib4") (some "alice/mathlib4") (some [.forks]) "bob/mathlib4" (unsafeWindow? := some 7)) - assert "unsafe reason names the window and outranks scope/cache-from/repo" + assertTrue "unsafe reason names the window and outranks scope/cache-from/repo" (reason == "--unsafe (automatic walk over up to 7 fork commit(s); trusting whoever built them)") scopeOverride.set none finally @@ -678,7 +678,7 @@ returns `none` with no probe. -/ def test_findMostRecentSHAWithCache : IO Unit := do IO.println "findMostRecentSHAWithCache:" let result ← withSuppressedOutput (findMostRecentSHAWithCache [] MATHLIBREPO) - assert "empty SHA list returns none without probing" (result == none) + assertTrue "empty SHA list returns none without probing" (result == none) /-- `findRecentSHAsWithCache` collects up to `limit` marked SHAs. The non-empty cases hit the network (a marker HEAD probe per SHA); here we pin that an empty @@ -686,9 +686,9 @@ candidate list returns `[]` for any limit, with no probe. -/ def test_findRecentSHAsWithCache : IO Unit := do IO.println "findRecentSHAsWithCache:" let result ← withSuppressedOutput (findRecentSHAsWithCache [] MATHLIBREPO 5) - assert "empty SHA list returns [] without probing" (result == []) + assertTrue "empty SHA list returns [] without probing" (result == []) let result ← withSuppressedOutput (findRecentSHAsWithCache [] MATHLIBREPO 0) - assert "limit 0 returns [] without probing" (result == []) + assertTrue "limit 0 returns [] without probing" (result == []) end NonDefaultScope @@ -718,21 +718,21 @@ def test_getRemoteRepo_gitFallback : IO Unit := do -- The try...catch in getRemoteRepo must intercept it and return none. let fakePath := "/tmp/surely-nonexistent-mathlib-cache-test-xyz-9999999" let r1 ← withSuppressedOutput (getRemoteRepo fakePath) - assert "getRemoteRepo returns none when git throws (nonexistent cwd)" (r1 == none) + assertTrue "getRemoteRepo returns none when git throws (nonexistent cwd)" (r1 == none) -- Case 2: existing directory that is not a git repo (git returns exit 128). -- This exercises the exit-code fallback path that predates the try...catch. let r2 ← withSuppressedOutput (getRemoteRepo "/tmp") - assert "getRemoteRepo returns none in a non-git directory" (r2 == none) + assertTrue "getRemoteRepo returns none in a non-git directory" (r2 == none) -- resolveRepo propagates the fallback correctly: -- detected? = none, resolved = MATHLIBREPO → master-only chain. let (detected?, resolved) ← withSuppressedOutput (resolveRepo none fakePath) - assert "resolveRepo detected? is none on git failure" (detected? == none) - assert "resolveRepo falls back to MATHLIBREPO on git failure" (resolved == MATHLIBREPO) - assert "fallback chain includes master" + assertTrue "resolveRepo detected? is none on git failure" (detected? == none) + assertTrue "resolveRepo falls back to MATHLIBREPO on git failure" (resolved == MATHLIBREPO) + assertTrue "fallback chain includes master" ((defaultContainersForRepo resolved).contains .master) - assert "fallback chain excludes forks (no fork container for dependency builds)" + assertTrue "fallback chain excludes forks (no fork container for dependency builds)" (!(defaultContainersForRepo resolved).contains .forks) /-- `headIsAncestorOfMaster` gates the uncached-fork-HEAD note: when HEAD is @@ -757,10 +757,10 @@ def test_headIsAncestorOfMaster_gitFallback : IO Unit := do IO.println "headIsAncestorOfMaster git fallback:" let fakePath := "/tmp/surely-nonexistent-mathlib-cache-test-xyz-9999999" let r1 ← withSuppressedOutput (headIsAncestorOfMaster fakePath) - assert "headIsAncestorOfMaster returns false when git throws (nonexistent cwd)" + assertTrue "headIsAncestorOfMaster returns false when git throws (nonexistent cwd)" (r1 == false) let r2 ← withSuppressedOutput (headIsAncestorOfMaster "/tmp") - assert "headIsAncestorOfMaster returns false in a non-git directory" (r2 == false) + assertTrue "headIsAncestorOfMaster returns false in a non-git directory" (r2 == false) end GitFallback @@ -782,45 +782,45 @@ unknown options or reject known ones. -/ def test_isKnownOpt : IO Unit := do IO.println "isKnownOpt:" -- Every named option is recognized when used with `=value` form. - assert "--repo=foo is known" (isKnownOpt "--repo=foo") - assert "--cache-from=master is known" (isKnownOpt "--cache-from=master") - assert "--scope=HEAD is known" (isKnownOpt "--scope=HEAD") - assert "--container=master is known" (isKnownOpt "--container=master") - assert "--staging-dir=/tmp is known" (isKnownOpt "--staging-dir=/tmp") - assert "--unsafe-window=5 is known" (isKnownOpt "--unsafe-window=5") + assertTrue "--repo=foo is known" (isKnownOpt "--repo=foo") + assertTrue "--cache-from=master is known" (isKnownOpt "--cache-from=master") + assertTrue "--scope=HEAD is known" (isKnownOpt "--scope=HEAD") + assertTrue "--container=master is known" (isKnownOpt "--container=master") + assertTrue "--staging-dir=/tmp is known" (isKnownOpt "--staging-dir=/tmp") + assertTrue "--unsafe-window=5 is known" (isKnownOpt "--unsafe-window=5") -- Empty value passes recognition (parseNamedOpt returns the empty string -- for these — callers decide whether to treat that as an error). - assert "--scope= (empty value) is known" (isKnownOpt "--scope=") + assertTrue "--scope= (empty value) is known" (isKnownOpt "--scope=") -- Flags use the bare `--name` form, no `=`. - assert "--help (no =) is known" (isKnownOpt "--help") - assert "--unsafe (no =) is known" (isKnownOpt "--unsafe") + assertTrue "--help (no =) is known" (isKnownOpt "--help") + assertTrue "--unsafe (no =) is known" (isKnownOpt "--unsafe") -- `--unsafe` is a flag, not a named option: the `=value` form is a user error. - assert "--unsafe=5 is NOT known (flags don't take values)" + assertTrue "--unsafe=5 is NOT known (flags don't take values)" (!isKnownOpt "--unsafe=5") -- A typo on a known option name should fail recognition, not be silently -- accepted. This is the regression-guard: if `--scoop=` were accepted, the -- user's `--scope=` would be silently dropped and reads would fall back to -- the default chain with no warning. - assert "--scoop=foo (typo on scope) is NOT known" (!isKnownOpt "--scoop=foo") - assert "--bogus=foo (unknown name) is NOT known" (!isKnownOpt "--bogus=foo") + assertTrue "--scoop=foo (typo on scope) is NOT known" (!isKnownOpt "--scoop=foo") + assertTrue "--bogus=foo (unknown name) is NOT known" (!isKnownOpt "--bogus=foo") -- A named option without `=` must NOT be accepted as a flag — `--scope` -- (no value) is a user error, distinct from the `--help` flag form. - assert "--scope (no =) is NOT known (named opts require value)" + assertTrue "--scope (no =) is NOT known (named opts require value)" (!isKnownOpt "--scope") -- Symmetric: a flag with `=` must NOT be accepted as a named opt. - assert "--help=foo is NOT known (flags don't take values)" + assertTrue "--help=foo is NOT known (flags don't take values)" (!isKnownOpt "--help=foo") -- A bare positional doesn't even look like an option. The cache binary -- splits args by `startsWith "--"` before consulting `isKnownOpt`, so this -- case should never reach us, but we pin it anyway for safety. - assert "bare positional 'scope' is NOT known" (!isKnownOpt "scope") + assertTrue "bare positional 'scope' is NOT known" (!isKnownOpt "scope") /-- `parseNamedOpt` extracts the value of a `--name=value` option from a list of args. The rules tests pin: @@ -837,32 +837,32 @@ def test_parseNamedOpt : IO Unit := do IO.println "parseNamedOpt:" -- Empty arg list. let v ← parseNamedOpt "scope" [] - assert "empty args → none" (v == none) + assertTrue "empty args → none" (v == none) -- Args without the target option. let v ← parseNamedOpt "scope" ["--repo=foo", "get"] - assert "no matching option → none" (v == none) + assertTrue "no matching option → none" (v == none) -- Single occurrence. let v ← parseNamedOpt "scope" ["--scope=abc123"] - assert "single occurrence → some value" (v == some "abc123") + assertTrue "single occurrence → some value" (v == some "abc123") -- `--scope=` is recognized with the empty string as its value, distinct from -- "not passed" (none). let v ← parseNamedOpt "scope" ["--scope="] - assert "empty value → some \"\"" (v == some "") + assertTrue "empty value → some \"\"" (v == some "") -- Multiple occurrences: last wins, matching shell precedence. let v ← parseNamedOpt "scope" ["--scope=first", "--scope=second"] - assert "duplicate option → last value wins" (v == some "second") + assertTrue "duplicate option → last value wins" (v == some "second") -- Surrounding positionals and other options don't interfere. let v ← parseNamedOpt "scope" ["get", "--repo=foo", "--scope=mid", "Mathlib/Init.lean"] - assert "found among other args" (v == some "mid") + assertTrue "found among other args" (v == some "mid") -- A longer lookalike name must not match. let v ← parseNamedOpt "scope" ["--scope-other=foo"] - assert "--scope-other does not match --scope" (v == none) + assertTrue "--scope-other does not match --scope" (v == none) /-- `parseFlagOpt` checks whether a bare `--name` flag is present in args. Used for `--help` today. The contract is strict equality — `--help` matches, @@ -870,21 +870,21 @@ Used for `--help` today. The contract is strict equality — `--help` matches, def test_parseFlagOpt : IO Unit := do IO.println "parseFlagOpt:" -- Empty args. - assert "empty args → false" (!parseFlagOpt "help" []) + assertTrue "empty args → false" (!parseFlagOpt "help" []) -- Bare `--help` present. - assert "--help present → true" (parseFlagOpt "help" ["--help"]) + assertTrue "--help present → true" (parseFlagOpt "help" ["--help"]) -- `--help=` with a value is NOT a bare flag. (`isKnownOpt` would also -- reject it; this is the parser-level guarantee.) - assert "--help=true is NOT a bare flag" (!parseFlagOpt "help" ["--help=true"]) + assertTrue "--help=true is NOT a bare flag" (!parseFlagOpt "help" ["--help=true"]) -- Flag absent among other args. - assert "no flag among args → false" + assertTrue "no flag among args → false" (!parseFlagOpt "help" ["get", "--repo=foo"]) -- Lookalike: `--help-me` isn't the `--help` flag. - assert "lookalike prefix doesn't match" (!parseFlagOpt "help" ["--help-me"]) + assertTrue "lookalike prefix doesn't match" (!parseFlagOpt "help" ["--help-me"]) end CliOptions @@ -899,15 +899,15 @@ revoked ahead of retirement). This guards old clients — whose chain still list def test_isCacheMissStatus : IO Unit := do IO.println "isCacheMissStatus:" -- 404 is a miss regardless of the flag. - assert "404 is a miss (flag off)" (isCacheMissStatus 404 false) - assert "404 is a miss (flag on)" (isCacheMissStatus 404 true) + assertTrue "404 is a miss (flag off)" (isCacheMissStatus 404 false) + assertTrue "404 is a miss (flag on)" (isCacheMissStatus 404 true) -- 403 is a miss only when the flag is set (i.e. for `legacy`). - assert "403 is a failure when flag off" (!isCacheMissStatus 403 false) - assert "403 is a miss when flag on" (isCacheMissStatus 403 true) + assertTrue "403 is a failure when flag off" (!isCacheMissStatus 403 false) + assertTrue "403 is a miss when flag on" (isCacheMissStatus 403 true) -- Success and server errors are never misses; they must surface. - assert "200 is not a miss" (!isCacheMissStatus 200 true) - assert "500 is not a miss" (!isCacheMissStatus 500 true) - assert "403-as-miss is scoped to 403" (!isCacheMissStatus 401 true) + assertTrue "200 is not a miss" (!isCacheMissStatus 200 true) + assertTrue "500 is not a miss" (!isCacheMissStatus 500 true) + assertTrue "403-as-miss is scoped to 403" (!isCacheMissStatus 401 true) end CacheMissStatus @@ -918,12 +918,12 @@ that already exists; both mean "present", not a failure. -/ def test_isAlreadyPresentStatus : IO Unit := do IO.println "isAlreadyPresentStatus:" -- 409/412 are the codes Azure returns for a blob that already exists. - assert "409 is already-present" (isAlreadyPresentStatus 409) - assert "412 is already-present" (isAlreadyPresentStatus 412) + assertTrue "409 is already-present" (isAlreadyPresentStatus 409) + assertTrue "412 is already-present" (isAlreadyPresentStatus 412) -- Successes, misses, and server errors are not. - assert "201 is not already-present" (!isAlreadyPresentStatus 201) - assert "404 is not already-present" (!isAlreadyPresentStatus 404) - assert "500 is not already-present" (!isAlreadyPresentStatus 500) + assertTrue "201 is not already-present" (!isAlreadyPresentStatus 201) + assertTrue "404 is not already-present" (!isAlreadyPresentStatus 404) + assertTrue "500 is not already-present" (!isAlreadyPresentStatus 500) end AlreadyPresentStatus @@ -945,38 +945,38 @@ def test_expandDownloadRounds : IO Unit := do [(some .master, "U_m"), (some .forks, "U_f"), (some .legacy, "U_l")] -- No unsafe scopes: one round per container, each carrying the base scope. - assert "no unsafe scopes, no base scope → scope none on every round" + assertTrue "no unsafe scopes, no base scope → scope none on every round" (expandDownloadRounds chain none [] == [(some .master, "U_m", none), (some .forks, "U_f", none), (some .legacy, "U_l", none)]) - assert "no unsafe scopes, base scope → base scope on every round" + assertTrue "no unsafe scopes, base scope → base scope on every round" (expandDownloadRounds chain (some "S") [] == [(some .master, "U_m", some "S"), (some .forks, "U_f", some "S"), (some .legacy, "U_l", some "S")]) -- With no base scope the forks round defaults to the HEAD scope; the other -- containers' layouts are not SHA-scoped, so it must not leak into them. - assert "no base scope, head scope → forks at head, others unscoped" + assertTrue "no base scope, head scope → forks at head, others unscoped" (expandDownloadRounds chain none [] (some "H") == [(some .master, "U_m", none), (some .forks, "U_f", some "H"), (some .legacy, "U_l", none)]) - assert "explicit base scope wins over head scope" + assertTrue "explicit base scope wins over head scope" (expandDownloadRounds chain (some "S") [] (some "H") == [(some .master, "U_m", some "S"), (some .forks, "U_f", some "S"), (some .legacy, "U_l", some "S")]) - assert "unsafe mode ignores head scope" + assertTrue "unsafe mode ignores head scope" (expandDownloadRounds chain none ["a"] (some "H") == [(some .master, "U_m", none), (some .forks, "U_f", some "a"), (some .legacy, "U_l", none)]) -- Unsafe scopes: only forks fans out, in order; others unscoped, base dropped. - assert "unsafe scopes fan out forks (in order), others unscoped" + assertTrue "unsafe scopes fan out forks (in order), others unscoped" (expandDownloadRounds chain (some "ignored") ["a", "b"] == [(some .master, "U_m", none), (some .forks, "U_f", some "a"), (some .forks, "U_f", some "b"), (some .legacy, "U_l", none)]) -- A chain without forks admits no SHA-scoped reads, so it is left unchanged. - assert "no forks container → unsafe scopes have no effect" + assertTrue "no forks container → unsafe scopes have no effect" (expandDownloadRounds [(some .master, "U_m"), (some .legacy, "U_l")] none ["a", "b"] == [(some .master, "U_m", none), (some .legacy, "U_l", none)]) @@ -1001,27 +1001,27 @@ def test_finalizeDecomp : IO Unit := do -- An empty pipeline passes the counters through unchanged. let (d, f) ← withSuppressedOutput <| finalizeDecomp { decompressed := 5, decompFailed := 2 } testDecompConfig - assert "empty pipeline passes counters through" (d == 5 && f == 2) + assertTrue "empty pipeline passes counters through" (d == 5 && f == 2) -- A finished successful batch is harvested into the success counter. let okTask : Task (Except IO.Error Unit) := Task.pure (.ok ()) let (d, f) ← withSuppressedOutput <| finalizeDecomp { currentTask := some okTask, lastBatchSize := 3, decompressed := 5 } testDecompConfig - assert "successful in-flight batch adds its size to decompressed" (d == 8 && f == 0) + assertTrue "successful in-flight batch adds its size to decompressed" (d == 8 && f == 0) -- A failed batch is harvested into the failure counter, not the success one. let errTask : Task (Except IO.Error Unit) := Task.pure (.error (IO.userError "boom")) let (d, f) ← withSuppressedOutput <| finalizeDecomp { currentTask := some errTask, lastBatchSize := 4, decompressed := 5, decompFailed := 1 } testDecompConfig - assert "failed in-flight batch adds its size to decompFailed" (d == 5 && f == 5) + assertTrue "failed in-flight batch adds its size to decompFailed" (d == 5 && f == 5) -- Pending files are drained even with no in-flight task; a batch whose -- leantar invocation fails lands in the failure counter. let (d, f) ← withSuppressedOutput <| finalizeDecomp { pending := #[(System.FilePath.mk "cache-test-missing-dir/bogus.ltar", `Mathlib.Bogus)] decompressed := 5 } testDecompConfig - assert "failed pending drain adds its size to decompFailed" (d == 5 && f == 1) + assertTrue "failed pending drain adds its size to decompFailed" (d == 5 && f == 1) /-- A download round returns its decompression pipeline state in `TransferState.decomp` so `downloadFiles` can hand it to the next round and @@ -1042,12 +1042,12 @@ def test_monitorCurl_carries_decomp_state : IO Unit := do decompFailed := 1 } let (s, served) ← withSuppressedOutput <| monitorCurl #["--version"] 1 "Downloaded" "speed_download" (decompState := carried) - assert "no transfers → an empty served set" served.isEmpty - assert "pending files survive the round" (s.decomp.pending.size == 1) - assert "the in-flight task survives the round" s.decomp.currentTask.isSome - assert "the batch size survives the round" (s.decomp.lastBatchSize == 7) - assert "the decompressed counter survives the round" (s.decomp.decompressed == 42) - assert "the decompFailed counter survives the round" (s.decomp.decompFailed == 1) + assertTrue "no transfers → an empty served set" served.isEmpty + assertTrue "pending files survive the round" (s.decomp.pending.size == 1) + assertTrue "the in-flight task survives the round" s.decomp.currentTask.isSome + assertTrue "the batch size survives the round" (s.decomp.lastBatchSize == 7) + assertTrue "the decompressed counter survives the round" (s.decomp.decompressed == 42) + assertTrue "the decompFailed counter survives the round" (s.decomp.decompFailed == 1) end DecompPipeline diff --git a/Counterexamples/AharoniKorman.lean b/Counterexamples/AharoniKorman.lean index 25abfb4d362143..3eea7e4bd418a2 100644 --- a/Counterexamples/AharoniKorman.lean +++ b/Counterexamples/AharoniKorman.lean @@ -589,7 +589,7 @@ lemma image_chainBetween_isChain {a b c d n : ℕ} : open Finset in lemma card_chainBetween {a b c d : ℕ} (hac : a ≤ c) (hbd : b ≤ d) : #(chainBetween a b c d) = c + d + 1 - (a + b) := by - rw [chainBetween, if_pos ⟨hac, hbd⟩, card_union_of_disjoint, Finset.card_Icc_prod] + rw [chainBetween, ite_eq_left ⟨hac, hbd⟩, card_union_of_disjoint, Finset.card_Icc_prod] · simp only [Icc_self, card_singleton, Nat.card_Icc] rw [← Finset.Ico_map_sectR, card_map, Nat.card_Ico] lia @@ -894,14 +894,14 @@ noncomputable def x0y0 (n : ℕ) (C : Set Hollom) : ℕ × ℕ := lemma x0y0_mem (h : (C ∩ level (n + 1)).Nonempty) : embed (n + 1) (x0y0 n C) ∈ C := by - rw [x0y0, dif_pos h] + rw [x0y0, dite_eq_left h] exact WellFounded.min_mem _ {x | embed (n + 1) x ∈ C} _ lemma x0y0_min (z : ℕ × ℕ) (hC : IsChain (· ≤ ·) C) (h : embed (n + 1) z ∈ C) : embed (n + 1) (x0y0 n C) ≤ embed (n + 1) z := by have : (C ∩ level (n + 1)).Nonempty := ⟨_, h, by simp [level_eq_range]⟩ refine hC.le_of_not_gt h (x0y0_mem this) ?_ - rw [x0y0, dif_pos this, OrderEmbedding.lt_iff_lt] + rw [x0y0, dite_eq_left this, OrderEmbedding.lt_iff_lt] exact wellFounded_lt.not_lt_min {x | embed (n + 1) x ∈ C} h /-- @@ -951,7 +951,7 @@ We will later show the same assuming `C ∩ level (n + 1)` is infinite. -/ lemma square_subset_S_case_1 (h : (C ∩ level n).Finite) (h' : (C ∩ level (n + 1)).Finite) : ∀ᶠ a in atTop, embed n '' Set.Ici (a, a) ⊆ S n C \ (C ∩ level n) := by - rw [S, if_pos h'] + rw [S, ite_eq_left h'] -- Take a maximal pair `(b, c)` so that any `(d, e, n)` in `C` satisfies -- `(d, e, n) ≤ (b, c, n)`. obtain ⟨b, c, hab⟩ : ∃ b c, ∀ d e, h(d, e, n + 1) ∈ C → (d, e) ≤ (b, c) := by @@ -986,7 +986,7 @@ We earlier showed the same assuming `C ∩ level (n + 1)` is finite. -/ lemma square_subset_S_case_2 (h : (C ∩ level n).Finite) (h' : (C ∩ level (n + 1)).Infinite) : ∀ᶠ a in atTop, embed n '' Set.Ici (a, a) ⊆ S n C \ (C ∩ level n) := by - rw [S, if_neg h'] + rw [S, ite_eq_right h'] filter_upwards [eventually_ge_atTop (x0 n C + 1), eventually_ge_atTop (y0 n C + 1), square_subset_R h] with a hax hay haR simp [Set.subset_def, embed_apply] at * @@ -1036,7 +1036,7 @@ theorem not_S_hits_next (f : SpinalMap C) (hC : IsChain (· ≤ ·) C) cases (C ∩ level (n + 1)).finite_or_infinite -- In the case that `C ∩ level (n + 1)` is finite, this is immediate from the definition of `S`. case inl h => - rw [S, if_pos h, Set.mem_ofPred_eq] at hx + rw [S, ite_eq_left h, Set.mem_ofPred_eq] at hx intro hy refine f.incomp_apply ?_ (hx.2 _ hy).symm have := R_subset_level hx.1 @@ -1047,7 +1047,7 @@ theorem not_S_hits_next (f : SpinalMap C) (hC : IsChain (· ≤ ·) C) case inr h => -- Write `(x, y, n)` for our given point, and set `(a, b, n + 1) := f(x, y, n)` induction S_subset_level hx using induction_on_level with | h x y => - simp only [S, if_neg h, Set.mem_ofPred_eq] at hx + simp only [S, ite_eq_right h, Set.mem_ofPred_eq] at hx intro hp set fp := f h(x, y, n) with hfp clear_value fp @@ -1172,7 +1172,7 @@ theorem not_S_mapsTo_previous (hC : IsChain (· ≤ ·) C) set c := f x with hc have hc' : c ∈ C ∩ level (n - 1) := h _ (F_subs hx) clear_value c - rw [coe_image, chainBetween, Ico_self, if_pos (by lia), empty_union, ← Icc_map_sectL] at hx + rw [coe_image, chainBetween, Ico_self, ite_eq_left (by lia), empty_union, ← Icc_map_sectL] at hx simp only [embed_apply, coe_map, Function.Embedding.sectL_apply, coe_Icc, Set.mem_image, Set.mem_Icc, exists_exists_and_eq_and] at hx obtain ⟨b, ⟨hab, hba⟩, rfl⟩ := hx diff --git a/Counterexamples/CliffordAlgebraNotInjective.lean b/Counterexamples/CliffordAlgebraNotInjective.lean index 391f689833da0d..ebb9cb50841a50 100644 --- a/Counterexamples/CliffordAlgebraNotInjective.lean +++ b/Counterexamples/CliffordAlgebraNotInjective.lean @@ -177,7 +177,7 @@ theorem Q'_apply_single (i : Fin 3) (x : K) : Q' (Pi.single i x) = x * x := calc Q' (Pi.single i x) = ∑ j : Fin 3, (Pi.single i x * Pi.single i x : Fin 3 → K) j := by simp [Q', sq] - _ = _ := by simp_rw [← Pi.single_mul, Finset.sum_pi_single', Finset.mem_univ, if_pos] + _ = _ := by simp_rw [← Pi.single_mul, Finset.sum_pi_single', Finset.mem_univ, ite_eq_left] theorem Q'_zero_under_ideal (v : Fin 3 → K) (hv : v ∈ LinearMap.ker lFunc) : Q' v = 0 := by rw [LinearMap.mem_ker, lFunc_apply] at hv diff --git a/Counterexamples/MapFloor.lean b/Counterexamples/MapFloor.lean index ccd46ac7f452e0..f72904b99c4738 100644 --- a/Counterexamples/MapFloor.lean +++ b/Counterexamples/MapFloor.lean @@ -117,7 +117,7 @@ theorem forgetEpsilons_floor_lt (n : ℤ) : forgetEpsilons ⌊(n - ↑ε : ℤ[ε])⌋ < ⌊forgetEpsilons (n - ↑ε)⌋ := by suffices ⌊(n - ↑ε : ℤ[ε])⌋ = n - 1 by simp [map_sub, this] have : (0 : ℤ[ε]) < ε := ⟨1, by simp⟩ - exact (if_neg <| by rw [coeff_sub, intCast_coeff_zero]; simp [this]).trans (by + exact (ite_eq_right <| by rw [coeff_sub, intCast_coeff_zero]; simp [this]).trans (by rw [coeff_sub, intCast_coeff_zero]; simp) set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/Algebra/BigOperators/Expect.lean b/Mathlib/Algebra/BigOperators/Expect.lean index 1c9ee18e86f466..6021bb34144e96 100644 --- a/Mathlib/Algebra/BigOperators/Expect.lean +++ b/Mathlib/Algebra/BigOperators/Expect.lean @@ -360,7 +360,7 @@ variable [Semifield K] [CharZero K] lemma expect_boole_mul [Fintype ι] [Nonempty ι] [DecidableEq ι] (f : ι → K) (i : ι) : 𝔼 j, ite (i = j) (Fintype.card ι : K) 0 * f j = f i := by - simp_rw [expect_univ, ite_mul, zero_mul, sum_ite_eq, if_pos (mem_univ _)] + simp_rw [expect_univ, ite_mul, zero_mul, sum_ite_eq, ite_eq_left (mem_univ _)] rw [← @NNRat.cast_natCast K, ← NNRat.smul_def, inv_smul_smul₀] simp [Fintype.card_ne_zero] diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index c6a54e43662234..13b5ef3fd8716b 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -178,7 +178,7 @@ notation3"∏ᶠ " (...) ", " r:67:(scoped f => finprod f) => r theorem finprod_eq_prod_plift_of_mulSupport_toFinset_subset {f : α → M} (hf : HasFiniteMulSupport (f ∘ PLift.down)) {s : Finset (PLift α)} (hs : hf.toFinset ⊆ s) : ∏ᶠ i, f i = ∏ i ∈ s, f i.down := by - rw [finprod, dif_pos hf] + rw [finprod, dite_eq_left hf] refine Finset.prod_subset hs fun x _ hxf => ?_ rwa [hf.mem_toFinset, notMem_mulSupport] at hxf @@ -290,7 +290,7 @@ theorem MonoidHom.map_finprod_Prop {p : Prop} (f : M →* N) (g : p → M) : theorem MonoidHom.map_finprod_of_preimage_one (f : M →* N) (hf : ∀ x, f x = 1 → x = 1) (g : α → M) : f (∏ᶠ i, g i) = ∏ᶠ i, f (g i) := by by_cases hg : HasFiniteMulSupport <| g ∘ PLift.down; · exact f.map_finprod_plift g hg - rw [finprod, dif_neg, f.map_one, finprod, dif_neg] + rw [finprod, dite_eq_right, f.map_one, finprod, dite_eq_right] exacts [Infinite.mono (fun x hx => mt (hf (g x.down)) hx) hg, hg] @[to_additive] @@ -391,7 +391,7 @@ theorem finprod_def (f : α → M) [Decidable (HasFiniteMulSupport f)] : ∏ᶠ i : α, f i = if h : HasFiniteMulSupport f then ∏ i ∈ h.toFinset, f i else 1 := by split_ifs with h · exact finprod_eq_prod_of_mulSupport_toFinset_subset _ h (Finset.Subset.refl _) - · rw [finprod, dif_neg] + · rw [finprod, dite_eq_right] rw [HasFiniteMulSupport, mulSupport_comp_eq_preimage] exact mt (fun hf => hf.of_preimage Equiv.plift.surjective) h @@ -402,7 +402,7 @@ theorem finprod_of_infinite_mulSupport {f : α → M} (hf : (mulSupport f).Infin classical rw [finprod_def] simp only [HasFiniteMulSupport] - rw [dif_neg hf] + rw [dite_eq_right hf] @[to_additive] theorem finprod_of_not_hasFiniteMulSupport {f : α → M} (hf : ¬ f.HasFiniteMulSupport) : @@ -433,7 +433,7 @@ theorem hasFiniteSupport_of_finsum_eq_one {R : Type*} [NonAssocSemiring R] {f : @[to_additive] theorem finprod_eq_prod (f : α → M) (hf : HasFiniteMulSupport f) : - ∏ᶠ i : α, f i = ∏ i ∈ hf.toFinset, f i := by classical rw [finprod_def, dif_pos hf] + ∏ᶠ i : α, f i = ∏ i ∈ hf.toFinset, f i := by classical rw [finprod_def, dite_eq_left hf] @[to_additive] theorem finprod_eq_prod_of_fintype [Fintype α] (f : α → M) : ∏ᶠ i : α, f i = ∏ i, f i := @@ -1295,7 +1295,7 @@ lemma finprod_apply {α ι : Type*} {f : ι → α → N} (hf : HasFiniteMulSupp (∏ᶠ i, f i) a = ∏ᶠ i, f i a := by classical have hf' : HasFiniteMulSupport fun i ↦ f i a := by fun_prop (disch := simp) - simp only [finprod_def, dif_pos, hf, hf', Finset.prod_apply] + simp only [finprod_def, dite_eq_left, hf, hf', Finset.prod_apply] symm apply Finset.prod_subset <;> aesop @@ -1368,7 +1368,7 @@ theorem finprod_curry₃ {γ : Type*} (f : α × β × γ → M) (h : HasFiniteM @[to_additive] theorem finprod_dmem {s : Set α} [DecidablePred (· ∈ s)] (f : ∀ a : α, a ∈ s → M) : (∏ᶠ (a : α) (h : a ∈ s), f a h) = ∏ᶠ (a : α) (_ : a ∈ s), if h' : a ∈ s then f a h' else 1 := - finprod_congr fun _ => finprod_congr fun ha => (dif_pos ha).symm + finprod_congr fun _ => finprod_congr fun ha => (dite_eq_left ha).symm @[to_additive] theorem finprod_emb_domain' {f : α → β} (hf : Injective f) [DecidablePred (· ∈ Set.range f)] @@ -1377,7 +1377,7 @@ theorem finprod_emb_domain' {f : α → β} (hf : Injective f) [DecidablePred ( simp_rw [← finprod_eq_dif] rw [finprod_dmem, finprod_mem_range hf, finprod_congr fun a => _] intro a - rw [dif_pos (Set.mem_range_self a), hf (Classical.choose_spec (Set.mem_range_self a))] + rw [dite_eq_left (Set.mem_range_self a), hf (Classical.choose_spec (Set.mem_range_self a))] @[to_additive] theorem finprod_emb_domain (f : α ↪ β) [DecidablePred (· ∈ Set.range f)] (g : α → M) : diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index b7faa997208659..ce6f063b535465 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -326,11 +326,11 @@ theorem prod_filter (p : ι → Prop) [DecidablePred p] (f : ι → M) : ∏ a ∈ s with p a, f a = ∏ a ∈ s, if p a then f a else 1 := calc ∏ a ∈ s with p a, f a = ∏ a ∈ s with p a, if p a then f a else 1 := - prod_congr rfl fun a h => by rw [if_pos]; simpa using (mem_filter.1 h).2 + prod_congr rfl fun a h => by rw [ite_eq_left]; simpa using (mem_filter.1 h).2 _ = ∏ a ∈ s, if p a then f a else 1 := by { refine prod_subset (filter_subset _ s) fun x hs h => ?_ rw [mem_filter, not_and] at h - exact if_neg (by simpa using h hs) } + exact ite_eq_right (by simpa using h hs) } @[to_additive] theorem prod_eq_single_of_mem {s : Finset ι} {f : ι → M} (a : ι) (h : a ∈ s) @@ -484,7 +484,7 @@ theorem prod_congr_set [Fintype ι] (s : Set ι) [DecidablePred (· ∈ s)] (f : @[to_additive] theorem prod_extend_by_one [DecidableEq ι] (s : Finset ι) (f : ι → M) : ∏ i ∈ s, (if i ∈ s then f i else 1) = ∏ i ∈ s, f i := - (prod_congr rfl) fun _i hi => if_pos hi + (prod_congr rfl) fun _i hi => ite_eq_left hi /-- Also see `Finset.prod_ite_mem_eq` -/ @[to_additive /-- Also see `Finset.sum_ite_mem_eq` -/] diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Piecewise.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Piecewise.lean index 973c845659ce40..b8b47e5aa35637 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Piecewise.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Piecewise.lean @@ -41,8 +41,9 @@ theorem prod_apply_dite {p : ι → Prop} [DecidablePred p] _ = (∏ x : {x ∈ s | p x}, h (f x.1 <| by simpa using (mem_filter.mp x.2).2)) * ∏ x : {x ∈ s | ¬p x}, h (g x.1 <| by simpa using (mem_filter.mp x.2).2) := congr_arg₂ _ (prod_congr rfl fun x _hx ↦ - congr_arg h (dif_pos <| by simpa using (mem_filter.mp x.2).2)) - (prod_congr rfl fun x _hx => congr_arg h (dif_neg <| by simpa using (mem_filter.mp x.2).2)) + congr_arg h (dite_eq_left <| by simpa using (mem_filter.mp x.2).2)) + (prod_congr rfl fun x _hx => + congr_arg h (dite_eq_right <| by simpa using (mem_filter.mp x.2).2)) @[to_additive] theorem prod_apply_ite {s : Finset ι} {p : ι → Prop} [DecidablePred p] (f g : ι → γ) @@ -116,9 +117,9 @@ lemma prod_attach_eq_prod_dite [Fintype ι] (s : Finset ι) (f : s → M) [Decid theorem prod_dite_eq [DecidableEq ι] (s : Finset ι) (a : ι) (b : ∀ x : ι, a = x → M) : ∏ x ∈ s, (if h : a = x then b x h else 1) = ite (a ∈ s) (b a rfl) 1 := by split_ifs with h - · rw [Finset.prod_eq_single a, dif_pos rfl] + · rw [Finset.prod_eq_single a, dite_eq_left rfl] · intro _ _ h - rw [dif_neg] + rw [dite_eq_right] exact h.symm · simp [h] · rw [Finset.prod_eq_one] @@ -128,9 +129,9 @@ theorem prod_dite_eq [DecidableEq ι] (s : Finset ι) (a : ι) (b : ∀ x : ι, theorem prod_dite_eq' [DecidableEq ι] (s : Finset ι) (a : ι) (b : ∀ x : ι, x = a → M) : ∏ x ∈ s, (if h : x = a then b x h else 1) = ite (a ∈ s) (b a rfl) 1 := by split_ifs with h - · rw [Finset.prod_eq_single a, dif_pos rfl] + · rw [Finset.prod_eq_single a, dite_eq_left rfl] · intro _ _ h - rw [dif_neg] + rw [dite_eq_right] exact h · simp [h] · rw [Finset.prod_eq_one] @@ -156,13 +157,13 @@ theorem prod_ite_eq' [DecidableEq ι] (s : Finset ι) (a : ι) (b : ι → M) : @[to_additive] theorem prod_ite_eq_of_mem [DecidableEq ι] (s : Finset ι) (a : ι) (b : ι → M) (h : a ∈ s) : (∏ x ∈ s, if a = x then b x else 1) = b a := by - simp only [prod_ite_eq, if_pos h] + simp only [prod_ite_eq, ite_eq_left h] /-- The difference with `Finset.prod_ite_eq_of_mem` is that the arguments to `Eq` are swapped. -/ @[to_additive] theorem prod_ite_eq_of_mem' [DecidableEq ι] (s : Finset ι) (a : ι) (b : ι → M) (h : a ∈ s) : (∏ x ∈ s, if x = a then b x else 1) = b a := by - simp only [prod_ite_eq', if_pos h] + simp only [prod_ite_eq', ite_eq_left h] @[to_additive (attr := simp)] theorem prod_pi_mulSingle' [DecidableEq ι] (a : ι) (x : M) (s : Finset ι) : @@ -255,11 +256,11 @@ theorem prod_ite_one (s : Finset ι) (p : ι → Prop) [DecidablePred p] ∏ i ∈ s, ite (p i) a 1 = ite (∃ i ∈ s, p i) a 1 := by split_ifs with h · obtain ⟨i, hi, hpi⟩ := h - rw [prod_eq_single_of_mem _ hi, if_pos hpi] - exact fun j hj hji ↦ if_neg fun hpj ↦ hji <| h _ hj _ hi hpj hpi + rw [prod_eq_single_of_mem _ hi, ite_eq_left hpi] + exact fun j hj hji ↦ ite_eq_right fun hpj ↦ hji <| h _ hj _ hi hpj hpi · push Not at h rw [prod_eq_one] - exact fun i hi => if_neg (h i hi) + exact fun i hi => ite_eq_right (h i hi) @[to_additive sum_boole_nsmul] theorem prod_pow_boole [DecidableEq ι] (s : Finset ι) (f : ι → M) (a : ι) : @@ -300,23 +301,23 @@ lemma prod_ite_mem (s : Finset ι) (f : ι → M) : ∏ i, (if i ∈ s then f i @[to_additive /-- See also `Finset.sum_dite_eq`. -/] lemma prod_dite_eq (i : ι) (f : ∀ j, i = j → M) : ∏ j, (if h : i = j then f j h else 1) = f i rfl := by - rw [Finset.prod_dite_eq, if_pos (mem_univ _)] + rw [Finset.prod_dite_eq, ite_eq_left (mem_univ _)] /-- See also `Finset.prod_dite_eq'`. -/ @[to_additive /-- See also `Finset.sum_dite_eq'`. -/] lemma prod_dite_eq' (i : ι) (f : ∀ j, j = i → M) : ∏ j, (if h : j = i then f j h else 1) = f i rfl := by - rw [Finset.prod_dite_eq', if_pos (mem_univ _)] + rw [Finset.prod_dite_eq', ite_eq_left (mem_univ _)] /-- See also `Finset.prod_ite_eq`. -/ @[to_additive /-- See also `Finset.sum_ite_eq`. -/] lemma prod_ite_eq (i : ι) (f : ι → M) : ∏ j, (if i = j then f j else 1) = f i := by - rw [Finset.prod_ite_eq, if_pos (mem_univ _)] + rw [Finset.prod_ite_eq, ite_eq_left (mem_univ _)] /-- See also `Finset.prod_ite_eq'`. -/ @[to_additive /-- See also `Finset.sum_ite_eq'`. -/] lemma prod_ite_eq' (i : ι) (f : ι → M) : ∏ j, (if j = i then f j else 1) = f i := by - rw [Finset.prod_ite_eq', if_pos (mem_univ _)] + rw [Finset.prod_ite_eq', ite_eq_left (mem_univ _)] /-- See also `Finset.prod_pi_mulSingle`. -/ @[to_additive /-- See also `Finset.sum_pi_single`. -/] diff --git a/Mathlib/Algebra/BigOperators/Ring/Finset.lean b/Mathlib/Algebra/BigOperators/Ring/Finset.lean index cdd6f7f559520a..bedfc7ff7ff493 100644 --- a/Mathlib/Algebra/BigOperators/Ring/Finset.lean +++ b/Mathlib/Algebra/BigOperators/Ring/Finset.lean @@ -210,7 +210,7 @@ theorem prod_add_ordered [LinearOrder ι] (s : Finset ι) (f g : ι → R) : clear s intro a s ha ihs have ha' : a ∉ s := fun ha' => lt_irrefl a (ha a ha') - rw [prod_insert ha', prod_insert ha', sum_insert ha', filter_insert, if_neg (lt_irrefl a), + rw [prod_insert ha', prod_insert ha', sum_insert ha', filter_insert, ite_eq_right (lt_irrefl a), filter_true_of_mem ha, ihs, add_mul, mul_add, mul_add, add_assoc] congr 1 rw [add_comm] @@ -219,8 +219,8 @@ theorem prod_add_ordered [LinearOrder ι] (s : Finset ι) (f g : ι → R) : exact (forall_mem_insert _ _ _).2 ⟨lt_irrefl a, fun i hi => (ha i hi).not_gt⟩ · rw [mul_sum] refine sum_congr rfl fun i hi => ?_ - rw [filter_insert, if_neg (ha i hi).not_gt, filter_insert, if_pos (ha i hi), prod_insert, - mul_left_comm] + rw [filter_insert, ite_eq_right (ha i hi).not_gt, filter_insert, ite_eq_left (ha i hi), + prod_insert, mul_left_comm] exact mt (fun ha => (mem_filter.1 ha).1) ha' theorem prod_one_add_ordered [LinearOrder ι] (s : Finset ι) (f : ι → R) : diff --git a/Mathlib/Algebra/Colimit/Ring.lean b/Mathlib/Algebra/Colimit/Ring.lean index 986be6cadd1567..bd596daaaf2336 100644 --- a/Mathlib/Algebra/Colimit/Ring.lean +++ b/Mathlib/Algebra/Colimit/Ring.lean @@ -329,7 +329,7 @@ noncomputable def inv (p : Ring.DirectLimit G f) : Ring.DirectLimit G f := if H : p = 0 then 0 else Classical.choose (DirectLimit.exists_inv G f H) protected theorem mul_inv_cancel {p : Ring.DirectLimit G f} (hp : p ≠ 0) : p * inv G f p = 1 := by - rw [inv, dif_neg hp, Classical.choose_spec (DirectLimit.exists_inv G f hp)] + rw [inv, dite_eq_right hp, Classical.choose_spec (DirectLimit.exists_inv G f hp)] protected theorem inv_mul_cancel {p : Ring.DirectLimit G f} (hp : p ≠ 0) : inv G f p * p = 1 := by rw [_root_.mul_comm, DirectLimit.mul_inv_cancel G f hp] @@ -342,7 +342,7 @@ protected noncomputable abbrev field [DirectedSystem G (f' · · ·)] : -- but leaving them implicit avoids a very expensive (2-3 minutes!) eta expansion. inv := inv G (f' · · ·) mul_inv_cancel := fun _ ↦ DirectLimit.mul_inv_cancel G (f' · · ·) - inv_zero := dif_pos rfl + inv_zero := dite_eq_left rfl nnqsmul := _ nnqsmul_def _ _ := rfl qsmul := _ diff --git a/Mathlib/Algebra/DirectSum/Basic.lean b/Mathlib/Algebra/DirectSum/Basic.lean index e9d35aa911a984..9ed54902562cd9 100644 --- a/Mathlib/Algebra/DirectSum/Basic.lean +++ b/Mathlib/Algebra/DirectSum/Basic.lean @@ -428,8 +428,9 @@ theorem coe_of_apply {M S : Type*} [DecidableEq ι] [AddCommMonoid M] [SetLike S [AddSubmonoidClass S M] {A : ι → S} (i j : ι) (x : A i) : (of (fun i ↦ {x // x ∈ A i}) i x j : M) = if i = j then x else 0 := by obtain rfl | h := Decidable.eq_or_ne j i - · rw [DirectSum.of_eq_same, if_pos rfl] - · rw [DirectSum.of_eq_of_ne _ _ _ h, if_neg h.symm, ZeroMemClass.coe_zero, ZeroMemClass.coe_zero] + · rw [DirectSum.of_eq_same, ite_eq_left rfl] + · rw [DirectSum.of_eq_of_ne _ _ _ h, ite_eq_right h.symm, ZeroMemClass.coe_zero, + ZeroMemClass.coe_zero] /-- The `DirectSum` formed by a collection of additive submonoids (or subgroups, or submodules) of `M` is said to be internal if the canonical map `(⨁ i, A i) →+ M` is bijective. diff --git a/Mathlib/Algebra/EuclideanDomain/Defs.lean b/Mathlib/Algebra/EuclideanDomain/Defs.lean index ab7635c4a5e85b..54e22bfdd5033f 100644 --- a/Mathlib/Algebra/EuclideanDomain/Defs.lean +++ b/Mathlib/Algebra/EuclideanDomain/Defs.lean @@ -190,7 +190,7 @@ termination_by a @[simp] theorem gcd_zero_left (a : R) : gcd 0 a = a := by rw [gcd] - exact if_pos rfl + exact ite_eq_left rfl /-- An implementation of the extended GCD algorithm. At each step we are computing a triple `(r, s, t)`, where `r` is the next value of the GCD @@ -212,14 +212,14 @@ termination_by r @[simp] theorem xgcd_zero_left {s t r' s' t' : R} : xgcdAux 0 s t r' s' t' = (r', s', t') := by unfold xgcdAux - exact if_pos rfl + exact ite_eq_left rfl theorem xgcdAux_rec {r s t r' s' t' : R} (h : r ≠ 0) : xgcdAux r s t r' s' t' = xgcdAux (r' % r) (s' - r' / r * s) (t' - r' / r * t) r s t := by conv => lhs rw [xgcdAux] - exact if_neg h + exact ite_eq_right h /-- Use the extended GCD algorithm to generate the `a` and `b` values satisfying `gcd x y = x * a + y * b`. -/ diff --git a/Mathlib/Algebra/EuclideanDomain/Field.lean b/Mathlib/Algebra/EuclideanDomain/Field.lean index 4d0ea217367aac..3f5e89cf0f9469 100644 --- a/Mathlib/Algebra/EuclideanDomain/Field.lean +++ b/Mathlib/Algebra/EuclideanDomain/Field.lean @@ -45,10 +45,10 @@ protected theorem gcd_eq [DecidableEq K] (a b : K) : protected theorem gcd_zero_eq [DecidableEq K] (b : K) : EuclideanDomain.gcd 0 b = b := by - rw [Field.gcd_eq, if_pos rfl] + rw [Field.gcd_eq, ite_eq_left rfl] protected theorem gcd_eq_of_ne [DecidableEq K] {a : K} (ha : a ≠ 0) (b : K) : EuclideanDomain.gcd a b = a := by - rw [Field.gcd_eq, if_neg ha] + rw [Field.gcd_eq, ite_eq_right ha] end Field diff --git a/Mathlib/Algebra/Field/IsField.lean b/Mathlib/Algebra/Field/IsField.lean index f6a3085f7edbbb..f3d73b5ce98496 100644 --- a/Mathlib/Algebra/Field/IsField.lean +++ b/Mathlib/Algebra/Field/IsField.lean @@ -76,8 +76,10 @@ noncomputable def IsField.toSemifield {R : Type u} [Semiring R] (h : IsField R) __ := ‹Semiring R› __ := h inv a := if ha : a = 0 then 0 else Classical.choose (h.mul_inv_cancel ha) - inv_zero := dif_pos rfl - mul_inv_cancel a ha := by convert! Classical.choose_spec (h.mul_inv_cancel ha); exact dif_neg ha + inv_zero := dite_eq_left rfl + mul_inv_cancel a ha := by + convert! Classical.choose_spec (h.mul_inv_cancel ha) + exact dite_eq_right ha nnqsmul := _ nnqsmul_def _ _ := rfl diff --git a/Mathlib/Algebra/Field/Rat.lean b/Mathlib/Algebra/Field/Rat.lean index 253655521fb440..598cd44720ef6a 100644 --- a/Mathlib/Algebra/Field/Rat.lean +++ b/Mathlib/Algebra/Field/Rat.lean @@ -111,8 +111,8 @@ theorem NNRatCast.ofScientific_eq_ite {K} [NNRatCast K] (m : ℕ) (b : Bool) (d rw [NNRatCast.toOfScientific_def] split_ifs · congr 2 - rw [← Rat.ofScientific_eq_ofScientific, Rat.ofScientific_def, if_pos ‹_›] + rw [← Rat.ofScientific_eq_ofScientific, Rat.ofScientific_def, ite_eq_left ‹_›] congr · congr 2 - rw [← Rat.ofScientific_eq_ofScientific, Rat.ofScientific_def, if_neg ‹_›] + rw [← Rat.ofScientific_eq_ofScientific, Rat.ofScientific_def, ite_eq_right ‹_›] congr diff --git a/Mathlib/Algebra/FreeAlgebra.lean b/Mathlib/Algebra/FreeAlgebra.lean index 125967838c2514..0d11de9221f702 100644 --- a/Mathlib/Algebra/FreeAlgebra.lean +++ b/Mathlib/Algebra/FreeAlgebra.lean @@ -501,9 +501,9 @@ theorem ι_injective [Nontrivial R] : Function.Injective (ι R : X → FreeAlgeb by_contradiction <| by classical exact fun hxy : x ≠ y ↦ let f : FreeAlgebra R X →ₐ[R] R := lift R fun z ↦ if x = z then (1 : R) else 0 - have hfx1 : f (ι R x) = 1 := (lift_ι_apply _ _).trans <| if_pos rfl + have hfx1 : f (ι R x) = 1 := (lift_ι_apply _ _).trans <| ite_eq_left rfl have hfy1 : f (ι R y) = 1 := hoxy ▸ hfx1 - have hfy0 : f (ι R y) = 0 := (lift_ι_apply _ _).trans <| if_neg hxy + have hfy0 : f (ι R y) = 0 := (lift_ι_apply _ _).trans <| ite_eq_right hxy one_ne_zero <| hfy1.symm.trans hfy0 @[simp] diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index 21d09cc04654af..ea0fd2a0d62740 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -93,11 +93,11 @@ noncomputable abbrev NormalizationMonoid.ofRightInverse {α : Type*} [MonoidWith have assoc a := (Associates.mk_eq_mk_iff_associated.mp <| mk_out (.mk a)).symm let := Classical.dec { normUnit a := if a = 0 then 1 else (assoc a).choose - normUnit_zero := if_pos rfl + normUnit_zero := ite_eq_left rfl normUnit_one := by nontriviality α; rw [← Units.val_inj]; convert ← (assoc 1).choose_spec <;> simp [out_one] normUnit_mul_units {a} u ha := by - simp_rw [Units.mul_left_eq_zero, if_neg ha, eq_inv_mul_iff_mul_eq, ← Units.val_inj] + simp_rw [Units.mul_left_eq_zero, ite_eq_right ha, eq_inv_mul_iff_mul_eq, ← Units.val_inj] rw [Units.val_mul, ← (IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha).eq_iff, (assoc a).choose_spec, ← mul_assoc, (assoc _).choose_spec, Associates.mk_eq_mk_iff_associated.mpr (associated_mul_unit_right a u u.isUnit)] } @@ -1064,9 +1064,10 @@ def strongNormalizationMonoidOfMonoidHomRightInverse [DecidableEq α] (f : Assoc normUnit a := if a = 0 then 1 else Classical.choose (Associates.mk_eq_mk_iff_associated.1 (hinv (Associates.mk a)).symm) - normUnit_zero := if_pos rfl + normUnit_zero := ite_eq_left rfl normUnit_mul {a b} ha hb := by - simp_rw [if_neg (mul_ne_zero ha hb), if_neg ha, if_neg hb, Units.ext_iff, Units.val_mul] + simp_rw [ite_eq_right (mul_ne_zero ha hb), ite_eq_right ha, ite_eq_right hb, Units.ext_iff, + Units.val_mul] suffices a * b * ↑(Classical.choose (associated_map_mk hinv (a * b))) = a * ↑(Classical.choose (associated_map_mk hinv a)) * (b * ↑(Classical.choose (associated_map_mk hinv b))) by @@ -1076,7 +1077,7 @@ def strongNormalizationMonoidOfMonoidHomRightInverse [DecidableEq α] (f : Assoc map_mul, Associates.mk_mul_mk] normUnit_coe_units u := by nontriviality α - simp_rw [if_neg (Units.ne_zero u), Units.ext_iff] + simp_rw [ite_eq_right (Units.ne_zero u), Units.ext_iff] apply mul_left_cancel₀ (Units.ne_zero u) rw [Units.mul_inv, map_mk_unit_aux hinv u, Associates.mk_eq_mk_iff_associated.2 (associated_one_iff_isUnit.2 ⟨u, rfl⟩), @@ -1101,7 +1102,7 @@ noncomputable def gcdMonoidOfGCD [DecidableEq α] (gcd : α → α → α) split_ifs with a0 · rw [mul_zero, a0, zero_mul] · rw [← Classical.choose_spec ((gcd_dvd_left a b).trans (Dvd.intro b rfl))] - lcm_zero_left := fun _ => if_pos rfl + lcm_zero_left := fun _ => ite_eq_left rfl lcm_zero_right := fun a => by split_ifs with a0 · rfl @@ -1135,7 +1136,7 @@ noncomputable def normalizedGCDMonoidOfGCD [NormalizationMonoid α] [DecidableEq · rw [mul_zero, a0, zero_mul] · exact .trans ((normalize_associated _).mul_left _) (.of_eq (Classical.choose_spec (_ : _ ∣ a * b)).symm) - lcm_zero_left _ := if_pos rfl + lcm_zero_left _ := ite_eq_left rfl lcm_zero_right a := by split_ifs with a0 · rfl @@ -1356,7 +1357,7 @@ variable (G₀ : Type*) [CommGroupWithZero G₀] [DecidableEq G₀] -- see Note [lower instance priority] instance (priority := 100) : StrongNormalizedGCDMonoid G₀ where normUnit x := if h : x = 0 then 1 else (Units.mk0 x h)⁻¹ - normUnit_zero := dif_pos rfl + normUnit_zero := dite_eq_left rfl normUnit_mul {x y} x0 y0 := Units.ext <| by simp [x0, y0, mul_comm] normUnit_coe_units u := by simp gcd a b := if a = 0 ∧ b = 0 then 0 else 1 @@ -1366,11 +1367,13 @@ instance (priority := 100) : StrongNormalizedGCDMonoid G₀ where dvd_gcd {a b c} hac hab := by simp_all gcd_mul_lcm a b := by split_ifs <;> simp_all [Associated.comm] - lcm_zero_left _ := if_pos (Or.inl rfl) - lcm_zero_right _ := if_pos (Or.inr rfl) + lcm_zero_left _ := ite_eq_left (Or.inl rfl) + lcm_zero_right _ := ite_eq_left (Or.inr rfl) -- `split_ifs` wants to split `normalize`, so handle the cases manually - normalize_gcd a b := if h : a = 0 ∧ b = 0 then by simp [if_pos h] else by simp [if_neg h] - normalize_lcm a b := if h : a = 0 ∨ b = 0 then by simp [if_pos h] else by simp [if_neg h] + normalize_gcd a b := + if h : a = 0 ∧ b = 0 then by simp [ite_eq_left h] else by simp [ite_eq_right h] + normalize_lcm a b := + if h : a = 0 ∨ b = 0 then by simp [ite_eq_left h] else by simp [ite_eq_right h] @[simp] theorem coe_normUnit {a : G₀} (h0 : a ≠ 0) : (↑(normUnit a) : G₀) = a⁻¹ := by diff --git a/Mathlib/Algebra/GCDMonoid/Finset.lean b/Mathlib/Algebra/GCDMonoid/Finset.lean index 2307eea5f10e07..6657b0af703399 100644 --- a/Mathlib/Algebra/GCDMonoid/Finset.lean +++ b/Mathlib/Algebra/GCDMonoid/Finset.lean @@ -250,7 +250,7 @@ theorem extract_gcd (f : β → α) (hs : s.Nonempty) : refine ⟨fun b ↦ if hb : b ∈ s then g' hb else 0, fun b hb ↦ ?_, extract_gcd' f _ h fun b hb ↦ ?_⟩ · simp only [hb, hg, dite_true] - rw [dif_pos hb, hg hb] + rw [dite_eq_left hb, hg hb] variable [Div α] [MulDivCancelClass α] {f : ι → α} {s : Finset ι} {i : ι} diff --git a/Mathlib/Algebra/GCDMonoid/Nat.lean b/Mathlib/Algebra/GCDMonoid/Nat.lean index 5ab65cf0b87e5f..aa378a5bf96eed 100644 --- a/Mathlib/Algebra/GCDMonoid/Nat.lean +++ b/Mathlib/Algebra/GCDMonoid/Nat.lean @@ -58,13 +58,13 @@ section NormalizationMonoid instance strongNormalizationMonoid : StrongNormalizationMonoid ℤ where normUnit a := if 0 ≤ a then 1 else -1 - normUnit_zero := if_pos le_rfl + normUnit_zero := ite_eq_left le_rfl normUnit_mul {a b} hna hnb := by rcases hna.lt_or_gt with ha | ha <;> rcases hnb.lt_or_gt with hb | hb <;> simp [Int.mul_nonneg_iff, ha.le, ha.not_ge, hb.le, hb.not_ge] normUnit_coe_units u := - (units_eq_one_or u).elim (fun eq => eq.symm ▸ if_pos Int.one_nonneg) fun eq => - eq.symm ▸ if_neg (not_le_of_gt <| show (-1 : ℤ) < 0 by decide) + (units_eq_one_or u).elim (fun eq => eq.symm ▸ ite_eq_left Int.one_nonneg) fun eq => + eq.symm ▸ ite_eq_right (not_le_of_gt <| show (-1 : ℤ) < 0 by decide) @[deprecated (since := "2026-07-08")] alias normalizationMonoid := strongNormalizationMonoid @@ -72,12 +72,12 @@ alias normalizationMonoid := strongNormalizationMonoid theorem normUnit_eq (z : ℤ) : normUnit z = if 0 ≤ z then 1 else -1 := rfl theorem normalize_of_nonneg {z : ℤ} (h : 0 ≤ z) : normalize z = z := by - rw [normalize_apply, normUnit_eq, if_pos h, Units.val_one, mul_one] + rw [normalize_apply, normUnit_eq, ite_eq_left h, Units.val_one, mul_one] theorem normalize_of_nonpos {z : ℤ} (h : z ≤ 0) : normalize z = -z := by obtain rfl | h := h.eq_or_lt · simp - · rw [normalize_apply, normUnit_eq, if_neg (not_le_of_gt h), Units.val_neg, Units.val_one, + · rw [normalize_apply, normUnit_eq, ite_eq_right (not_le_of_gt h), Units.val_neg, Units.val_one, mul_neg_one] theorem normalize_coe_nat (n : ℕ) : normalize (n : ℤ) = n := diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index e520df2ce65f16..3efeebe96e6443 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -594,7 +594,7 @@ theorem npowBinRec.go_spec {M : Type*} [Semigroup M] [One M] (k : ℕ) (m n : M) | one => simp [npowRec'] | bit b k' k'0 ih => rw [Nat.binaryRec_eq _ _ (Or.inl rfl), ih _ _ k'0] - cases b <;> simp only [Nat.bit, cond_false, cond_true, npowRec'_two_mul] + cases b <;> simp only [Nat.bit, Bool.cond_false, Bool.cond_true, npowRec'_two_mul] rw [npowRec'_succ (by lia), npowRec'_two_mul, ← npowRec'_two_mul, ← npowRec'_mul_comm (by lia), mul_assoc] diff --git a/Mathlib/Algebra/Group/End.lean b/Mathlib/Algebra/Group/End.lean index f2ad7a65fbacbf..f3d1b12fa35712 100644 --- a/Mathlib/Algebra/Group/End.lean +++ b/Mathlib/Algebra/Group/End.lean @@ -105,15 +105,15 @@ theorem mul_apply (f g : Perm α) (x) : (f * g) x = f (g x) := theorem one_apply (x) : (1 : Perm α) x = x := rfl -@[pull_end, push_end← ] +@[pull_end, push_end ←] theorem one_def : (1 : Perm α) = Equiv.refl α := rfl -@[pull_end, push_end← ] +@[pull_end, push_end ←] theorem mul_def (f g : Perm α) : f * g = g.trans f := rfl -@[pull_end, push_end← ] +@[pull_end, push_end ←] theorem inv_def (f : Perm α) : f⁻¹ = f.symm := rfl @@ -125,7 +125,7 @@ theorem inv_def (f : Perm α) : f⁻¹ = f.symm := @[norm_cast] lemma coe_pow (f : Perm α) (n : ℕ) : ⇑(f ^ n) = f^[n] := rfl -@[pull_end← , push_end] +@[pull_end ←, push_end] lemma iterate_eq_pow (f : Perm α) (n : ℕ) : f^[n] = ⇑(f ^ n) := rfl theorem eq_inv_iff_eq {f : Perm α} {x y : α} : x = f⁻¹ y ↔ f x = y := diff --git a/Mathlib/Algebra/Group/ForwardDiff.lean b/Mathlib/Algebra/Group/ForwardDiff.lean index 90a86ed78e6758..89564362529c91 100644 --- a/Mathlib/Algebra/Group/ForwardDiff.lean +++ b/Mathlib/Algebra/Group/ForwardDiff.lean @@ -198,12 +198,12 @@ lemma fwdDiff_iter_choose_zero (m n : ℕ) : Δ_[1]^[n] (fun x ↦ x.choose m : ℕ → ℤ) 0 = if n = m then 1 else 0 := by rcases lt_trichotomy m n with hmn | rfl | hnm · rcases Nat.exists_eq_add_of_lt hmn with ⟨k, rfl⟩ - simp_rw [hmn.ne', if_false, (by ring : m + k + 1 = k + 1 + m), iterate_add_apply, + simp_rw [hmn.ne', ite_false, (by ring : m + k + 1 = k + 1 + m), iterate_add_apply, add_zero m ▸ fwdDiff_iter_choose 0 m, choose_zero_right, iterate_one, cast_one, fwdDiff_const, fwdDiff_iter_eq_sum_shift, smul_zero, sum_const_zero] - · simp only [if_true, add_zero m ▸ fwdDiff_iter_choose 0 m, choose_zero_right, cast_one] + · simp only [ite_true, add_zero m ▸ fwdDiff_iter_choose 0 m, choose_zero_right, cast_one] · rcases Nat.exists_eq_add_of_lt hnm with ⟨k, rfl⟩ - simp_rw [hnm.ne, if_false, add_assoc n k 1, fwdDiff_iter_choose, choose_zero_succ, cast_zero] + simp_rw [hnm.ne, ite_false, add_assoc n k 1, fwdDiff_iter_choose, choose_zero_succ, cast_zero] end choose diff --git a/Mathlib/Algebra/GroupWithZero/Hom.lean b/Mathlib/Algebra/GroupWithZero/Hom.lean index 74531ee178a91f..4e906f39a1ec3c 100644 --- a/Mathlib/Algebra/GroupWithZero/Hom.lean +++ b/Mathlib/Algebra/GroupWithZero/Hom.lean @@ -231,12 +231,12 @@ lemma one_apply_def {M₀ N₀ : Type*} [MulZeroOneClass M₀] [MulZeroOneClass lemma one_apply_zero {M₀ N₀ : Type*} [MulZeroOneClass M₀] [MulZeroOneClass N₀] [DecidablePred fun x : M₀ ↦ x = 0] [Nontrivial M₀] [NoZeroDivisors M₀] : (1 : M₀ →*₀ N₀) 0 = 0 := - if_pos rfl + ite_eq_left rfl lemma one_apply_of_ne_zero {M₀ N₀ : Type*} [MulZeroOneClass M₀] [MulZeroOneClass N₀] [DecidablePred fun x : M₀ ↦ x = 0] [Nontrivial M₀] [NoZeroDivisors M₀] {x : M₀} (hx : x ≠ 0) : (1 : M₀ →*₀ N₀) x = 1 := - if_neg hx + ite_eq_right hx @[simp] lemma one_apply_eq_zero_iff {M₀ N₀ : Type*} [MulZeroOneClass M₀] [MulZeroOneClass N₀] diff --git a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean index f5962b7713cfc6..b3148d9bd8bac8 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean @@ -88,14 +88,14 @@ scoped postfix:max "⁻¹ʳ" => inverse /-- By definition, if `x` is invertible then `inverse x = x⁻¹`. -/ theorem inverse_unit (u : M₀ˣ) : (u : M₀)⁻¹ʳ = (u⁻¹ : M₀ˣ) := by - rw [inverse, dif_pos u.isUnit, IsUnit.unit_of_val_units] + rw [inverse, dite_eq_left u.isUnit, IsUnit.unit_of_val_units] -theorem inverse_of_isUnit {x : M₀} (h : IsUnit x) : x⁻¹ʳ = ((h.unit⁻¹ : M₀ˣ) : M₀) := dif_pos h +theorem inverse_of_isUnit {x : M₀} (h : IsUnit x) : x⁻¹ʳ = ((h.unit⁻¹ : M₀ˣ) : M₀) := dite_eq_left h /-- By definition, if `x` is not invertible then `inverse x = 0`. -/ @[simp] theorem inverse_non_unit (x : M₀) (h : ¬IsUnit x) : x⁻¹ʳ = 0 := - dif_neg h + dite_eq_right h theorem mul_inverse_cancel (x : M₀) (h : IsUnit x) : x * x⁻¹ʳ = 1 := by rcases h with ⟨u, rfl⟩ @@ -516,10 +516,10 @@ noncomputable def groupWithZeroOfIsUnitOrEqZero [hM : MonoidWithZero M] (h : ∀ a : M, IsUnit a ∨ a = 0) : GroupWithZero M := { hM with inv := fun a => if h0 : a = 0 then 0 else ↑((h a).resolve_right h0).unit⁻¹, - inv_zero := dif_pos rfl, + inv_zero := dite_eq_left rfl, mul_inv_cancel := fun a h0 => by change (a * if h0 : a = 0 then 0 else ↑((h a).resolve_right h0).unit⁻¹) = 1 - rw [dif_neg h0, Units.mul_inv_eq_iff_eq_mul, one_mul, IsUnit.unit_spec] } + rw [dite_eq_right h0, Units.mul_inv_eq_iff_eq_mul, one_mul, IsUnit.unit_spec] } /-- Constructs a `CommGroupWithZero` structure on a `CommMonoidWithZero` consisting only of units and 0. -/ diff --git a/Mathlib/Algebra/GroupWithZero/WithZero.lean b/Mathlib/Algebra/GroupWithZero/WithZero.lean index 508b4790bfe152..085ca266bc2a66 100644 --- a/Mathlib/Algebra/GroupWithZero/WithZero.lean +++ b/Mathlib/Algebra/GroupWithZero/WithZero.lean @@ -413,7 +413,7 @@ def log (x : Mᵐ⁰) : M := x.recZeroCoe 0 Multiplicative.toAdd lemma log_mul {x y : Mᵐ⁰} (hx : x ≠ 0) (hy : y ≠ 0) : log (x * y) = log x + log y := by lift x to Multiplicative M using hx; lift y to Multiplicative M using hy; rfl -@[simp← ] lemma exp_nsmul (n : ℕ) (a : M) : exp (n • a) = exp a ^ n := rfl +@[simp ←] lemma exp_nsmul (n : ℕ) (a : M) : exp (n • a) = exp a ^ n := rfl @[simp] lemma log_pow : ∀ (x : Mᵐ⁰) (n : ℕ), log (x ^ n) = n • log x @@ -458,7 +458,7 @@ lemma log_inv : ∀ x : Gᵐ⁰, log x⁻¹ = -log x | 0 => by simp | (x : Multiplicative G) => rfl -@[simp← ] lemma exp_zsmul (n : ℤ) (a : G) : exp (n • a) = exp a ^ n := rfl +@[simp ←] lemma exp_zsmul (n : ℤ) (a : G) : exp (n • a) = exp a ^ n := rfl @[simp] lemma log_zpow (x : Gᵐ⁰) (n : ℤ) : log (x ^ n) = n • log x := by cases n <;> simp [log_pow, log_inv] diff --git a/Mathlib/Algebra/Homology/Bifunctor.lean b/Mathlib/Algebra/Homology/Bifunctor.lean index 59d1f1dbe6110c..57fa435e345b12 100644 --- a/Mathlib/Algebra/Homology/Bifunctor.lean +++ b/Mathlib/Algebra/Homology/Bifunctor.lean @@ -138,11 +138,11 @@ noncomputable abbrev ιMapBifunctorOrZero (i₁ : I₁) (i₂ : I₂) (j : J) : lemma ιMapBifunctorOrZero_eq (i₁ : I₁) (i₂ : I₂) (j : J) (h : ComplexShape.π c₁ c₂ c (i₁, i₂) = j) : - ιMapBifunctorOrZero K₁ K₂ F c i₁ i₂ j = ιMapBifunctor K₁ K₂ F c i₁ i₂ j h := dif_pos h + ιMapBifunctorOrZero K₁ K₂ F c i₁ i₂ j = ιMapBifunctor K₁ K₂ F c i₁ i₂ j h := dite_eq_left h lemma ιMapBifunctorOrZero_eq_zero (i₁ : I₁) (i₂ : I₂) (j : J) (h : ComplexShape.π c₁ c₂ c (i₁, i₂) ≠ j) : - ιMapBifunctorOrZero K₁ K₂ F c i₁ i₂ j = 0 := dif_neg h + ιMapBifunctorOrZero K₁ K₂ F c i₁ i₂ j = 0 := dite_eq_right h section diff --git a/Mathlib/Algebra/Homology/BifunctorAssociator.lean b/Mathlib/Algebra/Homology/BifunctorAssociator.lean index 9de2cc124aca4c..1780d7ba29fdcb 100644 --- a/Mathlib/Algebra/Homology/BifunctorAssociator.lean +++ b/Mathlib/Algebra/Homology/BifunctorAssociator.lean @@ -159,11 +159,11 @@ noncomputable def ιOrZero (i₁ : ι₁) (i₂ : ι₂) (i₃ : ι₃) (j : ι lemma ιOrZero_eq (i₁ : ι₁) (i₂ : ι₂) (i₃ : ι₃) (j : ι₄) (h : ComplexShape.r c₁ c₂ c₃ c₁₂ c₄ (i₁, i₂, i₃) = j) : ιOrZero F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j = - ι F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j h := dif_pos h + ι F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j h := dite_eq_left h lemma ιOrZero_eq_zero (i₁ : ι₁) (i₂ : ι₂) (i₃ : ι₃) (j : ι₄) (h : ComplexShape.r c₁ c₂ c₃ c₁₂ c₄ (i₁, i₂, i₃) ≠ j) : - ιOrZero F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j = 0 := dif_neg h + ιOrZero F₁₂ G K₁ K₂ K₃ c₁₂ c₄ i₁ i₂ i₃ j = 0 := dite_eq_right h variable {F₁₂ G K₁ K₂ K₃ c₁₂ c₄} in @[ext] @@ -449,11 +449,11 @@ noncomputable def ιOrZero (i₁ : ι₁) (i₂ : ι₂) (i₃ : ι₃) (j : ι lemma ιOrZero_eq (i₁ : ι₁) (i₂ : ι₂) (i₃ : ι₃) (j : ι₄) (h : ComplexShape.r c₁ c₂ c₃ c₁₂ c₄ (i₁, i₂, i₃) = j) : ιOrZero F G₂₃ K₁ K₂ K₃ c₁₂ c₂₃ c₄ i₁ i₂ i₃ j = - ι F G₂₃ K₁ K₂ K₃ c₁₂ c₂₃ c₄ i₁ i₂ i₃ j h := dif_pos h + ι F G₂₃ K₁ K₂ K₃ c₁₂ c₂₃ c₄ i₁ i₂ i₃ j h := dite_eq_left h lemma ιOrZero_eq_zero (i₁ : ι₁) (i₂ : ι₂) (i₃ : ι₃) (j : ι₄) (h : ComplexShape.r c₁ c₂ c₃ c₁₂ c₄ (i₁, i₂, i₃) ≠ j) : - ιOrZero F G₂₃ K₁ K₂ K₃ c₁₂ c₂₃ c₄ i₁ i₂ i₃ j = 0 := dif_neg h + ιOrZero F G₂₃ K₁ K₂ K₃ c₁₂ c₂₃ c₄ i₁ i₂ i₃ j = 0 := dite_eq_right h variable [HasGoodTrifunctor₂₃Obj F G₂₃ K₁ K₂ K₃ c₁₂ c₂₃ c₄] diff --git a/Mathlib/Algebra/Homology/ComplexShape.lean b/Mathlib/Algebra/Homology/ComplexShape.lean index 79e961dc96d294..7a8b0a3ded9ac3 100644 --- a/Mathlib/Algebra/Homology/ComplexShape.lean +++ b/Mathlib/Algebra/Homology/ComplexShape.lean @@ -148,13 +148,13 @@ def next (c : ComplexShape ι) (i : ι) : ι := theorem next_eq' (c : ComplexShape ι) {i j : ι} (h : c.Rel i j) : c.next i = j := by apply c.next_eq _ h rw [next] - rw [dif_pos] + rw [dite_eq_left] exact Exists.choose_spec ⟨j, h⟩ @[to_dual] lemma next_eq_self' (c : ComplexShape ι) (j : ι) (hj : ∀ k, ¬c.Rel j k) : c.next j = j := - dif_neg (by simpa using hj) + dite_eq_right (by simpa using hj) @[to_dual] lemma next_eq_self (c : ComplexShape ι) (j : ι) (hj : ¬c.Rel j (c.next j)) : diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean index 2ee4d31030b25e..2abba2bebf4ca3 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean @@ -484,7 +484,7 @@ noncomputable def Ext.biproductAddEquiv {J : Type*} [Fintype J] {X : J → C} {c simp only [Ext.comp_sum, ← comp_assoc_of_second_deg_zero, mk₀_comp_mk₀] rw [Finset.sum_eq_single i _ (by simp), bicone_ι_π_self, mk₀_id_comp] intro _ _ hij - rw [c.ι_π, dif_neg hij.symm, mk₀_zero, zero_comp] + rw [c.ι_π, dite_eq_right hij.symm, mk₀_zero, zero_comp] map_add' _ _ := by simp only [comp_add, Pi.add_def] @@ -501,7 +501,7 @@ noncomputable def Ext.addEquivBiproduct (X : C) {J : Type*} [Fintype J] {Y : J simp only [Ext.sum_comp, comp_assoc_of_second_deg_zero, mk₀_comp_mk₀] rw [Finset.sum_eq_single i _ (by simp), bicone_ι_π_self, comp_mk₀_id] intro _ _ hij - rw [c.ι_π, dif_neg hij, mk₀_zero, comp_zero] + rw [c.ι_π, dite_eq_right hij, mk₀_zero, comp_zero] map_add' _ _ := by simp only [add_comp, Pi.add_def] diff --git a/Mathlib/Algebra/Homology/DifferentialObject.lean b/Mathlib/Algebra/Homology/DifferentialObject.lean index 5bd5eb6ce941e4..2c355d5c224764 100644 --- a/Mathlib/Algebra/Homology/DifferentialObject.lean +++ b/Mathlib/Algebra/Homology/DifferentialObject.lean @@ -87,7 +87,7 @@ def dgoToHomologicalComplex : { X := fun i => X.obj i d := fun i j => if h : i + b = j then X.d i ≫ X.objEqToHom (show i + (1 : ℤ) • b = j by simp [h]) else 0 - shape := fun i j w => by dsimp at w; convert! dif_neg w + shape := fun i j w => by dsimp at w; convert! dite_eq_right w d_comp_d' := fun i j k hij hjk => by dsimp at hij hjk; subst hij hjk simp [objEqToHom_d_assoc] } diff --git a/Mathlib/Algebra/Homology/Double.lean b/Mathlib/Algebra/Homology/Double.lean index c4ecd3ea3d8416..6c0983078dc0f3 100644 --- a/Mathlib/Algebra/Homology/Double.lean +++ b/Mathlib/Algebra/Homology/Double.lean @@ -40,8 +40,8 @@ noncomputable def double : HomologicalComplex C c where X k := if k = i₀ then X₀ else if k = i₁ then X₁ else 0 d k k' := if hk : k = i₀ ∧ k' = i₁ ∧ i₀ ≠ i₁ then - eqToHom (if_pos hk.1) ≫ f ≫ eqToHom (by - rw [if_neg, if_pos hk.2.1] + eqToHom (ite_eq_left hk.1) ≫ f ≫ eqToHom (by + rw [ite_eq_right, ite_eq_left hk.2.1] aesop) else 0 d_comp_d' := by @@ -51,40 +51,40 @@ noncomputable def double : HomologicalComplex C c where · subst hi by_cases hj : j = i₁ · subst hj - nth_rw 2 [dif_neg (by tauto)] + nth_rw 2 [dite_eq_right (by tauto)] rw [comp_zero] - · rw [dif_neg (by tauto), zero_comp] - · rw [dif_neg (by tauto), zero_comp] - shape i j hij := dif_neg (by aesop) + · rw [dite_eq_right (by tauto), zero_comp] + · rw [dite_eq_right (by tauto), zero_comp] + shape i j hij := dite_eq_right (by aesop) lemma isZero_double_X (k : ι) (h₀ : k ≠ i₀) (h₁ : k ≠ i₁) : IsZero ((double f hi₀₁).X k) := by dsimp [double] - rw [if_neg h₀, if_neg h₁] + rw [ite_eq_right h₀, ite_eq_right h₁] exact Limits.isZero_zero C /-- The isomorphism `(double f hi₀₁).X i₀ ≅ X₀`. -/ noncomputable def doubleXIso₀ : (double f hi₀₁).X i₀ ≅ X₀ := - eqToIso (dif_pos rfl) + eqToIso (dite_eq_left rfl) /-- The isomorphism `(double f hi₀₁).X i₁ ≅ X₁`. -/ noncomputable def doubleXIso₁ (h : i₀ ≠ i₁) : (double f hi₀₁).X i₁ ≅ X₁ := eqToIso (by dsimp [double] - rw [if_neg h.symm, if_pos rfl]) + rw [ite_eq_right h.symm, ite_eq_left rfl]) lemma double_d (h : i₀ ≠ i₁) : (double f hi₀₁).d i₀ i₁ = (doubleXIso₀ f hi₀₁).hom ≫ f ≫ (doubleXIso₁ f hi₀₁ h).inv := - dif_pos ⟨rfl, rfl, h⟩ + dite_eq_left ⟨rfl, rfl, h⟩ lemma double_d_eq_zero₀ (a b : ι) (ha : a ≠ i₀) : (double f hi₀₁).d a b = 0 := - dif_neg (by tauto) + dite_eq_right (by tauto) lemma double_d_eq_zero₁ (a b : ι) (hb : b ≠ i₁) : (double f hi₀₁).d a b = 0 := - dif_neg (by tauto) + dite_eq_right (by tauto) variable {f hi₀₁} in @[ext] @@ -124,14 +124,14 @@ noncomputable def mkHomFromDouble : double f hi₀₁ ⟶ K where comm' k₀ k₁ hk := by by_cases h₀ : k₀ = i₀ · subst h₀ - rw [dif_pos rfl] + rw [dite_eq_left rfl] obtain rfl := c.next_eq hk hi₀₁ - simp [dif_neg h.symm, double_d f hi₀₁ h, comm] - · rw [dif_neg h₀] + simp [dite_eq_right h.symm, double_d f hi₀₁ h, comm] + · rw [dite_eq_right h₀] by_cases h₁ : k₀ = i₁ · subst h₁ dsimp - rw [if_pos rfl, comp_id, id_comp, assoc, hφ k₁ hk, comp_zero, + rw [ite_eq_left rfl, comp_id, id_comp, assoc, hφ k₁ hk, comp_zero, double_d_eq_zero₀ _ _ _ _ h.symm, zero_comp] · apply (isZero_double_X f hi₀₁ k₀ h₀ h₁).eq_of_src @@ -140,14 +140,14 @@ lemma mkHomFromDouble_f₀ : (mkHomFromDouble hi₀₁ h φ₀ φ₁ comm hφ).f i₀ = (doubleXIso₀ f hi₀₁).hom ≫ φ₀ := by dsimp [mkHomFromDouble] - rw [if_pos rfl, id_comp, comp_id] + rw [ite_eq_left rfl, id_comp, comp_id] @[simp, reassoc] lemma mkHomFromDouble_f₁ : (mkHomFromDouble hi₀₁ h φ₀ φ₁ comm hφ).f i₁ = (doubleXIso₁ f hi₀₁ h).hom ≫ φ₁ := by dsimp [mkHomFromDouble] - rw [dif_neg h.symm, if_pos rfl, id_comp, comp_id] + rw [dite_eq_right h.symm, ite_eq_left rfl, id_comp, comp_id] end diff --git a/Mathlib/Algebra/Homology/Embedding/Basic.lean b/Mathlib/Algebra/Homology/Embedding/Basic.lean index c43326357b4176..36c33108d11b3e 100644 --- a/Mathlib/Algebra/Homology/Embedding/Basic.lean +++ b/Mathlib/Algebra/Homology/Embedding/Basic.lean @@ -149,11 +149,11 @@ lemma r_eq_some {i : ι} {i' : ι'} (hi : e.f i = i') : have h : ∃ (i : ι), e.f i = i' := ⟨i, hi⟩ have : h.choose = i := e.injective_f (h.choose_spec.trans (hi.symm)) dsimp [r] - rw [dif_pos ⟨i, hi⟩, this] + rw [dite_eq_left ⟨i, hi⟩, this] lemma r_eq_none (i' : ι') (hi : ∀ i, e.f i ≠ i') : e.r i' = none := - dif_neg (by + dite_eq_right (by rintro ⟨i, hi'⟩ exact hi i hi') diff --git a/Mathlib/Algebra/Homology/Embedding/TruncGE.lean b/Mathlib/Algebra/Homology/Embedding/TruncGE.lean index 25c81687628d28..a52a44c7a71d24 100644 --- a/Mathlib/Algebra/Homology/Embedding/TruncGE.lean +++ b/Mathlib/Algebra/Homology/Embedding/TruncGE.lean @@ -66,12 +66,12 @@ noncomputable def X (i : ι) : C := /-- The isomorphism `truncGE'.X K e i ≅ K.opcycles (e.f i)` when `e.BoundaryGE i` holds. -/ noncomputable def XIsoOpcycles {i : ι} (hi : e.BoundaryGE i) : X K e i ≅ K.opcycles (e.f i) := - eqToIso (if_pos hi) + eqToIso (ite_eq_left hi) /-- The isomorphism `truncGE'.X K e i ≅ K.X (e.f i)` when `e.BoundaryGE i` does not hold. -/ noncomputable def XIso {i : ι} (hi : ¬ e.BoundaryGE i) : X K e i ≅ K.X (e.f i) := - eqToIso (if_neg hi) + eqToIso (ite_eq_right hi) open scoped Classical in /-- The `d` field of `truncGE'`. -/ @@ -90,10 +90,10 @@ lemma d_comp_d (i j k : ι) : d K e i j ≫ d K e j k = 0 := by dsimp [d] by_cases hij : c.Rel i j · by_cases hjk : c.Rel j k - · rw [dif_pos hij, dif_pos hjk, dif_neg (e.not_boundaryGE_next hij)] + · rw [dite_eq_left hij, dite_eq_left hjk, dite_eq_right (e.not_boundaryGE_next hij)] split_ifs <;> simp - · rw [dif_neg hjk, comp_zero] - · rw [dif_neg hij, zero_comp] + · rw [dite_eq_right hjk, comp_zero] + · rw [dite_eq_right hij, zero_comp] end truncGE' @@ -102,7 +102,7 @@ of complex shapes `e` which satisfies `e.IsTruncGE`. -/ noncomputable def truncGE' : HomologicalComplex C c where X := truncGE'.X K e d := truncGE'.d K e - shape _ _ h := dif_neg h + shape _ _ h := dite_eq_right h /-- The isomorphism `(K.truncGE' e).X i ≅ K.X i'` when `e.f i = i'` and `e.BoundaryGE i` does not hold. -/ @@ -122,7 +122,7 @@ lemma truncGE'_d_eq {i j : ι} (hij : c.Rel i j) {i' j' : ι'} (K.truncGE' e).d i j = (K.truncGE'XIso e hi' hi).hom ≫ K.d i' j' ≫ (K.truncGE'XIso e hj' (e.not_boundaryGE_next hij)).inv := by dsimp [truncGE', truncGE'.d] - rw [dif_pos hij, dif_neg hi] + rw [dite_eq_left hij, dite_eq_right hi] subst hi' hj' simp [truncGE'XIso] @@ -132,7 +132,7 @@ lemma truncGE'_d_eq_fromOpcycles {i j : ι} (hij : c.Rel i j) {i' j' : ι'} (K.truncGE' e).d i j = (K.truncGE'XIsoOpcycles e hi' hi).hom ≫ K.fromOpcycles i' j' ≫ (K.truncGE'XIso e hj' (e.not_boundaryGE_next hij)).inv := by dsimp [truncGE', truncGE'.d] - rw [dif_pos hij, dif_pos hi] + rw [dite_eq_left hij, dite_eq_left hi] subst hi' hj' simp [truncGE'XIso, truncGE'XIsoOpcycles] @@ -173,12 +173,12 @@ noncomputable def truncGE'Map : K.truncGE' e ⟶ L.truncGE' e where else (K.truncGE'XIso e rfl hi).hom ≫ φ.f (e.f i) ≫ (L.truncGE'XIso e rfl hi).inv comm' i j hij := by - rw [dif_neg (e.not_boundaryGE_next hij)] + rw [dite_eq_right (e.not_boundaryGE_next hij)] by_cases hi : e.BoundaryGE i - · rw [dif_pos hi] + · rw [dite_eq_left hi] simp [truncGE'_d_eq_fromOpcycles _ e hij rfl rfl hi, ← cancel_epi (K.pOpcycles (e.f i))] - · rw [dif_neg hi] + · rw [dite_eq_right hi] simp [truncGE'_d_eq _ e hij rfl rfl hi] lemma truncGE'Map_f_eq_opcyclesMap {i : ι} (hi : e.BoundaryGE i) {i' : ι'} (h : e.f i = i') : @@ -186,13 +186,13 @@ lemma truncGE'Map_f_eq_opcyclesMap {i : ι} (hi : e.BoundaryGE i) {i' : ι'} (h (K.truncGE'XIsoOpcycles e h hi).hom ≫ opcyclesMap φ i' ≫ (L.truncGE'XIsoOpcycles e h hi).inv := by subst h - exact dif_pos hi + exact dite_eq_left hi lemma truncGE'Map_f_eq {i : ι} (hi : ¬ e.BoundaryGE i) {i' : ι'} (h : e.f i = i') : (truncGE'Map φ e).f i = (K.truncGE'XIso e h hi).hom ≫ φ.f i' ≫ (L.truncGE'XIso e h hi).inv := by subst h - exact dif_neg hi + exact dite_eq_right hi variable (K) in @[simp] @@ -242,7 +242,7 @@ lemma f_eq_iso_hom_pOpcycles_iso_inv {i : ι} {i' : ι'} (hi' : e.f i = i') (hi f K e i = (K.restrictionXIso e hi').hom ≫ K.pOpcycles i' ≫ (K.truncGE'XIsoOpcycles e hi' hi).inv := by dsimp [f] - rw [dif_pos hi] + rw [dite_eq_left hi] subst hi' simp [restrictionXIso] @@ -251,7 +251,7 @@ set_option backward.defeqAttrib.useBackward true in lemma f_eq_iso_hom_iso_inv {i : ι} {i' : ι'} (hi' : e.f i = i') (hi : ¬ e.BoundaryGE i) : f K e i = (K.restrictionXIso e hi').hom ≫ (K.truncGE'XIso e hi' hi).inv := by dsimp [f] - rw [dif_neg hi] + rw [dite_eq_right hi] subst hi' simp [restrictionXIso] diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 92c5358a95dd46..5cdf22f662c7a9 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -170,7 +170,7 @@ theorem next (α : Type*) [AddGroup α] [One α] (i : α) : (ComplexShape.down @[simp] theorem next_nat_zero : (ComplexShape.down ℕ).next 0 = 0 := by - refine dif_neg ?_ + refine dite_eq_right ?_ push Not intro apply Nat.noConfusion @@ -194,7 +194,7 @@ theorem next (α : Type*) [AddRightCancelSemigroup α] [One α] (i : α) : @[simp] theorem prev_nat_zero : (ComplexShape.up ℕ).prev 0 = 0 := by - refine dif_neg ?_ + refine dite_eq_right ?_ push Not intro apply Nat.noConfusion @@ -412,7 +412,7 @@ def xPrevIsoSelf {j : ι} (h : ¬c.Rel (c.prev j) j) : C.xPrev j ≅ C.X j := congr_arg C.X (by dsimp [ComplexShape.prev] - rw [dif_neg] + rw [dite_eq_right] push Not; intro i hi have : c.prev j = i := c.prev_eq' hi rw [this] at h; contradiction) @@ -431,7 +431,7 @@ def xNextIsoSelf {i : ι} (h : ¬c.Rel i (c.next i)) : C.xNext i ≅ C.X i := congr_arg C.X (by dsimp [ComplexShape.next] - rw [dif_neg]; rintro ⟨j, hj⟩ + rw [dite_eq_right]; rintro ⟨j, hj⟩ have : c.next i = j := c.next_eq' hj rw [this] at h; contradiction) @@ -655,10 +655,10 @@ theorem of_X : (of X d sq).X = X := @[simp] theorem of_d (j : α) : of.d X d (j + 1) j = d j := by dsimp [of.d] - rw [if_pos rfl, Category.id_comp] + rw [ite_eq_left rfl, Category.id_comp] theorem of_d_ne {i j : α} (h : i ≠ j + 1) : of.d X d i j = 0 := by - simp [of.d, dif_neg h] + simp [of.d, dite_eq_right h] end Of @@ -722,12 +722,12 @@ theorem mk_X_2 : (mk X₀ X₁ X₂ d₀ d₁ s succ).X 2 = X₂ := @[simp] theorem mk_d_1_0 : (mk X₀ X₁ X₂ d₀ d₁ s succ).d 1 0 = d₀ := by change ite (1 = 0 + 1) (𝟙 X₁ ≫ d₀) 0 = d₀ - rw [if_pos rfl, Category.id_comp] + rw [ite_eq_left rfl, Category.id_comp] @[simp] theorem mk_d_2_1 : (mk X₀ X₁ X₂ d₀ d₁ s succ).d 2 1 = d₁ := by change ite (2 = 1 + 1) (𝟙 X₂ ≫ d₁) 0 = d₁ - rw [if_pos rfl, Category.id_comp] + rw [ite_eq_left rfl, Category.id_comp] lemma mk_congr_succ_X₃ {S S' : ShortComplex V} (h : S = S') : (succ S).1 = (succ S').1 := by rw [h] @@ -765,7 +765,7 @@ lemma mk_d (n : ℕ) : rw [eqToHom_refl, comp_id] at eq refine Eq.trans ?_ eq dsimp only [mk, of, of.d] - rw [dif_pos (by rfl), eqToHom_refl, id_comp] + rw [dite_eq_left (by rfl), eqToHom_refl, id_comp] rfl /-- A simpler inductive constructor for `ℕ`-indexed chain complexes. @@ -793,7 +793,7 @@ theorem mk'_X_1 : (mk' X₀ X₁ d₀ succ').X 1 = X₁ := @[simp] theorem mk'_d_1_0 : (mk' X₀ X₁ d₀ succ').d 1 0 = d₀ := by change ite (1 = 0 + 1) (𝟙 X₁ ≫ d₀) 0 = d₀ - rw [if_pos rfl, Category.id_comp] + rw [ite_eq_left rfl, Category.id_comp] set_option backward.isDefEq.respectTransparency.types false in /-- The isomorphism from `(mk' X₀ X₁ d₀ succ').X (n + 2)` that is given by @@ -902,7 +902,7 @@ abbrev of (X : α → V) (d : ∀ n, X n ⟶ X (n + 1)) (sq : ∀ n, d n ≫ d ( CochainComplex V α := { X := X d := of.d X d - shape := fun i j w => dif_neg (c := i + 1 = j) w + shape := fun i j w => dite_eq_right (c := i + 1 = j) w d_comp_d' := fun i j k => by dsimp [of.d] split_ifs with h h' h' @@ -918,10 +918,10 @@ theorem of_X : (of X d sq).X = X := @[simp] theorem of_d (j : α) : of.d X d j (j + 1) = d j := by dsimp [of.d] - rw [if_pos rfl, Category.comp_id] + rw [ite_eq_left rfl, Category.comp_id] theorem of_d_ne {i j : α} (h : i + 1 ≠ j) : of.d X d i j = 0 := by - simp [of.d, dif_neg h] + simp [of.d, dite_eq_right h] end Of @@ -984,12 +984,12 @@ theorem mk_X_2 : (mk X₀ X₁ X₂ d₀ d₁ s succ).X 2 = X₂ := @[simp] theorem mk_d_1_0 : (mk X₀ X₁ X₂ d₀ d₁ s succ).d 0 1 = d₀ := by change ite (1 = 0 + 1) (d₀ ≫ 𝟙 X₁) 0 = d₀ - rw [if_pos rfl, Category.comp_id] + rw [ite_eq_left rfl, Category.comp_id] @[simp] theorem mk_d_2_0 : (mk X₀ X₁ X₂ d₀ d₁ s succ).d 1 2 = d₁ := by change ite (2 = 1 + 1) (d₁ ≫ 𝟙 X₂) 0 = d₁ - rw [if_pos rfl, Category.comp_id] + rw [ite_eq_left rfl, Category.comp_id] -- TODO simp lemmas for the inductive steps? It's not entirely clear that they are needed. /-- A simpler inductive constructor for `ℕ`-indexed cochain complexes. @@ -1017,7 +1017,7 @@ theorem mk'_X_1 : (mk' X₀ X₁ d₀ succ').X 1 = X₁ := @[simp] theorem mk'_d_1_0 : (mk' X₀ X₁ d₀ succ').d 0 1 = d₀ := by change ite (1 = 0 + 1) (d₀ ≫ 𝟙 X₁) 0 = d₀ - rw [if_pos rfl, Category.comp_id] + rw [ite_eq_left rfl, Category.comp_id] -- TODO simp lemmas for the inductive steps? It's not entirely clear that they are needed. end Mk diff --git a/Mathlib/Algebra/Homology/Homotopy.lean b/Mathlib/Algebra/Homology/Homotopy.lean index 16cb0345f8b25f..622b464b6a1687 100644 --- a/Mathlib/Algebra/Homology/Homotopy.lean +++ b/Mathlib/Algebra/Homology/Homotopy.lean @@ -530,7 +530,7 @@ def mkInductive : Homotopy e 0 where if h : i + 1 = j then (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.1 ≫ (Q.xPrevIso h).hom else 0 - zero i j w := by rw [dif_neg]; exact w + zero i j w := by rw [dite_eq_right]; exact w comm i := by dsimp simp only [add_zero] @@ -544,7 +544,7 @@ def mkInductive : Homotopy e 0 where dsimp [xNextIso] rw [id_comp] · dsimp [toPrev] - rw [dif_pos (by simp only [ChainComplex.prev])] + rw [dite_eq_left (by simp only [ChainComplex.prev])] simp [xPrevIso, comp_id] end @@ -664,7 +664,7 @@ def mkCoinductive : Homotopy e 0 where if h : j + 1 = i then (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1 else 0 - zero i j w := by rw [dif_neg]; exact w + zero i j w := by rw [dite_eq_right]; exact w comm i := by dsimp simp only [add_zero] @@ -679,7 +679,7 @@ def mkCoinductive : Homotopy e 0 where dsimp [xPrevIso] rw [comp_id] · dsimp [fromNext] - rw [dif_pos (by simp only [CochainComplex.next])] + rw [dite_eq_left (by simp only [CochainComplex.next])] simp [xNextIso, id_comp] end diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index ea74f0b4ea0d69..2494d1d86d4ca6 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -788,14 +788,14 @@ def equivHomotopy (φ₁ φ₂ : F ⟶ G) : toFun ho := ⟨Cochain.ofHomotopy ho, by simp only [δ_ofHomotopy, sub_add_cancel]⟩ invFun z := { hom := fun i j => if hij : i + (-1) = j then z.1.v i j hij else 0 - zero := fun i j (hij : j + 1 ≠ i) => dif_neg (fun _ => hij (by lia)) + zero := fun i j (hij : j + 1 ≠ i) => dite_eq_right (fun _ => hij (by lia)) comm := fun p => by have eq := Cochain.congr_v z.2 p p (add_zero p) have h₁ : (ComplexShape.up ℤ).Rel (p - 1) p := by simp have h₂ : (ComplexShape.up ℤ).Rel p (p + 1) := by simp simp only [δ_neg_one_cochain, Cochain.ofHom_v, ComplexShape.up_Rel, Cochain.add_v, Homotopy.nullHomotopicMap'_f h₁ h₂] at eq - rw [dNext_eq _ h₂, prevD_eq _ h₁, eq, dif_pos, dif_pos] } + rw [dNext_eq _ h₂, prevD_eq _ h₁, eq, dite_eq_left, dite_eq_left] } left_inv := fun ho => by ext i j dsimp @@ -805,7 +805,7 @@ def equivHomotopy (φ₁ φ₂ : F ⟶ G) : right_inv := fun z => by ext p q hpq dsimp [Cochain.ofHomotopy] - rw [dif_pos hpq] + rw [dite_eq_left hpq] @[simp] lemma equivHomotopy_apply_of_eq {φ₁ φ₂ : F ⟶ G} (h : φ₁ = φ₂) : @@ -829,14 +829,14 @@ set_option backward.defeqAttrib.useBackward true in lemma single_v {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (hpq : p + n = q) : (single f n).v p q hpq = f := by dsimp [single] - rw [if_pos, id_comp, comp_id] + rw [ite_eq_left, id_comp, comp_id] tauto lemma single_v_eq_zero {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (p' q' : ℤ) (hpq' : p' + n = q') (hp' : p' ≠ p) : (single f n).v p' q' hpq' = 0 := by dsimp [single] - rw [dif_neg] + rw [dite_eq_right] intro h exact hp' (by lia) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean b/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean index dab3233c370f21..909cf3cecfe6ab 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean @@ -49,7 +49,7 @@ noncomputable def singleFunctors : SingleFunctors C (CochainComplex C ℤ) ℤ w · subst h simp only [Functor.comp_obj, shiftFunctor_obj_X', single_obj_X_self] · dsimp [single] - rw [if_neg h, if_neg (fun h' => h (by lia))]))) + rw [ite_eq_right h, ite_eq_right (fun h' => h (by lia))]))) (fun {X Y} f => by obtain rfl : a' = a + n := by lia ext diff --git a/Mathlib/Algebra/Homology/HomotopyCofiber.lean b/Mathlib/Algebra/Homology/HomotopyCofiber.lean index 22faf6867b78bf..3862e48b921df8 100644 --- a/Mathlib/Algebra/Homology/HomotopyCofiber.lean +++ b/Mathlib/Algebra/Homology/HomotopyCofiber.lean @@ -72,12 +72,12 @@ noncomputable def XIsoBiprod (i j : ι) (hij : c.Rel i j) [HasBinaryBiproduct (F X φ i ≅ F.X j ⊞ G.X i := eqToIso (by obtain rfl := c.next_eq' hij - apply dif_pos hij) + apply dite_eq_left hij) /-- The canonical isomorphism `(homotopyCofiber φ).X i ≅ G.X i` when `¬ c.Rel i (c.next i)`. -/ noncomputable def XIso (i : ι) (hi : ¬ c.Rel i (c.next i)) : X φ i ≅ G.X i := - eqToIso (dif_neg hi) + eqToIso (dite_eq_right hi) lemma isZero_X (i : ι) (hG : IsZero (G.X i)) (hF : ∀ (j : ι), c.Rel i j → IsZero (F.X j)) : @@ -116,7 +116,7 @@ lemma inrX_sndX (i : ι) : inrX φ i ≫ sndX φ i = 𝟙 _ := by lemma sndX_inrX (i : ι) (hi : ¬ c.Rel i (c.next i)) : sndX φ i ≫ inrX φ i = 𝟙 _ := by dsimp [sndX, inrX] - simp only [dif_neg hi, Iso.hom_inv_id] + simp only [dite_eq_right hi, Iso.hom_inv_id] /-- The first projection `(homotopyCofiber φ).X i ⟶ F.X j` when `c.Rel i j`. -/ noncomputable def fstX (i j : ι) (hij : c.Rel i j) : X φ i ⟶ F.X j := @@ -137,13 +137,13 @@ lemma inlX_fstX (i j : ι) (hij : c.Rel j i) : lemma inlX_sndX (i j : ι) (hij : c.Rel j i) : inlX φ i j hij ≫ sndX φ j = 0 := by obtain rfl := c.next_eq' hij - simp [inlX, sndX, dif_pos hij] + simp [inlX, sndX, dite_eq_left hij] @[reassoc (attr := simp)] lemma inrX_fstX (i j : ι) (hij : c.Rel i j) : inrX φ i ≫ fstX φ i j hij = 0 := by obtain rfl := c.next_eq' hij - simp [inrX, fstX, dif_pos hij] + simp [inrX, fstX, dite_eq_left hij] @[reassoc (attr := simp)] lemma inlX_XIsoBiprod_hom (i j : ι) (hij : c.Rel j i) : @@ -164,7 +164,7 @@ lemma inrX_XIsoBiprod_hom (i j : ι) (hij : c.Rel j i) : inrX φ j ≫ (XIsoBiprod φ j i hij).hom = biprod.inr := by obtain rfl := c.next_eq' hij have := HasHomotopyCofiber.hasBinaryBiproduct φ _ _ hij - simp [inrX, XIsoBiprod, dif_pos hij] + simp [inrX, XIsoBiprod, dite_eq_left hij] @[reassoc (attr := simp)] lemma inr_XIsoBiprod_inv (i j : ι) (hij : c.Rel j i) : @@ -189,12 +189,12 @@ lemma ext_to_X (i j : ι) (hij : c.Rel i j) {A : C} {f g : A ⟶ X φ i} apply biprod.hom_ext · simpa using! h₁ · obtain rfl := c.next_eq' hij - simpa [sndX, dif_pos hij] using! h₂ + simpa [sndX, dite_eq_left hij] using! h₂ lemma ext_to_X' (i : ι) (hi : ¬ c.Rel i (c.next i)) {A : C} {f g : A ⟶ X φ i} (h : f ≫ sndX φ i = g ≫ sndX φ i) : f = g := by rw [← cancel_mono (XIso φ i hi).hom] - simpa only [sndX, dif_neg hi] using h + simpa only [sndX, dite_eq_right hi] using h lemma ext_from_X (i j : ι) (hij : c.Rel j i) {A : C} {f g : X φ j ⟶ A} (h₁ : inlX φ i j hij ≫ f = inlX φ i j hij ≫ g) (h₂ : inrX φ j ≫ f = inrX φ j ≫ g) : @@ -204,18 +204,18 @@ lemma ext_from_X (i j : ι) (hij : c.Rel j i) {A : C} {f g : X φ j ⟶ A} apply biprod.hom_ext' · simpa · obtain rfl := c.next_eq' hij - simpa [-inr_XIsoBiprod_inv, -inr_XIsoBiprod_inv_assoc, inrX, dif_pos hij] using h₂ + simpa [-inr_XIsoBiprod_inv, -inr_XIsoBiprod_inv_assoc, inrX, dite_eq_left hij] using h₂ lemma ext_from_X' (i : ι) (hi : ¬ c.Rel i (c.next i)) {A : C} {f g : X φ i ⟶ A} (h : inrX φ i ≫ f = inrX φ i ≫ g) : f = g := by rw [← cancel_epi (XIso φ i hi).inv] - simpa only [inrX, dif_neg hi] using h + simpa only [inrX, dite_eq_right hi] using h @[reassoc] lemma d_fstX (i j k : ι) (hij : c.Rel i j) (hjk : c.Rel j k) : d φ i j ≫ fstX φ j k hjk = -fstX φ i j hij ≫ F.d j k := by obtain rfl := c.next_eq' hjk - simp [d, dif_pos hij, dif_pos hjk] + simp [d, dite_eq_left hij, dite_eq_left hjk] @[reassoc] lemma d_sndX (i j : ι) (hij : c.Rel i j) : @@ -238,7 +238,7 @@ lemma inlX_d' (i j : ι) (hij : c.Rel i j) (hj : ¬ c.Rel j (c.next j)) : lemma shape (i j : ι) (hij : ¬ c.Rel i j) : d φ i j = 0 := - dif_neg hij + dite_eq_right hij @[reassoc (attr := simp)] lemma inrX_d (i j : ι) : @@ -286,13 +286,13 @@ noncomputable def inrCompHomotopy (hc : ∀ j, ∃ i, c.Rel i j) : Homotopy (φ ≫ inr φ) 0 where hom i j := if hij : c.Rel j i then inlX φ i j hij else 0 - zero _ _ hij := dif_neg hij + zero _ _ hij := dite_eq_right hij comm j := by obtain ⟨i, hij⟩ := hc j - rw [prevD_eq _ hij, dif_pos hij] + rw [prevD_eq _ hij, dite_eq_left hij] by_cases hj : c.Rel j (c.next j) · simp only [comp_f, homotopyCofiber_d, zero_f, add_zero, - inlX_d φ i j _ hij hj, dNext_eq _ hj, dif_pos hj, + inlX_d φ i j _ hij hj, dNext_eq _ hj, dite_eq_left hj, add_neg_cancel_left, inr_f] · rw [dNext_eq_zero _ _ hj, zero_add, zero_f, add_zero, homotopyCofiber_d, inlX_d' _ _ _ _ hj, comp_f, inr_f] @@ -300,10 +300,10 @@ noncomputable def inrCompHomotopy (hc : ∀ j, ∃ i, c.Rel i j) : variable (hc : ∀ j, ∃ i, c.Rel i j) lemma inrCompHomotopy_hom (i j : ι) (hij : c.Rel j i) : - (inrCompHomotopy φ hc).hom i j = inlX φ i j hij := dif_pos hij + (inrCompHomotopy φ hc).hom i j = inlX φ i j hij := dite_eq_left hij lemma inrCompHomotopy_hom_eq_zero (i j : ι) (hij : ¬ c.Rel j i) : - (inrCompHomotopy φ hc).hom i j = 0 := dif_neg hij + (inrCompHomotopy φ hc).hom i j = 0 := dite_eq_right hij end @@ -322,7 +322,7 @@ noncomputable def desc : else sndX φ j ≫ α.f j comm' j k hjk := by obtain rfl := c.next_eq' hjk - simp [dif_pos hjk] + simp [dite_eq_left hjk] have H := hα.comm (c.next j) simp only [comp_f, zero_f, add_zero, prevD_eq _ hjk] at H split_ifs with hj @@ -334,11 +334,11 @@ noncomputable def desc : lemma desc_f (j k : ι) (hjk : c.Rel j k) : (desc φ α hα).f j = fstX φ j _ hjk ≫ hα.hom _ j + sndX φ j ≫ α.f j := by obtain rfl := c.next_eq' hjk - apply dif_pos hjk + apply dite_eq_left hjk lemma desc_f' (j : ι) (hj : ¬ c.Rel j (c.next j)) : (desc φ α hα).f j = sndX φ j ≫ α.f j := by - apply dif_neg hj + apply dite_eq_right hj set_option backward.isDefEq.respectTransparency.types false in @[reassoc (attr := simp)] @@ -346,7 +346,7 @@ lemma inlX_desc_f (i j : ι) (hjk : c.Rel j i) : inlX φ i j hjk ≫ (desc φ α hα).f j = hα.hom i j := by obtain rfl := c.next_eq' hjk dsimp [desc] - rw [dif_pos hjk, comp_add, inlX_fstX_assoc, inlX_sndX_assoc, zero_comp, add_zero] + rw [dite_eq_left hjk, comp_add, inlX_fstX_assoc, inlX_sndX_assoc, zero_comp, add_zero] set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] @@ -490,7 +490,7 @@ lemma inlX_mapHomologicalComplexObjXIso_inv inlX ((H.mapHomologicalComplex c).map φ) i j hij ≫ (mapHomologicalComplexObjXIso φ H j).inv = H.map (inlX φ i j hij) := by obtain rfl := c.next_eq' hij - simp [mapHomologicalComplexObjXIso, dif_pos hij, ← Functor.map_comp] + simp [mapHomologicalComplexObjXIso, dite_eq_left hij, ← Functor.map_comp] set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] @@ -498,9 +498,9 @@ lemma inrX_mapHomologicalComplexObjXIso_inv (i : ι) : inrX ((H.mapHomologicalComplex c).map φ) i ≫ (mapHomologicalComplexObjXIso φ H i).inv = H.map (inrX φ i) := by by_cases hi : c.Rel i (c.next i) - · simp [mapHomologicalComplexObjXIso, dif_pos hi, ← Functor.map_comp] + · simp [mapHomologicalComplexObjXIso, dite_eq_left hi, ← Functor.map_comp] · dsimp [mapHomologicalComplexObjXIso, XIso, inrX] - simp [dif_neg hi] + simp [dite_eq_right hi] set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] diff --git a/Mathlib/Algebra/Homology/Monoidal.lean b/Mathlib/Algebra/Homology/Monoidal.lean index 1f1c41dc705523..6d53659633e075 100644 --- a/Mathlib/Algebra/Homology/Monoidal.lean +++ b/Mathlib/Algebra/Homology/Monoidal.lean @@ -197,7 +197,7 @@ lemma leftUnitor'_inv (i : I) : congr 2 rw [← cancel_epi (GradedObject.Monoidal.tensorUnit₀ (I := I)).hom, Iso.hom_inv_id_assoc] dsimp [tensorUnitIso] - rw [dif_pos rfl] + rw [dite_eq_left rfl] rfl set_option backward.defeqAttrib.useBackward true in @@ -248,7 +248,7 @@ lemma rightUnitor'_inv (i : I) : congr 2 rw [← cancel_epi (GradedObject.Monoidal.tensorUnit₀ (I := I)).hom, Iso.hom_inv_id_assoc] dsimp [tensorUnitIso] - rw [dif_pos rfl] + rw [dite_eq_left rfl] rfl set_option backward.defeqAttrib.useBackward true in diff --git a/Mathlib/Algebra/Homology/Single.lean b/Mathlib/Algebra/Homology/Single.lean index f613890c7ae62d..05fd3a5653e876 100644 --- a/Mathlib/Algebra/Homology/Single.lean +++ b/Mathlib/Algebra/Homology/Single.lean @@ -40,8 +40,8 @@ noncomputable def single (j : ι) : V ⥤ HomologicalComplex V c where { X := fun i => if i = j then A else 0 d := fun _ _ => 0 } map f := - { f := fun i => if h : i = j then eqToHom (by dsimp; rw [if_pos h]) ≫ f ≫ - eqToHom (by dsimp; rw [if_pos h]) else 0 } + { f := fun i => if h : i = j then eqToHom (by dsimp; rw [ite_eq_left h]) ≫ f ≫ + eqToHom (by dsimp; rw [ite_eq_left h]) else 0 } map_id A := by ext dsimp @@ -49,11 +49,11 @@ noncomputable def single (j : ι) : V ⥤ HomologicalComplex V c where · subst h simp · #adaptation_note /-- nightly-2024-03-07 - previously was `rw [if_neg h]; simp`, but that fails with "motive not type correct" + previously was `rw [ite_eq_right h]; simp`, but that fails with "motive not type correct" This is because dsimp does not simplify numerals; this note should be removable once https://github.com/leanprover/lean4/pull/8433 lands. -/ convert! (id_zero (C := V)).symm - all_goals simp [if_neg h] + all_goals simp [ite_eq_right h] map_comp f g := by ext dsimp @@ -66,12 +66,12 @@ variable {V} @[simp] lemma single_obj_X_self (j : ι) (A : V) : - ((single V c j).obj A).X j = A := if_pos rfl + ((single V c j).obj A).X j = A := ite_eq_left rfl lemma isZero_single_obj_X (j : ι) (A : V) (i : ι) (hi : i ≠ j) : IsZero (((single V c j).obj A).X i) := by dsimp [single] - rw [if_neg hi] + rw [ite_eq_right hi] exact Limits.isZero_zero V /-- The object in degree `i` of `(single V c h).obj A` is just `A` when `i = j`. -/ @@ -92,7 +92,7 @@ theorem single_map_f_self (j : ι) {A B : V} (f : A ⟶ B) : ((single V c j).map f).f j = (singleObjXSelf c j A).hom ≫ f ≫ (singleObjXSelf c j B).inv := by dsimp [single] - rw [dif_pos rfl] + rw [dite_eq_left rfl] rfl variable (V) @@ -160,7 +160,7 @@ lemma mkHomToSingle_f {K : HomologicalComplex V c} {j : ι} {A : V} (φ : K.X j (hφ : ∀ (i : ι), c.Rel i j → K.d i j ≫ φ = 0) : (mkHomToSingle φ hφ).f j = φ ≫ (singleObjXSelf c j A).inv := by dsimp [mkHomToSingle] - rw [dif_pos rfl, id_comp] + rw [dite_eq_left rfl, id_comp] rfl /-- Constructor for morphisms from a single homological complex. -/ @@ -185,7 +185,7 @@ lemma mkHomFromSingle_f {K : HomologicalComplex V c} {j : ι} {A : V} (φ : A (hφ : ∀ (k : ι), c.Rel j k → φ ≫ K.d j k = 0) : (mkHomFromSingle φ hφ).f j = (singleObjXSelf c j A).hom ≫ φ := by dsimp [mkHomFromSingle] - rw [dif_pos rfl, comp_id] + rw [dite_eq_left rfl, comp_id] rfl instance (j : ι) : (single V c j).PreservesZeroMorphisms where diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 91e6c7d8189ac0..561a1508c129cf 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -149,7 +149,7 @@ lemma pageD_eq (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq' obtain rfl : n₂ = data.deg pq + 1 := by lia obtain rfl : n₃ = data.deg pq + 2 := by lia dsimp [pageD, pageXIso] - rw [dif_pos hpq, Category.id_comp] + rw [dite_eq_left hpq, Category.id_comp] rfl @[reassoc (attr := simp)] @@ -173,9 +173,9 @@ lemma pageD_pageD (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : Category.assoc, Category.assoc, Iso.inv_hom_id_assoc, d_d_assoc .., zero_comp, comp_zero] · dsimp only [pageD] - rw [dif_neg hpq', comp_zero] + rw [dite_eq_right hpq', comp_zero] · dsimp only [pageD] - rw [dif_neg hpq, zero_comp] + rw [dite_eq_right hpq, zero_comp] /-- The `r`th page of the spectral sequence. -/ @[simps] @@ -183,7 +183,7 @@ noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : HomologicalComplex C (c r) where X pq := pageX X data r pq d := pageD X data r - shape pq pq' hpq := dif_neg hpq + shape pq pq' hpq := dite_eq_right hpq set_option backward.isDefEq.respectTransparency.types false in /-- The short complex of the `r`th page of the spectral sequence on position `pq'` diff --git a/Mathlib/Algebra/Homology/TotalComplex.lean b/Mathlib/Algebra/Homology/TotalComplex.lean index 14e126e05f0240..2e4d80bf9f4c45 100644 --- a/Mathlib/Algebra/Homology/TotalComplex.lean +++ b/Mathlib/Algebra/Homology/TotalComplex.lean @@ -297,11 +297,11 @@ noncomputable def ιTotalOrZero (i₁ : I₁) (i₂ : I₂) (i₁₂ : I₁₂) lemma ιTotalOrZero_eq (i₁ : I₁) (i₂ : I₂) (i₁₂ : I₁₂) (h : ComplexShape.π c₁ c₂ c₁₂ (i₁, i₂) = i₁₂) : - K.ιTotalOrZero c₁₂ i₁ i₂ i₁₂ = K.ιTotal c₁₂ i₁ i₂ i₁₂ h := dif_pos h + K.ιTotalOrZero c₁₂ i₁ i₂ i₁₂ = K.ιTotal c₁₂ i₁ i₂ i₁₂ h := dite_eq_left h lemma ιTotalOrZero_eq_zero (i₁ : I₁) (i₂ : I₂) (i₁₂ : I₁₂) (h : ComplexShape.π c₁ c₂ c₁₂ (i₁, i₂) ≠ i₁₂) : - K.ιTotalOrZero c₁₂ i₁ i₂ i₁₂ = 0 := dif_neg h + K.ιTotalOrZero c₁₂ i₁ i₂ i₁₂ = 0 := dite_eq_right h @[reassoc (attr := simp)] lemma ι_D₁ (i₁₂ i₁₂' : I₁₂) (i₁ : I₁) (i₂ : I₂) (h : ComplexShape.π c₁ c₂ c₁₂ ⟨i₁, i₂⟩ = i₁₂) : diff --git a/Mathlib/Algebra/Lie/CartanExists.lean b/Mathlib/Algebra/Lie/CartanExists.lean index 4d4665d212cbfc..64c74afcf10367 100644 --- a/Mathlib/Algebra/Lie/CartanExists.lean +++ b/Mathlib/Algebra/Lie/CartanExists.lean @@ -300,7 +300,7 @@ lemma engel_isBot_of_isMin (hLK : finrank K L ≤ #K) (U : LieSubalgebra K L) intro α hα -- Once again, we are left with showing that `⁅y, _⁆` acts nilpotently on `E`. rw [← coe_evalRingHom, ← coeff_map, lieCharpoly_map_eval, - (LinearMap.charpoly_eq_X_pow_iff _).mpr, coeff_X_pow, if_neg hi.ne] + (LinearMap.charpoly_eq_X_pow_iff _).mpr, coeff_X_pow, ite_eq_right hi.ne] -- To do so, it suffices to show that the Engel subalgebra of `v = a • u + x` is contained in `E`. let v := α • u + x' suffices engel K (v : L) ≤ engel K x by diff --git a/Mathlib/Algebra/Lie/Classical.lean b/Mathlib/Algebra/Lie/Classical.lean index ca8afa7134c773..b5398a77f3282c 100644 --- a/Mathlib/Algebra/Lie/Classical.lean +++ b/Mathlib/Algebra/Lie/Classical.lean @@ -365,8 +365,8 @@ theorem indefiniteDiagonal_assoc : ext ⟨⟨i₁ | i₂⟩ | i₃⟩ ⟨⟨j₁ | j₂⟩ | j₃⟩ <;> simp only [indefiniteDiagonal, Matrix.diagonal_apply, Equiv.sumAssoc_apply_inl_inl, Matrix.reindexLieEquiv_apply, Matrix.submatrix_apply, Equiv.symm_symm, Matrix.reindex_apply, - Sum.elim_inl, if_true, Matrix.one_apply_eq, Matrix.fromBlocks_apply₁₁, - Equiv.sumAssoc_apply_inl_inr, if_false, Matrix.fromBlocks_apply₁₂, Matrix.fromBlocks_apply₂₁, + Sum.elim_inl, ite_true, Matrix.one_apply_eq, Matrix.fromBlocks_apply₁₁, + Equiv.sumAssoc_apply_inl_inr, ite_false, Matrix.fromBlocks_apply₁₂, Matrix.fromBlocks_apply₂₁, Matrix.fromBlocks_apply₂₂, Equiv.sumAssoc_apply_inr, Sum.elim_inr, Sum.inl_injective.eq_iff, Sum.inr_injective.eq_iff, reduceCtorEq] <;> congr 1 diff --git a/Mathlib/Algebra/Lie/DirectSum.lean b/Mathlib/Algebra/Lie/DirectSum.lean index 853510ae4ce247..6409800aaece13 100644 --- a/Mathlib/Algebra/Lie/DirectSum.lean +++ b/Mathlib/Algebra/Lie/DirectSum.lean @@ -140,7 +140,7 @@ theorem lie_of_of_ne [DecidableEq ι] {i j : ι} (hij : i ≠ j) (x : L i) (y : theorem lie_of [DecidableEq ι] {i j : ι} (x : L i) (y : L j) : ⁅of L i x, of L j y⁆ = if hij : i = j then of L i ⁅x, hij.symm.recOn y⁆ else 0 := by obtain rfl | hij := Decidable.eq_or_ne i j - · simp only [lie_of_same L x y, dif_pos] + · simp only [lie_of_same L x y, dite_eq_left] · simp only [lie_of_of_ne L hij x y, hij, dite_false] instance lieAlgebra : LieAlgebra R (⨁ i, L i) := diff --git a/Mathlib/Algebra/Lie/Weights/Chain.lean b/Mathlib/Algebra/Lie/Weights/Chain.lean index 5d97ddf5978a82..92e8372626ac37 100644 --- a/Mathlib/Algebra/Lie/Weights/Chain.lean +++ b/Mathlib/Algebra/Lie/Weights/Chain.lean @@ -274,8 +274,8 @@ def chainBotCoeff : ℕ := chainTopCoeff (-α) β @[simp] lemma chainBotCoeff_neg : chainBotCoeff (-α) β = chainTopCoeff α β := by rw [← chainTopCoeff_neg, neg_neg] -@[simp] lemma chainTopCoeff_zero : chainTopCoeff 0 β = 0 := dif_pos rfl -@[simp] lemma chainBotCoeff_zero : chainBotCoeff 0 β = 0 := dif_pos neg_zero +@[simp] lemma chainTopCoeff_zero : chainTopCoeff 0 β = 0 := dite_eq_left rfl +@[simp] lemma chainBotCoeff_zero : chainBotCoeff 0 β = 0 := dite_eq_left neg_zero section variable (hα : α ≠ 0) @@ -286,7 +286,7 @@ lemma chainTopCoeff_add_one : chainTopCoeff α β + 1 = Nat.find (eventually_genWeightSpace_smul_add_eq_bot M α β hα).exists := by classical - rw [chainTopCoeff, dif_neg hα] + rw [chainTopCoeff, dite_eq_right hα] apply Nat.succ_pred_eq_of_pos rw [zero_lt_iff] intro e diff --git a/Mathlib/Algebra/Lie/Weights/RootSystem.lean b/Mathlib/Algebra/Lie/Weights/RootSystem.lean index 0605916ff57771..6a27db6fc5a41e 100644 --- a/Mathlib/Algebra/Lie/Weights/RootSystem.lean +++ b/Mathlib/Algebra/Lie/Weights/RootSystem.lean @@ -72,7 +72,7 @@ def chainLength (α β : Weight K H L) : ℕ := if hα : α.IsZero then 0 else (chainLength_aux α β hα (chainTop α β).exists_ne_zero.choose_spec.1).choose -lemma chainLength_of_isZero (hα : α.IsZero) : chainLength α β = 0 := dif_pos hα +lemma chainLength_of_isZero (hα : α.IsZero) : chainLength α β = 0 := dite_eq_left hα lemma chainLength_nsmul {x} (hx : x ∈ rootSpace H (chainTop α β)) : chainLength α β • x = ⁅coroot α, x⁆ := by @@ -84,7 +84,7 @@ lemma chainLength_nsmul {x} (hx : x ∈ rootSpace H (chainTop α β)) : obtain ⟨k, rfl⟩ : ∃ k : K, k • x' = x := by simpa using (finrank_eq_one_iff_of_nonzero' ⟨x', h.1⟩ (by simpa using h.2)).mp (finrank_rootSpace_eq_one _ (chainTop_isNonZero α β hα)) ⟨_, hx⟩ - rw [lie_smul, smul_comm, chainLength, dif_neg hα, (chainLength_aux α β hα h.1).choose_spec] + rw [lie_smul, smul_comm, chainLength, dite_eq_right hα, (chainLength_aux α β hα h.1).choose_spec] lemma chainLength_smul {x} (hx : x ∈ rootSpace H (chainTop α β)) : (chainLength α β : K) • x = ⁅coroot α, x⁆ := by @@ -93,8 +93,8 @@ lemma chainLength_smul {x} (hx : x ∈ rootSpace H (chainTop α β)) : lemma apply_coroot_eq_cast' : β (coroot α) = ↑(chainLength α β - 2 * chainTopCoeff α β : ℤ) := by by_cases hα : α.IsZero - · rw [coroot_eq_zero_iff.mpr hα, chainLength, dif_pos hα, hα.eq, chainTopCoeff_zero, map_zero, - CharP.cast_eq_zero, mul_zero, sub_self, Int.cast_zero] + · rw [coroot_eq_zero_iff.mpr hα, chainLength, dite_eq_left hα, hα.eq, chainTopCoeff_zero, + map_zero, CharP.cast_eq_zero, mul_zero, sub_self, Int.cast_zero] obtain ⟨x, hx, x_ne0⟩ := (chainTop α β).exists_ne_zero have := chainLength_smul _ _ hx rw [lie_eq_smul_of_mem_rootSpace hx, ← sub_eq_zero, ← sub_smul, diff --git a/Mathlib/Algebra/LinearRecurrence.lean b/Mathlib/Algebra/LinearRecurrence.lean index cbbc654009610a..50d53d42e3f784 100644 --- a/Mathlib/Algebra/LinearRecurrence.lean +++ b/Mathlib/Algebra/LinearRecurrence.lean @@ -90,7 +90,7 @@ theorem is_sol_mkSol (init : Fin E.order → R) : E.IsSolution (E.mkSol init) := theorem mkSol_eq_init (init : Fin E.order → R) : ∀ n : Fin E.order, E.mkSol init n = init n := by intro n rw [mkSol] - simp only [n.is_lt, dif_pos, Fin.mk_val] + simp only [n.is_lt, dite_eq_left, Fin.mk_val] /-- If `u` is a solution to `E` and `init` designates its first `E.order` values, then `∀ n, u n = E.mkSol init n`. -/ diff --git a/Mathlib/Algebra/Module/LinearMap/Polynomial.lean b/Mathlib/Algebra/Module/LinearMap/Polynomial.lean index c57b90b6ba5702..45157139cd4c7e 100644 --- a/Mathlib/Algebra/Module/LinearMap/Polynomial.lean +++ b/Mathlib/Algebra/Module/LinearMap/Polynomial.lean @@ -263,9 +263,9 @@ lemma polyCharpolyAux_baseChange (A : Type*) [CommRing A] [Algebra R A] : (toMatrix (basis A bₘ.end) (basis A bₘ).end) (tensorProduct R A M M) ij kl = if kl = ij then 1 else 0 by rw [Finset.sum_eq_single ij] - · rw [this, if_pos rfl, X] + · rw [this, ite_eq_left rfl, X] · rintro kl - H - rw [this, if_neg H, map_zero] + rw [this, ite_eq_right H, map_zero] · grind intro kl rw [toMatrix_apply, tensorProduct, TensorProduct.AlgebraTensorModule.lift_apply, diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index 6e25ccef62b4eb..14ec9780e1a6f2 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -132,13 +132,13 @@ def ceil (m : E) : span ℤ (Set.range b) := ∑ i, ⌈b.repr m i⌉ • b.restr theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by classical simp only [floor, ← Int.cast_smul_eq_zsmul K, b.repr.map_smul, Finsupp.single_apply, Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum, - Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum] + Finset.mem_univ, ite_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum] @[simp] theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by classical simp only [ceil, ← Int.cast_smul_eq_zsmul K, b.repr.map_smul, Finsupp.single_apply, Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum, - Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum] + Finset.mem_univ, ite_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum] @[simp] theorem floor_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (floor b m : E) = m := by diff --git a/Mathlib/Algebra/MonoidAlgebra/Degree.lean b/Mathlib/Algebra/MonoidAlgebra/Degree.lean index 76b97d8645fc62..e5770076769f2f 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Degree.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Degree.lean @@ -342,12 +342,12 @@ theorem coeff_add_of_supDegree_le (hadd : ∀ a1 a2, D (a1 + a2) = D a1 + D a2) (p * q).coeff (ap + aq) = p.coeff ap * q.coeff aq := by classical simp_rw [coeff_mul, Finsupp.sum] - rw [Finset.sum_eq_single ap, Finset.sum_eq_single aq, if_pos rfl] - · refine fun a ha hne => if_neg (fun he => ?_) + rw [Finset.sum_eq_single ap, Finset.sum_eq_single aq, ite_eq_left rfl] + · refine fun a ha hne => ite_eq_right (fun he => ?_) apply_fun D at he; simp_rw [hadd] at he exact (add_lt_add_right (((Finset.le_sup ha).trans hq).lt_of_ne <| hD.ne_iff.2 hne) _).ne he - · intro h; rw [if_pos rfl, Finsupp.notMem_support_iff.1 h, mul_zero] - · refine fun a ha hne => Finset.sum_eq_zero (fun a' ha' => if_neg <| fun he => ?_) + · intro h; rw [ite_eq_left rfl, Finsupp.notMem_support_iff.1 h, mul_zero] + · refine fun a ha hne => Finset.sum_eq_zero (fun a' ha' => ite_eq_right <| fun he => ?_) apply_fun D at he simp_rw [hadd] at he have := addLeftMono_of_addLeftStrictMono B @@ -602,9 +602,11 @@ lemma Monic.supDegree_pow [Nontrivial R] (hp : p.Monic D) : (p ^ n).supDegree D = n • p.supDegree D := by induction n with - | zero => rw [pow_zero, zero_nsmul, one_def, supDegree_single 0 1, if_neg one_ne_zero, hzero] - | succ n ih => rw [pow_succ', (hp.pow hadd hD).supDegree_mul_of_ne_zero_left hD hadd hp.ne_zero, - ih, succ_nsmul'] + | zero => + rw [pow_zero, zero_nsmul, one_def, supDegree_single 0 1, ite_eq_right one_ne_zero, hzero] + | succ n ih => + rw [pow_succ', (hp.pow hadd hD).supDegree_mul_of_ne_zero_left hD hadd hp.ne_zero, ih, + succ_nsmul'] end AddMonoid diff --git a/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean b/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean index 41f4d0293ac46a..dd9bb9594ac310 100644 --- a/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean +++ b/Mathlib/Algebra/MonoidAlgebra/NoZeroDivisors.lean @@ -75,8 +75,9 @@ theorem coeff_mul_mul_of_uniqueMul [Mul A] {f g : R[A]} {a0 b0 : A} (f * g).coeff (a0 * b0) = f.coeff a0 * g.coeff b0 := by classical simp_rw [coeff_mul, sum, ← Finset.sum_product'] - refine (Finset.sum_eq_single (a0, b0) ?_ ?_).trans (if_pos rfl) <;> simp_rw [Finset.mem_product] - · refine fun ab hab hne ↦ if_neg (fun he ↦ hne <| Prod.ext ?_ ?_) + refine (Finset.sum_eq_single (a0, b0) ?_ ?_).trans (ite_eq_left rfl) <;> + simp_rw [Finset.mem_product] + · refine fun ab hab hne ↦ ite_eq_right (fun he ↦ hne <| Prod.ext ?_ ?_) exacts [(h hab.1 hab.2 he).1, (h hab.1 hab.2 he).2] · refine fun hnotMem ↦ ite_eq_right_iff.mpr (fun _ ↦ ?_) rcases not_and_or.mp hnotMem with af | bg diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 57a2fdbe1d1080..a5cd8a654c5117 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -481,12 +481,12 @@ theorem support_add [DecidableEq σ] : (p + q).support ⊆ p.support ∪ q.suppo Finsupp.support_add theorem support_X [Nontrivial R] : (X n : MvPolynomial σ R).support = {Finsupp.single n 1} := by - classical rw [X, support_monomial, if_neg]; exact one_ne_zero + classical rw [X, support_monomial, ite_eq_right]; exact one_ne_zero theorem support_X_pow [Nontrivial R] (s : σ) (n : ℕ) : (X s ^ n : MvPolynomial σ R).support = {Finsupp.single s n} := by classical - rw [X_pow_eq_monomial, support_monomial, if_neg (one_ne_zero' R)] + rw [X_pow_eq_monomial, support_monomial, ite_eq_right (one_ne_zero' R)] @[simp] theorem support_zero : (0 : MvPolynomial σ R).support = ∅ := @@ -597,8 +597,9 @@ theorem eq_monomial_of_support_subset_singleton {φ : MvPolynomial σ R} {d₀ : classical ext d rcases eq_or_ne d d₀ with rfl | hd - · rw [coeff_monomial, if_pos rfl] - · rw [notMem_support_iff.mp fun hmem ↦ hd (h d hmem), coeff_monomial, if_neg fun e ↦ hd e.symm] + · rw [coeff_monomial, ite_eq_left rfl] + · rw [notMem_support_iff.mp fun hmem ↦ hd (h d hmem), coeff_monomial, + ite_eq_right fun e ↦ hd e.symm] @[simp] theorem coeff_C [DecidableEq σ] (m) (a) : @@ -606,7 +607,7 @@ theorem coeff_C [DecidableEq σ] (m) (a) : Finsupp.single_apply theorem coeff_C_of_ne_zero {m : σ →₀ ℕ} (h : m ≠ 0) (a : R) : coeff m (C a) = 0 := by - classical rw [coeff_C, if_neg h.symm] + classical rw [coeff_C, ite_eq_right h.symm] -- The intended use case of this theorem is for `n = 1` (often useful for `pderiv`). @[simp] @@ -647,7 +648,7 @@ alias coeff_X' := coeff_X @[simp] theorem coeff_X_same (i : σ) : coeff (Finsupp.single i 1) (X i : MvPolynomial σ R) = 1 := by - classical rw [coeff_X, if_pos rfl] + classical rw [coeff_X, ite_eq_left rfl] set_option backward.isDefEq.respectTransparency false in @[simp] diff --git a/Mathlib/Algebra/MvPolynomial/Coeff.lean b/Mathlib/Algebra/MvPolynomial/Coeff.lean index 9e9048fef94724..7e1e3077545bce 100644 --- a/Mathlib/Algebra/MvPolynomial/Coeff.lean +++ b/Mathlib/Algebra/MvPolynomial/Coeff.lean @@ -65,7 +65,7 @@ private lemma coeff_linearCombination_X_pow_of_ne (a : σ →₀ R) {n : ℕ} ← C_eq_coe_nat, coeff_C_mul, smul_eq_C_mul, mul_pow, Finset.prod_mul_distrib, ← map_prod, coeff_prod_X_pow, mul_ite, mul_one, mul_zero] apply Finset.sum_eq_zero (fun x hx ↦ ?_) - rw [if_neg] + rw [ite_eq_right] rintro ⟨rfl⟩ apply hs simp only [Finset.mem_piAntidiag] at hx diff --git a/Mathlib/Algebra/MvPolynomial/CommRing.lean b/Mathlib/Algebra/MvPolynomial/CommRing.lean index fcdaade15b39df..0ab0ec1103ecf7 100644 --- a/Mathlib/Algebra/MvPolynomial/CommRing.lean +++ b/Mathlib/Algebra/MvPolynomial/CommRing.lean @@ -87,7 +87,7 @@ theorem notMem_support_sub_monomial_sub_monomial (d d' : σ →₀ ℕ) (c : R) d ∉ (p - (monomial d c - monomial d' c)).support := by classical rw [notMem_support_iff, coeff_sub, coeff_sub, coeff_monomial, coeff_monomial, - if_pos rfl, if_neg hdd'.symm, sub_zero, hc, sub_self] + ite_eq_left rfl, ite_eq_right hdd'.symm, sub_zero, hc, sub_self] /-- Subtracting `monomial d c - monomial d' c` from `p`, where `c = coeff d p` and `d ≠ d'`, leaves the support inside `p.support.erase d ∪ {d'}`. -/ diff --git a/Mathlib/Algebra/MvPolynomial/Degrees.lean b/Mathlib/Algebra/MvPolynomial/Degrees.lean index 4d8ca1b2a3b18a..392cdee2895651 100644 --- a/Mathlib/Algebra/MvPolynomial/Degrees.lean +++ b/Mathlib/Algebra/MvPolynomial/Degrees.lean @@ -94,7 +94,7 @@ theorem degrees_monomial (s : σ →₀ ℕ) (a : R) : degrees (monomial s a) theorem degrees_monomial_eq (s : σ →₀ ℕ) (a : R) (ha : a ≠ 0) : degrees (monomial s a) = toMultiset s := by classical - exact (supDegree_single s a).trans (if_neg ha) + exact (supDegree_single s a).trans (ite_eq_right ha) theorem degrees_C (a : R) : degrees (C a : MvPolynomial σ R) = 0 := Multiset.le_zero.1 <| degrees_monomial _ _ @@ -192,7 +192,7 @@ theorem degrees_rename (f : σ → τ) (φ : MvPolynomial σ R) : intro j hj simp only [mem_degrees] at hi specialize hi j ⟨x, hx, hj⟩ - rw [Finsupp.single_apply, if_neg hi] + rw [Finsupp.single_apply, ite_eq_right hi] theorem degrees_map_of_injective [CommSemiring S] (p : MvPolynomial σ R) {f : R →+* S} (hf : Injective f) : (map f p).degrees = p.degrees := by @@ -252,7 +252,7 @@ theorem degreeOf_C (a : R) (x : σ) : degreeOf x (C a : MvPolynomial σ R) = 0 : theorem degreeOf_X [DecidableEq σ] (i j : σ) [Nontrivial R] : degreeOf i (X j : MvPolynomial σ R) = if i = j then 1 else 0 := by by_cases c : i = j - · simp only [c, if_true, degreeOf_def, degrees_X, Multiset.count_singleton] + · simp only [c, ite_true, degreeOf_def, degrees_X, Multiset.count_singleton] simp [c, degreeOf_def, degrees_X] @[simp] theorem degreeOf_X_self [Nontrivial R] (i : σ) : @@ -517,7 +517,7 @@ theorem totalDegree_pow (a : MvPolynomial σ R) (n : ℕ) : @[simp] theorem totalDegree_monomial (s : σ →₀ ℕ) {c : R} (hc : c ≠ 0) : (monomial s c : MvPolynomial σ R).totalDegree = s.sum fun _ e => e := by - classical simp [totalDegree, support_monomial, if_neg hc] + classical simp [totalDegree, support_monomial, ite_eq_right hc] theorem totalDegree_monomial_le (s : σ →₀ ℕ) (c : R) : (monomial s c).totalDegree ≤ s.sum fun _ ↦ id := by diff --git a/Mathlib/Algebra/MvPolynomial/Division.lean b/Mathlib/Algebra/MvPolynomial/Division.lean index 557cbd21f024b7..c5fa6d37163da2 100644 --- a/Mathlib/Algebra/MvPolynomial/Division.lean +++ b/Mathlib/Algebra/MvPolynomial/Division.lean @@ -192,7 +192,7 @@ theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} : have hj := hx j have hi := hx i classical - simp_rw [coeff_monomial, if_pos] at hj hi + simp_rw [coeff_monomial, ite_eq_left] at hj hi simp_rw [coeff_monomial_mul'] at hi hj split_ifs at hj with hi · exact ⟨Or.inr hi, _, hj⟩ diff --git a/Mathlib/Algebra/MvPolynomial/Equiv.lean b/Mathlib/Algebra/MvPolynomial/Equiv.lean index 40cd229bb9f00a..2c62d29126a684 100644 --- a/Mathlib/Algebra/MvPolynomial/Equiv.lean +++ b/Mathlib/Algebra/MvPolynomial/Equiv.lean @@ -519,7 +519,7 @@ theorem optionEquivLeft_coeff_some_coeff_none simp only [coeff_zero] by_cases hj : j = n · simp [hj] - · rw [if_neg hj] + · rw [ite_eq_right hj] simp only [ite_eq_right_iff] intro hj_none hj_some apply False.elim (hj _) @@ -696,18 +696,18 @@ theorem finSuccEquiv_coeff_coeff (m : Fin n →₀ ℕ) (f : MvPolynomial (Fin ( Fin.cases_succ, ← _root_.map_prod, ← map_pow, Function.comp_apply] rw [← mul_boole, mul_comm (Polynomial.X ^ j 0), Polynomial.coeff_C_mul_X_pow]; congr 1 obtain rfl | hjmi := eq_or_ne j (m.cons i) - · simpa only [cons_zero, cons_succ, if_pos rfl, monomial_eq, C_1, one_mul, + · simpa only [cons_zero, cons_succ, ite_eq_left rfl, monomial_eq, C_1, one_mul, Finsupp.prod_pow] using! coeff_monomial m m (1 : R) - · simp only [hjmi, if_false] + · simp only [hjmi, ite_false] obtain hij | rfl := ne_or_eq i (j 0) - · simp only [hij, if_false, coeff_zero] - simp only [if_true] + · simp only [hij, ite_false, coeff_zero] + simp only [ite_true] have hmj : m ≠ j.tail := by rintro rfl rw [cons_tail] at hjmi contradiction - simpa only [monomial_eq, C_1, one_mul, Finsupp.prod_pow, tail_apply, if_neg hmj.symm] using! - coeff_monomial m j.tail (1 : R) + simpa only [monomial_eq, C_1, one_mul, Finsupp.prod_pow, tail_apply, + ite_eq_right hmj.symm] using! coeff_monomial m j.tail (1 : R) theorem eval_eq_eval_mv_eval' (s : Fin n → R) (y : R) (f : MvPolynomial (Fin (n + 1)) R) : eval (Fin.cons y s : Fin (n + 1) → R) f = @@ -830,7 +830,7 @@ lemma degreeOf_eq_natDegree [DecidableEq σ] (a : σ) (p : MvPolynomial σ R) : (optionEquivLeft R {b // b ≠ a} (rename (Equiv.optionSubtypeNe a).symm p)).natDegree := by rw [natDegree_optionEquivLeft, eq_comm] convert! degreeOf_rename_of_injective (Equiv.injective (Equiv.optionSubtypeNe a).symm) a - rw [Equiv.optionSubtypeNe_symm_apply, dif_pos rfl] + rw [Equiv.optionSubtypeNe_symm_apply, dite_eq_left rfl] theorem degreeOf_coeff_finSuccEquiv (p : MvPolynomial (Fin (n + 1)) R) (j : Fin n) (i : ℕ) : degreeOf j (Polynomial.coeff (finSuccEquiv R n p) i) ≤ degreeOf j.succ p := by diff --git a/Mathlib/Algebra/MvPolynomial/Funext.lean b/Mathlib/Algebra/MvPolynomial/Funext.lean index edac9370c37edf..a68460a77c1ff4 100644 --- a/Mathlib/Algebra/MvPolynomial/Funext.lean +++ b/Mathlib/Algebra/MvPolynomial/Funext.lean @@ -69,7 +69,7 @@ theorem funext_set (h : ∀ x ∈ Set.pi .univ s, eval x p = eval x q) : · simp only [eval, eval₂Hom_rename, Function.extend_comp hf] obtain ⟨i, rfl⟩ | nex := em (∃ x, f x = i) · rw [hf.extend_apply]; exact hx _ ⟨⟩ - · simp_rw [Function.extend, dif_neg nex, hg] + · simp_rw [Function.extend, dite_eq_right nex, hg] theorem funext_set_iff : p = q ↔ (∀ x ∈ Set.pi .univ s, eval x p = eval x q) := ⟨by rintro rfl _ _; rfl, funext_set s hs⟩ diff --git a/Mathlib/Algebra/MvPolynomial/PDeriv.lean b/Mathlib/Algebra/MvPolynomial/PDeriv.lean index 9f76a70548e064..b476581dd08488 100644 --- a/Mathlib/Algebra/MvPolynomial/PDeriv.lean +++ b/Mathlib/Algebra/MvPolynomial/PDeriv.lean @@ -130,7 +130,7 @@ theorem coeff_pderiv {i : σ} (p : MvPolynomial σ R) (m : σ →₀ ℕ) : simp only [h, ↓reduceIte, zero_mul] by_cases hn : n i = 0 · simp [hn] - apply if_neg + apply ite_eq_right rwa [tsub_eq_iff_eq_add_of_le (fun _ ↦ by grind)] theorem pderiv_map {S} [CommSemiring S] {φ : R →+* S} {f : MvPolynomial σ R} {i : σ} : diff --git a/Mathlib/Algebra/MvPolynomial/Rename.lean b/Mathlib/Algebra/MvPolynomial/Rename.lean index 7b6c1a1a887fd1..6595942b58d082 100644 --- a/Mathlib/Algebra/MvPolynomial/Rename.lean +++ b/Mathlib/Algebra/MvPolynomial/Rename.lean @@ -137,7 +137,7 @@ theorem killCompl_C (r : R) : killCompl hf (C r) = C r := algHom_C _ _ theorem killCompl_comp_rename : (killCompl hf).comp (rename f) = AlgHom.id R _ := algHom_ext fun i => by dsimp - rw [rename_X, killCompl, aeval_X, dif_pos ⟨i, rfl⟩, Equiv.ofInjective_symm_apply] + rw [rename_X, killCompl, aeval_X, dite_eq_left ⟨i, rfl⟩, Equiv.ofInjective_symm_apply] @[simp] theorem killCompl_rename_app (p : MvPolynomial σ R) : killCompl hf (rename f p) = p := diff --git a/Mathlib/Algebra/Notation/Indicator.lean b/Mathlib/Algebra/Notation/Indicator.lean index cf61481ca68c40..937ee1f78e162e 100644 --- a/Mathlib/Algebra/Notation/Indicator.lean +++ b/Mathlib/Algebra/Notation/Indicator.lean @@ -64,10 +64,10 @@ lemma mulIndicator_apply (s : Set α) (f : α → M) (a : α) [Decidable (a ∈ congr @[to_additive (attr := simp)] -lemma mulIndicator_of_mem (h : a ∈ s) (f : α → M) : mulIndicator s f a = f a := if_pos h +lemma mulIndicator_of_mem (h : a ∈ s) (f : α → M) : mulIndicator s f a = f a := ite_eq_left h @[to_additive (attr := simp)] -lemma mulIndicator_of_notMem (h : a ∉ s) (f : α → M) : mulIndicator s f a = 1 := if_neg h +lemma mulIndicator_of_notMem (h : a ∉ s) (f : α → M) : mulIndicator s f a = 1 := ite_eq_right h @[to_additive] lemma mulIndicator_eq_one_or_self (s : Set α) (f : α → M) (a : α) : diff --git a/Mathlib/Algebra/Notation/Support.lean b/Mathlib/Algebra/Notation/Support.lean index a1370564d45000..16e9e4065edf1a 100644 --- a/Mathlib/Algebra/Notation/Support.lean +++ b/Mathlib/Algebra/Notation/Support.lean @@ -82,7 +82,7 @@ lemma mulSupport_extend_one_subset {f : ι → κ} {g : ι → N} : mulSupport (f.extend g 1) ⊆ f '' mulSupport g := mulSupport_subset_iff'.mpr fun x hfg ↦ by by_cases hf : ∃ a, f a = x - · rw [extend, dif_pos hf, ← notMem_mulSupport] + · rw [extend, dite_eq_left hf, ← notMem_mulSupport] rw [← Classical.choose_spec hf] at hfg exact fun hg ↦ hfg ⟨_, hg, rfl⟩ · rw [extend_apply' _ _ _ hf]; rfl diff --git a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean index 04b1a4dacc86be..6c0ffac866d0f9 100644 --- a/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean +++ b/Mathlib/Algebra/Order/AbsoluteValue/Basic.lean @@ -317,7 +317,7 @@ def trivial : AbsoluteValue R S where @[simp] lemma trivial_apply {x : R} (hx : x ≠ 0) : AbsoluteValue.trivial (S := S) x = 1 := - if_neg hx + ite_eq_right hx end trivial diff --git a/Mathlib/Algebra/Order/Antidiag/Finsupp.lean b/Mathlib/Algebra/Order/Antidiag/Finsupp.lean index 418a7c2c10e81f..7ea0b496b4d4c3 100644 --- a/Mathlib/Algebra/Order/Antidiag/Finsupp.lean +++ b/Mathlib/Algebra/Order/Antidiag/Finsupp.lean @@ -104,7 +104,7 @@ theorem finsuppAntidiag_insert {a : ι} {s : Finset ι} · replace hf := mt (hf.2 ·) h replace hg := mt (hg.2 ·) h rw [notMem_support_iff.mp hf, notMem_support_iff.mp hg] - · simpa only [coe_update, Function.update, dif_neg hx] using hfg x)⟩) := by + · simpa only [coe_update, Function.update, dite_eq_right hx] using hfg x)⟩) := by ext f rw [mem_finsuppAntidiag_insert h, mem_biUnion] simp_rw [mem_map, mem_attach, true_and, Subtype.exists, Embedding.coeFn_mk, exists_prop, and_comm, diff --git a/Mathlib/Algebra/Order/Antidiag/Nat.lean b/Mathlib/Algebra/Order/Antidiag/Nat.lean index b3c46e44e6de5d..7fdc2ca609ff44 100644 --- a/Mathlib/Algebra/Order/Antidiag/Nat.lean +++ b/Mathlib/Algebra/Order/Antidiag/Nat.lean @@ -195,7 +195,7 @@ private theorem primeFactorsPiBij_inj (d n : ℕ) apply ne_of_mem_of_not_mem (s := {x | p ∣ x}) <;> simp_rw [Set.mem_ofPred_eq] · rw [Finset.prod_filter] convert! Finset.dvd_prod_of_mem _ (mem_attach (n.primeFactors) ⟨p, hp⟩) - rw [if_pos rfl] + rw [ite_eq_left rfl] · rw [mem_primeFactors] at hp rw [Prime.dvd_finsetProd_iff hp.1.prime] push Not diff --git a/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean b/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean index 27eb96d5d109a8..d7e3cc183b983e 100644 --- a/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean +++ b/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean @@ -125,7 +125,7 @@ theorem sSup_def (s : Set ℝ) : rfl protected theorem isLUB_sSup (h₁ : s.Nonempty) (h₂ : BddAbove s) : IsLUB s (sSup s) := by - simp only [sSup_def, dif_pos (And.intro h₁ h₂)] + simp only [sSup_def, dite_eq_left (And.intro h₁ h₂)] apply Classical.choose_spec noncomputable instance : InfSet ℝ := @@ -169,7 +169,7 @@ theorem le_sSup_iff (h : BddAbove s) (h' : s.Nonempty) : @[simp] theorem sSup_empty : sSup (∅ : Set ℝ) = 0 := - dif_neg <| by simp + dite_eq_right <| by simp theorem sInf_univ : sInf (@Set.univ ℝ) = 0 := by simp [sInf_def] @@ -186,7 +186,7 @@ theorem iSup_const_zero : ⨆ _ : ι, (0 : ℝ) = 0 := by · exact Real.iSup_of_isEmpty _ · exact ciSup_const -lemma sSup_of_not_bddAbove (hs : ¬BddAbove s) : sSup s = 0 := dif_neg fun h => hs h.2 +lemma sSup_of_not_bddAbove (hs : ¬BddAbove s) : sSup s = 0 := dite_eq_right fun h => hs h.2 lemma iSup_of_not_bddAbove (hf : ¬BddAbove (Set.range f)) : ⨆ i, f i = 0 := sSup_of_not_bddAbove hf theorem sSup_univ : sSup (@Set.univ ℝ) = 0 := Real.sSup_of_not_bddAbove not_bddAbove_univ diff --git a/Mathlib/Algebra/Order/CauSeq/Completion.lean b/Mathlib/Algebra/Order/CauSeq/Completion.lean index 7bc0005e95c2aa..cd02820f278188 100644 --- a/Mathlib/Algebra/Order/CauSeq/Completion.lean +++ b/Mathlib/Algebra/Order/CauSeq/Completion.lean @@ -204,11 +204,11 @@ noncomputable instance : Inv (Cauchy abv) := rw [← mul_one (mk (inv f hf)), ← Ig', ← mul_assoc, If, mul_assoc, Ig', mul_one]⟩ theorem inv_zero : (0 : (Cauchy abv))⁻¹ = 0 := - congr_arg mk <| by rw [dif_pos] <;> [rfl; exact zero_limZero] + congr_arg mk <| by rw [dite_eq_left] <;> [rfl; exact zero_limZero] @[simp] theorem inv_mk {f} (hf) : (mk (abv := abv) f)⁻¹ = mk (inv f hf) := - congr_arg mk <| by rw [dif_neg] + congr_arg mk <| by rw [dite_eq_right] theorem cau_seq_zero_ne_one : ¬(0 : CauSeq _ abv) ≈ 1 := fun h ↦ have : LimZero (1 - 0 : CauSeq _ abv) := Setoid.symm h diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index b93ffa55d75b1e..f319d9e980a3bb 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -210,7 +210,7 @@ section Bot instance instBot : Bot (WithZero α) := ⟨none⟩ -@[simp← ] +@[simp ←] lemma zero_eq_bot : (0 : WithZero α) = ⊥ := rfl end Bot diff --git a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean index e29d0b34cead58..0f551ec4d177d9 100644 --- a/Mathlib/Algebra/Order/Module/HahnEmbedding.lean +++ b/Mathlib/Algebra/Order/Module/HahnEmbedding.lean @@ -527,12 +527,13 @@ theorem evalCoeff_eq [IsOrderedAddMonoid R] [Archimedean R] {x : M} {c : FiniteA {y : f.val.domain} (hy : y.val - x ∈ ball K c) : evalCoeff f x c = (ofLex (f.val y)).coeff c := by have hnonempty : ∃ y : f.val.domain, y.val - x ∈ ball K c := ⟨y, hy⟩ - simpa [evalCoeff, dif_pos hnonempty] using coeff_eq_of_mem f x hnonempty.choose_spec hy le_rfl + simpa [evalCoeff, dite_eq_left hnonempty] + using coeff_eq_of_mem f x hnonempty.choose_spec hy le_rfl theorem evalCoeff_eq_zero {x : M} {c : FiniteArchimedeanClass M} (h : ¬∃ y : f.val.domain, y.val - x ∈ ball K c) : f.evalCoeff x c = 0 := by - rw [evalCoeff, dif_neg h] + rw [evalCoeff, dite_eq_right h] theorem isWF_support_evalCoeff [IsOrderedAddMonoid R] [Archimedean R] (x : M) : (evalCoeff f x).support.IsWF := by @@ -541,7 +542,7 @@ theorem isWF_support_evalCoeff [IsOrderedAddMonoid R] [Archimedean R] (x : M) : have hnonempty : ∃ y : f.val.domain, y.val - x ∈ ball K (seq 0) := by specialize hmem 0 contrapose hmem with hempty - simp [evalCoeff, dif_neg hempty] + simp [evalCoeff, dite_eq_right hempty] obtain ⟨y, hy⟩ := hnonempty have hmem' (n : ℕ) : seq n ∈ (ofLex (f.val y)).coeff.support := by specialize hmem n diff --git a/Mathlib/Algebra/Order/Ring/GeomSum.lean b/Mathlib/Algebra/Order/Ring/GeomSum.lean index 0fcf496eb09ac5..d2bcfce0b362fe 100644 --- a/Mathlib/Algebra/Order/Ring/GeomSum.lean +++ b/Mathlib/Algebra/Order/Ring/GeomSum.lean @@ -109,16 +109,16 @@ lemma Odd.geom_sum_pos (h : Odd n) : 0 < ∑ i ∈ range n, x ^ i := by rw [← Nat.not_even_iff_odd] at h rcases lt_trichotomy (x + 1) 0 with (hx | hx | hx) · have := geom_sum_alternating_of_lt_neg_one hx k.one_lt_succ_succ - simp only [h, if_false] at this + simp only [h, ite_false] at this exact zero_lt_one.trans this - · simp only [eq_neg_of_add_eq_zero_left hx, h, neg_one_geom_sum, if_false, zero_lt_one] + · simp only [eq_neg_of_add_eq_zero_left hx, h, neg_one_geom_sum, ite_false, zero_lt_one] · exact geom_sum_pos' hx k.succ.succ_ne_zero lemma geom_sum_pos_iff (hn : n ≠ 0) : 0 < ∑ i ∈ range n, x ^ i ↔ Odd n ∨ 0 < x + 1 := by refine ⟨fun h => ?_, ?_⟩ · rw [or_iff_not_imp_left, ← not_le, Nat.not_odd_iff_even] refine fun hn hx => h.not_ge ?_ - simpa [if_pos hn] using geom_sum_alternating_of_le_neg_one hx n + simpa [ite_eq_left hn] using geom_sum_alternating_of_le_neg_one hx n · rintro (hn | hx') · exact hn.geom_sum_pos · exact geom_sum_pos' hx' hn @@ -136,7 +136,7 @@ lemma geom_sum_ne_zero (hx : x ≠ -1) (hn : n ≠ 0) : ∑ i ∈ range n, x ^ i · exact (geom_sum_pos' h n.succ.succ_ne_zero).ne' lemma geom_sum_eq_zero_iff_neg_one (hn : n ≠ 0) : ∑ i ∈ range n, x ^ i = 0 ↔ x = -1 ∧ Even n := by - refine ⟨fun h => ?_, @fun ⟨h, hn⟩ => by simp only [h, hn, neg_one_geom_sum, if_true]⟩ + refine ⟨fun h => ?_, @fun ⟨h, hn⟩ => by simp only [h, hn, neg_one_geom_sum, ite_true]⟩ contrapose! h have hx := eq_or_ne x (-1) rcases hx with hx | hx diff --git a/Mathlib/Algebra/Order/Ring/StandardPart.lean b/Mathlib/Algebra/Order/Ring/StandardPart.lean index 9d20ef772f8284..88d2ddc5f15b6e 100644 --- a/Mathlib/Algebra/Order/Ring/StandardPart.lean +++ b/Mathlib/Algebra/Order/Ring/StandardPart.lean @@ -290,7 +290,7 @@ def stdPart (x : K) : ℝ := set_option backward.isDefEq.respectTransparency.types false in theorem stdPart_of_mk_nonneg (f : FiniteResidueField K →+*o ℝ) (h : 0 ≤ mk x) : stdPart x = f (.mk <| .mk x h) := by - rw [stdPart, dif_pos h, OrderRingHom.comp_apply] + rw [stdPart, dite_eq_left h, OrderRingHom.comp_apply] congr exact Subsingleton.allEq _ _ @@ -299,8 +299,8 @@ set_option backward.isDefEq.respectTransparency.types false in theorem stdPart_eq_zero {x : K} : stdPart x = 0 ↔ mk x ≠ 0 where mpr h := by obtain h | h := h.lt_or_gt - · exact dif_neg h.not_ge - · rw [stdPart, dif_pos h.le, OrderRingHom.comp_apply, FiniteResidueField.mk_eq_zero.2 h, + · exact dite_eq_right h.not_ge + · rw [stdPart, dite_eq_left h.le, OrderRingHom.comp_apply, FiniteResidueField.mk_eq_zero.2 h, map_zero] mp := by contrapose! @@ -312,17 +312,17 @@ alias ⟨_, stdPart_of_mk_ne_zero⟩ := stdPart_eq_zero theorem stdPart_monotoneOn : MonotoneOn stdPart {x : K | 0 ≤ mk x} := by intro x (hx : 0 ≤ mk x) y (hy : 0 ≤ mk y) h unfold stdPart - rw [dif_pos hx, dif_pos hy] + rw [dite_eq_left hx, dite_eq_left hy] apply OrderRingHom.monotone' rwa [FiniteElement.mk_le_mk] @[simp] theorem stdPart_zero : stdPart (0 : K) = 0 := by - rw [stdPart, dif_pos] <;> simp + rw [stdPart, dite_eq_left] <;> simp @[simp] theorem stdPart_one : stdPart (1 : K) = 1 := by - rw [stdPart, dif_pos] <;> simp + rw [stdPart, dite_eq_left] <;> simp @[simp] theorem stdPart_neg (x : K) : stdPart (-x) = -stdPart x := by @@ -336,7 +336,7 @@ theorem stdPart_inv (x : K) : stdPart x⁻¹ = (stdPart x)⁻¹ := by obtain hx | hx := eq_or_ne (mk x) 0 · unfold stdPart have hx' : 0 ≤ mk x⁻¹ := by simp_all - rw [dif_pos hx.ge, dif_pos hx'] + rw [dite_eq_left hx.ge, dite_eq_left hx'] · apply eq_inv_of_mul_eq_one_left suffices FiniteElement.mk x⁻¹ hx' * .mk x hx.ge = 1 by rw [← map_mul, this, map_one] @@ -348,7 +348,7 @@ theorem stdPart_inv (x : K) : stdPart x⁻¹ = (stdPart x)⁻¹ := by theorem stdPart_add (hx : 0 ≤ mk x) (hy : 0 ≤ mk y) : stdPart (x + y) = stdPart x + stdPart y := by unfold stdPart - rw [dif_pos hx, dif_pos hy, dif_pos] + rw [dite_eq_left hx, dite_eq_left hy, dite_eq_left] exact map_add _ (FiniteElement.mk x hx) (.mk y hy) theorem stdPart_add_eq_right (hx : 0 < mk x) : stdPart (x + y) = stdPart y := by @@ -373,7 +373,7 @@ theorem stdPart_sub_eq_left (hy : 0 < mk y) : stdPart (x - y) = stdPart x := by theorem stdPart_mul (hx : 0 ≤ mk x) (hy : 0 ≤ mk y) : stdPart (x * y) = stdPart x * stdPart y := by unfold stdPart - rw [dif_pos hx, dif_pos hy, dif_pos] + rw [dite_eq_left hx, dite_eq_left hy, dite_eq_left] exact map_mul _ (FiniteElement.mk x hx) (.mk y hy) theorem stdPart_div (hx : 0 ≤ mk x) (hy : 0 ≤ -mk y) : @@ -401,7 +401,7 @@ theorem stdPart_ofNat (n : ℕ) [n.AtLeastTwo] : stdPart (ofNat(n) : K) = n := @[simp] theorem stdPart_map_real (f : ℝ →+*o K) (r : ℝ) : stdPart (f r) = r := by - rw [stdPart, dif_pos] + rw [stdPart, dite_eq_left] exact r.ringHom_apply <| OrderRingHom.comp _ (FiniteResidueField.ofArchimedean f) @[simp] @@ -411,12 +411,12 @@ theorem stdPart_real (r : ℝ) : stdPart r = r := set_option backward.isDefEq.respectTransparency.types false in theorem ofArchimedean_stdPart (f : ℝ →+*o K) (hx : 0 ≤ mk x) : FiniteResidueField.ofArchimedean f (stdPart x) = .mk (.mk x hx) := by - rw [stdPart, dif_pos hx, ← OrderRingHom.comp_apply, ← OrderRingHom.comp_assoc, + rw [stdPart, dite_eq_left hx, ← OrderRingHom.comp_apply, ← OrderRingHom.comp_assoc, OrderRingHom.comp_apply, OrderRingHom.apply_eq_self] theorem stdPart_nonneg {x : K} (h : 0 ≤ x) : 0 ≤ stdPart x := by obtain hx | hx := eq_or_ne (ArchimedeanClass.mk x) 0 - · rw [stdPart, dif_pos hx.ge] + · rw [stdPart, dite_eq_left hx.ge] exact map_nonneg _ h · rw [stdPart_of_mk_ne_zero hx] diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean index 3beca7b6ee5efe..8de1cef7ac16ba 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean @@ -38,7 +38,7 @@ variable {a b c p q : ℚ} theorem ofScientific_nonneg (m : ℕ) (s : Bool) (e : ℕ) : 0 ≤ Rat.ofScientific m s e := by rw [Rat.ofScientific] cases s - · rw [if_neg (by decide)] + · rw [ite_eq_right (by decide)] exact num_nonneg.mp <| Int.natCast_nonneg _ · grind [normalize_eq_mkRat, Rat.mkRat_nonneg] diff --git a/Mathlib/Algebra/Order/Ring/WithTop.lean b/Mathlib/Algebra/Order/Ring/WithTop.lean index a7a8bc4d82a7bd..04b6b39b82715d 100644 --- a/Mathlib/Algebra/Order/Ring/WithTop.lean +++ b/Mathlib/Algebra/Order/Ring/WithTop.lean @@ -34,24 +34,24 @@ instance instMulZeroClass : MulZeroClass (WithTop α) where | ⊤, ⊤ => ⊤ mul_zero | (a : α) => congr_arg some <| mul_zero _ - | ⊤ => if_pos rfl + | ⊤ => ite_eq_left rfl zero_mul | (b : α) => congr_arg some <| zero_mul _ - | ⊤ => if_pos rfl + | ⊤ => ite_eq_left rfl @[simp, norm_cast] lemma coe_mul (a b : α) : (↑(a * b) : WithTop α) = a * b := rfl lemma mul_top' : ∀ (a : WithTop α), a * ⊤ = if a = 0 then 0 else ⊤ | (a : α) => if_congr coe_eq_zero.symm rfl rfl - | ⊤ => (if_neg top_ne_zero).symm + | ⊤ => (ite_eq_right top_ne_zero).symm -@[simp] lemma mul_top (h : a ≠ 0) : a * ⊤ = ⊤ := by rw [mul_top', if_neg h] +@[simp] lemma mul_top (h : a ≠ 0) : a * ⊤ = ⊤ := by rw [mul_top', ite_eq_right h] lemma top_mul' : ∀ (b : WithTop α), ⊤ * b = if b = 0 then 0 else ⊤ | (b : α) => if_congr coe_eq_zero.symm rfl rfl - | ⊤ => (if_neg top_ne_zero).symm + | ⊤ => (ite_eq_right top_ne_zero).symm -@[simp] lemma top_mul (hb : b ≠ 0) : ⊤ * b = ⊤ := by rw [top_mul', if_neg hb] +@[simp] lemma top_mul (hb : b ≠ 0) : ⊤ * b = ⊤ := by rw [top_mul', ite_eq_right hb] @[simp] lemma top_mul_top : (⊤ * ⊤ : WithTop α) = ⊤ := rfl @@ -86,7 +86,7 @@ theorem mul_lt_top [LT α] {a b : WithTop α} (ha : a < ⊤) (hb : b < ⊤) : a instance instNoZeroDivisors [NoZeroDivisors α] : NoZeroDivisors (WithTop α) := by refine ⟨fun h₁ => Decidable.byContradiction fun h₂ => ?_⟩ - rw [mul_def, if_neg h₂] at h₁ + rw [mul_def, ite_eq_right h₂] at h₁ rcases Option.mem_map₂_iff.1 h₁ with ⟨a, b, (rfl : _ = _), (rfl : _ = _), hab⟩ exact h₂ ((eq_zero_or_eq_zero_of_mul_eq_zero hab).imp (congr_arg some) (congr_arg some)) @@ -303,15 +303,15 @@ instance : MulZeroClass (WithBot α) := inferInstanceAs <| MulZeroClass (WithTop lemma mul_bot' : ∀ (a : WithBot α), a * ⊥ = if a = 0 then 0 else ⊥ | (a : α) => if_congr coe_eq_zero.symm rfl rfl - | ⊥ => (if_neg bot_ne_zero).symm + | ⊥ => (ite_eq_right bot_ne_zero).symm -@[simp] lemma mul_bot (h : a ≠ 0) : a * ⊥ = ⊥ := by rw [mul_bot', if_neg h] +@[simp] lemma mul_bot (h : a ≠ 0) : a * ⊥ = ⊥ := by rw [mul_bot', ite_eq_right h] lemma bot_mul' : ∀ (b : WithBot α), ⊥ * b = if b = 0 then 0 else ⊥ | (b : α) => if_congr coe_eq_zero.symm rfl rfl - | ⊥ => (if_neg bot_ne_zero).symm + | ⊥ => (ite_eq_right bot_ne_zero).symm -@[simp] lemma bot_mul (hb : b ≠ 0) : ⊥ * b = ⊥ := by rw [bot_mul', if_neg hb] +@[simp] lemma bot_mul (hb : b ≠ 0) : ⊥ * b = ⊥ := by rw [bot_mul', ite_eq_right hb] @[simp] lemma bot_mul_bot : (⊥ * ⊥ : WithBot α) = ⊥ := rfl diff --git a/Mathlib/Algebra/Order/Round.lean b/Mathlib/Algebra/Order/Round.lean index 63b3adc40b54dc..fa96c3d85e2245 100644 --- a/Mathlib/Algebra/Order/Round.lean +++ b/Mathlib/Algebra/Order/Round.lean @@ -148,12 +148,12 @@ theorem round_ofNat_add (n : ℕ) [n.AtLeastTwo] (x : α) : theorem abs_sub_round_eq_min (x : α) : |x - round x| = min (fract x) (1 - fract x) := by simp_rw [round, min_def_lt, two_mul, ← lt_tsub_iff_left] rcases lt_or_ge (fract x) (1 - fract x) with hx | hx - · rw [if_pos hx, if_pos hx, self_sub_floor, abs_fract] + · rw [ite_eq_left hx, ite_eq_left hx, self_sub_floor, abs_fract] · have : 0 < fract x := by replace hx : 0 < fract x + fract x := lt_of_lt_of_le zero_lt_one (tsub_le_iff_left.mp hx) simpa only [← two_mul, mul_pos_iff_of_pos_left, zero_lt_two] using hx - rw [if_neg (not_lt.mpr hx), if_neg (not_lt.mpr hx), abs_sub_comm, ceil_sub_self_eq this.ne.symm, - abs_one_sub_fract] + rw [ite_eq_right (not_lt.mpr hx), ite_eq_right (not_lt.mpr hx), abs_sub_comm, + ceil_sub_self_eq this.ne.symm, abs_one_sub_fract] theorem round_le (x : α) (z : ℤ) : |x - round x| ≤ |x - z| := by rw [abs_sub_round_eq_min, min_le_iff] diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index 60c0b97c08c1ba..936428cd44087a 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -617,7 +617,7 @@ theorem coeff_X : coeff (X : R[X]) n = if 1 = n then 1 else 0 := coeff_monomial theorem coeff_X_of_ne_one {n : ℕ} (hn : n ≠ 1) : coeff (X : R[X]) n = 0 := by - rw [coeff_X, if_neg hn.symm] + rw [coeff_X, ite_eq_right hn.symm] set_option backward.isDefEq.respectTransparency false in @[simp, grind =] @@ -636,7 +636,7 @@ theorem coeff_C : coeff (C a) n = ite (n = 0) a 0 := by theorem coeff_C_zero : coeff (C a) 0 = a := coeff_monomial -theorem coeff_C_of_ne_zero (h : n ≠ 0) : (C a).coeff n = 0 := by rw [coeff_C, if_neg h] +theorem coeff_C_of_ne_zero (h : n ≠ 0) : (C a).coeff n = 0 := by rw [coeff_C, ite_eq_right h] @[deprecated (since := "2026-05-20")] alias coeff_C_ne_zero := coeff_C_of_ne_zero @@ -1017,10 +1017,10 @@ theorem coeff_update_apply (p : R[X]) (n : ℕ) (a : R) (i : ℕ) : @[simp] theorem coeff_update_same (p : R[X]) (n : ℕ) (a : R) : (p.update n a).coeff n = a := by - rw [p.coeff_update_apply, if_pos rfl] + rw [p.coeff_update_apply, ite_eq_left rfl] theorem coeff_update_ne (p : R[X]) {n i : ℕ} (a : R) (h : i ≠ n) : - (p.update n a).coeff i = p.coeff i := by rw [p.coeff_update_apply, if_neg h] + (p.update n a).coeff i = p.coeff i := by rw [p.coeff_update_apply, ite_eq_right h] @[simp] theorem update_zero_eq_erase (p : R[X]) (n : ℕ) : p.update n 0 = p.erase n := by @@ -1036,7 +1036,7 @@ theorem support_update_zero (p : R[X]) (n : ℕ) : support (p.update n 0) = p.su rw [update_zero_eq_erase, support_erase] theorem support_update_ne_zero (p : R[X]) (n : ℕ) {a : R} (ha : a ≠ 0) : - support (p.update n a) = insert n p.support := by classical rw [support_update, if_neg ha] + support (p.update n a) = insert n p.support := by classical rw [support_update, ite_eq_right ha] end Update diff --git a/Mathlib/Algebra/Polynomial/BigOperators.lean b/Mathlib/Algebra/Polynomial/BigOperators.lean index a95597b181e5cf..10833431a2c1e1 100644 --- a/Mathlib/Algebra/Polynomial/BigOperators.lean +++ b/Mathlib/Algebra/Polynomial/BigOperators.lean @@ -268,7 +268,7 @@ theorem multiset_prod_X_sub_C_coeff_card_pred (t : Multiset R) (ht : 0 < Multise (t.map fun x => X - C x).prod.coeff ((Multiset.card t) - 1) = -t.sum := by nontriviality R convert! multiset_prod_X_sub_C_nextCoeff (by assumption) - rw [nextCoeff, if_neg] + rw [nextCoeff, ite_eq_right] swap · rw [natDegree_multiset_prod_of_monic] swap diff --git a/Mathlib/Algebra/Polynomial/Coeff.lean b/Mathlib/Algebra/Polynomial/Coeff.lean index 084d9feb1abc0a..83b0733cab2c79 100644 --- a/Mathlib/Algebra/Polynomial/Coeff.lean +++ b/Mathlib/Algebra/Polynomial/Coeff.lean @@ -200,17 +200,18 @@ theorem support_binomial {k m : ℕ} (hkm : k ≠ m) {x y : R} (hx : x ≠ 0) (h support (C x * X ^ k + C y * X ^ m) = {k, m} := by apply subset_antisymm (support_binomial_subset k m x y) simp_rw [insert_subset_iff, singleton_subset_iff, mem_support_iff, coeff_add, coeff_C_mul, - coeff_X_pow_self, mul_one, coeff_X_pow, if_neg hkm, if_neg hkm.symm, mul_zero, zero_add, - add_zero, Ne, hx, hy, not_false_eq_true, and_true] + coeff_X_pow_self, mul_one, coeff_X_pow, ite_eq_right hkm, ite_eq_right hkm.symm, mul_zero, + zero_add, add_zero, Ne, hx, hy, not_false_eq_true, and_true] theorem support_trinomial {k m n : ℕ} (hkm : k < m) (hmn : m < n) {x y z : R} (hx : x ≠ 0) (hy : y ≠ 0) (hz : z ≠ 0) : support (C x * X ^ k + C y * X ^ m + C z * X ^ n) = {k, m, n} := by apply subset_antisymm (support_trinomial_subset k m n x y z) simp_rw [insert_subset_iff, singleton_subset_iff, mem_support_iff, coeff_add, coeff_C_mul, - coeff_X_pow_self, mul_one, coeff_X_pow, if_neg hkm.ne, if_neg hkm.ne', if_neg hmn.ne, - if_neg hmn.ne', if_neg (hkm.trans hmn).ne, if_neg (hkm.trans hmn).ne', mul_zero, add_zero, - zero_add, Ne, hx, hy, hz, not_false_eq_true, and_true] + coeff_X_pow_self, mul_one, coeff_X_pow, ite_eq_right hkm.ne, ite_eq_right hkm.ne', + ite_eq_right hmn.ne, ite_eq_right hmn.ne', ite_eq_right (hkm.trans hmn).ne, + ite_eq_right (hkm.trans hmn).ne', mul_zero, add_zero, zero_add, Ne, hx, hy, hz, + not_false_eq_true, and_true] theorem card_support_binomial {k m : ℕ} (h : k ≠ m) {x y : R} (hx : x ≠ 0) (hy : y ≠ 0) : #(support (C x * X ^ k + C y * X ^ m)) = 2 := by @@ -228,9 +229,9 @@ end Fewnomials @[simp] theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) : coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by - rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one] + rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, ite_eq_left rfl, mul_one] · rintro ⟨i, j⟩ h1 h2 - rw [coeff_X_pow, if_neg, mul_zero] + rw [coeff_X_pow, ite_eq_right, mul_zero] grind [mem_antidiagonal] · grind [mem_antidiagonal] @@ -244,7 +245,7 @@ theorem coeff_mul_X_pow' (p : R[X]) (n d : ℕ) : split_ifs with h · rw [← tsub_add_cancel_of_le h, coeff_mul_X_pow, add_tsub_cancel_right] · refine (coeff_mul _ _ _).trans (Finset.sum_eq_zero fun x hx => ?_) - rw [coeff_X_pow, if_neg, mul_zero] + rw [coeff_X_pow, ite_eq_right, mul_zero] exact ((le_of_add_le_right (mem_antidiagonal.mp hx).le).trans_lt <| not_le.mp h).ne theorem coeff_X_pow_mul' (p : R[X]) (n d : ℕ) : diff --git a/Mathlib/Algebra/Polynomial/Degree/CardPowDegree.lean b/Mathlib/Algebra/Polynomial/Degree/CardPowDegree.lean index 195860d1b24c60..3fe8765863e232 100644 --- a/Mathlib/Algebra/Polynomial/Degree/CardPowDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/CardPowDegree.lean @@ -60,15 +60,15 @@ noncomputable def cardPowDegree : AbsoluteValue Fq[X] ℤ := by_cases hp : p = 0; · simp [hp] by_cases hq : q = 0; · simp [hq] by_cases hpq : p + q = 0 - · simp only [hpq, hp, hq, if_true, if_false] + · simp only [hpq, hp, hq, ite_true, ite_false] exact add_nonneg (pow_pos _).le (pow_pos _).le - simp only [hpq, hp, hq, if_false] + simp only [hpq, hp, hq, ite_false] exact le_trans (pow_right_mono₀ (by lia) (Polynomial.natDegree_add_le _ _)) (by grind) map_mul' := fun p q => by by_cases hp : p = 0; · simp [hp] by_cases hq : q = 0; · simp [hq] have hpq : p * q ≠ 0 := mul_ne_zero hp hq - simp only [hpq, hp, hq, if_false, Polynomial.natDegree_mul hp hq, pow_add] } + simp only [hpq, hp, hq, ite_false, Polynomial.natDegree_mul hp hq, pow_add] } theorem cardPowDegree_apply [DecidableEq Fq] (p : Fq[X]) : cardPowDegree p = if p = 0 then 0 else (Fintype.card Fq : ℤ) ^ natDegree p := by @@ -80,7 +80,7 @@ theorem cardPowDegree_zero : cardPowDegree (0 : Fq[X]) = 0 := rfl @[simp] theorem cardPowDegree_nonzero (p : Fq[X]) (hp : p ≠ 0) : cardPowDegree p = (Fintype.card Fq : ℤ) ^ p.natDegree := - if_neg hp + ite_eq_right hp theorem cardPowDegree_isEuclidean : IsEuclidean (cardPowDegree : AbsoluteValue Fq[X] ℤ) := have card_pos : 0 < Fintype.card Fq := Fintype.card_pos_iff.mpr inferInstance diff --git a/Mathlib/Algebra/Polynomial/Degree/Defs.lean b/Mathlib/Algebra/Polynomial/Degree/Defs.lean index f98f77c66b3085..e0868f4d918765 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Defs.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Defs.lean @@ -229,7 +229,7 @@ theorem natDegree_monomial_le (a : R) {m : ℕ} : (monomial m a).natDegree ≤ m theorem natDegree_monomial_eq (i : ℕ) {r : R} (r0 : r ≠ 0) : (monomial i r).natDegree = i := letI := Classical.decEq R - Eq.trans (natDegree_monomial _ _) (if_neg r0) + Eq.trans (natDegree_monomial _ _) (ite_eq_right r0) theorem coeff_ne_zero_of_eq_degree (hn : degree p = n) : coeff p n ≠ 0 := fun h => mem_support_iff.mp (mem_of_max hn) h @@ -317,7 +317,7 @@ theorem nextCoeff_C_eq_zero (c : R) : nextCoeff (C c) = 0 := by theorem nextCoeff_of_natDegree_pos (hp : 0 < p.natDegree) : nextCoeff p = p.coeff (p.natDegree - 1) := by - rw [nextCoeff, if_neg] + rw [nextCoeff, ite_eq_right] contrapose! hp simpa @@ -415,7 +415,7 @@ theorem leadingCoeff_monomial (a : R) (n : ℕ) : leadingCoeff (monomial n a) = classical by_cases ha : a = 0 · simp only [ha, (monomial n).map_zero, leadingCoeff_zero] - · rw [leadingCoeff, natDegree_monomial, if_neg ha, coeff_monomial] + · rw [leadingCoeff, natDegree_monomial, ite_eq_right ha, coeff_monomial] simp theorem leadingCoeff_C_mul_X_pow (a : R) (n : ℕ) : leadingCoeff (C a * X ^ n) = a := by diff --git a/Mathlib/Algebra/Polynomial/Degree/Operations.lean b/Mathlib/Algebra/Polynomial/Degree/Operations.lean index 71f88889a733b0..15f66ee601c078 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Operations.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Operations.lean @@ -163,7 +163,7 @@ theorem natDegree_lt_natDegree_iff (hp : p ≠ 0) : natDegree p < natDegree q theorem eq_C_of_degree_le_zero (h : degree p ≤ 0) : p = C (coeff p 0) := by ext (_ | n) · simp - rw [coeff_C, if_neg (Nat.succ_ne_zero _), coeff_eq_zero_of_degree_lt] + rw [coeff_C, ite_eq_right (Nat.succ_ne_zero _), coeff_eq_zero_of_degree_lt] exact h.trans_lt (WithBot.coe_lt_coe.2 n.succ_pos) theorem eq_C_of_degree_eq_zero (h : degree p = 0) : p = C (coeff p 0) := @@ -653,7 +653,7 @@ theorem leadingCoeff_X_pow_add_C {n : ℕ} (hn : 0 < n) {r : R} : (X ^ n + C r).leadingCoeff = 1 := by nontriviality R rw [leadingCoeff, natDegree_X_pow_add_C, coeff_add, coeff_X_pow_self, coeff_C, - if_neg (pos_iff_ne_zero.mp hn), add_zero] + ite_eq_right (pos_iff_ne_zero.mp hn), add_zero] @[simp] theorem leadingCoeff_X_add_C [Semiring S] (r : S) : (X + C r).leadingCoeff = 1 := by diff --git a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean index a8cad592992e73..e1253c74df4b89 100644 --- a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean @@ -283,8 +283,8 @@ theorem natTrailingDegree_mul_X_pow {p : R[X]} (hp : p ≠ 0) (n : ℕ) : intro y hy have key : n ≤ y := by rw [mem_support_iff, coeff_mul_X_pow'] at hy - exact by_contra fun h => hy (if_neg h) - rw [mem_support_iff, coeff_mul_X_pow', if_pos key] at hy + exact by_contra fun h => hy (ite_eq_right h) + rw [mem_support_iff, coeff_mul_X_pow', ite_eq_left key] at hy exact (le_tsub_iff_right key).mp (natTrailingDegree_le_of_ne_zero hy) theorem le_trailingDegree_mul : p.trailingDegree + q.trailingDegree ≤ (p * q).trailingDegree := by @@ -410,7 +410,7 @@ theorem nextCoeffUp_of_constantCoeff_eq_zero (p : R[X]) (hp : coeff p 0 = 0) : nextCoeffUp p = p.coeff (p.natTrailingDegree + 1) := by obtain rfl | hp₀ := eq_or_ne p 0 · simp - · rw [nextCoeffUp, if_neg (natTrailingDegree_ne_zero.2 ⟨hp₀, hp⟩)] + · rw [nextCoeffUp, ite_eq_right (natTrailingDegree_ne_zero.2 ⟨hp₀, hp⟩)] end Semiring @@ -439,9 +439,9 @@ lemma eq_X_pow_iff_natDegree_le_natTrailingDegree (h₁ : p.Monic) : · ext n rw [coeff_X_pow] obtain hn | rfl | hn := lt_trichotomy n p.natDegree - · rw [if_neg hn.ne, coeff_eq_zero_of_lt_natTrailingDegree (hn.trans_le h)] - · simpa only [if_pos rfl] using! h₁.leadingCoeff - · rw [if_neg hn.ne', coeff_eq_zero_of_natDegree_lt hn] + · rw [ite_eq_right hn.ne, coeff_eq_zero_of_lt_natTrailingDegree (hn.trans_le h)] + · simpa only [ite_eq_left rfl] using! h₁.leadingCoeff + · rw [ite_eq_right hn.ne', coeff_eq_zero_of_natDegree_lt hn] lemma eq_X_pow_iff_natTrailingDegree_eq_natDegree (h₁ : p.Monic) : p = X ^ p.natDegree ↔ p.natTrailingDegree = p.natDegree := diff --git a/Mathlib/Algebra/Polynomial/Derivative.lean b/Mathlib/Algebra/Polynomial/Derivative.lean index 78181a7c5ac083..5e69cef23b27f3 100644 --- a/Mathlib/Algebra/Polynomial/Derivative.lean +++ b/Mathlib/Algebra/Polynomial/Derivative.lean @@ -60,13 +60,13 @@ theorem coeff_derivative (p : R[X]) (n : ℕ) : rw [derivative_apply] simp only [coeff_X_pow, coeff_sum, coeff_C_mul] rw [sum, Finset.sum_eq_single (n + 1)] - · simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true]; norm_cast + · simp only [Nat.add_succ_sub_one, add_zero, mul_one, ite_true]; norm_cast · intro b cases b · intros rw [Nat.cast_zero, mul_zero, zero_mul] · intro _ H - rw [Nat.add_one_sub_one, if_neg (mt (congr_arg Nat.succ) H.symm), mul_zero] + rw [Nat.add_one_sub_one, ite_eq_right (mt (congr_arg Nat.succ) H.symm), mul_zero] · simp_all @[simp] diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index 2101c4063f5628..405fe0993f18c0 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -158,13 +158,13 @@ theorem degree_modByMonic_lt [Nontrivial R] : (by unfold modByMonic divModByMonicAux dsimp - rw [dif_pos hq, if_neg h] + rw [dite_eq_left hq, ite_eq_right h] exact lt_of_not_ge) (by intro hp unfold modByMonic divModByMonicAux dsimp - rw [dif_pos hq, if_neg h, Classical.not_not.1 hp] + rw [dite_eq_left hq, ite_eq_right h, Classical.not_not.1 hp] exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 hq.ne_zero))) termination_by p => p @@ -191,7 +191,7 @@ theorem modByMonic_zero (p : R[X]) : p %ₘ 0 = p := if h : Monic (0 : R[X]) then by have := monic_zero_iff_subsingleton.mp h simp [eq_iff_true_of_subsingleton] - else by unfold modByMonic divModByMonicAux; rw [dif_neg h] + else by unfold modByMonic divModByMonicAux; rw [dite_eq_right h] @[simp] theorem divByMonic_zero (p : R[X]) : p /ₘ 0 = 0 := @@ -199,18 +199,19 @@ theorem divByMonic_zero (p : R[X]) : p /ₘ 0 = 0 := if h : Monic (0 : R[X]) then by have := monic_zero_iff_subsingleton.mp h simp [eq_iff_true_of_subsingleton] - else by unfold divByMonic divModByMonicAux; rw [dif_neg h] + else by unfold divByMonic divModByMonicAux; rw [dite_eq_right h] theorem divByMonic_eq_of_not_monic (p : R[X]) (hq : ¬Monic q) : p /ₘ q = 0 := - dif_neg hq + dite_eq_right hq theorem modByMonic_eq_of_not_monic (p : R[X]) (hq : ¬Monic q) : p %ₘ q = p := - dif_neg hq + dite_eq_right hq theorem modByMonic_eq_self_iff [Nontrivial R] (hq : Monic q) : p %ₘ q = p ↔ degree p < degree q := ⟨fun h => h ▸ degree_modByMonic_lt _ hq, fun h => by have : ¬degree q ≤ degree p := not_le_of_gt h - unfold modByMonic divModByMonicAux; dsimp; rw [dif_pos hq, if_neg (mt And.left this)]⟩ + unfold modByMonic divModByMonicAux; dsimp + rw [dite_eq_left hq, ite_eq_right (mt And.left this)]⟩ theorem degree_modByMonic_le (p : R[X]) {q : R[X]} (hq : Monic q) : degree (p %ₘ q) ≤ degree q := by nontriviality R @@ -244,14 +245,15 @@ theorem modByMonic_eq_sub_mul_div : have ih := modByMonic_eq_sub_mul_div (p - q * (C (leadingCoeff p) * X ^ (natDegree p - natDegree q))) q unfold modByMonic divByMonic divModByMonicAux - rw [dif_pos hq, dif_pos h] - rw [modByMonic, dif_pos hq] at ih + rw [dite_eq_left hq, dite_eq_left h] + rw [modByMonic, dite_eq_left hq] at ih refine ih.trans ?_ - rw [divByMonic, dif_pos hq, dif_pos hq, dif_pos h, mul_add, sub_add_eq_sub_sub] + rw [divByMonic, dite_eq_left hq, dite_eq_left hq, dite_eq_left h, mul_add, + sub_add_eq_sub_sub] else by unfold modByMonic divByMonic divModByMonicAux dsimp - rw [dif_pos hq, if_neg h, dif_pos hq, if_neg h, mul_zero, sub_zero] + rw [dite_eq_left hq, ite_eq_right h, dite_eq_left hq, ite_eq_right h, mul_zero, sub_zero] else by rw [modByMonic_eq_of_not_monic _ hq, divByMonic_eq_of_not_monic _ hq, mul_zero, sub_zero] termination_by p => p @@ -273,7 +275,8 @@ theorem divByMonic_eq_zero_iff [Nontrivial R] (hq : Monic q) : p /ₘ q = 0 ↔ rwa [h, mul_zero, add_zero, modByMonic_eq_self_iff hq] at this, fun h => by have : ¬degree q ≤ degree p := not_le_of_gt h - unfold divByMonic divModByMonicAux; dsimp; rw [dif_pos hq, if_neg (mt And.left this)]⟩ + unfold divByMonic divModByMonicAux; dsimp + rw [dite_eq_left hq, ite_eq_right (mt And.left this)]⟩ theorem degree_add_divByMonic (hq : Monic q) (h : degree q ≤ degree p) : degree q + degree (p /ₘ q) = degree p := by @@ -305,7 +308,7 @@ theorem degree_divByMonic_le (p q : R[X]) : degree (p /ₘ q) ≤ degree p := exact WithBot.coe_le_coe.2 (Nat.le_add_left _ _) else by unfold divByMonic divModByMonicAux - simp [dif_pos hq, h, degree_zero, bot_le] + simp [dite_eq_left hq, h, degree_zero, bot_le] else (divByMonic_eq_of_not_monic p hq).symm ▸ bot_le theorem degree_divByMonic_lt (p q : R[X]) (hp0 : p ≠ 0) @@ -510,7 +513,7 @@ theorem rootMultiplicity_eq_natFind_of_ne_zero {p : R[X]} (p0 : p ≠ 0) {a : R} [DecidablePred fun n : ℕ => ¬(X - C a) ^ (n + 1) ∣ p] : rootMultiplicity a p = Nat.find (finiteMultiplicity_X_sub_C a p0) := by dsimp [rootMultiplicity] - rw [dif_neg p0] + rw [dite_eq_right p0] congr @[deprecated (since := "2026-02-12")] @@ -530,7 +533,7 @@ theorem rootMultiplicity_eq_multiplicity [DecidableEq R] @[simp] theorem rootMultiplicity_zero {x : R} : rootMultiplicity x 0 = 0 := - dif_pos rfl + dite_eq_left rfl @[simp] theorem rootMultiplicity_C (r a : R) : rootMultiplicity a (C r) = 0 := by @@ -547,7 +550,7 @@ theorem pow_rootMultiplicity_dvd (p : R[X]) (a : R) : (X - C a) ^ rootMultiplici letI := Classical.decEq R if h : p = 0 then by simp [h] else by - rw [rootMultiplicity_eq_multiplicity, if_neg h]; apply pow_multiplicity_dvd + rw [rootMultiplicity_eq_multiplicity, ite_eq_right h]; apply pow_multiplicity_dvd theorem pow_mul_divByMonic_rootMultiplicity_eq (p : R[X]) (a : R) : (X - C a) ^ rootMultiplicity a p * (p /ₘ (X - C a) ^ rootMultiplicity a p) = p := by @@ -559,7 +562,7 @@ theorem pow_mul_divByMonic_rootMultiplicity_eq (p : R[X]) (a : R) : theorem exists_eq_pow_rootMultiplicity_mul_and_not_dvd (p : R[X]) (hp : p ≠ 0) (a : R) : ∃ q : R[X], p = (X - C a) ^ p.rootMultiplicity a * q ∧ ¬ (X - C a) ∣ q := by classical - rw [rootMultiplicity_eq_multiplicity, if_neg hp] + rw [rootMultiplicity_eq_multiplicity, ite_eq_right hp] apply (finiteMultiplicity_X_sub_C a hp).exists_eq_pow_mul_and_not_dvd end multiplicity @@ -645,7 +648,7 @@ theorem eval_divByMonic_pow_rootMultiplicity_ne_zero {p : R[X]} (a : R) (hp : p rw [Ne, ← IsRoot, ← dvd_iff_isRoot] rintro ⟨q, hq⟩ have := pow_mul_divByMonic_rootMultiplicity_eq p a - rw [hq, ← mul_assoc, ← pow_succ, rootMultiplicity_eq_multiplicity, if_neg hp] at this + rw [hq, ← mul_assoc, ← pow_succ, rootMultiplicity_eq_multiplicity, ite_eq_right hp] at this exact (finiteMultiplicity_of_degree_pos_of_monic (show (0 : WithBot ℕ) < degree (X - C a) by rw [degree_X_sub_C]; decide) @@ -713,7 +716,7 @@ lemma eval_divByMonic_eq_trailingCoeff_comp {p : R[X]} {t : R} : `(X - a) ^ n` divides `p`. -/ lemma le_rootMultiplicity_iff (p0 : p ≠ 0) {a : R} {n : ℕ} : n ≤ rootMultiplicity a p ↔ (X - C a) ^ n ∣ p := by - simp_rw [rootMultiplicity, dif_neg p0, Nat.le_find_iff, not_not] + simp_rw [rootMultiplicity, dite_eq_right p0, Nat.le_find_iff, not_not] refine ⟨fun h => ?_, fun h m hm => (pow_dvd_pow _ hm).trans h⟩ rcases n with - | n · rw [pow_zero] diff --git a/Mathlib/Algebra/Polynomial/EraseLead.lean b/Mathlib/Algebra/Polynomial/EraseLead.lean index df0bffaaa19fec..097318f43f87cd 100644 --- a/Mathlib/Algebra/Polynomial/EraseLead.lean +++ b/Mathlib/Algebra/Polynomial/EraseLead.lean @@ -133,7 +133,7 @@ theorem eraseLead_monomial (i : ℕ) (r : R) : eraseLead (monomial i r) = 0 := b by_cases hr : r = 0 · subst r simp only [monomial_zero_right, eraseLead_zero] - · rw [eraseLead, natDegree_monomial, if_neg hr, erase_monomial] + · rw [eraseLead, natDegree_monomial, ite_eq_right hr, erase_monomial] @[simp] theorem eraseLead_C (r : R) : eraseLead (C r) = 0 := @@ -158,9 +158,9 @@ theorem eraseLead_add_of_degree_lt_left {p q : R[X]} (pq : q.degree < p.degree) (p + q).eraseLead = p.eraseLead + q := by ext n by_cases nd : n = p.natDegree - · rw [nd, eraseLead_coeff, if_pos (natDegree_add_eq_left_of_degree_lt pq).symm] + · rw [nd, eraseLead_coeff, ite_eq_left (natDegree_add_eq_left_of_degree_lt pq).symm] simpa using (coeff_eq_zero_of_degree_lt (lt_of_lt_of_le pq degree_le_natDegree)).symm - · rw [eraseLead_coeff, coeff_add, coeff_add, eraseLead_coeff, if_neg, if_neg nd] + · rw [eraseLead_coeff, coeff_add, coeff_add, eraseLead_coeff, ite_eq_right, ite_eq_right nd] rintro rfl exact nd (natDegree_add_eq_left_of_degree_lt pq) @@ -172,9 +172,9 @@ theorem eraseLead_add_of_degree_lt_right {p q : R[X]} (pq : p.degree < q.degree) (p + q).eraseLead = p + q.eraseLead := by ext n by_cases nd : n = q.natDegree - · rw [nd, eraseLead_coeff, if_pos (natDegree_add_eq_right_of_degree_lt pq).symm] + · rw [nd, eraseLead_coeff, ite_eq_left (natDegree_add_eq_right_of_degree_lt pq).symm] simpa using (coeff_eq_zero_of_degree_lt (lt_of_lt_of_le pq degree_le_natDegree)).symm - · rw [eraseLead_coeff, coeff_add, coeff_add, eraseLead_coeff, if_neg, if_neg nd] + · rw [eraseLead_coeff, coeff_add, coeff_add, eraseLead_coeff, ite_eq_right, ite_eq_right nd] rintro rfl exact nd (natDegree_add_eq_right_of_degree_lt pq) @@ -249,7 +249,7 @@ lemma two_le_natDegree_of_nextCoeff_eraseLead (hlead : f.eraseLead ≠ 0) theorem leadingCoeff_eraseLead_eq_nextCoeff (h : f.nextCoeff ≠ 0) : f.eraseLead.leadingCoeff = f.nextCoeff := by have := natDegree_pos_of_nextCoeff_ne_zero h - rw [leadingCoeff, nextCoeff, natDegree_eraseLead h, if_neg, + rw [leadingCoeff, nextCoeff, natDegree_eraseLead h, ite_eq_right, eraseLead_coeff_of_ne _ (tsub_lt_self _ _).ne] all_goals positivity @@ -295,14 +295,15 @@ lemma eraseLead_mul_eq_mul_eraseLead_of_nextCoeff_zero {R : Type*} [Ring R] [NoZ · --n < P.natDegree have hd₁ : n < ((X - C x) * P).eraseLead.natDegree := by linarith [natDegree_eraseLead_add_one h₂] - rw [← self_sub_monomial_natDegree_leadingCoeff, coeff_sub, coeff_monomial, if_neg hd₁.ne'] - rw [← self_sub_monomial_natDegree_leadingCoeff, coeff_sub, coeff_monomial, if_neg (by lia)] + rw [← self_sub_monomial_natDegree_leadingCoeff, coeff_sub, coeff_monomial, ite_eq_right hd₁.ne'] + rw [← self_sub_monomial_natDegree_leadingCoeff, coeff_sub, coeff_monomial, + ite_eq_right (by lia)] rw [← self_sub_monomial_natDegree_leadingCoeff, mul_sub, coeff_sub, sub_zero, sub_zero, eq_sub_iff_add_eq, add_eq_left] rcases hn₂ : n · simpa [coeff_monomial, hp] using! fun _ ↦ by lia - · rw [coeff_X_sub_C_mul, coeff_monomial, coeff_monomial, if_neg (by lia), - if_neg (by lia), mul_zero, sub_zero] + · rw [coeff_X_sub_C_mul, coeff_monomial, coeff_monomial, ite_eq_right (by lia), + ite_eq_right (by lia), mul_zero, sub_zero] · --n ≥ P.natDegree, so all the coefficients are zero. trans 0 <;> rw [coeff_eq_zero_of_natDegree_lt] · grw [eraseLead_natDegree_le, eraseLead_natDegree_le] @@ -396,9 +397,9 @@ theorem card_support_eq' {n : ℕ} (k : Fin n → ℕ) (x : Fin n → R) (hk : F · obtain ⟨j, _, h⟩ := exists_ne_zero_of_sum_ne_zero h exact ⟨j, (ite_ne_right_iff.mp h).1.symm⟩ · rintro ⟨j, _, rfl⟩ - rw [sum_eq_single_of_mem j (mem_univ j), if_pos rfl] + rw [sum_eq_single_of_mem j (mem_univ j), ite_eq_left rfl] · exact hx j - · exact fun m _ hmj => if_neg fun h => hmj.symm (hk h) + · exact fun m _ hmj => ite_eq_right fun h => hmj.symm (hk h) theorem card_support_eq {n : ℕ} : #f.support = n ↔ @@ -432,7 +433,7 @@ theorem card_support_eq {n : ℕ} : rw [sum_eq_single, coeff_C_mul, coeff_X_pow_self, mul_one] · exact hx i · intro j _ hji - rw [coeff_C_mul, coeff_X_pow, if_neg (hk.injective.ne hji.symm), mul_zero] + rw [coeff_C_mul, coeff_X_pow, ite_eq_right (hk.injective.ne hji.symm), mul_zero] · exact fun hi => (hi (mem_univ i)).elim · intro i by_cases hi : ∃ i₀, Fin.castSucc i₀ = i diff --git a/Mathlib/Algebra/Polynomial/Eval/Degree.lean b/Mathlib/Algebra/Polynomial/Eval/Degree.lean index 2040f65da66435..434ebde0318cc1 100644 --- a/Mathlib/Algebra/Polynomial/Eval/Degree.lean +++ b/Mathlib/Algebra/Polynomial/Eval/Degree.lean @@ -108,8 +108,8 @@ theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) : (p.comp <| C r * X).coeff n = p.coeff n * r ^ n := by simp_rw [comp, eval₂_eq_sum_range, (commute_X _).symm.mul_pow, ← C_pow, finsetSum_coeff, coeff_C_mul, coeff_X_pow] - rw [Finset.sum_eq_single n _ fun h ↦ ?_, if_pos rfl, mul_one] - · intro b _ h; simp_rw [if_neg h.symm, mul_zero] + rw [Finset.sum_eq_single n _ fun h ↦ ?_, ite_eq_left rfl, mul_one] + · intro b _ h; simp_rw [ite_eq_right h.symm, mul_zero] · rw [coeff_eq_zero_of_natDegree_lt, zero_mul] rwa [Finset.mem_range_succ_iff, not_le] at h diff --git a/Mathlib/Algebra/Polynomial/Expand.lean b/Mathlib/Algebra/Polynomial/Expand.lean index 4f64e2f5a600f9..75ea931caa3d98 100644 --- a/Mathlib/Algebra/Polynomial/Expand.lean +++ b/Mathlib/Algebra/Polynomial/Expand.lean @@ -94,9 +94,9 @@ theorem coeff_expand {p : ℕ} (hp : 0 < p) (f : R[X]) (n : ℕ) : simp only [expand_eq_sum] simp_rw [coeff_sum, ← pow_mul, C_mul_X_pow_eq_monomial, coeff_monomial, sum] split_ifs with h - · rw [Finset.sum_eq_single (n / p), Nat.mul_div_cancel' h, if_pos rfl] + · rw [Finset.sum_eq_single (n / p), Nat.mul_div_cancel' h, ite_eq_left rfl] · intro b _ hb2 - rw [if_neg] + rw [ite_eq_right] intro hb3 apply hb2 rw [← hb3, Nat.mul_div_cancel_left b hp] @@ -105,13 +105,13 @@ theorem coeff_expand {p : ℕ} (hp : 0 < p) (f : R[X]) (n : ℕ) : split_ifs <;> rfl · rw [Finset.sum_eq_zero] intro k _ - rw [if_neg] + rw [ite_eq_right] exact fun hkn => h ⟨k, hkn.symm⟩ @[simp] theorem coeff_expand_mul {p : ℕ} (hp : 0 < p) (f : R[X]) (n : ℕ) : (expand R p f).coeff (n * p) = f.coeff n := by - rw [coeff_expand hp, if_pos (dvd_mul_left _ _), Nat.mul_div_cancel _ hp] + rw [coeff_expand hp, ite_eq_left (dvd_mul_left _ _), Nat.mul_div_cancel _ hp] @[simp] theorem coeff_expand_mul' {p : ℕ} (hp : 0 < p) (f : R[X]) (n : ℕ) : @@ -228,7 +228,7 @@ theorem contract_mul_expand {p : ℕ} (hp : p ≠ 0) (f g : R[X]) : obtain ⟨y, rfl⟩ := h refine (nex ⟨⟨x, y⟩, (Nat.mul_right_cancel_iff hp.bot_lt).mp ?_, by simp_rw [mul_comm]⟩).elim rw [← eq, mul_comm, mul_add] - · rw [coeff_expand hp.bot_lt, if_neg h, mul_zero] + · rw [coeff_expand hp.bot_lt, ite_eq_right h, mul_zero] @[simp] theorem isCoprime_expand {f g : R[X]} {p : ℕ} (hp : p ≠ 0) : IsCoprime (expand R p f) (expand R p g) ↔ IsCoprime f g := @@ -308,7 +308,7 @@ variable (R : Type u) [CommRing R] [IsDomain R] theorem isLocalHom_expand {p : ℕ} (hp : 0 < p) : IsLocalHom (expand R p) := by refine ⟨fun f hf1 => ?_⟩ have hf2 := eq_C_of_degree_eq_zero (degree_eq_zero_of_isUnit hf1) - rw [coeff_expand hp, if_pos (dvd_zero _), p.zero_div] at hf2 + rw [coeff_expand hp, ite_eq_left (dvd_zero _), p.zero_div] at hf2 rw [hf2, isUnit_C] at hf1; rw [expand_eq_C hp] at hf2; rwa [hf2, isUnit_C] variable {R} diff --git a/Mathlib/Algebra/Polynomial/FieldDivision.lean b/Mathlib/Algebra/Polynomial/FieldDivision.lean index 553755e3e42955..4ca607b3499204 100644 --- a/Mathlib/Algebra/Polynomial/FieldDivision.lean +++ b/Mathlib/Algebra/Polynomial/FieldDivision.lean @@ -370,10 +370,10 @@ theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q := ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p := not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0] - rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)] + rw [mod_def, modByMonic, dite_eq_left (monic_mul_leadingCoeff_inv hq0)] unfold divModByMonicAux dsimp - simp only [this, false_and, if_false]⟩ + simp only [this, false_and, ite_false]⟩ protected theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q := ⟨fun h => by diff --git a/Mathlib/Algebra/Polynomial/HasseDeriv.lean b/Mathlib/Algebra/Polynomial/HasseDeriv.lean index ec054db563a362..b62047dae033ad 100644 --- a/Mathlib/Algebra/Polynomial/HasseDeriv.lean +++ b/Mathlib/Algebra/Polynomial/HasseDeriv.lean @@ -107,10 +107,10 @@ theorem hasseDeriv_monomial (n : ℕ) (r : R) : simp only [hasseDeriv_coeff, coeff_monomial] by_cases hnik : n = i + k · grind - · rw [if_neg hnik, mul_zero] + · rw [ite_eq_right hnik, mul_zero] by_cases! hkn : k ≤ n · rw [← tsub_eq_iff_eq_add_of_le hkn] at hnik - rw [if_neg hnik] + rw [ite_eq_right hnik] · rw [Nat.choose_eq_zero_of_lt hkn, Nat.cast_zero, zero_mul, ite_self] theorem hasseDeriv_C (r : R) (hk : 0 < k) : hasseDeriv k (C r) = 0 := by diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index ce2a095caf6ad1..bc915e0af608f8 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -316,7 +316,7 @@ theorem leftInverse_trunc_toLaurent : simp only [hf, hg, map_add] · intro n r simp only [Polynomial.toLaurent_C_mul_T, trunc_C_mul_T, Int.natCast_nonneg, Int.toNat_natCast, - if_true] + ite_true] @[simp] theorem _root_.Polynomial.trunc_toLaurent (f : R[X]) : trunc (toLaurent f) = f := diff --git a/Mathlib/Algebra/Polynomial/Mirror.lean b/Mathlib/Algebra/Polynomial/Mirror.lean index 26234c588f95d5..b63eeffed4980a 100644 --- a/Mathlib/Algebra/Polynomial/Mirror.lean +++ b/Mathlib/Algebra/Polynomial/Mirror.lean @@ -46,7 +46,7 @@ theorem mirror_monomial (n : ℕ) (a : R) : (monomial n a).mirror = monomial n a classical by_cases ha : a = 0 · rw [ha, monomial_zero_right, mirror_zero] - · rw [mirror, reverse, natDegree_monomial n a, if_neg ha, natTrailingDegree_monomial ha, ← + · rw [mirror, reverse, natDegree_monomial n a, ite_eq_right ha, natTrailingDegree_monomial ha, ← C_mul_X_pow_eq_monomial, reflect_C_mul_X_pow, revAt_le (le_refl n), tsub_self, pow_zero, mul_one] @@ -77,12 +77,12 @@ theorem coeff_mirror (n : ℕ) : by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree] grw [h2, add_tsub_cancel_left] - · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2] + · rw [← revAtFun_eq, revAtFun, ite_eq_right h1, coeff_eq_zero_of_natDegree_lt h2] rw [not_lt] at h2 rw [revAt_le (h2.trans (Nat.le_add_right _ _))] by_cases h3 : p.natTrailingDegree ≤ n - · rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', if_pos h3, - coeff_reverse, revAt_le (tsub_le_self.trans h2)] + · rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', + ite_eq_left h3, coeff_reverse, revAt_le (tsub_le_self.trans h2)] rw [not_le] at h3 rw [coeff_eq_zero_of_natDegree_lt (lt_tsub_iff_right.mpr (Nat.add_lt_add_left h3 _))] exact coeff_eq_zero_of_lt_natTrailingDegree (by rwa [mirror_natTrailingDegree]) diff --git a/Mathlib/Algebra/Polynomial/Monic.lean b/Mathlib/Algebra/Polynomial/Monic.lean index 57ee0de96fefca..a2e166ba801849 100644 --- a/Mathlib/Algebra/Polynomial/Monic.lean +++ b/Mathlib/Algebra/Polynomial/Monic.lean @@ -72,7 +72,7 @@ theorem monic_mul_C_of_leadingCoeff_mul_eq_one {b : R} (hp : p.leadingCoeff * b theorem monic_X_pow_add {n : ℕ} (H : degree p < n) : Monic (X ^ n + p) := monic_of_degree_le n (le_trans (degree_add_le _ _) (max_le (degree_X_pow_le _) (le_of_lt H))) - (by rw [coeff_add, coeff_X_pow, if_pos rfl, coeff_eq_zero_of_degree_lt H, add_zero]) + (by rw [coeff_add, coeff_X_pow, ite_eq_left rfl, coeff_eq_zero_of_degree_lt H, add_zero]) variable (a) in theorem monic_X_pow_add_C {n : ℕ} (h : n ≠ 0) : (X ^ n + C a).Monic := diff --git a/Mathlib/Algebra/Polynomial/Reverse.lean b/Mathlib/Algebra/Polynomial/Reverse.lean index 64628cd5115ff1..625455d4bbec1b 100644 --- a/Mathlib/Algebra/Polynomial/Reverse.lean +++ b/Mathlib/Algebra/Polynomial/Reverse.lean @@ -64,7 +64,7 @@ theorem revAt_invol {N i : ℕ} : (revAt N) (revAt N i) = i := @[simp] theorem revAt_le {N i : ℕ} (H : i ≤ N) : revAt N i = N - i := - if_pos H + ite_eq_left H set_option backward.isDefEq.respectTransparency false in lemma revAt_eq_self_of_lt {N i : ℕ} (h : N < i) : revAt N i = i := by simp [revAt, Nat.not_le.mpr h] @@ -237,7 +237,7 @@ theorem reverse_natDegree_le (f : R[X]) : f.reverse.natDegree ≤ f.natDegree := rw [natDegree_le_iff_degree_le, degree_le_iff_coeff_zero] intro n hn rw [Nat.cast_lt] at hn - rw [coeff_reverse, revAt, Function.Embedding.coeFn_mk, if_neg (not_le_of_gt hn), + rw [coeff_reverse, revAt, Function.Embedding.coeFn_mk, ite_eq_right (not_le_of_gt hn), coeff_eq_zero_of_natDegree_lt hn] theorem natDegree_eq_reverse_natDegree_add_natTrailingDegree (f : R[X]) : diff --git a/Mathlib/Algebra/Polynomial/RingDivision.lean b/Mathlib/Algebra/Polynomial/RingDivision.lean index 04016c3ca5cbc2..74026281f0a1c8 100644 --- a/Mathlib/Algebra/Polynomial/RingDivision.lean +++ b/Mathlib/Algebra/Polynomial/RingDivision.lean @@ -293,9 +293,9 @@ theorem rootMultiplicity_mul {p q : R[X]} {x : R} (hpq : p * q ≠ 0) : classical have hp : p ≠ 0 := left_ne_zero_of_mul hpq have hq : q ≠ 0 := right_ne_zero_of_mul hpq - rw [rootMultiplicity_eq_multiplicity (p * q), if_neg hpq, rootMultiplicity_eq_multiplicity p, - if_neg hp, rootMultiplicity_eq_multiplicity q, if_neg hq, - multiplicity_mul (prime_X_sub_C x) (finiteMultiplicity_X_sub_C _ hpq)] + rw [rootMultiplicity_eq_multiplicity (p * q), ite_eq_right hpq, + rootMultiplicity_eq_multiplicity p, ite_eq_right hp, rootMultiplicity_eq_multiplicity q, + ite_eq_right hq, multiplicity_mul (prime_X_sub_C x) (finiteMultiplicity_X_sub_C _ hpq)] open Multiset in theorem exists_multiset_roots [DecidableEq R] : diff --git a/Mathlib/Algebra/Polynomial/Roots.lean b/Mathlib/Algebra/Polynomial/Roots.lean index d1eebd0d5f4074..27861e580c054f 100644 --- a/Mathlib/Algebra/Polynomial/Roots.lean +++ b/Mathlib/Algebra/Polynomial/Roots.lean @@ -69,12 +69,12 @@ theorem roots_def [DecidableEq R] (p : R[X]) [Decidable (p = 0)] : @[simp] theorem roots_zero : (0 : R[X]).roots = 0 := - dif_pos rfl + dite_eq_left rfl theorem card_roots (hp0 : p ≠ 0) : (Multiset.card (roots p) : WithBot ℕ) ≤ degree p := by classical unfold roots - rw [dif_neg hp0] + rw [dite_eq_right hp0] exact (Classical.choose_spec (exists_multiset_roots hp0)).1 theorem card_roots' (p : R[X]) : Multiset.card p.roots ≤ natDegree p := by @@ -99,7 +99,7 @@ theorem card_roots_sub_C' {p : R[X]} {a : R} (hp0 : 0 < degree p) : theorem count_roots [DecidableEq R] (p : R[X]) : p.roots.count a = rootMultiplicity a p := by by_cases hp : p = 0 · simp [hp] - rw [roots_def, dif_neg hp] + rw [roots_def, dite_eq_right hp] exact (Classical.choose_spec (exists_multiset_roots hp)).2 a @[simp] diff --git a/Mathlib/Algebra/Polynomial/RuleOfSigns.lean b/Mathlib/Algebra/Polynomial/RuleOfSigns.lean index 7cddfd744d4758..e8023d50f34e02 100644 --- a/Mathlib/Algebra/Polynomial/RuleOfSigns.lean +++ b/Mathlib/Algebra/Polynomial/RuleOfSigns.lean @@ -101,7 +101,7 @@ theorem signVariations_eq_eraseLead_add_ite {P : Polynomial R} (h : P ≠ 0) : grind by_cases h₄ : SignType.sign P.leadingCoeff = SignType.sign P.eraseLead.leadingCoeff · grind [SignType.neg_eq_self_iff] - rw [if_pos h₄, if_pos ?_] + rw [ite_eq_left h₄, ite_eq_left ?_] · grind [Nat.sub_add_cancel, List.length_pos_of_ne_nil, List.destutter'_ne_nil] cases _ : SignType.sign P.leadingCoeff <;> cases _ : SignType.sign P.eraseLead.leadingCoeff diff --git a/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean b/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean index 3dfbf95ffe2ba2..b10926ef147184 100644 --- a/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean +++ b/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean @@ -216,7 +216,7 @@ theorem aeval_sumIDeriv_of_pos [Nontrivial A] [NoZeroDivisors A] (p : R[X]) {q : · exact (aeval_iterate_derivative_of_ge A p q h).choose_spec.1 · rw [natDegree_zero]; exact Nat.zero_le _ have hc (k) (hk : q ≤ k) : ∀ (r : A), aeval r (derivative^[k] p) = q ! • aeval r (c k) := by - simp_rw [c, dif_pos hk] + simp_rw [c, dite_eq_left hk] exact (aeval_iterate_derivative_of_ge A p q hk).choose_spec.2 refine ⟨∑ x ∈ Ico q (p.natDegree + 1), c x, ?_, ?_⟩ · refine (natDegree_sum_le _ _).trans ?_ diff --git a/Mathlib/Algebra/Polynomial/UnitTrinomial.lean b/Mathlib/Algebra/Polynomial/UnitTrinomial.lean index 0dd4ccbb155194..fb08b9a744563e 100644 --- a/Mathlib/Algebra/Polynomial/UnitTrinomial.lean +++ b/Mathlib/Algebra/Polynomial/UnitTrinomial.lean @@ -51,17 +51,17 @@ variable {k m n u v w} theorem trinomial_leading_coeff' (hkm : k < m) (hmn : m < n) : (trinomial k m n u v w).coeff n = w := by rw [trinomial_def, coeff_add, coeff_add, coeff_C_mul_X_pow, coeff_C_mul_X_pow, coeff_C_mul_X_pow, - if_neg (hkm.trans hmn).ne', if_neg hmn.ne', if_pos rfl, zero_add, zero_add] + ite_eq_right (hkm.trans hmn).ne', ite_eq_right hmn.ne', ite_eq_left rfl, zero_add, zero_add] theorem trinomial_middle_coeff (hkm : k < m) (hmn : m < n) : (trinomial k m n u v w).coeff m = v := by rw [trinomial_def, coeff_add, coeff_add, coeff_C_mul_X_pow, coeff_C_mul_X_pow, coeff_C_mul_X_pow, - if_neg hkm.ne', if_pos rfl, if_neg hmn.ne, zero_add, add_zero] + ite_eq_right hkm.ne', ite_eq_left rfl, ite_eq_right hmn.ne, zero_add, add_zero] theorem trinomial_trailing_coeff' (hkm : k < m) (hmn : m < n) : (trinomial k m n u v w).coeff k = u := by rw [trinomial_def, coeff_add, coeff_add, coeff_C_mul_X_pow, coeff_C_mul_X_pow, coeff_C_mul_X_pow, - if_pos rfl, if_neg hkm.ne, if_neg (hkm.trans hmn).ne, add_zero, add_zero] + ite_eq_left rfl, ite_eq_right hkm.ne, ite_eq_right (hkm.trans hmn).ne, add_zero, add_zero] theorem trinomial_natDegree (hkm : k < m) (hmn : m < n) (hw : w ≠ 0) : (trinomial k m n u v w).natDegree = n := by @@ -169,9 +169,9 @@ theorem isUnitTrinomial_iff : replace hy := hp.2 m (mem_insert_of_mem (mem_insert_self m {n})) replace hz := hp.2 n (mem_insert_of_mem (mem_insert_of_mem (mem_singleton_self n))) simp_rw [coeff_add, coeff_C_mul, coeff_X_pow_self, mul_one, coeff_X_pow] at hx hy hz - rw [if_neg hkm.ne, if_neg (hkm.trans hmn).ne] at hx - rw [if_neg hkm.ne', if_neg hmn.ne] at hy - rw [if_neg (hkm.trans hmn).ne', if_neg hmn.ne'] at hz + rw [ite_eq_right hkm.ne, ite_eq_right (hkm.trans hmn).ne] at hx + rw [ite_eq_right hkm.ne', ite_eq_right hmn.ne] at hy + rw [ite_eq_right (hkm.trans hmn).ne', ite_eq_right hmn.ne'] at hz simp_rw [mul_zero, zero_add, add_zero] at hx hy hz exact ⟨k, m, n, hkm, hmn, hx.unit, hy.unit, hz.unit, rfl⟩ diff --git a/Mathlib/Algebra/Ring/Parity.lean b/Mathlib/Algebra/Ring/Parity.lean index 8672c229f5f79c..e71f001ab82f92 100644 --- a/Mathlib/Algebra/Ring/Parity.lean +++ b/Mathlib/Algebra/Ring/Parity.lean @@ -388,8 +388,8 @@ variable {R : Type*} [Monoid R] [HasDistribNeg R] {m n : ℕ} lemma neg_one_pow_eq_ite : (-1 : R) ^ n = if Even n then 1 else (-1) := by cases even_or_odd n with - | inl h => rw [h.neg_one_pow, if_pos h] - | inr h => rw [h.neg_one_pow, if_neg (by simpa using h)] + | inl h => rw [h.neg_one_pow, ite_eq_left h] + | inr h => rw [h.neg_one_pow, ite_eq_right (by simpa using h)] lemma neg_one_pow_congr (h : Even m ↔ Even n) : (-1 : R) ^ m = (-1) ^ n := by simp [h, neg_one_pow_eq_ite] diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean index 7f4a52f2127137..c6b3d05e9e6f1a 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Single.lean @@ -107,13 +107,13 @@ theorem coeff_update_apply [DecidableEq α] : @[deprecated Finsupp.update_apply (since := "2026-07-04")] theorem coeff_update_same : (f.update a b).coeff a = b := by classical - rw [f.coeff_update_apply, if_pos rfl] + rw [f.coeff_update_apply, ite_eq_left rfl] variable {a a'} in @[deprecated Finsupp.update_apply (since := "2026-07-04")] theorem coeff_update_ne (h : a' ≠ a) : (f.update a b).coeff a' = f.coeff a' := by classical - rw [f.coeff_update_apply, if_neg h] + rw [f.coeff_update_apply, ite_eq_right h] theorem update_eq_erase_add_single : f.update a b = f.erase a + single a b := by classical ext x; by_cases hx : x = a <;> aesop (add norm coeff_single_apply) diff --git a/Mathlib/Algebra/SkewPolynomial/Basic.lean b/Mathlib/Algebra/SkewPolynomial/Basic.lean index ff0d4f73937d07..b7695f2d80b6d6 100644 --- a/Mathlib/Algebra/SkewPolynomial/Basic.lean +++ b/Mathlib/Algebra/SkewPolynomial/Basic.lean @@ -364,14 +364,14 @@ lemma coeff_one [MulSemiringAction (Multiplicative ℕ) R] (n : ℕ) : lemma coeff_X : coeff (X : SkewPolynomial R) n = if 1 = n then 1 else 0 := coeff_monomial lemma coeff_X_of_ne_one {n : ℕ} (hn : n ≠ 1) : coeff (X : SkewPolynomial R) n = 0 := by - rw [coeff_X, if_neg hn.symm] + rw [coeff_X, ite_eq_right hn.symm] lemma coeff_C : coeff (C a) n = ite (n = 0) a 0 := by convert! coeff_monomial using 2; simp [eq_comm] @[simp] lemma coeff_C_zero : coeff (C a) 0 = a := coeff_monomial -lemma coeff_C_ne_zero (h : n ≠ 0) : (C a).coeff n = 0 := by rw [coeff_C, if_neg h] +lemma coeff_C_ne_zero (h : n ≠ 0) : (C a).coeff n = 0 := by rw [coeff_C, ite_eq_right h] @[simp] lemma coeff_C_succ {r : R} {n : ℕ} : coeff (C r) (n + 1) = 0 := by simp [coeff_C] @@ -710,11 +710,11 @@ lemma coeff_update_apply (p : SkewPolynomial R) (n : ℕ) (a : R) (i : ℕ) : @[deprecated coeff_update (since := "2026-07-06")] lemma coeff_update_same (p : SkewPolynomial R) (n : ℕ) (a : R) : (p.update n a).coeff n = a := by - rw [p.coeff_update_apply, if_pos rfl] + rw [p.coeff_update_apply, ite_eq_left rfl] @[deprecated coeff_update (since := "2026-07-06")] lemma coeff_update_ne (p : SkewPolynomial R) {n i : ℕ} (a : R) (h : i ≠ n) : - (p.update n a).coeff i = p.coeff i := by rw [p.coeff_update_apply, if_neg h] + (p.update n a).coeff i = p.coeff i := by rw [p.coeff_update_apply, ite_eq_right h] @[simp] lemma update_zero_eq_erase (p : SkewPolynomial R) (n : ℕ) : p.update n 0 = p.erase n := by @@ -730,7 +730,7 @@ lemma support_update_zero (p : SkewPolynomial R) (n : ℕ) : simp lemma support_update_ne_zero (p : SkewPolynomial R) (n : ℕ) {a : R} (ha : a ≠ 0) : - support (p.update n a) = insert n p.support := by classical rw [support_update, if_neg ha] + support (p.update n a) = insert n p.support := by classical rw [support_update, ite_eq_right ha] end update diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean index b5bc73430cc2fc..d5806774096d44 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Formula.lean @@ -180,7 +180,7 @@ def slope (x₁ x₂ y₁ y₂ : F) : F := @[simp] lemma slope_of_Y_eq {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ = W.negY x₂ y₂) : W.slope x₁ x₂ y₁ y₂ = 0 := by - rw [slope, if_pos hx, if_pos hy] + rw [slope, ite_eq_left hx, ite_eq_left hy] @[simp] lemma slope_of_Y_ne' {x₂ y₁ y₂ : F} (hy : ¬y₁ = -y₂ - W.a₁ * x₂ - W.a₃) : @@ -196,7 +196,7 @@ lemma slope_of_Y_ne {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ @[simp] lemma slope_of_X_ne {x₁ x₂ y₁ y₂ : F} (hx : x₁ ≠ x₂) : W.slope x₁ x₂ y₁ y₂ = (y₁ - y₂) / (x₁ - x₂) := by - rw [slope, if_neg hx] + rw [slope, ite_eq_right hx] lemma slope_of_Y_ne_eq_evalEval {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) : W.slope x₁ x₂ y₁ y₂ = -W.polynomialX.evalEval x₁ y₁ / W.polynomialY.evalEval x₁ y₁ := by diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean index 3c2431076352ca..31a41236982d64 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine/Point.lean @@ -123,7 +123,7 @@ lemma basis_apply (n : Fin 2) : CoordinateRing.basis W' n = (AdjoinRoot.powerBasis' monic_polynomial).gen ^ (n : ℕ) := by classical nontriviality R - rw [CoordinateRing.basis, Or.by_cases, dif_neg <| not_subsingleton R, Basis.reindex_apply, + rw [CoordinateRing.basis, Or.by_cases, dite_eq_right <| not_subsingleton R, Basis.reindex_apply, PowerBasis.basis_eq_pow, finCongr_symm_apply, Fin.val_cast] @[simp] @@ -412,7 +412,7 @@ lemma norm_smul_basis (p q : R[X]) : Algebra.norm R[X] (p • (1 : W'.Coordinate simp_rw [Algebra.norm_eq_matrix_det <| CoordinateRing.basis W', Matrix.det_fin_two, Algebra.leftMulMatrix_eq_repr_mul, basis_zero, mul_one, basis_one, smul_basis_mul_Y, map_add, Finsupp.add_apply, map_smul, Finsupp.smul_apply, ← basis_zero, ← basis_one, - Basis.repr_self_apply, if_pos, one_ne_zero, if_false, smul_eq_mul] + Basis.repr_self_apply, ite_eq_left, one_ne_zero, ite_false, smul_eq_mul] ring1 lemma coe_norm_smul_basis (p q : R[X]) : Algebra.norm R[X] (p • 1 + q • mk W' Y) = @@ -677,12 +677,12 @@ lemma add_def (P Q : W.Point) : P + Q = P.add Q := lemma add_some {x₁ x₂ y₁ y₂ : F} (hxy : ¬(x₁ = x₂ ∧ y₁ = W.negY x₂ y₂)) {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂} : some _ _ h₁ + some _ _ h₂ = some _ _ (nonsingular_add h₁ h₂ hxy) := by - simp only [add_def, add, dif_neg hxy] + simp only [add_def, add, dite_eq_right hxy] @[simp] lemma add_of_Y_eq {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂} (hx : x₁ = x₂) (hy : y₁ = W.negY x₂ y₂) : some _ _ h₁ + some _ _ h₂ = 0 := by - simpa only [add_def, add] using dif_pos ⟨hx, hy⟩ + simpa only [add_def, add] using dite_eq_left ⟨hx, hy⟩ -- Removing `@[simp]`, because `hy` causes a maximum recursion depth error in the simpNF linter. lemma add_self_of_Y_eq {x₁ y₁ : F} {h₁ : W.Nonsingular x₁ y₁} (hy : y₁ = W.negY x₁ y₁) : diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Basic.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Basic.lean index d05f0853bf59f2..0c9bc6b68af726 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Basic.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Basic.lean @@ -273,12 +273,12 @@ lemma ΨSq_neg (n : ℤ) : W.ΨSq (-n) = W.ΨSq n := by lemma ΨSq_even (m : ℤ) : W.ΨSq (2 * m) = (W.preΨ (m - 1) ^ 2 * W.preΨ m * W.preΨ (m + 2) - W.preΨ (m - 2) * W.preΨ m * W.preΨ (m + 1) ^ 2) ^ 2 * W.Ψ₂Sq := by - rw [ΨSq, preΨ_even, if_pos <| even_two_mul m] + rw [ΨSq, preΨ_even, ite_eq_left <| even_two_mul m] lemma ΨSq_odd (m : ℤ) : W.ΨSq (2 * m + 1) = (W.preΨ (m + 2) * W.preΨ m ^ 3 * (if Even m then W.Ψ₂Sq ^ 2 else 1) - W.preΨ (m - 1) * W.preΨ (m + 1) ^ 3 * (if Even m then 1 else W.Ψ₂Sq ^ 2)) ^ 2 := by - rw [ΨSq, preΨ_odd, if_neg m.not_even_two_mul_add_one, mul_one] + rw [ΨSq, preΨ_odd, ite_eq_right m.not_even_two_mul_add_one, mul_one] end ΨSq @@ -322,8 +322,8 @@ lemma Ψ_neg (n : ℤ) : W.Ψ (-n) = -W.Ψ n := by lemma Ψ_even (m : ℤ) : W.Ψ (2 * m) * W.ψ₂ = W.Ψ (m - 1) ^ 2 * W.Ψ m * W.Ψ (m + 2) - W.Ψ (m - 2) * W.Ψ m * W.Ψ (m + 1) ^ 2 := by - simp_rw [Ψ, preΨ_even, if_pos <| even_two_mul m, Int.even_add, Int.even_sub, even_two, iff_true, - Int.not_even_one, iff_false] + simp_rw [Ψ, preΨ_even, ite_eq_left <| even_two_mul m, Int.even_add, Int.even_sub, even_two, + iff_true, Int.not_even_one, iff_false] split_ifs <;> C_simp <;> ring1 lemma Ψ_odd (m : ℤ) : W.Ψ (2 * m + 1) = @@ -331,8 +331,8 @@ lemma Ψ_odd (m : ℤ) : W.Ψ (2 * m + 1) = W.toAffine.polynomial * (16 * W.toAffine.polynomial - 8 * W.ψ₂ ^ 2) * C (if Even m then W.preΨ (m + 2) * W.preΨ m ^ 3 else -W.preΨ (m - 1) * W.preΨ (m + 1) ^ 3) := by - simp_rw [Ψ, preΨ_odd, if_neg m.not_even_two_mul_add_one, Int.even_add, Int.even_sub, even_two, - iff_true, Int.not_even_one, iff_false] + simp_rw [Ψ, preΨ_odd, ite_eq_right m.not_even_two_mul_add_one, Int.even_add, Int.even_sub, + even_two, iff_true, Int.not_even_one, iff_false] split_ifs <;> C_simp <;> rw [C_Ψ₂Sq] <;> ring1 lemma Affine.CoordinateRing.mk_Ψ_sq (n : ℤ) : mk W (W.Ψ n) ^ 2 = mk W (C <| W.ΨSq n) := by @@ -369,21 +369,21 @@ lemma Φ_one : W.Φ 1 = X := by @[simp] lemma Φ_two : W.Φ 2 = X ^ 4 - C W.b₄ * X ^ 2 - C (2 * W.b₆) * X - C W.b₈ := by - rw [show 2 = ((1 : ℕ) + 1 : ℤ) by rfl, Φ_ofNat, preΨ'_two, if_neg Nat.not_even_one, Ψ₂Sq, - preΨ'_three, preΨ'_one, if_neg Nat.not_even_one, Ψ₃] + rw [show 2 = ((1 : ℕ) + 1 : ℤ) by rfl, Φ_ofNat, preΨ'_two, ite_eq_right Nat.not_even_one, Ψ₂Sq, + preΨ'_three, preΨ'_one, ite_eq_right Nat.not_even_one, Ψ₃] C_simp ring1 @[simp] lemma Φ_three : W.Φ 3 = X * W.Ψ₃ ^ 2 - W.preΨ₄ * W.Ψ₂Sq := by - rw [show 3 = ((2 : ℕ) + 1 : ℤ) by rfl, Φ_ofNat, preΨ'_three, if_pos <| by decide, mul_one, - preΨ'_four, preΨ'_two, mul_one, if_pos even_two] + rw [show 3 = ((2 : ℕ) + 1 : ℤ) by rfl, Φ_ofNat, preΨ'_three, ite_eq_left <| by decide, mul_one, + preΨ'_four, preΨ'_two, mul_one, ite_eq_left even_two] @[simp] lemma Φ_four : W.Φ 4 = X * W.preΨ₄ ^ 2 * W.Ψ₂Sq - W.Ψ₃ * (W.preΨ₄ * W.Ψ₂Sq ^ 2 - W.Ψ₃ ^ 3) := by - rw [show 4 = ((3 : ℕ) + 1 : ℤ) by rfl, Φ_ofNat, preΨ'_four, if_neg <| by decide, - show 3 + 2 = 2 * 2 + 1 by rfl, preΨ'_odd, preΨ'_four, preΨ'_two, if_pos Even.zero, preΨ'_one, - preΨ'_three, if_pos Even.zero, if_neg <| by decide] + rw [show 4 = ((3 : ℕ) + 1 : ℤ) by rfl, Φ_ofNat, preΨ'_four, ite_eq_right <| by decide, + show 3 + 2 = 2 * 2 + 1 by rfl, preΨ'_odd, preΨ'_four, preΨ'_two, ite_eq_left Even.zero, + preΨ'_one, preΨ'_three, ite_eq_left Even.zero, ite_eq_right <| by decide] ring1 @[simp] diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Degree.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Degree.lean index b5a1d91271235e..633b8e49f95668 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Degree.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/DivisionPolynomial/Degree.lean @@ -242,9 +242,9 @@ lemma coeff_preΨ' (n : ℕ) : (W.preΨ' n).coeff ((n ^ 2 - if Even n then 4 els lemma coeff_preΨ'_ne_zero {n : ℕ} (h : (n : R) ≠ 0) : (W.preΨ' n).coeff ((n ^ 2 - if Even n then 4 else 1) / 2) ≠ 0 := by rcases n.even_or_odd' with ⟨n, rfl | rfl⟩ - · rw [coeff_preΨ', if_pos <| even_two_mul n, n.mul_div_cancel_left two_pos] + · rw [coeff_preΨ', ite_eq_left <| even_two_mul n, n.mul_div_cancel_left two_pos] exact right_ne_zero_of_mul <| by rwa [← Nat.cast_mul] - · rwa [coeff_preΨ', if_neg n.not_even_two_mul_add_one] + · rwa [coeff_preΨ', ite_eq_right n.not_even_two_mul_add_one] @[simp] lemma natDegree_preΨ' {n : ℕ} (h : (n : R) ≠ 0) : diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Point.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Point.lean index 982090c35d0dd6..700a6ef537038d 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Point.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian/Point.lean @@ -195,7 +195,7 @@ noncomputable def add (P Q : Fin 3 → R) : Fin 3 → R := if P ≈ Q then W'.dblXYZ P else W'.addXYZ P Q lemma add_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.add P Q = W'.dblXYZ P := - if_pos h + ite_eq_left h lemma add_smul_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) {u v : R} (hu : IsUnit u) (hv : IsUnit v) : W'.add (u • P) (v • Q) = u ^ 4 • W'.add P Q := by @@ -208,7 +208,7 @@ lemma add_of_eq {P Q : Fin 3 → R} (h : P = Q) : W'.add P Q = W'.dblXYZ P := h ▸ add_self P lemma add_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) : W'.add P Q = W'.addXYZ P Q := - if_neg h + ite_eq_right h lemma add_smul_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) {u v : R} (hu : IsUnit u) (hv : IsUnit v) : W'.add (u • P) (v • Q) = (u * v) ^ 2 • W'.add P Q := by @@ -449,17 +449,17 @@ noncomputable def toAffine (P : Fin 3 → F) : W.toAffine.Point := if hP : W.Nonsingular P ∧ P z ≠ 0 then .some _ _ <| (nonsingular_of_Z_ne_zero hP.2).mp hP.1 else 0 lemma toAffine_of_singular {P : Fin 3 → F} (hP : ¬W.Nonsingular P) : toAffine W P = 0 := by - rw [toAffine, dif_neg <| not_and_of_not_left _ hP] + rw [toAffine, dite_eq_right <| not_and_of_not_left _ hP] lemma toAffine_of_Z_eq_zero {P : Fin 3 → F} (hPz : P z = 0) : toAffine W P = 0 := by - rw [toAffine, dif_neg <| not_and_not_right.mpr fun _ => hPz] + rw [toAffine, dite_eq_right <| not_and_not_right.mpr fun _ => hPz] lemma toAffine_zero : toAffine W ![1, 1, 0] = 0 := toAffine_of_Z_eq_zero rfl lemma toAffine_of_Z_ne_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) : toAffine W P = .some _ _ ((nonsingular_of_Z_ne_zero hPz).mp hP) := by - rw [toAffine, dif_pos ⟨hP, hPz⟩] + rw [toAffine, dite_eq_left ⟨hP, hPz⟩] lemma toAffine_some {X Y : F} (h : W.Nonsingular ![X, Y, 1]) : toAffine W ![X, Y, 1] = .some _ _ ((nonsingular_some ..).mp h) := by diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/ModelsWithJ.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/ModelsWithJ.lean index 2853054fa8f308..13eeae718fcd47 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/ModelsWithJ.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/ModelsWithJ.lean @@ -136,29 +136,30 @@ def ofJ : WeierstrassCurve F := else if j = 1728 then ofJ1728 F else ofJNe0Or1728 j lemma ofJ_0_of_three_ne_zero (h3 : (3 : F) ≠ 0) : ofJ 0 = ofJ0 F := by - rw [ofJ, if_pos rfl, if_neg h3] + rw [ofJ, ite_eq_left rfl, ite_eq_right h3] lemma ofJ_0_of_three_eq_zero (h3 : (3 : F) = 0) : ofJ 0 = ofJ1728 F := by - rw [ofJ, if_pos rfl, if_pos h3] + rw [ofJ, ite_eq_left rfl, ite_eq_left h3] lemma ofJ_0_of_two_eq_zero (h2 : (2 : F) = 0) : ofJ 0 = ofJ0 F := by - rw [ofJ, if_pos rfl, if_neg ((show (3 : F) = 1 by linear_combination h2) ▸ one_ne_zero)] + rw [ofJ, ite_eq_left rfl, + ite_eq_right ((show (3 : F) = 1 by linear_combination h2) ▸ one_ne_zero)] lemma ofJ_1728_of_three_eq_zero (h3 : (3 : F) = 0) : ofJ 1728 = ofJ1728 F := by - rw [ofJ, if_pos (by linear_combination 576 * h3), if_pos h3] + rw [ofJ, ite_eq_left (by linear_combination 576 * h3), ite_eq_left h3] lemma ofJ_1728_of_two_ne_zero (h2 : (2 : F) ≠ 0) : ofJ 1728 = ofJ1728 F := by by_cases h3 : (3 : F) = 0 · exact ofJ_1728_of_three_eq_zero h3 · rw [ofJ, show (1728 : F) = 2 ^ 6 * 3 ^ 3 by norm_num1, - if_neg (mul_ne_zero (pow_ne_zero 6 h2) (pow_ne_zero 3 h3)), if_pos rfl] + ite_eq_right (mul_ne_zero (pow_ne_zero 6 h2) (pow_ne_zero 3 h3)), ite_eq_left rfl] lemma ofJ_1728_of_two_eq_zero (h2 : (2 : F) = 0) : ofJ 1728 = ofJ0 F := by - rw [ofJ, if_pos (by linear_combination 864 * h2), - if_neg ((show (3 : F) = 1 by linear_combination h2) ▸ one_ne_zero)] + rw [ofJ, ite_eq_left (by linear_combination 864 * h2), + ite_eq_right ((show (3 : F) = 1 by linear_combination h2) ▸ one_ne_zero)] lemma ofJ_ne_0_ne_1728 (h0 : j ≠ 0) (h1728 : j ≠ 1728) : ofJ j = ofJNe0Or1728 j := by - rw [ofJ, if_neg h0, if_neg h1728] + rw [ofJ, ite_eq_right h0, ite_eq_right h1728] instance : (ofJ j).IsElliptic := by by_cases h0 : j = 0 diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean index 8187a52e0f7046..07054e09ffb71b 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean @@ -685,10 +685,10 @@ def toCharTwoNF [DecidableEq F] : VariableChange F := instance toCharTwoNF_spec [DecidableEq F] : (W.toCharTwoNF • W).IsCharTwoNF := by by_cases ha₁ : W.a₁ = 0 - · rw [toCharTwoNF, dif_pos ha₁] + · rw [toCharTwoNF, dite_eq_left ha₁] have := W.toCharTwoJEqZeroNF_spec ha₁ infer_instance - · rw [toCharTwoNF, dif_neg ha₁] + · rw [toCharTwoNF, dite_eq_right ha₁] have := W.toCharTwoJNeZeroNF_spec ha₁ infer_instance diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Point.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Point.lean index 63fa36b4e69b3b..bdff5e56c91360 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Point.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Projective/Point.lean @@ -183,7 +183,7 @@ noncomputable def add (P Q : Fin 3 → R) : Fin 3 → R := if P ≈ Q then W'.dblXYZ P else W'.addXYZ P Q lemma add_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.add P Q = W'.dblXYZ P := - if_pos h + ite_eq_left h lemma add_smul_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) {u v : R} (hu : IsUnit u) (hv : IsUnit v) : W'.add (u • P) (v • Q) = u ^ 4 • W'.add P Q := by @@ -196,7 +196,7 @@ lemma add_of_eq {P Q : Fin 3 → R} (h : P = Q) : W'.add P Q = W'.dblXYZ P := h ▸ add_self P lemma add_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) : W'.add P Q = W'.addXYZ P Q := - if_neg h + ite_eq_right h lemma add_smul_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) {u v : R} (hu : IsUnit u) (hv : IsUnit v) : W'.add (u • P) (v • Q) = (u * v) ^ 2 • W'.add P Q := by @@ -433,17 +433,17 @@ noncomputable def toAffine (P : Fin 3 → F) : W.toAffine.Point := if hP : W.Nonsingular P ∧ P z ≠ 0 then .some _ _ <| (nonsingular_of_Z_ne_zero hP.2).mp hP.1 else 0 lemma toAffine_of_singular {P : Fin 3 → F} (hP : ¬W.Nonsingular P) : toAffine W P = 0 := by - rw [toAffine, dif_neg <| not_and_of_not_left _ hP] + rw [toAffine, dite_eq_right <| not_and_of_not_left _ hP] lemma toAffine_of_Z_eq_zero {P : Fin 3 → F} (hPz : P z = 0) : toAffine W P = 0 := by - rw [toAffine, dif_neg <| not_and_not_right.mpr fun _ => hPz] + rw [toAffine, dite_eq_right <| not_and_not_right.mpr fun _ => hPz] lemma toAffine_zero : toAffine W ![0, 1, 0] = 0 := toAffine_of_Z_eq_zero rfl lemma toAffine_of_Z_ne_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) : toAffine W P = .some _ _ ((nonsingular_of_Z_ne_zero hPz).mp hP) := by - rw [toAffine, dif_pos ⟨hP, hPz⟩] + rw [toAffine, dite_eq_left ⟨hP, hPz⟩] lemma toAffine_some {X Y : F} (h : W.Nonsingular ![X, Y, 1]) : toAffine W ![X, Y, 1] = .some _ _ ((nonsingular_some ..).mp h) := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean index 0f95fcba4fad0f..d1c1232c42ae5d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean @@ -241,7 +241,7 @@ lemma isIso_pushoutSection_iff : set_option backward.defeqAttrib.useBackward true in attribute [local simp] IsAffineOpen.isoSpec_hom in -attribute [local simp← ] Scheme.Hom.resLE_eq_morphismRestrict in +attribute [local simp ←] Scheme.Hom.resLE_eq_morphismRestrict in lemma isIso_pushoutSection_of_isAffineOpen (hUS : IsAffineOpen US) (hUT : IsAffineOpen UT) (hUX : IsAffineOpen UX) : IsIso (pushoutSection H hUST hUSX hUY) := by refine (isIso_pushoutSection_iff ..).mpr (IsPullback.of_map_of_faithful Scheme.Spec ?_).unop diff --git a/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean b/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean index 3fb564c22a695d..fc8bac455be941 100644 --- a/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean +++ b/Mathlib/AlgebraicGeometry/OrderOfVanishing.lean @@ -55,11 +55,11 @@ def ord (f : X.functionField) (z : X) : ℤ := else 0 lemma ord_eq_ordHom_of_coheight_eq_one {z : X} (hz : coheight z = 1) (f : X.functionField) : - ord f z = Multiplicative.toAdd ((X.ordHom z hz f).unzeroD 1) := dif_pos hz + ord f z = Multiplicative.toAdd ((X.ordHom z hz f).unzeroD 1) := dite_eq_left hz @[simp] lemma ord_eq_zero_of_coheight_neq_one {z : X} (hz : coheight z ≠ 1) (f : X.functionField) : - ord f z = 0 := dif_neg hz + ord f z = 0 := dite_eq_right hz @[simp] lemma ord_zero : ord (0 : X.functionField) = 0 := by diff --git a/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean index cffd8bd19436ea..60be325f72949b 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/FunctorGamma.lean @@ -99,12 +99,12 @@ def mapMono (K : ChainComplex C ℕ) {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) variable (Δ) in theorem mapMono_id : mapMono K (𝟙 Δ) = 𝟙 _ := by unfold mapMono - simp only [eqToHom_refl, dite_eq_ite, if_true] + simp only [eqToHom_refl, dite_eq_ite, ite_true] theorem mapMono_δ₀' (i : Δ' ⟶ Δ) [Mono i] (hi : Isδ₀ i) : mapMono K i = K.d Δ.len Δ'.len := by unfold mapMono suffices Δ ≠ Δ' by - simp only [dif_neg this, dif_pos hi] + simp only [dite_eq_right this, dite_eq_left hi] rintro rfl simpa only [left_eq_add, Nat.one_ne_zero] using hi.1 diff --git a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean index c3e2fbbed0b211..08b57acd0c5df6 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean @@ -53,7 +53,7 @@ set_option backward.isDefEq.respectTransparency false in theorem cofan_inj_πSummand_eq_zero [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A B : IndexSet Δ) (h : B ≠ A) : (s.cofan Δ).inj A ≫ s.πSummand B = 0 := by dsimp [πSummand] - rw [ι_desc, dif_neg h.symm] + rw [ι_desc, dite_eq_right h.symm] variable [Preadditive C] diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean b/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean index 0d4397d323b424..1fe383ffeb63c5 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/DeltaZeroIter.lean @@ -124,14 +124,14 @@ def σ₀Iter (i : ℕ) {n m : ℕ} (hi : n + i = m := by lia) : ⦋m⦌ ⟶ ⦋ lemma σ₀Iter_coe_eq_of_lt (i : ℕ) {n m : ℕ} (j : Fin (m + 1)) (hi : n + i = m := by lia) (hj : j.val < i := by grind) : dsimp% (σ₀Iter i hi j).val = 0 := by - simp [σ₀Iter, Hom.mk, ConcreteCategory.hom, Hom.toOrderHom, if_pos hj] + simp [σ₀Iter, Hom.mk, ConcreteCategory.hom, Hom.toOrderHom, ite_eq_left hj] set_option backward.isDefEq.respectTransparency.types false in lemma σ₀Iter_coe_eq_of_ge (i : ℕ) {n m : ℕ} (j : Fin (m + 1)) (hi : n + i = m := by lia) (hj : i ≤ j.val := by grind) : dsimp% (σ₀Iter i hi j).val = j.val - i := by dsimp [σ₀Iter, Hom.mk, ConcreteCategory.hom, Hom.toOrderHom] - rw [if_neg (by lia)] + rw [ite_eq_right (by lia)] lemma σ₀Iter_coe_eq_of_le (i : ℕ) {n m : ℕ} (j : Fin (m + 1)) (hi : n + i = m := by lia) (hj : j.val ≤ i := by grind) : diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/ToMkOne.lean b/Mathlib/AlgebraicTopology/SimplexCategory/ToMkOne.lean index 33c05e69edb54c..a8d64dc2d1ea0f 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/ToMkOne.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/ToMkOne.lean @@ -123,7 +123,7 @@ lemma toMk₁_injective {n : ℕ} : Function.Injective (toMk₁ (n := n)) := by wlog hij : i < j generalizing i j · grind have := ConcreteCategory.congr_hom h ⟨i.1, lt_of_lt_of_le hij (by dsimp; lia)⟩ - simp [toMk₁_apply, if_pos hij] at this + simp [toMk₁_apply, ite_eq_left hij] at this lemma toMk₁_surjective {n : ℕ} : Function.Surjective (toMk₁ (n := n)) := by intro f @@ -151,7 +151,7 @@ lemma toMk₁_surjective {n : ℕ} : Function.Surjective (toMk₁ (n := n)) := b grind · refine ⟨Fin.last _, ConcreteCategory.hom_ext _ _ (fun i ↦ ?_)⟩ dsimp [toMk₁_apply] - rw [if_pos (by simp)] + rw [ite_eq_left (by simp)] obtain ⟨j, hj⟩ : ∃ (j : Fin 2), f i = j := ⟨_, rfl⟩ fin_cases j · #adaptation_note /-- Before https://github.com/leanprover/lean4/pull/13166 diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/ChainHomotopy.lean b/Mathlib/AlgebraicTopology/SimplicialObject/ChainHomotopy.lean index 1e648008611d9e..4d29797fdad97d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/ChainHomotopy.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/ChainHomotopy.lean @@ -49,7 +49,7 @@ lemma hom_eq (p : ℕ) : @[simp] lemma hom_eq_zero (p q : ℕ) (hpq : p + 1 ≠ q) : hom H p q = 0 := - dif_neg hpq + dite_eq_right hpq private lemma comm_zero : letI d : Y _⦋1⦌ ⟶ Y _⦋0⦌ := ((alternatingFaceMapComplex C).obj Y).d 1 0 diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean index b394809fc33e3d..791c67365796d4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/UnionProd.lean @@ -325,7 +325,7 @@ lemma φ_succAbove (i : Fin (d + 1)) : lemma φ_of_ne (i : Fin (d + 2)) (hi : i ≠ (min x hd).castSucc) : φ x hd i = objEquiv (x.cast hd).simplex ((min x hd).predAbove i) := - if_neg hi + ite_eq_right hi lemma φ_of_lt (i : Fin (d + 2)) (hi : i < (min x hd).castSucc) : φ x hd i = objEquiv (x.cast hd).simplex (i.castPred (by grind)) := by @@ -689,7 +689,7 @@ noncomputable def pairing {m : ℕ} (k : Fin (m + 2)) (n : ℕ) : lemma pairing_castSucc {m : ℕ} (k : Fin (m + 1)) (n : ℕ) : pairing.{u} k.castSucc n = (pairingCore.{u} k n).pairing := - dif_neg (by grind) + dite_eq_right (by grind) set_option backward.isDefEq.respectTransparency.types false in instance {m : ℕ} (k : Fin (m + 2)) (n : ℕ) : @@ -697,7 +697,7 @@ instance {m : ℕ} (k : Fin (m + 2)) (n : ℕ) : by_cases! hk : k = Fin.last (m + 1) · subst hk dsimp only [pairing] - rw [dif_pos rfl] + rw [dite_eq_left rfl] infer_instance · obtain ⟨k, rfl⟩ := Fin.eq_castSucc_of_ne_last hk rw [pairing_castSucc] diff --git a/Mathlib/Analysis/Analytic/Binomial.lean b/Mathlib/Analysis/Analytic/Binomial.lean index eae8dcd5478068..fde95f8f3d29f9 100644 --- a/Mathlib/Analysis/Analytic/Binomial.lean +++ b/Mathlib/Analysis/Analytic/Binomial.lean @@ -229,7 +229,7 @@ end Complex namespace Real -attribute [local simp← ] Complex.ofReal_choose in +attribute [local simp ←] Complex.ofReal_choose in attribute [-simp] FormalMultilinearSeries.apply_eq_prod_smul_coeff in theorem one_add_rpow_hasFPowerSeriesOnBall_zero {a : ℝ} : HasFPowerSeriesOnBall (fun x ↦ (1 + x) ^ a) (binomialSeries ℝ a) 0 1 := by diff --git a/Mathlib/Analysis/Analytic/CPolynomial.lean b/Mathlib/Analysis/Analytic/CPolynomial.lean index 46fe21a39e09c2..128ccc147f858a 100644 --- a/Mathlib/Analysis/Analytic/CPolynomial.lean +++ b/Mathlib/Analysis/Analytic/CPolynomial.lean @@ -115,10 +115,10 @@ open FormalMultilinearSeries protected theorem hasFiniteFPowerSeriesOnBall : HasFiniteFPowerSeriesOnBall f f.toFormalMultilinearSeries 0 (Fintype.card ι + 1) ⊤ := - .mk' (fun _ hm ↦ dif_neg (Nat.succ_le_iff.mp hm).ne) ENNReal.zero_lt_top fun y _ ↦ by + .mk' (fun _ hm ↦ dite_eq_right (Nat.succ_le_iff.mp hm).ne) ENNReal.zero_lt_top fun y _ ↦ by rw [Finset.sum_eq_single_of_mem _ (Finset.self_mem_range_succ _), zero_add] - · rw [toFormalMultilinearSeries, dif_pos rfl]; rfl - · intro m _ ne; rw [toFormalMultilinearSeries, dif_neg ne.symm]; rfl + · rw [toFormalMultilinearSeries, dite_eq_left rfl]; rfl + · intro m _ ne; rw [toFormalMultilinearSeries, dite_eq_right ne.symm]; rfl lemma cpolynomialAt : CPolynomialAt 𝕜 f x := f.hasFiniteFPowerSeriesOnBall.cpolynomialAt_of_mem @@ -162,12 +162,12 @@ protected theorem hasFiniteFPowerSeriesOnBall_uncurry_of_multilinear : f.toFormalMultilinearSeriesOfMultilinear 0 (Fintype.card (Option ι) + 1) ⊤ := by apply HasFiniteFPowerSeriesOnBall.mk' ?_ ENNReal.zero_lt_top ?_ · intro m hm - apply dif_neg + apply dite_eq_right exact Nat.ne_of_lt hm · intro y _ rw [Finset.sum_eq_single_of_mem _ (Finset.self_mem_range_succ _), zero_add] - · rw [toFormalMultilinearSeriesOfMultilinear, dif_pos rfl]; rfl - · intro m _ ne; rw [toFormalMultilinearSeriesOfMultilinear, dif_neg ne.symm]; rfl + · rw [toFormalMultilinearSeriesOfMultilinear, dite_eq_left rfl]; rfl + · intro m _ ne; rw [toFormalMultilinearSeriesOfMultilinear, dite_eq_right ne.symm]; rfl lemma cpolynomialAt_uncurry_of_multilinear : CPolynomialAt 𝕜 (fun (p : G × (Π i, Em i)) ↦ f p.1 p.2) x := diff --git a/Mathlib/Analysis/Analytic/Order.lean b/Mathlib/Analysis/Analytic/Order.lean index 43cc6d88cb0ecb..5dd01cf4031002 100644 --- a/Mathlib/Analysis/Analytic/Order.lean +++ b/Mathlib/Analysis/Analytic/Order.lean @@ -62,7 +62,7 @@ noncomputable def analyticOrderNatAt (f : 𝕜 → E) (z₀ : 𝕜) : ℕ := (an @[simp] lemma analyticOrderAt_of_not_analyticAt (hf : ¬ AnalyticAt 𝕜 f z₀) : analyticOrderAt f z₀ = 0 := - dif_neg hf + dite_eq_right hf @[simp] lemma analyticOrderNatAt_of_not_analyticAt (hf : ¬ AnalyticAt 𝕜 f z₀) : @@ -411,7 +411,7 @@ lemma AnalyticAt.exists_eq_sum_add_pow_mul [CharZero 𝕜] [CompleteSpace E] · exact hFa.congr (by filter_upwards [hU0] using by simp +contextual) · by_cases hz : z ∈ U · simpa [hz] using hU' z hz - · simp only [if_neg hz] + · simp only [ite_eq_right hz] rw [smul_inv_smul₀] · module · contrapose hz diff --git a/Mathlib/Analysis/BoxIntegral/Basic.lean b/Mathlib/Analysis/BoxIntegral/Basic.lean index 6fdefd88a4ba4f..39e9aba59bf1cc 100644 --- a/Mathlib/Analysis/BoxIntegral/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Basic.lean @@ -240,7 +240,7 @@ theorem HasIntegral.mono {l₁ l₂ : IntegrationParams} (h : HasIntegral I l₁ protected theorem Integrable.hasIntegral (h : Integrable I l f vol) : HasIntegral I l f vol (integral I l f vol) := by - rw [integral, dif_pos h] + rw [integral, dite_eq_left h] exact Classical.choose_spec h theorem Integrable.mono {l'} (h : Integrable I l f vol) (hle : l' ≤ l) : Integrable I l' f vol := @@ -284,7 +284,7 @@ theorem integrable_neg : Integrable I l (-f) vol ↔ Integrable I l f vol := theorem integral_neg : integral I l (-f) vol = -integral I l f vol := by classical exact if h : Integrable I l f vol then h.hasIntegral.neg.integral_eq - else by rw [integral, integral, dif_neg h, dif_neg (mt Integrable.of_neg h), neg_zero] + else by rw [integral, integral, dite_eq_right h, dite_eq_right (mt Integrable.of_neg h), neg_zero] theorem HasIntegral.sub (h : HasIntegral I l f vol y) (h' : HasIntegral I l g vol y') : HasIntegral I l (f - g) vol (y - y') := by simpa only [sub_eq_add_neg] using h.add h'.neg @@ -345,7 +345,7 @@ theorem integral_smul (c : ℝ) : integral I l (fun x => c • f x) vol = c • by_cases hf : Integrable I l f vol · exact (hf.hasIntegral.smul c).integral_eq · have : ¬Integrable I l (fun x => c • f x) vol := mt (fun h => h.of_smul hc) hf - rw [integral, integral, dif_neg hf, dif_neg this, smul_zero] + rw [integral, integral, dite_eq_right hf, dite_eq_right this, smul_zero] open MeasureTheory @@ -356,7 +356,7 @@ theorem integral_nonneg {g : ℝⁿ → ℝ} (hg : ∀ x ∈ Box.Icc I, 0 ≤ g by_cases hgi : Integrable I l g μ.toBoxAdditive.toSMul · refine ge_of_tendsto' hgi.hasIntegral fun π => sum_nonneg fun J _ => ?_ exact mul_nonneg ENNReal.toReal_nonneg (hg _ <| π.tag_mem_Icc _) - · rw [integral, dif_neg hgi] + · rw [integral, dite_eq_right hgi] /-- If `‖f x‖ ≤ g x` on `[l, u]` and `g` is integrable, then the norm of the integral of `f` is less than or equal to the integral of `g`. -/ @@ -370,7 +370,7 @@ theorem norm_integral_le_of_norm_le {g : ℝⁿ → ℝ} (hle : ∀ x ∈ Box.Ic μ.toBoxAdditive_apply, abs_of_nonneg measureReal_nonneg] gcongr exact hle _ <| π.tag_mem_Icc _ - · rw [integral, dif_neg hfi, norm_zero] + · rw [integral, dite_eq_right hfi, norm_zero] exact integral_nonneg (fun x hx => (norm_nonneg _).trans (hle x hx)) μ theorem norm_integral_le_of_le_const {c : ℝ} @@ -428,7 +428,7 @@ theorem convergenceR_cond (h : Integrable I l f vol) (ε : ℝ) (c : ℝ≥0) : theorem dist_integralSum_integral_le_of_memBaseSet (h : Integrable I l f vol) (h₀ : 0 < ε) (hπ : l.MemBaseSet I c (h.convergenceR ε c) π) (hπp : π.IsPartition) : dist (integralSum f vol π) (integral I l f vol) ≤ ε := by - rw [convergenceR, dif_pos h₀] at hπ + rw [convergenceR, dite_eq_left h₀] at hπ exact (hasIntegral_iff.1 h.hasIntegral ε h₀).choose_spec.2 c _ hπ hπp /-- **Henstock-Sacks inequality**. Let `r₁ r₂ : ℝⁿ → (0, ∞)` be a function such that for any tagged @@ -823,7 +823,7 @@ theorem HasIntegral.of_bRiemann_eq_false_of_forall_isLittleO (hl : l.bRiemann = rw [Finset.mem_filter] at hJ; obtain ⟨hJ, hJs⟩ := hJ refine Hδ₁ c _ ⟨π.tag_mem_Icc _, hJs⟩ _ (hεs0 _) _ (π.le_of_mem' _ hJ) ?_ (hπδ.2 hlH J hJ) fun hD => (Finset.le_sup hJ).trans (hπδ.3 hD) - convert! hπδ.1 J hJ using 3; exact (if_pos hJs).symm + convert! hπδ.1 J hJ using 3; exact (ite_eq_left hJs).symm refine (dist_sum_sum_le_of_le _ this).trans ?_ rw [sum_comp] refine (sum_le_sum ?_).trans (hεs _ ?_) @@ -843,7 +843,7 @@ theorem HasIntegral.of_bRiemann_eq_false_of_forall_isLittleO (hl : l.bRiemann = rw [Finset.mem_filter] at hJ; obtain ⟨hJ, hJs⟩ := hJ refine Hδ₂ c _ ⟨π.tag_mem_Icc _, hJs⟩ _ ε'0 _ (π.le_of_mem' _ hJ) ?_ (fun hH => hπδ.2 hH J hJ) fun hD => (Finset.le_sup hJ).trans (hπδ.3 hD) - convert! hπδ.1 J hJ using 3; exact (if_neg hJs).symm + convert! hπδ.1 J hJ using 3; exact (ite_eq_right hJs).symm _ ≤ ∑ J ∈ π.boxes, ε' * B J := by gcongr · exact fun _ _ _ ↦ mul_nonneg ε'0.le (hB0 _) diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean index f5a7507378a156..502475e1069d68 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean @@ -323,16 +323,16 @@ def biUnionIndex (πi : ∀ (J : Box ι), Prepartition J) (J : Box ι) : Box ι if hJ : J ∈ π.biUnion πi then (π.mem_biUnion.1 hJ).choose else I theorem biUnionIndex_mem (hJ : J ∈ π.biUnion πi) : π.biUnionIndex πi J ∈ π := by - rw [biUnionIndex, dif_pos hJ] + rw [biUnionIndex, dite_eq_left hJ] exact (π.mem_biUnion.1 hJ).choose_spec.1 theorem biUnionIndex_le (πi : ∀ J, Prepartition J) (J : Box ι) : π.biUnionIndex πi J ≤ I := by by_cases hJ : J ∈ π.biUnion πi · exact π.le_of_mem (π.biUnionIndex_mem hJ) - · rw [biUnionIndex, dif_neg hJ] + · rw [biUnionIndex, dite_eq_right hJ] theorem mem_biUnionIndex (hJ : J ∈ π.biUnion πi) : J ∈ πi (π.biUnionIndex πi J) := by - convert! (π.mem_biUnion.1 hJ).choose_spec.2 <;> exact dif_pos hJ + convert! (π.mem_biUnion.1 hJ).choose_spec.2 <;> exact dite_eq_left hJ theorem le_biUnionIndex (hJ : J ∈ π.biUnion πi) : J ≤ π.biUnionIndex πi J := le_of_mem _ (π.mem_biUnionIndex hJ) diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean b/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean index 84e1f0310b0e78..504b47b5958e5e 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean @@ -317,11 +317,12 @@ theorem iUnion_disjUnion (h : Disjoint π₁.iUnion π₂.iUnion) : theorem disjUnion_tag_of_mem_left (h : Disjoint π₁.iUnion π₂.iUnion) (hJ : J ∈ π₁) : (π₁.disjUnion π₂ h).tag J = π₁.tag J := - dif_pos hJ + dite_eq_left hJ theorem disjUnion_tag_of_mem_right (h : Disjoint π₁.iUnion π₂.iUnion) (hJ : J ∈ π₂) : (π₁.disjUnion π₂ h).tag J = π₂.tag J := - dif_neg fun h₁ => h.le_bot ⟨π₁.subset_iUnion h₁ J.upper_mem, π₂.subset_iUnion hJ J.upper_mem⟩ + dite_eq_right fun h₁ => + h.le_bot ⟨π₁.subset_iUnion h₁ J.upper_mem, π₂.subset_iUnion hJ J.upper_mem⟩ theorem IsSubordinate.disjUnion [Fintype ι] (h₁ : IsSubordinate π₁ r) (h₂ : IsSubordinate π₂ r) (h : Disjoint π₁.iUnion π₂.iUnion) : IsSubordinate (π₁.disjUnion π₂ h) r := by diff --git a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean index 5684b81b6a655a..9f3af3568c772e 100644 --- a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean +++ b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean @@ -238,9 +238,9 @@ def prepartition (B : Box ι) : TaggedPrepartition B where if hI : ∃ ν ∈ admissibleIndex n B, I = box n ν then tag n hI.choose else B.exists_mem.choose tag_mem_Icc I := by by_cases hI : ∃ ν ∈ admissibleIndex n B, I = box n ν - · simp_rw [dif_pos hI] + · simp_rw [dite_eq_left hI] exact Box.coe_subset_Icc <| (mem_admissibleIndex_iff.mp hI.choose_spec.1) (tag_mem n _) - · simp_rw [dif_neg hI] + · simp_rw [dite_eq_right hI] exact Box.coe_subset_Icc B.exists_mem.choose_spec set_option backward.isDefEq.respectTransparency.types false in @@ -260,7 +260,7 @@ theorem prepartition_tag {ν : ι → ℤ} {B : Box ι} (hν : ν ∈ admissible (prepartition n B).tag (box n ν) = tag n ν := by dsimp only [prepartition] have h : ∃ ν' ∈ admissibleIndex n B, box n ν = box n ν' := ⟨ν, hν, rfl⟩ - rw [dif_pos h, (tag_injective n).eq_iff, ← (box_injective n).eq_iff] + rw [dite_eq_left h, (tag_injective n).eq_iff, ← (box_injective n).eq_iff] exact h.choose_spec.2.symm theorem box_index_tag_eq_self {B I : Box ι} (hI : I ∈ (prepartition n B).boxes) : diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index 30b7a734f0a8f1..9c1539fa6a3d8a 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -224,7 +224,7 @@ variable (ha : p a := by cfc_tac) set_option backward.privateInPublic true in lemma cfcₙ_apply : cfcₙ f a = cfcₙHom (a := a) ha ⟨⟨_, hf.domRestrict⟩, hf0⟩ := by - rw [cfcₙ_def, dif_pos ⟨ha, hf, hf0⟩] + rw [cfcₙ_def, dite_eq_left ⟨ha, hf, hf0⟩] lemma cfcₙ_apply_pi {ι : Type*} (f : ι → R → R) (a : A) (ha := by cfc_tac) (hf : ∀ i, ContinuousOn (f i) (σₙ R a) := by cfc_cont_tac) @@ -236,19 +236,19 @@ lemma cfcₙ_apply_pi {ι : Type*} (f : ι → R → R) (a : A) (ha := by cfc_ta lemma cfcₙ_apply_of_not_and_and {f : R → R} (a : A) (ha : ¬ (p a ∧ ContinuousOn f (σₙ R a) ∧ f 0 = 0)) : cfcₙ f a = 0 := by - rw [cfcₙ_def, dif_neg ha] + rw [cfcₙ_def, dite_eq_right ha] lemma cfcₙ_apply_of_not_predicate {f : R → R} (a : A) (ha : ¬ p a) : cfcₙ f a = 0 := by - rw [cfcₙ_def, dif_neg (not_and_of_not_left _ ha)] + rw [cfcₙ_def, dite_eq_right (not_and_of_not_left _ ha)] lemma cfcₙ_apply_of_not_continuousOn {f : R → R} (a : A) (hf : ¬ ContinuousOn f (σₙ R a)) : cfcₙ f a = 0 := by - rw [cfcₙ_def, dif_neg (not_and_of_not_right _ (not_and_of_not_left _ hf))] + rw [cfcₙ_def, dite_eq_right (not_and_of_not_right _ (not_and_of_not_left _ hf))] lemma cfcₙ_apply_of_not_map_zero {f : R → R} (a : A) (hf : ¬ f 0 = 0) : cfcₙ f a = 0 := by - rw [cfcₙ_def, dif_neg (not_and_of_not_right _ (not_and_of_not_right _ hf))] + rw [cfcₙ_def, dite_eq_right (not_and_of_not_right _ (not_and_of_not_right _ hf))] set_option backward.isDefEq.respectTransparency false in lemma cfcₙHom_eq_cfcₙ_extend {a : A} (g : R → R) (ha : p a) (f : C(σₙ R a, R)₀) : @@ -266,7 +266,7 @@ lemma cfcₙHom_eq_cfcₙ_extend {a : A} (g : R → R) (ha : p a) (f : C(σₙ R lemma cfcₙ_eq_cfcₙL {a : A} {f : R → R} (ha : p a) (hf : ContinuousOn f (σₙ R a)) (hf0 : f 0 = 0) : cfcₙ f a = cfcₙL ha ⟨⟨_, hf.domRestrict⟩, hf0⟩ := by - rw [cfcₙ_def, dif_pos ⟨ha, hf, hf0⟩, cfcₙL_apply] + rw [cfcₙ_def, dite_eq_left ⟨ha, hf, hf0⟩, cfcₙL_apply] set_option backward.privateInPublic true in /-- A version of `cfcₙ_apply` in terms of `ContinuousMapZero.mkD` -/ diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean index a32d0687a18f6a..9587d3ffd42c14 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean @@ -315,7 +315,7 @@ variable (hg : ContinuousOn g (spectrum R a) := by cfc_cont_tac) set_option backward.privateInPublic true in lemma cfc_apply : cfc f a = cfcHom (a := a) ha ⟨_, hf.domRestrict⟩ := by - rw [cfc_def, dif_pos ⟨ha, hf⟩] + rw [cfc_def, dite_eq_left ⟨ha, hf⟩] lemma cfc_apply_pi {ι : Type*} (f : ι → R → R) (a : A) (ha : p a := by cfc_tac) (hf : ∀ i, ContinuousOn (f i) (spectrum R a) := by cfc_cont_tac) : @@ -325,15 +325,15 @@ lemma cfc_apply_pi {ι : Type*} (f : ι → R → R) (a : A) (ha : p a := by cfc lemma cfc_apply_of_not_and {f : R → R} (a : A) (ha : ¬ (p a ∧ ContinuousOn f (spectrum R a))) : cfc f a = 0 := by - rw [cfc_def, dif_neg ha] + rw [cfc_def, dite_eq_right ha] lemma cfc_apply_of_not_predicate {f : R → R} (a : A) (ha : ¬ p a) : cfc f a = 0 := by - rw [cfc_def, dif_neg (not_and_of_not_left _ ha)] + rw [cfc_def, dite_eq_right (not_and_of_not_left _ ha)] lemma cfc_apply_of_not_continuousOn {f : R → R} (a : A) (hf : ¬ ContinuousOn f (spectrum R a)) : cfc f a = 0 := by - rw [cfc_def, dif_neg (not_and_of_not_right _ hf)] + rw [cfc_def, dite_eq_right (not_and_of_not_right _ hf)] lemma cfcHom_eq_cfc_extend {a : A} (g : R → R) (ha : p a) (f : C(spectrum R a, R)) : cfcHom ha f = cfc (Function.extend Subtype.val f g) a := by @@ -346,7 +346,7 @@ lemma cfcHom_eq_cfc_extend {a : A} (g : R → R) (ha : p a) (f : C(spectrum R a, lemma cfc_eq_cfcL {a : A} {f : R → R} (ha : p a) (hf : ContinuousOn f (spectrum R a)) : cfc f a = cfcL ha ⟨_, hf.domRestrict⟩ := by - rw [cfc_def, dif_pos ⟨ha, hf⟩, cfcL_apply] + rw [cfc_def, dite_eq_left ⟨ha, hf⟩, cfcL_apply] set_option backward.privateInPublic true in /-- A version of `cfc_apply` in terms of `ContinuousMap.mkD` -/ diff --git a/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean b/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean index 4f554cb97bb2e7..e53eb612858e81 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean @@ -483,7 +483,7 @@ instance (priority := 100) {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E (Ioi 1 ×ˢ univ) by apply this.congr rintro ⟨R, x⟩ ⟨hR : 1 < R, _⟩ - simp only [hR, uncurry_apply_pair, if_true, Function.comp_apply] + simp only [hR, uncurry_apply_pair, ite_true, Function.comp_apply] apply (y_smooth E).comp · apply ContDiffOn.prodMk · refine @@ -504,7 +504,7 @@ instance (priority := 100) {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E simp only [prodMk_mem_set_prod_eq, mem_Ioo, mem_univ, and_true, A, B] eq_one := fun R hR x hx => by have A : 0 < R + 1 := by linarith - simp only [hR, if_true] + simp only [hR, ite_true] apply y_eq_one_of_mem_closedBall (IR R hR) simp only [norm_smul, inv_div, mem_closedBall_zero_iff, Real.norm_eq_abs, abs_div, abs_two, abs_of_nonneg A.le] @@ -514,7 +514,7 @@ instance (priority := 100) {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E support := fun R hR => by have A : 0 < (R + 1) / 2 := by linarith have C : (R - 1) / (R + 1) < 1 := by apply (div_lt_one _).2 <;> linarith - simp only [hR, if_true, support_comp_inv_smul₀ A.ne', y_support _ (IR R hR) C, + simp only [hR, ite_true, support_comp_inv_smul₀ A.ne', y_support _ (IR R hR) C, _root_.smul_ball A.ne', Real.norm_of_nonneg A.le, smul_zero] refine congr (congr_arg ball (Eq.refl 0)) ?_ field } diff --git a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean index e01b40b3fa16fc..1cca277dc7139d 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FaaDiBruno.lean @@ -674,7 +674,7 @@ def extendEquiv (n : ℕ) : by_cases h : range (c.emb 0) = {0} · have A : c.length - 1 + 1 = c.length := Nat.sub_add_cancel (c.length_pos (Nat.zero_lt_succ n)) dsimp only - rw [dif_pos h] + rw [dite_eq_left h] simp only [extend, extendLeft, eraseLeft] ext · exact A @@ -698,7 +698,7 @@ def extendEquiv (n : ℕ) : exact (apply_eq_of_range_eq_singleton h _).symm | succ i => simp · dsimp only - rw [dif_neg h] + rw [dite_eq_right h] have B : c.partSize (c.index 0) - 1 + 1 = c.partSize (c.index 0) := Nat.sub_add_cancel (c.partSize_pos (c.index 0)) simp only [extend, extendMiddle, eraseMiddle, ↓reduceDIte] diff --git a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean index d73e96d56424df..ac5499a0d9272b 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Analytic.lean @@ -587,7 +587,7 @@ theorem changeOriginSeries_support {k l : ℕ} (h : k + l ≠ Fintype.card ι) : f.toFormalMultilinearSeries.changeOriginSeries k l = 0 := Finset.sum_eq_zero fun _ _ ↦ by simp_rw [FormalMultilinearSeries.changeOriginSeriesTerm, - toFormalMultilinearSeries, dif_neg h.symm, LinearIsometryEquiv.map_zero] + toFormalMultilinearSeries, dite_eq_right h.symm, LinearIsometryEquiv.map_zero] variable {n : WithTop ℕ∞} (x : ∀ i, E i) @@ -619,7 +619,7 @@ theorem changeOrigin_toFormalMultilinearSeries [DecidableEq ι] : obtain ⟨a, ha⟩ := card_eq_one.mp h exact ⟨a, Subtype.ext (compl_eq_comm.mp ha)⟩ rw [Function.comp_apply, Subtype.coe_mk, compl_singleton, piecewise_erase_univ, - toFormalMultilinearSeries, dif_pos (Nat.add_sub_of_le Fintype.card_pos).symm] + toFormalMultilinearSeries, dite_eq_left (Nat.add_sub_of_le Fintype.card_pos).symm] simp_rw [domDomCongr_apply, compContinuousLinearMap_apply, ContinuousLinearMap.proj_apply, Function.update_apply, (Equiv.injective _).eq_iff, ite_apply] congr diff --git a/Mathlib/Analysis/Calculus/FDeriv/Basic.lean b/Mathlib/Analysis/Calculus/FDeriv/Basic.lean index 538d55195de38b..7153e3ef8b08c9 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Basic.lean @@ -378,7 +378,7 @@ theorem HasFDerivWithinAt.of_notMem_closure (h : x ∉ closure s) : HasFDerivWit theorem fderivWithin_zero_of_not_accPt (h : ¬AccPt x (𝓟 s)) : fderivWithin 𝕜 f s x = 0 := by - rw [fderivWithin, if_pos (.of_not_accPt h)] + rw [fderivWithin, ite_eq_left (.of_not_accPt h)] theorem fderivWithin_zero_of_notMem_closure (h : x ∉ closure s) : fderivWithin 𝕜 f s x = 0 := @@ -390,7 +390,7 @@ theorem fderivWithin_zero_of_not_uniqueDiffWithinAt {f : 𝕜 → F} {x : 𝕜} theorem DifferentiableWithinAt.hasFDerivWithinAt (h : DifferentiableWithinAt 𝕜 f s x) : HasFDerivWithinAt f (fderivWithin 𝕜 f s x) s x := by - simp only [fderivWithin, dif_pos h] + simp only [fderivWithin, dite_eq_left h] split_ifs with h₀ exacts [h₀, Classical.choose_spec h] diff --git a/Mathlib/Analysis/Calculus/FDeriv/Const.lean b/Mathlib/Analysis/Calculus/FDeriv/Const.lean index a35d81e96fb6e0..1b8be7c7309c45 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Const.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Const.lean @@ -183,7 +183,7 @@ theorem differentiableWithinAt_ofNat (n : ℕ) [OfNat F n] : DifferentiableWithinAt 𝕜 (ofNat(n) : E → F) s x := differentiableWithinAt_const _ theorem fderivWithin_const_apply (c : F) : fderivWithin 𝕜 (fun _ => c) s x = 0 := by - rw [fderivWithin, if_pos] + rw [fderivWithin, ite_eq_left] apply hasFDerivWithinAt_const @[simp] diff --git a/Mathlib/Analysis/Complex/Hadamard.lean b/Mathlib/Analysis/Complex/Hadamard.lean index edd044f8b102af..3f34b47a55d587 100644 --- a/Mathlib/Analysis/Complex/Hadamard.lean +++ b/Mathlib/Analysis/Complex/Hadamard.lean @@ -252,12 +252,12 @@ noncomputable def interpStrip (z : ℂ) : ℂ := /-- Rewrite for `InterpStrip` when `0 < sSupNormIm f 0` and `0 < sSupNormIm f 1`. -/ lemma interpStrip_eq_of_pos (z : ℂ) (h0 : 0 < sSupNormIm f 0) (h1 : 0 < sSupNormIm f 1) : interpStrip f z = sSupNormIm f 0 ^ (1 - z) * sSupNormIm f 1 ^ z := by - simp only [ne_of_gt h0, ne_of_gt h1, interpStrip, if_false, or_false] + simp only [ne_of_gt h0, ne_of_gt h1, interpStrip, ite_false, or_false] /-- Rewrite for `InterpStrip` when `0 = sSupNormIm f 0` or `0 = sSupNormIm f 1`. -/ lemma interpStrip_eq_of_zero (z : ℂ) (h : sSupNormIm f 0 = 0 ∨ sSupNormIm f 1 = 0) : interpStrip f z = 0 := - if_pos h + ite_eq_left h /-- Rewrite for `InterpStrip` on the open vertical strip. -/ lemma interpStrip_eq_of_mem_verticalStrip (z : ℂ) (hz : z ∈ verticalStrip 0 1) : diff --git a/Mathlib/Analysis/Complex/Polynomial/GaussLucas.lean b/Mathlib/Analysis/Complex/Polynomial/GaussLucas.lean index a157942e6135d8..9b816930115ce9 100644 --- a/Mathlib/Analysis/Complex/Polynomial/GaussLucas.lean +++ b/Mathlib/Analysis/Complex/Polynomial/GaussLucas.lean @@ -40,7 +40,7 @@ theorem sum_derivRootWeight_pos (hP : 0 < degree P) (z : ℂ) : have hP₀ : P ≠ 0 := by rintro rfl; simp at hP by_cases hPz : P.eval z = 0 · simp [derivRootWeight, hPz, hP₀] - · simp only [derivRootWeight, if_neg hPz] + · simp only [derivRootWeight, ite_eq_right hPz] apply Finset.sum_pos · intro w hw apply div_pos (by simp_all) @@ -71,11 +71,11 @@ theorem eq_centerMass_of_eval_derivative_eq_zero (hP : 0 < P.degree) _ = s.centerMass weight id := by simp only [add_eq_right, Finset.centerMass, this, smul_zero] by_cases hzP : P.eval z = 0 - · simp only [weight, derivRootWeight, if_pos hzP] + · simp only [weight, derivRootWeight, ite_eq_left hzP] rw [Finset.sum_eq_single z] <;> simp_all calc ∑ x ∈ s, weight x • (z - x) = conj (∑ x ∈ s, P.rootMultiplicity x • (1 / (z - x))) := by - simp only [map_sum, weight, derivRootWeight, if_neg hzP] + simp only [map_sum, weight, derivRootWeight, ite_eq_right hzP] refine Finset.sum_congr rfl fun x hx ↦ ?_ have : z - x ≠ 0 := by rw [sub_ne_zero] diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean index 52510c6ad4970e..3af6bb0f58901d 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/FixedPoints.lean @@ -69,7 +69,7 @@ theorem gl_smul_eq_self_iff_dist_sq_eq (h : g.val.det < 0) (htrace : g.val.trace g • z = z ↔ dist (z : ℂ) (-g 1 1 / g 1 0) ^ 2 = (-g.val.det) / g 1 0 ^ 2 := by rw [Matrix.trace_fin_two, ← eq_neg_iff_add_eq_zero] at htrace rw [eq_div_iff (by positivity), dist_eq_norm, ← Complex.normSq_eq_norm_sq, Complex.normSq_apply, - gl_smul_eq_iff_num_eq, σ, g.val_det_apply, if_neg h.not_gt] + gl_smul_eq_iff_num_eq, σ, g.val_det_apply, ite_eq_right h.not_gt] simp [num, denom, Complex.ext_iff, htrace, Matrix.det_fin_two, field] grind @@ -172,12 +172,12 @@ theorem gl_smul_eq_self_iff_eq_fixedPt (hpos : 0 < g.val.det) (hell : g.IsEllipt theorem gl_smul_I_eq_I_iff_of_pos {g : GL (Fin 2) ℝ} (hg : 0 < g.det.val) : g • I = I ↔ g 0 0 = g 1 1 ∧ g 0 1 = -g 1 0 := by - rw [gl_smul_eq_iff_num_eq, σ, if_pos hg] + rw [gl_smul_eq_iff_num_eq, σ, ite_eq_left hg] simp [Complex.ext_iff, num, denom, and_comm] theorem gl_smul_I_eq_I_iff_of_neg {g : GL (Fin 2) ℝ} (hg : g.det.val < 0) : g • I = I ↔ g 0 0 = -g 1 1 ∧ g 0 1 = g 1 0 := by - rw [gl_smul_eq_iff_num_eq, σ, if_neg (not_lt_of_gt hg)] + rw [gl_smul_eq_iff_num_eq, σ, ite_eq_right (not_lt_of_gt hg)] simp [num, denom, Complex.ext_iff, and_comm] /-- A matrix acts trivially on `ℍ` iff it belongs to the center of `GL(2, ℝ)`, diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean index 64c4be3caf4e8a..8b98e54b6b09d8 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/MoebiusAction.lean @@ -193,7 +193,7 @@ lemma coe_smul (g : GL (Fin 2) ℝ) (z : ℍ) : lemma coe_smul_of_det_pos {g : GL (Fin 2) ℝ} (hg : 0 < g.det.val) (z : ℍ) : ↑(g • z) = num g z / denom g z := by change smulAux' g z = _ - rw [smulAux', σ, if_pos hg, ContinuousAlgEquiv.refl_apply, num, denom] + rw [smulAux', σ, ite_eq_left hg, ContinuousAlgEquiv.refl_apply, num, denom] lemma denom_cocycle_σ (g h : GL (Fin 2) ℝ) (z : ℍ) : denom (g * h) z = σ h (denom g ↑(h • z)) * denom h z := diff --git a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean index d3056e8b6b9679..3d1123b2c66638 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/LogCounting/Asymptotic.lean @@ -132,11 +132,11 @@ lemma finite_support_of_logCounting_isBigO_log [ProperSpace E] intro w simp only [hD', coe_sum, Finset.sum_apply, single_apply, Finset.sum_ite_eq] by_cases hw : w ∈ t - · simp only [hw, if_true] + · simp only [hw, ite_true] have h₁ : D w ≠ 0 := mem_support.mp (htsub (Finset.mem_coe.2 hw)) have h₂ : (0 : ℤ) ≤ D w := by simpa using (le_def.1 h) w omega - · simpa [hw, if_false] using (le_def.1 h) w + · simpa [hw, ite_false] using (le_def.1 h) w -- A uniform bound on the norms of points in `t`. obtain ⟨R₀, hR₀⟩ : ∃ R₀ : ℝ, ∀ z ∈ t, ‖z‖ ≤ R₀ := t.finite_toSet.isBounded.exists_norm_le set K := ∑ z ∈ t, log ‖z‖ with hK diff --git a/Mathlib/Analysis/Convex/Combination.lean b/Mathlib/Analysis/Convex/Combination.lean index 8165b2b1fc2723..a23ccb16918dbe 100644 --- a/Mathlib/Analysis/Convex/Combination.lean +++ b/Mathlib/Analysis/Convex/Combination.lean @@ -114,8 +114,8 @@ theorem Finset.centerMass_ite_eq [DecidableEq ι] (hi : i ∈ t) : · congr with i split_ifs with h exacts [h ▸ one_smul _ _, zero_smul _ _] - · rw [sum_ite_eq, if_pos hi] - · rw [sum_ite_eq, if_pos hi] + · rw [sum_ite_eq, ite_eq_left hi] + · rw [sum_ite_eq, ite_eq_left hi] variable {t} @@ -225,13 +225,13 @@ theorem Convex.finsum_mem {ι : Sort*} {w : ι → R} {z : ι → E} {s : Set E} (∑ᶠ i, w i • z i) ∈ s := by have hfin_w : HasFiniteSupport (w ∘ PLift.down) := by by_contra H - rw [finsum, dif_neg H] at h₁ + rw [finsum, dite_eq_right H] at h₁ exact zero_ne_one h₁ have hsub : support ((fun i => w i • z i) ∘ PLift.down) ⊆ hfin_w.toFinset := (support_smul_subset_left _ _).trans hfin_w.coe_toFinset.ge rw [finsum_eq_sum_plift_of_support_subset hsub] refine hs.sum_mem (fun _ _ => h₀ _) ?_ fun i hi => hz _ ?_ - · rwa [finsum, dif_pos hfin_w] at h₁ + · rwa [finsum, dite_eq_left hfin_w] at h₁ · rwa [hfin_w.mem_toFinset] at hi theorem convex_iff_sum_mem : Convex R s ↔ ∀ (t : Finset E) (w : E → R), @@ -243,9 +243,9 @@ theorem convex_iff_sum_mem : Convex R s ↔ ∀ (t : Finset E) (w : E → R), · rw [h_cases, ← add_smul, hab, one_smul] exact hy · convert! h { x, y } (fun z => if z = y then b else a) _ _ _ - · simp only [sum_pair h_cases, if_neg h_cases, if_pos trivial] + · simp only [sum_pair h_cases, ite_eq_right h_cases, ite_eq_left trivial] · grind - · simp only [sum_pair h_cases, if_neg h_cases, if_pos trivial, hab] + · simp only [sum_pair h_cases, ite_eq_right h_cases, ite_eq_left trivial, hab] · intro i hi simp only [Finset.mem_singleton, Finset.mem_insert] at hi cases hi <;> subst i <;> assumption @@ -396,7 +396,7 @@ theorem Finset.convexHull_eq (s : Finset E) : convexHull R ↑s = · intros split_ifs exacts [zero_le_one, le_refl 0] - · rw [Finset.sum_ite_eq, if_pos hx] + · rw [Finset.sum_ite_eq, ite_eq_left hx] · rintro x ⟨wx, hwx₀, hwx₁, rfl⟩ y ⟨wy, hwy₀, hwy₁, rfl⟩ a b ha hb hab rw [Finset.centerMass_segment _ _ _ _ hwx₁ hwy₁ _ _ hab] refine ⟨_, ?_, ?_, rfl⟩ diff --git a/Mathlib/Analysis/Fourier/AddCircleMulti.lean b/Mathlib/Analysis/Fourier/AddCircleMulti.lean index 08ab569e1977c4..e141194f7ebb4a 100644 --- a/Mathlib/Analysis/Fourier/AddCircleMulti.lean +++ b/Mathlib/Analysis/Fourier/AddCircleMulti.lean @@ -233,7 +233,7 @@ theorem orthonormal_mFourier : Orthonormal ℂ (mFourierLp (d := d) 2) := by rw [mFourier, ContinuousMap.coe_mk, MeasureTheory.integral_fintype_prod_volume_eq_prod] obtain ⟨i, hi⟩ := Function.ne_iff.mp h apply Finset.prod_eq_zero (Finset.mem_univ i) - simpa only [eq_false_intro hi, if_false, ContinuousMap.inner_toLp, ← fourier_neg, + simpa only [eq_false_intro hi, ite_false, ContinuousMap.inner_toLp, ← fourier_neg, ← fourier_add] using! (orthonormal_iff_ite.mp <| orthonormal_fourier) (m i) (n i) end Lp diff --git a/Mathlib/Analysis/Fourier/FiniteAbelian/PontryaginDuality.lean b/Mathlib/Analysis/Fourier/FiniteAbelian/PontryaginDuality.lean index 3918dfeacbc483..58bd84ccac8ac3 100644 --- a/Mathlib/Analysis/Fourier/FiniteAbelian/PontryaginDuality.lean +++ b/Mathlib/Analysis/Fourier/FiniteAbelian/PontryaginDuality.lean @@ -145,7 +145,7 @@ lemma exists_apply_ne_zero : (∃ ψ : AddChar α ℂ, ψ a ≠ 1) ↔ a ≠ 0 : have h₀ := congr_fun ((complexBasis α).sum_repr f) 0 have h₁ := congr_fun ((complexBasis α).sum_repr f) a simp only [complexBasis_apply, Fintype.sum_apply, Pi.smul_apply, h, smul_eq_mul, mul_one, - map_zero_eq_one, if_pos rfl, if_neg ha, f] at h₀ h₁ + map_zero_eq_one, ite_eq_left rfl, ite_eq_right ha, f] at h₀ h₁ exact one_ne_zero (h₁.symm.trans h₀) lemma forall_apply_eq_zero : (∀ ψ : AddChar α ℂ, ψ a = 1) ↔ a = 0 := by diff --git a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean index 601755168bcab6..eaded718197752 100644 --- a/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean +++ b/Mathlib/Analysis/InnerProductSpace/LinearPMap.lean @@ -173,12 +173,12 @@ set_option backward.isDefEq.respectTransparency false in theorem adjoint_apply_of_not_dense (hT : ¬Dense (T.domain : Set E)) (y : T†.domain) : T† y = 0 := by classical change (if hT : Dense (T.domain : Set E) then adjointAux hT else 0) y = _ - simp only [hT, not_false_iff, dif_neg, LinearMap.zero_apply] + simp only [hT, not_false_iff, dite_eq_right, LinearMap.zero_apply] theorem adjoint_apply_of_dense (y : T†.domain) : T† y = adjointAux hT y := by classical change (if hT : Dense (T.domain : Set E) then adjointAux hT else 0) y = _ - simp only [hT, dif_pos] + simp only [hT, dite_eq_left] include hT in theorem adjoint_apply_eq (y : T†.domain) {x₀ : E} (hx₀ : ∀ x : T.domain, ⟪x₀, x⟫ = ⟪(y : F), T x⟫) : diff --git a/Mathlib/Analysis/InnerProductSpace/Orientation.lean b/Mathlib/Analysis/InnerProductSpace/Orientation.lean index 84c7293803a8d9..cc190eefff25a0 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orientation.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orientation.lean @@ -186,7 +186,7 @@ theorem volumeForm_zero_neg [_i : Fact (finrank ℝ E = 0)] : Orientation.volumeForm (-positiveOrientation : Orientation ℝ E (Fin 0)) = -AlternatingMap.constLinearEquivOfIsEmpty 1 := by simp_rw [volumeForm, Or.by_cases, positiveOrientation] - apply if_neg + apply ite_eq_right simp only [neg_rayOfNeZero] rw [ray_eq_iff, SameRay.sameRay_comm] intro h @@ -200,7 +200,7 @@ theorem volumeForm_robust (b : OrthonormalBasis (Fin n) ℝ E) (hb : b.toBasis.o cases n · classical have : o = positiveOrientation := hb.symm.trans b.toBasis.orientation_isEmpty - simp_rw [volumeForm, Or.by_cases, dif_pos this, Nat.rec_zero, Basis.det_isEmpty] + simp_rw [volumeForm, Or.by_cases, dite_eq_left this, Nat.rec_zero, Basis.det_isEmpty] · simp_rw [volumeForm] rw [same_orientation_iff_det_eq_det, hb] exact o.finOrthonormalBasis_orientation _ _ @@ -212,7 +212,7 @@ theorem volumeForm_robust_neg (b : OrthonormalBasis (Fin n) ℝ E) (hb : b.toBas rcases n with - | n · classical have : positiveOrientation ≠ o := by rwa [b.toBasis.orientation_isEmpty] at hb - simp_rw [volumeForm, Or.by_cases, dif_neg this.symm, Nat.rec_zero, Basis.det_isEmpty] + simp_rw [volumeForm, Or.by_cases, dite_eq_right this.symm, Nat.rec_zero, Basis.det_isEmpty] let e : OrthonormalBasis (Fin n.succ) ℝ E := o.finOrthonormalBasis n.succ_pos Fact.out simp_rw [volumeForm] apply e.det_eq_neg_det_of_opposite_orientation b diff --git a/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean b/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean index 2eb54e2e982f78..0de4d736fde309 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orthonormal.lean @@ -139,7 +139,7 @@ theorem Orthonormal.inner_left_sum {v : ι → E} (hv : Orthonormal 𝕜 v) (l : {i : ι} (hi : i ∈ s) : ⟪∑ i ∈ s, l i • v i, v i⟫ = conj (l i) := by classical simp only [sum_inner, inner_smul_left, orthonormal_iff_ite.mp hv, hi, mul_boole, - Finset.sum_ite_eq', if_true] + Finset.sum_ite_eq', ite_true] /-- The inner product of a linear combination of a set of orthonormal vectors with one of those vectors picks out the coefficient of that vector. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/Subspace.lean b/Mathlib/Analysis/InnerProductSpace/Subspace.lean index 7b76274671b706..9c9ac2bbf1896a 100644 --- a/Mathlib/Analysis/InnerProductSpace/Subspace.lean +++ b/Mathlib/Analysis/InnerProductSpace/Subspace.lean @@ -123,7 +123,7 @@ theorem OrthogonalFamily.inner_right_fintype [Fintype ι] (l : ∀ i, G i) (i : _ = ∑ j, ite (i = j) ⟪V i v, V j (l j)⟫ 0 := (congr_arg (Finset.sum Finset.univ) <| funext fun j => hV.eq_ite v (l j)) _ = ⟪v, l i⟫ := by - simp only [Finset.sum_ite_eq, Finset.mem_univ, (V i).inner_map_map, if_true] + simp only [Finset.sum_ite_eq, Finset.mem_univ, (V i).inner_map_map, ite_true] nonrec theorem OrthogonalFamily.inner_sum (l₁ l₂ : ∀ i, G i) (s : Finset ι) : ⟪∑ i ∈ s, V i (l₁ i), ∑ j ∈ s, V j (l₂ j)⟫ = ∑ i ∈ s, ⟪l₁ i, l₂ i⟫ := by @@ -171,8 +171,8 @@ theorem OrthogonalFamily.norm_sq_sdiff_sum [DecidableEq ι] (f : ∀ i, G i) (s (∑ i ∈ s₁ \ s₂, ‖f i‖ ^ 2) + ∑ i ∈ s₂ \ s₁, ‖f i‖ ^ 2 := by rw [← Finset.sum_sdiff_sub_sum_sdiff, sub_eq_add_neg, ← Finset.sum_neg_distrib] let F : ∀ i, G i := fun i => if i ∈ s₁ then f i else -f i - have hF₁ : ∀ i ∈ s₁ \ s₂, F i = f i := fun i hi => if_pos (Finset.sdiff_subset hi) - have hF₂ : ∀ i ∈ s₂ \ s₁, F i = -f i := fun i hi => if_neg (Finset.mem_sdiff.mp hi).2 + have hF₁ : ∀ i ∈ s₁ \ s₂, F i = f i := fun i hi => ite_eq_left (Finset.sdiff_subset hi) + have hF₂ : ∀ i ∈ s₂ \ s₁, F i = -f i := fun i hi => ite_eq_right (Finset.mem_sdiff.mp hi).2 have hF : ∀ i, ‖F i‖ = ‖f i‖ := by intro i dsimp only [F] diff --git a/Mathlib/Analysis/MeanInequalitiesPow.lean b/Mathlib/Analysis/MeanInequalitiesPow.lean index 18b89c5d8dbae4..a476415aaa6393 100644 --- a/Mathlib/Analysis/MeanInequalitiesPow.lean +++ b/Mathlib/Analysis/MeanInequalitiesPow.lean @@ -324,12 +324,12 @@ for `p ≥ 1` or `p = 0`, and `2^(1/p-1)` in the more tricky interval `(0, 1)`. if p ∈ Set.Ioo (0 : ℝ≥0∞) 1 then (2 : ℝ≥0∞) ^ (1 / p.toReal - 1) else 1 theorem LpAddConst_of_one_le {p : ℝ≥0∞} (hp : 1 ≤ p) : LpAddConst p = 1 := by - rw [LpAddConst, if_neg] + rw [LpAddConst, ite_eq_right] intro h exact lt_irrefl _ (h.2.trans_le hp) theorem LpAddConst_zero : LpAddConst 0 = 1 := by - rw [LpAddConst, if_neg] + rw [LpAddConst, ite_eq_right] intro h exact lt_irrefl _ h.1 @@ -352,7 +352,7 @@ theorem rpow_add_le_mul_rpow_add_rpow' (z₁ z₂ : ℝ≥0∞) {p : ℝ} (hp : · rwa [ENNReal.inv_lt_one, one_lt_ofReal] rw [show LpAddConst (ENNReal.ofReal p)⁻¹ = (2 : ℝ≥0∞) ^ (1 / ((ENNReal.ofReal p)⁻¹).toReal - 1) by - rw [LpAddConst, if_pos hmem]] + rw [LpAddConst, ite_eq_left hmem]] simp only [ENNReal.toReal_inv, div_inv_eq_mul, one_mul] rw [ENNReal.toReal_ofReal hp] exact rpow_add_le_mul_rpow_add_rpow _ _ h.le diff --git a/Mathlib/Analysis/Meromorphic/Order.lean b/Mathlib/Analysis/Meromorphic/Order.lean index 72860fac7141a4..c2d164b5e84074 100644 --- a/Mathlib/Analysis/Meromorphic/Order.lean +++ b/Mathlib/Analysis/Meromorphic/Order.lean @@ -55,7 +55,7 @@ noncomputable def meromorphicOrderAt (f : 𝕜 → E) (x : 𝕜) : WithTop ℤ : @[simp] lemma meromorphicOrderAt_of_not_meromorphicAt (hf : ¬ MeromorphicAt f x) : meromorphicOrderAt f x = 0 := - dif_neg hf + dite_eq_right hf lemma meromorphicAt_of_meromorphicOrderAt_ne_zero (hf : meromorphicOrderAt f x ≠ 0) : MeromorphicAt f x := by diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean index 38fb17e3bcd2d9..17c1cd581e23f7 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsorBases.lean @@ -101,7 +101,7 @@ theorem IsOpen.exists_between_affineIndependent_span_eq_top {s u : Set P} (hu : · intro p hp; use ⟨p, ht₁ hp⟩; simp [w, hp] · rintro y ⟨⟨p, hp⟩, rfl⟩ by_cases hps : p ∈ s <;> - simp only [w, hps, lineMap_apply_one, Units.val_mk0, dif_neg, dif_pos, not_false_iff, + simp only [w, hps, lineMap_apply_one, Units.val_mk0, dite_eq_right, dite_eq_left, not_false_iff, Units.val_one] <;> [exact hsu hps; exact hf p] · exact (ht₂.units_lineMap ⟨q, ht₁ hq⟩ w).range diff --git a/Mathlib/Analysis/Normed/Algebra/Exponential.lean b/Mathlib/Analysis/Normed/Algebra/Exponential.lean index 4c210b5cb05db4..491cc13aafe730 100644 --- a/Mathlib/Analysis/Normed/Algebra/Exponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/Exponential.lean @@ -134,7 +134,7 @@ noncomputable irreducible_def exp (x : 𝔸) : 𝔸 := /-- The junk value when `𝔸` can't be equipped with a `ℚ`-algebra structure. -/ @[simp] theorem exp_of_isEmpty_algebra_rat [IsEmpty (Algebra ℚ 𝔸)] (x : 𝔸) : exp x = 1 := by - rw [exp, dif_neg (not_nonempty_iff.mpr ‹_›)] + rw [exp, dite_eq_right (not_nonempty_iff.mpr ‹_›)] theorem expSeries_apply_eq (x : 𝔸) (n : ℕ) : (expSeries 𝕂 𝔸 n fun _ => x) = (n !⁻¹ : 𝕂) • x ^ n := by simp [expSeries] @@ -157,7 +157,7 @@ theorem expSeries_eq_expSeries_rat [Algebra ℚ 𝔸] (n : ℕ) : variable (𝕂) in theorem exp_eq_expSeries_sum [CharZero 𝕂] : exp = (expSeries 𝕂 𝔸).sum := by ext x - rw [exp, dif_pos ⟨RestrictScalars.algebra ℚ 𝕂 𝔸⟩, ← @expSeries_sum_eq_rat (𝕂 := 𝕂)] + rw [exp, dite_eq_left ⟨RestrictScalars.algebra ℚ 𝕂 𝔸⟩, ← @expSeries_sum_eq_rat (𝕂 := 𝕂)] variable (𝕂) in theorem exp_eq_tsum [CharZero 𝕂] : exp = fun x : 𝔸 => ∑' n : ℕ, (n !⁻¹ : 𝕂) • x ^ n := by diff --git a/Mathlib/Analysis/Normed/Algebra/GelfandFormula.lean b/Mathlib/Analysis/Normed/Algebra/GelfandFormula.lean index a59139a0d7e80b..d1eccbf5bc656f 100644 --- a/Mathlib/Analysis/Normed/Algebra/GelfandFormula.lean +++ b/Mathlib/Analysis/Normed/Algebra/GelfandFormula.lean @@ -111,7 +111,7 @@ theorem limsup_pow_nnnorm_pow_one_div_le_spectralRadius (a : A) : simp only [p, p.radius_eq_liminf, ← norm_toNNReal, norm_mkPiRing] congr ext n - rw [norm_toNNReal, ENNReal.coe_rpow_def ‖a ^ n‖₊ (1 / n : ℝ), if_neg] + rw [norm_toNNReal, ENNReal.coe_rpow_def ‖a ^ n‖₊ (1 / n : ℝ), ite_eq_right] exact fun ha => (lt_self_iff_false _).mp (ha.2.trans_le (one_div_nonneg.mpr n.cast_nonneg : 0 ≤ (1 / n : ℝ))) have H₁ := (differentiableOn_inverse_one_sub_smul r_lt).hasFPowerSeriesOnBall r_pos diff --git a/Mathlib/Analysis/Normed/Group/AddCircle.lean b/Mathlib/Analysis/Normed/Group/AddCircle.lean index a4ef224dc8b9c1..a4fa707ec0a0a8 100644 --- a/Mathlib/Analysis/Normed/Group/AddCircle.lean +++ b/Mathlib/Analysis/Normed/Group/AddCircle.lean @@ -158,7 +158,7 @@ theorem coe_real_preimage_closedBall_inter_eq {x ε : ℝ} (s : Set ℝ) · rcases eq_or_ne p 0 with (rfl | hp) · simp only [abs_zero, zero_div] at hε simp only [not_lt.mpr hε, coe_real_preimage_closedBall_period_zero, abs_zero, zero_div, - if_false, inter_eq_right] + ite_false, inter_eq_right] exact hs.trans (closedBall_subset_closedBall <| by simp [hε]) simp [closedBall_eq_univ_of_half_period_le p hp (↑x) hε, not_lt.mpr hε] · suffices ∀ z : ℤ, closedBall (x + z • p) ε ∩ s = if z = 0 then closedBall x ε ∩ s else ∅ by @@ -168,7 +168,7 @@ theorem coe_real_preimage_closedBall_inter_eq {x ε : ℝ} (s : Set ℝ) simp only [Real.closedBall_eq_Icc] at hs ⊢ rcases eq_or_ne z 0 with (rfl | hz) · simp - simp only [hz, zsmul_eq_mul, if_false, eq_empty_iff_forall_notMem] + simp only [hz, zsmul_eq_mul, ite_false, eq_empty_iff_forall_notMem] rintro y ⟨⟨hy₁, hy₂⟩, hy₀⟩ obtain ⟨hy₃, hy₄⟩ := hs hy₀ rcases lt_trichotomy 0 p with (hp | (rfl : 0 = p) | hp) diff --git a/Mathlib/Analysis/Normed/Group/Seminorm.lean b/Mathlib/Analysis/Normed/Group/Seminorm.lean index 4216f3f0e604b5..d92a0068e1345f 100644 --- a/Mathlib/Analysis/Normed/Group/Seminorm.lean +++ b/Mathlib/Analysis/Normed/Group/Seminorm.lean @@ -435,11 +435,11 @@ variable [AddGroup E] [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ instance toOne [DecidableEq E] : One (AddGroupSeminorm E) := ⟨{ toFun := fun x => if x = 0 then 0 else 1 - map_zero' := if_pos rfl + map_zero' := ite_eq_left rfl add_le' := fun x y => by by_cases hx : x = 0 - · rw [if_pos hx, hx, zero_add, zero_add] - · rw [if_neg hx] + · rw [ite_eq_left hx, hx, zero_add, zero_add] + · rw [ite_eq_right hx] refine le_add_of_le_of_nonneg ?_ ?_ <;> split_ifs <;> norm_num neg' := fun x => by simp_rw [neg_eq_zero] }⟩ @@ -621,11 +621,11 @@ variable [Group E] [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] instance toOne [DecidableEq E] : One (GroupSeminorm E) := ⟨{ toFun := fun x => if x = 1 then 0 else 1 - map_one' := if_pos rfl + map_one' := ite_eq_left rfl mul_le' := fun x y => by by_cases hx : x = 1 - · rw [if_pos hx, hx, one_mul, zero_add] - · rw [if_neg hx] + · rw [ite_eq_left hx, hx, one_mul, zero_add] + · rw [ite_eq_right hx] refine le_add_of_le_of_nonneg ?_ ?_ <;> split_ifs <;> norm_num inv' := fun x => by simp_rw [inv_eq_one] }⟩ @@ -673,12 +673,12 @@ variable [AddGroup E] [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ instance [DecidableEq E] : One (NonarchAddGroupSeminorm E) := ⟨{ toFun := fun x => if x = 0 then 0 else 1 - map_zero' := if_pos rfl + map_zero' := ite_eq_left rfl add_le_max' := fun x y => by by_cases hx : x = 0 - · simp_rw [if_pos hx, hx, zero_add] + · simp_rw [ite_eq_left hx, hx, zero_add] exact le_max_of_le_right (le_refl _) - · simp_rw [if_neg hx] + · simp_rw [ite_eq_right hx] split_ifs <;> simp neg' := fun x => by simp_rw [neg_eq_zero] }⟩ diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 6961e020117a12..cc1b078c81ac74 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -264,12 +264,12 @@ variable {β} theorem edist_eq_card (f g : PiLp 0 β) : edist f g = {i | edist (f i) (g i) ≠ 0}.toFinite.toFinset.card := - if_pos rfl + ite_eq_left rfl theorem edist_eq_sum {p : ℝ≥0∞} (hp : 0 < p.toReal) (f g : PiLp p β) : edist f g = (∑ i, edist (f i) (g i) ^ p.toReal) ^ (1 / p.toReal) := let hp' := ENNReal.toReal_pos_iff.mp hp - (if_neg hp'.1.ne').trans (if_neg hp'.2.ne) + (ite_eq_right hp'.1.ne').trans (ite_eq_right hp'.2.ne) theorem edist_eq_iSup (f g : PiLp ∞ β) : edist f g = ⨆ i, edist (f i) (g i) := rfl @@ -319,12 +319,12 @@ variable {α} theorem dist_eq_card (f g : PiLp 0 α) : dist f g = {i | dist (f i) (g i) ≠ 0}.toFinite.toFinset.card := - if_pos rfl + ite_eq_left rfl theorem dist_eq_sum {p : ℝ≥0∞} (hp : 0 < p.toReal) (f g : PiLp p α) : dist f g = (∑ i, dist (f i) (g i) ^ p.toReal) ^ (1 / p.toReal) := let hp' := ENNReal.toReal_pos_iff.mp hp - (if_neg hp'.1.ne').trans (if_neg hp'.2.ne) + (ite_eq_right hp'.1.ne').trans (ite_eq_right hp'.2.ne) theorem dist_eq_iSup (f g : PiLp ∞ α) : dist f g = ⨆ i, dist (f i) (g i) := rfl @@ -348,14 +348,14 @@ instance instNorm : Norm (PiLp p β) where variable {p β} theorem norm_eq_card (f : PiLp 0 β) : ‖f‖ = {i | ‖f i‖ ≠ 0}.toFinite.toFinset.card := - if_pos rfl + ite_eq_left rfl theorem norm_eq_ciSup (f : PiLp ∞ β) : ‖f‖ = ⨆ i, ‖f i‖ := rfl theorem norm_eq_sum (hp : 0 < p.toReal) (f : PiLp p β) : ‖f‖ = (∑ i, ‖f i‖ ^ p.toReal) ^ (1 / p.toReal) := let hp' := ENNReal.toReal_pos_iff.mp hp - (if_neg hp'.1.ne').trans (if_neg hp'.2.ne) + (ite_eq_right hp'.1.ne').trans (ite_eq_right hp'.2.ne) end Norm diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 29f1a202217f7f..0d0b033fbd0b2c 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -184,12 +184,12 @@ variable {p α β} theorem prod_edist_eq_card (f g : WithLp 0 (α × β)) : edist f g = (if edist f.fst g.fst = 0 then 0 else 1) + (if edist f.snd g.snd = 0 then 0 else 1) := by - convert! if_pos rfl + convert! ite_eq_left rfl theorem prod_edist_eq_add (hp : 0 < p.toReal) (f g : WithLp p (α × β)) : edist f g = (edist f.fst g.fst ^ p.toReal + edist f.snd g.snd ^ p.toReal) ^ (1 / p.toReal) := let hp' := ENNReal.toReal_pos_iff.mp hp - (if_neg hp'.1.ne').trans (if_neg hp'.2.ne) + (ite_eq_right hp'.1.ne').trans (ite_eq_right hp'.2.ne) theorem prod_edist_eq_sup (f g : WithLp ∞ (α × β)) : edist f g = edist f.fst g.fst ⊔ edist f.snd g.snd := rfl @@ -249,12 +249,12 @@ variable {p α β} theorem prod_dist_eq_card (f g : WithLp 0 (α × β)) : dist f g = (if dist f.fst g.fst = 0 then 0 else 1) + (if dist f.snd g.snd = 0 then 0 else 1) := by - convert! if_pos rfl + convert! ite_eq_left rfl theorem prod_dist_eq_add (hp : 0 < p.toReal) (f g : WithLp p (α × β)) : dist f g = (dist f.fst g.fst ^ p.toReal + dist f.snd g.snd ^ p.toReal) ^ (1 / p.toReal) := let hp' := ENNReal.toReal_pos_iff.mp hp - (if_neg hp'.1.ne').trans (if_neg hp'.2.ne) + (ite_eq_right hp'.1.ne').trans (ite_eq_right hp'.2.ne) theorem prod_dist_eq_sup (f g : WithLp ∞ (α × β)) : dist f g = dist f.fst g.fst ⊔ dist f.snd g.snd := rfl @@ -285,14 +285,14 @@ variable {p α β} @[simp] theorem prod_norm_eq_card (f : WithLp 0 (α × β)) : ‖f‖ = (if ‖f.fst‖ = 0 then 0 else 1) + (if ‖f.snd‖ = 0 then 0 else 1) := by - convert! if_pos rfl + convert! ite_eq_left rfl theorem prod_norm_eq_sup (f : WithLp ∞ (α × β)) : ‖f‖ = ‖f.fst‖ ⊔ ‖f.snd‖ := rfl theorem prod_norm_eq_add (hp : 0 < p.toReal) (f : WithLp p (α × β)) : ‖f‖ = (‖f.fst‖ ^ p.toReal + ‖f.snd‖ ^ p.toReal) ^ (1 / p.toReal) := let hp' := ENNReal.toReal_pos_iff.mp hp - (if_neg hp'.1.ne').trans (if_neg hp'.2.ne) + (ite_eq_right hp'.1.ne').trans (ite_eq_right hp'.2.ne) end Norm diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index 360c64995326b7..89060c77846ffc 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -82,7 +82,7 @@ def Memℓp (f : ∀ i, E i) (p : ℝ≥0∞) : Prop := theorem memℓp_zero_iff {f : ∀ i, E i} : Memℓp f 0 ↔ Set.Finite { i | f i ≠ 0 } := by dsimp [Memℓp] - rw [if_pos rfl] + rw [ite_eq_left rfl] theorem memℓp_zero {f : ∀ i, E i} (hf : Set.Finite { i | f i ≠ 0 }) : Memℓp f 0 := memℓp_zero_iff.2 hf @@ -97,7 +97,7 @@ theorem memℓp_gen_iff (hp : 0 < p.toReal) {f : ∀ i, E i} : Memℓp f p ↔ Summable fun i => ‖f i‖ ^ p.toReal := by rw [ENNReal.toReal_pos_iff] at hp dsimp [Memℓp] - rw [if_neg hp.1.ne', if_neg hp.2.ne] + rw [ite_eq_right hp.1.ne', ite_eq_right hp.2.ne] theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by rcases p.trichotomy with (rfl | rfl | hp) @@ -447,7 +447,7 @@ instance : Norm (lp E p) where else if p = ∞ then ⨆ i, ‖f i‖ else (∑' i, ‖f i‖ ^ p.toReal) ^ (1 / p.toReal) theorem norm_eq_card_dsupport (f : lp E 0) : ‖f‖ = (lp.memℓp f).finite_dsupport.toFinset.card := - dif_pos rfl + dite_eq_left rfl theorem norm_eq_ciSup (f : lp E ∞) : ‖f‖ = ⨆ i, ‖f i‖ := rfl @@ -459,7 +459,7 @@ theorem norm_eq_tsum_rpow (hp : 0 < p.toReal) (f : lp E p) : ‖f‖ = (∑' i, ‖f i‖ ^ p.toReal) ^ (1 / p.toReal) := by dsimp [norm] rw [ENNReal.toReal_pos_iff] at hp - rw [dif_neg hp.1.ne', if_neg hp.2.ne] + rw [dite_eq_right hp.1.ne', ite_eq_right hp.2.ne] theorem norm_rpow_eq_tsum (hp : 0 < p.toReal) (f : lp E p) : ‖f‖ ^ p.toReal = ∑' i, ‖f i‖ ^ p.toReal := by @@ -1092,10 +1092,10 @@ protected theorem norm_sum_single (hp : 0 < p.toReal) (f : ∀ i, E i) (s : Fins refine (hasSum_norm hp (∑ i ∈ s, lp.single p i (f i))).unique ?_ simp only [lp.coeFn_single, coeFn_sum, Finset.sum_apply, Finset.sum_pi_single] have h : ∀ i ∉ s, ‖ite (i ∈ s) (f i) 0‖ ^ p.toReal = 0 := fun i hi ↦ by - simp [if_neg hi, Real.zero_rpow hp.ne'] + simp [ite_eq_right hi, Real.zero_rpow hp.ne'] have h' : ∀ i ∈ s, ‖f i‖ ^ p.toReal = ‖ite (i ∈ s) (f i) 0‖ ^ p.toReal := by intro i hi - rw [if_pos hi] + rw [ite_eq_left hi] simpa [Finset.sum_congr rfl h'] using hasSum_sum_of_ne_finset_zero h @[simp] @@ -1156,10 +1156,10 @@ protected theorem norm_sub_norm_compl_sub_single (hp : 0 < p.toReal) (f : lp E p suffices ‖f i‖ ^ p.toReal - ‖f i - ite (i ∈ s) (f i) 0‖ ^ p.toReal = 0 by simpa only [coeFn_sub, coeFn_sum, lp.coeFn_single, Pi.sub_apply, Finset.sum_apply, Finset.sum_pi_single, F] using this - simp only [if_neg hi, sub_zero, sub_self] + simp only [ite_eq_right hi, sub_zero, sub_self] have hF' : ∀ i ∈ s, F i = ‖f i‖ ^ p.toReal := by intro i hi - simp only [F, coeFn_sum, lp.single_apply, if_pos hi, sub_self, coeFn_sub, + simp only [F, coeFn_sum, lp.single_apply, ite_eq_left hi, sub_self, coeFn_sub, Pi.sub_apply, Finset.sum_apply, Finset.sum_pi_single, sub_eq_self] simp [Real.zero_rpow hp.ne'] have : HasSum F (∑ i ∈ s, F i) := hasSum_sum_of_ne_finset_zero hF diff --git a/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean b/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean index 45b7a67aea8a76..2306585dd783fe 100644 --- a/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean +++ b/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean @@ -131,12 +131,12 @@ theorem univBall_source (c : P) (r : ℝ) : (univBall c r).source = univ := by unfold univBall; split_ifs <;> rfl theorem univBall_target (c : P) {r : ℝ} (hr : 0 < r) : (univBall c r).target = ball c r := by - rw [univBall, dif_pos hr]; rfl + rw [univBall, dite_eq_left hr]; rfl theorem ball_subset_univBall_target (c : P) (r : ℝ) : ball c r ⊆ (univBall c r).target := by by_cases hr : 0 < r · rw [univBall_target c hr] - · rw [univBall, dif_neg hr] + · rw [univBall, dite_eq_right hr] exact subset_univ _ set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/Analysis/Normed/Module/Bases.lean b/Mathlib/Analysis/Normed/Module/Bases.lean index c84d8fb24ec193..7beeedeb53303d 100644 --- a/Mathlib/Analysis/Normed/Module/Bases.lean +++ b/Mathlib/Analysis/Normed/Module/Bases.lean @@ -179,7 +179,7 @@ theorem range_proj_eq_span (A : Finset β) : · rw [Submodule.span_le] rintro _ ⟨i, hi, rfl⟩ use b i - rw [ContinuousLinearMap.coe_coe, proj_apply_basis_mem, if_pos (Finset.mem_coe.mp hi)] + rw [ContinuousLinearMap.coe_coe, proj_apply_basis_mem, ite_eq_left (Finset.mem_coe.mp hi)] set_option backward.isDefEq.respectTransparency false in open scoped Classical in diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index bf0e33c34c151c..ac6832a0b303b3 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -192,7 +192,7 @@ theorem ContinuousLinearMap.continuous_det : Continuous fun f : E →L[𝕜] E = ((LinearMap.toMatrix b b).toLinearMap.comp (ContinuousLinearMap.coeLM 𝕜)).continuous_of_finiteDimensional · rw [LinearMap.det] - simpa only [h, MonoidHom.one_apply, dif_neg, not_false_iff] using continuous_const + simpa only [h, MonoidHom.one_apply, dite_eq_right, not_false_iff] using continuous_const /-- Any `K`-Lipschitz map from a subset `s` of a metric space `α` to a finite-dimensional real vector space `E'` can be extended to a Lipschitz map on the whole space `α`, with a slightly worse diff --git a/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean b/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean index a22e5d17858bcf..932be11a947f27 100644 --- a/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean @@ -124,12 +124,12 @@ instance [DecidableEq R] : One (RingSeminorm R) := ⟨{ (1 : AddGroupSeminorm R) with mul_le' := fun x y => by by_cases h : x * y = 0 - · refine (if_pos h).trans_le (mul_nonneg ?_ ?_) <;> + · refine (ite_eq_left h).trans_le (mul_nonneg ?_ ?_) <;> · change _ ≤ ite _ _ _ split_ifs exacts [le_rfl, zero_le_one] · change ite _ _ _ ≤ ite _ _ _ * ite _ _ _ - simp only [if_false, h, left_ne_zero_of_mul h, right_ne_zero_of_mul h, mul_one, + simp only [ite_false, h, left_ne_zero_of_mul h, right_ne_zero_of_mul h, mul_one, le_refl] }⟩ @[simp] @@ -308,7 +308,7 @@ variable [DecidableEq R] [NoZeroDivisors R] [Nontrivial R] every other element. -/ instance : One (MulRingSeminorm R) := ⟨{ (1 : AddGroupSeminorm R) with - map_one' := if_neg one_ne_zero + map_one' := ite_eq_right one_ne_zero map_mul' := fun x y => by obtain rfl | hx := eq_or_ne x 0 · simp diff --git a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean index 0c1f2dffc5eb86..a5fa1a70430784 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SpectralNorm.lean @@ -103,10 +103,10 @@ def spectralValueTerms (p : R[X]) : ℕ → ℝ := fun n : ℕ ↦ theorem spectralValueTerms_of_lt_natDegree (p : R[X]) {n : ℕ} (hn : n < p.natDegree) : spectralValueTerms p n = ‖p.coeff n‖ ^ (1 / (p.natDegree - n : ℝ)) := by - simp [spectralValueTerms, if_pos hn] + simp [spectralValueTerms, ite_eq_left hn] theorem spectralValueTerms_of_natDegree_le (p : R[X]) {n : ℕ} (hn : p.natDegree ≤ n) : - spectralValueTerms p n = 0 := by simp only [spectralValueTerms, if_neg (not_lt.mpr hn)] + spectralValueTerms p n = 0 := by simp only [spectralValueTerms, ite_eq_right (not_lt.mpr hn)] /-- The spectral value of a polynomial in `R[X]`, where `R` is a seminormed ring. One motivation for the spectral value: if the norm on `R` is nonarchimedean, and if a monic polynomial @@ -148,11 +148,11 @@ theorem spectralValue_X_sub_C (r : R) : spectralValue (X - C r) = ‖r‖ := by apply congr_arg ext n by_cases hn : n = 0 - · rw [if_pos hn, if_pos hn, hn, cast_zero, sub_zero, coeff_X_zero, coeff_C_zero, zero_sub, - norm_neg, inv_one, rpow_one] - · rw [if_neg hn, if_neg hn] + · rw [ite_eq_left hn, ite_eq_left hn, hn, cast_zero, sub_zero, coeff_X_zero, coeff_C_zero, + zero_sub, norm_neg, inv_one, rpow_one] + · rw [ite_eq_right hn, ite_eq_right hn] · apply ciSup_eq_of_forall_le_of_forall_lt_exists_gt (fun n ↦ ?_) - (fun _ hx ↦ ⟨0, by simp only [if_true, hx]⟩) + (fun _ hx ↦ ⟨0, by simp only [ite_true, hx]⟩) split_ifs · exact le_refl _ · exact norm_nonneg _ @@ -165,11 +165,11 @@ theorem spectralValue_X_pow (n : ℕ) : spectralValue (X ^ n : R[X]) = 0 := by convert! ciSup_const using 2 · ext m by_cases hmn : m < n - · rw [if_pos hmn, rpow_eq_zero_iff_of_nonneg (norm_nonneg _), if_neg (_root_.ne_of_lt hmn), - norm_zero, one_div, ne_eq, inv_eq_zero, ← cast_sub (le_of_lt hmn), cast_eq_zero, - Nat.sub_eq_zero_iff_le] + · rw [ite_eq_left hmn, rpow_eq_zero_iff_of_nonneg (norm_nonneg _), + ite_eq_right (_root_.ne_of_lt hmn), norm_zero, one_div, ne_eq, inv_eq_zero, + ← cast_sub (le_of_lt hmn), cast_eq_zero, Nat.sub_eq_zero_iff_le] exact ⟨Eq.refl _, not_le_of_gt hmn⟩ - · rw [if_neg hmn] + · rw [ite_eq_right hmn] · infer_instance end Seminormed @@ -250,7 +250,8 @@ theorem norm_root_le_spectralValue {f : AlgebraNorm K L} (hf_pm : IsPowMul f) rw [spectralValue, iSup, not_le, Set.Finite.csSup_lt_iff (spectralValueTerms_finite_range p) (Set.range_nonempty (spectralValueTerms p))] at h_ge have h_rg : ‖p.coeff n‖ ^ (1 / (p.natDegree - n : ℝ)) ∈ - Set.range (spectralValueTerms p) := by use n; simp only [spectralValueTerms, if_pos hn] + Set.range (spectralValueTerms p) := by + use n; simp only [spectralValueTerms, ite_eq_left hn] exact h_ge (‖p.coeff n‖₊ ^ (1 / (p.natDegree - n : ℝ))) h_rg rw [← hexp, ← rpow_natCast, ← rpow_natCast] gcongr @@ -303,10 +304,10 @@ theorem max_norm_root_eq_spectralValue [DecidableEq L] {f : AlgebraNorm K L} (hf · apply ciSup_le (fun x ↦ ?_) by_cases hx : x ∈ s · have hx0 : aeval x p = 0 := aeval_root_of_mapAlg_eq_multiset_prod_X_sub_C s hx hp - rw [if_pos hx] + rw [ite_eq_left hx] exact norm_root_le_spectralValue hf_pm hf_na (monic_of_monic_mapAlg (hp ▸ monic_multisetProd_X_sub_C s)) hx0 - · simp only [if_neg hx, spectralValue_nonneg _] + · simp only [ite_eq_right hx, spectralValue_nonneg _] · apply ciSup_le (fun m ↦ ?_) by_cases hm : m < p.natDegree · rw [spectralValueTerms_of_lt_natDegree _ hm] @@ -359,8 +360,8 @@ theorem max_norm_root_eq_spectralValue [DecidableEq L] {f : AlgebraNorm K L} (hf · exact hy_max _ h · exact apply_nonneg _ _ exact le_trans this (pow_le_pow_left₀ (apply_nonneg _ _) - (le_trans (by rw [if_pos hyx]) (le_ciSup h_bdd y)) _) - · simp only [spectralValueTerms, if_neg hm, h_le] + (le_trans (by rw [ite_eq_left hyx]) (le_ciSup h_bdd y)) _) + · simp only [spectralValueTerms, ite_eq_right hm, h_le] end BddBySpectralValue @@ -431,7 +432,7 @@ theorem spectralNorm_zero_lt {y : L} (hy : y ≠ 0) (hy_alg : IsAlgebraic K y) : rw [spectralNorm, ne_eq, eq_comm, spectralValue_eq_zero_iff (minpoly.monic hy_alg.isIntegral)] intro h apply minpoly.coeff_zero_ne_zero hy_alg.isIntegral hy - rw [h, coeff_X_pow, if_neg (ne_of_lt (minpoly.natDegree_pos hy_alg.isIntegral))] + rw [h, coeff_X_pow, ite_eq_right (ne_of_lt (minpoly.natDegree_pos hy_alg.isIntegral))] /-- If `spectralNorm K L x = 0`, then `x = 0`. -/ theorem eq_zero_of_map_spectralNorm_eq_zero {x : L} (hx : spectralNorm K L x = 0) diff --git a/Mathlib/Analysis/ODE/ExistUnique.lean b/Mathlib/Analysis/ODE/ExistUnique.lean index 62609142eb50b4..2e12f90333b350 100644 --- a/Mathlib/Analysis/ODE/ExistUnique.lean +++ b/Mathlib/Analysis/ODE/ExistUnique.lean @@ -89,10 +89,10 @@ theorem exists_forall_mem_closedBall_eq_hasDerivWithinAt_lipschitzOnWith refine ⟨α', fun x hx ↦ ⟨?_, fun t ht ↦ ?_⟩, ?_⟩ · rw [hα'] beta_reduce - rw [dif_pos hx, FunSpace.compProj_val, ← hα, FunSpace.next_apply₀] + rw [dite_eq_left hx, FunSpace.compProj_val, ← hα, FunSpace.next_apply₀] · rw [hα'] beta_reduce - rw [dif_pos hx, FunSpace.compProj_apply] + rw [dite_eq_left hx, FunSpace.compProj_apply] apply hasDerivWithinAt_picard_Icc t₀.2 hf.continuousOn_uncurry (α x hx |>.continuous_compProj.continuousOn) (fun _ ht' ↦ α x hx |>.compProj_mem_closedBall hf.mul_max_le) @@ -103,7 +103,7 @@ theorem exists_forall_mem_closedBall_eq_hasDerivWithinAt_lipschitzOnWith · obtain ⟨L', h⟩ := FunSpace.exists_forall_closedBall_funSpace_dist_le_mul hf refine ⟨L', fun t ht ↦ LipschitzOnWith.of_dist_le_mul fun x hx y hy ↦ ?_⟩ simp_rw [hα'] - rw [dif_pos hx, dif_pos hy, FunSpace.compProj_apply, FunSpace.compProj_apply, + rw [dite_eq_left hx, dite_eq_left hy, FunSpace.compProj_apply, FunSpace.compProj_apply, ← FunSpace.toContinuousMap_apply_eq_apply, ← FunSpace.toContinuousMap_apply_eq_apply] have : Nonempty (Icc tmin tmax) := ⟨t₀⟩ apply ContinuousMap.dist_le_iff_of_nonempty.mp diff --git a/Mathlib/Analysis/ODE/Gronwall.lean b/Mathlib/Analysis/ODE/Gronwall.lean index bedc58a9ea540b..114eb0afdc524a 100644 --- a/Mathlib/Analysis/ODE/Gronwall.lean +++ b/Mathlib/Analysis/ODE/Gronwall.lean @@ -44,11 +44,11 @@ noncomputable def gronwallBound (δ K ε x : ℝ) : ℝ := if K = 0 then δ + ε * x else δ * exp (K * x) + ε / K * (exp (K * x) - 1) theorem gronwallBound_K0 (δ ε : ℝ) : gronwallBound δ 0 ε = fun x => δ + ε * x := - funext fun _ => if_pos rfl + funext fun _ => ite_eq_left rfl theorem gronwallBound_of_K_ne_0 {δ K ε : ℝ} (hK : K ≠ 0) : gronwallBound δ K ε = fun x => δ * exp (K * x) + ε / K * (exp (K * x) - 1) := - funext fun _ => if_neg hK + funext fun _ => ite_eq_right hK theorem hasDerivAt_gronwallBound (δ K ε x : ℝ) : HasDerivAt (gronwallBound δ K ε) (K * gronwallBound δ K ε x + ε) x := by @@ -71,8 +71,8 @@ theorem hasDerivAt_gronwallBound_shift (δ K ε x a : ℝ) : theorem gronwallBound_x0 (δ K ε : ℝ) : gronwallBound δ K ε 0 = δ := by by_cases hK : K = 0 - · simp only [gronwallBound, if_pos hK, mul_zero, add_zero] - · simp only [gronwallBound, if_neg hK, mul_zero, exp_zero, sub_self, mul_one, + · simp only [gronwallBound, ite_eq_left hK, mul_zero, add_zero] + · simp only [gronwallBound, ite_eq_right hK, mul_zero, exp_zero, sub_self, mul_one, add_zero] theorem gronwallBound_ε0 (δ K x : ℝ) : gronwallBound δ K 0 x = δ * exp (K * x) := by diff --git a/Mathlib/Analysis/RCLike/Sqrt.lean b/Mathlib/Analysis/RCLike/Sqrt.lean index 020ba6d6ebe0bd..af203533819e7e 100644 --- a/Mathlib/Analysis/RCLike/Sqrt.lean +++ b/Mathlib/Analysis/RCLike/Sqrt.lean @@ -104,7 +104,7 @@ theorem RCLike.sqrt_of_nonneg {a : 𝕜} (ha : 0 ≤ a) : sqrt a = √(re a) := by obtain (h | h) := I_eq_zero_or_im_I_eq_one (K := 𝕜) · simp [h, sqrt_eq_ite] - rw [sqrt_eq_ite, dif_pos h, RingEquiv.symm_apply_eq, Complex.sqrt_of_nonneg (by simpa)] + rw [sqrt_eq_ite, dite_eq_left h, RingEquiv.symm_apply_eq, Complex.sqrt_of_nonneg (by simpa)] simp theorem Complex.sqrt_neg_of_nonneg {a : ℂ} (ha : 0 ≤ a) : @@ -119,7 +119,7 @@ theorem RCLike.sqrt_neg_of_nonneg {a : 𝕜} (ha : 0 ≤ a) : sqrt (-a) = I * sqrt a := by obtain (h | h) := I_eq_zero_or_im_I_eq_one (K := 𝕜) · simp [h, sqrt_eq_ite, Real.sqrt_eq_zero', nonneg_iff.mp ha] - rw [sqrt_eq_ite, dif_pos h, RingEquiv.symm_apply_eq, map_neg, + rw [sqrt_eq_ite, dite_eq_left h, RingEquiv.symm_apply_eq, map_neg, Complex.sqrt_neg_of_nonneg (by simpa)] simp [h, sqrt, map_mul] diff --git a/Mathlib/Analysis/Real/Hyperreal.lean b/Mathlib/Analysis/Real/Hyperreal.lean index 7ad28f7837eb2e..db619366ee763e 100644 --- a/Mathlib/Analysis/Real/Hyperreal.lean +++ b/Mathlib/Analysis/Real/Hyperreal.lean @@ -483,7 +483,7 @@ theorem IsSt.unique {x : ℝ*} {r s : ℝ} (hr : IsSt x r) (hs : IsSt x s) : r = @[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] theorem IsSt.st_eq {x : ℝ*} {r : ℝ} (hxr : IsSt x r) : st x = r := by have h : ∃ r, IsSt x r := ⟨r, hxr⟩ - rw [st, dif_pos h] + rw [st, dite_eq_left h] exact (Classical.choose_spec h).unique hxr @[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] @@ -497,7 +497,7 @@ theorem not_infinite_of_exists_st {x : ℝ*} : (∃ r : ℝ, IsSt x r) → ¬Inf @[deprecated stdPart_eq_zero (since := "2026-01-05")] theorem Infinite.st_eq {x : ℝ*} (hi : Infinite x) : st x = 0 := - dif_neg fun ⟨_r, hr⟩ ↦ hr.not_infinite hi + dite_eq_right fun ⟨_r, hr⟩ ↦ hr.not_infinite hi @[deprecated stdPart_eq_sSup (since := "2026-01-05")] theorem isSt_sSup {x : ℝ*} (hni : ¬Infinite x) : IsSt x (sSup { y : ℝ | (y : ℝ*) < x }) := by diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index eafc0f88c844ff..9f8388dcfc1062 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -524,7 +524,7 @@ noncomputable instance instSupSet : SupSet (Seminorm 𝕜 E) where protected theorem coe_sSup_eq' {s : Set <| Seminorm 𝕜 E} (hs : BddAbove ((↑) '' s : Set (E → ℝ))) : ↑(sSup s) = ⨆ p : s, ((p : Seminorm 𝕜 E) : E → ℝ) := - congr_arg _ (dif_pos hs) + congr_arg _ (dite_eq_left hs) protected theorem bddAbove_iff {s : Set <| Seminorm 𝕜 E} : BddAbove s ↔ BddAbove ((↑) '' s : Set (E → ℝ)) := diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Analytic.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Analytic.lean index 3b4689beba9938..7d0e12902aba98 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Analytic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Analytic.lean @@ -57,7 +57,7 @@ theorem AnalyticWithinAt.cpow (fa : AnalyticWithinAt ℂ f s x) (ga : AnalyticWi have e : (fun z ↦ f z ^ g z) =ᶠ[𝓝[insert x s] x] fun z ↦ exp (log (f z) * g z) := by filter_upwards [(fa.continuousWithinAt_insert.eventually_ne (slitPlane_ne_zero m))] intro z fz - simp only [fz, cpow_def, if_false] + simp only [fz, cpow_def, ite_false] apply AnalyticWithinAt.congr_of_eventuallyEq_insert _ e exact ((fa.clog m).mul ga).cexp diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean index fa3a40b9565e67..3e35b6ce3ab150 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean @@ -90,7 +90,7 @@ theorem arg_mul_cos_add_sin_mul_I {r : ℝ} (hr : 0 < r) {θ : ℝ} (hθ : θ simp only [re_ofReal_mul, im_ofReal_mul, neg_im, ← ofReal_cos, ← ofReal_sin, ← mk_eq_add_mul_I, neg_div, mul_div_cancel_left₀ _ hr.ne', mul_nonneg_iff_right_nonneg_of_pos hr] by_cases h₁ : θ ∈ Set.Icc (-(π / 2)) (π / 2) - · rw [if_pos] + · rw [ite_eq_left] exacts [Real.arcsin_sin' h₁, Real.cos_nonneg_of_mem_Icc h₁] · rw [Set.mem_Icc, not_and_or, not_le, not_le] at h₁ rcases h₁ with h₁ | h₁ @@ -99,13 +99,13 @@ theorem arg_mul_cos_add_sin_mul_I {r : ℝ} (hr : 0 < r) {θ : ℝ} (hθ : θ rw [← neg_pos, ← Real.cos_add_pi] refine Real.cos_pos_of_mem_Ioo ⟨?_, ?_⟩ <;> linarith have hsin : Real.sin θ < 0 := Real.sin_neg_of_neg_of_neg_pi_lt (by linarith) hθ - rw [if_neg, if_neg, ← Real.sin_add_pi, Real.arcsin_sin, add_sub_cancel_right] <;> [linarith; - linarith; exact hsin.not_ge; exact hcos.not_ge] + rw [ite_eq_right, ite_eq_right, ← Real.sin_add_pi, Real.arcsin_sin, + add_sub_cancel_right] <;> [linarith; linarith; exact hsin.not_ge; exact hcos.not_ge] · replace hθ := hθ.2 have hcos : Real.cos θ < 0 := Real.cos_neg_of_pi_div_two_lt_of_lt h₁ (by linarith) have hsin : 0 ≤ Real.sin θ := Real.sin_nonneg_of_mem_Icc ⟨by linarith, hθ⟩ - rw [if_neg, if_pos, ← Real.sin_sub_pi, Real.arcsin_sin, sub_add_cancel] <;> [linarith; - linarith; exact hsin; exact hcos.not_ge] + rw [ite_eq_right, ite_eq_left, ← Real.sin_sub_pi, Real.arcsin_sin, + sub_add_cancel] <;> [linarith; linarith; exact hsin; exact hcos.not_ge] theorem arg_cos_add_sin_mul_I {θ : ℝ} (hθ : θ ∈ Set.Ioc (-π) π) : arg (cos θ + sin θ * I) = θ := by rw [← one_mul (_ + _), ← ofReal_one, arg_mul_cos_add_sin_mul_I zero_lt_one hθ] @@ -285,15 +285,15 @@ theorem arg_eq_neg_pi_div_two_iff {z : ℂ} : arg z = -(π / 2) ↔ z.re = 0 ∧ simp theorem arg_of_re_nonneg {x : ℂ} (hx : 0 ≤ x.re) : arg x = Real.arcsin (x.im / ‖x‖) := - if_pos hx + ite_eq_left hx theorem arg_of_re_neg_of_im_nonneg {x : ℂ} (hx_re : x.re < 0) (hx_im : 0 ≤ x.im) : arg x = Real.arcsin ((-x).im / ‖x‖) + π := by - simp only [arg, hx_re.not_ge, hx_im, if_true, if_false] + simp only [arg, hx_re.not_ge, hx_im, ite_true, ite_false] theorem arg_of_re_neg_of_im_neg {x : ℂ} (hx_re : x.re < 0) (hx_im : x.im < 0) : arg x = Real.arcsin ((-x).im / ‖x‖) - π := by - simp only [arg, hx_re.not_ge, hx_im.not_ge, if_false] + simp only [arg, hx_re.not_ge, hx_im.not_ge, ite_false] theorem arg_of_im_nonneg_of_ne_zero {z : ℂ} (h₁ : 0 ≤ z.im) (h₂ : z ≠ 0) : arg z = Real.arccos (z.re / ‖z‖) := by @@ -603,7 +603,7 @@ theorem tendsto_arg_nhdsWithin_im_neg_of_re_neg_of_im_zero {z : ℂ} (hre : z.re refine H.congr' ?_ have : ∀ᶠ x : ℂ in 𝓝 z, x.re < 0 := continuous_re.tendsto z (gt_mem_nhds hre) filter_upwards [self_mem_nhdsWithin, mem_nhdsWithin_of_mem_nhds this] with _ him hre - rw [arg, if_neg hre.not_ge, if_neg him.not_ge] + rw [arg, ite_eq_right hre.not_ge, ite_eq_right him.not_ge] convert! (Real.continuousAt_arcsin.comp_continuousWithinAt ((continuous_im.continuousAt.comp_continuousWithinAt continuousWithinAt_neg).div @@ -619,7 +619,7 @@ theorem continuousWithinAt_arg_of_re_neg_of_im_zero {z : ℂ} (hre : z.re < 0) ( have : ∀ᶠ x : ℂ in 𝓝 z, x.re < 0 := continuous_re.tendsto z (gt_mem_nhds hre) filter_upwards [self_mem_nhdsWithin (s := { z : ℂ | 0 ≤ z.im }), mem_nhdsWithin_of_mem_nhds this] with _ him hre - rw [arg, if_neg hre.not_ge, if_pos him] + rw [arg, ite_eq_right hre.not_ge, ite_eq_left him] refine ContinuousWithinAt.congr_of_eventuallyEq ?_ this ?_ · refine (Real.continuousAt_arcsin.comp_continuousWithinAt @@ -628,7 +628,7 @@ theorem continuousWithinAt_arg_of_re_neg_of_im_zero {z : ℂ} (hre : z.re < 0) ( tendsto_const_nhds lift z to ℝ using him simpa using hre.ne - · rw [arg, if_neg hre.not_ge, if_pos him.ge] + · rw [arg, ite_eq_right hre.not_ge, ite_eq_left him.ge] theorem tendsto_arg_nhdsWithin_im_nonneg_of_re_neg_of_im_zero {z : ℂ} (hre : z.re < 0) (him : z.im = 0) : Tendsto arg (𝓝[{ z : ℂ | 0 ≤ z.im }] z) (𝓝 π) := by diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean index ad59ce75e0c508..40691837719a7f 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean @@ -121,7 +121,7 @@ theorem log_conj_eq_ite (x : ℂ) : log (conj x) = if x.arg = π then log x else simp_rw [ofReal_neg, conj_I, mul_neg, neg_mul] theorem log_conj (x : ℂ) (h : x.arg ≠ π) : log (conj x) = conj (log x) := by - rw [log_conj_eq_ite, if_neg h] + rw [log_conj_eq_ite, ite_eq_right h] theorem log_inv_eq_ite (x : ℂ) : log x⁻¹ = if x.arg = π then -conj (log x) else -log x := by by_cases hx : x = 0 @@ -134,7 +134,8 @@ theorem log_inv_eq_ite (x : ℂ) : log x⁻¹ = if x.arg = π then -conj (log x) · rwa [inv_pos, Complex.normSq_pos] · rwa [map_ne_zero] -theorem log_inv (x : ℂ) (hx : x.arg ≠ π) : log x⁻¹ = -log x := by rw [log_inv_eq_ite, if_neg hx] +theorem log_inv (x : ℂ) (hx : x.arg ≠ π) : log x⁻¹ = -log x := by + rw [log_inv_eq_ite, ite_eq_right hx] theorem two_pi_I_ne_zero : (2 * π * I : ℂ) ≠ 0 := by simp [Real.pi_ne_zero, I_ne_zero] diff --git a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean index 42fc2904160ec0..e89bbaa039dfbe 100644 --- a/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean +++ b/Mathlib/Analysis/SpecialFunctions/Elliptic/Weierstrass.lean @@ -293,7 +293,7 @@ lemma weierstrassPExcept_of_notMem (l₀ : ℂ) (hl : l₀ ∉ L.lattice) : lemma hasSumLocallyUniformly_weierstrassP : HasSumLocallyUniformly (fun (l : L.lattice) (z : ℂ) ↦ 1 / (z - ↑l) ^ 2 - 1 / l ^ 2) ℘[L] := by convert! L.hasSumLocallyUniformly_weierstrassPExcept (L.ω₁ / 2) using 3 with l - · rw [if_neg]; exact fun e ↦ L.ω₁_div_two_notMem_lattice (e ▸ l.2) + · rw [ite_eq_right]; exact fun e ↦ L.ω₁_div_two_notMem_lattice (e ▸ l.2) · rw [L.weierstrassPExcept_of_notMem _ L.ω₁_div_two_notMem_lattice] lemma hasSum_weierstrassP (z : ℂ) : @@ -544,7 +544,7 @@ lemma derivWeierstrassPExcept_of_notMem (l₀ : ℂ) (hl : l₀ ∉ L.lattice) : lemma hasSumLocallyUniformly_derivWeierstrassP : HasSumLocallyUniformly (fun (l : L.lattice) (z : ℂ) ↦ - 2 / (z - l) ^ 3) ℘'[L] := by convert! L.hasSumLocallyUniformly_derivWeierstrassPExcept (L.ω₁ / 2) using 3 with l z - · rw [if_neg, neg_div]; exact fun e ↦ L.ω₁_div_two_notMem_lattice (e ▸ l.2) + · rw [ite_eq_right, neg_div]; exact fun e ↦ L.ω₁_div_two_notMem_lattice (e ▸ l.2) · rw [L.derivWeierstrassPExcept_of_notMem _ L.ω₁_div_two_notMem_lattice] lemma hasSum_derivWeierstrassP (z : ℂ) : @@ -932,7 +932,7 @@ lemma order_weierstrassP (l₀ : ℂ) (h : l₀ ∈ L.lattice) : · filter_upwards [self_mem_nhdsWithin] with z (hz : _ ≠ _) have : (z - l₀) ^ 2 ≠ 0 := by simpa [sub_eq_zero] simp [← L.ite_eq_one_sub_sq_mul_weierstrassP l₀ h, - if_neg hz, inv_mul_cancel_left₀ this, zpow_ofNat] + ite_eq_right hz, inv_mul_cancel_left₀ this, zpow_ofNat] · norm_num end Analytic @@ -971,7 +971,7 @@ private lemma meromorphic_relation : Meromorphic L.relation := by refine fun z ↦ (this _).congr ?_ filter_upwards [self_mem_nhdsWithin, mem_nhdsWithin_of_mem_nhds (L.compl_lattice_sdiff_singleton_mem_nhds _)] with w hw hw' - rw [relation, if_neg (by simp_all)] + rw [relation, ite_eq_right (by simp_all)] private lemma relation_mul_id_pow_six_eventuallyEq : (L.relation * id ^ 6) =ᶠ[nhds 0] fun z ↦ @@ -1069,7 +1069,7 @@ private lemma relation_eq_zero : L.relation = 0 := by have : Differentiable ℂ L.relation := fun x ↦ (L.analyticAt_relation x).differentiableAt exact (this.apply_eq_apply_of_bounded (IsZLattice.isCompact_range_of_periodic L.lattice _ this.continuous fun z w hw ↦ by lift w to L.lattice using hw; simp).isBounded x 0).trans - (if_pos (by simp)) + (ite_eq_left (by simp)) /-- `℘'(z)² = 4 ℘(z)³ - g₂ ℘(z) - g₃` -/ lemma derivWeierstrassP_sq (z : ℂ) (hz : z ∉ L.lattice) : diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean index 2776daac653ac8..d7c647e3cdbe4b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -45,7 +45,7 @@ noncomputable def log (x : ℝ) : ℝ := if hx : x = 0 then 0 else expOrderIso.symm ⟨|x|, abs_pos.2 hx⟩ theorem log_of_ne_zero (hx : x ≠ 0) : log x = expOrderIso.symm ⟨|x|, abs_pos.2 hx⟩ := - dif_neg hx + dite_eq_right hx theorem log_of_pos (hx : 0 < x) : log x = expOrderIso.symm ⟨x, hx⟩ := by rw [log_of_ne_zero hx.ne'] @@ -66,7 +66,7 @@ theorem exp_log_of_neg (hx : x < 0) : exp (log x) = -x := by theorem le_exp_log (x : ℝ) : x ≤ exp (log x) := by by_cases h_zero : x = 0 - · rw [h_zero, log, dif_pos rfl, exp_zero] + · rw [h_zero, log, dite_eq_left rfl, exp_zero] exact zero_le_one · rw [exp_log_eq_abs h_zero] exact le_abs_self _ @@ -101,7 +101,7 @@ theorem range_log : range log = univ := @[simp, push] theorem log_zero : log 0 = 0 := - dif_pos rfl + dite_eq_left rfl @[simp, push] theorem log_one : log 1 = 0 := diff --git a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLog.lean b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLog.lean index 5be24a87bf35ec..129eac56036325 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLog.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLog.lean @@ -48,20 +48,20 @@ noncomputable def log (x : ℝ≥0∞) : EReal := else if x = ⊤ then ⊤ else Real.log x.toReal -@[simp] lemma log_zero : log 0 = ⊥ := if_pos rfl +@[simp] lemma log_zero : log 0 = ⊥ := ite_eq_left rfl @[simp] lemma log_one : log 1 = 0 := by simp [log] @[simp] lemma log_top : log ⊤ = ⊤ := rfl @[simp] lemma log_ofReal (x : ℝ) : log (ENNReal.ofReal x) = if x ≤ 0 then ⊥ else ↑(Real.log x) := by simp only [log, ENNReal.ofReal_ne_top, - ENNReal.ofReal_eq_zero, if_false] + ENNReal.ofReal_eq_zero, ite_false] split_ifs with h_nonpos · rfl · rw [ENNReal.toReal_ofReal (not_le.mp h_nonpos).le] lemma log_ofReal_of_pos {x : ℝ} (hx : 0 < x) : log (ENNReal.ofReal x) = Real.log x := by - rw [log_ofReal, if_neg hx.not_ge] + rw [log_ofReal, ite_eq_right hx.not_ge] theorem log_pos_real {x : ℝ≥0∞} (h : x ≠ 0) (h' : x ≠ ⊤) : log x = Real.log (ENNReal.toReal x) := by simp [log, h, h'] @@ -153,7 +153,7 @@ theorem log_mul_add {x y : ℝ≥0∞} : log (x * y) = log x + log y := by theorem log_rpow {x : ℝ≥0∞} {y : ℝ} : log (x ^ y) = y * log x := by rcases lt_trichotomy y 0 with (y_neg | rfl | y_pos) · rcases ENNReal.trichotomy x with (rfl | rfl | x_real) - · simp only [ENNReal.zero_rpow_def y, not_lt_of_gt y_neg, y_neg.ne, if_false, log_top, + · simp only [ENNReal.zero_rpow_def y, not_lt_of_gt y_neg, y_neg.ne, ite_false, log_top, log_zero, EReal.coe_mul_bot_of_neg y_neg] · rw [ENNReal.top_rpow_of_neg y_neg, log_zero, log_top, EReal.coe_mul_top_of_neg y_neg] · have x_ne_zero := (ENNReal.toReal_pos_iff.1 x_real).1.ne' diff --git a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean index b1163b6cf30f7d..d2c54df91df268 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/ENNRealLogExp.lean @@ -41,7 +41,7 @@ section LogExp @[simp] lemma EReal.log_exp (x : EReal) : log (exp x) = x := by induction x · simp - · rw [exp_coe, log_ofReal, if_neg (not_le.mpr (Real.exp_pos _)), Real.log_exp] + · rw [exp_coe, log_ofReal, ite_eq_right (not_le.mpr (Real.exp_pos _)), Real.log_exp] · simp @[simp] lemma ENNReal.exp_log (x : ℝ≥0∞) : exp (log x) = x := by diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean index 3aac623dd59cb2..6a030eb487801a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Complex.lean @@ -36,7 +36,7 @@ theorem cpow_def (x y : ℂ) : x ^ y = if x = 0 then if y = 0 then 1 else 0 else rfl theorem cpow_def_of_ne_zero {x : ℂ} (hx : x ≠ 0) (y : ℂ) : x ^ y = exp (log x * y) := - if_neg hx + ite_eq_right hx @[simp] theorem cpow_zero (x : ℂ) : x ^ (0 : ℂ) = 1 := by simp [cpow_def] @@ -59,7 +59,7 @@ theorem zero_cpow {x : ℂ} (h : x ≠ 0) : (0 : ℂ) ^ x = 0 := by simp [cpow_d theorem zero_cpow_eq_iff {x : ℂ} {a : ℂ} : (0 : ℂ) ^ x = a ↔ x ≠ 0 ∧ a = 0 ∨ x = 0 ∧ a = 1 := by constructor · intro hyp - simp only [cpow_def, if_true] at hyp + simp only [cpow_def, ite_true] at hyp grind · rintro (⟨h, rfl⟩ | ⟨rfl, rfl⟩) · exact zero_cpow h @@ -71,7 +71,8 @@ theorem eq_zero_cpow_iff {x : ℂ} {a : ℂ} : a = (0 : ℂ) ^ x ↔ x ≠ 0 ∧ @[simp] theorem cpow_one (x : ℂ) : x ^ (1 : ℂ) = x := if hx : x = 0 then by simp [hx, cpow_def] - else by rw [cpow_def, if_neg (one_ne_zero : (1 : ℂ) ≠ 0), if_neg hx, mul_one, exp_log hx] + else by + rw [cpow_def, ite_eq_right (one_ne_zero : (1 : ℂ) ≠ 0), ite_eq_right hx, mul_one, exp_log hx] @[simp] theorem one_cpow (x : ℂ) : (1 : ℂ) ^ x = 1 := by @@ -212,7 +213,7 @@ theorem inv_cpow_eq_ite (x : ℂ) (n : ℂ) : split_ifs with hx hn ha ha <;> rfl theorem inv_cpow (x : ℂ) (n : ℂ) (hx : x.arg ≠ π) : x⁻¹ ^ n = (x ^ n)⁻¹ := by - rw [inv_cpow_eq_ite, if_neg hx] + rw [inv_cpow_eq_ite, ite_eq_right hx] lemma inv_cpow_ofReal_nonneg {a : ℝ} (ha : 0 ≤ a) (r : ℂ) : ((a : ℂ)⁻¹) ^ r = (a ^ r : ℂ)⁻¹ := @@ -238,7 +239,7 @@ theorem conj_cpow_eq_ite (x : ℂ) (n : ℂ) : split_ifs with hcx hn hx <;> rfl theorem conj_cpow (x : ℂ) (n : ℂ) (hx : x.arg ≠ π) : conj x ^ n = conj (x ^ conj n) := by - rw [conj_cpow_eq_ite, if_neg hx] + rw [conj_cpow_eq_ite, ite_eq_right hx] theorem cpow_conj (x : ℂ) (n : ℂ) (hx : x.arg ≠ π) : x ^ conj n = conj (conj x ^ n) := by rw [conj_cpow _ _ hx, conj_conj] diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean b/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean index 6e98036e4a5139..45f5d4907a68bc 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/NNReal.lean @@ -559,7 +559,7 @@ theorem rpow_ofNNReal {M : ℝ≥0} {P : ℝ} (hP : 0 ≤ P) : (M : ℝ≥0∞) @[simp] theorem rpow_one (x : ℝ≥0∞) : x ^ (1 : ℝ) = x := by cases x - · exact dif_pos zero_lt_one + · exact dite_eq_left zero_lt_one · change ite _ _ _ = _ simp only [NNReal.rpow_one, ite_eq_right_iff, top_ne_coe, and_imp] exact fun _ => zero_le_one.not_gt diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean index 4fa7722f332deb..33f77bc8acc192 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean @@ -49,7 +49,7 @@ theorem rpow_def_of_nonneg {x : ℝ} (hx : 0 ≤ x) (y : ℝ) : (Complex.ofReal_mul _ _).symm, Complex.exp_ofReal_re, Complex.ofReal_eq_zero] theorem rpow_def_of_pos {x : ℝ} (hx : 0 < x) (y : ℝ) : x ^ y = exp (log x * y) := by - rw [rpow_def_of_nonneg (le_of_lt hx), if_neg (ne_of_gt hx)] + rw [rpow_def_of_nonneg (le_of_lt hx), ite_eq_right (ne_of_gt hx)] theorem exp_mul (x y : ℝ) : exp (x * y) = exp x ^ y := by rw [rpow_def_of_pos (exp_pos _), log_exp] @@ -93,7 +93,7 @@ lemma rpow_ne_zero (hx : 0 ≤ x) (hy : y ≠ 0) : x ^ y ≠ 0 ↔ x ≠ 0 := by open Real theorem rpow_def_of_neg {x : ℝ} (hx : x < 0) (y : ℝ) : x ^ y = exp (log x * y) * cos (y * π) := by - rw [rpow_def, Complex.cpow_def, if_neg] + rw [rpow_def, Complex.cpow_def, ite_eq_right] · have : Complex.log x * y = ↑(log (-x) * y) + ↑(y * π) * Complex.I := by simp only [Complex.log, Complex.norm_real, norm_eq_abs, abs_of_neg hx, log_neg_eq_log, Complex.arg_ofReal_of_neg hx, Complex.ofReal_mul] diff --git a/Mathlib/Analysis/SpecificLimits/Basic.lean b/Mathlib/Analysis/SpecificLimits/Basic.lean index 3e6f9b38f9ce90..26bdd0fae5f72e 100644 --- a/Mathlib/Analysis/SpecificLimits/Basic.lean +++ b/Mathlib/Analysis/SpecificLimits/Basic.lean @@ -610,7 +610,7 @@ theorem Set.Countable.exists_pos_hasSum_le {ι : Type*} {s : Set ι} (hs : s.Cou · conv_rhs => simp split_ifs exacts [hf0 _, zero_lt_one] - · simpa only [Subtype.coe_prop, dif_pos, Subtype.coe_eta] + · simpa only [Subtype.coe_prop, dite_eq_left, Subtype.coe_eta] theorem Set.Countable.exists_pos_forall_sum_le {ι : Type*} {s : Set ι} (hs : s.Countable) {ε : ℝ} (hε : 0 < ε) : ∃ ε' : ι → ℝ, diff --git a/Mathlib/Analysis/SpecificLimits/Normed.lean b/Mathlib/Analysis/SpecificLimits/Normed.lean index deecc84a1b3899..a08f973615f5ef 100644 --- a/Mathlib/Analysis/SpecificLimits/Normed.lean +++ b/Mathlib/Analysis/SpecificLimits/Normed.lean @@ -605,7 +605,7 @@ theorem NormedAddCommGroup.cauchy_series_of_le_geometric'' {C : ℝ} {u : ℕ (mul_nonneg_iff_of_pos_right <| pow_pos hr₀ N).mp ((norm_nonneg _).trans <| h N <| le_refl N) have : ∀ n ≥ N, u n = v n := by intro n hn - simp [v, if_neg (not_lt.mpr hn)] + simp [v, ite_eq_right (not_lt.mpr hn)] apply cauchySeq_sum_of_eventually_eq this (NormedAddCommGroup.cauchy_series_of_le_geometric' hr₁ _) · exact C diff --git a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean index fa4de714fb932a..5f22186bb1930e 100644 --- a/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean +++ b/Mathlib/CategoryTheory/Abelian/GrothendieckCategory/EnoughInjectives.lean @@ -163,12 +163,12 @@ noncomputable def largerSubobject (A : Subobject X) : Subobject X := variable (X) in @[simp] -lemma largerSubobject_top : largerSubobject hG (⊤ : Subobject X) = ⊤ := dif_pos rfl +lemma largerSubobject_top : largerSubobject hG (⊤ : Subobject X) = ⊤ := dite_eq_left rfl lemma lt_largerSubobject (A : Subobject X) (hA : A ≠ ⊤) : A < largerSubobject hG A := by dsimp only [largerSubobject] - rw [dif_neg hA] + rw [dite_eq_right hA] exact (exists_larger_subobject hG A hA).choose_spec.choose lemma le_largerSubobject (A : Subobject X) : @@ -193,7 +193,7 @@ lemma pushouts_ofLE_le_largerSubobject (A : Subobject X) : · refine (MorphismProperty.arrow_mk_iso_iff _ ?_).1 (exists_larger_subobject hG A hA).choose_spec.choose_spec exact Arrow.isoMk (Iso.refl _) - (Subobject.isoOfEq _ _ ((by simp [largerSubobject, dif_neg hA]))) + (Subobject.isoOfEq _ _ ((by simp [largerSubobject, dite_eq_right hA]))) variable [IsGrothendieckAbelian.{w} C] diff --git a/Mathlib/CategoryTheory/Extensive.lean b/Mathlib/CategoryTheory/Extensive.lean index e1d2ab84770354..06c6e3d08a3d69 100644 --- a/Mathlib/CategoryTheory/Extensive.lean +++ b/Mathlib/CategoryTheory/Extensive.lean @@ -506,7 +506,7 @@ lemma FinitaryPreExtensive.hasPullbacks_of_is_coproduct [FinitaryPreExtensive C] · simp only [coprod.desc_comp, colimit.ι_desc, Cofan.mk_ι_app, eqToHom_refl, Category.id_comp, dite_true, BinaryCofan.ι_app_right, BinaryCofan.mk_inr, colimit.ι_desc_assoc, Discrete.functor_obj, Category.comp_id] - exact dif_neg j.prop } + exact dite_eq_right j.prop } let e' : c.pt ≅ f i ⨿ (∐ fun j : ({i}ᶜ : Set ι) ↦ f j) := hc.coconePointUniqueUpToIso (getColimitCocone _).2 ≪≫ e have : coprod.inl ≫ e'.inv = c.ι.app ⟨i⟩ := by diff --git a/Mathlib/CategoryTheory/GlueData.lean b/Mathlib/CategoryTheory/GlueData.lean index d18b4505c3aa82..0c1b3437fd4913 100644 --- a/Mathlib/CategoryTheory/GlueData.lean +++ b/Mathlib/CategoryTheory/GlueData.lean @@ -381,7 +381,7 @@ open scoped Classical in /-- (Implementation detail) the constructed `GlueData.f` from a `GlueData'`. -/ abbrev GlueData'.f' (D : GlueData' C) (i j : D.J) : (if h : i = j then D.U i else D.V i j h) ⟶ D.U i := - if h : i = j then eqToHom (dif_pos h) else eqToHom (dif_neg h) ≫ D.f i j h + if h : i = j then eqToHom (dite_eq_left h) else eqToHom (dite_eq_right h) ≫ D.f i j h instance (D : GlueData' C) (i j : D.J) : Mono (D.f' i j) := by dsimp [GlueData'.f']; split_ifs <;> infer_instance @@ -393,11 +393,11 @@ instance (D : GlueData' C) (i j k : D.J) : HasPullback (D.f' i j) (D.f' i k) := by if hij : i = j then apply +allowSynthFailures hasPullback_of_left_iso - simp only [GlueData'.f', dif_pos hij] + simp only [GlueData'.f', dite_eq_left hij] infer_instance else if hik : i = k then apply +allowSynthFailures hasPullback_of_right_iso - simp only [GlueData'.f', dif_pos hik] + simp only [GlueData'.f', dite_eq_left hik] infer_instance else have {X Y Z : C} (f : X ⟶ Y) (e : Z = X) : eqToHom e ≫ f ≍ f := by subst e; simp @@ -414,18 +414,18 @@ def GlueData'.t'' (D : GlueData' C) (i j k : D.J) : else if hik : i = k then have : IsIso (pullback.snd (D.f' j k) (D.f' j i)) := by subst hik; infer_instance - pullback.fst _ _ ≫ eqToHom (dif_neg hij) ≫ D.t _ _ _ ≫ - eqToHom (dif_neg (Ne.symm hij)).symm ≫ inv (pullback.snd _ _) + pullback.fst _ _ ≫ eqToHom (dite_eq_right hij) ≫ D.t _ _ _ ≫ + eqToHom (dite_eq_right (Ne.symm hij)).symm ≫ inv (pullback.snd _ _) else if hjk : j = k then have : IsIso (pullback.snd (D.f' j k) (D.f' j i)) := by apply +allowSynthFailures pullback_snd_iso_of_left_iso simp only [hjk, GlueData'.f', ↓reduceDIte] infer_instance - pullback.fst _ _ ≫ eqToHom (dif_neg hij) ≫ D.t _ _ _ ≫ - eqToHom (dif_neg (Ne.symm hij)).symm ≫ inv (pullback.snd _ _) + pullback.fst _ _ ≫ eqToHom (dite_eq_right hij) ≫ D.t _ _ _ ≫ + eqToHom (dite_eq_right (Ne.symm hij)).symm ≫ inv (pullback.snd _ _) else haveI := Ne.symm hij - pullback.map _ _ _ _ (eqToHom (by aesop)) (eqToHom (by rw [dif_neg hik])) + pullback.map _ _ _ _ (eqToHom (by aesop)) (eqToHom (by rw [dite_eq_right hik])) (eqToHom (by simp)) (by delta f'; aesop) (by delta f'; aesop) ≫ D.t' i j k hij hik hjk ≫ pullback.map _ _ _ _ (eqToHom (by aesop)) (eqToHom (by aesop)) (eqToHom (by simp)) @@ -444,7 +444,7 @@ def GlueData.ofGlueData' (D : GlueData' C) : GlueData C where f i j := D.f' i j f_id i := by simp only [↓reduceDIte, GlueData'.f']; infer_instance t i j := if h : i = j then eqToHom (by simp [h]) else - eqToHom (dif_neg h) ≫ D.t i j h ≫ eqToHom (dif_neg (Ne.symm h)).symm + eqToHom (dite_eq_right h) ≫ D.t i j h ≫ eqToHom (dite_eq_right (Ne.symm h)).symm t_id i := by simp t' := D.t'' t_fac i j k := by diff --git a/Mathlib/CategoryTheory/GradedObject.lean b/Mathlib/CategoryTheory/GradedObject.lean index 097e1ec4ae9fc9..d9092650a09a04 100644 --- a/Mathlib/CategoryTheory/GradedObject.lean +++ b/Mathlib/CategoryTheory/GradedObject.lean @@ -502,9 +502,9 @@ noncomputable def ιMapObjOrZero : X i ⟶ X.mapObj p j := then X.ιMapObj p i j h else 0 -lemma ιMapObjOrZero_eq (h : p i = j) : X.ιMapObjOrZero p i j = X.ιMapObj p i j h := dif_pos h +lemma ιMapObjOrZero_eq (h : p i = j) : X.ιMapObjOrZero p i j = X.ιMapObj p i j h := dite_eq_left h -lemma ιMapObjOrZero_eq_zero (h : p i ≠ j) : X.ιMapObjOrZero p i j = 0 := dif_neg h +lemma ιMapObjOrZero_eq_zero (h : p i ≠ j) : X.ιMapObjOrZero p i j = 0 := dite_eq_right h variable {X Y} in @[reassoc (attr := simp)] diff --git a/Mathlib/CategoryTheory/GradedObject/Single.lean b/Mathlib/CategoryTheory/GradedObject/Single.lean index 69eeb93aed8511..6885955517576b 100644 --- a/Mathlib/CategoryTheory/GradedObject/Single.lean +++ b/Mathlib/CategoryTheory/GradedObject/Single.lean @@ -31,8 +31,8 @@ and the initial object in other degrees. -/ noncomputable def single (j : J) : C ⥤ GradedObject J C where obj X i := if i = j then X else ⊥_ C map {X₁ X₂} f i := - if h : i = j then eqToHom (if_pos h) ≫ f ≫ eqToHom (if_pos h).symm - else eqToHom (by dsimp; rw [if_neg h, if_neg h]) + if h : i = j then eqToHom (ite_eq_left h) ≫ f ≫ eqToHom (ite_eq_left h).symm + else eqToHom (by dsimp; rw [ite_eq_right h, ite_eq_right h]) variable (J) in /-- The functor which sends `X : C` to the graded object which is `X` in degree `0` @@ -41,7 +41,7 @@ noncomputable abbrev single₀ [Zero J] : C ⥤ GradedObject J C := single 0 /-- The canonical isomorphism `(single j).obj X i ≅ X` when `i = j`. -/ noncomputable def singleObjApplyIsoOfEq (j : J) (X : C) (i : J) (h : i = j) : - (single j).obj X i ≅ X := eqToIso (if_pos h) + (single j).obj X i ≅ X := eqToIso (ite_eq_left h) /-- The canonical isomorphism `(single j).obj X j ≅ X`. -/ noncomputable abbrev singleObjApplyIso (j : J) (X : C) : @@ -51,7 +51,7 @@ noncomputable abbrev singleObjApplyIso (j : J) (X : C) : noncomputable def isInitialSingleObjApply (j : J) (X : C) (i : J) (h : i ≠ j) : IsInitial ((single j).obj X i) := by dsimp [single] - rw [if_neg h] + rw [ite_eq_right h] exact initialIsInitial lemma singleObjApplyIsoOfEq_inv_single_map (j : J) {X Y : C} (f : X ⟶ Y) (i : J) (h : i = j) : diff --git a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean index 2a327c9b543094..40ab0e87505352 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean @@ -83,7 +83,7 @@ lemma ι_sigmaConstCokernelCofork_π (b : β) (hb : b ∉ Set.range f) : Sigma.ι (fun _ ↦ R) ⟨b, hb⟩ := by dsimp [sigmaConstCokernelCofork] rw [Sigma.ι_desc] - apply dif_pos + apply dite_eq_left set_option backward.defeqAttrib.useBackward true in @[reassoc (attr := simp)] @@ -91,7 +91,7 @@ lemma ι_sigmaConstCokernelCofork_π_eq_zero (a : α) : dsimp% Sigma.ι (fun _ ↦ R) (f a) ≫ (sigmaConstCokernelCofork R f).π = 0 := by dsimp [sigmaConstCokernelCofork] rw [Sigma.ι_desc] - exact dif_neg (by simp) + exact dite_eq_right (by simp) set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index a8a145aa2c543e..69e945fbc9a2ec 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -753,10 +753,10 @@ theorem biproduct.fromSubtype_π [DecidablePred p] (j : J) : ext i rw [biproduct.fromSubtype, biproduct.ι_desc_assoc, biproduct.ι_π] by_cases h : p j - · rw [dif_pos h, biproduct.ι_π] + · rw [dite_eq_left h, biproduct.ι_π] split_ifs with h₁ h₂ h₂ exacts [rfl, False.elim (h₂ (Subtype.ext h₁)), False.elim (h₁ (congr_arg Subtype.val h₂)), rfl] - · rw [dif_neg h, dif_neg (show (i : J) ≠ j from fun h₂ => h (h₂ ▸ i.2)), comp_zero] + · rw [dite_eq_right h, dite_eq_right (show (i : J) ≠ j from fun h₂ => h (h₂ ▸ i.2)), comp_zero] theorem biproduct.fromSubtype_eq_lift [DecidablePred p] : biproduct.fromSubtype f p = @@ -787,10 +787,10 @@ theorem biproduct.ι_toSubtype [DecidablePred p] (j : J) : ext i rw [biproduct.toSubtype, Category.assoc, biproduct.lift_π, biproduct.ι_π] by_cases h : p j - · rw [dif_pos h, biproduct.ι_π] + · rw [dite_eq_left h, biproduct.ι_π] split_ifs with h₁ h₂ h₂ exacts [rfl, False.elim (h₂ (Subtype.ext h₁)), False.elim (h₁ (congr_arg Subtype.val h₂)), rfl] - · rw [dif_neg h, dif_neg (show j ≠ i from fun h₂ => h (h₂.symm ▸ i.2)), zero_comp] + · rw [dite_eq_right h, dite_eq_right (show j ≠ i from fun h₂ => h (h₂.symm ▸ i.2)), zero_comp] theorem biproduct.toSubtype_eq_desc [DecidablePred p] : biproduct.toSubtype f p = @@ -848,8 +848,8 @@ def biproduct.isLimitFromSubtype : rw [KernelFork.ι_ofι, Category.assoc, Category.assoc, biproduct.toSubtype_fromSubtype_assoc, biproduct.map_π] rcases Classical.em (i = j) with (rfl | h) - · rw [if_neg (Classical.not_not.2 rfl), comp_zero, comp_zero, KernelFork.condition] - · rw [if_pos (Ne.symm h), Category.comp_id], by + · rw [ite_eq_right (Classical.not_not.2 rfl), comp_zero, comp_zero, KernelFork.condition] + · rw [ite_eq_left (Ne.symm h), Category.comp_id], by intro m hm rw [← hm, KernelFork.ι_ofι, Category.assoc, biproduct.fromSubtype_toSubtype] exact (Category.comp_id _).symm⟩ @@ -874,8 +874,8 @@ def biproduct.isColimitToSubtype : apply biproduct.hom_ext'; intro j rw [CokernelCofork.π_ofπ, biproduct.toSubtype_fromSubtype_assoc, biproduct.ι_map_assoc] rcases Classical.em (i = j) with (rfl | h) - · rw [if_neg (Classical.not_not.2 rfl), zero_comp, CokernelCofork.condition] - · rw [if_pos (Ne.symm h), Category.id_comp], by + · rw [ite_eq_right (Classical.not_not.2 rfl), zero_comp, CokernelCofork.condition] + · rw [ite_eq_left (Ne.symm h), Category.id_comp], by intro m hm rw [← hm, CokernelCofork.π_ofπ, ← Category.assoc, biproduct.fromSubtype_toSubtype] exact (Category.id_comp _).symm⟩ @@ -908,7 +908,7 @@ def kernelForkBiproductToSubtype (p : K → Prop) : ext j k simp only [Category.assoc, biproduct.ι_fromSubtype_assoc, biproduct.ι_toSubtype_assoc, comp_zero, zero_comp] - rw [dif_neg k.2] + rw [dite_eq_right k.2] simp only [zero_comp]) isLimit := KernelFork.IsLimit.ofι _ _ (fun {_} g _ => g ≫ biproduct.toSubtype f pᶜ) @@ -946,7 +946,7 @@ def cokernelCoforkBiproductFromSubtype (p : K → Prop) : ext j k simp only [Category.assoc, Pi.compl_apply, biproduct.ι_fromSubtype_assoc, biproduct.ι_toSubtype_assoc, comp_zero, zero_comp] - rw [dif_neg] + rw [dite_eq_right] · simp only [zero_comp] · exact not_not.mpr k.2) isColimit := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean index 71bf6910d015d9..ca3364f6c7903b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/MultiequalizerPullback.lean @@ -52,12 +52,12 @@ noncomputable def multicofork : Multicofork I := @[simp] lemma multicofork_π_eq_inl : (multicofork h h' s).π (J.fst default) = s.inl := by dsimp only [multicofork, ofπ, π] - rw [dif_pos rfl, eqToHom_refl, Category.id_comp] + rw [dite_eq_left rfl, eqToHom_refl, Category.id_comp] @[simp] lemma multicofork_π_eq_inr : (multicofork h h' s).π (J.snd default) = s.inr := by dsimp only [multicofork, ofπ, π] - rw [dif_neg h'.symm, eqToHom_refl, Category.id_comp] + rw [dite_eq_right h'.symm, eqToHom_refl, Category.id_comp] end isPushout diff --git a/Mathlib/CategoryTheory/Limits/Shapes/PiProd.lean b/Mathlib/CategoryTheory/Limits/Shapes/PiProd.lean index 67733ba9429866..4c87dd237d0641 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/PiProd.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/PiProd.lean @@ -53,8 +53,8 @@ noncomputable def Pi.binaryFanOfPropIsLimit [∀ i, Decidable (P i)] : (by aesop) (by aesop) (fun _ _ h₁ h₂ ↦ Pi.hom_ext _ _ fun b ↦ by by_cases h : P b - · simp [← h₁, dif_pos h] - · simp [← h₂, dif_neg h]) + · simp [← h₁, dite_eq_left h] + · simp [← h₂, dite_eq_right h]) lemma hasBinaryProduct_of_products : HasBinaryProduct (∏ᶜ (fun (i : {x : I // P x}) ↦ X i.val)) (∏ᶜ (fun (i : {x : I // ¬ P x}) ↦ X i.val)) := by diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean b/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean index 187326f85d5f6c..de188f2d7bc1e1 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SequentialProduct.lean @@ -33,10 +33,10 @@ namespace CategoryTheory.Limits.SequentialProduct variable {C : Type*} {M N : ℕ → C} lemma functorObj_eq_pos {n m : ℕ} (h : m < n) : - (fun i ↦ if _ : i < n then M i else N i) m = M m := dif_pos h + (fun i ↦ if _ : i < n then M i else N i) m = M m := dite_eq_left h lemma functorObj_eq_neg {n m : ℕ} (h : ¬(m < n)) : - (fun i ↦ if _ : i < n then M i else N i) m = N m := dif_neg h + (fun i ↦ if _ : i < n then M i else N i) m = N m := dite_eq_right h variable [Category* C] (f : ∀ n, M n ⟶ N n) [HasCountableProducts C] @@ -89,7 +89,7 @@ lemma functorMap_commSq_aux {n m k : ℕ} (h : n ≤ m) (hh : ¬(k < m)) : functorMap, dite_eq_ite] split_ifs · omega - simp [dif_neg (by lia : ¬(k < m)), dif_neg hh] + simp [dite_eq_right (by lia : ¬(k < m)), dite_eq_right hh] set_option backward.isDefEq.respectTransparency false in lemma functorMap_commSq {n m : ℕ} (h : ¬(m < n)) : @@ -135,7 +135,7 @@ noncomputable def cone : Cone (Functor.ofOpSequence (functorMap f)) where Functor.const_obj_map, Category.id_comp, Pi.map_π, Functor.ofOpSequence_map_homOfLE_succ, functorMap, Category.assoc, Pi.map_π_assoc] split - · simp [dif_pos (by lia : m < n + 1)] + · simp [dite_eq_left (by lia : m < n + 1)] · split all_goals simp @@ -149,14 +149,14 @@ set_option backward.isDefEq.respectTransparency false in lemma cone_π_app_comp_Pi_π_pos (m n : ℕ) (h : n < m) : (cone f).π.app ⟨m⟩ ≫ Pi.π (fun i ↦ if _ : i < m then M i else N i) n = Pi.π _ n ≫ eqToHom (functorObj_eq_pos h).symm := by - simp [cone_π_app, dif_pos h] + simp [cone_π_app, dite_eq_left h] set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @[reassoc] lemma cone_π_app_comp_Pi_π_neg (m n : ℕ) (h : ¬(n < m)) : (cone f).π.app ⟨m⟩ ≫ Pi.π _ n = Pi.π _ n ≫ f n ≫ eqToHom (functorObj_eq_neg h).symm := by - simp [cone_π_app, dif_neg h] + simp [cone_π_app, dite_eq_right h] set_option backward.isDefEq.respectTransparency false in /-- @@ -169,7 +169,7 @@ with cone point `∏ M` is indeed a limit cone. noncomputable def isLimit : IsLimit (cone f) where lift s := Pi.lift fun m ↦ s.π.app ⟨m + 1⟩ ≫ Pi.π (fun i ↦ if _ : i < m + 1 then M i else N i) m ≫ - eqToHom (dif_pos (by lia : m < m + 1)) + eqToHom (dite_eq_left (by lia : m < m + 1)) fac s := by intro ⟨n⟩ apply Pi.hom_ext @@ -190,14 +190,14 @@ noncomputable def isLimit : IsLimit (cone f) where simp only [Nat.succ_eq_add_one, homOfLE_leOfHom, Functor.ofOpSequence_map_homOfLE_succ, Category.assoc] have h₁ : (if _ : m < m + 1 then M m else N m) = if _ : m < n then M m else N m := by - rw [dif_pos (by lia), dif_pos (by lia)] + rw [dite_eq_left (by lia), dite_eq_left (by lia)] have h₂ : (if _ : m < n then M m else N m) = if _ : m < n + 1 then M m else N m := by - rw [dif_pos h, dif_pos (by lia)] + rw [dite_eq_left h, dite_eq_left (by lia)] rw [← eqToHom_trans h₁ h₂] slice_lhs 2 4 => rw [ih (by lia)] simp only [functorMap, dite_eq_ite, Pi.π, Pi.map_π_assoc] split_ifs - rw [dif_pos (by lia)] + rw [dite_eq_left (by lia)] simp · simp only [Category.assoc] rw [cone_π_app_comp_Pi_π_neg f _ _ h] diff --git a/Mathlib/CategoryTheory/Limits/VanKampen.lean b/Mathlib/CategoryTheory/Limits/VanKampen.lean index a4b8eeff9ea07f..d914cfbe97e8a1 100644 --- a/Mathlib/CategoryTheory/Limits/VanKampen.lean +++ b/Mathlib/CategoryTheory/Limits/VanKampen.lean @@ -689,14 +689,15 @@ set_option backward.defeqAttrib.useBackward true in theorem isPullback_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {X : ι → C} {c : Cofan X} (hc : IsVanKampenColimit c) (i j : ι) [DecidableEq ι] : IsPullback (P := (if j = i then X i else ⊥_ C)) - (if h : j = i then eqToHom (if_pos h) else eqToHom (if_neg h) ≫ initial.to (X i)) - (if h : j = i then eqToHom ((if_pos h).trans (congr_arg X h.symm)) - else eqToHom (if_neg h) ≫ initial.to (X j)) + (if h : j = i then eqToHom (ite_eq_left h) else eqToHom (ite_eq_right h) ≫ initial.to (X i)) + (if h : j = i then eqToHom ((ite_eq_left h).trans (congr_arg X h.symm)) + else eqToHom (ite_eq_right h) ≫ initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j) := by refine (hc (Cofan.mk (X i) (f := fun k ↦ if k = i then X i else ⊥_ C) - (fun k ↦ if h : k = i then (eqToHom <| if_pos h) else (eqToHom <| if_neg h) ≫ initial.to _)) - (Discrete.natTrans (fun k ↦ if h : k.1 = i then (eqToHom <| (if_pos h).trans - (congr_arg X h.symm)) else (eqToHom <| if_neg h) ≫ initial.to _)) + (fun k ↦ + if h : k = i then (eqToHom <| ite_eq_left h) else (eqToHom <| ite_eq_right h) ≫ initial.to _)) + (Discrete.natTrans (fun k ↦ if h : k.1 = i then (eqToHom <| (ite_eq_left h).trans + (congr_arg X h.symm)) else (eqToHom <| ite_eq_right h) ≫ initial.to _)) (c.inj i) ?_ (.of_discrete _)).mp ⟨?_⟩ ⟨j⟩ · ext ⟨k⟩ simp only [Discrete.functor_obj, Functor.const_obj_obj, NatTrans.comp_app, @@ -704,7 +705,7 @@ theorem isPullback_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {X : ι → split · subst ‹k = i›; rfl · simp - · refine Cofan.IsColimit.mk _ (fun t ↦ (eqToHom (if_pos rfl).symm) ≫ t.inj i) ?_ ?_ + · refine Cofan.IsColimit.mk _ (fun t ↦ (eqToHom (ite_eq_left rfl).symm) ≫ t.inj i) ?_ ?_ · intro t j simp only [Cofan.mk_pt, cofan_mk_inj] split @@ -725,7 +726,7 @@ theorem isPullback_initial_to_of_cofan_isVanKampen [HasInitial C] {ι : Type*} { subst this have : ∀ i, Subsingleton (⊥_ C ⟶ (Discrete.functor f).obj i) := inferInstance convert! isPullback_of_cofan_isVanKampen hc i.as j.as - exact (if_neg (mt Discrete.ext hi.symm)).symm + exact (ite_eq_right (mt Discrete.ext hi.symm)).symm set_option backward.isDefEq.respectTransparency false in theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C} @@ -740,7 +741,7 @@ theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι nth_rw 1 [← Category.id_comp (c.ι.app i)] convert! IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as) swap - · exact (eqToHom (if_pos rfl).symm) + · exact (eqToHom (ite_eq_left rfl).symm) · simp · exact IsPullback.of_vert_isIso ⟨by simp⟩ diff --git a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean index 2ae6910a8af7a3..a527e9a0db5413 100644 --- a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean @@ -235,10 +235,12 @@ instance Functor.Monoidal.whiskeringLeft ((whiskeringLeft _ _ E).obj F).Monoidal := CoreMonoidal.toMonoidal { εIso := Iso.refl _, μIso _ _ := Iso.refl _ } +set_option backward.isDefEq.respectTransparency false in instance (E : Type*) [Category* E] [MonoidalCategory E] (e : C ≌ D) : (e.congrLeft (E := E)).functor.Monoidal := inferInstanceAs ((Functor.whiskeringLeft _ _ E).obj e.inverse).Monoidal +set_option backward.isDefEq.respectTransparency false in instance (E : Type*) [Category* E] [MonoidalCategory E] (e : C ≌ D) : (e.congrLeft (E := E)).inverse.Monoidal := inferInstanceAs ((Functor.whiskeringLeft _ _ E).obj e.functor).Monoidal diff --git a/Mathlib/CategoryTheory/Monoidal/Mon.lean b/Mathlib/CategoryTheory/Monoidal/Mon.lean index 8042a141f58ab5..73f7739fdd60f5 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon.lean @@ -1006,7 +1006,7 @@ variable [BraidedCategory C] [BraidedCategory D] (F) open scoped Obj attribute [-simp] IsMonHom.one_hom_assoc in -attribute [local simp← ] tensorHom_comp_tensorHom tensorHom_comp_tensorHom_assoc in +attribute [local simp ←] tensorHom_comp_tensorHom tensorHom_comp_tensorHom_assoc in attribute [local simp] tensorμ_comp_μ_tensorHom_μ_comp_μ_assoc MonObj.tensorObj.one_def MonObj.tensorObj.mul_def in @[to_additive instIsAddMonHomμ] @@ -1026,7 +1026,7 @@ instance [F.LaxBraided] : F.mapMon.LaxMonoidal where set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in attribute [-simp] IsMonHom.one_hom IsMonHom.one_hom_assoc IsMonHom.mul_hom in -attribute [local simp← ] tensorHom_comp_tensorHom tensorHom_comp_tensorHom_assoc in +attribute [local simp ←] tensorHom_comp_tensorHom tensorHom_comp_tensorHom_assoc in attribute [local simp] ε_tensorHom_comp_μ_assoc tensorμ_comp_μ_tensorHom_μ_comp_μ_assoc MonObj.tensorObj.one_def MonObj.tensorObj.mul_def in @[to_additive] diff --git a/Mathlib/CategoryTheory/Monoidal/Preadditive.lean b/Mathlib/CategoryTheory/Monoidal/Preadditive.lean index e50a926ce756c8..a348612e4f57e0 100644 --- a/Mathlib/CategoryTheory/Monoidal/Preadditive.lean +++ b/Mathlib/CategoryTheory/Monoidal/Preadditive.lean @@ -283,7 +283,7 @@ theorem rightDistributor_assoc {J : Type} [Finite J] (f : J → C) (X Y : C) : asIso_hom, comp_zero, comp_dite, Preadditive.sum_comp, Preadditive.comp_sum, sum_tensor, comp_tensor_id, tensorIso_hom, rightDistributor_hom, biproduct.mapIso_hom, biproduct.ι_map, biproduct.ι_π, Finset.sum_dite_irrel, Finset.sum_dite_eq', Finset.sum_const_zero, - Finset.mem_univ, if_true] + Finset.mem_univ, ite_true] simp_rw [← tensorHom_id] simp only [← comp_tensor_id, biproduct.ι_π, dite_tensor, comp_dite] simp @@ -301,7 +301,7 @@ theorem leftDistributor_rightDistributor_assoc {J : Type _} [Finite J] asIso_hom, comp_zero, comp_dite, Preadditive.sum_comp, Preadditive.comp_sum, sum_tensor, tensor_sum, comp_tensor_id, tensorIso_hom, leftDistributor_hom, rightDistributor_hom, biproduct.mapIso_hom, biproduct.ι_map, biproduct.ι_π, Finset.sum_dite_irrel, - Finset.sum_dite_eq', Finset.sum_const_zero, Finset.mem_univ, if_true] + Finset.sum_dite_eq', Finset.sum_const_zero, Finset.mem_univ, ite_true] simp_rw [← tensorHom_id, ← id_tensorHom] simp only [← comp_tensor_id, ← id_tensor_comp_assoc, Category.assoc, biproduct.ι_π, comp_dite, dite_comp, tensor_dite, dite_tensor] diff --git a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean index 84b92f63fa31bf..76269aecdb2b5e 100644 --- a/Mathlib/CategoryTheory/Preadditive/Biproducts.lean +++ b/Mathlib/CategoryTheory/Preadditive/Biproducts.lean @@ -223,7 +223,7 @@ theorem biproduct.lift_eq {T : C} {g : ∀ j, T ⟶ f j} : classical ext j simp only [sum_comp, biproduct.ι_π, comp_dite, biproduct.lift_π, Category.assoc, comp_zero, - Finset.sum_dite_eq', Finset.mem_univ, eqToHom_refl, Category.comp_id, if_true] + Finset.sum_dite_eq', Finset.mem_univ, eqToHom_refl, Category.comp_id, ite_true] theorem biproduct.desc_eq {T : C} {g : ∀ j, f j ⟶ T} : biproduct.desc g = ∑ j, biproduct.π f j ≫ g j := by diff --git a/Mathlib/CategoryTheory/Preadditive/Mat.lean b/Mathlib/CategoryTheory/Preadditive/Mat.lean index c85d04a5409a1a..f6a0b778533b6a 100644 --- a/Mathlib/CategoryTheory/Preadditive/Mat.lean +++ b/Mathlib/CategoryTheory/Preadditive/Mat.lean @@ -198,7 +198,7 @@ instance hasFiniteBiproducts : HasFiniteBiproducts (Mat_ C) where eqToHom_trans] rw [← Finset.univ_sigma_univ, Finset.sum_sigma] dsimp +instances - simp only [if_true, Finset.sum_dite_irrel, Finset.mem_univ, + simp only [ite_true, Finset.sum_dite_irrel, Finset.mem_univ, Finset.sum_const_zero, Finset.sum_dite_eq'] split_ifs with h h' · subst h h' @@ -216,12 +216,12 @@ instance hasFiniteBiproducts : HasFiniteBiproducts (Mat_ C) where · intro b _ hb apply Finset.sum_eq_zero intro x _ - rw [dif_neg hb.symm, zero_comp] + rw [dite_eq_right hb.symm, zero_comp] · intro hi simp at hi rw [Finset.sum_eq_single j]; rotate_left · intro b _ hb - rw [dif_pos rfl, dif_neg, zero_comp] + rw [dite_eq_left rfl, dite_eq_right, zero_comp] simp only tauto · intro hj @@ -230,13 +230,13 @@ instance hasFiniteBiproducts : HasFiniteBiproducts (Mat_ C) where Sigma.mk.inj_iff, id_def] by_cases h : i' = i · subst h - rw [dif_pos rfl] + rw [dite_eq_left rfl] simp only [heq_eq_eq, true_and] by_cases h : j' = j · subst h simp - · rw [dif_neg h, dif_neg (Ne.symm h)] - · rw [dif_neg h, dif_neg] + · rw [dite_eq_right h, dite_eq_right (Ne.symm h)] + · rw [dite_eq_right h, dite_eq_right] tauto) } end Mat_ @@ -325,7 +325,7 @@ def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M rw [Finset.sum_apply, Finset.sum_apply, Finset.sum_eq_single i]; rotate_left · intro b _ hb dsimp - rw [Fintype.univ_ofSubsingleton, Finset.sum_singleton, dif_neg hb.symm, zero_comp] + rw [Fintype.univ_ofSubsingleton, Finset.sum_singleton, dite_eq_right hb.symm, zero_comp] · intro h simp at h simp diff --git a/Mathlib/CategoryTheory/Preadditive/Schur.lean b/Mathlib/CategoryTheory/Preadditive/Schur.lean index 3a6560d8584eb1..f7abe0a5cdc5d3 100644 --- a/Mathlib/CategoryTheory/Preadditive/Schur.lean +++ b/Mathlib/CategoryTheory/Preadditive/Schur.lean @@ -64,10 +64,10 @@ the endomorphisms of a simple object form a division ring. -/ noncomputable instance [HasKernels C] {X : C} [Simple X] : DivisionRing (End X) where inv f := if h : f = 0 then 0 else haveI := isIso_of_hom_simple h; inv f exists_pair_ne := ⟨𝟙 X, 0, id_nonzero _⟩ - inv_zero := dif_pos rfl + inv_zero := dite_eq_left rfl mul_inv_cancel f hf := by dsimp - rw [dif_neg hf] + rw [dite_eq_right hf] have := isIso_of_hom_simple hf exact IsIso.inv_hom_id f nnqsmul := _ diff --git a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean index 6145f498b08a60..725d69aa8d471f 100644 --- a/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean +++ b/Mathlib/CategoryTheory/Presentable/SharplyLT/Basic.lean @@ -152,7 +152,7 @@ noncomputable def φ (B : Set X) : Set X := omit [Fact κ₁.IsRegular] [Fact κ₂.IsRegular] [PartialOrder X] in lemma φ_eq (B : Set X) (hB : HasCardinalLT B κ₂) : - φ Y m B = φ₀ Y m B hB := dif_pos hB + φ Y m B = φ₀ Y m B hB := dite_eq_left hB include hY' in omit [Fact κ₂.IsRegular] [PartialOrder X] in diff --git a/Mathlib/CategoryTheory/SmallObject/Iteration/ExtendToSucc.lean b/Mathlib/CategoryTheory/SmallObject/Iteration/ExtendToSucc.lean index 707492de3cb8d1..7426f532daafaf 100644 --- a/Mathlib/CategoryTheory/SmallObject/Iteration/ExtendToSucc.lean +++ b/Mathlib/CategoryTheory/SmallObject/Iteration/ExtendToSucc.lean @@ -44,7 +44,7 @@ def obj (i : Set.Iic (Order.succ j)) : C := if hij : i.1 ≤ j then F.obj ⟨i.1, hij⟩ else X lemma obj_eq (i : Set.Iic j) : - obj F X ⟨i, i.2.trans (Order.le_succ j)⟩ = F.obj i := dif_pos i.2 + obj F X ⟨i, i.2.trans (Order.le_succ j)⟩ = F.obj i := dite_eq_left i.2 /-- The isomorphism `obj F X ⟨i, _⟩ ≅ F.obj i` when `i : Set.Iic j`. -/ def objIso (i : Set.Iic j) : @@ -53,7 +53,7 @@ def objIso (i : Set.Iic j) : include hj in lemma obj_succ_eq : obj F X ⟨Order.succ j, by simp⟩ = X := - dif_neg (by simpa only [Order.succ_le_iff_isMax] using hj) + dite_eq_right (by simpa only [Order.succ_le_iff_isMax] using hj) /-- The isomorphism `obj F X ⟨Order.succ j, _⟩ ≅ X`. -/ def objSuccIso : @@ -83,24 +83,24 @@ lemma map_eq (i₁ i₂ : J) (hi : i₁ ≤ i₂) (hi₂ : i₂ ≤ j) : map hj F τ i₁ i₂ hi (hi₂.trans (Order.le_succ j)) = (objIso F X ⟨i₁, hi.trans hi₂⟩).hom ≫ F.map (homOfLE hi) ≫ (objIso F X ⟨i₂, hi₂⟩).inv := - dif_pos hi₂ + dite_eq_left hi₂ lemma map_self_succ : map hj F τ j (Order.succ j) (Order.le_succ j) (by rfl) = (objIso F X ⟨j, by simp⟩).hom ≫ τ ≫ (objSuccIso hj F X).inv := by dsimp [map] - rw [dif_neg (by simpa only [Order.succ_le_iff_isMax] using hj), - dif_pos (by rfl), Functor.map_id, comp_id, id_comp] + rw [dite_eq_right (by simpa only [Order.succ_le_iff_isMax] using hj), + dite_eq_left (by rfl), Functor.map_id, comp_id, id_comp] @[simp] lemma map_id (i : J) (hi : i ≤ Order.succ j) : map hj F τ i i (by rfl) hi = 𝟙 _ := by dsimp [map] by_cases h₁ : i ≤ j - · rw [dif_pos h₁, CategoryTheory.Functor.map_id, id_comp, Iso.hom_inv_id] + · rw [dite_eq_left h₁, CategoryTheory.Functor.map_id, id_comp, Iso.hom_inv_id] · obtain rfl : i = Order.succ j := le_antisymm hi (Order.succ_le_of_lt (not_le.1 h₁)) - rw [dif_neg (by simpa only [Order.succ_le_iff_isMax] using hj), - dif_neg h₁] + rw [dite_eq_right (by simpa only [Order.succ_le_iff_isMax] using hj), + dite_eq_right h₁] lemma map_comp (i₁ i₂ i₃ : J) (h₁₂ : i₁ ≤ i₂) (h₂₃ : i₂ ≤ i₃) (h : i₃ ≤ Order.succ j) : map hj F τ i₁ i₃ (h₁₂.trans h₂₃) h = @@ -114,8 +114,8 @@ lemma map_comp (i₁ i₂ i₃ : J) (h₁₂ : i₁ ≤ i₂) (h₂₃ : i₂ · rw [Order.lt_succ_iff_of_not_isMax hj] at h₂ rw [map_eq hj F τ i₁ i₂ _ h₂] dsimp [map] - rw [dif_neg h₁, dif_pos (h₁₂.trans h₂), dif_neg h₁, dif_pos h₂, assoc, assoc, - Iso.inv_hom_id_assoc, comp_id, ← Functor.map_comp_assoc, homOfLE_comp] + rw [dite_eq_right h₁, dite_eq_left (h₁₂.trans h₂), dite_eq_right h₁, dite_eq_left h₂, assoc, + assoc, Iso.inv_hom_id_assoc, comp_id, ← Functor.map_comp_assoc, homOfLE_comp] · rw [map_id, comp_id] end extendToSucc diff --git a/Mathlib/CategoryTheory/SmallObject/Iteration/FunctorOfCocone.lean b/Mathlib/CategoryTheory/SmallObject/Iteration/FunctorOfCocone.lean index e95b4aa5e08212..5a472da9cbf939 100644 --- a/Mathlib/CategoryTheory/SmallObject/Iteration/FunctorOfCocone.lean +++ b/Mathlib/CategoryTheory/SmallObject/Iteration/FunctorOfCocone.lean @@ -43,12 +43,12 @@ def obj (i : J) : C := /-- Auxiliary definition for `ofCocone`. -/ def objIso (i : J) (hi : i < j) : obj c i ≅ F.obj ⟨i, hi⟩ := - eqToIso (dif_pos hi) + eqToIso (dite_eq_left hi) /-- Auxiliary definition for `ofCocone`. -/ def objIsoPt : obj c j ≅ c.pt := - eqToIso (dif_neg (by simp)) + eqToIso (dite_eq_right (by simp)) /-- Auxiliary definition for `ofCocone`. -/ def map (i₁ i₂ : J) (hi : i₁ ≤ i₂) (hi₂ : i₂ ≤ j) : @@ -77,11 +77,11 @@ lemma map_comp (i₁ i₂ i₃ : J) (hi : i₁ ≤ i₂) (hi' : i₂ ≤ i₃) ( · obtain hi₂₃ | rfl := hi'.lt_or_eq · dsimp [map] obtain hi₃' | rfl := hi₃.lt_or_eq - · rw [dif_pos hi₃', dif_pos (hi₂₃.trans hi₃'), dif_pos hi₃', assoc, assoc, + · rw [dite_eq_left hi₃', dite_eq_left (hi₂₃.trans hi₃'), dite_eq_left hi₃', assoc, assoc, Iso.inv_hom_id_assoc, ← Functor.map_comp_assoc, homOfLE_comp] - · rw [dif_neg (by simp), dif_pos (hi₁₂.trans hi₂₃), dif_pos hi₂₃, dif_neg (by simp), - dif_pos hi₂₃, eqToHom_refl, comp_id, assoc, assoc, Iso.inv_hom_id_assoc, - Cocone.w_assoc] + · rw [dite_eq_right (by simp), dite_eq_left (hi₁₂.trans hi₂₃), dite_eq_left hi₂₃, + dite_eq_right (by simp), dite_eq_left hi₂₃, eqToHom_refl, comp_id, assoc, assoc, + Iso.inv_hom_id_assoc, Cocone.w_assoc] · rw [map_id, comp_id] · rw [map_id, id_comp] @@ -98,7 +98,7 @@ def ofCocone : Set.Iic j ⥤ C where lemma ofCocone_obj_eq (i : J) (hi : i < j) : (ofCocone c).obj ⟨i, hi.le⟩ = F.obj ⟨i, hi⟩ := - dif_pos hi + dite_eq_left hi /-- The isomorphism `(ofCocone c).obj ⟨i, _⟩ ≅ F.obj ⟨i, _⟩` when `i < j`. -/ def ofCoconeObjIso (i : J) (hi : i < j) : @@ -107,7 +107,7 @@ def ofCoconeObjIso (i : J) (hi : i < j) : lemma ofCocone_obj_eq_pt : (ofCocone c).obj ⟨j, by simp⟩ = c.pt := - dif_neg (by simp) + dite_eq_right (by simp) /-- The isomorphism `(ofCocone c).obj ⟨j, _⟩ ≅ c.pt`. -/ def ofCoconeObjIsoPt : @@ -118,7 +118,7 @@ lemma ofCocone_map_to_top (i : J) (hi : i < j) : (ofCocone c).map (homOfLE hi.le) = (ofCoconeObjIso c i hi).hom ≫ c.ι.app ⟨i, hi⟩ ≫ (ofCoconeObjIsoPt c).inv := by dsimp [ofCocone, ofCocone.map, ofCoconeObjIso, ofCoconeObjIsoPt] - rw [dif_neg (by simp), dif_pos hi, comp_id] + rw [dite_eq_right (by simp), dite_eq_left hi, comp_id] @[reassoc] lemma ofCocone_map (i₁ i₂ : J) (hi : i₁ ≤ i₂) (hi₂ : i₂ < j) : @@ -126,7 +126,7 @@ lemma ofCocone_map (i₁ i₂ : J) (hi : i₁ ≤ i₂) (hi₂ : i₂ < j) : (ofCoconeObjIso c i₁ (lt_of_le_of_lt hi hi₂)).hom ≫ F.map (homOfLE hi) ≫ (ofCoconeObjIso c i₂ hi₂).inv := by dsimp [ofCocone, ofCoconeObjIso, ofCocone.map] - rw [dif_pos hi₂] + rw [dite_eq_left hi₂] @[reassoc] lemma ofCoconeObjIso_hom_naturality (i₁ i₂ : J) (hi : i₁ ≤ i₂) (hi₂ : i₂ < j) : diff --git a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean index 22b6f2466c672e..dd7f6ab71f9529 100644 --- a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean +++ b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean @@ -299,13 +299,14 @@ instance algebraRight [PartialOrder α] [LocallyFiniteOrder α] [DecidableEq α] eq_comm, Icc_self] simp · simp only [one_apply, mul_one, smul_eq_mul, mul_apply, zero_mul, - constSMul_apply, ← ite_and, ite_mul, mul_ite, map_mul, mul_zero, if_neg h] + constSMul_apply, ← ite_and, ite_mul, mul_ite, map_mul, mul_zero, ite_eq_right h] refine (sum_eq_zero fun x _ ↦ ?_).symm - exact if_neg fun hx ↦ h <| hx.2.trans hx.1 + exact ite_eq_right fun hx ↦ h <| hx.2.trans hx.1 map_zero' := by rw [map_zero, zero_smul] map_add' c d := by rw [map_add, add_smul] } - commutes' c f := by classical ext a b hab; simp [if_pos hab, constSMul_apply, mul_comm] - smul_def' c f := by classical ext a b hab; simp [if_pos hab, constSMul_apply, Algebra.smul_def] + commutes' c f := by classical ext a b hab; simp [ite_eq_left hab, constSMul_apply, mul_comm] + smul_def' c f := by + classical ext a b hab; simp [ite_eq_left hab, constSMul_apply, Algebra.smul_def] /-! ### The Lambda function -/ @@ -316,7 +317,7 @@ variable (𝕜) [Zero 𝕜] [One 𝕜] [Preorder α] [DecidableRel (α := α) ( interval of cardinality one or two. -/ @[simps] def lambda : IncidenceAlgebra 𝕜 α := - ⟨fun a b ↦ if a ⩿ b then 1 else 0, fun _a _b h ↦ if_neg fun hh ↦ h hh.le⟩ + ⟨fun a b ↦ if a ⩿ b then 1 else 0, fun _a _b h ↦ ite_eq_right fun hh ↦ h hh.le⟩ end Lambda @@ -327,13 +328,13 @@ variable (𝕜) [Zero 𝕜] [One 𝕜] [LE α] [DecidableLE α] {a b : α} /-- The zeta function of the incidence algebra is the function that assigns 1 to every nonempty interval, convolution with this function sums functions over intervals. -/ -def zeta : IncidenceAlgebra 𝕜 α := ⟨fun a b ↦ if a ≤ b then 1 else 0, fun _a _b h ↦ if_neg h⟩ +def zeta : IncidenceAlgebra 𝕜 α := ⟨fun a b ↦ if a ≤ b then 1 else 0, fun _a _b h ↦ ite_eq_right h⟩ variable {𝕜} @[simp] lemma zeta_apply (a b : α) : zeta 𝕜 a b = if a ≤ b then 1 else 0 := rfl -lemma zeta_of_le (h : a ≤ b) : zeta 𝕜 a b = 1 := if_pos h +lemma zeta_of_le (h : a ≤ b) : zeta 𝕜 a b = 1 := ite_eq_left h end Zeta @@ -383,7 +384,7 @@ lemma mu_apply (a b : α) : mu 𝕜 a b = if a = b then 1 else -∑ x ∈ Ico a @[simp] lemma mu_self (a : α) : mu 𝕜 a a = 1 := by simp [mu_apply] lemma mu_eq_neg_sum_Ico_of_ne (hab : a ≠ b) : - mu 𝕜 a b = -∑ x ∈ Ico a b, mu 𝕜 a x := by rw [mu_apply, if_neg hab] + mu 𝕜 a b = -∑ x ∈ Ico a b, mu 𝕜 a x := by rw [mu_apply, ite_eq_right hab] variable (𝕜 α) /-- The Euler characteristic of a finite bounded order. -/ @@ -443,7 +444,7 @@ private lemma mu'_apply (a b : α) : mu' 𝕜 a b = if a = b then 1 else -∑ x @[simp] private lemma mu'_apply_self (a : α) : mu' 𝕜 a a = 1 := by simp [mu'_apply] private lemma mu'_eq_sum_Ioc_of_ne (h : a ≠ b) : mu' 𝕜 a b = -∑ x ∈ Ioc a b, mu' 𝕜 x b := by - rw [mu'_apply, if_neg h] + rw [mu'_apply, ite_eq_right h] end Mu' @@ -516,7 +517,7 @@ lemma mu_toDual (a b : α) : mu 𝕜 (toDual a) (toDual b) = mu 𝕜 b a := by simp only [mul_boole, one_apply, mul_apply, zeta_apply] calc ∑ x ∈ Icc a b, (if x ≤ b then mud a x else 0) = ∑ x ∈ Icc a b, mud a x := by - congr! with x hx; exact if_pos (mem_Icc.1 hx).2 + congr! with x hx; exact ite_eq_left (mem_Icc.1 hx).2 _ = ∑ x ∈ Icc (ofDual b) (ofDual a), mu 𝕜 x (ofDual a) := by simp [Icc_orderDual_def, mud] _ = if ofDual b = ofDual a then 1 else 0 := sum_Icc_mu_left .. _ = if a = b then 1 else 0 := by simp [eq_comm] @@ -543,7 +544,7 @@ lemma moebius_inversion_top (f g : α → 𝕜) (h : ∀ x, g x = ∑ y ∈ Ici _ = ∑ y ∈ Ici x, mu 𝕜 x y * ∑ z ∈ Ici y, zeta 𝕜 y z * f z := by congr with y rw [sum_congr rfl fun z hz ↦ ?_] - rw [zeta_apply, if_pos (mem_Ici.mp ‹_›), one_mul] + rw [zeta_apply, ite_eq_left (mem_Ici.mp ‹_›), one_mul] _ = ∑ y ∈ Ici x, ∑ z ∈ Ici y, mu 𝕜 x y * zeta 𝕜 y z * f z := by simp [mul_sum] _ = ∑ z ∈ Ici x, ∑ y ∈ Icc x z, mu 𝕜 x y * zeta 𝕜 y z * f z := by rw [sum_sigma' (Ici x) fun y ↦ Ici y] @@ -556,11 +557,11 @@ lemma moebius_inversion_top (f g : α → 𝕜) (h : ∀ x, g x = ∑ y ∈ Ici _ = ∑ y ∈ Ici x, ∑ z ∈ Ici y, (1 : IncidenceAlgebra 𝕜 α) x z * f z := by simp only [mu_mul_zeta 𝕜, one_apply, ite_mul, one_mul, zero_mul, sum_ite_eq, mem_Ici, le_refl, ↓reduceIte, ← add_sum_Ioi_eq_sum_Ici, left_eq_add] - exact sum_eq_zero fun y hy ↦ if_neg (mem_Ioi.mp hy).not_ge + exact sum_eq_zero fun y hy ↦ ite_eq_right (mem_Ioi.mp hy).not_ge _ = f x := by simp only [one_apply, ite_mul, one_mul, zero_mul, sum_ite_eq, mem_Ici, ← add_sum_Ioi_eq_sum_Ici, le_refl, ↓reduceIte, add_eq_left] - exact sum_eq_zero fun y hy ↦ if_neg (mem_Ioi.mp hy).not_ge + exact sum_eq_zero fun y hy ↦ ite_eq_right (mem_Ioi.mp hy).not_ge end InversionTop diff --git a/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean b/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean index 329a690d007514..7fad0ce7c92c1f 100644 --- a/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean +++ b/Mathlib/Combinatorics/Enumerative/Pentagonal/PowerSeries.lean @@ -83,7 +83,7 @@ def pentagonalSeries : R⟦X⟧ := 0 theorem coeff_pentagonalSeries_eq_zero {n : ℕ} (h : n ∉ Set.range pentagonal) : - (pentagonalSeries R).coeff n = 0 := dif_neg <| by simpa using h + (pentagonalSeries R).coeff n = 0 := dite_eq_right <| by simpa using h @[simp] theorem coeff_pentagonalSeries_pentagonal (k : ℤ) : diff --git a/Mathlib/Combinatorics/Matroid/Basic.lean b/Mathlib/Combinatorics/Matroid/Basic.lean index 2f143a4f6f9e94..d2d96bc17582aa 100644 --- a/Mathlib/Combinatorics/Matroid/Basic.lean +++ b/Mathlib/Combinatorics/Matroid/Basic.lean @@ -1057,7 +1057,7 @@ theorem IsBasis.union_isBasis_union (hIX : M.IsBasis I X) (hJY : M.IsBasis J Y) (h : M.Indep (I ∪ J)) : M.IsBasis (I ∪ J) (X ∪ Y) := by rw [union_eq_iUnion, union_eq_iUnion] refine IsBasis.iUnion_isBasis_iUnion _ _ ?_ ?_ - · simp only [Bool.forall_bool, cond_false, cond_true]; exact ⟨hJY, hIX⟩ + · simp only [Bool.forall_bool, Bool.cond_false, Bool.cond_true]; exact ⟨hJY, hIX⟩ rwa [← union_eq_iUnion] theorem IsBasis.isBasis_union (hIX : M.IsBasis I X) (hIY : M.IsBasis I Y) : diff --git a/Mathlib/Combinatorics/Schnirelmann.lean b/Mathlib/Combinatorics/Schnirelmann.lean index 2fc936fc3e93bd..ce8880ce47ebc6 100644 --- a/Mathlib/Combinatorics/Schnirelmann.lean +++ b/Mathlib/Combinatorics/Schnirelmann.lean @@ -103,7 +103,7 @@ lemma schnirelmannDensity_le_of_notMem {k : ℕ} (hk : k ∉ A) : gcongr rw [← Nat.cast_pred hk', Nat.cast_le] suffices {a ∈ Ioc 0 k | a ∈ A} ⊆ Ioo 0 k from (card_le_card this).trans_eq (by simp) - rw [← Ioo_insert_right hk', filter_insert, if_neg hk] + rw [← Ioo_insert_right hk', filter_insert, ite_eq_right hk] exact filter_subset _ _ /-- The Schnirelmann density of a set not containing `1` is `0`. -/ diff --git a/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean b/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean index 60c7e4948c2f05..3291ec6f1ace93 100644 --- a/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean +++ b/Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean @@ -131,9 +131,9 @@ def truncatedSup (s : Finset α) (a : α) : α := set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in lemma truncatedSup_of_mem (h : a ∈ lowerClosure s) : - truncatedSup s a = {b ∈ s | a ≤ b}.sup' (sup_aux h) id := dif_pos h + truncatedSup s a = {b ∈ s | a ≤ b}.sup' (sup_aux h) id := dite_eq_left h -lemma truncatedSup_of_notMem (h : a ∉ lowerClosure s) : truncatedSup s a = ⊤ := dif_neg h +lemma truncatedSup_of_notMem (h : a ∉ lowerClosure s) : truncatedSup s a = ⊤ := dite_eq_right h @[simp] lemma truncatedSup_empty (a : α) : truncatedSup ∅ a = ⊤ := truncatedSup_of_notMem (by simp) @@ -206,9 +206,9 @@ def truncatedInf (s : Finset α) (a : α) : α := set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in lemma truncatedInf_of_mem (h : a ∈ upperClosure s) : - truncatedInf s a = {b ∈ s | b ≤ a}.inf' (inf_aux h) id := dif_pos h + truncatedInf s a = {b ∈ s | b ≤ a}.inf' (inf_aux h) id := dite_eq_left h -lemma truncatedInf_of_notMem (h : a ∉ upperClosure s) : truncatedInf s a = ⊥ := dif_neg h +lemma truncatedInf_of_notMem (h : a ∉ upperClosure s) : truncatedInf s a = ⊥ := dite_eq_right h lemma truncatedInf_le : truncatedInf s a ≤ a := by unfold truncatedInf diff --git a/Mathlib/Combinatorics/SetFamily/Compression/UV.lean b/Mathlib/Combinatorics/SetFamily/Compression/UV.lean index b7e413d1b0b399..77149b75db9de0 100644 --- a/Mathlib/Combinatorics/SetFamily/Compression/UV.lean +++ b/Mathlib/Combinatorics/SetFamily/Compression/UV.lean @@ -84,7 +84,7 @@ def compress (u v a : α) : α := theorem compress_of_disjoint_of_le (hua : Disjoint u a) (hva : v ≤ a) : compress u v a = (a ⊔ u) \ v := - if_pos ⟨hua, hva⟩ + ite_eq_left ⟨hua, hva⟩ theorem compress_of_disjoint_of_le' (hva : Disjoint v a) (hua : u ≤ a) : compress u v ((a ⊔ v) \ u) = a := by diff --git a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean index b966aa3b362589..738ca974415fdd 100644 --- a/Mathlib/Combinatorics/SetFamily/FourFunctions.lean +++ b/Mathlib/Combinatorics/SetFamily/FourFunctions.lean @@ -120,14 +120,14 @@ set_option backward.privateInPublic.warn false in omit [LinearOrder β] [IsStrictOrderedRing β] in lemma collapse_of_mem (ha : a ∉ s) (ht : t ∈ 𝒜) (hu : u ∈ 𝒜) (hts : t = s) (hus : u = insert a s) : collapse 𝒜 a f s = f t + f u := by - subst hts; subst hus; simp_rw [collapse_eq ha, if_pos ht, if_pos hu] + subst hts; subst hus; simp_rw [collapse_eq ha, ite_eq_left ht, ite_eq_left hu] set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in lemma le_collapse_of_mem (ha : a ∉ s) (hf : 0 ≤ f) (hts : t = s) (ht : t ∈ 𝒜) : f t ≤ collapse 𝒜 a f s := by subst hts - rw [collapse_eq ha, if_pos ht] + rw [collapse_eq ha, ite_eq_left ht] split_ifs · exact le_add_of_nonneg_right <| hf _ · rw [add_zero] @@ -136,7 +136,7 @@ set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in lemma le_collapse_of_insert_mem (ha : a ∉ s) (hf : 0 ≤ f) (hts : t = insert a s) (ht : t ∈ 𝒜) : f t ≤ collapse 𝒜 a f s := by - rw [collapse_eq ha, ← hts, if_pos ht] + rw [collapse_eq ha, ← hts, ite_eq_left ht] split_ifs · exact le_add_of_nonneg_left <| hf _ · rw [zero_add] diff --git a/Mathlib/Combinatorics/SetFamily/Kleitman.lean b/Mathlib/Combinatorics/SetFamily/Kleitman.lean index f5b06e6a78b12a..20a5f789269a7d 100644 --- a/Mathlib/Combinatorics/SetFamily/Kleitman.lean +++ b/Mathlib/Combinatorics/SetFamily/Kleitman.lean @@ -55,7 +55,7 @@ theorem Finset.card_biUnion_le_of_intersecting (s : Finset ι) (f : ι → Finse have hf₁ : ∀ j, j ∈ cons i s hi → f j ⊆ f' j ∧ 2 * #(f' j) = 2 ^ Fintype.card α ∧ (f' j : Set (Finset α)).Intersecting := by rintro j hj - simp_rw [f', dif_pos hj, ← Fintype.card_finset] + simp_rw [f', dite_eq_left hj, ← Fintype.card_finset] exact Classical.choose_spec (hf j hj).exists_card_eq have hf₂ : ∀ j, j ∈ cons i s hi → IsUpperSet (f' j : Set (Finset α)) := by refine fun j hj ↦ (hf₁ _ hj).2.2.isUpperSet' ((hf₁ _ hj).2.2.is_max_iff_card_eq.2 ?_) diff --git a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean index af8a25d6895dde..f8fe3293e6b636 100644 --- a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean +++ b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean @@ -131,7 +131,7 @@ the set is being "shifted down" as `max U < max V`. -/ lemma toColex_compress_lt_toColex {hU : U.Nonempty} {hV : V.Nonempty} (h : max' U hU < max' V hV) (hA : compress U V s ≠ s) : toColex (compress U V s) < toColex s := by rw [compress, ite_ne_right_iff] at hA - rw [compress, if_pos hA.1, lt_iff_exists_filter_lt] + rw [compress, ite_eq_left hA.1, lt_iff_exists_filter_lt] simp_rw [mem_sdiff (s := s), filter_inj, and_assoc] refine ⟨_, hA.1.2 <| max'_mem _ hV, notMem_sdiff_of_mem_right <| max'_mem _ _, fun a ha ↦ ?_⟩ have : a ∉ V := fun H ↦ ha.not_ge (le_max' _ _ H) diff --git a/Mathlib/Combinatorics/SimpleGraph/Copy.lean b/Mathlib/Combinatorics/SimpleGraph/Copy.lean index 5669976ebb964b..1a52ff601ebf1f 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Copy.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Copy.lean @@ -615,12 +615,12 @@ lemma killCopies_le_left : G.killCopies H ≤ G := by rw [killCopies]; split_ifs; exacts [le_rfl, deleteEdges_le _] @[simp] lemma killCopies_bot (G : SimpleGraph V) : G.killCopies (⊥ : SimpleGraph W) = G := by - rw [killCopies]; exact dif_pos rfl + rw [killCopies]; exact dite_eq_left rfl private lemma killCopies_of_ne_bot (hH : H ≠ ⊥) (G : SimpleGraph V) : G.killCopies H = G.deleteEdges (⋃ (G' : G.Subgraph) (hG' : Nonempty (H ≃g G'.coe)), {(aux hH hG').some}) := by - rw [killCopies]; exact dif_neg hH + rw [killCopies]; exact dite_eq_right hH /-- `G.killCopies H` has no effect on `G` if and only if `G` already contained no copies of `H`. See `Free.killCopies_eq_left` for the reverse implication with no assumption on `H`. -/ diff --git a/Mathlib/Combinatorics/SimpleGraph/Hall.lean b/Mathlib/Combinatorics/SimpleGraph/Hall.lean index 5194383974b3d1..e9d943a24009df 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Hall.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Hall.lean @@ -75,7 +75,7 @@ theorem exists_isMatching_of_forall_ncard_le (h₁ : G.IsBipartiteWith p₁ p₂ · exact ⟨f ⟨v, h'⟩, by simp_all⟩ · use x have := hx₂ ▸ this ⟨x, hx₁⟩ - simp only [this, ↓reduceDIte, hx₁, hx₂, dite_else_false, forall_exists_index, true_and] + simp only [this, ↓reduceDIte, hx₁, hx₂, dite_false_right, forall_exists_index, true_and] exact fun _ _ k ↦ Subtype.ext_iff.mp <| hf₁ (hx₂ ▸ k) lemma union_eq_univ_of_forall_ncard_le (h₁ : G.IsBipartiteWith p₁ p₂) @@ -123,7 +123,7 @@ theorem exists_isPerfectMatching_of_forall_ncard_le rw [Set.range_comp', hb₁.surjective.range_eq, Subtype.coe_image_univ] exact union_eq_univ_of_forall_ncard_le h₁ h₂ refine ⟨fun v _ ↦ ?_, Subgraph.isSpanning_iff.mpr this⟩ - simp only [dite_else_false] + simp only [dite_false_right] split · exact existsUnique_eq' · obtain ⟨x, _⟩ := hb₁.existsUnique ⟨v, by grind⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Prod.lean b/Mathlib/Combinatorics/SimpleGraph/Prod.lean index 6523376a74b33c..94fa64d5bf6331 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Prod.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Prod.lean @@ -151,7 +151,7 @@ theorem ofBoxProdLeft_boxProdLeft [DecidableEq β] [DecidableRel G.Adj] {a₁ a ∀ (w : G.Walk a₁ a₂), (w.boxProdLeft H b).ofBoxProdLeft = w | nil => rfl | cons' x y z h w => by - rw [Walk.boxProdLeft, map_cons, ofBoxProdLeft, Or.by_cases, dif_pos, ← Walk.boxProdLeft] + rw [Walk.boxProdLeft, map_cons, ofBoxProdLeft, Or.by_cases, dite_eq_left, ← Walk.boxProdLeft] · simp [ofBoxProdLeft_boxProdLeft] · exact ⟨h, rfl⟩ @@ -161,7 +161,7 @@ theorem ofBoxProdRight_boxProdRight [DecidableEq α] [DecidableRel G.Adj] {a b ∀ (w : G.Walk b₁ b₂), (w.boxProdRight G a).ofBoxProdRight = w | nil => rfl | cons' x y z h w => by - rw [Walk.boxProdRight, map_cons, ofBoxProdRight, Or.by_cases, dif_pos, ← + rw [Walk.boxProdRight, map_cons, ofBoxProdRight, Or.by_cases, dite_eq_left, ← Walk.boxProdRight] · simp [ofBoxProdRight_boxProdRight] · exact ⟨h, rfl⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Equitabilise.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Equitabilise.lean index 7f825d534c9a70..a95d4de4313b67 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Equitabilise.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Equitabilise.lean @@ -98,8 +98,8 @@ theorem equitabilise_aux (hs : a * m + b * (m + 1) = #s) : · exact fun x hx => (card_le_card sdiff_subset).trans (Nat.lt_succ_iff.1 <| h _ hx) simp_rw [extend_parts, filter_insert, htn, n, m.succ_ne_self.symm.ite_eq_right_iff] split_ifs with ha - · rw [hR₃, if_pos ha] - rw [card_insert_of_notMem, hR₃, if_neg ha, tsub_add_cancel_of_le] + · rw [hR₃, ite_eq_left ha] + rw [card_insert_of_notMem, hR₃, ite_eq_right ha, tsub_add_cancel_of_le] · exact hab.resolve_left ha · intro H; exact ht.ne_empty (le_sdiff_right.1 <| R.le <| filter_subset _ _ H) obtain ⟨u, hu₁, hu₂⟩ := h @@ -117,7 +117,7 @@ theorem equitabilise_aux (hs : a * m + b * (m + 1) = #s) : · conv in _ ∈ _ => rw [← insert_erase hu₁] simp only [mem_insert, forall_eq_or_imp, extend_parts] refine ⟨?_, fun x hx => (card_le_card ?_).trans <| hR₂ x ?_⟩ - · simp only [filter_insert, if_pos htu, biUnion_insert, id] + · simp only [filter_insert, ite_eq_left htu, biUnion_insert, id] obtain rfl | hut := eq_or_ne u t · rw [sdiff_eq_empty_iff_subset.2 subset_union_left] exact bot_le @@ -135,8 +135,8 @@ theorem equitabilise_aux (hs : a * m + b * (m + 1) = #s) : P.disjoint (mem_of_mem_erase hx) hu₁ <| ne_of_mem_erase hx).sdiff_eq_left⟩ simp only [extend_parts, filter_insert, htn, hn, m.succ_ne_self.symm.ite_eq_right_iff] split_ifs with h - · rw [hR₃, if_pos h] - · rw [card_insert_of_notMem, hR₃, if_neg h, Nat.sub_add_cancel (hab.resolve_left h)] + · rw [hR₃, ite_eq_left h] + · rw [card_insert_of_notMem, hR₃, ite_eq_right h, Nat.sub_add_cancel (hab.resolve_left h)] intro H; exact ht.ne_empty (le_sdiff_right.1 <| R.le <| filter_subset _ _ H) variable (h : a * m + b * (m + 1) = #s) diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Uniform.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Uniform.lean index 46fdb6fe2c6282..1ea99a3dd6edf4 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Uniform.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Uniform.lean @@ -131,29 +131,29 @@ noncomputable def nonuniformWitnesses (ε : 𝕜) (s t : Finset α) : Finset α theorem left_nonuniformWitnesses_subset (h : ¬G.IsUniform ε s t) : (G.nonuniformWitnesses ε s t).1 ⊆ s := by - rw [nonuniformWitnesses, dif_pos h] + rw [nonuniformWitnesses, dite_eq_left h] exact (not_isUniform_iff.1 h).choose_spec.1 theorem left_nonuniformWitnesses_card (h : ¬G.IsUniform ε s t) : #s * ε ≤ #(G.nonuniformWitnesses ε s t).1 := by - rw [nonuniformWitnesses, dif_pos h] + rw [nonuniformWitnesses, dite_eq_left h] exact (not_isUniform_iff.1 h).choose_spec.2.choose_spec.2.1 theorem right_nonuniformWitnesses_subset (h : ¬G.IsUniform ε s t) : (G.nonuniformWitnesses ε s t).2 ⊆ t := by - rw [nonuniformWitnesses, dif_pos h] + rw [nonuniformWitnesses, dite_eq_left h] exact (not_isUniform_iff.1 h).choose_spec.2.choose_spec.1 theorem right_nonuniformWitnesses_card (h : ¬G.IsUniform ε s t) : #t * ε ≤ #(G.nonuniformWitnesses ε s t).2 := by - rw [nonuniformWitnesses, dif_pos h] + rw [nonuniformWitnesses, dite_eq_left h] exact (not_isUniform_iff.1 h).choose_spec.2.choose_spec.2.2.1 theorem nonuniformWitnesses_spec (h : ¬G.IsUniform ε s t) : ε ≤ |G.edgeDensity (G.nonuniformWitnesses ε s t).1 (G.nonuniformWitnesses ε s t).2 - G.edgeDensity s t| := by - rw [nonuniformWitnesses, dif_pos h] + rw [nonuniformWitnesses, dite_eq_left h] exact (not_isUniform_iff.1 h).choose_spec.2.choose_spec.2.2.2 open scoped Classical in @@ -180,10 +180,10 @@ theorem nonuniformWitness_spec (h₁ : s ≠ t) (h₂ : ¬G.IsUniform ε s t) : (G.nonuniformWitness ε s t) (G.nonuniformWitness ε t s) - G.edgeDensity s t| := by unfold nonuniformWitness rcases trichotomous_of WellOrderingRel s t with (lt | rfl | gt) - · rw [if_pos lt, if_neg (asymm lt)] + · rw [ite_eq_left lt, ite_eq_right (asymm lt)] exact G.nonuniformWitnesses_spec h₂ · cases h₁ rfl - · rw [if_neg (asymm gt), if_pos gt, edgeDensity_comm, edgeDensity_comm _ s] + · rw [ite_eq_right (asymm gt), ite_eq_left gt, edgeDensity_comm, edgeDensity_comm _ s] apply G.nonuniformWitnesses_spec fun i => h₂ i.symm end SimpleGraph diff --git a/Mathlib/Combinatorics/Young/SemistandardTableau.lean b/Mathlib/Combinatorics/Young/SemistandardTableau.lean index dbf52e01a9f9d3..4cd178c0910ea9 100644 --- a/Mathlib/Combinatorics/Young/SemistandardTableau.lean +++ b/Mathlib/Combinatorics/Young/SemistandardTableau.lean @@ -130,10 +130,10 @@ theorem col_weak {μ : YoungDiagram} (T : SemistandardYoungTableau μ) {i1 i2 j def highestWeight (μ : YoungDiagram) : SemistandardYoungTableau μ where entry i j := if (i, j) ∈ μ then i else 0 row_weak' hj hcell := by - rw [if_pos hcell, if_pos (μ.up_left_mem (by rfl) (le_of_lt hj) hcell)] + rw [ite_eq_left hcell, ite_eq_left (μ.up_left_mem (by rfl) (le_of_lt hj) hcell)] col_strict' hi hcell := by - rwa [if_pos hcell, if_pos (μ.up_left_mem (le_of_lt hi) (by rfl) hcell)] - zeros' not_cell := if_neg not_cell + rwa [ite_eq_left hcell, ite_eq_left (μ.up_left_mem (le_of_lt hi) (by rfl) hcell)] + zeros' not_cell := ite_eq_right not_cell @[simp] theorem highestWeight_apply {μ : YoungDiagram} {i j : ℕ} : diff --git a/Mathlib/Computability/Encoding.lean b/Mathlib/Computability/Encoding.lean index 0b0068dc8658f7..02b6f9f3d7a5b9 100644 --- a/Mathlib/Computability/Encoding.lean +++ b/Mathlib/Computability/Encoding.lean @@ -115,7 +115,7 @@ theorem encodePosNum_nonempty (n : PosNum) : encodePosNum n ≠ [] := | one => rfl | bit1 m hm => rw [hm] - exact if_neg (encodePosNum_nonempty m) + exact ite_eq_right (encodePosNum_nonempty m) | bit0 m hm => exact congr_arg PosNum.bit0 hm @[simp] theorem decode_encodeNum (n) : decodeNum (encodeNum n) = n := by @@ -123,7 +123,7 @@ theorem encodePosNum_nonempty (n : PosNum) : encodePosNum n ≠ [] := · rfl rw [decode_encodePosNum n] rw [PosNum.cast_to_num] - exact if_neg (encodePosNum_nonempty n) + exact ite_eq_right (encodePosNum_nonempty n) @[simp] theorem decode_encodeNat (n) : decodeNat (encodeNat n) = n := by conv_rhs => rw [← Num.to_of_nat n] diff --git a/Mathlib/Computability/Primrec/List.lean b/Mathlib/Computability/Primrec/List.lean index 2ca0e9dd7b8ba4..d1face987fc048 100644 --- a/Mathlib/Computability/Primrec/List.lean +++ b/Mathlib/Computability/Primrec/List.lean @@ -267,7 +267,7 @@ theorem list_findIdx {f : α → List β} {p : α → β → Bool} (hf : Primrec f) (hp : Primrec₂ p) : Primrec fun a => (f a).findIdx (p a) := (list_foldr hf (const 0) <| to₂ <| cond (hp.comp fst <| fst.comp snd) (const 0) (succ.comp <| snd.comp snd)).of_eq - fun a => by dsimp; induction f a <;> simp [List.findIdx_cons, *] + fun a => by dsimp; induction f a <;> simp_all [List.findIdx_cons, Bool.cond_eq_ite] theorem list_idxOf [DecidableEq α] : Primrec₂ (@List.idxOf α _) := to₂ <| list_findIdx snd <| Primrec.beq.comp₂ snd.to₂ (fst.comp fst).to₂ @@ -299,7 +299,7 @@ theorem listLookup [DecidableEq α] : Primrec₂ (List.lookup : α → List (α (snd.comp <| snd.comp snd)).of_eq fun a ps => by induction ps with simp [List.lookup, *] - | cons p ps ih => cases ha : a == p.1 <;> simp + | cons p ps ih => cases ha : a == p.1 <;> simp_all [Bool.cond_eq_ite, beq_iff_eq] set_option linter.flexible false in -- TODO: revisit this after #13791 is merged theorem nat_omega_rec' (f : β → σ) {m : β → ℕ} {l : β → List β} {g : β → List σ → Option σ} diff --git a/Mathlib/Computability/RegularExpressions.lean b/Mathlib/Computability/RegularExpressions.lean index 27f759f5e87e2c..c1efa011b07ec5 100644 --- a/Mathlib/Computability/RegularExpressions.lean +++ b/Mathlib/Computability/RegularExpressions.lean @@ -160,11 +160,11 @@ theorem deriv_one (a : α) : deriv 1 a = 0 := @[simp] theorem deriv_char_self (a : α) : deriv (char a) a = 1 := - if_pos rfl + ite_eq_left rfl @[simp] theorem deriv_char_of_ne (h : a ≠ b) : deriv (char a) b = 0 := - if_neg h + ite_eq_right h @[simp] theorem deriv_add (P Q : RegularExpression α) (a : α) : deriv (P + Q) a = deriv P a + deriv Q a := diff --git a/Mathlib/Computability/TuringMachine/Config.lean b/Mathlib/Computability/TuringMachine/Config.lean index 96491b4d837f85..9ef81bdec7c257 100644 --- a/Mathlib/Computability/TuringMachine/Config.lean +++ b/Mathlib/Computability/TuringMachine/Config.lean @@ -376,7 +376,7 @@ theorem exists_code {n} {f : List.Vector ℕ n →. ℕ} (hf : Nat.Partrec' f) : | succ n IH => refine IH (fun {m} h' => hm (Nat.lt_succ_of_lt h')) (PFun.mem_fix_iff.2 (Or.inr ⟨_, ?_, this⟩)) - simp only [hf, hm n.lt_succ_self, Part.bind_some, List.headI, if_false, + simp only [hf, hm n.lt_succ_self, Part.bind_some, List.headI, ite_false, Part.mem_some_iff, List.tail_cons] end Code @@ -629,7 +629,7 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : refine ⟨v', h₁, ?_⟩ rw [stepRet] at h revert h - by_cases he : v'.headI = 0 <;> simp only [if_pos, if_false, he] <;> intro h + by_cases he : v'.headI = 0 <;> simp only [ite_eq_left, ite_false, he] <;> intro h · refine ⟨_, Part.mem_some _, ?_⟩ rw [reaches_eval] · exact h @@ -639,7 +639,7 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : rw [e₀, Cont.then, Cfg.then] at e₁ simp only at e₁ obtain ⟨v₁, hv₁, v₂, hv₂, h₃⟩ := - IH (stepRet (k₀.then (Cont.fix f k)) v₀) (by rw [stepRet, if_neg he, e₁]; rfl) + IH (stepRet (k₀.then (Cont.fix f k)) v₀) (by rw [stepRet, ite_eq_right he, e₁]; rfl) v'.tail _ stepRet_then (by apply ReflTransGen.single; rw [e₀]; rfl) refine ⟨_, PFun.mem_fix_iff.2 ?_, h₃⟩ simp only [Part.eq_some_iff.2 hv₁, Part.map_some, Part.mem_some_iff] @@ -659,7 +659,7 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : rw [reaches_eval] swap · exact ReflTransGen.single rfl - rwa [stepRet, if_pos h] + rwa [stepRet, ite_eq_left h] · obtain ⟨v₁, he₁, he₂⟩ := (Part.mem_map_iff _).1 he₁' split_ifs at he₂ with h; cases he₂ clear he₁' @@ -667,8 +667,8 @@ theorem cont_eval_fix {f k v} (fok : Code.Ok f) : rw [reaches_eval] swap · exact ReflTransGen.single rfl - rw [stepRet, if_neg h] - exact IH v₁.tail ((Part.mem_map_iff _).2 ⟨_, he₁, if_neg h⟩) + rw [stepRet, ite_eq_right h] + exact IH v₁.tail ((Part.mem_map_iff _).2 ⟨_, he₁, ite_eq_right h⟩) set_option backward.isDefEq.respectTransparency false in theorem code_is_ok (c) : Code.Ok c := by diff --git a/Mathlib/Computability/TuringMachine/StackTuringMachine.lean b/Mathlib/Computability/TuringMachine/StackTuringMachine.lean index 916694942a3bfe..139842ce8cdc9a 100644 --- a/Mathlib/Computability/TuringMachine/StackTuringMachine.lean +++ b/Mathlib/Computability/TuringMachine/StackTuringMachine.lean @@ -588,7 +588,8 @@ theorem tr_respects_aux₂ [DecidableEq K] {k : K} {q : TM1.Stmt (Γ' K Γ) (Λ' · refine ⟨_, fun k' ↦ ?_, by erw [List.length_cons, Tape.move_right_n_head, Tape.mk'_nth_nat, addBottom_nth_succ_fst, - cond_false, iterate_succ', Function.comp, Tape.move_right_left, Tape.move_right_n_head, + Bool.cond_false, iterate_succ', Function.comp, Tape.move_right_left, + Tape.move_right_n_head, Tape.mk'_nth_nat, Tape.write_move_right_n fun a : Γ' K Γ ↦ (a.1, update a.2 k none), addBottom_modifyNth fun a ↦ update a k none, addBottom_nth_snd, stk_nth_val _ (hL k), e, diff --git a/Mathlib/Computability/TuringMachine/Tape.lean b/Mathlib/Computability/TuringMachine/Tape.lean index 6263e04e12114b..a6c37b5b8f5b0c 100644 --- a/Mathlib/Computability/TuringMachine/Tape.lean +++ b/Mathlib/Computability/TuringMachine/Tape.lean @@ -264,11 +264,11 @@ theorem ListBlank.nth_modifyNth {Γ} [Inhabited Γ] (f : Γ → Γ) (n i) (L : L (L.modifyNth f n).nth i = if i = n then f (L.nth i) else L.nth i := by induction n generalizing i L with | zero => - cases i <;> simp only [ListBlank.nth_zero, if_true, ListBlank.head_cons, ListBlank.modifyNth, - ListBlank.nth_succ, if_false, ListBlank.tail_cons, reduceCtorEq] + cases i <;> simp only [ListBlank.nth_zero, ite_true, ListBlank.head_cons, ListBlank.modifyNth, + ListBlank.nth_succ, ite_false, ListBlank.tail_cons, reduceCtorEq] | succ n IH => cases i - · rw [if_neg (Nat.succ_ne_zero _).symm] + · rw [ite_eq_right (Nat.succ_ne_zero _).symm] simp only [ListBlank.nth_zero, ListBlank.head_cons, ListBlank.modifyNth] · simp only [IH, ListBlank.modifyNth, ListBlank.nth_succ, ListBlank.tail_cons, Nat.succ.injEq] diff --git a/Mathlib/Computability/TuringMachine/ToPartrec.lean b/Mathlib/Computability/TuringMachine/ToPartrec.lean index b4854519e3bd01..b14b0183f87cbe 100644 --- a/Mathlib/Computability/TuringMachine/ToPartrec.lean +++ b/Mathlib/Computability/TuringMachine/ToPartrec.lean @@ -604,7 +604,7 @@ theorem move_ok {p k₁ k₂ q s L₁ o L₂} {S : K' → List Γ'} (h₁ : k₁ rcases e₃ : splitAtPred p Sk with ⟨_, _, _⟩ rw [e₃] at e cases e - simp only [List.head?_cons, e₂, List.tail_cons, cond_false] + simp only [List.head?_cons, e₂, List.tail_cons, Bool.cond_false] convert! @IH _ (update (update S k₁ Sk) k₂ (a :: S k₂)) _ using 2 <;> simp [Function.update_of_ne, h₁, h₁.symm, e₃, List.reverseAux] simp [Function.update_comm h₁.symm] @@ -621,7 +621,7 @@ theorem move₂_ok {p k₁ k₂ q s L₁ o L₂} {S : K' → List Γ'} (h₁ : k refine (move_ok h₁.1 e).trans (TransGen.head rfl ?_) simp only [TM2.step, Option.mem_def, Option.elim] cases o <;> simp only <;> rw [tr] - <;> simp only [id, TM2.stepAux, Option.isSome, cond_true, cond_false] + <;> simp only [id, TM2.stepAux, Option.isSome, Bool.cond_true, Bool.cond_false] · convert! move_ok h₁.2.1.symm (splitAtPred_false _) using 2 simp only [Function.update_comm h₁.1, Function.update_idem] rw [show update S rev [] = S by rw [← h₂, Function.update_eq_self]] @@ -647,7 +647,8 @@ theorem clear_ok {p k q s L₁ o L₂} {S : K' → List Γ'} (e : splitAtPred p rfl simp only [splitAtPred, List.head?, List.tail_cons] at e ⊢ revert e; cases p a <;> intro e <;> - simp only [cond_false, cond_true, Prod.mk.injEq, true_and, false_and, reduceCtorEq] at e ⊢ + simp only [Bool.cond_false, Bool.cond_true, Prod.mk.injEq, true_and, false_and, + reduceCtorEq] at e ⊢ rcases e with ⟨e₁, e₂⟩ rw [e₁, e₂] | cons a L₁ IH => @@ -661,7 +662,7 @@ theorem clear_ok {p k q s L₁ o L₂} {S : K' → List Γ'} (e : splitAtPred p rcases e₃ : splitAtPred p Sk with ⟨_, _, _⟩ rw [e₃] at e cases e - simp only [List.head?_cons, e₂, List.tail_cons, cond_false] + simp only [List.head?_cons, e₂, List.tail_cons, Bool.cond_false] convert! @IH _ (update S k Sk) _ using 2 <;> simp [e₃] set_option backward.isDefEq.respectTransparency false in @@ -677,7 +678,7 @@ theorem copy_ok (q s a b c d) : rw [tr] simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_rev, List.head?_cons, Option.isSome_some, List.tail_cons, elim_update_rev, elim_main, elim_update_main, - elim_stack, elim_update_stack, cond_true, List.reverseAux_cons, pop', push'] + elim_stack, elim_update_stack, Bool.cond_true, List.reverseAux_cons, pop', push'] exact IH _ _ _ theorem trPosNum_natEnd : ∀ (n), ∀ x ∈ trPosNum n, natEnd x = false @@ -714,7 +715,7 @@ theorem head_main_ok {q s L} {c d : List Γ'} : rw [tr] simp only [TM2.step, Option.mem_def, TM2.stepAux, elim_update_main, elim_rev, elim_update_rev, Function.update_self, trList] - rw [if_neg (show o ≠ some Γ'.consₗ by cases L <;> simp [o])] + rw [ite_eq_right (show o ≠ some Γ'.consₗ by cases L <;> simp [o])] refine (clear_ok (splitAtPred_eq _ _ _ none [] ?_ ⟨rfl, rfl⟩)).trans ?_ · exact fun x h => Bool.decide_false (trList_ne_consₗ _ _ h) convert! unrev_ok using 2; simp [List.reverseAux_eq] @@ -834,8 +835,7 @@ theorem pred_ok (q₁ q₂ s v) (c d : List Γ') : ∃ s', cases m <;> refine ⟨_, _, rfl, rfl⟩ refine ⟨Γ'.bit0 :: l₁, _, some a, rfl, TransGen.single ?_⟩ simp [trPosNum, PosNum.succ, e, h, show some Γ'.bit1 ≠ some Γ'.bit0 by decide, - Option.getD, -natEnd] - rfl + show natEnd Γ'.bit1 = false from rfl, Option.getD, -natEnd] set_option backward.isDefEq.respectTransparency false in theorem trNormal_respects (c k v s) : diff --git a/Mathlib/Data/Bool/Count.lean b/Mathlib/Data/Bool/Count.lean index 33a55fa697bc09..23fc2d05ef5b2d 100644 --- a/Mathlib/Data/Bool/Count.lean +++ b/Mathlib/Data/Bool/Count.lean @@ -90,7 +90,7 @@ theorem two_mul_count_bool_eq_ite (hl : IsChain (· ≠ ·) l) (b : Bool) : if Even (length l) then length l else if Option.some b == l.head? then length l + 1 else length l - 1 := by by_cases h2 : Even (length l) - · rw [if_pos h2, hl.two_mul_count_bool_of_even h2] + · rw [ite_eq_left h2, hl.two_mul_count_bool_of_even h2] · rcases l with - | ⟨x, l⟩ · exact (h2 .zero).elim grind [hl.tail.two_mul_count_bool_of_even] diff --git a/Mathlib/Data/DFinsupp/Defs.lean b/Mathlib/Data/DFinsupp/Defs.lean index 849a45ceefdb56..aa1d6332483d5d 100644 --- a/Mathlib/Data/DFinsupp/Defs.lean +++ b/Mathlib/Data/DFinsupp/Defs.lean @@ -401,7 +401,7 @@ variable [DecidableEq ι] defined on this `Finset`. -/ def mk (s : Finset ι) (x : ∀ i : (↑s : Set ι), β (i : ι)) : Π₀ i, β i := ⟨fun i => if H : i ∈ s then x ⟨i, H⟩ else 0, - Trunc.mk ⟨s.1, fun i => if H : i ∈ s then Or.inl H else Or.inr <| dif_neg H⟩⟩ + Trunc.mk ⟨s.1, fun i => if H : i ∈ s then Or.inl H else Or.inr <| dite_eq_right H⟩⟩ variable {s : Finset ι} {x : ∀ i : (↑s : Set ι), β i} {i : ι} @@ -410,10 +410,10 @@ theorem mk_apply : (mk s x : ∀ i, β i) i = if H : i ∈ s then x ⟨i, H⟩ e rfl theorem mk_of_mem (hi : i ∈ s) : (mk s x : ∀ i, β i) i = x ⟨i, hi⟩ := - dif_pos hi + dite_eq_left hi theorem mk_of_notMem (hi : i ∉ s) : (mk s x : ∀ i, β i) i = 0 := - dif_neg hi + dite_eq_right hi theorem mk_injective (s : Finset ι) : Function.Injective (@mk ι β _ _ s) := by intro x y H @@ -513,11 +513,11 @@ theorem filter_single (p : ι → Prop) [DecidablePred p] (i : ι) (x : β i) : @[simp] theorem filter_single_pos {p : ι → Prop} [DecidablePred p] (i : ι) (x : β i) (h : p i) : - (single i x).filter p = single i x := by rw [filter_single, if_pos h] + (single i x).filter p = single i x := by rw [filter_single, ite_eq_left h] @[simp] theorem filter_single_neg {p : ι → Prop} [DecidablePred p] (i : ι) (x : β i) (h : ¬p i) : - (single i x).filter p = 0 := by rw [filter_single, if_neg h] + (single i x).filter p = 0 := by rw [filter_single, ite_eq_right h] /-- Equality of sigma types is sufficient (but not necessary) to show equality of `DFinsupp`s. -/ theorem single_eq_of_sigma_eq {i j} {xi : β i} {xj : β j} (h : (⟨i, xi⟩ : Sigma β) = ⟨j, xj⟩) : @@ -600,11 +600,11 @@ theorem erase_single (j : ι) (i : ι) (x : β i) : @[simp] theorem erase_single_same (i : ι) (x : β i) : (single i x).erase i = 0 := by - rw [erase_single, if_pos rfl] + rw [erase_single, ite_eq_left rfl] @[simp] theorem erase_single_ne {i j : ι} (x : β i) (h : i ≠ j) : (single i x).erase j = single i x := by - rw [erase_single, if_neg h] + rw [erase_single, ite_eq_right h] section Update @@ -719,16 +719,18 @@ theorem erase_sub {β : ι → Type v} [∀ i, AddGroup (β i)] (i : ι) (f g : theorem single_add_erase (i : ι) (f : Π₀ i, β i) : single i (f i) + f.erase i = f := ext fun i' => if h : i = i' then by - subst h; simp only [add_apply, single_apply, erase_apply, add_zero, dite_eq_ite, if_true] + subst h; simp only [add_apply, single_apply, erase_apply, add_zero, dite_eq_ite, ite_true] else by - simp only [add_apply, single_apply, erase_apply, dif_neg h, if_neg (Ne.symm h), zero_add] + simp only [add_apply, single_apply, erase_apply, dite_eq_right h, ite_eq_right (Ne.symm h), + zero_add] theorem erase_add_single (i : ι) (f : Π₀ i, β i) : f.erase i + single i (f i) = f := ext fun i' => if h : i = i' then by - subst h; simp only [add_apply, single_apply, erase_apply, zero_add, dite_eq_ite, if_true] + subst h; simp only [add_apply, single_apply, erase_apply, zero_add, dite_eq_ite, ite_true] else by - simp only [add_apply, single_apply, erase_apply, dif_neg h, if_neg (Ne.symm h), add_zero] + simp only [add_apply, single_apply, erase_apply, dite_eq_right h, ite_eq_right (Ne.symm h), + add_zero] protected theorem induction {p : (Π₀ i, β i) → Prop} (f : Π₀ i, β i) (h0 : p 0) (ha : ∀ (i b) (f : Π₀ i, β i), f i = 0 → b ≠ 0 → p f → p (single i b + f)) : p f := by diff --git a/Mathlib/Data/DFinsupp/Sigma.lean b/Mathlib/Data/DFinsupp/Sigma.lean index f86455601be5dd..b4b5e89b4142ce 100644 --- a/Mathlib/Data/DFinsupp/Sigma.lean +++ b/Mathlib/Data/DFinsupp/Sigma.lean @@ -50,7 +50,8 @@ def sigmaCurry [∀ i j, Zero (δ i j)] (f : Π₀ (i : Σ _, _), δ i.1 i.2) : { toFun := fun j ↦ f ⟨i, j⟩, support' := f.support'.map (fun ⟨m, hm⟩ ↦ ⟨m.filterMap (fun ⟨i', j'⟩ ↦ if h : i' = i then some <| h.rec j' else none), - fun j ↦ (hm ⟨i, j⟩).imp_left (fun h ↦ (m.mem_filterMap _).mpr ⟨⟨i, j⟩, h, dif_pos rfl⟩)⟩) } + fun j ↦ (hm ⟨i, j⟩).imp_left (fun h ↦ (m.mem_filterMap _).mpr + ⟨⟨i, j⟩, h, dite_eq_left rfl⟩)⟩) } support' := f.support'.map (fun ⟨m, hm⟩ ↦ ⟨m.map Sigma.fst, fun i ↦ Decidable.or_iff_not_imp_left.mpr (fun h ↦ DFinsupp.ext (fun j ↦ (hm ⟨i, j⟩).resolve_left (fun H ↦ (Multiset.mem_map.not.mp h) ⟨⟨i, j⟩, H, rfl⟩)))⟩) diff --git a/Mathlib/Data/DFinsupp/WellFounded.lean b/Mathlib/Data/DFinsupp/WellFounded.lean index 343b3729cc67a6..bee9a98715c285 100644 --- a/Mathlib/Data/DFinsupp/WellFounded.lean +++ b/Mathlib/Data/DFinsupp/WellFounded.lean @@ -77,27 +77,27 @@ theorem lex_fibration [∀ (i) (s : Set ι), Decidable (i ∈ s)] : split_ifs at hs with hp · refine ⟨⟨{ j | r j i → j ∈ p }, piecewise x₁ x { j | r j i }, x₂⟩, .fst ⟨i, fun j hj ↦ ?_, ?_⟩, ?_⟩ <;> simp only [piecewise_apply, Set.mem_ofPred_eq] - · simp only [if_pos hj] + · simp only [ite_eq_left hj] · split_ifs with hi - · rwa [hr i hi, if_pos hp] at hs + · rwa [hr i hi, ite_eq_left hp] at hs · assumption · ext1 j simp only [piecewise_apply, Set.mem_ofPred_eq] split_ifs with h₁ h₂ <;> try rfl - · rw [hr j h₂, if_pos (h₁ h₂)] + · rw [hr j h₂, ite_eq_left (h₁ h₂)] · rw [Classical.not_imp] at h₁ - rw [hr j h₁.1, if_neg h₁.2] + rw [hr j h₁.1, ite_eq_right h₁.2] · refine ⟨⟨{ j | r j i ∧ j ∈ p }, x₁, piecewise x₂ x { j | r j i }⟩, .snd ⟨i, fun j hj ↦ ?_, ?_⟩, ?_⟩ <;> simp only [piecewise_apply, Set.mem_ofPred_eq] - · exact if_pos hj + · exact ite_eq_left hj · split_ifs with hi - · rwa [hr i hi, if_neg hp] at hs + · rwa [hr i hi, ite_eq_right hp] at hs · assumption · ext1 j simp only [piecewise_apply, Set.mem_ofPred_eq] split_ifs with h₁ h₂ <;> try rfl - · rw [hr j h₁.1, if_pos h₁.2] - · rw [hr j h₂, if_neg] + · rw [hr j h₁.1, ite_eq_left h₁.2] + · rw [hr j h₂, ite_eq_right] simpa [h₂] using h₁ variable {r s} diff --git a/Mathlib/Data/ENat/Pow.lean b/Mathlib/Data/ENat/Pow.lean index b008843be24cac..2ed5ca6da57859 100644 --- a/Mathlib/Data/ENat/Pow.lean +++ b/Mathlib/Data/ENat/Pow.lean @@ -76,7 +76,7 @@ lemma epow_one : x ^ (1 : ℕ∞) = x := by lemma epow_top (h : 1 < x) : x ^ (⊤ : ℕ∞) = ⊤ := by have : (0 : ℕ∞) ≤ 1 := zero_le_one - rw [epow_def, if_neg, if_neg, if_neg] <;> grind + rw [epow_def, ite_eq_right, ite_eq_right, ite_eq_right] <;> grind lemma epow_right_mono (h : x ≠ 0) : Monotone (fun y : ℕ∞ ↦ x ^ y) := by intro y z y_z diff --git a/Mathlib/Data/EReal/Basic.lean b/Mathlib/Data/EReal/Basic.lean index 2e8a1d014a1c2c..b2a6d084f68a2c 100644 --- a/Mathlib/Data/EReal/Basic.lean +++ b/Mathlib/Data/EReal/Basic.lean @@ -192,13 +192,13 @@ protected theorem mul_comm (x y : EReal) : x * y = y * x := by rw [← coe_mul, ← coe_mul, mul_comm] protected theorem one_mul : ∀ x : EReal, 1 * x = x - | ⊤ => if_pos one_pos - | ⊥ => if_pos one_pos + | ⊤ => ite_eq_left one_pos + | ⊥ => ite_eq_left one_pos | (x : ℝ) => congr_arg Real.toEReal (one_mul x) protected theorem zero_mul : ∀ x : EReal, 0 * x = 0 - | ⊤ => (if_neg (lt_irrefl _)).trans (if_pos rfl) - | ⊥ => (if_neg (lt_irrefl _)).trans (if_pos rfl) + | ⊤ => (ite_eq_right (lt_irrefl _)).trans (ite_eq_left rfl) + | ⊥ => (ite_eq_right (lt_irrefl _)).trans (ite_eq_left rfl) | (x : ℝ) => congr_arg Real.toEReal (zero_mul x) instance : MulZeroOneClass EReal where @@ -675,7 +675,7 @@ private theorem coe_ennreal_top_mul (x : ℝ≥0) : ((⊤ * x : ℝ≥0∞) : ER rcases eq_or_ne x 0 with (rfl | h0) · simp · rw [ENNReal.top_mul (ENNReal.coe_ne_zero.2 h0)] - exact Eq.symm <| if_pos <| NNReal.coe_pos.2 h0.bot_lt + exact Eq.symm <| ite_eq_left <| NNReal.coe_pos.2 h0.bot_lt @[simp, norm_cast] theorem coe_ennreal_mul : ∀ x y : ℝ≥0∞, ((x * y : ℝ≥0∞) : EReal) = (x : EReal) * y @@ -701,7 +701,7 @@ noncomputable def toENNReal (x : EReal) : ℝ≥0∞ := @[simp] lemma toENNReal_of_ne_top {x : EReal} (hx : x ≠ ⊤) : x.toENNReal = ENNReal.ofReal x.toReal := - if_neg hx + ite_eq_right hx @[simp] lemma toENNReal_eq_top_iff {x : EReal} : x.toENNReal = ⊤ ↔ x = ⊤ := by @@ -713,7 +713,7 @@ lemma toENNReal_ne_top_iff {x : EReal} : x.toENNReal ≠ ⊤ ↔ x ≠ ⊤ := to @[simp] lemma toENNReal_of_nonpos {x : EReal} (hx : x ≤ 0) : x.toENNReal = 0 := by - rw [toENNReal, if_neg (fun h ↦ ?_)] + rw [toENNReal, ite_eq_right (fun h ↦ ?_)] · exact ENNReal.ofReal_of_nonpos (toReal_nonpos hx) · exact zero_ne_top <| top_le_iff.mp <| h ▸ hx @@ -734,9 +734,9 @@ lemma toENNReal_pos_iff {x : EReal} : 0 < x.toENNReal ↔ 0 < x := by lemma coe_toENNReal {x : EReal} (hx : 0 ≤ x) : (x.toENNReal : EReal) = x := by rw [toENNReal] by_cases h_top : x = ⊤ - · rw [if_pos h_top, h_top] + · rw [ite_eq_left h_top, h_top] rfl - rw [if_neg h_top] + rw [ite_eq_right h_top] simp only [coe_ennreal_ofReal, hx, toReal_nonneg, max_eq_left] exact coe_toReal h_top fun _ ↦ by simp_all only [le_bot_iff, zero_ne_bot] @@ -749,7 +749,7 @@ lemma coe_toENNReal_eq_max {x : EReal} : x.toENNReal = max 0 x := by lemma toENNReal_coe {x : ℝ≥0∞} : (x : EReal).toENNReal = x := by by_cases h_top : x = ⊤ · rw [h_top, coe_ennreal_top, toENNReal_top] - rwa [toENNReal, if_neg _, toReal_coe_ennreal, ENNReal.ofReal_toReal_eq_iff] + rwa [toENNReal, ite_eq_right _, toReal_coe_ennreal, ENNReal.ofReal_toReal_eq_iff] simp [h_top] @[simp] lemma real_coe_toENNReal (x : ℝ) : (x : EReal).toENNReal = ENNReal.ofReal x := rfl diff --git a/Mathlib/Data/EReal/Operations.lean b/Mathlib/Data/EReal/Operations.lean index ffd3ada1959d11..3a653a0bfb0424 100644 --- a/Mathlib/Data/EReal/Operations.lean +++ b/Mathlib/Data/EReal/Operations.lean @@ -569,16 +569,16 @@ lemma _root_.ENNReal.toEReal_sub {x y : ℝ≥0∞} (hy_top : y ≠ ∞) (h_le : @[simp] lemma bot_mul_bot : (⊥ : EReal) * ⊥ = ⊤ := rfl lemma coe_mul_top_of_pos {x : ℝ} (h : 0 < x) : (x : EReal) * ⊤ = ⊤ := - if_pos h + ite_eq_left h lemma coe_mul_top_of_neg {x : ℝ} (h : x < 0) : (x : EReal) * ⊤ = ⊥ := - (if_neg h.not_gt).trans (if_neg h.ne) + (ite_eq_right h.not_gt).trans (ite_eq_right h.ne) lemma top_mul_coe_of_pos {x : ℝ} (h : 0 < x) : (⊤ : EReal) * x = ⊤ := - if_pos h + ite_eq_left h lemma top_mul_coe_of_neg {x : ℝ} (h : x < 0) : (⊤ : EReal) * x = ⊥ := - (if_neg h.not_gt).trans (if_neg h.ne) + (ite_eq_right h.not_gt).trans (ite_eq_right h.ne) lemma mul_top_of_pos : ∀ {x : EReal}, 0 < x → x * ⊤ = ⊤ | ⊥, h => absurd h not_lt_bot @@ -605,16 +605,16 @@ lemma coe_ennreal_mul_top {x : ℝ≥0∞} (hx : x ≠ 0) : (x : EReal) * ⊤ = rw [EReal.mul_comm, top_mul_coe_ennreal hx] lemma coe_mul_bot_of_pos {x : ℝ} (h : 0 < x) : (x : EReal) * ⊥ = ⊥ := - if_pos h + ite_eq_left h lemma coe_mul_bot_of_neg {x : ℝ} (h : x < 0) : (x : EReal) * ⊥ = ⊤ := - (if_neg h.not_gt).trans (if_neg h.ne) + (ite_eq_right h.not_gt).trans (ite_eq_right h.ne) lemma bot_mul_coe_of_pos {x : ℝ} (h : 0 < x) : (⊥ : EReal) * x = ⊥ := - if_pos h + ite_eq_left h lemma bot_mul_coe_of_neg {x : ℝ} (h : x < 0) : (⊥ : EReal) * x = ⊤ := - (if_neg h.not_gt).trans (if_neg h.ne) + (ite_eq_right h.not_gt).trans (ite_eq_right h.ne) lemma mul_bot_of_pos : ∀ {x : EReal}, 0 < x → x * ⊥ = ⊥ | ⊥, h => absurd h not_lt_bot diff --git a/Mathlib/Data/Fin/SuccPred.lean b/Mathlib/Data/Fin/SuccPred.lean index 99d0eb5599a338..2a35447046b472 100644 --- a/Mathlib/Data/Fin/SuccPred.lean +++ b/Mathlib/Data/Fin/SuccPred.lean @@ -512,7 +512,7 @@ def succAbove (p : Fin (n + 1)) (i : Fin n) : Fin (n + 1) := /-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)` embeds `i` by `castSucc` when the resulting `i.castSucc < p`. -/ lemma succAbove_of_castSucc_lt (p : Fin (n + 1)) (i : Fin n) (h : castSucc i < p) : - p.succAbove i = castSucc i := if_pos h + p.succAbove i = castSucc i := ite_eq_left h lemma succAbove_of_succ_le (p : Fin (n + 1)) (i : Fin n) (h : succ i ≤ p) : p.succAbove i = castSucc i := @@ -521,7 +521,7 @@ lemma succAbove_of_succ_le (p : Fin (n + 1)) (i : Fin n) (h : succ i ≤ p) : /-- Embedding `i : Fin n` into `Fin (n + 1)` with a hole around `p : Fin (n + 1)` embeds `i` by `succ` when the resulting `p < i.succ`. -/ lemma succAbove_of_le_castSucc (p : Fin (n + 1)) (i : Fin n) (h : p ≤ castSucc i) : - p.succAbove i = i.succ := if_neg (Fin.not_lt.2 h) + p.succAbove i = i.succ := ite_eq_right (Fin.not_lt.2 h) lemma succAbove_of_lt_succ (p : Fin (n + 1)) (i : Fin n) (h : p < succ i) : p.succAbove i = succ i := succAbove_of_le_castSucc _ _ (le_castSucc_iff.mpr h) @@ -752,14 +752,14 @@ def predAbove (p : Fin n) (i : Fin (n + 1)) : Fin n := lemma predAbove_of_le_castSucc (p : Fin n) (i : Fin (n + 1)) (h : i ≤ castSucc p) : p.predAbove i = i.castPred (Fin.ne_of_lt <| Fin.lt_of_le_of_lt h <| castSucc_lt_last _) := - dif_neg <| Fin.not_lt.2 h + dite_eq_right <| Fin.not_lt.2 h lemma predAbove_of_lt_succ (p : Fin n) (i : Fin (n + 1)) (h : i < succ p) : p.predAbove i = i.castPred (Fin.ne_last_of_lt h) := predAbove_of_le_castSucc _ _ (le_castSucc_iff.mpr h) lemma predAbove_of_castSucc_lt (p : Fin n) (i : Fin (n + 1)) (h : castSucc p < i) : - p.predAbove i = i.pred (Fin.ne_zero_of_lt h) := dif_pos h + p.predAbove i = i.pred (Fin.ne_zero_of_lt h) := dite_eq_left h lemma predAbove_of_succ_le (p : Fin n) (i : Fin (n + 1)) (h : succ p ≤ i) : p.predAbove i = i.pred (Fin.ne_of_gt <| Fin.lt_of_lt_of_le (succ_pos _) h) := diff --git a/Mathlib/Data/Fin/Tuple/Basic.lean b/Mathlib/Data/Fin/Tuple/Basic.lean index b9119b3c735890..35e83dd2575ab4 100644 --- a/Mathlib/Data/Fin/Tuple/Basic.lean +++ b/Mathlib/Data/Fin/Tuple/Basic.lean @@ -555,7 +555,7 @@ theorem snoc_comp_natAdd {n m : ℕ} {α : Sort*} (f : Fin (m + n) → α) (a : @[simp] theorem snoc_castAdd {α : Fin (n + m + 1) → Sort*} (f : ∀ i : Fin (n + m), α i.castSucc) (a : α (last (n + m))) (i : Fin n) : (snoc f a) (castAdd (m + 1) i) = f (castAdd m i) := - dif_pos _ + dite_eq_left _ @[simp] theorem snoc_comp_castAdd {n m : ℕ} {α : Sort*} (f : Fin (n + m) → α) (a : α) : @@ -860,7 +860,8 @@ theorem insertNth_apply_same (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succ @[simp] theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j)) (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by - simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff_castSucc_lt] + simp only [insertNth, succAboveCases, dite_eq_right (succAbove_ne _ _), + succAbove_lt_iff_castSucc_lt] split_ifs with hlt · generalize_proofs H₁ H₂; revert H₂ generalize hk : castPred ((succAbove i) j) H₁ = k @@ -931,12 +932,12 @@ theorem insertNth_right_injective {p : Fin (n + 1)} (x : α p) : theorem insertNth_apply_below {i j : Fin (n + 1)} (h : j < i) (x : α i) (p : ∀ k, α (i.succAbove k)) : i.insertNth x p j = succAbove_castPred_of_lt _ _ h ▸ (p <| j.castPred _) := by - rw [insertNth, succAboveCases, dif_neg (Fin.ne_of_lt h), dif_pos h] + rw [insertNth, succAboveCases, dite_eq_right (Fin.ne_of_lt h), dite_eq_left h] theorem insertNth_apply_above {i j : Fin (n + 1)} (h : i < j) (x : α i) (p : ∀ k, α (i.succAbove k)) : i.insertNth x p j = succAbove_pred_of_lt _ _ h ▸ (p <| j.pred _) := by - rw [insertNth, succAboveCases, dif_neg (Fin.ne_of_gt h), dif_neg (Fin.lt_asymm h)] + rw [insertNth, succAboveCases, dite_eq_right (Fin.ne_of_gt h), dite_eq_right (Fin.lt_asymm h)] theorem insertNth_zero (x : α 0) (p : ∀ j : Fin n, α (succAbove 0 j)) : insertNth 0 x p = @@ -1276,16 +1277,16 @@ def contractNth (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → theorem contractNth_apply_of_lt (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n) (h : (k : ℕ) < j) : contractNth j op g k = g (Fin.castSucc k) := - if_pos h + ite_eq_left h theorem contractNth_apply_of_eq (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n) (h : (k : ℕ) = j) : contractNth j op g k = op (g (Fin.castSucc k)) (g k.succ) := by have : ¬(k : ℕ) < j := not_lt.2 (le_of_eq h.symm) - rw [contractNth, if_neg this, if_pos h] + rw [contractNth, ite_eq_right this, ite_eq_left h] theorem contractNth_apply_of_gt (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n) (h : (j : ℕ) < k) : contractNth j op g k = g k.succ := by - rw [contractNth, if_neg (not_lt_of_gt h), if_neg (Ne.symm <| ne_of_lt h)] + rw [contractNth, ite_eq_right (not_lt_of_gt h), ite_eq_right (Ne.symm <| ne_of_lt h)] theorem contractNth_apply_of_ne (j : Fin (n + 1)) (op : α → α → α) (g : Fin (n + 1) → α) (k : Fin n) (hjk : (j : ℕ) ≠ k) : contractNth j op g k = g (j.succAbove k) := by diff --git a/Mathlib/Data/Fin/Tuple/Embedding.lean b/Mathlib/Data/Fin/Tuple/Embedding.lean index cb8d5fdbeedaba..f260544e95668e 100644 --- a/Mathlib/Data/Fin/Tuple/Embedding.lean +++ b/Mathlib/Data/Fin/Tuple/Embedding.lean @@ -105,8 +105,8 @@ def twoEmbeddingEquiv : (Fin 2 ↪ α) ≃ {(a, b) : α × α | a ≠ b} where by_cases hi : i = 0 · by_cases hj : j = 0 · simp [hi, hj] - · simp only [if_pos hi, eq_one_of_ne_zero j hj, - if_neg (Ne.symm Fin.zero_ne_one)] at hij + · simp only [ite_eq_left hi, eq_one_of_ne_zero j hj, + ite_eq_right (Ne.symm Fin.zero_ne_one)] at hij apply (h hij).elim · rw [eq_one_of_ne_zero i hi] at hij ⊢ by_cases hj : j = 0 diff --git a/Mathlib/Data/Finset/Fold.lean b/Mathlib/Data/Finset/Fold.lean index 16aa414d5ab191..930bc0f7ed9510 100644 --- a/Mathlib/Data/Finset/Fold.lean +++ b/Mathlib/Data/Finset/Fold.lean @@ -82,7 +82,7 @@ theorem fold_const [hd : Decidable (s = ∅)] (c : β) (h : op c (op b c) = op b induction s using Finset.induction_on generalizing hd with | empty => simp | insert x s hx IH => - simp only [Finset.fold_insert hx, IH, if_false, Finset.insert_ne_empty] + simp only [Finset.fold_insert hx, IH, ite_false, Finset.insert_ne_empty] split_ifs · rw [hc.comm] · exact h diff --git a/Mathlib/Data/Finset/Functor.lean b/Mathlib/Data/Finset/Functor.lean index 37378ff5f2df82..303b2cbc5eea0e 100644 --- a/Mathlib/Data/Finset/Functor.lean +++ b/Mathlib/Data/Finset/Functor.lean @@ -97,10 +97,10 @@ instance lawfulApplicative : LawfulApplicative Finset := seqLeft_eq := fun s t => by rw [seq_def, fmap_def, seqLeft_def] obtain rfl | ht := t.eq_empty_or_nonempty - · simp_rw [image_empty, if_true] + · simp_rw [image_empty, ite_true] exact (sup_bot _).symm · ext a - rw [if_neg ht.ne_empty, mem_sup] + rw [ite_eq_right ht.ne_empty, mem_sup] refine ⟨fun ha => ⟨const _ a, mem_image_of_mem _ ha, mem_image_const_self.2 ht⟩, ?_⟩ rintro ⟨f, hf, ha⟩ rw [mem_image] at hf ha @@ -110,9 +110,9 @@ instance lawfulApplicative : LawfulApplicative Finset := seqRight_eq := fun s t => by rw [seq_def, fmap_def, seqRight_def] obtain rfl | hs := s.eq_empty_or_nonempty - · rw [if_pos rfl, image_empty, sup_empty, bot_eq_empty] + · rw [ite_eq_left rfl, image_empty, sup_empty, bot_eq_empty] · ext a - rw [if_neg hs.ne_empty, mem_sup] + rw [ite_eq_right hs.ne_empty, mem_sup] refine ⟨fun ha => ⟨id, mem_image_const_self.2 hs, by rwa [image_id]⟩, ?_⟩ rintro ⟨f, hf, ha⟩ rw [mem_image] at hf ha diff --git a/Mathlib/Data/Finset/Lattice/Pi.lean b/Mathlib/Data/Finset/Lattice/Pi.lean index 299f4d576a48a5..61ee351efad8de 100644 --- a/Mathlib/Data/Finset/Lattice/Pi.lean +++ b/Mathlib/Data/Finset/Lattice/Pi.lean @@ -45,7 +45,8 @@ theorem inf_sup {κ : ι → Type*} (s : Finset ι) (t : ∀ i, Finset (κ i)) ( -- `simpa` doesn't support placeholders in proof terms have := h (fun j hj => if hji : j = i then cast (congr_arg κ hji.symm) a else g _ <| mem_of_mem_insert_of_ne hj hji) (fun j hj => ?_) - · simpa only [cast_eq, dif_pos, Function.comp_def, Subtype.coe_mk, dif_neg, aux] using! this + · simpa only [cast_eq, dite_eq_left, Function.comp_def, Subtype.coe_mk, dite_eq_right, + aux] using! this rw [mem_insert] at hj obtain (rfl | hj) := hj · simpa diff --git a/Mathlib/Data/Finset/Sigma.lean b/Mathlib/Data/Finset/Sigma.lean index 258c4a79bc364f..90c97fec4127e2 100644 --- a/Mathlib/Data/Finset/Sigma.lean +++ b/Mathlib/Data/Finset/Sigma.lean @@ -169,16 +169,16 @@ theorem mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (a : Si rintro x hx rfl exact ⟨rfl, rfl, hx⟩ · rintro ⟨⟨⟩, ⟨⟩, hx⟩ - rw [sigmaLift, dif_pos rfl, mem_map] + rw [sigmaLift, dite_eq_left rfl, mem_map] exact ⟨_, hx, by simp⟩ - · rw [sigmaLift, dif_neg h] + · rw [sigmaLift, dite_eq_right h] refine iff_of_false (notMem_empty _) ?_ rintro ⟨⟨⟩, ⟨⟩, _⟩ exact h rfl theorem mk_mem_sigmaLift (f : ∀ ⦃i⦄, α i → β i → Finset (γ i)) (i : ι) (a : α i) (b : β i) (x : γ i) : (⟨i, x⟩ : Sigma γ) ∈ sigmaLift f ⟨i, a⟩ ⟨i, b⟩ ↔ x ∈ f a b := by - rw [sigmaLift, dif_pos rfl, mem_map] + rw [sigmaLift, dite_eq_left rfl, mem_map] refine ⟨?_, fun hx => ⟨_, hx, rfl⟩⟩ rintro ⟨x, hx, _, rfl⟩ exact hx diff --git a/Mathlib/Data/Finset/Update.lean b/Mathlib/Data/Finset/Update.lean index 2554f50ab5598b..f7cb268bc23a4c 100644 --- a/Mathlib/Data/Finset/Update.lean +++ b/Mathlib/Data/Finset/Update.lean @@ -44,7 +44,7 @@ theorem updateFinset_singleton {y} : congr with j by_cases hj : j = i · cases hj - simp only [dif_pos, Finset.mem_singleton, update_self, updateFinset] + simp only [dite_eq_left, Finset.mem_singleton, update_self, updateFinset] · simp [hj, updateFinset] theorem update_eq_updateFinset {y} : @@ -52,7 +52,7 @@ theorem update_eq_updateFinset {y} : congr with j by_cases hj : j = i · cases hj - simp only [dif_pos, Finset.mem_singleton, update_self, updateFinset] + simp only [dite_eq_left, Finset.mem_singleton, update_self, updateFinset] exact uniqueElim_default (α := fun j : ({i} : Finset ι) => π j) y · simp [hj, updateFinset] @@ -79,7 +79,8 @@ theorem updateFinset_updateFinset (hst : Disjoint s t) : set e := Equiv.Finset.union s t hst ext i by_cases his : i ∈ s <;> by_cases hit : i ∈ t <;> - simp only [updateFinset, his, hit, dif_pos, dif_neg, Finset.mem_union, false_or, not_false_iff] + simp only [updateFinset, his, hit, dite_eq_left, dite_eq_right, Finset.mem_union, false_or, + not_false_iff] · exfalso; exact Finset.disjoint_left.mp hst his hit · exact piCongrLeft_sumInl (fun b : ↥(s ∪ t) => π b) e y z ⟨i, his⟩ |>.symm · exact piCongrLeft_sumInr (fun b : ↥(s ∪ t) => π b) e y z ⟨i, hit⟩ |>.symm @@ -92,7 +93,7 @@ lemma updateFinset_updateFinset_of_subset {s t : Finset ι} (hst : s ⊆ t) lemma restrict_updateFinset_of_subset {s t : Finset ι} (hst : s ⊆ t) (x : Π i, π i) (y : Π i : t, π i) : s.restrict (updateFinset x t y) = restrict₂ hst y := by ext i - simp [updateFinset, dif_pos (hst i.2)] + simp [updateFinset, dite_eq_left (hst i.2)] lemma restrict_updateFinset {s : Finset ι} (x : Π i, π i) (y : Π i : s, π i) : s.restrict (updateFinset x s y) = y := by diff --git a/Mathlib/Data/Finsupp/Antidiagonal.lean b/Mathlib/Data/Finsupp/Antidiagonal.lean index be855b3c5530bd..7e5c63f197a281 100644 --- a/Mathlib/Data/Finsupp/Antidiagonal.lean +++ b/Mathlib/Data/Finsupp/Antidiagonal.lean @@ -68,8 +68,8 @@ theorem antidiagonal_single (a : α) (n : ℕ) : replace h := DFunLike.congr_fun h i simp_rw [single_apply, Finsupp.add_apply] at h ⊢ obtain rfl | hai := Decidable.eq_or_ne a i - · exact ⟨if_pos rfl, if_pos rfl⟩ - · simp_rw [if_neg hai, add_eq_zero] at h ⊢ + · exact ⟨ite_eq_left rfl, ite_eq_left rfl⟩ + · simp_rw [ite_eq_right hai, add_eq_zero] at h ⊢ exact h.imp Eq.symm Eq.symm · rintro ⟨a, b, rfl, rfl, rfl⟩ exact (single_add _ _ _).symm diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 777ee5ee3df887..23d06f1c3fe8f0 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -378,12 +378,12 @@ theorem mapDomain_apply' (S : Set α) {f : α → β} (x : α →₀ M) (hS : (x rw [mapDomain, sum_apply, sum] simp_rw [single_apply] by_cases hax : a ∈ x.support - · rw [← Finset.add_sum_erase _ _ hax, if_pos rfl] + · rw [← Finset.add_sum_erase _ _ hax, ite_eq_left rfl] convert! add_zero (x a) - refine Finset.sum_eq_zero fun i hi => if_neg ?_ + refine Finset.sum_eq_zero fun i hi => ite_eq_right ?_ exact (hf.mono hS).ne (Finset.mem_of_mem_erase hi) hax (Finset.ne_of_mem_erase hi) · rw [notMem_support_iff.1 hax] - refine Finset.sum_eq_zero fun i hi => if_neg ?_ + refine Finset.sum_eq_zero fun i hi => ite_eq_right ?_ exact hf.ne (hS hi) ha (ne_of_mem_of_not_mem hi hax) theorem mapDomain_support_of_injOn [DecidableEq β] {f : α → β} (s : α →₀ M) @@ -679,10 +679,10 @@ theorem filter_eq_self_iff : f.filter p = f ↔ ∀ x, f x ≠ 0 → p x := by not_imp_comm] @[simp] -theorem filter_apply_pos {a : α} (h : p a) : f.filter p a = f a := if_pos h +theorem filter_apply_pos {a : α} (h : p a) : f.filter p a = f a := ite_eq_left h @[simp] -theorem filter_apply_neg {a : α} (h : ¬p a) : f.filter p a = 0 := if_neg h +theorem filter_apply_neg {a : α} (h : ¬p a) : f.filter p a = 0 := ite_eq_right h @[simp] theorem support_filter : (f.filter p).support = {x ∈ f.support | p x} := rfl @@ -1207,12 +1207,12 @@ def piecewise (f : Subtype P →₀ M) (g : {a // ¬ P a} →₀ M) : α →₀ @[simp] theorem subtypeDomain_piecewise (f : Subtype P →₀ M) (g : {a // ¬ P a} →₀ M) : subtypeDomain P (f.piecewise g) = f := - Finsupp.ext fun a => dif_pos a.prop + Finsupp.ext fun a => dite_eq_left a.prop @[simp] theorem subtypeDomain_not_piecewise (f : Subtype P →₀ M) (g : {a // ¬ P a} →₀ M) : subtypeDomain (¬P ·) (f.piecewise g) = g := - Finsupp.ext fun a => dif_neg a.prop + Finsupp.ext fun a => dite_eq_right a.prop #adaptation_note /-- `respectTransparency.types true` changes the auto-generated lemmas' signature -/ diff --git a/Mathlib/Data/Finsupp/Indicator.lean b/Mathlib/Data/Finsupp/Indicator.lean index 49b648b96f9200..e573c873432d79 100644 --- a/Mathlib/Data/Finsupp/Indicator.lean +++ b/Mathlib/Data/Finsupp/Indicator.lean @@ -42,10 +42,10 @@ def indicator (s : Finset ι) (f : ∀ i ∈ s, α) : ι →₀ α where simp theorem indicator_of_mem (hi : i ∈ s) (f : ∀ i ∈ s, α) : indicator s f i = f i hi := - @dif_pos _ (id _) hi _ _ _ + @dite_eq_left _ (id _) hi _ _ _ theorem indicator_of_notMem (hi : i ∉ s) (f : ∀ i ∈ s, α) : indicator s f i = 0 := - @dif_neg _ (id _) hi _ _ _ + @dite_eq_right _ (id _) hi _ _ _ variable (s i) diff --git a/Mathlib/Data/Finsupp/Multiset.lean b/Mathlib/Data/Finsupp/Multiset.lean index deb70f5487adb9..c0f7e372e887cc 100644 --- a/Mathlib/Data/Finsupp/Multiset.lean +++ b/Mathlib/Data/Finsupp/Multiset.lean @@ -104,7 +104,7 @@ theorem count_toMultiset [DecidableEq α] (f : α →₀ ℕ) (a : α) : (toMult _ = f.sum fun x n => n * ({x} : Multiset α).count a := by simp only [Multiset.count_nsmul] _ = f a * ({a} : Multiset α).count a := sum_eq_single _ - (fun a' _ H => by simp only [Multiset.count_singleton, if_false, H.symm, mul_zero]) + (fun a' _ H => by simp only [Multiset.count_singleton, ite_false, H.symm, mul_zero]) (fun _ => zero_mul _) _ = f a := by rw [Multiset.count_singleton_self, mul_one] diff --git a/Mathlib/Data/Finsupp/Single.lean b/Mathlib/Data/Finsupp/Single.lean index 3addc245e32f4b..a03ff3917a7a08 100644 --- a/Mathlib/Data/Finsupp/Single.lean +++ b/Mathlib/Data/Finsupp/Single.lean @@ -99,7 +99,7 @@ theorem single_of_single_apply (a a' : α) (b : M) : grind @[simp] lemma support_single (a : α) (hb : b ≠ 0) : (single a b).support = {a} := - if_neg hb + ite_eq_right hb @[deprecated (since := "2026-05-05")] alias support_single_ne_zero := support_single diff --git a/Mathlib/Data/Finsupp/ToDFinsupp.lean b/Mathlib/Data/Finsupp/ToDFinsupp.lean index 8989f05d0f8a00..1db29b9c2d5b88 100644 --- a/Mathlib/Data/Finsupp/ToDFinsupp.lean +++ b/Mathlib/Data/Finsupp/ToDFinsupp.lean @@ -298,9 +298,10 @@ theorem sigmaFinsuppEquivDFinsupp_single [DecidableEq ι] [Zero N] (a : Σ i, η by_cases h : i = j · subst h classical simp [split_apply, Finsupp.single_apply] - suffices Finsupp.single (⟨i, a⟩ : Σ i, η i) n ⟨j, b⟩ = 0 by simp [split_apply, dif_neg h, this] + suffices Finsupp.single (⟨i, a⟩ : Σ i, η i) n ⟨j, b⟩ = 0 by + simp [split_apply, dite_eq_right h, this] have H : (⟨i, a⟩ : Σ i, η i) ≠ ⟨j, b⟩ := by simp [h] - classical rw [Finsupp.single_apply, if_neg H] + classical rw [Finsupp.single_apply, ite_eq_right H] -- Without this Lean fails to find the `AddZeroClass` instance on `Π₀ i, (η i →₀ N)`. attribute [-instance] Finsupp.instZero diff --git a/Mathlib/Data/Fintype/BigOperators.lean b/Mathlib/Data/Fintype/BigOperators.lean index cbf19a0177656e..586f0e13325f76 100644 --- a/Mathlib/Data/Fintype/BigOperators.lean +++ b/Mathlib/Data/Fintype/BigOperators.lean @@ -235,7 +235,7 @@ theorem Finset.prod_fin_eq_prod_range [CommMonoid β] {n : ℕ} (c : Fin n → ∏ i, c i = ∏ i ∈ Finset.range n, if h : i < n then c ⟨i, h⟩ else 1 := by rw [← Fin.prod_univ_eq_prod_range, Finset.prod_congr rfl] rintro ⟨i, hi⟩ _ - simp only [hi, dif_pos] + simp only [hi, dite_eq_left] @[to_additive] theorem Finset.prod_toFinset_eq_subtype {M : Type*} [CommMonoid M] [Fintype α] (p : α → Prop) diff --git a/Mathlib/Data/Int/Basic.lean b/Mathlib/Data/Int/Basic.lean index 894581f3ab530a..6c8cba6a788ae5 100644 --- a/Mathlib/Data/Int/Basic.lean +++ b/Mathlib/Data/Int/Basic.lean @@ -40,7 +40,7 @@ variable {P : ℤ → Sort*} {lt : ∀ n < m, P n} {ge : ∀ n ≥ m, (∀ k < n lemma strongRec_of_ge : ∀ hn : m ≤ n, m.strongRec lt ge n = ge n hn fun k _ ↦ m.strongRec lt ge k := by refine m.strongRec (fun n hnm hmn ↦ (Int.not_lt.mpr hmn hnm).elim) (fun n _ ih hn ↦ ?_) n - rw [Int.strongRec, dif_neg (Int.not_lt.mpr hn)] + rw [Int.strongRec, dite_eq_right (Int.not_lt.mpr hn)] congr; revert ih refine n.inductionOn' m (fun _ ↦ ?_) (fun k hmk ih' ih ↦ ?_) (fun k hkm ih' _ ↦ ?_) <;> ext l hl · rw [inductionOn'_self, strongRec_of_lt hl] diff --git a/Mathlib/Data/Int/Bitwise.lean b/Mathlib/Data/Int/Bitwise.lean index 5b65326ece0b7b..a672ee5a7dfbc6 100644 --- a/Mathlib/Data/Int/Bitwise.lean +++ b/Mathlib/Data/Int/Bitwise.lean @@ -220,8 +220,8 @@ theorem testBit_bit_succ (m b) : ∀ n, testBit (bit b n) (Nat.succ m) = testBit theorem bitwise_or : bitwise or = lor := by funext m n rcases m with m | m <;> rcases n with n | n <;> try {rfl} - <;> simp only [bitwise, natBitwise, Bool.not_false, Bool.or_true, cond_true, lor, Nat.ldiff, - negSucc.injEq, Bool.true_or] + <;> simp only [bitwise, natBitwise, Bool.not_false, Bool.or_true, Bool.cond_true, lor, + Nat.ldiff, negSucc.injEq, Bool.true_or] · rw [Nat.bitwise_swap, Function.swap] congr funext x y @@ -235,7 +235,7 @@ theorem bitwise_and : bitwise and = land := by funext m n rcases m with m | m <;> rcases n with n | n <;> try {rfl} <;> simp only [bitwise, natBitwise, Bool.not_false, - cond_false, cond_true, Bool.and_true, + Bool.cond_false, Bool.cond_true, Bool.and_true, Bool.and_false] · rw [Nat.bitwise_swap, Function.swap] congr @@ -249,7 +249,7 @@ theorem bitwise_diff : (bitwise fun a b => a && not b) = ldiff := by funext m n rcases m with m | m <;> rcases n with n | n <;> try {rfl} <;> simp only [bitwise, natBitwise, Bool.not_false, - cond_false, cond_true, Nat.ldiff, Bool.and_true, negSucc.injEq, + Bool.cond_false, Bool.cond_true, Nat.ldiff, Bool.and_true, negSucc.injEq, Bool.and_false, Bool.not_true, ldiff] · congr simp @@ -265,7 +265,7 @@ theorem bitwise_xor : bitwise xor = Int.xor := by funext m n rcases m with m | m <;> rcases n with n | n <;> try {rfl} <;> simp only [bitwise, natBitwise, Bool.not_false, Bool.bne_eq_xor, - cond_false, cond_true, negSucc.injEq, Bool.false_xor, + Bool.cond_false, Bool.cond_true, negSucc.injEq, Bool.false_xor, Bool.true_xor, Bool.not_true, Int.xor, HXor.hXor, XorOp.xor, Nat.xor] <;> simp diff --git a/Mathlib/Data/Int/ConditionallyCompleteOrder.lean b/Mathlib/Data/Int/ConditionallyCompleteOrder.lean index 7b15b462c15526..6cda7ddbab99e4 100644 --- a/Mathlib/Data/Int/ConditionallyCompleteOrder.lean +++ b/Mathlib/Data/Int/ConditionallyCompleteOrder.lean @@ -38,10 +38,10 @@ instance : ConditionallyCompleteLinearOrder ℤ where leastOfBdd (Classical.choose h.2) (Classical.choose_spec h.2) h.1 else 0 isLUB_csSup _ hn hb := by - rw [dif_pos ⟨hn, hb⟩] + rw [dite_eq_left ⟨hn, hb⟩] exact (isGreatest_coe_greatestOfBdd ..).isLUB isGLB_csInf _ hn hb := by - rw [dif_pos ⟨hn, hb⟩] + rw [dite_eq_left ⟨hn, hb⟩] exact (isLeast_coe_leastOfBdd ..).isGLB csSup_of_not_bddAbove := fun s hs ↦ by simp [hs] csInf_of_not_bddBelow := fun s hs ↦ by simp [hs] @@ -50,37 +50,37 @@ set_option backward.isDefEq.respectTransparency false in theorem csSup_eq_greatestOfBdd {s : Set ℤ} [DecidablePred (· ∈ s)] (b : ℤ) (Hb : ∀ z ∈ s, z ≤ b) (Hinh : ∃ z : ℤ, z ∈ s) : sSup s = greatestOfBdd b Hb Hinh := by have : s.Nonempty ∧ BddAbove s := ⟨Hinh, b, Hb⟩ - simp only [sSup, dif_pos this] + simp only [sSup, dite_eq_left this] convert! (coe_greatestOfBdd_eq Hb (Classical.choose_spec (⟨b, Hb⟩ : BddAbove s)) Hinh).symm @[simp] theorem csSup_empty : sSup (∅ : Set ℤ) = 0 := - dif_neg (by simp) + dite_eq_right (by simp) theorem csSup_of_not_bddAbove {s : Set ℤ} (h : ¬BddAbove s) : sSup s = 0 := - dif_neg (by simp [h]) + dite_eq_right (by simp [h]) set_option backward.isDefEq.respectTransparency false in theorem csInf_eq_leastOfBdd {s : Set ℤ} [DecidablePred (· ∈ s)] (b : ℤ) (Hb : ∀ z ∈ s, b ≤ z) (Hinh : ∃ z : ℤ, z ∈ s) : sInf s = leastOfBdd b Hb Hinh := by have : s.Nonempty ∧ BddBelow s := ⟨Hinh, b, Hb⟩ - simp only [sInf, dif_pos this] + simp only [sInf, dite_eq_left this] convert! (coe_leastOfBdd_eq Hb (Classical.choose_spec (⟨b, Hb⟩ : BddBelow s)) Hinh).symm @[simp] theorem csInf_empty : sInf (∅ : Set ℤ) = 0 := - dif_neg (by simp) + dite_eq_right (by simp) theorem csInf_of_not_bddBelow {s : Set ℤ} (h : ¬BddBelow s) : sInf s = 0 := - dif_neg (by simp [h]) + dite_eq_right (by simp [h]) theorem csSup_mem {s : Set ℤ} (h1 : s.Nonempty) (h2 : BddAbove s) : sSup s ∈ s := by convert! (greatestOfBdd _ (Classical.choose_spec h2) h1).2.1 - exact dif_pos ⟨h1, h2⟩ + exact dite_eq_left ⟨h1, h2⟩ theorem csInf_mem {s : Set ℤ} (h1 : s.Nonempty) (h2 : BddBelow s) : sInf s ∈ s := by convert! (leastOfBdd _ (Classical.choose_spec h2) h1).2.1 - exact dif_pos ⟨h1, h2⟩ + exact dite_eq_left ⟨h1, h2⟩ end Int diff --git a/Mathlib/Data/Int/Init.lean b/Mathlib/Data/Int/Init.lean index d71152ac6830cc..fb55fc31647617 100644 --- a/Mathlib/Data/Int/Init.lean +++ b/Mathlib/Data/Int/Init.lean @@ -192,7 +192,7 @@ and is analogous to `Nat.strongRec` for integers on or above the threshold. -/ · exact fun n _ hn l _ ↦ hn l (by lia) variable {lt ge} -lemma strongRec_of_lt (hn : n < m) : m.strongRec lt ge n = lt n hn := dif_pos _ +lemma strongRec_of_lt (hn : n < m) : m.strongRec lt ge n = lt n hn := dite_eq_left _ end strongRec diff --git a/Mathlib/Data/Int/Log.lean b/Mathlib/Data/Int/Log.lean index 671d2bd27912d5..7f172094086223 100644 --- a/Mathlib/Data/Int/Log.lean +++ b/Mathlib/Data/Int/Log.lean @@ -63,13 +63,13 @@ def log (b : ℕ) (r : R) : ℤ := omit [IsStrictOrderedRing R] in theorem log_of_one_le_right (b : ℕ) {r : R} (hr : 1 ≤ r) : log b r = Nat.log b ⌊r⌋₊ := - if_pos hr + ite_eq_left hr theorem log_of_right_le_one (b : ℕ) {r : R} (hr : r ≤ 1) : log b r = -Nat.clog b ⌈r⁻¹⌉₊ := by obtain rfl | hr := hr.eq_or_lt - · rw [log, if_pos hr, inv_one, Nat.ceil_one, Nat.floor_one, Nat.log_one_right, Nat.clog_one_right, - Int.ofNat_zero, neg_zero] - · exact if_neg hr.not_ge + · rw [log, ite_eq_left hr, inv_one, Nat.ceil_one, Nat.floor_one, Nat.log_one_right, + Nat.clog_one_right, Int.ofNat_zero, neg_zero] + · exact ite_eq_right hr.not_ge @[simp, norm_cast] theorem log_natCast (b : ℕ) (n : ℕ) : log b (n : R) = Nat.log b n := by @@ -185,16 +185,16 @@ def clog (b : ℕ) (r : R) : ℤ := omit [IsStrictOrderedRing R] in theorem clog_of_one_le_right (b : ℕ) {r : R} (hr : 1 ≤ r) : clog b r = Nat.clog b ⌈r⌉₊ := - if_pos hr + ite_eq_left hr theorem clog_of_right_le_one (b : ℕ) {r : R} (hr : r ≤ 1) : clog b r = -Nat.log b ⌊r⁻¹⌋₊ := by obtain rfl | hr := hr.eq_or_lt - · rw [clog, if_pos hr, inv_one, Nat.ceil_one, Nat.floor_one, Nat.log_one_right, + · rw [clog, ite_eq_left hr, inv_one, Nat.ceil_one, Nat.floor_one, Nat.log_one_right, Nat.clog_one_right, Int.ofNat_zero, neg_zero] - · exact if_neg hr.not_ge + · exact ite_eq_right hr.not_ge theorem clog_of_right_le_zero (b : ℕ) {r : R} (hr : r ≤ 0) : clog b r = 0 := by - rw [clog, if_neg (hr.trans_lt zero_lt_one).not_ge, neg_eq_zero, Int.natCast_eq_zero, + rw [clog, ite_eq_right (hr.trans_lt zero_lt_one).not_ge, neg_eq_zero, Int.natCast_eq_zero, Nat.log_eq_zero_iff] rcases le_or_gt b 1 with hb | hb · exact Or.inr hb @@ -259,7 +259,7 @@ omit [IsStrictOrderedRing R] in theorem clog_zero_left (r : R) : clog 0 r = 0 := by by_cases hr : 1 ≤ r · simp only [clog, Nat.clog_zero_left, Nat.cast_zero, Nat.log_zero_left, neg_zero, ite_self] - · simp only [clog, hr, ite_cond_eq_false, Nat.log_zero_left, Nat.cast_zero, neg_zero] + · simp only [clog, hr, ite_eq_right_of_eq_false, Nat.log_zero_left, Nat.cast_zero, neg_zero] omit [IsStrictOrderedRing R] in @[simp] diff --git a/Mathlib/Data/Int/WithZero.lean b/Mathlib/Data/Int/WithZero.lean index 7c6b5481f804ef..58dd7924a6b831 100644 --- a/Mathlib/Data/Int/WithZero.lean +++ b/Mathlib/Data/Int/WithZero.lean @@ -45,16 +45,17 @@ namespace WithZeroMulInt def toNNReal {e : ℝ≥0} (he : e ≠ 0) : ℤᵐ⁰ →*₀ ℝ≥0 where toFun := fun x ↦ if hx : x = 0 then 0 else e ^ (WithZero.unzero hx).toAdd map_zero' := rfl - map_one' := by rw [dif_neg one_ne_zero, unzero_coe (x := 1), toAdd_one, zpow_zero] + map_one' := by rw [dite_eq_right one_ne_zero, unzero_coe (x := 1), toAdd_one, zpow_zero] map_mul' x y := by by_cases hxy : x * y = 0 · rcases mul_eq_zero.mp hxy with hx | hy -- either x = 0 or y = 0 - · rw [dif_pos hxy, dif_pos hx, zero_mul] - · rw [dif_pos hxy, dif_pos hy, mul_zero] + · rw [dite_eq_left hxy, dite_eq_left hx, zero_mul] + · rw [dite_eq_left hxy, dite_eq_left hy, mul_zero] · obtain ⟨hx, hy⟩ := mul_ne_zero_iff.mp hxy -- x ≠ 0 and y ≠ 0 - rw [dif_neg hxy, dif_neg hx, dif_neg hy, ← zpow_add' (Or.inl he), ← toAdd_mul] + rw [dite_eq_right hxy, dite_eq_right hx, dite_eq_right hy, ← zpow_add' (Or.inl he), + ← toAdd_mul] congr rw [← WithZero.coe_inj, WithZero.coe_mul, coe_unzero hx, coe_unzero hy, coe_unzero hxy] diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 3e4a92e1a882c2..5a427b4774968a 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -138,7 +138,7 @@ instance [DecidableEq α] : Insert α (List α) := ⟨List.insert⟩ instance [DecidableEq α] : LawfulSingleton α (List α) := { insert_empty_eq := fun x => - show (if x ∈ ([] : List α) then [] else [x]) = [x] from if_neg not_mem_nil } + show (if x ∈ ([] : List α) then [] else [x]) = [x] from ite_eq_right not_mem_nil } theorem singleton_eq (x : α) : ({x} : List α) = [x] := rfl @@ -930,7 +930,11 @@ theorem filter_singleton {a : α} : [a].filter p = bif p a then [a] else [] := theorem filter_eq_foldr (p : α → Bool) (l : List α) : filter p l = foldr (fun a out => bif p a then a :: out else out) [] l := by - induction l <;> simp [*, filter]; rfl + induction l with + | nil => rfl + | cons a l ih => + simp [filter, ih] + cases p a <;> rfl @[simp] theorem filter_subset_self (l : List α) : filter p l ⊆ l := diff --git a/Mathlib/Data/List/Cycle.lean b/Mathlib/Data/List/Cycle.lean index 986d0000f82106..0f6deda6ab8241 100644 --- a/Mathlib/Data/List/Cycle.lean +++ b/Mathlib/Data/List/Cycle.lean @@ -49,13 +49,13 @@ theorem nextOr_singleton (x y d : α) : nextOr [y] x d = d := @[simp] theorem nextOr_self_cons_cons (xs : List α) (x y d : α) : nextOr (x :: y :: xs) x d = y := - if_pos rfl + ite_eq_left rfl theorem nextOr_cons_of_ne (xs : List α) (y x d : α) (h : x ≠ y) : nextOr (y :: xs) x d = nextOr xs x d := by rcases xs with - | ⟨z, zs⟩ · rfl - · exact if_neg h + · exact ite_eq_right h /-- `nextOr` does not depend on the default value, if the next value appears. -/ theorem nextOr_eq_nextOr_of_mem_dropLast (xs : List α) (x d d' : α) (x_mem : x ∈ xs.dropLast) : @@ -145,7 +145,7 @@ theorem prev_singleton (x y : α) (h : x ∈ [y]) : prev [y] x h = y := rfl theorem next_cons_cons_eq' (y z : α) (h : x ∈ y :: z :: l) (hx : x = y) : - next (y :: z :: l) x h = z := by rw [next, nextOr, if_pos hx] + next (y :: z :: l) x h = z := by rw [next, nextOr, ite_eq_left hx] @[simp] theorem next_cons_cons_eq (z : α) (h : x ∈ x :: z :: l) : next (x :: z :: l) x h = z := @@ -192,7 +192,7 @@ theorem prev_head_eq_getLast (hl : l ≠ []) : l.prev (l.head hl) (head_mem hl) | cons head tail => apply prev_getLast_cons theorem prev_cons_cons_eq' (y z : α) (h : x ∈ y :: z :: l) (hx : x = y) : - prev (y :: z :: l) x h = getLast (z :: l) (cons_ne_nil _ _) := by rw [prev, dif_pos hx] + prev (y :: z :: l) x h = getLast (z :: l) (cons_ne_nil _ _) := by rw [prev, dite_eq_left hx] theorem prev_cons_cons_eq (z : α) (h : x ∈ x :: z :: l) : prev (x :: z :: l) x h = getLast (z :: l) (cons_ne_nil _ _) := @@ -202,7 +202,7 @@ theorem prev_cons_cons_of_ne' (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) prev (y :: z :: l) x h = y := by cases l · simp [prev, hz] - · rw [prev, dif_neg hy, if_pos hz] + · rw [prev, dite_eq_right hy, ite_eq_left hz] theorem prev_cons_cons_of_ne (y : α) (h : x ∈ y :: x :: l) (hy : x ≠ y) : prev (y :: x :: l) x h = y := @@ -212,7 +212,7 @@ theorem prev_ne_cons_cons (y z : α) (h : x ∈ y :: z :: l) (hy : x ≠ y) (hz prev (y :: z :: l) x h = prev (z :: l) x (by simpa [hy] using h) := by cases l · simp [hy, hz] at h - · rw [prev, dif_neg hy, if_neg hz] + · rw [prev, dite_eq_right hy, ite_eq_right hz] theorem next_mem (h : x ∈ l) : l.next x h ∈ l := nextOr_mem (get_mem _ _) @@ -226,7 +226,7 @@ theorem prev_mem (h : x ∈ l) : l.prev x h ∈ l := by by_cases hx : x = hd · simp only [hx, prev_cons_cons_eq] exact mem_cons_of_mem _ (getLast_mem _) - · rw [prev, dif_neg hx] + · rw [prev, dite_eq_right hx] split_ifs with hm · exact mem_cons_self · exact mem_cons_of_mem _ (hl _ _) diff --git a/Mathlib/Data/List/Destutter.lean b/Mathlib/Data/List/Destutter.lean index 17264eea64df55..47b74339afca40 100644 --- a/Mathlib/Data/List/Destutter.lean +++ b/Mathlib/Data/List/Destutter.lean @@ -50,11 +50,11 @@ variable {R} @[simp] theorem destutter'_cons_pos (h : R b a) : (a :: l).destutter' R b = b :: l.destutter' R a := by - rw [destutter', if_pos h] + rw [destutter', ite_eq_left h] @[simp] theorem destutter'_cons_neg (h : ¬R b a) : (a :: l).destutter' R b = l.destutter' R b := by - rw [destutter', if_neg h] + rw [destutter', ite_eq_right h] variable (R) @@ -85,10 +85,10 @@ theorem isChain_destutter' (l : List α) (a : α) : (l.destutter' R a).IsChain R | nil => simp | singleton => simp [apply_ite] | cons_cons b c l IH IH2 => - simp_rw [destutter'_cons, apply_ite (IsChain R ·), IH, if_true_right] at IH2 + simp_rw [destutter'_cons, apply_ite (IsChain R ·), IH, ite_true_right] at IH2 simp_rw [destutter'_cons, apply_ite (IsChain R ·), apply_ite (IsChain R <| a :: ·), IH, isChain_cons_cons, - if_true_right, ite_prop_iff_and, imp_and] + ite_true_right, ite_prop_iff_and, imp_and] exact ⟨⟨⟨Function.swap <| fun _ => id, fun _ => IH2 c b⟩, Function.swap <| fun _ => IH2 b a⟩, fun _ => IH2 c a⟩ @@ -185,15 +185,15 @@ theorem length_destutter'_cotrans_ge [i : IsTrans α Rᶜ] : by_cases hbc : R b c case pos => have hac : ¬Rᶜ a c := (mt (_root_.trans hba)) (not_not.2 hbc) - simp_rw [destutter', if_pos (not_not.1 hac), if_pos hbc, length_cons, le_refl] + simp_rw [destutter', ite_eq_left (not_not.1 hac), ite_eq_left hbc, length_cons, le_refl] case neg => - simp only [destutter', if_neg hbc] + simp only [destutter', ite_eq_right hbc] by_cases hac : R a c case pos => - simp only [if_pos hac, length_cons] + simp only [ite_eq_left hac, length_cons] exact Nat.le_succ_of_le (length_destutter'_cotrans_ge hbc) case neg => - simp only [if_neg hac] + simp only [ite_eq_right hac] exact length_destutter'_cotrans_ge hba /-- `List.destutter'` on a relation like `≠`, whose negation is an equivalence, gives the same @@ -214,12 +214,12 @@ theorem le_length_destutter'_cons [IsEquiv α Rᶜ] : | [] => by by_cases hab : (R a b) <;> simp_all [Nat.le_succ] | c :: cs => by by_cases hab : R a b - case pos => simp [destutter', if_pos hab, Nat.le_succ] + case pos => simp [destutter', ite_eq_left hab, Nat.le_succ] obtain hac | hac : R a c ∨ Rᶜ a c := em _ · have hbc : ¬Rᶜ b c := mt (_root_.trans hab) (not_not.2 hac) - simp [destutter', if_pos hac, if_pos (not_not.1 hbc), if_neg hab] + simp [destutter', ite_eq_left hac, ite_eq_left (not_not.1 hbc), ite_eq_right hab] · have hbc : ¬R b c := trans (symm hab) hac - simp only [destutter', if_neg hbc, if_neg hac, if_neg hab] + simp only [destutter', ite_eq_right hbc, ite_eq_right hac, ite_eq_right hab] exact (length_destutter'_congr cs hab).ge /-- `List.destutter` on a relation like ≠, whose negation is an equivalence, has length @@ -284,6 +284,6 @@ lemma Pairwise.destutter_eq_dedup [DecidableEq α] {r : α → α → Prop} [Std · simpa using h.2.destutter_eq_dedup · simp only [mem_cons, forall_eq_or_imp, pairwise_cons] at h have : x ∉ xs := fun hx ↦ hxy (antisymm h.1.1 (h.2.1 x hx)) - rw [if_pos hxy, dedup_cons_of_notMem (a := x) (by simp [*])] + rw [ite_eq_left hxy, dedup_cons_of_notMem (a := x) (by simp [*])] end List diff --git a/Mathlib/Data/List/DropRight.lean b/Mathlib/Data/List/DropRight.lean index 1d2f505245b4ce..b8dcfd5e4c2639 100644 --- a/Mathlib/Data/List/DropRight.lean +++ b/Mathlib/Data/List/DropRight.lean @@ -104,11 +104,11 @@ theorem rdropWhile_concat (x : α) : @[simp] theorem rdropWhile_concat_pos (x : α) (h : p x) : rdropWhile p (l ++ [x]) = rdropWhile p l := by - rw [rdropWhile_concat, if_pos h] + rw [rdropWhile_concat, ite_eq_left h] @[simp] theorem rdropWhile_concat_neg (x : α) (h : ¬p x) : rdropWhile p (l ++ [x]) = l ++ [x] := by - rw [rdropWhile_concat, if_neg h] + rw [rdropWhile_concat, ite_eq_right h] theorem rdropWhile_singleton (x : α) : rdropWhile p [x] = if p x then [] else [x] := by rw [← nil_append [x], rdropWhile_concat, rdropWhile_nil] @@ -158,11 +158,11 @@ theorem rtakeWhile_concat (x : α) : @[simp] theorem rtakeWhile_concat_pos (x : α) (h : p x) : - rtakeWhile p (l ++ [x]) = rtakeWhile p l ++ [x] := by rw [rtakeWhile_concat, if_pos h] + rtakeWhile p (l ++ [x]) = rtakeWhile p l ++ [x] := by rw [rtakeWhile_concat, ite_eq_left h] @[simp] theorem rtakeWhile_concat_neg (x : α) (h : ¬p x) : rtakeWhile p (l ++ [x]) = [] := by - rw [rtakeWhile_concat, if_neg h] + rw [rtakeWhile_concat, ite_eq_right h] theorem rtakeWhile_suffix : l.rtakeWhile p <:+ l := by rw [← reverse_prefix, rtakeWhile, reverse_reverse] diff --git a/Mathlib/Data/List/MinMax.lean b/Mathlib/Data/List/MinMax.lean index 420af3ab5fc1ff..f7d5b900971112 100644 --- a/Mathlib/Data/List/MinMax.lean +++ b/Mathlib/Data/List/MinMax.lean @@ -57,7 +57,7 @@ private theorem foldl_argAux_mem (l) : ∀ a m : α, m ∈ foldl (argAux r) (som @[simp] theorem argAux_self (hr₀ : Std.Irrefl r) (a : α) : argAux r (some a) a = a := - if_neg <| hr₀.irrefl _ + ite_eq_right <| hr₀.irrefl _ theorem not_of_mem_foldl_argAux (hr₀ : Std.Irrefl r) (hr₁ : IsTrans α r) : ∀ {a m : α} {o : Option α}, a ∈ l → m ∈ foldl (argAux r) o l → ¬r a m := by @@ -151,15 +151,15 @@ theorem index_of_argmax : simp_all rw [h] at hm dsimp only at hm - simp only [cond_eq_ite, beq_iff_eq] + simp only [beq_iff_eq] obtain ha | ha := ha <;> split_ifs at hm <;> injection hm with hm <;> subst hm · cases not_le_of_gt ‹_› ‹_› - · rw [if_pos rfl] - · rw [if_neg, if_neg] + · rw [ite_eq_left rfl] + · rw [ite_eq_right, ite_eq_right] · exact Nat.succ_le_succ (index_of_argmax h (by assumption) ham) · exact ne_of_apply_ne f (lt_of_lt_of_le ‹_› ‹_›).ne · exact ne_of_apply_ne _ ‹f hd < f _›.ne - · rw [if_pos rfl] + · rw [ite_eq_left rfl] exact Nat.zero_le _ @[to_dual] diff --git a/Mathlib/Data/List/Sigma.lean b/Mathlib/Data/List/Sigma.lean index b7dc804c2cc447..f0b11128ebcfaf 100644 --- a/Mathlib/Data/List/Sigma.lean +++ b/Mathlib/Data/List/Sigma.lean @@ -162,11 +162,11 @@ theorem dlookup_nil (a : α) : dlookup a [] = @none (β a) := @[simp, grind =] theorem dlookup_cons_eq (l) (a : α) (b : β a) : dlookup a (⟨a, b⟩ :: l) = some b := - dif_pos rfl + dite_eq_left rfl @[simp, grind =] theorem dlookup_cons_ne (l) {a} : ∀ s : Sigma β, a ≠ s.1 → dlookup a (s :: l) = dlookup a l - | ⟨_, _⟩, h => dif_neg h.symm + | ⟨_, _⟩, h => dite_eq_right h.symm @[grind =] theorem dlookup_isSome {a : α} {l : List (Sigma β)} : (dlookup a l).isSome ↔ a ∈ l.keys := by @@ -288,11 +288,11 @@ theorem lookupAll_nil (a : α) : lookupAll a [] = @nil (β a) := @[simp] theorem lookupAll_cons_eq (l) (a : α) (b : β a) : lookupAll a (⟨a, b⟩ :: l) = b :: lookupAll a l := - dif_pos rfl + dite_eq_left rfl @[simp] theorem lookupAll_cons_ne (l) {a} : ∀ s : Sigma β, a ≠ s.1 → lookupAll a (s :: l) = lookupAll a l - | ⟨_, _⟩, h => dif_neg h.symm + | ⟨_, _⟩, h => dite_eq_right h.symm theorem lookupAll_eq_nil {a : α} : ∀ {l : List (Sigma β)}, lookupAll a l = [] ↔ ∀ b : β a, Sigma.mk a b ∉ l diff --git a/Mathlib/Data/List/Sort.lean b/Mathlib/Data/List/Sort.lean index a7c527dfe7a23a..edf396034cba0a 100644 --- a/Mathlib/Data/List/Sort.lean +++ b/Mathlib/Data/List/Sort.lean @@ -53,10 +53,10 @@ def orderedInsert (a : α) : List α → List α theorem orderedInsert_cons_of_le {a b : α} (l : List α) (h : a ≼ b) : orderedInsert r a (b :: l) = a :: b :: l := - dif_pos h + dite_eq_left h theorem orderedInsert_of_not_le {a b : α} (l : List α) (h : ¬ a ≼ b) : - orderedInsert r a (b :: l) = b :: orderedInsert r a l := dif_neg h + orderedInsert r a (b :: l) = b :: orderedInsert r a l := dite_eq_right h /-- `insertionSort l` returns `l` sorted using the insertion sort algorithm. -/ def insertionSort : List α → List α := foldr (orderedInsert r) [] @@ -192,7 +192,7 @@ theorem Sublist.orderedInsert_sublist [IsTrans α r] {as bs} (x) (hs : as <+ bs) · have hba := pairwise_cons.mp hb |>.left _ (mem_of_cons_sublist ‹a :: as <+ bs›) exact absurd (trans_of _ ‹r x b› hba) hr · have ih := orderedInsert_sublist x ‹a :: as <+ bs› hb.of_cons - rw [orderedInsert_cons, if_neg hr] at ih + rw [orderedInsert_cons, ite_eq_right hr] at ih exact .cons _ ih · simp_all · exact .cons_cons _ <| orderedInsert_sublist x ‹as <+ bs› hb.of_cons diff --git a/Mathlib/Data/Matrix/Basis.lean b/Mathlib/Data/Matrix/Basis.lean index 4cf260f92e8301..ec3326550f8501 100644 --- a/Mathlib/Data/Matrix/Basis.lean +++ b/Mathlib/Data/Matrix/Basis.lean @@ -39,7 +39,7 @@ variable (i : m) (j : n) (c : α) (i' : m) (j' : n) @[simp] theorem single_apply_same : single i j c i j = c := - if_pos (And.intro rfl rfl) + ite_eq_left (And.intro rfl rfl) @[simp] theorem single_apply_of_ne (h : ¬(i = i' ∧ j = j')) : single i j c i' j' = 0 := by @@ -294,7 +294,7 @@ variable [Zero α] (i j : n) (c : α) -- This simp lemma should take priority over `diag_apply` @[simp 1050] theorem diag_single_of_ne (h : i ≠ j) : diag (single i j c) = 0 := - funext fun _ => if_neg fun ⟨e₁, e₂⟩ => h (e₁.trans e₂.symm) + funext fun _ => ite_eq_right fun ⟨e₁, e₂⟩ => h (e₁.trans e₂.symm) -- This simp lemma should take priority over `diag_apply` @[simp 1050] diff --git a/Mathlib/Data/Matrix/Block.lean b/Mathlib/Data/Matrix/Block.lean index 6da760144a3f2b..72704590d5a0c3 100644 --- a/Mathlib/Data/Matrix/Block.lean +++ b/Mathlib/Data/Matrix/Block.lean @@ -340,11 +340,11 @@ theorem blockDiagonal_apply (M : o → Matrix m n α) (ik jk) : @[simp] theorem blockDiagonal_apply_eq (M : o → Matrix m n α) (i j k) : blockDiagonal M (i, k) (j, k) = M k i j := - if_pos rfl + ite_eq_left rfl theorem blockDiagonal_apply_ne (M : o → Matrix m n α) (i j) {k k'} (h : k ≠ k') : blockDiagonal M (i, k) (j, k') = 0 := - if_neg h + ite_eq_right h theorem blockDiagonal_map (M : o → Matrix m n α) (f : α → β) (hf : f 0 = 0) : (blockDiagonal M).map f = blockDiagonal fun k => (M k).map f := by @@ -594,11 +594,11 @@ theorem blockDiagonal'_apply (M : ∀ i, Matrix (m' i) (n' i) α) (ik jk) : @[simp] theorem blockDiagonal'_apply_eq (M : ∀ i, Matrix (m' i) (n' i) α) (k i j) : blockDiagonal' M ⟨k, i⟩ ⟨k, j⟩ = M k i j := - dif_pos rfl + dite_eq_left rfl theorem blockDiagonal'_apply_ne (M : ∀ i, Matrix (m' i) (n' i) α) {k k'} (i j) (h : k ≠ k') : blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩ = 0 := - dif_neg h + dite_eq_right h theorem blockDiagonal'_map (M : ∀ i, Matrix (m' i) (n' i) α) (f : α → β) (hf : f 0 = 0) : (blockDiagonal' M).map f = blockDiagonal' fun k => (M k).map f := by @@ -679,10 +679,10 @@ theorem blockDiagonal'_mul [NonUnitalNonAssocSemiring α] [∀ i, Fintype (n' i) ext ⟨k, i⟩ ⟨k', j⟩ simp only [blockDiagonal'_apply, mul_apply, ← Finset.univ_sigma_univ, Finset.sum_sigma] rw [Fintype.sum_eq_single k] - · simp only [dif_pos] + · simp only [dite_eq_left] split_ifs <;> simp · intro j' hj' - exact Finset.sum_eq_zero fun _ _ => by rw [dif_neg hj'.symm, zero_mul] + exact Finset.sum_eq_zero fun _ _ => by rw [dite_eq_right hj'.symm, zero_mul] section diff --git a/Mathlib/Data/Multiset/AddSub.lean b/Mathlib/Data/Multiset/AddSub.lean index 3f50a550897135..cb54202ac73bf9 100644 --- a/Mathlib/Data/Multiset/AddSub.lean +++ b/Mathlib/Data/Multiset/AddSub.lean @@ -252,8 +252,8 @@ theorem card_erase_le {a : α} {s : Multiset α} : card (s.erase a) ≤ card s : theorem card_erase_eq_ite {a : α} {s : Multiset α} : card (s.erase a) = if a ∈ s then pred (card s) else card s := by by_cases h : a ∈ s - · rwa [card_erase_of_mem h, if_pos] - · rwa [erase_of_notMem h, if_neg] + · rwa [card_erase_of_mem h, ite_eq_left] + · rwa [erase_of_notMem h, ite_eq_right] @[simp] theorem count_erase_self (a : α) (s : Multiset α) : count a (erase s a) = count a s - 1 := diff --git a/Mathlib/Data/Multiset/Filter.lean b/Mathlib/Data/Multiset/Filter.lean index b921fe0cd5676c..22a8fad423a891 100644 --- a/Mathlib/Data/Multiset/Filter.lean +++ b/Mathlib/Data/Multiset/Filter.lean @@ -262,7 +262,7 @@ theorem map_filter_eq_filterMap (f : α → β) (p : α → Prop) [DecidablePred induction s using Multiset.induction with | empty => simp | cons a s ih => - simp only [filter_cons, map_add, ih, filterMap_cons, Option.map_if]; clear ih; congr + simp only [filter_cons, map_add, ih, filterMap_cons, Option.map_ite]; clear ih; congr split_ifs <;> simp /-! ### countP -/ diff --git a/Mathlib/Data/Multiset/Pi.lean b/Mathlib/Data/Multiset/Pi.lean index 59f3724ed8dc94..268575e7f5e049 100644 --- a/Mathlib/Data/Multiset/Pi.lean +++ b/Mathlib/Data/Multiset/Pi.lean @@ -44,11 +44,11 @@ variable {m a} theorem cons_same {b : δ a} {f : ∀ a ∈ m, δ a} (h : a ∈ a ::ₘ m) : cons m a b f a h = b := - dif_pos rfl + dite_eq_left rfl theorem cons_ne {a a' : α} {b : δ a} {f : ∀ a ∈ m, δ a} (h' : a' ∈ a ::ₘ m) (h : a' ≠ a) : Pi.cons m a b f a' h' = f a' ((mem_cons.1 h').resolve_left h) := - dif_neg h + dite_eq_right h theorem cons_swap {a a' : α} {b : δ a} {b' : δ a'} {m : Multiset α} {f : ∀ a ∈ m, δ a} (h : a ≠ a') : Pi.cons (a' ::ₘ m) a b (Pi.cons m a' b' f) ≍ diff --git a/Mathlib/Data/Multiset/UnionInter.lean b/Mathlib/Data/Multiset/UnionInter.lean index 8948926ca64ba4..bc03f9b1411625 100644 --- a/Mathlib/Data/Multiset/UnionInter.lean +++ b/Mathlib/Data/Multiset/UnionInter.lean @@ -227,8 +227,8 @@ theorem replicate_inter (n : ℕ) (x : α) (s : Multiset α) : ext y rw [count_inter, count_replicate, count_replicate] by_cases h : x = y - · simp only [h, if_true] - · simp only [h, if_false, Nat.zero_min] + · simp only [h, ite_true] + · simp only [h, ite_false, Nat.zero_min] @[simp] theorem inter_replicate (s : Multiset α) (n : ℕ) (x : α) : diff --git a/Mathlib/Data/Nat/BinaryRec.lean b/Mathlib/Data/Nat/BinaryRec.lean index 6d032edc007928..f9405a0390ee02 100644 --- a/Mathlib/Data/Nat/BinaryRec.lean +++ b/Mathlib/Data/Nat/BinaryRec.lean @@ -96,7 +96,8 @@ decreasing_by obtain _ | n := n; · exact (n0 rfl).elim obtain _ | n := n; · simp have : (n + 1 + 1) >>> 1 ≠ 0 := Nat.div_ne_zero_iff.mpr ⟨by decide, le_add_left ..⟩ - simpa only [if_neg n0, if_neg this, log2_eq_succ_log2_shiftRight this] using lt_succ_self _ + simpa only [ite_eq_right n0, ite_eq_right this, + log2_eq_succ_log2_shiftRight this] using lt_succ_self _ /-- The same as `binaryRec`, but the induction step can assume that if `n=0`, the bit being appended is `true` -/ @@ -172,7 +173,7 @@ theorem binaryRec_eq {zero : motive 0} {bit : ∀ b n, motive n → motive (bit unfold binaryRec exact h.symm case neg => - rw [binaryRec, dif_neg h'] + rw [binaryRec, dite_eq_right h'] change congrArg motive (n.bit b).bit_testBit_zero_shiftRight_one ▸ bit _ _ _ = _ generalize congrArg motive (n.bit b).bit_testBit_zero_shiftRight_one = e; revert e rw [testBit_bit_zero, bit_shiftRight_one] @@ -186,13 +187,13 @@ theorem binaryRec_eq {zero : motive 0} {bit : ∀ b n, motive n → motive (bit @[simp] theorem binaryRec'_one (zero : motive 0) (bit : (b : Bool) → (n : Nat) → (n = 0 → b = true) → motive n → motive (n.bit b)) : binaryRec' (motive := motive) zero bit 1 = bit true 0 (by simp) zero := by - rw [binaryRec', binaryRec_one, dif_pos] + rw [binaryRec', binaryRec_one, dite_eq_left] theorem binaryRec'_eq {zero : motive 0} {bit : (b : Bool) → (n : Nat) → (n = 0 → b = true) → motive n → motive (n.bit b)} (b n) (h : n = 0 → b = true) : binaryRec' zero bit (n.bit b) = bit b n h (binaryRec' zero bit n) := by - rw [binaryRec', binaryRec_eq _ _ (by simp), dif_pos h, binaryRec'] + rw [binaryRec', binaryRec_eq _ _ (by simp), dite_eq_left h, binaryRec'] @[simp] theorem binaryRecFromOne_zero (zero : motive 0) (one : motive 1) (bit : (b : Bool) → (n : Nat) → n ≠ 0 → motive n → motive (n.bit b)) : @@ -202,13 +203,13 @@ theorem binaryRec'_eq {zero : motive 0} @[simp] theorem binaryRecFromOne_one {zero : motive 0} {one : motive 1} (bit : (b : Bool) → (n : Nat) → n ≠ 0 → motive n → motive (n.bit b)) : binaryRecFromOne zero one bit 1 = one := by - rw [binaryRecFromOne, binaryRec'_one, dif_pos rfl] + rw [binaryRecFromOne, binaryRec'_one, dite_eq_left rfl] theorem binaryRecFromOne_eq {zero : motive 0} {one : motive 1} {bit : (b : Bool) → (n : Nat) → n ≠ 0 → motive n → motive (n.bit b)} (b n) (h) : binaryRecFromOne zero one bit (Nat.bit b n) = bit b n h (binaryRecFromOne zero one bit n) := by - rw [binaryRecFromOne, binaryRec'_eq _ _ (by simp [h]), dif_neg h, binaryRecFromOne] + rw [binaryRecFromOne, binaryRec'_eq _ _ (by simp [h]), dite_eq_right h, binaryRecFromOne] end Nat diff --git a/Mathlib/Data/Nat/Bitwise.lean b/Mathlib/Data/Nat/Bitwise.lean index 4e490227eefbb8..3d0074aeae61f7 100644 --- a/Mathlib/Data/Nat/Bitwise.lean +++ b/Mathlib/Data/Nat/Bitwise.lean @@ -75,7 +75,7 @@ lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) : theorem binaryRec_of_ne_zero {C : Nat → Sort*} (z : C 0) (f : ∀ b n, C n → C (bit b n)) {n} (h : n ≠ 0) : binaryRec z f n = n.bit_bodd_div2 ▸ f n.bodd n.div2 (binaryRec z f n.div2) := by - rw [binaryRec, dif_neg h, eqRec_eq_cast, eqRec_eq_cast]; rfl + rw [binaryRec, dite_eq_right h, eqRec_eq_cast, eqRec_eq_cast]; rfl @[simp] lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) : diff --git a/Mathlib/Data/Nat/Cast/Defs.lean b/Mathlib/Data/Nat/Cast/Defs.lean index aa0ed1759839b7..0a7977754e8474 100644 --- a/Mathlib/Data/Nat/Cast/Defs.lean +++ b/Mathlib/Data/Nat/Cast/Defs.lean @@ -128,10 +128,11 @@ theorem binCast_eq [AddMonoidWithOne R] (n : ℕ) : rw [Nat.binCast] by_cases h : (k + 1) % 2 = 0 · conv => rhs; rw [← Nat.mod_add_div (k + 1) 2] - rw [if_pos h, hk _ <| Nat.div_lt_self (Nat.succ_pos k) (Nat.le_refl 2), ← Nat.cast_add] + rw [ite_eq_left h, hk _ <| Nat.div_lt_self (Nat.succ_pos k) (Nat.le_refl 2), ← Nat.cast_add] rw [h, Nat.zero_add, Nat.succ_mul, Nat.one_mul] · conv => rhs; rw [← Nat.mod_add_div (k + 1) 2] - rw [if_neg h, hk _ <| Nat.div_lt_self (Nat.succ_pos k) (Nat.le_refl 2), ← Nat.cast_add] + rw [ite_eq_right h, hk _ <| Nat.div_lt_self (Nat.succ_pos k) (Nat.le_refl 2), + ← Nat.cast_add] have h1 := Or.resolve_left (Nat.mod_two_eq_zero_or_one (succ k)) h rw [h1, Nat.add_comm 1, Nat.succ_mul, Nat.one_mul] simp only [Nat.cast_add, Nat.cast_one] diff --git a/Mathlib/Data/Nat/Choose/Multinomial.lean b/Mathlib/Data/Nat/Choose/Multinomial.lean index 589dc794165ac3..415ed18da45454 100644 --- a/Mathlib/Data/Nat/Choose/Multinomial.lean +++ b/Mathlib/Data/Nat/Choose/Multinomial.lean @@ -133,7 +133,7 @@ theorem multinomial_single [DecidableEq α] : · rw [eq_comm, factorial_zero] apply Finset.prod_eq_one intro _ hb - rw [Pi.single_apply, if_neg (ne_of_mem_of_not_mem hb ha), factorial_zero] + rw [Pi.single_apply, ite_eq_right (ne_of_mem_of_not_mem hb ha), factorial_zero] /-! ### Connection to binomial coefficients @@ -164,7 +164,7 @@ theorem binomial_succ_succ [DecidableEq α] (h : a ≠ b) : multinomial {a, b} (Function.update f b (f b).succ) := by simp only [binomial_eq_choose, Function.update_apply, h, Ne, ite_true, ite_false, not_false_eq_true] - rw [if_neg h.symm] + rw [ite_eq_right h.symm] rw [add_succ, choose_succ_succ, succ_add_eq_add_succ] ring @@ -276,8 +276,8 @@ lemma sum_pow_eq_sum_piAntidiag_of_commute (s : Finset α) (f : α → R) | cons a s has ih => ?_ rw [Finset.sum_cons, piAntidiag_cons, sum_disjiUnion] simp only [sum_map, Pi.add_apply, multinomial_cons, - Pi.add_apply, if_true, Nat.cast_mul, noncommProd_cons, - if_true, sum_add_distrib, sum_ite_eq', has, if_false, add_zero, + Pi.add_apply, ite_true, Nat.cast_mul, noncommProd_cons, + ite_true, sum_add_distrib, sum_ite_eq', has, ite_false, add_zero, addRightEmbedding_apply] suffices ∀ p : ℕ × ℕ, p ∈ antidiagonal n → ∑ g ∈ piAntidiag s p.2, ((g a + p.1 + s.sum g).choose (g a + p.1) : R) * @@ -300,10 +300,10 @@ lemma sum_pow_eq_sum_piAntidiag_of_commute (s : Finset α) (f : α → R) · rw [mem_antidiagonal.1 hp] · rw [multinomial_congr] intro t ht - rw [Pi.add_apply, if_neg, add_zero] + rw [Pi.add_apply, ite_eq_right, add_zero] exact ne_of_mem_of_not_mem ht has refine noncommProd_congr rfl (fun t ht ↦ ?_) _ - rw [if_neg, add_zero] + rw [ite_eq_right, add_zero] exact ne_of_mem_of_not_mem ht has /-- The **multinomial theorem**. -/ @@ -439,9 +439,9 @@ theorem multinomial_cons (x : ℕ) (l : List ℕ) : ext i by_cases hi : i = 0 · simp [hi] - · simp [Finsupp.update_apply, if_neg hi, Finsupp.single_eq_of_ne hi] + · simp [Finsupp.update_apply, ite_eq_right hi, Finsupp.single_eq_of_ne hi] have h (x) : (l.toFinsupp.embDomain succEmb) (x + 1) = l[x]?.getD 0 := by - rw [Finsupp.embDomain_apply, dif_pos ⟨x, by simp [succEmb]⟩] + rw [Finsupp.embDomain_apply, dite_eq_left ⟨x, by simp [succEmb]⟩] simp [succEmb] simp [toFinsupp_cons_eq_single_add_embDomain, Finsupp.multinomial_eq, succEmb, this, Nat.multinomial, h] diff --git a/Mathlib/Data/Nat/Choose/Sum.lean b/Mathlib/Data/Nat/Choose/Sum.lean index bd330feba8b9b3..b1b469609209eb 100644 --- a/Mathlib/Data/Nat/Choose/Sum.lean +++ b/Mathlib/Data/Nat/Choose/Sum.lean @@ -198,7 +198,7 @@ theorem Int.alternating_sum_range_choose {n : ℕ} : theorem Int.alternating_sum_range_choose_of_ne {n : ℕ} (h0 : n ≠ 0) : (∑ m ∈ range (n + 1), ((-1) ^ m * n.choose m : ℤ)) = 0 := by - rw [Int.alternating_sum_range_choose, if_neg h0] + rw [Int.alternating_sum_range_choose, ite_eq_right h0] namespace Finset @@ -224,7 +224,7 @@ theorem sum_powerset_neg_one_pow_card_of_nonempty {α : Type*} {x : Finset α} ( (∑ m ∈ x.powerset, (-1 : ℤ) ^ #m) = 0 := by classical rw [sum_powerset_neg_one_pow_card] - exact if_neg (nonempty_iff_ne_empty.mp h0) + exact ite_eq_right (nonempty_iff_ne_empty.mp h0) variable [NonAssocSemiring R] diff --git a/Mathlib/Data/Nat/Digits/Defs.lean b/Mathlib/Data/Nat/Digits/Defs.lean index a8af782476861e..1b23d25af60d77 100644 --- a/Mathlib/Data/Nat/Digits/Defs.lean +++ b/Mathlib/Data/Nat/Digits/Defs.lean @@ -499,9 +499,9 @@ lemma toDigitsCore_lens_eq_aux (b f : Nat) : | zero => assumption | succ f ih => if hx : n / b = 0 then - simp only [hx, if_true, List.length, congrArg (fun l ↦ l + 1) hlen] + simp only [hx, ite_true, List.length, congrArg (fun l ↦ l + 1) hlen] else - simp only [hx, if_false] + simp only [hx, ite_false] specialize ih (n / b) (Nat.digitChar (n % b) :: l1) (Nat.digitChar (n % b) :: l2) simp only [List.length, congrArg (fun l ↦ l + 1) hlen] at ih exact ih trivial diff --git a/Mathlib/Data/Nat/Digits/Lemmas.lean b/Mathlib/Data/Nat/Digits/Lemmas.lean index 396761fc325d77..b7072ee91ef68e 100644 --- a/Mathlib/Data/Nat/Digits/Lemmas.lean +++ b/Mathlib/Data/Nat/Digits/Lemmas.lean @@ -214,6 +214,7 @@ theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits {p : ℕ} (n : ℕ) : theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by + simp only [Bool.cond_eq_ite] induction n using Nat.binaryRecFromOne with | zero => simp | one => simp diff --git a/Mathlib/Data/Nat/Init.lean b/Mathlib/Data/Nat/Init.lean index 1593364ec90cad..7144497528ac19 100644 --- a/Mathlib/Data/Nat/Init.lean +++ b/Mathlib/Data/Nat/Init.lean @@ -157,7 +157,7 @@ lemma leRec_self {n} {motive : (m : ℕ) → n ≤ m → Sort*} (le_succ_of_le : ∀ ⦃k⦄ (h : n ≤ k), motive k h → motive (k + 1) (le_succ_of_le h)) : (leRec (motive := motive) refl le_succ_of_le (Nat.le_refl _) : motive n (Nat.le_refl _)) = refl := by - cases n <;> simp [leRec, Or.by_cases, dif_neg] + cases n <;> simp [leRec, Or.by_cases, dite_eq_right] @[simp] lemma leRec_succ {n} {motive : (m : ℕ) → n ≤ m → Sort*} @@ -168,7 +168,7 @@ lemma leRec_succ {n} {motive : (m : ℕ) → n ≤ m → Sort*} le_succ_of_le h1 (leRec (motive := motive) refl le_succ_of_le h1) := by conv => lhs - rw [leRec, Or.by_cases, dif_pos h1] + rw [leRec, Or.by_cases, dite_eq_left h1] lemma leRec_succ' {n} {motive : (m : ℕ) → n ≤ m → Sort*} (refl le_succ_of_le) : (leRec (motive := motive) refl le_succ_of_le (le_succ _)) = le_succ_of_le _ refl := by diff --git a/Mathlib/Data/Nat/Log.lean b/Mathlib/Data/Nat/Log.lean index 2fc1a49008cd88..cb2bb551a46ab6 100644 --- a/Mathlib/Data/Nat/Log.lean +++ b/Mathlib/Data/Nat/Log.lean @@ -74,7 +74,7 @@ def log (b n : ℕ) : ℕ := if q < b then (q, 2 * e) else (q / b, 2 * e + 1) theorem log_of_left_le_one {b : ℕ} (hb : b ≤ 1) (n) : log b n = 0 := by - rw [log, if_pos hb] + rw [log, ite_eq_left hb] theorem log_of_lt {b n : ℕ} (hb : n < b) : log b n = 0 := by fun_cases log with @@ -99,7 +99,7 @@ lemma log.go_spec {b n fuel : ℕ} (hb : 1 < b) (hn : n ≠ 0) (hfuel : n < b ^ | inr hnb => rcases ih (Nat.one_mul 1 ▸ Nat.mul_lt_mul_of_lt_of_lt hb hb) (go_aux hb hfuel hnb) with ⟨ih₁, ih₂, ih₃⟩ - simp_all only [go, if_neg (Nat.not_lt_of_le hnb), ← Nat.pow_two, ← Nat.pow_mul, + simp_all only [go, ite_eq_right (Nat.not_lt_of_le hnb), ← Nat.pow_two, ← Nat.pow_mul, Nat.div_lt_iff_lt_mul, Nat.pow_pos (Nat.zero_lt_of_lt hb), Nat.div_div_eq_div_mul, ← Nat.pow_add_one, ← Nat.pow_add_one', Nat.mul_add_one] split <;> simp_all @@ -107,7 +107,7 @@ lemma log.go_spec {b n fuel : ℕ} (hb : 1 < b) (hn : n ≠ 0) (hfuel : n < b ^ theorem log_lt_iff_lt_pow {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) : log b y < x ↔ y < b ^ x := by rcases log.go_spec hb hy (Nat.lt_pow_self hb) with ⟨-, H₁, H₂⟩ - rw [log, if_neg (Nat.not_le_of_lt hb)] + rw [log, ite_eq_right (Nat.not_le_of_lt hb)] cases Nat.lt_or_ge (log.go y b y).snd x with | inl h => exact iff_of_true h <| Nat.lt_of_lt_of_le H₂ <| Nat.pow_le_pow_right (Nat.zero_lt_of_lt hb) h @@ -375,7 +375,7 @@ theorem clog.go_spec {n b fuel} (hn : 1 < n) (hb : 1 < b) (hfuel : n < b ^ fuel) | inl hbn => rcases ih (Nat.one_mul 1 ▸ Nat.mul_lt_mul_of_lt_of_lt hb hb) (log.go_aux hb hfuel (Nat.le_of_lt hbn)) with ⟨ih₁, ih₂, ih₃⟩ - simp_all only [go, if_neg (Nat.not_le_of_gt hbn), ← Nat.pow_two, ← Nat.pow_mul, + simp_all only [go, ite_eq_right (Nat.not_le_of_gt hbn), ← Nat.pow_two, ← Nat.pow_mul, Nat.div_lt_iff_lt_mul (Nat.zero_lt_of_lt hbn), Nat.div_div_eq_div_mul, Nat.mul_comm n b, Nat.mul_add_one, @Nat.pow_add_one' _ (2 * _ + 1), Nat.mul_lt_mul_left, Nat.mul_div_mul_left, Nat.zero_lt_of_lt hb] @@ -398,7 +398,7 @@ theorem clog_le_iff_le_pow {b : ℕ} (hb : 1 < b) {x y : ℕ} : clog b x ≤ y | case2 h => grind [Nat.one_le_pow] theorem clog_pos {b n : ℕ} (hb : 1 < b) (hn : 1 < n) : 0 < clog b n := by - rw [clog, if_pos] + rw [clog, ite_eq_left] exacts [Nat.succ_pos _, ⟨hb, hn⟩] theorem clog_of_one_lt {b n : ℕ} (hb : 1 < b) (hn : 1 < n) : diff --git a/Mathlib/Data/Nat/ModEq.lean b/Mathlib/Data/Nat/ModEq.lean index 1ffd68b0527a5b..a34b8afdb71e82 100644 --- a/Mathlib/Data/Nat/ModEq.lean +++ b/Mathlib/Data/Nat/ModEq.lean @@ -476,7 +476,7 @@ def chineseRemainder (co : n.Coprime m) (a b : ℕ) : { k // k ≡ a [MOD n] ∧ theorem chineseRemainder'_lt_lcm (h : a ≡ b [MOD gcd n m]) (hn : n ≠ 0) (hm : m ≠ 0) : ↑(chineseRemainder' h) < lcm n m := by dsimp only [chineseRemainder'] - rw [dif_neg hn, dif_neg hm, Subtype.coe_mk, xgcd_val, ← Int.toNat_natCast (lcm n m)] + rw [dite_eq_right hn, dite_eq_right hm, Subtype.coe_mk, xgcd_val, ← Int.toNat_natCast (lcm n m)] have lcm_pos := Int.natCast_pos.mpr (Nat.pos_of_ne_zero (lcm_ne_zero hn hm)) exact (Int.toNat_lt_toNat lcm_pos).mpr (Int.emod_lt_of_pos _ lcm_pos) @@ -530,15 +530,16 @@ theorem add_mod_add_ite (a b c : ℕ) : · rw [Nat.mod_eq_of_lt (lt_of_not_ge h), add_zero] theorem add_mod_of_add_mod_lt {a b c : ℕ} (hc : a % c + b % c < c) : - (a + b) % c = a % c + b % c := by rw [← add_mod_add_ite, if_neg (not_le_of_gt hc), add_zero] + (a + b) % c = a % c + b % c := by + rw [← add_mod_add_ite, ite_eq_right (not_le_of_gt hc), add_zero] theorem add_mod_add_of_le_add_mod {a b c : ℕ} (hc : c ≤ a % c + b % c) : - (a + b) % c + c = a % c + b % c := by rw [← add_mod_add_ite, if_pos hc] + (a + b) % c + c = a % c + b % c := by rw [← add_mod_add_ite, ite_eq_left hc] theorem add_div_eq_of_add_mod_lt {a b c : ℕ} (hc : a % c + b % c < c) : (a + b) / c = a / c + b / c := if hc0 : c = 0 then by simp [hc0] - else by rw [Nat.add_div (Nat.pos_of_ne_zero hc0), if_neg (not_le_of_gt hc), add_zero] + else by rw [Nat.add_div (Nat.pos_of_ne_zero hc0), ite_eq_right (not_le_of_gt hc), add_zero] protected theorem add_div_of_dvd_right {a b c : ℕ} (hca : c ∣ a) : (a + b) / c = a / c + b / c := if h : c = 0 then by simp [h] @@ -552,7 +553,7 @@ protected theorem add_div_of_dvd_left {a b c : ℕ} (hca : c ∣ b) : (a + b) / rwa [add_comm, Nat.add_div_of_dvd_right, add_comm] theorem add_div_eq_of_le_mod_add_mod {a b c : ℕ} (hc : c ≤ a % c + b % c) (hc0 : 0 < c) : - (a + b) / c = a / c + b / c + 1 := by rw [Nat.add_div hc0, if_pos hc] + (a + b) / c = a / c + b / c + 1 := by rw [Nat.add_div hc0, ite_eq_left hc] @[deprecated Nat.div_add_div_le_add_div (since := "2026-08-05")] theorem add_div_le_add_div (a b c : ℕ) : a / c + b / c ≤ (a + b) / c := diff --git a/Mathlib/Data/Nat/Multiplicity.lean b/Mathlib/Data/Nat/Multiplicity.lean index 46024dc2133dd1..642009443795e7 100644 --- a/Mathlib/Data/Nat/Multiplicity.lean +++ b/Mathlib/Data/Nat/Multiplicity.lean @@ -277,7 +277,7 @@ theorem emultiplicity_two_factorial_lt : ∀ {n : ℕ} (_ : n ≠ 0), emultiplic by_cases hn : n = 0 · subst hn simp only [ne_eq, bit_eq_zero_iff, true_and, Bool.not_eq_false] at h - simp only [bit, h, cond_true, mul_zero, zero_add, factorial_one] + simp only [bit, h, Bool.cond_true, mul_zero, zero_add, factorial_one] rw [Prime.emultiplicity_one] · exact zero_lt_one · decide diff --git a/Mathlib/Data/Nat/Nth.lean b/Mathlib/Data/Nat/Nth.lean index 96b0924441a24a..ad85ecb8368646 100644 --- a/Mathlib/Data/Nat/Nth.lean +++ b/Mathlib/Data/Nat/Nth.lean @@ -70,11 +70,11 @@ variable {p} theorem nth_of_card_le (hf : (Set.ofPred p).Finite) {n : ℕ} (hn : #hf.toFinset ≤ n) : - nth p n = 0 := by rw [nth, dif_pos hf, List.getD_eq_default]; rwa [Finset.length_sort] + nth p n = 0 := by rw [nth, dite_eq_left hf, List.getD_eq_default]; rwa [Finset.length_sort] theorem nth_eq_getD_sort (h : (Set.ofPred p).Finite) (n : ℕ) : nth p n = h.toFinset.sort.getD n 0 := - dif_pos h + dite_eq_left h theorem nth_eq_orderEmbOfFin (hf : (Set.ofPred p).Finite) {n : ℕ} (hn : n < #hf.toFinset) : nth p n = hf.toFinset.orderEmbOfFin rfl ⟨n, hn⟩ := by @@ -134,7 +134,8 @@ theorem exists_lt_card_finite_nth_eq (hf : (Set.ofPred p).Finite) {x} (h : p x) /-- When `s` is an infinite set, `nth` agrees with `Nat.Subtype.orderIsoOfNat`. -/ theorem nth_apply_eq_orderIsoOfNat (hf : (Set.ofPred p).Infinite) (n : ℕ) : - nth p n = @Nat.Subtype.orderIsoOfNat (Set.ofPred p) hf.to_subtype n := by rw [nth, dif_neg hf] + nth p n = @Nat.Subtype.orderIsoOfNat (Set.ofPred p) hf.to_subtype n := by + rw [nth, dite_eq_right hf] /-- When `s` is an infinite set, `nth` agrees with `Nat.Subtype.orderIsoOfNat`. -/ theorem nth_eq_orderIsoOfNat (hf : (Set.ofPred p).Infinite) : @@ -303,7 +304,7 @@ lemma nth_le_of_strictMonoOn_of_mapsTo {p : ℕ → Prop} (f : ℕ → ℕ) have : f k < f n := by apply hmono <;> grind grind · rcases hn with ⟨hf, hn⟩ - rw [nth, dif_pos hf, List.getD_eq_default _ _ (by simp [hn])] + rw [nth, dite_eq_left hf, List.getD_eq_default _ _ (by simp [hn])] exact Nat.zero_le _ /-- `Nat.nth p` is the greatest monotone function whose image contains `Set.ofPred p`. -/ @@ -449,11 +450,11 @@ theorem surjective_count_of_infinite_setOfPred (h : {n | p n}.Infinite) : alias surjective_count_of_infinite_setOf := surjective_count_of_infinite_setOfPred theorem count_nth_succ {n : ℕ} (hn : ∀ hf : (Set.ofPred p).Finite, n < #hf.toFinset) : - count p (nth p n + 1) = n + 1 := by rw [count_succ, count_nth hn, if_pos (nth_mem _ hn)] + count p (nth p n + 1) = n + 1 := by rw [count_succ, count_nth hn, ite_eq_left (nth_mem _ hn)] lemma count_nth_succ_of_infinite (hp : (Set.ofPred p).Infinite) (n : ℕ) : count p (nth p n + 1) = n + 1 := by - rw [count_succ, count_nth_of_infinite hp, if_pos (nth_mem_of_infinite hp _)] + rw [count_succ, count_nth_of_infinite hp, ite_eq_left (nth_mem_of_infinite hp _)] @[simp] theorem nth_count {n : ℕ} (hpn : p n) : nth p (count p n) = n := diff --git a/Mathlib/Data/Nat/Pairing.lean b/Mathlib/Data/Nat/Pairing.lean index eebe7c9f10f407..86ef7be745b111 100644 --- a/Mathlib/Data/Nat/Pairing.lean +++ b/Mathlib/Data/Nat/Pairing.lean @@ -140,8 +140,8 @@ theorem pair_lt_max_add_one_sq (m n : ℕ) : pair m n < (max m n + 1) ^ 2 := by theorem max_sq_add_min_le_pair (m n : ℕ) : max m n ^ 2 + min m n ≤ pair m n := by rw [pair] rcases lt_or_ge m n with h | h - · rw [if_pos h, max_eq_right h.le, min_eq_left h.le, Nat.pow_two] - rw [if_neg h.not_gt, max_eq_left h, min_eq_right h, Nat.pow_two, Nat.add_assoc, + · rw [ite_eq_left h, max_eq_right h.le, min_eq_left h.le, Nat.pow_two] + rw [ite_eq_right h.not_gt, max_eq_left h, min_eq_right h, Nat.pow_two, Nat.add_assoc, Nat.add_le_add_iff_left] exact Nat.le_add_left _ _ diff --git a/Mathlib/Data/Nat/Totient.lean b/Mathlib/Data/Nat/Totient.lean index 59083f41358979..67ecfe1b316f0b 100644 --- a/Mathlib/Data/Nat/Totient.lean +++ b/Mathlib/Data/Nat/Totient.lean @@ -126,7 +126,8 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by suffices 2 = orderOf (-1 : (ZMod n)ˣ) by rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this] exact orderOf_dvd_card - rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne'] + rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, + ite_eq_right hn.ne'] theorem totient_mul {m n : ℕ} (h : m.Coprime n) : φ (m * n) = φ m * φ n := if hmn0 : m * n = 0 then by @@ -223,7 +224,7 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr rw [totient_one, tsub_self] at h exact one_ne_zero h rw [totient_eq_card_coprime, range_eq_Ico, ← Finset.insert_Ico_add_one_left_eq_Ico hp.le, - Finset.filter_insert, if_neg (not_coprime_of_dvd_of_dvd hp (dvd_refl p) (dvd_zero p)), + Finset.filter_insert, ite_eq_right (not_coprime_of_dvd_of_dvd hp (dvd_refl p) (dvd_zero p)), ← Nat.card_Ico 1 p] at h refine p.prime_of_coprime hp fun n hn hnz => Finset.filter_card_eq h n <| Finset.mem_Ico.mpr ⟨?_, hn⟩ diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index 9a921aa540033f..23ff8ba08e9fee 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -303,9 +303,11 @@ theorem of_to_nat' : ∀ n : PosNum, Num.ofNat' (n : ℕ) = Num.pos n simp only [cast_one, Num.ofNat'_one] norm_cast | bit0 p => by - simpa only [Nat.bit_false, cond_false, two_mul, of_to_nat' p] using! Num.ofNat'_bit false p + simpa only [Nat.bit_false, Bool.cond_false, two_mul, of_to_nat' p] using! + Num.ofNat'_bit false p | bit1 p => by - simpa only [Nat.bit_true, cond_true, two_mul, of_to_nat' p] using! Num.ofNat'_bit true p + simpa only [Nat.bit_true, Bool.cond_true, two_mul, of_to_nat' p] using! + Num.ofNat'_bit true p end PosNum diff --git a/Mathlib/Data/Num/Prime.lean b/Mathlib/Data/Num/Prime.lean index 05de04fe8517c3..69e2b8c29a1309 100644 --- a/Mathlib/Data/Num/Prime.lean +++ b/Mathlib/Data/Num/Prime.lean @@ -66,7 +66,7 @@ def minFac : PosNum → PosNum theorem minFac_to_nat (n : PosNum) : (minFac n : ℕ) = Nat.minFac n := by obtain - | n := n · simp [minFac] - · rw [minFac, Nat.minFac_eq, if_neg] + · rw [minFac, Nat.minFac_eq, ite_eq_right] swap · simp [← two_mul] rw [minFacAux_to_nat] @@ -77,7 +77,7 @@ theorem minFac_to_nat (n : PosNum) : (minFac n : ℕ) = Nat.minFac n := by (n : ℕ) + (n : ℕ) + 1 ≤ (n : ℕ) + (n : ℕ) + (n : ℕ) := by simp _ = (n : ℕ) * (1 + 1 + 1) := by simp only [mul_add, mul_one] _ < _ := by simp [mul_lt_mul] - · rw [minFac, Nat.minFac_eq, if_pos] + · rw [minFac, Nat.minFac_eq, ite_eq_left] · rfl simp [← two_mul] diff --git a/Mathlib/Data/Ordering/Lemmas.lean b/Mathlib/Data/Ordering/Lemmas.lean index fdc0ed101ecbb9..a4ab4cf73abae3 100644 --- a/Mathlib/Data/Ordering/Lemmas.lean +++ b/Mathlib/Data/Ordering/Lemmas.lean @@ -47,11 +47,12 @@ attribute [local simp] cmpUsing @[simp] theorem cmpUsing_eq_lt (a b : α) : (cmpUsing lt a b = Ordering.lt) = lt a b := by - simp only [cmpUsing, Ordering.ite_eq_lt_distrib, ite_self, if_false_right, and_true, reduceCtorEq] + simp only [cmpUsing, Ordering.ite_eq_lt_distrib, ite_self, ite_false_right, and_true, + reduceCtorEq] @[simp] theorem cmpUsing_eq_gt [IsStrictOrder α lt] (a b : α) : cmpUsing lt a b = Ordering.gt ↔ lt b a := by - simp only [cmpUsing, Ordering.ite_eq_gt_distrib, if_false_right, and_true, if_false_left, + simp only [cmpUsing, Ordering.ite_eq_gt_distrib, ite_false_right, and_true, ite_false_left, and_iff_right_iff_imp, reduceCtorEq] exact fun hba hab ↦ (irrefl a) (_root_.trans hab hba) diff --git a/Mathlib/Data/Ordmap/Invariants.lean b/Mathlib/Data/Ordmap/Invariants.lean index 88e8f969e186aa..f9b77f45967cb3 100644 --- a/Mathlib/Data/Ordmap/Invariants.lean +++ b/Mathlib/Data/Ordmap/Invariants.lean @@ -569,7 +569,7 @@ theorem balance_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Si cases sr.2.2.2.1.size_eq_zero.1 this.1 cases sr.2.2.2.2.size_eq_zero.1 this.2 obtain rfl : rrs = 1 := sr.2.2.1 - rw [if_neg, rotateL_node, if_pos]; · rfl + rw [ite_eq_right, rotateL_node, ite_eq_left]; · rfl all_goals (try dsimp only [size]); decide · have : size rll = 0 ∧ size rlr = 0 := by have := balancedSz_zero.1 hr.1 @@ -577,9 +577,9 @@ theorem balance_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Si cases sr.2.1.2.1.size_eq_zero.1 this.1 cases sr.2.1.2.2.size_eq_zero.1 this.2 obtain rfl : rls = 1 := sr.2.1.1 - rw [if_neg, rotateL_node, if_neg]; · rfl + rw [ite_eq_right, rotateL_node, ite_eq_right]; · rfl all_goals (try dsimp only [size]); decide - · symm; rw [zero_add, if_neg, rotateL] + · symm; rw [zero_add, ite_eq_right, rotateL] · dsimp only [size_node]; split_ifs · simp [node3L, node']; abel · simp [node4L, node', sr.2.1.1]; abel @@ -595,7 +595,7 @@ theorem balance_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Si cases sl.2.2.2.1.size_eq_zero.1 this.1 cases sl.2.2.2.2.size_eq_zero.1 this.2 obtain rfl : lrs = 1 := sl.2.2.1 - rw [if_neg, rotateR_node, if_neg]; · rfl + rw [ite_eq_right, rotateR_node, ite_eq_right]; · rfl all_goals (try dsimp only [size]); decide · have : size lll = 0 ∧ size llr = 0 := by have := balancedSz_zero.1 hl.1 @@ -603,15 +603,15 @@ theorem balance_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Si cases sl.2.1.2.1.size_eq_zero.1 this.1 cases sl.2.1.2.2.size_eq_zero.1 this.2 obtain rfl : lls = 1 := sl.2.1.1 - rw [if_neg, rotateR_node, if_pos]; · rfl + rw [ite_eq_right, rotateR_node, ite_eq_left]; · rfl all_goals (try dsimp only [size]); decide - · symm; rw [if_neg, rotateR] + · symm; rw [ite_eq_right, rotateR] · dsimp only [size_node]; split_ifs · simp [node3R, node']; abel · simp [node4R, node', sl.2.2.1]; abel · exact not_le_of_gt (Nat.succ_lt_succ (add_pos sl.2.1.pos sl.2.2.pos)) · simp only [balance, id_eq, balance', size_node, gt_iff_lt] - symm; rw [if_neg] + symm; rw [ite_eq_right] · split_ifs with h h_1 · have rd : delta ≤ size rl + size rr := by have := lt_of_le_of_lt (Nat.mul_le_mul_left _ sl.pos) h diff --git a/Mathlib/Data/PEquiv.lean b/Mathlib/Data/PEquiv.lean index e8f11e00649fe6..e6b05fd3ef2f50 100644 --- a/Mathlib/Data/PEquiv.lean +++ b/Mathlib/Data/PEquiv.lean @@ -306,7 +306,7 @@ def single (a : α) (b : β) : · simp theorem mem_single (a : α) (b : β) : b ∈ single a b a := - if_pos rfl + ite_eq_left rfl theorem mem_single_iff (a₁ a₂ : α) (b₁ b₂ : β) : b₁ ∈ single a₂ b₂ a₁ ↔ a₁ = a₂ ∧ b₁ = b₂ := by dsimp [single]; split_ifs <;> simp [*, eq_comm] @@ -317,10 +317,10 @@ theorem symm_single (a : α) (b : β) : (single a b).symm = single b a := @[simp] theorem single_apply (a : α) (b : β) : single a b a = some b := - if_pos rfl + ite_eq_left rfl theorem single_apply_of_ne {a₁ a₂ : α} (h : a₁ ≠ a₂) (b : β) : single a₁ b a₂ = none := - if_neg h.symm + ite_eq_right h.symm theorem single_trans_of_mem (a : α) {b : β} {c : γ} {f : β ≃. γ} (h : c ∈ f b) : (single a b).trans f = single a c := by @@ -341,7 +341,7 @@ theorem single_trans_single (a : α) (b : β) (c : γ) : theorem single_subsingleton_eq_refl [Subsingleton α] (a b : α) : single a b = PEquiv.refl α := by ext i j dsimp [single] - rw [if_pos (Subsingleton.elim i a), Subsingleton.elim i j, Subsingleton.elim b j] + rw [ite_eq_left (Subsingleton.elim i a), Subsingleton.elim i j, Subsingleton.elim b j] theorem trans_single_of_eq_none {b : β} (c : γ) {f : δ ≃. β} (h : f.symm b = none) : f.trans (single b c) = ⊥ := by @@ -399,7 +399,7 @@ instance [DecidableEq α] [DecidableEq β] : SemilatticeInf (α ≃. β) := have hf := fg a b H have hg := gh a b H simp only [Option.mem_def, PEquiv.coe_mk_apply] at * - rw [hf, hg, if_pos rfl] } + rw [hf, hg, ite_eq_left rfl] } end Order diff --git a/Mathlib/Data/PFunctor/Univariate/Basic.lean b/Mathlib/Data/PFunctor/Univariate/Basic.lean index 4bb1cd66674ebf..49ff69976cc078 100644 --- a/Mathlib/Data/PFunctor/Univariate/Basic.lean +++ b/Mathlib/Data/PFunctor/Univariate/Basic.lean @@ -135,7 +135,7 @@ theorem fst_map (x : P α) (f : α → β) : (P.map f x).1 = x.1 := by cases x; @[simp] theorem iget_map [DecidableEq P.A] [Inhabited α] [Inhabited β] (x : P α) (f : α → β) (i : P.Idx) (h : i.1 = x.1) : (P.map f x).iget i = f (x.iget i) := by - simp only [Obj.iget, fst_map, *, dif_pos] + simp only [Obj.iget, fst_map, *, dite_eq_left] cases x rfl diff --git a/Mathlib/Data/PFunctor/Univariate/M.lean b/Mathlib/Data/PFunctor/Univariate/M.lean index f87649e15fbf1d..8b561a6ff6cefc 100644 --- a/Mathlib/Data/PFunctor/Univariate/M.lean +++ b/Mathlib/Data/PFunctor/Univariate/M.lean @@ -398,7 +398,7 @@ theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x simp only [iselect, isubtree] at ps_ih ⊢ by_cases h'' : a = x_a · subst x_a - simp only [dif_pos, casesOn_mk'] + simp only [dite_eq_left, casesOn_mk'] rw [ps_ih] intro h' apply h @@ -426,7 +426,7 @@ theorem ichildren_mk [DecidableEq F.A] [Inhabited (M F)] (x : F (M F)) (i : F.Id @[simp] theorem isubtree_cons [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) {a} (f : F.B a → M F) {i : F.B a} : isubtree (⟨_, i⟩ :: ps) (M.mk ⟨a, f⟩) = isubtree ps (f i) := by - simp only [isubtree, dif_pos, isubtree, M.casesOn_mk']; rfl + simp only [isubtree, dite_eq_left, isubtree, M.casesOn_mk']; rfl @[simp] theorem iselect_nil [DecidableEq F.A] [Inhabited (M F)] {a} (f : F.B a → M F) : diff --git a/Mathlib/Data/PNat/Basic.lean b/Mathlib/Data/PNat/Basic.lean index f8e2eee751627e..1e58070cd94fa3 100644 --- a/Mathlib/Data/PNat/Basic.lean +++ b/Mathlib/Data/PNat/Basic.lean @@ -256,7 +256,7 @@ theorem le_sub_one_of_lt {a b : ℕ+} (hab : a < b) : a ≤ b - (1 : ℕ+) := by theorem add_sub_of_lt {a b : ℕ+} : a < b → a + (b - a) = b := fun h => PNat.eq <| by - rw [add_coe, sub_coe, if_pos h] + rw [add_coe, sub_coe, ite_eq_left h] exact add_tsub_cancel_of_le h.le theorem sub_add_of_lt {a b : ℕ+} (h : b < a) : a - b + b = a := by @@ -328,12 +328,12 @@ theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by rw [Nat.dvd_iff_mod_eq_zero]; constructor · intro h apply PNat.eq - rw [mod_coe, if_pos h] + rw [mod_coe, ite_eq_left h] · intro h by_cases h' : (m : ℕ) % (k : ℕ) = 0 · exact h' · replace h : (mod m k : ℕ) = (k : ℕ) := congr_arg _ h - rw [mod_coe, if_neg h'] at h + rw [mod_coe, ite_eq_right h'] at h exact ((Nat.mod_lt (m : ℕ) k.pos).ne h).elim theorem le_of_dvd {m n : ℕ+} : m ∣ n → m ≤ n := by diff --git a/Mathlib/Data/PNat/Defs.lean b/Mathlib/Data/PNat/Defs.lean index 356d1193020665..f7ac725a6e5a63 100644 --- a/Mathlib/Data/PNat/Defs.lean +++ b/Mathlib/Data/PNat/Defs.lean @@ -81,7 +81,7 @@ theorem toPNat'_zero : Nat.toPNat' 0 = 1 := rfl theorem toPNat'_coe : ∀ n : ℕ, (toPNat' n : ℕ) = ite (0 < n) n 1 | 0 => rfl | m + 1 => by - rw [if_pos (succ_pos m)] + rw [ite_eq_left (succ_pos m)] rfl end Nat @@ -203,10 +203,10 @@ theorem mod_coe (m k : ℕ+) : dsimp [mod, modDiv] cases (m : ℕ) % (k : ℕ) with | zero => - rw [if_pos rfl] + rw [ite_eq_left rfl] rfl | succ n => - rw [if_neg n.succ_ne_zero] + rw [ite_eq_right n.succ_ne_zero] rfl theorem div_coe (m k : ℕ+) : @@ -214,10 +214,10 @@ theorem div_coe (m k : ℕ+) : dsimp [div, modDiv] cases (m : ℕ) % (k : ℕ) with | zero => - rw [if_pos rfl] + rw [ite_eq_left rfl] rfl | succ n => - rw [if_neg n.succ_ne_zero] + rw [ite_eq_right n.succ_ne_zero] rfl /-- If `h : k | m`, then `k * (div_exact m k) = m`. Note that this is not equal to `m / k`. -/ @@ -234,7 +234,7 @@ instance Nat.canLiftPNat : CanLift ℕ ℕ+ (↑) (fun n => 0 < n) := instance Int.canLiftPNat : CanLift ℤ ℕ+ (↑) ((0 < ·)) := ⟨fun n hn => ⟨Nat.toPNat' (Int.natAbs n), by - rw [Nat.toPNat'_coe, if_pos (Int.natAbs_pos.2 hn.ne'), + rw [Nat.toPNat'_coe, ite_eq_left (Int.natAbs_pos.2 hn.ne'), Int.natAbs_of_nonneg hn.le]⟩⟩ end CanLift diff --git a/Mathlib/Data/PNat/Xgcd.lean b/Mathlib/Data/PNat/Xgcd.lean index 2ed35dc2c80789..b4bc0a3550c39c 100644 --- a/Mathlib/Data/PNat/Xgcd.lean +++ b/Mathlib/Data/PNat/Xgcd.lean @@ -309,11 +309,11 @@ decreasing_by apply u.step_wf _h theorem reduce_a {u : XgcdType} (h : u.r = 0) : u.reduce = u.finish := by rw [reduce] - exact if_pos h + exact ite_eq_left h theorem reduce_b {u : XgcdType} (h : u.r ≠ 0) : u.reduce = u.step.reduce.flip := by rw [reduce] - exact if_neg h + exact ite_eq_right h theorem reduce_isReduced : ∀ u : XgcdType, u.reduce.IsReduced | u => diff --git a/Mathlib/Data/Part.lean b/Mathlib/Data/Part.lean index ef947f903066ed..34fd3ff0902520 100644 --- a/Mathlib/Data/Part.lean +++ b/Mathlib/Data/Part.lean @@ -229,11 +229,11 @@ theorem eq_of_mem {a b : Part α} (ha : a.Dom) (hb : a.get ha ∈ b) : a = b := @[simp] theorem none_toOption [Decidable (@none α).Dom] : (none : Part α).toOption = Option.none := - dif_neg id + dite_eq_right id @[simp] theorem some_toOption (a : α) [Decidable (some a).Dom] : (some a).toOption = Option.some a := - dif_pos trivial + dite_eq_left trivial instance noneDecidable : Decidable (@none α).Dom := instDecidableFalse @@ -248,11 +248,11 @@ def getOrElse (a : Part α) [Decidable a.Dom] (d : α) := theorem getOrElse_of_dom (a : Part α) (h : a.Dom) [Decidable a.Dom] (d : α) : getOrElse a d = a.get h := - dif_pos h + dite_eq_left h theorem getOrElse_of_not_dom (a : Part α) (h : ¬a.Dom) [Decidable a.Dom] (d : α) : getOrElse a d = d := - dif_neg h + dite_eq_right h @[simp] theorem getOrElse_none (d : α) [Decidable (none : Part α).Dom] : getOrElse none d = d := @@ -276,7 +276,7 @@ theorem toOption_eq_some_iff {o : Part α} [Decidable o.Dom] {a : α} : rw [← Option.mem_def, mem_toOption] protected theorem Dom.toOption {o : Part α} [Decidable o.Dom] (h : o.Dom) : o.toOption = o.get h := - dif_pos h + dite_eq_left h theorem toOption_eq_none_iff {a : Part α} [Decidable a.Dom] : a.toOption = Option.none ↔ ¬a.Dom := Ne.dite_eq_right_iff fun _ => Option.some_ne_none _ diff --git a/Mathlib/Data/Rat/Cast/Lemmas.lean b/Mathlib/Data/Rat/Cast/Lemmas.lean index 377b561a9cdc4b..c0f428f81b8b77 100644 --- a/Mathlib/Data/Rat/Cast/Lemmas.lean +++ b/Mathlib/Data/Rat/Cast/Lemmas.lean @@ -35,7 +35,7 @@ lemma cast_pow (p : ℚ) (n : ℕ) : ↑(p ^ n) = (p ^ n : α) := by theorem cast_inv_nat (n : ℕ) : ((n⁻¹ : ℚ) : α) = (n : α)⁻¹ := by rcases n with - | n · simp - rw [cast_def, inv_natCast_num, inv_natCast_den, if_neg n.succ_ne_zero, + rw [cast_def, inv_natCast_num, inv_natCast_den, ite_eq_right n.succ_ne_zero, Int.sign_eq_one_of_pos (Int.ofNat_succ_pos n), Int.cast_one, one_div] @[simp] diff --git a/Mathlib/Data/Real/Sign.lean b/Mathlib/Data/Real/Sign.lean index 6dda69b6a8fb9c..71adf14d48cd93 100644 --- a/Mathlib/Data/Real/Sign.lean +++ b/Mathlib/Data/Real/Sign.lean @@ -34,12 +34,14 @@ otherwise. -/ noncomputable def sign (r : ℝ) : ℝ := if r < 0 then -1 else if 0 < r then 1 else 0 -theorem sign_of_neg {r : ℝ} (hr : r < 0) : sign r = -1 := by rw [sign, if_pos hr] +theorem sign_of_neg {r : ℝ} (hr : r < 0) : sign r = -1 := by rw [sign, ite_eq_left hr] -theorem sign_of_pos {r : ℝ} (hr : 0 < r) : sign r = 1 := by rw [sign, if_pos hr, if_neg hr.not_gt] +theorem sign_of_pos {r : ℝ} (hr : 0 < r) : sign r = 1 := by + rw [sign, ite_eq_left hr, ite_eq_right hr.not_gt] @[simp] -theorem sign_zero : sign 0 = 0 := by rw [sign, if_neg (lt_irrefl _), if_neg (lt_irrefl _)] +theorem sign_zero : sign 0 = 0 := by + rw [sign, ite_eq_right (lt_irrefl _), ite_eq_right (lt_irrefl _)] @[simp] theorem sign_one : sign 1 = 1 := diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index 52b8f13cd2f277..cab6e20f4d6275 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -733,8 +733,8 @@ theorem one_le_ncard_insert (a : α) (s : Set α) (hs : s.Finite := by toFinite_ theorem ncard_insert_eq_ite {a : α} [Decidable (a ∈ s)] (hs : s.Finite := by toFinite_tac) : ncard (insert a s) = if a ∈ s then s.ncard else s.ncard + 1 := by by_cases h : a ∈ s - · rw [ncard_insert_of_mem h, if_pos h] - · rw [ncard_insert_of_notMem h hs, if_neg h] + · rw [ncard_insert_of_mem h, ite_eq_left h] + · rw [ncard_insert_of_notMem h hs, ite_eq_right h] theorem ncard_le_ncard_insert (a : α) (s : Set α) : s.ncard ≤ (insert a s).ncard := by classical diff --git a/Mathlib/Data/Set/Function.lean b/Mathlib/Data/Set/Function.lean index e7386cd4f81f6a..d28ffd7bdbb25b 100644 --- a/Mathlib/Data/Set/Function.lean +++ b/Mathlib/Data/Set/Function.lean @@ -957,7 +957,7 @@ noncomputable def invFunOn [Nonempty α] (f : α → β) (s : Set α) (b : β) : variable [Nonempty α] theorem invFunOn_pos (h : ∃ a ∈ s, f a = b) : invFunOn f s b ∈ s ∧ f (invFunOn f s b) = b := by - rw [invFunOn, dif_pos h] + rw [invFunOn, dite_eq_left h] exact Classical.choose_spec h theorem invFunOn_mem (h : ∃ a ∈ s, f a = b) : invFunOn f s b ∈ s := @@ -967,7 +967,7 @@ theorem invFunOn_eq (h : ∃ a ∈ s, f a = b) : f (invFunOn f s b) = b := (invFunOn_pos h).right theorem invFunOn_neg (h : ¬∃ a ∈ s, f a = b) : invFunOn f s b = Classical.choice ‹Nonempty α› := by - rw [invFunOn, dif_neg h] + rw [invFunOn, dite_eq_right h] @[simp] theorem invFunOn_apply_mem (h : a ∈ s) : invFunOn f s (f a) ∈ s := diff --git a/Mathlib/Data/Set/Piecewise.lean b/Mathlib/Data/Set/Piecewise.lean index 3b8f01b777e09a..81ee43d31248a6 100644 --- a/Mathlib/Data/Set/Piecewise.lean +++ b/Mathlib/Data/Set/Piecewise.lean @@ -50,11 +50,11 @@ theorem piecewise_insert [DecidableEq α] (j : α) [∀ i, Decidable (i ∈ inse @[simp] theorem piecewise_eq_of_mem {i : α} (hi : i ∈ s) : s.piecewise f g i = f i := - if_pos hi + ite_eq_left hi @[simp] theorem piecewise_eq_of_notMem {i : α} (hi : i ∉ s) : s.piecewise f g i = g i := - if_neg hi + ite_eq_right hi theorem piecewise_singleton (x : α) [∀ y, Decidable (y ∈ ({x} : Set α))] [DecidableEq α] (f g : α → β) : piecewise {x} f g = Function.update g x (f x) := by diff --git a/Mathlib/Data/Set/Restrict.lean b/Mathlib/Data/Set/Restrict.lean index efa8e9ee08c862..4fe388fdf5e688 100644 --- a/Mathlib/Data/Set/Restrict.lean +++ b/Mathlib/Data/Set/Restrict.lean @@ -62,14 +62,14 @@ theorem image_domRestrict (f : α → β) (s t : Set α) : theorem domRestrict_dite {s : Set α} [∀ x, Decidable (x ∈ s)] (f : ∀ a ∈ s, β) (g : ∀ a ∉ s, β) : (s.domRestrict fun a => if h : a ∈ s then f a h else g a h) = (fun a : s => f a a.2) := - funext fun a => dif_pos a.2 + funext fun a => dite_eq_left a.2 @[simp] theorem domRestrict_dite_compl {s : Set α} [∀ x, Decidable (x ∈ s)] (f : ∀ a ∈ s, β) (g : ∀ a ∉ s, β) : (sᶜ.domRestrict fun a => if h : a ∈ s then f a h else g a h) = (fun a : (sᶜ : Set α) => g a a.2) := - funext fun a => dif_neg a.2 + funext fun a => dite_eq_right a.2 @[simp] theorem domRestrict_ite (f g : α → β) (s : Set α) [∀ x, Decidable (x ∈ s)] : diff --git a/Mathlib/Data/Setoid/Partition/Card.lean b/Mathlib/Data/Setoid/Partition/Card.lean index ed5735b53930c1..4937dc6d4c6a5f 100644 --- a/Mathlib/Data/Setoid/Partition/Card.lean +++ b/Mathlib/Data/Setoid/Partition/Card.lean @@ -30,7 +30,7 @@ theorem Setoid.IsPartition.ncard_eq_finsum {α : Type*} {P : Set (Set α)} have hst' (t : Set α) : Nat.card ↑(s ∩ t) = (hst t).toFinset.card := Nat.card_eq_card_finite_toFinset (hst t) suffices hs' : _ by - rw [finsum_def, dif_pos hs'] + rw [finsum_def, dite_eq_left hs'] simp only [← Nat.card_coe_set_eq, Nat.card_eq_card_finite_toFinset hs] rw [Finset.sum_congr rfl (fun t ht ↦ by exact hst' ↑t)] rw [← Finset.card_sigma, eq_comm] diff --git a/Mathlib/Data/Sigma/Interval.lean b/Mathlib/Data/Sigma/Interval.lean index b9647ef1ba5803..65aab88bc027f2 100644 --- a/Mathlib/Data/Sigma/Interval.lean +++ b/Mathlib/Data/Sigma/Interval.lean @@ -78,19 +78,19 @@ variable (i : ι) (a b : α i) @[simp] theorem Icc_mk_mk : Icc (⟨i, a⟩ : Sigma α) ⟨i, b⟩ = (Icc a b).map (Embedding.sigmaMk i) := - dif_pos rfl + dite_eq_left rfl @[simp] theorem Ico_mk_mk : Ico (⟨i, a⟩ : Sigma α) ⟨i, b⟩ = (Ico a b).map (Embedding.sigmaMk i) := - dif_pos rfl + dite_eq_left rfl @[simp] theorem Ioc_mk_mk : Ioc (⟨i, a⟩ : Sigma α) ⟨i, b⟩ = (Ioc a b).map (Embedding.sigmaMk i) := - dif_pos rfl + dite_eq_left rfl @[simp] theorem Ioo_mk_mk : Ioo (⟨i, a⟩ : Sigma α) ⟨i, b⟩ = (Ioo a b).map (Embedding.sigmaMk i) := - dif_pos rfl + dite_eq_left rfl end LocallyFiniteOrder diff --git a/Mathlib/Data/Sign/Defs.lean b/Mathlib/Data/Sign/Defs.lean index 71820f8607b848..da71961afaf541 100644 --- a/Mathlib/Data/Sign/Defs.lean +++ b/Mathlib/Data/Sign/Defs.lean @@ -278,15 +278,16 @@ theorem sign_apply : sign a = ite (0 < a) 1 (ite (a < 0) (-1) 0) := theorem sign_zero : sign (0 : α) = 0 := by simp [sign_apply] @[simp] -theorem sign_pos (ha : 0 < a) : sign a = 1 := by rwa [sign_apply, if_pos] +theorem sign_pos (ha : 0 < a) : sign a = 1 := by rwa [sign_apply, ite_eq_left] @[simp] -theorem sign_neg (ha : a < 0) : sign a = -1 := by rwa [sign_apply, if_neg <| asymm ha, if_pos] +theorem sign_neg (ha : a < 0) : sign a = -1 := by + rwa [sign_apply, ite_eq_right <| asymm ha, ite_eq_left] theorem sign_eq_one_iff : sign a = 1 ↔ 0 < a := by refine ⟨fun h => ?_, fun h => sign_pos h⟩ by_contra hn - rw [sign_apply, if_neg hn] at h + rw [sign_apply, ite_eq_right hn] at h split_ifs at h theorem sign_eq_neg_one_iff : sign a = -1 ↔ a < 0 := by diff --git a/Mathlib/Data/String/Basic.lean b/Mathlib/Data/String/Basic.lean index 4f88876690e5c9..8bbde03eca345b 100644 --- a/Mathlib/Data/String/Basic.lean +++ b/Mathlib/Data/String/Basic.lean @@ -60,20 +60,20 @@ theorem ltb_cons_addChar' (c : Char) (s₁ s₂ : Legacy.Iterator) : fun_induction ltb s₁ s₂ with | case1 s₁ s₂ h₁ h₂ h ih => rw [ltb, Legacy.Iterator.hasNext_cons_addChar, Legacy.Iterator.hasNext_cons_addChar, - if_pos (by simpa using h₁), if_pos (by simpa using h₂), if_pos, ← ih] + ite_eq_left (by simpa using h₁), ite_eq_left (by simpa using h₂), ite_eq_left, ← ih] · simp only [Legacy.Iterator.next, Pos.Raw.next, get_cons_addChar, ofList_toList] congr 2 <;> apply Pos.Raw.add_char_right_comm · simpa only [Legacy.Iterator.curr, get_cons_addChar, ofList_toList] using h | case2 s₁ s₂ h₁ h₂ h => rw [ltb, Legacy.Iterator.hasNext_cons_addChar, Legacy.Iterator.hasNext_cons_addChar, - if_pos (by simpa using h₁), if_pos (by simpa using h₂), if_neg] + ite_eq_left (by simpa using h₁), ite_eq_left (by simpa using h₂), ite_eq_right] · simp only [Legacy.Iterator.curr, get_cons_addChar, ofList_toList] · simpa only [Legacy.Iterator.curr, get_cons_addChar, ofList_toList] using h | case3 s₁ s₂ h₁ h₂ => rw [ltb, Legacy.Iterator.hasNext_cons_addChar, Legacy.Iterator.hasNext_cons_addChar, - if_pos (by simpa using h₁), if_neg (by simpa using h₂)] + ite_eq_left (by simpa using h₁), ite_eq_right (by simpa using h₂)] | case4 s₁ s₂ h₁ => - rw [ltb, Legacy.Iterator.hasNext_cons_addChar, if_neg (by simpa using h₁)] + rw [ltb, Legacy.Iterator.hasNext_cons_addChar, ite_eq_right (by simpa using h₁)] theorem ltb_cons_addChar (c : Char) (cs₁ cs₂ : List Char) (i₁ i₂ : Pos.Raw) : ltb ⟨ofList (c :: cs₁), i₁ + c⟩ ⟨ofList (c :: cs₂), i₂ + c⟩ = diff --git a/Mathlib/Data/SubtypeNeLift.lean b/Mathlib/Data/SubtypeNeLift.lean index 681cef12384c1b..389cf14e61c66c 100644 --- a/Mathlib/Data/SubtypeNeLift.lean +++ b/Mathlib/Data/SubtypeNeLift.lean @@ -28,10 +28,10 @@ def subtypeNeLift (i : ι) : M i := if h : i = i₀ then by rw [h]; exact x else f ⟨i, h⟩ @[simp] -lemma subtypeNeLift_self : subtypeNeLift i₀ f x i₀ = x := dif_pos rfl +lemma subtypeNeLift_self : subtypeNeLift i₀ f x i₀ = x := dite_eq_left rfl lemma subtypeNeLift_of_neq (i : ι) (h : i ≠ i₀) : - subtypeNeLift i₀ f x i = f ⟨i, h⟩ := dif_neg h + subtypeNeLift i₀ f x i = f ⟨i, h⟩ := dite_eq_right h @[simp] lemma subtypeNeLift_restriction (φ : ∀ i, M i) (i₀ : ι) : diff --git a/Mathlib/Data/Sym/Basic.lean b/Mathlib/Data/Sym/Basic.lean index bd3c5d8e2f6dd2..ddd435c1736746 100644 --- a/Mathlib/Data/Sym/Basic.lean +++ b/Mathlib/Data/Sym/Basic.lean @@ -533,8 +533,8 @@ theorem fill_filterNe [DecidableEq α] (a : α) (m : Sym α n) : ext b; dsimp rw [count_add, count_filter, Sym.coe_replicate, count_replicate] obtain rfl | h := eq_or_ne a b - · rw [if_pos rfl, if_neg (not_not.2 rfl), zero_add] - · rw [if_pos h, if_neg h, add_zero]) + · rw [ite_eq_left rfl, ite_eq_right (not_not.2 rfl), zero_add] + · rw [ite_eq_left h, ite_eq_right h, add_zero]) theorem filter_ne_fill [DecidableEq α] (a : α) (m : Σ i : Fin (n + 1), Sym α (n - i)) (h : a ∉ m.2) : @@ -584,7 +584,7 @@ def encode [DecidableEq α] (s : Sym (Option α) n.succ) : Sym (Option α) n ⊕ @[simp] theorem encode_of_none_mem [DecidableEq α] (s : Sym (Option α) n.succ) (h : none ∈ s) : encode s = Sum.inl (s.erase none h) := - dif_pos h + dite_eq_left h @[simp] theorem encode_of_none_notMem [DecidableEq α] (s : Sym (Option α) n.succ) (h : none ∉ s) : @@ -592,7 +592,7 @@ theorem encode_of_none_notMem [DecidableEq α] (s : Sym (Option α) n.succ) (h : Sum.inr (s.attach.map fun o => o.1.get <| Option.ne_none_iff_isSome.1 <| ne_of_mem_of_not_mem o.2 h) := - dif_neg h + dite_eq_right h /-- Inverse of `Sym_option_succ_equiv.decode`. -/ def decode : Sym (Option α) n ⊕ Sym α n.succ → Sym (Option α) n.succ diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index 9049c491aa452a..da92e5cc63c1eb 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -562,7 +562,7 @@ theorem cast_sub_one {R : Type*} [Ring R] {n : ℕ} (k : ZMod n) : · dsimp [ZMod, ZMod.cast] rw [Int.cast_sub, Int.cast_one] · dsimp [ZMod, ZMod.cast, ZMod.val] - rw [Fin.coe_sub_one, if_neg] + rw [Fin.coe_sub_one, ite_eq_right] · rw [Nat.cast_sub, Nat.cast_one] rwa [Fin.ext_iff, Fin.val_zero, ← Ne, ← Nat.one_le_iff_ne_zero] at hk · exact hk @@ -910,7 +910,7 @@ def chineseRemainder {m n : ℕ} (h : m.Coprime n) : ZMod (m * n) ≃+* ZMod m intro x dsimp only [to_fun, inv_fun, ZMod.castHom_apply] conv_rhs => rw [← ZMod.natCast_zmod_val x] - rw [if_neg hmn0, ZMod.natCast_eq_natCast_iff, ← Nat.modEq_and_modEq_iff_modEq_mul h, + rw [ite_eq_right hmn0, ZMod.natCast_eq_natCast_iff, ← Nat.modEq_and_modEq_iff_modEq_mul h, Prod.fst_zmod_cast, Prod.snd_zmod_cast] refine ⟨(Nat.chineseRemainder h (cast x : ZMod m).val (cast x : ZMod n).val).2.left.trans ?_, @@ -1026,8 +1026,8 @@ theorem neg_val' {n : ℕ} [NeZero n] (a : ZMod n) : (-a).val = (n - a.val) % n theorem neg_val {n : ℕ} [NeZero n] (a : ZMod n) : (-a).val = if a = 0 then 0 else n - a.val := by rw [neg_val'] - by_cases h : a = 0; · rw [if_pos h, h, val_zero, tsub_zero, Nat.mod_self] - rw [if_neg h] + by_cases h : a = 0; · rw [ite_eq_left h, h, val_zero, tsub_zero, Nat.mod_self] + rw [ite_eq_right h] apply Nat.mod_eq_of_lt exact Nat.sub_lt (NeZero.pos n) (val_pos.mpr h) diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index 00e5d929d5bce7..059c7d519ece43 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -60,7 +60,7 @@ open scoped Fin.IntCast Fin.NatCast · rw [← Int.natCast_dvd] at h rw [Int.emod_eq_zero_of_dvd h, Int.toNat_zero] · rw [Int.emod_natAbs_of_neg (by lia) (NeZero.ne n), - if_neg (by rwa [← Int.natCast_dvd] at h)] + ite_eq_right (by rwa [← Int.natCast_dvd] at h)] have : x % n < n := Int.emod_lt_of_pos x (by have := NeZero.ne n; lia) lia diff --git a/Mathlib/Data/ZMod/ValMinAbs.lean b/Mathlib/Data/ZMod/ValMinAbs.lean index ef4a092798dcf8..75220e77266396 100644 --- a/Mathlib/Data/ZMod/ValMinAbs.lean +++ b/Mathlib/Data/ZMod/ValMinAbs.lean @@ -59,7 +59,7 @@ lemma valMinAbs_mul_two_eq_iff (a : ZMod n) : a.valMinAbs * 2 = n ↔ 2 * a.val · simp by_cases h : a.val ≤ n.succ / 2 · dsimp [valMinAbs] - rw [if_pos h, ← Int.natCast_inj, Nat.cast_mul, Nat.cast_two, mul_comm, Int.natCast_add, + rw [ite_eq_left h, ← Int.natCast_inj, Nat.cast_mul, Nat.cast_two, mul_comm, Int.natCast_add, Nat.cast_one] apply iff_of_false _ (mt _ h) · intro he @@ -103,7 +103,7 @@ set_option backward.isDefEq.respectTransparency false in @[simp] lemma valMinAbs_zero : ∀ n, (0 : ZMod n).valMinAbs = 0 | 0 => by simp only [valMinAbs_def_zero] - | n + 1 => by simp only [valMinAbs_def_pos, if_true, Int.ofNat_zero, zero_le, val_zero] + | n + 1 => by simp only [valMinAbs_def_pos, ite_true, Int.ofNat_zero, zero_le, val_zero] @[simp] lemma valMinAbs_eq_zero (x : ZMod n) : x.valMinAbs = 0 ↔ x = 0 := diff --git a/Mathlib/Dynamics/PeriodicPts/Defs.lean b/Mathlib/Dynamics/PeriodicPts/Defs.lean index 6d9415caebbd5b..859d79a73510ab 100644 --- a/Mathlib/Dynamics/PeriodicPts/Defs.lean +++ b/Mathlib/Dynamics/PeriodicPts/Defs.lean @@ -268,17 +268,17 @@ theorem iterate_mod_minimalPeriod_eq : f^[n % minimalPeriod f x] x = f^[n] x := theorem minimalPeriod_pos_of_mem_periodicPts (hx : x ∈ periodicPts f) : 0 < minimalPeriod f x := by classical - simp only [minimalPeriod, dif_pos hx, (Nat.find_spec hx).1.lt] + simp only [minimalPeriod, dite_eq_left hx, (Nat.find_spec hx).1.lt] theorem minimalPeriod_eq_zero_of_notMem_periodicPts (hx : x ∉ periodicPts f) : - minimalPeriod f x = 0 := by simp only [minimalPeriod, dif_neg hx] + minimalPeriod f x = 0 := by simp only [minimalPeriod, dite_eq_right hx] theorem IsPeriodicPt.minimalPeriod_pos (hn : 0 < n) (hx : IsPeriodicPt f n x) : 0 < minimalPeriod f x := minimalPeriod_pos_of_mem_periodicPts <| mk_mem_periodicPts hn hx theorem minimalPeriod_pos_iff_mem_periodicPts : 0 < minimalPeriod f x ↔ x ∈ periodicPts f := - ⟨not_imp_not.1 fun h => by simp only [minimalPeriod, dif_neg h, lt_irrefl 0, not_false_iff], + ⟨not_imp_not.1 fun h => by simp only [minimalPeriod, dite_eq_right h, lt_irrefl 0, not_false_iff], minimalPeriod_pos_of_mem_periodicPts⟩ theorem minimalPeriod_eq_zero_iff_notMem_periodicPts : @@ -288,7 +288,7 @@ theorem minimalPeriod_eq_zero_iff_notMem_periodicPts : theorem IsPeriodicPt.minimalPeriod_le (hn : 0 < n) (hx : IsPeriodicPt f n x) : minimalPeriod f x ≤ n := by classical - rw [minimalPeriod, dif_pos (mk_mem_periodicPts hn hx)] + rw [minimalPeriod, dite_eq_left (mk_mem_periodicPts hn hx)] exact Nat.find_min' (mk_mem_periodicPts hn hx) ⟨hn, hx⟩ theorem minimalPeriod_apply_iterate (hx : x ∈ periodicPts f) (n : ℕ) : diff --git a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean index be64434cf5e88c..cd2f0dccad212b 100644 --- a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean +++ b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean @@ -394,7 +394,7 @@ noncomputable def fromConfig (x : G → A) (U : Finset G) : Pattern A G := by classical exact { config := fun g => if g ∈ U then x g else default, support := U, - condition := fun g hg => if_neg hg } + condition := fun g hg => ite_eq_right hg } /-- On the translated support, `p.mulShift v` agrees with `p.config` at the preimage. diff --git a/Mathlib/FieldTheory/CardinalEmb.lean b/Mathlib/FieldTheory/CardinalEmb.lean index 6156a70cec549e..2aefc0405f6dd9 100644 --- a/Mathlib/FieldTheory/CardinalEmb.lean +++ b/Mathlib/FieldTheory/CardinalEmb.lean @@ -291,7 +291,7 @@ def equivLim : (E⟮.prod_eq_multiset_prod, ← Function.comp_def (X - C ·) Prod.fst, ← Multiset.map_map, diff --git a/Mathlib/FieldTheory/IsPerfectClosure.lean b/Mathlib/FieldTheory/IsPerfectClosure.lean index 2038d7e583b0e3..cf8aa7732eb5da 100644 --- a/Mathlib/FieldTheory/IsPerfectClosure.lean +++ b/Mathlib/FieldTheory/IsPerfectClosure.lean @@ -77,14 +77,14 @@ def pNilradical (R : Type*) [CommSemiring R] (p : ℕ) : Ideal R := if 1 < p the theorem pNilradical_le_nilradical {R : Type*} [CommSemiring R] {p : ℕ} : pNilradical R p ≤ nilradical R := by by_cases hp : 1 < p - · rw [pNilradical, if_pos hp] - simp_rw [pNilradical, if_neg hp, bot_le] + · rw [pNilradical, ite_eq_left hp] + simp_rw [pNilradical, ite_eq_right hp, bot_le] theorem pNilradical_eq_nilradical {R : Type*} [CommSemiring R] {p : ℕ} (hp : 1 < p) : - pNilradical R p = nilradical R := by rw [pNilradical, if_pos hp] + pNilradical R p = nilradical R := by rw [pNilradical, ite_eq_left hp] theorem pNilradical_eq_bot {R : Type*} [CommSemiring R] {p : ℕ} (hp : ¬ 1 < p) : - pNilradical R p = ⊥ := by rw [pNilradical, if_neg hp] + pNilradical R p = ⊥ := by rw [pNilradical, ite_eq_right hp] theorem pNilradical_eq_bot' {R : Type*} [CommSemiring R] {p : ℕ} (hp : p ≤ 1) : pNilradical R p = ⊥ := pNilradical_eq_bot (not_lt.2 hp) diff --git a/Mathlib/FieldTheory/KummerExtension.lean b/Mathlib/FieldTheory/KummerExtension.lean index 7ca6f1cd94d505..d4dad3dc7b8190 100644 --- a/Mathlib/FieldTheory/KummerExtension.lean +++ b/Mathlib/FieldTheory/KummerExtension.lean @@ -71,7 +71,8 @@ theorem X_pow_sub_C_splits_of_isPrimitiveRoot | inl hn => simp only [hn, pow_zero, ← C.map_one, ← map_sub, Splits.C] | inr hn => - rw [splits_iff_card_roots, ← nthRoots, hζ.card_nthRoots, natDegree_X_pow_sub_C, if_pos ⟨α, e⟩] + rw [splits_iff_card_roots, ← nthRoots, hζ.card_nthRoots, natDegree_X_pow_sub_C, + ite_eq_left ⟨α, e⟩] -- make this private, as we only use it to prove a strictly more general version private @@ -123,7 +124,7 @@ theorem X_pow_sub_C_irreducible_of_odd intro E _ _ x hx have : IsIntegral K x := not_not.mp fun h ↦ by simpa only [degree_zero, degree_X_pow_sub_C hp.pos, - WithBot.natCast_ne_bot] using congr_arg degree (hx.symm.trans (dif_neg h)) + WithBot.natCast_ne_bot] using congr_arg degree (hx.symm.trans (dite_eq_right h)) apply IH (Nat.odd_mul.mp hn).2 intro q hq hqn b hb apply ha q hq (dvd_mul_of_dvd_right hqn p) (Algebra.norm _ b) diff --git a/Mathlib/FieldTheory/Minpoly/Basic.lean b/Mathlib/FieldTheory/Minpoly/Basic.lean index ca19e0abb3af52..a72ebc79c35fc3 100644 --- a/Mathlib/FieldTheory/Minpoly/Basic.lean +++ b/Mathlib/FieldTheory/Minpoly/Basic.lean @@ -53,7 +53,7 @@ variable {x : B} /-- A minimal polynomial is monic. -/ theorem monic (hx : IsIntegral A x) : Monic (minpoly A x) := by delta minpoly - rw [dif_pos hx] + rw [dite_eq_left hx] exact (degree_lt_wf.min_mem _ hx).1 /-- A minimal polynomial is nonzero. -/ @@ -61,7 +61,7 @@ theorem ne_zero [Nontrivial A] (hx : IsIntegral A x) : minpoly A x ≠ 0 := (monic hx).ne_zero theorem eq_zero (hx : ¬IsIntegral A x) : minpoly A x = 0 := - dif_neg hx + dite_eq_right hx theorem ne_zero_iff [Nontrivial A] : minpoly A x ≠ 0 ↔ IsIntegral A x := ⟨fun h => of_not_not <| eq_zero.mt h, ne_zero⟩ diff --git a/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean b/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean index 0512776c018ead..ccba9dbe9550b3 100644 --- a/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean +++ b/Mathlib/FieldTheory/Minpoly/MinpolyDiv.lean @@ -45,7 +45,7 @@ variable {R x} lemma minpolyDiv_eq_zero (hx : ¬IsIntegral R x) : minpolyDiv R x = 0 := by delta minpolyDiv minpoly - rw [dif_neg hx, Polynomial.map_zero, zero_divByMonic] + rw [dite_eq_right hx, Polynomial.map_zero, zero_divByMonic] lemma eval_minpolyDiv_self : (minpolyDiv R x).eval x = aeval x (derivative <| minpoly R x) := by rw [← eval_map_algebraMap, ← derivative_map, ← minpolyDiv_spec R x]; simp diff --git a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean index 93bb362c78fc35..60c81c01310077 100644 --- a/Mathlib/FieldTheory/PolynomialGaloisGroup.lean +++ b/Mathlib/FieldTheory/PolynomialGaloisGroup.lean @@ -240,7 +240,7 @@ theorem restrictDvd_surjective (hpq : p ∣ q) (hq : q ≠ 0) : classical have := Fact.mk <| (SplittingField.splits q).of_dvd (map_ne_zero hq) ((map_dvd_map' _).mpr hpq) - simpa only [restrictDvd_def, dif_neg hq] using! restrict_surjective _ _ + simpa only [restrictDvd_def, dite_eq_right hq] using! restrict_surjective _ _ variable (p q) @@ -257,7 +257,7 @@ theorem restrictProd_injective : Function.Injective (restrictProd p q) := by intro f g hfg classical simp only [restrictProd, restrictDvd_def] at hfg - simp only [dif_neg hpq, MonoidHom.prod_apply, Prod.mk_inj] at hfg + simp only [dite_eq_right hpq, MonoidHom.prod_apply, Prod.mk_inj] at hfg ext (x hx) rw [rootSet_def, aroots_mul hpq] at hx rcases Multiset.mem_add.mp (Multiset.mem_toFinset.mp hx) with h | h diff --git a/Mathlib/FieldTheory/RatFunc/Basic.lean b/Mathlib/FieldTheory/RatFunc/Basic.lean index 497cd79e485fc4..e52d32c323c719 100644 --- a/Mathlib/FieldTheory/RatFunc/Basic.lean +++ b/Mathlib/FieldTheory/RatFunc/Basic.lean @@ -324,7 +324,7 @@ def map [MonoidHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap (fun n d => if h : φ d ∈ S[X]⁰ then ofFractionRing (Localization.mk (φ n) ⟨φ d, h⟩) else 0) fun {p q p' q'} hq hq' h => by simp only [Submonoid.mem_comap.mp (hφ hq), Submonoid.mem_comap.mp (hφ hq'), - dif_pos, ofFractionRing.injEq, Localization.mk_eq_mk_iff] + dite_eq_left, ofFractionRing.injEq, Localization.mk_eq_mk_iff] refine Localization.r_of_eq ?_ simpa only [map_mul] using congr_arg φ h map_one' := by @@ -340,8 +340,8 @@ def map [MonoidHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap have hq : φ q ∈ S[X]⁰ := hφ q.prop have hq' : φ q' ∈ S[X]⁰ := hφ q'.prop have hqq' : φ ↑(q * q') ∈ S[X]⁰ := by simpa using Submonoid.mul_mem _ hq hq' - simp_rw [← ofFractionRing_mul, Localization.mk_mul, liftOn_ofFractionRing_mk, dif_pos hq, - dif_pos hq', dif_pos hqq', ← ofFractionRing_mul, Submonoid.coe_mul, map_mul, + simp_rw [← ofFractionRing_mul, Localization.mk_mul, liftOn_ofFractionRing_mk, dite_eq_left hq, + dite_eq_left hq', dite_eq_left hqq', ← ofFractionRing_mul, Submonoid.coe_mul, map_mul, Localization.mk_mul, Submonoid.mk_mul_mk] theorem map_apply_ofFractionRing_mk [MonoidHomClass F R[X] S[X]] (φ : F) @@ -869,7 +869,7 @@ def numDenom (x : K⟮X⟯) : K[X] × K[X] := (by intro p q a hq ha dsimp - rw [if_neg hq, if_neg (mul_ne_zero ha hq)] + rw [ite_eq_right hq, ite_eq_right (mul_ne_zero ha hq)] have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha' simp only [Prod.ext_iff, gcd_mul_left, normalize_apply a, Polynomial.coe_normUnit, mul_assoc, @@ -896,9 +896,9 @@ theorem numDenom_div (p : K[X]) {q : K[X]} (hq : q ≠ 0) : numDenom (algebraMap _ _ p / algebraMap _ _ q) = (Polynomial.C (q / gcd p q).leadingCoeff⁻¹ * (p / gcd p q), Polynomial.C (q / gcd p q).leadingCoeff⁻¹ * (q / gcd p q)) := by - rw [numDenom, liftOn'_div, if_neg hq] + rw [numDenom, liftOn'_div, ite_eq_right hq] intro p - rw [if_pos rfl, if_neg (one_ne_zero' K[X])] + rw [ite_eq_left rfl, ite_eq_right (one_ne_zero' K[X])] simp /-- `RatFunc.num` is the numerator of a rational function, diff --git a/Mathlib/FieldTheory/RatFunc/Luroth.lean b/Mathlib/FieldTheory/RatFunc/Luroth.lean index ff6a20c3b98704..e8766bfdee1cff 100644 --- a/Mathlib/FieldTheory/RatFunc/Luroth.lean +++ b/Mathlib/FieldTheory/RatFunc/Luroth.lean @@ -84,10 +84,10 @@ public def generator : K⟮X⟯ := if h : E = ⊥ then 0 else (φ E).coeff (generatorIndex h) public lemma generator_eq_zero (h : E = ⊥) : generator E = 0 := - dif_pos h + dite_eq_left h lemma generator_eq_coeff (h : E ≠ ⊥) : generator E = (φ E).coeff (generatorIndex h) := - dif_neg h + dite_eq_right h public lemma generator_mem : generator E ∈ E := by by_cases h : E = ⊥ diff --git a/Mathlib/FieldTheory/RatFunc/Valuation.lean b/Mathlib/FieldTheory/RatFunc/Valuation.lean index ad340c2f547df2..effcc6bb7998bf 100644 --- a/Mathlib/FieldTheory/RatFunc/Valuation.lean +++ b/Mathlib/FieldTheory/RatFunc/Valuation.lean @@ -52,18 +52,18 @@ def inftyValuationDef (r : RatFunc F) : ℤᵐ⁰ := if r = 0 then 0 else exp r.intDegree theorem InftyValuation.map_zero' : inftyValuationDef F 0 = 0 := - if_pos rfl + ite_eq_left rfl theorem InftyValuation.map_one' : inftyValuationDef F 1 = 1 := - (if_neg one_ne_zero).trans <| by simp + (ite_eq_right one_ne_zero).trans <| by simp theorem InftyValuation.map_mul' (x y : RatFunc F) : inftyValuationDef F (x * y) = inftyValuationDef F x * inftyValuationDef F y := by rw [inftyValuationDef, inftyValuationDef, inftyValuationDef] by_cases hx : x = 0 - · rw [hx, zero_mul, if_pos (Eq.refl _), zero_mul] + · rw [hx, zero_mul, ite_eq_left (Eq.refl _), zero_mul] · by_cases hy : y = 0 - · rw [hy, mul_zero, if_pos (Eq.refl _), mul_zero] + · rw [hy, mul_zero, ite_eq_left (Eq.refl _), mul_zero] · simp_all [RatFunc.intDegree_mul] theorem InftyValuation.map_add_le_max' (x y : RatFunc F) : @@ -75,7 +75,7 @@ theorem InftyValuation.map_add_le_max' (x y : RatFunc F) : @[simp] theorem inftyValuation_of_nonzero {x : RatFunc F} (hx : x ≠ 0) : inftyValuationDef F x = exp x.intDegree := by - rw [inftyValuationDef, if_neg hx] + rw [inftyValuationDef, ite_eq_right hx] /-- The valuation at infinity on `F(t)`. -/ def inftyValuation : Valuation (RatFunc F) ℤᵐ⁰ where @@ -95,7 +95,8 @@ theorem inftyValuation.C {k : F} (hk : k ≠ 0) : @[simp] theorem inftyValuation.X : inftyValuation F RatFunc.X = exp 1 := by - simp [inftyValuation_apply, inftyValuationDef, if_neg RatFunc.X_ne_zero, RatFunc.intDegree_X] + simp [inftyValuation_apply, inftyValuationDef, ite_eq_right RatFunc.X_ne_zero, + RatFunc.intDegree_X] lemma inftyValuation.X_zpow (m : ℤ) : inftyValuation F (RatFunc.X ^ m) = exp m := by simp @@ -106,7 +107,7 @@ theorem inftyValuation.X_inv : inftyValuation F (1 / RatFunc.X) = exp (-1) := by -- https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.60synthInstance.2EmaxHeartbeats.60.20error.20but.20only.20in.20.60simpNF.60 theorem inftyValuation.polynomial {p : F[X]} (hp : p ≠ 0) : inftyValuationDef F (algebraMap F[X] (RatFunc F) p) = exp (p.natDegree : ℤ) := by - rw [inftyValuationDef, if_neg (by simpa), RatFunc.intDegree_polynomial] + rw [inftyValuationDef, ite_eq_right (by simpa), RatFunc.intDegree_polynomial] instance : Valuation.IsNontrivial (inftyValuation F) := ⟨RatFunc.X, by simp⟩ diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 052ffff94300f2..abfa0ddd97c193 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -271,7 +271,7 @@ theorem rootMultiplicity_le_one_of_separable [Nontrivial R] {p : R[X]} (hsep : S classical by_cases hp : p = 0 · simp [hp] - rw [rootMultiplicity_eq_multiplicity, if_neg hp, ← Nat.cast_le (α := ℕ∞), + rw [rootMultiplicity_eq_multiplicity, ite_eq_right hp, ← Nat.cast_le (α := ℕ∞), Nat.cast_one, ← (finiteMultiplicity_X_sub_C x hp).emultiplicity_eq_multiplicity] apply emultiplicity_le_one_of_separable (not_isUnit_X_sub_C _) hsep diff --git a/Mathlib/FieldTheory/SeparablyGenerated.lean b/Mathlib/FieldTheory/SeparablyGenerated.lean index 50417b47d7b220..7561782827dd8a 100644 --- a/Mathlib/FieldTheory/SeparablyGenerated.lean +++ b/Mathlib/FieldTheory/SeparablyGenerated.lean @@ -236,7 +236,7 @@ lemma exists_isTranscendenceBasis_and_isSeparable_of_linearIndepOn_pow replace eq := congr(Polynomial.coeff $eq (σ i)) rwa [← minpoly.eq_of_irreducible hF₂irr ((Polynomial.aeval_map_algebraMap ..).trans (aeval_toPolynomialAdjoinImageCompl_eq_zero hFa i)), Polynomial.coeff_mul_C, - Polynomial.coeff_expand hp.pos, if_neg hi, eq_mul_inv_iff_mul_eq₀ + Polynomial.coeff_expand hp.pos, ite_eq_right hi, eq_mul_inv_iff_mul_eq₀ (by simpa using hF₂irr.ne_zero), zero_mul, eq_comm, Polynomial.coeff_map, map_eq_zero_iff _ (FaithfulSMul.algebraMap_injective ..)] at eq diff --git a/Mathlib/FieldTheory/SplittingField/Construction.lean b/Mathlib/FieldTheory/SplittingField/Construction.lean index ff8bd752efb1e1..c7f21456d87ae1 100644 --- a/Mathlib/FieldTheory/SplittingField/Construction.lean +++ b/Mathlib/FieldTheory/SplittingField/Construction.lean @@ -65,7 +65,7 @@ attribute [local instance] fact_irreducible_factor theorem factor_dvd_of_not_isUnit {f : K[X]} (hf1 : ¬IsUnit f) : factor f ∣ f := by by_cases hf2 : f = 0; · rw [hf2]; exact dvd_zero _ - rw [factor, dif_pos (WfDvdMonoid.exists_irreducible_factor hf1 hf2)] + rw [factor, dite_eq_left (WfDvdMonoid.exists_irreducible_factor hf1 hf2)] exact (Classical.choose_spec <| WfDvdMonoid.exists_irreducible_factor hf1 hf2).2 theorem factor_dvd_of_degree_ne_zero {f : K[X]} (hf : f.degree ≠ 0) : factor f ∣ f := diff --git a/Mathlib/Geometry/Convex/Set.lean b/Mathlib/Geometry/Convex/Set.lean index 73603706e4de19..a2873695addff5 100644 --- a/Mathlib/Geometry/Convex/Set.lean +++ b/Mathlib/Geometry/Convex/Set.lean @@ -125,7 +125,7 @@ protected lemma IsConvexSet.image (hf : IsAffineMap R f) (hs : IsConvexSet R s) · rw [← huw, Finset.mem_image] at hy obtain ⟨x, hx, rfl⟩ := hy convert mapDomain_apply' _ _ support_onFinset_subset hfu hx - exact (if_pos hx).symm + exact (ite_eq_left hx).symm · rw [mapDomain_of_not_mem_image_support (by simp [← huw] at ⊢ hy; tauto)] simp_all diff --git a/Mathlib/Geometry/Euclidean/Circumcenter.lean b/Mathlib/Geometry/Euclidean/Circumcenter.lean index c39390db2cc772..70c28c9556b3fa 100644 --- a/Mathlib/Geometry/Euclidean/Circumcenter.lean +++ b/Mathlib/Geometry/Euclidean/Circumcenter.lean @@ -159,7 +159,7 @@ theorem _root_.AffineIndependent.existsUnique_dist_eq {ι : Type*} [hne : Nonemp classical have hc : Fintype.card ι2 = m + 1 := by rw [Fintype.card_of_subtype {x | x ≠ i}] - · rw [Finset.filter_not, Finset.filter_eq' _ i, if_pos (Finset.mem_univ _), + · rw [Finset.filter_not, Finset.filter_eq' _ i, ite_eq_left (Finset.mem_univ _), Finset.card_sdiff, Finset.card_univ, hn] simp · simp @@ -579,7 +579,7 @@ theorem sum_reflectionCircumcenterWeightsWithCircumcenter {n : ℕ} {i₁ i₂ : sum_const, filter_or, filter_eq'] rw [card_union_of_disjoint] · norm_num - · simpa only [if_true, mem_univ, disjoint_singleton] using h + · simpa only [ite_true, mem_univ, disjoint_singleton] using h /-- The reflection of the circumcenter of a simplex in an edge, in terms of `pointsWithCircumcenter`. -/ diff --git a/Mathlib/Geometry/Euclidean/MongePoint.lean b/Mathlib/Geometry/Euclidean/MongePoint.lean index e8d11808e27dba..623a8dfd653e2f 100644 --- a/Mathlib/Geometry/Euclidean/MongePoint.lean +++ b/Mathlib/Geometry/Euclidean/MongePoint.lean @@ -171,7 +171,7 @@ theorem mongePoint_eq_affineCombination_of_pointsWithCircumcenter {n : ℕ} simp_rw [centroidWeightsWithCircumcenter, circumcenterWeightsWithCircumcenter, mongePointWeightsWithCircumcenter] <;> rw [add_tsub_assoc_of_le (by decide : 1 ≤ 2), (by decide : 2 - 1 = 1)] - · rw [if_pos (mem_univ _), card_fin] + · rw [ite_eq_left (mem_univ _), card_fin] field · simp [field] ring diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index 9109509853bc05..1115ae522adc2d 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -359,7 +359,7 @@ theorem tangentMap_tangentBundle_pure [Is : IsManifold I 1 M] · exact ModelWithCorners.uniqueDiffWithinAt_image I · exact differentiableAt_id.prodMk (differentiableAt_const _) simp +unfoldPartialApp only [Bundle.zeroSection, tangentMap, mfderiv, A, - if_pos, chartAt, FiberBundle.chartedSpace_chartAt, TangentBundle.trivializationAt_apply, + ite_eq_left, chartAt, FiberBundle.chartedSpace_chartAt, TangentBundle.trivializationAt_apply, Function.comp_def, map_zero, mfld_simps] rw [← fderivWithin_inter N] at B rw [← fderivWithin_inter N, ← B] diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 55e1e0f500a57d..b1aff93effe517 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -442,9 +442,9 @@ instance instIccChartedSpace (x y : ℝ) [h : Fact (x < y)] : chartAt z := if z.val < y then IccLeftChart x y else IccRightChart x y mem_chart_source z := by by_cases h' : z.val < y - · simp only [h', if_true] + · simp only [h', ite_true] exact h' - · simp only [h', if_false] + · simp only [h', ite_false] apply lt_of_lt_of_le h.out simpa only [not_lt] using h' chart_mem_atlas z := by by_cases h' : (z : ℝ) < y <;> simp [h'] diff --git a/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean b/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean index 4b4ad1471634c5..fa5003c4b11036 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve/UniformTime.lean @@ -110,10 +110,10 @@ lemma eqOn_piecewise_of_isMIntegralCurveOn_Ioo [BoundarylessManifold I M] intro t ht suffices H : EqOn γ γ' (Ioo (max a a') (min b b')) by by_cases hmem : t ∈ Ioo a b - · rw [piecewise, if_pos hmem] + · rw [piecewise, ite_eq_left hmem] apply H simp [ht.1, ht.2, hmem.1, hmem.2] - · rw [piecewise, if_neg hmem] + · rw [piecewise, ite_eq_right hmem] apply isMIntegralCurveOn_Ioo_eqOn_of_contMDiff_boundaryless _ hv (hγ.mono (Ioo_subset_Ioo (le_max_left ..) (min_le_left ..))) (hγ'.mono (Ioo_subset_Ioo (le_max_right ..) (min_le_right ..))) h @@ -135,19 +135,19 @@ lemma isMIntegralCurveOn_piecewise [BoundarylessManifold I M] IsMIntegralCurveOn (piecewise (Ioo a b) γ γ') v (Ioo a b ∪ Ioo a' b') := by intro t ht by_cases hmem : t ∈ Ioo a b - · rw [piecewise, if_pos hmem] + · rw [piecewise, ite_eq_left hmem] apply hγ t hmem |>.hasMFDerivAt (Ioo_mem_nhds hmem.1 hmem.2) |>.hasMFDerivWithinAt - (s := Ioo a b ∪ Ioo a' b') |>.congr_of_eventuallyEq _ (by rw [piecewise, if_pos hmem]) + (s := Ioo a b ∪ Ioo a' b') |>.congr_of_eventuallyEq _ (by rw [piecewise, ite_eq_left hmem]) rw [Filter.eventuallyEq_iff_exists_mem] - refine ⟨Ioo a b, ?_, fun _ ht' ↦ by rw [piecewise, if_pos ht']⟩ + refine ⟨Ioo a b, ?_, fun _ ht' ↦ by rw [piecewise, ite_eq_left ht']⟩ rw [(isOpen_Ioo.union isOpen_Ioo).nhdsWithin_eq ht] exact Ioo_mem_nhds hmem.1 hmem.2 · have ht' := ht rw [mem_union, or_iff_not_imp_left] at ht - rw [piecewise, if_neg hmem] + rw [piecewise, ite_eq_right hmem] apply hγ' t (ht hmem) |>.hasMFDerivAt (Ioo_mem_nhds (ht hmem).1 (ht hmem).2) |>.hasMFDerivWithinAt (s := Ioo a b ∪ Ioo a' b') - |>.congr_of_eventuallyEq _ (by rw [piecewise, if_neg hmem]) + |>.congr_of_eventuallyEq _ (by rw [piecewise, ite_eq_right hmem]) rw [Filter.eventuallyEq_iff_exists_mem] refine ⟨Ioo a' b', ?_, eqOn_piecewise_of_isMIntegralCurveOn_Ioo hv hγ hγ' ht₀ h⟩ @@ -201,14 +201,14 @@ lemma exists_isMIntegralCurve_of_isMIntegralCurveOn [BoundarylessManifold I M] set γ_ext : ℝ → M := piecewise (Ioo (-(asup + ε / 2)) a) (piecewise (Ioo (-a) a) γ γ1) γ2 with γ_ext_def have heq_ext : γ_ext 0 = x := by - rw [γ_ext_def, piecewise, if_pos ⟨by linarith, by linarith⟩, piecewise, - if_pos ⟨by linarith, by linarith⟩, h0] + rw [γ_ext_def, piecewise, ite_eq_left ⟨by linarith, by linarith⟩, piecewise, + ite_eq_left ⟨by linarith, by linarith⟩, h0] -- `asup + ε / 2` is an element of `s` greater than `asup`, a contradiction suffices hext : IsMIntegralCurveOn γ_ext v (Ioo (-(asup + ε / 2)) (asup + ε / 2)) from (not_lt.mpr <| le_csSup hbdd ⟨γ_ext, heq_ext, hext⟩) <| lt_add_of_pos_right asup (half_pos hε) apply (isMIntegralCurveOn_piecewise (t₀ := asup - ε / 2) hv _ hγ2 ⟨⟨by linarith, hlt⟩, ⟨by linarith, by linarith⟩⟩ - (by rw [piecewise, if_pos ⟨by linarith, hlt⟩, ← heq2])).mono + (by rw [piecewise, ite_eq_left ⟨by linarith, hlt⟩, ← heq2])).mono (Ioo_subset_Ioo_union_Ioo le_rfl (by linarith) (by linarith)) exact (isMIntegralCurveOn_piecewise (t₀ := -(asup - ε / 2)) hv hγ hγ1 ⟨⟨neg_lt_neg hlt, by linarith⟩, ⟨by linarith, by linarith⟩⟩ heq1.symm).mono diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index 67f8c443522412..a4bbdf4e49ce8e 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -194,7 +194,7 @@ def ModelWithCorners.ofTargetUniv (𝕜 : Type*) [NontriviallyNormedField 𝕜] source_eq := hsource convex_range' := by have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm] - simp only [this, htarget, dite_else_true] + simp only [this, htarget, dite_true_right] intro h let := h.rclike 𝕜 let := NormedSpace.restrictScalars ℝ 𝕜 E diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index fd47f4d3de49e2..327537cd8acc1a 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -519,11 +519,11 @@ theorem mfderivWithin_univ : mfderiv[univ] f = mfderiv% f := by set_option backward.isDefEq.respectTransparency false in theorem mfderivWithin_zero_of_not_mdifferentiableWithinAt (h : ¬MDiffAt[s] f x) : mfderiv[s] f x = 0 := by - simp only [mfderivWithin, h, if_neg, not_false_iff] + simp only [mfderivWithin, h, ite_eq_right, not_false_iff] set_option backward.isDefEq.respectTransparency false in theorem mfderiv_zero_of_not_mdifferentiableAt (h : ¬MDiffAt f x) : - mfderiv% f x = 0 := by simp only [mfderiv, h, if_neg, not_false_iff] + mfderiv% f x = 0 := by simp only [mfderiv, h, ite_eq_right, not_false_iff] @[nontriviality] theorem mdifferentiable_of_subsingleton [Subsingleton E] : MDiff f := by @@ -643,7 +643,7 @@ protected theorem MDifferentiableWithinAt.mfderivWithin (h : MDiffAt[s] f x) : mfderiv[s] f x = fderivWithin 𝕜 (writtenInExtChartAt I I' x f :) ((extChartAt I x).symm ⁻¹' s ∩ range I) ((extChartAt I x) x) := by - simp only [mfderivWithin, h, if_pos] + simp only [mfderivWithin, h, ite_eq_left] theorem MDifferentiableAt.hasMFDerivAt (h : MDiffAt f x) : HasMFDerivAt% f x (mfderiv% f x) := by refine ⟨h.continuousAt, ?_⟩ @@ -654,7 +654,7 @@ set_option backward.isDefEq.respectTransparency false in protected theorem MDifferentiableAt.mfderiv (h : MDiffAt f x) : mfderiv% f x = fderivWithin 𝕜 (writtenInExtChartAt I I' x f :) (range I) ((extChartAt I x) x) := by - simp only [mfderiv, h, if_pos] + simp only [mfderiv, h, ite_eq_left] protected theorem HasMFDerivAt.mfderiv (h : HasMFDerivAt% f x f') : mfderiv% f x = f' := (hasMFDerivAt_unique h h.mdifferentiableAt.hasMFDerivAt).symm @@ -669,7 +669,7 @@ theorem HasMFDerivWithinAt.mfderivWithin_eq_zero (h : HasMFDerivWithinAt I I' f mfderiv[s] f x = 0 := by simp only [mfld_simps, mfderivWithin, h.mdifferentiableWithinAt, ↓reduceIte] simp only [HasMFDerivWithinAt, mfld_simps] at h - rw [fderivWithin, if_pos] + rw [fderivWithin, ite_eq_left] exact h.2 theorem MDifferentiable.mfderivWithin (h : MDiffAt f x) (hxs : UniqueMDiffAt[s] x) : @@ -1036,7 +1036,7 @@ theorem Filter.EventuallyEq.mfderivWithin_eq (hL : f₁ =ᶠ[𝓝[s] x] f) (hx : simp only [preimage_ofPred_eq, mem_ofPred_eq] at hy simp [-extChartAt, hy, hx] · unfold mfderivWithin - rw [if_neg h, if_neg] + rw [ite_eq_right h, ite_eq_right] rwa [← hL.mdifferentiableWithinAt_iff hx] theorem Filter.EventuallyEq.mfderivWithin_eq_of_mem (hL : f₁ =ᶠ[𝓝[s] x] f) (hx : x ∈ s) : diff --git a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean index 2531fe54145cce..94fa8345645e35 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/FDeriv.lean @@ -108,8 +108,8 @@ set_option backward.isDefEq.respectTransparency false in theorem mfderivWithin_eq_fderivWithin : mfderiv[s] f x = fderivWithin 𝕜 f s x := by by_cases h : MDiffAt[s] f x - · simp only [mfderivWithin, h, if_pos, mfld_simps] - · simp only [mfderivWithin, h, if_neg, not_false_iff] + · simp only [mfderivWithin, h, ite_eq_left, mfld_simps] + · simp only [mfderivWithin, h, ite_eq_right, not_false_iff] rw [mdifferentiableWithinAt_iff_differentiableWithinAt] at h exact (fderivWithin_zero_of_not_differentiableWithinAt h).symm diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 05bd236682c653..5540f1fbccadfa 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -889,7 +889,7 @@ theorem mfderivWithin_neg (hs : UniqueMDiffAt[s] x) : simp_rw [mfderivWithin] by_cases hf : MDiffAt[s] f x · exact hf.hasMFDerivWithinAt.neg.mfderivWithin hs - · rw [if_neg hf]; rw [← mdifferentiableWithinAt_neg] at hf; rw [if_neg hf, neg_zero] + · rw [ite_eq_right hf]; rw [← mdifferentiableWithinAt_neg] at hf; rw [ite_eq_right hf, neg_zero] theorem mfderiv_neg : mfderiv% (-f) x = -mfderiv% f x := by rw [← mfderivWithin_univ, mfderivWithin_neg (uniqueMDiffWithinAt_univ I), mfderivWithin_univ] diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean index 032c1ba7d91cf1..0147e88dba05dd 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean @@ -62,7 +62,7 @@ set_option backward.isDefEq.respectTransparency false in lemma mfderiv_chartAt_eq_tangentCoordChange {x y : M} (hsrc : x ∈ (chartAt H y).source) : mfderiv% (chartAt H y) x = tangentCoordChange I x y x := by have := mdifferentiableAt_atlas (I := I) (ChartedSpace.chart_mem_atlas _) hsrc - simp [mfderiv, if_pos this, Function.comp_assoc] + simp [mfderiv, ite_eq_left this, Function.comp_assoc] /-- The preimage under the projection from the tangent bundle of a set with unique differential in the basis also has unique differential. -/ @@ -86,7 +86,7 @@ lemma inTangentCoordinates_eq_mfderiv_comp · have : MDiffAt (extChartAt I' (g x₀)) (g x) := mdifferentiableAt_extChartAt hy simp_all [mfderiv] · simp only [mfderivWithin, writtenInExtChartAt, modelWithCornersSelf_coe, range_id, inter_univ] - rw [if_pos] + rw [ite_eq_left] · simp [Function.comp_def, OpenPartialHomeomorph.left_inv (chartAt H (f x₀)) hx] · apply mdifferentiableWithinAt_extChartAt_symm apply (extChartAt I (f x₀)).map_source diff --git a/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean b/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean index 08c6e1cbe53fcf..af15ba7885da5a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/FiberwiseLinear.lean @@ -195,7 +195,7 @@ theorem ContMDiffFiberwiseLinear.locality_aux₂ let Φ₀ : U → F ≃L[𝕜] F := iUnionLift u (fun x => φ x ∘ (↑)) huφ U hUu'.le let Φ : B → F ≃L[𝕜] F := fun y => if hy : y ∈ U then Φ₀ ⟨y, hy⟩ else ContinuousLinearEquiv.refl 𝕜 F - have hΦ : ∀ (y) (hy : y ∈ U), Φ y = Φ₀ ⟨y, hy⟩ := fun y hy => dif_pos hy + have hΦ : ∀ (y) (hy : y ∈ U), Φ y = Φ₀ ⟨y, hy⟩ := fun y hy => dite_eq_left hy have hΦφ : ∀ x : U, ∀ y ∈ u x, Φ y = φ x y := by intro x y hyu refine (hΦ y (hUu x hyu)).trans ?_ diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index f9814addf3e62e..fec40e5f38b3e6 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -157,14 +157,15 @@ lemma reciprocalFactors_even {n : ℕ} (h0 : n ≠ 0) (h2 : Even n) : have h1 : n ≠ 1 := by rintro rfl norm_num at h2 - rw [reciprocalFactors, dif_neg h0, dif_neg h1, if_pos h2] + rw [reciprocalFactors, dite_eq_right h0, dite_eq_right h1, ite_eq_left h2] lemma reciprocalFactors_odd {n : ℕ} (h1 : n ≠ 1) (h2 : Odd n) : reciprocalFactors n = n % 4 * n :: reciprocalFactors (n / 4 + 1) := by have h0 : n ≠ 0 := by rintro rfl norm_num [← Nat.not_even_iff_odd] at h2 - rw [reciprocalFactors, dif_neg h0, dif_neg h1, if_neg (Nat.not_even_iff_odd.2 h2)] + rw [reciprocalFactors, dite_eq_right h0, dite_eq_right h1, + ite_eq_right (Nat.not_even_iff_odd.2 h2)] /-- A finite product of Dihedral groups. -/ abbrev Product (l : List ℕ) : Type := diff --git a/Mathlib/GroupTheory/Complement.lean b/Mathlib/GroupTheory/Complement.lean index 3612796da5a4f4..34c95eab8f317f 100644 --- a/Mathlib/GroupTheory/Complement.lean +++ b/Mathlib/GroupTheory/Complement.lean @@ -276,7 +276,7 @@ lemma exists_isComplement_left (H : Subgroup G) (g : G) : ∃ S, IsComplement S QuotientGroup.mk g, Function.update_self (Quotient.mk'' g) g Quotient.out⟩ by_cases hq : q = Quotient.mk'' g · exact hq.symm ▸ congr_arg _ (Function.update_self (Quotient.mk'' g) g Quotient.out) - · simp [Function.update, dif_neg hq, q.out_eq'] + · simp [Function.update, dite_eq_right hq, q.out_eq'] @[to_additive] lemma exists_isComplement_right (H : Subgroup G) (g : G) : @@ -286,7 +286,7 @@ lemma exists_isComplement_right (H : Subgroup G) (g : G) : Quotient.mk'' g, Function.update_self (Quotient.mk'' g) g Quotient.out⟩ by_cases hq : q = Quotient.mk'' g · exact hq.symm ▸ congr_arg _ (Function.update_self (Quotient.mk'' g) g Quotient.out) - · simp [Function.update, dif_neg hq, q.out_eq'] + · simp [Function.update, dite_eq_right hq, q.out_eq'] /-- Given two subgroups `H' ⊆ H`, there exists a left transversal to `H'` inside `H`. -/ @[to_additive /-- Given two subgroups `H' ⊆ H`, there exists a transversal to `H'` inside `H` -/] diff --git a/Mathlib/GroupTheory/CoprodI.lean b/Mathlib/GroupTheory/CoprodI.lean index 076e3760fcdeb3..627584178ce48e 100644 --- a/Mathlib/GroupTheory/CoprodI.lean +++ b/Mathlib/GroupTheory/CoprodI.lean @@ -341,24 +341,24 @@ def rcons {i} (p : Pair M i) : Word M := @[simp] theorem prod_rcons {i} (p : Pair M i) : prod (rcons p) = of p.head * prod p.tail := - if hm : p.head = 1 then by rw [rcons, dif_pos hm, hm, map_one, one_mul] - else by rw [rcons, dif_neg hm, cons, prod, List.map_cons, List.prod_cons, prod] + if hm : p.head = 1 then by rw [rcons, dite_eq_left hm, hm, map_one, one_mul] + else by rw [rcons, dite_eq_right hm, cons, prod, List.map_cons, List.prod_cons, prod] theorem rcons_inj {i} : Function.Injective (rcons : Pair M i → Word M) := by rintro ⟨m, w, h⟩ ⟨m', w', h'⟩ he by_cases hm : m = 1 <;> by_cases hm' : m' = 1 - · simp only [rcons, dif_pos hm, dif_pos hm'] at he + · simp only [rcons, dite_eq_left hm, dite_eq_left hm'] at he simp_all · exfalso - simp only [rcons, dif_pos hm, dif_neg hm'] at he + simp only [rcons, dite_eq_left hm, dite_eq_right hm'] at he rw [he] at h exact h rfl · exfalso - simp only [rcons, dif_pos hm', dif_neg hm] at he + simp only [rcons, dite_eq_left hm', dite_eq_right hm] at he rw [← he] at h' exact h' rfl · have : m = m' ∧ w.toList = w'.toList := by - simpa [cons, rcons, dif_neg hm, dif_neg hm', eq_self_iff_true, Subtype.mk_eq_mk, + simpa [cons, rcons, dite_eq_right hm, dite_eq_right hm', eq_self_iff_true, Subtype.mk_eq_mk, heq_iff_eq, ← Subtype.ext_iff] using he rcases this with ⟨rfl, h⟩ congr @@ -434,7 +434,7 @@ theorem equivPair_symm (i) (p : Pair M i) : (equivPair i).symm p = rcons p := theorem equivPair_eq_of_fstIdx_ne {i} {w : Word M} (h : fstIdx w ≠ some i) : equivPair i w = ⟨1, w, h⟩ := - (equivPair i).eq_symm_apply.mp <| Eq.symm (dif_pos rfl) + (equivPair i).eq_symm_apply.mp <| Eq.symm (dite_eq_left rfl) theorem mem_equivPair_tail_iff {i j : ι} {w : Word M} (m : M i) : (⟨i, m⟩ ∈ (equivPair j w).tail.toList) ↔ ⟨i, m⟩ ∈ w.toList.tail diff --git a/Mathlib/GroupTheory/CosetCover.lean b/Mathlib/GroupTheory/CosetCover.lean index 72c5b48c85634e..e598607cd2ca27 100644 --- a/Mathlib/GroupTheory/CosetCover.lean +++ b/Mathlib/GroupTheory/CosetCover.lean @@ -248,7 +248,7 @@ theorem leftCoset_cover_filter_FiniteIndex_aux have ⟨j, hj, hjfi⟩ := exists_finiteIndex_of_leftCoset_cover hcovers have ⟨x, hx⟩ : (t j hj hjfi).Nonempty := Finset.nonempty_coe_sort.mp (ht j hj hjfi).1.leftQuotientEquiv.symm.nonempty - ⟨⟨⟨j, hj⟩, ⟨x, dif_pos hjfi ▸ hx⟩⟩, hjfi, if_pos hjfi⟩ + ⟨⟨⟨j, hj⟩, ⟨x, dite_eq_left hjfi ▸ hx⟩⟩, hjfi, ite_eq_left hjfi⟩ -- Since `D` is the unique subgroup of finite index whose cosets occur in the new covering, -- the cosets of the other subgroups can be omitted. replace hcovers' : ⋃ i ∈ Finset.univ.filter (K · = D), f i • (D : Set G) = Set.univ := by @@ -296,8 +296,8 @@ theorem leftCoset_cover_filter_FiniteIndex_aux rw [← (ht i hi.1 hi.2).2] at hi' suffices ∃ r : H i, r ∈ t i hi.1 hi.2 ∧ x ∈ (g i * r) • (D : Set G) by have ⟨r, hr, hxr⟩ := this - refine ⟨⟨⟨i, hi.1⟩, ⟨r, dif_pos hi.2 ▸ hr⟩⟩, rfl, ?_⟩ - simpa [K, f, if_pos hi.2] using! hxr + refine ⟨⟨⟨i, hi.1⟩, ⟨r, dite_eq_left hi.2 ▸ hr⟩⟩, rfl, ?_⟩ + simpa [K, f, ite_eq_left hi.2] using! hxr simpa [Set.mem_smul_set_iff_inv_smul_mem, smul_eq_mul, mul_assoc] using! hi' hx have ⟨k₁, hik₁, hk₁, hxk₁⟩ := hk' i hi hi' have ⟨k₂, hjk₂, hk₂, hxk₂⟩ := hk' j hj hj' diff --git a/Mathlib/GroupTheory/Coxeter/Basic.lean b/Mathlib/GroupTheory/Coxeter/Basic.lean index 9d635425464da8..6ab351d45c2de0 100644 --- a/Mathlib/GroupTheory/Coxeter/Basic.lean +++ b/Mathlib/GroupTheory/Coxeter/Basic.lean @@ -437,10 +437,10 @@ lemma getElem_alternatingWord_swapIndices (i j : B) (p k : ℕ) (h : k + 1 < p) rw [getElem_alternatingWord i j p (k + 1) (by lia), getElem_alternatingWord j i p k (by lia)] by_cases h_even : Even (p + k) - · rw [if_pos h_even, ← add_assoc] + · rw [ite_eq_left h_even, ← add_assoc] simp only [ite_eq_right_iff, isEmpty_Prop, Nat.not_even_iff_odd, Even.add_one h_even, IsEmpty.forall_iff] - · rw [if_neg h_even, ← add_assoc] + · rw [ite_eq_right h_even, ← add_assoc] simp [Odd.add_one (Nat.not_even_iff_odd.mp h_even)] lemma listTake_alternatingWord (i j : B) (p k : ℕ) (h : k < 2 * p) : @@ -499,15 +499,16 @@ theorem prod_alternatingWord_eq_prod_alternatingWord_sub (i i' : B) (m : ℕ) (h clear hm push_cast rcases Int.even_or_odd' m' with ⟨k, rfl | rfl⟩ - · rw [if_pos (by use k; ring), if_pos (by use -k + (M i i'); ring), mul_comm 2 k, ← sub_mul] + · rw [ite_eq_left (by use k; ring), ite_eq_left (by use -k + (M i i'); ring), mul_comm 2 k, + ← sub_mul] repeat rw [Int.mul_ediv_cancel _ (by simp)] rw [zpow_sub, zpow_natCast, simple_mul_simple_pow' cs i i', ← inv_zpow] simp · have : ¬Even (2 * k + 1) := Int.not_even_iff_odd.2 ⟨k, rfl⟩ - rw [if_neg this] + rw [ite_eq_right this] have : ¬Even (↑(M i i') * 2 - (2 * k + 1)) := Int.not_even_iff_odd.2 ⟨↑(M i i') - k - 1, by ring⟩ - rw [if_neg this] + rw [ite_eq_right this] rw [(by ring : ↑(M i i') * 2 - (2 * k + 1) = -1 + (-k + ↑(M i i')) * 2), (by ring : 2 * k + 1 = 1 + k * 2)] repeat rw [Int.add_mul_ediv_right _ _ (by simp)] diff --git a/Mathlib/GroupTheory/Divisible.lean b/Mathlib/GroupTheory/Divisible.lean index aedc67e0134ae6..bdbe319dc88670 100644 --- a/Mathlib/GroupTheory/Divisible.lean +++ b/Mathlib/GroupTheory/Divisible.lean @@ -131,10 +131,10 @@ implies the textbook approach. noncomputable def rootableByOfPowLeftSurj (H : ∀ {n : α}, n ≠ 0 → Function.Surjective (fun a => a ^ n : A → A)) : RootableBy A α where root a n := @dite _ (n = 0) (Classical.dec _) (fun _ => (1 : A)) fun hn => (H hn a).choose - root_zero _ := by exact dif_pos rfl + root_zero _ := by exact dite_eq_left rfl root_cancel a hn := by dsimp only - rw [dif_neg hn] + rw [dite_eq_right hn] exact (H hn a).choose_spec section Pi @@ -190,9 +190,9 @@ noncomputable def divisibleByIntOfSMulTopEqTop (H : ∀ {n : ℤ} (_hn : n ≠ 0), n • (⊤ : AddSubgroup A) = ⊤) : DivisibleBy A ℤ where div a n := if hn : n = 0 then 0 else (show a ∈ n • (⊤ : AddSubgroup A) by rw [H hn]; trivial).choose - div_zero _ := dif_pos rfl + div_zero _ := dite_eq_left rfl div_cancel a hn := by - simp_rw [dif_neg hn] + simp_rw [dite_eq_right hn] generalize_proofs h1 exact h1.choose_spec.2 diff --git a/Mathlib/GroupTheory/Exponent.lean b/Mathlib/GroupTheory/Exponent.lean index 512803052b67bb..4177032921e38b 100644 --- a/Mathlib/GroupTheory/Exponent.lean +++ b/Mathlib/GroupTheory/Exponent.lean @@ -132,7 +132,7 @@ theorem exponent_eq_sInf : Monoid.exponent G = sInf {d : ℕ | 0 < d ∧ ∀ x : G, x ^ d = 1} := by by_cases h : Monoid.ExponentExists G · have h' : {d : ℕ | 0 < d ∧ ∀ x : G, x ^ d = 1}.Nonempty := h - rw [Monoid.exponent, dif_pos h, Nat.sInf_def h'] + rw [Monoid.exponent, dite_eq_left h, Nat.sInf_def h'] congr · have : {d | 0 < d ∧ ∀ (x : G), x ^ d = 1} = ∅ := Set.eq_empty_of_forall_notMem fun n hn ↦ h ⟨n, hn⟩ @@ -150,9 +150,9 @@ theorem exponent_eq_zero_iff_forall : exponent G = 0 ↔ ∀ n > 0, ∃ g : G, g theorem pow_exponent_eq_one (g : G) : g ^ exponent G = 1 := by classical by_cases h : ExponentExists G - · simp_rw [exponent, dif_pos h] + · simp_rw [exponent, dite_eq_left h] exact (Nat.find_spec h).2 g - · simp_rw [exponent, dif_neg h, pow_zero] + · simp_rw [exponent, dite_eq_right h, pow_zero] @[to_additive] theorem pow_eq_mod_exponent {n : ℕ} (g : G) : g ^ n = g ^ (n % exponent G) := @@ -168,7 +168,7 @@ theorem exponent_pos_of_exists (n : ℕ) (hpos : 0 < n) (hG : ∀ g : G, g ^ n = @[to_additive] theorem exponent_min' (n : ℕ) (hpos : 0 < n) (hG : ∀ g : G, g ^ n = 1) : exponent G ≤ n := by classical - rw [exponent, dif_pos] + rw [exponent, dite_eq_left] · apply Nat.find_min' exact ⟨hpos, hG⟩ · exact ⟨n, hpos, hG⟩ diff --git a/Mathlib/GroupTheory/FiniteAbelian/Basic.lean b/Mathlib/GroupTheory/FiniteAbelian/Basic.lean index 6ae6c08bf50888..e0823abf6d0f4a 100644 --- a/Mathlib/GroupTheory/FiniteAbelian/Basic.lean +++ b/Mathlib/GroupTheory/FiniteAbelian/Basic.lean @@ -75,7 +75,7 @@ private def directSumNeZeroMulEquiv (ι : Type) [DecidableEq ι] (p : ι → ℕ | zero => simp | of i x => rw [directSumNeZeroMulHom, DirectSum.toAddMonoid_of, DirectSum.toAddMonoid_of, - dif_neg i.prop] + dite_eq_right i.prop] | add x y hx hy => rw [map_add, map_add, hx, hy] right_inv x := by induction x using DirectSum.induction_on with diff --git a/Mathlib/GroupTheory/FreeAbelianGroup.lean b/Mathlib/GroupTheory/FreeAbelianGroup.lean index b9c068cd46ca91..314b05e3565c60 100644 --- a/Mathlib/GroupTheory/FreeAbelianGroup.lean +++ b/Mathlib/GroupTheory/FreeAbelianGroup.lean @@ -150,9 +150,9 @@ theorem of_injective : Function.Injective (of : α → FreeAbelianGroup α) := b classical exact fun x y hoxy ↦ Classical.by_contradiction fun hxy : x ≠ y ↦ let f : FreeAbelianGroup α →+ ℤ := lift fun z ↦ if x = z then (1 : ℤ) else 0 - have hfx1 : f (of x) = 1 := (lift_apply_of _ _).trans <| if_pos rfl + have hfx1 : f (of x) = 1 := (lift_apply_of _ _).trans <| ite_eq_left rfl have hfy1 : f (of y) = 1 := hoxy ▸ hfx1 - have hfy0 : f (of y) = 0 := (lift_apply_of _ _).trans <| if_neg hxy + have hfy0 : f (of y) = 0 := (lift_apply_of _ _).trans <| ite_eq_right hxy one_ne_zero <| hfy1.symm.trans hfy0 @[simp] diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 75e90313f82451..38f65ac2a6daae 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -946,6 +946,7 @@ def freeGroupUnitEquivInt : FreeGroup Unit ≃ ℤ where exact List.recOn L rfl (fun ⟨⟨⟩, b⟩ tl ih => by + simp only [Bool.cond_eq_ite] at ih cases b <;> simp [zpow_add, ih] <;> rfl) right_inv x := Int.induction_on x (by simp) diff --git a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean index 039cca2fef9fc9..dc49c8329fabe3 100644 --- a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean +++ b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean @@ -241,7 +241,7 @@ lemma endIsFree : IsFreeGroup (End (root' T)) := · suffices ∀ {x y} (q : x ⟶ y), F'.map (loopOfHom T q) = (F'.map q : X) by rintro ⟨⟨a, b, e⟩, h⟩ simp only [Functor.mapEnd, DFunLike.coe, this, hF'] - exact dif_neg h + exact dite_eq_right h intro x y q suffices ∀ {a} (p : Path (root T) a), F'.map (homOfPath T p) = 1 by simp only [this, treeHom, comp_as_mul, inv_as_inv, loopOfHom, inv_one, mul_one, @@ -253,9 +253,9 @@ lemma endIsFree : IsFreeGroup (End (root' T)) := rw [homOfPath, F'.map_comp, comp_as_mul, ih, mul_one] rcases e with ⟨e | e, eT⟩ · rw [hF'] - exact dif_pos (Or.inl eT) + exact dite_eq_left (Or.inl eT) · rw [F'.map_inv, inv_as_inv, inv_eq_one, hF'] - exact dif_pos (Or.inr eT) + exact dite_eq_left (Or.inr eT) · intro E hE ext x suffices (functorOfMonoidHom T E).map x = F'.map x by diff --git a/Mathlib/GroupTheory/HNNExtension.lean b/Mathlib/GroupTheory/HNNExtension.lean index ae63f573fbae73..b919dee698990d 100644 --- a/Mathlib/GroupTheory/HNNExtension.lean +++ b/Mathlib/GroupTheory/HNNExtension.lean @@ -417,7 +417,7 @@ theorem unitsSMul_cancels_iff (u : ℤˣ) (w : NormalWord d) : cases h.2 simpa [Cancels, unitsSMulWithCancel, Subgroup.mul_mem_cancel_left] using hc - · simp only [unitsSMul, dif_neg h] + · simp only [unitsSMul, dite_eq_right h] simpa [Cancels] using h theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) : @@ -427,12 +427,12 @@ theorem unitsSMul_neg (u : ℤˣ) (w : NormalWord d) : · set_option backward.isDefEq.respectTransparency false in have hncan : ¬ Cancels u w := (unitsSMul_cancels_iff _ _ _).1 hcan unfold unitsSMul - simp only [dif_neg hncan] + simp only [dite_eq_right hncan] simp [unitsSMulWithCancel, unitsSMulGroup, (d.compl u).equiv_snd_eq_inv_mul, -SetLike.coe_sort_coe] · have hcan2 : Cancels u w := not_not.1 (mt (unitsSMul_cancels_iff _ _ _).2 hcan) unfold unitsSMul at hcan ⊢ - simp only [dif_pos hcan2] at hcan ⊢ + simp only [dite_eq_left hcan2] at hcan ⊢ cases w using consRecOn with | ofGroup => simp [Cancels] at hcan2 | cons g u' w h1 h2 ih => @@ -462,13 +462,13 @@ theorem unitsSMul_one_group_smul (g : A) (w : NormalWord d) : simp [Cancels, Subgroup.mul_mem_cancel_left] by_cases hcan : Cancels 1 w · simp only [unitsSMulWithCancel, toSubgroup_one, id_eq, toSubgroup_neg_one, toSubgroupEquiv_one, - group_smul_head, mul_inv_rev, dif_pos (this.2 hcan), dif_pos hcan] + group_smul_head, mul_inv_rev, dite_eq_left (this.2 hcan), dite_eq_left hcan] cases w using consRecOn · simp [Cancels] at hcan · simp only [smul_cons, consRecOn_cons] rw [← mul_smul, ← Subgroup.coe_mul, ← map_mul φ] rfl - · rw [dif_neg (mt this.1 hcan), dif_neg hcan] + · rw [dite_eq_right (mt this.1 hcan), dite_eq_right hcan] -- Before https://github.com/leanprover/lean4/pull/2644, all this was just -- `simp [← mul_smul, mul_assoc, unitsSMulGroup]` simp +instances only [toSubgroup_neg_one, unitsSMulGroup, toSubgroup_one, toSubgroupEquiv_one, @@ -571,7 +571,7 @@ theorem prod_smul_empty (w : NormalWord d) : | cons g u w h1 h2 ih => rw [prod_cons, ← mul_assoc, mul_smul, ih, mul_smul, t_pow_smul_eq_unitsSMul, of_smul_eq_smul, unitsSMul] - rw [dif_neg (not_cancels_of_cons_hyp u w h2)] + rw [dite_eq_right (not_cancels_of_cons_hyp u w h2)] -- Before https://github.com/leanprover/lean4/pull/2644, this was just -- simp [unitsSMulGroup, (d.compl _).equiv_fst_eq_one_of_mem_of_one_mem (one_mem _) h1, -- -SetLike.coe_sort_coe] @@ -657,7 +657,8 @@ theorem exists_normalWord_prod_eq (List.head?_eq_some_head _) hS rwa [List.head?_eq_some_head hl, Option.map_some, ← this, Option.some_inj] at hx' simp at this - simp [mul_smul, of_smul_eq_smul, t_pow_smul_eq_unitsSMul, unitsSMul, dif_neg this, ← hw'2] + simp [mul_smul, of_smul_eq_smul, t_pow_smul_eq_unitsSMul, unitsSMul, dite_eq_right this, + ← hw'2] /-- Two reduced words representing the same element of the `HNNExtension G A B φ` have the same length corresponding list, with the same pattern of occurrences of `t^1` and `t^(-1)`, diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 4d177f2e6036a3..20275730587a41 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -531,7 +531,7 @@ noncomputable def Group.nilpotencyClass : ℕ := @[to_additive] theorem Group.nilpotencyClass_of_not_nilpotent (hG : ¬ IsNilpotent G) : Group.nilpotencyClass G = 0 := - dif_neg hG + dite_eq_right hG variable [hG : IsNilpotent G] @@ -539,7 +539,7 @@ open scoped Classical in @[to_additive] theorem Group.nilpotencyClass_def : Group.nilpotencyClass G = Nat.find (IsNilpotent.nilpotent G) := - dif_pos hG + dite_eq_left hG namespace Subgroup diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index 7cd8b8787e1b1c..d813d174282025 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -203,7 +203,7 @@ theorem pow_orderOf_eq_one (x : G) : x ^ orderOf x = 1 := by @[to_additive] theorem orderOf_eq_zero (h : ¬IsOfFinOrder x) : orderOf x = 0 := by - rwa [orderOf, minimalPeriod, dif_neg] + rwa [orderOf, minimalPeriod, dite_eq_right] @[to_additive (attr := simp)] theorem orderOf_eq_zero_iff : orderOf x = 0 ↔ ¬IsOfFinOrder x := diff --git a/Mathlib/GroupTheory/Perm/Centralizer.lean b/Mathlib/GroupTheory/Perm/Centralizer.lean index 057b16dd8940e6..8d726226224775 100644 --- a/Mathlib/GroupTheory/Perm/Centralizer.lean +++ b/Mathlib/GroupTheory/Perm/Centralizer.lean @@ -281,13 +281,13 @@ theorem ofPermHomFun_apply_of_cycleOf_mem {x : α} {c : g.cycleFactorsFinset} rw [← IsCycleOn.zpow_apply_eq_zpow_apply (isCycleOn_support_of_mem_cycleFactorsFinset c.prop) (mem_support_self a c)] rw [hn, hm] - simp only [ofPermHomFun, dif_pos hx''] + simp only [ofPermHomFun, dite_eq_left hx''] congr exact hx'.symm theorem ofPermHomFun_apply_of_mem_fixedPoints {x : α} (hx : x ∈ Function.fixedPoints g) : ofPermHomFun a τ x = x := by - rw [ofPermHomFun, dif_neg] + rw [ofPermHomFun, dite_eq_right] rw [cycleOf_mem_cycleFactorsFinset_iff, notMem_support] exact hx @@ -704,7 +704,7 @@ theorem card_of_cycleType (m : Multiset ℕ) : apply Nat.div_eq_of_eq_mul_left · have : 0 < m.prod := Multiset.prod_pos <| fun a ha => zero_lt_two.trans_le (hm.2 a ha) positivity - rw [card_of_cycleType_mul_eq, if_pos hm] + rw [card_of_cycleType_mul_eq, ite_eq_left hm] · -- empty case exact (card_of_cycleType_eq_zero_iff α).mpr hm @@ -717,7 +717,7 @@ lemma card_of_cycleType_singleton {n : ℕ} (hn' : 2 ≤ n) (hα : n ≤ card α have aux : n ! = (n - 1)! * n := by rw [mul_comm, mul_factorial_pred hn₀] rw [mul_comm, ← Nat.mul_left_inj hn₀, mul_assoc, ← aux, ← Nat.mul_left_inj (factorial_ne_zero _), Nat.choose_mul_factorial_mul_factorial hα, mul_assoc] - simpa [ite_and, if_pos hα, if_pos hn', mul_comm _ n, mul_assoc] + simpa [ite_and, ite_eq_left hα, ite_eq_left hn', mul_comm _ n, mul_assoc] using card_of_cycleType_mul_eq α {n} end Equiv.Perm diff --git a/Mathlib/GroupTheory/Perm/ClosureSwap.lean b/Mathlib/GroupTheory/Perm/ClosureSwap.lean index 333bcdfe2e2baa..3c12752cb70b63 100644 --- a/Mathlib/GroupTheory/Perm/ClosureSwap.lean +++ b/Mathlib/GroupTheory/Perm/ClosureSwap.lean @@ -58,9 +58,10 @@ theorem exists_smul_notMem_of_subset_orbit_closure (S : Set G) (T : Set α) {a : variable [DecidableEq α] -theorem finite_compl_fixedBy_swap {x y : α} : (fixedBy α (swap x y))ᶜ.Finite := +theorem finite_compl_fixedBy_swap {x y : α} : (fixedBy α (Equiv.swap x y))ᶜ.Finite := Set.Finite.subset (s := {x, y}) (by simp) - (compl_subset_comm.mp fun z h ↦ by apply swap_apply_of_ne_of_ne <;> rintro rfl <;> simp at h) + (compl_subset_comm.mp fun z h ↦ by + apply Equiv.swap_apply_of_ne_of_ne <;> rintro rfl <;> simp at h) theorem Equiv.Perm.IsSwap.finite_compl_fixedBy {σ : Perm α} (h : σ.IsSwap) : (fixedBy α σ)ᶜ.Finite := by @@ -69,8 +70,8 @@ theorem Equiv.Perm.IsSwap.finite_compl_fixedBy {σ : Perm α} (h : σ.IsSwap) : -- this result cannot be moved to Perm/Basic since Perm/Basic is not allowed to import Submonoid theorem SubmonoidClass.swap_mem_trans {a b c : α} {C} [SetLike C (Perm α)] - [SubmonoidClass C (Perm α)] (M : C) (hab : swap a b ∈ M) (hbc : swap b c ∈ M) : - swap a c ∈ M := by + [SubmonoidClass C (Perm α)] (M : C) (hab : Equiv.swap a b ∈ M) + (hbc : Equiv.swap b c ∈ M) : Equiv.swap a c ∈ M := by obtain rfl | hab' := eq_or_ne a b · exact hbc obtain rfl | hac := eq_or_ne a c @@ -81,15 +82,15 @@ theorem SubmonoidClass.swap_mem_trans {a b c : α} {C} [SetLike C (Perm α)] /-- If a subgroup is generated by transpositions, then a transposition `swap x y` lies in the subgroup if and only if `x` lies in the same orbit as `y`. -/ theorem swap_mem_closure_isSwap {S : Set (Perm α)} (hS : ∀ f ∈ S, f.IsSwap) {x y : α} : - swap x y ∈ closure S ↔ x ∈ orbit (closure S) y := by - refine ⟨fun h ↦ ⟨⟨swap x y, h⟩, swap_apply_right x y⟩, fun hf ↦ ?_⟩ + Equiv.swap x y ∈ closure S ↔ x ∈ orbit (closure S) y := by + refine ⟨fun h ↦ ⟨⟨Equiv.swap x y, h⟩, Equiv.swap_apply_right x y⟩, fun hf ↦ ?_⟩ by_contra h - have := exists_smul_notMem_of_subset_orbit_closure S {x | swap x y ∈ closure S} + have := exists_smul_notMem_of_subset_orbit_closure S {x | Equiv.swap x y ∈ closure S} (fun f hf ↦ ?_) (fun z hz ↦ ?_) h ⟨y, ?_⟩ · obtain ⟨σ, hσ, a, ha, hσa⟩ := this obtain ⟨z, w, hzw, rfl⟩ := hS σ hσ have := ne_of_mem_of_not_mem ha hσa - rw [Perm.smul_def, ne_comm, swap_apply_ne_self_iff, and_iff_right hzw] at this + rw [Perm.smul_def, ne_comm, Equiv.swap_apply_ne_self_iff, and_iff_right hzw] at this refine hσa (SubmonoidClass.swap_mem_trans (closure S) ?_ ha) obtain rfl | rfl := this <;> simpa [Equiv.swap_comm] using subset_closure hσ · obtain ⟨x, y, -, rfl⟩ := hS f hf; rwa [swap_inv] @@ -126,7 +127,7 @@ theorem mem_closure_isSwap {S : Set (Perm α)} (hS : ∀ f ∈ S, f.IsSwap) {f : theorem mem_closure_isSwap' {f : Perm α} : f ∈ closure {σ : Perm α | σ.IsSwap} ↔ (fixedBy α f)ᶜ.Finite := by refine (mem_closure_isSwap fun _ ↦ id).trans - (and_iff_left fun x ↦ ⟨⟨swap x (f x), ?_⟩, swap_apply_left x (f x)⟩) + (and_iff_left fun x ↦ ⟨⟨Equiv.swap x (f x), ?_⟩, Equiv.swap_apply_left x (f x)⟩) by_cases h : x = f x · rw [← h, Equiv.swap_self] apply Subgroup.one_mem diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index 9a1de233ef70da..2738243f4f8957 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -425,7 +425,7 @@ theorem IsCycle.eq_swap_of_apply_apply_eq_self {α : Type*} [DecidableEq α] {f theorem IsCycle.swap_mul {α : Type*} [DecidableEq α] {f : Perm α} (hf : IsCycle f) {x : α} (hx : f x ≠ x) (hffx : f (f x) ≠ x) : IsCycle (swap x (f x) * f) := by refine ⟨f x, ?_, fun y hy ↦ ?_⟩ - · simp [swap_apply_def, mul_apply, if_neg hffx, f.injective.eq_iff, hx] + · simp [swap_apply_def, mul_apply, ite_eq_right hffx, f.injective.eq_iff, hx] obtain ⟨i, rfl⟩ := hf.exists_zpow_eq hx (ne_and_ne_of_swap_mul_apply_ne_self hy).1 exact isCycle_swap_mul_aux₂ (i - 1) hy (by simp [← mul_apply, -coe_mul, ← zpow_add_one]) diff --git a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean index b287f6a5a5067e..b6b8d134fb3a40 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Factors.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Factors.lean @@ -63,7 +63,7 @@ theorem cycleOf_pow_apply_self (f : Perm α) [DecidableRel f.SameCycle] (x : α) induction n with | zero => rfl | succ n hn => - rw [pow_succ', mul_apply, cycleOf_apply, hn, if_pos, pow_succ', mul_apply] + rw [pow_succ', mul_apply, cycleOf_apply, hn, ite_eq_left, pow_succ', mul_apply] exact ⟨n, rfl⟩ @[simp] @@ -123,10 +123,10 @@ theorem IsCycle.cycleOf_eq [DecidableRel f.SameCycle] @[simp] theorem cycleOf_eq_one_iff (f : Perm α) [DecidableRel f.SameCycle] : cycleOf f x = 1 ↔ f x = x := by simp_rw [Perm.ext_iff, cycleOf_apply, one_apply] - refine ⟨fun h => (if_pos (SameCycle.refl f x)).symm.trans (h x), fun h y => ?_⟩ + refine ⟨fun h => (ite_eq_left (SameCycle.refl f x)).symm.trans (h x), fun h y => ?_⟩ by_cases hy : f y = y · rw [hy, ite_self] - · exact if_neg (mt SameCycle.apply_eq_self_iff (by tauto)) + · exact ite_eq_right (mt SameCycle.apply_eq_self_iff (by tauto)) @[simp] theorem cycleOf_self_apply (f : Perm α) [DecidableRel f.SameCycle] (x : α) : @@ -146,8 +146,8 @@ theorem cycleOf_self_apply_zpow (f : Perm α) [DecidableRel f.SameCycle] (n : protected theorem IsCycle.cycleOf [DecidableRel f.SameCycle] [DecidableEq α] (hf : IsCycle f) : cycleOf f x = if f x = x then 1 else f := by by_cases hx : f x = x - · rwa [if_pos hx, cycleOf_eq_one_iff] - · rwa [if_neg hx, hf.cycleOf_eq] + · rwa [ite_eq_left hx, cycleOf_eq_one_iff] + · rwa [ite_eq_right hx, hf.cycleOf_eq] theorem cycleOf_one [DecidableRel (1 : Perm α).SameCycle] (x : α) : cycleOf 1 x = 1 := (cycleOf_eq_one_iff 1).mpr rfl diff --git a/Mathlib/GroupTheory/Perm/Cycle/Type.lean b/Mathlib/GroupTheory/Perm/Cycle/Type.lean index 9dfc4debbd6acc..d9ae9435c9a66b 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Type.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Type.lean @@ -347,16 +347,16 @@ theorem sign_of_cycleType_eq_replicate {σ : Perm α} {n : ℕ} (hn : 0 < n) (-1) ^ ((Fintype.card α - Fintype.card (Function.fixedPoints σ)) / n) := by rw [sign_of_cycleType', hσ, Multiset.map_replicate, Multiset.prod_replicate] obtain h | h := Nat.even_or_odd n - · rw [if_neg (Nat.not_odd_iff_even.mpr h), h.neg_one_pow, σ.card_fixedPoints, + · rw [ite_eq_right (Nat.not_odd_iff_even.mpr h), h.neg_one_pow, σ.card_fixedPoints, Nat.sub_sub_self σ.sum_cycleType_le, show σ.cycleType.sum = σ.cycleType.card * n by rw [hσ]; simp, Nat.mul_div_cancel _ hn] - · rw [if_pos h, h.neg_one_pow, neg_neg, one_pow] + · rw [ite_eq_left h, h.neg_one_pow, neg_neg, one_pow] theorem sign_of_pow_two_eq_one {σ : Perm α} (hσ : σ ^ 2 = 1) : sign σ = (-1) ^ ((Fintype.card α - Fintype.card (Function.fixedPoints σ)) / 2) := by rw [sign_of_cycleType_eq_replicate zero_lt_two (cycleType_of_pow_prime_eq_one hσ), - if_neg (Nat.not_odd_iff.mpr rfl)] + ite_eq_right (Nat.not_odd_iff.mpr rfl)] end CycleType @@ -707,8 +707,8 @@ theorem IsThreeCycle.support_eq_iff_mem_support simpa only [Finset.singleton_subset_iff, Perm.apply_mem_support] · rw [hg3.card_support] simp only [mem_support, ne_eq] at ha - rw [Finset.card_insert_eq_ite, if_neg] - · rw [Finset.card_insert_eq_ite, if_neg] + rw [Finset.card_insert_eq_ite, ite_eq_right] + · rw [Finset.card_insert_eq_ite, ite_eq_right] · simp · simpa using Ne.symm ha · simp only [Finset.mem_insert, Finset.mem_singleton] diff --git a/Mathlib/GroupTheory/Perm/Fin.lean b/Mathlib/GroupTheory/Perm/Fin.lean index e2582a29d62569..3b050d1d0c3e8f 100644 --- a/Mathlib/GroupTheory/Perm/Fin.lean +++ b/Mathlib/GroupTheory/Perm/Fin.lean @@ -88,7 +88,7 @@ theorem finRotate_succ_eq_decomposeFin {n : ℕ} : split_ifs with h · simp [h] · rw [Fin.val_succ, Function.Injective.map_swap Fin.val_injective, Fin.val_succ, coe_finRotate, - if_neg h, Fin.val_zero, Fin.val_one, + ite_eq_right h, Fin.val_zero, Fin.val_one, swap_apply_of_ne_of_ne (Nat.succ_ne_zero _) (Nat.succ_succ_ne_one _)] @[simp] @@ -182,13 +182,13 @@ theorem coe_cycleRange_of_le (h : i ≤ j) : _ ≤ n := Nat.lt_succ_iff.mp j.2) theorem cycleRange_of_lt [NeZero n] (h : i < j) : cycleRange j i = i + 1 := by - rw [cycleRange_of_le h.le, if_neg h.ne] + rw [cycleRange_of_le h.le, ite_eq_right h.ne] theorem coe_cycleRange_of_lt (h : i < j) : (cycleRange j i : ℕ) = i + 1 := by - rw [coe_cycleRange_of_le h.le, if_neg h.ne] + rw [coe_cycleRange_of_le h.le, ite_eq_right h.ne] theorem cycleRange_of_eq [NeZero n] (h : i = j) : cycleRange j i = 0 := by - rw [cycleRange_of_le h.le, if_pos h] + rw [cycleRange_of_le h.le, ite_eq_left h] @[simp] theorem cycleRange_self [NeZero n] (i : Fin n) : cycleRange i i = 0 := diff --git a/Mathlib/GroupTheory/Perm/Sign.lean b/Mathlib/GroupTheory/Perm/Sign.lean index 59fb103146af17..f321759b2ad68e 100644 --- a/Mathlib/GroupTheory/Perm/Sign.lean +++ b/Mathlib/GroupTheory/Perm/Sign.lean @@ -179,7 +179,7 @@ def signAux {n : ℕ} (a : Perm (Fin n)) : ℤˣ := theorem signAux_one (n : ℕ) : signAux (1 : Perm (Fin n)) = 1 := by unfold signAux conv => rhs; rw [← @Finset.prod_const_one _ _ (finPairsLT n)] - exact Finset.prod_congr rfl fun a ha => if_neg (mem_finPairsLT.1 ha).not_ge + exact Finset.prod_congr rfl fun a ha => ite_eq_right (mem_finPairsLT.1 ha).not_ge /-- `signBijAux f ⟨a, b⟩` returns the pair consisting of `f a` and `f b` in decreasing order. -/ def signBijAux {n : ℕ} (f : Perm (Fin n)) (a : Σ _ : Fin n, Fin n) : Σ _ : Fin n, Fin n := @@ -201,13 +201,13 @@ theorem signBijAux_surj {n : ℕ} {f : Perm (Fin n)} : fun ⟨a₁, a₂⟩ ha => if hxa : f.symm a₂ < f.symm a₁ then ⟨⟨f.symm a₁, f.symm a₂⟩, mem_finPairsLT.2 hxa, by - simp [signBijAux, if_pos (mem_finPairsLT.1 ha)]⟩ + simp [signBijAux, ite_eq_left (mem_finPairsLT.1 ha)]⟩ else ⟨⟨f.symm a₂, f.symm a₁⟩, mem_finPairsLT.2 <| (le_of_not_gt hxa).lt_of_ne fun h => by simp [mem_finPairsLT, f⁻¹.injective h] at ha, by - simp [signBijAux, if_neg (mem_finPairsLT.1 ha).le.not_gt]⟩ + simp [signBijAux, ite_eq_right (mem_finPairsLT.1 ha).le.not_gt]⟩ theorem signBijAux_mem {n : ℕ} {f : Perm (Fin n)} : ∀ a : Σ _ : Fin n, Fin n, a ∈ finPairsLT n → signBijAux f a ∈ finPairsLT n := @@ -223,7 +223,7 @@ theorem signAux_inv {n : ℕ} (f : Perm (Fin n)) : signAux f⁻¹ = signAux f := prod_nbij (signBijAux f⁻¹) signBijAux_mem signBijAux_injOn signBijAux_surj fun ⟨a, b⟩ hab ↦ by by_cases h : f.symm b < f.symm a · simp_all [signBijAux, (mem_finPairsLT.1 hab).not_ge] - · simp_all [signBijAux, dif_neg h, (mem_finPairsLT.1 hab).le] + · simp_all [signBijAux, dite_eq_right h, (mem_finPairsLT.1 hab).le] theorem signAux_mul {n : ℕ} (f g : Perm (Fin n)) : signAux (f * g) = signAux f * signAux g := by rw [← signAux_inv g] @@ -253,14 +253,14 @@ private theorem signAux_swap_zero_one' (n : ℕ) : signAux (swap (0 : Fin (n + 2 · simp only [and_true, heq_iff_eq, mem_singleton, Sigma.mk.inj_iff] at ha₂ have : 1 < a₁ := lt_of_le_of_ne' (Nat.succ_le_of_lt ha₁) ha₂ have h01 : Equiv.swap (0 : Fin (n + 2)) 1 0 = 1 := by simp - rw [swap_apply_of_ne_of_ne (ne_of_gt H) ha₂, h01, if_neg this.not_ge] + rw [swap_apply_of_ne_of_ne (ne_of_gt H) ha₂, h01, ite_eq_right this.not_ge] · have le : 1 ≤ a₂ := Nat.succ_le_of_lt H' have lt : 1 < a₁ := le.trans_lt ha₁ have h01 : Equiv.swap (0 : Fin (n + 2)) 1 1 = 0 := by simp only [swap_apply_right] rcases le.eq_or_lt with (rfl | lt') - · rw [swap_apply_of_ne_of_ne H.ne' lt.ne', h01, if_neg H.not_ge] + · rw [swap_apply_of_ne_of_ne H.ne' lt.ne', h01, ite_eq_right H.not_ge] · rw [swap_apply_of_ne_of_ne (ne_of_gt H) (ne_of_gt lt), - swap_apply_of_ne_of_ne (ne_of_gt H') (ne_of_gt lt'), if_neg ha₁.not_ge] + swap_apply_of_ne_of_ne (ne_of_gt H') (ne_of_gt lt'), ite_eq_right ha₁.not_ge] private theorem signAux_swap_zero_one {n : ℕ} (hn : 2 ≤ n) : signAux (swap (⟨0, lt_of_lt_of_le (by decide) hn⟩ : Fin n) ⟨1, lt_of_lt_of_le (by decide) hn⟩) = @@ -298,7 +298,7 @@ theorem signAux_eq_signAux2 {n : ℕ} : | x::l, f, e, h => by rw [signAux2] by_cases hfx : x = f x - · rw [if_pos hfx] + · rw [ite_eq_left hfx] exact signAux_eq_signAux2 l f _ fun y (hy : f y ≠ y) => List.mem_of_ne_of_mem (fun h : y = x => by simp [h, hfx.symm] at hy) (h y hy) @@ -313,7 +313,7 @@ theorem signAux_eq_signAux2 {n : ℕ} : simp [swap, swapCore] split_ifs <;> rfl have hefx : e x ≠ e (f x) := mt e.injective.eq_iff.1 hfx - rw [if_neg hfx, ← signAux_eq_signAux2 _ _ e hy, this, signAux_mul, signAux_swap hefx] + rw [ite_eq_right hfx, ← signAux_eq_signAux2 _ _ e hy, this, signAux_mul, signAux_swap hefx] simp only [neg_neg, one_mul, neg_mul] /-- When the multiset `s : Multiset α` contains all nonfixed points of the permutation `f : Perm α`, diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean index 671e2bf4d34ddc..f1674f616e27cc 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating/Centralizer.lean @@ -107,13 +107,13 @@ theorem card_of_cycleType (m : Multiset ℕ) : else 0 := by split_ifs with hm · -- m is an even cycle_type - rw [← Finset.card_map, map_subtype_of_cycleType, if_pos hm.2, - Equiv.Perm.card_of_cycleType α m, if_pos hm.1, mul_assoc] + rw [← Finset.card_map, map_subtype_of_cycleType, ite_eq_left hm.2, + Equiv.Perm.card_of_cycleType α m, ite_eq_left hm.1, mul_assoc] · -- m does not correspond to a permutation, or to an odd one, rw [← Finset.card_map, map_subtype_of_cycleType] rw [apply_ite Finset.card, Finset.card_empty] split_ifs with hm' - · rw [Equiv.Perm.card_of_cycleType, if_neg] + · rw [Equiv.Perm.card_of_cycleType, ite_eq_right] obtain hm | hm := not_and_or.mp hm · exact hm · contradiction diff --git a/Mathlib/GroupTheory/Transfer.lean b/Mathlib/GroupTheory/Transfer.lean index ff5a8110579785..0d7a32e035651b 100644 --- a/Mathlib/GroupTheory/Transfer.lean +++ b/Mathlib/GroupTheory/Transfer.lean @@ -132,8 +132,8 @@ lemma transferTransversal_apply'' (q : orbitRel.Quotient (zpowers g) (G ⧸ H)) ← zpow_one_add, Int.cast_add, Int.cast_neg, Int.cast_one, intCast_cast, cast_id', id, ← sub_eq_neg_add, cast_sub_one, add_sub_cancel] by_cases hk : k = 0 - · rw [if_pos hk, if_pos hk, zpow_natCast] - · rw [if_neg hk, if_neg hk] + · rw [ite_eq_left hk, ite_eq_left hk, zpow_natCast] + · rw [ite_eq_right hk, ite_eq_right hk] end Subgroup @@ -175,9 +175,9 @@ theorem transfer_eq_prod_quotient_orbitRel_zpowers_quot [FiniteIndex H] (g : G) simp only [quotientEquivSigmaZMod_symm_apply, transferTransversal_apply', transferTransversal_apply''] rw [Fintype.prod_eq_single (0 : ZMod (Function.minimalPeriod (g • ·) q.out)) _] - · simp only [if_pos, ZMod.cast_zero, zpow_zero, one_mul, mul_assoc] + · simp only [ite_eq_left, ZMod.cast_zero, zpow_zero, one_mul, mul_assoc] · intro k hk - simp only [if_neg hk, inv_mul_cancel] + simp only [ite_eq_right hk, inv_mul_cancel] exact map_one ϕ open scoped IsMulCommutative in diff --git a/Mathlib/InformationTheory/KullbackLeibler/Basic.lean b/Mathlib/InformationTheory/KullbackLeibler/Basic.lean index 8e7d7457a1bfb3..13554232dca143 100644 --- a/Mathlib/InformationTheory/KullbackLeibler/Basic.lean +++ b/Mathlib/InformationTheory/KullbackLeibler/Basic.lean @@ -62,22 +62,22 @@ noncomputable irreducible_def klDiv (μ ν : Measure α) : ℝ≥0∞ := lemma klDiv_of_ac_of_integrable (h1 : μ ≪ ν) (h2 : Integrable (llr μ ν) μ) : klDiv μ ν = ENNReal.ofReal (∫ x, llr μ ν x ∂μ + ν.real univ - μ.real univ) := by rw [klDiv_def] - exact if_pos ⟨h1, h2⟩ + exact ite_eq_left ⟨h1, h2⟩ @[simp] lemma klDiv_of_not_ac (h : ¬ μ ≪ ν) : klDiv μ ν = ∞ := by rw [klDiv_def] - exact if_neg (not_and_of_not_left _ h) + exact ite_eq_right (not_and_of_not_left _ h) @[simp] lemma klDiv_of_not_integrable (h : ¬ Integrable (llr μ ν) μ) : klDiv μ ν = ∞ := by rw [klDiv_def] - exact if_neg (not_and_of_not_right _ h) + exact ite_eq_right (not_and_of_not_right _ h) @[simp] lemma klDiv_self (μ : Measure α) [SigmaFinite μ] : klDiv μ μ = 0 := by have h := llr_self μ - rw [klDiv_def, if_pos] + rw [klDiv_def, ite_eq_left] · simp [integral_congr_ae h] · rw [integrable_congr h] exact ⟨Measure.AbsolutelyContinuous.rfl, integrable_zero _ _ μ⟩ @@ -170,7 +170,7 @@ lemma toReal_klDiv_of_measure_eq (h : μ ≪ ν) (h_eq : μ univ = ν univ) : lemma toReal_klDiv_eq_integral_klFun (h : μ ≪ ν) : (klDiv μ ν).toReal = ∫ x, klFun (μ.rnDeriv ν x).toReal ∂ν := by by_cases h_int : Integrable (llr μ ν) μ - · rw [klDiv_eq_integral_klFun, if_pos ⟨h, h_int⟩, ENNReal.toReal_ofReal] + · rw [klDiv_eq_integral_klFun, ite_eq_left ⟨h, h_int⟩, ENNReal.toReal_ofReal] exact integral_nonneg fun _ ↦ klFun_nonneg ENNReal.toReal_nonneg · rw [integral_undef] · rw [klDiv_of_not_integrable h_int, ENNReal.toReal_top] @@ -379,7 +379,7 @@ lemma klDiv_eq_zero_iff [IsFiniteMeasure μ] [IsFiniteMeasure ν] : refine ⟨fun h ↦ ?_, fun h ↦ h ▸ klDiv_self _⟩ have h_ne : klDiv μ ν ≠ ⊤ := by simp [h] rw [klDiv_ne_top_iff] at h_ne - rw [klDiv_eq_lintegral_klFun, if_pos h_ne.1, lintegral_eq_zero_iff (by fun_prop)] at h + rw [klDiv_eq_lintegral_klFun, ite_eq_left h_ne.1, lintegral_eq_zero_iff (by fun_prop)] at h refine (Measure.rnDeriv_eq_one_iff_eq h_ne.1).mp ?_ filter_upwards [h] with x hx simp only [Pi.zero_apply, ENNReal.ofReal_eq_zero] at hx diff --git a/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean b/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean index 31a9e198b2b17e..cb3891071c6282 100644 --- a/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean +++ b/Mathlib/InformationTheory/KullbackLeibler/DataProcessing.lean @@ -145,7 +145,7 @@ lemma toReal_klDiv_map_of_ac (hμν : μ ≪ ν) (hg : Measurable g) : lemma klDiv_map_of_ac (hμν : μ ≪ ν) (hg : Measurable g) (h_int : Integrable (llr μ ν) μ) : klDiv (μ.map g) (ν.map g) = ENNReal.ofReal (∫ x, klFun ((ν[fun x ↦ (μ.rnDeriv ν x).toReal | m𝓨.comap g]) x) ∂ν) := by - rw [klDiv_eq_integral_klFun, if_pos ⟨hμν.map hg, integrable_llr_map hμν hg h_int⟩] + rw [klDiv_eq_integral_klFun, ite_eq_left ⟨hμν.map hg, integrable_llr_map hμν hg h_int⟩] congr rw [← toReal_klDiv_eq_integral_klFun (hμν.map hg), toReal_klDiv_map_of_ac hμν hg] diff --git a/Mathlib/LinearAlgebra/AffineSpace/Basis.lean b/Mathlib/LinearAlgebra/AffineSpace/Basis.lean index 8e2f81e7905bd2..b9a62dddef88a6 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Basis.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Basis.lean @@ -202,14 +202,14 @@ theorem coord_apply [DecidableEq ι] (i j : ι) : b.coord i (b j) = if i = j the @[simp] theorem coord_apply_combination_of_mem (hi : i ∈ s) {w : ι → k} (hw : s.sum w = 1) : b.coord i (s.affineCombination k b w) = w i := by - classical simp only [coord_apply, hi, Finset.affineCombination_eq_linear_combination, if_true, + classical simp only [coord_apply, hi, Finset.affineCombination_eq_linear_combination, ite_true, mul_boole, hw, Function.comp_apply, smul_eq_mul, s.sum_ite_eq, s.map_affineCombination b w hw] @[simp] theorem coord_apply_combination_of_notMem (hi : i ∉ s) {w : ι → k} (hw : s.sum w = 1) : b.coord i (s.affineCombination k b w) = 0 := by - classical simp only [coord_apply, hi, Finset.affineCombination_eq_linear_combination, if_false, + classical simp only [coord_apply, hi, Finset.affineCombination_eq_linear_combination, ite_false, mul_boole, hw, Function.comp_apply, smul_eq_mul, s.sum_ite_eq, s.map_affineCombination b w hw] diff --git a/Mathlib/LinearAlgebra/AffineSpace/Combination.lean b/Mathlib/LinearAlgebra/AffineSpace/Combination.lean index dc9f0822ea2f1c..c35688997d8952 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Combination.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Combination.lean @@ -621,7 +621,7 @@ theorem affineCombinationSingleWeights_apply_of_ne [DecidableEq ι] {i j : ι} ( @[deprecated Finset.sum_pi_single' (since := "2026-04-16")] theorem sum_affineCombinationSingleWeights [DecidableEq ι] {i : ι} (h : i ∈ s) : ∑ j ∈ s, affineCombinationSingleWeights k i j = 1 := by - rw [affineCombinationSingleWeights, s.sum_pi_single', if_pos h] + rw [affineCombinationSingleWeights, s.sum_pi_single', ite_eq_left h] /-- Weights for expressing the subtraction of two points as a `weightedVSub`. -/ def weightedVSubVSubWeights [DecidableEq ι] (i j : ι) : ι → k := @@ -754,7 +754,7 @@ theorem weightedVSub_mem_vectorSpan {s : Finset ι} {w : ι → k} (h : ∑ i rw [Finsupp.linearCombination_apply, Finsupp.onFinset_sum hwx] · apply Finset.sum_congr rfl intro i hi - simp [w', Set.indicator_apply, if_pos hi] + simp [w', Set.indicator_apply, ite_eq_left hi] · exact fun _ => zero_smul k _ /-- An `affineCombination` with sum of weights 1 is in the diff --git a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean index 8c4107113eca8f..d51c3c690a2f99 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean @@ -108,7 +108,7 @@ theorem affineIndependent_iff_linearIndependent_vsub (p : ι → P) (i1 : ι) : Finset.sum_subtype_map_embedding fun x _ => (hfg x).symm] rw [hfdef] dsimp only - rw [dif_pos rfl] + rw [dite_eq_left rfl] exact neg_add_cancel _ have hs2 : s2.weightedVSub p f = (0 : V) := by set f2 : ι → V := fun x => f x • (p x -ᵥ p i1) with hf2def @@ -300,7 +300,7 @@ theorem AffineIndependent.comp_embedding {ι2 : Type*} (f : ι2 ↪ ι) {p : ι intro i2 have h : ∃ i : ι2, f i = f i2 := ⟨i2, rfl⟩ have hs : h.choose = i2 := f.injective h.choose_spec - simp_rw [w', dif_pos h, hs] + simp_rw [w', dite_eq_left h, hs] have hw's : ∑ i ∈ fs', w' i = 0 := by rw [← hw, Finset.sum_map] simp [hw'] @@ -827,7 +827,7 @@ theorem AffineIndependent.affineIndependent_of_notMem_span {p : ι → P} {i : have hw' : ∑ x ∈ s', w' x = 1 := by simp_rw [w', s', Finset.sum_subtype_eq_sum_filter] rw [← s.sum_filter_add_sum_filter_not (· ≠ i)] at hwm - simpa only [not_not, Finset.filter_eq' _ i, if_pos his.1, sum_singleton, hwmi, + simpa only [not_not, Finset.filter_eq' _ i, ite_eq_left his.1, sum_singleton, hwmi, add_neg_eq_zero] using hwm rw [← s.affineCombination_eq_of_weightedVSub_eq_zero_of_eq_neg_one hms his.1 hwmi, ← (Subtype.range_coe : _ = { x | x ≠ i }), ← Set.range_comp, ← @@ -944,7 +944,7 @@ theorem sign_eq_of_affineCombination_mem_affineSpan_single_lineMap {p : ι → P (s.sum_affineCombinationLineMapWeights h₂ h₃ c) hs h₂ h₃ (Pi.single_eq_of_ne h₁₂.symm _) (Pi.single_eq_of_ne h₁₃.symm _) ?_ - · rw [Finset.sum_pi_single', if_pos h₁] + · rw [Finset.sum_pi_single', ite_eq_left h₁] rw [Finset.affineCombinationLineMapWeights_apply_left h₂₃, Finset.affineCombinationLineMapWeights_apply_right h₂₃] simp_all only [sub_pos, sign_pos] diff --git a/Mathlib/LinearAlgebra/Basis/Basic.lean b/Mathlib/LinearAlgebra/Basis/Basic.lean index b0fa1439a882d2..146f6352a8408e 100644 --- a/Mathlib/LinearAlgebra/Basis/Basic.lean +++ b/Mathlib/LinearAlgebra/Basis/Basic.lean @@ -157,8 +157,8 @@ theorem mk_coord_apply_ne {i j : ι} (h : j ≠ i) : (Basis.mk hli hsp).coord i theorem mk_coord_apply [DecidableEq ι] {i j : ι} : (Basis.mk hli hsp).coord i (v j) = if j = i then 1 else 0 := by rcases eq_or_ne j i with h | h - · simp only [h, if_true, mk_coord_apply_eq i] - · simp only [h, if_false, mk_coord_apply_ne h] + · simp only [h, ite_true, mk_coord_apply_eq i] + · simp only [h, ite_false, mk_coord_apply_ne h] end Coord diff --git a/Mathlib/LinearAlgebra/Coevaluation.lean b/Mathlib/LinearAlgebra/Coevaluation.lean index 74520c923036af..dfe500776bf5ca 100644 --- a/Mathlib/LinearAlgebra/Coevaluation.lean +++ b/Mathlib/LinearAlgebra/Coevaluation.lean @@ -73,7 +73,7 @@ theorem contractLeft_assoc_coevaluation : rw [TensorProduct.tmul_sum, map_sum]; simp only [assoc_symm_tmul] rw [map_sum]; simp only [LinearMap.rTensor_tmul, contractLeft_apply] simp only [Basis.coe_dualBasis, Basis.coord_apply, Basis.repr_self_apply, TensorProduct.ite_tmul] - rw [Finset.sum_ite_eq']; simp only [Finset.mem_univ, if_true] + rw [Finset.sum_ite_eq']; simp only [Finset.mem_univ, ite_true] /-- This lemma corresponds to one of the coherence laws for duals in rigid categories, see `CategoryTheory.Monoidal.Rigid`. -/ @@ -91,6 +91,6 @@ theorem contractLeft_assoc_coevaluation' : rw [TensorProduct.sum_tmul, map_sum]; simp only [assoc_tmul] rw [map_sum]; simp only [LinearMap.lTensor_tmul, contractLeft_apply] simp only [Basis.coord_apply, Basis.repr_self_apply, TensorProduct.tmul_ite] - rw [Finset.sum_ite_eq]; simp only [Finset.mem_univ, if_true] + rw [Finset.sum_ite_eq]; simp only [Finset.mem_univ, ite_true] end coevaluation diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 8c3b6d97e0749b..c7a9c3852015db 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -206,7 +206,7 @@ end theorem det_eq_det_toMatrix_of_finset [DecidableEq M] {s : Finset M} (b : Basis s A M) (f : M →ₗ[A] M) : LinearMap.det f = Matrix.det (LinearMap.toMatrix b b f) := by have : ∃ s : Finset M, Nonempty (Basis s A M) := ⟨s, ⟨b⟩⟩ - rw [LinearMap.coe_det, dif_pos this, detAux_def'' _ b] + rw [LinearMap.coe_det, dite_eq_left this, detAux_def'' _ b] @[simp] theorem det_toMatrix (b : Basis ι A M) (f : M →ₗ[A] M) : @@ -239,7 +239,7 @@ theorem det_cases [DecidableEq M] {P : A → Prop} (f : M →ₗ[A] M) rw [← det_toMatrix b] exact hb s b else - rwa [LinearMap.det_def, dif_neg H] + rwa [LinearMap.det_def, dite_eq_right H] @[simp] theorem det_comp (f g : M →ₗ[A] M) : @@ -280,7 +280,7 @@ theorem det_zero [Module.Free A M] : simp only [← zero_smul A (1 : M →ₗ[A] M), det_smul, mul_one, map_one] theorem det_eq_one_of_not_module_finite (h : ¬Module.Finite R M) (f : M →ₗ[R] M) : f.det = 1 := by - rw [LinearMap.det, dif_neg, MonoidHom.one_apply] + rw [LinearMap.det, dite_eq_right, MonoidHom.one_apply] exact fun ⟨_, ⟨b⟩⟩ ↦ h (Module.Finite.of_basis b) @[nontriviality] @@ -318,7 +318,7 @@ theorem det_conj {N : Type*} [AddCommGroup N] [Module A N] (f : M →ₗ[A] M) ( contrapose H rcases H with ⟨s, ⟨b⟩⟩ exact ⟨_, ⟨(b.map e.symm).reindexFinsetRange⟩⟩ - simp only [coe_det, H, H', MonoidHom.one_apply, dif_neg, not_false_eq_true] + simp only [coe_det, H, H', MonoidHom.one_apply, dite_eq_right, not_false_eq_true] /-- If a linear map is invertible, so is its determinant. -/ theorem isUnit_det {A : Type*} [CommRing A] [Module A M] (f : M →ₗ[A] M) (hf : IsUnit f) : @@ -554,7 +554,7 @@ theorem LinearMap.equivOfIsUnitDet_apply {f : M →ₗ[R] M} (h : IsUnit f.det) (x : M) : (LinearMap.equivOfIsUnitDet h) x = f x := by nontriviality M - simp [equivOfIsUnitDet, dif_pos (Module.nontrivial R M)] + simp [equivOfIsUnitDet, dite_eq_left (Module.nontrivial R M)] @[simp] theorem LinearMap.coe_equivOfIsUnitDet diff --git a/Mathlib/LinearAlgebra/Dimension/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Finite.lean index 955efc96d75ad7..8238f924711d41 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finite.lean @@ -327,16 +327,16 @@ theorem Module.exists_nontrivial_relation_sum_zero_of_finrank_succ_lt_card -- After this, it's a matter of verifying the properties, -- based on the corresponding properties for `g`. · rw [sum_map, Embedding.coeFn_mk] at gsum - simp_rw [f, ← t.sum_erase_add _ x₀_mem, if_pos, neg_smul, sum_smul, + simp_rw [f, ← t.sum_erase_add _ x₀_mem, ite_eq_left, neg_smul, sum_smul, ← sub_eq_add_neg, ← sum_sub_distrib, ← gsum, smul_sub] refine sum_congr rfl fun x x_mem ↦ ?_ - rw [if_neg (mem_erase.mp x_mem).1] - · simp_rw [f, ← t.sum_erase_add _ x₀_mem, if_pos, add_neg_eq_zero] - exact sum_congr rfl fun x x_mem ↦ if_neg (mem_erase.mp x_mem).1 + rw [ite_eq_right (mem_erase.mp x_mem).1] + · simp_rw [f, ← t.sum_erase_add _ x₀_mem, ite_eq_left, add_neg_eq_zero] + exact sum_congr rfl fun x x_mem ↦ ite_eq_right (mem_erase.mp x_mem).1 · obtain ⟨x₁, x₁_mem', rfl⟩ := Finset.mem_map.mp x₁_mem have := mem_erase.mp x₁_mem' exact ⟨x₁, by - simpa only [f, Embedding.coeFn_mk, sub_add_cancel, this.2, true_and, if_neg this.1]⟩ + simpa only [f, Embedding.coeFn_mk, sub_add_cancel, this.2, true_and, ite_eq_right this.1]⟩ end diff --git a/Mathlib/LinearAlgebra/Dimension/Localization.lean b/Mathlib/LinearAlgebra/Dimension/Localization.lean index fb6dfbb307fc9a..0ebaa2ed413b2e 100644 --- a/Mathlib/LinearAlgebra/Dimension/Localization.lean +++ b/Mathlib/LinearAlgebra/Dimension/Localization.lean @@ -278,7 +278,7 @@ lemma aleph0_le_rank_of_isEmpty_oreSet (hS : IsEmpty (OreLocalization.OreSet R suffices ∀ (g : ℕ → R) (x), (∑ i ∈ Finset.range n, g i • (r * s ^ (i + x))) = 0 → ∀ i < n, g i = 0 by refine Fintype.linearIndependent_iff.mpr fun g hg i ↦ ?_ - simpa only [dif_pos i.prop] using this (fun i ↦ if h : i < n then g ⟨i, h⟩ else 0) 0 + simpa only [dite_eq_left i.prop] using this (fun i ↦ if h : i < n then g ⟨i, h⟩ else 0) 0 (by simp [← Fin.sum_univ_eq_sum_range, ← hg]) i i.prop intro g x hg i hin induction n generalizing g x i with diff --git a/Mathlib/LinearAlgebra/Dual/Basis.lean b/Mathlib/LinearAlgebra/Dual/Basis.lean index e53f0baea62686..12aa75e01e406d 100644 --- a/Mathlib/LinearAlgebra/Dual/Basis.lean +++ b/Mathlib/LinearAlgebra/Dual/Basis.lean @@ -145,7 +145,7 @@ theorem linearCombination_dualBasis (f : ι →₀ R) (i : ι) : cases nonempty_fintype ι rw [Finsupp.linearCombination_apply, Finsupp.sum_fintype, LinearMap.sum_apply] · simp_rw [LinearMap.smul_apply, smul_eq_mul, dualBasis_apply_self, mul_boole, - Finset.sum_ite_eq, if_pos (Finset.mem_univ i)] + Finset.sum_ite_eq, ite_eq_left (Finset.mem_univ i)] · intro rw [zero_smul] diff --git a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean index a7b066ae1089a3..e173401f4d0141 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean @@ -170,7 +170,7 @@ theorem inf_iSup_genEigenspace [FiniteDimensional K V] (h : ∀ x ∈ p, f x ∈ have hg₀ : g (m.sum fun _μ mμ ↦ mμ) = g (m μ) := by suffices ∀ μ' ∈ m.support, g (m μ') = if μ' = μ then g (m μ) else 0 by rw [map_finsuppSum, Finsupp.sum_congr (g2 := fun μ' _ ↦ if μ' = μ then g (m μ) else 0) this, - Finsupp.sum_ite_eq', if_pos hμ] + Finsupp.sum_ite_eq', ite_eq_left hμ] rintro μ' hμ' split_ifs with hμμ' · rw [hμμ'] diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index e6cef9228083a7..8a8923035ff394 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -508,9 +508,9 @@ noncomputable def divisionRingOfFiniteDimensional (F K : Type*) [Field F] [Ring letI := Classical.decEq K if H : x = 0 then 0 else Classical.choose <| FiniteDimensional.exists_mul_eq_one F H mul_inv_cancel x hx := show x * dite _ (h := _) _ _ = _ by - rw [dif_neg hx] + rw [dite_eq_right hx] exact (Classical.choose_spec (FiniteDimensional.exists_mul_eq_one F hx) :) - inv_zero := dif_pos rfl + inv_zero := dite_eq_left rfl nnqsmul := _ nnqsmul_def := fun _ _ => rfl qsmul := _ diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean index 6c25b2c94354e5..4905311320ee1e 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean @@ -309,7 +309,7 @@ theorem coe_basisOfPiSpaceOfLinearIndependent ⇑(basisOfPiSpaceOfLinearIndependent hb) = b := by by_cases hι : Nonempty ι · simp [hι, basisOfPiSpaceOfLinearIndependent] - · rw [basisOfPiSpaceOfLinearIndependent, dif_neg hι] + · rw [basisOfPiSpaceOfLinearIndependent, dite_eq_right hι] ext i exact ((not_nonempty_iff.mp hι).false i).elim diff --git a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean index 0b39c121234c53..91d2b679c96900 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean @@ -323,7 +323,7 @@ theorem Fintype.linearCombination_apply (f) : Fintype.linearCombination R v f = theorem Fintype.linearCombination_apply_single [DecidableEq α] (i : α) (r : R) : Fintype.linearCombination R v (Pi.single i r) = r • v i := by simp_rw [Fintype.linearCombination_apply, Pi.single_apply, ite_smul, zero_smul] - rw [Finset.sum_ite_eq', if_pos (Finset.mem_univ _)] + rw [Finset.sum_ite_eq', ite_eq_left (Finset.mem_univ _)] theorem Finsupp.linearCombination_eq_fintype_linearCombination_apply (x : α → R) : linearCombination R v ((Finsupp.linearEquivFunOnFinite R R α).symm x) = diff --git a/Mathlib/LinearAlgebra/Finsupp/Supported.lean b/Mathlib/LinearAlgebra/Finsupp/Supported.lean index b81a6ddf740d1c..dce3e55100169e 100644 --- a/Mathlib/LinearAlgebra/Finsupp/Supported.lean +++ b/Mathlib/LinearAlgebra/Finsupp/Supported.lean @@ -156,7 +156,7 @@ theorem supported_iUnion {δ : Type*} (s : δ → Set α) : theorem supported_union (s t : Set α) : supported M R (s ∪ t) = supported M R s ⊔ supported M R t := by - rw [Set.union_eq_iUnion, supported_iUnion, iSup_bool_eq, cond_true, cond_false] + rw [Set.union_eq_iUnion, supported_iUnion, iSup_bool_eq, Bool.cond_true, Bool.cond_false] theorem supported_iInter {ι : Type*} (s : ι → Set α) : supported M R (⋂ i, s i) = ⨅ i, supported M R (s i) := diff --git a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean index e41fa3e544a4f6..ad172b4c228cd8 100644 --- a/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Finsupp/VectorSpace.lean @@ -192,7 +192,7 @@ variable [Semiring R] [AddCommMonoid M] [Module R M] theorem _root_.Finset.sum_single_ite [Fintype n] (a : R) (i : n) : (∑ x : n, Finsupp.single x (if i = x then a else 0)) = Finsupp.single i a := by simp only [apply_ite (Finsupp.single _), Finsupp.single_zero, Finset.sum_ite_eq, - if_pos (Finset.mem_univ _)] + ite_eq_left (Finset.mem_univ _)] @[simp] theorem equivFun_symm_single [Finite n] (b : Basis n R M) (i : n) : diff --git a/Mathlib/LinearAlgebra/FreeModule/Norm.lean b/Mathlib/LinearAlgebra/FreeModule/Norm.lean index 2962cae544ddf3..77c07696b73a29 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Norm.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Norm.lean @@ -42,7 +42,7 @@ theorem associated_norm_prod_smith [Fintype ι] (b : Basis ι R S) {f : S} (hf : refine b'.ext fun i => ?_ simp_rw [LinearMap.comp_apply, LinearEquiv.coe_toLinearMap, Matrix.toLin_apply, Basis.repr_self, Finsupp.single_eq_pi_single, Matrix.diagonal_mulVec_single, Pi.single_apply, ite_smul, - zero_smul, Finset.sum_ite_eq', mul_one, if_pos (Finset.mem_univ _), b'.equiv_apply] + zero_smul, Finset.sum_ite_eq', mul_one, ite_eq_left (Finset.mem_univ _), b'.equiv_apply] change _ = f * _ rw [mul_comm, ← smul_eq_mul, LinearEquiv.restrictScalars_apply, LinearEquiv.coord_apply_smul] grind [Ideal.selfBasis_def] diff --git a/Mathlib/LinearAlgebra/Lagrange.lean b/Mathlib/LinearAlgebra/Lagrange.lean index d4d69cbc4623ef..15cdee460e800e 100644 --- a/Mathlib/LinearAlgebra/Lagrange.lean +++ b/Mathlib/LinearAlgebra/Lagrange.lean @@ -393,12 +393,12 @@ def funEquivDegreeLT (hvs : Set.InjOn v s) : degreeLT F #s ≃ₗ[F] s → F whe simp only [Subtype.mk_eq_mk, dite_eq_ite] rw [mem_degreeLT] at hf conv => rhs; rw [eq_interpolate hvs hf] - exact interpolate_eq_of_values_eq_on _ _ fun _ hi => if_pos hi + exact interpolate_eq_of_values_eq_on _ _ fun _ hi => ite_eq_left hi right_inv := by intro f ext ⟨i, hi⟩ simp only [eval_interpolate_at_node _ hvs hi] - exact dif_pos hi + exact dite_eq_left hi theorem interpolate_eq_sum_interpolate_insert_sdiff (hvt : Set.InjOn v t) (hs : s.Nonempty) (hst : s ⊆ t) : diff --git a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean index 7aa2a50b4add8f..5a98ccd705532f 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent/Defs.lean @@ -253,9 +253,9 @@ theorem linearIndependent_iff''ₛ : fun H s f g eq i hi ↦ by convert! H s (fun j ↦ if j ∈ s then f j else 0) (fun j ↦ if j ∈ s then g j else 0) - (fun j hj ↦ (if_neg hj).trans (if_neg hj).symm) + (fun j hj ↦ (ite_eq_right hj).trans (ite_eq_right hj).symm) (by simp_rw [ite_smul, zero_smul, Finset.sum_extend_by_zero, eq]) i <;> - exact (if_pos hi).symm⟩ + exact (ite_eq_left hi).symm⟩ theorem not_linearIndependent_iffₛ : ¬LinearIndependent R v ↔ ∃ s : Finset ι, @@ -746,9 +746,9 @@ theorem linearIndependent_iff'' : exact linearIndependent_iff'.trans ⟨fun H s g hg hv i => if his : i ∈ s then H s g hv i his else hg i his, fun H s g hg i hi => by convert! - H s (fun j => if j ∈ s then g j else 0) (fun j hj => if_neg hj) + H s (fun j => if j ∈ s then g j else 0) (fun j hj => ite_eq_right hj) (by simp_rw [ite_smul, zero_smul, Finset.sum_extend_by_zero, hg]) i - exact (if_pos hi).symm⟩ + exact (ite_eq_left hi).symm⟩ theorem linearIndependent_add_smul_iff {c : ι → R} {i : ι} (h₀ : c i = 0) : LinearIndependent R (v + (c · • v i)) ↔ LinearIndependent R v := by diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index b314e097a396a6..4dae185f114d73 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -957,7 +957,7 @@ theorem toLinearPMap_apply_aux {g : Submodule R (E × F)} g.toLinearPMap x = valFromGraph hg x.2 := by classical change (if hg : _ then g.toLinearPMapAux hg else 0) x = _ - rw [dif_pos] + rw [dite_eq_left] · rfl · exact hg diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean index 1e7c44ff6851be..bbc08d33ff786b 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean @@ -386,11 +386,11 @@ lemma det_piecewise_one_eq_submatrix_det (M.submatrix Subtype.val Subtype.val) (M.submatrix Subtype.val Subtype.val) 0 1 := by ext (i | i) (j | j) <;> dsimp [A, e] - · simp only [Finset.piecewise, if_pos i.prop] - · simp only [Finset.piecewise, if_pos i.prop] - · simp only [Finset.piecewise, if_neg i.prop] + · simp only [Finset.piecewise, ite_eq_left i.prop] + · simp only [Finset.piecewise, ite_eq_left i.prop] + · simp only [Finset.piecewise, ite_eq_right i.prop] exact Matrix.one_apply_ne (fun h => i.prop (h ▸ j.prop)) - · simp only [Finset.piecewise, if_neg i.prop, Matrix.one_apply, Subtype.ext_iff] + · simp only [Finset.piecewise, ite_eq_right i.prop, Matrix.one_apply, Subtype.ext_iff] rw [h_blocks, Matrix.det_fromBlocks_zero₂₁, Matrix.det_one, mul_one] set_option backward.isDefEq.respectTransparency.types false in diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean index 9f47c32c8ab7db..73999e6280bbd5 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean @@ -81,7 +81,7 @@ theorem det_diagonal {d : n → R} : det (diagonal d) = ∏ i, d i := by obtain ⟨x, h3⟩ := not_forall.1 (mt Equiv.ext h2) convert! mul_zero (ε σ) apply Finset.prod_eq_zero (mem_univ x) - exact if_neg h3 + exact ite_eq_right h3 · simp · simp @@ -736,7 +736,7 @@ theorem det_succ_column_zero {n : ℕ} (A : Matrix (Fin n.succ) (Fin n.succ) R) refine Finset.sum_congr rfl fun i _ => Fin.cases ?_ (fun i => ?_) i · simp only [Fin.prod_univ_succ, Matrix.det_apply, Finset.mul_sum, Equiv.Perm.decomposeFin_symm_apply_zero, Fin.val_zero, one_mul, - Equiv.Perm.decomposeFin.symm_sign, Equiv.swap_self, if_true, id, + Equiv.Perm.decomposeFin.symm_sign, Equiv.swap_self, ite_true, id, Equiv.Perm.decomposeFin_symm_apply_succ, Fin.succAbove_zero, Equiv.coe_refl, pow_zero, mul_smul_comm, of_apply] -- `univ_perm_fin_succ` gives a different embedding of `Perm (Fin n)` into @@ -747,7 +747,7 @@ theorem det_succ_column_zero {n : ℕ} (A : Matrix (Fin n.succ) (Fin n.succ) R) ← det_permute, Matrix.det_apply, Finset.mul_sum, Finset.mul_sum] -- now we just need to move the corresponding parts to the same place refine Finset.sum_congr rfl fun σ _ => ?_ - rw [Equiv.Perm.decomposeFin.symm_sign, if_neg (Fin.succ_ne_zero i)] + rw [Equiv.Perm.decomposeFin.symm_sign, ite_eq_right (Fin.succ_ne_zero i)] calc ((-1 * Perm.sign σ : ℤ) • ∏ i', A (Perm.decomposeFin.symm (Fin.succ i, σ) i') i') = (-1 * Perm.sign σ : ℤ) • (A (Fin.succ i) 0 * diff --git a/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean b/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean index 69de68bcf32c58..0c717f3efa74f7 100644 --- a/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean +++ b/Mathlib/LinearAlgebra/Matrix/Determinant/Misc.lean @@ -76,7 +76,7 @@ theorem det_eq_sum_column_mul_submatrix_succAbove_succAbove_det {n : ℕ} M.det = (-1) ^ (i₀ + j₀ : ℕ) * (∑ i, M i j₀) * (M.submatrix (Fin.succAbove i₀) (Fin.succAbove j₀)).det := by rw [← one_smul R M.det, ← Matrix.det_updateRow_sum _ i₀ (fun _ ↦ 1), Matrix.det_succ_row _ i₀] - simp only [updateRow_apply, if_true, one_smul, submatrix_updateRow_succAbove, Finset.sum_apply] + simp only [updateRow_apply, ite_true, one_smul, submatrix_updateRow_succAbove, Finset.sum_apply] rw [Fintype.sum_eq_add_sum_subtype_ne _ j₀] conv_lhs => enter [2, 2, i] diff --git a/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean b/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean index 5c9a66561da3d3..22c478df747f7f 100644 --- a/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean +++ b/Mathlib/LinearAlgebra/Matrix/FixedDetMatrices.lean @@ -113,19 +113,19 @@ lemma reduce_of_pos {A : Δ m} (hc : (A.1 1 0) = 0) (ha : 0 < A.1 0 0) : reduce A = (T ^ (-(A.1 0 1 / A.1 1 1))) • A := by rw [reduce] simp only [zpow_neg, Int.ediv_neg, neg_neg] at * - simp_rw [if_pos hc, if_pos ha] + simp_rw [ite_eq_left hc, ite_eq_left ha] lemma reduce_of_not_pos {A : Δ m} (hc : (A.1 1 0) = 0) (ha : ¬ 0 < A.1 0 0) : reduce A = (T ^ (-(-A.1 0 1 / -A.1 1 1))) • (S • (S • A)) := by rw [reduce] simp only [zpow_neg, Int.ediv_neg, neg_neg] at * - simp_rw [if_pos hc, if_neg ha] + simp_rw [ite_eq_left hc, ite_eq_right ha] @[simp] lemma reduce_reduceStep {A : Δ m} (hc : (A.1 1 0) ≠ 0) : reduce (reduceStep A) = reduce A := by symm - rw [reduce, if_neg hc] + rw [reduce, ite_eq_right hc] private lemma A_c_eq_zero {A : Δ m} (ha : A.1 1 0 = 0) : A.1 0 0 * A.1 1 1 = m := by simpa only [det_fin_two, ha, mul_zero, sub_zero] using A.2 diff --git a/Mathlib/LinearAlgebra/Matrix/Permanent.lean b/Mathlib/LinearAlgebra/Matrix/Permanent.lean index f83a309ee18f62..d3fb0988bb17bc 100644 --- a/Mathlib/LinearAlgebra/Matrix/Permanent.lean +++ b/Mathlib/LinearAlgebra/Matrix/Permanent.lean @@ -35,7 +35,7 @@ def permanent (M : Matrix n n R) : R := ∑ σ : Perm n, ∏ i, M (σ i) i theorem permanent_diagonal {d : n → R} : permanent (diagonal d) = ∏ i, d i := by refine (sum_eq_single 1 (fun σ _ hσ ↦ ?_) (fun h ↦ (h <| mem_univ _).elim)).trans ?_ · match not_forall.mp (mt Equiv.ext hσ) with - | ⟨x, hx⟩ => exact Finset.prod_eq_zero (mem_univ x) (if_neg hx) + | ⟨x, hx⟩ => exact Finset.prod_eq_zero (mem_univ x) (ite_eq_right hx) · simp only [Perm.one_apply, diagonal_apply_eq] @[simp] diff --git a/Mathlib/LinearAlgebra/Matrix/Rank.lean b/Mathlib/LinearAlgebra/Matrix/Rank.lean index a3385c40b95566..49063b03a3803d 100644 --- a/Mathlib/LinearAlgebra/Matrix/Rank.lean +++ b/Mathlib/LinearAlgebra/Matrix/Rank.lean @@ -382,7 +382,8 @@ theorem rank_le_card_of_support_subset [CommSemiring R] [StrongRankCondition R] simp only [hBdef, mul_apply, of_apply, submatrix_apply, id_eq] by_cases hi : i ∈ s · rw [Fintype.sum_eq_single (⟨i, hi⟩ : {x // x ∈ s}) - fun a ha => by rw [if_neg fun he => ha (Subtype.ext he), zero_mul], if_pos rfl, one_mul] + fun a ha => by rw [ite_eq_right fun he => ha (Subtype.ext he), zero_mul], + ite_eq_left rfl, one_mul] · have h0 : A i = 0 := hz i hi aesop calc A.rank = (B * A.submatrix Subtype.val id).rank := by rw [hB] diff --git a/Mathlib/LinearAlgebra/Matrix/RowCol.lean b/Mathlib/LinearAlgebra/Matrix/RowCol.lean index 8d46f17c0fda13..d21f5677b2761c 100644 --- a/Mathlib/LinearAlgebra/Matrix/RowCol.lean +++ b/Mathlib/LinearAlgebra/Matrix/RowCol.lean @@ -227,14 +227,14 @@ theorem updateCol_ne [DecidableEq n] {j' : n} (j_ne : j' ≠ j) : theorem updateRow_apply [DecidableEq m] {i' : m} : updateRow M i b i' j = if i' = i then b j else M i' j := by by_cases h : i' = i - · rw [h, updateRow_self, if_pos rfl] - · rw [updateRow_ne h, if_neg h] + · rw [h, updateRow_self, ite_eq_left rfl] + · rw [updateRow_ne h, ite_eq_right h] theorem updateCol_apply [DecidableEq n] {j' : n} : updateCol M j c i j' = if j' = j then c i else M i j' := by by_cases h : j' = j - · rw [h, updateCol_self, if_pos rfl] - · rw [updateCol_ne h, if_neg h] + · rw [h, updateCol_self, ite_eq_left rfl] + · rw [updateCol_ne h, ite_eq_right h] @[simp] theorem updateCol_subsingleton [Subsingleton n] (A : Matrix m n R) (i : n) (b : m → R) : diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index 32864908aec4bc..d4fb12e0e4a09d 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -685,7 +685,7 @@ lemma diag_eq_diag2n_prod (i₀ : ι) (D : ι → F) (hD : det (diagonal D) = 1) rw [Finset.map_noncommProd] simp_rw [coeMonoidHom_apply, apply_dite, coe_one] rw [Finset.noncommProd_congr (s₂ := {i | i ≠ i₀}) rfl (fun i hi ↦ - (dif_pos (Finset.mem_filter.1 hi).2 : _ = (diag2n (Finset.mem_filter.1 hi).2 _ _).1))] + (dite_eq_left (Finset.mem_filter.1 hi).2 : _ = (diag2n (Finset.mem_filter.1 hi).2 _ _).1))] convert_to! _ = Finset.noncommProd {i | i ≠ i₀} (fun x ↦ diagonal (g x)) _ simp_rw [← diagonalRingHom_apply] rw [← Finset.map_noncommProd _ _ (fun _ _ _ _ _ ↦ Commute.all _ _), Finset.noncommProd_eq_prod] diff --git a/Mathlib/LinearAlgebra/Matrix/ToLin.lean b/Mathlib/LinearAlgebra/Matrix/ToLin.lean index 154f6b98d74ac2..f5cf502db79675 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLin.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLin.lean @@ -1098,7 +1098,7 @@ lemma linearMap_apply_apply (ij : ι₂ × ι₁) (k : ι₁) : have := Classical.decEq ι₂ rw [linearMap_apply, Matrix.stdBasis_eq_single, Matrix.toLin_self] dsimp only [Matrix.single, of_apply] - simp_rw [ite_smul, one_smul, zero_smul, ite_and, Finset.sum_ite_eq, Finset.mem_univ, if_true] + simp_rw [ite_smul, one_smul, zero_smul, ite_and, Finset.sum_ite_eq, Finset.mem_univ, ite_true] /-- The standard basis of the endomorphism algebra of a module induced by a basis of the module. diff --git a/Mathlib/LinearAlgebra/Matrix/Transvection.lean b/Mathlib/LinearAlgebra/Matrix/Transvection.lean index 08f4f013afe3e8..94a833d7617ebd 100644 --- a/Mathlib/LinearAlgebra/Matrix/Transvection.lean +++ b/Mathlib/LinearAlgebra/Matrix/Transvection.lean @@ -415,14 +415,14 @@ theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : F simp only [ne_eq, inl.injEq, Ne.symm h, not_false_eq_true, transvection_mul_apply_of_ne] rw [IH] rcases le_or_gt (n + 1) i with (hi | hi) - · simp only [hi, n.le_succ.trans hi, if_true] - · rw [if_neg, if_neg] + · simp only [hi, n.le_succ.trans hi, ite_true] + · rw [ite_eq_right, ite_eq_right] · simpa only [hni.symm, not_le, or_false] using Nat.lt_succ_iff_lt_or_eq.1 hi · simpa only [not_le] using hi | self => simp only [length_listTransvecCol, le_refl, List.drop_eq_nil_of_le, List.prod_nil, Matrix.one_mul] - rw [if_neg] + rw [ite_eq_right] simpa only [not_le] using i.2 /-- Multiplying by some of the matrices in `listTransvecRow M` does not change the last column. -/ @@ -437,7 +437,7 @@ theorem mul_listTransvecRow_last_col_take (i : Fin r ⊕ Unit) {k : ℕ} (hk : k (listTransvecRow M)[k]? = ↑(transvection (inr Unit.unit) (inl k') (-M (inr Unit.unit) (inl k') / M (inr Unit.unit) (inr Unit.unit))) := by - simp only [k', listTransvecRow, hkr, dif_pos, List.getElem?_ofFn] + simp only [k', listTransvecRow, hkr, dite_eq_left, List.getElem?_ofFn] simp only [List.take_add_one, ← Matrix.mul_assoc, this, List.prod_append, Matrix.mul_one, List.prod_cons, List.prod_nil, Option.toList_some] rw [mul_transvection_apply_of_ne, IH hkr.le] @@ -473,7 +473,7 @@ theorem mul_listTransvecRow_last_row (hM : M (inr unit) (inr unit) ≠ 0) (i : F (listTransvecRow M)[n]? = ↑(transvection (inr unit) (inl n') (-M (inr unit) (inl n') / M (inr unit) (inr unit))) := by - simp only [n', listTransvecRow, hnr, dif_pos, List.getElem?_ofFn] + simp only [n', listTransvecRow, hnr, dite_eq_left, List.getElem?_ofFn] simp only [List.take_add_one, A, ← Matrix.mul_assoc, List.prod_append, Matrix.mul_one, List.prod_cons, List.prod_nil, Option.toList_some] by_cases h : n' = i @@ -482,8 +482,8 @@ theorem mul_listTransvecRow_last_row (hM : M (inr unit) (inr unit) ≠ 0) (i : F simp only [n', Fin.mk_eq_mk] at h simp only [h] have : ¬n.succ ≤ i := by simp only [← hni, n.lt_succ_self, not_le] - simp only [h, mul_transvection_apply_same, if_false, - mul_listTransvecRow_last_col_take _ _ hnr.le, hni.le, this, if_true, IH hnr.le] + simp only [h, mul_transvection_apply_same, ite_false, + mul_listTransvecRow_last_col_take _ _ hnr.le, hni.le, this, ite_true, IH hnr.le] field · have hni : n ≠ i := by rintro rfl @@ -493,7 +493,7 @@ theorem mul_listTransvecRow_last_row (hM : M (inr unit) (inr unit) ≠ 0) (i : F not_false_eq_true] rcases le_or_gt (n + 1) i with (hi | hi) · simp [hi, n.le_succ.trans hi] - · rw [if_neg, if_neg] + · rw [ite_eq_right, ite_eq_right] · simpa only [not_le] using! hi · simpa only [hni.symm, not_le, or_false] using! Nat.lt_succ_iff_lt_or_eq.1 hi diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index c65bd76e461ac7..4de9f80b8dc6fa 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -1359,13 +1359,13 @@ lemma map_piecewise_sub_map_piecewise [LinearOrder ι] (a b v : (i : ι) → M rw [← s.piecewise_idem_right b a, map_sub_map_piecewise] refine Finset.sum_congr rfl fun i hi ↦ congr_arg f <| funext fun j ↦ ?_ by_cases hjs : j ∈ s - · rw [if_pos hjs]; by_cases hji : j < i - · rw [if_pos fun _ ↦ hji, if_pos hji, s.piecewise_eq_of_mem _ _ hjs] - rw [if_neg (Classical.not_imp.mpr ⟨hjs, hji⟩), if_neg hji] + · rw [ite_eq_left hjs]; by_cases hji : j < i + · rw [ite_eq_left fun _ ↦ hji, ite_eq_left hji, s.piecewise_eq_of_mem _ _ hjs] + rw [ite_eq_right (Classical.not_imp.mpr ⟨hjs, hji⟩), ite_eq_right hji] obtain rfl | hij := eq_or_ne i j - · rw [if_pos rfl, if_pos rfl, s.piecewise_eq_of_mem _ _ hi] - · rw [if_neg hij, if_neg hij.symm] - · rw [if_neg hjs, if_pos fun h ↦ (hjs h).elim, s.piecewise_eq_of_notMem _ _ hjs] + · rw [ite_eq_left rfl, ite_eq_left rfl, s.piecewise_eq_of_mem _ _ hi] + · rw [ite_eq_right hij, ite_eq_right hij.symm] + · rw [ite_eq_right hjs, ite_eq_left fun h ↦ (hjs h).elim, s.piecewise_eq_of_notMem _ _ hjs] open Finset in lemma map_add_eq_map_add_linearDeriv_add [DecidableEq ι] [Fintype ι] (x h : (i : ι) → M₁ i) : diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index cb62852d4dfebd..e213045fff6335 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -309,10 +309,10 @@ def iInfKerProjEquiv {I J : Set ι} [DecidablePred fun i => i ∈ I] (hd : Disjo simp only [mem_iInf, mem_ker, proj_apply, pi_apply] intro j hjJ have : j ∉ I := fun hjI => hd.le_bot ⟨hjI, hjJ⟩ - rw [dif_neg this, zero_apply] + rw [dite_eq_right this, zero_apply] · simp only [pi_comp, comp_assoc, subtype_comp_codRestrict, proj_pi, Subtype.coe_prop] ext b ⟨j, hj⟩ - simp only [dif_pos, + simp only [dite_eq_left, LinearMap.coe_proj, LinearMap.pi_apply] rfl · ext1 ⟨b, hb⟩ diff --git a/Mathlib/LinearAlgebra/Projectivization/Constructions.lean b/Mathlib/LinearAlgebra/Projectivization/Constructions.lean index 04305fad079619..982ad66fb44533 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Constructions.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Constructions.lean @@ -87,12 +87,12 @@ lemma cross_mk {v w : Fin 3 → F} (hv : v ≠ 0) (hw : w ≠ 0) : lemma cross_mk_of_cross_eq_zero {v w : Fin 3 → F} (hv : v ≠ 0) (hw : w ≠ 0) (h : crossProduct v w = 0) : cross (mk F v hv) (mk F w hw) = mk F v hv := by - rw [cross_mk, dif_pos h] + rw [cross_mk, dite_eq_left h] lemma cross_mk_of_cross_ne_zero {v w : Fin 3 → F} (hv : v ≠ 0) (hw : w ≠ 0) (h : crossProduct v w ≠ 0) : cross (mk F v hv) (mk F w hw) = mk F (crossProduct v w) h := by - rw [cross_mk, dif_neg h] + rw [cross_mk, dite_eq_right h] lemma cross_self (v : ℙ F (Fin 3 → F)) : cross v v = v := by induction v with | h v hv => diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index a89e55fcc8c95c..d88d051e3d5658 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -365,13 +365,13 @@ protected theorem map_sum {ι} [DecidableEq ι] (Q : QuadraticMap R M N) (s : Fi | cons a s ha ih => simp_rw [Finset.sum_cons, QuadraticMap.map_add, ih, add_assoc, Finset.sym2_cons, Finset.sum_filter, Finset.sum_disjUnion, Finset.sum_map, Finset.sum_cons, - Sym2.mkEmbedding_apply, Sym2.mk_isDiag_iff, not_true, if_false, zero_add, + Sym2.mkEmbedding_apply, Sym2.mk_isDiag_iff, not_true, ite_false, zero_add, Sym2.map_mk, polarSym2_sym2Mk, ← polarBilin_apply_apply, _root_.map_sum, polarBilin_apply_apply] congr 2 rw [add_comm] congr! with i hi - rw [if_pos (ne_of_mem_of_not_mem hi ha).symm] + rw [ite_eq_left (ne_of_mem_of_not_mem hi ha).symm] protected theorem map_sum' {ι} (Q : QuadraticMap R M N) (s : Finset ι) (f : ι → M) : Q (∑ i ∈ s, f i) = ∑ ij ∈ s.sym2, polarSym2 Q (ij.map f) - ∑ i ∈ s, Q (f i) := by diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean index 5e257c0287067a..7e0dbd832cba88 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basis.lean @@ -99,7 +99,7 @@ theorem toQuadraticMap_toBilin (Q : QuadraticMap R M N) (bm : Basis ι R M) : Finsupp.linearCombination_apply, Finsupp.sum] simp_rw [LinearMap.map_sum₂, map_sum, LinearMap.map_smul₂, map_smul, toBilin_apply, smul_ite, smul_zero, ← Finset.sum_product', ← Finset.diag_union_offDiag, - Finset.sum_union (Finset.disjoint_diag_offDiag _), Finset.sum_diag, if_true] + Finset.sum_union (Finset.disjoint_diag_offDiag _), Finset.sum_diag, ite_true] rw [Finset.sum_ite_of_false, QuadraticMap.map_sum, ← Finset.sum_filter] · simp_rw [← polar_smul_right _ (bm.repr x <| Prod.snd _), ← polar_smul_left _ (bm.repr x <| Prod.fst _)] diff --git a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean index adc05655bb9d2e..c5ea4d473ec13a 100644 --- a/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean +++ b/Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Relations.lean @@ -118,14 +118,14 @@ private lemma lie_e_f_same_aux (k : ι) (hki : k ≠ i) (hki' : k ≠ P.reflecti Finset.sum_eq_single_of_mem y (Finset.mem_univ _) (by aesop)] simp only [hx, hy.symm, hx', hy', reduceIte, Nat.cast_add] ring - · simp_rw [if_neg (h₂ _), Finset.sum_const_zero, sub_zero] + · simp_rw [ite_eq_right (h₂ _), Finset.sum_const_zero, sub_zero] replace h₂ : P.chainTopCoeff i k = 0 := P.chainTopCoeff_eq_zero_iff.mpr <| Or.inr fun ⟨x, hx⟩ ↦ h₂ x <| by simp [hx] have h_lin_ind_x : LinearIndependent R ![P.root i, P.root x] := by simpa [hx] using h_lin_ind have hx' : P.chainBotCoeff i k = P.chainBotCoeff i x + 1 := chainBotCoeff_of_add h_lin_ind_x (add_comm (P.root i) _ ▸ hx) simp [hx, hx', h₂] - · simp_rw [if_neg (h₁ _), Finset.sum_const_zero, zero_sub] + · simp_rw [ite_eq_right (h₁ _), Finset.sum_const_zero, zero_sub] replace h₁ : P.chainBotCoeff i k = 0 := P.chainBotCoeff_eq_zero_iff.mpr <| Or.inr fun ⟨x, hx⟩ ↦ h₁ x <| by simp [hx] have h_lin_ind_y : LinearIndependent R ![P.root i, P.root y] := by @@ -176,8 +176,8 @@ lemma lie_e_f_same : simp [P.ne_zero x, eq_comm] simp only [e, f, h, Ring.lie_def, Matrix.sub_apply, Matrix.mul_apply, Fintype.sum_sum_type, Matrix.fromBlocks_apply₂₁, Matrix.of_apply, hki, reduceIte, zero_mul, Finset.sum_const_zero, - Matrix.fromBlocks_apply₂₂, mul_ite, ite_mul, mul_zero, ← ite_and, if_neg (hx _), add_zero, - aux, zero_sub, Matrix.diagonal_apply] + Matrix.fromBlocks_apply₂₂, mul_ite, ite_mul, mul_zero, ← ite_and, ite_eq_right (hx _), + add_zero, aux, zero_sub, Matrix.diagonal_apply] rw [Finset.sum_eq_single_of_mem i (Finset.mem_univ _) (by aesop)] simp [eq_comm, apply_ite ((-·) : R → R)] rcases eq_or_ne k l with rfl | hkl @@ -234,7 +234,7 @@ private lemma lie_e_f_ne_aux₁ : simpa [e, f, P.ne_zero, hij, -indexNeg_neg, -Finset.univ_eq_attach, ← ite_and, Finset.sum_eq_single_of_mem j (Finset.mem_univ _) aux] rcases eq_or_ne k i with rfl | hk; swap - · rw [if_neg (by tauto), Finset.sum_ite_of_false (by aesop)]; simp + · rw [ite_eq_right (by tauto), Finset.sum_ite_of_false (by aesop)]; simp by_cases hij_mem : P.root i + P.root j ∈ range P.root · obtain ⟨m, hm⟩ := hij_mem rw [Finset.sum_eq_single_of_mem m (Finset.mem_univ _) (by rintro x - hx; simp [← hm, hx]), @@ -273,7 +273,7 @@ lemma lie_e_f_ne [P.IsReduced] [P.IsIrreducible] : · exact lie_e_f_ne_aux₀ k l · have aux₁ : P.root k ≠ P.root i - P.root j := fun contra ↦ b.sub_notMem_range_root i.property j.property ⟨k, contra⟩ - simp [e, f, ← sub_eq_add_neg, if_neg aux₁] + simp [e, f, ← sub_eq_add_neg, ite_eq_right aux₁] · /- Geck Case 1 (covered by the auxiliary lemmas above). -/ rcases eq_or_ne l j with rfl | h₃ · rw [← ⁅e i, f j⁆.transpose_apply, lie_e_f_ne_aux₁ hij, Pi.zero_apply, Matrix.zero_apply] @@ -324,9 +324,14 @@ lemma lie_e_f_ne [P.IsReduced] [P.IsIrreducible] : have aux₄ (x) (hx : x ≠ l') : ¬ (P.root x = P.root i + P.root l ∧ P.root k = P.root x - P.root j) := by grind [EmbeddingLike.apply_eq_iff_eq] - rw [Finset.sum_eq_single_of_mem m (Finset.mem_univ _) (by rintro x - h; rw [if_neg (aux₃ _ h)]), - Finset.sum_eq_single_of_mem l' (Finset.mem_univ _) (by rintro x - h; rw [if_neg (aux₄ _ h)]), - if_pos (⟨hm, by rw [hm, hk]; abel⟩), if_pos ⟨by rw [hl', add_comm], by rw [hl', hk]⟩] + rw [Finset.sum_eq_single_of_mem m (Finset.mem_univ _) (by + rintro x - h + rw [ite_eq_right (aux₃ _ h)]), + Finset.sum_eq_single_of_mem l' (Finset.mem_univ _) (by + rintro x - h + rw [ite_eq_right (aux₄ _ h)]), + ite_eq_left (⟨hm, by rw [hm, hk]; abel⟩), + ite_eq_left ⟨by rw [hl', add_comm], by rw [hl', hk]⟩] have := chainBotCoeff_mul_chainTopCoeff i.property j.property hij' hl'.symm hm.symm h₅ norm_cast diff --git a/Mathlib/LinearAlgebra/Trace.lean b/Mathlib/LinearAlgebra/Trace.lean index 2e916eca8f2b72..15937293e9f2d3 100644 --- a/Mathlib/LinearAlgebra/Trace.lean +++ b/Mathlib/LinearAlgebra/Trace.lean @@ -80,7 +80,7 @@ open scoped Classical in theorem trace_eq_matrix_trace_of_finset {s : Finset M} (b : Basis s R M) (f : M →ₗ[R] M) : trace R M f = Matrix.trace (LinearMap.toMatrix b b f) := by have : ∃ s : Finset M, Nonempty (Basis s R M) := ⟨s, ⟨b⟩⟩ - rw [trace, dif_pos this, ← traceAux_def] + rw [trace, dite_eq_left this, ← traceAux_def] congr 1 apply traceAux_eq @@ -106,7 +106,7 @@ theorem trace_mul_comm (f g : M →ₗ[R] M) : trace R M (f * g) = trace R M (g · let ⟨s, ⟨b⟩⟩ := H simp_rw [trace_eq_matrix_trace R b, LinearMap.toMatrix_mul] apply Matrix.trace_mul_comm - · rw [trace, dif_neg H, LinearMap.zero_apply, LinearMap.zero_apply] + · rw [trace, dite_eq_right H, LinearMap.zero_apply, LinearMap.zero_apply] lemma trace_mul_cycle (f g h : M →ₗ[R] M) : trace R M (f * g * h) = trace R M (h * f * g) := by @@ -299,7 +299,7 @@ theorem trace_conj' (f : M →ₗ[R] M) (e : M ≃ₗ[R] N) : trace R N (e.conj have := (Module.free_def R N).mpr ⟨_, ⟨(b.map e).reindex (e.toEquiv.image _)⟩⟩ rw [e.conj_apply, trace_comp_comm', ← comp_assoc, LinearEquiv.comp_coe, LinearEquiv.self_trans_symm, LinearEquiv.refl_toLinearMap, id_comp] - · rw [trace, trace, dif_neg hM, dif_neg ?_, zero_apply, zero_apply] + · rw [trace, trace, dite_eq_right hM, dite_eq_right ?_, zero_apply, zero_apply] rintro ⟨s, ⟨b⟩⟩ exact hM ⟨s.image e.symm, ⟨(b.map e.symm).reindex ((e.symm.toEquiv.image s).trans (Equiv.setCongr Finset.coe_image.symm))⟩⟩ @@ -352,7 +352,7 @@ lemma isNilpotent_trace_of_isNilpotent {f : M →ₗ[R] M} (hf : IsNilpotent f) IsNilpotent (trace R M f) := by by_cases H : ∃ s : Finset M, Nonempty (Basis s R M) swap - · rw [LinearMap.trace, dif_neg H] + · rw [LinearMap.trace, dite_eq_right H] exact IsNilpotent.zero obtain ⟨s, ⟨b⟩⟩ := H classical diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index 25b21d2024a9ec..926468dc1be635 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -904,8 +904,9 @@ theorem eq_ite_iff : a = ite P b c ↔ P ∧ a = b ∨ ¬P ∧ a = c := eq_comm.trans <| ite_eq_iff.trans <| (Iff.rfl.and eq_comm).or (Iff.rfl.and eq_comm) theorem dite_eq_iff' : dite P A B = c ↔ (∀ h, A h = c) ∧ ∀ h, B h = c := - ⟨fun he ↦ ⟨fun h ↦ (dif_pos h).symm.trans he, fun h ↦ (dif_neg h).symm.trans he⟩, fun he ↦ - (em P).elim (fun h ↦ (dif_pos h).trans <| he.1 h) fun h ↦ (dif_neg h).trans <| he.2 h⟩ + ⟨fun he ↦ ⟨fun h ↦ (dite_eq_left h).symm.trans he, fun h ↦ (dite_eq_right h).symm.trans he⟩, + fun he ↦ (em P).elim (fun h ↦ (dite_eq_left h).trans <| he.1 h) fun h ↦ + (dite_eq_right h).trans <| he.2 h⟩ theorem ite_eq_iff' : ite P a b = c ↔ (P → a = c) ∧ (¬P → b = c) := dite_eq_iff' @@ -948,10 +949,10 @@ protected theorem Ne.ite_ne_right_iff (h : a ≠ b) : ite P a b ≠ b ↔ P := variable (P Q a b) theorem dite_eq_or_eq : (∃ h, dite P A B = A h) ∨ ∃ h, dite P A B = B h := - if h : _ then .inl ⟨h, dif_pos h⟩ else .inr ⟨h, dif_neg h⟩ + if h : _ then .inl ⟨h, dite_eq_left h⟩ else .inr ⟨h, dite_eq_right h⟩ theorem ite_eq_or_eq : ite P a b = a ∨ ite P a b = b := - if h : _ then .inl (if_pos h) else .inr (if_neg h) + if h : _ then .inl (ite_eq_left h) else .inr (ite_eq_right h) /-- A two-argument function applied to two `dite`s is a `dite` of that two-argument function applied to each of the branches. -/ diff --git a/Mathlib/Logic/Embedding/Basic.lean b/Mathlib/Logic/Embedding/Basic.lean index a116be00590261..59028035858c5f 100644 --- a/Mathlib/Logic/Embedding/Basic.lean +++ b/Mathlib/Logic/Embedding/Basic.lean @@ -477,13 +477,13 @@ def subtypeOrLeftEmbedding (p q : α → Prop) [DecidablePred p] : theorem subtypeOrLeftEmbedding_apply_left {p q : α → Prop} [DecidablePred p] (x : { x // p x ∨ q x }) (hx : p x) : subtypeOrLeftEmbedding p q x = Sum.inl ⟨x, hx⟩ := - dif_pos hx + dite_eq_left hx @[simp] theorem subtypeOrLeftEmbedding_apply_right {p q : α → Prop} [DecidablePred p] (x : { x // p x ∨ q x }) (hx : ¬p x) : subtypeOrLeftEmbedding p q x = Sum.inr ⟨x, x.prop.resolve_left hx⟩ := - dif_neg hx + dite_eq_right hx @[grind =] theorem subtypeOrLeftEmbedding_apply {p q : α → Prop} [DecidablePred p] diff --git a/Mathlib/Logic/Equiv/Basic.lean b/Mathlib/Logic/Equiv/Basic.lean index 15df8adf560a48..af7d6a9cb70292 100644 --- a/Mathlib/Logic/Equiv/Basic.lean +++ b/Mathlib/Logic/Equiv/Basic.lean @@ -111,7 +111,8 @@ is naturally equivalent to the type of functions `{a // ¬ p a} → β`. -/ @[simps] def subtypePreimage : { x : α → β // x ∘ Subtype.val = x₀ } ≃ ({ a // ¬p a } → β) where toFun (x : { x : α → β // x ∘ Subtype.val = x₀ }) a := (x : α → β) a - invFun x := ⟨fun a => if h : p a then x₀ ⟨a, h⟩ else x ⟨a, h⟩, funext fun ⟨_, h⟩ => dif_pos h⟩ + invFun x := + ⟨fun a => if h : p a then x₀ ⟨a, h⟩ else x ⟨a, h⟩, funext fun ⟨_, h⟩ => dite_eq_left h⟩ left_inv := fun ⟨x, hx⟩ => Subtype.val_injective <| funext fun a => by @@ -123,15 +124,15 @@ def subtypePreimage : { x : α → β // x ∘ Subtype.val = x₀ } ≃ ({ a // funext fun ⟨a, h⟩ => show dite (p a) _ _ = _ by dsimp only - rw [dif_neg h] + rw [dite_eq_right h] theorem subtypePreimage_symm_apply_coe_pos (x : { a // ¬p a } → β) (a : α) (h : p a) : ((subtypePreimage p x₀).symm x : α → β) a = x₀ ⟨a, h⟩ := - dif_pos h + dite_eq_left h theorem subtypePreimage_symm_apply_coe_neg (x : { a // ¬p a } → β) (a : α) (h : ¬p a) : ((subtypePreimage p x₀).symm x : α → β) a = x ⟨a, h⟩ := - dif_neg h + dite_eq_right h end subtypePreimage @@ -531,12 +532,12 @@ theorem subtypeEquivCodomain_symm_apply (f : { x' // x' ≠ x } → Y) (y : Y) ( theorem subtypeEquivCodomain_symm_apply_eq (f : { x' // x' ≠ x } → Y) (y : Y) : ((subtypeEquivCodomain f).symm y : X → Y) x = y := - dif_neg (not_not.mpr rfl) + dite_eq_right (not_not.mpr rfl) theorem subtypeEquivCodomain_symm_apply_ne (f : { x' // x' ≠ x } → Y) (y : Y) (x' : X) (h : x' ≠ x) : ((subtypeEquivCodomain f).symm y : X → Y) x' = f ⟨x', h⟩ := - dif_pos h + dite_eq_left h end subtypeEquivCodomain @@ -653,7 +654,7 @@ theorem swap_apply_def (a b x : α) : swap a b x = if x = a then b else if x = b @[simp] theorem swap_apply_left (a b : α) : swap a b a = b := - if_pos rfl + ite_eq_left rfl @[simp] theorem swap_apply_right (a b : α) : swap a b b = a := by diff --git a/Mathlib/Logic/Equiv/Fin/Basic.lean b/Mathlib/Logic/Equiv/Fin/Basic.lean index f91c461d1443e6..bad24cf558b7ae 100644 --- a/Mathlib/Logic/Equiv/Fin/Basic.lean +++ b/Mathlib/Logic/Equiv/Fin/Basic.lean @@ -266,12 +266,12 @@ def finSumNatEquiv (n : ℕ) : Fin n ⊕ ℕ ≃ ℕ where toFun := Sum.elim Fin.val (n + ·) invFun i := if hi : i < n then .inl ⟨i, hi⟩ else .inr (i - n) left_inv i := (i.casesOn - (fun _ => dif_pos (Fin.is_lt _)) - (fun _ => (dif_neg (Nat.le_add_right _ _).not_gt).trans <| + (fun _ => dite_eq_left (Fin.is_lt _)) + (fun _ => (dite_eq_right (Nat.le_add_right _ _).not_gt).trans <| congrArg _ (Nat.add_sub_cancel_left _ _))) right_inv i := (apply_dite _ _ _ _).trans <| (i.lt_or_ge n).by_cases - (fun hi => dif_pos hi) - (fun hi => (dif_neg hi.not_gt).trans <| Nat.add_sub_cancel' hi) + (fun hi => dite_eq_left hi) + (fun hi => (dite_eq_right hi.not_gt).trans <| Nat.add_sub_cancel' hi) @[simp] theorem finSumNatEquiv_apply_left (i : Fin n) : finSumNatEquiv n (.inl i) = i := rfl @@ -280,10 +280,10 @@ def finSumNatEquiv (n : ℕ) : Fin n ⊕ ℕ ≃ ℕ where finSumNatEquiv n (.inr i) = n + i := rfl @[simp] theorem finSumNatEquiv_symm_apply_of_lt {i : ℕ} (hi : i < n) : - (finSumNatEquiv n).symm i = .inl ⟨i, hi⟩ := dif_pos hi + (finSumNatEquiv n).symm i = .inl ⟨i, hi⟩ := dite_eq_left hi @[simp] theorem finSumNatEquiv_symm_apply_of_ge {i : ℕ} (hi : n ≤ i) : - (finSumNatEquiv n).symm i = .inr (i - n) := dif_neg (Nat.not_lt_of_ge hi) + (finSumNatEquiv n).symm i = .inr (i - n) := dite_eq_right (Nat.not_lt_of_ge hi) theorem finSumNatEquiv_symm_apply_fin (i : Fin n) : (finSumNatEquiv n).symm i = .inl i := by simp diff --git a/Mathlib/Logic/Equiv/Fin/Rotate.lean b/Mathlib/Logic/Equiv/Fin/Rotate.lean index 8553b11f066640..4677a3c73bf777 100644 --- a/Mathlib/Logic/Equiv/Fin/Rotate.lean +++ b/Mathlib/Logic/Equiv/Fin/Rotate.lean @@ -51,13 +51,13 @@ theorem Fin.snoc_eq_cons_rotate {α : Type*} (v : Fin n → α) (a : α) : @Fin.snoc _ (fun _ => α) v a = fun i => @Fin.cons _ (fun _ => α) a v (finRotate _ i) := by ext ⟨i, h⟩ by_cases h' : i < n - · rw [finRotate_of_lt h', Fin.snoc, Fin.cons, dif_pos h'] + · rw [finRotate_of_lt h', Fin.snoc, Fin.cons, dite_eq_left h'] rfl · have h'' : n = i := by simp only [not_lt] at h' exact (Nat.eq_of_le_of_lt_succ h' h).symm subst h'' - rw [finRotate_last', Fin.snoc, Fin.cons, dif_neg (lt_irrefl _)] + rw [finRotate_last', Fin.snoc, Fin.cons, dite_eq_right (lt_irrefl _)] rfl @[simp] diff --git a/Mathlib/Logic/Equiv/Option.lean b/Mathlib/Logic/Equiv/Option.lean index 613304a927d412..6f561c0646d018 100644 --- a/Mathlib/Logic/Equiv/Option.lean +++ b/Mathlib/Logic/Equiv/Option.lean @@ -179,7 +179,7 @@ def optionSubtype [DecidableEq β] (x : β) : | some a => simp only [casesOn'_some, Function.comp_apply, Subtype.coe_eta, symm_apply_apply, dite_eq_ite] - exact if_neg (e a).property, + exact ite_eq_right (e a).property, right_inv := fun b => by by_cases h : b = x <;> simp [h] }, rfl⟩ diff --git a/Mathlib/Logic/Equiv/Prod.lean b/Mathlib/Logic/Equiv/Prod.lean index b5fceded97edfb..1b65c394a19379 100644 --- a/Mathlib/Logic/Equiv/Prod.lean +++ b/Mathlib/Logic/Equiv/Prod.lean @@ -317,11 +317,11 @@ def prodExtendRight : Perm (α₁ × β₁) where @[simp] theorem prodExtendRight_apply_eq (b : β₁) : prodExtendRight a e (a, b) = (a, e b) := - if_pos rfl + ite_eq_left rfl theorem prodExtendRight_apply_ne {a a' : α₁} (h : a' ≠ a) (b : β₁) : prodExtendRight a e (a', b) = (a', b) := - if_neg h + ite_eq_right h theorem eq_of_prodExtendRight_ne {e : Perm β₁} {a a' : α₁} {b : β₁} (h : prodExtendRight a e (a', b) ≠ (a', b)) : a' = a := by diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index 93b898d2de8102..10ebd7f6d4fb98 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -227,11 +227,11 @@ protected def union {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Di theorem union_apply_left {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Disjoint s t) {a : (s ∪ t : Set α)} (ha : ↑a ∈ s) : Equiv.Set.union H a = Sum.inl ⟨a, ha⟩ := - dif_pos ha + dite_eq_left ha theorem union_apply_right {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Disjoint s t) {a : (s ∪ t : Set α)} (ha : ↑a ∈ t) : Equiv.Set.union H a = Sum.inr ⟨a, ha⟩ := - dif_neg fun h => Set.disjoint_left.mp H h ha + dite_eq_right fun h => Set.disjoint_left.mp H h ha @[simp] theorem union_symm_apply_left {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Disjoint s t) diff --git a/Mathlib/Logic/Equiv/Sum.lean b/Mathlib/Logic/Equiv/Sum.lean index 56e58fb458c9c0..684c759195ec1f 100644 --- a/Mathlib/Logic/Equiv/Sum.lean +++ b/Mathlib/Logic/Equiv/Sum.lean @@ -246,7 +246,7 @@ def sigmaEquivOptionOfInhabited (α : Type u) [Inhabited α] [DecidableEq α] : snd.left_inv a := by dsimp only; split_ifs <;> simp [*] snd.right_inv | none => by simp - | some ⟨_, ha⟩ => dif_neg ha + | some ⟨_, ha⟩ => dite_eq_right ha end @@ -264,8 +264,8 @@ def sumCompl {α : Type*} (p : α → Prop) [DecidablePred p] : invFun a := if h : p a then Sum.inl ⟨a, h⟩ else Sum.inr ⟨a, h⟩ left_inv := by rintro (⟨x, hx⟩ | ⟨x, hx⟩) <;> dsimp - · rw [dif_pos] - · rw [dif_neg] + · rw [dite_eq_left] + · rw [dite_eq_right] right_inv a := by dsimp split_ifs <;> rfl @@ -283,12 +283,12 @@ theorem sumCompl_apply_inr {α} {p : α → Prop} [DecidablePred p] (x : { a // @[simp] theorem sumCompl_symm_apply_of_pos {α} {p : α → Prop} [DecidablePred p] {a : α} (h : p a) : (sumCompl p).symm a = Sum.inl ⟨a, h⟩ := - dif_pos h + dite_eq_left h @[simp] theorem sumCompl_symm_apply_of_neg {α} {p : α → Prop} [DecidablePred p] {a : α} (h : ¬p a) : (sumCompl p).symm a = Sum.inr ⟨a, h⟩ := - dif_neg h + dite_eq_right h @[simp] theorem sumCompl_symm_apply_pos {α} {p : α → Prop} [DecidablePred p] (x : {x // p x}) : diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index 55aa858a0fb15e..d4ec1ff4a0a8e3 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -313,7 +313,7 @@ theorem injective_comp_right_iff_surjective {γ : Type*} [Nontrivial γ] : have ⟨b₀, hb⟩ := not_forall.mp not_surj classical have := inj (a₁ := fun _ ↦ c) (a₂ := (if · = b₀ then c' else c)) ?_ · simpa using congr_fun this b₀ - ext a; simp only [comp_apply, if_neg fun h ↦ hb ⟨a, h⟩] + ext a; simp only [comp_apply, ite_eq_right fun h ↦ hb ⟨a, h⟩] protected theorem Surjective.right_cancellable (hf : Surjective f) {g₁ g₂ : β → γ} : g₁ ∘ f = g₂ ∘ f ↔ g₁ = g₂ := @@ -498,13 +498,13 @@ theorem Injective.isPartialInv {α β} {f : α → β} (I : Injective f) : IsPar have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none := rfl if h' : ∃ a, f a = b - then by rw [hpi, dif_pos h'] at h + then by rw [hpi, dite_eq_left h'] at h injection h with h subst h apply Classical.choose_spec h' - else by rw [hpi, dif_neg h'] at h; contradiction, + else by rw [hpi, dite_eq_right h'] at h; contradiction, fun e => e ▸ have h : ∃ a', f a' = f a := ⟨_, rfl⟩ - (dif_pos h).trans (congr_arg _ (I <| Classical.choose_spec h))⟩ + (dite_eq_left h).trans (congr_arg _ (I <| Classical.choose_spec h))⟩ @[deprecated (since := "2026-03-11")] alias partialInv_of_injective := Injective.isPartialInv @@ -525,14 +525,14 @@ noncomputable def invFun {α : Sort u} {β} [Nonempty α] (f : α → β) : β fun y ↦ if h : (∃ x, f x = y) then h.choose else Classical.arbitrary α theorem invFun_eq (h : ∃ a, f a = b) : f (invFun f b) = b := by - simp only [invFun, dif_pos h, h.choose_spec] + simp only [invFun, dite_eq_left h, h.choose_spec] theorem apply_invFun_apply {α β : Type*} {f : α → β} {a : α} : f (@invFun _ _ ⟨a⟩ f (f a)) = f a := @invFun_eq _ _ ⟨a⟩ _ _ ⟨_, rfl⟩ theorem invFun_neg (h : ¬∃ a, f a = b) : invFun f b = Classical.choice ‹_› := - dif_neg h + dite_eq_right h theorem invFun_eq_of_injective_of_rightInverse {g : β → α} (hf : Injective f) (hg : RightInverse g f) : invFun f = g := @@ -640,11 +640,11 @@ def update (f : ∀ a, β a) (a' : α) (v : β a') (a : α) : β a := @[simp] theorem update_self (a : α) (v : β a) (f : ∀ a, β a) : update f a v a = v := - dif_pos rfl + dite_eq_left rfl @[simp] theorem update_of_ne {a a' : α} (h : a ≠ a') (v : β a') (f : ∀ a, β a) : update f a' v a = f a := - dif_neg h + dite_eq_right h /-- A congruence lemma for `Function.update`, specialized for the non-dependent case. Without this, @@ -844,7 +844,7 @@ lemma Injective.factorsThrough (hf : Injective f) (g : α → γ) : g.FactorsThr lemma FactorsThrough.extend_apply {g : α → γ} (hf : g.FactorsThrough f) (e' : β → γ) (a : α) : extend f g e' (f a) = g a := by classical - simp only [extend_def, dif_pos, exists_apply_eq_apply] + simp only [extend_def, dite_eq_left, exists_apply_eq_apply] exact hf (Classical.choose_spec (exists_apply_eq_apply f a)) @[simp] @@ -925,7 +925,7 @@ theorem surjective_comp_right_iff_injective {γ : Type*} [Nontrivial γ] : have ⟨f, hf⟩ := surj (if · = a₂ then c else c') have h₁ := congr_fun hf a₁ have h₂ := congr_fun hf a₂ - simp only [comp_apply, if_neg ne, reduceIte] at h₁ h₂ + simp only [comp_apply, ite_eq_right ne, reduceIte] at h₁ h₂ rw [← h₁, eq, h₂] theorem Bijective.comp_right (hf : Bijective f) : Bijective fun g : β → γ ↦ g ∘ f := @@ -1106,7 +1106,7 @@ noncomputable def sometimes {α β} [Nonempty β] (f : α → β) : β := if h : Nonempty α then f (Classical.choice h) else Classical.choice ‹_› theorem sometimes_eq {p : Prop} {α} [Nonempty α] (f : p → α) (a : p) : sometimes f = f a := - dif_pos ⟨a⟩ + dite_eq_left ⟨a⟩ theorem sometimes_spec {p : Prop} {α} [Nonempty α] (P : α → Prop) (f : p → α) (a : p) (h : P (f a)) : P (sometimes f) := by diff --git a/Mathlib/Logic/Hydra.lean b/Mathlib/Logic/Hydra.lean index bb0149f4ab9829..08f75d575cb788 100644 --- a/Mathlib/Logic/Hydra.lean +++ b/Mathlib/Logic/Hydra.lean @@ -66,7 +66,7 @@ theorem cutExpand_le_invImage_lex [DecidableEq α] [Std.Irrefl r] : replace hr := fun a' ↦ mt (hr a') refine ⟨a, fun b h ↦ ?_, ?_⟩ <;> simp_rw [toFinsupp_apply] · apply_fun count b at he - simpa only [count_add, count_singleton, if_neg h.2, add_zero, count_eq_zero.2 (hr b h.1)] + simpa only [count_add, count_singleton, ite_eq_right h.2, add_zero, count_eq_zero.2 (hr b h.1)] using he · apply_fun count a at he simp only [count_add, count_singleton_self, count_eq_zero.2 (hr _ (irrefl_of r a)), diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index 0cf4995802c825..1278e7eb1c4f3f 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -1008,8 +1008,8 @@ theorem Measurable.liminf' {ι ι'} {f : ι → δ → α} {v : Filter ι} (hf : rcases isEmpty_or_nonempty (Subtype p) with hp | hp · simp [hv.liminf_eq_sSup_iUnion_iInter] by_cases H : ∃ (j : Subtype p), s j = ∅ - · simp_rw [hv.liminf_eq_ite, if_pos H, measurable_const] - simp_rw [hv.liminf_eq_ite, if_neg H] + · simp_rw [hv.liminf_eq_ite, ite_eq_left H, measurable_const] + simp_rw [hv.liminf_eq_ite, ite_eq_right H] have : ∀ i, Countable (s i) := fun i ↦ countable_coe_iff.2 (hs i) let m : Subtype p → Set δ := fun j ↦ {x | BddBelow (range (fun (i : s j) ↦ f i x))} have m_meas : ∀ j, MeasurableSet (m j) := @@ -1035,9 +1035,9 @@ theorem Measurable.liminf' {ι ι'} {f : ι → δ → α} {v : Filter ι} (hf : ext x have A : reparam x j = if x ∈ m j then j else g (Nat.find (Z x)) := rfl split_ifs with hjx - · have : reparam x j = j := by rw [A, if_pos hjx] + · have : reparam x j = j := by rw [A, ite_eq_left hjx] simp only [hF1, this] - · have : reparam x j = g (Nat.find (Z x)) := by rw [A, if_neg hjx] + · have : reparam x j = g (Nat.find (Z x)) := by rw [A, ite_eq_right hjx] simp only [hF1, this] rw [this] apply Measurable.piecewise (m_meas j) (F0_meas j) diff --git a/Mathlib/MeasureTheory/Constructions/Cylinders.lean b/Mathlib/MeasureTheory/Constructions/Cylinders.lean index 1e28d660c5adb5..137dffc99e0560 100644 --- a/Mathlib/MeasureTheory/Constructions/Cylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/Cylinders.lean @@ -122,10 +122,10 @@ theorem comap_eval_le_generateFrom_squareCylinders_singleton classical refine ⟨fun j ↦ if hji : j = i then by convert! t else univ, fun j ↦ ?_, ?_⟩ · by_cases hji : j = i - · simp only [hji, eq_mpr_eq_cast, dif_pos] + · simp only [hji, eq_mpr_eq_cast, dite_eq_left] convert! ht simp only [cast_heq] - · simp only [hji, not_false_iff, dif_neg, MeasurableSet.univ] + · simp only [hji, not_false_iff, dite_eq_right, MeasurableSet.univ] · #adaptation_note /-- Before https://github.com/leanprover/lean4/pull/13166 (replacing grind's canonicalizer with a type-directed normalizer), `grind` closed this goal. It is not yet clear whether this is due to defeq abuse in Mathlib or a problem in the new @@ -185,7 +185,7 @@ theorem cylinder_eq_empty_iff [h_nonempty : Nonempty (∀ i, α i)] (s : Finset let f' : ∀ i, α i := fun i ↦ if hi : i ∈ s then f ⟨i, hi⟩ else h_nonempty.some i have hf' : f' ∈ cylinder s S := by rw [mem_cylinder] - simpa only [Finset.restrict_def, Finset.coe_mem, dif_pos, f'] + simpa only [Finset.restrict_def, Finset.coe_mem, dite_eq_left, f'] rw [h] at hf' exact notMem_empty _ hf' diff --git a/Mathlib/MeasureTheory/Constructions/ProjectiveFamilyContent.lean b/Mathlib/MeasureTheory/Constructions/ProjectiveFamilyContent.lean index cfb37b0cffeca7..73c9d6652f9b81 100644 --- a/Mathlib/MeasureTheory/Constructions/ProjectiveFamilyContent.lean +++ b/Mathlib/MeasureTheory/Constructions/ProjectiveFamilyContent.lean @@ -76,7 +76,7 @@ noncomputable def projectiveFamilyFun (P : ∀ J : Finset ι, Measure (Π j : J, lemma projectiveFamilyFun_congr (hP : IsProjectiveMeasureFamily P) (hs : s ∈ measurableCylinders α) (hs_eq : s = cylinder I S) (hS : MeasurableSet S) : projectiveFamilyFun P s = P I S := by - rw [projectiveFamilyFun, dif_pos hs] + rw [projectiveFamilyFun, dite_eq_left hs] exact hP.congr_cylinder (measurableCylinders.measurableSet hs) hS ((measurableCylinders.eq_cylinder hs).symm.trans hs_eq) diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index e44a090dcba719..6d4971ecfc5f96 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -372,13 +372,13 @@ theorem color_lt {i : Ordinal.{u}} (hi : i < p.lastStep) {N : ℕ} have color_G : ∀ n, n ≤ N → p.color (G n) = n := by intro n hn rcases hn.eq_or_lt with (rfl | H) - · simp only [G]; simp only [color_i, Inf_eq_N, if_true] - · simp only [G]; simp only [H.ne, (hg n H).right.right.symm, if_false] + · simp only [G]; simp only [color_i, Inf_eq_N, ite_true] + · simp only [G]; simp only [H.ne, (hg n H).right.right.symm, ite_false] have G_lt_last : ∀ n, n ≤ N → G n < p.lastStep := by intro n hn rcases hn.eq_or_lt with (rfl | H) - · simp only [G]; simp only [hi, if_true] - · simp only [G]; simp only [H.ne, (hg n H).left.trans hi, if_false] + · simp only [G]; simp only [hi, ite_true] + · simp only [G]; simp only [H.ne, (hg n H).left.trans hi, ite_false] have fGn : ∀ n, n ≤ N → p.c (p.index (G n)) ∉ p.iUnionUpTo (G n) ∧ p.R (G n) ≤ p.τ * p.r (p.index (G n)) := by @@ -439,7 +439,7 @@ theorem color_lt {i : Ordinal.{u}} (hi : i < p.lastStep) {N : ℕ} inter := by intro a ha have I : (a : ℕ) < N := ha - have J : G (Fin.last N) = i := by dsimp; simp only [G, if_true] + have J : G (Fin.last N) = i := by dsimp; simp only [G, ite_true] have K : G a = g a := by simp [G, I.ne] convert! dist_le_add_of_nonempty_closedBall_inter_closedBall (hg _ I).2.1 } -- this is a contradiction @@ -939,7 +939,7 @@ theorem exists_closedBall_covering_tsum_measure_le (μ : Measure α) [SFinite μ simp only [mem_iUnion, mem_image] at hx rcases hx with ⟨i, y, _, rfl⟩ exact y.2 - simp only [r, if_pos h'x, (hr1 x h'x).1.1] + simp only [r, ite_eq_left h'x, (hr1 x h'x).1.1] · intro x hx by_cases h'x : x ∈ s' · obtain ⟨i, y, ySi, xy⟩ : ∃ (i : Fin N) (y : ↥s'), y ∈ S i ∧ x ∈ ball (y : α) (r1 y) := by @@ -951,7 +951,7 @@ theorem exists_closedBall_covering_tsum_measure_le (μ : Measure α) [SFinite μ · simp only [mem_iUnion, mem_image] exact ⟨i, y, ySi, rfl⟩ · have : (y : α) ∈ s' := y.2 - simp only [r, if_pos this] + simp only [r, ite_eq_left this] exact ball_subset_closedBall xy · obtain ⟨y, yt0, hxy⟩ : ∃ y : α, y ∈ t0 ∧ x ∈ closedBall y (r0 y) := by simpa [s', hx, -mem_closedBall] using h'x diff --git a/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean b/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean index 30036d8b034b08..e0197b2b7a73a9 100644 --- a/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean +++ b/Mathlib/MeasureTheory/Covering/BesicovitchVectorSpace.lean @@ -463,17 +463,17 @@ theorem exists_normalized {N : ℕ} {τ : ℝ} (a : SatelliteConfig E N τ) (las · rw [norm_sub_rev]; exact this j i inej.symm (le_of_not_ge hij) rcases le_or_gt ‖a.c j‖ 2 with (Hj | Hj) -- case `‖c j‖ ≤ 2` (and therefore also `‖c i‖ ≤ 2`) - · simp_rw [c', Hj, hij.trans Hj, if_true] + · simp_rw [c', Hj, hij.trans Hj, ite_true] exact exists_normalized_aux1 a lastr hτ δ hδ1 hδ2 i j inej -- case `2 < ‖c j‖` · have H'j : ‖a.c j‖ ≤ 2 ↔ False := by simpa only [not_le, iff_false] using Hj rcases le_or_gt ‖a.c i‖ 2 with (Hi | Hi) · -- case `‖c i‖ ≤ 2` - simp_rw [c', Hi, if_true, H'j, if_false] + simp_rw [c', Hi, ite_true, H'j, ite_false] exact exists_normalized_aux2 a lastc lastr hτ δ hδ1 hδ2 i j inej Hi Hj · -- case `2 < ‖c i‖` have H'i : ‖a.c i‖ ≤ 2 ↔ False := by simpa only [not_le, iff_false] using Hi - simp_rw [c', H'i, if_false, H'j, if_false] + simp_rw [c', H'i, ite_false, H'j, ite_false] exact exists_normalized_aux3 a lastc lastr hτ δ hδ1 i j inej Hi hij end SatelliteConfig diff --git a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean index 6dc09757ddf3b1..f4445f820e3ed0 100644 --- a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean +++ b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean @@ -209,11 +209,11 @@ theorem blimsup_cthickening_mul_ae_eq (p : ℕ → Prop) (s : ℕ → Set α) {M ⟨Tendsto.if' hr tendsto_one_div_add_atTop_nhds_zero_nat, Eventually.of_forall fun i => ?_⟩ by_cases hi : 0 < r i · simp [r', hi] - · simp only [r', hi, one_div, mem_Ioi, if_false, inv_pos]; positivity + · simp only [r', hi, one_div, mem_Ioi, ite_false, inv_pos]; positivity have h₀ : ∀ i, p i ∧ 0 < r i → cthickening (r i) (s i) = cthickening (r' i) (s i) := by grind have h₁ : ∀ i, p i ∧ 0 < r i → cthickening (M * r i) (s i) = cthickening (M * r' i) (s i) := by - rintro i ⟨-, hi⟩; simp only [r', hi, if_true] + rintro i ⟨-, hi⟩; simp only [r', hi, ite_true] have h₂ : ∀ i, p i ∧ r i ≤ 0 → cthickening (M * r i) (s i) = cthickening (r i) (s i) := by rintro i ⟨-, hi⟩ have hi' : M * r i ≤ 0 := mul_nonpos_of_nonneg_of_nonpos hM.le hi diff --git a/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean b/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean index 7d9cc492ad554a..14a360ebec1d82 100644 --- a/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean +++ b/Mathlib/MeasureTheory/Function/AEMeasurableSequence.lean @@ -55,7 +55,7 @@ theorem mk_eq_fun_of_mem_aeSeqSet (hf : ∀ i, AEMeasurable (f i) μ) {x : α} ( theorem aeSeq_eq_mk_of_mem_aeSeqSet (hf : ∀ i, AEMeasurable (f i) μ) {x : α} (hx : x ∈ aeSeqSet hf p) (i : ι) : aeSeq hf p i x = (hf i).mk (f i) x := by - simp only [aeSeq, hx, if_true] + simp only [aeSeq, hx, ite_true] theorem aeSeq_eq_fun_of_mem_aeSeqSet (hf : ∀ i, AEMeasurable (f i) μ) {x : α} (hx : x ∈ aeSeqSet hf p) (i : ι) : aeSeq hf p i x = f i x := by @@ -63,7 +63,7 @@ theorem aeSeq_eq_fun_of_mem_aeSeqSet (hf : ∀ i, AEMeasurable (f i) μ) {x : α theorem prop_of_mem_aeSeqSet (hf : ∀ i, AEMeasurable (f i) μ) {x : α} (hx : x ∈ aeSeqSet hf p) : p x fun n => aeSeq hf p n x := by - simp only [aeSeq, hx, if_true] + simp only [aeSeq, hx, ite_true] rw [funext fun n => mk_eq_fun_of_mem_aeSeqSet hf hx n] have h_ss : aeSeqSet hf p ⊆ { x | p x fun n => f n x } := by rw [← compl_compl { x | p x fun n => f n x }, aeSeqSet, Set.compl_subset_compl] @@ -98,7 +98,7 @@ theorem measure_compl_aeSeqSet_eq_zero [Countable ι] (hf : ∀ i, AEMeasurable theorem aeSeq_eq_mk_ae [Countable ι] (hf : ∀ i, AEMeasurable (f i) μ) (hp : ∀ᵐ x ∂μ, p x fun n => f n x) : ∀ᵐ a : α ∂μ, ∀ i : ι, aeSeq hf p i a = (hf i).mk (f i) a := have h_ss : aeSeqSet hf p ⊆ { a : α | ∀ i, aeSeq hf p i a = (hf i).mk (f i) a } := fun x hx i => - by simp only [aeSeq, hx, if_true] + by simp only [aeSeq, hx, ite_true] (ae_iff.2 (measure_compl_aeSeqSet_eq_zero hf hp)).mono h_ss theorem aeSeq_eq_fun_ae [Countable ι] (hf : ∀ i, AEMeasurable (f i) μ) diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean index 049a6f52ee004e..a3d1ba56995da5 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean @@ -124,10 +124,11 @@ meta def condExpUnexpander : Lean.PrettyPrinter.Unexpander #guard_msgs in #check μ[f | m] (sorry : α) -theorem condExp_of_not_le (hm_not : ¬m ≤ m₀) : μ[f | m] = 0 := by rw [condExp, dif_neg hm_not] +theorem condExp_of_not_le (hm_not : ¬m ≤ m₀) : μ[f | m] = 0 := by rw [condExp, dite_eq_right hm_not] theorem condExp_of_not_sigmaFinite (hm : m ≤ m₀) (hμm_not : ¬SigmaFinite (μ.trim hm)) : - μ[f | m] = 0 := by rw [condExp, dif_pos hm, dif_neg]; push Not; exact fun h => absurd h hμm_not + μ[f | m] = 0 := by + rw [condExp, dite_eq_left hm, dite_eq_right (fun h => hμm_not h.1)] open scoped Classical in theorem condExp_of_sigmaFinite (hm : m ≤ m₀) [hμm : SigmaFinite (μ.trim hm)] : @@ -136,12 +137,12 @@ theorem condExp_of_sigmaFinite (hm : m ≤ m₀) [hμm : SigmaFinite (μ.trim hm if StronglyMeasurable[m] f then f else aestronglyMeasurable_condExpL1.mk (condExpL1 hm μ f) else 0 := by - rw [condExp, dif_pos hm] + rw [condExp, dite_eq_left hm] grind theorem condExp_of_stronglyMeasurable (hm : m ≤ m₀) [hμm : SigmaFinite (μ.trim hm)] {f : α → E} (hf : StronglyMeasurable[m] f) (hfi : Integrable f μ) : μ[f | m] = f := by - rw [condExp_of_sigmaFinite hm, if_pos hfi, if_pos hf] + rw [condExp_of_sigmaFinite hm, ite_eq_left hfi, ite_eq_left hf] @[simp] theorem condExp_const (hm : m ≤ m₀) (c : E) [IsFiniteMeasure μ] : @@ -153,13 +154,13 @@ theorem condExp_ae_eq_condExpL1 [CompleteSpace E] μ[f | m] =ᵐ[μ] condExpL1 hm μ f := by rw [condExp_of_sigmaFinite hm] by_cases hfi : Integrable f μ - · rw [if_pos hfi] + · rw [ite_eq_left hfi] by_cases hfm : StronglyMeasurable[m] f - · rw [if_pos hfm] + · rw [ite_eq_left hfm] exact (condExpL1_of_aestronglyMeasurable' hfm.aestronglyMeasurable hfi).symm - · rw [if_neg hfm] + · rw [ite_eq_right hfm] exact aestronglyMeasurable_condExpL1.ae_eq_mk.symm - rw [if_neg hfi, condExpL1_undef hfi] + rw [ite_eq_right hfi, condExpL1_undef hfi] exact (coeFn_zero _ _ _).symm theorem condExp_ae_eq_condExpL1CLM [CompleteSpace E] @@ -173,7 +174,7 @@ theorem condExp_of_not_integrable (hf : ¬Integrable f μ) : μ[f | m] = 0 := by swap; · rw [condExp_of_not_le hm] by_cases hμm : SigmaFinite (μ.trim hm) swap; · rw [condExp_of_not_sigmaFinite hm hμm] - rw [condExp_of_sigmaFinite, if_neg hf] + rw [condExp_of_sigmaFinite, ite_eq_right hf] @[to_fun (attr := simp) condExp_fun_zero] theorem condExp_zero : μ[(0 : α → E) | m] = 0 := by diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean index 2e679c127c22f6..da7bcf32a2f329 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean @@ -157,15 +157,15 @@ variable {hm : m ≤ m0} [SigmaFinite (μ.trim hm)] theorem condExpIndL1_of_measurableSet_of_measure_ne_top (hs : MeasurableSet s) (hμs : μ s ≠ ∞) (x : G) : condExpIndL1 hm μ s x = condExpIndL1Fin hm hs hμs x := by - simp only [condExpIndL1, And.intro hs hμs, dif_pos, Ne, not_false_iff, and_self_iff] + simp only [condExpIndL1, And.intro hs hμs, dite_eq_left, Ne, not_false_iff, and_self_iff] theorem condExpIndL1_of_measure_eq_top (hμs : μ s = ∞) (x : G) : condExpIndL1 hm μ s x = 0 := by - simp only [condExpIndL1, hμs, not_true, Ne, dif_neg, not_false_iff, + simp only [condExpIndL1, hμs, not_true, Ne, dite_eq_right, not_false_iff, and_false] theorem condExpIndL1_of_not_measurableSet (hs : ¬MeasurableSet s) (x : G) : condExpIndL1 hm μ s x = 0 := by - simp only [condExpIndL1, hs, dif_neg, not_false_iff, false_and] + simp only [condExpIndL1, hs, dite_eq_right, not_false_iff, false_and] theorem condExpIndL1_add (x y : G) : condExpIndL1 hm μ s (x + y) = condExpIndL1 hm μ s x + condExpIndL1 hm μ s y := by diff --git a/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean b/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean index 094252c2730d14..b21c7e80621719 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalLExpectation.lean @@ -94,10 +94,10 @@ meta def condLExpUnexpander : Lean.PrettyPrinter.Unexpander #check P⁻[X|mΩ] (sorry : Ω) theorem condLExp_of_not_le (hm_not : ¬mΩ ≤ mΩ₀) : P⁻[X|mΩ] = 0 := by - rw [condLExp, dif_neg hm_not] + rw [condLExp, dite_eq_right hm_not] theorem condLExp_of_not_sigmaFinite (hm : mΩ ≤ mΩ₀) (hμm_not : ¬SigmaFinite (P.trim hm)) : - P⁻[X|mΩ] = 0 := by simp [condLExp, dif_pos hm, hμm_not] + P⁻[X|mΩ] = 0 := by simp [condLExp, dite_eq_left hm, hμm_not] theorem condLExp_eq_self (hm : mΩ ≤ mΩ₀) (P : Measure[mΩ₀] Ω) [hσ : SigmaFinite (P.trim hm)] (hX : Measurable[mΩ] X) : P⁻[X|mΩ] = X := by diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 5895b55e6d15c6..4420b6b246195e 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -895,7 +895,7 @@ noncomputable def withDensitySMulLI {f : α → ℝ≥0} (f_meas : Measurable f) norm_map' := by intro u simp only [eLpNorm, LinearMap.coe_mk, AddHom.coe_mk, - one_ne_zero, ENNReal.one_ne_top, ENNReal.toReal_one, if_false, eLpNorm', ENNReal.rpow_one, + one_ne_zero, ENNReal.one_ne_top, ENNReal.toReal_one, ite_false, eLpNorm', ENNReal.rpow_one, _root_.div_one, Lp.norm_def] rw [lintegral_withDensity_eq_lintegral_mul_non_measurable _ f_meas.coe_nnreal_ennreal (Filter.Eventually.of_forall fun x => ENNReal.coe_lt_top)] diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index 4d153c2f027492..b9b3c2d8ab01cb 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -457,7 +457,7 @@ theorem eLpNorm_enorm_rpow (f : α → ε) (hq_pos : 0 < q) : · simp [h0, ENNReal.zero_rpow_of_pos hq_pos] by_cases hp_top : p = ∞ · simp only [hp_top, eLpNorm_exponent_top, ENNReal.top_mul', hq_pos.not_ge, - ENNReal.ofReal_eq_zero, if_false, eLpNorm_exponent_top, eLpNormEssSup_eq_essSup_enorm] + ENNReal.ofReal_eq_zero, ite_false, eLpNorm_exponent_top, eLpNormEssSup_eq_essSup_enorm] have h_rpow : essSup (‖‖f ·‖ₑ ^ q‖ₑ) μ = essSup (‖f ·‖ₑ ^ q) μ := by congr rw [h_rpow] have h_rpow_mono := ENNReal.strictMono_rpow_of_pos hq_pos diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean index fd5d7b12a712c1..2d6ab457a7ef81 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Count.lean @@ -22,7 +22,7 @@ namespace MeasureTheory @[simp] lemma eLpNorm_dirac (f : α → ε) (i : α) (hp : p ≠ 0) : eLpNorm f p (dirac i) = ‖f i‖ₑ := by - simp_rw [eLpNorm, if_neg hp] + simp_rw [eLpNorm, ite_eq_right hp] split_ifs · simp [eLpNormEssSup, essSup, limsup, limsSup, Set.Ici_def] · simp [eLpNorm', ENNReal.toReal_eq_zero_iff, *] diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/LpNorm.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/LpNorm.lean index 16e1c11f969567..b1df4ce84a62d9 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/LpNorm.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/LpNorm.lean @@ -27,14 +27,14 @@ variable {α E : Type*} {m : MeasurableSpace α} {p : ℝ≥0∞} {q : ℝ} {μ [NormedAddCommGroup E] {f g h : α → E} lemma toReal_eLpNorm (hf : AEStronglyMeasurable f μ) : (eLpNorm f p μ).toReal = lpNorm f p μ := by - rw [lpNorm, if_pos hf] + rw [lpNorm, ite_eq_left hf] lemma ofReal_lpNorm (hf : MemLp f p μ) : .ofReal (lpNorm f p μ) = eLpNorm f p μ := by rw [← toReal_eLpNorm hf.aestronglyMeasurable, ENNReal.ofReal_toReal hf.eLpNorm_ne_top] @[simp] lemma lpNorm_of_not_aestronglyMeasurable (hf : ¬ AEStronglyMeasurable f μ) : lpNorm f p μ = 0 := - if_neg hf + ite_eq_right hf @[simp] lemma lpNorm_of_not_memLp (hf' : ¬ MemLp f p μ) : lpNorm f p μ = 0 := by simp_all [MemLp, lpNorm] diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean index a9a9f4f8b8065e..cad4987086c317 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/TriangleInequality.lean @@ -69,7 +69,7 @@ theorem eLpNorm_add_le' (hf : AEStronglyMeasurable f μ) (hg : AEStronglyMeasura · simp only [eLpNorm_eq_eLpNorm' hp (h'p.trans ENNReal.one_lt_top).ne] convert! eLpNorm'_add_le_of_le_one hf ENNReal.toReal_nonneg _ · have : p ∈ Set.Ioo (0 : ℝ≥0∞) 1 := ⟨hp.bot_lt, h'p⟩ - simp only [LpAddConst, if_pos this] + simp only [LpAddConst, ite_eq_left this] · simpa using ENNReal.toReal_mono ENNReal.one_ne_top h'p.le · simpa [LpAddConst_of_one_le h'p] using eLpNorm_add_le hf hg h'p diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index ca211bf56a3c57..708cf705b9c3ed 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -749,13 +749,13 @@ def restrict (f : α →ₛ β) (s : Set α) : α →ₛ β := theorem restrict_of_not_measurable {f : α →ₛ β} {s : Set α} (hs : ¬MeasurableSet s) : restrict f s = 0 := - dif_neg hs + dite_eq_right hs @[simp] theorem coe_restrict (f : α →ₛ β) {s : Set α} (hs : MeasurableSet s) : ⇑(restrict f s) = indicator s f := by classical - rw [restrict, dif_pos hs, coe_piecewise, coe_zero, piecewise_eq_indicator] + rw [restrict, dite_eq_left hs, coe_piecewise, coe_zero, piecewise_eq_indicator] @[simp] theorem restrict_univ (f : α →ₛ β) : restrict f univ = f := by simp [restrict] @@ -859,7 +859,7 @@ theorem iSup_approx_apply [TopologicalSpace β] [CompleteLattice β] [OrderClose rw [approx_apply a hf] have : k ∈ Finset.range (k + 1) := Finset.mem_range.2 (Nat.lt_succ_self _) refine le_trans (le_of_eq ?_) (Finset.le_sup this) - rw [if_pos hk] + rw [ite_eq_left hk] end Approx diff --git a/Mathlib/MeasureTheory/Group/Measure.lean b/Mathlib/MeasureTheory/Group/Measure.lean index b1c9cd3d3004b3..0a8c5c7a091499 100644 --- a/Mathlib/MeasureTheory/Group/Measure.lean +++ b/Mathlib/MeasureTheory/Group/Measure.lean @@ -698,7 +698,7 @@ theorem measure_univ_of_isMulLeftInvariant [WeaklyLocallyCompactSpace G] [Noncom simp_rw [M] apply ENNReal.Tendsto.mul_const _ (Or.inl ENNReal.top_ne_zero) exact ENNReal.tendsto_nat_nhds_top.comp (tendsto_add_atTop_nat _) - simp only [ENNReal.top_mul', K_pos.ne', if_false] at N + simp only [ENNReal.top_mul', K_pos.ne', ite_false] at N apply top_le_iff.1 exact le_of_tendsto' N fun n => measure_mono (subset_univ _) diff --git a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean index 5aab70490dd61e..598253e209bb7a 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner/Basic.lean @@ -477,7 +477,7 @@ theorem integral_eq_lintegral_pos_part_sub_lintegral_neg_part {f : α → ℝ} ( apply NNReal.eq simp only [Real.coe_toNNReal', coe_nnnorm, nnnorm_neg] rw [Real.norm_of_nonpos (min_le_right _ _), ← max_neg_neg, neg_zero] - rw [eq₁, eq₂, integral, dif_pos, dif_pos] + rw [eq₁, eq₂, integral, dite_eq_left, dite_eq_left] exact L1.integral_eq_norm_posPart_sub _ theorem integral_eq_lintegral_of_nonneg_ae {f : α → ℝ} (hf : 0 ≤ᵐ[μ] f) @@ -903,7 +903,7 @@ variable {H : Type*} [NormedAddCommGroup H] theorem L1.norm_eq_integral_norm (f : α →₁[μ] H) : ‖f‖ = ∫ a, ‖f a‖ ∂μ := by simp only [eLpNorm, eLpNorm'_eq_lintegral_enorm, ENNReal.toReal_one, ENNReal.rpow_one, - Lp.norm_def, if_false, ENNReal.one_ne_top, one_ne_zero, _root_.div_one] + Lp.norm_def, ite_false, ENNReal.one_ne_top, one_ne_zero, _root_.div_one] rw [integral_eq_lintegral_of_nonneg_ae (Eventually.of_forall (by simp [norm_nonneg])) (Lp.aestronglyMeasurable f).norm] simp @@ -1321,7 +1321,7 @@ theorem eLpNorm_one_le_of_le {r : ℝ≥0} (hfint : Integrable f μ) (hfint' : 0 · have : μ Set.univ = ∞ := by by_contra hμ' exact hμ (IsFiniteMeasure.mk <| lt_top_iff_ne_top.2 hμ') - rw [this, ENNReal.mul_top', if_neg, ENNReal.top_mul', if_neg] + rw [this, ENNReal.mul_top', ite_eq_right, ENNReal.top_mul', ite_eq_right] · exact le_top · simp [hr] · simp diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean index 0fba96a44726e2..822c05f1a36d23 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Add.lean @@ -102,7 +102,7 @@ theorem lintegral_iSup' {f : ℕ → α → ℝ≥0∞} (hf : ∀ n, AEMeasurabl intro n m hnm x by_cases hx : x ∈ aeSeqSet hf p · exact aeSeq.prop_of_mem_aeSeqSet hf hx hnm - · simp only [aeSeq, hx, if_false, le_rfl] + · simp only [aeSeq, hx, ite_false, le_rfl] rw [lintegral_congr_ae (aeSeq.iSup hf hp).symm] simp_rw [iSup_apply] rw [lintegral_iSup (aeSeq.measurable hf p) h_ae_seq_mono] @@ -131,7 +131,7 @@ theorem lintegral_iSup_ae {f : ℕ → α → ℝ≥0∞} (hf : ∀ n, Measurabl let ⟨s, hs⟩ := exists_measurable_superset_of_null (ae_iff.1 (ae_all_iff.2 h_mono)) let g n a := if a ∈ s then 0 else f n a have g_eq_f : ∀ᵐ a ∂μ, ∀ n, g n a = f n a := - (measure_eq_zero_iff_ae_notMem.1 hs.2.2).mono fun a ha n => if_neg ha + (measure_eq_zero_iff_ae_notMem.1 hs.2.2).mono fun a ha n => ite_eq_right ha calc ∫⁻ a, ⨆ n, f n a ∂μ = ∫⁻ a, ⨆ n, g n a ∂μ := lintegral_congr_ae <| g_eq_f.mono fun a ha => by simp only [ha] @@ -187,7 +187,7 @@ theorem lintegral_iSup_directed [Countable β] {f : β → α → ℝ≥0∞} (h by_cases hx : x ∈ aeSeqSet hf p · repeat rw [aeSeq.aeSeq_eq_fun_of_mem_aeSeqSet hf hx] apply_rules [hz₁, hz₂] - · simp only [aeSeq, hx, if_false] + · simp only [aeSeq, hx, ite_false] exact le_rfl convert! lintegral_iSup_directed_of_measurable (aeSeq.measurable hf p) h_ae_seq_directed using 1 · simp_rw [← iSup_apply] diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/DominatedConvergence.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/DominatedConvergence.lean index 808e09449c5376..cca0dd0d655e8f 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/DominatedConvergence.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/DominatedConvergence.lean @@ -144,7 +144,7 @@ lemma tendsto_of_lintegral_tendsto_of_monotone_aux {α : Type*} {mα : Measurabl then h.choose else ∞ have hF'_tendsto : ∀ᵐ a ∂μ, Tendsto (fun i ↦ f i a) atTop (𝓝 (F' a)) := by filter_upwards [h_exists] with a ha - simp_rw [F', dif_pos ha] + simp_rw [F', dite_eq_left ha] exact ha.choose_spec suffices F' =ᵐ[μ] F by filter_upwards [this, hF'_tendsto] with a h_eq h_tendsto using h_eq ▸ h_tendsto @@ -223,7 +223,7 @@ lemma tendsto_of_lintegral_tendsto_of_antitone {α : Type*} {mα : MeasurableSpa then h.choose else ∞ have hF'_tendsto : ∀ᵐ a ∂μ, Tendsto (fun i ↦ f i a) atTop (𝓝 (F' a)) := by filter_upwards [h_exists] with a ha - simp_rw [F', dif_pos ha] + simp_rw [F', dite_eq_left ha] exact ha.choose_spec suffices F' =ᵐ[μ] F by filter_upwards [this, hF'_tendsto] with a h_eq h_tendsto using h_eq ▸ h_tendsto diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue/Sub.lean b/Mathlib/MeasureTheory/Integral/Lebesgue/Sub.lean index 14f6f14770cf63..68b6f997b52c33 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue/Sub.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue/Sub.lean @@ -93,7 +93,7 @@ theorem lintegral_iInf' {f : ℕ → α → ℝ≥0∞} (h_meas : ∀ n, AEMeasu intro n m hnm x by_cases hx : x ∈ aeSeqSet h_meas p · exact aeSeq.prop_of_mem_aeSeqSet h_meas hx hnm - · simp only [aeSeq, hx, if_false] + · simp only [aeSeq, hx, ite_false] exact le_rfl rw [lintegral_congr_ae (aeSeq.iInf h_meas hp).symm] simp_rw [iInf_apply] diff --git a/Mathlib/MeasureTheory/Integral/Prod.lean b/Mathlib/MeasureTheory/Integral/Prod.lean index 78ec1994b9fa11..afc6544a02349a 100644 --- a/Mathlib/MeasureTheory/Integral/Prod.lean +++ b/Mathlib/MeasureTheory/Integral/Prod.lean @@ -443,7 +443,7 @@ theorem continuous_integral_integral : of the right-hand side is integrable. -/ theorem integral_prod (f : α × β → E) (hf : Integrable f (μ.prod ν)) : ∫ z, f z ∂μ.prod ν = ∫ x, ∫ y, f (x, y) ∂ν ∂μ := by - by_cases hE : CompleteSpace E; swap; · simp only [integral, dif_neg hE] + by_cases hE : CompleteSpace E; swap; · simp only [integral, dite_eq_right hE] revert f apply Integrable.induction · intro c s hs h2s diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index d6fd2b10144cec..cfc8c8c87bdea2 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -926,12 +926,12 @@ theorem tendsto_setToFun_of_L1 (hT : DominatedFinMeasAdditive μ T C) {ι} (f : filter_upwards [hfsi] with i hi refine lintegral_congr_ae ?_ filter_upwards [hi.coeFn_toL1, hfi.coeFn_toL1] with x hxi hxf - simp_rw [F_lp, dif_pos hi, hxi, f_lp, hxf] + simp_rw [F_lp, dite_eq_left hi, hxi, f_lp, hxf] suffices Tendsto (fun i => setToFun μ T hT (F_lp i)) l (𝓝 (setToFun μ T hT f)) by refine (tendsto_congr' ?_).mp this filter_upwards [hfsi] with i hi suffices h_ae_eq : F_lp i =ᵐ[μ] fs i from setToFun_congr_ae hT h_ae_eq - simp_rw [F_lp, dif_pos hi] + simp_rw [F_lp, dite_eq_left hi] exact hi.coeFn_toL1 rw [setToFun_congr_ae hT hfi.coeFn_toL1.symm] exact ((continuous_setToFun hT).tendsto f_lp).comp tendsto_L1 diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean index 6e3db0bada0198..b4dcc953dcdf15 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Constructions.lean @@ -563,7 +563,7 @@ theorem exists_measurable_piecewise {ι} [Countable ι] [Nonempty ι] (t : ι classical refine ⟨fun x => if hx : x ∈ ⋃ i, t i then f ⟨x, hx⟩ else g default x, hfm.dite ((hg default).comp measurable_subtype_coe) (.iUnion t_meas), fun i x hx => ?_⟩ - simp only [dif_pos (mem_iUnion.2 ⟨i, hx⟩)] + simp only [dite_eq_left (mem_iUnion.2 ⟨i, hx⟩)] exact iUnionLift_of_mem ⟨x, mem_iUnion.2 ⟨i, hx⟩⟩ hx end Prod @@ -746,11 +746,11 @@ theorem measurable_piEquivPiSubtypeProd_symm (p : δ → Prop) [DecidablePred p] Measurable (Equiv.piEquivPiSubtypeProd p X).symm := by refine measurable_pi_iff.2 fun j => ?_ by_cases hj : p j - · simp only [hj, dif_pos, Equiv.piEquivPiSubtypeProd_symm_apply] + · simp only [hj, dite_eq_left, Equiv.piEquivPiSubtypeProd_symm_apply] have : Measurable fun (f : ∀ i : { x // p x }, X i.1) => f ⟨j, hj⟩ := measurable_pi_apply (X := fun i : {x // p x} => X i.1) ⟨j, hj⟩ exact Measurable.comp this measurable_fst - · simp only [hj, Equiv.piEquivPiSubtypeProd_symm_apply, dif_neg, not_false_iff] + · simp only [hj, Equiv.piEquivPiSubtypeProd_symm_apply, dite_eq_right, not_false_iff] have : Measurable fun (f : ∀ i : { x // ¬p x }, X i.1) => f ⟨j, hj⟩ := measurable_pi_apply (X := fun i : {x // ¬p x} => X i.1) ⟨j, hj⟩ exact Measurable.comp this measurable_snd diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index c56e525e1b2784..fcefb8eaa1c137 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -202,7 +202,7 @@ theorem MeasurableSet.ite' {s t : Set α} {p : Prop} (hs : p → MeasurableSet s @[simp, measurability] protected theorem MeasurableSet.cond {s₁ s₂ : Set α} (h₁ : MeasurableSet s₁) - (h₂ : MeasurableSet s₂) {i : Bool} : MeasurableSet (cond i s₁ s₂) := by + (h₂ : MeasurableSet s₂) {i : Bool} : MeasurableSet (if i = true then s₁ else s₂) := by cases i exacts [h₂, h₁] diff --git a/Mathlib/MeasureTheory/Measure/Comap.lean b/Mathlib/MeasureTheory/Measure/Comap.lean index e1c9d6b4c55fb0..fc7c3113d39aaf 100644 --- a/Mathlib/MeasureTheory/Measure/Comap.lean +++ b/Mathlib/MeasureTheory/Measure/Comap.lean @@ -52,7 +52,7 @@ set_option backward.isDefEq.respectTransparency false in theorem comapₗ_apply {_ : MeasurableSpace α} {_ : MeasurableSpace β} (f : α → β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → MeasurableSet (f '' s)) (μ : Measure β) (hs : MeasurableSet s) : comapₗ f μ s = μ (f '' s) := by - rw [comapₗ, dif_pos, liftLinear_apply _ hs, OuterMeasure.comap_apply, coe_toOuterMeasure] + rw [comapₗ, dite_eq_left, liftLinear_apply _ hs, OuterMeasure.comap_apply, coe_toOuterMeasure] exact ⟨hfi, hf⟩ open scoped Classical in @@ -73,17 +73,17 @@ variable {mα : MeasurableSpace α} {mβ : MeasurableSpace β} {mγ : Measurable theorem comap_apply₀ (f : α → β) (μ : Measure β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ) (hs : NullMeasurableSet s (comap f μ)) : comap f μ s = μ (f '' s) := by - rw [comap, dif_pos (And.intro hfi hf)] at hs ⊢ + rw [comap, dite_eq_left (And.intro hfi hf)] at hs ⊢ rw [toMeasure_apply₀ _ _ hs, OuterMeasure.comap_apply, coe_toOuterMeasure] lemma comap_undef {μ : Measure β} (h : ¬ (Injective f ∧ ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ)) : - comap f μ = 0 := dif_neg h + comap f μ = 0 := dite_eq_right h theorem le_comap_apply (f : α → β) (μ : Measure β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ) (s : Set α) : μ (f '' s) ≤ comap f μ s := by - rw [comap, dif_pos (And.intro hfi hf)] + rw [comap, dite_eq_left (And.intro hfi hf)] exact le_toMeasure_apply _ _ _ theorem comap_apply (f : α → β) (hfi : Injective f) @@ -161,7 +161,7 @@ lemma comap_comap (hf' : ∀ s, MeasurableSet s → MeasurableSet (f '' s)) (hg · ext s hs rw [comap_apply _ hf hf' _ hs, comap_apply _ hg hg' _ (hf' _ hs), comap_apply _ (hg.comp hf) (fun t ht ↦ image_comp g f _ ▸ hg' _ <| hf' _ ht) _ hs, image_comp] - · rw [comap, dif_neg <| mt And.left hf, comap, dif_neg fun h ↦ hf h.1.of_comp] + · rw [comap, dite_eq_right <| mt And.left hf, comap, dite_eq_right fun h ↦ hf h.1.of_comp] lemma comap_smul {μ : Measure β} (c : ℝ≥0∞) : comap f (c • μ) = c • comap f μ := by obtain rfl | hc := eq_or_ne c 0 diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean index 61fe8b8a04804a..7bbba0cab0ca3e 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Exhaustion.lean @@ -272,7 +272,7 @@ lemma measure_eq_top_of_subset_compl_sigmaFiniteSetWRT [SFinite ν] sigmaFinite_restrict_sigmaFiniteSetWRT' _ _, fun t ht_subset hνt ↦ measure_eq_top_of_subset_compl_sigmaFiniteSetWRT' ht_subset ?_⟩ exact fun hν't ↦ hνt (hνν' hν't) - rw [Measure.sigmaFiniteSetWRT, dif_pos h] at hs_subset + rw [Measure.sigmaFiniteSetWRT, dite_eq_left h] at hs_subset exact h.choose_spec.2.2 s hs_subset hνs lemma restrict_compl_sigmaFiniteSetWRT [SFinite ν] (hμν : μ ≪ ν) : diff --git a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean index ebed332152835a..5d06087c4dd98f 100644 --- a/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean @@ -85,16 +85,16 @@ section ByDefinition theorem haveLebesgueDecomposition_spec (μ ν : Measure α) [h : HaveLebesgueDecomposition μ ν] : Measurable (μ.rnDeriv ν) ∧ μ.singularPart ν ⟂ₘ ν ∧ μ = μ.singularPart ν + ν.withDensity (μ.rnDeriv ν) := by - rw [singularPart, rnDeriv, dif_pos h, dif_pos h] + rw [singularPart, rnDeriv, dite_eq_left h, dite_eq_left h] exact Classical.choose_spec h.lebesgue_decomposition lemma rnDeriv_of_not_haveLebesgueDecomposition (h : ¬ HaveLebesgueDecomposition μ ν) : μ.rnDeriv ν = 0 := by - rw [rnDeriv, dif_neg h] + rw [rnDeriv, dite_eq_right h] lemma singularPart_of_not_haveLebesgueDecomposition (h : ¬ HaveLebesgueDecomposition μ ν) : μ.singularPart ν = 0 := by - rw [singularPart, dif_neg h] + rw [singularPart, dite_eq_right h] @[fun_prop] theorem measurable_rnDeriv (μ ν : Measure α) : Measurable <| μ.rnDeriv ν := by @@ -197,14 +197,14 @@ theorem singularPart_le (μ ν : Measure α) : μ.singularPart ν ≤ μ := by by_cases hl : HaveLebesgueDecomposition μ ν · conv_rhs => rw [haveLebesgueDecomposition_add μ ν] exact Measure.le_add_right le_rfl - · rw [singularPart, dif_neg hl] + · rw [singularPart, dite_eq_right hl] exact Measure.zero_le μ theorem withDensity_rnDeriv_le (μ ν : Measure α) : ν.withDensity (μ.rnDeriv ν) ≤ μ := by by_cases hl : HaveLebesgueDecomposition μ ν · conv_rhs => rw [haveLebesgueDecomposition_add μ ν] exact Measure.le_add_left le_rfl - · rw [rnDeriv, dif_neg hl, withDensity_zero] + · rw [rnDeriv, dite_eq_right hl, withDensity_zero] exact Measure.zero_le μ lemma _root_.AEMeasurable.singularPart {β : Type*} {_ : MeasurableSpace β} {f : α → β} @@ -371,7 +371,8 @@ theorem lintegral_rnDeriv_lt_top_of_measure_ne_top (ν : Measure α) {s : Set α _ ≤ (singularPart μ ν) (toMeasurable μ s) + _ := le_add_self _ = μ s := by rw [← Measure.add_apply, ← haveLebesgueDecomposition_add, measure_toMeasurable] _ < ⊤ := hs.lt_top - · simp only [Measure.rnDeriv, dif_neg hl, Pi.zero_apply, lintegral_zero, ENNReal.zero_lt_top] + · simp only [Measure.rnDeriv, dite_eq_right hl, Pi.zero_apply, lintegral_zero, + ENNReal.zero_lt_top] theorem lintegral_rnDeriv_lt_top (μ ν : Measure α) [IsFiniteMeasure μ] : ∫⁻ x, μ.rnDeriv ν x ∂ν < ∞ := by @@ -443,7 +444,7 @@ theorem singularPart_smul (μ ν : Measure α) (r : ℝ≥0) : (MutuallySingular.smul r (mutuallySingular_singularPart _ _)) ?_).symm rw [withDensity_smul _ (measurable_rnDeriv _ _), ← smul_add, ← haveLebesgueDecomposition_add μ ν, ENNReal.smul_def] - · rw [singularPart, singularPart, dif_neg hl, dif_neg, smul_zero] + · rw [singularPart, singularPart, dite_eq_right hl, dite_eq_right, smul_zero] refine fun hl' ↦ hl ?_ rw [← inv_smul_smul₀ hr μ] infer_instance @@ -460,7 +461,7 @@ theorem singularPart_smul_right (μ ν : Measure α) (r : ℝ≥0) (hr : r ≠ 0 ext x simp only [Pi.smul_apply] rw [← ENNReal.smul_def, smul_inv_smul₀ hr] - · rw [singularPart, singularPart, dif_neg hl, dif_neg] + · rw [singularPart, singularPart, dite_eq_right hl, dite_eq_right] refine fun hl' ↦ hl ?_ rw [← inv_smul_smul₀ hr ν] infer_instance diff --git a/Mathlib/MeasureTheory/Measure/Dirac.lean b/Mathlib/MeasureTheory/Measure/Dirac.lean index a773c3402a4c98..1bab4f93ab825d 100644 --- a/Mathlib/MeasureTheory/Measure/Dirac.lean +++ b/Mathlib/MeasureTheory/Measure/Dirac.lean @@ -95,8 +95,8 @@ lemma map_const (μ : Measure α) (c : β) : μ.map (fun _ ↦ c) = (μ Set.univ classical rw [Measure.map_apply measurable_const hs, Set.preimage_const] by_cases hsc : c ∈ s - · rw [(Set.indicator_eq_one_iff_mem _).mpr hsc, mul_one, if_pos hsc] - · rw [if_neg hsc, (Set.indicator_eq_zero_iff_notMem _).mpr hsc, measure_empty, mul_zero] + · rw [(Set.indicator_eq_one_iff_mem _).mpr hsc, mul_one, ite_eq_left hsc] + · rw [ite_eq_right hsc, (Set.indicator_eq_zero_iff_notMem _).mpr hsc, measure_empty, mul_zero] @[simp] theorem restrict_singleton (μ : Measure α) (a : α) : μ.restrict {a} = μ {a} • dirac a := by diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 40c6cffbbc9303..65f530816868bc 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -476,13 +476,13 @@ theorem mkMetric_apply (m : ℝ≥0∞ → ℝ≥0∞) (s : Set X) : surjective_id.iInf_congr _ fun t => iInf_congr_Prop Iff.rfl fun ht => ?_ dsimp by_cases htr : ∀ n, ediam (t n) ≤ r - · rw [iInf_eq_if, if_pos htr] + · rw [iInf_eq_if, ite_eq_left htr] congr 1 with n : 1 - simp only [iInf_eq_if, htr n, if_true] - · rw [iInf_eq_if, if_neg htr] + simp only [iInf_eq_if, htr n, ite_true] + · rw [iInf_eq_if, ite_eq_right htr] push Not at htr; rcases htr with ⟨n, hn⟩ refine ENNReal.tsum_eq_top_of_eq_top ⟨n, ?_⟩ - rw [iSup_eq_if, if_pos, iInf_eq_if, if_neg] + rw [iSup_eq_if, ite_eq_left, iInf_eq_if, ite_eq_right] · exact hn.not_ge rcases ediam_pos_iff.1 hn.pos with ⟨x, hx, -⟩ exact ⟨x, hx⟩ diff --git a/Mathlib/MeasureTheory/Measure/LogLikelihoodRatio.lean b/Mathlib/MeasureTheory/Measure/LogLikelihoodRatio.lean index 741320696db561..10d76d1ddf3b94 100644 --- a/Mathlib/MeasureTheory/Measure/LogLikelihoodRatio.lean +++ b/Mathlib/MeasureTheory/Measure/LogLikelihoodRatio.lean @@ -47,19 +47,19 @@ lemma exp_llr (μ ν : Measure α) [SigmaFinite μ] : filter_upwards [Measure.rnDeriv_lt_top μ ν] with x hx by_cases h_zero : μ.rnDeriv ν x = 0 · simp only [llr, h_zero, ENNReal.toReal_zero, log_zero, exp_zero, ite_true] - · rw [llr, exp_log, if_neg h_zero] + · rw [llr, exp_log, ite_eq_right h_zero] exact ENNReal.toReal_pos h_zero hx.ne lemma exp_llr_of_ac (μ ν : Measure α) [SigmaFinite μ] [Measure.HaveLebesgueDecomposition μ ν] (hμν : μ ≪ ν) : (fun x ↦ exp (llr μ ν x)) =ᵐ[μ] fun x ↦ (μ.rnDeriv ν x).toReal := by filter_upwards [hμν.ae_le (exp_llr μ ν), Measure.rnDeriv_pos hμν] with x hx_eq hx_pos - rw [hx_eq, if_neg hx_pos.ne'] + rw [hx_eq, ite_eq_right hx_pos.ne'] lemma exp_llr_of_ac' (μ ν : Measure α) [SigmaFinite μ] [SigmaFinite ν] (hμν : ν ≪ μ) : (fun x ↦ exp (llr μ ν x)) =ᵐ[ν] fun x ↦ (μ.rnDeriv ν x).toReal := by filter_upwards [exp_llr μ ν, Measure.rnDeriv_pos' hμν] with x hx hx_pos - rwa [if_neg hx_pos.ne'] at hx + rwa [ite_eq_right hx_pos.ne'] at hx lemma neg_llr [SigmaFinite μ] [SigmaFinite ν] (hμν : μ ≪ ν) : -llr μ ν =ᵐ[μ] llr ν μ := by diff --git a/Mathlib/MeasureTheory/Measure/Map.lean b/Mathlib/MeasureTheory/Measure/Map.lean index 8c9c5d861fa242..75c929a4434067 100644 --- a/Mathlib/MeasureTheory/Measure/Map.lean +++ b/Mathlib/MeasureTheory/Measure/Map.lean @@ -81,7 +81,7 @@ set_option backward.isDefEq.respectTransparency false in theorem mapₗ_congr {f g : α → β} (hf : Measurable f) (hg : Measurable g) (h : f =ᵐ[μ] g) : mapₗ f μ = mapₗ g μ := by ext1 s hs - simpa only [mapₗ, hf, hg, hs, dif_pos, liftLinear_apply, OuterMeasure.map_apply] + simpa only [mapₗ, hf, hg, hs, dite_eq_left, liftLinear_apply, OuterMeasure.map_apply] using! measure_congr (h.preimage s) open scoped Classical in @@ -147,7 +147,7 @@ variable {f : α → β} lemma map_apply₀ {f : α → β} (hf : AEMeasurable f μ) {s : Set β} (hs : NullMeasurableSet s (map f μ)) : μ.map f s = μ (f ⁻¹' s) := by - rw [map, dif_pos hf, mapₗ, dif_pos hf.measurable_mk] at hs ⊢ + rw [map, dite_eq_left hf, mapₗ, dite_eq_left hf.measurable_mk] at hs ⊢ rw [liftLinear_apply₀ _ hs, measure_congr (hf.ae_eq_mk.preimage s)] rfl diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 4abf42905cf002..43a5034bd31ecf 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -1202,12 +1202,12 @@ lemma inf_apply {s : Set α} (hs : MeasurableSet s) : · refine mem_iUnion.2 ⟨1, ?_⟩ simp [hx, hxt] · simp only [iInf_image, coe_toOuterMeasure, iInf_pair] - rw [tsum_eq_add_tsum_ite 0, tsum_eq_add_tsum_ite 1, if_neg zero_ne_one.symm, + rw [tsum_eq_add_tsum_ite 0, tsum_eq_add_tsum_ite 1, ite_eq_right zero_ne_one.symm, ENNReal.summable.tsum_eq_zero_iff.2 _, add_zero] · exact add_le_add (inf_le_left.trans <| by simp [ht']) (inf_le_right.trans <| by simp [ht']) · simp only [ite_eq_left_iff] intro n hn₁ hn₀ - simp only [ht', if_neg hn₀, if_neg hn₁, measure_empty, le_refl, inf_of_le_left] + simp only [ht', ite_eq_right hn₀, ite_eq_right hn₁, measure_empty, le_refl, inf_of_le_left] · simp only [iInf_image, coe_toOuterMeasure, iInf_pair] -- Conversely, fixing `t' : ℕ → Set α` such that `s ⊆ ⋃ n, t' n`, we construct `t : Set α` -- for which `μ (t ∩ s) + ν (tᶜ ∩ s) ≤ ∑' n, μ (t' n) ⊓ ν (t' n)`. diff --git a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean index 32f7c49a57ec86..fec3590431dbfb 100644 --- a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean @@ -205,7 +205,7 @@ theorem exists_measurable_superset_ae_eq (h : NullMeasurableSet s μ) : simpa only [union_empty] using hst.symm.union this theorem toMeasurable_ae_eq (h : NullMeasurableSet s μ) : toMeasurable μ s =ᵐ[μ] s := by - rw [toMeasurable_def, dif_pos] + rw [toMeasurable_def, dite_eq_left] exact (exists_measurable_superset_ae_eq h).choose_spec.2.2 theorem compl_toMeasurable_compl_ae_eq (h : NullMeasurableSet s μ) : (toMeasurable μ sᶜ)ᶜ =ᵐ[μ] s := diff --git a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean index 96049a26d29acb..e9cb17f2c1a90a 100644 --- a/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/ProbabilityMeasure.lean @@ -463,7 +463,7 @@ theorem self_eq_mass_mul_normalize (s : Set Ω) : μ s = μ.mass * μ.normalize obtain rfl | h := eq_or_ne μ 0 · simp have mass_nonzero : μ.mass ≠ 0 := by rwa [μ.mass_nonzero_iff] - simp only [normalize, dif_neg mass_nonzero] + simp only [normalize, dite_eq_right mass_nonzero] simp [mul_inv_cancel_left₀ mass_nonzero, coeFn_def] theorem self_eq_mass_smul_normalize : μ = μ.mass • μ.normalize.toFiniteMeasure := by diff --git a/Mathlib/MeasureTheory/Measure/Restrict.lean b/Mathlib/MeasureTheory/Measure/Restrict.lean index 1c0d3412b2148b..504650bcb2434b 100644 --- a/Mathlib/MeasureTheory/Measure/Restrict.lean +++ b/Mathlib/MeasureTheory/Measure/Restrict.lean @@ -1019,7 +1019,7 @@ theorem mem_map_indicator_ae_iff_mem_map_restrict_ae_of_zero_mem [Zero β] {t : rw [Measure.restrict_apply' hs, Set.indicator_preimage, Set.ite] simp_rw [Set.compl_union, Set.compl_inter] change μ (((f ⁻¹' t)ᶜ ∪ sᶜ) ∩ ((fun _ => (0 : β)) ⁻¹' t \ s)ᶜ) = 0 ↔ μ ((f ⁻¹' t)ᶜ ∩ s) = 0 - simp only [ht, ← Set.compl_eq_univ_sdiff, compl_compl, if_true, + simp only [ht, ← Set.compl_eq_univ_sdiff, compl_compl, ite_true, Set.preimage_const] simp_rw [Set.union_inter_distrib_right, Set.compl_inter_self s, Set.union_empty] @@ -1028,7 +1028,7 @@ theorem mem_map_indicator_ae_iff_of_zero_notMem [Zero β] {t : Set β} (ht : (0 classical rw [mem_map, mem_ae_iff, Set.indicator_preimage, Set.ite, Set.compl_union, Set.compl_inter] change μ (((f ⁻¹' t)ᶜ ∪ sᶜ) ∩ ((fun _ => (0 : β)) ⁻¹' t \ s)ᶜ) = 0 ↔ μ ((f ⁻¹' t)ᶜ ∪ sᶜ) = 0 - simp only [ht, if_false, Set.compl_empty, Set.empty_sdiff, Set.inter_univ, Set.preimage_const] + simp only [ht, ite_false, Set.compl_empty, Set.empty_sdiff, Set.inter_univ, Set.preimage_const] theorem map_restrict_ae_le_map_indicator_ae [Zero β] (hs : MeasurableSet s) : Filter.map f (ae <| μ.restrict s) ≤ Filter.map (s.indicator f) (ae μ) := by diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index 98fb38f6865f26..5dc773c89827de 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -275,7 +275,7 @@ lemma length_eq [Nonempty R] (s : Set R) : simp [length] lemma length_eq_of_isEmpty [IsEmpty R] (s : Set R) : f.length s = 0 := by - simp only [length, if_pos] + simp only [length, ite_eq_left] @[simp] theorem length_empty : f.length ∅ = 0 := by diff --git a/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean b/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean index a357123ec33ab0..a67d3a6cb3902f 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean @@ -90,7 +90,7 @@ lemma toFinite_eq_zero_iff [SFinite μ] : μ.toFinite = 0 ↔ μ = 0 := by lemma toFinite_zero : Measure.toFinite (0 : Measure α) = 0 := by simp lemma toFinite_eq_self [IsProbabilityMeasure μ] : μ.toFinite = μ := by - rw [Measure.toFinite, Measure.toFiniteAux, if_pos, ProbabilityTheory.cond_univ] + rw [Measure.toFinite, Measure.toFiniteAux, ite_eq_left, ProbabilityTheory.cond_univ] infer_instance instance [SFinite μ] : IsFiniteMeasure μ.toFinite := by diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 41a978e1dd13fb..6dbfc3de293adb 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -407,7 +407,7 @@ noncomputable def disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (j : private theorem disjointOfUnion_coe (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) (j : J) : hC.disjointOfUnion hJ j = (hC.exists_partition_disjointed hJ j).choose.parts := by - rw [disjointOfUnion, dif_pos j.2] + rw [disjointOfUnion, dite_eq_left j.2] lemma pairwiseDisjoint_disjointOfUnion (hC : IsSetSemiring C) (hJ : ↑J ⊆ C) : PairwiseDisjoint J (hC.disjointOfUnion hJ) := by diff --git a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean index 3d94406c186689..ad8ee3442587dc 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Basic.lean @@ -443,7 +443,7 @@ def dirac (x : β) (v : M) : VectorMeasure β M where grind @[simp] lemma dirac_apply_of_mem (hs : MeasurableSet s) (hx : x ∈ s) : dirac x v s = v := - if_pos (And.intro hs hx) + ite_eq_left (And.intro hs hx) @[simp] lemma dirac_apply_of_notMem (hx : x ∉ s) : dirac x v s = 0 := by simp [dirac, hx] @@ -463,9 +463,9 @@ open scoped Classical in def toSignedMeasure (μ : Measure α) [hμ : IsFiniteMeasure μ] : SignedMeasure α where measureOf' s := if MeasurableSet s then μ.real s else 0 empty' := by simp - not_measurable' _ hi := if_neg hi + not_measurable' _ hi := ite_eq_right hi m_iUnion' f hf₁ hf₂ := by - simp only [*, MeasurableSet.iUnion hf₁, if_true, measure_iUnion hf₂ hf₁, measureReal_def] + simp only [*, MeasurableSet.iUnion hf₁, ite_true, measure_iUnion hf₂ hf₁, measureReal_def] rw [ENNReal.tsum_toReal_eq] exacts [(summable_measure_toReal hf₁ hf₂).hasSum, fun _ ↦ measure_ne_top _ _] @@ -476,7 +476,7 @@ theorem toSignedMeasure_apply (μ : Measure α) [hμ : IsFiniteMeasure μ] (i : theorem toSignedMeasure_apply_measurable {μ : Measure α} [IsFiniteMeasure μ] {i : Set α} (hi : MeasurableSet i) : μ.toSignedMeasure i = μ.real i := - if_pos hi + ite_eq_left hi -- Without this lemma, `singularPart_neg` in -- `Mathlib/MeasureTheory/Measure/Decomposition/Lebesgue.lean` is extremely slow @@ -519,11 +519,11 @@ open scoped Classical in def toENNRealVectorMeasure (μ : Measure α) : VectorMeasure α ℝ≥0∞ where measureOf' i := if MeasurableSet i then μ i else 0 empty' := by simp - not_measurable' _ hi := if_neg hi + not_measurable' _ hi := ite_eq_right hi m_iUnion' _ hf₁ hf₂ := by - rw [Summable.hasSum_iff ENNReal.summable, if_pos (MeasurableSet.iUnion hf₁), + rw [Summable.hasSum_iff ENNReal.summable, ite_eq_left (MeasurableSet.iUnion hf₁), MeasureTheory.measure_iUnion hf₂ hf₁] - exact tsum_congr fun n => if_pos (hf₁ n) + exact tsum_congr fun n => ite_eq_left (hf₁ n) open scoped Classical in @[simp] @@ -532,7 +532,7 @@ theorem toENNRealVectorMeasure_apply (μ : Measure α) (i : Set α) : theorem toENNRealVectorMeasure_apply_measurable {μ : Measure α} {i : Set α} (hi : MeasurableSet i) : μ.toENNRealVectorMeasure i = μ i := - if_pos hi + ite_eq_left hi @[simp] theorem toENNRealVectorMeasure_zero : (0 : Measure α).toENNRealVectorMeasure = 0 := by @@ -607,21 +607,21 @@ def map (v : VectorMeasure α M) (f : α → β) : VectorMeasure β M := if hf : Measurable f then { measureOf' := fun s => if MeasurableSet s then v (f ⁻¹' s) else 0 empty' := by simp - not_measurable' := fun _ hi => if_neg hi + not_measurable' := fun _ hi => ite_eq_right hi m_iUnion' := by intro g hg₁ hg₂ convert! v.m_iUnion (fun i => hf (hg₁ i)) fun i j hij => (hg₂ hij).preimage _ - · rw [if_pos (hg₁ _)] - · rw [Set.preimage_iUnion, if_pos (MeasurableSet.iUnion hg₁)] } + · rw [ite_eq_left (hg₁ _)] + · rw [Set.preimage_iUnion, ite_eq_left (MeasurableSet.iUnion hg₁)] } else 0 theorem map_not_measurable {f : α → β} (hf : ¬Measurable f) : v.map f = 0 := - dif_neg hf + dite_eq_right hf theorem map_apply {f : α → β} (hf : Measurable f) {s : Set β} (hs : MeasurableSet s) : v.map f s = v (f ⁻¹' s) := by - rw [map, dif_pos hf] - exact if_pos hs + rw [map, dite_eq_left hf] + exact ite_eq_left hs @[simp] theorem map_id : v.map id = v := @@ -632,7 +632,7 @@ theorem map_zero (f : α → β) : (0 : VectorMeasure α M).map f = 0 := by by_cases hf : Measurable f · ext i hi rw [map_apply _ hf hi, zero_apply, zero_apply] - · exact dif_neg hf + · exact dite_eq_right hf section @@ -714,23 +714,23 @@ open scoped Classical in if hi : MeasurableSet i then { measureOf' := fun s => if MeasurableSet s then v (s ∩ i) else 0 empty' := by simp - not_measurable' := fun _ hi => if_neg hi + not_measurable' := fun _ hi => ite_eq_right hi m_iUnion' := by intro f hf₁ hf₂ convert! v.m_iUnion (fun n => (hf₁ n).inter hi) (hf₂.mono fun i j => Disjoint.mono inf_le_left inf_le_left) - · rw [if_pos (hf₁ _)] - · rw [Set.iUnion_inter, if_pos (MeasurableSet.iUnion hf₁)] } + · rw [ite_eq_left (hf₁ _)] + · rw [Set.iUnion_inter, ite_eq_left (MeasurableSet.iUnion hf₁)] } else 0 theorem restrict_not_measurable {i : Set α} (hi : ¬MeasurableSet i) : v.restrict i = 0 := - dif_neg hi + dite_eq_right hi theorem restrict_apply {i : Set α} (hi : MeasurableSet i) {j : Set α} (hj : MeasurableSet j) : v.restrict i j = v (j ∩ i) := by - rw [restrict, dif_pos hi] - exact if_pos hj + rw [restrict, dite_eq_left hi] + exact ite_eq_left hj @[simp] theorem restrict_apply_univ {i : Set α} : v.restrict i univ = v i := by @@ -756,7 +756,7 @@ theorem restrict_zero {i : Set α} : (0 : VectorMeasure α M).restrict i = 0 := by_cases hi : MeasurableSet i · ext j hj rw [restrict_apply 0 hi hj, zero_apply, zero_apply] - · exact dif_neg hi + · exact dite_eq_right hi theorem restrict_dirac {s : Set α} {x : α} {m : M} (hs : MeasurableSet s) [Decidable (x ∈ s)] : (dirac x m).restrict s = if x ∈ s then dirac x m else 0 := by @@ -811,7 +811,7 @@ theorem map_add (v w : VectorMeasure α M) (f : α → β) : (v + w).map f = v.m by_cases hf : Measurable f · ext i hi simp [map_apply _ hf hi] - · simp [map, dif_neg hf] + · simp [map, dite_eq_right hf] /-- `VectorMeasure.map` as an additive monoid homomorphism. -/ @[simps] @@ -904,7 +904,7 @@ theorem map_smul {v : VectorMeasure α M} {f : α → β} (c : R) : (c • v).ma by_cases hf : Measurable f · ext i hi simp [map_apply _ hf hi] - · simp only [map, dif_neg hf] + · simp only [map, dite_eq_right hf] -- `smul_zero` does not work since we do not require `ContinuousAdd` ext i simp @@ -1327,29 +1327,29 @@ def trim {m n : MeasurableSpace α} (v : VectorMeasure α M) (hle : m ≤ n) : @VectorMeasure α m M _ _ := @VectorMeasure.mk α m M _ _ (fun i => if MeasurableSet[m] i then v i else 0) - (by rw [if_pos (@MeasurableSet.empty _ m), v.empty]) - (fun i hi => by rw [if_neg hi]) + (by rw [ite_eq_left (@MeasurableSet.empty _ m), v.empty]) + (fun i hi => by rw [ite_eq_right hi]) (fun f hf₁ hf₂ => by have hf₁' : ∀ k, MeasurableSet[n] (f k) := fun k => hle _ (hf₁ k) convert! v.m_iUnion hf₁' hf₂ using 1 · ext n - rw [if_pos (hf₁ n)] - · rw [if_pos (@MeasurableSet.iUnion _ _ m _ _ hf₁)]) + rw [ite_eq_left (hf₁ n)] + · rw [ite_eq_left (@MeasurableSet.iUnion _ _ m _ _ hf₁)]) variable {n : MeasurableSpace α} {v : VectorMeasure α M} theorem trim_eq_self : v.trim le_rfl = v := by ext i hi - exact if_pos hi + exact ite_eq_left hi @[simp] theorem zero_trim (hle : m ≤ n) : (0 : VectorMeasure α M).trim hle = 0 := by ext i hi - exact if_pos hi + exact ite_eq_left hi theorem trim_measurableSet_eq (hle : m ≤ n) {i : Set α} (hi : MeasurableSet[m] i) : v.trim hle i = v i := - if_pos hi + ite_eq_left hi theorem restrict_trim (hle : m ≤ n) {i : Set α} (hi : MeasurableSet[m] i) : @VectorMeasure.restrict α m M _ _ (v.trim hle) i = (v.restrict i).trim hle := by diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean index c654aaef8b65ad..8ea15821af4775 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Hahn.lean @@ -109,13 +109,13 @@ private def findExistsOneDivLT (s : SignedMeasure α) (i : Set α) : ℕ := private theorem findExistsOneDivLT_spec (hi : ¬s ≤[i] 0) : ExistsOneDivLT s i (findExistsOneDivLT s i) := by - rw [findExistsOneDivLT, dif_pos hi] + rw [findExistsOneDivLT, dite_eq_left hi] convert! Nat.find_spec (existsNatOneDivLTMeasure_of_not_negative hi) private theorem findExistsOneDivLT_min (hi : ¬s ≤[i] 0) {m : ℕ} (hm : m < findExistsOneDivLT s i) : ¬ExistsOneDivLT s i m := by classical - rw [findExistsOneDivLT, dif_pos hi] at hm + rw [findExistsOneDivLT, dite_eq_left hi] at hm exact Nat.find_min _ hm open scoped Classical in @@ -129,7 +129,7 @@ private theorem someExistsOneDivLT_spec (hi : ¬s ≤[i] 0) : someExistsOneDivLT s i ⊆ i ∧ MeasurableSet (someExistsOneDivLT s i) ∧ (1 / (findExistsOneDivLT s i + 1) : ℝ) < s (someExistsOneDivLT s i) := by - rw [someExistsOneDivLT, dif_pos hi] + rw [someExistsOneDivLT, dite_eq_left hi] exact Classical.choose_spec (findExistsOneDivLT_spec hi) private theorem someExistsOneDivLT_subset : someExistsOneDivLT s i ⊆ i := by @@ -137,7 +137,7 @@ private theorem someExistsOneDivLT_subset : someExistsOneDivLT s i ⊆ i := by · exact let ⟨h, _⟩ := someExistsOneDivLT_spec hi h - · rw [someExistsOneDivLT, dif_neg hi] + · rw [someExistsOneDivLT, dite_eq_right hi] exact Set.empty_subset _ private theorem someExistsOneDivLT_subset' : someExistsOneDivLT s (i \ j) ⊆ i := @@ -148,7 +148,7 @@ private theorem someExistsOneDivLT_measurableSet : MeasurableSet (someExistsOneD · exact let ⟨_, h, _⟩ := someExistsOneDivLT_spec hi h - · rw [someExistsOneDivLT, dif_neg hi] + · rw [someExistsOneDivLT, dite_eq_right hi] exact MeasurableSet.empty private theorem someExistsOneDivLT_lt (hi : ¬s ≤[i] 0) : diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean index 76deafebc304ab..d0cb518acb32ca 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Jordan.lean @@ -121,29 +121,29 @@ theorem real_smul_def (r : ℝ) (j : JordanDecomposition α) : @[simp] theorem coe_smul (r : ℝ≥0) : (r : ℝ) • j = r • j := by - rw [real_smul_def, if_pos (NNReal.coe_nonneg r), Real.toNNReal_coe] + rw [real_smul_def, ite_eq_left (NNReal.coe_nonneg r), Real.toNNReal_coe] theorem real_smul_nonneg (r : ℝ) (hr : 0 ≤ r) : r • j = r.toNNReal • j := - dif_pos hr + dite_eq_left hr theorem real_smul_neg (r : ℝ) (hr : r < 0) : r • j = -((-r).toNNReal • j) := - dif_neg (not_le.2 hr) + dite_eq_right (not_le.2 hr) theorem real_smul_posPart_nonneg (r : ℝ) (hr : 0 ≤ r) : (r • j).posPart = r.toNNReal • j.posPart := by - rw [real_smul_def, ← smul_posPart, if_pos hr] + rw [real_smul_def, ← smul_posPart, ite_eq_left hr] theorem real_smul_negPart_nonneg (r : ℝ) (hr : 0 ≤ r) : (r • j).negPart = r.toNNReal • j.negPart := by - rw [real_smul_def, ← smul_negPart, if_pos hr] + rw [real_smul_def, ← smul_negPart, ite_eq_left hr] theorem real_smul_posPart_neg (r : ℝ) (hr : r < 0) : (r • j).posPart = (-r).toNNReal • j.negPart := by - rw [real_smul_def, ← smul_negPart, if_neg (not_le.2 hr), neg_posPart] + rw [real_smul_def, ← smul_negPart, ite_eq_right (not_le.2 hr), neg_posPart] theorem real_smul_negPart_neg (r : ℝ) (hr : r < 0) : (r • j).negPart = (-r).toNNReal • j.posPart := by - rw [real_smul_def, ← smul_posPart, if_neg (not_le.2 hr), neg_negPart] + rw [real_smul_def, ← smul_posPart, ite_eq_right (not_le.2 hr), neg_negPart] /-- The signed measure associated with a Jordan decomposition. -/ def toSignedMeasure : SignedMeasure α := diff --git a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean index d45d4d5a06fdd5..be8598a7f6d8dd 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Decomposition/Lebesgue.lean @@ -266,7 +266,7 @@ theorem haveLebesgueDecomposition_mk (μ : Measure α) {f : α → ℝ} (hf : Me s.HaveLebesgueDecomposition μ := by by_cases hfi : Integrable f μ · exact haveLebesgueDecomposition_mk' μ hf hfi htμ hadd - · rw [withDensityᵥ, dif_neg hfi, add_zero] at hadd + · rw [withDensityᵥ, dite_eq_right hfi, add_zero] at hadd refine haveLebesgueDecomposition_mk' μ measurable_zero (integrable_zero _ _ μ) htμ ?_ rwa [withDensityᵥ_zero, add_zero] @@ -296,7 +296,7 @@ theorem eq_singularPart (t : SignedMeasure α) (f : α → ℝ) (htμ : t ⟂ᵥ · refine eq_singularPart' t hfi.1.measurable_mk (hfi.congr hfi.1.ae_eq_mk) htμ ?_ convert! hadd using 2 exact WithDensityᵥEq.congr_ae hfi.1.ae_eq_mk.symm - · rw [withDensityᵥ, dif_neg hfi, add_zero] at hadd + · rw [withDensityᵥ, dite_eq_right hfi, add_zero] at hadd refine eq_singularPart' t measurable_zero (integrable_zero _ _ μ) htμ ?_ rwa [withDensityᵥ_zero, add_zero] diff --git a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean index 165e673a4d9498..e5cc95e96d45e6 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/WithDensity.lean @@ -46,11 +46,11 @@ def Measure.withDensityᵥ {m : MeasurableSpace α} (μ : Measure α) (f : α if hf : Integrable f μ then { measureOf' := fun s => if MeasurableSet s then ∫ x in s, f x ∂μ else 0 empty' := by simp - not_measurable' := fun _ hs => if_neg hs + not_measurable' := fun _ hs => ite_eq_right hs m_iUnion' := fun s hs₁ hs₂ => by convert! hasSum_integral_iUnion hs₁ hs₂ hf.integrableOn with n - · rw [if_pos (hs₁ n)] - · rw [if_pos (MeasurableSet.iUnion hs₁)] } + · rw [ite_eq_left (hs₁ n)] + · rw [ite_eq_left (MeasurableSet.iUnion hs₁)] } else 0 open Measure @@ -58,7 +58,9 @@ open Measure variable {f g : α → E} theorem withDensityᵥ_apply (hf : Integrable f μ) {s : Set α} (hs : MeasurableSet s) : - μ.withDensityᵥ f s = ∫ x in s, f x ∂μ := by rw [withDensityᵥ, dif_pos hf]; exact dif_pos hs + μ.withDensityᵥ f s = ∫ x in s, f x ∂μ := by + rw [withDensityᵥ, dite_eq_left hf] + exact ite_eq_left hs @[simp] theorem withDensityᵥ_zero : μ.withDensityᵥ (0 : α → E) = 0 := by @@ -73,7 +75,7 @@ theorem withDensityᵥ_neg : μ.withDensityᵥ (-f) = -μ.withDensityᵥ f := by rw [_root_.neg_apply, withDensityᵥ_apply hf hi, ← integral_neg, withDensityᵥ_apply hf.neg hi] simp only [Pi.neg_apply] - · rw [withDensityᵥ, withDensityᵥ, dif_neg hf, dif_neg, neg_zero] + · rw [withDensityᵥ, withDensityᵥ, dite_eq_right hf, dite_eq_right, neg_zero] rwa [integrable_neg_iff] theorem withDensityᵥ_neg' : (μ.withDensityᵥ fun x => -f x) = -μ.withDensityᵥ f := @@ -113,7 +115,7 @@ theorem withDensityᵥ_smul {𝕜 : Type*} [NontriviallyNormedField 𝕜] [Norme simp only [Pi.smul_apply] · by_cases hr : r = 0 · rw [hr, zero_smul, zero_smul, withDensityᵥ_zero] - · rw [withDensityᵥ, withDensityᵥ, dif_neg hf, dif_neg, smul_zero] + · rw [withDensityᵥ, withDensityᵥ, dite_eq_right hf, dite_eq_right, smul_zero] rwa [integrable_smul_iff hr f] theorem withDensityᵥ_smul' {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 E] @@ -146,7 +148,7 @@ theorem Measure.withDensityᵥ_absolutelyContinuous (μ : Measure α) (f : α · refine VectorMeasure.AbsolutelyContinuous.mk fun i hi₁ hi₂ => ?_ rw [toENNRealVectorMeasure_apply_measurable hi₁] at hi₂ rw [withDensityᵥ_apply hf hi₁, Measure.restrict_zero_set hi₂, integral_zero_measure] - · rw [withDensityᵥ, dif_neg hf] + · rw [withDensityᵥ, dite_eq_right hf] exact VectorMeasure.AbsolutelyContinuous.zero _ /-- Having the same density implies the underlying functions are equal almost everywhere. -/ @@ -162,7 +164,7 @@ theorem WithDensityᵥEq.congr_ae {f g : α → E} (h : f =ᵐ[μ] g) : rw [withDensityᵥ_apply hf hi, withDensityᵥ_apply (hf.congr h) hi] exact integral_congr_ae (ae_restrict_of_ae h) · have hg : ¬Integrable g μ := by intro hg; exact hf (hg.congr h.symm) - rw [withDensityᵥ, withDensityᵥ, dif_neg hf, dif_neg hg] + rw [withDensityᵥ, withDensityᵥ, dite_eq_right hf, dite_eq_right hg] theorem Integrable.withDensityᵥ_eq_iff [CompleteSpace E] {f g : α → E} (hf : Integrable f μ) (hg : Integrable g μ) : diff --git a/Mathlib/ModelTheory/Algebra/Field/Basic.lean b/Mathlib/ModelTheory/Algebra/Field/Basic.lean index 1f48383a3d8b38..5fc371125e17f8 100644 --- a/Mathlib/ModelTheory/Algebra/Field/Basic.lean +++ b/Mathlib/ModelTheory/Algebra/Field/Basic.lean @@ -122,8 +122,8 @@ noncomputable abbrev fieldOfModelField (K : Type*) [Language.ring.Structure K] mulComm.toProp_of_model oneMul.toProp_of_model (fun x hx0 => show x * (dite _ _ _) = _ from - (dif_neg hx0).symm ▸ Classical.choose_spec (existsInv.toProp_of_model x hx0)) - (dif_pos rfl) + (dite_eq_right hx0).symm ▸ Classical.choose_spec (existsInv.toProp_of_model x hx0)) + (dite_eq_left rfl) leftDistrib.toProp_of_model existsPairNE.toProp_of_model diff --git a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean index c8b764647d3eb4..9390161aeafa45 100644 --- a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean +++ b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean @@ -187,7 +187,7 @@ theorem finite_ACF_prime_not_realize_of_ACF_zero_realize have f : ∀ ψ ∈ Theory.ACF 0, { s : Finset Nat.Primes // ∀ q : Nat.Primes, q ∉ s → Theory.ACF q ⊨ᵇ ψ } := by intro ψ hψ - rw [Theory.ACF, Theory.fieldOfChar, Set.union_right_comm, Set.mem_union, if_pos rfl, + rw [Theory.ACF, Theory.fieldOfChar, Set.union_right_comm, Set.mem_union, ite_eq_left rfl, Set.mem_image] at hψ apply Classical.choice rcases hψ with h | ⟨p, hp, rfl⟩ diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index 1d91ab5a2079f7..b781cb1268d3aa 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -226,7 +226,7 @@ theorem listDecode_encode_list (l : List (Σ n, L.BoundedFormula α n)) : | falsum => intro l; rw [listEncode, singleton_append, listDecode] | equal => intro l - rw [listEncode, cons_append, cons_append, listDecode, dif_pos] + rw [listEncode, cons_append, cons_append, listDecode, dite_eq_left] · simp only [eq_mp_eq_cast, cast_eq, nil_append] · simp only | @rel φ_n φ_l φ_R ts => @@ -242,10 +242,10 @@ theorem listDecode_encode_list (l : List (Σ n, L.BoundedFormula α n)) : rw [getElem_append_left, getElem_map] · simp only [getElem_finRange, cast_mk, Fin.eta, Function.comp_apply, Sum.getLeft?_inl] · simp only [length_map, length_finRange, is_lt] - rw [dif_pos] + rw [dite_eq_left] swap · exact fun i => Option.isSome_iff_exists.2 ⟨⟨_, ts i⟩, h i⟩ - rw [dif_pos] + rw [dite_eq_left] swap · intro i obtain ⟨h1, h2⟩ := Option.eq_some_iff_get_eq.1 (h i) diff --git a/Mathlib/ModelTheory/LanguageMap.lean b/Mathlib/ModelTheory/LanguageMap.lean index b95a9c0830ea6f..379911068b00f0 100644 --- a/Mathlib/ModelTheory/LanguageMap.lean +++ b/Mathlib/ModelTheory/LanguageMap.lean @@ -267,10 +267,10 @@ theorem Injective.isExpansionOn_default {ϕ : L →ᴸ L'} let := ϕ.defaultExpansion M refine ⟨fun {n} f xs => ?_, fun {n} r xs => ?_⟩ · have hf : ϕ.onFunction f ∈ Set.range fun f : L.Functions n => ϕ.onFunction f := ⟨f, rfl⟩ - refine (dif_pos hf).trans ?_ + refine (dite_eq_left hf).trans ?_ rw [h.onFunction hf.choose_spec] · have hr : ϕ.onRelation r ∈ Set.range fun r : L.Relations n => ϕ.onRelation r := ⟨r, rfl⟩ - refine (dif_pos hr).trans ?_ + refine (dite_eq_left hr).trans ?_ rw [h.onRelation hr.choose_spec] end LHom diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index 18e86ea15e52f5..a9e104f25f606f 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -425,7 +425,7 @@ theorem realize_liftAt_one_self {n : ℕ} {φ : L.BoundedFormula α n} {v : α {xs : Fin (n + 1) → M} : (φ.liftAt 1 n).Realize v xs ↔ φ.Realize v (xs ∘ castSucc) := by rw [realize_liftAt_one (refl n), iff_eq_eq] refine congr rfl (congr rfl (funext fun i => ?_)) - rw [if_pos i.is_lt] + rw [ite_eq_left i.is_lt] @[simp] theorem realize_subst {φ : L.BoundedFormula α n} {tf : α → L.Term β} {v : β → M} {xs : Fin n → M} : diff --git a/Mathlib/NumberTheory/AbelSummation.lean b/Mathlib/NumberTheory/AbelSummation.lean index af5755b62443ac..95478f167ffeb2 100644 --- a/Mathlib/NumberTheory/AbelSummation.lean +++ b/Mathlib/NumberTheory/AbelSummation.lean @@ -385,8 +385,9 @@ theorem summable_mul_of_bigO_atTop' have h : ∀ n, ∑ k ∈ Icc 1 n, ‖c k‖ = ∑ k ∈ Icc 0 n, ‖(fun n ↦ if n = 0 then 0 else c n) k‖ := by intro n rw [Icc_eq_cons_Ioc n.zero_le, sum_cons, ← Icc_add_one_left_eq_Ioc, zero_add] - simp_rw [if_pos, norm_zero, zero_add] - exact Finset.sum_congr rfl fun _ h ↦ by rw [if_neg (zero_lt_one.trans_le (mem_Icc.mp h).1).ne'] + simp_rw [ite_eq_left, norm_zero, zero_add] + exact Finset.sum_congr rfl fun _ h ↦ by + rw [ite_eq_right (zero_lt_one.trans_le (mem_Icc.mp h).1).ne'] simp_rw [h] at h_bdd hg₁ refine Summable.congr_atTop (summable_mul_of_bigO_atTop_aux (fun n ↦ if n = 0 then 0 else c n) 1 h_bdd (by rwa [Nat.cast_one]) (fun n ↦ ?_) hg₁ hg₂) ?_ @@ -394,6 +395,6 @@ theorem summable_mul_of_bigO_atTop' (fun _ ht ↦ hf_diff _ ht.1) (hf_int.integrableOn_compact_subset Set.Icc_subset_Ici_self isCompact_Icc) · filter_upwards [eventually_ne_atTop 0] with k hk - simp_rw [if_neg hk] + simp_rw [ite_eq_right hk] end summable diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean b/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean index d6aa067bbf6b58..f638a0b747f2fb 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Defs.lean @@ -107,7 +107,7 @@ theorem one_one : (1 : ArithmeticFunction R) 1 = 1 := @[simp] theorem one_apply_ne {x : ℕ} (h : x ≠ 1) : (1 : ArithmeticFunction R) x = 0 := - if_neg h + ite_eq_right h end One @@ -363,17 +363,17 @@ def dirichletInverseFun (n : ℕ) : R := @[simp] theorem dirichletInverseFun_apply_zero : dirichletInverseFun f hf 0 = 0 := by - rw [dirichletInverseFun, if_pos rfl] + rw [dirichletInverseFun, ite_eq_left rfl] @[simp] theorem dirichletInverseFun_apply_one : dirichletInverseFun f hf 1 = ⅟(f 1) := by - rw [dirichletInverseFun, if_neg one_ne_zero, if_pos rfl] + rw [dirichletInverseFun, ite_eq_right one_ne_zero, ite_eq_left rfl] @[simp] theorem dirichletInverseFun_apply_ne {n : ℕ} (hn0 : n ≠ 0) (hn1 : n ≠ 1) : dirichletInverseFun f hf n = - ⅟(f 1) * ∑ d ∈ n.properDivisors, f (n / d) * dirichletInverseFun f hf d := by - rw [dirichletInverseFun, if_neg hn0, if_neg hn1] + rw [dirichletInverseFun, ite_eq_right hn0, ite_eq_right hn1] conv_rhs => rw [← Finset.sum_attach, Finset.attach_eq_univ] /-- Given an inverse of `f 1`, construct the Dirichlet inverse of `f`. -/ diff --git a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean index 88641b892b3523..27326b9db3be3a 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/LFunction.lean @@ -134,7 +134,7 @@ noncomputable def ofPowerSeries (q : ℕ) : PowerSeries R →ₐ[R] ArithmeticFu set_option backward.isDefEq.respectTransparency.types false in theorem ofPowerSeries_apply {q : ℕ} (hq : 1 < q) (f : PowerSeries R) (n : ℕ) : ofPowerSeries q f n = Function.extend (q ^ ·) (f.coeff ·) 0 n := by - simp [ofPowerSeries, dif_pos hq] + simp [ofPowerSeries, dite_eq_left hq] theorem ofPowerSeries_apply_pow {q : ℕ} (hq : 1 < q) (f : PowerSeries R) (k : ℕ) : ofPowerSeries q f (q ^ k) = f.coeff k := by @@ -150,7 +150,7 @@ theorem ofPowerSeries_apply_one (q : ℕ) (f : PowerSeries R) : ofPowerSeries q f 1 = f.constantCoeff := by by_cases hq : 1 < q · rw [← pow_zero q, ofPowerSeries_apply_pow hq, PowerSeries.coeff_zero_eq_constantCoeff] - · simp [ofPowerSeries, dif_neg hq] + · simp [ofPowerSeries, dite_eq_right hq] end CommSemiring diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Liouville.lean b/Mathlib/NumberTheory/ArithmeticFunction/Liouville.lean index ef6215ebb9ac1c..72f70aaee6aade 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Liouville.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Liouville.lean @@ -29,7 +29,7 @@ def liouville : ArithmeticFunction ℤ where map_zero' := by simp theorem liouville_apply {n : ℕ} (h : n ≠ 0) : liouville n = (-1) ^ cardFactors n := - if_neg h + ite_eq_right h theorem liouville_ne_zero {n : ℕ} (h : n ≠ 0) : liouville n ≠ 0 := by simp [liouville_apply h] diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean index 24db3b4f1f748f..1fef5111e19ad2 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean @@ -52,7 +52,7 @@ section ProdPrimeFactors /-- The map $n \mapsto \prod_{p \mid n} f(p)$ as an arithmetic function -/ def prodPrimeFactors [CommMonoidWithZero R] (f : ℕ → R) : ArithmeticFunction R where toFun d := if d = 0 then 0 else ∏ p ∈ d.primeFactors, f p - map_zero' := if_pos rfl + map_zero' := ite_eq_left rfl open Batteries.ExtendedBinder @@ -64,7 +64,7 @@ scoped macro_rules (kind := bigproddvd) @[simp] theorem prodPrimeFactors_apply [CommMonoidWithZero R] {f : ℕ → R} {n : ℕ} (hn : n ≠ 0) : ∏ᵖ p ∣ n, f p = ∏ p ∈ n.primeFactors, f p := - if_neg hn + ite_eq_right hn namespace IsMultiplicative diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean b/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean index 9e6355da4e175f..0dbbe7b2aa95fb 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean @@ -58,11 +58,11 @@ open scoped Moebius @[simp] theorem moebius_apply_of_squarefree {n : ℕ} (h : Squarefree n) : μ n = (-1) ^ cardFactors n := - if_pos h + ite_eq_left h @[simp] theorem moebius_eq_zero_of_not_squarefree {n : ℕ} (h : ¬Squarefree n) : μ n = 0 := - if_neg h + ite_eq_right h theorem moebius_apply_one : μ 1 = 1 := by simp @@ -120,7 +120,7 @@ theorem moebius_apply_prime_pow {p k : ℕ} (hp : p.Prime) (hk : k ≠ 0) : theorem moebius_apply_isPrimePow_not_prime {n : ℕ} (hn : IsPrimePow n) (hn' : ¬n.Prime) : μ n = 0 := by obtain ⟨p, k, hp, hk, rfl⟩ := (isPrimePow_nat_iff _).1 hn - rw [moebius_apply_prime_pow hp hk.ne', if_neg] + rw [moebius_apply_prime_pow hp hk.ne', ite_eq_right] rintro rfl exact hn' (by simpa) @@ -208,8 +208,8 @@ set_option backward.isDefEq.respectTransparency false in theorem sum_eq_iff_sum_smul_moebius_eq [AddCommGroup R] {f g : ℕ → R} : (∀ n > 0, ∑ i ∈ n.divisors, f i = g n) ↔ ∀ n > 0, ∑ x ∈ n.divisorsAntidiagonal, μ x.fst • g x.snd = f n := by - let f' : ArithmeticFunction R := ⟨fun x => if x = 0 then 0 else f x, if_pos rfl⟩ - let g' : ArithmeticFunction R := ⟨fun x => if x = 0 then 0 else g x, if_pos rfl⟩ + let f' : ArithmeticFunction R := ⟨fun x => if x = 0 then 0 else f x, ite_eq_left rfl⟩ + let g' : ArithmeticFunction R := ⟨fun x => if x = 0 then 0 else g x, ite_eq_left rfl⟩ trans (ζ : ArithmeticFunction ℤ) • f' = g' · rw [ArithmeticFunction.ext_iff] apply forall_congr' @@ -219,7 +219,7 @@ theorem sum_eq_iff_sum_smul_moebius_eq [AddCommGroup R] {f g : ℕ → R} : | succ n => rw [coe_zeta_smul_apply] simp only [forall_prop_of_true, succ_pos', f', g', coe_mk, succ_ne_zero, ite_false] - rw [sum_congr rfl fun x hx => if_neg (pos_of_mem_divisors hx).ne'] + rw [sum_congr rfl fun x hx => ite_eq_right (pos_of_mem_divisors hx).ne'] trans μ • g' = f' · constructor <;> intro h <;> simp only [← h, ← mul_smul, moebius_mul_coe_zeta, coe_zeta_mul_moebius, one_smul] @@ -232,7 +232,7 @@ theorem sum_eq_iff_sum_smul_moebius_eq [AddCommGroup R] {f g : ℕ → R} : simp only [forall_prop_of_true, succ_pos', smul_apply, f', g', coe_mk, succ_ne_zero, ite_false] rw [sum_congr rfl fun x hx => ?_] - rw [if_neg (pos_of_mem_divisors (snd_mem_divisors_of_mem_antidiagonal hx)).ne'] + rw [ite_eq_right (pos_of_mem_divisors (snd_mem_divisors_of_mem_antidiagonal hx)).ne'] /-- Möbius inversion for functions to a `Ring`. -/ theorem sum_eq_iff_sum_mul_moebius_eq [NonAssocRing R] {f g : ℕ → R} : @@ -262,15 +262,15 @@ theorem prod_eq_iff_prod_pow_moebius_eq_of_nonzero [CommGroupWithZero R] {f g : if h : 0 < n then Units.mk0 (g n) (hg n h) else 1)) (forall_congr' fun n => ?_) <;> refine imp_congr_right fun hn => ?_ - · rw [dif_pos hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, + · rw [dite_eq_left hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, prod_congr rfl _] intro x hx - rw [dif_pos (pos_of_mem_divisors hx), Units.coeHom_apply, Units.val_mk0] - · rw [dif_pos hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, + rw [dite_eq_left (pos_of_mem_divisors hx), Units.coeHom_apply, Units.val_mk0] + · rw [dite_eq_left hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, prod_congr rfl _] intro x hx - rw [dif_pos (pos_of_mem_divisors (snd_mem_divisors_of_mem_antidiagonal hx)), Units.coeHom_apply, - Units.val_zpow_eq_zpow_val, Units.val_mk0] + rw [dite_eq_left (pos_of_mem_divisors (snd_mem_divisors_of_mem_antidiagonal hx)), + Units.coeHom_apply, Units.val_zpow_eq_zpow_val, Units.val_mk0] /-- Möbius inversion for functions to an `AddCommGroup`, where the equalities only hold on a well-behaved set. -/ @@ -346,14 +346,14 @@ theorem prod_eq_iff_prod_pow_moebius_eq_on_of_nonzero [CommGroupWithZero R] s hs)) (forall_congr' fun n => ?_) <;> refine imp_congr_right fun hn => ?_ - · rw [dif_pos hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, + · rw [dite_eq_left hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, prod_congr rfl _] intro x hx - rw [dif_pos (pos_of_mem_divisors hx), Units.coeHom_apply, Units.val_mk0] - · rw [dif_pos hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, + rw [dite_eq_left (pos_of_mem_divisors hx), Units.coeHom_apply, Units.val_mk0] + · rw [dite_eq_left hn, ← Units.val_inj, ← Units.coeHom_apply, map_prod, Units.val_mk0, prod_congr rfl _] intro x hx - rw [dif_pos (pos_of_mem_divisors (snd_mem_divisors_of_mem_antidiagonal hx)), + rw [dite_eq_left (pos_of_mem_divisors (snd_mem_divisors_of_mem_antidiagonal hx)), Units.coeHom_apply, Units.val_zpow_eq_zpow_val, Units.val_mk0] end ArithmeticFunction diff --git a/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean b/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean index 4cc8c9d13c1e3b..f0587555fbb762 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/VonMangoldt.lean @@ -63,7 +63,7 @@ This is also available in the `ArithmeticFunction.vonMangoldt` locale, allowing access to the notation. -/ noncomputable def vonMangoldt : ArithmeticFunction ℝ := - ⟨fun n => if IsPrimePow n then Real.log (minFac n) else 0, if_neg not_isPrimePow_zero⟩ + ⟨fun n => if IsPrimePow n then Real.log (minFac n) else 0, ite_eq_right not_isPrimePow_zero⟩ @[inherit_doc] scoped[ArithmeticFunction] notation "Λ" => ArithmeticFunction.vonMangoldt @@ -87,7 +87,7 @@ theorem vonMangoldt_apply_pow {n k : ℕ} (hk : k ≠ 0) : Λ (n ^ k) = Λ n := simp only [vonMangoldt_apply, isPrimePow_pow_iff hk, pow_minFac hk] theorem vonMangoldt_apply_prime {p : ℕ} (hp : p.Prime) : Λ p = Real.log p := by - rw [vonMangoldt_apply, Prime.minFac_eq hp, if_pos hp.prime.isPrimePow] + rw [vonMangoldt_apply, Prime.minFac_eq hp, ite_eq_left hp.prime.isPrimePow] theorem vonMangoldt_ne_zero_iff {n : ℕ} : Λ n ≠ 0 ↔ IsPrimePow n := by rcases eq_or_ne n 1 with (rfl | hn); · simp [not_isPrimePow_one] diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean index 86f4dffaaa4e92..40f1276743a9d8 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean @@ -50,7 +50,7 @@ theorem zeta_apply {x : ℕ} : ζ x = if x = 0 then 0 else 1 := rfl theorem zeta_apply_ne {x : ℕ} (h : x ≠ 0) : ζ x = 1 := - if_neg h + ite_eq_right h set_option backward.isDefEq.respectTransparency false in theorem zeta_eq_zero {x : ℕ} : ζ x = 0 ↔ x = 0 := by simp [zeta] @@ -146,7 +146,7 @@ def ppow (f : ArithmeticFunction R) (k : ℕ) : ArithmeticFunction R := set_option backward.isDefEq.respectTransparency false in @[simp] -theorem ppow_zero {f : ArithmeticFunction R} : f.ppow 0 = ζ := by rw [ppow, dif_pos rfl] +theorem ppow_zero {f : ArithmeticFunction R} : f.ppow 0 = ζ := by rw [ppow, dite_eq_left rfl] @[simp] theorem ppow_one {f : ArithmeticFunction R} : f.ppow 1 = f := by @@ -155,7 +155,7 @@ theorem ppow_one {f : ArithmeticFunction R} : f.ppow 1 = f := by set_option backward.isDefEq.respectTransparency false in @[simp] theorem ppow_apply {f : ArithmeticFunction R} {k x : ℕ} (kpos : 0 < k) : f.ppow k x = f x ^ k := by - rw [ppow, dif_neg (Nat.ne_of_gt kpos), coe_mk] + rw [ppow, dite_eq_right (Nat.ne_of_gt kpos), coe_mk] theorem ppow_succ' {f : ArithmeticFunction R} {k : ℕ} : f.ppow (k + 1) = f.pmul (f.ppow k) := by ext x diff --git a/Mathlib/NumberTheory/Bernoulli.lean b/Mathlib/NumberTheory/Bernoulli.lean index 8382b79b7c72fa..2f8050fad1a9bc 100644 --- a/Mathlib/NumberTheory/Bernoulli.lean +++ b/Mathlib/NumberTheory/Bernoulli.lean @@ -231,7 +231,7 @@ theorem sum_bernoulli (n : ℕ) : | succ n => suffices (∑ i ∈ range n, ↑((n + 2).choose (i + 2)) * bernoulli (i + 2)) = n / 2 by simp only [this, sum_range_succ', cast_succ, bernoulli_one, bernoulli_zero, choose_one_right, - mul_one, choose_zero_right, cast_zero, if_false, zero_add, succ_succ_ne_one] + mul_one, choose_zero_right, cast_zero, ite_false, zero_add, succ_succ_ne_one] ring have f := sum_bernoulli' n.succ.succ simp_rw [sum_range_succ', cast_succ, ← eq_sub_iff_add_eq] at f @@ -247,7 +247,7 @@ theorem bernoulli_spec' (n : ℕ) : (∑ k ∈ antidiagonal n, ((k.1 + k.2).choose k.2 : ℚ) / (k.2 + 1) * bernoulli k.1) = if n = 0 then 1 else 0 := by cases n with | zero => simp | succ n => - rw [if_neg (succ_ne_zero _)] + rw [ite_eq_right (succ_ne_zero _)] -- algebra facts have h₁ : (1, n) ∈ antidiagonal n.succ := by simp [mem_antidiagonal, add_comm] have h₃ : (1 + n).choose n = n + 1 := by simp [add_comm] @@ -273,12 +273,12 @@ theorem bernoulliPowerSeries_mul_exp_sub_one : bernoulliPowerSeries A * (exp A - -- constant coefficient is a special case cases n with | zero => simp | succ n => simp only [bernoulliPowerSeries, coeff_mul, coeff_X, sum_antidiagonal_succ', one_div, coeff_mk, - coeff_one, coeff_exp, map_sub, factorial, if_pos, cast_succ, cast_mul, - sub_zero, add_eq_zero, if_false, one_ne_zero, and_false, ← map_mul, ← map_sum] + coeff_one, coeff_exp, map_sub, factorial, ite_eq_left, cast_succ, cast_mul, + sub_zero, add_eq_zero, ite_false, one_ne_zero, and_false, ← map_mul, ← map_sum] cases n with | zero => simp | succ n => - rw [if_neg n.succ_succ_ne_one] + rw [ite_eq_right n.succ_succ_ne_one] have hfact : ∀ m, (m ! : ℚ) ≠ 0 := fun m => mod_cast factorial_ne_zero m - have hite2 : ite (n.succ = 0) 1 0 = (0 : ℚ) := if_neg n.succ_ne_zero + have hite2 : ite (n.succ = 0) 1 0 = (0 : ℚ) := ite_eq_right n.succ_ne_zero simp only [CharP.cast_eq_zero, zero_add, inv_one, map_one, sub_self, mul_zero] rw [← map_zero (algebraMap ℚ A), ← zero_div (n.succ ! : ℚ), ← hite2, ← bernoulli_spec', sum_div] refine congr_arg (algebraMap ℚ A) (sum_congr rfl fun x h => eq_div_of_mul_eq (hfact n.succ) ?_) diff --git a/Mathlib/NumberTheory/BernoulliPolynomials.lean b/Mathlib/NumberTheory/BernoulliPolynomials.lean index 21a770d7a26655..b7332181703408 100644 --- a/Mathlib/NumberTheory/BernoulliPolynomials.lean +++ b/Mathlib/NumberTheory/BernoulliPolynomials.lean @@ -80,7 +80,7 @@ theorem bernoulli_one : bernoulli 1 = X - C 2⁻¹ := by @[simp] theorem bernoulli_eval_zero (n : ℕ) : (bernoulli n).eval 0 = _root_.bernoulli n := by - rw [← coeff_zero_eq_eval_zero, coeff_bernoulli, if_pos (Nat.zero_le n), Nat.sub_zero, + rw [← coeff_zero_eq_eval_zero, coeff_bernoulli, ite_eq_left (Nat.zero_le n), Nat.sub_zero, Nat.choose_zero_right, Nat.cast_one, mul_one] @[simp] @@ -289,7 +289,7 @@ theorem bernoulli_generating_function (t : A) : -- factorials and binomial coefficients between ℕ and ℚ and A. intro i hi -- deal with coefficients of e^X-1 - simp only [Nat.cast_choose ℚ (mem_range_le hi), coeff_mk, if_neg (mem_range_sub_ne_zero hi), + simp only [Nat.cast_choose ℚ (mem_range_le hi), coeff_mk, ite_eq_right (mem_range_sub_ne_zero hi), PowerSeries.coeff_one, coeff_exp, sub_zero, Algebra.smul_def, mul_right_comm _ ((aeval t) _), ← mul_assoc, ← map_mul, ← Polynomial.C_eq_algebraMap, Polynomial.aeval_mul, Polynomial.aeval_C] diff --git a/Mathlib/NumberTheory/ClassNumber/Finite.lean b/Mathlib/NumberTheory/ClassNumber/Finite.lean index 9dc1ed8c70ff59..3d9bd5728d8060 100644 --- a/Mathlib/NumberTheory/ClassNumber/Finite.lean +++ b/Mathlib/NumberTheory/ClassNumber/Finite.lean @@ -235,7 +235,7 @@ theorem exists_mem_finsetApprox (a : S) {b} (hb : b ≠ (0 : R)) : congr simp_rw [map_sum, map_sub, map_smul, Finset.sum_apply', Finsupp.sub_apply, Finsupp.smul_apply, Finset.sum_sub_distrib, Basis.repr_self_apply, - smul_eq_mul, mul_boole, Finset.sum_ite_eq', Finset.mem_univ, if_true] + smul_eq_mul, mul_boole, Finset.sum_ite_eq', Finset.mem_univ, ite_true] · exact mod_cast ε_le /-- We can approximate `a / b : L` with `q / r`, where `r` has finitely many options for `L`. -/ diff --git a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean index 0f40c346fad4e0..7750f59a319b98 100644 --- a/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean +++ b/Mathlib/NumberTheory/Cyclotomic/CyclotomicCharacter.lean @@ -278,7 +278,7 @@ theorem toFun_apply : cyclotomicCharacter.toFun p g = PadicInt.ofIntSeq _ (PadicInt.isCauSeq_padicNorm_of_pow_dvd_sub (aux g <| p ^ ·) _ fun i ↦ pow_dvd_aux_pow_sub_aux_pow g p i.le_succ) := - dif_pos fun _ ↦ HasEnoughRootsOfUnity.exists_primitiveRoot _ _ + dite_eq_left fun _ ↦ HasEnoughRootsOfUnity.exists_primitiveRoot _ _ open modularCyclotomicCharacter in theorem toZModPow_toFun (n : ℕ) : @@ -312,13 +312,13 @@ noncomputable def cyclotomicCharacter (p : ℕ) [Fact p.Prime] : · have _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ refine PadicInt.ext_of_toZModPow.mp fun n ↦ ?_ simp [cyclotomicCharacter.toZModPow_toFun] - · simp [cyclotomicCharacter.toFun, dif_neg H] + · simp [cyclotomicCharacter.toFun, dite_eq_right H] map_mul' f g := by by_cases H : ∀ (i : ℕ), ∃ ζ : L, IsPrimitiveRoot ζ (p ^ i) · have _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ refine PadicInt.ext_of_toZModPow.mp fun n ↦ ?_ simp [cyclotomicCharacter.toZModPow_toFun] - · simp [cyclotomicCharacter.toFun, dif_neg H] } + · simp [cyclotomicCharacter.toFun, dite_eq_right H] } theorem cyclotomicCharacter.spec (p : ℕ) [Fact p.Prime] {n : ℕ} [∀ i, HasEnoughRootsOfUnity L (p ^ i)] (g : L ≃+* L) (t : L) (ht : t ^ p ^ n = 1) : @@ -337,7 +337,7 @@ lemma cyclotomicCharacter.continuous (p : ℕ) [Fact p.Prime] (K L : Type*) [Field K] [Field L] [Algebra K L] : Continuous ((cyclotomicCharacter L p).comp (MulSemiringAction.toRingAut Gal(L/K) L)) := by by_cases H : ∀ (i : ℕ), ∃ ζ : L, IsPrimitiveRoot ζ (p ^ i); swap - · simp only [cyclotomicCharacter, cyclotomicCharacter.toFun, dif_neg H, MonoidHom.coe_comp] + · simp only [cyclotomicCharacter, cyclotomicCharacter.toFun, dite_eq_right H, MonoidHom.coe_comp] exact continuous_const (y := 1) have _ (i) : HasEnoughRootsOfUnity L (p ^ i) := ⟨H i, rootsOfUnity.isCyclic _ _⟩ choose ζ hζ using H diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 442b660cf4ab74..ae81687d75b07a 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -98,7 +98,7 @@ theorem mem_properDivisors {m : ℕ} : n ∈ properDivisors m ↔ n ∣ m ∧ n theorem insert_self_properDivisors (h : n ≠ 0) : insert n (properDivisors n) = divisors n := by rw [divisors, properDivisors, ← Finset.insert_Ico_right_eq_Ico_add_one (one_le_iff_ne_zero.2 h), - Finset.filter_insert, if_pos (dvd_refl n)] + Finset.filter_insert, ite_eq_left (dvd_refl n)] theorem cons_self_properDivisors (h : n ≠ 0) : cons n (properDivisors n) self_notMem_properDivisors = divisors n := by diff --git a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean index 99cab97650e2f8..c09d760cf57509 100644 --- a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean +++ b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean @@ -385,13 +385,14 @@ lemma preNormEDS'_four : preNormEDS' b c d 4 = d := by lemma preNormEDS'_even (m : ℕ) : preNormEDS' b c d (2 * (m + 3)) = preNormEDS' b c d (m + 2) ^ 2 * preNormEDS' b c d (m + 3) * preNormEDS' b c d (m + 5) - preNormEDS' b c d (m + 1) * preNormEDS' b c d (m + 3) * preNormEDS' b c d (m + 4) ^ 2 := by - rw [show 2 * (m + 3) = 2 * m + 1 + 5 by rfl, preNormEDS', dif_neg m.not_even_two_mul_add_one] + rw [show 2 * (m + 3) = 2 * m + 1 + 5 by rfl, preNormEDS', + dite_eq_right m.not_even_two_mul_add_one] simp [Nat.mul_add_div two_pos] lemma preNormEDS'_odd (m : ℕ) : preNormEDS' b c d (2 * (m + 2) + 1) = preNormEDS' b c d (m + 4) * preNormEDS' b c d (m + 2) ^ 3 * (if Even m then b else 1) - preNormEDS' b c d (m + 1) * preNormEDS' b c d (m + 3) ^ 3 * (if Even m then 1 else b) := by - rw [show 2 * (m + 2) + 1 = 2 * m + 5 by rfl, preNormEDS', dif_pos <| even_two_mul m, + rw [show 2 * (m + 2) + 1 = 2 * m + 5 by rfl, preNormEDS', dite_eq_left <| even_two_mul m, m.mul_div_cancel_left two_pos] /-- The auxiliary sequence for a normalised EDS `W : ℤ → R`, with initial values @@ -486,12 +487,12 @@ lemma complEDS₂_two : complEDS₂ b c d 2 = d := by @[simp] lemma complEDS₂_three : complEDS₂ b c d 3 = preNormEDS (b ^ 4) c d 5 * b - d ^ 2 * b := by - simp [complEDS₂, if_neg (by decide : ¬Even (3 : ℤ)), sub_mul] + simp [complEDS₂, ite_eq_right (by decide : ¬Even (3 : ℤ)), sub_mul] @[simp] lemma complEDS₂_four : complEDS₂ b c d 4 = c ^ 2 * preNormEDS (b ^ 4) c d 6 - preNormEDS (b ^ 4) c d 5 ^ 2 := by - simp [complEDS₂, if_pos (by decide : Even (4 : ℤ))] + simp [complEDS₂, ite_eq_left (by decide : Even (4 : ℤ))] @[simp] lemma complEDS₂_neg (k : ℤ) : complEDS₂ b c d (-k) = complEDS₂ b c d k := by @@ -546,7 +547,7 @@ lemma normEDS_neg (n : ℤ) : normEDS b c d (-n) = -normEDS b c d n := by lemma normEDS_mul_complEDS₂ (k : ℤ) : normEDS b c d k * complEDS₂ b c d k = normEDS b c d (2 * k) := by simp_rw [normEDS, mul_right_comm, preNormEDS_mul_complEDS₂, mul_assoc, apply_ite₂, one_mul, - mul_one, ite_self, if_pos <| even_two_mul k] + mul_one, ite_self, ite_eq_left <| even_two_mul k] lemma normEDS_dvd_normEDS_two_mul (k : ℤ) : normEDS b c d k ∣ normEDS b c d (2 * k) := ⟨complEDS₂ .., (normEDS_mul_complEDS₂ ..).symm⟩ @@ -567,7 +568,8 @@ lemma normEDS_even (m : ℤ) : normEDS b c d (2 * m) * b = lemma normEDS_odd (m : ℤ) : normEDS b c d (2 * m + 1) = normEDS b c d (m + 2) * normEDS b c d m ^ 3 - normEDS b c d (m - 1) * normEDS b c d (m + 1) ^ 3 := by - simp_rw [normEDS, preNormEDS_odd, if_neg m.not_even_two_mul_add_one, Int.even_add, Int.even_sub, + simp_rw [normEDS, preNormEDS_odd, ite_eq_right m.not_even_two_mul_add_one, Int.even_add, + Int.even_sub, even_two, iff_true, Int.not_even_one, iff_false] split_ifs <;> ring1 @@ -634,7 +636,7 @@ lemma complEDS'_one : complEDS' b c d k 1 = 1 := by lemma complEDS'_even (m : ℕ) : complEDS' b c d k (2 * (m + 1)) = complEDS' b c d k (m + 1) * complEDS₂ b c d ((m + 1) * k) := by - rw [show 2 * (m + 1) = 2 * m + 2 by rfl, complEDS', dif_pos <| even_two_mul m, + rw [show 2 * (m + 1) = 2 * m + 2 by rfl, complEDS', dite_eq_left <| even_two_mul m, m.mul_div_cancel_left two_pos, Nat.cast_succ] lemma complEDS'_odd (m : ℕ) : complEDS' b c d k (2 * (m + 1) + 1) = @@ -642,7 +644,7 @@ lemma complEDS'_odd (m : ℕ) : complEDS' b c d k (2 * (m + 1) + 1) = * normEDS b c d ((m + 2) * k + 1) * normEDS b c d ((m + 2) * k - 1) - complEDS' b c d k (m + 2) ^ 2 * normEDS b c d ((m + 1) * k + 1) * normEDS b c d ((m + 1) * k - 1) := by - rw [show 2 * (m + 1) + 1 = 2 * m + 3 by rfl, complEDS', dif_neg m.not_even_two_mul_add_one] + rw [show 2 * (m + 1) + 1 = 2 * m + 3 by rfl, complEDS', dite_eq_right m.not_even_two_mul_add_one] simp [Nat.mul_add_div two_pos, add_assoc] /-- The complement sequence `Wᶜ : ℤ × ℤ → R` for a normalised EDS `W : ℤ → R` that witnesses diff --git a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean index 58a6430496fc0b..6bc84b0f6e3d1e 100644 --- a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean +++ b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean @@ -186,8 +186,8 @@ lemma DirichletCharacter.LSeries_changeLevel {M N : ℕ} [NeZero N] simp only [Set.mulIndicator_apply, Set.mem_ofPred_eq, Finset.mem_coe, Nat.mem_primeFactors, ne_eq, mul_ite, mul_one] by_cases h : p.Prime; swap - · simp only [h, false_and, if_false] - simp only [h, true_and, if_true] + · simp only [h, false_and, ite_false] + simp only [h, true_and, ite_true] by_cases hp' : p ∣ N; swap · simp only [hp', false_and, ↓reduceIte, inv_inj, sub_right_inj, mul_eq_mul_right_iff, cpow_eq_zero_iff, Nat.cast_eq_zero, h.ne_zero, ne_eq, neg_eq_zero, or_false] diff --git a/Mathlib/NumberTheory/GaussSum.lean b/Mathlib/NumberTheory/GaussSum.lean index 9092406fa0325b..630849d6b0b77c 100644 --- a/Mathlib/NumberTheory/GaussSum.lean +++ b/Mathlib/NumberTheory/GaussSum.lean @@ -198,7 +198,7 @@ theorem gaussSum_mul_gaussSum_eq_card {χ : MulChar R R'} (hχ : χ ≠ 1) {ψ : classical -- to get `[DecidableEq R]` for `sum_mulShift` simp_rw [← Finset.mul_sum, sum_mulShift _ hψ, sub_eq_zero, apply_ite, Nat.cast_zero, mul_zero] rw [Finset.sum_ite_eq' Finset.univ (1 : R)] - simp only [Finset.mem_univ, map_one, one_mul, if_true] + simp only [Finset.mem_univ, map_one, one_mul, ite_true] /-- If `χ` is a multiplicative character of order `n` on a finite field `F`, then `g(χ) * g(χ^(n-1)) = χ(-1)*#F` -/ diff --git a/Mathlib/NumberTheory/Harmonic/EulerMascheroni.lean b/Mathlib/NumberTheory/Harmonic/EulerMascheroni.lean index ae2e78cdaa83d2..8f4ba9ca8d7e63 100644 --- a/Mathlib/NumberTheory/Harmonic/EulerMascheroni.lean +++ b/Mathlib/NumberTheory/Harmonic/EulerMascheroni.lean @@ -87,7 +87,7 @@ lemma strictAnti_eulerMascheroniSeq' : StrictAnti eulerMascheroniSeq' := by refine strictAnti_nat_of_succ_lt (fun n ↦ ?_) rcases Nat.eq_zero_or_pos n with rfl | hn · simp [eulerMascheroniSeq'] - simp_rw [eulerMascheroniSeq', eq_false_intro hn.ne', reduceCtorEq, if_false] + simp_rw [eulerMascheroniSeq', eq_false_intro hn.ne', reduceCtorEq, ite_false] rw [← sub_pos, sub_sub_sub_comm, harmonic_succ, Rat.cast_add, ← sub_sub, sub_self, zero_sub, sub_eq_add_neg, neg_sub, ← sub_eq_neg_add, sub_pos, ← log_div (by positivity) (by positivity), ← neg_lt_neg_iff, @@ -116,7 +116,7 @@ lemma eulerMascheroniSeq_lt_eulerMascheroniSeq' (m n : ℕ) : have (r : ℕ) : eulerMascheroniSeq r < eulerMascheroniSeq' r := by rcases eq_zero_or_pos r with rfl | hr · simp [eulerMascheroniSeq, eulerMascheroniSeq'] - simp only [eulerMascheroniSeq, eulerMascheroniSeq', hr.ne', if_false] + simp only [eulerMascheroniSeq, eulerMascheroniSeq', hr.ne', ite_false] gcongr linarith apply (strictMono_eulerMascheroniSeq.monotone (le_max_left m n)).trans_lt @@ -151,7 +151,7 @@ lemma tendsto_harmonic_sub_log : Tendsto (fun n : ℕ ↦ harmonic n - log n) atTop (𝓝 eulerMascheroniConstant) := by apply tendsto_eulerMascheroniSeq'.congr' filter_upwards [eventually_ne_atTop 0] with n hn - simp_rw [eulerMascheroniSeq', hn, if_false] + simp_rw [eulerMascheroniSeq', hn, ite_false] lemma eulerMascheroniSeq_lt_eulerMascheroniConstant (n : ℕ) : eulerMascheroniSeq n < eulerMascheroniConstant := by diff --git a/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean b/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean index 6846dc699ecd29..e1fc6060b9ce66 100644 --- a/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean +++ b/Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean @@ -151,7 +151,7 @@ lemma term_tsum_one : HasSum (fun n ↦ term (n + 1) 1) (1 - γ) := by refine Tendsto.add ?_ tendsto_const_nhds have := (tendsto_eulerMascheroniSeq'.comp (tendsto_add_atTop_nat 1)).neg refine this.congr' (Eventually.of_forall (fun n ↦ ?_)) - simp_rw [Function.comp_apply, eulerMascheroniSeq', reduceCtorEq, if_false] + simp_rw [Function.comp_apply, eulerMascheroniSeq', reduceCtorEq, ite_false] push_cast abel diff --git a/Mathlib/NumberTheory/JacobiSum/Basic.lean b/Mathlib/NumberTheory/JacobiSum/Basic.lean index ba851e06089843..2df05512d169e4 100644 --- a/Mathlib/NumberTheory/JacobiSum/Basic.lean +++ b/Mathlib/NumberTheory/JacobiSum/Basic.lean @@ -106,7 +106,7 @@ theorem jacobiSum_trivial_trivial : rw [jacobiSum_eq_sum_sdiff] have : ∀ x ∈ univ \ {0, 1}, (MulChar.trivial F R) x * (MulChar.trivial F R) (1 - x) = 1 := by intro x hx - rw [← map_mul, MulChar.trivial_apply, if_pos] + rw [← map_mul, MulChar.trivial_apply, ite_eq_left] simp only [mem_sdiff, mem_univ, mem_insert, mem_singleton, not_or, ← ne_eq, true_and] at hx simpa only [isUnit_iff_ne_zero, mul_ne_zero_iff, ne_eq, sub_eq_zero, @eq_comm _ _ x] using hx calc ∑ x ∈ univ \ {0, 1}, (MulChar.trivial F R) x * (MulChar.trivial F R) (1 - x) diff --git a/Mathlib/NumberTheory/LSeries/Basic.lean b/Mathlib/NumberTheory/LSeries/Basic.lean index ffd10e7cd63394..9c600187008df2 100644 --- a/Mathlib/NumberTheory/LSeries/Basic.lean +++ b/Mathlib/NumberTheory/LSeries/Basic.lean @@ -91,7 +91,7 @@ lemma term_zero (f : ℕ → ℂ) (s : ℂ) : term f s 0 = 0 := rfl @[simp] lemma term_of_ne_zero {n : ℕ} (hn : n ≠ 0) (f : ℕ → ℂ) (s : ℂ) : term f s n = f n / n ^ s := - if_neg hn + ite_eq_right hn /-- If `s ≠ 0`, then the `if .. then .. else` construction in `LSeries.term` isn't needed, since @@ -328,7 +328,7 @@ lemma LSeriesSummable.le_const_mul_rpow {f : ℕ → ℂ} {s : ℂ} (h : LSeries use tsum fun n ↦ ‖term f s n‖ by_contra! ⟨n, hn₀, hn⟩ have := h.le_tsum n fun _ _ ↦ norm_nonneg _ - rw [norm_term_eq, if_neg hn₀, + rw [norm_term_eq, ite_eq_right hn₀, div_le_iff₀ <| Real.rpow_pos_of_pos (Nat.cast_pos.mpr <| Nat.pos_of_ne_zero hn₀) _] at this exact (this.trans_lt hn).false.elim diff --git a/Mathlib/NumberTheory/LSeries/Convergence.lean b/Mathlib/NumberTheory/LSeries/Convergence.lean index 8dd208aa006f6c..9cd5bd916c3d3e 100644 --- a/Mathlib/NumberTheory/LSeries/Convergence.lean +++ b/Mathlib/NumberTheory/LSeries/Convergence.lean @@ -127,7 +127,7 @@ lemma LSeries.summable_real_of_abscissaOfAbsConv_lt {f : ℕ → ℝ} {x : ℝ} simp only [LSeriesSummable, aux, summable_ofReal] at this refine this.congr_cofinite ?_ filter_upwards [(Set.finite_singleton 0).compl_mem_cofinite] with n hn - using if_neg (by simpa using hn) + using ite_eq_right (by simpa using hn) /-- If `F` is a binary operation on `ℕ → ℂ` with the property that the `LSeries` of `F f g` converges whenever the `LSeries` of `f` and `g` do, then the abscissa of absolute convergence diff --git a/Mathlib/NumberTheory/LSeries/Dirichlet.lean b/Mathlib/NumberTheory/LSeries/Dirichlet.lean index f718ca1edc35ff..b84c8c94dcfbca 100644 --- a/Mathlib/NumberTheory/LSeries/Dirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/Dirichlet.lean @@ -156,7 +156,7 @@ lemma convolution_mul_moebius {n : ℕ} (χ : DirichletCharacter ℂ n) : ↗χ lemma modZero_eq_delta {χ : DirichletCharacter ℂ 0} : ↗χ = δ := by ext n rcases eq_or_ne n 0 with rfl | hn - · simp_rw [cast_zero, χ.map_nonunit not_isUnit_zero, delta, reduceCtorEq, if_false] + · simp_rw [cast_zero, χ.map_nonunit not_isUnit_zero, delta, reduceCtorEq, ite_false] rcases eq_or_ne n 1 with rfl | hn' · simp [delta] have : ¬ IsUnit (n : ZMod 0) := fun h ↦ hn' <| ZMod.eq_one_of_isUnit_natCast h diff --git a/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean b/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean index e24ca61b0261ee..06c0ed7779db04 100644 --- a/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean +++ b/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean @@ -235,7 +235,7 @@ lemma isBigO_atTop_cosKernel_sub (a : UnitAddCircle) : obtain ⟨p, hp, hp'⟩ := HurwitzKernelBounds.isBigO_atTop_F_nat_zero_sub zero_le_one refine ⟨p, hp, (Eventually.isBigO ?_).trans (hp'.const_mul_left 2)⟩ filter_upwards [eventually_gt_atTop 0] with t ht - simp only [eq_false_intro one_ne_zero, if_false, sub_zero, + simp only [eq_false_intro one_ne_zero, ite_false, sub_zero, ← (hasSum_nat_cosKernel₀ a ht).tsum_eq, HurwitzKernelBounds.F_nat] apply tsum_of_norm_bounded ((HurwitzKernelBounds.summable_f_nat 0 1 ht).hasSum.mul_left 2) intro n diff --git a/Mathlib/NumberTheory/LSeries/Injectivity.lean b/Mathlib/NumberTheory/LSeries/Injectivity.lean index ea74e592e3d2b2..12206ef330cd95 100644 --- a/Mathlib/NumberTheory/LSeries/Injectivity.lean +++ b/Mathlib/NumberTheory/LSeries/Injectivity.lean @@ -125,7 +125,7 @@ lemma LSeries.tendsto_atTop {f : ℕ → ℂ} (ha : abscissaOfAbsConv f < ⊤) : Tendsto (fun x : ℝ ↦ LSeries f x) atTop (nhds (f 1)) := by let F (n : ℕ) : ℂ := if n = 0 then 0 else f n have hF₀ : F 0 = 0 := rfl - have hF {n : ℕ} (hn : n ≠ 0) : F n = f n := if_neg hn + have hF {n : ℕ} (hn : n ≠ 0) : F n = f n := ite_eq_right hn have ha' : abscissaOfAbsConv F < ⊤ := (abscissaOfAbsConv_congr hF).symm ▸ ha simp_rw [← LSeries_congr hF] convert! LSeries.tendsto_cpow_mul_atTop (n := 0) (fun _ hm ↦ Nat.le_zero.mp hm ▸ hF₀) ha' using 1 @@ -149,7 +149,7 @@ lemma LSeries_eventually_eq_zero_iff' {f : ℕ → ℂ} : refine ⟨fun H ↦ ?_, fun H ↦ Eventually.of_forall fun x ↦ ?_⟩ · let F (n : ℕ) : ℂ := if n = 0 then 0 else f n have hF₀ : F 0 = 0 := rfl - have hF {n : ℕ} (hn : n ≠ 0) : F n = f n := if_neg hn + have hF {n : ℕ} (hn : n ≠ 0) : F n = f n := ite_eq_right hn suffices ∀ n, F n = 0 from fun n hn ↦ (hF hn).symm.trans (this n) have ha : ¬ abscissaOfAbsConv F = ⊤ := abscissaOfAbsConv_congr hF ▸ h have h' (x : ℝ) : LSeries F x = LSeries f x := LSeries_congr hF x diff --git a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean index 3c92195fce20df..b382f3d6c15762 100644 --- a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean +++ b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean @@ -84,7 +84,7 @@ lemma HurwitzZeta.completedCosZeta₀_zero (s : ℂ) : lemma completedRiemannZeta_eq (s : ℂ) : completedRiemannZeta s = completedRiemannZeta₀ s - 1 / s - 1 / (1 - s) := by - simp_rw [completedRiemannZeta, completedRiemannZeta₀, completedHurwitzZetaEven_eq, if_true] + simp_rw [completedRiemannZeta, completedRiemannZeta₀, completedHurwitzZetaEven_eq, ite_true] /-- The modified completed Riemann zeta function `Λ(s) + 1 / s + 1 / (1 - s)` is entire. -/ theorem differentiable_completedZeta₀ : Differentiable ℂ completedRiemannZeta₀ := @@ -123,7 +123,7 @@ def riemannZeta := hurwitzZetaEven 0 lemma HurwitzZeta.hurwitzZetaEven_zero : hurwitzZetaEven 0 = riemannZeta := rfl lemma HurwitzZeta.cosZeta_zero : cosZeta 0 = riemannZeta := by - simp_rw [cosZeta, riemannZeta, hurwitzZetaEven, if_true, completedHurwitzZetaEven_zero, + simp_rw [cosZeta, riemannZeta, hurwitzZetaEven, ite_true, completedHurwitzZetaEven_zero, completedCosZeta_zero] lemma HurwitzZeta.hurwitzZeta_zero : hurwitzZeta 0 = riemannZeta := by @@ -149,7 +149,7 @@ lemma analyticOn_riemannZeta : /-- We have `ζ(0) = -1 / 2`. -/ theorem riemannZeta_zero : riemannZeta 0 = -1 / 2 := by - simp_rw [riemannZeta, hurwitzZetaEven, Function.update_self, if_true] + simp_rw [riemannZeta, hurwitzZetaEven, Function.update_self, ite_true] lemma riemannZeta_def_of_ne_zero {s : ℂ} (hs : s ≠ 0) : riemannZeta s = completedRiemannZeta s / Gammaℝ s := by diff --git a/Mathlib/NumberTheory/LSeries/SumCoeff.lean b/Mathlib/NumberTheory/LSeries/SumCoeff.lean index 7a380fec0c8848..95245a36bffead 100644 --- a/Mathlib/NumberTheory/LSeries/SumCoeff.lean +++ b/Mathlib/NumberTheory/LSeries/SumCoeff.lean @@ -77,10 +77,10 @@ theorem LSeriesSummable_of_sum_norm_bigO (hr : 0 ≤ r) (hs : r < s.re) : LSeriesSummable f s := by have h₁ : (fun n ↦ if n = 0 then 0 else f n) =ᶠ[atTop] f := by - filter_upwards [eventually_ne_atTop 0] with n hn using by simp_rw [if_neg hn] - refine (LSeriesSummable_of_sum_norm_bigO_aux (if_pos rfl) ?_ hr hs).congr' _ h₁ + filter_upwards [eventually_ne_atTop 0] with n hn using by simp_rw [ite_eq_right hn] + refine (LSeriesSummable_of_sum_norm_bigO_aux (ite_eq_left rfl) ?_ hr hs).congr' _ h₁ refine hO.congr' (Eventually.of_forall fun _ ↦ Finset.sum_congr rfl fun _ h ↦ ?_) EventuallyEq.rfl - rw [if_neg (zero_lt_one.trans_le (mem_Icc.mp h).1).ne'] + rw [ite_eq_right (zero_lt_one.trans_le (mem_Icc.mp h).1).ne'] /-- If `f` takes nonnegative real values and the partial sums `∑ k ∈ Icc 1 n, f k` are `O(n ^ r)` for some real `0 ≤ r`, then the L-series `LSeries f` converges at `s : ℂ` for all `s` @@ -139,10 +139,12 @@ theorem LSeries_eq_mul_integral (f : ℕ → ℂ) {r : ℝ} (hr : 0 ≤ r) {s : (hO : (fun n ↦ ∑ k ∈ Icc 1 n, f k) =O[atTop] fun n ↦ (n : ℝ) ^ r) : LSeries f s = s * ∫ t in Set.Ioi (1 : ℝ), (∑ k ∈ Icc 1 ⌊t⌋₊, f k) * t ^ (-(s + 1)) := by rw [← LSeriesSummable_congr' s (f := fun n ↦ if n = 0 then 0 else f n) - (by filter_upwards [eventually_ne_atTop 0] with n h using if_neg h)] at hS + (by filter_upwards [eventually_ne_atTop 0] with n h using ite_eq_right h)] at hS have (n : _) : ∑ k ∈ Icc 1 n, (if k = 0 then 0 else f k) = ∑ k ∈ Icc 1 n, f k := - Finset.sum_congr rfl fun k hk ↦ by rw [if_neg (zero_lt_one.trans_le (mem_Icc.mp hk).1).ne'] - rw [← LSeries_congr fun _ ↦ if_neg _, LSeries_eq_mul_integral_aux (if_pos rfl) hr hs hS] <;> + Finset.sum_congr rfl fun k hk ↦ by + rw [ite_eq_right (zero_lt_one.trans_le (mem_Icc.mp hk).1).ne'] + rw [← LSeries_congr fun _ ↦ ite_eq_right _, + LSeries_eq_mul_integral_aux (ite_eq_left rfl) hr hs hS] <;> simp_all /-- A version of `LSeries_eq_mul_integral` where we use the stronger condition that the partial sums diff --git a/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean b/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean index 0d7e121c0a5497..2184bbe6ea6367 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/GaussEisensteinLemmas.lean @@ -52,9 +52,9 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a · rw [natCast_natAbs_valMinAbs] split_ifs · rw [mul_div_cancel₀ _ hap, valMinAbs_def_pos, val_cast_of_lt (hep hb), - if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_natCast] + ite_eq_left (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_natCast] · rw [mul_neg, mul_div_cancel₀ _ hap, natAbs_valMinAbs_neg, valMinAbs_def_pos, - val_cast_of_lt (hep hb), if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_natCast] + val_cast_of_lt (hep hb), ite_eq_left (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_natCast] exact Multiset.map_eq_map_of_bij_of_nodup _ _ (Finset.nodup _) (Finset.nodup _) (fun x _ => (a * x : ZMod p).valMinAbs.natAbs) hmem (inj_on_of_surj_on_of_card_le _ hmem hsurj le_rfl) hsurj (fun _ _ => rfl) diff --git a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean index 970a536cb95257..ac5e0f490efe2a 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean @@ -347,7 +347,7 @@ theorem even_odd {a : ℤ} {b : ℕ} (ha2 : a % 2 = 0) (hb2 : b % 2 = 1) : obtain ⟨a, rfl⟩ := Int.dvd_of_emod_eq_zero ha2 rw [Int.mul_ediv_cancel_left _ (by decide), jacobiSym.mul_left, jacobiSym.at_two (Nat.odd_iff.mpr hb2), ZMod.χ₈_nat_eq_if_mod_eight, - if_neg (Nat.mod_two_ne_zero.mpr hb2)] + ite_eq_right (Nat.mod_two_ne_zero.mpr hb2)] grind end jacobiSym @@ -584,7 +584,7 @@ set_option backward.privateInPublic.warn false in Int.emod_two_ne_zero.mp ha2, one_left, one_mul] · rw [hb1, one_right] · rw [mod_left, hab, zero_left (lt_of_le_of_ne (Nat.pos_of_ne_zero hb0) (Ne.symm hb1))] - · rw [fastJacobiSymAux.eq_jacobiSym, if_neg Bool.false_ne_true, mod_left a b, + · rw [fastJacobiSymAux.eq_jacobiSym, ite_eq_right Bool.false_ne_true, mod_left a b, Int.natAbs_of_nonneg (a.emod_nonneg (mod_cast hb0))] · exact Nat.mod_two_ne_zero.mp hb2 · exact lt_of_le_of_ne (Nat.one_le_iff_ne_zero.mpr hb0) (Ne.symm hb1) diff --git a/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean b/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean index 4fe9cf2f5e7cc3..4574d7e5f25ab5 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/QuadraticChar/Basic.lean @@ -70,23 +70,23 @@ theorem quadraticCharFun_eq_zero_iff {a : F} : quadraticCharFun F a = 0 ↔ a = @[simp] theorem quadraticCharFun_zero : quadraticCharFun F 0 = 0 := by - simp only [quadraticCharFun, if_true] + simp only [quadraticCharFun, ite_true] @[simp] theorem quadraticCharFun_one : quadraticCharFun F 1 = 1 := by - simp only [quadraticCharFun, one_ne_zero, IsSquare.one, if_true, if_false] + simp only [quadraticCharFun, one_ne_zero, IsSquare.one, ite_true, ite_false] /-- If `ringChar F = 2`, then `quadraticCharFun F` takes the value `1` on nonzero elements. -/ theorem quadraticCharFun_eq_one_of_char_two (hF : ringChar F = 2) {a : F} (ha : a ≠ 0) : quadraticCharFun F a = 1 := by - simp only [quadraticCharFun, ha, if_false, ite_eq_left_iff] + simp only [quadraticCharFun, ha, ite_false, ite_eq_left_iff] exact fun h ↦ (h (FiniteField.isSquare_of_char_two hF a)).elim /-- If `ringChar F` is odd, then `quadraticCharFun F a` can be computed in terms of `a ^ (Fintype.card F / 2)`. -/ theorem quadraticCharFun_eq_pow_of_char_ne_two (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) : quadraticCharFun F a = if a ^ (Fintype.card F / 2) = 1 then 1 else -1 := by - simp only [quadraticCharFun, ha, if_false] + simp only [quadraticCharFun, ha, ite_false] simp_rw [FiniteField.isSquare_iff hF ha] /-- The quadratic character is multiplicative. -/ @@ -107,12 +107,12 @@ theorem quadraticCharFun_mul (a b : F) : rw [quadraticCharFun_eq_pow_of_char_ne_two hF ha, quadraticCharFun_eq_pow_of_char_ne_two hF hb, quadraticCharFun_eq_pow_of_char_ne_two hF hab, mul_pow] rcases FiniteField.pow_dichotomy hF hb with hb' | hb' - · simp only [hb', mul_one, if_true] + · simp only [hb', mul_one, ite_true] · have h := Ring.neg_one_ne_one_of_char_ne_two hF -- `-1 ≠ 1` - simp only [hb', mul_neg, mul_one, h, if_false] + simp only [hb', mul_neg, mul_one, h, ite_false] rcases FiniteField.pow_dichotomy hF ha with ha' | ha' <;> - simp only [ha', h, neg_neg, if_true, if_false] + simp only [ha', h, neg_neg, ite_true, ite_false] variable (F) in /-- The quadratic character as a multiplicative character. -/ @@ -133,13 +133,13 @@ theorem quadraticChar_zero : quadraticChar F 0 = 0 := by /-- For nonzero `a : F`, `quadraticChar F a = 1 ↔ IsSquare a`. -/ theorem quadraticChar_one_iff_isSquare {a : F} (ha : a ≠ 0) : quadraticChar F a = 1 ↔ IsSquare a := by - simp only [quadraticChar_apply, quadraticCharFun, ha, if_false, ite_eq_left_iff, + simp only [quadraticChar_apply, quadraticCharFun, ha, ite_false, ite_eq_left_iff, imp_false, not_not, reduceCtorEq] /-- The quadratic character takes the value `1` on nonzero squares. -/ theorem quadraticChar_sq_one' {a : F} (ha : a ≠ 0) : quadraticChar F (a ^ 2) = 1 := by - simp only [quadraticChar_apply, quadraticCharFun, sq_eq_zero_iff, ha, IsSquare.sq, if_true, - if_false] + simp only [quadraticChar_apply, quadraticCharFun, sq_eq_zero_iff, ha, IsSquare.sq, ite_true, + ite_false] /-- The square of the quadratic character on nonzero arguments is `1`. -/ theorem quadraticChar_sq_one {a : F} (ha : a ≠ 0) : quadraticChar F a ^ 2 = 1 := by @@ -189,7 +189,7 @@ theorem quadraticChar_eq_pow_of_char_ne_two' (hF : ringChar F ≠ 2) (a : F) : simp only [ha, quadraticChar_apply, quadraticCharFun_zero, Int.cast_zero, zero_pow this.ne'] · rw [quadraticChar_eq_pow_of_char_ne_two hF ha] by_cases ha' : a ^ (Fintype.card F / 2) = 1 - · simp only [ha', if_true, Int.cast_one] + · simp only [ha', ite_true, Int.cast_one] · have ha'' := Or.resolve_left (FiniteField.pow_dichotomy hF ha) ha' simp only [ha'', Int.cast_ite, Int.cast_one, Int.cast_neg, ite_eq_right_iff] exact Eq.symm @@ -261,7 +261,7 @@ theorem quadraticChar_neg_one [DecidableEq F] (hF : ringChar F ≠ 2) : rw [h, χ₄_eq_neg_one_pow (FiniteField.odd_card_of_char_ne_two hF)] generalize Fintype.card F / 2 = n rcases Nat.even_or_odd n with h₂ | h₂ - · simp only [Even.neg_one_pow h₂, if_true] + · simp only [Even.neg_one_pow h₂, ite_true] · simp only [Odd.neg_one_pow h₂, Ring.neg_one_ne_one_of_char_ne_two hF, ite_false] /-- `-1` is a square in `F` iff `#F` is not congruent to `3` mod `4`. -/ diff --git a/Mathlib/NumberTheory/LegendreSymbol/ZModChar.lean b/Mathlib/NumberTheory/LegendreSymbol/ZModChar.lean index 4d52c6e6cec8e2..aef4a5cd576937 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/ZModChar.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/ZModChar.lean @@ -76,7 +76,7 @@ theorem χ₄_nat_eq_if_mod_four (n : ℕ) : /-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/ theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by rw [χ₄_nat_eq_if_mod_four] - simp only [hn, Nat.one_ne_zero, if_false] + simp only [hn, Nat.one_ne_zero, ite_false] nth_rewrite 3 [← Nat.div_add_mod n 4] nth_rewrite 3 [show 4 = 2 * 2 by lia] rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ zero_lt_two, pow_add, pow_mul, diff --git a/Mathlib/NumberTheory/ModularForms/Cusps.lean b/Mathlib/NumberTheory/ModularForms/Cusps.lean index a6b26045153f1e..43393892fee378 100644 --- a/Mathlib/NumberTheory/ModularForms/Cusps.lean +++ b/Mathlib/NumberTheory/ModularForms/Cusps.lean @@ -335,7 +335,7 @@ lemma widthInfty_nonneg : 0 ≤ 𝒢.widthInfty := 𝒢.adjoinNegOne.strictWidth variable {𝒢} in lemma strictPeriods_eq_zmultiples_strictWidthInfty [DiscreteTopology 𝒢.strictPeriods] : 𝒢.strictPeriods = AddSubgroup.zmultiples 𝒢.strictWidthInfty := by - simp [Subgroup.strictWidthInfty, dif_pos, + simp [Subgroup.strictWidthInfty, dite_eq_left, Exists.choose_spec <| 𝒢.strictPeriods.isAddCyclic_iff_exists_zmultiples_eq_top.mp <| AddSubgroup.discrete_iff_addCyclic.mpr inferInstance] @@ -357,7 +357,7 @@ lemma strictWidthInfty_SL2Z : strictWidthInfty 𝒮ℒ = 1 := by lemma strictWidthInfty_mem_strictPeriods : 𝒢.strictWidthInfty ∈ 𝒢.strictPeriods := by by_cases h : DiscreteTopology 𝒢.strictPeriods · simp [strictPeriods_eq_zmultiples_strictWidthInfty] - · simp [strictWidthInfty, dif_neg h] + · simp [strictWidthInfty, dite_eq_right h] variable {𝒢} in lemma periods_eq_zmultiples_widthInfty [DiscreteTopology 𝒢.periods] : diff --git a/Mathlib/NumberTheory/ModularForms/JacobiTheta/Bounds.lean b/Mathlib/NumberTheory/ModularForms/JacobiTheta/Bounds.lean index da0999ad54bcd2..90a7a81121fba0 100644 --- a/Mathlib/NumberTheory/ModularForms/JacobiTheta/Bounds.lean +++ b/Mathlib/NumberTheory/ModularForms/JacobiTheta/Bounds.lean @@ -252,7 +252,7 @@ lemma isBigO_atTop_F_int_zero_sub (a : UnitAddCircle) : ∃ p, 0 < p ∧ obtain ⟨p, hp, hp'⟩ := isBigO_atTop_F_nat_zero_sub ha.1 obtain ⟨q, hq, hq'⟩ := isBigO_atTop_F_nat_zero_sub (sub_nonneg.mpr ha.2.le) simp_rw [AddCircle.coe_eq_zero_iff_of_mem_Ico ha] - simp_rw [eq_false_intro (by linarith [ha.2] : 1 - a ≠ 0), if_false, sub_zero] at hq' + simp_rw [eq_false_intro (by linarith [ha.2] : 1 - a ≠ 0), ite_false, sub_zero] at hq' refine ⟨_, lt_min hp hq, ?_⟩ have : (fun t ↦ F_int 0 a t - (if a = 0 then 1 else 0)) =ᶠ[atTop] fun t ↦ (F_nat 0 a t - (if a = 0 then 1 else 0)) + F_nat 0 (1 - a) t := by diff --git a/Mathlib/NumberTheory/MulChar/Basic.lean b/Mathlib/NumberTheory/MulChar/Basic.lean index dc3c465d304326..5b3f293f24cced 100644 --- a/Mathlib/NumberTheory/MulChar/Basic.lean +++ b/Mathlib/NumberTheory/MulChar/Basic.lean @@ -105,8 +105,8 @@ noncomputable def trivial : MulChar R R' where toFun := by classical exact fun x => if IsUnit x then 1 else 0 map_nonunit' := by intro a ha - simp only [ha, if_false] - map_one' := by simp only [isUnit_one, if_true] + simp only [ha, ite_false] + map_one' := by simp only [isUnit_one, ite_true] map_mul' := by intro x y classical @@ -158,22 +158,22 @@ noncomputable def ofUnitHom (f : Rˣ →* R'ˣ) : MulChar R R' where toFun := by classical exact fun x => if hx : IsUnit x then f hx.unit else 0 map_one' := by have h1 : (isUnit_one.unit : Rˣ) = 1 := Units.ext rfl - simp only [h1, dif_pos, Units.val_eq_one, map_one, isUnit_one] + simp only [h1, dite_eq_left, Units.val_eq_one, map_one, isUnit_one] map_mul' := by classical intro x y by_cases hx : IsUnit x - · simp only [hx, IsUnit.mul_iff, true_and, dif_pos] + · simp only [hx, IsUnit.mul_iff, true_and, dite_eq_left] by_cases hy : IsUnit y - · simp only [hy, dif_pos] + · simp only [hy, dite_eq_left] have hm : (hx.mul hy).unit = hx.unit * hy.unit := Units.ext rfl rw [hm, map_mul] norm_cast - · simp only [hy, not_false_iff, dif_neg, mul_zero] - · simp only [hx, IsUnit.mul_iff, false_and, not_false_iff, dif_neg, zero_mul] + · simp only [hy, not_false_iff, dite_eq_right, mul_zero] + · simp only [hx, IsUnit.mul_iff, false_and, not_false_iff, dite_eq_right, zero_mul] map_nonunit' := by intro a ha - simp only [ha, not_false_iff, dif_neg] + simp only [ha, not_false_iff, dite_eq_right] theorem ofUnitHom_coe (f : Rˣ →* R'ˣ) (a : Rˣ) : ofUnitHom f ↑a = f a := by simp [ofUnitHom] @@ -254,7 +254,7 @@ noncomputable instance inhabited : Inhabited (MulChar R R') := /-- Evaluation of the trivial character -/ @[simp] -theorem one_apply_coe (a : Rˣ) : (1 : MulChar R R') a = 1 := by exact dif_pos a.isUnit +theorem one_apply_coe (a : Rˣ) : (1 : MulChar R R') a = 1 := by exact dite_eq_left a.isUnit /-- Evaluation of the trivial character -/ lemma one_apply {x : R} (hx : IsUnit x) : (1 : MulChar R R') x = 1 := one_apply_coe hx.unit @@ -395,7 +395,7 @@ noncomputable def domRestrictHom {S : Type*} [SetLike S R] [SubmonoidClass S R] toFun := domRestrict T map_one' := by ext x - rw [domRestrict_apply, if_pos x.isUnit, MulChar.one_apply x.isUnit.coe, one_apply_coe] + rw [domRestrict_apply, ite_eq_left x.isUnit, MulChar.one_apply x.isUnit.coe, one_apply_coe] map_mul' x y := by ext; simp @[deprecated (since := "2026-07-19")] alias restrictHom := domRestrictHom diff --git a/Mathlib/NumberTheory/MulChar/Duality.lean b/Mathlib/NumberTheory/MulChar/Duality.lean index a0795bd1294a19..6de835ef1a4c41 100644 --- a/Mathlib/NumberTheory/MulChar/Duality.lean +++ b/Mathlib/NumberTheory/MulChar/Duality.lean @@ -106,7 +106,7 @@ theorem mulCharEquiv_symm_apply_apply (m : Mˣ) (χ : MulChar M R) : (mulCharEquiv M R).symm m χ = χ m := by classical rw [show ((mulCharEquiv M R).symm m) χ = - if IsUnit χ then ↑(mulEquivToUnitHom χ m) else (0 : R) by rfl, if_pos (Group.isUnit χ), + if IsUnit χ then ↑(mulEquivToUnitHom χ m) else (0 : R) by rfl, ite_eq_left (Group.isUnit χ), mulEquivToUnitHom_apply, coe_equivToUnitHom] @[simp] diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index b9051ae510212b..6a13859ff1f1ba 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -351,12 +351,12 @@ theorem normAtPlace_real (w : InfinitePlace K) (c : ℝ) : theorem normAtPlace_apply_of_isReal {w : InfinitePlace K} (hw : IsReal w) (x : mixedSpace K) : normAtPlace w x = ‖x.1 ⟨w, hw⟩‖ := by - rw [normAtPlace, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, dif_pos] + rw [normAtPlace, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, dite_eq_left] theorem normAtPlace_apply_of_isComplex {w : InfinitePlace K} (hw : IsComplex w) (x : mixedSpace K) : normAtPlace w x = ‖x.2 ⟨w, hw⟩‖ := by rw [normAtPlace, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, - dif_neg (not_isReal_iff_isComplex.mpr hw)] + dite_eq_right (not_isReal_iff_isComplex.mpr hw)] @[simp] theorem normAtPlace_apply (w : InfinitePlace K) (x : K) : @@ -900,13 +900,13 @@ variable {s} @[simp] theorem negAt_apply_isReal_and_mem (x : mixedSpace K) {w : {w // IsReal w}} (hw : w ∈ s) : (negAt s x).1 w = -x.1 w := by - simp_rw [negAt, prodCongr_apply, piCongrRight_apply, if_pos hw, + simp_rw [negAt, prodCongr_apply, piCongrRight_apply, ite_eq_left hw, ContinuousLinearEquiv.neg_apply] @[simp] theorem negAt_apply_isReal_and_notMem (x : mixedSpace K) {w : {w // IsReal w}} (hw : w ∉ s) : (negAt s x).1 w = x.1 w := by - simp_rw [negAt, prodCongr_apply, piCongrRight_apply, if_neg hw, + simp_rw [negAt, prodCongr_apply, piCongrRight_apply, ite_eq_right hw, ContinuousLinearEquiv.refl_apply] @[simp] @@ -927,9 +927,9 @@ theorem volume_preserving_negAt [NumberField K] : MeasurePreserving (negAt s) := by refine MeasurePreserving.prod (volume_preserving_pi fun w ↦ ?_) (MeasurePreserving.id _) by_cases hw : w ∈ s - · simp_rw [if_pos hw] + · simp_rw [ite_eq_left hw] exact Measure.measurePreserving_neg _ - · simp_rw [if_neg hw] + · simp_rw [ite_eq_right hw] exact MeasurePreserving.id _ variable (s) in @@ -954,10 +954,10 @@ theorem negAt_symm : ext x w · by_cases hw : w ∈ s · simp_rw [negAt_apply_isReal_and_mem _ hw, negAt, prodCongr_symm, - prodCongr_apply, piCongrRight_symm_apply, if_pos hw, symm_neg, + prodCongr_apply, piCongrRight_symm_apply, ite_eq_left hw, symm_neg, ContinuousLinearEquiv.neg_apply] · simp_rw [negAt_apply_isReal_and_notMem _ hw, negAt, prodCongr_symm, - prodCongr_apply, piCongrRight_symm_apply, if_neg hw, refl_symm, + prodCongr_apply, piCongrRight_symm_apply, ite_eq_right hw, refl_symm, refl_apply] · rfl @@ -1153,12 +1153,12 @@ abbrev normAtComplexPlaces (x : mixedSpace K) : realSpace K := @[simp] theorem normAtComplexPlaces_apply_isReal {x : mixedSpace K} (w : {w // IsReal w}) : normAtComplexPlaces x w = x.1 w := by - rw [normAtComplexPlaces, dif_pos] + rw [normAtComplexPlaces, dite_eq_left] @[simp] theorem normAtComplexPlaces_apply_isComplex {x : mixedSpace K} (w : {w // IsComplex w}) : normAtComplexPlaces x w = ‖x.2 w‖ := by - rw [normAtComplexPlaces, dif_neg (not_isReal_iff_isComplex.mpr w.prop), + rw [normAtComplexPlaces, dite_eq_right (not_isReal_iff_isComplex.mpr w.prop), normAtPlace_apply_of_isComplex] theorem normAtComplexPlaces_mixedSpaceOfRealSpace {x : realSpace K} diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean index 9dfad8b98b3b82..40cba1711a546e 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/ConvexBody.lean @@ -167,12 +167,12 @@ theorem convexBodyLT'_mem {x : K} : · specialize h₂ w (not_isReal_iff_isComplex.mp hw) rw [apply_ite (w.embedding x ∈ ·), Set.mem_ofPred_eq, mem_ball_zero_iff, norm_embedding_eq] at h₂ - rwa [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)] at h₂ - · simpa [if_true] using h₂ w₀.val w₀.prop + rwa [ite_eq_right (by exact Subtype.coe_ne_coe.1 h_ne)] at h₂ + · simpa [ite_true] using h₂ w₀.val w₀.prop · exact h₁ w (ne_of_isReal_isComplex hw w₀.prop) · by_cases h_ne : w = w₀ · simpa [h_ne] - · rw [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)] + · rw [ite_eq_right (by exact Subtype.coe_ne_coe.1 h_ne)] rw [mem_ball_zero_iff, norm_embedding_eq] exact h₁ w h_ne @@ -229,7 +229,7 @@ theorem convexBodyLT'_volume : rw [← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)] congr 2 · refine Finset.prod_congr rfl (fun w' hw' ↦ ?_) - rw [if_neg (Finset.ne_of_mem_erase hw'), Complex.volume_ball] + rw [ite_eq_right (Finset.ne_of_mem_erase hw'), Complex.volume_ball] · simpa only [ite_true] using vol_box (f w₀) _ = ((2 : ℝ≥0) ^ nrRealPlaces K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) * @@ -540,7 +540,7 @@ theorem exists_primitive_element_lt_of_isReal {w₀ : InfinitePlace K} (hw₀ : obtain ⟨a, h_nz, h_le⟩ := exists_ne_zero_mem_ringOfIntegers_lt K this refine ⟨a, ?_, fun w ↦ lt_of_lt_of_le (h_le w) ?_⟩ · exact is_primitive_element_of_infinitePlace_lt h_nz - (fun w h_ne ↦ by convert! (if_neg h_ne) ▸ h_le w) (Or.inl hw₀) + (fun w h_ne ↦ by convert! (ite_eq_right h_ne) ▸ h_le w) (Or.inl hw₀) · split_ifs <;> simp theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀ : IsComplex w₀) @@ -559,9 +559,9 @@ theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀ obtain ⟨a, h_nz, h_le, h_le₀⟩ := exists_ne_zero_mem_ringOfIntegers_lt' K ⟨w₀, hw₀⟩ this refine ⟨a, ?_, fun w ↦ ?_⟩ · exact is_primitive_element_of_infinitePlace_lt h_nz - (fun w h_ne ↦ by convert! if_neg h_ne ▸ h_le w h_ne) (Or.inr h_le₀.1) + (fun w h_ne ↦ by convert! ite_eq_right h_ne ▸ h_le w h_ne) (Or.inr h_le₀.1) · by_cases h_eq : w = w₀ - · rw [if_pos rfl] at h_le₀ + · rw [ite_eq_left rfl] at h_le₀ dsimp only at h_le₀ rw [h_eq, ← norm_embedding_eq, Real.lt_sqrt (norm_nonneg _), ← Complex.re_add_im (embedding w₀ _), Complex.norm_add_mul_I, Real.sq_sqrt (by positivity)] @@ -570,7 +570,7 @@ theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀ exact h_le₀.1 · rw [sq_lt_sq, NNReal.abs_eq, ← NNReal.sq_sqrt B] exact h_le₀.2 - · refine lt_of_lt_of_le (if_neg h_eq ▸ h_le w h_eq) ?_ + · refine lt_of_lt_of_le (ite_eq_right h_eq ▸ h_le w h_eq) ?_ rw [NNReal.coe_one, Real.le_sqrt' zero_lt_one, one_pow] norm_num diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean index 3d71faf8b0a105..22ee702d4e5918 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/NormLeOne.lean @@ -369,13 +369,13 @@ theorem realSpaceToLogSpace_expMap_symm {x : K} (hx : x ≠ 0) : theorem realSpaceToLogSpace_completeFamily_of_eq : realSpaceToLogSpace (completeFamily K w₀) = 0 := by ext - rw [realSpaceToLogSpace_apply, completeFamily, dif_pos rfl, ← Nat.cast_sum, sum_mult_eq, + rw [realSpaceToLogSpace_apply, completeFamily, dite_eq_left rfl, ← Nat.cast_sum, sum_mult_eq, mul_inv_cancel_right₀ (Nat.cast_ne_zero.mpr Module.finrank_pos.ne'), sub_self, Pi.zero_apply] theorem realSpaceToLogSpace_completeFamily_of_ne (i : {w : InfinitePlace K // w ≠ w₀}) : realSpaceToLogSpace (completeFamily K i) = basisUnitLattice K (equivFinRank.symm i) := by ext - rw [← logEmbedding_fundSystem, ← logMap_eq_logEmbedding, completeFamily, dif_neg, + rw [← logEmbedding_fundSystem, ← logMap_eq_logEmbedding, completeFamily, dite_eq_right, realSpaceToLogSpace_expMap_symm] exact coe_ne_zero _ @@ -385,7 +385,7 @@ theorem sum_eq_zero_of_mem_span_completeFamily {x : realSpace K} induction hx using Submodule.span_induction with | mem _ h => obtain ⟨w, rfl⟩ := h - simp_rw [completeFamily, dif_neg w.prop, sum_expMap_symm_apply (coe_ne_zero _), + simp_rw [completeFamily, dite_eq_right w.prop, sum_expMap_symm_apply (coe_ne_zero _), Units.norm, Rat.cast_one, Real.log_one] | zero => simp | add _ _ _ _ hx hy => simp [sum_add_distrib, hx, hy] @@ -405,7 +405,7 @@ theorem linearIndependent_completeFamily : (Set.range (fun w : {w // w ≠ w₀} ↦ completeFamily K w.1)) := by intro h have := sum_eq_zero_of_mem_span_completeFamily h - rw [completeFamily, dif_pos rfl, ← Nat.cast_sum, sum_mult_eq, Nat.cast_eq_zero] at this + rw [completeFamily, dite_eq_left rfl, ← Nat.cast_sum, sum_mult_eq, Nat.cast_eq_zero] at this exact Module.finrank_pos.ne' this rw [← linearIndependent_equiv (Equiv.optionSubtypeNe w₀), linearIndependent_option] exact ⟨h₁, h₂⟩ @@ -422,12 +422,12 @@ def completeBasis : Basis (InfinitePlace K) ℝ (realSpace K) := theorem completeBasis_apply_of_eq : completeBasis K w₀ = fun w ↦ (mult w : ℝ) := by - rw [completeBasis, coe_basisOfLinearIndependentOfCardEqFinrank, completeFamily, dif_pos rfl] + rw [completeBasis, coe_basisOfLinearIndependentOfCardEqFinrank, completeFamily, dite_eq_left rfl] theorem completeBasis_apply_of_ne (i : {w : InfinitePlace K // w ≠ w₀}) : completeBasis K i = expMap.symm (normAtAllPlaces (mixedEmbedding K (fundSystem K (equivFinRank.symm i)))) := by - rw [completeBasis, coe_basisOfLinearIndependentOfCardEqFinrank, completeFamily, dif_neg] + rw [completeBasis, coe_basisOfLinearIndependentOfCardEqFinrank, completeFamily, dite_eq_right] theorem expMap_basis_of_eq : expMap (completeBasis K w₀) = fun _ ↦ Real.exp 1 := by @@ -507,10 +507,10 @@ theorem expMapBasis_apply' (x : realSpace K) : open scoped Classical in theorem expMapBasis_apply'' (x : realSpace K) : expMapBasis x = Real.exp (x w₀) • expMapBasis (fun i ↦ if i = w₀ then 0 else x i) := by - rw [expMapBasis_apply', expMapBasis_apply', if_pos rfl, smul_smul, ← Real.exp_add, add_zero] + rw [expMapBasis_apply', expMapBasis_apply', ite_eq_left rfl, smul_smul, ← Real.exp_add, add_zero] conv_rhs => enter [2, w, 2, i] - rw [if_neg i.prop] + rw [ite_eq_right i.prop] theorem prod_expMapBasis_pow (x : realSpace K) : ∏ w, (expMapBasis x w) ^ w.mult = Real.exp (x w₀) ^ Module.finrank ℚ K := by @@ -540,11 +540,11 @@ theorem logMap_expMapBasis (x : realSpace K) : refine forall₂_congr fun w hw ↦ ?_ rw [expMapBasis_apply'', map_smul, logMap_real_smul (norm_expMapBasis_ne_zero _) (Real.exp_ne_zero _), expMapBasis_apply, logMap_expMap (by rw [← expMapBasis_apply, - norm_expMapBasis, if_pos rfl, Real.exp_zero, one_pow]), Basis.equivFun_symm_apply, - Fintype.sum_eq_add_sum_subtype_ne _ w₀, if_pos rfl, zero_smul, zero_add] + norm_expMapBasis, ite_eq_left rfl, Real.exp_zero, one_pow]), Basis.equivFun_symm_apply, + Fintype.sum_eq_add_sum_subtype_ne _ w₀, ite_eq_left rfl, zero_smul, zero_add] conv_lhs => enter [2, 1, 2, w, 2, i] - rw [if_neg i.prop] + rw [ite_eq_right i.prop] simp_rw [Finset.sum_apply, ← sum_fn, map_sum, Pi.smul_apply, ← Pi.smul_def, map_smul, completeBasis_apply_of_ne, expMap_symm_apply, normAtAllPlaces_mixedEmbedding, ← logEmbedding_component, logEmbedding_fundSystem, Finsupp.coe_finsetSum, Finsupp.coe_smul, @@ -704,8 +704,8 @@ theorem setLIntegral_paramSet_exp {n : ℕ} (hn : 0 < n) : classical have hn : 0 < (n : ℝ) := Nat.cast_pos.mpr hn rw [volume_pi, paramSet, Measure.restrict_pi_pi, lintegral_eq_lmarginal_univ 0, - lmarginal_erase' _ (by fun_prop) (Finset.mem_univ w₀), if_pos rfl] - simp_rw [Function.update_self, lmarginal, lintegral_const, Measure.pi_univ, if_neg + lmarginal_erase' _ (by fun_prop) (Finset.mem_univ w₀), ite_eq_left rfl] + simp_rw [Function.update_self, lmarginal, lintegral_const, Measure.pi_univ, ite_eq_right (Finset.ne_of_mem_erase (Subtype.prop _)), Measure.restrict_apply_univ, Real.volume_Ico, sub_zero, ofReal_one, prod_const_one, mul_one, mul_comm _ (n : ℝ)] rw [← ofReal_integral_eq_lintegral_ofReal (integrableOn_exp_mul_Iic hn _), integral_exp_mul_Iic @@ -763,7 +763,7 @@ theorem compactSet_eq_union_aux₁ {x : realSpace K} (hx₀ : x ≠ 0) · have hc' : 0 < c := by contrapose! hx₀ rw [le_antisymm hx₀ hc.1, zero_smul] - rw [expMapBasis_apply'', if_pos rfl, Real.exp_log hc'] + rw [expMapBasis_apply'', ite_eq_left rfl, Real.exp_log hc'] congr with w split_ifs with h · simpa [h, eq_comm] using hy w₀ diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean index 387b4a6aa3f1a4..a187e3c7cae4a5 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/PolarCoord.lean @@ -272,12 +272,12 @@ theorem homeoRealMixedSpacePolarSpace_apply (x : realMixedSpace K) : theorem homeoRealMixedSpacePolarSpace_apply_fst_ofIsReal (x : realMixedSpace K) (w : {w // IsReal w}) : (homeoRealMixedSpacePolarSpace K x).1 w.1 = x.1 w := by - simp_rw [homeoRealMixedSpacePolarSpace_apply, dif_pos w.prop] + simp_rw [homeoRealMixedSpacePolarSpace_apply, dite_eq_left w.prop] theorem homeoRealMixedSpacePolarSpace_apply_fst_ofIsComplex (x : realMixedSpace K) (w : {w // IsComplex w}) : (homeoRealMixedSpacePolarSpace K x).1 w.1 = (x.2 w).1 := by - simp_rw [homeoRealMixedSpacePolarSpace_apply, dif_neg (not_isReal_iff_isComplex.mpr w.prop)] + simp_rw [homeoRealMixedSpacePolarSpace_apply, dite_eq_right (not_isReal_iff_isComplex.mpr w.prop)] theorem homeoRealMixedSpacePolarSpace_apply_snd (x : realMixedSpace K) (w : {w // IsComplex w}) : (homeoRealMixedSpacePolarSpace K x).2 w = (x.2 w).2 := rfl @@ -379,7 +379,7 @@ private theorem volume_eq_two_pi_pow_mul_integral_aux exact Set.mem_image_of_mem _ ha · rwa [Set.mem_preimage, ← hA, Set.mem_preimage, normAtComplexPlaces_mixedSpaceOfRealSpace] at hx₁ intro w hw - simpa [if_neg (not_isReal_iff_isComplex.mpr hw)] using hx₂ w (Set.mem_univ w) + simpa [ite_eq_right (not_isReal_iff_isComplex.mpr hw)] using hx₂ w (Set.mem_univ w) open scoped Classical in /-- diff --git a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean index 932754de6f4d94..3860de9ad69253 100644 --- a/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/Completion/Ramification.lean @@ -102,7 +102,7 @@ protected noncomputable def inertiaDeg : ℕ := theorem inertiaDeg_of_liesOver [w.LiesOver v] : v.inertiaDeg w = (⊥ : Ideal w.Completion).inertiaDeg v.Completion := by - simp only [InfinitePlace.inertiaDeg, dif_pos] + simp only [InfinitePlace.inertiaDeg, dite_eq_left] theorem inertiaDeg_eq_finrank [w.LiesOver v] : v.inertiaDeg w = Module.finrank v.Completion w.Completion := by diff --git a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean index 782aa0ba644efb..2b3facbfacfdd6 100644 --- a/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Cyclotomic/Basic.lean @@ -932,12 +932,12 @@ theorem IsCyclotomicExtension.Rat.torsionOrder_eq [NeZero n] [NumberField K] have h_main := (IsCyclotomicExtension.Rat.finrank n K).symm.trans <| (IsCyclotomicExtension.Rat.finrank (n.lcm (torsionOrder K)) K) obtain hn | hn := Nat.even_or_odd n - · rw [if_pos hn] + · rw [ite_eq_left hn] apply dvd_antisymm · have := hn.eq_of_totient_eq_totient (Nat.dvd_lcm_left _ _) h_main rwa [eq_comm, Nat.lcm_eq_left_iff_dvd] at this · exact dvd_torsionOrder_of_isPrimitiveRoot hζ - · rw [if_neg (Nat.not_even_iff_odd.mpr hn)] + · rw [ite_eq_right (Nat.not_even_iff_odd.mpr hn)] have := (Nat.eq_or_eq_of_totient_eq_totient (Nat.dvd_lcm_left _ _) h_main).resolve_left ?_ · rw [this, eq_comm, Nat.lcm_eq_right_iff_dvd] exact dvd_torsionOrder_of_isPrimitiveRoot hζ diff --git a/Mathlib/NumberTheory/NumberField/DirichletDensity.lean b/Mathlib/NumberTheory/NumberField/DirichletDensity.lean index bd4e0c1e04bdb6..a24d5878512f82 100644 --- a/Mathlib/NumberTheory/NumberField/DirichletDensity.lean +++ b/Mathlib/NumberTheory/NumberField/DirichletDensity.lean @@ -92,12 +92,12 @@ variable {S} /-- If `S` has no Dirichlet density, then `dirichletDensity S = 0`. -/ theorem dirichletDensity_eq_zero_of_not_hasDirichletDensity (h : ∀ δ, ¬ S.HasDirichletDensity δ) : S.dirichletDensity = 0 := by - rw [dirichletDensity, dif_neg (not_exists.mpr h)] + rw [dirichletDensity, dite_eq_right (not_exists.mpr h)] /-- If `S` has Dirichlet density `δ`, then `dirichletDensity S = δ`. -/ theorem HasDirichletDensity.dirichletDensity_eq {δ : ℝ} (h : S.HasDirichletDensity δ) : S.dirichletDensity = δ := by - rw [dirichletDensity, dif_pos ⟨δ, h⟩, tendsto_nhds_unique (Exists.choose_spec ⟨δ, h⟩) h] + rw [dirichletDensity, dite_eq_left ⟨δ, h⟩, tendsto_nhds_unique (Exists.choose_spec ⟨δ, h⟩) h] /-- The empty set has Dirichlet density `0`. -/ theorem hasDirichletDensity_empty : diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean index 86c0ea3a187be9..3deef5f5720ec6 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Basic.lean @@ -274,10 +274,10 @@ define it, see `card_filter_mk_eq`. -/ noncomputable def mult (w : InfinitePlace K) : ℕ := if (IsReal w) then 1 else 2 theorem IsReal.mult_eq_one {w : InfinitePlace K} (hw : IsReal w) : mult w = 1 := - if_pos hw + ite_eq_left hw theorem IsComplex.mult_eq_two {w : InfinitePlace K} (hw : IsComplex w) : mult w = 2 := - if_neg (not_isReal_iff_isComplex.mpr hw) + ite_eq_right (not_isReal_iff_isComplex.mpr hw) @[simp] theorem mult_isReal (w : {w : InfinitePlace K // IsReal w}) : diff --git a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean index c983d5383e5ed5..34d4c66674f22d 100644 --- a/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean +++ b/Mathlib/NumberTheory/NumberField/InfinitePlace/Ramification.lean @@ -488,7 +488,7 @@ lemma card_isUnramified [NumberField k] [IsGalois k K] : intro e; rwa [← isUnramifiedIn_comap, ← e] · rw [Nat.card_eq_fintype_card, ← MulAction.card_orbit_mul_card_stabilizer_eq_card_group _ w, - ← Nat.card_eq_fintype_card (α := Stab w), card_stabilizer, if_pos, + ← Nat.card_eq_fintype_card (α := Stab w), card_stabilizer, ite_eq_left, mul_one, Set.toFinset_card] rwa [← isUnramifiedIn_comap] · simp [Set.MapsTo, isUnramifiedIn_comap] @@ -511,7 +511,7 @@ lemma card_isUnramified_compl [NumberField k] [IsGalois k K] : intro e; rwa [← isUnramifiedIn_comap, ← e] · rw [Nat.card_eq_fintype_card, ← MulAction.card_orbit_mul_card_stabilizer_eq_card_group _ w, - ← Nat.card_eq_fintype_card (α := Stab w), InfinitePlace.card_stabilizer, if_neg, + ← Nat.card_eq_fintype_card (α := Stab w), InfinitePlace.card_stabilizer, ite_eq_right, Nat.mul_div_cancel _ zero_lt_two, Set.toFinset_card] rwa [← isUnramifiedIn_comap] · simp [Set.MapsTo, isUnramifiedIn_comap] diff --git a/Mathlib/NumberTheory/NumberField/Units/Basic.lean b/Mathlib/NumberTheory/NumberField/Units/Basic.lean index 29c9a43acfd3ea..e7212c0b237069 100644 --- a/Mathlib/NumberTheory/NumberField/Units/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Units/Basic.lean @@ -228,7 +228,7 @@ theorem even_torsionOrder : rw [even_iff_two_dvd, ← this] apply orderOf_dvd_natCard rw [← Subgroup.orderOf_coe, ← orderOf_units, Units.val_neg, val_one, orderOf_neg_one, - ringChar.eq_zero, if_neg (by decide)] + ringChar.eq_zero, ite_eq_right (by decide)] section odd diff --git a/Mathlib/NumberTheory/NumberField/Units/Regulator.lean b/Mathlib/NumberTheory/NumberField/Units/Regulator.lean index cc03550c708700..ad681e27c1d3f3 100644 --- a/Mathlib/NumberTheory/NumberField/Units/Regulator.lean +++ b/Mathlib/NumberTheory/NumberField/Units/Regulator.lean @@ -146,12 +146,12 @@ def regOfFamily (u : Fin (rank K) → (𝓞 K)ˣ) : ℝ := theorem regOfFamily_eq_zero {u : Fin (rank K) → (𝓞 K)ˣ} (hu : ¬ IsMaxRank u) : regOfFamily u = 0 := by - rw [regOfFamily, dif_neg hu] + rw [regOfFamily, dite_eq_right hu] open scoped Classical in theorem regOfFamily_of_isMaxRank {u : Fin (rank K) → (𝓞 K)ˣ} (hu : IsMaxRank u) : regOfFamily u = ZLattice.covolume (span ℤ (Set.range (basisOfIsMaxRank hu))) := by - rw [regOfFamily, dif_pos hu] + rw [regOfFamily, dite_eq_left hu] theorem regOfFamily_pos {u : Fin (rank K) → (𝓞 K)ˣ} (hu : IsMaxRank u) : 0 < regOfFamily u := by @@ -245,17 +245,17 @@ theorem finrank_mul_regOfFamily_eq_det (u : Fin (rank K) → (𝓞 K)ˣ) (w' : I rw [← det_reindex_self f.symm, det_eq_sum_row_mul_submatrix_succAbove_succAbove_det _ (f.symm w') (f.symm w'), abs_mul, abs_mul, abs_neg_one_pow, one_mul] · simp_rw [reindex_apply, submatrix_submatrix, ← f.symm.sum_comp, f.symm_symm, submatrix_apply, - Function.comp_def, Equiv.apply_symm_apply, of_apply, dif_pos, ← Nat.cast_sum, sum_mult_eq, - Nat.abs_cast] + Function.comp_def, Equiv.apply_symm_apply, of_apply, dite_eq_left, ← Nat.cast_sum, + sum_mult_eq, Nat.abs_cast] rw [regOfFamily_eq_det u w' e, ← Matrix.det_reindex_self g] congr with i j - rw [reindex_apply, submatrix_apply, submatrix_apply, of_apply, of_apply, dif_neg] + rw [reindex_apply, submatrix_apply, submatrix_apply, of_apply, of_apply, dite_eq_right] rfl · simp_rw [Equiv.forall_congr_left f, ← f.symm.sum_comp, reindex_apply, submatrix_apply, of_apply, f.symm_symm, f.apply_symm_apply, Finset.sum_dite_irrel, ne_eq, EmbeddingLike.apply_eq_iff_eq] intro _ h - rw [dif_neg h, sum_mult_mul_log] + rw [dite_eq_right h, sum_mult_mul_log] end regOfFamily diff --git a/Mathlib/NumberTheory/Padics/PadicIntegers.lean b/Mathlib/NumberTheory/Padics/PadicIntegers.lean index d4a8e052267511..aa016f864d2a98 100644 --- a/Mathlib/NumberTheory/Padics/PadicIntegers.lean +++ b/Mathlib/NumberTheory/Padics/PadicIntegers.lean @@ -361,7 +361,7 @@ theorem mul_inv : ∀ {z : ℤ_[p]}, ‖z‖ = 1 → z * z.inv = 1 unfold PadicInt.inv rw [norm_eq_padic_norm] at h dsimp only - rw [dif_pos h] + rw [dite_eq_left h] apply Subtype.ext_iff.2 simp [mul_inv_cancel₀ hk] diff --git a/Mathlib/NumberTheory/Padics/PadicNorm.lean b/Mathlib/NumberTheory/Padics/PadicNorm.lean index 77e270b9705958..c9ebedd777e9ba 100644 --- a/Mathlib/NumberTheory/Padics/PadicNorm.lean +++ b/Mathlib/NumberTheory/Padics/PadicNorm.lean @@ -125,7 +125,7 @@ protected theorem nonzero {q : ℚ} (hq : q ≠ 0) : padicNorm p q ≠ 0 := by /-- If the `p`-adic norm of `q` is 0, then `q` is `0`. -/ theorem zero_of_padicNorm_eq_zero {q : ℚ} (h : padicNorm p q = 0) : q = 0 := by apply by_contradiction; intro hq - unfold padicNorm at h; rw [if_neg hq] at h + unfold padicNorm at h; rw [ite_eq_right hq] at h apply absurd h apply zpow_ne_zero exact mod_cast hp.1.ne_zero @@ -150,7 +150,7 @@ protected theorem div (q r : ℚ) : padicNorm p (q / r) = padicNorm p q / padicN protected theorem of_int (z : ℤ) : padicNorm p z ≤ 1 := by obtain rfl | hz := eq_or_ne z 0 · simp - · rw [padicNorm, if_neg (mod_cast hz)] + · rw [padicNorm, ite_eq_right (mod_cast hz)] exact zpow_le_one_of_nonpos₀ (mod_cast hp.1.one_le) (by simp) private theorem nonarchimedean_aux {q r : ℚ} (h : padicValRat p q ≤ padicValRat p r) : diff --git a/Mathlib/NumberTheory/Padics/PadicNumbers.lean b/Mathlib/NumberTheory/Padics/PadicNumbers.lean index 0308dc88ff0d0c..5d7ebf5c33d403 100644 --- a/Mathlib/NumberTheory/Padics/PadicNumbers.lean +++ b/Mathlib/NumberTheory/Padics/PadicNumbers.lean @@ -303,7 +303,7 @@ def valuation (f : PadicSeq p) : ℤ := theorem norm_eq_zpow_neg_valuation {f : PadicSeq p} (hf : ¬f ≈ 0) : f.norm = (p : ℚ) ^ (-f.valuation : ℤ) := by - rw [norm, valuation, dif_neg hf, dif_neg hf, padicNorm, if_neg] + rw [norm, valuation, dite_eq_right hf, dite_eq_right hf, padicNorm, ite_eq_right] intro H apply CauSeq.not_limZero_of_not_congr_zero hf intro ε hε @@ -362,11 +362,11 @@ theorem norm_mul (f g : PadicSeq p) : (f * g).norm = f.norm * g.norm := by classical exact if hf : f ≈ 0 then by have hg : f * g ≈ 0 := mul_equiv_zero' _ hf - simp only [hf, hg, norm, dif_pos, zero_mul] + simp only [hf, hg, norm, dite_eq_left, zero_mul] else if hg : g ≈ 0 then by have hf : f * g ≈ 0 := mul_equiv_zero _ hg - simp only [hf, hg, norm, dif_pos, mul_zero] + simp only [hf, hg, norm, dite_eq_left, mul_zero] else by unfold norm have hfg := mul_not_equiv_zero hf hg @@ -472,11 +472,11 @@ theorem norm_eq {f g : PadicSeq p} (h : ∀ k, padicNorm p (f k) = padicNorm p ( classical exact if hf : f ≈ 0 then by have hg : g ≈ 0 := equiv_zero_of_val_eq_of_equiv_zero h hf - simp only [hf, hg, norm, dif_pos] + simp only [hf, hg, norm, dite_eq_left] else by have hg : ¬g ≈ 0 := fun hg ↦ hf <| equiv_zero_of_val_eq_of_equiv_zero (by simp only [h, forall_const]) hg - simp only [hg, hf, norm, dif_neg, not_false_iff] + simp only [hg, hf, norm, dite_eq_right, not_false_iff] let i := max (stationaryPoint hf) (stationaryPoint hg) have hpf : padicNorm p (f (stationaryPoint hf)) = padicNorm p (f i) := by apply stationaryPoint_spec @@ -631,7 +631,7 @@ theorem defn (f : PadicSeq p) {ε : ℚ} (hε : 0 < ε) : obtain ⟨N, hN⟩ := cauchy₂ f hε rcases h N with ⟨i, hi, hge⟩ have hne : ¬f - const (padicNorm p) (f i) ≈ 0 := fun h ↦ by - rw [PadicSeq.norm, dif_pos h] at hge + rw [PadicSeq.norm, dite_eq_left h] at hge exact not_lt_of_ge hge hε unfold PadicSeq.norm at hge; split_ifs at hge apply not_le_of_gt _ hge @@ -685,8 +685,8 @@ theorem rat_dense' (q : ℚ_[p]) {ε : ℚ} (hε : 0 < ε) : ∃ r : ℚ, padicN dsimp [padicNormE] convert_to! PadicSeq.norm (q' - const _ (q' N)) < ε -- `change` times out here. rcases Decidable.em (q' - const (padicNorm p) (q' N) ≈ 0) with heq | hne' - · simpa only [heq, PadicSeq.norm, dif_pos] - · simp only [PadicSeq.norm, dif_neg hne'] + · simpa only [heq, PadicSeq.norm, dite_eq_left] + · simp only [PadicSeq.norm, dite_eq_right hne'] change padicNorm p (q' _ - q' _) < ε rcases Decidable.em (stationaryPoint hne' ≤ N) with hle | hle · have := (stationaryPoint_spec hne' le_rfl hle).symm @@ -1048,7 +1048,7 @@ def valuation : ℚ_[p] → ℤ := @[simp] theorem valuation_zero : valuation (0 : ℚ_[p]) = 0 := - dif_pos ((const_equiv p).2 rfl) + dite_eq_left ((const_equiv p).2 rfl) theorem norm_eq_zpow_neg_valuation {x : ℚ_[p]} : x ≠ 0 → ‖x‖ = (p : ℝ) ^ (-x.valuation) := by induction x using Quotient.inductionOn with | _ f @@ -1142,35 +1142,36 @@ def addValuationDef : ℚ_[p] → WithTop ℤ := @[simp] theorem AddValuation.map_zero : addValuationDef (0 : ℚ_[p]) = ⊤ := by - rw [addValuationDef, if_pos rfl] + rw [addValuationDef, ite_eq_left rfl] @[simp] theorem AddValuation.map_one : addValuationDef (1 : ℚ_[p]) = 0 := by - rw [addValuationDef, if_neg one_ne_zero, valuation_one, WithTop.coe_zero] + rw [addValuationDef, ite_eq_right one_ne_zero, valuation_one, WithTop.coe_zero] theorem AddValuation.map_mul (x y : ℚ_[p]) : addValuationDef (x * y : ℚ_[p]) = addValuationDef x + addValuationDef y := by simp only [addValuationDef] by_cases hx : x = 0 - · rw [hx, if_pos rfl, zero_mul, if_pos rfl, WithTop.top_add] + · rw [hx, ite_eq_left rfl, zero_mul, ite_eq_left rfl, WithTop.top_add] · by_cases hy : y = 0 - · rw [hy, if_pos rfl, mul_zero, if_pos rfl, WithTop.add_top] - · rw [if_neg hx, if_neg hy, if_neg (mul_ne_zero hx hy), ← WithTop.coe_add, WithTop.coe_eq_coe, - valuation_mul hx hy] + · rw [hy, ite_eq_left rfl, mul_zero, ite_eq_left rfl, WithTop.add_top] + · rw [ite_eq_right hx, ite_eq_right hy, ite_eq_right (mul_ne_zero hx hy), ← WithTop.coe_add, + WithTop.coe_eq_coe, valuation_mul hx hy] theorem AddValuation.map_add (x y : ℚ_[p]) : min (addValuationDef x) (addValuationDef y) ≤ addValuationDef (x + y : ℚ_[p]) := by simp only [addValuationDef] by_cases hxy : x + y = 0 - · rw [hxy, if_pos rfl] + · rw [hxy, ite_eq_left rfl] exact le_top · by_cases hx : x = 0 - · rw [hx, if_pos rfl, min_eq_right, zero_add] + · rw [hx, ite_eq_left rfl, min_eq_right, zero_add] exact le_top · by_cases hy : y = 0 - · rw [hy, if_pos rfl, min_eq_left, add_zero] + · rw [hy, ite_eq_left rfl, min_eq_left, add_zero] exact le_top - · rw [if_neg hx, if_neg hy, if_neg hxy, ← WithTop.coe_min, WithTop.coe_le_coe] + · rw [ite_eq_right hx, ite_eq_right hy, ite_eq_right hxy, ← WithTop.coe_min, + WithTop.coe_le_coe] exact le_valuation_add hxy open WithZero @@ -1210,7 +1211,7 @@ def addValuation : AddValuation ℚ_[p] (WithTop ℤ) := @[simp] theorem addValuation.apply {x : ℚ_[p]} (hx : x ≠ 0) : Padic.addValuation x = (x.valuation : WithTop ℤ) := by - simp only [Padic.addValuation, AddValuation.of_apply, addValuationDef, if_neg hx] + simp only [Padic.addValuation, AddValuation.of_apply, addValuationDef, ite_eq_right hx] section NormLEIff diff --git a/Mathlib/NumberTheory/Primorial.lean b/Mathlib/NumberTheory/Primorial.lean index 147e83d499d4d4..41a794626ac7ed 100644 --- a/Mathlib/NumberTheory/Primorial.lean +++ b/Mathlib/NumberTheory/Primorial.lean @@ -68,7 +68,7 @@ theorem primorial_dvd_primorial {m n : ℕ} (h : m ≤ n) : m# ∣ n# := theorem primorial_succ {n : ℕ} (hn1 : n ≠ 1) (hn : Odd n) : (n + 1)# = n# := by refine prod_congr ?_ fun _ _ ↦ rfl - rw [range_add_one, filter_insert, if_neg fun h ↦ not_even_iff_odd.2 hn _] + rw [range_add_one, filter_insert, ite_eq_right fun h ↦ not_even_iff_odd.2 hn _] exact fun h ↦ h.even_sub_one <| mt succ.inj hn1 theorem primorial_add (m n : ℕ) : diff --git a/Mathlib/NumberTheory/RamificationInertia/Basic.lean b/Mathlib/NumberTheory/RamificationInertia/Basic.lean index 508511d23463fb..9195283f387e71 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Basic.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Basic.lean @@ -206,7 +206,7 @@ theorem FinrankQuotientMap.linearIndependent_of_nontrivial [IsDedekindDomain R] let := Classical.propDecidable let g' i := if h : i ∈ s then g'' i h else 0 have hg' : ∀ i ∈ s, algebraMap _ _ (g' i) = a * g i := by - intro i hi; exact (congr_arg _ (dif_pos hi)).trans (hg'' i hi) + intro i hi; exact (congr_arg _ (dite_eq_left hi)).trans (hg'' i hi) -- Because `R/I` is nontrivial, we can lift `g` to a nontrivial linear dependence in `S`. have hgI : algebraMap R S (g' j) ≠ 0 := by simp only [FractionalIdeal.mem_coeIdeal, not_exists, not_and'] at hgI diff --git a/Mathlib/NumberTheory/RamificationInertia/Galois.lean b/Mathlib/NumberTheory/RamificationInertia/Galois.lean index 61c426e3bcf99d..44143783fd6be1 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Galois.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Galois.lean @@ -155,7 +155,7 @@ theorem ramificationIdxIn_eq_ramificationIdx : ramificationIdxIn p B = P.ramificationIdx A := by have h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p := ⟨P, hPp, hp⟩ obtain ⟨_, _⟩ := h.choose_spec - rw [ramificationIdxIn, dif_pos h] + rw [ramificationIdxIn, dite_eq_left h] exact ramificationIdx_eq_of_isGaloisGroup p h.choose P G include G in @@ -171,7 +171,7 @@ theorem inertiaDegIn_eq_inertiaDeg : inertiaDegIn p B = P.inertiaDeg A := by have h : ∃ P : Ideal B, P.IsPrime ∧ P.LiesOver p := ⟨P, hPp, hp⟩ obtain ⟨_, _⟩ := h.choose_spec - rw [inertiaDegIn, dif_pos h] + rw [inertiaDegIn, dite_eq_left h] exact inertiaDeg_eq_of_isGaloisGroup p h.choose P G include G in diff --git a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean index 1fed89890a588a..8b35155c283654 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean @@ -78,7 +78,7 @@ theorem inertiaDeg'_of_subsingleton [hp : p.IsMaximal] [hQ : Subsingleton (S ⧸ inertiaDeg' p P = 0 := by have := Ideal.Quotient.subsingleton_iff.mp hQ subst this - exact dif_neg fun h => hp.ne_top <| h.symm.trans comap_top + exact dite_eq_right fun h => hp.ne_top <| h.symm.trans comap_top @[deprecated (since := "2026-07-03")] alias inertiaDeg_of_subsingleton := inertiaDeg'_of_subsingleton @@ -86,7 +86,7 @@ theorem inertiaDeg'_of_subsingleton [hp : p.IsMaximal] [hQ : Subsingleton (S ⧸ @[simp] theorem inertiaDeg'_algebraMap [P.LiesOver p] : inertiaDeg' p P = finrank (R ⧸ p) (S ⧸ P) := by - rw [inertiaDeg', dif_pos (over_def P p).symm] + rw [inertiaDeg', dite_eq_left (over_def P p).symm] @[deprecated (since := "2026-07-03")] alias inertiaDeg_algebraMap := inertiaDeg'_algebraMap @@ -114,8 +114,8 @@ lemma inertiaDeg'_comap_eq (e : S ≃ₐ[R] S₁) (P : Ideal S₁) : by_cases h : P.LiesOver p · rw [inertiaDeg'_algebraMap, inertiaDeg'_algebraMap] exact (Quotient.algEquivOfEqComap p e rfl).toLinearEquiv.finrank_eq - · rw [inertiaDeg', dif_neg (fun eq => h ⟨(he.mp eq).symm⟩)] - rw [inertiaDeg', dif_neg (fun eq => h ⟨eq.symm⟩)] + · rw [inertiaDeg', dite_eq_right (fun eq => h ⟨(he.mp eq).symm⟩)] + rw [inertiaDeg', dite_eq_right (fun eq => h ⟨eq.symm⟩)] @[deprecated (since := "2026-07-03")] alias inertiaDeg_comap_eq := inertiaDeg'_comap_eq @@ -130,7 +130,7 @@ lemma inertiaDeg'_map_eq (P : Ideal S) theorem inertiaDeg'_bot [Nontrivial R] [IsDomain S] [Algebra.IsIntegral R S] [hP : P.LiesOver (⊥ : Ideal R)] : (⊥ : Ideal R).inertiaDeg' P = finrank R S := by - rw [inertiaDeg', dif_pos (over_def P (⊥ : Ideal R)).symm] + rw [inertiaDeg', dite_eq_left (over_def P (⊥ : Ideal R)).symm] replace hP : P = ⊥ := eq_bot_of_liesOver_bot R P rw [Algebra.finrank_eq_of_equiv_equiv (RingEquiv.quotientBot R).symm ((quotEquivOfEq hP).trans (RingEquiv.quotientBot S)).symm] @@ -197,7 +197,7 @@ theorem inertiaDeg'_algebra_tower (p : Ideal R) (P : Ideal S) (I : Ideal T) [p.I have h₁ := P.over_def p have h₂ := I.over_def P have h₃ := (LiesOver.trans I P p).over - simp only [inertiaDeg', dif_pos h₁.symm, dif_pos h₂.symm, dif_pos h₃.symm] + simp only [inertiaDeg', dite_eq_left h₁.symm, dite_eq_left h₂.symm, dite_eq_left h₃.symm] let : Algebra (R ⧸ p) (S ⧸ P) := Ideal.Quotient.algebraQuotientOfLEComap h₁.le let : Algebra (S ⧸ P) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₂.le let : Algebra (R ⧸ p) (T ⧸ I) := Ideal.Quotient.algebraQuotientOfLEComap h₃.le diff --git a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean index 67a42d6f710014..534a59718c3c55 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Ramification.lean @@ -78,7 +78,7 @@ theorem ramificationIdx'_eq_find [DecidablePred fun n ↦ ∀ (k : ℕ), map f p theorem ramificationIdx'_eq_zero (h : ∀ n : ℕ, ∃ k, map f p ≤ P ^ k ∧ n < k) : ramificationIdx' p P = 0 := - dif_neg (by push Not; exact h) + dite_eq_right (by push Not; exact h) @[deprecated (since := "2026-07-01")] alias ramificationIdx_eq_zero := ramificationIdx'_eq_zero @@ -112,7 +112,7 @@ theorem ramificationIdx'_lt {n : ℕ} (hgt : ¬map f p ≤ P ^ n) : ramification @[simp] theorem ramificationIdx'_bot : ramificationIdx' (⊥ : Ideal R) P = 0 := - dif_neg <| not_exists.mpr fun n hn => n.lt_succ_self.not_ge (hn _ (by simp)) + dite_eq_right <| not_exists.mpr fun n hn => n.lt_succ_self.not_ge (hn _ (by simp)) @[deprecated (since := "2026-07-01")] alias ramificationIdx_bot := ramificationIdx'_bot diff --git a/Mathlib/NumberTheory/RatFunc/Ostrowski.lean b/Mathlib/NumberTheory/RatFunc/Ostrowski.lean index 4e7cbad0f07236..cbcb6ab1ffc56c 100644 --- a/Mathlib/NumberTheory/RatFunc/Ostrowski.lean +++ b/Mathlib/NumberTheory/RatFunc/Ostrowski.lean @@ -217,8 +217,8 @@ lemma valuation_isEquiv_valuationIdeal_adic_of_valuation_X_le_one [IsRankOneDisc have hp0 : p ≠ 0 := by simp_all set pi := πᵥ with hpi_def have hpi : v.IsUniformizer (pi : RatFunc K) := uniformizingPolynomial_isUniformizer hle - simp only [map_div₀, valuation_of_algebraMap, intValuation_def, exp_neg, if_neg hp0, - if_neg hq0, div_inv_eq_mul] + simp only [map_div₀, valuation_of_algebraMap, intValuation_def, exp_neg, ite_eq_right hp0, + ite_eq_right hq0, div_inv_eq_mul] rw [valuation_eq_valuation_uniformizingPolynomial_pow_of_valuation_X_le_one hle hp0, valuation_eq_valuation_uniformizingPolynomial_pow_of_valuation_X_le_one hle hq0] simp_all [div_le_one₀, inv_mul_le_one₀, diff --git a/Mathlib/NumberTheory/ZetaValues.lean b/Mathlib/NumberTheory/ZetaValues.lean index 1c0c8af8c40468..805f9e4c4ab0be 100644 --- a/Mathlib/NumberTheory/ZetaValues.lean +++ b/Mathlib/NumberTheory/ZetaValues.lean @@ -119,7 +119,7 @@ theorem integral_bernoulliFun : ∫ x : ℝ in 0..1, bernoulliFun k x = if k = 0 variable {k} in theorem integral_bernoulliFun_eq_zero (hk : k ≠ 0) : ∫ x : ℝ in 0..1, bernoulliFun k x = 0 := by - rw [integral_bernoulliFun, if_neg hk] + rw [integral_bernoulliFun, ite_eq_right hk] /-- Fundamental theorem of calculus to express a Bernoulli polynomial via the previous one -/ theorem bernoulliFun_eq_integral (k : ℕ) (x y : ℝ) : @@ -204,7 +204,8 @@ theorem bernoulliFun_eval_half (k : ℕ) : bernoulliFun k 2⁻¹ = (2 / 2 ^ k - · have m := bernoulliFun_mul k two_ne_zero 2⁻¹ simp_rw [Nat.cast_ofNat, mul_inv_cancel₀ (two_ne_zero' ℝ), Finset.sum_range_succ, Finset.sum_range_zero, Nat.cast_zero, Nat.cast_one, ← one_div, add_halves, - bernoulliFun_eval_one, if_neg k1, bernoulliFun_eval_zero, zero_div, add_zero, zero_add] at m + bernoulliFun_eval_one, ite_eq_right k1, bernoulliFun_eval_zero, zero_div, add_zero, + zero_add] at m rw [← inv_mul_eq_iff_eq_mul₀ (by positivity), ← sub_eq_iff_eq_add, ← sub_one_mul, inv_div] at m rw [m, one_div] @@ -253,11 +254,11 @@ theorem bernoulliFourierCoeff_eq {k : ℕ} (hk : k ≠ 0) (n : ℤ) : div_zero] refine Nat.le_induction ?_ (fun k hk h'k => ?_) k (Nat.one_le_iff_ne_zero.mpr hk) · rw [bernoulliFourierCoeff_recurrence 1 hn] - simp only [Nat.cast_one, tsub_self, neg_mul, one_mul, if_true, + simp only [Nat.cast_one, tsub_self, neg_mul, one_mul, ite_true, Nat.factorial_one, pow_one] rw [bernoulli_zero_fourier_coeff hn, sub_zero, mul_one, div_neg, neg_div] - · rw [bernoulliFourierCoeff_recurrence (k + 1) hn, if_neg (by grind), Nat.add_sub_cancel k 1, h'k, - Nat.factorial_succ, zero_sub, Nat.cast_mul, pow_add] + · rw [bernoulliFourierCoeff_recurrence (k + 1) hn, ite_eq_right (by grind), + Nat.add_sub_cancel k 1, h'k, Nat.factorial_succ, zero_sub, Nat.cast_mul, pow_add] ring end BernoulliFourierCoeffs diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index 73ba47772225cd..a15c2491d30f0d 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -679,15 +679,19 @@ instance {α} [CompleteAtomicBooleanAlgebra α] : IsAtomistic α := inhabit α refine ⟨{ a | IsAtom a ∧ a ≤ b }, ?_, fun a ha => ha.1⟩ refine le_antisymm ?_ (sSup_le fun c hc => hc.2) - have : (⨅ c : α, ⨆ x, b ⊓ cond x c (cᶜ)) = b := by simp [iSup_bool_eq] + have : (⨅ c : α, ⨆ x, b ⊓ bif x then c else cᶜ) = b := by simp [iSup_bool_eq] rw [← this]; clear this simp_rw [iInf_iSup_eq, iSup_le_iff]; intro g - if h : (⨅ a, b ⊓ cond (g a) a (aᶜ)) = ⊥ then simp [h] else - refine le_sSup ⟨⟨h, fun c hc => ?_⟩, le_trans (by rfl) (le_iSup _ g)⟩; clear h - have := lt_of_lt_of_le hc (le_trans (iInf_le _ c) inf_le_right) - revert this - nontriviality α - cases g c <;> simp + if h : (⨅ a, b ⊓ bif g a then a else aᶜ) = ⊥ then + have h' : (⨅ a, b ⊓ if g a then a else aᶜ) = ⊥ := by + simpa only [Bool.cond_eq_ite] using h + simp [h'] + else + refine le_sSup ⟨⟨h, fun c hc => ?_⟩, le_trans (by rfl) (le_iSup _ g)⟩; clear h + have := lt_of_lt_of_le hc (le_trans (iInf_le _ c) inf_le_right) + revert this + nontriviality α + cases g c <;> simp instance {α} [CompleteAtomicBooleanAlgebra α] : IsCoatomistic α := isAtomistic_dual_iff_isCoatomistic.1 inferInstance @@ -909,20 +913,20 @@ protected noncomputable def completeLattice : CompleteLattice α := refine ⟨fun x h ↦ ?_, fun x h ↦ ?_⟩ · rcases eq_bot_or_eq_top x with (rfl | rfl) · exact bot_le - · rw [if_pos h] + · rw [ite_eq_left h] · rcases eq_bot_or_eq_top x with (rfl | rfl) - · rw [if_neg] + · rw [ite_eq_right] intro con exact bot_ne_top (eq_top_iff.2 (h con)) · exact le_top isGLB_sInf s := by refine ⟨fun x h ↦ ?_, fun x h ↦ ?_⟩ · rcases eq_bot_or_eq_top x with (rfl | rfl) - · rw [if_pos h] + · rw [ite_eq_left h] · exact le_top · rcases eq_bot_or_eq_top x with (rfl | rfl) · exact bot_le - · rw [if_neg] + · rw [ite_eq_right] intro con exact top_ne_bot (eq_bot_iff.2 (h con)) } diff --git a/Mathlib/Order/CompleteLatticeIntervals.lean b/Mathlib/Order/CompleteLatticeIntervals.lean index 916a55e0b0d96a..3a5d6800638c1b 100644 --- a/Mathlib/Order/CompleteLatticeIntervals.lean +++ b/Mathlib/Order/CompleteLatticeIntervals.lean @@ -201,12 +201,12 @@ noncomputable instance [ConditionallyCompleteLinearOrder α] {a b : α} [Fact (a lemma Set.Icc.coe_sSup [ConditionallyCompleteLattice α] {a b : α} (h : a ≤ b) {S : Set (Set.Icc a b)} (hS : S.Nonempty) : have : Fact (a ≤ b) := ⟨h⟩ ↑(sSup S) = sSup ((↑) '' S : Set α) := - congrArg Subtype.val (dif_neg hS.ne_empty) + congrArg Subtype.val (dite_eq_right hS.ne_empty) lemma Set.Icc.coe_sInf [ConditionallyCompleteLattice α] {a b : α} (h : a ≤ b) {S : Set (Set.Icc a b)} (hS : S.Nonempty) : have : Fact (a ≤ b) := ⟨h⟩ ↑(sInf S) = sInf ((↑) '' S : Set α) := - congrArg Subtype.val (dif_neg hS.ne_empty) + congrArg Subtype.val (dite_eq_right hS.ne_empty) lemma Set.Icc.coe_iSup [ConditionallyCompleteLattice α] {a b : α} (h : a ≤ b) [Nonempty ι] {S : ι → Set.Icc a b} : have : Fact (a ≤ b) := ⟨h⟩ diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index f55de6c4523038..8e9c61a7e7bf2b 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -62,24 +62,24 @@ noncomputable instance instInfSet [InfSet α] : InfSet (WithTop α) := @[to_dual] theorem sSup_eq [SupSet α] {s : Set (WithTop α)} (hs : ⊤ ∉ s) (hs' : BddAbove ((↑) ⁻¹' s : Set α)) : sSup s = ↑(sSup ((↑) ⁻¹' s) : α) := - (if_neg hs).trans <| if_pos hs' + (ite_eq_right hs).trans <| ite_eq_left hs' @[to_dual] theorem sInf_eq [InfSet α] {s : Set (WithTop α)} (hs : ¬s ⊆ {⊤}) (h's : BddBelow s) : sInf s = ↑(sInf ((↑) ⁻¹' s) : α) := - if_neg <| by simp [hs, h's] + ite_eq_right <| by simp [hs, h's] @[to_dual (attr := simp)] theorem sInf_empty [InfSet α] : sInf (∅ : Set (WithTop α)) = ⊤ := - if_pos <| by simp + ite_eq_left <| by simp @[to_dual (attr := simp)] theorem sInf_singleton_top [InfSet α] : sInf ({⊤} : Set (WithTop α)) = ⊤ := - if_pos <| .inl subset_rfl + ite_eq_left <| .inl subset_rfl @[to_dual (attr := simp)] theorem sSup_of_top_mem [SupSet α] {s : Set (WithTop α)} (h : ⊤ ∈ s) : sSup s = ⊤ := - if_pos h + ite_eq_left h @[to_dual] theorem sSup_singleton_top [SupSet α] : sSup ({⊤} : Set (WithTop α)) = ⊤ := by @@ -90,19 +90,19 @@ theorem sSup_of_not_bddAbove [SupSet α] {s : Set (WithTop α)} (h : ¬BddAbove ((↑) ⁻¹' s : Set α)) : sSup s = ⊤ := by by_cases hmem : ⊤ ∈ s · exact sSup_of_top_mem hmem - · exact if_neg hmem |>.trans <| if_neg h + · exact ite_eq_right hmem |>.trans <| ite_eq_right h @[to_dual (attr := simp)] theorem sInf_of_not_bddBelow [InfSet α] {s : Set (WithTop α)} (h : ¬BddBelow s) : sInf s = ⊤ := - if_pos <| .inr h + ite_eq_left <| .inr h @[to_dual (attr := norm_cast)] theorem coe_sSup' [SupSet α] {s : Set α} (hs : BddAbove s) : ↑(sSup s) = (sSup ((fun (a : α) ↦ ↑a) '' s) : WithTop α) := by classical change _ = ite _ _ _ - rw [if_neg, preimage_image_eq, if_pos hs] + rw [ite_eq_right, preimage_image_eq, ite_eq_left hs] · exact Option.some_injective _ · rintro ⟨x, _, ⟨⟩⟩ diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean b/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean index c534b3172d6739..1ce320b9c236fa 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Defs.lean @@ -171,7 +171,7 @@ noncomputable abbrev WellFoundedLT.conditionallyCompleteLinearOrderBot (α : Typ __ := letI : InfSet α := ⟨fun s => if hs : s.Nonempty then h.wf.min s hs else ⊥⟩ conditionallyCompleteLatticeOfLatticeOfsInf _ fun s _ hn ↦ by - simp only [dif_pos hn] + simp only [dite_eq_left hn] exact IsLeast.isGLB ⟨h.wf.min_mem s hn, fun _ hx ↦ h.wf.min_le hx⟩ csSup_empty := by simp [sSup, bot_unique (WellFounded.min_le _ (mem_univ _))] csSup_of_not_bddAbove s H := by diff --git a/Mathlib/Order/DirectedInverseSystem.lean b/Mathlib/Order/DirectedInverseSystem.lean index 468e2e921a06d6..5c66273ba9b44b 100644 --- a/Mathlib/Order/DirectedInverseSystem.lean +++ b/Mathlib/Order/DirectedInverseSystem.lean @@ -321,7 +321,7 @@ variable [PartialOrder ι] [DecidableEq ι] def piSplitLE : piLT X i × X i ≃ ∀ j : Iic i, X j where toFun f j := if h : j = i then h.symm ▸ f.2 else f.1 ⟨j, j.2.lt_of_ne h⟩ invFun f := (fun j ↦ f ⟨j, j.2.le⟩, f ⟨i, le_rfl⟩) - left_inv f := by ext j; exacts [dif_neg j.2.ne, dif_pos rfl] + left_inv f := by ext j; exacts [dite_eq_right j.2.ne, dite_eq_left rfl] right_inv f := by grind set_option backward.isDefEq.respectTransparency false in @@ -329,7 +329,7 @@ set_option backward.isDefEq.respectTransparency false in piSplitLE f ⟨i, le_rfl⟩ = f.2 := by simp [piSplitLE] theorem piSplitLE_lt {f : piLT X i × X i} {j} (hj : j < i) : - piSplitLE f ⟨j, hj.le⟩ = f.1 ⟨j, hj⟩ := dif_neg hj.ne + piSplitLE f ⟨j, hj.le⟩ = f.1 ⟨j, hj⟩ := dite_eq_right hj.ne end diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 98f4c29e9ba60b..f7adfcad5ac9f0 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -915,7 +915,7 @@ lemma skolem {ι : Type*} {α : ι → Type*} [∀ i, Nonempty (α i)] refine ⟨fun H ↦ ?_, fun ⟨b, hb⟩ ↦ hb.mp (.of_forall fun x a ↦ ⟨_, a⟩)⟩ refine ⟨fun i ↦ if h : ∃ b, P i b then h.choose else Nonempty.some inferInstance, ?_⟩ filter_upwards [H] with i hi - exact dif_pos hi ▸ hi.choose_spec + exact dite_eq_left hi ▸ hi.choose_spec /-! ### Relation “eventually equal” diff --git a/Mathlib/Order/Filter/Finite.lean b/Mathlib/Order/Filter/Finite.lean index 7c28143eefe087..94c28561d36371 100644 --- a/Mathlib/Order/Filter/Finite.lean +++ b/Mathlib/Order/Filter/Finite.lean @@ -116,8 +116,8 @@ theorem mem_iInf' {ι} {s : ι → Filter α} {U : Set α} : · dsimp only split_ifs exacts [hV ⟨i,_⟩, univ_mem] - · exact dif_neg hi - · simp only [iInter_dite, biInter_eq_iInter, dif_pos (Subtype.coe_prop _), Subtype.coe_eta, + · exact dite_eq_right hi + · simp only [iInter_dite, biInter_eq_iInter, dite_eq_left (Subtype.coe_prop _), Subtype.coe_eta, iInter_univ, inter_univ, true_and] theorem exists_iInter_of_mem_iInf {ι : Sort*} {α : Type*} {f : ι → Filter α} {s} diff --git a/Mathlib/Order/Filter/Germ/Basic.lean b/Mathlib/Order/Filter/Germ/Basic.lean index 8f71d1dce1e9b6..670f11ef2a2b65 100644 --- a/Mathlib/Order/Filter/Germ/Basic.lean +++ b/Mathlib/Order/Filter/Germ/Basic.lean @@ -758,7 +758,7 @@ instance instExistsMulOfLE [Mul β] [LE β] [ExistsMulOfLE β] : ExistsMulOfLE ( choose c hc using fun x (hx : f x ≤ g x) ↦ exists_mul_of_le hx refine ⟨ofFun fun x ↦ if hx : f x ≤ g x then c x hx else f x, coe_eq.2 ?_⟩ filter_upwards [h] with x hx - rw [dif_pos hx, hc] + rw [dite_eq_left hx, hc] end Germ diff --git a/Mathlib/Order/Interval/Basic.lean b/Mathlib/Order/Interval/Basic.lean index e2dcf378650041..7b1e3e48fbf3d8 100644 --- a/Mathlib/Order/Interval/Basic.lean +++ b/Mathlib/Order/Interval/Basic.lean @@ -515,7 +515,7 @@ instance lattice : Lattice (Interval α) := lift c to NonemptyInterval α using ne_bot_of_le_ne_bot WithBot.coe_ne_bot hc change _ ≤ dite _ _ _ simp only [Interval.coe_le_coe] at hb hc ⊢ - rw [dif_pos, Interval.coe_le_coe] + rw [dite_eq_left, Interval.coe_le_coe] · exact ⟨sup_le hb.1 hc.1, le_inf hb.2 hc.2⟩ -- Porting note: had to add the next 6 lines including the changes because -- it seems that lean cannot automatically turn `NonemptyInterval.toDualProd s` diff --git a/Mathlib/Order/Lattice.lean b/Mathlib/Order/Lattice.lean index f700ba1a0d8ffa..56cfca52fe72b5 100644 --- a/Mathlib/Order/Lattice.lean +++ b/Mathlib/Order/Lattice.lean @@ -308,7 +308,7 @@ theorem Ne.lt_sup_or_lt_sup (hab : a ≠ b) : a < a ⊔ b ∨ b < a ⊔ b := @[to_dual inf_le_ite] theorem ite_le_sup (a b : α) (P : Prop) [Decidable P] : ite P a b ≤ a ⊔ b := - if h : P then (if_pos h).trans_le le_sup_left else (if_neg h).trans_le le_sup_right + if h : P then (ite_eq_left h).trans_le le_sup_left else (ite_eq_right h).trans_le le_sup_right @[to_dual (reorder := H (x y))] theorem SemilatticeSup.ext_sup {α} {A B : SemilatticeSup α} diff --git a/Mathlib/Order/Lattice/Nat.lean b/Mathlib/Order/Lattice/Nat.lean index a16dcb6fe4b5cf..b8e225abbb7207 100644 --- a/Mathlib/Order/Lattice/Nat.lean +++ b/Mathlib/Order/Lattice/Nat.lean @@ -35,15 +35,15 @@ noncomputable instance : SupSet ℕ := open scoped Classical in theorem sInf_def {s : Set ℕ} (h : s.Nonempty) : sInf s = @Nat.find (fun n ↦ n ∈ s) _ h := - dif_pos _ + dite_eq_left _ open scoped Classical in theorem sSup_def {s : Set ℕ} (h : ∃ n, ∀ a ∈ s, a ≤ n) : sSup s = @Nat.find (fun n ↦ ∀ a ∈ s, a ≤ n) _ h := - dif_pos _ + dite_eq_left _ theorem _root_.Set.Infinite.Nat.sSup_eq_zero {s : Set ℕ} (h : s.Infinite) : sSup s = 0 := - dif_neg fun ⟨n, hn⟩ ↦ + dite_eq_right fun ⟨n, hn⟩ ↦ let ⟨k, hks, hk⟩ := h.exists_gt n (hn k hks).not_gt hk @@ -59,7 +59,7 @@ theorem sInf_eq_zero {s : Set ℕ} : sInf s = 0 ↔ 0 ∈ s ∨ s = ∅ := by cases eq_empty_or_nonempty s with | inl h => subst h simp only [or_true, InfSet.sInf, - mem_empty_iff_false, exists_false, dif_neg, not_false_iff] + mem_empty_iff_false, exists_false, dite_eq_right, not_false_iff] | inr h => simp only [h.ne_empty, or_false, Nat.sInf_def, h, Nat.find_eq_zero] @[simp] @@ -142,7 +142,7 @@ noncomputable instance : ConditionallyCompleteLinearOrderBot ℕ := intro s hs simp only [sSup, mem_empty_iff_false, IsEmpty.forall_iff, forall_const, exists_const, dite_true] - rw [dif_neg] + rw [dite_eq_right] · exact le_antisymm (zero_le _) (find_le trivial) · exact hs csInf_of_not_bddBelow := fun s hs ↦ by simp at hs } diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index d641dd5a6a1f61..c86d92d8f736bf 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -1025,8 +1025,8 @@ theorem HasBasis.liminf_eq_ciSup_ciInf {v : Filter ι} apply (Iic_ciInf _).symm change liminfReparam f s p j ∈ m by_cases Hj : j ∈ m - · simpa only [m, liminfReparam, if_pos Hj] using Hj - · simp only [m, liminfReparam, if_neg Hj] + · simpa only [m, liminfReparam, ite_eq_left Hj] using Hj + · simp only [m, liminfReparam, ite_eq_right Hj] have Z : ∃ n, (exists_surjective_nat (Subtype p)).choose n ∈ m ∨ ∀ j, j ∉ m := by rcases (exists_surjective_nat (Subtype p)).choose_spec j0 with ⟨n, rfl⟩ exact ⟨n, Or.inl hj0⟩ @@ -1045,16 +1045,16 @@ theorem HasBasis.liminf_eq_ite {v : Filter ι} {p : ι' → Prop} {s : ι' → S if ∀ (j : Subtype p), ¬BddBelow (range (fun (i : s j) ↦ f i)) then sSup ∅ else ⨆ (j : Subtype p), ⨅ (i : s (liminfReparam f s p j)), f i := by by_cases H : ∃ (j : Subtype p), s j = ∅ - · rw [if_pos H] + · rw [ite_eq_left H] rcases H with ⟨j, hj⟩ simp [hv.liminf_eq_sSup_univ_of_empty j j.2 hj] - rw [if_neg H] + rw [ite_eq_right H] by_cases H' : ∀ (j : Subtype p), ¬BddBelow (range (fun (i : s j) ↦ f i)) · have A : ∀ (j : Subtype p), ⋂ (i : s j), Iic (f i) = ∅ := by simp_rw [← not_nonempty_iff_eq_empty, nonempty_iInter_Iic_iff] exact H' - simp_rw [if_pos H', hv.liminf_eq_sSup_iUnion_iInter, A, iUnion_empty] - rw [if_neg H'] + simp_rw [ite_eq_left H', hv.liminf_eq_sSup_iUnion_iInter, A, iUnion_empty] + rw [ite_eq_right H'] apply hv.liminf_eq_ciSup_ciInf · push Not at H simpa only [nonempty_iff_ne_empty] using H diff --git a/Mathlib/Order/Monotone/Extension.lean b/Mathlib/Order/Monotone/Extension.lean index be45a28c643bea..422d0c3cfc3b63 100644 --- a/Mathlib/Order/Monotone/Extension.lean +++ b/Mathlib/Order/Monotone/Extension.lean @@ -37,11 +37,11 @@ theorem MonotoneOn.exists_monotone_extension (h : MonotoneOn f s) (hl : BddBelow intro x hx simp only [g] have : IsGreatest (Iic x ∩ s) x := ⟨⟨self_mem_Iic, hx⟩, fun y hy => hy.1⟩ - rw [if_neg this.nonempty.not_disjoint, + rw [ite_eq_right this.nonempty.not_disjoint, ((h.mono inter_subset_right).map_isGreatest this).csSup_eq] refine ⟨g, fun x y hxy => ?_, hgs⟩ by_cases hx : Disjoint (Iic x) s <;> by_cases hy : Disjoint (Iic y) s <;> - simp only [g, if_pos, if_neg, not_false_iff, *, refl] + simp only [g, ite_eq_left, ite_eq_right, not_false_iff, *, refl] · rcases not_disjoint_iff_nonempty_inter.1 hy with ⟨z, hz⟩ exact le_csSup_of_le (hu' _) (mem_image_of_mem _ hz) (ha <| mem_image_of_mem _ hz.2) · exact (hx <| hy.mono_left <| Iic_subset_Iic.2 hxy).elim diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 099f11bdb9715e..9a7b22e27a36fb 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -342,11 +342,11 @@ theorem ωSup_eq_some {c : Chain (Part α)} {a : α} (h : some a ∈ c) : Part. have : ∃ a, some a ∈ c := ⟨a, h⟩ have a' : some (Classical.choose this) ∈ c := Classical.choose_spec this calc - Part.ωSup c = some (Classical.choose this) := dif_pos this + Part.ωSup c = some (Classical.choose this) := dite_eq_left this _ = some a := congr_arg _ (eq_of_chain a' h) theorem ωSup_eq_none {c : Chain (Part α)} (h : ¬∃ a, some a ∈ c) : Part.ωSup c = none := - dif_neg h + dite_eq_right h theorem mem_chain_of_mem_ωSup {c : Chain (Part α)} {a : α} (h : a ∈ Part.ωSup c) : some a ∈ c := by simp only [Part.ωSup] at h; split_ifs at h with h_1 @@ -381,7 +381,7 @@ theorem mem_ωSup (x : α) (c : Chain (Part α)) : x ∈ ωSup c ↔ some x ∈ · exact fun a ↦ mem_chain_of_mem_ωSup a · intro h have h' : ∃ a : α, some a ∈ c := ⟨_, h⟩ - rw [dif_pos h'] + rw [dite_eq_left h'] have hh := Classical.choose_spec h' rw [eq_of_chain hh h] simp diff --git a/Mathlib/Order/OrderIsoNat.lean b/Mathlib/Order/OrderIsoNat.lean index 894c448ba1d659..e30fc68cf33440 100644 --- a/Mathlib/Order/OrderIsoNat.lean +++ b/Mathlib/Order/OrderIsoNat.lean @@ -295,7 +295,7 @@ theorem exists_covBy_seq_of_wellFoundedLT_wellFoundedGT (α) [Preorder α] refine ⟨a, isMin_iff_forall_not_lt.mpr fun _ ↦ wfl.wf.not_lt_min _ (Set.mem_univ _), ?_⟩ have cov n (hn : ¬ IsMax (a n)) : a n ⋖ a (n + 1) := by change a n ⋖ if ha : IsMax (a n) then a n else _ - rw [dif_neg hn] + rw [dite_eq_right hn] exact hnext hn have H : ∃ n, IsMax (a n) := by by_contra! diff --git a/Mathlib/Order/Partition/Basic.lean b/Mathlib/Order/Partition/Basic.lean index d69a518d279de9..78f0fbb6df74be 100644 --- a/Mathlib/Order/Partition/Basic.lean +++ b/Mathlib/Order/Partition/Basic.lean @@ -528,7 +528,7 @@ lemma exists_extend_partial (P : Partition u) (f₀ : t → α) · exact h.choose_spec.trans <| h_mem h.choose h.choose_spec.right_mem push Not at h exact P.rep_rel (P.partOf_mem ha) (P.mem_partOf ha) - · simp_rw [hfdef, dif_pos hab.left_mem, dif_pos hab.right_mem] + · simp_rw [hfdef, dite_eq_left hab.left_mem, dite_eq_left hab.right_mem] split_ifs with h₁ h₂ h₂ · exact h_eq _ _ <| (hab.symm.trans h₁.choose_spec).symm.trans h₂.choose_spec · exact h₂ ⟨_, hab.symm.trans h₁.choose_spec⟩ |>.elim diff --git a/Mathlib/Order/Preorder/Chain.lean b/Mathlib/Order/Preorder/Chain.lean index 0e11d2201928e7..8d63c5356657fd 100644 --- a/Mathlib/Order/Preorder/Chain.lean +++ b/Mathlib/Order/Preorder/Chain.lean @@ -300,13 +300,13 @@ noncomputable def SuccChain (r : α → α → Prop) (s : Set α) : Set α := theorem succChain_spec (h : ∃ t, IsChain r s ∧ SuperChain r s t) : SuperChain r s (SuccChain r s) := by have : IsChain r s ∧ SuperChain r s h.choose := h.choose_spec - simpa [SuccChain, dif_pos, exists_and_left.mp h] using this.2 + simpa [SuccChain, dite_eq_left, exists_and_left.mp h] using this.2 theorem IsChain.succ (hs : IsChain r s) : IsChain r (SuccChain r s) := by if h : ∃ t, IsChain r s ∧ SuperChain r s t then exact (succChain_spec h).1 else rw [exists_and_left] at h - simpa [SuccChain, dif_neg, h] using hs + simpa [SuccChain, dite_eq_right, h] using hs theorem IsChain.superChain_succChain (hs₁ : IsChain r s) (hs₂ : ¬IsMaxChain r s) : SuperChain r s (SuccChain r s) := by diff --git a/Mathlib/Order/Std.lean b/Mathlib/Order/Std.lean index cc4f6df8be5f5f..04b53b95d03eb7 100644 --- a/Mathlib/Order/Std.lean +++ b/Mathlib/Order/Std.lean @@ -269,14 +269,14 @@ def LinearOrder.ofStd (α : Type*) (args : OfStdArgs α := by exact {}) : Linear toDecidableLT := args.decidableLT toMin := args.min toMax := args.max - min_def _ _ := Std.min_eq_if + min_def _ _ := Std.min_eq_ite max_def a b := by - rw [Std.max_eq_if] + rw [Std.max_eq_ite] split · split · exact Std.le_antisymm ‹_› ‹_› · rfl - case _ h => rw [if_pos (Std.le_of_lt (Std.not_le.mp h))] + case _ h => rw [ite_eq_left (Std.le_of_lt (Std.not_le.mp h))] toOrd := args.ord compare_eq_compareOfLessAndEq a b := by let := args.ord diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 169c6c0dcfdd70..8834b951cd4bea 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -117,9 +117,9 @@ noncomputable def SuccOrder.ofLinearWellFoundedLT [WellFoundedLT α] : SuccOrder ofCore (fun a ↦ if h : (Ioi a).Nonempty then wellFounded_lt.min _ h else a) (fun ha _ ↦ by rw [not_isMax_iff] at ha - simp_rw [Set.Nonempty, mem_Ioi, dif_pos ha] + simp_rw [Set.Nonempty, mem_Ioi, dite_eq_left ha] exact ⟨wellFounded_lt.min_le (s := Ioi _), lt_of_lt_of_le (wellFounded_lt.prop_min ha)⟩) - fun _ ha ↦ dif_neg (not_not_intro ha <| not_isMax_iff.mpr ·) + fun _ ha ↦ dite_eq_right (not_not_intro ha <| not_isMax_iff.mpr ·) end LinearOrder @@ -752,11 +752,11 @@ instance : SuccOrder (WithTop α) where @[to_dual (attr := simp)] theorem succ_coe_of_isMax {a : α} (h : IsMax a) : succ ↑a = (⊤ : WithTop α) := - dif_pos (succ_eq_iff_isMax.2 h) + dite_eq_left (succ_eq_iff_isMax.2 h) @[to_dual] theorem succ_coe_of_not_isMax {a : α} (h : ¬ IsMax a) : succ (↑a : WithTop α) = ↑(succ a) := - dif_neg (succ_eq_iff_isMax.not.2 h) + dite_eq_right (succ_eq_iff_isMax.not.2 h) @[to_dual (attr := simp)] theorem succ_coe [NoMaxOrder α] {a : α} : succ (↑a : WithTop α) = ↑(succ a) := diff --git a/Mathlib/Order/SuccPred/Limit.lean b/Mathlib/Order/SuccPred/Limit.lean index 1a90f86fa04ee4..356865adfd9d51 100644 --- a/Mathlib/Order/SuccPred/Limit.lean +++ b/Mathlib/Order/SuccPred/Limit.lean @@ -568,7 +568,7 @@ noncomputable def isSuccPrelimitRecOn : motive b := @[to_dual] theorem isSuccPrelimitRecOn_of_isSuccPrelimit (hb : IsSuccPrelimit b) : isSuccPrelimitRecOn b succ isSuccPrelimit = isSuccPrelimit b hb := - dif_pos hb + dite_eq_left hb end PartialOrder @@ -582,7 +582,7 @@ theorem isSuccPrelimitRecOn_succ_of_not_isMax (hb : ¬IsMax b) : isSuccPrelimitRecOn (Order.succ b) succ isSuccPrelimit = succ b hb := by have hb' := mt IsSuccPrelimit.isMax hb have H := Classical.choose_spec (not_isSuccPrelimit_iff_succ_eq.1 hb') - rw [isSuccPrelimitRecOn, dif_neg hb', cast_eq_iff_heq] + rw [isSuccPrelimitRecOn, dite_eq_right hb', cast_eq_iff_heq] congr! exact (succ_eq_succ_iff_of_not_isMax H.1 hb).1 H.2 @@ -618,7 +618,7 @@ noncomputable def isSuccLimitRecOn : motive b := theorem isSuccLimitRecOn_of_isSuccLimit (hb : IsSuccLimit b) : isSuccLimitRecOn b isMin succ isSuccLimit = isSuccLimit b hb := by rw [isSuccLimitRecOn, isSuccPrelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, - dif_neg hb.not_isMin] + dite_eq_right hb.not_isMin] end PartialOrder @@ -641,7 +641,8 @@ theorem isSuccLimitRecOn_succ [NoMaxOrder α] (b : α) : @[to_dual] theorem isSuccLimitRecOn_of_isMin (hb : IsMin b) : isSuccLimitRecOn b isMin succ isSuccLimit = isMin b hb := by - rw [isSuccLimitRecOn, isSuccPrelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, dif_pos hb] + rw [isSuccLimitRecOn, isSuccPrelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, + dite_eq_left hb] end LinearOrder @@ -677,7 +678,7 @@ noncomputable def prelimitRecOn : motive b := theorem prelimitRecOn_of_isSuccPrelimit (hb : IsSuccPrelimit b) : prelimitRecOn b succ isSuccPrelimit = isSuccPrelimit b hb fun x _ ↦ SuccOrder.prelimitRecOn x succ isSuccPrelimit := by - rw [prelimitRecOn, WellFounded.fix_eq, dif_pos hb]; rfl + rw [prelimitRecOn, WellFounded.fix_eq, dite_eq_left hb]; rfl end PartialOrder @@ -693,7 +694,7 @@ theorem prelimitRecOn_succ_of_not_isMax (hb : ¬IsMax b) : succ b hb (prelimitRecOn b succ isSuccPrelimit) := by have h := mt IsSuccPrelimit.isMax hb have H := Classical.choose_spec (not_isSuccPrelimit_iff_succ_eq.1 h) - rw [prelimitRecOn, WellFounded.fix_eq, dif_neg h] + rw [prelimitRecOn, WellFounded.fix_eq, dite_eq_right h] have {a c : α} {ha hc} {x : ∀ a, motive a} (h : a = c) : cast (congr_arg (motive ∘ Order.succ) h) (succ a ha (x a)) = succ c hc (x c) := by subst h; rfl exact this <| (succ_eq_succ_iff_of_not_isMax H.1 hb).1 H.2 @@ -729,13 +730,14 @@ noncomputable def limitRecOn : motive b := @[to_dual (attr := simp)] theorem limitRecOn_isMin (hb : IsMin b) : limitRecOn b isMin succ isSuccLimit = isMin b hb := by - rw [limitRecOn, prelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, dif_pos hb] + rw [limitRecOn, prelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, dite_eq_left hb] @[to_dual (attr := simp)] theorem limitRecOn_of_isSuccLimit (hb : IsSuccLimit b) : limitRecOn b isMin succ isSuccLimit = isSuccLimit b hb fun x _ ↦ limitRecOn x isMin succ isSuccLimit := by - rw [limitRecOn, prelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, dif_neg hb.not_isMin]; rfl + rw [limitRecOn, prelimitRecOn_of_isSuccPrelimit _ _ hb.isSuccPrelimit, + dite_eq_right hb.not_isMin]; rfl end PartialOrder diff --git a/Mathlib/Order/SuccPred/LinearLocallyFinite.lean b/Mathlib/Order/SuccPred/LinearLocallyFinite.lean index 20c07a049918b8..df42132d209313 100644 --- a/Mathlib/Order/SuccPred/LinearLocallyFinite.lean +++ b/Mathlib/Order/SuccPred/LinearLocallyFinite.lean @@ -213,11 +213,11 @@ def toZ (i0 i : ι) : ℤ := -Nat.find (exists_pred_iterate_of_le (α := ι) (not_le.mp hi).le) theorem toZ_of_ge (hi : i0 ≤ i) : toZ i0 i = Nat.find (exists_succ_iterate_of_le hi) := - dif_pos hi + dite_eq_left hi theorem toZ_of_lt (hi : i < i0) : toZ i0 i = -Nat.find (exists_pred_iterate_of_le (α := ι) hi.le) := - dif_neg (not_le.mpr hi) + dite_eq_right (not_le.mpr hi) @[simp] theorem toZ_of_eq : toZ i0 i0 = 0 := by @@ -360,17 +360,17 @@ noncomputable def orderIsoIntOfLinearSuccPredArch [NoMaxOrder ι] [NoMinOrder ι left_inv i := by rcases le_or_gt hι.some i with hi | hi · have h_nonneg : 0 ≤ toZ hι.some i := toZ_nonneg hi - simp_rw [if_pos h_nonneg] + simp_rw [ite_eq_left h_nonneg] exact iterate_succ_toZ i hi · have h_neg : toZ hι.some i < 0 := toZ_neg hi - simp_rw [if_neg (not_le.mpr h_neg)] + simp_rw [ite_eq_right (not_le.mpr h_neg)] exact iterate_pred_toZ i hi right_inv n := by rcases le_or_gt 0 n with hn | hn - · simp_rw [if_pos hn] + · simp_rw [ite_eq_left hn] rw [toZ_iterate_succ] exact Int.toNat_of_nonneg hn - · simp_rw [if_neg (not_le.mpr hn)] + · simp_rw [ite_eq_right (not_le.mpr hn)] rw [toZ_iterate_pred] simp only [hn.le, Int.toNat_of_nonneg, Int.neg_nonneg_of_nonpos, Int.neg_neg] map_rel_iff' := by simp diff --git a/Mathlib/Order/WellFoundedSet.lean b/Mathlib/Order/WellFoundedSet.lean index d3312cd54e6acf..ba3bd1e2318987 100644 --- a/Mathlib/Order/WellFoundedSet.lean +++ b/Mathlib/Order/WellFoundedSet.lean @@ -846,9 +846,9 @@ theorem partiallyWellOrderedOn_sublistForall₂ (r : α → α → Prop) [IsPreo obtain ⟨g, hg⟩ := h.exists_monotone_subseq fun n => hf1.1 n _ (List.head!_mem_self (hnil n)) have hf' := hf2 (g 0) (fun n => if n < g 0 then f n else List.tail (f (g (n - g 0)))) - (fun m hm => (if_pos hm).symm) ?_ + (fun m hm => (ite_eq_left hm).symm) ?_ swap - · simp only [if_neg (lt_irrefl (g 0)), Nat.sub_self] + · simp only [ite_eq_right (lt_irrefl (g 0)), Nat.sub_self] rw [List.length_tail, ← Nat.pred_eq_sub_one] exact Nat.pred_lt fun con => hnil _ (List.length_eq_zero_iff.1 con) rw [IsBadSeq] at hf' @@ -858,9 +858,9 @@ theorem partiallyWellOrderedOn_sublistForall₂ (r : α → α → Prop) [IsPreo exacts [hf1.1 _ _ hx, hf1.1 _ _ (List.tail_subset _ hx)] by_cases hn : n < g 0 · apply hf1.2 m n mn - rwa [if_pos hn, if_pos (mn.trans hn)] at hmn + rwa [ite_eq_left hn, ite_eq_left (mn.trans hn)] at hmn · obtain ⟨n', rfl⟩ := Nat.exists_eq_add_of_le (not_lt.1 hn) - rw [if_neg hn, add_comm (g 0) n', Nat.add_sub_cancel_right] at hmn + rw [ite_eq_right hn, add_comm (g 0) n', Nat.add_sub_cancel_right] at hmn split_ifs at hmn with hm · apply hf1.2 m (g n') (lt_of_lt_of_le hm (g.monotone n'.zero_le)) exact _root_.trans hmn (List.tail_sublistForall₂_self _) diff --git a/Mathlib/Probability/Distributions/Beta.lean b/Mathlib/Probability/Distributions/Beta.lean index 04cc8de4a49590..2dd2f01818b6d3 100644 --- a/Mathlib/Probability/Distributions/Beta.lean +++ b/Mathlib/Probability/Distributions/Beta.lean @@ -73,7 +73,7 @@ lemma betaPDF_eq_zero_of_one_le {α β x : ℝ} (hx : 1 ≤ x) : lemma betaPDF_of_pos_lt_one {α β x : ℝ} (hx_pos : 0 < x) (hx_lt : x < 1) : betaPDF α β x = ENNReal.ofReal ((1 / beta α β) * x ^ (α - 1) * (1 - x) ^ (β - 1)) := by - rw [betaPDF_eq, if_pos ⟨hx_pos, hx_lt⟩] + rw [betaPDF_eq, ite_eq_left ⟨hx_pos, hx_lt⟩] lemma lintegral_betaPDF {α β : ℝ} : ∫⁻ x, betaPDF α β x = @@ -89,7 +89,7 @@ lemma lintegral_betaPDF {α β : ℝ} : /-- The beta pdf is positive for all positive reals with positive parameters. -/ lemma betaPDFReal_pos {α β x : ℝ} (hx1 : 0 < x) (hx2 : x < 1) (hα : 0 < α) (hβ : 0 < β) : 0 < betaPDFReal α β x := by - rw [betaPDFReal, if_pos ⟨hx1, hx2⟩] + rw [betaPDFReal, ite_eq_left ⟨hx1, hx2⟩] exact mul_pos (mul_pos (one_div_pos.2 (beta_pos hα hβ)) (Real.rpow_pos_of_pos hx1 (α - 1))) (Real.rpow_pos_of_pos (by linarith) (β - 1)) @@ -122,7 +122,7 @@ lemma lintegral_betaPDF_eq_one {α β : ℝ} (hα : 0 < α) (hβ : 0 < β) : rw [intervalIntegrable_iff_integrableOn_Ioc_of_le (by simp), IntegrableOn] · refine ae_restrict_of_forall_mem measurableSet_Ioo (fun x hx ↦ ?_) convert! betaPDFReal_pos hx.1 hx.2 hα hβ |>.le using 1 - rw [betaPDFReal, if_pos ⟨hx.1, hx.2⟩] + rw [betaPDFReal, ite_eq_left ⟨hx.1, hx.2⟩] · exact Measurable.aestronglyMeasurable (by fun_prop) end BetaPDF diff --git a/Mathlib/Probability/Distributions/Cauchy.lean b/Mathlib/Probability/Distributions/Cauchy.lean index e586a71e577c8f..e797ca93bbb7ef 100644 --- a/Mathlib/Probability/Distributions/Cauchy.lean +++ b/Mathlib/Probability/Distributions/Cauchy.lean @@ -174,13 +174,13 @@ noncomputable def cauchyMeasure (x₀ : ℝ) (γ : ℝ≥0) : Measure ℝ := alias _root_Probability.cauchyMeasure := cauchyMeasure lemma cauchyMeasure_of_scale_ne_zero (x₀ : ℝ) {γ : ℝ≥0} (hγ : γ ≠ 0) : - cauchyMeasure x₀ γ = volume.withDensity (cauchyPDF x₀ γ) := if_neg hγ + cauchyMeasure x₀ γ = volume.withDensity (cauchyPDF x₀ γ) := ite_eq_right hγ @[deprecated (since := "2026-03-06")] alias _root_Probability.cauchyMeasure_of_scale_ne_zero := cauchyMeasure_of_scale_ne_zero @[simp] -lemma cauchyMeasure_zero_scale (x₀ : ℝ) : cauchyMeasure x₀ 0 = dirac x₀ := if_pos rfl +lemma cauchyMeasure_zero_scale (x₀ : ℝ) : cauchyMeasure x₀ 0 = dirac x₀ := ite_eq_left rfl @[deprecated (since := "2026-03-06")] alias _root_Probability.cauchyMeasure_zero_scale := cauchyMeasure_zero_scale diff --git a/Mathlib/Probability/Distributions/Exponential.lean b/Mathlib/Probability/Distributions/Exponential.lean index 20f6e8d2b2bedc..41ba83e7ebf8b5 100644 --- a/Mathlib/Probability/Distributions/Exponential.lean +++ b/Mathlib/Probability/Distributions/Exponential.lean @@ -55,7 +55,7 @@ lemma exponentialPDF_of_neg {r x : ℝ} (hx : x < 0) : exponentialPDF r x = 0 := lemma exponentialPDF_of_nonneg {r x : ℝ} (hx : 0 ≤ x) : exponentialPDF r x = ENNReal.ofReal (r * rexp (-(r * x))) := by - simp only [exponentialPDF_eq, if_pos hx] + simp only [exponentialPDF_eq, ite_eq_left hx] /-- The Lebesgue integral of the exponential pdf over nonpositive reals equals 0 -/ lemma lintegral_exponentialPDF_of_nonpos {x r : ℝ} (hx : x ≤ 0) : @@ -129,7 +129,7 @@ lemma lintegral_exponentialPDF_eq_antiDeriv {r : ℝ} (hr : 0 < r) (x : ℝ) : case neg => simp only [exponentialPDF_eq] rw [setLIntegral_congr_fun measurableSet_Iic, lintegral_zero, ENNReal.ofReal_zero] - exact fun a (_ : a ≤ _) ↦ by rw [if_neg (by linarith), ENNReal.ofReal_eq_zero] + exact fun a (_ : a ≤ _) ↦ by rw [ite_eq_right (by linarith), ENNReal.ofReal_eq_zero] case pos => rw [lintegral_Iic_eq_lintegral_Iio_add_Icc _ h, lintegral_exponentialPDF_of_nonpos (le_refl 0), zero_add] @@ -140,7 +140,7 @@ lemma lintegral_exponentialPDF_eq_antiDeriv {r : ℝ} (hr : 0 < r) (x : ℝ) : ← integral_eq_lintegral_of_nonneg_ae (Eventually.of_forall fun _ ↦ le_of_lt (mul_pos hr (exp_pos _)))] · have : ∫ a in uIoc 0 x, r * rexp (-(r * a)) = ∫ a in 0..x, r * rexp (-(r * a)) := by - rw [intervalIntegral.intervalIntegral_eq_integral_uIoc, smul_eq_mul, if_pos h, one_mul] + rw [intervalIntegral.intervalIntegral_eq_integral_uIoc, smul_eq_mul, ite_eq_left h, one_mul] rw [integral_Icc_eq_integral_Ioc, ← uIoc_of_le h, this] rw [intervalIntegral.integral_eq_sub_of_hasDeriv_right_of_le h (f := fun a ↦ -1 * rexp (-(r * a))) _ _] diff --git a/Mathlib/Probability/Distributions/Gamma.lean b/Mathlib/Probability/Distributions/Gamma.lean index e1e44fae312943..b0b4bf1f10b979 100644 --- a/Mathlib/Probability/Distributions/Gamma.lean +++ b/Mathlib/Probability/Distributions/Gamma.lean @@ -56,11 +56,11 @@ lemma gammaPDF_eq (a r x : ℝ) : rfl lemma gammaPDF_of_neg {a r x : ℝ} (hx : x < 0) : gammaPDF a r x = 0 := by - simp only [gammaPDF_eq, if_neg (not_le.mpr hx), ENNReal.ofReal_zero] + simp only [gammaPDF_eq, ite_eq_right (not_le.mpr hx), ENNReal.ofReal_zero] lemma gammaPDF_of_nonneg {a r x : ℝ} (hx : 0 ≤ x) : gammaPDF a r x = ENNReal.ofReal (r ^ a / (Gamma a) * x ^ (a - 1) * exp (-(r * x))) := by - simp only [gammaPDF_eq, if_pos hx] + simp only [gammaPDF_eq, ite_eq_left hx] /-- The Lebesgue integral of the gamma pdf over nonpositive reals equals 0 -/ lemma lintegral_gammaPDF_of_nonpos {x a r : ℝ} (hx : x ≤ 0) : @@ -69,7 +69,7 @@ lemma lintegral_gammaPDF_of_nonpos {x a r : ℝ} (hx : x ≤ 0) : · rw [lintegral_zero, ← ENNReal.ofReal_zero] · intro a (_ : a < _) simp only [gammaPDF_eq, ENNReal.ofReal_eq_zero] - rw [if_neg (by linarith)] + rw [ite_eq_right (by linarith)] /-- The gamma pdf is measurable. -/ @[fun_prop] @@ -86,7 +86,7 @@ lemma stronglyMeasurable_gammaPDFReal (a r : ℝ) : /-- The gamma pdf is positive for all positive reals -/ lemma gammaPDFReal_pos {x a r : ℝ} (ha : 0 < a) (hr : 0 < r) (hx : 0 < x) : 0 < gammaPDFReal a r x := by - simp only [gammaPDFReal, if_pos hx.le] + simp only [gammaPDFReal, ite_eq_left hx.le] positivity /-- The gamma pdf is nonnegative -/ diff --git a/Mathlib/Probability/Distributions/Gaussian/Real.lean b/Mathlib/Probability/Distributions/Gaussian/Real.lean index f6c73c3aa20c46..f15479f0f54452 100644 --- a/Mathlib/Probability/Distributions/Gaussian/Real.lean +++ b/Mathlib/Probability/Distributions/Gaussian/Real.lean @@ -223,10 +223,10 @@ def gaussianReal (μ : ℝ) (v : ℝ≥0) : Measure ℝ := if v = 0 then Measure.dirac μ else volume.withDensity (gaussianPDF μ v) lemma gaussianReal_of_var_ne_zero (μ : ℝ) {v : ℝ≥0} (hv : v ≠ 0) : - gaussianReal μ v = volume.withDensity (gaussianPDF μ v) := if_neg hv + gaussianReal μ v = volume.withDensity (gaussianPDF μ v) := ite_eq_right hv @[simp] -lemma gaussianReal_zero_var (μ : ℝ) : gaussianReal μ 0 = Measure.dirac μ := if_pos rfl +lemma gaussianReal_zero_var (μ : ℝ) : gaussianReal μ 0 = Measure.dirac μ := ite_eq_left rfl instance instIsProbabilityMeasureGaussianReal (μ : ℝ) (v : ℝ≥0) : IsProbabilityMeasure (gaussianReal μ v) where diff --git a/Mathlib/Probability/Distributions/Geometric.lean b/Mathlib/Probability/Distributions/Geometric.lean index a73c3605ea835a..8631d30f90e8c9 100644 --- a/Mathlib/Probability/Distributions/Geometric.lean +++ b/Mathlib/Probability/Distributions/Geometric.lean @@ -58,7 +58,7 @@ noncomputable def geometricMeasure (p : unitInterval) : Measure ℕ := if p ≠ lemma geometricMeasure_eq (hp : p ≠ 0) : geometricMeasure p = Measure.sum (fun n ↦ ENNReal.ofReal ((1 - p) ^ n * p) • .dirac n) := - if_pos hp + ite_eq_left hp /-- The `positivty` tactic does not work for this goal. Use this lemma to rewrite `(ENNReal.ofReal ((1 - p) ^ n * p)).toReal = (1 - p) ^ n * p`. -/ diff --git a/Mathlib/Probability/Distributions/Pareto.lean b/Mathlib/Probability/Distributions/Pareto.lean index 9a05a58ed3fc21..249e2669ac7b85 100644 --- a/Mathlib/Probability/Distributions/Pareto.lean +++ b/Mathlib/Probability/Distributions/Pareto.lean @@ -45,11 +45,11 @@ lemma paretoPDF_eq (t r x : ℝ) : paretoPDF t r x = ENNReal.ofReal (if t ≤ x then r * t ^ r * x ^ (-(r + 1)) else 0) := rfl lemma paretoPDF_of_lt (hx : x < t) : paretoPDF t r x = 0 := by - simp only [paretoPDF_eq, if_neg (not_le.mpr hx), ENNReal.ofReal_zero] + simp only [paretoPDF_eq, ite_eq_right (not_le.mpr hx), ENNReal.ofReal_zero] lemma paretoPDF_of_le (hx : t ≤ x) : paretoPDF t r x = ENNReal.ofReal (r * t ^ r * x ^ (-(r + 1))) := by - simp only [paretoPDF_eq, if_pos hx] + simp only [paretoPDF_eq, ite_eq_left hx] /-- The Lebesgue integral of the Pareto pdf over reals `≤ t` equals `0`. -/ lemma lintegral_paretoPDF_of_le (hx : x ≤ t) : @@ -58,7 +58,7 @@ lemma lintegral_paretoPDF_of_le (hx : x ≤ t) : · rw [lintegral_zero, ← ENNReal.ofReal_zero] · intro a (_ : a < _) simp only [paretoPDF_eq, ENNReal.ofReal_eq_zero] - rw [if_neg (by linarith)] + rw [ite_eq_right (by linarith)] /-- The Pareto pdf is measurable. -/ @[fun_prop] @@ -74,7 +74,7 @@ lemma stronglyMeasurable_paretoPDFReal (t r : ℝ) : /-- The Pareto pdf is positive for all reals `>= t`. -/ lemma paretoPDFReal_pos (ht : 0 < t) (hr : 0 < r) (hx : t ≤ x) : 0 < paretoPDFReal t r x := by - rw [paretoPDFReal, if_pos hx] + rw [paretoPDFReal, ite_eq_left hx] have _ : 0 < x := by linarith positivity diff --git a/Mathlib/Probability/Distributions/Uniform.lean b/Mathlib/Probability/Distributions/Uniform.lean index ab9a9ec0f78a7b..ae69a97e9fab5e 100644 --- a/Mathlib/Probability/Distributions/Uniform.lean +++ b/Mathlib/Probability/Distributions/Uniform.lean @@ -221,7 +221,7 @@ def uniformOfFinset (s : Finset α) (hs : s.Nonempty) : PMF α := by simpa only [Ne, Nat.cast_eq_zero, Finset.card_eq_zero] using Finset.nonempty_iff_ne_empty.1 hs exact ENNReal.mul_inv_cancel this <| ENNReal.natCast_ne_top s.card - · exact fun x hx => by simp only [hx, if_false] + · exact fun x hx => by simp only [hx, ite_false] variable {s : Finset α} (hs : s.Nonempty) {a : α} @@ -261,11 +261,11 @@ theorem toOuterMeasure_uniformOfFinset_apply : _ = ∑' x, if x ∈ s ∧ x ∈ t then (#s : ℝ≥0∞)⁻¹ else 0 := tsum_congr fun x => by simp_rw [uniformOfFinset_apply, ← ite_and, and_comm] _ = ∑ x ∈ s with x ∈ t, if x ∈ s ∧ x ∈ t then (#s : ℝ≥0∞)⁻¹ else 0 := - tsum_eq_sum fun _ hx => if_neg fun h => hx (Finset.mem_filter.2 h) + tsum_eq_sum fun _ hx => ite_eq_right fun h => hx (Finset.mem_filter.2 h) _ = ∑ x ∈ s with x ∈ t, (#s : ℝ≥0∞)⁻¹ := Finset.sum_congr rfl fun x hx => by have : x ∈ s ∧ x ∈ t := by simpa using hx - simp only [this, and_self_iff, if_true] + simp only [this, and_self_iff, ite_true] _ = #{x ∈ s | x ∈ t} / #s := by simp only [div_eq_mul_inv, Finset.sum_const, nsmul_eq_mul] diff --git a/Mathlib/Probability/IdentDistrib.lean b/Mathlib/Probability/IdentDistrib.lean index 2bfc13bbd8f5ff..10e8ade1728e7f 100644 --- a/Mathlib/Probability/IdentDistrib.lean +++ b/Mathlib/Probability/IdentDistrib.lean @@ -205,8 +205,8 @@ theorem eLpNorm_eq [NormedAddCommGroup γ] [OpensMeasurableSpace γ] (h : IdentD by_cases h0 : p = 0 · simp [h0] by_cases h_top : p = ∞ - · simp only [h_top, eLpNorm, eLpNormEssSup, ENNReal.top_ne_zero, if_true, - if_false] + · simp only [h_top, eLpNorm, eLpNormEssSup, ENNReal.top_ne_zero, ite_true, + ite_false] apply essSup_eq exact h.comp (measurable_coe_nnreal_ennreal.comp measurable_nnnorm) simp only [eLpNorm_eq_eLpNorm' h0 h_top, eLpNorm', one_div] diff --git a/Mathlib/Probability/Independence/Conditional.lean b/Mathlib/Probability/Independence/Conditional.lean index 7f28cf57c2fdd8..cad164fc93016f 100644 --- a/Mathlib/Probability/Independence/Conditional.lean +++ b/Mathlib/Probability/Independence/Conditional.lean @@ -682,12 +682,12 @@ theorem iCondIndepFun_iff_condExp_inter_preimage_eq_mul {β : ι → Type*} · classical let g := fun i ↦ if hi : i ∈ s then (h_sets i hi).choose else Set.univ specialize h s (sets := g) (fun i hi ↦ ?_) - · simp only [g, dif_pos hi] + · simp only [g, dite_eq_left hi] exact (h_sets i hi).choose_spec.1 · have hg : ∀ i ∈ s, sets i = f i ⁻¹' g i := by intro i hi rw [(h_sets i hi).choose_spec.2.symm] - simp only [g, dif_pos hi] + simp only [g, dite_eq_left hi] convert! h with i hi i hi <;> exact hg i hi theorem condIndepFun_iff_condIndepSet_preimage {mβ : MeasurableSpace β} {mβ' : MeasurableSpace β'} diff --git a/Mathlib/Probability/Independence/Kernel/Indep.lean b/Mathlib/Probability/Independence/Kernel/Indep.lean index b80f009deda3c9..361bc7a864cdaa 100644 --- a/Mathlib/Probability/Independence/Kernel/Indep.lean +++ b/Mathlib/Probability/Independence/Kernel/Indep.lean @@ -555,10 +555,10 @@ theorem indepSets_piiUnionInter_of_disjoint {s : ι → Set (Set Ω)} rw [Finset.mem_union] at hi_mem_union rcases hi_mem_union with hi1 | hi2 · have hi2 : i ∉ p2 := fun hip2 => Set.disjoint_left.mp hST (hp1 hi1) (hp2 hip2) - simp_rw [g, if_pos hi1, if_neg hi2, Set.inter_univ] + simp_rw [g, ite_eq_left hi1, ite_eq_right hi2, Set.inter_univ] exact ht1_m i hi1 · have hi1 : i ∉ p1 := fun hip1 => Set.disjoint_right.mp hST (hp2 hi2) (hp1 hip1) - simp_rw [g, if_neg hi1, if_pos hi2, Set.univ_inter] + simp_rw [g, ite_eq_right hi1, ite_eq_left hi2, Set.univ_inter] exact ht2_m i hi2 have h_p1_inter_p2 : ((⋂ x ∈ p1, f1 x) ∩ ⋂ x ∈ p2, f2 x) = @@ -694,7 +694,7 @@ theorem iIndepSets.piiUnionInter_of_notMem {π : ι → Set (Set Ω)} {a : ι} { suffices h_forall : ∀ n ∈ s, f n = ft1 n by grind intro n hnS have hn_ne_a : n ≠ a := by rintro rfl; exact haS (hs_mem hnS) - simp_rw [f, if_pos hnS, if_neg hn_ne_a] + simp_rw [f, ite_eq_left hnS, ite_eq_right hn_ne_a] have h_μ_t1 : ∀ᵐ a' ∂μ, κ a' t1 = ∏ n ∈ s, κ a' (f n) := by filter_upwards [hp_ind s h_f_mem_pi] with a' ha' rw [h_t1, ← ha'] diff --git a/Mathlib/Probability/Independence/Kernel/IndepFun.lean b/Mathlib/Probability/Independence/Kernel/IndepFun.lean index 42b36162d5e834..e8780ab9b4f32c 100644 --- a/Mathlib/Probability/Independence/Kernel/IndepFun.lean +++ b/Mathlib/Probability/Independence/Kernel/IndepFun.lean @@ -154,11 +154,11 @@ theorem iIndepFun_iff_measure_inter_preimage_eq_mul {ι : Type*} {β : ι → Ty dite (i ∈ S) (fun hi_mem => (h_meas i hi_mem).choose) fun _ => Set.univ have h_measβ : ∀ i ∈ S, MeasurableSet[m i] (setsβ i) := by intro i hi_mem - simp_rw [setsβ, dif_pos hi_mem] + simp_rw [setsβ, dite_eq_left hi_mem] exact (h_meas i hi_mem).choose_spec.1 have h_preim : ∀ i ∈ S, setsΩ i = f i ⁻¹' setsβ i := by intro i hi_mem - simp_rw [setsβ, dif_pos hi_mem] + simp_rw [setsβ, dite_eq_left hi_mem] exact (h_meas i hi_mem).choose_spec.2.symm simp_all @@ -362,17 +362,17 @@ theorem iIndepFun.indepFun_finset (S T : Finset ι) (hST : Disjoint S T) let sets_s' : ∀ i : ι, Set (β i) := fun i => dite (i ∈ S) (fun hi => sets_s ⟨i, hi⟩) fun _ => Set.univ have h_sets_s'_eq : ∀ {i} (hi : i ∈ S), sets_s' i = sets_s ⟨i, hi⟩ := by - intro i hi; simp_rw [sets_s', dif_pos hi] + intro i hi; simp_rw [sets_s', dite_eq_left hi] have h_sets_s'_univ : ∀ {i} (_hi : i ∈ T), sets_s' i = Set.univ := by - intro i hi; simp_rw [sets_s', dif_neg (Finset.disjoint_right.mp hST hi)] + intro i hi; simp_rw [sets_s', dite_eq_right (Finset.disjoint_right.mp hST hi)] let sets_t' : ∀ i : ι, Set (β i) := fun i => dite (i ∈ T) (fun hi => sets_t ⟨i, hi⟩) fun _ => Set.univ have h_sets_t'_univ : ∀ {i} (_hi : i ∈ S), sets_t' i = Set.univ := by - intro i hi; simp_rw [sets_t', dif_neg (Finset.disjoint_left.mp hST hi)] + intro i hi; simp_rw [sets_t', dite_eq_right (Finset.disjoint_left.mp hST hi)] have h_meas_s' : ∀ i ∈ S, MeasurableSet (sets_s' i) := by intro i hi; rw [h_sets_s'_eq hi]; exact hs1 _ have h_meas_t' : ∀ i ∈ T, MeasurableSet (sets_t' i) := by - intro i hi; simp_rw [sets_t', dif_pos hi]; exact ht1 _ + intro i hi; simp_rw [sets_t', dite_eq_left hi]; exact ht1 _ have h_eq_inter_S : (fun (ω : Ω) (i : ↥S) => f (↑i) ω) ⁻¹' Set.pi Set.univ sets_s = ⋂ i ∈ S, f i ⁻¹' sets_s' i := by ext1 x @@ -383,8 +383,8 @@ theorem iIndepFun.indepFun_finset (S T : Finset ι) (hST : Disjoint S T) ext1 x simp only [Set.mem_preimage, Set.mem_univ_pi, Set.mem_iInter] constructor <;> intro h - · intro i hi; simp_rw [sets_t', dif_pos hi]; exact h ⟨i, hi⟩ - · rintro ⟨i, hi⟩; specialize h i hi; simp_rw [sets_t', dif_pos hi] at h; exact h + · intro i hi; simp_rw [sets_t', dite_eq_left hi]; exact h ⟨i, hi⟩ + · rintro ⟨i, hi⟩; specialize h i hi; simp_rw [sets_t', dite_eq_left hi] at h; exact h replace hf_Indep := hf_Indep.congr η_eq rw [iIndepFun_iff_measure_inter_preimage_eq_mul] at hf_Indep have h_Inter_inter : diff --git a/Mathlib/Probability/Independence/Process/HasIndepIncrements/IsGaussianProcess.lean b/Mathlib/Probability/Independence/Process/HasIndepIncrements/IsGaussianProcess.lean index 83a680adb52220..dee92bbb1a33c8 100644 --- a/Mathlib/Probability/Independence/Process/HasIndepIncrements/IsGaussianProcess.lean +++ b/Mathlib/Probability/Independence/Process/HasIndepIncrements/IsGaussianProcess.lean @@ -65,7 +65,7 @@ lemma orderEmbOfFinWithBot_zero : I.orderEmbOfFinWithBot 0 = ⊥ := rfl lemma orderEmbOfFinWithBot_of_ne_zero (i : Fin (#I + 1)) (hi : i ≠ 0) : I.orderEmbOfFinWithBot i = I.orderEmbOfFin rfl (i.pred hi) := by - rw [orderEmbOfFinWithBot, dif_neg hi] + rw [orderEmbOfFinWithBot, dite_eq_right hi] @[simp] lemma orderEmbOfFinWithBot_succ (i : Fin #I) : diff --git a/Mathlib/Probability/Kernel/Composition/ParallelComp.lean b/Mathlib/Probability/Kernel/Composition/ParallelComp.lean index 37945ad527781c..6fe40105c38bc5 100644 --- a/Mathlib/Probability/Kernel/Composition/ParallelComp.lean +++ b/Mathlib/Probability/Kernel/Composition/ParallelComp.lean @@ -65,17 +65,17 @@ scoped[ProbabilityTheory] infixl:100 " ∥ₖ " => ProbabilityTheory.Kernel.para @[simp] lemma parallelComp_of_not_isSFiniteKernel_left (η : Kernel γ δ) (h : ¬ IsSFiniteKernel κ) : κ ∥ₖ η = 0 := by - rw [parallelComp, dif_neg (not_and_of_not_left _ h)] + rw [parallelComp, dite_eq_right (not_and_of_not_left _ h)] @[simp] lemma parallelComp_of_not_isSFiniteKernel_right (κ : Kernel α β) (h : ¬ IsSFiniteKernel η) : κ ∥ₖ η = 0 := by - rw [parallelComp, dif_neg (not_and_of_not_right _ h)] + rw [parallelComp, dite_eq_right (not_and_of_not_right _ h)] lemma parallelComp_apply (κ : Kernel α β) [IsSFiniteKernel κ] (η : Kernel γ δ) [IsSFiniteKernel η] (x : α × γ) : (κ ∥ₖ η) x = (κ x.1).prod (η x.2) := by - rw [parallelComp, dif_pos ⟨inferInstance, inferInstance⟩, coe_mk] + rw [parallelComp, dite_eq_left ⟨inferInstance, inferInstance⟩, coe_mk] lemma parallelComp_apply' [IsSFiniteKernel κ] [IsSFiniteKernel η] {s : Set (β × δ)} (hs : MeasurableSet s) : diff --git a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean index 946cd932ec5be9..eb2c8f33cbfbfc 100644 --- a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean +++ b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean @@ -183,12 +183,12 @@ lemma defaultRatCDF_le_one (q : ℚ) : defaultRatCDF q ≤ 1 := by lemma tendsto_defaultRatCDF_atTop : Tendsto defaultRatCDF atTop (𝓝 1) := by refine (tendsto_congr' ?_).mp tendsto_const_nhds rw [EventuallyEq, eventually_atTop] - exact ⟨0, fun q hq => (if_neg (not_lt.mpr hq)).symm⟩ + exact ⟨0, fun q hq => (ite_eq_right (not_lt.mpr hq)).symm⟩ lemma tendsto_defaultRatCDF_atBot : Tendsto defaultRatCDF atBot (𝓝 0) := by refine (tendsto_congr' ?_).mp tendsto_const_nhds rw [EventuallyEq, eventually_atBot] - refine ⟨-1, fun q hq => (if_pos (hq.trans_lt ?_)).symm⟩ + refine ⟨-1, fun q hq => (ite_eq_left (hq.trans_lt ?_)).symm⟩ linarith set_option backward.isDefEq.respectTransparency false in @@ -205,7 +205,7 @@ lemma iInf_rat_gt_defaultRatCDF (t : ℚ) : · refine le_antisymm ?_ (le_ciInf fun x ↦ ?_) · obtain ⟨q, htq, hq_neg⟩ : ∃ q, t < q ∧ q < 0 := ⟨t / 2, by linarith, by linarith⟩ refine (ciInf_le h_bdd ⟨q, htq⟩).trans ?_ - rw [if_pos] + rw [ite_eq_left] rwa [Subtype.coe_mk] · split_ifs exacts [le_rfl, zero_le_one] @@ -214,7 +214,7 @@ lemma iInf_rat_gt_defaultRatCDF (t : ℚ) : split_ifs exacts [zero_le_one, le_rfl] · refine le_ciInf fun x ↦ ?_ - rw [if_neg] + rw [ite_eq_right] rw [not_lt] at h ⊢ exact h.trans (mem_Ioi.mp x.prop).le @@ -248,7 +248,7 @@ def toRatCDF (f : α → ℚ → ℝ) : α → ℚ → ℝ := fun a ↦ lemma toRatCDF_of_isRatStieltjesPoint {a : α} (h : IsRatStieltjesPoint f a) (q : ℚ) : toRatCDF f a q = f a q := by - rw [toRatCDF, if_pos h] + rw [toRatCDF, ite_eq_left h] lemma toRatCDF_unit_prod (a : α) : toRatCDF (fun (p : Unit × α) ↦ f p.2) ((), a) = toRatCDF f a := by diff --git a/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean b/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean index 95537e43dcba81..2becccfa7b0250 100644 --- a/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean @@ -281,7 +281,7 @@ lemma compProd_fst_borelMarkovFromReal_eq_comapRight_compProd · exact measurable_prodMk_left ht · exact measurable_prodMk_left ht classical - rw [piecewise_apply, if_pos] + rw [piecewise_apply, ite_eq_left] exact ha /-- For `κ' := map κ (Prod.map (id : β → β) e)`, the hypothesis `hη` is `fst κ' ⊗ₖ η = κ'`. diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean b/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean index b0c4f3a7f4d977..742ef9053bb7f5 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/Maps.lean @@ -184,9 +184,9 @@ lemma _root_.IicProdIoc_preimage {a b : ι} (hab : a ≤ b) (s : (i : Iic b) → Subtype.forall, mem_Iic, Set.mem_prod, frestrictLe₂_apply, restrict₂, mem_Ioc] refine ⟨fun h ↦ ⟨fun i hi ↦ ?_, fun i ⟨hi1, hi2⟩ ↦ ?_⟩, fun ⟨h1, h2⟩ i hi ↦ ?_⟩ · convert! h i (hi.trans hab) - rw [dif_pos hi] + rw [dite_eq_left hi] · convert! h i hi2 - rw [dif_neg (not_le.2 hi1)] + rw [dite_eq_right (not_le.2 hi1)] · split_ifs with hi3 · exact h1 i hi3 · exact h2 i ⟨not_le.1 hi3, hi⟩ diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean b/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean index d54033daae9218..745c2a432c57b2 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/PartialTraj.lean @@ -111,7 +111,7 @@ section Basic deterministic and is equal to the restriction of the trajectory up to time `a`. -/ lemma partialTraj_le (hba : b ≤ a) : partialTraj κ a b = deterministic (frestrictLe₂ hba) (measurable_frestrictLe₂ _) := by - rw [partialTraj, dif_pos hba] + rw [partialTraj, dite_eq_left hba] @[simp] lemma partialTraj_self (a : ℕ) : partialTraj κ a a = Kernel.id := by rw [partialTraj_le le_rfl]; rfl @@ -127,12 +127,12 @@ lemma partialTraj_le_def (hab : a ≤ b) : partialTraj κ a b = b hab := by obtain rfl | hab := eq_or_lt_of_le hab · simp - · rw [partialTraj, dif_neg (not_le.2 hab)] + · rw [partialTraj, dite_eq_right (not_le.2 hab)] lemma partialTraj_succ_of_le (hab : a ≤ b) : partialTraj κ a (b + 1) = ((Kernel.id ×ₖ ((κ b).map (piSingleton b))) ∘ₖ partialTraj κ a b).map (IicProdIoc b (b + 1)) := by - rw [partialTraj, dif_neg (by lia)] + rw [partialTraj, dite_eq_right (by lia)] induction b, hab using Nat.le_induction with | base => simp | succ k hak hk => rw [Nat.leRec_succ, ← partialTraj_le_def]; lia diff --git a/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean b/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean index b080a0a7338c44..4c052c007d2e98 100644 --- a/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean +++ b/Mathlib/Probability/Kernel/IonescuTulcea/Traj.lean @@ -130,7 +130,7 @@ lemma frestrictLe_iterateInduction {a : ℕ} (x : Π i : Iic a, X i) ext i simp only [frestrictLe_apply] obtain ⟨(zero | j), hj⟩ := i <;> rw [iterateInduction] - rw [dif_pos (mem_Iic.1 hj)] + rw [dite_eq_left (mem_Iic.1 hj)] end iterateInduction @@ -432,7 +432,7 @@ theorem trajContent_tendsto_zero {A : ℕ → Set (Π n, X n)} split_ifs with h1 h2 h3 h4 h5 any_goals lia cases h2 - rw [iterateInduction, dif_neg (by lia)] + rw [iterateInduction, dite_eq_right (by lia)] -- We now want to prove that the integral of `χₙ`, which is equal to the `trajContent` -- of `Aₙ`, converges to `0`. have aux x n : @@ -750,7 +750,7 @@ theorem condExp_traj' {a b c : ℕ} (hab : a ≤ b) (hbc : b ≤ c) · congr with y apply stronglyMeasurable_condExp.dependsOn_of_piLE simp only [Set.mem_Iic, updateFinset, mem_Iic, frestrictLe_apply, dite_eq_ite] - exact fun i hi ↦ (if_pos hi).symm + exact fun i hi ↦ (ite_eq_left hi).symm any_goals fun_prop exact (mcf.comp_measurable measurable_updateFinset).aestronglyMeasurable diff --git a/Mathlib/Probability/Kernel/WithDensity.lean b/Mathlib/Probability/Kernel/WithDensity.lean index c8c3044dc08b5d..83ef9c2d24d05d 100644 --- a/Mathlib/Probability/Kernel/WithDensity.lean +++ b/Mathlib/Probability/Kernel/WithDensity.lean @@ -55,12 +55,12 @@ noncomputable def withDensity (κ : Kernel α β) [IsSFiniteKernel κ] (f : α exact hf.setLIntegral_kernel_prod_right hs⟩ : Kernel α β)) fun _ => 0 theorem withDensity_of_not_measurable (κ : Kernel α β) [IsSFiniteKernel κ] - (hf : ¬Measurable (Function.uncurry f)) : withDensity κ f = 0 := by exact dif_neg hf + (hf : ¬Measurable (Function.uncurry f)) : withDensity κ f = 0 := by exact dite_eq_right hf protected theorem withDensity_apply (κ : Kernel α β) [IsSFiniteKernel κ] (hf : Measurable (Function.uncurry f)) (a : α) : withDensity κ f a = (κ a).withDensity (f a) := by - rw [withDensity, dif_pos hf] + rw [withDensity, dite_eq_left hf] rfl protected theorem withDensity_apply' (κ : Kernel α β) [IsSFiniteKernel κ] diff --git a/Mathlib/Probability/Martingale/Convergence.lean b/Mathlib/Probability/Martingale/Convergence.lean index eecdccc9272253..1dc703bc0fd9b6 100644 --- a/Mathlib/Probability/Martingale/Convergence.lean +++ b/Mathlib/Probability/Martingale/Convergence.lean @@ -212,13 +212,13 @@ theorem Submartingale.ae_tendsto_limitProcess [IsFiniteMeasure μ] (hf : Submart classical suffices ∃ g, StronglyMeasurable[⨆ n, ℱ n] g ∧ ∀ᵐ ω ∂μ, Tendsto (fun n => f n ω) atTop (𝓝 (g ω)) by - rw [limitProcess, dif_pos this] + rw [limitProcess, dite_eq_left this] exact (Classical.choose_spec this).2 set g' : Ω → ℝ := fun ω => if h : ∃ c, Tendsto (fun n => f n ω) atTop (𝓝 c) then h.choose else 0 have hle : ⨆ n, ℱ n ≤ m0 := sSup_le fun m ⟨n, hn⟩ => hn ▸ ℱ.le _ have hg' : ∀ᵐ ω ∂μ.trim hle, Tendsto (fun n => f n ω) atTop (𝓝 (g' ω)) := by filter_upwards [hf.exists_ae_trim_tendsto_of_bdd hbdd] with ω hω - simp_rw [g', dif_pos hω] + simp_rw [g', dite_eq_left hω] exact hω.choose_spec have hg'm : AEStronglyMeasurable[⨆ n, ℱ n] g' (μ.trim hle) := (@aemeasurable_of_tendsto_metrizable_ae' _ _ (⨆ n, ℱ n) _ _ _ _ _ _ _ diff --git a/Mathlib/Probability/Moments/CovarianceBilinDual.lean b/Mathlib/Probability/Moments/CovarianceBilinDual.lean index e3ffb10125ba32..0f9054f20fafb4 100644 --- a/Mathlib/Probability/Moments/CovarianceBilinDual.lean +++ b/Mathlib/Probability/Moments/CovarianceBilinDual.lean @@ -67,12 +67,12 @@ def toLpₗ (μ : Measure E) (p : ℝ≥0∞) : @[simp] lemma toLpₗ_apply (h_Lp : MemLp id p μ) (L : StrongDual 𝕜 E) : L.toLpₗ μ p = MemLp.toLp L (h_Lp.continuousLinearMap_comp L) := by - simp [toLpₗ, dif_pos h_Lp] + simp [toLpₗ, dite_eq_left h_Lp] @[simp] lemma toLpₗ_of_not_memLp (h_Lp : ¬ MemLp id p μ) (L : StrongDual 𝕜 E) : L.toLpₗ μ p = 0 := by - simp [toLpₗ, dif_neg h_Lp] + simp [toLpₗ, dite_eq_right h_Lp] lemma norm_toLpₗ_le [OpensMeasurableSpace E] (L : StrongDual 𝕜 E) : ‖L.toLpₗ μ p‖ ≤ ‖L‖ * (eLpNorm id p μ).toReal := by diff --git a/Mathlib/Probability/ProbabilityMassFunction/Basic.lean b/Mathlib/Probability/ProbabilityMassFunction/Basic.lean index dabd43d78b8d44..d3f10e333090aa 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Basic.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Basic.lean @@ -110,10 +110,10 @@ theorem apply_eq_one_iff (p : PMF α) (a : α) : p a = 1 ↔ p.support = {a} := 1 = 1 + 0 := (add_zero 1).symm _ < p a + ∑' b, ite (b = a) 0 (p b) := (ENNReal.add_lt_add_of_le_of_lt ENNReal.one_ne_top (le_of_eq h.symm) this) - _ = ite (a = a) (p a) 0 + ∑' b, ite (b = a) 0 (p b) := by rw [eq_self_iff_true, if_true] + _ = ite (a = a) (p a) 0 + ∑' b, ite (b = a) 0 (p b) := by rw [eq_self_iff_true, ite_true] _ = (∑' b, ite (b = a) (p b) 0) + ∑' b, ite (b = a) 0 (p b) := by congr - exact symm (tsum_eq_single a fun b hb => if_neg hb) + exact symm (tsum_eq_single a fun b hb => ite_eq_right hb) _ = ∑' b, (ite (b = a) (p b) 0 + ite (b = a) 0 (p b)) := ENNReal.tsum_add.symm _ = ∑' b, p b := tsum_congr fun b => by split_ifs <;> simp only [zero_add, add_zero] diff --git a/Mathlib/Probability/ProbabilityMassFunction/Binomial.lean b/Mathlib/Probability/ProbabilityMassFunction/Binomial.lean index a8d84fb907b88c..f5eb6e98e572e5 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Binomial.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Binomial.lean @@ -37,7 +37,7 @@ def binomial (p : ℝ≥0) (h : p ≤ 1) (n : ℕ) : PMF (Fin (n + 1)) := apply Finset.sum_congr rfl intro i hi rw [Finset.mem_range] at hi - rw [dif_pos hi] + rw [dite_eq_left hi] · rw [add_tsub_cancel_of_le (mod_cast h), one_pow]) @[deprecated ProbabilityTheory.binomial_real_singleton (since := "2026-04-07")] diff --git a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean index 75f5e5ef6a3576..07c4db05ab05a7 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean @@ -54,10 +54,10 @@ theorem support_pure : (pure a).support = {a} := theorem mem_support_pure_iff : a' ∈ (pure a).support ↔ a' = a := by simp theorem pure_apply_self : pure a a = 1 := - if_pos rfl + ite_eq_left rfl theorem pure_apply_of_ne (h : a' ≠ a) : pure a a' = 0 := - if_neg h + ite_eq_right h instance [Inhabited α] : Inhabited (PMF α) := ⟨pure default⟩ @@ -228,8 +228,8 @@ theorem bindOnSupport_eq_bind (p : PMF α) (f : α → PMF β) : theorem bindOnSupport_eq_zero_iff (b : β) : p.bindOnSupport f b = 0 ↔ ∀ (a) (ha : p a ≠ 0), f a ha b = 0 := by simp only [bindOnSupport_apply, ENNReal.tsum_eq_zero, mul_eq_zero, or_iff_not_imp_left] - exact ⟨fun h a ha => Trans.trans (dif_neg ha).symm (h a ha), - fun h a ha => Trans.trans (dif_neg ha) (h a ha)⟩ + exact ⟨fun h a ha => Trans.trans (dite_eq_right ha).symm (h a ha), + fun h a ha => Trans.trans (dite_eq_right ha) (h a ha)⟩ @[simp] theorem pure_bindOnSupport (a : α) (f : ∀ (a' : α) (_ : a' ∈ (pure a).support), PMF β) : diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index 7230b6601715e1..fbe5932b46e716 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -145,16 +145,16 @@ noncomputable instance : InfSet (Filtration ι m) := { seq := fun i => if Set.Nonempty s then sInf ((fun f : Filtration ι m => f i) '' s) else m mono' := fun i j hij => by by_cases h_nonempty : Set.Nonempty s - swap; · simp only [h_nonempty, if_false, le_refl] - simp only [h_nonempty, if_true, le_sInf_iff, Set.mem_image, forall_exists_index, and_imp, + swap; · simp only [h_nonempty, ite_false, le_refl] + simp only [h_nonempty, ite_true, le_sInf_iff, Set.mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] refine fun f hf_mem => le_trans ?_ (f.mono hij) have hfi_mem : f i ∈ (fun g : Filtration ι m => g i) '' s := ⟨f, hf_mem, rfl⟩ exact sInf_le hfi_mem le' := fun i => by by_cases h_nonempty : Set.Nonempty s - swap; · simp only [h_nonempty, if_false, le_refl] - simp only [h_nonempty, if_true] + swap; · simp only [h_nonempty, ite_false, le_refl] + simp only [h_nonempty, ite_true] obtain ⟨f, hf_mem⟩ := h_nonempty exact le_trans (sInf_le ⟨f, hf_mem, rfl⟩) (f.le i) }⟩ @@ -295,7 +295,7 @@ lemma rightCont_apply [PartialOrder ι] [TopologicalSpace ι] [OrderTopology ι] lemma rightCont_eq_of_nhdsGT_eq_bot [PartialOrder ι] [TopologicalSpace ι] [OrderTopology ι] (𝓕 : Filtration ι m) {i : ι} (hi : 𝓝[>] i = ⊥) : 𝓕₊ i = 𝓕 i := by - rw [rightCont_apply, hi, neBot_iff, ne_self_iff_false, if_false] + rw [rightCont_apply, hi, neBot_iff, ne_self_iff_false, ite_false] /-- If the index type is a `SuccOrder`, then `𝓕₊ = 𝓕`. -/ @[simp] lemma rightCont_eq_self [LinearOrder ι] [SuccOrder ι] (𝓕 : Filtration ι m) : @@ -323,7 +323,7 @@ topology, see `rightCont_eq`. -/ lemma rightCont_eq_of_neBot_nhdsGT [PartialOrder ι] [TopologicalSpace ι] [OrderTopology ι] (𝓕 : Filtration ι m) (i : ι) [(𝓝[>] i).NeBot] : 𝓕₊ i = ⨅ j > i, 𝓕 j := by - rw [rightCont_apply, if_pos ‹(𝓝[>] i).NeBot›] + rw [rightCont_apply, ite_eq_left ‹(𝓝[>] i).NeBot›] lemma rightCont_eq_of_not_isMax [LinearOrder ι] [DenselyOrdered ι] (𝓕 : Filtration ι m) {i : ι} (hi : ¬IsMax i) : @@ -347,7 +347,7 @@ lemma le_rightCont (𝓕 : Filtration ι m) : 𝓕 ≤ 𝓕₊ := by by_cases hne : (𝓝[>] i).NeBot · rw [rightCont_eq_of_neBot_nhdsGT] exact le_iInf₂ fun _ he => 𝓕.mono he.le - · rw [rightCont_apply, if_neg hne] + · rw [rightCont_apply, ite_eq_right hne] @[simp] lemma rightCont_self (𝓕 : Filtration ι m) : 𝓕₊₊ = 𝓕₊ := by let := Preorder.topology ι; have : OrderTopology ι := ⟨rfl⟩ @@ -367,7 +367,7 @@ lemma le_rightCont (𝓕 : Filtration ι m) : 𝓕 ≤ 𝓕₊ := by · simpa [rightCont_apply, hnv] using 𝓕.mono hv.2.le exact hle₁.trans hle₂ simpa [rightCont_eq_of_neBot_nhdsGT] using hineq - · rw [rightCont_apply, if_neg hne] + · rw [rightCont_apply, ite_eq_right hne] /-- A filtration `𝓕` is right continuous if it is equal to its right continuation `𝓕₊`. -/ class IsRightContinuous (𝓕 : Filtration ι m) where diff --git a/Mathlib/Probability/Process/HittingTime.lean b/Mathlib/Probability/Process/HittingTime.lean index 58507fb6b1f50f..b941ce3b41e804 100644 --- a/Mathlib/Probability/Process/HittingTime.lean +++ b/Mathlib/Probability/Process/HittingTime.lean @@ -97,7 +97,7 @@ lemma hittingAfter_univ {ι : Type*} [ConditionallyCompleteLattice ι] {u : ι ext ω classical simp only [hittingAfter_def, Set.mem_univ, and_true] - rw [if_pos ⟨n, le_rfl⟩] + rw [ite_eq_left ⟨n, le_rfl⟩] exact_mod_cast csInf_Ici end Basic @@ -123,13 +123,13 @@ theorem notMem_of_lt_hittingBtwn {m k : ι} (hk₁ : k < hittingBtwn u s n m ω) intro h have hexists : ∃ j ∈ Set.Icc n m, u j ω ∈ s := ⟨k, ⟨hk₂, le_trans hk₁.le <| hittingBtwn_le _⟩, h⟩ refine not_le.2 hk₁ ?_ - simp_rw [hittingBtwn, if_pos hexists] + simp_rw [hittingBtwn, ite_eq_left hexists] exact csInf_le bddBelow_Icc.inter_of_left ⟨⟨hk₂, le_trans hk₁.le <| hittingBtwn_le _⟩, h⟩ theorem notMem_of_lt_hittingAfter {k : ι} (hk₁ : k < hittingAfter u s n ω) (hk₂ : n ≤ k) : u k ω ∉ s := by refine fun h ↦ not_le.2 hk₁ ?_ - rw [hittingAfter, if_pos ⟨k, hk₂, h⟩] + rw [hittingAfter, ite_eq_left ⟨k, hk₂, h⟩] exact_mod_cast csInf_le bddBelow_Ici.inter_of_left ⟨hk₂, h⟩ theorem hittingBtwn_eq_end_iff {m : ι} : hittingBtwn u s n m ω = m ↔ @@ -178,7 +178,7 @@ theorem hittingBtwn_mem_Icc {m : ι} (hnm : n ≤ m) (ω : Ω) : hittingBtwn u s theorem hittingBtwn_mem_set [WellFoundedLT ι] {m : ι} (h_exists : ∃ j ∈ Set.Icc n m, u j ω ∈ s) : u (hittingBtwn u s n m ω) ω ∈ s := by - simp_rw [hittingBtwn, if_pos h_exists] + simp_rw [hittingBtwn, ite_eq_left h_exists] have h_nonempty : (Set.Icc n m ∩ {i : ι | u i ω ∈ s}).Nonempty := by obtain ⟨k, hk₁, hk₂⟩ := h_exists exact ⟨k, Set.mem_inter hk₁ hk₂⟩ @@ -188,7 +188,7 @@ theorem hittingBtwn_mem_set [WellFoundedLT ι] {m : ι} (h_exists : ∃ j ∈ Se lemma hittingAfter_mem_set [WellFoundedLT ι] (h_exists : ∃ j, n ≤ j ∧ u j ω ∈ s) : u (hittingAfter u s n ω).untopA ω ∈ s := by - rw [hittingAfter, if_pos h_exists] + rw [hittingAfter, ite_eq_left h_exists] have h_nonempty : {i : ι | n ≤ i ∧ u i ω ∈ s}.Nonempty := by obtain ⟨k, hk₁, hk₂⟩ := h_exists exact ⟨k, Set.mem_inter hk₁ hk₂⟩ @@ -199,7 +199,7 @@ theorem hittingBtwn_mem_set_of_hittingBtwn_lt [WellFoundedLT ι] {m : ι} u (hittingBtwn u s n m ω) ω ∈ s := by by_cases h : ∃ j ∈ Set.Icc n m, u j ω ∈ s · exact hittingBtwn_mem_set h - · simp_rw [hittingBtwn, if_neg h] at hl + · simp_rw [hittingBtwn, ite_eq_right h] at hl exact False.elim (hl.ne rfl) lemma hittingAfter_mem_set_of_ne_top [WellFoundedLT ι] (hl : hittingAfter u s n ω ≠ ⊤) : @@ -211,13 +211,13 @@ lemma hittingAfter_mem_set_of_ne_top [WellFoundedLT ι] (hl : hittingAfter u s n theorem hittingBtwn_le_of_mem {m : ι} (hin : n ≤ i) (him : i ≤ m) (his : u i ω ∈ s) : hittingBtwn u s n m ω ≤ i := by have h_exists : ∃ k ∈ Set.Icc n m, u k ω ∈ s := ⟨i, ⟨hin, him⟩, his⟩ - simp_rw [hittingBtwn, if_pos h_exists] + simp_rw [hittingBtwn, ite_eq_left h_exists] exact csInf_le (BddBelow.inter_of_left bddBelow_Icc) (Set.mem_inter ⟨hin, him⟩ his) lemma hittingAfter_le_of_mem (hin : n ≤ i) (his : u i ω ∈ s) : hittingAfter u s n ω ≤ i := by have h_exists : ∃ k, n ≤ k ∧ u k ω ∈ s := ⟨i, hin, his⟩ - rw [hittingAfter, if_pos h_exists] + rw [hittingAfter, ite_eq_left h_exists] exact_mod_cast csInf_le (BddBelow.inter_of_left bddBelow_Ici) (Set.mem_inter hin his) theorem hittingBtwn_le_iff_of_exists [WellFoundedLT ι] {m : ι} @@ -251,7 +251,7 @@ theorem hittingBtwn_le_iff_of_lt [WellFoundedLT ι] {m : ι} (i : ι) (hi : i < hittingBtwn u s n m ω ≤ i ↔ ∃ j ∈ Set.Icc n i, u j ω ∈ s := by by_cases h_exists : ∃ j ∈ Set.Icc n m, u j ω ∈ s · rw [hittingBtwn_le_iff_of_exists h_exists] - · simp_rw [hittingBtwn, if_neg h_exists] + · simp_rw [hittingBtwn, ite_eq_right h_exists] push Not at h_exists simp only [not_le.mpr hi, Set.mem_Icc, false_iff, not_exists, not_and, and_imp] exact fun k hkn hki => h_exists k ⟨hkn, hki.trans hi.le⟩ @@ -261,11 +261,11 @@ theorem hittingBtwn_lt_iff {m : ι} (i : ι) (hi : i ≤ m) : constructor <;> intro h' · have h : ∃ j ∈ Set.Icc n m, u j ω ∈ s := by by_contra h - simp_rw [hittingBtwn, if_neg h, ← not_le] at h' + simp_rw [hittingBtwn, ite_eq_right h, ← not_le] at h' exact h' hi have hni : n < i := (le_hittingBtwn_of_exists h).trans_lt h' have h_le := le_hittingBtwn (u := u) (s := s) (hni.le.trans hi) ω - rw [hittingBtwn, if_pos h, csInf_lt_iff] at h' + rw [hittingBtwn, ite_eq_left h, csInf_lt_iff] at h' rotate_left · exact ⟨n, by simp [mem_lowerBounds]; grind⟩ · exact h @@ -285,7 +285,7 @@ lemma hittingAfter_lt_iff : push Not at h_top exact h_top have h_le := le_hittingAfter (u := u) (s := s) (n := n) ω - rw [hittingAfter, if_pos h_exists] at h' + rw [hittingAfter, ite_eq_left h_exists] at h' norm_cast at h' rw [csInf_lt_iff] at h' rotate_left @@ -300,9 +300,9 @@ lemma hittingAfter_lt_iff : theorem hittingBtwn_eq_hittingBtwn_of_exists {m₁ m₂ : ι} (h : m₁ ≤ m₂) (h' : ∃ j ∈ Set.Icc n m₁, u j ω ∈ s) : hittingBtwn u s n m₁ ω = hittingBtwn u s n m₂ ω := by - simp only [hittingBtwn, if_pos h'] + simp only [hittingBtwn, ite_eq_left h'] obtain ⟨j, hj₁, hj₂⟩ := h' - rw [if_pos] + rw [ite_eq_left] · refine le_antisymm ?_ (by gcongr; exacts [bddBelow_Icc.inter_of_left, ⟨j, hj₁, hj₂⟩]) refine le_csInf ⟨j, Set.Icc_subset_Icc_right h hj₁, hj₂⟩ fun i hi => ?_ by_cases hi' : i ≤ m₁ @@ -349,7 +349,7 @@ theorem hittingBtwn_mono_right (u : ι → Ω → β) (s : Set β) (n : ι) : intro m₁ m₂ hm by_cases h : ∃ j ∈ Set.Icc n m₁, u j ω ∈ s · exact (hittingBtwn_eq_hittingBtwn_of_exists hm h).le - · simp_rw [hittingBtwn, if_neg h] + · simp_rw [hittingBtwn, ite_eq_right h] split_ifs with h' · obtain ⟨j, hj₁, hj₂⟩ := h' refine le_csInf ⟨j, hj₁, hj₂⟩ ?_ @@ -428,7 +428,7 @@ alias hittingAfter_isStoppingTime := Adapted.isStoppingTime_hittingAfter theorem stoppedValue_hittingBtwn_mem [ConditionallyCompleteLinearOrder ι] [WellFoundedLT ι] {u : ι → Ω → β} {s : Set β} {n m : ι} {ω : Ω} (h : ∃ j ∈ Set.Icc n m, u j ω ∈ s) : stoppedValue u (fun ω ↦ (hittingBtwn u s n m ω : ι)) ω ∈ s := by - simp only [stoppedValue, hittingBtwn, if_pos h] + simp only [stoppedValue, hittingBtwn, ite_eq_left h] obtain ⟨j, hj₁, hj₂⟩ := h have : sInf (Set.Icc n m ∩ {i | u i ω ∈ s}) ∈ Set.Icc n m ∩ {i | u i ω ∈ s} := csInf_mem (Set.nonempty_of_mem ⟨hj₁, hj₂⟩) diff --git a/Mathlib/Probability/ProductMeasure.lean b/Mathlib/Probability/ProductMeasure.lean index 5f4f6d45baa1e5..e8086d184ecbf7 100644 --- a/Mathlib/Probability/ProductMeasure.lean +++ b/Mathlib/Probability/ProductMeasure.lean @@ -69,8 +69,9 @@ lemma isProjectiveMeasureFamily_pi : simp_rw [Measure.map_apply (measurable_restrict₂ hJI) (.univ_pi ms), restrict₂_preimage hJI, Measure.pi_pi, prod_eq_prod_extend] refine (prod_subset_one_on_sdiff hJI (fun x hx ↦ ?_) (fun x hx ↦ ?_)).symm - · rw [Function.extend_val_apply (mem_sdiff.1 hx).1, dif_neg (mem_sdiff.1 hx).2, measure_univ] - · rw [Function.extend_val_apply hx, Function.extend_val_apply (hJI hx), dif_pos hx] + · rw [Function.extend_val_apply (mem_sdiff.1 hx).1, dite_eq_right (mem_sdiff.1 hx).2, + measure_univ] + · rw [Function.extend_val_apply hx, Function.extend_val_apply (hJI hx), dite_eq_left hx] /-- Consider a family of probability measures. You can take their products for any finite subfamily. This gives an additive content on the measurable cylinders. -/ @@ -296,7 +297,7 @@ theorem piContent_tendsto_zero {A : ℕ → Set (Π i, X i)} (A_mem : ∀ n, A n ext x i simp only [Function.comp_apply, Finset.restrict, Equiv.piCongrLeft_apply, Equiv.coe_fn_symm_mk, f, aux, g, t] - rw [dif_pos (Set.mem_iUnion.2 ⟨n, i.2⟩)] + rw [dite_eq_left (Set.mem_iUnion.2 ⟨n, i.2⟩)] -- `Bₙ` is the same as `Aₙ` but in the product indexed by `u` let B n := f ⁻¹' (A n) -- `Tₙ` is the same as `Sₙ` but in the product indexed by `u` @@ -367,7 +368,7 @@ theorem isProjectiveLimit_infinitePi : IsProjectiveLimit (infinitePi μ) (fun I : Finset ι ↦ (Measure.pi (fun i : I ↦ μ i))) := by intro I ext s hs - rw [map_apply (measurable_restrict I) hs, infinitePi, dif_pos hμ, AddContent.measure_eq, + rw [map_apply (measurable_restrict I) hs, infinitePi, dite_eq_left hμ, AddContent.measure_eq, ← cylinder, piContent_cylinder μ hs] · exact generateFrom_measurableCylinders.symm · exact cylinder_mem_measurableCylinders _ _ hs @@ -394,7 +395,7 @@ theorem eq_infinitePi {ν : Measure (Π i, X i)} classical rw [Measure.map_apply, restrict_preimage_univ, hν, ← prod_attach, univ_eq_attach] · congr with i - rw [dif_pos i.2] + rw [dite_eq_left i.2] any_goals fun_prop · rintro i split_ifs with hi diff --git a/Mathlib/RepresentationTheory/FiniteIndex.lean b/Mathlib/RepresentationTheory/FiniteIndex.lean index e97c51615fae59..628d4a1471773e 100644 --- a/Mathlib/RepresentationTheory/FiniteIndex.lean +++ b/Mathlib/RepresentationTheory/FiniteIndex.lean @@ -50,20 +50,20 @@ variable {A} @[simp] lemma indToCoindAux_self (g : G) (a : A) : indToCoindAux A g a g = a := by - rw [indToCoindAux, LinearMap.pi_apply, dif_pos] + rw [indToCoindAux, LinearMap.pi_apply, dite_eq_left] · simp [← S.1.one_def] · rfl lemma indToCoindAux_of_not_rel (g g₁ : G) (a : A) (h : ¬(QuotientGroup.rightRel S).r g₁ g) : indToCoindAux A g a g₁ = 0 := by - simp [indToCoindAux, dif_neg h] + simp [indToCoindAux, dite_eq_right h] @[simp] lemma indToCoindAux_mul_snd (g g₁ : G) (a : A) (s : S) : indToCoindAux A g a (s * g₁) = A.ρ s (indToCoindAux A g a g₁) := by rcases em ((QuotientGroup.rightRel S).r g₁ g) with ⟨s₁, rfl⟩ | h · simp only [indToCoindAux, LinearMap.pi_apply] - rw [dif_pos ⟨s * s₁, mul_assoc ..⟩, dif_pos ⟨s₁, rfl⟩] + rw [dite_eq_left ⟨s * s₁, mul_assoc ..⟩, dite_eq_left ⟨s₁, rfl⟩] simp [S.1.smul_def, mul_assoc, ← S.1.mul_def] · rw [indToCoindAux_of_not_rel _ _ _ h, indToCoindAux_of_not_rel, map_zero] exact mt (fun ⟨s₁, hs₁⟩ => ⟨s⁻¹ * s₁, by simp_all [S.1.smul_def, mul_assoc]⟩) h @@ -73,8 +73,8 @@ lemma indToCoindAux_mul_fst (g₁ g₂ : G) (a : A) (s : S) : indToCoindAux A (s * g₁) (A.ρ s a) g₂ = indToCoindAux A g₁ a g₂ := by rcases em ((QuotientGroup.rightRel S).r g₂ g₁) with ⟨s₁, rfl⟩ | h · simp only [indToCoindAux, LinearMap.pi_apply] - rw [dif_pos ⟨s₁ * s⁻¹, by simp [S.1.smul_def, smul_eq_mul, mul_assoc]⟩, dif_pos ⟨s₁, rfl⟩, - ← Module.End.mul_apply, ← map_mul] + rw [dite_eq_left ⟨s₁ * s⁻¹, by simp [S.1.smul_def, smul_eq_mul, mul_assoc]⟩, + dite_eq_left ⟨s₁, rfl⟩, ← Module.End.mul_apply, ← map_mul] congr simp [Subtype.ext_iff, S.1.smul_def, mul_assoc] · rw [indToCoindAux_of_not_rel (h := h), indToCoindAux_of_not_rel] diff --git a/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean b/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean index 7cb18640e27cf4..617ff0daa92e02 100644 --- a/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean +++ b/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean @@ -142,8 +142,8 @@ noncomputable def chainComplexFunctor : Rep k G ⥤ ChainComplex (Rep k G) ℕ w comm' := by rintro i j ⟨rfl⟩ by_cases hj : Even (j + 1) - · simp [if_pos hj, norm_comm] - · simp [if_neg hj, applyAsHom_comm] } + · simp [ite_eq_left hj, norm_comm] + · simp [ite_eq_right hj, applyAsHom_comm] } map_id _ := rfl map_comp _ _ := rfl @@ -226,12 +226,13 @@ lemma resolution_quasiIso (g : G) (hg : ∀ x, x ∈ Subgroup.zpowers g) : apply (forget₂ _ (ModuleCat k)).reflects_exact_of_faithful rw [ShortComplex.moduleCat_exact_iff_range_eq_ker] by_cases hm : Odd (m + 1) - · simpa [if_pos (Nat.even_add_one.2 (Nat.not_even_iff_odd.2 hm)), - if_neg (Nat.not_even_iff_odd.2 hm)] + · simpa [ite_eq_left (Nat.even_add_one.2 (Nat.not_even_iff_odd.2 hm)), + ite_eq_right (Nat.not_even_iff_odd.2 hm)] using! leftRegular.range_norm_eq_ker_applyAsHom_sub k g hg - · simpa [ShortComplex.moduleCat_exact_iff_range_eq_ker, if_pos (Nat.not_odd_iff_even.1 hm), - if_neg (Nat.not_even_iff_odd.2 <| Nat.odd_add_one.2 hm)] - using! leftRegular.range_applyAsHom_sub_eq_ker_norm k g hg + · simpa [ShortComplex.moduleCat_exact_iff_range_eq_ker, + ite_eq_left (Nat.not_odd_iff_even.1 hm), + ite_eq_right (Nat.not_even_iff_odd.2 <| Nat.odd_add_one.2 hm)] + using! leftRegular.range_applyAsHom_sub_eq_ker_norm k g hg /-- Given a finite cyclic group `G` generated by `g : G`, this is the projective resolution of `k` as a trivial `k`-linear `G`-representation given by periodic complex diff --git a/Mathlib/RepresentationTheory/Homological/Resolution.lean b/Mathlib/RepresentationTheory/Homological/Resolution.lean index 2ee094a14db21e..137e240b6320e6 100644 --- a/Mathlib/RepresentationTheory/Homological/Resolution.lean +++ b/Mathlib/RepresentationTheory/Homological/Resolution.lean @@ -276,7 +276,7 @@ theorem forget₂ToModuleCatHomotopyEquiv_f_0_eq : AlgebraicTopology.AlternatingFaceMapComplex.ε_app_f_zero, compForgetAugmentedIso, eqToIso.inv, HomologicalComplex.eqToHom_f, compForgetAugmented, compForgetAugmented.toModule, ε, SimplicialObject.augment, Unique.eq_default (terminal.from _), MonoidAlgebra.coeff_single, - Finsupp.single_apply, if_pos (Subsingleton.elim _ _)] + Finsupp.single_apply, ite_eq_left (Subsingleton.elim _ _)] set_option backward.isDefEq.respectTransparency false in theorem d_comp_ε : (standardComplex k G).d 1 0 ≫ ε k G = 0 := by diff --git a/Mathlib/RingTheory/Adjoin/PowerBasis.lean b/Mathlib/RingTheory/Adjoin/PowerBasis.lean index 1f34fb03ef14ee..315df15f48a39e 100644 --- a/Mathlib/RingTheory/Adjoin/PowerBasis.lean +++ b/Mathlib/RingTheory/Adjoin/PowerBasis.lean @@ -120,7 +120,7 @@ theorem repr_gen_pow_isIntegral (hB : IsIntegral R B.gen) Algebra.smul_def, map_smul] simp only [algebraMap_smul, Finsupp.coe_smul, Pi.smul_apply, B.basis.repr_self_apply] by_cases hij : (⟨j, hj⟩ : Fin _) = i - · simp only [hij, if_true] + · simp only [hij, ite_true] rw [Algebra.smul_def, mul_one] exact isIntegral_algebraMap · simp [hij, isIntegral_zero] diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index b863ef2b662ff7..9e6823333bc05b 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -608,7 +608,8 @@ def powerBasisAux' (hg : g.Monic) : Basis (Fin g.natDegree) R (AdjoinRoot g) := nontriviality R simp only [modByMonicHom_mk] rw [(modByMonic_eq_self_iff hg).mpr, finsetSum_coeff] - · simp_rw [coeff_monomial, Fin.val_eq_val, Finset.sum_ite_eq', if_pos (Finset.mem_univ _)] + · simp_rw [coeff_monomial, Fin.val_eq_val, Finset.sum_ite_eq', + ite_eq_left (Finset.mem_univ _)] · simp_rw [← C_mul_X_pow_eq_monomial] exact (degree_eq_natDegree <| hg.ne_zero).symm ▸ degree_sum_fin_lt _ } diff --git a/Mathlib/RingTheory/Algebraic/Basic.lean b/Mathlib/RingTheory/Algebraic/Basic.lean index 4125d527302c78..470120a2278428 100644 --- a/Mathlib/RingTheory/Algebraic/Basic.lean +++ b/Mathlib/RingTheory/Algebraic/Basic.lean @@ -691,7 +691,7 @@ theorem Subalgebra.inv_mem_of_algebraic {x : A} (hx : IsAlgebraic K (x : L)) : contradiction · intro p a hp ha _ih _ne_zero aeval_eq refine A.inv_mem_of_root_of_coeff_zero_ne_zero aeval_eq ?_ - rwa [coeff_add, hp, zero_add, coeff_C, if_pos rfl] + rwa [coeff_add, hp, zero_add, coeff_C, ite_eq_left rfl] · intro p hp ih _ne_zero aeval_eq rw [map_mul, aeval_X, mul_eq_zero] at aeval_eq rcases aeval_eq with aeval_eq | x_eq diff --git a/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean b/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean index 5b185e6f6f3b53..509c4ee5ec9454 100644 --- a/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean +++ b/Mathlib/RingTheory/Coalgebra/CoassocSimps.lean @@ -82,7 +82,7 @@ attribute [coassoc_simps] LinearMap.comp_id LinearMap.id_comp TensorProduct.map_ LinearEquiv.symm_comp_assoc TensorProduct.rightComm_def TensorProduct.leftComm_def TensorProduct.comm_symm TensorProduct.comm_comp_comm TensorProduct.comm_comp_comm_assoc -attribute [coassoc_simps← ] TensorProduct.map_comp TensorProduct.map_map_comp_assoc_eq +attribute [coassoc_simps ←] TensorProduct.map_comp TensorProduct.map_map_comp_assoc_eq TensorProduct.map_map_comp_assoc_symm_eq @[coassoc_simps] @@ -91,13 +91,13 @@ lemma TensorProduct.map_comp_assoc map g g' ∘ₗ map f f' ∘ₗ φ = map (g ∘ₗ f) (g' ∘ₗ f') ∘ₛₗ φ := by rw [← LinearMap.comp_assoc, TensorProduct.map_comp] -@[coassoc_simps← ] +@[coassoc_simps ←] lemma TensorProduct.map_map_comp_assoc_eq_assoc (f₁ : M₁ →ₗ[R] N₁) (f₂ : M₂ →ₗ[R] N₂) (f₃ : M₃ →ₗ[R] N₃) (f : M →ₗ[R] M₁ ⊗[R] M₂ ⊗[R] M₃) : f₁ ⊗ₘ (f₂ ⊗ₘ f₃) ∘ₗ α ∘ₗ f = α ∘ₗ ((f₁ ⊗ₘ f₂) ⊗ₘ f₃) ∘ₗ f := by rw [← LinearMap.comp_assoc, ← LinearMap.comp_assoc, TensorProduct.map_map_comp_assoc_eq] -@[coassoc_simps← ] +@[coassoc_simps ←] lemma TensorProduct.map_map_comp_assoc_symm_eq_assoc (f₁ : M₁ →ₗ[R] N₁) (f₂ : M₂ →ₗ[R] N₂) (f₃ : M₃ →ₗ[R] N₃) (f : M →ₗ[R] M₁ ⊗[R] (M₂ ⊗[R] M₃)) : (f₁ ⊗ₘ f₂) ⊗ₘ f₃ ∘ₗ α⁻¹ ∘ₗ f = α⁻¹ ∘ₗ (f₁ ⊗ₘ (f₂ ⊗ₘ f₃)) ∘ₗ f := by diff --git a/Mathlib/RingTheory/Coprime/Ideal.lean b/Mathlib/RingTheory/Coprime/Ideal.lean index b6e84354e62857..65538281c90cf2 100644 --- a/Mathlib/RingTheory/Coprime/Ideal.lean +++ b/Mathlib/RingTheory/Coprime/Ideal.lean @@ -40,7 +40,7 @@ theorem iSup_iInf_eq_top_iff_pairwise {t : Finset ι} (h : t.Nonempty) (I : ι · simp only [Finset.sum_singleton, Finset.coe_singleton, Set.pairwise_singleton, iff_true] refine fun a => ⟨fun i => if h : i = a then ⟨1, ?_⟩ else 0, ?_⟩ · simp [h] - · simp only [dif_pos, Submodule.coe_mk] + · simp only [dite_eq_left, Submodule.coe_mk] intro a t hat h ih have : Std.Symm (I · ⊔ I · = ⊤) := { symm i j := sup_comm .. |>.trans } rw [Finset.coe_cons, Set.pairwise_insert_of_symm] @@ -65,7 +65,8 @@ theorem iSup_iInf_eq_top_iff_pairwise {t : Finset ι} (h : t.Nonempty) (I : ι intro j hj ij exact this _ (Finset.subset_cons _ hj) ij case a3 => - rw [← @if_pos _ _ h.choose_spec R (μ a) 0, ← Finset.sum_pi_single', ← Finset.sum_add_distrib] + rw [← @ite_eq_left _ _ h.choose_spec R (μ a) 0, ← Finset.sum_pi_single', + ← Finset.sum_add_distrib] at hμ convert! hμ rename_i i _ @@ -103,13 +104,13 @@ theorem iSup_iInf_eq_top_iff_pairwise {t : Finset ι} (h : t.Nonempty) (I : ι · exact mul_mem_right _ _ hu · exact mul_mem_left _ _ (this _ hj ij) · dsimp only - rw [Finset.sum_cons, dif_pos rfl, add_comm] + rw [Finset.sum_cons, dite_eq_left rfl, add_comm] rw [← mul_one u] at huv rw [← huv, ← hμ, Finset.mul_sum] congr 1 apply Finset.sum_congr rfl intro j hj - rw [dif_neg] + rw [dite_eq_right] rintro rfl exact hat hj diff --git a/Mathlib/RingTheory/Coprime/Lemmas.lean b/Mathlib/RingTheory/Coprime/Lemmas.lean index 6f47cd085daf75..7877e4d9627e08 100644 --- a/Mathlib/RingTheory/Coprime/Lemmas.lean +++ b/Mathlib/RingTheory/Coprime/Lemmas.lean @@ -139,7 +139,7 @@ theorem exists_sum_eq_one_iff_pairwise_coprime [DecidableEq I] (h : t.Nonempty) rw [sum_cons, cons_eq_insert, sdiff_singleton_eq_erase, erase_insert hat] at hμ refine ⟨ih.mp ⟨Pi.single h.choose (μ a * s h.choose) + μ * fun _ ↦ s a, ?_⟩, fun b hb ↦ ?_⟩ · rw [prod_eq_mul_prod_sdiff_singleton_of_mem h.choose_spec, ← mul_assoc, ← - @if_pos _ _ h.choose_spec R (_ * _) 0, ← sum_pi_single', ← sum_add_distrib] at hμ + @ite_eq_left _ _ h.choose_spec R (_ * _) 0, ← sum_pi_single', ← sum_add_distrib] at hμ rw [← hμ, sum_congr rfl] intro x hx convert! add_mul (R := R) _ _ _ using 2 @@ -169,7 +169,7 @@ theorem exists_sum_eq_one_iff_pairwise_coprime [DecidableEq I] (h : t.Nonempty) simp only [↓reduceIte, ite_mul] rw [← huv, ← hμ', sum_congr rfl] intro x hx - rw [mul_assoc, if_neg fun ha : x = a ↦ hat (ha.casesOn hx)] + rw [mul_assoc, ite_eq_right fun ha : x = a ↦ hat (ha.casesOn hx)] rw [mul_assoc] congr rw [prod_eq_prod_sdiff_singleton_mul (mem x hx) _] diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index d64cab22b35496..49f01d2704827d 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -85,16 +85,16 @@ def intValuationDef (r : R) : ℤᵐ⁰ := exp (-(Associates.mk v.asIdeal).count (Associates.mk (Ideal.span {r} : Ideal R)).factors : ℤ) theorem intValuationDef_if_pos {r : R} (hr : r = 0) : v.intValuationDef r = 0 := - if_pos hr + ite_eq_left hr @[simp] theorem intValuationDef_zero : v.intValuationDef 0 = 0 := - if_pos rfl + ite_eq_left rfl theorem intValuationDef_if_neg {r : R} (hr : r ≠ 0) : v.intValuationDef r = exp (-(Associates.mk v.asIdeal).count (Associates.mk (Ideal.span {r} : Ideal R)).factors : ℤ) := - if_neg hr + ite_eq_right hr /-- The `v`-adic valuation of `0 : R` equals 0. -/ theorem intValuation.map_zero' : v.intValuationDef 0 = 0 := @@ -111,10 +111,10 @@ theorem intValuation.map_mul' (x y : R) : v.intValuationDef (x * y) = v.intValuationDef x * v.intValuationDef y := by simp only [intValuationDef] by_cases hx : x = 0 - · rw [hx, zero_mul, if_pos rfl, zero_mul] + · rw [hx, zero_mul, ite_eq_left rfl, zero_mul] · by_cases hy : y = 0 - · rw [hy, mul_zero, if_pos rfl, mul_zero] - · rw [if_neg hx, if_neg hy, if_neg (mul_ne_zero hx hy), ← exp_add, + · rw [hy, mul_zero, ite_eq_left rfl, mul_zero] + · rw [ite_eq_right hx, ite_eq_right hy, ite_eq_right (mul_ne_zero hx hy), ← exp_add, ← Ideal.span_singleton_mul_span_singleton, ← Associates.mk_mul_mk, ← neg_add, Associates.count_mul (Associates.mk_ne_zero'.mpr hx) (Associates.mk_ne_zero'.mpr hy) v.associates_irreducible, @@ -138,7 +138,7 @@ theorem intValuation.map_add_le_max' (x y : R) : · rw [hy, add_zero] order · by_cases hxy : x + y = 0 - · rw [intValuationDef, if_pos hxy]; exact zero_le + · rw [intValuationDef, ite_eq_left hxy]; exact zero_le · rw [v.intValuationDef_if_neg hxy, v.intValuationDef_if_neg hx, v.intValuationDef_if_neg hy, le_max_iff] simp only [exp_le_exp, neg_le_neg_iff, Nat.cast_le, ← min_le_iff] diff --git a/Mathlib/RingTheory/DedekindDomain/Different.lean b/Mathlib/RingTheory/DedekindDomain/Different.lean index 058f424ca2cb47..26cd02621902ef 100644 --- a/Mathlib/RingTheory/DedekindDomain/Different.lean +++ b/Mathlib/RingTheory/DedekindDomain/Different.lean @@ -261,7 +261,7 @@ variable [IsDedekindDomain B] {I J : FractionalIdeal B⁰ L} set_option backward.isDefEq.respectTransparency.types false in lemma coe_dual (hI : I ≠ 0) : - (dual A K I : Submodule B L) = Iᵛ := by rw [dual, dif_neg hI, coe_mk] + (dual A K I : Submodule B L) = Iᵛ := by rw [dual, dite_eq_right hI, coe_mk] variable (B L) @@ -274,14 +274,14 @@ lemma coe_dual_one : set_option backward.isDefEq.respectTransparency.types false in @[simp] lemma dual_zero : - dual A K (0 : FractionalIdeal B⁰ L) = 0 := by rw [dual, dif_pos rfl] + dual A K (0 : FractionalIdeal B⁰ L) = 0 := by rw [dual, dite_eq_left rfl] variable {A K L B} set_option backward.isDefEq.respectTransparency.types false in lemma mem_dual (hI : I ≠ 0) {x} : x ∈ dual A K I ↔ ∀ a ∈ I, traceForm K L x a ∈ (algebraMap A K).range := by - rw [dual, dif_neg hI]; exact forall₂_congr fun _ _ ↦ mem_one + rw [dual, dite_eq_right hI]; exact forall₂_congr fun _ _ ↦ mem_one variable (A K) @@ -318,7 +318,7 @@ variable (A K) set_option backward.isDefEq.respectTransparency.types false in lemma le_dual_inv_aux (hI : I ≠ 0) (hIJ : I * J ≤ 1) : J ≤ dual A K I := by - rw [dual, dif_neg hI] + rw [dual, dite_eq_right hI] intro x hx y hy rw [mem_one] apply IsIntegrallyClosed.isIntegral_iff.mp diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index 14c51c10eac37a..a8efdab49893e4 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -212,7 +212,8 @@ theorem iInf_maxPowDividing_eq {I : Ideal R} (h0 : I ≠ 0) : ⨅ i : HeightOneSpectrum R, i.maxPowDividing I = I := by nth_rw 2 [← Ideal.finprod_heightOneSpectrum_factorization h0] classical - rw [finprod_def, dif_pos (Ideal.hasFiniteMulSupport h0), Ideal.prod_eq_iInf_of_pairwise_isCoprime] + rw [finprod_def, dite_eq_left (Ideal.hasFiniteMulSupport h0), + Ideal.prod_eq_iInf_of_pairwise_isCoprime] · ext x constructor · aesop @@ -313,7 +314,7 @@ def count (I : FractionalIdeal R⁰ K) : ℤ := (Associates.mk v.asIdeal).count (Associates.mk (Ideal.span {a})).factors : ℤ) /-- `val_v(0) = 0`. -/ -lemma count_zero : count K v (0 : FractionalIdeal R⁰ K) = 0 := by simp only [count, dif_pos] +lemma count_zero : count K v (0 : FractionalIdeal R⁰ K) = 0 := by simp only [count, dite_eq_left] open Classical in lemma count_ne_zero {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) : @@ -321,7 +322,7 @@ lemma count_ne_zero {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) : (choose (choose_spec (exists_eq_spanSingleton_mul I)))).factors - (Associates.mk v.asIdeal).count (Associates.mk (Ideal.span {choose (exists_eq_spanSingleton_mul I)})).factors : ℤ) := by - simp only [count, dif_neg hI] + simp only [count, dite_eq_right hI] open Classical in /-- `val_v(I)` does not depend on the choice of `a` and `J` used to represent `I`. -/ @@ -350,7 +351,7 @@ theorem count_well_defined {I : FractionalIdeal R⁰ K} (hI : I ≠ 0) {a : R} exact Associates.irreducible_mk.mpr v.irreducible rw [h_a₁J₁, ← div_spanSingleton, ← div_spanSingleton, div_eq_div_iff h_a₁' h_a', ← coeIdeal_span_singleton, ← coeIdeal_span_singleton, ← coeIdeal_mul, ← coeIdeal_mul] at h_aJ - rw [count, dif_neg hI, sub_eq_sub_iff_add_eq_add, ← natCast_add, ← natCast_add, natCast_inj, + rw [count, dite_eq_right hI, sub_eq_sub_iff_add_eq_add, ← natCast_add, ← natCast_add, natCast_inj, ← Associates.count_mul _ _ hv, ← Associates.count_mul _ _ hv, Associates.mk_mul_mk, Associates.mk_mul_mk, coeIdeal_injective h_aJ] · rw [ne_eq, Associates.mk_eq_zero]; exact h_J_ne_zero @@ -420,8 +421,8 @@ theorem count_pow (n : ℕ) (I : FractionalIdeal R⁰ K) : classical rw [pow_succ, count_mul'] by_cases hI : I = 0 · have h_neg : ¬(I ^ n ≠ 0 ∧ I ≠ 0) := by order - rw [if_neg h_neg, hI, count_zero, mul_zero] - · rw [if_pos (And.intro (pow_ne_zero n hI) hI), h, Nat.cast_add, + rw [ite_eq_right h_neg, hI, count_zero, mul_zero] + · rw [ite_eq_left (And.intro (pow_ne_zero n hI) hI), h, Nat.cast_add, Nat.cast_one] ring @@ -504,8 +505,8 @@ theorem count_finprod_coprime (exps : HeightOneSpectrum R → ℤ) : · intro I I' hI hI' classical by_cases h : I ≠ 0 ∧ I' ≠ 0 - · rw [count_mul' K v, if_pos h, hI, hI', add_zero] - · rw [count_mul' K v, if_neg h] + · rw [count_mul' K v, ite_eq_left h, hI, hI', add_zero] + · rw [count_mul' K v, ite_eq_right h] · intro w hw rw [count_zpow, count_maximal_coprime K v hw, mul_zero] @@ -709,7 +710,7 @@ def divMod (c b a : FractionalIdeal R⁰ K) : K := lemma divMod_spec {a b c : FractionalIdeal R⁰ K} (hac : a ≤ c) (ha : a ≠ 0) (hb : b ≠ 0) : a + spanSingleton R⁰ (c.divMod b a) * b = c := by - rw [divMod, dif_pos ⟨hac, ha, hb⟩] + rw [divMod, dite_eq_left ⟨hac, ha, hb⟩] exact (IsDedekindDomain.exists_add_spanSingleton_mul_eq hac ha hb).choose_spec @[simp] diff --git a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean index f783414a6c8129..72d97170295444 100644 --- a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean +++ b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean @@ -101,8 +101,8 @@ theorem valuationOfNeZeroToFun_eq (x : Kˣ) : rw [Units.val_inv_eq_inv_val] change _ = ite _ _ _ * (ite _ _ _)⁻¹ simp_rw [IsLocalization.toLocalizationMap_sec, SubmonoidClass.coe_subtype, - if_neg <| IsLocalization.sec_fst_ne_zero x.ne_zero, - if_neg (nonZeroDivisors.coe_ne_zero _), + ite_eq_right <| IsLocalization.sec_fst_ne_zero x.ne_zero, + ite_eq_right (nonZeroDivisors.coe_ne_zero _), ← exp_neg, ← exp_add, valuationOfNeZeroToFun, ← sub_eq_add_neg, exp] /-- The multiplicative `v`-adic valuation on `Kˣ`. -/ diff --git a/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean b/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean index c36b5a97e98dfb..388a23a45e632a 100644 --- a/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean +++ b/Mathlib/RingTheory/DividedPowerAlgebra/Init.lean @@ -161,13 +161,13 @@ theorem dp_smul {r : R} {n : ℕ} {m : M} : dp R n (r • m) = r ^ n • dp R n theorem dp_null {n : ℕ} : dp R n (0 : M) = if n = 0 then 1 else 0 := by cases Nat.eq_zero_or_pos n with | inl hn => - rw [if_pos hn, hn, dp_zero] + rw [ite_eq_left hn, hn, dp_zero] | inr hn => - rw [if_neg (ne_of_gt hn), ← zero_smul R (0 : M), dp_smul] + rw [ite_eq_right (ne_of_gt hn), ← zero_smul R (0 : M), dp_smul] rw [zero_pow (Nat.pos_iff_ne_zero.mp hn), zero_smul] theorem dp_null_of_ne_zero {n : ℕ} (hn : n ≠ 0) : dp R n (0 : M) = 0 := by - rw [dp_null, if_neg hn] + rw [dp_null, ite_eq_right hn] theorem dp_mul {n p : ℕ} {m : M} : dp R n m * dp R p m = (n + p).choose n • dp R (n + p) m := by diff --git a/Mathlib/RingTheory/DividedPowers/Basic.lean b/Mathlib/RingTheory/DividedPowers/Basic.lean index dfcd7b6c18d184..4f81730247930e 100644 --- a/Mathlib/RingTheory/DividedPowers/Basic.lean +++ b/Mathlib/RingTheory/DividedPowers/Basic.lean @@ -97,7 +97,7 @@ noncomputable def dividedPowersBot : DividedPowers (⊥ : Ideal A) where dpow n a := open scoped Classical in ite (a = 0 ∧ n = 0) 1 0 dpow_null {n a} ha := by simp only [mem_bot] at ha - rw [if_neg] + rw [ite_eq_right] exact not_and_of_not_left (n = 0) ha dpow_zero ha := by rw [mem_bot.mp ha] @@ -119,21 +119,21 @@ noncomputable def dividedPowersBot : DividedPowers (⊥ : Ideal A) where rw [mem_bot.mp hx] simp only [mul_zero, true_and, mul_ite, mul_one] by_cases hn : n = 0 - · rw [if_pos hn, hn, if_pos rfl, _root_.pow_zero] - · simp only [if_neg hn] + · rw [ite_eq_left hn, hn, ite_eq_left rfl, _root_.pow_zero] + · simp only [ite_eq_right hn] mul_dpow {m n x} hx := by rw [mem_bot.mp hx] simp only [true_and, mul_ite, mul_one, mul_zero, add_eq_zero] by_cases hn : n = 0 · simp only [hn, ite_true, and_true, add_zero, choose_self, cast_one] - · rw [if_neg hn, if_neg] + · rw [ite_eq_right hn, ite_eq_right] exact not_and_of_not_right (m = 0) hn dpow_comp m {n a} hn ha := by rw [mem_bot.mp ha] simp only [true_and, ite_eq_right_iff, _root_.mul_eq_zero, mul_ite, mul_one, mul_zero] by_cases hm : m = 0 · simp [hm, uniformBell_zero_left, hn] - · simp only [hm, and_false, ite_false, false_or, if_neg hn] + · simp only [hm, and_false, ite_false, false_or, ite_eq_right hn] lemma dividedPowersBot_dpow_eq [DecidableEq A] (n : ℕ) (a : A) : (dividedPowersBot A).dpow n a = diff --git a/Mathlib/RingTheory/DividedPowers/Padic.lean b/Mathlib/RingTheory/DividedPowers/Padic.lean index 53a15185fa2b95..cc50ed4e259707 100644 --- a/Mathlib/RingTheory/DividedPowers/Padic.lean +++ b/Mathlib/RingTheory/DividedPowers/Padic.lean @@ -42,33 +42,34 @@ noncomputable def DividedPowers.ofInjective (f : A →+* B) (hf : Injective f) (hmem : ∀ (n : ℕ) {x : A} (_ : x ∈ I), ∃ (y : A) (_ : n ≠ 0 → y ∈ I), f y = hJ.dpow n (f x)) : DividedPowers I where dpow n x := open scoped Classical in if hx : x ∈ I then Exists.choose (hmem n hx) else 0 - dpow_null hx := by simp [dif_neg hx] + dpow_null hx := by simp [dite_eq_right hx] dpow_zero {x} hx := by - simp only [dif_pos hx, ← hf.eq_iff, (Exists.choose_spec (hmem 0 hx)).2, map_one] + simp only [dite_eq_left hx, ← hf.eq_iff, (Exists.choose_spec (hmem 0 hx)).2, map_one] rw [hJ.dpow_zero (hIJ ▸ Ideal.mem_map_of_mem f hx)] dpow_one hx := by - simpa only [dif_pos hx, ← hf.eq_iff, (Exists.choose_spec (_ : ∃ a, ∃ _, f a = _)).2] + simpa only [dite_eq_left hx, ← hf.eq_iff, (Exists.choose_spec (_ : ∃ a, ∃ _, f a = _)).2] using hJ.dpow_one (hIJ ▸ Ideal.mem_map_of_mem f hx) - dpow_mem {n x} hn hx := by simpa only [dif_pos hx] using (Exists.choose_spec (hmem n hx)).1 hn + dpow_mem {n x} hn hx := by + simpa only [dite_eq_left hx] using (Exists.choose_spec (hmem n hx)).1 hn dpow_add {n x y} hx hy := by have hxy : x + y ∈ I := Ideal.add_mem _ hx hy - simpa only [dif_pos hxy, dif_pos hx, dif_pos hy, ← hf.eq_iff, map_sum, map_mul, + simpa only [dite_eq_left hxy, dite_eq_left hx, dite_eq_left hy, ← hf.eq_iff, map_sum, map_mul, (Exists.choose_spec (_ : ∃ a, ∃ _, f a = _)).2, map_add] using hJ.dpow_add (hIJ ▸ I.mem_map_of_mem f hx) (hIJ ▸ I.mem_map_of_mem f hy) dpow_mul {n a x} hx := by have hax : a * x ∈ I := Ideal.mul_mem_left _ _ hx - simpa only [(Exists.choose_spec (_ : ∃ a, ∃ _, f a = _)).2, dif_pos hax, dif_pos hx, + simpa only [(Exists.choose_spec (_ : ∃ a, ∃ _, f a = _)).2, dite_eq_left hax, dite_eq_left hx, ← hf.eq_iff, map_mul, map_pow] using hJ.dpow_mul (hIJ ▸ I.mem_map_of_mem f hx) - mul_dpow hx := by simpa only [dif_pos hx, ← hf.eq_iff, (Exists.choose_spec (hmem _ hx)).2, + mul_dpow hx := by simpa only [dite_eq_left hx, ← hf.eq_iff, (Exists.choose_spec (hmem _ hx)).2, map_mul, map_natCast] using hJ.mul_dpow (hIJ ▸ I.mem_map_of_mem f hx) dpow_comp {n m x} hm hx := by - simp only [dif_pos hx, ← hf.eq_iff, map_mul, map_natCast] - -- the condition for the other `dif_pos` is a bit messy so we use `rw` to + simp only [dite_eq_left hx, ← hf.eq_iff, map_mul, map_natCast] + -- the condition for the other `dite_eq_left` is a bit messy so we use `rw` to -- spin it off into a separate branch - rw [dif_pos] + rw [dite_eq_left] · simp only [(Exists.choose_spec (_ : ∃ a, ∃ _, f a = _)).2] exact hJ.dpow_comp hm (hIJ ▸ I.mem_map_of_mem f hx) - · rw [dif_pos hx] + · rw [dite_eq_left hx] exact (Exists.choose_spec (hmem m hx)).1 hm end Injective diff --git a/Mathlib/RingTheory/DividedPowers/RatAlgebra.lean b/Mathlib/RingTheory/DividedPowers/RatAlgebra.lean index 9f04631d5bf070..bb184a8a32a450 100644 --- a/Mathlib/RingTheory/DividedPowers/RatAlgebra.lean +++ b/Mathlib/RingTheory/DividedPowers/RatAlgebra.lean @@ -87,7 +87,7 @@ theorem dpow_add_of_lt {n : ℕ} (hn_fac : IsUnit ((n - 1)! : A)) {m : ℕ} (hmn Finset.mul_sum, Commute.add_pow' (Commute.all _ _)] apply Finset.sum_congr rfl intro k hk - rw [if_pos hx, if_pos hy] + rw [ite_eq_left hx, ite_eq_left hy] ring_nf simp only [mul_assoc]; congr; rw [← mul_assoc] exact castChoose_eq (hn_fac.natCast_factorial_of_lt hmn) hk @@ -106,7 +106,7 @@ theorem dpow_add {n : ℕ} (hn_fac : IsUnit ((n - 1)! : A)) (hnI : I ^ n = 0) {m rw [hxy, mul_zero, eq_comm] apply Finset.sum_eq_zero intro k hk - rw [if_pos hx, if_pos hy, mul_assoc, mul_comm (x ^ k.1), mul_assoc, ← mul_assoc] + rw [ite_eq_left hx, ite_eq_left hy, mul_assoc, mul_comm (x ^ k.1), mul_assoc, ← mul_assoc] apply mul_eq_zero_of_right rw [← Ideal.mem_bot, ← Ideal.zero_eq_bot, ← hnI] apply Set.mem_of_subset_of_mem h_sub @@ -304,7 +304,7 @@ variable {I} /-- There are no other divided power structures on an ideal of a `ℚ`-algebra. -/ theorem dividedPowers_unique (hI : DividedPowers I) : hI = dividedPowers I := - hI.ext _ (fun n x hx ↦ by rw [dpow_apply, if_pos hx, eq_comm, inverse_mul_eq_iff_eq_mul _ _ _ + hI.ext _ (fun n x hx ↦ by rw [dpow_apply, ite_eq_left hx, eq_comm, inverse_mul_eq_iff_eq_mul _ _ _ (IsUnit.natCast_factorial_of_algebra ℚ n), factorial_mul_dpow_eq_pow _ hx]) end RatAlgebra diff --git a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean index 1702ec941f74b1..7854e39795ffab 100644 --- a/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean +++ b/Mathlib/RingTheory/DividedPowers/SubDPIdeal.lean @@ -100,17 +100,18 @@ set_option linter.style.whitespace false in -- manual alignment is not recognise def dividedPowers {J : Ideal A} (hJ : IsSubDPIdeal hI J) [∀ x, Decidable (x ∈ J)] : DividedPowers J where dpow n x := if x ∈ J then hI.dpow n x else 0 - dpow_null hx := by simp [if_neg hx] - dpow_zero hx := by simp [if_pos hx, hI.dpow_zero (hJ.isSubideal hx)] - dpow_one hx := by simp [if_pos hx, hI.dpow_one (hJ.isSubideal hx)] - dpow_mem hn hx := by simp [if_pos hx, hJ.dpow_mem _ hn hx] - dpow_add hx hy := by simp_rw [if_pos hx, if_pos hy, if_pos (Ideal.add_mem J hx hy), - hI.dpow_add (hJ.isSubideal hx) (hJ.isSubideal hy)] + dpow_null hx := by simp [ite_eq_right hx] + dpow_zero hx := by simp [ite_eq_left hx, hI.dpow_zero (hJ.isSubideal hx)] + dpow_one hx := by simp [ite_eq_left hx, hI.dpow_one (hJ.isSubideal hx)] + dpow_mem hn hx := by simp [ite_eq_left hx, hJ.dpow_mem _ hn hx] + dpow_add hx hy := by + simp_rw [ite_eq_left hx, ite_eq_left hy, ite_eq_left (Ideal.add_mem J hx hy), + hI.dpow_add (hJ.isSubideal hx) (hJ.isSubideal hy)] dpow_mul hx := by - simp [if_pos hx, if_pos (mul_mem_left J _ hx), hI.dpow_mul (hJ.isSubideal hx)] - mul_dpow hx := by simp [if_pos hx, hI.mul_dpow (hJ.isSubideal hx)] + simp [ite_eq_left hx, ite_eq_left (mul_mem_left J _ hx), hI.dpow_mul (hJ.isSubideal hx)] + mul_dpow hx := by simp [ite_eq_left hx, hI.mul_dpow (hJ.isSubideal hx)] dpow_comp hn hx := by - simp [if_pos hx, if_pos (hJ.dpow_mem _ hn hx), hI.dpow_comp hn (hJ.isSubideal hx)] + simp [ite_eq_left hx, ite_eq_left (hJ.dpow_mem _ hn hx), hI.dpow_comp hn (hJ.isSubideal hx)] variable {J : Ideal A} (hJ : IsSubDPIdeal hI J) [∀ x, Decidable (x ∈ J)] @@ -118,7 +119,7 @@ lemma dpow_eq (n : ℕ) (a : A) : (IsSubDPIdeal.dividedPowers hI hJ).dpow n a = if a ∈ J then hI.dpow n a else 0 := rfl lemma dpow_eq_of_mem {n : ℕ} {a : A} (ha : a ∈ J) : - (IsSubDPIdeal.dividedPowers hI hJ).dpow n a = hI.dpow n a := by rw [dpow_eq, if_pos ha] + (IsSubDPIdeal.dividedPowers hI hJ).dpow n a = hI.dpow n a := by rw [dpow_eq, ite_eq_left ha] theorem isDPMorphism (hJ : IsSubDPIdeal hI J) : (IsSubDPIdeal.dividedPowers hI hJ).IsDPMorphism hI (RingHom.id A) := by @@ -565,7 +566,7 @@ theorem dpow_apply' (hIf : IsSubDPIdeal hI (RingHom.ker f ⊓ I)) {n : ℕ} {a : classical simp only [dpow, Function.extend_def] have h : ∃ (a_1 : I), f ↑a_1 = f a := by use ⟨a, ha⟩ - rw [dif_pos h, ← sub_eq_zero, ← map_sub, ← RingHom.mem_ker] + rw [dite_eq_left h, ← sub_eq_zero, ← map_sub, ← RingHom.mem_ker] apply (hI.isSubDPIdeal_inf_iff.mp hIf) (Submodule.coe_mem _) ha rw [RingHom.mem_ker, map_sub, sub_eq_zero, h.choose_spec] @@ -577,7 +578,7 @@ noncomputable def dividedPowers : DividedPowers J where dpow := dpow hI f dpow_null n {x} hx' := by classical - rw [dpow, Function.extend_def, dif_neg, Pi.zero_apply] + rw [dpow, Function.extend_def, dite_eq_right, Pi.zero_apply] rintro ⟨⟨a, ha⟩, rfl⟩ exact (hIJ ▸ hx') (apply_coe_mem_map f I ⟨a, ha⟩) dpow_zero {x} hx := by diff --git a/Mathlib/RingTheory/Filtration.lean b/Mathlib/RingTheory/Filtration.lean index 7c312b1d9c5563..873d195ab6ed5a 100644 --- a/Mathlib/RingTheory/Filtration.lean +++ b/Mathlib/RingTheory/Filtration.lean @@ -300,12 +300,12 @@ theorem submodule_eq_span_le_iff_stable_ge (n₀ : ℕ) : intro x hx obtain ⟨l, hl⟩ := (Finsupp.mem_span_iff_linearCombination _ _ _).mp (H _ ⟨x, hx, rfl⟩) replace hl := congr_arg (fun f : PolynomialModule R M => f.coeff (n + 1)) hl - rw [PolynomialModule.coeff_single, Finsupp.single_apply, if_pos rfl] at hl + rw [PolynomialModule.coeff_single, Finsupp.single_apply, ite_eq_left rfl] at hl rw [← hl, Finsupp.linearCombination_apply, PolynomialModule.coeff_finsuppSum, Finsupp.sum_apply] apply Submodule.sum_mem _ _ rintro ⟨_, _, ⟨n', rfl⟩, _, ⟨hn', rfl⟩, m, hm, rfl⟩ - dsimp only [Subtype.coe_mk] - rw [Subalgebra.smul_def, smul_single_apply, if_pos (show n' ≤ n + 1 by lia)] + rw [Subalgebra.smul_def, smul_single_apply, ite_eq_left (show n' ≤ n + 1 by lia)] have e : n' ≤ n := by lia have := F.pow_smul_le_pow_smul (n - n') n' 1 rw [tsub_add_cancel_of_le e, pow_one, add_comm _ 1, ← add_tsub_assoc_of_le e, add_comm] at this diff --git a/Mathlib/RingTheory/Finiteness/Finsupp.lean b/Mathlib/RingTheory/Finiteness/Finsupp.lean index 2082f82178c711..0f5c74b1dd6c56 100644 --- a/Mathlib/RingTheory/Finiteness/Finsupp.lean +++ b/Mathlib/RingTheory/Finiteness/Finsupp.lean @@ -87,9 +87,9 @@ theorem fg_of_fg_map_of_fg_inf_ker (f : M →ₗ[R] P) {s : Submodule R M} exists fun y => if H : y ∈ t1 then g y H else 0 intro y H constructor - · simp only [dif_pos H] + · simp only [dite_eq_left H] apply hg1 - · simp only [dif_pos H] + · simp only [dite_eq_left H] apply hg2 obtain ⟨g, hg⟩ := this clear this diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index ecc710ca45a3ec..077d7fa2ca941e 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -401,16 +401,16 @@ variable {I J : FractionalIdeal R₁⁰ K} @[simp] theorem div_zero {I : FractionalIdeal R₁⁰ K} : I / 0 = 0 := - dif_pos rfl + dite_eq_left rfl theorem div_of_ne_zero {I J : FractionalIdeal R₁⁰ K} (h : J ≠ 0) : I / J = ⟨I / J, isFractional_div_of_ne_zero h⟩ := - dif_neg h + dite_eq_right h @[simp] theorem coe_div {I J : FractionalIdeal R₁⁰ K} (hJ : J ≠ 0) : (↑(I / J) : Submodule R₁ K) = ↑I / (↑J : Submodule R₁ K) := - congr_arg _ (dif_neg hJ) + congr_arg _ (dite_eq_right hJ) theorem mem_div_iff_of_ne_zero {I J : FractionalIdeal R₁⁰ K} (h : J ≠ 0) {x} : x ∈ I / J ↔ ∀ y ∈ J, x * y ∈ I := by diff --git a/Mathlib/RingTheory/FreeCommRing.lean b/Mathlib/RingTheory/FreeCommRing.lean index 991e7dbbedff95..7a6790ae63415d 100644 --- a/Mathlib/RingTheory/FreeCommRing.lean +++ b/Mathlib/RingTheory/FreeCommRing.lean @@ -251,7 +251,7 @@ theorem isSupported_of {p} {s : Set α} : IsSupported (of p) s ↔ p ∈ s := rw [map_neg, map_one, Int.cast_neg, Int.cast_one] · rintro _ ⟨z, hzs, rfl⟩ _ _ use 0 - rw [map_mul, lift_of, if_pos hzs, zero_mul] + rw [map_mul, lift_of, ite_eq_left hzs, zero_mul] norm_cast · rintro x y ⟨q, hq⟩ ⟨r, hr⟩ refine ⟨q + r, ?_⟩ @@ -266,7 +266,8 @@ theorem isSupported_of {p} {s : Set α} : IsSupported (of p) s ↔ p ∈ s := rcases this with ⟨w, H⟩ rw [← Polynomial.C_eq_intCast] at H have : Polynomial.X.coeff 1 = (Polynomial.C ↑w).coeff 1 := by rw [H]; rfl - rwa [Polynomial.coeff_C, if_neg (one_ne_zero : 1 ≠ 0), Polynomial.coeff_X, if_pos rfl] at this + rwa [Polynomial.coeff_C, ite_eq_right (one_ne_zero : 1 ≠ 0), Polynomial.coeff_X, + ite_eq_left rfl] at this theorem map_subtype_val_restriction {x} (s : Set α) [DecidablePred (· ∈ s)] (hxs : IsSupported x s) : map (↑) (restriction s x) = x := by @@ -276,7 +277,7 @@ theorem map_subtype_val_restriction {x} (s : Set α) [DecidablePred (· ∈ s)] · rw [map_neg, map_one] rfl · rintro _ ⟨p, hps, rfl⟩ n ih - rw [map_mul, restriction_of, dif_pos hps, map_mul, map_of, ih] + rw [map_mul, restriction_of, dite_eq_left hps, map_mul, map_of, ih] · intro x y ihx ihy rw [map_add, map_add, ihx, ihy] diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index eb95a35aee1bfb..7d38dfc7bd0f81 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -257,7 +257,7 @@ def orderTop (x : R⟦Γ⟧) : WithTop Γ := @[simp] theorem orderTop_zero : orderTop (0 : R⟦Γ⟧) = ⊤ := - dif_pos rfl + dite_eq_left rfl @[simp] theorem orderTop_of_subsingleton [Subsingleton R] : x.orderTop = ⊤ := @@ -265,7 +265,7 @@ theorem orderTop_of_subsingleton [Subsingleton R] : x.orderTop = ⊤ := theorem orderTop_of_ne_zero (hx : x ≠ 0) : orderTop x = x.isWF_support.min (support_nonempty_iff.2 hx) := - dif_neg hx + dite_eq_right hx @[simp] lemma orderTop_eq_top : orderTop x = ⊤ ↔ x = 0 := by simp [orderTop] @@ -361,11 +361,11 @@ def order (x : R⟦Γ⟧) : Γ := @[simp] theorem order_zero : order (0 : R⟦Γ⟧) = 0 := - dif_pos rfl + dite_eq_left rfl theorem order_of_ne {x : R⟦Γ⟧} (hx : x ≠ 0) : order x = x.isWF_support.min (support_nonempty_iff.2 hx) := - dif_neg hx + dite_eq_right hx theorem order_eq_orderTop_of_ne_zero (hx : x ≠ 0) : order x = orderTop x := by rw [order_of_ne hx, orderTop_of_ne_zero hx] @@ -439,7 +439,7 @@ def embDomain (f : Γ ↪o Γ') : R⟦Γ⟧ → R⟦Γ'⟧ := fun x => isPWO_support' := (x.isPWO_support.image_of_monotone f.monotone).mono fun b hb => by contrapose hb - rw [Function.mem_support, dif_neg hb, Classical.not_not] } + rw [Function.mem_support, dite_eq_right hb, Classical.not_not] } @[simp] theorem embDomain_coeff {f : Γ ↪o Γ'} {x : R⟦Γ⟧} {a : Γ} : @@ -447,9 +447,9 @@ theorem embDomain_coeff {f : Γ ↪o Γ'} {x : R⟦Γ⟧} {a : Γ} : rw [embDomain] dsimp only by_cases ha : a ∈ x.support - · rw [dif_pos (Set.mem_image_of_mem f ha)] + · rw [dite_eq_left (Set.mem_image_of_mem f ha)] exact congr rfl (f.injective (Classical.choose_spec (Set.mem_image_of_mem f ha)).2) - · rw [dif_neg, Classical.not_not.1 fun c => ha ((mem_support _ _).2 c)] + · rw [dite_eq_right, Classical.not_not.1 fun c => ha ((mem_support _ _).2 c)] contrapose ha obtain ⟨b, hb1, hb2⟩ := (Set.mem_image _ _ _).1 ha rwa [f.injective hb2] at hb1 @@ -462,7 +462,7 @@ theorem embDomain_mk_coeff {f : Γ → Γ'} (hfi : Function.Injective f) theorem embDomain_notin_image_support {f : Γ ↪o Γ'} {x : R⟦Γ⟧} {b : Γ'} (hb : b ∉ f '' x.support) : (embDomain f x).coeff b = 0 := - dif_neg hb + dite_eq_right hb theorem support_embDomain_subset {f : Γ ↪o Γ'} {x : R⟦Γ⟧} : support (embDomain f x) ⊆ f '' x.support := by diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 2c082d95aabe11..142c63736c2945 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -619,17 +619,17 @@ def embDomain (s : SummableFamily Γ R α) (f : α ↪ β) : SummableFamily Γ R isPWO_iUnion_support' := by refine s.isPWO_iUnion_support.mono (Set.iUnion_subset fun b g h => ?_) by_cases hb : b ∈ Set.range f - · rw [dif_pos hb] at h + · rw [dite_eq_left hb] at h exact Set.mem_iUnion.2 ⟨Classical.choose hb, h⟩ - · simp [-Set.mem_range, dif_neg hb] at h + · simp [-Set.mem_range, dite_eq_right hb] at h finite_co_support' g := ((s.finite_co_support g).image f).subset (by intro b h by_cases hb : b ∈ Set.range f - · simp only [Ne, Set.mem_ofPred_eq, dif_pos hb] at h + · simp only [Ne, Set.mem_ofPred_eq, dite_eq_left hb] at h exact ⟨Classical.choose hb, h, Classical.choose_spec hb⟩ - · simp only [Ne, Set.mem_ofPred_eq, dif_neg hb, coeff_zero, not_true_eq_false] at h) + · simp only [Ne, Set.mem_ofPred_eq, dite_eq_right hb, coeff_zero, not_true_eq_false] at h) variable (s : SummableFamily Γ R α) (f : α ↪ β) {a : α} {b : β} @@ -640,12 +640,12 @@ theorem embDomain_apply : @[simp] theorem embDomain_image : s.embDomain f (f a) = s a := by - rw [embDomain_apply, dif_pos (Set.mem_range_self a)] + rw [embDomain_apply, dite_eq_left (Set.mem_range_self a)] exact congr rfl (f.injective (Classical.choose_spec (Set.mem_range_self a))) @[simp] theorem embDomain_of_notMem_range (h : b ∉ Set.range f) : s.embDomain f b = 0 := by - rw [embDomain_apply, dif_neg h] + rw [embDomain_apply, dite_eq_right h] @[deprecated (since := "2026-07-15")] alias embDomain_notin_range := embDomain_of_notMem_range @@ -848,7 +848,7 @@ theorem isUnit_iff {x : R⟦Γ⟧} : IsUnit x ↔ IsUnit (x.leadingCoeff) := by refine .of_mul_eq_one (i.leadingCoeff) ((coeff_mul_order_add_order u i).symm.trans ?_) - rw [ui, coeff_one, if_pos] + rw [ui, coeff_one, ite_eq_left] rw [← order_mul (left_ne_zero_of_mul_eq_one ui) (right_ne_zero_of_mul_eq_one ui), ui, order_one] · rintro ⟨⟨u, i, ui, iu⟩, hx⟩ rw [Units.val_mk] at hx diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index e203e721574254..53bc7c18c2f44e 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -1338,7 +1338,7 @@ theorem range_finsuppTotal : rw [finsuppTotal_apply, Finsupp.sum_mapRange_index] · apply Finsupp.sum_congr intro i _ - rw [dif_pos (ha i)] + rw [dite_eq_left (ha i)] · exact fun _ => zero_smul _ _ end Total diff --git a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean index cf606703c0e42e..40e51966aa9ea9 100644 --- a/Mathlib/RingTheory/Ideal/Quotient/Basic.lean +++ b/Mathlib/RingTheory/Ideal/Quotient/Basic.lean @@ -120,8 +120,8 @@ protected noncomputable abbrev groupWithZero [hI : I.IsMaximal] : GroupWithZero (R ⧸ I) := fast_instance% { inv := fun a => if ha : a = 0 then 0 else Classical.choose (exists_inv ha) mul_inv_cancel := fun a (ha : a ≠ 0) => - show a * dite _ _ _ = _ by rw [dif_neg ha]; exact Classical.choose_spec (exists_inv ha) - inv_zero := dif_pos rfl + show a * dite _ _ _ = _ by rw [dite_eq_right ha]; exact Classical.choose_spec (exists_inv ha) + inv_zero := dite_eq_left rfl __ := Quotient.nontrivial_iff.mpr hI.out.1 } /-- The quotient by a two-sided ideal that is maximal as a left ideal is a division ring. diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean index 9ca9ada5ad1a80..e7e89e23bed0be 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Ideal.lean @@ -65,7 +65,7 @@ lemma exists_monic_aeval_eq_zero_forall_mem_pow_of_isIntegral simp only [q, map_sum, map_mul, aeval_C, map_pow, aeval_X] refine (Finset.sum_congr rfl fun i hi ↦ ?_).trans e simp only [Finset.mem_range, Nat.lt_succ_iff] at hi - rw [mul_pow, mul_left_comm, ← map_pow, coeff_C_mul, coeff_mul_X_pow', if_pos hi, mul_comm] + rw [mul_pow, mul_left_comm, ← map_pow, coeff_C_mul, coeff_mul_X_pow', ite_eq_left hi, mul_comm] simp [Subalgebra.algebraMap_def] · rw [hq] simp [q, apply_ite, coeff_mem_pow_of_mem_adjoin_C_mul_X (p.coeff _).2] diff --git a/Mathlib/RingTheory/IntegralDomain.lean b/Mathlib/RingTheory/IntegralDomain.lean index 8082b95429a845..df3a5a86b71dc5 100644 --- a/Mathlib/RingTheory/IntegralDomain.lean +++ b/Mathlib/RingTheory/IntegralDomain.lean @@ -58,7 +58,7 @@ def Fintype.groupWithZeroOfCancel (M : Type*) [MonoidWithZero M] [IsLeftCancelMu ‹MonoidWithZero M› with inv := fun a => if h : a = 0 then 0 else Fintype.bijInv (mul_right_bijective_of_finite₀ h) 1 mul_inv_cancel := fun a ha => by - simp only [dif_neg ha] + simp only [dite_eq_right ha] exact Fintype.rightInverse_bijInv _ _ inv_zero := by simp } diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index 858772ec012a59..84121674ed44b7 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -336,9 +336,9 @@ theorem coeff_coe (i : ℤ) : ((f : R⟦X⟧) : R⸨X⸩).coeff i = if i < 0 then 0 else PowerSeries.coeff i.natAbs f := by cases i - · rw [Int.ofNat_eq_natCast, coeff_coe_powerSeries, if_neg (Int.natCast_nonneg _).not_gt, + · rw [Int.ofNat_eq_natCast, coeff_coe_powerSeries, ite_eq_right (Int.natCast_nonneg _).not_gt, Int.natAbs_natCast] - · rw [ofPowerSeries_apply, embDomain_notin_image_support, if_pos (Int.negSucc_lt_zero _)] + · rw [ofPowerSeries_apply, embDomain_notin_image_support, ite_eq_left (Int.negSucc_lt_zero _)] simp theorem coe_C (r : R) : ((C r : R⟦X⟧) : R⸨X⸩) = HahnSeries.C r := @@ -824,7 +824,7 @@ theorem exists_Polynomial_intValuation_lt (F : K⟦X⟧) (η : ℤᵐ⁰ˣ) : (Multiplicative.ofAdd (-(d + 1 : ℤ))) := by apply (intValuation_le_iff_coeff_lt_eq_zero K _).mpr simpa only [map_sub, sub_eq_zero, Polynomial.coeff_coe, coeff_trunc] using - fun _ h ↦ (if_pos h).symm + fun _ h ↦ (ite_eq_left h).symm rw [neg_add, ofAdd_add, ← hd, ofAdd_toAdd, WithZero.coe_mul, coe_unzero, ← coe_algebraMap] at this rw [← valuation_of_algebraMap (K := K⸨X⸩) (PowerSeries.idealX K) (F - F.trunc (d + 1))] diff --git a/Mathlib/RingTheory/LocalRing/Module.lean b/Mathlib/RingTheory/LocalRing/Module.lean index 625f2413fff425..7f81596738804d 100644 --- a/Mathlib/RingTheory/LocalRing/Module.lean +++ b/Mathlib/RingTheory/LocalRing/Module.lean @@ -269,7 +269,7 @@ theorem IsLocalRing.linearIndependent_of_flat [Flat R M] {ι : Type u} (v : ι rw [show v n = _ from hay n] exact sum_mem fun _ _ ↦ Submodule.smul_mem_smul (this _) ⟨⟩ let a' (i : ι) : R := if hi : _ then a ⟨i, hi⟩ j else 0 - have a_eq i : a i j = a' i.1 := by simp_rw [a', dif_pos i.2] + have a_eq i : a i j = a' i.1 := by simp_rw [a', dite_eq_left i.2] have hfn : f n = -(∑ i ∈ s, f i * a' i) * hj.unit⁻¹ := by rw [← hj.mul_left_inj, mul_assoc, hj.val_inv_mul, mul_one, eq_neg_iff_add_eq_zero] convert! hfa j @@ -278,12 +278,12 @@ theorem IsLocalRing.linearIndependent_of_flat [Flat R M] {ι : Type u} (v : ι specialize ih (v + (c · • v n)) ?_ ?_ · convert! (linearIndependent_add_smul_iff (c := Ideal.Quotient.mk _ ∘ c) (i := n.1) ?_).mpr h · ext; simp [tmul_add]; rfl - simp_rw [Function.comp_def, c, if_pos, neg_zero, zero_mul, map_zero] + simp_rw [Function.comp_def, c, ite_eq_left, neg_zero, zero_mul, map_zero] · rw [Finset.sum_coe_sort _ (fun i ↦ f i • v i), s.sum_insert hn, add_comm, hfn] at hfv simp_rw [Pi.add_apply, smul_add, s.sum_add_distrib, c, smul_smul, ← s.sum_smul, ← mul_assoc, ← s.sum_mul, mul_neg, s.sum_neg_distrib, ← hfv] congr 4 - exact s.sum_congr rfl fun i hi ↦ by rw [if_neg (ne_of_mem_of_not_mem hi hn)] + exact s.sum_congr rfl fun i hi ↦ by rw [ite_eq_right (ne_of_mem_of_not_mem hi hn)] obtain hi | hi := Finset.mem_insert.mp hi · rw [hi, hfn, Finset.sum_eq_zero, neg_zero, zero_mul] intro i hi; rw [ih i hi, zero_mul] diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index 91a6038ceb3787..3df69d8d5f2392 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -639,7 +639,7 @@ noncomputable def selfZPow (m : ℤ) : B := if _ : 0 ≤ m then algebraMap _ _ x ^ m.natAbs else mk' _ (1 : R) (Submonoid.pow x m.natAbs) theorem selfZPow_of_nonneg {n : ℤ} (hn : 0 ≤ n) : selfZPow x B n = algebraMap R B x ^ n.natAbs := - dif_pos hn + dite_eq_left hn @[simp] theorem selfZPow_natCast (d : ℕ) : selfZPow x B d = algebraMap R B x ^ d := @@ -651,7 +651,7 @@ theorem selfZPow_zero : selfZPow x B 0 = 1 := by theorem selfZPow_of_neg {n : ℤ} (hn : n < 0) : selfZPow x B n = mk' _ (1 : R) (Submonoid.pow x n.natAbs) := - dif_neg hn.not_ge + dite_eq_right hn.not_ge theorem selfZPow_of_nonpos {n : ℤ} (hn : n ≤ 0) : selfZPow x B n = mk' _ (1 : R) (Submonoid.pow x n.natAbs) := by diff --git a/Mathlib/RingTheory/Localization/FractionRing.lean b/Mathlib/RingTheory/Localization/FractionRing.lean index 1198a37fc342d4..5b194d646d6aca 100644 --- a/Mathlib/RingTheory/Localization/FractionRing.lean +++ b/Mathlib/RingTheory/Localization/FractionRing.lean @@ -209,7 +209,7 @@ protected noncomputable irreducible_def inv (z : K) : K := open scoped Classical h <| eq_zero_of_fst_eq_zero (sec_spec (nonZeroDivisors A) z) h0⟩ protected theorem mul_inv_cancel (x : K) (hx : x ≠ 0) : x * IsFractionRing.inv A x = 1 := by - rw [IsFractionRing.inv, dif_neg hx, ← + rw [IsFractionRing.inv, dite_eq_right hx, ← IsUnit.mul_left_inj (map_units K ⟨(sec _ x).1, @@ -226,7 +226,9 @@ noncomputable abbrev toField : Field K where __ := IsFractionRing.isDomain A inv := IsFractionRing.inv A mul_inv_cancel := IsFractionRing.mul_inv_cancel A - inv_zero := show IsFractionRing.inv A (0 : K) = 0 by rw [IsFractionRing.inv]; exact dif_pos rfl + inv_zero := show IsFractionRing.inv A (0 : K) = 0 by + rw [IsFractionRing.inv] + exact dite_eq_left rfl nnqsmul := _ nnqsmul_def := fun _ _ => rfl qsmul := _ diff --git a/Mathlib/RingTheory/MvPolynomial/Groebner.lean b/Mathlib/RingTheory/MvPolynomial/Groebner.lean index a6e9f9fd30e998..67e560df156388 100644 --- a/Mathlib/RingTheory/MvPolynomial/Groebner.lean +++ b/Mathlib/RingTheory/MvPolynomial/Groebner.lean @@ -96,7 +96,7 @@ theorem degree_reduce_lt {f b : MvPolynomial σ R} (hb : IsUnit (m.leadingCoeff m.degree ((monomial (m.degree f - m.degree b)) (hb.unit⁻¹ * m.leadingCoeff f)) + m.degree b := by classical - rw [degree_monomial, if_neg] + rw [degree_monomial, ite_eq_right] · ext d rw [tsub_add_cancel_of_le hbf] · simp only [Units.mul_right_eq_zero, leadingCoeff_eq_zero_iff] diff --git a/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean b/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean index 5339bb38ce65d4..ad613300bc836e 100644 --- a/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean +++ b/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean @@ -168,7 +168,7 @@ theorem coeff_sumSMulX (i : n) : rw [Finset.sum_eq_single i _ (by simp)] · simp intro j hj hji - rw [coeff_smul, coeff_X, if_neg] + rw [coeff_smul, coeff_X, ite_eq_right] · simp · rwa [Finsupp.single_left_inj Nat.one_ne_zero] diff --git a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean index 4a110d6e962668..331ae5064e846d 100644 --- a/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean +++ b/Mathlib/RingTheory/MvPolynomial/MonomialOrder.lean @@ -193,7 +193,7 @@ theorem degree_X [Nontrivial R] {s : σ} : m.degree (X s : MvPolynomial σ R) = Finsupp.single s 1 := by classical change m.degree (monomial (Finsupp.single s 1) (1 : R)) = _ - rw [degree_monomial, if_neg one_ne_zero] + rw [degree_monomial, ite_eq_right one_ne_zero] @[simp] theorem degree_one : m.degree (1 : MvPolynomial σ R) = 0 := by nontriviality R @@ -320,7 +320,7 @@ theorem eq_C_of_degree_eq_zero {f : MvPolynomial σ R} (hf : m.degree f = 0) : classical by_cases hd : d = 0 · simp [hd] - · rw [coeff_C, if_neg (Ne.symm hd)] + · rw [coeff_C, ite_eq_right (Ne.symm hd)] apply coeff_eq_zero_of_lt (m := m) rw [hf, map_zero, lt_iff_le_and_ne, ne_eq, eq_comm, EmbeddingLike.map_eq_zero_iff] exact ⟨bot_le, hd⟩ diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean index c9e22d066f57d9..07dca6d8bd0454 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean @@ -107,14 +107,15 @@ lemma accumulate_invAccumulate {n m} (hmn : m ≤ n) {s : Fin m → ℕ} (hs : A revert hi refine Nat.decreasingInduction' (fun i hi _ ih him ↦ ?_) this fun hm ↦ ?_ · rw [← Nat.pred_eq_sub_one, Nat.lt_pred_iff, Nat.succ_eq_add_one] at hi - rw [accumulate_rec (him.trans_le hmn) hi, ih hi, invAccumulate, dif_pos him, dif_pos hi] + rw [accumulate_rec (him.trans_le hmn) hi, ih hi, invAccumulate, dite_eq_left him, + dite_eq_left hi] simp only exact Nat.sub_add_cancel (hs i.le_succ) · have := (Nat.sub_one_add_one <| Nat.ne_zero_of_lt hm).symm - rw [accumulate_last (hm.trans_le hmn) this, invAccumulate, dif_pos hm, dif_neg this.not_gt, - Nat.sub_zero] + rw [accumulate_last (hm.trans_le hmn) this, invAccumulate, dite_eq_left hm, + dite_eq_right this.not_gt, Nat.sub_zero] intro j hj - rw [invAccumulate, dif_neg hj.not_gt, Nat.zero_sub] + rw [invAccumulate, dite_eq_right hj.not_gt, Nat.zero_sub] end accumulate @@ -192,10 +193,10 @@ private lemma supDegree_monic_esymm [Nontrivial R] {i : ℕ} (him : i < m) : refine ⟨min' _ hne, fun k hk ↦ ?_, ?_⟩ all_goals simp only [ofLex_toLex, Finsupp.indicator_apply] · have hki := mem_Iic.2 (hk.le.trans <| mem_Iic.1 hkm.1) - rw [dif_pos hki, dif_pos] + rw [dite_eq_left hki, dite_eq_left] by_contra h exact lt_irrefl k <| ((lt_min'_iff _ _).1 hk) _ <| mem_sdiff.2 ⟨hki, h⟩ - · rw [dif_neg hkm.2, dif_pos hkm.1]; exact Nat.zero_lt_one + · rw [dite_eq_right hkm.2, dite_eq_left hkm.1]; exact Nat.zero_lt_one lemma supDegree_esymm [Nontrivial R] (him : i < m) : ofLex (supDegree toLex <| esymm (Fin m) R (i + 1)) = accumulate n m (Finsupp.single i 1) := by diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index 57b18a0573ea7e..ff5f4d1f4c52d3 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -412,7 +412,7 @@ theorem weightedHomogeneousComponent_isWeightedHomogeneous : classical intro d hd contrapose! hd - rw [coeff_weightedHomogeneousComponent, if_neg hd] + rw [coeff_weightedHomogeneousComponent, ite_eq_right hd] theorem weightedHomogeneousComponent_mem (w : σ → M) (φ : MvPolynomial σ R) (m : M) : weightedHomogeneousComponent w m φ ∈ weightedHomogeneousSubmodule R w m := by @@ -462,14 +462,14 @@ theorem sum_weightedHomogeneousComponent : ext1 d simp only [coeff_sum, coeff_weightedHomogeneousComponent] rw [Finset.sum_eq_single (weight w d)] - · rw [if_pos rfl] + · rw [ite_eq_left rfl] · intro m _ hm' - rw [if_neg hm'.symm] + rw [ite_eq_right hm'.symm] · intro hm - rw [if_pos rfl] + rw [ite_eq_left rfl] simp only [Finite.mem_toFinset, mem_support, Ne, Classical.not_not] at hm have := coeff_weightedHomogeneousComponent (w := w) (weight w d) φ d - rw [hm, if_pos rfl, coeff_zero] at this + rw [hm, ite_eq_left rfl, coeff_zero] at this exact this.symm theorem finsum_weightedHomogeneousComponent : @@ -488,7 +488,7 @@ theorem IsWeightedHomogeneous.weightedHomogeneousComponent_same {m : M} {p : MvP · split_ifs · rfl rw [zero_coeff] - · rw [hp zero_coeff, if_pos rfl] + · rw [hp zero_coeff, ite_eq_left rfl] theorem IsWeightedHomogeneous.weightedHomogeneousComponent_ne {m : M} (n : M) {p : MvPolynomial σ R} (hp : IsWeightedHomogeneous w p m) : @@ -499,7 +499,7 @@ theorem IsWeightedHomogeneous.weightedHomogeneousComponent_ne {m : M} (n : M) rw [coeff_weightedHomogeneousComponent] by_cases zero_coeff : coeff x p = 0 · simp [zero_coeff] - · rw [if_neg] + · rw [ite_eq_right] · rw [coeff_zero] · rw [hp zero_coeff]; exact Ne.symm hn @@ -585,8 +585,8 @@ theorem weightedHomogeneousComponent_zero [CanonicallyOrderedAdd M] [IsAddTorsio classical ext1 d rcases Classical.em (d = 0) with (rfl | hd) - · simp only [coeff_weightedHomogeneousComponent, if_pos, map_zero, coeff_zero_C] - · rw [coeff_weightedHomogeneousComponent, if_neg, coeff_C, if_neg (Ne.symm hd)] + · simp only [coeff_weightedHomogeneousComponent, ite_eq_left, map_zero, coeff_zero_C] + · rw [coeff_weightedHomogeneousComponent, ite_eq_right, coeff_C, ite_eq_right (Ne.symm hd)] simp only [weight, LinearMap.toAddMonoidHom_coe, Finsupp.linearCombination_apply, Finsupp.sum, sum_eq_zero_iff, Finsupp.mem_support_iff, Ne, smul_eq_zero, not_forall, not_or, and_self_left, exists_prop] diff --git a/Mathlib/RingTheory/MvPowerSeries/Basic.lean b/Mathlib/RingTheory/MvPowerSeries/Basic.lean index f5013b692f5a63..48a29cd8aefcdc 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Basic.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Basic.lean @@ -251,12 +251,12 @@ theorem coeff_mul_monomial (a : R) : theorem coeff_add_monomial_mul (a : R) : coeff (m + n) (monomial m a * φ) = a * coeff n φ := by - rw [coeff_monomial_mul, if_pos, add_tsub_cancel_left] + rw [coeff_monomial_mul, ite_eq_left, add_tsub_cancel_left] exact le_add_right le_rfl theorem coeff_add_mul_monomial (a : R) : coeff (m + n) (φ * monomial n a) = coeff m φ * a := by - rw [coeff_mul_monomial, if_pos, add_tsub_cancel_right] + rw [coeff_mul_monomial, ite_eq_left, add_tsub_cancel_right] exact le_add_left le_rfl @[simp] @@ -352,7 +352,7 @@ theorem coeff_zero_C (a : R) : coeff (0 : σ →₀ ℕ) (C a) = a := coeff_monomial_same 0 a theorem coeff_C_of_ne_zero {n : σ →₀ ℕ} (h : n ≠ 0) (a : R) : coeff n (C a) = 0 := by - classical rw [coeff_C, if_neg h] + classical rw [coeff_C, ite_eq_right h] -- The intended use case of this theorem is for `m = 1` (often useful for `pderiv`). @[simp] @@ -388,7 +388,7 @@ theorem coeff_index_single_self_X (s : σ) : coeff (single s 1) (X s : MvPowerSe theorem coeff_zero_X (s : σ) : coeff (0 : σ →₀ ℕ) (X s : MvPowerSeries σ R) = 0 := by classical - rw [coeff_X, if_neg] + rw [coeff_X, ite_eq_right] intro h exact one_ne_zero (single_eq_zero.mp h.symm) @@ -426,7 +426,7 @@ theorem coeff_C_mul (n : σ →₀ ℕ) (φ : MvPowerSeries σ R) (a : R) : theorem coeff_zero_mul_X (φ : MvPowerSeries σ R) (s : σ) : coeff (0 : σ →₀ ℕ) (φ * X s) = 0 := by have : ¬single s 1 ≤ 0 := fun h => by simpa using h s - simp only [X, coeff_mul_monomial, if_neg this] + simp only [X, coeff_mul_monomial, ite_eq_right this] theorem coeff_zero_X_mul (φ : MvPowerSeries σ R) (s : σ) : coeff (0 : σ →₀ ℕ) (X s * φ) = 0 := by rw [← (φ.commute_X s).eq, coeff_zero_mul_X] @@ -491,7 +491,7 @@ theorem X_inj [Nontrivial R] {s t : σ} : (X s : MvPowerSeries σ R) = X t ↔ s classical intro h replace h := congr_arg (coeff (single s 1)) h - rw [coeff_X, if_pos rfl, coeff_X] at h + rw [coeff_X, ite_eq_left rfl, coeff_X] at h split_ifs at h with H · rw [Finsupp.single_eq_single_iff] at H rcases H with H | H @@ -608,7 +608,7 @@ theorem X_pow_dvd_iff {s : σ} {n : ℕ} {φ : MvPowerSeries σ R} : · rintro ⟨φ, rfl⟩ m h rw [coeff_mul, Finset.sum_eq_zero] rintro ⟨i, j⟩ hij - rw [coeff_X_pow, if_neg, zero_mul] + rw [coeff_X_pow, ite_eq_right, zero_mul] contrapose! h dsimp at h subst i @@ -620,7 +620,7 @@ theorem X_pow_dvd_iff {s : σ} {n : ℕ} {φ : MvPowerSeries σ R} : ext m by_cases H : m - single s n + single s n = m · rw [coeff_mul, Finset.sum_eq_single (single s n, m - single s n)] - · rw [coeff_X_pow, if_pos rfl, one_mul] + · rw [coeff_X_pow, ite_eq_left rfl, one_mul] simpa using! congr_arg (fun m : σ →₀ ℕ => coeff m φ) H.symm · rintro ⟨i, j⟩ hij hne rw [mem_antidiagonal] at hij diff --git a/Mathlib/RingTheory/MvPowerSeries/Derivative.lean b/Mathlib/RingTheory/MvPowerSeries/Derivative.lean index 2d60ca78c9e679..b307fbdd1683dc 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Derivative.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Derivative.lean @@ -84,8 +84,8 @@ private theorem trunc_pderivFun [DecidableEq σ] {i : σ} (f : MvPowerSeries σ ext rw [coeff_trunc] split_ifs with h - · rw [coeff_pderivFun, coeff_pderiv, coeff_trunc, if_pos (add_lt_add_left h _)] - · rw [coeff_pderiv, coeff_trunc, if_neg ((add_lt_add_iff_right _).not.mpr h), zero_mul] + · rw [coeff_pderivFun, coeff_pderiv, coeff_trunc, ite_eq_left (add_lt_add_left h _)] + · rw [coeff_pderiv, coeff_trunc, ite_eq_right ((add_lt_add_iff_right _).not.mpr h), zero_mul] -- A special case of `pderivFun_mul`, used in its proof. private theorem pderivFun_coe_mul_coe {i : σ} (f g : MvPolynomial σ R) : @@ -145,7 +145,7 @@ theorem pderiv_X_of_ne {i j : σ} (h : j ≠ i) : pderiv R i (X j) = 0 := by classical ext n simpa only [coeff_pderiv, coeff_X, boole_mul, coeff_zero] using - if_neg (ne_iff.mpr ⟨i, by grind [Finsupp.add_apply]⟩) + ite_eq_right (ne_iff.mpr ⟨i, by grind [Finsupp.add_apply]⟩) theorem pderiv_X [DecidableEq σ] (i j : σ) : pderiv R i (X j) = Pi.single (M := fun _ => MvPowerSeries σ R) i 1 j := by diff --git a/Mathlib/RingTheory/MvPowerSeries/Equiv.lean b/Mathlib/RingTheory/MvPowerSeries/Equiv.lean index ba3b3f01ed9b36..399ba1381a2f1a 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Equiv.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Equiv.lean @@ -85,7 +85,7 @@ private theorem optionFunLeft_monomial (x : Option σ →₀ ℕ) (r : R) : · replace h1 : ¬ y = x.some := fun h ↦ by absurd h1; ext u cases u <;> simp_all - rw [coeff_monomial, if_neg h1] + rw [coeff_monomial, ite_eq_right h1] · rw [coeff_zero] private lemma optionFunLeft_mul (p q : MvPowerSeries (Option σ) R) : @@ -184,7 +184,7 @@ theorem finSuccEquiv_X_zero : finSuccEquiv R n (X 0) = .X := by split_ifs with h1 h2 h3 · simp [h1.left] · tauto - · rw [coeff_one, if_neg (by tauto)] + · rw [coeff_one, ite_eq_right (by tauto)] · rw [coeff_zero] @[simp] @@ -194,7 +194,7 @@ theorem finSuccEquiv_X_succ (j : Fin n) : finSuccEquiv R n (X j.succ) = .C (X j) split_ifs with h1 h2 h3 · simp [h1.left] · tauto - · rw [coeff_X, if_neg (by tauto)] + · rw [coeff_X, ite_eq_right (by tauto)] · rw [coeff_zero] @[simp] @@ -205,7 +205,7 @@ theorem finSuccEquiv_C (r : R) : (finSuccEquiv R n) (C r) = PowerSeries.C (C r) split_ifs with h1 h2 h3 · simp [h1.right] · tauto - · rw [coeff_C, if_neg (by tauto)] + · rw [coeff_C, ite_eq_right (by tauto)] · rw [coeff_zero] theorem finSuccEquiv_comp_C : (MvPowerSeries.finSuccEquiv R n).symm.toRingHom.comp diff --git a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean index fdbe675de82661..0e25eff68e6f74 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Evaluation.lean @@ -208,7 +208,7 @@ noncomputable def eval₂ (f : MvPowerSeries σ R) : S := theorem eval₂_coe (f : MvPolynomial σ R) : MvPowerSeries.eval₂ φ a f = MvPolynomial.eval₂ φ a f := by have : ∃ p : MvPolynomial σ R, (p : MvPowerSeries σ R) = f := ⟨f, rfl⟩ - rw [eval₂, dif_pos this] + rw [eval₂, dite_eq_left this] congr rw [← MvPolynomial.coe_inj, this.choose_spec] diff --git a/Mathlib/RingTheory/MvPowerSeries/Expand.lean b/Mathlib/RingTheory/MvPowerSeries/Expand.lean index 672cb6c8b550c3..aee2e3949dd73e 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Expand.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Expand.lean @@ -107,9 +107,9 @@ theorem coeff_expand_smul (φ : MvPowerSeries σ R) (m : σ →₀ ℕ) : have {d : σ →₀ ℕ} : (d.prod fun s e ↦ (X s (R := R) ^ p) ^ e) = monomial (p • d) 1 := by simp [monomial_smul_eq] rw [finsum_eq_single _ m] - · rw [this, coeff_monomial, if_pos rfl, mul_one] + · rw [this, coeff_monomial, ite_eq_left rfl, mul_one] · intro d hd - rw [this, coeff_monomial, if_neg _, mul_zero] + rw [this, coeff_monomial, ite_eq_right _, mul_zero] simp [nsmul_right_inj hp, hd.symm] @[simp] @@ -132,7 +132,7 @@ theorem coeff_expand_of_not_dvd (φ : MvPowerSeries σ R) {m : σ →₀ ℕ} {i rw [this, coeff_monomial] at hd have meq : m = p • d := by by_contra hc - rw [if_neg hc] at hd + rw [ite_eq_right hc] at hd contradiction simp [meq] @@ -201,8 +201,8 @@ theorem trunc'_expand [DecidableEq σ] {n : σ →₀ ℕ} (φ : MvPowerSeries · obtain ⟨m, hm⟩ : ∃ m, p • m = d := ⟨d.mapRange (fun a ↦ a / p) (by simp), by ext i; simp [(Nat.mul_div_cancel' (h i))]⟩ by_cases h_le : m ≤ n - · rw [← hm, coeff_trunc', if_pos (nsmul_le_nsmul_right h_le p), coeff_expand_smul, - MvPolynomial.coeff_expand_smul _ hp, coeff_trunc', if_pos h_le] + · rw [← hm, coeff_trunc', ite_eq_left (nsmul_le_nsmul_right h_le p), coeff_expand_smul, + MvPolynomial.coeff_expand_smul _ hp, coeff_trunc', ite_eq_left h_le] · have not_le : ¬ p • m ≤ p • n := by obtain ⟨i, hi⟩ : ∃ i, m i > n i := by by_contra! hc @@ -210,13 +210,13 @@ theorem trunc'_expand [DecidableEq σ] {n : σ →₀ ℕ} (φ : MvPowerSeries have : ¬ p • m i ≤ p • n i := by simp [Nat.mul_lt_mul_of_pos_left hi (p.ne_zero_iff_zero_lt.mp hp)] exact Not.intro fun a ↦ this (a i) - rw [coeff_trunc', ← hm, if_neg not_le, MvPolynomial.coeff_expand_smul _ hp, coeff_trunc', - if_neg h_le] + rw [coeff_trunc', ← hm, ite_eq_right not_le, MvPolynomial.coeff_expand_smul _ hp, + coeff_trunc', ite_eq_right h_le] · obtain ⟨i, hi⟩ := h rw [MvPolynomial.coeff_expand_of_not_dvd _ hi] by_cases hd : d ≤ p • n - · rw [coeff_trunc', if_pos hd, coeff_expand_of_not_dvd _ hp _ hi] - rw [coeff_trunc', if_neg hd] + · rw [coeff_trunc', ite_eq_left hd, coeff_expand_of_not_dvd _ hp _ hi] + rw [coeff_trunc', ite_eq_right hd] include hp in theorem trunc'_expand_trunc' {n m : σ →₀ ℕ} (h : n ≤ m) [DecidableEq σ] (f : MvPowerSeries σ R) : diff --git a/Mathlib/RingTheory/MvPowerSeries/Inverse.lean b/Mathlib/RingTheory/MvPowerSeries/Inverse.lean index ef53346a2f3738..26da5910cd4c3e 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Inverse.lean @@ -99,7 +99,7 @@ theorem coeff_invOfUnit [DecidableEq σ] (n : σ →₀ ℕ) (φ : MvPowerSeries theorem constantCoeff_invOfUnit (φ : MvPowerSeries σ R) (u : Rˣ) : constantCoeff (invOfUnit φ u) = ↑u⁻¹ := by classical - rw [← coeff_zero_eq_constantCoeff_apply, coeff_invOfUnit, if_pos rfl] + rw [← coeff_zero_eq_constantCoeff_apply, coeff_invOfUnit, ite_eq_left rfl] @[simp] theorem mul_invOfUnit (φ : MvPowerSeries σ R) (u : Rˣ) (h : constantCoeff φ = u) : @@ -112,16 +112,16 @@ theorem mul_invOfUnit (φ : MvPowerSeries σ R) (u : Rˣ) (h : constantCoeff φ else by classical have : ((0 : σ →₀ ℕ), n) ∈ antidiagonal n := by rw [mem_antidiagonal, zero_add] - rw [coeff_one, if_neg H, coeff_mul, ← Finset.insert_erase this, + rw [coeff_one, ite_eq_right H, coeff_mul, ← Finset.insert_erase this, Finset.sum_insert (Finset.notMem_erase _ _), coeff_zero_eq_constantCoeff_apply, h, - coeff_invOfUnit, if_neg H, neg_mul, mul_neg, Units.mul_inv_cancel_left, ← + coeff_invOfUnit, ite_eq_right H, neg_mul, mul_neg, Units.mul_inv_cancel_left, ← Finset.insert_erase this, Finset.sum_insert (Finset.notMem_erase _ _), - Finset.insert_erase this, if_neg (not_lt_of_ge <| le_rfl), zero_add, add_comm, ← + Finset.insert_erase this, ite_eq_right (not_lt_of_ge <| le_rfl), zero_add, add_comm, ← sub_eq_add_neg, sub_eq_zero, Finset.sum_congr rfl] rintro ⟨i, j⟩ hij rw [Finset.mem_erase, mem_antidiagonal] at hij obtain ⟨h₁, rfl⟩ := hij - rw [if_pos] + rw [ite_eq_left] refine lt_add_of_pos_left _ <| pos_iff_ne_zero.2 ?_ rintro rfl simp at h₁ @@ -206,7 +206,7 @@ theorem coeff_inv [DecidableEq σ] (n : σ →₀ ℕ) (φ : MvPowerSeries σ k) theorem constantCoeff_inv (φ : MvPowerSeries σ k) : constantCoeff φ⁻¹ = (constantCoeff φ)⁻¹ := by classical - rw [← coeff_zero_eq_constantCoeff_apply, coeff_inv, if_pos rfl] + rw [← coeff_zero_eq_constantCoeff_apply, coeff_inv, ite_eq_left rfl] theorem inv_eq_zero {φ : MvPowerSeries σ k} : φ⁻¹ = 0 ↔ constantCoeff φ = 0 := ⟨fun h => by simpa using congr_arg constantCoeff h, fun h => diff --git a/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean b/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean index c90e7635ac50ad..eba9b6cdfe0a5b 100644 --- a/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean +++ b/Mathlib/RingTheory/MvPowerSeries/LexOrder.lean @@ -47,7 +47,7 @@ theorem lexOrder_def_of_ne_zero {φ : MvPowerSeries σ R} (hφ : φ ≠ 0) : suffices ne : Set.Nonempty (toLex '' φ.support) by use ne unfold lexOrder - simp only [dif_neg hφ] + simp only [dite_eq_right hφ] exact (Function.support_nonempty_iff.mpr hφ).image _ @[simp] @@ -60,7 +60,7 @@ theorem lexOrder_eq_top_iff_eq_zero (φ : MvPowerSeries σ R) : @[simp] theorem lexOrder_zero : lexOrder (0 : MvPowerSeries σ R) = ⊤ := by unfold lexOrder - rw [dif_pos rfl] + rw [dite_eq_left rfl] theorem exists_finsupp_eq_lexOrder_of_ne_zero {φ : MvPowerSeries σ R} (hφ : φ ≠ 0) : ∃ (d : σ →₀ ℕ), lexOrder φ = toLex d := by diff --git a/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean b/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean index 2a578480230ac4..d102a54d2c48b5 100644 --- a/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean +++ b/Mathlib/RingTheory/MvPowerSeries/NoZeroDivisors.lean @@ -109,7 +109,7 @@ lemma monomial_mem_nonzeroDivisorsLeft {n : σ →₀ ℕ} {r} : · intro H p hrp ext i have := congr(coeff (i + n) $hrp) - rw [coeff_monomial_mul, if_pos le_add_self, add_tsub_cancel_right] at this + rw [coeff_monomial_mul, ite_eq_left le_add_self, add_tsub_cancel_right] at this simpa using H _ this -- TODO: reduce duplication @@ -122,7 +122,7 @@ lemma monomial_mem_nonzeroDivisorsRight {n : σ →₀ ℕ} {r} : · intro H p hrp ext i have := congr(coeff (i + n) $hrp) - rw [coeff_mul_monomial, if_pos le_add_self, add_tsub_cancel_right] at this + rw [coeff_mul_monomial, ite_eq_left le_add_self, add_tsub_cancel_right] at this simpa using H _ this lemma monomial_mem_nonzeroDivisors {n : σ →₀ ℕ} {r} : diff --git a/Mathlib/RingTheory/MvPowerSeries/Order.lean b/Mathlib/RingTheory/MvPowerSeries/Order.lean index 0097654ce0edb8..5590d111e9f051 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Order.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Order.lean @@ -143,7 +143,7 @@ def weightedOrder (f : MvPowerSeries σ R) : ℕ∞ := by Nat.find ((ne_zero_iff_exists_coeff_ne_zero_and_weight w).mp h) @[simp] theorem weightedOrder_zero : (0 : MvPowerSeries σ R).weightedOrder w = ⊤ := by - rw [weightedOrder, dif_pos rfl] + rw [weightedOrder, dite_eq_left rfl] theorem ne_zero_iff_weightedOrder_finite : f ≠ 0 ↔ (f.weightedOrder w).toNat = f.weightedOrder w := by @@ -162,7 +162,7 @@ theorem exists_coeff_ne_zero_and_weightedOrder (h : (toNat (f.weightedOrder w) : ℕ∞) = f.weightedOrder w) : ∃ d, coeff d f ≠ 0 ∧ weight w d = f.weightedOrder w := by classical - simp_rw [weightedOrder, dif_neg ((ne_zero_iff_weightedOrder_finite w).mpr h), Nat.cast_inj] + simp_rw [weightedOrder, dite_eq_right ((ne_zero_iff_weightedOrder_finite w).mpr h), Nat.cast_inj] generalize_proofs h1 exact Nat.find_spec h1 @@ -170,7 +170,7 @@ theorem exists_coeff_ne_zero_and_weightedOrder then the weighted order of the power series is less than or equal to `weight d w`. -/ theorem weightedOrder_le {d : σ →₀ ℕ} (h : coeff d f ≠ 0) : f.weightedOrder w ≤ weight w d := by - rw [weightedOrder, dif_neg] + rw [weightedOrder, dite_eq_right] · simp only [ne_eq, Nat.cast_le, Nat.find_le_iff] exact ⟨weight w d, le_rfl, d, h, rfl⟩ · exact (f.ne_zero_iff_exists_coeff_ne_zero_and_weight w).mpr ⟨weight w d, d, h, rfl⟩ @@ -227,7 +227,7 @@ theorem weightedOrder_monomial {d : σ →₀ ℕ} {a : R} [Decidable (a = 0)] : · use d simp only [coeff_monomial_same, ne_eq, h, not_false_eq_true, and_self] · intro b hb - rw [coeff_monomial, if_neg] + rw [coeff_monomial, ite_eq_right] rintro rfl exact hb.false @@ -235,7 +235,7 @@ theorem weightedOrder_monomial {d : σ →₀ ℕ} {a : R} [Decidable (a = 0)] : theorem weightedOrder_monomial_of_ne_zero {d : σ →₀ ℕ} {a : R} (h : a ≠ 0) : weightedOrder w (monomial d a) = weight w d := by classical - rw [weightedOrder_monomial, if_neg h] + rw [weightedOrder_monomial, ite_eq_right h] @[simp] theorem weightedOrder_one [Nontrivial R] : (1 : MvPowerSeries σ R).weightedOrder w = 0 := @@ -637,7 +637,7 @@ theorem isWeightedHomogeneous_weightedHomogeneousComponent (f : MvPowerSeries σ IsWeightedHomogeneous w (f.weightedHomogeneousComponent w p) p := fun {d} ↦ by rw [not_imp_comm] intro hd - rw [coeff_weightedHomogeneousComponent, if_neg hd] + rw [coeff_weightedHomogeneousComponent, ite_eq_right hd] variable {w} in theorem isWeightedHomogeneous_iff_eq_weightedHomogeneousComponent @@ -669,11 +669,11 @@ theorem weightedHomogeneousComponent_mul_of_le_weightedOrder {f g : MvPowerSerie rw [← hx, map_add] at hd simp only [coeff_weightedHomogeneousComponent] rcases trichotomy_of_add_eq_add hd with h | h | h - · rw [if_pos h.1, if_pos h.2] - · rw [if_neg (ne_of_lt h), zero_mul] + · rw [ite_eq_left h.1, ite_eq_left h.2] + · rw [ite_eq_right (ne_of_lt h), zero_mul] rw [← ENat.natCast_lt_natCast] at h rw [coeff_eq_zero_of_lt_weightedOrder w (lt_of_lt_of_le h hf), zero_mul] - · rw [if_neg (ne_of_lt h), mul_zero] + · rw [ite_eq_right (ne_of_lt h), mul_zero] rw [← ENat.natCast_lt_natCast] at h rw [coeff_eq_zero_of_lt_weightedOrder w (lt_of_lt_of_le h hg), mul_zero] · symm diff --git a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean index d9447d155470ef..48b4a7d9169283 100644 --- a/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean +++ b/Mathlib/RingTheory/MvPowerSeries/PiTopology.lean @@ -147,7 +147,7 @@ theorem tendsto_trunc_atTop [DecidableEq σ] [CommSemiring R] [Nonempty σ] (f : obtain ⟨s, _⟩ := (exists_const σ).mpr trivial apply tendsto_atTop_of_eventually_const (i₀ := d + Finsupp.single s 1) intro n hn - rw [MvPolynomial.coeff_coe, coeff_trunc, if_pos] + rw [MvPolynomial.coeff_coe, coeff_trunc, ite_eq_left] apply lt_of_lt_of_le _ hn simpa [Finsupp.lt_def] using ⟨s, by simp⟩ diff --git a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean index 8c166287fb5f29..9fe7b2c38a8895 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Substitution.lean @@ -745,7 +745,7 @@ theorem rescale_eq_subst (a : σ → R) (f : MvPowerSeries σ R) : rw [Finset.sum_eq_single n _ _] · simp [mul_comm, ← monomial_eq] · intro b hb hbn - rw [← monomial_eq, coeff_monomial, if_neg (Ne.symm hbn), mul_zero] + rw [← monomial_eq, coeff_monomial, ite_eq_right (Ne.symm hbn), mul_zero] · intro hn simpa using hn diff --git a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean index 983793e2b78bd6..08701bb5a6aefa 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Trunc.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Trunc.lean @@ -299,7 +299,7 @@ theorem ext_trunc' {f g : MvPowerSeries σ R} : f = g ↔ ∀ n, trunc' R n f = ext n specialize h n have {f' : MvPowerSeries σ R} : f'.coeff n = (trunc' R n f').coeff n := by - rw [coeff_trunc', if_pos le_rfl] + rw [coeff_trunc', ite_eq_left le_rfl] simp_rw [this, h] open Filter in @@ -309,7 +309,7 @@ theorem eq_iff_frequently_trunc'_eq {f g : MvPowerSeries σ R} : ext n obtain ⟨m, hm₁, hm₂⟩ := h.forall_exists_of_atTop n have {f' : MvPowerSeries σ R} : f'.coeff n = (trunc' R m f').coeff n := by - rw [coeff_trunc', if_pos hm₁] + rw [coeff_trunc', ite_eq_left hm₁] simp [this, hm₂] end @@ -334,8 +334,8 @@ theorem coeff_truncTotal_eq_zero (h : n ≤ degree x) : theorem coeff_truncTotal_eq_ite : (truncTotal n p).coeff x = if x.degree < n then p.coeff x else 0 := by by_cases h : x.degree < n - · rw [if_pos h, coeff_truncTotal _ h] - · rw [if_neg h, coeff_truncTotal_eq_zero _ (not_lt.mp h)] + · rw [ite_eq_left h, coeff_truncTotal _ h] + · rw [ite_eq_right h, coeff_truncTotal_eq_zero _ (not_lt.mp h)] theorem constantCoeff_truncTotal_eq_ite : (truncTotal n p).constantCoeff = if 0 < n then p.constantCoeff else 0 := by diff --git a/Mathlib/RingTheory/Nilpotent/Basic.lean b/Mathlib/RingTheory/Nilpotent/Basic.lean index 873ee88550945c..92012a8182419c 100644 --- a/Mathlib/RingTheory/Nilpotent/Basic.lean +++ b/Mathlib/RingTheory/Nilpotent/Basic.lean @@ -181,9 +181,9 @@ theorem isNilpotent_finsum {ι : Type*} {f : ι → R} IsNilpotent (finsum f) := by classical by_cases h : HasFiniteSupport f - · rw [finsum_def, dif_pos h] + · rw [finsum_def, dite_eq_left h] exact Commute.isNilpotent_sum (fun b _ ↦ hf b) (fun _ _ _ _ ↦ h_comm _ _) - · simp only [finsum_def, dif_neg h, IsNilpotent.zero] + · simp only [finsum_def, dite_eq_right h, IsNilpotent.zero] protected lemma isNilpotent_mul_right_iff (h_comm : Commute x y) (hy : y ∈ nonZeroDivisorsRight R) : IsNilpotent (x * y) ↔ IsNilpotent x := by diff --git a/Mathlib/RingTheory/NoetherNormalization.lean b/Mathlib/RingTheory/NoetherNormalization.lean index c2d6983b2ef217..47d9211ea6ac10 100644 --- a/Mathlib/RingTheory/NoetherNormalization.lean +++ b/Mathlib/RingTheory/NoetherNormalization.lean @@ -100,8 +100,9 @@ private lemma degreeOf_zero_t {a : k} (ha : a ≠ 0) : ((T f) (monomial v a)).de ∑ i : Fin (n + 1), (r i) * v i := by rw [← natDegree_finSuccEquiv, monomial_eq, Finsupp.prod_pow v fun a ↦ X a] simp only [Fin.prod_univ_succ, Fin.sum_univ_succ, map_mul, map_prod, map_pow, - AlgEquiv.ofAlgHom_apply, MvPolynomial.aeval_C, MvPolynomial.aeval_X, if_pos, Fin.succ_ne_zero, - ite_false, one_smul, map_add, finSuccEquiv_X_zero, finSuccEquiv_X_succ, algebraMap_eq] + AlgEquiv.ofAlgHom_apply, MvPolynomial.aeval_C, MvPolynomial.aeval_X, ite_eq_left, + Fin.succ_ne_zero, ite_false, one_smul, map_add, finSuccEquiv_X_zero, finSuccEquiv_X_succ, + algebraMap_eq] have h (i : Fin n) : (Polynomial.C (X (R := k) i) + Polynomial.X ^ r i.succ) ^ v i.succ ≠ 0 := pow_ne_zero (v i.succ) (leadingCoeff_ne_zero.mp <| by simp [add_comm, leadingCoeff_X_pow_add_C]) @@ -133,7 +134,7 @@ private lemma leadingCoeff_finSuccEquiv_t : have : ∀ j, ((finSuccEquiv k n) ((T1 f) 1 (X j))).leadingCoeff = 1 := fun j ↦ by by_cases h : j = 0 · simp [h, finSuccEquiv_apply] - · simp only [aeval_eq_bind₁, bind₁_X_right, if_neg h, one_smul, map_add, map_pow] + · simp only [aeval_eq_bind₁, bind₁_X_right, ite_eq_right h, one_smul, map_add, map_pow] obtain ⟨i, rfl⟩ := Fin.exists_succ_eq.mpr h simp [finSuccEquiv_X_succ, finSuccEquiv_X_zero, add_comm] simp only [this, one_pow, Finset.prod_const_one, mul_one] diff --git a/Mathlib/RingTheory/Norm/Transitivity.lean b/Mathlib/RingTheory/Norm/Transitivity.lean index 88c2e96d9e241d..ffebc5636c344d 100644 --- a/Mathlib/RingTheory/Norm/Transitivity.lean +++ b/Mathlib/RingTheory/Norm/Transitivity.lean @@ -50,17 +50,18 @@ def auxMat : Matrix m m S := lemma auxMat_blockTriangular : (auxMat M k).BlockTriangular (· ≠ k) := fun i j lt ↦ by simp_rw [lt_iff_not_ge, le_Prop_eq, Classical.not_imp, not_not] at lt - rw [auxMat, of_apply, if_pos lt.2, if_neg lt.1] + rw [auxMat, of_apply, ite_eq_left lt.2, ite_eq_right lt.1] lemma auxMat_toSquareBlock_ne : (auxMat M k).toSquareBlock (· ≠ k) True = M k k • 1 := by ext i j - simp [auxMat, toSquareBlock_def, if_neg (of_eq_true i.2), if_neg (of_eq_true j.2), + simp [auxMat, toSquareBlock_def, ite_eq_right (of_eq_true i.2), ite_eq_right (of_eq_true j.2), Matrix.one_apply, Subtype.ext_iff] lemma auxMat_toSquareBlock_eq : (auxMat M k).toSquareBlock (· ≠ k) False = 1 := by ext ⟨i, hi⟩ ⟨j, hj⟩ rw [eq_iff_iff, iff_false, not_not] at hi hj - simp [auxMat, toSquareBlock_def, if_pos hi, if_pos hj, Matrix.one_apply, if_pos (hj ▸ hi)] + simp [auxMat, toSquareBlock_def, ite_eq_left hi, ite_eq_left hj, Matrix.one_apply, + ite_eq_left (hj ▸ hi)] variable [Fintype m] @@ -68,9 +69,9 @@ variable [Fintype m] lemma mul_auxMat_blockTriangular : (M * auxMat M k).BlockTriangular (· = k) := fun i j lt ↦ by simp_rw [lt_iff_not_ge, le_Prop_eq, Classical.not_imp] at lt - simp_rw [Matrix.mul_apply, auxMat, of_apply, if_neg lt.2, mul_ite, mul_neg, mul_zero] - rw [Finset.sum_ite, Finset.filter_eq', if_pos (Finset.mem_univ _), Finset.sum_singleton, - Finset.sum_ite_eq', if_pos, lt.1, mul_comm, neg_add_cancel] + simp_rw [Matrix.mul_apply, auxMat, of_apply, ite_eq_right lt.2, mul_ite, mul_neg, mul_zero] + rw [Finset.sum_ite, Finset.filter_eq', ite_eq_left (Finset.mem_univ _), Finset.sum_singleton, + Finset.sum_ite_eq', ite_eq_left, lt.1, mul_comm, neg_add_cancel] exact Finset.mem_filter.mpr ⟨Finset.mem_univ _, lt.2⟩ /-- The lower-right corner of `M * aux M k` is the same as the corner of `M`. -/ diff --git a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean index a5805af5c8630d..6b79d08d5d6c88 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Basic.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Basic.lean @@ -270,7 +270,7 @@ of `Ring.ord R x` into `WithZero (Multiplicative ℤ)`. -/ theorem ordMonoidWithZeroHom_eq_ord [Nontrivial R] {x : R} (h : x ∈ nonZeroDivisors R) : ordMonoidWithZeroHom R x = - (ENat.recTopCoe 0 (WithZero.coe <| Multiplicative.ofAdd ·) (Ring.ord R x)) := dif_pos h + (ENat.recTopCoe 0 (WithZero.coe <| Multiplicative.ofAdd ·) (Ring.ord R x)) := dite_eq_left h lemma ordMonoidWithZeroHom_eq_coe [Nontrivial R] {x : R} (hx : x ∈ nonZeroDivisors R) {n : ℕ} (hn : Ring.ord R x = n) : @@ -283,7 +283,7 @@ If `x` is not a non zero divisor, `ordMonoidWithZeroHom` is equal to `0`. -/ @[simp] theorem ordMonoidWithZeroHom_eq_zero [Nontrivial R] {x : R} (h : x ∉ nonZeroDivisors R) : - ordMonoidWithZeroHom R x = 0 := dif_neg h + ordMonoidWithZeroHom R x = 0 := dite_eq_right h /-- The quotient of a Noetherian ring of krull dimension less than or equal to `1` by a principal ideal diff --git a/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean b/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean index 90d0018f86091d..8d0f7de5004b39 100644 --- a/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean +++ b/Mathlib/RingTheory/OreLocalization/NonZeroDivisors.lean @@ -58,7 +58,7 @@ protected noncomputable def inv : R[R⁰⁻¹] → R[R⁰⁻¹] := · exfalso apply nonZeroDivisors.coe_ne_zero ⟨_, hst⟩ simp [ht] - · simp only [hr, ht, dif_neg, not_false_iff, or_self_iff, mul_eq_zero, smul_eq_mul] + · simp only [hr, ht, dite_eq_right, not_false_iff, or_self_iff, mul_eq_zero, smul_eq_mul] apply OreLocalization.expand) noncomputable instance inv' : Inv R[R⁰⁻¹] := diff --git a/Mathlib/RingTheory/Perfection.lean b/Mathlib/RingTheory/Perfection.lean index 91e6fa8901bfd9..27cbc97a3f6075 100644 --- a/Mathlib/RingTheory/Perfection.lean +++ b/Mathlib/RingTheory/Perfection.lean @@ -551,7 +551,7 @@ variable {K v O p} @[simp] theorem preVal_zero : preVal K v O p 0 = 0 := - if_pos rfl + ite_eq_left rfl include hv @@ -559,7 +559,7 @@ theorem preVal_mk {x : O} (hx : (Ideal.Quotient.mk _ x : ModP O p) ≠ 0) : preVal K v O p (Ideal.Quotient.mk _ x) = v (algebraMap O K x) := by obtain ⟨r, hr⟩ : ∃ (a : O), a * (p : O) = (Ideal.Quotient.mk _ x).out - x := Ideal.mem_span_singleton'.1 <| Ideal.Quotient.eq.1 <| Quotient.sound' <| Quotient.mk_out' _ - refine (if_neg hx).trans (v.map_eq_of_sub_lt <| lt_of_not_ge ?_) + refine (ite_eq_right hx).trans (v.map_eq_of_sub_lt <| lt_of_not_ge ?_) rw [← map_sub, ← hr, hv.le_iff_dvd] exact fun hprx => hx (Ideal.Quotient.eq_zero_iff_mem.2 <| Ideal.mem_span_singleton.2 <| dvd_of_mul_left_dvd hprx) @@ -714,14 +714,14 @@ theorem coeff_nat_find_add_ne_zero {f : PreTilt O p} {h : ∃ n, coeff n f ≠ 0 @[simp] theorem valAux_zero : valAux K v O p 0 = 0 := - dif_neg fun ⟨_, hn⟩ => hn rfl + dite_eq_right fun ⟨_, hn⟩ => hn rfl include hv theorem valAux_eq {f : PreTilt O p} {n : ℕ} (hfn : coeff n f ≠ 0) : valAux K v O p f = ModP.preVal K v O p (coeff n f) ^ p ^ n := by have h : ∃ n, coeff n f ≠ 0 := ⟨n, hfn⟩ - rw [valAux, dif_pos h] + rw [valAux, dite_eq_left h] classical obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le (Nat.find_min' h hfn) induction k with diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index 34316182227831..cb038d3f7f0561 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -228,11 +228,11 @@ theorem geom_sum_X_comp_X_add_one_eq_sum (n : ℕ) : ext i trans (n.choose (i + 1) : R); swap · simp only [finsetSum_coeff, ← C_eq_natCast, coeff_C_mul_X_pow] - rw [Finset.sum_eq_single i, if_pos rfl] - · simp +contextual only [@eq_comm _ i, if_false, + rw [Finset.sum_eq_single i, ite_eq_left rfl] + · simp +contextual only [@eq_comm _ i, ite_false, imp_true_iff] · simp +contextual only [Nat.lt_add_one_iff, Nat.choose_eq_zero_of_lt, - Nat.cast_zero, Finset.mem_range, not_lt, if_true, imp_true_iff] + Nat.cast_zero, Finset.mem_range, not_lt, ite_true, imp_true_iff] induction n generalizing i with | zero => dsimp; simp only [zero_comp, coeff_zero, Nat.cast_zero] | succ n ih => diff --git a/Mathlib/RingTheory/Polynomial/Content.lean b/Mathlib/RingTheory/Polynomial/Content.lean index 2c8933de7c5e76..8b317f3e1371b3 100644 --- a/Mathlib/RingTheory/Polynomial/Content.lean +++ b/Mathlib/RingTheory/Polynomial/Content.lean @@ -197,7 +197,7 @@ theorem content_eq_gcd_leadingCoeff_content_eraseLead (p : R[X]) : eraseLead_support] refine congr rfl (Finset.gcd_congr rfl fun i hi => ?_) rw [Finset.mem_erase] at hi - rw [eraseLead_coeff, if_neg hi.1] + rw [eraseLead_coeff, ite_eq_right hi.1] theorem dvd_content_iff_C_dvd {p : R[X]} {r : R} : r ∣ p.content ↔ C r ∣ p := by rw [C_dvd_iff_dvd_coeff] @@ -230,11 +230,11 @@ noncomputable def primPart (p : R[X]) : R[X] := theorem eq_C_content_mul_primPart (p : R[X]) : p = C p.content * p.primPart := by by_cases h : p = 0; · simp [h] - rw [primPart, if_neg h, ← Classical.choose_spec (C_content_dvd p)] + rw [primPart, ite_eq_right h, ← Classical.choose_spec (C_content_dvd p)] @[simp] theorem primPart_zero : primPart (0 : R[X]) = 1 := - if_pos rfl + ite_eq_left rfl theorem isPrimitive_primPart (p : R[X]) : p.primPart.IsPrimitive := by by_cases h : p = 0; · simp [h] diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean index 91c2afa5a82764..5f853660d247b9 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Basic.lean @@ -233,7 +233,7 @@ def cyclotomic (n : ℕ) (R : Type*) [Ring R] : R[X] := theorem int_cyclotomic_rw {n : ℕ} (h : n ≠ 0) : cyclotomic n ℤ = (int_coeff_of_cyclotomic' (Complex.isPrimitiveRoot_exp n h)).choose := by - simp only [cyclotomic, h, dif_neg, not_false_iff] + simp only [cyclotomic, h, dite_eq_right, not_false_iff] ext i simp only [coeff_map, Int.cast_id, eq_intCast] @@ -241,14 +241,14 @@ theorem int_cyclotomic_rw {n : ℕ} (h : n ≠ 0) : theorem map_cyclotomic_int (n : ℕ) (R : Type*) [Ring R] : map (Int.castRingHom R) (cyclotomic n ℤ) = cyclotomic n R := by by_cases hzero : n = 0 - · simp only [hzero, cyclotomic, dif_pos, Polynomial.map_one] + · simp only [hzero, cyclotomic, dite_eq_left, Polynomial.map_one] simp [cyclotomic, hzero] theorem int_cyclotomic_spec (n : ℕ) : map (Int.castRingHom ℂ) (cyclotomic n ℤ) = cyclotomic' n ℂ ∧ (cyclotomic n ℤ).degree = (cyclotomic' n ℂ).degree ∧ (cyclotomic n ℤ).Monic := by by_cases hzero : n = 0 - · simp only [hzero, cyclotomic, degree_one, monic_one, cyclotomic'_zero, dif_pos, + · simp only [hzero, cyclotomic, degree_one, monic_one, cyclotomic'_zero, dite_eq_left, Polynomial.map_one, and_self_iff] rw [int_cyclotomic_rw hzero] exact (int_coeff_of_cyclotomic' (Complex.isPrimitiveRoot_exp n hzero)).choose_spec @@ -277,7 +277,7 @@ theorem cyclotomic.eval_apply {R S : Type*} (q : R) (n : ℕ) [Ring R] [Ring S] /-- The zeroth cyclotomic polynomial is `1`. -/ @[simp] theorem cyclotomic_zero (R : Type*) [Ring R] : cyclotomic 0 R = 1 := by - simp only [cyclotomic, dif_pos] + simp only [cyclotomic, dite_eq_left] /-- The first cyclotomic polynomial is `X - 1`. -/ @[simp] @@ -307,7 +307,7 @@ theorem degree_cyclotomic (n : ℕ) (R : Type*) [Ring R] [Nontrivial R] : rw [← map_cyclotomic_int] rw [degree_map_eq_of_leadingCoeff_ne_zero (Int.castRingHom R) _] · rcases n with - | k - · simp only [cyclotomic, degree_one, dif_pos, Nat.totient_zero, CharP.cast_eq_zero] + · simp only [cyclotomic, degree_one, dite_eq_left, Nat.totient_zero, CharP.cast_eq_zero] rw [← degree_cyclotomic' (Complex.isPrimitiveRoot_exp k.succ (Nat.succ_ne_zero k))] exact (int_cyclotomic_spec k.succ).2.1 simp only [(int_cyclotomic_spec n).right.right, eq_intCast, Monic.leadingCoeff, Int.cast_one, diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/Criterion.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/Criterion.lean index a59d1730a5c866..7d2248155b1191 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/Criterion.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/Criterion.lean @@ -107,7 +107,7 @@ private lemma generalizedEisenstein_aux {q f g : R[X]} {p : ℕ} rwa [leadingCoeff_C] at hgP by_contra hg' apply hgP - rw [hg, leadingCoeff, coeff_add, ← hg, coeff_C, if_neg hg', zero_add, + rw [hg, leadingCoeff, coeff_add, ← hg, coeff_C, ite_eq_right hg', zero_add, mem_ker, ← coeff_map, hr, coeff_zero] /-- A generalized Eisenstein criterion diff --git a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean index 19a2573fd2b801..14a6dbdacaa92e 100644 --- a/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean @@ -63,7 +63,7 @@ theorem cyclotomic_comp_X_add_one_isEisensteinAt [hp : Fact p.Prime] : rw [lcoeff_apply, ← C_eq_natCast, C_mul_X_pow_eq_monomial, coeff_monomial] rw [natDegree_comp, show (X + 1 : ℤ[X]) = X + C 1 by simp, natDegree_X_add_C, mul_one, natDegree_cyclotomic, Nat.totient_prime hp.out] at hi - simp only [hi.trans_le (Nat.sub_le _ _), sum_ite_eq', mem_range, if_true, + simp only [hi.trans_le (Nat.sub_le _ _), sum_ite_eq', mem_range, ite_true, Ideal.submodule_span_eq, Ideal.mem_span_singleton, Int.natCast_dvd_natCast] exact hp.out.dvd_choose_self i.succ_ne_zero (lt_tsub_iff_right.1 hi) · rw [coeff_zero_eq_eval_zero, eval_comp, cyclotomic_prime, eval_add, eval_X, eval_one, zero_add, diff --git a/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean b/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean index 5229e7c85a895d..bbfce1696d9458 100644 --- a/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean +++ b/Mathlib/RingTheory/Polynomial/IntegralNormalization.lean @@ -63,7 +63,7 @@ theorem support_integralNormalization_subset : simp +contextual [sum_def, integralNormalization, coeff_monomial, mem_support_iff] theorem integralNormalization_coeff_degree {i : ℕ} (hi : p.degree = i) : - (integralNormalization p).coeff i = 1 := by rw [integralNormalization_coeff, if_pos hi] + (integralNormalization p).coeff i = 1 := by rw [integralNormalization_coeff, ite_eq_left hi] theorem integralNormalization_coeff_natDegree (hp : p ≠ 0) : (integralNormalization p).coeff (natDegree p) = 1 := @@ -71,7 +71,7 @@ theorem integralNormalization_coeff_natDegree (hp : p ≠ 0) : theorem integralNormalization_coeff_degree_ne {i : ℕ} (hi : p.degree ≠ i) : coeff (integralNormalization p) i = coeff p i * p.leadingCoeff ^ (p.natDegree - 1 - i) := by - rw [integralNormalization_coeff, if_neg hi] + rw [integralNormalization_coeff, ite_eq_right hi] theorem integralNormalization_coeff_ne_natDegree {i : ℕ} (hi : i ≠ natDegree p) : coeff (integralNormalization p) i = coeff p i * p.leadingCoeff ^ (p.natDegree - 1 - i) := diff --git a/Mathlib/RingTheory/Polynomial/Pochhammer.lean b/Mathlib/RingTheory/Polynomial/Pochhammer.lean index ae098f694678e6..481a161835e3d3 100644 --- a/Mathlib/RingTheory/Polynomial/Pochhammer.lean +++ b/Mathlib/RingTheory/Polynomial/Pochhammer.lean @@ -223,7 +223,7 @@ theorem ascPochhammer_nat_eval_succ (r : ℕ) : | 0 => by by_cases h : r = 0 · simp only [h, zero_mul, zero_add] - · simp only [ascPochhammer_eval_zero, zero_mul, if_neg h, mul_zero] + · simp only [ascPochhammer_eval_zero, zero_mul, ite_eq_right h, mul_zero] | k + 1 => by simp only [ascPochhammer_nat_eq_ascFactorial, Nat.succ_ascFactorial, add_right_comm] theorem ascPochhammer_eval_succ (r n : ℕ) : diff --git a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean index a6256ae672e187..a49308f1730e78 100644 --- a/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Resultant/Basic.lean @@ -95,7 +95,7 @@ lemma sylvesterDeriv_updateRow (f : R[X]) (hf : 0 < f.natDegree) : by_cases hn : f.natDegree = 0 · ext ⟨i, hi⟩; lia ext ⟨i, hi⟩ ⟨j, hj⟩ - rw [sylvesterDeriv, dif_neg hn] + rw [sylvesterDeriv, dite_eq_right hn] rcases ne_or_eq i (2 * f.natDegree - 2) with hi' | rfl · -- Top part of matrix rw [Matrix.updateRow_ne (Fin.ne_of_val_ne hi'), @@ -224,7 +224,7 @@ private lemma resultant_add_mul_monomial_right (hk : k + m ≤ n) (hf : f.natDeg have : Fin.mk (n := m + n) (m + ↑i + (k + m)) (by lia) = Fin.natAdd m ⟨↑i + (k + m), by lia⟩ := Fin.ext (by simp; lia) simp only [Fin.addCases_right, Fin.val_natAdd, sub_eq_self, this] - rw [if_neg, mul_zero] + rw [ite_eq_right, mul_zero] lia lia rw [resultant, resultant, ← this m le_rfl] @@ -306,7 +306,7 @@ lemma resultant_succ_left_deg (hf : f.natDegree ≤ m) : · congr 1; lia · simp [pow_add] · simp only [sylvester, Set.mem_Icc, Matrix.of_apply, Fin.val_last, Fin.addCases_left] - rw [if_pos (by lia)] + rw [ite_eq_left (by lia)] simp [add_assoc, add_comm 1] · ext i j simp only [sylvester, Set.mem_Icc, Matrix.submatrix_apply, Function.comp_apply, diff --git a/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean b/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean index 3f980764122c22..f25d655f9c5fe0 100644 --- a/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean +++ b/Mathlib/RingTheory/Polynomial/UniqueFactorization.lean @@ -44,7 +44,7 @@ instance (priority := 100) wfDvdMonoid : WfDvdMonoid R[X] where DvdNotUnit →r Prod.Lex (· < ·) DvdNotUnit) (wellFounded_lt.prod_lex ‹WfDvdMonoid R›.wf) rintro a b ⟨ane0, ⟨c, ⟨not_unit_c, rfl⟩⟩⟩ - rw [Polynomial.degree_mul, if_neg ane0] + rw [Polynomial.degree_mul, ite_eq_right ane0] split_ifs with hac · rw [hac, Polynomial.leadingCoeff_zero] apply Prod.Lex.left diff --git a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean index a2effb36e2d148..b7e440521daf70 100644 --- a/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean +++ b/Mathlib/RingTheory/Polynomial/UniversalFactorizationRing.lean @@ -55,7 +55,7 @@ lemma coeff_freeMonic : by_cases h : k < n · simp +contextual [Finset.sum_eq_single (ι := Fin n) (a := ⟨k, h⟩), Fin.ext_iff, @eq_comm _ k, h, h.ne'] - · rw [Finset.sum_eq_zero fun x _ ↦ if_neg (by cases x; lia), add_zero, dif_neg h] + · rw [Finset.sum_eq_zero fun x _ ↦ ite_eq_right (by cases x; lia), add_zero, dite_eq_right h] lemma degree_freeMonic [Nontrivial R] : (freeMonic R n).degree = n := Polynomial.degree_eq_of_le_of_coeff_ne_zero ((Polynomial.degree_le_iff_coeff_zero _ _).mpr @@ -257,11 +257,11 @@ lemma pderiv_inl_universalFactorizationMap_X (i j) : apply_dite, apply_ite, ← Algebra.TensorProduct.one_def, Pi.single_apply, Fin.ext_iff, ← ite_and] · obtain h | h := lt_or_ge j.1 i.1 - · rw [Finset.sum_eq_zero, if_pos h] + · rw [Finset.sum_eq_zero, ite_eq_left h] simp only [Finset.mem_antidiagonal, Prod.forall] intro a b hab simp [show a ≠ i by lia] - rw [Finset.sum_eq_single ⟨i.1, j.1 - i.1⟩, if_neg h.not_gt] + rw [Finset.sum_eq_single ⟨i.1, j.1 - i.1⟩, ite_eq_right h.not_gt] · simp · simp only [Finset.mem_antidiagonal, ne_eq, Prod.forall, Prod.mk.injEq, not_and] intro a b e h @@ -280,10 +280,10 @@ lemma pderiv_inr_universalFactorizationMap_X (i j) : apply_dite, apply_ite, ← Algebra.TensorProduct.one_def, Pi.single_apply, Fin.ext_iff, ← ite_and] · obtain h | h := lt_or_ge j.1 i.1 - · rw [Finset.sum_eq_zero, if_pos h] + · rw [Finset.sum_eq_zero, ite_eq_left h] simp only [Finset.mem_antidiagonal] lia - rw [Finset.sum_eq_single ⟨j.1 - i.1, i.1⟩, if_neg h.not_gt] + rw [Finset.sum_eq_single ⟨j.1 - i.1, i.1⟩, ite_eq_right h.not_gt] · simp · simp only [Finset.mem_antidiagonal, ne_eq, ite_eq_right_iff, Prod.forall, Prod.mk.injEq] intro a b _ _ _ diff --git a/Mathlib/RingTheory/PowerBasis.lean b/Mathlib/RingTheory/PowerBasis.lean index ace47e3cfb5846..8dff9019a4f150 100644 --- a/Mathlib/RingTheory/PowerBasis.lean +++ b/Mathlib/RingTheory/PowerBasis.lean @@ -234,10 +234,11 @@ protected theorem leftMulMatrix (pb : PowerBasis A S) : Algebra.leftMulMatrix pb convert! pb.aeval_minpolyGen rw [add_comm, aeval_eq_sum_range, Finset.sum_range_succ, ← leadingCoeff, pb.minpolyGen_monic.leadingCoeff, one_smul, natDegree_minpolyGen, Finset.sum_range] - · rw [Fintype.sum_eq_single (⟨(k : ℕ) + 1, lt_of_le_of_ne k.2 h⟩ : Fin pb.dim), if_pos, one_smul] + · rw [Fintype.sum_eq_single (⟨(k : ℕ) + 1, lt_of_le_of_ne k.2 h⟩ : Fin pb.dim), ite_eq_left, + one_smul] · rfl intro x hx - rw [if_neg, zero_smul] + rw [ite_eq_right, zero_smul] apply mt Fin.ext hx end minpoly @@ -423,7 +424,7 @@ theorem linearIndependent_pow [Algebra K S] (x : S) : exact (degree_eq_natDegree <| minpoly.ne_zero h).symm ▸ degree_sum_fin_lt _ · apply_fun lcoeff K i at h0 simp_rw [map_sum, lcoeff_apply, coeff_monomial, Fin.val_eq_val, Finset.sum_ite_eq'] at h0 - exact (if_pos <| Finset.mem_univ _).symm.trans h0 + exact (ite_eq_left <| Finset.mem_univ _).symm.trans h0 theorem IsIntegral.mem_span_pow [Nontrivial R] {x y : S} (hx : IsIntegral R x) (hy : ∃ f : R[X], y = aeval x f) : diff --git a/Mathlib/RingTheory/PowerSeries/Basic.lean b/Mathlib/RingTheory/PowerSeries/Basic.lean index 6363eb10d7665b..9eab0a6bb30beb 100644 --- a/Mathlib/RingTheory/PowerSeries/Basic.lean +++ b/Mathlib/RingTheory/PowerSeries/Basic.lean @@ -193,10 +193,10 @@ theorem coeff_C (n : ℕ) (a : R) : coeff n (C a : R⟦X⟧) = if n = 0 then a e @[simp] theorem coeff_zero_C (a : R) : coeff 0 (C a) = a := by - rw [coeff_C, if_pos rfl] + rw [coeff_C, ite_eq_left rfl] theorem coeff_C_of_ne_zero {a : R} {n : ℕ} (h : n ≠ 0) : coeff n (C a) = 0 := by - rw [coeff_C, if_neg h] + rw [coeff_C, ite_eq_right h] @[deprecated (since := "2026-05-20")] alias coeff_ne_zero_C := coeff_C_of_ne_zero @@ -223,7 +223,7 @@ theorem coeff_zero_X : coeff 0 (X : R⟦X⟧) = 0 := by rw [coeff, Finsupp.single_zero, X, MvPowerSeries.coeff_zero_X] @[simp] -theorem coeff_one_X : coeff 1 (X : R⟦X⟧) = 1 := by rw [coeff_X, if_pos rfl] +theorem coeff_one_X : coeff 1 (X : R⟦X⟧) = 1 := by rw [coeff_X, ite_eq_left rfl] @[simp] theorem X_ne_zero [Nontrivial R] : (X : R⟦X⟧) ≠ 0 := fun H => by @@ -350,9 +350,9 @@ theorem coeff_C_mul_X_pow (x : R) (k n : ℕ) : @[simp] theorem coeff_mul_X_pow (p : R⟦X⟧) (n d : ℕ) : coeff (d + n) (p * X ^ n) = coeff d p := by - rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one] + rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, ite_eq_left rfl, mul_one] · rintro ⟨i, j⟩ h1 h2 - rw [coeff_X_pow, if_neg, mul_zero] + rw [coeff_X_pow, ite_eq_right, mul_zero] rintro rfl apply h2 rw [mem_antidiagonal, add_right_cancel_iff] at h1 @@ -363,9 +363,9 @@ theorem coeff_mul_X_pow (p : R⟦X⟧) (n d : ℕ) : @[simp] theorem coeff_X_pow_mul (p : R⟦X⟧) (n d : ℕ) : coeff (d + n) (X ^ n * p) = coeff d p := by - rw [coeff_mul, Finset.sum_eq_single (n, d), coeff_X_pow, if_pos rfl, one_mul] + rw [coeff_mul, Finset.sum_eq_single (n, d), coeff_X_pow, ite_eq_left rfl, one_mul] · rintro ⟨i, j⟩ h1 h2 - rw [coeff_X_pow, if_neg, zero_mul] + rw [coeff_X_pow, ite_eq_right, zero_mul] rintro rfl apply h2 rw [mem_antidiagonal, add_comm, add_right_cancel_iff] at h1 @@ -405,7 +405,7 @@ theorem coeff_mul_X_pow' (p : R⟦X⟧) (n d : ℕ) : split_ifs with h · rw [← tsub_add_cancel_of_le h, coeff_mul_X_pow, add_tsub_cancel_right] · refine (coeff_mul _ _ _).trans (Finset.sum_eq_zero fun x hx => ?_) - rw [coeff_X_pow, if_neg, mul_zero] + rw [coeff_X_pow, ite_eq_right, mul_zero] exact ((le_of_add_le_right (mem_antidiagonal.mp hx).le).trans_lt <| not_le.mp h).ne theorem coeff_X_pow_mul' (p : R⟦X⟧) (n d : ℕ) : @@ -414,7 +414,7 @@ theorem coeff_X_pow_mul' (p : R⟦X⟧) (n d : ℕ) : · rw [← tsub_add_cancel_of_le h, coeff_X_pow_mul] simp · refine (coeff_mul _ _ _).trans (Finset.sum_eq_zero fun x hx => ?_) - rw [coeff_X_pow, if_neg, zero_mul] + rw [coeff_X_pow, ite_eq_right, zero_mul] have := mem_antidiagonal.mp hx rw [add_comm] at this exact ((le_of_add_le_right this.le).trans_lt <| not_le.mp h).ne @@ -431,7 +431,7 @@ theorem eq_shift_mul_X_add_const (φ : R⟦X⟧) : ext (_ | n) · simp · simp only [coeff_succ_mul_X, coeff_mk, map_add, coeff_C, n.succ_ne_zero, - if_false, add_zero] + ite_false, add_zero] /-- Split off the constant coefficient. -/ theorem eq_X_mul_shift_add_const (φ : R⟦X⟧) : @@ -439,7 +439,7 @@ theorem eq_X_mul_shift_add_const (φ : R⟦X⟧) : ext (_ | n) · simp · simp only [coeff_succ_X_mul, coeff_mk, map_add, coeff_C, n.succ_ne_zero, - if_false, add_zero] + ite_false, add_zero] section Map diff --git a/Mathlib/RingTheory/PowerSeries/Catalan.lean b/Mathlib/RingTheory/PowerSeries/Catalan.lean index d91ced971ba6e9..1a792b575efdae 100644 --- a/Mathlib/RingTheory/PowerSeries/Catalan.lean +++ b/Mathlib/RingTheory/PowerSeries/Catalan.lean @@ -49,7 +49,7 @@ theorem catalanSeries_sq_mul_X_add_one : catalanSeries ^ 2 * X + 1 = catalanSeri cases n with | zero => simp | succ n => - simp_rw [add_comm, map_add, coeff_one, if_neg n.succ_ne_zero, zero_add, coeff_succ_mul_X, sq, - coeff_mul, catalanSeries_coeff, catalan_succ'] + simp_rw [add_comm, map_add, coeff_one, ite_eq_right n.succ_ne_zero, zero_add, coeff_succ_mul_X, + sq, coeff_mul, catalanSeries_coeff, catalan_succ'] end PowerSeries diff --git a/Mathlib/RingTheory/PowerSeries/Derivative.lean b/Mathlib/RingTheory/PowerSeries/Derivative.lean index 8ba5d9e04603c4..3b3492da76d4d6 100644 --- a/Mathlib/RingTheory/PowerSeries/Derivative.lean +++ b/Mathlib/RingTheory/PowerSeries/Derivative.lean @@ -93,9 +93,9 @@ theorem trunc_derivative (f : R⟦X⟧) (n : ℕ) : rw [coeff_trunc] split_ifs with h · have : d + 1 < n + 1 := succ_lt_succ_iff.2 h - rw [coeff_derivative, Polynomial.coeff_derivative, coeff_trunc, if_pos this] + rw [coeff_derivative, Polynomial.coeff_derivative, coeff_trunc, ite_eq_left this] · have : ¬d + 1 < n + 1 := by rwa [succ_lt_succ_iff] - rw [Polynomial.coeff_derivative, coeff_trunc, if_neg this, zero_mul] + rw [Polynomial.coeff_derivative, coeff_trunc, ite_eq_right this, zero_mul] theorem trunc_derivative' (f : R⟦X⟧) (n : ℕ) : trunc (n - 1) (d⁄dX R f) = Polynomial.derivative (trunc n f) := by diff --git a/Mathlib/RingTheory/PowerSeries/Inverse.lean b/Mathlib/RingTheory/PowerSeries/Inverse.lean index 01c77db9d93550..c24ea184084a67 100644 --- a/Mathlib/RingTheory/PowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/PowerSeries/Inverse.lean @@ -73,7 +73,7 @@ theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) : · rintro ⟨i, j⟩ _hij obtain H | H := le_or_gt n j · aesop - rw [if_pos H, if_pos] + rw [ite_eq_left H, ite_eq_left] · rfl refine ⟨?_, fun hh ↦ H.not_ge ?_⟩ · rintro ⟨⟩ @@ -96,7 +96,7 @@ theorem coeff_invOfUnit (n : ℕ) (φ : R⟦X⟧) (u : Rˣ) : @[simp] theorem constantCoeff_invOfUnit (φ : R⟦X⟧) (u : Rˣ) : constantCoeff (invOfUnit φ u) = ↑u⁻¹ := by - rw [← coeff_zero_eq_constantCoeff_apply, coeff_invOfUnit, if_pos rfl] + rw [← coeff_zero_eq_constantCoeff_apply, coeff_invOfUnit, ite_eq_left rfl] @[simp] theorem mul_invOfUnit (φ : R⟦X⟧) (u : Rˣ) (h : constantCoeff φ = u) : @@ -236,15 +236,15 @@ def Unit_of_divided_by_X_pow_order (f : k⟦X⟧) : k⟦X⟧ˣ := theorem isUnit_divided_by_X_pow_order {f : k⟦X⟧} (hf : f ≠ 0) : IsUnit (divXPowOrder f) := ⟨Unit_of_divided_by_X_pow_order f, - by simp only [Unit_of_divided_by_X_pow_order, dif_neg hf, Units.val_mk]⟩ + by simp only [Unit_of_divided_by_X_pow_order, dite_eq_right hf, Units.val_mk]⟩ theorem Unit_of_divided_by_X_pow_order_nonzero {f : k⟦X⟧} (hf : f ≠ 0) : ↑(Unit_of_divided_by_X_pow_order f) = divXPowOrder f := by - simp only [Unit_of_divided_by_X_pow_order, dif_neg hf, Units.val_mk] + simp only [Unit_of_divided_by_X_pow_order, dite_eq_right hf, Units.val_mk] @[simp] theorem Unit_of_divided_by_X_pow_order_zero : Unit_of_divided_by_X_pow_order (0 : k⟦X⟧) = 1 := by - simp only [Unit_of_divided_by_X_pow_order, dif_pos] + simp only [Unit_of_divided_by_X_pow_order, dite_eq_left] theorem eq_divided_by_X_pow_order_Iff_Unit {f : k⟦X⟧} (hf : f ≠ 0) : f = divXPowOrder f ↔ IsUnit f := diff --git a/Mathlib/RingTheory/PowerSeries/Order.lean b/Mathlib/RingTheory/PowerSeries/Order.lean index 68ed7443035f79..449dd045fdd2cc 100644 --- a/Mathlib/RingTheory/PowerSeries/Order.lean +++ b/Mathlib/RingTheory/PowerSeries/Order.lean @@ -58,7 +58,7 @@ def order (φ : R⟦X⟧) : ℕ∞ := /-- The order of the `0` power series is infinite. -/ @[simp] theorem order_zero : order (0 : R⟦X⟧) = ⊤ := - dif_pos rfl + dite_eq_left rfl theorem order_finite_iff_ne_zero : (order φ < ⊤) ↔ φ ≠ 0 := by simp only [order] @@ -76,14 +76,14 @@ theorem coe_toNat_order {φ : R⟦X⟧} (hf : φ ≠ 0) : φ.order.toNat = φ.or then the coefficient indexed by the order is nonzero. -/ theorem coeff_order (h : φ ≠ 0) : coeff φ.order.toNat φ ≠ 0 := by classical - simp only [order, h, not_false_iff, dif_neg] + simp only [order, h, not_false_iff, dite_eq_right] generalize_proofs h exact Nat.find_spec h /-- If the `n`th coefficient of a formal power series is nonzero, then the order of the power series is less than or equal to `n`. -/ theorem order_le (n : ℕ) (h : coeff n φ ≠ 0) : order φ ≤ n := by - rw [order, dif_neg] + rw [order, dite_eq_right] · simpa using ⟨n, le_rfl, h⟩ · exact exists_coeff_ne_zero_iff_ne_zero.mp ⟨n, h⟩ @@ -123,7 +123,7 @@ theorem order_eq_nat {φ : R⟦X⟧} {n : ℕ} : order φ = n ↔ coeff n φ ≠ 0 ∧ ∀ i, i < n → coeff i φ = 0 := by rcases eq_or_ne φ 0 with (rfl | hφ) · simp - simp [order, dif_neg hφ, Nat.find_eq_iff] + simp [order, dite_eq_right hφ, Nat.find_eq_iff] /-- The order of a formal power series is exactly `n` if the `n`th coefficient is nonzero, and the `i`th coefficient is `0` for all `i < n`. -/ @@ -240,13 +240,13 @@ theorem order_monomial (n : ℕ) (a : R) [Decidable (a = 0)] : · simp only [Nat.cast_inj] at hi rwa [hi, coeff_monomial_same] · simp only [Nat.cast_lt] at hi - rw [coeff_monomial, if_neg] + rw [coeff_monomial, ite_eq_right] exact ne_of_lt hi /-- The order of the monomial `a*X^n` is `n` if `a ≠ 0`. -/ theorem order_monomial_of_ne_zero (n : ℕ) (a : R) (h : a ≠ 0) : order (monomial n a) = n := by classical - rw [order_monomial, if_neg h] + rw [order_monomial, ite_eq_right h] /-- If `n` is strictly smaller than the order of `ψ`, then the `n`th coefficient of its product with any other power series is `0`. -/ diff --git a/Mathlib/RingTheory/PowerSeries/Schroder.lean b/Mathlib/RingTheory/PowerSeries/Schroder.lean index 53cb19c61867a3..8bf4b26fbe020b 100644 --- a/Mathlib/RingTheory/PowerSeries/Schroder.lean +++ b/Mathlib/RingTheory/PowerSeries/Schroder.lean @@ -86,7 +86,7 @@ lemma coeff_X_mul_largeSchroderSeriesSeries_sq (n : ℕ) (hn : 0 < n) : apply sum_congr rfl intros x hx have hx' : 0 < x := by grind - rw [if_pos hx'] + rw [ite_eq_left hx'] rw [this, sum_Ico_eq_sum_range, show n = n - 1 + 1 by lia, sum_range_succ] grind [largeSchroder_zero] diff --git a/Mathlib/RingTheory/PowerSeries/Substitution.lean b/Mathlib/RingTheory/PowerSeries/Substitution.lean index b90587cd27381b..78f0608fa34351 100644 --- a/Mathlib/RingTheory/PowerSeries/Substitution.lean +++ b/Mathlib/RingTheory/PowerSeries/Substitution.lean @@ -86,7 +86,7 @@ protected theorem HasSubst.monomial {n : τ →₀ ℕ} (hn : n ≠ 0) (s : S) : classical apply HasSubst.of_constantCoeff_zero rw [← MvPowerSeries.coeff_zero_eq_constantCoeff, MvPowerSeries.coeff_monomial, - if_neg hn.symm] + ite_eq_right hn.symm] /-- A variant of `HasSubst.monomial` to avoid the expansion of `Unit`. -/ protected theorem HasSubst.monomial' {n : ℕ} (hn : n ≠ 0) (s : S) : @@ -262,19 +262,19 @@ theorem coeff_subst_X_pow {k : ℕ} (hk : k ≠ 0) (f : PowerSeries R) (n : ℕ) · rw [coeff_subst' (.X_pow hk), finsum_eq_single _ (n / k), ← pow_mul, Nat.mul_div_cancel' h, coeff_X_pow_self, Algebra.algebraMap_eq_smul_one] intro j hj - rw [← pow_mul, coeff_X_pow, if_neg, smul_zero] + rw [← pow_mul, coeff_X_pow, ite_eq_right, smul_zero] contrapose hj rw [hj, Nat.mul_div_cancel_left j hk.pos] · rw [coeff_subst' (.X_pow hk), finsum_eq_zero_of_forall_eq_zero] intro j - rw [← pow_mul, coeff_X_pow, if_neg, smul_zero] + rw [← pow_mul, coeff_X_pow, ite_eq_right, smul_zero] contrapose h use j @[simp] theorem constantCoeff_subst_X_pow {k : ℕ} (hk : k ≠ 0) (f : PowerSeries R) : constantCoeff (subst (X ^ k) f) = algebraMap R S f.constantCoeff := by - rw [← coeff_zero_eq_constantCoeff, coeff_subst_X_pow hk, if_pos (dvd_zero k), + rw [← coeff_zero_eq_constantCoeff, coeff_subst_X_pow hk, ite_eq_left (dvd_zero k), Nat.zero_div, coeff_zero_eq_constantCoeff] theorem constantCoeff_subst_eq_zero (ha : a.constantCoeff = 0) (f : PowerSeries R) diff --git a/Mathlib/RingTheory/PowerSeries/Trunc.lean b/Mathlib/RingTheory/PowerSeries/Trunc.lean index f8bbbd3f6c470a..73daacee0a6194 100644 --- a/Mathlib/RingTheory/PowerSeries/Trunc.lean +++ b/Mathlib/RingTheory/PowerSeries/Trunc.lean @@ -99,7 +99,7 @@ theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* intro _ h rw [mem_range] at h congr - rw [coeff_trunc, if_pos h] + rw [coeff_trunc, ite_eq_left h] @[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by ext d @@ -168,7 +168,7 @@ theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) : ext d rw [coeff_trunc, coeff_trunc, coeff_coe] split_ifs with h - · rw [coeff_trunc, if_pos <| lt_of_lt_of_le h hnm] + · rw [coeff_trunc, ite_eq_left <| lt_of_lt_of_le h hnm] · rfl @[simp] theorem trunc_trunc {n} (f : R⟦X⟧) : trunc n ↑(trunc n f) = trunc n f := @@ -182,7 +182,7 @@ theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) : · rw [coeff_mul, coeff_mul, sum_congr rfl] intro _ hab have ha := lt_of_le_of_lt (antidiagonal.fst_le hab) h - rw [coeff_coe, coeff_trunc, if_pos ha] + rw [coeff_coe, coeff_trunc, ite_eq_left ha] · rfl @[simp] theorem trunc_mul_trunc {n} (f g : R⟦X⟧) : @@ -217,7 +217,7 @@ theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R long truncation of the power series `f`. -/ theorem coeff_coe_trunc_of_lt {n m} {f : R⟦X⟧} (h : n < m) : coeff n (trunc m f) = coeff n f := by - rwa [coeff_coe, coeff_trunc, if_pos] + rwa [coeff_coe, coeff_trunc, ite_eq_left] /-- The `n`-th coefficient of `f*g` may be calculated from the truncations of `f` and `g`. -/ diff --git a/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean b/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean index 4b1d186e22b259..39591fa44823a1 100644 --- a/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean +++ b/Mathlib/RingTheory/PowerSeries/WeierstrassPreparation.lean @@ -245,8 +245,8 @@ theorem coeff_seq_mem (k : ℕ) {i : ℕ} (hi : i ≥ (g.map (Ideal.Quotient.mk nth_rw 1 [g.eq_X_pow_mul_shift_add_trunc n] rw [add_mul, mul_assoc, IsUnit.mul_val_inv, hs] ring - rw [key, map_sub, Polynomial.coeff_coe, coeff_trunc, if_neg hi.not_gt, zero_sub, neg_mem_iff, - pow_succ'] + rw [key, map_sub, Polynomial.coeff_coe, coeff_trunc, ite_eq_right hi.not_gt, zero_sub, + neg_mem_iff, pow_succ'] refine coeff_mul_mem_ideal_of_coeff_left_mem_ideal' (fun i ↦ ?_) i refine coeff_mul_mem_ideal_mul_ideal_of_coeff_mem_ideal' (by simp [n, g.coeff_trunc_order_mem]) (fun i ↦ ?_) i @@ -339,7 +339,7 @@ theorem eq_zero_of_mul_eq [IsHausdorff I A] (fun j _ ↦ ih j) i le_rfl rw [map_add, Polynomial.coeff_coe] refine Ideal.add_mem _ ?_ (g.coeff_trunc_order_mem I j) - simp_rw [coeff_X_pow_mul', if_neg (lt_of_le_of_lt hj hi).not_ge, zero_mem] + simp_rw [coeff_X_pow_mul', ite_eq_right (lt_of_le_of_lt hj hi).not_ge, zero_mem] simp_rw [Polynomial.coeff_coe, Polynomial.coeff_eq_zero_of_degree_lt (lt_of_lt_of_le hdeg (by simpa)), zero_mem] rw [add_mul, mul_comm (X ^ _), ← eq_sub_iff_add_eq] at heq @@ -533,13 +533,13 @@ infixl:70 " %ʷ " => weierstrassMod @[simp] theorem weierstrassDiv_zero_right [IsPrecomplete (IsLocalRing.maximalIdeal A) A] : f /ʷ 0 = 0 := by - rw [weierstrassDiv, dif_neg (by simp)] + rw [weierstrassDiv, dite_eq_right (by simp)] alias weierstrassDiv_zero := weierstrassDiv_zero_right @[simp] theorem weierstrassMod_zero_right [IsPrecomplete (IsLocalRing.maximalIdeal A) A] : f %ʷ 0 = 0 := by - rw [weierstrassMod, dif_neg (by simp)] + rw [weierstrassMod, dite_eq_right (by simp)] alias weierstrassMod_zero := weierstrassMod_zero_right @@ -560,13 +560,13 @@ include hg theorem isWeierstrassDivision_weierstrassDiv_weierstrassMod [IsAdicComplete (IsLocalRing.maximalIdeal A) A] : f.IsWeierstrassDivision g (f /ʷ g) (f %ʷ g) := by - simp_rw [weierstrassDiv, weierstrassMod, dif_pos hg] + simp_rw [weierstrassDiv, weierstrassMod, dite_eq_left hg] exact (IsWeierstrassDivisor.of_map_ne_zero hg).isWeierstrassDivisionAt_div_mod f theorem eq_mul_weierstrassDiv_add_weierstrassMod [IsAdicComplete (IsLocalRing.maximalIdeal A) A] : f = g * (f /ʷ g) + (f %ʷ g) := by - simp_rw [weierstrassDiv, weierstrassMod, dif_pos hg] + simp_rw [weierstrassDiv, weierstrassMod, dite_eq_left hg] exact ((IsWeierstrassDivisor.of_map_ne_zero hg).isWeierstrassDivisionAt_div_mod f).2 variable {f} in @@ -765,9 +765,11 @@ theorem IsWeierstrassDivision.isWeierstrassFactorization rw [Polynomial.degree_sub_eq_left_of_degree_lt H1, Polynomial.degree_X_pow] refine ⟨⟨⟨fun {i} hi ↦ ?_⟩, .sub_of_left (Polynomial.monic_X_pow _) H1⟩, Units.isUnit _, ?_⟩ · rw [hfdeg] at hi - simp_rw [f, Polynomial.coeff_sub, Polynomial.coeff_X_pow, if_neg hi.ne, zero_sub, neg_mem_iff] + simp_rw [f, Polynomial.coeff_sub, Polynomial.coeff_X_pow, ite_eq_right hi.ne, zero_sub, + neg_mem_iff] have := H.coeff_f_sub_r_mem hi - rwa [map_sub, coeff_X_pow, if_neg hi.ne, zero_sub, neg_mem_iff, Polynomial.coeff_coe] at this + rwa [map_sub, coeff_X_pow, ite_eq_right hi.ne, zero_sub, neg_mem_iff, + Polynomial.coeff_coe] at this · have := congr($(H.2) * ↑(H.isUnit_of_map_ne_zero hg).unit⁻¹) rw [add_mul, mul_assoc, IsUnit.mul_val_inv, mul_one, ← sub_eq_iff_eq_add] at this simp_rw [← this, f, Polynomial.coe_sub, Polynomial.coe_pow, Polynomial.coe_X, sub_mul] diff --git a/Mathlib/RingTheory/PrincipalIdealDomain.lean b/Mathlib/RingTheory/PrincipalIdealDomain.lean index a3857b75db71ae..4bc8d58266a8d2 100644 --- a/Mathlib/RingTheory/PrincipalIdealDomain.lean +++ b/Mathlib/RingTheory/PrincipalIdealDomain.lean @@ -346,7 +346,7 @@ noncomputable def factors (a : R) : Multiset R := theorem factors_spec (a : R) (h : a ≠ 0) : (∀ b ∈ factors a, Irreducible b) ∧ Associated (factors a).prod a := by - unfold factors; rw [dif_neg h] + unfold factors; rw [dite_eq_right h] exact Classical.choose_spec (WfDvdMonoid.exists_factors a h) theorem ne_zero_of_mem_factors {R : Type v} [CommRing R] [IsDomain R] [IsPrincipalIdealRing R] diff --git a/Mathlib/RingTheory/RamificationInertia/Inertia.lean b/Mathlib/RingTheory/RamificationInertia/Inertia.lean index 23179a415b8879..7b0424e5d1e1e9 100644 --- a/Mathlib/RingTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/RingTheory/RamificationInertia/Inertia.lean @@ -49,13 +49,13 @@ theorem inertiaDeg_def [hq : q.IsPrime] [Algebra (Localization.AtPrime (q.under R)) (Localization.AtPrime q)] [Localization.AtPrime.IsLiesOverAlgebra (q.under R) q] : q.inertiaDeg R = Module.finrank (q.under R).ResidueField q.ResidueField := by - convert! dif_pos hq + convert! dite_eq_left hq simp [Algebra.algebra_ext_iff, Localization.AtPrime.IsLiesOverAlgebra.algebraMap_eq] @[deprecated (since := "2026-07-03")] alias inertiaDeg'_def := inertiaDeg_def theorem inertiaDeg_of_not_isPrime (hq : ¬ q.IsPrime) : q.inertiaDeg R = 0 := - dif_neg hq + dite_eq_right hq @[deprecated (since := "2026-07-03")] alias inertiaDeg'_of_not_isPrime := inertiaDeg_of_not_isPrime diff --git a/Mathlib/RingTheory/RamificationInertia/Ramification.lean b/Mathlib/RingTheory/RamificationInertia/Ramification.lean index 33298caa981ff9..1e3fe6f6124d04 100644 --- a/Mathlib/RingTheory/RamificationInertia/Ramification.lean +++ b/Mathlib/RingTheory/RamificationInertia/Ramification.lean @@ -57,12 +57,12 @@ noncomputable def ramificationIdx : ℕ := theorem ramificationIdx_def [q.IsPrime] : letI Sq := Localization.AtPrime q q.ramificationIdx R = (Module.length Sq (Sq ⧸ (q.under R).map (algebraMap R Sq))).toNat := - dif_pos _ + dite_eq_left _ @[deprecated (since := "2026-07-01")] alias ramificationIdx'_def := ramificationIdx_def theorem ramificationIdx_of_not_isPrime (hq : ¬ q.IsPrime) : q.ramificationIdx R = 0 := - dif_neg hq + dite_eq_right hq @[deprecated (since := "2026-07-01")] alias ramificationIdx'_of_not_isPrime := ramificationIdx_of_not_isPrime diff --git a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean index dbe8ecc7c6226a..6d3d3f6cc4a881 100644 --- a/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean +++ b/Mathlib/RingTheory/RootsOfUnity/PrimitiveRoots.lean @@ -436,7 +436,7 @@ theorem eq_neg_one_of_two_right [NoZeroDivisors R] {ζ : R} (h : IsPrimitiveRoot theorem neg_one (p : ℕ) [Nontrivial R] [h : CharP R p] (hp : p ≠ 2) : IsPrimitiveRoot (-1 : R) 2 := by convert! IsPrimitiveRoot.orderOf (-1 : R) - rw [orderOf_neg_one, if_neg <| by rwa [ringChar.eq_iff.mpr h]] + rw [orderOf_neg_one, ite_eq_right <| by rwa [ringChar.eq_iff.mpr h]] /-- If `1 < k` then `(∑ i ∈ range k, ζ ^ i) = 0`. -/ theorem geom_sum_eq_zero [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) : @@ -663,7 +663,7 @@ lemma _root_.card_rootsOfUnity_eq_iff_exists_isPrimitiveRoot {n : ℕ} [NeZero n if there is a primitive root of unity in `R`. -/ theorem card_nthRoots_one {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) : Multiset.card (nthRoots n (1 : R)) = n := by - rw [card_nthRoots h, if_pos ⟨ζ, h.pow_eq_one⟩] + rw [card_nthRoots h, ite_eq_left ⟨ζ, h.pow_eq_one⟩] theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) {a : R} (ha : a ≠ 0) : (nthRoots n a).Nodup := by diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index 9d011b5a840eda..99af6ae4137fcb 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -529,9 +529,9 @@ noncomputable instance _root_.Module.End.instDivisionRing inv f := if h : f = 0 then 0 else (LinearEquiv.ofBijective _ <| bijective_of_ne_zero h).symm exists_pair_ne := ⟨0, 1, have := IsSimpleModule.nontrivial R M; zero_ne_one⟩ mul_inv_cancel a a0 := by - simp_rw [dif_neg a0]; ext + simp_rw [dite_eq_right a0]; ext exact (LinearEquiv.ofBijective _ <| bijective_of_ne_zero a0).right_inv _ - inv_zero := dif_pos rfl + inv_zero := dite_eq_left rfl nnqsmul := _ nnqsmul_def := fun _ _ => rfl qsmul := _ diff --git a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean index 03476530bff79e..f0ad6731c2e0e1 100644 --- a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean +++ b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean @@ -180,7 +180,7 @@ def piLocalizationToMaximal : PiLocalization R →ₐ[R] MaximalSpectrum.PiLocal theorem piLocalizationToMaximal_surjective : Function.Surjective (piLocalizationToMaximal R) := by classical - exact fun r ↦ ⟨fun I ↦ if h : I.1.IsMaximal then r ⟨_, h⟩ else 0, funext fun _ ↦ dif_pos _⟩ + exact fun r ↦ ⟨fun I ↦ if h : I.1.IsMaximal then r ⟨_, h⟩ else 0, funext fun _ ↦ dite_eq_left _⟩ variable {R} diff --git a/Mathlib/RingTheory/Trace/Basic.lean b/Mathlib/RingTheory/Trace/Basic.lean index f2faaedc18e787..f0706b9cc3012b 100644 --- a/Mathlib/RingTheory/Trace/Basic.lean +++ b/Mathlib/RingTheory/Trace/Basic.lean @@ -309,8 +309,8 @@ lemma Algebra.trace_eq_zero_of_not_isSeparable (H : ¬ Algebra.IsSeparable K L) obtain rfl : g = minpoly K x := by simpa using hg₂ cases hx hg₁ | succ n => - rw [nextCoeff, if_neg, ← hg₂, coeff_expand (by positivity), - if_neg, neg_zero, mul_zero, LinearMap.zero_apply] + rw [nextCoeff, ite_eq_right, ← hg₂, coeff_expand (by positivity), + ite_eq_right, neg_zero, mul_zero, LinearMap.zero_apply] · rw [natDegree_expand] intro h have := Nat.dvd_sub (dvd_mul_left (p ^ (n + 1)) g.natDegree) h diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index cf1ec92d32d910..f20e5dbf0e7a25 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -323,10 +323,10 @@ theorem WfDvdMonoid.of_exists_prime_factors : WfDvdMonoid α := · exact ⊤ exact ↑(Multiset.card (Classical.choose (pf a h))) rintro a b ⟨ane0, ⟨c, hc, b_eq⟩⟩ - rw [dif_neg ane0] + rw [dite_eq_right ane0] by_cases h : b = 0 · simp [h, lt_top_iff_ne_top] - · rw [dif_neg h, Nat.cast_lt] + · rw [dite_eq_right h, Nat.cast_lt] have cne0 : c ≠ 0 := by refine mt (fun con => ?_) h rw [b_eq, con, mul_zero] diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean index 1b734daf5621bb..18e7045a5ca9a0 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean @@ -193,7 +193,7 @@ noncomputable def factors (a : α) : Multiset α := if h : a = 0 then 0 else Classical.choose (UniqueFactorizationMonoid.exists_prime_factors a h) theorem factors_prod {a : α} (ane0 : a ≠ 0) : Associated (factors a).prod a := by - rw [factors, dif_neg ane0] + rw [factors, dite_eq_right ane0] exact (Classical.choose_spec (exists_prime_factors a ane0)).2 @[simp] @@ -208,7 +208,7 @@ theorem dvd_of_mem_factors {p a : α} (h : p ∈ factors a) : p ∣ a := theorem prime_of_factor {a : α} (x : α) (hx : x ∈ factors a) : Prime x := by have ane0 := ne_zero_of_mem_factors hx - rw [factors, dif_neg ane0] at hx + rw [factors, dite_eq_right ane0] at hx exact (Classical.choose_spec (UniqueFactorizationMonoid.exists_prime_factors a ane0)).1 x hx theorem irreducible_of_factor {a : α} : ∀ x : α, x ∈ factors a → Irreducible x := fun x h => diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean index ea862e1026214c..a3aaca3f50ea32 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/FactorSet.lean @@ -118,13 +118,13 @@ def count (p : Associates α) : FactorSet α → ℕ := @[simp] theorem count_some (hp : Irreducible p) (s : Multiset _) : count p (WithTop.some s) = s.count ⟨p, hp⟩ := by - simp only [count, dif_pos hp, bcount] + simp only [count, dite_eq_left hp, bcount] @[simp] theorem count_zero (hp : Irreducible p) : count p (0 : FactorSet α) = 0 := by - simp only [count, dif_pos hp, bcount, Multiset.count_zero] + simp only [count, dite_eq_left hp, bcount, Multiset.count_zero] -theorem count_reducible (hp : ¬Irreducible p) : count p = 0 := dif_neg hp +theorem count_reducible (hp : ¬Irreducible p) : count p = 0 := dite_eq_right hp end count @@ -160,7 +160,7 @@ theorem mem_factorSet_some {p : Associates α} {hp : Irreducible p} theorem reducible_notMem_factorSet {p : Associates α} (hp : ¬Irreducible p) (s : FactorSet α) : p ∉ s := fun h ↦ by - rwa [← factorSetMem_eq_mem, FactorSetMem, dif_neg hp] at h + rwa [← factorSetMem_eq_mem, FactorSetMem, dite_eq_right hp] at h theorem irreducible_of_mem_factorSet {p : Associates α} {s : FactorSet α} (h : p ∈ s) : Irreducible p := @@ -221,12 +221,12 @@ noncomputable def factors (a : Associates α) : FactorSet α := by @[simp] theorem factors_zero : (0 : Associates α).factors = ⊤ := - dif_pos rfl + dite_eq_left rfl @[simp] theorem factors_mk (a : α) (h : a ≠ 0) : (Associates.mk a).factors = factors' a := by - apply dif_neg + apply dite_eq_right apply mt mk_eq_zero.1 h @[simp] @@ -458,7 +458,7 @@ variable [DecidableEq (Associates α)] [∀ p : Associates α, Decidable (Irredu theorem prime_pow_dvd_iff_le {m p : Associates α} (h₁ : m ≠ 0) (h₂ : Irreducible p) {k : ℕ} : p ^ k ≤ m ↔ k ≤ count p m.factors := by - rw [count, dif_pos h₂, prime_pow_le_iff_le_bcount h₁] + rw [count, dite_eq_left h₂, prime_pow_le_iff_le_bcount h₁] theorem le_of_count_ne_zero {m p : Associates α} (h0 : m ≠ 0) (hp : Irreducible p) : count p m.factors ≠ 0 → p ≤ m := by diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean index 52e7d74170489a..545156480cfb4b 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Moebius.lean @@ -43,11 +43,11 @@ theorem _root_.Nat.moebius_eq (n : ℕ) : moebius n = ArithmeticFunction.moebius @[simp] theorem _root_.Squarefree.moebius_eq (ha : Squarefree a) : moebius a = (-1) ^ (factors a).card := - if_pos ha + ite_eq_left ha @[simp] theorem moebius_of_not_squarefree (ha : ¬ Squarefree a) : moebius a = 0 := - if_neg ha + ite_eq_right ha theorem moebius_zero [Nontrivial α] : moebius (0 : α) = 0 := by simp diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Nat.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Nat.lean index 8e90e455372bdd..93bceed16682a6 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Nat.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Nat.lean @@ -35,7 +35,7 @@ instance instWfDvdMonoid : WfDvdMonoid ℕ where cases b · simp obtain ⟨h1, h2⟩ := dvd_and_not_dvd_iff.2 h - simp only [succ_ne_zero, cast_lt, if_false] + simp only [succ_ne_zero, cast_lt, ite_false] refine lt_of_le_of_ne (Nat.le_of_dvd (Nat.succ_pos _) h1) fun con => h2 ?_ rw [con] diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean index 13ba0a3bee8196..70ece8047033f2 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/NormalizedFactors.lean @@ -46,7 +46,7 @@ theorem factors_eq_normalizedFactors {M : Type*} [CommMonoidWithZero M] theorem prod_normalizedFactors {a : α} (ane0 : a ≠ 0) : Associated (normalizedFactors a).prod a := by - rw [normalizedFactors, factors, dif_neg ane0] + rw [normalizedFactors, factors, dite_eq_right ane0] refine Associated.trans ?_ (Classical.choose_spec (exists_prime_factors a ane0)).2 rw [← Associates.mk_eq_mk_iff_associated, ← Associates.prod_mk, ← Associates.prod_mk, Multiset.map_map] @@ -401,7 +401,7 @@ protected noncomputable def strongNormalizationMonoid : StrongNormalizationMonoi rw [Function.comp_apply, mkMonoidHom_apply, Classical.choose_spec mk_surjective.hasRightInverse x] rfl - rw [if_neg hx, ← mkMonoidHom_apply, MonoidHom.map_multiset_prod, map_map, h, map_id, ← + rw [ite_eq_right hx, ← mkMonoidHom_apply, MonoidHom.map_multiset_prod, map_map, h, map_id, ← associated_iff_eq] apply prod_normalizedFactors hx) diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index 0c0dcca687ef30..2df7c21a68e8cd 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -383,7 +383,7 @@ lemma one_apply_def (x : R) : (1 : Valuation R Γ₀) x = if x = 0 then 0 else 1 @[simp] lemma toMonoidWithZeroHom_one : (1 : Valuation R Γ₀).toMonoidWithZeroHom = 1 := rfl -lemma one_apply_of_ne_zero {x : R} (hx : x ≠ 0) : (1 : Valuation R Γ₀) x = 1 := if_neg hx +lemma one_apply_of_ne_zero {x : R} (hx : x ≠ 0) : (1 : Valuation R Γ₀) x = 1 := ite_eq_right hx @[simp] lemma one_apply_eq_zero_iff [Nontrivial Γ₀] {x : R} : (1 : Valuation R Γ₀) x = 0 ↔ x = 0 := @@ -831,7 +831,7 @@ theorem valueGroup₀Fun_spec (h : v.IsEquiv w) {r s : R} (hr : (MonoidWithZeroH (hs' : (MonoidWithZeroHom.ofClass w) s ≠ 0 := h.ofClass_eq_zero.ne.1 hs) : valueGroup₀Fun h (valueGroup.mk (.ofClass v) r s hr hs) = valueGroup.mk (.ofClass w) r s hr' hs' := by - rw [valueGroup₀Fun, dif_neg (by simp)] + rw [valueGroup₀Fun, dite_eq_right (by simp)] generalize_proofs _ _ _ _ H _ have c_spec := H.choose_spec simp only [MonoidWithZeroHom.coe_ofClass, ne_eq, WithZero.coe_inj, valueGroup.mk_inj] at c_spec ⊢ diff --git a/Mathlib/RingTheory/Valuation/RankOne.lean b/Mathlib/RingTheory/Valuation/RankOne.lean index f128dd1b55ff0c..57c6e6cbb99f4e 100644 --- a/Mathlib/RingTheory/Valuation/RankOne.lean +++ b/Mathlib/RingTheory/Valuation/RankOne.lean @@ -154,7 +154,7 @@ theorem exists_val_lt {γ : ℝ≥0} (hγ : γ ≠ 0) : ∃ x ≠ 0, RankOne.hom · simp only [restrict₀_apply, MonoidWithZeroHom.coe_ofClass, restrict_def, map_eq_zero, dite_eq_left_iff, coe_ne_zero, imp_false, not_not] at hk by_contra h0 - rw [dif_pos (by rw [dif_pos ((zero_iff v).mpr h0)]), eq_comm] at hk + rw [dite_eq_left (by rw [dite_eq_left ((zero_iff v).mpr h0)]), eq_comm] at hk simp at hk · convert! h simp only [restrict_RankOne_hom_eq, coe_comp, Function.comp_apply, ← hk] diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 12d87ad0c614f7..2e3fa6a22f350d 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -623,7 +623,7 @@ instance : Inv (ValueGroupWithZero R) where · absurd hx apply vle_mul_cancel t.prop simpa using vle_trans h₁ (mul_vle_mul_left hy s) - · simp only [dif_neg hx, dif_neg hy] + · simp only [dite_eq_right hx, dite_eq_right hy] apply ValueGroupWithZero.sound · grw [veq_mul_comm, veq_mul_comm _ x] simpa using h₂ @@ -632,7 +632,7 @@ instance : Inv (ValueGroupWithZero R) where @[simp] theorem ValueGroupWithZero.inv_mk (x : R) (y : posSubmonoid R) (hx : ¬x ≤ᵥ 0) : - (ValueGroupWithZero.mk x y)⁻¹ = ValueGroupWithZero.mk (y : R) ⟨x, hx⟩ := dif_neg hx + (ValueGroupWithZero.mk x y)⁻¹ = ValueGroupWithZero.mk (y : R) ⟨x, hx⟩ := dite_eq_right hx /-- The value group-with-zero is a linearly ordered commutative group with zero. -/ instance : LinearOrderedCommGroupWithZero (ValueGroupWithZero R) where @@ -643,7 +643,7 @@ instance : LinearOrderedCommGroupWithZero (ValueGroupWithZero R) where rw [← ValueGroupWithZero.mk_zero 1, ← ValueGroupWithZero.mk_one_one, ValueGroupWithZero.mk_le_mk] at h simp [not_vle_one_zero] at h - inv_zero := dif_pos .rfl + inv_zero := dite_eq_left .rfl mul_inv_cancel := ValueGroupWithZero.ind fun x y h => by rw [ne_eq, ← ValueGroupWithZero.mk_zero 1, ValueGroupWithZero.mk_eq_mk] at h simp only [Submonoid.coe_one, mul_one, zero_mul, zero_vle, and_true] at h diff --git a/Mathlib/RingTheory/WittVector/Identities.lean b/Mathlib/RingTheory/WittVector/Identities.lean index 9ba6ce06ae5bc2..f7b3b994389b5c 100644 --- a/Mathlib/RingTheory/WittVector/Identities.lean +++ b/Mathlib/RingTheory/WittVector/Identities.lean @@ -79,11 +79,11 @@ theorem coeff_p [CharP R p] (i : ℕ) : (p : 𝕎 R).coeff i = if i = 1 then 1 e @[simp] theorem coeff_p_zero [CharP R p] : (p : 𝕎 R).coeff 0 = 0 := by - rw [coeff_p, if_neg] + rw [coeff_p, ite_eq_right] exact zero_ne_one @[simp] -theorem coeff_p_one [CharP R p] : (p : 𝕎 R).coeff 1 = 1 := by rw [coeff_p, if_pos rfl] +theorem coeff_p_one [CharP R p] : (p : 𝕎 R).coeff 1 = 1 := by rw [coeff_p, ite_eq_left rfl] theorem p_nonzero [Nontrivial R] [CharP R p] : (p : 𝕎 R) ≠ 0 := by intro h diff --git a/Mathlib/RingTheory/WittVector/InitTail.lean b/Mathlib/RingTheory/WittVector/InitTail.lean index 76152d1d87779e..68edc419d59aab 100644 --- a/Mathlib/RingTheory/WittVector/InitTail.lean +++ b/Mathlib/RingTheory/WittVector/InitTail.lean @@ -102,8 +102,8 @@ theorem select_add_select_not : ∀ x : 𝕎 R, select P x + select (fun i => ¬ refine fun m _ => mul_eq_mul_left_iff.mpr (Or.inl ?_) rw [ite_pow, zero_pow (pow_ne_zero _ hp.out.ne_zero)] by_cases Pm : P m - · rw [if_pos Pm, if_neg <| not_not_intro Pm, zero_pow Fin.pos'.ne', add_zero] - · rwa [if_neg Pm, if_pos, zero_add] + · rw [ite_eq_left Pm, ite_eq_right <| not_not_intro Pm, zero_pow Fin.pos'.ne', add_zero] + · rwa [ite_eq_right Pm, ite_eq_left, zero_add] theorem coeff_add_of_disjoint (x y : 𝕎 R) (h : ∀ n, x.coeff n = 0 ∨ y.coeff n = 0) : (x + y).coeff n = x.coeff n + y.coeff n := by @@ -179,7 +179,7 @@ elab_rules : tactic fin_cases b <;> simp only [Function.uncurry, Matrix.cons_val_zero, Matrix.head_cons, WittVector.coeff_mk, Matrix.cons_val_one, WittVector.mk, Fin.mk_zero, Matrix.cons_val', Matrix.empty_val', Matrix.cons_val_fin_one, Matrix.cons_val_zero, - hk, if_true] + hk, ite_true] )) @[simp] diff --git a/Mathlib/RingTheory/WittVector/IsPoly.lean b/Mathlib/RingTheory/WittVector/IsPoly.lean index 902cfc16d982c3..e54d307d77513d 100644 --- a/Mathlib/RingTheory/WittVector/IsPoly.lean +++ b/Mathlib/RingTheory/WittVector/IsPoly.lean @@ -286,9 +286,9 @@ def onePoly (n : ℕ) : MvPolynomial ℕ ℤ := theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) : bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by rw [wittPolynomial_eq_sum_C_mul_X_pow, map_sum, Finset.sum_eq_single 0] - · simp only [onePoly, one_pow, one_mul, map_pow, C_1, pow_zero, bind₁_X_right, if_true] + · simp only [onePoly, one_pow, one_mul, map_pow, C_1, pow_zero, bind₁_X_right, ite_true] · intro i _hi hi0 - simp only [onePoly, if_neg hi0, zero_pow (pow_ne_zero _ hp.1.ne_zero), mul_zero, map_pow, + simp only [onePoly, ite_eq_right hi0, zero_pow (pow_ne_zero _ hp.1.ne_zero), mul_zero, map_pow, bind₁_X_right, map_mul] · simp @@ -370,7 +370,7 @@ end IsPoly₂ attribute [ghost_simps] AlgHom.id_apply map_natCast RingHom.map_zero RingHom.map_one RingHom.map_mul RingHom.map_add RingHom.map_sub RingHom.map_neg RingHom.id_apply mul_add add_mul add_zero zero_add mul_one one_mul mul_zero zero_mul Nat.succ_ne_zero add_tsub_cancel_right - Nat.succ_eq_add_one if_true eq_self_iff_true if_false forall_true_iff forall₂_true_iff + Nat.succ_eq_add_one ite_true eq_self_iff_true ite_false forall_true_iff forall₂_true_iff forall₃_true_iff end diff --git a/Mathlib/RingTheory/WittVector/Truncated.lean b/Mathlib/RingTheory/WittVector/Truncated.lean index 00fd63733332b1..36361b8a179cf6 100644 --- a/Mathlib/RingTheory/WittVector/Truncated.lean +++ b/Mathlib/RingTheory/WittVector/Truncated.lean @@ -100,7 +100,7 @@ def out (x : TruncatedWittVector p n R) : 𝕎 R := @[simp] theorem coeff_out (x : TruncatedWittVector p n R) (i : Fin n) : x.out.coeff i = x.coeff i := by - rw [out]; dsimp only; rw [dif_pos i.is_lt, Fin.eta] + rw [out]; dsimp only; rw [dite_eq_left i.is_lt, Fin.eta] theorem out_injective : Injective (@out p n R _) := by intro x y h diff --git a/Mathlib/RingTheory/WittVector/Verschiebung.lean b/Mathlib/RingTheory/WittVector/Verschiebung.lean index 7cd46cd4950ffc..3b8fb59c2a05e4 100644 --- a/Mathlib/RingTheory/WittVector/Verschiebung.lean +++ b/Mathlib/RingTheory/WittVector/Verschiebung.lean @@ -45,7 +45,7 @@ theorem verschiebungFun_coeff (x : 𝕎 R) (n : ℕ) : simp only [verschiebungFun] theorem verschiebungFun_coeff_zero (x : 𝕎 R) : (verschiebungFun x).coeff 0 = 0 := by - rw [verschiebungFun_coeff, if_pos rfl] + rw [verschiebungFun_coeff, ite_eq_left rfl] @[simp] theorem verschiebungFun_coeff_succ (x : 𝕎 R) (n : ℕ) : @@ -62,7 +62,7 @@ theorem ghostComponent_zero_verschiebungFun [hp : Fact p.Prime] (x : 𝕎 R) : theorem ghostComponent_verschiebungFun [hp : Fact p.Prime] (x : 𝕎 R) (n : ℕ) : ghostComponent (n + 1) (verschiebungFun x) = p * ghostComponent n x := by simp only [ghostComponent_apply, aeval_wittPolynomial] - rw [Finset.sum_range_succ', verschiebungFun_coeff, if_pos rfl, + rw [Finset.sum_range_succ', verschiebungFun_coeff, ite_eq_left rfl, zero_pow (pow_ne_zero _ hp.1.ne_zero), mul_zero, add_zero, Finset.mul_sum, Finset.sum_congr rfl] rintro i - simp only [pow_succ', verschiebungFun_coeff_succ, Nat.succ_sub_succ_eq_sub, mul_assoc] @@ -81,7 +81,7 @@ theorem aeval_verschiebung_poly' (x : 𝕎 R) (n : ℕ) : aeval x.coeff (verschiebungPoly n) = (verschiebungFun x).coeff n := by rcases n with - | n · simp only [verschiebungPoly, ite_true, map_zero, verschiebungFun_coeff_zero] - · rw [verschiebungPoly, verschiebungFun_coeff_succ, if_neg n.succ_ne_zero, aeval_X, + · rw [verschiebungPoly, verschiebungFun_coeff_succ, ite_eq_right n.succ_ne_zero, aeval_X, add_tsub_cancel_right] variable (p) diff --git a/Mathlib/RingTheory/WittVector/WittPolynomial.lean b/Mathlib/RingTheory/WittVector/WittPolynomial.lean index 9c2d845b0c49f1..e84e7147e40d64 100644 --- a/Mathlib/RingTheory/WittVector/WittPolynomial.lean +++ b/Mathlib/RingTheory/WittVector/WittPolynomial.lean @@ -124,7 +124,7 @@ theorem constantCoeff_wittPolynomial [hp : Fact p.Prime] (n : ℕ) : simp only [wittPolynomial, map_sum, constantCoeff_monomial] rw [sum_eq_zero] rintro i _ - rw [if_neg] + rw [ite_eq_right] rw [Finsupp.single_eq_zero] exact ne_of_gt (pow_pos hp.1.pos _) diff --git a/Mathlib/SetTheory/Cardinal/Arithmetic.lean b/Mathlib/SetTheory/Cardinal/Arithmetic.lean index 4d4c9ea909db3d..25f43127d111e6 100644 --- a/Mathlib/SetTheory/Cardinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Cardinal/Arithmetic.lean @@ -780,16 +780,16 @@ theorem mk_bounded_set_le_of_infinite (α : Type u) [Infinite α] (c : Cardinal) · rintro ⟨y, h⟩ dsimp only at h by_cases h' : ∃ z : s, g z = y - · rw [dif_pos h'] at h + · rw [dite_eq_left h'] at h cases Sum.inl.inj h exact (Classical.choose h').2 - · rw [dif_neg h'] at h + · rw [dite_eq_right h'] at h cases h · intro h have : ∃ z : s, g z = g ⟨x, h⟩ := ⟨⟨x, h⟩, rfl⟩ use g ⟨x, h⟩ dsimp only - rw [dif_pos this] + rw [dite_eq_left this] congr suffices Classical.choose this = ⟨x, h⟩ from congr_arg Subtype.val this apply g.2 diff --git a/Mathlib/SetTheory/Cardinal/Divisibility.lean b/Mathlib/SetTheory/Cardinal/Divisibility.lean index 5becbf7e87ac78..52eb4d48fd3384 100644 --- a/Mathlib/SetTheory/Cardinal/Divisibility.lean +++ b/Mathlib/SetTheory/Cardinal/Divisibility.lean @@ -83,7 +83,7 @@ theorem prime_of_aleph0_le (ha : ℵ₀ ≤ a) : Prime a := by all_goals rwa [mul_comm] left have habc := le_of_dvd hz hbc - rwa [mul_eq_max' <| ha.trans <| habc, max_def', if_pos h] at hbc + rwa [mul_eq_max' <| ha.trans <| habc, max_def', ite_eq_left h] at hbc theorem not_irreducible_of_aleph0_le (ha : ℵ₀ ≤ a) : ¬Irreducible a := by rw [irreducible_iff, not_and_or] diff --git a/Mathlib/SetTheory/Cardinal/NatCard.lean b/Mathlib/SetTheory/Cardinal/NatCard.lean index c238a719a3a6e4..bf6a91c05e2a26 100644 --- a/Mathlib/SetTheory/Cardinal/NatCard.lean +++ b/Mathlib/SetTheory/Cardinal/NatCard.lean @@ -50,7 +50,7 @@ theorem Nat.card_eq (α : Type*) : Nat.card α = if _ : Finite α then @Fintype.card α (Fintype.ofFinite α) else 0 := by cases finite_or_infinite α · let := Fintype.ofFinite α - simp only [this, *, Nat.card_eq_fintype_card, dif_pos] + simp only [this, *, Nat.card_eq_fintype_card, dite_eq_left] · simp only [*, card_eq_zero_of_infinite, not_finite_iff_infinite.mpr, dite_false] theorem Finite.card_pos_iff [Finite α] : 0 < Nat.card α ↔ Nonempty α := by diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index 36d8df03d5479c..103defb8e2cf81 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -380,7 +380,7 @@ instance : ConditionallyCompleteLinearOrderBot Cardinal := @[simp] theorem sInf_empty : sInf (∅ : Set Cardinal.{u}) = 0 := - dif_neg Set.not_nonempty_empty + dite_eq_right Set.not_nonempty_empty /-- Note that the successor of `c` is not the same as `c + 1` except in the case of finite `c`. -/ @[no_expose] instance : SuccOrder Cardinal := .ofLinearWellFoundedLT _ diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index efe143abee95af..50101d4b7bfd41 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -283,11 +283,11 @@ instance sub : Sub Ordinal where sub a b := if h : b ≤ a then Classical.choose (exists_add_of_le h) else 0 private theorem sub_eq_zero_of_lt {a b : Ordinal} (h : a < b) : a - b = 0 := - dif_neg h.not_ge + dite_eq_right h.not_ge protected theorem add_sub_cancel_of_le {a b : Ordinal} (h : b ≤ a) : b + (a - b) = a := by change b + dite _ _ _ = a - rw [dif_pos h] + rw [dite_eq_left h] exact (Classical.choose_spec (exists_add_of_le h)).symm @[simp] diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 844d543fae1134..7e71c38a40896d 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -891,7 +891,7 @@ protected theorem max_eq_zero {a b : Ordinal} : max a b = 0 ↔ a = 0 ∧ b = 0 @[simp] theorem sInf_empty : sInf (∅ : Set Ordinal) = 0 := - dif_neg Set.not_nonempty_empty + dite_eq_right Set.not_nonempty_empty /-! ### Successor order properties -/ diff --git a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean index 0efcdfec0fff1c..0779e81275ac4a 100644 --- a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean +++ b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean @@ -54,12 +54,12 @@ decreasing_by exact mod_opow_log_lt_self b h @[simp] theorem rec_zero {C : Ordinal → Sort*} (b : Ordinal) (H0 : C 0) (H : ∀ o, o ≠ 0 → C (o % b ^ log b o) → C o) : CNF.rec b H0 H 0 = H0 := by - rw [CNF.rec, dif_pos rfl] + rw [CNF.rec, dite_eq_left rfl] theorem rec_pos (b : Ordinal) {o : Ordinal} {C : Ordinal → Sort*} (ho : o ≠ 0) (H0 : C 0) (H : ∀ o, o ≠ 0 → C (o % b ^ log b o) → C o) : CNF.rec b H0 H o = H o ho (@CNF.rec b C H0 H _) := by - rw [CNF.rec, dif_neg] + rw [CNF.rec, dite_eq_right] /-- The Cantor normal form of an ordinal `o` is the list of coefficients and exponents in the base-`b` expansion of `o`. diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 88c0412600f5fc..859113c542c1ae 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -35,11 +35,11 @@ instance instPow : Pow Ordinal Ordinal := private theorem opow_of_ne_zero {a b : Ordinal} (h : a ≠ 0) : a ^ b = limitRecOn b 1 (fun _ x ↦ x * a) fun o _ f ↦ ⨆ x : Iio o, f x.1 x.2 := - if_neg h + ite_eq_right h /-- `0 ^ a = 1` if `a = 0` and `0 ^ a = 0` otherwise. -/ theorem zero_opow' (a : Ordinal) : 0 ^ a = 1 - a := - if_pos rfl + ite_eq_left rfl theorem zero_opow_le (a : Ordinal) : (0 : Ordinal) ^ a ≤ 1 := by rw [zero_opow'] diff --git a/Mathlib/SetTheory/Ordinal/Veblen.lean b/Mathlib/SetTheory/Ordinal/Veblen.lean index d05e6608d0e89a..59689eeb8e8c84 100644 --- a/Mathlib/SetTheory/Ordinal/Veblen.lean +++ b/Mathlib/SetTheory/Ordinal/Veblen.lean @@ -68,11 +68,11 @@ termination_by o @[simp] theorem veblenWith_zero (f : Ordinal → Ordinal) : veblenWith f 0 = f := by - rw [veblenWith, if_pos rfl] + rw [veblenWith, ite_eq_left rfl] theorem veblenWith_of_ne_zero (f : Ordinal → Ordinal) (h : o ≠ 0) : veblenWith f o = derivFamily fun x : Iio o ↦ veblenWith f x.1 := by - rw [veblenWith, if_neg h] + rw [veblenWith, ite_eq_right h] /-- `veblenWith f o` is always normal for `o ≠ 0`. See `isNormal_veblenWith` for a version which assumes `IsNormal f`. -/ diff --git a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean index c504e032b5cd09..c4c06a3670fb4c 100644 --- a/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean +++ b/Mathlib/Tactic/ComputeAsymptotics/Multiseries/Defs.lean @@ -463,7 +463,7 @@ theorem map_id {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) : Stream'.Seq.map_id ms set_option backward.isDefEq.respectTransparency false in -@[simp← ] +@[simp ←] theorem map_comp {b₁ b₂ b₃ bs₁ bs₂ bs₃} (f₁ : ℝ → ℝ) (g₁ : MultiseriesExpansion bs₁ → MultiseriesExpansion bs₂) (f₂ : ℝ → ℝ) (g₂ : MultiseriesExpansion bs₂ → MultiseriesExpansion bs₃) diff --git a/Mathlib/Tactic/Lift.lean b/Mathlib/Tactic/Lift.lean index c8746ed165379f..24001aa04826e3 100644 --- a/Mathlib/Tactic/Lift.lean +++ b/Mathlib/Tactic/Lift.lean @@ -54,7 +54,7 @@ theorem Subtype.exists_pi_extension {ι : Sort*} {α : ι → Sort*} [ne : ∀ i ∃ g : ∀ i : ι, α i, (fun i : Subtype p => g i) = f := by haveI : DecidablePred p := fun i ↦ Classical.propDecidable (p i) exact ⟨fun i => if hi : p i then f ⟨i, hi⟩ else Classical.choice (ne i), - funext fun i ↦ dif_pos i.2⟩ + funext fun i ↦ dite_eq_left i.2⟩ instance PiSubtype.canLift (ι : Sort*) (α : ι → Sort*) [∀ i, Nonempty (α i)] (p : ι → Prop) : CanLift (∀ i : Subtype p, α i) (∀ i, α i) (fun f i => f i) fun _ => True where diff --git a/Mathlib/Tactic/Linter/Whitespace.lean b/Mathlib/Tactic/Linter/Whitespace.lean index 0ba87d4e2b148f..2c6a496e390461 100644 --- a/Mathlib/Tactic/Linter/Whitespace.lean +++ b/Mathlib/Tactic/Linter/Whitespace.lean @@ -43,10 +43,10 @@ public register_option linter.style.whitespace : Bool := { } /-- Deprecated in favour of `linter.style.whitespace` -/ +@[deprecated linter.style.whitespace (since := "2026-01-07")] public register_option linter.style.commandStart : Bool := { defValue := false descr := "deprecated: use the `linter.style.whitespace` option instead" - deprecation? := some { since := "2026-01-07", text? := "use the `linter.style.whitespace` option instead" } } /-- If the `linter.style.whitespace.verbose` option is `true`, the `whitespace` linter diff --git a/Mathlib/Tactic/NormNum/LegendreSymbol.lean b/Mathlib/Tactic/NormNum/LegendreSymbol.lean index 7dac2cf1af7259..1f6074dc1143b2 100644 --- a/Mathlib/Tactic/NormNum/LegendreSymbol.lean +++ b/Mathlib/Tactic/NormNum/LegendreSymbol.lean @@ -133,25 +133,25 @@ We give one version for each of the four odd residue classes mod `8`. -/ theorem jacobiSymNat.even_odd₁ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 1) (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = r := by simp only [jacobiSymNat, ← hr, ← hc, Int.natCast_ediv, Nat.cast_ofNat] - rw [← jacobiSym.even_odd (mod_cast ha), if_neg (by simp [hb])] + rw [← jacobiSym.even_odd (mod_cast ha), ite_eq_right (by simp [hb])] rw [← Nat.mod_mod_of_dvd, hb]; simp theorem jacobiSymNat.even_odd₇ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 7) (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = r := by simp only [jacobiSymNat, ← hr, ← hc, Int.natCast_ediv, Nat.cast_ofNat] - rw [← jacobiSym.even_odd (mod_cast ha), if_neg (by simp [hb])] + rw [← jacobiSym.even_odd (mod_cast ha), ite_eq_right (by simp [hb])] rw [← Nat.mod_mod_of_dvd, hb]; simp theorem jacobiSymNat.even_odd₃ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 3) (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = -r := by simp only [jacobiSymNat, ← hr, ← hc, Int.natCast_ediv, Nat.cast_ofNat] - rw [← jacobiSym.even_odd (mod_cast ha), if_pos (by simp [hb])] + rw [← jacobiSym.even_odd (mod_cast ha), ite_eq_left (by simp [hb])] rw [← Nat.mod_mod_of_dvd, hb]; simp theorem jacobiSymNat.even_odd₅ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 5) (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = -r := by simp only [jacobiSymNat, ← hr, ← hc, Int.natCast_ediv, Nat.cast_ofNat] - rw [← jacobiSym.even_odd (mod_cast ha), if_pos (by simp [hb])] + rw [← jacobiSym.even_odd (mod_cast ha), ite_eq_left (by simp [hb])] rw [← Nat.mod_mod_of_dvd, hb]; simp /-- Use quadratic reciprocity to reduce to smaller `b`. -/ diff --git a/Mathlib/Tactic/NormNum/OfScientific.lean b/Mathlib/Tactic/NormNum/OfScientific.lean index d6df2f0d522105..c25f8c46ae39b3 100644 --- a/Mathlib/Tactic/NormNum/OfScientific.lean +++ b/Mathlib/Tactic/NormNum/OfScientific.lean @@ -27,14 +27,14 @@ variable {α : Type*} theorem isNNRat_ofScientific_of_true [DivisionSemiring α] : {m e : ℕ} → {n : ℕ} → {d : ℕ} → IsNNRat (NNRat.divNat m (10 ^ e) : α) n d → IsNNRat (OfScientific.ofScientific m true e : α) n d - | _, _, _, _, ⟨_, eq⟩ => ⟨‹_›, by rwa [NNRatCast.ofScientific_eq_ite, if_pos rfl]⟩ + | _, _, _, _, ⟨_, eq⟩ => ⟨‹_›, by rwa [NNRatCast.ofScientific_eq_ite, ite_eq_left rfl]⟩ -- see note [norm_num lemma function equality] theorem isNat_ofScientific_of_false [DivisionSemiring α] : {m e nm ne n : ℕ} → IsNat m nm → IsNat e ne → n = Nat.mul nm ((10 : ℕ) ^ ne) → IsNat (OfScientific.ofScientific m false e : α) n | _, _, _, _, _, ⟨rfl⟩, ⟨rfl⟩, (rfl : (_ : ℕ) = _ * _) => ⟨by - rw [NNRatCast.ofScientific_eq_ite, if_neg Bool.false_ne_true] + rw [NNRatCast.ofScientific_eq_ite, ite_eq_right Bool.false_ne_true] norm_cast⟩ /-- The `norm_num` extension which identifies expressions in scientific notation, normalizing them diff --git a/Mathlib/Testing/Plausible/Functions.lean b/Mathlib/Testing/Plausible/Functions.lean index dea6b1649d102f..1d278d55733cb1 100644 --- a/Mathlib/Testing/Plausible/Functions.lean +++ b/Mathlib/Testing/Plausible/Functions.lean @@ -207,7 +207,7 @@ theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodu · cases h₁ · obtain - | ⟨h₀, h₁⟩ := h₀ simp only [getElem?_cons_succ, zip_cons_cons, applyId_cons] at h₂ ⊢ - rw [if_neg] + rw [ite_eq_right] · apply xs_ih <;> solve_by_elim [Nat.succ.inj] · apply h₀; apply List.mem_of_getElem? h₂ @@ -268,7 +268,7 @@ theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup have h₂ := h₁.length_eq rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h rw [← hx, ← hy]; congr - apply (List.getElem?_inj _ (h₁.nodup_iff.1 h₀)).mp + apply (List.Nodup.getElem?_inj _ (h₁.nodup_iff.1 h₀)).mp · symm; rw [h] rw [← List.applyId_zip_eq] <;> assumption · rw [← h₁.length_eq] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index 2480307ec0476c..05d24f2c640886 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -171,13 +171,13 @@ lemma hasProd_singleton (m : β) (f : β → α) : HasProd (({m} : Set β).domRe theorem hasProd_ite_eq (b : β) [DecidablePred (· = b)] (a : α) (L := unconditional β) [L.LeAtTop] : HasProd (fun b' ↦ if b' = b then a else 1) a L := suffices HasProd (fun b' ↦ if b' = b then a else 1) (if b = b then a else 1) L by simpa - hasProd_single b (hf := fun b' hb' ↦ if_neg hb') (L := L) + hasProd_single b (hf := fun b' hb' ↦ ite_eq_right hb') (L := L) @[to_additive] theorem hasProd_ite_eq' (b : β) [DecidablePred (b = ·)] (a : α) (L := unconditional β) [L.LeAtTop] : HasProd (fun b' ↦ if b = b' then a else 1) a L := suffices HasProd (fun b' ↦ if b = b' then a else 1) (if b = b then a else 1) L by simpa - hasProd_single b (hf := fun b' hb' ↦ if_neg hb'.symm) (L := L) + hasProd_single b (hf := fun b' hb' ↦ ite_eq_right hb'.symm) (L := L) @[to_additive] theorem Equiv.hasProd_iff (e : γ ≃ β) : HasProd (f ∘ e) a ↔ HasProd f a := @@ -410,7 +410,7 @@ theorem HasProd.update' [L.LeAtTop] [L.NeBot] {α : Type*} [TopologicalSpace α] intro b' split_ifs with hb' · simpa only [Function.update_apply, hb', eq_self_iff_true] using! mul_comm (f b) x - · simp only [Function.update_apply, hb', if_false] + · simp only [Function.update_apply, hb', ite_false] have h := hf.mul (hasProd_ite_eq b x L) simp_rw [this] at h exact HasProd.unique h (hf'.mul (hasProd_ite_eq b (f b) L)) @@ -461,8 +461,8 @@ theorem tprod_eq_prod [L.LeAtTop] {s : Finset β} (hf : ∀ b ∉ s, f b = 1) : @[to_additive (attr := simp)] theorem tprod_one : ∏'[L] _, (1 : α) = 1 := by - rw [tprod_def, dif_pos multipliable_one, mulSupport_fun_one, Set.empty_inter, - Set.mulIndicator_one, finprod_one, eq_true_intro hasProd_one, if_true, ite_self] + rw [tprod_def, dite_eq_left multipliable_one, mulSupport_fun_one, Set.empty_inter, + Set.mulIndicator_one, finprod_one, eq_true_intro hasProd_one, ite_true, ite_self] @[to_additive (attr := simp)] theorem tprod_empty [IsEmpty β] : ∏'[L] b, f b = 1 := by @@ -555,7 +555,7 @@ theorem Function.Injective.tprod_eq {g : γ → β} (hg : Injective g) {f : β simp_rw [tprod_def, SummationFilter.support_eq_univ, Set.inter_univ, show (unconditional β).HasSupport by infer_instance, show (unconditional γ).HasSupport by infer_instance, true_and, - if_neg hf_fin, if_neg hf_fin', Multipliable] + ite_eq_right hf_fin, ite_eq_right hf_fin', Multipliable] simp [hg.hasProd_iff (mulSupport_subset_iff'.1 hf)] @[to_additive] @@ -742,12 +742,13 @@ protected theorem Multipliable.tprod_eq_mul_tprod_ite' [DecidableEq β] [L.LeAtT ∏'[L] x, f x = ∏'[L] x, (ite (x = b) (f x) 1 * update f b 1 x) := tprod_congr fun n ↦ by split_ifs with h <;> simp [h] _ = (∏'[L] x, ite (x = b) (f x) 1) * ∏'[L] x, update f b 1 x := - Multipliable.tprod_mul ⟨ite (b = b) (f b) 1, hasProd_single b (fun _ hb ↦ if_neg hb) L⟩ hf + Multipliable.tprod_mul ⟨ite (b = b) (f b) 1, + hasProd_single b (fun _ hb ↦ ite_eq_right hb) L⟩ hf _ = ite (b = b) (f b) 1 * ∏'[L] x, update f b 1 x := by congr - exact tprod_eq_mulSingle b fun b' hb' ↦ if_neg hb' + exact tprod_eq_mulSingle b fun b' hb' ↦ ite_eq_right hb' _ = f b * ∏'[L] x, ite (x = b) 1 (f x) := by - simp only [update, if_true, eq_rec_constant, dite_eq_ite] + simp only [update, ite_true, eq_rec_constant, dite_eq_ite] @[to_additive] protected theorem Multipliable.tprod_mul_tprod_compl {s : Set β} diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean index e53ce4e397d95c..b14a15efd33bc3 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Defs.lean @@ -182,14 +182,14 @@ equal to the finite sum (which is taken to be 1 if the support of `f` is infinit Note that in this case `HasSum f a` is satisfied for *every* element `a` of the target, so the value assigned to the `tsum` is a question of conventions. -/] lemma tprod_bot (hL : ¬L.NeBot) (f : β → α) : ∏'[L] b, f b = ∏ᶠ b, f b := by - simp only [tprod_def, dif_pos (multipliable_bot hL f)] + simp only [tprod_def, dite_eq_left (multipliable_bot hL f)] have : L.LeAtTop := L.leAtTop_of_not_NeBot hL rw [L.support_eq_univ, Set.inter_univ, Set.mulIndicator_univ] by_cases hf : (mulSupport f).Finite - · rw [eq_true_intro hf, if_pos] + · rw [eq_true_intro hf, ite_eq_left] simp only [and_true] infer_instance - · rwa [if_neg (by tauto), if_pos (hasProd_bot hL _ _), finprod_of_infinite_mulSupport] + · rwa [ite_eq_right (by tauto), ite_eq_left (hasProd_bot hL _ _), finprod_of_infinite_mulSupport] variable {f : β → α} {a : α} {s : Finset β} @@ -308,7 +308,7 @@ theorem multipliable_of_ne_finset_one (hf : ∀ b ∉ s, f b = 1) [L.HasSupport] theorem Multipliable.hasProd (ha : Multipliable f L) : HasProd f (∏'[L] b, f b) L := by -- This is quite delicate because of the fiddly special-casing for finite products. classical - rw [tprod_def, dif_pos ha] + rw [tprod_def, dite_eq_left ha] split_ifs with h h' · convert! hasProd_prod_support_of_ne_finset_one (s := h.2.toFinset) (L := L) _ using 2 · simp only [Set.inter_eq_left.mpr (show ↑h.2.toFinset ⊆ L.support by simp)] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean b/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean index 4ec7ec8c950bd5..33a9d39006f4b4 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean @@ -283,8 +283,11 @@ theorem tsum_iUnion_le {ι : Type*} [Fintype ι] (f : α → ℝ≥0∞) (t : ι theorem tsum_union_le (f : α → ℝ≥0∞) (s t : Set α) : ∑' x : ↑(s ∪ t), f x ≤ ∑' x : s, f x + ∑' x : t, f x := - calc ∑' x : ↑(s ∪ t), f x = ∑' x : ⋃ b, cond b s t, f x := tsum_congr_set_coe _ union_eq_iUnion - _ ≤ _ := by simpa using tsum_iUnion_le f (cond · s t) + calc + ∑' x : ↑(s ∪ t), f x = ∑' x : ⋃ b : Bool, if b = true then s else t, f x := + tsum_congr_set_coe _ (by ext x; simp [or_comm]) + _ ≤ _ := by + simpa using tsum_iUnion_le f (fun b : Bool => if b = true then s else t) open scoped Classical in theorem tsum_eq_add_tsum_ite {f : β → ℝ≥0∞} (b : β) : diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean index 089c65ef760b25..59ab373226bf66 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Group.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Group.lean @@ -78,7 +78,7 @@ theorem HasProd.update [L.LeAtTop] (hf : HasProd f a₁ L) (b : β) [DecidableEq by_cases h : b' = b · rw [h, update_self] simp - · simp only [h, update_of_ne, if_false, Ne, one_mul, not_false_iff] + · simp only [h, update_of_ne, ite_false, Ne, one_mul, not_false_iff] @[to_additive] theorem Multipliable.update [L.LeAtTop] (hf : Multipliable f L) (b : β) [DecidableEq β] (a : α) : diff --git a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean index 87629f9031603f..ac21ba68d58fe9 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean @@ -425,12 +425,12 @@ theorem HasProd.nat_mul_neg {f : ℤ → M} (hf : HasProd f m) : congr 1 refine (prod_subset_one_on_sdiff inter_subset_union ?_ ?_).symm · intro x hx - suffices x ≠ 0 by simp only [this, if_false] + suffices x ≠ 0 by simp only [this, ite_false] rintro rfl simp [u1, u2] at hx · intro x hx simp only [u1, u2, mem_inter, mem_image] at hx - suffices x = 0 by simp only [this, if_true] + suffices x = 0 by simp only [this, ite_true] lia _ = (∏ x ∈ u1, f x) * ∏ x ∈ u2, f x := prod_union_inter _ = (∏ b ∈ v', f b) * ∏ b ∈ v', f (-b) := by simp [u1, u2] diff --git a/Mathlib/Topology/Algebra/Module/Equiv.lean b/Mathlib/Topology/Algebra/Module/Equiv.lean index 41e0872183e6e0..4aa1346bb57684 100644 --- a/Mathlib/Topology/Algebra/Module/Equiv.lean +++ b/Mathlib/Topology/Algebra/Module/Equiv.lean @@ -1080,7 +1080,7 @@ theorem inverse_equiv (e : M ≃L[R] M₂) : inverse (e : M →L[R] M₂) = e.sy /-- By definition, if `f` is not invertible then `inverse f = 0`. -/ @[simp] lemma inverse_of_not_isInvertible {f : M →L[R] M₂} (hf : ¬ f.IsInvertible) : f.inverse = 0 := - dif_neg hf + dite_eq_right hf @[simp] theorem isInvertible_zero_iff : diff --git a/Mathlib/Topology/Algebra/UniformField.lean b/Mathlib/Topology/Algebra/UniformField.lean index 8f853c718e5b0f..60235fa1654553 100644 --- a/Mathlib/Topology/Algebra/UniformField.lean +++ b/Mathlib/Topology/Algebra/UniformField.lean @@ -115,7 +115,7 @@ theorem coe_inv (x : K) : (x : hat K)⁻¹ = ((x⁻¹ : K) : hat K) := by norm_cast simp · conv_lhs => dsimp [Inv.inv] - rw [if_neg] + rw [ite_eq_right] · exact hatInv_extends h · exact fun H => h (isDenseEmbedding_coe.injective H) @@ -147,7 +147,7 @@ theorem mul_hatInv_cancel {x : hat K} (x_ne : x ≠ 0) : x * hatInv x = 1 := by rwa [closure_singleton, mem_singleton_iff] at fxclo instance instField : Field (hat K) where - mul_inv_cancel := fun x x_ne => by simp only [Inv.inv, if_neg x_ne, mul_hatInv_cancel x_ne] + mul_inv_cancel := fun x x_ne => by simp only [Inv.inv, ite_eq_right x_ne, mul_hatInv_cancel x_ne] inv_zero := by simp only [Inv.inv, ite_true] -- TODO: use a better defeq nnqsmul := _ @@ -164,7 +164,7 @@ instance : IsTopologicalDivisionRing (hat K) := intro y y_ne rw [mem_compl_singleton_iff] at y_ne dsimp [Inv.inv] - rw [if_neg y_ne] + rw [ite_eq_right y_ne] mem_of_superset (compl_singleton_mem_nhds x_ne) this exact ContinuousAt.congr (continuous_hatInv x_ne) this } diff --git a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean index de3604c9b4a537..dbdf58d5d31040 100644 --- a/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean +++ b/Mathlib/Topology/Algebra/Valued/LocallyCompact.lean @@ -280,7 +280,7 @@ lemma locallyFiniteOrder_units_mrange_of_isCompact_integer (hc : IsCompact (X := · simp only [Set.mem_ofPred_eq, hc, Subtype.coe_le_coe, Units.val_le_val] at hj' simp [hcj, le_antisymm hj' hzi] · simp only [Set.mem_ofPred_eq] at hj' - rw [dif_neg hcj] + rw [dite_eq_right hcj] simp [← hj', hc] lemma mulArchimedean_mrange_of_isCompact_integer (hc : IsCompact (X := K) 𝒪[K]) : diff --git a/Mathlib/Topology/Algebra/Valued/ValuedField.lean b/Mathlib/Topology/Algebra/Valued/ValuedField.lean index 235700f18d270d..ea878d63cdd7c7 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuedField.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuedField.lean @@ -450,7 +450,7 @@ noncomputable def valueGroup₀_hom_extensionValuation : · simpa [← hx, hx0] using hxy · by_cases hy0 : y = 0 · simpa [← hy, hy0] using hxy - · rw [dif_neg, dif_neg, dif_neg] + · rw [dite_eq_right, dite_eq_right, dite_eq_right] · simp only [← WithZero.coe_mul, MulMemClass.mk_mul_mk, WithZero.coe_inj, Subtype.mk.injEq] rw [← Units.mk0_mul] · ext @@ -529,15 +529,15 @@ noncomputable instance valuedCompletion : Valued (hat K) Γ₀ where rw [embedding_strictMono.lt_iff_lt, Valuation.restrict_def, restrict₀_apply] by_cases hx0 : x = 0 · simp only [hx0] - rw [dif_pos (map_zero _)] + rw [dite_eq_left (map_zero _)] · simp only [valueGroup₀_equiv_extensionValuation, valueGroup₀_hom_extensionValuation, MulEquiv.ofBijective_apply, coe_mk, ZeroHom.coe_mk] - rw [Valuation.restrict_def, restrict₀_apply, dif_neg] + rw [Valuation.restrict_def, restrict₀_apply, dite_eq_right] · have hext : hv.extension 0 = 0 := by rw [extension_eq_zero_iff] simp [hext] · simp [← v.restrict.zero_iff, v.restrict_def, (restrict₀_surjective (.ofClass hv.v) _).choose_spec] - · rw [dif_neg (by simp [hx0])] + · rw [dite_eq_right (by simp [hx0])] · set y := (restrict₀_surjective (.ofClass hv.v) γ).choose with hy_def have hy := (restrict₀_surjective (.ofClass hv.v) γ).choose_spec apply_fun embedding at hy @@ -545,7 +545,7 @@ noncomputable instance valuedCompletion : Valued (hat K) Γ₀ where simp only [coe_ofClass, extensionValuation_toFun, valueGroup₀_equiv_extensionValuation, valueGroup₀_hom_extensionValuation, MulEquiv.ofBijective_apply, coe_mk, ZeroHom.coe_mk] - rw [Valuation.restrict_def, restrict₀_apply, ← hy_def, dif_neg] + rw [Valuation.restrict_def, restrict₀_apply, ← hy_def, dite_eq_right] · simp only [coe_ofClass, extensionValuation_toFun, extension_extends, Valuation.embedding_restrict, WithZero.coe_lt_coe, Subtype.mk_lt_mk, ← Units.val_lt_val, Units.val_mk0] diff --git a/Mathlib/Topology/Bases.lean b/Mathlib/Topology/Bases.lean index 9b1badd9e13844..010e4249e3e32b 100644 --- a/Mathlib/Topology/Bases.lean +++ b/Mathlib/Topology/Bases.lean @@ -428,7 +428,7 @@ instance {ι : Type*} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [∀ i, choose y hyt hyu using this lift y to ∀ i : I, t i using hyt refine ⟨f ⟨I, y⟩, huU fun i (hi : i ∈ I) ↦ ?_, mem_range_self (f := f) ⟨I, y⟩⟩ - simp only [f, dif_pos hi] + simp only [f, dite_eq_left hi] exact hyu ⟨i, _⟩ instance [SeparableSpace α] {r : α → α → Prop} : SeparableSpace (Quot r) := @@ -538,7 +538,7 @@ theorem IsSeparable.univ_pi {ι : Type*} [Countable ι] {X : ι → Type*} {s : suffices H : ∀ i ∈ I, (u i ∩ c i).Nonempty by choose f hfu hfc using H refine ⟨fun i ↦ ⟨f i i.2, hfc i i.2⟩, fun i (hi : i ∈ I) ↦ ?_⟩ - simpa only [g, dif_pos hi] using hfu i hi + simpa only [g, dite_eq_left hi] using hfu i hi intro i hi exact mem_closure_iff.1 (hc i <| hf _ trivial) _ (huo i hi).1 (huo i hi).2 @@ -644,7 +644,7 @@ lemma isOpenMap_eval (i : ι) : IsOpenMap (Function.eval i : (∀ i, X i) → X by_cases hi : i ∈ s · rw [eval_image_pi (mod_cast hi) h] exact hU _ hi - · rw [eval_image_pi_of_notMem (mod_cast hi), if_pos h] + · rw [eval_image_pi_of_notMem (mod_cast hi), ite_eq_left h] exact isOpen_univ end diff --git a/Mathlib/Topology/Basic.lean b/Mathlib/Topology/Basic.lean index e7713e564a954f..7ebe9780859a7a 100644 --- a/Mathlib/Topology/Basic.lean +++ b/Mathlib/Topology/Basic.lean @@ -237,7 +237,7 @@ theorem limUnder_of_not_tendsto [hX : Nonempty X] {f : Filter α} {g : α → X} (h : ¬ ∃ x, Tendsto g f (𝓝 x)) : limUnder f g = Classical.choice hX := by simp_rw [Tendsto] at h - simp_rw [limUnder, lim, Classical.epsilon, Classical.strongIndefiniteDescription, dif_neg h] + simp_rw [limUnder, lim, Classical.epsilon, Classical.strongIndefiniteDescription, dite_eq_right h] end lim diff --git a/Mathlib/Topology/Category/LightProfinite/Basic.lean b/Mathlib/Topology/Category/LightProfinite/Basic.lean index 51a5db192502cd..1523aa61238e1a 100644 --- a/Mathlib/Topology/Category/LightProfinite/Basic.lean +++ b/Mathlib/Topology/Category/LightProfinite/Basic.lean @@ -224,12 +224,12 @@ theorem epi_iff_surjective {X Y : LightProfinite.{u}} (f : X ⟶ Y) : ext x dsimp [g, LocallyConstant.ofIsClopen] rw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, hom_ofHom, ContinuousMap.coe_mk, - Function.comp_apply, if_neg] + Function.comp_apply, ite_eq_right] refine mt (fun α => hVU α) ?_ simp [U, C] apply_fun fun e => (e y).down at H dsimp [g, LocallyConstant.ofIsClopen] at H - rw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, Function.comp_apply, if_pos hyV] at H + rw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, Function.comp_apply, ite_eq_left hyV] at H exact top_ne_bot H · rw [← CategoryTheory.ofHom_epi_iff_surjective] apply (forget LightProfinite).epi_of_epi_map diff --git a/Mathlib/Topology/Category/Profinite/Basic.lean b/Mathlib/Topology/Category/Profinite/Basic.lean index 6021ee80649efb..4b6a5953d00770 100644 --- a/Mathlib/Topology/Category/Profinite/Basic.lean +++ b/Mathlib/Topology/Category/Profinite/Basic.lean @@ -248,12 +248,12 @@ theorem epi_iff_surjective {X Y : Profinite.{u}} (f : X ⟶ Y) : Epi f ↔ Funct ext x dsimp [g, LocallyConstant.ofIsClopen] rw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, ConcreteCategory.hom_ofHom, - ContinuousMap.coe_mk, Function.comp_apply, if_neg] + ContinuousMap.coe_mk, Function.comp_apply, ite_eq_right] refine mt (fun α => hVU α) ?_ simp [U, C] apply_fun fun e => (e y).down at H dsimp [g, LocallyConstant.ofIsClopen] at H - rw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, Function.comp_apply, if_pos hyV] at H + rw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, Function.comp_apply, ite_eq_left hyV] at H exact top_ne_bot H · rw [← CategoryTheory.ofHom_epi_iff_surjective] apply (forget Profinite).epi_of_epi_map diff --git a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean index ec025ce5116a93..bec602a4610d99 100644 --- a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean +++ b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean @@ -87,7 +87,7 @@ theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsCl · apply isClopen_biUnion_finset intro s hs dsimp [W] - rw [dif_pos hs] + rw [dite_eq_left hs] exact ⟨(hV s).1.1.preimage (F.map _).hom.hom.continuous, (hV s).1.2.preimage (F.map _).hom.hom.continuous⟩ · ext x @@ -96,14 +96,14 @@ theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsCl simp_rw [W, Set.preimage_iUnion, Set.mem_iUnion] obtain ⟨_, ⟨s, rfl⟩, _, ⟨hs, rfl⟩, hh⟩ := hG hx refine ⟨s, hs, ?_⟩ - rwa [dif_pos hs, ← Set.preimage_comp, ← CompHausLike.coe_comp, C.w] + rwa [dite_eq_left hs, ← Set.preimage_comp, ← CompHausLike.coe_comp, C.w] · intro hx simp_rw [W, Set.preimage_iUnion, Set.mem_iUnion] at hx obtain ⟨s, hs, hx⟩ := hx rw [h] refine ⟨s.1, s.2, ?_⟩ rw [(hV s).2] - rwa [dif_pos hs, ← Set.preimage_comp, ← CompHausLike.coe_comp, C.w] at hx + rwa [dite_eq_left hs, ← Set.preimage_comp, ← CompHausLike.coe_comp, C.w] at hx set_option backward.isDefEq.respectTransparency false in theorem exists_locallyConstant_fin_two (hC : IsLimit C) (f : LocallyConstant C.pt (Fin 2)) : @@ -171,7 +171,7 @@ theorem exists_locallyConstant_finite_nonempty {α : Type*} [Finite α] [Nonempt rw [h] rfl have h2 : ∃ a : α, ι a = gg (C.π.app j x) := ⟨f x, h1⟩ - rw [dif_pos] + rw [dite_eq_left] swap · assumption apply_fun ι @@ -180,7 +180,7 @@ theorem exists_locallyConstant_finite_nonempty {α : Type*} [Finite α] [Nonempt · intro a b hh have hhh := congr_fun hh a dsimp [ι] at hhh - rw [if_pos rfl] at hhh + rw [ite_eq_left rfl] at hhh split_ifs at hhh with hh1 · exact hh1.symm · exact False.elim (bot_ne_top hhh) diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean index c547cd151f17d9..d03a8d2df25f8b 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Basic.lean @@ -153,7 +153,7 @@ set_option backward.isDefEq.respectTransparency.types false in variable (J) in theorem projRestricts_eq_id : ProjRestricts C (fun i (h : J i) ↦ h) = id := by ext ⟨x, y, hy, rfl⟩ i - simp +contextual only [π, Proj, ProjRestricts_coe, id_eq, if_true] + simp +contextual only [π, Proj, ProjRestricts_coe, id_eq, ite_true] set_option backward.isDefEq.respectTransparency.types false in theorem projRestricts_eq_comp (hJK : ∀ i, J i → K i) (hKL : ∀ i, K i → L i) : @@ -189,12 +189,12 @@ lemma iso_map_bijective : Function.Bijective (iso_map C J) := by · exact congr_fun h ⟨i, hi⟩ · rcases a with ⟨_, c, hc, rfl⟩ rcases b with ⟨_, d, hd, rfl⟩ - simp only [Proj, if_neg hi] + simp only [Proj, ite_eq_right hi] · refine ⟨⟨fun i ↦ if hi : J i then a.val ⟨i, hi⟩ else false, ?_⟩, ?_⟩ · rcases a with ⟨_, y, hy, rfl⟩ exact ⟨y, hy, rfl⟩ · ext i - exact dif_pos i.prop + exact dite_eq_left i.prop variable {C} @@ -238,7 +238,7 @@ noncomputable def spanFunctorIsoIndexFunctor ext x have : iso_map C (· ∈ t) ∘ ProjRestricts C f = IndexFunctor.map C f ∘ iso_map C (· ∈ s) := by - ext _ i; exact dif_pos i.prop + ext _ i; exact dite_eq_left i.prop exact congr_fun this x) /-- `spanCone` is a limit cone. -/ @@ -249,7 +249,7 @@ def spanCone_isLimit [∀ (s : Finset I) (i : I), Decidable (i ∈ s)] (hC : IsC (IsLimit.ofIsoLimit (indexCone_isLimit hC) (Cone.ext (Iso.refl _) (fun ⟨s⟩ ↦ by ext have : iso_map C (· ∈ s) ∘ ProjRestrict C (· ∈ s) = IndexFunctor.π_app C (· ∈ s) := by - ext _ i; exact dif_pos i.prop + ext _ i; exact dite_eq_left i.prop exact congr_fun this.symm _))) end Projections @@ -392,7 +392,7 @@ theorem eval_eq (l : Products I) (x : C) : apply List.prod_eq_one simp only [List.mem_map, Function.comp_apply] rintro _ ⟨i, hi, rfl⟩ - exact if_pos (h i hi) + exact ite_eq_left (h i hi) · simp only [List.map_map, List.prod_eq_zero_iff, List.mem_map, Function.comp_apply] push Not at h convert! h with i @@ -426,7 +426,7 @@ theorem prop_of_isGood {l : Products I} (J : I → Prop) [∀ j, Decidable (J j) rw [this] exact Submodule.zero_mem _ ext ⟨_, _, _, rfl⟩ - rw [eval_eq, if_neg fun h ↦ ?_, LocallyConstant.zero_apply] + rw [eval_eq, ite_eq_right fun h ↦ ?_, LocallyConstant.zero_apply] simpa [Proj, h'] using h i hi end Products diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean index cbef1d3551ca73..62ff68b15332c0 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Span.lean @@ -62,7 +62,7 @@ instance : Fintype (π C (· ∈ s)) := by ext i by_cases hi : i ∈ s · exact congrFun h ⟨i, hi⟩ - · simp only [Proj, if_neg hi] + · simp only [Proj, ite_eq_right hi] open scoped Classical in /-- The Kronecker delta as a locally constant map from `π C (· ∈ s)` to `ℤ`. -/ @@ -105,15 +105,16 @@ theorem factors_prod_eq_basis_of_eq {x y : (π C fun x ↦ x ∈ s)} (h : y = x) rintro _ ⟨a, ⟨b, _, rfl⟩, rfl⟩ dsimp split_ifs with hh - · rw [e, LocallyConstant.coe_mk, if_pos hh] - · rw [LocallyConstant.sub_apply, e, LocallyConstant.coe_mk, LocallyConstant.coe_mk, if_neg hh] + · rw [e, LocallyConstant.coe_mk, ite_eq_left hh] + · rw [LocallyConstant.sub_apply, e, LocallyConstant.coe_mk, LocallyConstant.coe_mk, + ite_eq_right hh] simp only [LocallyConstant.toFun_eq_coe, LocallyConstant.coe_one, Pi.one_apply, sub_zero] theorem e_mem_of_eq_true {x : (π C (· ∈ s))} {a : I} (hx : x.val a = true) : e (π C (· ∈ s)) a ∈ factors C s x := by rcases x with ⟨_, z, hz, rfl⟩ simp only [factors, List.mem_map, Finset.mem_sort] - refine ⟨a, ?_, if_pos hx⟩ + refine ⟨a, ?_, ite_eq_left hx⟩ aesop (add simp Proj) theorem one_sub_e_mem_of_false {x y : (π C (· ∈ s))} {a : I} (ha : y.val a = true) @@ -134,10 +135,10 @@ theorem factors_prod_eq_basis_of_ne {x y : (π C (· ∈ s))} (h : y ≠ x) : · rw [hx, ne_eq, Bool.not_eq_false] at ha refine ⟨1 - (e (π C (· ∈ s)) a), ⟨one_sub_e_mem_of_false _ _ ha hx, ?_⟩⟩ rw [e, LocallyConstant.evalMonoidHom_apply, LocallyConstant.sub_apply, - LocallyConstant.coe_one, Pi.one_apply, LocallyConstant.coe_mk, if_pos ha, sub_self] + LocallyConstant.coe_one, Pi.one_apply, LocallyConstant.coe_mk, ite_eq_left ha, sub_self] · refine ⟨e (π C (· ∈ s)) a, ⟨e_mem_of_eq_true _ _ hx, ?_⟩⟩ rw [hx] at ha - rw [LocallyConstant.evalMonoidHom_apply, e, LocallyConstant.coe_mk, if_neg ha] + rw [LocallyConstant.evalMonoidHom_apply, e, LocallyConstant.coe_mk, ite_eq_right ha] /-- If `s` is finite, the product of the elements of the list `factors C s x` is the delta function at `x`. -/ diff --git a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean index 126fe2f46aaaf9..37c048e5b420d0 100644 --- a/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean +++ b/Mathlib/Topology/Category/Profinite/Nobeling/Successor.lean @@ -477,7 +477,7 @@ theorem Products.max_eq_eval [Inhabited I] (l : Products I) (hl : l.val ≠ []) apply forall_congr; intro i; apply forall_congr; intro hi; rw [hi' i hi] simp only [H] split_ifs with h₁ h₂ h₃ <;> try (dsimp [e]) - · rw [if_pos (swapTrue_eq_true _ _), if_neg] + · rw [ite_eq_left (swapTrue_eq_true _ _), ite_eq_right] · rfl · simp [mem_C'_eq_false C ho x x.prop] · push Not at h₂; obtain ⟨i, hi⟩ := h₂; exfalso; rw [hi' i hi.1] at hi; exact hi.2 (h₁ i hi.1) diff --git a/Mathlib/Topology/Category/Stonean/Basic.lean b/Mathlib/Topology/Category/Stonean/Basic.lean index ae6333485f8843..c8f3f0ee599831 100644 --- a/Mathlib/Topology/Category/Stonean/Basic.lean +++ b/Mathlib/Topology/Category/Stonean/Basic.lean @@ -141,13 +141,13 @@ lemma epi_iff_surjective {X Y : Stonean} (f : X ⟶ Y) : ext x apply ULift.ext -- why is `ext` not doing this automatically? change 1 = ite _ _ _ -- why is `dsimp` not getting me here? - rw [if_neg] + rw [ite_eq_right] refine mt (hVU ·) ?_ -- what would be an idiomatic tactic for this step? simpa only [U, Set.mem_compl_iff, Set.mem_range, not_exists, not_forall, not_not] using! exists_apply_eq_apply f x apply_fun fun e => (e y).down at H change 1 = ite _ _ _ at H -- why is `dsimp at H` not getting me here? - rw [if_pos hyV] at H + rw [ite_eq_left hyV] at H exact one_ne_zero H /-- Every Stonean space is projective in `CompHaus` -/ diff --git a/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean b/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean index a54939b506bd73..8b7aa0a966a367 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean @@ -85,7 +85,7 @@ theorem isTopologicalBasis_cofiltered_limit (hC : IsLimit C) (T : ∀ j, Set (Se refine this _ _ _ (univ _) (inter _) ?_ intro e he dsimp [Vs] - rw [dif_pos he] + rw [dite_eq_left he] exact compat j e (g e he) (U e) (h1 e he) · -- conclude... rw [h2] @@ -96,7 +96,7 @@ theorem isTopologicalBasis_cofiltered_limit (hC : IsLimit C) (T : ∀ j, Set (Se rw [Set.preimage_iInter] apply congrArg ext1 he - simp [Vs, dif_pos he, ← Set.preimage_comp, ← coe_comp] + simp [Vs, dite_eq_left he, ← Set.preimage_comp, ← coe_comp] end CofilteredLimit diff --git a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean index 9a534c7e789e48..b203d3a2f69f20 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Konig.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Konig.lean @@ -79,7 +79,8 @@ theorem partialSections.nonempty [IsCofilteredOrEmpty J] [h : ∀ j : J, Nonempt else (h _).some rintro ⟨X, Y, hX, hY, f⟩ hf dsimp only - rwa [dif_pos hX, dif_pos hY, ← comp_app, ← F.map_comp, @IsCofiltered.infTo_commutes _ _ _ G H] + rwa [dite_eq_left hX, dite_eq_left hY, ← comp_app, ← F.map_comp, + @IsCofiltered.infTo_commutes _ _ _ G H] set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index de6303f57eff6c..30cc9943356347 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -287,7 +287,7 @@ theorem binaryCofan_isColimit_iff {X Y : TopCat.{u}} (c : BinaryCofan X Y) : · rw [continuousOn_iff_continuous_domRestrict] convert_to Continuous (f ∘ h₁.isEmbedding.toHomeomorph.symm) · ext ⟨x, hx⟩ - exact dif_pos hx + exact dite_eq_left hx fun_prop · exact h₁.isOpen_range · revert h x @@ -300,7 +300,7 @@ theorem binaryCofan_isColimit_iff {X Y : TopCat.{u}} (c : BinaryCofan X Y) : convert_to! Continuous (g ∘ h₂.isEmbedding.toHomeomorph.symm ∘ Subtype.map _ this) · ext ⟨x, hx⟩ - exact dif_neg hx + exact dite_eq_right hx apply Continuous.comp · exact g.hom.continuous_toFun · apply Continuous.comp (by fun_prop) @@ -315,7 +315,7 @@ theorem binaryCofan_isColimit_iff {X Y : TopCat.{u}} (c : BinaryCofan X Y) : · intro T f g ext x dsimp - rw [dif_neg] + rw [dite_eq_right] · exact congr_arg g (Equiv.ofInjective_symm_apply _ _) · rintro ⟨y, e⟩ have : c.inr x ∈ Set.range c.inl ⊓ Set.range c.inr := ⟨⟨_, e⟩, ⟨_, rfl⟩⟩ diff --git a/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean b/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean index 81be1cd54b4d36..301818c1cbaf2a 100644 --- a/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean +++ b/Mathlib/Topology/Compactification/OnePoint/ProjectiveLine.lean @@ -93,8 +93,8 @@ def equivProjectivization : OnePoint K ≃ ℙ K (Fin 2 → K) where left_inv p := by cases p <;> simp right_inv p := by induction p using ind with | h w hw => - by_cases h₀ : w 1 = 0 <;> simp only [mk_eq_mk_iff', h₀, Projectivization.lift_mk, if_true, - if_false, OnePoint.elim_infty, OnePoint.elim_some] + by_cases h₀ : w 1 = 0 <;> simp only [mk_eq_mk_iff', h₀, Projectivization.lift_mk, ite_true, + ite_false, OnePoint.elim_infty, OnePoint.elim_some] · have : w 0 ≠ 0 := fun h ↦ hw <| funext <| by simp_all use (w 0)⁻¹ ext i @@ -204,7 +204,7 @@ lemma IsParabolic.smul_eq_self_iff {g : GL (Fin 2) K} (hg : g.IsParabolic) [NeZe refine fun hb ↦ fixpointPolynomial_eq_zero_iff.not.mpr hg ?_ simp [fixpointPolynomial, hb, hc, hd] · have : discrim (g 1 0) (g 1 1 - g 0 0) (-g 0 1) = 0 := by rw [discrim]; grind - simpa [parabolicFixedPoint, if_neg hc, sq, sub_eq_add_neg] + simpa [parabolicFixedPoint, ite_eq_right hc, sq, sub_eq_add_neg] using quadratic_eq_zero_iff_of_discrim_eq_zero hc this c lemma IsParabolic.parabolicFixedPoint_pow {g : GL (Fin 2) K} (hg : IsParabolic g) [CharZero K] diff --git a/Mathlib/Topology/Compactness/LocallyCompact.lean b/Mathlib/Topology/Compactness/LocallyCompact.lean index b8199e7196ef54..a8daae99ac29b2 100644 --- a/Mathlib/Topology/Compactness/LocallyCompact.lean +++ b/Mathlib/Topology/Compactness/LocallyCompact.lean @@ -120,9 +120,9 @@ instance Pi.locallyCompactSpace [∀ i, CompactSpace (X i)] : LocallyCompactSpac rw [← Set.univ_pi_ite] refine isCompact_univ_pi fun i => ?_ by_cases h : i ∈ s - · rw [if_pos h] + · rw [ite_eq_left h] exact hc i - · rw [if_neg h] + · rw [ite_eq_right h] exact CompactSpace.isCompact_univ⟩ instance Function.locallyCompactSpace_of_finite [Finite ι] [LocallyCompactSpace Y] : diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 9b301f937a5563..0efc7f68ed6795 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -507,11 +507,11 @@ noncomputable def connectedComponentIn (F : Set α) (x : α) : Set α := theorem connectedComponentIn_eq_image {F : Set α} {x : α} (h : x ∈ F) : connectedComponentIn F x = (↑) '' connectedComponent (⟨x, h⟩ : F) := - dif_pos h + dite_eq_left h theorem connectedComponentIn_eq_empty {F : Set α} {x : α} (h : x ∉ F) : connectedComponentIn F x = ∅ := - dif_neg h + dite_eq_right h theorem mem_connectedComponent {x : α} : x ∈ connectedComponent x := mem_sUnion_of_mem (mem_singleton x) ⟨isPreconnected_singleton, mem_singleton x⟩ diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index 2b7a4896b7af9c..951f9aa674b54b 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -1088,10 +1088,10 @@ theorem isOpen_pi_iff {s : Set (∀ a, A a)} : refine ⟨I, fun a => ite (a ∈ I) (t a) univ, fun i => ?_, ?_⟩ · by_cases hi : i ∈ I · use t i - simp_rw [if_pos hi] + simp_rw [ite_eq_left hi] exact ⟨Subset.rfl, (h1 i) hi⟩ · use univ - simp_rw [if_neg hi] + simp_rw [ite_eq_right hi] exact ⟨Subset.rfl, isOpen_univ, mem_univ _⟩ · rw [← univ_pi_ite] simp only [← ite_and, ← Finset.mem_coe, and_self_iff, univ_pi_ite, h2] diff --git a/Mathlib/Topology/ContinuousMap/CompactlySupported.lean b/Mathlib/Topology/ContinuousMap/CompactlySupported.lean index 3c40233c08de55..ddb70bfdd2b6ca 100644 --- a/Mathlib/Topology/ContinuousMap/CompactlySupported.lean +++ b/Mathlib/Topology/ContinuousMap/CompactlySupported.lean @@ -141,10 +141,10 @@ noncomputable def compLeft (g : C(β, γ)) (f : C_c(α, β)) : C_c(α, γ) where · exact .zero lemma toContinuousMap_compLeft {g : C(β, γ)} (hg : g 0 = 0) (f : C_c(α, β)) : - (f.compLeft g).toContinuousMap = g.comp f := if_pos hg + (f.compLeft g).toContinuousMap = g.comp f := ite_eq_left hg lemma coe_compLeft {g : C(β, γ)} (hg : g 0 = 0) (f : C_c(α, β)) : f.compLeft g = g ∘ f := by - simp [compLeft, if_pos hg] + simp [compLeft, ite_eq_left hg] lemma compLeft_apply {g : C(β, γ)} (hg : g 0 = 0) (f : C_c(α, β)) (a : α) : f.compLeft g a = g (f a) := by simp [coe_compLeft hg f] diff --git a/Mathlib/Topology/Covering/Basic.lean b/Mathlib/Topology/Covering/Basic.lean index 8b0990a1c623e6..261e55949c80c4 100644 --- a/Mathlib/Topology/Covering/Basic.lean +++ b/Mathlib/Topology/Covering/Basic.lean @@ -100,7 +100,7 @@ set_option backward.isDefEq.respectTransparency.types false in theorem toTrivialization_apply {x : E} [Nonempty I] (h : IsEvenlyCovered f (f x) I) : (h.toTrivialization x).2 = ⟨x, rfl⟩ := h.fiberHomeomorph.symm.injective <| by - simp [toTrivialization, toTrivialization', dif_pos h.2.choose_spec.1, fiberHomeomorph] + simp [toTrivialization, toTrivialization', dite_eq_left h.2.choose_spec.1, fiberHomeomorph] protected theorem continuousAt {x : E} (h : IsEvenlyCovered f (f x) I) : ContinuousAt f x := have ⟨_, _, hxU, _, _, H, _⟩ := h @@ -454,14 +454,14 @@ Then `f` admits a `Bundle.Trivialization` over the base set `V`. -/ source := f ⁻¹' V, target := V ×ˢ Set.univ, map_source' x hx := ⟨hx, ⟨⟩⟩ - map_target' x hx := by rw [dif_pos hx.1]; apply (f_inv _ hx.1).symm ▸ hx.1, + map_target' x hx := by rw [dite_eq_left hx.1]; apply (f_inv _ hx.1).symm ▸ hx.1, left_inv' e he := by - simp_rw [dif_pos (id he : f e ∈ V)] + simp_rw [dite_eq_left (id he : f e ∈ V)] exact inj _ (inv_U _ he) (idx_U e he) (f_inv _ _) right_inv' x hx := by - rw [dif_pos hx.1] + rw [dite_eq_left hx.1] refine Prod.ext (f_inv _ hx.1) ?_ - rw [dif_pos ((f_inv _ hx.1).symm ▸ hx.1)] + rw [dite_eq_left ((f_inv _ hx.1).symm ▸ hx.1)] by_contra h; exact (disjoint h).le_bot ⟨idx_U .., inv_U _ _⟩ } have open_preim {W} (hWV : W ⊆ V) (open_W : IsOpen W) : IsOpen (f ⁻¹' W) := by convert! isOpen_iUnion (fun i ↦ (open_iff i hWV).mp open_W) @@ -484,14 +484,14 @@ Then `f` admits a `Bundle.Trivialization` over the base set `V`. -/ target_eq := rfl, proj_toFun _ _ := rfl } · by_contra h; apply (disjoint h).le_bot - · dsimp only; rw [dif_pos (by exact he'.2)]; exact ⟨he'.1, idx_U ..⟩ + · dsimp only; rw [dite_eq_left (by exact he'.2)]; exact ⟨he'.1, idx_U ..⟩ · rwa [Set.inter_comm, ← open_iff _ subset_rfl] · simp_rw [F, Set.prodMk_mem_set_prod_eq, Set.mem_univ, and_true] refine (continuousOn_open_iff open_V).mpr fun W open_W ↦ ?_ rw [open_iff i Set.inter_subset_left] convert! ((open_iff i subset_rfl).mp open_V).inter open_W using 1 refine Set.ext fun e ↦ and_right_comm.trans (and_congr_right fun ⟨hV, hU⟩ ↦ ?_) - rw [Set.mem_preimage, dif_pos hV, inj i (inv_U i _) hU (f_inv i _)] + rw [Set.mem_preimage, dite_eq_left hV, inj i (inv_U i _) hU (f_inv i _)] variable {s} diff --git a/Mathlib/Topology/EMetricSpace/PairReduction.lean b/Mathlib/Topology/EMetricSpace/PairReduction.lean index 086bc71c47430a..5c277fa68f03af 100644 --- a/Mathlib/Topology/EMetricSpace/PairReduction.lean +++ b/Mathlib/Topology/EMetricSpace/PairReduction.lean @@ -126,12 +126,12 @@ def logSizeRadius (t : T) (V : Finset T) (a c : ℝ≥0∞) : ℕ := lemma one_le_logSizeRadius (ha : 1 < a) : 1 ≤ logSizeRadius t V a c := by - rw [logSizeRadius, dif_pos ha] + rw [logSizeRadius, dite_eq_left ha] exact (Nat.find_spec (exists_radius_le t V ha c)).1 lemma card_le_logSizeRadius_le_pow_logSizeRadius (ha : 1 < a) : #(V.filter fun x ↦ edist t x ≤ logSizeRadius t V a c * c) ≤ a ^ (logSizeRadius t V a c) := by - rw [logSizeRadius, dif_pos ha] + rw [logSizeRadius, dite_eq_left ha] exact (Nat.find_spec (exists_radius_le t V ha c)).2 lemma pow_logSizeRadius_le_card_le_logSizeRadius (ha : 1 < a) (ht : t ∈ V) : @@ -141,7 +141,7 @@ lemma pow_logSizeRadius_le_card_le_logSizeRadius (ha : 1 < a) (ht : t ∈ V) : · simp only [h_one, tsub_self, pow_zero, Nat.cast_one, zero_mul, nonpos_iff_eq_zero, Nat.one_le_cast, Finset.one_le_card] exact ⟨t, by simpa⟩ - rw [logSizeRadius, dif_pos ha] at h_one ⊢ + rw [logSizeRadius, dite_eq_left ha] at h_one ⊢ have : Nat.find (exists_radius_le t V ha c) - 1 < Nat.find (exists_radius_le t V ha c) := by simp have h := Nat.find_min (exists_radius_le t V ha c) this diff --git a/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean b/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean index 02ef52c23a7f0e..110253c4663de6 100644 --- a/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean +++ b/Mathlib/Topology/EMetricSpace/VariationOnFromTo.lean @@ -36,18 +36,18 @@ variable (f : α → E) (s : Set α) protected theorem self (a : α) : variationOnFromTo f s a a = 0 := by dsimp only [variationOnFromTo] - rw [if_pos le_rfl, Icc_self, eVariationOn.subsingleton, ENNReal.toReal_zero] + rw [ite_eq_left le_rfl, Icc_self, eVariationOn.subsingleton, ENNReal.toReal_zero] exact fun x hx y hy => hx.2.trans hy.2.symm protected theorem nonneg_of_le {a b : α} (h : a ≤ b) : 0 ≤ variationOnFromTo f s a b := by - simp only [variationOnFromTo, if_pos h, ENNReal.toReal_nonneg] + simp only [variationOnFromTo, ite_eq_left h, ENNReal.toReal_nonneg] protected theorem eq_neg_swap (a b : α) : variationOnFromTo f s a b = -variationOnFromTo f s b a := by rcases lt_trichotomy a b with (ab | rfl | ba) - · simp only [variationOnFromTo, if_pos ab.le, if_neg ab.not_ge, neg_neg] + · simp only [variationOnFromTo, ite_eq_left ab.le, ite_eq_right ab.not_ge, neg_neg] · simp only [variationOnFromTo.self, neg_zero] - · simp only [variationOnFromTo, if_pos ba.le, if_neg ba.not_ge] + · simp only [variationOnFromTo, ite_eq_left ba.le, ite_eq_right ba.not_ge] protected theorem nonpos_of_ge {a b : α} (h : b ≤ a) : variationOnFromTo f s a b ≤ 0 := by rw [variationOnFromTo.eq_neg_swap] @@ -64,7 +64,7 @@ theorem abs_le_eVariationOn (hf : BoundedVariationOn f s) {a b : α} : protected theorem eq_of_le {a b : α} (h : a ≤ b) : variationOnFromTo f s a b = (eVariationOn f (s ∩ Icc a b)).toReal := - if_pos h + ite_eq_left h protected theorem eq_of_ge {a b : α} (h : b ≤ a) : variationOnFromTo f s a b = -(eVariationOn f (s ∩ Icc b a)).toReal := by diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index 3e939884409947..91b5e7139bf1f2 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -238,7 +238,7 @@ protected noncomputable def symm (e : Pretrivialization F (π F E)) (b : B) (y : theorem symm_apply (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : F) : e.symm b y = cast (congr_arg E (e.symm_coe_proj hb)) (e.toPartialEquiv.symm (b, y)).2 := - dif_pos hb + dite_eq_left hb @[deprecated "The junk values of `Pretrivialization.symm` were changed from `0` to `Classical.arbitrary` and should not be relied on; this lemma will be removed soon. Note that this @@ -291,13 +291,13 @@ noncomputable def restrictPreimage' (e : Pretrivialization F proj) (s : Set B) simpa only [Prod.map_apply, ← e.proj_toFun _ hz] using! e.map_source' hz map_target' x hx := by simp only [mem_preimage, (Prod.map_apply), id_eq] at hx - rw [dif_pos hx]; exact e.map_target' hx + rw [dite_eq_left hx]; exact e.map_target' hx left_inv' z hz := by - dsimp only; rw [dif_pos] <;> all_goals simp_rw [← e.proj_toFun _ hz] + dsimp only; rw [dite_eq_left] <;> all_goals simp_rw [← e.proj_toFun _ hz] exacts [Subtype.ext (e.left_inv' hz), e.map_source' hz] right_inv' x hx := Subtype.val_injective.prodMap injective_id <| by simp only [mem_preimage, (Prod.map_apply), id_eq] at hx - simp_rw [Prod.map_apply]; rw [dif_pos hx] + simp_rw [Prod.map_apply]; rw [dite_eq_left hx] convert! ← e.right_inv' hx; exact e.proj_toFun _ (e.map_target' hx) open_target := e.open_target.preimage <| by fun_prop baseSet := Subtype.val ⁻¹' e.baseSet @@ -328,7 +328,7 @@ noncomputable def domExtend {s : Set B} (e : Pretrivialization F fun z : proj simpa [hzp, e.coe_fst hze] using e.map_source hze map_target' x hx := by simpa using ⟨(e.invFun x).2, e.map_target hx⟩ left_inv' _ := by rintro ⟨⟨z, hzp : proj z ∈ s⟩, hze, rfl⟩; simp [hzp, e.symm_apply_apply hze] - right_inv' x hx := (dif_pos (e.invFun x).2).trans (e.right_inv hx) + right_inv' x hx := (dite_eq_left (e.invFun x).2).trans (e.right_inv hx) open_target := e.open_target baseSet := e.baseSet open_baseSet := e.open_baseSet @@ -690,7 +690,7 @@ protected noncomputable def symm (e : Trivialization F (π F E)) (b : B) (y : F) theorem symm_apply (e : Trivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : F) : e.symm b y = cast (congr_arg E (e.symm_coe_proj hb)) (e.toOpenPartialHomeomorph.symm (b, y)).2 := - dif_pos hb + dite_eq_left hb @[deprecated "The junk values of `Trivialization.symm` were changed from `0` to `Classical.arbitrary` and should not be relied on; this lemma will be removed soon. Note that this @@ -831,7 +831,7 @@ noncomputable def restrictPreimage' (e : Trivialization F proj) (s : Set B) fun z hz ↦ by ext; exacts [(e.proj_toFun _ hz).symm, rfl] continuousOn_invFun := Topology.IsInducing.subtypeVal.continuousOn_iff.mpr <| (e.continuousOn_invFun.comp (continuous_subtype_val.prodMap continuous_id).continuousOn - fun _ ↦ id).congr fun x hx ↦ congr_arg Subtype.val (dif_pos hx) + fun _ ↦ id).congr fun x hx ↦ congr_arg Subtype.val (dite_eq_left hx) /-- The restriction of a trivialization to a set with nonempty intersection with the base set. -/ @[simps! apply source target baseSet] @@ -851,7 +851,7 @@ noncomputable def domExtend {s : Set B} (hps : IsOpen (proj ⁻¹' s)) continuousOn_toFun := Topology.IsInducing.subtypeVal.continuousOn_image_iff.mpr <| by convert! e.continuousOn_toFun ext1 ⟨x, (hx : proj x ∈ s)⟩ - simpa [Pretrivialization.domExtend] using! dif_pos hx + simpa [Pretrivialization.domExtend] using! dite_eq_left hx continuousOn_invFun := continuous_subtype_val.comp_continuousOn <| by convert! e.continuousOn_invFun diff --git a/Mathlib/Topology/Homotopy/HSpaces.lean b/Mathlib/Topology/Homotopy/HSpaces.lean index 6ff9e9a8344ad2..f060115fb5ce64 100644 --- a/Mathlib/Topology/Homotopy/HSpaces.lean +++ b/Mathlib/Topology/Homotopy/HSpaces.lean @@ -211,7 +211,7 @@ theorem delayReflRight_zero (γ : Path x y) : delayReflRight 0 γ = γ.trans (Pa split_ifs with h; swap on_goal 1 => conv_rhs => rw [← γ.target] all_goals apply congr_arg γ; ext1; rw [qRight_zero_right] - exacts [if_neg h, if_pos h] + exacts [ite_eq_right h, ite_eq_left h] theorem delayReflRight_one (γ : Path x y) : delayReflRight 1 γ = γ := by ext t diff --git a/Mathlib/Topology/Homotopy/HomotopyGroup.lean b/Mathlib/Topology/Homotopy/HomotopyGroup.lean index a0ddb6db8c8530..369e96f60f6b5f 100644 --- a/Mathlib/Topology/Homotopy/HomotopyGroup.lean +++ b/Mathlib/Topology/Homotopy/HomotopyGroup.lean @@ -73,8 +73,8 @@ abbrev insertAt (i : N) : (I × I^{ j // j ≠ i }) ≃ₜ I^N := theorem insertAt_boundary (i : N) {t₀ : I} {t} (H : (t₀ = 0 ∨ t₀ = 1) ∨ t ∈ boundary { j // j ≠ i }) : insertAt i ⟨t₀, t⟩ ∈ boundary N := by obtain H | ⟨j, H⟩ := H - · use i; rwa [funSplitAt_symm_apply, dif_pos rfl] - · use j; rwa [funSplitAt_symm_apply, dif_neg j.prop, Subtype.coe_eta] + · use i; rwa [funSplitAt_symm_apply, dite_eq_left rfl] + · use j; rwa [funSplitAt_symm_apply, dite_eq_right j.prop, Subtype.coe_eta] end Cube @@ -364,7 +364,7 @@ theorem homotopicTo (i : N) {p q : Ω^ N X x} : dsimp rw [homotopyTo_apply] apply H.eq_fst; use i - rw [funSplitAt_symm_apply, dif_pos rfl]; exact yH + rw [funSplitAt_symm_apply, dite_eq_left rfl]; exact yH /-- The converse to `GenLoop.homotopyTo`: a homotopy between two loops in the space of `n`-dimensional loops can be seen as a homotopy between two `n+1`-dimensional paths. -/ @@ -419,7 +419,7 @@ def symmAt (i : N) (f : Ω^ N X x) : Ω^ N X x := theorem transAt_distrib {i j : N} (h : i ≠ j) (a b c d : Ω^ N X x) : transAt i (transAt j a b) (transAt j c d) = transAt j (transAt i a c) (transAt i b d) := by - ext; simp_rw [transAt, coe_copy, Function.update_apply, if_neg h, if_neg h.symm] + ext; simp_rw [transAt, coe_copy, Function.update_apply, ite_eq_right h, ite_eq_right h.symm] split_ifs <;> · congr 1; ext1; simp only [Function.update, eq_rec_constant, dite_eq_ite] apply ite_ite_comm; rintro rfl; exact h.symm diff --git a/Mathlib/Topology/Homotopy/Lifting.lean b/Mathlib/Topology/Homotopy/Lifting.lean index 8886cdcacbb203..9a94b543849479 100644 --- a/Mathlib/Topology/Homotopy/Lifting.lean +++ b/Mathlib/Topology/Homotopy/Lifting.lean @@ -100,7 +100,7 @@ theorem exists_lift_nhds {f : C(I × A, X)} {g : I × A → E} (g_lifts : p ∘ · rw [← t_0]; exact ⟨t_mono n.zero_le, le_rfl⟩ · have ht := Set.mem_ofPred.mp (frontier_le_subset_eq continuous_fst continuous_const hfr) have : f ta ∈ (q e).target := huv ⟨hu (by rw [ht]; exact ⟨le_rfl, t_mono n.le_succ⟩), hav⟩ - rw [if_pos this] + rw [ite_eq_left this] -- here we use that {tₙ} × Nₙ₊₁ is mapped to the domain of `q e` apply (q e).injOn (by rwa [← ta.eta, ht]) ((q e).map_target this) rw [(q e).right_inv this, ← hpq e]; exact congr($g'_lifts ta) @@ -108,13 +108,13 @@ theorem exists_lift_nhds {f : C(I × A, X)} {g : I × A → E} (g_lifts : p ∘ exact ⟨⟨hta.1.1, ht⟩, hta.2.2.1⟩ · simp_rw [not_le]; exact (ContinuousOn.congr ((q e).continuousOn_invFun.comp f.2.continuousOn fun _ h ↦ huv ⟨hu ⟨h.2, h.1.1.2⟩, h.1.2.1⟩) - fun _ h ↦ if_pos <| huv ⟨hu ⟨h.2, h.1.1.2⟩, h.1.2.1⟩).mono + fun _ h ↦ ite_eq_left <| huv ⟨hu ⟨h.2, h.1.1.2⟩, h.1.2.1⟩).mono (Set.inter_subset_inter_right _ <| closure_lt_subset_le continuous_const continuous_fst) · ext ta; rw [Function.comp_apply]; split_ifs with _ hv · exact congr($g'_lifts ta) · rw [hpq e, (q e).right_inv hv] · exact congr($g_lifts ta) - · rw [← g'_0]; exact if_pos bot_le + · rw [← g'_0]; exact ite_eq_left bot_le · dsimp only; split_ifs with htn hf · exact g'_a t0 htn · apply (q e).injOn ((q e).map_target hf) (h_sub ⟨le_of_not_ge htn, htn1⟩) @@ -253,7 +253,7 @@ theorem exists_path_lifts : ∃ Γ : C(I, E), p ∘ Γ = γ ∧ Γ 0 = e := by exact ⟨t_sub ⟨closure_lt_subset_le continuous_const continuous_subtype_val h.2, h.1.2⟩, ⟨⟩⟩ · rw [Function.comp_apply]; split_ifs with h exacts [eqOn ⟨hs.1, h⟩, q.proj_symm_apply' (t_sub ⟨le_of_not_ge h, hs.2⟩)] - · dsimp only; rwa [if_pos (t_0 ▸ t_mono n.zero_le)] + · dsimp only; rwa [ite_eq_left (t_0 ▸ t_mono n.zero_le)] /-- The lift of a path to a covering space given a lift of the left endpoint. -/ def liftPath : C(I, E) := (cov.exists_path_lifts γ e γ_0).choose diff --git a/Mathlib/Topology/Instances/CantorSet.lean b/Mathlib/Topology/Instances/CantorSet.lean index 559ef80a5c80fd..c541f9ed402ef0 100644 --- a/Mathlib/Topology/Instances/CantorSet.lean +++ b/Mathlib/Topology/Instances/CantorSet.lean @@ -258,7 +258,7 @@ theorem cantorSequence_get_succ (x : ℝ) (n : ℕ) : (cantorSequence x).get (n + 1) = 3 * ((cantorSequence x).get n - 3 ^ n * ofDigitsTerm (cantorToTernary x).get n) := by simp only [cantorSequence, ofDigitsTerm, cantorToTernary, cantorToBinary, Set.mem_Icc, - Bool.if_true_right, Bool.or_false, Stream'.get_map, Bool.cond_not, Bool.cond_decide, + Bool.ite_true_right, Bool.or_false, Stream'.get_map, Bool.cond_not, Bool.cond_decide, Stream'.get_succ_iterate', cantorStep] split_ifs <;> simp field diff --git a/Mathlib/Topology/LocallyConstant/Basic.lean b/Mathlib/Topology/LocallyConstant/Basic.lean index 7fecd269873639..179efea5d0dd30 100644 --- a/Mathlib/Topology/LocallyConstant/Basic.lean +++ b/Mathlib/Topology/LocallyConstant/Basic.lean @@ -536,9 +536,9 @@ def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) · cases i <;> rw [continuousOn_iff_continuous_domRestrict] · convert! hg ext x - simp only [cond_false, domRestrict_apply, Subtype.coe_eta, dite_eq_right_iff] + simp only [Bool.cond_false, domRestrict_apply, Subtype.coe_eta, dite_eq_right_iff] exact fun hx ↦ hfg x ⟨hx, x.prop⟩ - · simp only [cond_true, domRestrict_dite, Subtype.coe_eta] + · simp only [Bool.cond_true, domRestrict_dite, Subtype.coe_eta] exact hf @[simp] @@ -549,7 +549,7 @@ lemma piecewise_apply_left {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : Is piecewise h₁ h₂ h f g hfg x = f ⟨x, hx⟩ := by simp only [piecewise, coe_mk] - rw [dif_pos hx] + rw [dite_eq_left hx] @[simp] lemma piecewise_apply_right {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 87ec3958a456cc..60178e79586b8f 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -668,7 +668,7 @@ singleton indicator functions. set s := h.toFinset with hs by_cases hw : w ∈ s · simp [hw] - · simp only [hw, if_false] + · simp only [hw, ite_false] have : w ∉ support D := by simpa only [hs, Set.Finite.mem_toFinset] using hw exact (notMem_support.mp this).symm diff --git a/Mathlib/Topology/MetricSpace/Dilation.lean b/Mathlib/Topology/MetricSpace/Dilation.lean index 2158ba0b0054f0..58de6f264bbd30 100644 --- a/Mathlib/Topology/MetricSpace/Dilation.lean +++ b/Mathlib/Topology/MetricSpace/Dilation.lean @@ -136,11 +136,11 @@ def ratio [DilationClass F α β] (f : F) : ℝ≥0 := theorem ratio_of_trivial [DilationClass F α β] (f : F) (h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞) : ratio f = 1 := - if_pos h + ite_eq_left h @[nontriviality] theorem ratio_of_subsingleton [Subsingleton α] [DilationClass F α β] (f : F) : ratio f = 1 := - if_pos fun x y ↦ by simp [Subsingleton.elim x y] + ite_eq_left fun x y ↦ by simp [Subsingleton.elim x y] theorem ratio_ne_zero [DilationClass F α β] (f : F) : ratio f ≠ 0 := by rw [ratio]; split_ifs @@ -279,7 +279,7 @@ protected theorem coe_id : ⇑(Dilation.id α) = id := theorem ratio_id : ratio (Dilation.id α) = 1 := by by_cases! h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞ - · rw [ratio, if_pos h] + · rw [ratio, ite_eq_left h] · rcases h with ⟨x, y, hne⟩ refine (ratio_unique hne.1 hne.2 ?_).symm simp diff --git a/Mathlib/Topology/MetricSpace/Gluing.lean b/Mathlib/Topology/MetricSpace/Gluing.lean index b2c1bb3b46eb8a..c0a92c775058bb 100644 --- a/Mathlib/Topology/MetricSpace/Gluing.lean +++ b/Mathlib/Topology/MetricSpace/Gluing.lean @@ -342,7 +342,7 @@ theorem dist_same (i : ι) (x y : E i) : dist (Sigma.mk i x) ⟨i, y⟩ = dist x @[simp] theorem dist_ne {i j : ι} (h : i ≠ j) (x : E i) (y : E j) : dist (⟨i, x⟩ : Σ k, E k) ⟨j, y⟩ = dist x (Nonempty.some ⟨x⟩) + 1 + dist (Nonempty.some ⟨y⟩) y := - dif_neg h + dite_eq_right h theorem one_le_dist_of_ne {i j : ι} (h : i ≠ j) (x : E i) (y : E j) : 1 ≤ dist (⟨i, x⟩ : Σ k, E k) ⟨j, y⟩ := by @@ -421,7 +421,7 @@ protected def metricSpace : MetricSpace (Σ i, E i) := by · rintro ⟨i, x⟩ ⟨j, y⟩ rcases eq_or_ne i j with (rfl | h) · simp [Sigma.dist, dist_comm] - · simp only [Sigma.dist, dist_comm, h, h.symm, not_false_iff, dif_neg] + · simp only [Sigma.dist, dist_comm, h, h.symm, not_false_iff, dite_eq_right] abel · rintro ⟨i, x⟩ ⟨j, y⟩ rcases eq_or_ne i j with (rfl | hij) diff --git a/Mathlib/Topology/MetricSpace/Infsep.lean b/Mathlib/Topology/MetricSpace/Infsep.lean index 5fb97b045864a6..71d2484efb8d97 100644 --- a/Mathlib/Topology/MetricSpace/Infsep.lean +++ b/Mathlib/Topology/MetricSpace/Infsep.lean @@ -383,7 +383,7 @@ theorem infsep_eq_iInf [Decidable s.Nontrivial] : theorem Nontrivial.infsep_eq_iInf (hs : s.Nontrivial) : s.infsep = ⨅ d : s.offDiag, (uncurry dist) (d : α × α) := by - classical rw [Set.infsep_eq_iInf, if_pos hs] + classical rw [Set.infsep_eq_iInf, ite_eq_left hs] theorem infsep_of_fintype [Decidable s.Nontrivial] [Fintype s] : s.infsep = if hs : s.Nontrivial then s.offDiag.toFinset.inf' (by simpa) (uncurry dist) else 0 := by @@ -396,7 +396,7 @@ theorem infsep_of_fintype [Decidable s.Nontrivial] [Fintype s] : s.infsep = theorem Nontrivial.infsep_of_fintype [Fintype s] (hs : s.Nontrivial) : s.infsep = s.offDiag.toFinset.inf' (by simpa) (uncurry dist) := by - classical rw [Set.infsep_of_fintype, dif_pos hs] + classical rw [Set.infsep_of_fintype, dite_eq_left hs] theorem Finite.infsep [Decidable s.Nontrivial] (hsf : s.Finite) : s.infsep = @@ -410,7 +410,7 @@ theorem Finite.infsep [Decidable s.Nontrivial] (hsf : s.Finite) : theorem Finite.infsep_of_nontrivial (hsf : s.Finite) (hs : s.Nontrivial) : s.infsep = hsf.offDiag.toFinset.inf' (by simpa) (uncurry dist) := by - classical simp_rw [hsf.infsep, dif_pos hs] + classical simp_rw [hsf.infsep, dite_eq_left hs] theorem _root_.Finset.coe_infsep (s : Finset α) : (s : Set α).infsep = if hs : s.offDiag.Nonempty then s.offDiag.inf' hs (uncurry dist) else 0 := by @@ -422,12 +422,12 @@ theorem _root_.Finset.coe_infsep (s : Finset α) : (s : Set α).infsep = theorem _root_.Finset.coe_infsep_of_offDiag_nonempty {s : Finset α} (hs : s.offDiag.Nonempty) : (s : Set α).infsep = s.offDiag.inf' hs (uncurry dist) := by - rw [Finset.coe_infsep, dif_pos hs] + rw [Finset.coe_infsep, dite_eq_left hs] theorem _root_.Finset.coe_infsep_of_offDiag_empty {s : Finset α} (hs : s.offDiag = ∅) : (s : Set α).infsep = 0 := by rw [← Finset.not_nonempty_iff_eq_empty] at hs - rw [Finset.coe_infsep, dif_neg hs] + rw [Finset.coe_infsep, dite_eq_right hs] theorem Nontrivial.infsep_exists_of_finite [Finite s] (hs : s.Nontrivial) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ s.infsep = dist x y := by diff --git a/Mathlib/Topology/MetricSpace/PiNat.lean b/Mathlib/Topology/MetricSpace/PiNat.lean index 0ff0d4f59dbc78..adc8982b9bde66 100644 --- a/Mathlib/Topology/MetricSpace/PiNat.lean +++ b/Mathlib/Topology/MetricSpace/PiNat.lean @@ -79,7 +79,7 @@ irreducible_def firstDiff (x y : ∀ n, E n) : ℕ := theorem apply_firstDiff_ne {x y : ∀ n, E n} (h : x ≠ y) : x (firstDiff x y) ≠ y (firstDiff x y) := by - rw [firstDiff_def, dif_pos h] + rw [firstDiff_def, dite_eq_left h] classical exact Nat.find_spec (ne_iff.1 h) @@ -492,7 +492,7 @@ def shortestPrefixDiff {E : ℕ → Type*} (x : ∀ n, E n) (s : Set (∀ n, E n theorem firstDiff_lt_shortestPrefixDiff {s : Set (∀ n, E n)} (hs : IsClosed s) {x y : ∀ n, E n} (hx : x ∉ s) (hy : y ∈ s) : firstDiff x y < shortestPrefixDiff x s := by have A := exists_disjoint_cylinder hs hx - rw [shortestPrefixDiff, dif_pos A] + rw [shortestPrefixDiff, dite_eq_left A] classical have B := Nat.find_spec A contrapose! B @@ -525,7 +525,7 @@ theorem inter_cylinder_longestPrefix_nonempty {s : Set (∀ n, E n)} (hs : IsClo have A := exists_disjoint_cylinder hs hx have B : longestPrefix x s < shortestPrefixDiff x s := Nat.pred_lt (shortestPrefixDiff_pos hs hne hx).ne' - rw [longestPrefix, shortestPrefixDiff, dif_pos A] at B ⊢ + rw [longestPrefix, shortestPrefixDiff, dite_eq_left A] at B ⊢ classical obtain ⟨y, ys, hy⟩ : ∃ y : ∀ n : ℕ, E n, y ∈ s ∧ x ∈ cylinder y (Nat.find A - 1) := by simpa only [not_disjoint_iff, mem_cylinder_comm] using Nat.find_min A B @@ -594,7 +594,8 @@ theorem exists_lipschitz_retraction_of_isClosed {s : Set (∀ n, E n)} (hs : IsC · rintro x ⟨y, rfl⟩ by_cases hy : y ∈ s · rwa [fs y hy] - simpa [f, if_neg hy] using! (inter_cylinder_longestPrefix_nonempty hs hne y).choose_spec.1 + simpa [f, ite_eq_right hy] + using! (inter_cylinder_longestPrefix_nonempty hs hne y).choose_spec.1 · intro x hx rw [← fs x hx] exact mem_range_self _ @@ -619,7 +620,7 @@ theorem exists_lipschitz_retraction_of_isClosed {s : Set (∀ n, E n)} (hs : IsC -- case where `y ∉ s` have A : (s ∩ cylinder y (longestPrefix y s)).Nonempty := inter_cylinder_longestPrefix_nonempty hs hne y - have fy : f y = A.some := by simp_rw [f, if_neg ys] + have fy : f y = A.some := by simp_rw [f, ite_eq_right ys] have I : cylinder A.some (firstDiff x y) = cylinder y (firstDiff x y) := by rw [← mem_cylinder_iff_eq, firstDiff_comm] apply cylinder_anti y _ A.some_mem.2 @@ -631,7 +632,7 @@ theorem exists_lipschitz_retraction_of_isClosed {s : Set (∀ n, E n)} (hs : IsC -- case where `y ∈ s` (similar to the above) · have A : (s ∩ cylinder x (longestPrefix x s)).Nonempty := inter_cylinder_longestPrefix_nonempty hs hne x - have fx : f x = A.some := by simp_rw [f, if_neg xs] + have fx : f x = A.some := by simp_rw [f, ite_eq_right xs] have I : cylinder A.some (firstDiff x y) = cylinder x (firstDiff x y) := by rw [← mem_cylinder_iff_eq] apply cylinder_anti x _ A.some_mem.2 @@ -641,10 +642,10 @@ theorem exists_lipschitz_retraction_of_isClosed {s : Set (∀ n, E n)} (hs : IsC -- case where `y ∉ s` · have Ax : (s ∩ cylinder x (longestPrefix x s)).Nonempty := inter_cylinder_longestPrefix_nonempty hs hne x - have fx : f x = Ax.some := by simp_rw [f, if_neg xs] + have fx : f x = Ax.some := by simp_rw [f, ite_eq_right xs] have Ay : (s ∩ cylinder y (longestPrefix y s)).Nonempty := inter_cylinder_longestPrefix_nonempty hs hne y - have fy : f y = Ay.some := by simp_rw [f, if_neg ys] + have fy : f y = Ay.some := by simp_rw [f, ite_eq_right ys] -- case where the common prefix to `x` and `s`, or `y` and `s`, is shorter than the -- common part to `x` and `y` -- then `f x = f y`. by_cases! H : longestPrefix x s < firstDiff x y ∨ longestPrefix y s < firstDiff x y diff --git a/Mathlib/Topology/Metrizable/Uniformity.lean b/Mathlib/Topology/Metrizable/Uniformity.lean index 4d61f3a49b1779..2ac7ec67a439f4 100644 --- a/Mathlib/Topology/Metrizable/Uniformity.lean +++ b/Mathlib/Topology/Metrizable/Uniformity.lean @@ -222,13 +222,13 @@ protected theorem UniformSpace.metrizable_uniformity (X : Type*) [UniformSpace X have hd_le : ∀ x y, ↑(d x y) ≤ 2 * dist x y := by refine PseudoMetricSpace.le_two_mul_dist_ofPreNNDist _ _ _ fun x₁ x₂ x₃ x₄ => ?_ by_cases H : ∃ n, (x₁, x₄) ∉ U n - · refine (dif_pos H).trans_le ?_ + · refine (dite_eq_left H).trans_le ?_ rw [← div_le_iff₀' zero_lt_two, ← mul_one_div (_ ^ _), ← pow_succ] simp only [le_max_iff, hle_d, ← not_and_or] rintro ⟨h₁₂, h₂₃, h₃₄⟩ refine Nat.find_spec H (hU_comp (lt_add_one <| Nat.find H) ?_) exact ⟨x₂, h₁₂, x₃, h₂₃, h₃₄⟩ - · exact (dif_neg H).trans_le zero_le + · exact (dite_eq_right H).trans_le zero_le -- Porting note: without the next line, `uniformity_basis_dist_pow` ends up introducing some -- `Subtype.val` applications instead of `NNReal.toReal`. rw [mem_Ioo, ← NNReal.coe_lt_coe, ← NNReal.coe_lt_coe] at hr diff --git a/Mathlib/Topology/Order/LeftRightLim.lean b/Mathlib/Topology/Order/LeftRightLim.lean index ba70e94ddaf5bb..5b68fd1fd0dd1f 100644 --- a/Mathlib/Topology/Order/LeftRightLim.lean +++ b/Mathlib/Topology/Order/LeftRightLim.lean @@ -68,7 +68,7 @@ theorem leftLim_eq_of_tendsto [hα : TopologicalSpace α] [h'α : OrderTopology leftLim f a = y := by have h'' : ∃ y, Tendsto f (𝓝[<] a) (𝓝 y) := ⟨y, h'⟩ rw [h'α.topology_eq_generate_intervals] at h h' h'' - simp only [leftLim, neBot_iff.mp h, h'', not_true, or_self_iff, if_false] + simp only [leftLim, neBot_iff.mp h, h'', not_true, or_self_iff, ite_false] exact lim_eq h' theorem rightLim_eq_of_tendsto [TopologicalSpace α] [OrderTopology α] [T2Space β] diff --git a/Mathlib/Topology/Path.lean b/Mathlib/Topology/Path.lean index a265e1564203ad..2319c64c2c806a 100644 --- a/Mathlib/Topology/Path.lean +++ b/Mathlib/Topology/Path.lean @@ -307,7 +307,7 @@ theorem extend_trans_of_le_half (γ₁ : Path x y) (γ₂ : Path y z) {t : ℝ} (γ₁.trans γ₂).extend t = γ₁.extend (2 * t) := by obtain _ | ht₀ := le_total t 0 · repeat rw [extend_of_le_zero _ (by linarith)] - · rwa [extend_apply _ ⟨ht₀, by linarith⟩, trans_apply, dif_pos, extend_apply] + · rwa [extend_apply _ ⟨ht₀, by linarith⟩, trans_apply, dite_eq_left, extend_apply] theorem extend_trans_of_half_le (γ₁ : Path x y) (γ₂ : Path y z) {t : ℝ} (ht : 1 / 2 ≤ t) : (γ₁.trans γ₂).extend t = γ₂.extend (2 * t - 1) := by diff --git a/Mathlib/Topology/Piecewise.lean b/Mathlib/Topology/Piecewise.lean index 9795376d214c09..445b1e50bf466f 100644 --- a/Mathlib/Topology/Piecewise.lean +++ b/Mathlib/Topology/Piecewise.lean @@ -48,7 +48,7 @@ theorem ContinuousOn.if' {s : Set α} {p : α → Prop} {f g : α → β} [∀ a · rw [← inter_univ s, ← union_compl_self { a | p a }, inter_union_distrib_left] at hx ⊢ rcases hx with hx | hx · apply ContinuousWithinAt.union - · exact (hf x hx).congr (fun y hy => if_pos hy.2) (if_pos hx.2) + · exact (hf x hx).congr (fun y hy => ite_eq_left hy.2) (ite_eq_left hx.2) · have : x ∉ closure { a | p a }ᶜ := fun h => hx' ⟨subset_closure hx.2, by rwa [closure_compl] at h⟩ exact continuousWithinAt_of_notMem_closure fun h => @@ -58,7 +58,7 @@ theorem ContinuousOn.if' {s : Set α} {p : α → Prop} {f g : α → β} [∀ a hx' ⟨h, fun h' : x ∈ interior { a | p a } => hx.2 (interior_subset h')⟩ exact continuousWithinAt_of_notMem_closure fun h => this (closure_inter_subset_inter_closure _ _ h).2 - · exact (hg x hx).congr (fun y hy => if_neg hy.2) (if_neg hx.2) + · exact (hg x hx).congr (fun y hy => ite_eq_right hy.2) (ite_eq_right hx.2) theorem ContinuousOn.piecewise' [∀ a, Decidable (a ∈ t)] (hpf : ∀ a ∈ s ∩ frontier t, Tendsto f (𝓝[s ∩ t] a) (𝓝 (piecewise t f g a))) diff --git a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean index 818c5ace8171f0..94ebdd8a623804 100644 --- a/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean +++ b/Mathlib/Topology/Semicontinuity/Hemicontinuity.lean @@ -437,7 +437,7 @@ lemma LowerHemicontinuousAt.exists_seq_tendsto {x₀ : α} (hf : LowerHemicontin -- Define `y n` to be some element of `f (x n) ∩ U (g n)` (or be arbitrary) let y : ℕ → β := fun n ↦ if h : (f (x n) ∩ U (g n)).Nonempty then h.some else y₀ have hy (n) (h : (f (x n) ∩ U (g n)).Nonempty) : y n ∈ f (x n) ∩ U (g n) := by - simpa only [y, dif_pos h] using h.some_mem + simpa only [y, dite_eq_left h] using h.some_mem refine ⟨y, (hev 0).mono (by grind), ?_⟩ -- Have to show for all `k`, eventually, all `y n ∈ U k`. rw [hUbasis.tendsto_right_iff] diff --git a/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean b/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean index 2dd670b93d1774..f16abbf7b67ac7 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean @@ -238,7 +238,7 @@ theorem eq_of_locally_eq₂ {U₁ U₂ V : Opens X} (i₁ : U₁ ⟶ V) (i₂ : (s t : ToType (F.1.obj (op V))) (h₁ : F.1.map i₁.op s = F.1.map i₁.op t) (h₂ : F.1.map i₂.op s = F.1.map i₂.op t) : s = t := by fapply F.eq_of_locally_eq' fun t : Bool => if t then U₁ else U₂ - · exact fun i => if h : i then eqToHom (if_pos h) ≫ i₁ else eqToHom (if_neg h) ≫ i₂ + · exact fun i => if h : i then eqToHom (ite_eq_left h) ≫ i₁ else eqToHom (ite_eq_right h) ≫ i₂ · refine le_trans hcover ?_ rw [sup_le_iff] constructor diff --git a/Mathlib/Topology/Sheaves/Skyscraper.lean b/Mathlib/Topology/Sheaves/Skyscraper.lean index b7c644818f625b..568cc9c4d81f77 100644 --- a/Mathlib/Topology/Sheaves/Skyscraper.lean +++ b/Mathlib/Topology/Sheaves/Skyscraper.lean @@ -60,16 +60,17 @@ point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A def skyscraperPresheaf : Presheaf C X where obj U := if p₀ ∈ unop U then A else terminal C map {U V} i := - if h : p₀ ∈ unop V then eqToHom <| by rw [if_pos h, if_pos (by simpa using i.unop.le h)] - else ((if_neg h).symm.ndrec terminalIsTerminal).from _ + if h : p₀ ∈ unop V then eqToHom <| by + rw [ite_eq_left h, ite_eq_left (by simpa using i.unop.le h)] + else ((ite_eq_right h).symm.ndrec terminalIsTerminal).from _ map_id U := - (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h => - ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _ + (em (p₀ ∈ U.unop)).elim (fun h => dite_eq_left h) fun h => + ((ite_eq_right h).symm.ndrec terminalIsTerminal).hom_ext _ _ map_comp {U V W} iVU iWV := by by_cases hW : p₀ ∈ unop W · have hV : p₀ ∈ unop V := leOfHom iWV.unop hW - simp only [dif_pos hW, dif_pos hV, eqToHom_trans] - · dsimp; rw [dif_neg hW]; apply ((if_neg hW).symm.ndrec terminalIsTerminal).hom_ext + simp only [dite_eq_left hW, dite_eq_left hV, eqToHom_trans] + · dsimp; rw [dite_eq_right hW]; apply ((ite_eq_right hW).symm.ndrec terminalIsTerminal).hom_ext theorem skyscraperPresheaf_eq_pushforward [hd : ∀ U : Opens (TopCat.of PUnit.{u + 1}), Decidable (PUnit.unit ∈ U)] : @@ -89,15 +90,15 @@ sending every `f : a ⟶ b` to the natural transformation `α` defined as: `α(U def SkyscraperPresheafFunctor.map' {a b : C} (f : a ⟶ b) : skyscraperPresheaf p₀ a ⟶ skyscraperPresheaf p₀ b where app U := - if h : p₀ ∈ U.unop then eqToHom (if_pos h) ≫ f ≫ eqToHom (if_pos h).symm - else ((if_neg h).symm.ndrec terminalIsTerminal).from _ + if h : p₀ ∈ U.unop then eqToHom (ite_eq_left h) ≫ f ≫ eqToHom (ite_eq_left h).symm + else ((ite_eq_right h).symm.ndrec terminalIsTerminal).from _ naturality U V i := by simp only [skyscraperPresheaf_map] by_cases hV : p₀ ∈ V.unop · have hU : p₀ ∈ U.unop := leOfHom i.unop hV simp only [skyscraperPresheaf_obj, hU, hV, ↓reduceDIte, eqToHom_trans_assoc, Category.assoc, eqToHom_trans] - · apply ((if_neg hV).symm.ndrec terminalIsTerminal).hom_ext + · apply ((ite_eq_right hV).symm.ndrec terminalIsTerminal).hom_ext set_option backward.defeqAttrib.useBackward true in theorem SkyscraperPresheafFunctor.map'_id {a : C} : @@ -141,9 +142,9 @@ def skyscraperPresheafCoconeOfSpecializes {y : X} (h : p₀ ⤳ y) : Cocone ((OpenNhds.inclusion y).op ⋙ skyscraperPresheaf p₀ A) where pt := A ι := - { app := fun U => eqToHom <| if_pos <| h.mem_open U.unop.1.2 U.unop.2 + { app := fun U => eqToHom <| ite_eq_left <| h.mem_open U.unop.1.2 U.unop.2 naturality := fun U V inc => by - change dite _ _ _ ≫ _ = _; rw [dif_pos] + change dite _ _ _ ≫ _ = _; rw [dite_eq_left] swap · exact h.mem_open V.unop.1.2 V.unop.2 · simp only [Functor.comp_obj, Functor.op_obj, skyscraperPresheaf_obj, unop_op, @@ -157,12 +158,12 @@ colimit -/ noncomputable def skyscraperPresheafCoconeIsColimitOfSpecializes {y : X} (h : p₀ ⤳ y) : IsColimit (skyscraperPresheafCoconeOfSpecializes p₀ A h) where - desc c := eqToHom (if_pos trivial).symm ≫ c.ι.app (op ⊤) + desc c := eqToHom (ite_eq_left trivial).symm ≫ c.ι.app (op ⊤) fac c U := by dsimp rw [← c.w (homOfLE <| (le_top : unop U ≤ _)).op] change _ ≫ _ ≫ dite _ _ _ ≫ _ = _ - rw [dif_pos] + rw [dite_eq_left] · simp only [eqToHom_trans_assoc, eqToHom_refl, Category.id_comp, op_unop] · exact h.mem_open U.unop.1.2 U.unop.2 @@ -180,7 +181,8 @@ noncomputable def skyscraperPresheafStalkOfSpecializes [HasColimits C] {y : X} ( @[reassoc (attr := simp)] lemma germ_skyscraperPresheafStalkOfSpecializes_hom [HasColimits C] {y : X} (h : p₀ ⤳ y) (U hU) : (skyscraperPresheaf p₀ A).germ U y hU ≫ - (skyscraperPresheafStalkOfSpecializes p₀ A h).hom = eqToHom (if_pos (h.mem_open U.2 hU)) := + (skyscraperPresheafStalkOfSpecializes p₀ A h).hom = + eqToHom (ite_eq_left (h.mem_open U.2 hU)) := colimit.isoColimitCocone_ι_hom _ _ /-- The cocone at `*` for the stalk functor of `skyscraperPresheaf p₀ A` when `y ∉ closure {p₀}` @@ -204,13 +206,13 @@ noncomputable def skyscraperPresheafCoconeIsColimitOfNotSpecializes {y : X} (h : let h1 : ∃ U : OpenNhds y, p₀ ∉ U.1 := let ⟨U, ho, h₀, hy⟩ := not_specializes_iff_exists_open.mp h ⟨⟨⟨U, ho⟩, h₀⟩, hy⟩ - { desc := fun c => eqToHom (if_neg h1.choose_spec).symm ≫ c.ι.app (op h1.choose) + { desc := fun c => eqToHom (ite_eq_right h1.choose_spec).symm ≫ c.ι.app (op h1.choose) fac := fun c U => by change _ = c.ι.app (op U.unop) simp only [← c.w (homOfLE <| @inf_le_left _ _ h1.choose U.unop).op, ← c.w (homOfLE <| @inf_le_right _ _ h1.choose U.unop).op, ← Category.assoc] congr 1 - refine ((if_neg ?_).symm.ndrec terminalIsTerminal).hom_ext _ _ + refine ((ite_eq_right ?_).symm.ndrec terminalIsTerminal).hom_ext _ _ exact fun h => h1.choose_spec h.1 uniq := fun c f H => by dsimp @@ -236,7 +238,7 @@ theorem skyscraperPresheaf_isSheaf : (skyscraperPresheaf p₀ A).IsSheaf := by (Sheaf.pushforward_sheaf_of_sheaf _ (Presheaf.isSheaf_on_punit_of_isTerminal _ (by dsimp [skyscraperPresheaf] - rw [if_neg] + rw [ite_eq_right] · exact terminalIsTerminal · #adaptation_note /-- 2024-03-24 Previously the universe annotation was not needed here. -/ @@ -273,8 +275,8 @@ if `p₀ ∉ U`. def toSkyscraperPresheaf {𝓕 : Presheaf C X} {c : C} (f : 𝓕.stalk p₀ ⟶ c) : 𝓕 ⟶ skyscraperPresheaf p₀ c where app U := - if h : p₀ ∈ U.unop then 𝓕.germ _ p₀ h ≫ f ≫ eqToHom (if_pos h).symm - else ((if_neg h).symm.ndrec terminalIsTerminal).from _ + if h : p₀ ∈ U.unop then 𝓕.germ _ p₀ h ≫ f ≫ eqToHom (ite_eq_left h).symm + else ((ite_eq_right h).symm.ndrec terminalIsTerminal).from _ naturality U V inc := by dsimp by_cases hV : p₀ ∈ V.unop @@ -282,7 +284,7 @@ def toSkyscraperPresheaf {𝓕 : Presheaf C X} {c : C} (f : 𝓕.stalk p₀ ⟶ split_ifs rw [← Category.assoc, 𝓕.germ_res' inc, Category.assoc, Category.assoc, eqToHom_trans] · split_ifs - exact ((if_neg hV).symm.ndrec terminalIsTerminal).hom_ext .. + exact ((ite_eq_right hV).symm.ndrec terminalIsTerminal).hom_ext .. set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @@ -292,19 +294,19 @@ set_option backward.isDefEq.respectTransparency false in def fromStalk {𝓕 : Presheaf C X} {c : C} (f : 𝓕 ⟶ skyscraperPresheaf p₀ c) : 𝓕.stalk p₀ ⟶ c := let χ : Cocone ((OpenNhds.inclusion p₀).op ⋙ 𝓕) := Cocone.mk c <| - { app := fun U => f.app ((OpenNhds.inclusion p₀).op.obj U) ≫ eqToHom (if_pos U.unop.2) + { app := fun U => f.app ((OpenNhds.inclusion p₀).op.obj U) ≫ eqToHom (ite_eq_left U.unop.2) naturality := fun U V inc => by dsimp only [Functor.const_obj_map, Functor.const_obj_obj, Functor.comp_map, Functor.comp_obj, Functor.op_obj, skyscraperPresheaf_obj] rw [Category.comp_id, ← Category.assoc, comp_eqToHom_iff, Category.assoc, eqToHom_trans, f.naturality, skyscraperPresheaf_map] have hV : p₀ ∈ (OpenNhds.inclusion p₀).obj V.unop := V.unop.2 - simp only [dif_pos hV] } + simp only [dite_eq_left hV] } colimit.desc _ χ @[reassoc (attr := simp)] lemma germ_fromStalk {𝓕 : Presheaf C X} {c : C} (f : 𝓕 ⟶ skyscraperPresheaf p₀ c) (U) (hU) : - 𝓕.germ U p₀ hU ≫ fromStalk p₀ f = f.app (op U) ≫ eqToHom (if_pos hU) := + 𝓕.germ U p₀ hU ≫ fromStalk p₀ f = f.app (op U) ≫ eqToHom (ite_eq_left hU) := colimit.ι_desc _ _ set_option backward.isDefEq.respectTransparency.types false in @@ -316,13 +318,13 @@ theorem to_skyscraper_fromStalk {𝓕 : Presheaf C X} {c : C} (f : 𝓕 ⟶ skys dsimp split_ifs with h · simp - · exact ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext .. + · exact ((ite_eq_right h).symm.ndrec terminalIsTerminal).hom_ext .. set_option backward.isDefEq.respectTransparency.types false in theorem fromStalk_to_skyscraper {𝓕 : Presheaf C X} {c : C} (f : 𝓕.stalk p₀ ⟶ c) : fromStalk p₀ (toSkyscraperPresheaf _ f) = f := by refine 𝓕.stalk_hom_ext fun U hxU ↦ ?_ - rw [germ_fromStalk, toSkyscraperPresheaf_app, dif_pos hxU, Category.assoc, Category.assoc, + rw [germ_fromStalk, toSkyscraperPresheaf_app, dite_eq_left hxU, Category.assoc, Category.assoc, eqToHom_trans, eqToHom_refl, Category.comp_id, Presheaf.germ] set_option backward.defeqAttrib.useBackward true in @@ -338,7 +340,7 @@ protected def unit : split_ifs with h · simp only [Category.id_comp, Category.assoc, eqToHom_trans_assoc, eqToHom_refl, Presheaf.stalkFunctor_map_germ_assoc, Presheaf.stalkFunctor_obj] - · apply ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext + · apply ((ite_eq_right h).symm.ndrec terminalIsTerminal).hom_ext set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @@ -376,7 +378,7 @@ def skyscraperPresheafStalkAdjunction [HasColimits C] : skyscraperPresheafCoconeOfSpecializes_pt, skyscraperPresheafCoconeOfSpecializes_ι_app, Functor.comp_obj, Functor.op_obj, skyscraperPresheaf_obj, Functor.const_obj_obj] rw [comp_eqToHom_iff] - apply ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext + apply ((ite_eq_right h).symm.ndrec terminalIsTerminal).hom_ext right_triangle_components Y := by ext simp only [skyscraperPresheafFunctor_obj, Functor.id_obj, skyscraperPresheaf_obj, @@ -435,7 +437,7 @@ noncomputable def isTerminalSkyscraperSheafObjObjOfNotMem {U : (Opens X)ᵒᵖ} (h : p₀ ∉ unop U) : IsTerminal ((skyscraperSheaf p₀ A).obj.obj U) := by dsimp - rw [if_neg h] + rw [ite_eq_right h] exact terminalIsTerminal end diff --git a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean index 83a6a2d541fafb..0cd1cc5fa209d5 100644 --- a/Mathlib/Topology/UniformSpace/AbstractCompletion.lean +++ b/Mathlib/Topology/UniformSpace/AbstractCompletion.lean @@ -124,7 +124,7 @@ protected def extend (f : α → β) : hatα → β := variable {f : α → β} theorem extend_def (hf : UniformContinuous f) : pkg.extend f = pkg.isDenseInducing.extend f := - if_pos hf + ite_eq_left hf theorem inseparable_extend_coe (hf : UniformContinuous f) (x : α) : Inseparable (pkg.extend f (ι x)) (f x) := by @@ -143,7 +143,7 @@ theorem uniformContinuous_extend : UniformContinuous (pkg.extend f) := by · rw [pkg.extend_def hf] exact uniformContinuous_uniformly_extend pkg.isUniformInducing pkg.dense hf · unfold AbstractCompletion.extend - rw [if_neg hf] + rw [ite_eq_right hf] exact uniformContinuous_of_const fun a b => by congr 1 theorem continuous_extend : Continuous (pkg.extend f) := diff --git a/Mathlib/Topology/UniformSpace/Completion.lean b/Mathlib/Topology/UniformSpace/Completion.lean index 71b55c667e8fd1..a4a0c891d91166 100644 --- a/Mathlib/Topology/UniformSpace/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Completion.lean @@ -231,7 +231,7 @@ variable [T0Space β] theorem extend_pureCauchy {f : α → β} (hf : UniformContinuous f) (a : α) : extend f (pureCauchy a) = f a := by - rw [extend, if_pos hf] + rw [extend, ite_eq_left hf] exact uniformly_extend_of_ind isUniformInducing_pureCauchy denseRange_pureCauchy hf _ end T0Space @@ -241,9 +241,9 @@ variable [CompleteSpace β] @[fun_prop] theorem uniformContinuous_extend {f : α → β} : UniformContinuous (extend f) := by by_cases hf : UniformContinuous f - · rw [extend, if_pos hf] + · rw [extend, ite_eq_left hf] exact uniformContinuous_uniformly_extend isUniformInducing_pureCauchy denseRange_pureCauchy hf - · rw [extend, if_neg hf] + · rw [extend, ite_eq_right hf] exact uniformContinuous_of_const fun a _b => by congr end Extend diff --git a/Mathlib/Topology/UniformSpace/Separation.lean b/Mathlib/Topology/UniformSpace/Separation.lean index 39c7b86a9c707a..af7720592ef197 100644 --- a/Mathlib/Topology/UniformSpace/Separation.lean +++ b/Mathlib/Topology/UniformSpace/Separation.lean @@ -298,13 +298,13 @@ def lift' [T0Space β] (f : α → β) : SeparationQuotient α → β := else fun x => f (Nonempty.some ⟨x.out⟩) theorem lift'_mk [T0Space β] {f : α → β} (h : UniformContinuous f) (a : α) : - lift' f (mk a) = f a := by rw [lift', dif_pos h, lift_mk] + lift' f (mk a) = f a := by rw [lift', dite_eq_left h, lift_mk] @[fun_prop] theorem uniformContinuous_lift' [T0Space β] (f : α → β) : UniformContinuous (lift' f) := by by_cases hf : UniformContinuous f - · rwa [lift', dif_pos hf, uniformContinuous_lift] - · rw [lift', dif_neg hf] + · rwa [lift', dite_eq_left hf, uniformContinuous_lift] + · rw [lift', dite_eq_right hf] exact uniformContinuous_of_const fun a _ => rfl /-- The separation quotient functor acting on functions. -/ diff --git a/Mathlib/Topology/VectorBundle/Basic.lean b/Mathlib/Topology/VectorBundle/Basic.lean index 475928158c9177..d2087abfa8b647 100644 --- a/Mathlib/Topology/VectorBundle/Basic.lean +++ b/Mathlib/Topology/VectorBundle/Basic.lean @@ -131,7 +131,7 @@ theorem coe_linearMapAt (e : Pretrivialization F (π F E)) [e.IsLinear R] (b : B @[simp] theorem coe_linearMapAt_of_mem (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) : ⇑(e.linearMapAt R b) = fun y => (e ⟨b, y⟩).2 := by - simp_rw [coe_linearMapAt, if_pos hb] + simp_rw [coe_linearMapAt, ite_eq_left hb] open scoped Classical in theorem linearMapAt_apply (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (y : E b) : @@ -140,15 +140,15 @@ theorem linearMapAt_apply (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : theorem linearMapAt_def_of_mem (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) : e.linearMapAt R b = e.linearEquivAt R b hb := - dif_pos hb + dite_eq_left hb theorem linearMapAt_def_of_notMem (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∉ e.baseSet) : e.linearMapAt R b = 0 := - dif_neg hb + dite_eq_right hb theorem linearMapAt_eq_zero (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∉ e.baseSet) : e.linearMapAt R b = 0 := - dif_neg hb + dite_eq_right hb theorem symmₗ_linearMapAt (e : Pretrivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) (y : E b) : e.symmₗ R b (e.linearMapAt R b y) = y := by simp [hb] @@ -231,7 +231,7 @@ theorem coe_linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] (b : B) : @[simp] theorem coe_linearMapAt_of_mem (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) : ⇑(e.linearMapAt R b) = fun y => (e ⟨b, y⟩).2 := by - simp_rw [coe_linearMapAt, if_pos hb] + simp_rw [coe_linearMapAt, ite_eq_left hb] open scoped Classical in theorem linearMapAt_apply (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (y : E b) : @@ -240,11 +240,11 @@ theorem linearMapAt_apply (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} theorem linearMapAt_def_of_mem (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) : e.linearMapAt R b = e.linearEquivAt R b hb := - dif_pos hb + dite_eq_left hb theorem linearMapAt_def_of_notMem (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∉ e.baseSet) : e.linearMapAt R b = 0 := - dif_neg hb + dite_eq_right hb theorem symm_linearMapAt (e : Trivialization F (π F E)) [e.IsLinear R] {b : B} (hb : b ∈ e.baseSet) (y : E b) : e.symm b (e.linearMapAt R b y) = y := by @@ -274,27 +274,27 @@ def coordChangeL (e e' : Trivialization F (π F E)) [e.IsLinear R] [e'.IsLinear else LinearEquiv.refl R F continuous_toFun := by by_cases hb : b ∈ e.baseSet ∩ e'.baseSet - · rw [dif_pos hb] + · rw [dite_eq_left hb] refine (e'.continuousOn.comp_continuous ?_ ?_).snd · exact e.continuousOn_symm.comp_continuous (Continuous.prodMk_right b) fun y => mk_mem_prod hb.1 (mem_univ y) · exact fun y => e'.mem_source.mpr hb.2 - · rw [dif_neg hb] + · rw [dite_eq_right hb] exact continuous_id continuous_invFun := by by_cases hb : b ∈ e.baseSet ∩ e'.baseSet - · rw [dif_pos hb] + · rw [dite_eq_left hb] refine (e.continuousOn.comp_continuous ?_ ?_).snd · exact e'.continuousOn_symm.comp_continuous (Continuous.prodMk_right b) fun y => mk_mem_prod hb.2 (mem_univ y) exact fun y => e.mem_source.mpr hb.1 - · rw [dif_neg hb] + · rw [dite_eq_right hb] exact continuous_id } theorem coe_coordChangeL (e e' : Trivialization F (π F E)) [e.IsLinear R] [e'.IsLinear R] {b : B} (hb : b ∈ e.baseSet ∩ e'.baseSet) : ⇑(coordChangeL R e e' b) = (e.linearEquivAt R b hb.1).symm.trans (e'.linearEquivAt R b hb.2) := - congr_arg (fun f : F ≃ₗ[R] F ↦ ⇑f) (dif_pos hb) + congr_arg (fun f : F ≃ₗ[R] F ↦ ⇑f) (dite_eq_left hb) theorem coe_coordChangeL' (e e' : Trivialization F (π F E)) [e.IsLinear R] [e'.IsLinear R] {b : B} (hb : b ∈ e.baseSet ∩ e'.baseSet) : @@ -339,7 +339,7 @@ theorem coordChangeL_symm_apply (e e' : Trivialization F (π F E)) [e.IsLinear R {b : B} (hb : b ∈ e.baseSet ∩ e'.baseSet) : ⇑(coordChangeL R e e' b).symm = (e'.linearEquivAt R b hb.2).symm.trans (e.linearEquivAt R b hb.1) := - congr_arg LinearEquiv.invFun (dif_pos hb) + congr_arg LinearEquiv.invFun (dite_eq_left hb) end Bundle.Trivialization diff --git a/MathlibTest/LibraryRewrite.lean b/MathlibTest/LibraryRewrite.lean index b3fe910d24e685..47e1003483b231 100644 --- a/MathlibTest/LibraryRewrite.lean +++ b/MathlibTest/LibraryRewrite.lean @@ -130,7 +130,7 @@ info: Pattern n / 2 Pattern x / y · if 0 < 2 ∧ 2 ≤ n then (n - 2) / 2 + 1 else 0 - Nat.div_eq + Nat.div_eq_ite · (n - n % 2) / 2 Nat.div_eq_sub_mod_div · 0 diff --git a/MathlibTest/Linter/Whitespace.lean b/MathlibTest/Linter/Whitespace.lean index 704aa027125f20..e1b1446afcf200 100644 --- a/MathlibTest/Linter/Whitespace.lean +++ b/MathlibTest/Linter/Whitespace.lean @@ -11,13 +11,13 @@ section set_option linter.style.setOption true /-- -warning: `linter.style.commandStart` has been deprecated: use the `linter.style.whitespace` option instead +warning: `linter.style.commandStart` has been deprecated: Use `linter.style.whitespace` instead -/ #guard_msgs in set_option linter.style.commandStart true /-- -warning: `linter.style.commandStart` has been deprecated: use the `linter.style.whitespace` option instead +warning: `linter.style.commandStart` has been deprecated: Use `linter.style.whitespace` instead -/ #guard_msgs in set_option linter.style.commandStart true in diff --git a/MathlibTest/Util/CountHeartbeats.lean b/MathlibTest/Util/CountHeartbeats.lean index 044f069bf77485..79ae60cada1576 100644 --- a/MathlibTest/Util/CountHeartbeats.lean +++ b/MathlibTest/Util/CountHeartbeats.lean @@ -19,72 +19,14 @@ example (a : Nat) : a = a := rfl guard_min_heartbeats approximately 1 in example (a : Nat) : a = a := rfl -/-! -# Tests for the `countHeartbeats` linter --/ - -section using_count_heartbeats - --- sets the `countHeartbeats` both linter option and the `approximate` option to `true` -/-- -warning: syntax 'Mathlib.Linter.CountHeartbeats.countHeartbeats' has been deprecated: use `#count_heartbeats in` or `set_option trace.profiler true` with `set_option trace.profiler.useHeartbeats true` - -Note: This linter can be disabled with `set_option linter.deprecated.syntax false` --/ -#guard_msgs in -#count_heartbeats approximately - -mutual -- mutual declarations get ignored -theorem XY : True := trivial -end - +-- The `countHeartbeats` linter and its option-setting `#count_heartbeats` notation were deprecated +-- (lean4, 2026-07-30) in favour of `#count_heartbeats in`, so the linter-specific tests have been +-- retired. This preserves the non-trivial-count coverage via `#count_heartbeats in`, which is +-- exactly what the linter invoked internally for each declaration. /-- info: Used approximately 1000 heartbeats, which is less than the current maximum of 200000. -/ #guard_msgs in --- we use two nested `set_option ... in` to test that the `heartBeats` linter enters both. -set_option linter.unusedTactic false in set_option linter.unusedTactic false in +#count_heartbeats approximately in example : True := by - sleep_heartbeats 1000 -- on top of these heartbeats, a few more are used by the rest of the proof + sleep_heartbeats 1000 trivial - -/-- info: Used approximately 0 heartbeats, which is less than the current maximum of 200000. -/ -#guard_msgs in -example : True := trivial - -/-- info: 'YX' used approximately 0 heartbeats, which is less than the current maximum of 200000. -/ -#guard_msgs in -set_option linter.unusedTactic false in -set_option linter.unusedTactic false in -theorem YX : True := trivial - -end using_count_heartbeats - -section using_linter_option - -set_option linter.countHeartbeats true -set_option linter.countHeartbeatsApprox true - -mutual -- mutual declarations get ignored -theorem XY' : True := trivial -end - -/-- info: Used approximately 0 heartbeats, which is less than the current maximum of 200000. -/ -#guard_msgs in --- we use two nested `set_option ... in` to test that the `heartBeats` linter enters both. -set_option linter.unusedTactic false in -set_option linter.unusedTactic false in -example : True := trivial - -/-- info: Used approximately 0 heartbeats, which is less than the current maximum of 200000. -/ -#guard_msgs in -example : True := trivial - -/-- -info: 'YX'' used approximately 0 heartbeats, which is less than the current maximum of 200000. --/ -#guard_msgs in -set_option linter.unusedTactic false in -set_option linter.unusedTactic false in -theorem YX' : True := trivial - -end using_linter_option diff --git a/lake-manifest.json b/lake-manifest.json index 1a4cd1dbe61cb8..0627cad184fddf 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b7eb3304aeae834b12dda98993a37f6a41f6f0bb", + "rev": "38e9c3ce15cbb63c92e90bb9a92e4eb82131f669", "name": "plausible", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "5f4d51b81cbd3f6b32b156bfad9056621a040404", + "rev": "2bc7cf064315b26bc38dac2e9612fb581be9b75f", "name": "LeanSearchClient", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "16f02aa7642864af59f1ff0e384a015994db9118", + "rev": "978b7ec9fbbf9a535114f1de8fe5b3778b358870", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -35,7 +35,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4be2e3d5087eeb272cf5a8853b8f9dd025ef5957", + "rev": "99e8adeea3c3cd86b6b79ba01a1383bf2d31d055", "name": "proofwidgets", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -45,7 +45,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "3448c0bcc5ce01b2d1546e483ec3620e32df3d0e", + "rev": "c1c4362a130f12e632d252180a6c2a31d8fd4726", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "92c15be17b7caf78c2ad767ec40f89052d908d81", + "rev": "3b55e9d00c6b0018e5d984eb011b6f93c09bd163", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4488d40d070b9700d4d5a6aa342f0d40c31b2a2d", + "rev": "01bc479e7432594821ba3fb0ca465211941de86d", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -75,10 +75,10 @@ "type": "git", "subDir": null, "scope": "leanprover", - "rev": "6130a47896ce867c6a4a55373441e59e565bad0f", + "rev": "af8bc067a4cc6c6df472a68909a3f40b1c76c43e", "name": "Cli", "manifestFile": "lake-manifest.json", - "inputRev": "v4.33.0", + "inputRev": "v4.34.0-rc1", "inherited": true, "configFile": "lakefile.toml"}], "name": "mathlib", diff --git a/lean-toolchain b/lean-toolchain index 025e59548e48cf..75def60936d3c4 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.33.0 +leanprover/lean4:v4.34.0-rc1 From 2918a25dd559a110d5a3d48e97071cdeb1f89769 Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen <5209952+bryangingechen@users.noreply.github.com> Date: Tue, 11 Aug 2026 07:20:01 +0000 Subject: [PATCH 1268/1300] chore: add `shake: keep` to imports that `shake --fix` wrongly drops (#42631) Found by examining the [latest build failure](https://github.com/leanprover-community/mathlib4/actions/runs/31334112781) for the automated shake --fix PR at #40343. Two fixes: * `Mathlib/Tactic/DuplicateDecls.lean`: shake demotes `public import ImportGraph.Lean.Environment` to `meta import`, since `Environment.getModuleFor?` is only reached through the private meta helper `mkModuleKey!`, so no `metaPub` need is ever recorded for it. This is leanprover/lean4#14427. * `Mathlib/Tactic/NormDet.lean`: shake drops the imports providing `Matrix.det` and `BirdDet.det_eq_birdDet`. Both are referenced only inside `q(...)`/`~q(...)` quotations and the `simproc_decl norm_det (Matrix.det _)` pattern, so they are invisible to `calcNeeds`, which only walks `Expr.foldConsts`. Generated with Claude code --- Mathlib/Tactic/DuplicateDecls.lean | 2 +- Mathlib/Tactic/NormDet.lean | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Tactic/DuplicateDecls.lean b/Mathlib/Tactic/DuplicateDecls.lean index cce91a0ef9278f..76bad352bd6990 100644 --- a/Mathlib/Tactic/DuplicateDecls.lean +++ b/Mathlib/Tactic/DuplicateDecls.lean @@ -6,7 +6,7 @@ Authors: Jovan Gerbscheid module public import Mathlib.Init -public import ImportGraph.Lean.Environment +public import ImportGraph.Lean.Environment -- shake: keep (Environment.getModuleFor? is used from public meta code), cf. lean#14427 /-! # A tool for finding duplicate declarations diff --git a/Mathlib/Tactic/NormDet.lean b/Mathlib/Tactic/NormDet.lean index f94552edc5052f..18e5cbf69cffac 100644 --- a/Mathlib/Tactic/NormDet.lean +++ b/Mathlib/Tactic/NormDet.lean @@ -5,8 +5,8 @@ Authors: Paul Cadman -/ module -public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic -public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Correctness +public import Mathlib.LinearAlgebra.Matrix.Determinant.Basic -- shake: keep (Matrix.det, Qq dependency) +public import Mathlib.LinearAlgebra.Matrix.Determinant.Bird.Correctness -- shake: keep (BirdDet.det_eq_birdDet, Qq dependency) public meta import Mathlib.Tactic.Determinant.Bird.Cert /-! From 70756d9213adc74ea414e9e80a88be24350ce432 Mon Sep 17 00:00:00 2001 From: Jovan Gerbscheid <56355248+JovanGerb@users.noreply.github.com> Date: Tue, 11 Aug 2026 08:41:56 +0000 Subject: [PATCH 1269/1300] chore: remove more backward options that are blocking `scripts/rm_set_option.py` (#42270) This PR removes some backward options that can be removed, but in doing so trigger the unused simp arguments linter. See also [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/4.2E33.2E0-rc1.20Multiple.20.60respectTransparency.60-related.20issues/near/613533366) --- Mathlib/Algebra/Category/Grp/Colimits.lean | 4 +--- Mathlib/Algebra/Homology/Opposite.lean | 7 +------ Mathlib/Condensed/Discrete/LocallyConstant.lean | 10 ++++------ Mathlib/MeasureTheory/VectorMeasure/Integral.lean | 7 ++----- .../Kernel/Disintegration/MeasurableStieltjes.lean | 7 ++----- Mathlib/RingTheory/LaurentSeries.lean | 1 - Mathlib/RingTheory/Valuation/Basic.lean | 1 + Mathlib/Topology/Category/TopCat/Limits/Products.lean | 8 ++------ 8 files changed, 13 insertions(+), 32 deletions(-) diff --git a/Mathlib/Algebra/Category/Grp/Colimits.lean b/Mathlib/Algebra/Category/Grp/Colimits.lean index ad8f228263a35e..9cbe4343e0f201 100644 --- a/Mathlib/Algebra/Category/Grp/Colimits.lean +++ b/Mathlib/Algebra/Category/Grp/Colimits.lean @@ -142,14 +142,12 @@ def quotUliftToQuot [DecidableEq J] : Quot (F ⋙ uliftFunctor.{u'}) →+ Quot F obtain ⟨j, j', u, a, rfl⟩ := hx simp -set_option backward.isDefEq.respectTransparency.types false in lemma quotUliftToQuot_ι [DecidableEq J] (j : J) (x : (F ⋙ uliftFunctor.{u'}).obj j) : quotUliftToQuot F (Quot.ι _ j x) = Quot.ι F j x.down := by dsimp [quotUliftToQuot, Quot.ι] conv_lhs => erw [AddMonoidHom.comp_apply (QuotientAddGroup.mk' (Relations (F ⋙ uliftFunctor))) (DFinsupp.singleAddHom _ j), QuotientAddGroup.lift_mk'] - simp only [DFinsupp.singleAddHom_apply, - DFinsupp.sumAddHom_single, AddMonoidHom.coe_comp, Function.comp_apply] + simp only [DFinsupp.singleAddHom_apply, DFinsupp.sumAddHom_single] rfl set_option backward.isDefEq.respectTransparency.types false in diff --git a/Mathlib/Algebra/Homology/Opposite.lean b/Mathlib/Algebra/Homology/Opposite.lean index 95ddefeb50cc8d..90dec953c0fe61 100644 --- a/Mathlib/Algebra/Homology/Opposite.lean +++ b/Mathlib/Algebra/Homology/Opposite.lean @@ -151,7 +151,6 @@ def opCounitIso : opInverse V c ⋙ opFunctor V c ≅ 𝟭 (HomologicalComplex V NatIso.ofComponents fun X => HomologicalComplex.Hom.isoOfComponents fun _ => Iso.refl _ -set_option backward.isDefEq.respectTransparency.types false in /-- Given a category of complexes with objects in `V`, there is a natural equivalence between its opposite category and a category of complexes with objects in `Vᵒᵖ`. -/ @[simps] @@ -160,11 +159,7 @@ def opEquivalence : (HomologicalComplex V c)ᵒᵖ ≌ HomologicalComplex Vᵒ inverse := opInverse V c unitIso := opUnitIso V c counitIso := opCounitIso V c - functor_unitIso_comp X := by - ext - simp only [opUnitIso, opCounitIso, NatIso.ofComponents_hom_app, Iso.op_hom, comp_f, - opFunctor_map_f, Hom.isoOfComponents_hom_f] - exact Category.comp_id _ + functor_unitIso_comp _ := Category.comp_id (𝟙 _) instance : (opFunctor V c).IsEquivalence := (opEquivalence V c).isEquivalence_functor instance : (opInverse V c).IsEquivalence := (opEquivalence V c).isEquivalence_inverse diff --git a/Mathlib/Condensed/Discrete/LocallyConstant.lean b/Mathlib/Condensed/Discrete/LocallyConstant.lean index 58d06717aef32d..a903ffa546c948 100644 --- a/Mathlib/Condensed/Discrete/LocallyConstant.lean +++ b/Mathlib/Condensed/Discrete/LocallyConstant.lean @@ -81,7 +81,7 @@ namespace CompHausLike.LocallyConstant The functor from the category of sets to presheaves on `CompHausLike P` given by locally constant maps. -/ -@[simps obj_obj obj_map map_app] +@[implicit_reducible, simps obj_obj obj_map map_app] def functorToPresheaves : Type (max u w) ⥤ ((CompHausLike.{u} P)ᵒᵖ ⥤ Type (max u w)) where obj X := { obj := fun ⟨S⟩ ↦ (LocallyConstant S X) @@ -231,7 +231,7 @@ noncomputable def functorToPresheavesIso (X : Type (max u w)) : NatIso.ofComponents (fun S ↦ locallyConstantIsoContinuousMap _ _) /-- `CompHausLike.LocallyConstant.functorToPresheaves` lands in sheaves. -/ -@[simps! obj_obj_obj obj_obj_map map_hom_app] +@[implicit_reducible, simps! obj_obj_obj obj_obj_map map_hom_app] def functor : haveI := CompHausLike.preregular hs Type (max u w) ⥤ Sheaf (coherentTopology (CompHausLike.{u} P)) (Type (max u w)) := @@ -310,8 +310,6 @@ noncomputable def unitIso : 𝟭 (Type (max u w)) ≅ functor.{u, w} P hs ⋙ hom := unit P hs inv := { app _ := ↾fun f ↦ f.toFun PUnit.unit } -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in lemma adjunction_left_triangle [HasExplicitFiniteCoproducts.{u} P] (X : Type (max u w)) : functorToPresheaves.{u, w}.map ((unit P hs).app X) ≫ ((counit P hs).app ((functor P hs).obj X)).hom = 𝟙 (functorToPresheaves.obj X) := by @@ -328,10 +326,10 @@ lemma adjunction_left_triangle [HasExplicitFiniteCoproducts.{u} P] intro a erw [incl_of_counitAppApp] simp only [functor_obj_obj_obj, Functor.id_obj, Functor.comp_obj, Functor.flip_obj_obj, - ObjectProperty.ι_obj, unit_app, counitAppAppImage, functor_obj_obj_map, + ObjectProperty.ι_obj, counitAppAppImage, functor_obj_obj_map, Quiver.Hom.unop_op, ConcreteCategory.hom_ofHom] ext x - erw [← map_eq_image _ a x] + rw [← map_eq_image _ a x] rfl set_option backward.isDefEq.respectTransparency.types false in diff --git a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean index e6ec621e482108..d21af83a8b33a2 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Integral.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Integral.lean @@ -191,7 +191,6 @@ instance [IsFiniteMeasure μ.variation] : IsFiniteMeasure (μ.transpose B).variation := isFiniteMeasure_of_le _ (variation_transpose_le μ B) -set_option backward.isDefEq.respectTransparency.types false in lemma variation_transpose_eq_smul [Nontrivial E] {C : ℝ≥0} (hB : ∀ x y, ‖B x y‖₊ = C * ‖x‖₊ * ‖y‖₊) : (μ.transpose B).variation = C • μ.variation := by @@ -205,14 +204,12 @@ lemma variation_transpose_eq_smul [Nontrivial E] {C : ℝ≥0} grw [this, smul_smul, mul_inv_cancel₀ hC, one_smul] apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) have : ‖μ s‖ₑ ≤ C⁻¹ • ‖(μ.transpose B) s‖ₑ := by - simp only [transpose, mapRange_apply, LinearMap.toAddMonoidHom_coe, coe_coe] obtain ⟨x, hx⟩ : ∃ (x : E), x ≠ 0 := exists_ne 0 have : ‖B.flip (μ s) x‖₊ ≤ ‖B.flip (μ s)‖₊ * ‖x‖₊ := le_opNNNorm _ _ simp only [flip_apply, hB] at this rw [mul_right_comm, mul_le_mul_iff_left₀ (by simpa), ← le_div_iff₀' (by positivity), - div_eq_inv_mul] at this - change ENNReal.ofNNReal _ ≤ ENNReal.ofNNReal _ - gcongr + div_eq_inv_mul, ← ENNReal.coe_le_coe] at this + exact this grw [this, enorm_measure_le_variation, Measure.smul_apply] lemma variation_transpose_eq [Nontrivial E] (hB : ∀ x y, ‖B x y‖₊ = ‖x‖₊ * ‖y‖₊) : diff --git a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean index eb2c8f33cbfbfc..f215e43e07a759 100644 --- a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean +++ b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean @@ -291,18 +291,15 @@ lemma IsMeasurableRatCDF.stieltjesFunctionAux_unit_prod {f : α → ℚ → ℝ} variable {f : α → ℚ → ℝ} [MeasurableSpace α] (hf : IsMeasurableRatCDF f) include hf -set_option backward.isDefEq.respectTransparency false in lemma IsMeasurableRatCDF.stieltjesFunctionAux_eq (a : α) (r : ℚ) : IsMeasurableRatCDF.stieltjesFunctionAux f a r = f a r := by rw [← hf.iInf_rat_gt_eq a r, IsMeasurableRatCDF.stieltjesFunctionAux] refine Equiv.iInf_congr ?_ ?_ · exact { toFun := fun t ↦ ⟨t.1, mod_cast t.2⟩ - invFun := fun t ↦ ⟨t.1, mod_cast t.2⟩ - left_inv := fun t ↦ by simp only [Subtype.coe_eta] - right_inv := fun t ↦ by simp only [Subtype.coe_eta] } + invFun := fun t ↦ ⟨t.1, mod_cast t.2⟩ } · intro t - simp only [Equiv.coe_fn_mk, Subtype.coe_mk] + rfl lemma IsMeasurableRatCDF.stieltjesFunctionAux_nonneg (a : α) (r : ℝ) : 0 ≤ IsMeasurableRatCDF.stieltjesFunctionAux f a r := by diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index 84121674ed44b7..e0b580bd6319c4 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -1070,7 +1070,6 @@ theorem valuation_LaurentSeries_equal_extension : rfl · exact Valued.continuous_valuation_of_surjective (valuation_surjective K) -set_option backward.isDefEq.respectTransparency.types false in theorem tendsto_valuation (a : (idealX K).adicCompletion K⟮X⟯) : Tendsto (Valued.v : K⟮X⟯ → ℤᵐ⁰) (comap (↑) (𝓝 a)) (𝓝 (Valued.v a : ℤᵐ⁰)) := by have := Valued.is_topological_valuation (R := (idealX K).adicCompletion K⟮X⟯) diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index 2df7c21a68e8cd..deb2d06519d661 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -463,6 +463,7 @@ lemma leAddSubgroup_monotone (v : Valuation R Γ₀) : Monotone v.leAddSubgroup open MonoidWithZeroHom MonoidWithZeroHom.ValueGroup₀ /-- The restriction of a valuation so that it takes values in its `valueGroup₀`. -/ +@[implicit_reducible] def restrict : Valuation R (ValueGroup₀ (.ofClass v)) where __ := restrict₀ (.ofClass v) map_add_le_max' x y := by diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index 30cc9943356347..33c3726c7fe051 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -152,18 +152,14 @@ equipped with the product topology. def prodIsoProd (X Y : TopCat.{u}) : X ⨯ Y ≅ TopCat.of (X × Y) := (limit.isLimit _).conePointUniqueUpToIso (prodBinaryFanIsLimit X Y) -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem prodIsoProd_hom_fst (X Y : TopCat.{u}) : - (prodIsoProd X Y).hom ≫ prodFst = Limits.prod.fst := by - simp [← Iso.eq_inv_comp, prodIsoProd] + (prodIsoProd X Y).hom ≫ prodFst = Limits.prod.fst := rfl -set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] theorem prodIsoProd_hom_snd (X Y : TopCat.{u}) : - (prodIsoProd X Y).hom ≫ prodSnd = Limits.prod.snd := by - simp [← Iso.eq_inv_comp, prodIsoProd] + (prodIsoProd X Y).hom ≫ prodSnd = Limits.prod.snd := rfl -- Note that `(x : X ⨯ Y)` would mean `(x : ↑X × ↑Y)` below: From 4302786da0bfce087fc701c860f91eb1154bb45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 09:07:32 +0000 Subject: [PATCH 1270/1300] feat(CategoryTheory/Bicategory): a retract of an equivalence is an equivalence (#42589) --- Mathlib.lean | 1 + .../Bicategory/Adjunction/Basic.lean | 8 + .../Bicategory/Functor/LocallyDiscrete.lean | 4 +- .../Bicategory/Functor/Pseudofunctor.lean | 4 +- .../Bicategory/RetractArrow.lean | 152 ++++++++++++++++++ 5 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 Mathlib/CategoryTheory/Bicategory/RetractArrow.lean diff --git a/Mathlib.lean b/Mathlib.lean index d03e6bafadcf88..aa20d8c3eb4aaf 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2573,6 +2573,7 @@ public import Mathlib.CategoryTheory.Bicategory.NaturalTransformation.Oplax public import Mathlib.CategoryTheory.Bicategory.NaturalTransformation.Pseudo public import Mathlib.CategoryTheory.Bicategory.Opposites public import Mathlib.CategoryTheory.Bicategory.Product +public import Mathlib.CategoryTheory.Bicategory.RetractArrow public import Mathlib.CategoryTheory.Bicategory.SingleObj public import Mathlib.CategoryTheory.Bicategory.Span.Basic public import Mathlib.CategoryTheory.Bicategory.Strict.Basic diff --git a/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean b/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean index b255d46edd7c89..db86a5f382c1a9 100644 --- a/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean +++ b/Mathlib/CategoryTheory/Bicategory/Adjunction/Basic.lean @@ -282,6 +282,14 @@ def mkOfAdjointifyCounit (η : 𝟙 a ≅ f ≫ g) (ε : g ≫ f ≅ 𝟙 b) : a counit := adjointifyCounit η ε left_triangle := adjointifyCounit_left_triangle η ε +/-- The adjunction induced by an equivalence in a bicategory. -/ +@[implicit_reducible, simps] +def adj (e : a ≌ b) : e.hom ⊣ e.inv where + unit := e.unit.hom + counit := e.counit.hom + left_triangle := e.left_triangle_hom + right_triangle := e.right_triangle_hom + end Equivalence end diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/LocallyDiscrete.lean b/Mathlib/CategoryTheory/Bicategory/Functor/LocallyDiscrete.lean index c5fe659faecdb9..268d436abbb534 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/LocallyDiscrete.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/LocallyDiscrete.lean @@ -125,7 +125,7 @@ corresponding locally discrete bicategories. This is just an abbreviation of `Functor.toPseudofunctor.toOplax`. -/ -@[simps! map] +@[simps! -isSimp map] abbrev Functor.toOplaxFunctor : LocallyDiscrete C ⥤ᵒᵖᴸ (LocallyDiscrete D) := F.toPseudofunctor.toOplax @@ -155,7 +155,7 @@ def Functor.toPseudofunctor' : LocallyDiscrete I ⥤ᵖ B := If `B` is a strict bicategory and `I` is a (1-)category, any functor (of 1-categories) `I ⥤ B` can be promoted to an oplax functor from `LocallyDiscrete I` to `B`. -/ -@[simps! map] +@[simps! -isSimp map] abbrev Functor.toOplaxFunctor' : LocallyDiscrete I ⥤ᵒᵖᴸ B := F.toPseudofunctor'.toOplax diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean index c65bcdfe25a8be..286407b5dc4fe7 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Pseudofunctor.lean @@ -115,7 +115,7 @@ attribute [nolint docBlame] CategoryTheory.Pseudofunctor.mapId variable (F : B ⥤ᵖ C) /-- The oplax functor associated with a pseudofunctor. -/ -@[simps] +@[implicit_reducible, simps] def toOplax : B ⥤ᵒᵖᴸ C where toPrelaxFunctor := F.toPrelaxFunctor mapId := fun a => (F.mapId a).hom @@ -125,7 +125,7 @@ instance hasCoeToOplax : Coe (B ⥤ᵖ C) (B ⥤ᵒᵖᴸ C) := ⟨toOplax⟩ /-- The lax functor associated with a pseudofunctor. -/ -@[simps] +@[implicit_reducible, simps] def toLax : B ⥤ᴸ C where toPrelaxFunctor := F.toPrelaxFunctor mapId := fun a => (F.mapId a).inv diff --git a/Mathlib/CategoryTheory/Bicategory/RetractArrow.lean b/Mathlib/CategoryTheory/Bicategory/RetractArrow.lean new file mode 100644 index 00000000000000..96d0beb2279d32 --- /dev/null +++ b/Mathlib/CategoryTheory/Bicategory/RetractArrow.lean @@ -0,0 +1,152 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.Bicategory.Adjunction.Basic +public import Mathlib.CategoryTheory.Bicategory.LocallyDiscrete +public import Mathlib.CategoryTheory.Retract + +/-! +# Retracts of 1-morphisms in bicategories + +If `f : X ⟶ Y` and `f' : X' ⟶ Y'` are 1-morphisms in a bicategory, +we introduce a structure `RetractArrow₁ f' f` expressing that +`f'` is a retract of `f`, and we show that if `f` is an +equivalence, then `f'` is also an equivalence. + +-/ + +@[expose] public section + +universe w v u + +namespace CategoryTheory + +namespace Bicategory + +variable {C : Type u} [Bicategory.{w, v} C] {X Y X' Y' : C} + +/-- A structure expressing that a 1-morphism `f' : X' ⟶ Y`' +in a bicategory is a retract of `f : X ⟶ Y`. -/ +structure RetractArrow₁ (f' : X' ⟶ Y') (f : X ⟶ Y) where + /-- the inclusion of the source object -/ + i₁ : X' ⟶ X + /-- the retraction to the source object -/ + r₁ : X ⟶ X' + /-- the inclusion of the target object -/ + i₂ : Y' ⟶ Y + /-- the retraction to the target object -/ + r₂ : Y ⟶ Y' + /-- the source of `f'` is a retract of the source of `f` -/ + id₁ : i₁ ≫ r₁ ≅ 𝟙 X' + /-- the target of `f'` is a retract of the target of `f` -/ + id₂ : i₂ ≫ r₂ ≅ 𝟙 Y' + /-- compatibility of the inclusions -/ + commi : f' ≫ i₂ ≅ i₁ ≫ f + /-- compatibility of the retractions -/ + commr : f ≫ r₂ ≅ r₁ ≫ f' + comm : commi.hom ▷ r₂ ≫ (α_ _ _ _).hom ≫ i₁ ◁ commr.hom = + (α_ _ _ _).hom ≫ f' ◁ id₂.hom ≫ (ρ_ _).hom ≫ (λ_ _).inv ≫ + id₁.inv ▷ f' ≫ (α_ _ _ _).hom := by cat_disch + +namespace RetractArrow₁ + +attribute [reassoc] comm + +@[reassoc] +lemma comm' {f' : X' ⟶ Y'} {f : X ⟶ Y} (r : RetractArrow₁ f' f) : + r.i₁ ◁ r.commr.inv ≫ (α_ _ _ _).inv ≫ r.commi.inv ▷ r.r₂ = + (α_ _ _ _).inv ≫ r.id₁.hom ▷ f' ≫ (λ_ _).hom ≫ (ρ_ _).inv ≫ + f' ◁ r.id₂.inv ≫ (α_ _ _ _).inv := by + rw [← cancel_epi (r.i₁ ◁ r.commr.hom), + ← cancel_epi (α_ _ _ _).hom, + ← cancel_epi (r.commi.hom ▷ r.r₂)] + nth_rw 2 [r.comm_assoc] + simp + +/-- If a `1`-morphism is a retract of another, it stays so +after the applicaton of a pseudofunctor. -/ +@[implicit_reducible, simps] +def map {f' : X' ⟶ Y'} {f : X ⟶ Y} (r : RetractArrow₁ f' f) + {D : Type*} [Bicategory D] (F : C ⥤ᵖ D) : + RetractArrow₁ (F.map f') (F.map f) where + i₁ := F.map r.i₁ + i₂ := F.map r.i₂ + r₁ := F.map r.r₁ + r₂ := F.map r.r₂ + id₁ := (F.mapComp _ _).symm ≪≫ F.map₂Iso r.id₁ ≪≫ F.mapId _ + id₂ := (F.mapComp _ _).symm ≪≫ F.map₂Iso r.id₂ ≪≫ F.mapId _ + commi := (F.mapComp _ _).symm ≪≫ F.map₂Iso r.commi ≪≫ F.mapComp _ _ + commr := (F.mapComp _ _).symm ≪≫ F.map₂Iso r.commr ≪≫ F.mapComp _ _ + comm := by + have := congr_arg (fun f ↦ F.map₂ f) r.comm + simp at this + simp [← cancel_mono (F.map r.i₁ ◁ (F.mapComp r.r₁ f').inv), + ← cancel_mono ((F.mapComp r.i₁ (r.r₁ ≫ f')).inv), + this, dsimp% F.toLax.map₂_leftUnitor_assoc f'] + +/-- In a bicategory, a `1`-morphism that is a retract +of an equivalence is an equivalence. -/ +@[implicit_reducible, simps] +def equivalence {f' : X' ⟶ Y'} {f : X ≌ Y} (r : RetractArrow₁ f' f.hom) : + X' ≌ Y' where + hom := f' + inv := r.i₂ ≫ f.inv ≫ r.r₁ + unit := + r.id₁.symm ≪≫ _ ◁ᵢ (λ_ _).symm ≪≫ r.i₁ ◁ᵢ f.unit ▷ᵢ r.r₁ ≪≫ + _ ◁ᵢ (α_ _ _ _) ≪≫ (α_ _ _ _).symm ≪≫ (r.commi.symm ▷ᵢ (f.inv ≫ r.r₁)) ≪≫ α_ _ _ _ + counit := + α_ _ _ _ ≪≫ _ ◁ᵢ (α_ _ _ _ ≪≫ _ ◁ᵢ r.commr.symm ≪≫ (α_ _ _ _).symm) ≪≫ + r.i₂ ◁ᵢ f.counit ▷ᵢ r.r₂ ≪≫ _ ◁ᵢ λ_ _ ≪≫ r.id₂ + left_triangle := by + ext : 1 + calc + _ = r.id₁.inv ▷ f' ⊗≫ ((r.i₁ ◁ f.unit.hom ⊗≫ r.commi.inv ▷ f.inv) ▷ (r.r₁ ≫ f') ≫ + ((f' ≫ r.i₂) ≫ f.inv) ◁ r.commr.inv) ⊗≫ + f' ◁ r.i₂ ◁ f.counit.hom ▷ r.r₂ ⊗≫ f' ◁ r.id₂.hom := by + simp only [leftZigzagIso, leftZigzagIso_hom, Iso.trans_hom, Iso.symm_hom, + whiskerLeftIso_hom, whiskerRightIso_hom] + bicategory + _ = r.id₁.inv ▷ f' ⊗≫ r.i₁ ◁ r.commr.inv ⊗≫ + (r.i₁ ◁ f.unit.hom) ▷ (f.hom ≫ r.r₂) ⊗≫ + ((r.commi.inv ▷ (f.inv ≫ f.hom) ≫ (f' ≫ r.i₂) ◁ f.counit.hom) ▷ r.r₂) ⊗≫ + f' ◁ r.id₂.hom := by + rw [← whisker_exchange] + bicategory + _ = r.id₁.inv ▷ f' ⊗≫ r.i₁ ◁ r.commr.inv ⊗≫ + r.i₁ ◁ (leftZigzag f.unit.hom f.counit.hom) ▷ r.r₂ ⊗≫ + (r.commi.inv ▷ r.r₂) ⊗≫ f' ◁ r.id₂.hom := by + rw [← whisker_exchange] + bicategory + _ = r.id₁.inv ▷ f' ⊗≫ r.i₁ ◁ r.commr.inv ⊗≫ + (r.commi.inv ▷ r.r₂) ⊗≫ f' ◁ r.id₂.hom := by + rw [f.left_triangle_hom] + bicategory + _ = _ := by + simp [bicategoricalComp, r.comm'_assoc] + +end RetractArrow₁ + +end Bicategory + +open Bicategory + +/-- A retract of morphisms in a category `C` induces a retract of +`1`-morphisms in the bicategory `LocallyDiscrete C`. -/ +@[implicit_reducible, simps] +def RetractArrow.toLoc {C : Type*} [Category* C] {X Y X' Y' : C} + {f' : X' ⟶ Y'} {f : X ⟶ Y} (r : RetractArrow f' f) : + RetractArrow₁ (Quiver.Hom.toLoc f') (Quiver.Hom.toLoc f) where + i₁ := Quiver.Hom.toLoc r.i.left + i₂ := Quiver.Hom.toLoc r.i.right + r₁ := Quiver.Hom.toLoc r.r.left + r₂ := Quiver.Hom.toLoc r.r.right + id₁ := eqToIso (by simp [← Quiver.Hom.comp_toLoc]) + id₂ := eqToIso (by simp [← Quiver.Hom.comp_toLoc]) + commi := eqToIso (by simp [← Quiver.Hom.comp_toLoc]) + commr := eqToIso (by simp [← Quiver.Hom.comp_toLoc]) + +end CategoryTheory From e76467f1ca8698fd4029f2e1fbe1088f52b1ec23 Mon Sep 17 00:00:00 2001 From: Kevin Buzzard Date: Tue, 11 Aug 2026 09:31:14 +0000 Subject: [PATCH 1271/1300] feat: add new `Wanted` directory for proof_wanted. (#42284) Move all `proof_wanted` into a new `Wanted` directory. The philosophy of the `Wanted` directory: it contains no declarations, just `proof_wanted` (and ultimately `def_wanted` -- see below). It is organised in the same way as `Mathlib`, and can and will import from `Mathlib`, but files in `Mathlib` will never import from `Wanted`. One advantage of this reorganization is that in current master there are several `proof_wanted`s which are commented out because they don't compile without further imports, or imports which are marked `noshake` because they are only used in `proof_wanted`. The new system deals with this issue much better. Another advantage is that this reorganization now maintains a clearer boundary between what is proved in mathlib and what is desired. This reorganisation is in anticipation of mathlib adopting the extension `def_wanted` (available in Batteries, see e.g. [here](https://github.com/leanprover-community/batteries/blob/main/BatteriesTest/def_wanted.lean)), and thus being able to go on to state results which we would like to see in mathlib, in what the community thinks is a canonical form. Co-authored-by: Oliver Nash --- .github/workflows/build_template.yml | 29 +++++++--- .github/workflows/lake_cache_shadow.yml | 6 +-- .github/workflows/publish_tools.yml | 4 +- .github/workflows/remove_deprecated_decls.yml | 8 +-- Cache/IO.lean | 1 + Mathlib/Analysis/Convex/Cone/Basic.lean | 13 +---- Mathlib/Analysis/Convex/Continuous.lean | 13 ----- Mathlib/Analysis/Real/Pi/Chudnovsky.lean | 6 +-- .../Limits/Shapes/Countable.lean | 36 ++----------- .../SimpleGraph/StronglyRegular.lean | 6 --- .../TuringMachine/Computable.lean | 14 ----- Mathlib/Data/EReal/Operations.lean | 5 -- .../Geometry/Euclidean/Volume/Measure.lean | 7 --- .../Geometry/Manifold/PoincareConjecture.lean | 36 ++----------- .../Geometry/Manifold/SmoothEmbedding.lean | 11 ---- Mathlib/GroupTheory/GroupAction/Jordan.lean | 22 -------- Mathlib/Order/KrullDimension.lean | 12 ----- .../BinomialRandomGraph/Defs.lean | 6 --- .../Probability/Distributions/Binomial.lean | 14 ----- Mathlib/RingTheory/Congruence/Basic.lean | 6 --- Mathlib/RingTheory/Etale/Descent.lean | 11 +--- Mathlib/RingTheory/KrullDimension/Basic.lean | 5 -- Mathlib/RingTheory/SimpleModule/Basic.lean | 8 --- .../SimpleModule/WedderburnArtin.lean | 9 ---- .../Tactic/Linter/DirectoryDependency.lean | 5 ++ Wanted.lean | 21 ++++++++ Wanted/Analysis/Convex/Cone/Basic.lean | 23 ++++++++ Wanted/Analysis/Convex/Continuous.lean | 25 +++++++++ Wanted/Analysis/Real/Pi/Chudnovsky.lean | 14 +++++ .../Limits/Shapes/Countable.lean | 52 ++++++++++++++++++ .../SimpleGraph/StronglyRegular.lean | 18 +++++++ .../TuringMachine/Computable.lean | 26 +++++++++ Wanted/Data/EReal/Operations.lean | 18 +++++++ Wanted/Geometry/Euclidean/Volume/Measure.lean | 17 ++++++ .../Geometry/Manifold/PoincareConjecture.lean | 51 ++++++++++++++++++ Wanted/Geometry/Manifold/SmoothEmbedding.lean | 41 ++++++++++++++ Wanted/GroupTheory/GroupAction/Jordan.lean | 54 +++++++++++++++++++ Wanted/Order/KrullDimension.lean | 25 +++++++++ .../BinomialRandomGraph/Defs.lean | 21 ++++++++ .../Probability/Distributions/Binomial.lean | 30 +++++++++++ Wanted/RingTheory/Congruence/Basic.lean | 24 +++++++++ Wanted/RingTheory/Etale/Descent.lean | 31 +++++++++++ Wanted/RingTheory/KrullDimension/Basic.lean | 15 ++++++ Wanted/RingTheory/SimpleModule/Basic.lean | 20 +++++++ .../SimpleModule/WedderburnArtin.lean | 19 +++++++ lakefile.lean | 13 +++++ 46 files changed, 607 insertions(+), 244 deletions(-) create mode 100644 Wanted.lean create mode 100644 Wanted/Analysis/Convex/Cone/Basic.lean create mode 100644 Wanted/Analysis/Convex/Continuous.lean create mode 100644 Wanted/Analysis/Real/Pi/Chudnovsky.lean create mode 100644 Wanted/CategoryTheory/Limits/Shapes/Countable.lean create mode 100644 Wanted/Combinatorics/SimpleGraph/StronglyRegular.lean create mode 100644 Wanted/Computability/TuringMachine/Computable.lean create mode 100644 Wanted/Data/EReal/Operations.lean create mode 100644 Wanted/Geometry/Euclidean/Volume/Measure.lean create mode 100644 Wanted/Geometry/Manifold/PoincareConjecture.lean create mode 100644 Wanted/Geometry/Manifold/SmoothEmbedding.lean create mode 100644 Wanted/GroupTheory/GroupAction/Jordan.lean create mode 100644 Wanted/Order/KrullDimension.lean create mode 100644 Wanted/Probability/Combinatorics/BinomialRandomGraph/Defs.lean create mode 100644 Wanted/Probability/Distributions/Binomial.lean create mode 100644 Wanted/RingTheory/Congruence/Basic.lean create mode 100644 Wanted/RingTheory/Etale/Descent.lean create mode 100644 Wanted/RingTheory/KrullDimension/Basic.lean create mode 100644 Wanted/RingTheory/SimpleModule/Basic.lean create mode 100644 Wanted/RingTheory/SimpleModule/WedderburnArtin.lean diff --git a/.github/workflows/build_template.yml b/.github/workflows/build_template.yml index 5ca82877f1e83b..b757ad206f4b53 100644 --- a/.github/workflows/build_template.yml +++ b/.github/workflows/build_template.yml @@ -57,6 +57,7 @@ jobs: build-outcome: ${{ steps.build.outcome }} archive-outcome: ${{ steps.archive.outcome }} counterexamples-outcome: ${{ steps.counterexamples.outcome }} + wanted-outcome: ${{ steps.wanted.outcome }} cache-staging-has-files: ${{ steps.cache_staging_check.outputs.has_files }} mk_all-outcome: ${{ steps.mk_all.outcome }} noisy-outcome: ${{ steps.noisy.outcome }} @@ -230,12 +231,13 @@ jobs: # storing and transferring oleans over the network. # Hopefully a future re-implementation of `cache` will obviate the present need for this hack. - - name: fetch archive and counterexamples cache + - name: fetch archive, counterexamples and wanted cache shell: bash run: | cd pr-branch ../tools-branch/.lake/build/bin/cache get Archive.lean ../tools-branch/.lake/build/bin/cache get Counterexamples.lean + ../tools-branch/.lake/build/bin/cache get Wanted.lean - name: build archive id: archive @@ -253,8 +255,16 @@ jobs: ../tools-branch/scripts/lake-build-with-retry.sh Counterexamples # results of build at pr-branch/.lake/build_summary_Counterexamples.json + - name: build wanted + id: wanted + continue-on-error: true + run: | + cd pr-branch + ../tools-branch/scripts/lake-build-with-retry.sh Wanted + # results of build at pr-branch/.lake/build_summary_Wanted.json + # Runs in the build job because it only needs the freshly-built Mathlib/ - # Archive/Counterexamples oleans, which are present here; keeping it in + # Archive/Counterexamples/Wanted oleans, which are present here; keeping it in # `build` also spares `test_lint` from fetching Archive/Counterexamples. - name: check for noisy stdout lines id: noisy @@ -263,7 +273,7 @@ jobs: buildMsgs="$( ## we exploit `lake`s replay feature: since the cache is present, running ## `lake build` will reproduce all the outputs without having to recompute - lake build -q --iofail Mathlib Archive Counterexamples + lake build -q --iofail Mathlib Archive Counterexamples Wanted )" if [ -n "${buildMsgs}" ] then @@ -300,6 +310,13 @@ jobs: cd pr-branch lake env ../tools-branch/.lake/build/bin/cache --staging-dir="../cache-staging" stage Counterexamples.lean + - name: stage Wanted cache files + if: ${{ steps.wanted.outcome == 'success' }} + shell: landrun --rox /usr --ro /etc/timezone --rw /dev --rox /home/lean/.elan --rox /home/lean/actions-runner/_work --rox /home/lean/.cache/mathlib/ --rw /home/lean/.cache/mathlib/ --rw pr-branch/.lake/ --rw cache-staging/ --env PATH --env HOME --env GITHUB_OUTPUT --env CI -- bash -euxo pipefail {0} + run: | + cd pr-branch + lake env ../tools-branch/.lake/build/bin/cache --staging-dir="../cache-staging" stage Wanted.lean + - name: check cache staging contents id: cache_staging_check if: ${{ always() && (steps.build.outcome == 'success' || steps.build.outcome == 'failure' || steps.build.outcome == 'cancelled') }} @@ -463,19 +480,19 @@ jobs: # the archive/counterexamples builds all succeeded. The condition reads those # from the build job's outputs, and the problem-matcher wrap is gated to match. - name: begin gh-problem-match-wrap for test step - if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} + if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' && needs.build.outputs.wanted-outcome == 'success' }} uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: add # In order to be able to run a multiline script, we need to add/remove the problem matcher before and after. linters: lean - name: test mathlib - if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} + if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' && needs.build.outputs.wanted-outcome == 'success' }} id: test run: | cd pr-branch ../tools-branch/scripts/lake-build-wrapper.py .lake/build_summary_MathlibTest.json lake --iofail test - name: end gh-problem-match-wrap for test step - if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' }} + if: ${{ needs.build.outputs.build-outcome == 'success' && needs.build.outputs.mk_all-outcome == 'success' && needs.build.outputs.archive-outcome == 'success' && needs.build.outputs.counterexamples-outcome == 'success' && needs.build.outputs.wanted-outcome == 'success' }} uses: leanprover-community/gh-problem-matcher-wrap@65a654fcdf7b64ff7633bc7a558f7b46d59a27bf # 2026-06-25 with: action: remove diff --git a/.github/workflows/lake_cache_shadow.yml b/.github/workflows/lake_cache_shadow.yml index 02cb18cc33ef0e..3024daf63f0b8a 100644 --- a/.github/workflows/lake_cache_shadow.yml +++ b/.github/workflows/lake_cache_shadow.yml @@ -72,7 +72,7 @@ on: # Default: the full `Mathlib` library — the representative master shadow. # For a cheaper experiment, pass a smaller set, e.g. # Mathlib.Topology.Basic Mathlib.Combinatorics.SimpleGraph.Basic Mathlib.RingTheory.Ideal.Basic - # or add `Archive Counterexamples` to also shadow those libraries. + # or add `Archive Counterexamples Wanted` to also shadow those libraries. default: Mathlib toolchain_override: description: >- @@ -582,12 +582,12 @@ jobs: # (no rebuild). Deps building is expected and excluded from the grep. # Emit an explicit health line (consumed by the Zulip report) and fail # the run if it's not a full hit. - BUILT_ROOT=$(grep -cE '^✔.*Built (Mathlib|Archive|Counterexamples)([. ]|$)' "$log" || true) + BUILT_ROOT=$(grep -cE '^✔.*Built (Mathlib|Archive|Counterexamples|Wanted)([. ]|$)' "$log" || true) if [ "$BUILT_ROOT" -ne 0 ]; then health="❌ NOT full cache hits — ${BUILT_ROOT} root-package module(s) rebuilt" echo "health=${health}" >> "$GITHUB_OUTPUT" echo "::error::${health}" - grep -E '^✔.*Built (Mathlib|Archive|Counterexamples)([. ]|$)' "$log" || true + grep -E '^✔.*Built (Mathlib|Archive|Counterexamples|Wanted)([. ]|$)' "$log" || true exit 1 fi health="✅ full cache hits — 0 root-package modules rebuilt (${FETCHED_ARTIFACTS} served from cache)" diff --git a/.github/workflows/publish_tools.yml b/.github/workflows/publish_tools.yml index 25037f561bf496..2258e0fe283322 100644 --- a/.github/workflows/publish_tools.yml +++ b/.github/workflows/publish_tools.yml @@ -77,8 +77,8 @@ jobs: # We ship the whole build dir, not just the # binary, in case it needs other files there # to run. - # - scripts/lake-build-with-retry.sh: builds Mathlib/Archive/Counterexamples - # with retries. + # - scripts/lake-build-with-retry.sh: builds Mathlib/Archive/Counterexamples/ + # Wanted with retries. # - scripts/lake-build-wrapper.py: wraps the `lake test` step. # - lean-toolchain: the toolchain this binary was built with; # the consumer installs it (via elan) so the diff --git a/.github/workflows/remove_deprecated_decls.yml b/.github/workflows/remove_deprecated_decls.yml index 152441dba2f298..3899dfac88fa71 100644 --- a/.github/workflows/remove_deprecated_decls.yml +++ b/.github/workflows/remove_deprecated_decls.yml @@ -129,7 +129,7 @@ jobs: printf $'::group::Running lake env\n' lake env | tr ':' '\n' echo "::endgroup::" - for repo in Mathlib Archive Counterexamples; do + for repo in Mathlib Archive Counterexamples Wanted; do echo "::group::Retrieving the cache for ${repo}" lake exe cache get "$repo" || true echo "::endgroup::" @@ -141,12 +141,12 @@ jobs: NEW_DATE: "${{ steps.process_dates.outputs.to_date }}" DRY_RUN: "${{ toJson(inputs.dry_run) }}" run: | - # We create a temporary file importing `Mathlib`, `Archive` and `Counterexamples` - # and running `#clear_deprecations` with the expected date-range. + # We create a temporary file importing `Mathlib`, `Archive`, `Counterexamples` and + # `Wanted`, and running `#clear_deprecations` with the expected date-range. tmplean="$(mktemp -p Mathlib --suffix=.lean RMDXXX)" echo "::group::Creating ${tmplean} file" { - for repo in Mathlib Archive Counterexamples; do + for repo in Mathlib Archive Counterexamples Wanted; do printf $'import %s\n' "$repo" done REALLY=$([ "$DRY_RUN" = "true" ] && echo "" || echo "really") diff --git a/Cache/IO.lean b/Cache/IO.lean index c8e18c204a914a..0f0b91441fbd7c 100644 --- a/Cache/IO.lean +++ b/Cache/IO.lean @@ -38,6 +38,7 @@ def isPartOfMathlibCache (mod : Name) : Bool := #[ `ProofWidgets, `Archive, `Counterexamples, + `Wanted, `MathlibTest, -- Allow PRs to upload oleans for Reap for testing. `Requests, diff --git a/Mathlib/Analysis/Convex/Cone/Basic.lean b/Mathlib/Analysis/Convex/Cone/Basic.lean index 22bac4b7c5e6d3..0af4828ca36209 100644 --- a/Mathlib/Analysis/Convex/Cone/Basic.lean +++ b/Mathlib/Analysis/Convex/Cone/Basic.lean @@ -160,21 +160,10 @@ end ProperCone ### Topological properties of convex cones This section proves topological results about convex cones. - -#### TODO - -This result generalises to G-submodules. -/ namespace ConvexCone -variable [Semifield 𝕜] [LinearOrder 𝕜] [Module 𝕜 E] {s : Set E} - --- FIXME: This is necessary for the proof below but triggers the `unusedSectionVars` linter. --- variable [IsStrictOrderedRing 𝕜] [IsTopologicalAddGroup M] in -/-- This is true essentially by `Submodule.span_eq_iUnion_nat`, except that `Submodule` currently -doesn't support that use case. See -https://leanprover.zulipchat.com/#narrow/channel/116395-maths/topic/G-submodules/with/514426583 -/ -proof_wanted isOpen_hull (hs : IsOpen s) : IsOpen (hull 𝕜 s : Set E) +variable [Semifield 𝕜] [LinearOrder 𝕜] [Module 𝕜 E] variable [TopologicalSpace 𝕜] [OrderTopology 𝕜] [DenselyOrdered 𝕜] [NoMaxOrder 𝕜] [ContinuousSMul 𝕜 E] {C : ConvexCone 𝕜 E} diff --git a/Mathlib/Analysis/Convex/Continuous.lean b/Mathlib/Analysis/Convex/Continuous.lean index da39705b256ca2..0cd9a983559f1d 100644 --- a/Mathlib/Analysis/Convex/Continuous.lean +++ b/Mathlib/Analysis/Convex/Continuous.lean @@ -221,19 +221,6 @@ protected lemma ConvexOn.locallyLipschitz (hf : ConvexOn ℝ univ f) : LocallyLi protected lemma ConcaveOn.locallyLipschitz (hf : ConcaveOn ℝ univ f) : LocallyLipschitz f := by simpa using hf.locallyLipschitzOn_interior --- Commented out since `intrinsicInterior` is not imported (but should be once these are proved) --- proof_wanted ConvexOn.locallyLipschitzOn_intrinsicInterior (hf : ConvexOn ℝ C f) : --- LocallyLipschitzOn (intrinsicInterior ℝ C) f - --- proof_wanted ConcaveOn.locallyLipschitzOn_intrinsicInterior (hf : ConcaveOn ℝ C f) : --- LocallyLipschitzOn (intrinsicInterior ℝ C) f - --- proof_wanted ConvexOn.continuousOn_intrinsicInterior (hf : ConvexOn ℝ C f) : --- ContinuousOn f (intrinsicInterior ℝ C) - --- proof_wanted ConcaveOn.continuousOn_intrinsicInterior (hf : ConcaveOn ℝ C f) : --- ContinuousOn f (intrinsicInterior ℝ C) - section Intervals lemma ConvexOn.continuousOn_Ici {f : ℝ → ℝ} {y : ℝ} (hf_cvx : ConvexOn ℝ (Ici y) f) diff --git a/Mathlib/Analysis/Real/Pi/Chudnovsky.lean b/Mathlib/Analysis/Real/Pi/Chudnovsky.lean index 8aa136c188f0ac..e080c9ed40f11d 100644 --- a/Mathlib/Analysis/Real/Pi/Chudnovsky.lean +++ b/Mathlib/Analysis/Real/Pi/Chudnovsky.lean @@ -24,7 +24,8 @@ but at present we are a long way off. ## Future work * Use this formula to give approximations for `π`. -* Prove the sum equals `π⁻¹`, as stated using `proof_wanted` below. +* Prove the sum equals `π⁻¹`, as stated using `proof_wanted` in + `Wanted/Analysis/Real/Pi/Chudnovsky.lean`. * Show that each imaginary quadratic field of class number 1 (corresponding to Heegner numbers) gives a Ramanujan type formula, and that this is the formula coming from 163, with `j ((1 + √-163) / 2) = -640320^3`, and the other magic constants coming from @@ -62,6 +63,3 @@ def chudnovskyTerm (n : ℕ) : ℚ := /-- The infinite sum in Chudnovsky's formula for `π⁻¹` -/ noncomputable def chudnovskySum : ℝ := 12 / (640320 : ℝ) ^ (3 / 2 : ℝ) * ∑' n : ℕ, (chudnovskyTerm n : ℝ) - -/-- **Chudnovsky's formula**: The sum equals `π⁻¹` -/ -proof_wanted chudnovskySum_eq_pi_inv : chudnovskySum = π⁻¹ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Countable.lean b/Mathlib/CategoryTheory/Limits/Shapes/Countable.lean index c7c448cfdad756..884715d3423fa3 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Countable.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Countable.lean @@ -19,8 +19,9 @@ limits, see `sequentialFunctor_initial`. ## Projects -* There is a series of `proof_wanted` at the bottom of this file, implying that all cofiltered - limits over countable categories are isomorphic to sequential limits. +* There is a series of `proof_wanted` in `Wanted/CategoryTheory/Limits/Shapes/Countable.lean`, + implying that all cofiltered limits over countable categories are isomorphic to sequential + limits. * Prove the dual result for filtered colimits. @@ -226,37 +227,6 @@ instance sequentialFunctor_initial : (sequentialFunctor J).Initial where · right exact ⟨CostructuredArrow.homMk (homOfLE h).op rfl⟩ -@[stacks 0032] -proof_wanted preorder_of_cofiltered (J : Type*) [Category* J] [IsCofiltered J] : - ∃ (I : Type*) (_ : Preorder I) (_ : IsCofiltered I) (F : I ⥤ J), F.Initial - -/-- -The proof of `preorder_of_cofiltered` should give a countable `I` in the case that `J` is a -countable category. --/ -proof_wanted preorder_of_cofiltered_countable - (J : Type*) [SmallCategory J] [IsCofiltered J] [CountableCategory J] : - ∃ (I : Type) (_ : Preorder I) (_ : Countable I) (_ : IsCofiltered I) (F : I ⥤ J), F.Initial - -/-- -Put together `sequentialFunctor_initial` and `preorder_of_cofiltered_countable`. --/ -proof_wanted hasCofilteredCountableLimits_of_hasSequentialLimits [HasLimitsOfShape ℕᵒᵖ C] : - ∀ (J : Type) [SmallCategory J] [IsCofiltered J] [CountableCategory J], HasLimitsOfShape J C - -/-- -This is the countable version of `CategoryTheory.Limits.has_limits_of_finite_and_cofiltered`, given -all of the above. --/ -proof_wanted hasCountableLimits_of_hasFiniteLimits_and_hasSequentialLimits [HasFiniteLimits C] - [HasLimitsOfShape ℕᵒᵖ C] : HasCountableLimits C - -/-- -For this we need to dualize this whole section. --/ -proof_wanted hasCountableColimits_of_hasFiniteColimits_and_hasSequentialColimits - [HasFiniteColimits C] [HasLimitsOfShape ℕ C] : HasCountableColimits C - end IsCofiltered end Preorder diff --git a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean index 9bea39c519e742..335b84b790d194 100644 --- a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean +++ b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -79,12 +79,6 @@ theorem IsSRGWith.ediam_eq_two [Nontrivial V] (h : G.IsSRGWith n k ℓ μ) (ht : have := not_subsingleton V simp_all [Order.le_one_iff] -/-- **Conway's 99-graph problem** (from https://oeis.org/A248380/a248380.pdf) -can be reformulated as the existence of a strongly regular graph with params (99, 14, 1, 2). -This is an open problem, and has no known proof of existence. -/ -proof_wanted conway_99 : ∃ (α : Type) (_ : Fintype α) (g : SimpleGraph α) (_ : DecidableRel g.Adj), - IsSRGWith g 99 14 1 2 - variable [DecidableEq V] /-- Complete graphs are strongly regular. Note that `μ` can take any value diff --git a/Mathlib/Computability/TuringMachine/Computable.lean b/Mathlib/Computability/TuringMachine/Computable.lean index 7779a00f0c3c39..06f40371e31ddb 100644 --- a/Mathlib/Computability/TuringMachine/Computable.lean +++ b/Mathlib/Computability/TuringMachine/Computable.lean @@ -273,20 +273,6 @@ instance inhabitedTM2Computable : instance inhabitedTM2ComputableAux : Inhabited (TM2ComputableAux Bool Bool) := ⟨(default : TM2Computable encodeBool encodeBool id).toTM2ComputableAux⟩ -/-- -For any two polynomial time Multi-tape Turing Machines, -there exists another polynomial time multi-tape Turing Machine that composes their operations. -This machine can work by simply having one tape for each tape in both of the composed TMs. -It first carries out the operations of the first TM on the tapes associated with the first TM, -then copies the output tape of the first TM to the input tape of the second TM, -then runs the second TM. --/ -proof_wanted TM2ComputableInPolyTime.comp - {α β γ αΓ βΓ γΓ : Type} {eα : α → List αΓ} {eβ : β → List βΓ} - {eγ : γ → List γΓ} {f : α → β} {g : β → γ} (h1 : TM2ComputableInPolyTime eα eβ f) - (h2 : TM2ComputableInPolyTime eβ eγ g) : - Nonempty (TM2ComputableInPolyTime eα eγ (g ∘ f)) - end end Turing diff --git a/Mathlib/Data/EReal/Operations.lean b/Mathlib/Data/EReal/Operations.lean index 3a653a0bfb0424..e1dc6974f02bdd 100644 --- a/Mathlib/Data/EReal/Operations.lean +++ b/Mathlib/Data/EReal/Operations.lean @@ -6,7 +6,6 @@ Authors: Kevin Buzzard module public import Mathlib.Data.EReal.Basic -public import Batteries.Util.ProofWanted /-! # Addition, negation, subtraction and multiplication on extended real numbers @@ -323,10 +322,6 @@ theorem recENNReal_coe_ennreal {motive : EReal → Sort*} (coe : ∀ x : ℝ≥0 obtain rfl : y.toENNReal = x := by simp [← hy] simp [recENNReal, H₁] -proof_wanted recENNReal_neg_coe_ennreal {motive : EReal → Sort*} (coe : ∀ x : ℝ≥0∞, motive x) - (neg_coe : ∀ x : ℝ≥0∞, 0 < x → motive (-x)) {x : ℝ≥0∞} (hx : 0 < x) : - recENNReal coe neg_coe (-x) = neg_coe x hx - /-! ### Subtraction diff --git a/Mathlib/Geometry/Euclidean/Volume/Measure.lean b/Mathlib/Geometry/Euclidean/Volume/Measure.lean index e3a22b453f5dc1..1d1243790d60c1 100644 --- a/Mathlib/Geometry/Euclidean/Volume/Measure.lean +++ b/Mathlib/Geometry/Euclidean/Volume/Measure.lean @@ -68,13 +68,6 @@ def MeasureTheory.Measure.euclideanHausdorffMeasure (d : ℕ) : Measure X := @[inherit_doc] scoped[MeasureTheory] notation "μHE[" d "]" => MeasureTheory.Measure.euclideanHausdorffMeasure d -/-- show the scaling factor equals to the ratio between the volume of `d`-dimensional -`Metric.ball` with Euclidean metric and with sup metric (i.e. a cube), or explicitly, -$\pi^{d/2} / (2^d \Gamma (d/2+1))$. -/ -proof_wanted MeasureTheory.Measure.addHaarScalarFactor_hausdorffMeasure_eq (d : ℕ) : - addHaarScalarFactor (volume : Measure (EuclideanSpace ℝ (Fin d))) μH[d] = - volume (Metric.ball (0 : EuclideanSpace ℝ (Fin d)) 1) / volume (Metric.ball (0 : Fin d → ℝ) 1) - theorem MeasureTheory.Measure.euclideanHausdorffMeasure_def (d : ℕ) : (μHE[d] : Measure X) = addHaarScalarFactor (volume : Measure (EuclideanSpace ℝ (Fin d))) μH[d] • μH[d] := by diff --git a/Mathlib/Geometry/Manifold/PoincareConjecture.lean b/Mathlib/Geometry/Manifold/PoincareConjecture.lean index 594a725faca092..35a71bbd1c70bb 100644 --- a/Mathlib/Geometry/Manifold/PoincareConjecture.lean +++ b/Mathlib/Geometry/Manifold/PoincareConjecture.lean @@ -5,8 +5,6 @@ Authors: Junyan Xu -/ module -public import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected -- shake: keep (`p_w`) -public import Mathlib.Geometry.Manifold.Diffeomorph public import Mathlib.Geometry.Manifold.Instances.Sphere public import Mathlib.Topology.Homotopy.Equiv public import Mathlib.Util.Superscript @@ -16,6 +14,9 @@ public import Mathlib.Util.Superscript https://en.wikipedia.org/wiki/Generalized_Poincar%C3%A9_conjecture +The `proof_wanted` statements of the generalized Poincaré conjecture and related conjectures +now live in `Wanted/Geometry/Manifold/PoincareConjecture.lean`. + The mathlib notation `≃ₕ` stands for a homotopy equivalence, `≃ₜ` stands for a homeomorphism, and `≃ₘ⟮𝓡 n, 𝓡 n⟯` stands for a diffeomorphism, where `𝓡 n` is the `n`-dimensional Euclidean space viewed as a model space. @@ -34,40 +35,9 @@ variable (M : Type*) [TopologicalSpace M] open ContinuousMap -/-- The generalized topological Poincaré conjecture. -- For n = 2 it follows from the classification of surfaces. -- For n ≥ 5 it was proven by Stephen Smale in 1961 assuming M admits a smooth structure; - Newman (1966) and Connell (1967) proved it without the condition. -- For n = 4 it was proven by Michael Freedman in 1982. -- For n = 3 it was proven by Grigori Perelman in 2003. -/ -proof_wanted ContinuousMap.HomotopyEquiv.nonempty_homeomorph_sphere [T2Space M] - (n : ℕ) [ChartedSpace ℝⁿ M] : M ≃ₕ 𝕊ⁿ → Nonempty (M ≃ₜ 𝕊ⁿ) - -/-- The 3-dimensional topological Poincaré conjecture (proven by Perelman) -/ -proof_wanted SimplyConnectedSpace.nonempty_homeomorph_sphere_three - [T2Space M] [ChartedSpace ℝ³ M] [SimplyConnectedSpace M] [CompactSpace M] : - Nonempty (M ≃ₜ 𝕊³) - -/-- The 3-dimensional smooth Poincaré conjecture (proven by Perelman) -/ -proof_wanted SimplyConnectedSpace.nonempty_sdiffeomorph_sphere_three - [T2Space M] [ChartedSpace ℝ³ M] [IsManifold (𝓡 3) ∞ M] - [SimplyConnectedSpace M] [CompactSpace M] : - Nonempty (M ≃ₘ⟮𝓡 3, 𝓡 3⟯ 𝕊³) - /-- The smooth Poincaré conjecture; true for n = 1, 2, 3, 5, 6, 12, 56, and 61, open for n = 4, and it is conjectured that there are no other n > 4 for which it is true (Conjecture 1.17, https://annals.math.princeton.edu/2017/186-2/p03). -/ def ContinuousMap.HomotopyEquiv.NonemptyDiffeomorphSphere (n : ℕ) : Prop := ∀ (_ : ChartedSpace ℝⁿ M) (_ : IsManifold (𝓡 n) ∞ M), M ≃ₕ 𝕊ⁿ → Nonempty (M ≃ₘ⟮𝓡 n, 𝓡 n⟯ 𝕊ⁿ) - -/-- The existence of an exotic 7-sphere (due to John Milnor) -/ -proof_wanted exists_homeomorph_isEmpty_diffeomorph_sphere_seven : - ∃ (M : Type) (_ : TopologicalSpace M) (_ : ChartedSpace ℝ⁷ M) - (_ : IsManifold (𝓡 7) ∞ M) (_homeo : M ≃ₜ 𝕊⁷), - IsEmpty (M ≃ₘ⟮𝓡 7, 𝓡 7⟯ 𝕊⁷) - -/-- The existence of a small exotic ℝ⁴, i.e. an open subset of ℝ⁴ that is homeomorphic but -not diffeomorphic to ℝ⁴. See https://en.wikipedia.org/wiki/Exotic_R4. -/ -proof_wanted exists_open_nonempty_homeomorph_isEmpty_diffeomorph_euclideanSpace_four : - ∃ M : TopologicalSpace.Opens ℝ⁴, Nonempty (M ≃ₜ ℝ⁴) ∧ IsEmpty (M ≃ₘ⟮𝓡 4, 𝓡 4⟯ ℝ⁴) diff --git a/Mathlib/Geometry/Manifold/SmoothEmbedding.lean b/Mathlib/Geometry/Manifold/SmoothEmbedding.lean index 622c8297de17e2..4bc4992ec04f09 100644 --- a/Mathlib/Geometry/Manifold/SmoothEmbedding.lean +++ b/Mathlib/Geometry/Manifold/SmoothEmbedding.lean @@ -7,7 +7,6 @@ module public import Mathlib.Geometry.Manifold.Immersion public import Mathlib.Geometry.Manifold.ContMDiff.Defs -public import Mathlib.Geometry.Manifold.Diffeomorph -- shake: keep (used in `proof_wanted` only) /-! # Smooth embeddings @@ -115,16 +114,6 @@ lemma contMDiff (hf : IsSmoothEmbedding I J n f) : ContMDiff I J n f := hf.isImmersion.contMDiff --- use IsImmersion.comp and IsEmbedding.comp -/-- The composition of two smooth embeddings between Banach manifolds is a smooth embedding. -/ -proof_wanted comp -- [CompleteSpace E] [CompleteSpace E'] [CompleteSpace F] [CompleteSpace F'] - {g : N → N'} (hg : IsSmoothEmbedding J J' n g) (hf : IsSmoothEmbedding I J n f) : - IsSmoothEmbedding I J' n (g ∘ f) - end IsSmoothEmbedding --- TODO: prove the same result for local diffeomorphisms and deduce it as a corollary -proof_wanted Diffeomorph.isSmoothEmbedding [IsManifold I n M] - (φ : Diffeomorph I I M M n) : IsSmoothEmbedding I I n φ - end Manifold diff --git a/Mathlib/GroupTheory/GroupAction/Jordan.lean b/Mathlib/GroupTheory/GroupAction/Jordan.lean index 23148d34ad92ff..3d110204b11b03 100644 --- a/Mathlib/GroupTheory/GroupAction/Jordan.lean +++ b/Mathlib/GroupTheory/GroupAction/Jordan.lean @@ -91,13 +91,6 @@ theorem normalClosure_of_stabilizer_eq_top (hsn' : 2 < ENat.card α) simp only [subgroup_smul_def, smul_smul, ← mul_assoc, ← mem_stabilizer_iff] exact hyp (normalClosure_normal.conj_mem g (le_normalClosure hg) h) --- Wielandt claims that this is proved by the same method as above. -proof_wanted IsPreprimitive.is_two_pretransitive' - (hG : IsPreprimitive G α) - {s : Set α} {n : ℕ} (hsn : Nat.card s = n + 1) (hsn' : n + 1 < Nat.card α) - (hs_trans : IsPretransitive (fixingSubgroup G s) (SubMulAction.ofFixingSubgroup G s)) : - IsMultiplyPretransitive (Subgroup.normalClosure (fixingSubgroup G s : Set G)) α 2 - open MulAction.IsPreprimitive open scoped Pointwise @@ -236,13 +229,6 @@ theorem MulAction.IsPreprimitive.is_two_preprimitive IsMultiplyPreprimitive G α 2 := (hG.is_two_motive_of_is_motive hsn hsn').2 hs_prim --- Wielandt claims that this stronger version is proved in the same way -proof_wanted is_two_preprimitive_strong_jordan - (hG : IsPreprimitive G α) - {s : Set α} {n : ℕ} (hsn : s.ncard = n + 1) (hsn' : n + 2 < Nat.card α) - (hs_prim : IsPreprimitive (fixingSubgroup G s) (ofFixingSubgroup G s)) : - IsMultiplyPreprimitive (Subgroup.normalClosure (fixingSubgroup G s : Set G)) α 2 - /-- Jordan's multiple primitivity criterion (Wielandt, 13.3) -/ theorem MulAction.IsPreprimitive.isMultiplyPreprimitive (hG : IsPreprimitive G α) {s : Set α} {n : ℕ} @@ -457,14 +443,6 @@ theorem alternatingGroup_le_of_isPreprimitive_of_isThreeCycle_mem ext x simp [SubMulAction.mem_ofFixingSubgroup_iff] -/-- A primitive subgroup of `Equiv.Perm α` that contains a cycle of prime order -contains the alternating group. -/ -proof_wanted alternatingGroup_le_of_isPreprimitive_of_isCycle_mem - (hG : IsPreprimitive G α) - {p : ℕ} (hp : p.Prime) (hp' : p + 3 ≤ Nat.card α) - {g : Perm α} (hgc : g.IsCycle) (hgp : g.support.card = p) - (hg : g ∈ G) : alternatingGroup α ≤ G - end Equiv.Perm end Subgroups diff --git a/Mathlib/Order/KrullDimension.lean b/Mathlib/Order/KrullDimension.lean index fdedd7636603f3..fe3840074f9c90 100644 --- a/Mathlib/Order/KrullDimension.lean +++ b/Mathlib/Order/KrullDimension.lean @@ -953,18 +953,6 @@ lemma krullDim_eq_one_iff_of_boundedOrder {α : Type*} [PartialOrder α] [Bounde variable {α : Type*} [Preorder α] -/- -These two lemmas could possibly be used to simplify the subsequent calculations, -especially once the `Set.encard` api is richer. - -(Commented out to avoid importing modules purely for `proof_wanted`.) -proof_wanted height_of_linearOrder {α : Type*} [LinearOrder α] (a : α) : - height a = (Set.Iio a).encard - -proof_wanted coheight_of_linearOrder {α : Type*} [LinearOrder α] (a : α) : - coheight a = (Set.Ioi a).encard --/ - @[simp] lemma height_nat (n : ℕ) : height n = n := by induction n using Nat.strongRecOn with | ind n ih => apply le_antisymm diff --git a/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean b/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean index a8a46c3a353cf0..09bee4a03dfeed 100644 --- a/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean +++ b/Mathlib/Probability/Combinatorics/BinomialRandomGraph/Defs.lean @@ -97,10 +97,4 @@ variable (p) in rw [Nat.card_eq_fintype_card, ← Sym2.card_diagSet_compl, Fintype.card_eq_nat_card, ← Nat.card_coe_set_eq] --- This should be restated as an equality of distributions once --- https://github.com/leanprover-community/mathlib4/pull/28248 is in. -proof_wanted binomialRandom_map_ncard_edgeSet_singleton [Finite V] (n : ℕ) : - G(V, p).map (fun G ↦ G.edgeSet.ncard) {n} = ((Nat.card V).choose 2).choose n * toNNReal p ^ n * - toNNReal (σ p) ^ ((Nat.card V).choose 2 - n) - end SimpleGraph diff --git a/Mathlib/Probability/Distributions/Binomial.lean b/Mathlib/Probability/Distributions/Binomial.lean index 60685f1760f7cd..ed3603a904d467 100644 --- a/Mathlib/Probability/Distributions/Binomial.lean +++ b/Mathlib/Probability/Distributions/Binomial.lean @@ -203,18 +203,4 @@ theorem integral_of_hasLaw_binomial (hX : HasLaw X Bin(ℝ, n, p) P) : P[X] = p. group _ = p * (n + 1) := by grind [add_pow p.val (1 - p) n, one_pow] -/-- **Variance of a binomial random variable**. - -The variance of a binomial random variable with parameters `n` and `p` is `p(1 - p)n`. -/ -proof_wanted variance_of_hasLaw_binomial (hX : HasLaw X Bin(ℝ, n, p) P) : - Var[X; P] = p * (1 - p) * n - -/-- **Conditional variance of a binomial random variable**. - -The conditional variance of a binomial random variable is the product of the conditional -probabilities that it's equal to `0` and that it's equal to `1`. -/ -proof_wanted condVar_of_hasLaw_binomial {m₀ : MeasurableSpace Ω} (hm : m ≤ m₀) {P : Measure[m₀] Ω} - (hX : HasLaw X Bin(ℝ, n, p) P) : - Var[X; P | m] =ᵐ[P] P[X | m] * P[1 - X | m] - end ProbabilityTheory diff --git a/Mathlib/RingTheory/Congruence/Basic.lean b/Mathlib/RingTheory/Congruence/Basic.lean index cbd85e276d1fab..fc055593fe7fee 100644 --- a/Mathlib/RingTheory/Congruence/Basic.lean +++ b/Mathlib/RingTheory/Congruence/Basic.lean @@ -348,12 +348,6 @@ theorem comap_ringConGen_ringEquiv {R R'} [NonAssocSemiring R] [NonAssocSemiring · rw [← comap_nonUnitalRingHomComp] simp --- This one probably needs the RingCon version of `Setoid.comap_surjective` -proof_wanted comap_ringConGen_equiv - {F} [FunLike F R' R] [MulHomClass F R' R] [AddHomClass F R' R] [EquivLike F R' R] - (r : R → R → Prop) (f : F) : - (ringConGen r).comap f = ringConGen (r on f) - end Lattice end RingCon diff --git a/Mathlib/RingTheory/Etale/Descent.lean b/Mathlib/RingTheory/Etale/Descent.lean index 0ab2fd7dd0cbb6..d946a6effb2547 100644 --- a/Mathlib/RingTheory/Etale/Descent.lean +++ b/Mathlib/RingTheory/Etale/Descent.lean @@ -30,7 +30,8 @@ We also provide the corresponding `RingHom.CodescendsAlong` lemmas. of finite presentation is projective and the former descends. This also holds without the finite presentation assumption, but requires showing that projectivity descends along faithfully flat base change, which is due to Raynaud and Gruson - (see https://stacks.math.columbia.edu/tag/058B). + (see https://stacks.math.columbia.edu/tag/058B). See `Wanted/RingTheory/Etale/Descent.lean` + for the precise statement. -/ public section @@ -51,14 +52,6 @@ lemma FormallyUnramified.of_formallyUnramified_tensorProduct_of_faithfullyFlat (KaehlerDifferential.tensorKaehlerEquivBase R T S (T ⊗[R] S)).subsingleton exact Module.FaithfullyFlat.lTensor_reflects_triviality R T _ -/-- Formally smooth algebras descend along faithfully flat base change. See the TODO -in the module docstring. -/ -proof_wanted FormallySmooth.of_formallySmooth_tensorProduct_of_faithfullyFlat - {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] - (T : Type*) [CommRing T] [Algebra R T] [Module.FaithfullyFlat R T] - [FormallySmooth T (T ⊗[R] S)] : - FormallySmooth R S - lemma Smooth.of_smooth_tensorProduct_of_faithfullyFlat [Smooth T (T ⊗[R] S)] : Smooth R S := by have : Algebra.FinitePresentation R S := .of_finitePresentation_tensorProduct_of_faithfullyFlat T diff --git a/Mathlib/RingTheory/KrullDimension/Basic.lean b/Mathlib/RingTheory/KrullDimension/Basic.lean index b6cb632903383f..15fa8988c86150 100644 --- a/Mathlib/RingTheory/KrullDimension/Basic.lean +++ b/Mathlib/RingTheory/KrullDimension/Basic.lean @@ -5,7 +5,6 @@ Authors: Fangming Li, Jujian Zhang -/ module -public import Mathlib.Algebra.MvPolynomial.Basic -- shake: keep (used in `proof_wanted` only) public import Mathlib.Order.KrullDimension public import Mathlib.RingTheory.Ideal.Quotient.Defs public import Mathlib.RingTheory.Ideal.MinimalPrime.Basic @@ -91,10 +90,6 @@ lemma Nontrivial.of_finiteRingKrullDim [FiniteRingKrullDim R] : Nontrivial R := rw [← PrimeSpectrum.nonempty_iff_nontrivial] exact LTSeries.nonempty_of_finiteDimensionalOrder _ -proof_wanted MvPolynomial.fin_ringKrullDim_eq_add_of_isNoetherianRing - [IsNoetherianRing R] (n : ℕ) : - ringKrullDim (MvPolynomial (Fin n) R) = ringKrullDim R + n - section Zero -- See `Mathlib/RingTheory/KrullDimension/Zero.lean` for further results. diff --git a/Mathlib/RingTheory/SimpleModule/Basic.lean b/Mathlib/RingTheory/SimpleModule/Basic.lean index 99af6ae4137fcb..ea3ab4ccfb90a7 100644 --- a/Mathlib/RingTheory/SimpleModule/Basic.lean +++ b/Mathlib/RingTheory/SimpleModule/Basic.lean @@ -331,14 +331,6 @@ theorem _root_.LinearMap.isSemisimpleModule_iff_of_bijective simp_rw [isSemisimpleModule_iff, (Submodule.orderIsoMapComapOfBijective l hl).complementedLattice_iff] --- TODO: generalize Submodule.equivMapOfInjective from InvPair to RingHomSurjective -proof_wanted _root_.LinearMap.isSemisimpleModule_of_injective (_ : Function.Injective l) - [IsSemisimpleModule S N'] : IsSemisimpleModule R M' - ---TODO: generalize LinearMap.quotKerEquivOfSurjective to SemilinearMaps + RingHomSurjective -proof_wanted _root_.LinearMap.isSemisimpleModule_of_surjective (_ : Function.Surjective l) - [IsSemisimpleModule R M'] : IsSemisimpleModule S N' - end end IsSemisimpleModule diff --git a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean index ac49ed1a061fd5..d24f98e7d7e4f6 100644 --- a/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean +++ b/Mathlib/RingTheory/SimpleModule/WedderburnArtin.lean @@ -248,12 +248,3 @@ theorem isSemisimpleRing_iff_pi_matrix_divisionRing : IsSemisimpleRing R ↔ mp _ := have ⟨n, D, d, _, _, e⟩ := IsSemisimpleRing.exists_ringEquiv_pi_matrix_divisionRing R ⟨n, D, d, _, e⟩ mpr := fun ⟨_, _, _, _, ⟨e⟩⟩ ↦ e.symm.isSemisimpleRing - --- Need left-right symmetry of Jacobson radical -proof_wanted IsSemiprimaryRing.mulOpposite [IsSemiprimaryRing R] : IsSemiprimaryRing Rᵐᵒᵖ - -proof_wanted isSemiprimaryRing_mulOpposite_iff : IsSemiprimaryRing Rᵐᵒᵖ ↔ IsSemiprimaryRing R - --- A left Artinian ring is right Noetherian iff it is right Artinian. To be left as an `example`. -proof_wanted IsArtinianRing.isNoetherianRing_iff_isArtinianRing_mulOpposite - [IsArtinianRing R] : IsNoetherianRing Rᵐᵒᵖ ↔ IsArtinianRing Rᵐᵒᵖ diff --git a/Mathlib/Tactic/Linter/DirectoryDependency.lean b/Mathlib/Tactic/Linter/DirectoryDependency.lean index 9e9bd3ca160442..2688a47b5572e1 100644 --- a/Mathlib/Tactic/Linter/DirectoryDependency.lean +++ b/Mathlib/Tactic/Linter/DirectoryDependency.lean @@ -284,6 +284,11 @@ outside `Mathlib/Algebra/Notation.lean`. def forbiddenImportDirs : NamePrefixRel := .ofArray #[ (`Mathlib.Algebra.Notation, `Mathlib.Algebra), (`Mathlib, `Mathlib.Deprecated), + -- Files in `Wanted` look like theorems but have no proofs (`proof_wanted`), so importing them + -- is banned everywhere: they may import from `Mathlib`, never the other way around. + (`Mathlib, `Wanted), + (`Archive, `Wanted), + (`Counterexamples, `Wanted), -- This is used to test the linter. (`MathlibTest.Header, `Mathlib.Deprecated), diff --git a/Wanted.lean b/Wanted.lean new file mode 100644 index 00000000000000..a1769ab52ca305 --- /dev/null +++ b/Wanted.lean @@ -0,0 +1,21 @@ +module -- shake: keep-all --deprecated_module: ignore + +public import Wanted.Analysis.Convex.Cone.Basic +public import Wanted.Analysis.Convex.Continuous +public import Wanted.Analysis.Real.Pi.Chudnovsky +public import Wanted.CategoryTheory.Limits.Shapes.Countable +public import Wanted.Combinatorics.SimpleGraph.StronglyRegular +public import Wanted.Computability.TuringMachine.Computable +public import Wanted.Data.EReal.Operations +public import Wanted.Geometry.Euclidean.Volume.Measure +public import Wanted.Geometry.Manifold.PoincareConjecture +public import Wanted.Geometry.Manifold.SmoothEmbedding +public import Wanted.GroupTheory.GroupAction.Jordan +public import Wanted.Order.KrullDimension +public import Wanted.Probability.Combinatorics.BinomialRandomGraph.Defs +public import Wanted.Probability.Distributions.Binomial +public import Wanted.RingTheory.Congruence.Basic +public import Wanted.RingTheory.Etale.Descent +public import Wanted.RingTheory.KrullDimension.Basic +public import Wanted.RingTheory.SimpleModule.Basic +public import Wanted.RingTheory.SimpleModule.WedderburnArtin diff --git a/Wanted/Analysis/Convex/Cone/Basic.lean b/Wanted/Analysis/Convex/Cone/Basic.lean new file mode 100644 index 00000000000000..a4edfcb5bd6b8c --- /dev/null +++ b/Wanted/Analysis/Convex/Cone/Basic.lean @@ -0,0 +1,23 @@ +/- +Copyright (c) 2025 Yaël Dillies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies +-/ +module + +public import Mathlib.Analysis.Convex.Cone.Basic + +variable {𝕜 E : Type*} [AddCommGroup E] [TopologicalSpace E] + +namespace ConvexCone +variable [Semifield 𝕜] [LinearOrder 𝕜] [Module 𝕜 E] {s : Set E} + +-- TODO: This result generalises to `G`-submodules in the sense of the Zulip thread linked below. + +variable [IsStrictOrderedRing 𝕜] [IsTopologicalAddGroup E] in +/-- This is true essentially by `Submodule.span_eq_iUnion_nat`, except that `Submodule` currently +doesn't support that use case. See +https://leanprover.zulipchat.com/#narrow/channel/116395-maths/topic/G-submodules/with/514426583 -/ +proof_wanted isOpen_hull (hs : IsOpen s) : IsOpen (hull 𝕜 s : Set E) + +end ConvexCone diff --git a/Wanted/Analysis/Convex/Continuous.lean b/Wanted/Analysis/Convex/Continuous.lean new file mode 100644 index 00000000000000..a25b5953e1889d --- /dev/null +++ b/Wanted/Analysis/Convex/Continuous.lean @@ -0,0 +1,25 @@ +/- +Copyright (c) 2024 Yaël Dillies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies +-/ +module + +public import Mathlib.Analysis.Convex.Continuous +public import Mathlib.Analysis.Convex.Intrinsic + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {C : Set E} {f : E → ℝ} + +variable [FiniteDimensional ℝ E] + +proof_wanted ConvexOn.locallyLipschitzOn_intrinsicInterior (hf : ConvexOn ℝ C f) : + LocallyLipschitzOn (intrinsicInterior ℝ C) f + +proof_wanted ConcaveOn.locallyLipschitzOn_intrinsicInterior (hf : ConcaveOn ℝ C f) : + LocallyLipschitzOn (intrinsicInterior ℝ C) f + +proof_wanted ConvexOn.continuousOn_intrinsicInterior (hf : ConvexOn ℝ C f) : + ContinuousOn f (intrinsicInterior ℝ C) + +proof_wanted ConcaveOn.continuousOn_intrinsicInterior (hf : ConcaveOn ℝ C f) : + ContinuousOn f (intrinsicInterior ℝ C) diff --git a/Wanted/Analysis/Real/Pi/Chudnovsky.lean b/Wanted/Analysis/Real/Pi/Chudnovsky.lean new file mode 100644 index 00000000000000..9a2b01e26695a0 --- /dev/null +++ b/Wanted/Analysis/Real/Pi/Chudnovsky.lean @@ -0,0 +1,14 @@ +/- +Copyright (c) 2025 Kim Morrison. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kim Morrison +-/ +module + +public import Mathlib.Analysis.Real.Pi.Chudnovsky + +open scoped Real + +/-- **Chudnovsky's formula**: the sum `chudnovskySum` (defined in +`Mathlib/Analysis/Real/Pi/Chudnovsky.lean`) equals `π⁻¹`. -/ +proof_wanted chudnovskySum_eq_pi_inv : chudnovskySum = π⁻¹ diff --git a/Wanted/CategoryTheory/Limits/Shapes/Countable.lean b/Wanted/CategoryTheory/Limits/Shapes/Countable.lean new file mode 100644 index 00000000000000..c374350070b3f0 --- /dev/null +++ b/Wanted/CategoryTheory/Limits/Shapes/Countable.lean @@ -0,0 +1,52 @@ +/- +Copyright (c) 2024 Dagur Asgeirsson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Dagur Asgeirsson +-/ +module + +public import Mathlib.CategoryTheory.Limits.Shapes.Countable + +open CategoryTheory + +variable {C : Type*} [Category* C] + +namespace CategoryTheory.Limits + +namespace IsCofiltered + +@[stacks 0032] +proof_wanted preorder_of_cofiltered (J : Type*) [Category* J] [IsCofiltered J] : + ∃ (I : Type*) (_ : Preorder I) (_ : IsCofiltered I) (F : I ⥤ J), F.Initial + +/-- +The proof of `preorder_of_cofiltered` should give a countable `I` in the case that `J` is a +countable category. +-/ +proof_wanted preorder_of_cofiltered_countable + (J : Type*) [SmallCategory J] [IsCofiltered J] [CountableCategory J] : + ∃ (I : Type) (_ : Preorder I) (_ : Countable I) (_ : IsCofiltered I) (F : I ⥤ J), F.Initial + +/-- +Put together `sequentialFunctor_initial` and `preorder_of_cofiltered_countable`. +-/ +proof_wanted hasCofilteredCountableLimits_of_hasSequentialLimits [HasLimitsOfShape ℕᵒᵖ C] : + ∀ (J : Type) [SmallCategory J] [IsCofiltered J] [CountableCategory J], HasLimitsOfShape J C + +/-- +This is the countable version of `CategoryTheory.Limits.has_limits_of_finite_and_cofiltered`, given +all of the above. +-/ +proof_wanted hasCountableLimits_of_hasFiniteLimits_and_hasSequentialLimits [HasFiniteLimits C] + [HasLimitsOfShape ℕᵒᵖ C] : HasCountableLimits C + +/-- +For this we need to dualize `sequentialFunctor_initial` (in +`Mathlib/CategoryTheory/Limits/Shapes/Countable.lean`) and the `proof_wanted` statements above. +-/ +proof_wanted hasCountableColimits_of_hasFiniteColimits_and_hasSequentialColimits + [HasFiniteColimits C] [HasLimitsOfShape ℕ C] : HasCountableColimits C + +end IsCofiltered + +end CategoryTheory.Limits diff --git a/Wanted/Combinatorics/SimpleGraph/StronglyRegular.lean b/Wanted/Combinatorics/SimpleGraph/StronglyRegular.lean new file mode 100644 index 00000000000000..b4275981c3d91c --- /dev/null +++ b/Wanted/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -0,0 +1,18 @@ +/- +Copyright (c) 2025 Tristan Figueroa-Reid. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Tristan Figueroa-Reid +-/ +module + +public import Mathlib.Combinatorics.SimpleGraph.StronglyRegular + +namespace SimpleGraph + +/-- **Conway's 99-graph problem** (from https://oeis.org/A248380/a248380.pdf) +can be reformulated as the existence of a strongly regular graph with params (99, 14, 1, 2). +This is an open problem, and has no known proof of existence. -/ +proof_wanted conway_99 : ∃ (α : Type) (_ : Fintype α) (G : SimpleGraph α) (_ : DecidableRel G.Adj), + IsSRGWith G 99 14 1 2 + +end SimpleGraph diff --git a/Wanted/Computability/TuringMachine/Computable.lean b/Wanted/Computability/TuringMachine/Computable.lean new file mode 100644 index 00000000000000..637ae3a14e6de3 --- /dev/null +++ b/Wanted/Computability/TuringMachine/Computable.lean @@ -0,0 +1,26 @@ +/- +Copyright (c) 2025 Bolton Bailey. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Bolton Bailey +-/ +module + +public import Mathlib.Computability.TuringMachine.Computable + +namespace Turing + +/-- +For any two polynomial time Multi-tape Turing Machines, +there exists another polynomial time multi-tape Turing Machine that composes their operations. +This machine can work by simply having one tape for each tape in both of the composed TMs. +It first carries out the operations of the first TM on the tapes associated with the first TM, +then copies the output tape of the first TM to the input tape of the second TM, +then runs the second TM. +-/ +proof_wanted TM2ComputableInPolyTime.comp + {α β γ αΓ βΓ γΓ : Type} {eα : α → List αΓ} {eβ : β → List βΓ} + {eγ : γ → List γΓ} {f : α → β} {g : β → γ} (h1 : TM2ComputableInPolyTime eα eβ f) + (h2 : TM2ComputableInPolyTime eβ eγ g) : + Nonempty (TM2ComputableInPolyTime eα eγ (g ∘ f)) + +end Turing diff --git a/Wanted/Data/EReal/Operations.lean b/Wanted/Data/EReal/Operations.lean new file mode 100644 index 00000000000000..bc84dbfa07e3a8 --- /dev/null +++ b/Wanted/Data/EReal/Operations.lean @@ -0,0 +1,18 @@ +/- +Copyright (c) 2025 Yury Kudryashov. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yury Kudryashov +-/ +module + +public import Mathlib.Data.EReal.Operations + +open ENNReal + +namespace EReal + +proof_wanted recENNReal_neg_coe_ennreal {motive : EReal → Sort*} (coe : ∀ x : ℝ≥0∞, motive x) + (neg_coe : ∀ x : ℝ≥0∞, 0 < x → motive (-x)) {x : ℝ≥0∞} (hx : 0 < x) : + recENNReal coe neg_coe (-x) = neg_coe x hx + +end EReal diff --git a/Wanted/Geometry/Euclidean/Volume/Measure.lean b/Wanted/Geometry/Euclidean/Volume/Measure.lean new file mode 100644 index 00000000000000..1a28d879be571c --- /dev/null +++ b/Wanted/Geometry/Euclidean/Volume/Measure.lean @@ -0,0 +1,17 @@ +/- +Copyright (c) 2026 Weiyi Wang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Weiyi Wang +-/ +module + +public import Mathlib.Geometry.Euclidean.Volume.Measure + +open MeasureTheory Measure Module + +/-- show the scaling factor equals to the ratio between the volume of `d`-dimensional +`Metric.ball` with Euclidean metric and with sup metric (i.e. a cube), or explicitly, +$\pi^{d/2} / (2^d \Gamma (d/2+1))$. -/ +proof_wanted MeasureTheory.Measure.addHaarScalarFactor_hausdorffMeasure_eq (d : ℕ) : + addHaarScalarFactor (volume : Measure (EuclideanSpace ℝ (Fin d))) μH[d] = + volume (Metric.ball (0 : EuclideanSpace ℝ (Fin d)) 1) / volume (Metric.ball (0 : Fin d → ℝ) 1) diff --git a/Wanted/Geometry/Manifold/PoincareConjecture.lean b/Wanted/Geometry/Manifold/PoincareConjecture.lean new file mode 100644 index 00000000000000..db9141082b9a19 --- /dev/null +++ b/Wanted/Geometry/Manifold/PoincareConjecture.lean @@ -0,0 +1,51 @@ +/- +Copyright (c) 2024 Junyan Xu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Junyan Xu +-/ +module + +public import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected +public import Mathlib.Geometry.Manifold.PoincareConjecture + +open scoped Manifold ContDiff +open Metric (sphere) + +local macro:max "ℝ" noWs n:superscript(term) : term => `(EuclideanSpace ℝ (Fin $(⟨n.raw[0]⟩))) +local macro:max "𝕊" noWs n:superscript(term) : term => + `(sphere (0 : EuclideanSpace ℝ (Fin ($(⟨n.raw[0]⟩) + 1))) 1) + +variable (M : Type*) [TopologicalSpace M] + +open ContinuousMap + +/-- The generalized topological Poincaré conjecture. +- For n = 2 it follows from the classification of surfaces. +- For n ≥ 5 it was proven by Stephen Smale in 1961 assuming M admits a smooth structure; + Newman (1966) and Connell (1967) proved it without the condition. +- For n = 4 it was proven by Michael Freedman in 1982. +- For n = 3 it was proven by Grigori Perelman in 2003. -/ +proof_wanted ContinuousMap.HomotopyEquiv.nonempty_homeomorph_sphere [T2Space M] + (n : ℕ) [ChartedSpace ℝⁿ M] : M ≃ₕ 𝕊ⁿ → Nonempty (M ≃ₜ 𝕊ⁿ) + +/-- The 3-dimensional topological Poincaré conjecture (proven by Perelman) -/ +proof_wanted SimplyConnectedSpace.nonempty_homeomorph_sphere_three + [T2Space M] [ChartedSpace ℝ³ M] [SimplyConnectedSpace M] [CompactSpace M] : + Nonempty (M ≃ₜ 𝕊³) + +/-- The 3-dimensional smooth Poincaré conjecture (proven by Perelman) -/ +proof_wanted SimplyConnectedSpace.nonempty_sdiffeomorph_sphere_three + [T2Space M] [ChartedSpace ℝ³ M] [IsManifold (𝓡 3) ∞ M] + [SimplyConnectedSpace M] [CompactSpace M] : + Nonempty (M ≃ₘ⟮𝓡 3, 𝓡 3⟯ 𝕊³) + +/-- The existence of an exotic 7-sphere (due to John Milnor) -/ +proof_wanted exists_homeomorph_isEmpty_diffeomorph_sphere_seven : + ∃ (M : Type) (_ : TopologicalSpace M) (_ : ChartedSpace ℝ⁷ M) + (_ : IsManifold (𝓡 7) ∞ M) (_homeo : M ≃ₜ 𝕊⁷), + IsEmpty (M ≃ₘ⟮𝓡 7, 𝓡 7⟯ 𝕊⁷) + +/-- The existence of a small exotic ℝ⁴, i.e. an open subset of ℝ⁴ that is homeomorphic but +not diffeomorphic to ℝ⁴. See https://en.wikipedia.org/wiki/Exotic_R4. -/ +proof_wanted exists_open_nonempty_homeomorph_isEmpty_diffeomorph_euclideanSpace_four : + ∃ M : TopologicalSpace.Opens ℝ⁴, Nonempty (M ≃ₜ ℝ⁴) ∧ IsEmpty (M ≃ₘ⟮𝓡 4, 𝓡 4⟯ ℝ⁴) diff --git a/Wanted/Geometry/Manifold/SmoothEmbedding.lean b/Wanted/Geometry/Manifold/SmoothEmbedding.lean new file mode 100644 index 00000000000000..abaeb1720fb39b --- /dev/null +++ b/Wanted/Geometry/Manifold/SmoothEmbedding.lean @@ -0,0 +1,41 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.Diffeomorph +public import Mathlib.Geometry.Manifold.SmoothEmbedding + +open scoped ContDiff +open Topology + +namespace Manifold + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E₁ E₃ E₄ : Type*} [NormedAddCommGroup E₁] [NormedSpace 𝕜 E₁] + [NormedAddCommGroup E₃] [NormedSpace 𝕜 E₃] [NormedAddCommGroup E₄] [NormedSpace 𝕜 E₄] + {H G G' : Type*} [TopologicalSpace H] [TopologicalSpace G] [TopologicalSpace G'] + {I : ModelWithCorners 𝕜 E₁ H} {J : ModelWithCorners 𝕜 E₃ G} {J' : ModelWithCorners 𝕜 E₄ G'} + {M N N' : Type*} [TopologicalSpace M] [ChartedSpace H M] + [TopologicalSpace N] [ChartedSpace G N] [TopologicalSpace N'] [ChartedSpace G' N'] + {n : ℕ∞ω} + +namespace IsSmoothEmbedding + +variable {f : M → N} + +-- use IsImmersion.comp and IsEmbedding.comp +/-- The composition of two smooth embeddings between Banach manifolds is a smooth embedding. -/ +proof_wanted comp -- [CompleteSpace E] [CompleteSpace E'] [CompleteSpace F] [CompleteSpace F'] + {g : N → N'} (hg : IsSmoothEmbedding J J' n g) (hf : IsSmoothEmbedding I J n f) : + IsSmoothEmbedding I J' n (g ∘ f) + +end IsSmoothEmbedding + +-- TODO: prove the same result for local diffeomorphisms and deduce it as a corollary +proof_wanted Diffeomorph.isSmoothEmbedding [IsManifold I n M] + (φ : Diffeomorph I I M M n) : IsSmoothEmbedding I I n φ + +end Manifold diff --git a/Wanted/GroupTheory/GroupAction/Jordan.lean b/Wanted/GroupTheory/GroupAction/Jordan.lean new file mode 100644 index 00000000000000..bd28145951527a --- /dev/null +++ b/Wanted/GroupTheory/GroupAction/Jordan.lean @@ -0,0 +1,54 @@ +/- +Copyright (c) 2025 Antoine Chambert-Loir. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Antoine Chambert-Loir +-/ +module + +public import Mathlib.GroupTheory.GroupAction.Jordan + +open MulAction SubMulAction Subgroup + +section Jordan + +variable {G α : Type*} [Group G] [MulAction G α] + +-- Wielandt claims that this is proved by the same method as +-- `normalClosure_of_stabilizer_eq_top` in `Mathlib/GroupTheory/GroupAction/Jordan.lean`. +proof_wanted IsPreprimitive.is_two_pretransitive' + (hG : IsPreprimitive G α) + {s : Set α} {n : ℕ} (hsn : Nat.card s = n + 1) (hsn' : n + 1 < Nat.card α) + (hs_trans : IsPretransitive (fixingSubgroup G s) (SubMulAction.ofFixingSubgroup G s)) : + IsMultiplyPretransitive (Subgroup.normalClosure (fixingSubgroup G s : Set G)) α 2 + +-- Wielandt claims that this stronger version of `MulAction.IsPreprimitive.is_two_preprimitive` +-- is proved in the same way. +proof_wanted is_two_preprimitive_strong_jordan + (hG : IsPreprimitive G α) + {s : Set α} {n : ℕ} (hsn : s.ncard = n + 1) (hsn' : n + 2 < Nat.card α) + (hs_prim : IsPreprimitive (fixingSubgroup G s) (ofFixingSubgroup G s)) : + IsMultiplyPreprimitive (Subgroup.normalClosure (fixingSubgroup G s : Set G)) α 2 + +end Jordan + +section Subgroups + +namespace Equiv.Perm + +variable {α : Type*} + +variable {G : Subgroup (Perm α)} + +variable [Fintype α] [DecidableEq α] + +/-- A primitive subgroup of `Equiv.Perm α` that contains a cycle of prime order +contains the alternating group. -/ +proof_wanted alternatingGroup_le_of_isPreprimitive_of_isCycle_mem + (hG : IsPreprimitive G α) + {p : ℕ} (hp : p.Prime) (hp' : p + 3 ≤ Nat.card α) + {g : Perm α} (hgc : g.IsCycle) (hgp : g.support.card = p) + (hg : g ∈ G) : alternatingGroup α ≤ G + +end Equiv.Perm + +end Subgroups diff --git a/Wanted/Order/KrullDimension.lean b/Wanted/Order/KrullDimension.lean new file mode 100644 index 00000000000000..a1c5944a600cfe --- /dev/null +++ b/Wanted/Order/KrullDimension.lean @@ -0,0 +1,25 @@ +/- +Copyright (c) 2024 Joachim Breitner. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joachim Breitner +-/ +module + +public import Mathlib.Data.Set.Card +public import Mathlib.Order.KrullDimension + +namespace Order + +/- +These two lemmas could possibly be used to simplify the calculations in +the `Concrete calculations` section of `Mathlib/Order/KrullDimension.lean`, especially once +the `Set.encard` api is richer. +-/ + +proof_wanted height_of_linearOrder {α : Type*} [LinearOrder α] (a : α) : + height a = (Set.Iio a).encard + +proof_wanted coheight_of_linearOrder {α : Type*} [LinearOrder α] (a : α) : + coheight a = (Set.Ioi a).encard + +end Order diff --git a/Wanted/Probability/Combinatorics/BinomialRandomGraph/Defs.lean b/Wanted/Probability/Combinatorics/BinomialRandomGraph/Defs.lean new file mode 100644 index 00000000000000..539cddaec23198 --- /dev/null +++ b/Wanted/Probability/Combinatorics/BinomialRandomGraph/Defs.lean @@ -0,0 +1,21 @@ +/- +Copyright (c) 2026 Yaël Dillies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies +-/ +module + +public import Mathlib.Probability.Combinatorics.BinomialRandomGraph.Defs + +open MeasureTheory Measure ProbabilityTheory unitInterval + +namespace SimpleGraph +variable {V : Type*} {p : I} + +-- This should be restated as an equality of distributions now +-- https://github.com/leanprover-community/mathlib4/pull/28248 is in. +proof_wanted binomialRandom_map_ncard_edgeSet_singleton [Finite V] (n : ℕ) : + G(V, p).map (fun G ↦ G.edgeSet.ncard) {n} = ((Nat.card V).choose 2).choose n * toNNReal p ^ n * + toNNReal (σ p) ^ ((Nat.card V).choose 2 - n) + +end SimpleGraph diff --git a/Wanted/Probability/Distributions/Binomial.lean b/Wanted/Probability/Distributions/Binomial.lean new file mode 100644 index 00000000000000..82ce513b2957a5 --- /dev/null +++ b/Wanted/Probability/Distributions/Binomial.lean @@ -0,0 +1,30 @@ +/- +Copyright (c) 2026 Yaël Dillies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dillies +-/ +module + +public import Mathlib.Probability.Distributions.Binomial + +open MeasureTheory +open scoped ProbabilityTheory unitInterval + +namespace ProbabilityTheory +variable {Ω : Type*} {m : MeasurableSpace Ω} {P : Measure Ω} {n : ℕ} {p : I} {X : Ω → ℝ} + +/-- **Variance of a binomial random variable**. + +The variance of a binomial random variable with parameters `n` and `p` is `p(1 - p)n`. -/ +proof_wanted variance_of_hasLaw_binomial (hX : HasLaw X Bin(ℝ, n, p) P) : + Var[X; P] = p * (1 - p) * n + +/-- **Conditional variance of a binomial random variable**. + +The conditional variance of a binomial random variable is the product of the conditional +probabilities that it's equal to `0` and that it's equal to `1`. -/ +proof_wanted condVar_of_hasLaw_binomial {m₀ : MeasurableSpace Ω} (hm : m ≤ m₀) {P : Measure[m₀] Ω} + (hX : HasLaw X Bin(ℝ, n, p) P) : + Var[X; P | m] =ᵐ[P] P[X | m] * P[1 - X | m] + +end ProbabilityTheory diff --git a/Wanted/RingTheory/Congruence/Basic.lean b/Wanted/RingTheory/Congruence/Basic.lean new file mode 100644 index 00000000000000..3084287e53f377 --- /dev/null +++ b/Wanted/RingTheory/Congruence/Basic.lean @@ -0,0 +1,24 @@ +/- +Copyright (c) 2026 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ +module + +public import Mathlib.RingTheory.Congruence.Basic + +variable {R R' : Type*} + +namespace RingCon + +variable [Add R] [Mul R] [Add R'] [Mul R'] + +open scoped Function + +-- This probably needs the RingCon version of `Setoid.comap_surjective` +proof_wanted comap_ringConGen_equiv + {F} [FunLike F R' R] [MulHomClass F R' R] [AddHomClass F R' R] [EquivLike F R' R] + (r : R → R → Prop) (f : F) : + (ringConGen r).comap f = ringConGen (r on f) + +end RingCon diff --git a/Wanted/RingTheory/Etale/Descent.lean b/Wanted/RingTheory/Etale/Descent.lean new file mode 100644 index 00000000000000..0cafeef8ee5c20 --- /dev/null +++ b/Wanted/RingTheory/Etale/Descent.lean @@ -0,0 +1,31 @@ +/- +Copyright (c) 2026 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +module + +public import Mathlib.RingTheory.Etale.Descent + +open TensorProduct + +namespace Algebra + +/- +The lemma `Algebra.FormallySmooth.of_formallySmooth_tensorProduct_of_faithfullyFlat` has an +additional `Algebra.FinitePresentation` assumption, because the proof uses that a flat module +of finite presentation is projective and the former descends. This also holds without +the finite presentation assumption, but requires showing that projectivity descends +along faithfully flat base change, which is due to Raynaud and Gruson +(see https://stacks.math.columbia.edu/tag/058B). +-/ + +/-- Formally smooth algebras descend along faithfully flat base change. See the TODO +in the module docstring of `Mathlib/RingTheory/Etale/Descent.lean`. -/ +proof_wanted FormallySmooth.of_formallySmooth_tensorProduct_of_faithfullyFlat + {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] + (T : Type*) [CommRing T] [Algebra R T] [Module.FaithfullyFlat R T] + [FormallySmooth T (T ⊗[R] S)] : + FormallySmooth R S + +end Algebra diff --git a/Wanted/RingTheory/KrullDimension/Basic.lean b/Wanted/RingTheory/KrullDimension/Basic.lean new file mode 100644 index 00000000000000..03c8242578a85a --- /dev/null +++ b/Wanted/RingTheory/KrullDimension/Basic.lean @@ -0,0 +1,15 @@ +/- +Copyright (c) 2024 Fangming Li. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Fangming Li +-/ +module + +public import Mathlib.Algebra.MvPolynomial.Basic +public import Mathlib.RingTheory.KrullDimension.Basic + +variable {R : Type*} [CommSemiring R] + +proof_wanted MvPolynomial.fin_ringKrullDim_eq_add_of_isNoetherianRing + [IsNoetherianRing R] (n : ℕ) : + ringKrullDim (MvPolynomial (Fin n) R) = ringKrullDim R + n diff --git a/Wanted/RingTheory/SimpleModule/Basic.lean b/Wanted/RingTheory/SimpleModule/Basic.lean new file mode 100644 index 00000000000000..65427af99b501e --- /dev/null +++ b/Wanted/RingTheory/SimpleModule/Basic.lean @@ -0,0 +1,20 @@ +/- +Copyright (c) 2024 Junyan Xu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Junyan Xu +-/ +module + +public import Mathlib.RingTheory.SimpleModule.Basic + +variable {R S : Type*} [Ring R] [Ring S] + {M' : Type*} [AddCommGroup M'] [Module R M'] {N'} [AddCommGroup N'] [Module S N'] + {σ : R →+* S} (l : M' →ₛₗ[σ] N') + +-- TODO: generalize Submodule.equivMapOfInjective from InvPair to RingHomSurjective +proof_wanted LinearMap.isSemisimpleModule_of_injective (_ : Function.Injective l) + [IsSemisimpleModule S N'] : IsSemisimpleModule R M' + +--TODO: generalize LinearMap.quotKerEquivOfSurjective to SemilinearMaps + RingHomSurjective +proof_wanted LinearMap.isSemisimpleModule_of_surjective (_ : Function.Surjective l) + [IsSemisimpleModule R M'] : IsSemisimpleModule S N' diff --git a/Wanted/RingTheory/SimpleModule/WedderburnArtin.lean b/Wanted/RingTheory/SimpleModule/WedderburnArtin.lean new file mode 100644 index 00000000000000..f6eb1aa6e18c3e --- /dev/null +++ b/Wanted/RingTheory/SimpleModule/WedderburnArtin.lean @@ -0,0 +1,19 @@ +/- +Copyright (c) 2025 Junyan Xu. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Junyan Xu +-/ +module + +public import Mathlib.RingTheory.SimpleModule.WedderburnArtin + +variable {R : Type*} [Ring R] + +-- Need left-right symmetry of Jacobson radical +proof_wanted IsSemiprimaryRing.mulOpposite [IsSemiprimaryRing R] : IsSemiprimaryRing Rᵐᵒᵖ + +proof_wanted isSemiprimaryRing_mulOpposite_iff : IsSemiprimaryRing Rᵐᵒᵖ ↔ IsSemiprimaryRing R + +-- A left Artinian ring is right Noetherian iff it is right Artinian. To be left as an `example`. +proof_wanted IsArtinianRing.isNoetherianRing_iff_isArtinianRing_mulOpposite + [IsArtinianRing R] : IsNoetherianRing Rᵐᵒᵖ ↔ IsArtinianRing Rᵐᵒᵖ diff --git a/lakefile.lean b/lakefile.lean index 2afc2a7a30308a..05977eed5329a2 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -93,6 +93,19 @@ lean_lib Archive where lean_lib Counterexamples where leanOptions := mathlibLeanOptions +/-- Wanted statements: `Wanted/X/Y/Z.lean` contains the `proof_wanted` statements +corresponding to `Mathlib/X/Y/Z.lean`. Each file carries a copyright header naming the +author of the original statements, but beyond that contains only imports, context setup +(`open`/`namespace`/`variable`) and `proof_wanted` statements; in particular there are no +module docstrings, so the header style linter is disabled. +`proof_wanted` elaborates to a `private` placeholder declaration, so every module here +consists solely of private declarations; the `privateModule` linter is disabled accordingly +(neither `@[expose] public section` nor a `public` modifier suppresses it, since the +placeholder is unconditionally `private`). -/ +lean_lib Wanted where + leanOptions := mathlibLeanOptions.push ⟨`weak.linter.style.header, false⟩ + |>.push ⟨`weak.linter.privateModule, false⟩ + /-- Additional documentation in the form of modules that only contain module docstrings. -/ lean_lib docs where roots := #[`docs] From 03e4536e25f67f0b468492fd9a91611c154726da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 10:46:00 +0000 Subject: [PATCH 1272/1300] feat(Algebra/Homology): homotopy equivalences in degreewise split short exact sequences (#42323) --- Mathlib.lean | 2 + .../Algebra/Homology/Embedding/Extend.lean | 10 ++++ .../Algebra/Homology/Embedding/Splitting.lean | 47 +++++++++++++++ .../HomotopyCategory/ChainComplex.lean | 59 +++++++++++++++++++ .../HomotopyCategory/DegreewiseSplit.lean | 29 +++++++-- .../Algebra/Homology/ShortComplex/Exact.lean | 8 +++ 6 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 Mathlib/Algebra/Homology/Embedding/Splitting.lean create mode 100644 Mathlib/Algebra/Homology/HomotopyCategory/ChainComplex.lean diff --git a/Mathlib.lean b/Mathlib.lean index aa20d8c3eb4aaf..faf12e5137a99b 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -612,6 +612,7 @@ public import Mathlib.Algebra.Homology.Embedding.HomEquiv public import Mathlib.Algebra.Homology.Embedding.IsSupported public import Mathlib.Algebra.Homology.Embedding.Restriction public import Mathlib.Algebra.Homology.Embedding.RestrictionHomology +public import Mathlib.Algebra.Homology.Embedding.Splitting public import Mathlib.Algebra.Homology.Embedding.StupidTrunc public import Mathlib.Algebra.Homology.Embedding.TruncGE public import Mathlib.Algebra.Homology.Embedding.TruncGEHomology @@ -638,6 +639,7 @@ public import Mathlib.Algebra.Homology.HomologySequenceLemmas public import Mathlib.Algebra.Homology.Homotopy public import Mathlib.Algebra.Homology.HomotopyCategory public import Mathlib.Algebra.Homology.HomotopyCategory.Acyclic +public import Mathlib.Algebra.Homology.HomotopyCategory.ChainComplex public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology diff --git a/Mathlib/Algebra/Homology/Embedding/Extend.lean b/Mathlib/Algebra/Homology/Embedding/Extend.lean index 47c6cecdd69e81..4ed846b09b5fa5 100644 --- a/Mathlib/Algebra/Homology/Embedding/Extend.lean +++ b/Mathlib/Algebra/Homology/Embedding/Extend.lean @@ -357,6 +357,16 @@ noncomputable def extendFunctor [HasZeroMorphisms C] : obj K := K.extend e map φ := HomologicalComplex.extendMap φ e +set_option backward.defeqAttrib.useBackward true in +/-- Given an embedding `e : c.Embedding c'` of complex shapes, this is the isomorphism +`e.extendFunctor C ⋙ HomologicalComplex.eval _ _ i' ≅ HomologicalComplex.eval _ _ i` +when `e.f i = i'. -/ +noncomputable def extendFunctorCompEvalIso + [HasZeroMorphisms C] {i : ι} {i' : ι'} (h : e.f i = i') : + e.extendFunctor C ⋙ HomologicalComplex.eval _ _ i' ≅ HomologicalComplex.eval _ _ i := + NatIso.ofComponents (fun K ↦ K.extendXIso e h) + (by simp [HomologicalComplex.extendMap_f _ _ h]) + instance [HasZeroMorphisms C] : (e.extendFunctor C).PreservesZeroMorphisms where instance [Preadditive C] : (e.extendFunctor C).Additive where diff --git a/Mathlib/Algebra/Homology/Embedding/Splitting.lean b/Mathlib/Algebra/Homology/Embedding/Splitting.lean new file mode 100644 index 00000000000000..931e36742118d8 --- /dev/null +++ b/Mathlib/Algebra/Homology/Embedding/Splitting.lean @@ -0,0 +1,47 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.Homotopy +public import Mathlib.Algebra.Homology.Embedding.AreComplementary +public import Mathlib.Algebra.Homology.ShortComplex.Exact + +/-! +# Extension of degreewise splittings + +-/ + +@[expose] public section + +open CategoryTheory Limits HomologicalComplex + +variable {ι₁ ι₂ : Type*} {c₁ : ComplexShape ι₁} {c₂ : ComplexShape ι₂} + +namespace ComplexShape.Embedding + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] + (e : Embedding c₁ c₂) {S : ShortComplex (HomologicalComplex C c₁)} + (σ : ∀ i, (S.map (eval _ _ i)).Splitting) + +open Classical in +/-- If `S` is a short complex in `HomologicalComplex C c₁` that is degreewise split, +then `S.map (e.extendFunctor C)` also is if `e : Embedding c₁ c₂`. -/ +noncomputable def splittingExtend (i₂ : ι₂) : + ((S.map (e.extendFunctor C)).map (eval _ _ i₂)).Splitting := + if hi₂ : ∃ i₁, e.f i₁ = i₂ then + .ofIso (σ _) (S.mapNatIso (e.extendFunctorCompEvalIso C hi₂.choose_spec).symm) + else by + refine .ofIsZero _ ?_ ?_ ?_ + all_goals exact isZero_extend_X _ _ _ (by tauto) + +lemma splittingExtend_apply {i₁ : ι₁} {i₂ : ι₂} (h : e.f i₁ = i₂) : + splittingExtend e σ i₂ = + .ofIso (σ _) (S.mapNatIso (e.extendFunctorCompEvalIso C h).symm) := by + have : ∃ i₁, e.f i₁ = i₂ := ⟨_, h⟩ + obtain rfl := e.injective_f (this.choose_spec.trans h.symm) + apply dite_eq_left + +end ComplexShape.Embedding diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/ChainComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/ChainComplex.lean new file mode 100644 index 00000000000000..94daaec7f17c2f --- /dev/null +++ b/Mathlib/Algebra/Homology/HomotopyCategory/ChainComplex.lean @@ -0,0 +1,59 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit +public import Mathlib.Algebra.Homology.Embedding.ExtendHomotopy +public import Mathlib.Algebra.Homology.Embedding.Splitting + +/-! +# Homotopy equivalences between chain complexes + +If `0 ⟶ K₁ ⟶ K₂ ⟶ K₃ ⟶ 0` is a degreewise short exact sequence of +chain complexes, we show that `K₁ ⟶ K₂` is a homotopy equivalence +iff `K₃` is contractible, and `K₂ ⟶ K₃` is a homotopy equivalence +iff `K₁`. + +-/ + +@[expose] public section + +open CategoryTheory Limits HomologicalComplex + +namespace ChainComplex + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasBinaryBiproducts C] + (S : ShortComplex (ChainComplex C ℕ)) + +set_option backward.isDefEq.respectTransparency false in +lemma homotopyEquivalences_shortComplexF_iff_of_degreewiseSplit + (σ : ∀ n, (S.map (eval _ _ n)).Splitting) : + homotopyEquivalences _ _ S.f ↔ Nonempty (Homotopy (𝟙 S.X₃) 0) := by + have := CochainComplex.homotopyEquivalences_shortComplexF_iff_of_splitting _ + (ComplexShape.embeddingDownNat.splittingExtend σ) + simp only [ShortComplex.map_f, ComplexShape.Embedding.extendFunctor_map, + homotopyEquivalences_extendMap_iff] at this + rw [this] + refine Equiv.nonempty_congr + (Equiv.trans ?_ (Homotopy.extendEquiv ComplexShape.embeddingDownNat).symm) + simp + rfl + +set_option backward.isDefEq.respectTransparency false in +lemma homotopyEquivalences_shortComplexG_iff_of_degreewiseSplit + (σ : ∀ n, (S.map (eval _ _ n)).Splitting) : + homotopyEquivalences _ _ S.g ↔ Nonempty (Homotopy (𝟙 S.X₁) 0) := by + have := CochainComplex.homotopyEquivalences_shortComplexG_iff_of_splitting _ + (ComplexShape.embeddingDownNat.splittingExtend σ) + simp only [ShortComplex.map_g, ComplexShape.Embedding.extendFunctor_map, + homotopyEquivalences_extendMap_iff] at this + rw [this] + refine Equiv.nonempty_congr + (Equiv.trans ?_ (Homotopy.extendEquiv ComplexShape.embeddingDownNat).symm) + simp + rfl + +end ChainComplex diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean b/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean index e5fe56e3d4ea1c..78460dbfdbba7e 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/DegreewiseSplit.lean @@ -244,6 +244,28 @@ noncomputable def trianglehRotateIsoTrianglehOfDegreewiseSplit : end mappingCone +lemma trianglehOfDegreewiseSplit_distinguished [HasZeroObject C] + (σ : ∀ n, (S.map (eval _ _ n)).Splitting) : + trianglehOfDegreewiseSplit S σ ∈ distTriang _ := by + rw [rotate_distinguished_triangle, rotate_distinguished_triangle] + refine isomorphic_distinguished _ ?_ _ + (CochainComplex.trianglehOfDegreewiseSplitRotateRotateIso S σ) + exact ⟨_, _, _, ⟨Iso.refl _⟩⟩ + +lemma homotopyEquivalences_shortComplexF_iff_of_splitting [HasZeroObject C] + (σ : ∀ n, (S.map (eval _ _ n)).Splitting) : + homotopyEquivalences _ _ S.f ↔ Nonempty (Homotopy (𝟙 S.X₃) 0) := by + rw [← HomotopyCategory.isZero_quotient_obj_iff, + ← isIso_quotient_map_iff_homotopyEquivalences] + exact (Triangle.isZero₃_iff_isIso₁ _ (trianglehOfDegreewiseSplit_distinguished S σ)).symm + +lemma homotopyEquivalences_shortComplexG_iff_of_splitting [HasZeroObject C] + (σ : ∀ n, (S.map (eval _ _ n)).Splitting) : + homotopyEquivalences _ _ S.g ↔ Nonempty (Homotopy (𝟙 S.X₁) 0) := by + rw [← HomotopyCategory.isZero_quotient_obj_iff, + ← isIso_quotient_map_iff_homotopyEquivalences] + exact (Triangle.isZero₁_iff_isIso₂ _ (trianglehOfDegreewiseSplit_distinguished S σ)).symm + end CochainComplex namespace HomotopyCategory @@ -261,10 +283,7 @@ lemma distinguished_iff_iso_trianglehOfDegreewiseSplit exact ⟨_, _, ⟨(triangleRotation _).counitIso.symm.app _ ≪≫ (rotate _).mapIso e ≪≫ CochainComplex.mappingCone.trianglehRotateIsoTrianglehOfDegreewiseSplit φ⟩⟩ · rintro ⟨S, σ, ⟨e⟩⟩ - rw [rotate_distinguished_triangle, rotate_distinguished_triangle] - refine isomorphic_distinguished _ ?_ _ - ((rotate _ ⋙ rotate _).mapIso e ≪≫ - CochainComplex.trianglehOfDegreewiseSplitRotateRotateIso S σ) - exact ⟨_, _, _, ⟨Iso.refl _⟩⟩ + exact isomorphic_distinguished _ + (CochainComplex.trianglehOfDegreewiseSplit_distinguished S σ) _ e end HomotopyCategory diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index 9916143396dc42..2ae2bed6364cdd 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -676,6 +676,14 @@ noncomputable def ofIsIsoOfIsZero (hf : IsIso S.f) (hg : IsZero S.X₃) : Splitt s := 0 s_g := hg.eq_of_src _ _ +/-- The obvious splitting of a short complex `S` when `S.X₁`, `S.X₂` and `S.X₃` are zero. -/ +def ofIsZero (h₁ : IsZero S.X₁) (h₂ : IsZero S.X₂) (h₃ : IsZero S.X₃) : Splitting S where + r := 0 + s := 0 + f_r := h₁.eq_of_src .. + s_g := h₃.eq_of_src .. + id := h₂.eq_of_src .. + variable {S} set_option backward.defeqAttrib.useBackward true in From 4c940b7c0bfd9b77097e9463e0c7e66ae1074554 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 11 Aug 2026 10:55:42 +0000 Subject: [PATCH 1273/1300] feat(Analysis/Complex/IsIntegral): `I` is integral over any `CommRing` (#42514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have separate theorems for `ℤ` and `ℚ`, but one is enough for all rings. --- Mathlib/Analysis/Complex/IsIntegral.lean | 20 +++++++++++--------- Mathlib/NumberTheory/Niven.lean | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Mathlib/Analysis/Complex/IsIntegral.lean b/Mathlib/Analysis/Complex/IsIntegral.lean index 1bdd07963bd2bb..e152e12dd0bc2d 100644 --- a/Mathlib/Analysis/Complex/IsIntegral.lean +++ b/Mathlib/Analysis/Complex/IsIntegral.lean @@ -1,18 +1,20 @@ /- Copyright (c) 2022 Yuyang Zhao. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Yuyang Zhao +Authors: Yuyang Zhao, Snir Broshi -/ module -public import Mathlib.Algebra.Algebra.Rat public import Mathlib.Data.Complex.Basic -public import Mathlib.RingTheory.IntegralClosure.IsIntegral.Basic +public import Mathlib.RingTheory.IntegralClosure.IsIntegral.Defs + +import Mathlib.Algebra.Polynomial.Monic /-! # Integral elements of ℂ -This file proves that `Complex.I` is integral over ℤ and ℚ. +This file proves that `Complex.I` is integral over any commutative ring `R` when `ℂ` is an +`R`-algebra. -/ public section @@ -21,11 +23,11 @@ open Polynomial namespace Complex -theorem isIntegral_int_I : IsIntegral ℤ I := by - refine ⟨X ^ 2 + C 1, monic_X_pow_add_C _ two_ne_zero, ?_⟩ - rw [eval₂_add, eval₂_X_pow, eval₂_C, I_sq, eq_intCast, Int.cast_one, neg_add_cancel] +theorem isIntegral_I (R : Type*) [CommRing R] [Algebra R ℂ] : IsIntegral R I := + ⟨X ^ 2 + C 1, monic_X_pow_add_C _ two_ne_zero, by simp⟩ + +@[deprecated (since := "2026-08-06")] alias isIntegral_int_I := isIntegral_I -theorem isIntegral_rat_I : IsIntegral ℚ I := - isIntegral_int_I.tower_top +@[deprecated (since := "2026-08-06")] alias isIntegral_rat_I := isIntegral_I end Complex diff --git a/Mathlib/NumberTheory/Niven.lean b/Mathlib/NumberTheory/Niven.lean index 68444271f6f6ac..80427fbe2ce115 100644 --- a/Mathlib/NumberTheory/Niven.lean +++ b/Mathlib/NumberTheory/Niven.lean @@ -68,7 +68,7 @@ theorem isIntegral_exp_neg_rat_mul_pi_mul_I (q : ℚ) : theorem isIntegral_two_mul_sin_rat_mul_pi (q : ℚ) : IsIntegral ℤ <| 2 * sin (q * π) := by rw [sin.eq_1, mul_div_cancel₀ _ two_ne_zero] exact (isIntegral_exp_neg_rat_mul_pi_mul_I q).sub (isIntegral_exp_rat_mul_pi_mul_I q) - |>.mul isIntegral_int_I + |>.mul <| isIntegral_I ℤ /-- `2 cos(q * π)` for `q : ℚ` is integral over `ℤ`, using the complex `cos` function. -/ theorem isIntegral_two_mul_cos_rat_mul_pi (q : ℚ) : IsIntegral ℤ <| 2 * cos (q * π) := by From f31bcf05ae323cf173e45950e4805a653b5028f4 Mon Sep 17 00:00:00 2001 From: Snir Broshi <26556598+SnirBroshi@users.noreply.github.com> Date: Tue, 11 Aug 2026 10:55:44 +0000 Subject: [PATCH 1274/1300] feat(Order/JordanHolder): `IsWeakLowerModularLattice` is sufficient for `JordanHolderLattice` (#42556) --- Mathlib/Order/JordanHolder.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Order/JordanHolder.lean b/Mathlib/Order/JordanHolder.lean index 7b7671e89efcf2..a737f7952cb4b6 100644 --- a/Mathlib/Order/JordanHolder.lean +++ b/Mathlib/Order/JordanHolder.lean @@ -79,8 +79,8 @@ class JordanHolderLattice (X : Type u) [Lattice X] where namespace JordanHolderLattice -/-- Every modular lattice is a Jordan Hölder lattice. -/ -instance (X : Type u) [Lattice X] [IsModularLattice X] : JordanHolderLattice X where +/-- Every weakly lower modular lattice is a Jordan Hölder lattice. -/ +instance (X : Type u) [Lattice X] [IsWeakLowerModularLattice X] : JordanHolderLattice X where IsMaximal := (· ⋖ ·) lt_of_isMaximal := CovBy.lt sup_eq_of_isMaximal hxz hyz := hxz.wcovBy.sup_eq hyz.wcovBy From 8ed593ec9da582fcd42e48be70d05c7018816208 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Tue, 11 Aug 2026 10:55:47 +0000 Subject: [PATCH 1275/1300] feat(RingTheory/Nilpotents): basic MulOpposite lemmas for `IsNilpotent`/`IsReduced` (#42625) --- Mathlib/RingTheory/Nilpotent/Defs.lean | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Mathlib/RingTheory/Nilpotent/Defs.lean b/Mathlib/RingTheory/Nilpotent/Defs.lean index 4108190b2a5f23..c794aaf6892988 100644 --- a/Mathlib/RingTheory/Nilpotent/Defs.lean +++ b/Mathlib/RingTheory/Nilpotent/Defs.lean @@ -52,6 +52,20 @@ theorem IsUnit.isNilpotent_unit_mul_of_commute_iff [MonoidWithZero R] {r u : R} IsNilpotent (u * r) ↔ IsNilpotent r := h_comm ▸ hu.isNilpotent_mul_unit_of_commute_iff h_comm +@[simp] +theorem isNilpotent_op [MonoidWithZero R] {x : R} : + IsNilpotent (MulOpposite.op x) ↔ IsNilpotent x := by + simp_rw [IsNilpotent, ← MulOpposite.op_pow, MulOpposite.op_eq_zero_iff] + +alias ⟨_, IsNilpotent.op⟩ := isNilpotent_op + +@[simp] +theorem isNilpotent_unop [MonoidWithZero R] {x : Rᵐᵒᵖ} : + IsNilpotent (MulOpposite.unop x) ↔ IsNilpotent x := + isNilpotent_op.symm + +alias ⟨_, IsNilpotent.unop⟩ := isNilpotent_unop + section NilpotencyClass section ZeroPow @@ -120,6 +134,13 @@ end MonoidWithZero end NilpotencyClass +@[simp] +theorem isReduced_mulOpposite_iff [MonoidWithZero R] : IsReduced Rᵐᵒᵖ ↔ IsReduced R := by + simp [isReduced_iff] + +instance [MonoidWithZero R] [IsReduced R] : IsReduced Rᵐᵒᵖ := + isReduced_mulOpposite_iff.mpr ‹_› + theorem isReduced_of_injective [MonoidWithZero R] [MonoidWithZero S] {F : Type*} [FunLike F R S] [MonoidWithZeroHomClass F R S] (f : F) (hf : Function.Injective f) [IsReduced S] : From 6fe456bf5ca39dc0d9df19eb2607b1a8a8a129b4 Mon Sep 17 00:00:00 2001 From: Floris van Doorn Date: Tue, 11 Aug 2026 11:20:16 +0000 Subject: [PATCH 1276/1300] fix: typo in simps error messages (#41984) * Remove trailing underscores in names `simps`-errors would erroneously print * Restore Lean 3 error message tests. --- Mathlib/Tactic/Simps/Basic.lean | 15 ++++++--- MathlibTest/Simps.lean | 58 ++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index b6059d59f72267..7588f05786754d 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -1094,8 +1094,8 @@ private partial def addProjections (nm : NameStruct) (type lhs rhs : Expr) throwError "Invalid `simps` attribute. Target {str} is not a structure" if !todoNext.isEmpty && str ∉ cfg.notRecursive then let firstTodo := todoNext.head!.1 - throwError "Invalid simp lemma {nm.update firstTodo false |>.toName}.\nProjection \ - {(splitOnNotNumber firstTodo "_")[1]!} doesn't exist, \ + throwError "Invalid simp lemma {nm.update (dropLast firstTodo) false |>.toName}.\n\ + Projection {(splitOnNotNumber firstTodo "_")[1]!} doesn't exist, \ because target {str} is not a structure." if cfg.fullyApplied then addProjection stxProj univs nm.toName tgt lhsAp rhsAp newArgs cfg @@ -1151,8 +1151,8 @@ private partial def addProjections (nm : NameStruct) (type lhs rhs : Expr) throwError "Invalid `simps` attribute. The body is not a constructor application:\ {indentExpr rhsWhnf}" if !todoNext.isEmpty then - throwError "Invalid simp lemma {nm.update todoNext.head!.1 false |>.toName}.\n\ - The given definition is not a constructor application:{indentExpr rhsWhnf}" + throwError "Invalid simp lemma {nm.update (dropLast todoNext.head!.1) false |>.toName}.\ + \nThe given definition is not a constructor application:{indentExpr rhsWhnf}" if !addThisProjection then if cfg.fullyApplied then addProjection stxProj univs nm.toName tgt lhsAp rhsEta newArgs cfg @@ -1181,7 +1181,7 @@ private partial def addProjections (nm : NameStruct) (type lhs rhs : Expr) -- check whether all elements in `todo` have a projection as prefix if let some (x, _) := todo.find? fun (x, _) ↦ projs.all fun proj ↦ !isPrefixOfAndNotNumber (proj.lastComponentAsString ++ "_") x then - let simpLemma := nm.update x |>.toName + let simpLemma := nm.update (dropLast x) |>.toName let neededProj := (splitOnNotNumber x "_")[0]! throwError "Invalid simp lemma {simpLemma}. \ Structure {str} does not have projection {neededProj}.\n\ @@ -1203,6 +1203,11 @@ private partial def addProjections (nm : NameStruct) (type lhs rhs : Expr) trace[simps.debug] "Recursively add projections for:{indentExpr newLhs}" addProjections newName newType newLhs newRhs newArgs false cfg newTodo projNrs return if addThisProjection then nms.push nm.toName else nms +where + /-- Drop the last character of a string, used to remove the interal trailing underscore in the + variable `todo`. -/ + dropLast (todo : String) : String := + todo.dropEnd 1 |>.copy end Simps open Simps diff --git a/MathlibTest/Simps.lean b/MathlibTest/Simps.lean index 851404520f8ac9..d7bbe911a29705 100644 --- a/MathlibTest/Simps.lean +++ b/MathlibTest/Simps.lean @@ -355,29 +355,43 @@ run_cmd liftTermElabM do #[`specify.specify4_snd_snd, `specify.specify4_snd] guard <| simpsAttr.getParam? env `specify.specify5 == #[`specify.specify5_fst, `specify.specify5_snd] - _ ← successIfFail <| simpsTac .missing `specify.specify1 {} [("fst_fst", .missing)] --- "Invalid simp lemma specify.specify1_fst_fst. --- Projection fst doesn't exist, because target is not a structure." - _ ← successIfFail <| simpsTac .missing `specify.specify1 {} [("foo_fst", .missing)] --- "Invalid simp lemma specify.specify1_foo_fst. Structure prod does not have projection foo. --- The known projections are: --- [fst, snd] --- You can also see this information by running --- `initialize_simps_projections? prod`. --- Note: these projection names might not correspond to the projection names of the structure." - _ ← successIfFail <| simpsTac .missing `specify.specify1 {} [("snd_bar", .missing)] --- "Invalid simp lemma specify.specify1_snd_bar. Structure prod does not have projection bar. --- The known projections are: --- [fst, snd] --- You can also see this information by running --- `initialize_simps_projections? prod`. --- Note: these projection names might not correspond to the projection names of the structure." - _ ← successIfFail <| simpsTac .missing `specify.specify5 { rhsMd := .default, simpRhs := true } - [("snd_snd", .missing)] --- "Invalid simp lemma specify.specify5_snd_snd. --- The given definition is not a constructor application: --- Classical.choice specify.specify5._proof_1" +/-- +error: Invalid simp lemma failure1_fst_fst. +Projection doesn't exist, because target Nat is not a structure. +-/ +#guard_msgs in +@[simps fst_fst] def failure1 : ℕ × ℕ × ℕ := (1, 2, 3) + +/-- +error: Invalid simp lemma failure2_foo_fst. Structure Prod does not have projection foo. +The known projections are: + [fst, snd] +You can also see this information by running + `initialize_simps_projections? Prod`. +Note: these projection names might be customly defined for `simps`, and could differ from the projection names of the structure. +-/ +#guard_msgs in +@[simps foo_fst] def failure2 : ℕ × ℕ × ℕ := (1, 2, 3) + +/-- +error: Invalid simp lemma failure3_snd_bar. Structure Prod does not have projection bar. +The known projections are: + [fst, snd] +You can also see this information by running + `initialize_simps_projections? Prod`. +Note: these projection names might be customly defined for `simps`, and could differ from the projection names of the structure. +-/ +#guard_msgs in +@[simps snd_bar] def failure3 : ℕ × ℕ × ℕ := (1, 2, 3) + +/-- +error: Invalid simp lemma specify5_snd_snd. +The given definition is not a constructor application: + Classical.choice specify.specify5._proof_1 +-/ +#guard_msgs in +@[simps! snd_snd] noncomputable def specify5 : ℕ × ℕ × ℕ := (1, Classical.choice ⟨(2, 3)⟩) /- We also eta-reduce if we explicitly specify the projection. -/ attribute [simps extra] test From 20a890a070086b07b8dbe3763c0bf4c71f3a4b7d Mon Sep 17 00:00:00 2001 From: Yi Liu Date: Tue, 11 Aug 2026 11:20:18 +0000 Subject: [PATCH 1277/1300] feat(Probability/Kernel/Composition): kernel Radon-Nikodym derivative of composition products (#42292) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR resolves the TODO in this file by adding `rnDeriv_measure_compProd_right` and `rnDeriv_measure_compProd`, which replace `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)` by `∂κ/∂η` under the suitable assumptions. --- .../Kernel/Composition/RadonNikodym.lean | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/Mathlib/Probability/Kernel/Composition/RadonNikodym.lean b/Mathlib/Probability/Kernel/Composition/RadonNikodym.lean index 46e1678bbc656c..1c52d34a60bf8c 100644 --- a/Mathlib/Probability/Kernel/Composition/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/Composition/RadonNikodym.lean @@ -6,8 +6,9 @@ Authors: Rémy Degenne module public import Mathlib.Probability.Kernel.Composition.MeasureCompProd +public import Mathlib.Probability.Kernel.RadonNikodym -import Mathlib.MeasureTheory.Measure.Decomposition.RadonNikodym +import Mathlib.Probability.Kernel.CompProdEqIff /-! # Radon-Nikodym derivative of a composition product @@ -16,17 +17,19 @@ We compute the Radon-Nikodym derivative of a composition product `μ ⊗ₘ κ` composition product `ν ⊗ₘ η` in terms of the Radon-Nikodym derivatives `∂μ/∂ν` and `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)`. +If `α` is countable or `β` is countably generated, the kernels have a Radon-Nikodym derivative +`∂κ/∂η` and we give statements in terms of `∂κ/∂η`. + ## Main statements * `rnDeriv_compProd`: the Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(ν ⊗ₘ η)` equals the product of `∂μ/∂ν` and `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)`. * `rnDeriv_measure_compProd_left`: the Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(ν ⊗ₘ κ)` (with the same kernel) equals `∂μ/∂ν`. - -## TODO - -Under suitable assumptions to have Radon-Nikodym derivatives defined for kernels, we should give -equivalent statements with `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)` replaced by `∂κ/∂η`. +* `rnDeriv_measure_compProd`: the Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(ν ⊗ₘ η)` equals the + product of `∂μ/∂ν` and `∂κ/∂η`. +* `rnDeriv_measure_compProd_right`: the Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)` + (with the same measure) equals `∂κ/∂η`. -/ @@ -103,7 +106,11 @@ lemma rnDeriv_measure_compProd_left (μ ν : Measure α) (κ : Kernel α β) (Measure.rnDeriv_withDensity ν (by fun_prop)) /-- The Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(ν ⊗ₘ η)` equals the product of `∂μ/∂ν` and -`∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)`. -/ +`∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)`. + +See `rnDeriv_measure_compProd` for a version that replaces `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)` by `∂κ/∂η` +and does not require the absolute continuity hypothesis, assuming that `α` is countable or `β` is +countably generated. -/ lemma rnDeriv_compProd [IsFiniteMeasure μ] [IsFiniteKernel κ] [IsFiniteKernel η] (h_ac : μ ⊗ₘ κ ≪ μ ⊗ₘ η) (ν : Measure α) [IsFiniteMeasure ν] : (μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) =ᵐ[ν ⊗ₘ η] @@ -112,4 +119,46 @@ lemma rnDeriv_compProd [IsFiniteMeasure μ] [IsFiniteKernel κ] [IsFiniteKernel filter_upwards [rnDeriv_measure_compProd_left μ ν η] with p hp rw [Pi.mul_apply, hp, mul_comm] +section CountableOrCountablyGenerated + +variable [MeasurableSpace.CountableOrCountablyGenerated α β] + +/-- The Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(ν ⊗ₘ η)` equals the product of `∂μ/∂ν` and +`∂κ/∂η`. -/ +lemma rnDeriv_measure_compProd (μ ν : Measure α) (κ η : Kernel α β) + [IsFiniteMeasure μ] [IsFiniteMeasure ν] [IsFiniteKernel κ] [IsFiniteKernel η] : + (μ ⊗ₘ κ).rnDeriv (ν ⊗ₘ η) =ᵐ[ν ⊗ₘ η] fun p ↦ μ.rnDeriv ν p.1 * κ.rnDeriv η p.1 p.2 := by + have h_add : μ ⊗ₘ κ = μ ⊗ₘ κ.singularPart η + μ ⊗ₘ η.withDensity (κ.rnDeriv η) := by + conv_lhs => rw [← Kernel.rnDeriv_add_singularPart κ η] + rw [Measure.compProd_add_right, add_comm] + have h_sing : (μ ⊗ₘ κ.singularPart η).rnDeriv (ν ⊗ₘ η) =ᵐ[ν ⊗ₘ η] 0 := + Measure.rnDeriv_eq_zero_of_mutuallySingular + (Measure.MutuallySingular.compProd_of_right μ ν + (.of_forall <| Kernel.mutuallySingular_singularPart κ η)) .rfl + have h_ne_top : ∀ᵐ p ∂(μ ⊗ₘ η), κ.rnDeriv η p.1 p.2 ≠ ∞ := by + refine Measure.ae_compProd_of_ae_ae (p := fun p ↦ κ.rnDeriv η p.1 p.2 ≠ ∞) + (Kernel.measurable_rnDeriv κ η (measurableSet_singleton ∞)).compl ?_ + exact ae_of_all _ fun _ ↦ Kernel.rnDeriv_ne_top κ η + have h_wd : (μ ⊗ₘ η.withDensity (κ.rnDeriv η)).rnDeriv (ν ⊗ₘ η) + =ᵐ[ν ⊗ₘ η] fun p ↦ κ.rnDeriv η p.1 p.2 * (μ ⊗ₘ η).rnDeriv (ν ⊗ₘ η) p := by + rw [Measure.compProd_withDensity (Kernel.measurable_rnDeriv κ η)] + exact Measure.rnDeriv_withDensity_left (Kernel.measurable_rnDeriv κ η).aemeasurable h_ne_top + rw [h_add] + have h_add' := Measure.rnDeriv_add' (μ ⊗ₘ κ.singularPart η) + (μ ⊗ₘ η.withDensity (κ.rnDeriv η)) (ν ⊗ₘ η) + filter_upwards [h_add', h_sing, h_wd, rnDeriv_measure_compProd_left μ ν η] + with p h1 h2 h3 h4 + rw [h1, Pi.add_apply, h2, Pi.zero_apply, zero_add, h3, h4, mul_comm] + +/-- The Radon-Nikodym derivative `∂(μ ⊗ₘ κ)/∂(μ ⊗ₘ η)` (with the same measure) +equals `∂κ/∂η`. -/ +lemma rnDeriv_measure_compProd_right (μ : Measure α) (κ η : Kernel α β) + [IsFiniteMeasure μ] [IsFiniteKernel κ] [IsFiniteKernel η] : + (μ ⊗ₘ κ).rnDeriv (μ ⊗ₘ η) =ᵐ[μ ⊗ₘ η] fun p ↦ κ.rnDeriv η p.1 p.2 := by + filter_upwards [Measure.ae_compProd_of_ae_fst η (by measurability) μ.rnDeriv_self, + rnDeriv_measure_compProd μ μ κ η] + simp_all + +end CountableOrCountablyGenerated + end ProbabilityTheory From d0eb2622a28dcbd3131653ed336e6637582e794c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez=20Palacios?= Date: Tue, 11 Aug 2026 11:20:21 +0000 Subject: [PATCH 1278/1300] chore: fix all instances of `linter.defProp` (#42463) I've omitted the `MathlibTest` folder, since it's a bit difficult to tell which of those usages are intended. --- Mathlib/CategoryTheory/Category/Preorder.lean | 4 +--- Mathlib/Combinatorics/Hindman.lean | 23 ++++++++----------- Mathlib/Computability/Partrec.lean | 3 +-- Mathlib/Computability/Primrec/Basic.lean | 2 +- Mathlib/Data/Nat/Find.lean | 7 +++--- Mathlib/NumberTheory/Padics/Hensel.lean | 4 ++-- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/Mathlib/CategoryTheory/Category/Preorder.lean b/Mathlib/CategoryTheory/Category/Preorder.lean index 4f84c09560328b..8c0cf9dd5b2473 100644 --- a/Mathlib/CategoryTheory/Category/Preorder.lean +++ b/Mathlib/CategoryTheory/Category/Preorder.lean @@ -80,9 +80,7 @@ theorem homOfLE_comp {x y z : X} (h : x ≤ y) (k : y ≤ z) : theorem leOfHom {x y : X} (h : x ⟶ y) : x ≤ y := h.down.down -set_option linter.defProp false in -@[inherit_doc leOfHom] -abbrev _root_.Quiver.Hom.le := @leOfHom +alias _root_.Quiver.Hom.le := leOfHom @[simp] theorem homOfLE_leOfHom {x y : X} (h : x ⟶ y) : h.le.hom = h := diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index bf9a75e82362f4..5f044719705b0b 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -104,23 +104,20 @@ section Aliases /-! Since the constructors for `FS` and `FP` cheat using the `Set M = M → Prop` defeq, we provide match patterns that preserve the defeq correctly in their type. -/ -variable {M} [Semigroup M] (a : Stream' M) (m : M) (h : FP a.tail m) +variable {M} [Semigroup M] (a : Stream' M) (m : M) -set_option linter.defProp false in /-- Constructor for `FP`. This is the preferred spelling over `FP.head'`. -/ -@[to_additive (attr := match_pattern) - /-- Constructor for `FS`. This is the preferred spelling over `FS.head'`. -/] -abbrev FP.head : a.head ∈ FP a := FP.head' a -set_option linter.defProp false in +@[to_additive +/-- Constructor for `FS`. This is the preferred spelling over `FS.head'`. -/] +theorem FP.head : a.head ∈ FP a := FP.head' a /-- Constructor for `FP`. This is the preferred spelling over `FP.tail'`. -/ -@[to_additive (attr := match_pattern) - /-- Constructor for `FS`. This is the preferred spelling over `FS.tail'`. -/] -abbrev FP.tail : m ∈ FP a := FP.tail' a m h -set_option linter.defProp false in +@[to_additive +/-- Constructor for `FS`. This is the preferred spelling over `FS.tail'`. -/] +theorem FP.tail (h : FP a.tail m) : m ∈ FP a := FP.tail' a m h /-- Constructor for `FP`. This is the preferred spelling over `FP.cons'`. -/ -@[to_additive (attr := match_pattern) - /-- Constructor for `FS`. This is the preferred spelling over `FS.cons'`. -/] -abbrev FP.cons : a.head * m ∈ FP a := FP.cons' a m h +@[to_additive +/-- Constructor for `FS`. This is the preferred spelling over `FS.cons'`. -/] +theorem FP.cons (h : FP a.tail m) : a.head * m ∈ FP a := FP.cons' a m h end Aliases diff --git a/Mathlib/Computability/Partrec.lean b/Mathlib/Computability/Partrec.lean index 7d6f5466e870aa..f11518d5ac0b23 100644 --- a/Mathlib/Computability/Partrec.lean +++ b/Mathlib/Computability/Partrec.lean @@ -46,9 +46,8 @@ set_option backward.privateInPublic true in private def lbp (m n : ℕ) : Prop := m = n + 1 ∧ ∀ k ≤ n, false ∈ p k -set_option linter.defProp false in set_option backward.privateInPublic true in -private def wf_lbp (H : ∃ n, true ∈ p n ∧ ∀ k < n, (p k).Dom) : WellFounded (lbp p) := +private theorem wf_lbp (H : ∃ n, true ∈ p n ∧ ∀ k < n, (p k).Dom) : WellFounded (lbp p) := ⟨by let ⟨n, pn⟩ := H suffices ∀ m k, n ≤ k + m → Acc (lbp p) k by exact fun a => this _ _ (Nat.le_add_left _ _) diff --git a/Mathlib/Computability/Primrec/Basic.lean b/Mathlib/Computability/Primrec/Basic.lean index 70faf1d6eb86cd..a3ec0c5fcb829e 100644 --- a/Mathlib/Computability/Primrec/Basic.lean +++ b/Mathlib/Computability/Primrec/Basic.lean @@ -696,7 +696,7 @@ theorem nat_findGreatest {f : α → ℕ} {p : α → ℕ → Prop} [DecidableRe (nat_rec' (h := fun x nih => if p x (nih.1 + 1) then nih.1 + 1 else nih.2) hf (const 0) (ite (hp.comp fst (snd |> fst.comp |> succ.comp)) (snd |> fst.comp |> succ.comp) (snd.comp snd))).of_eq fun x => by - induction f x <;> simp [Nat.findGreatest, *] + induction f x <;> simp [Nat.findGreatest_succ, *] /-- To show a function `f : α → ℕ` is primitive recursive, it is enough to show that the function is bounded by a primitive recursive function and that its graph is primitive recursive -/ diff --git a/Mathlib/Data/Nat/Find.lean b/Mathlib/Data/Nat/Find.lean index 1a61e465b21bd9..3ccfa8155d3329 100644 --- a/Mathlib/Data/Nat/Find.lean +++ b/Mathlib/Data/Nat/Find.lean @@ -27,11 +27,8 @@ set_option backward.privateInPublic true in private def lbp (m n : ℕ) : Prop := m = n + 1 ∧ ∀ k ≤ n, ¬p k -variable [DecidablePred p] (H : ∃ n, p n) - -set_option linter.defProp false in set_option backward.privateInPublic true in -private def wf_lbp : WellFounded (@lbp p) := +private theorem wf_lbp (H : ∃ n, p n) : WellFounded (@lbp p) := ⟨let ⟨n, pn⟩ := H suffices ∀ m k, n ≤ k + m → Acc lbp k from fun _ => this _ _ (Nat.le_add_left _ _) fun m => @@ -45,6 +42,8 @@ private def wf_lbp : WellFounded (@lbp p) := match y, r with | _, ⟨rfl, _a⟩ => IH _ (by rw [Nat.add_right_comm]; exact kn)⟩⟩ +variable [DecidablePred p] (H : ∃ n, p n) + set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in /-- Find the smallest `n` satisfying `p n`. Returns a subtype. -/ diff --git a/Mathlib/NumberTheory/Padics/Hensel.lean b/Mathlib/NumberTheory/Padics/Hensel.lean index 01e13cb45fdcb2..ca6b9c603a7a41 100644 --- a/Mathlib/NumberTheory/Padics/Hensel.lean +++ b/Mathlib/NumberTheory/Padics/Hensel.lean @@ -228,8 +228,8 @@ private def calc_eval_z' {z z' z1 : ℤ_[p]} (hz' : z' = z - z1) {n} (hz : ih n _ = -F.aeval z := by simp only [mul_div_cancel₀ _ hdzne', Subtype.coe_eta] exact ⟨q, by simpa [sub_eq_add_neg, neg_mul_eq_mul_neg, this, hz'] using hq⟩ -set_option linter.defProp false in -private def calc_eval_z'_norm {z z' z1 : ℤ_[p]} {n} (hz : ih n z) {q} +omit hnorm in +private theorem calc_eval_z'_norm {z z' z1 : ℤ_[p]} {n} (hz : ih n z) {q} (heq : F.aeval z' = q * z1 ^ 2) (h1 : ‖(↑(F.aeval z) : ℚ_[p]) / ↑(F.derivative.aeval z)‖ ≤ 1) (hzeq : z1 = ⟨_, h1⟩) : ‖F.aeval z'‖ ≤ ‖F.derivative.aeval a‖ ^ 2 * T ^ 2 ^ (n + 1) := by From c7d00295fb7168a388c62e7d1e0f7c045bbdc5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 11:20:23 +0000 Subject: [PATCH 1279/1300] feat(CategoryTheory): more API for `IsoCat` (#42526) --- Mathlib/CategoryTheory/IsoCat.lean | 57 ++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/IsoCat.lean b/Mathlib/CategoryTheory/IsoCat.lean index 5912c5c4839c9f..c8519666e2b200 100644 --- a/Mathlib/CategoryTheory/IsoCat.lean +++ b/Mathlib/CategoryTheory/IsoCat.lean @@ -51,7 +51,7 @@ structure IsoCat where variable (C) in /-- The identity isomorphism of categories. -/ -@[simps, refl] +@[simps, refl, implicit_reducible] def IsoCat.refl : IsoCat C C where functor := 𝟭 C inverse := 𝟭 C @@ -59,7 +59,7 @@ def IsoCat.refl : IsoCat C C where counit_eq := Functor.comp_id _ /-- The inverse isomorphism of categories, obtained by swapping `functor` and `inverse`. -/ -@[simps, symm] +@[simps, symm, implicit_reducible] def IsoCat.symm (e : IsoCat C D) : IsoCat D C where functor := e.inverse inverse := e.functor @@ -67,7 +67,7 @@ def IsoCat.symm (e : IsoCat C D) : IsoCat D C where counit_eq := e.unit_eq.symm /-- Composition of isomorphisms of categories. -/ -@[simps, trans] +@[simps, trans, implicit_reducible] def IsoCat.trans (e : IsoCat C D) (f : IsoCat D E) : IsoCat C E where functor := e.functor ⋙ f.functor inverse := f.inverse ⋙ e.inverse @@ -78,6 +78,28 @@ def IsoCat.trans (e : IsoCat C D) (f : IsoCat D E) : IsoCat C E where rw [Functor.assoc, ← Functor.assoc e.inverse, e.counit_eq, Functor.id_comp] exact f.counit_eq +/-- The bijection on objects induced by an isomorphism of categories. -/ +@[simps, implicit_reducible] +def IsoCat.objEquiv (e : IsoCat C D) : C ≃ D where + toFun := e.functor.obj + invFun := e.inverse.obj + left_inv x := (Functor.congr_obj e.unit_eq x).symm + right_inv x := Functor.congr_obj e.counit_eq x + +lemma IsoCat.functor_comp_injective + (e : IsoCat C D) {F G : D ⥤ E} (h : e.functor ⋙ F = e.functor ⋙ G) : + F = G := by + have : (e.inverse ⋙ e.functor) ⋙ F = (e.inverse ⋙ e.functor) ⋙ G := by + simp only [Functor.assoc, h] + simpa [counit_eq, Functor.id_comp] using this + +lemma IsoCat.comp_functor_injective + (e : IsoCat C D) {F G : E ⥤ C} (h : F ⋙ e.functor = G ⋙ e.functor) : + F = G := by + have : F ⋙ e.functor ⋙ e.inverse = G ⋙ e.functor ⋙ e.inverse := by + simp [← Functor.assoc, h] + simpa only [← unit_eq, Functor.comp_id] using this + namespace Functor /-- A functor `F : C ⥤ D` is an isomorphism of categories if it is full, faithful and @@ -177,4 +199,33 @@ instance [F.IsIso] : F.strictInv.IsIso := F.asIsomorphism.symm.isIso_functor instance [F.IsIso] [G.IsIso] : (F ⋙ G).IsIso := (F.asIsomorphism.trans G.asIsomorphism).isIso_functor +section + +variable {C D : Type*} [Category* C] (e : D ≃ C) + +namespace InducedCategory + +/-- The isomorphism of categories between `InducedCategory C e` and `C` when +`e : D ≃ C` is a bijection. -/ +@[simps, implicit_reducible] +def isoCat : IsoCat (InducedCategory C e) C where + functor := inducedFunctor e + inverse.obj X := e.symm X + inverse.map f := { hom := eqToHom (by simp) ≫ f ≫ eqToHom (by simp) } + unit_eq := Functor.ext (by simp) (by cat_disch) + counit_eq := Functor.ext (by simp) (by cat_disch) + +/-- The equivalence of categories between `InducedCategory C e` and `C` when +`e : D ≃ C` is a bijection. -/ +abbrev equivalence : InducedCategory C e ≌ C := + (isoCat e).toEquivalence + +end InducedCategory + +lemma isIso_inducedFunctor_of_bijective (f : D → C) (hf : Function.Bijective f) : + (inducedFunctor f).IsIso := + inferInstanceAs (InducedCategory.isoCat (.ofBijective f hf)).functor.IsIso + +end + end CategoryTheory From 52ee81cb4dd6dbff1efadef57cebd9ea50cc76bf Mon Sep 17 00:00:00 2001 From: Jeremy Tan Jie Rui <54175463+Parcly-Taxel@users.noreply.github.com> Date: Tue, 11 Aug 2026 12:14:45 +0000 Subject: [PATCH 1280/1300] chore: delete deprecated declarations/modules from January 2026 (#42075) `Mathlib.Util.MemoFix` is directly removed since all deprecations in it are more than 6 months old. Co-authored-by: Parcly Taxel --- Mathlib.lean | 16 - Mathlib/Algebra/Algebra/Basic.lean | 6 - Mathlib/Algebra/Algebra/Epi.lean | 4 - .../Algebra/Algebra/NonUnitalSubalgebra.lean | 4 - Mathlib/Algebra/BigOperators/Finprod.lean | 8 - Mathlib/Algebra/Category/ModuleCat/Semi.lean | 4 - Mathlib/Algebra/Category/Ring/Epi.lean | 3 - Mathlib/Algebra/Group/Basic.lean | 10 - Mathlib/Algebra/Group/Int/Defs.lean | 6 - .../Algebra/GroupWithZero/Action/Defs.lean | 5 - Mathlib/Algebra/GroupWithZero/Basic.lean | 6 - Mathlib/Algebra/GroupWithZero/Defs.lean | 12 - Mathlib/Algebra/GroupWithZero/Int.lean | 6 - .../GroupWithZero/NonZeroDivisors.lean | 10 - Mathlib/Algebra/GroupWithZero/Regular.lean | 2 - Mathlib/Algebra/ModEq.lean | 8 - Mathlib/Algebra/Module/Hom.lean | 7 - Mathlib/Algebra/Module/LinearMap/End.lean | 2 - Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean | 11 - .../Algebra/Order/Archimedean/Real/Basic.lean | 4 - .../Polynomial/Degree/Definitions.lean | 10 - Mathlib/Algebra/Polynomial/Splits.lean | 21 - Mathlib/Algebra/Ring/Regular.lean | 2 - Mathlib/AlgebraicGeometry/Artinian.lean | 3 - .../Cover/MorphismProperty.lean | 18 - .../Morphisms/ClosedImmersion.lean | 3 - .../Morphisms/FinitePresentation.lean | 4 - .../Morphisms/FiniteType.lean | 4 - Mathlib/AlgebraicGeometry/Morphisms/Flat.lean | 2 - .../Morphisms/FormallyUnramified.lean | 3 - .../Morphisms/OpenImmersion.lean | 3 - .../Morphisms/Preimmersion.lean | 2 - .../Morphisms/Separated.lean | 5 +- .../Morphisms/SurjectiveOnStalks.lean | 3 - .../Morphisms/UniversallyClosed.lean | 3 - .../Morphisms/UniversallyOpen.lean | 3 - .../FundamentalGroupoid/SimplyConnected.lean | 3 - .../CofibrantObjectHomotopy.lean | 3 - Mathlib/Analysis/Analytic/Composition.lean | 2 - .../Asymptotics/AsymptoticEquivalent.lean | 3 - Mathlib/Analysis/Calculus/Deriv/Mul.lean | 10 - Mathlib/Analysis/Calculus/FDeriv/Add.lean | 5 - Mathlib/Analysis/Calculus/Implicit.lean | 12 - .../Analysis/Calculus/ImplicitContDiff.lean | 29 - .../Analysis/Calculus/TangentCone/Basic.lean | 3 - Mathlib/Analysis/Complex/IntegerCompl.lean | 6 - Mathlib/Analysis/Complex/Schwarz.lean | 10 - Mathlib/Analysis/Complex/TaylorSeries.lean | 9 - Mathlib/Analysis/Complex/UnitDisc/Basic.lean | 28 - .../Complex/UpperHalfPlane/Basic.lean | 14 - Mathlib/Analysis/Convex/Body.lean | 6 - .../Distribution/FourierSchwartz.lean | 7 - .../Analysis/Distribution/SchwartzSpace.lean | 5 - .../Distribution/SchwartzSpace/Fourier.lean | 9 - .../Distribution/TemperedDistribution.lean | 24 - Mathlib/Analysis/Fourier/Notation.lean | 14 - .../InnerProductSpace/Orthogonal.lean | 4 - Mathlib/Analysis/InnerProductSpace/PiL2.lean | 33 - Mathlib/Analysis/LocallyConvex/Barrelled.lean | 23 - Mathlib/Analysis/Matrix/Spectrum.lean | 5 - Mathlib/Analysis/Normed/Group/Basic.lean | 6 - Mathlib/Analysis/Normed/Group/Pointwise.lean | 13 - .../Normed/Module/Ball/Pointwise.lean | 8 - Mathlib/Analysis/Normed/Order/Basic.lean | 17 - .../Normed/Unbundled/SeminormFromConst.lean | 3 - .../Analysis/Polynomial/MahlerMeasure.lean | 3 - Mathlib/Analysis/Real/Hyperreal.lean | 694 ------------------ .../SpecialFunctions/Complex/Log.lean | 3 - .../SpecialFunctions/NonIntegrable.lean | 4 - .../Trigonometric/Cotangent.lean | 2 - .../CategoryTheory/Adjunction/Opposites.lean | 15 - Mathlib/CategoryTheory/Category/Grpd.lean | 10 - .../Limits/Shapes/Products.lean | 5 - .../Limits/Shapes/Pullback/CommSq.lean | 20 - .../Limits/Shapes/Pullback/Equifibered.lean | 5 - .../MorphismProperty/Basic.lean | 3 - Mathlib/CategoryTheory/Sites/IsSheafFor.lean | 3 - .../Triangulated/TStructure/Basic.lean | 3 - .../Combinatorics/SimpleGraph/AdjMatrix.lean | 3 - .../SimpleGraph/Coloring/Vertex.lean | 3 - .../SimpleGraph/VertexCover.lean | 5 - Mathlib/Computability/Primrec.lean | 10 - Mathlib/Computability/Primrec/Basic.lean | 4 - Mathlib/Data/Finsupp/Basic.lean | 2 - Mathlib/Data/Fintype/Prod.lean | 3 - Mathlib/Data/Int/ModEq.lean | 3 - Mathlib/Data/List/Basic.lean | 8 - Mathlib/Data/List/Flatten.lean | 6 - Mathlib/Data/List/GetD.lean | 4 - Mathlib/Data/Option/Basic.lean | 12 - Mathlib/Data/Option/Defs.lean | 11 - Mathlib/Data/Set/Card.lean | 2 - Mathlib/Data/SetLike/Basic.lean | 2 - Mathlib/Data/Tree/RBMap.lean | 5 - Mathlib/FieldTheory/Isaacs.lean | 6 - .../Geometry/Manifold/PartitionOfUnity.lean | 4 - .../Geometry/Manifold/Riemannian/Basic.lean | 6 - Mathlib/Lean/Expr.lean | 10 - Mathlib/Lean/Expr/ReplaceRec.lean | 41 -- .../AffineSpace/AffineSubspace/Basic.lean | 4 - .../BilinearForm/Properties.lean | 2 - Mathlib/LinearAlgebra/BilinearMap.lean | 3 - Mathlib/LinearAlgebra/DirectSum/Finsupp.lean | 13 - Mathlib/LinearAlgebra/Finsupp/Defs.lean | 5 - Mathlib/LinearAlgebra/Lagrange.lean | 5 - .../LinearAlgebra/Matrix/BilinearForm.lean | 50 -- .../LinearAlgebra/QuadraticForm/Complex.lean | 35 - Mathlib/Logic/Basic.lean | 9 - Mathlib/Logic/Encodable/Basic.lean | 5 - Mathlib/Logic/Relation.lean | 2 - .../Constructions/BorelSpace/Metric.lean | 6 - .../Function/L1Space/HasFiniteIntegral.lean | 7 - .../MeasureTheory/MeasurableSpace/Defs.lean | 2 - .../MeasureTheory/Measure/Lebesgue/Basic.lean | 6 - Mathlib/MeasureTheory/Measure/OpenPos.lean | 6 - .../ModularForms/SlashActions.lean | 7 - Mathlib/Order/Antichain.lean | 2 - Mathlib/Order/Bounds/Basic.lean | 8 - Mathlib/Order/Comparable.lean | 147 ---- Mathlib/Order/Defs/Unbundled.lean | 36 - Mathlib/Order/Notation.lean | 9 - Mathlib/Order/PiLex.lean | 2 - Mathlib/Order/RelClasses.lean | 15 - Mathlib/Order/RelIso/Basic.lean | 18 - Mathlib/Order/WellFounded.lean | 4 - Mathlib/Probability/Moments/SubGaussian.lean | 11 - Mathlib/Probability/Process/HittingTime.lean | 9 - Mathlib/Probability/Process/Predictable.lean | 9 - Mathlib/Probability/UniformOn.lean | 3 - .../DedekindDomain/AdicValuation.lean | 5 - Mathlib/RingTheory/Filtration.lean | 4 - Mathlib/RingTheory/Finiteness/Basic.lean | 3 - Mathlib/RingTheory/HahnSeries/Basic.lean | 27 - .../RingTheory/HahnSeries/Multiplication.lean | 9 - Mathlib/RingTheory/Ideal/Colon.lean | 8 - Mathlib/RingTheory/Ideal/IsPrimary.lean | 3 - Mathlib/RingTheory/Ideal/Prime.lean | 3 - Mathlib/RingTheory/Kaehler/TensorProduct.lean | 2 - .../RingTheory/KrullDimension/Regular.lean | 14 - Mathlib/RingTheory/Lasker.lean | 27 - Mathlib/RingTheory/MvPowerSeries/Order.lean | 3 - Mathlib/RingTheory/Nakayama.lean | 4 - .../RingTheory/OreLocalization/OreSet.lean | 2 - Mathlib/RingTheory/Polynomial/IsIntegral.lean | 5 - .../RingTheory/Smooth/NoetherianDescent.lean | 7 - Mathlib/RingTheory/Valuation/Basic.lean | 4 - .../Valuation/ValuativeRel/Basic.lean | 14 - Mathlib/SetTheory/Cardinal/Basic.lean | 15 - Mathlib/SetTheory/Cardinal/ENat.lean | 4 - Mathlib/SetTheory/Cardinal/Ordinal.lean | 6 - Mathlib/SetTheory/Cardinal/Pigeonhole.lean | 3 - .../SetTheory/Ordinal/CantorNormalForm.lean | 9 - Mathlib/SetTheory/Ordinal/Exponential.lean | 4 - Mathlib/SetTheory/Ordinal/Topology.lean | 16 - Mathlib/SetTheory/ZFC/Ordinal.lean | 5 - Mathlib/Tactic.lean | 1 - Mathlib/Tactic/Linter/CommandStart.lean | 5 - Mathlib/Tactic/Linter/Whitespace.lean | 7 - .../Module/Spaces/CompactConvergenceCLM.lean | 12 - .../Module/Spaces/UniformConvergenceCLM.lean | 12 - Mathlib/Topology/Algebra/Valued/WithVal.lean | 28 - Mathlib/Topology/Compactness/Lindelof.lean | 12 - Mathlib/Topology/EMetricSpace/Defs.lean | 72 -- Mathlib/Topology/EMetricSpace/Diam.lean | 32 - Mathlib/Topology/EMetricSpace/Lipschitz.lean | 6 - .../Topology/EMetricSpace/Paracompact.lean | 3 - .../Topology/Instances/AddCircle/Defs.lean | 6 - .../Topology/Instances/ENNReal/Lemmas.lean | 7 - Mathlib/Topology/Instances/NNReal/Lemmas.lean | 23 - Mathlib/Topology/MetricSpace/Closeds.lean | 54 -- Mathlib/Topology/MetricSpace/Dilation.lean | 6 - .../MetricSpace/HausdorffDistance.lean | 121 --- .../Topology/MetricSpace/IsometricSMul.lean | 52 -- Mathlib/Topology/MetricSpace/Isometry.lean | 24 - .../MetricSpace/PartitionOfUnity.lean | 27 - Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 15 - Mathlib/Topology/MetricSpace/Snowflaking.lean | 24 - .../MetricSpace/ThickenedIndicator.lean | 6 - Mathlib/Topology/MetricSpace/Thickening.lean | 23 - Mathlib/Topology/Order.lean | 14 - Mathlib/Topology/Order/DenselyOrdered.lean | 2 - .../Topology/Order/MonotoneConvergence.lean | 4 - Mathlib/Util/MemoFix.lean | 39 - MathlibTest/Linter/Whitespace.lean | 20 - 184 files changed, 1 insertion(+), 2759 deletions(-) delete mode 100644 Mathlib/Algebra/GroupWithZero/Int.lean delete mode 100644 Mathlib/Algebra/ModEq.lean delete mode 100644 Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean delete mode 100644 Mathlib/Algebra/Polynomial/Degree/Definitions.lean delete mode 100644 Mathlib/Analysis/Distribution/FourierSchwartz.lean delete mode 100644 Mathlib/Analysis/Distribution/SchwartzSpace.lean delete mode 100644 Mathlib/Analysis/Normed/Order/Basic.lean delete mode 100644 Mathlib/CategoryTheory/Category/Grpd.lean delete mode 100644 Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean delete mode 100644 Mathlib/Computability/Primrec.lean delete mode 100644 Mathlib/Data/Tree/RBMap.lean delete mode 100644 Mathlib/Lean/Expr.lean delete mode 100644 Mathlib/Lean/Expr/ReplaceRec.lean delete mode 100644 Mathlib/LinearAlgebra/QuadraticForm/Complex.lean delete mode 100644 Mathlib/Tactic/Linter/CommandStart.lean delete mode 100644 Mathlib/Util/MemoFix.lean diff --git a/Mathlib.lean b/Mathlib.lean index faf12e5137a99b..f374c965bc3eb4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -530,7 +530,6 @@ public import Mathlib.Algebra.GroupWithZero.Hom public import Mathlib.Algebra.GroupWithZero.Idempotent public import Mathlib.Algebra.GroupWithZero.Indicator public import Mathlib.Algebra.GroupWithZero.InjSurj -public import Mathlib.Algebra.GroupWithZero.Int public import Mathlib.Algebra.GroupWithZero.Invertible public import Mathlib.Algebra.GroupWithZero.Nat public import Mathlib.Algebra.GroupWithZero.NeZero @@ -777,7 +776,6 @@ public import Mathlib.Algebra.Lie.Weights.RootSystem public import Mathlib.Algebra.LieRinehartAlgebra.Defs public import Mathlib.Algebra.LieRinehartAlgebra.Subalgebra public import Mathlib.Algebra.LinearRecurrence -public import Mathlib.Algebra.ModEq public import Mathlib.Algebra.Module.Basic public import Mathlib.Algebra.Module.BigOperators public import Mathlib.Algebra.Module.Bimodule @@ -909,7 +907,6 @@ public import Mathlib.Algebra.NeZero public import Mathlib.Algebra.NoZeroSMulDivisors.Basic public import Mathlib.Algebra.NoZeroSMulDivisors.Defs public import Mathlib.Algebra.NoZeroSMulDivisors.Pi -public import Mathlib.Algebra.NoZeroSMulDivisors.Prod public import Mathlib.Algebra.NonAssoc.LieAdmissible.Defs public import Mathlib.Algebra.NonAssoc.PreLie.Basic public import Mathlib.Algebra.Notation @@ -1153,7 +1150,6 @@ public import Mathlib.Algebra.Polynomial.Coeff public import Mathlib.Algebra.Polynomial.CoeffList public import Mathlib.Algebra.Polynomial.CoeffMem public import Mathlib.Algebra.Polynomial.Degree.CardPowDegree -public import Mathlib.Algebra.Polynomial.Degree.Definitions public import Mathlib.Algebra.Polynomial.Degree.Defs public import Mathlib.Algebra.Polynomial.Degree.Domain public import Mathlib.Algebra.Polynomial.Degree.IsMonicOfDegree @@ -2010,8 +2006,6 @@ public import Mathlib.Analysis.Distribution.ContDiffMapSupportedIn public import Mathlib.Analysis.Distribution.DerivNotation public import Mathlib.Analysis.Distribution.Distribution public import Mathlib.Analysis.Distribution.FourierMultiplier -public import Mathlib.Analysis.Distribution.FourierSchwartz -public import Mathlib.Analysis.Distribution.SchwartzSpace public import Mathlib.Analysis.Distribution.SchwartzSpace.Basic public import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv public import Mathlib.Analysis.Distribution.SchwartzSpace.Fourier @@ -2267,7 +2261,6 @@ public import Mathlib.Analysis.Normed.Operator.NNNorm public import Mathlib.Analysis.Normed.Operator.NormedSpace public import Mathlib.Analysis.Normed.Operator.Perturbation.StrictByFinite public import Mathlib.Analysis.Normed.Operator.Prod -public import Mathlib.Analysis.Normed.Order.Basic public import Mathlib.Analysis.Normed.Order.Hom.Basic public import Mathlib.Analysis.Normed.Order.Hom.Ultra public import Mathlib.Analysis.Normed.Order.Lattice @@ -2594,7 +2587,6 @@ public import Mathlib.CategoryTheory.Category.Cat.Op public import Mathlib.CategoryTheory.Category.Cat.Terminal public import Mathlib.CategoryTheory.Category.Factorisation public import Mathlib.CategoryTheory.Category.GaloisConnection -public import Mathlib.CategoryTheory.Category.Grpd public import Mathlib.CategoryTheory.Category.Init public import Mathlib.CategoryTheory.Category.KleisliCat public import Mathlib.CategoryTheory.Category.Pairwise @@ -2963,7 +2955,6 @@ public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Assoc public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Categorical.Basic public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Categorical.CatCospanTransform public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.ChosenPullback -public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.CommSq public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Connected public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Cospan public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Equalizer @@ -3752,7 +3743,6 @@ public import Mathlib.Computability.Partrec public import Mathlib.Computability.PartrecBasis public import Mathlib.Computability.PartrecCode public import Mathlib.Computability.PostTuringMachine -public import Mathlib.Computability.Primrec public import Mathlib.Computability.Primrec.Basic public import Mathlib.Computability.Primrec.List public import Mathlib.Computability.RE @@ -4450,7 +4440,6 @@ public import Mathlib.Data.Sym.Sym2.Init public import Mathlib.Data.Sym.Sym2.Order public import Mathlib.Data.Tree.Basic public import Mathlib.Data.Tree.Get -public import Mathlib.Data.Tree.RBMap public import Mathlib.Data.Tree.Traversable public import Mathlib.Data.TwoPointing public import Mathlib.Data.TypeVec @@ -4926,11 +4915,9 @@ public import Mathlib.Lean.Elab.Term public import Mathlib.Lean.EnvExtension public import Mathlib.Lean.Environment public import Mathlib.Lean.Exception -public import Mathlib.Lean.Expr public import Mathlib.Lean.Expr.Basic public import Mathlib.Lean.Expr.ExtraRecognizers public import Mathlib.Lean.Expr.Rat -public import Mathlib.Lean.Expr.ReplaceRec public import Mathlib.Lean.FoldEnvironment public import Mathlib.Lean.GoalsLocation public import Mathlib.Lean.Json @@ -5233,7 +5220,6 @@ public import Mathlib.LinearAlgebra.Projectivization.Subspace public import Mathlib.LinearAlgebra.QuadraticForm.AlgClosed public import Mathlib.LinearAlgebra.QuadraticForm.Basic public import Mathlib.LinearAlgebra.QuadraticForm.Basis -public import Mathlib.LinearAlgebra.QuadraticForm.Complex public import Mathlib.LinearAlgebra.QuadraticForm.Dual public import Mathlib.LinearAlgebra.QuadraticForm.Isometry public import Mathlib.LinearAlgebra.QuadraticForm.IsometryEquiv @@ -7424,7 +7410,6 @@ public import Mathlib.Tactic.LinearCombinationPrime public import Mathlib.Tactic.Linter public import Mathlib.Tactic.Linter.AuxLemma public import Mathlib.Tactic.Linter.CommandRanges -public import Mathlib.Tactic.Linter.CommandStart public import Mathlib.Tactic.Linter.DeprecatedModule public import Mathlib.Tactic.Linter.DeprecatedSyntaxLinter public import Mathlib.Tactic.Linter.DirectoryDependency @@ -8302,7 +8287,6 @@ public import Mathlib.Util.Export public import Mathlib.Util.FormatTable public import Mathlib.Util.GetAllModules public import Mathlib.Util.LongNames -public import Mathlib.Util.MemoFix public import Mathlib.Util.Notation3 public import Mathlib.Util.PPOptions public import Mathlib.Util.ParseCommand diff --git a/Mathlib/Algebra/Algebra/Basic.lean b/Mathlib/Algebra/Algebra/Basic.lean index 81ec13d6fbf7c0..2a893c91bfbb7c 100644 --- a/Mathlib/Algebra/Algebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Basic.lean @@ -488,12 +488,6 @@ lemma isTorsionFree_iff_algebraMap_injective : IsTorsionFree R A ↔ Injective ( end Module -@[deprecated (since := "2026-01-21")] -alias NoZeroSMulDivisors.iff_algebraMap_injective := isTorsionFree_iff_algebraMap_injective - -@[deprecated (since := "2026-01-21")] -alias NoZeroSMulDivisors.iff_faithfulSMul := isTorsionFree_iff_faithfulSMul - example {R A} [CommSemiring R] [Semiring A] [Module R A] [SMulCommClass R A A] [IsScalarTower R A A] : Algebra R A := Algebra.ofModule smul_mul_assoc mul_smul_comm diff --git a/Mathlib/Algebra/Algebra/Epi.lean b/Mathlib/Algebra/Algebra/Epi.lean index 8e114e11a53858..afc836df37b759 100644 --- a/Mathlib/Algebra/Algebra/Epi.lean +++ b/Mathlib/Algebra/Algebra/Epi.lean @@ -99,10 +99,6 @@ lemma isEpi_iff_surjective_algebraMap_of_finite [Module.Finite R A] : rw [← map_tmul R'.mkQ R'.mkQ, ← hs, map_tmul, this, zero_tmul] cases false_of_nontrivial_of_subsingleton ((A ⧸ R') ⊗[R] (A ⧸ R')) -@[deprecated (since := "2026-01-13")] -alias _root_.RingHom.surjective_of_tmul_eq_tmul_of_finite := - isEpi_iff_surjective_algebraMap_of_finite - end Ring section CommSemiring diff --git a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index 47b6fce6df8a09..53240160fff965 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean @@ -724,8 +724,6 @@ theorem toNonUnitalSubring_top {R A : Type*} [CommRing R] [NonUnitalNonAssocRing (⊤ : NonUnitalSubalgebra R A).toNonUnitalSubring = ⊤ := rfl -@[deprecated (since := "2026-01-03")] alias top_toSubring := toNonUnitalSubring_top - @[simp] lemma toNonUnitalSubsemiring_eq_top {S : NonUnitalSubalgebra R A} : S.toNonUnitalSubsemiring = ⊤ ↔ S = ⊤ := by simp [← SetLike.coe_set_eq] @@ -737,8 +735,6 @@ theorem toNonUnitalSubring_eq_top {R A : Type*} [CommRing R] [Ring A] [Algebra R {S : NonUnitalSubalgebra R A} : S.toNonUnitalSubring = ⊤ ↔ S = ⊤ := by simp [← SetLike.coe_set_eq] -@[deprecated (since := "2026-01-01")] alias to_subring_eq_top := toNonUnitalSubring_eq_top - theorem mem_sup_left {S T : NonUnitalSubalgebra R A} : ∀ {x : A}, x ∈ S → x ∈ S ⊔ T := by rw [← SetLike.le_def] exact le_sup_left diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index 13b5ef3fd8716b..97b7d39861e449 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -592,8 +592,6 @@ theorem one_lt_finprod_cond {M : Type*} [CommMonoid M] [PartialOrder M] [IsOrder · aesop · simp +contextual -@[deprecated (since := "2026-01-06")] alias finprod_cond_pos := finsum_cond_pos - @[to_additive finsum_pos] theorem one_lt_finprod {M : Type*} [CommMonoid M] [PartialOrder M] [IsOrderedCancelMonoid M] {f : ι → M} @@ -601,12 +599,6 @@ theorem one_lt_finprod {M : Type*} [CommMonoid M] [PartialOrder M] [IsOrderedCan rw [← finprod_mem_univ] apply one_lt_finprod_cond <;> simpa -@[deprecated (since := "2026-01-03")] -alias finsum_pos' := finsum_pos - -@[to_additive existing finsum_pos', deprecated (since := "2026-01-03")] -alias one_lt_finprod' := one_lt_finprod - /-- Monotonicity of `finprod`. See `finprod_le_finprod` for a variant where `M` is a `CommMonoidWithZero`. -/ @[to_additive /-- Monotonicity of `finsum.` -/] diff --git a/Mathlib/Algebra/Category/ModuleCat/Semi.lean b/Mathlib/Algebra/Category/ModuleCat/Semi.lean index d2a9e36b3f0b69..b9c873404061cf 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Semi.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Semi.lean @@ -299,10 +299,6 @@ instance : SMul ℕ (M ⟶ N) where @[simp] lemma hom_nsmul (n : ℕ) (f : M ⟶ N) : (n • f).hom = n • f.hom := rfl --- There is no `ℤ`-smul operation on a general semimodule! -@[deprecated (since := "2026-01-06")] -alias hom_zsmul := hom_nsmul - instance : AddCommMonoid (M ⟶ N) := Function.Injective.addCommMonoid Hom.hom hom_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) diff --git a/Mathlib/Algebra/Category/Ring/Epi.lean b/Mathlib/Algebra/Category/Ring/Epi.lean index fbd4bf461dadf5..2ac291d0a14157 100644 --- a/Mathlib/Algebra/Category/Ring/Epi.lean +++ b/Mathlib/Algebra/Category/Ring/Epi.lean @@ -40,9 +40,6 @@ lemma CommRingCat.epi_iff_epi {R S : Type u} [CommRing R] [CommRing S] [Algebra ext s simpa using! congr(Algebra.TensorProduct.lift f' g' (fun _ _ ↦ .all _ _) $(H s)) -@[deprecated (since := "2026-01-13")] -alias CommRingCat.epi_iff_tmul_eq_tmul := CommRingCat.epi_iff_epi - lemma RingHom.surjective_of_epi_of_finite {R S : CommRingCat} (f : R ⟶ S) [Epi f] (h₂ : RingHom.Finite f.hom) : Function.Surjective f := by algebraize [f.hom] diff --git a/Mathlib/Algebra/Group/Basic.lean b/Mathlib/Algebra/Group/Basic.lean index c28a5efa016538..0f66eb663813a6 100644 --- a/Mathlib/Algebra/Group/Basic.lean +++ b/Mathlib/Algebra/Group/Basic.lean @@ -1028,11 +1028,6 @@ alias additive_of_symmetric_of_total := additive_of_symm_of_total @[to_additive existing additive_of_symmetric_of_total, deprecated (since := "2026-06-10")] alias multiplicative_of_symmetric_of_total := multiplicative_of_symm_of_total -@[deprecated (since := "2026-01-09")] -alias additive_of_symmetric_of_isTotal := additive_of_symm_of_total -@[to_additive existing additive_of_symmetric_of_isTotal, deprecated (since := "2026-01-09")] -alias multiplicative_of_symmetric_of_isTotal := multiplicative_of_symm_of_total - /-- If a binary function from a type equipped with a total relation `r` to a monoid is anti-symmetric (i.e. satisfies `f a b * f b a = 1`), in order to show it is multiplicative (i.e. satisfies `f a c = f a b * f b c`), we may assume `r a b` and `r b c` are satisfied. @@ -1050,11 +1045,6 @@ theorem multiplicative_of_total (p : α → Prop) (hswap : ∀ {a b}, p a → p · exact fun rab rbc pab _pbc pac => hmul rab rbc pab.1 pab.2 pac.2 exacts [⟨pa, pb⟩, ⟨pb, pc⟩, ⟨pa, pc⟩] -@[deprecated (since := "2026-01-09")] -alias additive_of_isTotal := additive_of_total -@[to_additive existing additive_of_isTotal, deprecated (since := "2026-01-09")] -alias multiplicative_of_isTotal := multiplicative_of_total - end multiplicative /-- An auxiliary lemma that can be used to prove `⇑(f ^ n) = ⇑f^[n]`. -/ diff --git a/Mathlib/Algebra/Group/Int/Defs.lean b/Mathlib/Algebra/Group/Int/Defs.lean index 9e06bbccfe336d..abacc277735e4f 100644 --- a/Mathlib/Algebra/Group/Int/Defs.lean +++ b/Mathlib/Algebra/Group/Int/Defs.lean @@ -86,9 +86,3 @@ end @[simp high] protected lemma zsmul_eq_mul (n a : ℤ) : n • a = n * a := rfl end Int - -@[deprecated "use `zsmul_eq_mul`" (since := "2026-01-05")] -lemma zsmul_int_int (a b : ℤ) : a • b = a * b := rfl - -@[deprecated "use `zsmul_one`" (since := "2026-01-05")] -lemma zsmul_int_one (n : ℤ) : n • (1 : ℤ) = n := mul_one _ diff --git a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean index 25971ff5f2c0f1..696759ce00b04e 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean @@ -380,11 +380,6 @@ protected abbrev Function.Surjective.distribMulAction [AddMonoid B] [SMul M B] ( variable (A) -/-- Each element of the monoid defines an additive monoid homomorphism. -/ -@[simps!, deprecated DistribSMul.toAddMonoidHom (since := "2026-01-07")] -def DistribMulAction.toAddMonoidHom (x : M) : A →+ A := - DistribSMul.toAddMonoidHom A x - variable (M) /-- Each element of the monoid defines an additive monoid homomorphism. -/ diff --git a/Mathlib/Algebra/GroupWithZero/Basic.lean b/Mathlib/Algebra/GroupWithZero/Basic.lean index b645df61d0cab8..f876aa13480b36 100644 --- a/Mathlib/Algebra/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Basic.lean @@ -265,12 +265,6 @@ lemma sq_eq_zero_iff : a ^ 2 = 0 ↔ a = 0 := pow_eq_zero_iff two_ne_zero @[simp] lemma pow_eq_zero_iff' [Nontrivial M₀] : a ^ n = 0 ↔ a = 0 ∧ n ≠ 0 := by obtain rfl | hn := eq_or_ne n 0 <;> simp [*] -@[deprecated (since := "2026-01-08")] alias IsReduced.pow_eq_zero := eq_zero_of_pow_eq_zero -@[deprecated (since := "2026-01-08")] alias IsReduced.pow_eq_zero_iff := pow_eq_zero_iff -@[deprecated (since := "2026-01-08")] alias IsReduced.pow_ne_zero_iff := pow_ne_zero_iff -@[deprecated (since := "2026-01-08")] alias IsReduced.pow_ne_zero := pow_ne_zero -@[deprecated (since := "2026-01-08")] alias IsReduced.pow_eq_zero_iff' := pow_eq_zero_iff' - theorem exists_right_inv_of_exists_left_inv {α} [MonoidWithZero α] (h : ∀ a : α, a ≠ 0 → ∃ b : α, b * a = 1) {a : α} (ha : a ≠ 0) : ∃ b : α, a * b = 1 := by obtain _ | _ := subsingleton_or_nontrivial α diff --git a/Mathlib/Algebra/GroupWithZero/Defs.lean b/Mathlib/Algebra/GroupWithZero/Defs.lean index 0845c14350e2d6..271841a926c122 100644 --- a/Mathlib/Algebra/GroupWithZero/Defs.lean +++ b/Mathlib/Algebra/GroupWithZero/Defs.lean @@ -137,11 +137,6 @@ theorem pow_mul_apply_eq_pow_mul {M : Type*} [Monoid M] (f : M₀ → M) {x : M end MonoidWithZero -/-- A type `M` is a `CancelMonoidWithZero` if it is a monoid with zero element, `0` is left -and right absorbing, and left/right multiplication by a non-zero element is injective. -/ -@[deprecated "Use `[MonoidWithZero M₀] [IsCancelMulZero M₀].`" (since := "2026-01-11")] -structure CancelMonoidWithZero (M₀ : Type*) extends MonoidWithZero M₀, IsCancelMulZero M₀ - /-- A type `M` is a commutative “monoid with zero” if it is a commutative monoid with zero element, and `0` is left and right absorbing. -/ class CommMonoidWithZero (M₀ : Type*) extends CommMonoid M₀, MonoidWithZero M₀ @@ -188,13 +183,6 @@ lemma IsRightCancelMulZero.to_isCancelMulZero [IsRightCancelMulZero M₀] : end CommMagma -/-- A type `M` is a `CancelCommMonoidWithZero` if it is a commutative monoid with zero element, -`0` is left and right absorbing, -and left/right multiplication by a non-zero element is injective. -/ -@[deprecated "Use `[CommMonoidWithZero M₀] [IsCancelMulZero M₀].`" (since := "2026-01-11")] -structure CancelCommMonoidWithZero (M₀ : Type*) - extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀ - /-- Prop-valued mixin for a monoid with zero to be equipped with a cancelling division. The obvious use case is groups with zero, but this condition is also satisfied by `ℕ`, `ℤ` and, more diff --git a/Mathlib/Algebra/GroupWithZero/Int.lean b/Mathlib/Algebra/GroupWithZero/Int.lean deleted file mode 100644 index 4dbf0d0605be5f..00000000000000 --- a/Mathlib/Algebra/GroupWithZero/Int.lean +++ /dev/null @@ -1,6 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Tactic.Common -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2026-01-01") diff --git a/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean b/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean index 66fd240db88eae..38d39ec7ab1c2d 100644 --- a/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean +++ b/Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean @@ -153,16 +153,6 @@ lemma IsUnit.mem_nonZeroDivisors (hx : IsUnit x) : x ∈ M₀⁰ := variable (M₀) in lemma isUnit_le_nonZeroDivisors : IsUnit.submonoid M₀ ≤ M₀⁰ := fun _ ↦ (·.mem_nonZeroDivisors) -@[deprecated "Use `Submonoid.mul_mem _ hx hy` instead." (since := "2026-01-07")] -lemma mul_mem_nonZeroDivisorsLeft_of_mem_nonZeroDivisorsLeft (hx : x ∈ nonZeroDivisorsLeft M₀) - (hy : y ∈ nonZeroDivisorsLeft M₀) : - x * y ∈ nonZeroDivisorsLeft M₀ := Submonoid.mul_mem _ hx hy - -@[deprecated "Use `Submonoid.mul_mem _ hx hy` instead." (since := "2026-01-07")] -lemma mul_mem_nonZeroDivisorsRight_of_mem_nonZeroDivisorsRight (hx : x ∈ nonZeroDivisorsRight M₀) - (hy : y ∈ nonZeroDivisorsRight M₀) : - x * y ∈ nonZeroDivisorsRight M₀ := Submonoid.mul_mem _ hx hy - lemma mul_mem_nonZeroDivisors_of_mem_nonZeroDivisors (hx : x ∈ M₀⁰) (hy : y ∈ M₀⁰) : x * y ∈ M₀⁰ := mem_nonZeroDivisors_iff'.mpr ⟨Submonoid.mul_mem _ hx.1 hy.1, Submonoid.mul_mem _ hx.2 hy.2⟩ diff --git a/Mathlib/Algebra/GroupWithZero/Regular.lean b/Mathlib/Algebra/GroupWithZero/Regular.lean index cc8c99501f7f19..5d78bce11fc678 100644 --- a/Mathlib/Algebra/GroupWithZero/Regular.lean +++ b/Mathlib/Algebra/GroupWithZero/Regular.lean @@ -102,8 +102,6 @@ variable [MulZeroClass R] [IsCancelMulZero R] {a : R} theorem IsRegular.of_ne_zero (a0 : a ≠ 0) : IsRegular a := ⟨fun _ _ => mul_left_cancel₀ a0, fun _ _ => mul_right_cancel₀ a0⟩ -@[deprecated (since := "2026-01-21")] alias isRegular_of_ne_zero := IsRegular.of_ne_zero - /-- In a non-trivial integral domain, an element is regular iff it is non-zero. -/ theorem isRegular_iff_ne_zero [Nontrivial R] : IsRegular a ↔ a ≠ 0 := ⟨IsRegular.ne_zero, .of_ne_zero⟩ diff --git a/Mathlib/Algebra/ModEq.lean b/Mathlib/Algebra/ModEq.lean deleted file mode 100644 index 23ef90a973256f..00000000000000 --- a/Mathlib/Algebra/ModEq.lean +++ /dev/null @@ -1,8 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2026-01-15") diff --git a/Mathlib/Algebra/Module/Hom.lean b/Mathlib/Algebra/Module/Hom.lean index 0482e7ef123f8e..3861ecc4439f01 100644 --- a/Mathlib/Algebra/Module/Hom.lean +++ b/Mathlib/Algebra/Module/Hom.lean @@ -112,13 +112,6 @@ end AddMonoid.End namespace AddMonoidHom -/-- Scalar multiplication on the left as an additive monoid homomorphism. - -See also the linear map version of this `Module.End.smulLeft`. -/ -@[simps! -fullyApplied, deprecated DistribSMul.toAddMonoidHom (since := "2026-01-07")] -protected def smulLeft [AddMonoid A] [DistribSMul M A] (c : M) : A →+ A := - DistribSMul.toAddMonoidHom _ c - /-- Scalar multiplication as a biadditive monoid homomorphism. We need `M` to be commutative to have addition on `M →+ M`. -/ protected def smul [Semiring R] [AddCommMonoid M] [Module R M] : R →+ M →+ M := diff --git a/Mathlib/Algebra/Module/LinearMap/End.lean b/Mathlib/Algebra/Module/LinearMap/End.lean index c60fb89dc6720f..485d17dedd0d78 100644 --- a/Mathlib/Algebra/Module/LinearMap/End.lean +++ b/Mathlib/Algebra/Module/LinearMap/End.lean @@ -253,8 +253,6 @@ def DistribMulAction.toModuleEnd [DistribMulAction S M] [SMulCommClass S R M] : map_one' := LinearMap.ext <| one_smul _ map_mul' _ _ := LinearMap.ext <| mul_smul _ _ -@[deprecated (since := "2026-01-07")] alias DistribMulAction.toLinearMap := DistribSMul.toLinearMap - end section Module diff --git a/Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean b/Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean deleted file mode 100644 index 49273cee4eaeb6..00000000000000 --- a/Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean +++ /dev/null @@ -1,11 +0,0 @@ -/- -Copyright (c) 2018 Simon Hudon. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Anne Baanen --/ -module -- shake: keep-all - -public import Mathlib.Tactic.Common -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2026-01-19") diff --git a/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean b/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean index d7e3cc183b983e..2785615cacb521 100644 --- a/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean +++ b/Mathlib/Algebra/Order/Archimedean/Real/Basic.lean @@ -52,10 +52,6 @@ theorem of_near (f : ℕ → ℚ) (x : ℝ) (h : ∀ ε > 0, ∃ i, ∀ j ≥ i, (eq_of_le_of_forall_lt_imp_le_of_dense (abs_nonneg _)) fun _ε ε0 => mk_near_of_forall_near <| (h _ ε0).imp fun _i h j ij => le_of_lt (h j ij)⟩ -@[deprecated _root_.exists_floor (since := "2026-01-29")] -theorem exists_floor (x : ℝ) : ∃ ub : ℤ, (ub : ℝ) ≤ x ∧ ∀ z : ℤ, (z : ℝ) ≤ x → z ≤ ub := - ⟨⌊x⌋, Int.floor_le x, fun _ ↦ Int.le_floor.mpr⟩ - theorem exists_isLUB (hne : s.Nonempty) (hbdd : BddAbove s) : ∃ x, IsLUB s x := by rcases hne, hbdd with ⟨⟨L, hL⟩, ⟨U, hU⟩⟩ have : ∀ d : ℕ, BddAbove { m : ℤ | ∃ y ∈ s, (m : ℝ) ≤ y * d } := by diff --git a/Mathlib/Algebra/Polynomial/Degree/Definitions.lean b/Mathlib/Algebra/Polynomial/Degree/Definitions.lean deleted file mode 100644 index 302423210bf95d..00000000000000 --- a/Mathlib/Algebra/Polynomial/Degree/Definitions.lean +++ /dev/null @@ -1,10 +0,0 @@ -/- -Copyright (c) 2018 Chris Hughes. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Chris Hughes, Johannes Hölzl, Kim Morrison, Jens Wagemaker --/ -module -- shake: keep-all - -public import Mathlib.Algebra.Polynomial.Degree.Defs - -deprecated_module (since := "2026-01-26") diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index b7da22f4a56f1a..5a87d3af1c5fea 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -482,12 +482,6 @@ theorem splits_prod_iff {ι : Type*} {f : ι → R[X]} {s : Finset ι} (hf : ∀ ⟨fun h _ hx ↦ h.of_dvd (Finset.prod_ne_zero_iff.mpr hf) (Finset.dvd_prod_of_mem f hx), Splits.prod⟩ -@[deprecated "Use `Splits.degree_le_one_of_irreducible` instead." (since := "2026-01-13")] -theorem Splits.splits (hf : Splits f) : - f = 0 ∨ ∀ {g : R[X]}, Irreducible g → g ∣ f → degree g ≤ 1 := - or_iff_not_imp_left.mpr fun hf0 _ hg hgf ↦ degree_le_of_natDegree_le <| - (hf.of_dvd hf0 hgf).natDegree_le_one_of_irreducible hg - lemma map_sub_sprod_roots_eq_prod_map_eval (s : Multiset R) (g : R[X]) (hg : g.Monic) (hg' : g.Splits) : ((s ×ˢ g.roots).map fun ij ↦ ij.1 - ij.2).prod = (s.map g.eval).prod := by @@ -670,21 +664,6 @@ theorem Splits.of_natDegree_eq_two {x : R} (h₁ : f.natDegree = 2) (h₂ : f.ev theorem Splits.of_degree_eq_two {x : R} (h₁ : f.degree = 2) (h₂ : f.eval x = 0) : Splits f := Splits.of_natDegree_eq_two (natDegree_eq_of_degree_eq_some h₁) h₂ -open UniqueFactorizationMonoid in -@[deprecated "Use `Splits.degree_eq_one_of_irreducible` instead." (since := "2026-01-13")] -theorem splits_iff_splits {f : R[X]} : - Splits f ↔ f = 0 ∨ ∀ {g : R[X]}, Irreducible g → g ∣ f → degree g = 1 := by - refine ⟨fun hf ↦ or_iff_not_imp_left.mpr fun h0 g hg hgf ↦ - (hf.of_dvd h0 hgf).degree_eq_one_of_irreducible hg, ?_⟩ - rintro (rfl | hf) - · aesop - by_cases hf0 : f = 0 - · simp [hf0] - obtain ⟨u, hu⟩ := factors_prod hf0 - rw [← hu] - refine (Splits.multisetProd fun g hg ↦ ?_).mul u.isUnit.splits - exact Splits.of_degree_eq_one (hf (irreducible_of_factor g hg) (dvd_of_mem_factors hg)) - end Field noncomputable section diff --git a/Mathlib/Algebra/Ring/Regular.lean b/Mathlib/Algebra/Ring/Regular.lean index e1546108849ec8..c35cc66b9ec90f 100644 --- a/Mathlib/Algebra/Ring/Regular.lean +++ b/Mathlib/Algebra/Ring/Regular.lean @@ -39,8 +39,6 @@ theorem IsRegular.of_ne_zero' [NonUnitalNonAssocRing α] [NoZeroDivisors α] {k isRightRegular_of_non_zero_divisor k fun _ h => (NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero h).resolve_right hk⟩ -@[deprecated (since := "2026-01-21")] alias isRegular_of_ne_zero' := IsRegular.of_ne_zero' - theorem isRegular_iff_ne_zero' [Nontrivial α] [NonUnitalNonAssocRing α] [NoZeroDivisors α] {k : α} : IsRegular k ↔ k ≠ 0 := ⟨fun h => by diff --git a/Mathlib/AlgebraicGeometry/Artinian.lean b/Mathlib/AlgebraicGeometry/Artinian.lean index f465a94b506c1e..4feb2b35b479c1 100644 --- a/Mathlib/AlgebraicGeometry/Artinian.lean +++ b/Mathlib/AlgebraicGeometry/Artinian.lean @@ -102,9 +102,6 @@ instance (priority := low) IsLocallyArtinian.discreteTopology [IsLocallyArtinian have : DiscreteTopology W := hW1.isoSpec.hom.homeomorph.symm.discreteTopology simpa using (isOpen_discrete ({⟨x, hW2⟩} : Set W)).trans W.2 -@[deprecated (since := "2026-01-14")] -alias IsLocallyArtinian.discreteTopology_of_isAffine := IsLocallyArtinian.discreteTopology - theorem IsLocallyArtinian.iff_isLocallyNoetherian_and_discreteTopology : IsLocallyArtinian X ↔ IsLocallyNoetherian X ∧ DiscreteTopology X := ⟨fun _ ↦ ⟨inferInstance, inferInstance⟩, fun ⟨_, _⟩ ↦ .of_isLocallyNoetherian_of_discreteTopology⟩ diff --git a/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean b/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean index fe84c8700dc990..f9e80ef8fdb7b0 100644 --- a/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean +++ b/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean @@ -245,24 +245,6 @@ This is implemented as an `abbrev` for `CategoryTheory.Precoverage.ZeroHypercove abbrev Cover.Hom {X : Scheme.{u}} (𝒰 𝒱 : Cover.{v} K X) := Precoverage.ZeroHypercover.Hom K 𝒰 𝒱 -@[deprecated (since := "2026-01-13")] alias Cover.Hom.idx := PreZeroHypercover.Hom.s₀ - -@[deprecated (since := "2026-01-13")] alias Cover.Hom.app := PreZeroHypercover.Hom.h₀ - -@[deprecated (since := "2026-01-13")] alias Cover.Hom.w := PreZeroHypercover.Hom.w₀ - -@[deprecated (since := "2026-01-13")] alias Cover.Hom.id := PreZeroHypercover.Hom.id - -@[deprecated (since := "2026-01-13")] alias Cover.Hom.comp := PreZeroHypercover.Hom.comp - -@[deprecated (since := "2026-01-13")] alias Cover.id_idx_apply := PreZeroHypercover.id_s₀ - -@[deprecated (since := "2026-01-13")] alias Cover.id_app := PreZeroHypercover.id_h₀ - -@[deprecated (since := "2026-01-13")] alias Cover.comp_idx_apply := PreZeroHypercover.comp_s₀ - -@[deprecated (since := "2026-01-13")] alias Cover.comp_app := PreZeroHypercover.comp_h₀ - end category end MorphismProperty diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index a0f4c4bad5e6a1..421927c5a63b6b 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -47,9 +47,6 @@ class IsClosedImmersion {X Y : Scheme} (f : X ⟶ Y) : Prop extends SurjectiveOn alias Scheme.Hom.isClosedEmbedding := IsClosedImmersion.isClosedEmbedding -@[deprecated (since := "2026-01-20")] -alias IsClosedImmersion.base_closed := Scheme.Hom.isClosedEmbedding - namespace IsClosedImmersion lemma eq_inf : @IsClosedImmersion = (topologically IsClosedEmbedding) ⊓ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean b/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean index 83a7b57ef31c8a..56c01022f6b5ac 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FinitePresentation.lean @@ -49,10 +49,6 @@ class LocallyOfFinitePresentation (f : X ⟶ Y) : Prop where alias Scheme.Hom.finitePresentation_appLE := LocallyOfFinitePresentation.finitePresentation_appLE -@[deprecated (since := "2026-01-20")] -alias LocallyOfFinitePresentation.finitePresentation_of_affine_subset := - Scheme.Hom.finitePresentation_appLE - instance : HasRingHomProperty @LocallyOfFinitePresentation RingHom.FinitePresentation where isLocal_ringHomProperty := RingHom.finitePresentation_isLocal eq_affineLocally' := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean index b4babad0160370..1fedabf2ef5b3e 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean @@ -47,10 +47,6 @@ class LocallyOfFiniteType (f : X ⟶ Y) : Prop where alias Scheme.Hom.finiteType_appLE := LocallyOfFiniteType.finiteType_appLE -@[deprecated (since := "2026-01-20")] -alias LocallyOfFiniteType.finiteType_of_affine_subset := - Scheme.Hom.finiteType_appLE - instance : HasRingHomProperty @LocallyOfFiniteType RingHom.FiniteType where isLocal_ringHomProperty := RingHom.finiteType_isLocal eq_affineLocally' := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean index d1c1232c42ae5d..8df1840034f03f 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Flat.lean @@ -46,8 +46,6 @@ class Flat (f : X ⟶ Y) : Prop where alias Scheme.Hom.flat_appLE := Flat.flat_appLE -@[deprecated (since := "2026-01-20")] alias Flat.flat_of_affine_subset := Scheme.Hom.flat_appLE - namespace Flat instance : HasRingHomProperty @Flat RingHom.Flat where diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean index fb76c100ace2b3..8827ae777da570 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FormallyUnramified.lean @@ -58,9 +58,6 @@ class FormallyUnramified (f : X ⟶ Y) : Prop where alias Scheme.Hom.formallyUnramified_appLE := FormallyUnramified.formallyUnramified_appLE -@[deprecated (since := "2026-01-20")] -alias FormallyUnramified.formallyUnramified_of_affine_subset := Scheme.Hom.formallyUnramified_appLE - namespace FormallyUnramified instance : HasRingHomProperty @FormallyUnramified RingHom.FormallyUnramified where diff --git a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean index 501572d427a8dd..75bc258cda7e8d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean @@ -66,9 +66,6 @@ lemma isOpenImmersion_SpecMap_iff_of_surjective {R S : CommRingCat} variable {X Y : Scheme.{u}} -@[deprecated (since := "2026-01-20")] -alias isOpenImmersion_iff_stalk := IsOpenImmersion.iff_isIso_stalkMap - set_option backward.isDefEq.respectTransparency false in theorem IsOpenImmersion.of_openCover_source (f : X ⟶ Y) (𝒰 : X.OpenCover) (hf : Function.Injective f) (h𝒰 : ∀ i, IsOpenImmersion (𝒰.f i ≫ f)) : diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean index cbc9212a4c7b9b..94afbb24fc3328 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean @@ -35,8 +35,6 @@ class IsPreimmersion {X Y : Scheme} (f : X ⟶ Y) : Prop extends SurjectiveOnSta alias Scheme.Hom.isEmbedding := IsPreimmersion.isEmbedding -@[deprecated (since := "2026-01-20")] alias IsPreimmersion.base_embedding := Scheme.Hom.isEmbedding - lemma isPreimmersion_eq_inf : @IsPreimmersion = (@SurjectiveOnStalks ⊓ topologically IsEmbedding : MorphismProperty _) := by ext diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean index 8f38f401c09c4e..f1fcf83eec1123 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean @@ -45,12 +45,9 @@ class IsSeparated : Prop where /-- A morphism is separated if the diagonal map is a closed immersion. -/ isClosedImmersion_diagonal : IsClosedImmersion (pullback.diagonal f) := by infer_instance -@[deprecated (since := "2026-01-20")] -alias IsSeparated.diagonal_isClosedImmersion := IsSeparated.isClosedImmersion_diagonal - namespace IsSeparated -attribute [instance] diagonal_isClosedImmersion +attribute [instance] isClosedImmersion_diagonal theorem isSeparated_eq_diagonal_isClosedImmersion : @IsSeparated = MorphismProperty.diagonal @IsClosedImmersion := by diff --git a/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean b/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean index 1164abb4b6a5dc..46ddace785908d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/SurjectiveOnStalks.lean @@ -39,9 +39,6 @@ class SurjectiveOnStalks (f : X ⟶ Y) : Prop where alias Scheme.Hom.stalkMap_surjective := SurjectiveOnStalks.stalkMap_surjective -@[deprecated (since := "2026-01-20")] -alias SurjectiveOnStalks.surj_on_stalks := Scheme.Hom.stalkMap_surjective - namespace SurjectiveOnStalks instance (priority := 900) [IsOpenImmersion f] : SurjectiveOnStalks f := diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean index bee804f020a50e..6a4fcbe6655d2d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean @@ -43,9 +43,6 @@ along any morphism `Y' ⟶ Y` is (topologically) a closed map. class UniversallyClosed (f : X ⟶ Y) : Prop where universally_isClosedMap : universally (topologically @IsClosedMap) f -@[deprecated (since := "2026-01-20")] -alias UniversallyClosed.out := UniversallyClosed.universally_isClosedMap - lemma Scheme.Hom.isClosedMap {X Y : Scheme} (f : X ⟶ Y) [UniversallyClosed f] : IsClosedMap f := UniversallyClosed.universally_isClosedMap _ _ _ IsPullback.of_id_snd diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean index 9205e33a255bf4..dd49b11a74329a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyOpen.lean @@ -42,9 +42,6 @@ along any morphism `Y' ⟶ Y` is (topologically) an open map. class UniversallyOpen (f : X ⟶ Y) : Prop where universally_isOpenMap : universally (topologically @IsOpenMap) f -@[deprecated (since := "2026-01-20")] -alias UniversallyOpen.out := UniversallyOpen.universally_isOpenMap - lemma Scheme.Hom.isOpenMap {X Y : Scheme} (f : X ⟶ Y) [UniversallyOpen f] : IsOpenMap f := UniversallyOpen.universally_isOpenMap _ _ _ IsPullback.of_id_snd diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean index 55c5697d31858a..6572a22d60627d 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/SimplyConnected.lean @@ -40,9 +40,6 @@ variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] class SimplyConnectedSpace (X : Type*) [TopologicalSpace X] : Prop where equiv_unit : Nonempty (FundamentalGroupoid X ≌ Discrete Unit) -@[deprecated (since := "2026-01-08")] -alias simply_connected_def := simplyConnectedSpace_iff - theorem simply_connected_iff_unique_homotopic (X : Type*) [TopologicalSpace X] : SimplyConnectedSpace X ↔ Nonempty X ∧ ∀ x y : X, Nonempty (Unique (Path.Homotopic.Quotient x y)) := by diff --git a/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean b/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean index 0e842de11a775a..5bd190755f8047 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/CofibrantObjectHomotopy.lean @@ -257,9 +257,6 @@ full subcategory of cofibrant objects factors through the homotopy category of cofibrant objects. -/ def HoCat.toHoCatCompToLocalizationIso : toHoCat ⋙ toLocalization L ≅ ι ⋙ L := Iso.refl _ -@[deprecated (since := "2026-01-31")] -alias HoCat.toπCompToLocalizationIso := HoCat.toHoCatCompToLocalizationIso - /-- The natural isomorphism `HoCat.resolution ⋙ HoCat.toLocalization L ⟶ L` when `L : C ⥤ D` is a localization functor. -/ noncomputable def HoCat.resolutionCompToLocalizationNatTrans : diff --git a/Mathlib/Analysis/Analytic/Composition.lean b/Mathlib/Analysis/Analytic/Composition.lean index d4c0139b0ff4c1..0dba39a346691c 100644 --- a/Mathlib/Analysis/Analytic/Composition.lean +++ b/Mathlib/Analysis/Analytic/Composition.lean @@ -861,8 +861,6 @@ theorem AnalyticAt.comp {g : F → G} {f : E → F} {x : E} (hg : AnalyticAt rw [← analyticWithinAt_univ] at hg hf ⊢ apply hg.comp hf (by simp) -@[deprecated (since := "2026-01-24")] alias AnalyticAt.comp' := AnalyticAt.fun_comp - /-- Version of `AnalyticAt.comp` where point equality is a separate hypothesis. -/ @[to_fun] theorem AnalyticAt.comp_of_eq {g : F → G} {f : E → F} {y : F} {x : E} (hg : AnalyticAt 𝕜 g y) diff --git a/Mathlib/Analysis/Asymptotics/AsymptoticEquivalent.lean b/Mathlib/Analysis/Asymptotics/AsymptoticEquivalent.lean index 19c60b57a7f537..ff18422cb90e97 100644 --- a/Mathlib/Analysis/Asymptotics/AsymptoticEquivalent.lean +++ b/Mathlib/Analysis/Asymptotics/AsymptoticEquivalent.lean @@ -202,9 +202,6 @@ theorem isEquivalent_of_tendsto_one (huv : Tendsto (u / v) l (𝓝 1)) : replace h : ∃ᶠ t in l, (u / v) t = 0 := h.mono fun x ⟨hv, hu⟩ ↦ by simp [hv] simpa using tendsto_nhds_unique_of_frequently_eq (b := 0) huv tendsto_const_nhds h -@[deprecated (since := "2026-01-26")] alias isEquivalent_of_tendsto_one' := - isEquivalent_of_tendsto_one - theorem isEquivalent_iff_tendsto_one (hz : ∀ᶠ x in l, v x ≠ 0) : u ~[l] v ↔ Tendsto (u / v) l (𝓝 1) := by constructor diff --git a/Mathlib/Analysis/Calculus/Deriv/Mul.lean b/Mathlib/Analysis/Calculus/Deriv/Mul.lean index f688112f3812e3..235563b8145477 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Mul.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Mul.lean @@ -211,18 +211,12 @@ lemma derivWithin_fun_const_smul_field (c : 𝕝) (f : 𝕜 → F) : · simp [← fderivWithin_derivWithin, ← Pi.smul_def, fderivWithin_const_smul_field c hsx] · simp [derivWithin_zero_of_not_uniqueDiffWithinAt hsx] -@[deprecated (since := "2026-01-11")] alias derivWithin_fun_const_smul' := - derivWithin_fun_const_smul_field - /-- A variant of `derivWithin_const_smul` without differentiability assumption when the scalar multiplication is by division ring elements. -/ lemma derivWithin_const_smul_field (c : 𝕝) (f : 𝕜 → F) : derivWithin (c • f) s x = c • derivWithin f s x := derivWithin_fun_const_smul_field c f -@[deprecated (since := "2026-01-11")] alias derivWithin_const_smul' := - derivWithin_const_smul_field - theorem deriv_fun_const_smul (c : R) (hf : DifferentiableAt 𝕜 f x) : deriv (fun y => c • f y) x = c • deriv f x := (hf.hasDerivAt.const_smul c).deriv @@ -237,16 +231,12 @@ lemma deriv_fun_const_smul_field (c : 𝕝) (f : 𝕜 → F) : deriv (fun y ↦ c • f y) x = c • deriv f x := by simp only [← derivWithin_univ, derivWithin_fun_const_smul_field] -@[deprecated (since := "2026-01-11")] alias deriv_fun_const_smul' := deriv_fun_const_smul_field - /-- A variant of `deriv_const_smul` without differentiability assumption when the scalar multiplication is by division ring elements. -/ lemma deriv_const_smul_field (c : 𝕝) (f : 𝕜 → F) : deriv (c • f) x = c • deriv f x := by simp only [← derivWithin_univ, derivWithin_const_smul_field] -@[deprecated (since := "2026-01-11")] alias deriv_const_smul' := deriv_const_smul_field - end ConstSMul section Mul diff --git a/Mathlib/Analysis/Calculus/FDeriv/Add.lean b/Mathlib/Analysis/Calculus/FDeriv/Add.lean index 3b517d59265c11..c6209d8463835a 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Add.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Add.lean @@ -167,9 +167,6 @@ lemma fderivWithin_neg' {s : Set 𝕜} {f : 𝕜 → F} {x : 𝕜} : fderivWithin 𝕜 (-f) s x = -fderivWithin 𝕜 f s x := by simpa only [neg_smul, one_smul] using fderivWithin_const_smul_field' (f := f) (-1 : 𝕜) -@[deprecated (since := "2026-01-11")] alias fderivWithin_const_smul_of_field := - fderivWithin_const_smul_field - /-- Special case of `fderiv_const_smul_of_invertible` over a division semiring: any constant is allowed. @@ -180,8 +177,6 @@ lemma fderiv_const_smul_field (c : R) : fderiv 𝕜 (c • f) = c • fderiv ext x simp [fderivWithin_const_smul_field c uniqueDiffWithinAt_univ] -@[deprecated (since := "2026-01-11")] alias fderiv_const_smul_of_field := fderiv_const_smul_field - end ConstSMulDivisionRing section Add diff --git a/Mathlib/Analysis/Calculus/Implicit.lean b/Mathlib/Analysis/Calculus/Implicit.lean index 53c79482aee0fd..cbfe985ddce446 100644 --- a/Mathlib/Analysis/Calculus/Implicit.lean +++ b/Mathlib/Analysis/Calculus/Implicit.lean @@ -184,23 +184,14 @@ theorem prodFun_implicitFunction : ∀ᶠ p : F × G in 𝓝 (φ.prodFun φ.pt), φ.prodFun (φ.implicitFunction p.1 p.2) = p := φ.hasStrictFDerivAt.eventually_right_inverse.mono fun ⟨_, _⟩ h => h -@[deprecated (since := "2026-01-27")] -alias prod_map_implicitFunction := prodFun_implicitFunction - theorem leftFun_implicitFunction : ∀ᶠ p : F × G in 𝓝 (φ.prodFun φ.pt), φ.leftFun (φ.implicitFunction p.1 p.2) = p.1 := φ.prodFun_implicitFunction.mono fun _ => congr_arg Prod.fst -@[deprecated (since := "2026-01-27")] -alias left_map_implicitFunction := leftFun_implicitFunction - theorem rightFun_implicitFunction : ∀ᶠ p : F × G in 𝓝 (φ.prodFun φ.pt), φ.rightFun (φ.implicitFunction p.1 p.2) = p.2 := φ.prodFun_implicitFunction.mono fun _ => congr_arg Prod.snd -@[deprecated (since := "2026-01-27")] -alias right_map_implicitFunction := rightFun_implicitFunction - theorem implicitFunction_apply_image : ∀ᶠ x in 𝓝 φ.pt, φ.implicitFunction (φ.leftFun x) (φ.rightFun x) = x := φ.hasStrictFDerivAt.eventually_left_inverse @@ -266,9 +257,6 @@ theorem hasStrictFDerivAt_implicitFunction (g'inv : G →L[𝕜] E) rw [eq_comm, fderiv_implicitFunction_apply_eq_iff] simp_all [DFunLike.ext_iff] -@[deprecated (since := "2026-01-27")] -alias implicitFunction_hasStrictFDerivAt := hasStrictFDerivAt_implicitFunction - theorem map_implicitFunction_nhdsWithin_preimage (φ : ImplicitFunctionData 𝕜 E F G) (s : Set E) : (𝓝[φ.implicitFunction (φ.leftFun φ.pt) ⁻¹' s] (φ.rightFun φ.pt)).map diff --git a/Mathlib/Analysis/Calculus/ImplicitContDiff.lean b/Mathlib/Analysis/Calculus/ImplicitContDiff.lean index e0bdd104a1df87..74332e2d31d4a6 100644 --- a/Mathlib/Analysis/Calculus/ImplicitContDiff.lean +++ b/Mathlib/Analysis/Calculus/ImplicitContDiff.lean @@ -99,33 +99,4 @@ theorem contDiffAt_implicitFunction end ContDiffAt -/-- A predicate stating the sufficient conditions on an implicit equation `f : E₁ × E₂ → F` that -will lead to a $C^n$ implicit function `ψ : E₁ → E₂`. -/ -@[deprecated "ContDiffAt.implicitFunction does not require this" (since := "2026-01-27")] -structure IsContDiffImplicitAt (n : ℕ∞ω) (f : E₁ × E₂ → F) (f' : E₁ × E₂ →L[𝕜] F) - (u : E₁ × E₂) : Prop where - hasFDerivAt : HasFDerivAt f f' u - contDiffAt : ContDiffAt 𝕜 n f u - bijective : Function.Bijective (f'.comp (ContinuousLinearMap.inr 𝕜 E₁ E₂)) - ne_zero : n ≠ 0 - -namespace IsContDiffImplicitAt - -@[deprecated (since := "2026-01-27")] -alias implicitFunction := ContDiffAt.implicitFunction - -@[deprecated (since := "2026-01-27")] -alias implicitFunction_def := ContDiffAt.implicitFunction_def - -@[deprecated (since := "2026-01-27")] -alias apply_implicitFunction := ContDiffAt.eventually_apply_implicitFunction - -@[deprecated (since := "2026-01-27")] -alias eventually_implicitFunction_apply_eq := ContDiffAt.eventually_apply_eq_iff_implicitFunction - -@[deprecated (since := "2026-01-27")] -alias contDiffAt_implicitFunction := ContDiffAt.contDiffAt_implicitFunction - -end IsContDiffImplicitAt - end diff --git a/Mathlib/Analysis/Calculus/TangentCone/Basic.lean b/Mathlib/Analysis/Calculus/TangentCone/Basic.lean index d436c99da89424..daa37e93316213 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Basic.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Basic.lean @@ -153,9 +153,6 @@ theorem zero_mem_tangentConeAt (hx : x ∈ closure s) : · simp only [Pi.one_apply, one_smul] exact Continuous.tendsto' (by fun_prop) _ _ (by simp) -@[deprecated (since := "2026-01-21")] -alias zero_mem_tangentCone := zero_mem_tangentConeAt - @[simp] theorem zero_mem_tangentConeAt_iff : 0 ∈ tangentConeAt 𝕜 s x ↔ x ∈ closure s := ⟨fun h ↦ mem_closure_of_nonempty_tangentConeAt ⟨_, h⟩, zero_mem_tangentConeAt⟩ diff --git a/Mathlib/Analysis/Complex/IntegerCompl.lean b/Mathlib/Analysis/Complex/IntegerCompl.lean index e886144cc8a265..9b44932dcd48b1 100644 --- a/Mathlib/Analysis/Complex/IntegerCompl.lean +++ b/Mathlib/Analysis/Complex/IntegerCompl.lean @@ -30,9 +30,6 @@ lemma integerComplement_eq : ℂ_ℤ = {z : ℂ | ¬ ∃ (n : ℤ), n = z} := rf lemma mem_integerComplement_iff {x : ℂ} : x ∈ ℂ_ℤ ↔ ¬ ∃ (n : ℤ), n = x := Iff.rfl -@[deprecated (since := "2026-01-29")] -alias integerComplement.mem_iff := mem_integerComplement_iff - @[simp] lemma _root_.UpperHalfPlane.coe_mem_integerComplement (z : ℍ) : ↑z ∈ ℂ_ℤ := not_exists.mpr fun x hx ↦ ne_intCast z x hx.symm @@ -43,9 +40,6 @@ lemma add_intCast_mem_integerComplement {x : ℂ} (a : ℤ) : x + (a : ℂ) ∈ exact ⟨(Exists.elim · fun n hn ↦ ⟨n - a, by simp [hn]⟩), (Exists.elim · fun n hn ↦ ⟨n + a, by simp [hn]⟩)⟩ -@[deprecated (since := "2026-01-29")] -alias integerComplement.add_coe_int_mem := add_intCast_mem_integerComplement - lemma integerComplement.ne_zero {x : ℂ} (hx : x ∈ ℂ_ℤ) : x ≠ 0 := fun hx' ↦ hx ⟨0, by exact_mod_cast hx'.symm⟩ diff --git a/Mathlib/Analysis/Complex/Schwarz.lean b/Mathlib/Analysis/Complex/Schwarz.lean index a6d138a4634249..00be646899782c 100644 --- a/Mathlib/Analysis/Complex/Schwarz.lean +++ b/Mathlib/Analysis/Complex/Schwarz.lean @@ -218,9 +218,6 @@ theorem dist_le_dist_of_mapsTo_ball (hd : DifferentiableOn ℂ f (ball c R)) dist (f z) (f c) ≤ dist z c := by simpa [(nonempty_ball.1 ⟨z, hz⟩).ne'] using dist_le_div_mul_dist_of_mapsTo_ball hd h_maps hz -@[deprecated (since := "2026-01-03")] -alias dist_le_dist_of_mapsTo_ball_self := dist_le_dist_of_mapsTo_ball - /-- The **Schwarz Lemma**. Let `f : E → F` be a complex analytic function on an open ball with center `c` and a positive radius. If `f` sends this ball to a closed ball with center `f c` and the same radius, @@ -240,9 +237,6 @@ theorem norm_le_norm_of_mapsTo_ball (hd : DifferentiableOn ℂ f (ball 0 R)) ‖f z‖ ≤ ‖z‖ := by simpa [h₀] using dist_le_dist_of_mapsTo_ball hd (by rwa [h₀]) (mem_ball_zero_iff.mpr hz) -@[deprecated (since := "2026-01-03")] -alias norm_le_norm_of_mapsTo_ball_self := norm_le_norm_of_mapsTo_ball - end NormedSpace section DimOne @@ -329,10 +323,6 @@ theorem affine_of_mapsTo_ball_of_norm_dslope_eq_div [StrictConvexSpace ℝ E] simp only [heq, SameRay.rfl.norm_add, heq_add] simp [← this] -@[deprecated (since := "2026-01-03")] -alias affine_of_mapsTo_ball_of_exists_norm_dslope_eq_div := - affine_of_mapsTo_ball_of_norm_dslope_eq_div - /-- Equality case in the **Schwarz Lemma**: in the setup of `norm_dslope_le_div_of_mapsTo_ball`, if there exists a point `z₀` in the ball such that `‖dslope f c z₀‖ = R₂ / R₁`, then the map `f` is affine with the absolute value of the slope equal to `R₂ / R₁`. diff --git a/Mathlib/Analysis/Complex/TaylorSeries.lean b/Mathlib/Analysis/Complex/TaylorSeries.lean index 139c1c86c83be1..f838b289451936 100644 --- a/Mathlib/Analysis/Complex/TaylorSeries.lean +++ b/Mathlib/Analysis/Complex/TaylorSeries.lean @@ -93,9 +93,6 @@ lemma hasSum_taylorSeries_on_eball : rw [← Metric.eball_coe] exact hf.mono <| Metric.eball_subset_eball hr'.le -@[deprecated (since := "2026-01-24")] -alias hasSum_taylorSeries_on_emetric_ball := hasSum_taylorSeries_on_eball - include hf hz in /-- A function that is complex differentiable on the open ball of radius `r ≤ ∞` around `c` is given by evaluating its Taylor series at `c` on this open ball. -/ @@ -103,9 +100,6 @@ lemma taylorSeries_eq_on_eball : ∑' n : ℕ, (n ! : ℂ)⁻¹ • (z - c) ^ n • iteratedDeriv n f c = f z := (hasSum_taylorSeries_on_eball hf hz).tsum_eq -@[deprecated (since := "2026-01-24")] -alias taylorSeries_eq_on_emetric_ball := taylorSeries_eq_on_eball - include hz in /-- A function that is complex differentiable on the open ball of radius `r ≤ ∞` around `c` is given by evaluating its Taylor series at `c` on this open ball. -/ @@ -114,9 +108,6 @@ lemma taylorSeries_eq_on_eball' {f : ℂ → ℂ} (hf : DifferentiableOn ℂ f ( convert! taylorSeries_eq_on_eball hf hz using 3 with n rw [mul_right_comm, smul_eq_mul, smul_eq_mul, mul_assoc] -@[deprecated (since := "2026-01-24")] -alias taylorSeries_eq_on_emetric_ball' := taylorSeries_eq_on_eball' - end emetric section entire diff --git a/Mathlib/Analysis/Complex/UnitDisc/Basic.lean b/Mathlib/Analysis/Complex/UnitDisc/Basic.lean index e6ce3a7c5e48fb..6727a05ec5f0e8 100644 --- a/Mathlib/Analysis/Complex/UnitDisc/Basic.lean +++ b/Mathlib/Analysis/Complex/UnitDisc/Basic.lean @@ -175,9 +175,6 @@ instance instSMulCommClass_circle_right : SMulCommClass 𝔻 Circle 𝔻 := theorem coe_circle_smul (z : Circle) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) := rfl -@[deprecated (since := "2026-01-06")] -alias coe_smul_circle := coe_circle_smul - instance : Pow UnitDisc ℕ+ where pow z n := ⟨z ^ (n : ℕ), by simp [pow_lt_one_iff_of_nonneg, z.norm_lt_one]⟩ @@ -235,15 +232,8 @@ theorem im_neg (z : 𝔻) : (-z).im = -z.im := instance : Star 𝔻 where star z := mk (conj z) <| (norm_conj z).symm ▸ z.norm_lt_one -/-- Conjugate point of the unit disc. Deprecated, use `star` instead. -/ -@[deprecated star (since := "2026-01-06")] -protected def «conj» (z : 𝔻) := star z - @[simp] theorem coe_star (z : 𝔻) : (↑(star z) : ℂ) = conj ↑z := rfl -@[deprecated (since := "2026-01-06")] -alias coe_conj := coe_star - @[simp] protected theorem star_eq_zero {z : 𝔻} : star z = 0 ↔ z = 0 := by simp [← coe_eq_zero] @@ -254,30 +244,15 @@ protected theorem star_zero : star (0 : 𝔻) = 0 := by simp instance : InvolutiveStar 𝔻 where star_involutive z := by ext; simp -@[deprecated star_star (since := "2026-01-06")] -theorem conj_conj (z : 𝔻) : star (star z) = z := star_star z - @[simp] protected theorem star_neg (z : 𝔻) : star (-z) = -(star z) := rfl -@[deprecated (since := "2026-01-06")] -alias conj_neg := UnitDisc.star_neg - @[simp] protected theorem re_star (z : 𝔻) : (star z).re = z.re := rfl -@[deprecated (since := "2026-01-06")] -alias re_conj := UnitDisc.re_star - @[simp] protected theorem im_star (z : 𝔻) : (star z).im = -z.im := rfl -@[deprecated (since := "2026-01-06")] alias im_conj := UnitDisc.im_star - instance : StarMul 𝔻 where star_mul z w := coe_injective <| by simp [mul_comm] -@[deprecated star_mul' (since := "2026-01-06")] -theorem conj_mul (z w : 𝔻) : star (z * w) = star z * star w := - star_mul' z w - end UnitDisc namespace UnitClosedDisc @@ -435,9 +410,6 @@ instance instSMulCommClass_closedBall_circle : SMulCommClass 𝕔𝔻 Circle theorem coe_closedBall_smul (z : 𝕔𝔻) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) := rfl -@[deprecated (since := "2026-01-06")] -alias coe_smul_closedBall := coe_closedBall_smul - @[simp, norm_cast] theorem coe_circle_smul (z : Circle) (w : 𝕔𝔻) : ↑(z • w) = (z * w : ℂ) := rfl diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 6786ec87928768..dae7cbc9f06edb 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -53,8 +53,6 @@ instance : Inhabited ℍ := ⟨.I⟩ @[simp, norm_cast] theorem coe_inj {a b : ℍ} : (a : ℂ) = b ↔ a = b := UpperHalfPlane.ext_iff.symm -@[deprecated (since := "2026-01-31")] alias ext_iff' := coe_inj - theorem coe_injective : Function.Injective UpperHalfPlane.coe := fun _ _ ↦ UpperHalfPlane.ext instance canLift : CanLift ℂ ℍ ((↑) : ℍ → ℂ) fun z => 0 < z.im where @@ -78,9 +76,6 @@ def re (z : ℍ) := theorem ext_re_im {a b : ℍ} (hre : a.re = b.re) (him : a.im = b.im) : a = b := UpperHalfPlane.ext <| Complex.ext hre him -@[deprecated (since := "2026-01-29")] -alias ext' := ext_re_im - @[simp] theorem coe_im (z : ℍ) : (z : ℂ).im = z.im := rfl @@ -113,11 +108,6 @@ lemma I_re : I.re = 0 := Complex.I_re @[simp, norm_cast] lemma coe_I : I = Complex.I := rfl -@[deprecated coe_mk (since := "2026-01-29")] -lemma coe_mk_subtype {z : ℂ} (hz : 0 < z.im) : - UpperHalfPlane.coe ⟨z, hz⟩ = z := - rfl - theorem re_add_im (z : ℍ) : (z.re + z.im * Complex.I : ℂ) = z := Complex.re_add_im z @@ -188,12 +178,8 @@ lemma ne_ofReal (z : ℍ) (x : ℝ) : (z : ℂ) ≠ x := lemma ne_intCast (z : ℍ) (n : ℤ) : (z : ℂ) ≠ n := mod_cast ne_ofReal z n -@[deprecated (since := "2026-01-29")] alias ne_int := ne_intCast - lemma ne_natCast (z : ℍ) (n : ℕ) : (z : ℂ) ≠ n := mod_cast ne_intCast z n -@[deprecated (since := "2026-01-29")] alias ne_nat := ne_natCast - section PosRealAction instance posRealAction : MulAction {x : ℝ // 0 < x} ℍ where diff --git a/Mathlib/Analysis/Convex/Body.lean b/Mathlib/Analysis/Convex/Body.lean index c184ffeba37dc6..4a57cd191fe9b0 100644 --- a/Mathlib/Analysis/Convex/Body.lean +++ b/Mathlib/Analysis/Convex/Body.lean @@ -180,9 +180,6 @@ theorem hausdorffEDist_ne_top {K L : ConvexBody V} : Metric.hausdorffEDist (K : apply_rules [Metric.hausdorffEDist_ne_top_of_nonempty_of_bounded, ConvexBody.nonempty, ConvexBody.isBounded] -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_ne_top := hausdorffEDist_ne_top - /-- Convex bodies in a fixed seminormed space $V$ form a pseudo-metric space under the Hausdorff metric. -/ noncomputable instance : PseudoMetricSpace (ConvexBody V) where @@ -200,9 +197,6 @@ theorem hausdorffEDist_coe : Metric.hausdorffEDist (K : Set V) L = edist K L := rw [edist_dist] exact (ENNReal.ofReal_toReal hausdorffEDist_ne_top).symm -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_coe := hausdorffEDist_coe - open Filter /-- Let `K` be a convex body that contains `0` and let `u n` be a sequence of nonnegative real diff --git a/Mathlib/Analysis/Distribution/FourierSchwartz.lean b/Mathlib/Analysis/Distribution/FourierSchwartz.lean deleted file mode 100644 index 42a44c1a9c25eb..00000000000000 --- a/Mathlib/Analysis/Distribution/FourierSchwartz.lean +++ /dev/null @@ -1,7 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Analysis.SpecialFunctions.Bernstein -public import Mathlib.Analysis.SpecialFunctions.Gamma.Basic -public import Mathlib.Data.Nat.Factorial.DoubleFactorial - -deprecated_module (since := "2026-01-19") diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace.lean b/Mathlib/Analysis/Distribution/SchwartzSpace.lean deleted file mode 100644 index 2775ffb0407423..00000000000000 --- a/Mathlib/Analysis/Distribution/SchwartzSpace.lean +++ /dev/null @@ -1,5 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv - -deprecated_module (since := "2026-01-19") diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean index 29b759c53de55f..0127fd08f9f1a8 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Fourier.lean @@ -139,15 +139,6 @@ instance instFourierInvPair : FourierInvPair 𝓢(V, E) 𝓢(V, E) where rw [fourier_coe, fourierInv_coe, f.continuous.fourier_fourierInv_eq f.integrable (𝓕 f).integrable] -@[deprecated (since := "2026-01-06")] -alias fourierTransformCLE := FourierTransform.fourierCLE - -@[deprecated (since := "2026-01-06")] -alias fourierTransformCLE_apply := FourierTransform.fourierCLE_apply - -@[deprecated (since := "2026-01-06")] -alias fourierTransformCLE_symm_apply := FourierTransform.fourierCLE_symm_apply - end definition section eval diff --git a/Mathlib/Analysis/Distribution/TemperedDistribution.lean b/Mathlib/Analysis/Distribution/TemperedDistribution.lean index 3bbfd124249ffd..3e4ba3774e5a6b 100644 --- a/Mathlib/Analysis/Distribution/TemperedDistribution.lean +++ b/Mathlib/Analysis/Distribution/TemperedDistribution.lean @@ -481,15 +481,6 @@ instance instContinuousFourier : ContinuousFourier 𝓢'(E, F) 𝓢'(E, F) where @[simp] theorem fourier_apply (f : 𝓢'(E, F)) (g : 𝓢(E, ℂ)) : 𝓕 f g = f (𝓕 g) := rfl -@[deprecated (since := "2026-01-06")] -alias fourierTransformCLM := FourierTransform.fourierCLM - -@[deprecated (since := "2026-01-06")] -alias fourierTransformCLM_apply := FourierTransform.fourierCLM_apply - -@[deprecated (since := "2026-01-06")] -alias fourierTransform_apply := fourier_apply - instance instFourierTransformInv : FourierTransformInv 𝓢'(E, F) 𝓢'(E, F) where fourierInv := PointwiseConvergenceCLM.precomp F (fourierInvCLM ℂ 𝓢(E, ℂ)) @@ -505,15 +496,6 @@ instance instContinuousFourierInv : ContinuousFourierInv 𝓢'(E, F) 𝓢'(E, F) @[simp] theorem fourierInv_apply (f : 𝓢'(E, F)) (g : 𝓢(E, ℂ)) : 𝓕⁻ f g = f (𝓕⁻ g) := rfl -@[deprecated (since := "2026-01-06")] -alias fourierTransformInvCLM := FourierTransform.fourierInvCLM - -@[deprecated (since := "2026-01-06")] -alias fourierTransformInvCLM_apply := FourierTransform.fourierInvCLM_apply - -@[deprecated (since := "2026-01-06")] -alias fourierTransformInv_apply := fourierInv_apply - instance instFourierPair : FourierPair 𝓢'(E, F) 𝓢'(E, F) where fourierInv_fourier_eq f := by ext; simp @@ -533,9 +515,6 @@ theorem fourier_toTemperedDistributionCLM_eq (f : 𝓢(E, F)) : ext g simpa using integral_fourier_smul_eq g f -@[deprecated (since := "2026-01-14")] -alias fourierTransform_toTemperedDistributionCLM_eq := fourier_toTemperedDistributionCLM_eq - /-- The distributional inverse Fourier transform and the classical inverse Fourier transform coincide on `𝓢(E, F)`. -/ theorem fourierInv_toTemperedDistributionCLM_eq (f : 𝓢(E, F)) : @@ -546,9 +525,6 @@ theorem fourierInv_toTemperedDistributionCLM_eq (f : 𝓢(E, F)) : rw [fourier_toTemperedDistributionCLM_eq] _ = _ := fourierInv_fourier_eq _ -@[deprecated (since := "2026-01-14")] -alias fourierTransformInv_toTemperedDistributionCLM_eq := fourierInv_toTemperedDistributionCLM_eq - end embedding open LineDeriv Real diff --git a/Mathlib/Analysis/Fourier/Notation.lean b/Mathlib/Analysis/Fourier/Notation.lean index fa130a45039688..f08101cad55dae 100644 --- a/Mathlib/Analysis/Fourier/Notation.lean +++ b/Mathlib/Analysis/Fourier/Notation.lean @@ -92,20 +92,6 @@ class ContinuousFourierInv (E : Type*) (F : outParam (Type*)) [TopologicalSpace E] [TopologicalSpace F] [FourierTransformInv E F] where continuous_fourierInv : Continuous (𝓕⁻ : E → F) -/-- A `FourierModule` is a function space on which the Fourier transform is a linear map. -/ -@[deprecated "use `FourierAdd` and `FourierSMul` instead" (since := "2026-01-06")] -structure FourierModule (R : Type*) (E : Type*) (F : outParam (Type*)) [Add E] [Add F] [SMul R E] - [SMul R F] extends FourierTransform E F where - fourier_add : ∀ (f g : E), 𝓕 (f + g) = 𝓕 f + 𝓕 g - fourier_smul : ∀ (r : R) (f : E), 𝓕 (r • f) = r • 𝓕 f - -/-- A `FourierInvModule` is a function space on which the Fourier transform is a linear map. -/ -@[deprecated "use `FourierInvAdd` and `FourierInvSMul` instead" (since := "2026-01-06")] -structure FourierInvModule (R : Type*) (E : Type*) (F : outParam (Type*)) [Add E] [Add F] [SMul R E] - [SMul R F] extends FourierTransformInv E F where - fourierInv_add : ∀ (f g : E), 𝓕⁻ (f + g) = 𝓕⁻ f + 𝓕⁻ g - fourierInv_smul : ∀ (r : R) (f : E), 𝓕⁻ (r • f) = r • 𝓕⁻ f - namespace FourierTransform export FourierAdd (fourier_add) diff --git a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean index 5077f2a85bcd59..5a8658501d139d 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orthogonal.lean @@ -411,13 +411,9 @@ notation:1200 K "ᗮ" => orthogonal K @[simp] lemma toSubmodule_orthogonal_eq : K.orthogonal.toSubmodule = K.toSubmodule.orthogonal := rfl -@[deprecated (since := "2026-01-18")] alias orthogonal_toSubmodule_eq := toSubmodule_orthogonal_eq - @[simp] lemma mem_orthogonal_toSubmodule_iff (v : E) : v ∈ (K.toSubmodule)ᗮ ↔ v ∈ Kᗮ := Iff.rfl -@[deprecated (since := "2026-01-18")] alias mem_orthogonal_iff := mem_orthogonal_toSubmodule_iff - /-- When a vector is in `Kᗮ`. -/ @[simp] theorem mem_orthogonal (v : E) : v ∈ Kᗮ ↔ ∀ u ∈ K, ⟪u, v⟫ = 0 := Iff.rfl diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index a938a909f274d3..9e7b49cb4815e4 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -1243,36 +1243,6 @@ variable [Fintype n] [DecidableEq n] abbrev toEuclideanLin : Matrix m n 𝕜 ≃ₗ[𝕜] EuclideanSpace 𝕜 n →ₗ[𝕜] EuclideanSpace 𝕜 m := toLpLin 2 2 -@[deprecated toLpLin_toLp (since := "2026-01-22")] -lemma toEuclideanLin_toLp (A : Matrix m n 𝕜) (x : n → 𝕜) : - Matrix.toEuclideanLin A (toLp _ x) = toLp _ (Matrix.toLin' A x) := rfl - -@[deprecated ofLp_toLpLin (since := "2026-01-22")] -theorem piLp_ofLp_toEuclideanLin (A : Matrix m n 𝕜) (x : EuclideanSpace 𝕜 n) : - ofLp (Matrix.toEuclideanLin A x) = Matrix.toLin' A (ofLp x) := - rfl - -@[deprecated toLpLin_apply (since := "2026-01-22")] -theorem toEuclideanLin_apply (M : Matrix m n 𝕜) (v : EuclideanSpace 𝕜 n) : - toEuclideanLin M v = toLp _ (M *ᵥ ofLp v) := rfl - -@[deprecated ofLp_toLpLin (since := "2026-01-22")] -theorem ofLp_toEuclideanLin_apply (M : Matrix m n 𝕜) (v : EuclideanSpace 𝕜 n) : - ofLp (toEuclideanLin M v) = M *ᵥ ofLp v := - rfl - -@[deprecated toLpLin_toLp (since := "2026-01-22")] -theorem toEuclideanLin_apply_piLp_toLp (M : Matrix m n 𝕜) (v : n → 𝕜) : - toEuclideanLin M (toLp _ v) = toLp _ (M *ᵥ v) := - rfl - --- `Matrix.toEuclideanLin` is the same as `Matrix.toLin` applied to `PiLp.basisFun`, -@[deprecated toLpLin_eq_toLin (since := "2026-01-22")] -theorem toEuclideanLin_eq_toLin [Finite m] : - (toEuclideanLin : Matrix m n 𝕜 ≃ₗ[𝕜] _) = - Matrix.toLin (PiLp.basisFun _ _ _) (PiLp.basisFun _ _ _) := - rfl - open EuclideanSpace in lemma toEuclideanLin_eq_toLin_orthonormal [Fintype m] : toEuclideanLin = toLin (basisFun n 𝕜).toBasis (basisFun m 𝕜).toBasis := @@ -1299,9 +1269,6 @@ theorem LinearMap.toMatrix_innerₛₗ_apply [Fintype n] [DecidableEq n] [Fintyp (innerₛₗ 𝕜 x).toMatrix b.toBasis b₂.toBasis = vecMulVec (star b₂) (star (b.repr x)) := by ext; simp [LinearMap.toMatrix_apply, vecMulVec_apply, OrthonormalBasis.repr_apply_apply, mul_comm] -@[deprecated (since := "2026-01-03")] alias toMatrix_innerSL_apply := - LinearMap.toMatrix_innerₛₗ_apply - end Matrix open ContinuousLinearMap LinearMap in diff --git a/Mathlib/Analysis/LocallyConvex/Barrelled.lean b/Mathlib/Analysis/LocallyConvex/Barrelled.lean index a9614fc00d3fba..e81095b92226be 100644 --- a/Mathlib/Analysis/LocallyConvex/Barrelled.lean +++ b/Mathlib/Analysis/LocallyConvex/Barrelled.lean @@ -226,27 +226,4 @@ def continuousLinearMapOfTendsto end PolynormableSpace -section Deprecated - -variable [UniformSpace E] [UniformSpace F] [IsUniformAddGroup E] [IsUniformAddGroup F] - [ContinuousSMul 𝕜₁ E] [BarrelledSpace 𝕜₁ E] [ContinuousSMul 𝕜₂ F] {𝓕 : ι → E →SL[σ₁₂] F} - {q : SeminormFamily 𝕜₂ F κ} (hq : WithSeminorms q) -include hq - -/-- Given a sequence of continuous linear maps which converges pointwise and for which the -domain is barrelled, the Banach-Steinhaus theorem is used to guarantee that the limit map -is a *continuous* linear map as well. - -This actually works for any *countably generated* filter instead of `atTop : Filter ℕ`, -but the proof ultimately goes back to sequences. -/ -@[deprecated continuousLinearMapOfTendsto (since := "2026-01-16")] -protected abbrev WithSeminorms.continuousLinearMapOfTendsto [T2Space F] {l : Filter α} - [l.IsCountablyGenerated] [l.NeBot] (g : α → E →SL[σ₁₂] F) {f : E → F} - (h : Tendsto (fun n x ↦ g n x) l (𝓝 f)) : - E →SL[σ₁₂] F := - haveI : PolynormableSpace 𝕜₂ F := hq.toPolynormableSpace - continuousLinearMapOfTendsto g h - -end Deprecated - end TVS_anyField diff --git a/Mathlib/Analysis/Matrix/Spectrum.lean b/Mathlib/Analysis/Matrix/Spectrum.lean index 9d663107693060..38c25d4a202d87 100644 --- a/Mathlib/Analysis/Matrix/Spectrum.lean +++ b/Mathlib/Analysis/Matrix/Spectrum.lean @@ -41,11 +41,6 @@ theorem spectrum_toLpLin [DecidableEq n] (p : ENNReal) : spectrum 𝕜 (toLpLin p p A) = spectrum 𝕜 A := AlgEquiv.spectrum_eq (Matrix.toLinAlgEquiv (PiLp.basisFun p 𝕜 n)) _ -/-- The spectrum of a matrix `A` coincides with the spectrum of `toEuclideanLin A`. -/ -@[deprecated spectrum_toLpLin (since := "2026-01-21")] -theorem spectrum_toEuclideanLin [DecidableEq n] : spectrum 𝕜 (toEuclideanLin A) = spectrum 𝕜 A := - spectrum_toLpLin 2 - namespace IsHermitian section DecidableEq diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index 0e3933a6fd8ffc..5013d184f41d6e 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -640,12 +640,6 @@ lemma enorm_div_rev {E : Type*} [SeminormedGroup E] (a b : E) : ‖a / b‖ₑ = theorem mem_eball_one_iff {r : ℝ≥0∞} : a ∈ eball 1 r ↔ ‖a‖ₑ < r := by rw [Metric.mem_eball, edist_one_right] -@[deprecated (since := "2026-01-24")] -alias mem_emetric_ball_zero_iff := mem_eball_zero_iff - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias mem_emetric_ball_one_iff := mem_eball_one_iff - end ENorm section ESeminormedMonoid diff --git a/Mathlib/Analysis/Normed/Group/Pointwise.lean b/Mathlib/Analysis/Normed/Group/Pointwise.lean index 263bdd2a9378ce..882569ca94cf18 100644 --- a/Mathlib/Analysis/Normed/Group/Pointwise.lean +++ b/Mathlib/Analysis/Normed/Group/Pointwise.lean @@ -65,23 +65,10 @@ open EMetric theorem infEDist_inv_inv (x : E) (s : Set E) : infEDist x⁻¹ s⁻¹ = infEDist x s := by rw [← image_inv_eq_inv, infEDist_image isometry_inv] -@[deprecated (since := "2026-01-08")] -alias infEdist_neg_neg := infEDist_neg_neg - -@[to_additive existing, deprecated (since := "2026-01-08")] -alias infEdist_inv_inv := infEDist_inv_inv - - @[to_additive] theorem infEDist_inv (x : E) (s : Set E) : infEDist x⁻¹ s = infEDist x s⁻¹ := by rw [← infEDist_inv_inv, inv_inv] -@[deprecated (since := "2026-01-08")] -alias infEdist_neg := infEDist_neg - -@[to_additive existing, deprecated (since := "2026-01-08")] -alias infEdist_inv := infEDist_inv - @[to_additive] theorem ediam_mul_le (x y : Set E) : ediam (x * y) ≤ ediam x + ediam y := (LipschitzOnWith.ediam_image2_le (· * ·) _ _ diff --git a/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean b/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean index 4255404818da12..a8ca6f38fcbf99 100644 --- a/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean +++ b/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean @@ -62,8 +62,6 @@ theorem infEDist_smul₀ {c : 𝕜} (hc : c ≠ 0) (s : Set E) (x : E) : · have : (‖c‖₊ : ENNReal) ≠ 0 := by simp [hc] simp_rw [ENNReal.smul_def, smul_eq_mul, ENNReal.mul_iInf_of_ne this ENNReal.coe_ne_top] -@[deprecated (since := "2026-01-08")] alias infEdist_smul₀ := infEDist_smul₀ - theorem infDist_smul₀ {c : 𝕜} (hc : c ≠ 0) (s : Set E) (x : E) : Metric.infDist (c • x) (c • s) = ‖c‖ * Metric.infDist x s := by simp_rw [Metric.infDist, infEDist_smul₀ hc s, ENNReal.toReal_smul, NNReal.smul_def, coe_nnnorm, @@ -256,9 +254,6 @@ theorem infEDist_thickening (hδ : 0 < δ) (s : Set E) (x : E) : infEDist_lt_iff.2 ⟨_, mem_thickening_iff.2 ⟨_, hz, hyz⟩, edist_lt_ofReal.2 hxy⟩).trans_le ?_ rw [← ofReal_add hr.le hδ.le, sub_add_cancel, ofReal_coe_nnreal] -@[deprecated (since := "2026-01-08")] -alias infEdist_thickening := infEDist_thickening - @[simp] theorem thickening_thickening (hε : 0 < ε) (hδ : 0 < δ) (s : Set E) : thickening ε (thickening δ s) = thickening (ε + δ) s := @@ -289,9 +284,6 @@ theorem infEDist_cthickening (δ : ℝ) (s : Set E) (x : E) : · rw [cthickening_of_nonpos hδ, infEDist_closure, ofReal_of_nonpos hδ, tsub_zero] · rw [← closure_thickening hδ, infEDist_closure, infEDist_thickening hδ] -@[deprecated (since := "2026-01-08")] -alias infEdist_cthickening := infEDist_cthickening - @[simp] theorem thickening_cthickening (hε : 0 < ε) (hδ : 0 ≤ δ) (s : Set E) : thickening ε (cthickening δ s) = thickening (ε + δ) s := by diff --git a/Mathlib/Analysis/Normed/Order/Basic.lean b/Mathlib/Analysis/Normed/Order/Basic.lean deleted file mode 100644 index e76b7f4f1f0897..00000000000000 --- a/Mathlib/Analysis/Normed/Order/Basic.lean +++ /dev/null @@ -1,17 +0,0 @@ -/- -Copyright (c) 2020 Anatole Dedecker. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Anatole Dedecker, Yaël Dillies --/ -module -- shake: keep-all - -public import Mathlib.Analysis.Normed.Group.Basic - -/-! -# Ordered normed spaces - -In this file, we define classes for fields and groups that are both normed and ordered. -These are mostly useful to avoid diamonds during type class inference. --/ - -deprecated_module (since := "2026-01-16") diff --git a/Mathlib/Analysis/Normed/Unbundled/SeminormFromConst.lean b/Mathlib/Analysis/Normed/Unbundled/SeminormFromConst.lean index 86c4d3235960ae..075c6e7a2cb4c8 100644 --- a/Mathlib/Analysis/Normed/Unbundled/SeminormFromConst.lean +++ b/Mathlib/Analysis/Normed/Unbundled/SeminormFromConst.lean @@ -118,9 +118,6 @@ theorem tendsto_seminormFromConst_seq_atTop (x : R) : tendsto_atTop_ciInf (seminormFromConst_seq_antitone hf1 hc hpm x) (seminormFromConst_bddBelow c f x) -@[deprecated (since := "2026-01-14")] -alias seminormFromConst_isLimit := tendsto_seminormFromConst_seq_atTop - theorem seminormFromConst_one : seminormFromConst' c f 1 = 1 := by apply tendsto_nhds_unique_of_eventuallyEq (tendsto_seminormFromConst_seq_atTop hf1 hc hpm 1) tendsto_const_nhds diff --git a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean index 9735cf811ef79d..abd2c0a5c4b0a7 100644 --- a/Mathlib/Analysis/Polynomial/MahlerMeasure.lean +++ b/Mathlib/Analysis/Polynomial/MahlerMeasure.lean @@ -244,9 +244,6 @@ lemma leadingCoeff_le_mahlerMeasure (p : ℂ[X]) : ‖p.leadingCoeff‖ ≤ p.ma gcongr exact one_le_prod_max_one_norm_roots p -@[deprecated (since := "2026-01-02")] alias leading_coeff_le_mahlerMeasure := - leadingCoeff_le_mahlerMeasure - lemma prod_max_one_norm_roots_le_mahlerMeasure_of_one_le_leadingCoeff {p : ℂ[X]} (hlc : 1 ≤ ‖p.leadingCoeff‖) : (p.roots.map (fun a ↦ max 1 ‖a‖)).prod ≤ p.mahlerMeasure := by rw [← one_mul (Multiset.prod _), mahlerMeasure_eq_leadingCoeff_mul_prod_roots] diff --git a/Mathlib/Analysis/Real/Hyperreal.lean b/Mathlib/Analysis/Real/Hyperreal.lean index db619366ee763e..e176101e17f363 100644 --- a/Mathlib/Analysis/Real/Hyperreal.lean +++ b/Mathlib/Analysis/Real/Hyperreal.lean @@ -309,25 +309,6 @@ theorem epsilon_lt_of_pos {r : ℝ} : 0 < r → ε < r := theorem epsilon_lt_of_neg {r : ℝ} : r < 0 → r < ε := lt_of_neg_of_archimedean coeRingHom archimedeanClassMk_epsilon_pos -@[deprecated (since := "2026-01-05")] -alias epsilon_lt_pos := epsilon_lt_of_pos - -@[deprecated archimedeanClassMk_pos_of_tendsto (since := "2026-01-05")] -theorem lt_of_tendsto_zero_of_pos {f : ℕ → ℝ} (hf : Tendsto f atTop (𝓝 0)) : - ∀ {r : ℝ}, 0 < r → ofSeq f < (r : ℝ*) := fun hr ↦ - ofSeq_lt_ofSeq.2 <| (hf.eventually <| gt_mem_nhds hr).filter_mono Nat.hyperfilter_le_atTop - -@[deprecated archimedeanClassMk_pos_of_tendsto (since := "2026-01-05")] -theorem neg_lt_of_tendsto_zero_of_pos {f : ℕ → ℝ} (hf : Tendsto f atTop (𝓝 0)) : - ∀ {r : ℝ}, 0 < r → (-r : ℝ*) < ofSeq f := fun hr => - have hg := hf.neg - neg_lt_of_neg_lt (by rw [neg_zero] at hg; exact lt_of_tendsto_zero_of_pos hg hr) - -@[deprecated archimedeanClassMk_pos_of_tendsto (since := "2026-01-05")] -theorem gt_of_tendsto_zero_of_neg {f : ℕ → ℝ} (hf : Tendsto f atTop (𝓝 0)) : - ∀ {r : ℝ}, r < 0 → (r : ℝ*) < ofSeq f := fun {r} hr => by - rw [← neg_neg r, coe_neg]; exact neg_lt_of_tendsto_zero_of_pos hf (neg_pos.mpr hr) - theorem lt_of_tendsto_atTop {x : ℝ*} (r : ℝ) (hx : x.Tendsto atTop) : r < x := by rcases ofSeq_surjective x with ⟨f, rfl⟩ rw [tendsto_ofSeq] at hx @@ -364,681 +345,6 @@ theorem tendsto_atBot_iff {x : ℝ*} : x.Tendsto atBot ↔ x < 0 ∧ mk x < 0 wh exact fun r ↦ ofSeq_le_ofSeq.1 <| (lt_of_mk_lt_mk_of_nonpos (h.2.trans_le <| archimedeanClassMk_coe_nonneg r) h.1.le).le -/-- Standard part predicate. -**Do not use.** This is equivalent to the conjunction of `0 ≤ ArchimedeanClass.mk x` and -`ArchimedeanClass.stdPart x = r`. -/ -@[deprecated stdPart (since := "2026-01-05")] -def IsSt (x : ℝ*) (r : ℝ) := - ∀ δ : ℝ, 0 < δ → (r - δ : ℝ*) < x ∧ x < r + δ - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_iff {x r} : IsSt x r ↔ 0 ≤ mk x ∧ stdPart x = r where - mp h := by - refine ⟨?_, stdPart_eq coeRingHom (fun s hs ↦ ?_) (fun s hs ↦ ?_)⟩ - · have h := h 1 zero_lt_one - exact mk_nonneg_of_le_of_le_of_archimedean coeRingHom h.1.le h.2.le - · simpa using (h _ (sub_pos_of_lt hs)).1.le - · simpa using (h _ (sub_pos_of_lt hs)).2.le - mpr h := by - obtain ⟨h, rfl⟩ := h - refine fun y hy ↦ ⟨?_, ?_⟩ - · apply lt_of_lt_stdPart coeRingHom h; simpa - · apply lt_of_stdPart_lt coeRingHom h; simpa - -open scoped Classical in -/-- Standard part function: like a "round" to ℝ instead of ℤ -/ -@[deprecated stdPart (since := "2026-01-05")] -noncomputable def st : ℝ* → ℝ := fun x => if h : ∃ r, IsSt x r then Classical.choose h else 0 - -@[deprecated "`st` is deprecated" (since := "2026-01-05")] -theorem st_eq (x : ℝ*) : st x = stdPart x := by - rw [st] - split_ifs with h - · exact (isSt_iff.1 (Classical.choose_spec h)).2.symm - · simp_rw [isSt_iff] at h - push Not at h - rw [eq_comm, stdPart_eq_zero] - apply ne_of_lt - by_contra! hx - exact h _ hx rfl - -/-- A hyperreal number is infinitesimal if its standard part is 0. -**Do not use.** Write `0 < ArchimedeanClass.mk x` instead. -/ -@[deprecated ArchimedeanClass.mk (since := "2026-01-05")] -def Infinitesimal (x : ℝ*) := - IsSt x 0 - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_iff {x : ℝ*} : Infinitesimal x ↔ 0 < mk x := by - rw [Infinitesimal, isSt_iff, stdPart_eq_zero, lt_iff_le_and_ne'] - -/-- A hyperreal number is positive infinite if it is larger than all real numbers. -**Do not use.** Write `0 < x ∧ ArchimedeanClass.mk x < 0` instead. -/ -@[deprecated ArchimedeanClass.mk (since := "2026-01-05")] -def InfinitePos (x : ℝ*) := - ∀ r : ℝ, ↑r < x - -@[deprecated "`InfinitePos` is deprecated" (since := "2026-01-05")] -theorem infinitePos_iff {x : ℝ*} : InfinitePos x ↔ 0 < x ∧ mk x < 0 := by - refine ⟨fun h ↦ ?_, fun ⟨hx, hx'⟩ r ↦ ?_⟩ - · have hx : 0 < x := h 0 - refine ⟨h 0, fun n ↦ ?_⟩ - simpa [abs_of_pos hx] using! h n - · exact lt_of_mk_lt_mk_of_nonneg (hx'.trans_le <| mk_map_nonneg_of_archimedean coeRingHom _) hx.le - -/-- A hyperreal number is negative infinite if it is smaller than all real numbers. -**Do not use.** Write `x < 0 ∧ ArchimedeanClass.mk x < 0` instead. -/ -@[deprecated ArchimedeanClass.mk (since := "2026-01-05")] -def InfiniteNeg (x : ℝ*) := - ∀ r : ℝ, x < r - -@[deprecated "`InfiniteNeg` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_iff {x : ℝ*} : InfiniteNeg x ↔ x < 0 ∧ mk x < 0 := by - refine ⟨fun h ↦ ?_, fun ⟨hx, hx'⟩ r ↦ ?_⟩ - · have hx : x < 0 := h 0 - refine ⟨h 0, fun n ↦ ?_⟩ - simpa [abs_of_neg hx, lt_neg] using! h (-n) - · exact lt_of_mk_lt_mk_of_nonpos (hx'.trans_le <| mk_map_nonneg_of_archimedean coeRingHom _) hx.le - -/-- A hyperreal number is infinite if it is infinite positive or infinite negative. -**Do not use.** Write `ArchimedeanClass.mk x < 0` instead. -/ -@[deprecated ArchimedeanClass.mk (since := "2026-01-05")] -def Infinite (x : ℝ*) := - InfinitePos x ∨ InfiniteNeg x - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinite_iff {x : ℝ*} : Infinite x ↔ mk x < 0 := by - rw [Infinite, infinitePos_iff, infiniteNeg_iff] - aesop - -@[deprecated tendsto_iff_forall (since := "2026-01-05")] -theorem isSt_ofSeq_iff_tendsto {f : ℕ → ℝ} {r : ℝ} : - IsSt (ofSeq f) r ↔ Tendsto f (hyperfilter ℕ) (𝓝 r) := - Iff.trans (forall₂_congr fun _ _ ↦ (ofSeq_lt_ofSeq.and ofSeq_lt_ofSeq).trans eventually_and.symm) - (nhds_basis_Ioo_pos _).tendsto_right_iff.symm - -@[deprecated tendsto_iff_forall (since := "2026-01-05")] -theorem isSt_iff_tendsto {x : ℝ*} {r : ℝ} : IsSt x r ↔ x.Tendsto (𝓝 r) := by - rcases ofSeq_surjective x with ⟨f, rfl⟩ - exact isSt_ofSeq_iff_tendsto - -@[deprecated stdPart_of_tendsto (since := "2026-01-05")] -theorem isSt_of_tendsto {f : ℕ → ℝ} {r : ℝ} (hf : Tendsto f atTop (𝓝 r)) : IsSt (ofSeq f) r := - isSt_ofSeq_iff_tendsto.2 <| hf.mono_left Nat.hyperfilter_le_atTop - -@[deprecated "Use `stdPart_monotoneOn` and `MonotoneOn.reflect_lt`" (since := "2026-01-05")] -protected theorem IsSt.lt {x y : ℝ*} {r s : ℝ} (hxr : IsSt x r) (hys : IsSt y s) (hrs : r < s) : - x < y := by - rcases ofSeq_surjective x with ⟨f, rfl⟩ - rcases ofSeq_surjective y with ⟨g, rfl⟩ - rw [isSt_ofSeq_iff_tendsto] at hxr hys - exact ofSeq_lt_ofSeq.2 <| hxr.eventually_lt hys hrs - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem IsSt.unique {x : ℝ*} {r s : ℝ} (hr : IsSt x r) (hs : IsSt x s) : r = s := by - rcases ofSeq_surjective x with ⟨f, rfl⟩ - rw [isSt_ofSeq_iff_tendsto] at hr hs - exact tendsto_nhds_unique hr hs - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem IsSt.st_eq {x : ℝ*} {r : ℝ} (hxr : IsSt x r) : st x = r := by - have h : ∃ r, IsSt x r := ⟨r, hxr⟩ - rw [st, dite_eq_left h] - exact (Classical.choose_spec h).unique hxr - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem IsSt.not_infinite {x : ℝ*} {r : ℝ} (h : IsSt x r) : ¬Infinite x := fun hi ↦ - hi.elim (fun hp ↦ lt_asymm (h 1 one_pos).2 (hp (r + 1))) fun hn ↦ - lt_asymm (h 1 one_pos).1 (hn (r - 1)) - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem not_infinite_of_exists_st {x : ℝ*} : (∃ r : ℝ, IsSt x r) → ¬Infinite x := fun ⟨_r, hr⟩ => - hr.not_infinite - -@[deprecated stdPart_eq_zero (since := "2026-01-05")] -theorem Infinite.st_eq {x : ℝ*} (hi : Infinite x) : st x = 0 := - dite_eq_right fun ⟨_r, hr⟩ ↦ hr.not_infinite hi - -@[deprecated stdPart_eq_sSup (since := "2026-01-05")] -theorem isSt_sSup {x : ℝ*} (hni : ¬Infinite x) : IsSt x (sSup { y : ℝ | (y : ℝ*) < x }) := by - rw [infinite_iff, not_lt] at hni - rw [isSt_iff] - exact ⟨hni, stdPart_eq_sSup coeRingHom x⟩ - -@[deprecated stdPart_eq_sSup (since := "2026-01-05")] -theorem exists_st_of_not_infinite {x : ℝ*} (hni : ¬Infinite x) : ∃ r : ℝ, IsSt x r := - ⟨sSup { y : ℝ | (y : ℝ*) < x }, isSt_sSup hni⟩ - -@[deprecated stdPart_eq_sSup (since := "2026-01-05")] -theorem st_eq_sSup {x : ℝ*} : st x = sSup { y : ℝ | (y : ℝ*) < x } := by - rw [st_eq] - exact stdPart_eq_sSup coeRingHom x - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem exists_st_iff_not_infinite {x : ℝ*} : (∃ r : ℝ, IsSt x r) ↔ ¬Infinite x := - ⟨not_infinite_of_exists_st, exists_st_of_not_infinite⟩ - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem infinite_iff_not_exists_st {x : ℝ*} : Infinite x ↔ ¬∃ r : ℝ, IsSt x r := - iff_not_comm.mp exists_st_iff_not_infinite - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem IsSt.isSt_st {x : ℝ*} {r : ℝ} (hxr : IsSt x r) : IsSt x (st x) := by - rwa [hxr.st_eq] - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_st_of_exists_st {x : ℝ*} (hx : ∃ r : ℝ, IsSt x r) : IsSt x (st x) := - let ⟨_r, hr⟩ := hx; hr.isSt_st - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_st' {x : ℝ*} (hx : ¬Infinite x) : IsSt x (st x) := - (isSt_sSup hx).isSt_st - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_st {x : ℝ*} (hx : st x ≠ 0) : IsSt x (st x) := - isSt_st' <| mt Infinite.st_eq hx - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_refl_real (r : ℝ) : IsSt r r := isSt_ofSeq_iff_tendsto.2 tendsto_const_nhds - -@[deprecated stdPart_coe (since := "2026-01-05")] -theorem st_id_real (r : ℝ) : st r = r := (isSt_refl_real r).st_eq - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem eq_of_isSt_real {r s : ℝ} : IsSt r s → r = s := - (isSt_refl_real r).unique - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_real_iff_eq {r s : ℝ} : IsSt r s ↔ r = s := - ⟨eq_of_isSt_real, fun hrs => hrs ▸ isSt_refl_real r⟩ - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_symm_real {r s : ℝ} : IsSt r s ↔ IsSt s r := by - rw [isSt_real_iff_eq, isSt_real_iff_eq, eq_comm] - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_trans_real {r s t : ℝ} : IsSt r s → IsSt s t → IsSt r t := by - rw [isSt_real_iff_eq, isSt_real_iff_eq, isSt_real_iff_eq]; exact Eq.trans - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_inj_real {r₁ r₂ s : ℝ} (h1 : IsSt r₁ s) (h2 : IsSt r₂ s) : r₁ = r₂ := - Eq.trans (eq_of_isSt_real h1) (eq_of_isSt_real h2).symm - -@[deprecated "`IsSt` is deprecated" (since := "2026-01-05")] -theorem isSt_iff_abs_sub_lt_delta {x : ℝ*} {r : ℝ} : IsSt x r ↔ ∀ δ : ℝ, 0 < δ → |x - ↑r| < δ := by - simp only [abs_sub_lt_iff, sub_lt_iff_lt_add, IsSt, and_comm, add_comm] - -@[deprecated stdPart_map (since := "2026-01-05")] -theorem IsSt.map {x : ℝ*} {r : ℝ} (hxr : IsSt x r) {f : ℝ → ℝ} (hf : ContinuousAt f r) : - IsSt (x.map f) (f r) := by - rcases ofSeq_surjective x with ⟨g, rfl⟩ - exact isSt_ofSeq_iff_tendsto.2 <| hf.tendsto.comp (isSt_ofSeq_iff_tendsto.1 hxr) - -@[deprecated stdPart_map₂ (since := "2026-01-05")] -theorem IsSt.map₂ {x y : ℝ*} {r s : ℝ} (hxr : IsSt x r) (hys : IsSt y s) {f : ℝ → ℝ → ℝ} - (hf : ContinuousAt (Function.uncurry f) (r, s)) : IsSt (x.map₂ f y) (f r s) := by - rcases ofSeq_surjective x with ⟨x, rfl⟩ - rcases ofSeq_surjective y with ⟨y, rfl⟩ - rw [isSt_ofSeq_iff_tendsto] at hxr hys - exact isSt_ofSeq_iff_tendsto.2 <| hf.tendsto.comp (hxr.prodMk_nhds hys) - -@[deprecated stdPart_add (since := "2026-01-05")] -theorem IsSt.add {x y : ℝ*} {r s : ℝ} (hxr : IsSt x r) (hys : IsSt y s) : - IsSt (x + y) (r + s) := hxr.map₂ hys continuous_add.continuousAt - -@[deprecated stdPart_neg (since := "2026-01-05")] -theorem IsSt.neg {x : ℝ*} {r : ℝ} (hxr : IsSt x r) : IsSt (-x) (-r) := - hxr.map continuous_neg.continuousAt - -@[deprecated stdPart_sub (since := "2026-01-05")] -theorem IsSt.sub {x y : ℝ*} {r s : ℝ} (hxr : IsSt x r) (hys : IsSt y s) : IsSt (x - y) (r - s) := - hxr.map₂ hys continuous_sub.continuousAt - -@[deprecated stdPart_monotoneOn (since := "2026-01-05")] -theorem IsSt.le {x y : ℝ*} {r s : ℝ} (hrx : IsSt x r) (hsy : IsSt y s) (hxy : x ≤ y) : r ≤ s := - not_lt.1 fun h ↦ hxy.not_gt <| hsy.lt hrx h - -@[deprecated stdPart_monotoneOn (since := "2026-01-05")] -theorem st_le_of_le {x y : ℝ*} (hix : ¬Infinite x) (hiy : ¬Infinite y) : x ≤ y → st x ≤ st y := - (isSt_st' hix).le (isSt_st' hiy) - -@[deprecated stdPart_monotoneOn (since := "2026-01-05")] -theorem lt_of_st_lt {x y : ℝ*} (hix : ¬Infinite x) (hiy : ¬Infinite y) : st x < st y → x < y := - (isSt_st' hix).lt (isSt_st' hiy) - -@[deprecated "`InfinitePos` is deprecated" (since := "2026-01-05")] -theorem infinitePos_def {x : ℝ*} : InfinitePos x ↔ ∀ r : ℝ, ↑r < x := Iff.rfl - -@[deprecated "`InfiniteNeg` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_def {x : ℝ*} : InfiniteNeg x ↔ ∀ r : ℝ, x < r := Iff.rfl - -@[deprecated "`InfinitePos` is deprecated" (since := "2026-01-05")] -theorem InfinitePos.pos {x : ℝ*} (hip : InfinitePos x) : 0 < x := hip 0 - -@[deprecated "`InfiniteNeg` is deprecated" (since := "2026-01-05")] -theorem InfiniteNeg.lt_zero {x : ℝ*} : InfiniteNeg x → x < 0 := fun hin => hin 0 - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem Infinite.ne_zero {x : ℝ*} (hI : Infinite x) : x ≠ 0 := - hI.elim (fun hip => hip.pos.ne') fun hin => hin.lt_zero.ne - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem not_infinite_zero : ¬Infinite 0 := fun hI => hI.ne_zero rfl - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem InfiniteNeg.not_infinitePos {x : ℝ*} : InfiniteNeg x → ¬InfinitePos x := fun hn hp => - (hn 0).not_gt (hp 0) - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem InfinitePos.not_infiniteNeg {x : ℝ*} (hp : InfinitePos x) : ¬InfiniteNeg x := fun hn ↦ - hn.not_infinitePos hp - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem InfinitePos.neg {x : ℝ*} : InfinitePos x → InfiniteNeg (-x) := fun hp r => - neg_lt.mp (hp (-r)) - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem InfiniteNeg.neg {x : ℝ*} : InfiniteNeg x → InfinitePos (-x) := fun hp r => - lt_neg.mp (hp (-r)) - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem infiniteNeg_neg {x : ℝ*} : InfiniteNeg (-x) ↔ InfinitePos x := - ⟨fun hin => neg_neg x ▸ hin.neg, InfinitePos.neg⟩ - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem infinitePos_neg {x : ℝ*} : InfinitePos (-x) ↔ InfiniteNeg x := - ⟨fun hin => neg_neg x ▸ hin.neg, InfiniteNeg.neg⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinite_neg {x : ℝ*} : Infinite (-x) ↔ Infinite x := - or_comm.trans <| infiniteNeg_neg.or infinitePos_neg - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -nonrec theorem Infinitesimal.not_infinite {x : ℝ*} (h : Infinitesimal x) : ¬Infinite x := - h.not_infinite - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem Infinite.not_infinitesimal {x : ℝ*} (h : Infinite x) : ¬Infinitesimal x := fun h' ↦ - h'.not_infinite h - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem InfinitePos.not_infinitesimal {x : ℝ*} (h : InfinitePos x) : ¬Infinitesimal x := - Infinite.not_infinitesimal (Or.inl h) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem InfiniteNeg.not_infinitesimal {x : ℝ*} (h : InfiniteNeg x) : ¬Infinitesimal x := - Infinite.not_infinitesimal (Or.inr h) - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinitePos_iff_infinite_and_pos {x : ℝ*} : InfinitePos x ↔ Infinite x ∧ 0 < x := - ⟨fun hip => ⟨Or.inl hip, hip 0⟩, fun ⟨hi, hp⟩ => - hi.casesOn id fun hin => False.elim (not_lt_of_gt hp (hin 0))⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_iff_infinite_and_neg {x : ℝ*} : InfiniteNeg x ↔ Infinite x ∧ x < 0 := - ⟨fun hip => ⟨Or.inr hip, hip 0⟩, fun ⟨hi, hp⟩ => - hi.casesOn (fun hin => False.elim (not_lt_of_gt hp (hin 0))) fun hip => hip⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinitePos_iff_infinite_of_nonneg {x : ℝ*} (hp : 0 ≤ x) : InfinitePos x ↔ Infinite x := - .symm <| or_iff_left fun h ↦ h.lt_zero.not_ge hp - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinitePos_iff_infinite_of_pos {x : ℝ*} (hp : 0 < x) : InfinitePos x ↔ Infinite x := - infinitePos_iff_infinite_of_nonneg hp.le - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_iff_infinite_of_neg {x : ℝ*} (hn : x < 0) : InfiniteNeg x ↔ Infinite x := - .symm <| or_iff_right fun h ↦ h.pos.not_gt hn - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinitePos_abs_iff_infinite_abs {x : ℝ*} : InfinitePos |x| ↔ Infinite |x| := - infinitePos_iff_infinite_of_nonneg (abs_nonneg _) - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinite_abs_iff {x : ℝ*} : Infinite |x| ↔ Infinite x := by - cases le_total 0 x <;> simp [*, abs_of_nonneg, abs_of_nonpos, infinite_neg] - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinitePos_abs_iff_infinite {x : ℝ*} : InfinitePos |x| ↔ Infinite x := - infinitePos_abs_iff_infinite_abs.trans infinite_abs_iff - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinite_iff_abs_lt_abs {x : ℝ*} : Infinite x ↔ ∀ r : ℝ, (|r| : ℝ*) < |x| := - infinitePos_abs_iff_infinite.symm.trans ⟨fun hI r => coe_abs r ▸ hI |r|, fun hR r => - (le_abs_self _).trans_lt (hR r)⟩ - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem infinitePos_add_not_infiniteNeg {x y : ℝ*} : - InfinitePos x → ¬InfiniteNeg y → InfinitePos (x + y) := by - intro hip hnin r - obtain ⟨r₂, hr₂⟩ := not_forall.mp hnin - convert! add_lt_add_of_lt_of_le (hip (r + -r₂)) (not_lt.mp hr₂) using 1 - simp - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem not_infiniteNeg_add_infinitePos {x y : ℝ*} : - ¬InfiniteNeg x → InfinitePos y → InfinitePos (x + y) := fun hx hy => - add_comm y x ▸ infinitePos_add_not_infiniteNeg hy hx - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem infiniteNeg_add_not_infinitePos {x y : ℝ*} : - InfiniteNeg x → ¬InfinitePos y → InfiniteNeg (x + y) := by - rw [← infinitePos_neg, ← infinitePos_neg, ← @infiniteNeg_neg y, neg_add] - exact infinitePos_add_not_infiniteNeg - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem not_infinitePos_add_infiniteNeg {x y : ℝ*} : - ¬InfinitePos x → InfiniteNeg y → InfiniteNeg (x + y) := fun hx hy => - add_comm y x ▸ infiniteNeg_add_not_infinitePos hy hx - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem infinitePos_add_infinitePos {x y : ℝ*} : - InfinitePos x → InfinitePos y → InfinitePos (x + y) := fun hx hy => - infinitePos_add_not_infiniteNeg hx hy.not_infiniteNeg - -@[deprecated "`InfinitePos` and `InfiniteNeg` are deprecated" (since := "2026-01-05")] -theorem infiniteNeg_add_infiniteNeg {x y : ℝ*} : - InfiniteNeg x → InfiniteNeg y → InfiniteNeg (x + y) := fun hx hy => - infiniteNeg_add_not_infinitePos hx hy.not_infinitePos - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infinitePos_add_not_infinite {x y : ℝ*} : - InfinitePos x → ¬Infinite y → InfinitePos (x + y) := fun hx hy => - infinitePos_add_not_infiniteNeg hx (not_or.mp hy).2 - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_add_not_infinite {x y : ℝ*} : - InfiniteNeg x → ¬Infinite y → InfiniteNeg (x + y) := fun hx hy => - infiniteNeg_add_not_infinitePos hx (not_or.mp hy).1 - -@[deprecated "`InfinitePos` is deprecated" (since := "2026-01-05")] -theorem infinitePos_of_tendsto_top {f : ℕ → ℝ} (hf : Tendsto f atTop atTop) : - InfinitePos (ofSeq f) := by - replace hf := hf.mono_left Nat.hyperfilter_le_atTop - rw [infinitePos_iff] - exact ⟨lt_of_tendsto_atTop 0 hf, archimedeanClassMk_neg_of_tendsto_atTop hf⟩ - -@[deprecated "`InfiniteNeg` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_of_tendsto_bot {f : ℕ → ℝ} (hf : Tendsto f atTop atBot) : - InfiniteNeg (ofSeq f) := by - replace hf := hf.mono_left Nat.hyperfilter_le_atTop - rw [infiniteNeg_iff] - exact ⟨lt_of_tendsto_atBot 0 hf, archimedeanClassMk_neg_of_tendsto_atBot hf⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem not_infinite_neg {x : ℝ*} : ¬Infinite x → ¬Infinite (-x) := mt infinite_neg.mp - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem not_infinite_add {x y : ℝ*} (hx : ¬Infinite x) (hy : ¬Infinite y) : ¬Infinite (x + y) := - have ⟨r, hr⟩ := exists_st_of_not_infinite hx - have ⟨s, hs⟩ := exists_st_of_not_infinite hy - not_infinite_of_exists_st <| ⟨r + s, hr.add hs⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem not_infinite_iff_exist_lt_gt {x : ℝ*} : ¬Infinite x ↔ ∃ r s : ℝ, (r : ℝ*) < x ∧ x < s := - ⟨fun hni ↦ let ⟨r, hr⟩ := exists_st_of_not_infinite hni; ⟨r - 1, r + 1, hr 1 one_pos⟩, - fun ⟨r, s, hr, hs⟩ hi ↦ hi.elim (fun hp ↦ (hp s).not_gt hs) (fun hn ↦ (hn r).not_gt hr)⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem not_infinite_real (r : ℝ) : ¬Infinite r := by - rw [not_infinite_iff_exist_lt_gt] - exact ⟨r - 1, r + 1, coe_lt_coe.2 <| sub_one_lt r, coe_lt_coe.2 <| lt_add_one r⟩ - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem Infinite.ne_real {x : ℝ*} : Infinite x → ∀ r : ℝ, x ≠ r := fun hi r hr => - not_infinite_real r <| @Eq.subst _ Infinite _ _ hr hi - -/-! -### Facts about `st` that require some infinite machinery --/ - -@[deprecated stdPart_mul (since := "2026-01-05")] -theorem IsSt.mul {x y : ℝ*} {r s : ℝ} (hxr : IsSt x r) (hys : IsSt y s) : IsSt (x * y) (r * s) := - hxr.map₂ hys continuous_mul.continuousAt - -@[deprecated mk_mul (since := "2026-01-05")] -theorem not_infinite_mul {x y : ℝ*} (hx : ¬Infinite x) (hy : ¬Infinite y) : ¬Infinite (x * y) := - have ⟨_r, hr⟩ := exists_st_of_not_infinite hx - have ⟨_s, hs⟩ := exists_st_of_not_infinite hy - (hr.mul hs).not_infinite - -@[deprecated stdPart_add (since := "2026-01-05")] -theorem st_add {x y : ℝ*} (hx : ¬Infinite x) (hy : ¬Infinite y) : st (x + y) = st x + st y := - (isSt_st' (not_infinite_add hx hy)).unique ((isSt_st' hx).add (isSt_st' hy)) - -@[deprecated stdPart_neg (since := "2026-01-05")] -theorem st_neg (x : ℝ*) : st (-x) = -st x := by - by_cases h : Infinite x - · rw [h.st_eq, (infinite_neg.2 h).st_eq, neg_zero] - · exact (isSt_st' (not_infinite_neg h)).unique (isSt_st' h).neg - -@[deprecated stdPart_mul (since := "2026-01-05")] -theorem st_mul {x y : ℝ*} (hx : ¬Infinite x) (hy : ¬Infinite y) : st (x * y) = st x * st y := - have hx' := isSt_st' hx - have hy' := isSt_st' hy - have hxy := isSt_st' (not_infinite_mul hx hy) - hxy.unique (hx'.mul hy') - -/-! -### Basic lemmas about infinitesimal --/ - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_def {x : ℝ*} : Infinitesimal x ↔ ∀ r : ℝ, 0 < r → -(r : ℝ*) < x ∧ x < r := by - simp [Infinitesimal, IsSt] - -@[deprecated lt_of_pos_of_archimedean (since := "2026-01-05")] -theorem lt_of_pos_of_infinitesimal {x : ℝ*} : Infinitesimal x → ∀ r : ℝ, 0 < r → x < r := - fun hi r hr => ((infinitesimal_def.mp hi) r hr).2 - -@[deprecated lt_of_neg_of_archimedean (since := "2026-01-05")] -theorem lt_neg_of_pos_of_infinitesimal {x : ℝ*} : Infinitesimal x → ∀ r : ℝ, 0 < r → -↑r < x := - fun hi r hr => ((infinitesimal_def.mp hi) r hr).1 - -@[deprecated lt_of_neg_of_archimedean (since := "2026-01-05")] -theorem gt_of_neg_of_infinitesimal {x : ℝ*} (hi : Infinitesimal x) (r : ℝ) (hr : r < 0) : ↑r < x := - neg_neg r ▸ (infinitesimal_def.1 hi (-r) (neg_pos.2 hr)).1 - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem abs_lt_real_iff_infinitesimal {x : ℝ*} : Infinitesimal x ↔ ∀ r : ℝ, r ≠ 0 → |x| < |↑r| := - ⟨fun hi r hr ↦ abs_lt.mpr (coe_abs r ▸ infinitesimal_def.mp hi |r| (abs_pos.2 hr)), fun hR ↦ - infinitesimal_def.mpr fun r hr => abs_lt.mp <| (abs_of_pos <| coe_pos.2 hr) ▸ hR r <| hr.ne'⟩ - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_zero : Infinitesimal 0 := isSt_refl_real 0 - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem Infinitesimal.eq_zero {r : ℝ} : Infinitesimal r → r = 0 := eq_of_isSt_real - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_real_iff {r : ℝ} : Infinitesimal r ↔ r = 0 := - isSt_real_iff_eq - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -nonrec theorem Infinitesimal.add {x y : ℝ*} (hx : Infinitesimal x) (hy : Infinitesimal y) : - Infinitesimal (x + y) := by simpa only [add_zero] using! hx.add hy - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -nonrec theorem Infinitesimal.neg {x : ℝ*} (hx : Infinitesimal x) : Infinitesimal (-x) := by - simpa only [neg_zero] using! hx.neg - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_neg {x : ℝ*} : Infinitesimal (-x) ↔ Infinitesimal x := - ⟨fun h => neg_neg x ▸ h.neg, Infinitesimal.neg⟩ - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -nonrec theorem Infinitesimal.mul {x y : ℝ*} (hx : Infinitesimal x) (hy : Infinitesimal y) : - Infinitesimal (x * y) := by simpa only [mul_zero] using! hx.mul hy - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_of_tendsto_zero {f : ℕ → ℝ} (h : Tendsto f atTop (𝓝 0)) : - Infinitesimal (ofSeq f) := - isSt_of_tendsto h - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_epsilon : Infinitesimal ε := - infinitesimal_of_tendsto_zero tendsto_inv_atTop_nhds_zero_nat - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem not_real_of_infinitesimal_ne_zero (x : ℝ*) : Infinitesimal x → x ≠ 0 → ∀ r : ℝ, x ≠ r := - fun hi hx r hr => - hx <| hr.trans <| coe_eq_zero.2 <| IsSt.unique (hr.symm ▸ isSt_refl_real r : IsSt x r) hi - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem IsSt.infinitesimal_sub {x : ℝ*} {r : ℝ} (hxr : IsSt x r) : Infinitesimal (x - ↑r) := by - simpa only [sub_self] using! hxr.sub (isSt_refl_real r) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_sub_st {x : ℝ*} (hx : ¬Infinite x) : Infinitesimal (x - ↑(st x)) := - (isSt_st' hx).infinitesimal_sub - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_iff_infinitesimal_inv_pos {x : ℝ*} : - InfinitePos x ↔ Infinitesimal x⁻¹ ∧ 0 < x⁻¹ := by - rw [infinitePos_iff, infinitesimal_iff] - aesop - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_iff_infinitesimal_inv_neg {x : ℝ*} : - InfiniteNeg x ↔ Infinitesimal x⁻¹ ∧ x⁻¹ < 0 := by - rw [← infinitePos_neg, infinitePos_iff_infinitesimal_inv_pos, inv_neg, neg_pos, infinitesimal_neg] - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_inv_of_infinite {x : ℝ*} : Infinite x → Infinitesimal x⁻¹ := fun hi => - Or.casesOn hi (fun hip => (infinitePos_iff_infinitesimal_inv_pos.mp hip).1) fun hin => - (infiniteNeg_iff_infinitesimal_inv_neg.mp hin).1 - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinite_of_infinitesimal_inv {x : ℝ*} (h0 : x ≠ 0) (hi : Infinitesimal x⁻¹) : - Infinite x := by - rcases lt_or_gt_of_ne h0 with hn | hp - · exact Or.inr (infiniteNeg_iff_infinitesimal_inv_neg.mpr ⟨hi, inv_lt_zero.mpr hn⟩) - · exact Or.inl (infinitePos_iff_infinitesimal_inv_pos.mpr ⟨hi, inv_pos.mpr hp⟩) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinite_iff_infinitesimal_inv {x : ℝ*} (h0 : x ≠ 0) : Infinite x ↔ Infinitesimal x⁻¹ := - ⟨infinitesimal_inv_of_infinite, infinite_of_infinitesimal_inv h0⟩ - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_pos_iff_infinitePos_inv {x : ℝ*} : - InfinitePos x⁻¹ ↔ Infinitesimal x ∧ 0 < x := - infinitePos_iff_infinitesimal_inv_pos.trans <| by rw [inv_inv] - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_neg_iff_infiniteNeg_inv {x : ℝ*} : - InfiniteNeg x⁻¹ ↔ Infinitesimal x ∧ x < 0 := - infiniteNeg_iff_infinitesimal_inv_neg.trans <| by rw [inv_inv] - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitesimal_iff_infinite_inv {x : ℝ*} (h : x ≠ 0) : Infinitesimal x ↔ Infinite x⁻¹ := - Iff.trans (by rw [inv_inv]) (infinite_iff_infinitesimal_inv (inv_ne_zero h)).symm - -@[deprecated stdPart_inv (since := "2026-01-05")] -theorem IsSt.inv {x : ℝ*} {r : ℝ} (hi : ¬Infinitesimal x) (hr : IsSt x r) : IsSt x⁻¹ r⁻¹ := - hr.map <| continuousAt_inv₀ <| by rintro rfl; exact hi hr - -@[deprecated stdPart_inv (since := "2026-01-05")] -theorem st_inv (x : ℝ*) : st x⁻¹ = (st x)⁻¹ := by - simp [st_eq] - -@[deprecated archimedeanClassMk_omega_neg (since := "2026-01-05")] -theorem infinitePos_omega : InfinitePos ω := - infinitePos_iff_infinitesimal_inv_pos.mpr ⟨infinitesimal_epsilon, epsilon_pos⟩ - -@[deprecated archimedeanClassMk_omega_neg (since := "2026-01-05")] -theorem infinite_omega : Infinite ω := - (infinite_iff_infinitesimal_inv omega_ne_zero).mpr infinitesimal_epsilon - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_mul_of_infinitePos_not_infinitesimal_pos {x y : ℝ*} : - InfinitePos x → ¬Infinitesimal y → 0 < y → InfinitePos (x * y) := fun hx hy₁ hy₂ r => by - have hy₁' := not_forall.mp (mt infinitesimal_def.2 hy₁) - let ⟨r₁, hy₁''⟩ := hy₁' - have hyr : 0 < r₁ ∧ ↑r₁ ≤ y := by - rwa [Classical.not_imp, ← abs_lt, not_lt, abs_of_pos hy₂] at hy₁'' - rw [← div_mul_cancel₀ r (ne_of_gt hyr.1), coe_mul] - exact mul_lt_mul (hx (r / r₁)) hyr.2 (coe_lt_coe.2 hyr.1) (le_of_lt (hx 0)) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_mul_of_not_infinitesimal_pos_infinitePos {x y : ℝ*} : - ¬Infinitesimal x → 0 < x → InfinitePos y → InfinitePos (x * y) := fun hx hp hy => - mul_comm y x ▸ infinitePos_mul_of_infinitePos_not_infinitesimal_pos hy hx hp - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_mul_of_infiniteNeg_not_infinitesimal_neg {x y : ℝ*} : - InfiniteNeg x → ¬Infinitesimal y → y < 0 → InfinitePos (x * y) := by - rw [← infinitePos_neg, ← neg_pos, ← neg_mul_neg, ← infinitesimal_neg] - exact infinitePos_mul_of_infinitePos_not_infinitesimal_pos - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_mul_of_not_infinitesimal_neg_infiniteNeg {x y : ℝ*} : - ¬Infinitesimal x → x < 0 → InfiniteNeg y → InfinitePos (x * y) := fun hx hp hy => - mul_comm y x ▸ infinitePos_mul_of_infiniteNeg_not_infinitesimal_neg hy hx hp - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_mul_of_infinitePos_not_infinitesimal_neg {x y : ℝ*} : - InfinitePos x → ¬Infinitesimal y → y < 0 → InfiniteNeg (x * y) := by - rw [← infinitePos_neg, ← neg_pos, neg_mul_eq_mul_neg, ← infinitesimal_neg] - exact infinitePos_mul_of_infinitePos_not_infinitesimal_pos - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_mul_of_not_infinitesimal_neg_infinitePos {x y : ℝ*} : - ¬Infinitesimal x → x < 0 → InfinitePos y → InfiniteNeg (x * y) := fun hx hp hy => - mul_comm y x ▸ infiniteNeg_mul_of_infinitePos_not_infinitesimal_neg hy hx hp - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_mul_of_infiniteNeg_not_infinitesimal_pos {x y : ℝ*} : - InfiniteNeg x → ¬Infinitesimal y → 0 < y → InfiniteNeg (x * y) := by - rw [← infinitePos_neg, ← infinitePos_neg, neg_mul_eq_neg_mul] - exact infinitePos_mul_of_infinitePos_not_infinitesimal_pos - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_mul_of_not_infinitesimal_pos_infiniteNeg {x y : ℝ*} : - ¬Infinitesimal x → 0 < x → InfiniteNeg y → InfiniteNeg (x * y) := fun hx hp hy => by - rw [mul_comm]; exact infiniteNeg_mul_of_infiniteNeg_not_infinitesimal_pos hy hx hp - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_mul_infinitePos {x y : ℝ*} : - InfinitePos x → InfinitePos y → InfinitePos (x * y) := fun hx hy => - infinitePos_mul_of_infinitePos_not_infinitesimal_pos hx hy.not_infinitesimal (hy 0) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_mul_infiniteNeg {x y : ℝ*} : - InfiniteNeg x → InfiniteNeg y → InfinitePos (x * y) := fun hx hy => - infinitePos_mul_of_infiniteNeg_not_infinitesimal_neg hx hy.not_infinitesimal (hy 0) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinitePos_mul_infiniteNeg {x y : ℝ*} : - InfinitePos x → InfiniteNeg y → InfiniteNeg (x * y) := fun hx hy => - infiniteNeg_mul_of_infinitePos_not_infinitesimal_neg hx hy.not_infinitesimal (hy 0) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infiniteNeg_mul_infinitePos {x y : ℝ*} : - InfiniteNeg x → InfinitePos y → InfiniteNeg (x * y) := fun hx hy => - infiniteNeg_mul_of_infiniteNeg_not_infinitesimal_pos hx hy.not_infinitesimal (hy 0) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinite_mul_of_infinite_not_infinitesimal {x y : ℝ*} : - Infinite x → ¬Infinitesimal y → Infinite (x * y) := fun hx hy => - have h0 : y < 0 ∨ 0 < y := lt_or_gt_of_ne fun H0 => hy (Eq.substr H0 (isSt_refl_real 0)) - hx.elim - (h0.elim - (fun H0 Hx => Or.inr (infiniteNeg_mul_of_infinitePos_not_infinitesimal_neg Hx hy H0)) - fun H0 Hx => Or.inl (infinitePos_mul_of_infinitePos_not_infinitesimal_pos Hx hy H0)) - (h0.elim - (fun H0 Hx => Or.inl (infinitePos_mul_of_infiniteNeg_not_infinitesimal_neg Hx hy H0)) - fun H0 Hx => Or.inr (infiniteNeg_mul_of_infiniteNeg_not_infinitesimal_pos Hx hy H0)) - -@[deprecated "`Infinitesimal` is deprecated" (since := "2026-01-05")] -theorem infinite_mul_of_not_infinitesimal_infinite {x y : ℝ*} : - ¬Infinitesimal x → Infinite y → Infinite (x * y) := fun hx hy => by - rw [mul_comm]; exact infinite_mul_of_infinite_not_infinitesimal hy hx - -@[deprecated "`Infinite` is deprecated" (since := "2026-01-05")] -theorem Infinite.mul {x y : ℝ*} : Infinite x → Infinite y → Infinite (x * y) := fun hx hy => - infinite_mul_of_infinite_not_infinitesimal hx hy.not_infinitesimal - end Hyperreal end diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean index 40691837719a7f..ff8bb62b9bc75f 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Log.lean @@ -313,7 +313,4 @@ noncomputable def expOpenPartialHomeomorph : OpenPartialHomeomorph ℂ ℂ where continuousOn_toFun := by fun_prop continuousOn_invFun := continuousOn_id.clog fun _ ↦ id -@[deprecated (since := "2026-01-13")] -alias expPartialHomeomorph := expOpenPartialHomeomorph - end Complex diff --git a/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean b/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean index 3d3e3a85d82e49..c12622da3b5992 100644 --- a/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean +++ b/Mathlib/Analysis/SpecialFunctions/NonIntegrable.lean @@ -215,11 +215,7 @@ theorem not_integrableOn_Ici_inv {a : ℝ} : (A.mono (fun x hx ↦ hx.differentiableAt)) B (Filter.EventuallyEq.isBigO (A.mono (fun x hx ↦ hx.deriv))) -@[deprecated (since := "2026-01-30")] alias not_IntegrableOn_Ici_inv := not_integrableOn_Ici_inv - /-- The function `fun x ↦ x⁻¹` is not integrable on any interval `(a, +∞)`. -/ theorem not_integrableOn_Ioi_inv {a : ℝ} : ¬ IntegrableOn (·⁻¹) (Ioi a) := by simpa only [IntegrableOn, restrict_Ioi_eq_restrict_Ici] using not_integrableOn_Ici_inv - -@[deprecated (since := "2026-01-30")] alias not_IntegrableOn_Ioi_inv := not_integrableOn_Ioi_inv diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index d5b7ed3e60971b..4e119b3c5ad7ba 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -219,8 +219,6 @@ lemma summable_cotTerm (hz : x ∈ ℂ_ℤ) : Summable fun n ↦ cotTerm x n := apply (EisensteinSeries.summable_linear_sub_mul_linear_add x 1 1).congr simp [mul_comm] -@[deprecated (since := "2026-01-28")] alias Summable_cotTerm := summable_cotTerm - lemma cot_series_rep' (hz : x ∈ ℂ_ℤ) : π * cot (π * x) - 1 / x = ∑' n : ℕ, (1 / (x - (n + 1)) + 1 / (x + (n + 1))) := by rw [HasSum.tsum_eq] diff --git a/Mathlib/CategoryTheory/Adjunction/Opposites.lean b/Mathlib/CategoryTheory/Adjunction/Opposites.lean index d73b423a1566c6..3af5c0957687af 100644 --- a/Mathlib/CategoryTheory/Adjunction/Opposites.lean +++ b/Mathlib/CategoryTheory/Adjunction/Opposites.lean @@ -90,21 +90,6 @@ def leftAdjointsCoyonedaEquiv {F F' : C ⥤ D} {G : D ⥤ C} (adj1 : F ⊣ G) (a NatIso.ofComponents fun Y => ((adj1.homEquiv X.unop Y).trans (adj2.homEquiv X.unop Y).symm).toIso -/-- Deprecated: prefer `(Adjunction.conjugateIsoEquiv adj1 adj2).symm`. -/ -@[deprecated "Use `(Adjunction.conjugateIsoEquiv adj1 adj2).symm` \ - (requires `import Mathlib.CategoryTheory.Adjunction.Mates`)." (since := "2026-01-31")] -def natIsoOfRightAdjointNatIso {F F' : C ⥤ D} {G G' : D ⥤ C} - (adj1 : F ⊣ G) (adj2 : F' ⊣ G') (r : G ≅ G') : F ≅ F' := - NatIso.removeOp ((Coyoneda.fullyFaithful.whiskeringRight _).isoEquiv.symm - (leftAdjointsCoyonedaEquiv adj2 (adj1.ofNatIsoRight r))) - -/-- Deprecated: prefer `Adjunction.conjugateIsoEquiv adj1 adj2`. -/ -@[deprecated "Use `Adjunction.conjugateIsoEquiv adj1 adj2` \ - (requires `import Mathlib.CategoryTheory.Adjunction.Mates`)." (since := "2026-01-31")] -def natIsoOfLeftAdjointNatIso {F F' : C ⥤ D} {G G' : D ⥤ C} - (adj1 : F ⊣ G) (adj2 : F' ⊣ G') (l : F ≅ F') : G ≅ G' := - NatIso.removeOp (natIsoOfRightAdjointNatIso (op adj2) (op adj1) (NatIso.op l)) - end Adjunction namespace Functor diff --git a/Mathlib/CategoryTheory/Category/Grpd.lean b/Mathlib/CategoryTheory/Category/Grpd.lean deleted file mode 100644 index 4111ff8d977cd7..00000000000000 --- a/Mathlib/CategoryTheory/Category/Grpd.lean +++ /dev/null @@ -1,10 +0,0 @@ -module -- shake: keep-all - -import Mathlib.CategoryTheory.Category.Init -import Mathlib.Data.Finset.Attr -import Mathlib.Tactic.Common -import Mathlib.Tactic.Finiteness.Attr -import Mathlib.Tactic.SetLike -import Mathlib.Util.CompileInductive - -deprecated_module (since := "2026-01-14") diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index 277c61c75b79f1..1041a23e85ff5d 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -124,8 +124,6 @@ def Fan.IsLimit.lift {F : β → C} {c : Fan F} (hc : IsLimit c) {A : C} (f : ∀ i, A ⟶ F i) : A ⟶ c.pt := hc.lift (Fan.mk A f) -@[deprecated (since := "2026-01-12")] alias Fan.IsLimit.desc := Fan.IsLimit.lift - @[reassoc (attr := simp)] lemma Fan.IsLimit.fac {F : β → C} {c : Fan F} (hc : IsLimit c) {A : C} (f : ∀ i, A ⟶ F i) (i : β) : @@ -304,9 +302,6 @@ lemma Cofan.nonempty_isColimit_iff_isIso_sigmaDesc {f : β → C} [HasCoproduct Nonempty (IsColimit c) ↔ IsIso (Sigma.desc c.inj) := (colimit.isColimit (Discrete.functor f)).nonempty_isColimit_iff_isIso_desc -@[deprecated (since := "2026-01-21")] -alias Cofan.isColimit_iff_isIso_sigmaDesc := Cofan.nonempty_isColimit_iff_isIso_sigmaDesc - /-- A coproduct of coproducts is a coproduct -/ def Cofan.isColimitTrans {X : α → C} (c : Cofan X) (hc : IsColimit c) {β : α → Type*} {Y : (a : α) → β a → C} (π : (a : α) → (b : β a) → Y a b ⟶ X a) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean deleted file mode 100644 index 256ca656dab787..00000000000000 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean +++ /dev/null @@ -1,20 +0,0 @@ -/- -Copyright (c) 2022 Kim Morrison. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kim Morrison, Joël Riou, Calle Sönne --/ -module -- shake: keep-all - -public import Mathlib.CategoryTheory.Category.Init -public import Mathlib.Data.Finset.Attr -public import Mathlib.Tactic.Common -public import Mathlib.Tactic.Finiteness.Attr -public import Mathlib.Tactic.SetLike -public import Mathlib.Util.CompileInductive - -deprecated_module - "This module was split into three parts: - `Mathlib.CategoryTheory.Limits.Shapes.Pullback.IsPullback.Defs`, - `Mathlib.CategoryTheory.Limits.Shapes.Pullback.IsPullback.Basic`, and - `Mathlib.CategoryTheory.Limits.Shapes.Pullback.IsPullback.BicartesianSq`" - (since := "2026-01-15") diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Equifibered.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Equifibered.lean index f0d2cfc2ade722..a6147f447a6cbd 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Equifibered.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Equifibered.lean @@ -77,11 +77,6 @@ theorem Equifibered.of_discrete {F G : Discrete ι ⥤ C} (α : F ⟶ G) : Equif simp only [Discrete.functor_map_id] exact IsPullback.of_horiz_isIso ⟨by rw [Category.id_comp, Category.comp_id]⟩ -@[deprecated (since := "2026-01-23")] -alias _root_.CategoryTheory.mapPair_equifibered := Equifibered.of_discrete - -@[deprecated (since := "2026-01-23")] alias equifibered_of_discrete := Equifibered.of_discrete - /-- A natural transformation is co-equifibered if every commutative square of the following form is a pushout. ``` diff --git a/Mathlib/CategoryTheory/MorphismProperty/Basic.lean b/Mathlib/CategoryTheory/MorphismProperty/Basic.lean index 74fa8da4857ebc..954432702e7d94 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Basic.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Basic.lean @@ -694,9 +694,6 @@ theorem epimorphisms.infer_property [hf : Epi f] : (epimorphisms C) f := end -@[deprecated "Use `op_isomorphisms _` instead." (since := "2026-01-18")] -lemma isomorphisms_op : (isomorphisms C).op = isomorphisms Cᵒᵖ := op_isomorphisms _ - instance RespectsIso.monomorphisms : RespectsIso (monomorphisms C) := by apply RespectsIso.mk <;> · intro X Y Z e f diff --git a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean index 297bc3a8b72207..0de8c8f6506419 100644 --- a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean +++ b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean @@ -683,9 +683,6 @@ theorem isSheafFor_top (P : Cᵒᵖ ⥤ Type w) : IsSheafFor P (⊤ : Presieve X rw [← isSheafFor_iff_generate] apply isSheafFor_singleton_iso -@[deprecated (since := "2026-01-22")] -alias isSheafFor_top_sieve := isSheafFor_top - /-- If `P₁ : Cᵒᵖ ⥤ Type w` and `P₂ : Cᵒᵖ ⥤ Type w` are two naturally equivalent presheaves, and `P₁` is a sheaf for a presieve `R`, then `P₂` is also a sheaf for `R`. -/ lemma isSheafFor_of_nat_equiv {P₁ : Cᵒᵖ ⥤ Type w} {P₂ : Cᵒᵖ ⥤ Type w'} diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean index f0c00f382b1fd8..e03d365ad1e05a 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean @@ -181,9 +181,6 @@ lemma isLE_of_le (X : C) (p q : ℤ) (hpq : p ≤ q := by lia) [t.IsLE X p] : t. lemma isGE_of_ge (X : C) (p q : ℤ) (hpq : p ≤ q := by lia) [t.IsGE X q] : t.IsGE X p where ge := ge_antitone t hpq _ (t.ge_of_isGE X q) -@[deprecated (since := "2026-01-30")] alias isLE_of_LE := isLE_of_le -@[deprecated (since := "2026-01-30")] alias isGE_of_GE := isGE_of_ge - @[simp] lemma le_iff_isLE (X : C) (n : ℤ) : t.le n X ↔ t.IsLE X n := ⟨fun h ↦ ⟨h⟩, fun _ ↦ t.le_of_isLE X n⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean b/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean index e3f9ae59fd486b..6cd78f0a5c115c 100644 --- a/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean +++ b/Mathlib/Combinatorics/SimpleGraph/AdjMatrix.lean @@ -315,9 +315,6 @@ theorem one_add_adjMatrix_add_compl_adjMatrix_eq_of_one [DecidableEq V] [Decidab [AddMonoid α] [One α] : 1 + G.adjMatrix α + (G.adjMatrix α).compl = of 1 := by aesop (add simp [add_assoc]) -@[deprecated (since := "2026-01-30")] alias one_add_adjMatrix_add_compl_adjMatrix_eq_allOnes := - one_add_adjMatrix_add_compl_adjMatrix_eq_of_one - variable (V) @[simp] theorem compl_adjMatrix_completeGraph [Zero α] [One α] [DecidableEq α] [DecidableEq V] : diff --git a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean index 8116036b084a49..ee06cb3f1b4cf7 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Coloring/Vertex.lean @@ -171,9 +171,6 @@ def Coloring.ofIsEmpty [IsEmpty V] : G.Coloring α := .mk isEmptyElim fun {v} => theorem Colorable.of_isEmpty [IsEmpty V] (n : ℕ) : G.Colorable n := ⟨.ofIsEmpty⟩ -@[deprecated (since := "2026-01-03")] alias coloringOfIsEmpty := Coloring.ofIsEmpty -@[deprecated (since := "2026-01-03")] alias colorableOfIsEmpty := Colorable.of_isEmpty - @[simp] lemma colorable_zero_iff : G.Colorable 0 ↔ IsEmpty V := ⟨fun ⟨C⟩ ↦ Function.isEmpty C, fun _ ↦ .of_isEmpty 0⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean b/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean index 89fd57f3f80745..e5b51edc202cd7 100644 --- a/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean +++ b/Mathlib/Combinatorics/SimpleGraph/VertexCover.lean @@ -190,11 +190,6 @@ theorem IsContained.vertexCoverNum_le_vertexCoverNum (h : G ⊑ H) : grw [this.vertexCoverNum_le, ← hs₁] exact Function.Embedding.encard_le <| Function.Embedding.mk f hf |>.subtypeMap (by simp) -@[deprecated IsContained.vertexCoverNum_le_vertexCoverNum (since := "2026-01-07")] -theorem vertexCoverNum_le_vertexCoverNum_of_injective (f : G →g H) (hf : Function.Injective f) : - vertexCoverNum G ≤ vertexCoverNum H := - IsContained.vertexCoverNum_le_vertexCoverNum ⟨f, hf⟩ - @[gcongr] theorem vertexCoverNum_mono (h : G ≤ G') : vertexCoverNum G ≤ vertexCoverNum G' := (IsContained.of_le h).vertexCoverNum_le_vertexCoverNum diff --git a/Mathlib/Computability/Primrec.lean b/Mathlib/Computability/Primrec.lean deleted file mode 100644 index 5f86b7cda1dd98..00000000000000 --- a/Mathlib/Computability/Primrec.lean +++ /dev/null @@ -1,10 +0,0 @@ -/- -Copyright (c) 2018 Mario Carneiro. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Mario Carneiro --/ -module -- shake: keep-all - -public import Mathlib.Computability.Primrec.List - -deprecated_module (since := "2026-01-10") diff --git a/Mathlib/Computability/Primrec/Basic.lean b/Mathlib/Computability/Primrec/Basic.lean index a3ec0c5fcb829e..b96415cc75d5e4 100644 --- a/Mathlib/Computability/Primrec/Basic.lean +++ b/Mathlib/Computability/Primrec/Basic.lean @@ -573,10 +573,6 @@ theorem option_getD : Primrec₂ (@Option.getD α) := theorem option_getD_default [Inhabited α] : Primrec (fun o : Option α => o.getD default) := option_getD.comp .id (const default) -@[deprecated option_getD_default (since := "2026-01-05")] -theorem option_iget [Inhabited α] : Primrec (@Option.iget α _) := - option_getD_default - theorem option_isSome : Primrec (@Option.isSome α) := (option_casesOn .id (const false) (const true).to₂).of_eq fun o => by cases o <;> rfl diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index 23d06f1c3fe8f0..c17568a07a67d1 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -1009,8 +1009,6 @@ def curryEquiv : (α × β →₀ M) ≃ (α →₀ β →₀ M) where left_inv := uncurry_curry right_inv := curry_uncurry -@[deprecated (since := "2026-01-03")] noncomputable alias finsuppProdEquiv := curryEquiv - theorem filter_curry (f : α × β →₀ M) (p : α → Prop) [DecidablePred p] : (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by ext a b diff --git a/Mathlib/Data/Fintype/Prod.lean b/Mathlib/Data/Fintype/Prod.lean index d385ab7979e860..b6abe0a05f6d11 100644 --- a/Mathlib/Data/Fintype/Prod.lean +++ b/Mathlib/Data/Fintype/Prod.lean @@ -37,9 +37,6 @@ theorem toFinset_offDiag {s : Set α} [Fintype s] [Fintype s.offDiag] : s.offDiag.toFinset = s.toFinset.offDiag := Finset.ext <| by simp -@[deprecated (since := "2026-01-09")] -alias toFinset_off_diag := toFinset_offDiag - end Set instance instFintypeProd (α β : Type*) [Fintype α] [Fintype β] : Fintype (α × β) := diff --git a/Mathlib/Data/Int/ModEq.lean b/Mathlib/Data/Int/ModEq.lean index af9eb4fd26e2d1..c4f699544ce830 100644 --- a/Mathlib/Data/Int/ModEq.lean +++ b/Mathlib/Data/Int/ModEq.lean @@ -41,9 +41,6 @@ theorem modEq_iff_intModEq {a b z : ℤ} : a ≡ b [PMOD z] ↔ a ≡ b [ZMOD z] simp [modEq_iff_zsmul', dvd_iff_exists_eq_mul_left, Int.ModEq, Int.emod_eq_emod_iff_emod_sub_eq_zero, ← Int.dvd_iff_emod_eq_zero] -@[deprecated (since := "2026-01-13")] -alias modEq_iff_int_modEq := modEq_iff_intModEq - variable {G : Type*} [AddCommGroupWithOne G] [CharZero G] @[simp, norm_cast] diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 5a427b4774968a..53a34b8463f6de 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -360,10 +360,6 @@ theorem getLastI_eq_getLast?_getD [Inhabited α] : ∀ l : List α, l.getLastI = | [_, _, _] => rfl | _ :: _ :: c :: l => by simp [getLastI, getLastI_eq_getLast?_getD (c :: l)] -@[deprecated getLastI_eq_getLast?_getD (since := "2026-01-05")] -theorem getLastI_eq_getLast? [Inhabited α] : ∀ l : List α, l.getLastI = l.getLast?.getD default := - getLastI_eq_getLast?_getD - theorem getLast?_append_cons : ∀ (l₁ : List α) (a : α) (l₂ : List α), getLast? (l₁ ++ a :: l₂) = getLast? (a :: l₂) | [], _, _ => rfl @@ -403,10 +399,6 @@ theorem head_eq_getElem_zero {l : List α} (hl : l ≠ []) : theorem head!_eq_head?_getD [Inhabited α] (l : List α) : head! l = (head? l).getD default := by cases l <;> rfl -@[deprecated head!_eq_head?_getD (since := "2026-01-05")] -theorem head!_eq_head? [Inhabited α] (l : List α) : head! l = (head? l).getD default := - head!_eq_head?_getD l - theorem surjective_head! [Inhabited α] : Surjective (@head! α _) := fun x => ⟨[x], rfl⟩ theorem surjective_head? : Surjective (@head? α) := diff --git a/Mathlib/Data/List/Flatten.lean b/Mathlib/Data/List/Flatten.lean index 3c475a18eb5502..84a258808986aa 100644 --- a/Mathlib/Data/List/Flatten.lean +++ b/Mathlib/Data/List/Flatten.lean @@ -66,16 +66,10 @@ theorem getLast_getLast_eq_getLast_flatten {l : List (List α)} l.flatten.getLast (flatten_ne_nil_iff.2 ⟨_, getLast_mem hl, hl'⟩) := by cases eq_nil_or_concat l with grind -@[deprecated (since := "2026-01-31")] -alias getLast_flatten_of_getLast_ne_nil := getLast_getLast_eq_getLast_flatten - /-- See also `getLast_getLast_eq_getLast_flatten`, which switches around the proof obligations. -/ theorem getLast_flatten_eq_getLast_getLast {l : List (List α)} (hl : l.flatten ≠ []) (hl' : l.getLast (by grind) ≠ []) : l.flatten.getLast hl = (l.getLast (by grind)).getLast hl' := (getLast_getLast_eq_getLast_flatten ..).symm -@[deprecated (since := "2026-01-31")] -alias getLast_flatten_of_flatten_ne_nil := getLast_flatten_eq_getLast_getLast - end List diff --git a/Mathlib/Data/List/GetD.lean b/Mathlib/Data/List/GetD.lean index 296b75d1659c7e..470e5e2f77fa32 100644 --- a/Mathlib/Data/List/GetD.lean +++ b/Mathlib/Data/List/GetD.lean @@ -123,10 +123,6 @@ theorem getI_append_right (l l' : List α) (n : ℕ) (h : l.length ≤ n) : theorem getI_eq_getElem?_getD (n : ℕ) : l.getI n = (l[n]?).getD default := by rw [← getD_default_eq_getI, getD_eq_getElem?_getD] -@[deprecated getI_eq_getElem?_getD (since := "2026-01-05")] -theorem getI_eq_iget_getElem? (n : ℕ) : l.getI n = l[n]?.getD default := - getI_eq_getElem?_getD (l := l) n - theorem getI_zero_eq_headI : l.getI 0 = l.headI := by cases l <;> rfl end getI diff --git a/Mathlib/Data/Option/Basic.lean b/Mathlib/Data/Option/Basic.lean index e66b8f9b8b3ef2..17ada9269a2c0c 100644 --- a/Mathlib/Data/Option/Basic.lean +++ b/Mathlib/Data/Option/Basic.lean @@ -146,18 +146,6 @@ end pmap theorem seq_some {α β} {a : α} {f : α → β} : some f <*> some a = some (f a) := rfl -@[deprecated "Use `Option.get` with proof of `isSome`." (since := "2026-01-05")] -theorem iget_mem [Inhabited α] : ∀ {o : Option α}, isSome o → o.iget ∈ o - | some _, _ => rfl - -@[deprecated "Use `Option.getD`." (since := "2026-01-05")] -theorem iget_of_mem [Inhabited α] {a : α} : ∀ {o : Option α}, a ∈ o → o.iget = a - | _, rfl => rfl - -@[deprecated "Use `Option.getD` directly." (since := "2026-01-05")] -theorem getD_default_eq_iget [Inhabited α] (o : Option α) : - o.getD default = o.iget := by cases o <;> rfl - @[simp, grind =] theorem failure_eq_none {α} : failure = (none : Option α) := rfl diff --git a/Mathlib/Data/Option/Defs.lean b/Mathlib/Data/Option/Defs.lean index deb95bf324272c..783002f81764df 100644 --- a/Mathlib/Data/Option/Defs.lean +++ b/Mathlib/Data/Option/Defs.lean @@ -45,15 +45,4 @@ lemma elim'_eq_elim {α β : Type*} (b : β) (f : α → β) (a : Option α) : Option.elim' b f a = Option.elim a b f := by cases a <;> rfl -/-- Inhabited `get` function. Returns `a` if the input is `some a`, otherwise returns `default`. -/ -@[deprecated "Use `Option.get!` (which will panic on `none`) or \ - `Option.getD` (which takes an explicit default value)." (since := "2026-01-05")] -abbrev iget [Inhabited α] : Option α → α - | some x => x - | none => default - -@[deprecated "Use `Option.getD`." (since := "2026-01-05")] -theorem iget_some [Inhabited α] {a : α} : (some a).iget = a := - rfl - end Option diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index cab6e20f4d6275..23e58f5ee50e8c 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -815,8 +815,6 @@ theorem ncard_image_le (hs : s.Finite := by toFinite_tac) : (f '' s).ncard ≤ s theorem InjOn.ncard_image (H : Set.InjOn f s) : (f '' s).ncard = s.ncard := congr_arg ENat.toNat <| H.encard_image -@[deprecated (since := "2026-01-30")] alias ncard_image_of_injOn := InjOn.ncard_image - theorem injOn_of_ncard_image_eq (h : (f '' s).ncard = s.ncard) (hs : s.Finite := by toFinite_tac) : Set.InjOn f s := by rw [← Nat.cast_inj (R := ℕ∞), hs.cast_ncard_eq, (hs.image _).cast_ncard_eq] at h diff --git a/Mathlib/Data/SetLike/Basic.lean b/Mathlib/Data/SetLike/Basic.lean index 42d6868b82cfbd..84d739cf67c7c2 100644 --- a/Mathlib/Data/SetLike/Basic.lean +++ b/Mathlib/Data/SetLike/Basic.lean @@ -264,8 +264,6 @@ theorem le_def {S T : A} : S ≤ T ↔ ∀ ⦃x : B⦄, x ∈ S → x ∈ T := b @[gcongr low] -- lower priority than `Set.mem_of_subset_of_mem` alias ⟨_root_.mem_of_le_of_mem, _⟩ := le_def -@[deprecated (since := "2026-01-07")] alias GCongr.mem_of_le_of_mem := _root_.mem_of_le_of_mem - theorem not_le_iff_exists : ¬p ≤ q ↔ ∃ x ∈ p, x ∉ q := by simpa [← coe_subset_coe] using! Set.not_subset diff --git a/Mathlib/Data/Tree/RBMap.lean b/Mathlib/Data/Tree/RBMap.lean deleted file mode 100644 index ac4a59e6bd04a3..00000000000000 --- a/Mathlib/Data/Tree/RBMap.lean +++ /dev/null @@ -1,5 +0,0 @@ -module -- shake: keep-all - -public import Mathlib.Util.CompileInductive - -deprecated_module (since := "2026-01-16") diff --git a/Mathlib/FieldTheory/Isaacs.lean b/Mathlib/FieldTheory/Isaacs.lean index 759c2623759ad7..725f6ea061e1c2 100644 --- a/Mathlib/FieldTheory/Isaacs.lean +++ b/Mathlib/FieldTheory/Isaacs.lean @@ -74,9 +74,6 @@ theorem nonempty_algHom_of_exists_root (h : ∀ x : E, ∃ y : K, aeval y (minpo exact ((botEquiv K K').toAlgHom.restrictScalars F).comp (ω.choose.codRestrict K₀.toSubalgebra fun x ↦ ω.choose_spec trivial) -@[deprecated (since := "2026-01-31")] -alias nonempty_algHom_of_exist_roots := nonempty_algHom_of_exists_root - theorem nonempty_algHom_of_minpoly_eq (h : ∀ x : E, ∃ y : K, minpoly F x = minpoly F y) : Nonempty (E →ₐ[F] K) := @@ -122,7 +119,4 @@ theorem _root_.IsAlgClosure.of_exists_root h _ (minpoly.monic this) (minpoly.irreducible this) Splits.of_algHom (SplittingField.splits _) σ -@[deprecated (since := "2026-01-31")] -alias _root_.IsAlgClosure.of_exist_roots := IsAlgClosure.of_exists_root - end Field diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index e9d0243283efab..558e3d7e89a6b9 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -673,10 +673,6 @@ theorem Metric.exists_contMDiffMap_forall_closedEBall_subset Metric.exists_forall_closedEBall_subset_aux₂ (Metric.exists_forall_closedEBall_subset_aux₁ hK hU hKU hfin) -@[deprecated (since := "2026-01-24")] -alias Emetric.exists_contMDiffMap_forall_closedBall_subset := - Metric.exists_contMDiffMap_forall_closedEBall_subset - /-- Let `M` be a smooth σ-compact manifold with a metric. Let `K : ι → Set M` be a locally finite family of closed sets, let `U : ι → Set M` be a family of open sets such that `K i ⊆ U i` for all `i`. Then there exists a positive smooth function `δ : M → ℝ≥0` such that for any `i` and `x ∈ K i`, diff --git a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean index a77ad8f2ea8290..4eb6a5d861029f 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean @@ -527,9 +527,6 @@ additionally the predicate `IsRiemannianManifold I M`. -/ (fun _ hs ↦ setOfPred_riemannianEDist_lt_subset_nhds' I hs) (fun _ hc ↦ eventually_riemannianEDist_lt I x hc)) -@[deprecated (since := "2026-01-08")] -noncomputable alias PseudoEmetricSpace.ofRiemannianMetric := PseudoEMetricSpace.ofRiemannianMetric - /-- Given a manifold with a Riemannian metric, consider the associated Riemannian distance. Then by definition the distance is the infimum of the length of paths between the points, i.e., the manifold satisfies the `IsRiemannianManifold I M` predicate. -/ @@ -550,7 +547,4 @@ additionally the predicate `IsRiemannianManifold I M`. -/ letI : PseudoEMetricSpace M := .ofRiemannianMetric I M EMetricSpace.ofT0PseudoEMetricSpace M -@[deprecated (since := "2026-01-08")] -noncomputable alias EmetricSpace.ofRiemannianMetric := EMetricSpace.ofRiemannianMetric - end diff --git a/Mathlib/Lean/Expr.lean b/Mathlib/Lean/Expr.lean deleted file mode 100644 index 2000ba4f4204b6..00000000000000 --- a/Mathlib/Lean/Expr.lean +++ /dev/null @@ -1,10 +0,0 @@ -/- -Copyright (c) 2019 Robert Y. Lewis. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Mario Carneiro, Simon Hudon, Kim Morrison, Keeley Hoek, Robert Y. Lewis, Floris van Doorn --/ -module -- shake: keep-all - -public import Mathlib.Lean.Expr.Basic - -deprecated_module (since := "2026-01-27") diff --git a/Mathlib/Lean/Expr/ReplaceRec.lean b/Mathlib/Lean/Expr/ReplaceRec.lean deleted file mode 100644 index 57242b27344049..00000000000000 --- a/Mathlib/Lean/Expr/ReplaceRec.lean +++ /dev/null @@ -1,41 +0,0 @@ -/- -Copyright (c) 2019 Robert Y. Lewis. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Mario Carneiro, Simon Hudon, Kim Morrison, Keeley Hoek, Robert Y. Lewis, -Floris van Doorn, Edward Ayers --/ -module -- shake: keep-all - -public import Lean.Expr -public import Mathlib.Util.MemoFix - -/-! -# ReplaceRec - -We define a more flexible version of `Expr.replace` where we can use recursive calls even when -replacing a subexpression. We completely mimic the implementation of `Expr.replace`. --/ - -deprecated_module (since := "2026-01-26") - -@[expose] public section - -namespace Lean.Expr - -/-- A version of `Expr.replace` where the replacement function is available to the function `f?`. - -`replaceRec f? e` will call `f? r e` where `r = replaceRec f?`. -If `f? r e = none` then `r` will be called on each immediate subexpression of `e` and reassembled. -If it is `some x`, traversal terminates and `x` is returned. -If you wish to recursively replace things in the implementation of `f?`, you can apply `r`. - -The function is also memoised, which means that if the -same expression (by reference) is encountered the cached replacement is used. -/ -@[deprecated "use `MonadCacheT` and `checkCache`" (since := "2026-01-24")] -def replaceRec (f? : (Expr → Expr) → Expr → Option Expr) : Expr → Expr := - memoFix fun r e ↦ - match f? r e with - | some x => x - | none => Id.run <| traverseChildren (pure <| r ·) e - -end Lean.Expr diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean index 199ab8efa6025d..3dd7ac92ed219f 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean @@ -525,10 +525,6 @@ theorem AffineMap.map_vectorSpan {s : Set P₁} : Submodule.map f.linear (vectorSpan k s) = vectorSpan k (f '' s) := by simp [vectorSpan_def, f.image_vsub_image] --- this name was backwards -@[deprecated (since := "2026-01-20")] -alias AffineMap.vectorSpan_image_eq_submodule_map := AffineMap.map_vectorSpan - namespace AffineSubspace /-- The image of an affine subspace under an affine map as an affine subspace. -/ diff --git a/Mathlib/LinearAlgebra/BilinearForm/Properties.lean b/Mathlib/LinearAlgebra/BilinearForm/Properties.lean index fa737f807f92ad..db4393c123ec0e 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Properties.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Properties.lean @@ -362,8 +362,6 @@ lemma apply_toDual_symm_apply {B : BilinForm K V} {hB : B.Nondegenerate} change B.toDual hB ((B.toDual hB).symm f) v = f v simp only [LinearEquiv.apply_symm_apply] -@[deprecated (since := "2026-01-17")] alias nonDegenerateFlip_iff := nondegenerate_flip_iff - end FiniteDimensional section DualBasis diff --git a/Mathlib/LinearAlgebra/BilinearMap.lean b/Mathlib/LinearAlgebra/BilinearMap.lean index 3e8b3394998a39..93ea3c9677e709 100644 --- a/Mathlib/LinearAlgebra/BilinearMap.lean +++ b/Mathlib/LinearAlgebra/BilinearMap.lean @@ -513,9 +513,6 @@ variable {R} lemma lsmul_eq_distribSMultoLinearMap (r : R) : lsmul R M r = DistribSMul.toLinearMap R M r := rfl -@[deprecated (since := "2026-01-07")] -alias lsmul_eq_DistribMulAction_toLinearMap := lsmul_eq_distribSMultoLinearMap - variable {M} @[simp] diff --git a/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean b/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean index d20ee75742b565..b7d9d5cc4ede9b 100644 --- a/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean +++ b/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean @@ -129,12 +129,6 @@ lemma finsuppLeft_smul' (s : S) (t : (ι →₀ M) ⊗[R] N) : finsuppLeft R S M N ι (s • t) = s • finsuppLeft R S M N ι t := by simp -@[deprecated (since := "2026-01-01")] alias finsuppLeft' := finsuppLeft - -@[nolint synTaut, deprecated "is syntactic rfl now" (since := "2026-01-01")] -lemma finsuppLeft'_apply (x : (ι →₀ M) ⊗[R] N) : - finsuppLeft R S M N ι x = finsuppLeft R S M N ι x := rfl - variable (R M N ι) in /-- The tensor product of `ι →₀ R` and `N` is linearly equivalent to `ι →₀ N` -/ noncomputable def finsuppScalarLeft : @@ -195,13 +189,6 @@ theorem finsuppScalarRight_smul (s : S) (t) : finsuppScalarRight R S M ι (s • t) = s • finsuppScalarRight R S M ι t := by simp -@[deprecated (since := "2026-01-01")] alias finsuppScalarRight' := finsuppScalarRight - -@[nolint synTaut, deprecated "is syntactic rfl now" (since := "2026-01-01")] -theorem coe_finsuppScalarRight' : - ⇑(finsuppScalarRight R S M ι) = finsuppScalarRight R S M ι := - rfl - end TensorProduct end TensorProduct diff --git a/Mathlib/LinearAlgebra/Finsupp/Defs.lean b/Mathlib/LinearAlgebra/Finsupp/Defs.lean index 51d89abaf6ff11..c2f1634c915428 100644 --- a/Mathlib/LinearAlgebra/Finsupp/Defs.lean +++ b/Mathlib/LinearAlgebra/Finsupp/Defs.lean @@ -286,15 +286,10 @@ noncomputable def curryLinearEquiv : (α × β →₀ M) ≃ₗ[R] α →₀ β toAddEquiv := curryAddEquiv map_smul' c f := by ext; simp -@[deprecated (since := "2026-01-03")] alias finsuppProdLEquiv := curryLinearEquiv - theorem curryLinearEquiv_symm_apply_apply (f : α →₀ β →₀ M) (xy) : (curryLinearEquiv R).symm f xy = f xy.1 xy.2 := rfl -@[deprecated (since := "2026-01-03")] -alias finsuppProdLEquiv_symm_apply_apply := curryLinearEquiv_symm_apply_apply - end Prod end Finsupp diff --git a/Mathlib/LinearAlgebra/Lagrange.lean b/Mathlib/LinearAlgebra/Lagrange.lean index 15cdee460e800e..1ce7a74eea2aa2 100644 --- a/Mathlib/LinearAlgebra/Lagrange.lean +++ b/Mathlib/LinearAlgebra/Lagrange.lean @@ -487,11 +487,6 @@ theorem eval_iterate_derivative_eq_sum (hvs : Set.InjOn v s) {P : Polynomial F} nth_rewrite 1 [eq_interpolate hvs hP, iterate_derivative_interpolate _ hvs hk] simp [eval_finsetSum, eval_prod] -@[deprecated eq_interpolate (since := "2026-01-14")] -theorem interpolate_poly_eq_self - (hvs : Set.InjOn v s) {P : Polynomial F} (hP : P.degree < s.card) : - interpolate s v (fun i => P.eval (v i)) = P := (eq_interpolate hvs hP).symm - theorem coeff_eq_sum (hvs : Set.InjOn v s) {P : Polynomial F} (hP : P.degree < #s) : P.coeff (#s - 1) = ∑ i ∈ s, (P.eval (v i)) / ∏ j ∈ s.erase i, (v i - v j) := by diff --git a/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean b/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean index 1c1c0c338eba94..27b6183eccca58 100644 --- a/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean +++ b/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean @@ -64,8 +64,6 @@ This is an auxiliary definition for the equivalence `Matrix.toBilin'`. -/ def LinearMap.BilinForm.toMatrixAux (b : n → M₁) : BilinForm R₁ M₁ →ₗ[R₁] Matrix n n R₁ := LinearMap.toMatrix₂Aux R₁ b b -@[deprecated (since := "2026-01-16")] alias BilinForm.toMatrixAux := LinearMap.BilinForm.toMatrixAux - @[simp] theorem LinearMap.BilinForm.toMatrixAux_apply (B : BilinForm R₁ M₁) (b : n → M₁) (i j : n) : BilinForm.toMatrixAux b B i j = B (b i) (b j) := @@ -77,9 +75,6 @@ theorem LinearMap.toBilin'Aux_toMatrixAux [DecidableEq n] (B₂ : BilinForm R₁ Matrix.toBilin'Aux (BilinForm.toMatrixAux (fun j => Pi.single j 1) B₂) = B₂ := by rw [BilinForm.toMatrixAux, Matrix.toBilin'Aux, toLinearMap₂'Aux_toMatrix₂Aux] -@[deprecated (since := "2026-01-16")] alias toBilin'Aux_toMatrixAux := - LinearMap.toBilin'Aux_toMatrixAux - section ToMatrix' /-! ### `ToMatrix'` section @@ -192,8 +187,6 @@ variable [DecidableEq n] (b : Basis n R₁ M₁) noncomputable def LinearMap.BilinForm.toMatrix : BilinForm R₁ M₁ ≃ₗ[R₁] Matrix n n R₁ := LinearMap.toMatrix₂ b b -@[deprecated (since := "2026-01-16")] alias BilinForm.toMatrix := LinearMap.BilinForm.toMatrix - /-- `BilinForm.toMatrix b` is the equivalence between `R`-bilinear forms on `M` and `n`-by-`n` matrices with entries in `R`, if `b` is an `R`-basis for `M`. -/ noncomputable def Matrix.toBilin : Matrix n n R₁ ≃ₗ[R₁] BilinForm R₁ M₁ := @@ -204,24 +197,14 @@ theorem LinearMap.BilinForm.toMatrix_apply (B : BilinForm R₁ M₁) (i j : n) : BilinForm.toMatrix b B i j = B (b i) (b j) := LinearMap.toMatrix₂_apply _ _ B _ _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_apply := LinearMap.BilinForm.toMatrix_apply - theorem LinearMap.BilinForm.dotProduct_toMatrix_mulVec (B : BilinForm R₁ M₁) (x y : n → R₁) : x ⬝ᵥ (BilinForm.toMatrix b B) *ᵥ y = B (b.equivFun.symm x) (b.equivFun.symm y) := dotProduct_toMatrix₂_mulVec b b B x y -@[deprecated (since := "2026-01-16")] -alias BilinForm.dotProduct_toMatrix_mulVec := LinearMap.BilinForm.dotProduct_toMatrix_mulVec - lemma LinearMap.BilinForm.apply_eq_dotProduct_toMatrix_mulVec (B : BilinForm R₁ M₁) (x y : M₁) : B x y = (b.repr x) ⬝ᵥ (BilinForm.toMatrix b B) *ᵥ (b.repr y) := apply_eq_dotProduct_toMatrix₂_mulVec b b B x y -@[deprecated (since := "2026-01-16")] -alias BilinForm.apply_eq_dotProduct_toMatrix_mulVec := - LinearMap.BilinForm.apply_eq_dotProduct_toMatrix_mulVec - @[simp] theorem Matrix.toBilin_apply (M : Matrix n n R₁) (x y : M₁) : Matrix.toBilin b M x y = ∑ i, ∑ j, b.repr x i * M i j * b.repr y j := @@ -233,16 +216,10 @@ theorem LinearMap.BilinForm.toMatrixAux_eq (B : BilinForm R₁ M₁) : BilinForm.toMatrixAux (R₁ := R₁) b B = BilinForm.toMatrix b B := LinearMap.toMatrix₂Aux_eq _ _ B -@[deprecated (since := "2026-01-16")] -alias BilinearForm.toMatrixAux_eq := LinearMap.BilinForm.toMatrixAux_eq - @[simp] theorem LinearMap.BilinForm.toMatrix_symm : (BilinForm.toMatrix b).symm = Matrix.toBilin b := rfl -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_symm := LinearMap.BilinForm.toMatrix_symm - @[simp] theorem Matrix.toBilin_symm : (Matrix.toBilin b).symm = LinearMap.BilinForm.toMatrix b := (LinearMap.BilinForm.toMatrix b).symm_symm @@ -256,9 +233,6 @@ theorem LinearMap.BilinForm.toMatrix_basisFun : BilinForm.toMatrix (Pi.basisFun R₁ n) = BilinForm.toMatrix' := by rw [BilinForm.toMatrix, BilinForm.toMatrix', LinearMap.toMatrix₂_basisFun] -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_basisFun := LinearMap.BilinForm.toMatrix_basisFun - @[simp] theorem Matrix.toBilin_toMatrix (B : BilinForm R₁ M₁) : Matrix.toBilin b (B.toMatrix b) = B := @@ -269,9 +243,6 @@ theorem LinearMap.BilinForm.toMatrix_toBilin (M : Matrix n n R₁) : BilinForm.toMatrix b (Matrix.toBilin b M) = M := (BilinForm.toMatrix b).apply_symm_apply M -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_toBilin := LinearMap.BilinForm.toMatrix_toBilin - variable {M₂' : Type*} [AddCommMonoid M₂'] [Module R₁ M₂'] variable (c : Basis o R₁ M₂') variable [DecidableEq o] @@ -282,54 +253,33 @@ theorem LinearMap.BilinForm.toMatrix_comp (B : BilinForm R₁ M₁) (l r : M₂' (LinearMap.toMatrix c b l)ᵀ * BilinForm.toMatrix b B * LinearMap.toMatrix c b r := LinearMap.toMatrix₂_compl₁₂ _ _ _ _ B _ _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_comp := LinearMap.BilinForm.toMatrix_comp - theorem LinearMap.BilinForm.toMatrix_compLeft (B : BilinForm R₁ M₁) (f : M₁ →ₗ[R₁] M₁) : BilinForm.toMatrix b (B.compLeft f) = (LinearMap.toMatrix b b f)ᵀ * BilinForm.toMatrix b B := LinearMap.toMatrix₂_comp _ _ _ B _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_compLeft := LinearMap.BilinForm.toMatrix_compLeft - theorem LinearMap.BilinForm.toMatrix_compRight (B : BilinForm R₁ M₁) (f : M₁ →ₗ[R₁] M₁) : BilinForm.toMatrix b (B.compRight f) = BilinForm.toMatrix b B * LinearMap.toMatrix b b f := LinearMap.toMatrix₂_compl₂ _ _ _ B _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_compRight := LinearMap.BilinForm.toMatrix_compRight - @[simp] theorem LinearMap.BilinForm.toMatrix_mul_basis_toMatrix (c : Basis o R₁ M₁) (B : BilinForm R₁ M₁) : (b.toMatrix c)ᵀ * BilinForm.toMatrix b B * b.toMatrix c = BilinForm.toMatrix c B := LinearMap.toMatrix₂_mul_basis_toMatrix _ _ _ _ B -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_mul_basis_toMatrix := LinearMap.BilinForm.toMatrix_mul_basis_toMatrix - theorem LinearMap.BilinForm.mul_toMatrix_mul (B : BilinForm R₁ M₁) (M : Matrix o n R₁) (N : Matrix n o R₁) : M * BilinForm.toMatrix b B * N = BilinForm.toMatrix c (B.comp (Matrix.toLin c b Mᵀ) (Matrix.toLin c b N)) := LinearMap.mul_toMatrix₂_mul _ _ _ _ B _ _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.mul_toMatrix_mul := LinearMap.BilinForm.mul_toMatrix_mul - theorem LinearMap.BilinForm.mul_toMatrix (B : BilinForm R₁ M₁) (M : Matrix n n R₁) : M * BilinForm.toMatrix b B = BilinForm.toMatrix b (B.compLeft (Matrix.toLin b b Mᵀ)) := LinearMap.mul_toMatrix₂ _ _ _ B _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.mul_toMatrix := LinearMap.BilinForm.mul_toMatrix - theorem LinearMap.BilinForm.toMatrix_mul (B : BilinForm R₁ M₁) (M : Matrix n n R₁) : BilinForm.toMatrix b B * M = BilinForm.toMatrix b (B.compRight (Matrix.toLin b b M)) := LinearMap.toMatrix₂_mul _ _ _ B _ -@[deprecated (since := "2026-01-16")] -alias BilinForm.toMatrix_mul := LinearMap.BilinForm.toMatrix_mul - theorem Matrix.toBilin_comp (M : Matrix n n R₁) (P Q : Matrix n o R₁) : (Matrix.toBilin b M).comp (toLin c b P) (toLin c b Q) = Matrix.toBilin c (Pᵀ * M * Q) := by ext x y diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Complex.lean b/Mathlib/LinearAlgebra/QuadraticForm/Complex.lean deleted file mode 100644 index 101a1e438cc60b..00000000000000 --- a/Mathlib/LinearAlgebra/QuadraticForm/Complex.lean +++ /dev/null @@ -1,35 +0,0 @@ -/- -Copyright (c) 2020 Anne Baanen. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Anne Baanen, Kexing Ying, Eric Wieser --/ -module - -public import Mathlib.Data.Complex.Basic -public import Mathlib.LinearAlgebra.QuadraticForm.AlgClosed -public import Mathlib.Algebra.CharP.Invertible -import Mathlib.Analysis.Complex.Polynomial.Basic - -deprecated_module (since := "2026-01-19") - -public section - -open QuadraticMap - -namespace QuadraticForm - -@[deprecated "Use QuadraticForm.equivalent_weightedSumSquares_of_isAlgClosed" - (since := "2026-01-19")] -theorem equivalent_sum_squares {M : Type*} [AddCommGroup M] [Module ℂ M] [FiniteDimensional ℂ M] - (Q : QuadraticForm ℂ M) (hQ : (associated (R := ℂ) Q).SeparatingLeft) : - Equivalent Q (weightedSumSquares ℂ (1 : Fin (Module.finrank ℂ M) → ℂ)) := - equivalent_weightedSumSquares_of_isAlgClosed Q hQ - -@[deprecated "Use QuadraticForm.equivalent_of_isAlgClosed" (since := "2026-01-19")] -theorem complex_equivalent {M : Type*} [AddCommGroup M] [Module ℂ M] - [FiniteDimensional ℂ M] (Q₁ Q₂ : QuadraticForm ℂ M) - (hQ₁ : (associated Q₁).SeparatingLeft) - (hQ₂ : (associated Q₂).SeparatingLeft) : Equivalent Q₁ Q₂ := - equivalent_of_isAlgClosed Q₁ Q₂ hQ₁ hQ₂ - -end QuadraticForm diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index 926468dc1be635..557c007e6d6378 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -193,9 +193,6 @@ section Propositional alias Iff.imp := imp_congr -@[deprecated (since := "2026-01-30")] alias imp_iff_right_iff := Classical.imp_iff_right_iff -@[deprecated (since := "2026-01-30")] alias and_or_imp := Classical.and_or_imp - /-- Provide modus tollens (`mt`) as dot notation for implications. -/ protected theorem Function.mt {a b : Prop} : (a → b) → ¬b → ¬a := mt @@ -358,10 +355,6 @@ theorem imp_iff_or_not {b a : Prop} : b → a ↔ a ∨ ¬b := theorem not_imp_not : ¬a → ¬b ↔ b → a := open scoped Classical in Decidable.not_imp_not -@[deprecated Classical.imp_and_neg_imp_iff (since := "2026-01-30")] -theorem imp_and_neg_imp_iff (p q : Prop) : (p → q) ∧ (¬p → q) ↔ q := - Classical.imp_and_neg_imp_iff p - /-- Provide the reverse of modus tollens (`mt`) as dot notation for implications. -/ protected theorem Function.mtr : (¬a → ¬b) → b → a := not_imp_not.mp @@ -386,8 +379,6 @@ theorem imp_or {a b c : Prop} : a → b ∨ c ↔ (a → b) ∨ (a → c) := theorem imp_or' {a : Sort*} {b c : Prop} : a → b ∨ c ↔ (a → b) ∨ (a → c) := open scoped Classical in Decidable.imp_or' -@[deprecated (since := "2026-01-30")] alias not_imp := Classical.not_imp - theorem peirce (a b : Prop) : ((a → b) → a) → a := open scoped Classical in Decidable.peirce _ _ theorem not_iff_not : (¬a ↔ ¬b) ↔ (a ↔ b) := open scoped Classical in Decidable.not_iff_not diff --git a/Mathlib/Logic/Encodable/Basic.lean b/Mathlib/Logic/Encodable/Basic.lean index 1d367e6a4f5cd6..2f4d7626c1b6c6 100644 --- a/Mathlib/Logic/Encodable/Basic.lean +++ b/Mathlib/Logic/Encodable/Basic.lean @@ -81,11 +81,6 @@ theorem surjective_decode_getD (α : Type*) [Encodable α] (d : α) : Surjective fun n => (Encodable.decode n).getD d := fun x => ⟨Encodable.encode x, by simp_rw [Encodable.encodek]; rfl⟩ -@[deprecated surjective_decode_getD (since := "2026-01-05")] -theorem surjective_decode_iget (α : Type*) [Encodable α] [Inhabited α] : - Surjective fun n => ((Encodable.decode n).getD default : α) := - surjective_decode_getD α default - /-- An encodable type has decidable equality. Not set as an instance because this is usually not the best way to infer decidability. -/ @[instance_reducible] diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 4b990aaa2e420f..4efde3535fbff9 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -66,8 +66,6 @@ variable {r : α → α → Prop} @[deprecated (since := "2026-03-27")] alias Std.Refl.reflexive := refl -@[deprecated (since := "2026-01-09")] alias IsRefl.reflexive := refl - /-- To show a reflexive relation `r : α → α → Prop` holds over `x y : α`, it suffices to show it holds when `x ≠ y`. -/ theorem Std.Refl.rel_of_ne_imp [Std.Refl r] {x y : α} (hr : x ≠ y → r x y) : r x y := by diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean index cb37da1a32f73c..04006037e23fed 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean @@ -116,17 +116,11 @@ theorem measurable_edist_left : Measurable fun y ↦ edist y x := by fun_prop theorem measurable_infEDist {s : Set α} : Measurable fun x => infEDist x s := continuous_infEDist.measurable -@[deprecated (since := "2026-01-08")] -alias measurable_infEdist := measurable_infEDist - @[fun_prop] protected theorem Measurable.infEDist {f : β → α} (hf : Measurable f) {s : Set α} : Measurable fun x => infEDist (f x) s := measurable_infEDist.comp hf -@[deprecated (since := "2026-01-08")] -alias Measurable.infEdist := Measurable.infEDist - /-- If a set has a closed thickening with finite measure, then the measure of its `r`-closed thickenings converges to the measure of its closure as `r` tends to `0`. -/ theorem tendsto_measure_cthickening {μ : Measure α} {s : Set α} diff --git a/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean b/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean index a554bc1a8ee6a4..4f3db5cb2e2eaf 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean @@ -320,9 +320,6 @@ theorem all_ae_norm_ofReal_F_le_bound (h : ∀ n, ∀ᵐ a ∂μ, ‖F n a‖ ∀ n, ∀ᵐ a ∂μ, ENNReal.ofReal ‖F n a‖ ≤ ENNReal.ofReal (bound a) := fun n => (h n).mono fun _ h => ENNReal.ofReal_le_ofReal h -@[deprecated (since := "2026-01-26")] alias -all_ae_ofReal_F_le_bound := all_ae_norm_ofReal_F_le_bound - theorem ae_tendsto_enorm (h : ∀ᵐ a ∂μ, Tendsto (fun n ↦ F' n a) atTop <| 𝓝 <| f' a) : ∀ᵐ a ∂μ, Tendsto (fun n ↦ ‖F' n a‖ₑ) atTop <| 𝓝 <| ‖f' a‖ₑ := h.mono fun _ h ↦ Tendsto.comp (Continuous.tendsto continuous_enorm _) h @@ -331,8 +328,6 @@ theorem ae_tendsto_ofReal_norm (h : ∀ᵐ a ∂μ, Tendsto (fun n => F n a) atT ∀ᵐ a ∂μ, Tendsto (fun n => ENNReal.ofReal ‖F n a‖) atTop <| 𝓝 <| ENNReal.ofReal ‖f a‖ := by convert! ae_tendsto_enorm h <;> simp -@[deprecated (since := "2026-01-26")] alias all_ae_tendsto_ofReal_norm := ae_tendsto_ofReal_norm - theorem ae_norm_ofReal_f_le_bound (h_bound : ∀ n, ∀ᵐ a ∂μ, ‖F n a‖ ≤ bound a) (h_lim : ∀ᵐ a ∂μ, Tendsto (fun n => F n a) atTop (𝓝 (f a))) : ∀ᵐ a ∂μ, ENNReal.ofReal ‖f a‖ ≤ ENNReal.ofReal (bound a) := by @@ -342,8 +337,6 @@ theorem ae_norm_ofReal_f_le_bound (h_bound : ∀ n, ∀ᵐ a ∂μ, ‖F n a‖ intro a tendsto_norm F_le_bound exact le_of_tendsto' tendsto_norm F_le_bound -@[deprecated (since := "2026-01-26")] alias all_ae_ofReal_f_le_bound := ae_norm_ofReal_f_le_bound - theorem ae_enorm_le_bound (h_bound : ∀ n, ∀ᵐ a ∂μ, ‖F' n a‖ₑ ≤ bound' a) (h_lim : ∀ᵐ a ∂μ, Tendsto (fun n ↦ F' n a) atTop (𝓝 (f' a))) : ∀ᵐ a ∂μ, ‖f' a‖ₑ ≤ bound' a := by diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index fcefb8eaa1c137..e36f013e5e9ee8 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -527,8 +527,6 @@ protected theorem Measurable.comp {_ : MeasurableSpace α} {_ : MeasurableSpace attribute [fun_prop] Measurable.fun_comp -@[deprecated (since := "2026-01-23")] alias Measurable.comp' := Measurable.fun_comp - @[simp, fun_prop] theorem measurable_const {_ : MeasurableSpace α} {_ : MeasurableSpace β} {a : α} : Measurable fun _ : β => a := fun s _ => .const (a ∈ s) diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean index d6538e19f43682..61792c16573586 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean @@ -153,9 +153,6 @@ theorem volume_eball (a : ℝ) (r : ℝ≥0∞) : volume (Metric.eball a r) = 2 rw [Metric.eball_coe, volume_ball, two_mul, ← NNReal.coe_add, ENNReal.ofReal_coe_nnreal, ENNReal.coe_add, two_mul] -@[deprecated (since := "2026-01-24")] -alias volume_emetric_ball := volume_eball - @[simp] theorem volume_closedEBall (a : ℝ) (r : ℝ≥0∞) : volume (Metric.closedEBall a r) = 2 * r := by rcases eq_or_ne r ∞ with (rfl | hr) @@ -164,9 +161,6 @@ theorem volume_closedEBall (a : ℝ) (r : ℝ≥0∞) : volume (Metric.closedEBa rw [Metric.closedEBall_coe, volume_closedBall, two_mul, ← NNReal.coe_add, ENNReal.ofReal_coe_nnreal, ENNReal.coe_add, two_mul] -@[deprecated (since := "2026-01-24")] -alias volume_emetric_closedBall := volume_closedEBall - instance nullSingletonClass_volume : NullSingletonClass (volume : Measure ℝ) := ⟨fun _ => volume_singleton⟩ diff --git a/Mathlib/MeasureTheory/Measure/OpenPos.lean b/Mathlib/MeasureTheory/Measure/OpenPos.lean index cf337d162b0566..8107499cfcfddf 100644 --- a/Mathlib/MeasureTheory/Measure/OpenPos.lean +++ b/Mathlib/MeasureTheory/Measure/OpenPos.lean @@ -239,12 +239,6 @@ theorem measure_closedEBall_pos (x : X) {r : ℝ≥0∞} (hr : r ≠ 0) : 0 < μ end Metric -@[deprecated (since := "2026-01-24")] -alias EMetric.measure_ball_pos := Metric.measure_eball_pos - -@[deprecated (since := "2026-01-24")] -alias EMetric.measure_closedBall_pos := Metric.measure_closedEBall_pos - section MeasureZero /-! ## Meagre sets and measure zero In general, neither of meagre and measure zero implies the other. diff --git a/Mathlib/NumberTheory/ModularForms/SlashActions.lean b/Mathlib/NumberTheory/ModularForms/SlashActions.lean index dc666c4dae75c6..4f5064fdc9c0b0 100644 --- a/Mathlib/NumberTheory/ModularForms/SlashActions.lean +++ b/Mathlib/NumberTheory/ModularForms/SlashActions.lean @@ -250,13 +250,6 @@ lemma prod_slash {ι : Type*} {k : ℤ} {g : GL (Fin 2) ℝ} {f : ι → ℍ → rw [this] exact prod_slash_sum_weights -@[deprecated prod_slash (since := "2026-01-22")] -lemma prod_fintype_slash {ι : Type*} [Fintype ι] [Nonempty ι] {k : ℤ} {g : GL (Fin 2) ℝ} - {f : ι → ℍ → ℂ} : (∏ i, f i) ∣[k * Fintype.card ι] g = - |g.det.val| ^ (Fintype.card ι - 1) • (∏ i, f i ∣[k] g) := by - have : 0 < Fintype.card ι := Fintype.card_pos - simpa [← zpow_natCast, this] using ModularForm.prod_slash (s := (.univ : Finset ι)) - end end ModularForm diff --git a/Mathlib/Order/Antichain.lean b/Mathlib/Order/Antichain.lean index 33447320056fba..2bcf7f498a2893 100644 --- a/Mathlib/Order/Antichain.lean +++ b/Mathlib/Order/Antichain.lean @@ -71,8 +71,6 @@ protected theorem eq' (hs : IsAntichain r s) {a b : α} (ha : a ∈ s) (hb : b protected theorem antisymm (h : IsAntichain r univ) : Std.Antisymm r := ⟨fun _ _ ha _ => h.eq trivial trivial ha⟩ -@[deprecated (since := "2026-01-06")] protected alias isAntisymm := antisymm - protected theorem subsingleton [Std.Trichotomous r] (h : IsAntichain r s) : s.Subsingleton := by rintro a ha b hb obtain hab | hab | hab := trichotomous_of r a b diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index d1d39f236d70ce..1e16519eed3f4c 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -108,11 +108,6 @@ alias LE.le.isCofinalFor := IsCofinalFor.of_subset @[deprecated (since := "2026-03-23")] alias HasSubset.Subset.isCofinalFor := LE.le.isCofinalFor @[deprecated (since := "2026-03-23")] alias HasSubset.Subset.isCoinitialFor := LE.le.isCoinitialFor -@[deprecated LE.le.isCofinalFor (since := "2026-01-08")] -alias HasSubset.Subset.iscofinalfor := IsCofinalFor.of_subset -@[deprecated LE.le.isCoinitialFor (since := "2026-01-08")] -alias HasSubset.Subset.iscoinitialfor := IsCoinitialFor.of_subset - @[to_dual (attr := refl)] protected lemma IsCofinalFor.rfl : IsCofinalFor s s := .of_subset .rfl @@ -453,9 +448,6 @@ theorem bddAbove_Iio : BddAbove (Iio a) := theorem le_of_isLUB_Iio (a : α) (hb : IsLUB (Iio a) b) : b ≤ a := (isLUB_le_iff hb).mpr fun _ hk => le_of_lt hk -@[deprecated (since := "2026-01-17")] alias lub_Iio_le := le_of_isLUB_Iio -@[deprecated (since := "2026-01-17")] alias le_glb_Ioi := le_of_isGLB_Ioi - @[to_dual] theorem lub_Iio_eq_self_or_Iio_eq_Iic [PartialOrder γ] {j : γ} (i : γ) (hj : IsLUB (Iio i) j) : j = i ∨ Iio i = Iic j := by diff --git a/Mathlib/Order/Comparable.lean b/Mathlib/Order/Comparable.lean index 1af998bfe0bce5..2e480821fe3bfb 100644 --- a/Mathlib/Order/Comparable.lean +++ b/Mathlib/Order/Comparable.lean @@ -43,136 +43,6 @@ variable {α : Type*} {a b c d : α} /-! ### Comparability -/ -section Relation - -variable {r : α → α → Prop} - -/-- The comparability relation `CompRel r a b` means that either `r a b` or `r b a`. -/ -@[deprecated SymmGen (since := "2026-01-25")] -def CompRel (r : α → α → Prop) (a b : α) : Prop := - r a b ∨ r b a - -@[deprecated SymmGen.of_rel (since := "2026-01-25")] -theorem CompRel.of_rel (h : r a b) : CompRel r a b := - SymmGen.of_rel h - -@[deprecated SymmGen.of_rel_symm (since := "2026-01-25")] -theorem CompRel.of_rel_symm (h : r b a) : CompRel r a b := - SymmGen.of_rel_symm h - -@[deprecated symmGen_swap (since := "2026-01-25")] -theorem compRel_swap (r : α → α → Prop) : CompRel (swap r) = CompRel r := - symmGen_swap r - -@[deprecated symmGen_swap_apply (since := "2026-01-25")] -theorem compRel_swap_apply (r : α → α → Prop) : CompRel (swap r) a b ↔ CompRel r a b := - symmGen_swap_apply r - -@[simp, refl, deprecated SymmGen.refl (since := "2026-01-25")] -theorem CompRel.refl (r : α → α → Prop) [Std.Refl r] (a : α) : CompRel r a a := - SymmGen.refl r a - -@[deprecated SymmGen.rfl (since := "2026-01-25")] -theorem CompRel.rfl [Std.Refl r] : CompRel r a a := SymmGen.rfl - -@[deprecated SymmGen.instRefl (since := "2026-01-25")] -instance [Std.Refl r] : Std.Refl (CompRel r) := - SymmGen.instRefl - -@[symm, deprecated SymmGen.symm (since := "2026-01-25")] -theorem CompRel.symm : CompRel r a b → CompRel r b a := - SymmGen.symm - -@[deprecated SymmGen.instSymm (since := "2026-01-25")] -instance : Std.Symm (CompRel r) := - SymmGen.instSymm - -@[deprecated symmGen_comm (since := "2026-01-25")] -theorem compRel_comm {a b : α} : CompRel r a b ↔ CompRel r b a := - symmGen_comm - -@[deprecated SymmGen.decidableRel (since := "2026-01-25")] -instance CompRel.decidableRel [DecidableRel r] : DecidableRel (CompRel r) := - SymmGen.decidableRel - -@[deprecated AntisymmRel.symmGen (since := "2026-01-25")] -theorem AntisymmRel.compRel (h : AntisymmRel r a b) : CompRel r a b := - AntisymmRel.symmGen h - -@[simp, deprecated symmGen_of_total (since := "2026-01-25")] -theorem compRel_of_total [Std.Total r] (a b : α) : CompRel r a b := - symmGen_of_total a b - -@[deprecated (since := "2026-01-13")] alias IsTotal.compRel := symmGen_of_total - -end Relation - -section LE - -variable [LE α] - -@[deprecated SymmGen.of_le (since := "2026-01-25")] -theorem CompRel.of_le (h : a ≤ b) : CompRel (· ≤ ·) a b := SymmGen.of_le h - -@[deprecated SymmGen.of_ge (since := "2026-01-25")] -theorem CompRel.of_ge (h : b ≤ a) : CompRel (· ≤ ·) a b := SymmGen.of_ge h - -alias LE.le.compRel := CompRel.of_le -alias LE.le.compRel_symm := CompRel.of_ge - -end LE - -section Preorder - -variable [Preorder α] - -@[deprecated SymmGen.of_lt (since := "2026-01-25")] -theorem CompRel.of_lt (h : a < b) : CompRel (· ≤ ·) a b := SymmGen.of_lt h - -@[deprecated SymmGen.of_gt (since := "2026-01-25")] -theorem CompRel.of_gt (h : b < a) : CompRel (· ≤ ·) a b := SymmGen.of_gt h - -alias LT.lt.compRel := CompRel.of_lt -alias LT.lt.compRel_symm := CompRel.of_gt - -@[trans, deprecated SymmGen.of_symmGen_of_antisymmRel (since := "2026-01-25")] -theorem CompRel.of_compRel_of_antisymmRel - (h₁ : CompRel (· ≤ ·) a b) (h₂ : AntisymmRel (· ≤ ·) b c) : CompRel (· ≤ ·) a c := - SymmGen.of_symmGen_of_antisymmRel h₁ h₂ - -alias CompRel.trans_antisymmRel := CompRel.of_compRel_of_antisymmRel - -@[deprecated instTransSymmGenLeAntisymmRel (since := "2026-01-25")] -instance : @Trans α α α (CompRel (· ≤ ·)) (AntisymmRel (· ≤ ·)) (CompRel (· ≤ ·)) := - instTransSymmGenLeAntisymmRel - -@[trans, deprecated SymmGen.of_antisymmRel_of_symmGen (since := "2026-01-25")] -theorem CompRel.of_antisymmRel_of_compRel - (h₁ : AntisymmRel (· ≤ ·) a b) (h₂ : CompRel (· ≤ ·) b c) : CompRel (· ≤ ·) a c := - SymmGen.of_antisymmRel_of_symmGen h₁ h₂ - -alias AntisymmRel.trans_compRel := CompRel.of_antisymmRel_of_compRel -@[deprecated instTransAntisymmRelLeSymmGen (since := "2026-01-25")] -instance : @Trans α α α (AntisymmRel (· ≤ ·)) (CompRel (· ≤ ·)) (CompRel (· ≤ ·)) := - instTransAntisymmRelLeSymmGen - -@[deprecated AntisymmRel.symmGen_congr (since := "2026-01-25")] -theorem AntisymmRel.compRel_congr (h₁ : AntisymmRel (· ≤ ·) a b) (h₂ : AntisymmRel (· ≤ ·) c d) : - CompRel (· ≤ ·) a c ↔ CompRel (· ≤ ·) b d := - AntisymmRel.symmGen_congr h₁ h₂ - -@[deprecated AntisymmRel.symmGen_congr_left (since := "2026-01-25")] -theorem AntisymmRel.compRel_congr_left (h : AntisymmRel (· ≤ ·) a b) : - CompRel (· ≤ ·) a c ↔ CompRel (· ≤ ·) b c := - AntisymmRel.symmGen_congr_left h - -@[deprecated AntisymmRel.symmGen_congr_right (since := "2026-01-25")] -theorem AntisymmRel.compRel_congr_right (h : AntisymmRel (· ≤ ·) b c) : - CompRel (· ≤ ·) a b ↔ CompRel (· ≤ ·) a c := - AntisymmRel.symmGen_congr_right h - -end Preorder - /-- A partial order where any two elements are comparable is a linear order. -/ @[instance_reducible] def Relation.linearOrderOfSymmGen [PartialOrder α] @@ -183,13 +53,6 @@ def Relation.linearOrderOfSymmGen [PartialOrder α] toDecidableEq := decEq toDecidableLT := decLT -/-- A partial order where any two elements are comparable is a linear order. -/ -@[deprecated linearOrderOfSymmGen (since := "2026-01-25"), instance_reducible] -def linearOrderOfComprel [PartialOrder α] - [decLE : DecidableLE α] [decLT : DecidableLT α] [decEq : DecidableEq α] - (h : ∀ a b : α, CompRel (· ≤ ·) a b) : LinearOrder α := - linearOrderOfSymmGen h - /-! ### Incomparability relation -/ section Relation @@ -254,24 +117,14 @@ theorem AntisymmRel.not_incompRel (h : AntisymmRel r a b) : ¬ IncompRel r a b : theorem not_symmGen_iff : ¬ Relation.SymmGen r a b ↔ IncompRel r a b := by simp [Relation.SymmGen, IncompRel] -@[deprecated not_symmGen_iff (since := "2026-01-25")] -theorem not_compRel_iff : ¬ CompRel r a b ↔ IncompRel r a b := - not_symmGen_iff - theorem not_incompRel_iff_symmGen : ¬ IncompRel r a b ↔ Relation.SymmGen r a b := by rw [← not_symmGen_iff, not_not] -@[deprecated not_incompRel_iff_symmGen (since := "2026-01-25")] -theorem not_incompRel_iff : ¬ IncompRel r a b ↔ CompRel r a b := - not_incompRel_iff_symmGen - @[simp] theorem not_incompRel_of_total [Std.Total r] (a b : α) : ¬ IncompRel r a b := by rw [not_incompRel_iff_symmGen] exact symmGen_of_total a b -@[deprecated (since := "2026-01-13")] alias IsTotal.not_incompRel := not_incompRel_of_total - theorem IncompRel.ne [Std.Refl r] {a b : α} (h : IncompRel r a b) : a ≠ b := by rintro rfl exact h.1 <| refl_of r a diff --git a/Mathlib/Order/Defs/Unbundled.lean b/Mathlib/Order/Defs/Unbundled.lean index 6515efb649d119..28a3e8bc65c0d2 100644 --- a/Mathlib/Order/Defs/Unbundled.lean +++ b/Mathlib/Order/Defs/Unbundled.lean @@ -22,24 +22,6 @@ and proves some basic lemmas about them. /-! ### Unbundled classes -/ -/-- `IsIrrefl X r` means the binary relation `r` on `X` is irreflexive (that is, `r x x` never -holds). -/ -@[deprecated Std.Irrefl (since := "2026-01-07")] -abbrev IsIrrefl (α : Sort*) (r : α → α → Prop) : Prop := Std.Irrefl r - -/-- `IsRefl X r` means the binary relation `r` on `X` is reflexive. -/ -@[deprecated Std.Refl (since := "2026-01-08")] -abbrev IsRefl (α : Sort*) (r : α → α → Prop) : Prop := Std.Refl r - -/-- `IsAsymm X r` means that the binary relation `r` on `X` is asymmetric, that is, -`r a b → ¬ r b a`. -/ -@[deprecated Std.Asymm (since := "2026-01-03")] -abbrev IsAsymm (α : Sort*) (r : α → α → Prop) : Prop := Std.Asymm r - -/-- `IsAntisymm X r` means the binary relation `r` on `X` is antisymmetric. -/ -@[deprecated Std.Antisymm (since := "2026-01-06")] -abbrev IsAntisymm (α : Sort*) (r : α → α → Prop) : Prop := Std.Antisymm r - /-- `IsTrans X r` means the binary relation `r` on `X` is transitive. -/ class IsTrans (α : Sort*) (r : α → α → Prop) : Prop where trans : ∀ a b c, r a b → r b c → r a c @@ -50,11 +32,6 @@ instance {α : Sort*} {r : α → α → Prop} [IsTrans α r] : Trans r r r := instance (priority := 100) {α : Sort*} {r : α → α → Prop} [Trans r r r] : IsTrans α r := ⟨fun _ _ _ => Trans.trans⟩ -/-- `IsTotal X r` means that the binary relation `r` on `X` is total, that is, that for any -`x y : X` we have `r x y` or `r y x`. -/ -@[deprecated Std.Total (since := "2026-01-09")] -abbrev IsTotal (α : Sort*) (r : α → α → Prop) : Prop := Std.Total r - /-- `IsPreorder X r` means that the binary relation `r` on `X` is a pre-order, that is, reflexive and transitive. -/ class IsPreorder (α : Sort*) (r : α → α → Prop) : Prop extends Std.Refl r, IsTrans α r @@ -80,11 +57,6 @@ that is, `IsStrictOrder X lt` and `¬lt a b ∧ ¬lt b a → ¬lt b c ∧ ¬lt c class IsStrictWeakOrder (α : Sort*) (lt : α → α → Prop) : Prop extends IsStrictOrder α lt where incomp_trans : ∀ a b c, ¬lt a b ∧ ¬lt b a → ¬lt b c ∧ ¬lt c b → ¬lt a c ∧ ¬lt c a -/-- `IsTrichotomous X lt` means that the binary relation `lt` on `X` is trichotomous, that is, -either `lt a b` or `a = b` or `lt b a` for any `a` and `b`. -/ -@[deprecated Std.Trichotomous (since := "2026-01-24")] -abbrev IsTrichotomous (α : Sort*) (lt : α → α → Prop) : Prop := Std.Trichotomous lt - /-- `IsStrictTotalOrder X lt` means that the binary relation `lt` on `X` is a strict total order, that is, `Std.Trichotomous lt` and `IsStrictOrder X lt`. -/ class IsStrictTotalOrder (α : Sort*) (lt : α → α → Prop) : Prop @@ -398,20 +370,12 @@ theorem comm_of (r : α → α → Prop) [Std.Symm r] {a b : α} : r a b ↔ r b protected theorem Std.Asymm.antisymm (r : α → α → Prop) [Std.Asymm r] : Std.Antisymm r := inferInstance -@[deprecated (since := "2026-01-05")] protected alias IsAsymm.isAntisymm := Std.Asymm.antisymm -@[deprecated (since := "2026-01-06")] protected alias Std.Asymm.isAntisymm := Std.Asymm.antisymm - protected theorem Std.Asymm.irrefl [Std.Asymm r] : Std.Irrefl r := inferInstance -@[deprecated (since := "2026-01-05")] protected alias IsAsymm.isIrrefl := Std.Asymm.irrefl -@[deprecated (since := "2026-01-07")] protected alias Std.Asymm.isIrrefl := Std.Asymm.irrefl - protected theorem Std.Total.trichotomous (r : α → α → Prop) [Std.Total r] : Std.Trichotomous r := inferInstance -@[deprecated (since := "2026-01-24")] alias Std.Total.isTrichotomous := Std.Total.trichotomous - -- see Note [lower instance priority] instance (priority := 100) Std.Total.to_refl (r : α → α → Prop) [Std.Total r] : Std.Refl r := inferInstance diff --git a/Mathlib/Order/Notation.lean b/Mathlib/Order/Notation.lean index a9cc7495f656de..8422d938de3953 100644 --- a/Mathlib/Order/Notation.lean +++ b/Mathlib/Order/Notation.lean @@ -47,19 +47,10 @@ class Compl (α : Type*) where export Compl (compl) -/-- Set / lattice complement -/ -@[deprecated Compl (since := "2026-01-04")] -class HasCompl (α : Type*) where - /-- Set / lattice complement -/ - compl : α → α - -attribute [deprecated Compl.compl (since := "2026-01-04")] HasCompl.compl - @[inherit_doc] postfix:1024 "ᶜ" => compl initialize_simps_projections Compl -initialize_simps_projections HasCompl /-! ### `Sup` and `Inf` -/ diff --git a/Mathlib/Order/PiLex.lean b/Mathlib/Order/PiLex.lean index 1d2a72aece1d7e..fbea8f946d09b4 100644 --- a/Mathlib/Order/PiLex.lean +++ b/Mathlib/Order/PiLex.lean @@ -79,8 +79,6 @@ theorem trichotomous_lex [∀ i, Std.Trichotomous (α := β i) s] (wf : WellFoun have := Std.Trichotomous.trichotomous (a i) (b i) (hab ⟨i, hri, ·⟩) exact hba ⟨i, (hri · · |>.symm), Not.imp_symm this <| wf.min_mem {i | a i ≠ b i} h⟩ } -@[deprecated (since := "2026-01-24")] alias isTrichotomous_lex := trichotomous_lex - /- These instances are leaky, because they define the relation on `∀ i, β i` instead of `Lex (∀ i, β i)`/`Colex (∀ i, β i)`. So, we would like to mark them `@[semireducible]`. diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index ffdfdd4ad82556..fa9d7be51bee23 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -31,8 +31,6 @@ open Function theorem Std.Refl.swap (r : α → α → Prop) [Std.Refl r] : Std.Refl (swap r) := inferInstance -@[deprecated (since := "2026-01-09")] alias IsRefl.swap := Std.Refl.swap - @[deprecated inferInstance (since := "2026-04-28")] theorem Std.Irrefl.swap (r : α → α → Prop) [Std.Irrefl r] : Std.Irrefl (swap r) := inferInstance @@ -49,8 +47,6 @@ theorem Std.Antisymm.swap (r : α → α → Prop) [Std.Antisymm r] : Std.Antisy theorem Std.Asymm.swap (r : α → α → Prop) [Std.Asymm r] : Std.Asymm (swap r) := inferInstance -@[deprecated (since := "2026-01-05")] alias IsAsymm.swap := Std.Asymm.swap - @[deprecated inferInstance (since := "2026-04-28")] theorem Std.Total.swap (r : α → α → Prop) [Std.Total r] : Std.Total (swap r) := inferInstance @@ -59,8 +55,6 @@ theorem Std.Total.swap (r : α → α → Prop) [Std.Total r] : Std.Total (swap theorem Std.Trichotomous.swap (r : α → α → Prop) [Std.Trichotomous r] : Std.Trichotomous (swap r) := inferInstance -@[deprecated (since := "2026-01-24")] alias IsTrichotomous.swap := Std.Trichotomous.swap - @[deprecated inferInstance (since := "2026-04-28")] theorem IsPreorder.swap (r) [IsPreorder α r] : IsPreorder α (swap r) := inferInstance @@ -151,8 +145,6 @@ theorem InvImage.trichotomous [Std.Trichotomous r] {f : β → α} (h : Function Std.Trichotomous (InvImage r f) := ⟨fun {a b} hab hba ↦ h <| Std.Trichotomous.trichotomous (f a) (f b) hab hba⟩ -@[deprecated (since := "2026-01-24")] alias InvImage.isTrichotomous := InvImage.trichotomous - instance InvImage.asymm [Std.Asymm r] (f : β → α) : Std.Asymm (InvImage r f) where asymm a b h h2 := Std.Asymm.asymm (f a) (f b) h h2 @@ -379,9 +371,6 @@ instance Prod.wellFoundedLT [Preorder α] [WellFoundedLT α] [Preorder β] [Well · exact iha x.1 (ha'.trans_le ha) x.1 le_rfl x.2 · exact ihb x.2 hb x.1 (ha'.trans ha) -@[deprecated (since := "2026-01-12")] alias Prod.wellFoundedLT' := Prod.wellFoundedLT -@[deprecated (since := "2026-01-12")] alias Prod.wellFoundedGT' := Prod.wellFoundedGT - namespace Set /-- An unbounded or cofinal set. -/ @@ -438,8 +427,6 @@ instance instTotal [Std.Total r] {f : β → α} : Std.Total (f ⁻¹'o r) := theorem antisymm [Std.Antisymm r] {f : β → α} (hf : f.Injective) : Std.Antisymm (f ⁻¹'o r) := ⟨fun _ _ h₁ h₂ ↦ hf <| antisymm_of r h₁ h₂⟩ -@[deprecated (since := "2026-01-06")] alias isAntisymm := antisymm - end Order.Preimage /-! ### Strict-non strict relations -/ @@ -475,8 +462,6 @@ attribute [to_set_notation] @[deprecated (since := "2026-05-24")] alias HasSubset.subset.trans_eq := LE.le.trans_eq -@[deprecated (since := "2026-01-24")] alias Eq.subset' := Eq.subset - @[deprecated LE.le.trans (since := "2026-05-24")] alias HasSubset.Subset.trans := subset_trans diff --git a/Mathlib/Order/RelIso/Basic.lean b/Mathlib/Order/RelIso/Basic.lean index 8a0e924fa22292..e3e47e2c7da39d 100644 --- a/Mathlib/Order/RelIso/Basic.lean +++ b/Mathlib/Order/RelIso/Basic.lean @@ -77,13 +77,9 @@ variable {F : Type*} [FunLike F α β] protected theorem irrefl [RelHomClass F r s] (f : F) : ∀ [Std.Irrefl s], Std.Irrefl r | ⟨H⟩ => ⟨fun _ h => H _ (map_rel f h)⟩ -@[deprecated (since := "2026-01-07")] protected alias isIrrefl := RelHomClass.irrefl - protected theorem asymm [RelHomClass F r s] (f : F) : ∀ [Std.Asymm s], Std.Asymm r | ⟨H⟩ => ⟨fun _ _ h₁ h₂ => H _ _ (map_rel f h₁) (map_rel f h₂)⟩ -@[deprecated (since := "2026-01-07")] protected alias isAsymm := RelHomClass.asymm - protected theorem acc [RelHomClass F r s] (f : F) (a : α) : Acc s (f a) → Acc r a := by generalize h : f a = b intro ac @@ -317,36 +313,24 @@ theorem eq_preimage (f : r ↪r s) : r = f ⁻¹'o s := by protected theorem irrefl (f : r ↪r s) [Std.Irrefl s] : Std.Irrefl r := ⟨fun a => mt f.map_rel_iff.2 (irrefl (f a))⟩ -@[deprecated (since := "2026-01-07")] protected alias isIrrefl := RelEmbedding.irrefl - protected theorem stdRefl (f : r ↪r s) [Std.Refl s] : Std.Refl r := ⟨fun _ => f.map_rel_iff.1 <| refl _⟩ -@[deprecated (since := "2026-01-08")] protected alias isRefl := RelEmbedding.stdRefl - protected theorem symm (f : r ↪r s) [Std.Symm s] : Std.Symm r := ⟨fun _ _ => imp_imp_imp f.map_rel_iff.2 f.map_rel_iff.1 symm⟩ -@[deprecated (since := "2026-01-06")] protected alias isSymm := RelEmbedding.symm - protected theorem asymm (f : r ↪r s) [Std.Asymm s] : Std.Asymm r := ⟨fun _ _ h₁ h₂ => asymm (f.map_rel_iff.2 h₁) (f.map_rel_iff.2 h₂)⟩ -@[deprecated (since := "2026-01-07")] protected alias isAsymm := RelEmbedding.asymm - protected theorem antisymm : ∀ (_ : r ↪r s) [Std.Antisymm s], Std.Antisymm r | ⟨f, o⟩, ⟨H⟩ => ⟨fun _ _ h₁ h₂ => f.inj' (H _ _ (o.2 h₁) (o.2 h₂))⟩ -@[deprecated (since := "2026-01-06")] protected alias isAntisymm := RelEmbedding.antisymm - protected theorem isTrans : ∀ (_ : r ↪r s) [IsTrans β s], IsTrans α r | ⟨_, o⟩, ⟨H⟩ => ⟨fun _ _ _ h₁ h₂ => o.1 (H _ _ _ (o.2 h₁) (o.2 h₂))⟩ protected theorem total : ∀ (_ : r ↪r s) [Std.Total s], Std.Total r | ⟨_, o⟩, ⟨H⟩ => ⟨fun _ _ => (or_congr o o).1 (H _ _)⟩ -@[deprecated (since := "2026-01-09")] protected alias isTotal := RelEmbedding.total - protected theorem isPreorder : ∀ (_ : r ↪r s) [IsPreorder β s], IsPreorder α r | f, _ => { f.stdRefl, f.isTrans with } @@ -362,8 +346,6 @@ protected theorem isStrictOrder : ∀ (_ : r ↪r s) [IsStrictOrder β s], IsStr protected theorem trichotomous : ∀ (_ : r ↪r s) [Std.Trichotomous s], Std.Trichotomous r | ⟨f, o⟩, ⟨H⟩ => ⟨fun _ _ hab hba ↦ f.injective <| H _ _ (o.not.mpr hab) (o.not.mpr hba)⟩ -@[deprecated (since := "2026-01-24")] protected alias isTrichotomous := RelEmbedding.trichotomous - protected theorem isStrictTotalOrder : ∀ (_ : r ↪r s) [IsStrictTotalOrder β s], IsStrictTotalOrder α r | f, _ => { f.trichotomous, f.isStrictOrder with } diff --git a/Mathlib/Order/WellFounded.lean b/Mathlib/Order/WellFounded.lean index 9aec1f0dfcf2a0..f05f3a2fbffad5 100644 --- a/Mathlib/Order/WellFounded.lean +++ b/Mathlib/Order/WellFounded.lean @@ -61,12 +61,8 @@ variable {r r' : α → α → Prop} protected theorem asymm (h : WellFounded r) : Std.Asymm r := ⟨h.asymmetric⟩ -@[deprecated (since := "2026-01-07")] protected alias isAsymm := WellFounded.asymm - protected theorem irrefl (h : WellFounded r) : Std.Irrefl r := @Std.Asymm.irrefl α r h.asymm -@[deprecated (since := "2026-01-07")] protected alias isIrrefl := WellFounded.irrefl - instance [WellFoundedRelation α] : Std.Asymm (α := α) WellFoundedRelation.rel := WellFoundedRelation.wf.asymm diff --git a/Mathlib/Probability/Moments/SubGaussian.lean b/Mathlib/Probability/Moments/SubGaussian.lean index 040fc9790b7c21..f41e748d373659 100644 --- a/Mathlib/Probability/Moments/SubGaussian.lean +++ b/Mathlib/Probability/Moments/SubGaussian.lean @@ -895,10 +895,6 @@ lemma HasSubgaussianMGF.add_of_hasCondSubgaussianMGF [IsFiniteMeasure μ] ext rw [Kernel.const_apply, ← Measure.compProd, compProd_trim_condExpKernel] -@[deprecated (since := "2026-01-27")] -alias HasSubgaussianMGF_add_of_HasCondSubgaussianMGF := - HasSubgaussianMGF.add_of_hasCondSubgaussianMGF - variable {Y : ℕ → Ω → ℝ} {cY : ℕ → ℝ≥0} {ℱ : Filtration ℕ mΩ} /-- Let `Y` be a random process strongly adapted to a filtration `ℱ`, such that for all `i : ℕ`, @@ -924,10 +920,6 @@ lemma HasSubgaussianMGF.sum_of_hasCondSubgaussianMGF [IsZeroOrProbabilityMeasure simp only [Finset.mem_range] at hm lia -@[deprecated (since := "2026-01-27")] -alias HasSubgaussianMGF_sum_of_HasCondSubgaussianMGF := - HasSubgaussianMGF.sum_of_hasCondSubgaussianMGF - /-- **Azuma-Hoeffding inequality** for sub-Gaussian random variables. -/ lemma measure_sum_ge_le_of_hasCondSubgaussianMGF [IsZeroOrProbabilityMeasure μ] (h_adapted : StronglyAdapted ℱ Y) (h0 : HasSubgaussianMGF (Y 0) (cY 0) μ) (n : ℕ) @@ -937,9 +929,6 @@ lemma measure_sum_ge_le_of_hasCondSubgaussianMGF [IsZeroOrProbabilityMeasure μ] ≤ exp (-ε ^ 2 / (2 * ∑ i ∈ Finset.range n, cY i)) := (HasSubgaussianMGF.sum_of_hasCondSubgaussianMGF h_adapted h0 n h_subG).measure_ge_le hε -@[deprecated (since := "2026-01-27")] -alias measure_sum_ge_le_of_HasCondSubgaussianMGF := measure_sum_ge_le_of_hasCondSubgaussianMGF - end Martingale end ProbabilityTheory diff --git a/Mathlib/Probability/Process/HittingTime.lean b/Mathlib/Probability/Process/HittingTime.lean index b941ce3b41e804..d0ea12da69e871 100644 --- a/Mathlib/Probability/Process/HittingTime.lean +++ b/Mathlib/Probability/Process/HittingTime.lean @@ -409,9 +409,6 @@ theorem Adapted.isStoppingTime_hittingBtwn [ConditionallyCompleteLinearOrder ι] simpa [h_set_eq_Union] using MeasurableSet.iUnion fun j => MeasurableSet.iUnion fun hj => f.mono hj.2 _ ((hu j) hs) -@[deprecated (since := "2026-01-25")] -alias hittingBtwn_isStoppingTime := Adapted.isStoppingTime_hittingBtwn - theorem Adapted.isStoppingTime_hittingAfter [ConditionallyCompleteLinearOrder ι] [WellFoundedLT ι] [Countable ι] {_ : MeasurableSpace β} {f : Filtration ι m} {u : ι → Ω → β} {s : Set β} {n : ι} (hu : Adapted f u) (hs : MeasurableSet s) : @@ -422,9 +419,6 @@ theorem Adapted.isStoppingTime_hittingAfter [ConditionallyCompleteLinearOrder ι simpa [h_set_eq_Union] using MeasurableSet.iUnion fun j => MeasurableSet.iUnion fun hj => f.mono hj.2 _ ((hu j) hs) -@[deprecated (since := "2026-01-25")] -alias hittingAfter_isStoppingTime := Adapted.isStoppingTime_hittingAfter - theorem stoppedValue_hittingBtwn_mem [ConditionallyCompleteLinearOrder ι] [WellFoundedLT ι] {u : ι → Ω → β} {s : Set β} {n m : ι} {ω : Ω} (h : ∃ j ∈ Set.Icc n m, u j ω ∈ s) : stoppedValue u (fun ω ↦ (hittingBtwn u s n m ω : ι)) ω ∈ s := by @@ -468,9 +462,6 @@ theorem Adapted.isStoppingTime_hittingBtwn_isStoppingTime [ConditionallyComplete (f.mono hi _ (hτ.measurableSet_eq i)).inter ?_ simpa using hf.isStoppingTime_hittingBtwn hs n -@[deprecated (since := "2026-01-25")] -alias isStoppingTime_hittingBtwn_isStoppingTime := Adapted.isStoppingTime_hittingBtwn_isStoppingTime - section CompleteLattice variable [CompleteLattice ι] {u : ι → Ω → β} {s : Set β} diff --git a/Mathlib/Probability/Process/Predictable.lean b/Mathlib/Probability/Process/Predictable.lean index a65eba9fe22b23..d296eac3c6a52d 100644 --- a/Mathlib/Probability/Process/Predictable.lean +++ b/Mathlib/Probability/Process/Predictable.lean @@ -259,15 +259,6 @@ end Discrete end IsStronglyPredictable -@[deprecated IsStronglyPredictable.stronglyAdapted (since := "2026-01-05")] -theorem Predictable.stronglyAdapted {β : Type*} [TopologicalSpace β] {f : Filtration ℕ m} - {u : ℕ → Ω → β} (hu : StronglyAdapted f fun n => u (n + 1)) - (hu0 : StronglyMeasurable[f 0] (u 0)) : - StronglyAdapted f u := fun n => - match n with - | 0 => hu0 - | n + 1 => (hu n).mono (f.mono n.le_succ) - @[deprecated (since := "2026-04-24")] alias IsPredictable := IsStronglyPredictable diff --git a/Mathlib/Probability/UniformOn.lean b/Mathlib/Probability/UniformOn.lean index dde1c39b4d0397..3943579f0379a0 100644 --- a/Mathlib/Probability/UniformOn.lean +++ b/Mathlib/Probability/UniformOn.lean @@ -116,9 +116,6 @@ theorem isProbabilityMeasure_uniformOn {s : Set Ω} (hs : s.Finite) (hs' : s.Non · rwa [Measure.count_ne_zero_iff] · exact (Measure.count_apply_lt_top.2 hs).ne -@[deprecated (since := "2026-01-26")] -alias uniformOn_isProbabilityMeasure := isProbabilityMeasure_uniformOn - theorem uniformOn_singleton (ω : Ω) (t : Set Ω) [Decidable (ω ∈ t)] : uniformOn {ω} t = if ω ∈ t then 1 else 0 := by rw [uniformOn, cond_apply (measurableSet_singleton ω), Measure.count_singleton, inv_one, diff --git a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean index 49f01d2704827d..17bdb7db71d44c 100644 --- a/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean +++ b/Mathlib/RingTheory/DedekindDomain/AdicValuation.lean @@ -588,11 +588,6 @@ def adicValued : Valued K ℤᵐ⁰ := theorem adicValued_apply {x : K} : v.adicValued.v x = v.valuation K x := rfl -@[deprecated adicValued_apply (since := "2026-01-28")] -theorem adicValued_apply' (x : WithVal (v.valuation K)) : - v.adicValued.v (WithVal.equiv _ x) = v.valuation K (WithVal.equiv _ x) := - rfl - variable (K) /-- The completion of `K` with respect to its `v`-adic valuation, defined as a one-field structure diff --git a/Mathlib/RingTheory/Filtration.lean b/Mathlib/RingTheory/Filtration.lean index 873d195ab6ed5a..1498e9515bf799 100644 --- a/Mathlib/RingTheory/Filtration.lean +++ b/Mathlib/RingTheory/Filtration.lean @@ -460,10 +460,6 @@ theorem Ideal.iInf_pow_smul_eq_bot_of_isTorsionFree [IsDomain R] have := smul_left_injective _ hx' (hr.trans (one_smul _ x).symm) exact I.eq_top_iff_one.not.mp h (this ▸ r.prop) -@[deprecated (since := "2026-01-17")] -alias Ideal.iInf_pow_smul_eq_bot_of_noZeroSMulDivisors := - Ideal.iInf_pow_smul_eq_bot_of_isTorsionFree - /-- **Krull's intersection theorem** for Noetherian domains. -/ theorem Ideal.iInf_pow_eq_bot_of_isDomain [IsNoetherianRing R] [IsDomain R] (h : I ≠ ⊤) : ⨅ i : ℕ, I ^ i = ⊥ := by diff --git a/Mathlib/RingTheory/Finiteness/Basic.lean b/Mathlib/RingTheory/Finiteness/Basic.lean index 3f21935a1d41da..d5552ca49326bd 100644 --- a/Mathlib/RingTheory/Finiteness/Basic.lean +++ b/Mathlib/RingTheory/Finiteness/Basic.lean @@ -163,9 +163,6 @@ theorem FG.restrictScalars_of_surjective [CommSemiring R] [Algebra R A] [Module obtain ⟨s, rfl⟩ := hS exact ⟨s, .symm <| restrictScalars_span R A h _⟩ -@[deprecated (since := "2026-01-24")] -alias fg_restrictScalars := FG.restrictScalars_of_surjective - theorem FG.of_restrictScalars (R) [Semiring R] [Module R M] [SMul R A] [IsScalarTower R A M] (hS : (S.restrictScalars R).FG) : S.FG := by obtain ⟨s, e⟩ := hS diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index 7d38dfc7bd0f81..ac82c0403a76e0 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -522,17 +522,6 @@ section LinearOrder variable [Zero R] [LinearOrder Γ] -@[deprecated "directly use n as a lower bound." (since := "2026-01-02")] -theorem forallLTEqZero_supp_BddBelow (f : Γ → R) (n : Γ) (hn : ∀ (m : Γ), m < n → f m = 0) : - BddBelow (Function.support f) := by - refine ⟨n, fun _ ↦ ?_⟩ - contrapose - simp_all - -@[deprecated bddBelow_empty (since := "2026-01-02")] -theorem BddBelow_zero [Nonempty Γ] : BddBelow (Function.support (0 : Γ → R)) := by - simp - theorem le_orderTop_iff_forall {x : R⟦Γ⟧} {i : WithTop Γ} : i ≤ x.orderTop ↔ ∀ j : Γ, j < i → x.coeff j = 0 where mp hi j hj := coeff_eq_zero_of_lt_orderTop (hj.trans_le hi) @@ -562,11 +551,6 @@ theorem order_lt_iff_exists [Zero Γ] {x : R⟦Γ⟧} {i : Γ} (h : x ≠ 0) : variable [LocallyFiniteOrder Γ] -@[deprecated BddBelow.isWF (since := "2026-01-02")] -theorem suppBddBelow_supp_PWO (f : Γ → R) (hf : BddBelow (Function.support f)) : - (Function.support f).IsPWO := - hf.isWF.isPWO - /-- Construct a Hahn series from any function whose support is bounded below. -/ @[simps] def ofSuppBddBelow (f : Γ → R) (hf : BddBelow (Function.support f)) : R⟦Γ⟧ := @@ -576,9 +560,6 @@ def ofSuppBddBelow (f : Γ → R) (hf : BddBelow (Function.support f)) : R⟦Γ theorem ofSuppBddBelow_zero [Nonempty Γ] : ofSuppBddBelow 0 (by simp) = (0 : R⟦Γ⟧) := rfl -@[deprecated (since := "2026-01-02")] -alias zero_ofSuppBddBelow := ofSuppBddBelow_zero - @[simp] theorem ofSuppBddBelow_eq_zero {f : Γ → R} {hf} : ofSuppBddBelow f hf = 0 ↔ f = 0 := HahnSeries.ext_iff @@ -587,14 +568,6 @@ theorem ofSuppBddBelow_eq_zero {f : Γ → R} {hf} : ofSuppBddBelow f hf = 0 ↔ theorem coeff_ofSuppBddBelow {f : Γ → R} {hf} : (ofSuppBddBelow f hf).coeff = f := rfl -@[deprecated le_order_iff_forall (since := "2026-01-02")] -theorem order_ofForallLtEqZero [Zero Γ] (f : Γ → R) (hf : f ≠ 0) (n : Γ) - (hn : ∀ (m : Γ), m < n → f m = 0) : - n ≤ order (ofSuppBddBelow f (forallLTEqZero_supp_BddBelow f n hn)) := by - rw [le_order_iff_forall] - · exact hn - · simpa - end LinearOrder section Truncate diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index e152c4a7ab8a8c..770577404b6e7e 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -530,9 +530,6 @@ theorem orderTop_mul_of_ne_zero {x y : R⟦Γ⟧} (h : x.leadingCoeff * y.leadin ← Set.IsWF.min_add] exact Set.IsWF.min_le_min_of_subset support_mul_subset -@[deprecated (since := "2026-01-02")] -alias orderTop_mul_of_nonzero := orderTop_mul_of_ne_zero - @[simp] theorem orderTop_mul (x y : R⟦Γ⟧) [NoZeroDivisors R] : (x * y).orderTop = x.orderTop + y.orderTop := by @@ -557,16 +554,10 @@ theorem order_mul_of_ne_zero {x y : R⟦Γ⟧} order_of_ne <| ne_zero_of_coeff_ne_zero hxy, ← Set.IsWF.min_add] exact Set.IsWF.min_le_min_of_subset support_mul_subset -@[deprecated (since := "2026-01-02")] -alias order_mul_of_nonzero := order_mul_of_ne_zero - theorem leadingCoeff_mul_of_ne_zero {x y : R⟦Γ⟧} (h : x.leadingCoeff * y.leadingCoeff ≠ 0) : (x * y).leadingCoeff = x.leadingCoeff * y.leadingCoeff := by simp only [leadingCoeff_eq, order_mul_of_ne_zero h, coeff_mul_order_add_order] -@[deprecated (since := "2026-01-02")] -alias leadingCoeff_mul_of_nonzero := leadingCoeff_mul_of_ne_zero - @[simp] theorem leadingCoeff_mul (x y : R⟦Γ⟧) [NoZeroDivisors R] : (x * y).leadingCoeff = x.leadingCoeff * y.leadingCoeff := by diff --git a/Mathlib/RingTheory/Ideal/Colon.lean b/Mathlib/RingTheory/Ideal/Colon.lean index 0314583b7a14a1..f52f5830bcea86 100644 --- a/Mathlib/RingTheory/Ideal/Colon.lean +++ b/Mathlib/RingTheory/Ideal/Colon.lean @@ -58,8 +58,6 @@ theorem colon_univ {I : Ideal R} [I.IsTwoSided] : I.colon Set.univ = I := by simp_rw [SetLike.ext_iff, mem_colon, smul_eq_mul] exact fun x ↦ ⟨fun h ↦ mul_one x ▸ h 1 trivial, fun h _ _ ↦ I.mul_mem_right _ h⟩ -@[deprecated (since := "2026-01-11")] alias colon_top := colon_univ - @[simp] theorem bot_colon : colon (⊥ : Submodule R M) (N : Set M) = N.annihilator := by ext x @@ -75,8 +73,6 @@ theorem iInf_colon_iUnion (ι₁ : Sort*) (f : ι₁ → Submodule R M) (ι₂ : (⨅ i, f i).colon (⋃ j, g j) = ⨅ (i) (j), (f i).colon (g j) := by aesop (add simp mem_colon) -@[deprecated (since := "2026-01-11")] alias iInf_colon_iSup := iInf_colon_iUnion - /-- If `S ⊆ N₂`, then intersecting with `N₂` does not change the colon ideal. -/ lemma colon_inf_eq_left_of_subset (h : S ⊆ (N₂ : Set M)) : (N₁ ⊓ N₂).colon S = N₁.colon S := by aesop (add simp mem_colon) @@ -127,10 +123,6 @@ section CommSemiring variable [CommSemiring R] [AddCommMonoid M] [Module R M] variable {N N' : Submodule R M} {S : Set M} -@[deprecated mem_colon (since := "2026-01-15")] -theorem mem_colon' {r} : r ∈ N.colon S ↔ S ≤ comap (r • (LinearMap.id : M →ₗ[R] M)) N := - mem_colon - theorem mem_colon_iff_le {r} : r ∈ N.colon N' ↔ r • N' ≤ N := by aesop (add simp SetLike.coe_subset_coe) diff --git a/Mathlib/RingTheory/Ideal/IsPrimary.lean b/Mathlib/RingTheory/Ideal/IsPrimary.lean index 698106b6d3cb2e..b31eb8dcb741d5 100644 --- a/Mathlib/RingTheory/Ideal/IsPrimary.lean +++ b/Mathlib/RingTheory/Ideal/IsPrimary.lean @@ -73,9 +73,6 @@ lemma isPrimary_finsetInf {ι} {s : Finset ι} {f : ι → Ideal R} {i : ι} (hi IsPrimary (s.inf f) := Submodule.isPrimary_finsetInf hi hs (by simpa) -@[deprecated (since := "2026-01-19")] -alias isPrimary_finset_inf := isPrimary_finsetInf - lemma IsPrimary.comap {I : Ideal S} (hI : I.IsPrimary) (φ : R →+* S) : (I.comap φ).IsPrimary := by rw [isPrimary_iff] at hI ⊢ refine hI.imp (comap_ne_top φ) fun h ↦ ?_ diff --git a/Mathlib/RingTheory/Ideal/Prime.lean b/Mathlib/RingTheory/Ideal/Prime.lean index c19bef639068a2..7983ced7053f97 100644 --- a/Mathlib/RingTheory/Ideal/Prime.lean +++ b/Mathlib/RingTheory/Ideal/Prime.lean @@ -92,9 +92,6 @@ instance isPrime_bot [Nontrivial α] [NoZeroDivisors α] : (⊥ : Ideal α).IsPr ⟨fun h => one_ne_zero (α := α) (by rwa [Ideal.eq_top_iff_one, Submodule.mem_bot] at h), fun h => mul_eq_zero.mp (by simpa only [Submodule.mem_bot] using h)⟩ -@[deprecated isPrime_bot (since := "2026-01-10")] -theorem bot_prime [Nontrivial α] [NoZeroDivisors α] : (⊥ : Ideal α).IsPrime := isPrime_bot - theorem IsPrime.mul_mem_iff_mem_or_mem {I : Ideal α} [I.IsTwoSided] (hI : I.IsPrime) : ∀ {x y : α}, x * y ∈ I ↔ x ∈ I ∨ y ∈ I := @fun x y => ⟨hI.mem_or_mem, by diff --git a/Mathlib/RingTheory/Kaehler/TensorProduct.lean b/Mathlib/RingTheory/Kaehler/TensorProduct.lean index 82545a22e33534..7a37219e757ef1 100644 --- a/Mathlib/RingTheory/Kaehler/TensorProduct.lean +++ b/Mathlib/RingTheory/Kaehler/TensorProduct.lean @@ -215,8 +215,6 @@ lemma tensorKaehlerEquivBase_tmul [Algebra.IsPushout R S A B] (a b) : tensorKaehlerEquivBase R S A B (a ⊗ₜ b) = a • map R S A B b := LinearMap.liftBaseChange_tmul _ _ _ _ -@[deprecated (since := "2026-01-01")] alias tensorKaehlerEquiv_tmul := tensorKaehlerEquivBase_tmul - /-- If `B` is the tensor product of `S` and `A` over `R`, then `Ω[B⁄S]` is the base change of `Ω[A⁄R]` along `R → S`. diff --git a/Mathlib/RingTheory/KrullDimension/Regular.lean b/Mathlib/RingTheory/KrullDimension/Regular.lean index 7428318395e51b..65f6fbdeb6ca3a 100644 --- a/Mathlib/RingTheory/KrullDimension/Regular.lean +++ b/Mathlib/RingTheory/KrullDimension/Regular.lean @@ -148,20 +148,6 @@ lemma _root_.ringKrullDim_le_ringKrullDim_quotSMulTop_succ {x : R} (hx : x ∈ m rw [← Module.supportDim_self_eq_ringKrullDim, ← Module.supportDim_quotient_eq_ringKrullDim] exact supportDim_le_supportDim_quotSMulTop_succ hx -@[deprecated ringKrullDim_le_ringKrullDim_quotient_add_card (since := "2026-01-12")] -lemma _root_.ringKrullDim_le_ringKrullDim_add_card {S : Finset R} - (hS : (S : Set R) ⊆ maximalIdeal R) : - ringKrullDim R ≤ ringKrullDim (R ⧸ Ideal.span (SetLike.coe S)) + S.card := by - apply ringKrullDim_le_ringKrullDim_quotient_add_card - rwa [IsLocalRing.ringJacobson_eq_maximalIdeal] - -@[deprecated ringKrullDim_le_ringKrullDim_quotient_add_spanFinrank (since := "2026-01-12")] -lemma _root_.ringKrullDim_le_ringKrullDim_add_spanFinrank {I : Ideal R} (h : I ≠ ⊤) : - ringKrullDim R ≤ ringKrullDim (R ⧸ I) + I.spanFinrank := by - apply ringKrullDim_le_ringKrullDim_quotient_add_spanFinrank - rw [IsLocalRing.ringJacobson_eq_maximalIdeal] - exact le_maximalIdeal h - @[stacks 0B52 "the equality case"] theorem supportDim_quotSMulTop_succ_eq_of_notMem_minimalPrimes_of_mem_maximalIdeal {x : R} (hn : ∀ p ∈ (annihilator R M).minimalPrimes, x ∉ p) (hx : x ∈ maximalIdeal R) : diff --git a/Mathlib/RingTheory/Lasker.lean b/Mathlib/RingTheory/Lasker.lean index e3daaf80a1bf6b..abc598ed63750b 100644 --- a/Mathlib/RingTheory/Lasker.lean +++ b/Mathlib/RingTheory/Lasker.lean @@ -148,9 +148,6 @@ lemma image_radical_eq_associated_primes obtain ⟨q, hq1, hq2⟩ := eq_inf_of_isPrime_inf hp exact ⟨q, Finset.mem_of_mem_filter q hq1, hq2⟩ -@[deprecated (since := "2026-01-19")] -alias mem_image_radical_colon_iff := image_radical_eq_associated_primes - lemma mem_associatedPrimes {N : Submodule R M} {t : Finset (Submodule R M)} (ht : IsMinimalPrimaryDecomposition N t) {q : Submodule R M} (hq : q ∈ t) : (q.colon Set.univ).radical ∈ N.associatedPrimes := by @@ -235,27 +232,6 @@ lemma Ideal.IsMinimalPrimaryDecomposition.minimalPrimes_subset_image_radical exact ⟨q, hqt, le_antisymm hqp (hp.2 ⟨isPrime_radical (ht.primary hqt), ht.inf_eq.symm.trans_le ((Finset.inf_le hqt).trans le_radical)⟩ hqp)⟩ -@[deprecated (since := "2026-01-19")] -alias Ideal.decomposition_erase_inf := Submodule.decomposition_erase_inf - -@[deprecated (since := "2026-01-19")] -alias Ideal.isPrimary_decomposition_pairwise_ne_radical := - Submodule.isPrimary_decomposition_pairwise_ne_radical - -@[deprecated (since := "2026-01-19")] -alias Ideal.exists_minimal_isPrimary_decomposition_of_isPrimary_decomposition := - Submodule.exists_minimal_isPrimary_decomposition_of_isPrimary_decomposition - -@[deprecated (since := "2026-01-19")] -alias Ideal.IsMinimalPrimaryDecomposition := Submodule.IsMinimalPrimaryDecomposition - -@[deprecated (since := "2026-01-19")] -alias Ideal.IsLasker.exists_isMinimalPrimaryDecomposition := - Submodule.IsLasker.exists_isMinimalPrimaryDecomposition - -@[deprecated (since := "2026-01-19")] -alias Ideal.IsLasker.minimal := Submodule.IsLasker.exists_isMinimalPrimaryDecomposition - end IsLasker namespace Submodule @@ -302,6 +278,3 @@ lemma isLasker : IsLasker R M := fun I ↦ end Noetherian end Submodule - -@[deprecated (since := "2026-01-19")] -alias Ideal.isLasker := Submodule.isLasker diff --git a/Mathlib/RingTheory/MvPowerSeries/Order.lean b/Mathlib/RingTheory/MvPowerSeries/Order.lean index 5590d111e9f051..da040c04cee88c 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Order.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Order.lean @@ -377,9 +377,6 @@ section Order variable {f g : MvPowerSeries σ R} -@[deprecated (since := "2026-01-06")] -alias eq_zero_iff_forall_coeff_eq_zero_and := eq_zero_iff_forall_coeff_zero - theorem ne_zero_iff_exists_coeff_ne_zero_and_degree : f ≠ 0 ↔ (∃ n : ℕ, ∃ d : σ →₀ ℕ, coeff d f ≠ 0 ∧ degree d = n) := by simp_rw [degree_eq_weight_one] diff --git a/Mathlib/RingTheory/Nakayama.lean b/Mathlib/RingTheory/Nakayama.lean index b9e2e546afb237..5c51814e0230cb 100644 --- a/Mathlib/RingTheory/Nakayama.lean +++ b/Mathlib/RingTheory/Nakayama.lean @@ -194,10 +194,6 @@ lemma le_of_map_mkQ_le_map_mkQ_of_le_jacobson_bot simp only [comap_map_mkQ, smul_le_right, sup_of_le_right] at hmaple grw [sup_comm, ← hmaple] -@[deprecated (since := "2026-01-03")] -alias le_span_of_map_mkQ_le_map_mkQ_span_of_le_jacobson_bot := - le_of_map_mkQ_le_map_mkQ_of_le_jacobson_bot - lemma eq_of_map_mkQ_eq_map_mkQ_of_le_jacobson_bot {I : Ideal R} {N N' : Submodule R M} (hN : N.FG) (hIjac : I ≤ jacobson ⊥) (hmaple : map (I • N).mkQ N = map (I • N).mkQ N') : N = N' := by diff --git a/Mathlib/RingTheory/OreLocalization/OreSet.lean b/Mathlib/RingTheory/OreLocalization/OreSet.lean index ee5370dc069b2f..d75b0ed64b38be 100644 --- a/Mathlib/RingTheory/OreLocalization/OreSet.lean +++ b/Mathlib/RingTheory/OreLocalization/OreSet.lean @@ -38,8 +38,6 @@ def oreSetOfIsCancelMulZero {R : Type*} [MonoidWithZero R] [IsCancelMulZero R] oreDenom ore_eq } -@[deprecated (since := "2026-01-12")] alias oreSetOfCancelMonoidWithZero := oreSetOfIsCancelMulZero - /-- In rings without zero divisors, the first (cancellability) condition is always fulfilled, it suffices to give a proof for the Ore condition itself. -/ @[instance_reducible] diff --git a/Mathlib/RingTheory/Polynomial/IsIntegral.lean b/Mathlib/RingTheory/Polynomial/IsIntegral.lean index d35d84433c53fa..cdd8f4a70de707 100644 --- a/Mathlib/RingTheory/Polynomial/IsIntegral.lean +++ b/Mathlib/RingTheory/Polynomial/IsIntegral.lean @@ -155,11 +155,6 @@ protected lemma IsIntegral.coeff · simpa [show i ≠ m by lia] using this · simp [coeff_eq_zero_of_natDegree_lt hi, isIntegral_zero] -@[deprecated (since := "2026-01-01")] -alias IsIntegral.coeff_of_exists_smul_mem_lifts := IsIntegral.coeff - -@[deprecated (since := "2026-01-01")] alias IsIntegral.coeff_of_isFractionRing := IsIntegral.coeff - theorem Polynomial.isIntegral_iff_isIntegral_coeff {f : S[X]} : IsIntegral R[X] f ↔ ∀ n, IsIntegral R (f.coeff n) := by refine ⟨IsIntegral.coeff, fun H ↦ ?_⟩ diff --git a/Mathlib/RingTheory/Smooth/NoetherianDescent.lean b/Mathlib/RingTheory/Smooth/NoetherianDescent.lean index 9255cf2f38d237..f6ff5fc455611e 100644 --- a/Mathlib/RingTheory/Smooth/NoetherianDescent.lean +++ b/Mathlib/RingTheory/Smooth/NoetherianDescent.lean @@ -251,13 +251,6 @@ public theorem exists_subalgebra_fg [Smooth A B] : D.fg_subalgebra R, ⟨.of_split _ σ₀ hσ₀, inferInstance⟩, ⟨(P.tensorModelOfHasCoeffsEquiv (D.subalgebra R)).symm⟩⟩ -@[deprecated exists_subalgebra_fg (since := "2026-01-07")] -public theorem exists_subalgebra_finiteType [Smooth A B] : - ∃ (A₀ : Subalgebra R A) (B₀ : Type u) (_ : CommRing B₀) (_ : Algebra A₀ B₀), - FiniteType R A₀ ∧ Smooth A₀ B₀ ∧ Nonempty (B ≃ₐ[A] A ⊗[A₀] B₀) := by - obtain ⟨A₀, B₀, _, _, h0, h1, h2⟩ := exists_subalgebra_fg R A B - exact ⟨A₀, B₀, inferInstance, inferInstance, (Subalgebra.fg_iff_finiteType A₀).mp h0, h1, h2⟩ - /-- Let `A` be an `R`-algebra. If `B` is a smooth `A`-algebra, there exists an `R`-algebra of finite type `A₀` and a smooth `A₀`-algebra `B₀` such that `B ≃ₐ A ⊗[A₀] B₀` diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index deb2d06519d661..744371cf19ddec 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -736,10 +736,6 @@ theorem eq_zero (h : v₁.IsEquiv v₂) {r : R} : v₁ r = 0 ↔ v₂ r = 0 := b lemma ofClass_eq_zero (h : v₁.IsEquiv v₂) {r : R} : (MonoidWithZeroHom.ofClass v₁) r = 0 ↔ (MonoidWithZeroHom.ofClass v₂) r = 0 := eq_zero h -@[deprecated "use `(eq_zero _).ne` instead." (since := "2026-01-05")] -theorem ne_zero (h : v₁.IsEquiv v₂) {r : R} : v₁ r ≠ 0 ↔ v₂ r ≠ 0 := - (eq_zero h).ne - lemma pos_iff (h : v₁.IsEquiv v₂) {x : R} : 0 < v₁ x ↔ 0 < v₂ x := by rw [zero_lt_iff, zero_lt_iff, h.eq_zero.ne] diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean index 2e3fa6a22f350d..5621ef0b3388cf 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Basic.lean @@ -181,10 +181,6 @@ theorem vlt.ne_zero (h : x <ᵥ y) : y ≠ 0 := by lemma zero_vlt_one : (0 : R) <ᵥ 1 := not_vle_one_zero -@[deprecated mul_vle_mul_left (since := "2026-01-06")] -lemma vle_mul_right (z) (h : x ≤ᵥ y) : x * z ≤ᵥ y * z := - mul_vle_mul_left h z - lemma mul_vle_mul_right (h : x ≤ᵥ y) (z) : z * x ≤ᵥ z * y := vle_trans (veq_mul_comm _ _).1 (vle_trans (mul_vle_mul_left h z) ((veq_mul_comm _ _).1)) @@ -275,13 +271,11 @@ lemma mul_vle_mul {x x' y y' : R} (h1 : x ≤ᵥ y) (h2 : x' ≤ᵥ y') : x * x' (mul_vle_mul_iff_left hz).not @[gcongr] alias ⟨_, mul_vlt_mul_left⟩ := mul_vlt_mul_iff_left -@[deprecated (since := "2026-01-06")] alias vlt_mul_right := mul_vlt_mul_left @[simp] lemma mul_vlt_mul_iff_right (hx : 0 <ᵥ x) : x * y <ᵥ x * z ↔ y <ᵥ z := (mul_vle_mul_iff_right hx).not @[gcongr] alias ⟨_, mul_vlt_mul_right⟩ := mul_vlt_mul_iff_right -@[deprecated (since := "2026-01-06")] alias vlt_mul_left := mul_vlt_mul_right @[gcongr] lemma mul_veq_mul (h1 : x =ᵥ y) (h2 : x' =ᵥ y') : x * x' =ᵥ y * y' := @@ -832,14 +826,6 @@ section Ring variable {R : Type*} [Ring R] [ValuativeRel R] {a b c d : R} -@[deprecated (since := "2026-01-06")] alias vle_mul_right_iff := mul_vle_mul_iff_left - -@[deprecated (since := "2026-01-06")] alias vle_mul_left_iff := mul_vle_mul_iff_right - -@[deprecated (since := "2026-01-06")] alias vlt_mul_right_iff := mul_vlt_mul_iff_left - -@[deprecated (since := "2026-01-06")] alias vlt_mul_left_iff := mul_vlt_mul_iff_right - lemma mul_vlt_mul_of_vlt_of_vle (hab : a <ᵥ b) (hcd : c ≤ᵥ d) (hd : 0 <ᵥ d) : a * c <ᵥ b * d := (mul_vle_mul_right hcd _).trans_vlt (mul_vlt_mul_left hd hab) diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 7a57624058d4fe..ed109067333bf1 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -340,9 +340,6 @@ protected theorem le_one_iff {c : Cardinal} : c ≤ 1 ↔ c = 0 ∨ c = 1 := by rw [← natCast_add_one_le_iff, ← Nat.cast_add_one, ← lift_mk_fin, aleph0, lift_mk_le.{u}] exact ⟨⟨(↑), fun a b => Fin.ext⟩⟩ -@[deprecated natCast_lt_aleph0 (since := "2026-01-21")] -theorem nat_lt_aleph0 (n : ℕ) : (n : Cardinal.{u}) < ℵ₀ := natCast_lt_aleph0 - @[simp] lemma natCast_le_aleph0 {n : ℕ} : (n : Cardinal.{u}) ≤ ℵ₀ := natCast_lt_aleph0.le @[simp] lemma ofNat_lt_aleph0 {n : ℕ} [n.AtLeastTwo] : ofNat(n) < ℵ₀ := natCast_lt_aleph0 @@ -656,16 +653,9 @@ theorem mk_le_mk_of_subset {α} {s t : Set α} (h : s ⊆ t) : #s ≤ #t := theorem mk_monotone : Monotone (α := Set α) (mk ∘ (↑)) := fun _ _ ↦ mk_le_mk_of_subset -@[deprecated mk_eq_zero (since := "2026-01-31")] -theorem mk_emptyCollection (α : Type u) : #(∅ : Set α) = 0 := - mk_eq_zero _ - theorem mk_set_eq_zero_iff {s : Set α} : #s = 0 ↔ s = ∅ := by rw [mk_eq_zero_iff, isEmpty_coe_sort] -@[deprecated (since := "2026-01-31")] -alias mk_emptyCollection_iff := mk_set_eq_zero_iff - theorem mk_set_ne_zero_iff {s : Set α} : #s ≠ 0 ↔ s.Nonempty := by rw [mk_ne_zero_iff, nonempty_coe_sort] @@ -702,11 +692,6 @@ theorem mk_range_eq_of_injective {α : Type u} {β : Type v} {f : α → β} (hf lift.{u} #(range f) = lift.{v} #α := lift_mk_eq'.mpr ⟨(Equiv.ofInjective f hf).symm⟩ -@[deprecated mk_range_eq_of_injective (since := "2026-01-06")] -theorem mk_range_eq_lift {α : Type u} {β : Type v} {f : α → β} (hf : Injective f) : - lift.{max u w} #(range f) = lift.{max v w} #α := - lift_mk_eq.{v, u, w}.mpr ⟨(Equiv.ofInjective f hf).symm⟩ - lemma lift_mk_le_lift_mk_of_injective {α : Type u} {β : Type v} {f : α → β} (hf : Injective f) : Cardinal.lift.{v} (#α) ≤ Cardinal.lift.{u} (#β) := by rw [← Cardinal.mk_range_eq_of_injective hf] diff --git a/Mathlib/SetTheory/Cardinal/ENat.lean b/Mathlib/SetTheory/Cardinal/ENat.lean index fb62164e162911..cfab4f7ad0fc13 100644 --- a/Mathlib/SetTheory/Cardinal/ENat.lean +++ b/Mathlib/SetTheory/Cardinal/ENat.lean @@ -255,8 +255,6 @@ variable {c c' : Cardinal.{u}} {n : ℕ} @[simp] lemma toENat_le_ofNat [n.AtLeastTwo] : toENat c ≤ ofNat(n) ↔ c ≤ ofNat(n) := toENat_le_natCast -@[deprecated (since := "2026-01-13")] alias toENat_le_nat := toENat_le_natCast - lemma toENat_le_iff_of_le_aleph0 (hc : c ≤ ℵ₀) : toENat c ≤ toENat c' ↔ c ≤ c' := by lift c to ℕ∞ using hc; simp_rw [toENat_ofENat, enat_gc _] @@ -291,8 +289,6 @@ lemma toENat_eq_iff_of_le_aleph0 (hc : c ≤ ℵ₀) (hc' : c' ≤ ℵ₀) : toE @[deprecated toENat_eq_zero (since := "2026-05-25")] lemma toENat_lt_one : toENat c < 1 ↔ c < 1 := by simp -@[deprecated (since := "2026-01-13")] alias toENat_eq_nat := toENat_eq_natCast - @[simp] lemma natCast_eq_toENat : n = toENat c ↔ n = c := by simp [eq_comm (a := Nat.cast _)] @[simp] lemma ofNat_eq_toENat [n.AtLeastTwo] : ofNat(n) = toENat c ↔ ofNat(n) = c := natCast_eq_toENat diff --git a/Mathlib/SetTheory/Cardinal/Ordinal.lean b/Mathlib/SetTheory/Cardinal/Ordinal.lean index eb9fe0c8b127b4..d9c3417240f6d2 100644 --- a/Mathlib/SetTheory/Cardinal/Ordinal.lean +++ b/Mathlib/SetTheory/Cardinal/Ordinal.lean @@ -35,18 +35,12 @@ lemma mk_biUnion_le_of_le_lift {β : Type v} {o : Ordinal.{u}} {c : Cardinal.{v} intro i simpa using hA _ i.toOrd.prop -@[deprecated (since := "2026-01-26")] -alias mk_iUnion_Ordinal_lift_le_of_le := mk_biUnion_le_of_le_lift - lemma mk_biUnion_le_of_le {β : Type*} {o : Ordinal} {c : Cardinal} (ho : o.card ≤ c) (hc : ℵ₀ ≤ c) (A : Ordinal → Set β) (hA : ∀ j < o, #(A j) ≤ c) : #(⋃ j < o, A j) ≤ c := by apply mk_biUnion_le_of_le_lift _ hc A hA rwa [Cardinal.lift_le] -@[deprecated (since := "2026-01-26")] -alias mk_iUnion_Ordinal_le_of_le := mk_biUnion_le_of_le - end Cardinal /-! ### Cardinality of ordinals -/ diff --git a/Mathlib/SetTheory/Cardinal/Pigeonhole.lean b/Mathlib/SetTheory/Cardinal/Pigeonhole.lean index a984c3e42cd348..d3f275df56a1f6 100644 --- a/Mathlib/SetTheory/Cardinal/Pigeonhole.lean +++ b/Mathlib/SetTheory/Cardinal/Pigeonhole.lean @@ -122,7 +122,4 @@ theorem le_range_of_union_finset_eq_univ {α β : Type*} [Infinite β] (f : α obtain ⟨⟨-, ⟨a, rfl⟩⟩, p⟩ := exists_infinite_fiber u' h exact (@Infinite.of_injective _ _ p (inclusion (v' a)) (inclusion_injective _)).false -@[deprecated (since := "2026-01-17")] alias le_range_of_union_finset_eq_top := - le_range_of_union_finset_eq_univ - end Cardinal diff --git a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean index 0779e81275ac4a..f94eb798f7e5c8 100644 --- a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean +++ b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean @@ -127,9 +127,6 @@ theorem snd_pos {b o : Ordinal.{u}} {x : Ordinal × Ordinal} : x ∈ CNF b o → · exact div_opow_log_pos b ho · exact IH h -@[deprecated (since := "2026-01-11")] -alias lt_snd := snd_pos - /-- Every coefficient in the Cantor normal form `CNF b o` is less than `b`. -/ theorem snd_lt {b o : Ordinal.{u}} (hb : 1 < b) {x : Ordinal × Ordinal} : x ∈ CNF b o → x.2 < b := by @@ -159,9 +156,6 @@ protected theorem sortedGT (b o : Ordinal) : ((CNF b o).map Prod.fst).SortedGT : rcases H with ⟨⟨a, a'⟩, H, rfl⟩ exact (fst_le_log H).trans_lt (log_mod_opow_log_lt_log_self hb hbo) -@[deprecated (since := "2026-01-11")] -alias sorted := CNF.sortedGT - private theorem nodupKeys (b o : Ordinal) : (map Prod.toSigma (CNF b o)).NodupKeys := by rw [NodupKeys, List.keys, map_map, Prod.fst_comp_toSigma] exact (CNF.sortedGT ..).nodup @@ -194,9 +188,6 @@ theorem coeff_of_notMem_CNF {b o e : Ordinal} (h : e ∉ (CNF b o).map Prod.fst) coeff b o e = 0 := by rwa [← notMem_support_iff, support_coeff, mem_toFinset] -@[deprecated (since := "2026-01-11")] -alias coeff_of_not_mem_CNF := coeff_of_notMem_CNF - theorem coeff_eq_zero_of_lt {b o e : Ordinal} (h : o < b ^ e) : coeff b o e = 0 := by apply coeff_of_notMem_CNF intro he diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 859113c542c1ae..0308fb12e050f8 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -525,10 +525,6 @@ theorem natCast_pow (m : ℕ) : ∀ n : ℕ, ↑(m ^ n : ℕ) = (m : Ordinal) ^ | 0 => by simp | n + 1 => by simp [pow_succ, natCast_pow m n] -@[deprecated natCast_pow (since := "2026-01-31")] -theorem natCast_opow (m : ℕ) : ∀ n : ℕ, ↑(m ^ n : ℕ) = (m : Ordinal) ^ (n : Ordinal) := by - simp - theorem iSup_pow_natCast {o : Ordinal} (ho : 0 < o) : ⨆ n : ℕ, o ^ n = o ^ ω := by rcases (one_le_iff_pos.2 ho).lt_or_eq with ho₁ | rfl · simpa using apply_omega0_of_isNormal (isNormal_opow ho₁) diff --git a/Mathlib/SetTheory/Ordinal/Topology.lean b/Mathlib/SetTheory/Ordinal/Topology.lean index d08298527a1674..7496d78530a870 100644 --- a/Mathlib/SetTheory/Ordinal/Topology.lean +++ b/Mathlib/SetTheory/Ordinal/Topology.lean @@ -43,18 +43,6 @@ variable {s : Set Ordinal.{u}} {a : Ordinal.{u}} instance : TopologicalSpace Ordinal.{u} := Preorder.topology Ordinal.{u} instance : OrderTopology Ordinal.{u} := ⟨rfl⟩ -@[deprecated SuccOrder.isOpen_singleton_iff (since := "2026-01-20")] -theorem isOpen_singleton_iff : IsOpen ({a} : Set Ordinal) ↔ ¬ IsSuccLimit a := - SuccOrder.isOpen_singleton_iff - -@[deprecated SuccOrder.nhds_eq_pure (since := "2026-01-20")] -theorem nhds_eq_pure : 𝓝 a = pure a ↔ ¬ IsSuccLimit a := - SuccOrder.nhds_eq_pure - -@[deprecated SuccOrder.isOpen_iff (since := "2026-01-20")] -theorem isOpen_iff : IsOpen s ↔ ∀ o ∈ s, IsSuccLimit o → ∃ a < o, Set.Ioo a o ⊆ s := - SuccOrder.isOpen_iff - open List Set in theorem mem_closure_tfae (a : Ordinal.{u}) (s : Set Ordinal) : TFAE [a ∈ closure s, @@ -138,10 +126,6 @@ theorem isClosed_iff_bsup : apply H (type_ne_zero_iff_nonempty.2 hι) exact fun i hi => hf _ -@[deprecated SuccOrder.isSuccLimit_of_mem_frontier (since := "2026-01-20")] -theorem isSuccLimit_of_mem_frontier (ha : a ∈ frontier s) : IsSuccLimit a := - SuccOrder.isSuccLimit_of_mem_frontier ha - @[deprecated isNormal_enum_iff_dirSupClosed (since := "2026-05-25")] theorem enumOrd_isNormal_iff_isClosed (hs : ¬ BddAbove s) : IsNormal (enumOrd s) ↔ IsClosed s := by diff --git a/Mathlib/SetTheory/ZFC/Ordinal.lean b/Mathlib/SetTheory/ZFC/Ordinal.lean index 5c8eadb98388f3..d0c198c86718fb 100644 --- a/Mathlib/SetTheory/ZFC/Ordinal.lean +++ b/Mathlib/SetTheory/ZFC/Ordinal.lean @@ -210,8 +210,6 @@ protected theorem trichotomous (h : x.IsOrdinal) : Std.Trichotomous (Subrel (· intro ⟨a, ha⟩ ⟨b, hb⟩ simpa using mem_trichotomous (h.mem ha) (h.mem hb) -@[deprecated (since := "2026-01-24")] protected alias isTrichotomous := IsOrdinal.trichotomous - /-- An ordinal is a transitive set, trichotomous under membership. -/ theorem _root_.ZFSet.isOrdinal_iff_trichotomous : x.IsOrdinal ↔ x.IsTransitive ∧ Std.Trichotomous (Subrel (· ∈ ·) (· ∈ x)) where @@ -225,9 +223,6 @@ theorem _root_.ZFSet.isOrdinal_iff_trichotomous : · cases asymm hyz hzw · cases mem_wf.asymmetric₃ _ _ _ hyz hzw hwy -@[deprecated (since := "2026-01-24")] -alias _root_.ZFSet.isOrdinal_iff_isTrichotomous := _root_.ZFSet.isOrdinal_iff_trichotomous - protected theorem isWellOrder (h : x.IsOrdinal) : IsWellOrder _ (Subrel (· ∈ ·) (· ∈ x)) where wf := (Subrel.relEmbedding _ _).wellFounded mem_wf trichotomous := h.trichotomous.1 diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index a4e13e14d0203b..2ed0ee63eb826c 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -181,7 +181,6 @@ public import Mathlib.Tactic.LinearCombinationPrime public import Mathlib.Tactic.Linter public import Mathlib.Tactic.Linter.AuxLemma public import Mathlib.Tactic.Linter.CommandRanges -public import Mathlib.Tactic.Linter.CommandStart public import Mathlib.Tactic.Linter.DeprecatedModule public import Mathlib.Tactic.Linter.DeprecatedSyntaxLinter public import Mathlib.Tactic.Linter.DirectoryDependency diff --git a/Mathlib/Tactic/Linter/CommandStart.lean b/Mathlib/Tactic/Linter/CommandStart.lean deleted file mode 100644 index 0e4df37962e7c9..00000000000000 --- a/Mathlib/Tactic/Linter/CommandStart.lean +++ /dev/null @@ -1,5 +0,0 @@ -module -- shake: keep-all - -import Mathlib.Tactic.Linter.Whitespace - -deprecated_module (since := "2026-01-07") diff --git a/Mathlib/Tactic/Linter/Whitespace.lean b/Mathlib/Tactic/Linter/Whitespace.lean index 2c6a496e390461..492e334f9a0538 100644 --- a/Mathlib/Tactic/Linter/Whitespace.lean +++ b/Mathlib/Tactic/Linter/Whitespace.lean @@ -42,13 +42,6 @@ public register_option linter.style.whitespace : Bool := { descr := "enable the whitespace linter" } -/-- Deprecated in favour of `linter.style.whitespace` -/ -@[deprecated linter.style.whitespace (since := "2026-01-07")] -public register_option linter.style.commandStart : Bool := { - defValue := false - descr := "deprecated: use the `linter.style.whitespace` option instead" -} - /-- If the `linter.style.whitespace.verbose` option is `true`, the `whitespace` linter reports some helpful diagnostic information. -/ public register_option linter.style.whitespace.verbose : Bool := { diff --git a/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean index 68ab995d659ca3..5381f8413dc0df 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean @@ -111,12 +111,6 @@ def ContinuousLinearMap.precompCompactConvergenceCLM [IsTopologicalAddGroup G] [ContinuousConstSMul 𝕜₃ G] (L : E →SL[σ] F) : (F →SL_c[τ] G) →L[𝕜₃] E →SL_c[ρ] G := L.precompUniformConvergenceCLM G _ _ (fun _ hs ↦ hs.image L.continuous) -@[deprecated (since := "2026-01-27")] -alias precomp_compactConvergenceCLM := precompCompactConvergenceCLM - -@[deprecated (since := "2026-01-27")] -alias precomp_compactConvergenceCLM_apply := precompCompactConvergenceCLM_apply - variable (E) in /-- Specialization of `ContinuousLinearMap.postcomp_uniformConvergenceCLM` to compact convergence. -/ @@ -126,12 +120,6 @@ def ContinuousLinearMap.postcompCompactConvergenceCLM [IsTopologicalAddGroup F] (L : F →SL[τ] G) : (E →SL_c[σ] F) →SL[τ] E →SL_c[ρ] G := L.postcompUniformConvergenceCLM _ -@[deprecated (since := "2026-01-27")] -alias postcomp_compactConvergenceCLM := postcompCompactConvergenceCLM - -@[deprecated (since := "2026-01-27")] -alias postcomp_compactConvergenceCLM_apply := postcompCompactConvergenceCLM_apply - end comp /-! ### Continuous linear equivalences -/ diff --git a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean index 7333c8e05c3273..cff5bab051608f 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/UniformConvergenceCLM.lean @@ -505,12 +505,6 @@ def precompUniformConvergenceCLM [IsTopologicalAddGroup G] [ContinuousConstSMul exact (UniformOnFun.precomp_uniformContinuous hL).continuous.comp (UniformConvergenceCLM.isEmbedding_coeFn _ _ _).continuous -@[deprecated (since := "2026-01-27")] -alias precomp_uniformConvergenceCLM := precompUniformConvergenceCLM - -@[deprecated (since := "2026-01-27")] -alias precomp_uniformConvergenceCLM_apply := precompUniformConvergenceCLM_apply - set_option backward.isDefEq.respectTransparency false in /-- Post-composition by a *fixed* continuous linear map as a continuous linear map for the uniform convergence topology. -/ @@ -531,12 +525,6 @@ def postcompUniformConvergenceCLM [IsTopologicalAddGroup F] [IsTopologicalAddGro (UniformOnFun.postcomp_uniformContinuous L.uniformContinuous).continuous.comp (UniformConvergenceCLM.isEmbedding_coeFn _ _ _).continuous -@[deprecated (since := "2026-01-27")] -alias postcomp_uniformConvergenceCLM := postcompUniformConvergenceCLM - -@[deprecated (since := "2026-01-27")] -alias postcomp_uniformConvergenceCLM_apply := postcompUniformConvergenceCLM_apply - end ContinuousLinearMap /-! ### Continuous linear equivalences -/ diff --git a/Mathlib/Topology/Algebra/Valued/WithVal.lean b/Mathlib/Topology/Algebra/Valued/WithVal.lean index f45c2985d075a9..7c016e6f00ae57 100644 --- a/Mathlib/Topology/Algebra/Valued/WithVal.lean +++ b/Mathlib/Topology/Algebra/Valued/WithVal.lean @@ -393,31 +393,6 @@ instance [NumberField R] : NumberField (WithVal v) where end Field -section Ring - -variable [Ring R] (v : Valuation R Γ₀) - -variable {Γ'₀ : Type*} [LinearOrderedCommGroupWithZero Γ'₀] - -/-- Canonical ring equivalence between `WithVal v` and `WithVal w`. -/ -@[deprecated "Use `WithVal.congr v w (.refl R)` instead" (since := "2026-01-27")] -def equivWithVal (v : Valuation R Γ₀) (w : Valuation R Γ'₀) : - WithVal v ≃+* WithVal w := - (equiv v).trans (equiv w).symm - -@[deprecated WithVal.congr_symm (since := "2026-01-27")] -theorem equivWithVal_symm (v : Valuation R Γ₀) (w : Valuation R Γ'₀) : - (congr v w (.refl R)).symm = congr w v (.refl R) := rfl - -@[deprecated "Use `WithVal.congr_apply` instead" (since := "2026-01-27")] -theorem equivWithVal_apply (v : Valuation R Γ₀) (w : Valuation R Γ'₀) {x : WithVal v} : - congr v w (.refl R) x = (equiv w).symm (equiv v x) := by simp - -@[deprecated "Use `WithVal.congr_symm_apply` instead" (since := "2026-01-27")] -theorem equivWithVal_symm_apply (v : Valuation R Γ₀) (w : Valuation R Γ'₀) {x : WithVal w} : - (congr v w (.refl R)).symm x = (equiv v).symm (equiv w x) := by simp - -end Ring section ValueGroup₀ variable {R : Type*} [Ring R] (v : Valuation R Γ₀) @@ -613,9 +588,6 @@ theorem IsEquiv.uniformContinuous_congr (h : v.IsEquiv w) : exact @UniformContinuous.comp R R (WithVal w) (Valued.mk' w).toUniformSpace (Valued.mk' v).toUniformSpace _ (WithVal.equiv w).symm (RingEquiv.refl R) h2 hR -@[deprecated (since := "2026-01-27")] - alias IsEquiv.uniformContinuous_equivWithVal := IsEquiv.uniformContinuous_congr - /-- If two valuations `v` and `w` are equivalent then `WithVal v` and `WithVal w` are isomorphic as uniform spaces. -/ def IsEquiv.uniformEquiv (h : v.IsEquiv w) : WithVal v ≃ᵤ WithVal w where diff --git a/Mathlib/Topology/Compactness/Lindelof.lean b/Mathlib/Topology/Compactness/Lindelof.lean index d7ccffdcb649fc..3c09468d9e286c 100644 --- a/Mathlib/Topology/Compactness/Lindelof.lean +++ b/Mathlib/Topology/Compactness/Lindelof.lean @@ -644,9 +644,6 @@ theorem isLindelof_iff_isLindelof_univ : IsLindelof s ↔ IsLindelof (univ : Set theorem isLindelof_iff_lindelofSpace : IsLindelof s ↔ LindelofSpace s := isLindelof_iff_isLindelof_univ.trans isLindelof_univ_iff -@[deprecated (since := "2026-01-12")] -alias isLindelof_iff_LindelofSpace := isLindelof_iff_lindelofSpace - lemma IsLindelof.of_coe [LindelofSpace s] : IsLindelof s := isLindelof_iff_lindelofSpace.mpr ‹_› theorem IsLindelof.countable (hs : IsLindelof s) (hs' : DiscreteTopology s) : s.Countable := @@ -685,15 +682,9 @@ instance Quot.lindelofSpace {r : X → X → Prop} [LindelofSpace X] : LindelofS rw [← range_quot_mk] exact isLindelof_range continuous_quot_mk -@[deprecated (since := "2026-01-12")] -alias Quot.LindelofSpace := Quot.lindelofSpace - instance Quotient.lindelofSpace {s : Setoid X} [LindelofSpace X] : LindelofSpace (Quotient s) := Quot.lindelofSpace -@[deprecated (since := "2026-01-12")] -alias Quotient.LindelofSpace := Quotient.lindelofSpace - /-- A continuous image of a Lindelöf set is a Lindelöf set within the codomain. -/ theorem LindelofSpace.of_continuous_surjective {f : X → Y} [LindelofSpace X] (hf : Continuous f) (hsur : Function.Surjective f) : LindelofSpace Y where @@ -726,9 +717,6 @@ theorem HereditarilyLindelofSpace.isLindelof [HereditarilyLindelofSpace X] (s : apply HereditarilyLindelofSpace.isHereditarilyLindelof_univ exact subset_univ s -@[deprecated (since := "2026-01-12")] -alias HereditarilyLindelof_LindelofSets := HereditarilyLindelofSpace.isLindelof - theorem HereditarilyLindelofSpace.of_forall_isOpen (H : ∀ s : Set X, IsOpen s → IsLindelof s) : HereditarilyLindelofSpace X := by refine ⟨fun s _ ↦ isLindelof_of_countable_subcover fun U U_open hU ↦ ?_⟩ diff --git a/Mathlib/Topology/EMetricSpace/Defs.lean b/Mathlib/Topology/EMetricSpace/Defs.lean index 7008002199fb9a..fe647e32634d6d 100644 --- a/Mathlib/Topology/EMetricSpace/Defs.lean +++ b/Mathlib/Topology/EMetricSpace/Defs.lean @@ -350,9 +350,6 @@ distance, with a topology defeq to the initial one. -/ toUniformSpace := uniformSpaceOfEDistOfHasBasis d h_self h_comm h_triangle h_basis uniformity_edist := rfl -@[deprecated (since := "2026-01-08")] -alias PseudoEmetricSpace.ofEdistOfTopology := PseudoEMetricSpace.ofEDistOfTopology - namespace MulOpposite /-- Pseudoemetric space instance on the multiplicative opposite of a pseudoemetric space. -/ @@ -631,60 +628,6 @@ theorem closedEBall_prod_same [PseudoEMetricSpace β] (x : α) (y : β) (r : ℝ end Metric -namespace EMetric - -open Metric - -@[deprecated (since := "2026-01-24")] alias ball := eball -@[deprecated (since := "2026-01-24")] alias mem_ball := mem_eball -@[deprecated (since := "2026-01-24")] alias mem_ball' := mem_eball' -@[deprecated (since := "2026-01-24")] alias closedBall := closedEBall -@[deprecated (since := "2026-01-24")] alias mem_closedBall := mem_closedEBall -@[deprecated (since := "2026-01-24")] alias mem_closedBall' := mem_closedEBall' -@[deprecated (since := "2026-01-24")] alias closedBall_top := closedEBall_top -@[deprecated (since := "2026-01-24")] alias ball_subset_closedBall := eball_subset_closedEBall -@[deprecated (since := "2026-01-24")] alias pos_of_mem_ball := pos_of_mem_eball -@[deprecated (since := "2026-01-24")] alias mem_ball_self := mem_eball_self -@[deprecated (since := "2026-01-24")] alias mem_closedBall_self := mem_closedEBall_self -@[deprecated (since := "2026-01-24")] alias mem_ball_comm := mem_eball_comm -@[deprecated (since := "2026-01-24")] alias mem_closedBall_comm := mem_closedEBall_comm -@[deprecated (since := "2026-01-24")] alias ball_subset_ball := eball_subset_eball - -@[deprecated (since := "2026-01-24")] -alias closedBall_subset_closedBall := closedEBall_subset_closedEBall - -@[deprecated (since := "2026-01-24")] alias ball_disjoint := eball_disjoint -@[deprecated (since := "2026-01-24")] alias ball_subset := eball_subset -@[deprecated (since := "2026-01-24")] alias exists_ball_subset_ball := exists_eball_subset_eball -@[deprecated (since := "2026-01-24")] alias ball_eq_empty_iff := eball_eq_empty_iff - -@[deprecated (since := "2026-01-24")] -alias ordConnected_setOf_closedBall_subset := ordConnected_setOfPred_closedEBall_subset - -@[deprecated (since := "2026-01-24")] -alias ordConnected_setOf_ball_subset := ordConnected_setOfPred_eball_subset - -@[deprecated (since := "2026-01-24")] alias edistLtTopSetoid := edistLtTopSetoid -@[deprecated (since := "2026-01-24")] alias ball_zero := eball_zero - -@[deprecated (since := "2026-01-24")] -protected alias nhds_basis_eball := nhds_basis_eball - -@[deprecated (since := "2026-01-24")] alias nhdsWithin_basis_eball := nhdsWithin_basis_eball -@[deprecated (since := "2026-01-24")] alias nhds_basis_closed_eball := nhds_basis_closedEBall - -@[deprecated (since := "2026-01-24")] -alias nhdsWithin_basis_closed_eball := nhdsWithin_basis_closedEBall - -@[deprecated (since := "2026-01-24")] alias isOpen_ball := isOpen_eball -@[deprecated (since := "2026-01-24")] alias isClosed_ball_top := isClosed_eball_top -@[deprecated (since := "2026-01-24")] alias ball_mem_nhds := eball_mem_nhds -@[deprecated (since := "2026-01-24")] alias closedBall_mem_nhds := closedEBall_mem_nhds -@[deprecated (since := "2026-01-24")] alias ball_prod_same := eball_prod_same -@[deprecated (since := "2026-01-24")] alias closedBall_prod_same := closedEBall_prod_same - -end EMetric - namespace Subtype open Metric @@ -694,33 +637,21 @@ theorem preimage_eball {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val ⁻¹' (eball a.1 r) = eball a r := rfl -@[deprecated (since := "2026-01-24")] -alias preimage_emetricBall := preimage_eball - @[simp] theorem preimage_closedEBall {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val ⁻¹' (closedEBall a.1 r) = closedEBall a r := rfl -@[deprecated (since := "2026-01-24")] -alias preimage_emetricClosedBall := preimage_closedEBall - @[simp] theorem image_eball {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val '' (eball a r) = eball a.1 r ∩ {a | p a} := by rw [← preimage_eball, image_preimage_eq_inter_range, range_val_subtype] -@[deprecated (since := "2026-01-24")] -alias image_emetricBall := image_eball - @[simp] theorem image_closedEBall {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val '' (closedEBall a r) = closedEBall a.1 r ∩ {a | p a} := by rw [← preimage_closedEBall, image_preimage_eq_inter_range, range_val_subtype] -@[deprecated (since := "2026-01-24")] -alias image_emetricClosedBall := image_closedEBall - end Subtype /-- An extended metric space is a type endowed with a `ℝ≥0∞`-valued distance `edist` satisfying @@ -770,9 +701,6 @@ theorem edist_pos {x y : γ} : 0 < edist x y ↔ x ≠ y := by simp [← not_le] @[simp] lemma Metric.closedEBall_zero (x : γ) : closedEBall x 0 = {x} := by ext; simp -@[deprecated (since := "2026-01-24")] -alias EMetric.closedBall_zero := Metric.closedEBall_zero - /-- Two points coincide if their distance is `< ε` for all positive ε -/ theorem eq_of_forall_edist_le {x y : γ} (h : ∀ ε > 0, edist x y ≤ ε) : x = y := eq_of_edist_eq_zero (eq_of_le_of_forall_lt_imp_le_of_dense bot_le h) diff --git a/Mathlib/Topology/EMetricSpace/Diam.lean b/Mathlib/Topology/EMetricSpace/Diam.lean index a2df423701992f..4674885d174afb 100644 --- a/Mathlib/Topology/EMetricSpace/Diam.lean +++ b/Mathlib/Topology/EMetricSpace/Diam.lean @@ -153,35 +153,3 @@ theorem ediam_pos_iff' : 0 < ediam s ↔ ∃ x ∈ s, ∃ y ∈ s, x ≠ y := by end EMetricSpace end Metric - -namespace EMetric - -open Metric - -@[deprecated (since := "2026-01-04")] alias diam := Metric.ediam -@[deprecated (since := "2026-01-04")] alias diam_eq_sSup := ediam_eq_sSup -@[deprecated (since := "2026-01-04")] alias diam_le_iff := ediam_le_iff -@[deprecated (since := "2026-01-04")] alias diam_image_le_iff := ediam_image_le_iff -@[deprecated (since := "2026-01-04")] alias edist_le_of_diam_le := edist_le_of_ediam_le -@[deprecated (since := "2026-01-04")] alias edist_le_diam_of_mem := edist_le_ediam_of_mem -@[deprecated (since := "2026-01-04")] alias diam_le := ediam_le -@[deprecated (since := "2026-01-04")] alias diam_subsingleton := ediam_subsingleton -@[deprecated (since := "2026-01-04")] alias diam_empty := ediam_empty -@[deprecated (since := "2026-01-04")] alias diam_singleton := ediam_singleton -@[deprecated (since := "2026-01-04")] alias diam_zero := ediam_zero -@[to_additive existing, deprecated (since := "2026-01-04")] alias diam_one := ediam_one -@[deprecated (since := "2026-01-04")] alias diam_iUnion_mem_option := ediam_iUnion_mem_option -@[deprecated (since := "2026-01-04")] alias diam_insert := ediam_insert -@[deprecated (since := "2026-01-04")] alias diam_pair := ediam_pair -@[deprecated (since := "2026-01-04")] alias diam_triple := ediam_triple -@[deprecated (since := "2026-01-04")] alias diam_mono := ediam_mono -@[deprecated (since := "2026-01-04")] alias diam_union := ediam_union_le_add_edist -@[deprecated (since := "2026-01-04")] alias diam_union' := ediam_union_le -@[deprecated (since := "2026-01-04")] alias diam_closedBall := ediam_closedEBall_le -@[deprecated (since := "2026-01-04")] alias diam_ball := ediam_eball_le -@[deprecated (since := "2026-01-04")] alias diam_pi_le_of_le := ediam_pi_le_of_le -@[deprecated (since := "2026-01-04")] alias diam_eq_zero_iff := ediam_eq_zero_iff -@[deprecated (since := "2026-01-04")] alias diam_pos_iff := ediam_pos_iff -@[deprecated (since := "2026-01-04")] alias diam_pos_iff' := ediam_pos_iff' - -end EMetric diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index 344d98497ae0a9..024066a705c84c 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -149,15 +149,9 @@ theorem edist_lt_mul_of_lt (h : LipschitzWith K f) (hK : K ≠ 0) (hr : edist x theorem mapsTo_closedEBall (h : LipschitzWith K f) (x : α) (r : ℝ≥0∞) : MapsTo f (closedEBall x r) (closedEBall (f x) (K * r)) := fun _y hy => h.edist_le_mul_of_le hy -@[deprecated (since := "2026-01-24")] -alias mapsTo_emetric_closedBall := mapsTo_closedEBall - theorem mapsTo_eball (h : LipschitzWith K f) (hK : K ≠ 0) (x : α) (r : ℝ≥0∞) : MapsTo f (eball x r) (eball (f x) (K * r)) := fun _y hy => h.edist_lt_mul_of_lt hK hy -@[deprecated (since := "2026-01-24")] -alias mapsTo_emetric_ball := mapsTo_eball - theorem edist_lt_top (hf : LipschitzWith K f) {x y : α} (h : edist x y ≠ ⊤) : edist (f x) (f y) < ⊤ := (hf x y).trans_lt (by finiteness) diff --git a/Mathlib/Topology/EMetricSpace/Paracompact.lean b/Mathlib/Topology/EMetricSpace/Paracompact.lean index 02ceccf4ed2b5e..e14930c10c1fa1 100644 --- a/Mathlib/Topology/EMetricSpace/Paracompact.lean +++ b/Mathlib/Topology/EMetricSpace/Paracompact.lean @@ -166,6 +166,3 @@ instance (priority := 100) instParacompactSpace [PseudoEMetricSpace α] : Paraco theorem t4Space [EMetricSpace α] : T4Space α := inferInstance end Metric - -@[deprecated (since := "2026-01-24")] -alias EMetric.t4Space := Metric.t4Space diff --git a/Mathlib/Topology/Instances/AddCircle/Defs.lean b/Mathlib/Topology/Instances/AddCircle/Defs.lean index 1d16654533c69e..b57d20f859d8ee 100644 --- a/Mathlib/Topology/Instances/AddCircle/Defs.lean +++ b/Mathlib/Topology/Instances/AddCircle/Defs.lean @@ -99,17 +99,11 @@ theorem continuousWithinAt_toIcoMod_Ici : ContinuousWithinAt (toIcoMod hp a) (Ic continuousWithinAt_id.sub <| (continuousWithinAt_toIcoDiv_Ici hp a x).smul continuousWithinAt_const -@[deprecated (since := "2026-01-04")] -alias continuous_right_toIcoMod := continuousWithinAt_toIcoMod_Ici - /-- `toIocMod` is continuous on the right at every point. -/ theorem continuousWithinAt_toIocMod_Iic : ContinuousWithinAt (toIocMod hp a) (Iic x) x := continuousWithinAt_id.sub <| (continuousWithinAt_toIocDiv_Iic hp a x).smul continuousWithinAt_const -@[deprecated (since := "2026-01-04")] -alias continuous_left_toIocMod := continuousWithinAt_toIocMod_Iic - /-- At every point `x`, for all `y < x` sufficiently close to `x`, we have `toIcoDiv hp a y = toIocDiv hp a x`. diff --git a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean index 21abe387b6a04a..cc47b757fa1ed5 100644 --- a/Mathlib/Topology/Instances/ENNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/ENNReal/Lemmas.lean @@ -466,8 +466,6 @@ protected theorem continuous_zpow : ∀ n : ℤ, Continuous (· ^ n : ℝ≥0∞ | (n : ℕ) => mod_cast ENNReal.continuous_pow n | .negSucc n => by simpa using (ENNReal.continuous_pow _).fun_inv -@[deprecated (since := "2026-01-15")] protected alias tendsto_inv_iff := tendsto_inv_iff - protected theorem Tendsto.div {f : Filter α} {ma : α → ℝ≥0∞} {mb : α → ℝ≥0∞} {a b : ℝ≥0∞} (hma : Tendsto ma f (𝓝 a)) (ha : a ≠ 0 ∨ b ≠ 0) (hmb : Tendsto mb f (𝓝 b)) (hb : b ≠ ∞ ∨ a ≠ ∞) : Tendsto (fun a => ma a / mb a) f (𝓝 (a / b)) := by @@ -645,9 +643,6 @@ theorem Filter.Tendsto.edist {f g : β → α} {x : Filter β} {a b : α} (hf : theorem Metric.isClosed_closedEBall {a : α} {r : ℝ≥0∞} : IsClosed (closedEBall a r) := isClosed_le (by fun_prop) continuous_const -@[deprecated (since := "2026-01-24")] -alias EMetric.isClosed_closedBall := Metric.isClosed_closedEBall - @[simp] theorem Metric.ediam_closure (s : Set α) : ediam (closure s) = ediam s := by refine le_antisymm (ediam_le fun x hx y hy => ?_) (ediam_mono subset_closure) @@ -655,8 +650,6 @@ theorem Metric.ediam_closure (s : Set α) : ediam (closure s) = ediam s := by map_mem_closure₂ continuous_edist hx hy fun x hx y hy => edist_le_ediam_of_mem hx hy rwa [closure_Iic] at this -@[deprecated (since := "2026-01-04")] alias EMetric.diam_closure := Metric.ediam_closure - @[simp] theorem Metric.diam_closure {α : Type*} [PseudoMetricSpace α] (s : Set α) : Metric.diam (closure s) = diam s := by simp only [Metric.diam, Metric.ediam_closure] diff --git a/Mathlib/Topology/Instances/NNReal/Lemmas.lean b/Mathlib/Topology/Instances/NNReal/Lemmas.lean index cd1f53297b9ea3..417284b0fd3405 100644 --- a/Mathlib/Topology/Instances/NNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/NNReal/Lemmas.lean @@ -226,29 +226,6 @@ def powOrderIso (n : ℕ) (hn : n ≠ 0) : ℝ≥0 ≃o ℝ≥0 := (continuous_id.pow _).surjective (tendsto_pow_atTop hn) <| by simpa [OrderBot.atBot_eq, pos_iff_ne_zero] -section Monotone - -/-- A monotone, bounded above sequence `f : ℕ → ℝ` has a finite limit. -/ -@[deprecated tendsto_atTop_ciSup (since := "2026-01-14")] -theorem _root_.Real.tendsto_of_bddAbove_monotone {f : ℕ → ℝ} (h_bdd : BddAbove (Set.range f)) - (h_mon : Monotone f) : ∃ r : ℝ, Tendsto f atTop (𝓝 r) := - ⟨iSup f, tendsto_atTop_ciSup h_mon h_bdd⟩ - -/-- An antitone, bounded below sequence `f : ℕ → ℝ` has a finite limit. -/ -@[deprecated tendsto_atTop_ciInf (since := "2026-01-14")] -theorem _root_.Real.tendsto_of_bddBelow_antitone {f : ℕ → ℝ} (h_bdd : BddBelow (Set.range f)) - (h_ant : Antitone f) : ∃ r : ℝ, Tendsto f atTop (𝓝 r) := - ⟨iInf f, tendsto_atTop_ciInf h_ant h_bdd⟩ - -variable {ι : Type*} [Preorder ι] - -/-- An antitone sequence `f : ℕ → ℝ≥0` has a finite limit. -/ -@[deprecated tendsto_atTop_ciInf (since := "2026-01-14")] -theorem tendsto_of_antitone {f : ℕ → ℝ≥0} (h_ant : Antitone f) : - ∃ r : ℝ≥0, Tendsto f atTop (𝓝 r) := ⟨iInf f, tendsto_atTop_ciInf h_ant (by simp)⟩ - -end Monotone - lemma iSup_pow_of_ne_zero (hn : n ≠ 0) (f : ι → ℝ≥0) : (⨆ i, f i) ^ n = ⨆ i, f i ^ n := (NNReal.powOrderIso n hn).map_ciSup' _ diff --git a/Mathlib/Topology/MetricSpace/Closeds.lean b/Mathlib/Topology/MetricSpace/Closeds.lean index 84f4056f1a67af..b374908ddb14a5 100644 --- a/Mathlib/Topology/MetricSpace/Closeds.lean +++ b/Mathlib/Topology/MetricSpace/Closeds.lean @@ -269,14 +269,6 @@ theorem isometry_toCloseds : Isometry (@NonemptyCompacts.toCloseds α _ _) := theorem isometry_toCompacts : Isometry (NonemptyCompacts.toCompacts (α := α)) := fun _ _ => rfl -/-- The range of `NonemptyCompacts.toCloseds` is closed in a complete space -/ -@[deprecated - "Use `TopologicalSpace.NonemptyCompacts.isClosedEmbedding_toCloseds.isClosed_range` instead" - (since := "2026-01-28")] -theorem isClosed_in_closeds [CompleteSpace α] : - IsClosed (range <| @NonemptyCompacts.toCloseds α _ _) := - NonemptyCompacts.isClosedEmbedding_toCloseds.isClosed_range - theorem isometry_singleton : Isometry ({·} : α → NonemptyCompacts α) := fun _ _ => hausdorffEDist_singleton @@ -292,52 +284,6 @@ end NonemptyCompacts end TopologicalSpace -namespace EMetric - -open Metric - -@[deprecated (since := "2026-01-08")] -alias mem_hausdorffEntourage_of_hausdorffEdist_lt := - mem_hausdorffEntourage_of_hausdorffEDist_lt - -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_le_of_mem_hausdorffEntourage := hausdorffEDist_le_of_mem_hausdorffEntourage - -@[deprecated (since := "2026-01-08")] -alias continuous_infEdist_hausdorffEdist := - TopologicalSpace.Closeds.continuous_infEDist - -@[deprecated (since := "2026-01-08")] -alias Closeds.edist_eq := TopologicalSpace.Closeds.edist_eq - -@[deprecated (since := "2026-01-08")] -alias Closeds.isometry_singleton := TopologicalSpace.Closeds.isometry_singleton - -@[deprecated (since := "2026-01-08")] -alias Closeds.lipschitz_sup := TopologicalSpace.Closeds.lipschitz_sup - -@[deprecated (since := "2026-01-08")] -alias NonemptyCompacts.isometry_toCloseds := - TopologicalSpace.NonemptyCompacts.isometry_toCloseds - -@[deprecated (since := "2026-01-08")] -alias NonemptyCompacts.isClosed_in_closeds := - TopologicalSpace.NonemptyCompacts.isClosed_in_closeds - -@[deprecated (since := "2026-01-08")] -alias NonemptyCompacts.isometry_singleton := - TopologicalSpace.NonemptyCompacts.isometry_singleton - -@[deprecated (since := "2026-01-08")] -alias NonemptyCompacts.lipschitz_sup := - TopologicalSpace.NonemptyCompacts.lipschitz_sup - -@[deprecated (since := "2026-01-08")] -alias NonemptyCompacts.lipschitz_prod := - TopologicalSpace.NonemptyCompacts.lipschitz_prod - -end EMetric --namespace - namespace Metric section diff --git a/Mathlib/Topology/MetricSpace/Dilation.lean b/Mathlib/Topology/MetricSpace/Dilation.lean index 58de6f264bbd30..91d94116b84adb 100644 --- a/Mathlib/Topology/MetricSpace/Dilation.lean +++ b/Mathlib/Topology/MetricSpace/Dilation.lean @@ -397,17 +397,11 @@ theorem mapsTo_eball (x : α) (r : ℝ≥0∞) : MapsTo (f : α → β) (Metric.eball x r) (Metric.eball (f x) (ratio f * r)) := fun y (hy : _ < r) ↦ by rw [Metric.mem_eball, edist_eq f y x]; gcongr <;> simp [ratio_ne_zero, *] -@[deprecated (since := "2026-01-24")] -alias mapsTo_emetric_ball := mapsTo_eball - /-- A dilation maps closed balls to closed balls and scales the radius by `ratio f`. -/ theorem mapsTo_closedEBall (x : α) (r' : ℝ≥0∞) : MapsTo (f : α → β) (Metric.closedEBall x r') (Metric.closedEBall (f x) (ratio f * r')) := fun y hy => (edist_eq f y x).trans_le <| by gcongr; exact hy -@[deprecated (since := "2026-01-24")] -alias mapsTo_emetric_closedBall := mapsTo_closedEBall - theorem comp_continuousOn_iff {γ} [TopologicalSpace γ] {g : γ → α} {s : Set γ} : ContinuousOn ((f : α → β) ∘ g) s ↔ ContinuousOn g s := (Dilation.isUniformInducing f).isInducing.continuousOn_iff.symm diff --git a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean index bc5626fe15264c..32ad0e82e1fef6 100644 --- a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean +++ b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean @@ -443,118 +443,6 @@ end HausdorffEDist -- section end Metric -- namespace -namespace EMetric - -open Metric - -@[deprecated (since := "2026-01-08")] -noncomputable alias infEdist := infEDist - -@[deprecated (since := "2026-01-08")] -alias infEdist_empty := infEDist_empty - -@[deprecated (since := "2026-01-08")] alias le_infEdist := le_infEDist -@[deprecated (since := "2026-01-08")] alias infEdist_union := infEDist_union -@[deprecated (since := "2026-01-08")] alias infEdist_iUnion := infEDist_iUnion -@[deprecated (since := "2026-01-08")] alias infEdist_biUnion := infEDist_biUnion -@[deprecated (since := "2026-01-08")] alias infEdist_singleton := infEDist_singleton -@[deprecated (since := "2026-01-08")] alias infEdist_le_edist_of_mem := infEDist_le_edist_of_mem -@[deprecated (since := "2026-01-08")] alias infEdist_zero_of_mem := infEDist_zero_of_mem -@[deprecated (since := "2026-01-08")] alias infEdist_anti := infEDist_anti -@[deprecated (since := "2026-01-08")] alias infEdist_lt_iff := infEDist_lt_iff - -@[deprecated (since := "2026-01-08")] -alias infEdist_le_infEdist_add_edist := infEDist_le_infEDist_add_edist - -@[deprecated (since := "2026-01-08")] -alias infEdist_le_edist_add_infEdist := infEDist_le_edist_add_infEDist - -@[deprecated (since := "2026-01-08")] -alias edist_le_infEdist_add_ediam := edist_le_infEDist_add_ediam - -@[deprecated (since := "2026-01-08")] alias continuous_infEdist := continuous_infEDist -@[deprecated (since := "2026-01-08")] alias infEdist_closure := infEDist_closure - -@[deprecated (since := "2026-01-08")] -alias mem_closure_iff_infEdist_zero := mem_closure_iff_infEDist_zero - -@[deprecated (since := "2026-01-08")] -alias mem_iff_infEdist_zero_of_closed := mem_iff_infEDist_zero_of_closed - -@[deprecated (since := "2026-01-08")] -alias infEdist_pos_iff_notMem_closure := infEDist_pos_iff_notMem_closure - -@[deprecated (since := "2026-01-08")] -alias infEdist_closure_pos_iff_notMem_closure := infEDist_closure_pos_iff_notMem_closure - -@[deprecated (since := "2026-01-08")] -alias exists_real_pos_lt_infEdist_of_notMem_closure := exists_real_pos_lt_infEDist_of_notMem_closure - -@[deprecated (since := "2026-01-08")] -alias disjoint_closedBall_of_lt_infEdist := disjoint_closedEBall_of_lt_infEDist - -@[deprecated (since := "2026-01-08")] alias infEdist_image := infEDist_image -@[deprecated (since := "2026-01-08")] alias infEdist_vadd := infEDist_vadd -@[to_additive existing, deprecated (since := "2026-01-08")] alias infEdist_smul := infEDist_smul - -@[deprecated (since := "2026-01-08")] -alias _root_.IsCompact.exists_infEdist_eq_edist := _root_.IsCompact.exists_infEDist_eq_edist - -@[deprecated (since := "2026-01-08")] alias exists_pos_forall_lt_edist := exists_pos_forall_lt_edist -@[deprecated (since := "2026-01-08")] alias infEdist_prod := infEDist_prod - -@[deprecated (since := "2026-01-08")] noncomputable alias hausdorffEdist := hausdorffEDist -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_def := hausdorffEDist_def -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_self := hausdorffEDist_self -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_comm := hausdorffEDist_comm - -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_le_of_infEdist := hausdorffEDist_le_of_infEDist - -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_le_of_mem_edist := hausdorffEDist_le_of_mem_edist - -@[deprecated (since := "2026-01-08")] -alias infEdist_le_hausdorffEdist_of_mem := infEDist_le_hausdorffEDist_of_mem - -@[deprecated (since := "2026-01-08")] -alias exists_edist_lt_of_hausdorffEdist_lt := exists_edist_lt_of_hausdorffEDist_lt - -@[deprecated (since := "2026-01-08")] -alias infEdist_le_infEdist_add_hausdorffEdist := infEDist_le_infEDist_add_hausdorffEDist - -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_image := hausdorffEDist_image -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_le_ediam := hausdorffEDist_le_ediam -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_triangle := hausdorffEDist_triangle - -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_zero_iff_closure_eq_closure := hausdorffEDist_zero_iff_closure_eq_closure - -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_self_closure := hausdorffEDist_self_closure - -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_closure₁ := hausdorffEDist_closure_left -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_closure₂ := hausdorffEDist_closure_right -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_closure := hausdorffEDist_closure - -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_zero_iff_eq_of_closed := IsClosed.hausdorffEDist_zero_iff - -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_empty := hausdorffEDist_empty - -@[deprecated (since := "2026-01-08")] -alias nonempty_of_hausdorffEdist_ne_top := nonempty_of_hausdorffEDist_ne_top - -@[deprecated (since := "2026-01-08")] -alias empty_or_nonempty_of_hausdorffEdist_ne_top := empty_or_nonempty_of_hausdorffEDist_ne_top - -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_singleton := hausdorffEDist_singleton -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_iUnion_le := hausdorffEDist_iUnion_le -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_union_le := hausdorffEDist_union_le -@[deprecated (since := "2026-01-08")] alias hausdorffEdist_prod_le := hausdorffEDist_prod_le - -end EMetric - /-! Now, we turn to the same notions in metric spaces. To avoid the difficulties related to `sInf` and `sSup` on `ℝ` (which is only conditionally complete), we use the notions in `ℝ≥0∞` formulated in terms of the edistance, and coerce them to `ℝ`. @@ -595,16 +483,10 @@ theorem infEDist_ne_top (h : s.Nonempty) : infEDist x s ≠ ∞ := by rcases h with ⟨y, hy⟩ exact ne_top_of_le_ne_top (edist_ne_top _ _) (infEDist_le_edist_of_mem hy) -@[deprecated (since := "2026-01-08")] -alias infEdist_ne_top := infEDist_ne_top - @[simp] theorem infEDist_eq_top_iff : infEDist x s = ∞ ↔ s = ∅ := by rcases s.eq_empty_or_nonempty with rfl | hs <;> simp [*, Nonempty.ne_empty, infEDist_ne_top] -@[deprecated (since := "2026-01-08")] -alias infEdist_eq_top_iff := infEDist_eq_top_iff - /-- The minimal distance of a point to a set containing it vanishes. -/ theorem infDist_zero_of_mem (h : x ∈ s) : infDist x s = 0 := by simp [infEDist_zero_of_mem h, infDist] @@ -799,9 +681,6 @@ theorem hausdorffEDist_ne_top_of_nonempty_of_bounded (hs : s.Nonempty) (ht : t.N exact le_trans dist_nonneg this exact ne_top_of_le_ne_top ENNReal.ofReal_ne_top this -@[deprecated (since := "2026-01-08")] -alias hausdorffEdist_ne_top_of_nonempty_of_bounded := hausdorffEDist_ne_top_of_nonempty_of_bounded - /-- The Hausdorff distance between a set and itself is zero. -/ @[simp] theorem hausdorffDist_self_zero : hausdorffDist s s = 0 := by simp [hausdorffDist] diff --git a/Mathlib/Topology/MetricSpace/IsometricSMul.lean b/Mathlib/Topology/MetricSpace/IsometricSMul.lean index a7c1d6541cb204..b72f542202b560 100644 --- a/Mathlib/Topology/MetricSpace/IsometricSMul.lean +++ b/Mathlib/Topology/MetricSpace/IsometricSMul.lean @@ -243,58 +243,6 @@ end Metric end EMetric -namespace EMetric -open Metric - -@[deprecated (since := "2026-01-24")] -alias vadd_ball := vadd_eball - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias smul_ball := smul_eball - -@[deprecated (since := "2026-01-24")] alias preimage_vadd_ball := preimage_vadd_eball - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias preimage_smul_ball := preimage_smul_eball - -@[deprecated (since := "2026-01-24")] -alias vadd_closedBall := vadd_closedEBall - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias smul_closedBall := smul_closedEBall - -@[deprecated (since := "2026-01-24")] -alias preimage_vadd_closedBall := preimage_vadd_closedEBall - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias preimage_smul_closedBall := preimage_smul_closedEBall - -@[deprecated (since := "2026-01-24")] -alias preimage_add_left_ball := preimage_add_left_eball - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias preimage_mul_left_ball := preimage_mul_left_eball - -@[deprecated (since := "2026-01-24")] -alias preimage_add_right_ball := preimage_add_right_eball - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias preimage_mul_right_ball := preimage_mul_right_eball - -@[deprecated (since := "2026-01-24")] -alias preimage_add_left_closedBall := preimage_add_left_closedEBall - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias preimage_mul_left_closedBall := preimage_mul_left_closedEBall - -@[deprecated (since := "2026-01-24")] -alias preimage_add_right_closedBall := preimage_add_right_closedEBall - -@[to_additive existing, deprecated (since := "2026-01-24")] -alias preimage_mul_right_closedBall := preimage_mul_right_closedEBall - -end EMetric - @[to_additive (attr := simp)] theorem dist_smul [PseudoMetricSpace X] [SMul M X] [IsIsometricSMul M X] (c : M) (x y : X) : dist (c • x) (c • y) = dist x y := diff --git a/Mathlib/Topology/MetricSpace/Isometry.lean b/Mathlib/Topology/MetricSpace/Isometry.lean index b9e0189c095dff..fb19d6892e43e5 100644 --- a/Mathlib/Topology/MetricSpace/Isometry.lean +++ b/Mathlib/Topology/MetricSpace/Isometry.lean @@ -150,17 +150,11 @@ theorem preimage_closedEBall (h : Isometry f) (x : α) (r : ℝ≥0∞) : ext y simp [h.edist_eq] -@[deprecated (since := "2026-01-24")] -alias preimage_emetric_closedBall := preimage_closedEBall - theorem preimage_eball (h : Isometry f) (x : α) (r : ℝ≥0∞) : f ⁻¹' Metric.eball (f x) r = Metric.eball x r := by ext y simp [h.edist_eq] -@[deprecated (since := "2026-01-24")] -alias preimage_emetric_ball := preimage_eball - /-- Isometries preserve the diameter in pseudoemetric spaces. -/ theorem ediam_image (hf : Isometry f) (s : Set α) : Metric.ediam (f '' s) = Metric.ediam s := eq_of_forall_ge_iff fun d => by simp only [Metric.ediam_le_iff, forall_mem_image, hf.edist_eq] @@ -173,16 +167,10 @@ theorem mapsTo_eball (hf : Isometry f) (x : α) (r : ℝ≥0∞) : MapsTo f (Metric.eball x r) (Metric.eball (f x) r) := (hf.preimage_eball x r).ge -@[deprecated (since := "2026-01-24")] -alias mapsTo_emetric_ball := mapsTo_eball - theorem mapsTo_closedEBall (hf : Isometry f) (x : α) (r : ℝ≥0∞) : MapsTo f (Metric.closedEBall x r) (Metric.closedEBall (f x) r) := (hf.preimage_closedEBall x r).ge -@[deprecated (since := "2026-01-24")] -alias mapsTo_emetric_closedBall := mapsTo_closedEBall - /-- The injection from a subtype is an isometry -/ theorem _root_.isometry_subtype_coe {s : Set α} : Isometry ((↑) : s → α) := fun _ _ => rfl @@ -518,33 +506,21 @@ theorem preimage_eball (h : α ≃ᵢ β) (x : β) (r : ℝ≥0∞) : h ⁻¹' Metric.eball x r = Metric.eball (h.symm x) r := by rw [← h.isometry.preimage_eball (h.symm x) r, h.apply_symm_apply] -@[deprecated (since := "2026-01-24")] -alias preimage_emetric_ball := preimage_eball - @[simp] theorem preimage_closedEBall (h : α ≃ᵢ β) (x : β) (r : ℝ≥0∞) : h ⁻¹' Metric.closedEBall x r = Metric.closedEBall (h.symm x) r := by rw [← h.isometry.preimage_closedEBall (h.symm x) r, h.apply_symm_apply] -@[deprecated (since := "2026-01-24")] -alias preimage_emetric_closedBall := preimage_closedEBall - @[simp] theorem image_eball (h : α ≃ᵢ β) (x : α) (r : ℝ≥0∞) : h '' Metric.eball x r = Metric.eball (h x) r := by rw [← h.preimage_symm, h.symm.preimage_eball, symm_symm] -@[deprecated (since := "2026-01-24")] -alias image_emetric_ball := image_eball - @[simp] theorem image_closedEBall (h : α ≃ᵢ β) (x : α) (r : ℝ≥0∞) : h '' Metric.closedEBall x r = Metric.closedEBall (h x) r := by rw [← h.preimage_symm, h.symm.preimage_closedEBall, symm_symm] -@[deprecated (since := "2026-01-24")] -alias image_emetric_closedBall := image_closedEBall - /-- The (bundled) homeomorphism associated to an isometric isomorphism. -/ @[simps toEquiv] protected def toHomeomorph (h : α ≃ᵢ β) : α ≃ₜ β where diff --git a/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean b/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean index a84ec966909b97..8c11617e46be6f 100644 --- a/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean +++ b/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean @@ -119,33 +119,6 @@ theorem exists_continuous_ennreal_forall_closedEBall_subset (hK : ∀ i, IsClose end Metric -namespace EMetric -open Metric - -@[deprecated (since := "2026-01-24")] -alias eventually_nhds_zero_forall_closedBall_subset := - eventually_nhds_zero_forall_closedEBall_subset - -@[deprecated (since := "2026-01-24")] -alias exists_forall_closedBall_subset_aux₁ := exists_forall_closedEBall_subset_aux₁ - -@[deprecated (since := "2026-01-24")] -alias exists_forall_closedBall_subset_aux₂ := exists_forall_closedEBall_subset_aux₂ - -@[deprecated (since := "2026-01-24")] -alias exists_continuous_real_forall_closedBall_subset := - exists_continuous_real_forall_closedEBall_subset - -@[deprecated (since := "2026-01-24")] -alias exists_continuous_nnreal_forall_closedBall_subset := - exists_continuous_nnreal_forall_closedEBall_subset - -@[deprecated (since := "2026-01-24")] -alias exists_continuous_eNNReal_forall_closedBall_subset := - exists_continuous_ennreal_forall_closedEBall_subset - -end EMetric - namespace Metric variable [MetricSpace X] {K : ι → Set X} {U : ι → Set X} diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index a7f27cf04491d5..3f07a9dd82ca42 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -995,42 +995,27 @@ theorem Metric.eball_ofReal {x : α} {ε : ℝ} : eball x (.ofReal ε) = ball x simp only [mem_eball, mem_ball, edist_dist] exact ENNReal.ofReal_lt_ofReal_iff_of_nonneg dist_nonneg -@[deprecated (since := "2026-01-24")] -alias Metric.emetric_ball := Metric.eball_ofReal - /-- Balls defined using the distance or the edistance coincide -/ @[simp] theorem Metric.eball_coe {x : α} {ε : ℝ≥0} : eball x ε = ball x ε := by rw [← eball_ofReal] simp -@[deprecated (since := "2026-01-24")] -alias Metric.emetric_ball_nnreal := Metric.eball_coe - /-- Closed balls defined using the distance or the edistance coincide -/ theorem Metric.closedEBall_ofReal {x : α} {ε : ℝ} (h : 0 ≤ ε) : closedEBall x (.ofReal ε) = closedBall x ε := by ext y; simp [edist_le_ofReal h] -@[deprecated (since := "2026-01-24")] -alias Metric.emetric_closedBall := Metric.closedEBall_ofReal - /-- Closed balls defined using the distance or the edistance coincide -/ @[simp] theorem Metric.closedEBall_coe {x : α} {ε : ℝ≥0} : closedEBall x ε = closedBall x ε := by rw [← closedEBall_ofReal ε.coe_nonneg, ENNReal.ofReal_coe_nnreal] -@[deprecated (since := "2026-01-24")] -alias Metric.emetric_closedBall_nnreal := Metric.closedEBall_coe - @[simp] theorem Metric.eball_top (x : α) : eball x ⊤ = univ := eq_univ_of_forall fun _ => edist_lt_top _ _ -@[deprecated (since := "2026-01-24")] -alias Metric.emetric_ball_top := Metric.eball_top - /-- Build a new pseudometric space from an old one where the bundled uniform structure is provably (but typically non-definitionaly) equal to some given uniform structure. See Note [forgetful inheritance]. diff --git a/Mathlib/Topology/MetricSpace/Snowflaking.lean b/Mathlib/Topology/MetricSpace/Snowflaking.lean index 365ed2843654fb..a199811081de44 100644 --- a/Mathlib/Topology/MetricSpace/Snowflaking.lean +++ b/Mathlib/Topology/MetricSpace/Snowflaking.lean @@ -316,35 +316,23 @@ theorem preimage_ofSnowflaking_eball (x : X) (r : ℝ≥0∞) : ext ⟨y⟩ simp (disch := positivity) [ENNReal.rpow_lt_rpow_iff] -@[deprecated (since := "2026-01-24")] -alias preimage_ofSnowflaking_emetricBall := preimage_ofSnowflaking_eball - @[simp] theorem image_toSnowflaking_eball (x : X) (r : ℝ≥0∞) : toSnowflaking '' Metric.eball x r = Metric.eball (toSnowflaking x : Snowflaking X α hα₀ hα₁) (r ^ α) := by rw [image_toSnowflaking_eq_preimage, preimage_ofSnowflaking_eball] -@[deprecated (since := "2026-01-24")] -alias image_toSnowflaking_emetricBall := image_toSnowflaking_eball - @[simp] theorem preimage_toSnowflaking_eball (x : Snowflaking X α hα₀ hα₁) (d : ℝ≥0∞) : toSnowflaking ⁻¹' Metric.eball x d = Metric.eball x.ofSnowflaking (d ^ α⁻¹) := by rw [toSnowflaking.preimage_eq_iff_eq_image, image_toSnowflaking_eball, toSnowflaking_ofSnowflaking, ENNReal.rpow_inv_rpow hα₀.ne'] -@[deprecated (since := "2026-01-24")] -alias preimage_toSnowflaking_emetricBall := preimage_toSnowflaking_eball - @[simp] theorem image_ofSnowflaking_eball (x : Snowflaking X α hα₀ hα₁) (d : ℝ≥0∞) : ofSnowflaking '' Metric.eball x d = Metric.eball x.ofSnowflaking (d ^ α⁻¹) := by rw [image_ofSnowflaking_eq_preimage, preimage_toSnowflaking_eball] -@[deprecated (since := "2026-01-24")] -alias image_ofSnowflaking_emetricBall := image_ofSnowflaking_eball - @[simp] theorem preimage_ofSnowflaking_closedEBall (x : X) (r : ℝ≥0∞) : ofSnowflaking ⁻¹' Metric.closedEBall x r = @@ -352,36 +340,24 @@ theorem preimage_ofSnowflaking_closedEBall (x : X) (r : ℝ≥0∞) : ext ⟨y⟩ simp (disch := positivity) [ENNReal.rpow_le_rpow_iff] -@[deprecated (since := "2026-01-24")] -alias preimage_ofSnowflaking_emetricClosedBall := preimage_ofSnowflaking_closedEBall - @[simp] theorem image_toSnowflaking_closedEBall (x : X) (r : ℝ≥0∞) : toSnowflaking '' Metric.closedEBall x r = Metric.closedEBall (toSnowflaking x : Snowflaking X α hα₀ hα₁) (r ^ α) := by rw [image_toSnowflaking_eq_preimage, preimage_ofSnowflaking_closedEBall] -@[deprecated (since := "2026-01-24")] -alias image_toSnowflaking_emetricClosedBall := image_toSnowflaking_closedEBall - @[simp] theorem preimage_toSnowflaking_closedEBall (x : Snowflaking X α hα₀ hα₁) (d : ℝ≥0∞) : toSnowflaking ⁻¹' Metric.closedEBall x d = Metric.closedEBall x.ofSnowflaking (d ^ α⁻¹) := by rw [toSnowflaking.preimage_eq_iff_eq_image, image_toSnowflaking_closedEBall, toSnowflaking_ofSnowflaking, ENNReal.rpow_inv_rpow hα₀.ne'] -@[deprecated (since := "2026-01-24")] -alias preimage_toSnowflaking_emetricClosedBall := preimage_toSnowflaking_closedEBall - @[simp] theorem image_ofSnowflaking_closedEBall (x : Snowflaking X α hα₀ hα₁) (d : ℝ≥0∞) : ofSnowflaking '' Metric.closedEBall x d = Metric.closedEBall x.ofSnowflaking (d ^ α⁻¹) := by rw [image_ofSnowflaking_eq_preimage, preimage_toSnowflaking_closedEBall] -@[deprecated (since := "2026-01-24")] -alias image_ofSnowflaking_emetricClosedBall := image_ofSnowflaking_closedEBall - @[simp] theorem ediam_image_ofSnowflaking (s : Set (Snowflaking X α hα₀ hα₁)) : ediam (ofSnowflaking '' s) = ediam s ^ α⁻¹ := by diff --git a/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean b/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean index de806dfeab2a6e..90a2ca01671146 100644 --- a/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean +++ b/Mathlib/Topology/MetricSpace/ThickenedIndicator.lean @@ -118,9 +118,6 @@ lemma thickenedIndicatorAux_mono_infEDist (δ : ℝ) {E : Set α} {x y : α} · rw [tsub_eq_zero_of_le hle, tsub_eq_zero_of_le] exact hle.trans (by gcongr) -@[deprecated (since := "2026-01-08")] -alias thickenedIndicatorAux_mono_infEdist := thickenedIndicatorAux_mono_infEDist - /-- As the thickening radius δ tends to 0, the δ-thickened indicator of a set E (in α) tends pointwise (i.e., w.r.t. the product topology on `α → ℝ≥0∞`) to the indicator function of the closure of E. @@ -237,9 +234,6 @@ lemma thickenedIndicator_mono_infEDist {δ : ℝ} (δ_pos : 0 < δ) {E : Set α} · finiteness · exact thickenedIndicatorAux_mono_infEDist δ h -@[deprecated (since := "2026-01-08")] -alias thickenedIndicator_mono_infEdist := thickenedIndicator_mono_infEDist - /-- As the thickening radius δ tends to 0, the δ-thickened indicator of a set E (in α) tends pointwise to the indicator function of the closure of E. diff --git a/Mathlib/Topology/MetricSpace/Thickening.lean b/Mathlib/Topology/MetricSpace/Thickening.lean index 6718f1919ccf03..4bbfe188a390cb 100644 --- a/Mathlib/Topology/MetricSpace/Thickening.lean +++ b/Mathlib/Topology/MetricSpace/Thickening.lean @@ -54,9 +54,6 @@ def thickening (δ : ℝ) (E : Set α) : Set α := theorem mem_thickening_iff_infEDist_lt : x ∈ thickening δ s ↔ infEDist x s < ENNReal.ofReal δ := Iff.rfl -@[deprecated (since := "2026-01-08")] -alias mem_thickening_iff_infEdist_lt := mem_thickening_iff_infEDist_lt - /-- An exterior point of a subset `E` (i.e., a point outside the closure of `E`) is not in the (open) `δ`-thickening of `E` for small enough positive `δ`. -/ lemma eventually_notMem_thickening_of_infEDist_pos {E : Set α} {x : α} (h : x ∉ closure E) : @@ -66,18 +63,11 @@ lemma eventually_notMem_thickening_of_infEDist_pos {E : Set α} {x : α} (h : x simp only [thickening, mem_ofPred_eq, not_lt] exact (ENNReal.ofReal_le_ofReal hδ.le).trans ε_lt.le -@[deprecated (since := "2026-01-08")] -alias eventually_notMem_thickening_of_infEdist_pos := - eventually_notMem_thickening_of_infEDist_pos - /-- The (open) thickening equals the preimage of an open interval under `Metric.infEDist`. -/ theorem thickening_eq_preimage_infEDist (δ : ℝ) (E : Set α) : thickening δ E = (infEDist · E) ⁻¹' Iio (ENNReal.ofReal δ) := rfl -@[deprecated (since := "2026-01-08")] -alias thickening_eq_preimage_infEdist := thickening_eq_preimage_infEDist - /-- The (open) thickening is an open set. -/ theorem isOpen_thickening {δ : ℝ} {E : Set α} : IsOpen (thickening δ E) := Continuous.isOpen_preimage continuous_infEDist _ isOpen_Iio @@ -204,10 +194,6 @@ lemma eventually_notMem_cthickening_of_infEDist_pos {E : Set α} {x : α} (h : x simp only [cthickening, mem_ofPred_eq, not_le] exact ((ofReal_lt_ofReal_iff ε_pos).mpr hδ).trans ε_lt -@[deprecated (since := "2026-01-08")] -alias eventually_notMem_cthickening_of_infEdist_pos := - eventually_notMem_cthickening_of_infEDist_pos - theorem mem_cthickening_of_edist_le (x y : α) (δ : ℝ) (E : Set α) (h : y ∈ E) (h' : edist x y ≤ ENNReal.ofReal δ) : x ∈ cthickening δ E := (infEDist_le_edist_of_mem h).trans h' @@ -222,9 +208,6 @@ theorem cthickening_eq_preimage_infEDist (δ : ℝ) (E : Set α) : cthickening δ E = (fun x => infEDist x E) ⁻¹' Iic (ENNReal.ofReal δ) := rfl -@[deprecated (since := "2026-01-08")] -alias cthickening_eq_preimage_infEdist := cthickening_eq_preimage_infEDist - /-- The closed thickening is a closed set. -/ theorem isClosed_cthickening {δ : ℝ} {E : Set α} : IsClosed (cthickening δ E) := IsClosed.preimage continuous_infEDist isClosed_Iic @@ -609,17 +592,11 @@ theorem infEDist_le_infEDist_cthickening_add : ((ENNReal.add_lt_add_of_lt_of_le (hy.trans_lt ENNReal.ofReal_lt_top).ne hxy hy).trans_eq (tsub_add_cancel_of_le <| le_self_add.trans (lt_tsub_iff_left.1 hxy).le)) -@[deprecated (since := "2026-01-08")] -alias infEdist_le_infEdist_cthickening_add := infEDist_le_infEDist_cthickening_add - /-- For the equality, see `infEDist_thickening`. -/ theorem infEDist_le_infEDist_thickening_add : infEDist x s ≤ infEDist x (thickening δ s) + ENNReal.ofReal δ := infEDist_le_infEDist_cthickening_add.trans <| by gcongr; exact thickening_subset_cthickening .. -@[deprecated (since := "2026-01-08")] -alias infEdist_le_infEdist_thickening_add := infEDist_le_infEDist_thickening_add - /-- For the equality, see `thickening_thickening`. -/ @[simp] theorem thickening_thickening_subset (ε δ : ℝ) (s : Set α) : diff --git a/Mathlib/Topology/Order.lean b/Mathlib/Topology/Order.lean index 4476de9fddcb5c..1526de15ba3e50 100644 --- a/Mathlib/Topology/Order.lean +++ b/Mathlib/Topology/Order.lean @@ -755,20 +755,6 @@ theorem TopologicalSpace.nontrivial_iff_exists_not_inseparable {t : TopologicalS alias ⟨NontrivialTopology.exists_not_inseparable, NontrivialTopology.of_exists_not_inseparable⟩ := TopologicalSpace.nontrivial_iff_exists_not_inseparable -@[deprecated Inseparable.all (since := "2026-01-21")] -theorem inseparable_top (x y : α) : @Inseparable α ⊤ x y := - @Inseparable.all _ ⊤ _ x y - -@[deprecated TopologicalSpace.indiscrete_iff_forall_inseparable (since := "2026-01-21")] -theorem TopologicalSpace.eq_top_iff_forall_inseparable {t : TopologicalSpace α} : - t = ⊤ ↔ (∀ x y : α, Inseparable x y) := by - rw [← TopologicalSpace.indiscrete_iff_forall_inseparable, indiscreteTopology_iff] - -@[deprecated TopologicalSpace.nontrivial_iff_exists_not_inseparable (since := "2026-01-21")] -theorem TopologicalSpace.ne_top_iff_exists_not_inseparable {t : TopologicalSpace α} : - t ≠ ⊤ ↔ ∃ x y : α, ¬Inseparable x y := by - rw [← TopologicalSpace.nontrivial_iff_exists_not_inseparable, nontrivialTopology_iff] - open TopologicalSpace variable {γ : Type*} {f : α → β} {ι : Sort*} diff --git a/Mathlib/Topology/Order/DenselyOrdered.lean b/Mathlib/Topology/Order/DenselyOrdered.lean index 96fae95f47aa9e..e5b987ad5dd5b8 100644 --- a/Mathlib/Topology/Order/DenselyOrdered.lean +++ b/Mathlib/Topology/Order/DenselyOrdered.lean @@ -229,8 +229,6 @@ theorem nhdsWithin_Iio_neBot [NoMinOrder α] {a b : α} (H : a ≤ b) : NeBot ( theorem nhdsLT_neBot_of_exists_lt {b : α} (H : ∃ a, a < b) : NeBot (𝓝[<] b) := nhdsWithin_Iio_neBot' H (le_refl b) -@[deprecated (since := "2026-01-16")] alias nhdsWithin_Iio_self_neBot' := nhdsLT_neBot_of_exists_lt - instance nhdsLT_neBot [NoMinOrder α] (a : α) : NeBot (𝓝[<] a) := nhdsWithin_Iio_neBot (le_refl a) theorem right_nhdsWithin_Ico_neBot {a b : α} (H : a < b) : NeBot (𝓝[Ico a b] b) := diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index d74c618daea080..07c904c7d4cf8a 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -207,15 +207,11 @@ theorem tendsto_atTop_of_monotone {ι α : Type*} [Preorder ι] [TopologicalSpac exact if H : BddAbove (range f) then Or.inr ⟨_, tendsto_atTop_ciSup h_mono H⟩ else Or.inl <| tendsto_atTop_atTop_of_monotone' h_mono H -@[deprecated (since := "2026-01-22")] alias tendsto_of_monotone := tendsto_atTop_of_monotone - theorem tendsto_atTop_of_antitone {ι α : Type*} [Preorder ι] [TopologicalSpace α] [ConditionallyCompleteLinearOrder α] [OrderTopology α] {f : ι → α} (h_mono : Antitone f) : Tendsto f atTop atBot ∨ ∃ l, Tendsto f atTop (𝓝 l) := tendsto_atTop_of_monotone (α := αᵒᵈ) h_mono -@[deprecated (since := "2026-01-22")] alias tendsto_of_antitone := tendsto_atTop_of_antitone - theorem tendsto_atBot_of_monotone {ι α : Type*} [Preorder ι] [TopologicalSpace α] [ConditionallyCompleteLinearOrder α] [OrderTopology α] {f : ι → α} (h_mono : Monotone f) : Tendsto f atBot atBot ∨ ∃ l, Tendsto f atBot (𝓝 l) := diff --git a/Mathlib/Util/MemoFix.lean b/Mathlib/Util/MemoFix.lean deleted file mode 100644 index 679ede647803b2..00000000000000 --- a/Mathlib/Util/MemoFix.lean +++ /dev/null @@ -1,39 +0,0 @@ -/- -Copyright (c) 2022 Gabriel Ebner. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Gabriel Ebner, Edward Ayers --/ -module - -public import Mathlib.Init - -/-! -# Fixpoint function with memoisation - --/ - -variable {α β : Type} - -@[noinline, deprecated "deprecated without replacement" (since := "2026-01-24")] -def injectIntoBaseIO {α : Type} (a : α) : BaseIO α := pure a - -@[deprecated "deprecated without replacement" (since := "2026-01-24")] -unsafe def memoFixImpl [Nonempty β] (f : (α → β) → (α → β)) : α → β := unsafeBaseIO do - let cache : IO.Ref (Lean.PtrMap α β) ← ST.mkRef Lean.mkPtrMap - let rec fix (a) : β := unsafeBaseIO do - if let some b := (← cache.get).find? a then - return b - let b ← injectIntoBaseIO (f fix a) - cache.modify (·.insert a b) - return b - return fix - -/-- Takes the fixpoint of `f` with caching of values that have been seen before. -Hashing makes use of a pointer hash. - -This is useful for implementing tree traversal functions where -subtrees may be referenced in multiple places. --/ -@[implemented_by memoFixImpl, -deprecated "use `MonadCacheT` and `checkCache`" (since := "2026-01-24")] -public opaque memoFix [Nonempty β] (f : (α → β) → (α → β)) : α → β diff --git a/MathlibTest/Linter/Whitespace.lean b/MathlibTest/Linter/Whitespace.lean index e1b1446afcf200..be97626f546f03 100644 --- a/MathlibTest/Linter/Whitespace.lean +++ b/MathlibTest/Linter/Whitespace.lean @@ -5,26 +5,6 @@ import all Mathlib.Tactic.Linter.Whitespace import Mathlib.Tactic.Linter.Style import Mathlib.Init --- Deprecation warnings for the old linter option. -section - -set_option linter.style.setOption true - -/-- -warning: `linter.style.commandStart` has been deprecated: Use `linter.style.whitespace` instead --/ -#guard_msgs in -set_option linter.style.commandStart true - -/-- -warning: `linter.style.commandStart` has been deprecated: Use `linter.style.whitespace` instead --/ -#guard_msgs in -set_option linter.style.commandStart true in -example : Nat := 0 - -end - set_option linter.style.whitespace true /-- From bbf307ae36178e59564000ff173f296ede41e2ef Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 11 Aug 2026 12:14:47 +0000 Subject: [PATCH 1281/1300] feat: define `PositiveContinuousLinearMap` (#42202) This PR defines the continuous version of `PositiveLinearMap` via `extend`ing this structure as well as `ContinuousLinearMap`. In the process, we also create `Is{Add,Zero,SMul}Apply` instances for `PositiveLinearMap`. --- Mathlib.lean | 1 + .../Order/Module/PositiveLinearMap.lean | 43 ++-- .../Module/ContinuousLinearMap/Positive.lean | 241 ++++++++++++++++++ 3 files changed, 269 insertions(+), 16 deletions(-) create mode 100644 Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Positive.lean diff --git a/Mathlib.lean b/Mathlib.lean index f374c965bc3eb4..b2248aa61be484 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7671,6 +7671,7 @@ public import Mathlib.Topology.Algebra.Module.Complement public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Basic public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Idempotent public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.PiProd +public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Positive public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Quotient public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Restrict public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.RestrictScalars diff --git a/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean b/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean index e32de62a976895..7f325c338d40f3 100644 --- a/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean +++ b/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Module.LinearMap.Defs public import Mathlib.Algebra.Order.Hom.Monoid +public import Mathlib.Data.FunLike.Group public import Mathlib.Tactic.ContinuousFunctionalCalculus /-! # Positive linear maps @@ -66,11 +67,12 @@ namespace PositiveLinearMap section general -variable {R E₁ E₂ E₃ : Type*} [Semiring R] +variable {R E₁ E₂ E₃ E₄ : Type*} [Semiring R] [AddCommMonoid E₁] [PartialOrder E₁] [AddCommMonoid E₂] [PartialOrder E₂] [AddCommMonoid E₃] [PartialOrder E₃] - [Module R E₁] [Module R E₂] [Module R E₃] + [AddCommMonoid E₄] [PartialOrder E₄] + [Module R E₁] [Module R E₂] [Module R E₃] [Module R E₄] instance : FunLike (E₁ →ₚ[R] E₂) E₁ E₂ where coe f := f.toFun @@ -105,6 +107,10 @@ def comp (g : E₂ →ₚ[R] E₃) (f : E₁ →ₚ[R] E₂) : E₁ →ₚ[R] E (g.comp f).toOrderHom = g.toOrderHom.comp f.toOrderHom := rfl +lemma comp_assoc (h : E₃ →ₚ[R] E₄) (g : E₂ →ₚ[R] E₃) (f : E₁ →ₚ[R] E₂) : + h.comp (g.comp f) = (h.comp g).comp f := + rfl + @[simp] lemma comp_id (f : E₁ →ₚ[R] E₂) : f.comp (.id R E₁) = f := rfl @[simp] lemma id_comp (f : E₁ →ₚ[R] E₂) : (PositiveLinearMap.id R E₂).comp f = f := rfl @@ -143,9 +149,14 @@ instance : Zero (E₁ →ₚ[R] E₂) where lemma toLinearMap_zero : (0 : E₁ →ₚ[R] E₂).toLinearMap = 0 := rfl -@[simp] -lemma zero_apply (x : E₁) : (0 : E₁ →ₚ[R] E₂) x = 0 := - rfl +instance : IsZeroApply (E₁ →ₚ[R] E₂) E₁ E₂ where + zero_apply _ := rfl + +@[deprecated zero_apply (since := "2026-07-29")] +protected lemma zero_apply (x : E₁) : (0 : E₁ →ₚ[R] E₂) x = 0 := rfl + +@[simp] lemma zero_comp (f : E₁ →ₚ[R] E₂) : (0 : E₂ →ₚ[R] E₃).comp f = 0 := rfl +@[simp] lemma comp_zero (f : E₂ →ₚ[R] E₃) : f.comp (0 : E₁ →ₚ[R] E₂) = 0 := by ext; simp variable [IsOrderedAddMonoid E₂] @@ -158,10 +169,11 @@ lemma toLinearMap_add (f g : E₁ →ₚ[R] E₂) : (f + g).toLinearMap = f.toLinearMap + g.toLinearMap := by rfl -@[simp] -lemma add_apply (f g : E₁ →ₚ[R] E₂) (x : E₁) : - (f + g) x = f x + g x := by - rfl +instance : IsAddApply (E₁ →ₚ[R] E₂) E₁ E₂ where + add_apply _ _ _ := rfl + +@[deprecated add_apply (since := "2026-07-29")] +protected lemma add_apply (f g : E₁ →ₚ[R] E₂) (x : E₁) : (f + g) x = f x + g x := rfl instance : SMul ℕ (E₁ →ₚ[R] E₂) where smul n f := .mk (n • f.toLinearMap) fun x y h ↦ by @@ -174,14 +186,13 @@ lemma toLinearMap_nsmul (f : E₁ →ₚ[R] E₂) (n : ℕ) : (n • f).toLinearMap = n • f.toLinearMap := rfl -@[simp] -lemma nsmul_apply (f : E₁ →ₚ[R] E₂) (n : ℕ) (x : E₁) : - (n • f) x = n • (f x) := - rfl +instance : IsSMulApply ℕ (E₁ →ₚ[R] E₂) E₁ E₂ where + smul_apply _ _ _ := rfl + +@[deprecated smul_apply (since := "2026-07-29")] +protected lemma nsmul_apply (f : E₁ →ₚ[R] E₂) (n : ℕ) (x : E₁) : (n • f) x = n • f x := rfl -instance : AddCommMonoid (E₁ →ₚ[R] E₂) := - toLinearMap_injective.addCommMonoid _ toLinearMap_zero toLinearMap_add - toLinearMap_nsmul +instance : AddCommMonoid (E₁ →ₚ[R] E₂) := fast_instance% FunLike.addCommMonoid end general diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Positive.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Positive.lean new file mode 100644 index 00000000000000..da3f2c7514b1ba --- /dev/null +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Positive.lean @@ -0,0 +1,241 @@ +/- +Copyright (c) 2026 Jireh Loreaux. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jireh Loreaux +-/ +module + +public import Mathlib.Algebra.Order.Module.PositiveLinearMap +public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Basic + +/-! # Positive continuous linear maps + +This file contains the continuous version of `PositiveLinearMap`. While positive linear maps between +C⋆-algebras are automatically continuous (see `PositiveLinearMap.exists_norm_apply_le` which leads +to an instance of `ContinuousLinearMapClass`) there are other situations (e.g., in the theory of +W⋆-algebras) in which this does not hold and yet we wish to restrict to consider only *continuous* +positive linear maps. + +## Implementation notes + +We do not define `PositiveContinuousLinearMapClass` to avoid adding a class that mixes order and +algebra. One can achieve the same effect by using a combination of `ContinuousLinearMapClass` and +`OrderHomClass`. + +-/ + +@[expose] public section + +/-- A `PositiveContinuousLinearMap` is a linear map which is both an order homomorphism and +continuous. This comes equipped with the notation `E₁ →P[R] E₂`. -/ +structure PositiveContinuousLinearMap (R E₁ E₂ : Type*) [Semiring R] + [AddCommMonoid E₁] [PartialOrder E₁] [TopologicalSpace E₁] + [AddCommMonoid E₂] [PartialOrder E₂] [TopologicalSpace E₂] + [Module R E₁] [Module R E₂] extends E₁ →ₚ[R] E₂, E₁ →L[R] E₂ + +/-- Notation for a `PositiveContinuousLinearMap`. -/ +notation:25 E " →P[" R:25 "] " F:0 => PositiveContinuousLinearMap R E F + +/-- The `ContinuousLinearMap` underlying a `PositiveContinuousLinearMap`. -/ +add_decl_doc PositiveContinuousLinearMap.toContinuousLinearMap +/-- The `PositiveLinearMap` underlying a `PositiveContinuousLinearMap`. -/ +add_decl_doc PositiveContinuousLinearMap.toPositiveLinearMap + +namespace PositiveContinuousLinearMap + +section General + +variable {R E₁ E₂ E₃ E₄ : Type*} [Semiring R] + [AddCommMonoid E₁] [PartialOrder E₁] [AddCommMonoid E₂] [PartialOrder E₂] + [Module R E₁] [Module R E₂] [TopologicalSpace E₁] [TopologicalSpace E₂] + +instance : FunLike (E₁ →P[R] E₂) E₁ E₂ where + coe f := f.toFun + coe_injective f g h := by cases f; cases g; congr; exact DFunLike.coe_injective h + +instance : ContinuousLinearMapClass (E₁ →P[R] E₂) R E₁ E₂ where + map_add f := map_add f.toLinearMap + map_smulₛₗ f := f.toLinearMap.map_smul' + map_continuous f := f.cont + +instance : OrderHomClass (E₁ →P[R] E₂) E₁ E₂ where + map_rel f _ _ h := f.monotone' h + +initialize_simps_projections PositiveContinuousLinearMap + (toFun → apply, as_prefix toPositiveLinearMap) + +@[ext] +lemma ext {f g : E₁ →P[R] E₂} (h : ∀ x, f x = g x) : f = g := + DFunLike.ext f g h + +@[simp] +lemma map_smul_of_tower {S : Type*} [SMul S E₁] [SMul S E₂] + [LinearMap.CompatibleSMul E₁ E₂ S R] (f : E₁ →P[R] E₂) (c : S) (x : E₁) : + f (c • x) = c • f x := LinearMapClass.map_smul_of_tower f _ _ + +-- We add the more specific lemma here purely for the aesop tag. +@[aesop safe apply (rule_sets := [CStarAlgebra])] +protected lemma map_nonneg (f : E₁ →P[R] E₂) {x : E₁} (hx : 0 ≤ x) : 0 ≤ f x := + map_nonneg f hx + +section ofClass + +variable {F : Type*} [FunLike F E₁ E₂] [ContinuousLinearMapClass F R E₁ E₂] [OrderHomClass F E₁ E₂] + +/-- Reinterpret an element of a type of positive continuous linear maps as +a positive continuous linear map. -/ +def ofClass (f : F) : E₁ →P[R] E₂ where + toPositiveLinearMap := .ofClass f + cont := map_continuous f + +@[simp] +lemma coe_ofClass (f : F) : ⇑(ofClass f) = f := rfl + +end ofClass + +instance : Coe (E₁ →P[R] E₂) (E₁ →L[R] E₂) := ⟨toContinuousLinearMap⟩ +instance : Coe (E₁ →P[R] E₂) (E₁ →ₚ[R] E₂) := ⟨toPositiveLinearMap⟩ + +@[simp] +lemma coe_toPositiveLinearMap (f : E₁ →P[R] E₂) : + (f.toPositiveLinearMap : E₁ → E₂) = f := + rfl + +@[simp] +lemma coe_toContinuousLinearMap (f : E₁ →P[R] E₂) : + (f.toContinuousLinearMap : E₁ → E₂) = f := + rfl + +lemma toPositiveLinearMap_injective : + Function.Injective ((↑) : (E₁ →P[R] E₂) → (E₁ →ₚ[R] E₂)) := + fun _ _ h ↦ by ext x; congrm($h x) + +@[simp] +lemma toPositiveLinearMap_inj (f g : E₁ →P[R] E₂) : + f.toPositiveLinearMap = g.toPositiveLinearMap ↔ f = g := + toPositiveLinearMap_injective.eq_iff + +lemma toContinuousLinearMap_injective : + Function.Injective ((↑) : (E₁ →P[R] E₂) → (E₁ →L[R] E₂)) := + fun _ _ h ↦ by ext x; congrm($h x) + +-- not marked `@[simp]` because `simp` can already prove it. +lemma toContinuousLinearMap_inj (f g : E₁ →P[R] E₂) : + f.toContinuousLinearMap = g.toContinuousLinearMap ↔ f = g := + toContinuousLinearMap_injective.eq_iff + +instance : Zero (E₁ →P[R] E₂) where + zero := .mk (0 : E₁ →ₚ[R] E₂) <| by fun_prop + +@[simp] +lemma toPositiveLinearMap_zero : (0 : E₁ →P[R] E₂).toPositiveLinearMap = 0 := + rfl + +@[simp] +lemma toContinuousLinearMap_zero : (0 : E₁ →P[R] E₂).toContinuousLinearMap = 0 := + rfl + +instance : IsZeroApply (E₁ →P[R] E₂) E₁ E₂ where + zero_apply _ := rfl + +variable (R E₁) in +/-- The identity as a positive continuous linear map. -/ +@[simps! apply toPositiveLinearMap] protected def id : E₁ →P[R] E₁ where + toPositiveLinearMap := .id R E₁ + cont := continuous_id + +@[simp] lemma toContinuousLinearMap_id : + (PositiveContinuousLinearMap.id R E₁).toContinuousLinearMap = .id R E₁ := rfl + +section Comp + +variable [AddCommMonoid E₃] [PartialOrder E₃] [Module R E₃] [TopologicalSpace E₃] +variable [AddCommMonoid E₄] [PartialOrder E₄] [Module R E₄] [TopologicalSpace E₄] + +/-- Composition of positive continuous linear maps. -/ +@[simps! apply toPositiveLinearMap] +def comp (g : E₂ →P[R] E₃) (f : E₁ →P[R] E₂) : E₁ →P[R] E₃ where + toPositiveLinearMap := g.toPositiveLinearMap.comp f.toPositiveLinearMap + cont := g.cont.comp f.cont + +@[simp] +lemma toContinuousLinearMap_comp (g : E₂ →P[R] E₃) (f : E₁ →P[R] E₂) : + (g.comp f).toContinuousLinearMap = g.toContinuousLinearMap.comp f.toContinuousLinearMap := + rfl + +lemma comp_assoc (h : E₃ →P[R] E₄) (g : E₂ →P[R] E₃) (f : E₁ →P[R] E₂) : + h.comp (g.comp f) = (h.comp g).comp f := + rfl + +@[simp] lemma comp_id (f : E₁ →P[R] E₂) : f.comp (.id R E₁) = f := rfl +@[simp] lemma id_comp (f : E₁ →P[R] E₂) : (PositiveContinuousLinearMap.id R E₂).comp f = f := rfl +@[simp] lemma zero_comp (f : E₁ →P[R] E₂) : (0 : E₂ →P[R] E₃).comp f = 0 := rfl +@[simp] lemma comp_zero (f : E₂ →P[R] E₃) : f.comp (0 : E₁ →P[R] E₂) = 0 := by ext; simp + +end Comp + +variable [IsOrderedAddMonoid E₂] [ContinuousAdd E₂] + +instance : Add (E₁ →P[R] E₂) where + add f g := .mk (f.toPositiveLinearMap + g.toPositiveLinearMap) <| + show Continuous (fun x ↦ f x + g x) by fun_prop + +@[simp] +lemma toPositiveLinearMap_add (f g : E₁ →P[R] E₂) : + (f + g).toPositiveLinearMap = f.toPositiveLinearMap + g.toPositiveLinearMap := by + rfl + +@[simp] +lemma toContinuousLinearMap_add (f g : E₁ →P[R] E₂) : + (f + g).toContinuousLinearMap = f.toContinuousLinearMap + g.toContinuousLinearMap := by + rfl + +instance : IsAddApply (E₁ →P[R] E₂) E₁ E₂ where + add_apply _ _ _ := rfl + +instance : SMul ℕ (E₁ →P[R] E₂) where + smul n f := .mk (n • f.toPositiveLinearMap) <| + show Continuous (fun x ↦ n • f x) by fun_prop + +@[simp] +lemma toPositiveLinearMap_nsmul (f : E₁ →P[R] E₂) (n : ℕ) : + (n • f).toPositiveLinearMap = n • f.toPositiveLinearMap := + rfl + +@[simp] +lemma toContinuousLinearMap_nsmul (f : E₁ →P[R] E₂) (n : ℕ) : + (n • f).toContinuousLinearMap = n • f.toContinuousLinearMap := + rfl + +instance : IsSMulApply ℕ (E₁ →P[R] E₂) E₁ E₂ where + smul_apply _ _ _ := rfl + +instance : AddCommMonoid (E₁ →P[R] E₂) := fast_instance% FunLike.addCommMonoid + +end General + +section AddGroup + +variable {R E₁ E₂ : Type*} [Semiring R] + [AddCommGroup E₁] [PartialOrder E₁] [IsOrderedAddMonoid E₁] [TopologicalSpace E₁] + [AddCommGroup E₂] [PartialOrder E₂] [IsOrderedAddMonoid E₂] [TopologicalSpace E₂] + [Module R E₁] [Module R E₂] + +/-- Define a positive continuous linear map from a continuous linear map that maps +nonnegative elements to nonnegative elements -/ +@[simps toPositiveLinearMap] +def mk₀ (f : E₁ →L[R] E₂) (hf : ∀ x, 0 ≤ x → 0 ≤ f x) : E₁ →P[R] E₂ where + toPositiveLinearMap := .mk₀ f.toLinearMap hf + cont := f.cont + +@[simp] +lemma mk₀_apply (f : E₁ →L[R] E₂) (hf : ∀ x, 0 ≤ x → 0 ≤ f x) (x : E₁) : + mk₀ f hf x = f x := rfl + +@[simp] +lemma toContinuousLinearMap_mk₀ (f : E₁ →L[R] E₂) (hf : ∀ x, 0 ≤ x → 0 ≤ f x) : + (mk₀ f hf).toContinuousLinearMap = f := rfl + +end AddGroup + +end PositiveContinuousLinearMap From 4a9d59a1cca12f30f3ae307e8b4f3244b6b20b5e Mon Sep 17 00:00:00 2001 From: ooovi <79147175+ooovi@users.noreply.github.com> Date: Tue, 11 Aug 2026 13:08:11 +0000 Subject: [PATCH 1282/1300] feat(Geometry/Convex/Cone/Pointed): face lattice of pointed cones (#33664) - Define PointedCone.IsFaceOf, for a pointed cone being a face of another pointed cone. - Prove some basic properties, that faces are extreme sets of their cone, and how they behave under intersection, map and product operations. - Define `Face` by bundling the `IsFaceOf` structure, and show the complete lattice structure on it. - Prove that taking the product of two faces is an order isomorphism. Co-authored-by: Martin Winter Co-authored-by: ovi Co-authored-by: Oliver Nash Co-authored-by: M. Winter <112132359+martinwintermath@users.noreply.github.com> --- Mathlib.lean | 1 + .../Geometry/Convex/Cone/Face/Lattice.lean | 200 ++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 Mathlib/Geometry/Convex/Cone/Face/Lattice.lean diff --git a/Mathlib.lean b/Mathlib.lean index b2248aa61be484..192d721c1868cb 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4592,6 +4592,7 @@ public import Mathlib.Geometry.Convex.Cone.Basic public import Mathlib.Geometry.Convex.Cone.Dual public import Mathlib.Geometry.Convex.Cone.DualFinite public import Mathlib.Geometry.Convex.Cone.Face.Basic +public import Mathlib.Geometry.Convex.Cone.Face.Lattice public import Mathlib.Geometry.Convex.Cone.Pointed public import Mathlib.Geometry.Convex.Cone.Simplicial public import Mathlib.Geometry.Convex.Cone.TensorProduct diff --git a/Mathlib/Geometry/Convex/Cone/Face/Lattice.lean b/Mathlib/Geometry/Convex/Cone/Face/Lattice.lean new file mode 100644 index 00000000000000..b6482512e9efe3 --- /dev/null +++ b/Mathlib/Geometry/Convex/Cone/Face/Lattice.lean @@ -0,0 +1,200 @@ +/- +Copyright (c) 2025 Olivia Röhrig. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Olivia Röhrig +-/ +module + +public import Mathlib.Geometry.Convex.Cone.Face.Basic + +/-! +## Face + +This file defines the concept of a face of a pointed cone. It also defines the complete lattice +structure on the collection of all faces of such a cone. + +## Main definitions + +* `Face C`: the face lattice of `C`. +* `Face.prod`: the product of two faces of pointed cones, together with projections `fst` and `snd`. +* `Face.prodOrderIso`: proves that the face lattices of a product cone is the product of the face + lattices of the individual cones. + +## Implementation notes + +This is separate from faces of general convex sets in affine spaces, since the empty set is not a +face of a convex cone, but of the corresponding convex set. The notion we use here allows a clean +correspondence between the face lattice of convex sets and their homogenization cones. + +-/ + +public section + +namespace PointedCone + +variable {R M N : Type*} + +section Semiring + +variable [Semiring R] [PartialOrder R] [IsOrderedRing R] [AddCommGroup M] [Module R M] + +/-- The face lattice of a pointed cone `C`. -/ +structure Face (C : PointedCone R M) extends PointedCone R M where + isFaceOf : IsFaceOf toSubmodule C + +namespace Face + +variable {C C₁ C₂ : PointedCone R M} {F F₁ F₂ : Face C} + +-- TODO: This whould not be required if Lean allowed us to write: +-- `structure Face (C : PointedCone R M) extends toPointedCone : PointedCone R M where` +-- but as of August 2026 it does not. See: +-- see https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Structure.20extensions.20vs.20abbrev.20difference.20in.20dot.20notation/with/581169071 +/-- Converts a face of a pointed cone into a pointed cone. -/ +@[coe] +abbrev toPointedCone {C : PointedCone R M} (F : Face C) : PointedCone R M := F.toSubmodule + +instance : CoeOut (Face C) (PointedCone R M) := ⟨toPointedCone⟩ + +instance : SetLike (Face C) M where + coe C := C.toPointedCone + coe_injective := SetLike.coe_injective.comp <| by rintro ⟨_, _⟩ ⟨_, _⟩ _; congr + +instance : PartialOrder (Face C) := .ofSetLike (Face C) M + +lemma toPointedCone_le : F ≤ C := F.isFaceOf.le + +@[ext] +theorem ext (h : ∀ x, x ∈ F₁ ↔ x ∈ F₂) : F₁ = F₂ := SetLike.ext h + +@[simp] +theorem toPointedCone_le_toPointedCone {F₁ F₂ : Face C} : + F₁.toPointedCone ≤ F₂.toPointedCone ↔ F₁ ≤ F₂ := .rfl + +@[simp] +theorem toPointedCone_lt_toPointedCone {F₁ F₂ : Face C} : + F₁.toPointedCone < F₂.toPointedCone ↔ F₁ < F₂ := .rfl + +@[simp] +theorem mem_toPointedCone {F : Face C} (x : M) : x ∈ F.toPointedCone ↔ x ∈ F := .rfl + +/-! ### Infimum, supremum and lattice -/ + +/-- The infimum of two faces `F₁`, `F₂` of `C` is the intersection of the cones `F₁` and `F₂`. -/ +instance : Min (Face C) where + min F₁ F₂ := ⟨F₁ ⊓ F₂, F₁.isFaceOf.inf_left F₂.isFaceOf⟩ + +instance : InfSet (Face C) where + sInf S := + { toSubmodule := C ⊓ sInf {s.1 | s ∈ S} + isFaceOf := IsFaceOf.sInf _ (fun F Fs ↦ by obtain ⟨F, Fss, rfl⟩ := Fs; exact F.isFaceOf) } + +instance : SemilatticeInf (Face C) where + inf := min + inf_le_left _ _ _ xi := xi.1 + inf_le_right _ _ _ xi := xi.2 + le_inf _ _ _ h₁₂ h₂₃ _ xi := ⟨h₁₂ xi, h₂₃ xi⟩ + +instance : CompleteSemilatticeInf (Face C) where + __ := instSemilatticeInf + isGLB_sInf S := by + constructor <;> intro f fS + · rw [← toPointedCone_le_toPointedCone] + refine inf_le_of_right_le ?_ + simpa [LE.le] using fun _ xs ↦ xs f fS + · simp only [sInf, Set.mem_ofPred_eq, Set.iInter_exists, Set.biInter_and', + Set.iInter_iInter_eq_right, ← toPointedCone_le_toPointedCone, toPointedCone, le_inf_iff] + refine ⟨f.isFaceOf.le, ?_⟩ + simpa [LE.le] using fun ⦃x⦄ a _ i ↦ (mem_toPointedCone x).mp (fS i a) + +instance : CompleteLattice (Face C) where + top := ⟨C, .refl _⟩ + le_top F := F.toPointedCone_le + __ := completeLatticeOfCompleteSemilatticeInf _ + +instance : Inhabited (Face C) := ⟨⊤⟩ + +end Face + +end Semiring + +section DivisionRing + +namespace Face + +variable [DivisionRing R] [LinearOrder R] [IsOrderedRing R] [AddCommGroup M] [Module R M] + [AddCommGroup N] [Module R N] {C C₁ : PointedCone R M} {C₂ : PointedCone R N} + +/-- The bottom face of `C` is its lineality space. -/ +theorem lineal_eq_bot : ((⊥ : Face C) : PointedCone R M) = C.lineal := by + apply (⊥ : Face C).isFaceOf.lineal_le.antisymm' + exact fun x hx ↦ bot_le (α := Face C) (a := ⟨_, IsFaceOf.lineal C⟩) hx + +/-! ### Product -/ +section Prod + +open Submodule + +/-- The face of `C₁ × C₂` obtained by taking the (submodule) product of faces `F₁ ≤ C₁` and +`F₂ ≤ C₂`. -/ +def prod (F₁ : Face C₁) (F₂ : Face C₂) : Face (C₁.prod C₂) := ⟨_, F₁.isFaceOf.prod F₂.isFaceOf⟩ + +/-- The face of `C₁` obtained by projecting to the first component of a face `F ≤ C₁ × C₂`. -/ +def fst (F : Face (C₁.prod C₂)) : Face C₁ := ⟨_, F.isFaceOf.fst⟩ + +/-- The face of `C₁` obtained by projecting to the second component of a face `F ≤ C₁ × C₂`. -/ +def snd (F : Face (C₁.prod C₂)) : Face C₂ := ⟨_, F.isFaceOf.snd⟩ + +@[simp] +theorem fst_prod (F₁ : Face C₁) (F₂ : Face C₂) : (F₁.prod F₂).fst = F₁ := by + ext + simpa [fst, prod, ← mem_toPointedCone, toPointedCone] using fun _ ↦ ⟨0, F₂.toSubmodule.zero_mem⟩ + +@[simp] +theorem snd_prod (F₁ : Face C₁) (F₂ : Face C₂) : (F₁.prod F₂).snd = F₂ := by + ext + simpa [snd, prod, ← mem_toPointedCone, toPointedCone] using fun _ ↦ ⟨0, F₁.toSubmodule.zero_mem⟩ + +theorem fst_prod_snd (G : Face (C₁.prod C₂)) : G.fst.prod G.snd = G := by + ext x + simp only [prod, fst, snd, ← mem_toPointedCone, toPointedCone, mem_prod, mem_map, + LinearMap.fst_apply, Prod.exists, exists_and_right, exists_eq_right, LinearMap.snd_apply] + constructor + · simp only [and_imp, forall_exists_index] + intro y yn z zm + have := add_mem zm yn + simp only [Prod.mk_add_mk, add_comm] at this + rw [← Prod.mk_add_mk, add_comm] at this + refine G.isFaceOf.mem_of_add_mem_left ?_ ?_ this + · exact ⟨(mem_prod.mp (G.isFaceOf.le yn)).1, (mem_prod.mp (G.isFaceOf.le zm)).2⟩ + · exact ⟨(mem_prod.mp (G.isFaceOf.le zm)).1, (mem_prod.mp (G.isFaceOf.le yn)).2⟩ + · intro h; exact ⟨⟨x.2, h⟩, ⟨x.1, h⟩⟩ + +@[gcongr] +theorem prod_mono {F₁ F₁' : Face C₁} {F₂ F₂' : Face C₂} (h₁ : F₁ ≤ F₁') (h₂ : F₂ ≤ F₂') : + prod F₁ F₂ ≤ prod F₁' F₂' := + Submodule.prod_mono h₁ h₂ + +/-- The face lattice of the product of two cones is isomorphic to the product of their face +lattices. -/ +def prodOrderIso (C : PointedCone R M) (D : PointedCone R N) : + Face (C.prod D) ≃o Face C × Face D where + toFun G := ⟨fst G, snd G⟩ + invFun G := G.1.prod G.2 + left_inv G := by simp [fst_prod_snd] + right_inv G := by simp + map_rel_iff' := by + simp only [Equiv.coe_fn_mk, ge_iff_le, Prod.mk_le_mk] + intro F₁ F₂; constructor <;> intro a + · simpa [fst_prod_snd, toPointedCone_le_toPointedCone] using Face.prod_mono a.1 a.2 + · constructor; all_goals + try simpa only [prod_left, prod_right] + exact fun _ d ↦ Submodule.map_mono a d + +end Prod + +end Face + +end DivisionRing + +end PointedCone From 53144a64cffb7d1db533c69669f7c0899b7920a3 Mon Sep 17 00:00:00 2001 From: Sebastien Gouezel <10818434+sgouezel@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:33:12 +0000 Subject: [PATCH 1283/1300] feat: the variation of a Stieltjes vector measure (#41154) Co-authored-by: sgouezel --- .../VectorMeasure/BoundedVariation.lean | 328 +++++++++++++++++- .../VectorMeasure/Variation/Basic.lean | 7 + 2 files changed, 330 insertions(+), 5 deletions(-) diff --git a/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean b/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean index 505009ea9beeb5..38ce70e9e291e9 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/BoundedVariation.lean @@ -5,12 +5,12 @@ Authors: Sébastien Gouëzel -/ module -public import Mathlib.Analysis.Normed.Group.Defs public import Mathlib.MeasureTheory.Measure.Stieltjes -public import Mathlib.MeasureTheory.VectorMeasure.Basic +public import Mathlib.MeasureTheory.VectorMeasure.Variation.Defs public import Mathlib.Topology.EMetricSpace.VariationOnFromTo import Mathlib.MeasureTheory.VectorMeasure.AddContent +import Mathlib.MeasureTheory.VectorMeasure.Variation.Basic /-! # Vector valued Stieltjes measure associated to a bounded variation function @@ -28,16 +28,21 @@ dominated by a finite measure. For this, we can use the Stieltjes measure associ variation of `f.rightLim`. The extension we get is not exactly the desired vector measure, as we need to tweak things if there is a bot element `a`: the previous vector measure gives to `{a}` the mass `0` instead of the desired `f.rightLim a - f a`, so we add a Dirac mass to correct this defect. + +We also study the variation of this vector measure. We show that it is always finite, and we +control its variation on the different kinds of intervals in terms of the `eVariationOn` of `f` +(for upper bounds) or `f.leftLim` or `f.rightLim` (for exact formulas). -/ @[expose] public section -open Filter Set MeasureTheory MeasurableSpace MeasureTheory +open Filter Set MeasureTheory MeasurableSpace open scoped symmDiff Topology NNReal ENNReal variable {α : Type*} [LinearOrder α] [DenselyOrdered α] [TopologicalSpace α] [OrderTopology α] [SecondCountableTopology α] [CompactIccSpace α] [hα : MeasurableSpace α] [BorelSpace α] - {E : Type*} [NormedAddCommGroup E] [CompleteSpace E] + {E F G : Type*} [NormedAddCommGroup E] [CompleteSpace E] + [NormedAddCommGroup F] [NormedAddCommGroup G] {f : α → E} {a b : α} namespace BoundedVariationOn @@ -131,7 +136,7 @@ lemma vectorMeasure_Ioc (hf : BoundedVariationOn f univ) (h : a ≤ b) : · simp [hx] simp [vectorMeasure, A, B] -lemma vectorMeasure_singleton (hf : BoundedVariationOn f univ) : +@[simp] lemma vectorMeasure_singleton (hf : BoundedVariationOn f univ) : hf.vectorMeasure {a} = f.rightLim a - f.leftLim a := by by_cases ha : IsBot a · have h : ∃ x, IsBot x := ⟨a, ha⟩ @@ -270,4 +275,317 @@ theorem vectorMeasure_univ (hf : BoundedVariationOn f univ) : measurableSet_Ici, hf.vectorMeasure_Iio, hf.vectorMeasure_Ici] abel +open scoped Classical in +/-- Auxiliary measure, which will be proved to coincide with the variation of the vector measure +associated to the bounded variation function `f`. Do not use: use instead the properties +of `hf.vectorMeasure.variation` which are deduced from this equality. -/ +private noncomputable def variationAux (hf : BoundedVariationOn f univ) : Measure α := + hf.measureAux + + (if h : ∃ x, IsBot x then ‖f.rightLim h.choose - f h.choose‖₊ • Measure.dirac h.choose else 0) + +private instance (hf : BoundedVariationOn f univ) : IsFiniteMeasure hf.variationAux := by + classical + have : IsFiniteMeasure (if h : ∃ x, IsBot x then ‖Function.rightLim f h.choose - f h.choose‖₊ • + Measure.dirac h.choose else 0) := by split_ifs <;> infer_instance + exact isFiniteMeasureAdd + +open VectorMeasure + +private lemma variation_vectorMeasure_le_variationAux (hf : BoundedVariationOn f univ) : + hf.vectorMeasure.variation ≤ hf.variationAux := by + apply variation_le_of_forall_enorm_le (fun s hs ↦ ?_) + simp only [vectorMeasure, add_apply, variationAux, Measure.coe_add, Pi.add_apply] + grw [enorm_add_le] + gcongr + · apply hf.exists_vectorMeasure_le_measureAux.choose_spec.2.2 + · split_ifs with h + · by_cases hx : h.choose ∈ s <;> simp [hx, hs] + · simp + +private lemma variationAux_Ioc_le (hf : BoundedVariationOn f univ) {a b : α} (h : a ≤ b) : + hf.variationAux (Ioc a b) ≤ eVariationOn f.rightLim (Ioc a b) := by + classical + have : (if h : ∃ x, IsBot x then ‖Function.rightLim f h.choose - f h.choose‖₊ • + Measure.dirac h.choose else 0) (Ioc a b) = 0 := by + split_ifs with h + · simp [not_lt.mpr (h.choose_spec a)] + · simp + have hα : Nonempty α := ⟨a⟩ + simp only [variationAux, measureAux, hα, ↓reduceDIte, stieltjesFunctionRightLim, Measure.coe_add, + Pi.add_apply, StieltjesFunction.measure_Ioc, this, add_zero] + rw [← variationOnFromTo.add hf.rightLim.locallyBoundedVariationOn (mem_univ hα.some) (mem_univ a) + (mem_univ b), add_sub_cancel_left, variationOnFromTo.eq_of_le _ _ h, univ_inter, + ENNReal.ofReal_toReal (hf.rightLim.mono (subset_univ _)), + eVariationOn.eVariationOn_Ioc_eq_Icc_of_continuousWithinAt + (continuousWithinAt_rightLim_Ici (hf.tendsto_rightLim a))] + +private lemma eVariationOn_Ioc_le_variation (hf : BoundedVariationOn f univ) {a b : α} : + eVariationOn f.rightLim (Ioc a b) ≤ hf.vectorMeasure.variation (Ioc a b) := by + simp only [eVariationOn, iSup_le_iff, Prod.forall, Subtype.forall, mem_Ioc, and_imp, + edist_eq_enorm_sub] + intro n u u_mono u_mem + calc ∑ i ∈ Finset.range n, ‖Function.rightLim f (u (i + 1)) - Function.rightLim f (u i)‖ₑ + _ ≤ ∑ i ∈ Finset.range n, hf.vectorMeasure.variation (Ioc (u i) (u (i + 1))) := by + gcongr with i + grw [← enorm_measure_le_variation, vectorMeasure_Ioc _ (u_mono (by grind))] + _ = hf.vectorMeasure.variation (⋃ i ∈ Finset.range n, Ioc (u i) (u (i + 1))) := by + rw [measure_biUnion_finset ?_ (fun i hi ↦ measurableSet_Ioc)] + rintro i - j - hij + simp [Function.onFun] + grind [Monotone] + _ ≤ hf.vectorMeasure.variation (Ioc a b) := measure_mono (by simp; grind) + +private lemma variationAux_Ioc (hf : BoundedVariationOn f univ) {a b : α} (h : a ≤ b) : + hf.variationAux (Ioc a b) = hf.vectorMeasure.variation (Ioc a b) := + le_antisymm (by grw [variationAux_Ioc_le hf h, eVariationOn_Ioc_le_variation hf]) + (variation_vectorMeasure_le_variationAux _ _) + +lemma variation_vectorMeasure_Ioc (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ioc a b) = eVariationOn f.rightLim (Ioc a b) := by + rcases le_or_gt a b with h | h + · exact le_antisymm (by grw [← variationAux_Ioc hf h, variationAux_Ioc_le hf h]) + (eVariationOn_Ioc_le_variation hf) + · have : Ioc a b = ∅ := by grind + simp [this] + +lemma variation_vectorMeasure_singleton (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation {a} = ‖f.rightLim a - f.leftLim a‖ₑ := by + simp + +private lemma variationAux_singleton (hf : BoundedVariationOn f univ) {a : α} : + hf.variationAux {a} = hf.vectorMeasure.variation {a} := by + classical + have hα : Nonempty α := ⟨a⟩ + simp only [variationAux, Measure.coe_add, Pi.add_apply, variation_vectorMeasure_singleton] + by_cases ha : IsBot a + · have hx : ∃ x, IsBot x := ⟨a, ha⟩ + have A : hx.choose = a := le_antisymm (hx.choose_spec _) (ha _) + suffices hf.measureAux {a} = 0 by simpa [hx, A, leftLim_eq_of_isBot ha, ← enorm_eq_nnnorm] + simp [measureAux, hα, leftLim_eq_of_isBot ha] + have : (𝓝[<] a).NeBot := nhdsLT_neBot_of_exists_lt (by simpa [IsBot] using ha) + have : (if h : ∃ x, IsBot x then ‖Function.rightLim f h.choose - f h.choose‖₊ • + Measure.dirac h.choose else 0) {a} = 0 := by + split_ifs with h + · have : h.choose ≠ a := by grind + simp [this] + · simp + simp [measureAux, hα, this, variationOnFromTo.leftLim_eq hf.rightLim, dist_eq_norm_sub, + leftLim_rightLim (hf.tendsto_leftLim _), stieltjesFunctionRightLim] + +private lemma variationAux_eq_variation_vectorMeasure (hf : BoundedVariationOn f univ) : + hf.variationAux = hf.vectorMeasure.variation := by + apply Measure.ext_of_Icc _ _ (fun a b hab ↦ ?_) + rw [← Icc_union_Ioc_eq_Icc le_rfl hab, measure_union (by grind) measurableSet_Ioc, + measure_union (by grind) measurableSet_Ioc] + simp [variationAux_singleton hf, variationAux_Ioc hf hab] + +instance (hf : BoundedVariationOn f univ) : IsFiniteMeasure hf.vectorMeasure.variation := by + rw [← variationAux_eq_variation_vectorMeasure hf] + infer_instance + +lemma variation_vectorMeasure_Ioo_right + (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ioo a b) = eVariationOn f.rightLim (Ioo a b) := by + rcases le_or_gt b a with hab | hab + · simp [hab] + have : (𝓝[<] b).NeBot := nhdsLT_neBot_of_exists_lt ⟨a, hab⟩ + have A : hf.vectorMeasure.variation (Ioc a b) = eVariationOn f.rightLim (Ioc a b) := + variation_vectorMeasure_Ioc _ + have B : eVariationOn f.rightLim (Ioc a b) = eVariationOn f.rightLim (Ioo a b) + + edist (f.rightLim b) (f.leftLim b) := by + rw [show Ioc a b = Ioc a b ∩ Iic b by grind, + eVariationOn.eVariationOn_on_inter_Iic_eq_Iio_add_edist (l := f.leftLim b), + show Ioc a b ∩ Iio b = Ioo a b by grind] + · have : 𝓝[Ioc a b ∩ Iio b] b = 𝓝[<] b := nhdsWithin_inter_of_mem (Ioc_mem_nhdsLT hab) + rwa [this] + · grind + · rw [← leftLim_rightLim (hf.tendsto_leftLim _)] + apply (hf.rightLim.tendsto_leftLim b).mono_left + exact nhdsWithin_mono _ inter_subset_right + have C : hf.vectorMeasure.variation (Ioc a b) = + hf.vectorMeasure.variation (Ioo a b) + ‖f.rightLim b - f.leftLim b‖ₑ := by + rw [show Ioc a b = Ioo a b ∪ {b} by grind, measure_union (by grind) + (measurableSet_singleton _), variation_vectorMeasure_singleton] + rwa [B, C, edist_eq_enorm_sub, ENNReal.add_left_inj (by simp)] at A + +lemma variation_vectorMeasure_Ioo_left + (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ioo a b) = eVariationOn f.leftLim (Ioo a b) := by + rw [variation_vectorMeasure_Ioo_right] + apply le_antisymm + · have : eVariationOn f.rightLim (Ioo a b) = eVariationOn f.leftLim.rightLim (Ioo a b) := by + apply eVariationOn.congr + intro x hx + have : (𝓝[>] x).NeBot := nhdsGT_neBot_of_exists_gt ⟨b, hx.2⟩ + exact (rightLim_leftLim (hf.tendsto_rightLim _)).symm + rw [this] + exact eVariationOn.eVariationOn_rightLim_le isOpen_Ioo + · have : eVariationOn f.leftLim (Ioo a b) = eVariationOn f.rightLim.leftLim (Ioo a b) := by + apply eVariationOn.congr + intro x hx + have : (𝓝[<] x).NeBot := nhdsLT_neBot_of_exists_lt ⟨a, hx.1⟩ + exact (leftLim_rightLim (hf.tendsto_leftLim _)).symm + rw [this] + exact eVariationOn.eVariationOn_leftLim_le isOpen_Ioo + +lemma variation_vectorMeasure_Ico (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ico a b) = eVariationOn f.leftLim (Ico a b) := by + rcases le_or_gt b a with hab | hab + · simp [hab] + have : (𝓝[>] a).NeBot := nhdsGT_neBot_of_exists_gt ⟨b, hab⟩ + have A : eVariationOn f.leftLim (Ico a b) = eVariationOn f.leftLim (Ioo a b) + + edist (f.rightLim a) (f.leftLim a) := by + rw [show Ico a b = Ico a b ∩ Ici a by grind, + eVariationOn.eVariationOn_on_inter_Ici_eq_Ioi_add_edist (l := f.rightLim a), + show Ico a b ∩ Ioi a = Ioo a b by grind, edist_comm] + · have : 𝓝[Ico a b ∩ Ioi a] a = 𝓝[>] a := nhdsWithin_inter_of_mem (Ico_mem_nhdsGT hab) + rwa [this] + · grind + · rw [← rightLim_leftLim (hf.tendsto_rightLim _)] + apply (hf.leftLim.tendsto_rightLim a).mono_left + exact nhdsWithin_mono _ inter_subset_right + have B : hf.vectorMeasure.variation (Ico a b) = + hf.vectorMeasure.variation (Ioo a b) + ‖f.rightLim a - f.leftLim a‖ₑ := by + rw [show Ico a b = Ioo a b ∪ {a} by grind, measure_union (by grind) + (measurableSet_singleton _), variation_vectorMeasure_singleton] + rw [A, B, edist_eq_enorm_sub, variation_vectorMeasure_Ioo_left] + +lemma variation_vectorMeasure_Ioi (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation (Ioi a) = eVariationOn f.rightLim (Ioi a) := by + by_cases hb : ∃ (b : α), IsTop b + · rcases hb with ⟨b, hb⟩ + rw [show Ioi a = Ioc a b by grind [IsTop], variation_vectorMeasure_Ioc] + apply le_antisymm + · have : Nonempty α := ⟨a⟩ + obtain ⟨u, u_mono, hu⟩ : ∃ u, Monotone u ∧ Tendsto u atTop atTop := + Filter.exists_seq_monotone_tendsto_atTop_atTop α + have A : Tendsto (fun n ↦ hf.vectorMeasure.variation (Ioc a (u n))) atTop + (𝓝 (hf.vectorMeasure.variation (Ioi a))) := by + have : Ioi a = ⋃ n, Ioc a (u n) := by + apply le_antisymm ?_ (by simp [Ioc_subset_Ioi_self]) + intro x (hx : a < x) + simpa [hx] using (hu.eventually (Ici_mem_atTop x)).exists + rw [this] + exact tendsto_measure_iUnion_atTop (fun i j hij x hx ↦ by grind [Monotone]) + apply le_of_tendsto A + filter_upwards with n + grw [variation_vectorMeasure_Ioc, eVariationOn.mono] + grind + · simp only [eVariationOn, iSup_le_iff, Prod.forall, Subtype.forall, mem_Ioi, and_imp] + intro n u u_mono hu + obtain ⟨b, hb⟩ : ∃ b, u n < b := by + simp only [IsTop, not_exists, not_forall, not_le] at hb + exact hb (u n) + apply (eVariationOn.sum_le_of_monotoneOn_Iic (s := Ioo a b) (u_mono.monotoneOn _) + (by grind [Monotone])).trans + rw [← variation_vectorMeasure_Ioo_right hf] + exact measure_mono Ioo_subset_Ioi_self + +lemma variation_vectorMeasure_Iio (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation (Iio a) = eVariationOn f.leftLim (Iio a) := by + by_cases hb : ∃ (b : α), IsBot b + · rcases hb with ⟨b, hb⟩ + rw [show Iio a = Ico b a by grind [IsBot], variation_vectorMeasure_Ico] + apply le_antisymm + · have : Nonempty α := ⟨a⟩ + obtain ⟨u, u_mono, hu⟩ : ∃ u, Antitone u ∧ Tendsto u atTop atBot := + Filter.exists_seq_antitone_tendsto_atTop_atBot α + have A : Tendsto (fun n ↦ hf.vectorMeasure.variation (Ico (u n) a)) atTop + (𝓝 (hf.vectorMeasure.variation (Iio a))) := by + have : Iio a = ⋃ n, Ico (u n) a := by + apply le_antisymm ?_ (by simp [Ico_subset_Iio_self]) + intro x (hx : x < a) + simpa [hx] using (hu.eventually (Iic_mem_atBot x)).exists + rw [this] + exact tendsto_measure_iUnion_atTop (fun i j hij x hx ↦ by grind [Antitone]) + apply le_of_tendsto A + filter_upwards with n + grw [variation_vectorMeasure_Ico, eVariationOn.mono] + grind + · simp only [eVariationOn, iSup_le_iff, Prod.forall, Subtype.forall, mem_Iio, and_imp] + intro n u u_mono hu + obtain ⟨b, hb⟩ : ∃ b, b < u 0 := by + simp only [IsBot, not_exists, not_forall, not_le] at hb + exact hb (u 0) + apply (eVariationOn.sum_le_of_monotoneOn_Iic (s := Ioo b a) (u_mono.monotoneOn _) ?_).trans + · rw [← variation_vectorMeasure_Ioo_left hf] + exact measure_mono Ioo_subset_Iio_self + · intro i hi + have : u 0 ≤ u i := u_mono (Nat.zero_le i) + grind [Monotone] + +lemma variation_vectorMeasure_Ioo_le (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ioo a b) ≤ eVariationOn f (Ioo a b) := by + rw [variation_vectorMeasure_Ioo_right] + exact eVariationOn.eVariationOn_rightLim_le isOpen_Ioo + +lemma variation_vectorMeasure_Ioc_le (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ioc a b) ≤ + eVariationOn f (Ioo a b) + ‖f.rightLim b - f.leftLim b‖ₑ := by + rcases le_or_gt b a with hab | hab + · simp [hab] + grw [show Ioc a b = Ioo a b ∪ {b} by grind, measure_union (by grind) (measurableSet_singleton _), + variation_vectorMeasure_singleton, variation_vectorMeasure_Ioo_le] + +lemma variation_vectorMeasure_Ico_le (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Ico a b) ≤ + eVariationOn f (Ioo a b) + ‖f.rightLim a - f.leftLim a‖ₑ := by + rcases le_or_gt b a with hab | hab + · simp [hab] + grw [show Ico a b = Ioo a b ∪ {a} by grind, measure_union (by grind) (measurableSet_singleton _), + variation_vectorMeasure_singleton, variation_vectorMeasure_Ioo_le] + +lemma variation_vectorMeasure_Icc_le (hf : BoundedVariationOn f univ) {a b : α} : + hf.vectorMeasure.variation (Icc a b) ≤ + eVariationOn f (Ioo a b) + ‖f.rightLim a - f.leftLim a‖ₑ + ‖f.rightLim b - f.leftLim b‖ₑ := by + rcases lt_or_ge b a with hab | hab + · simp [hab] + grw [show Icc a b = Ico a b ∪ {b} by grind, measure_union (by grind) (measurableSet_singleton _), + variation_vectorMeasure_singleton, variation_vectorMeasure_Ico_le] + +lemma variation_vectorMeasure_Ioi_le (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation (Ioi a) ≤ eVariationOn f (Ioi a) := by + grw [variation_vectorMeasure_Ioi, eVariationOn.eVariationOn_rightLim_le isOpen_Ioi] + +lemma variation_vectorMeasure_Ici_le (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation (Ici a) ≤ + eVariationOn f (Ioi a) + ‖f.rightLim a - f.leftLim a‖ₑ := by + grw [show Ici a = Ioi a ∪ {a} by grind, measure_union (by grind) (measurableSet_singleton _), + variation_vectorMeasure_singleton, variation_vectorMeasure_Ioi_le] + +lemma variation_vectorMeasure_Iio_le (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation (Iio a) ≤ eVariationOn f (Iio a) := by + grw [variation_vectorMeasure_Iio, eVariationOn.eVariationOn_leftLim_le isOpen_Iio] + +lemma variation_vectorMeasure_Iic_le (hf : BoundedVariationOn f univ) {a : α} : + hf.vectorMeasure.variation (Iic a) ≤ + eVariationOn f (Iio a) + ‖f.rightLim a - f.leftLim a‖ₑ := by + grw [show Iic a = Iio a ∪ {a} by grind, measure_union (by grind) (measurableSet_singleton _), + variation_vectorMeasure_singleton, variation_vectorMeasure_Iio_le] + +lemma variation_vectorMeasure_univ_le (hf : BoundedVariationOn f univ) : + hf.vectorMeasure.variation univ ≤ eVariationOn f univ := by + rcases isEmpty_or_nonempty α with hα | ⟨⟨a⟩⟩ + · simp [univ_eq_empty_iff.2] + calc hf.vectorMeasure.variation univ + _ = hf.vectorMeasure.variation (Iio a ∪ {a} ∪ Ioi a) := by simp + _ = hf.vectorMeasure.variation (Iio a) + hf.vectorMeasure.variation {a} + + hf.vectorMeasure.variation (Ioi a) := by rw [measure_union (by grind) measurableSet_Ioi, + measure_union (by grind) (measurableSet_singleton _)] + _ ≤ eVariationOn f (Iio a) + (‖f a - f.rightLim a‖ₑ + ‖f a - f.leftLim a‖ₑ) + + eVariationOn f (Ioi a) := by + gcongr + · exact variation_vectorMeasure_Iio_le _ + · rw [variation_vectorMeasure_singleton] + simp only [← edist_eq_enorm_sub] + apply edist_triangle_left + · exact variation_vectorMeasure_Ioi_le _ + _ = (eVariationOn f (Iio a) + ‖f a - f.leftLim a‖ₑ) + + (eVariationOn f (Ioi a) + ‖f a - f.rightLim a‖ₑ) := by abel + _ = eVariationOn f (Iic a) + eVariationOn f (Ici a) := by + rw [← edist_eq_enorm_sub, ← edist_eq_enorm_sub, hf.eVariationOn_Ici_eq_Ioi_add_edist, + hf.eVariationOn_Iic_eq_Iio_add_edist] + _ = eVariationOn f univ := by + rw [← eVariationOn.union (x := a) _ isGreatest_Iic isLeast_Ici, Iic_union_Ici] + end BoundedVariationOn diff --git a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean index 70a8a696c203ed..c8a2bf72636d62 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Variation/Basic.lean @@ -285,6 +285,13 @@ theorem _root_.MeasurableEmbedding.variation_map (hφ : MeasurableEmbedding φ) apply le_trans ?_ (enorm_measure_le_variation _ _) by_cases hx : x ∈ s <;> simp [hs, hx] +@[simp] lemma variation_apply_singleton {x : X} [MeasurableSingletonClass X] : + μ.variation {x} = ‖μ {x}‖ₑ := by + apply le_antisymm ?_ (enorm_measure_le_variation μ {x}) + rw [show ‖μ {x}‖ₑ = (‖μ {x}‖ₑ • Measure.dirac x) {x} by simp] + apply variation_apply_le_of_forall_enorm_le (.singleton x) (fun s hs h's ↦ ?_) + obtain rfl | rfl := s.subset_singleton_iff_eq.1 h's <;> simp + end Basic section NormedAddCommGroup From 9aa55045016ce35bb2379a8fc3d7f268995fb99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:33:15 +0000 Subject: [PATCH 1284/1300] chore(CategoryTheory/Adjunction/AdjointFunctorTheorems): generalize universes (#41244) For theorems involving a category `C : Type u` (with `Category.{v} C`), the smallness assumptions or the existence of limits/colimits are expressed relative to an arbitrary universe `w` (instead of `w = v`), provided the assumption `LocallySmall.{w} C` is added. (This makes this more coherent with the API about locally presentable/accessible categories.) --- .../Adjunction/AdjointFunctorTheorems.lean | 64 +++++++++++-------- .../Comma/StructuredArrow/Small.lean | 9 ++- .../Limits/Constructions/WeaklyInitial.lean | 10 ++- .../Limits/Shapes/WideEqualizers.lean | 24 ++++++- 4 files changed, 71 insertions(+), 36 deletions(-) diff --git a/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean b/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean index 3a66f3169349e0..65bfd8cb0b1aae 100644 --- a/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean +++ b/Mathlib/CategoryTheory/Adjunction/AdjointFunctorTheorems.lean @@ -79,46 +79,52 @@ theorem solutionSetCondition_of_isRightAdjoint [G.IsRightAdjoint] : SolutionSetC /-- The general adjoint functor theorem says that if `G : D ⥤ C` preserves limits and `D` has them, if `G` satisfies the solution set condition then `G` is a right adjoint. -/ -lemma isRightAdjoint_of_preservesLimits_of_solutionSetCondition [HasLimits D] - [PreservesLimitsOfSize.{v₁, v₁} G] (hG : SolutionSetCondition.{v₁} G) : G.IsRightAdjoint := by - refine @isRightAdjointOfStructuredArrowInitials _ _ _ _ G ?_ +lemma isRightAdjoint_of_preservesLimits_of_solutionSetCondition [HasLimitsOfSize.{w, w} D] + [PreservesLimitsOfSize.{w, w} G] (hG : SolutionSetCondition.{w} G) + [LocallySmall.{w} D] : G.IsRightAdjoint := by + apply +allowSynthFailures isRightAdjointOfStructuredArrowInitials intro A - specialize hG A - choose ι B f g using hG - let B' : ι → StructuredArrow A G := fun i => StructuredArrow.mk (f i) + choose ι B f g using hG A + let B' (i : ι) : StructuredArrow A G := StructuredArrow.mk (f i) have hB' : ∀ A' : StructuredArrow A G, ∃ i, Nonempty (B' i ⟶ A') := by intro A' obtain ⟨i, _, t⟩ := g _ A'.hom exact ⟨i, ⟨StructuredArrow.homMk _ t⟩⟩ obtain ⟨T, hT⟩ := has_weakly_initial_of_weakly_initial_set_and_hasProducts hB' - apply hasInitial_of_weakly_initial_and_hasWideEqualizers hT + exact hasInitial_of_weakly_initial_and_hasWideEqualizers hT end GeneralAdjointFunctorTheorem section SpecialAdjointFunctorTheorem -variable {D : Type u'} [Category.{v} D] +variable {D : Type u₁} [Category.{v₁} D] /-- The special adjoint functor theorem: if `G : D ⥤ C` preserves limits and `D` is complete, well-powered and has a small coseparating set, then `G` has a left adjoint. -/ -lemma isRightAdjoint_of_preservesLimits_of_isCoseparating [HasLimits D] [WellPowered.{v} D] - {P : ObjectProperty D} [ObjectProperty.Small.{v} P] - (hP : P.IsCoseparating) (G : D ⥤ C) [PreservesLimits G] : +lemma isRightAdjoint_of_preservesLimits_of_isCoseparating [HasLimitsOfSize.{w, w} D] + [LocallySmall.{w} C] [LocallySmall.{w} D] [WellPowered.{w} D] + {P : ObjectProperty D} [ObjectProperty.Small.{w} P] + (hP : P.IsCoseparating) (G : D ⥤ C) [PreservesLimitsOfSize.{w, w} G] : G.IsRightAdjoint := by - have : ∀ A, HasInitial (StructuredArrow A G) := fun A ↦ - hasInitial_of_isCoseparating.{v} (StructuredArrow.isCoseparating_inverseImage_proj A G hP) + have := hasFiniteLimits_of_hasLimitsOfSize D + have := PreservesLimitsOfSize.preservesFiniteLimits G + have (A : C) : HasInitial (StructuredArrow A G) := + hasInitial_of_isCoseparating (StructuredArrow.isCoseparating_inverseImage_proj A G hP) exact isRightAdjointOfStructuredArrowInitials _ /-- The special adjoint functor theorem: if `F : C ⥤ D` preserves colimits and `C` is cocomplete, well-copowered and has a small separating set, then `F` has a right adjoint. -/ -lemma isLeftAdjoint_of_preservesColimits_of_isSeparating [HasColimits C] [WellPowered.{v} Cᵒᵖ] - {P : ObjectProperty C} [ObjectProperty.Small.{v} P] - (h𝒢 : P.IsSeparating) (F : C ⥤ D) [PreservesColimits F] : +lemma isLeftAdjoint_of_preservesColimits_of_isSeparating [HasColimitsOfSize.{w, w} C] + [LocallySmall.{w} C] [LocallySmall.{w} D] [WellPowered.{w} Cᵒᵖ] + {P : ObjectProperty C} [ObjectProperty.Small.{w} P] + (h𝒢 : P.IsSeparating) (F : C ⥤ D) [PreservesColimitsOfSize.{w, w} F] : F.IsLeftAdjoint := - have : ∀ A, HasTerminal (CostructuredArrow F A) := fun A => - hasTerminal_of_isSeparating.{v} (CostructuredArrow.isSeparating_inverseImage_proj F A h𝒢) + have := hasFiniteColimits_of_hasColimitsOfSize C + have := PreservesColimitsOfSize.preservesFiniteColimits F + have (A : D) : HasTerminal (CostructuredArrow F A) := + hasTerminal_of_isSeparating.{w} (CostructuredArrow.isSeparating_inverseImage_proj F A h𝒢) isLeftAdjoint_of_costructuredArrowTerminals _ end SpecialAdjointFunctorTheorem @@ -127,30 +133,36 @@ namespace Limits /-- A consequence of the special adjoint functor theorem: if `C` is complete, well-powered and has a small coseparating set, then it is cocomplete. -/ -theorem hasColimits_of_hasLimits_of_isCoseparating [HasLimits C] [WellPowered.{v} C] - {P : ObjectProperty C} [ObjectProperty.Small.{v} P] (hP : P.IsCoseparating) : HasColimits C := +theorem hasColimits_of_hasLimits_of_isCoseparating + [HasLimitsOfSize.{w, w} C] [LocallySmall.{w} C] [WellPowered.{w} C] + {P : ObjectProperty C} [ObjectProperty.Small.{w} P] (hP : P.IsCoseparating) : + HasColimitsOfSize.{w, w} C := { has_colimits_of_shape := fun _ _ => hasColimitsOfShape_iff_isRightAdjoint_const.2 (isRightAdjoint_of_preservesLimits_of_isCoseparating hP _) } /-- A consequence of the special adjoint functor theorem: if `C` is cocomplete, well-copowered and has a small separating set, then it is complete. -/ -theorem hasLimits_of_hasColimits_of_isSeparating [HasColimits C] [WellPowered.{v} Cᵒᵖ] - {P : ObjectProperty C} [ObjectProperty.Small.{v} P] (hP : P.IsSeparating) : HasLimits C := +theorem hasLimits_of_hasColimits_of_isSeparating + [HasColimitsOfSize.{w, w} C] [LocallySmall.{w} C] [WellPowered.{w} Cᵒᵖ] + {P : ObjectProperty C} [ObjectProperty.Small.{w} P] (hP : P.IsSeparating) : + HasLimitsOfSize.{w, w} C := { has_limits_of_shape := fun _ _ => hasLimitsOfShape_iff_isLeftAdjoint_const.2 (isLeftAdjoint_of_preservesColimits_of_isSeparating hP _) } /-- A consequence of the special adjoint functor theorem: if `C` is complete, well-powered and has a separator, then it is complete. -/ -theorem hasLimits_of_hasColimits_of_hasSeparator [HasColimits C] [HasSeparator C] - [WellPowered.{v} Cᵒᵖ] : HasLimits C := +theorem hasLimits_of_hasColimits_of_hasSeparator + [HasColimitsOfSize.{w, w} C] [HasSeparator C] [LocallySmall.{w} C] + [WellPowered.{w} Cᵒᵖ] : HasLimitsOfSize.{w, w} C := hasLimits_of_hasColimits_of_isSeparating <| isSeparator_separator C /-- A consequence of the special adjoint functor theorem: if `C` is complete, well-powered and has a coseparator, then it is cocomplete. -/ -theorem hasColimits_of_hasLimits_of_hasCoseparator [HasLimits C] [HasCoseparator C] - [WellPowered.{v} C] : HasColimits C := +theorem hasColimits_of_hasLimits_of_hasCoseparator + [HasLimitsOfSize.{w, w} C] [HasCoseparator C] [LocallySmall.{w} C] + [WellPowered.{w} C] : HasColimitsOfSize.{w, w} C := hasColimits_of_hasLimits_of_isCoseparating <| isCoseparator_coseparator C end Limits diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow/Small.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow/Small.lean index e45fc118ad6ab9..557591b458ee28 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow/Small.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow/Small.lean @@ -6,7 +6,6 @@ Authors: Markus Himmel module public import Mathlib.CategoryTheory.Comma.StructuredArrow.Basic -public import Mathlib.CategoryTheory.EssentiallySmall public import Mathlib.CategoryTheory.ObjectProperty.Small /-! @@ -36,8 +35,8 @@ instance [Small.{w} C] [LocallySmall.{w} D] : Small.{w} (StructuredArrow S T) := exact ⟨⟨X, f⟩, rfl⟩) instance small_inverseImage_proj_of_locallySmall - {P : ObjectProperty C} [ObjectProperty.Small.{v₁} P] [LocallySmall.{v₁} D] : - ObjectProperty.Small.{v₁} (P.inverseImage (proj S T)) := by + {P : ObjectProperty C} [ObjectProperty.Small.{w} P] [LocallySmall.{w} D] : + ObjectProperty.Small.{w} (P.inverseImage (proj S T)) := by suffices P.inverseImage (proj S T) = .ofObj fun f : Σ (G : Subtype P), S ⟶ T.obj G => mk f.2 by rw [this] infer_instance @@ -65,8 +64,8 @@ instance [Small.{w} C] [LocallySmall.{w} D] : Small.{w} (CostructuredArrow S T) exact ⟨⟨X, f⟩, rfl⟩) instance small_inverseImage_proj_of_locallySmall - {P : ObjectProperty C} [ObjectProperty.Small.{v₁} P] [LocallySmall.{v₁} D] : - ObjectProperty.Small.{v₁} (P.inverseImage (proj S T)) := by + {P : ObjectProperty C} [ObjectProperty.Small.{w} P] [LocallySmall.{w} D] : + ObjectProperty.Small.{w} (P.inverseImage (proj S T)) := by suffices P.inverseImage (proj S T) = .ofObj fun f : Σ (G : Subtype P), S.obj G ⟶ T => mk f.2 by rw [this] infer_instance diff --git a/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean b/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean index d65f644094c053..a601e33fa74717 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/WeaklyInitial.lean @@ -22,7 +22,7 @@ These are primarily useful to show the General Adjoint Functor Theorem. public section -universe v u +universe w v u namespace CategoryTheory @@ -34,7 +34,7 @@ variable {C : Type u} [Category.{v} C] If `C` has (small) products and a small weakly initial set of objects, then it has a weakly initial object. -/ -theorem has_weakly_initial_of_weakly_initial_set_and_hasProducts [HasProducts.{v} C] {ι : Type v} +theorem has_weakly_initial_of_weakly_initial_set_and_hasProducts [HasProducts.{w} C] {ι : Type w} {B : ι → C} (hB : ∀ A : C, ∃ i, Nonempty (B i ⟶ A)) : ∃ T : C, ∀ X, Nonempty (T ⟶ X) := ⟨∏ᶜ B, fun X => ⟨Pi.π _ _ ≫ (hB X).choose_spec.some⟩⟩ @@ -43,9 +43,13 @@ theorem has_weakly_initial_of_weakly_initial_set_and_hasProducts [HasProducts.{v The initial object is constructed as the wide equalizer of all endomorphisms on the given weakly initial object. -/ -theorem hasInitial_of_weakly_initial_and_hasWideEqualizers [HasWideEqualizers.{v} C] {T : C} +theorem hasInitial_of_weakly_initial_and_hasWideEqualizers [HasWideEqualizers.{w} C] {T : C} + [LocallySmall.{w} C] (hT : ∀ X, Nonempty (T ⟶ X)) : HasInitial C := by let endos := T ⟶ T + have : HasLimitsOfShape (WalkingParallelFamily endos) C := + hasLimitsOfShape_of_equivalence + (WalkingParallelFamily.equivalenceOfEquiv (equivShrink.{w} endos).symm) let i := wideEqualizer.ι (id : endos → endos) have : Nonempty endos := ⟨𝟙 _⟩ have : ∀ X : C, Unique (wideEqualizer (id : endos → endos) ⟶ X) := by diff --git a/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean index 51580dfccb2e3c..79486dcd9f80b2 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean @@ -5,7 +5,6 @@ Authors: Bhavik Mehta -/ module -public import Mathlib.CategoryTheory.Limits.HasLimits public import Mathlib.CategoryTheory.Limits.Shapes.Equalizers /-! @@ -52,7 +51,7 @@ namespace CategoryTheory.Limits open CategoryTheory -universe w v u u₂ +universe w w' v u u₂ variable {J : Type w} @@ -149,6 +148,27 @@ theorem parallelFamily_obj_one : (parallelFamily f).obj one = Y := theorem parallelFamily_map_left {j : J} : (parallelFamily f).map (line j) = f j := rfl +/-- A bijection between types gives an equivalence between `WalkingParallelFamily` categories. -/ +@[simps] +def WalkingParallelFamily.equivalenceOfEquiv {J' : Type w'} (e : J ≃ J') : + WalkingParallelFamily J ≌ WalkingParallelFamily J' where + functor := + parallelFamily (X := .zero) (Y := .one) (fun j ↦ .line (e j)) + inverse := + parallelFamily (X := .zero) (Y := .one) (fun j ↦ .line (e.symm j)) + unitIso := + NatIso.ofComponents + (fun x ↦ match x with + | zero => Iso.refl _ + | one => Iso.refl _) + (fun f ↦ by induction f <;> cat_disch) + counitIso := + NatIso.ofComponents + (fun x ↦ match x with + | zero => Iso.refl _ + | one => Iso.refl _) + (fun f ↦ by induction f <;> cat_disch) + set_option backward.isDefEq.respectTransparency.types false in /-- Every functor indexing a wide (co)equalizer is naturally isomorphic (actually, equal) to a `parallelFamily` -/ From 5d488cb2c3109ee4877f9f65b1fb32e799553476 Mon Sep 17 00:00:00 2001 From: Felix Pernegger <188575194+felixpernegger@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:44:13 +0000 Subject: [PATCH 1285/1300] refactor: reorganize Topology/EMetricSpace/Defs to generalise basic results (#40510) This PR reorganizes the Topology/EMetricSpace/Defs so that various results that previously only held for `PseudoEMetricSpace` now also hold for `WeakPseudoEMetricSpace` (in particular, `ENNReal`). This is a necessary stepping stone to generalise many definitions and theorems to `WeakPseudoEMetricSpace`. Co-authored-by: Batixx --- Mathlib.lean | 1 + Mathlib/Topology/EMetricSpace/Defs.lean | 398 ++++++++++-------- .../Topology/EMetricSpace/MulOpposite.lean | 46 ++ Mathlib/Topology/EMetricSpace/Weak.lean | 6 +- .../MetricSpace/HausdorffDistance.lean | 2 +- .../Topology/MetricSpace/IsometricSMul.lean | 1 + Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 4 +- 7 files changed, 272 insertions(+), 186 deletions(-) create mode 100644 Mathlib/Topology/EMetricSpace/MulOpposite.lean diff --git a/Mathlib.lean b/Mathlib.lean index 192d721c1868cb..69f1fe5f039fb7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7941,6 +7941,7 @@ public import Mathlib.Topology.EMetricSpace.BoundedVariation public import Mathlib.Topology.EMetricSpace.Defs public import Mathlib.Topology.EMetricSpace.Diam public import Mathlib.Topology.EMetricSpace.Lipschitz +public import Mathlib.Topology.EMetricSpace.MulOpposite public import Mathlib.Topology.EMetricSpace.PairReduction public import Mathlib.Topology.EMetricSpace.Paracompact public import Mathlib.Topology.EMetricSpace.Pi diff --git a/Mathlib/Topology/EMetricSpace/Defs.lean b/Mathlib/Topology/EMetricSpace/Defs.lean index fe647e32634d6d..db285f63e9f168 100644 --- a/Mathlib/Topology/EMetricSpace/Defs.lean +++ b/Mathlib/Topology/EMetricSpace/Defs.lean @@ -1,7 +1,8 @@ /- Copyright (c) 2015 Jeremy Avigad. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Jeremy Avigad, Robert Y. Lewis, Johannes Hölzl, Mario Carneiro, Sébastien Gouëzel +Authors: Jeremy Avigad, Robert Y. Lewis, Johannes Hölzl, Mario Carneiro, Sébastien Gouëzel, + Felix Pernegger -/ module @@ -55,17 +56,21 @@ class EDist (α : Type*) where export EDist (edist) -section +namespace Metric -variable {x y z : α} {ε : ℝ≥0∞} [EDist α] +variable {x y z : α} {ε ε₁ ε₂ : ℝ≥0∞} [EDist α] -/-- `EMetric.ball x ε` is the set of all points `y` with `edist y x < ε` -/ -def Metric.eball (x : α) (ε : ℝ≥0∞) : Set α := +/-- `Metric.eball x ε` is the set of all points `y` with `edist y x < ε` -/ +def eball (x : α) (ε : ℝ≥0∞) : Set α := { y | edist y x < ε } -@[simp] theorem Metric.mem_eball {x y : α} {ε : ℝ≥0∞} : y ∈ eball x ε ↔ edist y x < ε := Iff.rfl +@[simp] theorem mem_eball {x y : α} {ε : ℝ≥0∞} : y ∈ eball x ε ↔ edist y x < ε := Iff.rfl -end +@[gcongr] +theorem eball_subset_eball (h : ε₁ ≤ ε₂) : eball x ε₁ ⊆ eball x ε₂ := fun _y (yx : _ < ε₁) => + lt_of_lt_of_le yx h + +end Metric /-- Creating a uniform space from an extended distance. -/ @[reducible] @@ -128,12 +133,104 @@ protected theorem PseudoEMetricSpace.ext {α : Type*} {m m' : PseudoEMetricSpace congr 1 exact UniformSpace.ext (((show ed = ed' from h) ▸ hU).trans hU'.symm) +variable {x : α} {s t : Set α} + +section + +open Metric + variable [PseudoEMetricSpace α] -export PseudoEMetricSpace (edist_self edist_comm edist_triangle) +/-- Reformulation of the uniform structure in terms of the extended distance -/ +theorem uniformity_pseudoedist : 𝓤 α = ⨅ ε > 0, 𝓟 { p : α × α | edist p.1 p.2 < ε } := + PseudoEMetricSpace.uniformity_edist + +theorem uniformSpace_edist : + ‹PseudoEMetricSpace α›.toUniformSpace = + uniformSpaceOfEDist (α := α) edist PseudoEMetricSpace.edist_self PseudoEMetricSpace.edist_comm + PseudoEMetricSpace.edist_triangle := + UniformSpace.ext uniformity_pseudoedist + +theorem uniformity_basis_edist : + (𝓤 α).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) fun ε => { p : α × α | edist p.1 p.2 < ε } := + (@uniformSpace_edist α _).symm ▸ UniformSpace.hasBasis_ofFun ⟨1, one_pos⟩ _ _ _ _ _ + +theorem Metric.nhds_basis_eball : (𝓝 x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) (Metric.eball x) := + nhds_basis_uniformity uniformity_basis_edist + +/-- Characterization of the elements of the uniformity in terms of the extended distance -/ +theorem mem_uniformity_edist {s : Set (α × α)} : + s ∈ 𝓤 α ↔ ∃ ε > 0, ∀ {a b : α}, edist a b < ε → (a, b) ∈ s := + uniformity_basis_edist.mem_uniformity_iff + +theorem EMetric.nhds_eq : 𝓝 x = ⨅ ε > 0, 𝓟 (Metric.eball x ε) := + nhds_basis_eball.eq_biInf + +theorem EMetric.mem_nhds_iff : s ∈ 𝓝 x ↔ ∃ ε > 0, eball x ε ⊆ s := + nhds_basis_eball.mem_iff + +theorem Metric.nhdsWithin_basis_eball : + (𝓝[s] x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) fun ε => eball x ε ∩ s := + nhdsWithin_hasBasis nhds_basis_eball s + +theorem EMetric.mem_nhdsWithin_iff : s ∈ 𝓝[t] x ↔ ∃ ε > 0, eball x ε ∩ t ⊆ s := + nhdsWithin_basis_eball.mem_iff + +theorem EMetric.isOpen_iff : IsOpen s ↔ ∀ x ∈ s, ∃ ε > 0, eball x ε ⊆ s := by + simp [isOpen_iff_nhds, mem_nhds_iff] + +@[simp] theorem Metric.isOpen_eball {r : ℝ≥0∞} : IsOpen (eball x r) := by + apply EMetric.isOpen_iff.mpr fun y hy ↦ ?_ + refine ⟨r - edist x y, by simp_all [PseudoEMetricSpace.edist_comm], fun a ha ↦ ?_⟩ + simp only [mem_eball, PseudoEMetricSpace.edist_comm y x] at hy ha ⊢ + grw [PseudoEMetricSpace.edist_triangle a y x, PseudoEMetricSpace.edist_comm y x, + ← tsub_add_cancel_of_le hy.le, (ENNReal.add_lt_add_iff_right (LT.lt.ne_top hy)).mpr ha] + +end + +/-- A `WeakPseudoEMetricSpace` is a topological space endowed with a `ℝ≥0∞`-value distance `edist` +which is *almost* an extended pseudometric space: the `edist` is reflexive, commutative and +satisfies the triangle inequality, but the topology on `α` need not *equal* the topology induced +by the `edist`. (It must be at least as fine, and agree with it on eballs of finite radius.) + +This generalises both pseudo extended metric spaces and `ℝ≥0∞` (which have an extended distance, +which does not induce the order topology there). -/ +class WeakPseudoEMetricSpace + (α : Type u) [τ : TopologicalSpace α] : Type u extends EDist α where + edist_self : ∀ x : α, edist x x = 0 + edist_comm : ∀ x y : α, edist x y = edist y x + edist_triangle : ∀ x y z : α, edist x z ≤ edist x y + edist y z + /-- The topology on `α` is at most as fine as the topology generated by the `edist`. -/ + topology_le : + (uniformSpaceOfEDist edist edist_self edist_comm edist_triangle).toTopologicalSpace ≤ τ + /-- The ambient topology on `α` matches the `edist` topology on eballs. -/ + topology_eq_on_restrict : + ∀ (x : α) (r : ℝ≥0∞), IsOpen (Metric.eball x ⊤ ↓∩ Metric.eball x r) + +@[ext] +protected theorem WeakPseudoEMetricSpace.ext + {α : Type*} [TopologicalSpace α] {m m' : WeakPseudoEMetricSpace α} + (h : m.toEDist = m'.toEDist) : m = m' := by + cases m; cases m'; congr + +/-- Every `PseudoEMetricSpace` has a `WeakPseudoEMetricSpace` structure by +using the topology induced by `edist`. -/ +instance PseudoEMetricSpace.toWeakPseudoEMetricSpace (α : Type u) [inst : PseudoEMetricSpace α] : + WeakPseudoEMetricSpace α where + edist_self := edist_self + edist_comm := edist_comm + edist_triangle := edist_triangle + topology_le := by rw [uniformSpace_edist] + topology_eq_on_restrict x r := Metric.isOpen_eball.preimage_val + +export WeakPseudoEMetricSpace (edist_self edist_comm edist_triangle) attribute [simp] edist_self +section + +variable [TopologicalSpace α] [WeakPseudoEMetricSpace α] + /-- Triangle inequality for the extended distance -/ theorem edist_triangle_left (x y z : α) : edist x y ≤ edist z x + edist z y := by rw [edist_comm z]; apply edist_triangle @@ -160,24 +257,6 @@ theorem edist_congr {w x y z : α} (hl : edist w x = 0) (hr : edist y z = 0) : theorem edist_triangle4 (x y z t : α) : edist x t ≤ edist x y + edist y z + edist z t := by grw [edist_triangle _ z, edist_triangle] -/-- Reformulation of the uniform structure in terms of the extended distance -/ -theorem uniformity_pseudoedist : 𝓤 α = ⨅ ε > 0, 𝓟 { p : α × α | edist p.1 p.2 < ε } := - PseudoEMetricSpace.uniformity_edist - -theorem uniformSpace_edist : - ‹PseudoEMetricSpace α›.toUniformSpace = - uniformSpaceOfEDist edist edist_self edist_comm edist_triangle := - UniformSpace.ext uniformity_pseudoedist - -theorem uniformity_basis_edist : - (𝓤 α).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) fun ε => { p : α × α | edist p.1 p.2 < ε } := - (@uniformSpace_edist α _).symm ▸ UniformSpace.hasBasis_ofFun ⟨1, one_pos⟩ _ _ _ _ _ - -/-- Characterization of the elements of the uniformity in terms of the extended distance -/ -theorem mem_uniformity_edist {s : Set (α × α)} : - s ∈ 𝓤 α ↔ ∃ ε > 0, ∀ {a b : α}, edist a b < ε → (a, b) ∈ s := - uniformity_basis_edist.mem_uniformity_iff - /-- Make a `PseudoEMetricSpace` from a metric. Warning: the uniformity and topology included herein are the ones generated by the metric. If the type has a pre-existing topology or uniformity, `PseudoEMetricSpace.ofEDistOfTopology` should be used instead. -/ @@ -198,13 +277,19 @@ theorem EMetric.toUniformSpace_ofEDist {α : Type u} [EDist α] (edist_self : (PseudoEMetricSpace.ofEDist edist edist_self edist_comm edist_triangle).toUniformSpace = (uniformSpaceOfEDist edist edist_self edist_comm edist_triangle) := by rfl +end + +section + +variable [PseudoEMetricSpace α] + /-- Given `f : β → ℝ≥0∞`, if `f` sends `{i | p i}` to a set of positive numbers accumulating to zero, then `f i`-neighborhoods of the diagonal form a basis of `𝓤 α`. For specific bases see `uniformity_basis_edist`, `uniformity_basis_edist'`, `uniformity_basis_edist_nnreal`, and `uniformity_basis_edist_inv_nat`. -/ -protected theorem EMetric.mk_uniformity_basis {β : Type*} {p : β → Prop} {f : β → ℝ≥0∞} - (hf₀ : ∀ x, p x → 0 < f x) (hf : ∀ ε, 0 < ε → ∃ x, p x ∧ f x ≤ ε) : +protected theorem EMetric.mk_uniformity_basis {β : Type*} {p : β → Prop} + {f : β → ℝ≥0∞} (hf₀ : ∀ x, p x → 0 < f x) (hf : ∀ ε, 0 < ε → ∃ x, p x ∧ f x ≤ ε) : (𝓤 α).HasBasis p fun x => { p : α × α | edist p.1 p.2 < f x } := by refine ⟨fun s => uniformity_basis_edist.mem_iff.trans ?_⟩ constructor @@ -291,6 +376,8 @@ theorem uniformContinuous_iff [PseudoEMetricSpace β] {f : α → β} : end EMetric +end + open EMetric /-- Auxiliary function to replace the uniformity on a pseudoemetric space with @@ -320,10 +407,45 @@ abbrev PseudoEMetricSpace.induced {α β} (f : α → β) (m : PseudoEMetricSpac toUniformSpace := UniformSpace.comap f m.toUniformSpace uniformity_edist := (uniformity_basis_edist.comap (Prod.map f f)).eq_biInf +/-- `WeakPseudoEMetricSpace` can be induced backwards. -/ +abbrev WeakPseudoEMetricSpace.IsInducing {α β : Type*} [e : TopologicalSpace α] + [n : TopologicalSpace β] {f : α → β} (hf : IsInducing f) (m : WeakPseudoEMetricSpace β) : + WeakPseudoEMetricSpace α where + edist := fun x y ↦ edist (f x) (f y) + edist_self x := edist_self (f x) + edist_comm x y := edist_comm (f x) (f y) + edist_triangle x y z := edist_triangle (f x) (f y) (f z) + topology_le := by + let hα := PseudoEMetricSpace.ofEDist (fun x y ↦ edist (f x) (f y)) + (fun x ↦ edist_self (f x)) (fun x y ↦ edist_comm (f x) (f y)) + (fun x y z ↦ edist_triangle (f x) (f y) (f z)) + let hβ := PseudoEMetricSpace.ofEDist m.edist edist_self edist_comm edist_triangle + rw [(isInducing_iff f).mp hf] + refine (continuous_le_rng m.topology_le ?_).le_induced + refine @Continuous.mk α β hα.toUniformSpace.toTopologicalSpace + hβ.toUniformSpace.toTopologicalSpace f fun s hs ↦ ?_ + rw [EMetric.isOpen_iff] at hs ⊢ + intro x (hx : f x ∈ s) + obtain ⟨ε, hε, hεs⟩ := hs (f x) hx + exact ⟨ε, hε, fun y hy ↦ hεs hy⟩ + topology_eq_on_restrict x r := by + obtain ⟨u, hu, uy⟩ := m.topology_eq_on_restrict (f x) r + rw [(isInducing_iff f).mp hf] + exact ⟨f ⁻¹' u, isOpen_induced hu, by aesop (add simp [Set.ext_iff])⟩ + +/-- Weak pseudo-emetric space instance on subsets of weak pseudo-emetric spaces -/ +instance {α : Type*} {p : α → Prop} [TopologicalSpace α] [WeakPseudoEMetricSpace α] : + WeakPseudoEMetricSpace (Subtype p) := + WeakPseudoEMetricSpace.IsInducing IsInducing.subtypeVal ‹_› + /-- Pseudoemetric space instance on subsets of pseudoemetric spaces -/ instance {α : Type*} {p : α → Prop} [PseudoEMetricSpace α] : PseudoEMetricSpace (Subtype p) := PseudoEMetricSpace.induced Subtype.val ‹_› +section + +variable [TopologicalSpace α] [WeakPseudoEMetricSpace α] + /-- The extended pseudodistance on a subset of a pseudoemetric space is the restriction of the original pseudodistance, by definition. -/ theorem Subtype.edist_eq {p : α → Prop} (x y : Subtype p) : edist x y = edist (x : α) y := rfl @@ -350,25 +472,14 @@ distance, with a topology defeq to the initial one. -/ toUniformSpace := uniformSpaceOfEDistOfHasBasis d h_self h_comm h_triangle h_basis uniformity_edist := rfl -namespace MulOpposite - -/-- Pseudoemetric space instance on the multiplicative opposite of a pseudoemetric space. -/ -@[to_additive -/-- Pseudoemetric space instance on the additive opposite of a pseudoemetric space. -/] -instance {α : Type*} [PseudoEMetricSpace α] : PseudoEMetricSpace αᵐᵒᵖ := - PseudoEMetricSpace.induced unop ‹_› - -@[to_additive] -theorem edist_unop (x y : αᵐᵒᵖ) : edist (unop x) (unop y) = edist x y := rfl - -@[to_additive] -theorem edist_op (x y : α) : edist (op x) (op y) = edist x y := rfl +end -end MulOpposite +variable {α : Type*} [PseudoEMetricSpace α] section ULift -instance : PseudoEMetricSpace (ULift α) := PseudoEMetricSpace.induced ULift.down ‹_› +instance : PseudoEMetricSpace (ULift α) := + PseudoEMetricSpace.induced ULift.down ‹_› theorem ULift.edist_eq (x y : ULift α) : edist x y = edist x.down y.down := rfl @@ -398,26 +509,29 @@ theorem Prod.edist_eq [PseudoEMetricSpace β] (x y : α × β) : namespace Metric -variable {x y z : α} {ε ε₁ ε₂ : ℝ≥0∞} {s t : Set α} +variable {α : Type*} [TopologicalSpace α] [WeakPseudoEMetricSpace α] {x y z : α} {ε ε₁ ε₂ : ℝ≥0∞} + {s t : Set α} theorem mem_eball' : y ∈ eball x ε ↔ edist x y < ε := by rw [edist_comm, mem_eball] /-- `Metric.closedEBall x ε` is the set of all points `y` with `edist y x ≤ ε` -/ -def closedEBall (x : α) (ε : ℝ≥0∞) := +def closedEBall {α : Type*} [h : EDist α] (x : α) (ε : ℝ≥0∞) := { y | edist y x ≤ ε } -@[simp] theorem mem_closedEBall : y ∈ closedEBall x ε ↔ edist y x ≤ ε := Iff.rfl +@[simp] theorem mem_closedEBall {α : Type*} [EDist α] {x y : α} : + y ∈ closedEBall x ε ↔ edist y x ≤ ε := Iff.rfl theorem mem_closedEBall' : y ∈ closedEBall x ε ↔ edist x y ≤ ε := by rw [edist_comm, mem_closedEBall] @[simp] -theorem closedEBall_top (x : α) : closedEBall x ∞ = univ := +theorem closedEBall_top {α : Type*} [EDist α] (x : α) : closedEBall x ∞ = univ := eq_univ_of_forall fun _ => mem_ofPred.2 le_top -theorem eball_subset_closedEBall : eball x ε ⊆ closedEBall x ε := fun _ h => le_of_lt h.out +theorem eball_subset_closedEBall {α : Type*} [EDist α] {x : α} : + eball x ε ⊆ closedEBall x ε := fun _ h => le_of_lt h.out -theorem pos_of_mem_eball (hy : y ∈ eball x ε) : 0 < ε := +theorem pos_of_mem_eball {α : Type*} [EDist α] {x y : α} (hy : y ∈ eball x ε) : 0 < ε := hy.pos theorem mem_eball_self (h : 0 < ε) : x ∈ eball x ε := by @@ -432,11 +546,8 @@ theorem mem_closedEBall_comm : x ∈ closedEBall y ε ↔ y ∈ closedEBall x ε rw [mem_closedEBall', mem_closedEBall] @[gcongr] -theorem eball_subset_eball (h : ε₁ ≤ ε₂) : eball x ε₁ ⊆ eball x ε₂ := fun _y (yx : _ < ε₁) => - lt_of_lt_of_le yx h - -@[gcongr] -theorem closedEBall_subset_closedEBall (h : ε₁ ≤ ε₂) : closedEBall x ε₁ ⊆ closedEBall x ε₂ := +theorem closedEBall_subset_closedEBall {α : Type*} [EDist α] {x : α} (h : ε₁ ≤ ε₂) : + closedEBall x ε₁ ⊆ closedEBall x ε₂ := fun _y (yx : _ ≤ ε₁) => le_trans yx h theorem eball_disjoint (h : ε₁ + ε₂ ≤ edist x y) : Disjoint (eball x ε₁) (eball y ε₂) := @@ -485,18 +596,15 @@ def edistLtTopSetoid : Setoid α where trans hxy hyz := lt_of_le_of_lt (edist_triangle _ _ _) (ENNReal.add_lt_top.2 ⟨hxy, hyz⟩) } @[simp] -theorem eball_zero : eball x 0 = ∅ := by rw [eball_eq_empty_iff] +theorem eball_zero {α : Type*} [EDist α] {x : α} : eball x 0 = ∅ := by + ext + simp -theorem nhds_basis_eball : (𝓝 x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) (eball x) := - nhds_basis_uniformity uniformity_basis_edist - -theorem nhdsWithin_basis_eball : (𝓝[s] x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) fun ε => eball x ε ∩ s := - nhdsWithin_hasBasis nhds_basis_eball s - -theorem nhds_basis_closedEBall : (𝓝 x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) (closedEBall x) := +theorem nhds_basis_closedEBall {α : Type*} [PseudoEMetricSpace α] {x : α} : + (𝓝 x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) (closedEBall x) := nhds_basis_uniformity uniformity_basis_edist_le -theorem nhdsWithin_basis_closedEBall : +theorem nhdsWithin_basis_closedEBall {α : Type*} [PseudoEMetricSpace α] {s : Set α} {x : α} : (𝓝[s] x).HasBasis (fun ε : ℝ≥0∞ => 0 < ε) fun ε => closedEBall x ε ∩ s := nhdsWithin_hasBasis nhds_basis_closedEBall s @@ -507,18 +615,6 @@ variable {x : α} {ε : ℝ≥0∞} {s t : Set α} open Metric -theorem nhds_eq : 𝓝 x = ⨅ ε > 0, 𝓟 (eball x ε) := - nhds_basis_eball.eq_biInf - -theorem mem_nhds_iff : s ∈ 𝓝 x ↔ ∃ ε > 0, eball x ε ⊆ s := - nhds_basis_eball.mem_iff - -theorem mem_nhdsWithin_iff : s ∈ 𝓝[t] x ↔ ∃ ε > 0, eball x ε ∩ t ⊆ s := - nhdsWithin_basis_eball.mem_iff - -theorem isOpen_iff : IsOpen s ↔ ∀ x ∈ s, ∃ ε > 0, eball x ε ⊆ s := by - simp [isOpen_iff_nhds, mem_nhds_iff] - /-- ε-characterization of the closure in pseudoemetric spaces -/ theorem mem_closure_iff : x ∈ closure s ↔ ∀ ε > 0, ∃ y ∈ s, edist x y < ε := (mem_closure_iff_nhds_basis nhds_basis_eball).trans <| by simp only [mem_eball, edist_comm x] @@ -604,18 +700,17 @@ end EMetric namespace Metric variable {x : α} {ε : ℝ≥0∞} {s t : Set α} -@[simp] theorem isOpen_eball : IsOpen (eball x ε) := - EMetric.isOpen_iff.2 fun _ => exists_eball_subset_eball - theorem isClosed_eball_top : IsClosed (eball x ⊤) := isOpen_compl_iff.1 <| EMetric.isOpen_iff.2 fun _y hy => ⟨⊤, ENNReal.coe_lt_top, fun _z hzy hzx => hy (edistLtTopSetoid.trans (edistLtTopSetoid.symm hzy) hzx)⟩ -theorem eball_mem_nhds (x : α) {ε : ℝ≥0∞} (ε0 : 0 < ε) : eball x ε ∈ 𝓝 x := +variable (x) + +theorem eball_mem_nhds (ε0 : 0 < ε) : eball x ε ∈ 𝓝 x := isOpen_eball.mem_nhds (mem_eball_self ε0) -theorem closedEBall_mem_nhds (x : α) {ε : ℝ≥0∞} (ε0 : 0 < ε) : closedEBall x ε ∈ 𝓝 x := +theorem closedEBall_mem_nhds (ε0 : 0 < ε) : closedEBall x ε ∈ 𝓝 x := mem_of_superset (eball_mem_nhds x ε0) eball_subset_closedEBall theorem eball_prod_same [PseudoEMetricSpace β] (x : α) (y : β) (r : ℝ≥0∞) : @@ -630,25 +725,30 @@ end Metric namespace Subtype +variable {α : Type*} [EDist α] {p : α → Prop} + +instance : EDist (Subtype p) where + edist x y := edist x.val y.val + open Metric @[simp] -theorem preimage_eball {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : +theorem preimage_eball (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val ⁻¹' (eball a.1 r) = eball a r := rfl @[simp] -theorem preimage_closedEBall {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : +theorem preimage_closedEBall (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val ⁻¹' (closedEBall a.1 r) = closedEBall a r := rfl @[simp] -theorem image_eball {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : +theorem image_eball (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val '' (eball a r) = eball a.1 r ∩ {a | p a} := by rw [← preimage_eball, image_preimage_eq_inter_range, range_val_subtype] @[simp] -theorem image_closedEBall {p : α → Prop} (a : {a // p a}) (r : ℝ≥0∞) : +theorem image_closedEBall (a : {a // p a}) (r : ℝ≥0∞) : Subtype.val '' (closedEBall a r) = closedEBall a.1 r ∩ {a | p a} := by rw [← preimage_closedEBall, image_preimage_eq_inter_range, range_val_subtype] @@ -681,9 +781,32 @@ protected theorem EMetricSpace.ext ext1 assumption -variable {γ : Type w} [EMetricSpace γ] -export EMetricSpace (eq_of_edist_eq_zero) +/-- A weak extended metric space extends a `WeakPseudoEMetricSpace` with the condition +`edist x y = 0 ↔ x = y`. -/ +class WeakEMetricSpace + (α : Type u) [TopologicalSpace α] : Type u extends WeakPseudoEMetricSpace α where + eq_of_edist_eq_zero : ∀ {x y : α}, edist x y = 0 → x = y + +@[ext] +protected theorem WeakEMetricSpace.ext {α : Type*} [TopologicalSpace α] {m m' : WeakEMetricSpace α} + (h : m.toEDist = m'.toEDist) : m = m' := by + cases m + cases m' + congr + ext1 + assumption + +/-- +Every `EMetricSpace` has a `WeakEMetricSpace` structure by using the topology induced by its +`edist`. -/ +instance EMetricSpace.toWeakEMetricSpace (α : Type u) [EMetricSpace α] : + WeakEMetricSpace α where + eq_of_edist_eq_zero := eq_of_edist_eq_zero + +variable {γ : Type w} [TopologicalSpace γ] [WeakEMetricSpace γ] + +export WeakEMetricSpace (eq_of_edist_eq_zero) /-- Characterize the equality of points by the vanishing of their extended distance -/ @[simp] @@ -715,10 +838,10 @@ See note [reducible non-instances]. abbrev EMetricSpace.replaceUniformity {γ} [U : UniformSpace γ] (m : EMetricSpace γ) (H : 𝓤[U] = 𝓤[PseudoEMetricSpace.toUniformSpace]) : EMetricSpace γ where edist := @edist _ m.toEDist - edist_self := edist_self + edist_self := edist_self (τ := m.toUniformSpace.toTopologicalSpace) eq_of_edist_eq_zero := @eq_of_edist_eq_zero _ _ - edist_comm := edist_comm - edist_triangle := edist_triangle + edist_comm := edist_comm (τ := m.toUniformSpace.toTopologicalSpace) + edist_triangle := edist_triangle (τ := m.toUniformSpace.toTopologicalSpace) toUniformSpace := U uniformity_edist := H.trans (@PseudoEMetricSpace.uniformity_edist γ _) @@ -732,10 +855,10 @@ See note [reducible non-instances]. abbrev EMetricSpace.replaceTopology {γ} [T : TopologicalSpace γ] (m : EMetricSpace γ) (H : T = m.toUniformSpace.toTopologicalSpace) : EMetricSpace γ where edist := @edist _ m.toEDist - edist_self := edist_self + edist_self := edist_self (τ := m.toUniformSpace.toTopologicalSpace) eq_of_edist_eq_zero := @eq_of_edist_eq_zero _ _ - edist_comm := edist_comm - edist_triangle := edist_triangle + edist_comm := edist_comm (τ := m.toUniformSpace.toTopologicalSpace) + edist_triangle := edist_triangle (τ := m.toUniformSpace.toTopologicalSpace) toUniformSpace := m.toUniformSpace.replaceTopology H uniformity_edist := PseudoEMetricSpace.uniformity_edist @@ -759,7 +882,8 @@ instance {α : Type*} [EMetricSpace α] : EMetricSpace (ULift α) := EMetricSpace.induced ULift.down ULift.down_injective ‹_› /-- Reformulation of the uniform structure in terms of the extended distance -/ -theorem uniformity_edist : 𝓤 γ = ⨅ ε > 0, 𝓟 { p : γ × γ | edist p.1 p.2 < ε } := +theorem uniformity_edist {γ} [EMetricSpace γ] : + 𝓤 γ = ⨅ ε > 0, 𝓟 { p : γ × γ | edist p.1 p.2 < ε } := PseudoEMetricSpace.uniformity_edist /-! @@ -828,94 +952,6 @@ end section -/-- A `WeakPseudoEMetricSpace` is a topological space endowed with a `ℝ≥0∞`-value distance `edist` -which is *almost* an extended pseudometric space: the `edist` is reflexive, commutative and -satisfies the triangle inequality, but the topology on `α` need not *equal* the topology induced -by the `edist`. (It must be at least as fine, and agree with it on eballs of finite radius.) - -This generalises both pseudo extended metric spaces and `ℝ≥0∞` (which have an extended distance, -which does not induce the order topology there). -/ -class WeakPseudoEMetricSpace - (α : Type u) [τ : TopologicalSpace α] : Type u extends EDist α where - edist_self : ∀ x : α, edist x x = 0 - edist_comm : ∀ x y : α, edist x y = edist y x - edist_triangle : ∀ x y z : α, edist x z ≤ edist x y + edist y z - /-- The topology on `α` is at most as fine as the topology generated by the `edist`. -/ - topology_le : - (uniformSpaceOfEDist edist edist_self edist_comm edist_triangle).toTopologicalSpace ≤ τ - /-- The ambient topology on `α` matches the `edist` topology on eballs. -/ - topology_eq_on_restrict : - ∀ (x : α) (r : ℝ≥0∞), - IsOpen ((Metric.eball x ⊤) ↓∩ (Metric.eball x r)) - -@[ext] -protected theorem WeakPseudoEMetricSpace.ext - {α : Type*} [TopologicalSpace α] {m m' : WeakPseudoEMetricSpace α} - (h : m.toEDist = m'.toEDist) : m = m' := by - cases m; cases m'; congr - -/-- Every `PseudoEMetricSpace` has a `WeakPseudoEMetricSpace` structure by -using the topology induced by `edist`. -/ -instance PseudoEMetricSpace.toWeakPseudoEMetricSpace (α : Type u) [inst : PseudoEMetricSpace α] : - WeakPseudoEMetricSpace α where - edist_self := edist_self - edist_comm := edist_comm - edist_triangle := edist_triangle - topology_le := by rw [uniformSpace_edist] - topology_eq_on_restrict _ _ := Metric.isOpen_eball.preimage_val - -/-- `WeakPseudoEMetricSpace` can be induced backwards. -/ -abbrev WeakPseudoEMetricSpace.IsInducing {α β : Type*} [e : TopologicalSpace α] - [n : TopologicalSpace β] {f : α → β} (hf : IsInducing f) (m : WeakPseudoEMetricSpace β) : - WeakPseudoEMetricSpace α where - edist := fun x y ↦ edist (f x) (f y) - edist_self x := edist_self (f x) - edist_comm x y := edist_comm (f x) (f y) - edist_triangle x y z := edist_triangle (f x) (f y) (f z) - topology_le := by - let hα := PseudoEMetricSpace.ofEDist (fun x y ↦ edist (f x) (f y)) - (fun x ↦ edist_self (f x)) (fun x y ↦ edist_comm (f x) (f y)) - (fun x y z ↦ edist_triangle (f x) (f y) (f z)) - let hβ := PseudoEMetricSpace.ofEDist m.edist edist_self edist_comm edist_triangle - rw [(isInducing_iff f).mp hf] - refine (continuous_le_rng m.topology_le ?_).le_induced - refine @Continuous.mk α β hα.toUniformSpace.toTopologicalSpace - hβ.toUniformSpace.toTopologicalSpace f fun s hs ↦ ?_ - rw [isOpen_iff] at hs ⊢ - intro x (hx : f x ∈ s) - obtain ⟨ε, hε, hεs⟩ := hs (f x) hx - exact ⟨ε, hε, fun y hy ↦ hεs hy⟩ - topology_eq_on_restrict x r := by - obtain ⟨u, hu, uy⟩ := m.topology_eq_on_restrict (f x) r - rw [(isInducing_iff f).mp hf] - exact ⟨f ⁻¹' u, isOpen_induced hu, by aesop (add simp [Set.ext_iff])⟩ - -/-- Weak pseudo-emetric space instance on subsets of weak pseudo-emetric spaces -/ -instance {α : Type*} {p : α → Prop} [TopologicalSpace α] [WeakPseudoEMetricSpace α] : - WeakPseudoEMetricSpace (Subtype p) := - WeakPseudoEMetricSpace.IsInducing IsInducing.subtypeVal ‹_› - -/-- A weak extended metric space extends a `WeakPseudoEMetricSpace` with the condition -`edist x y = 0 ↔ x = y`. -/ -class WeakEMetricSpace - (α : Type u) [TopologicalSpace α] : Type u extends WeakPseudoEMetricSpace α where - eq_of_edist_eq_zero : ∀ {x y : α}, edist x y = 0 → x = y - -@[ext] -protected theorem WeakEMetricSpace.ext {α : Type*} [TopologicalSpace α] {m m' : WeakEMetricSpace α} - (h : m.toEDist = m'.toEDist) : m = m' := by - cases m - cases m' - congr - ext1 - assumption - -/-- -Every `EMetricSpace` has a `WeakEMetricSpace` structure by using the topology induced by edist. -/ -instance EMetricSpace.toWeakEMetricSpace (α : Type u) [EMetricSpace α] : - WeakEMetricSpace α where - eq_of_edist_eq_zero := eq_of_edist_eq_zero - /-- The `WeakEMetric` space induced by pulling back a topology along an injective function. -/ abbrev WeakEMetricSpace.induced {α β : Type*} [n : TopologicalSpace β] diff --git a/Mathlib/Topology/EMetricSpace/MulOpposite.lean b/Mathlib/Topology/EMetricSpace/MulOpposite.lean new file mode 100644 index 00000000000000..023baf7cf1c76d --- /dev/null +++ b/Mathlib/Topology/EMetricSpace/MulOpposite.lean @@ -0,0 +1,46 @@ +/- +Copyright (c) 2026 Felix Pernegger. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Felix Pernegger +-/ +module + +public import Mathlib.Topology.Algebra.Constructions +public import Mathlib.Topology.EMetricSpace.Defs + +/-! +# Extended metric spaces on multiplicative opposites + +This file proves that if `α` is some (weak) pseudo extended metric space, so it `αᵐᵒᵖ`. +We do this in this file instead of `Mathlib/Topology/EMetricSpace/Defs.lean` to avoid imports. +-/ + +public section + +open Filter Set Topology Set.Notation + +namespace MulOpposite + +variable {α : Type*} [TopologicalSpace α] [WeakPseudoEMetricSpace α] + +/-- weak pseudoemetric space instance on the multiplicative opposite of a +weak pseudoemetric space. -/ +@[to_additive +/-- Weak pseudoemetric space instance on the additive opposite of a weak pseudoemetric space. -/] +instance {α : Type*} [TopologicalSpace α] [WeakPseudoEMetricSpace α] : + WeakPseudoEMetricSpace αᵐᵒᵖ := + WeakPseudoEMetricSpace.IsInducing MulOpposite.opHomeomorph.symm.isInducing ‹_› + +/-- Pseudoemetric space instance on the multiplicative opposite of a pseudoemetric space. -/ +@[to_additive +/-- Pseudoemetric space instance on the additive opposite of a pseudoemetric space. -/] +instance {α : Type*} [PseudoEMetricSpace α] : PseudoEMetricSpace αᵐᵒᵖ := + PseudoEMetricSpace.induced unop ‹_› + +@[to_additive] +theorem edist_unop (x y : αᵐᵒᵖ) : edist (unop x) (unop y) = edist x y := rfl + +@[to_additive] +theorem edist_op (x y : α) : edist (op x) (op y) = edist x y := rfl + +end MulOpposite diff --git a/Mathlib/Topology/EMetricSpace/Weak.lean b/Mathlib/Topology/EMetricSpace/Weak.lean index add0cc36ac9133..fccd3183afda30 100644 --- a/Mathlib/Topology/EMetricSpace/Weak.lean +++ b/Mathlib/Topology/EMetricSpace/Weak.lean @@ -88,7 +88,7 @@ theorem some_eball (a : α) (r : ENNReal) : lemma edist_self' {α : Type u} [TopologicalSpace α] (m : WeakPseudoEMetricSpace α) : ∀ x : Option α, edist x x = 0 - | (_ : α) => by simp [m.edist_self] + | (_ : α) => by simp | none => rfl lemma edist_comm' {α : Type u} [TopologicalSpace α] (m : WeakPseudoEMetricSpace α) : @@ -128,7 +128,7 @@ abbrev WeakPseudoEMetricSpace.OfIsOpenEmbedding {α : Type u} [t : TopologicalSp edist_comm := h_edist ▸ edist_comm' m edist_triangle := h_edist ▸ edist_triangle' m topology_le s so := by - apply (@EMetric.isOpen_iff (Option α) (PseudoEMetricSpace.ofEDist edist + apply (@EMetric.isOpen_iff (Option α) _ (PseudoEMetricSpace.ofEDist edist (h_edist ▸ edist_self' m) (h_edist ▸ edist_comm' m) (h_edist ▸ edist_triangle' m))).mpr intro x xs suffices ∃ ε > 0, @Metric.eball (Option α) Option.toEDist x ε ⊆ s by rwa [← h_edist] at this @@ -136,7 +136,7 @@ abbrev WeakPseudoEMetricSpace.OfIsOpenEmbedding {α : Type u} [t : TopologicalSp | none => exact ⟨1, by norm_num, by simpa [ball_infty_of_pos]⟩ | (x : α) => - obtain ⟨ε, εp, εt⟩ := (@EMetric.isOpen_iff α (PseudoEMetricSpace.ofEDist edist + obtain ⟨ε, εp, εt⟩ := (@EMetric.isOpen_iff α _ (PseudoEMetricSpace.ofEDist edist m.edist_self m.edist_comm m.edist_triangle)).mp (m.topology_le _ <| h.continuous.isOpen_preimage s so) x (mem_preimage.mpr xs) exact ⟨ε, εp, some_eball x ε ▸ image_subset_iff.mpr εt⟩ diff --git a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean index 32ad0e82e1fef6..acd7b2e31cd28e 100644 --- a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean +++ b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean @@ -104,7 +104,7 @@ theorem infEDist_le_edist_of_mem (h : y ∈ s) : infEDist x s ≤ edist x y := /-- If a point `x` belongs to `s`, then its edist to `s` vanishes -/ theorem infEDist_zero_of_mem (h : x ∈ s) : infEDist x s = 0 := - nonpos_iff_eq_zero.1 <| @edist_self _ _ x ▸ infEDist_le_edist_of_mem h + nonpos_iff_eq_zero.1 <| edist_self x ▸ infEDist_le_edist_of_mem h /-- The edist is antitone with respect to inclusion. -/ @[gcongr] diff --git a/Mathlib/Topology/MetricSpace/IsometricSMul.lean b/Mathlib/Topology/MetricSpace/IsometricSMul.lean index b72f542202b560..f293df58f11d97 100644 --- a/Mathlib/Topology/MetricSpace/IsometricSMul.lean +++ b/Mathlib/Topology/MetricSpace/IsometricSMul.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.GroupWithZero.Pointwise.Set.Basic public import Mathlib.Topology.Algebra.ConstMulAction +public import Mathlib.Topology.EMetricSpace.MulOpposite public import Mathlib.Topology.MetricSpace.Isometry public import Mathlib.Topology.MetricSpace.Lipschitz diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index 3f07a9dd82ca42..eaab1495053e91 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -1061,7 +1061,9 @@ abbrev PseudoEMetricSpace.toPseudoMetricSpaceOfDist {X : Type*} [e : PseudoEMetr (dist : X → X → ℝ) (dist_nonneg : ∀ x y, 0 ≤ dist x y) (h : ∀ x y, edist x y = .ofReal (dist x y)) : PseudoMetricSpace X where dist := dist - dist_self x := by simpa [h, (dist_nonneg _ _).ge_iff_eq', -edist_self] using edist_self x + dist_self x := by + refine le_antisymm ?_ (dist_nonneg x x) + rw [← ENNReal.zero_eq_ofReal, ← h x x, edist_self] dist_comm x y := by simpa [h, dist_nonneg] using edist_comm x y dist_triangle x y z := by simpa [h, dist_nonneg, add_nonneg, ← ENNReal.ofReal_add] using edist_triangle x y z From c8155c7929b5d175577a728327c0351673657287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:45:19 +0000 Subject: [PATCH 1286/1300] feat(AlgebraicTopology/SimplicialSet/Homology): extension of scalars (#38965) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If `X` is a simplicial set, `R₁ →+* R₂` is a morphism of commutative rings, and `M₁` is a `R₁`-module, then the chain complex of `R₂`-modules of `X` with coefficients in `R₂ ⊗[R₁] M₁` identifies to the extensions of scalars of the chain complex of `R₁`-modules of `X` with coefficients in `M₁`. In this file, we obtain a formulation of this result where the extension of scalars functor `ModuleCat R₁ ⥤ ModuleCat R₂` is replaced by an arbitrary functor `F : C ⥤ D` which commutes with coproducts. (As `SimplicialObject` is now an `abbrev` for a category of functors, `SimplicialObject.whiskering` is also made an abbrev here.) --- Mathlib.lean | 1 + Mathlib/Algebra/Homology/Additive.lean | 2 +- .../Algebra/Homology/HomologicalComplex.lean | 10 ++- .../AlternatingFaceMapComplex.lean | 32 ++++----- .../SimplicialObject/Basic.lean | 13 ++-- .../Homology/MapHomologicalComplex.lean | 70 +++++++++++++++++++ .../SingularHomology/Basic.lean | 3 - .../Limits/Preserves/SigmaConst.lean | 43 ++++++++++-- .../Limits/Shapes/Products.lean | 2 + 9 files changed, 140 insertions(+), 36 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/Homology/MapHomologicalComplex.lean diff --git a/Mathlib.lean b/Mathlib.lean index 69f1fe5f039fb7..13446deab57164 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1599,6 +1599,7 @@ public import Mathlib.AlgebraicTopology.SimplicialSet.HoFunctorMonoidal public import Mathlib.AlgebraicTopology.SimplicialSet.Homology.Basic public import Mathlib.AlgebraicTopology.SimplicialSet.Homology.HomologyZero public import Mathlib.AlgebraicTopology.SimplicialSet.Homology.HomotopyInvariance +public import Mathlib.AlgebraicTopology.SimplicialSet.Homology.MapHomologicalComplex public import Mathlib.AlgebraicTopology.SimplicialSet.Homology.Nondegenerate public import Mathlib.AlgebraicTopology.SimplicialSet.Homotopy public import Mathlib.AlgebraicTopology.SimplicialSet.HomotopyCat diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 075b5c8c028f94..0165862beb993a 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -99,7 +99,7 @@ namespace CategoryTheory /-- An additive functor induces a functor between homological complexes. This is sometimes called the "prolongation". -/ -@[simps] +@[simps, implicit_reducible] def Functor.mapHomologicalComplex (F : W₁ ⥤ W₂) [F.PreservesZeroMorphisms] (c : ComplexShape ι) : HomologicalComplex W₁ c ⥤ HomologicalComplex W₂ c where obj C := diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 5cdf22f662c7a9..83afd4698277d8 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -269,6 +269,14 @@ theorem eqToHom_f {C₁ C₂ : HomologicalComplex V c} (h : C₁ = C₂) (n : ι subst h rfl +lemma ext_of_hom {C₁ C₂ : HomologicalComplex V c} (f : C₁ ⟶ C₂) (h₁ : ∀ i, C₁.X i = C₂.X i) + (h₂ : ∀ i, f.f i = eqToHom (h₁ i) := by cat_disch) : C₁ = C₂ := + HomologicalComplex.ext (by cat_disch) (fun _ _ _ ↦ by simp [← h₂]) + +lemma ext_of_iso {C₁ C₂ : HomologicalComplex V c} (e : C₁ ≅ C₂) (h₁ : ∀ i, C₁.X i = C₂.X i) + (h₂ : ∀ i, e.hom.f i = eqToHom (h₁ i) := by cat_disch) : C₁ = C₂ := + ext_of_hom e.hom h₁ h₂ + -- We'll use this later to show that `HomologicalComplex V c` is preadditive when `V` is. theorem hom_f_injective {C₁ C₂ : HomologicalComplex V c} : Function.Injective fun f : Hom C₁ C₂ => f.f := by cat_disch @@ -503,7 +511,7 @@ def isoApp (f : C₁ ≅ C₂) (i : ι) : C₁.X i ≅ C₂.X i := /-- Construct an isomorphism of chain complexes from isomorphism of the objects which commute with the differentials. -/ -@[simps] +@[simps, implicit_reducible] def isoOfComponents (f : ∀ i, C₁.X i ≅ C₂.X i) (hf : ∀ i j, c.Rel i j → (f i).hom ≫ C₂.d i j = C₁.d i j ≫ (f j).hom := by cat_disch) : C₁ ≅ C₂ where diff --git a/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean b/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean index 967618574f0171..7992ff15f83a2d 100644 --- a/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean +++ b/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean @@ -178,28 +178,26 @@ theorem alternatingFaceMapComplex_map_f {X Y : SimplicialObject C} (f : X ⟶ Y) ((alternatingFaceMapComplex C).map f).f n = f.app (op ⦋n⦌) := rfl +attribute [local simp] Functor.map_zsmul in +/-- The construction of the alternating face map complex commutes with the application +of an additive functor. -/ +@[simps!] +def alternatingFaceMapComplexCompMapHomologicalComplexIso + {D : Type*} [Category* D] [Preadditive D] (F : C ⥤ D) [F.Additive] : + alternatingFaceMapComplex C ⋙ F.mapHomologicalComplex _ ≅ + (SimplicialObject.whiskering C D).obj F ⋙ alternatingFaceMapComplex D := + NatIso.ofComponents + (fun X ↦ HomologicalComplex.Hom.isoOfComponents (fun _ ↦ Iso.refl _)) + set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in theorem map_alternatingFaceMapComplex {D : Type*} [Category* D] [Preadditive D] (F : C ⥤ D) [F.Additive] : alternatingFaceMapComplex C ⋙ F.mapHomologicalComplex _ = - (SimplicialObject.whiskering C D).obj F ⋙ alternatingFaceMapComplex D := by - apply CategoryTheory.Functor.ext - · intro X Y f - ext n - simp only [Functor.comp_map, HomologicalComplex.comp_f, alternatingFaceMapComplex_map_f, - Functor.mapHomologicalComplex_map_f, HomologicalComplex.eqToHom_f, eqToHom_refl, comp_id, - id_comp, SimplicialObject.whiskering_obj_map_app] - · intro X - apply HomologicalComplex.ext - · rintro i j (rfl : j + 1 = i) - dsimp only [Functor.comp_obj] - simp only [Functor.mapHomologicalComplex_obj_d, alternatingFaceMapComplex_obj_d, - eqToHom_refl, id_comp, comp_id, AlternatingFaceMapComplex.objD, Functor.map_sum, - Functor.map_zsmul] - rfl - · ext n - rfl + (SimplicialObject.whiskering C D).obj F ⋙ alternatingFaceMapComplex D := + Functor.ext_of_iso (alternatingFaceMapComplexCompMapHomologicalComplexIso F) (fun X ↦ + HomologicalComplex.ext_of_iso + ((alternatingFaceMapComplexCompMapHomologicalComplexIso F).app X) (fun _ ↦ rfl)) instance : (alternatingFaceMapComplex C).Additive where diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean index 93b27ce11c54fe..46fe6c71ba67a0 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Basic.lean @@ -217,8 +217,7 @@ variable {D : Type*} [Category* D] variable (D) in /-- Functor composition induces a functor on simplicial objects. -/ -@[simps!] -def whiskering : (C ⥤ D) ⥤ SimplicialObject C ⥤ SimplicialObject D := +abbrev whiskering : (C ⥤ D) ⥤ SimplicialObject C ⥤ SimplicialObject D := whiskeringRight _ _ _ set_option backward.defeqAttrib.useBackward true in @@ -242,8 +241,7 @@ namespace Truncated variable (C) in /-- Functor composition induces a functor on truncated simplicial objects. -/ -@[simps!] -def whiskering {n} (D : Type*) [Category* D] : (C ⥤ D) ⥤ Truncated C n ⥤ Truncated D n := +abbrev whiskering {n} (D : Type*) [Category* D] : (C ⥤ D) ⥤ Truncated C n ⥤ Truncated D n := whiskeringRight _ _ _ open Mathlib.Tactic (subscriptTerm) in @@ -695,8 +693,8 @@ theorem σ_naturality {X' X : CosimplicialObject C} (f : X ⟶ X') {n : ℕ} (i variable (C) /-- Functor composition induces a functor on cosimplicial objects. -/ -@[simps!] -def whiskering (D : Type*) [Category* D] : (C ⥤ D) ⥤ CosimplicialObject C ⥤ CosimplicialObject D := +abbrev whiskering (D : Type*) [Category* D] : + (C ⥤ D) ⥤ CosimplicialObject C ⥤ CosimplicialObject D := whiskeringRight _ _ _ /-- Truncated cosimplicial objects. -/ @@ -728,8 +726,7 @@ instance {n} [HasColimits C] : HasColimits (CosimplicialObject.Truncated C n) := variable (C) in /-- Functor composition induces a functor on truncated cosimplicial objects. -/ -@[simps!] -def whiskering {n} (D : Type*) [Category* D] : (C ⥤ D) ⥤ Truncated C n ⥤ Truncated D n := +abbrev whiskering {n} (D : Type*) [Category* D] : (C ⥤ D) ⥤ Truncated C n ⥤ Truncated D n := whiskeringRight _ _ _ open Mathlib.Tactic (subscriptTerm) in diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Homology/MapHomologicalComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Homology/MapHomologicalComplex.lean new file mode 100644 index 00000000000000..c3c37f61155ed8 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Homology/MapHomologicalComplex.lean @@ -0,0 +1,70 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.AlgebraicTopology.SimplicialSet.Homology.Basic +public import Mathlib.CategoryTheory.Limits.Preserves.SigmaConst + +/-! +# Extension of scalars + +If `X` is a simplicial set, `R₁ →+* R₂` is a morphism of commutative rings, +and `M₁` is a `R₁`-module, then the chain complex of `R₂`-modules of `X` with +coefficients in `R₂ ⊗[R₁] M₁` identifies to the extensions of scalars of the +chain complex of `R₁`-modules of `X` with coefficients in `M₁`. In this file, +we obtain a formulation of this result where the extension of scalars +functor `ModuleCat R₁ ⥤ ModuleCat R₂` is replaced by an arbitrary functor +`F : C ⥤ D` which commutes with coproducts. + +-/ + +@[expose] public section + +universe w v v' u u' + +open CategoryTheory Limits AlgebraicTopology Simplicial + +namespace SSet + +variable {C : Type u} {D : Type u'} [Category.{v} C] [Category.{v'} D] + [Preadditive C] [Preadditive D] [HasCoproducts.{w} C] [HasCoproducts.{w} D] + (X : SSet.{w}) (F : C ⥤ D) [F.Additive] + [∀ (T : Type w), PreservesColimitsOfShape (Discrete T) F] (R : C) + +open SimplicialObject Functor in +/-- The chain complex functor commutes with the "extension of scalars". +More precisely, if `F : C ⥤ D` is a functor which commutes with arbitrary coproducts, +`R : C` and `X : SSet`, then the chain complex of `X` with coefficients +in `F.obj R` is obtained by applying `F` to the chain complex of `X` +with coefficients in `R`. -/ +noncomputable def chainComplexFunctorObjCompMapIso : + (chainComplexFunctor C).obj R ⋙ F.mapHomologicalComplex (.down ℕ) ≅ + (chainComplexFunctor D).obj (F.obj R) := + calc + _ ≅ (whiskering ..).obj (sigmaConst.obj R) ⋙ + alternatingFaceMapComplex C ⋙ F.mapHomologicalComplex _ := associator .. + _ ≅ (whiskering ..).obj (sigmaConst.obj R) ⋙ + (whiskering ..).obj F ⋙ alternatingFaceMapComplex D := + isoWhiskerLeft _ (alternatingFaceMapComplexCompMapHomologicalComplexIso _) + _ ≅ ((whiskering ..).obj (sigmaConst.obj R) ⋙ + (whiskering ..).obj F) ⋙ alternatingFaceMapComplex D := + (associator ..).symm + _ ≅ (whiskering ..).obj (sigmaConst.obj R ⋙ F) ⋙ alternatingFaceMapComplex D := + isoWhiskerRight (whiskeringRightObjCompIso ..) _ + _ ≅ (whiskering ..).obj (sigmaConst.obj (F.obj R)) ⋙ alternatingFaceMapComplex D := + isoWhiskerRight ((whiskering ..).mapIso (sigmaConstObjCompIso F R)) _ + +variable {R} in +@[reassoc (attr := simp)] +lemma map_ιChainComplex_chainComplexFunctorObjCompMapIso_hom_app_f + {n : ℕ} (x : X _⦋n⦌) : + dsimp% F.map (X.ιChainComplex x) ≫ + ((chainComplexFunctorObjCompMapIso F R).hom.app X).f n = + X.ιChainComplex x := by + simp [chainComplexFunctorObjCompMapIso, ιChainComplex, + SSet.chainComplexFunctor] + +end SSet diff --git a/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean b/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean index c4adbbf61b5c9b..e005cdf8ce08c3 100644 --- a/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean +++ b/Mathlib/AlgebraicTopology/SingularHomology/Basic.lean @@ -46,9 +46,6 @@ instance [Limits.HasPullbacks C] {X : C} : ((singularChainComplexFunctor C).obj X).PreservesMonomorphisms where preserves f _ := by dsimp [singularChainComplexFunctor, SSet.chainComplexFunctor] - apply +allowSynthFailures Functor.map_mono - apply +allowSynthFailures Functor.map_mono - dsimp [SSet, SimplicialObject.whiskering, SimplicialObject] infer_instance /-- The `n`-th singular homology functor with coefficients in `C`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean index 40ab0e87505352..124ae08e71e3a9 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/SigmaConst.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.CategoryTheory.Limits.Preserves.Basic +public import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Products public import Mathlib.CategoryTheory.Limits.Shapes.ZeroMorphisms public import Mathlib.CategoryTheory.Limits.Shapes.Kernels public import Mathlib.CategoryTheory.Limits.Types.Coproducts @@ -26,7 +26,7 @@ universe w v' v u' u namespace CategoryTheory.Limits -variable {C : Type u} [Category.{v} C] +variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] set_option backward.defeqAttrib.useBackward true in set_option backward.isDefEq.respectTransparency false in @@ -56,11 +56,9 @@ instance [HasCoproducts.{w} C] (R : C) : simp [coconeTypes, ← hm, dsimp% hc.fac_apply, dsimp% Sigma.ι_desc (hc.desc (coconeTypes s))] }⟩⟩⟩ -variable [HasZeroMorphisms C] (R : C) - section -variable {α β : Type*} (f : α → β) +variable [HasZeroMorphisms C] (R : C) {α β : Type*} (f : α → β) [HasCoproduct (fun (_ : α) ↦ R)] [HasCoproduct (fun (_ : β) ↦ R)] [HasCoproduct (fun (_ : ((Set.range f)ᶜ : Set _)) ↦ R)] @@ -120,8 +118,41 @@ instance : end set_option backward.defeqAttrib.useBackward true in -instance [HasCoproducts.{w} C] {α β : Type w} (f : α ⟶ β) : +instance [HasZeroMorphisms C] (R : C) [HasCoproducts.{w} C] {α β : Type w} (f : α ⟶ β) : HasCokernel ((sigmaConst.obj R).map f) := by dsimp; infer_instance +section + +variable [HasCoproducts.{w} C] [HasCoproducts.{w} D] + (F : C ⥤ D) [∀ (T : Type w), PreservesColimitsOfShape (Discrete T) F] (X : C) + +/-- The isomophism `sigmaConst.obj X ⋙ F ≅ sigmaConst.obj (F.obj X)` when `F` +preserves coproducts. -/ +noncomputable def sigmaConstObjCompIso : sigmaConst.obj X ⋙ F ≅ sigmaConst.obj (F.obj X) := + NatIso.ofComponents (fun _ ↦ PreservesCoproduct.iso _ _) (fun {T₁ T₂} f ↦ by + dsimp [Sigma.map'] + rw [← cancel_epi (PreservesCoproduct.iso F (fun (_ : T₁) ↦ X)).inv, + ← cancel_mono (PreservesCoproduct.iso F (fun (_ : T₂) ↦ X)).inv, + Iso.inv_hom_id_assoc, Category.assoc, Category.assoc, Iso.hom_inv_id, Category.comp_id, + PreservesCoproduct.inv_hom, PreservesCoproduct.inv_hom, sigmaComparison_map_desc] + cat_disch) + +@[reassoc (attr := simp)] +lemma map_ι_sigmaConstObjCompIso_hom_app {T : Type w} (t : T) : + dsimp% F.map (Sigma.ι (fun (_ : T) ↦ X) t) ≫ (sigmaConstObjCompIso F X).hom.app T = + Sigma.ι (fun (_ : T) ↦ F.obj X) t := by + dsimp [sigmaConstObjCompIso] + rw [← cancel_mono (PreservesCoproduct.iso F (fun (_ : T) ↦ X)).inv, + Category.assoc, Iso.hom_inv_id] + simp + +@[reassoc (attr := simp)] +lemma ι_sigmaConstObjCompIso_inv_app {T : Type w} (t : T) : + Sigma.ι (fun (_ : T) ↦ F.obj X) t ≫ (sigmaConstObjCompIso F X).inv.app T = + F.map (Sigma.ι (fun (_ : T) ↦ X) t) := by + simp [sigmaConstObjCompIso] + +end + end CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index 1041a23e85ff5d..11a2573d9c6518 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -752,6 +752,8 @@ def piConstAdj [Limits.HasProducts.{v} C] (X : C) : naturality _ _ _ := by apply Quiver.Hom.unop_inj; cat_disch } left_triangle_components _ := by apply Quiver.Hom.unop_inj; cat_disch +-- Note: We may consider making `sigmaConst` an abbrev in order to +-- improve automation downstream /-- The functor sending `(X, n)` to the coproduct of copies of `X` indexed by `n`. -/ @[implicit_reducible, simps] def sigmaConst [Limits.HasCoproducts.{w} C] : C ⥤ Type w ⥤ C where From 2c9f4d7f5c3a85981386206da861661fb15acbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:45:22 +0000 Subject: [PATCH 1287/1300] feat(CategoryTheory): (co)kernels in functor categories/homological complexes (#41301) --- Mathlib.lean | 1 + .../Algebra/Homology/HomologicalComplex.lean | 4 +- .../Homology/HomologicalComplexKernels.lean | 53 +++++++++++++++++++ .../FunctorCategory/Shapes/Kernels.lean | 39 ++++++++++++-- .../Limits/Preserves/Shapes/Kernels.lean | 2 + .../CategoryTheory/Limits/Shapes/Kernels.lean | 4 +- 6 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 Mathlib/Algebra/Homology/HomologicalComplexKernels.lean diff --git a/Mathlib.lean b/Mathlib.lean index 13446deab57164..23f9c70eb42f0e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -631,6 +631,7 @@ public import Mathlib.Algebra.Homology.HomologicalBicomplex public import Mathlib.Algebra.Homology.HomologicalComplex public import Mathlib.Algebra.Homology.HomologicalComplexAbelian public import Mathlib.Algebra.Homology.HomologicalComplexBiprod +public import Mathlib.Algebra.Homology.HomologicalComplexKernels public import Mathlib.Algebra.Homology.HomologicalComplexLimits public import Mathlib.Algebra.Homology.HomologicalComplexLimitsEventuallyConstant public import Mathlib.Algebra.Homology.HomologySequence diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 83afd4698277d8..e2780152484335 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -333,7 +333,7 @@ section variable (V c) /-- The functor picking out the `i`-th object of a complex. -/ -@[simps] +@[simps, implicit_reducible] def eval (i : ι) : HomologicalComplex V c ⥤ V where obj C := C.X i map f := f.f i @@ -341,7 +341,7 @@ def eval (i : ι) : HomologicalComplex V c ⥤ V where instance (i : ι) : (eval V c i).PreservesZeroMorphisms where /-- The functor forgetting the differential in a complex, obtaining a graded object. -/ -@[simps] +@[simps, implicit_reducible] def forget : HomologicalComplex V c ⥤ GradedObject ι V where obj C := C.X map f := f.f diff --git a/Mathlib/Algebra/Homology/HomologicalComplexKernels.lean b/Mathlib/Algebra/Homology/HomologicalComplexKernels.lean new file mode 100644 index 00000000000000..54002e7ee88583 --- /dev/null +++ b/Mathlib/Algebra/Homology/HomologicalComplexKernels.lean @@ -0,0 +1,53 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Kernels +public import Mathlib.Algebra.Homology.HomologicalComplexLimits + +/-! +# Kernels and cokernels in categories of homological complexes + +-/ + +public section + +open CategoryTheory Limits + +namespace HomologicalComplex + +variable {ι C : Type*} [Category* C] [HasZeroMorphisms C] {c : ComplexShape ι} + {K L : HomologicalComplex C c} (f : K ⟶ L) + +lemma hasKernel_of_hasKernel_f [∀ i, HasKernel (f.f i)] : HasKernel f := + have (i : ι) : HasLimit (parallelPair f 0 ⋙ eval C c i) := + hasLimit_of_iso (F := (parallelPair (f.f i) 0)) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + ⟨_, isLimitConeOfHasLimitEval _⟩ + +lemma hasCokernel_of_hasCokernel_f [∀ i, HasCokernel (f.f i)] : HasCokernel f := + have (i : ι) : HasColimit (parallelPair f 0 ⋙ eval C c i) := + hasColimit_of_iso (F := (parallelPair (f.f i) 0)) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + ⟨_, isColimitCoconeOfHasColimitEval _⟩ + +lemma eval_preservesLimit_of_hasKernel_f [∀ i, HasKernel (f.f i)] (i : ι) : + PreservesLimit (parallelPair f 0) (eval C c i) := + have (i : ι) : HasLimit (parallelPair f 0 ⋙ eval C c i) := + hasLimit_of_iso (F := (parallelPair (f.f i) 0)) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + preservesLimit_of_preserves_limit_cone + (isLimitConeOfHasLimitEval _) (limit.isLimit _) + +lemma eval_preservesColimit_of_hasCokernel_f [∀ i, HasCokernel (f.f i)] (i : ι) : + PreservesColimit (parallelPair f 0) (eval C c i) := + have (i : ι) : HasColimit (parallelPair f 0 ⋙ eval C c i) := + hasColimit_of_iso (F := (parallelPair (f.f i) 0)) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + preservesColimit_of_preserves_colimit_cocone + (isColimitCoconeOfHasColimitEval _) (colimit.isColimit _) + +end HomologicalComplex diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Kernels.lean index ad87ed754c1d58..3fcbbfad82daf1 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Kernels.lean @@ -15,21 +15,52 @@ public import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Kernels @[expose] public section namespace CategoryTheory.Limits -universe u -variable (C : Type*) [Category.{u} C] [HasZeroMorphisms C] +variable (J C : Type*) [Category* J] [Category* C] [HasZeroMorphisms C] -set_option backward.isDefEq.respectTransparency false in /-- The kernel inclusion is itself a kernel in the functor category. -/ noncomputable def kerIsKernel [HasKernels C] : IsLimit (KernelFork.ofι (ker.ι C) (ker.condition C)) := evaluationJointlyReflectsLimits _ fun f ↦ (KernelFork.isLimitMapConeEquiv ..).2 <| (kernelIsKernel f.hom).ofIsoLimit <| Fork.ext <| .refl _ -set_option backward.isDefEq.respectTransparency false in /-- The cokernel projection is itself a cokernel in the functor category. -/ noncomputable def cokerIsCokernel [HasCokernels C] : IsColimit (CokernelCofork.ofπ (coker.π C) (coker.condition C)) := evaluationJointlyReflectsColimits _ fun f ↦ (CokernelCofork.isColimitMapCoconeEquiv ..).2 <| (cokernelIsCokernel f.hom).ofIsoColimit <| Cofork.ext <| .refl _ +variable {J C} {F₁ F₂ : J ⥤ C} (f : F₁ ⟶ F₂) + +lemma hasKernel_of_hasKernel_app [∀ j, HasKernel (f.app j)] : HasKernel f := + have (j : J) : HasLimit ((parallelPair f 0).flip.obj j) := + hasLimit_of_iso (F := parallelPair (f.app j) 0) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + functorCategoryHasLimit _ + +lemma hasCokernel_of_hasCokernel_app [∀ j, HasCokernel (f.app j)] : HasCokernel f := + have (j : J) : HasColimit ((parallelPair f 0).flip.obj j) := + hasColimit_of_iso (F := parallelPair (f.app j) 0) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + functorCategoryHasColimit _ + +lemma evaluation_preservesLimit_of_hasKernel_app [∀ j, HasKernel (f.app j)] (j : J) : + PreservesLimit (parallelPair f 0) ((evaluation _ _).obj j) := + have (j : J) : HasLimit ((parallelPair f 0).flip.obj j) := + hasLimit_of_iso (F := parallelPair (f.app j) 0) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + preservesLimit_of_preserves_limit_cone + (combinedIsLimit (F := parallelPair f 0) + (fun j ↦ getLimitCone ((parallelPair f 0).flip.obj j))) + (limit.isLimit _) + +lemma evaluation_preservesColimit_of_hasCokernel_app [∀ j, HasCokernel (f.app j)] (j : J) : + PreservesColimit (parallelPair f 0) ((evaluation _ _).obj j) := + have (j : J) : HasColimit ((parallelPair f 0).flip.obj j) := + hasColimit_of_iso (F := parallelPair (f.app j) 0) + (parallelPair.ext (Iso.refl _) (Iso.refl _)) + preservesColimit_of_preserves_colimit_cocone + (combinedIsColimit (F := parallelPair f 0) + (fun j ↦ getColimitCocone ((parallelPair f 0).flip.obj j))) + (colimit.isColimit _) + end CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean index 75b13392e5de1a..ccedef3b11618d 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Kernels.lean @@ -43,6 +43,7 @@ lemma map_condition : G.map c.ι ≫ G.map f = 0 := by /-- A kernel fork for `f` is mapped to a kernel fork for `G.map f` if `G` is a functor which preserves zero morphisms. -/ +@[implicit_reducible] def map : KernelFork (G.map f) := KernelFork.ofι (G.map c.ι) (c.map_condition G) @@ -172,6 +173,7 @@ lemma map_condition : G.map f ≫ G.map c.π = 0 := by /-- A cokernel cofork for `f` is mapped to a cokernel cofork for `G.map f` if `G` is a functor which preserves zero morphisms. -/ +@[implicit_reducible] def map : CokernelCofork (G.map f) := CokernelCofork.ofπ (G.map c.π) (c.map_condition G) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean index b4f0d7bd9ae593..32824e7105c1e7 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean @@ -1294,7 +1294,7 @@ section HasKernels variable [HasKernels C] /-- The kernel of an arrow is natural. -/ -@[simps] +@[simps, implicit_reducible] noncomputable def ker : Arrow C ⥤ C where obj f := kernel f.hom map {f g} u := kernel.lift _ (kernel.ι _ ≫ u.left) (by simp) @@ -1314,7 +1314,7 @@ section HasCokernels variable [HasCokernels C] /-- The cokernel of an arrow is natural. -/ -@[simps] +@[simps, implicit_reducible] noncomputable def coker : Arrow C ⥤ C where obj f := cokernel f.hom map {f g} u := cokernel.desc _ (u.right ≫ cokernel.π _) (by simp [← Arrow.w_assoc u]) From 5e3076d06831eb5b28eb24c2b65bdc02f5eca833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:45:24 +0000 Subject: [PATCH 1288/1300] feat(Geometry/Convex): a topology on StdSimplex (#42131) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this PR, we define a topology on the standard simplex `StdSimplex R M`. When `M` is finite, this is the topology that is induced by the embedding `StdSimplex R M → (M → R)`. In general, we use the supremum of the coinduced topologies for the maps `StdSimplex.map f : StdSimplex R ι → StdSimplex R M` where `f : ι → M` is a map from a finite set `ι`. --- Mathlib.lean | 1 + .../Algebra/BigOperators/Finsupp/Basic.lean | 7 + .../BigOperators/Group/Finset/Basic.lean | 8 + Mathlib/Data/Finsupp/Basic.lean | 4 + Mathlib/Geometry/Convex/ConvexSpace/Defs.lean | 73 ++++++++ .../Geometry/Convex/ConvexSpace/Topology.lean | 177 ++++++++++++++++++ Mathlib/LinearAlgebra/Vandermonde.lean | 3 +- 7 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Geometry/Convex/ConvexSpace/Topology.lean diff --git a/Mathlib.lean b/Mathlib.lean index 23f9c70eb42f0e..83aa20982dfed8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4603,6 +4603,7 @@ public import Mathlib.Geometry.Convex.ConvexSpace.AffineSpace public import Mathlib.Geometry.Convex.ConvexSpace.Defs public import Mathlib.Geometry.Convex.ConvexSpace.Module public import Mathlib.Geometry.Convex.ConvexSpace.Prod +public import Mathlib.Geometry.Convex.ConvexSpace.Topology public import Mathlib.Geometry.Convex.Hull public import Mathlib.Geometry.Convex.Set public import Mathlib.Geometry.Convex.Star diff --git a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean index 927d687ccb9b31..fe2001a6f7e664 100644 --- a/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Finsupp/Basic.lean @@ -411,6 +411,13 @@ theorem liftAddHom_singleAddHom [AddCommMonoid M] : AddMonoidHom.id _ := liftAddHom.toEquiv.eq_symm_apply.1 rfl +lemma sum_finsetSum + (f : ι → (α →₀ A)) (s : Finset ι) (g : α → A → B) + (h₁ : ∀ a, g a 0 = 0) + (h₂ : ∀ a m₁ m₂, g a (m₁ + m₂) = g a m₁ + g a m₂) : + (∑ i ∈ s, f i).sum g = ∑ i ∈ s, (f i).sum g := + map_sum (liftAddHom (fun a ↦ { toFun := g a, map_zero' := h₁ a, map_add' := h₂ a })) f s + @[simp] theorem sum_single [AddCommMonoid M] (f : α →₀ M) : f.sum single = f := DFunLike.congr_fun liftAddHom_singleAddHom f diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index ce6f063b535465..d3f3404d9c55bc 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -153,6 +153,14 @@ lemma prod_filter_not_mul_prod_filter (s : Finset ι) (p : ι → Prop) [Decidab (∏ x ∈ s with ¬p x, f x) * ∏ x ∈ s with p x, f x = ∏ x ∈ s, f x := by rw [mul_comm, prod_filter_mul_prod_filter_not] +open Classical in +@[to_additive] +lemma prod_eq_of_subset + {s₁ s₂ : Finset ι} (h : s₁ ⊆ s₂) (f : ι → M) (hf : ∀ (i : ι), i ∈ s₂ → i ∉ s₁ → f i = 1) : + ∏ i ∈ s₁, f i = ∏ i ∈ s₂, f i := by + rw [show s₂ = s₁.disjUnion (s₂ \ s₁) disjoint_sdiff by simpa, Finset.prod_disjUnion, + Finset.prod_eq_one (s := s₂ \ s₁) (by aesop), mul_one] + set_option backward.isDefEq.respectTransparency.types false in @[to_additive] theorem prod_filter_xor (p q : ι → Prop) [DecidablePred p] [DecidablePred q] : diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index c17568a07a67d1..3f9bc2b8cc0c09 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -444,6 +444,10 @@ theorem mapDomain_surjective {f : α → β} (hf : f.Surjective) : use mapDomain (surjInv hf) x rw [← mapDomain_comp, (rightInverse_surjInv hf).id, mapDomain_id] +lemma mapDomain_fintype [Fintype α] (f : α → β) (g : α →₀ M) : + Finsupp.mapDomain f g = ∑ (a : α), .single (f a) (g a) := + Finsupp.sum_fintype _ _ (by simp) + /-- When `f` is an embedding we have an embedding `(α →₀ ℕ) ↪ (β →₀ ℕ)` given by `mapDomain`. -/ @[simps] def mapDomainEmbedding {α β : Type*} (f : α ↪ β) : (α →₀ ℕ) ↪ β →₀ ℕ := diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean index 49aa134dd90065..63e365ea8fa1a9 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/Defs.lean @@ -81,6 +81,26 @@ lemma nonempty [Nontrivial R] (w : StdSimplex R M) : Nonempty M := @[ext] alias ⟨ext, _⟩ := weights_inj +@[simp] +lemma total_of_fintype [Fintype M] (w : StdSimplex R M) : + ∑ i, w.weights i = 1 := by + have := w.total + rwa [Finsupp.sum_fintype _ _ (by simp)] at this + +lemma range_toFun_comp_weights [Fintype M] : + Set.range (fun t ↦ t.weights : StdSimplex R M → (M → R)) = + (⋂ (i : M), { s | 0 ≤ s i }) ∩ { s | ∑ i, s i = 1 } := by + ext s + simp only [Set.mem_range, Set.mem_inter_iff, Set.mem_iInter, Set.mem_ofPred_eq] + refine ⟨?_, ?_⟩ + · rintro ⟨s, rfl⟩ + exact ⟨s.weights_nonneg, by simp⟩ + · rintro ⟨h₁, h₂⟩ + exact ⟨{ + weights := equivFunOnFinite.symm s + nonneg m := by simpa using h₁ m + total := by simpa [Finsupp.sum_fintype] }, by simp⟩ + variable [IsStrictOrderedRing R] /-- The point mass distribution concentrated at `x`. -/ @@ -136,14 +156,67 @@ lemma map_duple {s t : R} (hs : 0 ≤ s) (ht : 0 ≤ t) (h : s + t = 1) (x y : M lemma map_id (f : StdSimplex R M) : f.map id = f := by ext; simp +lemma map_id' : map (R := R) (id : M → M) = id := by aesop + lemma map_comp (f : StdSimplex R M) (g₁ : M → N) (g₂ : N → P) : f.map (g₂ ∘ g₁) = (f.map g₁).map g₂ := by ext; simp [mapDomain_comp] +lemma map_comp' (g₁ : M → N) (g₂ : N → P) : + map (R := R) (g₂ ∘ g₁) = map g₂ ∘ map g₁ := by + ext : 1 + simp [map_comp] + lemma map_map (f : StdSimplex R M) (g₁ : M → N) (g₂ : N → P) : (f.map g₁).map g₂ = f.map (fun x ↦ g₂ (g₁ x)) := (map_comp ..).symm +lemma mem_range_map_iff + (f : M → N) (s : StdSimplex R N) : + s ∈ Set.range (map f) ↔ ∀ (x : N), x ∉ Set.range f → s.weights x = 0 := by + refine ⟨?_, fun h ↦ ?_⟩ + · rintro ⟨s, rfl⟩ + intro x hx + simpa using Finsupp.mapDomain_of_notMem_range s.weights x hx + · have (i : s.weights.support) : ∃ (m : M), f m = i := by grind + choose m hm using this + refine ⟨{ + weights := ∑ (y : s.weights.support), .single (m y) (s.weights y) + nonneg x := by + simp only [Finsupp.coe_finsetSum, Finset.sum_apply, + Finsupp.coe_zero, Pi.zero_apply] + refine Finset.sum_nonneg' (fun y ↦ ?_) + by_cases hy : m y = x + · subst hy + simp + · rw [Finsupp.single_eq_of_ne' hy] + total := by + rw [Finsupp.sum_finsetSum _ _ _ (by simp) (by simp), ← s.total] + conv_rhs => dsimp [Finsupp.sum]; rw [← Finset.sum_attach] + congr + ext + simp }, ?_⟩ + ext y + by_cases hy : y ∈ s.weights.support + · simp only [Finset.univ_eq_attach, weights_map, Finsupp.mapDomain, Finsupp.sum_apply] + rw [Finsupp.sum_finsetSum _ _ _ (by simp) (by simp), + Finset.sum_eq_single ⟨y, hy⟩ ?_ (by simp)] + · simp [hm] + · intro z hz hz' + simp only [hm, Finsupp.single_zero, Finsupp.coe_zero, Pi.zero_apply, + Finsupp.sum_single_index] + aesop + · rw [Finsupp.notMem_support_iff] at hy + rw [hy] + refine Finsupp.mapDomain_of_not_mem_image_support ?_ + simp only [Finset.univ_eq_attach, Set.mem_image, SetLike.mem_coe, Finsupp.mem_support_iff, + Finsupp.coe_finsetSum, Finset.sum_apply, ne_eq, not_exists, not_and] + intro x hx rfl + refine hx (Finset.sum_eq_zero (fun z hz ↦ Finsupp.single_eq_of_ne ?_)) + intro rfl + simp only [hm, ← Finsupp.notMem_support_iff] at hy + exact hy z.prop + /-- Join operation for standard simplices (monadic join). Given a distribution over distributions, flattens it to a single distribution. diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Topology.lean b/Mathlib/Geometry/Convex/ConvexSpace/Topology.lean new file mode 100644 index 00000000000000..41df23b71c6bd2 --- /dev/null +++ b/Mathlib/Geometry/Convex/ConvexSpace/Topology.lean @@ -0,0 +1,177 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Geometry.Convex.ConvexSpace.Module +public import Mathlib.Order.CompletePartialOrder +public import Mathlib.SetTheory.Cardinal.NatCard +public import Mathlib.Topology.Algebra.Ring.Basic + +/-! +# The topology on the standard simplex + +In this file, we define a topology on the standard simplex `StdSimplex R M`. +When `M` is finite, this is the topology that is induced by the +embedding `StdSimplex R M → (M → R)`. In general, we use the supremum of +the coinduced topologies for the maps `StdSimplex.map f : StdSimplex R ι → StdSimplex R M` +where `f : ι → M` is a map from a finite set `ι`. + +-/ + +universe u v + +open Topology + +variable (R : Type u) [PartialOrder R] [Ring R] [TopologicalSpace R] + +namespace Convexity.StdSimplex + +/-- The topology on `StdSimplex R ι` that is induced by the embedding +`StdSimplex R ι → (ι → R)`. This is the correct topoplogy only when +`ι` is finite, see `StdSimplex.isEmbedding_toFun_comp_weights`. -/ +abbrev topologicalSpaceInduced (ι : Type*) : TopologicalSpace (StdSimplex R ι) := + .induced (fun t ↦ t.weights : StdSimplex R ι → ι → R) inferInstance + +namespace topologicalSpaceInduced + +attribute [local instance] topologicalSpaceInduced + +lemma continuous_iff {T ι : Type*} [TopologicalSpace T] (f : T → StdSimplex R ι) : + Continuous f ↔ ∀ (i : ι), Continuous (fun t ↦ (f t).weights i) := by + rw [continuous_induced_rng] + exact continuous_pi_iff + +@[fun_prop] +lemma continuous_weights_apply {ι : Type*} (i : ι) : + Continuous (fun (t : StdSimplex R ι) ↦ t.weights i) := + (continuous_apply i).comp (by rw [continuous_iff_le_induced]) + +open Classical in +@[fun_prop] +lemma continuous_map_weights_apply + [IsStrictOrderedRing R] [IsTopologicalRing R] {ι₁ ι₂ : Type*} + [Finite ι₁] (f : ι₁ → ι₂) (i₂ : ι₂) : + Continuous (fun t ↦ (map (R := R) f t).weights i₂) := by + have := Fintype.ofFinite ι₁ + have (t : StdSimplex R ι₁) : + (map (R := R) f t).weights i₂ = + ∑ i₁ with f i₁ = i₂, t.weights i₁ := by + rw [weights_map, Finsupp.mapDomain_fintype, Finsupp.coe_finsetSum, Finset.sum_apply, + ← Finset.sum_eq_of_subset (s₁ := { i₁ | f i₁ = i₂}) (by simp) + _ (fun i₁ _ hi₁ ↦ Finsupp.single_eq_of_ne' (by simpa using hi₁))] + refine Finset.sum_congr rfl (fun i₁ hi₁ ↦ ?_) + obtain rfl : f i₁ = i₂ := by simpa using hi₁ + simp + simp only [this] + fun_prop + +lemma continuous_map [IsStrictOrderedRing R] [IsTopologicalRing R] + {ι₁ ι₂ : Type*} [Finite ι₁] (f : ι₁ → ι₂) : + Continuous (map (R := R) f) := by + rw [continuous_iff] + fun_prop + +end topologicalSpaceInduced + +variable [IsStrictOrderedRing R] [IsTopologicalRing R] + +attribute [local instance] topologicalSpaceInduced in +/-- This is the topology on `StdSimplex R M` when `M` is a possibly +infinite type. The lemma `StdSimplex.continuous_iff` shows that +this topology is characterized by the fact that a map `f` from +`StdSimplex R M` is continuous iff for any map `g : ι → M` +with a finite `ι`, the composition `f ∘ map g : StdSimplex R ι → _` +is continuous, where `StdSimplex R ι` is equipped with the +topology that is induced by the embedding `StdSimplex R ι → (ι → R)`. -/ +@[no_expose] +public noncomputable instance topologicalSpace (M : Type v) : + TopologicalSpace (StdSimplex R M) := + ⨆ (ι : Type v) (_ : Finite ι) (f : ι → M), .coinduced (map f) inferInstance + +lemma topologicalSpace_eq (M : Type v) [Finite M] : + topologicalSpace R M = topologicalSpaceInduced _ _ := by + refine le_antisymm ?_ ?_ + · exact iSup_le (fun ι ↦ iSup_le (fun _ ↦ iSup_le + (fun f ↦ (topologicalSpaceInduced.continuous_map R f).coinduced_le))) + · refine le_trans ?_ (le_iSup _ M) + refine le_trans ?_ (le_iSup _ (by assumption)) + refine le_trans ?_ (le_iSup _ id) + rw [map_id'] + rfl + +variable {R} in +public lemma continuous_iff + {M : Type v} {T : Type*} [TopologicalSpace T] (f : StdSimplex R M → T) : + Continuous f ↔ + ∀ (ι : Type v) [Finite ι] (g : ι → M), Continuous (f ∘ map g) := by + rw [continuous_iSup_dom] + refine forall_congr' (fun ι ↦ ?_) + rw [continuous_iSup_dom] + refine forall_congr' (fun _ ↦ ?_) + rw [continuous_iSup_dom] + refine forall_congr' (fun M ↦ ?_) + rw [continuous_coinduced_dom, topologicalSpace_eq] + +@[fun_prop] +public lemma continuous_map {M : Type*} {N : Type v} (f : M → N) : + Continuous (map (R := R) f) := by + wlog h : Finite M generalizing M + · rw [continuous_iff] + intro ι _ g + rw [← map_comp'] + exact this (f ∘ g) inferInstance + have H {ι : Type v} [Finite ι] (g : ι → N) : Continuous (map (R := R) g) := by + rw [continuous_iff_coinduced_le] + refine le_trans ?_ (le_iSup _ ι) + refine le_trans ?_ (le_iSup _ (by assumption)) + refine le_trans ?_ (le_iSup _ g) + rw [topologicalSpace_eq] + obtain ⟨ι, _, ⟨e⟩⟩ : ∃ (ι : Type v) (_ : Finite ι), Nonempty (M ≃ ι) := + ⟨_, inferInstance, ⟨(Finite.equivFin M).trans Equiv.ulift.{v}.symm⟩⟩ + have : Continuous (map (R := R) e) := by + rw [topologicalSpace_eq, topologicalSpace_eq] + apply topologicalSpaceInduced.continuous_map + convert (H (f ∘ e.symm)).comp this + rw [← map_comp', Function.comp_assoc, Equiv.symm_comp_self, Function.comp_id] + +open Classical in +/-- Same as `StdSimplex.continuous_iff` but we only consider inclusions of +finite subsets of `M` instead of all maps `ι → M` for arbitrary finite types `ι`. -/ +public lemma continuous_iff' + {M T : Type*} [TopologicalSpace T] (f : StdSimplex R M → T) : + Continuous f ↔ ∀ (s : Finset M), Continuous (f ∘ map (Subtype.val : s → M)) := by + rw [continuous_iff] + refine ⟨fun h s ↦ h _ _, fun h ι _ g ↦ ?_⟩ + have := Fintype.ofFinite ι + have := (h (Finset.image g .univ)).comp (continuous_map R (fun i ↦ ⟨g i, by grind⟩)) + rwa [Function.comp_assoc, ← map_comp'] at this + +open topologicalSpaceInduced in +@[fun_prop] +public lemma continuous_weights_apply {M : Type*} (m : M) : + Continuous (fun (t : StdSimplex R M) ↦ t.weights m) := by + rw [continuous_iff] + intro ι _ g + rw [topologicalSpace_eq] + exact continuous_map_weights_apply R g m + +public lemma isEmbedding_toFun_comp_weights (M : Type*) [Finite M] : + IsEmbedding (fun t ↦ t.weights : StdSimplex R M → M → R) where + eq_induced := by rw [topologicalSpace_eq] + injective _ _ h := by ext; apply congr_fun h + +public lemma isClosedEmbedding_toFun_comp_weights + [OrderClosedTopology R] (M : Type*) [Finite M] : + IsClosedEmbedding (fun t ↦ t.weights : StdSimplex R M → M → R) where + toIsEmbedding := isEmbedding_toFun_comp_weights R M + isClosed_range := by + have := Fintype.ofFinite M + rw [range_toFun_comp_weights] + refine IsClosed.inter (isClosed_iInter (fun _ ↦ isClosed_le ?_ ?_)) + (isClosed_eq ?_ ?_) + all_goals fun_prop + +end Convexity.StdSimplex diff --git a/Mathlib/LinearAlgebra/Vandermonde.lean b/Mathlib/LinearAlgebra/Vandermonde.lean index 5822e62d221874..ddf84df393ba84 100644 --- a/Mathlib/LinearAlgebra/Vandermonde.lean +++ b/Mathlib/LinearAlgebra/Vandermonde.lean @@ -270,7 +270,8 @@ theorem eval_matrixOfPolynomials_eq_vandermonde_mul_matrixOfPolynomials (v : Fin simp_rw [Matrix.mul_apply, eval, Matrix.of_apply, eval₂_eq_sum] simp only [Matrix.vandermonde] have : (p j).support ⊆ range n := supp_subset_range <| Nat.lt_of_le_of_lt (h_deg j) <| Fin.prop j - rw [sum_eq_of_subset _ (fun j => zero_mul ((v i) ^ j)) this, ← Fin.sum_univ_eq_sum_range] + rw [Polynomial.sum_eq_of_subset _ (fun j => zero_mul ((v i) ^ j)) this, + ← Fin.sum_univ_eq_sum_range] congr ext k rw [mul_comm, Matrix.of_apply, RingHom.id_apply] From 4e9f33fff31168d1a915e544f4f0dfc76f3201be Mon Sep 17 00:00:00 2001 From: Oliver Nash <7734364+ocfnash@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:45:27 +0000 Subject: [PATCH 1289/1300] chore: improve `Set` / `Finset` congruence API (#42640) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These changes concern the following four equivalences: ```lean variable {α β : Type*} example (e : α ≃ β) : Set α ≃ Set β := Equiv.Set.congr e -- No change example (e : α ≃ β) : Finset α ≃ Finset β := Equiv.finsetCongr e -- Rename to `Equiv.Finset.congr` example {s t : Set α} (h : s = t) : s ≃ t := Equiv.setCongr h -- No change example {s t : Finset α} (h : s = t) : s ≃ t := sorry -- Missing: add as `Equiv.finsetCongr` ``` In summary we essentially implement two changes: 1. Rename the existing `Equiv.finsetCongr` to `Equiv.Finset.congr` since it is currently inconsistent with both `Equiv.Set.congr` and `Equiv.setCongr` 2. Fill a gap by giving the the now-available `Equiv.finsetCongr` name to the `Finset` version of `Equiv.setCongr` --- Mathlib/Algebra/Order/Antidiag/Pi.lean | 9 ++-- .../Combinatorics/Additive/Dissociation.lean | 4 +- Mathlib/Combinatorics/Young/YoungDiagram.lean | 4 +- Mathlib/Data/Finset/Image.lean | 50 +++++++++++++++---- Mathlib/Logic/Equiv/Set.lean | 8 ++- Mathlib/Topology/Irreducible.lean | 4 +- 6 files changed, 59 insertions(+), 20 deletions(-) diff --git a/Mathlib/Algebra/Order/Antidiag/Pi.lean b/Mathlib/Algebra/Order/Antidiag/Pi.lean index 10dfd75c03ab53..3b28dc83d10792 100644 --- a/Mathlib/Algebra/Order/Antidiag/Pi.lean +++ b/Mathlib/Algebra/Order/Antidiag/Pi.lean @@ -141,13 +141,16 @@ variable {s : Finset ι} {n : μ} {f : ι → μ} lemma piAntidiag_empty (n : μ) : piAntidiag (∅ : Finset ι) n = if n = 0 then {0} else ∅ := by split_ifs with hn <;> simp [*] -lemma finsetCongr_piAntidiag_eq_antidiag (n : μ) : - Equiv.finsetCongr (Equiv.boolArrowEquivProd _) (piAntidiag univ n) = antidiagonal n := by +lemma finset_congr_piAntidiag_eq_antidiag (n : μ) : + Equiv.Finset.congr (Equiv.boolArrowEquivProd _) (piAntidiag univ n) = antidiagonal n := by ext ⟨x₁, x₂⟩ - simp_rw [Equiv.finsetCongr_apply, mem_map, Equiv.toEmbedding, Function.Embedding.coeFn_mk, + simp_rw [Equiv.Finset.congr_apply, mem_map, Equiv.toEmbedding, Function.Embedding.coeFn_mk, ← Equiv.eq_symm_apply] simp [add_comm] +@[deprecated (since := "2026-08-11")] +alias finsetCongr_piAntidiag_eq_antidiag := finset_congr_piAntidiag_eq_antidiag + end AddCommMonoid section AddCancelCommMonoid diff --git a/Mathlib/Combinatorics/Additive/Dissociation.lean b/Mathlib/Combinatorics/Additive/Dissociation.lean index fb6a16620d56c6..31c7fcf0b79284 100644 --- a/Mathlib/Combinatorics/Additive/Dissociation.lean +++ b/Mathlib/Combinatorics/Additive/Dissociation.lean @@ -79,8 +79,8 @@ lemma not_mulDissociated_iff_exists_disjoint : @[to_additive (attr := simp)] lemma MulEquiv.mulDissociated_preimage (e : β ≃* α) : MulDissociated (e ⁻¹' s) ↔ MulDissociated s := by - simp [MulDissociated, InjOn, ← e.finsetCongr.forall_congr_right, ← e.apply_eq_iff_eq, - (Finset.map_injective _).eq_iff] + simp [MulDissociated, InjOn, ← (Equiv.Finset.congr e.toEquiv).forall_congr_right, + ← e.apply_eq_iff_eq, (Finset.map_injective _).eq_iff] @[to_additive (attr := simp)] lemma mulDissociated_inv : MulDissociated s⁻¹ ↔ MulDissociated s := (MulEquiv.inv α).mulDissociated_preimage diff --git a/Mathlib/Combinatorics/Young/YoungDiagram.lean b/Mathlib/Combinatorics/Young/YoungDiagram.lean index 3b7180b0fd6aac..7c29256ed40301 100644 --- a/Mathlib/Combinatorics/Young/YoungDiagram.lean +++ b/Mathlib/Combinatorics/Young/YoungDiagram.lean @@ -184,9 +184,9 @@ section Transpose /-- The `transpose` of a Young diagram is obtained by swapping i's with j's. -/ def transpose (μ : YoungDiagram) : YoungDiagram where - cells := (Equiv.prodComm _ _).finsetCongr μ.cells + cells := Equiv.Finset.congr (Equiv.prodComm _ _) μ.cells isLowerSet _ _ h := by - simp only [Finset.mem_coe, Equiv.finsetCongr_apply, Finset.mem_map_equiv] + simp only [Finset.mem_coe, Equiv.Finset.congr_apply, Finset.mem_map_equiv] intro hcell apply μ.isLowerSet _ hcell simp [h] diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index 1d13014ff47769..e8e6ef37457c1c 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -741,36 +741,68 @@ theorem Multiset.toFinset_map [DecidableEq α] [DecidableEq β] (f : α → β) namespace Equiv -/-- Given an equivalence `α` to `β`, produce an equivalence between `Finset α` and `Finset β`. -/ -protected def finsetCongr (e : α ≃ β) : Finset α ≃ Finset β where +/-- The subtypes corresponding to equal finsets are equivalent. + +See also `Equiv.setCongr`. -/ +@[simps!] def finsetCongr {s t : Finset α} (h : s = t) : + s ≃ t := + .subtypeEquivProp <| by simp [h] + +@[simp] lemma finsetCongr_refl {s : Finset α} : finsetCongr (s := s) rfl = .refl _ := rfl + +lemma finsetCongr_symm {s t : Finset α} (h : s = t) : + finsetCongr h.symm = (finsetCongr h).symm := rfl + +lemma finsetCongr_trans {s t u : Finset α} (h : s = t) (h' : t = u) : + finsetCongr (h.trans h') = (finsetCongr h).trans (finsetCongr h') := + rfl + +namespace Finset + +/-- If `α` is equivalent to `β`, then `Finset α` is equivalent to `Finset β`. + +See also `Equiv.Set.congr`. -/ +protected def congr (e : α ≃ β) : Finset α ≃ Finset β where toFun s := s.map e.toEmbedding invFun s := s.map e.symm.toEmbedding left_inv s := by simp [Finset.map_map] right_inv s := by simp [Finset.map_map] @[simp] -theorem finsetCongr_apply (e : α ≃ β) (s : Finset α) : e.finsetCongr s = s.map e.toEmbedding := +theorem congr_apply (e : α ≃ β) (s : Finset α) : Equiv.Finset.congr e s = s.map e.toEmbedding := rfl +@[deprecated (since := "2026-08-11")] alias finsetCongr_apply := congr_apply + @[simp] -theorem finsetCongr_refl : (Equiv.refl α).finsetCongr = Equiv.refl _ := by +theorem congr_refl : Equiv.Finset.congr (Equiv.refl α) = Equiv.refl _ := by ext simp +@[deprecated (since := "2026-08-11")] alias finsetCongr_refl := congr_refl + @[simp] -theorem finsetCongr_symm (e : α ≃ β) : e.finsetCongr.symm = e.symm.finsetCongr := +theorem congr_symm (e : α ≃ β) : (Equiv.Finset.congr e).symm = Equiv.Finset.congr e.symm := rfl +@[deprecated (since := "2026-08-11")] alias finsetCongr_symm := congr_symm + @[simp] -theorem finsetCongr_trans (e : α ≃ β) (e' : β ≃ γ) : - e.finsetCongr.trans e'.finsetCongr = (e.trans e').finsetCongr := by +theorem congr_trans (e : α ≃ β) (e' : β ≃ γ) : + (Equiv.Finset.congr e).trans (Equiv.Finset.congr e') = Equiv.Finset.congr (e.trans e') := by ext simp [-Finset.mem_map, -Equiv.trans_toEmbedding] -theorem finsetCongr_toEmbedding (e : α ≃ β) : - e.finsetCongr.toEmbedding = (Finset.mapEmbedding e.toEmbedding).toEmbedding := +@[deprecated (since := "2026-08-11")] alias finsetCongr_trans := congr_trans + +theorem congr_toEmbedding (e : α ≃ β) : + (Equiv.Finset.congr e).toEmbedding = (Finset.mapEmbedding e.toEmbedding).toEmbedding := rfl +@[deprecated (since := "2026-08-11")] alias finsetCongr_toEmbedding := congr_toEmbedding + +end Finset + set_option backward.isDefEq.respectTransparency false in /-- Given a predicate `p : α → Prop`, produces an equivalence between `Finset {a : α // p a}` and `{s : Finset α // ∀ a ∈ s, p a}`. -/ diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index 10ebd7f6d4fb98..1936310085d556 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -152,7 +152,9 @@ def setProdEquivSigma {α β : Type*} (s : Set (α × β)) : toFun x := ⟨x.1.1, x.1.2, by simp⟩ invFun x := ⟨(x.1, x.2.1), x.2.2⟩ -/-- The subtypes corresponding to equal sets are equivalent. -/ +/-- The subtypes corresponding to equal sets are equivalent. + +See also `Equiv.finsetCongr`. -/ @[simps! apply symm_apply] def setCongr {α : Type*} {s t : Set α} (h : s = t) : s ≃ t := subtypeEquivProp <| h ▸ rfl @@ -439,7 +441,9 @@ theorem image_symm_preimage {α β} {f : α → β} (hf : Injective f) (u s : Se ext ⟨b, a, has, rfl⟩ simp [hf.eq_iff] -/-- If `α` is equivalent to `β`, then `Set α` is equivalent to `Set β`. -/ +/-- If `α` is equivalent to `β`, then `Set α` is equivalent to `Set β`. + +See also `Equiv.Finset.congr`. -/ @[simps] protected def congr {α β : Type*} (e : α ≃ β) : Set α ≃ Set β := ⟨fun s => e '' s, fun t => e.symm '' t, symm_image_image e, symm_image_image e.symm⟩ diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 1b9488ed10d67b..c964d88b4c91db 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -313,8 +313,8 @@ theorem isIrreducible_iff_sUnion_isClosed : IsIrreducible s ↔ ∀ t : Finset (Set X), (∀ z ∈ t, IsClosed z) → (s ⊆ ⋃₀ ↑t) → ∃ z ∈ t, s ⊆ z := by simp only [isIrreducible_iff_sInter] - refine ((@compl_involutive (Set X) _).toPerm _).finsetCongr.forall_congr fun {t} => ?_ - simp_rw [Equiv.finsetCongr_apply, Finset.forall_mem_map, Finset.mem_map, Finset.coe_map, + refine (Equiv.Finset.congr ((@compl_involutive (Set X) _).toPerm _)).forall_congr fun {t} => ?_ + simp_rw [Equiv.Finset.congr_apply, Finset.forall_mem_map, Finset.mem_map, Finset.coe_map, sUnion_image, Equiv.coe_toEmbedding, Function.Involutive.coe_toPerm, isClosed_compl_iff, exists_exists_and_eq_and] refine forall_congr' fun _ => Iff.trans ?_ not_imp_not From abea25c40f32fe4590031e9ad5242f1917937093 Mon Sep 17 00:00:00 2001 From: "mathlib-update-dependencies[bot]" <258990618+mathlib-update-dependencies[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:45:30 +0000 Subject: [PATCH 1290/1300] chore: update Mathlib dependencies 2026-08-11 (#42651) This PR updates the Mathlib dependencies. --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 0627cad184fddf..20a42d53bea692 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "01bc479e7432594821ba3fb0ca465211941de86d", + "rev": "9a86b38593ce6411eb26cc53e512392e12cd8939", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From ac47869476d367300219cbbb258ca07760b89821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:58:28 +0000 Subject: [PATCH 1291/1300] chore(Algebra/Homology): make `HomologicalComplex.eval` `implicit_reducible` (#42648) --- Mathlib/Algebra/Homology/Additive.lean | 31 +++++-------------- .../Algebra/Homology/HomologicalComplex.lean | 8 ++--- Mathlib/CategoryTheory/GradedObject.lean | 2 +- 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 0165862beb993a..213beac6af74d7 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -103,13 +103,13 @@ This is sometimes called the "prolongation". def Functor.mapHomologicalComplex (F : W₁ ⥤ W₂) [F.PreservesZeroMorphisms] (c : ComplexShape ι) : HomologicalComplex W₁ c ⥤ HomologicalComplex W₂ c where obj C := - { X := fun i => F.obj (C.X i) - d := fun i j => F.map (C.d i j) - shape := fun i j w => by + { X i := F.obj (C.X i) + d i j := F.map (C.d i j) + shape i j w := by rw [C.shape _ _ w, F.map_zero] d_comp_d' := fun i j k _ _ => by rw [← F.map_comp, C.d_comp_d, F.map_zero] } map f := - { f := fun i => F.map (f.f i) + { f i := F.map (f.f i) comm' := fun i j _ => by dsimp rw [← F.map_comp, ← F.map_comp, f.comm] } @@ -122,8 +122,6 @@ instance Functor.map_homogical_complex_additive (F : V ⥤ W) [F.Additive] (c : variable (W₁) -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- The functor on homological complexes induced by the identity functor is isomorphic to the identity functor. -/ @[simps!] @@ -148,7 +146,6 @@ instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] : ext exact F.map_injective ((HomologicalComplex.eval W c _).congr_map h) -set_option backward.isDefEq.respectTransparency.types false in instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] [F.Full] : (F.mapHomologicalComplex c).Full where map_surjective {X Y} f := ⟨ @@ -160,7 +157,6 @@ instance (F : V ⥤ W) [F.Additive] (c : ComplexShape ι) [F.Faithful] [F.Full] variable {W₁} -set_option backward.defeqAttrib.useBackward true in /-- A natural transformation between functors induces a natural transformation between those functors applied to homological complexes. -/ @@ -215,12 +211,10 @@ def Functor.mapHomologicalComplexCompIso {W' : Type*} [Category W'] [Preadditive F.mapHomologicalComplex c ⋙ G.mapHomologicalComplex c ≅ H.mapHomologicalComplex c := NatIso.mapHomologicalComplex e c -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in /-- An equivalence of categories induces an equivalences between the respective categories of homological complex. -/ -@[simps] +@[implicit_reducible, simps] def Equivalence.mapHomologicalComplex (e : W₁ ≌ W₂) [e.functor.PreservesZeroMorphisms] (c : ComplexShape ι) : HomologicalComplex W₁ c ≌ HomologicalComplex W₂ c where @@ -237,16 +231,12 @@ namespace ChainComplex variable {α : Type*} [AddRightCancelSemigroup α] [One α] [DecidableEq α] -set_option backward.isDefEq.respectTransparency.types false in -set_option backward.defeqAttrib.useBackward true in theorem map_chain_complex_of (F : W₁ ⥤ W₂) [F.PreservesZeroMorphisms] (X : α → W₁) (d : ∀ n, X (n + 1) ⟶ X n) (sq : ∀ n, d (n + 1) ≫ d n = 0) : (F.mapHomologicalComplex _).obj (ChainComplex.of X d sq) = ChainComplex.of (fun n => F.obj (X n)) (fun n => F.map (d n)) fun n => by - rw [← F.map_comp, sq n, Functor.map_zero] := by - refine HomologicalComplex.ext rfl ?_ - rintro i j (rfl : j + 1 = i) - simp + rw [← F.map_comp, sq n, Functor.map_zero] := + HomologicalComplex.ext rfl (by cat_disch) end ChainComplex @@ -254,16 +244,13 @@ variable [HasZeroObject W₁] [HasZeroObject W₂] namespace HomologicalComplex -set_option backward.isDefEq.respectTransparency false in instance (W : Type*) [Category* W] [Preadditive W] [HasZeroObject W] [DecidableEq ι] (j : ι) : (single W c j).Additive where - map_add {_ _ f g} := by ext; simp [single] + map_add {_ _ f g} := by ext; simp [single_map_f_self] variable (F : W₁ ⥤ W₂) [F.PreservesZeroMorphisms] (c : ComplexShape ι) [DecidableEq ι] -set_option backward.defeqAttrib.useBackward true in -set_option backward.isDefEq.respectTransparency false in /-- Turning an object into a complex supported at `j` then applying a functor is the same as applying the functor then forming the complex. -/ @@ -294,7 +281,6 @@ noncomputable def singleMapHomologicalComplex (j : ι) : simp [single_map_f_self, singleObjXSelf, singleObjXIsoOfEq, eqToHom_map] · apply (isZero_single_obj_X c j _ _ h).eq_of_tgt -set_option backward.defeqAttrib.useBackward true in @[simp] theorem singleMapHomologicalComplex_hom_app_self (j : ι) (X : W₁) : ((singleMapHomologicalComplex F c j).hom.app X).f j = @@ -306,7 +292,6 @@ theorem singleMapHomologicalComplex_hom_app_ne {i j : ι} (h : i ≠ j) (X : W ((singleMapHomologicalComplex F c j).hom.app X).f i = 0 := by simp [singleMapHomologicalComplex, h] -set_option backward.defeqAttrib.useBackward true in @[simp] theorem singleMapHomologicalComplex_inv_app_self (j : ι) (X : W₁) : ((singleMapHomologicalComplex F c j).inv.app X).f j = diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index e2780152484335..50646b814429df 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -351,16 +351,14 @@ instance : (forget V c).Faithful where ext i exact congr_fun h i -set_option backward.defeqAttrib.useBackward true in /-- Forgetting the differentials than picking out the `i`-th object is the same as just picking out the `i`-th object. -/ -@[simps!] +@[implicit_reducible, simps!] def forgetEval (i : ι) : forget V c ⋙ GradedObject.eval i ≅ eval V c i := NatIso.ofComponents fun _ => Iso.refl _ -set_option backward.defeqAttrib.useBackward true in /-- The differential as a natural transformation between `eval`. -/ -@[simps] def dNatTrans (i j : ι) : +@[implicit_reducible, simps] def dNatTrans (i j : ι) : HomologicalComplex.eval V c i ⟶ HomologicalComplex.eval V c j where app X := X.d i j @@ -642,7 +640,6 @@ variable {V} {α : Type*} [AddRightCancelSemigroup α] [One α] [DecidableEq α] def of.d (X : α → V) (d : ∀ n, X (n + 1) ⟶ X n) (i : α) (j : α) : X i ⟶ X j := if h : i = j + 1 then eqToHom (by rw [h]) ≫ d j else 0 -set_option backward.defeqAttrib.useBackward true in /-- Construct an `α`-indexed chain complex from a dependently-typed differential. -/ abbrev of (X : α → V) (d : ∀ n, X (n + 1) ⟶ X n) (sq : ∀ n, d (n + 1) ≫ d n = 0) : @@ -903,7 +900,6 @@ variable {V} {α : Type*} [AddRightCancelSemigroup α] [One α] [DecidableEq α] def of.d (X : α → V) (d : ∀ n, X n ⟶ X (n + 1)) (i : α) (j : α) : X i ⟶ X j := if h : i + 1 = j then d _ ≫ eqToHom (by rw [h]) else 0 -set_option backward.defeqAttrib.useBackward true in /-- Construct an `α`-indexed cochain complex from a dependently-typed differential. -/ abbrev of (X : α → V) (d : ∀ n, X n ⟶ X (n + 1)) (sq : ∀ n, d n ≫ d (n + 1) = 0) : diff --git a/Mathlib/CategoryTheory/GradedObject.lean b/Mathlib/CategoryTheory/GradedObject.lean index d9092650a09a04..bc3b626cf46bed 100644 --- a/Mathlib/CategoryTheory/GradedObject.lean +++ b/Mathlib/CategoryTheory/GradedObject.lean @@ -71,7 +71,7 @@ lemma hom_ext {β : Type*} {X Y : GradedObject β C} (f g : X ⟶ Y) (h : ∀ x, apply h /-- The projection of a graded object to its `i`-th component. -/ -@[simps] +@[implicit_reducible, simps] def eval {β : Type w} (b : β) : GradedObject β C ⥤ C where obj X := X b map f := f b From f5809ef6d5ca171b70db20940625e4f6f36ddee8 Mon Sep 17 00:00:00 2001 From: Noah Walker <30136151+NoahW314@users.noreply.github.com> Date: Tue, 11 Aug 2026 20:25:43 +0000 Subject: [PATCH 1292/1300] chore(Algebra/Order/GroupWithZero/Canonical): remove unnecessary typeclass assumptions (#42539) `IsReduced` and `NoZeroDivisors` can already be inferred from `LinearOrderedCommMonoidWithZero`. Co-authored-by: NoahW314 Co-authored-by: Monica Omar <23701951+themathqueen@users.noreply.github.com> --- Mathlib/Algebra/Order/GroupWithZero/Canonical.lean | 2 -- Mathlib/RingTheory/Valuation/Basic.lean | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index f319d9e980a3bb..52d15e19a96f24 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -104,8 +104,6 @@ instance instLinearOrderedAddCommMonoidWithTopOrderDualAdditive : top_add' a := by ext; simp; simp [bot_eq_zero (α := α)] isAddLeftRegular_of_ne_top := by simp; simp +contextual [bot_eq_zero, IsRegular.of_ne_zero] -variable [IsReduced α] - lemma pow_pos_iff (hn : n ≠ 0) : 0 < a ^ n ↔ 0 < a := by simp_rw [pos_iff_ne_zero, pow_ne_zero_iff hn] diff --git a/Mathlib/RingTheory/Valuation/Basic.lean b/Mathlib/RingTheory/Valuation/Basic.lean index 744371cf19ddec..ed8b787f132fa3 100644 --- a/Mathlib/RingTheory/Valuation/Basic.lean +++ b/Mathlib/RingTheory/Valuation/Basic.lean @@ -1041,7 +1041,7 @@ theorem mem_supp_iff (x : R) : x ∈ supp v ↔ v x = 0 := Iff.rfl /-- The support of a valuation is a prime ideal. -/ -instance [Nontrivial Γ₀] [NoZeroDivisors Γ₀] : Ideal.IsPrime (supp v) := +instance [Nontrivial Γ₀] : Ideal.IsPrime (supp v) := ⟨fun h => one_ne_zero (α := Γ₀) <| calc From f01aa3455a1c0b2b76f1c298bd30e75d1c1aa68f Mon Sep 17 00:00:00 2001 From: Marcelo Lynch Date: Tue, 11 Aug 2026 21:14:20 +0000 Subject: [PATCH 1293/1300] chore: remove unused open declarations (#42235) This PR removes namespaces from `open` commands when no declaration of the scope uses them. Found the candidates with metaprogramming, then double checked file by file. The linter used for this itself is not proposed for adoption (the approach is prone to false positives) but these verified removals still stand. Unused `open` declarations carry two costs: they invite ambiguous-reference errors for later edits in the scope, and they misdescribe the dependencies of the file to readers. There is no performance effect. Zulip discussion: https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Removing.20unnecessary.20.60open.60.20declarations/with/613515627 Co-authored-by: Floris van Doorn --- Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean | 2 +- Mathlib/Algebra/BigOperators/Group/Finset/Pi.lean | 2 -- Mathlib/Algebra/BigOperators/Group/Finset/Preimage.lean | 2 -- Mathlib/Algebra/BigOperators/Group/Finset/Sigma.lean | 2 +- Mathlib/Algebra/BigOperators/Ring/List.lean | 2 +- Mathlib/Algebra/Category/AlgCat/Basic.lean | 2 +- Mathlib/Algebra/Category/BialgCat/Monoidal.lean | 2 +- Mathlib/Algebra/Category/BoolRing.lean | 2 +- Mathlib/Algebra/Category/CommAlgCat/FiniteType.lean | 2 +- Mathlib/Algebra/Category/FGModuleCat/Abelian.lean | 2 +- Mathlib/Algebra/Category/Grp/Abelian.lean | 2 +- Mathlib/Algebra/Category/HopfAlgCat/Monoidal.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/AB.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/Ext/Basic.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/Sheaf/Abelian.lean | 2 +- Mathlib/Algebra/CharP/Reduced.lean | 3 --- Mathlib/Algebra/CharZero/Infinite.lean | 3 --- Mathlib/Algebra/Colimit/Module.lean | 2 -- Mathlib/Algebra/DirectSum/Finsupp.lean | 2 +- Mathlib/Algebra/Field/Basic.lean | 2 +- Mathlib/Algebra/Field/Defs.lean | 2 -- Mathlib/Algebra/Field/GeomSum.lean | 2 +- Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean | 2 +- Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean | 2 -- Mathlib/Algebra/Group/Subgroup/Defs.lean | 2 -- Mathlib/Algebra/GroupWithZero/Action/Faithful.lean | 2 -- Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean | 1 - Mathlib/Algebra/GroupWithZero/Pointwise/Set/Basic.lean | 1 - Mathlib/Algebra/Homology/DerivedCategory/Linear.lean | 2 +- Mathlib/Algebra/Homology/ImageToKernel.lean | 2 -- Mathlib/Algebra/Homology/LeftResolution/Transport.lean | 2 -- Mathlib/Algebra/Homology/ShortComplex/ModuleCat.lean | 2 -- Mathlib/Algebra/Lie/EngelSubalgebra.lean | 2 +- Mathlib/Algebra/Lie/Weights/Linear.lean | 2 -- Mathlib/Algebra/Module/CharacterModule.lean | 2 -- Mathlib/Algebra/Module/Defs.lean | 2 +- Mathlib/Algebra/Module/End.lean | 2 -- Mathlib/Algebra/Module/Equiv/Basic.lean | 2 -- Mathlib/Algebra/Module/GradedModule.lean | 2 +- Mathlib/Algebra/Module/LocalizedModule/Int.lean | 2 -- Mathlib/Algebra/Module/LocalizedModule/Submodule.lean | 2 -- Mathlib/Algebra/Module/NatInt.lean | 2 -- Mathlib/Algebra/Module/PID.lean | 2 -- Mathlib/Algebra/Module/RingHom.lean | 2 +- Mathlib/Algebra/Module/Submodule/Map.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Support.lean | 2 +- Mathlib/Algebra/MvPolynomial/CommRing.lean | 2 +- Mathlib/Algebra/MvPolynomial/PDeriv.lean | 2 +- Mathlib/Algebra/Order/AddTorsor.lean | 2 -- Mathlib/Algebra/Order/Algebra.lean | 2 +- Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean | 2 -- Mathlib/Algebra/Order/Field/GeomSum.lean | 2 +- Mathlib/Algebra/Order/Field/Pointwise.lean | 2 +- Mathlib/Algebra/Order/Floor/Defs.lean | 2 -- Mathlib/Algebra/Order/Floor/Semifield.lean | 2 -- Mathlib/Algebra/Order/Group/Abs.lean | 2 -- Mathlib/Algebra/Order/Group/CompleteLattice.lean | 2 +- Mathlib/Algebra/Order/Group/Defs.lean | 2 -- Mathlib/Algebra/Order/Group/Lattice.lean | 2 -- Mathlib/Algebra/Order/Group/OrderIso.lean | 2 -- Mathlib/Algebra/Order/Group/Pointwise/CompleteLattice.lean | 2 +- Mathlib/Algebra/Order/Group/Unbundled/Abs.lean | 2 -- Mathlib/Algebra/Order/Group/Unbundled/Basic.lean | 2 -- Mathlib/Algebra/Order/Group/Unbundled/Int.lean | 2 +- Mathlib/Algebra/Order/GroupWithZero/Synonym.lean | 3 --- Mathlib/Algebra/Order/Hom/Basic.lean | 2 -- Mathlib/Algebra/Order/Interval/Basic.lean | 2 +- Mathlib/Algebra/Order/Interval/Finset/Basic.lean | 2 +- Mathlib/Algebra/Order/Interval/Finset/SuccPred.lean | 2 +- Mathlib/Algebra/Order/Interval/Set/SuccPred.lean | 2 +- Mathlib/Algebra/Order/Monoid/NatCast.lean | 2 -- Mathlib/Algebra/Order/Monoid/OrderDual.lean | 2 -- Mathlib/Algebra/Order/Monoid/Unbundled/MinMax.lean | 3 --- Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean | 2 -- Mathlib/Algebra/Order/Monoid/WithTop.lean | 2 -- Mathlib/Algebra/Order/Nonneg/Basic.lean | 2 -- Mathlib/Algebra/Order/Nonneg/Field.lean | 2 -- Mathlib/Algebra/Order/Nonneg/Ring.lean | 2 -- Mathlib/Algebra/Order/Ring/Basic.lean | 2 +- Mathlib/Algebra/Order/Ring/Cast.lean | 2 +- Mathlib/Algebra/Order/Ring/Defs.lean | 2 -- Mathlib/Algebra/Order/Ring/GeomSum.lean | 2 +- Mathlib/Algebra/Order/SuccPred/PartialSups.lean | 2 -- Mathlib/Algebra/Order/ZeroLEOne.lean | 2 -- Mathlib/Algebra/Pointwise/Stabilizer.lean | 2 +- Mathlib/Algebra/Polynomial/Cardinal.lean | 2 +- Mathlib/Algebra/Polynomial/Degree/Domain.lean | 2 -- Mathlib/Algebra/Polynomial/Degree/Lemmas.lean | 2 +- Mathlib/Algebra/Polynomial/Degree/Monomial.lean | 2 +- Mathlib/Algebra/Polynomial/Degree/SmallDegree.lean | 2 -- Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean | 2 +- Mathlib/Algebra/Polynomial/Degree/Units.lean | 2 +- Mathlib/Algebra/Polynomial/DenomsClearable.lean | 2 +- Mathlib/Algebra/Polynomial/Eval/Algebra.lean | 2 -- Mathlib/Algebra/Polynomial/Eval/Degree.lean | 2 +- Mathlib/Algebra/Polynomial/Eval/Irreducible.lean | 2 -- Mathlib/Algebra/Polynomial/Eval/SMul.lean | 2 +- Mathlib/Algebra/Polynomial/Inductions.lean | 2 -- Mathlib/Algebra/Polynomial/RingDivision.lean | 2 -- Mathlib/Algebra/Polynomial/Splits.lean | 4 ---- Mathlib/Algebra/Ring/Action/Pointwise/Set.lean | 1 - Mathlib/Algebra/Ring/Basic.lean | 2 -- Mathlib/Algebra/Ring/Commute.lean | 2 -- Mathlib/Algebra/Ring/Defs.lean | 2 -- Mathlib/Algebra/Ring/Parity.lean | 2 -- Mathlib/Algebra/Ring/Periodic.lean | 2 -- Mathlib/Algebra/Ring/Pointwise/Set.lean | 1 - Mathlib/Algebra/Ring/Semiconj.lean | 2 -- Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean | 2 +- Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean | 2 -- Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean | 2 -- Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean | 2 +- .../AlgebraicGeometry/Morphisms/UniversallyInjective.lean | 2 +- Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean | 2 +- Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean | 2 +- Mathlib/AlgebraicGeometry/Sites/Pretopology.lean | 2 +- Mathlib/AlgebraicGeometry/Sites/QuasiCompact.lean | 2 +- Mathlib/AlgebraicGeometry/Sites/Small.lean | 2 +- .../AlgebraicTopology/ModelCategory/FundamentalLemma.lean | 2 +- .../SimplicialSet/AnodyneExtensions/Rank.lean | 2 -- Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean | 2 +- .../SimplicialSet/CompStructTruncated.lean | 2 +- Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean | 2 +- Mathlib/Analysis/Analytic/CPolynomial.lean | 4 +--- Mathlib/Analysis/Analytic/CPolynomialDef.lean | 2 +- Mathlib/Analysis/Analytic/Inverse.lean | 2 +- Mathlib/Analysis/Analytic/IsolatedZeros.lean | 2 +- Mathlib/Analysis/Analytic/Linear.lean | 2 +- Mathlib/Analysis/Analytic/OfScalars.lean | 1 - Mathlib/Analysis/Asymptotics/Defs.lean | 2 +- Mathlib/Analysis/Asymptotics/Lemmas.lean | 2 +- Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean | 2 +- Mathlib/Analysis/BoxIntegral/UnitPartition.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Basic.lean | 2 -- .../CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Extreme.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Matrix.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Multiplier.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Spectrum.lean | 2 +- Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean | 2 +- Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean | 2 +- Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean | 2 +- Mathlib/Analysis/Calculus/Conformal/NormedSpace.lean | 2 +- Mathlib/Analysis/Calculus/ContDiff/Bounds.lean | 2 +- Mathlib/Analysis/Calculus/ContDiff/CPolynomial.lean | 4 +--- Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean | 2 +- Mathlib/Analysis/Calculus/ContDiff/Operations.lean | 2 +- Mathlib/Analysis/Calculus/ContDiff/RCLike.lean | 2 +- Mathlib/Analysis/Calculus/ContDiff/WithLp.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Abs.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Add.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Comp.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Linear.lean | 4 ++-- Mathlib/Analysis/Calculus/Deriv/Mul.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Prod.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Slope.lean | 2 -- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 2 +- Mathlib/Analysis/Calculus/DifferentialForm/VectorField.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Basic.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Comp.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Congr.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Const.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Defs.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Equiv.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/Measurable.lean | 2 -- Mathlib/Analysis/Calculus/FDeriv/Prod.lean | 2 +- Mathlib/Analysis/Calculus/FDeriv/RestrictScalars.lean | 2 +- Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean | 2 +- .../Analysis/Calculus/InverseFunctionTheorem/FDeriv.lean | 4 ++-- Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean | 2 +- Mathlib/Analysis/Calculus/ParametricIntervalIntegral.lean | 2 +- Mathlib/Analysis/Calculus/SmoothSeries.lean | 2 +- Mathlib/Analysis/Calculus/TangentCone/Basic.lean | 2 +- Mathlib/Analysis/Calculus/TangentCone/Defs.lean | 2 +- Mathlib/Analysis/Calculus/TangentCone/DimOne.lean | 2 +- Mathlib/Analysis/Complex/AbsMax.lean | 2 +- Mathlib/Analysis/Complex/Harmonic/Analytic.lean | 2 +- Mathlib/Analysis/Complex/Harmonic/Poisson.lean | 2 +- Mathlib/Analysis/Complex/Liouville.lean | 2 +- Mathlib/Analysis/Complex/LocallyUniformLimit.lean | 2 +- Mathlib/Analysis/Complex/MeanValue.lean | 2 +- Mathlib/Analysis/Complex/Norm.lean | 2 +- Mathlib/Analysis/Complex/ReImTopology.lean | 2 +- Mathlib/Analysis/Complex/Schwarz.lean | 2 +- Mathlib/Analysis/Complex/Trigonometric.lean | 4 ++-- Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean | 2 +- Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean | 2 +- .../Complex/ValueDistribution/CharacteristicFunction.lean | 2 +- .../Complex/ValueDistribution/FirstMainTheorem.lean | 2 +- Mathlib/Analysis/Convex/Cone/Basic.lean | 2 +- Mathlib/Analysis/Convex/Deriv.lean | 2 +- Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean | 2 +- Mathlib/Analysis/Convex/Exposed.lean | 2 +- Mathlib/Analysis/Convex/Extreme.lean | 2 +- Mathlib/Analysis/Convex/Function.lean | 2 +- Mathlib/Analysis/Convex/Independent.lean | 2 +- Mathlib/Analysis/Convex/Jensen.lean | 2 +- Mathlib/Analysis/Convex/LinearIsometry.lean | 2 +- Mathlib/Analysis/Convex/MetricSpace.lean | 2 -- Mathlib/Analysis/Convex/Segment.lean | 2 -- Mathlib/Analysis/Convex/StrictConvexBetween.lean | 1 - Mathlib/Analysis/Convex/StrictConvexSpace.lean | 2 +- Mathlib/Analysis/Convex/Uniform.lean | 5 ----- Mathlib/Analysis/Convolution.lean | 2 +- Mathlib/Analysis/Distribution/DerivNotation.lean | 2 +- Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean | 2 +- Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean | 2 +- Mathlib/Analysis/Distribution/TestFunction.lean | 2 +- Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean | 2 +- Mathlib/Analysis/Fourier/FiniteAbelian/Orthogonality.lean | 2 +- Mathlib/Analysis/Fourier/Inversion.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Calculus.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Continuous.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Convex.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Defs.lean | 2 +- Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean | 4 ++-- .../InnerProductSpace/Harmonic/HarmonicContOnCl.lean | 2 +- Mathlib/Analysis/InnerProductSpace/LaxMilgram.lean | 2 +- Mathlib/Analysis/InnerProductSpace/LinearMap.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Orthonormal.lean | 2 +- .../InnerProductSpace/Projection/FiniteDimensional.lean | 2 +- .../Analysis/InnerProductSpace/Projection/Submodule.lean | 2 +- Mathlib/Analysis/InnerProductSpace/StandardSubspace.lean | 2 +- Mathlib/Analysis/InnerProductSpace/Subspace.lean | 2 +- Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean | 2 +- Mathlib/Analysis/LocallyConvex/Montel.lean | 2 +- Mathlib/Analysis/LocallyConvex/Polar.lean | 2 -- Mathlib/Analysis/LocallyConvex/StrongTopology.lean | 3 --- Mathlib/Analysis/Matrix/PosDef.lean | 2 +- Mathlib/Analysis/Meromorphic/RCLike.lean | 2 +- Mathlib/Analysis/Normed/Affine/AddTorsor.lean | 4 +--- Mathlib/Analysis/Normed/Affine/MazurUlam.lean | 2 +- Mathlib/Analysis/Normed/Field/Ultra.lean | 1 - Mathlib/Analysis/Normed/Group/AddTorsor.lean | 2 +- Mathlib/Analysis/Normed/Group/Continuity.lean | 6 ++---- Mathlib/Analysis/Normed/Group/Defs.lean | 4 ++-- Mathlib/Analysis/Normed/Group/Quotient.lean | 2 +- Mathlib/Analysis/Normed/Group/Real.lean | 4 ++-- Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean | 2 +- Mathlib/Analysis/Normed/Group/Subgroup.lean | 4 ---- Mathlib/Analysis/Normed/Group/Uniform.lean | 4 +--- Mathlib/Analysis/Normed/Lp/PiLp.lean | 2 +- Mathlib/Analysis/Normed/Lp/ProdLp.lean | 2 +- Mathlib/Analysis/Normed/Lp/SmoothApprox.lean | 2 +- Mathlib/Analysis/Normed/Module/Alternating/Basic.lean | 2 +- Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean | 2 +- Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean | 2 +- Mathlib/Analysis/Normed/Module/FiniteDimension.lean | 2 -- Mathlib/Analysis/Normed/Module/HahnBanach.lean | 2 -- Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean | 2 +- Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean | 2 +- Mathlib/Analysis/Normed/Module/RieszLemma.lean | 2 -- Mathlib/Analysis/Normed/Operator/Basic.lean | 2 -- Mathlib/Analysis/Normed/Operator/Bilinear.lean | 5 ++--- Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean | 2 +- Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean | 4 ++-- Mathlib/Analysis/Normed/Operator/Mul.lean | 1 - Mathlib/Analysis/Normed/Operator/NNNorm.lean | 1 - Mathlib/Analysis/Normed/Operator/NormedSpace.lean | 2 +- Mathlib/Analysis/Normed/Operator/Prod.lean | 2 +- Mathlib/Analysis/Normed/Order/UpperLower.lean | 2 +- Mathlib/Analysis/Normed/Ring/Ultra.lean | 2 +- Mathlib/Analysis/Normed/Ring/Units.lean | 2 +- Mathlib/Analysis/Normed/Ring/WithAbs.lean | 2 -- Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean | 5 ----- Mathlib/Analysis/ODE/ExistUnique.lean | 2 +- Mathlib/Analysis/ODE/Gronwall.lean | 2 +- Mathlib/Analysis/PSeries.lean | 2 +- Mathlib/Analysis/RCLike/Basic.lean | 2 -- Mathlib/Analysis/RCLike/BoundedContinuous.lean | 2 +- Mathlib/Analysis/Real/Spectrum.lean | 4 ++-- Mathlib/Analysis/Real/Sqrt.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Arcosh.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Artanh.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean | 4 ++-- .../SpecialFunctions/Gaussian/FourierTransform.lean | 2 +- Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Log/Summable.lean | 2 +- .../Analysis/SpecialFunctions/MulExpNegMulSqIntegral.lean | 2 +- .../Analysis/SpecialFunctions/OrdinaryHypergeometric.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Pow/Continuity.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Pow/Real.lean | 4 ++-- Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean | 2 +- .../Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean | 1 - Mathlib/Analysis/SpecificLimits/Normed.lean | 4 +--- Mathlib/Analysis/SpecificLimits/RCLike.lean | 2 +- Mathlib/Analysis/SumIntegralComparisons.lean | 2 +- Mathlib/CategoryTheory/Action/Continuous.lean | 2 +- Mathlib/CategoryTheory/Adjunction/Additive.lean | 2 +- Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean | 2 -- Mathlib/CategoryTheory/Bicategory/Adjunction/Mate.lean | 2 -- .../Bicategory/Functor/Cat/ObjectProperty.lean | 2 -- Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean | 2 -- Mathlib/CategoryTheory/Bicategory/LocallyGroupoid.lean | 2 -- Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean | 2 -- Mathlib/CategoryTheory/Center/Basic.lean | 2 -- Mathlib/CategoryTheory/Comma/Final.lean | 2 +- Mathlib/CategoryTheory/CopyDiscardCategory/Cartesian.lean | 2 -- Mathlib/CategoryTheory/EffectiveEpi/Enough.lean | 2 -- Mathlib/CategoryTheory/Endomorphism.lean | 2 -- Mathlib/CategoryTheory/Enriched/EnrichedCat.lean | 4 ---- Mathlib/CategoryTheory/Equivalence/Symmetry.lean | 2 +- Mathlib/CategoryTheory/Filtered/Flat.lean | 2 -- Mathlib/CategoryTheory/Generator/Preadditive.lean | 2 +- .../CategoryTheory/GuitartExact/HorizontalComposition.lean | 2 -- Mathlib/CategoryTheory/GuitartExact/Opposite.lean | 2 -- Mathlib/CategoryTheory/IsoCat.lean | 2 +- Mathlib/CategoryTheory/Join/Pseudofunctor.lean | 2 +- .../LiftingProperties/ParametrizedAdjunction.lean | 2 +- .../CategoryTheory/Limits/Constructions/Over/Products.lean | 2 -- .../Limits/FormalCoproducts/ExtraDegeneracy.lean | 2 -- .../CategoryTheory/Limits/Preserves/Creates/Opposites.lean | 2 +- Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean | 2 +- Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean | 2 +- .../CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean | 4 ---- .../Limits/Shapes/Pullback/IsPullback/Basic.lean | 2 -- Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean | 6 +----- Mathlib/CategoryTheory/Limits/Types/End.lean | 2 +- Mathlib/CategoryTheory/Limits/Types/Multiequalizer.lean | 2 +- Mathlib/CategoryTheory/Limits/Types/Products.lean | 2 +- .../CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean | 2 +- Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean | 2 +- .../Localization/DerivabilityStructure/Derives.lean | 2 -- .../DerivabilityStructure/PointwiseRightDerived.lean | 2 +- Mathlib/CategoryTheory/Localization/Resolution.lean | 2 -- Mathlib/CategoryTheory/Monoidal/Cartesian/Ring.lean | 2 +- Mathlib/CategoryTheory/Monoidal/CoherenceLemmas.lean | 2 +- .../CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean | 1 - Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean | 2 -- Mathlib/CategoryTheory/MorphismProperty/Comma.lean | 2 -- Mathlib/CategoryTheory/NatIso.lean | 2 -- Mathlib/CategoryTheory/NatTrans.lean | 2 -- Mathlib/CategoryTheory/ObjectProperty/Shift.lean | 2 +- Mathlib/CategoryTheory/Preadditive/Comma.lean | 2 -- Mathlib/CategoryTheory/Preadditive/Mat.lean | 2 -- .../Presentable/CardinalFilteredPresentation.lean | 2 -- Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean | 2 +- Mathlib/CategoryTheory/Sites/Coherent/RegularTopology.lean | 2 -- Mathlib/CategoryTheory/Sites/Grothendieck.lean | 2 -- Mathlib/CategoryTheory/Sites/LocalProperties.lean | 2 +- Mathlib/CategoryTheory/Sites/Localization.lean | 2 -- Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean | 2 +- Mathlib/CategoryTheory/Sites/LocallyInjective.lean | 2 +- Mathlib/CategoryTheory/Skeletal.lean | 4 ---- Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean | 2 +- Mathlib/CategoryTheory/Subobject/Limits.lean | 2 -- Mathlib/CategoryTheory/Yoneda.lean | 2 -- Mathlib/Combinatorics/Additive/SmallTripling.lean | 2 +- Mathlib/Combinatorics/Digraph/Basic.lean | 2 +- Mathlib/Combinatorics/Enumerative/DyckWord.lean | 2 +- Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean | 2 +- Mathlib/Combinatorics/Graph/Delete.lean | 2 +- Mathlib/Combinatorics/Graph/Lattice.lean | 2 +- Mathlib/Combinatorics/Quiver/Arborescence.lean | 3 --- .../SimpleGraph/Extremal/ErdosStoneSimonovits.lean | 2 +- Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean | 2 +- Mathlib/Computability/Halting.lean | 2 +- Mathlib/Computability/Primrec/Basic.lean | 2 +- Mathlib/Computability/TuringDegree.lean | 2 -- Mathlib/Condensed/Basic.lean | 2 +- Mathlib/Condensed/Discrete/Basic.lean | 2 +- Mathlib/Condensed/Light/AB.lean | 2 +- Mathlib/Condensed/Light/Basic.lean | 2 +- Mathlib/Condensed/Solid.lean | 2 +- Mathlib/Control/Fix.lean | 2 -- Mathlib/Control/Random.lean | 2 -- Mathlib/Data/DFinsupp/Module.lean | 2 -- Mathlib/Data/DList/Instances.lean | 2 +- Mathlib/Data/ENNReal/Action.lean | 2 +- Mathlib/Data/ENNReal/Basic.lean | 2 +- Mathlib/Data/ENNReal/Lemmas.lean | 2 +- Mathlib/Data/ENNReal/Real.lean | 4 ++-- Mathlib/Data/EReal/Inv.lean | 2 +- Mathlib/Data/Fin/Tuple/Reflection.lean | 2 +- Mathlib/Data/Finset/Attach.lean | 2 +- Mathlib/Data/Finset/BooleanAlgebra.lean | 2 -- Mathlib/Data/Finset/Dedup.lean | 2 +- Mathlib/Data/Finset/Density.lean | 2 +- Mathlib/Data/Finset/Disjoint.lean | 2 +- Mathlib/Data/Finset/Empty.lean | 4 ++-- Mathlib/Data/Finset/Erase.lean | 2 +- Mathlib/Data/Finset/Lattice/Basic.lean | 2 +- Mathlib/Data/Finset/Lattice/Lemmas.lean | 2 -- Mathlib/Data/Finset/Lattice/Prod.lean | 2 -- Mathlib/Data/Finset/Lattice/Union.lean | 2 +- Mathlib/Data/Finset/Range.lean | 2 +- Mathlib/Data/Finset/SDiff.lean | 2 +- Mathlib/Data/Finset/SymmDiff.lean | 2 +- Mathlib/Data/Fintype/BigOperators.lean | 2 -- Mathlib/Data/Fintype/Fin.lean | 2 -- Mathlib/Data/Fintype/Inv.lean | 4 +--- Mathlib/Data/Fintype/Lattice.lean | 5 ----- Mathlib/Data/Fintype/OfMap.lean | 2 -- Mathlib/Data/Fintype/Sigma.lean | 5 ----- Mathlib/Data/List/Defs.lean | 2 +- Mathlib/Data/List/Map2.lean | 2 -- Mathlib/Data/List/Pairwise.lean | 2 +- Mathlib/Data/List/Perm/Subperm.lean | 2 -- Mathlib/Data/List/Sections.lean | 2 +- Mathlib/Data/List/TakeDrop.lean | 2 -- Mathlib/Data/Multiset/AddSub.lean | 2 +- Mathlib/Data/Multiset/Defs.lean | 2 +- Mathlib/Data/Multiset/Interval.lean | 2 +- Mathlib/Data/Multiset/OrderedMonoid.lean | 2 -- Mathlib/Data/Multiset/Replicate.lean | 2 +- Mathlib/Data/Multiset/UnionInter.lean | 2 +- Mathlib/Data/Multiset/ZeroCons.lean | 2 +- Mathlib/Data/NNRat/Lemmas.lean | 1 - Mathlib/Data/NNReal/Defs.lean | 2 +- Mathlib/Data/Nat/Cast/Basic.lean | 2 -- Mathlib/Data/Nat/Factorization/Induction.lean | 2 +- Mathlib/Data/Nat/Factorization/LCM.lean | 2 +- Mathlib/Data/Nat/Init.lean | 2 -- Mathlib/Data/Prod/TProd.lean | 2 +- Mathlib/Data/Rat/Cast/Order.lean | 2 +- Mathlib/Data/Set/Disjoint.lean | 2 -- Mathlib/Data/Set/Enumerate.lean | 2 -- Mathlib/Data/Set/Finite/Monad.lean | 2 +- Mathlib/Data/Set/Order.lean | 2 -- Mathlib/Data/Set/Pairwise/Basic.lean | 2 +- Mathlib/Data/Set/Piecewise.lean | 2 +- Mathlib/Data/Set/Restrict.lean | 2 +- Mathlib/Data/Set/Subsingleton.lean | 2 -- Mathlib/Data/Sum/Lattice.lean | 2 -- Mathlib/Data/WSeq/Defs.lean | 2 -- Mathlib/Data/WSeq/Productive.lean | 2 -- Mathlib/Data/ZMod/QuotientRing.lean | 2 +- Mathlib/Dynamics/Ergodic/AddCircleAdd.lean | 2 +- Mathlib/Dynamics/Ergodic/Function.lean | 2 +- Mathlib/Dynamics/Flow.lean | 2 +- Mathlib/Dynamics/Newton.lean | 2 +- Mathlib/Dynamics/SymbolicDynamics/Basic.lean | 2 +- Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean | 4 ++-- Mathlib/FieldTheory/AlgebraicClosure.lean | 2 +- Mathlib/FieldTheory/Finite/Polynomial.lean | 2 +- Mathlib/FieldTheory/Finiteness.lean | 2 +- Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean | 2 +- Mathlib/FieldTheory/IsPerfectClosure.lean | 2 +- Mathlib/FieldTheory/JacobsonNoether.lean | 2 +- Mathlib/FieldTheory/Tower.lean | 2 +- Mathlib/Geometry/Convex/Cone/Pointed.lean | 2 +- Mathlib/Geometry/Convex/ConvexSpace/Prod.lean | 2 +- Mathlib/Geometry/Convex/Star.lean | 2 +- Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean | 2 +- Mathlib/Geometry/Euclidean/Angle/Sphere.lean | 2 +- Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean | 2 +- Mathlib/Geometry/Euclidean/Inversion/Basic.lean | 2 +- Mathlib/Geometry/Euclidean/Inversion/Calculus.lean | 2 +- Mathlib/Geometry/Euclidean/Inversion/ImageHyperplane.lean | 2 +- Mathlib/Geometry/Euclidean/Similarity.lean | 2 +- Mathlib/Geometry/Euclidean/Sphere/Power.lean | 2 +- Mathlib/Geometry/Manifold/Bordism.lean | 2 +- Mathlib/Geometry/Manifold/GroupLieAlgebra.lean | 2 +- Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean | 2 -- Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean | 2 +- Mathlib/Geometry/Manifold/Riemannian/Basic.lean | 2 +- Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean | 2 +- Mathlib/Geometry/Manifold/StructureGroupoid.lean | 2 +- Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean | 2 +- Mathlib/Geometry/RingedSpace/OpenImmersion.lean | 2 -- Mathlib/GroupTheory/ClassEquation.lean | 2 +- Mathlib/GroupTheory/Coxeter/Inversion.lean | 2 +- Mathlib/GroupTheory/Coxeter/Length.lean | 2 +- Mathlib/GroupTheory/Index.lean | 2 +- Mathlib/GroupTheory/MonoidLocalization/Away.lean | 2 -- Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean | 2 -- Mathlib/GroupTheory/Perm/Basic.lean | 2 +- Mathlib/GroupTheory/Sylow.lean | 2 +- Mathlib/Lean/FoldEnvironment.lean | 2 +- Mathlib/LinearAlgebra/Basis/Cardinality.lean | 2 +- Mathlib/LinearAlgebra/Basis/Defs.lean | 2 -- Mathlib/LinearAlgebra/Basis/Prod.lean | 2 +- Mathlib/LinearAlgebra/Basis/Submodule.lean | 2 -- Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean | 4 ++-- Mathlib/LinearAlgebra/Complex/Module.lean | 4 +--- Mathlib/LinearAlgebra/DFinsupp.lean | 2 -- Mathlib/LinearAlgebra/Dimension/Constructions.lean | 4 +--- Mathlib/LinearAlgebra/Dimension/DivisionRing.lean | 2 +- Mathlib/LinearAlgebra/Dimension/Finite.lean | 2 +- Mathlib/LinearAlgebra/Dimension/Free.lean | 2 +- Mathlib/LinearAlgebra/Dimension/LinearMap.lean | 2 +- Mathlib/LinearAlgebra/Dimension/RankNullity.lean | 2 +- Mathlib/LinearAlgebra/DirectSum/Finsupp.lean | 2 +- Mathlib/LinearAlgebra/Dual/Basis.lean | 4 ++-- Mathlib/LinearAlgebra/Dual/Lemmas.lean | 2 +- Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean | 2 +- Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean | 6 ++---- Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean | 2 +- Mathlib/LinearAlgebra/Finsupp/LSum.lean | 2 +- Mathlib/LinearAlgebra/Finsupp/SumProd.lean | 2 +- Mathlib/LinearAlgebra/FreeModule/Basic.lean | 2 -- Mathlib/LinearAlgebra/Goursat.lean | 2 +- .../LinearAlgebra/Matrix/ProjectiveSpecialLinearGroup.lean | 2 +- Mathlib/LinearAlgebra/Multilinear/Curry.lean | 2 +- Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean | 2 +- Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean | 2 -- Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean | 2 -- Mathlib/LinearAlgebra/Quotient/Card.lean | 2 -- Mathlib/LinearAlgebra/RootSystem/Chain.lean | 2 +- Mathlib/LinearAlgebra/RootSystem/Hom.lean | 2 +- Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean | 2 +- Mathlib/LinearAlgebra/SModEq/Pointwise.lean | 2 -- Mathlib/LinearAlgebra/TensorProduct/Basis.lean | 2 +- Mathlib/LinearAlgebra/TensorProduct/Vanishing.lean | 2 +- Mathlib/LinearAlgebra/Transvection/Basic.lean | 4 ++-- Mathlib/Logic/Denumerable.lean | 2 +- Mathlib/Logic/Encodable/Basic.lean | 4 ++-- Mathlib/Logic/IsEmpty/Defs.lean | 2 -- Mathlib/Logic/Unique.lean | 2 -- .../MeasureTheory/Constructions/Polish/EmbeddingReal.lean | 2 +- Mathlib/MeasureTheory/Constructions/SimpleGraph.lean | 1 - Mathlib/MeasureTheory/Covering/DensityTheorem.lean | 2 +- Mathlib/MeasureTheory/Function/AEEqFun.lean | 2 +- .../Function/ConditionalExpectation/CondexpL2.lean | 2 +- .../Function/ConditionalExpectation/Indicator.lean | 2 +- .../Function/ConditionalExpectation/PullOut.lean | 2 +- .../MeasureTheory/Function/ConditionalExpectation/Real.lean | 2 +- Mathlib/MeasureTheory/Function/Egorov.lean | 2 +- Mathlib/MeasureTheory/Function/Holder.lean | 2 +- Mathlib/MeasureTheory/Function/JacobianOneDim.lean | 2 +- Mathlib/MeasureTheory/Function/L1Space/AEEqFun.lean | 2 +- .../MeasureTheory/Function/L1Space/HasFiniteIntegral.lean | 2 +- Mathlib/MeasureTheory/Function/L1Space/Integrable.lean | 2 +- Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean | 2 -- Mathlib/MeasureTheory/Group/AddCircle.lean | 2 +- Mathlib/MeasureTheory/Group/FoelnerFilter.lean | 2 +- Mathlib/MeasureTheory/Integral/Average.lean | 2 +- Mathlib/MeasureTheory/Integral/CircleTransform.lean | 2 +- .../MeasureTheory/Integral/IntervalIntegral/ContDiff.lean | 2 +- .../Integral/IntervalIntegral/DistLEIntegral.lean | 2 +- Mathlib/MeasureTheory/Integral/Marginal.lean | 2 +- Mathlib/MeasureTheory/MeasurableSpace/Card.lean | 2 +- Mathlib/MeasureTheory/MeasurableSpace/Defs.lean | 2 +- Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean | 2 +- Mathlib/MeasureTheory/MeasurableSpace/PreorderRestrict.lean | 2 -- Mathlib/MeasureTheory/Measure/AbsolutelyContinuous.lean | 2 +- Mathlib/MeasureTheory/Measure/DiracProba.lean | 2 +- Mathlib/MeasureTheory/Measure/Doubling.lean | 2 +- Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean | 2 +- Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean | 2 +- Mathlib/MeasureTheory/Measure/Haar/Unique.lean | 2 +- Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean | 2 +- Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean | 2 +- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 4 +--- Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean | 2 +- Mathlib/MeasureTheory/Measure/Prod.lean | 4 +--- Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean | 2 +- Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean | 2 +- Mathlib/MeasureTheory/OuterMeasure/Operations.lean | 2 +- Mathlib/MeasureTheory/VectorMeasure/Prod.lean | 2 +- Mathlib/ModelTheory/Bundled.lean | 2 +- Mathlib/ModelTheory/Encoding.lean | 2 +- Mathlib/ModelTheory/Equivalence.lean | 2 -- Mathlib/ModelTheory/Types.lean | 2 +- Mathlib/NumberTheory/AbelSummation.lean | 4 ++-- Mathlib/NumberTheory/ArithmeticFunction/Misc.lean | 2 +- Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean | 2 -- Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean | 2 +- Mathlib/NumberTheory/Chebyshev.lean | 2 +- Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean | 2 +- Mathlib/NumberTheory/FLT/MasonStothers.lean | 2 +- Mathlib/NumberTheory/KummerDedekind.lean | 2 +- Mathlib/NumberTheory/LSeries/DirichletContinuation.lean | 2 +- Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean | 2 +- Mathlib/NumberTheory/Modular.lean | 2 +- Mathlib/NumberTheory/ModularForms/Basic.lean | 2 +- Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean | 2 +- Mathlib/NumberTheory/ModularForms/LFunction.lean | 2 +- .../ModularForms/LevelOne/DimensionFormula.lean | 2 +- Mathlib/NumberTheory/ModularForms/SlashActions.lean | 2 +- Mathlib/NumberTheory/NumberField/AdeleRing.lean | 2 +- Mathlib/NumberTheory/Padics/Hensel.lean | 2 +- Mathlib/NumberTheory/Padics/Measure/Topology.lean | 2 +- Mathlib/NumberTheory/Padics/WithVal.lean | 2 +- Mathlib/NumberTheory/RamificationInertia/Inertia.lean | 2 -- Mathlib/NumberTheory/SelbergSieve.lean | 2 +- .../Transcendental/Liouville/LiouvilleWith.lean | 2 +- Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean | 2 +- Mathlib/Order/Atoms/Finite.lean | 2 -- Mathlib/Order/Birkhoff.lean | 2 +- Mathlib/Order/BooleanAlgebra/Defs.lean | 2 -- Mathlib/Order/BooleanAlgebra/Set.lean | 2 -- Mathlib/Order/BoundedOrder/Lattice.lean | 2 -- Mathlib/Order/Category/HeytAlg.lean | 2 +- Mathlib/Order/CompleteLattice/Defs.lean | 2 +- Mathlib/Order/CompleteLattice/Finset.lean | 2 +- Mathlib/Order/ConditionallyCompletePartialOrder/Basic.lean | 2 +- .../Order/ConditionallyCompletePartialOrder/Indexed.lean | 2 +- Mathlib/Order/Filter/AtTopBot/Finite.lean | 2 +- Mathlib/Order/Filter/Interval.lean | 2 +- Mathlib/Order/Filter/Ring.lean | 2 +- Mathlib/Order/GaloisConnection/Defs.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 2 -- Mathlib/Order/Monotone/Defs.lean | 2 -- Mathlib/Order/TeichmullerTukey.lean | 2 +- Mathlib/Order/Types/Defs.lean | 2 +- Mathlib/Order/ULift.lean | 2 -- Mathlib/Order/UpperLower/Hom.lean | 2 -- Mathlib/Probability/Decision/Risk/Countable.lean | 2 +- Mathlib/Probability/Distributions/Gaussian/CharFun.lean | 2 +- Mathlib/Probability/Distributions/Geometric.lean | 2 +- Mathlib/Probability/Distributions/Pareto.lean | 4 +--- Mathlib/Probability/IdentDistrib.lean | 4 +--- Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean | 2 +- Mathlib/Probability/Kernel/MeasurableLIntegral.lean | 2 +- Mathlib/Probability/Kernel/Proper.lean | 2 +- Mathlib/Probability/Martingale/Basic.lean | 2 +- Mathlib/Probability/Martingale/Centering.lean | 2 +- Mathlib/Probability/Moments/ComplexMGF.lean | 2 +- Mathlib/Probability/Moments/CovarianceBilinDual.lean | 2 +- Mathlib/Probability/Moments/IntegrableExpMul.lean | 2 +- Mathlib/Probability/Moments/MGFAnalytic.lean | 2 +- Mathlib/Probability/Moments/Tilted.lean | 2 +- Mathlib/Probability/ProbabilityMassFunction/Monad.lean | 2 +- Mathlib/Probability/Process/Adapted.lean | 2 +- Mathlib/Probability/Process/Filtration.lean | 2 +- Mathlib/Probability/Process/HittingTime.lean | 2 +- Mathlib/Probability/Process/Predictable.lean | 2 -- Mathlib/Probability/Process/Stopping.lean | 5 ----- .../Homological/ContCohomology/Basic.lean | 2 +- .../Homological/ContCohomology/LowDegree.lean | 2 +- Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean | 2 +- .../Homological/GroupCohomology/Shapiro.lean | 2 +- .../Homological/GroupHomology/FiniteCyclic.lean | 2 +- .../Homological/GroupHomology/Shapiro.lean | 2 +- Mathlib/RepresentationTheory/Induced.lean | 4 ---- Mathlib/RingTheory/AdicCompletion/Algebra.lean | 2 -- Mathlib/RingTheory/AdicCompletion/Topology.lean | 2 +- Mathlib/RingTheory/Adjoin/FG.lean | 2 +- Mathlib/RingTheory/Artinian/Module.lean | 2 +- Mathlib/RingTheory/Binomial.lean | 2 +- Mathlib/RingTheory/Conductor.lean | 2 +- Mathlib/RingTheory/DedekindDomain/Factorization.lean | 2 +- Mathlib/RingTheory/Discriminant.lean | 2 +- Mathlib/RingTheory/FiniteType.lean | 2 -- Mathlib/RingTheory/Finiteness/Cardinality.lean | 1 - Mathlib/RingTheory/Finiteness/Projective.lean | 2 -- Mathlib/RingTheory/Finiteness/Subalgebra.lean | 1 - Mathlib/RingTheory/GradedAlgebra/Homogeneous/Submodule.lean | 2 +- .../RingTheory/GradedAlgebra/HomogeneousLocalization.lean | 4 ++-- Mathlib/RingTheory/HahnSeries/Basic.lean | 2 +- Mathlib/RingTheory/HahnSeries/PowerSeries.lean | 2 +- Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean | 2 -- Mathlib/RingTheory/Ideal/Defs.lean | 2 +- Mathlib/RingTheory/Ideal/Lattice.lean | 2 +- Mathlib/RingTheory/Ideal/Maximal.lean | 2 +- Mathlib/RingTheory/Ideal/Prime.lean | 2 +- Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean | 2 +- Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean | 3 --- Mathlib/RingTheory/LaurentSeries.lean | 4 ++-- Mathlib/RingTheory/LocalProperties/Exactness.lean | 2 -- Mathlib/RingTheory/LocalProperties/Submodule.lean | 2 +- Mathlib/RingTheory/LocalRing/Quotient.lean | 2 +- Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean | 2 +- Mathlib/RingTheory/Localization/Away/Basic.lean | 2 -- Mathlib/RingTheory/Localization/Pi.lean | 2 +- Mathlib/RingTheory/MatrixAlgebra.lean | 2 -- Mathlib/RingTheory/MvPolynomial.lean | 2 +- Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean | 2 -- Mathlib/RingTheory/MvPowerSeries/Order.lean | 2 +- Mathlib/RingTheory/Noetherian/Basic.lean | 2 +- Mathlib/RingTheory/Noetherian/Defs.lean | 2 +- Mathlib/RingTheory/Noetherian/Filter.lean | 4 ++-- Mathlib/RingTheory/Noetherian/Orzech.lean | 3 --- Mathlib/RingTheory/Norm/Basic.lean | 2 +- Mathlib/RingTheory/Norm/Defs.lean | 2 +- Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean | 2 +- Mathlib/RingTheory/Polynomial/Radical.lean | 2 +- Mathlib/RingTheory/Polynomial/RationalRoot.lean | 2 +- Mathlib/RingTheory/PowerSeries/Order.lean | 2 -- Mathlib/RingTheory/PowerSeries/PiTopology.lean | 2 +- Mathlib/RingTheory/Radical/Basic.lean | 1 - Mathlib/RingTheory/RingHom/Bijective.lean | 2 -- Mathlib/RingTheory/RingHomProperties.lean | 2 +- Mathlib/RingTheory/Smooth/Quotient.lean | 2 -- Mathlib/RingTheory/Smooth/StandardSmooth.lean | 2 +- Mathlib/RingTheory/Spectrum/Maximal/Localization.lean | 2 +- Mathlib/RingTheory/Spectrum/Prime/Chevalley.lean | 2 +- Mathlib/RingTheory/TensorProduct/Finite.lean | 1 - Mathlib/RingTheory/TensorProduct/MvPolynomial.lean | 4 ++-- Mathlib/RingTheory/Trace/Quotient.lean | 2 +- Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean | 2 +- Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean | 2 -- Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean | 2 -- Mathlib/RingTheory/WittVector/Domain.lean | 2 -- Mathlib/RingTheory/WittVector/StructurePolynomial.lean | 2 +- Mathlib/RingTheory/WittVector/TeichmullerSeries.lean | 2 +- Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean | 2 +- Mathlib/SetTheory/Cardinal/Defs.lean | 2 +- Mathlib/SetTheory/Cardinal/NatCount.lean | 2 +- Mathlib/SetTheory/Cardinal/Order.lean | 2 +- Mathlib/SetTheory/Ordinal/Topology.lean | 2 +- Mathlib/Tactic/Bound.lean | 2 +- Mathlib/Tactic/Determinant/Bird/Cert.lean | 2 +- Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean | 1 - Mathlib/Tactic/NormNum/Result.lean | 2 +- Mathlib/Testing/Plausible/Functions.lean | 2 -- Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean | 2 +- Mathlib/Topology/Algebra/ContinuousMonoidHom.lean | 2 +- Mathlib/Topology/Algebra/Group/GroupTopology.lean | 2 +- Mathlib/Topology/Algebra/GroupCompletion.lean | 2 +- Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean | 2 -- Mathlib/Topology/Algebra/InfiniteSum/Module.lean | 2 +- Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean | 2 +- Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean | 4 ++-- .../Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean | 2 +- Mathlib/Topology/Algebra/IsUniformGroup/Order.lean | 2 +- Mathlib/Topology/Algebra/Module/ClosedSubmodule.lean | 2 +- .../Topology/Algebra/Module/ContinuousLinearMap/Basic.lean | 1 - .../Topology/Algebra/Module/ContinuousLinearMap/PiProd.lean | 1 - Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean | 2 +- Mathlib/Topology/Algebra/Module/Equiv.lean | 2 +- Mathlib/Topology/Algebra/Module/LinearPMap.lean | 3 --- Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean | 2 +- .../Algebra/Module/Spaces/CompactConvergenceCLM.lean | 2 +- Mathlib/Topology/Algebra/OpenSubgroup.lean | 2 -- Mathlib/Topology/Algebra/Order/UpperLower.lean | 2 +- Mathlib/Topology/Algebra/Valued/ValuativeRel.lean | 2 +- Mathlib/Topology/Bornology/BoundedOperation.lean | 2 +- Mathlib/Topology/CWComplex/Classical/Graph.lean | 2 +- Mathlib/Topology/CantorBendixson.lean | 2 +- Mathlib/Topology/Category/CompHausLike/EffectiveEpi.lean | 2 +- Mathlib/Topology/Category/CompactlyGenerated.lean | 2 +- Mathlib/Topology/Category/TopCat/Limits/Basic.lean | 2 +- Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean | 2 +- Mathlib/Topology/Clopen.lean | 2 +- Mathlib/Topology/ClopenBox.lean | 2 +- Mathlib/Topology/Compactness/CompactSystem.lean | 2 +- Mathlib/Topology/Connected/Clopen.lean | 2 +- Mathlib/Topology/Connected/LocallyPathConnected.lean | 2 +- Mathlib/Topology/ContinuousMap/Bounded/Star.lean | 4 ++-- Mathlib/Topology/ContinuousMap/Sigma.lean | 2 +- Mathlib/Topology/Convenient/Localization.lean | 2 +- Mathlib/Topology/Defs/Basic.lean | 2 +- Mathlib/Topology/DerivedSet.lean | 2 +- Mathlib/Topology/EMetricSpace/Diam.lean | 2 +- Mathlib/Topology/EMetricSpace/Lipschitz.lean | 2 +- Mathlib/Topology/EMetricSpace/Pi.lean | 2 -- Mathlib/Topology/FiberBundle/Basic.lean | 2 -- Mathlib/Topology/FiberBundle/Constructions.lean | 4 ++-- Mathlib/Topology/GDelta/Basic.lean | 2 +- Mathlib/Topology/Instances/AddCircle/Real.lean | 2 +- Mathlib/Topology/Instances/Discrete.lean | 2 +- Mathlib/Topology/Instances/EReal/Lemmas.lean | 2 +- Mathlib/Topology/Instances/NNReal/Lemmas.lean | 2 +- Mathlib/Topology/Instances/RatLemmas.lean | 2 +- Mathlib/Topology/Instances/ZMultiples.lean | 2 +- Mathlib/Topology/KrullDimension.lean | 2 +- Mathlib/Topology/LocallyFinsupp/Pushforward.lean | 2 +- Mathlib/Topology/MetricSpace/Basic.lean | 4 ---- Mathlib/Topology/MetricSpace/Bounded.lean | 2 +- Mathlib/Topology/MetricSpace/Contracting.lean | 2 +- Mathlib/Topology/MetricSpace/CoveringNumbers.lean | 2 +- Mathlib/Topology/MetricSpace/DilationEquiv.lean | 2 +- Mathlib/Topology/MetricSpace/Gluing.lean | 6 +----- Mathlib/Topology/MetricSpace/HolderNorm.lean | 4 ++-- Mathlib/Topology/MetricSpace/Lipschitz.lean | 4 +--- Mathlib/Topology/MetricSpace/MetricSeparated.lean | 2 +- Mathlib/Topology/MetricSpace/PartitionOfUnity.lean | 2 +- Mathlib/Topology/MetricSpace/Pseudo/Basic.lean | 4 +--- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 2 +- Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean | 2 +- Mathlib/Topology/MetricSpace/Pseudo/Real.lean | 2 +- Mathlib/Topology/MetricSpace/Sequences.lean | 2 +- Mathlib/Topology/MetricSpace/Thickening.lean | 2 -- Mathlib/Topology/Metrizable/CompletelyMetrizable.lean | 2 +- Mathlib/Topology/OpenPartialHomeomorph/Composition.lean | 2 +- Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean | 2 +- Mathlib/Topology/OpenPartialHomeomorph/Defs.lean | 2 +- Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean | 2 +- Mathlib/Topology/Order/Category/FrameAdjunction.lean | 2 +- Mathlib/Topology/Order/DenselyOrdered.lean | 2 +- Mathlib/Topology/Order/ExtrClosure.lean | 2 -- Mathlib/Topology/Order/T5.lean | 2 +- Mathlib/Topology/PartialHomeomorph/Basic.lean | 2 +- Mathlib/Topology/PartialHomeomorph/Defs.lean | 2 +- Mathlib/Topology/Separation/SeparatedNhds.lean | 2 +- Mathlib/Topology/Sequences.lean | 2 +- Mathlib/Topology/Sheaves/CommRingCat.lean | 2 +- Mathlib/Topology/Sheaves/Functors.lean | 4 +--- Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean | 2 +- Mathlib/Topology/Sheaves/SheafOfFunctions.lean | 2 +- Mathlib/Topology/Spectral/Hom.lean | 2 +- Mathlib/Topology/UniformSpace/AbsoluteValue.lean | 2 +- Mathlib/Topology/UniformSpace/Ascoli.lean | 2 +- Mathlib/Topology/UniformSpace/Cauchy.lean | 2 +- Mathlib/Topology/UniformSpace/Completion.lean | 4 ---- .../Topology/UniformSpace/LocallyUniformConvergence.lean | 2 +- Mathlib/Topology/UniformSpace/Matrix.lean | 2 +- Mathlib/Topology/UniformSpace/Ultra/Completion.lean | 2 +- Mathlib/Topology/UnitInterval.lean | 2 +- Mathlib/Util/Tactic.lean | 2 +- 797 files changed, 616 insertions(+), 1099 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean index d3f3404d9c55bc..68590eef0965a9 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Basic.lean @@ -22,7 +22,7 @@ assert_not_exists MonoidWithZero MulAction IsOrderedMonoid assert_not_exists Finset.preimage Finset.sigma Fintype.piFinset assert_not_exists Finset.piecewise Set.indicator MonoidHom.coeFn Function.support IsSquare -open Fin Function +open Function variable {ι κ G M : Type*} {s s₁ s₂ : Finset ι} {a : ι} diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Pi.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Pi.lean index 66b1a277efd624..8ab774e0a17237 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Pi.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Pi.lean @@ -20,8 +20,6 @@ assert_not_exists MonoidWithZero MulAction IsOrderedMonoid variable {ι β : Type*} -open Fin Function - namespace Finset variable [CommMonoid β] diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Preimage.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Preimage.lean index e8a227892b1dc1..ccbd018e19e13e 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Preimage.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Preimage.lean @@ -18,8 +18,6 @@ assert_not_exists MonoidWithZero MulAction IsOrderedMonoid variable {ι κ β : Type*} -open Fin Function - namespace Finset variable [CommMonoid β] diff --git a/Mathlib/Algebra/BigOperators/Group/Finset/Sigma.lean b/Mathlib/Algebra/BigOperators/Group/Finset/Sigma.lean index 6ff55ea7c0fcfb..16e3c981440975 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset/Sigma.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset/Sigma.lean @@ -17,7 +17,7 @@ public section variable {ι κ α β γ : Type*} -open Fin Function +open Function variable {s s₁ s₂ : Finset α} {a : α} {f g : α → β} diff --git a/Mathlib/Algebra/BigOperators/Ring/List.lean b/Mathlib/Algebra/BigOperators/Ring/List.lean index f34365300e7f52..a672bcfcea68dd 100644 --- a/Mathlib/Algebra/BigOperators/Ring/List.lean +++ b/Mathlib/Algebra/BigOperators/Ring/List.lean @@ -20,7 +20,7 @@ This file contains the results concerning the interaction of list big operators public section -open MulOpposite List +open List variable {ι κ M M₀ R : Type*} diff --git a/Mathlib/Algebra/Category/AlgCat/Basic.lean b/Mathlib/Algebra/Category/AlgCat/Basic.lean index c771d334529417..d82397ca0a5cd5 100644 --- a/Mathlib/Algebra/Category/AlgCat/Basic.lean +++ b/Mathlib/Algebra/Category/AlgCat/Basic.lean @@ -21,7 +21,7 @@ associating to a type the free `R`-algebra on that type is left adjoint to the f @[expose] public section -open CategoryTheory Limits +open CategoryTheory universe v u diff --git a/Mathlib/Algebra/Category/BialgCat/Monoidal.lean b/Mathlib/Algebra/Category/BialgCat/Monoidal.lean index c3cf8a5f2da83c..0899fdb84fce0d 100644 --- a/Mathlib/Algebra/Category/BialgCat/Monoidal.lean +++ b/Mathlib/Algebra/Category/BialgCat/Monoidal.lean @@ -28,7 +28,7 @@ using `Monoidal.induced`. universe u namespace BialgCat -open CategoryTheory MonoidalCategory TensorProduct +open CategoryTheory TensorProduct variable (R : Type u) [CommRing R] diff --git a/Mathlib/Algebra/Category/BoolRing.lean b/Mathlib/Algebra/Category/BoolRing.lean index 14531f2cb58fda..84c2de491b697e 100644 --- a/Mathlib/Algebra/Category/BoolRing.lean +++ b/Mathlib/Algebra/Category/BoolRing.lean @@ -24,7 +24,7 @@ Finish the equivalence with `BoolAlg`. universe u -open CategoryTheory Order +open CategoryTheory /-- The category of Boolean rings. -/ structure BoolRing where diff --git a/Mathlib/Algebra/Category/CommAlgCat/FiniteType.lean b/Mathlib/Algebra/Category/CommAlgCat/FiniteType.lean index 23321900ff35ed..ecc14f612da9ef 100644 --- a/Mathlib/Algebra/Category/CommAlgCat/FiniteType.lean +++ b/Mathlib/Algebra/Category/CommAlgCat/FiniteType.lean @@ -20,7 +20,7 @@ We define the category of finitely generated `R`-algebras and show it is essenti universe w v u -open CategoryTheory Limits +open CategoryTheory variable (R : Type u) [CommRing R] diff --git a/Mathlib/Algebra/Category/FGModuleCat/Abelian.lean b/Mathlib/Algebra/Category/FGModuleCat/Abelian.lean index 0d529fb7c42124..e56f7fc428d78d 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Abelian.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Abelian.lean @@ -21,7 +21,7 @@ noncomputable section universe v u -open CategoryTheory Limits +open CategoryTheory namespace FGModuleCat diff --git a/Mathlib/Algebra/Category/Grp/Abelian.lean b/Mathlib/Algebra/Category/Grp/Abelian.lean index 8149f6ee485631..645a125b6310ed 100644 --- a/Mathlib/Algebra/Category/Grp/Abelian.lean +++ b/Mathlib/Algebra/Category/Grp/Abelian.lean @@ -18,7 +18,7 @@ public import Mathlib.CategoryTheory.Limits.ConcreteCategory.Basic @[expose] public section -open CategoryTheory Limits +open CategoryTheory universe u diff --git a/Mathlib/Algebra/Category/HopfAlgCat/Monoidal.lean b/Mathlib/Algebra/Category/HopfAlgCat/Monoidal.lean index b5b11a1288ca73..88fdb3b99710d9 100644 --- a/Mathlib/Algebra/Category/HopfAlgCat/Monoidal.lean +++ b/Mathlib/Algebra/Category/HopfAlgCat/Monoidal.lean @@ -24,7 +24,7 @@ the existing monoidal structure on `BialgCat`. universe u namespace HopfAlgCat -open CategoryTheory MonoidalCategory TensorProduct +open CategoryTheory TensorProduct variable (R : Type u) [CommRing R] diff --git a/Mathlib/Algebra/Category/ModuleCat/AB.lean b/Mathlib/Algebra/Category/ModuleCat/AB.lean index 183a3dd6be8be7..76c8a3d7bac7a3 100644 --- a/Mathlib/Algebra/Category/ModuleCat/AB.lean +++ b/Mathlib/Algebra/Category/ModuleCat/AB.lean @@ -22,7 +22,7 @@ public section universe u v -open CategoryTheory Limits +open CategoryTheory variable (R : Type u) [Ring R] diff --git a/Mathlib/Algebra/Category/ModuleCat/Ext/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Ext/Basic.lean index ac503df5cf226f..0f1a0c7ff66eeb 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Ext/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Ext/Basic.lean @@ -21,7 +21,7 @@ public import Mathlib.RingTheory.Ideal.Maps universe v u -open LinearMap CategoryTheory Limits +open LinearMap CategoryTheory variable {R : Type u} [CommRing R] diff --git a/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean b/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean index 384f9e81601bef..f55c03958de1e6 100644 --- a/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean +++ b/Mathlib/Algebra/Category/ModuleCat/InjectiveDimension.lean @@ -41,7 +41,7 @@ universe v v' u u' variable {R : Type u} [Ring R] -open CategoryTheory Abelian +open CategoryTheory namespace ModuleCat diff --git a/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean b/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean index de496361c2c1be..d67b5c8139939f 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ProjectiveDimension.lean @@ -42,7 +42,7 @@ universe v v' u u' variable {R : Type u} [Ring R] -open CategoryTheory Abelian Module +open CategoryTheory Module namespace ModuleCat diff --git a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Abelian.lean b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Abelian.lean index 5db7be5899a63d..09646031a2c61c 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Sheaf/Abelian.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Sheaf/Abelian.lean @@ -28,7 +28,7 @@ public section universe v v' u u' -open CategoryTheory Limits +open CategoryTheory variable {C : Type u'} [Category.{v'} C] {J : GrothendieckTopology C} diff --git a/Mathlib/Algebra/CharP/Reduced.lean b/Mathlib/Algebra/CharP/Reduced.lean index 73cbf0284089b8..a84123b5bda5a2 100644 --- a/Mathlib/Algebra/CharP/Reduced.lean +++ b/Mathlib/Algebra/CharP/Reduced.lean @@ -13,9 +13,6 @@ public import Mathlib.Algebra.CharP.Frobenius public section - -open Finset - section variable (R : Type*) [CommRing R] [IsReduced R] (p n : ℕ) [ExpChar R p] diff --git a/Mathlib/Algebra/CharZero/Infinite.lean b/Mathlib/Algebra/CharZero/Infinite.lean index 022623bd2ad100..fb2f94fb4e8d09 100644 --- a/Mathlib/Algebra/CharZero/Infinite.lean +++ b/Mathlib/Algebra/CharZero/Infinite.lean @@ -12,9 +12,6 @@ public import Mathlib.Data.Fintype.EquivFin public section - -open Set - variable (M : Type*) [AddMonoidWithOne M] [CharZero M] -- see Note [lower instance priority] diff --git a/Mathlib/Algebra/Colimit/Module.lean b/Mathlib/Algebra/Colimit/Module.lean index 9e4d148fa1445b..f43aea4ebfe883 100644 --- a/Mathlib/Algebra/Colimit/Module.lean +++ b/Mathlib/Algebra/Colimit/Module.lean @@ -36,8 +36,6 @@ noncomputable section -- needed for `deriving` variable {R : Type*} [Semiring R] {ι : Type*} [Preorder ι] {G : ι → Type*} -open Submodule - namespace Module alias DirectedSystem.map_self := DirectedSystem.map_self' diff --git a/Mathlib/Algebra/DirectSum/Finsupp.lean b/Mathlib/Algebra/DirectSum/Finsupp.lean index 5f2ef41569ec43..ebd8c2b2a04a32 100644 --- a/Mathlib/Algebra/DirectSum/Finsupp.lean +++ b/Mathlib/Algebra/DirectSum/Finsupp.lean @@ -24,7 +24,7 @@ noncomputable section open DirectSum -open LinearMap Submodule +open LinearMap variable {R : Type u} {M : Type v} [Semiring R] [AddCommMonoid M] [Module R M] diff --git a/Mathlib/Algebra/Field/Basic.lean b/Mathlib/Algebra/Field/Basic.lean index f903c5e449f4b3..ad6cfbeee5fa77 100644 --- a/Mathlib/Algebra/Field/Basic.lean +++ b/Mathlib/Algebra/Field/Basic.lean @@ -23,7 +23,7 @@ import Mathlib.Tactic.Tauto @[expose] public section -open Function OrderDual Set +open Function OrderDual universe u diff --git a/Mathlib/Algebra/Field/Defs.lean b/Mathlib/Algebra/Field/Defs.lean index d07e14959ce750..c281ddd4536167 100644 --- a/Mathlib/Algebra/Field/Defs.lean +++ b/Mathlib/Algebra/Field/Defs.lean @@ -54,8 +54,6 @@ assert_not_imported Mathlib.Algebra.NeZero assert_not_exists MonoidHom Set -open Function - universe u variable {K : Type*} diff --git a/Mathlib/Algebra/Field/GeomSum.lean b/Mathlib/Algebra/Field/GeomSum.lean index 506e6aaaa6b713..04fb08a1d3472d 100644 --- a/Mathlib/Algebra/Field/GeomSum.lean +++ b/Mathlib/Algebra/Field/GeomSum.lean @@ -30,7 +30,7 @@ assert_not_exists IsOrderedRing variable {R K : Type*} -open Finset MulOpposite +open Finset section DivisionRing variable [DivisionRing K] {x y : K} diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean index fc380aa9b54e2e..5a7bfa847bb5a1 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Scalar.lean @@ -47,7 +47,7 @@ pointwise subtraction assert_not_exists Cardinal Finset.dens MonoidWithZero MulAction IsOrderedMonoid -open Function MulOpposite +open MulOpposite open scoped Pointwise diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean b/Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean index 7d6a33cc4df4cf..926260aba58c10 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Lattice.lean @@ -25,8 +25,6 @@ public section assert_not_exists MulAction MonoidWithZero -open Function MulOpposite - variable {F α β γ : Type*} namespace Set diff --git a/Mathlib/Algebra/Group/Subgroup/Defs.lean b/Mathlib/Algebra/Group/Subgroup/Defs.lean index 81e5bb70d1a79d..e17371dc0b0d24 100644 --- a/Mathlib/Algebra/Group/Subgroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subgroup/Defs.lean @@ -599,8 +599,6 @@ theorem subtype_comp_inclusion {H K : Subgroup G} (hH : H ≤ K) : K.subtype.comp (inclusion hH) = H.subtype := rfl -open Set - /-- A subgroup `H` is normal if whenever `n ∈ H`, then `g * n * g⁻¹ ∈ H` for every `g : G` -/ structure Normal : Prop where /-- `H` is closed under conjugation -/ diff --git a/Mathlib/Algebra/GroupWithZero/Action/Faithful.lean b/Mathlib/Algebra/GroupWithZero/Action/Faithful.lean index 926fb1cd272ddd..53cf29fdc12035 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Faithful.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Faithful.lean @@ -17,8 +17,6 @@ public section assert_not_exists Equiv.Perm.equivUnitsEnd Prod.fst_mul Ring -open Function - variable {α : Type*} /-- `Monoid.toMulAction` is faithful on nontrivial cancellative monoids with zero. -/ diff --git a/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean b/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean index d38334edd8b231..b119a702edb805 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Pointwise/Set.lean @@ -25,7 +25,6 @@ pointwise subtraction assert_not_exists IsOrderedMonoid Ring -open Function open scoped Pointwise variable {α β : Type*} diff --git a/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Basic.lean b/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Basic.lean index 64b2314f287afd..a2e8d581e294fc 100644 --- a/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Basic.lean @@ -23,7 +23,6 @@ public section assert_not_exists MulAction IsOrderedMonoid Ring -open Function open scoped Pointwise variable {α : Type*} diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Linear.lean b/Mathlib/Algebra/Homology/DerivedCategory/Linear.lean index 6445e66a097c0c..a01f8bf3172928 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Linear.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Linear.lean @@ -17,7 +17,7 @@ public import Mathlib.CategoryTheory.Shift.Linear public section -open CategoryTheory Category Limits Pretriangulated ZeroObject Preadditive +open CategoryTheory universe t w v u diff --git a/Mathlib/Algebra/Homology/ImageToKernel.lean b/Mathlib/Algebra/Homology/ImageToKernel.lean index 000ea09d602d06..be3ad0306b94b1 100644 --- a/Mathlib/Algebra/Homology/ImageToKernel.lean +++ b/Mathlib/Algebra/Homology/ImageToKernel.lean @@ -122,8 +122,6 @@ theorem imageToKernel_comp_hom_inv_comp [HasEqualizers V] [HasImages V] {Z : V} ext simp -open ZeroObject - /-- `imageToKernel` for `A --0--> B --g--> C`, where `g` is a mono is itself an epi (i.e. the sequence is exact at `B`). -/ diff --git a/Mathlib/Algebra/Homology/LeftResolution/Transport.lean b/Mathlib/Algebra/Homology/LeftResolution/Transport.lean index c37a923c087eea..b5681cc0896d03 100644 --- a/Mathlib/Algebra/Homology/LeftResolution/Transport.lean +++ b/Mathlib/Algebra/Homology/LeftResolution/Transport.lean @@ -21,8 +21,6 @@ define `Λ.transport .. : LeftResolution ι'`. namespace CategoryTheory.Abelian -open Category - variable {A C : Type*} [Category* C] [Category* A] {A' C' : Type*} [Category* C'] [Category* A'] diff --git a/Mathlib/Algebra/Homology/ShortComplex/ModuleCat.lean b/Mathlib/Algebra/Homology/ShortComplex/ModuleCat.lean index 8379920c4b8e76..43297140cebf4e 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/ModuleCat.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/ModuleCat.lean @@ -25,8 +25,6 @@ variable {R : Type u} [Ring R] namespace CategoryTheory -open Limits - namespace ShortComplex noncomputable instance : (forget₂ (ModuleCat.{v} R) Ab).PreservesHomology where diff --git a/Mathlib/Algebra/Lie/EngelSubalgebra.lean b/Mathlib/Algebra/Lie/EngelSubalgebra.lean index 44a2f30a061f39..e64b7597d68f1b 100644 --- a/Mathlib/Algebra/Lie/EngelSubalgebra.lean +++ b/Mathlib/Algebra/Lie/EngelSubalgebra.lean @@ -34,7 +34,7 @@ and minimal ones are nilpotent (TODO), hence Cartan subalgebras. @[expose] public section -open LieAlgebra LieModule +open LieAlgebra variable {R L M : Type*} [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M] [LieRingModule L M] [LieModule R L M] diff --git a/Mathlib/Algebra/Lie/Weights/Linear.lean b/Mathlib/Algebra/Lie/Weights/Linear.lean index 312681d6a56801..b35e2890b73af5 100644 --- a/Mathlib/Algebra/Lie/Weights/Linear.lean +++ b/Mathlib/Algebra/Lie/Weights/Linear.lean @@ -43,8 +43,6 @@ or `R` has characteristic zero. @[expose] public section -open Set - variable (k R L M : Type*) [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M] [LieRingModule L M] [LieModule R L M] diff --git a/Mathlib/Algebra/Module/CharacterModule.lean b/Mathlib/Algebra/Module/CharacterModule.lean index 2cf6f59f89c433..dc75327beaba02 100644 --- a/Mathlib/Algebra/Module/CharacterModule.lean +++ b/Mathlib/Algebra/Module/CharacterModule.lean @@ -31,8 +31,6 @@ For commutative ring `R` and an `R`-module `M` and an injective module `D`, its @[expose] public section -open CategoryTheory - universe uR uA uB variable (R : Type uR) [CommRing R] diff --git a/Mathlib/Algebra/Module/Defs.lean b/Mathlib/Algebra/Module/Defs.lean index 086f3910a4dc3e..18e95308350e13 100644 --- a/Mathlib/Algebra/Module/Defs.lean +++ b/Mathlib/Algebra/Module/Defs.lean @@ -39,7 +39,7 @@ public section assert_not_exists Field Invertible Pi.single_smul₀ RingHom Set.indicator Multiset Units -open Function Set +open Function universe u v diff --git a/Mathlib/Algebra/Module/End.lean b/Mathlib/Algebra/Module/End.lean index 9849c0378801f1..c453d8dec0c7e8 100644 --- a/Mathlib/Algebra/Module/End.lean +++ b/Mathlib/Algebra/Module/End.lean @@ -19,8 +19,6 @@ We use this to prove some results on scalar multiplication by integers. assert_not_exists RelIso Multiset Set.indicator Pi.single_smul₀ Field -open Function Set - universe u v variable {R S M M₂ : Type*} diff --git a/Mathlib/Algebra/Module/Equiv/Basic.lean b/Mathlib/Algebra/Module/Equiv/Basic.lean index a805a427a61688..985b6a42cac60a 100644 --- a/Mathlib/Algebra/Module/Equiv/Basic.lean +++ b/Mathlib/Algebra/Module/Equiv/Basic.lean @@ -786,8 +786,6 @@ section Field variable [Field K] [AddCommGroup M] [Module K M] variable (K) (M) -open LinearMap - /-- Multiplying by a nonzero element `a` of the field `K` is a linear equivalence. -/ @[simps!] def smulOfNeZero (a : K) (ha : a ≠ 0) : M ≃ₗ[K] M := diff --git a/Mathlib/Algebra/Module/GradedModule.lean b/Mathlib/Algebra/Module/GradedModule.lean index f2e0bd81ff0d05..e0176aa0c0413c 100644 --- a/Mathlib/Algebra/Module/GradedModule.lean +++ b/Mathlib/Algebra/Module/GradedModule.lean @@ -80,7 +80,7 @@ def smulAddMonoidHom [DecidableEq ιA] [DecidableEq ιB] [GMonoid A] [Gmodule A section -open GradedMonoid DirectSum Gmodule +open GradedMonoid DirectSum instance [DecidableEq ιA] [DecidableEq ιB] [GMonoid A] [Gmodule A M] : SMul (⨁ i, A i) (⨁ i, M i) where diff --git a/Mathlib/Algebra/Module/LocalizedModule/Int.lean b/Mathlib/Algebra/Module/LocalizedModule/Int.lean index e43294f55d06fe..93cd49e2fd800e 100644 --- a/Mathlib/Algebra/Module/LocalizedModule/Int.lean +++ b/Mathlib/Algebra/Module/LocalizedModule/Int.lean @@ -30,8 +30,6 @@ can be unified. variable {R : Type*} [CommSemiring R] {S : Submonoid R} {M : Type*} [AddCommMonoid M] [Module R M] {M' : Type*} [AddCommMonoid M'] [Module R M'] (f : M →ₗ[R] M') -open Function - namespace IsLocalizedModule /-- Given `x : M'`, `M'` a localization of `M` via `f`, `IsInteger f x` iff `x` is in the image of diff --git a/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean b/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean index a237aa5d75fa28..7312937cd1d946 100644 --- a/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean +++ b/Mathlib/Algebra/Module/LocalizedModule/Submodule.lean @@ -30,8 +30,6 @@ Results about localizations of submodules and quotient modules are provided in t @[expose] public section -open nonZeroDivisors - variable {R S M N : Type*} variable (S) [CommSemiring R] [CommSemiring S] [AddCommMonoid M] [AddCommMonoid N] variable [Module R M] [Module R N] [Algebra R S] [Module S N] [IsScalarTower R S N] diff --git a/Mathlib/Algebra/Module/NatInt.lean b/Mathlib/Algebra/Module/NatInt.lean index 853ea5298476f6..18c0d4c442af54 100644 --- a/Mathlib/Algebra/Module/NatInt.lean +++ b/Mathlib/Algebra/Module/NatInt.lean @@ -31,8 +31,6 @@ semimodule, module, vector space assert_not_exists RelIso Field Invertible Multiset Pi.single_smul₀ Set.indicator -open Function Set - universe u v variable {R S M M₂ : Type*} diff --git a/Mathlib/Algebra/Module/PID.lean b/Mathlib/Algebra/Module/PID.lean index 9b4a981dfc1ba1..1c1ac34c4cb600 100644 --- a/Mathlib/Algebra/Module/PID.lean +++ b/Mathlib/Algebra/Module/PID.lean @@ -163,8 +163,6 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^ rw [mk_sub, mk_smul, (Quotient.mk_eq_zero _).mpr <| Submodule.mem_span_singleton_self _, smul_zero, sub_zero, f1.choose_spec] -open Finset Multiset - set_option backward.isDefEq.respectTransparency.types false in omit dec in /-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some diff --git a/Mathlib/Algebra/Module/RingHom.lean b/Mathlib/Algebra/Module/RingHom.lean index 6df2b99a7a5b87..6b6c2a8909cc72 100644 --- a/Mathlib/Algebra/Module/RingHom.lean +++ b/Mathlib/Algebra/Module/RingHom.lean @@ -26,7 +26,7 @@ semimodule, module, vector space assert_not_exists Field Invertible Multiset Pi.single_smul₀ Set.indicator -open Function Set +open Function universe u v diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index bb3e5df6eb879d..90d2850e56c978 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -28,7 +28,7 @@ submodule, subspace, linear map, pushforward, pullback @[expose] public section -open Function Pointwise Set +open Function Set variable {R : Type*} {R₁ : Type*} {R₂ : Type*} {R₃ : Type*} variable {M : Type*} {M₁ : Type*} {M₂ : Type*} {M₃ : Type*} diff --git a/Mathlib/Algebra/MonoidAlgebra/Support.lean b/Mathlib/Algebra/MonoidAlgebra/Support.lean index ca1beaa6f8bebb..16b4269d49e348 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Support.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Support.lean @@ -123,7 +123,7 @@ end MonoidAlgebra namespace AddMonoidAlgebra -open Finset Finsupp MulOpposite +open Finset Finsupp variable {k : Type u₁} {G : Type u₂} [Semiring k] diff --git a/Mathlib/Algebra/MvPolynomial/CommRing.lean b/Mathlib/Algebra/MvPolynomial/CommRing.lean index 0ab0ec1103ecf7..a651488a9be9ee 100644 --- a/Mathlib/Algebra/MvPolynomial/CommRing.lean +++ b/Mathlib/Algebra/MvPolynomial/CommRing.lean @@ -39,7 +39,7 @@ As in other polynomial files, we typically use the notation: noncomputable section -open Set Function Finsupp +open Function Finsupp universe u v diff --git a/Mathlib/Algebra/MvPolynomial/PDeriv.lean b/Mathlib/Algebra/MvPolynomial/PDeriv.lean index b476581dd08488..448d2d11d0fa02 100644 --- a/Mathlib/Algebra/MvPolynomial/PDeriv.lean +++ b/Mathlib/Algebra/MvPolynomial/PDeriv.lean @@ -49,7 +49,7 @@ universe u v namespace MvPolynomial -open Set Function Finsupp +open Function Finsupp variable {R : Type u} {σ : Type v} {a a' a₁ a₂ : R} {s : σ →₀ ℕ} diff --git a/Mathlib/Algebra/Order/AddTorsor.lean b/Mathlib/Algebra/Order/AddTorsor.lean index 18392fee332b1b..e2f3ef0b298f06 100644 --- a/Mathlib/Algebra/Order/AddTorsor.lean +++ b/Mathlib/Algebra/Order/AddTorsor.lean @@ -52,8 +52,6 @@ an ordered field. public section -open Function - variable {G P : Type*} /-- An ordered vector addition is a bi-monotone vector addition. -/ diff --git a/Mathlib/Algebra/Order/Algebra.lean b/Mathlib/Algebra/Order/Algebra.lean index 36fe510b349ab7..4810c02688cf1b 100644 --- a/Mathlib/Algebra/Order/Algebra.lean +++ b/Mathlib/Algebra/Order/Algebra.lean @@ -91,7 +91,7 @@ end Nontrivial end ZeroLEOneClass namespace Mathlib.Meta.Positivity -open Lean Meta Qq Function +open Lean Qq /-- Extension for `algebraMap`. -/ @[positivity algebraMap _ _ _] diff --git a/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean b/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean index 160df874e13737..2ec176d13eafe6 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/LocallyFinite.lean @@ -19,8 +19,6 @@ This file proves lemmas about `∏ x ∈ Ixx a b, f x` and `∑ x ∈ Ixx a b, f public section -open Order - variable {α M : Type*} [CommMonoid M] {f : α → M} {a b : α} namespace Finset diff --git a/Mathlib/Algebra/Order/Field/GeomSum.lean b/Mathlib/Algebra/Order/Field/GeomSum.lean index 33c2ed23f21d8f..ddf09c546347da 100644 --- a/Mathlib/Algebra/Order/Field/GeomSum.lean +++ b/Mathlib/Algebra/Order/Field/GeomSum.lean @@ -19,7 +19,7 @@ public section variable {K : Type*} -open Finset MulOpposite +open Finset section Semifield variable [Semifield K] [LinearOrder K] [IsStrictOrderedRing K] [CanonicallyOrderedAdd K] diff --git a/Mathlib/Algebra/Order/Field/Pointwise.lean b/Mathlib/Algebra/Order/Field/Pointwise.lean index 1e9f4d2eac7c97..253ae3c360540c 100644 --- a/Mathlib/Algebra/Order/Field/Pointwise.lean +++ b/Mathlib/Algebra/Order/Field/Pointwise.lean @@ -20,7 +20,7 @@ This file contains lemmas about the effect of pointwise operations on sets with public section -open Function Set +open Set open scoped Pointwise namespace LinearOrderedField diff --git a/Mathlib/Algebra/Order/Floor/Defs.lean b/Mathlib/Algebra/Order/Floor/Defs.lean index 1b56a36497d868..fc0d03d2c1c7d5 100644 --- a/Mathlib/Algebra/Order/Floor/Defs.lean +++ b/Mathlib/Algebra/Order/Floor/Defs.lean @@ -50,8 +50,6 @@ rounding, floor, ceil assert_not_exists Finset -open Set - variable {F α β : Type*} /-! ### Floor semiring -/ diff --git a/Mathlib/Algebra/Order/Floor/Semifield.lean b/Mathlib/Algebra/Order/Floor/Semifield.lean index 49670521edd546..b60750a3c5198a 100644 --- a/Mathlib/Algebra/Order/Floor/Semifield.lean +++ b/Mathlib/Algebra/Order/Floor/Semifield.lean @@ -23,8 +23,6 @@ public section assert_not_exists Finset -open Set - variable {R K : Type*} namespace Nat diff --git a/Mathlib/Algebra/Order/Group/Abs.lean b/Mathlib/Algebra/Order/Group/Abs.lean index 91700fe5dec73d..df35708857ce7d 100644 --- a/Mathlib/Algebra/Order/Group/Abs.lean +++ b/Mathlib/Algebra/Order/Group/Abs.lean @@ -23,8 +23,6 @@ negation. This generalizes the usual absolute value on real numbers (`|x| = max public section -open Function - variable {G : Type*} section LinearOrderedCommGroup diff --git a/Mathlib/Algebra/Order/Group/CompleteLattice.lean b/Mathlib/Algebra/Order/Group/CompleteLattice.lean index 9b05e9bc27fb78..b7ae579e09e2b6 100644 --- a/Mathlib/Algebra/Order/Group/CompleteLattice.lean +++ b/Mathlib/Algebra/Order/Group/CompleteLattice.lean @@ -14,7 +14,7 @@ public import Mathlib.Order.ConditionallyCompleteLattice.Indexed public section -open Function Set +open Set variable {ι G : Type*} [Group G] [ConditionallyCompleteLattice G] [Nonempty ι] {f : ι → G} diff --git a/Mathlib/Algebra/Order/Group/Defs.lean b/Mathlib/Algebra/Order/Group/Defs.lean index a62a3910a084eb..1a5bb07ef78c2e 100644 --- a/Mathlib/Algebra/Order/Group/Defs.lean +++ b/Mathlib/Algebra/Order/Group/Defs.lean @@ -28,8 +28,6 @@ public section -/ assert_not_imported Mathlib.Algebra.NeZero -open Function - universe u variable {α : Type u} diff --git a/Mathlib/Algebra/Order/Group/Lattice.lean b/Mathlib/Algebra/Order/Group/Lattice.lean index 0bbd1acea016ee..883e9109de8ca1 100644 --- a/Mathlib/Algebra/Order/Group/Lattice.lean +++ b/Mathlib/Algebra/Order/Group/Lattice.lean @@ -39,8 +39,6 @@ lattice, order, group @[expose] public section -open Function - variable {α : Type*} section Group diff --git a/Mathlib/Algebra/Order/Group/OrderIso.lean b/Mathlib/Algebra/Order/Group/OrderIso.lean index 400baf0164f2f7..2e28f9e670fa9f 100644 --- a/Mathlib/Algebra/Order/Group/OrderIso.lean +++ b/Mathlib/Algebra/Order/Group/OrderIso.lean @@ -16,8 +16,6 @@ public import Mathlib.Order.Hom.Basic @[expose] public section -open Function - universe u variable {α : Type u} diff --git a/Mathlib/Algebra/Order/Group/Pointwise/CompleteLattice.lean b/Mathlib/Algebra/Order/Group/Pointwise/CompleteLattice.lean index 00dde7f6ffaa6c..358097b4331965 100644 --- a/Mathlib/Algebra/Order/Group/Pointwise/CompleteLattice.lean +++ b/Mathlib/Algebra/Order/Group/Pointwise/CompleteLattice.lean @@ -21,7 +21,7 @@ In this file we prove a few facts like “The infimum of `-s` is `-` the supremu public section -open Function Set +open Set open scoped Pointwise variable {M : Type*} diff --git a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean index 86f4b2ffae45a8..29f5079a243a1c 100644 --- a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean +++ b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean @@ -24,8 +24,6 @@ negation. This generalizes the usual absolute value on real numbers (`|x| = max @[expose] public section -open Function - variable {α : Type*} section Lattice diff --git a/Mathlib/Algebra/Order/Group/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Group/Unbundled/Basic.lean index 208efcc3f833f6..ca9d325c1b1333 100644 --- a/Mathlib/Algebra/Order/Group/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Group/Unbundled/Basic.lean @@ -24,8 +24,6 @@ public section assert_not_exists IsOrderedMonoid -open Function - universe u variable {α : Type u} diff --git a/Mathlib/Algebra/Order/Group/Unbundled/Int.lean b/Mathlib/Algebra/Order/Group/Unbundled/Int.lean index 29a16113927141..342fdd69cc3fc6 100644 --- a/Mathlib/Algebra/Order/Group/Unbundled/Int.lean +++ b/Mathlib/Algebra/Order/Group/Unbundled/Int.lean @@ -29,7 +29,7 @@ public section -- We should need only a minimal development of sets in order to get here. assert_not_exists Set.Subsingleton Ring -open Function Nat +open Nat namespace Int diff --git a/Mathlib/Algebra/Order/GroupWithZero/Synonym.lean b/Mathlib/Algebra/Order/GroupWithZero/Synonym.lean index 39d0b6b7f9e312..6af1f0af62a1c4 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Synonym.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Synonym.lean @@ -16,9 +16,6 @@ Transfer algebraic instances from `α` to `αᵒᵈ` and `Lex α`. public section - -open Function - variable {α : Type*} diff --git a/Mathlib/Algebra/Order/Hom/Basic.lean b/Mathlib/Algebra/Order/Hom/Basic.lean index d645cbb2a06c33..d48589c807cc67 100644 --- a/Mathlib/Algebra/Order/Hom/Basic.lean +++ b/Mathlib/Algebra/Order/Hom/Basic.lean @@ -73,8 +73,6 @@ There are two workarounds: `Middle.toTop`'s parameter, in this example replacing `[Left α]` with `[Leaf α]`. -/ -open Function - variable {ι F α β γ δ : Type*} /-! ### Basics -/ diff --git a/Mathlib/Algebra/Order/Interval/Basic.lean b/Mathlib/Algebra/Order/Interval/Basic.lean index df0af1a9951de5..72325433a3c5ce 100644 --- a/Mathlib/Algebra/Order/Interval/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Basic.lean @@ -656,7 +656,7 @@ end Interval end Length namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/ @[positivity NonemptyInterval.length _] diff --git a/Mathlib/Algebra/Order/Interval/Finset/Basic.lean b/Mathlib/Algebra/Order/Interval/Finset/Basic.lean index 443e5d9b3a7a92..1e5672538943c2 100644 --- a/Mathlib/Algebra/Order/Interval/Finset/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Finset/Basic.lean @@ -17,7 +17,7 @@ This file provides results about the interaction of algebra with `Finset.Ixx`. public section -open Function OrderDual +open Function variable {ι α : Type*} diff --git a/Mathlib/Algebra/Order/Interval/Finset/SuccPred.lean b/Mathlib/Algebra/Order/Interval/Finset/SuccPred.lean index b35cd824a34e1b..5e5807caa281e5 100644 --- a/Mathlib/Algebra/Order/Interval/Finset/SuccPred.lean +++ b/Mathlib/Algebra/Order/Interval/Finset/SuccPred.lean @@ -28,7 +28,7 @@ Copy over `insert` lemmas from `Mathlib/Order/Interval/Finset/Nat.lean`. public section -open Function Order OrderDual +open Order variable {ι α : Type*} diff --git a/Mathlib/Algebra/Order/Interval/Set/SuccPred.lean b/Mathlib/Algebra/Order/Interval/Set/SuccPred.lean index 215113e8f5b3ce..d20646c99c3fc4 100644 --- a/Mathlib/Algebra/Order/Interval/Set/SuccPred.lean +++ b/Mathlib/Algebra/Order/Interval/Set/SuccPred.lean @@ -28,7 +28,7 @@ Copy over `insert` lemmas from `Mathlib/Order/Interval/Finset/Nat.lean`. public section -open Function Order OrderDual +open Order variable {ι α : Type*} diff --git a/Mathlib/Algebra/Order/Monoid/NatCast.lean b/Mathlib/Algebra/Order/Monoid/NatCast.lean index 052f330208c071..bc1e082d81760f 100644 --- a/Mathlib/Algebra/Order/Monoid/NatCast.lean +++ b/Mathlib/Algebra/Order/Monoid/NatCast.lean @@ -17,8 +17,6 @@ public section variable {α : Type*} -open Function - lemma lt_add_one [One α] [AddZeroClass α] [PartialOrder α] [ZeroLEOneClass α] [NeZero (1 : α)] [AddLeftStrictMono α] (a : α) : a < a + 1 := lt_add_of_pos_right _ zero_lt_one diff --git a/Mathlib/Algebra/Order/Monoid/OrderDual.lean b/Mathlib/Algebra/Order/Monoid/OrderDual.lean index b4320cfb32e4df..0317b06f71475b 100644 --- a/Mathlib/Algebra/Order/Monoid/OrderDual.lean +++ b/Mathlib/Algebra/Order/Monoid/OrderDual.lean @@ -17,8 +17,6 @@ universe u variable {α : Type u} -open Function - namespace OrderDual @[to_additive] diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/MinMax.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/MinMax.lean index 3d1f8007a80dfc..9f6680d2b2819f 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/MinMax.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/MinMax.lean @@ -13,9 +13,6 @@ public import Mathlib.Algebra.Order.Monoid.Unbundled.Basic public section - -open Function - variable {α β : Type*} /-! Some lemmas about types that have an ordering and a binary operation, with no diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index 1206a324df55b2..d26815c51b1fbb 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean @@ -16,8 +16,6 @@ public import Mathlib.Tactic.Monotonicity.Attr public section -open Function - variable {β G M : Type*} section Monoid diff --git a/Mathlib/Algebra/Order/Monoid/WithTop.lean b/Mathlib/Algebra/Order/Monoid/WithTop.lean index 895064b9a9fa21..c3e25d9b6b32ff 100644 --- a/Mathlib/Algebra/Order/Monoid/WithTop.lean +++ b/Mathlib/Algebra/Order/Monoid/WithTop.lean @@ -17,8 +17,6 @@ universe u variable {α : Type u} -open Function - namespace WithTop instance isOrderedAddMonoid [AddCommMonoid α] [PartialOrder α] [IsOrderedAddMonoid α] : diff --git a/Mathlib/Algebra/Order/Nonneg/Basic.lean b/Mathlib/Algebra/Order/Nonneg/Basic.lean index f7915045096ce2..c418700b644b51 100644 --- a/Mathlib/Algebra/Order/Nonneg/Basic.lean +++ b/Mathlib/Algebra/Order/Nonneg/Basic.lean @@ -39,8 +39,6 @@ assert_not_exists IsOrderedMonoid -- TODO -- assert_not_exists PosMulMono assert_not_exists mem_upperBounds -open Set - variable {α : Type*} namespace Nonneg diff --git a/Mathlib/Algebra/Order/Nonneg/Field.lean b/Mathlib/Algebra/Order/Nonneg/Field.lean index 3e1f5c8136cdfb..d00049b2829919 100644 --- a/Mathlib/Algebra/Order/Nonneg/Field.lean +++ b/Mathlib/Algebra/Order/Nonneg/Field.lean @@ -24,8 +24,6 @@ This is used to derive algebraic structures on `ℝ≥0` and `ℚ≥0` automatic assert_not_exists abs_inv -open Set - variable {α : Type*} section NNRat diff --git a/Mathlib/Algebra/Order/Nonneg/Ring.lean b/Mathlib/Algebra/Order/Nonneg/Ring.lean index 7bed53c24a457c..a42a2fa674c1c0 100644 --- a/Mathlib/Algebra/Order/Nonneg/Ring.lean +++ b/Mathlib/Algebra/Order/Nonneg/Ring.lean @@ -34,8 +34,6 @@ The disadvantage is that we have to duplicate some instances about `Set.Ici` to public section -open Set - variable {α : Type*} namespace Nonneg diff --git a/Mathlib/Algebra/Order/Ring/Basic.lean b/Mathlib/Algebra/Order/Ring/Basic.lean index 6bd5827d8ae773..3719db9e4e9d1c 100644 --- a/Mathlib/Algebra/Order/Ring/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Basic.lean @@ -18,7 +18,7 @@ public import Mathlib.Tactic.Bound.Attribute -- We should need only a minimal development of sets in order to get here. assert_not_exists Set.Subsingleton -open Function Int +open Function variable {α M R : Type*} diff --git a/Mathlib/Algebra/Order/Ring/Cast.lean b/Mathlib/Algebra/Order/Ring/Cast.lean index fe04f33a4b509d..168b5ed704890c 100644 --- a/Mathlib/Algebra/Order/Ring/Cast.lean +++ b/Mathlib/Algebra/Order/Ring/Cast.lean @@ -25,7 +25,7 @@ Move order lemmas about `Nat.cast`, `Rat.cast`, `NNRat.cast` here. public section -open Function Nat +open Nat variable {R : Type*} diff --git a/Mathlib/Algebra/Order/Ring/Defs.lean b/Mathlib/Algebra/Order/Ring/Defs.lean index 920929518e66b2..01b0f880254e84 100644 --- a/Mathlib/Algebra/Order/Ring/Defs.lean +++ b/Mathlib/Algebra/Order/Ring/Defs.lean @@ -58,8 +58,6 @@ public section assert_not_exists MonoidHom -open Function - universe u variable {R : Type u} diff --git a/Mathlib/Algebra/Order/Ring/GeomSum.lean b/Mathlib/Algebra/Order/Ring/GeomSum.lean index d2bcfce0b362fe..199990c2702ae8 100644 --- a/Mathlib/Algebra/Order/Ring/GeomSum.lean +++ b/Mathlib/Algebra/Order/Ring/GeomSum.lean @@ -21,7 +21,7 @@ public section assert_not_exists Field -open Finset MulOpposite +open Finset variable {R : Type*} diff --git a/Mathlib/Algebra/Order/SuccPred/PartialSups.lean b/Mathlib/Algebra/Order/SuccPred/PartialSups.lean index be021e32a91bc2..36b8782ec9c219 100644 --- a/Mathlib/Algebra/Order/SuccPred/PartialSups.lean +++ b/Mathlib/Algebra/Order/SuccPred/PartialSups.lean @@ -18,8 +18,6 @@ the `PartialSup` is defined over a `SuccAddOrder`. public section -open Finset - variable {α ι : Type*} [SemilatticeSup α] [LinearOrder ι] @[simp] diff --git a/Mathlib/Algebra/Order/ZeroLEOne.lean b/Mathlib/Algebra/Order/ZeroLEOne.lean index 9a761a0b310891..c9d4e15447f028 100644 --- a/Mathlib/Algebra/Order/ZeroLEOne.lean +++ b/Mathlib/Algebra/Order/ZeroLEOne.lean @@ -17,8 +17,6 @@ public section variable {α : Type*} -open Function - /-- Typeclass for expressing that the `0` of a type is less or equal to its `1`. -/ class ZeroLEOneClass (α : Type*) [Zero α] [One α] [LE α] : Prop where /-- Zero is less than or equal to one. -/ diff --git a/Mathlib/Algebra/Pointwise/Stabilizer.lean b/Mathlib/Algebra/Pointwise/Stabilizer.lean index a5c195215e823e..61f943ddce85cb 100644 --- a/Mathlib/Algebra/Pointwise/Stabilizer.lean +++ b/Mathlib/Algebra/Pointwise/Stabilizer.lean @@ -17,7 +17,7 @@ This file characterises the stabilizer of a set/finset under the pointwise actio public section -open Function MulOpposite Set +open MulOpposite Set open scoped Pointwise namespace MulAction diff --git a/Mathlib/Algebra/Polynomial/Cardinal.lean b/Mathlib/Algebra/Polynomial/Cardinal.lean index 86d5b3634034a7..da527c43fbc793 100644 --- a/Mathlib/Algebra/Polynomial/Cardinal.lean +++ b/Mathlib/Algebra/Polynomial/Cardinal.lean @@ -18,7 +18,7 @@ of `#R` and `ℵ₀`. public section -open Cardinal Fintype +open Cardinal universe u v variable {R : Type u} {M : Type v} [Semiring R] diff --git a/Mathlib/Algebra/Polynomial/Degree/Domain.lean b/Mathlib/Algebra/Polynomial/Degree/Domain.lean index 878ee5dcebc5d9..2be8bc7b4e34e7 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Domain.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Domain.lean @@ -20,8 +20,6 @@ public section noncomputable section -open Finsupp Finset - open Polynomial namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/Degree/Lemmas.lean b/Mathlib/Algebra/Polynomial/Degree/Lemmas.lean index 5752203baf7fba..890e3baa9cfa4a 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Lemmas.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Lemmas.lean @@ -23,7 +23,7 @@ noncomputable section open Polynomial -open Finsupp Finset +open Finset namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/Degree/Monomial.lean b/Mathlib/Algebra/Polynomial/Degree/Monomial.lean index 8a5ca933b1f434..aabff2326b9eea 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Monomial.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Monomial.lean @@ -17,7 +17,7 @@ public section noncomputable section -open Finsupp Finset Polynomial +open Finset Polynomial namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/Degree/SmallDegree.lean b/Mathlib/Algebra/Polynomial/Degree/SmallDegree.lean index bd3f8c3b11be3b..5d80294af10a8d 100644 --- a/Mathlib/Algebra/Polynomial/Degree/SmallDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/SmallDegree.lean @@ -14,8 +14,6 @@ public import Mathlib.Data.Nat.WithBot public section -open Finsupp Finset - open Polynomial namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean index e1253c74df4b89..3580a40c5a5877 100644 --- a/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean +++ b/Mathlib/Algebra/Polynomial/Degree/TrailingDegree.lean @@ -26,7 +26,7 @@ end of a polynomial noncomputable section -open Function Polynomial Finsupp Finset +open Function Polynomial Finset open scoped Polynomial diff --git a/Mathlib/Algebra/Polynomial/Degree/Units.lean b/Mathlib/Algebra/Polynomial/Degree/Units.lean index 49f930eb19f1db..9bcc138a35dee6 100644 --- a/Mathlib/Algebra/Polynomial/Degree/Units.lean +++ b/Mathlib/Algebra/Polynomial/Degree/Units.lean @@ -16,7 +16,7 @@ public section noncomputable section -open Finsupp Finset Polynomial +open Polynomial namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/DenomsClearable.lean b/Mathlib/Algebra/Polynomial/DenomsClearable.lean index d105c74c489eab..4a2d2b1909d161 100644 --- a/Mathlib/Algebra/Polynomial/DenomsClearable.lean +++ b/Mathlib/Algebra/Polynomial/DenomsClearable.lean @@ -21,7 +21,7 @@ the image of the homomorphism `i`. @[expose] public section -open Polynomial Finset +open Polynomial open Polynomial diff --git a/Mathlib/Algebra/Polynomial/Eval/Algebra.lean b/Mathlib/Algebra/Polynomial/Eval/Algebra.lean index 4d4a438317c984..ace1e0ec767382 100644 --- a/Mathlib/Algebra/Polynomial/Eval/Algebra.lean +++ b/Mathlib/Algebra/Polynomial/Eval/Algebra.lean @@ -20,8 +20,6 @@ public section noncomputable section -open Finset AddMonoidAlgebra - open Polynomial namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/Eval/Degree.lean b/Mathlib/Algebra/Polynomial/Eval/Degree.lean index 434ebde0318cc1..0f31aaeb1b7f75 100644 --- a/Mathlib/Algebra/Polynomial/Eval/Degree.lean +++ b/Mathlib/Algebra/Polynomial/Eval/Degree.lean @@ -21,7 +21,7 @@ This file contains results on the interaction of `Polynomial.eval` and `Polynomi noncomputable section -open Finset AddMonoidAlgebra +open Finset open Polynomial diff --git a/Mathlib/Algebra/Polynomial/Eval/Irreducible.lean b/Mathlib/Algebra/Polynomial/Eval/Irreducible.lean index 2a08bbf3f4a985..b21fb3589b3629 100644 --- a/Mathlib/Algebra/Polynomial/Eval/Irreducible.lean +++ b/Mathlib/Algebra/Polynomial/Eval/Irreducible.lean @@ -22,8 +22,6 @@ public section noncomputable section -open Finset AddMonoidAlgebra - open Polynomial namespace Polynomial diff --git a/Mathlib/Algebra/Polynomial/Eval/SMul.lean b/Mathlib/Algebra/Polynomial/Eval/SMul.lean index 52d1055d9bf4c4..eeefb66bf8c223 100644 --- a/Mathlib/Algebra/Polynomial/Eval/SMul.lean +++ b/Mathlib/Algebra/Polynomial/Eval/SMul.lean @@ -21,7 +21,7 @@ public import Mathlib.Algebra.Polynomial.Eval.Defs noncomputable section -open Finset AddMonoidAlgebra +open Finset open Polynomial diff --git a/Mathlib/Algebra/Polynomial/Inductions.lean b/Mathlib/Algebra/Polynomial/Inductions.lean index 897336644d5b5d..58ed29586d4d74 100644 --- a/Mathlib/Algebra/Polynomial/Inductions.lean +++ b/Mathlib/Algebra/Polynomial/Inductions.lean @@ -23,8 +23,6 @@ noncomputable section open Polynomial -open Finset - namespace Polynomial universe u v w z diff --git a/Mathlib/Algebra/Polynomial/RingDivision.lean b/Mathlib/Algebra/Polynomial/RingDivision.lean index 74026281f0a1c8..59999ade930b84 100644 --- a/Mathlib/Algebra/Polynomial/RingDivision.lean +++ b/Mathlib/Algebra/Polynomial/RingDivision.lean @@ -25,8 +25,6 @@ noncomputable section open Polynomial -open Finset - namespace Polynomial universe u v w z diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index 5a87d3af1c5fea..b20f84be4e8965 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -668,8 +668,6 @@ end Field noncomputable section -open Polynomial - universe u v w variable {F : Type u} {K : Type v} {L : Type w} @@ -696,8 +694,6 @@ attribute [local instance] PrincipalIdealRing.to_uniqueFactorizationMonoid local infixl:50 " ~ᵤ " => Associated -open UniqueFactorizationMonoid Associates - end UFD variable [Algebra R K] [Algebra R L] diff --git a/Mathlib/Algebra/Ring/Action/Pointwise/Set.lean b/Mathlib/Algebra/Ring/Action/Pointwise/Set.lean index 61f094534bc2e3..8e7ae3b27b1366 100644 --- a/Mathlib/Algebra/Ring/Action/Pointwise/Set.lean +++ b/Mathlib/Algebra/Ring/Action/Pointwise/Set.lean @@ -25,7 +25,6 @@ public section assert_not_exists IsOrderedMonoid Field -open Function open scoped Pointwise variable {α β : Type*} diff --git a/Mathlib/Algebra/Ring/Basic.lean b/Mathlib/Algebra/Ring/Basic.lean index 377ab3dc195de9..8274065c5e90f1 100644 --- a/Mathlib/Algebra/Ring/Basic.lean +++ b/Mathlib/Algebra/Ring/Basic.lean @@ -29,8 +29,6 @@ assert_not_exists Nat.cast_sub variable {R S : Type*} -open Function - namespace AddHom /-- Left multiplication by an element of a type with distributive multiplication is an `AddHom`. -/ diff --git a/Mathlib/Algebra/Ring/Commute.lean b/Mathlib/Algebra/Ring/Commute.lean index 5ee61f26fb82ca..6ba5bd83b1365e 100644 --- a/Mathlib/Algebra/Ring/Commute.lean +++ b/Mathlib/Algebra/Ring/Commute.lean @@ -29,8 +29,6 @@ universe u variable {R : Type u} -open Function - namespace Commute @[simp] diff --git a/Mathlib/Algebra/Ring/Defs.lean b/Mathlib/Algebra/Ring/Defs.lean index 5bcb9b4e73ec77..e14de20957b33e 100644 --- a/Mathlib/Algebra/Ring/Defs.lean +++ b/Mathlib/Algebra/Ring/Defs.lean @@ -52,8 +52,6 @@ universe u v variable {α : Type u} {R : Type v} -open Function - /-! ### `Distrib` class -/ diff --git a/Mathlib/Algebra/Ring/Parity.lean b/Mathlib/Algebra/Ring/Parity.lean index e71f001ab82f92..dbda9c5801085b 100644 --- a/Mathlib/Algebra/Ring/Parity.lean +++ b/Mathlib/Algebra/Ring/Parity.lean @@ -33,8 +33,6 @@ to `Mathlib/Algebra/Group/Even.lean`. assert_not_exists DenselyOrdered IsOrderedRing -open MulOpposite - variable {F α β : Type*} section Monoid diff --git a/Mathlib/Algebra/Ring/Periodic.lean b/Mathlib/Algebra/Ring/Periodic.lean index 71fcf017b9bc3e..1128ba9eae6d18 100644 --- a/Mathlib/Algebra/Ring/Periodic.lean +++ b/Mathlib/Algebra/Ring/Periodic.lean @@ -33,8 +33,6 @@ assert_not_exists Field variable {α β γ : Type*} {f g : α → β} {c c₁ c₂ x : α} -open Set - namespace Function /-! ### Periodicity -/ diff --git a/Mathlib/Algebra/Ring/Pointwise/Set.lean b/Mathlib/Algebra/Ring/Pointwise/Set.lean index c5860d72243ce0..c39b54e6f0c6c8 100644 --- a/Mathlib/Algebra/Ring/Pointwise/Set.lean +++ b/Mathlib/Algebra/Ring/Pointwise/Set.lean @@ -23,7 +23,6 @@ pointwise subtraction assert_not_exists MulAction IsOrderedMonoid Field -open Function open scoped Pointwise variable {α : Type*} diff --git a/Mathlib/Algebra/Ring/Semiconj.lean b/Mathlib/Algebra/Ring/Semiconj.lean index 5ea3d78f5325a9..16dfaeac6887e4 100644 --- a/Mathlib/Algebra/Ring/Semiconj.lean +++ b/Mathlib/Algebra/Ring/Semiconj.lean @@ -27,8 +27,6 @@ universe u variable {R : Type u} -open Function - namespace SemiconjBy @[simp] diff --git a/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean b/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean index f9e80ef8fdb7b0..6747f40d82e02f 100644 --- a/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean +++ b/Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean @@ -30,7 +30,7 @@ immersions can be used to deduce these assumptions in the general case. noncomputable section -open TopologicalSpace CategoryTheory Opposite CategoryTheory.Limits +open CategoryTheory CategoryTheory.Limits universe v v₁ v₂ u diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean index 5ef4ba3b118a6a..58722997b352a3 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/IsomOfJ.lean @@ -22,8 +22,6 @@ public import Mathlib.FieldTheory.IsSepClosed public section -open Polynomial - variable {F : Type*} [Field F] [IsSepClosed F] namespace WeierstrassCurve diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index 421927c5a63b6b..265dba1303c8ba 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -237,8 +237,6 @@ section Affine variable {X Y : Scheme.{u}} [IsAffine Y] {f : X ⟶ Y} -open IsClosedImmersion LocallyRingedSpace - set_option backward.isDefEq.respectTransparency.types false in /-- If `f : X ⟶ Y` is a morphism of schemes with quasi-compact source and affine target, `f` induces an injection on global sections, then `f` is dominant. -/ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean index 6a4fcbe6655d2d..e20d33189fdfb3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean @@ -26,7 +26,7 @@ public section noncomputable section -open CategoryTheory CategoryTheory.Limits Opposite TopologicalSpace +open CategoryTheory CategoryTheory.Limits TopologicalSpace universe v u diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean index 33afd04ba94e1d..7d2ffaed1bed9d 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyInjective.lean @@ -29,7 +29,7 @@ public section noncomputable section -open CategoryTheory CategoryTheory.Limits Opposite TopologicalSpace +open CategoryTheory CategoryTheory.Limits TopologicalSpace universe v u diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index 86ddc99037b082..e932816b8aa269 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -250,7 +250,7 @@ open HomogeneousLocalization variable {𝒜} variable {f : A} {m : ℕ} (f_deg : f ∈ 𝒜 m) -open Lean Meta Elab Tactic +open Lean /-- `mem_tac` tries to prove goals of the form `x ∈ 𝒜 i` when `x` has the form of: * `y ^ n` where `i = n • j` and `y ∈ 𝒜 j`. diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean index 079d8d5597d8cb..dc3c5c3011da3c 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Topology.lean @@ -42,7 +42,7 @@ It is naturally endowed with a topology: the Zariski topology. noncomputable section -open DirectSum Pointwise SetLike TopCat TopologicalSpace CategoryTheory Opposite +open DirectSum SetLike TopCat TopologicalSpace variable {A σ : Type*} variable [CommRing A] [SetLike σ A] [AddSubmonoidClass σ A] diff --git a/Mathlib/AlgebraicGeometry/Sites/Pretopology.lean b/Mathlib/AlgebraicGeometry/Sites/Pretopology.lean index 76e9fd0272884f..cef0c62aa4a949 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Pretopology.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Pretopology.lean @@ -26,7 +26,7 @@ because the former does not have `HasPullbacks Scheme`. universe v u -open CategoryTheory Limits +open CategoryTheory namespace AlgebraicGeometry.Scheme diff --git a/Mathlib/AlgebraicGeometry/Sites/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Sites/QuasiCompact.lean index bd5a2da40cf8ef..91435d8ad3e3f8 100644 --- a/Mathlib/AlgebraicGeometry/Sites/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Sites/QuasiCompact.lean @@ -23,7 +23,7 @@ The fpqc precoverage is the precoverage by flat covers that are quasi-compact in universe w' w v u -open CategoryTheory Limits +open CategoryTheory namespace AlgebraicGeometry.Scheme diff --git a/Mathlib/AlgebraicGeometry/Sites/Small.lean b/Mathlib/AlgebraicGeometry/Sites/Small.lean index b257f5528f2c03..49ff4daab2cd15 100644 --- a/Mathlib/AlgebraicGeometry/Sites/Small.lean +++ b/Mathlib/AlgebraicGeometry/Sites/Small.lean @@ -35,7 +35,7 @@ generating pretopologies. universe v u -open CategoryTheory Limits +open CategoryTheory namespace AlgebraicGeometry.Scheme diff --git a/Mathlib/AlgebraicTopology/ModelCategory/FundamentalLemma.lean b/Mathlib/AlgebraicTopology/ModelCategory/FundamentalLemma.lean index 2c2e7570f012b7..e02b3ec45123a9 100644 --- a/Mathlib/AlgebraicTopology/ModelCategory/FundamentalLemma.lean +++ b/Mathlib/AlgebraicTopology/ModelCategory/FundamentalLemma.lean @@ -24,7 +24,7 @@ the left and right homotopy relations coincide). @[expose] public section -open CategoryTheory Limits +open CategoryTheory namespace HomotopicalAlgebra diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean index a2b0af5074e5d8..99440f0f9894a4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean @@ -33,8 +33,6 @@ then `P.RankFunction ℕ` is non empty (TODO @joelriou). universe v u -open CategoryTheory Simplicial - namespace SSet.Subcomplex variable {X : SSet.{u}} {A : X.Subcomplex} diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean b/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean index fbd4a6e3f73cbc..cff2864774c092 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/CoherentIso.lean @@ -136,7 +136,7 @@ end CategoryTheory namespace SSet -open Simplicial Edge +open Simplicial /-- The simplicial set that encodes a single isomorphism. Its n-simplices are formal compositions of arrows in WalkingIso. -/ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/CompStructTruncated.lean b/Mathlib/AlgebraicTopology/SimplicialSet/CompStructTruncated.lean index 95f21e438147bc..b63547f8b4f77f 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/CompStructTruncated.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/CompStructTruncated.lean @@ -25,7 +25,7 @@ Given a `2`-truncated simplicial set `X`, we introduce two types: universe v u -open CategoryTheory Simplicial SimplicialObject.Truncated +open CategoryTheory SimplicialObject.Truncated SimplexCategory.Truncated namespace SSet.Truncated diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean index cac6d90cf6c128..8f2c4f6564e27e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean @@ -24,7 +24,7 @@ which is the category `Fin (n + 1) ⥤ C`. @[expose] public section -open CategoryTheory Category Simplicial Opposite +open CategoryTheory Simplicial Opposite universe v u diff --git a/Mathlib/Analysis/Analytic/CPolynomial.lean b/Mathlib/Analysis/Analytic/CPolynomial.lean index 128ccc147f858a..6a614e74c55816 100644 --- a/Mathlib/Analysis/Analytic/CPolynomial.lean +++ b/Mathlib/Analysis/Analytic/CPolynomial.lean @@ -24,7 +24,7 @@ variable {𝕜 E F G : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup [NormedAddCommGroup F] [NormedSpace 𝕜 F] [NormedAddCommGroup G] [NormedSpace 𝕜 G] open scoped Topology -open Set Filter Asymptotics NNReal ENNReal +open Set Filter ENNReal variable {f g : E → F} {p pf pg : FormalMultilinearSeries 𝕜 E F} {x : E} {r r' : ℝ≥0∞} {n m : ℕ} @@ -111,8 +111,6 @@ namespace ContinuousMultilinearMap variable {ι : Type*} {Em : ι → Type*} [∀ i, NormedAddCommGroup (Em i)] [∀ i, NormedSpace 𝕜 (Em i)] [Fintype ι] (f : ContinuousMultilinearMap 𝕜 Em F) {x : Π i, Em i} {s : Set (Π i, Em i)} -open FormalMultilinearSeries - protected theorem hasFiniteFPowerSeriesOnBall : HasFiniteFPowerSeriesOnBall f f.toFormalMultilinearSeries 0 (Fintype.card ι + 1) ⊤ := .mk' (fun _ hm ↦ dite_eq_right (Nat.succ_le_iff.mp hm).ne) ENNReal.zero_lt_top fun y _ ↦ by diff --git a/Mathlib/Analysis/Analytic/CPolynomialDef.lean b/Mathlib/Analysis/Analytic/CPolynomialDef.lean index 979ee9a81876f0..8d4b46ec6bde35 100644 --- a/Mathlib/Analysis/Analytic/CPolynomialDef.lean +++ b/Mathlib/Analysis/Analytic/CPolynomialDef.lean @@ -50,7 +50,7 @@ variable {𝕜 E F G : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup [NormedAddCommGroup F] [NormedSpace 𝕜 F] [NormedAddCommGroup G] [NormedSpace 𝕜 G] open scoped Topology -open Set Filter Asymptotics NNReal ENNReal +open Set Filter ENNReal variable {f g : E → F} {p pf pg : FormalMultilinearSeries 𝕜 E F} {x : E} {r r' : ℝ≥0∞} {n m : ℕ} diff --git a/Mathlib/Analysis/Analytic/Inverse.lean b/Mathlib/Analysis/Analytic/Inverse.lean index 26df5e360d7ad4..1ae15ddb4cf94b 100644 --- a/Mathlib/Analysis/Analytic/Inverse.lean +++ b/Mathlib/Analysis/Analytic/Inverse.lean @@ -563,7 +563,7 @@ end FormalMultilinearSeries ### The inverse of an analytic open partial homeomorphism is analytic -/ -open FormalMultilinearSeries List +open FormalMultilinearSeries lemma HasFPowerSeriesAt.tendsto_partialSum_prod_of_comp {f : E → G} {q : FormalMultilinearSeries 𝕜 F G} diff --git a/Mathlib/Analysis/Analytic/IsolatedZeros.lean b/Mathlib/Analysis/Analytic/IsolatedZeros.lean index 9bad403947a195..2acbece4b80c4e 100644 --- a/Mathlib/Analysis/Analytic/IsolatedZeros.lean +++ b/Mathlib/Analysis/Analytic/IsolatedZeros.lean @@ -40,7 +40,7 @@ in this setup. public section -open Filter Function Module Nat FormalMultilinearSeries EMetric Set +open Filter Function Module Nat FormalMultilinearSeries Set open scoped Topology diff --git a/Mathlib/Analysis/Analytic/Linear.lean b/Mathlib/Analysis/Analytic/Linear.lean index df061f57a0de58..4bedda5e7bb63b 100644 --- a/Mathlib/Analysis/Analytic/Linear.lean +++ b/Mathlib/Analysis/Analytic/Linear.lean @@ -25,7 +25,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCom [NormedAddCommGroup G] [NormedSpace 𝕜 G] open scoped Topology NNReal ENNReal -open Set Filter Asymptotics +open Set noncomputable section diff --git a/Mathlib/Analysis/Analytic/OfScalars.lean b/Mathlib/Analysis/Analytic/OfScalars.lean index f9f06964d5e244..4f83542cbe5757 100644 --- a/Mathlib/Analysis/Analytic/OfScalars.lean +++ b/Mathlib/Analysis/Analytic/OfScalars.lean @@ -159,7 +159,6 @@ end Field section Seminormed -open Filter ENNReal open scoped Topology NNReal variable {𝕜 : Type*} (E : Type*) [NontriviallyNormedField 𝕜] [SeminormedRing E] diff --git a/Mathlib/Analysis/Asymptotics/Defs.lean b/Mathlib/Analysis/Asymptotics/Defs.lean index 11d00735f6e010..d6010b10847ba1 100644 --- a/Mathlib/Analysis/Asymptotics/Defs.lean +++ b/Mathlib/Analysis/Asymptotics/Defs.lean @@ -57,7 +57,7 @@ set_option linter.style.longFile 1600 assert_not_exists IsBoundedSMul Summable OpenPartialHomeomorph BoundedLENhdsClass -open Set Topology Filter NNReal +open Set Topology Filter namespace Asymptotics diff --git a/Mathlib/Analysis/Asymptotics/Lemmas.lean b/Mathlib/Analysis/Asymptotics/Lemmas.lean index 6dd234c97c8585..128b24ff6cb5c4 100644 --- a/Mathlib/Analysis/Asymptotics/Lemmas.lean +++ b/Mathlib/Analysis/Asymptotics/Lemmas.lean @@ -18,7 +18,7 @@ public import Mathlib.Topology.OpenPartialHomeomorph.Continuity public section -open Set Topology Filter NNReal +open Set Topology Filter namespace Asymptotics diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean b/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean index 504b47b5958e5e..e4ff4294929c0a 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Tagged.lean @@ -29,7 +29,7 @@ rectangular box, box partition noncomputable section -open Finset Function ENNReal NNReal Set +open Finset Function NNReal Set namespace BoxIntegral diff --git a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean index 9f3af3568c772e..35313037decf6e 100644 --- a/Mathlib/Analysis/BoxIntegral/UnitPartition.lean +++ b/Mathlib/Analysis/BoxIntegral/UnitPartition.lean @@ -321,7 +321,7 @@ theorem prepartition_isPartition {B : Box ι} (hB : hasIntegralVertices B) : end fintype -open Submodule Pointwise +open Submodule open scoped Pointwise diff --git a/Mathlib/Analysis/CStarAlgebra/Basic.lean b/Mathlib/Analysis/CStarAlgebra/Basic.lean index 3ecd3338d80bc0..449f02d9d7e132 100644 --- a/Mathlib/Analysis/CStarAlgebra/Basic.lean +++ b/Mathlib/Analysis/CStarAlgebra/Basic.lean @@ -38,8 +38,6 @@ Note that the type classes corresponding to C⋆-algebras are defined in assert_not_exists ContinuousLinearMap.hasOpNorm -open Topology - local postfix:max "⋆" => star /-- A normed star group is a normed group with a compatible `star` which is isometric. -/ diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean index a0c58585f2073e..ae9aa0b71bc717 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Integral.lean @@ -41,7 +41,7 @@ with the API developed in `Mathlib.MeasureTheory.SpecificCodomains.ContinuousMap public section -open MeasureTheory Topology +open MeasureTheory open scoped ContinuousMapZero section unital diff --git a/Mathlib/Analysis/CStarAlgebra/Extreme.lean b/Mathlib/Analysis/CStarAlgebra/Extreme.lean index 7bf7715670618e..49c9b432782c87 100644 --- a/Mathlib/Analysis/CStarAlgebra/Extreme.lean +++ b/Mathlib/Analysis/CStarAlgebra/Extreme.lean @@ -18,7 +18,7 @@ This file contains results on the extreme points of the closed unit ball in (uni public section -open Set Metric CFC CStarAlgebra Unitization +open Set Metric CStarAlgebra Unitization variable {A : Type*} [NonUnitalCStarAlgebra A] diff --git a/Mathlib/Analysis/CStarAlgebra/Matrix.lean b/Mathlib/Analysis/CStarAlgebra/Matrix.lean index 177e5295e09034..23c559a1cb80c2 100644 --- a/Mathlib/Analysis/CStarAlgebra/Matrix.lean +++ b/Mathlib/Analysis/CStarAlgebra/Matrix.lean @@ -149,7 +149,7 @@ def l2OpNormedRingAux : NormedRing (Matrix n n 𝕜) := @NormedRing.induced ((Matrix n n 𝕜) ≃⋆ₐ[𝕜] (EuclideanSpace 𝕜 n →L[𝕜] EuclideanSpace 𝕜 n)) _ _ _ _ ContinuousLinearMap.toNormedRing _ _ toEuclideanCLM.injective -open Bornology Filter +open Filter open scoped Topology Uniformity /-- The metric on `Matrix m n 𝕜` arising from the operator norm given by the identification with diff --git a/Mathlib/Analysis/CStarAlgebra/Multiplier.lean b/Mathlib/Analysis/CStarAlgebra/Multiplier.lean index 5ba03960d1c82d..9fdb9bf5699b84 100644 --- a/Mathlib/Analysis/CStarAlgebra/Multiplier.lean +++ b/Mathlib/Analysis/CStarAlgebra/Multiplier.lean @@ -57,7 +57,7 @@ separately. @[expose] public section -open NNReal ENNReal ContinuousLinearMap MulOpposite +open NNReal ContinuousLinearMap MulOpposite universe u v diff --git a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean index 951ea294ce6b81..a3f7170e4de4c7 100644 --- a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean +++ b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean @@ -317,7 +317,7 @@ end namespace WeakDual -open ContinuousMap Complex +open Complex open scoped ComplexStarModule diff --git a/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean b/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean index 2bf4bd218d8658..f25097ab888938 100644 --- a/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean +++ b/Mathlib/Analysis/Calculus/AbsolutelyMonotone.lean @@ -45,7 +45,7 @@ iterated derivative within `s` nonnegative. public section -open Set Filter +open Set open scoped ContDiff /-- A function `f : ℝ → ℝ` is **absolutely monotone on a set `s`** if, heuristically, all diff --git a/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean b/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean index e53eb612858e81..28e8e9e3bc0377 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/FiniteDimension.lean @@ -29,7 +29,7 @@ the indicator function of `closedBall 0 1` with a function as above with `s = ba noncomputable section -open Set Metric TopologicalSpace Function Asymptotics MeasureTheory Module +open Set Metric TopologicalSpace Function MeasureTheory Module ContinuousLinearMap Filter MeasureTheory.Measure Bornology open scoped Pointwise Topology NNReal Convolution ContDiff diff --git a/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean b/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean index 67c4ec8a525ff5..7cea03bdbf1dee 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/SmoothApprox.lean @@ -27,7 +27,7 @@ variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensi [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] {f : E → F} {ε : ℝ} open scoped ContDiff unitInterval Topology -open Function Set Metric MeasureTheory +open Set Metric MeasureTheory theorem MeasureTheory.LocallyIntegrable.exists_contDiff_dist_le_of_forall_mem_ball_dist_le [MeasurableSpace E] [BorelSpace E] {μ : Measure E} [μ.IsAddHaarMeasure] diff --git a/Mathlib/Analysis/Calculus/Conformal/NormedSpace.lean b/Mathlib/Analysis/Calculus/Conformal/NormedSpace.lean index 96c8c91f6e8ebb..5bf7ba342fbdae 100644 --- a/Mathlib/Analysis/Calculus/Conformal/NormedSpace.lean +++ b/Mathlib/Analysis/Calculus/Conformal/NormedSpace.lean @@ -52,7 +52,7 @@ variable {X Y Z : Type*} [NormedAddCommGroup X] [NormedAddCommGroup Y] [NormedAd section LocConformality -open LinearIsometry ContinuousLinearMap +open ContinuousLinearMap /-- A map `f` is said to be conformal if it has a conformal differential `f'`. -/ def ConformalAt (f : X → Y) (x : X) := diff --git a/Mathlib/Analysis/Calculus/ContDiff/Bounds.lean b/Mathlib/Analysis/Calculus/ContDiff/Bounds.lean index fa113ea69a5af7..609188b4d37ce7 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Bounds.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Bounds.lean @@ -26,7 +26,7 @@ open scoped NNReal Nat ContDiff universe u uD uE uF uG -open Set Fin Filter Function +open Set Fin Function variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {D : Type uD} [NormedAddCommGroup D] [NormedSpace 𝕜 D] {E : Type uE} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {F : Type uF} diff --git a/Mathlib/Analysis/Calculus/ContDiff/CPolynomial.lean b/Mathlib/Analysis/Calculus/ContDiff/CPolynomial.lean index 091ddad107ffc9..0a9c5d2735ee7e 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/CPolynomial.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/CPolynomial.lean @@ -17,7 +17,7 @@ of continuous multilinear maps. public section -open Filter Asymptotics +open Filter open scoped ENNReal ContDiff @@ -55,8 +55,6 @@ namespace ContinuousMultilinearMap variable {ι : Type*} {E : ι → Type*} [∀ i, NormedAddCommGroup (E i)] [∀ i, NormedSpace 𝕜 (E i)] [Fintype ι] (f : ContinuousMultilinearMap 𝕜 E F) {n : ℕ∞ω} {x : Π i, E i} -open FormalMultilinearSeries - lemma contDiffAt : ContDiffAt 𝕜 n f x := f.cpolynomialAt.contDiffAt lemma contDiff : ContDiff 𝕜 n f := contDiff_iff_contDiffAt.mpr (fun _ ↦ f.contDiffAt) diff --git a/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean b/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean index 084664a10b855d..ead281a99b476d 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/FTaylorSeries.lean @@ -107,7 +107,7 @@ In this file, we denote `WithTop ℕ∞` with `ℕ∞ω`, `(⊤ : ℕ∞) : ℕ noncomputable section -open ENat NNReal Topology Filter Set Fin Filter Function +open ENat Topology Filter Set Fin Filter Function /-- The type of smoothness exponents, consisting of all natural numbers and two special terms `∞` and `ω`. diff --git a/Mathlib/Analysis/Calculus/ContDiff/Operations.lean b/Mathlib/Analysis/Calculus/ContDiff/Operations.lean index fcd9c1301e8602..40e309d4f2e2e5 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Operations.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Operations.lean @@ -770,7 +770,7 @@ section AlgebraInverse variable (𝕜) variable {R : Type*} [NormedRing R] [NormedAlgebra 𝕜 R] -open NormedRing ContinuousLinearMap Ring +open NormedRing Ring /-- In a complete normed algebra, the operation of inversion is `C^n`, for all `n`, at each invertible element, as it is analytic. -/ diff --git a/Mathlib/Analysis/Calculus/ContDiff/RCLike.lean b/Mathlib/Analysis/Calculus/ContDiff/RCLike.lean index 42448834422c2c..dff89ca9f7fee6 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/RCLike.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/RCLike.lean @@ -16,7 +16,7 @@ public section noncomputable section -open Set Fin Filter Function +open Set Fin Filter open scoped NNReal Topology diff --git a/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean b/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean index 48f0c2c7b8e0f2..8c42cc4bb3abd3 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean @@ -18,7 +18,7 @@ open scoped ENNReal section PiLp -open ContinuousLinearMap WithLp +open WithLp variable {𝕜 ι : Type*} {E : ι → Type*} {H : Type*} variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup H] [∀ i, NormedAddCommGroup (E i)] diff --git a/Mathlib/Analysis/Calculus/Deriv/Abs.lean b/Mathlib/Analysis/Calculus/Deriv/Abs.lean index 52c70a137aea08..3101803958c585 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Abs.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Abs.lean @@ -22,7 +22,7 @@ absolute value, derivative public section -open Filter Real Set +open Real Set variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {n : ℕ∞} {f : E → ℝ} {f' : StrongDual ℝ E} {s : Set E} {x : E} diff --git a/Mathlib/Analysis/Calculus/Deriv/Add.lean b/Mathlib/Analysis/Calculus/Deriv/Add.lean index abf6222dfea024..240c7d41e7793d 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Add.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Add.lean @@ -28,7 +28,7 @@ universe u v w open scoped Topology Filter ENNReal -open Asymptotics Set +open Set variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] diff --git a/Mathlib/Analysis/Calculus/Deriv/Comp.lean b/Mathlib/Analysis/Calculus/Deriv/Comp.lean index 0b9db5a45db798..56140236f7b045 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Comp.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Comp.lean @@ -40,7 +40,7 @@ universe u v w open scoped Topology Filter ENNReal -open Filter Asymptotics Set +open Filter Set variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] diff --git a/Mathlib/Analysis/Calculus/Deriv/Linear.lean b/Mathlib/Analysis/Calculus/Deriv/Linear.lean index 324895e784b892..4bb6e37f979f53 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Linear.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Linear.lean @@ -26,9 +26,9 @@ public section universe u v w -open Topology Filter +open Filter -open Filter Asymptotics Set +open Filter Set variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] diff --git a/Mathlib/Analysis/Calculus/Deriv/Mul.lean b/Mathlib/Analysis/Calculus/Deriv/Mul.lean index 235563b8145477..72534c7d4bdd8a 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Mul.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Mul.lean @@ -31,7 +31,7 @@ noncomputable section open scoped Topology Filter ENNReal -open Filter Asymptotics Set +open Filter Set variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] diff --git a/Mathlib/Analysis/Calculus/Deriv/Prod.lean b/Mathlib/Analysis/Calculus/Deriv/Prod.lean index e0b103cf8ddcca..78c041a972d224 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Prod.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Prod.lean @@ -26,7 +26,7 @@ public section universe u v w -open Topology Filter Asymptotics Set +open Filter Set variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] diff --git a/Mathlib/Analysis/Calculus/Deriv/Slope.lean b/Mathlib/Analysis/Calculus/Deriv/Slope.lean index e56c725fab8b85..6a258b1131e840 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Slope.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Slope.lean @@ -241,8 +241,6 @@ end Real section RealSpace -open Metric - variable {E : Type u} [NormedAddCommGroup E] [NormedSpace ℝ E] {f : ℝ → E} {f' : E} {s : Set ℝ} {x r : ℝ} diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index e52733ae9f6973..f2ef23c541dc79 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -26,7 +26,7 @@ public section universe u v w -open Topology Filter Asymptotics Set +open Set open scoped Nat variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] diff --git a/Mathlib/Analysis/Calculus/DifferentialForm/VectorField.lean b/Mathlib/Analysis/Calculus/DifferentialForm/VectorField.lean index a816b9f515f577..4135c68b1c3bfd 100644 --- a/Mathlib/Analysis/Calculus/DifferentialForm/VectorField.lean +++ b/Mathlib/Analysis/Calculus/DifferentialForm/VectorField.lean @@ -36,7 +36,7 @@ For this reason, we have `-` before the sum in our formal statement. public section -open Filter ContinuousAlternatingMap Finset VectorField +open ContinuousAlternatingMap Finset VectorField open scoped Topology variable {𝕜 E F : Type*} diff --git a/Mathlib/Analysis/Calculus/FDeriv/Basic.lean b/Mathlib/Analysis/Calculus/FDeriv/Basic.lean index 7153e3ef8b08c9..ee7ef484ab4e80 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Basic.lean @@ -109,7 +109,7 @@ derivative, differentiable, Fréchet, calculus public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter Asymptotics ContinuousLinearMap Set Topology NNReal noncomputable section diff --git a/Mathlib/Analysis/Calculus/FDeriv/Comp.lean b/Mathlib/Analysis/Calculus/FDeriv/Comp.lean index b569401f8f2ceb..4eefb0d3610c2a 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Comp.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Comp.lean @@ -20,7 +20,7 @@ composition of functions (the chain rule). public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter Asymptotics ContinuousLinearMap Set Topology noncomputable section diff --git a/Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean b/Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean index ff3a7d7f2560e4..6c8da1e83ab3c1 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/CompCLM.lean @@ -23,7 +23,7 @@ This file contains the usual formulas (and existence assertions) for the derivat public section -open Asymptotics ContinuousLinearMap Topology +open ContinuousLinearMap section diff --git a/Mathlib/Analysis/Calculus/FDeriv/Congr.lean b/Mathlib/Analysis/Calculus/FDeriv/Congr.lean index fa50ff49921b4e..9010a195b2dfff 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Congr.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Congr.lean @@ -20,7 +20,7 @@ derivative, differentiable, Fréchet, calculus public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter Asymptotics ContinuousLinearMap Set Topology noncomputable section diff --git a/Mathlib/Analysis/Calculus/FDeriv/Const.lean b/Mathlib/Analysis/Calculus/FDeriv/Const.lean index 1b8be7c7309c45..998a45cd6424ce 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Const.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Const.lean @@ -22,7 +22,7 @@ derivative, differentiable, Fréchet, calculus public section -open Asymptotics Function Filter Set Metric +open Asymptotics Function Filter Set open scoped Topology NNReal ENNReal noncomputable section diff --git a/Mathlib/Analysis/Calculus/FDeriv/Defs.lean b/Mathlib/Analysis/Calculus/FDeriv/Defs.lean index d7a84bb64d1fa7..3bbce951f15c2d 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Defs.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Defs.lean @@ -82,7 +82,7 @@ derivative, differentiable, Fréchet, calculus @[expose] public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter Asymptotics ContinuousLinearMap Set Topology variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] diff --git a/Mathlib/Analysis/Calculus/FDeriv/Equiv.lean b/Mathlib/Analysis/Calculus/FDeriv/Equiv.lean index acf9397be0212c..a2832b11f2229d 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Equiv.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Equiv.lean @@ -24,7 +24,7 @@ The inverse function theorem is in `Mathlib/Analysis/Calculus/InverseFunctionThe public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter Asymptotics ContinuousLinearMap Set Topology NNReal noncomputable section diff --git a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean index 305bb401e14bca..aaafc77d15100c 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean @@ -788,8 +788,6 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] namespace FDerivMeasurableAux -open Uniformity - lemma isOpen_A_with_param {r s : ℝ} (hf : Continuous f.uncurry) (L : E →L[𝕜] F) : IsOpen {p : α × E | p.2 ∈ A (f p.1) L r s} := by have : ProperSpace E := .of_locallyCompactSpace 𝕜 diff --git a/Mathlib/Analysis/Calculus/FDeriv/Prod.lean b/Mathlib/Analysis/Calculus/FDeriv/Prod.lean index dbb096bfa9f7d1..9ed81206aa0030 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Prod.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Prod.lean @@ -22,7 +22,7 @@ Cartesian products of functions, and functions into Pi-types. public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter Asymptotics ContinuousLinearMap Set noncomputable section diff --git a/Mathlib/Analysis/Calculus/FDeriv/RestrictScalars.lean b/Mathlib/Analysis/Calculus/FDeriv/RestrictScalars.lean index ccf673194c5f3d..1e381c43d0f9d3 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/RestrictScalars.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/RestrictScalars.lean @@ -20,7 +20,7 @@ the scalar restriction of a linear map. public section -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal +open Filter ContinuousLinearMap Set noncomputable section diff --git a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean index ddbfde34b6c570..6d319b9d8520f0 100644 --- a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean +++ b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean @@ -29,7 +29,7 @@ multilinear, formal series noncomputable section -open Set Fin Topology +open Set Fin universe u u' v w x y variable {𝕜 : Type u} {𝕜' : Type u'} {E : Type v} {F : Type w} {G : Type x} {H : Type y} diff --git a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FDeriv.lean b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FDeriv.lean index dab1f7b269b71a..0551f85dd69402 100644 --- a/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/InverseFunctionTheorem/FDeriv.lean @@ -43,7 +43,7 @@ derivative, strictly differentiable, continuously differentiable, smooth, invers @[expose] public section -open Function Set Filter Metric +open Set Filter open scoped Topology NNReal @@ -53,7 +53,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -open Asymptotics Filter Metric Set +open Asymptotics Filter Set open ContinuousLinearMap (id) diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean index 301c2076a2ee07..86135f3b729563 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean @@ -46,7 +46,7 @@ iterated Fréchet derivative. noncomputable section open scoped Topology ContDiff -open Filter Asymptotics Set +open Filter Set variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] diff --git a/Mathlib/Analysis/Calculus/ParametricIntervalIntegral.lean b/Mathlib/Analysis/Calculus/ParametricIntervalIntegral.lean index 6a44e04a88fffa..778e967eb411db 100644 --- a/Mathlib/Analysis/Calculus/ParametricIntervalIntegral.lean +++ b/Mathlib/Analysis/Calculus/ParametricIntervalIntegral.lean @@ -17,7 +17,7 @@ integrals. -/ public section -open TopologicalSpace MeasureTheory Filter Metric Set +open TopologicalSpace MeasureTheory Filter Set open scoped Topology Filter Interval diff --git a/Mathlib/Analysis/Calculus/SmoothSeries.lean b/Mathlib/Analysis/Calculus/SmoothSeries.lean index 73c763dade6705..e831266f23f5d8 100644 --- a/Mathlib/Analysis/Calculus/SmoothSeries.lean +++ b/Mathlib/Analysis/Calculus/SmoothSeries.lean @@ -26,7 +26,7 @@ We also give versions of these statements which are localized to a set. public section -open Set Metric TopologicalSpace Function Asymptotics Filter +open Set TopologicalSpace Function Filter open scoped Topology NNReal diff --git a/Mathlib/Analysis/Calculus/TangentCone/Basic.lean b/Mathlib/Analysis/Calculus/TangentCone/Basic.lean index daa37e93316213..ad2f89743eddce 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Basic.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Basic.lean @@ -18,7 +18,7 @@ and `UniqueDiffOn`. public section -open Filter Set Metric +open Filter Set open scoped Topology Pointwise variable {𝕜 E : Type*} diff --git a/Mathlib/Analysis/Calculus/TangentCone/Defs.lean b/Mathlib/Analysis/Calculus/TangentCone/Defs.lean index f78390aa206123..14b08a77f07a18 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/Defs.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/Defs.lean @@ -35,7 +35,7 @@ prove here. @[expose] public section -open Filter Set Metric +open Filter Set open scoped Topology Pointwise universe u v diff --git a/Mathlib/Analysis/Calculus/TangentCone/DimOne.lean b/Mathlib/Analysis/Calculus/TangentCone/DimOne.lean index c37ceed1c2c582..7a44d5aecd97e3 100644 --- a/Mathlib/Analysis/Calculus/TangentCone/DimOne.lean +++ b/Mathlib/Analysis/Calculus/TangentCone/DimOne.lean @@ -19,7 +19,7 @@ iff `x` is an accumulation point of the set, see `uniqueDiffWithinAt_iff_accPt`. public section -open Filter Metric Set +open Filter Set open scoped Topology variable {𝕜 : Type*} [NormedDivisionRing 𝕜] diff --git a/Mathlib/Analysis/Complex/AbsMax.lean b/Mathlib/Analysis/Complex/AbsMax.lean index d3f4f0ec12187f..20478d67f140da 100644 --- a/Mathlib/Analysis/Complex/AbsMax.lean +++ b/Mathlib/Analysis/Complex/AbsMax.lean @@ -83,7 +83,7 @@ maximum modulus principle, complex analysis public section -open TopologicalSpace Metric Set Filter Asymptotics Function MeasureTheory AffineMap Bornology +open TopologicalSpace Metric Set Filter Function AffineMap Bornology open scoped Topology Filter NNReal Real diff --git a/Mathlib/Analysis/Complex/Harmonic/Analytic.lean b/Mathlib/Analysis/Complex/Harmonic/Analytic.lean index bcf8efc296cddc..43db4fc7c9572c 100644 --- a/Mathlib/Analysis/Complex/Harmonic/Analytic.lean +++ b/Mathlib/Analysis/Complex/Harmonic/Analytic.lean @@ -20,7 +20,7 @@ holomorphic on the ball. This implies in particular that harmonic functions are public section -open Complex InnerProductSpace Metric Set Topology +open Complex InnerProductSpace Metric Set variable {f : ℂ → ℝ} {x : ℂ} diff --git a/Mathlib/Analysis/Complex/Harmonic/Poisson.lean b/Mathlib/Analysis/Complex/Harmonic/Poisson.lean index a496e295af0e66..ce8970468be3b0 100644 --- a/Mathlib/Analysis/Complex/Harmonic/Poisson.lean +++ b/Mathlib/Analysis/Complex/Harmonic/Poisson.lean @@ -20,7 +20,7 @@ TODO: Extend this formula to vector-valued harmonic functions public section -open Complex InnerProductSpace Metric Real Topology +open Complex InnerProductSpace Metric Real variable {f : ℂ → ℝ} {c w : ℂ} {R : ℝ} diff --git a/Mathlib/Analysis/Complex/Liouville.lean b/Mathlib/Analysis/Complex/Liouville.lean index 6dbaa4eb65d1a6..b44338eadde7bc 100644 --- a/Mathlib/Analysis/Complex/Liouville.lean +++ b/Mathlib/Analysis/Complex/Liouville.lean @@ -24,7 +24,7 @@ The proof is based on the Cauchy integral formula for the derivative of an analy public section -open TopologicalSpace Metric Set Filter Asymptotics Function MeasureTheory Bornology +open TopologicalSpace Metric Set Filter Function Bornology open scoped Topology Filter NNReal Real diff --git a/Mathlib/Analysis/Complex/LocallyUniformLimit.lean b/Mathlib/Analysis/Complex/LocallyUniformLimit.lean index afc9908533c307..2a301070e1f25c 100644 --- a/Mathlib/Analysis/Complex/LocallyUniformLimit.lean +++ b/Mathlib/Analysis/Complex/LocallyUniformLimit.lean @@ -26,7 +26,7 @@ subset of the complex plane. @[expose] public section -open Set Metric MeasureTheory Filter Complex intervalIntegral +open Set Metric Filter Complex open scoped Real Topology diff --git a/Mathlib/Analysis/Complex/MeanValue.lean b/Mathlib/Analysis/Complex/MeanValue.lean index e49a236535624b..c7a04b9bbf0330 100644 --- a/Mathlib/Analysis/Complex/MeanValue.lean +++ b/Mathlib/Analysis/Complex/MeanValue.lean @@ -19,7 +19,7 @@ averages over suitable weighted functions. public section -open Complex Filter Function Metric Real Set Topology +open Complex Metric Real Set variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] [CompleteSpace E] diff --git a/Mathlib/Analysis/Complex/Norm.lean b/Mathlib/Analysis/Complex/Norm.lean index 0898fb3ad035a8..5969f71fdcb38a 100644 --- a/Mathlib/Analysis/Complex/Norm.lean +++ b/Mathlib/Analysis/Complex/Norm.lean @@ -17,7 +17,7 @@ public import Mathlib.Data.Complex.Basic noncomputable section -open ComplexConjugate Topology Filter Set +open ComplexConjugate Set namespace Complex variable {z : ℂ} diff --git a/Mathlib/Analysis/Complex/ReImTopology.lean b/Mathlib/Analysis/Complex/ReImTopology.lean index d7cb693dea1abd..72d4301f3ffaad 100644 --- a/Mathlib/Analysis/Complex/ReImTopology.lean +++ b/Mathlib/Analysis/Complex/ReImTopology.lean @@ -218,7 +218,7 @@ alias frontier_setOf_le_re_and_im_le := frontier_setOfPred_le_re_and_im_le end Complex -open Complex Metric +open Complex variable {s t : Set ℝ} diff --git a/Mathlib/Analysis/Complex/Schwarz.lean b/Mathlib/Analysis/Complex/Schwarz.lean index 00be646899782c..f85d1999f403c5 100644 --- a/Mathlib/Analysis/Complex/Schwarz.lean +++ b/Mathlib/Analysis/Complex/Schwarz.lean @@ -55,7 +55,7 @@ we state it for maps between any two normed spaces. Schwarz lemma -/ -open Metric Set Function Filter TopologicalSpace +open Metric Set Function Filter open scoped Topology ComplexConjugate diff --git a/Mathlib/Analysis/Complex/Trigonometric.lean b/Mathlib/Analysis/Complex/Trigonometric.lean index 3d37f9aa071a00..bafac5c4e1cbb0 100644 --- a/Mathlib/Analysis/Complex/Trigonometric.lean +++ b/Mathlib/Analysis/Complex/Trigonometric.lean @@ -18,7 +18,7 @@ hyperbolic sine, hyperbolic cosine, and hyperbolic tangent functions. @[expose] public section -open CauSeq Finset IsAbsoluteValue +open Finset open scoped ComplexConjugate namespace Complex @@ -839,7 +839,7 @@ nonrec theorem cosh_three_mul : cosh (3 * x) = 4 * cosh x ^ 3 - 3 * cosh x := by nonrec theorem sinh_three_mul : sinh (3 * x) = 4 * sinh x ^ 3 + 3 * sinh x := by rw [← ofReal_inj]; simp [sinh_three_mul] -open IsAbsoluteValue Nat +open Nat /-- `Real.cosh` is always positive -/ theorem cosh_pos (x : ℝ) : 0 < Real.cosh x := diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index dae7cbc9f06edb..d388e507ce641d 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -134,7 +134,7 @@ end UpperHalfPlane namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: `UpperHalfPlane.im`. -/ @[positivity UpperHalfPlane.im _] diff --git a/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean b/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean index ca8a1ad15387d2..5a43e0f1c55d52 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/Cartan.lean @@ -34,7 +34,7 @@ discussion. public section -open Filter Metric Real Set Topology +open Filter Metric Real Set variable {f : ℂ → ℂ} {R : ℝ} diff --git a/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean b/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean index a533a0991f2211..2a10cfecad7ddd 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/CharacteristicFunction.lean @@ -33,7 +33,7 @@ Approximation*][MR3156076] for a detailed discussion. @[expose] public section -open Filter Metric Real Set +open Filter Real Set namespace ValueDistribution diff --git a/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean b/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean index d51c71156612ef..87aabc9f115e47 100644 --- a/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean +++ b/Mathlib/Analysis/Complex/ValueDistribution/FirstMainTheorem.lean @@ -30,7 +30,7 @@ Approximation*][MR3156076] for a detailed discussion. public section namespace ValueDistribution -open Asymptotics Filter Function.locallyFinsuppWithin MeromorphicAt MeromorphicOn Metric Real +open Asymptotics Filter Function.locallyFinsuppWithin MeromorphicOn Metric Real section FirstPart diff --git a/Mathlib/Analysis/Convex/Cone/Basic.lean b/Mathlib/Analysis/Convex/Cone/Basic.lean index 0af4828ca36209..424d814f53c387 100644 --- a/Mathlib/Analysis/Convex/Cone/Basic.lean +++ b/Mathlib/Analysis/Convex/Cone/Basic.lean @@ -45,7 +45,7 @@ The next steps are: @[expose] public section -open ContinuousLinearMap Filter Function Set +open ContinuousLinearMap Function Set variable {𝕜 R E F G : Type*} [Semiring R] [PartialOrder R] [IsOrderedRing R] variable [AddCommMonoid E] [TopologicalSpace E] [Module R E] diff --git a/Mathlib/Analysis/Convex/Deriv.lean b/Mathlib/Analysis/Convex/Deriv.lean index 2b1ccf5be34b2b..1b4b7285f0161d 100644 --- a/Mathlib/Analysis/Convex/Deriv.lean +++ b/Mathlib/Analysis/Convex/Deriv.lean @@ -23,7 +23,7 @@ Here we relate convexity of functions `ℝ → ℝ` to properties of their deriv public section -open Metric Set Asymptotics ContinuousLinearMap Filter +open Set Filter open scoped Topology NNReal /-! diff --git a/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean b/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean index 3e493475626fd0..7d9a8f7e16ba73 100644 --- a/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean +++ b/Mathlib/Analysis/Convex/DoublyStochasticMatrix.lean @@ -28,7 +28,7 @@ Doubly stochastic, Birkhoff's theorem, Birkhoff-von Neumann theorem @[expose] public section -open Finset Function Matrix +open Finset Matrix variable {R n : Type*} [Fintype n] [DecidableEq n] diff --git a/Mathlib/Analysis/Convex/Exposed.lean b/Mathlib/Analysis/Convex/Exposed.lean index 66d569963faad9..a684d3740e3390 100644 --- a/Mathlib/Analysis/Convex/Exposed.lean +++ b/Mathlib/Analysis/Convex/Exposed.lean @@ -43,7 +43,7 @@ Prove lemmas relating exposed sets and points to the intrinsic frontier. @[expose] public section -open Affine Set +open Set section PreorderSemiring diff --git a/Mathlib/Analysis/Convex/Extreme.lean b/Mathlib/Analysis/Convex/Extreme.lean index a3daff0007e3da..915764e46ad2c6 100644 --- a/Mathlib/Analysis/Convex/Extreme.lean +++ b/Mathlib/Analysis/Convex/Extreme.lean @@ -43,7 +43,7 @@ Prove lemmas relating extreme sets and points to the intrinsic frontier. @[expose] public section -open Function Module Set Affine +open Function Module Set variable {𝕜 E F ι : Type*} {M : ι → Type*} diff --git a/Mathlib/Analysis/Convex/Function.lean b/Mathlib/Analysis/Convex/Function.lean index 78749ca0befddc..63662a49b8d878 100644 --- a/Mathlib/Analysis/Convex/Function.lean +++ b/Mathlib/Analysis/Convex/Function.lean @@ -30,7 +30,7 @@ a convex set. @[expose] public section -open LinearMap Set Convex Pointwise +open LinearMap Set Convex variable {𝕜 E F α β ι : Type*} diff --git a/Mathlib/Analysis/Convex/Independent.lean b/Mathlib/Analysis/Convex/Independent.lean index c6e5858a1e69b2..a6bb28916ba51c 100644 --- a/Mathlib/Analysis/Convex/Independent.lean +++ b/Mathlib/Analysis/Convex/Independent.lean @@ -44,7 +44,7 @@ independence, convex position @[expose] public section -open Affine Finset Function +open Finset Function variable {𝕜 E ι : Type*} diff --git a/Mathlib/Analysis/Convex/Jensen.lean b/Mathlib/Analysis/Convex/Jensen.lean index fe77049f8736c4..1036c148628bd4 100644 --- a/Mathlib/Analysis/Convex/Jensen.lean +++ b/Mathlib/Analysis/Convex/Jensen.lean @@ -35,7 +35,7 @@ As corollaries, we get: public section -open Finset LinearMap Set Convex Pointwise +open Finset Set Convex variable {𝕜 E F β ι : Type*} diff --git a/Mathlib/Analysis/Convex/LinearIsometry.lean b/Mathlib/Analysis/Convex/LinearIsometry.lean index 33daf80c837f85..7db1a30301986e 100644 --- a/Mathlib/Analysis/Convex/LinearIsometry.lean +++ b/Mathlib/Analysis/Convex/LinearIsometry.lean @@ -17,7 +17,7 @@ In this file we prove some basic lemmas about (strict) convexity and linear isom public section -open Function Set Metric +open Set Metric open scoped Convex section SeminormedAddCommGroup diff --git a/Mathlib/Analysis/Convex/MetricSpace.lean b/Mathlib/Analysis/Convex/MetricSpace.lean index 32c1b7127a55bc..97eb94dfadedd6 100644 --- a/Mathlib/Analysis/Convex/MetricSpace.lean +++ b/Mathlib/Analysis/Convex/MetricSpace.lean @@ -43,8 +43,6 @@ public section namespace Convexity -open ConvexSpace - variable {I X : Type*} variable (X) in diff --git a/Mathlib/Analysis/Convex/Segment.lean b/Mathlib/Analysis/Convex/Segment.lean index c5933d477bfb22..01f14c053f9f3e 100644 --- a/Mathlib/Analysis/Convex/Segment.lean +++ b/Mathlib/Analysis/Convex/Segment.lean @@ -95,8 +95,6 @@ theorem openSegment_subset_iff : end SMul -open Convex - section MulActionWithZero variable (𝕜) diff --git a/Mathlib/Analysis/Convex/StrictConvexBetween.lean b/Mathlib/Analysis/Convex/StrictConvexBetween.lean index 43ca1ad16da523..4fc673691d6738 100644 --- a/Mathlib/Analysis/Convex/StrictConvexBetween.lean +++ b/Mathlib/Analysis/Convex/StrictConvexBetween.lean @@ -20,7 +20,6 @@ space. @[expose] public section -open Metric open scoped Convex variable {V P : Type*} [NormedAddCommGroup V] [NormedSpace ℝ V] diff --git a/Mathlib/Analysis/Convex/StrictConvexSpace.lean b/Mathlib/Analysis/Convex/StrictConvexSpace.lean index d0bb7c6c8cfbf3..167083bd1e0e23 100644 --- a/Mathlib/Analysis/Convex/StrictConvexSpace.lean +++ b/Mathlib/Analysis/Convex/StrictConvexSpace.lean @@ -56,7 +56,7 @@ convex, strictly convex public section -open Convex Pointwise Set Metric +open Convex Set Metric /-- A *strictly convex space* is a normed space where the closed balls are strictly convex. We only require balls of positive radius with center at the origin to be strictly convex in the definition, diff --git a/Mathlib/Analysis/Convex/Uniform.lean b/Mathlib/Analysis/Convex/Uniform.lean index cf78bab0a7c022..6d66e274f5bcc8 100644 --- a/Mathlib/Analysis/Convex/Uniform.lean +++ b/Mathlib/Analysis/Convex/Uniform.lean @@ -33,11 +33,6 @@ convex, uniformly convex public section - -open Set Metric - -open Convex Pointwise - /-- A *uniformly convex space* is a real normed space where the triangle inequality is strict with a uniform bound. Namely, over the `x` and `y` of norm `1`, `‖x + y‖` is uniformly bounded above by a constant `< 2` when `‖x - y‖` is uniformly bounded below by a positive constant. -/ diff --git a/Mathlib/Analysis/Convolution.lean b/Mathlib/Analysis/Convolution.lean index 2f7b10b145e3f6..4ef7ef9b70e4e7 100644 --- a/Mathlib/Analysis/Convolution.lean +++ b/Mathlib/Analysis/Convolution.lean @@ -89,7 +89,7 @@ assert_not_exists ContDiffAt HasDerivAt @[expose] public section open Set Function Filter MeasureTheory MeasureTheory.Measure TopologicalSpace -open Bornology ContinuousLinearMap Metric Topology +open ContinuousLinearMap Metric Topology open scoped Pointwise NNReal Filter universe u𝕜 uG uE uE' uE'' uF uF' uF'' uP diff --git a/Mathlib/Analysis/Distribution/DerivNotation.lean b/Mathlib/Analysis/Distribution/DerivNotation.lean index ac41360aa6d623..07aaa764f14df1 100644 --- a/Mathlib/Analysis/Distribution/DerivNotation.lean +++ b/Mathlib/Analysis/Distribution/DerivNotation.lean @@ -291,7 +291,7 @@ variable [CommRing R] [AddCommGroup E] [Module R E] [LineDerivAdd E V₂ V₃] [LineDerivAdd E V₁ V₂] [LineDerivSMul R E V₂ V₃] [LineDerivLeftSMul R E V₁ V₂] [LineDerivLeftSMul R E V₂ V₃] -open InnerProductSpace TensorProduct +open TensorProduct variable (R) in /-- The second derivative in terms `lineDerivOp` as a bilinear map. diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean index 3662f5e0037daf..a09c0ecd442313 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Basic.lean @@ -1093,7 +1093,7 @@ section Integration /-! ### Integration -/ -open Real Complex Filter MeasureTheory MeasureTheory.Measure Module +open Real Filter MeasureTheory MeasureTheory.Measure Module variable [RCLike 𝕜] variable [NormedAddCommGroup D] [NormedSpace ℝ D] diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean b/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean index 9efebf08e07e4c..1f8ff065657a44 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace/Deriv.lean @@ -216,7 +216,7 @@ section integration_by_parts variable [NormedSpace ℝ E] -open ENNReal MeasureTheory +open MeasureTheory section one_dim diff --git a/Mathlib/Analysis/Distribution/TestFunction.lean b/Mathlib/Analysis/Distribution/TestFunction.lean index 93e58459dfd467..df3405dd451f77 100644 --- a/Mathlib/Analysis/Distribution/TestFunction.lean +++ b/Mathlib/Analysis/Distribution/TestFunction.lean @@ -53,7 +53,7 @@ distributions, test function @[expose] public section -open Function Seminorm SeminormFamily Set TopologicalSpace UniformSpace +open Function Set TopologicalSpace UniformSpace open scoped BoundedContinuousFunction NNReal Topology ContDiff variable {𝕜 𝕂 : Type*} [NontriviallyNormedField 𝕜] diff --git a/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean b/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean index 508771150864a1..108c80cb65dae9 100644 --- a/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean +++ b/Mathlib/Analysis/Fourier/BoundedContinuousFunctionChar.lean @@ -39,7 +39,7 @@ measure. @[expose] public section -open Filter BoundedContinuousFunction Complex +open BoundedContinuousFunction Complex namespace BoundedContinuousFunction diff --git a/Mathlib/Analysis/Fourier/FiniteAbelian/Orthogonality.lean b/Mathlib/Analysis/Fourier/FiniteAbelian/Orthogonality.lean index 619b123068af91..74ae2ed0df4931 100644 --- a/Mathlib/Analysis/Fourier/FiniteAbelian/Orthogonality.lean +++ b/Mathlib/Analysis/Fourier/FiniteAbelian/Orthogonality.lean @@ -20,7 +20,7 @@ public section open Finset hiding card open Fintype (card) -open Function RCLike +open RCLike open scoped BigOperators ComplexConjugate DirectSum variable {G H R : Type*} diff --git a/Mathlib/Analysis/Fourier/Inversion.lean b/Mathlib/Analysis/Fourier/Inversion.lean index 5fecc40d5bcbdc..c1e54ede8b12a6 100644 --- a/Mathlib/Analysis/Fourier/Inversion.lean +++ b/Mathlib/Analysis/Fourier/Inversion.lean @@ -41,7 +41,7 @@ rely on the explicit computation of the Fourier transform of Gaussians. public section -open Filter MeasureTheory Complex Module Metric Real Bornology +open Filter MeasureTheory Complex Module Real Bornology open scoped Topology FourierTransform RealInnerProductSpace Complex diff --git a/Mathlib/Analysis/InnerProductSpace/Calculus.lean b/Mathlib/Analysis/InnerProductSpace/Calculus.lean index 0cb732b074509d..a876761210bfec 100644 --- a/Mathlib/Analysis/InnerProductSpace/Calculus.lean +++ b/Mathlib/Analysis/InnerProductSpace/Calculus.lean @@ -32,7 +32,7 @@ The last part of the file should be generalized to `PiLp`. noncomputable section -open RCLike Real Filter +open RCLike Real section DerivInner diff --git a/Mathlib/Analysis/InnerProductSpace/Continuous.lean b/Mathlib/Analysis/InnerProductSpace/Continuous.lean index 9775c5b0524fba..ef43fde3e2fa87 100644 --- a/Mathlib/Analysis/InnerProductSpace/Continuous.lean +++ b/Mathlib/Analysis/InnerProductSpace/Continuous.lean @@ -23,7 +23,7 @@ public section noncomputable section -open RCLike Real Filter Topology ComplexConjugate Finsupp +open RCLike Real Filter Topology open LinearMap renaming BilinForm → BilinForm variable {𝕜 E F : Type*} [RCLike 𝕜] diff --git a/Mathlib/Analysis/InnerProductSpace/Convex.lean b/Mathlib/Analysis/InnerProductSpace/Convex.lean index decacf811f501d..df5747b3afcdb4 100644 --- a/Mathlib/Analysis/InnerProductSpace/Convex.lean +++ b/Mathlib/Analysis/InnerProductSpace/Convex.lean @@ -26,7 +26,7 @@ public section noncomputable section -open RCLike Real Filter Topology ComplexConjugate Finsupp +open Real open LinearMap (BilinForm) variable {𝕜 E F : Type*} [RCLike 𝕜] [SeminormedAddCommGroup E] [InnerProductSpace 𝕜 E] diff --git a/Mathlib/Analysis/InnerProductSpace/Defs.lean b/Mathlib/Analysis/InnerProductSpace/Defs.lean index c9bff8edc5adf4..78e3e893066037 100644 --- a/Mathlib/Analysis/InnerProductSpace/Defs.lean +++ b/Mathlib/Analysis/InnerProductSpace/Defs.lean @@ -69,7 +69,7 @@ The Coq code is available at the following address: inner 𝕜 x y local notation "absR" => @abs ℝ _ _ -open Topology Finsupp Submodule RCLike Real Filter InnerProductSpace +open Finsupp Submodule RCLike Real InnerProductSpace open LinearMap (ker range) variable (K : Submodule 𝕜 E) diff --git a/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean b/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean index 5640963319a3c1..99f5d55d71883d 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection/Submodule.lean @@ -110,7 +110,7 @@ theorem orthogonal_eq_bot_iff [K.HasOrthogonalProjection] : Kᗮ = ⊥ ↔ K = have : K ⊔ Kᗮ = ⊤ := Submodule.sup_orthogonal_of_hasOrthogonalProjection rwa [h, sup_comm, bot_sup_eq] at this -open Topology Finsupp RCLike Real Filter +open Topology RCLike Real Filter /-- Given a monotone family `U` of complete submodules of `E` and a fixed `x : E`, the orthogonal projection of `x` on `U i` tends to the orthogonal projection of `x` on diff --git a/Mathlib/Analysis/InnerProductSpace/StandardSubspace.lean b/Mathlib/Analysis/InnerProductSpace/StandardSubspace.lean index 35b4de247cb9c9..2b703a3df30fcb 100644 --- a/Mathlib/Analysis/InnerProductSpace/StandardSubspace.lean +++ b/Mathlib/Analysis/InnerProductSpace/StandardSubspace.lean @@ -44,7 +44,7 @@ Define the Tomita conjugation, prove Tomita's theorem, prove the KMS condition. @[expose] public section -open Complex ContinuousLinearMap +open Complex open scoped ComplexInnerProductSpace section ScalarSMulCLE diff --git a/Mathlib/Analysis/InnerProductSpace/Subspace.lean b/Mathlib/Analysis/InnerProductSpace/Subspace.lean index 9c9ac2bbf1896a..452348de4fce49 100644 --- a/Mathlib/Analysis/InnerProductSpace/Subspace.lean +++ b/Mathlib/Analysis/InnerProductSpace/Subspace.lean @@ -18,7 +18,7 @@ some theorems about orthogonal families of subspaces. noncomputable section -open RCLike Real Filter Topology ComplexConjugate Finsupp Module +open RCLike Real Module open LinearMap (BilinForm) diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean index 06bf70242eb829..7b751608759d6c 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvexOpen.lean @@ -35,7 +35,7 @@ convex open neighborhoods of zero. open NormedField Set -open NNReal Pointwise Topology +open Topology variable {𝕜 E : Type*} diff --git a/Mathlib/Analysis/LocallyConvex/Montel.lean b/Mathlib/Analysis/LocallyConvex/Montel.lean index e4c1a2e46169f2..e6af14e29fa167 100644 --- a/Mathlib/Analysis/LocallyConvex/Montel.lean +++ b/Mathlib/Analysis/LocallyConvex/Montel.lean @@ -30,7 +30,7 @@ space would be `[MontelSpace 𝕜 E] [BarrelledSpace 𝕜 E]`. @[expose] public section -open Filter Topology Set ContinuousLinearMap Bornology +open Filter Set ContinuousLinearMap Bornology section Definition diff --git a/Mathlib/Analysis/LocallyConvex/Polar.lean b/Mathlib/Analysis/LocallyConvex/Polar.lean index ed78d7dbaea42c..a05b422e2a5de5 100644 --- a/Mathlib/Analysis/LocallyConvex/Polar.lean +++ b/Mathlib/Analysis/LocallyConvex/Polar.lean @@ -40,8 +40,6 @@ polar variable {𝕜 E F : Type*} -open Topology - namespace LinearMap section NormedRing diff --git a/Mathlib/Analysis/LocallyConvex/StrongTopology.lean b/Mathlib/Analysis/LocallyConvex/StrongTopology.lean index 71979c683adb39..1d5da97db92c13 100644 --- a/Mathlib/Analysis/LocallyConvex/StrongTopology.lean +++ b/Mathlib/Analysis/LocallyConvex/StrongTopology.lean @@ -29,9 +29,6 @@ locally convex, bounded convergence public section - -open Topology UniformConvergence - variable {R 𝕜₁ 𝕜₂ E F : Type*} variable [AddCommGroup E] [TopologicalSpace E] [AddCommGroup F] [TopologicalSpace F] diff --git a/Mathlib/Analysis/Matrix/PosDef.lean b/Mathlib/Analysis/Matrix/PosDef.lean index a9e7fd020b3fd7..9b499da70d66ef 100644 --- a/Mathlib/Analysis/Matrix/PosDef.lean +++ b/Mathlib/Analysis/Matrix/PosDef.lean @@ -22,7 +22,7 @@ This file proves that eigenvalues of positive (semi)definite matrices are (nonne @[expose] public section -open WithLp Matrix Unitary +open Matrix Unitary open scoped ComplexOrder namespace Matrix diff --git a/Mathlib/Analysis/Meromorphic/RCLike.lean b/Mathlib/Analysis/Meromorphic/RCLike.lean index fdfa23aebe7bb1..1e2d6596e64977 100644 --- a/Mathlib/Analysis/Meromorphic/RCLike.lean +++ b/Mathlib/Analysis/Meromorphic/RCLike.lean @@ -16,7 +16,7 @@ This file gathers results on meromorphic functions specifict to the real and com public section -open Set Complex +open Set variable {𝕜 : Type*} [RCLike 𝕜] diff --git a/Mathlib/Analysis/Normed/Affine/AddTorsor.lean b/Mathlib/Analysis/Normed/Affine/AddTorsor.lean index ad55eec21840bb..7dec25f132fa8e 100644 --- a/Mathlib/Analysis/Normed/Affine/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Affine/AddTorsor.lean @@ -24,9 +24,7 @@ This file contains lemmas about normed additive torsors over normed spaces. noncomputable section -open NNReal Topology - -open Filter +open NNReal variable {V P W Q : Type*} [SeminormedAddCommGroup V] [PseudoMetricSpace P] [NormedAddTorsor V P] [NormedAddCommGroup W] [MetricSpace Q] [NormedAddTorsor W Q] diff --git a/Mathlib/Analysis/Normed/Affine/MazurUlam.lean b/Mathlib/Analysis/Normed/Affine/MazurUlam.lean index 7b9dafac98dbc3..97a64fda4f043f 100644 --- a/Mathlib/Analysis/Normed/Affine/MazurUlam.lean +++ b/Mathlib/Analysis/Normed/Affine/MazurUlam.lean @@ -35,7 +35,7 @@ variable {E PE F PF : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [MetricS [NormedAddTorsor E PE] [NormedAddCommGroup F] [NormedSpace ℝ F] [MetricSpace PF] [NormedAddTorsor F PF] -open Set AffineMap AffineIsometryEquiv +open Set AffineIsometryEquiv noncomputable section diff --git a/Mathlib/Analysis/Normed/Field/Ultra.lean b/Mathlib/Analysis/Normed/Field/Ultra.lean index f0fc65d8bb86fb..054b8e2388741c 100644 --- a/Mathlib/Analysis/Normed/Field/Ultra.lean +++ b/Mathlib/Analysis/Normed/Field/Ultra.lean @@ -34,7 +34,6 @@ ultrametric, nonarchimedean -/ public section -open Metric NNReal namespace IsUltrametricDist diff --git a/Mathlib/Analysis/Normed/Group/AddTorsor.lean b/Mathlib/Analysis/Normed/Group/AddTorsor.lean index 00b071a37e83f4..7c53ef40d37cf0 100644 --- a/Mathlib/Analysis/Normed/Group/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Group/AddTorsor.lean @@ -24,7 +24,7 @@ spaces. noncomputable section -open NNReal Topology +open NNReal open Filter diff --git a/Mathlib/Analysis/Normed/Group/Continuity.lean b/Mathlib/Analysis/Normed/Group/Continuity.lean index cb8b0096449194..124eff42095a00 100644 --- a/Mathlib/Analysis/Normed/Group/Continuity.lean +++ b/Mathlib/Analysis/Normed/Group/Continuity.lean @@ -23,15 +23,13 @@ public section variable {α ι κ E F G : Type*} -open Filter Function Metric Bornology -open ENNReal Filter NNReal Uniformity Pointwise Topology +open Filter Function Metric +open ENNReal Filter NNReal Uniformity Topology section SeminormedGroup variable [SeminormedGroup E] [SeminormedGroup F] [SeminormedGroup G] -open Finset - section ContinuousENorm variable {E : Type*} [TopologicalSpace E] [ContinuousENorm E] diff --git a/Mathlib/Analysis/Normed/Group/Defs.lean b/Mathlib/Analysis/Normed/Group/Defs.lean index 91d2e8006fe908..57b8b12b1a2e0a 100644 --- a/Mathlib/Analysis/Normed/Group/Defs.lean +++ b/Mathlib/Analysis/Normed/Group/Defs.lean @@ -50,8 +50,8 @@ public section variable {𝓕 α ι κ E F G : Type*} -open Filter Function Metric Bornology -open ENNReal Filter NNReal Uniformity Pointwise Topology +open Filter Bornology +open ENNReal Filter NNReal /-- Auxiliary class, endowing a type `E` with a function `norm : E → ℝ` with notation `‖x‖`. This class is designed to be extended in more interesting classes specifying the properties of the norm. diff --git a/Mathlib/Analysis/Normed/Group/Quotient.lean b/Mathlib/Analysis/Normed/Group/Quotient.lean index 38dac8b8c09b77..e0f2be84dc49ae 100644 --- a/Mathlib/Analysis/Normed/Group/Quotient.lean +++ b/Mathlib/Analysis/Normed/Group/Quotient.lean @@ -259,7 +259,7 @@ def quotientQuotientIsometryEquivQuotient (h : S ≤ T) : (M ⧸ S) ⧸ T.map (m end QuotientGroup -open QuotientAddGroup Metric Set Topology NNReal +open QuotientAddGroup Metric Set NNReal variable {M N : Type*} [SeminormedAddCommGroup M] [SeminormedAddCommGroup N] diff --git a/Mathlib/Analysis/Normed/Group/Real.lean b/Mathlib/Analysis/Normed/Group/Real.lean index 4080f0f631f66d..53d5fef7a02e8c 100644 --- a/Mathlib/Analysis/Normed/Group/Real.lean +++ b/Mathlib/Analysis/Normed/Group/Real.lean @@ -22,8 +22,8 @@ public section variable {𝓕 α ι κ E F G : Type*} -open Filter Function Metric Bornology -open ENNReal Filter NNReal Uniformity Pointwise Topology +open Filter +open ENNReal Filter NNReal namespace NNReal diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean index 1ee7202bea5b46..f0c1939ab4538b 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean @@ -38,7 +38,7 @@ noncomputable section universe u -open UniformSpace MulOpposite CategoryTheory NormedAddGroupHom +open UniformSpace CategoryTheory NormedAddGroupHom namespace SemiNormedGrp diff --git a/Mathlib/Analysis/Normed/Group/Subgroup.lean b/Mathlib/Analysis/Normed/Group/Subgroup.lean index 7d480f16ad865d..eb63e289922262 100644 --- a/Mathlib/Analysis/Normed/Group/Subgroup.lean +++ b/Mathlib/Analysis/Normed/Group/Subgroup.lean @@ -20,10 +20,6 @@ normed group public section - -open Filter Function Metric Bornology -open ENNReal Filter NNReal Uniformity Pointwise Topology - /-! ### Subgroups of normed groups -/ variable {E : Type*} diff --git a/Mathlib/Analysis/Normed/Group/Uniform.lean b/Mathlib/Analysis/Normed/Group/Uniform.lean index 82be8e8e0979af..569b81b580ee6f 100644 --- a/Mathlib/Analysis/Normed/Group/Uniform.lean +++ b/Mathlib/Analysis/Normed/Group/Uniform.lean @@ -21,7 +21,7 @@ public section variable {𝓕 E F : Type*} -open Filter Function Metric Bornology +open Filter open scoped ENNReal NNReal Uniformity Pointwise Topology section SeminormedGroup @@ -57,8 +57,6 @@ theorem dist_self_mul_right (a b : E) : dist b (b * a) = ‖a‖ := by theorem dist_self_mul_left (a b : E) : dist (b * a) b = ‖a‖ := by rw [dist_comm, dist_self_mul_right] -open Finset - variable [FunLike 𝓕 E F] /-- A homomorphism `f` of seminormed groups is Lipschitz, if there exists a constant `C` such that diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index cc1b078c81ac74..334c902eb1c907 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -74,7 +74,7 @@ the only remaining results are about `Lipschitz` and `Antilipschitz`. @[expose] public section -open Module Real Set Filter RCLike Bornology Uniformity Topology NNReal ENNReal WithLp +open Module Real Set Filter Bornology Uniformity NNReal ENNReal WithLp noncomputable section diff --git a/Mathlib/Analysis/Normed/Lp/ProdLp.lean b/Mathlib/Analysis/Normed/Lp/ProdLp.lean index 0d0b033fbd0b2c..bec0eb8f429b3f 100644 --- a/Mathlib/Analysis/Normed/Lp/ProdLp.lean +++ b/Mathlib/Analysis/Normed/Lp/ProdLp.lean @@ -50,7 +50,7 @@ the only remaining results are about `Lipschitz` and `Antilipschitz`. @[expose] public section -open Real Set Filter RCLike Bornology Uniformity Topology NNReal ENNReal +open Real Set Filter Bornology Uniformity NNReal ENNReal noncomputable section diff --git a/Mathlib/Analysis/Normed/Lp/SmoothApprox.lean b/Mathlib/Analysis/Normed/Lp/SmoothApprox.lean index be25da2e7b60e1..b6fc018dc2b7f6 100644 --- a/Mathlib/Analysis/Normed/Lp/SmoothApprox.lean +++ b/Mathlib/Analysis/Normed/Lp/SmoothApprox.lean @@ -27,7 +27,7 @@ public section variable {α β E F : Type*} [MeasurableSpace E] [NormedAddCommGroup F] open scoped Nat NNReal ContDiff -open MeasureTheory Pointwise ENNReal +open MeasureTheory ENNReal namespace HasCompactSupport diff --git a/Mathlib/Analysis/Normed/Module/Alternating/Basic.lean b/Mathlib/Analysis/Normed/Module/Alternating/Basic.lean index b66cdf9d425823..67a83b318eedc8 100644 --- a/Mathlib/Analysis/Normed/Module/Alternating/Basic.lean +++ b/Mathlib/Analysis/Normed/Module/Alternating/Basic.lean @@ -24,7 +24,7 @@ Most proofs just invoke the corresponding fact about continuous multilinear maps noncomputable section open scoped NNReal -open Finset Metric +open Finset /-! ### Type variables diff --git a/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean b/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean index 2306585dd783fe..9ed45b676328fb 100644 --- a/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean +++ b/Mathlib/Analysis/Normed/Module/Ball/Homeomorph.lean @@ -35,7 +35,7 @@ homeomorphism, ball @[expose] public section -open Set Metric Pointwise +open Set Metric variable {E : Type*} [SeminormedAddCommGroup E] [NormedSpace ℝ E] noncomputable section diff --git a/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean b/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean index a8ca6f38fcbf99..cc66afd40fcc02 100644 --- a/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean +++ b/Mathlib/Analysis/Normed/Module/Ball/Pointwise.lean @@ -227,7 +227,7 @@ theorem disjoint_closedBall_closedBall_iff (hδ : 0 ≤ δ) (hε : 0 ≤ ε) : rw [dist_comm] at hxz exact h.le_bot ⟨hxz, hzy⟩ -open EMetric ENNReal +open ENNReal @[simp] theorem infEDist_thickening (hδ : 0 < δ) (s : Set E) (x : E) : diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index ac6832a0b303b3..3dd9b1e0fba338 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -88,8 +88,6 @@ end LinearIsometry namespace AffineIsometry -open AffineMap - variable {𝕜 : Type*} {V₁ V₂ : Type*} {P₁ P₂ : Type*} [NormedField 𝕜] [NormedAddCommGroup V₁] [SeminormedAddCommGroup V₂] [NormedSpace 𝕜 V₁] [NormedSpace 𝕜 V₂] [MetricSpace P₁] [PseudoMetricSpace P₂] [NormedAddTorsor V₁ P₁] [NormedAddTorsor V₂ P₂] diff --git a/Mathlib/Analysis/Normed/Module/HahnBanach.lean b/Mathlib/Analysis/Normed/Module/HahnBanach.lean index fd7c25cfaa0735..fc3a9ce53e5048 100644 --- a/Mathlib/Analysis/Normed/Module/HahnBanach.lean +++ b/Mathlib/Analysis/Normed/Module/HahnBanach.lean @@ -35,8 +35,6 @@ universe u v section RCLike -open RCLike - variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [IsRCLikeNormedField 𝕜] {E : Type*} [SeminormedAddCommGroup E] [NormedSpace 𝕜 E] diff --git a/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean b/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean index 6e759e7d578086..eabe46a1852fab 100644 --- a/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean +++ b/Mathlib/Analysis/Normed/Module/Multilinear/Curry.lean @@ -37,7 +37,7 @@ suppress_compilation noncomputable section -open NNReal Finset Metric ContinuousMultilinearMap Fin Function +open Finset ContinuousMultilinearMap Fin Function /-! ### Type variables diff --git a/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean b/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean index 11855889c53cd9..a83e1de6e543ef 100644 --- a/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean +++ b/Mathlib/Analysis/Normed/Module/MultipliableUniformlyOn.lean @@ -19,7 +19,7 @@ the form `∏' i, (1 + f i x)` for a sequence `f` of complex-valued functions. public section -open Filter Function Complex Finset Topology +open Filter Function Complex Finset variable {α ι : Type*} {s : Set α} {K : Set α} {u : ι → ℝ} diff --git a/Mathlib/Analysis/Normed/Module/RieszLemma.lean b/Mathlib/Analysis/Normed/Module/RieszLemma.lean index 5e1c8155be7138..e5f9fd584bd361 100644 --- a/Mathlib/Analysis/Normed/Module/RieszLemma.lean +++ b/Mathlib/Analysis/Normed/Module/RieszLemma.lean @@ -32,8 +32,6 @@ public section open Set Metric -open Topology - variable {𝕜 : Type*} [NormedField 𝕜] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {F : Type*} [SeminormedAddCommGroup F] [NormedSpace ℝ F] diff --git a/Mathlib/Analysis/Normed/Operator/Basic.lean b/Mathlib/Analysis/Normed/Operator/Basic.lean index de6448bdf39c75..2ed7ced28524d5 100644 --- a/Mathlib/Analysis/Normed/Operator/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Basic.lean @@ -142,8 +142,6 @@ theorem ebound [RingHomIsometric σ₁₂] (f : E →SL[σ₁₂] F) : section -open Filter - variable (𝕜 E) /-- Given a unit-length element `x` of a normed space `E` over a field `𝕜`, the natural linear diff --git a/Mathlib/Analysis/Normed/Operator/Bilinear.lean b/Mathlib/Analysis/Normed/Operator/Bilinear.lean index d8d68e766caf5d..79a4dd4d60556f 100644 --- a/Mathlib/Analysis/Normed/Operator/Bilinear.lean +++ b/Mathlib/Analysis/Normed/Operator/Bilinear.lean @@ -21,7 +21,6 @@ interpreted as linear maps `E → F → G` as usual (and similarly for semilinea suppress_compilation -open Bornology open Filter hiding map_smul open scoped NNReal Topology Uniformity @@ -30,7 +29,7 @@ variable {𝕜 𝕜₂ 𝕜₃ E Eₗ F Fₗ G Gₗ 𝓕 : Type*} section SemiNormed -open Metric ContinuousLinearMap +open ContinuousLinearMap variable [SeminormedAddCommGroup E] [SeminormedAddCommGroup Eₗ] [SeminormedAddCommGroup F] [SeminormedAddCommGroup Fₗ] [SeminormedAddCommGroup G] [SeminormedAddCommGroup Gₗ] @@ -46,7 +45,7 @@ namespace ContinuousLinearMap section OpNorm -open Set Real +open Real theorem opNorm_ext [RingHomIsometric σ₁₃] (f : E →SL[σ₁₂] F) (g : E →SL[σ₁₃] G) (h : ∀ x, ‖f x‖ = ‖g x‖) : ‖f‖ = ‖g‖ := diff --git a/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean b/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean index b14f659d85e0a8..45fd852e705f0f 100644 --- a/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean +++ b/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean @@ -61,7 +61,7 @@ open Topology open Filter (Tendsto) -open Metric ContinuousLinearMap +open ContinuousLinearMap section Semiring diff --git a/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean b/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean index 7cbae9947bc753..51db9ec09bacb7 100644 --- a/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean +++ b/Mathlib/Analysis/Normed/Operator/ContinuousLinearMap.lean @@ -32,9 +32,9 @@ before adding imports! @[expose] public section -open Metric ContinuousLinearMap +open ContinuousLinearMap -open Set Real +open Real open NNReal diff --git a/Mathlib/Analysis/Normed/Operator/Mul.lean b/Mathlib/Analysis/Normed/Operator/Mul.lean index 3cf11c69837973..7f47ef7384bdfd 100644 --- a/Mathlib/Analysis/Normed/Operator/Mul.lean +++ b/Mathlib/Analysis/Normed/Operator/Mul.lean @@ -19,7 +19,6 @@ of multiplication and scalar-multiplication operations in normed algebras and no suppress_compilation -open Metric open scoped NNReal Topology Uniformity variable {𝕜 E : Type*} [NontriviallyNormedField 𝕜] diff --git a/Mathlib/Analysis/Normed/Operator/NNNorm.lean b/Mathlib/Analysis/Normed/Operator/NNNorm.lean index 5510b8ea8c9b7c..2a52b05ec914f3 100644 --- a/Mathlib/Analysis/Normed/Operator/NNNorm.lean +++ b/Mathlib/Analysis/Normed/Operator/NNNorm.lean @@ -19,7 +19,6 @@ public section suppress_compilation -open Bornology open Filter hiding map_smul open scoped NNReal Topology Uniformity ENNReal open Metric ContinuousLinearMap diff --git a/Mathlib/Analysis/Normed/Operator/NormedSpace.lean b/Mathlib/Analysis/Normed/Operator/NormedSpace.lean index 7272c4bbf258d3..12440e195e23a8 100644 --- a/Mathlib/Analysis/Normed/Operator/NormedSpace.lean +++ b/Mathlib/Analysis/Normed/Operator/NormedSpace.lean @@ -149,7 +149,7 @@ end LinearMap namespace ContinuousLinearMap -open Set Real +open Real /-- An operator is zero iff its norm vanishes. -/ theorem opNorm_zero_iff [RingHomIsometric σ₁₂] : ‖f‖ = 0 ↔ f = 0 := diff --git a/Mathlib/Analysis/Normed/Operator/Prod.lean b/Mathlib/Analysis/Normed/Operator/Prod.lean index 3dc7deb8d689d6..e9787fccacfb1d 100644 --- a/Mathlib/Analysis/Normed/Operator/Prod.lean +++ b/Mathlib/Analysis/Normed/Operator/Prod.lean @@ -17,7 +17,7 @@ Interaction of operator norm with Cartesian products. variable {𝕜 E F G : Type*} [NontriviallyNormedField 𝕜] -open Set Real Metric ContinuousLinearMap +open Set Real ContinuousLinearMap section SemiNormed diff --git a/Mathlib/Analysis/Normed/Order/UpperLower.lean b/Mathlib/Analysis/Normed/Order/UpperLower.lean index 364b117e86af48..9d8befb203d9b4 100644 --- a/Mathlib/Analysis/Normed/Order/UpperLower.lean +++ b/Mathlib/Analysis/Normed/Order/UpperLower.lean @@ -32,7 +32,7 @@ situations. public section -open Bornology Function Metric Set +open Function Metric Set open scoped Pointwise variable {α ι : Type*} diff --git a/Mathlib/Analysis/Normed/Ring/Ultra.lean b/Mathlib/Analysis/Normed/Ring/Ultra.lean index a90520d01bf44b..356d1f79108565 100644 --- a/Mathlib/Analysis/Normed/Ring/Ultra.lean +++ b/Mathlib/Analysis/Normed/Ring/Ultra.lean @@ -39,7 +39,7 @@ ultrametric, nonarchimedean -/ public section -open Metric NNReal +open NNReal namespace IsUltrametricDist diff --git a/Mathlib/Analysis/Normed/Ring/Units.lean b/Mathlib/Analysis/Normed/Ring/Units.lean index da3c564517dfb9..c617763067e715 100644 --- a/Mathlib/Analysis/Normed/Ring/Units.lean +++ b/Mathlib/Analysis/Normed/Ring/Units.lean @@ -194,7 +194,7 @@ end NormedRing namespace Units -open MulOpposite Filter NormedRing +open NormedRing /-- In a normed ring with summable geometric series, the coercion from `Rˣ` (equipped with the induced topology from the embedding in `R × R`) to `R` is an open embedding. -/ diff --git a/Mathlib/Analysis/Normed/Ring/WithAbs.lean b/Mathlib/Analysis/Normed/Ring/WithAbs.lean index 5a19b8b32bd085..2ab87589e5b65c 100644 --- a/Mathlib/Analysis/Normed/Ring/WithAbs.lean +++ b/Mathlib/Analysis/Normed/Ring/WithAbs.lean @@ -25,8 +25,6 @@ public import Mathlib.Topology.Algebra.Ring.Basic @[expose] public section -open Topology - variable {R : Type*} {S : Type*} [Semiring S] [PartialOrder S] /-- Type synonym for a semiring which depends on an absolute value. This is a function that takes diff --git a/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean b/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean index 932be11a947f27..3c3cb0dec0f9f8 100644 --- a/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean +++ b/Mathlib/Analysis/Normed/Unbundled/RingSeminorm.lean @@ -43,9 +43,6 @@ ring_seminorm, ring_norm @[expose] public section - -open NNReal - variable {R : Type*} /-- A seminorm on a ring `R` is a function `f : R → ℝ` that preserves zero, takes nonnegative @@ -424,8 +421,6 @@ def RingSeminorm.toRingNorm {K : Type*} [Field K] (f : RingSeminorm K) (hnt : f def normRingNorm (R : Type*) [NonUnitalNormedRing R] : RingNorm R := { normAddGroupNorm R, normRingSeminorm R with } -open Int - set_option linter.style.whitespace false in -- manual alignment is not recognised /-- The seminorm on a `SeminormedRing`, as a `RingSeminorm`. -/ def SeminormedRing.toRingSeminorm (R : Type*) [SeminormedRing R] : RingSeminorm R where diff --git a/Mathlib/Analysis/ODE/ExistUnique.lean b/Mathlib/Analysis/ODE/ExistUnique.lean index 2e12f90333b350..57d118be53f6e5 100644 --- a/Mathlib/Analysis/ODE/ExistUnique.lean +++ b/Mathlib/Analysis/ODE/ExistUnique.lean @@ -39,7 +39,7 @@ integral curve, vector field, existence, uniqueness, Picard-Lindelöf, Gronwall @[expose] public section -open Function intervalIntegral MeasureTheory Metric Set +open Function Metric Set open scoped Nat NNReal Topology /-! ## Existence of solutions to ODEs -/ diff --git a/Mathlib/Analysis/ODE/Gronwall.lean b/Mathlib/Analysis/ODE/Gronwall.lean index 114eb0afdc524a..b3f89944997f5c 100644 --- a/Mathlib/Analysis/ODE/Gronwall.lean +++ b/Mathlib/Analysis/ODE/Gronwall.lean @@ -31,7 +31,7 @@ Sec. 4.5][HubbardWest-ode], where `norm_le_gronwallBound_of_norm_deriv_right_le` @[expose] public section -open Metric Set Asymptotics Filter Real +open Set Filter Real open scoped Topology NNReal variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] diff --git a/Mathlib/Analysis/PSeries.lean b/Mathlib/Analysis/PSeries.lean index 6499506f39f848..70b423b7d3c687 100644 --- a/Mathlib/Analysis/PSeries.lean +++ b/Mathlib/Analysis/PSeries.lean @@ -448,7 +448,7 @@ lemma Real.not_summable_indicator_one_div_natCast {m : ℕ} (hm : m ≠ 0) (k : -/ section shifted -open Filter Asymptotics Topology +open Filter Asymptotics lemma Real.summable_one_div_nat_add_rpow (a : ℝ) (s : ℝ) : Summable (fun n : ℕ ↦ 1 / |n + a| ^ s) ↔ 1 < s := by diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 6dfc89e90b652b..40d75f7f792374 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -714,8 +714,6 @@ theorem im_eq_zero_of_le {a : K} (h : ‖a‖ ≤ re a) : im a = 0 := by theorem re_eq_self_of_le {a : K} (h : ‖a‖ ≤ re a) : (re a : K) = a := by rw [← conj_eq_iff_re, conj_eq_iff_im, im_eq_zero_of_le h] -open IsAbsoluteValue - theorem abs_re_div_norm_le_one (z : K) : |re z / ‖z‖| ≤ 1 := by rw [abs_div, abs_norm] exact div_le_one_of_le₀ (abs_re_le_norm _) (norm_nonneg _) diff --git a/Mathlib/Analysis/RCLike/BoundedContinuous.lean b/Mathlib/Analysis/RCLike/BoundedContinuous.lean index 5e6dfd73891ac4..b4d0a14c95292a 100644 --- a/Mathlib/Analysis/RCLike/BoundedContinuous.lean +++ b/Mathlib/Analysis/RCLike/BoundedContinuous.lean @@ -14,7 +14,7 @@ public import Mathlib.Topology.ContinuousMap.Bounded.Star public section -open Filter Real RCLike BoundedContinuousFunction +open Real RCLike BoundedContinuousFunction open scoped Topology diff --git a/Mathlib/Analysis/Real/Spectrum.lean b/Mathlib/Analysis/Real/Spectrum.lean index 54af5973bf7c0c..f2d13c6ca29b58 100644 --- a/Mathlib/Analysis/Real/Spectrum.lean +++ b/Mathlib/Analysis/Real/Spectrum.lean @@ -18,7 +18,7 @@ public section namespace SpectrumRestricts -open NNReal ENNReal +open NNReal variable {A : Type*} [Ring A] [Algebra ℝ A] @@ -57,7 +57,7 @@ end SpectrumRestricts namespace QuasispectrumRestricts -open NNReal ENNReal +open NNReal local notation "σₙ" => quasispectrum variable {A : Type*} [NonUnitalRing A] diff --git a/Mathlib/Analysis/Real/Sqrt.lean b/Mathlib/Analysis/Real/Sqrt.lean index e111a1394cab20..92936ac2ea8d16 100644 --- a/Mathlib/Analysis/Real/Sqrt.lean +++ b/Mathlib/Analysis/Real/Sqrt.lean @@ -319,7 +319,7 @@ end Real namespace Mathlib.Meta.Positivity -open Lean Meta Qq Function +open Lean Qq /-- Extension for the `positivity` tactic: a square root of a strictly positive nonnegative real is positive. -/ diff --git a/Mathlib/Analysis/SpecialFunctions/Arcosh.lean b/Mathlib/Analysis/SpecialFunctions/Arcosh.lean index af648895ac132b..b65e0259ef72c9 100644 --- a/Mathlib/Analysis/SpecialFunctions/Arcosh.lean +++ b/Mathlib/Analysis/SpecialFunctions/Arcosh.lean @@ -48,7 +48,7 @@ arcosh, arccosh, argcosh, acosh noncomputable section -open Function Filter Set +open Function Set open scoped Topology diff --git a/Mathlib/Analysis/SpecialFunctions/Artanh.lean b/Mathlib/Analysis/SpecialFunctions/Artanh.lean index 58d7945093c46f..c0dd7efab7be4e 100644 --- a/Mathlib/Analysis/SpecialFunctions/Artanh.lean +++ b/Mathlib/Analysis/SpecialFunctions/Artanh.lean @@ -39,7 +39,7 @@ artanh, arctanh, argtanh, atanh noncomputable section -open Function Filter Set +open Function Set open scoped Topology diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean b/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean index ac76b43547faea..e3c68f3219b26c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean @@ -20,7 +20,7 @@ public section assert_not_exists IsConformalMap Conformal -open Set Filter +open Set open scoped Real Topology @@ -57,7 +57,7 @@ end Complex section LogDeriv -open Complex Filter +open Complex open scoped Topology diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean index e66f719517bc84..179491edbeb37e 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/FourierTransform.lean @@ -32,7 +32,7 @@ We also give versions of these formulas in finite-dimensional inner product spac ## Fourier integral of Gaussian functions -/ -open Real Set MeasureTheory Filter Asymptotics intervalIntegral +open Real Set MeasureTheory Filter intervalIntegral open scoped Real Topology FourierTransform RealInnerProductSpace diff --git a/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean b/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean index 7002ba9f72b6ff..3350a82ed9c418 100644 --- a/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean +++ b/Mathlib/Analysis/SpecialFunctions/JapaneseBracket.lean @@ -34,7 +34,7 @@ noncomputable section open scoped NNReal Filter Topology ENNReal -open Asymptotics Filter Set Real MeasureTheory Module +open Filter Set Real MeasureTheory Module variable {E : Type*} [NormedAddCommGroup E] diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean b/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean index 60d8611ab55778..5a580ec5c9997a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean @@ -20,7 +20,7 @@ public section variable {ι : Type*} -open Filter Topology NNReal SummationFilter +open Filter Topology SummationFilter namespace Complex variable {f : ι → ℂ} {a : ℂ} diff --git a/Mathlib/Analysis/SpecialFunctions/MulExpNegMulSqIntegral.lean b/Mathlib/Analysis/SpecialFunctions/MulExpNegMulSqIntegral.lean index 6df787cee1caba..80d676451ef595 100644 --- a/Mathlib/Analysis/SpecialFunctions/MulExpNegMulSqIntegral.lean +++ b/Mathlib/Analysis/SpecialFunctions/MulExpNegMulSqIntegral.lean @@ -41,7 +41,7 @@ it is shown that a subalgebra of functions that separates points separates finit public section -open MeasureTheory Real NNReal ENNReal BoundedContinuousFunction Filter +open MeasureTheory Real ENNReal BoundedContinuousFunction Filter open scoped Topology diff --git a/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean b/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean index 69e305c14fcc94..c29d7f6762761c 100644 --- a/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean +++ b/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean @@ -135,7 +135,7 @@ end Field section RCLike -open Asymptotics Filter Real Set Nat +open Filter Real Nat open scoped Topology diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean index 40bde6d8539f88..9b6b2e81151850 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean @@ -21,7 +21,7 @@ public section noncomputable section -open Real Topology NNReal ENNReal Filter ComplexConjugate Finset Set +open Real Topology NNReal ENNReal Filter Set /-! ## Limits at `+∞` diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Continuity.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Continuity.lean index b7d14ef68dde16..4b48d8ca19e18a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Continuity.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Continuity.lean @@ -19,7 +19,7 @@ public section noncomputable section -open Real Topology NNReal ENNReal Filter ComplexConjugate Finset Set +open Real Topology NNReal ENNReal Filter Set section CpowLimits diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean index 33f77bc8acc192..81ac23e1c9087a 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean @@ -20,7 +20,7 @@ We construct the power functions `x ^ y`, where `x` and `y` are real numbers. noncomputable section -open Real ComplexConjugate Finset Set +open Real Finset Set /- ## Definitions @@ -370,7 +370,7 @@ end Complex /-! ### Positivity extension -/ namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: exponentiation by a real number is positive (namely 1) when the exponent is zero. The other cases are done in `evalRpow`. -/ diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean index dc89658bb21aeb..7da4320dc6a440 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Arctan.lean @@ -395,7 +395,7 @@ theorem coe_tanPartialHomeomorph_symm : ⇑tanPartialHomeomorph.symm = arctan := end Real namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for `Real.arctan`. -/ @[positivity Real.arctan _] diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean index 7568fe3549d181..6a57b78ae08e77 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/DerivHyp.lean @@ -789,7 +789,7 @@ end LogDeriv end namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq alias ⟨_, sinh_pos_of_pos⟩ := Real.sinh_pos_iff alias ⟨_, sinh_nonneg_of_nonneg⟩ := Real.sinh_nonneg_iff diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean index b338262c7656fa..6325e857e08b6b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Sinc.lean @@ -26,7 +26,6 @@ This file contains the definition of the sinc function and some of its propertie @[expose] public section -open Filter open scoped Topology namespace Real diff --git a/Mathlib/Analysis/SpecificLimits/Normed.lean b/Mathlib/Analysis/SpecificLimits/Normed.lean index a08f973615f5ef..21c9fcefb005e3 100644 --- a/Mathlib/Analysis/SpecificLimits/Normed.lean +++ b/Mathlib/Analysis/SpecificLimits/Normed.lean @@ -30,7 +30,7 @@ well as such computations in `ℝ` when the natural proof passes through a fact noncomputable section -open Set Function Filter Finset Metric Module Asymptotics Topology Nat NNReal ENNReal +open Set Function Filter Finset Metric Module Asymptotics Topology Nat open scoped Ring variable {α : Type*} @@ -286,8 +286,6 @@ section HasSummableGeometricSeries variable {R : Type*} [NormedRing R] -open NormedSpace - /-- Bound for the sum of a geometric series in a normed ring. This formula does not assume that the normed ring satisfies the axiom `‖1‖ = 1`. -/ theorem tsum_geometric_le_of_norm_lt_one (x : R) (h : ‖x‖ < 1) : diff --git a/Mathlib/Analysis/SpecificLimits/RCLike.lean b/Mathlib/Analysis/SpecificLimits/RCLike.lean index d281e7165eec8d..70e85897277e30 100644 --- a/Mathlib/Analysis/SpecificLimits/RCLike.lean +++ b/Mathlib/Analysis/SpecificLimits/RCLike.lean @@ -15,7 +15,7 @@ public import Mathlib.Analysis.RCLike.Basic public section -open Set Algebra Filter +open Filter open scoped Topology namespace RCLike diff --git a/Mathlib/Analysis/SumIntegralComparisons.lean b/Mathlib/Analysis/SumIntegralComparisons.lean index 16026e45f2abf3..ab4ac6fb93d3c3 100644 --- a/Mathlib/Analysis/SumIntegralComparisons.lean +++ b/Mathlib/Analysis/SumIntegralComparisons.lean @@ -49,7 +49,7 @@ analysis, comparison, asymptotics public section -open Set MeasureTheory MeasureSpace intervalIntegral +open Set MeasureTheory intervalIntegral variable {x₀ : ℝ} {a b : ℕ} {f g : ℝ → ℝ} diff --git a/Mathlib/CategoryTheory/Action/Continuous.lean b/Mathlib/CategoryTheory/Action/Continuous.lean index cf638edfcdc5a3..058c0862dc9011 100644 --- a/Mathlib/CategoryTheory/Action/Continuous.lean +++ b/Mathlib/CategoryTheory/Action/Continuous.lean @@ -29,7 +29,7 @@ of `HasForget₂` instances. @[expose] public section -open CategoryTheory Limits +open CategoryTheory variable (V : Type*) [Category* V] {FV : V → V → Type*} {CV : V → Type*} [∀ X Y, FunLike (FV X Y) (CV X) (CV Y)] [ConcreteCategory V FV] [HasForget₂ V TopCat] diff --git a/Mathlib/CategoryTheory/Adjunction/Additive.lean b/Mathlib/CategoryTheory/Adjunction/Additive.lean index 1352d0890f413a..6850dd2d47a7ef 100644 --- a/Mathlib/CategoryTheory/Adjunction/Additive.lean +++ b/Mathlib/CategoryTheory/Adjunction/Additive.lean @@ -28,7 +28,7 @@ namespace CategoryTheory namespace Adjunction -open CategoryTheory Category CategoryTheory.Functor +open CategoryTheory CategoryTheory.Functor variable {C : Type u₁} {D : Type u₂} [Category.{v₁} C] [Category.{v₂} D] [Preadditive C] [Preadditive D] {F : C ⥤ D} {G : D ⥤ C} (adj : F ⊣ G) diff --git a/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean b/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean index d74b5d71269c72..d732c2b68d0f11 100644 --- a/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean +++ b/Mathlib/CategoryTheory/Bicategory/Adjunction/Cat.lean @@ -22,8 +22,6 @@ universe v u namespace CategoryTheory -open Bicategory - section variable {C D E : Type u} [Category.{v} C] [Category.{v} D] [Category.{v} E] diff --git a/Mathlib/CategoryTheory/Bicategory/Adjunction/Mate.lean b/Mathlib/CategoryTheory/Bicategory/Adjunction/Mate.lean index 49d6e2eae87ab8..79257de7f27666 100644 --- a/Mathlib/CategoryTheory/Bicategory/Adjunction/Mate.lean +++ b/Mathlib/CategoryTheory/Bicategory/Adjunction/Mate.lean @@ -52,8 +52,6 @@ namespace CategoryTheory namespace Bicategory -open Bicategory - variable {B : Type u} [Bicategory.{w, v} B] namespace Adjunction diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean index c409350fa4e9c0..da31061fbffae4 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Cat/ObjectProperty.lean @@ -31,8 +31,6 @@ universe w v v' u u' namespace CategoryTheory -open Bicategory - namespace Pseudofunctor variable {B : Type u} [Bicategory.{w, v} B] (F : Pseudofunctor B Cat.{v', u'}) diff --git a/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean b/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean index 653a26fe111dae..ac8507522afdad 100644 --- a/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean +++ b/Mathlib/CategoryTheory/Bicategory/Functor/Prelax.lean @@ -43,8 +43,6 @@ corresponding hom types. namespace CategoryTheory -open Category Bicategory - universe w₁ w₂ w₃ v₁ v₂ v₃ u₁ u₂ u₃ section diff --git a/Mathlib/CategoryTheory/Bicategory/LocallyGroupoid.lean b/Mathlib/CategoryTheory/Bicategory/LocallyGroupoid.lean index 56266791ecaf3a..9f48c50aeda4e3 100644 --- a/Mathlib/CategoryTheory/Bicategory/LocallyGroupoid.lean +++ b/Mathlib/CategoryTheory/Bicategory/LocallyGroupoid.lean @@ -31,8 +31,6 @@ through the inclusion from `Pith B` to `B` (see namespace CategoryTheory.Bicategory -open Bicategory - universe w₁ w₂ v₁ v₂ u₁ u₂ /-- A bicategory is locally groupoidal if the categories of 1-morphisms are groupoids. -/ diff --git a/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean b/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean index 3bbac00b2f138c..f803064bf5ce06 100644 --- a/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean +++ b/Mathlib/CategoryTheory/Bicategory/Monad/Basic.lean @@ -144,8 +144,6 @@ instance (m : ComonadBicat B) : Comonad m.hom := def mkOfComonad {a : B} (t : a ⟶ a) [Comonad t] : ComonadBicat B := Comonad.toOplax t -open Comonad - section variable {a : B} (t : a ⟶ a) [Comonad t] diff --git a/Mathlib/CategoryTheory/Center/Basic.lean b/Mathlib/CategoryTheory/Center/Basic.lean index bd17367b2d9a3b..91bbbdbaf3e189 100644 --- a/Mathlib/CategoryTheory/Center/Basic.lean +++ b/Mathlib/CategoryTheory/Center/Basic.lean @@ -24,8 +24,6 @@ universe v u namespace CategoryTheory -open Category - variable (C : Type u) [Category.{v} C] /-- The center of a category `C` is the type `End (𝟭 C)` of the endomorphisms diff --git a/Mathlib/CategoryTheory/Comma/Final.lean b/Mathlib/CategoryTheory/Comma/Final.lean index 90335c5ada1754..c774a1370d0eef 100644 --- a/Mathlib/CategoryTheory/Comma/Final.lean +++ b/Mathlib/CategoryTheory/Comma/Final.lean @@ -35,7 +35,7 @@ namespace CategoryTheory namespace Comma -open Limits CategoryTheory.Functor CostructuredArrow +open CategoryTheory.Functor variable {A : Type u₁} [Category.{v₁} A] variable {B : Type u₂} [Category.{v₂} B] diff --git a/Mathlib/CategoryTheory/CopyDiscardCategory/Cartesian.lean b/Mathlib/CategoryTheory/CopyDiscardCategory/Cartesian.lean index e39a2c2deefcba..1e96def091189a 100644 --- a/Mathlib/CategoryTheory/CopyDiscardCategory/Cartesian.lean +++ b/Mathlib/CategoryTheory/CopyDiscardCategory/Cartesian.lean @@ -33,8 +33,6 @@ universe v u namespace CategoryTheory -open MonoidalCategory CartesianMonoidalCategory ComonObj - variable {C : Type u} [Category.{v} C] [CartesianMonoidalCategory.{v} C] namespace CartesianCopyDiscard diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean b/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean index 9cb3742fecb660..bb6d2c5230e108 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Enough.lean @@ -18,8 +18,6 @@ in `D`, there exists an effective epi to it from an object in the image of `F`. namespace CategoryTheory -open Limits - variable {C D : Type*} [Category* C] [Category* D] (F : C ⥤ D) namespace Functor diff --git a/Mathlib/CategoryTheory/Endomorphism.lean b/Mathlib/CategoryTheory/Endomorphism.lean index 55ce568f6f2a85..22bec9ade70f2e 100644 --- a/Mathlib/CategoryTheory/Endomorphism.lean +++ b/Mathlib/CategoryTheory/Endomorphism.lean @@ -79,8 +79,6 @@ section MulAction variable {C : Type u} [Category.{v} C] -open Opposite - instance mulActionRight {X Y : C} : MulAction (End Y) (X ⟶ Y) where smul r f := f ≫ r one_smul := Category.comp_id diff --git a/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean b/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean index 1d8c3502773af1..b2e31150406801 100644 --- a/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean +++ b/Mathlib/CategoryTheory/Enriched/EnrichedCat.lean @@ -29,8 +29,6 @@ universe w v u u₁ u₂ u₃ namespace CategoryTheory -open MonoidalCategory - variable (V : Type v) [Category.{w} V] [MonoidalCategory V] /-- Category of `V`-enriched categories for a monoidal category `V`. -/ @@ -48,8 +46,6 @@ instance str (C : EnrichedCat.{w, v, u} V) : EnrichedCategory.{w, v, u} V C := def of (C : Type u) [EnrichedCategory.{w} V C] : EnrichedCat.{w, v, u} V := Bundled.of C -open EnrichedCategory ForgetEnrichment - variable {V} {C : Type u} [EnrichedCategory V C] {D : Type u₁} [EnrichedCategory V D] {E : Type u₂} [EnrichedCategory V E] {E' : Type u₃} [EnrichedCategory V E'] diff --git a/Mathlib/CategoryTheory/Equivalence/Symmetry.lean b/Mathlib/CategoryTheory/Equivalence/Symmetry.lean index dfa49661d16e16..0251f630ba3e9a 100644 --- a/Mathlib/CategoryTheory/Equivalence/Symmetry.lean +++ b/Mathlib/CategoryTheory/Equivalence/Symmetry.lean @@ -31,7 +31,7 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory -open CategoryTheory.Functor NatIso Category +open CategoryTheory.Functor namespace Equivalence diff --git a/Mathlib/CategoryTheory/Filtered/Flat.lean b/Mathlib/CategoryTheory/Filtered/Flat.lean index 11b6d1fea5c2c1..9bfaaf4f402153 100644 --- a/Mathlib/CategoryTheory/Filtered/Flat.lean +++ b/Mathlib/CategoryTheory/Filtered/Flat.lean @@ -26,8 +26,6 @@ universe v₁ v₂ u₁ u₂ namespace CategoryTheory -open Limits - variable {C : Type u₁} [Category.{v₁} C] variable {D : Type u₂} [Category.{v₂} D] variable (F : C ⥤ D) diff --git a/Mathlib/CategoryTheory/Generator/Preadditive.lean b/Mathlib/CategoryTheory/Generator/Preadditive.lean index 71354fa91768f9..092d930df6785b 100644 --- a/Mathlib/CategoryTheory/Generator/Preadditive.lean +++ b/Mathlib/CategoryTheory/Generator/Preadditive.lean @@ -21,7 +21,7 @@ public section universe v u -open CategoryTheory Opposite ObjectProperty +open CategoryTheory Opposite namespace CategoryTheory diff --git a/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean b/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean index 4ae05225baa88e..9762296b862661 100644 --- a/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean +++ b/Mathlib/CategoryTheory/GuitartExact/HorizontalComposition.lean @@ -19,8 +19,6 @@ is Guitart exact. namespace CategoryTheory -open Category - variable {C₁ C₂ C₃ D₁ D₂ D₃ : Type*} [Category* C₁] [Category* C₂] [Category* C₃] [Category* D₁] [Category* D₂] [Category* D₃] diff --git a/Mathlib/CategoryTheory/GuitartExact/Opposite.lean b/Mathlib/CategoryTheory/GuitartExact/Opposite.lean index e5267638261d13..74b45790b6b58d 100644 --- a/Mathlib/CategoryTheory/GuitartExact/Opposite.lean +++ b/Mathlib/CategoryTheory/GuitartExact/Opposite.lean @@ -21,8 +21,6 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory -open Category - variable {C₁ : Type u₁} {C₂ : Type u₂} {C₃ : Type u₃} {C₄ : Type u₄} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} C₃] [Category.{v₄} C₄] {T : C₁ ⥤ C₂} {L : C₁ ⥤ C₃} {R : C₂ ⥤ C₄} {B : C₃ ⥤ C₄} diff --git a/Mathlib/CategoryTheory/IsoCat.lean b/Mathlib/CategoryTheory/IsoCat.lean index c8519666e2b200..55f5e431c27d96 100644 --- a/Mathlib/CategoryTheory/IsoCat.lean +++ b/Mathlib/CategoryTheory/IsoCat.lean @@ -31,7 +31,7 @@ to be preferred. namespace CategoryTheory -open CategoryTheory.Functor NatIso Category +open CategoryTheory.Functor variable {C : Type*} {D : Type*} {E : Type*} [Category* C] [Category* D] [Category* E] variable (F : C ⥤ D) (G : D ⥤ E) diff --git a/Mathlib/CategoryTheory/Join/Pseudofunctor.lean b/Mathlib/CategoryTheory/Join/Pseudofunctor.lean index 0750fec1200523..5fa73b455a9874 100644 --- a/Mathlib/CategoryTheory/Join/Pseudofunctor.lean +++ b/Mathlib/CategoryTheory/Join/Pseudofunctor.lean @@ -23,7 +23,7 @@ universe v₁ v₂ u₁ u₂ namespace CategoryTheory.Join -open Bicategory CategoryTheory.Functor +open CategoryTheory.Functor -- The proof gets too slow if we put it in a single `pseudofunctor` constructor, -- so we break down the component proofs for the pseudofunctors over several lemmas. diff --git a/Mathlib/CategoryTheory/LiftingProperties/ParametrizedAdjunction.lean b/Mathlib/CategoryTheory/LiftingProperties/ParametrizedAdjunction.lean index 931ead0deb1de4..6d211573cca0c6 100644 --- a/Mathlib/CategoryTheory/LiftingProperties/ParametrizedAdjunction.lean +++ b/Mathlib/CategoryTheory/LiftingProperties/ParametrizedAdjunction.lean @@ -26,7 +26,7 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open Opposite Limits +open Opposite variable {C₁ : Type u₁} {C₂ : Type u₂} {C₃ : Type u₃} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} C₃] diff --git a/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean b/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean index 215af2517495b8..e1e582623f828f 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/Over/Products.lean @@ -179,8 +179,6 @@ namespace Over section BinaryProduct variable {X : C} {Y Z : Over X} -open Limits - set_option backward.isDefEq.respectTransparency.types false in lemma isPullback_of_binaryFan_isLimit (c : BinaryFan Y Z) (hc : IsLimit c) : IsPullback c.fst.left c.snd.left Y.hom Z.hom := diff --git a/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean b/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean index da98aa840ed219..714b0869e5d26b 100644 --- a/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean +++ b/Mathlib/CategoryTheory/Limits/FormalCoproducts/ExtraDegeneracy.lean @@ -26,8 +26,6 @@ morphism `T ⟶ U.obj i₀` for some `i₀`. universe w t v u -open Simplicial - namespace CategoryTheory.Limits.FormalCoproduct variable {C : Type u} [Category.{v} C] [HasFiniteProducts C] diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean b/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean index 04f7847409478a..fd3fad926cd44e 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Creates/Opposites.lean @@ -22,7 +22,7 @@ universe w w' v₁ v₂ u₁ u₂ noncomputable section -open CategoryTheory Limits +open CategoryTheory namespace CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean index 4f994d6b66d739..2ebd276221d523 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/BinaryBiproducts.lean @@ -35,7 +35,7 @@ noncomputable section universe w w' v u -open CategoryTheory Functor Opposite +open CategoryTheory Opposite namespace CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 69e945fbc9a2ec..3e93dad693f295 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -45,7 +45,7 @@ noncomputable section universe w w' v u -open CategoryTheory Functor +open CategoryTheory namespace CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean index e2e5e749c297f5..a3dee62a1b92f6 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean @@ -484,8 +484,6 @@ end section PullbackSymmetry -open WalkingCospan - variable (f : X ⟶ Z) (g : Y ⟶ Z) /-- Making this a global instance would make the typeclass search go in an infinite loop. -/ @@ -521,8 +519,6 @@ end PullbackSymmetry section PushoutSymmetry -open WalkingCospan - variable (f : X ⟶ Y) (g : X ⟶ Z) /-- Making this a global instance would make the typeclass search go in an infinite loop. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean index 77f75ccb000cbe..3b51ef0a016cf8 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean @@ -995,8 +995,6 @@ end Thin section IsPullbackOverPullback -open Limits - variable {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasPullbacksAlong g] namespace IsPullback diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean index a00b81356f4a30..92f46a12e2dc6b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean @@ -36,7 +36,7 @@ universe w v₁ v₂ v u u₂ namespace CategoryTheory.Limits -open WalkingSpan.Hom WalkingCospan.Hom WidePullbackShape.Hom WidePushoutShape.Hom PullbackCone +open WalkingSpan.Hom WalkingCospan.Hom WidePullbackShape.Hom WidePushoutShape.Hom variable {C : Type u} [Category.{v} C] {W X Y Z : C} @@ -187,8 +187,6 @@ end section -open WalkingCospan - variable (f : X ⟶ Y) [Mono f] instance has_kernel_pair_of_mono : HasPullback f f := @@ -375,8 +373,6 @@ end section -open WalkingSpan - variable (f : X ⟶ Y) [Epi f] instance has_cokernel_pair_of_epi : HasPushout f f := diff --git a/Mathlib/CategoryTheory/Limits/Types/End.lean b/Mathlib/CategoryTheory/Limits/Types/End.lean index 3b92bc7bc368dc..48cbbc3c4c2832 100644 --- a/Mathlib/CategoryTheory/Limits/Types/End.lean +++ b/Mathlib/CategoryTheory/Limits/Types/End.lean @@ -20,7 +20,7 @@ universe w v u namespace CategoryTheory -open Opposite TypeCat ConcreteCategory +open Opposite TypeCat namespace Limits.Types diff --git a/Mathlib/CategoryTheory/Limits/Types/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Types/Multiequalizer.lean index 19a037087dab05..cfdc7a50203807 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Multiequalizer.lean @@ -22,7 +22,7 @@ that `c` is a limit iff the canonical map universe v u -open CategoryTheory Limits +open CategoryTheory namespace CategoryTheory.Limits diff --git a/Mathlib/CategoryTheory/Limits/Types/Products.lean b/Mathlib/CategoryTheory/Limits/Types/Products.lean index 426d1d10ba01a9..092c873a7ccaee 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Products.lean @@ -22,7 +22,7 @@ and the terminal object. universe v u -open CategoryTheory Limits +open CategoryTheory namespace CategoryTheory.Limits.Types diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean index ce51e6a949d41c..29e36c337b16b5 100644 --- a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakEqualizers.lean @@ -21,7 +21,7 @@ universe u v w noncomputable section -open CategoryTheory Category Limits +open CategoryTheory variable {C : Type*} [Category* C] diff --git a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean index 259502b1308092..688a0125fe99de 100644 --- a/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/WeakLimits/WeakPullbacks.lean @@ -23,7 +23,7 @@ universe u v w noncomputable section -open CategoryTheory Category Limits +open CategoryTheory variable {C : Type*} [Category* C] diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean index 675aec54995d6a..ec5cc79beab50b 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/Derives.lean @@ -33,8 +33,6 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory -open Limits Category - variable {C₁ : Type u₁} {C₂ : Type u₂} {H : Type u₃} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} H] {D₂ : Type u₄} [Category.{v₄} D₂] diff --git a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean index c614f856bf80e0..3b04dc5bde1a76 100644 --- a/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean +++ b/Mathlib/CategoryTheory/Localization/DerivabilityStructure/PointwiseRightDerived.lean @@ -38,7 +38,7 @@ universe v₁ v₂ v₃ v₄ v₅ u₁ u₂ u₃ u₄ u₅ namespace CategoryTheory -open Limits Category CategoryTheory.Functor +open CategoryTheory.Functor variable {C₁ : Type u₁} {C₂ : Type u₂} {H : Type u₃} [Category.{v₁} C₁] [Category.{v₂} C₂] [Category.{v₃} H] diff --git a/Mathlib/CategoryTheory/Localization/Resolution.lean b/Mathlib/CategoryTheory/Localization/Resolution.lean index a67f603a91dd16..6c5b8ed8af56c2 100644 --- a/Mathlib/CategoryTheory/Localization/Resolution.lean +++ b/Mathlib/CategoryTheory/Localization/Resolution.lean @@ -42,8 +42,6 @@ universe v₁ v₂ v₂' u₁ u₂ u₂' namespace CategoryTheory -open Category Localization - variable {C₁ C₂ D₁ D₂ H : Type*} [Category* C₁] [Category* C₂] [Category* D₁] [Category* D₂] [Category* H] {W₁ : MorphismProperty C₁} {W₂ : MorphismProperty C₂} diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Ring.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Ring.lean index 9eff091690cd96..88da075d4a1c75 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Ring.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Ring.lean @@ -15,7 +15,7 @@ public import Mathlib.CategoryTheory.Monoidal.Ring @[expose] public section -open CategoryTheory MonObj +open CategoryTheory universe v u diff --git a/Mathlib/CategoryTheory/Monoidal/CoherenceLemmas.lean b/Mathlib/CategoryTheory/Monoidal/CoherenceLemmas.lean index aefd9de825242f..da919bf113972f 100644 --- a/Mathlib/CategoryTheory/Monoidal/CoherenceLemmas.lean +++ b/Mathlib/CategoryTheory/Monoidal/CoherenceLemmas.lean @@ -20,7 +20,7 @@ or if they can be replaced by use of the `coherence` tactic. public section -open CategoryTheory Category Iso +open CategoryTheory namespace CategoryTheory.MonoidalCategory diff --git a/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean b/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean index 6393251ae27328..4f4f446197a455 100644 --- a/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean +++ b/Mathlib/CategoryTheory/Monoidal/DayConvolution/DayFunctor.lean @@ -167,7 +167,6 @@ lemma η_comp_tensorDesc_app {F G H : C ⊛⥤ V} (η F G).app (x, y) ≫ (tensorDesc α).natTrans.app (x ⊗ y) = α.app (x, y) := Functor.descOfIsLeftKanExtension_fac_app _ _ _ _ _ -open LawfulDayConvolutionMonoidalCategoryStruct /-- An abstract isomorphism between `(F ⊗ G).functor` and the generic pointwise left Kan extension of `F.functor ⊠ G.functor` along the -/ def isoPointwiseLeftKanExtension (F G : C ⊛⥤ V) : diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index cd9918c98651db..f91fc974b46518 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -127,8 +127,6 @@ section attribute [local instance] monoidalOfHasFiniteCoproducts -open MonoidalCategory - set_option backward.isDefEq.respectTransparency false in /-- The monoidal structure coming from finite coproducts is symmetric. -/ diff --git a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean index 6161d19aa842b9..8eacc375fc8353 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Comma.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Comma.lean @@ -42,8 +42,6 @@ set_option backward.defeqAttrib.useBackward true namespace CategoryTheory.MorphismProperty -open Limits - section Comma variable {A : Type*} [Category* A] {B : Type*} [Category* B] {T : Type*} [Category* T] diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index b4547cad3b4d9b..739b42424b3571 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -40,8 +40,6 @@ universe v₁ v₂ v₃ v₄ u₁ u₂ u₃ u₄ namespace CategoryTheory -open NatTrans - variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] {E : Type u₃} [Category.{v₃} E] {E' : Type u₄} [Category.{v₄} E'] diff --git a/Mathlib/CategoryTheory/NatTrans.lean b/Mathlib/CategoryTheory/NatTrans.lean index b919dae13f2647..4fbc4a18a55d7c 100644 --- a/Mathlib/CategoryTheory/NatTrans.lean +++ b/Mathlib/CategoryTheory/NatTrans.lean @@ -88,8 +88,6 @@ theorem id_app' (F : C ⥤ D) (X : C) : (NatTrans.id F).app X = 𝟙 (F.obj X) : instance (F : C ⥤ D) : Inhabited (NatTrans F F) := ⟨NatTrans.id F⟩ -open Category - open CategoryTheory.Functor section diff --git a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean index b08036902eb037..3c0390fc59f147 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean @@ -21,7 +21,7 @@ implies `P (X⟦a⟧)` for all `a : A`. @[expose] public section -open CategoryTheory Category +open CategoryTheory namespace CategoryTheory diff --git a/Mathlib/CategoryTheory/Preadditive/Comma.lean b/Mathlib/CategoryTheory/Preadditive/Comma.lean index dc477de5a32189..6747676a281273 100644 --- a/Mathlib/CategoryTheory/Preadditive/Comma.lean +++ b/Mathlib/CategoryTheory/Preadditive/Comma.lean @@ -25,8 +25,6 @@ comma, arrow, preadditive namespace CategoryTheory -open Category - universe v₁ v₂ v₃ u₁ u₂ u₃ variable {A : Type u₁} [Category.{v₁} A] [Preadditive A] diff --git a/Mathlib/CategoryTheory/Preadditive/Mat.lean b/Mathlib/CategoryTheory/Preadditive/Mat.lean index f6a0b778533b6a..9084861f5a227e 100644 --- a/Mathlib/CategoryTheory/Preadditive/Mat.lean +++ b/Mathlib/CategoryTheory/Preadditive/Mat.lean @@ -572,8 +572,6 @@ end variable (R : Type) [Ring R] -open Opposite - set_option backward.isDefEq.respectTransparency.types false in /-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Presentable/CardinalFilteredPresentation.lean b/Mathlib/CategoryTheory/Presentable/CardinalFilteredPresentation.lean index ea4d3d2bcf4dd8..320a1a5c25b0ac 100644 --- a/Mathlib/CategoryTheory/Presentable/CardinalFilteredPresentation.lean +++ b/Mathlib/CategoryTheory/Presentable/CardinalFilteredPresentation.lean @@ -52,8 +52,6 @@ lemma isCardinalPresentable {X : C} {J : Type w} [SmallCategory J] end Limits.ColimitPresentation -open Limits - namespace ObjectProperty variable {P : ObjectProperty C} diff --git a/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean b/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean index 2317272d033edb..dbe74d0b4d2177 100644 --- a/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean +++ b/Mathlib/CategoryTheory/Shift/SingleFunctorsLift.lean @@ -24,7 +24,7 @@ we lift `F` in `SingleFunctor C D A`. namespace CategoryTheory -open Category CategoryTheory.Functor +open CategoryTheory.Functor variable {C D E : Type*} [Category C] [Category D] [Category E] {A : Type*} [AddMonoid A] [HasShift D A] [HasShift E A] diff --git a/Mathlib/CategoryTheory/Sites/Coherent/RegularTopology.lean b/Mathlib/CategoryTheory/Sites/Coherent/RegularTopology.lean index d971a5b8174760..480f7b05cd2d64 100644 --- a/Mathlib/CategoryTheory/Sites/Coherent/RegularTopology.lean +++ b/Mathlib/CategoryTheory/Sites/Coherent/RegularTopology.lean @@ -22,8 +22,6 @@ public section namespace CategoryTheory.regularTopology -open Limits - variable {C : Type*} [Category* C] [Preregular C] {X : C} /-- diff --git a/Mathlib/CategoryTheory/Sites/Grothendieck.lean b/Mathlib/CategoryTheory/Sites/Grothendieck.lean index f9fd39dca663b8..14626e26d62deb 100644 --- a/Mathlib/CategoryTheory/Sites/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/Grothendieck.lean @@ -58,8 +58,6 @@ universe v₁ u₁ v u namespace CategoryTheory -open Category - variable (C : Type u) [Category.{v} C] /-- The definition of a Grothendieck topology: a set of sieves `J X` on each object `X` satisfying diff --git a/Mathlib/CategoryTheory/Sites/LocalProperties.lean b/Mathlib/CategoryTheory/Sites/LocalProperties.lean index 9767ccf899b84f..c87840bb728847 100644 --- a/Mathlib/CategoryTheory/Sites/LocalProperties.lean +++ b/Mathlib/CategoryTheory/Sites/LocalProperties.lean @@ -22,7 +22,7 @@ public section namespace CategoryTheory -open Limits Opposite +open Opposite variable {C : Type*} [Category* C] {K : GrothendieckTopology C} {A : Type*} [Category* A] diff --git a/Mathlib/CategoryTheory/Sites/Localization.lean b/Mathlib/CategoryTheory/Sites/Localization.lean index 0b50036ff53fb1..7b6655f5326606 100644 --- a/Mathlib/CategoryTheory/Sites/Localization.lean +++ b/Mathlib/CategoryTheory/Sites/Localization.lean @@ -23,8 +23,6 @@ public section namespace CategoryTheory -open Localization - variable {C : Type*} [Category* C] (J : GrothendieckTopology C) {A : Type*} [Category* A] namespace GrothendieckTopology diff --git a/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean b/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean index a0351d6a8f8312..c0e847007a6890 100644 --- a/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean +++ b/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean @@ -72,7 +72,7 @@ lemma Functor.imageSieve_eq_imageSieve {D : Type uD} [Category.{vC} D] (G : C (f : G.obj U ⟶ G.obj V) : G.imageSieve f = Presheaf.imageSieve (yonedaMap G V) f := rfl -open Presieve Opposite +open Opposite namespace Functor diff --git a/Mathlib/CategoryTheory/Sites/LocallyInjective.lean b/Mathlib/CategoryTheory/Sites/LocallyInjective.lean index d353825716fc44..95ab43e2f06696 100644 --- a/Mathlib/CategoryTheory/Sites/LocallyInjective.lean +++ b/Mathlib/CategoryTheory/Sites/LocallyInjective.lean @@ -30,7 +30,7 @@ universe w v' v u' u namespace CategoryTheory -open Opposite Limits +open Opposite variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] {FD : D → D → Type*} {CD : D → Type w} diff --git a/Mathlib/CategoryTheory/Skeletal.lean b/Mathlib/CategoryTheory/Skeletal.lean index 24898f3d4a4e80..313f8196f3a217 100644 --- a/Mathlib/CategoryTheory/Skeletal.lean +++ b/Mathlib/CategoryTheory/Skeletal.lean @@ -32,8 +32,6 @@ universe v₁ v₂ v₃ u₁ u₂ u₃ namespace CategoryTheory -open Category - variable (C : Type u₁) [Category.{v₁} C] variable (D : Type u₂) [Category.{v₂} D] variable {E : Type u₃} [Category.{v₃} E] @@ -431,8 +429,6 @@ def lowerAdjunction (R : D ⥤ C) (L : C ⥤ D) (h : L ⊣ R) : end ThinSkeleton -open ThinSkeleton - section variable {C} {α : Type*} [PartialOrder α] diff --git a/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean b/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean index eca77b33d8bab6..98397a66ab99b0 100644 --- a/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean +++ b/Mathlib/CategoryTheory/Subfunctor/SubmonoidFunctor.lean @@ -28,7 +28,7 @@ We provide the complete lattice structure and the basic functoriality properties universe w v u -open Opposite CategoryTheory ConcreteCategory +open CategoryTheory namespace CategoryTheory diff --git a/Mathlib/CategoryTheory/Subobject/Limits.lean b/Mathlib/CategoryTheory/Subobject/Limits.lean index c06870c1d8a379..8940ce5feba66b 100644 --- a/Mathlib/CategoryTheory/Subobject/Limits.lean +++ b/Mathlib/CategoryTheory/Subobject/Limits.lean @@ -367,8 +367,6 @@ theorem imageSubobject_comp_le {X' : C} (h : X' ⟶ X) (f : X ⟶ Y) [HasImage f section -open ZeroObject - variable [HasZeroMorphisms C] [HasZeroObject C] @[simp] diff --git a/Mathlib/CategoryTheory/Yoneda.lean b/Mathlib/CategoryTheory/Yoneda.lean index 0f43ae85c1bfc3..66fee0e9e56b6a 100644 --- a/Mathlib/CategoryTheory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Yoneda.lean @@ -711,8 +711,6 @@ instance prodCategoryInstance1 : Category ((Cᵒᵖ ⥤ Type v₁) × Cᵒᵖ) : instance prodCategoryInstance2 : Category (Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)) := CategoryTheory.prod'.{v₁, max u₁ v₁} Cᵒᵖ (Cᵒᵖ ⥤ Type v₁) -open Yoneda - section YonedaLemma variable {C} diff --git a/Mathlib/Combinatorics/Additive/SmallTripling.lean b/Mathlib/Combinatorics/Additive/SmallTripling.lean index 3808b94d12ed0b..addacb4dd46e37 100644 --- a/Mathlib/Combinatorics/Additive/SmallTripling.lean +++ b/Mathlib/Combinatorics/Additive/SmallTripling.lean @@ -27,7 +27,7 @@ implies small powers. See `Mathlib/Combinatorics/Additive/PluenneckeRuzsa.lean`. public section -open Fin MulOpposite +open Fin open List hiding tail open scoped Pointwise diff --git a/Mathlib/Combinatorics/Digraph/Basic.lean b/Mathlib/Combinatorics/Digraph/Basic.lean index 312878b32c8f58..f7d7ca485ebaa1 100644 --- a/Mathlib/Combinatorics/Digraph/Basic.lean +++ b/Mathlib/Combinatorics/Digraph/Basic.lean @@ -36,7 +36,7 @@ of digraphs on `V`. @[expose] public section -open Finset Function +open Function /-- A digraph is a relation `Adj` on a vertex type `V`. diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index c5938308747cc5..7275647bb19c86 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -555,7 +555,7 @@ end DyckWord namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: `p.firstReturn` is positive if `p` is nonzero. -/ @[positivity DyckWord.firstReturn _] diff --git a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean index 10052b591711b1..9b5c3f4a9bad22 100644 --- a/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean +++ b/Mathlib/Combinatorics/Extremal/RuzsaSzemeredi.lean @@ -30,7 +30,7 @@ original set. @[expose] public section -open Finset Nat Real SimpleGraph Sum3 SimpleGraph.TripartiteFromTriangles +open Finset Nat Real SimpleGraph SimpleGraph.TripartiteFromTriangles open Fintype (card) open scoped Pointwise diff --git a/Mathlib/Combinatorics/Graph/Delete.lean b/Mathlib/Combinatorics/Graph/Delete.lean index cec0ab58d13829..f5f48428026a4a 100644 --- a/Mathlib/Combinatorics/Graph/Delete.lean +++ b/Mathlib/Combinatorics/Graph/Delete.lean @@ -29,7 +29,7 @@ public section variable {α β : Type*} {x y : α} {e : β} {G H : Graph α β} {F F₀ : Set β} {X : Set α} -open Set Function +open Set namespace Graph diff --git a/Mathlib/Combinatorics/Graph/Lattice.lean b/Mathlib/Combinatorics/Graph/Lattice.lean index c4d5f0c3583888..a97878108d96ca 100644 --- a/Mathlib/Combinatorics/Graph/Lattice.lean +++ b/Mathlib/Combinatorics/Graph/Lattice.lean @@ -31,7 +31,7 @@ This has the effect of, when taking the intersection of non-compatible graphs, public section -open Function Set +open Set variable {α β : Type*} {x y : α} {e : β} {G H : Graph α β} diff --git a/Mathlib/Combinatorics/Quiver/Arborescence.lean b/Mathlib/Combinatorics/Quiver/Arborescence.lean index 063ffb6f43e888..6c3618c088d2dc 100644 --- a/Mathlib/Combinatorics/Quiver/Arborescence.lean +++ b/Mathlib/Combinatorics/Quiver/Arborescence.lean @@ -30,9 +30,6 @@ that for every `b : V` there is a unique path from `root` to `b`. @[expose] public section - -open Opposite - universe v u namespace Quiver diff --git a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean index d3a02d29b42b8f..514ec13e1d01b4 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Extremal/ErdosStoneSimonovits.lean @@ -21,7 +21,7 @@ This file proves the **Erdős-Stone-Simonovits theorem** for simple graphs. minimal degree version of the **Erdős-Stone theorem** for simple graphs. -/ -open Filter Finset Fintype Real Topology +open Filter Finset Fintype Real namespace SimpleGraph diff --git a/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean b/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean index a700cb47768a8e..b771c677eea67a 100644 --- a/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean +++ b/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean @@ -29,7 +29,7 @@ arise in practice. @[expose] public section -open Finset Real Filter Asymptotics +open Real Filter Asymptotics open scoped Topology namespace AkraBazziRecurrence diff --git a/Mathlib/Computability/Halting.lean b/Mathlib/Computability/Halting.lean index 971cac8777655f..9a36ea2bcb21d7 100644 --- a/Mathlib/Computability/Halting.lean +++ b/Mathlib/Computability/Halting.lean @@ -20,7 +20,7 @@ A universal partial recursive function, Rice's theorem, and the halting problem. public section -open Encodable Denumerable +open Denumerable open Computable Part open Nat.Partrec (Code) open Nat.Partrec.Code diff --git a/Mathlib/Computability/Primrec/Basic.lean b/Mathlib/Computability/Primrec/Basic.lean index b96415cc75d5e4..f4883ec8028c02 100644 --- a/Mathlib/Computability/Primrec/Basic.lean +++ b/Mathlib/Computability/Primrec/Basic.lean @@ -789,7 +789,7 @@ end Primrec namespace PrimrecRel -open Primrec List PrimrecPred +open PrimrecPred variable {α β : Type*} {R : α → β → Prop} {L : List α} {b : β} diff --git a/Mathlib/Computability/TuringDegree.lean b/Mathlib/Computability/TuringDegree.lean index f8cffe130d0638..24ff9eb0ad7a9b 100644 --- a/Mathlib/Computability/TuringDegree.lean +++ b/Mathlib/Computability/TuringDegree.lean @@ -39,8 +39,6 @@ Computability, Oracle, Turing Degrees, Reducibility, Equivalence Relation public section -open Primrec - variable {f g h : ℕ →. ℕ} /-- diff --git a/Mathlib/Condensed/Basic.lean b/Mathlib/Condensed/Basic.lean index 926e02ac2875d9..dcfc0f3b777365 100644 --- a/Mathlib/Condensed/Basic.lean +++ b/Mathlib/Condensed/Basic.lean @@ -32,7 +32,7 @@ as we do not impose cardinality bounds, and manage universes carefully instead. public section -open CategoryTheory Limits +open CategoryTheory open CategoryTheory diff --git a/Mathlib/Condensed/Discrete/Basic.lean b/Mathlib/Condensed/Discrete/Basic.lean index 064c024b17326b..204f08689b61d4 100644 --- a/Mathlib/Condensed/Discrete/Basic.lean +++ b/Mathlib/Condensed/Discrete/Basic.lean @@ -32,7 +32,7 @@ set or module that characterize it as discrete. universe u v w -open CategoryTheory Limits Opposite GrothendieckTopology +open CategoryTheory Opposite namespace Condensed diff --git a/Mathlib/Condensed/Light/AB.lean b/Mathlib/Condensed/Light/AB.lean index c6d09a208818e7..4f55edfcfed0d1 100644 --- a/Mathlib/Condensed/Light/AB.lean +++ b/Mathlib/Condensed/Light/AB.lean @@ -20,7 +20,7 @@ public section universe u -open CategoryTheory Limits +open CategoryTheory namespace LightCondensed diff --git a/Mathlib/Condensed/Light/Basic.lean b/Mathlib/Condensed/Light/Basic.lean index 7434e0d09e87b4..f3ae4acfde2763 100644 --- a/Mathlib/Condensed/Light/Basic.lean +++ b/Mathlib/Condensed/Light/Basic.lean @@ -20,7 +20,7 @@ public section universe u v w -open CategoryTheory Limits +open CategoryTheory /-- `LightCondensed.{u} C` is the category of light condensed objects in a category `C`, which are diff --git a/Mathlib/Condensed/Solid.lean b/Mathlib/Condensed/Solid.lean index f5214433f91ee8..8929490f0d26ba 100644 --- a/Mathlib/Condensed/Solid.lean +++ b/Mathlib/Condensed/Solid.lean @@ -31,7 +31,7 @@ universe u variable (R : Type (u + 1)) [Ring R] -open CategoryTheory Limits Profinite Condensed +open CategoryTheory Profinite Condensed noncomputable section diff --git a/Mathlib/Control/Fix.lean b/Mathlib/Control/Fix.lean index 4553cd46f208ff..d637d567cc6f69 100644 --- a/Mathlib/Control/Fix.lean +++ b/Mathlib/Control/Fix.lean @@ -117,8 +117,6 @@ instance hasFix : Fix (Part α) := end Part -open Sigma - namespace Pi instance Part.hasFix {β} : Fix (α → Part β) := diff --git a/Mathlib/Control/Random.lean b/Mathlib/Control/Random.lean index fb4093817ac2b5..528cfadd08b4a9 100644 --- a/Mathlib/Control/Random.lean +++ b/Mathlib/Control/Random.lean @@ -85,8 +85,6 @@ end Rand namespace Random -open Rand - variable [Monad m] /-- Generate a random value of type `α`. -/ diff --git a/Mathlib/Data/DFinsupp/Module.lean b/Mathlib/Data/DFinsupp/Module.lean index 20aa2e99b440eb..b6e26751c948e0 100644 --- a/Mathlib/Data/DFinsupp/Module.lean +++ b/Mathlib/Data/DFinsupp/Module.lean @@ -156,8 +156,6 @@ end DecidableEq section Equiv -open Finset - variable {κ : Type*} @[simp] diff --git a/Mathlib/Data/DList/Instances.lean b/Mathlib/Data/DList/Instances.lean index d2d89ffc6a26c0..d05033932b690c 100644 --- a/Mathlib/Data/DList/Instances.lean +++ b/Mathlib/Data/DList/Instances.lean @@ -19,7 +19,7 @@ for `DList`. @[expose] public section -open Function Equiv +open Equiv namespace Batteries diff --git a/Mathlib/Data/ENNReal/Action.lean b/Mathlib/Data/ENNReal/Action.lean index 3210f20daccfa1..2c05f4272f00a1 100644 --- a/Mathlib/Data/ENNReal/Action.lean +++ b/Mathlib/Data/ENNReal/Action.lean @@ -18,7 +18,7 @@ This file defines basic scalar actions on extended nonnegative reals, showing th @[expose] public section -open Set NNReal ENNReal +open NNReal ENNReal namespace ENNReal diff --git a/Mathlib/Data/ENNReal/Basic.lean b/Mathlib/Data/ENNReal/Basic.lean index 1a0a1261a3c53c..b877be8ed39605 100644 --- a/Mathlib/Data/ENNReal/Basic.lean +++ b/Mathlib/Data/ENNReal/Basic.lean @@ -739,7 +739,7 @@ unsafe instance : Repr ℝ≥0∞ where namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: `ENNReal.toReal`. -/ @[positivity ENNReal.toReal _] diff --git a/Mathlib/Data/ENNReal/Lemmas.lean b/Mathlib/Data/ENNReal/Lemmas.lean index 5a6d41605da22a..35457ccf936003 100644 --- a/Mathlib/Data/ENNReal/Lemmas.lean +++ b/Mathlib/Data/ENNReal/Lemmas.lean @@ -19,7 +19,7 @@ They are probably good targets for further cleanup or moves. public section -open Function Set NNReal +open Set NNReal variable {α : Type*} diff --git a/Mathlib/Data/ENNReal/Real.lean b/Mathlib/Data/ENNReal/Real.lean index 2aeca7a1b8dabf..48caab90c0c1c2 100644 --- a/Mathlib/Data/ENNReal/Real.lean +++ b/Mathlib/Data/ENNReal/Real.lean @@ -30,7 +30,7 @@ This file provides a `positivity` extension for `ENNReal.ofReal`. assert_not_exists Finset -open Set NNReal ENNReal +open NNReal ENNReal namespace ENNReal @@ -388,7 +388,7 @@ end ENNReal namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: `ENNReal.ofReal`. -/ @[positivity ENNReal.ofReal _] diff --git a/Mathlib/Data/EReal/Inv.lean b/Mathlib/Data/EReal/Inv.lean index 487d3f4fd09112..4d90b4e279d0a0 100644 --- a/Mathlib/Data/EReal/Inv.lean +++ b/Mathlib/Data/EReal/Inv.lean @@ -548,7 +548,7 @@ end EReal namespace Mathlib.Meta.Positivity -open Lean Meta Qq Function +open Lean Qq /-- Extension for the `positivity` tactic: inverse of an `EReal`. -/ @[positivity (_⁻¹ : EReal)] diff --git a/Mathlib/Data/Fin/Tuple/Reflection.lean b/Mathlib/Data/Fin/Tuple/Reflection.lean index e577f7abd086a9..d2b3c437ba98d3 100644 --- a/Mathlib/Data/Fin/Tuple/Reflection.lean +++ b/Mathlib/Data/Fin/Tuple/Reflection.lean @@ -169,7 +169,7 @@ example [AddCommMonoid α] (a : Fin 3 → α) : ∑ i, a i = a 0 + a 1 + a 2 := (sum_eq _).symm section Meta -open Lean Meta Qq +open Lean Qq /-- Produce a term of the form `f 0 * f 1 * ... * f (n - 1)` and an application of `FinVec.prod_eq` that shows it is equal to `∏ i, f i`. -/ diff --git a/Mathlib/Data/Finset/Attach.lean b/Mathlib/Data/Finset/Attach.lean index 2823309d9bee2d..234fb2fa35a72a 100644 --- a/Mathlib/Data/Finset/Attach.lean +++ b/Mathlib/Data/Finset/Attach.lean @@ -28,7 +28,7 @@ finite sets, finset -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice IsOrderedMonoid -open Multiset Subtype Function +open Multiset Subtype universe u diff --git a/Mathlib/Data/Finset/BooleanAlgebra.lean b/Mathlib/Data/Finset/BooleanAlgebra.lean index ae2576a09891db..cdf6eb5629cc22 100644 --- a/Mathlib/Data/Finset/BooleanAlgebra.lean +++ b/Mathlib/Data/Finset/BooleanAlgebra.lean @@ -27,8 +27,6 @@ assert_not_exists Monoid open Function -open Nat - universe u v variable {α β γ : Type*} diff --git a/Mathlib/Data/Finset/Dedup.lean b/Mathlib/Data/Finset/Dedup.lean index a56e20fb441271..8625b3b4b195ac 100644 --- a/Mathlib/Data/Finset/Dedup.lean +++ b/Mathlib/Data/Finset/Dedup.lean @@ -26,7 +26,7 @@ finite sets, finset -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice IsOrderedMonoid -open Multiset Subtype Function +open Multiset Function universe u diff --git a/Mathlib/Data/Finset/Density.lean b/Mathlib/Data/Finset/Density.lean index 3c837b046b56fd..504c991ea013c9 100644 --- a/Mathlib/Data/Finset/Density.lean +++ b/Mathlib/Data/Finset/Density.lean @@ -52,7 +52,7 @@ overengineering basic definitions is likely to hinder user experience. -- TODO -- assert_not_exists Ring -open Function Multiset Nat +open Function Nat variable {𝕜 α β : Type*} [Fintype α] diff --git a/Mathlib/Data/Finset/Disjoint.lean b/Mathlib/Data/Finset/Disjoint.lean index fc3931e2f3cca6..105388337bff94 100644 --- a/Mathlib/Data/Finset/Disjoint.lean +++ b/Mathlib/Data/Finset/Disjoint.lean @@ -28,7 +28,7 @@ finite sets, finset -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice Monoid -open Multiset Subtype Function +open Multiset Function variable {ι α β γ : Type*} diff --git a/Mathlib/Data/Finset/Empty.lean b/Mathlib/Data/Finset/Empty.lean index d6c6804b82af3e..d87f3a9912101d 100644 --- a/Mathlib/Data/Finset/Empty.lean +++ b/Mathlib/Data/Finset/Empty.lean @@ -30,7 +30,7 @@ finite sets, finset -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice IsOrderedMonoid -open Multiset Subtype Function +open Multiset Subtype universe u @@ -195,7 +195,7 @@ end Empty end Finset namespace Mathlib.Meta -open Qq Lean Meta Finset +open Qq Lean /-- Attempt to prove that a finset is nonempty using the `finsetNonempty` aesop rule-set. diff --git a/Mathlib/Data/Finset/Erase.lean b/Mathlib/Data/Finset/Erase.lean index 18a0169fb632f4..bf8fe13304522a 100644 --- a/Mathlib/Data/Finset/Erase.lean +++ b/Mathlib/Data/Finset/Erase.lean @@ -27,7 +27,7 @@ finite sets, finset -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice IsOrderedMonoid -open Multiset Subtype Function +open Multiset universe u diff --git a/Mathlib/Data/Finset/Lattice/Basic.lean b/Mathlib/Data/Finset/Lattice/Basic.lean index 7249c420ec26c7..c1b5076d829a1f 100644 --- a/Mathlib/Data/Finset/Lattice/Basic.lean +++ b/Mathlib/Data/Finset/Lattice/Basic.lean @@ -39,7 +39,7 @@ public section -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice IsOrderedMonoid -open Multiset Subtype Function +open Multiset universe u diff --git a/Mathlib/Data/Finset/Lattice/Lemmas.lean b/Mathlib/Data/Finset/Lattice/Lemmas.lean index f64aa7f920d21f..9e5f22a618806e 100644 --- a/Mathlib/Data/Finset/Lattice/Lemmas.lean +++ b/Mathlib/Data/Finset/Lattice/Lemmas.lean @@ -26,8 +26,6 @@ public section -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice Monoid -open Multiset Subtype Function - universe u variable {α : Type*} {β : Type*} {γ : Type*} diff --git a/Mathlib/Data/Finset/Lattice/Prod.lean b/Mathlib/Data/Finset/Lattice/Prod.lean index 0511defb7b136e..811f40072b026b 100644 --- a/Mathlib/Data/Finset/Lattice/Prod.lean +++ b/Mathlib/Data/Finset/Lattice/Prod.lean @@ -18,8 +18,6 @@ public section assert_not_exists IsOrderedMonoid MonoidWithZero -open Function Multiset OrderDual - variable {F α β γ ι κ : Type*} namespace Finset diff --git a/Mathlib/Data/Finset/Lattice/Union.lean b/Mathlib/Data/Finset/Lattice/Union.lean index 535b93f818b98f..ecc7cdd1ee6390 100644 --- a/Mathlib/Data/Finset/Lattice/Union.lean +++ b/Mathlib/Data/Finset/Lattice/Union.lean @@ -20,7 +20,7 @@ Remove `Finset.biUnion` in favour of `Finset.sup`. public section -open Function Multiset OrderDual +open OrderDual variable {F α β γ ι κ : Type*} variable {s s₁ s₂ : Finset β} {f g : β → α} {a : α} diff --git a/Mathlib/Data/Finset/Range.lean b/Mathlib/Data/Finset/Range.lean index ef9326b0cd34ee..f173b7aeae4213 100644 --- a/Mathlib/Data/Finset/Range.lean +++ b/Mathlib/Data/Finset/Range.lean @@ -38,7 +38,7 @@ variable {α : Type*} {β : Type*} {γ : Type*} namespace Finset -open Multiset Subtype Function +open Multiset /-! ### range -/ diff --git a/Mathlib/Data/Finset/SDiff.lean b/Mathlib/Data/Finset/SDiff.lean index 5aa4996f9db80b..d11481108e1f4c 100644 --- a/Mathlib/Data/Finset/SDiff.lean +++ b/Mathlib/Data/Finset/SDiff.lean @@ -28,7 +28,7 @@ public section -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice IsOrderedMonoid -open Multiset Subtype Function +open Multiset universe u diff --git a/Mathlib/Data/Finset/SymmDiff.lean b/Mathlib/Data/Finset/SymmDiff.lean index e811a9b7b8b0c4..1d71a1af576f58 100644 --- a/Mathlib/Data/Finset/SymmDiff.lean +++ b/Mathlib/Data/Finset/SymmDiff.lean @@ -25,7 +25,7 @@ public section -- Note that we cannot use `List.sublists` itself as that is defined very early. assert_not_exists List.sublistsLen Multiset.powerset CompleteLattice Monoid -open Multiset Subtype Function +open Function universe u diff --git a/Mathlib/Data/Fintype/BigOperators.lean b/Mathlib/Data/Fintype/BigOperators.lean index 586f0e13325f76..040b0132073370 100644 --- a/Mathlib/Data/Fintype/BigOperators.lean +++ b/Mathlib/Data/Fintype/BigOperators.lean @@ -31,8 +31,6 @@ public section assert_not_exists MulAction -open Mathlib - universe u v variable {α : Type*} {β : Type*} {γ : Type*} diff --git a/Mathlib/Data/Fintype/Fin.lean b/Mathlib/Data/Fintype/Fin.lean index a2e74adc058cfb..7d8f88a4c1aecb 100644 --- a/Mathlib/Data/Fintype/Fin.lean +++ b/Mathlib/Data/Fintype/Fin.lean @@ -21,8 +21,6 @@ open List (Vector) open Finset -open Fintype - namespace Fin variable {α β : Type*} {n : ℕ} diff --git a/Mathlib/Data/Fintype/Inv.lean b/Mathlib/Data/Fintype/Inv.lean index 4955764aea0eb6..93cbacfa957779 100644 --- a/Mathlib/Data/Fintype/Inv.lean +++ b/Mathlib/Data/Fintype/Inv.lean @@ -24,8 +24,6 @@ assert_not_exists Monoid open Function -open Nat - universe u v variable {α β γ : Type*} @@ -112,7 +110,7 @@ namespace Fintype section Choose -open Fintype Equiv +open Fintype variable [Fintype α] (p : α → Prop) [DecidablePred p] diff --git a/Mathlib/Data/Fintype/Lattice.lean b/Mathlib/Data/Fintype/Lattice.lean index 8b5a364e5186c1..06cad265e9bb97 100644 --- a/Mathlib/Data/Fintype/Lattice.lean +++ b/Mathlib/Data/Fintype/Lattice.lean @@ -14,11 +14,6 @@ public import Mathlib.Data.Fintype.Basic public section - -open Function - -open Nat - universe u v variable {ι α β : Type*} diff --git a/Mathlib/Data/Fintype/OfMap.lean b/Mathlib/Data/Fintype/OfMap.lean index 30f53d2f7f648b..6797370d7da438 100644 --- a/Mathlib/Data/Fintype/OfMap.lean +++ b/Mathlib/Data/Fintype/OfMap.lean @@ -26,8 +26,6 @@ assert_not_exists Monoid open Function -open Nat - universe u v variable {α β γ : Type*} diff --git a/Mathlib/Data/Fintype/Sigma.lean b/Mathlib/Data/Fintype/Sigma.lean index bad625b1368190..82b0379cbcbdd4 100644 --- a/Mathlib/Data/Fintype/Sigma.lean +++ b/Mathlib/Data/Fintype/Sigma.lean @@ -14,11 +14,6 @@ public import Mathlib.Data.Fintype.OfMap public section - -open Function - -open Nat - universe u v variable {ι α : Type*} {κ : ι → Type*} [Π i, Fintype (κ i)] diff --git a/Mathlib/Data/List/Defs.lean b/Mathlib/Data/List/Defs.lean index d77363c4f50ddc..583b8126a699d5 100644 --- a/Mathlib/Data/List/Defs.lean +++ b/Mathlib/Data/List/Defs.lean @@ -24,7 +24,7 @@ proofs about these definitions, those are contained in other files in `Data.List namespace List -open Function Nat +open Nat universe u v w x diff --git a/Mathlib/Data/List/Map2.lean b/Mathlib/Data/List/Map2.lean index bfc81d1622e131..80664eecf71be0 100644 --- a/Mathlib/Data/List/Map2.lean +++ b/Mathlib/Data/List/Map2.lean @@ -30,8 +30,6 @@ assert_not_exists Prod.swap_eq_iff_eq_swap assert_not_exists Ring assert_not_exists Set.range -open Function - open Nat hiding one_pos namespace List diff --git a/Mathlib/Data/List/Pairwise.lean b/Mathlib/Data/List/Pairwise.lean index 7860619d193500..22f82420b0ab99 100644 --- a/Mathlib/Data/List/Pairwise.lean +++ b/Mathlib/Data/List/Pairwise.lean @@ -30,7 +30,7 @@ sorted, nodup public section -open Nat Function +open Nat namespace List diff --git a/Mathlib/Data/List/Perm/Subperm.lean b/Mathlib/Data/List/Perm/Subperm.lean index 4d36d0ac531cdc..c0e73511d6e125 100644 --- a/Mathlib/Data/List/Perm/Subperm.lean +++ b/Mathlib/Data/List/Perm/Subperm.lean @@ -27,8 +27,6 @@ open Nat namespace List variable {α : Type*} {l l₁ l₂ : List α} {a : α} -open Perm - section Subperm attribute [trans] Subperm.trans diff --git a/Mathlib/Data/List/Sections.lean b/Mathlib/Data/List/Sections.lean index 9676e39b237dc6..dcb15edd6e8c91 100644 --- a/Mathlib/Data/List/Sections.lean +++ b/Mathlib/Data/List/Sections.lean @@ -16,7 +16,7 @@ list of lists `[l₁, ..., lₙ]` is a list whose `i`-th element comes from the public section -open Nat Function +open Nat namespace List diff --git a/Mathlib/Data/List/TakeDrop.lean b/Mathlib/Data/List/TakeDrop.lean index 5b87b33c5b3cd6..2990076707a471 100644 --- a/Mathlib/Data/List/TakeDrop.lean +++ b/Mathlib/Data/List/TakeDrop.lean @@ -23,8 +23,6 @@ assert_not_exists Prod.swap_eq_iff_eq_swap assert_not_exists Ring assert_not_exists Set.range -open Function - open Nat hiding one_pos namespace List diff --git a/Mathlib/Data/Multiset/AddSub.lean b/Mathlib/Data/Multiset/AddSub.lean index cb54202ac73bf9..2837709ba08905 100644 --- a/Mathlib/Data/Multiset/AddSub.lean +++ b/Mathlib/Data/Multiset/AddSub.lean @@ -33,7 +33,7 @@ assert_not_exists Monoid universe v -open List Subtype Nat Function +open List Nat variable {α : Type*} {β : Type v} {γ : Type*} diff --git a/Mathlib/Data/Multiset/Defs.lean b/Mathlib/Data/Multiset/Defs.lean index 0465105b9189c8..96d4da834801b9 100644 --- a/Mathlib/Data/Multiset/Defs.lean +++ b/Mathlib/Data/Multiset/Defs.lean @@ -61,7 +61,7 @@ assert_not_exists Monoid OrderHom universe v -open List Subtype Nat Function +open List Subtype Nat variable {α : Type*} {β : Type v} {γ : Type*} diff --git a/Mathlib/Data/Multiset/Interval.lean b/Mathlib/Data/Multiset/Interval.lean index de9722a3bbabc1..2310cff93ac805 100644 --- a/Mathlib/Data/Multiset/Interval.lean +++ b/Mathlib/Data/Multiset/Interval.lean @@ -29,7 +29,7 @@ multisets are typically used computationally. public section -open Finset DFinsupp Function +open Finset DFinsupp open scoped Pointwise diff --git a/Mathlib/Data/Multiset/OrderedMonoid.lean b/Mathlib/Data/Multiset/OrderedMonoid.lean index 2a722581743537..f8a71115ac35b5 100644 --- a/Mathlib/Data/Multiset/OrderedMonoid.lean +++ b/Mathlib/Data/Multiset/OrderedMonoid.lean @@ -21,8 +21,6 @@ variable {α : Type*} namespace Multiset -open List - instance : IsOrderedCancelAddMonoid (Multiset α) where add_le_add_left := fun _ _ => add_le_add_left le_of_add_le_add_left := fun _ _ _ => le_of_add_le_add_left diff --git a/Mathlib/Data/Multiset/Replicate.lean b/Mathlib/Data/Multiset/Replicate.lean index 20010802a85389..bd06015a119497 100644 --- a/Mathlib/Data/Multiset/Replicate.lean +++ b/Mathlib/Data/Multiset/Replicate.lean @@ -23,7 +23,7 @@ assert_not_exists Monoid universe v -open List Subtype Nat Function +open List Nat Function variable {α : Type*} {β : Type v} {γ : Type*} diff --git a/Mathlib/Data/Multiset/UnionInter.lean b/Mathlib/Data/Multiset/UnionInter.lean index bc03f9b1411625..7d30a81189962a 100644 --- a/Mathlib/Data/Multiset/UnionInter.lean +++ b/Mathlib/Data/Multiset/UnionInter.lean @@ -29,7 +29,7 @@ assert_not_exists Monoid universe v -open List Subtype Nat Function +open List Nat Function variable {α : Type*} {β : Type v} {γ : Type*} diff --git a/Mathlib/Data/Multiset/ZeroCons.lean b/Mathlib/Data/Multiset/ZeroCons.lean index bba540882d9761..8a70475853a868 100644 --- a/Mathlib/Data/Multiset/ZeroCons.lean +++ b/Mathlib/Data/Multiset/ZeroCons.lean @@ -40,7 +40,7 @@ assert_not_exists Monoid OrderHom universe v -open List Subtype Nat Function +open List Subtype Nat variable {α : Type*} {β : Type v} {γ : Type*} diff --git a/Mathlib/Data/NNRat/Lemmas.lean b/Mathlib/Data/NNRat/Lemmas.lean index 7c0c1d60f5aef0..8ec55c9b47a765 100644 --- a/Mathlib/Data/NNRat/Lemmas.lean +++ b/Mathlib/Data/NNRat/Lemmas.lean @@ -20,7 +20,6 @@ cycles. @[expose] public section -open Function open scoped NNRat namespace NNRat diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index 1c6e7636119389..8bf272a1a75be7 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -999,7 +999,7 @@ unsafe instance : Repr ℝ≥0 where namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq alias ⟨_, nnreal_coe_pos⟩ := coe_pos diff --git a/Mathlib/Data/Nat/Cast/Basic.lean b/Mathlib/Data/Nat/Cast/Basic.lean index 5a263f821b04ef..65e315e6ebb697 100644 --- a/Mathlib/Data/Nat/Cast/Basic.lean +++ b/Mathlib/Data/Nat/Cast/Basic.lean @@ -30,8 +30,6 @@ assert_not_exists IsOrderedMonoid Commute.zero_right Commute.add_right abs_eq_ma -- TODO: `MulOpposite.op_natCast` was not intended to be imported -- assert_not_exists MulOpposite.op_natCast -open Additive Multiplicative - variable {α β : Type*} namespace Nat diff --git a/Mathlib/Data/Nat/Factorization/Induction.lean b/Mathlib/Data/Nat/Factorization/Induction.lean index ae5e856c124fe7..1279719df8b4f3 100644 --- a/Mathlib/Data/Nat/Factorization/Induction.lean +++ b/Mathlib/Data/Nat/Factorization/Induction.lean @@ -13,7 +13,7 @@ public import Mathlib.Data.Nat.Factorization.Defs @[expose] public section -open Nat Finset List Finsupp +open Nat Finsupp namespace Nat variable {a b m n p : ℕ} diff --git a/Mathlib/Data/Nat/Factorization/LCM.lean b/Mathlib/Data/Nat/Factorization/LCM.lean index 9aa5aa0919dbb5..ae4240824e7fe2 100644 --- a/Mathlib/Data/Nat/Factorization/LCM.lean +++ b/Mathlib/Data/Nat/Factorization/LCM.lean @@ -17,7 +17,7 @@ These were split from `Mathlib.Data.Nat.Factorization.Basic` to reduce transitiv public section -open Finset List Finsupp +open Finset Finsupp namespace Nat diff --git a/Mathlib/Data/Nat/Init.lean b/Mathlib/Data/Nat/Init.lean index 7144497528ac19..a2e945bf8a9da5 100644 --- a/Mathlib/Data/Nat/Init.lean +++ b/Mathlib/Data/Nat/Init.lean @@ -54,8 +54,6 @@ The relevant files are: /- We don't want to import the algebraic hierarchy in this file. -/ assert_not_exists Monoid -open Function - namespace Nat variable {a b c d e m n k : ℕ} {p : ℕ → Prop} diff --git a/Mathlib/Data/Prod/TProd.lean b/Mathlib/Data/Prod/TProd.lean index 5188a52ccf1468..ef2a61e1ac4515 100644 --- a/Mathlib/Data/Prod/TProd.lean +++ b/Mathlib/Data/Prod/TProd.lean @@ -39,7 +39,7 @@ construction/theorem that is easier to define/prove on binary products than on f @[expose] public section -open List Function +open List universe u v variable {ι : Type u} {α : ι → Type v} {i j : ι} {l : List ι} diff --git a/Mathlib/Data/Rat/Cast/Order.lean b/Mathlib/Data/Rat/Cast/Order.lean index 8fecc133d64446..c2105037fe8d63 100644 --- a/Mathlib/Data/Rat/Cast/Order.lean +++ b/Mathlib/Data/Rat/Cast/Order.lean @@ -256,7 +256,7 @@ theorem preimage_cast_uIoc (p q : ℚ≥0) : (↑) ⁻¹' uIoc (p : K) q = uIoc end NNRat namespace Mathlib.Meta.Positivity -open Lean Meta Qq Function +open Lean Qq /-- Extension for Rat.cast. -/ @[positivity Rat.cast _] diff --git a/Mathlib/Data/Set/Disjoint.lean b/Mathlib/Data/Set/Disjoint.lean index 2227bbb9d0af32..e454989683e886 100644 --- a/Mathlib/Data/Set/Disjoint.lean +++ b/Mathlib/Data/Set/Disjoint.lean @@ -17,8 +17,6 @@ assert_not_exists HeytingAlgebra RelIso /-! ### Set coercion to a type -/ -open Function - universe u v namespace Set diff --git a/Mathlib/Data/Set/Enumerate.lean b/Mathlib/Data/Set/Enumerate.lean index ba8b7a5df130d1..a661ae2ed04e07 100644 --- a/Mathlib/Data/Set/Enumerate.lean +++ b/Mathlib/Data/Set/Enumerate.lean @@ -23,8 +23,6 @@ assert_not_exists RelIso noncomputable section -open Function - namespace Set section Enumerate diff --git a/Mathlib/Data/Set/Finite/Monad.lean b/Mathlib/Data/Set/Finite/Monad.lean index 69fa3987ab35dd..a59f4abe29554e 100644 --- a/Mathlib/Data/Set/Finite/Monad.lean +++ b/Mathlib/Data/Set/Finite/Monad.lean @@ -21,7 +21,7 @@ finite sets assert_not_exists IsOrderedRing MonoidWithZero -open Set Function +open Set universe u v w x diff --git a/Mathlib/Data/Set/Order.lean b/Mathlib/Data/Set/Order.lean index f5a0749752689b..a36f0fac758a32 100644 --- a/Mathlib/Data/Set/Order.lean +++ b/Mathlib/Data/Set/Order.lean @@ -13,8 +13,6 @@ public import Mathlib.Data.Set.Basic public section -open Function - universe u v namespace Set diff --git a/Mathlib/Data/Set/Pairwise/Basic.lean b/Mathlib/Data/Set/Pairwise/Basic.lean index f1bb1b4a50a058..d42def57ca0cb9 100644 --- a/Mathlib/Data/Set/Pairwise/Basic.lean +++ b/Mathlib/Data/Set/Pairwise/Basic.lean @@ -32,7 +32,7 @@ on `Set.PairwiseDisjoint`, even though the latter unfolds to something nicer. @[expose] public section -open Function Order Set +open Function Set variable {α β γ ι ι' : Type*} {r p : α → α → Prop} diff --git a/Mathlib/Data/Set/Piecewise.lean b/Mathlib/Data/Set/Piecewise.lean index 81ee43d31248a6..8e88e5b84e0a04 100644 --- a/Mathlib/Data/Set/Piecewise.lean +++ b/Mathlib/Data/Set/Piecewise.lean @@ -17,7 +17,7 @@ public section variable {α β γ δ : Type*} {ι : Sort*} {π : α → Type*} -open Equiv Equiv.Perm Function +open Equiv.Perm Function namespace Set diff --git a/Mathlib/Data/Set/Restrict.lean b/Mathlib/Data/Set/Restrict.lean index 4fe388fdf5e688..4b61e3aa5c92e7 100644 --- a/Mathlib/Data/Set/Restrict.lean +++ b/Mathlib/Data/Set/Restrict.lean @@ -20,7 +20,7 @@ public import Mathlib.Data.Set.Image variable {α β γ δ : Type*} {ι : Sort*} {π : α → Type*} -open Equiv Equiv.Perm Function +open Equiv.Perm Function namespace Set diff --git a/Mathlib/Data/Set/Subsingleton.lean b/Mathlib/Data/Set/Subsingleton.lean index 3af37eac7e4c0b..f35011a0c4f569 100644 --- a/Mathlib/Data/Set/Subsingleton.lean +++ b/Mathlib/Data/Set/Subsingleton.lean @@ -22,8 +22,6 @@ elements. assert_not_exists HeytingAlgebra RelIso -open Function - universe u v namespace Set diff --git a/Mathlib/Data/Sum/Lattice.lean b/Mathlib/Data/Sum/Lattice.lean index a77ae52e745223..d309ed98f1a31d 100644 --- a/Mathlib/Data/Sum/Lattice.lean +++ b/Mathlib/Data/Sum/Lattice.lean @@ -17,8 +17,6 @@ everything in `α` is declared smaller than everything in `β`. @[expose] public section -open OrderDual - namespace Sum.Lex variable {α β : Type*} diff --git a/Mathlib/Data/WSeq/Defs.lean b/Mathlib/Data/WSeq/Defs.lean index ad1172a9f4ad46..ae33b29da9fe11 100644 --- a/Mathlib/Data/WSeq/Defs.lean +++ b/Mathlib/Data/WSeq/Defs.lean @@ -23,8 +23,6 @@ namespace Stream'.WSeq variable {α : Type u} {β : Type v} {γ : Type w} -open Function - /-- Get the length of `s` (if it is finite and completes in finite time). -/ def length (s : WSeq α) : Computation ℕ := @Computation.corec ℕ (ℕ × WSeq α) diff --git a/Mathlib/Data/WSeq/Productive.lean b/Mathlib/Data/WSeq/Productive.lean index a241eb999cc8d2..995e6ffb189b7c 100644 --- a/Mathlib/Data/WSeq/Productive.lean +++ b/Mathlib/Data/WSeq/Productive.lean @@ -23,8 +23,6 @@ namespace Stream'.WSeq variable {α : Type u} -open Function - /-- A weak sequence is *productive* if it never stalls forever - there are always a finite number of `think`s between `cons` constructors. The sequence itself is allowed to be infinite though. -/ diff --git a/Mathlib/Data/ZMod/QuotientRing.lean b/Mathlib/Data/ZMod/QuotientRing.lean index 8ae25270c721aa..a392032c810ea6 100644 --- a/Mathlib/Data/ZMod/QuotientRing.lean +++ b/Mathlib/Data/ZMod/QuotientRing.lean @@ -28,7 +28,7 @@ zmod, quotient ring, ideal quotient @[expose] public section -open QuotientAddGroup Set ZMod +open Set ZMod variable (n : ℕ) {A R : Type*} [AddGroup A] [Ring R] diff --git a/Mathlib/Dynamics/Ergodic/AddCircleAdd.lean b/Mathlib/Dynamics/Ergodic/AddCircleAdd.lean index 93b7adf576f5c6..bb4c802d06dbd3 100644 --- a/Mathlib/Dynamics/Ergodic/AddCircleAdd.lean +++ b/Mathlib/Dynamics/Ergodic/AddCircleAdd.lean @@ -18,7 +18,7 @@ if and only if `a` has infinite order (in other words, if `a / p` is irrational) public section -open Metric MeasureTheory AddSubgroup +open MeasureTheory AddSubgroup open scoped Pointwise namespace AddCircle diff --git a/Mathlib/Dynamics/Ergodic/Function.lean b/Mathlib/Dynamics/Ergodic/Function.lean index 63d8939bc590ff..747aa0dd0e5e54 100644 --- a/Mathlib/Dynamics/Ergodic/Function.lean +++ b/Mathlib/Dynamics/Ergodic/Function.lean @@ -20,7 +20,7 @@ with all a.e. equalities replaced with equalities in the quotient space. public section -open Function Set Filter MeasureTheory Topology TopologicalSpace +open Function Set Filter MeasureTheory TopologicalSpace variable {α X : Type*} [MeasurableSpace α] {μ : MeasureTheory.Measure α} diff --git a/Mathlib/Dynamics/Flow.lean b/Mathlib/Dynamics/Flow.lean index 61f9826be4b98b..ebcdc1313754cc 100644 --- a/Mathlib/Dynamics/Flow.lean +++ b/Mathlib/Dynamics/Flow.lean @@ -32,7 +32,7 @@ flow onto an invariant subset, and the time-reversal of a flow by a group. @[expose] public section -open Set Function Filter +open Set Function variable {τ α : Type*} diff --git a/Mathlib/Dynamics/Newton.lean b/Mathlib/Dynamics/Newton.lean index 3d302b548de0c9..fb98012aeb3fe5 100644 --- a/Mathlib/Dynamics/Newton.lean +++ b/Mathlib/Dynamics/Newton.lean @@ -31,7 +31,7 @@ as Hensel's lemma and the Jordan-Chevalley decomposition. @[expose] public section -open Set Function +open Function noncomputable section diff --git a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean index cd2f0dccad212b..4addd7cb24fd7e 100644 --- a/Mathlib/Dynamics/SymbolicDynamics/Basic.lean +++ b/Mathlib/Dynamics/SymbolicDynamics/Basic.lean @@ -107,7 +107,7 @@ between the two viewpoints, since both may naturally want to reuse names like @[expose] public section noncomputable section -open Set Topology +open Set namespace SymbolicDynamics diff --git a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean index 907f5c1bea1884..fae2bf600934e7 100644 --- a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean +++ b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean @@ -56,7 +56,7 @@ entropy, semiconjugacy public section -open Function Prod Set Uniformity UniformSpace +open Function Prod Set UniformSpace open scoped SetRel namespace Dynamics @@ -111,7 +111,7 @@ lemma coverMincard_image_le (h : Semiconj φ S T) (F : Set X) (V : SetRel Y Y) ( rw [← s.coe_image] at this exact this.coverMincard_le_card.trans (WithTop.coe_le_coe.2 s.card_image_le) -open ENNReal EReal ExpGrowth Filter +open EReal ExpGrowth Filter lemma le_coverEntropyEntourage_image (h : Semiconj φ S T) (F : Set X) [V.IsSymm] : coverEntropyEntourage S F ((map φ φ) ⁻¹' (V ○ V)) ≤ coverEntropyEntourage T (φ '' F) V := diff --git a/Mathlib/FieldTheory/AlgebraicClosure.lean b/Mathlib/FieldTheory/AlgebraicClosure.lean index 6bfa07f324596f..5e0e3eb613feaa 100644 --- a/Mathlib/FieldTheory/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/AlgebraicClosure.lean @@ -23,7 +23,7 @@ In this file we construct the relative algebraic closure of a field extension. @[expose] public section noncomputable section -open Polynomial FiniteDimensional IntermediateField Field +open Polynomial IntermediateField Field variable (F E : Type*) [Field F] [Field E] [Algebra F E] variable {K : Type*} [Field K] [Algebra F K] diff --git a/Mathlib/FieldTheory/Finite/Polynomial.lean b/Mathlib/FieldTheory/Finite/Polynomial.lean index 407f421b45c2ad..27247ee09ddb7e 100644 --- a/Mathlib/FieldTheory/Finite/Polynomial.lean +++ b/Mathlib/FieldTheory/Finite/Polynomial.lean @@ -49,7 +49,7 @@ namespace MvPolynomial noncomputable section -open Set LinearMap Submodule +open LinearMap Submodule variable {K : Type*} {σ : Type*} diff --git a/Mathlib/FieldTheory/Finiteness.lean b/Mathlib/FieldTheory/Finiteness.lean index 36b3c6da7f7100..42379ad1496752 100644 --- a/Mathlib/FieldTheory/Finiteness.lean +++ b/Mathlib/FieldTheory/Finiteness.lean @@ -18,7 +18,7 @@ public import Mathlib.LinearAlgebra.Dimension.Finite universe u v -open Cardinal Submodule Module Function +open Cardinal Submodule Module namespace IsNoetherian diff --git a/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean b/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean index 4356fb001bd12b..473dc032f7a159 100644 --- a/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean +++ b/Mathlib/FieldTheory/IntermediateField/Adjoin/Algebra.lean @@ -19,7 +19,7 @@ This file relates `IntermediateField.adjoin` to `Algebra.adjoin`. public section -open Module Polynomial +open Module namespace IntermediateField diff --git a/Mathlib/FieldTheory/IsPerfectClosure.lean b/Mathlib/FieldTheory/IsPerfectClosure.lean index cf8aa7732eb5da..07007ae41b7951 100644 --- a/Mathlib/FieldTheory/IsPerfectClosure.lean +++ b/Mathlib/FieldTheory/IsPerfectClosure.lean @@ -64,7 +64,7 @@ perfect ring, perfect closure, purely inseparable @[expose] public section -open Module Polynomial IntermediateField Field +open Field noncomputable section diff --git a/Mathlib/FieldTheory/JacobsonNoether.lean b/Mathlib/FieldTheory/JacobsonNoether.lean index a6f82c4e7180e1..7b29736832a573 100644 --- a/Mathlib/FieldTheory/JacobsonNoether.lean +++ b/Mathlib/FieldTheory/JacobsonNoether.lean @@ -56,7 +56,7 @@ variable {D : Type*} [DivisionRing D] [Algebra.IsAlgebraic (Subring.center D) D] local notation3 "k" => Subring.center D -open Polynomial LinearMap LieAlgebra +open LinearMap LieAlgebra /-- If `D` is a purely inseparable extension of `k` with characteristic `p`, then for every element `a` of `D`, there exists a natural number `n` diff --git a/Mathlib/FieldTheory/Tower.lean b/Mathlib/FieldTheory/Tower.lean index df09ff7607a362..2e40c198ff8745 100644 --- a/Mathlib/FieldTheory/Tower.lean +++ b/Mathlib/FieldTheory/Tower.lean @@ -29,7 +29,7 @@ public section universe u v w u₁ v₁ w₁ -open Cardinal Submodule +open Submodule variable (F : Type u) (K : Type v) (A : Type w) diff --git a/Mathlib/Geometry/Convex/Cone/Pointed.lean b/Mathlib/Geometry/Convex/Cone/Pointed.lean index 55ff334f44df7b..17420b4c7b1dce 100644 --- a/Mathlib/Geometry/Convex/Cone/Pointed.lean +++ b/Mathlib/Geometry/Convex/Cone/Pointed.lean @@ -36,7 +36,7 @@ abbrev PointedCone (R E) namespace PointedCone -open Function Submodule Pointwise +open Function Submodule open scoped Pointwise diff --git a/Mathlib/Geometry/Convex/ConvexSpace/Prod.lean b/Mathlib/Geometry/Convex/ConvexSpace/Prod.lean index c5cd965bb5fa61..fb31353e0165b3 100644 --- a/Mathlib/Geometry/Convex/ConvexSpace/Prod.lean +++ b/Mathlib/Geometry/Convex/ConvexSpace/Prod.lean @@ -13,7 +13,7 @@ public import Mathlib.Geometry.Convex.ConvexSpace.Defs This file defines the cartesian product of convex spaces. -/ -open Convexity Finsupp Set +open Convexity Finsupp public noncomputable section diff --git a/Mathlib/Geometry/Convex/Star.lean b/Mathlib/Geometry/Convex/Star.lean index 1fa1548a6e9297..c6cd79d5f4d8b2 100644 --- a/Mathlib/Geometry/Convex/Star.lean +++ b/Mathlib/Geometry/Convex/Star.lean @@ -29,7 +29,7 @@ Incidentally, this choice means we don't need to assume a set is nonempty for it Concretely, the empty set is star-convex at every point. -/ -open Finsupp Set +open Set public section diff --git a/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean b/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean index ab792de1c22873..0d35e4bc5e5123 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Oriented/Affine.lean @@ -26,7 +26,7 @@ This file defines oriented angles in Euclidean affine spaces. noncomputable section -open Module Complex +open Module open scoped Affine EuclideanGeometry Real RealInnerProductSpace ComplexConjugate diff --git a/Mathlib/Geometry/Euclidean/Angle/Sphere.lean b/Mathlib/Geometry/Euclidean/Angle/Sphere.lean index 82667ad1417015..db9105e198d660 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Sphere.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Sphere.lean @@ -21,7 +21,7 @@ public section noncomputable section -open Module Complex +open Module open scoped EuclideanGeometry Real RealInnerProductSpace ComplexConjugate diff --git a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean index f583bf76b20867..665c31e008a1ea 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Unoriented/Affine.lean @@ -26,7 +26,7 @@ This file defines unoriented angles in Euclidean affine spaces. noncomputable section -open Real RealInnerProductSpace +open Real namespace EuclideanGeometry diff --git a/Mathlib/Geometry/Euclidean/Inversion/Basic.lean b/Mathlib/Geometry/Euclidean/Inversion/Basic.lean index 9ced846f557349..777c216782d743 100644 --- a/Mathlib/Geometry/Euclidean/Inversion/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Inversion/Basic.lean @@ -28,7 +28,7 @@ Currently, we prove only a few basic lemmas needed to prove Ptolemy's inequality noncomputable section -open Metric Function AffineMap Set AffineSubspace +open Metric Function AffineMap Set open scoped Topology variable {V P : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V] [MetricSpace P] diff --git a/Mathlib/Geometry/Euclidean/Inversion/Calculus.lean b/Mathlib/Geometry/Euclidean/Inversion/Calculus.lean index 8ad55e9fee219f..d26b48b5fac712 100644 --- a/Mathlib/Geometry/Euclidean/Inversion/Calculus.lean +++ b/Mathlib/Geometry/Euclidean/Inversion/Calculus.lean @@ -27,7 +27,7 @@ inversion, derivative public section -open Metric Function AffineMap Set AffineSubspace +open Function Set open scoped Topology RealInnerProductSpace variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] diff --git a/Mathlib/Geometry/Euclidean/Inversion/ImageHyperplane.lean b/Mathlib/Geometry/Euclidean/Inversion/ImageHyperplane.lean index d57acd63ab9fff..ca41184f333e6c 100644 --- a/Mathlib/Geometry/Euclidean/Inversion/ImageHyperplane.lean +++ b/Mathlib/Geometry/Euclidean/Inversion/ImageHyperplane.lean @@ -28,7 +28,7 @@ inversion public section -open Metric Function AffineMap Set AffineSubspace +open Metric AffineMap Set AffineSubspace open scoped Topology variable {V P : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V] [MetricSpace P] diff --git a/Mathlib/Geometry/Euclidean/Similarity.lean b/Mathlib/Geometry/Euclidean/Similarity.lean index 8599c2ba2330b3..e9b11b912683e7 100644 --- a/Mathlib/Geometry/Euclidean/Similarity.lean +++ b/Mathlib/Geometry/Euclidean/Similarity.lean @@ -21,7 +21,7 @@ public section open scoped Congruent EuclideanGeometry -open Similar NNReal Affine +open Similar namespace EuclideanGeometry diff --git a/Mathlib/Geometry/Euclidean/Sphere/Power.lean b/Mathlib/Geometry/Euclidean/Sphere/Power.lean index a79253fd8dd3e4..4d6ff080c3afd0 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Power.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Power.lean @@ -33,7 +33,7 @@ secants) in spheres in real inner product spaces and Euclidean affine spaces. @[expose] public section -open Real EuclideanGeometry RealInnerProductSpace Real Module FiniteDimensional +open Real EuclideanGeometry RealInnerProductSpace Real Module variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V] diff --git a/Mathlib/Geometry/Manifold/Bordism.lean b/Mathlib/Geometry/Manifold/Bordism.lean index e156ba8ea13737..00a615911e3f3c 100644 --- a/Mathlib/Geometry/Manifold/Bordism.lean +++ b/Mathlib/Geometry/Manifold/Bordism.lean @@ -95,7 +95,7 @@ singular manifold, bordism, bordism group public section open scoped Manifold -open Module Set +open Module suppress_compilation diff --git a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean index 3ba1ad6ba5b184..df0bf58c6042d7 100644 --- a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean +++ b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean @@ -40,7 +40,7 @@ noncomputable section section LieGroup -open Bundle Filter Function Set +open Bundle Function open scoped Manifold variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] diff --git a/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean b/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean index 46f2b6ea9d182a..b6b839afd706de 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve/Transform.lean @@ -102,8 +102,6 @@ end Translation section Scaling -open Manifold - lemma IsMIntegralCurveOn.comp_mul (hγ : IsMIntegralCurveOn γ v s) (a : ℝ) : IsMIntegralCurveOn (γ ∘ (· * a)) (a • v) { t | t * a ∈ s } := by intro t ht diff --git a/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean b/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean index ab1e4a4b92d4d4..d3e7458eb8e918 100644 --- a/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean +++ b/Mathlib/Geometry/Manifold/LocalSourceTargetProperty.lean @@ -42,7 +42,7 @@ public section open scoped Manifold Topology ContDiff -open Function Set +open Set variable {𝕜 E E' F F' H H' G G' : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] diff --git a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean index 4eb6a5d861029f..67606ae2453b8d 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/Basic.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/Basic.lean @@ -139,7 +139,7 @@ lemma enorm_tangentSpace_vectorSpace {x : F} {v : TangentSpace% x} : ‖v‖ₑ = ‖letI V : F := v; V‖ₑ := by simp [enorm, nnnorm_tangentSpace_vectorSpace] -open MeasureTheory Measure +open MeasureTheory lemma lintegral_fderiv_lineMap_eq_edist {x y : E} : ∫⁻ t in Icc 0 1, ‖fderivWithin ℝ (ContinuousAffineMap.lineMap (R := ℝ) x y) (Icc 0 1) t 1‖ₑ diff --git a/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean b/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean index 1933e856a715f8..a597611983dc04 100644 --- a/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/Manifold/Sheaf/LocallyRingedSpace.lean @@ -141,7 +141,7 @@ def ChartedSpace.locallyRingedSpace : LocallyRingedSpace where @[deprecated (since := "2026-04-01")] alias IsManifold.locallyRingedSpace := ChartedSpace.locallyRingedSpace -open CategoryTheory Limits +open CategoryTheory variable {M IM IN} diff --git a/Mathlib/Geometry/Manifold/StructureGroupoid.lean b/Mathlib/Geometry/Manifold/StructureGroupoid.lean index 001bbfc8d402b3..92779b04b21b46 100644 --- a/Mathlib/Geometry/Manifold/StructureGroupoid.lean +++ b/Mathlib/Geometry/Manifold/StructureGroupoid.lean @@ -39,7 +39,7 @@ composition of partial equivs with `≫`. noncomputable section -open TopologicalSpace Topology +open TopologicalSpace variable {H : Type*} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index ed056ceab00c41..0fd18472da12b7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -17,7 +17,7 @@ import Mathlib.Geometry.Manifold.Notation public section -open Bundle Set ContinuousLinearMap Pretrivialization Filter +open Bundle Set ContinuousLinearMap Filter open scoped Manifold Topology section diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index cc16fc4c453885..48e3b5f7930ef1 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -96,8 +96,6 @@ instance {X Y : LocallyRingedSpace} (f : X ⟶ Y) [LocallyRingedSpace.IsOpenImme namespace PresheafedSpace.IsOpenImmersion -open PresheafedSpace - local notation "IsOpenImmersion" => PresheafedSpace.IsOpenImmersion attribute [instance] IsOpenImmersion.c_iso diff --git a/Mathlib/GroupTheory/ClassEquation.lean b/Mathlib/GroupTheory/ClassEquation.lean index 2147807039c374..485f6c024f126c 100644 --- a/Mathlib/GroupTheory/ClassEquation.lean +++ b/Mathlib/GroupTheory/ClassEquation.lean @@ -26,7 +26,7 @@ This file establishes the class equation for finite groups. public section -open MulAction ConjClasses +open ConjClasses variable (G : Type*) [Group G] diff --git a/Mathlib/GroupTheory/Coxeter/Inversion.lean b/Mathlib/GroupTheory/Coxeter/Inversion.lean index f6da05161685be..a5e05a1df8da80 100644 --- a/Mathlib/GroupTheory/Coxeter/Inversion.lean +++ b/Mathlib/GroupTheory/Coxeter/Inversion.lean @@ -51,7 +51,7 @@ assert_not_exists TwoSidedIdeal namespace CoxeterSystem -open List Matrix Function +open List Function variable {B : Type*} variable {W : Type*} [Group W] diff --git a/Mathlib/GroupTheory/Coxeter/Length.lean b/Mathlib/GroupTheory/Coxeter/Length.lean index 2ddaecacc15999..3cc79d848f0873 100644 --- a/Mathlib/GroupTheory/Coxeter/Length.lean +++ b/Mathlib/GroupTheory/Coxeter/Length.lean @@ -55,7 +55,7 @@ assert_not_exists TwoSidedIdeal namespace CoxeterSystem -open List Matrix Function +open List Function variable {B W : Type*} [Group W] variable {M : CoxeterMatrix B} (cs : CoxeterSystem M W) diff --git a/Mathlib/GroupTheory/Index.lean b/Mathlib/GroupTheory/Index.lean index 579a2624ffd741..2ffffef8e6dc0a 100644 --- a/Mathlib/GroupTheory/Index.lean +++ b/Mathlib/GroupTheory/Index.lean @@ -47,7 +47,7 @@ open scoped Pointwise namespace Subgroup -open Cardinal Function +open Function variable {G G' : Type*} [Group G] [Group G'] (H K L : Subgroup G) diff --git a/Mathlib/GroupTheory/MonoidLocalization/Away.lean b/Mathlib/GroupTheory/MonoidLocalization/Away.lean index 689b87ad84db31..7da3b199ba081b 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Away.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Away.lean @@ -23,8 +23,6 @@ commutative monoid, grothendieck group assert_not_exists MonoidWithZero -open Function - section CommMonoid variable {M : Type*} [CommMonoid M] {S : Submonoid M} {N : Type*} [CommMonoid N] {P : Type*} diff --git a/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean b/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean index 6c43362e98db7c..df2dc06d833cb7 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean @@ -18,8 +18,6 @@ public import Mathlib.RingTheory.OreLocalization.Basic @[expose] public section -open Function - section CommMonoidWithZero variable {M : Type*} [CommMonoidWithZero M] (S : Submonoid M) (N : Type*) [CommMonoidWithZero N] diff --git a/Mathlib/GroupTheory/Perm/Basic.lean b/Mathlib/GroupTheory/Perm/Basic.lean index b4d349f276baab..e8fae1e39ca89f 100644 --- a/Mathlib/GroupTheory/Perm/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Basic.lean @@ -47,7 +47,7 @@ theorem swap_smul_involutive [MulAction (Perm α) β] (i j : α) : end Swap end Equiv -open Equiv Function +open Equiv namespace Set variable {α : Type*} {f : Perm α} {s : Set α} diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index 022790fc8c2f24..90936dc286012c 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -550,7 +550,7 @@ end Sylow end InfiniteSylow -open Equiv Equiv.Perm Finset Function List QuotientGroup +open Equiv Equiv.Perm Finset Function QuotientGroup universe u diff --git a/Mathlib/Lean/FoldEnvironment.lean b/Mathlib/Lean/FoldEnvironment.lean index 91e548801c9aea..a2aa70e3f9db3f 100644 --- a/Mathlib/Lean/FoldEnvironment.lean +++ b/Mathlib/Lean/FoldEnvironment.lean @@ -20,7 +20,7 @@ without any parallelism. variable {α : Type} -open Lean Meta +open Lean namespace Lean.Meta diff --git a/Mathlib/LinearAlgebra/Basis/Cardinality.lean b/Mathlib/LinearAlgebra/Basis/Cardinality.lean index 2e312c3745c929..65c2d61316977d 100644 --- a/Mathlib/LinearAlgebra/Basis/Cardinality.lean +++ b/Mathlib/LinearAlgebra/Basis/Cardinality.lean @@ -18,7 +18,7 @@ public section section Finite -open Module Basis Cardinal Set Submodule Finsupp +open Module Cardinal Set Submodule Finsupp universe u v w w' diff --git a/Mathlib/LinearAlgebra/Basis/Defs.lean b/Mathlib/LinearAlgebra/Basis/Defs.lean index 4428deb1f33dff..442db84a62a603 100644 --- a/Mathlib/LinearAlgebra/Basis/Defs.lean +++ b/Mathlib/LinearAlgebra/Basis/Defs.lean @@ -216,8 +216,6 @@ end Basis section Fintype -open Basis - open Fintype /-- A module over `R` with a finite basis is linearly equivalent to functions from its basis to `R`. diff --git a/Mathlib/LinearAlgebra/Basis/Prod.lean b/Mathlib/LinearAlgebra/Basis/Prod.lean index 03595d952427d4..284f4a4071f3d2 100644 --- a/Mathlib/LinearAlgebra/Basis/Prod.lean +++ b/Mathlib/LinearAlgebra/Basis/Prod.lean @@ -22,7 +22,7 @@ noncomputable section universe u -open Function Set Submodule Finsupp +open Function Finsupp variable {ι : Type*} {ι' : Type*} {R : Type*} {R₂ : Type*} {M : Type*} {M' : Type*} diff --git a/Mathlib/LinearAlgebra/Basis/Submodule.lean b/Mathlib/LinearAlgebra/Basis/Submodule.lean index 9675e3ef19ff73..3e2d77746e8996 100644 --- a/Mathlib/LinearAlgebra/Basis/Submodule.lean +++ b/Mathlib/LinearAlgebra/Basis/Submodule.lean @@ -48,8 +48,6 @@ theorem mem_submodule_iff' [Fintype ι] {P : Submodule R M} (b : Basis ι R P) { end Basis -open LinearMap - variable {v : ι → M} variable [Ring R] [CommRing R₂] [AddCommGroup M] variable [Module R M] [Module R₂ M] diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean index abfb945c6049b4..f06d1130ec5d8d 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/SpinGroup.lean @@ -53,7 +53,7 @@ variable {Q : QuadraticForm R M} section Pin -open CliffordAlgebra MulAction +open CliffordAlgebra open scoped Pointwise @@ -284,7 +284,7 @@ end Pin section Spin -open CliffordAlgebra MulAction +open CliffordAlgebra open scoped Pointwise diff --git a/Mathlib/LinearAlgebra/Complex/Module.lean b/Mathlib/LinearAlgebra/Complex/Module.lean index ce14d98da1ed4e..0e413d41f1b5d6 100644 --- a/Mathlib/LinearAlgebra/Complex/Module.lean +++ b/Mathlib/LinearAlgebra/Complex/Module.lean @@ -52,8 +52,6 @@ element of a `StarModule` over `ℂ`. assert_not_exists NNReal namespace Complex -open ComplexConjugate - open scoped Complex.SMul variable {R : Type*} {S : Type*} @@ -138,7 +136,7 @@ theorem algHom_ext ⦃f g : ℂ →ₐ[ℝ] A⦄ (h : f I = g I) : f = g := by end -open Module Submodule +open Module /-- `ℂ` has a basis over `ℝ` given by `1` and `I`. -/ noncomputable def basisOneI : Basis (Fin 2) ℝ ℂ := diff --git a/Mathlib/LinearAlgebra/DFinsupp.lean b/Mathlib/LinearAlgebra/DFinsupp.lean index 1f226ab346280a..8da979ef341c17 100644 --- a/Mathlib/LinearAlgebra/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/DFinsupp.lean @@ -681,8 +681,6 @@ variable [AddCommMonoid M] [AddCommMonoid M₂] variable {σ₁₂ : R →+* R₂} variable [Module R M] [Module R₂ M₂] -open Submodule - section DFinsupp open DFinsupp diff --git a/Mathlib/LinearAlgebra/Dimension/Constructions.lean b/Mathlib/LinearAlgebra/Dimension/Constructions.lean index b3f30440e9fa01..af7f5fbc98e91d 100644 --- a/Mathlib/LinearAlgebra/Dimension/Constructions.lean +++ b/Mathlib/LinearAlgebra/Dimension/Constructions.lean @@ -41,7 +41,7 @@ universe u u' v v' u₁' w w' variable {R : Type u} {S : Type u'} {M : Type v} {M' : Type v'} {M₁ : Type v} variable {ι : Type w} {ι' : Type w'} {η : Type u₁'} {φ : η → Type*} -open Basis Cardinal DirectSum Function Module Set Submodule +open Cardinal DirectSum Function Module Set Submodule section Quotient @@ -274,8 +274,6 @@ variable [∀ i, AddCommMonoid (φ i)] [∀ i, Module R (φ i)] [∀ i, Module.F open Module.Free -open LinearMap - /-- The rank of a finite product of free modules is the sum of the ranks. -/ -- this result is not true without the freeness assumption @[simp] diff --git a/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean b/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean index 2e6f917a2ce024..52c5bede553ef6 100644 --- a/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean +++ b/Mathlib/LinearAlgebra/Dimension/DivisionRing.lean @@ -38,7 +38,7 @@ universe u₀ u v v' v'' u₁' w w' variable {K : Type u} {V V₁ V₂ V₃ : Type v} variable {ι : Type w} -open Cardinal Basis Submodule Function Set +open Cardinal Submodule Function Set section Module diff --git a/Mathlib/LinearAlgebra/Dimension/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Finite.lean index 8238f924711d41..95945b016c4ab5 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finite.lean @@ -30,7 +30,7 @@ variable [Module R M] attribute [local instance] nontrivial_of_invariantBasisNumber -open Basis Cardinal Function Module Set Submodule +open Cardinal Function Module Set Submodule /-- If every finite set of linearly independent vectors has cardinality at most `n`, then the same is true for arbitrary sets of linearly independent vectors. diff --git a/Mathlib/LinearAlgebra/Dimension/Free.lean b/Mathlib/LinearAlgebra/Dimension/Free.lean index 0f0b6dcf881b1e..a4c56d84a653b4 100644 --- a/Mathlib/LinearAlgebra/Dimension/Free.lean +++ b/Mathlib/LinearAlgebra/Dimension/Free.lean @@ -28,7 +28,7 @@ noncomputable section universe u v v' w -open Cardinal Basis Submodule Function Set Module +open Cardinal Function Set Module section Tower diff --git a/Mathlib/LinearAlgebra/Dimension/LinearMap.lean b/Mathlib/LinearAlgebra/Dimension/LinearMap.lean index 646f6b8ecfbe98..831f3cde3042eb 100644 --- a/Mathlib/LinearAlgebra/Dimension/LinearMap.lean +++ b/Mathlib/LinearAlgebra/Dimension/LinearMap.lean @@ -25,7 +25,7 @@ universe u v v' v'' variable {K : Type u} {V V₁ : Type v} {V' V'₁ : Type v'} {V'' : Type v''} -open Cardinal Basis Submodule Function Set +open Cardinal Submodule Function Set namespace LinearMap diff --git a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean index b3575ffeac2e2a..3552fd1a4e8234 100644 --- a/Mathlib/LinearAlgebra/Dimension/RankNullity.lean +++ b/Mathlib/LinearAlgebra/Dimension/RankNullity.lean @@ -199,7 +199,7 @@ theorem Submodule.exists_smul_notMem_of_rank_lt {N : Submodule R M} simp_rw [← N.mkQ_apply, ← map_smul, N.mkQ_apply, ne_eq, Submodule.Quotient.mk_eq_zero] at this exact this -open Cardinal Basis Submodule Function Set LinearMap +open Cardinal Submodule Function LinearMap theorem Submodule.rank_sup_add_rank_inf_eq (s t : Submodule R M) : Module.rank R (s ⊔ t : Submodule R M) + Module.rank R (s ⊓ t : Submodule R M) = diff --git a/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean b/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean index b7d9d5cc4ede9b..867ca62364d7ec 100644 --- a/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean +++ b/Mathlib/LinearAlgebra/DirectSum/Finsupp.lean @@ -40,7 +40,7 @@ noncomputable section open DirectSum TensorProduct -open Set LinearMap Submodule +open LinearMap section TensorProduct diff --git a/Mathlib/LinearAlgebra/Dual/Basis.lean b/Mathlib/LinearAlgebra/Dual/Basis.lean index 12aa75e01e406d..e43aa18d2337a6 100644 --- a/Mathlib/LinearAlgebra/Dual/Basis.lean +++ b/Mathlib/LinearAlgebra/Dual/Basis.lean @@ -34,7 +34,7 @@ This file concerns bases on dual vector spaces. @[expose] public section -open Module Dual Submodule LinearMap Function +open Module Submodule LinearMap Function noncomputable section @@ -230,7 +230,7 @@ end DualBases namespace Module.DualBases -open LinearMap Function +open LinearMap variable {R M ι : Type*} variable [CommSemiring R] [AddCommMonoid M] [Module R M] diff --git a/Mathlib/LinearAlgebra/Dual/Lemmas.lean b/Mathlib/LinearAlgebra/Dual/Lemmas.lean index 580046e9239464..bda1d04b15ece1 100644 --- a/Mathlib/LinearAlgebra/Dual/Lemmas.lean +++ b/Mathlib/LinearAlgebra/Dual/Lemmas.lean @@ -104,7 +104,7 @@ end Module section -open Module Module.Dual Submodule LinearMap Cardinal Function +open Module Module.Dual LinearMap Cardinal Function universe uR uM uK uV uι variable {R : Type uR} {M : Type uM} {K : Type uK} {V : Type uV} {ι : Type uι} diff --git a/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean b/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean index d02e0ae0cfd889..dfbd206a219d1e 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Semisimple.lean @@ -30,7 +30,7 @@ endomorphisms. public section -open Function Set +open Set namespace Module.End diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean index 8a8923035ff394..f08799b229649b 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Basic.lean @@ -44,7 +44,7 @@ Plenty of the results hold for general finitely generated modules (see universe u v v' w -open Cardinal Function IsNoetherian Module Submodule +open Cardinal Function Module Submodule variable {K : Type u} {V : Type v} @@ -186,7 +186,7 @@ end ZeroRank namespace Submodule -open IsNoetherian Module +open Module section DivisionRing @@ -625,8 +625,6 @@ end DivisionRing section SubalgebraRank -open Module - variable {F E : Type*} [Field F] [Ring E] [Algebra F E] /-- A `Subalgebra` is `FiniteDimensional` iff it is `FiniteDimensional` as a submodule. -/ diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean index 4905311320ee1e..bc8812db5be62b 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Lemmas.lean @@ -33,7 +33,7 @@ variable {K : Type u} {V : Type v} namespace Submodule -open IsNoetherian Module +open Module section DivisionRing diff --git a/Mathlib/LinearAlgebra/Finsupp/LSum.lean b/Mathlib/LinearAlgebra/Finsupp/LSum.lean index d910e7ca703258..c4d7d0ef503c30 100644 --- a/Mathlib/LinearAlgebra/Finsupp/LSum.lean +++ b/Mathlib/LinearAlgebra/Finsupp/LSum.lean @@ -30,7 +30,7 @@ function with finite support, module, linear algebra noncomputable section -open Set LinearMap Submodule +open LinearMap Submodule namespace Finsupp diff --git a/Mathlib/LinearAlgebra/Finsupp/SumProd.lean b/Mathlib/LinearAlgebra/Finsupp/SumProd.lean index 8aad66182cf555..308a1ddd22f766 100644 --- a/Mathlib/LinearAlgebra/Finsupp/SumProd.lean +++ b/Mathlib/LinearAlgebra/Finsupp/SumProd.lean @@ -24,7 +24,7 @@ function with finite support, module, linear algebra noncomputable section -open Set LinearMap +open LinearMap namespace Finsupp diff --git a/Mathlib/LinearAlgebra/FreeModule/Basic.lean b/Mathlib/LinearAlgebra/FreeModule/Basic.lean index 5bfdafe4fd012b..b3b8535899616e 100644 --- a/Mathlib/LinearAlgebra/FreeModule/Basic.lean +++ b/Mathlib/LinearAlgebra/FreeModule/Basic.lean @@ -175,8 +175,6 @@ end Free namespace Basis -open Finset - variable {S : Type*} [CommRing R] [Ring S] [Algebra R S] set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/LinearAlgebra/Goursat.lean b/Mathlib/LinearAlgebra/Goursat.lean index a9760292dab31a..5eded4413b4dea 100644 --- a/Mathlib/LinearAlgebra/Goursat.lean +++ b/Mathlib/LinearAlgebra/Goursat.lean @@ -24,7 +24,7 @@ respectively. @[expose] public section -open Function Set LinearMap +open Function LinearMap namespace Submodule variable {R M N : Type*} [Ring R] [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N] diff --git a/Mathlib/LinearAlgebra/Matrix/ProjectiveSpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/ProjectiveSpecialLinearGroup.lean index 5dde844d6ebd13..d4ea5c6b122ada 100644 --- a/Mathlib/LinearAlgebra/Matrix/ProjectiveSpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/ProjectiveSpecialLinearGroup.lean @@ -23,7 +23,7 @@ namespace Matrix universe u v -open Matrix LinearMap +open Matrix open scoped MatrixGroups diff --git a/Mathlib/LinearAlgebra/Multilinear/Curry.lean b/Mathlib/LinearAlgebra/Multilinear/Curry.lean index 59033dde003028..fc2f58c37362a5 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Curry.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Curry.lean @@ -25,7 +25,7 @@ in linear functions), called respectively `multilinearCurryLeftEquiv` and @[expose] public section -open Fin Function Finset Set +open Fin Function Finset universe uR uS uι uι' v v' v₁ v₂ v₃ diff --git a/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean b/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean index e9b880da072aa9..4fd092eca05780 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct/Basis.lean @@ -20,7 +20,7 @@ section PiTensorProduct attribute [local ext] PiTensorProduct.ext -open LinearMap PiTensorProduct Module TensorProduct +open PiTensorProduct Module TensorProduct variable {ι R : Type*} {M : ι → Type*} {κ : ι → Type*} [CommSemiring R] [∀ i, AddCommMonoid (M i)] [∀ i, Module R (M i)] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean b/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean index c1fad5dd199c43..e9f107fa34a7a5 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/AlgClosed.lean @@ -23,8 +23,6 @@ public section open QuadraticMap namespace QuadraticForm -open Finset - variable {ι : Type*} [Fintype ι] {K : Type*} [Field K] [IsAlgClosed K] /-- The isometry between a weighted sum of squares on an algebraically closed field and the diff --git a/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean b/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean index b846483cb03b54..5eeaddb1cdc736 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean @@ -131,8 +131,6 @@ end QuadraticModuleCat namespace CategoryTheory.Iso -open QuadraticForm - variable {X Y Z : QuadraticModuleCat.{v} R} /-- Build a `QuadraticForm.IsometryEquiv` from an isomorphism in the category diff --git a/Mathlib/LinearAlgebra/Quotient/Card.lean b/Mathlib/LinearAlgebra/Quotient/Card.lean index a414799a4296d3..92512b1c6499fe 100644 --- a/Mathlib/LinearAlgebra/Quotient/Card.lean +++ b/Mathlib/LinearAlgebra/Quotient/Card.lean @@ -15,8 +15,6 @@ public section namespace Submodule -open LinearMap QuotientAddGroup - variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M] theorem card_eq_card_quotient_mul_card (S : Submodule R M) : diff --git a/Mathlib/LinearAlgebra/RootSystem/Chain.lean b/Mathlib/LinearAlgebra/RootSystem/Chain.lean index a9d2b86d8a5bdd..2f03ec767f1369 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Chain.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Chain.lean @@ -31,7 +31,7 @@ length, `p + q` is at most 3. noncomputable section -open FaithfulSMul Function Set Submodule +open FaithfulSMul Function Set variable {ι R M N : Type*} [Finite ι] [CommRing R] [CharZero R] [IsDomain R] [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N] diff --git a/Mathlib/LinearAlgebra/RootSystem/Hom.lean b/Mathlib/LinearAlgebra/RootSystem/Hom.lean index 8b3cac1a050cf5..901fa2927b4fd2 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Hom.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Hom.lean @@ -50,7 +50,7 @@ given in SGA III Exp. 21 Section 6. @[expose] public section -open Set Function +open Function noncomputable section diff --git a/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean b/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean index 0360126e568c25..1d46e0372560b6 100644 --- a/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean +++ b/Mathlib/LinearAlgebra/RootSystem/RootPairingCat.lean @@ -30,7 +30,7 @@ This is mostly copied from `ModuleCat`. public section -open Set Function CategoryTheory +open CategoryTheory noncomputable section diff --git a/Mathlib/LinearAlgebra/SModEq/Pointwise.lean b/Mathlib/LinearAlgebra/SModEq/Pointwise.lean index bb765cb39944cf..3d218265a9c885 100644 --- a/Mathlib/LinearAlgebra/SModEq/Pointwise.lean +++ b/Mathlib/LinearAlgebra/SModEq/Pointwise.lean @@ -19,8 +19,6 @@ public section open Submodule -open Polynomial - variable {R : Type*} [Ring R] {I : Ideal R} variable {M : Type*} [AddCommGroup M] [Module R M] {U : Submodule R M} variable {x y : M} diff --git a/Mathlib/LinearAlgebra/TensorProduct/Basis.lean b/Mathlib/LinearAlgebra/TensorProduct/Basis.lean index d026a04c23f79c..0fa2bd75c3d290 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Basis.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Basis.lean @@ -22,7 +22,7 @@ and shows that the tensor product of free modules is again free. noncomputable section -open LinearMap Module Set Submodule +open LinearMap Module open scoped TensorProduct diff --git a/Mathlib/LinearAlgebra/TensorProduct/Vanishing.lean b/Mathlib/LinearAlgebra/TensorProduct/Vanishing.lean index bfc7d8ee384e8b..c0ce640eb4dcf7 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Vanishing.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Vanishing.lean @@ -62,7 +62,7 @@ variable (R : Type*) [CommRing R] variable {M : Type*} [AddCommGroup M] [Module R M] variable {N : Type*} [AddCommGroup N] [Module R N] -open DirectSum LinearMap Function Submodule Finsupp +open LinearMap Function Submodule Finsupp namespace TensorProduct diff --git a/Mathlib/LinearAlgebra/Transvection/Basic.lean b/Mathlib/LinearAlgebra/Transvection/Basic.lean index 6fa4b3ef83fdf3..7a0dea89b9f18f 100644 --- a/Mathlib/LinearAlgebra/Transvection/Basic.lean +++ b/Mathlib/LinearAlgebra/Transvection/Basic.lean @@ -61,7 +61,7 @@ def transvection (f : Dual R V) (v : V) : V →ₗ[R] V where namespace transvection -open Submodule LinearMap +open LinearMap theorem apply (f : Dual R V) (v x : V) : transvection f v x = x + f x • v := @@ -547,7 +547,7 @@ section determinant namespace LinearMap.transvection -open Polynomial Module +open Module open scoped TensorProduct diff --git a/Mathlib/Logic/Denumerable.lean b/Mathlib/Logic/Denumerable.lean index d581bf2173465a..40c3b3ba71a210 100644 --- a/Mathlib/Logic/Denumerable.lean +++ b/Mathlib/Logic/Denumerable.lean @@ -179,7 +179,7 @@ end Denumerable namespace Nat.Subtype -open Function Encodable +open Function /-! ### Subsets of `ℕ` -/ diff --git a/Mathlib/Logic/Encodable/Basic.lean b/Mathlib/Logic/Encodable/Basic.lean index 2f4d7626c1b6c6..08bef2a057817b 100644 --- a/Mathlib/Logic/Encodable/Basic.lean +++ b/Mathlib/Logic/Encodable/Basic.lean @@ -44,7 +44,7 @@ assert_not_exists Monoid -- We want the theorems in this file to be constructive. set_option linter.unusedDecidableInType false -open Option List Nat Function +open Option Nat Function /-- Constructively countable type. Made from an explicit injection `encode : α → ℕ` and a partial inverse `decode : ℕ → Option α`. Note that finite types *are* countable. See `Denumerable` if you @@ -344,7 +344,7 @@ end Prod section Subtype -open Subtype Decidable +open Subtype variable {P : α → Prop} [encA : Encodable α] [decP : DecidablePred P] diff --git a/Mathlib/Logic/IsEmpty/Defs.lean b/Mathlib/Logic/IsEmpty/Defs.lean index 1eedb5f3cee50a..b776219b4ed78a 100644 --- a/Mathlib/Logic/IsEmpty/Defs.lean +++ b/Mathlib/Logic/IsEmpty/Defs.lean @@ -103,8 +103,6 @@ theorem isEmpty_iff : IsEmpty α ↔ α → False := namespace IsEmpty -open Function - /-- Eliminate out of a type that `IsEmpty` (using projection notation). -/ @[elab_as_elim] protected def elim (_ : IsEmpty α) {p : α → Sort v} (a : α) : p a := diff --git a/Mathlib/Logic/Unique.lean b/Mathlib/Logic/Unique.lean index dae1020bde6485..29de0a384a284c 100644 --- a/Mathlib/Logic/Unique.lean +++ b/Mathlib/Logic/Unique.lean @@ -99,8 +99,6 @@ instance : Unique True := namespace Unique -open Function - section variable {α : Sort*} [Unique α] diff --git a/Mathlib/MeasureTheory/Constructions/Polish/EmbeddingReal.lean b/Mathlib/MeasureTheory/Constructions/Polish/EmbeddingReal.lean index 167836fbd0800b..6c4544dd77e7a6 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/EmbeddingReal.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/EmbeddingReal.lean @@ -14,7 +14,7 @@ public import Mathlib.MeasureTheory.Constructions.Polish.Basic @[expose] public section -open Set Function PolishSpace PiNat TopologicalSpace Bornology Metric Filter Topology MeasureTheory +open Set Function PolishSpace TopologicalSpace Topology MeasureTheory namespace MeasureTheory variable (α : Type*) [MeasurableSpace α] [StandardBorelSpace α] diff --git a/Mathlib/MeasureTheory/Constructions/SimpleGraph.lean b/Mathlib/MeasureTheory/Constructions/SimpleGraph.lean index 3f44ad4b7e5112..d6683dbc92910a 100644 --- a/Mathlib/MeasureTheory/Constructions/SimpleGraph.lean +++ b/Mathlib/MeasureTheory/Constructions/SimpleGraph.lean @@ -17,7 +17,6 @@ In this file, we pull back the sigma-algebra on `V → V → Prop` to a sigma-al public section -open MeasureTheory open scoped Finset namespace SimpleGraph diff --git a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean index c7b88a5764cad5..38041655206d9b 100644 --- a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean +++ b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean @@ -32,7 +32,7 @@ form of Lebesgue's density theorem. noncomputable section -open Set Filter Metric MeasureTheory TopologicalSpace +open Set Filter Metric MeasureTheory open scoped NNReal Topology diff --git a/Mathlib/MeasureTheory/Function/AEEqFun.lean b/Mathlib/MeasureTheory/Function/AEEqFun.lean index 546c7a7d4bd733..df291d93b22402 100644 --- a/Mathlib/MeasureTheory/Function/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/AEEqFun.lean @@ -77,7 +77,7 @@ assert_not_exists InnerProductSpace noncomputable section -open Topology Set Filter TopologicalSpace ENNReal EMetric MeasureTheory Function +open Topology Set Filter TopologicalSpace ENNReal MeasureTheory Function variable {α β γ δ : Type*} [MeasurableSpace α] {μ ν : Measure α} diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean index a82501d2a0f100..73301cd7a26574 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean @@ -35,7 +35,7 @@ However, some lemmas also use `𝕜 : RCLike`: @[expose] public section -open TopologicalSpace Filter ContinuousLinearMap +open Filter ContinuousLinearMap open scoped ENNReal Topology MeasureTheory diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean index 8bcb431f846b69..d25bfa4aab65e2 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Indicator.lean @@ -28,7 +28,7 @@ public section noncomputable section -open TopologicalSpace MeasureTheory.Lp Filter ContinuousLinearMap +open MeasureTheory.Lp Filter open scoped NNReal ENNReal Topology MeasureTheory diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/PullOut.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/PullOut.lean index 5ad7fa290a0d1d..a9749dbee01c2e 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/PullOut.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/PullOut.lean @@ -37,7 +37,7 @@ conditional expectation, pull-out, bilinear map public section -open TopologicalSpace MeasureTheory.Lp Filter ContinuousLinearMap +open MeasureTheory.Lp Filter ContinuousLinearMap open scoped NNReal ENNReal Topology MeasureTheory diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean index 58c792403511d1..c7eb18aabfaae7 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Real.lean @@ -32,7 +32,7 @@ public section noncomputable section -open TopologicalSpace MeasureTheory.Lp Filter ContinuousLinearMap +open TopologicalSpace MeasureTheory.Lp Filter open scoped NNReal ENNReal Topology MeasureTheory diff --git a/Mathlib/MeasureTheory/Function/Egorov.lean b/Mathlib/MeasureTheory/Function/Egorov.lean index c082381b5d8e03..af373cc2456556 100644 --- a/Mathlib/MeasureTheory/Function/Egorov.lean +++ b/Mathlib/MeasureTheory/Function/Egorov.lean @@ -27,7 +27,7 @@ convergence in measure. noncomputable section -open MeasureTheory NNReal ENNReal Topology +open MeasureTheory ENNReal Topology namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/Function/Holder.lean b/Mathlib/MeasureTheory/Function/Holder.lean index 28a09ce608dfff..dab687c3067ecd 100644 --- a/Mathlib/MeasureTheory/Function/Holder.lean +++ b/Mathlib/MeasureTheory/Function/Holder.lean @@ -26,7 +26,7 @@ is the natural map `Lp (StrongDual 𝕜 E) p μ →L[𝕜] StrongDual 𝕜 (Lp E @[expose] public section -open ENNReal MeasureTheory Lp +open ENNReal MeasureTheory open scoped NNReal noncomputable section diff --git a/Mathlib/MeasureTheory/Function/JacobianOneDim.lean b/Mathlib/MeasureTheory/Function/JacobianOneDim.lean index f4c98d5cea2c7a..dcd70216dd5680 100644 --- a/Mathlib/MeasureTheory/Function/JacobianOneDim.lean +++ b/Mathlib/MeasureTheory/Function/JacobianOneDim.lean @@ -27,7 +27,7 @@ the interval integral and with stronger requirements on the integrand. public section -open MeasureTheory MeasureTheory.Measure Metric Filter Set Module Asymptotics +open MeasureTheory MeasureTheory.Measure Filter Set Module TopologicalSpace ContinuousLinearMap open scoped NNReal ENNReal Topology Pointwise diff --git a/Mathlib/MeasureTheory/Function/L1Space/AEEqFun.lean b/Mathlib/MeasureTheory/Function/L1Space/AEEqFun.lean index ab01c02274e12d..87415d414c14f2 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/AEEqFun.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/AEEqFun.lean @@ -31,7 +31,7 @@ function space, l1 noncomputable section -open EMetric ENNReal Filter MeasureTheory NNReal Set +open ENNReal Filter MeasureTheory Set variable {α β ε ε' : Type*} {m : MeasurableSpace α} {μ ν : Measure α} variable [NormedAddCommGroup β] [TopologicalSpace ε] [ContinuousENorm ε] diff --git a/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean b/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean index 4f3db5cb2e2eaf..5baf1b7d3c4075 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/HasFiniteIntegral.lean @@ -34,7 +34,7 @@ noncomputable section open Topology ENNReal MeasureTheory NNReal -open Set Filter TopologicalSpace ENNReal EMetric MeasureTheory +open Set Filter TopologicalSpace ENNReal MeasureTheory variable {α β γ ε ε' ε'' : Type*} {m : MeasurableSpace α} {μ ν : Measure α} variable [NormedAddCommGroup β] [NormedAddCommGroup γ] [ENorm ε] [ENorm ε'] diff --git a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean index 4420b6b246195e..57e51c1d5adcc0 100644 --- a/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean +++ b/Mathlib/MeasureTheory/Function/L1Space/Integrable.lean @@ -41,7 +41,7 @@ integrable noncomputable section -open EMetric ENNReal Filter MeasureTheory NNReal Set TopologicalSpace +open ENNReal Filter MeasureTheory NNReal Set TopologicalSpace open scoped Topology diff --git a/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean b/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean index 703f87f29b7afa..8f34ac3c33ba73 100644 --- a/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean +++ b/Mathlib/MeasureTheory/Function/SpecialFunctions/RCLike.lean @@ -18,8 +18,6 @@ public section noncomputable section -open NNReal ENNReal - namespace RCLike variable {𝕜 : Type*} [RCLike 𝕜] diff --git a/Mathlib/MeasureTheory/Group/AddCircle.lean b/Mathlib/MeasureTheory/Group/AddCircle.lean index a15d9fa162de53..367522edafbde8 100644 --- a/Mathlib/MeasureTheory/Group/AddCircle.lean +++ b/Mathlib/MeasureTheory/Group/AddCircle.lean @@ -25,7 +25,7 @@ The file is a place to collect measure-theoretic results about the additive circ public section -open Set Function Filter MeasureTheory MeasureTheory.Measure Metric +open Set Filter MeasureTheory MeasureTheory.Measure Metric open scoped Finset MeasureTheory Pointwise Topology ENNReal diff --git a/Mathlib/MeasureTheory/Group/FoelnerFilter.lean b/Mathlib/MeasureTheory/Group/FoelnerFilter.lean index 2586b9b844e4c1..e4765815973657 100644 --- a/Mathlib/MeasureTheory/Group/FoelnerFilter.lean +++ b/Mathlib/MeasureTheory/Group/FoelnerFilter.lean @@ -61,7 +61,7 @@ Foelner, Følner filter, amenability, amenable group @[expose] public section -open MeasureTheory Filter Set Tendsto +open MeasureTheory Filter Set open scoped ENNReal Pointwise symmDiff Topology Filter variable {G X : Type*} [MeasurableSpace X] {μ : Measure X} [Group G] [MulAction G X] diff --git a/Mathlib/MeasureTheory/Integral/Average.lean b/Mathlib/MeasureTheory/Integral/Average.lean index d4fedf0a71b88e..c8ad2d79912881 100644 --- a/Mathlib/MeasureTheory/Integral/Average.lean +++ b/Mathlib/MeasureTheory/Integral/Average.lean @@ -39,7 +39,7 @@ integral, center mass, average value, set average @[expose] public section -open ENNReal MeasureTheory MeasureTheory.Measure Metric Set Filter TopologicalSpace Function +open ENNReal MeasureTheory MeasureTheory.Measure Set Filter TopologicalSpace Function open scoped Topology ENNReal Convex diff --git a/Mathlib/MeasureTheory/Integral/CircleTransform.lean b/Mathlib/MeasureTheory/Integral/CircleTransform.lean index 72e288c0158436..8e143c50a68d03 100644 --- a/Mathlib/MeasureTheory/Integral/CircleTransform.lean +++ b/Mathlib/MeasureTheory/Integral/CircleTransform.lean @@ -22,7 +22,7 @@ is holomorphic. @[expose] public section -open Set MeasureTheory Metric Filter Function +open Set MeasureTheory Metric Function open scoped Interval Real diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/ContDiff.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/ContDiff.lean index 6bdc0be048e1cd..085ce1357951d1 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/ContDiff.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/ContDiff.lean @@ -18,7 +18,7 @@ public section noncomputable section -open MeasureTheory Set Filter Function Asymptotics +open MeasureTheory Set Filter Function open scoped Topology ENNReal Interval NNReal diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean index f826953a35631b..a0d75699b35578 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral/DistLEIntegral.lean @@ -22,7 +22,7 @@ the displacement (`dist (f a) (f b)`) is at most the integral of `‖deriv f‖` public section -open Filter Set MeasureTheory Measure Metric +open Filter Set MeasureTheory Metric open scoped Topology variable {E F : Type*} diff --git a/Mathlib/MeasureTheory/Integral/Marginal.lean b/Mathlib/MeasureTheory/Integral/Marginal.lean index 5787f9f1a46188..91419ccc2207e9 100644 --- a/Mathlib/MeasureTheory/Integral/Marginal.lean +++ b/Mathlib/MeasureTheory/Integral/Marginal.lean @@ -59,7 +59,7 @@ since there is no well-behaved measure on the domain of `f`. open scoped ENNReal -open Set Function Equiv Finset +open Function Equiv Finset noncomputable section diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Card.lean b/Mathlib/MeasureTheory/MeasurableSpace/Card.lean index 9fa88ef9201adb..d2e4689badbfd9 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Card.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Card.lean @@ -34,7 +34,7 @@ universe u v variable {α : Type u} -open Cardinal Ordinal Set MeasureTheory +open Cardinal Ordinal Set namespace MeasurableSpace diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index e36f013e5e9ee8..6028d57954b0bd 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -41,7 +41,7 @@ measurable space, σ-algebra, measurable function assert_not_exists Covariant MonoidWithZero -open Set Encodable Function Equiv +open Set Function variable {α β γ δ δ' : Type*} {ι : Sort*} {s t u : Set α} diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 3f52e91e301cfa..be97938b6c7f54 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -40,7 +40,7 @@ measurable equivalence, measurable embedding @[expose] public section -open Set Function Equiv MeasureTheory +open Set Function Equiv universe uι diff --git a/Mathlib/MeasureTheory/MeasurableSpace/PreorderRestrict.lean b/Mathlib/MeasureTheory/MeasurableSpace/PreorderRestrict.lean index c5085dfeeaf82d..245776759ccb94 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/PreorderRestrict.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/PreorderRestrict.lean @@ -17,8 +17,6 @@ measurable. public section -open MeasureTheory - namespace Preorder variable {α : Type*} [Preorder α] {X : α → Type*} [∀ a, MeasurableSpace (X a)] diff --git a/Mathlib/MeasureTheory/Measure/AbsolutelyContinuous.lean b/Mathlib/MeasureTheory/Measure/AbsolutelyContinuous.lean index cf968bc328dda1..11bad6155adf34 100644 --- a/Mathlib/MeasureTheory/Measure/AbsolutelyContinuous.lean +++ b/Mathlib/MeasureTheory/Measure/AbsolutelyContinuous.lean @@ -197,7 +197,7 @@ end MeasureTheory namespace MeasurableEmbedding -open MeasureTheory Measure +open MeasureTheory variable {m0 : MeasurableSpace α} {m1 : MeasurableSpace β} {f : α → β} {μ ν : Measure α} diff --git a/Mathlib/MeasureTheory/Measure/DiracProba.lean b/Mathlib/MeasureTheory/Measure/DiracProba.lean index 05edb5e0a45be0..398dae49c1cd68 100644 --- a/Mathlib/MeasureTheory/Measure/DiracProba.lean +++ b/Mathlib/MeasureTheory/Measure/DiracProba.lean @@ -25,7 +25,7 @@ probability measure, Dirac delta, embedding @[expose] public section -open Topology Metric Filter Set ENNReal NNReal BoundedContinuousFunction +open Topology Filter Set ENNReal NNReal BoundedContinuousFunction open scoped Topology ENNReal NNReal BoundedContinuousFunction diff --git a/Mathlib/MeasureTheory/Measure/Doubling.lean b/Mathlib/MeasureTheory/Measure/Doubling.lean index df6db88bb11394..faca1f8040639e 100644 --- a/Mathlib/MeasureTheory/Measure/Doubling.lean +++ b/Mathlib/MeasureTheory/Measure/Doubling.lean @@ -30,7 +30,7 @@ assert_not_exists Real.instPow noncomputable section -open Set Filter Metric MeasureTheory TopologicalSpace ENNReal NNReal Topology +open Set Filter Metric MeasureTheory ENNReal NNReal Topology /-- A measure `μ` is said to be a uniformly locally doubling measure if there exists a constant `C` such that for all sufficiently small radii `ε`, and for any centre, the measure of a ball of radius diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean index 3f849138663f48..cbd28503b3e219 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasurePi.lean @@ -30,7 +30,7 @@ continuously on the factors. @[expose] public section -open MeasureTheory Topology Metric Filter Set ENNReal NNReal +open MeasureTheory Metric Filter Set ENNReal NNReal open scoped Topology ENNReal NNReal BoundedContinuousFunction diff --git a/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean b/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean index a34f6dda00349d..cd7c32276d72d9 100644 --- a/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean +++ b/Mathlib/MeasureTheory/Measure/FiniteMeasureProd.lean @@ -30,7 +30,7 @@ continuously on the factors. @[expose] public section -open MeasureTheory Topology Metric Filter Set ENNReal NNReal +open MeasureTheory Metric Filter Set ENNReal NNReal open scoped Topology ENNReal NNReal BoundedContinuousFunction diff --git a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean index caaaa7c755bcca..d08f42a14d897d 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Unique.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Unique.lean @@ -66,7 +66,7 @@ the measures but discarding the assumption that they are finite on compact sets. @[expose] public section -open Filter Set TopologicalSpace Function MeasureTheory Measure +open Filter Set TopologicalSpace Function MeasureTheory open scoped Uniformity Topology ENNReal Pointwise NNReal namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean index 2ef5d93cf2b87b..24acba94dd117c 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean @@ -39,7 +39,7 @@ convergence in distribution for random variables behave somewhat well in spaces @[expose] public section -open BoundedContinuousFunction MeasureTheory Topology Metric Filter Set ENNReal NNReal +open BoundedContinuousFunction MeasureTheory Filter Set ENNReal NNReal open scoped Topology ENNReal NNReal BoundedContinuousFunction section auxiliary diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean index 3fd4ab3dd1c2ac..cae589ba7a2b6d 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosedProd.lean @@ -55,7 +55,7 @@ bounded continuous function, product measure public section -open BoundedContinuousFunction MeasureTheory Topology Filter Set ENNReal NNReal MeasurableSpace +open BoundedContinuousFunction MeasureTheory Filter Set ENNReal NNReal MeasurableSpace open scoped Topology ENNReal NNReal namespace Measure diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 65f530816868bc..345dfa1668316f 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -114,7 +114,7 @@ Hausdorff measure, measure, metric measure open scoped NNReal ENNReal Topology -open Metric EMetric Set Function Filter Encodable Module TopologicalSpace +open Metric Set Function Filter Encodable Module TopologicalSpace noncomputable section @@ -716,8 +716,6 @@ end HolderOnWith namespace LipschitzOnWith -open Submodule - variable {K : ℝ≥0} {f : X → Y} {s : Set X} /-- If `f : X → Y` is `K`-Lipschitz on `s`, then `μH[d] (f '' s) ≤ K ^ d * μH[d] s`. -/ diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean b/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean index 6218e85fbdea7e..e0bfa1476cd9a7 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpaceDef.lean @@ -59,7 +59,7 @@ assert_not_exists Module.Basis noncomputable section -open Set Function MeasurableSpace Topology Filter ENNReal NNReal +open Set Function MeasurableSpace Filter ENNReal open Filter hiding map diff --git a/Mathlib/MeasureTheory/Measure/Prod.lean b/Mathlib/MeasureTheory/Measure/Prod.lean index 25c0a0fb7a00de..794adb30a94b71 100644 --- a/Mathlib/MeasureTheory/Measure/Prod.lean +++ b/Mathlib/MeasureTheory/Measure/Prod.lean @@ -57,7 +57,7 @@ product measure, Tonelli's theorem, Fubini-Tonelli theorem noncomputable section -open Topology ENNReal MeasureTheory Set Function Real ENNReal MeasurableSpace MeasureTheory.Measure +open ENNReal MeasureTheory Set Function Real ENNReal MeasurableSpace MeasureTheory.Measure open TopologicalSpace hiding generateFrom @@ -851,8 +851,6 @@ lemma prod_smul_left {μ : Measure α} {R : Type*} [SMul R ℝ≥0∞] [IsScalar end Measure -open Measure - namespace MeasurePreserving variable {δ : Type*} [MeasurableSpace δ] {μa : Measure α} {μb : Measure β} {μc : Measure γ} diff --git a/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean b/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean index e982e256a5225f..9be48467d35191 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Caratheodory.lean @@ -34,7 +34,7 @@ Carathéodory-measurable, Carathéodory's criterion noncomputable section -open Set Function Filter +open Set Function open scoped NNReal Topology ENNReal namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean b/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean index 18d825d93554b2..6d1c2bd96e9c66 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean @@ -42,7 +42,7 @@ assert_not_exists Module.Basis noncomputable section -open Set Function Filter +open Set Function open scoped NNReal Topology ENNReal namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/OuterMeasure/Operations.lean b/Mathlib/MeasureTheory/OuterMeasure/Operations.lean index e928f1711c0649..ca4d89fda4cb12 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Operations.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Operations.lean @@ -30,7 +30,7 @@ outer measure noncomputable section -open Set Function Filter +open Set Function open scoped NNReal Topology ENNReal namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/VectorMeasure/Prod.lean b/Mathlib/MeasureTheory/VectorMeasure/Prod.lean index 04f1e98f87acea..a404a41a1a8c5e 100644 --- a/Mathlib/MeasureTheory/VectorMeasure/Prod.lean +++ b/Mathlib/MeasureTheory/VectorMeasure/Prod.lean @@ -21,7 +21,7 @@ The API is modelled on the one for the product of positive measures. public section -open Filter Function MeasureTheory RCLike Set TopologicalSpace Topology +open Filter Function MeasureTheory Set TopologicalSpace open scoped ENNReal NNReal Finset variable {ι X Y E F G H I J : Type*} {mX : MeasurableSpace X} {mY : MeasurableSpace Y} diff --git a/Mathlib/ModelTheory/Bundled.lean b/Mathlib/ModelTheory/Bundled.lean index cb1d26a19bba85..327db752eefbeb 100644 --- a/Mathlib/ModelTheory/Bundled.lean +++ b/Mathlib/ModelTheory/Bundled.lean @@ -34,7 +34,7 @@ protected instance CategoryTheory.Bundled.structure {L : FirstOrder.Language.{u, (M : CategoryTheory.Bundled.{w} L.Structure) : L.Structure M := M.str -open FirstOrder Cardinal +open FirstOrder namespace Equiv diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index b781cb1268d3aa..a46e02d2a0032c 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -48,7 +48,7 @@ variable {α : Type u'} open FirstOrder Cardinal -open Computability List Structure Fin +open Computability List Fin namespace Term diff --git a/Mathlib/ModelTheory/Equivalence.lean b/Mathlib/ModelTheory/Equivalence.lean index c06e80f564f593..c65773802787a0 100644 --- a/Mathlib/ModelTheory/Equivalence.lean +++ b/Mathlib/ModelTheory/Equivalence.lean @@ -24,8 +24,6 @@ public import Mathlib.ModelTheory.Satisfiability universe u v w w' -open Cardinal CategoryTheory - open FirstOrder namespace FirstOrder diff --git a/Mathlib/ModelTheory/Types.lean b/Mathlib/ModelTheory/Types.lean index 8f9efd01ea82d4..79d58d84141ef9 100644 --- a/Mathlib/ModelTheory/Types.lean +++ b/Mathlib/ModelTheory/Types.lean @@ -44,7 +44,7 @@ This file defines the space of complete types over a first-order theory. universe u v w w' -open Cardinal Set FirstOrder +open Set FirstOrder namespace FirstOrder diff --git a/Mathlib/NumberTheory/AbelSummation.lean b/Mathlib/NumberTheory/AbelSummation.lean index 95478f167ffeb2..02f221d3a90518 100644 --- a/Mathlib/NumberTheory/AbelSummation.lean +++ b/Mathlib/NumberTheory/AbelSummation.lean @@ -263,7 +263,7 @@ end specialversions section limit -open Filter Topology abelSummationProof intervalIntegral +open Filter Topology intervalIntegral theorem locallyIntegrableOn_mul_sum_Icc {m : ℕ} (ha : 0 ≤ a) {g : ℝ → 𝕜} (hg : LocallyIntegrableOn g (Set.Ici a)) : @@ -323,7 +323,7 @@ end limit section summable -open Filter abelSummationProof +open Filter private theorem summable_mul_of_bigO_atTop_aux (m : ℕ) (h_bdd : (fun n : ℕ ↦ ‖f n‖ * ∑ k ∈ Icc 0 n, ‖c k‖) =O[atTop] fun _ ↦ (1 : ℝ)) diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean index 1fef5111e19ad2..550d824b0b9747 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Misc.lean @@ -451,7 +451,7 @@ theorem sum_divisors_mul {m n : ℕ} (hmn : m.Coprime n) : end Nat.Coprime namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for `ArithmeticFunction.sigma`. -/ @[positivity ArithmeticFunction.sigma _ _] diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean b/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean index 0dbbe7b2aa95fb..05f76c89adb093 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Moebius.lean @@ -152,8 +152,6 @@ theorem IsMultiplicative.prodPrimeFactors_one_sub_of_squarefree [CommRing R] · rw [(isMultiplicative_moebius.intCast.pmul hf).prodPrimeFactors_one_add_of_squarefree hn] simp_rw [pmul_apply, intCoe_apply] -open UniqueFactorizationMonoid - @[simp] theorem moebius_mul_coe_zeta : (μ * ζ : ArithmeticFunction ℤ) = 1 := by ext n diff --git a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean index 40f1276743a9d8..3f3a3d09b20960 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction/Zeta.lean @@ -223,7 +223,7 @@ end IsMultiplicative end ArithmeticFunction namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for `ArithmeticFunction.zeta`. -/ @[positivity ArithmeticFunction.zeta _] diff --git a/Mathlib/NumberTheory/Chebyshev.lean b/Mathlib/NumberTheory/Chebyshev.lean index 6ffaf1bc3538b5..24a6e81ef8e703 100644 --- a/Mathlib/NumberTheory/Chebyshev.lean +++ b/Mathlib/NumberTheory/Chebyshev.lean @@ -859,7 +859,7 @@ end Chebyshev namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: the first Chebyshev function is nonnegative. -/ @[positivity Chebyshev.theta _] diff --git a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean index 6bc84b0f6e3d1e..52b1343a0de67c 100644 --- a/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean +++ b/Mathlib/NumberTheory/EulerProduct/DirichletLSeries.lean @@ -209,7 +209,7 @@ lemma DirichletCharacter.LSeries_changeLevel {M N : ℕ} [NeZero N] section LogDirichlet open Real hiding log exp_nat_mul exp_add -open ArithmeticFunction Primes Summable +open ArithmeticFunction Summable variable {N : ℕ} (χ : DirichletCharacter ℂ N) {s : ℂ} diff --git a/Mathlib/NumberTheory/FLT/MasonStothers.lean b/Mathlib/NumberTheory/FLT/MasonStothers.lean index bce9515a2ceef1..befec2e870a690 100644 --- a/Mathlib/NumberTheory/FLT/MasonStothers.lean +++ b/Mathlib/NumberTheory/FLT/MasonStothers.lean @@ -22,7 +22,7 @@ but slightly different. public section -open Polynomial UniqueFactorizationMonoid UniqueFactorizationDomain EuclideanDomain +open Polynomial UniqueFactorizationMonoid EuclideanDomain variable {k : Type*} [Field k] [DecidableEq k] diff --git a/Mathlib/NumberTheory/KummerDedekind.lean b/Mathlib/NumberTheory/KummerDedekind.lean index a224752c352e88..ad0645d74b9e41 100644 --- a/Mathlib/NumberTheory/KummerDedekind.lean +++ b/Mathlib/NumberTheory/KummerDedekind.lean @@ -61,7 +61,7 @@ kummer, dedekind, kummer dedekind, dedekind-kummer, dedekind kummer variable {R : Type*} {S : Type*} [CommRing R] [CommRing S] [Algebra R S] {x : S} {I : Ideal R} -open Ideal Polynomial DoubleQuot UniqueFactorizationMonoid Algebra RingHom +open Ideal Polynomial UniqueFactorizationMonoid Algebra RingHom namespace KummerDedekind diff --git a/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean b/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean index 9ccc38f52d669a..89c72580697983 100644 --- a/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean +++ b/Mathlib/NumberTheory/LSeries/DirichletContinuation.lean @@ -42,7 +42,7 @@ All definitions and theorems are in the `DirichletCharacter` namespace. @[expose] public section -open HurwitzZeta Complex Finset ZMod Filter +open Complex Finset ZMod Filter open scoped Real Topology diff --git a/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean b/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean index 1d6b46e9c172a1..a23c30ad74e718 100644 --- a/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean @@ -15,7 +15,7 @@ a Dirichlet series". public section -open Filter Topology Asymptotics Real Set MeasureTheory +open Real Set MeasureTheory open Complex variable {ι : Type*} [Countable ι] diff --git a/Mathlib/NumberTheory/Modular.lean b/Mathlib/NumberTheory/Modular.lean index caf3b202dfb850..4a7e71d4dc54f7 100644 --- a/Mathlib/NumberTheory/Modular.lean +++ b/Mathlib/NumberTheory/Modular.lean @@ -105,7 +105,7 @@ end BottomRow section TendstoLemmas -open Filter ContinuousLinearMap +open Filter attribute [local simp] FunLike.coe_smul diff --git a/Mathlib/NumberTheory/ModularForms/Basic.lean b/Mathlib/NumberTheory/ModularForms/Basic.lean index f0088951dab59e..bfb440e14e06bd 100644 --- a/Mathlib/NumberTheory/ModularForms/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/Basic.lean @@ -691,7 +691,7 @@ end translate section SL2Z -open ModularForm CuspForm OnePoint +open ModularForm OnePoint variable {k F} {Γ : Subgroup (GL (Fin 2) ℝ)} [FunLike F ℍ ℂ] (f : F) diff --git a/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean b/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean index 16557bc7bb67a1..5aab2cb9def9cd 100644 --- a/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean +++ b/Mathlib/NumberTheory/ModularForms/CuspFormSubmodule.lean @@ -36,7 +36,7 @@ q-expansion coefficient (for `𝒮ℒ`). @[expose] public noncomputable section open UpperHalfPlane ModularForm Complex SlashInvariantForm SlashInvariantFormClass - ModularFormClass MatrixGroups OnePoint Filter Topology + ModularFormClass MatrixGroups OnePoint Filter variable {Γ : Subgroup (GL (Fin 2) ℝ)} {k : ℤ} diff --git a/Mathlib/NumberTheory/ModularForms/LFunction.lean b/Mathlib/NumberTheory/ModularForms/LFunction.lean index 30cd98cb30b24e..9995dc693a71fb 100644 --- a/Mathlib/NumberTheory/ModularForms/LFunction.lean +++ b/Mathlib/NumberTheory/ModularForms/LFunction.lean @@ -18,7 +18,7 @@ public import Mathlib.Analysis.PSeries open UpperHalfPlane hiding I open scoped Real -open Filter Complex MatrixGroups Asymptotics +open Filter Complex Asymptotics variable {Γ : Subgroup (GL (Fin 2) ℝ)} [Γ.IsArithmetic] {k : ℤ} (hk : 0 < k) {F : Type*} [FunLike F ℍ ℂ] (f : F) {s : ℂ} diff --git a/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean b/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean index d64e0c83bf96cb..f0917658438bff 100644 --- a/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean +++ b/Mathlib/NumberTheory/ModularForms/LevelOne/DimensionFormula.lean @@ -30,7 +30,7 @@ for `𝒮ℒ` (= `SL(2, ℤ)`) of even weight. @[expose] public noncomputable section -open UpperHalfPlane ModularForm SlashInvariantForm SlashInvariantFormClass ModularFormClass +open UpperHalfPlane ModularForm SlashInvariantForm SlashInvariantFormClass CuspFormClass MatrixGroups OnePoint Filter EisensteinSeries Asymptotics open scoped Topology diff --git a/Mathlib/NumberTheory/ModularForms/SlashActions.lean b/Mathlib/NumberTheory/ModularForms/SlashActions.lean index 4f5064fdc9c0b0..3c085f78c1b970 100644 --- a/Mathlib/NumberTheory/ModularForms/SlashActions.lean +++ b/Mathlib/NumberTheory/ModularForms/SlashActions.lean @@ -27,7 +27,7 @@ Scoped in the `ModularForm` namespace, this file defines @[expose] public section -open Complex UpperHalfPlane ModularGroup +open Complex UpperHalfPlane open scoped MatrixGroups diff --git a/Mathlib/NumberTheory/NumberField/AdeleRing.lean b/Mathlib/NumberTheory/NumberField/AdeleRing.lean index c88b4583107e9e..10eb809ea75480 100644 --- a/Mathlib/NumberTheory/NumberField/AdeleRing.lean +++ b/Mathlib/NumberTheory/NumberField/AdeleRing.lean @@ -32,7 +32,7 @@ noncomputable section namespace NumberField -open InfinitePlace AbsoluteValue.Completion InfinitePlace.Completion IsDedekindDomain +open AbsoluteValue.Completion InfinitePlace.Completion IsDedekindDomain /-! ## The adele ring -/ diff --git a/Mathlib/NumberTheory/Padics/Hensel.lean b/Mathlib/NumberTheory/Padics/Hensel.lean index ca6b9c603a7a41..09c6bce927a918 100644 --- a/Mathlib/NumberTheory/Padics/Hensel.lean +++ b/Mathlib/NumberTheory/Padics/Hensel.lean @@ -51,7 +51,7 @@ theorem padic_polynomial_dist {p : ℕ} [Fact p.Prime] {R : Type*} [CommSemiring _ ≤ 1 * ‖x - y‖ := by gcongr; apply PadicInt.norm_le_one _ = ‖x - y‖ := by simp -open Filter Metric +open Filter private theorem comp_tendsto_lim {p : ℕ} [Fact p.Prime] {F : Polynomial ℤ_[p]} (ncs : CauSeq ℤ_[p] norm) : Tendsto (fun i => F.eval (ncs i)) atTop (𝓝 (F.eval ncs.lim)) := diff --git a/Mathlib/NumberTheory/Padics/Measure/Topology.lean b/Mathlib/NumberTheory/Padics/Measure/Topology.lean index 9a7cf8e4d6901d..f4c4ade16d8119 100644 --- a/Mathlib/NumberTheory/Padics/Measure/Topology.lean +++ b/Mathlib/NumberTheory/Padics/Measure/Topology.lean @@ -17,7 +17,7 @@ instances in order to avoid favouring one topology over the other. @[expose] public section -open ContinuousMap Topology +open ContinuousMap variable {X R E : Type*} [TopologicalSpace X] diff --git a/Mathlib/NumberTheory/Padics/WithVal.lean b/Mathlib/NumberTheory/Padics/WithVal.lean index 641d6ab71534f2..db972bcb609f80 100644 --- a/Mathlib/NumberTheory/Padics/WithVal.lean +++ b/Mathlib/NumberTheory/Padics/WithVal.lean @@ -33,7 +33,7 @@ namespace Padic variable {p : ℕ} [Fact p.Prime] -open NNReal WithZero UniformSpace +open WithZero UniformSpace set_option backward.isDefEq.respectTransparency.types false in open MonoidWithZeroHom.ValueGroup₀ in diff --git a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean index 8b35155c283654..40e7815a12491f 100644 --- a/Mathlib/NumberTheory/RamificationInertia/Inertia.lean +++ b/Mathlib/NumberTheory/RamificationInertia/Inertia.lean @@ -48,8 +48,6 @@ local notation "f" => algebraMap R S open Module -open UniqueFactorizationMonoid - attribute [local instance] Ideal.Quotient.field section DecEq diff --git a/Mathlib/NumberTheory/SelbergSieve.lean b/Mathlib/NumberTheory/SelbergSieve.lean index 1bdaf06eaeaaf1..0a350af239b2c0 100644 --- a/Mathlib/NumberTheory/SelbergSieve.lean +++ b/Mathlib/NumberTheory/SelbergSieve.lean @@ -85,7 +85,7 @@ attribute [arith_mult] BoundingSieve.nu_mult namespace Mathlib.Meta.Positivity -open Lean Meta Qq +open Lean Qq /-- Extension for the `positivity` tactic: `BoundingSieve.weights`. -/ @[positivity BoundingSieve.weights _ _] diff --git a/Mathlib/NumberTheory/Transcendental/Liouville/LiouvilleWith.lean b/Mathlib/NumberTheory/Transcendental/Liouville/LiouvilleWith.lean index 682e83ab6f38d2..d46cfeeb2bceac 100644 --- a/Mathlib/NumberTheory/Transcendental/Liouville/LiouvilleWith.lean +++ b/Mathlib/NumberTheory/Transcendental/Liouville/LiouvilleWith.lean @@ -38,7 +38,7 @@ Liouville number, irrational, irrationality exponent @[expose] public section -open Filter Metric Real Set +open Filter Real Set open scoped Filter Topology diff --git a/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean index 6122184f814e7a..e5a9a7513a9e6e 100644 --- a/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/TsumDivisorsAntidiagonal.lean @@ -24,7 +24,7 @@ Lambert series. @[expose] public section -open Filter Complex ArithmeticFunction Nat Topology +open Filter ArithmeticFunction Nat Topology /-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a, b)`. -/ diff --git a/Mathlib/Order/Atoms/Finite.lean b/Mathlib/Order/Atoms/Finite.lean index b1e7282843106d..1aedad4b71da63 100644 --- a/Mathlib/Order/Atoms/Finite.lean +++ b/Mathlib/Order/Atoms/Finite.lean @@ -76,8 +76,6 @@ end Bool section Fintype -open Finset - -- see Note [lower instance priority] instance (priority := 100) Finite.to_isCoatomic [PartialOrder α] [OrderTop α] [Finite α] : IsCoatomic α := diff --git a/Mathlib/Order/Birkhoff.lean b/Mathlib/Order/Birkhoff.lean index f43fcfb6751abf..84175d243f5011 100644 --- a/Mathlib/Order/Birkhoff.lean +++ b/Mathlib/Order/Birkhoff.lean @@ -52,7 +52,7 @@ birkhoff, representation, stone duality, lattice embedding @[expose] public section -open Finset Function OrderDual UpperSet LowerSet +open Finset Function UpperSet LowerSet variable {α : Type*} diff --git a/Mathlib/Order/BooleanAlgebra/Defs.lean b/Mathlib/Order/BooleanAlgebra/Defs.lean index be7f6b1654a89b..1d0a050a060e8d 100644 --- a/Mathlib/Order/BooleanAlgebra/Defs.lean +++ b/Mathlib/Order/BooleanAlgebra/Defs.lean @@ -62,8 +62,6 @@ generalized Boolean algebras, Boolean algebras, lattices, sdiff, compl assert_not_exists RelIso -open Function OrderDual - universe u v variable {α : Type u} {β : Type*} {x y z : α} diff --git a/Mathlib/Order/BooleanAlgebra/Set.lean b/Mathlib/Order/BooleanAlgebra/Set.lean index 3968a813dbc413..91b0b1950fe6a1 100644 --- a/Mathlib/Order/BooleanAlgebra/Set.lean +++ b/Mathlib/Order/BooleanAlgebra/Set.lean @@ -29,8 +29,6 @@ set, sets, subset, subsets, complement assert_not_exists RelIso -open Function - namespace Set variable {α β : Type*} {s s₁ s₂ t t₁ t₂ u : Set α} {a b : α} diff --git a/Mathlib/Order/BoundedOrder/Lattice.lean b/Mathlib/Order/BoundedOrder/Lattice.lean index 7f56c2b15491cf..4d38b91904d8c5 100644 --- a/Mathlib/Order/BoundedOrder/Lattice.lean +++ b/Mathlib/Order/BoundedOrder/Lattice.lean @@ -24,8 +24,6 @@ This file contains miscellaneous lemmas about lattices with top or bottom elemen public section -open Function OrderDual - variable {α β : Type*} /-! ### Top, bottom element -/ diff --git a/Mathlib/Order/Category/HeytAlg.lean b/Mathlib/Order/Category/HeytAlg.lean index 5a17e83667cf90..292bf795ff1785 100644 --- a/Mathlib/Order/Category/HeytAlg.lean +++ b/Mathlib/Order/Category/HeytAlg.lean @@ -19,7 +19,7 @@ This file defines `HeytAlg`, the category of Heyting algebras. universe u -open CategoryTheory Opposite Order +open CategoryTheory Order /-- The category of Heyting algebras. -/ structure HeytAlg where diff --git a/Mathlib/Order/CompleteLattice/Defs.lean b/Mathlib/Order/CompleteLattice/Defs.lean index 86abda9d041f21..7356cb22e505f4 100644 --- a/Mathlib/Order/CompleteLattice/Defs.lean +++ b/Mathlib/Order/CompleteLattice/Defs.lean @@ -44,7 +44,7 @@ In lemma names, @[expose] public section -open Function OrderDual Set +open OrderDual Set variable {α β γ : Type*} {ι ι' : Sort*} {κ : ι → Sort*} {κ' : ι' → Sort*} diff --git a/Mathlib/Order/CompleteLattice/Finset.lean b/Mathlib/Order/CompleteLattice/Finset.lean index eff556937c4e88..8cddcaf8d00bb1 100644 --- a/Mathlib/Order/CompleteLattice/Finset.lean +++ b/Mathlib/Order/CompleteLattice/Finset.lean @@ -21,7 +21,7 @@ public section assert_not_exists IsOrderedMonoid MonoidWithZero -open Function Multiset OrderDual +open Function variable {F α β γ ι κ : Type*} diff --git a/Mathlib/Order/ConditionallyCompletePartialOrder/Basic.lean b/Mathlib/Order/ConditionallyCompletePartialOrder/Basic.lean index f718486c1c0d5d..4956fefc0a7a30 100644 --- a/Mathlib/Order/ConditionallyCompletePartialOrder/Basic.lean +++ b/Mathlib/Order/ConditionallyCompletePartialOrder/Basic.lean @@ -24,7 +24,7 @@ public section -- Guard against import creep assert_not_exists Multiset -open Function OrderDual Set +open OrderDual Set variable {α β γ : Type*} {ι : Sort*} diff --git a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean index 58859320d93b60..beecd79ab39bc7 100644 --- a/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean +++ b/Mathlib/Order/ConditionallyCompletePartialOrder/Indexed.lean @@ -21,7 +21,7 @@ public section -- Guard against import creep assert_not_exists Multiset -open Function OrderDual Set +open Function Set variable {α β γ : Type*} {ι : Sort*} diff --git a/Mathlib/Order/Filter/AtTopBot/Finite.lean b/Mathlib/Order/Filter/AtTopBot/Finite.lean index 9aec2c6ce0e1da..c46178f29dad3d 100644 --- a/Mathlib/Order/Filter/AtTopBot/Finite.lean +++ b/Mathlib/Order/Filter/AtTopBot/Finite.lean @@ -124,7 +124,7 @@ theorem HasAntitoneBasis.subbasis_with_rel {f : Filter α} {s : ℕ → Set α} end Filter -open Filter Finset +open Filter namespace Nat diff --git a/Mathlib/Order/Filter/Interval.lean b/Mathlib/Order/Filter/Interval.lean index 6c44be90d1d622..2ceddbd4eb2531 100644 --- a/Mathlib/Order/Filter/Interval.lean +++ b/Mathlib/Order/Filter/Interval.lean @@ -80,7 +80,7 @@ public section variable {α β : Type*} -open Filter Set Function +open Filter Set namespace Filter diff --git a/Mathlib/Order/Filter/Ring.lean b/Mathlib/Order/Filter/Ring.lean index 0f02ce5379ac7e..ce9653028d7ebf 100644 --- a/Mathlib/Order/Filter/Ring.lean +++ b/Mathlib/Order/Filter/Ring.lean @@ -15,7 +15,7 @@ public import Mathlib.Algebra.Order.Ring.Defs public section namespace Filter -open Function Filter +open Filter universe u v diff --git a/Mathlib/Order/GaloisConnection/Defs.lean b/Mathlib/Order/GaloisConnection/Defs.lean index 4ab966280e4dd1..61927d2d393e30 100644 --- a/Mathlib/Order/GaloisConnection/Defs.lean +++ b/Mathlib/Order/GaloisConnection/Defs.lean @@ -27,7 +27,7 @@ such that `∀ a b, l a ≤ b ↔ a ≤ u b`. assert_not_exists CompleteLattice RelIso -open Function OrderDual Set +open Function OrderDual universe u v w x diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index c67d0ab9562107..5ee38e362a5ed3 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -1036,8 +1036,6 @@ theorem dualDual_symm_apply (a : αᵒᵈᵒᵈ) : (dualDual α).symm a = ofDual end LE -open Set - section LE variable [LE α] [LE β] diff --git a/Mathlib/Order/Monotone/Defs.lean b/Mathlib/Order/Monotone/Defs.lean index 42f482df67ff03..9a08d9c6614a64 100644 --- a/Mathlib/Order/Monotone/Defs.lean +++ b/Mathlib/Order/Monotone/Defs.lean @@ -459,8 +459,6 @@ section Preorder variable [Preorder β] {f : α → β} {s : Set α} -open Ordering - @[to_dual self] theorem Monotone.reflect_lt (hf : Monotone f) {a b : α} (h : f a < f b) : a < b := lt_of_not_ge fun h' ↦ h.not_ge (hf h') diff --git a/Mathlib/Order/TeichmullerTukey.lean b/Mathlib/Order/TeichmullerTukey.lean index 7b9a87277fc8cb..e604d10c2b7a02 100644 --- a/Mathlib/Order/TeichmullerTukey.lean +++ b/Mathlib/Order/TeichmullerTukey.lean @@ -32,7 +32,7 @@ Teichmuller-Tukey lemma. @[expose] public section -open Set Finite +open Set variable {α : Type*} (F : Set (Set α)) diff --git a/Mathlib/Order/Types/Defs.lean b/Mathlib/Order/Types/Defs.lean index 1e46789757f661..f39a6d190cb3ee 100644 --- a/Mathlib/Order/Types/Defs.lean +++ b/Mathlib/Order/Types/Defs.lean @@ -42,7 +42,7 @@ order type, order isomorphism, linear order public noncomputable section -open Function Set Equiv Order +open Function Equiv universe u v variable {α β : Type u} [LinearOrder α] [LinearOrder β] {δ : Sort v} diff --git a/Mathlib/Order/ULift.lean b/Mathlib/Order/ULift.lean index 638cb78c7bd0f8..dd80f5b77db462 100644 --- a/Mathlib/Order/ULift.lean +++ b/Mathlib/Order/ULift.lean @@ -18,8 +18,6 @@ public section namespace ULift -open Batteries - universe v u variable {α : Type u} diff --git a/Mathlib/Order/UpperLower/Hom.lean b/Mathlib/Order/UpperLower/Hom.lean index c04d816ed9f418..aaceca5fd2c80e 100644 --- a/Mathlib/Order/UpperLower/Hom.lean +++ b/Mathlib/Order/UpperLower/Hom.lean @@ -20,8 +20,6 @@ In this file we define `UpperSet.iciSupHom` etc. These functions are `UpperSet.I variable {α : Type*} -open OrderDual - namespace UpperSet section SemilatticeSup diff --git a/Mathlib/Probability/Decision/Risk/Countable.lean b/Mathlib/Probability/Decision/Risk/Countable.lean index b78624afd4c314..bcbaac671bc272 100644 --- a/Mathlib/Probability/Decision/Risk/Countable.lean +++ b/Mathlib/Probability/Decision/Risk/Countable.lean @@ -19,7 +19,7 @@ with sums instead of integrals. public section -open MeasureTheory Function +open MeasureTheory open scoped ENNReal NNReal namespace ProbabilityTheory diff --git a/Mathlib/Probability/Distributions/Gaussian/CharFun.lean b/Mathlib/Probability/Distributions/Gaussian/CharFun.lean index 82d54b8d6c3a54..627df936874f15 100644 --- a/Mathlib/Probability/Distributions/Gaussian/CharFun.lean +++ b/Mathlib/Probability/Distributions/Gaussian/CharFun.lean @@ -40,7 +40,7 @@ Gaussian measure, characteristic function public section -open Complex MeasureTheory WithLp ContinuousLinearMap +open Complex MeasureTheory ContinuousLinearMap open scoped Matrix NNReal Real RealInnerProductSpace ProbabilityTheory diff --git a/Mathlib/Probability/Distributions/Geometric.lean b/Mathlib/Probability/Distributions/Geometric.lean index 8631d30f90e8c9..8ba0ed972087aa 100644 --- a/Mathlib/Probability/Distributions/Geometric.lean +++ b/Mathlib/Probability/Distributions/Geometric.lean @@ -42,7 +42,7 @@ geometric distribution open scoped ENNReal NNReal -open MeasureTheory Real Set Filter Topology +open MeasureTheory Real Set namespace ProbabilityTheory diff --git a/Mathlib/Probability/Distributions/Pareto.lean b/Mathlib/Probability/Distributions/Pareto.lean index 249e2669ac7b85..4d6d42189755de 100644 --- a/Mathlib/Probability/Distributions/Pareto.lean +++ b/Mathlib/Probability/Distributions/Pareto.lean @@ -26,7 +26,7 @@ Define the Pareto measure over the reals. open scoped ENNReal NNReal -open MeasureTheory Real Set Filter Topology +open MeasureTheory Real Set Filter namespace ProbabilityTheory variable {t r x : ℝ} @@ -91,8 +91,6 @@ lemma paretoPDFReal_nonneg (ht : 0 ≤ t) (hr : 0 ≤ r) (x : ℝ) : positivity [lt_of_lt_of_le htp h] · positivity -open Measure - /-- The pdf of the Pareto distribution integrates to `1`. -/ @[simp] lemma lintegral_paretoPDF_eq_one (ht : 0 < t) (hr : 0 < r) : diff --git a/Mathlib/Probability/IdentDistrib.lean b/Mathlib/Probability/IdentDistrib.lean index 10e8ade1728e7f..8cfa41181178d2 100644 --- a/Mathlib/Probability/IdentDistrib.lean +++ b/Mathlib/Probability/IdentDistrib.lean @@ -54,7 +54,7 @@ so on. public section -open MeasureTheory Filter Finset +open MeasureTheory Filter noncomputable section @@ -292,8 +292,6 @@ end IdentDistrib section UniformIntegrable -open TopologicalSpace - variable {E : Type*} [MeasurableSpace E] [NormedAddCommGroup E] [BorelSpace E] {μ : Measure α} [IsFiniteMeasure μ] diff --git a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean index 68403b544d1a92..c2930c5c51fd88 100644 --- a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean @@ -49,7 +49,7 @@ Let `κ : Kernel α (β × ℝ)` and `ν : Kernel α β`. @[expose] public section -open MeasureTheory Set Filter TopologicalSpace +open MeasureTheory Set Filter open scoped NNReal ENNReal MeasureTheory Topology ProbabilityTheory diff --git a/Mathlib/Probability/Kernel/MeasurableLIntegral.lean b/Mathlib/Probability/Kernel/MeasurableLIntegral.lean index 2a7782dbce9357..86b71551d8e4c2 100644 --- a/Mathlib/Probability/Kernel/MeasurableLIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableLIntegral.lean @@ -24,7 +24,7 @@ The Lebesgue integral of a measurable function against a kernel is measurable. public section -open MeasureTheory ProbabilityTheory Function Set Filter +open MeasureTheory ProbabilityTheory Function Set open scoped MeasureTheory ENNReal Topology diff --git a/Mathlib/Probability/Kernel/Proper.lean b/Mathlib/Probability/Kernel/Proper.lean index 61beb895b36e20..23cac378738440 100644 --- a/Mathlib/Probability/Kernel/Proper.lean +++ b/Mathlib/Probability/Kernel/Proper.lean @@ -29,7 +29,7 @@ Prove the `integral` versions of the `lintegral` lemmas below public section -open MeasureTheory ENNReal NNReal Set +open MeasureTheory ENNReal Set open scoped ProbabilityTheory namespace ProbabilityTheory.Kernel diff --git a/Mathlib/Probability/Martingale/Basic.lean b/Mathlib/Probability/Martingale/Basic.lean index f7b8ad3773599f..30fb3db3d09f85 100644 --- a/Mathlib/Probability/Martingale/Basic.lean +++ b/Mathlib/Probability/Martingale/Basic.lean @@ -39,7 +39,7 @@ with respect to `ℱ` and for all `i ≤ j`, `f i ≤ᵐ[μ] μ[f j | ℱ i]`. @[expose] public section -open TopologicalSpace Filter +open Filter open scoped NNReal ENNReal MeasureTheory ProbabilityTheory diff --git a/Mathlib/Probability/Martingale/Centering.lean b/Mathlib/Probability/Martingale/Centering.lean index 09243a048a6c1f..22963efcd5a85f 100644 --- a/Mathlib/Probability/Martingale/Centering.lean +++ b/Mathlib/Probability/Martingale/Centering.lean @@ -34,7 +34,7 @@ two processes `martingalePart f ℱ μ` and `predictablePart f ℱ μ`. @[expose] public section -open TopologicalSpace Filter +open Filter open scoped NNReal ENNReal MeasureTheory ProbabilityTheory diff --git a/Mathlib/Probability/Moments/ComplexMGF.lean b/Mathlib/Probability/Moments/ComplexMGF.lean index 80d8551aa605b5..5a0a1ee7f411ed 100644 --- a/Mathlib/Probability/Moments/ComplexMGF.lean +++ b/Mathlib/Probability/Moments/ComplexMGF.lean @@ -59,7 +59,7 @@ properties of the mgf from those of the characteristic function). @[expose] public section -open MeasureTheory Filter Finset Real Complex +open MeasureTheory Filter Real Complex open scoped MeasureTheory ProbabilityTheory ENNReal NNReal Topology diff --git a/Mathlib/Probability/Moments/CovarianceBilinDual.lean b/Mathlib/Probability/Moments/CovarianceBilinDual.lean index 0f9054f20fafb4..946b32ee2f8d3e 100644 --- a/Mathlib/Probability/Moments/CovarianceBilinDual.lean +++ b/Mathlib/Probability/Moments/CovarianceBilinDual.lean @@ -42,7 +42,7 @@ The hypothesis that `μ` has a second moment is written as `MemLp id 2 μ` in th @[expose] public section -open MeasureTheory ProbabilityTheory Complex NormedSpace +open MeasureTheory ProbabilityTheory NormedSpace open scoped ENNReal NNReal Real Topology variable {E : Type*} [NormedAddCommGroup E] {mE : MeasurableSpace E} {μ : Measure E} {p : ℝ≥0∞} diff --git a/Mathlib/Probability/Moments/IntegrableExpMul.lean b/Mathlib/Probability/Moments/IntegrableExpMul.lean index 02b6c4d22d0bf8..fee526c37090f1 100644 --- a/Mathlib/Probability/Moments/IntegrableExpMul.lean +++ b/Mathlib/Probability/Moments/IntegrableExpMul.lean @@ -40,7 +40,7 @@ We prove the integrability of other functions for `t` in the interior of that in @[expose] public section -open MeasureTheory Filter Finset Real +open MeasureTheory Filter Real open scoped MeasureTheory ProbabilityTheory ENNReal NNReal Topology diff --git a/Mathlib/Probability/Moments/MGFAnalytic.lean b/Mathlib/Probability/Moments/MGFAnalytic.lean index 7128f36812acab..e5a289d805c247 100644 --- a/Mathlib/Probability/Moments/MGFAnalytic.lean +++ b/Mathlib/Probability/Moments/MGFAnalytic.lean @@ -29,7 +29,7 @@ is analytic on the interior of `integrableExpSet X μ`, the interval on which it public section -open MeasureTheory Filter Finset Real +open MeasureTheory Filter Real open scoped MeasureTheory ProbabilityTheory ENNReal NNReal Topology Nat diff --git a/Mathlib/Probability/Moments/Tilted.lean b/Mathlib/Probability/Moments/Tilted.lean index 6c558c4b530af4..305a7521150173 100644 --- a/Mathlib/Probability/Moments/Tilted.lean +++ b/Mathlib/Probability/Moments/Tilted.lean @@ -29,7 +29,7 @@ of `X`. public section -open MeasureTheory Real Set Finset +open MeasureTheory Real Set open scoped NNReal ENNReal ProbabilityTheory diff --git a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean index 07c4db05ab05a7..8bfbf6b5d5daba 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean @@ -27,7 +27,7 @@ noncomputable section variable {α β γ : Type*} -open NNReal ENNReal +open ENNReal open MeasureTheory diff --git a/Mathlib/Probability/Process/Adapted.lean b/Mathlib/Probability/Process/Adapted.lean index 4b0473c6c2ada0..c91f5fcb9b1982 100644 --- a/Mathlib/Probability/Process/Adapted.lean +++ b/Mathlib/Probability/Process/Adapted.lean @@ -41,7 +41,7 @@ adapted, progressively measurable @[expose] public section -open Filter Order TopologicalSpace +open Filter TopologicalSpace open scoped MeasureTheory NNReal ENNReal Topology diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index fbe5932b46e716..dc39879a2f07e0 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -39,7 +39,7 @@ filtration, stochastic process @[expose] public section -open Filter Order TopologicalSpace +open Filter TopologicalSpace open scoped MeasureTheory NNReal ENNReal Topology diff --git a/Mathlib/Probability/Process/HittingTime.lean b/Mathlib/Probability/Process/HittingTime.lean index d0ea12da69e871..dfe6c576b7e3b6 100644 --- a/Mathlib/Probability/Process/HittingTime.lean +++ b/Mathlib/Probability/Process/HittingTime.lean @@ -35,7 +35,7 @@ we have only proved it for the discrete case so far). @[expose] public section -open Filter Order TopologicalSpace +open TopologicalSpace open scoped MeasureTheory NNReal ENNReal Topology diff --git a/Mathlib/Probability/Process/Predictable.lean b/Mathlib/Probability/Process/Predictable.lean index d296eac3c6a52d..256cb3bff21842 100644 --- a/Mathlib/Probability/Process/Predictable.lean +++ b/Mathlib/Probability/Process/Predictable.lean @@ -165,8 +165,6 @@ def IsStronglyPredictable [Preorder ι] [OrderBot ι] (𝓕 : Filtration ι m) ( namespace IsStronglyPredictable -open Filtration - variable [LinearOrder ι] [OrderBot ι] [MeasurableSpace ι] [TopologicalSpace ι] [OpensMeasurableSpace ι] [OrderClosedTopology ι] diff --git a/Mathlib/Probability/Process/Stopping.lean b/Mathlib/Probability/Process/Stopping.lean index 0e98b272618003..3521be79ea02e3 100644 --- a/Mathlib/Probability/Process/Stopping.lean +++ b/Mathlib/Probability/Process/Stopping.lean @@ -273,8 +273,6 @@ end Countable section IsRightContinuous -open Filtration - variable [ConditionallyCompleteLinearOrder ι] [TopologicalSpace ι] [OrderTopology ι] [FirstCountableTopology ι] {f : Filtration ι m} {τ : Ω → WithTop ι} @@ -1289,9 +1287,6 @@ section Nat /-! ### Filtrations indexed by `ℕ` -/ - -open Filtration - variable {u : ℕ → Ω → β} {τ π : Ω → ℕ∞} theorem stoppedValue_sub_eq_sum [AddCommGroup β] (hle : τ ≤ π) (hπ : ∀ ω, π ω ≠ ∞) : diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean index c7fdc66d39ca92..b99681e6460d7a 100644 --- a/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/Basic.lean @@ -46,7 +46,7 @@ See `TopRep.d`. variable {k G : Type*} [Ring k] [Group G] [TopologicalSpace k] [TopologicalSpace G] [IsTopologicalGroup G] -open CategoryTheory ContRepresentation Limits +open CategoryTheory ContRepresentation namespace TopRep diff --git a/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean index 3b56514a64514b..46c4b1afcdb981 100644 --- a/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/Homological/ContCohomology/LowDegree.lean @@ -18,7 +18,7 @@ invariants of the representation. namespace ContinuousCohomology -open CategoryTheory Functor TopRep ContRepresentation +open CategoryTheory TopRep ContRepresentation variable {k G : Type*} [Ring k] [Group G] [TopologicalSpace k] [TopologicalSpace G] [IsTopologicalGroup G] diff --git a/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean b/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean index 617ff0daa92e02..2ae11bd619643f 100644 --- a/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean +++ b/Mathlib/RepresentationTheory/Homological/FiniteCyclic.lean @@ -96,7 +96,7 @@ variable (k : Type u) {G : Type u} [CommRing k] [CommGroup G] [Fintype G] (A : R namespace leftRegular -open Finsupp IsCyclic Representation +open Finsupp Representation lemma range_norm_eq_ker_applyAsHom_sub (hg : ∀ x, x ∈ Subgroup.zpowers g) : LinearMap.range (leftRegular k G).norm.hom.toLinearMap = diff --git a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean index 2ba62d9de0e080..ac07dbb98b163b 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupCohomology/Shapiro.lean @@ -36,7 +36,7 @@ universe u namespace groupCohomology -open CategoryTheory Finsupp TensorProduct Rep +open CategoryTheory Rep variable {k G : Type u} [CommRing k] [Group G] {S : Subgroup G} (A : Rep k S) diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean index aba75e46af8252..b20d6a83d9fcd8 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/FiniteCyclic.lean @@ -38,7 +38,7 @@ computes group homology. universe v u -open CategoryTheory Representation Finsupp Limits +open CategoryTheory Representation Finsupp namespace Rep.FiniteCyclicGroup diff --git a/Mathlib/RepresentationTheory/Homological/GroupHomology/Shapiro.lean b/Mathlib/RepresentationTheory/Homological/GroupHomology/Shapiro.lean index fa54b68591fe4c..13cb6d3ce7c74d 100644 --- a/Mathlib/RepresentationTheory/Homological/GroupHomology/Shapiro.lean +++ b/Mathlib/RepresentationTheory/Homological/GroupHomology/Shapiro.lean @@ -43,7 +43,7 @@ universe u namespace groupHomology -open CategoryTheory Finsupp TensorProduct Rep Representation +open CategoryTheory Rep variable {k G : Type u} [CommRing k] [Group G] (S : Subgroup G) (A : Rep k S) diff --git a/Mathlib/RepresentationTheory/Induced.lean b/Mathlib/RepresentationTheory/Induced.lean index 2677fd901a31d3..70b3a2784fde17 100644 --- a/Mathlib/RepresentationTheory/Induced.lean +++ b/Mathlib/RepresentationTheory/Induced.lean @@ -49,8 +49,6 @@ universe t w w' u u' v v' namespace Representation -open Finsupp - variable {k G H : Type*} [CommRing k] [Group G] [Group H] (φ : G →* H) {A B : Type*} [AddCommGroup A] [Module k A] (ρ : Representation k G A) [AddCommGroup B] [Module k B] (τ : Representation k G B) @@ -162,8 +160,6 @@ noncomputable def indResAdjunction : indFunctor k φ ⊣ resFunctor.{max w v' u} ext; simp [indMap, indResHomEquiv] homEquiv_naturality_right := by intros; rfl } -open Finsupp - noncomputable instance : (indFunctor.{max u v' w} k φ).IsLeftAdjoint := (indResAdjunction k φ).isLeftAdjoint diff --git a/Mathlib/RingTheory/AdicCompletion/Algebra.lean b/Mathlib/RingTheory/AdicCompletion/Algebra.lean index 6c460f5c90fc5a..b824c52875b962 100644 --- a/Mathlib/RingTheory/AdicCompletion/Algebra.lean +++ b/Mathlib/RingTheory/AdicCompletion/Algebra.lean @@ -348,8 +348,6 @@ example : module I = @Algebra.toModule (AdicCompletion I R) section liftRingHom -open Quotient - variable {R S : Type*} [NonAssocSemiring R] [CommRing S] (I : Ideal S) set_option backward.isDefEq.respectTransparency false in diff --git a/Mathlib/RingTheory/AdicCompletion/Topology.lean b/Mathlib/RingTheory/AdicCompletion/Topology.lean index e0c6c0d33a17c6..751595eacf434f 100644 --- a/Mathlib/RingTheory/AdicCompletion/Topology.lean +++ b/Mathlib/RingTheory/AdicCompletion/Topology.lean @@ -36,7 +36,7 @@ end TopologicalSpace section UniformSpace -open Topology Uniformity +open Uniformity variable {R : Type*} [CommRing R] [UniformSpace R] [IsUniformAddGroup R] {I : Ideal R} (hI : IsAdic I) diff --git a/Mathlib/RingTheory/Adjoin/FG.lean b/Mathlib/RingTheory/Adjoin/FG.lean index d07893b5078e1e..37c46210abd644 100644 --- a/Mathlib/RingTheory/Adjoin/FG.lean +++ b/Mathlib/RingTheory/Adjoin/FG.lean @@ -32,7 +32,7 @@ adjoin, algebra, finitely-generated algebra universe u v w -open Subsemiring Ring Submodule +open Ring Submodule open scoped Pointwise diff --git a/Mathlib/RingTheory/Artinian/Module.lean b/Mathlib/RingTheory/Artinian/Module.lean index 5bccde52d124ca..727b42f6c1ad19 100644 --- a/Mathlib/RingTheory/Artinian/Module.lean +++ b/Mathlib/RingTheory/Artinian/Module.lean @@ -57,7 +57,7 @@ Artinian, artinian, Artinian ring, Artinian module, artinian ring, artinian modu @[expose] public section -open Set Filter Pointwise +open Set Filter section Semiring diff --git a/Mathlib/RingTheory/Binomial.lean b/Mathlib/RingTheory/Binomial.lean index fea1415c4514d6..29ea28732ccc71 100644 --- a/Mathlib/RingTheory/Binomial.lean +++ b/Mathlib/RingTheory/Binomial.lean @@ -67,7 +67,7 @@ Further results in Elliot's paper: @[expose] public section -open Function Polynomial +open Polynomial /-- A binomial ring is a ring for which ascending Pochhammer evaluations are uniquely divisible by suitable factorials. We define this notion as a mixin for additive commutative monoids with natural diff --git a/Mathlib/RingTheory/Conductor.lean b/Mathlib/RingTheory/Conductor.lean index 01c6d097802771..29a07561d840fa 100644 --- a/Mathlib/RingTheory/Conductor.lean +++ b/Mathlib/RingTheory/Conductor.lean @@ -23,7 +23,7 @@ This file defines the conductor ideal of an element `x` of `R`-algebra `S`. This variable (R : Type*) {S : Type*} [CommRing R] [CommRing S] [Algebra R S] -open Ideal Polynomial DoubleQuot Module UniqueFactorizationMonoid Algebra RingHom +open Ideal Module Algebra RingHom local notation:max R "<" x:max ">" => adjoin R ({x} : Set S) diff --git a/Mathlib/RingTheory/DedekindDomain/Factorization.lean b/Mathlib/RingTheory/DedekindDomain/Factorization.lean index a8efdab49893e4..a5f78326ae40f2 100644 --- a/Mathlib/RingTheory/DedekindDomain/Factorization.lean +++ b/Mathlib/RingTheory/DedekindDomain/Factorization.lean @@ -800,7 +800,7 @@ section primesOver variable {S : Type*} [CommRing S] [Algebra S R] [Algebra.IsIntegral S R] [IsDomain S] [Module.IsTorsionFree S R] -open IsDedekindDomain Ideal.IsDedekindDomain HeightOneSpectrum +open IsDedekindDomain Ideal.IsDedekindDomain /-- If `p` is a maximal ideal, then the lift of `p` in an extension is the product of the primes diff --git a/Mathlib/RingTheory/Discriminant.lean b/Mathlib/RingTheory/Discriminant.lean index c5d0ad3a4e73a7..6124385060d6d3 100644 --- a/Mathlib/RingTheory/Discriminant.lean +++ b/Mathlib/RingTheory/Discriminant.lean @@ -54,7 +54,7 @@ universe u v w z open scoped Matrix -open Matrix Module Fintype Polynomial Finset IntermediateField +open Matrix Module Fintype Polynomial Finset namespace Algebra diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index 1ba1ee31b36601..36624434723f72 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -45,8 +45,6 @@ variable [Semiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R namespace Finite -open Submodule Set - variable {R S M N} section Algebra diff --git a/Mathlib/RingTheory/Finiteness/Cardinality.lean b/Mathlib/RingTheory/Finiteness/Cardinality.lean index a97a315cef6e90..d92c280ec5a4b8 100644 --- a/Mathlib/RingTheory/Finiteness/Cardinality.lean +++ b/Mathlib/RingTheory/Finiteness/Cardinality.lean @@ -22,7 +22,6 @@ This file relates `Module.Finite` and `_root_.Finite`. @[expose] public section open Function (Surjective) -open Finsupp section ModuleAndAlgebra diff --git a/Mathlib/RingTheory/Finiteness/Projective.lean b/Mathlib/RingTheory/Finiteness/Projective.lean index 7e2bf92a9b5302..24ad58ece3ab49 100644 --- a/Mathlib/RingTheory/Finiteness/Projective.lean +++ b/Mathlib/RingTheory/Finiteness/Projective.lean @@ -21,8 +21,6 @@ namespace Module namespace Finite -open Submodule Set - variable {R M N : Type*} variable [Semiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] diff --git a/Mathlib/RingTheory/Finiteness/Subalgebra.lean b/Mathlib/RingTheory/Finiteness/Subalgebra.lean index 0de81782ba8eef..537c6240fae2f0 100644 --- a/Mathlib/RingTheory/Finiteness/Subalgebra.lean +++ b/Mathlib/RingTheory/Finiteness/Subalgebra.lean @@ -16,7 +16,6 @@ public import Mathlib.RingTheory.Finiteness.Bilinear public section open Function (Surjective) -open Finsupp namespace Subalgebra diff --git a/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Submodule.lean b/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Submodule.lean index df61073e417bf9..e2bf93cc440b07 100644 --- a/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Submodule.lean +++ b/Mathlib/RingTheory/GradedAlgebra/Homogeneous/Submodule.lean @@ -37,7 +37,7 @@ graded algebra, homogeneous @[expose] public section -open SetLike DirectSum Pointwise Set +open SetLike DirectSum Set variable {ιA ιM σA σM A M : Type*} diff --git a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean index e0c7c357ef885c..ad756fb104e656 100644 --- a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean +++ b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean @@ -77,7 +77,7 @@ circumvent this, we quotient `NumDenSameDeg 𝒜 x` by the kernel of `c ↦ c.nu noncomputable section -open DirectSum Pointwise +open DirectSum open DirectSum SetLike @@ -102,7 +102,7 @@ end namespace NumDenSameDeg -open SetLike.GradedMonoid Submodule +open SetLike.GradedMonoid @[ext] theorem ext {𝒜 : ι → σ} (x : Submonoid A) diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index ac82c0403a76e0..034271855bdc5a 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -43,7 +43,7 @@ in the file `Mathlib/RingTheory/LaurentSeries.lean`. @[expose] public section -open Finset Function +open Function noncomputable section diff --git a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean index edae469e7ab14b..791b8c52953402 100644 --- a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean +++ b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean @@ -38,7 +38,7 @@ we get the more familiar semiring of formal power series with coefficients in `R @[expose] public section -open Finset Function Pointwise Polynomial +open Finset Function Polynomial noncomputable section diff --git a/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean b/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean index 9610c02f01002e..9d57b2d008ad1a 100644 --- a/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean +++ b/Mathlib/RingTheory/HopfAlgebra/MonoidAlgebra.lean @@ -62,8 +62,6 @@ end MonoidAlgebra namespace LaurentPolynomial -open Finsupp - variable (R A : Type*) [CommSemiring R] [Semiring A] [HopfAlgebra R A] instance instHopfAlgebra : HopfAlgebra R A[T;T⁻¹] := diff --git a/Mathlib/RingTheory/Ideal/Defs.lean b/Mathlib/RingTheory/Ideal/Defs.lean index 2bff77320cba98..dc651d54e43403 100644 --- a/Mathlib/RingTheory/Ideal/Defs.lean +++ b/Mathlib/RingTheory/Ideal/Defs.lean @@ -31,7 +31,7 @@ universe u v w variable {α : Type u} {β : Type v} {F : Type w} -open Set Function +open Set open scoped Pointwise diff --git a/Mathlib/RingTheory/Ideal/Lattice.lean b/Mathlib/RingTheory/Ideal/Lattice.lean index ebaa0aa5f20212..96333cd17c8bc2 100644 --- a/Mathlib/RingTheory/Ideal/Lattice.lean +++ b/Mathlib/RingTheory/Ideal/Lattice.lean @@ -27,7 +27,7 @@ universe u v w variable {α : Type u} {β : Type v} {F : Type w} -open Set Function +open Set open scoped Pointwise diff --git a/Mathlib/RingTheory/Ideal/Maximal.lean b/Mathlib/RingTheory/Ideal/Maximal.lean index 5d7eb16cfa9833..d96a2bdb3d293f 100644 --- a/Mathlib/RingTheory/Ideal/Maximal.lean +++ b/Mathlib/RingTheory/Ideal/Maximal.lean @@ -32,7 +32,7 @@ universe u v w variable {α : Type u} {β : Type v} {F : Type w} -open Set Function +open Set open scoped Pointwise diff --git a/Mathlib/RingTheory/Ideal/Prime.lean b/Mathlib/RingTheory/Ideal/Prime.lean index 7983ced7053f97..970f524ca66132 100644 --- a/Mathlib/RingTheory/Ideal/Prime.lean +++ b/Mathlib/RingTheory/Ideal/Prime.lean @@ -26,7 +26,7 @@ universe u v w variable {α : Type u} {β : Type v} {F : Type w} -open Set Function +open Set open scoped Pointwise diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean index 18d7ea9e81a655..5fa755efb488d8 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean @@ -24,7 +24,7 @@ Let `R` be a `CommRing` and let `A` be an R-algebra. @[expose] public section -open Polynomial Submodule +open Submodule section diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean index 203c46d45f7b73..816544c9e9f306 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean @@ -20,9 +20,6 @@ Let `R` be a `CommRing` and let `A` be an R-algebra. public section - -open Polynomial Submodule - section Ring variable {R S A : Type*} diff --git a/Mathlib/RingTheory/LaurentSeries.lean b/Mathlib/RingTheory/LaurentSeries.lean index e0b580bd6319c4..cc922e3a7d655d 100644 --- a/Mathlib/RingTheory/LaurentSeries.lean +++ b/Mathlib/RingTheory/LaurentSeries.lean @@ -415,7 +415,7 @@ def idealX : IsDedekindDomain.HeightOneSpectrum K⟦X⟧ where isPrime := PowerSeries.span_X_isPrime ne_bot := by rw [ne_eq, Ideal.span_singleton_eq_bot]; exact X_ne_zero -open IsDedekindDomain.HeightOneSpectrum RatFunc WithZero +open IsDedekindDomain.HeightOneSpectrum WithZero variable {K} @@ -631,7 +631,7 @@ variable {K : Type*} [Field K] section Complete -open Filter WithZero PowerSeries +open Filter WithZero variable (K) in lemma valuation_surjective : Function.Surjective (Valued.v (R := K⸨X⸩)) := by diff --git a/Mathlib/RingTheory/LocalProperties/Exactness.lean b/Mathlib/RingTheory/LocalProperties/Exactness.lean index cd1c1b94c7b3b1..a5265fe141c47e 100644 --- a/Mathlib/RingTheory/LocalProperties/Exactness.lean +++ b/Mathlib/RingTheory/LocalProperties/Exactness.lean @@ -236,8 +236,6 @@ variable [∀ (p : Ideal R) [p.IsMaximal], IsLocalizedModule.AtPrime p (IsScalarTower.toAlgHom R S (Sₚ p) : S →ₗ[R] (Sₚ p))] -open TensorProduct - lemma IsLocalizedModule.map_linearMap_of_isLocalization (Rₚ Sₚ : Type*) [CommSemiring Rₚ] [Algebra R Rₚ] [CommSemiring Sₚ] [Algebra S Sₚ] [Algebra R Sₚ] [IsScalarTower R S Sₚ] [Algebra Rₚ Sₚ] [IsScalarTower R Rₚ Sₚ] (p : Ideal R) [p.IsPrime] diff --git a/Mathlib/RingTheory/LocalProperties/Submodule.lean b/Mathlib/RingTheory/LocalProperties/Submodule.lean index 014c000986975f..6eb0ea86ea7d41 100644 --- a/Mathlib/RingTheory/LocalProperties/Submodule.lean +++ b/Mathlib/RingTheory/LocalProperties/Submodule.lean @@ -132,7 +132,7 @@ end maximal section span -open IsLocalizedModule LocalizedModule Ideal +open IsLocalizedModule Ideal variable (s : Set R) (span_eq : Ideal.span s = ⊤) include span_eq diff --git a/Mathlib/RingTheory/LocalRing/Quotient.lean b/Mathlib/RingTheory/LocalRing/Quotient.lean index ee5c4b00d368ac..75276a8acab57c 100644 --- a/Mathlib/RingTheory/LocalRing/Quotient.lean +++ b/Mathlib/RingTheory/LocalRing/Quotient.lean @@ -24,7 +24,7 @@ We gather results about the quotients of local rings. @[expose] public section -open Submodule FiniteDimensional Module +open Submodule Module variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] [IsLocalRing R] [Module.Finite R S] diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean index 93c620109dc6f4..1fb5b29cf0e7cf 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Fiber.lean @@ -24,7 +24,7 @@ public import Mathlib.Topology.Homeomorph.Lemmas @[expose] public section -open Algebra TensorProduct nonZeroDivisors +open Algebra TensorProduct variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] (p : Ideal R) [p.IsPrime] diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index 3df69d8d5f2392..8bed43f5f6144b 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -623,8 +623,6 @@ end Localization end CommSemiring -open Localization - variable {R : Type*} [CommSemiring R] section NumDen diff --git a/Mathlib/RingTheory/Localization/Pi.lean b/Mathlib/RingTheory/Localization/Pi.lean index 90d996a5b6a0be..c5c6260446a323 100644 --- a/Mathlib/RingTheory/Localization/Pi.lean +++ b/Mathlib/RingTheory/Localization/Pi.lean @@ -81,7 +81,7 @@ theorem bijective_lift_piRingHom_algebraMap_comp_piEvalRingHom [IsLocalization M (ringEquivOfRingEquiv (M := M) (T := M) _ _ (.refl _) <| Submonoid.map_equiv_eq_comap_symm _ _).bijective -open Function Ideal +open Function include M in variable {R} in diff --git a/Mathlib/RingTheory/MatrixAlgebra.lean b/Mathlib/RingTheory/MatrixAlgebra.lean index 73830fa293be3c..879fb4423d567e 100644 --- a/Mathlib/RingTheory/MatrixAlgebra.lean +++ b/Mathlib/RingTheory/MatrixAlgebra.lean @@ -210,8 +210,6 @@ variable [Fintype n] [DecidableEq n] def matrixEquivTensor : Matrix n n A ≃ₐ[R] A ⊗[R] Matrix n n R := AlgEquiv.symm { MatrixEquivTensor.toFunAlgHom n R A, MatrixEquivTensor.equiv n R A with } -open MatrixEquivTensor - @[simp] theorem matrixEquivTensor_apply (M : Matrix n n A) : matrixEquivTensor n R A M = ∑ p : n × n, M p.1 p.2 ⊗ₜ single p.1 p.2 1 := diff --git a/Mathlib/RingTheory/MvPolynomial.lean b/Mathlib/RingTheory/MvPolynomial.lean index 72cc6a34385f27..91ec9fef82c1da 100644 --- a/Mathlib/RingTheory/MvPolynomial.lean +++ b/Mathlib/RingTheory/MvPolynomial.lean @@ -24,7 +24,7 @@ public section noncomputable section -open Set LinearMap Submodule +open Submodule universe u v diff --git a/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean b/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean index ad613300bc836e..36f1e050dd9bfb 100644 --- a/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean +++ b/Mathlib/RingTheory/MvPolynomial/IrreducibleQuadratic.lean @@ -129,8 +129,6 @@ end section /-! ## The quadratic polynomial $$\sum_{i=1}^n X_i Y_i$$. -/ -open Polynomial - variable {n : Type*} {R : Type*} [CommRing R] theorem irreducible_of_totalDegree_eq_one diff --git a/Mathlib/RingTheory/MvPowerSeries/Order.lean b/Mathlib/RingTheory/MvPowerSeries/Order.lean index da040c04cee88c..caca27fc2e94b4 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Order.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Order.lean @@ -123,7 +123,7 @@ namespace MvPowerSeries noncomputable section -open ENat WithTop Finsupp +open ENat Finsupp variable {σ R : Type*} [Semiring R] diff --git a/Mathlib/RingTheory/Noetherian/Basic.lean b/Mathlib/RingTheory/Noetherian/Basic.lean index e2457ce2c3363d..5f62a5128556be 100644 --- a/Mathlib/RingTheory/Noetherian/Basic.lean +++ b/Mathlib/RingTheory/Noetherian/Basic.lean @@ -58,7 +58,7 @@ public section assert_not_exists Matrix -open Set Pointwise +open Set section diff --git a/Mathlib/RingTheory/Noetherian/Defs.lean b/Mathlib/RingTheory/Noetherian/Defs.lean index 2349fb89d4b146..3b7943d50c9c96 100644 --- a/Mathlib/RingTheory/Noetherian/Defs.lean +++ b/Mathlib/RingTheory/Noetherian/Defs.lean @@ -53,7 +53,7 @@ Noetherian, noetherian, Noetherian ring, Noetherian module, noetherian ring, noe assert_not_exists Finsupp.linearCombination Matrix Pi.basis -open Set Pointwise +open Set /-- `IsNoetherian R M` is the proposition that `M` is a Noetherian `R`-module, implemented as the predicate that all `R`-submodules of `M` are finitely generated. diff --git a/Mathlib/RingTheory/Noetherian/Filter.lean b/Mathlib/RingTheory/Noetherian/Filter.lean index dde545365f1d98..a5beccaa008162 100644 --- a/Mathlib/RingTheory/Noetherian/Filter.lean +++ b/Mathlib/RingTheory/Noetherian/Filter.lean @@ -32,9 +32,9 @@ Noetherian, noetherian, Noetherian ring, Noetherian module, noetherian ring, noe public section -open Set Filter Pointwise +open Filter -open IsNoetherian Submodule Function +open IsNoetherian Submodule section Semiring diff --git a/Mathlib/RingTheory/Noetherian/Orzech.lean b/Mathlib/RingTheory/Noetherian/Orzech.lean index eb3f64234d857f..af7924a22e8336 100644 --- a/Mathlib/RingTheory/Noetherian/Orzech.lean +++ b/Mathlib/RingTheory/Noetherian/Orzech.lean @@ -23,9 +23,6 @@ public import Mathlib.RingTheory.OrzechProperty @[expose] public section - -open Set Filter Pointwise - open IsNoetherian Submodule Function section diff --git a/Mathlib/RingTheory/Norm/Basic.lean b/Mathlib/RingTheory/Norm/Basic.lean index 9d7cce53e9e6c7..10a05df9e7abbc 100644 --- a/Mathlib/RingTheory/Norm/Basic.lean +++ b/Mathlib/RingTheory/Norm/Basic.lean @@ -171,7 +171,7 @@ end IntermediateField section EqProdEmbeddings -open IntermediateField IntermediateField.AdjoinSimple Polynomial +open IntermediateField.AdjoinSimple Polynomial variable (F) (E : Type*) [Field E] [Algebra K E] diff --git a/Mathlib/RingTheory/Norm/Defs.lean b/Mathlib/RingTheory/Norm/Defs.lean index 401d4bd8d9a15d..3df771e30ea796 100644 --- a/Mathlib/RingTheory/Norm/Defs.lean +++ b/Mathlib/RingTheory/Norm/Defs.lean @@ -48,7 +48,7 @@ open Module open LinearMap -open Matrix Polynomial +open Matrix open scoped Matrix diff --git a/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean b/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean index ee87c5495bbc8a..bea3eaccbc00b2 100644 --- a/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean +++ b/Mathlib/RingTheory/OrderOfVanishing/Noetherian.lean @@ -191,7 +191,7 @@ lemma ordFrac_irreducible IsDiscreteValuationRing.intValuation_maximalIdeal, IsDiscreteValuationRing.addVal_uniformizer hϖ, ← WithZero.exp_eq_coe_ofAdd] -open IsDedekindDomain HeightOneSpectrum +open IsDedekindDomain lemma isUnit_iff_ordFrac_one_of_isDiscreteValuationRing {x : R} : IsUnit x ↔ ordFrac R (algebraMap R K x) = 1 := by diff --git a/Mathlib/RingTheory/Polynomial/Radical.lean b/Mathlib/RingTheory/Polynomial/Radical.lean index 3e0336f3c4495b..918360db45e5f3 100644 --- a/Mathlib/RingTheory/Polynomial/Radical.lean +++ b/Mathlib/RingTheory/Polynomial/Radical.lean @@ -19,7 +19,7 @@ See `Mathlib.RingTheory.Radical.Basic` for the definition of `radical` and `divR public section -open Polynomial UniqueFactorizationMonoid UniqueFactorizationDomain EuclideanDomain +open Polynomial UniqueFactorizationMonoid EuclideanDomain variable {k : Type*} [Field k] [DecidableEq k] diff --git a/Mathlib/RingTheory/Polynomial/RationalRoot.lean b/Mathlib/RingTheory/Polynomial/RationalRoot.lean index 5afbbad9796a0e..bf1e6799926ad3 100644 --- a/Mathlib/RingTheory/Polynomial/RationalRoot.lean +++ b/Mathlib/RingTheory/Polynomial/RationalRoot.lean @@ -37,7 +37,7 @@ section ScaleRoots variable {A K R S : Type*} [CommRing A] [Field K] [CommRing R] [CommRing S] variable {M : Submonoid A} [Algebra A S] [IsLocalization M S] [Algebra A K] [IsFractionRing A K] -open Finsupp IsFractionRing IsLocalization Polynomial +open IsFractionRing IsLocalization Polynomial theorem scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero {p : A[X]} {r : A} {s : M} (hr : aeval (mk' S r s) p = 0) : aeval (algebraMap A S r) (scaleRoots p s) = 0 := by diff --git a/Mathlib/RingTheory/PowerSeries/Order.lean b/Mathlib/RingTheory/PowerSeries/Order.lean index 449dd045fdd2cc..6cb2a85e3ef506 100644 --- a/Mathlib/RingTheory/PowerSeries/Order.lean +++ b/Mathlib/RingTheory/PowerSeries/Order.lean @@ -30,8 +30,6 @@ proving that `R⟦X⟧` is a normalization monoid, which is done in `PowerSeries @[expose] public section noncomputable section -open Polynomial - open Finset (antidiagonal mem_antidiagonal) namespace PowerSeries diff --git a/Mathlib/RingTheory/PowerSeries/PiTopology.lean b/Mathlib/RingTheory/PowerSeries/PiTopology.lean index dc1d3885c15e39..fcde89c7724d56 100644 --- a/Mathlib/RingTheory/PowerSeries/PiTopology.lean +++ b/Mathlib/RingTheory/PowerSeries/PiTopology.lean @@ -317,7 +317,7 @@ section Summable variable [Semiring R] [TopologicalSpace R] -open WithPiTopology MvPowerSeries.WithPiTopology +open MvPowerSeries.WithPiTopology variable {R} diff --git a/Mathlib/RingTheory/Radical/Basic.lean b/Mathlib/RingTheory/Radical/Basic.lean index 2b536c44fb969e..f21167c42bbab9 100644 --- a/Mathlib/RingTheory/Radical/Basic.lean +++ b/Mathlib/RingTheory/Radical/Basic.lean @@ -371,7 +371,6 @@ theorem radical_neg_one : radical (-1 : R) = 1 := by simp end UniqueFactorizationDomain -open UniqueFactorizationDomain namespace EuclideanDomain variable {E : Type*} [EuclideanDomain E] [NormalizationMonoid E] [UniqueFactorizationMonoid E] diff --git a/Mathlib/RingTheory/RingHom/Bijective.lean b/Mathlib/RingTheory/RingHom/Bijective.lean index 6886ea94fb0a68..509abc6c91bd62 100644 --- a/Mathlib/RingTheory/RingHom/Bijective.lean +++ b/Mathlib/RingTheory/RingHom/Bijective.lean @@ -21,8 +21,6 @@ the ring hom property. public section -open TensorProduct - variable {R S : Type*} [CommRing R] [CommRing S] namespace RingHom.Bijective diff --git a/Mathlib/RingTheory/RingHomProperties.lean b/Mathlib/RingTheory/RingHomProperties.lean index e4b392180f2b75..8e4a48b2c8c7f6 100644 --- a/Mathlib/RingTheory/RingHomProperties.lean +++ b/Mathlib/RingTheory/RingHomProperties.lean @@ -31,7 +31,7 @@ The following meta-properties of predicates on ring homomorphisms are defined universe u -open CategoryTheory Opposite CategoryTheory.Limits TensorProduct +open CategoryTheory CategoryTheory.Limits TensorProduct namespace RingHom diff --git a/Mathlib/RingTheory/Smooth/Quotient.lean b/Mathlib/RingTheory/Smooth/Quotient.lean index 57733197c8cef7..89d9a0df4e8b88 100644 --- a/Mathlib/RingTheory/Smooth/Quotient.lean +++ b/Mathlib/RingTheory/Smooth/Quotient.lean @@ -21,8 +21,6 @@ In this file, we formalize the result [Stacks 031L] : For flat ring homomorphism public section -open IsLocalRing - variable {R : Type*} [CommRing R] /-- For any surjection `f : M →ₗ[R] N`, with `N` a flat `R`-module, diff --git a/Mathlib/RingTheory/Smooth/StandardSmooth.lean b/Mathlib/RingTheory/Smooth/StandardSmooth.lean index ad083a3e38272d..1f420e9aaad9e5 100644 --- a/Mathlib/RingTheory/Smooth/StandardSmooth.lean +++ b/Mathlib/RingTheory/Smooth/StandardSmooth.lean @@ -45,7 +45,7 @@ in June 2024. universe t t' w w' u v -open TensorProduct Module MvPolynomial +open TensorProduct variable (n m : ℕ) diff --git a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean index f0ad6731c2e0e1..5f2b789877c0a1 100644 --- a/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean +++ b/Mathlib/RingTheory/Spectrum/Maximal/Localization.lean @@ -25,7 +25,7 @@ namespace MaximalSpectrum variable {R} -open PrimeSpectrum Set +open Set variable (R : Type*) variable [CommRing R] [IsDomain R] (K : Type*) [Field K] [Algebra R K] [IsFractionRing R K] diff --git a/Mathlib/RingTheory/Spectrum/Prime/Chevalley.lean b/Mathlib/RingTheory/Spectrum/Prime/Chevalley.lean index 9297286dbe9a34..7aec199d5e7add 100644 --- a/Mathlib/RingTheory/Spectrum/Prime/Chevalley.lean +++ b/Mathlib/RingTheory/Spectrum/Prime/Chevalley.lean @@ -20,7 +20,7 @@ public section variable {R S : Type*} [CommRing R] [CommRing S] -open Function Localization MvPolynomial Polynomial TensorProduct PrimeSpectrum Topology +open Function Localization Polynomial TensorProduct PrimeSpectrum Topology open scoped Pointwise namespace PrimeSpectrum diff --git a/Mathlib/RingTheory/TensorProduct/Finite.lean b/Mathlib/RingTheory/TensorProduct/Finite.lean index bc887b9d279e33..72a4eac45e4cfe 100644 --- a/Mathlib/RingTheory/TensorProduct/Finite.lean +++ b/Mathlib/RingTheory/TensorProduct/Finite.lean @@ -22,7 +22,6 @@ is again finitely generated. public section open Function (Surjective) -open Finsupp namespace Submodule diff --git a/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean b/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean index cf25c5461a1c52..7d1ff4215ae90a 100644 --- a/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean +++ b/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean @@ -48,9 +48,9 @@ noncomputable section namespace MvPolynomial -open DirectSum TensorProduct +open TensorProduct -open Set LinearMap Submodule +open LinearMap variable {R : Type u} {N : Type v} [CommSemiring R] diff --git a/Mathlib/RingTheory/Trace/Quotient.lean b/Mathlib/RingTheory/Trace/Quotient.lean index de76e73dc4a406..6dc353b98dddfe 100644 --- a/Mathlib/RingTheory/Trace/Quotient.lean +++ b/Mathlib/RingTheory/Trace/Quotient.lean @@ -26,7 +26,7 @@ public section variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] -open IsLocalRing FiniteDimensional Module Submodule IsLocalization.AtPrime +open IsLocalRing Module Submodule IsLocalization.AtPrime section IsLocalRing diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean index f20e5dbf0e7a25..2580a3b46ad3ef 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Basic.lean @@ -39,7 +39,7 @@ namespace WfDvdMonoid variable [CommMonoidWithZero α] -open Associates Nat +open Associates theorem of_wfDvdMonoid_associates (_ : WfDvdMonoid (Associates α)) : WfDvdMonoid α := ⟨(mk_surjective.wellFounded_iff mk_dvdNotUnit_mk_iff.symm).2 wellFounded_dvdNotUnit⟩ diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean index 18e7045a5ca9a0..e0ea096066fde6 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain/Defs.lean @@ -44,8 +44,6 @@ namespace WfDvdMonoid variable [CommMonoidWithZero α] -open Associates Nat - variable [WfDvdMonoid α] theorem exists_irreducible_factor {a : α} (ha : ¬IsUnit a) (ha0 : a ≠ 0) : diff --git a/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean b/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean index 72194dc66f8f0a..c3bf00832e5f82 100644 --- a/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean +++ b/Mathlib/RingTheory/Valuation/ValuativeRel/Trivial.lean @@ -28,8 +28,6 @@ namespace ValuativeRel variable {R Γ : Type} [Ring R] [DecidableEq R] [IsDomain R] [LinearOrderedCommGroupWithZero Γ] -open WithZero - /-- The trivial valuative relation on a domain `R`, such that all non-zero elements are related. The domain condition is necessary so that the relation is closed when multiplying. -/ diff --git a/Mathlib/RingTheory/WittVector/Domain.lean b/Mathlib/RingTheory/WittVector/Domain.lean index 1596872f2caa2b..cf786f327b26d2 100644 --- a/Mathlib/RingTheory/WittVector/Domain.lean +++ b/Mathlib/RingTheory/WittVector/Domain.lean @@ -40,8 +40,6 @@ noncomputable section namespace WittVector -open Function - variable {p : ℕ} {R : Type*} local notation "𝕎" => WittVector p -- type as `\bbW` diff --git a/Mathlib/RingTheory/WittVector/StructurePolynomial.lean b/Mathlib/RingTheory/WittVector/StructurePolynomial.lean index cc98c44df9f9a9..eed952ff3d28ff 100644 --- a/Mathlib/RingTheory/WittVector/StructurePolynomial.lean +++ b/Mathlib/RingTheory/WittVector/StructurePolynomial.lean @@ -89,7 +89,7 @@ dvd_sub_pow_of_dvd_sub {R : Type*} [CommRing R] {p : ℕ} {a b : R} : @[expose] public section -open MvPolynomial Set +open MvPolynomial open Finset (range) diff --git a/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean b/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean index 7a93ca69f21609..8714ae7684d947 100644 --- a/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean +++ b/Mathlib/RingTheory/WittVector/TeichmullerSeries.lean @@ -31,7 +31,7 @@ Show that the Teichmuller series is unique. public section -open Ideal Quotient +open Ideal namespace WittVector variable {p : ℕ} [hp : Fact (Nat.Prime p)] diff --git a/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean b/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean index 945495351dc27f..15d34c1db6acbf 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality/Basic.lean @@ -17,7 +17,7 @@ cardinality of a cofinal subset. public noncomputable section -open Function Cardinal Set Order +open Cardinal Set Order universe u v w diff --git a/Mathlib/SetTheory/Cardinal/Defs.lean b/Mathlib/SetTheory/Cardinal/Defs.lean index 7889e0f375c920..451c2a600e449e 100644 --- a/Mathlib/SetTheory/Cardinal/Defs.lean +++ b/Mathlib/SetTheory/Cardinal/Defs.lean @@ -54,7 +54,7 @@ Cantor's theorem, König's theorem, Konig's theorem assert_not_exists Monoid -open List Function Set +open List noncomputable section diff --git a/Mathlib/SetTheory/Cardinal/NatCount.lean b/Mathlib/SetTheory/Cardinal/NatCount.lean index 6b223db08f53f8..b1dd768f97867f 100644 --- a/Mathlib/SetTheory/Cardinal/NatCount.lean +++ b/Mathlib/SetTheory/Cardinal/NatCount.lean @@ -18,7 +18,7 @@ public section namespace Nat -open Nat Count +open Nat variable {p : ℕ → Prop} [DecidablePred p] (n : ℕ) diff --git a/Mathlib/SetTheory/Cardinal/Order.lean b/Mathlib/SetTheory/Cardinal/Order.lean index 103defb8e2cf81..08af7be84164d6 100644 --- a/Mathlib/SetTheory/Cardinal/Order.lean +++ b/Mathlib/SetTheory/Cardinal/Order.lean @@ -62,7 +62,7 @@ Cantor's theorem, König's theorem, Konig's theorem assert_not_exists Field -open List Function Order Set +open Function Order Set noncomputable section diff --git a/Mathlib/SetTheory/Ordinal/Topology.lean b/Mathlib/SetTheory/Ordinal/Topology.lean index 7496d78530a870..5b051cd75f56ca 100644 --- a/Mathlib/SetTheory/Ordinal/Topology.lean +++ b/Mathlib/SetTheory/Ordinal/Topology.lean @@ -34,7 +34,7 @@ topologies. universe u v -open Cardinal Order Topology +open Order Topology namespace Ordinal diff --git a/Mathlib/Tactic/Bound.lean b/Mathlib/Tactic/Bound.lean index 3179e36a78b5c3..c301acf7ac22a6 100644 --- a/Mathlib/Tactic/Bound.lean +++ b/Mathlib/Tactic/Bound.lean @@ -89,7 +89,7 @@ We close numerical goals with `norm_num` and `linarith`. public meta section -open Lean Elab Meta Term Mathlib.Tactic Syntax +open Lean Mathlib.Tactic open Lean.Elab.Tactic (liftMetaTactic liftMetaTactic' TacticM getMainGoal) namespace Mathlib.Tactic.Bound diff --git a/Mathlib/Tactic/Determinant/Bird/Cert.lean b/Mathlib/Tactic/Determinant/Bird/Cert.lean index 33493a3b404957..72c0418b3c692c 100644 --- a/Mathlib/Tactic/Determinant/Bird/Cert.lean +++ b/Mathlib/Tactic/Determinant/Bird/Cert.lean @@ -73,7 +73,7 @@ improve performance. public meta section -open Lean Meta Qq +open Lean Qq open Mathlib.Tactic.Ring variable {u : Level} {α : Q(Type u)} {rα : Q(CommRing $α)} diff --git a/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean b/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean index 4a88eaaeda8c8f..d6baad8ab4cb8e 100644 --- a/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean +++ b/Mathlib/Tactic/Linarith/Oracle/FourierMotzkin.lean @@ -34,7 +34,6 @@ we conclude that the original system was unsatisfiable. public meta section -open Batteries open Std (format ToFormat TreeSet) namespace Mathlib.Tactic.Linarith diff --git a/Mathlib/Tactic/NormNum/Result.lean b/Mathlib/Tactic/NormNum/Result.lean index 8583027f5b8b9d..6ba0b19c83e8e7 100644 --- a/Mathlib/Tactic/NormNum/Result.lean +++ b/Mathlib/Tactic/NormNum/Result.lean @@ -32,7 +32,7 @@ universe u variable {α : Type u} open Lean -open Lean.Meta Qq Lean.Elab Term +open Lean.Meta Qq Lean.Elab namespace Mathlib namespace Meta.NormNum diff --git a/Mathlib/Testing/Plausible/Functions.lean b/Mathlib/Testing/Plausible/Functions.lean index 1d278d55733cb1..b97a1675a83e4c 100644 --- a/Mathlib/Testing/Plausible/Functions.lean +++ b/Mathlib/Testing/Plausible/Functions.lean @@ -285,8 +285,6 @@ theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup open TotalFunction (List.toFinmap') -open SampleableExt - /-- Remove a slice of length `m` at index `n` in a list and a permutation, maintaining the property that it is a permutation. -/ diff --git a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean index 57e5d0d9593898..f184a18ab08d7f 100644 --- a/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean +++ b/Mathlib/Topology/Algebra/Category/ProfiniteGrp/Basic.lean @@ -34,7 +34,7 @@ disconnected. universe u v -open CategoryTheory Topology +open CategoryTheory /-- The category of profinite groups. A term of this type consists of a profinite diff --git a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean index 9e09e4146624ce..6f814fd12fc742 100644 --- a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean +++ b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean @@ -28,7 +28,7 @@ assert_not_exists ContinuousLinearEquiv section -open Function Topology +open Function variable (F A B C D E : Type*) variable [Monoid A] [Monoid B] [Monoid C] [Monoid D] diff --git a/Mathlib/Topology/Algebra/Group/GroupTopology.lean b/Mathlib/Topology/Algebra/Group/GroupTopology.lean index 5074ba1bd69c40..02235dee972152 100644 --- a/Mathlib/Topology/Algebra/Group/GroupTopology.lean +++ b/Mathlib/Topology/Algebra/Group/GroupTopology.lean @@ -23,7 +23,7 @@ The additive version `AddGroupTopology α` and corresponding results are provide @[expose] public section -open Set Filter TopologicalSpace Function Topology Pointwise MulOpposite +open Set TopologicalSpace Function Topology universe u v w x diff --git a/Mathlib/Topology/Algebra/GroupCompletion.lean b/Mathlib/Topology/Algebra/GroupCompletion.lean index 0ead91986c5b44..da0f19604d3e34 100644 --- a/Mathlib/Topology/Algebra/GroupCompletion.lean +++ b/Mathlib/Topology/Algebra/GroupCompletion.lean @@ -37,7 +37,7 @@ variable {M R α β : Type*} section Group -open UniformSpace CauchyFilter Filter Set +open UniformSpace variable [UniformSpace α] diff --git a/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean b/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean index 33a9d39006f4b4..7222b9f92c29d2 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/ENNReal.lean @@ -440,8 +440,6 @@ theorem tsum_indicator_ne_zero {f : α → ℝ≥0} (hf : Summable f) {s : Set hap ((Set.indicator_apply_eq_self.mpr (absurd ha)).symm.trans ((indicator_summable hf s).tsum_eq_zero_iff.1 h' a)) -open Finset - /-- For `f : ℕ → ℝ≥0`, then `∑' k, f (k + i)` tends to zero. This does not require a summability assumption on `f`, as otherwise all sums are zero. -/ theorem tendsto_sum_nat_add (f : ℕ → ℝ≥0) : Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Module.lean b/Mathlib/Topology/Algebra/InfiniteSum/Module.lean index fd734dde59a7fc..d0a11476cbfb7b 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Module.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Module.lean @@ -14,7 +14,7 @@ public import Mathlib.Topology.Algebra.Module.Equiv variable {α β γ δ : Type*} -open Filter Finset Function +open Function section ConstSMul diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 928620af8c1ba9..1dd793d5695e36 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -24,7 +24,7 @@ version. public section -open Set Metric TopologicalSpace Function Filter +open Set TopologicalSpace Filter open scoped Topology NNReal diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean index 6ef4e005cf55a1..b469fb35776d15 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Defs.lean @@ -50,11 +50,11 @@ assert_not_exists Cauchy noncomputable section -open Uniformity Topology Filter Pointwise +open Uniformity Topology Filter section LeftRight -open Filter Set +open Filter variable {G Gₗ Gᵣ Hₗ Hᵣ X : Type*} diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean b/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean index a600331bc4a9b0..c4d0559af026ba 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/DiscreteSubgroup.lean @@ -19,7 +19,7 @@ be used in other files without requiring lots of group-theoretic imports. @[expose] public section -open Filter Topology Uniformity +open Filter Topology variable {G : Type*} [Group G] [TopologicalSpace G] diff --git a/Mathlib/Topology/Algebra/IsUniformGroup/Order.lean b/Mathlib/Topology/Algebra/IsUniformGroup/Order.lean index 6558c65299d960..4cf3800e453360 100644 --- a/Mathlib/Topology/Algebra/IsUniformGroup/Order.lean +++ b/Mathlib/Topology/Algebra/IsUniformGroup/Order.lean @@ -19,7 +19,7 @@ in particular bounding the values of `f` in terms of bounds on the limit `g`. public section -open Filter Function Finset Topology +open Filter variable {α ι : Type*} diff --git a/Mathlib/Topology/Algebra/Module/ClosedSubmodule.lean b/Mathlib/Topology/Algebra/Module/ClosedSubmodule.lean index 04914f2de4edec..fad80db455e7b1 100644 --- a/Mathlib/Topology/Algebra/Module/ClosedSubmodule.lean +++ b/Mathlib/Topology/Algebra/Module/ClosedSubmodule.lean @@ -23,7 +23,7 @@ Actually provide the `Order.Frame (ClosedSubmodule R M)` instance. @[expose] public section -open Function Order TopologicalSpace +open Function TopologicalSpace variable {ι : Sort*} {R M N O : Type*} [Semiring R] [AddCommMonoid M] [TopologicalSpace M] [Module R M] diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean index 2f0b3d8ffb97e1..710fc8ec5bf397 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/Basic.lean @@ -51,7 +51,6 @@ Later files endow it with a topological structure, see the docstring of assert_not_exists TrivialStar open LinearMap (ker range) -open Topology Filter Pointwise universe u v w u' diff --git a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/PiProd.lean b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/PiProd.lean index e2445131faa582..644ce80ee53818 100644 --- a/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/PiProd.lean +++ b/Mathlib/Topology/Algebra/Module/ContinuousLinearMap/PiProd.lean @@ -62,7 +62,6 @@ Indexed products: assert_not_exists TrivialStar open LinearMap (ker range) -open Topology Filter Pointwise universe u v w u' diff --git a/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean b/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean index 29325bbb0d51eb..6dd48a9ef9fc01 100644 --- a/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean +++ b/Mathlib/Topology/Algebra/Module/EmbeddingOfLocal.lean @@ -63,7 +63,7 @@ proof for more details. @[expose] public section -open Topology Filter Bornology Set +open Topology Filter Set open scoped Pointwise Set.Notation variable {𝕜₁ 𝕜₂ E F : Type*} [NontriviallyNormedField 𝕜₁] [NontriviallyNormedField 𝕜₂] diff --git a/Mathlib/Topology/Algebra/Module/Equiv.lean b/Mathlib/Topology/Algebra/Module/Equiv.lean index 4aa1346bb57684..8000e5fb2bdd9d 100644 --- a/Mathlib/Topology/Algebra/Module/Equiv.lean +++ b/Mathlib/Topology/Algebra/Module/Equiv.lean @@ -39,7 +39,7 @@ by `M ≃SL[σ] M₂`, `M ≃L[R] M₂` and `M ≃L⋆[R] M₂`. assert_not_exists TrivialStar open LinearMap (ker range) -open Topology Filter Pointwise +open Topology Filter open scoped Ring universe u v w u' diff --git a/Mathlib/Topology/Algebra/Module/LinearPMap.lean b/Mathlib/Topology/Algebra/Module/LinearPMap.lean index 999f059ebdc1b1..a8c7e94acdbce5 100644 --- a/Mathlib/Topology/Algebra/Module/LinearPMap.lean +++ b/Mathlib/Topology/Algebra/Module/LinearPMap.lean @@ -45,9 +45,6 @@ Unbounded operators, closed operators @[expose] public section - -open Topology - variable {R E F : Type*} variable [CommRing R] [AddCommGroup E] [AddCommGroup F] variable [Module R E] [Module R F] diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean index e9e26963455cdd..90f6910a738f02 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean @@ -37,7 +37,7 @@ especially when defining iterated derivatives. @[expose] public section -open Function Fin Set +open Function Fin universe u v w w₁ w₁' w₂ w₃ w₄ diff --git a/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean b/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean index 5381f8413dc0df..855679030c2bc1 100644 --- a/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean +++ b/Mathlib/Topology/Algebra/Module/Spaces/CompactConvergenceCLM.lean @@ -36,7 +36,7 @@ uniform convergence, bounded convergence @[expose] public section -open Bornology Filter Function Set Topology ContinuousLinearMap +open Filter Function Set Topology ContinuousLinearMap open scoped UniformConvergence Uniformity section CompactSets diff --git a/Mathlib/Topology/Algebra/OpenSubgroup.lean b/Mathlib/Topology/Algebra/OpenSubgroup.lean index f11c46f8ac78a1..d1ffb5933ee30a 100644 --- a/Mathlib/Topology/Algebra/OpenSubgroup.lean +++ b/Mathlib/Topology/Algebra/OpenSubgroup.lean @@ -329,8 +329,6 @@ end OpenSubgroup namespace Submodule -open OpenAddSubgroup - variable {R : Type*} {M : Type*} [CommRing R] variable [AddCommGroup M] [TopologicalSpace M] [IsTopologicalAddGroup M] [Module R M] diff --git a/Mathlib/Topology/Algebra/Order/UpperLower.lean b/Mathlib/Topology/Algebra/Order/UpperLower.lean index 0f006f8e6f83ff..b3cd265748fe2d 100644 --- a/Mathlib/Topology/Algebra/Order/UpperLower.lean +++ b/Mathlib/Topology/Algebra/Order/UpperLower.lean @@ -24,7 +24,7 @@ provide `HasUpperLowerClosure`, an ad hoc axiomatisation of the properties we ne public section -open Function Set +open Set open scoped Pointwise diff --git a/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean b/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean index 6d1b786b733b71..171c0b147acd5c 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuativeRel.lean @@ -45,7 +45,7 @@ end variable {R : Type*} [Ring R] [ValuativeRel R] [TopologicalSpace R] [IsValuativeTopology R] -open ValuativeRel TopologicalSpace Filter Topology Set +open ValuativeRel TopologicalSpace Filter Set local notation "v" => valuation R diff --git a/Mathlib/Topology/Bornology/BoundedOperation.lean b/Mathlib/Topology/Bornology/BoundedOperation.lean index e966feecff9536..db72c9f1de65f0 100644 --- a/Mathlib/Topology/Bornology/BoundedOperation.lean +++ b/Mathlib/Topology/Bornology/BoundedOperation.lean @@ -162,7 +162,7 @@ lemma SeminormedAddCommGroup.lipschitzWith_sub : instance : BoundedSub R := boundedSub_of_lipschitzWith_sub SeminormedAddCommGroup.lipschitzWith_sub -open Filter Pointwise Bornology +open Filter Bornology /- TODO: diff --git a/Mathlib/Topology/CWComplex/Classical/Graph.lean b/Mathlib/Topology/CWComplex/Classical/Graph.lean index fa0cf4dc09d44d..44a430050da064 100644 --- a/Mathlib/Topology/CWComplex/Classical/Graph.lean +++ b/Mathlib/Topology/CWComplex/Classical/Graph.lean @@ -20,7 +20,7 @@ In this file we define the 1-skeleton of a CW complex as a graph. public section -open Metric Set Graph +open Set Graph namespace Topology diff --git a/Mathlib/Topology/CantorBendixson.lean b/Mathlib/Topology/CantorBendixson.lean index b6a3ce56652c67..56b0d97cad5d0d 100644 --- a/Mathlib/Topology/CantorBendixson.lean +++ b/Mathlib/Topology/CantorBendixson.lean @@ -56,7 +56,7 @@ Cantor-Bendixson derivative sequence of a closed set. @[expose] public section -open Filter Set Cardinal OrdinalApprox Function +open Set Cardinal OrdinalApprox Function universe u diff --git a/Mathlib/Topology/Category/CompHausLike/EffectiveEpi.lean b/Mathlib/Topology/Category/CompHausLike/EffectiveEpi.lean index 187b498a02dfc0..ef7a26b15cb209 100644 --- a/Mathlib/Topology/Category/CompHausLike/EffectiveEpi.lean +++ b/Mathlib/Topology/Category/CompHausLike/EffectiveEpi.lean @@ -23,7 +23,7 @@ If furthermore explicit finite coproducts exist, then `CompHausLike P` is precoh universe u -open CategoryTheory Limits Topology +open CategoryTheory Topology namespace CompHausLike diff --git a/Mathlib/Topology/Category/CompactlyGenerated.lean b/Mathlib/Topology/Category/CompactlyGenerated.lean index 1509d32e544470..c2c58ee802c2f7 100644 --- a/Mathlib/Topology/Category/CompactlyGenerated.lean +++ b/Mathlib/Topology/Category/CompactlyGenerated.lean @@ -26,7 +26,7 @@ compact Hausdorff spaces `S` mapping continuously to `X`. universe u w -open CategoryTheory Topology TopologicalSpace +open CategoryTheory TopologicalSpace /-- `CompactlyGenerated.{u, w}` is the type of `u`-compactly generated `w`-small topological spaces. This should always be used with explicit universe parameters. -/ diff --git a/Mathlib/Topology/Category/TopCat/Limits/Basic.lean b/Mathlib/Topology/Category/TopCat/Limits/Basic.lean index 2e5322bef5807d..7f36339dc428dc 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Basic.lean @@ -21,7 +21,7 @@ underlying types are just the limits in the category of types. @[expose] public section -open TopologicalSpace CategoryTheory CategoryTheory.Limits Opposite +open TopologicalSpace CategoryTheory CategoryTheory.Limits universe v u u' w diff --git a/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean b/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean index 8b7aa0a966a367..685ccb57f6d6b5 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean @@ -19,7 +19,7 @@ of sets in the limit is, in fact, a topological basis. public section -open TopologicalSpace Topology +open TopologicalSpace open CategoryTheory diff --git a/Mathlib/Topology/Clopen.lean b/Mathlib/Topology/Clopen.lean index 6eca3456925d07..3c8d3a34b987ca 100644 --- a/Mathlib/Topology/Clopen.lean +++ b/Mathlib/Topology/Clopen.lean @@ -16,7 +16,7 @@ A clopen set is a set that is both closed and open. public section -open Set Filter Topology TopologicalSpace +open Set Topology TopologicalSpace universe u v diff --git a/Mathlib/Topology/ClopenBox.lean b/Mathlib/Topology/ClopenBox.lean index 764ece7be66f59..c527e7620ce7a1 100644 --- a/Mathlib/Topology/ClopenBox.lean +++ b/Mathlib/Topology/ClopenBox.lean @@ -34,7 +34,7 @@ Cartesian products of compact spaces (this is relevant to the theory of light pr public section -open Function Set Filter TopologicalSpace +open Function Set TopologicalSpace open scoped Topology variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] [CompactSpace Y] diff --git a/Mathlib/Topology/Compactness/CompactSystem.lean b/Mathlib/Topology/Compactness/CompactSystem.lean index 11e01cc117c7a1..3360187f0d8df4 100644 --- a/Mathlib/Topology/Compactness/CompactSystem.lean +++ b/Mathlib/Topology/Compactness/CompactSystem.lean @@ -28,7 +28,7 @@ This file defines compact systems of sets. @[expose] public section -open Set Finset Nat +open Set Nat variable {α : Type*} {S : Set (Set α)} {C : ℕ → Set α} diff --git a/Mathlib/Topology/Connected/Clopen.lean b/Mathlib/Topology/Connected/Clopen.lean index 4a8f04efceb89d..aec216bc9402bd 100644 --- a/Mathlib/Topology/Connected/Clopen.lean +++ b/Mathlib/Topology/Connected/Clopen.lean @@ -27,7 +27,7 @@ to clopen sets. @[expose] public section -open Set Function Topology TopologicalSpace Relation +open Set Function Topology TopologicalSpace universe u v diff --git a/Mathlib/Topology/Connected/LocallyPathConnected.lean b/Mathlib/Topology/Connected/LocallyPathConnected.lean index 14d2f01fbdc4c3..e66fcc1c008a62 100644 --- a/Mathlib/Topology/Connected/LocallyPathConnected.lean +++ b/Mathlib/Topology/Connected/LocallyPathConnected.lean @@ -50,7 +50,7 @@ a theorem in `isOpen_isPathConnected_basis`. noncomputable section -open Topology Filter unitInterval Set Function +open Topology Filter Set Function variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] {x y z : X} {ι : Type*} {F : Set X} diff --git a/Mathlib/Topology/ContinuousMap/Bounded/Star.lean b/Mathlib/Topology/ContinuousMap/Bounded/Star.lean index 1e1edba6156436..e364d154654339 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded/Star.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded/Star.lean @@ -18,9 +18,9 @@ public import Mathlib.Topology.ContinuousMap.Star noncomputable section -open Topology Bornology NNReal uniformity UniformConvergence RCLike BoundedContinuousFunction +open BoundedContinuousFunction -open Set Filter Metric Function +open Set universe u v w diff --git a/Mathlib/Topology/ContinuousMap/Sigma.lean b/Mathlib/Topology/ContinuousMap/Sigma.lean index 22dd4cc1e02274..05b841875d47fb 100644 --- a/Mathlib/Topology/ContinuousMap/Sigma.lean +++ b/Mathlib/Topology/ContinuousMap/Sigma.lean @@ -38,7 +38,7 @@ continuous map, sigma type, disjoint union noncomputable section -open Filter Topology +open Topology variable {X ι : Type*} {Y : ι → Type*} [TopologicalSpace X] [∀ i, TopologicalSpace (Y i)] diff --git a/Mathlib/Topology/Convenient/Localization.lean b/Mathlib/Topology/Convenient/Localization.lean index 678105533b75df..66a21a31131b4d 100644 --- a/Mathlib/Topology/Convenient/Localization.lean +++ b/Mathlib/Topology/Convenient/Localization.lean @@ -28,7 +28,7 @@ a localization functor. universe v t u -open CategoryTheory MorphismProperty +open CategoryTheory namespace TopCat diff --git a/Mathlib/Topology/Defs/Basic.lean b/Mathlib/Topology/Defs/Basic.lean index 5d4bc0697dafcf..e64f2a1f2d785e 100644 --- a/Mathlib/Topology/Defs/Basic.lean +++ b/Mathlib/Topology/Defs/Basic.lean @@ -206,7 +206,7 @@ scoped notation (name := closure_of) "closure[" t "]" => @closure _ t scoped notation (name := Continuous_of) "Continuous[" t₁ ", " t₂ "]" => @Continuous _ _ t₁ t₂ -open Topology Lean.PrettyPrinter.Delaborator Delab.Noncanonical +open Lean.PrettyPrinter.Delaborator Delab.Noncanonical /-- Delaborator for `IsOpen[_]`. -/ @[scoped app_delab IsOpen] meta def delabIsOpen : Delab := delabUnary 2 1 fun x ↦ `(IsOpen[$x]) diff --git a/Mathlib/Topology/DerivedSet.lean b/Mathlib/Topology/DerivedSet.lean index e63908ffb209c4..8650680a4df0bd 100644 --- a/Mathlib/Topology/DerivedSet.lean +++ b/Mathlib/Topology/DerivedSet.lean @@ -18,7 +18,7 @@ and proves some properties of it. @[expose] public section -open Filter Topology +open Filter variable {X : Type*} [TopologicalSpace X] diff --git a/Mathlib/Topology/EMetricSpace/Diam.lean b/Mathlib/Topology/EMetricSpace/Diam.lean index 4674885d174afb..79015c3d23825b 100644 --- a/Mathlib/Topology/EMetricSpace/Diam.lean +++ b/Mathlib/Topology/EMetricSpace/Diam.lean @@ -16,7 +16,7 @@ as an extended nonnegative real number. @[expose] public section -open Set Filter +open Set open scoped Uniformity Topology Filter NNReal ENNReal Pointwise diff --git a/Mathlib/Topology/EMetricSpace/Lipschitz.lean b/Mathlib/Topology/EMetricSpace/Lipschitz.lean index 024066a705c84c..f6cd97e3b913df 100644 --- a/Mathlib/Topology/EMetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/EMetricSpace/Lipschitz.lean @@ -46,7 +46,7 @@ argument, and return `LipschitzWith (Real.toNNReal K) f`. universe u v w x -open Filter Function Set Topology NNReal ENNReal Bornology +open Filter Function Set Topology NNReal ENNReal variable {α : Type u} {β : Type v} {γ : Type w} {ι : Type x} diff --git a/Mathlib/Topology/EMetricSpace/Pi.lean b/Mathlib/Topology/EMetricSpace/Pi.lean index 5b96678f747b7e..38eb9e653ea19b 100644 --- a/Mathlib/Topology/EMetricSpace/Pi.lean +++ b/Mathlib/Topology/EMetricSpace/Pi.lean @@ -78,8 +78,6 @@ variable {γ : Type w} [EMetricSpace γ] section Pi -open Finset - variable {X : β → Type*} [Fintype β] /-- The product of a finite number of emetric spaces, with the max distance, is still diff --git a/Mathlib/Topology/FiberBundle/Basic.lean b/Mathlib/Topology/FiberBundle/Basic.lean index 054bcbbaa56355..a6332331ecdcf6 100644 --- a/Mathlib/Topology/FiberBundle/Basic.lean +++ b/Mathlib/Topology/FiberBundle/Basic.lean @@ -305,8 +305,6 @@ theorem trivializationAt_proj_fst {x : TotalSpace F E} : variable (F) -open Trivialization - /-- Characterization of continuous functions (at a point, within a set) into a fiber bundle. -/ theorem continuousWithinAt_totalSpace (f : X → TotalSpace F E) {s : Set X} {x₀ : X} : ContinuousWithinAt f s x₀ ↔ diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index a3a215afae4ff9..bcd731b39e401c 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -29,7 +29,7 @@ fiber bundle, fibre bundle, fiberwise product, pullback @[expose] public section -open Bundle Filter Set TopologicalSpace Topology +open Bundle Set TopologicalSpace Topology /-! ### The trivial bundle -/ @@ -222,7 +222,7 @@ theorem prod_symm_apply (x : B) (w₁ : F₁) (w₂ : F₂) : end Bundle.Trivialization -open Bundle Trivialization +open Bundle variable [∀ x, Zero (E₁ x)] [∀ x, Zero (E₂ x)] [∀ x : B, TopologicalSpace (E₁ x)] [∀ x : B, TopologicalSpace (E₂ x)] [FiberBundle F₁ E₁] [FiberBundle F₂ E₂] diff --git a/Mathlib/Topology/GDelta/Basic.lean b/Mathlib/Topology/GDelta/Basic.lean index 0b9aad1476bf83..d6b49f6e10ae76 100644 --- a/Mathlib/Topology/GDelta/Basic.lean +++ b/Mathlib/Topology/GDelta/Basic.lean @@ -50,7 +50,7 @@ assert_not_exists UniformSpace noncomputable section -open Topology TopologicalSpace Filter Encodable Set +open Topology TopologicalSpace Filter Set variable {X Y ι : Type*} {ι' : Sort*} diff --git a/Mathlib/Topology/Instances/AddCircle/Real.lean b/Mathlib/Topology/Instances/AddCircle/Real.lean index b360e250d0d12b..a0c6fec9387db3 100644 --- a/Mathlib/Topology/Instances/AddCircle/Real.lean +++ b/Mathlib/Topology/Instances/AddCircle/Real.lean @@ -20,7 +20,7 @@ Results specific to the additive circle over `ℝ`. noncomputable section -open AddCommGroup Set Function AddSubgroup TopologicalSpace Topology +open AddCommGroup Set Function AddSubgroup namespace AddCircle diff --git a/Mathlib/Topology/Instances/Discrete.lean b/Mathlib/Topology/Instances/Discrete.lean index 9e09daf5bf9b7b..1ffd0c404f1b35 100644 --- a/Mathlib/Topology/Instances/Discrete.lean +++ b/Mathlib/Topology/Instances/Discrete.lean @@ -25,7 +25,7 @@ and `OrderTopology ℕ` become available. public section -open Order Set TopologicalSpace Filter +open Set TopologicalSpace Filter variable {α : Type*} [TopologicalSpace α] diff --git a/Mathlib/Topology/Instances/EReal/Lemmas.lean b/Mathlib/Topology/Instances/EReal/Lemmas.lean index 21769f8ca7d518..c05325f9aa7d9d 100644 --- a/Mathlib/Topology/Instances/EReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/EReal/Lemmas.lean @@ -29,7 +29,7 @@ Most proofs are adapted from the corresponding proofs on `ℝ≥0∞`. noncomputable section -open Set Filter Metric TopologicalSpace Topology +open Set Filter TopologicalSpace Topology open scoped ENNReal variable {α : Type*} [TopologicalSpace α] diff --git a/Mathlib/Topology/Instances/NNReal/Lemmas.lean b/Mathlib/Topology/Instances/NNReal/Lemmas.lean index 417284b0fd3405..e7375dbe495cc2 100644 --- a/Mathlib/Topology/Instances/NNReal/Lemmas.lean +++ b/Mathlib/Topology/Instances/NNReal/Lemmas.lean @@ -39,7 +39,7 @@ a few of which rely on the fact that subtraction is continuous. noncomputable section -open Filter Metric Set TopologicalSpace Topology +open Filter Set TopologicalSpace Topology variable {ι : Sort*} {n : ℕ} diff --git a/Mathlib/Topology/Instances/RatLemmas.lean b/Mathlib/Topology/Instances/RatLemmas.lean index 83a06b3a0c2951..828e1a768ae389 100644 --- a/Mathlib/Topology/Instances/RatLemmas.lean +++ b/Mathlib/Topology/Instances/RatLemmas.lean @@ -32,7 +32,7 @@ compactification. public section -open Set Metric Filter TopologicalSpace +open Set Filter TopologicalSpace open Topology OnePoint diff --git a/Mathlib/Topology/Instances/ZMultiples.lean b/Mathlib/Topology/Instances/ZMultiples.lean index 5bfc1ccb037390..b4f6a765743fd5 100644 --- a/Mathlib/Topology/Instances/ZMultiples.lean +++ b/Mathlib/Topology/Instances/ZMultiples.lean @@ -21,7 +21,7 @@ public section noncomputable section -open Filter Int Metric Set TopologicalSpace Bornology +open Filter Int Metric Set TopologicalSpace open scoped Topology Uniformity Interval universe u v w diff --git a/Mathlib/Topology/KrullDimension.lean b/Mathlib/Topology/KrullDimension.lean index 0b55b422398669..b95e8f15e45ed0 100644 --- a/Mathlib/Topology/KrullDimension.lean +++ b/Mathlib/Topology/KrullDimension.lean @@ -30,7 +30,7 @@ dimension inequalities. @[expose] public section -open Set Function Order TopologicalSpace Topology TopologicalSpace.IrreducibleCloseds +open Set Order TopologicalSpace Topology TopologicalSpace.IrreducibleCloseds /-- The Krull dimension of a topological space is the supremum of lengths of chains of diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index caa37458bda0ae..2e662880bffd79 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -30,7 +30,7 @@ specialized to the degree of the residue field extension @[expose] public section -open Set Order Topology TopologicalSpace +open Set TopologicalSpace variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] {f : X → Y} (hf : IsSpectralMap f) (w : X → R) diff --git a/Mathlib/Topology/MetricSpace/Basic.lean b/Mathlib/Topology/MetricSpace/Basic.lean index a254c5c87e1000..7f3f1d2061d368 100644 --- a/Mathlib/Topology/MetricSpace/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Basic.lean @@ -151,8 +151,6 @@ end Prod section Pi -open Finset - variable {X : β → Type*} [Fintype β] [∀ b, MetricSpace (X b)] /-- A finite product of metric spaces is a metric space, with the sup distance. -/ @@ -164,8 +162,6 @@ namespace Metric section SecondCountable -open TopologicalSpace - -- TODO: use `Countable` instead of `Encodable` /-- A metric space is second countable if one can reconstruct up to any `ε>0` any element of the space from countably many data. -/ diff --git a/Mathlib/Topology/MetricSpace/Bounded.lean b/Mathlib/Topology/MetricSpace/Bounded.lean index 21b9c3843d5a62..df319ab03c501c 100644 --- a/Mathlib/Topology/MetricSpace/Bounded.lean +++ b/Mathlib/Topology/MetricSpace/Bounded.lean @@ -584,7 +584,7 @@ end Metric namespace Mathlib.Meta.Positivity -open Lean Meta Qq Function +open Lean Qq /-- Extension for the `positivity` tactic: the diameter of a set is always nonnegative. -/ @[positivity Metric.diam _] diff --git a/Mathlib/Topology/MetricSpace/Contracting.lean b/Mathlib/Topology/MetricSpace/Contracting.lean index c4bd6fe2e61b90..5db61aa618bb62 100644 --- a/Mathlib/Topology/MetricSpace/Contracting.lean +++ b/Mathlib/Topology/MetricSpace/Contracting.lean @@ -44,7 +44,7 @@ namespace ContractingWith variable [EMetricSpace α] {K : ℝ≥0} {f : α → α} -open EMetric Set +open Set theorem toLipschitzWith (hf : ContractingWith K f) : LipschitzWith K f := hf.2 diff --git a/Mathlib/Topology/MetricSpace/CoveringNumbers.lean b/Mathlib/Topology/MetricSpace/CoveringNumbers.lean index cab95f248e8316..ac4085f88cc6ec 100644 --- a/Mathlib/Topology/MetricSpace/CoveringNumbers.lean +++ b/Mathlib/Topology/MetricSpace/CoveringNumbers.lean @@ -55,7 +55,7 @@ in the set), but we have the following inequality: @[expose] public section -open EMetric Set +open Set open scoped ENNReal NNReal namespace Metric diff --git a/Mathlib/Topology/MetricSpace/DilationEquiv.lean b/Mathlib/Topology/MetricSpace/DilationEquiv.lean index b6eba13de0165e..9e92c3bab7e41a 100644 --- a/Mathlib/Topology/MetricSpace/DilationEquiv.lean +++ b/Mathlib/Topology/MetricSpace/DilationEquiv.lean @@ -24,7 +24,7 @@ We also develop basic API about these equivalences. @[expose] public section open scoped NNReal ENNReal -open Function Set Filter Bornology +open Function Filter Bornology open Dilation (ratio ratio_ne_zero ratio_pos edist_eq) section Class diff --git a/Mathlib/Topology/MetricSpace/Gluing.lean b/Mathlib/Topology/MetricSpace/Gluing.lean index c0a92c775058bb..e557f9f6d20810 100644 --- a/Mathlib/Topology/MetricSpace/Gluing.lean +++ b/Mathlib/Topology/MetricSpace/Gluing.lean @@ -55,7 +55,7 @@ noncomputable section universe u v w -open Function Set Uniformity Topology +open Function Set Uniformity namespace Metric @@ -434,10 +434,6 @@ protected def metricSpace : MetricSpace (Σ i, E i) := by attribute [local instance] Sigma.metricSpace -open Topology - -open Filter - /-- The injection of a space in a disjoint union is an isometry -/ theorem isometry_mk (i : ι) : Isometry (Sigma.mk i : E i → Σ k, E k) := Isometry.of_dist_eq fun x y => by simp diff --git a/Mathlib/Topology/MetricSpace/HolderNorm.lean b/Mathlib/Topology/MetricSpace/HolderNorm.lean index fdc37615f136da..65c1f765c13d5f 100644 --- a/Mathlib/Topology/MetricSpace/HolderNorm.lean +++ b/Mathlib/Topology/MetricSpace/HolderNorm.lean @@ -36,9 +36,9 @@ Hölder norm, Hoelder norm, Holder norm variable {X Y : Type*} -open Filter Set +open Set -open NNReal ENNReal Topology +open NNReal ENNReal section PseudoEMetricSpace diff --git a/Mathlib/Topology/MetricSpace/Lipschitz.lean b/Mathlib/Topology/MetricSpace/Lipschitz.lean index 6907ca8a731bc4..99d4f0815f5328 100644 --- a/Mathlib/Topology/MetricSpace/Lipschitz.lean +++ b/Mathlib/Topology/MetricSpace/Lipschitz.lean @@ -38,7 +38,7 @@ assert_not_exists Module.Basis Ideal ContinuousMul universe u v w x -open Filter Function Set Topology NNReal ENNReal Bornology +open Filter Function Set NNReal ENNReal Bornology variable {α : Type u} {β : Type v} {γ : Type w} {ι : Type x} @@ -302,8 +302,6 @@ theorem const_min (hf : LocallyLipschitz f) (a : ℝ) : LocallyLipschitz fun x = end Real end LocallyLipschitz -open Metric - variable [PseudoMetricSpace α] [PseudoMetricSpace β] {f : α → β} /-- A function `f : α → ℝ` which is `K`-Lipschitz on a subset `s` admits a `K`-Lipschitz extension diff --git a/Mathlib/Topology/MetricSpace/MetricSeparated.lean b/Mathlib/Topology/MetricSpace/MetricSeparated.lean index 0270e069e35ce0..317e1c8a3413a7 100644 --- a/Mathlib/Topology/MetricSpace/MetricSeparated.lean +++ b/Mathlib/Topology/MetricSpace/MetricSeparated.lean @@ -25,7 +25,7 @@ constant. @[expose] public section -open EMetric Set +open Set open scoped NNReal ENNReal noncomputable section diff --git a/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean b/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean index 8c11617e46be6f..b677b54a6d1608 100644 --- a/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean +++ b/Mathlib/Topology/MetricSpace/PartitionOfUnity.lean @@ -29,7 +29,7 @@ metric space, partition of unity, locally finite public section -open Topology ENNReal NNReal Filter Set Function TopologicalSpace Metric +open Topology ENNReal NNReal Filter Set TopologicalSpace Metric variable {ι X : Type*} diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean index 0d1a6668760ace..799d926fbaf183 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean @@ -20,7 +20,7 @@ Further results about pseudo-metric spaces. public section -open Set Filter TopologicalSpace Bornology +open Set Filter TopologicalSpace open scoped ENNReal NNReal Uniformity Topology universe u v @@ -240,8 +240,6 @@ namespace Metric section SecondCountable -open TopologicalSpace - /-- A pseudometric space is second countable if, for every `ε > 0`, there is a countable set which is `ε`-dense. -/ theorem secondCountable_of_almost_dense_set diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index eaab1495053e91..5d03fd10989a0b 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -254,7 +254,7 @@ theorem dist_nonneg {x y : α} : 0 ≤ dist x y := namespace Mathlib.Meta.Positivity -open Lean Meta Qq Function +open Lean Qq /-- Extension for the `positivity` tactic: distances are nonnegative. -/ @[positivity Dist.dist _ _] diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean b/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean index bd5e7cc7d38204..69241442ed64a5 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Lemmas.lean @@ -15,7 +15,7 @@ public import Mathlib.Topology.UniformSpace.Compact public section -open Bornology Filter Metric Set +open Filter Metric Set open scoped NNReal Topology variable {ι α : Type*} [PseudoMetricSpace α] diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Real.lean b/Mathlib/Topology/MetricSpace/Pseudo/Real.lean index 384754d8fc1cca..00d4feebe3bbe2 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Real.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Real.lean @@ -14,7 +14,7 @@ public import Mathlib.Topology.MetricSpace.Pseudo.Pi public section -open Bornology Filter Metric Set +open Set open scoped NNReal Topology namespace Real diff --git a/Mathlib/Topology/MetricSpace/Sequences.lean b/Mathlib/Topology/MetricSpace/Sequences.lean index a31e60ff142f17..054ef649ac4242 100644 --- a/Mathlib/Topology/MetricSpace/Sequences.lean +++ b/Mathlib/Topology/MetricSpace/Sequences.lean @@ -16,7 +16,7 @@ In this file we prove 2 versions of Bolzano-Weierstrass theorem for proper metri public section -open Filter Bornology Metric +open Filter Bornology open scoped Topology variable {X : Type*} [PseudoMetricSpace X] diff --git a/Mathlib/Topology/MetricSpace/Thickening.lean b/Mathlib/Topology/MetricSpace/Thickening.lean index 4bbfe188a390cb..ada67591c6c9f8 100644 --- a/Mathlib/Topology/MetricSpace/Thickening.lean +++ b/Mathlib/Topology/MetricSpace/Thickening.lean @@ -174,8 +174,6 @@ section Cthickening variable [PseudoEMetricSpace α] {δ ε : ℝ} {s t : Set α} {x : α} -open EMetric - /-- The closed `δ`-thickening `Metric.cthickening δ E` of a subset `E` in a pseudo emetric space consists of those points that are at infimum distance at most `δ` from `E`. -/ def cthickening (δ : ℝ) (E : Set α) : Set α := diff --git a/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean b/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean index cfa453081a70f2..ed439f58a69f46 100644 --- a/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean +++ b/Mathlib/Topology/Metrizable/CompletelyMetrizable.lean @@ -41,7 +41,7 @@ is a convenience class and no instance should be registered for it. @[expose] public section -open Filter Function Set Topology +open Filter Set Topology variable {X Y : Type*} diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean b/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean index b60b59954a009f..b183373382e47e 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Composition.lean @@ -16,7 +16,7 @@ public import Mathlib.Topology.OpenPartialHomeomorph.IsImage @[expose] public section -open Function Set Filter Topology +open Function Set variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean index 9b447abef39aa9..1ac6255f70bd0a 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Constructions.lean @@ -26,7 +26,7 @@ public import Mathlib.Topology.OpenPartialHomeomorph.Composition @[expose] public section -open Function Set Filter Topology +open Function Set Topology variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] diff --git a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean index c9563195b3dc36..e118e3a066adb8 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/Defs.lean @@ -43,7 +43,7 @@ then it should use `e.source ∩ s` or `e.target ∩ t`, not `s ∩ e.source` or @[expose] public section -open Function Set Filter Topology +open Function Set variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] diff --git a/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean b/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean index 48dc62ba1dc3a4..49ceb1eb29b97f 100644 --- a/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean +++ b/Mathlib/Topology/OpenPartialHomeomorph/IsImage.lean @@ -31,7 +31,7 @@ then it should use `e.source ∩ s` or `e.target ∩ t`, not `s ∩ e.source` or @[expose] public section -open Function Set Filter Topology +open Set Filter Topology variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] diff --git a/Mathlib/Topology/Order/Category/FrameAdjunction.lean b/Mathlib/Topology/Order/Category/FrameAdjunction.lean index bca85b7a868217..46c9c61a913fc4 100644 --- a/Mathlib/Topology/Order/Category/FrameAdjunction.lean +++ b/Mathlib/Topology/Order/Category/FrameAdjunction.lean @@ -41,7 +41,7 @@ topological space, frame, locale, Stone duality, adjunction, points @[expose] public section -open CategoryTheory Order Set Topology TopologicalSpace +open CategoryTheory Order Set TopologicalSpace namespace Locale diff --git a/Mathlib/Topology/Order/DenselyOrdered.lean b/Mathlib/Topology/Order/DenselyOrdered.lean index e5b987ad5dd5b8..38a9963dc47751 100644 --- a/Mathlib/Topology/Order/DenselyOrdered.lean +++ b/Mathlib/Topology/Order/DenselyOrdered.lean @@ -13,7 +13,7 @@ public import Mathlib.Topology.Order.IsLUB public section -open Set Filter TopologicalSpace Topology Function +open Set Filter TopologicalSpace Topology open OrderDual (toDual ofDual) diff --git a/Mathlib/Topology/Order/ExtrClosure.lean b/Mathlib/Topology/Order/ExtrClosure.lean index b300de2eff1457..6581c86a0f35d0 100644 --- a/Mathlib/Topology/Order/ExtrClosure.lean +++ b/Mathlib/Topology/Order/ExtrClosure.lean @@ -21,8 +21,6 @@ public section open Filter Set -open Topology - variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] [Preorder Y] [OrderClosedTopology Y] {f : X → Y} {s : Set X} {a : X} diff --git a/Mathlib/Topology/Order/T5.lean b/Mathlib/Topology/Order/T5.lean index 3873d6566d6e8f..e525c03cf3ea55 100644 --- a/Mathlib/Topology/Order/T5.lean +++ b/Mathlib/Topology/Order/T5.lean @@ -19,7 +19,7 @@ topological space. public section -open Filter Set Function OrderDual Topology Interval +open Filter Set OrderDual Topology variable {X : Type*} [LinearOrder X] [TopologicalSpace X] [OrderTopology X] {a : X} {s t : Set X} diff --git a/Mathlib/Topology/PartialHomeomorph/Basic.lean b/Mathlib/Topology/PartialHomeomorph/Basic.lean index 065a60a32b12d0..ce8f969a6b9426 100644 --- a/Mathlib/Topology/PartialHomeomorph/Basic.lean +++ b/Mathlib/Topology/PartialHomeomorph/Basic.lean @@ -21,7 +21,7 @@ public import Mathlib.Topology.PartialHomeomorph.Defs @[expose] public section -open Function Set Filter Topology +open Function Set Topology variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] diff --git a/Mathlib/Topology/PartialHomeomorph/Defs.lean b/Mathlib/Topology/PartialHomeomorph/Defs.lean index 3cd827e68cc315..ae874fde197689 100644 --- a/Mathlib/Topology/PartialHomeomorph/Defs.lean +++ b/Mathlib/Topology/PartialHomeomorph/Defs.lean @@ -43,7 +43,7 @@ then it should use `e.source ∩ s` or `e.target ∩ t`, not `s ∩ e.source` or @[expose] public section -open Function Set Filter Topology +open Function Set variable {X X' : Type*} {Y Y' : Type*} {Z Z' : Type*} [TopologicalSpace X] [TopologicalSpace X'] [TopologicalSpace Y] [TopologicalSpace Y'] diff --git a/Mathlib/Topology/Separation/SeparatedNhds.lean b/Mathlib/Topology/Separation/SeparatedNhds.lean index 905097149c4464..e2666d4e4c3a4e 100644 --- a/Mathlib/Topology/Separation/SeparatedNhds.lean +++ b/Mathlib/Topology/Separation/SeparatedNhds.lean @@ -29,7 +29,7 @@ formulating separation axioms for topological spaces. @[expose] public section -open Function Set Filter Topology TopologicalSpace +open Set Filter Topology TopologicalSpace universe u v diff --git a/Mathlib/Topology/Sequences.lean b/Mathlib/Topology/Sequences.lean index 2825cddf51a682..946541fdfda48c 100644 --- a/Mathlib/Topology/Sequences.lean +++ b/Mathlib/Topology/Sequences.lean @@ -65,7 +65,7 @@ sequentially closed, sequentially compact, sequential space public section -open Bornology Filter Function Set TopologicalSpace Topology +open Filter Function Set TopologicalSpace Topology open scoped Uniformity variable {X Y : Type*} diff --git a/Mathlib/Topology/Sheaves/CommRingCat.lean b/Mathlib/Topology/Sheaves/CommRingCat.lean index 58124e187e0c0c..d663c66a7156eb 100644 --- a/Mathlib/Topology/Sheaves/CommRingCat.lean +++ b/Mathlib/Topology/Sheaves/CommRingCat.lean @@ -34,7 +34,7 @@ universe u v w v₁ v₂ u₁ u₂ noncomputable section -open CategoryTheory Limits TopologicalSpace Opposite +open CategoryTheory TopologicalSpace Opposite namespace TopCat.Presheaf diff --git a/Mathlib/Topology/Sheaves/Functors.lean b/Mathlib/Topology/Sheaves/Functors.lean index 34fcc88acc77dd..c624cf9dac6de7 100644 --- a/Mathlib/Topology/Sheaves/Functors.lean +++ b/Mathlib/Topology/Sheaves/Functors.lean @@ -48,8 +48,6 @@ namespace TopCat namespace Sheaf -open Presheaf - /-- The pushforward of a sheaf (by a continuous map) is a sheaf. -/ theorem pushforward_sheaf_of_sheaf {F : X.Presheaf C} (h : F.IsSheaf) : (f _* F).IsSheaf := @@ -113,7 +111,7 @@ end TopCat namespace Topology.IsOpenEmbedding -open TopCat Sheaf +open TopCat variable (A : Type*) [Category.{w} A] variable {f : X ⟶ Y} (hf : IsOpenEmbedding f) diff --git a/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean b/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean index f16abbf7b67ac7..35f474743c9a6c 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/UniqueGluing.lean @@ -167,7 +167,7 @@ end Presheaf namespace Sheaf -open Presheaf CategoryTheory +open CategoryTheory section diff --git a/Mathlib/Topology/Sheaves/SheafOfFunctions.lean b/Mathlib/Topology/Sheaves/SheafOfFunctions.lean index 01954859d965e1..bc85ea4716e122 100644 --- a/Mathlib/Topology/Sheaves/SheafOfFunctions.lean +++ b/Mathlib/Topology/Sheaves/SheafOfFunctions.lean @@ -31,7 +31,7 @@ Obviously there's more to do: @[expose] public section -open CategoryTheory Limits TopologicalSpace Opens +open CategoryTheory TopologicalSpace Opens noncomputable section diff --git a/Mathlib/Topology/Spectral/Hom.lean b/Mathlib/Topology/Spectral/Hom.lean index 0ebc489e10574e..c0003f047b849e 100644 --- a/Mathlib/Topology/Spectral/Hom.lean +++ b/Mathlib/Topology/Spectral/Hom.lean @@ -29,7 +29,7 @@ Once we have `SpectralSpace`, `IsSpectralMap` should move to `Mathlib/Topology/S @[expose] public section -open Function OrderDual +open Function variable {F α β γ δ : Type*} diff --git a/Mathlib/Topology/UniformSpace/AbsoluteValue.lean b/Mathlib/Topology/UniformSpace/AbsoluteValue.lean index c95e2e750ae7c2..b2310c6c8039e6 100644 --- a/Mathlib/Topology/UniformSpace/AbsoluteValue.lean +++ b/Mathlib/Topology/UniformSpace/AbsoluteValue.lean @@ -28,7 +28,7 @@ absolute value, uniform spaces @[expose] public section -open Set Function Filter Uniformity +open Set Filter Uniformity namespace AbsoluteValue diff --git a/Mathlib/Topology/UniformSpace/Ascoli.lean b/Mathlib/Topology/UniformSpace/Ascoli.lean index 5c7c248f62fcc5..803caffc52b146 100644 --- a/Mathlib/Topology/UniformSpace/Ascoli.lean +++ b/Mathlib/Topology/UniformSpace/Ascoli.lean @@ -72,7 +72,7 @@ equicontinuity, uniform convergence, ascoli public section -open Set Filter Uniformity Topology Function UniformConvergence +open Set Filter Topology Function UniformConvergence variable {ι X α : Type*} [TopologicalSpace X] [UniformSpace α] {F : ι → X → α} diff --git a/Mathlib/Topology/UniformSpace/Cauchy.lean b/Mathlib/Topology/UniformSpace/Cauchy.lean index 146088998669cd..e64d3fed51e385 100644 --- a/Mathlib/Topology/UniformSpace/Cauchy.lean +++ b/Mathlib/Topology/UniformSpace/Cauchy.lean @@ -831,7 +831,7 @@ namespace SequentiallyComplete variable {f : Filter α} (hf : Cauchy f) {U : ℕ → SetRel α α} (U_mem : ∀ n, U n ∈ 𝓤 α) -open Set Finset +open Set noncomputable section diff --git a/Mathlib/Topology/UniformSpace/Completion.lean b/Mathlib/Topology/UniformSpace/Completion.lean index a4a0c891d91166..a1f5c54988ae7e 100644 --- a/Mathlib/Topology/UniformSpace/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Completion.lean @@ -555,8 +555,6 @@ section Extension₂ variable (f : α → β → γ) -open Function - /-- Extend a two variable map to the Hausdorff completions. -/ protected def extension₂ (f : α → β → γ) : Completion α → Completion β → γ := cPkg.extend₂ cPkg f @@ -581,8 +579,6 @@ end Extension₂ section Map₂ -open Function - /-- Lift a two variable map to the Hausdorff completions. -/ protected def map₂ (f : α → β → γ) : Completion α → Completion β → Completion γ := cPkg.map₂ cPkg cPkg f diff --git a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean index b4092ca5e7bab6..8dfa3180f56e0d 100644 --- a/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/LocallyUniformConvergence.lean @@ -39,7 +39,7 @@ Uniform limit, uniform convergence, tends uniformly to noncomputable section -open Topology Uniformity Filter Set Uniform +open Topology Uniformity Filter Set variable {α β γ ι : Type*} [TopologicalSpace α] [UniformSpace β] variable {F : ι → α → β} {f : α → β} {s s' : Set α} {x : α} {p : Filter ι} diff --git a/Mathlib/Topology/UniformSpace/Matrix.lean b/Mathlib/Topology/UniformSpace/Matrix.lean index 09e927f8a08075..6781e160981191 100644 --- a/Mathlib/Topology/UniformSpace/Matrix.lean +++ b/Mathlib/Topology/UniformSpace/Matrix.lean @@ -17,7 +17,7 @@ public import Mathlib.Topology.Algebra.IsUniformGroup.Constructions public section -open Uniformity Topology +open Uniformity variable (m n 𝕜 : Type*) [UniformSpace 𝕜] diff --git a/Mathlib/Topology/UniformSpace/Ultra/Completion.lean b/Mathlib/Topology/UniformSpace/Ultra/Completion.lean index d06e74a7cea05e..57e689f4979fdc 100644 --- a/Mathlib/Topology/UniformSpace/Ultra/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Ultra/Completion.lean @@ -23,7 +23,7 @@ public section variable {X Y : Type*} [UniformSpace X] [UniformSpace Y] -open Filter Set Topology Uniformity +open Filter Set lemma IsUniformInducing.isUltraUniformity [IsUltraUniformity Y] {f : X → Y} (hf : IsUniformInducing f) : IsUltraUniformity X := diff --git a/Mathlib/Topology/UnitInterval.lean b/Mathlib/Topology/UnitInterval.lean index 819658eb1ff1dd..bcc39634abbdcd 100644 --- a/Mathlib/Topology/UnitInterval.lean +++ b/Mathlib/Topology/UnitInterval.lean @@ -23,7 +23,7 @@ We provide basic instances, as well as a custom tactic for discharging noncomputable section -open Topology Filter Set Int Set.Icc +open Set Int Set.Icc /-! ### The unit interval -/ diff --git a/Mathlib/Util/Tactic.lean b/Mathlib/Util/Tactic.lean index e5bafd44e7ea67..19e4ac2fb9e502 100644 --- a/Mathlib/Util/Tactic.lean +++ b/Mathlib/Util/Tactic.lean @@ -18,7 +18,7 @@ public meta section namespace Mathlib.Tactic -open Lean Meta Tactic +open Lean variable {m : Type → Type} From f4fd7f7e24a83af258ec9d80deb04648d3428d34 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Tue, 11 Aug 2026 22:12:57 +0000 Subject: [PATCH 1294/1300] feat: composition of Fredholm operators (#41601) Co-authored-by: Yongxi (Aaron) Lin --- .../Algebra/Module/LinearMap/FiniteRange.lean | 4 + .../Normed/Operator/Fredholm/Basic.lean | 85 ++++++++++++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean index b3d308793cfde2..b1f5515f531618 100644 --- a/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean +++ b/Mathlib/Algebra/Module/LinearMap/FiniteRange.lean @@ -238,10 +238,14 @@ lemma equiv_iff_hasFiniteRange [IsNoetherianRing K] {u v : V →ₗ[K] V₂} : lemma equiv_zero_iff_hasNoetherianRange {u : V →ₗ[K] V₂} : u ≈ 0 ↔ u.HasNoetherianRange := by simp [equiv_iff_hasNoetherianRange] +alias ⟨_, _root_.LinearMap.HasNoetherianRange.equiv_zero⟩ := equiv_zero_iff_hasNoetherianRange + lemma equiv_zero_iff_hasFiniteRange [IsNoetherianRing K] {u : V →ₗ[K] V₂} : u ≈ 0 ↔ u.HasFiniteRange := by simp [equiv_iff_hasFiniteRange] +alias ⟨_, _root_.LinearMap.HasFiniteRange.equiv_zero⟩ := equiv_zero_iff_hasFiniteRange + lemma equiv_iff_isNoetherian_quotient_eqLocus {u v : V →ₗ[K] V₂} : u ≈ v ↔ IsNoetherian K (V ⧸ eqLocus u v) := by rw [equiv_iff_hasNoetherianRange, hasNoetherianRange_iff_quotient_ker, eqLocus_eq_ker_sub] diff --git a/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean b/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean index 63dec73d83bd64..76ded2d712ed23 100644 --- a/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean +++ b/Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean @@ -97,8 +97,10 @@ open LinearMap.FiniteRangeSetoid namespace ContinuousLinearMap section TVS -variable {𝕜 E F : Type*} [NontriviallyNormedField 𝕜] [AddCommGroup E] [AddCommGroup F] - [Module 𝕜 E] [Module 𝕜 F] [TopologicalSpace E] [TopologicalSpace F] +variable {𝕜 E F G : Type*} [NontriviallyNormedField 𝕜] + [AddCommGroup E] [AddCommGroup F] [AddCommGroup G] + [Module 𝕜 E] [Module 𝕜 F] [Module 𝕜 G] + [TopologicalSpace E] [TopologicalSpace F] [TopologicalSpace G] /-! ## Definition and equivalent conditions @@ -368,6 +370,85 @@ theorem IsFredholm.of_isQuasiInverse {u : E →L[𝕜] F} {v : F →L[𝕜] E} ( end DefTFAE +section Constructions + +/-! +## Constructions of Fredholm operators +-/ + +theorem _root_.ContinuousLinearEquiv.isFredholm (e : E ≃L[𝕜] F) : + IsFredholm (e : E →L[𝕜] F) where + isStrictMap := e.isHomeomorph.isStrictMap + isClosed_range := by simp + finite_ker := by + rw [LinearMap.ker_eq_bot.2 (by exact e.injective)] + infer_instance + finite_coker := by simp + closedComplemented_ker := by simp + +protected theorem IsFredholm.id : IsFredholm (.id 𝕜 E) := + ContinuousLinearEquiv.refl 𝕜 E |>.isFredholm + +theorem IsInvertible.isFredholm {f : E →L[𝕜] F} (hf : f.IsInvertible) : + IsFredholm f := by + rcases hf with ⟨e, rfl⟩ + exact e.isFredholm + +variable [CompleteSpace 𝕜] [IsTopologicalAddGroup E] [IsTopologicalAddGroup F] + [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 E] [ContinuousSMul 𝕜 F] [ContinuousSMul 𝕜 G] + [T2Space E] [T2Space F] [T2Space G] + +theorem isFredholm_congr {u u' : E →L[𝕜] F} (h : u.toLinearMap ≈ u'.toLinearMap) : + IsFredholm u ↔ IsFredholm u' := by + simp_rw [isFredholm_iff_exists_isQuasiInverse] + exact exists_congr fun _ ↦ isQuasiInverse_congr (Setoid.refl _) (Setoid.symm h) + +theorem IsFredholm.congr {u u' : E →L[𝕜] F} (hu : IsFredholm u) + (h : u.toLinearMap ≈ u'.toLinearMap) : + IsFredholm u' := (isFredholm_congr h).mp hu + +theorem IsFredholm.add_hasFiniteRange {u v : E →L[𝕜] F} (hu : IsFredholm u) + (hv : HasFiniteRange v.toLinearMap) : + IsFredholm (u + v) := + hu.congr (by simpa [equiv_iff_hasFiniteRange] using hv.neg) + +theorem IsFredholm.hasFiniteRange_add {u v : E →L[𝕜] F} (hu : IsFredholm u) + (hv : HasFiniteRange v.toLinearMap) : + IsFredholm (v + u) := + add_comm u v ▸ hu.add_hasFiniteRange hv + +theorem IsFredholm.comp {f' : F →L[𝕜] G} {f : E →L[𝕜] F} (hf' : IsFredholm f') + (hf : IsFredholm f) : IsFredholm (f' ∘L f) := by + obtain ⟨g, hg⟩ := hf.exists_isQuasiInverse + obtain ⟨g', hg'⟩ := hf'.exists_isQuasiInverse + exact .of_isQuasiInverse (mod_cast hg.comp hg') + +theorem IsFredholm.comp_iff_left {f : E →L[𝕜] F} {f' : F →L[𝕜] G} (hf : IsFredholm f) : + IsFredholm (f' ∘L f) ↔ IsFredholm f' := by + refine ⟨fun hcomp ↦ ?_, fun hf' ↦ hf'.comp hf⟩ + obtain ⟨g, hg⟩ := hf.exists_isQuasiInverse + obtain ⟨w, hw⟩ := hcomp.exists_isQuasiInverse + exact .of_isQuasiInverse (mod_cast hg.of_comp_left hw) + +theorem IsFredholm.comp_iff_right {f : E →L[𝕜] F} {f' : F →L[𝕜] G} (hf' : IsFredholm f') : + IsFredholm (f' ∘L f) ↔ IsFredholm f := by + refine ⟨fun hcomp ↦ ?_, fun hf ↦ hf'.comp hf⟩ + obtain ⟨g', hg'⟩ := hf'.exists_isQuasiInverse + obtain ⟨w, hw⟩ := hcomp.exists_isQuasiInverse + exact .of_isQuasiInverse (mod_cast hg'.of_comp_right hw) + +@[simp] +theorem isFredholm_comp_equiv {f : E ≃L[𝕜] F} {f' : F →L[𝕜] G} : + IsFredholm (f' ∘L (f : E →L[𝕜] F)) ↔ IsFredholm f' := + f.isFredholm.comp_iff_left + +@[simp] +theorem isFredholm_equiv_comp {f : E →L[𝕜] F} {f' : F ≃L[𝕜] G} : + IsFredholm ((f' : F →L[𝕜] G) ∘L f) ↔ IsFredholm f := + f'.isFredholm.comp_iff_right + +end Constructions + end TVS end ContinuousLinearMap From 54c99e1f5e123dfa97306502806cfbd85f2f94e3 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:11:37 -0700 Subject: [PATCH 1295/1300] Update Mathlib/Topology/Order/MonotoneConvergence.lean Co-authored-by: Jireh Loreaux --- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index afd4d9864168c1..e6e1c8f1cae4c6 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -130,7 +130,7 @@ end ConditionallyCompletePartialOrder section ConditionallyCompleteLattice -theorem tendsto_finset_sup_ciSup {ι} [ConditionallyCompleteLattice α] [OrderBot α] +theorem tendsto_finsetSup_ciSup {ι} [ConditionallyCompleteLattice α] [OrderBot α] [SupConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddAbove (range a)) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by simpa [ciSup_eq_ciSup_finset ha] using From 884781f93dc1926c9755e780d464f3f7c35c45d3 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:11:47 -0700 Subject: [PATCH 1296/1300] Update Mathlib/Topology/Order/MonotoneConvergence.lean Co-authored-by: Jireh Loreaux --- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index e6e1c8f1cae4c6..306246e8085ba6 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -156,7 +156,7 @@ end ConditionallyCompletePartialOrder section ConditionallyCompleteLattice -theorem tendsto_finset_inf_ciInf {ι} [ConditionallyCompleteLattice α] [OrderTop α] +theorem tendsto_finsetInf_ciInf {ι} [ConditionallyCompleteLattice α] [OrderTop α] [InfConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddBelow (range a)) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := tendsto_finset_sup_ciSup (α := αᵒᵈ) ha From ae17a3a324ba5e30f1bff2248898c2ea324d049c Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:11:53 -0700 Subject: [PATCH 1297/1300] Update Mathlib/Topology/Order/MonotoneConvergence.lean Co-authored-by: Jireh Loreaux --- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 306246e8085ba6..fae64a5dc87ea2 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -172,7 +172,7 @@ variable [CompleteLattice α] [SupConvergenceClass α] {f : ι → α} theorem tendsto_atTop_iSup (h_mono : Monotone f) : Tendsto f atTop (𝓝 (⨆ i, f i)) := tendsto_atTop_ciSup h_mono (OrderTop.bddAbove _) -theorem tendsto_finset_sup_iSup {ι} (a : ι → α) : +theorem tendsto_finsetSup_iSup {ι} (a : ι → α) : Tendsto (fun F : Finset ι => F.sup a) atTop (𝓝 (⨆ i, a i)) := by simpa [Finset.sup_eq_iSup, ← iSup_eq_iSup_finset a] using tendsto_atTop_iSup (Finset.monotone_sup a) From 50cb440abc0fb1c5fc88e153bcfbaf3e3fc2504b Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:11:58 -0700 Subject: [PATCH 1298/1300] Update Mathlib/Topology/Order/MonotoneConvergence.lean Co-authored-by: Jireh Loreaux --- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index fae64a5dc87ea2..721a1c4fe71391 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -189,7 +189,7 @@ variable [CompleteLattice α] [InfConvergenceClass α] {f : ι → α} theorem tendsto_atBot_iInf (h_mono : Monotone f) : Tendsto f atBot (𝓝 (⨅ i, f i)) := tendsto_atBot_ciInf h_mono (OrderBot.bddBelow _) -theorem tendsto_finset_inf_iInf {ι} (a : ι → α) : +theorem tendsto_finsetInf_iInf {ι} (a : ι → α) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := tendsto_finset_sup_iSup (α := αᵒᵈ) a From 21f9b23c602446d2dce81db1da3c885b3209cad4 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:13:22 -0700 Subject: [PATCH 1299/1300] Update Mathlib/Topology/Order/MonotoneConvergence.lean --- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 721a1c4fe71391..3485b4ad4efb2a 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -159,7 +159,7 @@ section ConditionallyCompleteLattice theorem tendsto_finsetInf_ciInf {ι} [ConditionallyCompleteLattice α] [OrderTop α] [InfConvergenceClass α] [Nonempty ι] {a : ι → α} (ha : BddBelow (range a)) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := - tendsto_finset_sup_ciSup (α := αᵒᵈ) ha + tendsto_finsetSup_ciSup (α := αᵒᵈ) ha end ConditionallyCompleteLattice From 78b6c01f05ebdac73deef6be17186e7e279547a1 Mon Sep 17 00:00:00 2001 From: "Yongxi (Aaron) Lin" <97214596+CoolRmal@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:13:28 -0700 Subject: [PATCH 1300/1300] Update Mathlib/Topology/Order/MonotoneConvergence.lean --- Mathlib/Topology/Order/MonotoneConvergence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Order/MonotoneConvergence.lean b/Mathlib/Topology/Order/MonotoneConvergence.lean index 3485b4ad4efb2a..ea1c9b14469ad3 100644 --- a/Mathlib/Topology/Order/MonotoneConvergence.lean +++ b/Mathlib/Topology/Order/MonotoneConvergence.lean @@ -191,7 +191,7 @@ theorem tendsto_atBot_iInf (h_mono : Monotone f) : Tendsto f atBot (𝓝 (⨅ i, theorem tendsto_finsetInf_iInf {ι} (a : ι → α) : Tendsto (fun F : Finset ι => F.inf a) atTop (𝓝 (⨅ i, a i)) := - tendsto_finset_sup_iSup (α := αᵒᵈ) a + tendsto_finsetSup_iSup (α := αᵒᵈ) a theorem tendsto_atTop_iInf (h_anti : Antitone f) : Tendsto f atTop (𝓝 (⨅ i, f i)) := tendsto_atTop_ciInf h_anti (OrderBot.bddBelow _)